cubing 0.59.2 → 0.60.0

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.
Files changed (36) hide show
  1. package/dist/lib/cubing/{KPattern-DEaZMwD9.d.ts → PuzzleLoader-ApHCdGgn.d.ts} +94 -91
  2. package/dist/lib/cubing/alg/index.d.ts +3 -2
  3. package/dist/lib/cubing/bluetooth/index.d.ts +6 -5
  4. package/dist/lib/cubing/bluetooth/index.js.map +2 -2
  5. package/dist/lib/cubing/{bluetooth-puzzle-CweI5h6j.d.ts → bluetooth-puzzle-CN0X1-Rm.d.ts} +1 -1
  6. package/dist/lib/cubing/chunks/{chunk-UD4LT3FY.js → chunk-BUZPONAW.js} +1 -1
  7. package/dist/lib/cubing/chunks/chunk-BUZPONAW.js.map +7 -0
  8. package/dist/lib/cubing/chunks/{chunk-V7MAXDP4.js → chunk-PVOSBZRD.js} +2 -2
  9. package/dist/lib/cubing/chunks/chunk-PVOSBZRD.js.map +7 -0
  10. package/dist/lib/cubing/chunks/{chunk-2HSEQ2FC.js → chunk-UWBMBZER.js} +1 -1
  11. package/dist/lib/cubing/chunks/{inside-NS3PIQ5Z.js → inside-7R2QE4L7.js} +3 -3
  12. package/dist/lib/cubing/chunks/{search-dynamic-solve-4x4x4-GNM5XEZR.js → search-dynamic-solve-4x4x4-YZ3W3BZR.js} +2 -2
  13. package/dist/lib/cubing/chunks/search-worker-entry.js +1 -1
  14. package/dist/lib/cubing/chunks/{twisty-dynamic-3d-SIRF3JVR.js → twisty-dynamic-3d-LPZQIDD2.js} +2 -2
  15. package/dist/lib/cubing/chunks/{twisty-dynamic-3d-SIRF3JVR.js.map → twisty-dynamic-3d-LPZQIDD2.js.map} +2 -2
  16. package/dist/lib/cubing/{index-B28YEQVF.d.ts → index-BFw0u55q.d.ts} +1 -1
  17. package/dist/lib/cubing/kpuzzle/index.d.ts +2 -1
  18. package/dist/lib/cubing/notation/index.d.ts +3 -2
  19. package/dist/lib/cubing/notation/index.js +1 -1
  20. package/dist/lib/cubing/protocol/index.d.ts +2 -1
  21. package/dist/lib/cubing/puzzle-geometry/index.d.ts +3 -2
  22. package/dist/lib/cubing/puzzles/index.d.ts +2 -1
  23. package/dist/lib/cubing/scramble/index.d.ts +3 -2
  24. package/dist/lib/cubing/scramble/index.js +1 -1
  25. package/dist/lib/cubing/search/index.d.ts +3 -2
  26. package/dist/lib/cubing/search/index.js +1 -1
  27. package/dist/lib/cubing/stream/index.d.ts +3 -2
  28. package/dist/lib/cubing/twisty/index.d.ts +18 -17
  29. package/dist/lib/cubing/twisty/index.js +40 -22
  30. package/dist/lib/cubing/twisty/index.js.map +2 -2
  31. package/package.json +3 -2
  32. package/dist/lib/cubing/chunks/chunk-UD4LT3FY.js.map +0 -7
  33. package/dist/lib/cubing/chunks/chunk-V7MAXDP4.js.map +0 -7
  34. /package/dist/lib/cubing/chunks/{chunk-2HSEQ2FC.js.map → chunk-UWBMBZER.js.map} +0 -0
  35. /package/dist/lib/cubing/chunks/{inside-NS3PIQ5Z.js.map → inside-7R2QE4L7.js.map} +0 -0
  36. /package/dist/lib/cubing/chunks/{search-dynamic-solve-4x4x4-GNM5XEZR.js.map → search-dynamic-solve-4x4x4-YZ3W3BZR.js.map} +0 -0
