cubing 0.35.18 → 0.36.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 (85) hide show
  1. package/dist/esm/alg/index.js +1 -1
  2. package/dist/esm/bluetooth/index.js +53 -5
  3. package/dist/esm/bluetooth/index.js.map +2 -2
  4. package/dist/esm/{chunk-Z6WT2ASL.js → chunk-6OUID4YZ.js} +6 -3
  5. package/dist/esm/{chunk-Z6WT2ASL.js.map → chunk-6OUID4YZ.js.map} +1 -1
  6. package/dist/esm/{chunk-YU62MHVH.js → chunk-7C5DKKWG.js} +35 -3
  7. package/dist/esm/chunk-7C5DKKWG.js.map +7 -0
  8. package/dist/esm/{chunk-TZLV35JV.js → chunk-7LQBLROH.js} +11 -7
  9. package/dist/esm/chunk-7LQBLROH.js.map +7 -0
  10. package/dist/esm/{chunk-UDX76B24.js → chunk-BI4IALY5.js} +99 -6
  11. package/dist/esm/{chunk-UDX76B24.js.map → chunk-BI4IALY5.js.map} +1 -1
  12. package/dist/esm/{chunk-HVZKPYTG.js → chunk-CFNRQVBC.js} +186 -2
  13. package/dist/esm/chunk-CFNRQVBC.js.map +7 -0
  14. package/dist/esm/{chunk-JVS2MAXS.js → chunk-EXWFZEJA.js} +6 -3
  15. package/dist/esm/{chunk-JVS2MAXS.js.map → chunk-EXWFZEJA.js.map} +1 -1
  16. package/dist/esm/{chunk-AA7SSE6X.js → chunk-IBLLQ5L6.js} +2 -2
  17. package/dist/esm/{chunk-AA7SSE6X.js.map → chunk-IBLLQ5L6.js.map} +1 -1
  18. package/dist/esm/{chunk-6KPOQHQA.js → chunk-LCARNWZG.js} +23 -16
  19. package/dist/esm/chunk-LCARNWZG.js.map +7 -0
  20. package/dist/esm/{chunk-LFMH7YXT.js → chunk-OZ7BVDDY.js} +32 -3
  21. package/dist/esm/{chunk-LFMH7YXT.js.map → chunk-OZ7BVDDY.js.map} +2 -2
  22. package/dist/esm/{chunk-FVWUXED6.js → chunk-RCFH7AT2.js} +3 -3
  23. package/dist/esm/{chunk-FVWUXED6.js.map → chunk-RCFH7AT2.js.map} +1 -1
  24. package/dist/esm/{chunk-6FGST3DR.js → chunk-TF2GO5ZC.js} +43 -14
  25. package/dist/esm/chunk-TF2GO5ZC.js.map +7 -0
  26. package/dist/esm/{chunk-LZTD2XRZ.js → chunk-UOAT7IN5.js} +16 -2
  27. package/dist/esm/{chunk-LZTD2XRZ.js.map → chunk-UOAT7IN5.js.map} +1 -1
  28. package/dist/esm/{chunk-EV25IJFC.js → chunk-ZYCJIZDN.js} +2 -1
  29. package/dist/esm/{chunk-EV25IJFC.js.map → chunk-ZYCJIZDN.js.map} +1 -1
  30. package/dist/esm/kpuzzle/index.js +2 -2
  31. package/dist/esm/notation/index.js +4 -4
  32. package/dist/esm/protocol/index.js +4 -4
  33. package/dist/esm/puzzle-geometry/index.js +116 -1
  34. package/dist/esm/puzzle-geometry/index.js.map +2 -2
  35. package/dist/esm/puzzles/index.js +4 -4
  36. package/dist/esm/{puzzles-dynamic-side-events-TEAE45HA.js → puzzles-dynamic-side-events-SRPR4BEO.js} +8 -1
  37. package/dist/esm/{puzzles-dynamic-side-events-TEAE45HA.js.map → puzzles-dynamic-side-events-SRPR4BEO.js.map} +1 -1
  38. package/dist/esm/scramble/index.js +9 -9
  39. package/dist/esm/search/index.js +9 -9
  40. package/dist/esm/{search-dynamic-sgs-side-events-T2RBUDFD.js → search-dynamic-sgs-side-events-QD7TLXPV.js} +6 -6
  41. package/dist/esm/search-dynamic-sgs-side-events-QD7TLXPV.js.map +7 -0
  42. package/dist/esm/{search-dynamic-sgs-unofficial-TJXF7BKM.js → search-dynamic-sgs-unofficial-UEIZW7YS.js} +6 -6
  43. package/dist/esm/search-dynamic-sgs-unofficial-UEIZW7YS.js.map +7 -0
  44. package/dist/esm/{search-dynamic-solve-3x3x3-VY7R3CDP.js → search-dynamic-solve-3x3x3-FJI2OWOW.js} +1 -1
  45. package/dist/esm/{search-dynamic-solve-3x3x3-VY7R3CDP.js.map → search-dynamic-solve-3x3x3-FJI2OWOW.js.map} +1 -1
  46. package/dist/esm/{search-dynamic-solve-4x4x4-I77ZF4Z5.js → search-dynamic-solve-4x4x4-USNQSEDX.js} +6 -6
  47. package/dist/esm/{search-dynamic-solve-4x4x4-I77ZF4Z5.js.map → search-dynamic-solve-4x4x4-USNQSEDX.js.map} +1 -1
  48. package/dist/esm/{search-dynamic-solve-fto-JJ32OJVM.js → search-dynamic-solve-fto-IDE3JR5R.js} +36 -1
  49. package/dist/esm/{search-dynamic-solve-fto-JJ32OJVM.js.map → search-dynamic-solve-fto-IDE3JR5R.js.map} +1 -1
  50. package/dist/esm/{search-dynamic-solve-kilominx-F22YIQDX.js → search-dynamic-solve-kilominx-DUXFWYAF.js} +2 -2
  51. package/dist/esm/{search-dynamic-solve-kilominx-F22YIQDX.js.map → search-dynamic-solve-kilominx-DUXFWYAF.js.map} +1 -1
  52. package/dist/esm/{search-dynamic-solve-master_tetraminx-UF5FKJW6.js → search-dynamic-solve-master_tetraminx-N2NAFS2P.js} +2 -1
  53. package/dist/esm/{search-dynamic-solve-master_tetraminx-UF5FKJW6.js.map → search-dynamic-solve-master_tetraminx-N2NAFS2P.js.map} +1 -1
  54. package/dist/esm/{search-dynamic-solve-sq1-S6V3FTO2.js → search-dynamic-solve-sq1-OKRDTBN4.js} +1 -1
  55. package/dist/esm/{search-dynamic-solve-sq1-S6V3FTO2.js.map → search-dynamic-solve-sq1-OKRDTBN4.js.map} +1 -1
  56. package/dist/esm/{search-worker-inside-generated-string-2SRY6LLB.js → search-worker-inside-generated-string-BOLAH6BY.js} +45 -36
  57. package/dist/esm/search-worker-inside-generated-string-BOLAH6BY.js.map +7 -0
  58. package/dist/esm/search-worker-js-entry-XBNFXQ5S.js +17 -0
  59. package/dist/esm/{search-worker-ts-entry-D3F64FG2.js → search-worker-ts-entry-ERCMEK5N.js} +4 -4
  60. package/dist/esm/{search-worker-ts-entry-D3F64FG2.js.map → search-worker-ts-entry-ERCMEK5N.js.map} +1 -1
  61. package/dist/esm/stream/index.js +1 -1
  62. package/dist/esm/twisty/index.js +179 -34
  63. package/dist/esm/twisty/index.js.map +3 -3
  64. package/dist/esm/{twisty-dynamic-3d-2TN37YPE.js → twisty-dynamic-3d-GJKWHMDR.js} +40 -6
  65. package/dist/esm/twisty-dynamic-3d-GJKWHMDR.js.map +7 -0
  66. package/dist/esm/{twsearch-BDAXZGZU-WI6J7JNA.js → twsearch-BDAXZGZU-4Y6SSRS3.js} +1 -1
  67. package/dist/esm/{twsearch-BDAXZGZU-WI6J7JNA.js.map → twsearch-BDAXZGZU-4Y6SSRS3.js.map} +1 -1
  68. package/dist/esm/{twsearch-DGXZZNDD.js → twsearch-GXY4U67H.js} +3 -3
  69. package/dist/esm/{twsearch-DGXZZNDD.js.map → twsearch-GXY4U67H.js.map} +1 -1
  70. package/dist/types/{TwizzleLink-9f92123d.d.ts → TwizzleLink-f8f2c814.d.ts} +17 -17
  71. package/dist/types/notation/index.d.ts +1 -1
  72. package/dist/types/puzzles/index.d.ts +2 -2
  73. package/dist/types/twisty/index.d.ts +2 -2
  74. package/package.json +17 -17
  75. package/dist/esm/chunk-6FGST3DR.js.map +0 -7
  76. package/dist/esm/chunk-6KPOQHQA.js.map +0 -7
  77. package/dist/esm/chunk-HVZKPYTG.js.map +0 -7
  78. package/dist/esm/chunk-TZLV35JV.js.map +0 -7
  79. package/dist/esm/chunk-YU62MHVH.js.map +0 -7
  80. package/dist/esm/search-dynamic-sgs-side-events-T2RBUDFD.js.map +0 -7
  81. package/dist/esm/search-dynamic-sgs-unofficial-TJXF7BKM.js.map +0 -7
  82. package/dist/esm/search-worker-inside-generated-string-2SRY6LLB.js.map +0 -7
  83. package/dist/esm/search-worker-js-entry-CLLXI4HB.js +0 -17
  84. package/dist/esm/twisty-dynamic-3d-2TN37YPE.js.map +0 -7
  85. /package/dist/esm/{search-worker-js-entry-CLLXI4HB.js.map → search-worker-js-entry-XBNFXQ5S.js.map} +0 -0
