ronantakizawa/codereview-bench huggingface dataset:
Repository: go-gitea/gitea
File: build/generate-go-licenses.go (Go)

Code before:
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

//go:build ignore

package main

import (
	"encoding/json"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"slices"
	"sort"
	"strings"
)

// regexp is based on go-license, excluding README and NOTICE
// https://github.com/google/go-licenses/blob/master/licenses/find.go
var licenseRe = regexp.MustCompile(`^(?i)((UN)?LICEN(S|C)E|COPYING).*$`)

// ignoredNames are LicenseEntry.Name values to exclude from the output.
var ignoredNames = map[string]bool{
	"code.gitea.io/gitea":                true,
	"code.gitea.io/gitea/options/license": true,
}

var excludedExt = map[string]bool{
	".gitignore": true,
	".go":        true,
	".mod":       true,
	".sum":       true,
	".toml":      true,
	".yaml":      true,
	".yml":       true,
}

type ModuleInfo struct {
	Path    string
	Dir     string
	PkgDirs []string // directories of packages imported from this module
}

type LicenseEntry struct {
	Name        string `json:"name"`
	Path        string `json:"path"`
	LicenseText string `json:"licenseText"`
}


Review comment (suggestion):
```suggestion
	"code.gitea.io/gitea":                 true,
```

Code after:
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

//go:build ignore

package main

import (
	"encoding/json"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"slices"
	"sort"
	"strings"
)

// regexp is based on go-license, excluding README and NOTICE
// https://github.com/google/go-licenses/blob/master/licenses/find.go
var licenseRe = regexp.MustCompile(`^(?i)((UN)?LICEN(S|C)E|COPYING).*$`)

// primaryLicenseRe matches exact primary license filenames without suffixes.
// When a directory has both primary and variant files (e.g. LICENSE and
// LICENSE.docs), only the primary files are kept.
var primaryLicenseRe = regexp.MustCompile(`^(?i)(LICEN[SC]E|COPYING)$`)

// ignoredNames are LicenseEntry.Name values to exclude from the output.
var ignoredNames = map[string]bool{
	"code.gitea.io/gitea":                 true,
	"code.gitea.io/gitea/options/license": true,
}

var excludedExt = map[string]bool{
	".gitignore": true,
	".go":        true,
	".mod":       true,
	".sum":       true,
	".toml":      true,
	".yaml":      true,
	".yml":       true,
}

type ModuleInfo struct {
	Path    string
	Dir     string
	PkgDirs []string // directories of packages imported from this module
}

type LicenseEntry struct {
Repository: go-gitea/gitea
File: tests/integration/heatmap_test.go (Go)

Code before:

	"github.com/stretchr/testify/assert"
)

func TestHeatmapEndpoints(t *testing.T) {
	defer tests.PrepareTestEnv(t)()

	// Mock time so fixture actions fall within the heatmap's time window
	timeutil.MockSet(time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC))
	defer timeutil.MockUnset()

	session := loginUser(t, "user2")

	t.Run("UserProfile", func(t *testing.T) {
		defer tests.PrintCurrentTest(t)()
		req := NewRequest(t, "GET", "/user2/-/heatmap")
		resp := session.MakeRequest(t, req, http.StatusOK)

		var result map[string]any
		DecodeJSON(t, resp, &result)
		assert.Contains(t, result, "heatmapData")
		assert.Contains(t, result, "totalContributions")
		assert.Positive(t, result["totalContributions"])
	})

	t.Run("OrgDashboard", func(t *testing.T) {
		defer tests.PrintCurrentTest(t)()
		req := NewRequest(t, "GET", "/org/org3/dashboard/-/heatmap")
		resp := session.MakeRequest(t, req, http.StatusOK)

		var result map[string]any
		DecodeJSON(t, resp, &result)
		assert.Contains(t, result, "heatmapData")
		assert.Contains(t, result, "totalContributions")
	})

	t.Run("OrgTeamDashboard", func(t *testing.T) {
		defer tests.PrintCurrentTest(t)()
		req := NewRequest(t, "GET", "/org/org3/dashboard/team1/-/heatmap")
		resp := session.MakeRequest(t, req, http.StatusOK)

		var result map[string]any
		DecodeJSON(t, resp, &result)
		assert.Contains(t, result, "heatmapData")
		assert.Contains(t, result, "totalContributions")
	})
}


