@joystyk/launcher 0.0.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +245 -2
  3. package/dist/browser/daily-prefetch.d.ts +8 -0
  4. package/dist/browser/daily-prefetch.js +32 -0
  5. package/dist/browser/daily-prefetch.js.map +1 -0
  6. package/dist/browser/index.d.ts +3 -0
  7. package/dist/browser/index.js +4 -0
  8. package/dist/browser/rooms.d.ts +2 -0
  9. package/dist/browser/rooms.js +49 -0
  10. package/dist/browser/rooms.js.map +1 -0
  11. package/dist/browser/services.d.ts +127 -0
  12. package/dist/browser/services.js +95 -0
  13. package/dist/browser/services.js.map +1 -0
  14. package/dist/browser/stage.d.ts +28 -0
  15. package/dist/browser/stage.js +1195 -0
  16. package/dist/browser/stage.js.map +1 -0
  17. package/dist/fixture/engine.d.ts +60 -0
  18. package/dist/fixture/engine.js +164 -0
  19. package/dist/fixture/engine.js.map +1 -0
  20. package/dist/fixture/index.d.ts +52 -0
  21. package/dist/fixture/index.js +63 -0
  22. package/dist/fixture/index.js.map +1 -0
  23. package/dist/fixture/module.d.ts +2 -0
  24. package/dist/fixture/module.js +135 -0
  25. package/dist/fixture/module.js.map +1 -0
  26. package/dist/fixture/probe.d.ts +10 -0
  27. package/dist/fixture/probe.js +19 -0
  28. package/dist/fixture/probe.js.map +1 -0
  29. package/dist/index.d.ts +3 -0
  30. package/dist/index.js +4 -0
  31. package/dist/launcher.d.ts +190 -0
  32. package/dist/launcher.js +4614 -0
  33. package/dist/launcher.js.map +1 -0
  34. package/dist/model.d.ts +431 -0
  35. package/dist/model.js +566 -0
  36. package/dist/model.js.map +1 -0
  37. package/dist/report-problem.d.ts +39 -0
  38. package/dist/report-problem.js +359 -0
  39. package/dist/report-problem.js.map +1 -0
  40. package/dist/report.d.ts +18 -0
  41. package/dist/report.js +32 -0
  42. package/dist/report.js.map +1 -0
  43. package/dist/room-drivers.d.ts +26 -0
  44. package/dist/room-drivers.js +92 -0
  45. package/dist/room-drivers.js.map +1 -0
  46. package/dist/safe-point.d.ts +33 -0
  47. package/dist/safe-point.js +44 -0
  48. package/dist/safe-point.js.map +1 -0
  49. package/dist/save-slots.d.ts +6 -0
  50. package/dist/save-slots.js +18 -0
  51. package/dist/save-slots.js.map +1 -0
  52. package/dist/theme.d.ts +35 -0
  53. package/dist/theme.js +111 -0
  54. package/dist/theme.js.map +1 -0
  55. package/package.json +67 -11
