@cubingcenter/scrambler 0.6.3 → 0.8.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 (191) hide show
  1. package/README.md +17 -4
  2. package/dist/core/api.d.ts.map +1 -1
  3. package/dist/core/api.js +10 -2
  4. package/dist/puzzles/cube2/solver/browser-loader.d.ts +4 -7
  5. package/dist/puzzles/cube2/solver/browser-loader.d.ts.map +1 -1
  6. package/dist/puzzles/cube2/solver/browser-loader.js +42 -14
  7. package/dist/puzzles/cube2/solver/generated-assets.d.ts.map +1 -1
  8. package/dist/puzzles/cube2/solver/generated-assets.js +8 -3
  9. package/dist/puzzles/cube2/solver/search.d.ts.map +1 -1
  10. package/dist/puzzles/cube2/solver/search.js +3 -3
  11. package/dist/puzzles/cube2/solver/tables.d.ts +6 -0
  12. package/dist/puzzles/cube2/solver/tables.d.ts.map +1 -1
  13. package/dist/puzzles/cube2/solver/tables.js +16 -2
  14. package/dist/puzzles/cube3/index.d.ts +1 -0
  15. package/dist/puzzles/cube3/index.d.ts.map +1 -1
  16. package/dist/puzzles/cube3/moves.d.ts.map +1 -1
  17. package/dist/puzzles/cube3/moves.js +104 -18
  18. package/dist/puzzles/cube3/scrambler.d.ts +16 -1
  19. package/dist/puzzles/cube3/scrambler.d.ts.map +1 -1
  20. package/dist/puzzles/cube3/scrambler.js +1 -1
  21. package/dist/puzzles/cube3/solver/browser-loader.d.ts.map +1 -1
  22. package/dist/puzzles/cube3/solver/browser-loader.js +48 -22
  23. package/dist/puzzles/cube3/solver/generated-assets.d.ts.map +1 -1
  24. package/dist/puzzles/cube3/solver/generated-assets.js +9 -3
  25. package/dist/puzzles/cube3/solver/index.d.ts +5 -3
  26. package/dist/puzzles/cube3/solver/index.d.ts.map +1 -1
  27. package/dist/puzzles/cube3/solver/index.js +2 -1
  28. package/dist/puzzles/cube3/solver/node-loader.js +9 -2
  29. package/dist/puzzles/cube3/solver/phase1.d.ts +37 -0
  30. package/dist/puzzles/cube3/solver/phase1.d.ts.map +1 -1
  31. package/dist/puzzles/cube3/solver/phase1.js +156 -15
  32. package/dist/puzzles/cube3/solver/phase2.d.ts +75 -0
  33. package/dist/puzzles/cube3/solver/phase2.d.ts.map +1 -1
  34. package/dist/puzzles/cube3/solver/phase2.js +279 -68
  35. package/dist/puzzles/cube3/solver/search-utils.d.ts +1 -1
  36. package/dist/puzzles/cube3/solver/search-utils.d.ts.map +1 -1
  37. package/dist/puzzles/cube3/solver/symmetry.d.ts +24 -0
  38. package/dist/puzzles/cube3/solver/symmetry.d.ts.map +1 -0
  39. package/dist/puzzles/cube3/solver/symmetry.js +74 -0
  40. package/dist/puzzles/cube3/solver/tables.d.ts +6 -1
  41. package/dist/puzzles/cube3/solver/tables.d.ts.map +1 -1
  42. package/dist/puzzles/cube3/solver/tables.js +14 -12
  43. package/dist/puzzles/cube3/validation.d.ts.map +1 -1
  44. package/dist/puzzles/cube3/validation.js +15 -7
  45. package/dist/puzzles/cube4/browser-worker-pool.d.ts +82 -0
  46. package/dist/puzzles/cube4/browser-worker-pool.d.ts.map +1 -0
  47. package/dist/puzzles/cube4/browser-worker-pool.js +205 -0
  48. package/dist/puzzles/cube4/browser-worker.d.ts +2 -0
  49. package/dist/puzzles/cube4/browser-worker.d.ts.map +1 -0
  50. package/dist/puzzles/cube4/browser-worker.js +31 -0
  51. package/dist/puzzles/cube4/index.d.ts +10 -2
  52. package/dist/puzzles/cube4/index.d.ts.map +1 -1
  53. package/dist/puzzles/cube4/index.js +6 -2
  54. package/dist/puzzles/cube4/moves.d.ts +5 -0
  55. package/dist/puzzles/cube4/moves.d.ts.map +1 -1
  56. package/dist/puzzles/cube4/moves.js +212 -11
  57. package/dist/puzzles/cube4/reduction/browser-loader.d.ts +29 -1
  58. package/dist/puzzles/cube4/reduction/browser-loader.d.ts.map +1 -1
  59. package/dist/puzzles/cube4/reduction/browser-loader.js +227 -32
  60. package/dist/puzzles/cube4/reduction/center2.d.ts +44 -3
  61. package/dist/puzzles/cube4/reduction/center2.d.ts.map +1 -1
  62. package/dist/puzzles/cube4/reduction/center2.js +152 -10
  63. package/dist/puzzles/cube4/reduction/edge3.d.ts +4 -0
  64. package/dist/puzzles/cube4/reduction/edge3.d.ts.map +1 -1
  65. package/dist/puzzles/cube4/reduction/edge3.js +23 -3
  66. package/dist/puzzles/cube4/reduction/finish3.d.ts +53 -0
  67. package/dist/puzzles/cube4/reduction/finish3.d.ts.map +1 -0
  68. package/dist/puzzles/cube4/reduction/finish3.js +393 -0
  69. package/dist/puzzles/cube4/reduction/generated/c3_pair_dist.bin +1 -0
  70. package/dist/puzzles/cube4/reduction/generated/center2-manifest.json +36 -0
  71. package/dist/puzzles/cube4/reduction/generated/center2-pruning-wide.bin +1 -0
  72. package/dist/puzzles/cube4/reduction/generated/hc-distances.bin +1 -0
  73. package/dist/puzzles/cube4/reduction/generated/hc-manifest.json +44 -0
  74. package/dist/puzzles/cube4/reduction/generated/hc-move.bin +0 -0
  75. package/dist/puzzles/cube4/reduction/hc-pdb.d.ts +52 -0
  76. package/dist/puzzles/cube4/reduction/hc-pdb.d.ts.map +1 -0
  77. package/dist/puzzles/cube4/reduction/hc-pdb.js +220 -0
  78. package/dist/puzzles/cube4/reduction/node-loader.d.ts +15 -1
  79. package/dist/puzzles/cube4/reduction/node-loader.d.ts.map +1 -1
  80. package/dist/puzzles/cube4/reduction/node-loader.js +199 -25
  81. package/dist/puzzles/cube4/reduction/pair-transversal.d.ts +28 -0
  82. package/dist/puzzles/cube4/reduction/pair-transversal.d.ts.map +1 -0
  83. package/dist/puzzles/cube4/reduction/pair-transversal.js +107 -0
  84. package/dist/puzzles/cube4/reduction/pairing-coordinate.js +5 -5
  85. package/dist/puzzles/cube4/reduction/phase3-search.d.ts +116 -7
  86. package/dist/puzzles/cube4/reduction/phase3-search.d.ts.map +1 -1
  87. package/dist/puzzles/cube4/reduction/phase3-search.js +458 -32
  88. package/dist/puzzles/cube4/reduction/rotation-fix.d.ts +28 -0
  89. package/dist/puzzles/cube4/reduction/rotation-fix.d.ts.map +1 -0
  90. package/dist/puzzles/cube4/reduction/rotation-fix.js +212 -0
  91. package/dist/puzzles/cube4/reduction/solve.d.ts +172 -2
  92. package/dist/puzzles/cube4/reduction/solve.d.ts.map +1 -1
  93. package/dist/puzzles/cube4/reduction/solve.js +1201 -180
  94. package/dist/puzzles/cube4/scramble-cache.d.ts +93 -0
  95. package/dist/puzzles/cube4/scramble-cache.d.ts.map +1 -0
  96. package/dist/puzzles/cube4/scramble-cache.js +150 -0
  97. package/dist/puzzles/cube4/scrambler.d.ts +201 -6
  98. package/dist/puzzles/cube4/scrambler.d.ts.map +1 -1
  99. package/dist/puzzles/cube4/scrambler.js +414 -176
  100. package/dist/puzzles/cube4/state.d.ts.map +1 -1
  101. package/dist/puzzles/cube4/state.js +4 -1
  102. package/dist/puzzles/cube4/worker-pool.d.ts +139 -0
  103. package/dist/puzzles/cube4/worker-pool.d.ts.map +1 -0
  104. package/dist/puzzles/cube4/worker-pool.js +405 -0
  105. package/dist/puzzles/cube4/worker-protocol.d.ts +58 -0
  106. package/dist/puzzles/cube4/worker-protocol.d.ts.map +1 -0
  107. package/dist/puzzles/cube4/worker-protocol.js +58 -0
  108. package/dist/puzzles/cube4/worker.d.ts +26 -0
  109. package/dist/puzzles/cube4/worker.d.ts.map +1 -0
  110. package/dist/puzzles/cube4/worker.js +49 -0
  111. package/dist/puzzles/pyraminx/solver/browser-loader.d.ts +4 -8
  112. package/dist/puzzles/pyraminx/solver/browser-loader.d.ts.map +1 -1
  113. package/dist/puzzles/pyraminx/solver/browser-loader.js +44 -15
  114. package/dist/puzzles/pyraminx/solver/generated-assets.d.ts.map +1 -1
  115. package/dist/puzzles/pyraminx/solver/generated-assets.js +8 -3
  116. package/dist/puzzles/pyraminx/solver/search.d.ts.map +1 -1
  117. package/dist/puzzles/pyraminx/solver/search.js +3 -6
  118. package/dist/puzzles/pyraminx/solver/tables.d.ts +6 -0
  119. package/dist/puzzles/pyraminx/solver/tables.d.ts.map +1 -1
  120. package/dist/puzzles/pyraminx/solver/tables.js +17 -0
  121. package/dist/puzzles/shared/compressed-fetch.d.ts +37 -1
  122. package/dist/puzzles/shared/compressed-fetch.d.ts.map +1 -1
  123. package/dist/puzzles/shared/compressed-fetch.js +226 -31
  124. package/dist/puzzles/shared/load-once.d.ts +16 -0
  125. package/dist/puzzles/shared/load-once.d.ts.map +1 -0
  126. package/dist/puzzles/shared/load-once.js +11 -0
  127. package/dist/puzzles/skewb/solver/browser-loader.d.ts +4 -11
  128. package/dist/puzzles/skewb/solver/browser-loader.d.ts.map +1 -1
  129. package/dist/puzzles/skewb/solver/browser-loader.js +44 -16
  130. package/dist/puzzles/skewb/solver/generated-assets.d.ts.map +1 -1
  131. package/dist/puzzles/skewb/solver/generated-assets.js +8 -3
  132. package/dist/puzzles/skewb/solver/search.js +3 -3
  133. package/dist/puzzles/skewb/solver/tables.d.ts +6 -0
  134. package/dist/puzzles/skewb/solver/tables.d.ts.map +1 -1
  135. package/dist/puzzles/skewb/solver/tables.js +17 -0
  136. package/dist/puzzles/sq1/solver/browser-loader.d.ts.map +1 -1
  137. package/dist/puzzles/sq1/solver/browser-loader.js +58 -26
  138. package/dist-cjs/core/api.js +10 -2
  139. package/dist-cjs/puzzles/cube2/solver/browser-loader.js +42 -14
  140. package/dist-cjs/puzzles/cube2/solver/generated-assets.js +8 -3
  141. package/dist-cjs/puzzles/cube2/solver/search.js +2 -2
  142. package/dist-cjs/puzzles/cube2/solver/tables.js +17 -3
  143. package/dist-cjs/puzzles/cube3/moves.js +104 -18
  144. package/dist-cjs/puzzles/cube3/scrambler.js +1 -1
  145. package/dist-cjs/puzzles/cube3/solver/browser-loader.js +48 -22
  146. package/dist-cjs/puzzles/cube3/solver/generated-assets.js +9 -3
  147. package/dist-cjs/puzzles/cube3/solver/index.js +8 -1
  148. package/dist-cjs/puzzles/cube3/solver/node-loader.js +9 -2
  149. package/dist-cjs/puzzles/cube3/solver/phase1.js +157 -15
  150. package/dist-cjs/puzzles/cube3/solver/phase2.js +276 -65
  151. package/dist-cjs/puzzles/cube3/solver/symmetry.js +80 -0
  152. package/dist-cjs/puzzles/cube3/solver/tables.js +14 -12
  153. package/dist-cjs/puzzles/cube3/validation.js +15 -7
  154. package/dist-cjs/puzzles/cube4/browser-worker-pool.js +211 -0
  155. package/dist-cjs/puzzles/cube4/index.js +23 -1
  156. package/dist-cjs/puzzles/cube4/moves.js +213 -11
  157. package/dist-cjs/puzzles/cube4/reduction/browser-loader.js +227 -32
  158. package/dist-cjs/puzzles/cube4/reduction/center2.js +155 -10
  159. package/dist-cjs/puzzles/cube4/reduction/edge3.js +24 -3
  160. package/dist-cjs/puzzles/cube4/reduction/finish3.js +398 -0
  161. package/dist-cjs/puzzles/cube4/reduction/generated/c3_pair_dist.bin +1 -0
  162. package/dist-cjs/puzzles/cube4/reduction/generated/center2-manifest.json +36 -0
  163. package/dist-cjs/puzzles/cube4/reduction/generated/center2-pruning-wide.bin +1 -0
  164. package/dist-cjs/puzzles/cube4/reduction/generated/hc-distances.bin +1 -0
  165. package/dist-cjs/puzzles/cube4/reduction/generated/hc-manifest.json +44 -0
  166. package/dist-cjs/puzzles/cube4/reduction/generated/hc-move.bin +0 -0
  167. package/dist-cjs/puzzles/cube4/reduction/hc-pdb.js +232 -0
  168. package/dist-cjs/puzzles/cube4/reduction/node-loader.js +200 -25
  169. package/dist-cjs/puzzles/cube4/reduction/pair-transversal.js +112 -0
  170. package/dist-cjs/puzzles/cube4/reduction/pairing-coordinate.js +5 -5
  171. package/dist-cjs/puzzles/cube4/reduction/phase3-search.js +460 -33
  172. package/dist-cjs/puzzles/cube4/reduction/rotation-fix.js +216 -0
  173. package/dist-cjs/puzzles/cube4/reduction/solve.js +1203 -172
  174. package/dist-cjs/puzzles/cube4/scramble-cache.js +156 -0
  175. package/dist-cjs/puzzles/cube4/scrambler.js +416 -174
  176. package/dist-cjs/puzzles/cube4/state.js +4 -1
  177. package/dist-cjs/puzzles/cube4/worker-pool.js +447 -0
  178. package/dist-cjs/puzzles/cube4/worker-protocol.js +62 -0
  179. package/dist-cjs/puzzles/pyraminx/solver/browser-loader.js +44 -15
  180. package/dist-cjs/puzzles/pyraminx/solver/generated-assets.js +8 -3
  181. package/dist-cjs/puzzles/pyraminx/solver/search.js +2 -5
  182. package/dist-cjs/puzzles/pyraminx/solver/tables.js +18 -1
  183. package/dist-cjs/puzzles/shared/compressed-fetch.js +229 -31
  184. package/dist-cjs/puzzles/shared/load-once.js +14 -0
  185. package/dist-cjs/puzzles/skewb/solver/browser-loader.js +44 -16
  186. package/dist-cjs/puzzles/skewb/solver/generated-assets.js +8 -3
  187. package/dist-cjs/puzzles/skewb/solver/search.js +2 -2
  188. package/dist-cjs/puzzles/skewb/solver/tables.js +18 -1
  189. package/dist-cjs/puzzles/sq1/solver/browser-loader.js +58 -26
  190. package/docs/development.md +19 -7
  191. package/package.json +17 -7