@@ -18,22 +18,22 @@ import {
18
18
  rawRenderPooled,
19
19
  setCameraFromOrbitCoordinates,
20
20
  setTwistyDebug
21
- } from "../chunk-LFMH7YXT.js";
21
+ } from "../chunk-OZ7BVDDY.js";
22
22
  import {
23
23
  countAnimatedLeaves,
24
24
  countMetricMoves,
25
25
  countMoves
26
- } from "../chunk-JVS2MAXS.js";
26
+ } from "../chunk-EXWFZEJA.js";
27
27
  import {
28
28
  cube3x3x3,
29
29
  puzzles
30
- } from "../chunk-6FGST3DR.js";
30
+ } from "../chunk-TF2GO5ZC.js";
31
31
  import {
32
32
  customPGPuzzleLoader,
33
33
  getPartialAppendOptionsForPuzzleSpecificSimplifyOptions,
34
34
  getPieceStickeringMask
35
- } from "../chunk-YU62MHVH.js";
36
- import "../chunk-LZTD2XRZ.js";
35
+ } from "../chunk-7C5DKKWG.js";
36
+ import "../chunk-UOAT7IN5.js";
37
37
  import {
38
38
  Alg,
39
39
  AlgBuilder,
@@ -47,7 +47,7 @@ import {
47
47
  directedGenerator,
48
48
  experimentalAppendMove,
49
49
  functionFromTraversal
50
- } from "../chunk-HVZKPYTG.js";
50
+ } from "../chunk-CFNRQVBC.js";
51
51
 
52
52
  // src/cubing/twisty/controllers/AnimationTypes.ts