Review comment (suggestion):
```suggestion
	t.Run("UserDashboard", func(t *testing.T) {
```

Code after:

	"github.com/stretchr/testify/assert"
)

func TestHeatmapEndpoints(t *testing.T) {
	defer tests.PrepareTestEnv(t)()

	// Mock time so fixture actions fall within the heatmap's time window
	timeutil.MockSet(time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC))
	defer timeutil.MockUnset()

	session := loginUser(t, "user2")

	t.Run("UserProfile", func(t *testing.T) {
		defer tests.PrintCurrentTest(t)()
		req := NewRequest(t, "GET", "/user2/-/heatmap")
		resp := session.MakeRequest(t, req, http.StatusOK)

		var result map[string]any
		DecodeJSON(t, resp, &result)
		assert.Contains(t, result, "heatmapData")
		assert.Contains(t, result, "totalContributions")
		assert.Positive(t, result["totalContributions"])
	})

	t.Run("OrgDashboard", func(t *testing.T) {
		defer tests.PrintCurrentTest(t)()
		req := NewRequest(t, "GET", "/org/org3/dashboard/-/heatmap")
		resp := session.MakeRequest(t, req, http.StatusOK)

		var result map[string]any
		DecodeJSON(t, resp, &result)
		assert.Contains(t, result, "heatmapData")
		assert.Contains(t, result, "totalContributions")
	})

	t.Run("OrgTeamDashboard", func(t *testing.T) {
		defer tests.PrintCurrentTest(t)()
		req := NewRequest(t, "GET", "/org/org3/dashboard/-/heatmap/team1")
		resp := session.MakeRequest(t, req, http.StatusOK)

		var result map[string]any
		DecodeJSON(t, resp, &result)
		assert.Contains(t, result, "heatmapData")
		assert.Contains(t, result, "totalContributions")
	})
}
Repository: go-gitea/gitea
File: models/actions/task_test.go (Go)

Code before:
		},
		{
			name: "uses step",
			jobStep: &jobparser.Step{
				Uses: "actions/checkout@v4",
			},
			expected: "Run actions/checkout@v4",
		},
		{
			name: "single-line run",
			jobStep: &jobparser.Step{
				Run: "echo hello",
			},
			expected: "Run echo hello",
		},
		{
			name: "multi-line run",
			jobStep: &jobparser.Step{
				Run: "echo hello\necho world",
			},
			expected: "Run echo hello",
		},
		{
			name: "multi-line run block scalar", // run: |\n  echo hello\n  echo world\n
			jobStep: &jobparser.Step{
				Run: "echo hello\necho world\n",
			},
			expected: "Run echo hello",
		},
		{
			name: "multi-line run with leading newline",
			jobStep: &jobparser.Step{
				Run: "\n  echo hello\n  echo world",
			},
			expected: "Run echo hello",
		},
		{
			name: "multi-line run with CRLF",
			jobStep: &jobparser.Step{
				Run: "echo hello\r\necho world",
			},
			expected: "Run echo hello",
		},
		{
			name: "fallback to id",
			jobStep: &jobparser.Step{
				ID: "step-id",
			},
			expected: "Run step-id",
		},
		{

Review comment (suggestion):
```suggestion
				Run: "\necho hello\necho world\n",
```

Code after:
		},
		{
			name: "uses step",
			jobStep: &jobparser.Step{
				Uses: "actions/checkout@v4",
			},
			expected: "Run actions/checkout@v4",
		},
		{
			name: "single-line run",
			jobStep: &jobparser.Step{
				Run: "echo hello",
			},
			expected: "Run echo hello",
		},
		{
			name: "multi-line run block scalar",
			jobStep: &jobparser.Step{
				Run: "\n  echo hello  \r\n  echo world  \n  ",
			},
			expected: "Run echo hello",
		},
		{
			name: "fallback to id",
			jobStep: &jobparser.Step{
				ID: "step-id",
			},
			expected: "Run step-id",
		},
		{
			name: "very long name truncated",
			jobStep: &jobparser.Step{
				Name: strings.Repeat("a", 300),
			},
			expected: strings.Repeat("a", 252) + "…",
		},
		{
			name: "very long run truncated",
			jobStep: &jobparser.Step{
				Run: strings.Repeat("a", 300),
			},
			expected: "Run " + strings.Repeat("a", 248) + "…",
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := makeTaskStepDisplayName(tt.jobStep, 255)
			assert.Equal(t, tt.expected, result)
		})
	}
}
Repository: go-gitea/gitea
File: web_src/js/utils/color.ts (TypeScript)