@@ -41,15 +41,23 @@ export function isAllowedRandomCube3State(state) {
41
41
  !isOneMoveFromSolvedCube3State(state);
42
42
  }
43
43
  export function permutationParity(permutation) {
44
- let inversions = 0;
45
- for (let left = 0; left < permutation.length; left += 1) {
46
- for (let right = left + 1; right < permutation.length; right += 1) {
47
- if (permutation[left] > permutation[right]) {
48
- inversions += 1;
49
- }
44
+ // Cycle-decomposition parity in O(n) instead of O(n²) inversion counting
45
+ // (identical result: parity = (n − cycles) mod 2).
46
+ const visited = new Array(permutation.length).fill(false);
47
+ let parity = 0;
48
+ for (let start = 0; start < permutation.length; start += 1) {
49
+ if (visited[start] || permutation[start] === start)
50
+ continue;
51
+ let length = 0;
52
+ let current = start;
53
+ while (!visited[current]) {
54
+ visited[current] = true;
55
+ current = permutation[current];
56
+ length += 1;
50
57
  }
58
+ parity ^= (length - 1) & 1;
51
59
  }
52
- return (inversions % 2);
60
+ return parity;
53
61
  }
54
62
  function validatePermutation(label, permutation, length) {
55
63
  const errors = [];
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Web Worker pool for 4x4 random-state scrambles — the browser counterpart
3
+ * of `worker-pool.ts` with the same protocol, lazy-spawn lifecycle, FIFO
4
+ * queue, typed error propagation and per-thread table reuse.
5
+ *
6
+ * Unlike the Node pool (which locates its own worker file), the browser
7
+ * pool REQUIRES the caller to pass `workerUrl`, because only the caller's
8
+ * file can host the static `new URL("./browser-worker.js", import.meta.url)`
9
+ * expression that bundlers (Vite, Webpack 5, Parcel) statically analyse to
10
+ * emit a separate worker chunk:
11
+ *
12
+ * ```ts
13
+ * const pool = new Cube4BrowserWorkerPool({
14
+ * workerUrl: new URL("./browser-worker.js", import.meta.url)
15
+ * });
16
+ * const batch = await pool.generateBatch(8, { seed: "demo" });
17
+ * await pool.terminate();
18
+ * ```
19
+ *
20
+ * This file contains no `import.meta` and no static Node imports, so it
21
+ * also compiles in the CommonJS build (unlike a hard-coded
22
+ * `new URL(..., import.meta.url)` default).
23
+ *
24
+ * Errors crossing the worker boundary arrive as `Error` instances with the
25
+ * original `name`, `message` and `code` preserved (`worker-protocol.ts`).
26
+ */
27
+ import type { ScrambleResult } from "../../core/types.js";
28
+ import { type Cube4WorkerGenerationOptions } from "./worker-protocol.js";
29
+ export interface Cube4BrowserWorkerPoolOptions {
30
+ /**
31
+ * URL of the worker entry, normally
32
+ * `new URL("./browser-worker.js", import.meta.url)` written in the
33
+ * consumer's module (statically analysable by bundlers).
34
+ */
35
+ workerUrl: string | URL;
36
+ /**
37
+ * Maximum number of Web Workers. Defaults to
38
+ * `navigator.hardwareConcurrency - 1` (min 1).
39
+ */
40
+ size?: number;
41
+ }
42
+ /** Typed rejection used for post-terminate operations and shutdown itself. */
43
+ export declare class Cube4BrowserWorkerPoolClosedError extends Error {
44
+ readonly code: "cube4-browser-pool-closed";
45
+ constructor(action?: string);
46
+ }
47
+ /**
48
+ * Batch seed derivation — identical to core `generateScrambles` and to
49
+ * `deriveBatchCube4Options` in the Node pool.
50
+ */
51
+ export declare function deriveBrowserBatchCube4Options(options: Cube4WorkerGenerationOptions, index: number, count: number): Cube4WorkerGenerationOptions;
52
+ export declare class Cube4BrowserWorkerPool {
53
+ private readonly workers;
54
+ private readonly queue;
55
+ private readonly workerUrl;
56
+ private readonly maxSize;
57
+ private pumping;
58
+ private terminatePromise;
59
+ private nextId;
60
+ private terminated;
61
+ constructor(options: Cube4BrowserWorkerPoolOptions);
62
+ /** Threads spawned so far (lazily grown; 0 before the first job). */
63
+ get workerCount(): number;
64
+ get queuedCount(): number;
65
+ get busyCount(): number;
66
+ get closed(): boolean;
67
+ generate(options?: Cube4WorkerGenerationOptions): Promise<ScrambleResult>;
68
+ generateBatch(count: number, options?: Cube4WorkerGenerationOptions): Promise<ScrambleResult[]>;
69
+ /**
70
+ * Prompt shutdown: rejects queued/in-flight tasks and terminates every
71
+ * Web Worker synchronously (no threads to join in the browser).
72
+ * Idempotent.
73
+ */
74
+ terminate(): void;
75
+ private pump;
76
+ private runPump;
77
+ private spawnWorker;
78
+ private dispatch;
79
+ private handleResponse;
80
+ private handleWorkerGone;
81
+ }
82
+ //# sourceMappingURL=browser-worker-pool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-worker-pool.d.ts","sourceRoot":"","sources":["../../../src/puzzles/cube4/browser-worker-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAEL,KAAK,4BAA4B,EAGlC,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,6BAA6B;IAC5C;;;;OAIG;IACH,SAAS,EAAE,MAAM,GAAG,GAAG,CAAC;IACxB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,8EAA8E;AAC9E,qBAAa,iCAAkC,SAAQ,KAAK;IAC1D,QAAQ,CAAC,IAAI,EAAG,2BAA2B,CAAU;gBAEzC,MAAM,SAAc;CAIjC;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,4BAA4B,EACrC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,4BAA4B,CAK9B;AAqBD,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,gBAAgB,CAA4B;IACpD,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,UAAU,CAAS;gBAEf,OAAO,EAAE,6BAA6B;IAiBlD,qEAAqE;IACrE,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,QAAQ,CAAC,OAAO,GAAE,4BAAiC,GAAG,OAAO,CAAC,cAAc,CAAC;IAW7E,aAAa,CACX,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,cAAc,EAAE,CAAC;IAW5B;;;;OAIG;IACH,SAAS,IAAI,IAAI;IAoBjB,OAAO,CAAC,IAAI;YAUE,OAAO;IAerB,OAAO,CAAC,WAAW;IAoBnB,OAAO,CAAC,QAAQ;IAYhB,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,gBAAgB;CAUzB"}
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Web Worker pool for 4x4 random-state scrambles — the browser counterpart
3
+ * of `worker-pool.ts` with the same protocol, lazy-spawn lifecycle, FIFO
4
+ * queue, typed error propagation and per-thread table reuse.
5
+ *
6
+ * Unlike the Node pool (which locates its own worker file), the browser
7
+ * pool REQUIRES the caller to pass `workerUrl`, because only the caller's
8
+ * file can host the static `new URL("./browser-worker.js", import.meta.url)`
9
+ * expression that bundlers (Vite, Webpack 5, Parcel) statically analyse to
10
+ * emit a separate worker chunk:
11
+ *
12
+ * ```ts
13
+ * const pool = new Cube4BrowserWorkerPool({
14
+ * workerUrl: new URL("./browser-worker.js", import.meta.url)
15
+ * });
16
+ * const batch = await pool.generateBatch(8, { seed: "demo" });
17
+ * await pool.terminate();
18
+ * ```
19
+ *
20
+ * This file contains no `import.meta` and no static Node imports, so it
21
+ * also compiles in the CommonJS build (unlike a hard-coded
22
+ * `new URL(..., import.meta.url)` default).
23
+ *
24
+ * Errors crossing the worker boundary arrive as `Error` instances with the
25
+ * original `name`, `message` and `code` preserved (`worker-protocol.ts`).
26
+ */
27
+ import { deserializeCube4Error } from "./worker-protocol.js";
28
+ /** Typed rejection used for post-terminate operations and shutdown itself. */
29
+ export class Cube4BrowserWorkerPoolClosedError extends Error {
30
+ code = "cube4-browser-pool-closed";
31
+ constructor(action = "operation") {
32
+ super(`[cube4] browser worker pool is closed (${action} rejected).`);
33
+ this.name = "Cube4BrowserWorkerPoolClosedError";
34
+ }
35
+ }
36
+ /**
37
+ * Batch seed derivation — identical to core `generateScrambles` and to
38
+ * `deriveBatchCube4Options` in the Node pool.
39
+ */
40
+ export function deriveBrowserBatchCube4Options(options, index, count) {
41
+ if (count === 1 || options.seed === undefined) {
42
+ return options;
43
+ }
44
+ return { ...options, seed: `${options.seed}:${index}` };
45
+ }
46
+ function defaultBrowserSize() {
47
+ if (typeof navigator !== "undefined" && navigator.hardwareConcurrency) {
48
+ return Math.max(1, navigator.hardwareConcurrency - 1);
49
+ }
50
+ return 4;
51
+ }
52
+ export class Cube4BrowserWorkerPool {
53
+ workers = [];
54
+ queue = [];
55
+ workerUrl;
56
+ maxSize;
57
+ pumping = false;
58
+ terminatePromise;
59
+ nextId = 0;
60
+ terminated = false;
61
+ constructor(options) {
62
+ if (typeof Worker === "undefined") {
63
+ throw new Error("[cube4] Web Workers are not available in this environment; " +
64
+ "use generateCube4Scramble() directly for single-threaded generation.");
65
+ }
66
+ if (options.size !== undefined) {
67
+ if (!Number.isInteger(options.size) || options.size < 1) {
68
+ throw new RangeError(`[cube4] pool size must be an integer >= 1 (got ${options.size}).`);
69
+ }
70
+ }
71
+ this.workerUrl =
72
+ typeof options.workerUrl === "string" ? options.workerUrl : options.workerUrl.href;
73
+ this.maxSize = options.size ?? defaultBrowserSize();
74
+ }
75
+ /** Threads spawned so far (lazily grown; 0 before the first job). */
76
+ get workerCount() {
77
+ return this.workers.length;
78
+ }
79
+ get queuedCount() {
80
+ return this.queue.length;
81
+ }
82
+ get busyCount() {
83
+ return this.workers.reduce((n, rec) => n + (rec.task !== null ? 1 : 0), 0);
84
+ }
85
+ get closed() {
86
+ return this.terminated;
87
+ }
88
+ generate(options = {}) {
89
+ if (this.terminated) {
90
+ return Promise.reject(new Cube4BrowserWorkerPoolClosedError("generate"));
91
+ }
92
+ const id = this.nextId++;
93
+ return new Promise((resolve, reject) => {
94
+ this.queue.push({ id, options, resolve, reject });
95
+ this.pump();
96
+ });
97
+ }
98
+ generateBatch(count, options = {}) {
99
+ if (!Number.isInteger(count) || count < 1) {
100
+ return Promise.reject(new RangeError(`count must be a positive integer (got ${count}).`));
101
+ }
102
+ return Promise.all(Array.from({ length: count }, (_, index) => this.generate(deriveBrowserBatchCube4Options(options, index, count))));
103
+ }
104
+ /**
105
+ * Prompt shutdown: rejects queued/in-flight tasks and terminates every
106
+ * Web Worker synchronously (no threads to join in the browser).
107
+ * Idempotent.
108
+ */
109
+ terminate() {
110
+ if (this.terminatePromise !== undefined)
111
+ return;
112
+ this.terminated = true;
113
+ const closed = () => new Cube4BrowserWorkerPoolClosedError();
114
+ for (const task of this.queue.splice(0))
115
+ task.reject(closed());
116
+ const records = this.workers.splice(0);
117
+ for (const rec of records) {
118
+ if (rec.task !== null) {
119
+ rec.task.reject(closed());
120
+ rec.task = null;
121
+ }
122
+ rec.worker.terminate();
123
+ }
124
+ this.terminatePromise = Promise.resolve();
125
+ }
126
+ // ── internals (same shape as the Node pool) ──────────────────────────
127
+ pump() {
128
+ if (this.pumping || this.terminated)
129
+ return;
130
+ this.pumping = true;
131
+ void this.runPump()
132
+ .catch(() => undefined)
133
+ .finally(() => {
134
+ this.pumping = false;
135
+ });
136
+ }
137
+ async runPump() {
138
+ while (!this.terminated && this.queue.length > 0) {
139
+ const idle = this.workers.find((rec) => rec.task === null);
140
+ if (idle !== undefined) {
141
+ this.dispatch(idle, this.queue.shift());
142
+ continue;
143
+ }
144
+ if (this.workers.length < this.maxSize) {
145
+ this.spawnWorker();
146
+ continue;
147
+ }
148
+ break;
149
+ }
150
+ }
151
+ spawnWorker() {
152
+ const worker = new Worker(this.workerUrl, { type: "module", name: "cubingcenter-444" });
153
+ const rec = { worker, task: null };
154
+ worker.onmessage = (event) => {
155
+ this.handleResponse(rec, event.data);
156
+ };
157
+ worker.onerror = (event) => {
158
+ this.handleWorkerGone(rec, event.error instanceof Error
159
+ ? event.error
160
+ : new Error(event.message || "[cube4] browser worker failed."));
161
+ };
162
+ this.workers.push(rec);
163
+ return rec;
164
+ }
165
+ dispatch(rec, task) {
166
+ rec.task = task;
167
+ const message = { id: task.id, options: task.options };
168
+ try {
169
+ rec.worker.postMessage(message);
170
+ }
171
+ catch (error) {
172
+ rec.task = null;
173
+ task.reject(error);
174
+ this.pump();
175
+ }
176
+ }
177
+ handleResponse(rec, response) {
178
+ const task = rec.task;
179
+ if (task === null || task.id !== response.id)
180
+ return;
181
+ rec.task = null;
182
+ if (this.terminated)
183
+ return;
184
+ if (response.ok)
185
+ task.resolve(response.result);
186
+ else
187
+ task.reject(deserializeCube4Error(response.error));
188
+ const next = this.queue.shift();
189
+ if (next !== undefined)
190
+ this.dispatch(rec, next);
191
+ this.pump();
192
+ }
193
+ handleWorkerGone(rec, error) {
194
+ const index = this.workers.indexOf(rec);
195
+ if (index === -1)
196
+ return;
197
+ this.workers.splice(index, 1);
198
+ const task = rec.task;
199
+ rec.task = null;
200
+ if (task !== null && !this.terminated)
201
+ task.reject(error);
202
+ if (!this.terminated)
203
+ this.pump();
204
+ }
205
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=browser-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-worker.d.ts","sourceRoot":"","sources":["../../../src/puzzles/cube4/browser-worker.ts"],"names":[],"mappings":""}
@@ -0,0 +1,31 @@
1
+ /// <reference lib="webworker" />
2
+ /**
3
+ * Web Worker entry for 4x4 scramble generation (browser build).
4
+ *
5
+ * Mirror of `worker.ts`: no work at boot, tables loaded on the FIRST task
6
+ * and reused afterwards (the browser loader caches per worker via
7
+ * `scrambler.ts`'s promise-deduplicated `loadCube4Tables`), full options
8
+ * passed through verbatim, errors flattened through `worker-protocol.ts`.
9
+ *
10
+ * Bundlers pick this file up through the static
11
+ * `new Worker(new URL(..., import.meta.url))` pattern used by the pool's
12
+ * consumer — see `Cube4BrowserWorkerPool`'s `workerUrl` option.
13
+ */
14
+ import { generateCube4Scramble } from "./scrambler.js";
15
+ import { serializeCube4Error } from "./worker-protocol.js";
16
+ const workerScope = self;
17
+ workerScope.onmessage = (event) => {
18
+ const task = event.data;
19
+ void (async () => {
20
+ const response = await (async () => {
21
+ try {
22
+ const result = await generateCube4Scramble(task.options);
23
+ return { id: task.id, ok: true, result };
24
+ }
25
+ catch (error) {
26
+ return { id: task.id, ok: false, error: serializeCube4Error(error) };
27
+ }
28
+ })();
29
+ workerScope.postMessage(response);
30
+ })();
31
+ };
@@ -1,8 +1,16 @@
1
1
  export { CORNER_COUNT, WING_COUNT, CENTER_COUNT, FACE_COUNT, CENTERS_PER_FACE, U, R, F, D, L, B, CUBE4_FACE_MOVES, CUBE4_ALL_MOVES, CUBE4_OUTER_MOVES } from "./types.js";
2
2
  export type { Cube4Face, Cube4FaceMove, Cube4Move, Cube4MoveSuffix, Cube4State, Cube4Sticker, Cube4Facelets, Cube4ValidationResult, Cube4RandomStateOptions } from "./types.js";
3
3
  export { createSolvedCube4State, cloneCube4State, cube4StatesEqual, isSolvedCube4State, areCentersReduced, areWingsPaired } from "./state.js";
4
- export { cube4ScrambleGenerator, generateCube4Scramble } from "./scrambler.js";
5
- export { applyCube4Move, applyCube4Algorithm, invertCube4Move, invertCube4Algorithm, formatCube4Algorithm, parseCube4Algorithm, parseCube4Move, parseMove, FACE_MOVE_EFFECTS } from "./moves.js";
4
+ export { Cube4FinishCapError, Cube4Phase2CapError, Cube4Phase3CapError } from "./reduction/solve.js";
5
+ export { cube4ScrambleGenerator, generateCube4Scramble, generateCube4Attempt } from "./scrambler.js";
6
+ export type { Cube4ScrambleOptions } from "./scrambler.js";
7
+ export { Cube4WorkerPool, Cube4WorkerPoolClosedError, deriveBatchCube4Options, generateCube4ScrambleBatch, getDefaultCube4WorkerPool, closeDefaultCube4WorkerPool } from "./worker-pool.js";
8
+ export type { Cube4WorkerPoolOptions } from "./worker-pool.js";
9
+ export { Cube4BrowserWorkerPool, Cube4BrowserWorkerPoolClosedError, deriveBrowserBatchCube4Options } from "./browser-worker-pool.js";
10
+ export type { Cube4BrowserWorkerPoolOptions } from "./browser-worker-pool.js";
11
+ export { Cube4ScrambleCache, createCube4ScrambleCache, deriveCube4StreamOptions } from "./scramble-cache.js";
12
+ export type { Cube4ScrambleCacheOptions, Cube4ScrambleGenerator } from "./scramble-cache.js";
13
+ export { applyCube4Move, applyCube4Algorithm, invertCube4Move, invertCube4Algorithm, simplifyCube4Algorithm, formatCube4Algorithm, parseCube4Algorithm, parseCube4Move, parseMove, FACE_MOVE_EFFECTS } from "./moves.js";
6
14
  export { generateRandomCube4State } from "./random-state.js";
7
15
  export { validateCube4State, isOneMoveFromSolvedCube4State, isTrivialCube4State, isAllowedRandomCube4State } from "./validation.js";
8
16
  export { toCube4Facelets, formatCube4Facelets, getCube4FaceOrder } from "./facelets.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/puzzles/cube4/index.ts"],"names":[],"mappings":"AASA,OAAO,EACL,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAChB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,SAAS,EACT,aAAa,EACb,SAAS,EACT,eAAe,EACf,UAAU,EACV,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,uBAAuB,EACxB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACtB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACd,SAAS,EACT,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,wBAAwB,EACzB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,kBAAkB,EAClB,6BAA6B,EAC7B,mBAAmB,EACnB,yBAAyB,EAC1B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/puzzles/cube4/index.ts"],"names":[],"mappings":"AASA,OAAO,EACL,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAChB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,SAAS,EACT,aAAa,EACb,SAAS,EACT,eAAe,EACf,UAAU,EACV,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,uBAAuB,EACxB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACrB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE3D,OAAO,EACL,eAAe,EACf,0BAA0B,EAC1B,uBAAuB,EACvB,0BAA0B,EAC1B,yBAAyB,EACzB,2BAA2B,EAC5B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,EACL,sBAAsB,EACtB,iCAAiC,EACjC,8BAA8B,EAC/B,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AAE9E,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACzB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,yBAAyB,EACzB,sBAAsB,EACvB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACd,SAAS,EACT,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,wBAAwB,EACzB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,kBAAkB,EAClB,6BAA6B,EAC7B,mBAAmB,EACnB,yBAAyB,EAC1B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC"}
@@ -6,8 +6,12 @@ import { cube4ScrambleGenerator } from "./scrambler.js";
6
6
  registerScrambleGenerator(cube4ScrambleGenerator);
7
7
  export { CORNER_COUNT, WING_COUNT, CENTER_COUNT, FACE_COUNT, CENTERS_PER_FACE, U, R, F, D, L, B, CUBE4_FACE_MOVES, CUBE4_ALL_MOVES, CUBE4_OUTER_MOVES } from "./types.js";
8
8
  export { createSolvedCube4State, cloneCube4State, cube4StatesEqual, isSolvedCube4State, areCentersReduced, areWingsPaired } from "./state.js";
9
- export { cube4ScrambleGenerator, generateCube4Scramble } from "./scrambler.js";
10
- export { applyCube4Move, applyCube4Algorithm, invertCube4Move, invertCube4Algorithm, formatCube4Algorithm, parseCube4Algorithm, parseCube4Move, parseMove, FACE_MOVE_EFFECTS } from "./moves.js";
9
+ export { Cube4FinishCapError, Cube4Phase2CapError, Cube4Phase3CapError } from "./reduction/solve.js";
10
+ export { cube4ScrambleGenerator, generateCube4Scramble, generateCube4Attempt } from "./scrambler.js";
11
+ export { Cube4WorkerPool, Cube4WorkerPoolClosedError, deriveBatchCube4Options, generateCube4ScrambleBatch, getDefaultCube4WorkerPool, closeDefaultCube4WorkerPool } from "./worker-pool.js";
12
+ export { Cube4BrowserWorkerPool, Cube4BrowserWorkerPoolClosedError, deriveBrowserBatchCube4Options } from "./browser-worker-pool.js";
13
+ export { Cube4ScrambleCache, createCube4ScrambleCache, deriveCube4StreamOptions } from "./scramble-cache.js";
14
+ export { applyCube4Move, applyCube4Algorithm, invertCube4Move, invertCube4Algorithm, simplifyCube4Algorithm, formatCube4Algorithm, parseCube4Algorithm, parseCube4Move, parseMove, FACE_MOVE_EFFECTS } from "./moves.js";
11
15
  export { generateRandomCube4State } from "./random-state.js";
12
16
  export { validateCube4State, isOneMoveFromSolvedCube4State, isTrivialCube4State, isAllowedRandomCube4State } from "./validation.js";
13
17
  export { toCube4Facelets, formatCube4Facelets, getCube4FaceOrder } from "./facelets.js";
@@ -33,5 +33,10 @@ export declare function invertCube4Algorithm(moves: readonly Cube4Move[]): Cube4
33
33
  export declare function formatCube4Algorithm(moves: readonly Cube4Move[]): string;
34
34
  export declare function parseCube4Algorithm(algorithm: string): Cube4Move[];
35
35
  export declare function parseCube4Move(value: string): Cube4Move;
36
+ /**
37
+ * Simplifies a 4x4 algorithm by canceling inverse moves and merging redundant
38
+ * turns on the same face or across commuting parallel faces.
39
+ */
40
+ export declare function simplifyCube4Algorithm(moves: readonly Cube4Move[]): Cube4Move[];
36
41
  export { FACE_MOVE_EFFECTS };
37
42
  //# sourceMappingURL=moves.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"moves.d.ts","sourceRoot":"","sources":["../../../src/puzzles/cube4/moves.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAQxF,UAAU,UAAU;IAClB,+DAA+D;IAC/D,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,yDAAyD;IACzD,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,kFAAkF;IAClF,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,oDAAoD;IACpD,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;AA0KD,QAAA,MAAM,iBAAiB,EAAE,MAAM,CAAC,aAAa,EAAE,UAAU,CAGxD,CAAC;AA0BF,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAc1G;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,GAAG,UAAU,CAS7E;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,UAAU,CAM9F;AAMD,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAI1D;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,EAAE,CAE7E;AAMD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,CAExE;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,CAIlE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAMvD;AAMD,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
1
+ {"version":3,"file":"moves.d.ts","sourceRoot":"","sources":["../../../src/puzzles/cube4/moves.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAOxF,UAAU,UAAU;IAClB,+DAA+D;IAC/D,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,yDAAyD;IACzD,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,kFAAkF;IAClF,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,oDAAoD;IACpD,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;AA0KD,QAAA,MAAM,iBAAiB,EAAE,MAAM,CAAC,aAAa,EAAE,UAAU,CAGxD,CAAC;AAuDF,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAc1G;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,GAAG,UAAU,CAK7E;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,UAAU,CA4C9F;AAKD,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAI1D;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,EAAE,CAE7E;AAMD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,CAExE;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,CAIlE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAMvD;AA+HD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,EAAE,CAsC/E;AAMD,OAAO,EAAE,iBAAiB,EAAE,CAAC"}