@rednaxela101/cubing 0.63.5

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 (136) hide show
  1. package/README.md +120 -0
  2. package/alg/index.d.ts +1 -0
  3. package/bluetooth/index.d.ts +1 -0
  4. package/dist/bin/chunks/chunk-22VWCGBC.js +13 -0
  5. package/dist/bin/chunks/chunk-22VWCGBC.js.map +7 -0
  6. package/dist/bin/order.js +59 -0
  7. package/dist/bin/order.js.map +7 -0
  8. package/dist/bin/puzzle-geometry-bin.js +407 -0
  9. package/dist/bin/puzzle-geometry-bin.js.map +7 -0
  10. package/dist/bin/scramble.js +188 -0
  11. package/dist/bin/scramble.js.map +7 -0
  12. package/dist/bin/svg.js +56 -0
  13. package/dist/bin/svg.js.map +7 -0
  14. package/dist/lib/cubing/alg/index.d.ts +2 -0
  15. package/dist/lib/cubing/alg/index.js +43 -0
  16. package/dist/lib/cubing/alg/index.js.map +7 -0
  17. package/dist/lib/cubing/bluetooth/index.d.ts +189 -0
  18. package/dist/lib/cubing/bluetooth/index.js +2271 -0
  19. package/dist/lib/cubing/bluetooth/index.js.map +7 -0
  20. package/dist/lib/cubing/chunks/big-puzzle-orientation-BA6QHO5C.js +68 -0
  21. package/dist/lib/cubing/chunks/big-puzzle-orientation-BA6QHO5C.js.map +7 -0
  22. package/dist/lib/cubing/chunks/chunk-2VJB4TMH.js +1774 -0
  23. package/dist/lib/cubing/chunks/chunk-2VJB4TMH.js.map +7 -0
  24. package/dist/lib/cubing/chunks/chunk-52ZXJEUO.js +665 -0
  25. package/dist/lib/cubing/chunks/chunk-52ZXJEUO.js.map +7 -0
  26. package/dist/lib/cubing/chunks/chunk-56VZAEPF.js +274 -0
  27. package/dist/lib/cubing/chunks/chunk-56VZAEPF.js.map +7 -0
  28. package/dist/lib/cubing/chunks/chunk-7GUL3OBQ.js +9 -0
  29. package/dist/lib/cubing/chunks/chunk-7GUL3OBQ.js.map +7 -0
  30. package/dist/lib/cubing/chunks/chunk-7L7BJSIM.js +21 -0
  31. package/dist/lib/cubing/chunks/chunk-7L7BJSIM.js.map +7 -0
  32. package/dist/lib/cubing/chunks/chunk-AESPJKN6.js +265 -0
  33. package/dist/lib/cubing/chunks/chunk-AESPJKN6.js.map +7 -0
  34. package/dist/lib/cubing/chunks/chunk-C2Q347XS.js +89 -0
  35. package/dist/lib/cubing/chunks/chunk-C2Q347XS.js.map +7 -0
  36. package/dist/lib/cubing/chunks/chunk-CGBMJBU3.js +1195 -0
  37. package/dist/lib/cubing/chunks/chunk-CGBMJBU3.js.map +7 -0
  38. package/dist/lib/cubing/chunks/chunk-HZQONEMD.js +249 -0
  39. package/dist/lib/cubing/chunks/chunk-HZQONEMD.js.map +7 -0
  40. package/dist/lib/cubing/chunks/chunk-IAGCVPL3.js +1069 -0
  41. package/dist/lib/cubing/chunks/chunk-IAGCVPL3.js.map +7 -0
  42. package/dist/lib/cubing/chunks/chunk-NAPITA3L.js +1 -0
  43. package/dist/lib/cubing/chunks/chunk-NAPITA3L.js.map +7 -0
  44. package/dist/lib/cubing/chunks/chunk-XPDJUSZ7.js +1876 -0
  45. package/dist/lib/cubing/chunks/chunk-XPDJUSZ7.js.map +7 -0
  46. package/dist/lib/cubing/chunks/chunk-YSI6PF35.js +619 -0
  47. package/dist/lib/cubing/chunks/chunk-YSI6PF35.js.map +7 -0
  48. package/dist/lib/cubing/chunks/inside-LG2EAKCL.js +557 -0
  49. package/dist/lib/cubing/chunks/inside-LG2EAKCL.js.map +7 -0
  50. package/dist/lib/cubing/chunks/puzzles-dynamic-2x2x2-JYJJXB4V.js +142 -0
  51. package/dist/lib/cubing/chunks/puzzles-dynamic-2x2x2-JYJJXB4V.js.map +7 -0
  52. package/dist/lib/cubing/chunks/puzzles-dynamic-3x3x3-FYXD7SIU.js +365 -0
  53. package/dist/lib/cubing/chunks/puzzles-dynamic-3x3x3-FYXD7SIU.js.map +7 -0
  54. package/dist/lib/cubing/chunks/puzzles-dynamic-4x4x4-AIGABOAR.js +132 -0
  55. package/dist/lib/cubing/chunks/puzzles-dynamic-4x4x4-AIGABOAR.js.map +7 -0
  56. package/dist/lib/cubing/chunks/puzzles-dynamic-5x5x5-JUNRX27W.js +277 -0
  57. package/dist/lib/cubing/chunks/puzzles-dynamic-5x5x5-JUNRX27W.js.map +7 -0
  58. package/dist/lib/cubing/chunks/puzzles-dynamic-clock-USGQTDPO.js +836 -0
  59. package/dist/lib/cubing/chunks/puzzles-dynamic-clock-USGQTDPO.js.map +7 -0
  60. package/dist/lib/cubing/chunks/puzzles-dynamic-fto-WJHMLYCJ.js +100 -0
  61. package/dist/lib/cubing/chunks/puzzles-dynamic-fto-WJHMLYCJ.js.map +7 -0
  62. package/dist/lib/cubing/chunks/puzzles-dynamic-megaminx-2LVHIDL4.js +224 -0
  63. package/dist/lib/cubing/chunks/puzzles-dynamic-megaminx-2LVHIDL4.js.map +7 -0
  64. package/dist/lib/cubing/chunks/puzzles-dynamic-pyraminx-7UWX4HHI.js +93 -0
  65. package/dist/lib/cubing/chunks/puzzles-dynamic-pyraminx-7UWX4HHI.js.map +7 -0
  66. package/dist/lib/cubing/chunks/puzzles-dynamic-square1-PQEKBPFN.js +842 -0
  67. package/dist/lib/cubing/chunks/puzzles-dynamic-square1-PQEKBPFN.js.map +7 -0
  68. package/dist/lib/cubing/chunks/search-dynamic-sgs-2x2x2-XFKQ4VJS.js +125 -0
  69. package/dist/lib/cubing/chunks/search-dynamic-sgs-2x2x2-XFKQ4VJS.js.map +7 -0
  70. package/dist/lib/cubing/chunks/search-dynamic-sgs-megaminx-ZDOOLEDW.js +1564 -0
  71. package/dist/lib/cubing/chunks/search-dynamic-sgs-megaminx-ZDOOLEDW.js.map +7 -0
  72. package/dist/lib/cubing/chunks/search-dynamic-sgs-pyraminx-W6UJWBYY.js +108 -0
  73. package/dist/lib/cubing/chunks/search-dynamic-sgs-pyraminx-W6UJWBYY.js.map +7 -0
  74. package/dist/lib/cubing/chunks/search-dynamic-sgs-skewb-FXGKV4KD.js +125 -0
  75. package/dist/lib/cubing/chunks/search-dynamic-sgs-skewb-FXGKV4KD.js.map +7 -0
  76. package/dist/lib/cubing/chunks/search-dynamic-sgs-unofficial-YK6HA7BK.js +644 -0
  77. package/dist/lib/cubing/chunks/search-dynamic-sgs-unofficial-YK6HA7BK.js.map +7 -0
  78. package/dist/lib/cubing/chunks/search-dynamic-solve-3x3x3-DLMAGPXS.js +2549 -0
  79. package/dist/lib/cubing/chunks/search-dynamic-solve-3x3x3-DLMAGPXS.js.map +7 -0
  80. package/dist/lib/cubing/chunks/search-dynamic-solve-4x4x4-NONXQHOJ.js +2923 -0
  81. package/dist/lib/cubing/chunks/search-dynamic-solve-4x4x4-NONXQHOJ.js.map +7 -0
  82. package/dist/lib/cubing/chunks/search-dynamic-solve-fto-3GQ2HLSW.js +1405 -0
  83. package/dist/lib/cubing/chunks/search-dynamic-solve-fto-3GQ2HLSW.js.map +7 -0
  84. package/dist/lib/cubing/chunks/search-worker-entry.js +19 -0
  85. package/dist/lib/cubing/chunks/search-worker-entry.js.map +7 -0
  86. package/dist/lib/cubing/chunks/square1-stickerings-W2ZLZWIN.js +73 -0
  87. package/dist/lib/cubing/chunks/square1-stickerings-W2ZLZWIN.js.map +7 -0
  88. package/dist/lib/cubing/chunks/twips-2RNTWYNZ.js +433 -0
  89. package/dist/lib/cubing/chunks/twips-2RNTWYNZ.js.map +7 -0
  90. package/dist/lib/cubing/chunks/twips_wasm_bg-TJNYGA2C-23XTPLIK.js +10 -0
  91. package/dist/lib/cubing/chunks/twips_wasm_bg-TJNYGA2C-23XTPLIK.js.map +7 -0
  92. package/dist/lib/cubing/chunks/twisty-dynamic-3d-JO6OGKOF.js +2424 -0
  93. package/dist/lib/cubing/chunks/twisty-dynamic-3d-JO6OGKOF.js.map +7 -0
  94. package/dist/lib/cubing/index-BX6f56uo.d.ts +76 -0
  95. package/dist/lib/cubing/index-CcRu94bx.d.ts +2622 -0
  96. package/dist/lib/cubing/kpuzzle/index.d.ts +2 -0
  97. package/dist/lib/cubing/kpuzzle/index.js +12 -0
  98. package/dist/lib/cubing/kpuzzle/index.js.map +7 -0
  99. package/dist/lib/cubing/notation/index.d.ts +32 -0
  100. package/dist/lib/cubing/notation/index.js +20 -0
  101. package/dist/lib/cubing/notation/index.js.map +7 -0
  102. package/dist/lib/cubing/outside-BCzgSYQ_.d.ts +38 -0
  103. package/dist/lib/cubing/protocol/index.d.ts +28 -0
  104. package/dist/lib/cubing/protocol/index.js +20 -0
  105. package/dist/lib/cubing/protocol/index.js.map +7 -0
  106. package/dist/lib/cubing/puzzle-geometry/index.d.ts +2 -0
  107. package/dist/lib/cubing/puzzle-geometry/index.js +5024 -0
  108. package/dist/lib/cubing/puzzle-geometry/index.js.map +7 -0
  109. package/dist/lib/cubing/puzzles/index.d.ts +2 -0
  110. package/dist/lib/cubing/puzzles/index.js +23 -0
  111. package/dist/lib/cubing/puzzles/index.js.map +7 -0
  112. package/dist/lib/cubing/scramble/index.d.ts +2 -0
  113. package/dist/lib/cubing/scramble/index.js +16 -0
  114. package/dist/lib/cubing/scramble/index.js.map +7 -0
  115. package/dist/lib/cubing/search/index.d.ts +7 -0
  116. package/dist/lib/cubing/search/index.js +37 -0
  117. package/dist/lib/cubing/search/index.js.map +7 -0
  118. package/dist/lib/cubing/stream/index.d.ts +2 -0
  119. package/dist/lib/cubing/stream/index.js +111 -0
  120. package/dist/lib/cubing/stream/index.js.map +7 -0
  121. package/dist/lib/cubing/twisty/index.d.ts +2 -0
  122. package/dist/lib/cubing/twisty/index.js +6236 -0
  123. package/dist/lib/cubing/twisty/index.js.map +7 -0
  124. package/experimental-json-schema/kpuzzle/KPatternData.schema.json +34 -0
  125. package/experimental-json-schema/kpuzzle/KPuzzleDefinition.schema.json +97 -0
  126. package/experimental-json-schema/kpuzzle/KTransformationData.schema.json +27 -0
  127. package/kpuzzle/index.d.ts +1 -0
  128. package/notation/index.d.ts +1 -0
  129. package/package.json +146 -0
  130. package/protocol/index.d.ts +1 -0
  131. package/puzzle-geometry/index.d.ts +1 -0
  132. package/puzzles/index.d.ts +1 -0
  133. package/scramble/index.d.ts +1 -0
  134. package/search/index.d.ts +1 -0
  135. package/stream/index.d.ts +1 -0
  136. package/twisty/index.d.ts +1 -0