Code before:
import {colord} from 'colord';
import type {AnyColor} from 'colord';

/** Returns relative luminance for a SRGB color - https://en.wikipedia.org/wiki/Relative_luminance */
// Keep this in sync with modules/util/color.go
function getRelativeLuminance(color: AnyColor): number {
  const {r, g, b} = colord(color).toRgb();
  return (0.2126729 * r + 0.7151522 * g + 0.072175 * b) / 255;
}

function useLightText(backgroundColor: AnyColor): boolean {
  return getRelativeLuminance(backgroundColor) < 0.453;
}

/** Given a background color, returns a black or white foreground color that the highest
 *  contrast ratio. */
// In the future, the APCA contrast function, or CSS `contrast-color` will be better.
// https://github.com/color-js/color.js/blob/eb7b53f7a13bb716ec8b28c7a56f052cd599acd9/src/contrast/APCA.js#L42
export function contrastColor(backgroundColor: AnyColor): string {
  return useLightText(backgroundColor) ? '#fff' : '#000';
}

function resolveColors(obj: Record<string, string>): Record<string, string> {
  const styles = window.getComputedStyle(document.documentElement);
  const getColor = (name: string) => styles.getPropertyValue(name).trim();
  return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, getColor(value)]));
}

export const chartJsColors = resolveColors({
  text: '--color-text',
  border: '--color-secondary-alpha-60',
  commits: '--color-primary-alpha-60',
  additions: '--color-green',
  deletions: '--color-red',
});


Review comment (suggestion):
```suggestion
/** Given a background color, returns a black or white foreground color with the highest contrast ratio. */
```

Code after:
import {colord} from 'colord';
import type {AnyColor} from 'colord';

/** Returns relative luminance for a SRGB color - https://en.wikipedia.org/wiki/Relative_luminance */
// Keep this in sync with modules/util/color.go
function getRelativeLuminance(color: AnyColor): number {
  const {r, g, b} = colord(color).toRgb();
  return (0.2126729 * r + 0.7151522 * g + 0.072175 * b) / 255;
}

function useLightText(backgroundColor: AnyColor): boolean {
  return getRelativeLuminance(backgroundColor) < 0.453;
}

/** Given a background color, returns a black or white foreground color with the highest contrast ratio. */
// In the future, the APCA contrast function, or CSS `contrast-color` will be better.
// https://github.com/color-js/color.js/blob/eb7b53f7a13bb716ec8b28c7a56f052cd599acd9/src/contrast/APCA.js#L42
export function contrastColor(backgroundColor: AnyColor): string {
  return useLightText(backgroundColor) ? '#fff' : '#000';
}

function resolveColors(obj: Record<string, string>): Record<string, string> {
  const styles = window.getComputedStyle(document.documentElement);
  const getColor = (name: string) => styles.getPropertyValue(name).trim();
  return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, getColor(value)]));
}

export const chartJsColors = resolveColors({
  text: '--color-text',
  border: '--color-secondary-alpha-60',
  commits: '--color-primary-alpha-60',
  additions: '--color-green',
  deletions: '--color-red',
});
Repository: go-gitea/gitea
File: web_src/js/modules/tippy.ts (TypeScript)