@@ -0,0 +1,4614 @@
1
+ import { reportSafePoint } from "./safe-point.js";
2
+ import { AI_NOTICE, MODE_LABELS, ONLINE_CHECKING, clockLabel, clockValue, computerSeatsFor, formatElapsed, initialSetup, isLauncherGame, isoDuration, modeOptions, needsAiNotice, offerAnnouncement, offerText, parseClockValue, parsePreferenceChange, parseRoomCode, parseStageOutput, pickMode, playerCounts, resultView, seatsFor, spacedCode, startProblem, toStageMode } from "./model.js";
3
+ import "./report-problem.js";
4
+ import { checkOnline, copyText, readInvite, shareText, showRoomInUrl } from "./room-drivers.js";
5
+ import { call, command, css, define, defineDriver, each, focus, intentsOf, keyed, nothing, prop } from "@gyral/core";
6
+ import { optionsForMode } from "@joystyk/contracts";
7
+ import { compiled } from "@gyral/core/compiled";
8
+ import "@joystyk/ui/ad-slot";
9
+ //#region src/launcher.ts
10
+ var _gyral$t0 = {
11
+ "id": "1744dly5uvw",
12
+ "html": "<form class=\"join\" aria-labelledby=\"join-title\"><h3 id=\"join-title\">Join a friend's room</h3><p class=\"field\"><label for=\"room-code\">Room code or invite link</label> <input id=\"room-code\" name=\"code\" autocomplete=\"off\" autocapitalize=\"characters\" spellcheck=\"false\" maxlength=\"200\"> <small id=\"room-code-hint\" class=\"note\">Six letters and digits, such as K7M 2QX.</small></p><p class=\"check\"><input type=\"checkbox\" id=\"room-watch\" name=\"watch\"> <label for=\"room-watch\">Just watch</label></p><div class=\"actions\"><button type=\"submit\" class=\"join-room\">Join room</button></div></form>",
13
+ "parts": [
14
+ [
15
+ 3,
16
+ [0],
17
+ "data-intent"
18
+ ],
19
+ [
20
+ 3,
21
+ [
22
+ 0,
23
+ 1,
24
+ 2
25
+ ],
26
+ "value"
27
+ ],
28
+ [
29
+ 3,
30
+ [
31
+ 0,
32
+ 1,
33
+ 2
34
+ ],
35
+ "aria-invalid"
36
+ ],
37
+ [
38
+ 3,
39
+ [
40
+ 0,
41
+ 1,
42
+ 2
43
+ ],
44
+ "aria-describedby"
45
+ ],
46
+ [
47
+ 3,
48
+ [
49
+ 0,
50
+ 1,
51
+ 2
52
+ ],
53
+ "data-intent"
54
+ ],
55
+ [
56
+ 2,
57
+ [0],
58
+ 2
59
+ ],
60
+ [
61
+ 5,
62
+ [
63
+ 0,
64
+ 2,
65
+ 0
66
+ ],
67
+ "checked"
68
+ ],
69
+ [
70
+ 3,
71
+ [
72
+ 0,
73
+ 2,
74
+ 0
75
+ ],
76
+ "data-intent"
77
+ ],
78
+ [
79
+ 5,
80
+ [
81
+ 0,
82
+ 3,
83
+ 0
84
+ ],
85
+ "disabled"
86
+ ]
87
+ ],
88
+ "segments": [
89
+ "<form class=\"join\" aria-labelledby=\"join-title\"",
90
+ {
91
+ "k": "attr",
92
+ "name": "data-intent"
93
+ },
94
+ "><h3 id=\"join-title\">Join a friend's room</h3><p class=\"field\"><label for=\"room-code\">Room code or invite link</label> <input id=\"room-code\" name=\"code\" autocomplete=\"off\" autocapitalize=\"characters\" spellcheck=\"false\" maxlength=\"200\"",
95
+ {
96
+ "k": "attr",
97
+ "name": "value"
98
+ },
99
+ {
100
+ "k": "attr",
101
+ "name": "aria-invalid"
102
+ },
103
+ {
104
+ "k": "attr",
105
+ "name": "aria-describedby"
106
+ },
107
+ {
108
+ "k": "attr",
109
+ "name": "data-intent"
110
+ },
111
+ "> <small id=\"room-code-hint\" class=\"note\">Six letters and digits, such as K7M 2QX.</small></p>",
112
+ {
113
+ "k": "child",
114
+ "in": "form"
115
+ },
116
+ "<p class=\"check\"><input type=\"checkbox\" id=\"room-watch\" name=\"watch\"",
117
+ {
118
+ "k": "bool",
119
+ "name": "checked"
120
+ },
121
+ {
122
+ "k": "attr",
123
+ "name": "data-intent"
124
+ },
125
+ "> <label for=\"room-watch\">Just watch</label></p><div class=\"actions\"><button type=\"submit\" class=\"join-room\"",
126
+ {
127
+ "k": "bool",
128
+ "name": "disabled"
129
+ },
130
+ ">Join room</button></div></form>"
131
+ ]
132
+ };
133
+ var _gyral$t1 = {
134
+ "id": "1293d8ofaon",
135
+ "html": "<p class=\"error\" id=\"room-code-error\"></p>",
136
+ "parts": [[1, [0]]],
137
+ "segments": [
138
+ "<p class=\"error\" id=\"room-code-error\">",
139
+ {
140
+ "k": "child",
141
+ "in": "p"
142
+ },
143
+ "</p>"
144
+ ]
145
+ };
146
+ var _gyral$t2 = {
147
+ "id": "1y4p7mb17gh",
148
+ "html": "<li class=\"seat\"><span class=\"seat-name\"></span> <small class=\"seat-tags\"></small> <!----> </li>",
149
+ "parts": [
150
+ [
151
+ 3,
152
+ [0],
153
+ "data-open"
154
+ ],
155
+ [
156
+ 3,
157
+ [0],
158
+ "data-ready"
159
+ ],
160
+ [1, [0, 0]],
161
+ [1, [0, 2]],
162
+ [
163
+ 2,
164
+ [0],
165
+ 4
166
+ ],
167
+ [0, [0]]
168
+ ],
169
+ "segments": [
170
+ "<li class=\"seat\"",
171
+ {
172
+ "k": "attr",
173
+ "name": "data-open"
174
+ },
175
+ {
176
+ "k": "attr",
177
+ "name": "data-ready"
178
+ },
179
+ "><span class=\"seat-name\">",
180
+ {
181
+ "k": "child",
182
+ "in": "span"
183
+ },
184
+ "</span> <small class=\"seat-tags\">",
185
+ {
186
+ "k": "child",
187
+ "in": "small"
188
+ },
189
+ "</small> ",
190
+ {
191
+ "k": "child",
192
+ "in": "li"
193
+ },
194
+ "<!----> ",
195
+ {
196
+ "k": "child",
197
+ "in": "li"
198
+ },
199
+ "</li>"
200
+ ]
201
+ };
202
+ var _gyral$t3 = {
203
+ "id": "i6qirpw7sh",
204
+ "html": "<button type=\"button\" class=\"small\">Add the computer<span class=\"visually-hidden\"> to seat </span></button>",
205
+ "parts": [
206
+ [
207
+ 3,
208
+ [0],
209
+ "value"
210
+ ],
211
+ [
212
+ 3,
213
+ [0],
214
+ "data-intent"
215
+ ],
216
+ [0, [0, 1]]
217
+ ],
218
+ "segments": [
219
+ "<button type=\"button\" class=\"small\"",
220
+ {
221
+ "k": "attr",
222
+ "name": "value"
223
+ },
224
+ {
225
+ "k": "attr",
226
+ "name": "data-intent"
227
+ },
228
+ ">Add the computer<span class=\"visually-hidden\"> to seat ",
229
+ {
230
+ "k": "child",
231
+ "in": "span"
232
+ },
233
+ "</span></button>"
234
+ ]
235
+ };
236
+ var _gyral$t4 = {
237
+ "id": "1yy965hyry9",
238
+ "html": "<button type=\"button\" class=\"small\">Remove<span class=\"visually-hidden\"> <!----> from seat </span></button>",
239
+ "parts": [
240
+ [
241
+ 3,
242
+ [0],
243
+ "value"
244
+ ],
245
+ [
246
+ 3,
247
+ [0],
248
+ "data-intent"
249
+ ],
250
+ [
251
+ 2,
252
+ [0, 1],
253
+ 1
254
+ ],
255
+ [0, [0, 1]]
256
+ ],
257
+ "segments": [
258
+ "<button type=\"button\" class=\"small\"",
259
+ {
260
+ "k": "attr",
261
+ "name": "value"
262
+ },
263
+ {
264
+ "k": "attr",
265
+ "name": "data-intent"
266
+ },
267
+ ">Remove<span class=\"visually-hidden\"> ",
268
+ {
269
+ "k": "child",
270
+ "in": "span"
271
+ },
272
+ "<!----> from seat ",
273
+ {
274
+ "k": "child",
275
+ "in": "span"
276
+ },
277
+ "</span></button>"
278
+ ]
279
+ };
280
+ var _gyral$t5 = {
281
+ "id": "qobqqeiasp",
282
+ "html": "<option></option>",
283
+ "parts": [
284
+ [
285
+ 3,
286
+ [0],
287
+ "value"
288
+ ],
289
+ [
290
+ 5,
291
+ [0],
292
+ "selected"
293
+ ],
294
+ [1, [0]]
295
+ ],
296
+ "segments": [
297
+ "<option",
298
+ {
299
+ "k": "attr",
300
+ "name": "value"
301
+ },
302
+ {
303
+ "k": "bool",
304
+ "name": "selected"
305
+ },
306
+ ">",
307
+ {
308
+ "k": "child",
309
+ "in": "option"
310
+ },
311
+ "</option>"
312
+ ]
313
+ };
314
+ var _gyral$t6 = {
315
+ "id": "13ti0qh2tcj",
316
+ "html": "<section class=\"lobby panel\" aria-labelledby=\"lobby-title\"><h3 id=\"lobby-title\" tabindex=\"-1\"><!----> room <span class=\"code\"></span></h3><p class=\"room-status\" role=\"status\"></p></section>",
317
+ "parts": [
318
+ [
319
+ 2,
320
+ [0, 0],
321
+ 0
322
+ ],
323
+ [1, [
324
+ 0,
325
+ 0,
326
+ 2
327
+ ]],
328
+ [1, [0, 1]],
329
+ [0, [0]]
330
+ ],
331
+ "segments": [
332
+ "<section class=\"lobby panel\" aria-labelledby=\"lobby-title\"><h3 id=\"lobby-title\" tabindex=\"-1\">",
333
+ {
334
+ "k": "child",
335
+ "in": "h3"
336
+ },
337
+ "<!----> room <span class=\"code\">",
338
+ {
339
+ "k": "child",
340
+ "in": "span"
341
+ },
342
+ "</span></h3><p class=\"room-status\" role=\"status\">",
343
+ {
344
+ "k": "child",
345
+ "in": "p"
346
+ },
347
+ "</p>",
348
+ {
349
+ "k": "child",
350
+ "in": "section"
351
+ },
352
+ "</section>"
353
+ ]
354
+ };
355
+ var _gyral$t7 = {
356
+ "id": "1y5ajq0t8j7",
357
+ "html": "<div class=\"actions\"><!----> <button type=\"button\" value=\"leave\">Back</button></div>",
358
+ "parts": [[
359
+ 2,
360
+ [0],
361
+ 0
362
+ ], [
363
+ 3,
364
+ [0, 2],
365
+ "data-intent"
366
+ ]],
367
+ "segments": [
368
+ "<div class=\"actions\">",
369
+ {
370
+ "k": "child",
371
+ "in": "div"
372
+ },
373
+ "<!----> <button type=\"button\" value=\"leave\"",
374
+ {
375
+ "k": "attr",
376
+ "name": "data-intent"
377
+ },
378
+ ">Back</button></div>"
379
+ ]
380
+ };
381
+ var _gyral$t8 = {
382
+ "id": "q0gtlcf5vu",
383
+ "html": "<button type=\"button\" class=\"primary\" value=\"reconnect\">Use this tab instead</button>",
384
+ "parts": [[
385
+ 3,
386
+ [0],
387
+ "data-intent"
388
+ ]],
389
+ "segments": [
390
+ "<button type=\"button\" class=\"primary\" value=\"reconnect\"",
391
+ {
392
+ "k": "attr",
393
+ "name": "data-intent"
394
+ },
395
+ ">Use this tab instead</button>"
396
+ ]
397
+ };
398
+ var _gyral$t9 = {
399
+ "id": "1thzuxk9p0n",
400
+ "html": "<div class=\"invite\"><p class=\"field\"><label for=\"invite-link\">Invite link</label> <input id=\"invite-link\" class=\"invite-link\" readonly></p><div class=\"actions\"><button type=\"button\" value=\"link\">Copy link</button> <button type=\"button\" value=\"code\">Copy code</button></div><p class=\"note\">Send the link to a friend, or read them the code. Anyone with it can join or watch.</p></div><h4 id=\"seats-title\">Players</h4><ol class=\"seats\" aria-labelledby=\"seats-title\"></ol><p class=\"note\"></p><!----> <div class=\"actions\"><!----> <!----> <button type=\"button\" class=\"leave\" value=\"leave\">Leave room</button></div><!----> ",
401
+ "parts": [
402
+ [
403
+ 3,
404
+ [
405
+ 0,
406
+ 0,
407
+ 2
408
+ ],
409
+ "value"
410
+ ],
411
+ [
412
+ 3,
413
+ [
414
+ 0,
415
+ 1,
416
+ 0
417
+ ],
418
+ "data-intent"
419
+ ],
420
+ [
421
+ 3,
422
+ [
423
+ 0,
424
+ 1,
425
+ 2
426
+ ],
427
+ "data-intent"
428
+ ],
429
+ [1, [2]],
430
+ [1, [3]],
431
+ [
432
+ 2,
433
+ [],
434
+ 4
435
+ ],
436
+ [
437
+ 2,
438
+ [],
439
+ 6
440
+ ],
441
+ [
442
+ 2,
443
+ [6],
444
+ 0
445
+ ],
446
+ [
447
+ 2,
448
+ [6],
449
+ 2
450
+ ],
451
+ [
452
+ 3,
453
+ [6, 4],
454
+ "data-intent"
455
+ ],
456
+ [
457
+ 2,
458
+ [],
459
+ 7
460
+ ],
461
+ [0, []]
462
+ ],
463
+ "segments": [
464
+ "<div class=\"invite\"><p class=\"field\"><label for=\"invite-link\">Invite link</label> <input id=\"invite-link\" class=\"invite-link\" readonly",
465
+ {
466
+ "k": "attr",
467
+ "name": "value"
468
+ },
469
+ "></p><div class=\"actions\"><button type=\"button\" value=\"link\"",
470
+ {
471
+ "k": "attr",
472
+ "name": "data-intent"
473
+ },
474
+ ">Copy link</button> <button type=\"button\" value=\"code\"",
475
+ {
476
+ "k": "attr",
477
+ "name": "data-intent"
478
+ },
479
+ ">Copy code</button></div><p class=\"note\">Send the link to a friend, or read them the code. Anyone with it can join or watch.</p></div><h4 id=\"seats-title\">Players</h4><ol class=\"seats\" aria-labelledby=\"seats-title\">",
480
+ {
481
+ "k": "child",
482
+ "in": "ol"
483
+ },
484
+ "</ol><p class=\"note\">",
485
+ {
486
+ "k": "child",
487
+ "in": "p"
488
+ },
489
+ "</p>",
490
+ { "k": "child" },
491
+ "<!----> ",
492
+ { "k": "child" },
493
+ "<div class=\"actions\">",
494
+ {
495
+ "k": "child",
496
+ "in": "div"
497
+ },
498
+ "<!----> ",
499
+ {
500
+ "k": "child",
501
+ "in": "div"
502
+ },
503
+ "<!----> <button type=\"button\" class=\"leave\" value=\"leave\"",
504
+ {
505
+ "k": "attr",
506
+ "name": "data-intent"
507
+ },
508
+ ">Leave room</button></div>",
509
+ { "k": "child" },
510
+ "<!----> ",
511
+ { "k": "child" }
512
+ ]
513
+ };
514
+ var _gyral$t10 = {
515
+ "id": "2c7r2l15wny",
516
+ "html": "<p class=\"field\"><label for=\"room-clock\">Turn clock</label><select id=\"room-clock\" name=\"clock\"></select></p>",
517
+ "parts": [[
518
+ 3,
519
+ [0, 1],
520
+ "data-intent"
521
+ ], [1, [0, 1]]],
522
+ "segments": [
523
+ "<p class=\"field\"><label for=\"room-clock\">Turn clock</label><select id=\"room-clock\" name=\"clock\"",
524
+ {
525
+ "k": "attr",
526
+ "name": "data-intent"
527
+ },
528
+ ">",
529
+ {
530
+ "k": "child",
531
+ "in": "select"
532
+ },
533
+ "</select></p>"
534
+ ]
535
+ };
536
+ var _gyral$t11 = {
537
+ "id": "p736qw50jb",
538
+ "html": "<p class=\"clock-setting\">Turn clock: </p>",
539
+ "parts": [[0, [0]]],
540
+ "segments": [
541
+ "<p class=\"clock-setting\">Turn clock: ",
542
+ {
543
+ "k": "child",
544
+ "in": "p"
545
+ },
546
+ "</p>"
547
+ ]
548
+ };
549
+ var _gyral$t12 = {
550
+ "id": "249se4hphje",
551
+ "html": "<p class=\"field\"><label for=\"room-ai-level\">Computer level</label><select id=\"room-ai-level\" name=\"aiLevel\"></select></p>",
552
+ "parts": [[
553
+ 3,
554
+ [0, 1],
555
+ "data-intent"
556
+ ], [1, [0, 1]]],
557
+ "segments": [
558
+ "<p class=\"field\"><label for=\"room-ai-level\">Computer level</label><select id=\"room-ai-level\" name=\"aiLevel\"",
559
+ {
560
+ "k": "attr",
561
+ "name": "data-intent"
562
+ },
563
+ ">",
564
+ {
565
+ "k": "child",
566
+ "in": "select"
567
+ },
568
+ "</select></p>"
569
+ ]
570
+ };
571
+ var _gyral$t13 = {
572
+ "id": "11vo9uem4xh",
573
+ "html": "<p class=\"note\"></p>",
574
+ "parts": [[1, [0]]],
575
+ "segments": [
576
+ "<p class=\"note\">",
577
+ {
578
+ "k": "child",
579
+ "in": "p"
580
+ },
581
+ "</p>"
582
+ ]
583
+ };
584
+ var _gyral$t14 = {
585
+ "id": "6yzkk0r0zp",
586
+ "html": "<button type=\"button\" class=\"ready\">Ready</button>",
587
+ "parts": [
588
+ [
589
+ 3,
590
+ [0],
591
+ "aria-pressed"
592
+ ],
593
+ [
594
+ 3,
595
+ [0],
596
+ "value"
597
+ ],
598
+ [
599
+ 3,
600
+ [0],
601
+ "data-intent"
602
+ ]
603
+ ],
604
+ "segments": [
605
+ "<button type=\"button\" class=\"ready\"",
606
+ {
607
+ "k": "attr",
608
+ "name": "aria-pressed"
609
+ },
610
+ {
611
+ "k": "attr",
612
+ "name": "value"
613
+ },
614
+ {
615
+ "k": "attr",
616
+ "name": "data-intent"
617
+ },
618
+ ">Ready</button>"
619
+ ]
620
+ };
621
+ var _gyral$t15 = {
622
+ "id": "20x2rffpqfu",
623
+ "html": "<button type=\"button\" class=\"primary start-match\" aria-describedby=\"start-hint\">Start the match</button>",
624
+ "parts": [[
625
+ 5,
626
+ [0],
627
+ "disabled"
628
+ ], [
629
+ 3,
630
+ [0],
631
+ "data-intent"
632
+ ]],
633
+ "segments": [
634
+ "<button type=\"button\" class=\"primary start-match\" aria-describedby=\"start-hint\"",
635
+ {
636
+ "k": "bool",
637
+ "name": "disabled"
638
+ },
639
+ {
640
+ "k": "attr",
641
+ "name": "data-intent"
642
+ },
643
+ ">Start the match</button>"
644
+ ]
645
+ };
646
+ var _gyral$t16 = {
647
+ "id": "94m9ii6qcx",
648
+ "html": "<p class=\"hint\" id=\"start-hint\"></p>",
649
+ "parts": [[1, [0]]],
650
+ "segments": [
651
+ "<p class=\"hint\" id=\"start-hint\">",
652
+ {
653
+ "k": "child",
654
+ "in": "p"
655
+ },
656
+ "</p>"
657
+ ]
658
+ };
659
+ var _gyral$t17 = {
660
+ "id": "2byw35y04qu",
661
+ "html": "<p class=\"hint\">The host starts the match once everyone is ready.</p>",
662
+ "parts": [],
663
+ "segments": ["<p class=\"hint\">The host starts the match once everyone is ready.</p>"]
664
+ };
665
+ var _gyral$t18 = {
666
+ "id": "9nkfq8trco",
667
+ "html": "<label class=\"mode\"> <input type=\"radio\" name=\"mode\"> <span></span> <!----> </label>",
668
+ "parts": [
669
+ [
670
+ 3,
671
+ [0],
672
+ "data-playable"
673
+ ],
674
+ [
675
+ 3,
676
+ [0, 1],
677
+ "value"
678
+ ],
679
+ [
680
+ 5,
681
+ [0, 1],
682
+ "checked"
683
+ ],
684
+ [
685
+ 5,
686
+ [0, 1],
687
+ "disabled"
688
+ ],
689
+ [
690
+ 3,
691
+ [0, 1],
692
+ "data-intent"
693
+ ],
694
+ [1, [0, 3]],
695
+ [
696
+ 2,
697
+ [0],
698
+ 5
699
+ ]
700
+ ],
701
+ "segments": [
702
+ "<label class=\"mode\"",
703
+ {
704
+ "k": "attr",
705
+ "name": "data-playable"
706
+ },
707
+ "> <input type=\"radio\" name=\"mode\"",
708
+ {
709
+ "k": "attr",
710
+ "name": "value"
711
+ },
712
+ {
713
+ "k": "bool",
714
+ "name": "checked"
715
+ },
716
+ {
717
+ "k": "bool",
718
+ "name": "disabled"
719
+ },
720
+ {
721
+ "k": "attr",
722
+ "name": "data-intent"
723
+ },
724
+ "> <span>",
725
+ {
726
+ "k": "child",
727
+ "in": "span"
728
+ },
729
+ "</span> ",
730
+ {
731
+ "k": "child",
732
+ "in": "label"
733
+ },
734
+ "<!----> </label>"
735
+ ]
736
+ };
737
+ var _gyral$t19 = {
738
+ "id": "rcatdmatl1",
739
+ "html": "<small class=\"soon\"></small>",
740
+ "parts": [[1, [0]]],
741
+ "segments": [
742
+ "<small class=\"soon\">",
743
+ {
744
+ "k": "child",
745
+ "in": "small"
746
+ },
747
+ "</small>"
748
+ ]
749
+ };
750
+ var _gyral$t20 = {
751
+ "id": "1medvoqk9ym",
752
+ "html": "<div class=\"name\"><label>Player </label> <input maxlength=\"20\" autocomplete=\"off\" spellcheck=\"false\"> </div>",
753
+ "parts": [
754
+ [
755
+ 4,
756
+ [0, 0],
757
+ "for",
758
+ ["name-", ""]
759
+ ],
760
+ [0, [0, 0]],
761
+ [
762
+ 4,
763
+ [0, 2],
764
+ "id",
765
+ ["name-", ""]
766
+ ],
767
+ [
768
+ 4,
769
+ [0, 2],
770
+ "name",
771
+ ["seat-", ""]
772
+ ],
773
+ [
774
+ 3,
775
+ [0, 2],
776
+ "value"
777
+ ],
778
+ [
779
+ 4,
780
+ [0, 2],
781
+ "placeholder",
782
+ ["Player ", ""]
783
+ ],
784
+ [
785
+ 3,
786
+ [0, 2],
787
+ "aria-invalid"
788
+ ],
789
+ [
790
+ 3,
791
+ [0, 2],
792
+ "aria-describedby"
793
+ ],
794
+ [
795
+ 3,
796
+ [0, 2],
797
+ "data-intent"
798
+ ],
799
+ [0, [0]]
800
+ ],
801
+ "segments": [
802
+ "<div class=\"name\"><label",
803
+ {
804
+ "k": "attr",
805
+ "name": "for",
806
+ "strings": ["name-", ""]
807
+ },
808
+ ">Player ",
809
+ {
810
+ "k": "child",
811
+ "in": "label"
812
+ },
813
+ "</label> <input maxlength=\"20\" autocomplete=\"off\" spellcheck=\"false\"",
814
+ {
815
+ "k": "attr",
816
+ "name": "id",
817
+ "strings": ["name-", ""]
818
+ },
819
+ {
820
+ "k": "attr",
821
+ "name": "name",
822
+ "strings": ["seat-", ""]
823
+ },
824
+ {
825
+ "k": "attr",
826
+ "name": "value"
827
+ },
828
+ {
829
+ "k": "attr",
830
+ "name": "placeholder",
831
+ "strings": ["Player ", ""]
832
+ },
833
+ {
834
+ "k": "attr",
835
+ "name": "aria-invalid"
836
+ },
837
+ {
838
+ "k": "attr",
839
+ "name": "aria-describedby"
840
+ },
841
+ {
842
+ "k": "attr",
843
+ "name": "data-intent"
844
+ },
845
+ "> ",
846
+ {
847
+ "k": "child",
848
+ "in": "div"
849
+ },
850
+ "</div>"
851
+ ]
852
+ };
853
+ var _gyral$t21 = {
854
+ "id": "2cl8g4cl685",
855
+ "html": "<p class=\"error\"></p>",
856
+ "parts": [[
857
+ 4,
858
+ [0],
859
+ "id",
860
+ ["name-", "-error"]
861
+ ], [1, [0]]],
862
+ "segments": [
863
+ "<p class=\"error\"",
864
+ {
865
+ "k": "attr",
866
+ "name": "id",
867
+ "strings": ["name-", "-error"]
868
+ },
869
+ ">",
870
+ {
871
+ "k": "child",
872
+ "in": "p"
873
+ },
874
+ "</p>"
875
+ ]
876
+ };
877
+ var _gyral$t22 = {
878
+ "id": "dhoc5scuf8",
879
+ "html": "<p class=\"field\"><!----> </p>",
880
+ "parts": [[
881
+ 2,
882
+ [0],
883
+ 0
884
+ ], [0, [0]]],
885
+ "segments": [
886
+ "<p class=\"field\">",
887
+ {
888
+ "k": "child",
889
+ "in": "p"
890
+ },
891
+ "<!----> ",
892
+ {
893
+ "k": "child",
894
+ "in": "p"
895
+ },
896
+ "</p>"
897
+ ]
898
+ };
899
+ var _gyral$t23 = {
900
+ "id": "bq7dsq2t9u",
901
+ "html": "<label><input type=\"checkbox\" value=\"toggle\"> </label>",
902
+ "parts": [
903
+ [
904
+ 3,
905
+ [0, 0],
906
+ "name"
907
+ ],
908
+ [
909
+ 5,
910
+ [0, 0],
911
+ "checked"
912
+ ],
913
+ [
914
+ 3,
915
+ [0, 0],
916
+ "data-intent"
917
+ ],
918
+ [0, [0]]
919
+ ],
920
+ "segments": [
921
+ "<label><input type=\"checkbox\" value=\"toggle\"",
922
+ {
923
+ "k": "attr",
924
+ "name": "name"
925
+ },
926
+ {
927
+ "k": "bool",
928
+ "name": "checked"
929
+ },
930
+ {
931
+ "k": "attr",
932
+ "name": "data-intent"
933
+ },
934
+ "> ",
935
+ {
936
+ "k": "child",
937
+ "in": "label"
938
+ },
939
+ "</label>"
940
+ ]
941
+ };
942
+ var _gyral$t24 = {
943
+ "id": "n90chqg56o",
944
+ "html": "<label><select></select></label>",
945
+ "parts": [
946
+ [
947
+ 2,
948
+ [0],
949
+ 0
950
+ ],
951
+ [
952
+ 3,
953
+ [0, 0],
954
+ "name"
955
+ ],
956
+ [
957
+ 3,
958
+ [0, 0],
959
+ "data-intent"
960
+ ],
961
+ [1, [0, 0]]
962
+ ],
963
+ "segments": [
964
+ "<label>",
965
+ {
966
+ "k": "child",
967
+ "in": "label"
968
+ },
969
+ "<select",
970
+ {
971
+ "k": "attr",
972
+ "name": "name"
973
+ },
974
+ {
975
+ "k": "attr",
976
+ "name": "data-intent"
977
+ },
978
+ ">",
979
+ {
980
+ "k": "child",
981
+ "in": "select"
982
+ },
983
+ "</select></label>"
984
+ ]
985
+ };
986
+ var _gyral$t25 = {
987
+ "id": "zh1wffvn2t",
988
+ "html": "<small></small>",
989
+ "parts": [[1, [0]]],
990
+ "segments": [
991
+ "<small>",
992
+ {
993
+ "k": "child",
994
+ "in": "small"
995
+ },
996
+ "</small>"
997
+ ]
998
+ };
999
+ var _gyral$t26 = {
1000
+ "id": "198nvu48nzu",
1001
+ "html": "<form class=\"setup\"><fieldset class=\"modes\"><legend>Choose how to play</legend><div class=\"mode-list\"></div></fieldset><!----> <!----> <!----> <!----> <div class=\"actions\"><p class=\"hint\"></p></div></form>",
1002
+ "parts": [
1003
+ [
1004
+ 4,
1005
+ [0],
1006
+ "aria-label",
1007
+ ["Start ", ""]
1008
+ ],
1009
+ [
1010
+ 3,
1011
+ [0],
1012
+ "data-intent"
1013
+ ],
1014
+ [
1015
+ 2,
1016
+ [0],
1017
+ 0
1018
+ ],
1019
+ [1, [
1020
+ 0,
1021
+ 0,
1022
+ 1
1023
+ ]],
1024
+ [
1025
+ 2,
1026
+ [0],
1027
+ 1
1028
+ ],
1029
+ [
1030
+ 2,
1031
+ [0],
1032
+ 3
1033
+ ],
1034
+ [
1035
+ 2,
1036
+ [0],
1037
+ 5
1038
+ ],
1039
+ [
1040
+ 2,
1041
+ [0],
1042
+ 7
1043
+ ],
1044
+ [
1045
+ 2,
1046
+ [0],
1047
+ 9
1048
+ ],
1049
+ [
1050
+ 2,
1051
+ [0, 9],
1052
+ 0
1053
+ ],
1054
+ [1, [
1055
+ 0,
1056
+ 9,
1057
+ 0
1058
+ ]],
1059
+ [0, [0]],
1060
+ [0, []]
1061
+ ],
1062
+ "segments": [
1063
+ "<form class=\"setup\"",
1064
+ {
1065
+ "k": "attr",
1066
+ "name": "aria-label",
1067
+ "strings": ["Start ", ""]
1068
+ },
1069
+ {
1070
+ "k": "attr",
1071
+ "name": "data-intent"
1072
+ },
1073
+ ">",
1074
+ {
1075
+ "k": "child",
1076
+ "in": "form"
1077
+ },
1078
+ "<fieldset class=\"modes\"><legend>Choose how to play</legend><div class=\"mode-list\">",
1079
+ {
1080
+ "k": "child",
1081
+ "in": "div"
1082
+ },
1083
+ "</div></fieldset>",
1084
+ {
1085
+ "k": "child",
1086
+ "in": "form"
1087
+ },
1088
+ "<!----> ",
1089
+ {
1090
+ "k": "child",
1091
+ "in": "form"
1092
+ },
1093
+ "<!----> ",
1094
+ {
1095
+ "k": "child",
1096
+ "in": "form"
1097
+ },
1098
+ "<!----> ",
1099
+ {
1100
+ "k": "child",
1101
+ "in": "form"
1102
+ },
1103
+ "<!----> ",
1104
+ {
1105
+ "k": "child",
1106
+ "in": "form"
1107
+ },
1108
+ "<div class=\"actions\">",
1109
+ {
1110
+ "k": "child",
1111
+ "in": "div"
1112
+ },
1113
+ "<p class=\"hint\">",
1114
+ {
1115
+ "k": "child",
1116
+ "in": "p"
1117
+ },
1118
+ "</p></div>",
1119
+ {
1120
+ "k": "child",
1121
+ "in": "form"
1122
+ },
1123
+ "</form>",
1124
+ { "k": "child" }
1125
+ ]
1126
+ };
1127
+ var _gyral$t27 = {
1128
+ "id": "1f1kopmmi8c",
1129
+ "html": "<p class=\"notice\"></p>",
1130
+ "parts": [[1, [0]]],
1131
+ "segments": [
1132
+ "<p class=\"notice\">",
1133
+ {
1134
+ "k": "child",
1135
+ "in": "p"
1136
+ },
1137
+ "</p>"
1138
+ ]
1139
+ };
1140
+ var _gyral$t28 = {
1141
+ "id": "r1c4i1o73h",
1142
+ "html": "<p class=\"field\"><label for=\"ai-level\">Computer level</label><select id=\"ai-level\" name=\"aiLevel\"></select></p>",
1143
+ "parts": [[
1144
+ 3,
1145
+ [0, 1],
1146
+ "data-intent"
1147
+ ], [1, [0, 1]]],
1148
+ "segments": [
1149
+ "<p class=\"field\"><label for=\"ai-level\">Computer level</label><select id=\"ai-level\" name=\"aiLevel\"",
1150
+ {
1151
+ "k": "attr",
1152
+ "name": "data-intent"
1153
+ },
1154
+ ">",
1155
+ {
1156
+ "k": "child",
1157
+ "in": "select"
1158
+ },
1159
+ "</select></p>"
1160
+ ]
1161
+ };
1162
+ var _gyral$t29 = {
1163
+ "id": "17cyw7e7ccp",
1164
+ "html": "<p class=\"field\"><label for=\"players\">Players</label><select id=\"players\" name=\"players\"></select></p>",
1165
+ "parts": [[
1166
+ 3,
1167
+ [0, 1],
1168
+ "data-intent"
1169
+ ], [1, [0, 1]]],
1170
+ "segments": [
1171
+ "<p class=\"field\"><label for=\"players\">Players</label><select id=\"players\" name=\"players\"",
1172
+ {
1173
+ "k": "attr",
1174
+ "name": "data-intent"
1175
+ },
1176
+ ">",
1177
+ {
1178
+ "k": "child",
1179
+ "in": "select"
1180
+ },
1181
+ "</select></p>"
1182
+ ]
1183
+ };
1184
+ var _gyral$t30 = {
1185
+ "id": "bs2sl7v7ap",
1186
+ "html": "<fieldset class=\"names\"><legend>Player names</legend><!----> </fieldset>",
1187
+ "parts": [[
1188
+ 2,
1189
+ [0],
1190
+ 1
1191
+ ], [0, [0]]],
1192
+ "segments": [
1193
+ "<fieldset class=\"names\"><legend>Player names</legend>",
1194
+ {
1195
+ "k": "child",
1196
+ "in": "fieldset"
1197
+ },
1198
+ "<!----> ",
1199
+ {
1200
+ "k": "child",
1201
+ "in": "fieldset"
1202
+ },
1203
+ "</fieldset>"
1204
+ ]
1205
+ };
1206
+ var _gyral$t31 = {
1207
+ "id": "136vmwrlfvv",
1208
+ "html": "<p class=\"note\">The computer plays the other <!---->.</p>",
1209
+ "parts": [[
1210
+ 2,
1211
+ [0],
1212
+ 1
1213
+ ]],
1214
+ "segments": [
1215
+ "<p class=\"note\">The computer plays the other ",
1216
+ {
1217
+ "k": "child",
1218
+ "in": "p"
1219
+ },
1220
+ "<!---->.</p>"
1221
+ ]
1222
+ };
1223
+ var _gyral$t32 = {
1224
+ "id": "2buap2fkqw3",
1225
+ "html": "<p class=\"note\">Open a room and invite friends with a link, or join a friend's room below.</p>",
1226
+ "parts": [],
1227
+ "segments": ["<p class=\"note\">Open a room and invite friends with a link, or join a friend's room below.</p>"]
1228
+ };
1229
+ var _gyral$t33 = {
1230
+ "id": "11n5ptkd7pe",
1231
+ "html": "<fieldset class=\"game-options\"><legend>Game options</legend></fieldset>",
1232
+ "parts": [[0, [0]]],
1233
+ "segments": [
1234
+ "<fieldset class=\"game-options\"><legend>Game options</legend>",
1235
+ {
1236
+ "k": "child",
1237
+ "in": "fieldset"
1238
+ },
1239
+ "</fieldset>"
1240
+ ]
1241
+ };
1242
+ var _gyral$t34 = {
1243
+ "id": "wkl8p07h4v",
1244
+ "html": "<button type=\"submit\" class=\"start primary\">Create a room</button>",
1245
+ "parts": [[
1246
+ 5,
1247
+ [0],
1248
+ "disabled"
1249
+ ]],
1250
+ "segments": [
1251
+ "<button type=\"submit\" class=\"start primary\"",
1252
+ {
1253
+ "k": "bool",
1254
+ "name": "disabled"
1255
+ },
1256
+ ">Create a room</button>"
1257
+ ]
1258
+ };
1259
+ var _gyral$t35 = {
1260
+ "id": "293s45n2l6i",
1261
+ "html": "<button type=\"submit\" class=\"start primary\">Start</button>",
1262
+ "parts": [[
1263
+ 4,
1264
+ [0],
1265
+ "aria-label",
1266
+ ["Start ", ""]
1267
+ ], [
1268
+ 5,
1269
+ [0],
1270
+ "disabled"
1271
+ ]],
1272
+ "segments": [
1273
+ "<button type=\"submit\" class=\"start primary\"",
1274
+ {
1275
+ "k": "attr",
1276
+ "name": "aria-label",
1277
+ "strings": ["Start ", ""]
1278
+ },
1279
+ {
1280
+ "k": "bool",
1281
+ "name": "disabled"
1282
+ },
1283
+ ">Start</button>"
1284
+ ]
1285
+ };
1286
+ var _gyral$t36 = {
1287
+ "id": "28zmidyt7l2",
1288
+ "html": "<p class=\"note\">This game uses AI-made content. You'll see a short notice before it starts.</p>",
1289
+ "parts": [],
1290
+ "segments": ["<p class=\"note\">This game uses AI-made content. You'll see a short notice before it starts.</p>"]
1291
+ };
1292
+ var _gyral$t37 = {
1293
+ "id": "b0fsa4mspw",
1294
+ "html": "<section class=\"resume panel\" aria-labelledby=\"resume-title\"><h3 id=\"resume-title\">Continue your saved game?</h3><p><time></time> played so far.</p><div class=\"actions\"><button type=\"button\" class=\"primary\">Resume</button> <button type=\"button\">Start a new game</button> <button type=\"button\">Back</button></div></section>",
1295
+ "parts": [
1296
+ [
1297
+ 2,
1298
+ [0],
1299
+ 1
1300
+ ],
1301
+ [
1302
+ 2,
1303
+ [0, 1],
1304
+ 0
1305
+ ],
1306
+ [
1307
+ 3,
1308
+ [
1309
+ 0,
1310
+ 1,
1311
+ 0
1312
+ ],
1313
+ "datetime"
1314
+ ],
1315
+ [1, [
1316
+ 0,
1317
+ 1,
1318
+ 0
1319
+ ]],
1320
+ [
1321
+ 3,
1322
+ [
1323
+ 0,
1324
+ 2,
1325
+ 0
1326
+ ],
1327
+ "data-intent"
1328
+ ],
1329
+ [
1330
+ 3,
1331
+ [
1332
+ 0,
1333
+ 2,
1334
+ 2
1335
+ ],
1336
+ "data-intent"
1337
+ ],
1338
+ [
1339
+ 3,
1340
+ [
1341
+ 0,
1342
+ 2,
1343
+ 4
1344
+ ],
1345
+ "data-intent"
1346
+ ]
1347
+ ],
1348
+ "segments": [
1349
+ "<section class=\"resume panel\" aria-labelledby=\"resume-title\"><h3 id=\"resume-title\">Continue your saved game?</h3>",
1350
+ {
1351
+ "k": "child",
1352
+ "in": "section"
1353
+ },
1354
+ "<p>",
1355
+ {
1356
+ "k": "child",
1357
+ "in": "p"
1358
+ },
1359
+ "<time",
1360
+ {
1361
+ "k": "attr",
1362
+ "name": "datetime"
1363
+ },
1364
+ ">",
1365
+ {
1366
+ "k": "child",
1367
+ "in": "time"
1368
+ },
1369
+ "</time> played so far.</p><div class=\"actions\"><button type=\"button\" class=\"primary\"",
1370
+ {
1371
+ "k": "attr",
1372
+ "name": "data-intent"
1373
+ },
1374
+ ">Resume</button> <button type=\"button\"",
1375
+ {
1376
+ "k": "attr",
1377
+ "name": "data-intent"
1378
+ },
1379
+ ">Start a new game</button> <button type=\"button\"",
1380
+ {
1381
+ "k": "attr",
1382
+ "name": "data-intent"
1383
+ },
1384
+ ">Back</button></div></section>"
1385
+ ]
1386
+ };
1387
+ var _gyral$t38 = {
1388
+ "id": "ugp0n1dbby",
1389
+ "html": "<label>Saved game<select aria-label=\"Saved game\"></select></label>",
1390
+ "parts": [[
1391
+ 3,
1392
+ [0, 1],
1393
+ "data-intent"
1394
+ ], [1, [0, 1]]],
1395
+ "segments": [
1396
+ "<label>Saved game<select aria-label=\"Saved game\"",
1397
+ {
1398
+ "k": "attr",
1399
+ "name": "data-intent"
1400
+ },
1401
+ ">",
1402
+ {
1403
+ "k": "child",
1404
+ "in": "select"
1405
+ },
1406
+ "</select></label>"
1407
+ ]
1408
+ };
1409
+ var _gyral$t39 = {
1410
+ "id": "t5q6c617ry",
1411
+ "html": "<section class=\"ai-notice panel\" aria-labelledby=\"ai-notice-title\"><h3 id=\"ai-notice-title\"></h3><p></p><p></p><div class=\"actions\"><button type=\"button\" class=\"primary\">Accept and play</button> <button type=\"button\">Not now</button></div></section>",
1412
+ "parts": [
1413
+ [1, [0, 0]],
1414
+ [1, [0, 1]],
1415
+ [1, [0, 2]],
1416
+ [
1417
+ 3,
1418
+ [
1419
+ 0,
1420
+ 3,
1421
+ 0
1422
+ ],
1423
+ "data-intent"
1424
+ ],
1425
+ [
1426
+ 3,
1427
+ [
1428
+ 0,
1429
+ 3,
1430
+ 2
1431
+ ],
1432
+ "data-intent"
1433
+ ]
1434
+ ],
1435
+ "segments": [
1436
+ "<section class=\"ai-notice panel\" aria-labelledby=\"ai-notice-title\"><h3 id=\"ai-notice-title\">",
1437
+ {
1438
+ "k": "child",
1439
+ "in": "h3"
1440
+ },
1441
+ "</h3><p>",
1442
+ {
1443
+ "k": "child",
1444
+ "in": "p"
1445
+ },
1446
+ "</p><p>",
1447
+ {
1448
+ "k": "child",
1449
+ "in": "p"
1450
+ },
1451
+ "</p><div class=\"actions\"><button type=\"button\" class=\"primary\"",
1452
+ {
1453
+ "k": "attr",
1454
+ "name": "data-intent"
1455
+ },
1456
+ ">Accept and play</button> <button type=\"button\"",
1457
+ {
1458
+ "k": "attr",
1459
+ "name": "data-intent"
1460
+ },
1461
+ ">Not now</button></div></section>"
1462
+ ]
1463
+ };
1464
+ var _gyral$t40 = {
1465
+ "id": "25lab0ckfjv",
1466
+ "html": "<section class=\"handoff panel\" aria-labelledby=\"handoff-title\"><h3 id=\"handoff-title\">Pass to <!---->, then tap to reveal</h3><p>Only <!----> should look at the screen.</p><button type=\"button\" class=\"reveal primary\">Tap to reveal</button></section>",
1467
+ "parts": [
1468
+ [
1469
+ 2,
1470
+ [0, 0],
1471
+ 1
1472
+ ],
1473
+ [
1474
+ 2,
1475
+ [0, 1],
1476
+ 1
1477
+ ],
1478
+ [
1479
+ 3,
1480
+ [0, 2],
1481
+ "data-intent"
1482
+ ]
1483
+ ],
1484
+ "segments": [
1485
+ "<section class=\"handoff panel\" aria-labelledby=\"handoff-title\"><h3 id=\"handoff-title\">Pass to ",
1486
+ {
1487
+ "k": "child",
1488
+ "in": "h3"
1489
+ },
1490
+ "<!---->, then tap to reveal</h3><p>Only ",
1491
+ {
1492
+ "k": "child",
1493
+ "in": "p"
1494
+ },
1495
+ "<!----> should look at the screen.</p><button type=\"button\" class=\"reveal primary\"",
1496
+ {
1497
+ "k": "attr",
1498
+ "name": "data-intent"
1499
+ },
1500
+ ">Tap to reveal</button></section>"
1501
+ ]
1502
+ };
1503
+ var _gyral$t41 = {
1504
+ "id": "iethxerav1",
1505
+ "html": "<button type=\"button\" value=\"withdraw\">Withdraw the offer</button>",
1506
+ "parts": [[
1507
+ 3,
1508
+ [0],
1509
+ "data-intent"
1510
+ ]],
1511
+ "segments": [
1512
+ "<button type=\"button\" value=\"withdraw\"",
1513
+ {
1514
+ "k": "attr",
1515
+ "name": "data-intent"
1516
+ },
1517
+ ">Withdraw the offer</button>"
1518
+ ]
1519
+ };
1520
+ var _gyral$t42 = {
1521
+ "id": "11nggs7xd2x",
1522
+ "html": "<button type=\"button\" class=\"primary\" value=\"accept\">Accept<span class=\"visually-hidden\"> </span></button> <button type=\"button\" value=\"decline\">Decline<span class=\"visually-hidden\"> </span></button>",
1523
+ "parts": [
1524
+ [
1525
+ 3,
1526
+ [0],
1527
+ "data-intent"
1528
+ ],
1529
+ [0, [0, 1]],
1530
+ [
1531
+ 3,
1532
+ [2],
1533
+ "data-intent"
1534
+ ],
1535
+ [0, [2, 1]]
1536
+ ],
1537
+ "segments": [
1538
+ "<button type=\"button\" class=\"primary\" value=\"accept\"",
1539
+ {
1540
+ "k": "attr",
1541
+ "name": "data-intent"
1542
+ },
1543
+ ">Accept<span class=\"visually-hidden\"> ",
1544
+ {
1545
+ "k": "child",
1546
+ "in": "span"
1547
+ },
1548
+ "</span></button> <button type=\"button\" value=\"decline\"",
1549
+ {
1550
+ "k": "attr",
1551
+ "name": "data-intent"
1552
+ },
1553
+ ">Decline<span class=\"visually-hidden\"> ",
1554
+ {
1555
+ "k": "child",
1556
+ "in": "span"
1557
+ },
1558
+ "</span></button>"
1559
+ ]
1560
+ };
1561
+ var _gyral$t43 = {
1562
+ "id": "c4stiz0yc9",
1563
+ "html": "<div class=\"actions\"><!----> <!----> <a class=\"back\" href=\"/\">Back to all games</a></div>",
1564
+ "parts": [[
1565
+ 2,
1566
+ [0],
1567
+ 0
1568
+ ], [
1569
+ 2,
1570
+ [0],
1571
+ 2
1572
+ ]],
1573
+ "segments": [
1574
+ "<div class=\"actions\">",
1575
+ {
1576
+ "k": "child",
1577
+ "in": "div"
1578
+ },
1579
+ "<!----> ",
1580
+ {
1581
+ "k": "child",
1582
+ "in": "div"
1583
+ },
1584
+ "<!----> <a class=\"back\" href=\"/\">Back to all games</a></div>"
1585
+ ]
1586
+ };
1587
+ var _gyral$t44 = {
1588
+ "id": "1rlyy4wr5uj",
1589
+ "html": "<button type=\"button\" class=\"primary share\" value=\"symbols\">Share</button> <button type=\"button\" value=\"words\">Copy as text</button>",
1590
+ "parts": [[
1591
+ 3,
1592
+ [0],
1593
+ "data-intent"
1594
+ ], [
1595
+ 3,
1596
+ [2],
1597
+ "data-intent"
1598
+ ]],
1599
+ "segments": [
1600
+ "<button type=\"button\" class=\"primary share\" value=\"symbols\"",
1601
+ {
1602
+ "k": "attr",
1603
+ "name": "data-intent"
1604
+ },
1605
+ ">Share</button> <button type=\"button\" value=\"words\"",
1606
+ {
1607
+ "k": "attr",
1608
+ "name": "data-intent"
1609
+ },
1610
+ ">Copy as text</button>"
1611
+ ]
1612
+ };
1613
+ var _gyral$t45 = {
1614
+ "id": "1ong5qoig11",
1615
+ "html": "<button type=\"button\">Change mode</button>",
1616
+ "parts": [[
1617
+ 3,
1618
+ [0],
1619
+ "data-intent"
1620
+ ]],
1621
+ "segments": [
1622
+ "<button type=\"button\"",
1623
+ {
1624
+ "k": "attr",
1625
+ "name": "data-intent"
1626
+ },
1627
+ ">Change mode</button>"
1628
+ ]
1629
+ };
1630
+ var _gyral$t46 = {
1631
+ "id": "1dsdqme90bz",
1632
+ "html": "<div class=\"actions\"><button type=\"button\" class=\"primary\">Play again</button> <button type=\"button\">Change mode</button> <a class=\"back\" href=\"/\">Back to all games</a></div>",
1633
+ "parts": [[
1634
+ 3,
1635
+ [0, 0],
1636
+ "data-intent"
1637
+ ], [
1638
+ 3,
1639
+ [0, 2],
1640
+ "data-intent"
1641
+ ]],
1642
+ "segments": [
1643
+ "<div class=\"actions\"><button type=\"button\" class=\"primary\"",
1644
+ {
1645
+ "k": "attr",
1646
+ "name": "data-intent"
1647
+ },
1648
+ ">Play again</button> <button type=\"button\"",
1649
+ {
1650
+ "k": "attr",
1651
+ "name": "data-intent"
1652
+ },
1653
+ ">Change mode</button> <a class=\"back\" href=\"/\">Back to all games</a></div>"
1654
+ ]
1655
+ };
1656
+ var _gyral$t47 = {
1657
+ "id": "1ayhaoow3t1",
1658
+ "html": "<div class=\"actions\"><!----> <!----> <button type=\"button\">Leave room</button> <a class=\"back\" href=\"/\">Back to all games</a></div><p class=\"note offer-state\"></p>",
1659
+ "parts": [
1660
+ [
1661
+ 2,
1662
+ [0],
1663
+ 0
1664
+ ],
1665
+ [
1666
+ 2,
1667
+ [0],
1668
+ 2
1669
+ ],
1670
+ [
1671
+ 3,
1672
+ [0, 4],
1673
+ "data-intent"
1674
+ ],
1675
+ [1, [1]]
1676
+ ],
1677
+ "segments": [
1678
+ "<div class=\"actions\">",
1679
+ {
1680
+ "k": "child",
1681
+ "in": "div"
1682
+ },
1683
+ "<!----> ",
1684
+ {
1685
+ "k": "child",
1686
+ "in": "div"
1687
+ },
1688
+ "<!----> <button type=\"button\"",
1689
+ {
1690
+ "k": "attr",
1691
+ "name": "data-intent"
1692
+ },
1693
+ ">Leave room</button> <a class=\"back\" href=\"/\">Back to all games</a></div><p class=\"note offer-state\">",
1694
+ {
1695
+ "k": "child",
1696
+ "in": "p"
1697
+ },
1698
+ "</p>"
1699
+ ]
1700
+ };
1701
+ var _gyral$t48 = {
1702
+ "id": "1k42f1vhk2z",
1703
+ "html": "<button type=\"button\" class=\"primary offer-rematch\">Offer a rematch</button>",
1704
+ "parts": [[
1705
+ 3,
1706
+ [0],
1707
+ "data-intent"
1708
+ ]],
1709
+ "segments": [
1710
+ "<button type=\"button\" class=\"primary offer-rematch\"",
1711
+ {
1712
+ "k": "attr",
1713
+ "name": "data-intent"
1714
+ },
1715
+ ">Offer a rematch</button>"
1716
+ ]
1717
+ };
1718
+ var _gyral$t49 = {
1719
+ "id": "wzd54mzrdq",
1720
+ "html": "<dl class=\"facts daily-facts\"><div><dt>Streak</dt><dd><!----> <!----> (best <!---->)</dd></div></dl><p class=\"next\"></p>",
1721
+ "parts": [
1722
+ [
1723
+ 2,
1724
+ [
1725
+ 0,
1726
+ 0,
1727
+ 1
1728
+ ],
1729
+ 0
1730
+ ],
1731
+ [
1732
+ 2,
1733
+ [
1734
+ 0,
1735
+ 0,
1736
+ 1
1737
+ ],
1738
+ 2
1739
+ ],
1740
+ [
1741
+ 2,
1742
+ [
1743
+ 0,
1744
+ 0,
1745
+ 1
1746
+ ],
1747
+ 4
1748
+ ],
1749
+ [0, [0]],
1750
+ [
1751
+ 2,
1752
+ [],
1753
+ 1
1754
+ ],
1755
+ [1, [1]],
1756
+ [0, []]
1757
+ ],
1758
+ "segments": [
1759
+ "<dl class=\"facts daily-facts\"><div><dt>Streak</dt><dd>",
1760
+ {
1761
+ "k": "child",
1762
+ "in": "dd"
1763
+ },
1764
+ "<!----> ",
1765
+ {
1766
+ "k": "child",
1767
+ "in": "dd"
1768
+ },
1769
+ "<!----> (best ",
1770
+ {
1771
+ "k": "child",
1772
+ "in": "dd"
1773
+ },
1774
+ "<!---->)</dd></div>",
1775
+ {
1776
+ "k": "child",
1777
+ "in": "dl"
1778
+ },
1779
+ "</dl>",
1780
+ { "k": "child" },
1781
+ "<p class=\"next\">",
1782
+ {
1783
+ "k": "child",
1784
+ "in": "p"
1785
+ },
1786
+ "</p>",
1787
+ { "k": "child" }
1788
+ ]
1789
+ };
1790
+ var _gyral$t50 = {
1791
+ "id": "1ovn3cmme5j",
1792
+ "html": "<div><dt>Wins in a row</dt><dd><!----> (best <!---->)</dd></div>",
1793
+ "parts": [[
1794
+ 2,
1795
+ [0, 1],
1796
+ 0
1797
+ ], [
1798
+ 2,
1799
+ [0, 1],
1800
+ 2
1801
+ ]],
1802
+ "segments": [
1803
+ "<div><dt>Wins in a row</dt><dd>",
1804
+ {
1805
+ "k": "child",
1806
+ "in": "dd"
1807
+ },
1808
+ "<!----> (best ",
1809
+ {
1810
+ "k": "child",
1811
+ "in": "dd"
1812
+ },
1813
+ "<!---->)</dd></div>"
1814
+ ]
1815
+ };
1816
+ var _gyral$t51 = {
1817
+ "id": "22i1lju9pgg",
1818
+ "html": "<section class=\"word-statistics\" aria-labelledby=\"word-statistics-title\"><h4 id=\"word-statistics-title\">Daily Word statistics</h4><dl class=\"facts\"><div><dt>Played</dt><dd></dd></div><div><dt>Won</dt><dd></dd></div><div><dt>Win rate</dt><dd><!---->%</dd></div></dl><table><caption>Wins by guess count</caption><tbody></tbody></table></section>",
1819
+ "parts": [
1820
+ [1, [
1821
+ 0,
1822
+ 1,
1823
+ 0,
1824
+ 1
1825
+ ]],
1826
+ [1, [
1827
+ 0,
1828
+ 1,
1829
+ 1,
1830
+ 1
1831
+ ]],
1832
+ [
1833
+ 2,
1834
+ [
1835
+ 0,
1836
+ 1,
1837
+ 2,
1838
+ 1
1839
+ ],
1840
+ 0
1841
+ ],
1842
+ [1, [
1843
+ 0,
1844
+ 2,
1845
+ 1
1846
+ ]]
1847
+ ],
1848
+ "segments": [
1849
+ "<section class=\"word-statistics\" aria-labelledby=\"word-statistics-title\"><h4 id=\"word-statistics-title\">Daily Word statistics</h4><dl class=\"facts\"><div><dt>Played</dt><dd>",
1850
+ {
1851
+ "k": "child",
1852
+ "in": "dd"
1853
+ },
1854
+ "</dd></div><div><dt>Won</dt><dd>",
1855
+ {
1856
+ "k": "child",
1857
+ "in": "dd"
1858
+ },
1859
+ "</dd></div><div><dt>Win rate</dt><dd>",
1860
+ {
1861
+ "k": "child",
1862
+ "in": "dd"
1863
+ },
1864
+ "<!---->%</dd></div></dl><table><caption>Wins by guess count</caption><tbody>",
1865
+ {
1866
+ "k": "child",
1867
+ "in": "tbody"
1868
+ },
1869
+ "</tbody></table></section>"
1870
+ ]
1871
+ };
1872
+ var _gyral$t52 = {
1873
+ "id": "998l9yvgdy",
1874
+ "html": "<tr><th scope=\"row\"><!----> </th><td><meter min=\"0\"></meter></td><td></td></tr>",
1875
+ "parts": [
1876
+ [
1877
+ 2,
1878
+ [0, 0],
1879
+ 0
1880
+ ],
1881
+ [0, [0, 0]],
1882
+ [
1883
+ 3,
1884
+ [
1885
+ 0,
1886
+ 1,
1887
+ 0
1888
+ ],
1889
+ "max"
1890
+ ],
1891
+ [
1892
+ 3,
1893
+ [
1894
+ 0,
1895
+ 1,
1896
+ 0
1897
+ ],
1898
+ "value"
1899
+ ],
1900
+ [
1901
+ 4,
1902
+ [
1903
+ 0,
1904
+ 1,
1905
+ 0
1906
+ ],
1907
+ "aria-label",
1908
+ ["Wins in ", " guesses"]
1909
+ ],
1910
+ [1, [
1911
+ 0,
1912
+ 1,
1913
+ 0
1914
+ ]],
1915
+ [1, [0, 2]]
1916
+ ],
1917
+ "segments": [
1918
+ "<tr><th scope=\"row\">",
1919
+ {
1920
+ "k": "child",
1921
+ "in": "th"
1922
+ },
1923
+ "<!----> ",
1924
+ {
1925
+ "k": "child",
1926
+ "in": "th"
1927
+ },
1928
+ "</th><td><meter min=\"0\"",
1929
+ {
1930
+ "k": "attr",
1931
+ "name": "max"
1932
+ },
1933
+ {
1934
+ "k": "attr",
1935
+ "name": "value"
1936
+ },
1937
+ {
1938
+ "k": "attr",
1939
+ "name": "aria-label",
1940
+ "strings": ["Wins in ", " guesses"]
1941
+ },
1942
+ ">",
1943
+ {
1944
+ "k": "child",
1945
+ "in": "meter"
1946
+ },
1947
+ "</meter></td><td>",
1948
+ {
1949
+ "k": "child",
1950
+ "in": "td"
1951
+ },
1952
+ "</td></tr>"
1953
+ ]
1954
+ };
1955
+ var _gyral$t53 = {
1956
+ "id": "1ipqkcu4ml6",
1957
+ "html": "<figure class=\"share-preview\"><figcaption>What Share sends</figcaption><pre aria-hidden=\"true\">\n</pre><p class=\"visually-hidden\"></p></figure>",
1958
+ "parts": [[1, [0, 1]], [1, [0, 2]]],
1959
+ "segments": [
1960
+ "<figure class=\"share-preview\"><figcaption>What Share sends</figcaption><pre aria-hidden=\"true\">\n",
1961
+ {
1962
+ "k": "child",
1963
+ "in": "pre"
1964
+ },
1965
+ "</pre><p class=\"visually-hidden\">",
1966
+ {
1967
+ "k": "child",
1968
+ "in": "p"
1969
+ },
1970
+ "</p></figure>"
1971
+ ]
1972
+ };
1973
+ var _gyral$t54 = {
1974
+ "id": "w2t1ydcz3n",
1975
+ "html": "<dialog id=\"results\" class=\"results\" aria-labelledby=\"results-title\" data-intent-on=\"keydown\"><div class=\"results-body\"><p class=\"kicker\">Game over</p><h3 id=\"results-title\" tabindex=\"-1\"></h3><p class=\"summary\"></p><dl class=\"facts\"><!----> </dl><!----> <!----> <!----> </div><ad-slot class=\"results-ad\" slot-id=\"results\" page=\"results\"></ad-slot></dialog>",
1976
+ "parts": [
1977
+ [
1978
+ 3,
1979
+ [0],
1980
+ "data-result"
1981
+ ],
1982
+ [
1983
+ 5,
1984
+ [0],
1985
+ "open"
1986
+ ],
1987
+ [
1988
+ 3,
1989
+ [0],
1990
+ "data-intent"
1991
+ ],
1992
+ [1, [
1993
+ 0,
1994
+ 0,
1995
+ 1
1996
+ ]],
1997
+ [1, [
1998
+ 0,
1999
+ 0,
2000
+ 2
2001
+ ]],
2002
+ [
2003
+ 2,
2004
+ [
2005
+ 0,
2006
+ 0,
2007
+ 3
2008
+ ],
2009
+ 0
2010
+ ],
2011
+ [0, [
2012
+ 0,
2013
+ 0,
2014
+ 3
2015
+ ]],
2016
+ [
2017
+ 2,
2018
+ [0, 0],
2019
+ 4
2020
+ ],
2021
+ [
2022
+ 2,
2023
+ [0, 0],
2024
+ 6
2025
+ ],
2026
+ [
2027
+ 2,
2028
+ [0, 0],
2029
+ 8
2030
+ ],
2031
+ [0, [0, 0]],
2032
+ [
2033
+ 3,
2034
+ [0, 1],
2035
+ "game-id"
2036
+ ]
2037
+ ],
2038
+ "segments": [
2039
+ "<dialog id=\"results\" class=\"results\" aria-labelledby=\"results-title\" data-intent-on=\"keydown\"",
2040
+ {
2041
+ "k": "attr",
2042
+ "name": "data-result"
2043
+ },
2044
+ {
2045
+ "k": "bool",
2046
+ "name": "open"
2047
+ },
2048
+ {
2049
+ "k": "attr",
2050
+ "name": "data-intent"
2051
+ },
2052
+ "><div class=\"results-body\"><p class=\"kicker\">Game over</p><h3 id=\"results-title\" tabindex=\"-1\">",
2053
+ {
2054
+ "k": "child",
2055
+ "in": "h3"
2056
+ },
2057
+ "</h3><p class=\"summary\">",
2058
+ {
2059
+ "k": "child",
2060
+ "in": "p"
2061
+ },
2062
+ "</p><dl class=\"facts\">",
2063
+ {
2064
+ "k": "child",
2065
+ "in": "dl"
2066
+ },
2067
+ "<!----> ",
2068
+ {
2069
+ "k": "child",
2070
+ "in": "dl"
2071
+ },
2072
+ "</dl>",
2073
+ {
2074
+ "k": "child",
2075
+ "in": "div"
2076
+ },
2077
+ "<!----> ",
2078
+ {
2079
+ "k": "child",
2080
+ "in": "div"
2081
+ },
2082
+ "<!----> ",
2083
+ {
2084
+ "k": "child",
2085
+ "in": "div"
2086
+ },
2087
+ "<!----> ",
2088
+ {
2089
+ "k": "child",
2090
+ "in": "div"
2091
+ },
2092
+ "</div>",
2093
+ {
2094
+ "k": "open",
2095
+ "tag": "ad-slot",
2096
+ "html": "<ad-slot class=\"results-ad\" slot-id=\"results\" page=\"results\"",
2097
+ "attrs": [
2098
+ ["class", "results-ad"],
2099
+ ["slot-id", "results"],
2100
+ ["page", "results"]
2101
+ ]
2102
+ },
2103
+ {
2104
+ "k": "attr",
2105
+ "name": "game-id"
2106
+ },
2107
+ { "k": "openEnd" },
2108
+ {
2109
+ "k": "close",
2110
+ "tag": "ad-slot"
2111
+ },
2112
+ "</dialog>"
2113
+ ]
2114
+ };
2115
+ var _gyral$t55 = {
2116
+ "id": "269k2rfzktl",
2117
+ "html": "<div><dt>Time</dt><dd><time></time></dd></div>",
2118
+ "parts": [[
2119
+ 3,
2120
+ [
2121
+ 0,
2122
+ 1,
2123
+ 0
2124
+ ],
2125
+ "datetime"
2126
+ ], [1, [
2127
+ 0,
2128
+ 1,
2129
+ 0
2130
+ ]]],
2131
+ "segments": [
2132
+ "<div><dt>Time</dt><dd><time",
2133
+ {
2134
+ "k": "attr",
2135
+ "name": "datetime"
2136
+ },
2137
+ ">",
2138
+ {
2139
+ "k": "child",
2140
+ "in": "time"
2141
+ },
2142
+ "</time></dd></div>"
2143
+ ]
2144
+ };
2145
+ var _gyral$t56 = {
2146
+ "id": "287gewx4qif",
2147
+ "html": "<div class=\"assisted\"><dt>Help</dt><dd></dd></div>",
2148
+ "parts": [[1, [0, 1]]],
2149
+ "segments": [
2150
+ "<div class=\"assisted\"><dt>Help</dt><dd>",
2151
+ {
2152
+ "k": "child",
2153
+ "in": "dd"
2154
+ },
2155
+ "</dd></div>"
2156
+ ]
2157
+ };
2158
+ var _gyral$t57 = {
2159
+ "id": "5aariaehiy",
2160
+ "html": "<p class=\"review\"><button type=\"button\" class=\"review-board\" aria-keyshortcuts=\"Escape\">Review the board</button></p>",
2161
+ "parts": [[
2162
+ 3,
2163
+ [0, 0],
2164
+ "data-intent"
2165
+ ]],
2166
+ "segments": [
2167
+ "<p class=\"review\"><button type=\"button\" class=\"review-board\" aria-keyshortcuts=\"Escape\"",
2168
+ {
2169
+ "k": "attr",
2170
+ "name": "data-intent"
2171
+ },
2172
+ ">Review the board</button></p>"
2173
+ ]
2174
+ };
2175
+ var _gyral$t58 = {
2176
+ "id": "1mzd6e35azm",
2177
+ "html": "<section class=\"failed panel\" role=\"alert\" aria-labelledby=\"failed-title\"><h3 id=\"failed-title\" tabindex=\"-1\">The game couldn't start</h3><p></p><div class=\"actions\"><button type=\"button\" class=\"primary\">Back</button></div></section>",
2178
+ "parts": [[1, [0, 1]], [
2179
+ 3,
2180
+ [
2181
+ 0,
2182
+ 2,
2183
+ 0
2184
+ ],
2185
+ "data-intent"
2186
+ ]],
2187
+ "segments": [
2188
+ "<section class=\"failed panel\" role=\"alert\" aria-labelledby=\"failed-title\"><h3 id=\"failed-title\" tabindex=\"-1\">The game couldn't start</h3><p>",
2189
+ {
2190
+ "k": "child",
2191
+ "in": "p"
2192
+ },
2193
+ "</p><div class=\"actions\"><button type=\"button\" class=\"primary\"",
2194
+ {
2195
+ "k": "attr",
2196
+ "name": "data-intent"
2197
+ },
2198
+ ">Back</button></div></section>"
2199
+ ]
2200
+ };
2201
+ var _gyral$t59 = {
2202
+ "id": "t3zwp4rm2k",
2203
+ "html": "<fieldset class=\"prefs\"><legend>Preferences</legend><p class=\"field\"><label for=\"pref-motion\">Motion</label><select id=\"pref-motion\" name=\"reducedMotion\"></select></p><p class=\"field\"><label for=\"pref-theme\">Game colors</label><select id=\"pref-theme\" name=\"theme\"></select></p><p class=\"check\"><input type=\"checkbox\" id=\"pref-sound\" name=\"sound\"> <label for=\"pref-sound\">Sound</label></p><p class=\"field\"><label for=\"pref-volume\">Volume</label> <input type=\"range\" id=\"pref-volume\" name=\"volume\" min=\"0\" max=\"100\" step=\"5\"></p><p class=\"check\"><input type=\"checkbox\" id=\"pref-keys\" name=\"singleKeyShortcuts\" aria-describedby=\"pref-keys-note\"> <label for=\"pref-keys\">Single-key shortcuts</label></p><p class=\"note\" id=\"pref-keys-note\">Turn these off if you use speech input or a switch.</p><p class=\"check\"><input type=\"checkbox\" id=\"pref-ai\" name=\"aiContentAccepted\" aria-describedby=\"pref-ai-note\"> <label for=\"pref-ai\">Allow games with AI-made content</label></p><p class=\"note\" id=\"pref-ai-note\">Turned off, those games ask again before they start.</p></fieldset>",
2204
+ "parts": [
2205
+ [
2206
+ 3,
2207
+ [
2208
+ 0,
2209
+ 1,
2210
+ 1
2211
+ ],
2212
+ "data-intent"
2213
+ ],
2214
+ [1, [
2215
+ 0,
2216
+ 1,
2217
+ 1
2218
+ ]],
2219
+ [
2220
+ 3,
2221
+ [
2222
+ 0,
2223
+ 2,
2224
+ 1
2225
+ ],
2226
+ "data-intent"
2227
+ ],
2228
+ [1, [
2229
+ 0,
2230
+ 2,
2231
+ 1
2232
+ ]],
2233
+ [
2234
+ 5,
2235
+ [
2236
+ 0,
2237
+ 3,
2238
+ 0
2239
+ ],
2240
+ "checked"
2241
+ ],
2242
+ [
2243
+ 3,
2244
+ [
2245
+ 0,
2246
+ 3,
2247
+ 0
2248
+ ],
2249
+ "data-intent"
2250
+ ],
2251
+ [
2252
+ 3,
2253
+ [
2254
+ 0,
2255
+ 4,
2256
+ 2
2257
+ ],
2258
+ "value"
2259
+ ],
2260
+ [
2261
+ 3,
2262
+ [
2263
+ 0,
2264
+ 4,
2265
+ 2
2266
+ ],
2267
+ "data-intent"
2268
+ ],
2269
+ [
2270
+ 5,
2271
+ [
2272
+ 0,
2273
+ 5,
2274
+ 0
2275
+ ],
2276
+ "checked"
2277
+ ],
2278
+ [
2279
+ 3,
2280
+ [
2281
+ 0,
2282
+ 5,
2283
+ 0
2284
+ ],
2285
+ "data-intent"
2286
+ ],
2287
+ [
2288
+ 5,
2289
+ [
2290
+ 0,
2291
+ 7,
2292
+ 0
2293
+ ],
2294
+ "checked"
2295
+ ],
2296
+ [
2297
+ 3,
2298
+ [
2299
+ 0,
2300
+ 7,
2301
+ 0
2302
+ ],
2303
+ "data-intent"
2304
+ ]
2305
+ ],
2306
+ "segments": [
2307
+ "<fieldset class=\"prefs\"><legend>Preferences</legend><p class=\"field\"><label for=\"pref-motion\">Motion</label><select id=\"pref-motion\" name=\"reducedMotion\"",
2308
+ {
2309
+ "k": "attr",
2310
+ "name": "data-intent"
2311
+ },
2312
+ ">",
2313
+ {
2314
+ "k": "child",
2315
+ "in": "select"
2316
+ },
2317
+ "</select></p><p class=\"field\"><label for=\"pref-theme\">Game colors</label><select id=\"pref-theme\" name=\"theme\"",
2318
+ {
2319
+ "k": "attr",
2320
+ "name": "data-intent"
2321
+ },
2322
+ ">",
2323
+ {
2324
+ "k": "child",
2325
+ "in": "select"
2326
+ },
2327
+ "</select></p><p class=\"check\"><input type=\"checkbox\" id=\"pref-sound\" name=\"sound\"",
2328
+ {
2329
+ "k": "bool",
2330
+ "name": "checked"
2331
+ },
2332
+ {
2333
+ "k": "attr",
2334
+ "name": "data-intent"
2335
+ },
2336
+ "> <label for=\"pref-sound\">Sound</label></p><p class=\"field\"><label for=\"pref-volume\">Volume</label> <input type=\"range\" id=\"pref-volume\" name=\"volume\" min=\"0\" max=\"100\" step=\"5\"",
2337
+ {
2338
+ "k": "attr",
2339
+ "name": "value"
2340
+ },
2341
+ {
2342
+ "k": "attr",
2343
+ "name": "data-intent"
2344
+ },
2345
+ "></p><p class=\"check\"><input type=\"checkbox\" id=\"pref-keys\" name=\"singleKeyShortcuts\" aria-describedby=\"pref-keys-note\"",
2346
+ {
2347
+ "k": "bool",
2348
+ "name": "checked"
2349
+ },
2350
+ {
2351
+ "k": "attr",
2352
+ "name": "data-intent"
2353
+ },
2354
+ "> <label for=\"pref-keys\">Single-key shortcuts</label></p><p class=\"note\" id=\"pref-keys-note\">Turn these off if you use speech input or a switch.</p><p class=\"check\"><input type=\"checkbox\" id=\"pref-ai\" name=\"aiContentAccepted\" aria-describedby=\"pref-ai-note\"",
2355
+ {
2356
+ "k": "bool",
2357
+ "name": "checked"
2358
+ },
2359
+ {
2360
+ "k": "attr",
2361
+ "name": "data-intent"
2362
+ },
2363
+ "> <label for=\"pref-ai\">Allow games with AI-made content</label></p><p class=\"note\" id=\"pref-ai-note\">Turned off, those games ask again before they start.</p></fieldset>"
2364
+ ]
2365
+ };
2366
+ var _gyral$t60 = {
2367
+ "id": "24h8i6rpo60",
2368
+ "html": "<jy-report-problem class=\"report\"></jy-report-problem>",
2369
+ "parts": [[
2370
+ 3,
2371
+ [0],
2372
+ "game-id"
2373
+ ], [
2374
+ 3,
2375
+ [0],
2376
+ "puzzle-id"
2377
+ ]],
2378
+ "segments": [
2379
+ {
2380
+ "k": "open",
2381
+ "tag": "jy-report-problem",
2382
+ "html": "<jy-report-problem class=\"report\"",
2383
+ "attrs": [["class", "report"]]
2384
+ },
2385
+ {
2386
+ "k": "attr",
2387
+ "name": "game-id"
2388
+ },
2389
+ {
2390
+ "k": "attr",
2391
+ "name": "puzzle-id"
2392
+ },
2393
+ { "k": "openEnd" },
2394
+ {
2395
+ "k": "close",
2396
+ "tag": "jy-report-problem"
2397
+ }
2398
+ ]
2399
+ };
2400
+ var _gyral$t61 = {
2401
+ "id": "emi37eycjo",
2402
+ "html": "<dialog class=\"overlay\" aria-labelledby=\"menu-title\" data-intent-on=\"close\"><h3 id=\"menu-title\"></h3><p class=\"note\"></p><div class=\"actions\"><button type=\"button\" class=\"primary\" autofocus></button> <!----> <button type=\"button\" class=\"exit\"></button></div><!----> <!----> </dialog>",
2403
+ "parts": [
2404
+ [
2405
+ 5,
2406
+ [0],
2407
+ "modal"
2408
+ ],
2409
+ [
2410
+ 3,
2411
+ [0],
2412
+ "data-intent"
2413
+ ],
2414
+ [1, [0, 0]],
2415
+ [1, [0, 1]],
2416
+ [
2417
+ 3,
2418
+ [
2419
+ 0,
2420
+ 2,
2421
+ 0
2422
+ ],
2423
+ "data-intent"
2424
+ ],
2425
+ [1, [
2426
+ 0,
2427
+ 2,
2428
+ 0
2429
+ ]],
2430
+ [
2431
+ 2,
2432
+ [0, 2],
2433
+ 2
2434
+ ],
2435
+ [
2436
+ 3,
2437
+ [
2438
+ 0,
2439
+ 2,
2440
+ 4
2441
+ ],
2442
+ "data-intent"
2443
+ ],
2444
+ [1, [
2445
+ 0,
2446
+ 2,
2447
+ 4
2448
+ ]],
2449
+ [
2450
+ 2,
2451
+ [0],
2452
+ 3
2453
+ ],
2454
+ [
2455
+ 2,
2456
+ [0],
2457
+ 5
2458
+ ],
2459
+ [0, [0]]
2460
+ ],
2461
+ "segments": [
2462
+ "<dialog class=\"overlay\" aria-labelledby=\"menu-title\" data-intent-on=\"close\"",
2463
+ {
2464
+ "k": "bool",
2465
+ "name": "modal"
2466
+ },
2467
+ {
2468
+ "k": "attr",
2469
+ "name": "data-intent"
2470
+ },
2471
+ "><h3 id=\"menu-title\">",
2472
+ {
2473
+ "k": "child",
2474
+ "in": "h3"
2475
+ },
2476
+ "</h3><p class=\"note\">",
2477
+ {
2478
+ "k": "child",
2479
+ "in": "p"
2480
+ },
2481
+ "</p><div class=\"actions\"><button type=\"button\" class=\"primary\" autofocus",
2482
+ {
2483
+ "k": "attr",
2484
+ "name": "data-intent"
2485
+ },
2486
+ ">",
2487
+ {
2488
+ "k": "child",
2489
+ "in": "button"
2490
+ },
2491
+ "</button> ",
2492
+ {
2493
+ "k": "child",
2494
+ "in": "div"
2495
+ },
2496
+ "<!----> <button type=\"button\" class=\"exit\"",
2497
+ {
2498
+ "k": "attr",
2499
+ "name": "data-intent"
2500
+ },
2501
+ ">",
2502
+ {
2503
+ "k": "child",
2504
+ "in": "button"
2505
+ },
2506
+ "</button></div>",
2507
+ {
2508
+ "k": "child",
2509
+ "in": "dialog"
2510
+ },
2511
+ "<!----> ",
2512
+ {
2513
+ "k": "child",
2514
+ "in": "dialog"
2515
+ },
2516
+ "<!----> ",
2517
+ {
2518
+ "k": "child",
2519
+ "in": "dialog"
2520
+ },
2521
+ "</dialog>"
2522
+ ]
2523
+ };
2524
+ var _gyral$t62 = {
2525
+ "id": "181k9o959ig",
2526
+ "html": "<button type=\"button\" class=\"end-match\" aria-describedby=\"end-match-note\">Ask to end the match</button>",
2527
+ "parts": [[
2528
+ 3,
2529
+ [0],
2530
+ "data-intent"
2531
+ ]],
2532
+ "segments": [
2533
+ "<button type=\"button\" class=\"end-match\" aria-describedby=\"end-match-note\"",
2534
+ {
2535
+ "k": "attr",
2536
+ "name": "data-intent"
2537
+ },
2538
+ ">Ask to end the match</button>"
2539
+ ]
2540
+ };
2541
+ var _gyral$t63 = {
2542
+ "id": "18yfd5xxj6q",
2543
+ "html": "<p class=\"note\" id=\"end-match-note\">It ends with no result if the others agree, or if nobody declines within a minute.</p>",
2544
+ "parts": [],
2545
+ "segments": ["<p class=\"note\" id=\"end-match-note\">It ends with no result if the others agree, or if nobody declines within a minute.</p>"]
2546
+ };
2547
+ var _gyral$t64 = {
2548
+ "id": "m9x8eu78dz",
2549
+ "html": "<jy-game-stage class=\"stage\" role=\"region\" tabindex=\"-1\"></jy-game-stage>",
2550
+ "parts": [
2551
+ [
2552
+ 3,
2553
+ [0],
2554
+ "aria-label"
2555
+ ],
2556
+ [
2557
+ 5,
2558
+ [0],
2559
+ "hidden"
2560
+ ],
2561
+ [
2562
+ 5,
2563
+ [0],
2564
+ "inert"
2565
+ ],
2566
+ [
2567
+ 6,
2568
+ [0],
2569
+ "control"
2570
+ ],
2571
+ [
2572
+ 3,
2573
+ [0],
2574
+ "data-intent"
2575
+ ]
2576
+ ],
2577
+ "segments": [
2578
+ {
2579
+ "k": "open",
2580
+ "tag": "jy-game-stage",
2581
+ "html": "<jy-game-stage class=\"stage\" role=\"region\" tabindex=\"-1\"",
2582
+ "attrs": [
2583
+ ["class", "stage"],
2584
+ ["role", "region"],
2585
+ ["tabindex", "-1"]
2586
+ ]
2587
+ },
2588
+ {
2589
+ "k": "attr",
2590
+ "name": "aria-label"
2591
+ },
2592
+ {
2593
+ "k": "bool",
2594
+ "name": "hidden"
2595
+ },
2596
+ {
2597
+ "k": "bool",
2598
+ "name": "inert"
2599
+ },
2600
+ {
2601
+ "k": "prop",
2602
+ "name": "control"
2603
+ },
2604
+ {
2605
+ "k": "attr",
2606
+ "name": "data-intent"
2607
+ },
2608
+ { "k": "openEnd" },
2609
+ {
2610
+ "k": "close",
2611
+ "tag": "jy-game-stage"
2612
+ }
2613
+ ]
2614
+ };
2615
+ var _gyral$t65 = {
2616
+ "id": "vo1dlzjvsk",
2617
+ "html": "<button type=\"button\" class=\"menu-button\" aria-haspopup=\"dialog\">Menu</button>",
2618
+ "parts": [[
2619
+ 5,
2620
+ [0],
2621
+ "disabled"
2622
+ ], [
2623
+ 3,
2624
+ [0],
2625
+ "data-intent"
2626
+ ]],
2627
+ "segments": [
2628
+ "<button type=\"button\" class=\"menu-button\" aria-haspopup=\"dialog\"",
2629
+ {
2630
+ "k": "bool",
2631
+ "name": "disabled"
2632
+ },
2633
+ {
2634
+ "k": "attr",
2635
+ "name": "data-intent"
2636
+ },
2637
+ ">Menu</button>"
2638
+ ]
2639
+ };
2640
+ var _gyral$t66 = {
2641
+ "id": "7i5f9u8ttv",
2642
+ "html": "<button type=\"button\" class=\"menu-button show-results\" aria-controls=\"results\">Show results</button>",
2643
+ "parts": [[
2644
+ 3,
2645
+ [0],
2646
+ "data-held"
2647
+ ], [
2648
+ 3,
2649
+ [0],
2650
+ "data-intent"
2651
+ ]],
2652
+ "segments": [
2653
+ "<button type=\"button\" class=\"menu-button show-results\" aria-controls=\"results\"",
2654
+ {
2655
+ "k": "attr",
2656
+ "name": "data-held"
2657
+ },
2658
+ {
2659
+ "k": "attr",
2660
+ "name": "data-intent"
2661
+ },
2662
+ ">Show results</button>"
2663
+ ]
2664
+ };
2665
+ var _gyral$t67 = {
2666
+ "id": "1varrvlye3n",
2667
+ "html": "<p class=\"timer\" role=\"timer\"><!---->: <time></time></p>",
2668
+ "parts": [
2669
+ [
2670
+ 3,
2671
+ [0],
2672
+ "data-low"
2673
+ ],
2674
+ [
2675
+ 3,
2676
+ [0],
2677
+ "data-paused"
2678
+ ],
2679
+ [
2680
+ 2,
2681
+ [0],
2682
+ 0
2683
+ ],
2684
+ [
2685
+ 3,
2686
+ [0, 2],
2687
+ "datetime"
2688
+ ],
2689
+ [1, [0, 2]],
2690
+ [0, [0]]
2691
+ ],
2692
+ "segments": [
2693
+ "<p class=\"timer\" role=\"timer\"",
2694
+ {
2695
+ "k": "attr",
2696
+ "name": "data-low"
2697
+ },
2698
+ {
2699
+ "k": "attr",
2700
+ "name": "data-paused"
2701
+ },
2702
+ ">",
2703
+ {
2704
+ "k": "child",
2705
+ "in": "p"
2706
+ },
2707
+ "<!---->: <time",
2708
+ {
2709
+ "k": "attr",
2710
+ "name": "datetime"
2711
+ },
2712
+ ">",
2713
+ {
2714
+ "k": "child",
2715
+ "in": "time"
2716
+ },
2717
+ "</time>",
2718
+ {
2719
+ "k": "child",
2720
+ "in": "p"
2721
+ },
2722
+ "</p>"
2723
+ ]
2724
+ };
2725
+ var _gyral$t68 = {
2726
+ "id": "23jo20vn6im",
2727
+ "html": "<div class=\"offer\" role=\"group\" aria-label=\"Offer to end the match\"><p class=\"offer-text\"></p></div>",
2728
+ "parts": [[1, [0, 0]], [0, [0]]],
2729
+ "segments": [
2730
+ "<div class=\"offer\" role=\"group\" aria-label=\"Offer to end the match\"><p class=\"offer-text\">",
2731
+ {
2732
+ "k": "child",
2733
+ "in": "p"
2734
+ },
2735
+ "</p>",
2736
+ {
2737
+ "k": "child",
2738
+ "in": "div"
2739
+ },
2740
+ "</div>"
2741
+ ]
2742
+ };
2743
+ var _gyral$t69 = {
2744
+ "id": "1mi9jvk4xdn",
2745
+ "html": "<div class=\"play\"><div class=\"bar\"><p class=\"mode-label\"><!----> · <!----></p><p class=\"status\" role=\"status\"></p><!----> <!----> <!----> </div><!----> <!----> <!----> <div class=\"arena\"><!----> </div></div>",
2746
+ "parts": [
2747
+ [
2748
+ 2,
2749
+ [
2750
+ 0,
2751
+ 0,
2752
+ 0
2753
+ ],
2754
+ 0
2755
+ ],
2756
+ [
2757
+ 2,
2758
+ [
2759
+ 0,
2760
+ 0,
2761
+ 0
2762
+ ],
2763
+ 2
2764
+ ],
2765
+ [0, [
2766
+ 0,
2767
+ 0,
2768
+ 0
2769
+ ]],
2770
+ [1, [
2771
+ 0,
2772
+ 0,
2773
+ 1
2774
+ ]],
2775
+ [
2776
+ 2,
2777
+ [0, 0],
2778
+ 2
2779
+ ],
2780
+ [
2781
+ 2,
2782
+ [0, 0],
2783
+ 4
2784
+ ],
2785
+ [
2786
+ 2,
2787
+ [0, 0],
2788
+ 6
2789
+ ],
2790
+ [0, [0, 0]],
2791
+ [
2792
+ 2,
2793
+ [0],
2794
+ 1
2795
+ ],
2796
+ [
2797
+ 2,
2798
+ [0],
2799
+ 3
2800
+ ],
2801
+ [
2802
+ 2,
2803
+ [0],
2804
+ 5
2805
+ ],
2806
+ [
2807
+ 2,
2808
+ [0],
2809
+ 7
2810
+ ],
2811
+ [
2812
+ 2,
2813
+ [0, 7],
2814
+ 0
2815
+ ],
2816
+ [0, [0, 7]],
2817
+ [0, [0]]
2818
+ ],
2819
+ "segments": [
2820
+ "<div class=\"play\"><div class=\"bar\"><p class=\"mode-label\">",
2821
+ {
2822
+ "k": "child",
2823
+ "in": "p"
2824
+ },
2825
+ "<!----> · ",
2826
+ {
2827
+ "k": "child",
2828
+ "in": "p"
2829
+ },
2830
+ "<!---->",
2831
+ {
2832
+ "k": "child",
2833
+ "in": "p"
2834
+ },
2835
+ "</p><p class=\"status\" role=\"status\">",
2836
+ {
2837
+ "k": "child",
2838
+ "in": "p"
2839
+ },
2840
+ "</p>",
2841
+ {
2842
+ "k": "child",
2843
+ "in": "div"
2844
+ },
2845
+ "<!----> ",
2846
+ {
2847
+ "k": "child",
2848
+ "in": "div"
2849
+ },
2850
+ "<!----> ",
2851
+ {
2852
+ "k": "child",
2853
+ "in": "div"
2854
+ },
2855
+ "<!----> ",
2856
+ {
2857
+ "k": "child",
2858
+ "in": "div"
2859
+ },
2860
+ "</div>",
2861
+ {
2862
+ "k": "child",
2863
+ "in": "div"
2864
+ },
2865
+ "<!----> ",
2866
+ {
2867
+ "k": "child",
2868
+ "in": "div"
2869
+ },
2870
+ "<!----> ",
2871
+ {
2872
+ "k": "child",
2873
+ "in": "div"
2874
+ },
2875
+ "<!----> ",
2876
+ {
2877
+ "k": "child",
2878
+ "in": "div"
2879
+ },
2880
+ "<div class=\"arena\">",
2881
+ {
2882
+ "k": "child",
2883
+ "in": "div"
2884
+ },
2885
+ "<!----> ",
2886
+ {
2887
+ "k": "child",
2888
+ "in": "div"
2889
+ },
2890
+ "</div>",
2891
+ {
2892
+ "k": "child",
2893
+ "in": "div"
2894
+ },
2895
+ "</div>"
2896
+ ]
2897
+ };
2898
+ var _gyral$t70 = {
2899
+ "id": "1t27w3oacdv",
2900
+ "html": "<button type=\"button\" value=\"reconnect\">Use this tab instead</button>",
2901
+ "parts": [[
2902
+ 3,
2903
+ [0],
2904
+ "data-intent"
2905
+ ]],
2906
+ "segments": [
2907
+ "<button type=\"button\" value=\"reconnect\"",
2908
+ {
2909
+ "k": "attr",
2910
+ "name": "data-intent"
2911
+ },
2912
+ ">Use this tab instead</button>"
2913
+ ]
2914
+ };
2915
+ var _gyral$t71 = {
2916
+ "id": "1n359ysb8d",
2917
+ "html": "<div class=\"launcher\"><p class=\"visually-hidden\" aria-live=\"polite\"></p><p class=\"visually-hidden\" aria-live=\"assertive\"></p></div>",
2918
+ "parts": [
2919
+ [
2920
+ 3,
2921
+ [0],
2922
+ "data-phase"
2923
+ ],
2924
+ [
2925
+ 2,
2926
+ [0],
2927
+ 0
2928
+ ],
2929
+ [1, [0, 0]],
2930
+ [1, [0, 1]]
2931
+ ],
2932
+ "segments": [
2933
+ "<div class=\"launcher\"",
2934
+ {
2935
+ "k": "attr",
2936
+ "name": "data-phase"
2937
+ },
2938
+ ">",
2939
+ {
2940
+ "k": "child",
2941
+ "in": "div"
2942
+ },
2943
+ "<p class=\"visually-hidden\" aria-live=\"polite\">",
2944
+ {
2945
+ "k": "child",
2946
+ "in": "p"
2947
+ },
2948
+ "</p><p class=\"visually-hidden\" aria-live=\"assertive\">",
2949
+ {
2950
+ "k": "child",
2951
+ "in": "p"
2952
+ },
2953
+ "</p></div>"
2954
+ ]
2955
+ };
2956
+ var props = {
2957
+ /** The game, from its manifest and catalog listing. Property only (`.game=${…}`). */
2958
+ game: prop.value(isLauncherGame, { required: true }) };
2959
+ var i = intentsOf();
2960
+ /** Loads and registers `<jy-game-stage>` on first Start, so pages pay for it only when played. */
2961
+ var stageLoader = defineDriver({
2962
+ name: "launcher-stage",
2963
+ run: async () => {
2964
+ await import("./browser/stage.js");
2965
+ },
2966
+ concurrency: "exhaust",
2967
+ toError: (cause) => cause instanceof Error ? cause.message : String(cause)
2968
+ });
2969
+ var loadStage = () => command(stageLoader, void 0, {
2970
+ onSuccess: () => ({ _tag: "StageLoaded" }),
2971
+ onFailure: () => ({
2972
+ _tag: "StageOut",
2973
+ out: {
2974
+ _tag: "Failed",
2975
+ message: "The game couldn't load. Check your connection, then try again."
2976
+ }
2977
+ })
2978
+ });
2979
+ var freshState = (game, live = false, online = ONLINE_CHECKING) => ({
2980
+ live,
2981
+ setup: initialSetup(game, online),
2982
+ phase: { _tag: "Setup" },
2983
+ round: 0,
2984
+ stageReady: false,
2985
+ seats: [],
2986
+ begin: null,
2987
+ resumeSlot: null,
2988
+ reveals: 0,
2989
+ preferences: null,
2990
+ polite: "",
2991
+ assertive: "",
2992
+ notice: null,
2993
+ safe: true,
2994
+ config: null,
2995
+ rematch: null,
2996
+ plan: null,
2997
+ room: null,
2998
+ daily: null,
2999
+ puzzle: null,
3000
+ online
3001
+ });
3002
+ /** True when the page should ask the room server which games it hosts: the game lists online play and nobody has answered yet. */
3003
+ var asksOnline = (game, online) => online._tag === "Checking" && game.modes.includes("server");
3004
+ /** The modes this game offers, given the room server's last answer. */
3005
+ var optionsOf = (s, game) => modeOptions(game, s.online);
3006
+ /** Whether an update could be offered now (offline-and-updates.md, Rule 2). */
3007
+ var isSafePoint = (phase) => phase._tag === "Playing" ? phase.frame?.safePoint ?? false : true;
3008
+ /** Returns the next state, reporting the safe point to the page when it changed. */
3009
+ var settle = (next, game, commands = []) => {
3010
+ const safe = isSafePoint(next.phase);
3011
+ return safe === next.safe ? [next, commands] : [{
3012
+ ...next,
3013
+ safe
3014
+ }, [...commands, reportSafePoint({
3015
+ safe,
3016
+ gameId: game.id
3017
+ })]];
3018
+ };
3019
+ /** A fresh live region text; repeating a message nudges it so screen readers say it again. */
3020
+ var say = (previous, message) => previous === message ? `${message} ` : message;
3021
+ var STAGE = "jy-game-stage";
3022
+ var beginPlay = (s, game, begin) => s.plan !== null ? settle({
3023
+ ...s,
3024
+ begin,
3025
+ phase: { _tag: "Loading" }
3026
+ }, game) : settle({
3027
+ ...s,
3028
+ begin,
3029
+ resumeSlot: begin === "resume" && s.phase._tag === "Resume" ? s.phase.save.slot ?? null : null,
3030
+ phase: {
3031
+ _tag: "Playing",
3032
+ frame: null,
3033
+ menu: false
3034
+ }
3035
+ }, game, [focus(STAGE)]);
3036
+ var toSetup = (s, game) => settle({
3037
+ ...s,
3038
+ phase: { _tag: "Setup" },
3039
+ begin: null,
3040
+ room: null,
3041
+ plan: null
3042
+ }, game, [focus(".start"), ...s.room === null ? [] : [showRoomInUrl(null)]]);
3043
+ var startRound = (s, game, seats, config, plan = null) => settle({
3044
+ ...s,
3045
+ seats,
3046
+ config,
3047
+ rematch: null,
3048
+ round: s.round + 1,
3049
+ begin: null,
3050
+ resumeSlot: null,
3051
+ reveals: 0,
3052
+ notice: null,
3053
+ plan,
3054
+ room: null,
3055
+ daily: null,
3056
+ puzzle: null,
3057
+ phase: { _tag: "Loading" },
3058
+ polite: say(s.polite, plan === null ? `Loading ${game.name}…` : plan.action === "create" ? "Opening a room…" : "Joining the room…")
3059
+ }, game, s.stageReady ? [] : [loadStage()]);
3060
+ /** Hands a request to the room through the stage. */
3061
+ var ask = (s, request) => [s, [call(STAGE, "roomRequest", request)]];
3062
+ /** A lobby request, once the room is open. The room itself checks who may ask what. */
3063
+ var askRoom = (s, request) => s.plan !== null && s.room !== null ? ask(s, request) : s;
3064
+ /** A seat number from a button's value. */
3065
+ var seatOf = (value) => {
3066
+ if (value === void 0 || !/^\d{1,2}$/.test(value)) return void 0;
3067
+ return Number(value);
3068
+ };
3069
+ /** True while this round plays in a server room. */
3070
+ var inRoom = (s) => s.plan !== null;
3071
+ /** The stage's room report: the lobby until the match starts, the address bar once the code is known. */
3072
+ var roomReport = (s, room, game) => {
3073
+ const commands = s.room === null || s.room.code !== room.code ? [showRoomInUrl(room.code)] : [];
3074
+ const next = {
3075
+ ...s,
3076
+ room
3077
+ };
3078
+ const offered = offerAnnouncement(s.room?.offer ?? null, room.offer, room.seat, room.seats);
3079
+ const line = room.notice !== null && room.notice !== s.room?.notice ? room.notice : offered;
3080
+ const announce = line === null ? {} : { polite: say(s.polite, line) };
3081
+ if (s.phase._tag === "Loading") return settle({
3082
+ ...next,
3083
+ ...announce,
3084
+ phase: { _tag: "Lobby" }
3085
+ }, game, [...commands, focus("#lobby-title")]);
3086
+ return settle({
3087
+ ...next,
3088
+ ...announce
3089
+ }, game, commands);
3090
+ };
3091
+ /** After loading (and the AI-content notice): resume a save, or begin at once. */
3092
+ var proceed = (s, game, save) => save === null ? beginPlay(s, game, "new") : settle({
3093
+ ...s,
3094
+ phase: {
3095
+ _tag: "Resume",
3096
+ save
3097
+ }
3098
+ }, game, [focus(".resume .primary")]);
3099
+ var fromStage = (s, out, game) => {
3100
+ switch (out._tag) {
3101
+ case "Prepared": {
3102
+ if (s.phase._tag !== "Loading") return {
3103
+ ...s,
3104
+ preferences: out.preferences
3105
+ };
3106
+ const prepared = {
3107
+ ...s,
3108
+ preferences: out.preferences
3109
+ };
3110
+ return needsAiNotice(game, out.preferences) ? settle({
3111
+ ...prepared,
3112
+ phase: {
3113
+ _tag: "AiNotice",
3114
+ save: out.save
3115
+ }
3116
+ }, game, [focus(".ai-notice .primary")]) : proceed(prepared, game, out.save);
3117
+ }
3118
+ case "Preferences": return s.preferences === null ? s : {
3119
+ ...s,
3120
+ preferences: out.preferences
3121
+ };
3122
+ case "Rematch": return {
3123
+ ...s,
3124
+ rematch: out.config
3125
+ };
3126
+ case "Daily": {
3127
+ const { daily } = out;
3128
+ if (s.phase._tag === "Results") return {
3129
+ ...s,
3130
+ daily
3131
+ };
3132
+ if (daily.earlier === null || s.phase._tag !== "Playing" && s.phase._tag !== "Loading") return s;
3133
+ const result = {
3134
+ result: daily.earlier.result,
3135
+ headline: "You've played today's puzzle",
3136
+ summary: daily.earlier.summary,
3137
+ elapsedMs: null,
3138
+ assisted: null
3139
+ };
3140
+ return settle({
3141
+ ...s,
3142
+ daily,
3143
+ phase: {
3144
+ _tag: "Results",
3145
+ result,
3146
+ shown: true
3147
+ },
3148
+ polite: say(s.polite, `${result.headline}. ${daily.next}.`)
3149
+ }, game, [focus("#results-title")]);
3150
+ }
3151
+ case "Puzzle": return {
3152
+ ...s,
3153
+ puzzle: out.puzzleId
3154
+ };
3155
+ case "Room": return inRoom(s) ? roomReport(s, out.room, game) : s;
3156
+ case "Frame": {
3157
+ const { frame } = out;
3158
+ if (inRoom(s) && frame.outcome === null && (s.phase._tag === "Lobby" || s.phase._tag === "Loading" || s.phase._tag === "Results")) return settle({
3159
+ ...s,
3160
+ phase: {
3161
+ _tag: "Playing",
3162
+ frame,
3163
+ menu: false
3164
+ }
3165
+ }, game, [focus(STAGE)]);
3166
+ const looking = inRoom(s) && frame.outcome !== null && (s.phase._tag === "Lobby" || s.phase._tag === "Loading");
3167
+ if (s.phase._tag !== "Playing" && !looking) return s;
3168
+ if (frame.outcome !== null) {
3169
+ const result = resultView(frame.outcome, frame.seats, toStageMode(s.setup.mode ?? "solo") ?? "solo", s.room?.seat ?? null);
3170
+ return settle({
3171
+ ...s,
3172
+ phase: {
3173
+ _tag: "Results",
3174
+ result,
3175
+ shown: true
3176
+ },
3177
+ assertive: say(s.assertive, `${result.headline} ${result.summary}`)
3178
+ }, game, [focus("#results-title")]);
3179
+ }
3180
+ if (s.phase._tag !== "Playing") return s;
3181
+ const before = s.phase.frame?.handoff ?? null;
3182
+ const handedOff = frame.handoff !== null && (before === null || before.seat !== frame.handoff.seat);
3183
+ return settle({
3184
+ ...s,
3185
+ phase: {
3186
+ ...s.phase,
3187
+ frame,
3188
+ menu: s.phase.menu && frame.handoff === null
3189
+ }
3190
+ }, game, handedOff ? [focus(".reveal")] : []);
3191
+ }
3192
+ case "ExitRequested": return s.phase._tag === "Playing" || s.phase._tag === "Results" || s.phase._tag === "Lobby" ? toSetup(s, game) : s;
3193
+ case "Announce": return out.politeness === "assertive" ? {
3194
+ ...s,
3195
+ assertive: say(s.assertive, out.message)
3196
+ } : {
3197
+ ...s,
3198
+ polite: say(s.polite, out.message)
3199
+ };
3200
+ case "Notice": return {
3201
+ ...s,
3202
+ notice: out.message,
3203
+ polite: say(s.polite, out.message)
3204
+ };
3205
+ case "Failed": return s.phase._tag === "Setup" ? s : settle({
3206
+ ...s,
3207
+ phase: {
3208
+ _tag: "Failed",
3209
+ message: out.message
3210
+ }
3211
+ }, game, [focus(".failed h3")]);
3212
+ }
3213
+ };
3214
+ var joinView = (s) => compiled(_gyral$t0, [
3215
+ i.JoinRoom,
3216
+ s.setup.code,
3217
+ s.setup.codeError === null ? null : "true",
3218
+ s.setup.codeError === null ? "room-code-hint" : "room-code-hint room-code-error",
3219
+ i.TypeCode,
3220
+ s.setup.codeError === null ? nothing : compiled(_gyral$t1, [s.setup.codeError]),
3221
+ s.setup.watch,
3222
+ i.ToggleWatch,
3223
+ !s.live
3224
+ ]);
3225
+ var seatTags = (seat, pick) => {
3226
+ const tags = [];
3227
+ if (seat.id === pick.me) tags.push("you");
3228
+ if (seat.id === pick.host) tags.push("host");
3229
+ if (seat.controller === "ai") tags.push(seat.claimed ? "the computer plays for now" : `the computer${seat.aiLevel === null ? "" : `, ${seat.aiLevel}`}`);
3230
+ else if (seat.claimed) {
3231
+ if (!seat.connected) tags.push("away");
3232
+ else if (pick.lobby) tags.push(seat.ready ? "ready" : "not ready");
3233
+ }
3234
+ return tags.join(" · ");
3235
+ };
3236
+ var SeatRow = (seat, pick) => {
3237
+ const open = !seat.claimed && seat.controller === "human";
3238
+ const label = open ? "Open seat" : seat.controller === "ai" && !seat.claimed ? "Computer" : seat.name;
3239
+ const removable = pick.hosting && pick.lobby && seat.id !== pick.me && !open;
3240
+ return compiled(_gyral$t2, [
3241
+ open ? "yes" : "no",
3242
+ seat.ready ? "yes" : "no",
3243
+ label,
3244
+ seatTags(seat, pick),
3245
+ pick.hosting && pick.lobby && open ? compiled(_gyral$t3, [
3246
+ seat.id,
3247
+ i.FillSeat,
3248
+ seat.id + 1
3249
+ ]) : nothing,
3250
+ removable ? compiled(_gyral$t4, [
3251
+ seat.id,
3252
+ i.RemoveSeat,
3253
+ label,
3254
+ seat.id + 1
3255
+ ]) : nothing
3256
+ ]);
3257
+ };
3258
+ var ClockRow = (o, picked) => compiled(_gyral$t5, [
3259
+ o.value,
3260
+ picked,
3261
+ o.label
3262
+ ]);
3263
+ var connectionLine = (room) => {
3264
+ if (room.connection === "connecting") return "Connecting to the room…";
3265
+ if (room.connection === "reconnecting") return "Connection lost. Reconnecting…";
3266
+ return null;
3267
+ };
3268
+ var lobbyView = (s, game) => {
3269
+ const room = s.room;
3270
+ if (room === null) return nothing;
3271
+ const me = room.seat === null ? void 0 : room.seats.find((seat) => seat.id === room.seat);
3272
+ const hosting = room.seat !== null && room.seat === room.host;
3273
+ const lobby = room.phase === "lobby";
3274
+ const problem = startProblem(room);
3275
+ const pick = {
3276
+ me: room.seat,
3277
+ host: room.host,
3278
+ hosting,
3279
+ lobby
3280
+ };
3281
+ const status = connectionLine(room) ?? room.notice ?? "";
3282
+ const closed = room.connection === "closed";
3283
+ return compiled(_gyral$t6, [
3284
+ game.name,
3285
+ spacedCode(room.code),
3286
+ status,
3287
+ closed ? compiled(_gyral$t7, [room.noticeCode === "replaced" ? compiled(_gyral$t8, [i.RoomAction]) : nothing, i.RoomAction]) : compiled(_gyral$t9, [
3288
+ room.link,
3289
+ i.Copy,
3290
+ i.Copy,
3291
+ each(room.seats, (seat) => seat.id, SeatRow, () => pick),
3292
+ room.spectators === 0 ? "Nobody is watching." : room.spectators === 1 ? "1 person is watching." : `${String(room.spectators)} people are watching.`,
3293
+ room.clockOptions.length === 0 ? nothing : hosting && lobby ? compiled(_gyral$t10, [i.PickClock, each(room.clockOptions, (o) => o.value, ClockRow, (o) => o.value === clockValue(room.clock))]) : compiled(_gyral$t11, [clockLabel(room.clock)]),
3294
+ hosting && lobby && room.aiLevels.length > 1 ? compiled(_gyral$t12, [i.PickRoomLevel, each(room.aiLevels, (l) => l, LevelOption, (l) => l === (room.aiLevel ?? room.aiLevels[0]))]) : nothing,
3295
+ me === void 0 || !lobby ? compiled(_gyral$t13, [room.seat === null ? "You are watching. The match starts when the host starts it." : ""]) : compiled(_gyral$t14, [
3296
+ me.ready ? "true" : "false",
3297
+ me.ready ? "no" : "yes",
3298
+ i.ToggleReady
3299
+ ]),
3300
+ hosting && lobby ? compiled(_gyral$t15, [problem !== null, i.StartMatch]) : nothing,
3301
+ i.RoomAction,
3302
+ hosting && lobby ? compiled(_gyral$t16, [problem ?? "Everyone is ready."]) : nothing,
3303
+ !hosting && lobby && me !== void 0 ? compiled(_gyral$t17, []) : nothing
3304
+ ])
3305
+ ]);
3306
+ };
3307
+ var ModeRow = (o, picked) => compiled(_gyral$t18, [
3308
+ o.playable ? "yes" : "no",
3309
+ o.mode,
3310
+ picked,
3311
+ !o.playable,
3312
+ i.PickMode,
3313
+ o.label,
3314
+ o.note === null ? nothing : compiled(_gyral$t19, [o.note])
3315
+ ]);
3316
+ var LevelOption = (level, picked) => compiled(_gyral$t5, [
3317
+ level,
3318
+ picked,
3319
+ level
3320
+ ]);
3321
+ var CountOption = (count, picked) => compiled(_gyral$t5, [
3322
+ count,
3323
+ picked,
3324
+ count
3325
+ ]);
3326
+ var NameRow = (f) => compiled(_gyral$t20, [
3327
+ f.seat,
3328
+ f.seat + 1,
3329
+ f.seat,
3330
+ f.seat,
3331
+ f.name,
3332
+ f.seat + 1,
3333
+ f.error === null ? null : "true",
3334
+ f.error === null ? null : `name-${f.seat}-error`,
3335
+ i.Rename,
3336
+ f.error === null ? nothing : compiled(_gyral$t21, [f.seat, f.error])
3337
+ ]);
3338
+ var setupHint = (s, game, options) => {
3339
+ if (!s.live) return "JavaScript is needed to play.";
3340
+ if (game.status !== "available") return "Coming soon: not playable yet.";
3341
+ if (!options.some((o) => o.playable)) return "This game is coming soon.";
3342
+ return "";
3343
+ };
3344
+ var GameChoice = (choice, selected) => compiled(_gyral$t5, [
3345
+ String(choice.value),
3346
+ choice.value === selected,
3347
+ choice.label
3348
+ ]);
3349
+ var GameOptionRow = (option, value) => compiled(_gyral$t22, [option.kind === "toggle" ? compiled(_gyral$t23, [
3350
+ option.key,
3351
+ value === true,
3352
+ i.PickGameOption,
3353
+ option.label
3354
+ ]) : compiled(_gyral$t24, [
3355
+ option.label,
3356
+ option.key,
3357
+ i.PickGameOption,
3358
+ each(option.choices, (c) => String(c.value), GameChoice, () => value)
3359
+ ]), option.help === void 0 ? nothing : compiled(_gyral$t25, [option.help])]);
3360
+ var setupView = (s, game) => {
3361
+ const options = optionsOf(s, game);
3362
+ const { mode } = s.setup;
3363
+ const counts = playerCounts(game, mode);
3364
+ const playable = options.some((o) => o.mode === mode && o.playable);
3365
+ const names = [];
3366
+ if (mode === "pass-and-play") for (let seat = 0; seat < s.setup.players; seat += 1) names.push({
3367
+ seat,
3368
+ name: s.setup.names[seat] ?? "",
3369
+ error: s.setup.errors[seat] ?? null
3370
+ });
3371
+ return compiled(_gyral$t26, [
3372
+ game.name,
3373
+ i.Start,
3374
+ s.notice === null ? nothing : compiled(_gyral$t27, [s.notice]),
3375
+ each(options, (o) => o.mode, ModeRow, (o) => o.mode === mode),
3376
+ (mode === "ai" || computerSeatsFor(game, s.setup) > 0) && game.aiLevels.length > 1 ? compiled(_gyral$t28, [i.PickLevel, each(game.aiLevels, (l) => l, LevelOption, (l) => l === s.setup.aiLevel)]) : nothing,
3377
+ counts.length > 1 ? compiled(_gyral$t29, [i.PickPlayers, each(counts, (n) => n, CountOption, (n) => n === s.setup.players)]) : nothing,
3378
+ mode === "pass-and-play" ? compiled(_gyral$t30, [each(names, (f) => f.seat, NameRow), computerSeatsFor(game, s.setup) > 0 ? compiled(_gyral$t31, [computerSeatsFor(game, s.setup) === 1 ? "seat" : `${String(computerSeatsFor(game, s.setup))} seats`]) : nothing]) : nothing,
3379
+ mode === "server" ? compiled(_gyral$t32, []) : nothing,
3380
+ optionsForMode(game.options ?? [], mode ?? "solo").length === 0 ? nothing : compiled(_gyral$t33, [each(optionsForMode(game.options ?? [], mode ?? "solo"), (o) => o.key, GameOptionRow, (o) => s.setup.options?.[o.key] ?? o.default)]),
3381
+ mode === "server" ? compiled(_gyral$t34, [!s.live || !playable]) : compiled(_gyral$t35, [game.name, !s.live || !playable]),
3382
+ setupHint(s, game, options),
3383
+ game.aiContent === true ? compiled(_gyral$t36, []) : nothing,
3384
+ mode === "server" && playable ? joinView(s) : nothing
3385
+ ]);
3386
+ };
3387
+ var resumeView = (save) => {
3388
+ const players = save.players.filter((p) => p !== "");
3389
+ return compiled(_gyral$t37, [
3390
+ save.choices === void 0 ? nothing : compiled(_gyral$t38, [i.ChooseSave, save.choices.map((choice) => compiled(_gyral$t5, [
3391
+ choice.slot,
3392
+ choice.slot === save.slot,
3393
+ choice.label
3394
+ ]))]),
3395
+ players.length > 1 ? `${players.join(" and ")}: ` : "",
3396
+ isoDuration(save.elapsedMs),
3397
+ formatElapsed(save.elapsedMs),
3398
+ i.Resume,
3399
+ i.NewGame,
3400
+ i.Exit
3401
+ ]);
3402
+ };
3403
+ var aiNoticeView = () => compiled(_gyral$t39, [
3404
+ AI_NOTICE.title,
3405
+ AI_NOTICE.body,
3406
+ AI_NOTICE.scope,
3407
+ i.AcceptAiNotice,
3408
+ i.Exit
3409
+ ]);
3410
+ var handoffView = (handoff) => compiled(_gyral$t40, [
3411
+ handoff.name,
3412
+ handoff.name,
3413
+ i.Reveal
3414
+ ]);
3415
+ /**
3416
+ * The results, as a non-modal dialog over the finished game's canvas: modal would make the
3417
+ * page inert, and the results are where the page may offer an update (a safe point). It stays
3418
+ * in the document while closed, so reopening it keeps the ad slot as it was.
3419
+ */
3420
+ /** The buttons that answer an open offer, for a player who hasn't answered it yet. */
3421
+ var answerButtons = (offer, me, what) => {
3422
+ if (me === null || offer.status !== "open") return nothing;
3423
+ if (offer.by === me) return compiled(_gyral$t41, [i.AnswerOffer]);
3424
+ if (offer.accepted.includes(me)) return nothing;
3425
+ return compiled(_gyral$t42, [
3426
+ i.AnswerOffer,
3427
+ what,
3428
+ i.AnswerOffer,
3429
+ what
3430
+ ]);
3431
+ };
3432
+ /** The results' actions: a local game plays again; in a room any player offers a rematch, which starts when everyone accepts (D-61). */
3433
+ var resultActions = (s, game) => {
3434
+ if (s.setup.mode === "daily") return compiled(_gyral$t43, [s.daily === null || s.daily.share === "" ? nothing : compiled(_gyral$t44, [i.Share, i.Share]), game.modes.length > 1 ? compiled(_gyral$t45, [i.ChangeMode]) : nothing]);
3435
+ if (!inRoom(s)) return compiled(_gyral$t46, [i.PlayAgain, i.ChangeMode]);
3436
+ const room = s.room;
3437
+ const me = room?.seat ?? null;
3438
+ const seated = room !== null && me !== null && room.connection === "online";
3439
+ const offer = room?.offer?.kind === "rematch" ? room.offer : null;
3440
+ const open = offer?.status === "open" ? offer : null;
3441
+ const note = offer !== null ? offerText(offer, me) : me === null ? "The players may start a rematch; stay to watch it." : "Any player can offer a rematch. It starts when everyone accepts.";
3442
+ return compiled(_gyral$t47, [
3443
+ seated && open === null ? compiled(_gyral$t48, [i.PlayAgain]) : nothing,
3444
+ seated && open !== null ? answerButtons(open, me, "the rematch") : nothing,
3445
+ i.ChangeMode,
3446
+ note
3447
+ ]);
3448
+ };
3449
+ /** The daily part of the results: streaks, the next release and the share text it would send. */
3450
+ var dailyView = (d) => compiled(_gyral$t49, [
3451
+ d.streak,
3452
+ d.streak === 1 ? "day" : "days",
3453
+ d.bestStreak,
3454
+ d.winStreak === null ? nothing : compiled(_gyral$t50, [d.winStreak, d.bestWinStreak ?? d.winStreak]),
3455
+ d.statistics === void 0 ? nothing : compiled(_gyral$t51, [
3456
+ d.statistics.played,
3457
+ d.statistics.won,
3458
+ d.statistics.winPercent,
3459
+ d.statistics.distribution.map((count, index) => compiled(_gyral$t52, [
3460
+ index + 1,
3461
+ index === 0 ? "guess" : "guesses",
3462
+ Math.max(1, d.statistics.won),
3463
+ count,
3464
+ index + 1,
3465
+ count,
3466
+ count
3467
+ ]))
3468
+ ]),
3469
+ d.next,
3470
+ d.share === "" ? nothing : compiled(_gyral$t53, [d.share, d.shareWords])
3471
+ ]);
3472
+ var resultsView = (s, r, shown, game) => compiled(_gyral$t54, [
3473
+ r.result,
3474
+ shown,
3475
+ i.HideResults,
3476
+ r.headline,
3477
+ r.summary,
3478
+ r.elapsedMs === null ? nothing : compiled(_gyral$t55, [isoDuration(r.elapsedMs), formatElapsed(r.elapsedMs)]),
3479
+ r.assisted === null ? nothing : compiled(_gyral$t56, [r.assisted]),
3480
+ s.daily === null ? nothing : dailyView(s.daily),
3481
+ resultActions(s, game),
3482
+ reportView(s, game),
3483
+ s.daily?.earlier != null ? nothing : compiled(_gyral$t57, [i.HideResults]),
3484
+ game.id
3485
+ ]);
3486
+ var failedView = (message) => compiled(_gyral$t58, [message, i.ChangeMode]);
3487
+ var ReducedMotionOption = (o, picked) => compiled(_gyral$t5, [
3488
+ o.value,
3489
+ picked,
3490
+ o.label
3491
+ ]);
3492
+ var MOTION_OPTIONS = [
3493
+ {
3494
+ value: "system",
3495
+ label: "Follow my device"
3496
+ },
3497
+ {
3498
+ value: "reduce",
3499
+ label: "Reduce motion"
3500
+ },
3501
+ {
3502
+ value: "no-preference",
3503
+ label: "Full motion"
3504
+ }
3505
+ ];
3506
+ var THEME_OPTIONS = [
3507
+ {
3508
+ value: "system",
3509
+ label: "Follow my device"
3510
+ },
3511
+ {
3512
+ value: "light",
3513
+ label: "Light"
3514
+ },
3515
+ {
3516
+ value: "dark",
3517
+ label: "Dark"
3518
+ }
3519
+ ];
3520
+ var preferencesView = (p) => compiled(_gyral$t59, [
3521
+ i.SetPreference,
3522
+ each(MOTION_OPTIONS, (o) => o.value, ReducedMotionOption, (o) => o.value === p.reducedMotion),
3523
+ i.SetPreference,
3524
+ each(THEME_OPTIONS, (o) => o.value, ReducedMotionOption, (o) => o.value === p.theme),
3525
+ p.sound,
3526
+ i.SetPreference,
3527
+ Math.round(p.volume * 100),
3528
+ i.SetPreference,
3529
+ p.singleKeyShortcuts,
3530
+ i.SetPreference,
3531
+ p.aiContentAccepted === true,
3532
+ i.SetPreference
3533
+ ]);
3534
+ /** The puzzle a report names: the one the stage reported, else the daily result's date. */
3535
+ var puzzleOf = (s, game) => s.puzzle ?? (s.daily === null ? "" : `${game.id}:${s.daily.date}`);
3536
+ /**
3537
+ * "Report a problem" for a game with AI-made content (D-52), in the frame: the results and the
3538
+ * menu, never the canvas (D-07).
3539
+ */
3540
+ var reportView = (s, game) => game.aiContent === true ? compiled(_gyral$t60, [game.id, puzzleOf(s, game)]) : nothing;
3541
+ var overlayView = (open, preferences, game, room, canEnd, report) => compiled(_gyral$t61, [
3542
+ open,
3543
+ i.MenuClosed,
3544
+ room ? "Menu" : "Paused",
3545
+ room ? "The match goes on while this menu is open." : `${game.name} waits while this menu is open.`,
3546
+ i.CloseMenu,
3547
+ room ? "Back to the game" : "Resume",
3548
+ canEnd ? compiled(_gyral$t62, [i.OfferEnd]) : nothing,
3549
+ i.Exit,
3550
+ room ? "Leave room" : "Save and exit",
3551
+ canEnd ? compiled(_gyral$t63, []) : nothing,
3552
+ report,
3553
+ preferences === null ? nothing : preferencesView(preferences)
3554
+ ]);
3555
+ var StageRow = (_round, pick) => compiled(_gyral$t64, [
3556
+ pick[2],
3557
+ pick[1],
3558
+ pick[3],
3559
+ pick[0],
3560
+ i.StageOut
3561
+ ]);
3562
+ var stageControl = (s, game) => ({
3563
+ gameId: game.id,
3564
+ mode: toStageMode(s.setup.mode ?? "solo") ?? "solo",
3565
+ seats: s.seats,
3566
+ begin: s.begin,
3567
+ paused: s.phase._tag === "Playing" && s.phase.menu && !inRoom(s),
3568
+ reveals: s.reveals,
3569
+ preferences: s.preferences,
3570
+ config: s.config,
3571
+ setup: Object.fromEntries(optionsForMode(game.options ?? [], s.setup.mode ?? "solo").map((o) => [o.key, s.setup.options?.[o.key] ?? o.default]).concat(s.setup.mode === "ai" && game.players.max === 1 ? [["level", s.setup.aiLevel ?? game.aiLevels[0] ?? "medium"]] : [])),
3572
+ room: s.plan,
3573
+ ...s.resumeSlot === null ? {} : { resumeSlot: s.resumeSlot }
3574
+ });
3575
+ /** The bar's button: the overlay during play; after it, a way back to closed results. */
3576
+ var barButton = (phase, handoff) => {
3577
+ if (phase._tag === "Playing") return compiled(_gyral$t65, [handoff, i.OpenMenu]);
3578
+ if (phase._tag !== "Results") return nothing;
3579
+ return compiled(_gyral$t66, [phase.shown ? "yes" : "no", i.ShowResults]);
3580
+ };
3581
+ /** The bar's clock while a room's decision clock runs: whose it is and what is left. */
3582
+ var timerView = (room) => {
3583
+ const timer = room?.timer ?? null;
3584
+ if (timer === null) return nothing;
3585
+ const mine = timer.seat === room?.seat;
3586
+ return compiled(_gyral$t67, [
3587
+ timer.seconds <= 10 && !timer.paused ? "yes" : "no",
3588
+ timer.paused ? "yes" : "no",
3589
+ mine ? "Your time" : `${timer.name}'s time`,
3590
+ isoDuration(timer.seconds * 1e3),
3591
+ formatElapsed(timer.seconds * 1e3),
3592
+ timer.paused ? " (paused: nobody is at the table)" : ""
3593
+ ]);
3594
+ };
3595
+ /** The bar's line for an offer to end the match: its state, and the viewer's answer buttons. */
3596
+ var offerBar = (room) => {
3597
+ const offer = room?.offer ?? null;
3598
+ if (room === null || offer?.kind !== "end") return nothing;
3599
+ return compiled(_gyral$t68, [offerText(offer, room.seat), room.connection === "online" ? answerButtons(offer, room.seat, "ending the match") : nothing]);
3600
+ };
3601
+ /** A seated player may ask to end a match in progress when no such offer is open. */
3602
+ var canOfferEnd = (room) => room !== null && room.seat !== null && room.phase === "playing" && room.connection === "online" && room.offer?.status !== "open";
3603
+ /** The bar's status line: loading, a room's connection, or the latest notice. */
3604
+ var statusLine = (s, game, notice) => {
3605
+ if (s.phase._tag === "Loading") return s.plan === null ? `Loading ${game.name}…` : s.plan.action === "create" ? "Opening a room…" : "Joining the room…";
3606
+ if (s.phase._tag === "Lobby") return "";
3607
+ return (s.room === null ? null : connectionLine(s.room)) ?? notice ?? "";
3608
+ };
3609
+ var playView = (s, game) => {
3610
+ const { phase } = s;
3611
+ const results = phase._tag === "Results" ? phase : null;
3612
+ const staged = phase._tag === "Loading" || phase._tag === "AiNotice" || phase._tag === "Resume" || phase._tag === "Lobby" || phase._tag === "Playing" || results !== null;
3613
+ const frame = phase._tag === "Playing" ? phase.frame : null;
3614
+ const handoff = frame?.handoff ?? null;
3615
+ const hidden = phase._tag !== "Playing" && results === null || handoff !== null;
3616
+ const inert = results?.shown ?? false;
3617
+ const control = stageControl(s, game);
3618
+ const label = `${game.name}: game`;
3619
+ const notice = frame?.notice ?? s.room?.notice ?? s.notice;
3620
+ const replaced = s.room?.connection === "closed" && s.room.noticeCode === "replaced" && phase._tag !== "Lobby";
3621
+ return compiled(_gyral$t69, [
3622
+ game.name,
3623
+ MODE_LABELS[s.setup.mode ?? "solo"],
3624
+ s.room === null ? "" : ` · ${spacedCode(s.room.code)}`,
3625
+ statusLine(s, game, notice),
3626
+ phase._tag === "Lobby" ? nothing : timerView(s.room),
3627
+ replaced ? compiled(_gyral$t70, [i.RoomAction]) : nothing,
3628
+ barButton(phase, handoff !== null),
3629
+ phase._tag === "Playing" ? offerBar(s.room) : nothing,
3630
+ phase._tag === "AiNotice" ? aiNoticeView() : nothing,
3631
+ phase._tag === "Resume" ? resumeView(phase.save) : nothing,
3632
+ phase._tag === "Lobby" ? lobbyView(s, game) : nothing,
3633
+ handoff === null ? nothing : handoffView(handoff),
3634
+ staged && s.stageReady ? keyed(s.round, StageRow(s.round, [
3635
+ control,
3636
+ hidden,
3637
+ label,
3638
+ inert
3639
+ ])) : nothing,
3640
+ results === null ? nothing : resultsView(s, results.result, results.shown, game),
3641
+ phase._tag === "Playing" ? overlayView(phase.menu, s.preferences, game, inRoom(s), inRoom(s) && canOfferEnd(s.room), reportView(s, game)) : nothing
3642
+ ]);
3643
+ };
3644
+ var mainView = (s, game) => {
3645
+ switch (s.phase._tag) {
3646
+ case "Setup": return setupView(s, game);
3647
+ case "Failed": return failedView(s.phase.message);
3648
+ case "Loading":
3649
+ case "AiNotice":
3650
+ case "Resume":
3651
+ case "Lobby":
3652
+ case "Playing":
3653
+ case "Results": return playView(s, game);
3654
+ }
3655
+ };
3656
+ var styles = css`
3657
+ @layer components {
3658
+ :host {
3659
+ display: block;
3660
+ container-type: inline-size;
3661
+ --launcher-accent: var(--jy-arcade-yellow, var(--jy-accent, oklch(50% 0.2 285)));
3662
+ --launcher-ink: var(--jy-arcade-ink, oklch(20% 0.03 285));
3663
+ }
3664
+ *,
3665
+ *::before,
3666
+ *::after {
3667
+ box-sizing: border-box;
3668
+ }
3669
+ h3,
3670
+ p,
3671
+ dl,
3672
+ dd,
3673
+ fieldset {
3674
+ margin: 0;
3675
+ }
3676
+ .launcher {
3677
+ display: grid;
3678
+ gap: var(--jy-space-s, 1rem);
3679
+ }
3680
+ .setup,
3681
+ .panel,
3682
+ .play {
3683
+ display: grid;
3684
+ gap: var(--jy-space-s, 1rem);
3685
+ }
3686
+ fieldset {
3687
+ padding: var(--jy-space-xs, 0.75rem) var(--jy-space-s, 1rem);
3688
+ border: 2px solid color-mix(in oklch, currentColor 30%, transparent);
3689
+ border-radius: var(--jy-radius-s, 0.5rem);
3690
+ }
3691
+ legend,
3692
+ .kicker,
3693
+ .mode-label,
3694
+ .start,
3695
+ .soon {
3696
+ font-family: var(--jy-font-mono, ui-monospace, monospace);
3697
+ letter-spacing: 0.08em;
3698
+ text-transform: uppercase;
3699
+ }
3700
+ legend {
3701
+ padding-inline: 0.4em;
3702
+ font-size: var(--jy-step--1, 0.9rem);
3703
+ }
3704
+ .mode-list {
3705
+ display: flex;
3706
+ flex-wrap: wrap;
3707
+ gap: var(--jy-space-2xs, 0.5rem) var(--jy-space-s, 1rem);
3708
+ }
3709
+ .mode {
3710
+ display: inline-flex;
3711
+ align-items: center;
3712
+ gap: 0.5em;
3713
+ min-block-size: var(--jy-target-min, 2.75rem);
3714
+ cursor: pointer;
3715
+ &[data-playable='no'] {
3716
+ cursor: not-allowed;
3717
+ opacity: 0.75;
3718
+ }
3719
+ }
3720
+ .soon {
3721
+ font-size: 0.7rem;
3722
+ padding: 0.1em 0.5em;
3723
+ border: 1px solid currentColor;
3724
+ border-radius: var(--jy-radius-pill, 999px);
3725
+ }
3726
+ input[type='radio'],
3727
+ input[type='checkbox'] {
3728
+ inline-size: 1.15em;
3729
+ block-size: 1.15em;
3730
+ margin: 0;
3731
+ accent-color: var(--launcher-accent);
3732
+ }
3733
+ input[type='range'] {
3734
+ accent-color: var(--launcher-accent);
3735
+ }
3736
+ .field,
3737
+ .name {
3738
+ display: grid;
3739
+ gap: var(--jy-space-3xs, 0.25rem);
3740
+ justify-items: start;
3741
+ }
3742
+ .names {
3743
+ display: grid;
3744
+ gap: var(--jy-space-xs, 0.75rem);
3745
+ }
3746
+ .check {
3747
+ display: flex;
3748
+ align-items: center;
3749
+ gap: 0.5em;
3750
+ min-block-size: var(--jy-target-min, 2.75rem);
3751
+ }
3752
+ input:not([type]),
3753
+ select {
3754
+ min-block-size: var(--jy-target-min, 2.75rem);
3755
+ padding-inline: 0.6em;
3756
+ border: 2px solid color-mix(in oklch, currentColor 35%, transparent);
3757
+ border-radius: var(--jy-radius-s, 0.5rem);
3758
+ background: var(--jy-surface-raised, Canvas);
3759
+ color: var(--jy-text, CanvasText);
3760
+ font: inherit;
3761
+ }
3762
+ input[aria-invalid='true'] {
3763
+ border-color: var(--jy-danger, red);
3764
+ }
3765
+ .error {
3766
+ color: var(--jy-danger, red);
3767
+ font-weight: 600;
3768
+ }
3769
+ .actions {
3770
+ display: flex;
3771
+ flex-wrap: wrap;
3772
+ align-items: center;
3773
+ gap: var(--jy-space-2xs, 0.5rem) var(--jy-space-s, 1rem);
3774
+ }
3775
+ button,
3776
+ .back {
3777
+ min-block-size: var(--jy-target-min, 2.75rem);
3778
+ padding: 0.55em 1.2em;
3779
+ border: 2px solid var(--launcher-accent);
3780
+ border-radius: var(--jy-radius-s, 0.5rem);
3781
+ background: transparent;
3782
+ color: inherit;
3783
+ font: inherit;
3784
+ font-weight: 600;
3785
+ cursor: pointer;
3786
+ touch-action: manipulation;
3787
+ transition: translate var(--jy-duration-fast, 120ms) var(--jy-ease-out, ease-out);
3788
+ }
3789
+ .back {
3790
+ display: inline-flex;
3791
+ align-items: center;
3792
+ text-decoration: none;
3793
+ }
3794
+ .primary {
3795
+ border-color: transparent;
3796
+ background: var(--launcher-accent);
3797
+ color: var(--launcher-ink);
3798
+ box-shadow: 0 0.25em 0 color-mix(in oklch, var(--launcher-accent) 55%, black);
3799
+ }
3800
+ .start {
3801
+ padding-inline: 1.6em;
3802
+ font-weight: 700;
3803
+ letter-spacing: 0.1em;
3804
+ }
3805
+ button:active:not(:disabled) {
3806
+ translate: 0 0.15em;
3807
+ }
3808
+ button:disabled {
3809
+ opacity: 0.6;
3810
+ cursor: not-allowed;
3811
+ }
3812
+ :is(button, .back, input, select):focus-visible {
3813
+ outline: 3px solid var(--jy-focus-ring, currentColor);
3814
+ outline-offset: 3px;
3815
+ }
3816
+ .hint,
3817
+ .note {
3818
+ font-size: var(--jy-step--1, 0.9rem);
3819
+ opacity: 0.85;
3820
+ }
3821
+ .notice {
3822
+ font-weight: 600;
3823
+ }
3824
+ .bar {
3825
+ display: flex;
3826
+ flex-wrap: wrap;
3827
+ align-items: center;
3828
+ gap: var(--jy-space-2xs, 0.5rem) var(--jy-space-s, 1rem);
3829
+ }
3830
+ .mode-label {
3831
+ font-size: var(--jy-step--1, 0.9rem);
3832
+ color: var(--launcher-accent);
3833
+ }
3834
+ .status {
3835
+ flex: 1;
3836
+ min-inline-size: 0;
3837
+ min-block-size: 1lh;
3838
+ }
3839
+ .menu-button {
3840
+ margin-inline-start: auto;
3841
+ }
3842
+ /* Keeps its place in the bar while the results show, so nothing moves when they close. */
3843
+ .show-results[data-held='yes'] {
3844
+ visibility: hidden;
3845
+ }
3846
+ /* The canvas and, after the game, the results over it. */
3847
+ .arena {
3848
+ position: relative;
3849
+ display: grid;
3850
+ }
3851
+ /* The canvas: the game's own surface and theme tokens, set by the stage. */
3852
+ .stage {
3853
+ display: block;
3854
+ min-block-size: 12rem;
3855
+ border-radius: var(--jy-radius-m, 0.75rem);
3856
+ outline-offset: 4px;
3857
+ transition: opacity var(--jy-duration, 200ms) var(--jy-ease-out, ease-out);
3858
+ &[hidden] {
3859
+ display: none;
3860
+ }
3861
+ /* Behind the results the final board stays visible, dimmed, and can't be used. */
3862
+ &[inert] {
3863
+ opacity: 0.55;
3864
+ }
3865
+ }
3866
+ .handoff {
3867
+ place-items: center;
3868
+ min-block-size: 16rem;
3869
+ padding: var(--jy-space-l, 2rem) var(--jy-space-s, 1rem);
3870
+ border: 3px dashed var(--launcher-accent);
3871
+ border-radius: var(--jy-radius-m, 0.75rem);
3872
+ text-align: center;
3873
+ h3 {
3874
+ font-size: var(--jy-step-1, 1.4rem);
3875
+ text-wrap: balance;
3876
+ }
3877
+ }
3878
+ .reveal {
3879
+ min-inline-size: min(100%, 16rem);
3880
+ min-block-size: 3.5rem;
3881
+ }
3882
+ /*
3883
+ * Over the canvas, out of the flow: opening and closing the results never moves the board
3884
+ * or the page. A board shorter than the results scrolls them instead of growing.
3885
+ */
3886
+ .results {
3887
+ position: absolute;
3888
+ inset-block-start: var(--jy-space-s, 1rem);
3889
+ inset-inline: var(--jy-space-s, 1rem);
3890
+ z-index: 1;
3891
+ inline-size: auto;
3892
+ block-size: auto;
3893
+ max-inline-size: 48rem;
3894
+ max-block-size: calc(100% - 2 * var(--jy-space-s, 1rem));
3895
+ margin: 0 auto;
3896
+ padding: var(--jy-space-m, 1.5rem);
3897
+ overflow: auto;
3898
+ overscroll-behavior: contain;
3899
+ border: 3px solid var(--launcher-accent);
3900
+ border-radius: var(--jy-radius-m, 0.75rem);
3901
+ background: var(--jy-surface, Canvas);
3902
+ color: var(--jy-text, CanvasText);
3903
+ box-shadow: var(--jy-shadow, none);
3904
+ opacity: 1;
3905
+ translate: 0 0;
3906
+ transition:
3907
+ opacity var(--jy-duration, 200ms) var(--jy-ease-out, ease-out),
3908
+ translate var(--jy-duration, 200ms) var(--jy-ease-out, ease-out),
3909
+ display var(--jy-duration, 200ms) allow-discrete;
3910
+ &[open] {
3911
+ display: grid;
3912
+ grid-template-columns: minmax(0, 1fr);
3913
+ gap: var(--jy-space-s, 1rem);
3914
+ align-items: start;
3915
+ }
3916
+ &:not([open]) {
3917
+ opacity: 0;
3918
+ translate: 0 0.5rem;
3919
+ }
3920
+ }
3921
+ @starting-style {
3922
+ .results[open] {
3923
+ /* Keep text readable from the first frame; animate the panel's position. */
3924
+ translate: 0 0.5rem;
3925
+ }
3926
+ }
3927
+ @container (inline-size >= 40rem) {
3928
+ .results[open] {
3929
+ grid-template-columns: minmax(0, 1fr) 300px;
3930
+ }
3931
+ }
3932
+ .results-body {
3933
+ display: grid;
3934
+ gap: var(--jy-space-s, 1rem);
3935
+ align-content: start;
3936
+ }
3937
+ .results h3 {
3938
+ font-size: var(--jy-step-2, 2rem);
3939
+ color: var(--launcher-accent);
3940
+ }
3941
+ .kicker {
3942
+ font-size: var(--jy-step--1, 0.9rem);
3943
+ }
3944
+ .facts {
3945
+ display: flex;
3946
+ flex-wrap: wrap;
3947
+ gap: var(--jy-space-s, 1rem);
3948
+ dt {
3949
+ font-size: 0.75rem;
3950
+ letter-spacing: 0.08em;
3951
+ text-transform: uppercase;
3952
+ opacity: 0.8;
3953
+ }
3954
+ dd {
3955
+ font-weight: 700;
3956
+ font-variant-numeric: tabular-nums;
3957
+ }
3958
+ }
3959
+ /* The daily results: the next release, and the share text exactly as Share sends it. */
3960
+ .next {
3961
+ margin-block: var(--jy-space-xs, 0.5rem);
3962
+ }
3963
+ .share-preview {
3964
+ margin: 0 0 var(--jy-space-s, 1rem);
3965
+ figcaption {
3966
+ font-size: 0.75rem;
3967
+ letter-spacing: 0.08em;
3968
+ text-transform: uppercase;
3969
+ opacity: 0.8;
3970
+ }
3971
+ pre {
3972
+ margin: var(--jy-space-2xs, 0.25rem) 0 0;
3973
+ padding: var(--jy-space-xs, 0.5rem);
3974
+ border-radius: 0.5rem;
3975
+ background: color-mix(in oklch, currentColor 8%, transparent);
3976
+ font-family: inherit;
3977
+ line-height: 1.3;
3978
+ white-space: pre-wrap;
3979
+ overflow-wrap: anywhere;
3980
+ }
3981
+ }
3982
+ .results-ad {
3983
+ min-inline-size: 0;
3984
+ }
3985
+ .review-board {
3986
+ min-inline-size: 0;
3987
+ padding-inline: 0;
3988
+ border-color: transparent;
3989
+ text-decoration: underline;
3990
+ text-underline-offset: 0.2em;
3991
+ }
3992
+ .overlay {
3993
+ inline-size: min(100% - 2rem, 30rem);
3994
+ max-block-size: min(100dvh - 2rem, 44rem);
3995
+ padding: var(--jy-space-m, 1.5rem);
3996
+ border: 3px solid var(--launcher-accent);
3997
+ border-radius: var(--jy-radius-m, 0.75rem);
3998
+ background: var(--jy-surface, Canvas);
3999
+ color: var(--jy-text, CanvasText);
4000
+ box-shadow: var(--jy-shadow, none);
4001
+ opacity: 1;
4002
+ scale: 1;
4003
+ transition:
4004
+ opacity var(--jy-duration, 200ms) var(--jy-ease-out, ease-out),
4005
+ scale var(--jy-duration, 200ms) var(--jy-ease-out, ease-out),
4006
+ display var(--jy-duration, 200ms) allow-discrete,
4007
+ overlay var(--jy-duration, 200ms) allow-discrete;
4008
+ &:not([open]) {
4009
+ opacity: 0;
4010
+ scale: 0.96;
4011
+ }
4012
+ &::backdrop {
4013
+ background: oklch(15% 0.03 285 / 0.6);
4014
+ }
4015
+ &[open] {
4016
+ display: grid;
4017
+ gap: var(--jy-space-s, 1rem);
4018
+ }
4019
+ }
4020
+ @starting-style {
4021
+ .overlay[open] {
4022
+ opacity: 0;
4023
+ scale: 0.96;
4024
+ }
4025
+ }
4026
+ /* Online with friends: the join form and the lobby. */
4027
+ .join,
4028
+ .lobby {
4029
+ display: grid;
4030
+ gap: var(--jy-space-s, 1rem);
4031
+ padding: var(--jy-space-s, 1rem);
4032
+ border: 2px solid color-mix(in oklch, currentColor 30%, transparent);
4033
+ border-radius: var(--jy-radius-s, 0.5rem);
4034
+ }
4035
+ .join h3,
4036
+ .lobby h3 {
4037
+ font-size: var(--jy-step-1, 1.4rem);
4038
+ }
4039
+ .lobby h4 {
4040
+ margin: 0;
4041
+ font-size: var(--jy-step-0, 1rem);
4042
+ }
4043
+ .code,
4044
+ .invite-link {
4045
+ font-family: var(--jy-font-mono, ui-monospace, monospace);
4046
+ letter-spacing: 0.08em;
4047
+ }
4048
+ .code {
4049
+ color: var(--launcher-accent);
4050
+ white-space: nowrap;
4051
+ }
4052
+ .invite {
4053
+ display: grid;
4054
+ gap: var(--jy-space-2xs, 0.5rem);
4055
+ }
4056
+ .invite .field,
4057
+ .join .field {
4058
+ justify-items: stretch;
4059
+ }
4060
+ .invite-link,
4061
+ #room-code {
4062
+ inline-size: min(100%, 36rem);
4063
+ }
4064
+ .seats {
4065
+ display: grid;
4066
+ gap: var(--jy-space-2xs, 0.5rem);
4067
+ margin: 0;
4068
+ padding: 0;
4069
+ list-style: none;
4070
+ counter-reset: seat;
4071
+ }
4072
+ .seat {
4073
+ display: flex;
4074
+ flex-wrap: wrap;
4075
+ align-items: center;
4076
+ gap: var(--jy-space-3xs, 0.25rem) var(--jy-space-xs, 0.75rem);
4077
+ min-block-size: var(--jy-target-min, 2.75rem);
4078
+ padding-inline: var(--jy-space-xs, 0.75rem);
4079
+ border-radius: var(--jy-radius-s, 0.5rem);
4080
+ background: color-mix(in oklch, currentColor 6%, transparent);
4081
+ counter-increment: seat;
4082
+ &::before {
4083
+ content: counter(seat);
4084
+ min-inline-size: 1.5em;
4085
+ font-family: var(--jy-font-mono, ui-monospace, monospace);
4086
+ opacity: 0.7;
4087
+ }
4088
+ &[data-open='yes'] .seat-name {
4089
+ font-style: italic;
4090
+ opacity: 0.8;
4091
+ }
4092
+ &[data-ready='yes']::after {
4093
+ content: '✓' / '';
4094
+ color: var(--launcher-accent);
4095
+ font-weight: 700;
4096
+ }
4097
+ }
4098
+ .seat-name {
4099
+ font-weight: 600;
4100
+ }
4101
+ .seat-tags {
4102
+ flex: 1;
4103
+ opacity: 0.85;
4104
+ }
4105
+ .small {
4106
+ min-block-size: var(--jy-target-min, 2.75rem);
4107
+ padding: 0.3em 0.9em;
4108
+ font-size: var(--jy-step--1, 0.9rem);
4109
+ }
4110
+ .ready[aria-pressed='true'] {
4111
+ background: color-mix(in oklch, var(--launcher-accent) 25%, transparent);
4112
+ }
4113
+ .room-status:empty {
4114
+ display: none;
4115
+ }
4116
+ .timer {
4117
+ font-family: var(--jy-font-mono, ui-monospace, monospace);
4118
+ font-variant-numeric: tabular-nums;
4119
+ &[data-low='yes'] {
4120
+ color: var(--jy-danger, red);
4121
+ font-weight: 700;
4122
+ }
4123
+ }
4124
+ .offer {
4125
+ display: flex;
4126
+ flex-wrap: wrap;
4127
+ align-items: center;
4128
+ gap: var(--jy-space-3xs, 0.25rem) var(--jy-space-xs, 0.75rem);
4129
+ flex-basis: 100%;
4130
+ }
4131
+ .visually-hidden {
4132
+ position: absolute;
4133
+ inline-size: 1px;
4134
+ block-size: 1px;
4135
+ overflow: hidden;
4136
+ clip-path: inset(50%);
4137
+ white-space: nowrap;
4138
+ }
4139
+ /* Reduced motion removes the frame's decorative motion: the player's choice wins over the system's. */
4140
+ :host(:state(reduce-motion)) *,
4141
+ :host(:state(reduce-motion)) *::backdrop {
4142
+ transition: none !important;
4143
+ animation: none !important;
4144
+ }
4145
+ @media (prefers-reduced-motion: reduce) {
4146
+ :host(:not(:state(allow-motion))) *,
4147
+ :host(:not(:state(allow-motion))) *::backdrop {
4148
+ transition: none !important;
4149
+ animation: none !important;
4150
+ }
4151
+ }
4152
+ @media (forced-colors: active) {
4153
+ button,
4154
+ .back {
4155
+ border-color: ButtonText;
4156
+ }
4157
+ }
4158
+ }
4159
+ `;
4160
+ var Launcher = define()("jy-launcher", {
4161
+ props,
4162
+ init: (p) => [freshState(p.game), [reportSafePoint({
4163
+ safe: true,
4164
+ gameId: p.game.id
4165
+ })]],
4166
+ states: (s) => ({
4167
+ live: s.live,
4168
+ playing: s.phase._tag === "Playing",
4169
+ "reduce-motion": s.preferences?.reducedMotion === "reduce",
4170
+ "allow-motion": s.preferences?.reducedMotion === "no-preference"
4171
+ }),
4172
+ intent: {
4173
+ PickGameOption: ({ target, value, checked }) => {
4174
+ const key = target.name;
4175
+ return /^[a-z][A-Za-z0-9]{0,49}$/.test(key) && value !== void 0 ? {
4176
+ _tag: "PickGameOption",
4177
+ key,
4178
+ value,
4179
+ checked
4180
+ } : void 0;
4181
+ },
4182
+ PickMode: ({ value }) => value !== void 0 && [
4183
+ "solo",
4184
+ "ai",
4185
+ "pass-and-play",
4186
+ "p2p",
4187
+ "server",
4188
+ "daily"
4189
+ ].some((m) => m === value) ? {
4190
+ _tag: "PickMode",
4191
+ mode: value
4192
+ } : void 0,
4193
+ PickLevel: ({ value }) => value === void 0 || value === "" ? void 0 : {
4194
+ _tag: "PickLevel",
4195
+ level: value
4196
+ },
4197
+ PickPlayers: ({ value }) => {
4198
+ const players = Number(value);
4199
+ return Number.isInteger(players) && players > 0 ? {
4200
+ _tag: "PickPlayers",
4201
+ players
4202
+ } : void 0;
4203
+ },
4204
+ Rename: ({ value, target }) => {
4205
+ const match = /^seat-(\d+)$/.exec(target.name);
4206
+ return match?.[1] === void 0 ? void 0 : {
4207
+ _tag: "Rename",
4208
+ seat: Number(match[1]),
4209
+ name: (value ?? "").slice(0, 40)
4210
+ };
4211
+ },
4212
+ Start: () => ({ _tag: "Start" }),
4213
+ StageOut: ({ detail }) => {
4214
+ const out = parseStageOutput(detail);
4215
+ return out === void 0 ? void 0 : {
4216
+ _tag: "StageOut",
4217
+ out
4218
+ };
4219
+ },
4220
+ AcceptAiNotice: () => ({ _tag: "AcceptAiNotice" }),
4221
+ Resume: () => ({ _tag: "Resume" }),
4222
+ ChooseSave: ({ value }) => value === void 0 ? void 0 : {
4223
+ _tag: "ChooseSave",
4224
+ slot: value
4225
+ },
4226
+ NewGame: () => ({ _tag: "NewGame" }),
4227
+ Reveal: () => ({ _tag: "Reveal" }),
4228
+ OpenMenu: () => ({ _tag: "OpenMenu" }),
4229
+ CloseMenu: () => ({ _tag: "CloseMenu" }),
4230
+ MenuClosed: () => ({ _tag: "MenuClosed" }),
4231
+ SetPreference: ({ value, checked, target }) => {
4232
+ const changes = parsePreferenceChange(target.name, value, checked);
4233
+ return changes === void 0 ? void 0 : {
4234
+ _tag: "SetPreference",
4235
+ changes
4236
+ };
4237
+ },
4238
+ Exit: () => ({ _tag: "Exit" }),
4239
+ PlayAgain: () => ({ _tag: "PlayAgain" }),
4240
+ ChangeMode: () => ({ _tag: "ChangeMode" }),
4241
+ HideResults: ({ key }) => key === void 0 || key === "Escape" ? { _tag: "HideResults" } : void 0,
4242
+ ShowResults: () => ({ _tag: "ShowResults" }),
4243
+ TypeCode: ({ value }) => ({
4244
+ _tag: "TypeCode",
4245
+ code: (value ?? "").slice(0, 200)
4246
+ }),
4247
+ ToggleWatch: ({ checked }) => checked === void 0 ? void 0 : {
4248
+ _tag: "ToggleWatch",
4249
+ watch: checked
4250
+ },
4251
+ JoinRoom: () => ({ _tag: "JoinRoom" }),
4252
+ ToggleReady: ({ value }) => value === "yes" || value === "no" ? {
4253
+ _tag: "RoomRequest",
4254
+ request: {
4255
+ kind: "ready",
4256
+ ready: value === "yes"
4257
+ }
4258
+ } : void 0,
4259
+ StartMatch: () => ({
4260
+ _tag: "RoomRequest",
4261
+ request: { kind: "start" }
4262
+ }),
4263
+ PickClock: ({ value }) => {
4264
+ const setting = parseClockValue(value);
4265
+ return setting === void 0 ? void 0 : {
4266
+ _tag: "RoomRequest",
4267
+ request: {
4268
+ kind: "clock",
4269
+ setting
4270
+ }
4271
+ };
4272
+ },
4273
+ PickRoomLevel: ({ value }) => value === void 0 || value === "" ? void 0 : {
4274
+ _tag: "RoomRequest",
4275
+ request: {
4276
+ kind: "ai-level",
4277
+ level: value
4278
+ }
4279
+ },
4280
+ FillSeat: ({ value }) => {
4281
+ const seat = seatOf(value);
4282
+ return seat === void 0 ? void 0 : {
4283
+ _tag: "RoomRequest",
4284
+ request: {
4285
+ kind: "fill-with-ai",
4286
+ seat
4287
+ }
4288
+ };
4289
+ },
4290
+ RemoveSeat: ({ value }) => {
4291
+ const seat = seatOf(value);
4292
+ return seat === void 0 ? void 0 : {
4293
+ _tag: "RoomRequest",
4294
+ request: {
4295
+ kind: "remove-seat",
4296
+ seat
4297
+ }
4298
+ };
4299
+ },
4300
+ RoomAction: ({ value }) => value === "leave" || value === "reconnect" ? {
4301
+ _tag: "RoomRequest",
4302
+ request: { kind: value }
4303
+ } : void 0,
4304
+ OfferEnd: () => ({ _tag: "OfferEnd" }),
4305
+ AnswerOffer: ({ value }) => value === "accept" || value === "decline" || value === "withdraw" ? {
4306
+ _tag: "AnswerOffer",
4307
+ answer: value
4308
+ } : void 0,
4309
+ Copy: ({ value }) => value === "link" || value === "code" ? {
4310
+ _tag: "Copy",
4311
+ what: value
4312
+ } : void 0,
4313
+ Share: ({ value }) => value === "symbols" || value === "words" ? {
4314
+ _tag: "Share",
4315
+ form: value
4316
+ } : void 0
4317
+ },
4318
+ update: {
4319
+ PickGameOption: (s, m, { props: { game } }) => {
4320
+ if (s.phase._tag !== "Setup") return s;
4321
+ const option = optionsForMode(game.options ?? [], s.setup.mode ?? "solo").find((o) => o.key === m.key);
4322
+ const value = option?.kind === "toggle" ? m.checked : option?.choices.find((c) => String(c.value) === m.value)?.value;
4323
+ return value === void 0 ? s : {
4324
+ ...s,
4325
+ setup: {
4326
+ ...s.setup,
4327
+ options: {
4328
+ ...s.setup.options,
4329
+ [m.key]: value
4330
+ }
4331
+ }
4332
+ };
4333
+ },
4334
+ PickMode: (s, m, { props: { game } }) => s.phase._tag === "Setup" && optionsOf(s, game).some((o) => o.mode === m.mode && o.playable) ? {
4335
+ ...s,
4336
+ setup: pickMode(game, s.setup, m.mode)
4337
+ } : s,
4338
+ PickLevel: (s, m, { props: { game } }) => game.aiLevels.includes(m.level) ? {
4339
+ ...s,
4340
+ setup: {
4341
+ ...s.setup,
4342
+ aiLevel: m.level
4343
+ }
4344
+ } : s,
4345
+ PickPlayers: (s, m, { props: { game } }) => playerCounts(game, s.setup.mode).includes(m.players) ? {
4346
+ ...s,
4347
+ setup: {
4348
+ ...s.setup,
4349
+ players: m.players,
4350
+ errors: []
4351
+ }
4352
+ } : s,
4353
+ Rename: (s, m) => {
4354
+ if (m.seat < 0 || m.seat >= s.setup.players) return s;
4355
+ const names = Array.from({ length: s.setup.players }, (_, seat) => seat === m.seat ? m.name : s.setup.names[seat] ?? "");
4356
+ const errors = s.setup.errors.map((e, seat) => seat === m.seat ? null : e);
4357
+ return {
4358
+ ...s,
4359
+ setup: {
4360
+ ...s.setup,
4361
+ names,
4362
+ errors
4363
+ }
4364
+ };
4365
+ },
4366
+ Start: (s, _m, { props: { game } }) => {
4367
+ if (!s.live || s.phase._tag !== "Setup") return s;
4368
+ if (!optionsOf(s, game).some((o) => o.mode === s.setup.mode && o.playable)) return s;
4369
+ if (s.setup.mode === "server") return startRound(s, game, [], null, { action: "create" });
4370
+ const seats = seatsFor(game, s.setup);
4371
+ if (!seats.ok) return [{
4372
+ ...s,
4373
+ setup: {
4374
+ ...s.setup,
4375
+ errors: seats.errors
4376
+ }
4377
+ }, [focus("input[aria-invalid=\"true\"]")]];
4378
+ return startRound(s, game, seats.seats, null);
4379
+ },
4380
+ StageLoaded: (s) => ({
4381
+ ...s,
4382
+ stageReady: true
4383
+ }),
4384
+ StageOut: (s, m, { props: { game } }) => fromStage(s, m.out, game),
4385
+ AcceptAiNotice: (s, _m, { props: { game } }) => s.phase._tag === "AiNotice" && s.preferences !== null ? proceed({
4386
+ ...s,
4387
+ preferences: {
4388
+ ...s.preferences,
4389
+ aiContentAccepted: true
4390
+ }
4391
+ }, game, s.phase.save) : s,
4392
+ Resume: (s, _m, { props: { game } }) => s.phase._tag === "Resume" ? beginPlay(s, game, "resume") : s,
4393
+ ChooseSave: (s, m) => {
4394
+ if (s.phase._tag !== "Resume") return s;
4395
+ const choice = s.phase.save.choices?.find((c) => c.slot === m.slot);
4396
+ return choice === void 0 ? s : {
4397
+ ...s,
4398
+ phase: {
4399
+ _tag: "Resume",
4400
+ save: {
4401
+ ...s.phase.save,
4402
+ ...choice
4403
+ }
4404
+ }
4405
+ };
4406
+ },
4407
+ NewGame: (s, _m, { props: { game } }) => s.phase._tag === "Resume" ? beginPlay(s, game, "new") : s,
4408
+ Reveal: (s) => s.phase._tag === "Playing" && s.phase.frame?.handoff != null ? [{
4409
+ ...s,
4410
+ reveals: s.reveals + 1
4411
+ }, [focus(STAGE)]] : s,
4412
+ OpenMenu: (s, _m, { props: { game } }) => s.phase._tag === "Playing" && s.phase.frame?.handoff == null ? settle({
4413
+ ...s,
4414
+ phase: {
4415
+ ...s.phase,
4416
+ menu: true
4417
+ }
4418
+ }, game) : s,
4419
+ CloseMenu: (s) => s.phase._tag === "Playing" && s.phase.menu ? {
4420
+ ...s,
4421
+ phase: {
4422
+ ...s.phase,
4423
+ menu: false
4424
+ }
4425
+ } : s,
4426
+ MenuClosed: (s) => s.phase._tag === "Playing" && s.phase.menu ? {
4427
+ ...s,
4428
+ phase: {
4429
+ ...s.phase,
4430
+ menu: false
4431
+ }
4432
+ } : s,
4433
+ SetPreference: (s, m) => s.preferences === null ? s : {
4434
+ ...s,
4435
+ preferences: {
4436
+ ...s.preferences,
4437
+ ...m.changes
4438
+ }
4439
+ },
4440
+ Exit: (s, _m, { props: { game } }) => {
4441
+ if (inRoom(s) && s.room !== null && (s.phase._tag === "Playing" || s.phase._tag === "Lobby")) return ask(s, { kind: "leave" });
4442
+ return s.phase._tag === "Playing" || s.phase._tag === "Resume" || s.phase._tag === "Loading" || s.phase._tag === "AiNotice" ? toSetup(s, game) : s;
4443
+ },
4444
+ PlayAgain: (s, _m, { props: { game } }) => {
4445
+ if (s.phase._tag !== "Results") return s;
4446
+ return inRoom(s) ? askRoom(s, {
4447
+ kind: "offer",
4448
+ offer: "rematch"
4449
+ }) : startRound(s, game, s.seats, s.rematch);
4450
+ },
4451
+ ChangeMode: (s, _m, { props: { game } }) => {
4452
+ if (inRoom(s) && s.room !== null && s.phase._tag === "Results") return ask(s, { kind: "leave" });
4453
+ return s.phase._tag === "Results" || s.phase._tag === "Failed" ? toSetup(s, game) : s;
4454
+ },
4455
+ HideResults: (s) => s.phase._tag === "Results" && s.phase.shown && s.daily?.earlier == null ? [{
4456
+ ...s,
4457
+ phase: {
4458
+ ...s.phase,
4459
+ shown: false
4460
+ }
4461
+ }, [focus(STAGE)]] : s,
4462
+ ShowResults: (s) => s.phase._tag === "Results" && !s.phase.shown ? [{
4463
+ ...s,
4464
+ phase: {
4465
+ ...s.phase,
4466
+ shown: true
4467
+ }
4468
+ }, [focus("#results-title")]] : s,
4469
+ Hydrated: (s, _m, { props: { game } }) => [{
4470
+ ...s,
4471
+ live: true
4472
+ }, [asksOnline(game, s.online) ? checkOnline((online) => ({
4473
+ _tag: "OnlineChecked",
4474
+ online
4475
+ })) : readInvite((code) => ({
4476
+ _tag: "InviteFound",
4477
+ code
4478
+ }))]],
4479
+ OnlineChecked: (s, m, { props: { game } }) => {
4480
+ const next = {
4481
+ ...s,
4482
+ online: m.online
4483
+ };
4484
+ const options = optionsOf(next, game);
4485
+ const first = options.find((o) => o.playable)?.mode;
4486
+ const keep = s.setup.mode !== null && options.some((o) => o.mode === s.setup.mode && o.playable);
4487
+ const setup = s.phase._tag !== "Setup" || keep || first === void 0 ? s.setup : pickMode(game, s.setup, first);
4488
+ return [{
4489
+ ...next,
4490
+ setup
4491
+ }, [readInvite((code) => ({
4492
+ _tag: "InviteFound",
4493
+ code
4494
+ }))]];
4495
+ },
4496
+ TypeCode: (s, m) => s.phase._tag === "Setup" ? {
4497
+ ...s,
4498
+ setup: {
4499
+ ...s.setup,
4500
+ code: m.code,
4501
+ codeError: null
4502
+ }
4503
+ } : s,
4504
+ ToggleWatch: (s, m) => s.phase._tag === "Setup" ? {
4505
+ ...s,
4506
+ setup: {
4507
+ ...s.setup,
4508
+ watch: m.watch
4509
+ }
4510
+ } : s,
4511
+ JoinRoom: (s, _m, { props: { game } }) => {
4512
+ if (!s.live || s.phase._tag !== "Setup" || s.setup.mode !== "server") return s;
4513
+ if (!optionsOf(s, game).some((o) => o.mode === "server" && o.playable)) return s;
4514
+ const code = parseRoomCode(s.setup.code);
4515
+ if (code === null) return [{
4516
+ ...s,
4517
+ setup: {
4518
+ ...s.setup,
4519
+ codeError: "Enter the six-character code from the invite, or paste the invite link."
4520
+ }
4521
+ }, [focus("#room-code")]];
4522
+ return startRound({
4523
+ ...s,
4524
+ setup: {
4525
+ ...s.setup,
4526
+ code,
4527
+ codeError: null
4528
+ }
4529
+ }, game, [], null, {
4530
+ action: "join",
4531
+ code,
4532
+ watch: s.setup.watch
4533
+ });
4534
+ },
4535
+ InviteFound: (s, m, { props: { game } }) => {
4536
+ if (s.phase._tag !== "Setup" || !optionsOf(s, game).some((o) => o.mode === "server" && o.playable)) return s;
4537
+ return [{
4538
+ ...s,
4539
+ setup: {
4540
+ ...pickMode(game, s.setup, "server"),
4541
+ code: m.code,
4542
+ codeError: null
4543
+ }
4544
+ }, [focus(".join-room")]];
4545
+ },
4546
+ RoomRequest: (s, m) => m.request.kind === "ai-level" && s.room?.aiLevels.includes(m.request.level) !== true ? s : askRoom(s, m.request),
4547
+ OfferEnd: (s) => s.phase._tag === "Playing" && canOfferEnd(s.room) ? askRoom({
4548
+ ...s,
4549
+ phase: {
4550
+ ...s.phase,
4551
+ menu: false
4552
+ }
4553
+ }, {
4554
+ kind: "offer",
4555
+ offer: "end"
4556
+ }) : s,
4557
+ AnswerOffer: (s, m) => {
4558
+ const offer = s.room?.offer ?? null;
4559
+ return offer?.status === "open" ? askRoom(s, {
4560
+ kind: "answer",
4561
+ offer: offer.id,
4562
+ answer: m.answer
4563
+ }) : s;
4564
+ },
4565
+ Copy: (s, m) => s.room === null ? s : [s, [copyText(m.what === "link" ? s.room.link : s.room.code, (ok) => ({
4566
+ _tag: "Copied",
4567
+ what: m.what,
4568
+ ok
4569
+ }))]],
4570
+ Copied: (s, m) => ({
4571
+ ...s,
4572
+ polite: say(s.polite, m.ok ? m.what === "link" ? "Invite link copied." : "Room code copied." : "Copying didn’t work here. Select the link and copy it yourself.")
4573
+ }),
4574
+ Share: (s, m) => {
4575
+ const d = s.daily;
4576
+ if (d === null || d.share === "" || s.phase._tag !== "Results") return s;
4577
+ return m.form === "symbols" ? [s, [shareText(d.share, (how) => ({
4578
+ _tag: "Shared",
4579
+ form: "symbols",
4580
+ how
4581
+ }))]] : [s, [copyText(d.shareWords, (ok) => ({
4582
+ _tag: "Shared",
4583
+ form: "words",
4584
+ how: ok ? "copied" : "failed"
4585
+ }))]];
4586
+ },
4587
+ Shared: (s, m) => {
4588
+ const line = m.how === "shared" ? "Shared." : m.how === "copied" ? m.form === "words" ? "Result copied as text." : "Result copied. Paste it anywhere." : m.how === "cancelled" ? null : "Copying didn’t work here. Select the result and copy it yourself.";
4589
+ return line === null ? s : {
4590
+ ...s,
4591
+ polite: say(s.polite, line)
4592
+ };
4593
+ },
4594
+ PropsChanged: (s, { props: p, prev }) => {
4595
+ if (p.game.id === prev.game.id) return s;
4596
+ const fresh = freshState(p.game, s.live, s.online);
4597
+ return s.live && asksOnline(p.game, s.online) ? [fresh, [checkOnline((online) => ({
4598
+ _tag: "OnlineChecked",
4599
+ online
4600
+ }))]] : fresh;
4601
+ }
4602
+ },
4603
+ view: (s, _i, { props: { game } }) => compiled(_gyral$t71, [
4604
+ s.phase._tag,
4605
+ mainView(s, game),
4606
+ s.polite,
4607
+ s.assertive
4608
+ ]),
4609
+ styles
4610
+ });
4611
+ //#endregion
4612
+ export { Launcher, freshState, isSafePoint, stageLoader };
4613
+
4614
+ //# sourceMappingURL=launcher.js.map