@@ -0,0 +1,1195 @@
1
+ import {
2
+ LazyPromise
3
+ } from "./chunk-2VJB4TMH.js";
4
+
5
+ // src/cubing/twisty/debug.ts
6
+ var twistyDebugGlobals = {
7
+ shareAllNewRenderers: "auto",
8
+ showRenderStats: false
9
+ };
10
+ function setTwistyDebug(options) {
11
+ for (const [key, value] of Object.entries(options)) {
12
+ if (key in twistyDebugGlobals) {
13
+ twistyDebugGlobals[key] = value;
14
+ }
15
+ }
16
+ }
17
+
18
+ // src/cubing/twisty/model/PromiseFreshener.ts
19
+ var StaleDropper = class {
20
+ #latestAssignedIdx = 0;
21
+ #latestResolvedIdx = 0;
22
+ queue(p) {
23
+ return new Promise(async (resolve, reject) => {
24
+ try {
25
+ const idx = ++this.#latestAssignedIdx;
26
+ const result = await p;
27
+ if (idx > this.#latestResolvedIdx) {
28
+ this.#latestResolvedIdx = idx;
29
+ resolve(result);
30
+ }
31
+ } catch (e) {
32
+ reject(e);
33
+ }
34
+ });
35
+ }
36
+ };
37
+
38
+ // src/cubing/twisty/model/props/TwistyProp.ts
39
+ var globalSourceGeneration = 0;
40
+ var TwistyPropParent = class {
41
+ // Don't overwrite this. Overwrite `canReuseValue` instead.
42
+ canReuse(v1, v2) {
43
+ return v1 === v2 || this.canReuseValue(v1, v2);
44
+ }
45
+ // Overwrite with a cheap semantic comparison when possible.
46
+ // Note that this is not called if `v1 === v2` (in which case the value is automatically reused).
47
+ canReuseValue(_v1, _v2) {
48
+ return false;
49
+ }
50
+ debugGetChildren() {
51
+ return Array.from(this.#children.values());
52
+ }
53
+ // Propagation
54
+ #children = /* @__PURE__ */ new Set();
55
+ addChild(child) {
56
+ this.#children.add(child);
57
+ }
58
+ removeChild(child) {
59
+ this.#children.delete(child);
60
+ }
61
+ lastSourceGeneration = 0;
62
+ // Synchronously marks all descendants as stale. This doesn't actually
63
+ // literally mark as stale, but it updates the last source generation, which
64
+ // is used to tell if a cahced result is stale.
65
+ markStale(sourceEvent) {
66
+ if (sourceEvent.detail.generation !== globalSourceGeneration) {
67
+ throw new Error("A TwistyProp was marked stale too late!");
68
+ }
69
+ if (this.lastSourceGeneration === sourceEvent.detail.generation) {
70
+ return;
71
+ }
72
+ this.lastSourceGeneration = sourceEvent.detail.generation;
73
+ for (const child of this.#children) {
74
+ child.markStale(sourceEvent);
75
+ }
76
+ this.#scheduleRawDispatch();
77
+ }
78
+ #rawListeners = /* @__PURE__ */ new Set();
79
+ /** @deprecated */
80
+ addRawListener(listener, options) {
81
+ this.#rawListeners.add(listener);
82
+ if (options?.initial) {
83
+ listener();
84
+ }
85
+ }
86
+ /** @deprecated */
87
+ removeRawListener(listener) {
88
+ this.#rawListeners.delete(listener);
89
+ }
90
+ /** @deprecated */
91
+ #scheduleRawDispatch() {
92
+ if (!this.#rawDispatchPending) {
93
+ this.#rawDispatchPending = true;
94
+ setTimeout(() => this.#dispatchRawListeners(), 0);
95
+ }
96
+ }
97
+ #rawDispatchPending = false;
98
+ #dispatchRawListeners() {
99
+ if (!this.#rawDispatchPending) {
100
+ throw new Error("Invalid dispatch state!");
101
+ }
102
+ for (const listener of this.#rawListeners) {
103
+ listener();
104
+ }
105
+ this.#rawDispatchPending = false;
106
+ }
107
+ #freshListeners = /* @__PURE__ */ new Map();
108
+ // TODO: Pick a better name.
109
+ addFreshListener(listener) {
110
+ const staleDropper = new StaleDropper();
111
+ let lastResult = null;
112
+ const callback = async () => {
113
+ const result = await staleDropper.queue(this.get());
114
+ if (lastResult !== null && this.canReuse(lastResult, result)) {
115
+ return;
116
+ }
117
+ lastResult = result;
118
+ listener(result);
119
+ };
120
+ this.#freshListeners.set(listener, callback);
121
+ this.addRawListener(callback, { initial: true });
122
+ }
123
+ removeFreshListener(listener) {
124
+ this.removeRawListener(this.#freshListeners.get(listener));
125
+ this.#freshListeners.delete(listener);
126
+ }
127
+ };
128
+ var TwistyPropSource = class extends TwistyPropParent {
129
+ #value;
130
+ constructor(initialValue) {
131
+ super();
132
+ this.#value = new LazyPromise(async () => this.getDefaultValue());
133
+ if (initialValue) {
134
+ this.#value = this.deriveFromPromiseOrValue(initialValue, this.#value);
135
+ }
136
+ }
137
+ set(input) {
138
+ this.#value = this.deriveFromPromiseOrValue(input, this.#value);
139
+ const sourceEventDetail = {
140
+ sourceProp: this,
141
+ value: this.#value,
142
+ generation: ++globalSourceGeneration
143
+ };
144
+ this.markStale(
145
+ new CustomEvent("stale", {
146
+ detail: sourceEventDetail
147
+ })
148
+ );
149
+ }
150
+ async get() {
151
+ return this.#value;
152
+ }
153
+ async deriveFromPromiseOrValue(input, oldValuePromise) {
154
+ return this.derive(await input, oldValuePromise);
155
+ }
156
+ };
157
+ var SimpleTwistyPropSource = class extends TwistyPropSource {
158
+ derive(input) {
159
+ return input;
160
+ }
161
+ };
162
+ var NO_VALUE = /* @__PURE__ */ Symbol("no value");
163
+ var TwistyPropDerived = class extends TwistyPropParent {
164
+ constructor(parents, userVisibleErrorTracker) {
165
+ super();
166
+ this.userVisibleErrorTracker = userVisibleErrorTracker;
167
+ this.#parents = parents;
168
+ for (const parent of Object.values(parents)) {
169
+ parent.addChild(this);
170
+ }
171
+ }
172
+ userVisibleErrorTracker;
173
+ // cachedInputs:
174
+ #parents;
175
+ #cachedLastSuccessfulCalculation = null;
176
+ #cachedLatestGenerationCalculation = null;
177
+ async get() {
178
+ const generation = this.lastSourceGeneration;
179
+ if (this.#cachedLatestGenerationCalculation?.generation === generation) {
180
+ return this.#cachedLatestGenerationCalculation.output;
181
+ }
182
+ const latestGenerationCalculation = {
183
+ generation,
184
+ output: this.#cacheDerive(
185
+ this.#getParents(),
186
+ generation,
187
+ this.#cachedLastSuccessfulCalculation
188
+ )
189
+ };
190
+ this.#cachedLatestGenerationCalculation = latestGenerationCalculation;
191
+ this.userVisibleErrorTracker?.reset();
192
+ return latestGenerationCalculation.output;
193
+ }
194
+ async #getParents() {
195
+ const inputValuePromises = {};
196
+ for (const [key, parent] of Object.entries(this.#parents)) {
197
+ inputValuePromises[key] = parent.get();
198
+ }
199
+ const inputs = {};
200
+ for (const key in this.#parents) {
201
+ inputs[key] = await inputValuePromises[key];
202
+ }
203
+ return inputs;
204
+ }
205
+ async #cacheDerive(inputsPromise, generation, cachedLatestGenerationCalculation = null) {
206
+ const inputs = await inputsPromise;
207
+ const cache = (output) => {
208
+ this.#cachedLastSuccessfulCalculation = {
209
+ inputs,
210
+ output: Promise.resolve(output),
211
+ generation
212
+ };
213
+ return output;
214
+ };
215
+ if (!cachedLatestGenerationCalculation) {
216
+ return cache(await this.derive(inputs));
217
+ }
218
+ const cachedInputs = cachedLatestGenerationCalculation.inputs;
219
+ for (const key in this.#parents) {
220
+ const parent = this.#parents[key];
221
+ if (!parent.canReuse(inputs[key], cachedInputs[key])) {
222
+ return cache(await this.derive(inputs));
223
+ }
224
+ }
225
+ return cachedLatestGenerationCalculation.output;
226
+ }
227
+ };
228
+ var FreshListenerManager = class {
229
+ #disconnectionFunctions = [];
230
+ addListener(prop, listener) {
231
+ let disconnected = false;
232
+ const wrappedListener = (value) => {
233
+ if (disconnected) {
234
+ return;
235
+ }
236
+ listener(value);
237
+ };
238
+ prop.addFreshListener(wrappedListener);
239
+ this.#disconnectionFunctions.push(() => {
240
+ prop.removeFreshListener(wrappedListener);
241
+ disconnected = true;
242
+ });
243
+ }
244
+ // TODO: Figure out the signature to let us do overloads
245
+ /** @deprecated */
246
+ addMultiListener3(props, listener) {
247
+ this.addMultiListener(props, listener);
248
+ }
249
+ addMultiListener(props, listener) {
250
+ let disconnected = false;
251
+ let initialIgnoresLeft = props.length - 1;
252
+ const wrappedListener = async (_) => {
253
+ if (initialIgnoresLeft > 0) {
254
+ initialIgnoresLeft--;
255
+ return;
256
+ }
257
+ if (disconnected) {
258
+ return;
259
+ }
260
+ const promises = props.map(
261
+ (prop) => prop.get()
262
+ );
263
+ const values = await Promise.all(promises);
264
+ listener(values);
265
+ };
266
+ for (const prop of props) {
267
+ prop.addFreshListener(wrappedListener);
268
+ }
269
+ this.#disconnectionFunctions.push(() => {
270
+ for (const prop of props) {
271
+ prop.removeFreshListener(wrappedListener);
272
+ }
273
+ disconnected = true;
274
+ });
275
+ }
276
+ disconnect() {
277
+ for (const disconnectionFunction of this.#disconnectionFunctions) {
278
+ disconnectionFunction();
279
+ }
280
+ }
281
+ };
282
+
283
+ // src/cubing/twisty/views/node-custom-element-shims.ts
284
+ var HTMLElementStub = class {
285
+ };
286
+ var HTMLElementShim;
287
+ if (globalThis.HTMLElement) {
288
+ HTMLElementShim = globalThis.HTMLElement;
289
+ } else {
290
+ HTMLElementShim = HTMLElementStub;
291
+ }
292
+ var CustomElementsStub = class {
293
+ define() {
294
+ }
295
+ };
296
+ var customElementsShim;
297
+ if (globalThis.customElements) {
298
+ customElementsShim = globalThis.customElements;
299
+ } else {
300
+ customElementsShim = new CustomElementsStub();
301
+ }
302
+ var cssStyleSheetShim;
303
+ var CSSStyleSheetStub = class {
304
+ replaceSync() {
305
+ }
306
+ };
307
+ if (globalThis.CSSStyleSheet) {
308
+ cssStyleSheetShim = globalThis.CSSStyleSheet;
309
+ } else {
310
+ cssStyleSheetShim = CSSStyleSheetStub;
311
+ }
312
+
313
+ // src/cubing/twisty/views/ManagedCustomElement.ts
314
+ var ManagedCustomElement = class extends HTMLElementShim {
315
+ shadow;
316
+ // TODO: hide this
317
+ contentWrapper;
318
+ // TODO: can we get rid of this wrapper?
319
+ constructor(options) {
320
+ super();
321
+ this.shadow = this.attachShadow({ mode: options?.mode ?? "closed" });
322
+ this.contentWrapper = document.createElement("div");
323
+ this.contentWrapper.classList.add("wrapper");
324
+ this.shadow.appendChild(this.contentWrapper);
325
+ }
326
+ // Add the source, if not already added.
327
+ // Returns the existing if it's already on the element.
328
+ addCSS(cssSource) {
329
+ this.shadow.adoptedStyleSheets.push(cssSource);
330
+ }
331
+ removeCSS(cssSource) {
332
+ const cssIndex = this.shadow.adoptedStyleSheets.indexOf(cssSource);
333
+ if (typeof cssIndex !== "undefined") {
334
+ this.shadow.adoptedStyleSheets.splice(cssIndex, cssIndex + 1);
335
+ }
336
+ }
337
+ addElement(element) {
338
+ return this.contentWrapper.appendChild(element);
339
+ }
340
+ prependElement(element) {
341
+ this.contentWrapper.prepend(element);
342
+ }
343
+ removeElement(element) {
344
+ return this.contentWrapper.removeChild(element);
345
+ }
346
+ };
347
+ customElementsShim.define(
348
+ "twisty-managed-custom-element",
349
+ ManagedCustomElement
350
+ );
351
+
352
+ // src/cubing/twisty/controllers/RenderScheduler.ts
353
+ var RenderScheduler = class {
354
+ constructor(callback) {
355
+ this.callback = callback;
356
+ }
357
+ callback;
358
+ animFrameID = null;
359
+ animFrame = this.animFrameWrapper.bind(this);
360
+ requestIsPending() {
361
+ return !!this.animFrameID;
362
+ }
363
+ requestAnimFrame() {
364
+ if (!this.animFrameID) {
365
+ this.animFrameID = requestAnimationFrame(this.animFrame);
366
+ }
367
+ }
368
+ cancelAnimFrame() {
369
+ if (this.animFrameID) {
370
+ cancelAnimationFrame(this.animFrameID);
371
+ this.animFrameID = 0;
372
+ }
373
+ }
374
+ animFrameWrapper(timestamp) {
375
+ this.animFrameID = 0;
376
+ this.callback(timestamp);
377
+ }
378
+ };
379
+
380
+ // src/cubing/twisty/model/props/puzzle/display/HintFaceletProp.ts
381
+ var hintFaceletStyles = {
382
+ floating: true,
383
+ // default
384
+ none: true
385
+ };
386
+ var HintFaceletProp = class extends SimpleTwistyPropSource {
387
+ getDefaultValue() {
388
+ return "auto";
389
+ }
390
+ };
391
+
392
+ // src/cubing/twisty/views/3D/TAU.ts
393
+ var TAU = Math.PI * 2;
394
+ var DEGREES_PER_RADIAN = 360 / TAU;
395
+
396
+ // src/cubing/vendor/mit/three/examples/jsm/libs/stats.modified.module.ts
397
+ var performance = globalThis.performance;
398
+ var Stats = class {
399
+ mode = 0;
400
+ dom = document.createElement("div");
401
+ constructor() {
402
+ this.dom.style.cssText = "position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000";
403
+ this.dom.addEventListener(
404
+ "click",
405
+ (event) => {
406
+ event.preventDefault();
407
+ this.showPanel(++this.mode % this.dom.children.length);
408
+ },
409
+ false
410
+ );
411
+ this.showPanel(0);
412
+ }
413
+ addPanel(panel) {
414
+ this.dom.appendChild(panel.dom);
415
+ return panel;
416
+ }
417
+ showPanel(id) {
418
+ for (let i = 0; i < this.dom.children.length; i++) {
419
+ this.dom.children[i].style.display = i === id ? "block" : "none";
420
+ }
421
+ this.mode = id;
422
+ }
423
+ beginTime = (performance || Date).now();
424
+ prevTime = this.beginTime;
425
+ frames = 0;
426
+ fpsPanel = this.addPanel(new StatsPanel("FPS", "#0ff", "#002"));
427
+ msPanel = this.addPanel(new StatsPanel("MS", "#0f0", "#020"));
428
+ memPanel = performance?.memory ? this.addPanel(new StatsPanel("MB", "#f08", "#201")) : null;
429
+ REVISION = 16;
430
+ begin() {
431
+ this.beginTime = (performance || Date).now();
432
+ }
433
+ end() {
434
+ this.frames++;
435
+ const time = (performance || Date).now();
436
+ this.msPanel.update(time - this.beginTime, 200);
437
+ if (time >= this.prevTime + 1e3) {
438
+ this.fpsPanel.update(this.frames * 1e3 / (time - this.prevTime), 100);
439
+ this.prevTime = time;
440
+ this.frames = 0;
441
+ if (this.memPanel) {
442
+ const memory = performance.memory;
443
+ this.memPanel.update(
444
+ memory.usedJSHeapSize / 1048576,
445
+ memory.jsHeapSizeLimit / 1048576
446
+ );
447
+ }
448
+ }
449
+ return time;
450
+ }
451
+ update() {
452
+ this.beginTime = this.end();
453
+ }
454
+ };
455
+ var PR = Math.round(globalThis?.window?.devicePixelRatio ?? 1);
456
+ var WIDTH = 80 * PR;
457
+ var HEIGHT = 48 * PR;
458
+ var TEXT_X = 3 * PR;
459
+ var TEXT_Y = 2 * PR;
460
+ var GRAPH_X = 3 * PR;
461
+ var GRAPH_Y = 15 * PR;
462
+ var GRAPH_WIDTH = 74 * PR;
463
+ var GRAPH_HEIGHT = 30 * PR;
464
+ var StatsPanel = class {
465
+ constructor(name, fg, bg) {
466
+ this.name = name;
467
+ this.fg = fg;
468
+ this.bg = bg;
469
+ this.dom.width = WIDTH;
470
+ this.dom.height = HEIGHT;
471
+ this.dom.style.cssText = "width:80px;height:48px";
472
+ this.context.font = `bold ${9 * PR}px Helvetica,Arial,sans-serif`;
473
+ this.context.textBaseline = "top";
474
+ this.context.fillStyle = bg;
475
+ this.context.fillRect(0, 0, WIDTH, HEIGHT);
476
+ this.context.fillStyle = fg;
477
+ this.context.fillText(name, TEXT_X, TEXT_Y);
478
+ this.context.fillRect(GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT);
479
+ this.context.fillStyle = bg;
480
+ this.context.globalAlpha = 0.9;
481
+ this.context.fillRect(GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT);
482
+ }
483
+ name;
484
+ fg;
485
+ bg;
486
+ min = Infinity;
487
+ max = 0;
488
+ dom = document.createElement("canvas");
489
+ context = this.dom.getContext("2d");
490
+ update(value, maxValue) {
491
+ this.min = Math.min(this.min, value);
492
+ this.max = Math.max(this.max, value);
493
+ this.context.fillStyle = this.bg;
494
+ this.context.globalAlpha = 1;
495
+ this.context.fillRect(0, 0, WIDTH, GRAPH_Y);
496
+ this.context.fillStyle = this.fg;
497
+ this.context.fillText(
498
+ `${Math.round(value)} ${this.name} (${Math.round(this.min)}-${Math.round(
499
+ this.max
500
+ )})`,
501
+ TEXT_X,
502
+ TEXT_Y
503
+ );
504
+ this.context.drawImage(
505
+ this.dom,
506
+ GRAPH_X + PR,
507
+ GRAPH_Y,
508
+ GRAPH_WIDTH - PR,
509
+ GRAPH_HEIGHT,
510
+ GRAPH_X,
511
+ GRAPH_Y,
512
+ GRAPH_WIDTH - PR,
513
+ GRAPH_HEIGHT
514
+ );
515
+ this.context.fillRect(
516
+ GRAPH_X + GRAPH_WIDTH - PR,
517
+ GRAPH_Y,
518
+ PR,
519
+ GRAPH_HEIGHT
520
+ );
521
+ this.context.fillStyle = this.bg;
522
+ this.context.globalAlpha = 0.9;
523
+ this.context.fillRect(
524
+ GRAPH_X + GRAPH_WIDTH - PR,
525
+ GRAPH_Y,
526
+ PR,
527
+ Math.round((1 - value / maxValue) * GRAPH_HEIGHT)
528
+ );
529
+ }
530
+ };
531
+
532
+ // src/cubing/twisty/heavy-code-imports/3d.ts
533
+ var bulk3DCode = new LazyPromise(
534
+ () => import("./twisty-dynamic-3d-JO6OGKOF.js")
535
+ );
536
+
537
+ // src/cubing/twisty/views/canvas.ts
538
+ var globalPixelRatioOverride = null;
539
+ function pixelRatio() {
540
+ return globalPixelRatioOverride ?? (devicePixelRatio || 1);
541
+ }
542
+
543
+ // src/cubing/twisty/views/3D/DragTracker.ts
544
+ var MOVEMENT_EPSILON = 0.1;
545
+ var DragTracker = class extends EventTarget {
546
+ constructor(target) {
547
+ super();
548
+ this.target = target;
549
+ }
550
+ target;
551
+ #dragInfoMap = /* @__PURE__ */ new Map();
552
+ // Idempotent
553
+ start() {
554
+ this.addTargetListener("pointerdown", this.onPointerDown.bind(this));
555
+ this.addTargetListener("contextmenu", (e) => {
556
+ e.preventDefault();
557
+ });
558
+ this.addTargetListener(
559
+ "touchmove",
560
+ (e) => e.preventDefault()
561
+ );
562
+ this.addTargetListener("dblclick", (e) => e.preventDefault());
563
+ }
564
+ // Idempotent
565
+ stop() {
566
+ for (const [eventType, listener] of this.#targetListeners.entries()) {
567
+ this.target.removeEventListener(
568
+ eventType,
569
+ listener
570
+ );
571
+ }
572
+ this.#targetListeners.clear();
573
+ this.#lazyListenersRegistered = false;
574
+ }
575
+ #targetListeners = /* @__PURE__ */ new Map();
576
+ addTargetListener(eventType, listener) {
577
+ if (!this.#targetListeners.has(eventType)) {
578
+ this.target.addEventListener(
579
+ eventType,
580
+ listener
581
+ // TODO
582
+ );
583
+ this.#targetListeners.set(eventType, listener);
584
+ }
585
+ }
586
+ // This allows us to avoid getting a callback every time the pointer moves over the canvas, until we have a down event.
587
+ // TODO: Ideally we'd also support unregistering when we're certain there are no more active touches. But this means we need to properly handle every way a pointer "click" can end, which is tricky across environments (due to e.g. mouse vs. touch vs. stylues, canvas/viewport/window/scroll boundaries, right-click and other ways of losing focus, etc.), so we conservatively leave the listeners on.
588
+ #lazyListenersRegistered = false;
589
+ #registerLazyListeners() {
590
+ if (this.#lazyListenersRegistered) {
591
+ return;
592
+ }
593
+ this.addTargetListener("pointermove", this.onPointerMove.bind(this));
594
+ this.addTargetListener("pointerup", this.onPointerUp.bind(this));
595
+ this.#lazyListenersRegistered = true;
596
+ }
597
+ #clear(e) {
598
+ this.#dragInfoMap.delete(e.pointerId);
599
+ }
600
+ // `null`: means: ignore this result (no movement, or not
601
+ #trackDrag(e) {
602
+ const existing = this.#dragInfoMap.get(e.pointerId);
603
+ if (!existing) {
604
+ return { movementInfo: null, hasMoved: false };
605
+ }
606
+ let movementInfo;
607
+ if ((e.movementX ?? 0) !== 0 || (e.movementY ?? 0) !== 0) {
608
+ movementInfo = {
609
+ attachedInfo: existing.attachedInfo,
610
+ movementX: e.movementX,
611
+ movementY: e.movementY,
612
+ elapsedMs: e.timeStamp - existing.lastTimeStamp
613
+ };
614
+ } else {
615
+ movementInfo = {
616
+ attachedInfo: existing.attachedInfo,
617
+ movementX: e.clientX - existing.lastClientX,
618
+ movementY: e.clientY - existing.lastClientY,
619
+ elapsedMs: e.timeStamp - existing.lastTimeStamp
620
+ };
621
+ }
622
+ existing.lastClientX = e.clientX;
623
+ existing.lastClientY = e.clientY;
624
+ existing.lastTimeStamp = e.timeStamp;
625
+ if (Math.abs(movementInfo.movementX) < MOVEMENT_EPSILON && Math.abs(movementInfo.movementY) < MOVEMENT_EPSILON) {
626
+ return { movementInfo: null, hasMoved: existing.hasMoved };
627
+ } else {
628
+ existing.hasMoved = true;
629
+ return { movementInfo, hasMoved: existing.hasMoved };
630
+ }
631
+ }
632
+ onPointerDown(e) {
633
+ this.#registerLazyListeners();
634
+ const newDragInfo = {
635
+ attachedInfo: {},
636
+ hasMoved: false,
637
+ lastClientX: e.clientX,
638
+ lastClientY: e.clientY,
639
+ lastTimeStamp: e.timeStamp
640
+ };
641
+ this.#dragInfoMap.set(e.pointerId, newDragInfo);
642
+ this.target.setPointerCapture(e.pointerId);
643
+ }
644
+ onPointerMove(e) {
645
+ const movementInfo = this.#trackDrag(e).movementInfo;
646
+ if (movementInfo) {
647
+ e.preventDefault();
648
+ this.dispatchEvent(
649
+ new CustomEvent("move", {
650
+ detail: movementInfo
651
+ })
652
+ );
653
+ }
654
+ }
655
+ onPointerUp(e) {
656
+ const trackDragResult = this.#trackDrag(e);
657
+ const existing = this.#dragInfoMap.get(e.pointerId);
658
+ this.#clear(e);
659
+ this.target.releasePointerCapture(e.pointerId);
660
+ let event;
661
+ if (trackDragResult.hasMoved) {
662
+ event = new CustomEvent("up", {
663
+ detail: { attachedInfo: existing.attachedInfo }
664
+ });
665
+ } else {
666
+ const { altKey, ctrlKey, metaKey, shiftKey } = e;
667
+ event = new CustomEvent("press", {
668
+ detail: {
669
+ normalizedX: e.offsetX / this.target.offsetWidth * 2 - 1,
670
+ normalizedY: 1 - e.offsetY / this.target.offsetHeight * 2,
671
+ rightClick: !!(e.button & 2),
672
+ keys: {
673
+ altKey,
674
+ ctrlOrMetaKey: ctrlKey || metaKey,
675
+ shiftKey
676
+ }
677
+ }
678
+ });
679
+ }
680
+ this.dispatchEvent(event);
681
+ }
682
+ };
683
+
684
+ // src/cubing/twisty/views/3D/RendererPool.ts
685
+ var renderers = [];
686
+ async function rawRenderPooled(width, height, scene, camera) {
687
+ if (renderers.length === 0) {
688
+ renderers.push(newRenderer());
689
+ }
690
+ const renderer = await renderers[0];
691
+ renderer.setSize(width, height);
692
+ renderer.render(scene, camera);
693
+ return renderer.domElement;
694
+ }
695
+ async function renderPooled(width, height, canvas, scene, camera) {
696
+ if (width === 0 || height === 0) {
697
+ return;
698
+ }
699
+ if (renderers.length === 0) {
700
+ renderers.push(newRenderer());
701
+ }
702
+ const rendererCanvas = await rawRenderPooled(width, height, scene, camera);
703
+ const context = canvas.getContext("2d");
704
+ context.clearRect(0, 0, canvas.width, canvas.height);
705
+ context.drawImage(rendererCanvas, 0, 0);
706
+ }
707
+ var linearSRGBColorSpace = "srgb-linear";
708
+ async function newRenderer() {
709
+ const rendererConstructor = (await bulk3DCode).ThreeWebGLRenderer;
710
+ const renderer = new rendererConstructor({
711
+ antialias: true,
712
+ alpha: true
713
+ });
714
+ renderer.outputColorSpace = linearSRGBColorSpace;
715
+ renderer.setPixelRatio(pixelRatio());
716
+ return renderer;
717
+ }
718
+
719
+ // src/cubing/twisty/views/3D/Twisty3DVantage.css.ts
720
+ var twisty3DVantageCSS = new cssStyleSheetShim();
721
+ twisty3DVantageCSS.replaceSync(
722
+ `
723
+ :host {
724
+ width: 384px;
725
+ height: 256px;
726
+ display: grid;
727
+ }
728
+
729
+ .wrapper {
730
+ width: 100%;
731
+ height: 100%;
732
+ display: grid;
733
+ overflow: hidden;
734
+ place-content: center;
735
+ contain: strict;
736
+ }
737
+
738
+ .loading {
739
+ width: 4em;
740
+ height: 4em;
741
+ border-radius: 2.5em;
742
+ border: 0.5em solid rgba(0, 0, 0, 0);
743
+ border-top: 0.5em solid rgba(0, 0, 0, 0.7);
744
+ border-right: 0.5em solid rgba(0, 0, 0, 0.7);
745
+ animation: fade-in-delayed 4s, rotate 1s linear infinite;
746
+ }
747
+
748
+ @keyframes fade-in-delayed {
749
+ 0% { opacity: 0; }
750
+ 25% {opacity: 0; }
751
+ 100% { opacity: 1; }
752
+ }
753
+
754
+ @keyframes rotate {
755
+ from { transform: rotate(0deg); }
756
+ to { transform: rotate(360deg); }
757
+ }
758
+
759
+ /* TODO: This is due to stats hack. Replace with \`canvas\`. */
760
+ .wrapper > canvas {
761
+ max-width: 100%;
762
+ max-height: 100%;
763
+ animation: fade-in 0.25s ease-in;
764
+ }
765
+
766
+ @keyframes fade-in {
767
+ from { opacity: 0; }
768
+ to { opacity: 1; }
769
+ }
770
+
771
+ .wrapper.invisible {
772
+ opacity: 0;
773
+ }
774
+
775
+ .wrapper.drag-input-enabled > canvas {
776
+ cursor: grab;
777
+ }
778
+
779
+ .wrapper.drag-input-enabled > canvas:active {
780
+ cursor: grabbing;
781
+ }
782
+ `
783
+ );
784
+
785
+ // src/cubing/twisty/views/3D/TwistyOrbitControls.ts
786
+ var INERTIA_DEFAULT = true;
787
+ var INERTIA_DURATION_MS = 500;
788
+ var INERTIA_TIMEOUT_MS = 50;
789
+ var VERTICAL_MOVEMENT_BASE_SCALE = 0.75;
790
+ function momentumScale(progress) {
791
+ return (Math.exp(1 - progress) - (1 - progress)) / (1 - Math.E) + 1;
792
+ }
793
+ var Inertia = class {
794
+ constructor(startTimestamp, momentumX, momentumY, callback) {
795
+ this.startTimestamp = startTimestamp;
796
+ this.momentumX = momentumX;
797
+ this.momentumY = momentumY;
798
+ this.callback = callback;
799
+ this.scheduler.requestAnimFrame();
800
+ this.lastTimestamp = startTimestamp;
801
+ }
802
+ startTimestamp;
803
+ momentumX;
804
+ momentumY;
805
+ callback;
806
+ scheduler = new RenderScheduler(this.render.bind(this));
807
+ lastTimestamp;
808
+ render(now) {
809
+ const progressBefore = (this.lastTimestamp - this.startTimestamp) / INERTIA_DURATION_MS;
810
+ const progressAfter = Math.min(
811
+ 1,
812
+ (now - this.startTimestamp) / INERTIA_DURATION_MS
813
+ );
814
+ if (progressBefore === 0 && progressAfter > INERTIA_TIMEOUT_MS / INERTIA_DURATION_MS) {
815
+ return;
816
+ }
817
+ const delta = momentumScale(progressAfter) - momentumScale(progressBefore);
818
+ this.callback(this.momentumX * delta * 1e3, this.momentumY * delta * 1e3);
819
+ if (progressAfter < 1) {
820
+ this.scheduler.requestAnimFrame();
821
+ }
822
+ this.lastTimestamp = now;
823
+ }
824
+ };
825
+ var TwistyOrbitControls = class {
826
+ constructor(model, mirror, canvas, dragTracker) {
827
+ this.model = model;
828
+ this.mirror = mirror;
829
+ this.canvas = canvas;
830
+ this.dragTracker = dragTracker;
831
+ this.dragTracker.addEventListener(
832
+ "move",
833
+ this.onMove.bind(this)
834
+ // TODO: https://github.com/microsoft/TypeScript/issues/28357
835
+ );
836
+ this.dragTracker.addEventListener(
837
+ "up",
838
+ this.onUp.bind(this)
839
+ // TODO: https://github.com/microsoft/TypeScript/issues/28357
840
+ );
841
+ }
842
+ model;
843
+ mirror;
844
+ canvas;
845
+ dragTracker;
846
+ /** @deprecated */
847
+ experimentalInertia = INERTIA_DEFAULT;
848
+ onMovementBound = this.onMovement.bind(this);
849
+ experimentalHasBeenMoved = false;
850
+ // f is the fraction of the canvas traversed per ms.
851
+ temperMovement(f) {
852
+ return Math.sign(f) * Math.log(Math.abs(f * 10) + 1) / 6;
853
+ }
854
+ onMove(e) {
855
+ e.detail.attachedInfo ??= {};
856
+ const { temperedX, temperedY } = this.onMovement(
857
+ e.detail.movementX,
858
+ e.detail.movementY
859
+ );
860
+ const attachedInfo = e.detail.attachedInfo;
861
+ attachedInfo.lastTemperedX = temperedX * 10;
862
+ attachedInfo.lastTemperedY = temperedY * 10;
863
+ attachedInfo.timestamp = e.timeStamp;
864
+ }
865
+ onMovement(movementX, movementY) {
866
+ const scale = this.mirror ? -1 : 1;
867
+ const minDim = Math.min(this.canvas.offsetWidth, this.canvas.offsetHeight);
868
+ const temperedX = this.temperMovement(movementX / minDim);
869
+ const temperedY = this.temperMovement(
870
+ movementY / minDim * VERTICAL_MOVEMENT_BASE_SCALE
871
+ );
872
+ this.model.twistySceneModel.orbitCoordinatesRequest.set(
873
+ (async () => {
874
+ const prevCoords = await this.model.twistySceneModel.orbitCoordinates.get();
875
+ const newCoords = {
876
+ latitude: prevCoords.latitude + 2 * temperedY * DEGREES_PER_RADIAN * scale,
877
+ longitude: prevCoords.longitude - 2 * temperedX * DEGREES_PER_RADIAN
878
+ };
879
+ return newCoords;
880
+ })()
881
+ );
882
+ return { temperedX, temperedY };
883
+ }
884
+ onUp(e) {
885
+ e.preventDefault();
886
+ if ("lastTemperedX" in e.detail.attachedInfo && "lastTemperedY" in e.detail.attachedInfo && "timestamp" in e.detail.attachedInfo && e.timeStamp - e.detail.attachedInfo["timestamp"] < 60) {
887
+ new Inertia(
888
+ e.timeStamp,
889
+ // TODO
890
+ e.detail.attachedInfo.lastTemperedX,
891
+ e.detail.attachedInfo.lastTemperedY,
892
+ this.onMovementBound
893
+ );
894
+ }
895
+ }
896
+ };
897
+
898
+ // src/cubing/twisty/views/3D/Twisty3DVantage.ts
899
+ async function setCameraFromOrbitCoordinates(camera, orbitCoordinates, backView = false) {
900
+ const spherical = new (await bulk3DCode).ThreeSpherical(
901
+ orbitCoordinates.distance,
902
+ (90 - (backView ? -1 : 1) * orbitCoordinates.latitude) / DEGREES_PER_RADIAN,
903
+ ((backView ? 180 : 0) + orbitCoordinates.longitude) / DEGREES_PER_RADIAN
904
+ );
905
+ spherical.makeSafe();
906
+ camera.position.setFromSpherical(spherical);
907
+ camera.lookAt(0, 0, 0);
908
+ }
909
+ var dedicatedRenderersSoFar = 0;
910
+ var DEFAULT_MAX_DEDICATED_RENDERERS = 2;
911
+ var sharingRenderers = false;
912
+ function shareRenderer() {
913
+ if (twistyDebugGlobals.shareAllNewRenderers !== "auto") {
914
+ if (!twistyDebugGlobals.shareAllNewRenderers) {
915
+ dedicatedRenderersSoFar++;
916
+ }
917
+ return twistyDebugGlobals.shareAllNewRenderers !== "never";
918
+ }
919
+ if (dedicatedRenderersSoFar < DEFAULT_MAX_DEDICATED_RENDERERS) {
920
+ dedicatedRenderersSoFar++;
921
+ return false;
922
+ } else {
923
+ sharingRenderers = true;
924
+ return true;
925
+ }
926
+ }
927
+ function haveStartedSharingRenderers() {
928
+ return sharingRenderers;
929
+ }
930
+ var Twisty3DVantage = class extends ManagedCustomElement {
931
+ constructor(model, scene, options) {
932
+ super();
933
+ this.model = model;
934
+ this.options = options;
935
+ this.scene = scene ?? null;
936
+ this.loadingElement = this.addElement(document.createElement("div"));
937
+ this.loadingElement.classList.add("loading");
938
+ if (twistyDebugGlobals.showRenderStats) {
939
+ this.stats = new Stats();
940
+ this.stats.dom.style.position = "absolute";
941
+ this.contentWrapper.appendChild(this.stats.dom);
942
+ }
943
+ }
944
+ model;
945
+ options;
946
+ scene = null;
947
+ stats = null;
948
+ rendererIsShared = shareRenderer();
949
+ loadingElement = null;
950
+ async connectedCallback() {
951
+ this.addCSS(twisty3DVantageCSS);
952
+ this.addElement((await this.canvasInfo()).canvas);
953
+ void this.#onResize();
954
+ const observer = new ResizeObserver(this.#onResize.bind(this));
955
+ observer.observe(this.contentWrapper);
956
+ void this.orbitControls();
957
+ void this.#setupBasicPresses();
958
+ this.scheduleRender();
959
+ }
960
+ async #setupBasicPresses() {
961
+ const dragTracker = await this.#dragTracker();
962
+ dragTracker.addEventListener(
963
+ "press",
964
+ (async (e) => {
965
+ const movePressInput = await this.model.twistySceneModel.movePressInput.get();
966
+ if (movePressInput !== "basic") {
967
+ return;
968
+ }
969
+ this.dispatchEvent(
970
+ new CustomEvent("press", {
971
+ detail: {
972
+ pressInfo: e.detail,
973
+ cameraPromise: this.camera()
974
+ }
975
+ })
976
+ );
977
+ })
978
+ // TODO
979
+ );
980
+ }
981
+ #onResizeStaleDropper = new StaleDropper();
982
+ async clearCanvas() {
983
+ if (this.rendererIsShared) {
984
+ const canvasInfo = await this.canvasInfo();
985
+ canvasInfo.context.clearRect(
986
+ 0,
987
+ 0,
988
+ canvasInfo.canvas.width,
989
+ canvasInfo.canvas.height
990
+ );
991
+ } else {
992
+ const renderer = await this.renderer();
993
+ const context = renderer.getContext();
994
+ context.clear(context.COLOR_BUFFER_BIT);
995
+ }
996
+ }
997
+ // TODO: Why doesn't this work for the top-right back view height?
998
+ #width = 0;
999
+ #height = 0;
1000
+ async #onResize() {
1001
+ const camera = await this.#onResizeStaleDropper.queue(this.camera());
1002
+ const w = this.contentWrapper.clientWidth;
1003
+ const h = this.contentWrapper.clientHeight;
1004
+ this.#width = w;
1005
+ this.#height = h;
1006
+ const off = 0;
1007
+ let yoff = 0;
1008
+ let excess = 0;
1009
+ if (h > w) {
1010
+ excess = h - w;
1011
+ yoff = -Math.floor(0.5 * excess);
1012
+ }
1013
+ camera.aspect = w / h;
1014
+ camera.setViewOffset(w, h - excess, off, yoff, w, h);
1015
+ camera.updateProjectionMatrix();
1016
+ void this.clearCanvas();
1017
+ if (this.rendererIsShared) {
1018
+ const canvasInfo = await this.canvasInfo();
1019
+ canvasInfo.canvas.width = w * pixelRatio();
1020
+ canvasInfo.canvas.height = h * pixelRatio();
1021
+ canvasInfo.canvas.style.width = `${w.toString()}px`;
1022
+ canvasInfo.canvas.style.height = `${h.toString()}px`;
1023
+ } else {
1024
+ const renderer = await this.renderer();
1025
+ renderer.setSize(w, h, true);
1026
+ }
1027
+ this.scheduleRender();
1028
+ }
1029
+ #cachedRenderer = null;
1030
+ async renderer() {
1031
+ if (this.rendererIsShared) {
1032
+ throw new Error("renderer expected to be shared.");
1033
+ }
1034
+ return this.#cachedRenderer ??= newRenderer();
1035
+ }
1036
+ #cachedCanvas = null;
1037
+ async canvasInfo() {
1038
+ return this.#cachedCanvas ??= (async () => {
1039
+ let canvas;
1040
+ if (this.rendererIsShared) {
1041
+ canvas = this.addElement(document.createElement("canvas"));
1042
+ } else {
1043
+ const renderer = await this.renderer();
1044
+ canvas = this.addElement(renderer.domElement);
1045
+ }
1046
+ this.loadingElement?.remove();
1047
+ const context = canvas.getContext("2d");
1048
+ return { canvas, context };
1049
+ })();
1050
+ }
1051
+ #cachedDragTracker = null;
1052
+ async #dragTracker() {
1053
+ return this.#cachedDragTracker ??= (async () => {
1054
+ const dragTracker = new DragTracker((await this.canvasInfo()).canvas);
1055
+ this.model?.twistySceneModel.dragInput.addFreshListener(
1056
+ (dragInputMode) => {
1057
+ let dragInputEnabled = false;
1058
+ switch (dragInputMode) {
1059
+ case "auto": {
1060
+ dragTracker.start();
1061
+ dragInputEnabled = true;
1062
+ break;
1063
+ }
1064
+ case "none": {
1065
+ dragTracker.stop();
1066
+ break;
1067
+ }
1068
+ }
1069
+ this.contentWrapper.classList.toggle(
1070
+ "drag-input-enabled",
1071
+ dragInputEnabled
1072
+ );
1073
+ }
1074
+ );
1075
+ return dragTracker;
1076
+ })();
1077
+ }
1078
+ #cachedCamera = null;
1079
+ async camera() {
1080
+ return this.#cachedCamera ??= (async () => {
1081
+ const camera = new (await bulk3DCode).ThreePerspectiveCamera(
1082
+ 20,
1083
+ 1,
1084
+ // We rely on the resize logic to handle this.
1085
+ 0.1,
1086
+ 20
1087
+ );
1088
+ camera.position.copy(
1089
+ new (await bulk3DCode).ThreeVector3(2, 4, 4).multiplyScalar(
1090
+ this.options?.backView ? -1 : 1
1091
+ )
1092
+ );
1093
+ camera.lookAt(0, 0, 0);
1094
+ return camera;
1095
+ })();
1096
+ }
1097
+ #cachedOrbitControls = null;
1098
+ async orbitControls() {
1099
+ return this.#cachedOrbitControls ??= (async () => {
1100
+ const orbitControls = new TwistyOrbitControls(
1101
+ this.model,
1102
+ !!this.options?.backView,
1103
+ (await this.canvasInfo()).canvas,
1104
+ await this.#dragTracker()
1105
+ );
1106
+ if (this.model) {
1107
+ this.addListener(
1108
+ this.model.twistySceneModel.orbitCoordinates,
1109
+ async (orbitCoordinates) => {
1110
+ const camera = await this.camera();
1111
+ void setCameraFromOrbitCoordinates(
1112
+ camera,
1113
+ orbitCoordinates,
1114
+ this.options?.backView
1115
+ );
1116
+ this.scheduleRender();
1117
+ }
1118
+ );
1119
+ }
1120
+ return orbitControls;
1121
+ })();
1122
+ }
1123
+ addListener(prop, listener) {
1124
+ prop.addFreshListener(listener);
1125
+ this.#disconnectionFunctions.push(() => {
1126
+ prop.removeFreshListener(listener);
1127
+ });
1128
+ }
1129
+ #disconnectionFunctions = [];
1130
+ disconnect() {
1131
+ for (const fn of this.#disconnectionFunctions) {
1132
+ fn();
1133
+ }
1134
+ this.#disconnectionFunctions = [];
1135
+ }
1136
+ #experimentalNextRenderFinishedCallback = null;
1137
+ experimentalNextRenderFinishedCallback(callback) {
1138
+ this.#experimentalNextRenderFinishedCallback = callback;
1139
+ }
1140
+ async render() {
1141
+ if (!this.scene) {
1142
+ throw new Error("Attempted to render without a scene");
1143
+ }
1144
+ this.stats?.begin();
1145
+ const [scene, camera, canvas] = await Promise.all([
1146
+ this.scene.scene(),
1147
+ this.camera(),
1148
+ this.canvasInfo()
1149
+ ]);
1150
+ if (this.rendererIsShared) {
1151
+ await renderPooled(
1152
+ this.#width,
1153
+ this.#height,
1154
+ canvas.canvas,
1155
+ scene,
1156
+ camera
1157
+ );
1158
+ } else {
1159
+ (await this.renderer()).render(scene, camera);
1160
+ }
1161
+ this.stats?.end();
1162
+ this.#experimentalNextRenderFinishedCallback?.();
1163
+ this.#experimentalNextRenderFinishedCallback = null;
1164
+ }
1165
+ #scheduler = new RenderScheduler(this.render.bind(this));
1166
+ scheduleRender() {
1167
+ this.#scheduler.requestAnimFrame();
1168
+ }
1169
+ };
1170
+ customElementsShim.define("twisty-3d-vantage", Twisty3DVantage);
1171
+
1172
+ export {
1173
+ setTwistyDebug,
1174
+ StaleDropper,
1175
+ TwistyPropSource,
1176
+ SimpleTwistyPropSource,
1177
+ NO_VALUE,
1178
+ TwistyPropDerived,
1179
+ FreshListenerManager,
1180
+ HTMLElementShim,
1181
+ customElementsShim,
1182
+ cssStyleSheetShim,
1183
+ ManagedCustomElement,
1184
+ RenderScheduler,
1185
+ hintFaceletStyles,
1186
+ HintFaceletProp,
1187
+ TAU,
1188
+ DEGREES_PER_RADIAN,
1189
+ rawRenderPooled,
1190
+ setCameraFromOrbitCoordinates,
1191
+ haveStartedSharingRenderers,
1192
+ Twisty3DVantage,
1193
+ bulk3DCode
1194
+ };
1195
+ //# sourceMappingURL=chunk-CGBMJBU3.js.map