Code before:
    // for example, the "Copy Permalink" button in the "File View" page for the selected lines
    target = document.body;
    refClientRect = document.querySelector(`[aria-controls="${CSS.escape(popupTippyId)}"]`)?.getBoundingClientRect();
    refClientRect = refClientRect ?? new DOMRect(0, 0, 0, 0); // fallback to empty rect if not found, tippy doesn't accept null
  } else {
    // for example, the "Copy Link" button in the issue header dropdown menu
    target = target.closest('.ui.dropdown') ?? target;
    refClientRect = target.getBoundingClientRect();
    useHideTimeout = true;
  }
  const tooltipTippy = target._tippy ?? attachTooltip(target, content);
  tooltipTippy.setContent(content);
  tooltipTippy.setProps({getReferenceClientRect: () => refClientRect});
  if (!tooltipTippy.state.isShown) tooltipTippy.show();

  tooltipTippy.setProps({
    onHidden: (tippy) => {
      // reset the default tooltip content, if no default, then this temporary tooltip could be destroyed
      if (!attachTooltip(target)) {
        tippy.destroy();
      }
    },
  });

  // on elements where the tooltip is re-locacted like "Copy Link" inside fomantic dropdowns, tippy.js gets
  // no mouseOut event so we have to hide the tooltip manually.
  if (useHideTimeout) {
    setTimeout(() => {
      if (tooltipTippy.state.isVisible) tooltipTippy.hide();
    }, 1500);
  }
}

export function getAttachedTippyInstance(el: Element): Instance | null {
  return el._tippy ?? null;
}


Review comment (suggestion):
```suggestion
  // no mouseOut event and the tooltip stays visible, hide it with timeout.
```

Code after:
    target = document.body;
    refClientRect = document.querySelector(`[aria-controls="${CSS.escape(popupTippyId)}"]`)?.getBoundingClientRect();
    refClientRect = refClientRect ?? new DOMRect(0, 0, 0, 0); // fallback to empty rect if not found, tippy doesn't accept null
  } else {
    // for example, the "Copy Link" button in the issue header dropdown menu
    target = target.closest('.ui.dropdown') ?? target;
    refClientRect = target.getBoundingClientRect();
  }
  const tooltipTippy = target._tippy ?? attachTooltip(target, content);
  tooltipTippy.setContent(content);
  tooltipTippy.setProps({getReferenceClientRect: () => refClientRect});
  if (!tooltipTippy.state.isShown) tooltipTippy.show();

  tooltipTippy.setProps({
    onHidden: (tippy) => {
      // reset the default tooltip content, if no default, then this temporary tooltip could be destroyed
      if (!attachTooltip(target)) {
        tippy.destroy();
      }
    },
  });

  // on elements where the tooltip is re-located like "Copy Link" inside fomantic dropdowns, tippy.js gets
  // no `mouseout` event and the tooltip stays visible, hide it with timeout.
  if (!popupTippyId) {
    setTimeout(() => {
      if (tooltipTippy.state.isVisible) tooltipTippy.hide();
    }, 1500);
  }
}

export function getAttachedTippyInstance(el: Element): Instance | null {
  return el._tippy ?? null;
}
Repository: go-gitea/gitea
File: web_src/js/modules/tippy.ts (TypeScript)

Code before:
  if (popupTippyId) {
    // for example, the "Copy Permalink" button in the "File View" page for the selected lines
    target = document.body;
    refClientRect = document.querySelector(`[aria-controls="${CSS.escape(popupTippyId)}"]`)?.getBoundingClientRect();
    refClientRect = refClientRect ?? new DOMRect(0, 0, 0, 0); // fallback to empty rect if not found, tippy doesn't accept null
  } else {
    // for example, the "Copy Link" button in the issue header dropdown menu
    target = target.closest('.ui.dropdown') ?? target;
    refClientRect = target.getBoundingClientRect();
  }
  const tooltipTippy = target._tippy ?? attachTooltip(target, content);
  tooltipTippy.setContent(content);
  tooltipTippy.setProps({getReferenceClientRect: () => refClientRect});
  if (!tooltipTippy.state.isShown) tooltipTippy.show();

  tooltipTippy.setProps({
    onHidden: (tippy) => {
      // reset the default tooltip content, if no default, then this temporary tooltip could be destroyed
      if (!attachTooltip(target)) {
        tippy.destroy();
      }
    },
  });

  // on elements where the tooltip is re-located like "Copy Link" inside fomantic dropdowns, tippy.js gets
  // no mouseOut event and the tooltip stays visible, hide it with timeout.
  if (!popupTippyId) {
    setTimeout(() => {
      if (tooltipTippy.state.isVisible) tooltipTippy.hide();
    }, 1500);
  }
}

