@puzzmo/sdk 1.0.31 → 1.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contracts.cjs +0 -0
- package/dist/contracts.d.ts +95 -0
- package/dist/contracts.d.ts.map +1 -0
- package/dist/contracts.js +0 -0
- package/dist/{createSimulator-xa9RclNq.js → createSimulator-Bo6J_KC_.js} +422 -296
- package/dist/createSimulator-Bo6J_KC_.js.map +1 -0
- package/dist/{createSimulator-GzKfEQWQ.cjs → createSimulator-EBKHk3L6.cjs} +55 -34
- package/dist/createSimulator-EBKHk3L6.cjs.map +1 -0
- package/dist/fonts.cjs +1 -1
- package/dist/fonts.cjs.map +1 -1
- package/dist/fonts.d.ts +13 -13
- package/dist/fonts.js +1 -1
- package/dist/fonts.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +100 -90
- package/dist/index.js.map +1 -1
- package/dist/plugins.d.ts +2 -0
- package/dist/plugins.d.ts.map +1 -0
- package/dist/plugins.spec.d.ts +2 -0
- package/dist/plugins.spec.d.ts.map +1 -0
- package/dist/sdk.d.ts +7 -2
- package/dist/sdk.d.ts.map +1 -1
- package/dist/simulator/createSimulator.d.ts.map +1 -1
- package/dist/simulator/index.cjs +1 -1
- package/dist/simulator/index.d.ts +1 -1
- package/dist/simulator/index.d.ts.map +1 -1
- package/dist/simulator/index.js +1 -1
- package/dist/simulator/standalone.cjs +1 -1
- package/dist/simulator/standalone.js +1 -1
- package/dist/simulator/state.d.ts +3 -1
- package/dist/simulator/state.d.ts.map +1 -1
- package/dist/simulator/types.d.ts +28 -1
- package/dist/simulator/types.d.ts.map +1 -1
- package/dist/simulator/views/HostView.d.ts +9 -0
- package/dist/simulator/views/HostView.d.ts.map +1 -0
- package/dist/simulator/views/index.d.ts +1 -0
- package/dist/simulator/views/index.d.ts.map +1 -1
- package/dist/types.d.ts +31 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.ts +19 -0
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js.map +1 -1
- package/package.json +6 -1
- package/dist/createSimulator-GzKfEQWQ.cjs.map +0 -1
- package/dist/createSimulator-xa9RclNq.js.map +0 -1
|
@@ -314,9 +314,26 @@ var r = {
|
|
|
314
314
|
fixturePuzzle: "simulator-fixture-puzzle",
|
|
315
315
|
renderHost: "simulator-render-host",
|
|
316
316
|
renderContext: "simulator-render-context",
|
|
317
|
-
gameSettings: "simulator-game-settings"
|
|
317
|
+
gameSettings: "simulator-game-settings",
|
|
318
|
+
hostContext: "simulator-host-context"
|
|
318
319
|
};
|
|
320
|
+
/** The Host tab's persisted `hostContext` override, or null when the tab hasn't set one. */
|
|
319
321
|
function i() {
|
|
322
|
+
let e = localStorage.getItem(r.hostContext);
|
|
323
|
+
if (!e) return null;
|
|
324
|
+
try {
|
|
325
|
+
let t = JSON.parse(e);
|
|
326
|
+
if (Array.isArray(t)) return t;
|
|
327
|
+
} catch (e) {}
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
330
|
+
function a(e) {
|
|
331
|
+
localStorage.setItem(r.hostContext, JSON.stringify(e));
|
|
332
|
+
}
|
|
333
|
+
function o() {
|
|
334
|
+
localStorage.removeItem(r.hostContext);
|
|
335
|
+
}
|
|
336
|
+
function s() {
|
|
320
337
|
let e = localStorage.getItem(r.gameSettings);
|
|
321
338
|
if (!e) return {};
|
|
322
339
|
try {
|
|
@@ -325,7 +342,7 @@ function i() {
|
|
|
325
342
|
} catch (e) {}
|
|
326
343
|
return {};
|
|
327
344
|
}
|
|
328
|
-
function
|
|
345
|
+
function c() {
|
|
329
346
|
let e = localStorage.getItem(r.theme);
|
|
330
347
|
if (e) {
|
|
331
348
|
let t = n.find((t) => t.name === e);
|
|
@@ -333,16 +350,16 @@ function a() {
|
|
|
333
350
|
}
|
|
334
351
|
return n[0];
|
|
335
352
|
}
|
|
336
|
-
function
|
|
353
|
+
function l(e) {
|
|
337
354
|
var t;
|
|
338
355
|
let n = localStorage.getItem(r.tab);
|
|
339
356
|
return n && e.includes(n) ? n : (t = e[0]) == null ? "ctrl" : t;
|
|
340
357
|
}
|
|
341
|
-
function
|
|
358
|
+
function u(e) {
|
|
342
359
|
let t = localStorage.getItem(r.collapsed);
|
|
343
360
|
return t === null ? e : t === "true";
|
|
344
361
|
}
|
|
345
|
-
function
|
|
362
|
+
function d() {
|
|
346
363
|
let e = localStorage.getItem(r.renderHost);
|
|
347
364
|
return e && [
|
|
348
365
|
"game",
|
|
@@ -350,7 +367,7 @@ function c() {
|
|
|
350
367
|
"opengraph"
|
|
351
368
|
].includes(e) ? e : "game";
|
|
352
369
|
}
|
|
353
|
-
function
|
|
370
|
+
function f() {
|
|
354
371
|
let e = localStorage.getItem(r.renderContext);
|
|
355
372
|
if (e && [
|
|
356
373
|
"preview",
|
|
@@ -359,58 +376,64 @@ function l() {
|
|
|
359
376
|
"timeline"
|
|
360
377
|
].includes(e)) return e;
|
|
361
378
|
}
|
|
362
|
-
function
|
|
363
|
-
var
|
|
364
|
-
let
|
|
379
|
+
function p(e, t, n) {
|
|
380
|
+
var a, o, p;
|
|
381
|
+
let m = localStorage.getItem(r.fixtureCategory), h = localStorage.getItem(r.fixturePuzzle), g = i();
|
|
365
382
|
return {
|
|
366
|
-
|
|
383
|
+
hostContext: (a = g == null ? e.hostContext : g) == null ? [{
|
|
384
|
+
type: "app",
|
|
385
|
+
layout: "desktop",
|
|
386
|
+
host: null
|
|
387
|
+
}] : a,
|
|
388
|
+
hostContextIsOverridden: g !== null,
|
|
389
|
+
isCollapsed: u((o = e.collapsed) == null ? !0 : o),
|
|
367
390
|
isPaused: !1,
|
|
368
391
|
hasStarted: !1,
|
|
369
|
-
activeTab:
|
|
392
|
+
activeTab: l(n),
|
|
370
393
|
puzzleData: null,
|
|
371
394
|
originalPuzzle: "",
|
|
372
395
|
currentInputStr: "",
|
|
373
396
|
completionData: null,
|
|
374
|
-
selectedTheme:
|
|
375
|
-
selectedCategory:
|
|
376
|
-
selectedPuzzle:
|
|
377
|
-
renderHost:
|
|
378
|
-
renderContext:
|
|
379
|
-
gameSettings:
|
|
397
|
+
selectedTheme: c(),
|
|
398
|
+
selectedCategory: m && t.includes(m) ? m : (p = t[0]) == null ? null : p,
|
|
399
|
+
selectedPuzzle: h == null ? null : h,
|
|
400
|
+
renderHost: d(),
|
|
401
|
+
renderContext: f(),
|
|
402
|
+
gameSettings: s(),
|
|
380
403
|
settingsComponents: null
|
|
381
404
|
};
|
|
382
405
|
}
|
|
383
|
-
function
|
|
406
|
+
function m(e) {
|
|
384
407
|
localStorage.setItem(r.gameSettings, JSON.stringify(e));
|
|
385
408
|
}
|
|
386
|
-
function
|
|
409
|
+
function h() {
|
|
387
410
|
localStorage.removeItem(r.gameSettings);
|
|
388
411
|
}
|
|
389
|
-
function
|
|
412
|
+
function g(e) {
|
|
390
413
|
localStorage.setItem(r.collapsed, String(e));
|
|
391
414
|
}
|
|
392
|
-
function
|
|
415
|
+
function ee(e) {
|
|
393
416
|
localStorage.setItem(r.tab, e);
|
|
394
417
|
}
|
|
395
|
-
function
|
|
418
|
+
function te(e) {
|
|
396
419
|
localStorage.setItem(r.theme, e);
|
|
397
420
|
}
|
|
398
|
-
function
|
|
421
|
+
function _(e) {
|
|
399
422
|
localStorage.setItem(r.fixtureCategory, e);
|
|
400
423
|
}
|
|
401
|
-
function
|
|
424
|
+
function v(e) {
|
|
402
425
|
localStorage.setItem(r.fixturePuzzle, e);
|
|
403
426
|
}
|
|
404
|
-
function
|
|
427
|
+
function ne() {
|
|
405
428
|
localStorage.removeItem(r.fixturePuzzle);
|
|
406
429
|
}
|
|
407
|
-
function
|
|
430
|
+
function y(e) {
|
|
408
431
|
e ? localStorage.setItem(r.renderHost, e) : localStorage.removeItem(r.renderHost);
|
|
409
432
|
}
|
|
410
|
-
function
|
|
433
|
+
function b(e) {
|
|
411
434
|
e ? localStorage.setItem(r.renderContext, e) : localStorage.removeItem(r.renderContext);
|
|
412
435
|
}
|
|
413
|
-
function
|
|
436
|
+
function re(e) {
|
|
414
437
|
let t = [];
|
|
415
438
|
return {
|
|
416
439
|
log(n, r, i) {
|
|
@@ -435,13 +458,13 @@ function te(e) {
|
|
|
435
458
|
}
|
|
436
459
|
};
|
|
437
460
|
}
|
|
438
|
-
function
|
|
461
|
+
function ie(e, t, n) {
|
|
439
462
|
console.log("Simulator sending:", e, t), n == null || n.log(e, t, "out"), window.postMessage({
|
|
440
463
|
type: e,
|
|
441
464
|
data: t
|
|
442
465
|
}, "*");
|
|
443
466
|
}
|
|
444
|
-
function
|
|
467
|
+
function ae(e, t) {
|
|
445
468
|
let n = (n) => {
|
|
446
469
|
var r, i, a;
|
|
447
470
|
if (!(!(n == null || (r = n.data) == null) && r.type)) return;
|
|
@@ -451,7 +474,7 @@ function re(e, t) {
|
|
|
451
474
|
return window.addEventListener("message", n), () => window.removeEventListener("message", n);
|
|
452
475
|
}
|
|
453
476
|
/** Parse fixture imports into a structured format: { category: { filename: data } } */
|
|
454
|
-
function
|
|
477
|
+
function oe(e) {
|
|
455
478
|
let t = /* @__PURE__ */ new Map();
|
|
456
479
|
console.log("Simulator: Parsing fixtures", Object.keys(e));
|
|
457
480
|
for (let [o, s] of Object.entries(e)) {
|
|
@@ -470,7 +493,7 @@ function ie(e) {
|
|
|
470
493
|
}), t;
|
|
471
494
|
}
|
|
472
495
|
/** Render fixture selector HTML */
|
|
473
|
-
function
|
|
496
|
+
function x(e, t) {
|
|
474
497
|
return e.length === 0 ? "" : `
|
|
475
498
|
<div class="simulator-fixtures">
|
|
476
499
|
<div class="simulator-field">
|
|
@@ -487,7 +510,7 @@ function b(e, t) {
|
|
|
487
510
|
`;
|
|
488
511
|
}
|
|
489
512
|
/** Update puzzle select options based on selected category */
|
|
490
|
-
function
|
|
513
|
+
function S(e, t, n, r) {
|
|
491
514
|
let i = t.get(n);
|
|
492
515
|
if (!i) return null;
|
|
493
516
|
let a = Array.from(i.keys()), o = r;
|
|
@@ -498,11 +521,11 @@ function x(e, t, n, r) {
|
|
|
498
521
|
return e.innerHTML = a.map((e) => `<option value="${e}" ${e === o ? "selected" : ""}>${e}</option>`).join(""), o;
|
|
499
522
|
}
|
|
500
523
|
/** Get puzzle data from fixtures */
|
|
501
|
-
function
|
|
524
|
+
function C(e, t, n) {
|
|
502
525
|
var r, i;
|
|
503
526
|
return !t || !n || (r = (i = e.get(t)) == null ? void 0 : i.get(n)) == null ? null : r;
|
|
504
527
|
}
|
|
505
|
-
function
|
|
528
|
+
function se() {
|
|
506
529
|
return {
|
|
507
530
|
id: "ctrl",
|
|
508
531
|
label: "Ctrl",
|
|
@@ -517,19 +540,19 @@ function ae() {
|
|
|
517
540
|
selectedCategory: e.state.selectedCategory,
|
|
518
541
|
selectedPuzzle: e.state.selectedPuzzle
|
|
519
542
|
}), e.fixtures && e.fixtureCategories.length > 0 && i) {
|
|
520
|
-
i.innerHTML =
|
|
543
|
+
i.innerHTML = x(e.fixtureCategories, e.state.selectedCategory);
|
|
521
544
|
let t = e.getElement("#simulator-fixture-category"), n = e.getElement("#simulator-fixture-puzzle");
|
|
522
545
|
if (t && n && e.state.selectedCategory) {
|
|
523
|
-
e.state.selectedPuzzle =
|
|
524
|
-
let r =
|
|
546
|
+
e.state.selectedPuzzle = S(n, e.fixtures, e.state.selectedCategory, e.state.selectedPuzzle);
|
|
547
|
+
let r = C(e.fixtures, e.state.selectedCategory, e.state.selectedPuzzle);
|
|
525
548
|
console.log("Simulator: Loading fixture puzzle", {
|
|
526
549
|
category: e.state.selectedCategory,
|
|
527
550
|
puzzle: e.state.selectedPuzzle,
|
|
528
551
|
hasPuzzleData: !!r
|
|
529
|
-
}), r && (e.state.puzzleData = r, e.state.originalPuzzle = r, e.state.selectedCategory &&
|
|
530
|
-
console.log("Simulator: Category changed, reloading...", t.value),
|
|
552
|
+
}), r && (e.state.puzzleData = r, e.state.originalPuzzle = r, e.state.selectedCategory && _(e.state.selectedCategory), e.state.selectedPuzzle && v(e.state.selectedPuzzle)), t.addEventListener("change", () => {
|
|
553
|
+
console.log("Simulator: Category changed, reloading...", t.value), _(t.value), ne(), window.location.reload();
|
|
531
554
|
}), n.addEventListener("change", () => {
|
|
532
|
-
console.log("Simulator: Puzzle changed, reloading...", n.value),
|
|
555
|
+
console.log("Simulator: Puzzle changed, reloading...", n.value), v(n.value), window.location.reload();
|
|
533
556
|
});
|
|
534
557
|
}
|
|
535
558
|
}
|
|
@@ -547,9 +570,9 @@ function ae() {
|
|
|
547
570
|
}
|
|
548
571
|
};
|
|
549
572
|
}
|
|
550
|
-
var
|
|
573
|
+
var w = "simulator-saved-states";
|
|
551
574
|
/** Find thumbnail function on globalThis (looks for functions ending in "Thumbnail") */
|
|
552
|
-
function
|
|
575
|
+
function T() {
|
|
553
576
|
let e = globalThis;
|
|
554
577
|
for (let t of Object.keys(e)) if (t.endsWith("Thumbnail") && typeof e[t] == "function") return {
|
|
555
578
|
name: t,
|
|
@@ -558,8 +581,8 @@ function w() {
|
|
|
558
581
|
return null;
|
|
559
582
|
}
|
|
560
583
|
/** Generate a small thumbnail SVG for a given input string */
|
|
561
|
-
function
|
|
562
|
-
let n =
|
|
584
|
+
function E(e, t) {
|
|
585
|
+
let n = T();
|
|
563
586
|
if (!n) return "";
|
|
564
587
|
try {
|
|
565
588
|
var r;
|
|
@@ -574,14 +597,14 @@ function T(e, t) {
|
|
|
574
597
|
return "";
|
|
575
598
|
}
|
|
576
599
|
}
|
|
577
|
-
var
|
|
578
|
-
function
|
|
600
|
+
var D = [];
|
|
601
|
+
function O(e, t = 8) {
|
|
579
602
|
let n = 14 * t + 8 + 4;
|
|
580
603
|
e.style.height = "auto";
|
|
581
604
|
let r = Math.min(Math.max(e.scrollHeight, 40), n);
|
|
582
605
|
e.style.height = `${r}px`;
|
|
583
606
|
}
|
|
584
|
-
function
|
|
607
|
+
function ce() {
|
|
585
608
|
let e = "", t = "";
|
|
586
609
|
return {
|
|
587
610
|
id: "data",
|
|
@@ -599,102 +622,102 @@ function oe() {
|
|
|
599
622
|
let i = n.getElement(".data-view-container");
|
|
600
623
|
i == null || i.querySelectorAll(".data-subtab-content").forEach((e) => {
|
|
601
624
|
e.classList.toggle("active", e.id === `data-subtab-${t}`);
|
|
602
|
-
}), t === "edit" ?
|
|
625
|
+
}), t === "edit" ? N(n) : t === "history" ? A(n) : t === "saves" && j(n);
|
|
603
626
|
});
|
|
604
627
|
});
|
|
605
628
|
let i = n.getElement("#simulator-puzzle"), a = n.getElement("#simulator-input"), o = n.getElement("#simulator-puzzle-reset"), s = n.getElement("#simulator-puzzle-apply"), c = n.getElement("#simulator-input-reset"), l = n.getElement("#simulator-input-apply"), u = n.getElement("#simulator-start"), d = n.getElement("#simulator-pause");
|
|
606
629
|
setTimeout(() => {
|
|
607
|
-
i && n.state.originalPuzzle && (i.value = n.state.originalPuzzle, e = n.state.originalPuzzle,
|
|
630
|
+
i && n.state.originalPuzzle && (i.value = n.state.originalPuzzle, e = n.state.originalPuzzle, O(i)), a && n.state.currentInputStr && (a.value = n.state.currentInputStr, t = n.state.currentInputStr, O(a));
|
|
608
631
|
}, 0), i == null || i.addEventListener("input", () => {
|
|
609
|
-
|
|
632
|
+
O(i);
|
|
610
633
|
let t = i.value !== e;
|
|
611
634
|
s && (s.disabled = !t);
|
|
612
635
|
}), a == null || a.addEventListener("input", () => {
|
|
613
|
-
|
|
636
|
+
O(a);
|
|
614
637
|
let e = a.value !== t;
|
|
615
638
|
l && (l.disabled = !e);
|
|
616
639
|
}), o == null || o.addEventListener("click", () => {
|
|
617
|
-
i && (i.value = n.state.originalPuzzle, e = n.state.originalPuzzle,
|
|
640
|
+
i && (i.value = n.state.originalPuzzle, e = n.state.originalPuzzle, O(i), s && (s.disabled = !0));
|
|
618
641
|
}), s == null || s.addEventListener("click", () => {
|
|
619
642
|
i && (n.state.puzzleData = i.value, n.state.originalPuzzle = i.value, e = i.value, n.sendToGame("RETRY_PUZZLE", {}), n.state.hasStarted = !1, n.state.isPaused = !1, d && (d.disabled = !0, d.textContent = "Pause"), u && (u.textContent = "Start"), n.updateStatus("Puzzle updated", "ready"), s.disabled = !0);
|
|
620
643
|
}), c == null || c.addEventListener("click", () => {
|
|
621
|
-
a && (a.value = t,
|
|
644
|
+
a && (a.value = t, O(a), l && (l.disabled = !0));
|
|
622
645
|
}), l == null || l.addEventListener("click", () => {
|
|
623
646
|
a && (n.state.currentInputStr = a.value, t = a.value, console.log("Simulator: Input string updated (game restart required to apply)"), n.updateStatus("Input stored", "ready"), l.disabled = !0);
|
|
624
647
|
});
|
|
625
648
|
let f = n.getElement("#simulator-history-clear");
|
|
626
649
|
f == null || f.addEventListener("click", () => {
|
|
627
|
-
|
|
650
|
+
D = [], A(n);
|
|
628
651
|
});
|
|
629
652
|
let p = n.getElement("#simulator-save-name"), m = n.getElement("#simulator-save-btn");
|
|
630
653
|
m == null || m.addEventListener("click", () => {
|
|
631
654
|
if (!p || !p.value.trim()) return;
|
|
632
|
-
let e =
|
|
655
|
+
let e = k(), t = {
|
|
633
656
|
name: p.value.trim(),
|
|
634
657
|
puzzleStr: n.state.originalPuzzle,
|
|
635
658
|
inputStr: n.state.currentInputStr,
|
|
636
659
|
timestamp: Date.now()
|
|
637
660
|
};
|
|
638
|
-
e.push(t), localStorage.setItem(
|
|
639
|
-
}),
|
|
661
|
+
e.push(t), localStorage.setItem(w, JSON.stringify(e)), p.value = "", j(n);
|
|
662
|
+
}), j(n);
|
|
640
663
|
},
|
|
641
664
|
onActivate(n) {
|
|
642
|
-
e = n.state.originalPuzzle, t = n.state.currentInputStr,
|
|
665
|
+
e = n.state.originalPuzzle, t = n.state.currentInputStr, N(n), A(n);
|
|
643
666
|
},
|
|
644
667
|
onMessage(e, n, r) {
|
|
645
668
|
var i, a;
|
|
646
669
|
let o = r.getElement("#simulator-input"), s = r.getElement("#simulator-input-apply"), c = (i = n == null || (a = n.input) == null ? void 0 : a.boardState) == null ? n == null ? void 0 : n.boardState : i;
|
|
647
670
|
if (e === "UPLOAD_NEW_GAME_STATE" && c) {
|
|
648
|
-
if (r.state.currentInputStr = c,
|
|
649
|
-
|
|
671
|
+
if (r.state.currentInputStr = c, D.length === 0 || D[D.length - 1].value !== c) {
|
|
672
|
+
D.push({
|
|
650
673
|
value: c,
|
|
651
674
|
timestamp: Date.now()
|
|
652
|
-
}),
|
|
675
|
+
}), D.length > 100 && (D = D.slice(-100));
|
|
653
676
|
let e = r.getElement("#data-subtab-history");
|
|
654
|
-
e != null && e.classList.contains("active") &&
|
|
677
|
+
e != null && e.classList.contains("active") && A(r);
|
|
655
678
|
}
|
|
656
|
-
o && (o.value = r.state.currentInputStr, t = r.state.currentInputStr,
|
|
679
|
+
o && (o.value = r.state.currentInputStr, t = r.state.currentInputStr, O(o), s && (s.disabled = !0));
|
|
657
680
|
}
|
|
658
681
|
}
|
|
659
682
|
};
|
|
660
683
|
}
|
|
661
|
-
function
|
|
684
|
+
function k() {
|
|
662
685
|
try {
|
|
663
|
-
let e = localStorage.getItem(
|
|
686
|
+
let e = localStorage.getItem(w);
|
|
664
687
|
return e ? JSON.parse(e) : [];
|
|
665
688
|
} catch (e) {
|
|
666
689
|
return [];
|
|
667
690
|
}
|
|
668
691
|
}
|
|
669
|
-
function
|
|
692
|
+
function A(e) {
|
|
670
693
|
let t = e.getElement("#simulator-history-list");
|
|
671
694
|
if (t) {
|
|
672
|
-
if (t.style.setProperty("--history-thumb-bg", e.state.selectedTheme.a_bg),
|
|
695
|
+
if (t.style.setProperty("--history-thumb-bg", e.state.selectedTheme.a_bg), D.length === 0) {
|
|
673
696
|
t.innerHTML = "<div class=\"simulator-empty\">No history yet</div>";
|
|
674
697
|
return;
|
|
675
698
|
}
|
|
676
|
-
t.innerHTML = [...
|
|
677
|
-
let r =
|
|
699
|
+
t.innerHTML = [...D].reverse().map((t, n) => {
|
|
700
|
+
let r = D.length - 1 - n, i = new Date(t.timestamp).toLocaleTimeString(), a = t.value.length > 60 ? t.value.slice(0, 60) + "..." : t.value;
|
|
678
701
|
return `
|
|
679
702
|
<div class="history-item" data-history-idx="${r}">
|
|
680
|
-
<div class="history-item-thumb">${
|
|
703
|
+
<div class="history-item-thumb">${E(e, t.value)}</div>
|
|
681
704
|
<div class="history-item-content">
|
|
682
705
|
<div class="history-item-header">
|
|
683
706
|
<span class="history-item-num">#${r + 1}</span>
|
|
684
707
|
<span class="history-item-time">${i}</span>
|
|
685
708
|
<button class="simulator-btn tiny history-restore-btn" data-history-idx="${r}">Restore</button>
|
|
686
709
|
</div>
|
|
687
|
-
<div class="history-item-preview">${
|
|
710
|
+
<div class="history-item-preview">${M(a)}</div>
|
|
688
711
|
</div>
|
|
689
712
|
</div>
|
|
690
713
|
`;
|
|
691
714
|
}).join(""), t.querySelectorAll(".history-restore-btn").forEach((t) => {
|
|
692
715
|
t.addEventListener("click", (t) => {
|
|
693
|
-
let n = parseInt(t.target.getAttribute("data-history-idx") || "0"), r =
|
|
716
|
+
let n = parseInt(t.target.getAttribute("data-history-idx") || "0"), r = D[n];
|
|
694
717
|
if (r) {
|
|
695
718
|
e.state.currentInputStr = r.value;
|
|
696
719
|
let t = e.getElement("#simulator-input");
|
|
697
|
-
t && (t.value = r.value,
|
|
720
|
+
t && (t.value = r.value, O(t)), e.updateStatus("Input restored from history", "ready");
|
|
698
721
|
let n = e.getElement(".data-subtab[data-subtab=\"edit\"]");
|
|
699
722
|
n == null || n.click();
|
|
700
723
|
}
|
|
@@ -702,10 +725,10 @@ function k(e) {
|
|
|
702
725
|
});
|
|
703
726
|
}
|
|
704
727
|
}
|
|
705
|
-
function
|
|
728
|
+
function j(e) {
|
|
706
729
|
let t = e.getElement("#simulator-saves-list");
|
|
707
730
|
if (!t) return;
|
|
708
|
-
let n =
|
|
731
|
+
let n = k();
|
|
709
732
|
if (n.length === 0) {
|
|
710
733
|
t.innerHTML = "<div class=\"simulator-empty\">No saved states</div>";
|
|
711
734
|
return;
|
|
@@ -715,7 +738,7 @@ function A(e) {
|
|
|
715
738
|
return `
|
|
716
739
|
<div class="save-item">
|
|
717
740
|
<div class="save-item-header">
|
|
718
|
-
<span class="save-item-name">${
|
|
741
|
+
<span class="save-item-name">${M(e.name)}</span>
|
|
719
742
|
<span class="save-item-time">${i} ${a}</span>
|
|
720
743
|
</div>
|
|
721
744
|
<div class="save-item-actions">
|
|
@@ -730,7 +753,7 @@ function A(e) {
|
|
|
730
753
|
if (r) {
|
|
731
754
|
e.state.puzzleData = r.puzzleStr, e.state.originalPuzzle = r.puzzleStr, e.state.currentInputStr = r.inputStr;
|
|
732
755
|
let t = e.getElement("#simulator-puzzle"), n = e.getElement("#simulator-input");
|
|
733
|
-
t && (t.value = r.puzzleStr,
|
|
756
|
+
t && (t.value = r.puzzleStr, O(t)), n && (n.value = r.inputStr, O(n)), e.updateStatus(`Loaded: ${r.name}`, "ready");
|
|
734
757
|
let i = e.getElement(".data-subtab[data-subtab=\"edit\"]");
|
|
735
758
|
i == null || i.click();
|
|
736
759
|
}
|
|
@@ -738,21 +761,21 @@ function A(e) {
|
|
|
738
761
|
}), t.querySelectorAll(".save-delete-btn").forEach((t) => {
|
|
739
762
|
t.addEventListener("click", (t) => {
|
|
740
763
|
let r = parseInt(t.target.getAttribute("data-save-idx") || "0"), i = n.filter((e, t) => t !== r);
|
|
741
|
-
localStorage.setItem(
|
|
764
|
+
localStorage.setItem(w, JSON.stringify(i)), j(e);
|
|
742
765
|
});
|
|
743
766
|
});
|
|
744
767
|
}
|
|
745
|
-
function
|
|
768
|
+
function M(e) {
|
|
746
769
|
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
747
770
|
}
|
|
748
|
-
function
|
|
771
|
+
function N(e) {
|
|
749
772
|
let t = e.getElement("#simulator-puzzle"), n = e.getElement("#simulator-input"), r = e.getElement("#simulator-puzzle-apply"), i = e.getElement("#simulator-input-apply");
|
|
750
|
-
t && e.state.originalPuzzle && (t.value = e.state.originalPuzzle,
|
|
773
|
+
t && e.state.originalPuzzle && (t.value = e.state.originalPuzzle, O(t), r && (r.disabled = !0)), n && (n.value = e.state.currentInputStr, O(n), i && (i.disabled = !0));
|
|
751
774
|
}
|
|
752
|
-
function
|
|
775
|
+
function P(e) {
|
|
753
776
|
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
754
777
|
}
|
|
755
|
-
function
|
|
778
|
+
function le() {
|
|
756
779
|
let e = 0;
|
|
757
780
|
return {
|
|
758
781
|
id: "msgs",
|
|
@@ -779,7 +802,7 @@ function se() {
|
|
|
779
802
|
<span class="simulator-msg-type">${t.direction === "out" ? "→" : "←"} ${t.type}</span>
|
|
780
803
|
<span class="simulator-msg-time">${t.time}</span>
|
|
781
804
|
</div>
|
|
782
|
-
${a ? `<div class="simulator-msg-data">${
|
|
805
|
+
${a ? `<div class="simulator-msg-data">${P(a)}</div>` : ""}
|
|
783
806
|
`;
|
|
784
807
|
let o = i.querySelector(".simulator-msg-data");
|
|
785
808
|
for (o && o.addEventListener("click", () => {
|
|
@@ -790,7 +813,7 @@ function se() {
|
|
|
790
813
|
}
|
|
791
814
|
};
|
|
792
815
|
}
|
|
793
|
-
function
|
|
816
|
+
function ue() {
|
|
794
817
|
return {
|
|
795
818
|
id: "done",
|
|
796
819
|
label: "Done",
|
|
@@ -827,7 +850,7 @@ function ce() {
|
|
|
827
850
|
}
|
|
828
851
|
};
|
|
829
852
|
}
|
|
830
|
-
function
|
|
853
|
+
function de() {
|
|
831
854
|
let e = [], t = () => (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: !1 }), n = (e) => {
|
|
832
855
|
let { checkpointName: t, augConfig: n, time: r } = e, i = n == null ? void 0 : n.deeds;
|
|
833
856
|
return `
|
|
@@ -878,7 +901,7 @@ function le() {
|
|
|
878
901
|
};
|
|
879
902
|
}
|
|
880
903
|
/** Find thumbnail function on globalThis (looks for functions ending in "Thumbnail") */
|
|
881
|
-
function
|
|
904
|
+
function F() {
|
|
882
905
|
let e = globalThis;
|
|
883
906
|
for (let t of Object.keys(e)) if (t.endsWith("Thumbnail") && typeof e[t] == "function") return {
|
|
884
907
|
name: t,
|
|
@@ -886,7 +909,7 @@ function P() {
|
|
|
886
909
|
};
|
|
887
910
|
return null;
|
|
888
911
|
}
|
|
889
|
-
function
|
|
912
|
+
function fe() {
|
|
890
913
|
return {
|
|
891
914
|
id: "thumb",
|
|
892
915
|
label: "Thumb",
|
|
@@ -899,10 +922,10 @@ function ue() {
|
|
|
899
922
|
let n = e.getElement("#simulator-render-host-select"), r = e.getElement("#simulator-render-context-select"), i = e.getElement("#simulator-render-context-field"), a = () => {
|
|
900
923
|
i && (i.style.display = e.state.renderHost === "opengraph" ? "block" : "none");
|
|
901
924
|
};
|
|
902
|
-
n && (e.state.renderHost || (e.state.renderHost = "game",
|
|
903
|
-
e.state.renderHost = n.value,
|
|
904
|
-
})), r && (e.state.renderContext || (e.state.renderContext = "preview",
|
|
905
|
-
e.state.renderContext = r.value,
|
|
925
|
+
n && (e.state.renderHost || (e.state.renderHost = "game", y(e.state.renderHost)), n.value = e.state.renderHost || "game", n.addEventListener("change", () => {
|
|
926
|
+
e.state.renderHost = n.value, y(e.state.renderHost), a(), e.updateThumbnail();
|
|
927
|
+
})), r && (e.state.renderContext || (e.state.renderContext = "preview", b(e.state.renderContext)), r.value = e.state.renderContext || "preview", r.addEventListener("change", () => {
|
|
928
|
+
e.state.renderContext = r.value, b(e.state.renderContext), e.updateThumbnail();
|
|
906
929
|
})), a();
|
|
907
930
|
},
|
|
908
931
|
onActivate(e) {
|
|
@@ -911,7 +934,7 @@ function ue() {
|
|
|
911
934
|
updatePreview: (e) => {
|
|
912
935
|
let t = e.getElement("#simulator-thumb-preview"), n = e.getElement("#simulator-thumb-fn");
|
|
913
936
|
t == null || t.style.setProperty("--sim-thumb-bg", e.state.selectedTheme.g_bg);
|
|
914
|
-
let r =
|
|
937
|
+
let r = F();
|
|
915
938
|
if (!r) {
|
|
916
939
|
t && (t.innerHTML = "<span class=\"simulator-empty\">No thumbnail function found</span>"), n && (n.textContent = "");
|
|
917
940
|
return;
|
|
@@ -934,7 +957,7 @@ function ue() {
|
|
|
934
957
|
};
|
|
935
958
|
}
|
|
936
959
|
/** Generate theme preview HTML showing key colors */
|
|
937
|
-
function
|
|
960
|
+
function I(e) {
|
|
938
961
|
let t = [
|
|
939
962
|
e.key,
|
|
940
963
|
e.subBrand,
|
|
@@ -945,7 +968,7 @@ function F(e) {
|
|
|
945
968
|
].map((e) => `<div class="simulator-theme-preview-cell" style="background: ${e}"></div>`).join("");
|
|
946
969
|
return `<div class="simulator-theme-preview" style="background: ${e.g_bg}">${t}</div>`;
|
|
947
970
|
}
|
|
948
|
-
function
|
|
971
|
+
function pe() {
|
|
949
972
|
return {
|
|
950
973
|
id: "theme",
|
|
951
974
|
label: "Theme",
|
|
@@ -957,49 +980,154 @@ function de() {
|
|
|
957
980
|
t && n.forEach((n) => {
|
|
958
981
|
let r = document.createElement("div");
|
|
959
982
|
r.className = `simulator-theme-item${n.name === e.state.selectedTheme.name ? " selected" : ""}`, r.innerHTML = `
|
|
960
|
-
${
|
|
983
|
+
${I(n)}
|
|
961
984
|
<div class="simulator-theme-name">${n.name}</div>
|
|
962
985
|
<div class="simulator-theme-type">${n.type}</div>
|
|
963
986
|
`, r.addEventListener("click", () => {
|
|
964
|
-
console.log("Simulator: Theme changed, reloading...", n.name),
|
|
987
|
+
console.log("Simulator: Theme changed, reloading...", n.name), te(n.name), window.location.reload();
|
|
965
988
|
}), t.appendChild(r);
|
|
966
989
|
});
|
|
967
990
|
}
|
|
968
991
|
};
|
|
969
992
|
}
|
|
970
|
-
var
|
|
971
|
-
|
|
972
|
-
|
|
993
|
+
var L = [
|
|
994
|
+
{
|
|
995
|
+
name: "app (desktop)",
|
|
996
|
+
context: [{
|
|
997
|
+
type: "app",
|
|
998
|
+
layout: "desktop",
|
|
999
|
+
host: null
|
|
1000
|
+
}]
|
|
1001
|
+
},
|
|
1002
|
+
{
|
|
1003
|
+
name: "app (mobile)",
|
|
1004
|
+
context: [{
|
|
1005
|
+
type: "app",
|
|
1006
|
+
layout: "mobile",
|
|
1007
|
+
host: null
|
|
1008
|
+
}]
|
|
1009
|
+
},
|
|
1010
|
+
{
|
|
1011
|
+
name: "app (ios)",
|
|
1012
|
+
context: [{
|
|
1013
|
+
type: "app",
|
|
1014
|
+
layout: "mobile",
|
|
1015
|
+
host: "ios-app"
|
|
1016
|
+
}]
|
|
1017
|
+
},
|
|
1018
|
+
{
|
|
1019
|
+
name: "embed",
|
|
1020
|
+
context: [{ type: "embed" }]
|
|
1021
|
+
},
|
|
1022
|
+
{
|
|
1023
|
+
name: "embed (no UI)",
|
|
1024
|
+
context: [{
|
|
1025
|
+
type: "embed",
|
|
1026
|
+
noUI: !0
|
|
1027
|
+
}]
|
|
1028
|
+
},
|
|
1029
|
+
{
|
|
1030
|
+
name: "sandbox",
|
|
1031
|
+
context: [{ type: "sandbox" }]
|
|
1032
|
+
}
|
|
1033
|
+
];
|
|
1034
|
+
/**
|
|
1035
|
+
* Host tab — edit the `hostContext` array the simulator sends in READY_DATA, so host-context
|
|
1036
|
+
* dependent features (embed settings, sandbox mode, mobile layout, …) can be exercised locally.
|
|
1037
|
+
* The bootstrap is only read at game boot, so applying a change persists it to localStorage and
|
|
1038
|
+
* restarts (reloads) the page — the same flow as the Theme tab.
|
|
1039
|
+
*/
|
|
1040
|
+
function me(e = []) {
|
|
1041
|
+
let t = [...L, ...e];
|
|
1042
|
+
return {
|
|
1043
|
+
id: "host",
|
|
1044
|
+
label: "Host",
|
|
1045
|
+
render() {
|
|
1046
|
+
return `
|
|
1047
|
+
<style>
|
|
1048
|
+
#simulator-tab-host .host-note { opacity: 0.5; font-size: 10px; margin: 4px 0 8px; }
|
|
1049
|
+
#simulator-tab-host .host-error { color: #f66; font-size: 11px; margin-top: 6px; white-space: pre-wrap; }
|
|
1050
|
+
#simulator-tab-host .host-actions { display: flex; gap: 6px; margin-top: 8px; }
|
|
1051
|
+
#simulator-tab-host .simulator-textarea { min-height: 140px; font-family: monospace; }
|
|
1052
|
+
</style>
|
|
1053
|
+
<div class="simulator-section">
|
|
1054
|
+
<div class="simulator-section-title">Host Context</div>
|
|
1055
|
+
<div class="host-note" id="host-source"></div>
|
|
1056
|
+
<select class="simulator-select" id="host-presets">
|
|
1057
|
+
<option value="">Preset…</option>
|
|
1058
|
+
${t.map((e, t) => `<option value="${t}">${R(e.name)}</option>`).join("")}
|
|
1059
|
+
</select>
|
|
1060
|
+
<textarea class="simulator-textarea" id="host-json" spellcheck="false"></textarea>
|
|
1061
|
+
<div class="host-actions">
|
|
1062
|
+
<button class="simulator-btn primary" id="host-apply">Apply & Restart</button>
|
|
1063
|
+
<button class="simulator-btn subtle" id="host-reset">Reset</button>
|
|
1064
|
+
</div>
|
|
1065
|
+
<div class="host-error" id="host-error"></div>
|
|
1066
|
+
</div>
|
|
1067
|
+
`;
|
|
1068
|
+
},
|
|
1069
|
+
bind(e) {
|
|
1070
|
+
var n, r;
|
|
1071
|
+
let i = e.getElement("#host-json"), s = e.getElement("#host-presets"), c = e.getElement("#host-error"), l = e.getElement("#host-source");
|
|
1072
|
+
!i || !s || !c || !l || (i.value = JSON.stringify(e.state.hostContext, null, 2), l.textContent = e.state.hostContextIsOverridden ? "Using this tab's override. Changes apply on restart." : "Using the vite config / default context. Changes apply on restart.", s.addEventListener("change", () => {
|
|
1073
|
+
let e = t[Number(s.value)];
|
|
1074
|
+
e && (i.value = JSON.stringify(e.context, null, 2));
|
|
1075
|
+
}), (n = e.getElement("#host-apply")) == null || n.addEventListener("click", () => {
|
|
1076
|
+
let e;
|
|
1077
|
+
try {
|
|
1078
|
+
e = JSON.parse(i.value);
|
|
1079
|
+
} catch (e) {
|
|
1080
|
+
c.textContent = `Invalid JSON: ${e.message}`;
|
|
1081
|
+
return;
|
|
1082
|
+
}
|
|
1083
|
+
if (!Array.isArray(e) || !e.every((e) => e && typeof e == "object" && typeof e.type == "string")) {
|
|
1084
|
+
c.textContent = "hostContext must be an array of { type: string, ... } objects";
|
|
1085
|
+
return;
|
|
1086
|
+
}
|
|
1087
|
+
console.log("Simulator: hostContext changed, reloading...", e), a(e), window.location.reload();
|
|
1088
|
+
}), (r = e.getElement("#host-reset")) == null || r.addEventListener("click", () => {
|
|
1089
|
+
o(), window.location.reload();
|
|
1090
|
+
}));
|
|
1091
|
+
}
|
|
1092
|
+
};
|
|
1093
|
+
}
|
|
1094
|
+
/** Minimal HTML-escape so preset names can't break the simulator markup. */
|
|
1095
|
+
function R(e) {
|
|
1096
|
+
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
1097
|
+
}
|
|
1098
|
+
var z = "puzzmo_sim_api_mode", B = "http://localhost:8911", V = "https://api.puzzmo.com", H = () => localStorage.getItem(z) === "dev" ? "dev" : "prod", he = (e) => {
|
|
1099
|
+
localStorage.setItem(z, e);
|
|
1100
|
+
}, U = null, ge = function() {
|
|
973
1101
|
var e = t(function* () {
|
|
974
|
-
if (
|
|
1102
|
+
if (U !== null) return U;
|
|
975
1103
|
try {
|
|
976
|
-
let e = new AbortController(), t = setTimeout(() => e.abort(), 1e3), n = yield fetch(`${
|
|
977
|
-
return clearTimeout(t),
|
|
1104
|
+
let e = new AbortController(), t = setTimeout(() => e.abort(), 1e3), n = yield fetch(`${B}/healthz`, { signal: e.signal });
|
|
1105
|
+
return clearTimeout(t), U = n.ok, U;
|
|
978
1106
|
} catch (e) {
|
|
979
|
-
return
|
|
1107
|
+
return U = !1, !1;
|
|
980
1108
|
}
|
|
981
1109
|
});
|
|
982
1110
|
return function() {
|
|
983
1111
|
return e.apply(this, arguments);
|
|
984
1112
|
};
|
|
985
|
-
}(),
|
|
986
|
-
apiURL:
|
|
1113
|
+
}(), W = () => ({
|
|
1114
|
+
apiURL: H() === "dev" ? B : V,
|
|
987
1115
|
clientID: "protosdk:oauthclient",
|
|
988
1116
|
redirectUri: `${window.location.origin}/oauth/callback`
|
|
989
|
-
}),
|
|
1117
|
+
}), _e = () => {
|
|
990
1118
|
let e = new Uint8Array(32);
|
|
991
1119
|
return crypto.getRandomValues(e), Array.from(e, (e) => e.toString(16).padStart(2, "0")).join("");
|
|
992
|
-
},
|
|
993
|
-
let e = localStorage.getItem(
|
|
1120
|
+
}, G = "puzzmo_sim_oauth_token", K = "puzzmo_sim_oauth_refresh_token", ve = (e) => localStorage.setItem(G, e), ye = (e) => localStorage.setItem(K, e), q = () => {
|
|
1121
|
+
let e = localStorage.getItem(G);
|
|
994
1122
|
return e && `${e.substring(0, 20)}`, e;
|
|
995
|
-
},
|
|
996
|
-
localStorage.removeItem(
|
|
997
|
-
},
|
|
998
|
-
let e =
|
|
1123
|
+
}, J = () => localStorage.getItem(K), Y = () => {
|
|
1124
|
+
localStorage.removeItem(G), localStorage.removeItem(K);
|
|
1125
|
+
}, be = () => {
|
|
1126
|
+
let e = W(), t = _e();
|
|
999
1127
|
sessionStorage.setItem("oauth_state", t), sessionStorage.setItem("oauth_return_url", window.location.href);
|
|
1000
1128
|
let n = new URL(`${e.apiURL}/oauth/auth`);
|
|
1001
1129
|
n.searchParams.set("client_id", e.clientID), n.searchParams.set("response_type", "code"), n.searchParams.set("redirect_uri", e.redirectUri), n.searchParams.set("state", t), window.location.href = n.toString();
|
|
1002
|
-
},
|
|
1130
|
+
}, xe = (e) => {
|
|
1003
1131
|
try {
|
|
1004
1132
|
let t = e.split(".");
|
|
1005
1133
|
if (t.length !== 3) return !0;
|
|
@@ -1008,11 +1136,11 @@ var I = "puzzmo_sim_api_mode", L = "http://localhost:8911", R = "https://api.puz
|
|
|
1008
1136
|
} catch (e) {
|
|
1009
1137
|
return !0;
|
|
1010
1138
|
}
|
|
1011
|
-
},
|
|
1139
|
+
}, Se = function() {
|
|
1012
1140
|
var e = t(function* () {
|
|
1013
|
-
let e =
|
|
1141
|
+
let e = J();
|
|
1014
1142
|
if (!e) return !1;
|
|
1015
|
-
let t =
|
|
1143
|
+
let t = W();
|
|
1016
1144
|
try {
|
|
1017
1145
|
let n = new URLSearchParams({
|
|
1018
1146
|
grant_type: "refresh_token",
|
|
@@ -1026,9 +1154,9 @@ var I = "puzzmo_sim_api_mode", L = "http://localhost:8911", R = "https://api.puz
|
|
|
1026
1154
|
if (!r.ok) return r.statusText, !1;
|
|
1027
1155
|
let i = yield r.json(), a = i.access_token || i.accessToken;
|
|
1028
1156
|
if (!a) return !1;
|
|
1029
|
-
|
|
1157
|
+
ve(a);
|
|
1030
1158
|
let o = i.refresh_token || i.refreshToken;
|
|
1031
|
-
return o &&
|
|
1159
|
+
return o && ye(o), !0;
|
|
1032
1160
|
} catch (e) {
|
|
1033
1161
|
return !1;
|
|
1034
1162
|
}
|
|
@@ -1036,9 +1164,9 @@ var I = "puzzmo_sim_api_mode", L = "http://localhost:8911", R = "https://api.puz
|
|
|
1036
1164
|
return function() {
|
|
1037
1165
|
return e.apply(this, arguments);
|
|
1038
1166
|
};
|
|
1039
|
-
}(),
|
|
1167
|
+
}(), Ce = function() {
|
|
1040
1168
|
var e = t(function* (e, t) {
|
|
1041
|
-
let n =
|
|
1169
|
+
let n = W(), r = sessionStorage.getItem("oauth_state");
|
|
1042
1170
|
if (!r || r !== t) return null;
|
|
1043
1171
|
sessionStorage.removeItem("oauth_state");
|
|
1044
1172
|
try {
|
|
@@ -1060,13 +1188,13 @@ var I = "puzzmo_sim_api_mode", L = "http://localhost:8911", R = "https://api.puz
|
|
|
1060
1188
|
return function(t, n) {
|
|
1061
1189
|
return e.apply(this, arguments);
|
|
1062
1190
|
};
|
|
1063
|
-
}(),
|
|
1191
|
+
}(), we = function() {
|
|
1064
1192
|
var e = t(function* (e, t = {}) {
|
|
1065
|
-
let n =
|
|
1193
|
+
let n = W(), r = q();
|
|
1066
1194
|
if (!r) throw Error("Not authenticated");
|
|
1067
|
-
if (
|
|
1068
|
-
if (r =
|
|
1069
|
-
} else throw
|
|
1195
|
+
if (xe(r)) if (yield Se()) {
|
|
1196
|
+
if (r = q(), !r) throw Error("Token refresh succeeded but no token available");
|
|
1197
|
+
} else throw Y(), Error("Session expired. Please log in again.");
|
|
1070
1198
|
let i = yield fetch(`${n.apiURL}/graphql`, {
|
|
1071
1199
|
method: "POST",
|
|
1072
1200
|
headers: {
|
|
@@ -1085,7 +1213,7 @@ var I = "puzzmo_sim_api_mode", L = "http://localhost:8911", R = "https://api.puz
|
|
|
1085
1213
|
return function(t) {
|
|
1086
1214
|
return e.apply(this, arguments);
|
|
1087
1215
|
};
|
|
1088
|
-
}(),
|
|
1216
|
+
}(), Te = (e) => {
|
|
1089
1217
|
try {
|
|
1090
1218
|
let t = e.split(".");
|
|
1091
1219
|
return t.length, t.length === 3 ? JSON.parse(atob(t[1])) : null;
|
|
@@ -1093,15 +1221,15 @@ var I = "puzzmo_sim_api_mode", L = "http://localhost:8911", R = "https://api.puz
|
|
|
1093
1221
|
return null;
|
|
1094
1222
|
}
|
|
1095
1223
|
};
|
|
1096
|
-
function
|
|
1224
|
+
function Ee() {
|
|
1097
1225
|
let e = !1;
|
|
1098
1226
|
return {
|
|
1099
1227
|
id: "auth",
|
|
1100
1228
|
label: "Auth",
|
|
1101
1229
|
render() {
|
|
1102
|
-
let e =
|
|
1230
|
+
let e = q(), t = !!e, n = H(), r = n === "dev" ? B : V, i = `<button class="simulator-btn tiny" id="auth-dev-toggle" style="display: none;">${n === "dev" ? "Using Dev" : "Dev"}</button>`;
|
|
1103
1231
|
if (t) {
|
|
1104
|
-
let t =
|
|
1232
|
+
let t = Te(e), n = t != null && t.exp ? (/* @__PURE__ */ new Date(t.exp * 1e3)).toLocaleString() : "Unknown", a = !!J(), o = a ? Te(J()) : null, s = o != null && o.exp ? (/* @__PURE__ */ new Date(o.exp * 1e3)).toLocaleString() : null;
|
|
1105
1233
|
return `
|
|
1106
1234
|
<div class="simulator-section">
|
|
1107
1235
|
<div class="simulator-section-title auth-title-row">
|
|
@@ -1142,7 +1270,7 @@ function Ce() {
|
|
|
1142
1270
|
</div>
|
|
1143
1271
|
<p class="auth-description">
|
|
1144
1272
|
Login with your Puzzmo account to make authenticated API requests.
|
|
1145
|
-
${n === "dev" ? `<br><strong>Using local dev server:</strong> ${
|
|
1273
|
+
${n === "dev" ? `<br><strong>Using local dev server:</strong> ${B}` : ""}
|
|
1146
1274
|
</p>
|
|
1147
1275
|
<div class="simulator-row">
|
|
1148
1276
|
<button class="simulator-btn primary" id="auth-login">Login with Puzzmo</button>
|
|
@@ -1153,21 +1281,21 @@ function Ce() {
|
|
|
1153
1281
|
},
|
|
1154
1282
|
bind(n) {
|
|
1155
1283
|
let r = n.getElement("#auth-login"), i = n.getElement("#auth-logout"), a = n.getElement("#auth-refresh"), o = n.getElement("#auth-test-api"), s = n.getElement("#auth-api-result"), c = n.getElement("#auth-dev-toggle");
|
|
1156
|
-
e ?
|
|
1157
|
-
e && c && (c.style.display = "",
|
|
1284
|
+
e ? U && c && (c.style.display = "", H() === "dev" && c.classList.add("active")) : (e = !0, ge().then((e) => {
|
|
1285
|
+
e && c && (c.style.display = "", H() === "dev" && c.classList.add("active"));
|
|
1158
1286
|
})), c == null || c.addEventListener("click", () => {
|
|
1159
|
-
|
|
1287
|
+
he(H() === "dev" ? "prod" : "dev"), Y(), window.location.reload();
|
|
1160
1288
|
}), r == null || r.addEventListener("click", () => {
|
|
1161
|
-
|
|
1289
|
+
be();
|
|
1162
1290
|
}), i == null || i.addEventListener("click", () => {
|
|
1163
|
-
|
|
1291
|
+
Y(), window.location.reload();
|
|
1164
1292
|
}), a == null || a.addEventListener("click", t(function* () {
|
|
1165
|
-
a.disabled = !0, a.textContent = "Refreshing...", (yield
|
|
1293
|
+
a.disabled = !0, a.textContent = "Refreshing...", (yield Se()) ? window.location.reload() : (a.textContent = "Refresh Failed", a.disabled = !1);
|
|
1166
1294
|
})), o == null || o.addEventListener("click", t(function* () {
|
|
1167
1295
|
if (s) {
|
|
1168
1296
|
s.innerHTML = "<div class=\"loading\">Loading...</div>";
|
|
1169
1297
|
try {
|
|
1170
|
-
let t = yield
|
|
1298
|
+
let t = yield we("\n query {\n currentUser {\n id\n username\n usernameID\n name\n }\n }\n ");
|
|
1171
1299
|
if (t.errors) {
|
|
1172
1300
|
var e;
|
|
1173
1301
|
s.innerHTML = `<div class="error">Error: ${((e = t.errors[0]) == null ? void 0 : e.message) || "Unknown error"}</div>`;
|
|
@@ -1189,13 +1317,13 @@ function Ce() {
|
|
|
1189
1317
|
if (n && r) {
|
|
1190
1318
|
let t = e.getElement("#auth-status");
|
|
1191
1319
|
t && (t.innerHTML = "<span class=\"indicator waiting\"></span><span>Exchanging code...</span>");
|
|
1192
|
-
let i = yield
|
|
1320
|
+
let i = yield Ce(n, r);
|
|
1193
1321
|
if (window.history.replaceState({}, "", window.location.pathname), i) {
|
|
1194
1322
|
let e = i.access_token || i.accessToken;
|
|
1195
1323
|
if (e) {
|
|
1196
|
-
|
|
1324
|
+
ve(e);
|
|
1197
1325
|
let t = i.refresh_token || i.refreshToken;
|
|
1198
|
-
t &&
|
|
1326
|
+
t && ye(t);
|
|
1199
1327
|
}
|
|
1200
1328
|
window.location.reload();
|
|
1201
1329
|
} else {
|
|
@@ -1207,9 +1335,9 @@ function Ce() {
|
|
|
1207
1335
|
}
|
|
1208
1336
|
};
|
|
1209
1337
|
}
|
|
1210
|
-
var
|
|
1211
|
-
localStorage.removeItem(
|
|
1212
|
-
},
|
|
1338
|
+
var De = "puzzmo_sim_api_mode", Oe = "http://localhost:8911", ke = "https://api.puzzmo.com", X = "puzzmo_sim_oauth_token", Ae = "puzzmo_sim_oauth_refresh_token", je = () => localStorage.getItem(De) === "dev" ? "dev" : "prod", Me = () => localStorage.getItem(X), Ne = () => localStorage.getItem(Ae), Pe = (e) => localStorage.setItem(X, e), Fe = (e) => localStorage.setItem(Ae, e), Ie = () => {
|
|
1339
|
+
localStorage.removeItem(X), localStorage.removeItem(Ae);
|
|
1340
|
+
}, Le = (e) => {
|
|
1213
1341
|
try {
|
|
1214
1342
|
let t = e.split(".");
|
|
1215
1343
|
if (t.length !== 3) return !0;
|
|
@@ -1218,11 +1346,11 @@ var we = "puzzmo_sim_api_mode", Te = "http://localhost:8911", Ee = "https://api.
|
|
|
1218
1346
|
} catch (e) {
|
|
1219
1347
|
return !0;
|
|
1220
1348
|
}
|
|
1221
|
-
},
|
|
1349
|
+
}, Re = function() {
|
|
1222
1350
|
var e = t(function* () {
|
|
1223
|
-
let e =
|
|
1351
|
+
let e = Ne();
|
|
1224
1352
|
if (!e) return !1;
|
|
1225
|
-
let t =
|
|
1353
|
+
let t = je() === "dev" ? Oe : ke;
|
|
1226
1354
|
try {
|
|
1227
1355
|
let n = new URLSearchParams({
|
|
1228
1356
|
grant_type: "refresh_token",
|
|
@@ -1236,9 +1364,9 @@ var we = "puzzmo_sim_api_mode", Te = "http://localhost:8911", Ee = "https://api.
|
|
|
1236
1364
|
if (!r.ok) return !1;
|
|
1237
1365
|
let i = yield r.json(), a = i.access_token || i.accessToken;
|
|
1238
1366
|
if (!a) return !1;
|
|
1239
|
-
|
|
1367
|
+
Pe(a);
|
|
1240
1368
|
let o = i.refresh_token || i.refreshToken;
|
|
1241
|
-
return o &&
|
|
1369
|
+
return o && Fe(o), !0;
|
|
1242
1370
|
} catch (e) {
|
|
1243
1371
|
return !1;
|
|
1244
1372
|
}
|
|
@@ -1246,13 +1374,13 @@ var we = "puzzmo_sim_api_mode", Te = "http://localhost:8911", Ee = "https://api.
|
|
|
1246
1374
|
return function() {
|
|
1247
1375
|
return e.apply(this, arguments);
|
|
1248
1376
|
};
|
|
1249
|
-
}(),
|
|
1377
|
+
}(), ze = function() {
|
|
1250
1378
|
var e = t(function* (e, t = {}) {
|
|
1251
|
-
let n =
|
|
1379
|
+
let n = je() === "dev" ? Oe : ke, r = Me();
|
|
1252
1380
|
if (!r) throw Error("Not authenticated");
|
|
1253
|
-
if (
|
|
1254
|
-
if (r =
|
|
1255
|
-
} else throw
|
|
1381
|
+
if (Le(r)) if (yield Re()) {
|
|
1382
|
+
if (r = Me(), !r) throw Error("Token refresh succeeded but no token available");
|
|
1383
|
+
} else throw Ie(), Error("Session expired. Please log in again.");
|
|
1256
1384
|
let i = yield fetch(`${n}/graphql`, {
|
|
1257
1385
|
method: "POST",
|
|
1258
1386
|
headers: {
|
|
@@ -1271,19 +1399,19 @@ var we = "puzzmo_sim_api_mode", Te = "http://localhost:8911", Ee = "https://api.
|
|
|
1271
1399
|
return function(t) {
|
|
1272
1400
|
return e.apply(this, arguments);
|
|
1273
1401
|
};
|
|
1274
|
-
}(),
|
|
1402
|
+
}(), Be = "\n query GameFeaturesQuery($slug: ID!) {\n game(id: $slug) {\n id\n slug\n displayName\n featuresArr\n gameFeatures {\n slug\n title\n features {\n featureID\n title\n isEnabled\n }\n }\n }\n }\n", Ve = "\n mutation ToggleFeatureMutation($gameSlug: ID!, $input: UpdateGameInput!) {\n updateGame(id: $gameSlug, input: $input) {\n id\n featuresArr\n gameFeatures {\n slug\n title\n features {\n featureID\n title\n isEnabled\n }\n }\n }\n }\n", He = (e, t) => {
|
|
1275
1403
|
let n = t - 1, r = Math.floor(n / 31), i = n % 31, a = [...e];
|
|
1276
1404
|
for (; a.length <= r;) a.push(0);
|
|
1277
1405
|
return a[r] = a[r] ^ 1 << i, a;
|
|
1278
1406
|
};
|
|
1279
|
-
const
|
|
1280
|
-
function
|
|
1407
|
+
const Ue = () => !!Me();
|
|
1408
|
+
function We() {
|
|
1281
1409
|
let n = null, r = !1, i = null, a = function() {
|
|
1282
1410
|
var e = t(function* (e) {
|
|
1283
1411
|
r = !0, i = null;
|
|
1284
1412
|
try {
|
|
1285
1413
|
var t;
|
|
1286
|
-
let r = yield
|
|
1414
|
+
let r = yield ze(Be, { slug: e });
|
|
1287
1415
|
if (r.errors) {
|
|
1288
1416
|
var a;
|
|
1289
1417
|
i = ((a = r.errors[0]) == null ? void 0 : a.message) || "Unknown error", n = null;
|
|
@@ -1300,10 +1428,10 @@ function ze() {
|
|
|
1300
1428
|
}(), o = function() {
|
|
1301
1429
|
var r = t(function* (t) {
|
|
1302
1430
|
if (!n) return;
|
|
1303
|
-
let r =
|
|
1431
|
+
let r = He(n.featuresArr, t);
|
|
1304
1432
|
try {
|
|
1305
1433
|
var i;
|
|
1306
|
-
let t = yield
|
|
1434
|
+
let t = yield ze(Ve, {
|
|
1307
1435
|
gameSlug: n.slug,
|
|
1308
1436
|
input: { featuresArr: r }
|
|
1309
1437
|
});
|
|
@@ -1351,7 +1479,7 @@ function ze() {
|
|
|
1351
1479
|
id: "features",
|
|
1352
1480
|
label: "Features",
|
|
1353
1481
|
render() {
|
|
1354
|
-
return
|
|
1482
|
+
return Ue() ? `
|
|
1355
1483
|
<div class="features-view-container">
|
|
1356
1484
|
<div class="simulator-section">
|
|
1357
1485
|
<div class="simulator-section-title">Game Features</div>
|
|
@@ -1392,7 +1520,7 @@ function ze() {
|
|
|
1392
1520
|
e && (yield d(e));
|
|
1393
1521
|
})), i == null || i.addEventListener("keypress", (e) => {
|
|
1394
1522
|
e.key === "Enter" && (r == null || r.click());
|
|
1395
|
-
}), console.log("[FeaturesView] bind called, ctx.gameSlug:", e.gameSlug, "slugInput:", i), e.gameSlug && i && (i.value = e.gameSlug,
|
|
1523
|
+
}), console.log("[FeaturesView] bind called, ctx.gameSlug:", e.gameSlug, "slugInput:", i), e.gameSlug && i && (i.value = e.gameSlug, Ue() && !n && d(e.gameSlug)), u();
|
|
1396
1524
|
},
|
|
1397
1525
|
onActivate(e) {
|
|
1398
1526
|
let t = e.getElement("#simulator-tab-features");
|
|
@@ -1401,7 +1529,7 @@ function ze() {
|
|
|
1401
1529
|
};
|
|
1402
1530
|
}
|
|
1403
1531
|
/** Renders a single keyboard key as an HTML button string */
|
|
1404
|
-
var
|
|
1532
|
+
var Ge = (e, t) => {
|
|
1405
1533
|
var n, r;
|
|
1406
1534
|
let i = (n = t.symbols[e]) == null ? e : n, a = t.disabled.includes(e), o = t.highlight.includes(e), s = t.xl.includes(e), c = t.l.includes(e), l = (r = t.flexGrowSymbols) == null ? void 0 : r.includes(e);
|
|
1407
1535
|
return `<button class="${[
|
|
@@ -1412,9 +1540,9 @@ var Be = (e, t) => {
|
|
|
1412
1540
|
c ? "l" : "",
|
|
1413
1541
|
l ? "grow" : ""
|
|
1414
1542
|
].filter(Boolean).join(" ")}" data-key="${e}" ${a ? "disabled" : ""}>${i}</button>`;
|
|
1415
|
-
},
|
|
1416
|
-
function
|
|
1417
|
-
let e = null, t = () => e ?
|
|
1543
|
+
}, Ke = (e) => `<div class="sim-kb">${e.layout.filter((e) => e != null).map((t) => `<div class="sim-kb-row">${[...t].map((t) => Ge(t, e)).join("")}</div>`).join("")}</div>`;
|
|
1544
|
+
function qe() {
|
|
1545
|
+
let e = null, t = () => e ? Ke(e) : "<div class=\"sim-kb-empty\">No keyboard config received from game yet.<br>The game calls <code>sdk.keyboard.show(config)</code> to display a keyboard.</div>";
|
|
1418
1546
|
return {
|
|
1419
1547
|
id: "kbd",
|
|
1420
1548
|
label: "Kbd",
|
|
@@ -1428,19 +1556,19 @@ function He() {
|
|
|
1428
1556
|
`;
|
|
1429
1557
|
},
|
|
1430
1558
|
bind(e) {
|
|
1431
|
-
|
|
1559
|
+
Je(e);
|
|
1432
1560
|
},
|
|
1433
1561
|
onMessage(n, r, i) {
|
|
1434
1562
|
var a;
|
|
1435
1563
|
if (n !== "KEYBOARD_UPDATE_CONFIG") return;
|
|
1436
1564
|
e = !(!(r == null || (a = r.layout) == null) && a.length) || r.layout.every((e) => !e) ? null : r;
|
|
1437
1565
|
let o = i.getElement("#sim-kb-content");
|
|
1438
|
-
o && (o.innerHTML = t(),
|
|
1566
|
+
o && (o.innerHTML = t(), Je(i)), i.updateBadge("kbd", void 0);
|
|
1439
1567
|
}
|
|
1440
1568
|
};
|
|
1441
1569
|
}
|
|
1442
1570
|
/** Attach click handlers to all rendered keys */
|
|
1443
|
-
function
|
|
1571
|
+
function Je(e) {
|
|
1444
1572
|
var t;
|
|
1445
1573
|
let n = (t = e.getElement("#sim-kb-content")) == null ? void 0 : t.querySelectorAll(".sim-kb-key");
|
|
1446
1574
|
n == null || n.forEach((t) => {
|
|
@@ -1455,15 +1583,15 @@ function X(e) {
|
|
|
1455
1583
|
* change values (persisted to localStorage and pushed to the game as SETTINGS_UPDATE, matching the
|
|
1456
1584
|
* production host) and reflects UPDATE_SETTINGS_FROM_EMBED writes coming from the game.
|
|
1457
1585
|
*/
|
|
1458
|
-
function
|
|
1586
|
+
function Ye() {
|
|
1459
1587
|
let t = (e) => {
|
|
1460
1588
|
let t = e.state.settingsComponents;
|
|
1461
|
-
return !t || t.length === 0 ? "<div class=\"sim-settings-empty\">No settings registered by the game yet.<br>The game calls <code>sdk.settings.initialize(components)</code> to describe its settings UI.</div>" : `<div class="sim-settings-form">${t.map((t) =>
|
|
1589
|
+
return !t || t.length === 0 ? "<div class=\"sim-settings-empty\">No settings registered by the game yet.<br>The game calls <code>sdk.settings.initialize(components)</code> to describe its settings UI.</div>" : `<div class="sim-settings-form">${t.map((t) => Xe(t, e.state.gameSettings)).join("")}</div><div class="sim-settings-actions"><button class="simulator-btn tiny" id="sim-settings-reset">Reset to defaults</button></div>`;
|
|
1462
1590
|
}, n = (e) => {
|
|
1463
1591
|
let n = e.getElement("#sim-settings-content");
|
|
1464
1592
|
n && (n.innerHTML = t(e), i(e));
|
|
1465
1593
|
}, r = (e) => {
|
|
1466
|
-
|
|
1594
|
+
m(e.state.gameSettings), e.sendToGame("SETTINGS_UPDATE", e.state.gameSettings);
|
|
1467
1595
|
}, i = (t) => {
|
|
1468
1596
|
var i;
|
|
1469
1597
|
let a = t.getElement("#sim-settings-content");
|
|
@@ -1479,7 +1607,7 @@ function Ue() {
|
|
|
1479
1607
|
});
|
|
1480
1608
|
}), (i = a.querySelector("#sim-settings-reset")) == null || i.addEventListener("click", () => {
|
|
1481
1609
|
var e;
|
|
1482
|
-
|
|
1610
|
+
h(), t.state.gameSettings = Ze((e = t.state.settingsComponents) == null ? [] : e), r(t), n(t);
|
|
1483
1611
|
}));
|
|
1484
1612
|
};
|
|
1485
1613
|
return {
|
|
@@ -1494,21 +1622,21 @@ function Ue() {
|
|
|
1494
1622
|
onMessage(t, r, i) {
|
|
1495
1623
|
if (t === "INITIALIZE_SETTINGS") {
|
|
1496
1624
|
var a;
|
|
1497
|
-
i.state.settingsComponents = (a = r == null ? void 0 : r.components) == null ? [] : a, i.state.gameSettings = e(e({}, r == null ? void 0 : r.settings), i.state.gameSettings),
|
|
1625
|
+
i.state.settingsComponents = (a = r == null ? void 0 : r.components) == null ? [] : a, i.state.gameSettings = e(e({}, r == null ? void 0 : r.settings), i.state.gameSettings), m(i.state.gameSettings), n(i);
|
|
1498
1626
|
return;
|
|
1499
1627
|
}
|
|
1500
|
-
t === "UPDATE_SETTINGS_FROM_EMBED" && (i.state.gameSettings = e(e({}, i.state.gameSettings), r == null ? void 0 : r.settings),
|
|
1628
|
+
t === "UPDATE_SETTINGS_FROM_EMBED" && (i.state.gameSettings = e(e({}, i.state.gameSettings), r == null ? void 0 : r.settings), m(i.state.gameSettings), n(i));
|
|
1501
1629
|
}
|
|
1502
1630
|
};
|
|
1503
1631
|
}
|
|
1504
1632
|
/** Renders a single settings UI component as HTML, reading its current value from `settings` */
|
|
1505
|
-
function
|
|
1633
|
+
function Xe(e, t) {
|
|
1506
1634
|
switch (e.type) {
|
|
1507
1635
|
case "title": return `<div class="sim-settings-heading">${Q(e.value)}</div>`;
|
|
1508
1636
|
case "subtitle": return `<div class="sim-settings-subheading">${Q(e.value)}</div>`;
|
|
1509
1637
|
case "paragraph": return `<p class="sim-settings-paragraph">${Q(e.value)}</p>`;
|
|
1510
1638
|
case "separator": return "<div class=\"simulator-divider\"></div>";
|
|
1511
|
-
case "split": return `<div class="sim-settings-split">${e.content.map((e) =>
|
|
1639
|
+
case "split": return `<div class="sim-settings-split">${e.content.map((e) => Xe(e, t)).join("")}</div>`;
|
|
1512
1640
|
case "boolean": {
|
|
1513
1641
|
var n;
|
|
1514
1642
|
let r = ((n = t[e.name]) == null ? e.defaultValue : n) ? "checked" : "", i = e.subtitle ? `<div class="sim-settings-subtitle">${Q(e.subtitle)}</div>` : "";
|
|
@@ -1576,9 +1704,9 @@ function Z(e) {
|
|
|
1576
1704
|
return `<span class="simulator-label">${Q(e.title)}</span>${t}`;
|
|
1577
1705
|
}
|
|
1578
1706
|
/** Collects name → defaultValue pairs from components, recursing into split groups */
|
|
1579
|
-
function
|
|
1707
|
+
function Ze(e) {
|
|
1580
1708
|
let t = {};
|
|
1581
|
-
for (let n of e) n.type === "split" ? Object.assign(t,
|
|
1709
|
+
for (let n of e) n.type === "split" ? Object.assign(t, Ze(n.content)) : "name" in n && (t[n.name] = n.defaultValue);
|
|
1582
1710
|
return t;
|
|
1583
1711
|
}
|
|
1584
1712
|
function Q(e) {
|
|
@@ -1622,33 +1750,35 @@ var $ = null;
|
|
|
1622
1750
|
* Fixtures are loaded as raw strings and passed to the game verbatim (any text format works; the game parses it).
|
|
1623
1751
|
* This will show dropdowns in the Ctrl tab to select category and puzzle.
|
|
1624
1752
|
*/
|
|
1625
|
-
function
|
|
1626
|
-
var n, r;
|
|
1753
|
+
function Qe(e = {}) {
|
|
1754
|
+
var n, r, i;
|
|
1627
1755
|
if (console.log("[Simulator] createSimulator called with config:", {
|
|
1628
1756
|
slug: e.slug,
|
|
1629
1757
|
hasFixtures: !!e.fixtures
|
|
1630
1758
|
}), $) return e.fixtures && (console.log("[Simulator] Instance already exists, updating fixtures"), $.updateFixtures(e.fixtures)), $;
|
|
1631
|
-
let
|
|
1632
|
-
|
|
1633
|
-
oe(),
|
|
1634
|
-
s,
|
|
1759
|
+
let a = (n = e.autoStart) == null ? !0 : n, o = e.fixtures ? oe(e.fixtures) : null, s = o ? Array.from(o.keys()).sort() : [], c = le(), l = fe(), u = [
|
|
1760
|
+
se(),
|
|
1635
1761
|
ce(),
|
|
1636
|
-
le(),
|
|
1637
1762
|
c,
|
|
1763
|
+
ue(),
|
|
1638
1764
|
de(),
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1765
|
+
l,
|
|
1766
|
+
pe(),
|
|
1767
|
+
me(e.hostContextPresets),
|
|
1768
|
+
Ee(),
|
|
1769
|
+
We(),
|
|
1770
|
+
qe(),
|
|
1771
|
+
Ye(),
|
|
1772
|
+
...(r = e.views) == null ? [] : r
|
|
1773
|
+
], d = u.map((e) => e.id), f = p(e, s, d), m = {
|
|
1644
1774
|
pause: "<svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"currentColor\"><rect x=\"1\" y=\"1\" width=\"3\" height=\"8\"/><rect x=\"6\" y=\"1\" width=\"3\" height=\"8\"/></svg>",
|
|
1645
1775
|
play: "<svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"currentColor\"><polygon points=\"2,1 9,5 2,9\"/></svg>",
|
|
1646
1776
|
retry: "<svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"currentColor\"><path d=\"M5 1C2.8 1 1 2.8 1 5s1.8 4 4 4c1.8 0 3.3-1.2 3.8-2.8H7.5c-.4.9-1.3 1.5-2.5 1.5-1.5 0-2.7-1.2-2.7-2.7S3.5 2.3 5 2.3c.7 0 1.4.3 1.9.8L5.5 4.5H9V1L7.6 2.4C6.9 1.5 5.9 1 5 1z\"/></svg>",
|
|
1647
1777
|
cog: "<svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"currentColor\"><path d=\"M9.5 5.8l-.8-.5c0-.2.1-.5.1-.8s0-.5-.1-.8l.8-.5c.1-.1.2-.2.1-.4l-.8-1.4c-.1-.1-.2-.2-.4-.1l-1 .3c-.3-.3-.7-.5-1.1-.6L6.1.2C6.1.1 6 0 5.8 0H4.2c-.2 0-.3.1-.3.2l-.2 1c-.4.1-.7.3-1.1.6l-1-.3c-.2 0-.3 0-.4.1l-.8 1.4c-.1.2 0 .3.1.4l.8.5c0 .2-.1.5-.1.8s0 .5.1.8l-.8.5c-.1.1-.2.2-.1.4l.8 1.4c.1.1.2.2.4.1l1-.3c.3.3.7.5 1.1.6l.2 1c0 .1.1.2.3.2h1.6c.2 0 .3-.1.3-.2l.2-1c.4-.1.7-.3 1.1-.6l1 .3c.2 0 .3 0 .4-.1l.8-1.4c.1-.2 0-.3-.1-.4zM5 6.5c-.8 0-1.5-.7-1.5-1.5S4.2 3.5 5 3.5 6.5 4.2 6.5 5 5.8 6.5 5 6.5z\"/></svg>",
|
|
1648
1778
|
minimize: "<svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"currentColor\"><rect x=\"1\" y=\"4\" width=\"8\" height=\"2\"/></svg>",
|
|
1649
1779
|
expand: "<svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"currentColor\"><polygon points=\"1,1 7,4 1,7\"/></svg>"
|
|
1650
|
-
},
|
|
1651
|
-
|
|
1780
|
+
}, h = document.createElement("div");
|
|
1781
|
+
h.id = "simulator", h.innerHTML = `
|
|
1652
1782
|
<style>
|
|
1653
1783
|
:root {
|
|
1654
1784
|
--sim-bg: #1a1a2e;
|
|
@@ -2892,8 +3022,8 @@ function Ke(e = {}) {
|
|
|
2892
3022
|
<div id="simulator-timer">--:--</div>
|
|
2893
3023
|
<span class="header-sep">|</span>
|
|
2894
3024
|
<div id="simulator-header-controls">
|
|
2895
|
-
<button id="simulator-header-pause" class="header-icon-btn" title="Pause" disabled>${
|
|
2896
|
-
<button id="simulator-header-retry" class="header-icon-btn" title="Retry" disabled>${
|
|
3025
|
+
<button id="simulator-header-pause" class="header-icon-btn" title="Pause" disabled>${m.pause}</button>
|
|
3026
|
+
<button id="simulator-header-retry" class="header-icon-btn" title="Retry" disabled>${m.retry}</button>
|
|
2897
3027
|
</div>
|
|
2898
3028
|
<span class="header-sep">|</span>
|
|
2899
3029
|
<div id="simulator-header-status">
|
|
@@ -2901,104 +3031,104 @@ function Ke(e = {}) {
|
|
|
2901
3031
|
<span id="simulator-header-status-text">Waiting...</span>
|
|
2902
3032
|
</div>
|
|
2903
3033
|
<span class="header-spacer"></span>
|
|
2904
|
-
<button id="simulator-header-settings" class="header-icon-btn" title="Settings">${
|
|
2905
|
-
<button id="simulator-toggle" class="header-icon-btn" title="Minimize">${
|
|
3034
|
+
<button id="simulator-header-settings" class="header-icon-btn" title="Settings">${m.cog}</button>
|
|
3035
|
+
<button id="simulator-toggle" class="header-icon-btn" title="Minimize">${m.minimize}</button>
|
|
2906
3036
|
</div>
|
|
2907
3037
|
<div id="simulator-body">
|
|
2908
3038
|
<div id="simulator-tabs">
|
|
2909
|
-
${
|
|
3039
|
+
${u.filter((e) => e.id !== "auth").map((e) => `<button class="simulator-tab" data-tab="${e.id}">${e.label}<span class="simulator-tab-badge" data-badge="${e.id}"></span></button>`).join("")}
|
|
2910
3040
|
</div>
|
|
2911
3041
|
<div id="simulator-content" class="hidden">
|
|
2912
|
-
${
|
|
3042
|
+
${u.map((e) => `<div id="simulator-tab-${e.id}" class="simulator-tab-content">${e.render()}</div>`).join("")}
|
|
2913
3043
|
</div>
|
|
2914
3044
|
</div>
|
|
2915
3045
|
</div>
|
|
2916
|
-
`, document.body.appendChild(
|
|
2917
|
-
let
|
|
2918
|
-
|
|
3046
|
+
`, document.body.appendChild(h);
|
|
3047
|
+
let te = h.querySelector("#simulator-panel"), _ = h.querySelector("#simulator-header"), v = h.querySelector("#simulator-header-indicator"), ne = h.querySelector("#simulator-header-status-text"), y = h.querySelector("#simulator-header-pause"), b = h.querySelector("#simulator-header-retry"), x = h.querySelector("#simulator-header-settings"), S = h.querySelector("#simulator-toggle"), C = h.querySelector("#simulator-timer"), w = h.querySelector("#simulator-tabs"), T = h.querySelector("#simulator-content"), E = (e) => h.querySelector(e), D = (e) => {
|
|
3048
|
+
y.innerHTML = e ? m.play : m.pause, y.title = e ? "Resume" : "Pause";
|
|
3049
|
+
}, O = (e, t) => {
|
|
3050
|
+
let n = E("#simulator-status .text"), r = E("#simulator-status .indicator"), i = t === "complete" ? "✓" : "";
|
|
3051
|
+
n && (n.textContent = e), r && (r.className = `indicator ${t}`, r.textContent = i), v.className = t, v.textContent = i, ne.textContent = e;
|
|
2919
3052
|
}, k = (e, t) => {
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
}, A = (e, t) => {
|
|
2923
|
-
t && t !== "0" ? w.innerHTML = `${e}<span class="penalty">+${t}</span>` : w.textContent = e;
|
|
2924
|
-
}, j = (e) => {
|
|
3053
|
+
t && t !== "0" ? C.innerHTML = `${e}<span class="penalty">+${t}</span>` : C.textContent = e;
|
|
3054
|
+
}, A = (e) => {
|
|
2925
3055
|
var t;
|
|
2926
|
-
f.activeTab = e,
|
|
3056
|
+
f.activeTab = e, T.classList.remove("hidden"), ee(e), w.querySelectorAll(".simulator-tab").forEach((t) => {
|
|
2927
3057
|
t.classList.toggle("active", t.getAttribute("data-tab") === e);
|
|
2928
|
-
}),
|
|
3058
|
+
}), h.querySelectorAll(".simulator-tab-content").forEach((t) => {
|
|
2929
3059
|
t.classList.toggle("active", t.id === `simulator-tab-${e}`);
|
|
2930
|
-
}),
|
|
2931
|
-
let n =
|
|
2932
|
-
n == null || (t = n.onActivate) == null || t.call(n,
|
|
2933
|
-
},
|
|
2934
|
-
f.isCollapsed = e,
|
|
2935
|
-
},
|
|
2936
|
-
|
|
2937
|
-
},
|
|
3060
|
+
}), x.classList.toggle("active", e === "auth");
|
|
3061
|
+
let n = u.find((t) => t.id === e);
|
|
3062
|
+
n == null || (t = n.onActivate) == null || t.call(n, L);
|
|
3063
|
+
}, j = (e) => {
|
|
3064
|
+
f.isCollapsed = e, te.classList.toggle("collapsed", e), g(e), e ? (T.classList.add("hidden"), w.querySelectorAll(".simulator-tab").forEach((e) => e.classList.remove("active"))) : A(f.activeTab);
|
|
3065
|
+
}, M = () => {
|
|
3066
|
+
l.updatePreview(L);
|
|
3067
|
+
}, N = function() {
|
|
2938
3068
|
var e = t(function* () {
|
|
2939
3069
|
var e, t;
|
|
2940
3070
|
if (f.puzzleData) return f.puzzleData;
|
|
2941
|
-
if (!
|
|
2942
|
-
let n = (e = f.selectedCategory) == null ?
|
|
3071
|
+
if (!o || o.size === 0) throw Error("No fixtures configured. Add puzzle fixture files (.json or .toml) to a fixtures directory and pass fixturesGlob to the simulator.");
|
|
3072
|
+
let n = (e = f.selectedCategory) == null ? s[0] : e, r = n ? o.get(n) : void 0;
|
|
2943
3073
|
if (!r || r.size === 0) throw Error(`No puzzles found in fixture category "${n}"`);
|
|
2944
|
-
let i = (t = f.selectedPuzzle) == null ? r.keys().next().value : t,
|
|
2945
|
-
if (!
|
|
2946
|
-
f.puzzleData =
|
|
3074
|
+
let i = (t = f.selectedPuzzle) == null ? r.keys().next().value : t, a = i ? r.get(i) : void 0;
|
|
3075
|
+
if (!a) throw Error(`Puzzle "${i}" not found in category "${n}"`);
|
|
3076
|
+
f.puzzleData = a, console.log("Simulator: Puzzle loaded from fixtures", {
|
|
2947
3077
|
category: n,
|
|
2948
3078
|
puzzle: i
|
|
2949
|
-
}), f.originalPuzzle =
|
|
2950
|
-
let c =
|
|
2951
|
-
return c && (c.value = f.originalPuzzle), f.activeTab === "thumb" &&
|
|
3079
|
+
}), f.originalPuzzle = a;
|
|
3080
|
+
let c = E("#simulator-puzzle");
|
|
3081
|
+
return c && (c.value = f.originalPuzzle), f.activeTab === "thumb" && M(), f.puzzleData;
|
|
2952
3082
|
});
|
|
2953
3083
|
return function() {
|
|
2954
3084
|
return e.apply(this, arguments);
|
|
2955
3085
|
};
|
|
2956
|
-
}(),
|
|
2957
|
-
|
|
2958
|
-
}),
|
|
2959
|
-
|
|
2960
|
-
},
|
|
2961
|
-
let n =
|
|
3086
|
+
}(), P = re((e) => {
|
|
3087
|
+
c.addLogEntry(e, L);
|
|
3088
|
+
}), F = (e, t) => {
|
|
3089
|
+
ie(e, t, P);
|
|
3090
|
+
}, I = (e, t) => {
|
|
3091
|
+
let n = h.querySelector(`[data-badge="${e}"]`);
|
|
2962
3092
|
n && (n.textContent = t && t > 0 ? String(t) : "");
|
|
2963
|
-
},
|
|
3093
|
+
}, L = {
|
|
2964
3094
|
state: f,
|
|
2965
|
-
getElement:
|
|
2966
|
-
sendToGame:
|
|
2967
|
-
logMessage:
|
|
2968
|
-
loadPuzzle:
|
|
2969
|
-
updateStatus:
|
|
2970
|
-
updateTimer:
|
|
2971
|
-
setCollapsed:
|
|
2972
|
-
switchTab:
|
|
2973
|
-
updateThumbnail:
|
|
2974
|
-
updateBadge:
|
|
2975
|
-
fixtures:
|
|
2976
|
-
fixtureCategories:
|
|
2977
|
-
gameSlug: (
|
|
3095
|
+
getElement: E,
|
|
3096
|
+
sendToGame: F,
|
|
3097
|
+
logMessage: P.log,
|
|
3098
|
+
loadPuzzle: N,
|
|
3099
|
+
updateStatus: O,
|
|
3100
|
+
updateTimer: k,
|
|
3101
|
+
setCollapsed: j,
|
|
3102
|
+
switchTab: A,
|
|
3103
|
+
updateThumbnail: M,
|
|
3104
|
+
updateBadge: I,
|
|
3105
|
+
fixtures: o,
|
|
3106
|
+
fixtureCategories: s,
|
|
3107
|
+
gameSlug: (i = e.slug) == null ? null : i
|
|
2978
3108
|
};
|
|
2979
|
-
console.log("[Simulator] Context created with gameSlug:",
|
|
3109
|
+
console.log("[Simulator] Context created with gameSlug:", L.gameSlug), u.forEach((e) => e.bind(L)), w.querySelectorAll(".simulator-tab").forEach((e) => {
|
|
2980
3110
|
e.addEventListener("click", () => {
|
|
2981
3111
|
let t = e.getAttribute("data-tab");
|
|
2982
|
-
|
|
3112
|
+
A(t), I(t, 0);
|
|
2983
3113
|
});
|
|
2984
|
-
}),
|
|
2985
|
-
e.stopPropagation(),
|
|
2986
|
-
}),
|
|
2987
|
-
e.stopPropagation(), f.isPaused ? (
|
|
2988
|
-
let t =
|
|
3114
|
+
}), S.addEventListener("click", (e) => {
|
|
3115
|
+
e.stopPropagation(), j(!0);
|
|
3116
|
+
}), y.addEventListener("click", (e) => {
|
|
3117
|
+
e.stopPropagation(), f.isPaused ? (F("RESUME_GAME", {}), f.isPaused = !1, D(!1), O("Running", "ready")) : (F("PAUSE_GAME", {}), f.isPaused = !0, D(!0), O("Paused", "paused"));
|
|
3118
|
+
let t = E("#simulator-pause");
|
|
2989
3119
|
t && (t.textContent = f.isPaused ? "Resume" : "Pause");
|
|
2990
|
-
}),
|
|
2991
|
-
e.stopPropagation(),
|
|
2992
|
-
let t =
|
|
3120
|
+
}), b.addEventListener("click", (e) => {
|
|
3121
|
+
e.stopPropagation(), F("RETRY_PUZZLE", {}), f.hasStarted = !1, f.isPaused = !1, D(!1), y.disabled = !0, O("Ready to retry", "ready");
|
|
3122
|
+
let t = E("#simulator-pause"), n = E("#simulator-start");
|
|
2993
3123
|
t && (t.disabled = !0, t.textContent = "Pause"), n && (n.textContent = "Start");
|
|
2994
|
-
}),
|
|
2995
|
-
e.stopPropagation(), f.isCollapsed &&
|
|
2996
|
-
}),
|
|
2997
|
-
f.isCollapsed && e.target !==
|
|
2998
|
-
}), f.isCollapsed ||
|
|
2999
|
-
let
|
|
3000
|
-
(
|
|
3001
|
-
let
|
|
3124
|
+
}), x.addEventListener("click", (e) => {
|
|
3125
|
+
e.stopPropagation(), f.isCollapsed && j(!1), A("auth");
|
|
3126
|
+
}), _.addEventListener("click", (e) => {
|
|
3127
|
+
f.isCollapsed && e.target !== S && j(!1);
|
|
3128
|
+
}), f.isCollapsed || A(f.activeTab);
|
|
3129
|
+
let R = new URLSearchParams(window.location.search);
|
|
3130
|
+
(R.has("code") || R.has("error")) && (j(!1), A("auth"));
|
|
3131
|
+
let z = (e) => ({
|
|
3002
3132
|
userState: {
|
|
3003
3133
|
gameSettings: f.gameSettings,
|
|
3004
3134
|
id: "simulator-user",
|
|
@@ -3038,48 +3168,44 @@ function Ke(e = {}) {
|
|
|
3038
3168
|
}
|
|
3039
3169
|
} },
|
|
3040
3170
|
theme: f.selectedTheme,
|
|
3041
|
-
hostContext:
|
|
3042
|
-
type: "app",
|
|
3043
|
-
layout: "desktop",
|
|
3044
|
-
host: null
|
|
3045
|
-
}],
|
|
3171
|
+
hostContext: f.hostContext,
|
|
3046
3172
|
appRuntimeContract: "1.0"
|
|
3047
3173
|
}), B = function() {
|
|
3048
3174
|
var e = t(function* () {
|
|
3049
|
-
|
|
3175
|
+
O("Loading puzzle...", "waiting");
|
|
3050
3176
|
try {
|
|
3051
|
-
let e =
|
|
3052
|
-
|
|
3177
|
+
let e = z(yield N());
|
|
3178
|
+
O("Sending READY_DATA...", "waiting"), F("READY_DATA", e), O("Waiting for game to load...", "waiting");
|
|
3053
3179
|
} catch (e) {
|
|
3054
|
-
|
|
3180
|
+
O(`Error: ${e}`, "paused");
|
|
3055
3181
|
}
|
|
3056
3182
|
});
|
|
3057
3183
|
return function() {
|
|
3058
3184
|
return e.apply(this, arguments);
|
|
3059
3185
|
};
|
|
3060
|
-
}(),
|
|
3061
|
-
console.log("Simulator: Game loaded, ready to start"),
|
|
3186
|
+
}(), V = () => {
|
|
3187
|
+
console.log("Simulator: Game loaded, ready to start"), b.disabled = !1, u.forEach((e) => {
|
|
3062
3188
|
var t;
|
|
3063
|
-
return (t = e.onMessage) == null ? void 0 : t.call(e, "READY_GAME_LOADED", void 0,
|
|
3064
|
-
}),
|
|
3065
|
-
let e =
|
|
3066
|
-
e == null || e.click(),
|
|
3189
|
+
return (t = e.onMessage) == null ? void 0 : t.call(e, "READY_GAME_LOADED", void 0, L);
|
|
3190
|
+
}), a && !f.hasStarted && setTimeout(() => {
|
|
3191
|
+
let e = E("#simulator-start");
|
|
3192
|
+
e == null || e.click(), y.disabled = !1, f.hasStarted = !0, O("Running", "ready");
|
|
3067
3193
|
}, 100);
|
|
3068
3194
|
};
|
|
3069
|
-
return
|
|
3195
|
+
return ae((e, t) => {
|
|
3070
3196
|
var n, r;
|
|
3071
3197
|
if (e === "READY") {
|
|
3072
3198
|
console.log("Simulator: Received READY from game"), B();
|
|
3073
3199
|
return;
|
|
3074
3200
|
}
|
|
3075
3201
|
if (e === "READY_GAME_LOADED") {
|
|
3076
|
-
|
|
3202
|
+
V();
|
|
3077
3203
|
return;
|
|
3078
3204
|
}
|
|
3079
3205
|
if (e === "TIMER_TICK") {
|
|
3080
3206
|
if (t != null && t.display) {
|
|
3081
3207
|
let [e, n] = t.display;
|
|
3082
|
-
|
|
3208
|
+
k(e, n);
|
|
3083
3209
|
}
|
|
3084
3210
|
return;
|
|
3085
3211
|
}
|
|
@@ -3088,30 +3214,30 @@ function Ke(e = {}) {
|
|
|
3088
3214
|
console.log("Simulator: Sidebar update", t);
|
|
3089
3215
|
return;
|
|
3090
3216
|
}
|
|
3091
|
-
|
|
3217
|
+
u.forEach((n) => {
|
|
3092
3218
|
var r;
|
|
3093
|
-
return (r = n.onMessage) == null ? void 0 : r.call(n, e, t,
|
|
3219
|
+
return (r = n.onMessage) == null ? void 0 : r.call(n, e, t, L);
|
|
3094
3220
|
});
|
|
3095
3221
|
let i = (n = t == null || (r = t.input) == null ? void 0 : r.boardState) == null ? t == null ? void 0 : t.boardState : n;
|
|
3096
|
-
e === "UPLOAD_NEW_GAME_STATE" && i && (f.currentInputStr = i, f.activeTab === "thumb" &&
|
|
3097
|
-
},
|
|
3222
|
+
e === "UPLOAD_NEW_GAME_STATE" && i && (f.currentInputStr = i, f.activeTab === "thumb" && M(), console.log("Simulator: Game state uploaded", t)), e === "GAME_COMPLETED" && (console.log("Simulator: Game completed!", t), y.disabled = !0, f.hasStarted = !1, O("Completed!", "complete"));
|
|
3223
|
+
}, P), console.log("Simulator initialized"), $ = {
|
|
3098
3224
|
updateFixtures: (e) => {
|
|
3099
|
-
|
|
3225
|
+
o = oe(e), s = Array.from(o.keys()).sort(), L.fixtures = o, L.fixtureCategories = s;
|
|
3100
3226
|
let t = localStorage.getItem("simulator-fixture-category");
|
|
3101
|
-
if (!f.selectedCategory || !
|
|
3227
|
+
if (!f.selectedCategory || !s.includes(f.selectedCategory)) {
|
|
3102
3228
|
var n;
|
|
3103
|
-
f.selectedCategory = t &&
|
|
3229
|
+
f.selectedCategory = t && s.includes(t) ? t : (n = s[0]) == null ? null : n;
|
|
3104
3230
|
}
|
|
3105
|
-
let r =
|
|
3106
|
-
r == null || r.bind(
|
|
3107
|
-
categories:
|
|
3231
|
+
let r = u.find((e) => e.id === "ctrl");
|
|
3232
|
+
r == null || r.bind(L), console.log("Simulator: Fixtures updated", {
|
|
3233
|
+
categories: s,
|
|
3108
3234
|
selectedCategory: f.selectedCategory
|
|
3109
3235
|
});
|
|
3110
3236
|
},
|
|
3111
|
-
sendToGame:
|
|
3112
|
-
loadPuzzle:
|
|
3237
|
+
sendToGame: F,
|
|
3238
|
+
loadPuzzle: N
|
|
3113
3239
|
}, $;
|
|
3114
3240
|
}
|
|
3115
|
-
export {
|
|
3241
|
+
export { Qe as t };
|
|
3116
3242
|
|
|
3117
|
-
//# sourceMappingURL=createSimulator-
|
|
3243
|
+
//# sourceMappingURL=createSimulator-Bo6J_KC_.js.map
|