diff --git a/src/Bladeburner/Bladeburner.tsx b/src/Bladeburner/Bladeburner.tsx index e94934d1f..cd1d832de 100644 --- a/src/Bladeburner/Bladeburner.tsx +++ b/src/Bladeburner/Bladeburner.tsx @@ -35,6 +35,7 @@ import { joinFaction } from "../Faction/FactionHelpers"; import { WorkerScript } from "../Netscript/WorkerScript"; import { FactionNames } from "../Faction/data/FactionNames"; import { BlackOperationNames } from "./data/BlackOperationNames"; +import { KEY } from "../utils/helpers/keyCodes"; interface BlackOpsAttempt { error?: string; @@ -793,7 +794,7 @@ export class Bladeburner implements IBladeburner { if (c === '"') { // Double quotes const endQuote = command.indexOf('"', i + 1); - if (endQuote !== -1 && (endQuote === command.length - 1 || command.charAt(endQuote + 1) === " ")) { + if (endQuote !== -1 && (endQuote === command.length - 1 || command.charAt(endQuote + 1) === KEY.SPACE)) { args.push(command.substr(i + 1, endQuote - i - 1)); if (endQuote === command.length - 1) { start = i = endQuote + 1; @@ -805,7 +806,7 @@ export class Bladeburner implements IBladeburner { } else if (c === "'") { // Single quotes, same thing as above const endQuote = command.indexOf("'", i + 1); - if (endQuote !== -1 && (endQuote === command.length - 1 || command.charAt(endQuote + 1) === " ")) { + if (endQuote !== -1 && (endQuote === command.length - 1 || command.charAt(endQuote + 1) === KEY.SPACE)) { args.push(command.substr(i + 1, endQuote - i - 1)); if (endQuote === command.length - 1) { start = i = endQuote + 1; @@ -814,7 +815,7 @@ export class Bladeburner implements IBladeburner { } continue; } - } else if (c === " ") { + } else if (c === KEY.SPACE) { args.push(command.substr(start, i - start)); start = i + 1; } diff --git a/src/Bladeburner/ui/Console.tsx b/src/Bladeburner/ui/Console.tsx index 1a839a15e..c0600a4e3 100644 --- a/src/Bladeburner/ui/Console.tsx +++ b/src/Bladeburner/ui/Console.tsx @@ -89,7 +89,7 @@ export function Console(props: IProps): React.ReactElement { const consoleHistory = props.bladeburner.consoleHistory; - if (event.key === KEY.UPARROW) { + if (event.key === KEY.UP_ARROW) { // up let i = consoleHistoryIndex; const len = consoleHistory.length; @@ -109,7 +109,7 @@ export function Console(props: IProps): React.ReactElement { setCommand(prevCommand); } - if (event.key === KEY.DOWNARROW) { + if (event.key === KEY.DOWN_ARROW) { const i = consoleHistoryIndex; const len = consoleHistory.length; @@ -140,14 +140,16 @@ export function Console(props: IProps): React.ReactElement { return ( - + @@ -195,9 +197,7 @@ function Logs({ entries }: ILogProps): React.ReactElement { return ( - {entries && entries.map((log: any, i: number) => ( - - ))} + {entries && entries.map((log: any, i: number) => )} ); } diff --git a/src/Infiltration/ui/BackwardGame.tsx b/src/Infiltration/ui/BackwardGame.tsx index 6202aefcb..7cd7ed724 100644 --- a/src/Infiltration/ui/BackwardGame.tsx +++ b/src/Infiltration/ui/BackwardGame.tsx @@ -7,6 +7,7 @@ import { random } from "../utils"; import { interpolate } from "./Difficulty"; import { BlinkingCursor } from "./BlinkingCursor"; import Typography from "@mui/material/Typography"; +import { KEY } from "../../utils/helpers/keyCodes"; interface Difficulty { [key: string]: number; @@ -36,7 +37,7 @@ export function BackwardGame(props: IMinigameProps): React.ReactElement { function press(this: Document, event: KeyboardEvent): void { event.preventDefault(); - if (event.key === "Backspace") return; + if (event.key === KEY.BACKSPACE) return; const nextGuess = guess + event.key.toUpperCase(); if (!answer.startsWith(nextGuess)) props.onFailure(); else if (answer === nextGuess) props.onSuccess(); diff --git a/src/Infiltration/ui/BracketGame.tsx b/src/Infiltration/ui/BracketGame.tsx index 9bad60379..6c1aee432 100644 --- a/src/Infiltration/ui/BracketGame.tsx +++ b/src/Infiltration/ui/BracketGame.tsx @@ -7,6 +7,7 @@ import { random } from "../utils"; import { interpolate } from "./Difficulty"; import { BlinkingCursor } from "./BlinkingCursor"; import Typography from "@mui/material/Typography"; +import { KEY } from "../../utils/helpers/keyCodes"; interface Difficulty { [key: string]: number; @@ -29,28 +30,29 @@ const difficulties: { function generateLeftSide(difficulty: Difficulty): string { let str = ""; + const options = [KEY.OPEN_BRACKET, KEY.LESS_THAN, KEY.OPEN_PARENTHESIS, KEY.OPEN_BRACE]; const length = random(difficulty.min, difficulty.max); for (let i = 0; i < length; i++) { - str += ["[", "<", "(", "{"][Math.floor(Math.random() * 4)]; + str += options[Math.floor(Math.random() * 4)]; } return str; } function getChar(event: KeyboardEvent): string { - if (event.key === ")") return ")"; - if (event.key === "]") return "]"; - if (event.key === "}") return "}"; - if (event.key === ">") return ">"; + if (event.key === KEY.CLOSE_PARENTHESIS) return KEY.CLOSE_PARENTHESIS; + if (event.key === KEY.CLOSE_BRACKET) return KEY.CLOSE_BRACKET; + if (event.key === KEY.CLOSE_BRACE) return KEY.CLOSE_BRACE; + if (event.key === KEY.GREATER_THAN) return KEY.GREATER_THAN; return ""; } function match(left: string, right: string): boolean { return ( - (left === "[" && right === "]") || - (left === "<" && right === ">") || - (left === "(" && right === ")") || - (left === "{" && right === "}") + (left === KEY.OPEN_BRACKET && right === KEY.CLOSE_BRACKET) || + (left === KEY.LESS_THAN && right === KEY.GREATER_THAN) || + (left === KEY.OPEN_PARENTHESIS && right === KEY.CLOSE_PARENTHESIS) || + (left === KEY.OPEN_BRACE && right === KEY.CLOSE_BRACE) ); } diff --git a/src/Infiltration/ui/BribeGame.tsx b/src/Infiltration/ui/BribeGame.tsx index e5fa424df..f7ff526a8 100644 --- a/src/Infiltration/ui/BribeGame.tsx +++ b/src/Infiltration/ui/BribeGame.tsx @@ -5,6 +5,8 @@ import { KeyHandler } from "./KeyHandler"; import { GameTimer } from "./GameTimer"; import { interpolate } from "./Difficulty"; import Typography from "@mui/material/Typography"; +import { KEY } from "../../utils/helpers/keyCodes"; +import { downArrowSymbol, upArrowSymbol } from "../utils"; interface Difficulty { [key: string]: number; @@ -34,15 +36,15 @@ export function BribeGame(props: IMinigameProps): React.ReactElement { function press(this: Document, event: KeyboardEvent): void { event.preventDefault(); const k = event.key; - if (k === " ") { + if (k === KEY.SPACE) { if (positive.includes(choices[index])) props.onSuccess(); else props.onFailure(); return; } let newIndex = index; - if (["ArrowUp", "w", "ArrowRight", "d"].includes(k)) newIndex++; - if (["ArrowDown", "s", "ArrowLeft", "a"].includes(k)) newIndex--; + if ([KEY.UP_ARROW, KEY.W, KEY.RIGHT_ARROW, KEY.D].map((key) => key as string).includes(k)) newIndex++; + if ([KEY.DOWN_ARROW, KEY.S, KEY.LEFT_ARROW, KEY.A].map((key) => key as string).includes(k)) newIndex--; while (newIndex < 0) newIndex += choices.length; while (newIndex > choices.length - 1) newIndex -= choices.length; setIndex(newIndex); @@ -57,13 +59,13 @@ export function BribeGame(props: IMinigameProps): React.ReactElement { - ↑ + {upArrowSymbol} {choices[index]} - ↓ + {downArrowSymbol} diff --git a/src/Infiltration/ui/CheatCodeGame.tsx b/src/Infiltration/ui/CheatCodeGame.tsx index 68fd61329..38cb80e6a 100644 --- a/src/Infiltration/ui/CheatCodeGame.tsx +++ b/src/Infiltration/ui/CheatCodeGame.tsx @@ -3,7 +3,7 @@ import Grid from "@mui/material/Grid"; import { IMinigameProps } from "./IMinigameProps"; import { KeyHandler } from "./KeyHandler"; import { GameTimer } from "./GameTimer"; -import { random, getArrow } from "../utils"; +import { random, getArrow, rightArrowSymbol, leftArrowSymbol, upArrowSymbol, downArrowSymbol } from "../utils"; import { interpolate } from "./Difficulty"; import Typography from "@mui/material/Typography"; @@ -56,7 +56,7 @@ export function CheatCodeGame(props: IMinigameProps): React.ReactElement { } function generateCode(difficulty: Difficulty): string { - const arrows = ["←", "→", "↑", "↓"]; + const arrows = [leftArrowSymbol, rightArrowSymbol, upArrowSymbol, downArrowSymbol]; let code = ""; for (let i = 0; i < random(difficulty.min, difficulty.max); i++) { let arrow = arrows[Math.floor(4 * Math.random())]; diff --git a/src/Infiltration/ui/Cyberpunk2077Game.tsx b/src/Infiltration/ui/Cyberpunk2077Game.tsx index d0c8736b6..ab63eccac 100644 --- a/src/Infiltration/ui/Cyberpunk2077Game.tsx +++ b/src/Infiltration/ui/Cyberpunk2077Game.tsx @@ -4,8 +4,9 @@ import { IMinigameProps } from "./IMinigameProps"; import { KeyHandler } from "./KeyHandler"; import { GameTimer } from "./GameTimer"; import { interpolate } from "./Difficulty"; -import { getArrow } from "../utils"; +import { downArrowSymbol, getArrow, leftArrowSymbol, rightArrowSymbol, upArrowSymbol } from "../utils"; import Typography from "@mui/material/Typography"; +import { KEY } from "../../utils/helpers/keyCodes"; interface Difficulty { [key: string]: number; @@ -41,16 +42,16 @@ export function Cyberpunk2077Game(props: IMinigameProps): React.ReactElement { const move = [0, 0]; const arrow = getArrow(event); switch (arrow) { - case "↑": + case upArrowSymbol: move[1]--; break; - case "←": + case leftArrowSymbol: move[0]--; break; - case "↓": + case downArrowSymbol: move[1]++; break; - case "→": + case rightArrowSymbol: move[0]++; break; } @@ -59,7 +60,7 @@ export function Cyberpunk2077Game(props: IMinigameProps): React.ReactElement { next[1] = (next[1] + grid.length) % grid.length; setPos(next); - if (event.key === " ") { + if (event.key === KEY.SPACE) { const selected = grid[pos[1]][pos[0]]; const expected = answer[index]; if (selected !== expected) { diff --git a/src/Infiltration/ui/MinesweeperGame.tsx b/src/Infiltration/ui/MinesweeperGame.tsx index 532c654ee..fd6c78f9e 100644 --- a/src/Infiltration/ui/MinesweeperGame.tsx +++ b/src/Infiltration/ui/MinesweeperGame.tsx @@ -4,8 +4,9 @@ import { IMinigameProps } from "./IMinigameProps"; import { KeyHandler } from "./KeyHandler"; import { GameTimer } from "./GameTimer"; import { interpolate } from "./Difficulty"; -import { getArrow } from "../utils"; +import { downArrowSymbol, getArrow, leftArrowSymbol, rightArrowSymbol, upArrowSymbol } from "../utils"; import Typography from "@mui/material/Typography"; +import { KEY } from "../../utils/helpers/keyCodes"; interface Difficulty { [key: string]: number; @@ -42,16 +43,16 @@ export function MinesweeperGame(props: IMinigameProps): React.ReactElement { const move = [0, 0]; const arrow = getArrow(event); switch (arrow) { - case "↑": + case upArrowSymbol: move[1]--; break; - case "←": + case leftArrowSymbol: move[0]--; break; - case "↓": + case downArrowSymbol: move[1]++; break; - case "→": + case rightArrowSymbol: move[0]++; break; } @@ -60,7 +61,7 @@ export function MinesweeperGame(props: IMinigameProps): React.ReactElement { next[1] = (next[1] + minefield.length) % minefield.length; setPos(next); - if (event.key == " ") { + if (event.key == KEY.SPACE) { if (!minefield[pos[1]][pos[0]]) { props.onFailure(); return; diff --git a/src/Infiltration/ui/SlashGame.tsx b/src/Infiltration/ui/SlashGame.tsx index 5aa633f78..2926052ef 100644 --- a/src/Infiltration/ui/SlashGame.tsx +++ b/src/Infiltration/ui/SlashGame.tsx @@ -5,6 +5,7 @@ import { KeyHandler } from "./KeyHandler"; import { GameTimer } from "./GameTimer"; import { interpolate } from "./Difficulty"; import Typography from "@mui/material/Typography"; +import { KEY } from "../../utils/helpers/keyCodes"; interface Difficulty { [key: string]: number; @@ -30,7 +31,7 @@ export function SlashGame(props: IMinigameProps): React.ReactElement { function press(this: Document, event: KeyboardEvent): void { event.preventDefault(); - if (event.key !== " ") return; + if (event.key !== KEY.SPACE) return; if (phase !== 2) { props.onFailure(); } else { diff --git a/src/Infiltration/ui/WireCuttingGame.tsx b/src/Infiltration/ui/WireCuttingGame.tsx index 875f42641..efd1c2eb8 100644 --- a/src/Infiltration/ui/WireCuttingGame.tsx +++ b/src/Infiltration/ui/WireCuttingGame.tsx @@ -6,6 +6,7 @@ import { KeyHandler } from "./KeyHandler"; import { GameTimer } from "./GameTimer"; import { random } from "../utils"; import { interpolate } from "./Difficulty"; +import { KEY } from "../../utils/helpers/keyCodes"; interface Difficulty { [key: string]: number; @@ -27,7 +28,7 @@ const difficulties: { Impossible: { timer: 4000, wiresmin: 9, wiresmax: 9, rules: 4 }, }; -const types = ["|", ".", "/", "-", "█", "#"]; +const types = [KEY.PIPE, KEY.DOT, KEY.FORWARD_SLASH, KEY.HYPHEN, "█", KEY.HASH]; const colors = ["red", "#FFC107", "blue", "white"]; @@ -61,6 +62,10 @@ export function WireCuttingGame(props: IMinigameProps): React.ReactElement { const [cutWires, setCutWires] = useState(new Array(wires.length).fill(false)); const [questions] = useState(generateQuestion(wires, difficulty)); + function checkWire(wireNum: number): boolean { + return questions.some((q) => q.shouldCut(wires[wireNum - 1], wireNum - 1)); + } + function press(this: Document, event: KeyboardEvent): void { event.preventDefault(); const wireNum = parseInt(event.key); @@ -69,7 +74,7 @@ export function WireCuttingGame(props: IMinigameProps): React.ReactElement { setCutWires((old) => { const next = [...old]; next[wireNum - 1] = true; - if (!questions.some((q) => q.shouldCut(wires[wireNum - 1], wireNum - 1))) { + if (checkWire(wireNum)) { props.onFailure(); } diff --git a/src/Infiltration/utils.ts b/src/Infiltration/utils.ts index cdbce68d9..d338423d5 100644 --- a/src/Infiltration/utils.ts +++ b/src/Infiltration/utils.ts @@ -1,21 +1,46 @@ +import { KEY } from "../utils/helpers/keyCodes"; + export function random(min: number, max: number): number { return Math.random() * (max - min) + min; } +export const upArrowSymbol = "↑"; +export const downArrowSymbol = "↑"; +export const leftArrowSymbol = "↑"; +export const rightArrowSymbol = "↑"; + export function getArrow(event: KeyboardEvent): string { switch (event.key) { - case "ArrowUp": - case "w": - return "↑"; - case "ArrowLeft": - case "a": - return "←"; - case "ArrowDown": - case "s": - return "↓"; - case "ArrowRight": - case "d": - return "→"; + case KEY.UP_ARROW: + case KEY.W: + return upArrowSymbol; + case KEY.LEFT_ARROW: + case KEY.A: + return leftArrowSymbol; + case KEY.DOWN_ARROW: + case KEY.S: + return downArrowSymbol; + case KEY.RIGHT_ARROW: + case KEY.D: + return rightArrowSymbol; + } + return ""; +} + +export function getInverseArrow(event: KeyboardEvent): string { + switch (event.key) { + case KEY.DOWN_ARROW: + case KEY.S: + return upArrowSymbol; + case KEY.RIGHT_ARROW: + case KEY.D: + return leftArrowSymbol; + case KEY.UP_ARROW: + case KEY.W: + return downArrowSymbol; + case KEY.LEFT_ARROW: + case KEY.A: + return rightArrowSymbol; } return ""; } diff --git a/src/Sidebar/ui/SidebarRoot.tsx b/src/Sidebar/ui/SidebarRoot.tsx index 81f724304..c13b7e81e 100644 --- a/src/Sidebar/ui/SidebarRoot.tsx +++ b/src/Sidebar/ui/SidebarRoot.tsx @@ -276,7 +276,7 @@ export function SidebarRoot(props: IProps): React.ReactElement { function handleShortcuts(this: Document, event: KeyboardEvent): any { if (Settings.DisableHotkeys) return; if ((props.player.isWorking && props.player.focus) || redPillFlag) return; - if (event.key === "t" && event.altKey) { + if (event.key === KEY.T && event.altKey) { event.preventDefault(); clickTerminal(); } else if (event.key === KEY.C && event.altKey) { @@ -522,7 +522,9 @@ export function SidebarRoot(props: IProps): React.ReactElement { - + @@ -570,7 +572,9 @@ export function SidebarRoot(props: IProps): React.ReactElement { > - + diff --git a/src/Terminal/Parser.ts b/src/Terminal/Parser.ts index 80c3654b4..fc38c1ba3 100644 --- a/src/Terminal/Parser.ts +++ b/src/Terminal/Parser.ts @@ -1,3 +1,4 @@ +import { KEY } from "../utils/helpers/keyCodes"; import { substituteAliases } from "../Alias"; // Helper function that checks if an argument (which is a string) is a valid number function isNumber(str: string): boolean { @@ -55,11 +56,11 @@ export function ParseCommand(command: string): (string | number | boolean)[] { } const c = command.charAt(i); - if (c === '"') { + if (c === KEY.DOUBLE_QUOTE) { // Double quotes - if (!escaped && prevChar === " ") { - const endQuote = command.indexOf('"', i + 1); - if (endQuote !== -1 && (endQuote === command.length - 1 || command.charAt(endQuote + 1) === " ")) { + if (!escaped && prevChar === KEY.SPACE) { + const endQuote = command.indexOf(KEY.DOUBLE_QUOTE, i + 1); + if (endQuote !== -1 && (endQuote === command.length - 1 || command.charAt(endQuote + 1) === KEY.SPACE)) { args.push(command.substr(i + 1, endQuote - i - 1)); if (endQuote === command.length - 1) { start = i = endQuote + 1; @@ -69,15 +70,15 @@ export function ParseCommand(command: string): (string | number | boolean)[] { continue; } } else if (inQuote === ``) { - inQuote = `"`; - } else if (inQuote === `"`) { - inQuote = ``; - } - } else if (c === "'") { + inQuote = KEY.DOUBLE_QUOTE; + } else if (inQuote === KEY.DOUBLE_QUOTE) { + inQuote = ``; + } + } else if (c === KEY.QUOTE) { // Single quotes, same thing as above - if (!escaped && prevChar === " ") { - const endQuote = command.indexOf("'", i + 1); - if (endQuote !== -1 && (endQuote === command.length - 1 || command.charAt(endQuote + 1) === " ")) { + if (!escaped && prevChar === KEY.SPACE) { + const endQuote = command.indexOf(KEY.QUOTE, i + 1); + if (endQuote !== -1 && (endQuote === command.length - 1 || command.charAt(endQuote + 1) === KEY.SPACE)) { args.push(command.substr(i + 1, endQuote - i - 1)); if (endQuote === command.length - 1) { start = i = endQuote + 1; @@ -87,11 +88,11 @@ export function ParseCommand(command: string): (string | number | boolean)[] { continue; } } else if (inQuote === ``) { - inQuote = `'`; - } else if (inQuote === `'`) { - inQuote = ``; - } - } else if (c === " " && inQuote === ``) { + inQuote = KEY.QUOTE; + } else if (inQuote === KEY.QUOTE) { + inQuote = ``; + } + } else if (c === KEY.SPACE && inQuote === ``) { const arg = command.substr(start, i - start); // If this is a number, convert it from a string to number diff --git a/src/Terminal/ui/TerminalInput.tsx b/src/Terminal/ui/TerminalInput.tsx index f84623535..afaf7604b 100644 --- a/src/Terminal/ui/TerminalInput.tsx +++ b/src/Terminal/ui/TerminalInput.tsx @@ -97,7 +97,7 @@ export function TerminalInput({ terminal, router, player }: IProps): React.React break; case "deletewordbefore": // Delete rest of word before the cursor for (let delStart = start - 1; delStart > -2; --delStart) { - if ((inputText.charAt(delStart) === " " || delStart === -1) && delStart !== start - 1) { + if ((inputText.charAt(delStart) === KEY.SPACE || delStart === -1) && delStart !== start - 1) { saveValue(inputText.substr(0, delStart + 1) + inputText.substr(start), () => { // Move cursor to correct location // foo bar |baz bum --> foo |baz bum @@ -110,7 +110,7 @@ export function TerminalInput({ terminal, router, player }: IProps): React.React break; case "deletewordafter": // Delete rest of word after the cursor, including trailing space for (let delStart = start + 1; delStart <= value.length + 1; ++delStart) { - if (inputText.charAt(delStart) === " " || delStart === value.length + 1) { + if (inputText.charAt(delStart) === KEY.SPACE || delStart === value.length + 1) { saveValue(inputText.substr(0, start) + inputText.substr(delStart + 1), () => { // Move cursor to correct location // foo bar |baz bum --> foo bar |bum @@ -151,7 +151,7 @@ export function TerminalInput({ terminal, router, player }: IProps): React.React break; case "prevword": for (let i = start - 2; i >= 0; --i) { - if (ref.value.charAt(i) === " ") { + if (ref.value.charAt(i) === KEY.SPACE) { ref.setSelectionRange(i + 1, i + 1); return; } @@ -163,7 +163,7 @@ export function TerminalInput({ terminal, router, player }: IProps): React.React break; case "nextword": for (let i = start + 1; i <= inputLength; ++i) { - if (ref.value.charAt(i) === " ") { + if (ref.value.charAt(i) === KEY.SPACE) { ref.setSelectionRange(i, i); return; } @@ -262,7 +262,7 @@ export function TerminalInput({ terminal, router, player }: IProps): React.React } // Select previous command. - if (event.key === KEY.UPARROW || (Settings.EnableBashHotkeys && event.key === "p" && event.ctrlKey)) { + if (event.key === KEY.UP_ARROW || (Settings.EnableBashHotkeys && event.key === KEY.P && event.ctrlKey)) { if (Settings.EnableBashHotkeys) { event.preventDefault(); } @@ -290,7 +290,7 @@ export function TerminalInput({ terminal, router, player }: IProps): React.React } // Select next command - if (event.key === KEY.DOWNARROW || (Settings.EnableBashHotkeys && event.key === "m" && event.ctrlKey)) { + if (event.key === KEY.DOWN_ARROW || (Settings.EnableBashHotkeys && event.key === KEY.M && event.ctrlKey)) { if (Settings.EnableBashHotkeys) { event.preventDefault(); } diff --git a/src/utils/helpers/keyCodes.ts b/src/utils/helpers/keyCodes.ts index a03290a26..29231dfec 100644 --- a/src/utils/helpers/keyCodes.ts +++ b/src/utils/helpers/keyCodes.ts @@ -8,10 +8,29 @@ export enum KEY { ENTER = "Enter", ESC = "Escape", TAB = "Tab", - UPARROW = "ArrowUp", - DOWNARROW = "ArrowDown", - LEFTARROW = "ArrowLeft", - RIGHTARROW = "ArrowRight", + SPACE = " ", + BACKSPACE = "Backspace", + UP_ARROW = "ArrowUp", + DOWN_ARROW = "ArrowDown", + LEFT_ARROW = "ArrowLeft", + RIGHT_ARROW = "ArrowRight", + + QUOTE = "'", + DOUBLE_QUOTE = '"', + OPEN_BRACKET = "[", + CLOSE_BRACKET = "]", + LESS_THAN = "<", + GREATER_THAN = ">", + OPEN_PARENTHESIS = "(", + CLOSE_PARENTHESIS = ")", + OPEN_BRACE = "{", + CLOSE_BRACE = "}", + + PIPE = "|", + DOT = ".", + FORWARD_SLASH = "/", + HYPHEN = "-", + HASH = "#", k0 = "0", k1 = "1",