export function getAttachedTippyInstance(el: Element): Instance | null {
  return el._tippy ?? null;
}


Review comment (suggestion):
```suggestion
  // no `mouseout` event and the tooltip stays visible, hide it with timeout.
```

Code after:
  if (popupTippyId) {
    // for example, the "Copy Permalink" button in the "File View" page for the selected lines
    target = document.body;
    refClientRect = document.querySelector(`[aria-controls="${CSS.escape(popupTippyId)}"]`)?.getBoundingClientRect();
    refClientRect = refClientRect ?? new DOMRect(0, 0, 0, 0); // fallback to empty rect if not found, tippy doesn't accept null
  } else {
    // for example, the "Copy Link" button in the issue header dropdown menu
    target = target.closest('.ui.dropdown') ?? target;
    refClientRect = target.getBoundingClientRect();
  }
  const tooltipTippy = target._tippy ?? attachTooltip(target, content);
  tooltipTippy.setContent(content);
  tooltipTippy.setProps({getReferenceClientRect: () => refClientRect});
  if (!tooltipTippy.state.isShown) tooltipTippy.show();

  tooltipTippy.setProps({
    onHidden: (tippy) => {
      // reset the default tooltip content, if no default, then this temporary tooltip could be destroyed
      if (!attachTooltip(target)) {
        tippy.destroy();
      }
    },
  });

  // on elements where the tooltip is re-located like "Copy Link" inside fomantic dropdowns, tippy.js gets
  // no `mouseout` event and the tooltip stays visible, hide it with timeout.
  if (!popupTippyId) {
    setTimeout(() => {
      if (tooltipTippy.state.isVisible) tooltipTippy.hide();
    }, 1500);
  }
}

export function getAttachedTippyInstance(el: Element): Instance | null {
  return el._tippy ?? null;
}
Repository: godotengine/godot
File: editor/scene_tree_dock.cpp (C++)

