cubing 0.49.1 → 0.49.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -912,6 +912,7 @@ var giiKERConfig = {
|
|
|
912
912
|
// Suspected prefixes GiY, Gi3
|
|
913
913
|
{ namePrefix: "Gi" },
|
|
914
914
|
{ namePrefix: "Mi" },
|
|
915
|
+
{ namePrefix: "Hi-" },
|
|
915
916
|
{ services: ["0000aadb-0000-1000-8000-00805f9b34fb"] },
|
|
916
917
|
{ services: ["0000aaaa-0000-1000-8000-00805f9b34fb"] },
|
|
917
918
|
{ services: ["0000fe95-0000-1000-8000-00805f9b34fb"] }
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/cubing/bluetooth/debug.ts", "../../../../src/cubing/bluetooth/transformer.ts", "../../../../src/cubing/bluetooth/smart-puzzle/bluetooth-puzzle.ts", "../../../../src/cubing/bluetooth/keyboard.ts", "../../../../src/cubing/bluetooth/connect/index.ts", "../../../../src/cubing/bluetooth/smart-puzzle/gan.ts", "../../../../src/cubing/vendor/public-domain/unsafe-raw-aes/unsafe-raw-aes.ts", "../../../../src/cubing/bluetooth/smart-puzzle/giiker.ts", "../../../../src/cubing/bluetooth/smart-puzzle/gocube.ts", "../../../../src/cubing/bluetooth/smart-puzzle/endianness.ts", "../../../../src/cubing/bluetooth/smart-puzzle/Heykube.ts", "../../../../src/cubing/bluetooth/smart-puzzle/connect.ts", "../../../../src/cubing/bluetooth/smart-robot/GanRobot.ts", "../../../../src/cubing/bluetooth/smart-robot/index.ts", "../../../../src/cubing/bluetooth/smart-timer/GanTimer.ts", "../../../../src/cubing/bluetooth/smart-timer/index.ts"],
|
|
4
|
-
"sourcesContent": ["let DEBUG_LOGGING_ENABLED = false;\n\nexport function enableDebugLogging(enable: boolean): void {\n DEBUG_LOGGING_ENABLED = enable;\n}\n\n// TODO: Remove this.\nexport function debugLog(...args: any[]): void {\n if (!DEBUG_LOGGING_ENABLED) {\n return;\n }\n\n if (console.info) {\n console.info(...args);\n } else {\n console.log(...args);\n }\n}\n", "import { Quaternion, Vector3 } from \"three\";\nimport type {\n AlgLeafEvent,\n OrientationEvent,\n} from \"./smart-puzzle/bluetooth-puzzle\";\n\n// TODO: Combine orientation and alg leaves into a single event to handle quaternion remapping.\nexport interface StreamTransformer {\n // Modifies the input.\n transformAlgLeaf(algLeafEvent: AlgLeafEvent): void;\n // Modifies the input.\n transformOrientation(orientationEvent: OrientationEvent): void;\n}\n\nfunction maxAxis(v: Vector3): string {\n const maxVal = Math.max(Math.abs(v.x), Math.abs(v.y), Math.abs(v.z));\n switch (maxVal) {\n case v.x:\n return \"x\";\n case -v.x:\n return \"-x\";\n case v.y:\n return \"y\";\n case -v.y:\n return \"-y\";\n case v.z:\n return \"z\";\n case -v.z:\n return \"-z\";\n default:\n throw new Error(\"Uh-oh.\");\n }\n}\n\nconst s2 = Math.sqrt(0.5);\n\nconst m: { [s: string]: Quaternion } = {\n \"y z\": new Quaternion(0, 0, 0, 1),\n \"-z y\": new Quaternion(s2, 0, 0, s2),\n \"x z\": new Quaternion(0, 0, -s2, s2),\n \"-x z\": new Quaternion(0, 0, s2, s2),\n};\n\nexport class BasicRotationTransformer implements StreamTransformer {\n // private reorientQuat = new Quaternion();\n\n public transformAlgLeaf(_algLeafEvent: AlgLeafEvent): void {\n // Nothing to do.\n }\n\n public transformOrientation(orientationEvent: OrientationEvent): void {\n const { x, y, z, w } = orientationEvent.quaternion;\n const quat = new Quaternion(x, y, z, w);\n\n const U = new Vector3(0, 1, 0);\n const F = new Vector3(0, 0, 1);\n const maxU = maxAxis(U.applyQuaternion(quat));\n const maxF = maxAxis(F.applyQuaternion(quat));\n\n const oriQuat = m[`${maxU} ${maxF}`] || m[\"y z\"];\n\n console.log(quat);\n console.log(oriQuat);\n const q2 = quat.premultiply(oriQuat);\n\n // console.log(maxAxis(U.applyQuaternion(quat)), maxAxis(F.applyQuaternion(quat)));\n console.log(q2);\n\n orientationEvent.quaternion = quat;\n\n console.log(orientationEvent.quaternion);\n }\n}\n", "import type { AlgLeaf } from \"../../alg/alg-nodes/AlgNode\";\nimport type { KPattern } from \"../../kpuzzle/KPattern\";\nimport {\n BasicRotationTransformer,\n type StreamTransformer,\n} from \"../transformer\";\n\n/******** BluetoothPuzzle ********/\n\n// TODO: Use actual `CustomEvent`s?\n// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent\n/** @category Smart Puzzles */\nexport interface AlgLeafEvent {\n latestAlgLeaf: AlgLeaf;\n timeStamp: number;\n debug?: Record<string, unknown>;\n pattern?: KPattern;\n quaternion?: any; // TODO: Unused\n}\n\n// TODO: Only use the `quaternion` field in the `AlgLeafEvent`?\n/** @category Smart Puzzles */\nexport interface OrientationEvent {\n quaternion: {\n x: number;\n y: number;\n z: number;\n w: number;\n };\n timeStamp: number;\n debug?: Record<string, unknown>;\n}\n\nexport interface BluetoothConfig<T> {\n connect: (\n server: BluetoothRemoteGATTServer,\n device?: BluetoothDevice,\n ) => Promise<T>;\n // TODO: Can we reuse `filters`?\n prefixes: string[]; // `[\"\"]` for GiiKER\n filters: BluetoothLEScanFilter[];\n optionalServices: BluetoothServiceUUID[];\n}\n\n// TODO: Expose device name (and/or globally unique identifier)?\n\n/** @category Smart Puzzles */\nexport abstract class BluetoothPuzzle extends EventTarget {\n public transformers: StreamTransformer[] = [];\n protected listeners: Array<(e: AlgLeafEvent) => void> = []; // TODO: type\n protected orientationListeners: Array<(e: OrientationEvent) => void> = []; // TODO: type\n\n public abstract name(): string | undefined;\n public abstract disconnect(): void; // TODO: Can we make this reutrn (async) on success?\n\n // TODO: require subclasses to implement this?\n public async getPattern(): Promise<KPattern> {\n throw new Error(\"cannot get pattern\");\n }\n\n public addAlgLeafListener(listener: (e: AlgLeafEvent) => void): void {\n this.listeners.push(listener);\n }\n\n public addOrientationListener(listener: (e: OrientationEvent) => void): void {\n this.orientationListeners.push(listener);\n }\n\n public experimentalAddBasicRotationTransformer(): void {\n this.transformers.push(new BasicRotationTransformer());\n }\n\n protected dispatchAlgLeaf(algLeaf: AlgLeafEvent): void {\n for (const transformer of this.transformers) {\n transformer.transformAlgLeaf(algLeaf);\n }\n for (const l of this.listeners) {\n l(algLeaf);\n }\n }\n\n protected dispatchOrientation(orientationEvent: OrientationEvent): void {\n for (const transformer of this.transformers) {\n transformer.transformOrientation(orientationEvent);\n }\n const { x, y, z, w } = orientationEvent.quaternion;\n // TODO: can we avoid mutating the source event?\n orientationEvent.quaternion = {\n x,\n y,\n z,\n w,\n };\n for (const l of this.orientationListeners) {\n // TODO: Convert quaternion.\n l(orientationEvent);\n }\n }\n}\n", "import { Alg, keyToMove } from \"../alg\";\nimport type { KPuzzle } from \"../kpuzzle\";\nimport type { KPattern } from \"../kpuzzle/KPattern\";\nimport { puzzles } from \"../puzzles\";\nimport { BluetoothPuzzle } from \"./smart-puzzle/bluetooth-puzzle\";\n\n/** @category Keyboard Puzzles */\nexport class KeyboardPuzzle extends BluetoothPuzzle {\n private puzzle: Promise<KPuzzle> = puzzles[\"3x3x3\"].kpuzzle();\n private pattern: Promise<KPattern> = (async () =>\n (await this.puzzle).defaultPattern())();\n\n listener: (e: KeyboardEvent) => Promise<void>;\n\n // TODO: Decide on the right arguments.\n constructor(private target: Element) {\n super();\n // TODO: Filter out repeated keydown?\n this.listener = this.onKeyDown.bind(this);\n target.addEventListener(\"keydown\", this.listener);\n }\n\n public name(): string | undefined {\n return \"Keyboard Input\";\n }\n\n disconnect() {\n this.target.removeEventListener(\"keydown\", this.listener);\n }\n\n public override async getPattern(): Promise<KPattern> {\n return this.pattern;\n }\n\n private async onKeyDown(e: KeyboardEvent): Promise<void> {\n if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {\n return;\n }\n\n const algLeaf = keyToMove(e);\n if (algLeaf) {\n const newPattern = (await this.pattern).applyAlg(new Alg([algLeaf])); // TODO\n this.pattern = Promise.resolve(newPattern);\n this.dispatchAlgLeaf({\n latestAlgLeaf: algLeaf,\n timeStamp: e.timeStamp,\n pattern: newPattern,\n });\n e.preventDefault();\n }\n }\n}\n\n// TODO: Type\n/** @category Keyboard Puzzles */\nexport async function debugKeyboardConnect(\n target: any = window,\n): Promise<KeyboardPuzzle> {\n return new KeyboardPuzzle(target);\n}\n", "import { debugLog } from \"../debug\";\nimport type { BluetoothConfig } from \"../smart-puzzle/bluetooth-puzzle\";\n\n/******** requestOptions ********/\n\nfunction requestOptions<T>(\n configs: BluetoothConfig<T>[],\n acceptAllDevices: boolean = false,\n): RequestDeviceOptions {\n const options = acceptAllDevices\n ? {\n acceptAllDevices: true,\n optionalServices: [] as BluetoothServiceUUID[],\n }\n : {\n filters: [] as BluetoothLEScanFilter[],\n optionalServices: [] as BluetoothServiceUUID[],\n };\n for (const config of configs) {\n if (!acceptAllDevices) {\n options.filters = options.filters!.concat(config.filters);\n }\n options.optionalServices = options.optionalServices.concat(\n config.optionalServices,\n );\n }\n debugLog({ requestOptions: options });\n return options;\n}\n\n/******** connect() ********/\n\nexport interface BluetoothConnectOptions {\n acceptAllDevices?: boolean;\n}\n\n// We globally track the number of connection failures,\n// in order to offer the user recourse (accept all devices) if they're having issues.\n// This allows us to future-proof situations where a device might not show up in\n// the chooser, but works if we connect.\nlet consecutiveFailures = 0;\nconst MAX_FAILURES_BEFORE_ACCEPT_ALL_FALLBACK = 2;\n\n// TODO: Debug options to allow connecting to any device?\nexport async function bluetoothConnect<T>(\n configs: BluetoothConfig<T>[],\n options: BluetoothConnectOptions = {},\n): Promise<T> {\n debugLog(\"Attempting to pair.\");\n let device: BluetoothDevice;\n try {\n let acceptAllDevices = options.acceptAllDevices;\n if (\n !acceptAllDevices &&\n consecutiveFailures >= MAX_FAILURES_BEFORE_ACCEPT_ALL_FALLBACK\n ) {\n console.info(\n `The last ${MAX_FAILURES_BEFORE_ACCEPT_ALL_FALLBACK} Bluetooth puzzle connection attempts failed. This time, the Bluetooth prompt will show all possible devices.`,\n );\n acceptAllDevices = true;\n }\n device = await navigator.bluetooth.requestDevice(\n requestOptions<T>(configs, acceptAllDevices),\n );\n consecutiveFailures = 0;\n } catch (e) {\n consecutiveFailures++;\n throw new Error(e);\n }\n debugLog(\"Device:\", device);\n\n if (typeof device.gatt === \"undefined\") {\n return Promise.reject(\"Device did not have a GATT server.\");\n }\n\n const server = await device.gatt.connect();\n debugLog(\"Server:\", server);\n\n const name = server.device?.name || \"\";\n\n // TODO by reading supported matched filters or provided services.\n\n for (const config of configs) {\n for (const prefix of config.prefixes) {\n if (name?.startsWith(prefix)) {\n return config.connect(server, device);\n }\n }\n }\n\n throw Error(\"Unknown Bluetooth devive.\");\n}\n", "/* tslint:disable no-bitwise */\n\nimport { Quaternion } from \"three\";\nimport { Move } from \"../../alg\";\nimport type { KPuzzle, KPatternData } from \"../../kpuzzle\";\nimport { KPattern } from \"../../kpuzzle\";\nimport { puzzles } from \"../../puzzles\";\nimport {\n importKey,\n unsafeDecryptBlock,\n} from \"../../vendor/public-domain/unsafe-raw-aes/unsafe-raw-aes\";\nimport { debugLog } from \"../debug\";\nimport { type BluetoothConfig, BluetoothPuzzle } from \"./bluetooth-puzzle\";\n\n// This needs to be short enough to capture 6 moves (OBQTM).\nconst DEFAULT_INTERVAL_MS = 150;\n// Number of latest moves provided by the Gan 356i.\nconst MAX_LATEST_MOVES = 6;\n\nconst ganMoveToBlockMove: { [i: number]: Move } = {\n 0 /* 0x00 */: new Move(\"U\"),\n 2 /* 0x02 */: new Move(\"U\", -1),\n 3 /* 0x03 */: new Move(\"R\"),\n 5 /* 0x05 */: new Move(\"R\", -1),\n 6 /* 0x06 */: new Move(\"F\"),\n 8 /* 0x08 */: new Move(\"F\", -1),\n 9 /* 0x09 */: new Move(\"D\"),\n 11 /* 0x0b */: new Move(\"D\", -1),\n 12 /* 0x0c */: new Move(\"L\"),\n 14 /* 0x0e */: new Move(\"L\", -1),\n 15 /* 0x0f */: new Move(\"B\"),\n 17 /* 0x11 */: new Move(\"B\", -1),\n};\n\nlet homeQuatInverse: Quaternion | null = null;\n\nfunction probablyDecodedCorrectly(data: Uint8Array): boolean {\n return (\n data[13] < 0x12 &&\n data[14] < 0x12 &&\n data[15] < 0x12 &&\n data[16] < 0x12 &&\n data[17] < 0x12 &&\n data[18] < 0x12\n );\n}\n\nconst key10 = new Uint8Array([\n 198, 202, 21, 223, 79, 110, 19, 182, 119, 13, 230, 89, 58, 175, 186, 162,\n]);\nconst key11 = new Uint8Array([\n 67, 226, 91, 214, 125, 220, 120, 216, 7, 96, 163, 218, 130, 60, 1, 241,\n]);\n\n// Clean-room reverse-engineered\nasync function decryptPattern(\n data: Uint8Array,\n aesKey: CryptoKey | null,\n): Promise<Uint8Array> {\n if (aesKey === null) {\n return data;\n }\n\n const copy = new Uint8Array(data);\n copy.set(new Uint8Array(await unsafeDecryptBlock(aesKey, copy.slice(3))), 3);\n copy.set(\n new Uint8Array(await unsafeDecryptBlock(aesKey, copy.slice(0, 16))),\n 0,\n );\n\n if (probablyDecodedCorrectly(copy)) {\n return copy;\n }\n\n throw new Error(\"Invalid Gan cube pattern\");\n}\n\nclass PhysicalState {\n public static async read(\n characteristic: BluetoothRemoteGATTCharacteristic,\n aesKey: CryptoKey | null,\n ): Promise<PhysicalState> {\n const value = await decryptPattern(\n new Uint8Array((await characteristic.readValue()).buffer),\n aesKey,\n );\n const timeStamp = Date.now();\n // console.log(value);\n return new PhysicalState(new DataView(value.buffer), timeStamp);\n }\n\n private arr: Uint8Array;\n private arrLen = 19;\n private constructor(\n private dataView: DataView,\n public timeStamp: number,\n ) {\n this.arr = new Uint8Array(dataView.buffer);\n if (this.arr.length !== this.arrLen) {\n throw new Error(\"Unexpected array length\");\n }\n }\n\n public rotQuat(): Quaternion {\n let x = this.dataView.getInt16(0, true) / 16384;\n let y = this.dataView.getInt16(2, true) / 16384;\n let z = this.dataView.getInt16(4, true) / 16384;\n [x, y, z] = [-y, z, -x];\n const wSquared = 1 - (x * x + y * y + z * z);\n const w = wSquared > 0 ? Math.sqrt(wSquared) : 0;\n const quat = new Quaternion(x, y, z, w);\n\n if (!homeQuatInverse) {\n homeQuatInverse = quat.clone().invert();\n }\n\n return quat.clone().multiply(homeQuatInverse.clone());\n }\n\n // Loops from 255 to 0.\n public moveCounter(): number {\n return this.arr[12];\n }\n\n public numMovesSince(previousMoveCounter: number): number {\n return (this.moveCounter() - previousMoveCounter) & 0xff;\n }\n\n // Due to the design of the Gan356i protocol, it's common to query for the\n // latest physical state and find 0 moves have been performed since the last\n // query. Therefore, it's useful to allow 0 as an argument.\n public latestMoves(n: number): Move[] {\n if (n < 0 || n > MAX_LATEST_MOVES) {\n throw new Error(`Must ask for 0 to 6 latest moves. (Asked for ${n})`);\n }\n return Array.from(this.arr.slice(19 - n, 19)).map(\n (i) => ganMoveToBlockMove[i],\n );\n }\n\n public debugInfo(): { arr: Uint8Array } {\n return {\n arr: this.arr,\n };\n }\n}\n\n// TODO: Short IDs\nconst UUIDs = {\n ganCubeService: \"0000fff0-0000-1000-8000-00805f9b34fb\",\n physicalStateCharacteristic: \"0000fff5-0000-1000-8000-00805f9b34fb\",\n actualAngleAndBatteryCharacteristic: \"0000fff7-0000-1000-8000-00805f9b34fb\",\n faceletStatus1Characteristic: \"0000fff2-0000-1000-8000-00805f9b34fb\",\n faceletStatus2Characteristic: \"0000fff3-0000-1000-8000-00805f9b34fb\",\n infoService: \"0000180a-0000-1000-8000-00805f9b34fb\",\n systemIDCharacteristic: \"00002a23-0000-1000-8000-00805f9b34fb\",\n versionCharacteristic: \"00002a28-0000-1000-8000-00805f9b34fb\",\n};\n\nconst commands: { [cmd: string]: BufferSource } = {\n reset: new Uint8Array([\n 0x00, 0x00, 0x24, 0x00, 0x49, 0x92, 0x24, 0x49, 0x6d, 0x92, 0xdb, 0xb6,\n 0x49, 0x92, 0xb6, 0x24, 0x6d, 0xdb,\n ]),\n};\n\nfunction buf2hex(buffer: ArrayBuffer): string {\n // buffer is an ArrayBuffer\n return (\n Array.prototype.map.call(new Uint8Array(buffer), (x: number) =>\n `00${x.toString(16)}`.slice(-2),\n ) as string[]\n ).join(\" \");\n}\n\nconst reidEdgeOrder = \"UF UR UB UL DF DR DB DL FR FL BR BL\".split(\" \");\nconst reidCornerOrder = \"UFR URB UBL ULF DRF DFL DLB DBR\".split(\" \");\n\ninterface PieceInfo {\n piece: number;\n orientation: number;\n}\n\nfunction rotateLeft(s: string, i: number): string {\n return s.slice(i) + s.slice(0, i);\n}\n\nconst pieceMap: { [s: string]: PieceInfo } = {};\n// TODO: Condense the for loops.\nreidEdgeOrder.forEach((edge, idx) => {\n for (let i = 0; i < 2; i++) {\n pieceMap[rotateLeft(edge, i)] = { piece: idx, orientation: i };\n }\n});\nreidCornerOrder.forEach((corner, idx) => {\n for (let i = 0; i < 3; i++) {\n pieceMap[rotateLeft(corner, i)] = { piece: idx, orientation: i };\n }\n});\n\nconst gan356iCornerMappings = [\n [0, 21, 15],\n [5, 13, 47],\n [7, 45, 39],\n [2, 37, 23],\n [29, 10, 16],\n [31, 18, 32],\n [26, 34, 40],\n [24, 42, 8],\n];\n\nconst gan356iEdgeMappings = [\n [1, 22],\n [3, 14],\n [6, 46],\n [4, 38],\n [30, 17],\n [27, 9],\n [25, 41],\n [28, 33],\n [19, 12],\n [20, 35],\n [44, 11],\n [43, 36],\n];\nconst faceOrder = \"URFDLB\";\n\nasync function getKey(\n server: BluetoothRemoteGATTServer,\n): Promise<CryptoKey | null> {\n const infoService = await server.getPrimaryService(UUIDs.infoService);\n\n const versionCharacteristic = await infoService.getCharacteristic(\n UUIDs.versionCharacteristic,\n );\n const versionBuffer = new Uint8Array(\n (await versionCharacteristic.readValue()).buffer,\n );\n\n const versionValue =\n (((versionBuffer[0] << 8) + versionBuffer[1]) << 8) + versionBuffer[2];\n if (versionValue < 0x01_00_08) {\n return null;\n }\n\n const keyXor = versionValue < 0x01_01_00 ? key10 : key11;\n\n const systemIDCharacteristic = await infoService.getCharacteristic(\n UUIDs.systemIDCharacteristic,\n );\n const systemID = new Uint8Array(\n (await systemIDCharacteristic.readValue()).buffer,\n ).reverse();\n\n const key = new Uint8Array(keyXor);\n for (let i = 0; i < systemID.length; i++) {\n key[i] = (key[i] + systemID[i]) % 256;\n }\n\n return importKey(key);\n}\n\n/** @category Smart Puzzles */\nexport class GanCube extends BluetoothPuzzle {\n // We have to perform async operations before we call the constructor.\n public static async connect(\n server: BluetoothRemoteGATTServer,\n ): Promise<GanCube> {\n const ganCubeService = await server.getPrimaryService(UUIDs.ganCubeService);\n debugLog(\"Service:\", ganCubeService);\n\n const physicalStateCharacteristic = await ganCubeService.getCharacteristic(\n UUIDs.physicalStateCharacteristic,\n );\n debugLog(\"Characteristic:\", physicalStateCharacteristic);\n\n const aesKey = await getKey(server);\n\n const initialMoveCounter = (\n await PhysicalState.read(physicalStateCharacteristic, aesKey)\n ).moveCounter();\n debugLog(\"Initial Move Counter:\", initialMoveCounter);\n const cube = new GanCube(\n await puzzles[\"3x3x3\"].kpuzzle(),\n ganCubeService,\n server,\n physicalStateCharacteristic,\n initialMoveCounter,\n aesKey,\n );\n return cube;\n }\n\n public INTERVAL_MS: number = DEFAULT_INTERVAL_MS;\n private intervalHandle: number | null = null;\n private pattern: KPattern;\n private cachedFaceletStatus1Characteristic: Promise<BluetoothRemoteGATTCharacteristic>;\n\n private cachedFaceletStatus2Characteristic: Promise<BluetoothRemoteGATTCharacteristic>;\n\n private cachedActualAngleAndBatteryCharacteristic: Promise<BluetoothRemoteGATTCharacteristic>;\n\n private constructor(\n private kpuzzle: KPuzzle,\n private service: BluetoothRemoteGATTService,\n private server: BluetoothRemoteGATTServer,\n private physicalStateCharacteristic: BluetoothRemoteGATTCharacteristic,\n private lastMoveCounter: number,\n private aesKey: CryptoKey | null,\n ) {\n super();\n this.pattern = kpuzzle.defaultPattern();\n this.startTrackingMoves();\n }\n\n public name(): string | undefined {\n return this.server.device.name;\n }\n\n disconnect(): void {\n this.server.disconnect();\n }\n\n public startTrackingMoves(): void {\n // `window.setInterval` instead of `setInterval`:\n // https://github.com/Microsoft/TypeScript/issues/842#issuecomment-252445883\n this.intervalHandle = window.setInterval(\n this.intervalHandler.bind(this),\n this.INTERVAL_MS,\n );\n }\n\n public stopTrackingMoves(): void {\n if (!this.intervalHandle) {\n throw new Error(\"Not tracking moves!\");\n }\n clearInterval(this.intervalHandle);\n this.intervalHandle = null;\n }\n\n // TODO: Can we ever receive async responses out of order?\n public async intervalHandler(): Promise<void> {\n const physicalState = await PhysicalState.read(\n this.physicalStateCharacteristic,\n this.aesKey,\n );\n let numInterveningMoves = physicalState.numMovesSince(this.lastMoveCounter);\n // console.log(numInterveningMoves);\n if (numInterveningMoves > MAX_LATEST_MOVES) {\n debugLog(\n `Too many moves! Dropping ${\n numInterveningMoves - MAX_LATEST_MOVES\n } moves`,\n );\n numInterveningMoves = MAX_LATEST_MOVES;\n }\n for (const move of physicalState.latestMoves(numInterveningMoves)) {\n // console.log(move);\n this.pattern = this.pattern.applyMove(move);\n this.dispatchAlgLeaf({\n latestAlgLeaf: move,\n timeStamp: physicalState.timeStamp,\n debug: physicalState.debugInfo(),\n pattern: this.pattern,\n // quaternion: physicalState.rotQuat(),\n });\n }\n this.dispatchOrientation({\n timeStamp: physicalState.timeStamp,\n quaternion: physicalState.rotQuat(),\n });\n this.lastMoveCounter = physicalState.moveCounter();\n }\n\n public async getBattery(): Promise<number> {\n return new Uint8Array(\n await this.readActualAngleAndBatteryCharacteristic(),\n )[7];\n }\n\n public override async getPattern(): Promise<KPattern> {\n const arr: Uint8Array = await decryptPattern(\n new Uint8Array(await this.readFaceletStatus1Characteristic()),\n this.aesKey,\n );\n const stickers: number[] = [];\n for (let i = 0; i < 18; i += 3) {\n let v = (((arr[i ^ 1] << 8) + arr[(i + 1) ^ 1]) << 8) + arr[(i + 2) ^ 1];\n for (let j = 0; j < 8; j++) {\n stickers.push(v & 7);\n v >>= 3;\n }\n }\n\n const patternData: KPatternData = {\n CORNERS: {\n pieces: [],\n orientation: [],\n },\n EDGES: {\n pieces: [],\n orientation: [],\n },\n CENTERS: {\n pieces: [0, 1, 2, 3, 4, 5],\n orientation: [0, 0, 0, 0, 0, 0],\n orientationMod: [1, 1, 1, 1, 1, 1], // TODO\n },\n };\n\n for (const cornerMapping of gan356iCornerMappings) {\n const pieceInfo: PieceInfo =\n pieceMap[cornerMapping.map((i) => faceOrder[stickers[i]]).join(\"\")];\n patternData.CORNERS.pieces.push(pieceInfo.piece);\n patternData.CORNERS.orientation.push(pieceInfo.orientation);\n }\n\n for (const edgeMapping of gan356iEdgeMappings) {\n const pieceInfo: PieceInfo =\n pieceMap[edgeMapping.map((i) => faceOrder[stickers[i]]).join(\"\")];\n patternData.EDGES.pieces.push(pieceInfo.piece);\n patternData.EDGES.orientation.push(pieceInfo.orientation);\n }\n\n return new KPattern(this.kpuzzle, patternData);\n }\n\n public async faceletStatus1Characteristic(): Promise<BluetoothRemoteGATTCharacteristic> {\n this.cachedFaceletStatus1Characteristic =\n this.cachedFaceletStatus1Characteristic ||\n this.service.getCharacteristic(UUIDs.faceletStatus1Characteristic);\n return this.cachedFaceletStatus1Characteristic;\n }\n\n public async faceletStatus2Characteristic(): Promise<BluetoothRemoteGATTCharacteristic> {\n this.cachedFaceletStatus2Characteristic =\n this.cachedFaceletStatus2Characteristic ||\n this.service.getCharacteristic(UUIDs.faceletStatus2Characteristic);\n return this.cachedFaceletStatus2Characteristic;\n }\n\n public async actualAngleAndBatteryCharacteristic(): Promise<BluetoothRemoteGATTCharacteristic> {\n this.cachedActualAngleAndBatteryCharacteristic =\n this.cachedActualAngleAndBatteryCharacteristic ||\n this.service.getCharacteristic(UUIDs.actualAngleAndBatteryCharacteristic);\n return this.cachedActualAngleAndBatteryCharacteristic;\n }\n\n public async reset(): Promise<void> {\n const faceletStatus1Characteristic =\n await this.faceletStatus1Characteristic();\n await faceletStatus1Characteristic.writeValue(commands.reset);\n }\n\n public async readFaceletStatus1Characteristic(): Promise<ArrayBuffer> {\n const faceletStatus1Characteristic =\n await this.faceletStatus1Characteristic();\n return (await faceletStatus1Characteristic.readValue()).buffer;\n }\n\n public async readFaceletStatus2Characteristic(): Promise<string> {\n const faceletStatus2Characteristic =\n await this.faceletStatus2Characteristic();\n return buf2hex((await faceletStatus2Characteristic.readValue()).buffer);\n }\n\n public async readActualAngleAndBatteryCharacteristic(): Promise<ArrayBuffer> {\n const actualAngleAndBatteryCharacteristic =\n await this.actualAngleAndBatteryCharacteristic();\n return (await actualAngleAndBatteryCharacteristic.readValue()).buffer;\n }\n // TODO\n // private onphysicalStateCharacteristicChanged(event: any): void {\n // var val = event.target.value;\n // debugLog(val);\n // }\n}\n\n// // TODO: Move this into a factory?\nexport const ganConfig: BluetoothConfig<BluetoothPuzzle> = {\n connect: GanCube.connect.bind(GanCube),\n prefixes: [\"GAN\"],\n filters: [{ namePrefix: \"GAN\" }],\n optionalServices: [UUIDs.ganCubeService, UUIDs.infoService],\n};\n", "// Note: we could use the `unsafe-raw-aes` npm package instead. But:\n//\n// 1. This is a rather small amount of code, thanks to a clever hack of the Web Crypto API.\n// 2. This code is used (and therefore loaded) only for Gan cube decoding, and unlikely to be needed directly by projects using `cubing.js`.\n// 3. A dependency called `unsafe-raw-aes` would (rightfully) raise some eyebrows.\n//\n// So we just vendor the entire file instead.\n\nconst blockSize = 16;\nconst zeros = new Uint8Array(blockSize);\nconst paddingBlockPlaintext = new Uint8Array(\n new Array(blockSize).fill(blockSize),\n);\nconst AES_CBC = \"AES-CBC\";\n\nexport async function importKey(\n keyBytes: ArrayBuffer | Uint8Array,\n): Promise<CryptoKey> {\n return await crypto.subtle.importKey(\"raw\", keyBytes, AES_CBC, true, [\n \"encrypt\",\n \"decrypt\",\n ]);\n}\n\nasync function unsafeEncryptBlockWithIV(\n key: CryptoKey,\n plaintextBlock: ArrayBuffer | Uint8Array,\n iv: ArrayBuffer | Uint8Array,\n): Promise<ArrayBuffer> {\n const cryptoResult: ArrayBuffer = await window.crypto.subtle.encrypt(\n {\n name: AES_CBC,\n iv,\n },\n key,\n plaintextBlock,\n );\n return cryptoResult.slice(0, blockSize);\n}\n\nexport async function unsafeEncryptBlock(\n key: CryptoKey,\n plaintextBlock: ArrayBuffer | Uint8Array,\n): Promise<ArrayBuffer> {\n return (await unsafeEncryptBlockWithIV(key, plaintextBlock, zeros)).slice(\n 0,\n blockSize,\n );\n}\n\nexport async function unsafeDecryptBlock(\n key: CryptoKey,\n ciphertextBlock: ArrayBuffer | Uint8Array,\n): Promise<ArrayBuffer> {\n const paddingBlock = await unsafeEncryptBlockWithIV(\n key,\n paddingBlockPlaintext,\n ciphertextBlock,\n );\n\n const cbcCiphertext = new Uint8Array(2 * blockSize);\n cbcCiphertext.set(new Uint8Array(ciphertextBlock), 0);\n cbcCiphertext.set(new Uint8Array(paddingBlock), blockSize);\n\n const cryptoResult: ArrayBuffer = await window.crypto.subtle.decrypt(\n {\n name: AES_CBC,\n iv: zeros,\n },\n key,\n cbcCiphertext,\n );\n return cryptoResult.slice(0, blockSize);\n}\n", "/* tslint:disable no-bitwise */\n\nimport { Move } from \"../../alg\";\nimport { KPattern, type KPatternData } from \"../../kpuzzle\";\nimport { experimental3x3x3KPuzzle } from \"../../puzzles/cubing-private\";\nimport { debugLog } from \"../debug\";\nimport { BluetoothPuzzle, type BluetoothConfig } from \"./bluetooth-puzzle\";\n\nconst MESSAGE_LENGTH = 20;\n\nconst UUIDs = {\n cubeService: \"0000aadb-0000-1000-8000-00805f9b34fb\",\n cubeCharacteristic: \"0000aadc-0000-1000-8000-00805f9b34fb\",\n};\n\n// TODO: Expose for testing.\nfunction giikerMoveToAlgMove(face: number, amount: number): Move {\n switch (amount) {\n case 3: {\n amount = -1;\n break;\n }\n case 9: {\n debugLog(\"Encountered 9\", face, amount);\n amount = -2;\n break;\n }\n }\n\n const family = [\"?\", \"B\", \"D\", \"L\", \"U\", \"R\", \"F\"][face];\n return new Move(family, amount);\n}\n\nexport { giikerMoveToAlgMove as giikerMoveToAlgMoveForTesting };\n\nfunction giikerStateStr(giikerState: number[]): string {\n let str = \"\";\n str += giikerState.slice(0, 8).join(\".\");\n str += \"\\n\";\n str += giikerState.slice(8, 16).join(\".\");\n str += \"\\n\";\n str += giikerState.slice(16, 28).join(\".\");\n str += \"\\n\";\n str += giikerState.slice(28, 32).join(\".\");\n str += \"\\n\";\n str += giikerState.slice(32, 40).join(\".\");\n return str;\n}\n\n// TODO\n// const Reid333Orbits = {\n// \"EDGES\": {\"numPieces\": 12, \"orientations\": 2},\n// \"CORNERS\": {\"numPieces\": 8, \"orientations\": 3},\n// \"CENTERS\": {\"numPieces\": 6, \"orientations\": 4}\n// };\n\nconst Reid333SolvedCenters = {\n pieces: [0, 1, 2, 3, 4, 5],\n orientation: [0, 0, 0, 0, 0, 0],\n orientationMod: [1, 1, 1, 1, 1, 1], // TODO\n};\n\nconst epGiiKERtoReid333: number[] = [4, 8, 0, 9, 5, 1, 3, 7, 6, 10, 2, 11];\nconst epReid333toGiiKER: number[] = [2, 5, 10, 6, 0, 4, 8, 7, 1, 3, 9, 11];\n\nconst preEO: number[] = [1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0];\nconst postEO: number[] = [1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0];\n\nconst cpGiiKERtoReid333: number[] = [4, 0, 3, 5, 7, 1, 2, 6];\nconst cpReid333toGiiKER: number[] = [1, 5, 6, 2, 0, 3, 7, 4];\n\nconst preCO: number[] = [1, 2, 1, 2, 2, 1, 2, 1];\nconst postCO: number[] = [2, 1, 2, 1, 1, 2, 1, 2];\n\nconst coFlip: number[] = [-1, 1, -1, 1, 1, -1, 1, -1];\n\nfunction getNibble(val: Uint8Array, i: number): number {\n if (i % 2 === 1) {\n return val[(i / 2) | 0] % 16;\n }\n return 0 | (val[(i / 2) | 0] / 16);\n}\n\nfunction probablyEncrypted(data: Uint8Array): boolean {\n return data[18] === 0xa7;\n}\n\nconst lookup = [\n 176, 81, 104, 224, 86, 137, 237, 119, 38, 26, 193, 161, 210, 126, 150, 81, 93,\n 13, 236, 249, 89, 235, 88, 24, 113, 81, 214, 131, 130, 199, 2, 169, 39, 165,\n 171, 41,\n];\n\nfunction decryptState(data: Uint8Array): Uint8Array {\n const offset1 = getNibble(data, 38);\n const offset2 = getNibble(data, 39);\n const output = new Uint8Array(MESSAGE_LENGTH);\n for (let i = 0; i < MESSAGE_LENGTH; i++) {\n output[i] = data[i] + lookup[offset1 + i] + lookup[offset2 + i];\n }\n return output;\n}\n\n// TODO: Support caching which decoding strategy worked last time.\nasync function decodeState(data: Uint8Array): Promise<Uint8Array> {\n if (!probablyEncrypted(data)) {\n return data;\n }\n return decryptState(data);\n // TODO: Check that the decrypted state is a valid staet.\n}\n\n/** @category Smart Puzzles */\nexport class GiiKERCube extends BluetoothPuzzle {\n public static async connect(\n server: BluetoothRemoteGATTServer,\n ): Promise<GiiKERCube> {\n const cubeService = await server.getPrimaryService(UUIDs.cubeService);\n debugLog(\"Service:\", cubeService);\n\n const cubeCharacteristic = await cubeService.getCharacteristic(\n UUIDs.cubeCharacteristic,\n );\n debugLog(\"Characteristic:\", cubeCharacteristic);\n\n // TODO: Can we safely save the async promise instead of waiting for the response?\n\n const originalValue = await decodeState(\n new Uint8Array((await cubeCharacteristic.readValue()).buffer),\n );\n debugLog(\"Original value:\", originalValue);\n const cube = new GiiKERCube(server, cubeCharacteristic, originalValue);\n\n await cubeCharacteristic.startNotifications();\n cubeCharacteristic.addEventListener(\n \"characteristicvaluechanged\",\n cube.onCubeCharacteristicChanged.bind(cube),\n );\n\n return cube;\n }\n\n private constructor(\n private server: BluetoothRemoteGATTServer,\n private cubeCharacteristic: BluetoothRemoteGATTCharacteristic,\n private originalValue?: Uint8Array | null,\n ) {\n super();\n }\n\n public name(): string | undefined {\n return this.server.device.name;\n }\n\n disconnect(): void {\n this.server.disconnect();\n }\n\n public override async getPattern(): Promise<KPattern> {\n return this.toReid333(\n new Uint8Array((await this.cubeCharacteristic.readValue()).buffer),\n );\n }\n\n private getBit(val: Uint8Array, i: number): number {\n const n = (i / 8) | 0;\n const shift = 7 - (i % 8);\n return (val[n] >> shift) & 1;\n }\n\n private toReid333(val: Uint8Array): KPattern {\n const patternData: KPatternData = {\n EDGES: {\n pieces: new Array(12),\n orientation: new Array(12),\n },\n CORNERS: {\n pieces: new Array(8),\n orientation: new Array(8),\n },\n CENTERS: Reid333SolvedCenters,\n };\n\n for (let i = 0; i < 12; i++) {\n const gi = epReid333toGiiKER[i];\n patternData.EDGES.pieces[i] =\n epGiiKERtoReid333[getNibble(val, gi + 16) - 1];\n patternData.EDGES.orientation[i] =\n this.getBit(val, gi + 112) ^\n preEO[patternData.EDGES.pieces[i]] ^\n postEO[i];\n }\n for (let i = 0; i < 8; i++) {\n const gi = cpReid333toGiiKER[i];\n patternData.CORNERS.pieces[i] = cpGiiKERtoReid333[getNibble(val, gi) - 1];\n patternData.CORNERS.orientation[i] =\n (getNibble(val, gi + 8) * coFlip[gi] +\n preCO[patternData.CORNERS.pieces[i]] +\n postCO[i]) %\n 3;\n }\n return new KPattern(experimental3x3x3KPuzzle, patternData);\n }\n\n private async onCubeCharacteristicChanged(event: any): Promise<void> {\n const val = await decodeState(new Uint8Array(event.target.value.buffer));\n debugLog(val);\n debugLog(val);\n\n if (this.isRepeatedInitialValue(val)) {\n debugLog(\"Skipping repeated initial value.\");\n return;\n }\n\n const giikerState = [];\n for (let i = 0; i < MESSAGE_LENGTH; i++) {\n giikerState.push(Math.floor(val[i] / 16));\n giikerState.push(val[i] % 16);\n }\n debugLog(giikerState);\n const str = giikerStateStr(giikerState);\n debugLog(str);\n\n this.dispatchAlgLeaf({\n latestAlgLeaf: giikerMoveToAlgMove(giikerState[32], giikerState[33]),\n timeStamp: event.timeStamp,\n debug: {\n stateStr: str,\n },\n pattern: this.toReid333(val),\n });\n }\n\n private isRepeatedInitialValue(val: Uint8Array): boolean {\n if (typeof this.originalValue === \"undefined\") {\n // TODO: Test this branch.\n throw new Error(\"GiiKERCube has uninitialized original value.\");\n }\n\n if (this.originalValue === null) {\n return false;\n }\n\n const originalValue = this.originalValue;\n // Reset the value here, so we can return early below.\n this.originalValue = null;\n\n debugLog(\"Comparing against original value.\");\n for (let i = 0; i < MESSAGE_LENGTH - 2; i++) {\n if (originalValue[i] !== val[i]) {\n debugLog(\"Different at index \", i);\n return false;\n }\n }\n return true;\n }\n}\n\n// TODO: Move this into a factory?\nexport const giiKERConfig: BluetoothConfig<BluetoothPuzzle> = {\n connect: GiiKERCube.connect.bind(GiiKERCube),\n prefixes: [\"Gi\", \"\", \"Mi\", \"Hi-\"], // Hack\n filters: [\n // Known prefixes: GiC, GiS (3x3x3), Gi2 (2x2x2)\n // Suspected prefixes GiY, Gi3\n { namePrefix: \"Gi\" },\n { namePrefix: \"Mi\" },\n { services: [\"0000aadb-0000-1000-8000-00805f9b34fb\"] },\n { services: [\"0000aaaa-0000-1000-8000-00805f9b34fb\"] },\n { services: [\"0000fe95-0000-1000-8000-00805f9b34fb\"] },\n ],\n optionalServices: [\n // \"00001530-1212-efde-1523-785feabcd123\",\n // \"0000aaaa-0000-1000-8000-00805f9b34fb\",\n UUIDs.cubeService,\n // \"0000180f-0000-1000-8000-00805f9b34fb\",\n // \"0000180a-0000-1000-8000-00805f9b34fb\"\n ],\n};\n", "import { Quaternion } from \"three\";\nimport { Alg, experimentalAppendMove, Move } from \"../../alg\";\nimport { debugLog } from \"../debug\";\nimport { type BluetoothConfig, BluetoothPuzzle } from \"./bluetooth-puzzle\";\n\nconst UUIDs = {\n goCubeService: \"6e400001-b5a3-f393-e0a9-e50e24dcca9e\",\n goCubeStateCharacteristic: \"6e400003-b5a3-f393-e0a9-e50e24dcca9e\",\n};\n\n// https://stackoverflow.com/a/40031979\nfunction buf2hex(buffer: ArrayBuffer): string {\n // buffer is an ArrayBuffer\n return (\n Array.prototype.map.call(new Uint8Array(buffer), (x: number) =>\n `00${x.toString(16)}`.slice(-2),\n ) as string[]\n ).join(\" \");\n}\n\nfunction bufferToString(buffer: ArrayBuffer): string {\n const byteView = new Uint8Array(buffer);\n let str = \"\";\n for (const charCode of byteView) {\n str += String.fromCharCode(charCode);\n }\n return str;\n}\n\nconst moveMap: Move[] = [\n new Move(\"B\", 1),\n new Move(\"B\", -1),\n new Move(\"F\", 1),\n new Move(\"F\", -1),\n new Move(\"U\", 1),\n new Move(\"U\", -1),\n new Move(\"D\", 1),\n new Move(\"D\", -1),\n new Move(\"R\", 1),\n new Move(\"R\", -1),\n new Move(\"L\", 1),\n new Move(\"L\", -1),\n];\n\n/** @category Smart Puzzles */\nexport class GoCube extends BluetoothPuzzle {\n // We have to perform async operations before we call the constructor.\n public static async connect(\n server: BluetoothRemoteGATTServer,\n ): Promise<GoCube> {\n const service = await server.getPrimaryService(UUIDs.goCubeService);\n debugLog({ service });\n const goCubeStateCharacteristic = await service.getCharacteristic(\n UUIDs.goCubeStateCharacteristic,\n );\n debugLog({ goCubeStateCharacteristic });\n\n const cube = new GoCube(server, goCubeStateCharacteristic);\n\n await goCubeStateCharacteristic.startNotifications();\n goCubeStateCharacteristic.addEventListener(\n \"characteristicvaluechanged\",\n cube.onCubeCharacteristicChanged.bind(cube),\n );\n\n return cube;\n }\n\n // public async getState(): Promise<PuzzleState> {\n // return new Promise((resolve, reject) => {\n // this.resolve = (value: any) => {\n // resolve(buf2hex(value.buffer) as any);\n // };\n // this.goCubeStateCharacteristic.startNotifications();\n // });\n // }\n\n private recorded: any[][] = [];\n\n private homeQuatInverse: Quaternion | null = null;\n private lastRawQuat: Quaternion = new Quaternion(0, 0, 0, 1);\n private currentQuat: Quaternion = new Quaternion(0, 0, 0, 1);\n private lastTarget: Quaternion = new Quaternion(0, 0, 0, 1);\n private alg: Alg = new Alg();\n\n private constructor(\n private server: BluetoothRemoteGATTServer,\n public goCubeStateCharacteristic: BluetoothRemoteGATTCharacteristic,\n ) {\n super();\n }\n\n disconnect(): void {\n this.server.disconnect();\n }\n\n public reset(): void {\n this.resetAlg();\n this.resetOrientation();\n }\n\n public resetAlg(alg?: Alg): void {\n this.alg = alg || new Alg();\n }\n\n public resetOrientation(): void {\n this.homeQuatInverse = this.lastRawQuat.clone().invert();\n this.currentQuat = new Quaternion(0, 0, 0, 1);\n this.lastTarget = new Quaternion(0, 0, 0, 1);\n }\n\n public name(): string | undefined {\n return this.server.device.name;\n }\n\n private onCubeCharacteristicChanged(event: any): void {\n const buffer: DataView = event.target.value;\n this.recorded.push([event.timeStamp, buf2hex(buffer.buffer)]);\n // TODO: read bytes from buffer instead of guessing meaning based on length.\n if (buffer.byteLength < 16) {\n for (let i = 3; i < buffer.byteLength - 4; i += 2) {\n const move = moveMap[buffer.getUint8(i)];\n this.alg = experimentalAppendMove(this.alg, move);\n this.dispatchAlgLeaf({\n latestAlgLeaf: moveMap[buffer.getUint8(i)],\n timeStamp: event.timeStamp,\n debug: {\n stateStr: buf2hex(buffer.buffer),\n },\n });\n }\n } else {\n const coords = bufferToString(\n buffer.buffer.slice(3, buffer.byteLength - 3),\n )\n .split(\"#\")\n .map((s) => parseInt(s, 10) / 16384);\n const quat = new Quaternion(coords[0], coords[1], coords[2], coords[3]);\n\n this.lastRawQuat = quat.clone();\n\n if (!this.homeQuatInverse) {\n this.homeQuatInverse = quat.clone().invert();\n }\n\n const targetQuat = quat.clone().multiply(this.homeQuatInverse.clone());\n targetQuat.y = -targetQuat.y; // GoCube axis fix.\n\n this.lastTarget.slerp(targetQuat, 0.5);\n this.currentQuat.rotateTowards(this.lastTarget, rotateTowardsRate);\n\n this.dispatchOrientation({\n quaternion: this.currentQuat,\n timeStamp: event.timeStamp,\n });\n }\n }\n}\n\nconst rotateTowardsRate = 0.5;\n\n// TODO: Move this into a factory?\nexport const goCubeConfig: BluetoothConfig<BluetoothPuzzle> = {\n connect: GoCube.connect.bind(GoCube),\n prefixes: [\"GoCube\", \"Rubik\"],\n filters: [{ namePrefix: \"GoCube\" }, { namePrefix: \"Rubik\" }],\n optionalServices: [UUIDs.goCubeService],\n};\n", "export function flipBitOrder(v: number, numBits: number): number {\n let result = 0;\n for (let i = 0; i < numBits; i++) {\n const shiftLeft = numBits - 1 - 2 * i;\n const unShiftedBit = v & (0b1 << i);\n // console.log(\n // unShiftedBit,\n // shiftLeft,\n // shiftLeft < 0 ? unShiftedBit >> -shiftLeft : unShiftedBit << shiftLeft,\n // );\n result +=\n shiftLeft < 0 ? unShiftedBit >> -shiftLeft : unShiftedBit << shiftLeft;\n }\n return result;\n}\n", "/* tslint:disable no-bitwise */\n\nimport { Move } from \"../../alg\";\nimport type { KPuzzle } from \"../../kpuzzle\";\nimport type { KPattern } from \"../../kpuzzle/KPattern\";\nimport {\n experimentalBinaryComponentsToReid3x3x3,\n experimentalTwizzleBinaryToBinaryComponents,\n} from \"../../protocol\";\nimport { puzzles } from \"../../puzzles\";\nimport { debugLog } from \"../debug\";\nimport { type BluetoothConfig, BluetoothPuzzle } from \"./bluetooth-puzzle\";\nimport { flipBitOrder } from \"./endianness\";\n\n// TODO: Short IDs\nconst UUIDs = {\n heykubeService: \"b46a791a-8273-4fc1-9e67-94d3dc2aac1c\",\n stateCharacteristic: \"a2f41a4e-0e31-4bbc-9389-4253475481fb\",\n batteryCharacteristic: \"fd51b3ba-99c7-49c6-9f85-5644ff56a378\",\n};\n\n/** @category Smart Puzzles */\nexport class HeykubeCube extends BluetoothPuzzle {\n // We have to perform async operations before we call the constructor.\n public static async connect(\n server: BluetoothRemoteGATTServer,\n device: BluetoothDevice,\n ): Promise<HeykubeCube> {\n const service = await server.getPrimaryService(UUIDs.heykubeService);\n debugLog(\"Service:\", service);\n\n const stateCharacteristic = await service.getCharacteristic(\n UUIDs.stateCharacteristic,\n );\n debugLog(\"Characteristic:\", stateCharacteristic);\n\n const cube = new HeykubeCube(\n await puzzles[\"3x3x3\"].kpuzzle(),\n service,\n device,\n server,\n stateCharacteristic,\n );\n return cube;\n }\n\n private constructor(\n _kpuzzle: KPuzzle,\n _service: BluetoothRemoteGATTService,\n device: BluetoothDevice,\n private server: BluetoothRemoteGATTServer,\n private stateCharacteristic: BluetoothRemoteGATTCharacteristic,\n ) {\n super();\n\n device.addEventListener(\n \"gattserverdisconnected\",\n this.onDisconnect.bind(this),\n );\n\n this.stateCharacteristic.startNotifications();\n this.startTrackingMoves();\n }\n\n public name(): string | undefined {\n return this.server.device.name;\n }\n\n disconnect(): void {\n this.server.disconnect();\n }\n\n onDisconnect(): void {\n this.dispatchEvent(new CustomEvent(\"disconnect\"));\n }\n\n public startTrackingMoves(): void {\n this.stateCharacteristic.addEventListener(\n \"characteristicvaluechanged\",\n (e: any) => this.onStateCharacteristic(e),\n ); // TODO\n }\n\n // public stopTrackingMoves(): void {}\n\n // public async getBattery(): Promise<number> {\n // return new Uint8Array(\n // await this.readActualAngleAndBatteryCharacteristic(),\n // )[7];\n // }srcElement: BluetoothRemoteGATTCharacteristic\n\n private onStateCharacteristic(event: {\n target: BluetoothRemoteGATTCharacteristic;\n timeStamp: number;\n }): void {\n const state = this.decodeState(event.target.value!);\n // console.log(event, state.latestMove.toString(), state);\n this.dispatchAlgLeaf({\n latestAlgLeaf: state.latestMove,\n timeStamp: event.timeStamp,\n pattern: state.pattern,\n });\n }\n\n private decodeState(dv: DataView): { pattern: KPattern; latestMove: Move } {\n const moves = [\n new Move(\"U\"),\n new Move(\"U'\"),\n new Move(\"B\"),\n new Move(\"B'\"),\n new Move(\"F\"),\n new Move(\"F'\"),\n null,\n null,\n new Move(\"L\"),\n new Move(\"L'\"),\n new Move(\"D\"),\n new Move(\"D'\"),\n new Move(\"R\"),\n new Move(\"R'\"),\n // null,\n // null,\n ];\n\n const b2 = new Uint8Array(dv.byteLength);\n for (let i = 0; i < dv.byteLength; i++) {\n b2[i] = flipBitOrder(dv.getUint8(i), 8);\n }\n const components1 = experimentalTwizzleBinaryToBinaryComponents(\n b2.slice(0, 11),\n );\n // console.log(\"sliced\", dv.byteLength, bufferToSpacedHex(b2.slice(11)));\n const components2 = {\n epLex: flipBitOrder(components1.epLex, 29),\n eoMask: flipBitOrder(components1.eoMask, 12),\n cpLex: flipBitOrder(components1.cpLex, 16),\n coMask: flipBitOrder(components1.coMask, 13),\n poIdxL: 0,\n poIdxU: 0b111,\n moSupport: 0b1, // TODO\n moMask: 0,\n };\n // console.log(components2, binaryComponentsToReid3x3x3(components2));\n\n return {\n pattern: experimentalBinaryComponentsToReid3x3x3(components2),\n latestMove: moves[b2[20] & 0b00001111]!,\n };\n }\n\n public override async getPattern(): Promise<KPattern> {\n const b1 = await this.stateCharacteristic.readValue();\n return this.decodeState(b1).pattern;\n }\n}\n\n// // TODO: Move this into a factory?\nexport const heykubeConfig: BluetoothConfig<BluetoothPuzzle> = {\n connect: HeykubeCube.connect.bind(HeykubeCube),\n prefixes: [\"HEYKUBE\"],\n filters: [{ namePrefix: \"HEYKUBE\" }],\n optionalServices: [UUIDs.heykubeService],\n};\n", "import { bluetoothConnect, type BluetoothConnectOptions } from \"../connect\";\nimport type { BluetoothPuzzle } from \"./bluetooth-puzzle\";\nimport { ganConfig } from \"./gan\";\nimport { giiKERConfig } from \"./giiker\";\nimport { goCubeConfig } from \"./gocube\";\nimport { heykubeConfig } from \"./Heykube\";\n\nconst smartPuzzleConfigs = [\n ganConfig,\n goCubeConfig,\n heykubeConfig,\n giiKERConfig, // GiiKER must be last, due to Xiaomi naming. TODO: enforce this using tests.\n];\n\n/** @category Smart Puzzles */\nexport async function connectSmartPuzzle(\n options?: BluetoothConnectOptions,\n): Promise<BluetoothPuzzle> {\n return bluetoothConnect<BluetoothPuzzle>(smartPuzzleConfigs, options);\n}\n", "import { Alg, type Move } from \"../../alg\";\nimport { cube3x3x3 } from \"../../puzzles\";\nimport type { BluetoothConfig } from \"../smart-puzzle/bluetooth-puzzle\";\n\n// TODO: Remove this. It's only used for debugging.\nfunction buf2hex(buffer: ArrayBuffer | Uint8Array): string {\n // buffer is an ArrayBuffer\n return (\n Array.prototype.map.call(new Uint8Array(buffer), (x: number) =>\n `00${x.toString(16)}`.slice(-2),\n ) as string[]\n ).join(\" \");\n}\n\nconst MAX_NIBBLES_PER_WRITE = 18 * 2;\nconst QUANTUM_TURN_DURATION_MS = 150;\nconst DOUBLE_TURN_DURATION_MS = 250;\n\nconst U_D_SWAP = new Alg(\"F B R2 L2 B' F'\");\nconst U_D_UNSWAP = U_D_SWAP.invert(); // TODO: make `cubing.js` clever enough to be able to reuse the regular swap.\nconst F_B_SWAP = new Alg(\"U D R2 L2 D' U'\");\nconst F_B_UNSWAP = F_B_SWAP.invert();\n\n// TODO: Short IDs\nconst UUIDs = {\n ganRobotService: \"0000fff0-0000-1000-8000-00805f9b34fb\",\n statusCharacteristic: \"0000fff2-0000-1000-8000-00805f9b34fb\",\n moveCharacteristic: \"0000fff3-0000-1000-8000-00805f9b34fb\",\n};\n\nconst moveMap: Record<string, number> = {\n R: 0,\n R2: 1,\n \"R2'\": 1,\n \"R'\": 2,\n F: 3,\n F2: 4,\n \"F2'\": 4,\n \"F'\": 5,\n D: 6,\n D2: 7,\n \"D2'\": 7,\n \"D'\": 8,\n L: 9,\n L2: 10,\n \"L2'\": 10,\n \"L'\": 11,\n B: 12,\n B2: 13,\n \"B2'\": 13,\n \"B'\": 14,\n};\n\nconst moveMapX: Record<string, number> = {\n R: 0,\n R2: 1,\n \"R2'\": 1,\n \"R'\": 2,\n U: 3,\n U2: 4,\n \"U2'\": 4,\n \"U'\": 5,\n F: 6,\n F2: 7,\n \"F2'\": 7,\n \"F'\": 8,\n L: 9,\n L2: 10,\n \"L2'\": 10,\n \"L'\": 11,\n D: 12,\n D2: 13,\n \"D2'\": 13,\n \"D'\": 14,\n};\n\nfunction isDoubleTurnNibble(nibble: number): boolean {\n return nibble % 3 === 1;\n}\n\nfunction nibbleDuration(nibble: number): number {\n return isDoubleTurnNibble(nibble)\n ? DOUBLE_TURN_DURATION_MS\n : QUANTUM_TURN_DURATION_MS;\n}\n\nfunction throwInvalidMove(move: Move) {\n console.error(\"invalid move\", move, move.toString());\n throw new Error(\"invalid move!\");\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport interface GanRobotStatus {\n movesRemaining: number;\n}\n\ninterface GanRobotOptions {\n xAngle: boolean;\n singleMoveFixHack: boolean;\n bufferQueue: number;\n postSleep: number;\n}\n\n/** @category Robots */\nexport class GanRobot extends EventTarget {\n experimentalDebugOnSend: ((alg: Alg) => void) | null = null;\n experimentalDebugLog: typeof console.log = () => {};\n\n // Because our Bluetooth connection code is set up not to know what kind of device is connecting, we put these options directly on the class.\n experimentalOptions: GanRobotOptions = {\n xAngle: false,\n singleMoveFixHack: false,\n bufferQueue: 0,\n postSleep: 0,\n };\n\n constructor(\n _service: BluetoothRemoteGATTService,\n private server: BluetoothRemoteGATTServer,\n device: BluetoothDevice,\n private statusCharacteristic: BluetoothRemoteGATTCharacteristic,\n private moveCharacteristic: BluetoothRemoteGATTCharacteristic,\n ) {\n super();\n device.addEventListener(\n \"gattserverdisconnected\",\n this.onDisconnect.bind(this),\n );\n }\n\n // We have to perform async operations before we call the constructor.\n static async connect(\n server: BluetoothRemoteGATTServer,\n device: BluetoothDevice,\n ) {\n const ganTimerService = await server.getPrimaryService(\n UUIDs.ganRobotService,\n );\n const statusCharacteristic = await ganTimerService.getCharacteristic(\n UUIDs.statusCharacteristic,\n );\n const moveCharacteristic = await ganTimerService.getCharacteristic(\n UUIDs.moveCharacteristic,\n );\n const timer = new GanRobot(\n ganTimerService,\n server,\n device,\n statusCharacteristic,\n moveCharacteristic,\n );\n return timer;\n }\n\n public name(): string | undefined {\n return this.server.device.name;\n }\n\n disconnect(): void {\n this.server.disconnect();\n }\n\n onDisconnect(): void {\n this.dispatchEvent(new CustomEvent(\"disconnect\"));\n }\n\n private moveToNibble(move: Move): number {\n const nibble =\n (this.experimentalOptions.xAngle ? moveMapX : moveMap)[move.toString()] ??\n null;\n if (nibble === null) {\n throwInvalidMove(move);\n }\n return nibble;\n }\n\n private async writeNibbles(nibbles: number[]): Promise<void> {\n if (nibbles.length > MAX_NIBBLES_PER_WRITE) {\n throw new Error(\n `Can only write ${MAX_NIBBLES_PER_WRITE} nibbles at a time!`,\n );\n }\n // const byteLength = Math.ceil(nibbles.length / 2);\n const bytes = new Uint8Array(18);\n let i: number;\n for (i = 0; i < nibbles.length; i++) {\n const byteIdx = Math.floor(i / 2);\n bytes[byteIdx] += nibbles[i];\n if (i % 2 === 0) {\n bytes[byteIdx] *= 0x10;\n }\n }\n if (nibbles.length % 2 === 1) {\n bytes[Math.ceil(nibbles.length / 2) - 1] += 0xf;\n }\n for (let i = Math.ceil(nibbles.length / 2); i < 18; i++) {\n bytes[i] = 0xff;\n }\n let sleepDuration = 0;\n for (const nibble of nibbles) {\n sleepDuration += nibbleDuration(nibble);\n }\n this.experimentalDebugLog(\"WRITING:\", buf2hex(bytes));\n await this.moveCharacteristic.writeValue(bytes);\n await sleep(sleepDuration * 0.75);\n while ((await this.getStatus()).movesRemaining > 0) {\n // repeat\n }\n await sleep(this.experimentalOptions.postSleep);\n }\n\n private async getStatus(): Promise<GanRobotStatus> {\n const statusBytes = new Uint8Array(\n (await this.statusCharacteristic.readValue()).buffer,\n );\n this.experimentalDebugLog(\"moves remaining:\", statusBytes[0]);\n return {\n movesRemaining: statusBytes[0],\n };\n }\n\n locked: boolean = false;\n processQueue(): void {}\n\n private moveQueue: Alg = new Alg();\n // TODO: Don't let this resolve until the move is done?\n private async queueMoves(moves: Alg): Promise<void> {\n this.moveQueue = this.moveQueue.concat(moves).experimentalSimplify({\n puzzleSpecificSimplifyOptions: cube3x3x3.puzzleSpecificSimplifyOptions,\n });\n if (!this.locked) {\n // TODO: We're currently iterating over alg nodes instead of leaves to avoid \"zip bomps\".\n try {\n this.locked = true;\n if (this.moveQueue.experimentalNumChildAlgNodes() === 1) {\n await sleep(this.experimentalOptions.bufferQueue);\n }\n // await this.writeNibbles([0xf, 0xf]);\n while (this.moveQueue.experimentalNumChildAlgNodes() > 0) {\n let algNodes = Array.from(this.moveQueue.childAlgNodes());\n if (\n this.experimentalOptions.singleMoveFixHack &&\n algNodes.length === 1\n ) {\n const move = algNodes[0] as Move;\n if (move.amount === 2) {\n algNodes = [\n move.modified({ amount: 1 }),\n move.modified({ amount: 1 }),\n ];\n } else {\n algNodes = [\n move.modified({ amount: -move.amount }),\n move.modified({ amount: 2 }),\n ];\n }\n }\n const moves = algNodes.splice(0, MAX_NIBBLES_PER_WRITE);\n const nibbles: number[] = moves.map(this.moveToNibble.bind(this));\n const sending = new Alg(moves);\n this.experimentalDebugLog(\"SENDING\", sending.toString());\n if (this.experimentalDebugOnSend) {\n this.experimentalDebugOnSend(sending);\n }\n const write = this.writeNibbles(nibbles);\n this.moveQueue = new Alg(algNodes);\n await write;\n }\n } finally {\n this.locked = false;\n }\n }\n }\n\n async applyMoves(moves: Iterable<Move>): Promise<void> {\n // const nibbles: number[] = [];\n for (const move of moves) {\n const str = move.toString();\n if (str in (this.experimentalOptions.xAngle ? moveMapX : moveMap)) {\n await this.queueMoves(new Alg([move]));\n } else if (\n move.family === (this.experimentalOptions.xAngle ? \"B\" : \"U\")\n ) {\n // We purposely send just the swap, so that U2 will get cancelled\n await Promise.all([\n this.queueMoves(\n this.experimentalOptions.xAngle ? F_B_SWAP : U_D_SWAP,\n ),\n this.queueMoves(\n new Alg([\n move.modified({\n family: this.experimentalOptions.xAngle ? \"F\" : \"D\",\n }),\n ]).concat(\n this.experimentalOptions.xAngle ? F_B_UNSWAP : U_D_UNSWAP,\n ),\n ),\n ]);\n }\n }\n }\n}\n\n// // TODO: Move this into a factory?\nexport const ganTimerConfig: BluetoothConfig<GanRobot> = {\n connect: GanRobot.connect.bind(GanRobot),\n prefixes: [\"GAN\"],\n filters: [{ namePrefix: \"GAN\" }],\n optionalServices: [UUIDs.ganRobotService],\n};\n", "import { bluetoothConnect, type BluetoothConnectOptions } from \"../connect\";\nimport type { BluetoothConfig } from \"../smart-puzzle/bluetooth-puzzle\";\nimport { ganTimerConfig, type GanRobot } from \"./GanRobot\";\n\n/** @category Robots */\nexport type BluetoothRobot = GanRobot; // TODO\n\nconst smartRobotConfigs: BluetoothConfig<BluetoothRobot>[] = [ganTimerConfig];\n\n/** @category Robots */\nexport async function connectSmartRobot(\n options?: BluetoothConnectOptions,\n): Promise<BluetoothRobot> {\n return bluetoothConnect<BluetoothRobot>(smartRobotConfigs, options);\n}\n", "import type { MillisecondTimestamp } from \"../../twisty/controllers/AnimationTypes\";\nimport type { BluetoothConfig } from \"../smart-puzzle/bluetooth-puzzle\";\n\n// TODO: Short IDs\nconst UUIDs = {\n ganTimerService: \"0000fff0-0000-1000-8000-00805f9b34fb\",\n timeCharacteristic: \"0000fff2-0000-1000-8000-00805f9b34fb\",\n};\n\ninterface GanTimerDetail {\n currentTime: MillisecondTimestamp;\n latestTimes: [\n MillisecondTimestamp,\n MillisecondTimestamp,\n MillisecondTimestamp,\n ];\n}\n\n/** @category Timers */\nexport class GanTimer extends EventTarget {\n private polling = false;\n private previousDetail: GanTimerDetail | null = null;\n\n constructor(\n _service: BluetoothRemoteGATTService,\n private server: BluetoothRemoteGATTServer,\n device: BluetoothDevice,\n private timeCharacteristic: BluetoothRemoteGATTCharacteristic,\n ) {\n super();\n this.startPolling();\n console.log(server);\n device.addEventListener(\n \"gattserverdisconnected\",\n this.onDisconnect.bind(this),\n );\n }\n\n // We have to perform async operations before we call the constructor.\n static async connect(\n server: BluetoothRemoteGATTServer,\n device: BluetoothDevice,\n ) {\n const ganTimerService = await server.getPrimaryService(\n UUIDs.ganTimerService,\n );\n console.log(\"Service:\", ganTimerService);\n const timeCharacteristic = await ganTimerService.getCharacteristic(\n UUIDs.timeCharacteristic,\n );\n console.log(\"Characteristic:\", timeCharacteristic);\n const timer = new GanTimer(\n ganTimerService,\n server,\n device,\n timeCharacteristic,\n );\n return timer;\n }\n\n disconnect(): void {\n this.server.disconnect();\n }\n\n async poll() {\n if (!this.polling) {\n return;\n }\n const value = await this.getTimeCharacteristic();\n\n const detail: GanTimerDetail = {\n currentTime: this.decodeTimeMs(value.slice(0, 4)),\n latestTimes: [\n this.decodeTimeMs(value.slice(4, 8)),\n this.decodeTimeMs(value.slice(8, 12)),\n this.decodeTimeMs(value.slice(12, 16)),\n ],\n };\n\n if (detail.currentTime === 0) {\n if (this.previousDetail && this.previousDetail.currentTime !== 0) {\n this.dispatchEvent(new CustomEvent(\"reset\"));\n }\n }\n\n if (detail.currentTime !== 0 && this.previousDetail) {\n if (this.previousDetail.currentTime === 0) {\n this.dispatchEvent(new CustomEvent(\"start\"));\n }\n\n if (detail.currentTime !== this.previousDetail.currentTime) {\n this.dispatchEvent(new CustomEvent(\"update\", { detail }));\n\n if (\n detail.currentTime === detail.latestTimes[0] &&\n detail.latestTimes[1] === this.previousDetail.latestTimes[0] &&\n detail.latestTimes[2] === this.previousDetail.latestTimes[1]\n ) {\n this.dispatchEvent(new CustomEvent(\"stop\", { detail }));\n }\n }\n }\n\n this.previousDetail = detail;\n\n this.poll();\n }\n\n onDisconnect(): void {\n this.dispatchEvent(new CustomEvent(\"disconnect\"));\n }\n\n async getTimeCharacteristic() {\n return new Uint8Array((await this.timeCharacteristic.readValue()).buffer);\n }\n\n async getTime() {\n const value = await this.getTimeCharacteristic();\n return this.decodeTimeMs(value.slice(0, 4));\n }\n\n decodeTimeMs(bytes: Uint8Array) {\n return (bytes[0] * 60 + bytes[1]) * 1000 + bytes[2] + bytes[3] * 256;\n }\n\n startPolling() {\n this.polling = true;\n this.poll();\n }\n\n stopPolling() {\n this.polling = false;\n }\n}\n\n// // TODO: Move this into a factory?\nexport const ganTimerConfig: BluetoothConfig<GanTimer> = {\n connect: GanTimer.connect.bind(GanTimer),\n prefixes: [\"GAN\"],\n filters: [{ namePrefix: \"GAN\" }],\n optionalServices: [UUIDs.ganTimerService],\n};\n", "import { bluetoothConnect, type BluetoothConnectOptions } from \"../connect\";\nimport type { BluetoothConfig } from \"../smart-puzzle/bluetooth-puzzle\";\nimport { ganTimerConfig, type GanTimer } from \"./GanTimer\";\n\n/** @category Timers */\nexport type BluetoothTimer = GanTimer; // TODO\n\nconst smartTimerConfigs: BluetoothConfig<BluetoothTimer>[] = [ganTimerConfig];\n\n/** @category Timers */\nexport async function connectSmartTimer(\n options?: BluetoothConnectOptions,\n): Promise<BluetoothTimer> {\n return bluetoothConnect<BluetoothTimer>(smartTimerConfigs, options);\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["let DEBUG_LOGGING_ENABLED = false;\n\nexport function enableDebugLogging(enable: boolean): void {\n DEBUG_LOGGING_ENABLED = enable;\n}\n\n// TODO: Remove this.\nexport function debugLog(...args: any[]): void {\n if (!DEBUG_LOGGING_ENABLED) {\n return;\n }\n\n if (console.info) {\n console.info(...args);\n } else {\n console.log(...args);\n }\n}\n", "import { Quaternion, Vector3 } from \"three\";\nimport type {\n AlgLeafEvent,\n OrientationEvent,\n} from \"./smart-puzzle/bluetooth-puzzle\";\n\n// TODO: Combine orientation and alg leaves into a single event to handle quaternion remapping.\nexport interface StreamTransformer {\n // Modifies the input.\n transformAlgLeaf(algLeafEvent: AlgLeafEvent): void;\n // Modifies the input.\n transformOrientation(orientationEvent: OrientationEvent): void;\n}\n\nfunction maxAxis(v: Vector3): string {\n const maxVal = Math.max(Math.abs(v.x), Math.abs(v.y), Math.abs(v.z));\n switch (maxVal) {\n case v.x:\n return \"x\";\n case -v.x:\n return \"-x\";\n case v.y:\n return \"y\";\n case -v.y:\n return \"-y\";\n case v.z:\n return \"z\";\n case -v.z:\n return \"-z\";\n default:\n throw new Error(\"Uh-oh.\");\n }\n}\n\nconst s2 = Math.sqrt(0.5);\n\nconst m: { [s: string]: Quaternion } = {\n \"y z\": new Quaternion(0, 0, 0, 1),\n \"-z y\": new Quaternion(s2, 0, 0, s2),\n \"x z\": new Quaternion(0, 0, -s2, s2),\n \"-x z\": new Quaternion(0, 0, s2, s2),\n};\n\nexport class BasicRotationTransformer implements StreamTransformer {\n // private reorientQuat = new Quaternion();\n\n public transformAlgLeaf(_algLeafEvent: AlgLeafEvent): void {\n // Nothing to do.\n }\n\n public transformOrientation(orientationEvent: OrientationEvent): void {\n const { x, y, z, w } = orientationEvent.quaternion;\n const quat = new Quaternion(x, y, z, w);\n\n const U = new Vector3(0, 1, 0);\n const F = new Vector3(0, 0, 1);\n const maxU = maxAxis(U.applyQuaternion(quat));\n const maxF = maxAxis(F.applyQuaternion(quat));\n\n const oriQuat = m[`${maxU} ${maxF}`] || m[\"y z\"];\n\n console.log(quat);\n console.log(oriQuat);\n const q2 = quat.premultiply(oriQuat);\n\n // console.log(maxAxis(U.applyQuaternion(quat)), maxAxis(F.applyQuaternion(quat)));\n console.log(q2);\n\n orientationEvent.quaternion = quat;\n\n console.log(orientationEvent.quaternion);\n }\n}\n", "import type { AlgLeaf } from \"../../alg/alg-nodes/AlgNode\";\nimport type { KPattern } from \"../../kpuzzle/KPattern\";\nimport {\n BasicRotationTransformer,\n type StreamTransformer,\n} from \"../transformer\";\n\n/******** BluetoothPuzzle ********/\n\n// TODO: Use actual `CustomEvent`s?\n// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent\n/** @category Smart Puzzles */\nexport interface AlgLeafEvent {\n latestAlgLeaf: AlgLeaf;\n timeStamp: number;\n debug?: Record<string, unknown>;\n pattern?: KPattern;\n quaternion?: any; // TODO: Unused\n}\n\n// TODO: Only use the `quaternion` field in the `AlgLeafEvent`?\n/** @category Smart Puzzles */\nexport interface OrientationEvent {\n quaternion: {\n x: number;\n y: number;\n z: number;\n w: number;\n };\n timeStamp: number;\n debug?: Record<string, unknown>;\n}\n\nexport interface BluetoothConfig<T> {\n connect: (\n server: BluetoothRemoteGATTServer,\n device?: BluetoothDevice,\n ) => Promise<T>;\n // TODO: Can we reuse `filters`?\n prefixes: string[]; // `[\"\"]` for GiiKER\n filters: BluetoothLEScanFilter[];\n optionalServices: BluetoothServiceUUID[];\n}\n\n// TODO: Expose device name (and/or globally unique identifier)?\n\n/** @category Smart Puzzles */\nexport abstract class BluetoothPuzzle extends EventTarget {\n public transformers: StreamTransformer[] = [];\n protected listeners: Array<(e: AlgLeafEvent) => void> = []; // TODO: type\n protected orientationListeners: Array<(e: OrientationEvent) => void> = []; // TODO: type\n\n public abstract name(): string | undefined;\n public abstract disconnect(): void; // TODO: Can we make this reutrn (async) on success?\n\n // TODO: require subclasses to implement this?\n public async getPattern(): Promise<KPattern> {\n throw new Error(\"cannot get pattern\");\n }\n\n public addAlgLeafListener(listener: (e: AlgLeafEvent) => void): void {\n this.listeners.push(listener);\n }\n\n public addOrientationListener(listener: (e: OrientationEvent) => void): void {\n this.orientationListeners.push(listener);\n }\n\n public experimentalAddBasicRotationTransformer(): void {\n this.transformers.push(new BasicRotationTransformer());\n }\n\n protected dispatchAlgLeaf(algLeaf: AlgLeafEvent): void {\n for (const transformer of this.transformers) {\n transformer.transformAlgLeaf(algLeaf);\n }\n for (const l of this.listeners) {\n l(algLeaf);\n }\n }\n\n protected dispatchOrientation(orientationEvent: OrientationEvent): void {\n for (const transformer of this.transformers) {\n transformer.transformOrientation(orientationEvent);\n }\n const { x, y, z, w } = orientationEvent.quaternion;\n // TODO: can we avoid mutating the source event?\n orientationEvent.quaternion = {\n x,\n y,\n z,\n w,\n };\n for (const l of this.orientationListeners) {\n // TODO: Convert quaternion.\n l(orientationEvent);\n }\n }\n}\n", "import { Alg, keyToMove } from \"../alg\";\nimport type { KPuzzle } from \"../kpuzzle\";\nimport type { KPattern } from \"../kpuzzle/KPattern\";\nimport { puzzles } from \"../puzzles\";\nimport { BluetoothPuzzle } from \"./smart-puzzle/bluetooth-puzzle\";\n\n/** @category Keyboard Puzzles */\nexport class KeyboardPuzzle extends BluetoothPuzzle {\n private puzzle: Promise<KPuzzle> = puzzles[\"3x3x3\"].kpuzzle();\n private pattern: Promise<KPattern> = (async () =>\n (await this.puzzle).defaultPattern())();\n\n listener: (e: KeyboardEvent) => Promise<void>;\n\n // TODO: Decide on the right arguments.\n constructor(private target: Element) {\n super();\n // TODO: Filter out repeated keydown?\n this.listener = this.onKeyDown.bind(this);\n target.addEventListener(\"keydown\", this.listener);\n }\n\n public name(): string | undefined {\n return \"Keyboard Input\";\n }\n\n disconnect() {\n this.target.removeEventListener(\"keydown\", this.listener);\n }\n\n public override async getPattern(): Promise<KPattern> {\n return this.pattern;\n }\n\n private async onKeyDown(e: KeyboardEvent): Promise<void> {\n if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {\n return;\n }\n\n const algLeaf = keyToMove(e);\n if (algLeaf) {\n const newPattern = (await this.pattern).applyAlg(new Alg([algLeaf])); // TODO\n this.pattern = Promise.resolve(newPattern);\n this.dispatchAlgLeaf({\n latestAlgLeaf: algLeaf,\n timeStamp: e.timeStamp,\n pattern: newPattern,\n });\n e.preventDefault();\n }\n }\n}\n\n// TODO: Type\n/** @category Keyboard Puzzles */\nexport async function debugKeyboardConnect(\n target: any = window,\n): Promise<KeyboardPuzzle> {\n return new KeyboardPuzzle(target);\n}\n", "import { debugLog } from \"../debug\";\nimport type { BluetoothConfig } from \"../smart-puzzle/bluetooth-puzzle\";\n\n/******** requestOptions ********/\n\nfunction requestOptions<T>(\n configs: BluetoothConfig<T>[],\n acceptAllDevices: boolean = false,\n): RequestDeviceOptions {\n const options = acceptAllDevices\n ? {\n acceptAllDevices: true,\n optionalServices: [] as BluetoothServiceUUID[],\n }\n : {\n filters: [] as BluetoothLEScanFilter[],\n optionalServices: [] as BluetoothServiceUUID[],\n };\n for (const config of configs) {\n if (!acceptAllDevices) {\n options.filters = options.filters!.concat(config.filters);\n }\n options.optionalServices = options.optionalServices.concat(\n config.optionalServices,\n );\n }\n debugLog({ requestOptions: options });\n return options;\n}\n\n/******** connect() ********/\n\nexport interface BluetoothConnectOptions {\n acceptAllDevices?: boolean;\n}\n\n// We globally track the number of connection failures,\n// in order to offer the user recourse (accept all devices) if they're having issues.\n// This allows us to future-proof situations where a device might not show up in\n// the chooser, but works if we connect.\nlet consecutiveFailures = 0;\nconst MAX_FAILURES_BEFORE_ACCEPT_ALL_FALLBACK = 2;\n\n// TODO: Debug options to allow connecting to any device?\nexport async function bluetoothConnect<T>(\n configs: BluetoothConfig<T>[],\n options: BluetoothConnectOptions = {},\n): Promise<T> {\n debugLog(\"Attempting to pair.\");\n let device: BluetoothDevice;\n try {\n let acceptAllDevices = options.acceptAllDevices;\n if (\n !acceptAllDevices &&\n consecutiveFailures >= MAX_FAILURES_BEFORE_ACCEPT_ALL_FALLBACK\n ) {\n console.info(\n `The last ${MAX_FAILURES_BEFORE_ACCEPT_ALL_FALLBACK} Bluetooth puzzle connection attempts failed. This time, the Bluetooth prompt will show all possible devices.`,\n );\n acceptAllDevices = true;\n }\n device = await navigator.bluetooth.requestDevice(\n requestOptions<T>(configs, acceptAllDevices),\n );\n consecutiveFailures = 0;\n } catch (e) {\n consecutiveFailures++;\n throw new Error(e);\n }\n debugLog(\"Device:\", device);\n\n if (typeof device.gatt === \"undefined\") {\n return Promise.reject(\"Device did not have a GATT server.\");\n }\n\n const server = await device.gatt.connect();\n debugLog(\"Server:\", server);\n\n const name = server.device?.name || \"\";\n\n // TODO by reading supported matched filters or provided services.\n\n for (const config of configs) {\n for (const prefix of config.prefixes) {\n if (name?.startsWith(prefix)) {\n return config.connect(server, device);\n }\n }\n }\n\n throw Error(\"Unknown Bluetooth devive.\");\n}\n", "/* tslint:disable no-bitwise */\n\nimport { Quaternion } from \"three\";\nimport { Move } from \"../../alg\";\nimport type { KPuzzle, KPatternData } from \"../../kpuzzle\";\nimport { KPattern } from \"../../kpuzzle\";\nimport { puzzles } from \"../../puzzles\";\nimport {\n importKey,\n unsafeDecryptBlock,\n} from \"../../vendor/public-domain/unsafe-raw-aes/unsafe-raw-aes\";\nimport { debugLog } from \"../debug\";\nimport { type BluetoothConfig, BluetoothPuzzle } from \"./bluetooth-puzzle\";\n\n// This needs to be short enough to capture 6 moves (OBQTM).\nconst DEFAULT_INTERVAL_MS = 150;\n// Number of latest moves provided by the Gan 356i.\nconst MAX_LATEST_MOVES = 6;\n\nconst ganMoveToBlockMove: { [i: number]: Move } = {\n 0 /* 0x00 */: new Move(\"U\"),\n 2 /* 0x02 */: new Move(\"U\", -1),\n 3 /* 0x03 */: new Move(\"R\"),\n 5 /* 0x05 */: new Move(\"R\", -1),\n 6 /* 0x06 */: new Move(\"F\"),\n 8 /* 0x08 */: new Move(\"F\", -1),\n 9 /* 0x09 */: new Move(\"D\"),\n 11 /* 0x0b */: new Move(\"D\", -1),\n 12 /* 0x0c */: new Move(\"L\"),\n 14 /* 0x0e */: new Move(\"L\", -1),\n 15 /* 0x0f */: new Move(\"B\"),\n 17 /* 0x11 */: new Move(\"B\", -1),\n};\n\nlet homeQuatInverse: Quaternion | null = null;\n\nfunction probablyDecodedCorrectly(data: Uint8Array): boolean {\n return (\n data[13] < 0x12 &&\n data[14] < 0x12 &&\n data[15] < 0x12 &&\n data[16] < 0x12 &&\n data[17] < 0x12 &&\n data[18] < 0x12\n );\n}\n\nconst key10 = new Uint8Array([\n 198, 202, 21, 223, 79, 110, 19, 182, 119, 13, 230, 89, 58, 175, 186, 162,\n]);\nconst key11 = new Uint8Array([\n 67, 226, 91, 214, 125, 220, 120, 216, 7, 96, 163, 218, 130, 60, 1, 241,\n]);\n\n// Clean-room reverse-engineered\nasync function decryptPattern(\n data: Uint8Array,\n aesKey: CryptoKey | null,\n): Promise<Uint8Array> {\n if (aesKey === null) {\n return data;\n }\n\n const copy = new Uint8Array(data);\n copy.set(new Uint8Array(await unsafeDecryptBlock(aesKey, copy.slice(3))), 3);\n copy.set(\n new Uint8Array(await unsafeDecryptBlock(aesKey, copy.slice(0, 16))),\n 0,\n );\n\n if (probablyDecodedCorrectly(copy)) {\n return copy;\n }\n\n throw new Error(\"Invalid Gan cube pattern\");\n}\n\nclass PhysicalState {\n public static async read(\n characteristic: BluetoothRemoteGATTCharacteristic,\n aesKey: CryptoKey | null,\n ): Promise<PhysicalState> {\n const value = await decryptPattern(\n new Uint8Array((await characteristic.readValue()).buffer),\n aesKey,\n );\n const timeStamp = Date.now();\n // console.log(value);\n return new PhysicalState(new DataView(value.buffer), timeStamp);\n }\n\n private arr: Uint8Array;\n private arrLen = 19;\n private constructor(\n private dataView: DataView,\n public timeStamp: number,\n ) {\n this.arr = new Uint8Array(dataView.buffer);\n if (this.arr.length !== this.arrLen) {\n throw new Error(\"Unexpected array length\");\n }\n }\n\n public rotQuat(): Quaternion {\n let x = this.dataView.getInt16(0, true) / 16384;\n let y = this.dataView.getInt16(2, true) / 16384;\n let z = this.dataView.getInt16(4, true) / 16384;\n [x, y, z] = [-y, z, -x];\n const wSquared = 1 - (x * x + y * y + z * z);\n const w = wSquared > 0 ? Math.sqrt(wSquared) : 0;\n const quat = new Quaternion(x, y, z, w);\n\n if (!homeQuatInverse) {\n homeQuatInverse = quat.clone().invert();\n }\n\n return quat.clone().multiply(homeQuatInverse.clone());\n }\n\n // Loops from 255 to 0.\n public moveCounter(): number {\n return this.arr[12];\n }\n\n public numMovesSince(previousMoveCounter: number): number {\n return (this.moveCounter() - previousMoveCounter) & 0xff;\n }\n\n // Due to the design of the Gan356i protocol, it's common to query for the\n // latest physical state and find 0 moves have been performed since the last\n // query. Therefore, it's useful to allow 0 as an argument.\n public latestMoves(n: number): Move[] {\n if (n < 0 || n > MAX_LATEST_MOVES) {\n throw new Error(`Must ask for 0 to 6 latest moves. (Asked for ${n})`);\n }\n return Array.from(this.arr.slice(19 - n, 19)).map(\n (i) => ganMoveToBlockMove[i],\n );\n }\n\n public debugInfo(): { arr: Uint8Array } {\n return {\n arr: this.arr,\n };\n }\n}\n\n// TODO: Short IDs\nconst UUIDs = {\n ganCubeService: \"0000fff0-0000-1000-8000-00805f9b34fb\",\n physicalStateCharacteristic: \"0000fff5-0000-1000-8000-00805f9b34fb\",\n actualAngleAndBatteryCharacteristic: \"0000fff7-0000-1000-8000-00805f9b34fb\",\n faceletStatus1Characteristic: \"0000fff2-0000-1000-8000-00805f9b34fb\",\n faceletStatus2Characteristic: \"0000fff3-0000-1000-8000-00805f9b34fb\",\n infoService: \"0000180a-0000-1000-8000-00805f9b34fb\",\n systemIDCharacteristic: \"00002a23-0000-1000-8000-00805f9b34fb\",\n versionCharacteristic: \"00002a28-0000-1000-8000-00805f9b34fb\",\n};\n\nconst commands: { [cmd: string]: BufferSource } = {\n reset: new Uint8Array([\n 0x00, 0x00, 0x24, 0x00, 0x49, 0x92, 0x24, 0x49, 0x6d, 0x92, 0xdb, 0xb6,\n 0x49, 0x92, 0xb6, 0x24, 0x6d, 0xdb,\n ]),\n};\n\nfunction buf2hex(buffer: ArrayBuffer): string {\n // buffer is an ArrayBuffer\n return (\n Array.prototype.map.call(new Uint8Array(buffer), (x: number) =>\n `00${x.toString(16)}`.slice(-2),\n ) as string[]\n ).join(\" \");\n}\n\nconst reidEdgeOrder = \"UF UR UB UL DF DR DB DL FR FL BR BL\".split(\" \");\nconst reidCornerOrder = \"UFR URB UBL ULF DRF DFL DLB DBR\".split(\" \");\n\ninterface PieceInfo {\n piece: number;\n orientation: number;\n}\n\nfunction rotateLeft(s: string, i: number): string {\n return s.slice(i) + s.slice(0, i);\n}\n\nconst pieceMap: { [s: string]: PieceInfo } = {};\n// TODO: Condense the for loops.\nreidEdgeOrder.forEach((edge, idx) => {\n for (let i = 0; i < 2; i++) {\n pieceMap[rotateLeft(edge, i)] = { piece: idx, orientation: i };\n }\n});\nreidCornerOrder.forEach((corner, idx) => {\n for (let i = 0; i < 3; i++) {\n pieceMap[rotateLeft(corner, i)] = { piece: idx, orientation: i };\n }\n});\n\nconst gan356iCornerMappings = [\n [0, 21, 15],\n [5, 13, 47],\n [7, 45, 39],\n [2, 37, 23],\n [29, 10, 16],\n [31, 18, 32],\n [26, 34, 40],\n [24, 42, 8],\n];\n\nconst gan356iEdgeMappings = [\n [1, 22],\n [3, 14],\n [6, 46],\n [4, 38],\n [30, 17],\n [27, 9],\n [25, 41],\n [28, 33],\n [19, 12],\n [20, 35],\n [44, 11],\n [43, 36],\n];\nconst faceOrder = \"URFDLB\";\n\nasync function getKey(\n server: BluetoothRemoteGATTServer,\n): Promise<CryptoKey | null> {\n const infoService = await server.getPrimaryService(UUIDs.infoService);\n\n const versionCharacteristic = await infoService.getCharacteristic(\n UUIDs.versionCharacteristic,\n );\n const versionBuffer = new Uint8Array(\n (await versionCharacteristic.readValue()).buffer,\n );\n\n const versionValue =\n (((versionBuffer[0] << 8) + versionBuffer[1]) << 8) + versionBuffer[2];\n if (versionValue < 0x01_00_08) {\n return null;\n }\n\n const keyXor = versionValue < 0x01_01_00 ? key10 : key11;\n\n const systemIDCharacteristic = await infoService.getCharacteristic(\n UUIDs.systemIDCharacteristic,\n );\n const systemID = new Uint8Array(\n (await systemIDCharacteristic.readValue()).buffer,\n ).reverse();\n\n const key = new Uint8Array(keyXor);\n for (let i = 0; i < systemID.length; i++) {\n key[i] = (key[i] + systemID[i]) % 256;\n }\n\n return importKey(key);\n}\n\n/** @category Smart Puzzles */\nexport class GanCube extends BluetoothPuzzle {\n // We have to perform async operations before we call the constructor.\n public static async connect(\n server: BluetoothRemoteGATTServer,\n ): Promise<GanCube> {\n const ganCubeService = await server.getPrimaryService(UUIDs.ganCubeService);\n debugLog(\"Service:\", ganCubeService);\n\n const physicalStateCharacteristic = await ganCubeService.getCharacteristic(\n UUIDs.physicalStateCharacteristic,\n );\n debugLog(\"Characteristic:\", physicalStateCharacteristic);\n\n const aesKey = await getKey(server);\n\n const initialMoveCounter = (\n await PhysicalState.read(physicalStateCharacteristic, aesKey)\n ).moveCounter();\n debugLog(\"Initial Move Counter:\", initialMoveCounter);\n const cube = new GanCube(\n await puzzles[\"3x3x3\"].kpuzzle(),\n ganCubeService,\n server,\n physicalStateCharacteristic,\n initialMoveCounter,\n aesKey,\n );\n return cube;\n }\n\n public INTERVAL_MS: number = DEFAULT_INTERVAL_MS;\n private intervalHandle: number | null = null;\n private pattern: KPattern;\n private cachedFaceletStatus1Characteristic: Promise<BluetoothRemoteGATTCharacteristic>;\n\n private cachedFaceletStatus2Characteristic: Promise<BluetoothRemoteGATTCharacteristic>;\n\n private cachedActualAngleAndBatteryCharacteristic: Promise<BluetoothRemoteGATTCharacteristic>;\n\n private constructor(\n private kpuzzle: KPuzzle,\n private service: BluetoothRemoteGATTService,\n private server: BluetoothRemoteGATTServer,\n private physicalStateCharacteristic: BluetoothRemoteGATTCharacteristic,\n private lastMoveCounter: number,\n private aesKey: CryptoKey | null,\n ) {\n super();\n this.pattern = kpuzzle.defaultPattern();\n this.startTrackingMoves();\n }\n\n public name(): string | undefined {\n return this.server.device.name;\n }\n\n disconnect(): void {\n this.server.disconnect();\n }\n\n public startTrackingMoves(): void {\n // `window.setInterval` instead of `setInterval`:\n // https://github.com/Microsoft/TypeScript/issues/842#issuecomment-252445883\n this.intervalHandle = window.setInterval(\n this.intervalHandler.bind(this),\n this.INTERVAL_MS,\n );\n }\n\n public stopTrackingMoves(): void {\n if (!this.intervalHandle) {\n throw new Error(\"Not tracking moves!\");\n }\n clearInterval(this.intervalHandle);\n this.intervalHandle = null;\n }\n\n // TODO: Can we ever receive async responses out of order?\n public async intervalHandler(): Promise<void> {\n const physicalState = await PhysicalState.read(\n this.physicalStateCharacteristic,\n this.aesKey,\n );\n let numInterveningMoves = physicalState.numMovesSince(this.lastMoveCounter);\n // console.log(numInterveningMoves);\n if (numInterveningMoves > MAX_LATEST_MOVES) {\n debugLog(\n `Too many moves! Dropping ${\n numInterveningMoves - MAX_LATEST_MOVES\n } moves`,\n );\n numInterveningMoves = MAX_LATEST_MOVES;\n }\n for (const move of physicalState.latestMoves(numInterveningMoves)) {\n // console.log(move);\n this.pattern = this.pattern.applyMove(move);\n this.dispatchAlgLeaf({\n latestAlgLeaf: move,\n timeStamp: physicalState.timeStamp,\n debug: physicalState.debugInfo(),\n pattern: this.pattern,\n // quaternion: physicalState.rotQuat(),\n });\n }\n this.dispatchOrientation({\n timeStamp: physicalState.timeStamp,\n quaternion: physicalState.rotQuat(),\n });\n this.lastMoveCounter = physicalState.moveCounter();\n }\n\n public async getBattery(): Promise<number> {\n return new Uint8Array(\n await this.readActualAngleAndBatteryCharacteristic(),\n )[7];\n }\n\n public override async getPattern(): Promise<KPattern> {\n const arr: Uint8Array = await decryptPattern(\n new Uint8Array(await this.readFaceletStatus1Characteristic()),\n this.aesKey,\n );\n const stickers: number[] = [];\n for (let i = 0; i < 18; i += 3) {\n let v = (((arr[i ^ 1] << 8) + arr[(i + 1) ^ 1]) << 8) + arr[(i + 2) ^ 1];\n for (let j = 0; j < 8; j++) {\n stickers.push(v & 7);\n v >>= 3;\n }\n }\n\n const patternData: KPatternData = {\n CORNERS: {\n pieces: [],\n orientation: [],\n },\n EDGES: {\n pieces: [],\n orientation: [],\n },\n CENTERS: {\n pieces: [0, 1, 2, 3, 4, 5],\n orientation: [0, 0, 0, 0, 0, 0],\n orientationMod: [1, 1, 1, 1, 1, 1], // TODO\n },\n };\n\n for (const cornerMapping of gan356iCornerMappings) {\n const pieceInfo: PieceInfo =\n pieceMap[cornerMapping.map((i) => faceOrder[stickers[i]]).join(\"\")];\n patternData.CORNERS.pieces.push(pieceInfo.piece);\n patternData.CORNERS.orientation.push(pieceInfo.orientation);\n }\n\n for (const edgeMapping of gan356iEdgeMappings) {\n const pieceInfo: PieceInfo =\n pieceMap[edgeMapping.map((i) => faceOrder[stickers[i]]).join(\"\")];\n patternData.EDGES.pieces.push(pieceInfo.piece);\n patternData.EDGES.orientation.push(pieceInfo.orientation);\n }\n\n return new KPattern(this.kpuzzle, patternData);\n }\n\n public async faceletStatus1Characteristic(): Promise<BluetoothRemoteGATTCharacteristic> {\n this.cachedFaceletStatus1Characteristic =\n this.cachedFaceletStatus1Characteristic ||\n this.service.getCharacteristic(UUIDs.faceletStatus1Characteristic);\n return this.cachedFaceletStatus1Characteristic;\n }\n\n public async faceletStatus2Characteristic(): Promise<BluetoothRemoteGATTCharacteristic> {\n this.cachedFaceletStatus2Characteristic =\n this.cachedFaceletStatus2Characteristic ||\n this.service.getCharacteristic(UUIDs.faceletStatus2Characteristic);\n return this.cachedFaceletStatus2Characteristic;\n }\n\n public async actualAngleAndBatteryCharacteristic(): Promise<BluetoothRemoteGATTCharacteristic> {\n this.cachedActualAngleAndBatteryCharacteristic =\n this.cachedActualAngleAndBatteryCharacteristic ||\n this.service.getCharacteristic(UUIDs.actualAngleAndBatteryCharacteristic);\n return this.cachedActualAngleAndBatteryCharacteristic;\n }\n\n public async reset(): Promise<void> {\n const faceletStatus1Characteristic =\n await this.faceletStatus1Characteristic();\n await faceletStatus1Characteristic.writeValue(commands.reset);\n }\n\n public async readFaceletStatus1Characteristic(): Promise<ArrayBuffer> {\n const faceletStatus1Characteristic =\n await this.faceletStatus1Characteristic();\n return (await faceletStatus1Characteristic.readValue()).buffer;\n }\n\n public async readFaceletStatus2Characteristic(): Promise<string> {\n const faceletStatus2Characteristic =\n await this.faceletStatus2Characteristic();\n return buf2hex((await faceletStatus2Characteristic.readValue()).buffer);\n }\n\n public async readActualAngleAndBatteryCharacteristic(): Promise<ArrayBuffer> {\n const actualAngleAndBatteryCharacteristic =\n await this.actualAngleAndBatteryCharacteristic();\n return (await actualAngleAndBatteryCharacteristic.readValue()).buffer;\n }\n // TODO\n // private onphysicalStateCharacteristicChanged(event: any): void {\n // var val = event.target.value;\n // debugLog(val);\n // }\n}\n\n// // TODO: Move this into a factory?\nexport const ganConfig: BluetoothConfig<BluetoothPuzzle> = {\n connect: GanCube.connect.bind(GanCube),\n prefixes: [\"GAN\"],\n filters: [{ namePrefix: \"GAN\" }],\n optionalServices: [UUIDs.ganCubeService, UUIDs.infoService],\n};\n", "// Note: we could use the `unsafe-raw-aes` npm package instead. But:\n//\n// 1. This is a rather small amount of code, thanks to a clever hack of the Web Crypto API.\n// 2. This code is used (and therefore loaded) only for Gan cube decoding, and unlikely to be needed directly by projects using `cubing.js`.\n// 3. A dependency called `unsafe-raw-aes` would (rightfully) raise some eyebrows.\n//\n// So we just vendor the entire file instead.\n\nconst blockSize = 16;\nconst zeros = new Uint8Array(blockSize);\nconst paddingBlockPlaintext = new Uint8Array(\n new Array(blockSize).fill(blockSize),\n);\nconst AES_CBC = \"AES-CBC\";\n\nexport async function importKey(\n keyBytes: ArrayBuffer | Uint8Array,\n): Promise<CryptoKey> {\n return await crypto.subtle.importKey(\"raw\", keyBytes, AES_CBC, true, [\n \"encrypt\",\n \"decrypt\",\n ]);\n}\n\nasync function unsafeEncryptBlockWithIV(\n key: CryptoKey,\n plaintextBlock: ArrayBuffer | Uint8Array,\n iv: ArrayBuffer | Uint8Array,\n): Promise<ArrayBuffer> {\n const cryptoResult: ArrayBuffer = await window.crypto.subtle.encrypt(\n {\n name: AES_CBC,\n iv,\n },\n key,\n plaintextBlock,\n );\n return cryptoResult.slice(0, blockSize);\n}\n\nexport async function unsafeEncryptBlock(\n key: CryptoKey,\n plaintextBlock: ArrayBuffer | Uint8Array,\n): Promise<ArrayBuffer> {\n return (await unsafeEncryptBlockWithIV(key, plaintextBlock, zeros)).slice(\n 0,\n blockSize,\n );\n}\n\nexport async function unsafeDecryptBlock(\n key: CryptoKey,\n ciphertextBlock: ArrayBuffer | Uint8Array,\n): Promise<ArrayBuffer> {\n const paddingBlock = await unsafeEncryptBlockWithIV(\n key,\n paddingBlockPlaintext,\n ciphertextBlock,\n );\n\n const cbcCiphertext = new Uint8Array(2 * blockSize);\n cbcCiphertext.set(new Uint8Array(ciphertextBlock), 0);\n cbcCiphertext.set(new Uint8Array(paddingBlock), blockSize);\n\n const cryptoResult: ArrayBuffer = await window.crypto.subtle.decrypt(\n {\n name: AES_CBC,\n iv: zeros,\n },\n key,\n cbcCiphertext,\n );\n return cryptoResult.slice(0, blockSize);\n}\n", "/* tslint:disable no-bitwise */\n\nimport { Move } from \"../../alg\";\nimport { KPattern, type KPatternData } from \"../../kpuzzle\";\nimport { experimental3x3x3KPuzzle } from \"../../puzzles/cubing-private\";\nimport { debugLog } from \"../debug\";\nimport { BluetoothPuzzle, type BluetoothConfig } from \"./bluetooth-puzzle\";\n\nconst MESSAGE_LENGTH = 20;\n\nconst UUIDs = {\n cubeService: \"0000aadb-0000-1000-8000-00805f9b34fb\",\n cubeCharacteristic: \"0000aadc-0000-1000-8000-00805f9b34fb\",\n};\n\n// TODO: Expose for testing.\nfunction giikerMoveToAlgMove(face: number, amount: number): Move {\n switch (amount) {\n case 3: {\n amount = -1;\n break;\n }\n case 9: {\n debugLog(\"Encountered 9\", face, amount);\n amount = -2;\n break;\n }\n }\n\n const family = [\"?\", \"B\", \"D\", \"L\", \"U\", \"R\", \"F\"][face];\n return new Move(family, amount);\n}\n\nexport { giikerMoveToAlgMove as giikerMoveToAlgMoveForTesting };\n\nfunction giikerStateStr(giikerState: number[]): string {\n let str = \"\";\n str += giikerState.slice(0, 8).join(\".\");\n str += \"\\n\";\n str += giikerState.slice(8, 16).join(\".\");\n str += \"\\n\";\n str += giikerState.slice(16, 28).join(\".\");\n str += \"\\n\";\n str += giikerState.slice(28, 32).join(\".\");\n str += \"\\n\";\n str += giikerState.slice(32, 40).join(\".\");\n return str;\n}\n\n// TODO\n// const Reid333Orbits = {\n// \"EDGES\": {\"numPieces\": 12, \"orientations\": 2},\n// \"CORNERS\": {\"numPieces\": 8, \"orientations\": 3},\n// \"CENTERS\": {\"numPieces\": 6, \"orientations\": 4}\n// };\n\nconst Reid333SolvedCenters = {\n pieces: [0, 1, 2, 3, 4, 5],\n orientation: [0, 0, 0, 0, 0, 0],\n orientationMod: [1, 1, 1, 1, 1, 1], // TODO\n};\n\nconst epGiiKERtoReid333: number[] = [4, 8, 0, 9, 5, 1, 3, 7, 6, 10, 2, 11];\nconst epReid333toGiiKER: number[] = [2, 5, 10, 6, 0, 4, 8, 7, 1, 3, 9, 11];\n\nconst preEO: number[] = [1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0];\nconst postEO: number[] = [1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0];\n\nconst cpGiiKERtoReid333: number[] = [4, 0, 3, 5, 7, 1, 2, 6];\nconst cpReid333toGiiKER: number[] = [1, 5, 6, 2, 0, 3, 7, 4];\n\nconst preCO: number[] = [1, 2, 1, 2, 2, 1, 2, 1];\nconst postCO: number[] = [2, 1, 2, 1, 1, 2, 1, 2];\n\nconst coFlip: number[] = [-1, 1, -1, 1, 1, -1, 1, -1];\n\nfunction getNibble(val: Uint8Array, i: number): number {\n if (i % 2 === 1) {\n return val[(i / 2) | 0] % 16;\n }\n return 0 | (val[(i / 2) | 0] / 16);\n}\n\nfunction probablyEncrypted(data: Uint8Array): boolean {\n return data[18] === 0xa7;\n}\n\nconst lookup = [\n 176, 81, 104, 224, 86, 137, 237, 119, 38, 26, 193, 161, 210, 126, 150, 81, 93,\n 13, 236, 249, 89, 235, 88, 24, 113, 81, 214, 131, 130, 199, 2, 169, 39, 165,\n 171, 41,\n];\n\nfunction decryptState(data: Uint8Array): Uint8Array {\n const offset1 = getNibble(data, 38);\n const offset2 = getNibble(data, 39);\n const output = new Uint8Array(MESSAGE_LENGTH);\n for (let i = 0; i < MESSAGE_LENGTH; i++) {\n output[i] = data[i] + lookup[offset1 + i] + lookup[offset2 + i];\n }\n return output;\n}\n\n// TODO: Support caching which decoding strategy worked last time.\nasync function decodeState(data: Uint8Array): Promise<Uint8Array> {\n if (!probablyEncrypted(data)) {\n return data;\n }\n return decryptState(data);\n // TODO: Check that the decrypted state is a valid staet.\n}\n\n/** @category Smart Puzzles */\nexport class GiiKERCube extends BluetoothPuzzle {\n public static async connect(\n server: BluetoothRemoteGATTServer,\n ): Promise<GiiKERCube> {\n const cubeService = await server.getPrimaryService(UUIDs.cubeService);\n debugLog(\"Service:\", cubeService);\n\n const cubeCharacteristic = await cubeService.getCharacteristic(\n UUIDs.cubeCharacteristic,\n );\n debugLog(\"Characteristic:\", cubeCharacteristic);\n\n // TODO: Can we safely save the async promise instead of waiting for the response?\n\n const originalValue = await decodeState(\n new Uint8Array((await cubeCharacteristic.readValue()).buffer),\n );\n debugLog(\"Original value:\", originalValue);\n const cube = new GiiKERCube(server, cubeCharacteristic, originalValue);\n\n await cubeCharacteristic.startNotifications();\n cubeCharacteristic.addEventListener(\n \"characteristicvaluechanged\",\n cube.onCubeCharacteristicChanged.bind(cube),\n );\n\n return cube;\n }\n\n private constructor(\n private server: BluetoothRemoteGATTServer,\n private cubeCharacteristic: BluetoothRemoteGATTCharacteristic,\n private originalValue?: Uint8Array | null,\n ) {\n super();\n }\n\n public name(): string | undefined {\n return this.server.device.name;\n }\n\n disconnect(): void {\n this.server.disconnect();\n }\n\n public override async getPattern(): Promise<KPattern> {\n return this.toReid333(\n new Uint8Array((await this.cubeCharacteristic.readValue()).buffer),\n );\n }\n\n private getBit(val: Uint8Array, i: number): number {\n const n = (i / 8) | 0;\n const shift = 7 - (i % 8);\n return (val[n] >> shift) & 1;\n }\n\n private toReid333(val: Uint8Array): KPattern {\n const patternData: KPatternData = {\n EDGES: {\n pieces: new Array(12),\n orientation: new Array(12),\n },\n CORNERS: {\n pieces: new Array(8),\n orientation: new Array(8),\n },\n CENTERS: Reid333SolvedCenters,\n };\n\n for (let i = 0; i < 12; i++) {\n const gi = epReid333toGiiKER[i];\n patternData.EDGES.pieces[i] =\n epGiiKERtoReid333[getNibble(val, gi + 16) - 1];\n patternData.EDGES.orientation[i] =\n this.getBit(val, gi + 112) ^\n preEO[patternData.EDGES.pieces[i]] ^\n postEO[i];\n }\n for (let i = 0; i < 8; i++) {\n const gi = cpReid333toGiiKER[i];\n patternData.CORNERS.pieces[i] = cpGiiKERtoReid333[getNibble(val, gi) - 1];\n patternData.CORNERS.orientation[i] =\n (getNibble(val, gi + 8) * coFlip[gi] +\n preCO[patternData.CORNERS.pieces[i]] +\n postCO[i]) %\n 3;\n }\n return new KPattern(experimental3x3x3KPuzzle, patternData);\n }\n\n private async onCubeCharacteristicChanged(event: any): Promise<void> {\n const val = await decodeState(new Uint8Array(event.target.value.buffer));\n debugLog(val);\n debugLog(val);\n\n if (this.isRepeatedInitialValue(val)) {\n debugLog(\"Skipping repeated initial value.\");\n return;\n }\n\n const giikerState = [];\n for (let i = 0; i < MESSAGE_LENGTH; i++) {\n giikerState.push(Math.floor(val[i] / 16));\n giikerState.push(val[i] % 16);\n }\n debugLog(giikerState);\n const str = giikerStateStr(giikerState);\n debugLog(str);\n\n this.dispatchAlgLeaf({\n latestAlgLeaf: giikerMoveToAlgMove(giikerState[32], giikerState[33]),\n timeStamp: event.timeStamp,\n debug: {\n stateStr: str,\n },\n pattern: this.toReid333(val),\n });\n }\n\n private isRepeatedInitialValue(val: Uint8Array): boolean {\n if (typeof this.originalValue === \"undefined\") {\n // TODO: Test this branch.\n throw new Error(\"GiiKERCube has uninitialized original value.\");\n }\n\n if (this.originalValue === null) {\n return false;\n }\n\n const originalValue = this.originalValue;\n // Reset the value here, so we can return early below.\n this.originalValue = null;\n\n debugLog(\"Comparing against original value.\");\n for (let i = 0; i < MESSAGE_LENGTH - 2; i++) {\n if (originalValue[i] !== val[i]) {\n debugLog(\"Different at index \", i);\n return false;\n }\n }\n return true;\n }\n}\n\n// TODO: Move this into a factory?\nexport const giiKERConfig: BluetoothConfig<BluetoothPuzzle> = {\n connect: GiiKERCube.connect.bind(GiiKERCube),\n prefixes: [\"Gi\", \"\", \"Mi\", \"Hi-\"], // Hack\n filters: [\n // Known prefixes: GiC, GiS (3x3x3), Gi2 (2x2x2)\n // Suspected prefixes GiY, Gi3\n { namePrefix: \"Gi\" },\n { namePrefix: \"Mi\" },\n { namePrefix: \"Hi-\" },\n { services: [\"0000aadb-0000-1000-8000-00805f9b34fb\"] },\n { services: [\"0000aaaa-0000-1000-8000-00805f9b34fb\"] },\n { services: [\"0000fe95-0000-1000-8000-00805f9b34fb\"] },\n ],\n optionalServices: [\n // \"00001530-1212-efde-1523-785feabcd123\",\n // \"0000aaaa-0000-1000-8000-00805f9b34fb\",\n UUIDs.cubeService,\n // \"0000180f-0000-1000-8000-00805f9b34fb\",\n // \"0000180a-0000-1000-8000-00805f9b34fb\"\n ],\n};\n", "import { Quaternion } from \"three\";\nimport { Alg, experimentalAppendMove, Move } from \"../../alg\";\nimport { debugLog } from \"../debug\";\nimport { type BluetoothConfig, BluetoothPuzzle } from \"./bluetooth-puzzle\";\n\nconst UUIDs = {\n goCubeService: \"6e400001-b5a3-f393-e0a9-e50e24dcca9e\",\n goCubeStateCharacteristic: \"6e400003-b5a3-f393-e0a9-e50e24dcca9e\",\n};\n\n// https://stackoverflow.com/a/40031979\nfunction buf2hex(buffer: ArrayBuffer): string {\n // buffer is an ArrayBuffer\n return (\n Array.prototype.map.call(new Uint8Array(buffer), (x: number) =>\n `00${x.toString(16)}`.slice(-2),\n ) as string[]\n ).join(\" \");\n}\n\nfunction bufferToString(buffer: ArrayBuffer): string {\n const byteView = new Uint8Array(buffer);\n let str = \"\";\n for (const charCode of byteView) {\n str += String.fromCharCode(charCode);\n }\n return str;\n}\n\nconst moveMap: Move[] = [\n new Move(\"B\", 1),\n new Move(\"B\", -1),\n new Move(\"F\", 1),\n new Move(\"F\", -1),\n new Move(\"U\", 1),\n new Move(\"U\", -1),\n new Move(\"D\", 1),\n new Move(\"D\", -1),\n new Move(\"R\", 1),\n new Move(\"R\", -1),\n new Move(\"L\", 1),\n new Move(\"L\", -1),\n];\n\n/** @category Smart Puzzles */\nexport class GoCube extends BluetoothPuzzle {\n // We have to perform async operations before we call the constructor.\n public static async connect(\n server: BluetoothRemoteGATTServer,\n ): Promise<GoCube> {\n const service = await server.getPrimaryService(UUIDs.goCubeService);\n debugLog({ service });\n const goCubeStateCharacteristic = await service.getCharacteristic(\n UUIDs.goCubeStateCharacteristic,\n );\n debugLog({ goCubeStateCharacteristic });\n\n const cube = new GoCube(server, goCubeStateCharacteristic);\n\n await goCubeStateCharacteristic.startNotifications();\n goCubeStateCharacteristic.addEventListener(\n \"characteristicvaluechanged\",\n cube.onCubeCharacteristicChanged.bind(cube),\n );\n\n return cube;\n }\n\n // public async getState(): Promise<PuzzleState> {\n // return new Promise((resolve, reject) => {\n // this.resolve = (value: any) => {\n // resolve(buf2hex(value.buffer) as any);\n // };\n // this.goCubeStateCharacteristic.startNotifications();\n // });\n // }\n\n private recorded: any[][] = [];\n\n private homeQuatInverse: Quaternion | null = null;\n private lastRawQuat: Quaternion = new Quaternion(0, 0, 0, 1);\n private currentQuat: Quaternion = new Quaternion(0, 0, 0, 1);\n private lastTarget: Quaternion = new Quaternion(0, 0, 0, 1);\n private alg: Alg = new Alg();\n\n private constructor(\n private server: BluetoothRemoteGATTServer,\n public goCubeStateCharacteristic: BluetoothRemoteGATTCharacteristic,\n ) {\n super();\n }\n\n disconnect(): void {\n this.server.disconnect();\n }\n\n public reset(): void {\n this.resetAlg();\n this.resetOrientation();\n }\n\n public resetAlg(alg?: Alg): void {\n this.alg = alg || new Alg();\n }\n\n public resetOrientation(): void {\n this.homeQuatInverse = this.lastRawQuat.clone().invert();\n this.currentQuat = new Quaternion(0, 0, 0, 1);\n this.lastTarget = new Quaternion(0, 0, 0, 1);\n }\n\n public name(): string | undefined {\n return this.server.device.name;\n }\n\n private onCubeCharacteristicChanged(event: any): void {\n const buffer: DataView = event.target.value;\n this.recorded.push([event.timeStamp, buf2hex(buffer.buffer)]);\n // TODO: read bytes from buffer instead of guessing meaning based on length.\n if (buffer.byteLength < 16) {\n for (let i = 3; i < buffer.byteLength - 4; i += 2) {\n const move = moveMap[buffer.getUint8(i)];\n this.alg = experimentalAppendMove(this.alg, move);\n this.dispatchAlgLeaf({\n latestAlgLeaf: moveMap[buffer.getUint8(i)],\n timeStamp: event.timeStamp,\n debug: {\n stateStr: buf2hex(buffer.buffer),\n },\n });\n }\n } else {\n const coords = bufferToString(\n buffer.buffer.slice(3, buffer.byteLength - 3),\n )\n .split(\"#\")\n .map((s) => parseInt(s, 10) / 16384);\n const quat = new Quaternion(coords[0], coords[1], coords[2], coords[3]);\n\n this.lastRawQuat = quat.clone();\n\n if (!this.homeQuatInverse) {\n this.homeQuatInverse = quat.clone().invert();\n }\n\n const targetQuat = quat.clone().multiply(this.homeQuatInverse.clone());\n targetQuat.y = -targetQuat.y; // GoCube axis fix.\n\n this.lastTarget.slerp(targetQuat, 0.5);\n this.currentQuat.rotateTowards(this.lastTarget, rotateTowardsRate);\n\n this.dispatchOrientation({\n quaternion: this.currentQuat,\n timeStamp: event.timeStamp,\n });\n }\n }\n}\n\nconst rotateTowardsRate = 0.5;\n\n// TODO: Move this into a factory?\nexport const goCubeConfig: BluetoothConfig<BluetoothPuzzle> = {\n connect: GoCube.connect.bind(GoCube),\n prefixes: [\"GoCube\", \"Rubik\"],\n filters: [{ namePrefix: \"GoCube\" }, { namePrefix: \"Rubik\" }],\n optionalServices: [UUIDs.goCubeService],\n};\n", "export function flipBitOrder(v: number, numBits: number): number {\n let result = 0;\n for (let i = 0; i < numBits; i++) {\n const shiftLeft = numBits - 1 - 2 * i;\n const unShiftedBit = v & (0b1 << i);\n // console.log(\n // unShiftedBit,\n // shiftLeft,\n // shiftLeft < 0 ? unShiftedBit >> -shiftLeft : unShiftedBit << shiftLeft,\n // );\n result +=\n shiftLeft < 0 ? unShiftedBit >> -shiftLeft : unShiftedBit << shiftLeft;\n }\n return result;\n}\n", "/* tslint:disable no-bitwise */\n\nimport { Move } from \"../../alg\";\nimport type { KPuzzle } from \"../../kpuzzle\";\nimport type { KPattern } from \"../../kpuzzle/KPattern\";\nimport {\n experimentalBinaryComponentsToReid3x3x3,\n experimentalTwizzleBinaryToBinaryComponents,\n} from \"../../protocol\";\nimport { puzzles } from \"../../puzzles\";\nimport { debugLog } from \"../debug\";\nimport { type BluetoothConfig, BluetoothPuzzle } from \"./bluetooth-puzzle\";\nimport { flipBitOrder } from \"./endianness\";\n\n// TODO: Short IDs\nconst UUIDs = {\n heykubeService: \"b46a791a-8273-4fc1-9e67-94d3dc2aac1c\",\n stateCharacteristic: \"a2f41a4e-0e31-4bbc-9389-4253475481fb\",\n batteryCharacteristic: \"fd51b3ba-99c7-49c6-9f85-5644ff56a378\",\n};\n\n/** @category Smart Puzzles */\nexport class HeykubeCube extends BluetoothPuzzle {\n // We have to perform async operations before we call the constructor.\n public static async connect(\n server: BluetoothRemoteGATTServer,\n device: BluetoothDevice,\n ): Promise<HeykubeCube> {\n const service = await server.getPrimaryService(UUIDs.heykubeService);\n debugLog(\"Service:\", service);\n\n const stateCharacteristic = await service.getCharacteristic(\n UUIDs.stateCharacteristic,\n );\n debugLog(\"Characteristic:\", stateCharacteristic);\n\n const cube = new HeykubeCube(\n await puzzles[\"3x3x3\"].kpuzzle(),\n service,\n device,\n server,\n stateCharacteristic,\n );\n return cube;\n }\n\n private constructor(\n _kpuzzle: KPuzzle,\n _service: BluetoothRemoteGATTService,\n device: BluetoothDevice,\n private server: BluetoothRemoteGATTServer,\n private stateCharacteristic: BluetoothRemoteGATTCharacteristic,\n ) {\n super();\n\n device.addEventListener(\n \"gattserverdisconnected\",\n this.onDisconnect.bind(this),\n );\n\n this.stateCharacteristic.startNotifications();\n this.startTrackingMoves();\n }\n\n public name(): string | undefined {\n return this.server.device.name;\n }\n\n disconnect(): void {\n this.server.disconnect();\n }\n\n onDisconnect(): void {\n this.dispatchEvent(new CustomEvent(\"disconnect\"));\n }\n\n public startTrackingMoves(): void {\n this.stateCharacteristic.addEventListener(\n \"characteristicvaluechanged\",\n (e: any) => this.onStateCharacteristic(e),\n ); // TODO\n }\n\n // public stopTrackingMoves(): void {}\n\n // public async getBattery(): Promise<number> {\n // return new Uint8Array(\n // await this.readActualAngleAndBatteryCharacteristic(),\n // )[7];\n // }srcElement: BluetoothRemoteGATTCharacteristic\n\n private onStateCharacteristic(event: {\n target: BluetoothRemoteGATTCharacteristic;\n timeStamp: number;\n }): void {\n const state = this.decodeState(event.target.value!);\n // console.log(event, state.latestMove.toString(), state);\n this.dispatchAlgLeaf({\n latestAlgLeaf: state.latestMove,\n timeStamp: event.timeStamp,\n pattern: state.pattern,\n });\n }\n\n private decodeState(dv: DataView): { pattern: KPattern; latestMove: Move } {\n const moves = [\n new Move(\"U\"),\n new Move(\"U'\"),\n new Move(\"B\"),\n new Move(\"B'\"),\n new Move(\"F\"),\n new Move(\"F'\"),\n null,\n null,\n new Move(\"L\"),\n new Move(\"L'\"),\n new Move(\"D\"),\n new Move(\"D'\"),\n new Move(\"R\"),\n new Move(\"R'\"),\n // null,\n // null,\n ];\n\n const b2 = new Uint8Array(dv.byteLength);\n for (let i = 0; i < dv.byteLength; i++) {\n b2[i] = flipBitOrder(dv.getUint8(i), 8);\n }\n const components1 = experimentalTwizzleBinaryToBinaryComponents(\n b2.slice(0, 11),\n );\n // console.log(\"sliced\", dv.byteLength, bufferToSpacedHex(b2.slice(11)));\n const components2 = {\n epLex: flipBitOrder(components1.epLex, 29),\n eoMask: flipBitOrder(components1.eoMask, 12),\n cpLex: flipBitOrder(components1.cpLex, 16),\n coMask: flipBitOrder(components1.coMask, 13),\n poIdxL: 0,\n poIdxU: 0b111,\n moSupport: 0b1, // TODO\n moMask: 0,\n };\n // console.log(components2, binaryComponentsToReid3x3x3(components2));\n\n return {\n pattern: experimentalBinaryComponentsToReid3x3x3(components2),\n latestMove: moves[b2[20] & 0b00001111]!,\n };\n }\n\n public override async getPattern(): Promise<KPattern> {\n const b1 = await this.stateCharacteristic.readValue();\n return this.decodeState(b1).pattern;\n }\n}\n\n// // TODO: Move this into a factory?\nexport const heykubeConfig: BluetoothConfig<BluetoothPuzzle> = {\n connect: HeykubeCube.connect.bind(HeykubeCube),\n prefixes: [\"HEYKUBE\"],\n filters: [{ namePrefix: \"HEYKUBE\" }],\n optionalServices: [UUIDs.heykubeService],\n};\n", "import { bluetoothConnect, type BluetoothConnectOptions } from \"../connect\";\nimport type { BluetoothPuzzle } from \"./bluetooth-puzzle\";\nimport { ganConfig } from \"./gan\";\nimport { giiKERConfig } from \"./giiker\";\nimport { goCubeConfig } from \"./gocube\";\nimport { heykubeConfig } from \"./Heykube\";\n\nconst smartPuzzleConfigs = [\n ganConfig,\n goCubeConfig,\n heykubeConfig,\n giiKERConfig, // GiiKER must be last, due to Xiaomi naming. TODO: enforce this using tests.\n];\n\n/** @category Smart Puzzles */\nexport async function connectSmartPuzzle(\n options?: BluetoothConnectOptions,\n): Promise<BluetoothPuzzle> {\n return bluetoothConnect<BluetoothPuzzle>(smartPuzzleConfigs, options);\n}\n", "import { Alg, type Move } from \"../../alg\";\nimport { cube3x3x3 } from \"../../puzzles\";\nimport type { BluetoothConfig } from \"../smart-puzzle/bluetooth-puzzle\";\n\n// TODO: Remove this. It's only used for debugging.\nfunction buf2hex(buffer: ArrayBuffer | Uint8Array): string {\n // buffer is an ArrayBuffer\n return (\n Array.prototype.map.call(new Uint8Array(buffer), (x: number) =>\n `00${x.toString(16)}`.slice(-2),\n ) as string[]\n ).join(\" \");\n}\n\nconst MAX_NIBBLES_PER_WRITE = 18 * 2;\nconst QUANTUM_TURN_DURATION_MS = 150;\nconst DOUBLE_TURN_DURATION_MS = 250;\n\nconst U_D_SWAP = new Alg(\"F B R2 L2 B' F'\");\nconst U_D_UNSWAP = U_D_SWAP.invert(); // TODO: make `cubing.js` clever enough to be able to reuse the regular swap.\nconst F_B_SWAP = new Alg(\"U D R2 L2 D' U'\");\nconst F_B_UNSWAP = F_B_SWAP.invert();\n\n// TODO: Short IDs\nconst UUIDs = {\n ganRobotService: \"0000fff0-0000-1000-8000-00805f9b34fb\",\n statusCharacteristic: \"0000fff2-0000-1000-8000-00805f9b34fb\",\n moveCharacteristic: \"0000fff3-0000-1000-8000-00805f9b34fb\",\n};\n\nconst moveMap: Record<string, number> = {\n R: 0,\n R2: 1,\n \"R2'\": 1,\n \"R'\": 2,\n F: 3,\n F2: 4,\n \"F2'\": 4,\n \"F'\": 5,\n D: 6,\n D2: 7,\n \"D2'\": 7,\n \"D'\": 8,\n L: 9,\n L2: 10,\n \"L2'\": 10,\n \"L'\": 11,\n B: 12,\n B2: 13,\n \"B2'\": 13,\n \"B'\": 14,\n};\n\nconst moveMapX: Record<string, number> = {\n R: 0,\n R2: 1,\n \"R2'\": 1,\n \"R'\": 2,\n U: 3,\n U2: 4,\n \"U2'\": 4,\n \"U'\": 5,\n F: 6,\n F2: 7,\n \"F2'\": 7,\n \"F'\": 8,\n L: 9,\n L2: 10,\n \"L2'\": 10,\n \"L'\": 11,\n D: 12,\n D2: 13,\n \"D2'\": 13,\n \"D'\": 14,\n};\n\nfunction isDoubleTurnNibble(nibble: number): boolean {\n return nibble % 3 === 1;\n}\n\nfunction nibbleDuration(nibble: number): number {\n return isDoubleTurnNibble(nibble)\n ? DOUBLE_TURN_DURATION_MS\n : QUANTUM_TURN_DURATION_MS;\n}\n\nfunction throwInvalidMove(move: Move) {\n console.error(\"invalid move\", move, move.toString());\n throw new Error(\"invalid move!\");\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport interface GanRobotStatus {\n movesRemaining: number;\n}\n\ninterface GanRobotOptions {\n xAngle: boolean;\n singleMoveFixHack: boolean;\n bufferQueue: number;\n postSleep: number;\n}\n\n/** @category Robots */\nexport class GanRobot extends EventTarget {\n experimentalDebugOnSend: ((alg: Alg) => void) | null = null;\n experimentalDebugLog: typeof console.log = () => {};\n\n // Because our Bluetooth connection code is set up not to know what kind of device is connecting, we put these options directly on the class.\n experimentalOptions: GanRobotOptions = {\n xAngle: false,\n singleMoveFixHack: false,\n bufferQueue: 0,\n postSleep: 0,\n };\n\n constructor(\n _service: BluetoothRemoteGATTService,\n private server: BluetoothRemoteGATTServer,\n device: BluetoothDevice,\n private statusCharacteristic: BluetoothRemoteGATTCharacteristic,\n private moveCharacteristic: BluetoothRemoteGATTCharacteristic,\n ) {\n super();\n device.addEventListener(\n \"gattserverdisconnected\",\n this.onDisconnect.bind(this),\n );\n }\n\n // We have to perform async operations before we call the constructor.\n static async connect(\n server: BluetoothRemoteGATTServer,\n device: BluetoothDevice,\n ) {\n const ganTimerService = await server.getPrimaryService(\n UUIDs.ganRobotService,\n );\n const statusCharacteristic = await ganTimerService.getCharacteristic(\n UUIDs.statusCharacteristic,\n );\n const moveCharacteristic = await ganTimerService.getCharacteristic(\n UUIDs.moveCharacteristic,\n );\n const timer = new GanRobot(\n ganTimerService,\n server,\n device,\n statusCharacteristic,\n moveCharacteristic,\n );\n return timer;\n }\n\n public name(): string | undefined {\n return this.server.device.name;\n }\n\n disconnect(): void {\n this.server.disconnect();\n }\n\n onDisconnect(): void {\n this.dispatchEvent(new CustomEvent(\"disconnect\"));\n }\n\n private moveToNibble(move: Move): number {\n const nibble =\n (this.experimentalOptions.xAngle ? moveMapX : moveMap)[move.toString()] ??\n null;\n if (nibble === null) {\n throwInvalidMove(move);\n }\n return nibble;\n }\n\n private async writeNibbles(nibbles: number[]): Promise<void> {\n if (nibbles.length > MAX_NIBBLES_PER_WRITE) {\n throw new Error(\n `Can only write ${MAX_NIBBLES_PER_WRITE} nibbles at a time!`,\n );\n }\n // const byteLength = Math.ceil(nibbles.length / 2);\n const bytes = new Uint8Array(18);\n let i: number;\n for (i = 0; i < nibbles.length; i++) {\n const byteIdx = Math.floor(i / 2);\n bytes[byteIdx] += nibbles[i];\n if (i % 2 === 0) {\n bytes[byteIdx] *= 0x10;\n }\n }\n if (nibbles.length % 2 === 1) {\n bytes[Math.ceil(nibbles.length / 2) - 1] += 0xf;\n }\n for (let i = Math.ceil(nibbles.length / 2); i < 18; i++) {\n bytes[i] = 0xff;\n }\n let sleepDuration = 0;\n for (const nibble of nibbles) {\n sleepDuration += nibbleDuration(nibble);\n }\n this.experimentalDebugLog(\"WRITING:\", buf2hex(bytes));\n await this.moveCharacteristic.writeValue(bytes);\n await sleep(sleepDuration * 0.75);\n while ((await this.getStatus()).movesRemaining > 0) {\n // repeat\n }\n await sleep(this.experimentalOptions.postSleep);\n }\n\n private async getStatus(): Promise<GanRobotStatus> {\n const statusBytes = new Uint8Array(\n (await this.statusCharacteristic.readValue()).buffer,\n );\n this.experimentalDebugLog(\"moves remaining:\", statusBytes[0]);\n return {\n movesRemaining: statusBytes[0],\n };\n }\n\n locked: boolean = false;\n processQueue(): void {}\n\n private moveQueue: Alg = new Alg();\n // TODO: Don't let this resolve until the move is done?\n private async queueMoves(moves: Alg): Promise<void> {\n this.moveQueue = this.moveQueue.concat(moves).experimentalSimplify({\n puzzleSpecificSimplifyOptions: cube3x3x3.puzzleSpecificSimplifyOptions,\n });\n if (!this.locked) {\n // TODO: We're currently iterating over alg nodes instead of leaves to avoid \"zip bomps\".\n try {\n this.locked = true;\n if (this.moveQueue.experimentalNumChildAlgNodes() === 1) {\n await sleep(this.experimentalOptions.bufferQueue);\n }\n // await this.writeNibbles([0xf, 0xf]);\n while (this.moveQueue.experimentalNumChildAlgNodes() > 0) {\n let algNodes = Array.from(this.moveQueue.childAlgNodes());\n if (\n this.experimentalOptions.singleMoveFixHack &&\n algNodes.length === 1\n ) {\n const move = algNodes[0] as Move;\n if (move.amount === 2) {\n algNodes = [\n move.modified({ amount: 1 }),\n move.modified({ amount: 1 }),\n ];\n } else {\n algNodes = [\n move.modified({ amount: -move.amount }),\n move.modified({ amount: 2 }),\n ];\n }\n }\n const moves = algNodes.splice(0, MAX_NIBBLES_PER_WRITE);\n const nibbles: number[] = moves.map(this.moveToNibble.bind(this));\n const sending = new Alg(moves);\n this.experimentalDebugLog(\"SENDING\", sending.toString());\n if (this.experimentalDebugOnSend) {\n this.experimentalDebugOnSend(sending);\n }\n const write = this.writeNibbles(nibbles);\n this.moveQueue = new Alg(algNodes);\n await write;\n }\n } finally {\n this.locked = false;\n }\n }\n }\n\n async applyMoves(moves: Iterable<Move>): Promise<void> {\n // const nibbles: number[] = [];\n for (const move of moves) {\n const str = move.toString();\n if (str in (this.experimentalOptions.xAngle ? moveMapX : moveMap)) {\n await this.queueMoves(new Alg([move]));\n } else if (\n move.family === (this.experimentalOptions.xAngle ? \"B\" : \"U\")\n ) {\n // We purposely send just the swap, so that U2 will get cancelled\n await Promise.all([\n this.queueMoves(\n this.experimentalOptions.xAngle ? F_B_SWAP : U_D_SWAP,\n ),\n this.queueMoves(\n new Alg([\n move.modified({\n family: this.experimentalOptions.xAngle ? \"F\" : \"D\",\n }),\n ]).concat(\n this.experimentalOptions.xAngle ? F_B_UNSWAP : U_D_UNSWAP,\n ),\n ),\n ]);\n }\n }\n }\n}\n\n// // TODO: Move this into a factory?\nexport const ganTimerConfig: BluetoothConfig<GanRobot> = {\n connect: GanRobot.connect.bind(GanRobot),\n prefixes: [\"GAN\"],\n filters: [{ namePrefix: \"GAN\" }],\n optionalServices: [UUIDs.ganRobotService],\n};\n", "import { bluetoothConnect, type BluetoothConnectOptions } from \"../connect\";\nimport type { BluetoothConfig } from \"../smart-puzzle/bluetooth-puzzle\";\nimport { ganTimerConfig, type GanRobot } from \"./GanRobot\";\n\n/** @category Robots */\nexport type BluetoothRobot = GanRobot; // TODO\n\nconst smartRobotConfigs: BluetoothConfig<BluetoothRobot>[] = [ganTimerConfig];\n\n/** @category Robots */\nexport async function connectSmartRobot(\n options?: BluetoothConnectOptions,\n): Promise<BluetoothRobot> {\n return bluetoothConnect<BluetoothRobot>(smartRobotConfigs, options);\n}\n", "import type { MillisecondTimestamp } from \"../../twisty/controllers/AnimationTypes\";\nimport type { BluetoothConfig } from \"../smart-puzzle/bluetooth-puzzle\";\n\n// TODO: Short IDs\nconst UUIDs = {\n ganTimerService: \"0000fff0-0000-1000-8000-00805f9b34fb\",\n timeCharacteristic: \"0000fff2-0000-1000-8000-00805f9b34fb\",\n};\n\ninterface GanTimerDetail {\n currentTime: MillisecondTimestamp;\n latestTimes: [\n MillisecondTimestamp,\n MillisecondTimestamp,\n MillisecondTimestamp,\n ];\n}\n\n/** @category Timers */\nexport class GanTimer extends EventTarget {\n private polling = false;\n private previousDetail: GanTimerDetail | null = null;\n\n constructor(\n _service: BluetoothRemoteGATTService,\n private server: BluetoothRemoteGATTServer,\n device: BluetoothDevice,\n private timeCharacteristic: BluetoothRemoteGATTCharacteristic,\n ) {\n super();\n this.startPolling();\n console.log(server);\n device.addEventListener(\n \"gattserverdisconnected\",\n this.onDisconnect.bind(this),\n );\n }\n\n // We have to perform async operations before we call the constructor.\n static async connect(\n server: BluetoothRemoteGATTServer,\n device: BluetoothDevice,\n ) {\n const ganTimerService = await server.getPrimaryService(\n UUIDs.ganTimerService,\n );\n console.log(\"Service:\", ganTimerService);\n const timeCharacteristic = await ganTimerService.getCharacteristic(\n UUIDs.timeCharacteristic,\n );\n console.log(\"Characteristic:\", timeCharacteristic);\n const timer = new GanTimer(\n ganTimerService,\n server,\n device,\n timeCharacteristic,\n );\n return timer;\n }\n\n disconnect(): void {\n this.server.disconnect();\n }\n\n async poll() {\n if (!this.polling) {\n return;\n }\n const value = await this.getTimeCharacteristic();\n\n const detail: GanTimerDetail = {\n currentTime: this.decodeTimeMs(value.slice(0, 4)),\n latestTimes: [\n this.decodeTimeMs(value.slice(4, 8)),\n this.decodeTimeMs(value.slice(8, 12)),\n this.decodeTimeMs(value.slice(12, 16)),\n ],\n };\n\n if (detail.currentTime === 0) {\n if (this.previousDetail && this.previousDetail.currentTime !== 0) {\n this.dispatchEvent(new CustomEvent(\"reset\"));\n }\n }\n\n if (detail.currentTime !== 0 && this.previousDetail) {\n if (this.previousDetail.currentTime === 0) {\n this.dispatchEvent(new CustomEvent(\"start\"));\n }\n\n if (detail.currentTime !== this.previousDetail.currentTime) {\n this.dispatchEvent(new CustomEvent(\"update\", { detail }));\n\n if (\n detail.currentTime === detail.latestTimes[0] &&\n detail.latestTimes[1] === this.previousDetail.latestTimes[0] &&\n detail.latestTimes[2] === this.previousDetail.latestTimes[1]\n ) {\n this.dispatchEvent(new CustomEvent(\"stop\", { detail }));\n }\n }\n }\n\n this.previousDetail = detail;\n\n this.poll();\n }\n\n onDisconnect(): void {\n this.dispatchEvent(new CustomEvent(\"disconnect\"));\n }\n\n async getTimeCharacteristic() {\n return new Uint8Array((await this.timeCharacteristic.readValue()).buffer);\n }\n\n async getTime() {\n const value = await this.getTimeCharacteristic();\n return this.decodeTimeMs(value.slice(0, 4));\n }\n\n decodeTimeMs(bytes: Uint8Array) {\n return (bytes[0] * 60 + bytes[1]) * 1000 + bytes[2] + bytes[3] * 256;\n }\n\n startPolling() {\n this.polling = true;\n this.poll();\n }\n\n stopPolling() {\n this.polling = false;\n }\n}\n\n// // TODO: Move this into a factory?\nexport const ganTimerConfig: BluetoothConfig<GanTimer> = {\n connect: GanTimer.connect.bind(GanTimer),\n prefixes: [\"GAN\"],\n filters: [{ namePrefix: \"GAN\" }],\n optionalServices: [UUIDs.ganTimerService],\n};\n", "import { bluetoothConnect, type BluetoothConnectOptions } from \"../connect\";\nimport type { BluetoothConfig } from \"../smart-puzzle/bluetooth-puzzle\";\nimport { ganTimerConfig, type GanTimer } from \"./GanTimer\";\n\n/** @category Timers */\nexport type BluetoothTimer = GanTimer; // TODO\n\nconst smartTimerConfigs: BluetoothConfig<BluetoothTimer>[] = [ganTimerConfig];\n\n/** @category Timers */\nexport async function connectSmartTimer(\n options?: BluetoothConnectOptions,\n): Promise<BluetoothTimer> {\n return bluetoothConnect<BluetoothTimer>(smartTimerConfigs, options);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;AAAA,IAAI,wBAAwB;AAErB,SAAS,mBAAmB,QAAuB;AACxD,0BAAwB;AAC1B;AAGO,SAAS,YAAY,MAAmB;AAC7C,MAAI,CAAC,uBAAuB;AAC1B;AAAA,EACF;AAEA,MAAI,QAAQ,MAAM;AAChB,YAAQ,KAAK,GAAG,IAAI;AAAA,EACtB,OAAO;AACL,YAAQ,IAAI,GAAG,IAAI;AAAA,EACrB;AACF;;;ACjBA,SAAS,YAAY,eAAe;AAcpC,SAAS,QAAQ,GAAoB;AACnC,QAAM,SAAS,KAAK,IAAI,KAAK,IAAI,EAAE,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC,CAAC;AACnE,UAAQ,QAAQ;AAAA,IACd,KAAK,EAAE;AACL,aAAO;AAAA,IACT,KAAK,CAAC,EAAE;AACN,aAAO;AAAA,IACT,KAAK,EAAE;AACL,aAAO;AAAA,IACT,KAAK,CAAC,EAAE;AACN,aAAO;AAAA,IACT,KAAK,EAAE;AACL,aAAO;AAAA,IACT,KAAK,CAAC,EAAE;AACN,aAAO;AAAA,IACT;AACE,YAAM,IAAI,MAAM,QAAQ;AAAA,EAC5B;AACF;AAEA,IAAM,KAAK,KAAK,KAAK,GAAG;AAExB,IAAM,IAAiC;AAAA,EACrC,OAAO,IAAI,WAAW,GAAG,GAAG,GAAG,CAAC;AAAA,EAChC,QAAQ,IAAI,WAAW,IAAI,GAAG,GAAG,EAAE;AAAA,EACnC,OAAO,IAAI,WAAW,GAAG,GAAG,CAAC,IAAI,EAAE;AAAA,EACnC,QAAQ,IAAI,WAAW,GAAG,GAAG,IAAI,EAAE;AACrC;AAEO,IAAM,2BAAN,MAA4D;AAAA;AAAA,EAG1D,iBAAiB,eAAmC;AAAA,EAE3D;AAAA,EAEO,qBAAqB,kBAA0C;AACpE,UAAM,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI,iBAAiB;AACxC,UAAM,OAAO,IAAI,WAAW,GAAG,GAAG,GAAG,CAAC;AAEtC,UAAM,IAAI,IAAI,QAAQ,GAAG,GAAG,CAAC;AAC7B,UAAM,IAAI,IAAI,QAAQ,GAAG,GAAG,CAAC;AAC7B,UAAM,OAAO,QAAQ,EAAE,gBAAgB,IAAI,CAAC;AAC5C,UAAM,OAAO,QAAQ,EAAE,gBAAgB,IAAI,CAAC;AAE5C,UAAM,UAAU,EAAE,GAAG,IAAI,IAAI,IAAI,EAAE,KAAK,EAAE,KAAK;AAE/C,YAAQ,IAAI,IAAI;AAChB,YAAQ,IAAI,OAAO;AACnB,UAAM,KAAK,KAAK,YAAY,OAAO;AAGnC,YAAQ,IAAI,EAAE;AAEd,qBAAiB,aAAa;AAE9B,YAAQ,IAAI,iBAAiB,UAAU;AAAA,EACzC;AACF;;;ACzBO,IAAe,kBAAf,cAAuC,YAAY;AAAA,EACjD,eAAoC,CAAC;AAAA,EAClC,YAA8C,CAAC;AAAA;AAAA,EAC/C,uBAA6D,CAAC;AAAA;AAAA;AAAA,EAMxE,MAAa,aAAgC;AAC3C,UAAM,IAAI,MAAM,oBAAoB;AAAA,EACtC;AAAA,EAEO,mBAAmB,UAA2C;AACnE,SAAK,UAAU,KAAK,QAAQ;AAAA,EAC9B;AAAA,EAEO,uBAAuB,UAA+C;AAC3E,SAAK,qBAAqB,KAAK,QAAQ;AAAA,EACzC;AAAA,EAEO,0CAAgD;AACrD,SAAK,aAAa,KAAK,IAAI,yBAAyB,CAAC;AAAA,EACvD;AAAA,EAEU,gBAAgB,SAA6B;AACrD,eAAW,eAAe,KAAK,cAAc;AAC3C,kBAAY,iBAAiB,OAAO;AAAA,IACtC;AACA,eAAW,KAAK,KAAK,WAAW;AAC9B,QAAE,OAAO;AAAA,IACX;AAAA,EACF;AAAA,EAEU,oBAAoB,kBAA0C;AACtE,eAAW,eAAe,KAAK,cAAc;AAC3C,kBAAY,qBAAqB,gBAAgB;AAAA,IACnD;AACA,UAAM,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI,iBAAiB;AAExC,qBAAiB,aAAa;AAAA,MAC5B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,eAAW,KAAK,KAAK,sBAAsB;AAEzC,QAAE,gBAAgB;AAAA,IACpB;AAAA,EACF;AACF;;;AC3FO,IAAM,iBAAN,cAA6B,gBAAgB;AAAA;AAAA,EAQlD,YAAoB,QAAiB;AACnC,UAAM;AADY;AAGlB,SAAK,WAAW,KAAK,UAAU,KAAK,IAAI;AACxC,WAAO,iBAAiB,WAAW,KAAK,QAAQ;AAAA,EAClD;AAAA,EAZQ,SAA2B,QAAQ,OAAO,EAAE,QAAQ;AAAA,EACpD,WAA8B,aACnC,MAAM,KAAK,QAAQ,eAAe,GAAG;AAAA,EAExC;AAAA,EAUO,OAA2B;AAChC,WAAO;AAAA,EACT;AAAA,EAEA,aAAa;AACX,SAAK,OAAO,oBAAoB,WAAW,KAAK,QAAQ;AAAA,EAC1D;AAAA,EAEA,MAAsB,aAAgC;AACpD,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAc,UAAU,GAAiC;AACvD,QAAI,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU;AACpD;AAAA,IACF;AAEA,UAAM,UAAU,UAAU,CAAC;AAC3B,QAAI,SAAS;AACX,YAAM,cAAc,MAAM,KAAK,SAAS,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;AACnE,WAAK,UAAU,QAAQ,QAAQ,UAAU;AACzC,WAAK,gBAAgB;AAAA,QACnB,eAAe;AAAA,QACf,WAAW,EAAE;AAAA,QACb,SAAS;AAAA,MACX,CAAC;AACD,QAAE,eAAe;AAAA,IACnB;AAAA,EACF;AACF;AAIA,eAAsB,qBACpB,SAAc,QACW;AACzB,SAAO,IAAI,eAAe,MAAM;AAClC;;;ACtDA,SAAS,eACP,SACA,mBAA4B,OACN;AACtB,QAAM,UAAU,mBACZ;AAAA,IACE,kBAAkB;AAAA,IAClB,kBAAkB,CAAC;AAAA,EACrB,IACA;AAAA,IACE,SAAS,CAAC;AAAA,IACV,kBAAkB,CAAC;AAAA,EACrB;AACJ,aAAW,UAAU,SAAS;AAC5B,QAAI,CAAC,kBAAkB;AACrB,cAAQ,UAAU,QAAQ,QAAS,OAAO,OAAO,OAAO;AAAA,IAC1D;AACA,YAAQ,mBAAmB,QAAQ,iBAAiB;AAAA,MAClD,OAAO;AAAA,IACT;AAAA,EACF;AACA,WAAS,EAAE,gBAAgB,QAAQ,CAAC;AACpC,SAAO;AACT;AAYA,IAAI,sBAAsB;AAC1B,IAAM,0CAA0C;AAGhD,eAAsB,iBACpB,SACA,UAAmC,CAAC,GACxB;AACZ,WAAS,qBAAqB;AAC9B,MAAI;AACJ,MAAI;AACF,QAAI,mBAAmB,QAAQ;AAC/B,QACE,CAAC,oBACD,uBAAuB,yCACvB;AACA,cAAQ;AAAA,QACN,YAAY,uCAAuC;AAAA,MACrD;AACA,yBAAmB;AAAA,IACrB;AACA,aAAS,MAAM,UAAU,UAAU;AAAA,MACjC,eAAkB,SAAS,gBAAgB;AAAA,IAC7C;AACA,0BAAsB;AAAA,EACxB,SAAS,GAAG;AACV;AACA,UAAM,IAAI,MAAM,CAAC;AAAA,EACnB;AACA,WAAS,WAAW,MAAM;AAE1B,MAAI,OAAO,OAAO,SAAS,aAAa;AACtC,WAAO,QAAQ,OAAO,oCAAoC;AAAA,EAC5D;AAEA,QAAM,SAAS,MAAM,OAAO,KAAK,QAAQ;AACzC,WAAS,WAAW,MAAM;AAE1B,QAAM,OAAO,OAAO,QAAQ,QAAQ;AAIpC,aAAW,UAAU,SAAS;AAC5B,eAAW,UAAU,OAAO,UAAU;AACpC,UAAI,MAAM,WAAW,MAAM,GAAG;AAC5B,eAAO,OAAO,QAAQ,QAAQ,MAAM;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,MAAM,2BAA2B;AACzC;;;ACzFA,SAAS,cAAAA,mBAAkB;;;ACM3B,IAAM,YAAY;AAClB,IAAM,QAAQ,IAAI,WAAW,SAAS;AACtC,IAAM,wBAAwB,IAAI;AAAA,EAChC,IAAI,MAAM,SAAS,EAAE,KAAK,SAAS;AACrC;AACA,IAAM,UAAU;AAEhB,eAAsB,UACpB,UACoB;AACpB,SAAO,MAAM,OAAO,OAAO,UAAU,OAAO,UAAU,SAAS,MAAM;AAAA,IACnE;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAEA,eAAe,yBACb,KACA,gBACA,IACsB;AACtB,QAAM,eAA4B,MAAM,OAAO,OAAO,OAAO;AAAA,IAC3D;AAAA,MACE,MAAM;AAAA,MACN;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO,aAAa,MAAM,GAAG,SAAS;AACxC;AAYA,eAAsB,mBACpB,KACA,iBACsB;AACtB,QAAM,eAAe,MAAM;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,gBAAgB,IAAI,WAAW,IAAI,SAAS;AAClD,gBAAc,IAAI,IAAI,WAAW,eAAe,GAAG,CAAC;AACpD,gBAAc,IAAI,IAAI,WAAW,YAAY,GAAG,SAAS;AAEzD,QAAM,eAA4B,MAAM,OAAO,OAAO,OAAO;AAAA,IAC3D;AAAA,MACE,MAAM;AAAA,MACN,IAAI;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO,aAAa,MAAM,GAAG,SAAS;AACxC;;;AD1DA,IAAM,sBAAsB;AAE5B,IAAM,mBAAmB;AAEzB,IAAM,qBAA4C;AAAA,EAChD,GAAe,IAAI,KAAK,GAAG;AAAA,EAC3B,GAAe,IAAI,KAAK,KAAK,EAAE;AAAA,EAC/B,GAAe,IAAI,KAAK,GAAG;AAAA,EAC3B,GAAe,IAAI,KAAK,KAAK,EAAE;AAAA,EAC/B,GAAe,IAAI,KAAK,GAAG;AAAA,EAC3B,GAAe,IAAI,KAAK,KAAK,EAAE;AAAA,EAC/B,GAAe,IAAI,KAAK,GAAG;AAAA,EAC3B,IAAe,IAAI,KAAK,KAAK,EAAE;AAAA,EAC/B,IAAe,IAAI,KAAK,GAAG;AAAA,EAC3B,IAAe,IAAI,KAAK,KAAK,EAAE;AAAA,EAC/B,IAAe,IAAI,KAAK,GAAG;AAAA,EAC3B,IAAe,IAAI,KAAK,KAAK,EAAE;AACjC;AAEA,IAAI,kBAAqC;AAEzC,SAAS,yBAAyB,MAA2B;AAC3D,SACE,KAAK,EAAE,IAAI,MACX,KAAK,EAAE,IAAI,MACX,KAAK,EAAE,IAAI,MACX,KAAK,EAAE,IAAI,MACX,KAAK,EAAE,IAAI,MACX,KAAK,EAAE,IAAI;AAEf;AAEA,IAAM,QAAQ,IAAI,WAAW;AAAA,EAC3B;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AACvE,CAAC;AACD,IAAM,QAAQ,IAAI,WAAW;AAAA,EAC3B;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAG;AACrE,CAAC;AAGD,eAAe,eACb,MACA,QACqB;AACrB,MAAI,WAAW,MAAM;AACnB,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,IAAI,WAAW,IAAI;AAChC,OAAK,IAAI,IAAI,WAAW,MAAM,mBAAmB,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;AAC3E,OAAK;AAAA,IACH,IAAI,WAAW,MAAM,mBAAmB,QAAQ,KAAK,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,IAClE;AAAA,EACF;AAEA,MAAI,yBAAyB,IAAI,GAAG;AAClC,WAAO;AAAA,EACT;AAEA,QAAM,IAAI,MAAM,0BAA0B;AAC5C;AAEA,IAAM,gBAAN,MAAM,eAAc;AAAA,EAgBV,YACE,UACD,WACP;AAFQ;AACD;AAEP,SAAK,MAAM,IAAI,WAAW,SAAS,MAAM;AACzC,QAAI,KAAK,IAAI,WAAW,KAAK,QAAQ;AACnC,YAAM,IAAI,MAAM,yBAAyB;AAAA,IAC3C;AAAA,EACF;AAAA,EAvBA,aAAoB,KAClB,gBACA,QACwB;AACxB,UAAM,QAAQ,MAAM;AAAA,MAClB,IAAI,YAAY,MAAM,eAAe,UAAU,GAAG,MAAM;AAAA,MACxD;AAAA,IACF;AACA,UAAM,YAAY,KAAK,IAAI;AAE3B,WAAO,IAAI,eAAc,IAAI,SAAS,MAAM,MAAM,GAAG,SAAS;AAAA,EAChE;AAAA,EAEQ;AAAA,EACA,SAAS;AAAA,EAWV,UAAsB;AAC3B,QAAI,IAAI,KAAK,SAAS,SAAS,GAAG,IAAI,IAAI;AAC1C,QAAI,IAAI,KAAK,SAAS,SAAS,GAAG,IAAI,IAAI;AAC1C,QAAI,IAAI,KAAK,SAAS,SAAS,GAAG,IAAI,IAAI;AAC1C,KAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;AACtB,UAAM,WAAW,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI;AAC1C,UAAM,IAAI,WAAW,IAAI,KAAK,KAAK,QAAQ,IAAI;AAC/C,UAAM,OAAO,IAAIC,YAAW,GAAG,GAAG,GAAG,CAAC;AAEtC,QAAI,CAAC,iBAAiB;AACpB,wBAAkB,KAAK,MAAM,EAAE,OAAO;AAAA,IACxC;AAEA,WAAO,KAAK,MAAM,EAAE,SAAS,gBAAgB,MAAM,CAAC;AAAA,EACtD;AAAA;AAAA,EAGO,cAAsB;AAC3B,WAAO,KAAK,IAAI,EAAE;AAAA,EACpB;AAAA,EAEO,cAAc,qBAAqC;AACxD,WAAQ,KAAK,YAAY,IAAI,sBAAuB;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA,EAKO,YAAY,GAAmB;AACpC,QAAI,IAAI,KAAK,IAAI,kBAAkB;AACjC,YAAM,IAAI,MAAM,gDAAgD,CAAC,GAAG;AAAA,IACtE;AACA,WAAO,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC,EAAE;AAAA,MAC5C,CAAC,MAAM,mBAAmB,CAAC;AAAA,IAC7B;AAAA,EACF;AAAA,EAEO,YAAiC;AACtC,WAAO;AAAA,MACL,KAAK,KAAK;AAAA,IACZ;AAAA,EACF;AACF;AAGA,IAAM,QAAQ;AAAA,EACZ,gBAAgB;AAAA,EAChB,6BAA6B;AAAA,EAC7B,qCAAqC;AAAA,EACrC,8BAA8B;AAAA,EAC9B,8BAA8B;AAAA,EAC9B,aAAa;AAAA,EACb,wBAAwB;AAAA,EACxB,uBAAuB;AACzB;AAEA,IAAM,WAA4C;AAAA,EAChD,OAAO,IAAI,WAAW;AAAA,IACpB;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAClE;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,EAChC,CAAC;AACH;AAEA,SAAS,QAAQ,QAA6B;AAE5C,SACE,MAAM,UAAU,IAAI;AAAA,IAAK,IAAI,WAAW,MAAM;AAAA,IAAG,CAAC,MAChD,KAAK,EAAE,SAAS,EAAE,CAAC,GAAG,MAAM,EAAE;AAAA,EAChC,EACA,KAAK,GAAG;AACZ;AAEA,IAAM,gBAAgB,sCAAsC,MAAM,GAAG;AACrE,IAAM,kBAAkB,kCAAkC,MAAM,GAAG;AAOnE,SAAS,WAAW,GAAW,GAAmB;AAChD,SAAO,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC;AAClC;AAEA,IAAM,WAAuC,CAAC;AAE9C,cAAc,QAAQ,CAAC,MAAM,QAAQ;AACnC,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAS,WAAW,MAAM,CAAC,CAAC,IAAI,EAAE,OAAO,KAAK,aAAa,EAAE;AAAA,EAC/D;AACF,CAAC;AACD,gBAAgB,QAAQ,CAAC,QAAQ,QAAQ;AACvC,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAS,WAAW,QAAQ,CAAC,CAAC,IAAI,EAAE,OAAO,KAAK,aAAa,EAAE;AAAA,EACjE;AACF,CAAC;AAED,IAAM,wBAAwB;AAAA,EAC5B,CAAC,GAAG,IAAI,EAAE;AAAA,EACV,CAAC,GAAG,IAAI,EAAE;AAAA,EACV,CAAC,GAAG,IAAI,EAAE;AAAA,EACV,CAAC,GAAG,IAAI,EAAE;AAAA,EACV,CAAC,IAAI,IAAI,EAAE;AAAA,EACX,CAAC,IAAI,IAAI,EAAE;AAAA,EACX,CAAC,IAAI,IAAI,EAAE;AAAA,EACX,CAAC,IAAI,IAAI,CAAC;AACZ;AAEA,IAAM,sBAAsB;AAAA,EAC1B,CAAC,GAAG,EAAE;AAAA,EACN,CAAC,GAAG,EAAE;AAAA,EACN,CAAC,GAAG,EAAE;AAAA,EACN,CAAC,GAAG,EAAE;AAAA,EACN,CAAC,IAAI,EAAE;AAAA,EACP,CAAC,IAAI,CAAC;AAAA,EACN,CAAC,IAAI,EAAE;AAAA,EACP,CAAC,IAAI,EAAE;AAAA,EACP,CAAC,IAAI,EAAE;AAAA,EACP,CAAC,IAAI,EAAE;AAAA,EACP,CAAC,IAAI,EAAE;AAAA,EACP,CAAC,IAAI,EAAE;AACT;AACA,IAAM,YAAY;AAElB,eAAe,OACb,QAC2B;AAC3B,QAAM,cAAc,MAAM,OAAO,kBAAkB,MAAM,WAAW;AAEpE,QAAM,wBAAwB,MAAM,YAAY;AAAA,IAC9C,MAAM;AAAA,EACR;AACA,QAAM,gBAAgB,IAAI;AAAA,KACvB,MAAM,sBAAsB,UAAU,GAAG;AAAA,EAC5C;AAEA,QAAM,iBACD,cAAc,CAAC,KAAK,KAAK,cAAc,CAAC,KAAM,KAAK,cAAc,CAAC;AACvE,MAAI,eAAe,OAAY;AAC7B,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,eAAe,QAAa,QAAQ;AAEnD,QAAM,yBAAyB,MAAM,YAAY;AAAA,IAC/C,MAAM;AAAA,EACR;AACA,QAAM,WAAW,IAAI;AAAA,KAClB,MAAM,uBAAuB,UAAU,GAAG;AAAA,EAC7C,EAAE,QAAQ;AAEV,QAAM,MAAM,IAAI,WAAW,MAAM;AACjC,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,QAAI,CAAC,KAAK,IAAI,CAAC,IAAI,SAAS,CAAC,KAAK;AAAA,EACpC;AAEA,SAAO,UAAU,GAAG;AACtB;AAGO,IAAM,UAAN,MAAM,iBAAgB,gBAAgB;AAAA,EAuCnC,YACE,SACA,SACA,QACA,6BACA,iBACA,QACR;AACA,UAAM;AAPE;AACA;AACA;AACA;AACA;AACA;AAGR,SAAK,UAAU,QAAQ,eAAe;AACtC,SAAK,mBAAmB;AAAA,EAC1B;AAAA;AAAA,EAhDA,aAAoB,QAClB,QACkB;AAClB,UAAM,iBAAiB,MAAM,OAAO,kBAAkB,MAAM,cAAc;AAC1E,aAAS,YAAY,cAAc;AAEnC,UAAM,8BAA8B,MAAM,eAAe;AAAA,MACvD,MAAM;AAAA,IACR;AACA,aAAS,mBAAmB,2BAA2B;AAEvD,UAAM,SAAS,MAAM,OAAO,MAAM;AAElC,UAAM,sBACJ,MAAM,cAAc,KAAK,6BAA6B,MAAM,GAC5D,YAAY;AACd,aAAS,yBAAyB,kBAAkB;AACpD,UAAM,OAAO,IAAI;AAAA,MACf,MAAM,QAAQ,OAAO,EAAE,QAAQ;AAAA,MAC/B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEO,cAAsB;AAAA,EACrB,iBAAgC;AAAA,EAChC;AAAA,EACA;AAAA,EAEA;AAAA,EAEA;AAAA,EAeD,OAA2B;AAChC,WAAO,KAAK,OAAO,OAAO;AAAA,EAC5B;AAAA,EAEA,aAAmB;AACjB,SAAK,OAAO,WAAW;AAAA,EACzB;AAAA,EAEO,qBAA2B;AAGhC,SAAK,iBAAiB,OAAO;AAAA,MAC3B,KAAK,gBAAgB,KAAK,IAAI;AAAA,MAC9B,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EAEO,oBAA0B;AAC/B,QAAI,CAAC,KAAK,gBAAgB;AACxB,YAAM,IAAI,MAAM,qBAAqB;AAAA,IACvC;AACA,kBAAc,KAAK,cAAc;AACjC,SAAK,iBAAiB;AAAA,EACxB;AAAA;AAAA,EAGA,MAAa,kBAAiC;AAC5C,UAAM,gBAAgB,MAAM,cAAc;AAAA,MACxC,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AACA,QAAI,sBAAsB,cAAc,cAAc,KAAK,eAAe;AAE1E,QAAI,sBAAsB,kBAAkB;AAC1C;AAAA,QACE,4BACE,sBAAsB,gBACxB;AAAA,MACF;AACA,4BAAsB;AAAA,IACxB;AACA,eAAW,QAAQ,cAAc,YAAY,mBAAmB,GAAG;AAEjE,WAAK,UAAU,KAAK,QAAQ,UAAU,IAAI;AAC1C,WAAK,gBAAgB;AAAA,QACnB,eAAe;AAAA,QACf,WAAW,cAAc;AAAA,QACzB,OAAO,cAAc,UAAU;AAAA,QAC/B,SAAS,KAAK;AAAA;AAAA,MAEhB,CAAC;AAAA,IACH;AACA,SAAK,oBAAoB;AAAA,MACvB,WAAW,cAAc;AAAA,MACzB,YAAY,cAAc,QAAQ;AAAA,IACpC,CAAC;AACD,SAAK,kBAAkB,cAAc,YAAY;AAAA,EACnD;AAAA,EAEA,MAAa,aAA8B;AACzC,WAAO,IAAI;AAAA,MACT,MAAM,KAAK,wCAAwC;AAAA,IACrD,EAAE,CAAC;AAAA,EACL;AAAA,EAEA,MAAsB,aAAgC;AACpD,UAAM,MAAkB,MAAM;AAAA,MAC5B,IAAI,WAAW,MAAM,KAAK,iCAAiC,CAAC;AAAA,MAC5D,KAAK;AAAA,IACP;AACA,UAAM,WAAqB,CAAC;AAC5B,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK,GAAG;AAC9B,UAAI,MAAO,IAAI,IAAI,CAAC,KAAK,KAAK,IAAK,IAAI,IAAK,CAAC,KAAM,KAAK,IAAK,IAAI,IAAK,CAAC;AACvE,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,iBAAS,KAAK,IAAI,CAAC;AACnB,cAAM;AAAA,MACR;AAAA,IACF;AAEA,UAAM,cAA4B;AAAA,MAChC,SAAS;AAAA,QACP,QAAQ,CAAC;AAAA,QACT,aAAa,CAAC;AAAA,MAChB;AAAA,MACA,OAAO;AAAA,QACL,QAAQ,CAAC;AAAA,QACT,aAAa,CAAC;AAAA,MAChB;AAAA,MACA,SAAS;AAAA,QACP,QAAQ,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,QACzB,aAAa,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,QAC9B,gBAAgB,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA;AAAA,MACnC;AAAA,IACF;AAEA,eAAW,iBAAiB,uBAAuB;AACjD,YAAM,YACJ,SAAS,cAAc,IAAI,CAAC,MAAM,UAAU,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;AACpE,kBAAY,QAAQ,OAAO,KAAK,UAAU,KAAK;AAC/C,kBAAY,QAAQ,YAAY,KAAK,UAAU,WAAW;AAAA,IAC5D;AAEA,eAAW,eAAe,qBAAqB;AAC7C,YAAM,YACJ,SAAS,YAAY,IAAI,CAAC,MAAM,UAAU,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;AAClE,kBAAY,MAAM,OAAO,KAAK,UAAU,KAAK;AAC7C,kBAAY,MAAM,YAAY,KAAK,UAAU,WAAW;AAAA,IAC1D;AAEA,WAAO,IAAI,SAAS,KAAK,SAAS,WAAW;AAAA,EAC/C;AAAA,EAEA,MAAa,+BAA2E;AACtF,SAAK,qCACH,KAAK,sCACL,KAAK,QAAQ,kBAAkB,MAAM,4BAA4B;AACnE,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAa,+BAA2E;AACtF,SAAK,qCACH,KAAK,sCACL,KAAK,QAAQ,kBAAkB,MAAM,4BAA4B;AACnE,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAa,sCAAkF;AAC7F,SAAK,4CACH,KAAK,6CACL,KAAK,QAAQ,kBAAkB,MAAM,mCAAmC;AAC1E,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAa,QAAuB;AAClC,UAAM,+BACJ,MAAM,KAAK,6BAA6B;AAC1C,UAAM,6BAA6B,WAAW,SAAS,KAAK;AAAA,EAC9D;AAAA,EAEA,MAAa,mCAAyD;AACpE,UAAM,+BACJ,MAAM,KAAK,6BAA6B;AAC1C,YAAQ,MAAM,6BAA6B,UAAU,GAAG;AAAA,EAC1D;AAAA,EAEA,MAAa,mCAAoD;AAC/D,UAAM,+BACJ,MAAM,KAAK,6BAA6B;AAC1C,WAAO,SAAS,MAAM,6BAA6B,UAAU,GAAG,MAAM;AAAA,EACxE;AAAA,EAEA,MAAa,0CAAgE;AAC3E,UAAM,sCACJ,MAAM,KAAK,oCAAoC;AACjD,YAAQ,MAAM,oCAAoC,UAAU,GAAG;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAMF;AAGO,IAAM,YAA8C;AAAA,EACzD,SAAS,QAAQ,QAAQ,KAAK,OAAO;AAAA,EACrC,UAAU,CAAC,KAAK;AAAA,EAChB,SAAS,CAAC,EAAE,YAAY,MAAM,CAAC;AAAA,EAC/B,kBAAkB,CAAC,MAAM,gBAAgB,MAAM,WAAW;AAC5D;;;AE5dA,IAAM,iBAAiB;AAEvB,IAAMC,SAAQ;AAAA,EACZ,aAAa;AAAA,EACb,oBAAoB;AACtB;AAGA,SAAS,oBAAoB,MAAc,QAAsB;AAC/D,UAAQ,QAAQ;AAAA,IACd,KAAK,GAAG;AACN,eAAS;AACT;AAAA,IACF;AAAA,IACA,KAAK,GAAG;AACN,eAAS,iBAAiB,MAAM,MAAM;AACtC,eAAS;AACT;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,EAAE,IAAI;AACvD,SAAO,IAAI,KAAK,QAAQ,MAAM;AAChC;AAIA,SAAS,eAAe,aAA+B;AACrD,MAAI,MAAM;AACV,SAAO,YAAY,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG;AACvC,SAAO;AACP,SAAO,YAAY,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG;AACxC,SAAO;AACP,SAAO,YAAY,MAAM,IAAI,EAAE,EAAE,KAAK,GAAG;AACzC,SAAO;AACP,SAAO,YAAY,MAAM,IAAI,EAAE,EAAE,KAAK,GAAG;AACzC,SAAO;AACP,SAAO,YAAY,MAAM,IAAI,EAAE,EAAE,KAAK,GAAG;AACzC,SAAO;AACT;AASA,IAAM,uBAAuB;AAAA,EAC3B,QAAQ,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,EACzB,aAAa,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,EAC9B,gBAAgB,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA;AACnC;AAEA,IAAM,oBAA8B,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,EAAE;AACzE,IAAM,oBAA8B,CAAC,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAEzE,IAAM,QAAkB,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAC3D,IAAM,SAAmB,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE5D,IAAM,oBAA8B,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAC3D,IAAM,oBAA8B,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE3D,IAAM,QAAkB,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAC/C,IAAM,SAAmB,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEhD,IAAM,SAAmB,CAAC,IAAI,GAAG,IAAI,GAAG,GAAG,IAAI,GAAG,EAAE;AAEpD,SAAS,UAAU,KAAiB,GAAmB;AACrD,MAAI,IAAI,MAAM,GAAG;AACf,WAAO,IAAK,IAAI,IAAK,CAAC,IAAI;AAAA,EAC5B;AACA,SAAO,IAAK,IAAK,IAAI,IAAK,CAAC,IAAI;AACjC;AAEA,SAAS,kBAAkB,MAA2B;AACpD,SAAO,KAAK,EAAE,MAAM;AACtB;AAEA,IAAM,SAAS;AAAA,EACb;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC3E;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAI;AAAA,EACxE;AAAA,EAAK;AACP;AAEA,SAAS,aAAa,MAA8B;AAClD,QAAM,UAAU,UAAU,MAAM,EAAE;AAClC,QAAM,UAAU,UAAU,MAAM,EAAE;AAClC,QAAM,SAAS,IAAI,WAAW,cAAc;AAC5C,WAAS,IAAI,GAAG,IAAI,gBAAgB,KAAK;AACvC,WAAO,CAAC,IAAI,KAAK,CAAC,IAAI,OAAO,UAAU,CAAC,IAAI,OAAO,UAAU,CAAC;AAAA,EAChE;AACA,SAAO;AACT;AAGA,eAAe,YAAY,MAAuC;AAChE,MAAI,CAAC,kBAAkB,IAAI,GAAG;AAC5B,WAAO;AAAA,EACT;AACA,SAAO,aAAa,IAAI;AAE1B;AAGO,IAAM,aAAN,MAAM,oBAAmB,gBAAgB;AAAA,EA6BtC,YACE,QACA,oBACA,eACR;AACA,UAAM;AAJE;AACA;AACA;AAAA,EAGV;AAAA,EAlCA,aAAoB,QAClB,QACqB;AACrB,UAAM,cAAc,MAAM,OAAO,kBAAkBC,OAAM,WAAW;AACpE,aAAS,YAAY,WAAW;AAEhC,UAAM,qBAAqB,MAAM,YAAY;AAAA,MAC3CA,OAAM;AAAA,IACR;AACA,aAAS,mBAAmB,kBAAkB;AAI9C,UAAM,gBAAgB,MAAM;AAAA,MAC1B,IAAI,YAAY,MAAM,mBAAmB,UAAU,GAAG,MAAM;AAAA,IAC9D;AACA,aAAS,mBAAmB,aAAa;AACzC,UAAM,OAAO,IAAI,YAAW,QAAQ,oBAAoB,aAAa;AAErE,UAAM,mBAAmB,mBAAmB;AAC5C,uBAAmB;AAAA,MACjB;AAAA,MACA,KAAK,4BAA4B,KAAK,IAAI;AAAA,IAC5C;AAEA,WAAO;AAAA,EACT;AAAA,EAUO,OAA2B;AAChC,WAAO,KAAK,OAAO,OAAO;AAAA,EAC5B;AAAA,EAEA,aAAmB;AACjB,SAAK,OAAO,WAAW;AAAA,EACzB;AAAA,EAEA,MAAsB,aAAgC;AACpD,WAAO,KAAK;AAAA,MACV,IAAI,YAAY,MAAM,KAAK,mBAAmB,UAAU,GAAG,MAAM;AAAA,IACnE;AAAA,EACF;AAAA,EAEQ,OAAO,KAAiB,GAAmB;AACjD,UAAM,IAAK,IAAI,IAAK;AACpB,UAAM,QAAQ,IAAK,IAAI;AACvB,WAAQ,IAAI,CAAC,KAAK,QAAS;AAAA,EAC7B;AAAA,EAEQ,UAAU,KAA2B;AAC3C,UAAM,cAA4B;AAAA,MAChC,OAAO;AAAA,QACL,QAAQ,IAAI,MAAM,EAAE;AAAA,QACpB,aAAa,IAAI,MAAM,EAAE;AAAA,MAC3B;AAAA,MACA,SAAS;AAAA,QACP,QAAQ,IAAI,MAAM,CAAC;AAAA,QACnB,aAAa,IAAI,MAAM,CAAC;AAAA,MAC1B;AAAA,MACA,SAAS;AAAA,IACX;AAEA,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,YAAM,KAAK,kBAAkB,CAAC;AAC9B,kBAAY,MAAM,OAAO,CAAC,IACxB,kBAAkB,UAAU,KAAK,KAAK,EAAE,IAAI,CAAC;AAC/C,kBAAY,MAAM,YAAY,CAAC,IAC7B,KAAK,OAAO,KAAK,KAAK,GAAG,IACzB,MAAM,YAAY,MAAM,OAAO,CAAC,CAAC,IACjC,OAAO,CAAC;AAAA,IACZ;AACA,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAM,KAAK,kBAAkB,CAAC;AAC9B,kBAAY,QAAQ,OAAO,CAAC,IAAI,kBAAkB,UAAU,KAAK,EAAE,IAAI,CAAC;AACxE,kBAAY,QAAQ,YAAY,CAAC,KAC9B,UAAU,KAAK,KAAK,CAAC,IAAI,OAAO,EAAE,IACjC,MAAM,YAAY,QAAQ,OAAO,CAAC,CAAC,IACnC,OAAO,CAAC,KACV;AAAA,IACJ;AACA,WAAO,IAAI,SAAS,0BAA0B,WAAW;AAAA,EAC3D;AAAA,EAEA,MAAc,4BAA4B,OAA2B;AACnE,UAAM,MAAM,MAAM,YAAY,IAAI,WAAW,MAAM,OAAO,MAAM,MAAM,CAAC;AACvE,aAAS,GAAG;AACZ,aAAS,GAAG;AAEZ,QAAI,KAAK,uBAAuB,GAAG,GAAG;AACpC,eAAS,kCAAkC;AAC3C;AAAA,IACF;AAEA,UAAM,cAAc,CAAC;AACrB,aAAS,IAAI,GAAG,IAAI,gBAAgB,KAAK;AACvC,kBAAY,KAAK,KAAK,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;AACxC,kBAAY,KAAK,IAAI,CAAC,IAAI,EAAE;AAAA,IAC9B;AACA,aAAS,WAAW;AACpB,UAAM,MAAM,eAAe,WAAW;AACtC,aAAS,GAAG;AAEZ,SAAK,gBAAgB;AAAA,MACnB,eAAe,oBAAoB,YAAY,EAAE,GAAG,YAAY,EAAE,CAAC;AAAA,MACnE,WAAW,MAAM;AAAA,MACjB,OAAO;AAAA,QACL,UAAU;AAAA,MACZ;AAAA,MACA,SAAS,KAAK,UAAU,GAAG;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EAEQ,uBAAuB,KAA0B;AACvD,QAAI,OAAO,KAAK,kBAAkB,aAAa;AAE7C,YAAM,IAAI,MAAM,8CAA8C;AAAA,IAChE;AAEA,QAAI,KAAK,kBAAkB,MAAM;AAC/B,aAAO;AAAA,IACT;AAEA,UAAM,gBAAgB,KAAK;AAE3B,SAAK,gBAAgB;AAErB,aAAS,mCAAmC;AAC5C,aAAS,IAAI,GAAG,IAAI,iBAAiB,GAAG,KAAK;AAC3C,UAAI,cAAc,CAAC,MAAM,IAAI,CAAC,GAAG;AAC/B,iBAAS,uBAAuB,CAAC;AACjC,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AAGO,IAAM,eAAiD;AAAA,EAC5D,SAAS,WAAW,QAAQ,KAAK,UAAU;AAAA,EAC3C,UAAU,CAAC,MAAM,IAAI,MAAM,KAAK;AAAA;AAAA,EAChC,SAAS;AAAA;AAAA;AAAA,IAGP,EAAE,YAAY,KAAK;AAAA,IACnB,EAAE,YAAY,KAAK;AAAA,IACnB,EAAE,YAAY,MAAM;AAAA,IACpB,EAAE,UAAU,CAAC,sCAAsC,EAAE;AAAA,IACrD,EAAE,UAAU,CAAC,sCAAsC,EAAE;AAAA,IACrD,EAAE,UAAU,CAAC,sCAAsC,EAAE;AAAA,EACvD;AAAA,EACA,kBAAkB;AAAA;AAAA;AAAA,IAGhBA,OAAM;AAAA;AAAA;AAAA,EAGR;AACF;;;ACvRA,SAAS,cAAAC,mBAAkB;AAK3B,IAAMC,SAAQ;AAAA,EACZ,eAAe;AAAA,EACf,2BAA2B;AAC7B;AAGA,SAASC,SAAQ,QAA6B;AAE5C,SACE,MAAM,UAAU,IAAI;AAAA,IAAK,IAAI,WAAW,MAAM;AAAA,IAAG,CAAC,MAChD,KAAK,EAAE,SAAS,EAAE,CAAC,GAAG,MAAM,EAAE;AAAA,EAChC,EACA,KAAK,GAAG;AACZ;AAEA,SAAS,eAAe,QAA6B;AACnD,QAAM,WAAW,IAAI,WAAW,MAAM;AACtC,MAAI,MAAM;AACV,aAAW,YAAY,UAAU;AAC/B,WAAO,OAAO,aAAa,QAAQ;AAAA,EACrC;AACA,SAAO;AACT;AAEA,IAAM,UAAkB;AAAA,EACtB,IAAI,KAAK,KAAK,CAAC;AAAA,EACf,IAAI,KAAK,KAAK,EAAE;AAAA,EAChB,IAAI,KAAK,KAAK,CAAC;AAAA,EACf,IAAI,KAAK,KAAK,EAAE;AAAA,EAChB,IAAI,KAAK,KAAK,CAAC;AAAA,EACf,IAAI,KAAK,KAAK,EAAE;AAAA,EAChB,IAAI,KAAK,KAAK,CAAC;AAAA,EACf,IAAI,KAAK,KAAK,EAAE;AAAA,EAChB,IAAI,KAAK,KAAK,CAAC;AAAA,EACf,IAAI,KAAK,KAAK,EAAE;AAAA,EAChB,IAAI,KAAK,KAAK,CAAC;AAAA,EACf,IAAI,KAAK,KAAK,EAAE;AAClB;AAGO,IAAM,SAAN,MAAM,gBAAe,gBAAgB;AAAA,EAwClC,YACE,QACD,2BACP;AACA,UAAM;AAHE;AACD;AAAA,EAGT;AAAA;AAAA,EA3CA,aAAoB,QAClB,QACiB;AACjB,UAAM,UAAU,MAAM,OAAO,kBAAkBD,OAAM,aAAa;AAClE,aAAS,EAAE,QAAQ,CAAC;AACpB,UAAM,4BAA4B,MAAM,QAAQ;AAAA,MAC9CA,OAAM;AAAA,IACR;AACA,aAAS,EAAE,0BAA0B,CAAC;AAEtC,UAAM,OAAO,IAAI,QAAO,QAAQ,yBAAyB;AAEzD,UAAM,0BAA0B,mBAAmB;AACnD,8BAA0B;AAAA,MACxB;AAAA,MACA,KAAK,4BAA4B,KAAK,IAAI;AAAA,IAC5C;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWQ,WAAoB,CAAC;AAAA,EAErB,kBAAqC;AAAA,EACrC,cAA0B,IAAIE,YAAW,GAAG,GAAG,GAAG,CAAC;AAAA,EACnD,cAA0B,IAAIA,YAAW,GAAG,GAAG,GAAG,CAAC;AAAA,EACnD,aAAyB,IAAIA,YAAW,GAAG,GAAG,GAAG,CAAC;AAAA,EAClD,MAAW,IAAI,IAAI;AAAA,EAS3B,aAAmB;AACjB,SAAK,OAAO,WAAW;AAAA,EACzB;AAAA,EAEO,QAAc;AACnB,SAAK,SAAS;AACd,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEO,SAAS,KAAiB;AAC/B,SAAK,MAAM,OAAO,IAAI,IAAI;AAAA,EAC5B;AAAA,EAEO,mBAAyB;AAC9B,SAAK,kBAAkB,KAAK,YAAY,MAAM,EAAE,OAAO;AACvD,SAAK,cAAc,IAAIA,YAAW,GAAG,GAAG,GAAG,CAAC;AAC5C,SAAK,aAAa,IAAIA,YAAW,GAAG,GAAG,GAAG,CAAC;AAAA,EAC7C;AAAA,EAEO,OAA2B;AAChC,WAAO,KAAK,OAAO,OAAO;AAAA,EAC5B;AAAA,EAEQ,4BAA4B,OAAkB;AACpD,UAAM,SAAmB,MAAM,OAAO;AACtC,SAAK,SAAS,KAAK,CAAC,MAAM,WAAWD,SAAQ,OAAO,MAAM,CAAC,CAAC;AAE5D,QAAI,OAAO,aAAa,IAAI;AAC1B,eAAS,IAAI,GAAG,IAAI,OAAO,aAAa,GAAG,KAAK,GAAG;AACjD,cAAM,OAAO,QAAQ,OAAO,SAAS,CAAC,CAAC;AACvC,aAAK,MAAM,uBAAuB,KAAK,KAAK,IAAI;AAChD,aAAK,gBAAgB;AAAA,UACnB,eAAe,QAAQ,OAAO,SAAS,CAAC,CAAC;AAAA,UACzC,WAAW,MAAM;AAAA,UACjB,OAAO;AAAA,YACL,UAAUA,SAAQ,OAAO,MAAM;AAAA,UACjC;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,OAAO;AACL,YAAM,SAAS;AAAA,QACb,OAAO,OAAO,MAAM,GAAG,OAAO,aAAa,CAAC;AAAA,MAC9C,EACG,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,SAAS,GAAG,EAAE,IAAI,KAAK;AACrC,YAAM,OAAO,IAAIC,YAAW,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAEtE,WAAK,cAAc,KAAK,MAAM;AAE9B,UAAI,CAAC,KAAK,iBAAiB;AACzB,aAAK,kBAAkB,KAAK,MAAM,EAAE,OAAO;AAAA,MAC7C;AAEA,YAAM,aAAa,KAAK,MAAM,EAAE,SAAS,KAAK,gBAAgB,MAAM,CAAC;AACrE,iBAAW,IAAI,CAAC,WAAW;AAE3B,WAAK,WAAW,MAAM,YAAY,GAAG;AACrC,WAAK,YAAY,cAAc,KAAK,YAAY,iBAAiB;AAEjE,WAAK,oBAAoB;AAAA,QACvB,YAAY,KAAK;AAAA,QACjB,WAAW,MAAM;AAAA,MACnB,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,IAAM,oBAAoB;AAGnB,IAAM,eAAiD;AAAA,EAC5D,SAAS,OAAO,QAAQ,KAAK,MAAM;AAAA,EACnC,UAAU,CAAC,UAAU,OAAO;AAAA,EAC5B,SAAS,CAAC,EAAE,YAAY,SAAS,GAAG,EAAE,YAAY,QAAQ,CAAC;AAAA,EAC3D,kBAAkB,CAACF,OAAM,aAAa;AACxC;;;ACvKO,SAAS,aAAa,GAAW,SAAyB;AAC/D,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,SAAS,KAAK;AAChC,UAAM,YAAY,UAAU,IAAI,IAAI;AACpC,UAAM,eAAe,IAAK,KAAO;AAMjC,cACE,YAAY,IAAI,gBAAgB,CAAC,YAAY,gBAAgB;AAAA,EACjE;AACA,SAAO;AACT;;;ACCA,IAAMG,SAAQ;AAAA,EACZ,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,uBAAuB;AACzB;AAGO,IAAM,cAAN,MAAM,qBAAoB,gBAAgB;AAAA,EAwBvC,YACN,UACA,UACA,QACQ,QACA,qBACR;AACA,UAAM;AAHE;AACA;AAIR,WAAO;AAAA,MACL;AAAA,MACA,KAAK,aAAa,KAAK,IAAI;AAAA,IAC7B;AAEA,SAAK,oBAAoB,mBAAmB;AAC5C,SAAK,mBAAmB;AAAA,EAC1B;AAAA;AAAA,EAtCA,aAAoB,QAClB,QACA,QACsB;AACtB,UAAM,UAAU,MAAM,OAAO,kBAAkBA,OAAM,cAAc;AACnE,aAAS,YAAY,OAAO;AAE5B,UAAM,sBAAsB,MAAM,QAAQ;AAAA,MACxCA,OAAM;AAAA,IACR;AACA,aAAS,mBAAmB,mBAAmB;AAE/C,UAAM,OAAO,IAAI;AAAA,MACf,MAAM,QAAQ,OAAO,EAAE,QAAQ;AAAA,MAC/B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAoBO,OAA2B;AAChC,WAAO,KAAK,OAAO,OAAO;AAAA,EAC5B;AAAA,EAEA,aAAmB;AACjB,SAAK,OAAO,WAAW;AAAA,EACzB;AAAA,EAEA,eAAqB;AACnB,SAAK,cAAc,IAAI,YAAY,YAAY,CAAC;AAAA,EAClD;AAAA,EAEO,qBAA2B;AAChC,SAAK,oBAAoB;AAAA,MACvB;AAAA,MACA,CAAC,MAAW,KAAK,sBAAsB,CAAC;AAAA,IAC1C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,sBAAsB,OAGrB;AACP,UAAM,QAAQ,KAAK,YAAY,MAAM,OAAO,KAAM;AAElD,SAAK,gBAAgB;AAAA,MACnB,eAAe,MAAM;AAAA,MACrB,WAAW,MAAM;AAAA,MACjB,SAAS,MAAM;AAAA,IACjB,CAAC;AAAA,EACH;AAAA,EAEQ,YAAY,IAAuD;AACzE,UAAM,QAAQ;AAAA,MACZ,IAAI,KAAK,GAAG;AAAA,MACZ,IAAI,KAAK,IAAI;AAAA,MACb,IAAI,KAAK,GAAG;AAAA,MACZ,IAAI,KAAK,IAAI;AAAA,MACb,IAAI,KAAK,GAAG;AAAA,MACZ,IAAI,KAAK,IAAI;AAAA,MACb;AAAA,MACA;AAAA,MACA,IAAI,KAAK,GAAG;AAAA,MACZ,IAAI,KAAK,IAAI;AAAA,MACb,IAAI,KAAK,GAAG;AAAA,MACZ,IAAI,KAAK,IAAI;AAAA,MACb,IAAI,KAAK,GAAG;AAAA,MACZ,IAAI,KAAK,IAAI;AAAA;AAAA;AAAA,IAGf;AAEA,UAAM,KAAK,IAAI,WAAW,GAAG,UAAU;AACvC,aAAS,IAAI,GAAG,IAAI,GAAG,YAAY,KAAK;AACtC,SAAG,CAAC,IAAI,aAAa,GAAG,SAAS,CAAC,GAAG,CAAC;AAAA,IACxC;AACA,UAAM,cAAc;AAAA,MAClB,GAAG,MAAM,GAAG,EAAE;AAAA,IAChB;AAEA,UAAM,cAAc;AAAA,MAClB,OAAO,aAAa,YAAY,OAAO,EAAE;AAAA,MACzC,QAAQ,aAAa,YAAY,QAAQ,EAAE;AAAA,MAC3C,OAAO,aAAa,YAAY,OAAO,EAAE;AAAA,MACzC,QAAQ,aAAa,YAAY,QAAQ,EAAE;AAAA,MAC3C,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,WAAW;AAAA;AAAA,MACX,QAAQ;AAAA,IACV;AAGA,WAAO;AAAA,MACL,SAAS,4BAAwC,WAAW;AAAA,MAC5D,YAAY,MAAM,GAAG,EAAE,IAAI,EAAU;AAAA,IACvC;AAAA,EACF;AAAA,EAEA,MAAsB,aAAgC;AACpD,UAAM,KAAK,MAAM,KAAK,oBAAoB,UAAU;AACpD,WAAO,KAAK,YAAY,EAAE,EAAE;AAAA,EAC9B;AACF;AAGO,IAAM,gBAAkD;AAAA,EAC7D,SAAS,YAAY,QAAQ,KAAK,WAAW;AAAA,EAC7C,UAAU,CAAC,SAAS;AAAA,EACpB,SAAS,CAAC,EAAE,YAAY,UAAU,CAAC;AAAA,EACnC,kBAAkB,CAACA,OAAM,cAAc;AACzC;;;AC3JA,IAAM,qBAAqB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AACF;AAGA,eAAsB,mBACpB,SAC0B;AAC1B,SAAO,iBAAkC,oBAAoB,OAAO;AACtE;;;ACdA,SAASC,SAAQ,QAA0C;AAEzD,SACE,MAAM,UAAU,IAAI;AAAA,IAAK,IAAI,WAAW,MAAM;AAAA,IAAG,CAAC,MAChD,KAAK,EAAE,SAAS,EAAE,CAAC,GAAG,MAAM,EAAE;AAAA,EAChC,EACA,KAAK,GAAG;AACZ;AAEA,IAAM,wBAAwB,KAAK;AACnC,IAAM,2BAA2B;AACjC,IAAM,0BAA0B;AAEhC,IAAM,WAAW,IAAI,IAAI,iBAAiB;AAC1C,IAAM,aAAa,SAAS,OAAO;AACnC,IAAM,WAAW,IAAI,IAAI,iBAAiB;AAC1C,IAAM,aAAa,SAAS,OAAO;AAGnC,IAAMC,SAAQ;AAAA,EACZ,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,oBAAoB;AACtB;AAEA,IAAMC,WAAkC;AAAA,EACtC,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,MAAM;AAAA,EACN,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,MAAM;AAAA,EACN,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,MAAM;AAAA,EACN,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,MAAM;AAAA,EACN,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,MAAM;AACR;AAEA,IAAM,WAAmC;AAAA,EACvC,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,MAAM;AAAA,EACN,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,MAAM;AAAA,EACN,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,MAAM;AAAA,EACN,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,MAAM;AAAA,EACN,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,MAAM;AACR;AAEA,SAAS,mBAAmB,QAAyB;AACnD,SAAO,SAAS,MAAM;AACxB;AAEA,SAAS,eAAe,QAAwB;AAC9C,SAAO,mBAAmB,MAAM,IAC5B,0BACA;AACN;AAEA,SAAS,iBAAiB,MAAY;AACpC,UAAQ,MAAM,gBAAgB,MAAM,KAAK,SAAS,CAAC;AACnD,QAAM,IAAI,MAAM,eAAe;AACjC;AAEA,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AAcO,IAAM,WAAN,MAAM,kBAAiB,YAAY;AAAA,EAYxC,YACE,UACQ,QACR,QACQ,sBACA,oBACR;AACA,UAAM;AALE;AAEA;AACA;AAGR,WAAO;AAAA,MACL;AAAA,MACA,KAAK,aAAa,KAAK,IAAI;AAAA,IAC7B;AAAA,EACF;AAAA,EAvBA,0BAAuD;AAAA,EACvD,uBAA2C,MAAM;AAAA,EAAC;AAAA;AAAA,EAGlD,sBAAuC;AAAA,IACrC,QAAQ;AAAA,IACR,mBAAmB;AAAA,IACnB,aAAa;AAAA,IACb,WAAW;AAAA,EACb;AAAA;AAAA,EAiBA,aAAa,QACX,QACA,QACA;AACA,UAAM,kBAAkB,MAAM,OAAO;AAAA,MACnCD,OAAM;AAAA,IACR;AACA,UAAM,uBAAuB,MAAM,gBAAgB;AAAA,MACjDA,OAAM;AAAA,IACR;AACA,UAAM,qBAAqB,MAAM,gBAAgB;AAAA,MAC/CA,OAAM;AAAA,IACR;AACA,UAAM,QAAQ,IAAI;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEO,OAA2B;AAChC,WAAO,KAAK,OAAO,OAAO;AAAA,EAC5B;AAAA,EAEA,aAAmB;AACjB,SAAK,OAAO,WAAW;AAAA,EACzB;AAAA,EAEA,eAAqB;AACnB,SAAK,cAAc,IAAI,YAAY,YAAY,CAAC;AAAA,EAClD;AAAA,EAEQ,aAAa,MAAoB;AACvC,UAAM,UACH,KAAK,oBAAoB,SAAS,WAAWC,UAAS,KAAK,SAAS,CAAC,KACtE;AACF,QAAI,WAAW,MAAM;AACnB,uBAAiB,IAAI;AAAA,IACvB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,aAAa,SAAkC;AAC3D,QAAI,QAAQ,SAAS,uBAAuB;AAC1C,YAAM,IAAI;AAAA,QACR,kBAAkB,qBAAqB;AAAA,MACzC;AAAA,IACF;AAEA,UAAM,QAAQ,IAAI,WAAW,EAAE;AAC/B,QAAI;AACJ,SAAK,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACnC,YAAM,UAAU,KAAK,MAAM,IAAI,CAAC;AAChC,YAAM,OAAO,KAAK,QAAQ,CAAC;AAC3B,UAAI,IAAI,MAAM,GAAG;AACf,cAAM,OAAO,KAAK;AAAA,MACpB;AAAA,IACF;AACA,QAAI,QAAQ,SAAS,MAAM,GAAG;AAC5B,YAAM,KAAK,KAAK,QAAQ,SAAS,CAAC,IAAI,CAAC,KAAK;AAAA,IAC9C;AACA,aAASC,KAAI,KAAK,KAAK,QAAQ,SAAS,CAAC,GAAGA,KAAI,IAAIA,MAAK;AACvD,YAAMA,EAAC,IAAI;AAAA,IACb;AACA,QAAI,gBAAgB;AACpB,eAAW,UAAU,SAAS;AAC5B,uBAAiB,eAAe,MAAM;AAAA,IACxC;AACA,SAAK,qBAAqB,YAAYH,SAAQ,KAAK,CAAC;AACpD,UAAM,KAAK,mBAAmB,WAAW,KAAK;AAC9C,UAAM,MAAM,gBAAgB,IAAI;AAChC,YAAQ,MAAM,KAAK,UAAU,GAAG,iBAAiB,GAAG;AAAA,IAEpD;AACA,UAAM,MAAM,KAAK,oBAAoB,SAAS;AAAA,EAChD;AAAA,EAEA,MAAc,YAAqC;AACjD,UAAM,cAAc,IAAI;AAAA,OACrB,MAAM,KAAK,qBAAqB,UAAU,GAAG;AAAA,IAChD;AACA,SAAK,qBAAqB,oBAAoB,YAAY,CAAC,CAAC;AAC5D,WAAO;AAAA,MACL,gBAAgB,YAAY,CAAC;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,SAAkB;AAAA,EAClB,eAAqB;AAAA,EAAC;AAAA,EAEd,YAAiB,IAAI,IAAI;AAAA;AAAA,EAEjC,MAAc,WAAW,OAA2B;AAClD,SAAK,YAAY,KAAK,UAAU,OAAO,KAAK,EAAE,qBAAqB;AAAA,MACjE,+BAA+B,UAAU;AAAA,IAC3C,CAAC;AACD,QAAI,CAAC,KAAK,QAAQ;AAEhB,UAAI;AACF,aAAK,SAAS;AACd,YAAI,KAAK,UAAU,6BAA6B,MAAM,GAAG;AACvD,gBAAM,MAAM,KAAK,oBAAoB,WAAW;AAAA,QAClD;AAEA,eAAO,KAAK,UAAU,6BAA6B,IAAI,GAAG;AACxD,cAAI,WAAW,MAAM,KAAK,KAAK,UAAU,cAAc,CAAC;AACxD,cACE,KAAK,oBAAoB,qBACzB,SAAS,WAAW,GACpB;AACA,kBAAM,OAAO,SAAS,CAAC;AACvB,gBAAI,KAAK,WAAW,GAAG;AACrB,yBAAW;AAAA,gBACT,KAAK,SAAS,EAAE,QAAQ,EAAE,CAAC;AAAA,gBAC3B,KAAK,SAAS,EAAE,QAAQ,EAAE,CAAC;AAAA,cAC7B;AAAA,YACF,OAAO;AACL,yBAAW;AAAA,gBACT,KAAK,SAAS,EAAE,QAAQ,CAAC,KAAK,OAAO,CAAC;AAAA,gBACtC,KAAK,SAAS,EAAE,QAAQ,EAAE,CAAC;AAAA,cAC7B;AAAA,YACF;AAAA,UACF;AACA,gBAAMI,SAAQ,SAAS,OAAO,GAAG,qBAAqB;AACtD,gBAAM,UAAoBA,OAAM,IAAI,KAAK,aAAa,KAAK,IAAI,CAAC;AAChE,gBAAM,UAAU,IAAI,IAAIA,MAAK;AAC7B,eAAK,qBAAqB,WAAW,QAAQ,SAAS,CAAC;AACvD,cAAI,KAAK,yBAAyB;AAChC,iBAAK,wBAAwB,OAAO;AAAA,UACtC;AACA,gBAAM,QAAQ,KAAK,aAAa,OAAO;AACvC,eAAK,YAAY,IAAI,IAAI,QAAQ;AACjC,gBAAM;AAAA,QACR;AAAA,MACF,UAAE;AACA,aAAK,SAAS;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,OAAsC;AAErD,eAAW,QAAQ,OAAO;AACxB,YAAM,MAAM,KAAK,SAAS;AAC1B,UAAI,QAAQ,KAAK,oBAAoB,SAAS,WAAWF,WAAU;AACjE,cAAM,KAAK,WAAW,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;AAAA,MACvC,WACE,KAAK,YAAY,KAAK,oBAAoB,SAAS,MAAM,MACzD;AAEA,cAAM,QAAQ,IAAI;AAAA,UAChB,KAAK;AAAA,YACH,KAAK,oBAAoB,SAAS,WAAW;AAAA,UAC/C;AAAA,UACA,KAAK;AAAA,YACH,IAAI,IAAI;AAAA,cACN,KAAK,SAAS;AAAA,gBACZ,QAAQ,KAAK,oBAAoB,SAAS,MAAM;AAAA,cAClD,CAAC;AAAA,YACH,CAAC,EAAE;AAAA,cACD,KAAK,oBAAoB,SAAS,aAAa;AAAA,YACjD;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;AAGO,IAAM,iBAA4C;AAAA,EACvD,SAAS,SAAS,QAAQ,KAAK,QAAQ;AAAA,EACvC,UAAU,CAAC,KAAK;AAAA,EAChB,SAAS,CAAC,EAAE,YAAY,MAAM,CAAC;AAAA,EAC/B,kBAAkB,CAACD,OAAM,eAAe;AAC1C;;;ACjTA,IAAM,oBAAuD,CAAC,cAAc;AAG5E,eAAsB,kBACpB,SACyB;AACzB,SAAO,iBAAiC,mBAAmB,OAAO;AACpE;;;ACVA,IAAMI,SAAQ;AAAA,EACZ,iBAAiB;AAAA,EACjB,oBAAoB;AACtB;AAYO,IAAM,WAAN,MAAM,kBAAiB,YAAY;AAAA,EAIxC,YACE,UACQ,QACR,QACQ,oBACR;AACA,UAAM;AAJE;AAEA;AAGR,SAAK,aAAa;AAClB,YAAQ,IAAI,MAAM;AAClB,WAAO;AAAA,MACL;AAAA,MACA,KAAK,aAAa,KAAK,IAAI;AAAA,IAC7B;AAAA,EACF;AAAA,EAhBQ,UAAU;AAAA,EACV,iBAAwC;AAAA;AAAA,EAkBhD,aAAa,QACX,QACA,QACA;AACA,UAAM,kBAAkB,MAAM,OAAO;AAAA,MACnCA,OAAM;AAAA,IACR;AACA,YAAQ,IAAI,YAAY,eAAe;AACvC,UAAM,qBAAqB,MAAM,gBAAgB;AAAA,MAC/CA,OAAM;AAAA,IACR;AACA,YAAQ,IAAI,mBAAmB,kBAAkB;AACjD,UAAM,QAAQ,IAAI;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,aAAmB;AACjB,SAAK,OAAO,WAAW;AAAA,EACzB;AAAA,EAEA,MAAM,OAAO;AACX,QAAI,CAAC,KAAK,SAAS;AACjB;AAAA,IACF;AACA,UAAM,QAAQ,MAAM,KAAK,sBAAsB;AAE/C,UAAM,SAAyB;AAAA,MAC7B,aAAa,KAAK,aAAa,MAAM,MAAM,GAAG,CAAC,CAAC;AAAA,MAChD,aAAa;AAAA,QACX,KAAK,aAAa,MAAM,MAAM,GAAG,CAAC,CAAC;AAAA,QACnC,KAAK,aAAa,MAAM,MAAM,GAAG,EAAE,CAAC;AAAA,QACpC,KAAK,aAAa,MAAM,MAAM,IAAI,EAAE,CAAC;AAAA,MACvC;AAAA,IACF;AAEA,QAAI,OAAO,gBAAgB,GAAG;AAC5B,UAAI,KAAK,kBAAkB,KAAK,eAAe,gBAAgB,GAAG;AAChE,aAAK,cAAc,IAAI,YAAY,OAAO,CAAC;AAAA,MAC7C;AAAA,IACF;AAEA,QAAI,OAAO,gBAAgB,KAAK,KAAK,gBAAgB;AACnD,UAAI,KAAK,eAAe,gBAAgB,GAAG;AACzC,aAAK,cAAc,IAAI,YAAY,OAAO,CAAC;AAAA,MAC7C;AAEA,UAAI,OAAO,gBAAgB,KAAK,eAAe,aAAa;AAC1D,aAAK,cAAc,IAAI,YAAY,UAAU,EAAE,OAAO,CAAC,CAAC;AAExD,YACE,OAAO,gBAAgB,OAAO,YAAY,CAAC,KAC3C,OAAO,YAAY,CAAC,MAAM,KAAK,eAAe,YAAY,CAAC,KAC3D,OAAO,YAAY,CAAC,MAAM,KAAK,eAAe,YAAY,CAAC,GAC3D;AACA,eAAK,cAAc,IAAI,YAAY,QAAQ,EAAE,OAAO,CAAC,CAAC;AAAA,QACxD;AAAA,MACF;AAAA,IACF;AAEA,SAAK,iBAAiB;AAEtB,SAAK,KAAK;AAAA,EACZ;AAAA,EAEA,eAAqB;AACnB,SAAK,cAAc,IAAI,YAAY,YAAY,CAAC;AAAA,EAClD;AAAA,EAEA,MAAM,wBAAwB;AAC5B,WAAO,IAAI,YAAY,MAAM,KAAK,mBAAmB,UAAU,GAAG,MAAM;AAAA,EAC1E;AAAA,EAEA,MAAM,UAAU;AACd,UAAM,QAAQ,MAAM,KAAK,sBAAsB;AAC/C,WAAO,KAAK,aAAa,MAAM,MAAM,GAAG,CAAC,CAAC;AAAA,EAC5C;AAAA,EAEA,aAAa,OAAmB;AAC9B,YAAQ,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,MAAO,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI;AAAA,EACnE;AAAA,EAEA,eAAe;AACb,SAAK,UAAU;AACf,SAAK,KAAK;AAAA,EACZ;AAAA,EAEA,cAAc;AACZ,SAAK,UAAU;AAAA,EACjB;AACF;AAGO,IAAMC,kBAA4C;AAAA,EACvD,SAAS,SAAS,QAAQ,KAAK,QAAQ;AAAA,EACvC,UAAU,CAAC,KAAK;AAAA,EAChB,SAAS,CAAC,EAAE,YAAY,MAAM,CAAC;AAAA,EAC/B,kBAAkB,CAACD,OAAM,eAAe;AAC1C;;;ACtIA,IAAM,oBAAuD,CAACE,eAAc;AAG5E,eAAsB,kBACpB,SACyB;AACzB,SAAO,iBAAiC,mBAAmB,OAAO;AACpE;",
|
|
6
6
|
"names": ["Quaternion", "Quaternion", "UUIDs", "UUIDs", "Quaternion", "UUIDs", "buf2hex", "Quaternion", "UUIDs", "buf2hex", "UUIDs", "moveMap", "i", "moves", "UUIDs", "ganTimerConfig", "ganTimerConfig"]
|
|
7
7
|
}
|