@wodzik/cubecore 0.1.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.
- package/LICENSE +373 -0
- package/README.md +118 -0
- package/analyze/client.d.ts +18 -0
- package/analyze/client.js +42 -0
- package/analyze/index.d.ts +114 -0
- package/analyze/index.js +151 -0
- package/analyze/rotations.d.ts +3 -0
- package/analyze/rotations.js +15 -0
- package/analyze/roux.d.ts +67 -0
- package/analyze/roux.js +95 -0
- package/analyze/worker.d.ts +6 -0
- package/analyze/worker.js +31 -0
- package/analyze/zz.d.ts +47 -0
- package/analyze/zz.js +102 -0
- package/bld/index.d.ts +14 -0
- package/bld/index.js +14 -0
- package/bld/memo.d.ts +66 -0
- package/bld/memo.js +139 -0
- package/bld/scheme.d.ts +30 -0
- package/bld/scheme.js +35 -0
- package/bld/skin.d.ts +26 -0
- package/bld/skin.js +46 -0
- package/bld/tracker.d.ts +68 -0
- package/bld/tracker.js +145 -0
- package/bluetooth/clock.d.ts +22 -0
- package/bluetooth/clock.js +37 -0
- package/bluetooth/cubeSkins.d.ts +31 -0
- package/bluetooth/cubeSkins.js +32 -0
- package/bluetooth/gyro.d.ts +31 -0
- package/bluetooth/gyro.js +46 -0
- package/bluetooth/index.d.ts +5 -0
- package/bluetooth/index.js +5 -0
- package/bluetooth/session.d.ts +140 -0
- package/bluetooth/session.js +201 -0
- package/bluetooth/simulated.d.ts +52 -0
- package/bluetooth/simulated.js +80 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-cube-definitions.d.ts +38 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-cube-definitions.js +51 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-cube-encrypter.d.ts +35 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-cube-encrypter.js +70 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-cube-protocol.d.ts +273 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-cube-protocol.js +846 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-gen1.d.ts +38 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-gen1.js +340 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-gen234-packet-validate.d.ts +11 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-gen234-packet-validate.js +118 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-mac-salt.d.ts +2 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-mac-salt.js +15 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-smart-cube.d.ts +18 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-smart-cube.js +152 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-smart-timer.d.ts +74 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-smart-timer.js +161 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-write-queue.d.ts +7 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-write-queue.js +11 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gatt-characteristic-write.d.ts +2 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gatt-characteristic-write.js +36 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/index.d.ts +4 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/index.js +4 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/address-hints.d.ts +12 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/address-hints.js +122 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/build-picker-options.d.ts +11 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/build-picker-options.js +55 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/default-optional-services.d.ts +21 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/default-optional-services.js +47 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/device-name-scan-filters.d.ts +6 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/device-name-scan-filters.js +24 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/gatt-snapshot.d.ts +6 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/gatt-snapshot.js +57 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/mac-candidates.d.ts +11 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/mac-candidates.js +67 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/mac-probe-moyu32.d.ts +8 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/mac-probe-moyu32.js +98 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/mac-probe-qiyi.d.ts +8 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/mac-probe-qiyi.js +128 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/moyu32-session-crypto.d.ts +5 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/moyu32-session-crypto.js +60 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/normalize-uuid.d.ts +2 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/normalize-uuid.js +8 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/packet-sanity.d.ts +7 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/packet-sanity.js +142 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/profile-rank.d.ts +6 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/profile-rank.js +21 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/types.d.ts +32 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/types.js +1 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/ble-utils.d.ts +6 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/ble-utils.js +68 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/connect.d.ts +3 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/connect.js +178 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/cubie-cube.d.ts +16 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/cubie-cube.js +141 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/index.d.ts +11 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/index.js +10 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocol.d.ts +26 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocol.js +8 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/gan.d.ts +3 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/gan.js +265 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/giiker.d.ts +3 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/giiker.js +345 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/gocube.d.ts +15 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/gocube.js +382 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/moyu-mhc.d.ts +3 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/moyu-mhc.js +352 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/moyu-v1.d.ts +57 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/moyu-v1.js +243 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/moyu32.d.ts +3 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/moyu32.js +454 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/qiyi.d.ts +3 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/qiyi.js +424 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/types.d.ts +78 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/types.js +1 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/utils.d.ts +45 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/utils.js +150 -0
- package/cfop/caseData.d.ts +16 -0
- package/cfop/caseData.js +88 -0
- package/cfop/cases.d.ts +42 -0
- package/cfop/cases.js +116 -0
- package/cfop/f2l.d.ts +28 -0
- package/cfop/f2l.js +88 -0
- package/cfop/f2lData.d.ts +15 -0
- package/cfop/f2lData.js +49 -0
- package/cfop/index.d.ts +41 -0
- package/cfop/index.js +110 -0
- package/cfop/slots.d.ts +2 -0
- package/cfop/slots.js +1 -0
- package/core/arrows.d.ts +24 -0
- package/core/arrows.js +22 -0
- package/core/bytes.d.ts +27 -0
- package/core/bytes.js +145 -0
- package/core/centers.d.ts +32 -0
- package/core/centers.js +83 -0
- package/core/checks.d.ts +53 -0
- package/core/checks.js +85 -0
- package/core/cubies.d.ts +45 -0
- package/core/cubies.js +169 -0
- package/core/frames.d.ts +61 -0
- package/core/frames.js +126 -0
- package/core/geometry.d.ts +58 -0
- package/core/geometry.js +132 -0
- package/core/index.d.ts +19 -0
- package/core/index.js +19 -0
- package/core/masks.d.ts +32 -0
- package/core/masks.js +39 -0
- package/core/method.d.ts +35 -0
- package/core/method.js +30 -0
- package/core/moves.d.ts +48 -0
- package/core/moves.js +88 -0
- package/core/notation.d.ts +48 -0
- package/core/notation.js +226 -0
- package/core/physical.d.ts +53 -0
- package/core/physical.js +99 -0
- package/core/practice.d.ts +62 -0
- package/core/practice.js +87 -0
- package/core/sequence.d.ts +90 -0
- package/core/sequence.js +157 -0
- package/core/stages.d.ts +90 -0
- package/core/stages.js +21 -0
- package/core/state.d.ts +55 -0
- package/core/state.js +140 -0
- package/core/stateCodec.d.ts +12 -0
- package/core/stateCodec.js +51 -0
- package/core/stream.d.ts +45 -0
- package/core/stream.js +75 -0
- package/core/tracker.d.ts +62 -0
- package/core/tracker.js +121 -0
- package/element/alg.d.ts +45 -0
- package/element/alg.js +150 -0
- package/element/base.d.ts +2 -0
- package/element/base.js +3 -0
- package/element/bld.d.ts +82 -0
- package/element/bld.js +222 -0
- package/element/index.d.ts +8 -0
- package/element/index.js +21 -0
- package/element/model.d.ts +36 -0
- package/element/model.js +64 -0
- package/element/player.d.ts +196 -0
- package/element/player.js +680 -0
- package/element/practice.d.ts +75 -0
- package/element/practice.js +150 -0
- package/element/scramble.d.ts +50 -0
- package/element/scramble.js +107 -0
- package/element/sequence.d.ts +126 -0
- package/element/sequence.js +254 -0
- package/element/styles.d.ts +32 -0
- package/element/styles.js +196 -0
- package/image/cache.d.ts +21 -0
- package/image/cache.js +66 -0
- package/image/index.d.ts +2 -0
- package/image/index.js +2 -0
- package/image/png-node.d.ts +6 -0
- package/image/png-node.js +10 -0
- package/image/svg.d.ts +36 -0
- package/image/svg.js +215 -0
- package/lbl/index.d.ts +10 -0
- package/lbl/index.js +31 -0
- package/methods/index.d.ts +20 -0
- package/methods/index.js +33 -0
- package/package.json +133 -0
- package/petrus/index.d.ts +11 -0
- package/petrus/index.js +27 -0
- package/react/index.d.ts +176 -0
- package/react/index.js +228 -0
- package/render/arrows.d.ts +68 -0
- package/render/arrows.js +190 -0
- package/render/build/attachments.d.ts +35 -0
- package/render/build/attachments.js +94 -0
- package/render/build/models.d.ts +9 -0
- package/render/build/models.js +27 -0
- package/render/build/tiles.d.ts +48 -0
- package/render/build/tiles.js +194 -0
- package/render/gltf.d.ts +10 -0
- package/render/gltf.js +106 -0
- package/render/index.d.ts +12 -0
- package/render/index.js +12 -0
- package/render/layers.d.ts +21 -0
- package/render/layers.js +24 -0
- package/render/pictures.d.ts +46 -0
- package/render/pictures.js +80 -0
- package/render/pieceModels.d.ts +38 -0
- package/render/pieceModels.js +43 -0
- package/render/renderer.d.ts +165 -0
- package/render/renderer.js +647 -0
- package/render/tile.d.ts +114 -0
- package/render/tile.js +390 -0
- package/render/viewports.d.ts +25 -0
- package/render/viewports.js +26 -0
- package/roux/cmll.d.ts +35 -0
- package/roux/cmll.js +121 -0
- package/roux/cmllData.d.ts +12 -0
- package/roux/cmllData.js +49 -0
- package/roux/index.d.ts +52 -0
- package/roux/index.js +175 -0
- package/skin/attachments.d.ts +82 -0
- package/skin/attachments.js +110 -0
- package/skin/index.d.ts +3 -0
- package/skin/index.js +3 -0
- package/skin/shapes.d.ts +112 -0
- package/skin/shapes.js +147 -0
- package/skin/skin.d.ts +911 -0
- package/skin/skin.js +412 -0
- package/solve/client.d.ts +58 -0
- package/solve/client.js +56 -0
- package/solve/handle.d.ts +6 -0
- package/solve/handle.js +38 -0
- package/solve/index.d.ts +8 -0
- package/solve/index.js +7 -0
- package/solve/lse.d.ts +42 -0
- package/solve/lse.js +151 -0
- package/solve/pieces.d.ts +18 -0
- package/solve/pieces.js +24 -0
- package/solve/protocol.d.ts +70 -0
- package/solve/protocol.js +16 -0
- package/solve/scramble.d.ts +76 -0
- package/solve/scramble.js +187 -0
- package/solve/stage.d.ts +108 -0
- package/solve/stage.js +532 -0
- package/solve/twophase.d.ts +36 -0
- package/solve/twophase.js +229 -0
- package/solve/worker.d.ts +6 -0
- package/solve/worker.js +15 -0
- package/timeline/codec.d.ts +23 -0
- package/timeline/codec.js +84 -0
- package/timeline/index.d.ts +7 -0
- package/timeline/index.js +7 -0
- package/timeline/recording.d.ts +19 -0
- package/timeline/recording.js +20 -0
- package/timeline/replay.d.ts +68 -0
- package/timeline/replay.js +145 -0
- package/timeline/segments.d.ts +31 -0
- package/timeline/segments.js +39 -0
- package/timeline/share.d.ts +30 -0
- package/timeline/share.js +62 -0
- package/timeline/stats.d.ts +34 -0
- package/timeline/stats.js +56 -0
- package/timeline/timings.d.ts +30 -0
- package/timeline/timings.js +54 -0
- package/zz/index.d.ts +29 -0
- package/zz/index.js +68 -0
- package/zz/seeds.d.ts +9 -0
- package/zz/seeds.js +29 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { ModeOfOperation } from 'aes-js';
|
|
2
|
+
/**
|
|
3
|
+
* Implementation for encryption scheme used in the GAN Gen2 Smart Cubes
|
|
4
|
+
*/
|
|
5
|
+
class GanGen2CubeEncrypter {
|
|
6
|
+
_key;
|
|
7
|
+
_iv;
|
|
8
|
+
constructor(key, iv, salt) {
|
|
9
|
+
if (key.length != 16)
|
|
10
|
+
throw new Error("Key must be 16 bytes (128-bit) long");
|
|
11
|
+
if (iv.length != 16)
|
|
12
|
+
throw new Error("Iv must be 16 bytes (128-bit) long");
|
|
13
|
+
if (salt.length != 6)
|
|
14
|
+
throw new Error("Salt must be 6 bytes (48-bit) long");
|
|
15
|
+
// Apply salt to key and iv
|
|
16
|
+
this._key = new Uint8Array(key);
|
|
17
|
+
this._iv = new Uint8Array(iv);
|
|
18
|
+
for (let i = 0; i < 6; i++) {
|
|
19
|
+
this._key[i] = (key[i] + salt[i]) % 0xFF;
|
|
20
|
+
this._iv[i] = (iv[i] + salt[i]) % 0xFF;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** Encrypt 16-byte buffer chunk starting at offset using AES-128-CBC */
|
|
24
|
+
encryptChunk(buffer, offset) {
|
|
25
|
+
var cipher = new ModeOfOperation.cbc(this._key, this._iv);
|
|
26
|
+
var chunk = cipher.encrypt(buffer.subarray(offset, offset + 16));
|
|
27
|
+
buffer.set(chunk, offset);
|
|
28
|
+
}
|
|
29
|
+
/** Decrypt 16-byte buffer chunk starting at offset using AES-128-CBC */
|
|
30
|
+
decryptChunk(buffer, offset) {
|
|
31
|
+
var cipher = new ModeOfOperation.cbc(this._key, this._iv);
|
|
32
|
+
var chunk = cipher.decrypt(buffer.subarray(offset, offset + 16));
|
|
33
|
+
buffer.set(chunk, offset);
|
|
34
|
+
}
|
|
35
|
+
encrypt(data) {
|
|
36
|
+
if (data.length < 16)
|
|
37
|
+
throw Error('Data must be at least 16 bytes long');
|
|
38
|
+
var res = new Uint8Array(data);
|
|
39
|
+
// encrypt 16-byte chunk aligned to message start
|
|
40
|
+
this.encryptChunk(res, 0);
|
|
41
|
+
// encrypt 16-byte chunk aligned to message end
|
|
42
|
+
if (res.length > 16) {
|
|
43
|
+
this.encryptChunk(res, res.length - 16);
|
|
44
|
+
}
|
|
45
|
+
return res;
|
|
46
|
+
}
|
|
47
|
+
decrypt(data) {
|
|
48
|
+
if (data.length < 16)
|
|
49
|
+
throw Error('Data must be at least 16 bytes long');
|
|
50
|
+
var res = new Uint8Array(data);
|
|
51
|
+
// decrypt 16-byte chunk aligned to message end
|
|
52
|
+
if (res.length > 16) {
|
|
53
|
+
this.decryptChunk(res, res.length - 16);
|
|
54
|
+
}
|
|
55
|
+
// decrypt 16-byte chunk aligned to message start
|
|
56
|
+
this.decryptChunk(res, 0);
|
|
57
|
+
return res;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Implementation for encryption scheme used in the GAN Gen3 cubes
|
|
62
|
+
*/
|
|
63
|
+
class GanGen3CubeEncrypter extends GanGen2CubeEncrypter {
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Implementation for encryption scheme used in the GAN Gen3 cubes
|
|
67
|
+
*/
|
|
68
|
+
class GanGen4CubeEncrypter extends GanGen2CubeEncrypter {
|
|
69
|
+
}
|
|
70
|
+
export { GanGen2CubeEncrypter, GanGen3CubeEncrypter, GanGen4CubeEncrypter };
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/// <reference types="web-bluetooth" />
|
|
2
|
+
import { GanCubeEncrypter } from './gan-cube-encrypter.js';
|
|
3
|
+
import { Observable, Subject } from 'rxjs';
|
|
4
|
+
/** Command for requesting information about GAN Smart Cube hardware */
|
|
5
|
+
type GanCubeReqHardwareCommand = {
|
|
6
|
+
type: "REQUEST_HARDWARE";
|
|
7
|
+
};
|
|
8
|
+
/** Command for requesting information about current facelets state */
|
|
9
|
+
type GanCubeReqFaceletsCommand = {
|
|
10
|
+
type: "REQUEST_FACELETS";
|
|
11
|
+
};
|
|
12
|
+
/** Command for requesting information about current battery level */
|
|
13
|
+
type GanCubeReqBatteryCommand = {
|
|
14
|
+
type: "REQUEST_BATTERY";
|
|
15
|
+
};
|
|
16
|
+
/** Command for resetting GAN Smart Cube internal facelets state to solved state */
|
|
17
|
+
type GanCubeReqResetCommand = {
|
|
18
|
+
type: "REQUEST_RESET";
|
|
19
|
+
};
|
|
20
|
+
/** Command message */
|
|
21
|
+
type GanCubeCommand = GanCubeReqHardwareCommand | GanCubeReqFaceletsCommand | GanCubeReqBatteryCommand | GanCubeReqResetCommand;
|
|
22
|
+
/**
|
|
23
|
+
* Representation of GAN Smart Cube move
|
|
24
|
+
*/
|
|
25
|
+
type GanCubeMove = {
|
|
26
|
+
/** Face: 0 - U, 1 - R, 2 - F, 3 - D, 4 - L, 5 - B */
|
|
27
|
+
face: number;
|
|
28
|
+
/** Face direction: 0 - CW, 1 - CCW */
|
|
29
|
+
direction: number;
|
|
30
|
+
/** Cube move in common string notation, like R' or U */
|
|
31
|
+
move: string;
|
|
32
|
+
/** Timestamp according to host device clock, null in case if bluetooth event was missed and recovered */
|
|
33
|
+
localTimestamp: number | null;
|
|
34
|
+
/** Timestamp according to cube internal clock, for some cube models may be null in case if bluetooth event was missed and recovered */
|
|
35
|
+
cubeTimestamp: number | null;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Move event
|
|
39
|
+
*/
|
|
40
|
+
type GanCubeMoveEvent = {
|
|
41
|
+
type: "MOVE";
|
|
42
|
+
/** Serial number, value range 0-255, increased in a circle on each facelets state change */
|
|
43
|
+
serial: number;
|
|
44
|
+
} & GanCubeMove;
|
|
45
|
+
/**
|
|
46
|
+
* Representation of GAN Smart Cube facelets state
|
|
47
|
+
*/
|
|
48
|
+
type GanCubeState = {
|
|
49
|
+
/** Corner Permutation: 8 elements, values from 0 to 7 */
|
|
50
|
+
CP: Array<number>;
|
|
51
|
+
/** Corner Orientation: 8 elements, values from 0 to 2 */
|
|
52
|
+
CO: Array<number>;
|
|
53
|
+
/** Edge Permutation: 12 elements, values from 0 to 11 */
|
|
54
|
+
EP: Array<number>;
|
|
55
|
+
/** Edge Orientation: 12 elements, values from 0 to 1 */
|
|
56
|
+
EO: Array<number>;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Facelets event
|
|
60
|
+
*/
|
|
61
|
+
type GanCubeFaceletsEvent = {
|
|
62
|
+
type: "FACELETS";
|
|
63
|
+
/** Serial number, value range 0-255, increased in a circle on each facelets state change */
|
|
64
|
+
serial: number;
|
|
65
|
+
/** Cube facelets state in the Kociemba notation like "UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB" */
|
|
66
|
+
facelets: string;
|
|
67
|
+
/** Cube state representing corners and edges orientation and permutation */
|
|
68
|
+
state: GanCubeState;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Quaternion to represent orientation
|
|
72
|
+
*/
|
|
73
|
+
type GanCubeOrientationQuaternion = {
|
|
74
|
+
x: number;
|
|
75
|
+
y: number;
|
|
76
|
+
z: number;
|
|
77
|
+
w: number;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Representation of angular velocity by axes
|
|
81
|
+
*/
|
|
82
|
+
type GanCubeAngularVelocity = {
|
|
83
|
+
x: number;
|
|
84
|
+
y: number;
|
|
85
|
+
z: number;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Gyroscope event
|
|
89
|
+
*/
|
|
90
|
+
type GanCubeGyroEvent = {
|
|
91
|
+
type: "GYRO";
|
|
92
|
+
/** Cube orientation quaternion, uses Right-Handed coordinate system, +X - Red, +Y - Blue, +Z - White */
|
|
93
|
+
quaternion: GanCubeOrientationQuaternion;
|
|
94
|
+
/** Cube angular velocity over current ODR time frame */
|
|
95
|
+
velocity?: GanCubeAngularVelocity;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Battery event
|
|
99
|
+
*/
|
|
100
|
+
type GanCubeBatteryEvent = {
|
|
101
|
+
type: "BATTERY";
|
|
102
|
+
/** Current battery level in percent */
|
|
103
|
+
batteryLevel: number;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Hardware event
|
|
107
|
+
*/
|
|
108
|
+
type GanCubeHardwareEvent = {
|
|
109
|
+
type: "HARDWARE";
|
|
110
|
+
/** Internal cube hardware device model name */
|
|
111
|
+
hardwareName?: string;
|
|
112
|
+
/** Software/Firmware version of the cube */
|
|
113
|
+
softwareVersion?: string;
|
|
114
|
+
/** Hardware version of the cube */
|
|
115
|
+
hardwareVersion?: string;
|
|
116
|
+
/** Production Date of the cube */
|
|
117
|
+
productDate?: string;
|
|
118
|
+
/** Is gyroscope supported by this cube model */
|
|
119
|
+
gyroSupported?: boolean;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Disconnect event
|
|
123
|
+
*/
|
|
124
|
+
type GanCubeDisconnectEvent = {
|
|
125
|
+
type: "DISCONNECT";
|
|
126
|
+
};
|
|
127
|
+
/** All possible event message types */
|
|
128
|
+
type GanCubeEventMessage = GanCubeMoveEvent | GanCubeFaceletsEvent | GanCubeGyroEvent | GanCubeBatteryEvent | GanCubeHardwareEvent | GanCubeDisconnectEvent;
|
|
129
|
+
/** Cube event / response to command */
|
|
130
|
+
type GanCubeEvent = {
|
|
131
|
+
timestamp: number;
|
|
132
|
+
} & GanCubeEventMessage;
|
|
133
|
+
/** Extention to the BluetoothDevice for storing and accessing device MAC address */
|
|
134
|
+
interface BluetoothDeviceWithMAC extends BluetoothDevice {
|
|
135
|
+
mac?: string;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Connection object representing connection API and state
|
|
139
|
+
*/
|
|
140
|
+
interface GanCubeConnection {
|
|
141
|
+
/** Connected Bluetooth cube device name */
|
|
142
|
+
readonly deviceName: string;
|
|
143
|
+
/** Connected Bluetoooth cube device MAC address */
|
|
144
|
+
readonly deviceMAC: string;
|
|
145
|
+
/** RxJS Subject to subscribe for cube event messages */
|
|
146
|
+
events$: Observable<GanCubeEvent>;
|
|
147
|
+
/** Method to send command to the cube */
|
|
148
|
+
sendCubeCommand(command: GanCubeCommand): Promise<void>;
|
|
149
|
+
/** Close this connection */
|
|
150
|
+
disconnect(): Promise<void>;
|
|
151
|
+
}
|
|
152
|
+
/** Raw connection interface for internal use */
|
|
153
|
+
interface GanCubeRawConnection {
|
|
154
|
+
sendCommandMessage(message: Uint8Array): Promise<void>;
|
|
155
|
+
disconnect(): Promise<void>;
|
|
156
|
+
}
|
|
157
|
+
/** Protocol Driver interface */
|
|
158
|
+
interface GanProtocolDriver {
|
|
159
|
+
/** Create binary command message for cube device */
|
|
160
|
+
createCommandMessage(command: GanCubeCommand): Uint8Array | undefined;
|
|
161
|
+
/** Handle binary event messages from cube device */
|
|
162
|
+
handleStateEvent(conn: GanCubeRawConnection, eventMessage: Uint8Array): Promise<GanCubeEvent[]>;
|
|
163
|
+
}
|
|
164
|
+
/** Optional hooks for {@link GanCubeClassicConnection.create}. */
|
|
165
|
+
export type GanClassicConnectionOptions = {
|
|
166
|
+
/** If set, decrypted payloads that fail this check are dropped (wrong MAC / noise). */
|
|
167
|
+
validateDecrypted?: (plaintext: Uint8Array) => boolean;
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* Implementation of classic command/response connection with GAN Smart Cube device
|
|
171
|
+
*/
|
|
172
|
+
declare class GanCubeClassicConnection implements GanCubeConnection, GanCubeRawConnection {
|
|
173
|
+
device: BluetoothDeviceWithMAC;
|
|
174
|
+
commandCharacteristic: BluetoothRemoteGATTCharacteristic;
|
|
175
|
+
stateCharacteristic: BluetoothRemoteGATTCharacteristic;
|
|
176
|
+
encrypter: GanCubeEncrypter;
|
|
177
|
+
driver: GanProtocolDriver;
|
|
178
|
+
events$: Subject<GanCubeEvent>;
|
|
179
|
+
private readonly validateDecrypted?;
|
|
180
|
+
private readonly writeQueue;
|
|
181
|
+
private disconnectOnce;
|
|
182
|
+
private constructor();
|
|
183
|
+
static create(device: BluetoothDeviceWithMAC, commandCharacteristic: BluetoothRemoteGATTCharacteristic, stateCharacteristic: BluetoothRemoteGATTCharacteristic, encrypter: GanCubeEncrypter, driver: GanProtocolDriver, options?: GanClassicConnectionOptions): Promise<GanCubeConnection>;
|
|
184
|
+
get deviceName(): string;
|
|
185
|
+
get deviceMAC(): string;
|
|
186
|
+
sendCommandMessage(message: Uint8Array): Promise<void>;
|
|
187
|
+
onStateUpdate: (evt: Event) => Promise<void>;
|
|
188
|
+
onDisconnect: () => Promise<void>;
|
|
189
|
+
sendCubeCommand(command: GanCubeCommand): Promise<void>;
|
|
190
|
+
disconnect(): Promise<void>;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Driver implementation for GAN Gen2 protocol, supported cubes:
|
|
194
|
+
* - GAN Mini ui FreePlay
|
|
195
|
+
* - GAN12 ui FreePlay
|
|
196
|
+
* - GAN12 ui
|
|
197
|
+
* - GAN356 i Carry S
|
|
198
|
+
* - GAN356 i Carry
|
|
199
|
+
* - GAN356 i 3
|
|
200
|
+
* - Monster Go 3Ai
|
|
201
|
+
*/
|
|
202
|
+
declare class GanGen2ProtocolDriver implements GanProtocolDriver {
|
|
203
|
+
private lastSerial;
|
|
204
|
+
private lastMoveTimestamp;
|
|
205
|
+
private cubeTimestamp;
|
|
206
|
+
createCommandMessage(command: GanCubeCommand): Uint8Array | undefined;
|
|
207
|
+
handleStateEvent(conn: GanCubeRawConnection, eventMessage: Uint8Array): Promise<GanCubeEvent[]>;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Driver implementation for GAN Gen3 protocol, supported cubes:
|
|
211
|
+
* - GAN356 i Carry 2
|
|
212
|
+
*/
|
|
213
|
+
declare class GanGen3ProtocolDriver implements GanProtocolDriver {
|
|
214
|
+
private serial;
|
|
215
|
+
private lastSerial;
|
|
216
|
+
private lastLocalTimestamp;
|
|
217
|
+
private moveBuffer;
|
|
218
|
+
createCommandMessage(command: GanCubeCommand): Uint8Array | undefined;
|
|
219
|
+
/** Private cube command for requesting move history */
|
|
220
|
+
private requestMoveHistory;
|
|
221
|
+
/**
|
|
222
|
+
* Evict move events from FIFO buffer until missing move event detected
|
|
223
|
+
* In case of missing move, and if connection is provided, submit request for move history to fill gap in buffer
|
|
224
|
+
*/
|
|
225
|
+
private evictMoveBuffer;
|
|
226
|
+
/**
|
|
227
|
+
* Check if circular serial number (modulo 256) fits into (start,end) serial number range.
|
|
228
|
+
* By default range is open, set closedStart / closedEnd to make it closed.
|
|
229
|
+
*/
|
|
230
|
+
private isSerialInRange;
|
|
231
|
+
/** Used to inject missed moves to FIFO buffer */
|
|
232
|
+
private injectMissedMoveToBuffer;
|
|
233
|
+
/** Used in response to periodic facelets event to check if any moves missed */
|
|
234
|
+
private checkIfMoveMissed;
|
|
235
|
+
handleStateEvent(conn: GanCubeRawConnection, eventMessage: Uint8Array): Promise<GanCubeEvent[]>;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Driver implementation for GAN Gen4 protocol, supported cubes:
|
|
239
|
+
* - GAN12 ui Maglev
|
|
240
|
+
* - GAN14 ui FreePlay
|
|
241
|
+
*/
|
|
242
|
+
declare class GanGen4ProtocolDriver implements GanProtocolDriver {
|
|
243
|
+
private serial;
|
|
244
|
+
private lastSerial;
|
|
245
|
+
private lastLocalTimestamp;
|
|
246
|
+
private moveBuffer;
|
|
247
|
+
private hwInfo;
|
|
248
|
+
/** Set when we have seen at least one 0xEC GYRO packet this connection (not cleared on REQUEST_HARDWARE). */
|
|
249
|
+
private gyroObserved;
|
|
250
|
+
/** Set when a full HARDWARE snapshot was emitted for the current hwInfo assembly; reset when REQUEST_HARDWARE clears hwInfo. */
|
|
251
|
+
private hardwareInfoEmitted;
|
|
252
|
+
createCommandMessage(command: GanCubeCommand): Uint8Array | undefined;
|
|
253
|
+
private buildHardwareEvent;
|
|
254
|
+
/** Private cube command for requesting move history */
|
|
255
|
+
private requestMoveHistory;
|
|
256
|
+
/**
|
|
257
|
+
* Evict move events from FIFO buffer until missing move event detected
|
|
258
|
+
* In case of missing move, and if connection is provided, submit request for move history to fill gap in buffer
|
|
259
|
+
*/
|
|
260
|
+
private evictMoveBuffer;
|
|
261
|
+
/**
|
|
262
|
+
* Check if circular serial number (modulo 256) fits into (start,end) serial number range.
|
|
263
|
+
* By default range is open, set closedStart / closedEnd to make it closed.
|
|
264
|
+
*/
|
|
265
|
+
private isSerialInRange;
|
|
266
|
+
/** Used to inject missed moves to FIFO buffer */
|
|
267
|
+
private injectMissedMoveToBuffer;
|
|
268
|
+
/** Used in response to periodic facelets event to check if any moves missed */
|
|
269
|
+
private checkIfMoveMissed;
|
|
270
|
+
handleStateEvent(conn: GanCubeRawConnection, eventMessage: Uint8Array): Promise<GanCubeEvent[]>;
|
|
271
|
+
}
|
|
272
|
+
export type { BluetoothDeviceWithMAC, GanCubeConnection, GanCubeEvent, GanCubeCommand, GanCubeMove, GanProtocolDriver };
|
|
273
|
+
export { GanCubeClassicConnection, GanGen2ProtocolDriver, GanGen3ProtocolDriver, GanGen4ProtocolDriver };
|