Code before:
		} break;
		case TOOL_REPLACE: {
			if (!profile_allow_editing) {
				break;
			}

			if (!_validate_no_foreign()) {
				break;
			}

			if (!_validate_no_instance()) {
				break;
			}

			if (reset_create_dialog) {
				create_dialog->set_base_type("Node");
				reset_create_dialog = false;
			}

			Node *selected = scene_tree->get_selected();
			if (!selected && !editor_selection->get_selected_node_list().is_empty()) {
				selected = editor_selection->get_selected_node_list().front()->get();
			}

			if (selected) {
				create_dialog->popup_create(false, true, selected->get_class());
			}

		} break;
		case TOOL_EXTEND_SCRIPT: {
			attach_script_to_selected(true);
		} break;
		case TOOL_ATTACH_SCRIPT: {
			attach_script_to_selected(false);
		} break;
		case TOOL_DETACH_SCRIPT: {
			if (!profile_allow_script_editing) {
				break;
			}

			Array selection = editor_selection->get_selected_nodes();

			if (selection.is_empty()) {
				return;
			}

			editor_data->get_undo_redo().create_action(TTR("Detach Script"));
			editor_data->get_undo_redo().add_do_method(EditorNode::get_singleton(), "push_item", (Script *)nullptr);

			for (int i = 0; i < selection.size(); i++) {
				Node *n = Object::cast_to<Node>(selection[i]);

Review comment (suggestion):
```suggestion
			if (selected) {
				create_dialog->popup_create(false, true, selected->get_class(), selected->get_name());
			}
```

Code after:
		} break;
		case TOOL_REPLACE: {
			if (!profile_allow_editing) {
				break;
			}

			if (!_validate_no_foreign()) {
				break;
			}

			if (!_validate_no_instance()) {
				break;
			}

			if (reset_create_dialog) {
				create_dialog->set_base_type("Node");
				reset_create_dialog = false;
			}

			Node *selected = scene_tree->get_selected();
			if (!selected && !editor_selection->get_selected_node_list().is_empty()) {
				selected = editor_selection->get_selected_node_list().front()->get();
			}

			if (selected) {
				create_dialog->popup_create(false, true, selected->get_class(), selected->get_name());
			}
		} break;
		case TOOL_EXTEND_SCRIPT: {
			attach_script_to_selected(true);
		} break;
		case TOOL_ATTACH_SCRIPT: {
			attach_script_to_selected(false);
		} break;
		case TOOL_DETACH_SCRIPT: {
			if (!profile_allow_script_editing) {
				break;
			}

			Array selection = editor_selection->get_selected_nodes();

			if (selection.is_empty()) {
				return;
			}

			editor_data->get_undo_redo().create_action(TTR("Detach Script"));
			editor_data->get_undo_redo().add_do_method(EditorNode::get_singleton(), "push_item", (Script *)nullptr);

			for (int i = 0; i < selection.size(); i++) {
				Node *n = Object::cast_to<Node>(selection[i]);
				Ref<Script> existing = n->get_script();
Repository: godotengine/godot
File: core/input/input.h (C/C++)

Code before:

#ifndef INPUT_H
#define INPUT_H

#include "core/input/input_event.h"
#include "core/object/object.h"
#include "core/os/thread_safe.h"

class Input : public Object {
	GDCLASS(Input, Object);
	_THREAD_SAFE_CLASS_

	static Input *singleton;

public:
	enum MouseMode {
		MOUSE_MODE_VISIBLE,
		MOUSE_MODE_HIDDEN,
		MOUSE_MODE_CAPTURED,
		MOUSE_MODE_CONFINED
	};

#undef CursorShape
	enum CursorShape {
		CURSOR_ARROW,
		CURSOR_IBEAM,
		CURSOR_POINTING_HAND,
		CURSOR_CROSS,
		CURSOR_WAIT,
		CURSOR_BUSY,
		CURSOR_DRAG,
		CURSOR_CAN_DROP,
		CURSOR_FORBIDDEN,
		CURSOR_VSIZE,
		CURSOR_HSIZE,
		CURSOR_BDIAGSIZE,
		CURSOR_FDIAGSIZE,
		CURSOR_MOVE,
		CURSOR_VSPLIT,
		CURSOR_HSPLIT,
		CURSOR_HELP,
		CURSOR_MAX
	};

	enum HatMask {
		HAT_MASK_CENTER = 0,
		HAT_MASK_UP = 1,
		HAT_MASK_RIGHT = 2,
		HAT_MASK_DOWN = 4,
		HAT_MASK_LEFT = 8,
	};

Review comment (suggestion):
It's a bit confusing that `MOUSE_MODE_CAPTURED_VISIBLE` is not bound, and that `MOUSE_MODE_GRABBED` exists but is not meant to be used. With this PR's changes, `set_mouse_mode(6)` would still be valid input.

Code after:

#ifndef INPUT_H
#define INPUT_H

#include "core/input/input_event.h"
#include "core/object/object.h"
#include "core/os/thread_safe.h"

class Input : public Object {
	GDCLASS(Input, Object);
	_THREAD_SAFE_CLASS_

	static Input *singleton;

public:
	enum MouseMode {
		MOUSE_MODE_VISIBLE,
		MOUSE_MODE_HIDDEN,
		MOUSE_MODE_CAPTURED,
		MOUSE_MODE_CONFINED,
		MOUSE_MODE_CONFINED_HIDDEN,
	};

#undef CursorShape
	enum CursorShape {
		CURSOR_ARROW,
		CURSOR_IBEAM,
		CURSOR_POINTING_HAND,
		CURSOR_CROSS,
		CURSOR_WAIT,
		CURSOR_BUSY,
		CURSOR_DRAG,
		CURSOR_CAN_DROP,
		CURSOR_FORBIDDEN,
		CURSOR_VSIZE,
		CURSOR_HSIZE,
		CURSOR_BDIAGSIZE,
		CURSOR_FDIAGSIZE,
		CURSOR_MOVE,
		CURSOR_VSPLIT,
		CURSOR_HSPLIT,
		CURSOR_HELP,
		CURSOR_MAX
	};

	enum HatMask {
		HAT_MASK_CENTER = 0,
		HAT_MASK_UP = 1,
		HAT_MASK_RIGHT = 2,
		HAT_MASK_DOWN = 4,
		HAT_MASK_LEFT = 8,