@@ -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/common.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/qiyi.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 } from \"three/src/math/Quaternion.js\";\nimport { Vector3 } from \"three/src/math/Vector3.js\";\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 | ((\n server: BluetoothRemoteGATTServer,\n device: BluetoothDevice,\n ) => Promise<T>)\n | ((\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 { KPattern } from \"../kpuzzle/KPattern\";\nimport type { PuzzleLoader } from \"../puzzles\";\nimport type { KeyMapping } from \"../puzzles/cubing-private\";\nimport type { PuzzleID } from \"../twisty\";\nimport { BluetoothPuzzle } from \"./smart-puzzle/bluetooth-puzzle\";\n\n/** @category Keyboard Puzzles */\nexport class KeyboardPuzzle extends BluetoothPuzzle {\n private keyMappingAndPatternPromise: Promise<\n [KeyMapping | undefined, KPattern]\n >;\n\n listener: EventListener; // (e: KeyboardEvent) => Promise<void>;\n\n // TODO: Decide on the right arguments.\n // TODO: support tying the puzzle to a TwistyPlayer.\n constructor(\n private target: Element,\n puzzle: PuzzleID | PuzzleLoader = \"3x3x3\",\n ) {\n super();\n // TODO: Filter out repeated keydown?\n // TODO: how do we avoid this awkward cast?\n this.listener = this.onKeyDown.bind(this) as any as EventListener;\n target.addEventListener(\"keydown\", this.listener);\n this.keyMappingAndPatternPromise = this.setPuzzleInternal(puzzle);\n }\n\n public name(): string | undefined {\n return \"Keyboard Input\";\n }\n\n async setPuzzleInternal(\n puzzle: PuzzleID | PuzzleLoader,\n ): Promise<[KeyMapping | undefined, KPattern]> {\n const puzzleLoader = await (async () =>\n typeof puzzle === \"string\"\n ? (await import(\"../puzzles\")).puzzles[puzzle]\n : puzzle)();\n const kpuzzle = await (async () => puzzleLoader.kpuzzle())();\n return Promise.all([puzzleLoader.keyMapping?.(), kpuzzle.defaultPattern()]);\n }\n\n disconnect() {\n this.target.removeEventListener(\"keydown\", this.listener as EventListener);\n }\n\n public override async getPattern(): Promise<KPattern> {\n return (await this.keyMappingAndPatternPromise)[1];\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 this.keyMappingAndPatternPromise = (async () => {\n const [keyMapping, pattern] = await this.keyMappingAndPatternPromise;\n const algLeaf = keyToMove(keyMapping, e);\n let newPattern: KPattern | undefined;\n if (algLeaf) {\n newPattern = pattern.applyAlg(new Alg([algLeaf])); // TODO\n this.dispatchAlgLeaf({\n latestAlgLeaf: algLeaf,\n timeStamp: e.timeStamp,\n pattern: newPattern,\n });\n e.preventDefault();\n }\n return [keyMapping, newPattern ?? pattern];\n })();\n }\n}\n\n// TODO: Type\n/** @category Keyboard Puzzles */\nexport async function debugKeyboardConnect(\n target: any = window,\n puzzle: PuzzleID | PuzzleLoader = \"3x3x3\",\n): Promise<KeyboardPuzzle> {\n return new KeyboardPuzzle(target, puzzle);\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 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/src/math/Quaternion.js\";\nimport { Move } from \"../../alg\";\nimport { KPattern, type KPuzzle } 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\";\nimport { getPatternData } from \"./common\";\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: ArrayBufferLike): 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 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:\n | Promise<BluetoothRemoteGATTCharacteristic>\n | undefined;\n\n private cachedFaceletStatus2Characteristic:\n | Promise<BluetoothRemoteGATTCharacteristic>\n | undefined;\n\n private cachedActualAngleAndBatteryCharacteristic:\n | Promise<BluetoothRemoteGATTCharacteristic>\n | undefined;\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 return new KPattern(\n this.kpuzzle,\n getPatternData(\n stickers,\n faceOrder,\n gan356iEdgeMappings,\n gan356iCornerMappings,\n ),\n );\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<ArrayBufferLike> {\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<ArrayBufferLike> {\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 smart 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: BufferSource | Uint8Array,\n): Promise<CryptoKey> {\n return await crypto.subtle.importKey(\n \"raw\",\n keyBytes as BufferSource,\n AES_CBC,\n true,\n [\"encrypt\", \"decrypt\"],\n );\n}\n\nasync function unsafeEncryptBlockWithIV(\n key: CryptoKey,\n plaintextBlock: BufferSource | Uint8Array,\n iv: BufferSource | Uint8Array,\n): Promise<ArrayBuffer> {\n const cryptoResult: ArrayBuffer = await window.crypto.subtle.encrypt(\n {\n name: AES_CBC,\n iv: iv as BufferSource,\n },\n key,\n plaintextBlock as BufferSource,\n );\n return cryptoResult.slice(0, blockSize);\n}\n\nexport async function unsafeEncryptBlock(\n key: CryptoKey,\n plaintextBlock: BufferSource | 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: BufferSource | Uint8Array,\n): Promise<ArrayBuffer> {\n const paddingBlock = await unsafeEncryptBlockWithIV(\n key,\n paddingBlockPlaintext,\n ciphertextBlock as BufferSource,\n );\n\n const cbcCiphertext = new Uint8Array(2 * blockSize);\n cbcCiphertext.set(new Uint8Array(ciphertextBlock as Uint8Array), 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", "import type { KPatternData } from \"../../kpuzzle\";\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\nexport function getPatternData(\n stickers: number[],\n faceOrder: string,\n edgeMappings: number[][],\n cornerMappings: number[][],\n): KPatternData {\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],\n },\n };\n\n for (const cornerMapping of cornerMappings) {\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 edgeMappings) {\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 patternData;\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 { type BluetoothConfig, BluetoothPuzzle } 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] =\n 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/src/math/Quaternion.js\";\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<ArrayBuffer> = 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", "/* tslint:disable no-bitwise */\n\nimport { type AlgLeaf, Move } from \"../../alg\";\nimport { KPattern, type KPuzzle } from \"../../kpuzzle\";\nimport { puzzles } from \"../../puzzles\";\nimport {\n importKey,\n unsafeDecryptBlock,\n unsafeEncryptBlock,\n} from \"../../vendor/public-domain/unsafe-raw-aes/unsafe-raw-aes\";\nimport { type BluetoothConfig, BluetoothPuzzle } from \"./bluetooth-puzzle\";\nimport { getPatternData } from \"./common\";\n\nconst UUIDs = {\n qiyiMainService: 0xfff0,\n qiyiMainCharacteristic: 0xfff6,\n};\n\nconst qiyiMoveToBlockMove: { [i: number]: Move } = {\n 1: new Move(\"L\", -1),\n 2: new Move(\"L\"),\n 3: new Move(\"R\", -1),\n 4: new Move(\"R\"),\n 5: new Move(\"D\", -1),\n 6: new Move(\"D\"),\n 7: new Move(\"U\", -1),\n 8: new Move(\"U\"),\n 9: new Move(\"F\", -1),\n 10: new Move(\"F\"),\n 11: new Move(\"B\", -1),\n 12: new Move(\"B\"),\n};\n\nconst faceOrder = \"LRDUFB\";\n\n// \u250C\u2500\u2500\u252C\u2500\u2500\u252C\u2500\u2500\u2510\n// \u250200\u250201\u250202\u2502\n// \u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\n// \u250203\u250204\u250205\u2502\n// \u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\n// \u250206\u250207\u250208\u2502\n// \u2514\u2500\u2500\u2534\u2500\u2500\u2534\u2500\u2500\u2518\n// \u250C\u2500\u2500\u252C\u2500\u2500\u252C\u2500\u2500\u2510\u250C\u2500\u2500\u252C\u2500\u2500\u252C\u2500\u2500\u2510\u250C\u2500\u2500\u252C\u2500\u2500\u252C\u2500\u2500\u2510\u250C\u2500\u2500\u252C\u2500\u2500\u252C\u2500\u2500\u2510\n// \u250236\u250237\u250238\u2502\u250218\u250219\u250220\u2502\u250209\u250210\u250211\u2502\u250245\u250246\u250247\u2502\n// \u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\n// \u250239\u250240\u250241\u2502\u250221\u250222\u250223\u2502\u250212\u250213\u250214\u2502\u250248\u250249\u250250\u2502\n// \u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\n// \u250242\u250243\u250244\u2502\u250224\u250225\u250226\u2502\u250215\u250216\u250217\u2502\u250251\u250252\u250253\u2502\n// \u2514\u2500\u2500\u2534\u2500\u2500\u2534\u2500\u2500\u2518\u2514\u2500\u2500\u2534\u2500\u2500\u2534\u2500\u2500\u2518\u2514\u2500\u2500\u2534\u2500\u2500\u2534\u2500\u2500\u2518\u2514\u2500\u2500\u2534\u2500\u2500\u2534\u2500\u2500\u2518\n// \u250C\u2500\u2500\u252C\u2500\u2500\u252C\u2500\u2500\u2510\n// \u250227\u250228\u250229\u2502\n// \u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\n// \u250230\u250231\u250232\u2502\n// \u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\n// \u250233\u250234\u250235\u2502\n// \u2514\u2500\u2500\u2534\u2500\u2500\u2534\u2500\u2500\u2518\n\nconst qiyiCornerMappings: number[][] = [\n [8, 20, 9], // UFR,\n [2, 11, 45], // URB,\n [0, 47, 36], // UBL,\n [6, 38, 18], // ULF,\n [29, 15, 26], // DRF,\n [27, 24, 44], // DFL,\n [33, 42, 53], // DLB,\n [35, 51, 17], // DBR,\n];\n\nconst qiyiEdgeMappings: number[][] = [\n [7, 19], // UF,\n [5, 10], // UR,\n [1, 46], // UB,\n [3, 37], // UL,\n [28, 25], // DF,\n [32, 16], // DR,\n [34, 52], // DB,\n [30, 43], // DL,\n [23, 12], // FR,\n [21, 41], // FL,\n [48, 14], // BR,\n [50, 39], // BL,\n];\n\n/**\n * Generates the checksum of the data using the CRC-16 MODBUS algorithm\n * @param data The array of data to generate the checksum for\n * @param length The length of the data, excluding any 0 padding\n */\nfunction generateChecksum(data: number[]) {\n const TABLE = new Uint16Array([\n 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601,\n 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0,\n 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81,\n 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941,\n 0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01,\n 0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0,\n 0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081,\n 0x1040, 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,\n 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, 0x3c00,\n 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 0xfa01, 0x3ac0,\n 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 0x2800, 0xe8c1, 0xe981,\n 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2f80, 0xef41,\n 0x2d00, 0xedc1, 0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700,\n 0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0,\n 0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281,\n 0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,\n 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 0xaa01,\n 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1,\n 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7f80,\n 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 0xb401, 0x74c0, 0x7580, 0xb541,\n 0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101,\n 0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0,\n 0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481,\n 0x5440, 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,\n 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 0x8801,\n 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1,\n 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1, 0x8581,\n 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341,\n 0x4100, 0x81c1, 0x8081, 0x4040,\n ]);\n\n let crc = 0xffff;\n for (const dataPoint of data) {\n const xor = (dataPoint ^ crc) & 0xff;\n crc >>= 8;\n crc ^= TABLE[xor];\n }\n\n return crc;\n}\n\n/**\n * Prepares a message to be sent from the app to the cube by adding a checksum,\n * padding the message, and encrypting it with AES-ECB.\n * @param message the message to be sent to the cube, without the checksum\n * @param aesKey AES-ECB encryption key\n * @returns prepared message (including checksum, padding, and encryption)\n */\nasync function prepareMessage(\n message: number[],\n aesKey: CryptoKey,\n): Promise<Uint8Array<ArrayBuffer>> {\n // TODO: this directly inside the `ArrayBugger.`\n const messageCopyForChecksum = structuredClone(message);\n const checksum = generateChecksum(messageCopyForChecksum);\n messageCopyForChecksum.push(checksum & 0xff);\n messageCopyForChecksum.push(checksum >> 8);\n\n const paddedLength = Math.ceil(messageCopyForChecksum.length / 16) * 16;\n const paddedArray = new Uint8Array([\n ...messageCopyForChecksum,\n ...Array(paddedLength - messageCopyForChecksum.length).fill(0),\n ]);\n\n const encryptedMessage = new Uint8Array(paddedLength);\n for (let i = 0; i < paddedArray.length / 16; i++) {\n const encryptedBlock = new Uint8Array(\n await unsafeEncryptBlock(aesKey, paddedArray.slice(i * 16, (i + 1) * 16)),\n );\n encryptedMessage.set(encryptedBlock, i * 16);\n }\n return encryptedMessage;\n}\n\n/**\n * Decrypts a message sent by the cube, using AES-EBC\n * @param encryptedMessage the encryped message sent by the cube\n * @param aesKey AES-EBC encryption key\n * @returns decrypted message\n */\nasync function decryptMessage(\n encryptedMessage: Uint8Array,\n aesKey: CryptoKey,\n): Promise<Uint8Array<ArrayBuffer>> {\n const decryptedMessage = new Uint8Array(encryptedMessage.length);\n for (let i = 0; i < encryptedMessage.length / 16; i++) {\n const decryptedBlock = new Uint8Array(\n await unsafeDecryptBlock(\n aesKey,\n encryptedMessage.slice(i * 16, (i + 1) * 16),\n ),\n );\n decryptedMessage.set(decryptedBlock, i * 16);\n }\n return decryptedMessage;\n}\n\n/**\n * Guess the MAC address of the cube, based on its name.\n *\n * A QiYi smart cube device with the name 'QY-QYSC-S-A94B' has a MAC address of CC:A3:00:00:A9:4B.\n * @param device\n * @returns array of 8-bit integers equal to the MAC address in order\n */\nfunction getMacAddress(device: BluetoothDevice): number[] | undefined {\n if (device.name === undefined) {\n return;\n }\n\n return [\n 0xcc,\n 0xa3,\n 0x00,\n 0x00,\n parseInt(device.name.slice(10, 12), 16),\n parseInt(device.name.slice(12, 14), 16),\n ];\n}\n\n/**\n * Maximum amount of timestamps stored, to limit memory usage, while\n * avoiding performing duplicate moves on the cube. 12 was chosen because\n * there are 55 bytes for previous moves (each one is five bytes), plus\n * one move, stored as the latest one.\n */\nconst MAX_TIMESTAMP_COUNT = 12;\nconst TIMESTAMP_SCALE = 1.6;\n\nconst CUBE_HELLO = 0x02;\nconst STATE_CHANGE = 0x03;\n/** @category Smart Puzzles */\nexport class QiyiCube extends BluetoothPuzzle {\n private latestTimestamp: number | undefined;\n private allTimeStamps: Set<number>; // Without this set, moves are constantly duplicated\n private allTimeStampsQueue: number[];\n private stickers: number[] = [\n 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4,\n 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5,\n 5, 5, 5, 5,\n ];\n private batteryLevel: number = 100;\n\n public static async connect(\n server: BluetoothRemoteGATTServer,\n ): Promise<BluetoothPuzzle> {\n const aesKey = await importKey(\n new Uint8Array([\n 87, 177, 249, 171, 205, 90, 232, 167, 156, 185, 140, 231, 87, 140, 81,\n 8,\n ]),\n );\n return new QiyiCube(await puzzles[\"3x3x3\"].kpuzzle(), aesKey, server);\n }\n\n public constructor(\n private kpuzzle: KPuzzle,\n private aesKey: CryptoKey,\n private server: BluetoothRemoteGATTServer,\n ) {\n super();\n this.startNotifications().then(this.sendAppHello.bind(this));\n this.allTimeStamps = new Set();\n this.allTimeStampsQueue = [];\n }\n\n public async sendAppHello() {\n const mainService = await this.server.getPrimaryService(\n UUIDs.qiyiMainService,\n );\n const mainCharacteristic = await mainService.getCharacteristic(\n UUIDs.qiyiMainCharacteristic,\n );\n\n // Values of `0x00` and `0x01` have been observed for the 4th byte of the\n // MAC in the wild. We send some larger values for future-proofing, as the\n // QiYi cube doesn't seem to mind.\n for (let macGuessCounter = 0; macGuessCounter < 8; macGuessCounter++) {\n const mac = getMacAddress(this.server.device)!;\n mac[3] = macGuessCounter;\n const reversedMac = mac.reverse();\n\n const appHello = [\n 0xfe,\n 0x15,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n ...reversedMac,\n ];\n\n const appHelloMessage = await prepareMessage(appHello, this.aesKey);\n await mainCharacteristic.writeValue(appHelloMessage);\n }\n }\n\n public async startNotifications() {\n const mainService = await this.server.getPrimaryService(\n UUIDs.qiyiMainService,\n );\n const mainCharacteristic = await mainService.getCharacteristic(\n UUIDs.qiyiMainCharacteristic,\n );\n\n mainCharacteristic.addEventListener(\n \"characteristicvaluechanged\",\n this.cubeMessageHandler.bind(this),\n );\n await mainCharacteristic.startNotifications();\n }\n\n public async cubeMessageHandler(event: Event) {\n const characteristic = event.target as BluetoothRemoteGATTCharacteristic;\n const decryptedMessage = await decryptMessage(\n new Uint8Array(characteristic.value!.buffer),\n this.aesKey,\n );\n\n const opCode = decryptedMessage[2];\n let needsAck = false;\n switch (opCode) {\n case CUBE_HELLO: {\n const initialState = decryptedMessage.slice(7, 34);\n this.updateState(initialState);\n this.batteryLevel = decryptedMessage[35];\n needsAck = true;\n break;\n }\n\n case STATE_CHANGE: {\n const state = decryptedMessage.slice(7, 34);\n this.updateState(state);\n\n const latestMove = qiyiMoveToBlockMove[decryptedMessage[34]];\n const latestTimestamp = new DataView(\n decryptedMessage.slice(3, 7).buffer,\n ).getInt32(0);\n\n const moves = [[latestMove, latestTimestamp]];\n\n const previousMoves = new DataView(\n decryptedMessage.slice(36, 91).buffer,\n );\n for (\n let i = previousMoves.byteLength - 1;\n i > 0 && previousMoves.getUint8(i) !== 255;\n i -= 5\n ) {\n const move = qiyiMoveToBlockMove[previousMoves.getUint8(i)];\n const timestamp = previousMoves.getUint32(i - 4);\n\n if (\n this.latestTimestamp === undefined ||\n timestamp <= this.latestTimestamp\n ) {\n continue;\n }\n\n moves.push([move, timestamp]);\n }\n\n moves.sort((a, b) => (a[1] as number) - (b[1] as number));\n\n for (const move of moves) {\n const latestAlgLeaf = move[0] as AlgLeaf;\n const timeStamp = Math.round((move[1] as number) / TIMESTAMP_SCALE);\n if (!this.allTimeStamps.has(timeStamp)) {\n this.dispatchAlgLeaf({\n latestAlgLeaf,\n timeStamp,\n });\n this.allTimeStamps.add(timeStamp);\n this.allTimeStampsQueue.push(timeStamp);\n if (this.allTimeStampsQueue.length > MAX_TIMESTAMP_COUNT) {\n this.allTimeStamps.delete(this.allTimeStampsQueue.shift()!);\n }\n }\n }\n\n this.latestTimestamp = latestTimestamp;\n\n needsAck = decryptedMessage[91] === 1;\n break;\n }\n\n default:\n console.error(`Opcode not implemented: ${opCode}`);\n break;\n }\n\n if (needsAck) {\n await characteristic.writeValue(\n await prepareMessage(\n [0xfe, 0x09, ...decryptedMessage.slice(2, 7)],\n this.aesKey,\n ),\n );\n }\n }\n\n private updateState(state: Uint8Array) {\n this.stickers = Array.from(state).flatMap((twoPieces) => [\n twoPieces & 0xf,\n twoPieces >> 4,\n ]);\n }\n\n public override name(): string | undefined {\n return this.server.device.name;\n }\n\n public override disconnect(): void {\n this.server.disconnect();\n }\n\n public override async getPattern(): Promise<KPattern> {\n return new KPattern(\n this.kpuzzle,\n getPatternData(\n this.stickers,\n faceOrder,\n qiyiEdgeMappings,\n qiyiCornerMappings,\n ),\n );\n }\n\n public getBattery(): number {\n return this.batteryLevel;\n }\n}\n\nexport const qiyiConfig: BluetoothConfig<BluetoothPuzzle> = {\n connect: QiyiCube.connect.bind(QiyiCube),\n prefixes: [\"QY-QYSC\"],\n filters: [\n {\n namePrefix: \"QY-QYSC\",\n },\n ],\n optionalServices: [UUIDs.qiyiMainService],\n};\n", "import { type BluetoothConnectOptions, bluetoothConnect } from \"../connect\";\nimport type { BluetoothPuzzle } from \"./bluetooth-puzzle\";\nimport { ganConfig } from \"./gan\";\nimport { giiKERConfig } from \"./giiker\";\nimport { goCubeConfig } from \"./gocube\";\nimport { heykubeConfig } from \"./Heykube\";\nimport { qiyiConfig } from \"./qiyi\";\n\nconst smartPuzzleConfigs = [\n ganConfig,\n goCubeConfig,\n heykubeConfig,\n qiyiConfig,\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, Move as AlgNode, 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 throwInvalidAlgNode(algNode: AlgNode): never {\n console.error(\"invalid alg node\", algNode, algNode.toString());\n throw new Error(\"invalid alg node!\");\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 algNodeToNibble(algNode: AlgNode): number {\n const move = algNode.as(AlgNode);\n if (!move) {\n throwInvalidAlgNode(algNode);\n }\n const nibble =\n (this.experimentalOptions.xAngle ? moveMapX : moveMap)[move.toString()] ??\n null;\n if (nibble === null) {\n throwInvalidAlgNode(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 // @ts-expect-error: Is TypeScript just straight-up false positiving here?\n let algNodes: AlgNode[] = 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) {\n if (move.amount === 2) {\n algNodes = [\n move.modified({ amount: 1 }) as AlgNode,\n move.modified({ amount: 1 }) as AlgNode,\n ];\n } else {\n algNodes = [\n move.modified({ amount: -move.amount }),\n move.modified({ amount: 2 }) as AlgNode,\n ];\n }\n }\n }\n const splicedAlgNodes: AlgNode[] = algNodes.splice(\n 0,\n MAX_NIBBLES_PER_WRITE,\n );\n const nibbles: number[] = splicedAlgNodes.map(\n this.algNodeToNibble.bind(this),\n );\n const sending = new Alg(splicedAlgNodes);\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<AlgNode>): 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 { type BluetoothConnectOptions, bluetoothConnect } from \"../connect\";\nimport type { BluetoothConfig } from \"../smart-puzzle/bluetooth-puzzle\";\nimport { type GanRobot, ganTimerConfig } 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 { type BluetoothConnectOptions, bluetoothConnect } from \"../connect\";\nimport type { BluetoothConfig } from \"../smart-puzzle/bluetooth-puzzle\";\nimport { type GanTimer, ganTimerConfig } 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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A,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;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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 } from \"three/src/math/Quaternion.js\";\nimport { Vector3 } from \"three/src/math/Vector3.js\";\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 | ((\n server: BluetoothRemoteGATTServer,\n device: BluetoothDevice,\n ) => Promise<T>)\n | ((\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 { KPattern } from \"../kpuzzle/KPattern\";\nimport type { PuzzleLoader } from \"../puzzles\";\nimport type { KeyMapping } from \"../puzzles/cubing-private\";\nimport type { PuzzleID } from \"../twisty\";\nimport { BluetoothPuzzle } from \"./smart-puzzle/bluetooth-puzzle\";\n\n/** @category Keyboard Puzzles */\nexport class KeyboardPuzzle extends BluetoothPuzzle {\n private keyMappingAndPatternPromise: Promise<\n [KeyMapping | undefined, KPattern]\n >;\n\n listener: EventListener; // (e: KeyboardEvent) => Promise<void>;\n\n // TODO: Decide on the right arguments.\n // TODO: support tying the puzzle to a TwistyPlayer.\n constructor(\n private target: Element,\n puzzle: PuzzleID | PuzzleLoader = \"3x3x3\",\n ) {\n super();\n // TODO: Filter out repeated keydown?\n // TODO: how do we avoid this awkward cast?\n this.listener = this.onKeyDown.bind(this) as any as EventListener;\n target.addEventListener(\"keydown\", this.listener);\n this.keyMappingAndPatternPromise = this.setPuzzleInternal(puzzle);\n }\n\n public name(): string | undefined {\n return \"Keyboard Input\";\n }\n\n async setPuzzleInternal(\n puzzle: PuzzleID | PuzzleLoader,\n ): Promise<[KeyMapping | undefined, KPattern]> {\n const puzzleLoader = await (async () =>\n typeof puzzle === \"string\"\n ? (await import(\"../puzzles\")).puzzles[puzzle]\n : puzzle)();\n const kpuzzle = await (async () => puzzleLoader.kpuzzle())();\n return Promise.all([puzzleLoader.keyMapping?.(), kpuzzle.defaultPattern()]);\n }\n\n disconnect() {\n this.target.removeEventListener(\"keydown\", this.listener as EventListener);\n }\n\n public override async getPattern(): Promise<KPattern> {\n return (await this.keyMappingAndPatternPromise)[1];\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 this.keyMappingAndPatternPromise = (async () => {\n const [keyMapping, pattern] = await this.keyMappingAndPatternPromise;\n const algLeaf = keyToMove(keyMapping, e);\n let newPattern: KPattern | undefined;\n if (algLeaf) {\n newPattern = pattern.applyAlg(new Alg([algLeaf])); // TODO\n this.dispatchAlgLeaf({\n latestAlgLeaf: algLeaf,\n timeStamp: e.timeStamp,\n pattern: newPattern,\n });\n e.preventDefault();\n }\n return [keyMapping, newPattern ?? pattern];\n })();\n }\n}\n\n// TODO: Type\n/** @category Keyboard Puzzles */\nexport async function debugKeyboardConnect(\n target: any = window,\n puzzle: PuzzleID | PuzzleLoader = \"3x3x3\",\n): Promise<KeyboardPuzzle> {\n return new KeyboardPuzzle(target, puzzle);\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 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/src/math/Quaternion.js\";\nimport { Move } from \"../../alg\";\nimport { KPattern, type KPuzzle } 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\";\nimport { getPatternData } from \"./common\";\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: ArrayBufferLike): 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 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:\n | Promise<BluetoothRemoteGATTCharacteristic>\n | undefined;\n\n private cachedFaceletStatus2Characteristic:\n | Promise<BluetoothRemoteGATTCharacteristic>\n | undefined;\n\n private cachedActualAngleAndBatteryCharacteristic:\n | Promise<BluetoothRemoteGATTCharacteristic>\n | undefined;\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 return new KPattern(\n this.kpuzzle,\n getPatternData(\n stickers,\n faceOrder,\n gan356iEdgeMappings,\n gan356iCornerMappings,\n ),\n );\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<ArrayBufferLike> {\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<ArrayBufferLike> {\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 smart 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: BufferSource | Uint8Array,\n): Promise<CryptoKey> {\n return await crypto.subtle.importKey(\n \"raw\",\n keyBytes as BufferSource,\n AES_CBC,\n true,\n [\"encrypt\", \"decrypt\"],\n );\n}\n\nasync function unsafeEncryptBlockWithIV(\n key: CryptoKey,\n plaintextBlock: BufferSource | Uint8Array,\n iv: BufferSource | Uint8Array,\n): Promise<ArrayBuffer> {\n const cryptoResult: ArrayBuffer = await window.crypto.subtle.encrypt(\n {\n name: AES_CBC,\n iv: iv as BufferSource,\n },\n key,\n plaintextBlock as BufferSource,\n );\n return cryptoResult.slice(0, blockSize);\n}\n\nexport async function unsafeEncryptBlock(\n key: CryptoKey,\n plaintextBlock: BufferSource | 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: BufferSource | Uint8Array,\n): Promise<ArrayBuffer> {\n const paddingBlock = await unsafeEncryptBlockWithIV(\n key,\n paddingBlockPlaintext,\n ciphertextBlock as BufferSource,\n );\n\n const cbcCiphertext = new Uint8Array(2 * blockSize);\n cbcCiphertext.set(new Uint8Array(ciphertextBlock as Uint8Array), 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", "import type { KPatternData } from \"../../kpuzzle\";\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\nexport function getPatternData(\n stickers: number[],\n faceOrder: string,\n edgeMappings: number[][],\n cornerMappings: number[][],\n): KPatternData {\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],\n },\n };\n\n for (const cornerMapping of cornerMappings) {\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 edgeMappings) {\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 patternData;\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 { type BluetoothConfig, BluetoothPuzzle } 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] =\n 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/src/math/Quaternion.js\";\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<ArrayBuffer> = 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", "/* tslint:disable no-bitwise */\n\nimport { type AlgLeaf, Move } from \"../../alg\";\nimport { KPattern, type KPuzzle } from \"../../kpuzzle\";\nimport { puzzles } from \"../../puzzles\";\nimport {\n importKey,\n unsafeDecryptBlock,\n unsafeEncryptBlock,\n} from \"../../vendor/public-domain/unsafe-raw-aes/unsafe-raw-aes\";\nimport { type BluetoothConfig, BluetoothPuzzle } from \"./bluetooth-puzzle\";\nimport { getPatternData } from \"./common\";\n\nconst UUIDs = {\n qiyiMainService: 0xfff0,\n qiyiMainCharacteristic: 0xfff6,\n};\n\nconst qiyiMoveToBlockMove: { [i: number]: Move } = {\n 1: new Move(\"L\", -1),\n 2: new Move(\"L\"),\n 3: new Move(\"R\", -1),\n 4: new Move(\"R\"),\n 5: new Move(\"D\", -1),\n 6: new Move(\"D\"),\n 7: new Move(\"U\", -1),\n 8: new Move(\"U\"),\n 9: new Move(\"F\", -1),\n 10: new Move(\"F\"),\n 11: new Move(\"B\", -1),\n 12: new Move(\"B\"),\n};\n\nconst faceOrder = \"LRDUFB\";\n\n// \u250C\u2500\u2500\u252C\u2500\u2500\u252C\u2500\u2500\u2510\n// \u250200\u250201\u250202\u2502\n// \u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\n// \u250203\u250204\u250205\u2502\n// \u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\n// \u250206\u250207\u250208\u2502\n// \u2514\u2500\u2500\u2534\u2500\u2500\u2534\u2500\u2500\u2518\n// \u250C\u2500\u2500\u252C\u2500\u2500\u252C\u2500\u2500\u2510\u250C\u2500\u2500\u252C\u2500\u2500\u252C\u2500\u2500\u2510\u250C\u2500\u2500\u252C\u2500\u2500\u252C\u2500\u2500\u2510\u250C\u2500\u2500\u252C\u2500\u2500\u252C\u2500\u2500\u2510\n// \u250236\u250237\u250238\u2502\u250218\u250219\u250220\u2502\u250209\u250210\u250211\u2502\u250245\u250246\u250247\u2502\n// \u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\n// \u250239\u250240\u250241\u2502\u250221\u250222\u250223\u2502\u250212\u250213\u250214\u2502\u250248\u250249\u250250\u2502\n// \u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\n// \u250242\u250243\u250244\u2502\u250224\u250225\u250226\u2502\u250215\u250216\u250217\u2502\u250251\u250252\u250253\u2502\n// \u2514\u2500\u2500\u2534\u2500\u2500\u2534\u2500\u2500\u2518\u2514\u2500\u2500\u2534\u2500\u2500\u2534\u2500\u2500\u2518\u2514\u2500\u2500\u2534\u2500\u2500\u2534\u2500\u2500\u2518\u2514\u2500\u2500\u2534\u2500\u2500\u2534\u2500\u2500\u2518\n// \u250C\u2500\u2500\u252C\u2500\u2500\u252C\u2500\u2500\u2510\n// \u250227\u250228\u250229\u2502\n// \u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\n// \u250230\u250231\u250232\u2502\n// \u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524\n// \u250233\u250234\u250235\u2502\n// \u2514\u2500\u2500\u2534\u2500\u2500\u2534\u2500\u2500\u2518\n\nconst qiyiCornerMappings: number[][] = [\n [8, 20, 9], // UFR,\n [2, 11, 45], // URB,\n [0, 47, 36], // UBL,\n [6, 38, 18], // ULF,\n [29, 15, 26], // DRF,\n [27, 24, 44], // DFL,\n [33, 42, 53], // DLB,\n [35, 51, 17], // DBR,\n];\n\nconst qiyiEdgeMappings: number[][] = [\n [7, 19], // UF,\n [5, 10], // UR,\n [1, 46], // UB,\n [3, 37], // UL,\n [28, 25], // DF,\n [32, 16], // DR,\n [34, 52], // DB,\n [30, 43], // DL,\n [23, 12], // FR,\n [21, 41], // FL,\n [48, 14], // BR,\n [50, 39], // BL,\n];\n\n/**\n * Generates the checksum of the data using the CRC-16 MODBUS algorithm\n * @param data The array of data to generate the checksum for\n * @param length The length of the data, excluding any 0 padding\n */\nfunction generateChecksum(data: number[]) {\n const TABLE = new Uint16Array([\n 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601,\n 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0,\n 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81,\n 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941,\n 0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01,\n 0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0,\n 0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081,\n 0x1040, 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,\n 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, 0x3c00,\n 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 0xfa01, 0x3ac0,\n 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 0x2800, 0xe8c1, 0xe981,\n 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2f80, 0xef41,\n 0x2d00, 0xedc1, 0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700,\n 0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0,\n 0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281,\n 0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,\n 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 0xaa01,\n 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1,\n 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7f80,\n 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 0xb401, 0x74c0, 0x7580, 0xb541,\n 0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101,\n 0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0,\n 0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481,\n 0x5440, 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,\n 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 0x8801,\n 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1,\n 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1, 0x8581,\n 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341,\n 0x4100, 0x81c1, 0x8081, 0x4040,\n ]);\n\n let crc = 0xffff;\n for (const dataPoint of data) {\n const xor = (dataPoint ^ crc) & 0xff;\n crc >>= 8;\n crc ^= TABLE[xor];\n }\n\n return crc;\n}\n\n/**\n * Prepares a message to be sent from the app to the cube by adding a checksum,\n * padding the message, and encrypting it with AES-ECB.\n * @param message the message to be sent to the cube, without the checksum\n * @param aesKey AES-ECB encryption key\n * @returns prepared message (including checksum, padding, and encryption)\n */\nasync function prepareMessage(\n message: number[],\n aesKey: CryptoKey,\n): Promise<Uint8Array<ArrayBuffer>> {\n // TODO: this directly inside the `ArrayBugger.`\n const messageCopyForChecksum = structuredClone(message);\n const checksum = generateChecksum(messageCopyForChecksum);\n messageCopyForChecksum.push(checksum & 0xff);\n messageCopyForChecksum.push(checksum >> 8);\n\n const paddedLength = Math.ceil(messageCopyForChecksum.length / 16) * 16;\n const paddedArray = new Uint8Array([\n ...messageCopyForChecksum,\n ...Array(paddedLength - messageCopyForChecksum.length).fill(0),\n ]);\n\n const encryptedMessage = new Uint8Array(paddedLength);\n for (let i = 0; i < paddedArray.length / 16; i++) {\n const encryptedBlock = new Uint8Array(\n await unsafeEncryptBlock(aesKey, paddedArray.slice(i * 16, (i + 1) * 16)),\n );\n encryptedMessage.set(encryptedBlock, i * 16);\n }\n return encryptedMessage;\n}\n\n/**\n * Decrypts a message sent by the cube, using AES-EBC\n * @param encryptedMessage the encryped message sent by the cube\n * @param aesKey AES-EBC encryption key\n * @returns decrypted message\n */\nasync function decryptMessage(\n encryptedMessage: Uint8Array,\n aesKey: CryptoKey,\n): Promise<Uint8Array<ArrayBuffer>> {\n const decryptedMessage = new Uint8Array(encryptedMessage.length);\n for (let i = 0; i < encryptedMessage.length / 16; i++) {\n const decryptedBlock = new Uint8Array(\n await unsafeDecryptBlock(\n aesKey,\n encryptedMessage.slice(i * 16, (i + 1) * 16),\n ),\n );\n decryptedMessage.set(decryptedBlock, i * 16);\n }\n return decryptedMessage;\n}\n\n/**\n * Guess the MAC address of the cube, based on its name.\n *\n * A QiYi smart cube device with the name 'QY-QYSC-S-A94B' has a MAC address of CC:A3:00:00:A9:4B.\n * @param device\n * @returns array of 8-bit integers equal to the MAC address in order\n */\nfunction getMacAddress(device: BluetoothDevice): number[] | undefined {\n if (device.name === undefined) {\n return;\n }\n\n return [\n 0xcc,\n 0xa3,\n 0x00,\n 0x00,\n parseInt(device.name.slice(10, 12), 16),\n parseInt(device.name.slice(12, 14), 16),\n ];\n}\n\n/**\n * Maximum amount of timestamps stored, to limit memory usage, while\n * avoiding performing duplicate moves on the cube. 12 was chosen because\n * there are 55 bytes for previous moves (each one is five bytes), plus\n * one move, stored as the latest one.\n */\nconst MAX_TIMESTAMP_COUNT = 12;\nconst TIMESTAMP_SCALE = 1.6;\n\nconst CUBE_HELLO = 0x02;\nconst STATE_CHANGE = 0x03;\n/** @category Smart Puzzles */\nexport class QiyiCube extends BluetoothPuzzle {\n private latestTimestamp: number | undefined;\n private allTimeStamps: Set<number>; // Without this set, moves are constantly duplicated\n private allTimeStampsQueue: number[];\n private stickers: number[] = [\n 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4,\n 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5,\n 5, 5, 5, 5,\n ];\n private batteryLevel: number = 100;\n\n public static async connect(\n server: BluetoothRemoteGATTServer,\n ): Promise<BluetoothPuzzle> {\n const aesKey = await importKey(\n new Uint8Array([\n 87, 177, 249, 171, 205, 90, 232, 167, 156, 185, 140, 231, 87, 140, 81,\n 8,\n ]),\n );\n return new QiyiCube(await puzzles[\"3x3x3\"].kpuzzle(), aesKey, server);\n }\n\n public constructor(\n private kpuzzle: KPuzzle,\n private aesKey: CryptoKey,\n private server: BluetoothRemoteGATTServer,\n ) {\n super();\n this.startNotifications().then(this.sendAppHello.bind(this));\n this.allTimeStamps = new Set();\n this.allTimeStampsQueue = [];\n }\n\n public async sendAppHello() {\n const mainService = await this.server.getPrimaryService(\n UUIDs.qiyiMainService,\n );\n const mainCharacteristic = await mainService.getCharacteristic(\n UUIDs.qiyiMainCharacteristic,\n );\n\n // Values of `0x00` and `0x01` have been observed for the 4th byte of the\n // MAC in the wild. We send some larger values for future-proofing, as the\n // QiYi cube doesn't seem to mind.\n for (let macGuessCounter = 0; macGuessCounter < 8; macGuessCounter++) {\n const mac = getMacAddress(this.server.device)!;\n mac[3] = macGuessCounter;\n const reversedMac = mac.reverse();\n\n const appHello = [\n 0xfe,\n 0x15,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n ...reversedMac,\n ];\n\n const appHelloMessage = await prepareMessage(appHello, this.aesKey);\n await mainCharacteristic.writeValue(appHelloMessage);\n }\n }\n\n public async startNotifications() {\n const mainService = await this.server.getPrimaryService(\n UUIDs.qiyiMainService,\n );\n const mainCharacteristic = await mainService.getCharacteristic(\n UUIDs.qiyiMainCharacteristic,\n );\n\n mainCharacteristic.addEventListener(\n \"characteristicvaluechanged\",\n this.cubeMessageHandler.bind(this),\n );\n await mainCharacteristic.startNotifications();\n }\n\n public async cubeMessageHandler(event: Event) {\n const characteristic = event.target as BluetoothRemoteGATTCharacteristic;\n const decryptedMessage = await decryptMessage(\n new Uint8Array(characteristic.value!.buffer),\n this.aesKey,\n );\n\n const opCode = decryptedMessage[2];\n let needsAck = false;\n switch (opCode) {\n case CUBE_HELLO: {\n const initialState = decryptedMessage.slice(7, 34);\n this.updateState(initialState);\n this.batteryLevel = decryptedMessage[35];\n needsAck = true;\n break;\n }\n\n case STATE_CHANGE: {\n const state = decryptedMessage.slice(7, 34);\n this.updateState(state);\n\n const latestMove = qiyiMoveToBlockMove[decryptedMessage[34]];\n const latestTimestamp = new DataView(\n decryptedMessage.slice(3, 7).buffer,\n ).getInt32(0);\n\n const moves = [[latestMove, latestTimestamp]];\n\n const previousMoves = new DataView(\n decryptedMessage.slice(36, 91).buffer,\n );\n for (\n let i = previousMoves.byteLength - 1;\n i > 0 && previousMoves.getUint8(i) !== 255;\n i -= 5\n ) {\n const move = qiyiMoveToBlockMove[previousMoves.getUint8(i)];\n const timestamp = previousMoves.getUint32(i - 4);\n\n if (\n this.latestTimestamp === undefined ||\n timestamp <= this.latestTimestamp\n ) {\n continue;\n }\n\n moves.push([move, timestamp]);\n }\n\n moves.sort((a, b) => (a[1] as number) - (b[1] as number));\n\n for (const move of moves) {\n const latestAlgLeaf = move[0] as AlgLeaf;\n const timeStamp = Math.round((move[1] as number) / TIMESTAMP_SCALE);\n if (!this.allTimeStamps.has(timeStamp)) {\n this.dispatchAlgLeaf({\n latestAlgLeaf,\n timeStamp,\n });\n this.allTimeStamps.add(timeStamp);\n this.allTimeStampsQueue.push(timeStamp);\n if (this.allTimeStampsQueue.length > MAX_TIMESTAMP_COUNT) {\n this.allTimeStamps.delete(this.allTimeStampsQueue.shift()!);\n }\n }\n }\n\n this.latestTimestamp = latestTimestamp;\n\n needsAck = decryptedMessage[91] === 1;\n break;\n }\n\n default:\n console.error(`Opcode not implemented: ${opCode}`);\n break;\n }\n\n if (needsAck) {\n await characteristic.writeValue(\n await prepareMessage(\n [0xfe, 0x09, ...decryptedMessage.slice(2, 7)],\n this.aesKey,\n ),\n );\n }\n }\n\n private updateState(state: Uint8Array) {\n this.stickers = Array.from(state).flatMap((twoPieces) => [\n twoPieces & 0xf,\n twoPieces >> 4,\n ]);\n }\n\n public override name(): string | undefined {\n return this.server.device.name;\n }\n\n public override disconnect(): void {\n this.server.disconnect();\n }\n\n public override async getPattern(): Promise<KPattern> {\n return new KPattern(\n this.kpuzzle,\n getPatternData(\n this.stickers,\n faceOrder,\n qiyiEdgeMappings,\n qiyiCornerMappings,\n ),\n );\n }\n\n public getBattery(): number {\n return this.batteryLevel;\n }\n}\n\nexport const qiyiConfig: BluetoothConfig<BluetoothPuzzle> = {\n connect: QiyiCube.connect.bind(QiyiCube),\n prefixes: [\"QY-QYSC\"],\n filters: [\n {\n namePrefix: \"QY-QYSC\",\n },\n ],\n optionalServices: [UUIDs.qiyiMainService],\n};\n", "import { type BluetoothConnectOptions, bluetoothConnect } from \"../connect\";\nimport type { BluetoothPuzzle } from \"./bluetooth-puzzle\";\nimport { ganConfig } from \"./gan\";\nimport { giiKERConfig } from \"./giiker\";\nimport { goCubeConfig } from \"./gocube\";\nimport { heykubeConfig } from \"./Heykube\";\nimport { qiyiConfig } from \"./qiyi\";\n\nconst smartPuzzleConfigs = [\n ganConfig,\n goCubeConfig,\n heykubeConfig,\n qiyiConfig,\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, Move as AlgNode, 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 throwInvalidAlgNode(algNode: AlgNode): never {\n console.error(\"invalid alg node\", algNode, algNode.toString());\n throw new Error(\"invalid alg node!\");\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 algNodeToNibble(algNode: AlgNode): number {\n const move = algNode.as(AlgNode);\n if (!move) {\n throwInvalidAlgNode(algNode);\n }\n const nibble =\n (this.experimentalOptions.xAngle ? moveMapX : moveMap)[move.toString()] ??\n null;\n if (nibble === null) {\n throwInvalidAlgNode(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 // @ts-expect-error: Is TypeScript just straight-up false positiving here?\n let algNodes: AlgNode[] = 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) {\n if (move.amount === 2) {\n algNodes = [\n move.modified({ amount: 1 }) as AlgNode,\n move.modified({ amount: 1 }) as AlgNode,\n ];\n } else {\n algNodes = [\n move.modified({ amount: -move.amount }),\n move.modified({ amount: 2 }) as AlgNode,\n ];\n }\n }\n }\n const splicedAlgNodes: AlgNode[] = algNodes.splice(\n 0,\n MAX_NIBBLES_PER_WRITE,\n );\n const nibbles: number[] = splicedAlgNodes.map(\n this.algNodeToNibble.bind(this),\n );\n const sending = new Alg(splicedAlgNodes);\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<AlgNode>): 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 { type BluetoothConnectOptions, bluetoothConnect } from \"../connect\";\nimport type { BluetoothConfig } from \"../smart-puzzle/bluetooth-puzzle\";\nimport { type GanRobot, ganTimerConfig } 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): MillisecondTimestamp {\n return ((bytes[0] * 60 + bytes[1]) * 1000 +\n bytes[2] +\n bytes[3] * 256) as MillisecondTimestamp;\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 { type BluetoothConnectOptions, bluetoothConnect } from \"../connect\";\nimport type { BluetoothConfig } from \"../smart-puzzle/bluetooth-puzzle\";\nimport { type GanTimer, ganTimerConfig } 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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A,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChE;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;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",
6
6
  "names": ["Quaternion", "faceOrder", "Quaternion", "UUIDs", "UUIDs", "Quaternion", "UUIDs", "buf2hex", "Quaternion", "UUIDs", "UUIDs", "faceOrder", "buf2hex", "UUIDs", "moveMap", "i", "UUIDs", "ganTimerConfig", "ganTimerConfig"]
7
7
  }