53
53
  function directionScalar(direction) {
@@ -146,6 +146,7 @@ var CatchUpHelper = class {
146
146
  var TwistyAnimationController = class {
147
147
  constructor(model, delegate) {
148
148
  this.delegate = delegate;
149
+ // TODO: #private?
149
150
  this.playing = false;
150
151
  this.direction = 1 /* Forwards */;
151
152
  this.lastDatestamp = 0;
@@ -159,11 +160,13 @@ var TwistyAnimationController = class {
159
160
  this.catchUpHelper = new CatchUpHelper(this.model);
160
161
  this.model.catchUpMove.addFreshListener(this.onCatchUpMoveProp.bind(this));
161
162
  }
163
+ // TODO: Do we need this?
162
164
  async onPlayingProp(playingInfo) {
163
165
  if (playingInfo.playing !== this.playing) {
164
166
  playingInfo.playing ? this.play(playingInfo) : this.pause();
165
167
  }
166
168
  }
169
+ // TODO: Do we need this?
167
170
  async onCatchUpMoveProp(catchUpMove) {
168
171
  const catchingUp = catchUpMove.move !== null;
169
172
  if (catchingUp !== this.catchUpHelper.catchingUp) {
@@ -174,6 +177,7 @@ var TwistyAnimationController = class {
174
177
  async #effectiveTimestampMilliseconds() {
175
178
  return (await this.model.detailedTimelineInfo.get()).timestamp;
176
179
  }
180
+ // TODO: Return the animation we've switched to.
177
181
  jumpToStart(options) {
178
182
  this.model.timestampRequest.set("start");
179
183
  this.pause();
@@ -181,6 +185,7 @@ var TwistyAnimationController = class {
181
185
  this.delegate.flash();
182
186
  }
183
187
  }
188
+ // TODO: Return the animation we've switched to.
184
189
  jumpToEnd(options) {
185
190
  this.model.timestampRequest.set("end");
186
191
  this.pause();
@@ -188,6 +193,7 @@ var TwistyAnimationController = class {
188
193
  this.delegate.flash();
189
194
  }
190
195
  }
196
+ // TODO: Return the playing info we've switched to.
191
197
  playPause() {
192
198
  if (this.playing) {
193
199
  this.pause();
@@ -195,6 +201,7 @@ var TwistyAnimationController = class {
195
201
  this.play();
196
202
  }
197
203
  }
204
+ // TODO: bundle playing direction, and boundary into `toggle`.
198
205
  async play(options) {
199
206
  const direction = options?.direction ?? 1 /* Forwards */;
200
207
  const coarseTimelineInfo = await this.model.coarseTimelineInfo.get();
@@ -332,6 +339,7 @@ var TwistyPlayerController = class {
332
339
  // src/cubing/twisty/model/props/viewer/ControlPanelProp.ts
333
340
  var controlsLocations = {
334
341
  "bottom-row": true,
342
+ // default
335
343
  none: true
336
344
  };
337
345
  var ControlPanelProp = class extends SimpleTwistyPropSource {
@@ -398,6 +406,7 @@ var colorMaps = {
398
406
  limegreen: "#008800",
399
407
  red: "#660000",
400
408
  "rgb(34, 102, 255)": "#000088",
409
+ // TODO
401
410
  yellow: "#888800",
402
411
  "rgb(102, 0, 153)": "rgb(50, 0, 76)",
403
412
  purple: "#3f003f"
@@ -483,6 +492,7 @@ var KPuzzleSVGWrapper = class {
483
492
  drawState(state, nextState, fraction) {
484
493
  this.draw(state, nextState, fraction);
485
494
  }
495
+ // TODO: save definition in the constructor?
486
496
  draw(state, nextState, fraction) {
487
497
  const transformation = state.experimentalToTransformation();
488
498
  const nextTransformation = nextState?.experimentalToTransformation();
@@ -636,6 +646,7 @@ svg {
636
646
 
637
647
  // src/cubing/twisty/views/2D/Twisty2DPuzzle.ts
638
648
  var Twisty2DPuzzle = class extends ManagedCustomElement {
649
+ // TODO: pull when needed.
639
650
  constructor(model, kpuzzle, svgSource, options, puzzleLoader) {
640
651
  super();
641
652
  this.model = model;
@@ -704,6 +715,7 @@ var Twisty2DPuzzle = class extends ManagedCustomElement {
704
715
  experimentalSetStickeringMask(stickeringMask) {
705
716
  this.resetSVG(stickeringMask);
706
717
  }
718
+ // TODO: do this without constructing a new SVG.
707
719
  resetSVG(stickeringMask) {
708
720
  if (this.svgWrapper) {
709
721
  this.removeElement(this.svgWrapper.wrapperElement);
@@ -747,9 +759,11 @@ var Twisty2DPuzzleWrapper = class {
747
759
  disconnect() {
748
760
  this.#freshListenerManager.disconnect();
749
761
  }
762
+ // TODO: Hook this up nicely.
750
763
  scheduleRender() {
751
764
  }
752
765
  #cachedTwisty2DPuzzle = null;
766
+ // TODO: Stale dropper?
753
767
  async twisty2DPuzzle() {
754
768
  return this.#cachedTwisty2DPuzzle ?? (this.#cachedTwisty2DPuzzle = (async () => {
755
769
  const svgPromise = this.effectiveVisualization === "experimental-2D-LL" ? this.puzzleLoader.llSVG() : this.puzzleLoader.svg();
@@ -795,6 +809,7 @@ var Twisty2DSceneWrapper = class extends ManagedCustomElement {
795
809
  currentTwisty2DPuzzleWrapper() {
796
810
  return this.#currentTwisty2DPuzzleWrapper;
797
811
  }
812
+ // #oldTwisty3DPuzzleWrappers: Twisty3DPuzzleWrapper[] = []; // TODO: Animate these out.
798
813
  async setCurrentTwisty2DPuzzleWrapper(twisty2DPuzzleWrapper) {
799
814
  const old = this.#currentTwisty2DPuzzleWrapper;
800
815
  this.#currentTwisty2DPuzzleWrapper = twisty2DPuzzleWrapper;
@@ -818,18 +833,21 @@ customElementsShim.define("twisty-2d-scene-wrapper", Twisty2DSceneWrapper);
818
833
 
819
834
  // src/cubing/twisty/views/ClassListManager.ts
820
835
  var ClassListManager = class {
836
+ // The prefix should ideally end in a dash.
821
837
  constructor(elem, prefix, validSuffixes) {
822
838
  this.elem = elem;
823
839
  this.prefix = prefix;
824
840
  this.validSuffixes = validSuffixes;
825
841
  }
826
842
  #currentClassName = null;
843
+ // Does nothing if there was no value.
827
844
  clearValue() {
828
845
  if (this.#currentClassName) {
829
846
  this.elem.contentWrapper.classList.remove(this.#currentClassName);
830
847
  }
831
848
  this.#currentClassName = null;
832
849
  }
850
+ // Returns if the value changed
833
851
  setValue(suffix) {
834
852
  if (!this.validSuffixes.includes(suffix)) {
835
853
  throw new Error(`Invalid suffix: ${suffix}`);
@@ -848,6 +866,7 @@ var ClassListManager = class {
848
866
  // src/cubing/twisty/views/InitialValueTracker.ts
849
867
  var InitialValueTracker = class {
850
868
  constructor() {
869
+ // TODO: AbortController?
851
870
  this.promise = new Promise((resolve, reject) => {
852
871
  this.#resolve = resolve;
853
872
  this.reject = reject;
@@ -986,6 +1005,7 @@ var Twisty3DPuzzleWrapper = class extends EventTarget {
986
1005
  hintFacelets === "auto" ? "floating" : hintFacelets,
987
1006
  faceletScale,
988
1007
  this.puzzleLoader.id === "kilominx"
1008
+ // TODO: generalize to other puzzles
989
1009
  );
990
1010
  pg3d.then(
991
1011
  (p) => p.experimentalUpdateTexture(
@@ -1130,6 +1150,7 @@ var Twisty3DSceneWrapper = class extends ManagedCustomElement {
1130
1150
  }
1131
1151
  }
1132
1152
  #currentTwisty3DPuzzleWrapper = null;
1153
+ // #oldTwisty3DPuzzleWrappers: Twisty3DPuzzleWrapper[] = []; // TODO: Animate these out.
1133
1154
  async setCurrentTwisty3DPuzzleWrapper(scene, twisty3DPuzzleWrapper) {
1134
1155
  const old = this.#currentTwisty3DPuzzleWrapper;
1135
1156
  try {
@@ -1144,6 +1165,7 @@ var Twisty3DSceneWrapper = class extends ManagedCustomElement {
1144
1165
  this.#initialWrapperTracker.handleNewValue(twisty3DPuzzleWrapper);
1145
1166
  }
1146
1167
  #initialWrapperTracker = new InitialValueTracker();
1168
+ /** @deprecated */
1147
1169
  async experimentalTwisty3DPuzzleWrapper() {
1148
1170
  return this.#currentTwisty3DPuzzleWrapper || this.#initialWrapperTracker.promise;
1149
1171
  }
@@ -1157,6 +1179,7 @@ var Twisty3DSceneWrapper = class extends ManagedCustomElement {
1157
1179
  Promise.all([
1158
1180
  this.scene(),
1159
1181
  new Twisty3DPuzzleWrapper(this.model, this, inputs[0], inputs[1])
1182
+ // TODO
1160
1183
  ])
1161
1184
  );
1162
1185
  this.setCurrentTwisty3DPuzzleWrapper(scene, twisty3DPuzzleWrapper);
@@ -1337,11 +1360,17 @@ var buttonIcons = [
1337
1360
  "twizzle-tw"
1338
1361
  ];
1339
1362
  var ButtonAppearanceProp = class extends TwistyPropDerived {
1363
+ // TODO: This still seems to fire twice for play/pause?
1340
1364
  derive(inputs) {
1341
1365
  const buttonAppearances = {
1342
1366
  fullscreen: {
1367
+ // TODO: Cache?// TODO: Cache?
1343
1368
  enabled: fullscreenEnabled,
1344
- icon: document.fullscreenElement === null ? "enter-fullscreen" : "exit-fullscreen",
1369
+ icon: (
1370
+ // TODO: Check against the expected element?
1371
+ // TODO: This will *not* update when we enter/leave fullscreen. We need to work more closely with the controller.
1372
+ document.fullscreenElement === null ? "enter-fullscreen" : "exit-fullscreen"
1373
+ ),
1345
1374
  title: "Enter fullscreen"
1346
1375
  },
1347
1376
  "jump-to-start": {
@@ -1391,6 +1420,7 @@ var buttonCommands = {
1391
1420
  "twizzle-link": true
1392
1421
  };
1393
1422
  var TwistyButtons = class extends ManagedCustomElement {
1423
+ // TODO: Privacy
1394
1424
  constructor(model, controller, defaultFullscreenElement) {
1395
1425
  super();
1396
1426
  this.model = model;
@@ -1412,8 +1442,8 @@ var TwistyButtons = class extends ManagedCustomElement {
1412
1442
  }
1413
1443
  this.buttons = buttons;
1414
1444
  this.model?.buttonAppearance.addFreshListener(this.update.bind(this));
1415
- this.model?.twistySceneModel.darkMode.addFreshListener(
1416
- this.updateDarkMode.bind(this)
1445
+ this.model?.twistySceneModel.colorScheme.addFreshListener(
1446
+ this.updateColorScheme.bind(this)
1417
1447
  );
1418
1448
  }
1419
1449
  #onCommand(command) {
@@ -1456,6 +1486,8 @@ var TwistyButtons = class extends ManagedCustomElement {
1456
1486
  throw new Error("Missing command");
1457
1487
  }
1458
1488
  }
1489
+ // TODO: Should we have a prop, or a way to query if we're fullscreen?
1490
+ // https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullScreen
1459
1491
  async onFullscreenButton() {
1460
1492
  if (!this.defaultFullscreenElement) {
1461
1493
  throw new Error("Attempted to go fullscreen without an element.");
@@ -1486,9 +1518,9 @@ var TwistyButtons = class extends ManagedCustomElement {
1486
1518
  button.hidden = !!info.hidden;
1487
1519
  }
1488
1520
  }
1489
- updateDarkMode(darkMode) {
1521
+ updateColorScheme(colorScheme) {
1490
1522
  for (const button of Object.values(this.buttons ?? {})) {
1491
- button.updateDarkMode(darkMode);
1523
+ button.updateColorScheme(colorScheme);
1492
1524
  }
1493
1525
  }
1494
1526
  };
@@ -1503,8 +1535,9 @@ var TwistyButton = class extends ManagedCustomElement {
1503
1535
  buttonIcons
1504
1536
  );
1505
1537
  }
1506
- updateDarkMode(darkMode) {
1507
- this.contentWrapper.classList.toggle("dark-mode", darkMode === "dark");
1538
+ // TODO: async?
1539
+ updateColorScheme(colorScheme) {
1540
+ this.contentWrapper.classList.toggle("dark-mode", colorScheme === "dark");
1508
1541
  }
1509
1542
  connectedCallback() {
1510
1543
  this.addCSS(buttonCSS);
@@ -1601,12 +1634,12 @@ var TwistyScrubber = class extends ManagedCustomElement {
1601
1634
  async connectedCallback() {
1602
1635
  this.addCSS(twistyScrubberCSS);
1603
1636
  this.addElement(await this.inputElem());
1604
- this.model?.twistySceneModel.darkMode.addFreshListener(
1605
- this.updateDarkMode.bind(this)
1637
+ this.model?.twistySceneModel.colorScheme.addFreshListener(
1638
+ this.updateColorScheme.bind(this)
1606
1639
  );
1607
1640
  }
1608
- updateDarkMode(darkMode) {
1609
- this.contentWrapper.classList.toggle("dark-mode", darkMode === "dark");
1641
+ updateColorScheme(colorScheme) {
1642
+ this.contentWrapper.classList.toggle("dark-mode", colorScheme === "dark");
1610
1643
  }
1611
1644
  #inputElem = null;
1612
1645
  async inputElem() {
@@ -1692,7 +1725,9 @@ async function screenshot(model, options) {
1692
1725
  puzzleLoader,
1693
1726
  visualizationStrategy,
1694
1727
  _stickering,
1728
+ // TODO
1695
1729
  _stickeringMaskRequest,
1730
+ // TODO
1696
1731
  _legacyPosition,
1697
1732
  orbitCoordinates
1698
1733
  ] = await Promise.all([
@@ -1865,6 +1900,7 @@ var AlgIssues = class {
1865
1900
  errors: this.errors.concat(issues?.errors ?? [])
1866
1901
  });
1867
1902
  }
1903
+ /** @deprecated */
1868
1904
  log() {
1869
1905
  if (this.errors.length > 0) {
1870
1906
  console.error(`\u{1F6A8} ${this.errors[0]}`);
@@ -1994,7 +2030,9 @@ var CurrentMoveInfoProp = class extends TwistyPropDerived {
1994
2030
  direction: -1 /* Backwards */,
1995
2031
  fraction: 1 - inputs.catchUpMove.amount,
1996
2032
  startTimestamp: -1,
2033
+ // TODO
1997
2034
  endTimestamp: -1
2035
+ // TODO
1998
2036
  });
1999
2037
  }
2000
2038
  return currentMoveInfo;
@@ -2084,6 +2122,7 @@ function defaultDurationForAmount(amount) {
2084
2122
  }
2085
2123
  }
2086
2124
  var AlgDuration = class extends TraversalUp {
2125
+ // TODO: Pass durationForAmount as Down type instead?
2087
2126
  constructor(durationForAmount = defaultDurationForAmount) {
2088
2127
  super();
2089
2128
  this.durationForAmount = durationForAmount;
@@ -2122,6 +2161,7 @@ var AlgDuration = class extends TraversalUp {
2122
2161
  var SimpleAlgIndexer = class {
2123
2162
  constructor(kpuzzle, alg) {
2124
2163
  this.kpuzzle = kpuzzle;
2164
+ // TODO: Allow custom `durationFn`.
2125
2165
  this.durationFn = new AlgDuration(
2126
2166
  defaultDurationForAmount
2127
2167
  );
@@ -2278,6 +2318,7 @@ var LocalSimulMoves = class extends TraversalUp {
2278
2318
  {
2279
2319
  animLeafAlgNode: pause,
2280
2320
  msUntilNext: duration,
2321
+ // TODO
2281
2322
  duration
2282
2323
  }
2283
2324
  ];
@@ -2354,6 +2395,7 @@ var demos = {
2354
2395
  ]
2355
2396
  };
2356
2397
  var SimultaneousMoveIndexer = class {
2398
+ // TODO: Allow custom `durationFn`.
2357
2399
  constructor(kpuzzle, alg) {
2358
2400
  this.kpuzzle = kpuzzle;
2359
2401
  this.animLeaves = demos[alg.toString()] ?? simulMoves(alg);
@@ -2397,6 +2439,7 @@ var SimultaneousMoveIndexer = class {
2397
2439
  movesInProgress: currentMoveInfo.currentMoves
2398
2440
  };
2399
2441
  }
2442
+ // TODO: Caching
2400
2443
  currentMoveInfo(timestamp) {
2401
2444
  let windowEarliestTimestamp = Infinity;
2402
2445
  for (const leafWithRange of this.animLeaves) {
@@ -2862,6 +2905,7 @@ var ChunkAlgs = class extends TraversalUp {
2862
2905
  return new Grouping(
2863
2906
  this.traverseAlg(grouping.alg),
2864
2907
  grouping.amount
2908
+ // TODO
2865
2909
  );
2866
2910
  }
2867
2911
  traverseMove(move) {
@@ -2931,6 +2975,9 @@ var TreeAlgIndexer = class {
2931
2975
  this.walker.st
2932
2976
  );
2933
2977
  }
2978
+ // TransformAtIndex does not reflect the start state; it only reflects
2979
+ // the change from the start state to the current move index. If you
2980
+ // want the actual state, use stateAtIndex.
2934
2981
  transformationAtIndex(index) {
2935
2982
  this.walker.moveByIndex(index);
2936
2983
  return this.walker.st;
@@ -3202,6 +3249,7 @@ var TimestampRequestProp = class extends SimpleTwistyPropSource {
3202
3249
  // src/cubing/twisty/model/props/viewer/BackViewProp.ts
3203
3250
  var backViewLayouts = {
3204
3251
  none: true,
3252
+ // default
3205
3253
  "side-by-side": true,
3206
3254
  "top-right": true
3207
3255
  };
@@ -3353,6 +3401,7 @@ var StickeringMaskProp = class extends TwistyPropDerived {
3353
3401
  inputs.stickeringRequest ?? "full"
3354
3402
  ) ?? fullStickeringMask(inputs.puzzleLoader);
3355
3403
  }
3404
+ // TODO: Implement canReuseValue?
3356
3405
  };
3357
3406
 
3358
3407
  // src/cubing/twisty/model/props/puzzle/display/parseSerializedStickeringMask.ts
@@ -3360,12 +3409,18 @@ var charMap = {
3360
3409
  "-": "Regular" /* Regular */,
3361
3410
  D: "Dim" /* Dim */,
3362
3411
  I: "Ignored" /* Ignored */,
3412
+ // o: ExperimentalPieceStickering.OrientationStickers, // TODO: hack for centers
3363
3413
  X: "Invisible" /* Invisible */,
3364
3414
  O: "IgnoreNonPrimary" /* IgnoreNonPrimary */,
3415
+ // orient color known
3365
3416
  P: "PermuteNonPrimary" /* PermuteNonPrimary */,
3417
+ // Example: PLL
3366
3418
  o: "Ignoriented" /* Ignoriented */,
3419
+ // Example: LL edges during CLS
3367
3420
  "?": "OrientationWithoutPermutation" /* OrientationWithoutPermutation */,
3421
+ // ACube: ignore position
3368
3422
  "@": "Regular" /* Regular */
3423
+ // ACube: ignore orientation // TODO: distinguish from "regular"
3369
3424
  };
3370
3425
  function parseSerializedStickeringMask(serializedStickeringMask) {
3371
3426
  const stickeringMask = {
@@ -3440,15 +3495,15 @@ var BackgroundProp = class extends SimpleTwistyPropSource {
3440
3495
  }
3441
3496
  };
3442
3497
 
3443
- // src/cubing/twisty/model/props/viewer/DarkModeProp.ts
3444
- var DarkModeProp = class extends TwistyPropDerived {
3498
+ // src/cubing/twisty/model/props/viewer/ColorSchemeProp.ts
3499
+ var ColorSchemeProp = class extends TwistyPropDerived {
3445
3500
  derive(inputs) {
3446
- return inputs.darkModeRequest === "dark" ? "dark" : "light";
3501
+ return inputs.colorSchemeRequest === "dark" ? "dark" : "light";
3447
3502
  }
3448
3503
  };
3449
3504
 
3450
- // src/cubing/twisty/model/props/viewer/DarkModeRequestProp.ts
3451
- var DarkModeRequstProp = class extends SimpleTwistyPropSource {
3505
+ // src/cubing/twisty/model/props/viewer/ColorSchemeRequestProp.ts
3506
+ var ColorSchemeRequstProp = class extends SimpleTwistyPropSource {
3452
3507
  getDefaultValue() {
3453
3508
  return "auto";
3454
3509
  }
@@ -3580,8 +3635,9 @@ function defaultCameraOrbitCoordinates(puzzleID, strategy) {
3580
3635
  var TwistySceneModel = class {
3581
3636
  constructor(twistyPlayerModel) {
3582
3637
  this.twistyPlayerModel = twistyPlayerModel;
3638
+ // Depth 0
3583
3639
  this.background = new BackgroundProp();
3584
- this.darkModeRequest = new DarkModeRequstProp();
3640
+ this.colorSchemeRequest = new ColorSchemeRequstProp();
3585
3641
  this.dragInput = new DragInputProp();
3586
3642
  this.foundationDisplay = new FoundationDisplayProp();
3587
3643
  this.foundationStickerSpriteURL = new URLProp();
@@ -3593,10 +3649,14 @@ var TwistySceneModel = class {
3593
3649
  this.movePressInput = new MovePressInputProp();
3594
3650
  this.movePressCancelOptions = new MovePressCancelOptions();
3595
3651
  this.orbitCoordinatesRequest = new OrbitCoordinatesRequestProp();
3652
+ // `stickeringMaskRequest` takes priority over `stickeringRequest`
3596
3653
  this.stickeringMaskRequest = new StickeringMaskRequestProp();
3597
3654
  this.stickeringRequest = new StickeringRequestProp();
3598
3655
  this.faceletScale = new FaceletScaleProp();
3599
- this.darkMode = new DarkModeProp({ darkModeRequest: this.darkModeRequest });
3656
+ // Depth 1
3657
+ this.colorScheme = new ColorSchemeProp({
3658
+ colorSchemeRequest: this.colorSchemeRequest
3659
+ });
3600
3660
  this.foundationStickerSprite = new SpriteProp({
3601
3661
  spriteURL: this.foundationStickerSpriteURL
3602
3662
  });
@@ -3634,7 +3694,11 @@ var UserVisibleErrorTracker = class extends SimpleTwistyPropSource {
3634
3694
  // src/cubing/twisty/model/TwistyPlayerModel.ts
3635
3695
  var TwistyPlayerModel = class {
3636
3696
  constructor() {
3697
+ // TODO: incorporate error handling into the entire prop graph.
3698
+ // TODO: Make this something that can't get confused with normal props?
3637
3699
  this.userVisibleErrorTracker = new UserVisibleErrorTracker();
3700
+ // TODO: Redistribute and group props with controllers.
3701
+ // Depth 0
3638
3702
  this.alg = new AlgProp();
3639
3703
  this.backView = new BackViewProp();
3640
3704
  this.controlPanel = new ControlPanelProp();
@@ -3650,9 +3714,11 @@ var TwistyPlayerModel = class {
3650
3714
  this.timestampRequest = new TimestampRequestProp();
3651
3715
  this.viewerLink = new ViewerLinkProp();
3652
3716
  this.visualizationFormat = new VisualizationFormatProp();
3717
+ // Metadata
3653
3718
  this.title = new ArbitraryStringProp();
3654
3719
  this.videoURL = new URLProp();
3655
3720
  this.competitionID = new ArbitraryStringProp();
3721
+ // Depth 1
3656
3722
  this.puzzleLoader = new PuzzleLoaderProp(
3657
3723
  {
3658
3724
  puzzleIDRequest: this.puzzleIDRequest,
@@ -3660,8 +3726,10 @@ var TwistyPlayerModel = class {
3660
3726
  },
3661
3727
  this.userVisibleErrorTracker
3662
3728
  );
3729
+ // Depth 2
3663
3730
  this.kpuzzle = new KPuzzleProp({ puzzleLoader: this.puzzleLoader });
3664
3731
  this.puzzleID = new PuzzleIDProp({ puzzleLoader: this.puzzleLoader });
3732
+ // Depth 3
3665
3733
  this.puzzleAlg = new PuzzleAlgProp({
3666
3734
  algWithIssues: this.alg,
3667
3735
  kpuzzle: this.kpuzzle
@@ -3674,6 +3742,7 @@ var TwistyPlayerModel = class {
3674
3742
  visualizationRequest: this.visualizationFormat,
3675
3743
  puzzleID: this.puzzleID
3676
3744
  });
3745
+ // Depth 4
3677
3746
  this.indexerConstructor = new IndexerConstructorProp({
3678
3747
  alg: this.alg,
3679
3748
  puzzle: this.puzzleID,
@@ -3684,11 +3753,13 @@ var TwistyPlayerModel = class {
3684
3753
  setupAlg: this.puzzleSetupAlg,
3685
3754
  kpuzzle: this.kpuzzle
3686
3755
  });
3756
+ // Depth 5
3687
3757
  this.indexer = new IndexerProp({
3688
3758
  indexerConstructor: this.indexerConstructor,
3689
3759
  algWithIssues: this.puzzleAlg,
3690
3760
  kpuzzle: this.kpuzzle
3691
3761
  });
3762
+ // Depth 6
3692
3763
  this.anchorTransformation = new AnchorTransformationProp({
3693
3764
  setupTransformation: this.setupTransformation,
3694
3765
  setupAnchor: this.setupAnchor,
@@ -3698,6 +3769,7 @@ var TwistyPlayerModel = class {
3698
3769
  this.timeRange = new TimeRangeProp({
3699
3770
  indexer: this.indexer
3700
3771
  });
3772
+ // Depth 7
3701
3773
  this.detailedTimelineInfo = new DetailedTimelineInfoProp(
3702
3774
  {
3703
3775
  timestampRequest: this.timestampRequest,
@@ -3706,6 +3778,7 @@ var TwistyPlayerModel = class {
3706
3778
  setupAlg: this.setupAlg
3707
3779
  }
3708
3780
  );
3781
+ // Depth 8
3709
3782
  this.coarseTimelineInfo = new CoarseTimelineInfoProp({
3710
3783
  detailedTimelineInfo: this.detailedTimelineInfo,
3711
3784
  playingInfo: this.playingInfo
@@ -3715,6 +3788,8 @@ var TwistyPlayerModel = class {
3715
3788
  detailedTimelineInfo: this.detailedTimelineInfo,
3716
3789
  catchUpMove: this.catchUpMove
3717
3790
  });
3791
+ // Depth 9
3792
+ // TODO: Inline Twisty3D management.
3718
3793
  this.buttonAppearance = new ButtonAppearanceProp({
3719
3794
  coarseTimelineInfo: this.coarseTimelineInfo,
3720
3795
  viewerLink: this.viewerLink
@@ -3722,11 +3797,13 @@ var TwistyPlayerModel = class {
3722
3797
  this.currentLeavesSimplified = new CurrentLeavesSimplifiedProp({
3723
3798
  currentMoveInfo: this.currentMoveInfo
3724
3799
  });
3800
+ // Depth 10
3725
3801
  this.currentState = new CurrentStateProp({
3726
3802
  anchoredStart: this.anchorTransformation,
3727
3803
  currentLeavesSimplified: this.currentLeavesSimplified,
3728
3804
  indexer: this.indexer
3729
3805
  });
3806
+ // Depth 11
3730
3807
  this.legacyPosition = new LegacyPositionProp({
3731
3808
  currentMoveInfo: this.currentMoveInfo,
3732
3809
  state: this.currentState
@@ -3797,6 +3874,7 @@ var TwistyPlayerModel = class {
3797
3874
  );
3798
3875
  }
3799
3876
  }
3877
+ // TODO: Animate the new move.
3800
3878
  experimentalAddMove(flexibleMove, options) {
3801
3879
  const move = typeof flexibleMove === "string" ? new Move(flexibleMove) : flexibleMove;
3802
3880
  this.alg.set(
@@ -3820,6 +3898,7 @@ var TwistyPlayerModel = class {
3820
3898
  })()
3821
3899
  );
3822
3900
  }
3901
+ // TODO: allow more than 1?
3823
3902
  experimentalRemoveFinalChild() {
3824
3903
  this.alg.set(
3825
3904
  (async () => {
@@ -3929,11 +4008,11 @@ var TwistyPlayerSettable = class extends ManagedCustomElement {
3929
4008
  get background() {
3930
4009
  throw err("background");
3931
4010
  }
3932
- set darkMode(darkMode) {
3933
- this.experimentalModel.twistySceneModel.darkModeRequest.set(darkMode);
4011
+ set colorScheme(colorScheme) {
4012
+ this.experimentalModel.twistySceneModel.colorSchemeRequest.set(colorScheme);
3934
4013
  }
3935
- get darkMode() {
3936
- throw err("darkMode");
4014
+ get colorScheme() {
4015
+ throw err("colorScheme");
3937
4016
  }
3938
4017
  set controlPanel(newControlPanel) {
3939
4018
  this.experimentalModel.controlPanel.set(newControlPanel);
@@ -4081,8 +4160,14 @@ var ExperimentalGetters = class {
4081
4160
  // src/cubing/twisty/views/TwistyPlayer.ts
4082
4161
  var DATA_ATTRIBUTE_PREFIX = "data-";
4083
4162
  var twistyPlayerAttributeMap = {
4163
+ // TODO: We assume each of these can be set using a string or will be automatically converted by JS (e.g. numbers). Can we enforce
4164
+ // that with types? Do we need to add a translation mechanism for things we
4165
+ // don't want to leave settable as strings?
4166
+ // TODO: Enum validation.
4167
+ // Alg
4084
4168
  alg: "alg",
4085
4169
  "experimental-setup-alg": "experimentalSetupAlg",
4170
+ // String-based
4086
4171
  "experimental-setup-anchor": "experimentalSetupAnchor",
4087
4172
  puzzle: "puzzle",
4088
4173
  "experimental-puzzle-description": "experimentalPuzzleDescription",
@@ -4091,21 +4176,25 @@ var twistyPlayerAttributeMap = {
4091
4176
  "experimental-stickering": "experimentalStickering",
4092
4177
  "experimental-stickering-mask-orbits": "experimentalStickeringMaskOrbits",
4093
4178
  background: "background",
4094
- "dark-mode": "darkMode",
4179
+ "color-scheme": "colorScheme",
4095
4180
  "control-panel": "controlPanel",
4096
4181
  "back-view": "backView",
4097
4182
  "experimental-initial-hint-facelets-animation": "experimentalInitialHintFaceletsAnimation",
4183
+ // "indexer": "indexer",
4098
4184
  "viewer-link": "viewerLink",
4099
4185
  "experimental-move-press-input": "experimentalMovePressInput",
4100
4186
  "experimental-drag-input": "experimentalDragInput",
4187
+ // Metadata
4101
4188
  "experimental-title": "experimentalTitle",
4102
4189
  "experimental-video-url": "experimentalVideoURL",
4103
4190
  "experimental-competition-id": "experimentalCompetitionID",
4191
+ // Number-based
4104
4192
  "camera-latitude": "cameraLatitude",
4105
4193
  "camera-longitude": "cameraLongitude",
4106
4194
  "camera-distance": "cameraDistance",
4107
4195
  "camera-latitude-limit": "cameraLatitudeLimit",
4108
4196
  "tempo-scale": "tempoScale",
4197
+ // URL-based
4109
4198
  "experimental-sprite": "experimentalSprite",
4110
4199
  "experimental-hint-sprite": "experimentalHintSprite"
4111
4200
  };
@@ -4116,6 +4205,8 @@ var propOnly = {
4116
4205
  experimentalMovePressCancelOptions: true
4117
4206
  };
4118
4207
  var TwistyPlayer = class extends TwistyPlayerSettable {
4208
+ // #onCanvasClick() {
4209
+ // }
4119
4210
  constructor(config = {}) {
4120
4211
  super();
4121
4212
  this.controller = new TwistyPlayerController(
@@ -4132,7 +4223,9 @@ var TwistyPlayer = class extends TwistyPlayerSettable {
4132
4223
  )
4133
4224
  );
4134
4225
  this.#visualizationWrapperElem = document.createElement("div");
4226
+ // TODO: Better pattern.
4135
4227
  this.#errorElem = document.createElement("div");
4228
+ // TODO: Better pattern.
4136
4229
  this.#alreadyConnected = false;
4137
4230
  this.#flashLevel = "auto";
4138
4231
  this.#visualizationWrapper = null;
@@ -4150,6 +4243,7 @@ var TwistyPlayer = class extends TwistyPlayerSettable {
4150
4243
  #visualizationWrapperElem;
4151
4244
  #errorElem;
4152
4245
  #alreadyConnected;
4246
+ // TODO: support resetting
4153
4247
  async connectedCallback() {
4154
4248
  if (this.#alreadyConnected) {
4155
4249
  return;
@@ -4193,11 +4287,11 @@ var TwistyPlayer = class extends TwistyPlayerSettable {
4193
4287
  );
4194
4288
  }
4195
4289
  );
4196
- this.experimentalModel.twistySceneModel.darkMode.addFreshListener(
4197
- (darkModeTheme) => {
4290
+ this.experimentalModel.twistySceneModel.colorScheme.addFreshListener(
4291
+ (colorScheme) => {
4198
4292
  this.contentWrapper.classList.toggle(
4199
4293
  "dark-mode",
4200
- ["dark"].includes(darkModeTheme)
4294
+ ["dark"].includes(colorScheme)
4201
4295
  );
4202
4296
  }
4203
4297
  );
@@ -4212,6 +4306,7 @@ var TwistyPlayer = class extends TwistyPlayerSettable {
4212
4306
  this.experimentalModel.puzzleID.addFreshListener(this.flash.bind(this));
4213
4307
  }
4214
4308
  #flashLevel;
4309
+ /** @deprecated */
4215
4310
  experimentalSetFlashLevel(newLevel) {
4216
4311
  this.#flashLevel = newLevel;
4217
4312
  }
@@ -4270,6 +4365,28 @@ var TwistyPlayer = class extends TwistyPlayerSettable {
4270
4365
  }
4271
4366
  return canvases;
4272
4367
  }
4368
+ /**
4369
+ * Get the first available puzzle `Object3D`. This can be inserted into
4370
+ * another `three.js` scene, essentially "adopting" it from the
4371
+ * `TwistyPlayer`'s scenes while still allowing the `TwistyPlayer` to animate
4372
+ * it. The function returns a `Promise` that returns if and when the
4373
+ * `Object3D` is available, and accepts a callback that is called whenever a
4374
+ * render is scheduled for the puzzle (essentially, if something about the
4375
+ * puzzle has changed, like its appearance or current animated state).
4376
+ *
4377
+ * Note:
4378
+ * - This may never resolve if the player never creates the relevant 3D object
4379
+ * under the hood (e.g. if the config is set to 2D, or is not valid for
4380
+ * rendering a puzzle)
4381
+ * - The architecture of `cubing.js` may change significantly, so it is not
4382
+ * guaranteed that a `three.js` `Object3D` will be available from the main
4383
+ * thread in the future.
4384
+ * - This function only returns the current `three.js` puzzle object (once one
4385
+ * exists). If you change e.g. the `puzzle` config for the player, then the
4386
+ * object will currently become stale. This may be replaced with more
4387
+ * convenient behaviour in the future.
4388
+ *
4389
+ * @deprecated */
4273
4390
  async experimentalCurrentThreeJSPuzzleObject(puzzleRenderScheduledCallback) {
4274
4391
  this.connectedCallback();
4275
4392
  const sceneWrapper = await this.#initial3DVisualizationWrapper.promise;
@@ -4304,12 +4421,20 @@ var TwistyPlayer = class extends TwistyPlayerSettable {
4304
4421
  pause() {
4305
4422
  this.controller.togglePlay(false);
4306
4423
  }
4424
+ // Inspiration:
4425
+ // - https://developer.mozilla.org/en-US/docs/Web/API/Element/toggleAttribute (`force` argument)
4426
+ // - https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/toggle (`force` argument)
4427
+ // We still provide `play()` and `pause()` individually for convenience, though.
4307
4428
  togglePlay(play) {
4308
4429
  this.controller.togglePlay(play);
4309
4430
  }
4431
+ // TODO: Animate the new move.
4432
+ // TODO: Automatically handle puzzle.
4310
4433
  experimentalAddMove(flexibleMove, options) {
4311
4434
  this.experimentalModel.experimentalAddMove(flexibleMove, options);
4312
4435
  }
4436
+ // TODO: Animate the new move.
4437
+ // TODO: Automatically handle puzzle.
4313
4438
  experimentalAddAlgLeaf(algLeaf, options) {
4314
4439
  this.experimentalModel.experimentalAddAlgLeaf(algLeaf, options);
4315
4440
  }
@@ -4333,9 +4458,13 @@ var TwistyPlayer = class extends TwistyPlayerSettable {
4333
4458
  }
4334
4459
  this[setterName] = newValue;
4335
4460
  }
4461
+ // TODO: Make this more ergonomic and flexible.
4462
+ // TODO: dimensions.
4336
4463
  async experimentalScreenshot(options) {
4337
4464
  return (await screenshot(this.experimentalModel, options)).dataURL;
4338
4465
  }
4466
+ // TODO: Make this more ergonomic and flexible.
4467
+ // TODO: dimensions.
4339
4468
  async experimentalDownloadScreenshot(filename) {
4340
4469
  if (["2D", "experimental-2D-LL"].includes(
4341
4470
  await this.experimentalModel.visualizationStrategy.get()
@@ -4534,6 +4663,7 @@ var AlgToDOMTree = class extends TraversalDownUp {
4534
4663
  moveCount: 1,
4535
4664
  element: new TwistyAlgLeafElem(
4536
4665
  "twisty-alg-move",
4666
+ // TODO: Mark the tuple with a special class?
4537
4667
  square1Tuple[0].amount.toString(),
4538
4668
  dataDown,
4539
4669
  square1Tuple[0],
@@ -4546,6 +4676,7 @@ var AlgToDOMTree = class extends TraversalDownUp {
4546
4676
  moveCount: 1,
4547
4677
  element: new TwistyAlgLeafElem(
4548
4678
  "twisty-alg-move",
4679
+ // TODO: Mark the tuple with a special class?
4549
4680
  square1Tuple[1].amount.toString(),
4550
4681
  dataDown,
4551
4682
  square1Tuple[1],
@@ -4786,6 +4917,7 @@ var TwistyAlgViewer = class extends HTMLElementShim {
4786
4917
  })();
4787
4918
  twistyPlayer.experimentalModel.timestampRequest.set(
4788
4919
  await timestampPromise
4920
+ // TODO
4789
4921
  );
4790
4922
  if (this.lastClickTimestamp === await timestampPromise) {
4791
4923
  twistyPlayer.play();
@@ -4897,6 +5029,7 @@ var AlgEditorAlgWithIssuesProp = class extends TwistyPropDerived {
4897
5029
  derive(input) {
4898
5030
  return algWithIssuesFromString(input.value);
4899
5031
  }
5032
+ // TODO: canReuse needs to take the source string into account.
4900
5033
  };
4901
5034
  var TwistyAlgEditorSelectionProp = class extends TwistyPropSource {
4902
5035
  getDefaultValue() {
@@ -5065,17 +5198,21 @@ var TwistyAlgEditor = class extends ManagedCustomElement {
5065
5198
  constructor(options) {
5066
5199
  super();
5067
5200
  this.model = new TwistyAlgEditorModel();
5201
+ // #alg: Alg = new Alg();
5068
5202
  this.#textarea = document.createElement("textarea");
5069
5203
  this.#carbonCopy = document.createElement("div");
5070
5204
  this.#carbonCopyPrefix = document.createElement("span");
5071
5205
  this.#carbonCopyHighlight = document.createElement("span");
5072
5206
  this.#carbonCopySuffix = document.createElement("span");
5207
+ // #textareaClassListManager: ClassListManager<"none" | "warning" | "error"> =
5208
+ // new ClassListManager(this, "issue-", ["none", "warning", "error"]);
5073
5209
  this.#textareaClassListValidForPuzzleManager = new ClassListManager(this, "valid-for-puzzle-", [
5074
5210
  "none",
5075
5211
  "warning",
5076
5212
  "error"
5077
5213
  ]);
5078
5214
  this.#twistyPlayer = null;
5215
+ // Temporary Workaround for Twizzle Explorer
5079
5216
  this.debugNeverRequestTimestamp = false;
5080
5217
  this.#onInputHasFired = false;
5081
5218
  this.#highlightedLeaf = null;
@@ -5130,13 +5267,16 @@ var TwistyAlgEditor = class extends ManagedCustomElement {
5130
5267
  return this.#twistyPlayer.experimentalModel[this.#twistyPlayerProp];
5131
5268
  }
5132
5269
  }
5270
+ // TODO
5133
5271
  set algString(s) {
5134
5272
  this.#textarea.value = s;
5135
5273
  this.onInput();
5136
5274
  }
5275
+ // TODO: remove?
5137
5276
  get algString() {
5138
5277
  return this.#textarea.value;
5139
5278
  }
5279
+ // To we need a getter?
5140
5280
  set placeholder(placeholderText) {
5141
5281
  this.#textarea.placeholder = placeholderText;
5142
5282
  }
@@ -5166,10 +5306,13 @@ var TwistyAlgEditor = class extends ManagedCustomElement {
5166
5306
  setAlgIssueClassForPuzzle(issues) {
5167
5307
  this.#textareaClassListValidForPuzzleManager.setValue(issues);
5168
5308
  }
5309
+ // `white-space: pre;` mostly matches the formatting of the `<textarea>`, *except* when we end with a newline.
5310
+ // So we add an space to ensure that there is a character on the final line (that is very unlikely to trigger extra line wrapping).
5169
5311
  #padSuffix(s) {
5170
5312
  return s.endsWith("\n") ? `${s} ` : s;
5171
5313
  }
5172
5314
  #highlightedLeaf;
5315
+ // TODO: support a primary highlighted move and secondary ones.
5173
5316
  highlightLeaf(leaf) {
5174
5317
  if (this.#twistyPlayerProp !== "alg") {
5175
5318
  return;
@@ -5202,6 +5345,7 @@ var TwistyAlgEditor = class extends ManagedCustomElement {
5202
5345
  get twistyPlayer() {
5203
5346
  return this.#twistyPlayer;
5204
5347
  }
5348
+ // TODO: spread out this impl over private methods instead of self-listeners.
5205
5349
  set twistyPlayer(twistyPlayer) {
5206
5350
  if (this.#twistyPlayer) {
5207
5351
  console.warn("twisty-player reassignment/clearing is not supported");
@@ -5219,6 +5363,7 @@ var TwistyAlgEditor = class extends ManagedCustomElement {
5219
5363
  (algWithIssues) => {
5220
5364
  if (algWithIssues.issues.errors.length === 0) {
5221
5365
  this.setAlgIssueClassForPuzzle(
5366
+ // TODO: Allow trailing spaces.
5222
5367
  algWithIssues.issues.warnings.length === 0 ? "none" : "warning"
5223
5368
  );
5224
5369
  const newAlg = algWithIssues.alg;
@@ -5566,7 +5711,7 @@ var TwizzleLink = class extends ManagedCustomElement {
5566
5711
  async connectedCallback() {
5567
5712
  this.#responsiveWrapper = this.addElement(document.createElement("div"));
5568
5713
  this.#responsiveWrapper.classList.add("responsive-wrapper");
5569
- if (this.options?.darkMode) {
5714
+ if (this.options?.colorScheme) {
5570
5715
  this.contentWrapper.classList.add("dark-mode");
5571
5716
  }
5572
5717
  this.#cssElem = this.addCSS(twizzleLinkCSS);
@@ -5594,7 +5739,7 @@ var TwizzleLink = class extends ManagedCustomElement {
5594
5739
  this.twistyPlayer = this.#responsiveWrapper.appendChild(
5595
5740
  new TwistyPlayer({
5596
5741
  background: this.options?.cdnForumTweaks ? "checkered-transparent" : "checkered",
5597
- darkMode: this.options?.darkMode ? "dark" : "light",
5742
+ colorScheme: this.options?.colorScheme ? "dark" : "light",
5598
5743
  ...config,
5599
5744
  viewerLink: isExplorer ? "experimental-twizzle-explorer" : "auto"
5600
5745
  })