@rohal12/spindle 0.59.14 → 0.59.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/pkg/format.js +1 -1
- package/dist/pkg/headless.js +814 -321
- package/dist/pkg/story-variables.js +349 -152
- package/package.json +1 -1
- package/src/class-registry.ts +105 -35
- package/src/components/Passage.tsx +21 -13
- package/src/components/PassageDialog.tsx +12 -2
- package/src/components/macros/For.tsx +16 -9
- package/src/components/macros/Radiobutton.tsx +4 -1
- package/src/components/macros/Watch.tsx +24 -4
- package/src/components/macros/detached-body.tsx +17 -6
- package/src/define-macro.ts +11 -2
- package/src/execute-mutation.ts +3 -2
- package/src/markup/render.tsx +17 -1
- package/src/markup/spindle.peggy +16 -0
- package/src/runtime-errors.ts +4 -8
- package/src/saves/save-manager.ts +63 -0
- package/src/store.ts +54 -10
- package/src/story-api.ts +4 -3
- package/src/story-variables.ts +15 -3
- package/src/structural.ts +74 -38
- package/src/triggers.ts +23 -2
- package/src/utils/control-edits.ts +81 -30
- package/src/utils/listeners.ts +23 -0
- package/src/utils/object-path.ts +18 -6
- package/src/utils/stable-key.ts +73 -40
- package/src/utils/value-kinds.ts +42 -0
- package/types/index.d.ts +7 -2
- package/types/tooling.d.ts +5 -1
package/dist/pkg/headless.js
CHANGED
|
@@ -124,6 +124,11 @@ var LINK_SEPARATORS = [
|
|
|
124
124
|
];
|
|
125
125
|
var NO_SELECTORS = {};
|
|
126
126
|
/**
|
|
127
|
+
* A CommonMark email autolink, `<` an address `>` (without braces, which
|
|
128
|
+
* are markup), as markdown reads one.
|
|
129
|
+
*/
|
|
130
|
+
var EMAIL_AUTOLINK = /^<[a-zA-Z0-9.!#$%&'*+/=?^_`|~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*>$/;
|
|
131
|
+
/**
|
|
127
132
|
* A link's display text and target, from its text `inner` (at `at` in the
|
|
128
133
|
* input), with where the target is written.
|
|
129
134
|
*/
|
|
@@ -401,10 +406,11 @@ function peg$parse(input, options) {
|
|
|
401
406
|
const peg$c10 = " ";
|
|
402
407
|
const peg$c11 = "}";
|
|
403
408
|
const peg$c12 = "/";
|
|
404
|
-
const peg$c13 = "
|
|
405
|
-
const peg$c14 = "
|
|
406
|
-
const peg$c15 = "
|
|
407
|
-
const peg$c16 = "
|
|
409
|
+
const peg$c13 = "@";
|
|
410
|
+
const peg$c14 = "</";
|
|
411
|
+
const peg$c15 = "=";
|
|
412
|
+
const peg$c16 = "\"";
|
|
413
|
+
const peg$c17 = "'";
|
|
408
414
|
const peg$r0 = /^[^\\{[<]/;
|
|
409
415
|
const peg$r1 = /^[{}]/;
|
|
410
416
|
const peg$r2 = /^[$_@%(!\/a-zA-Z]/;
|
|
@@ -415,14 +421,16 @@ function peg$parse(input, options) {
|
|
|
415
421
|
const peg$r7 = /^[$_@%(!]/;
|
|
416
422
|
const peg$r8 = /^[a-zA-Z]/;
|
|
417
423
|
const peg$r9 = /^[^ \t\n\r\v\f\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF}]/;
|
|
418
|
-
const peg$r10 = /^[
|
|
419
|
-
const peg$r11 = /^[a-zA-Z0-9
|
|
420
|
-
const peg$r12 = /^[\t-\r
|
|
421
|
-
const peg$r13 = /^[
|
|
422
|
-
const peg$r14 = /^[
|
|
423
|
-
const peg$r15 = /^["
|
|
424
|
-
const peg$r16 = /^[^
|
|
425
|
-
const peg$r17 = /^[
|
|
424
|
+
const peg$r10 = /^[a-zA-Z0-9.!#$%&'*+\/=?\^_`|~\-]/;
|
|
425
|
+
const peg$r11 = /^[a-zA-Z0-9.\-]/;
|
|
426
|
+
const peg$r12 = /^[\t-\r \/>\xA0\u1680\u2000-\u200A\u2028-\u2029\u202F\u205F\u3000\uFEFF]/;
|
|
427
|
+
const peg$r13 = /^[a-zA-Z0-9\-]/;
|
|
428
|
+
const peg$r14 = /^[\t-\r "'\/<->{}\xA0\u1680\u2000-\u200A\u2028-\u2029\u202F\u205F\u3000\uFEFF]/;
|
|
429
|
+
const peg$r15 = /^[^"]/;
|
|
430
|
+
const peg$r16 = /^[^']/;
|
|
431
|
+
const peg$r17 = /^["']/;
|
|
432
|
+
const peg$r18 = /^[^ \t\n\r\v\f\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF>]/;
|
|
433
|
+
const peg$r19 = /^[ \t\n\r\v\f\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]/;
|
|
426
434
|
const peg$e0 = peg$anyExpectation();
|
|
427
435
|
const peg$e1 = peg$classExpectation([
|
|
428
436
|
"\\",
|
|
@@ -504,6 +512,37 @@ function peg$parse(input, options) {
|
|
|
504
512
|
"}"
|
|
505
513
|
], true, false, false);
|
|
506
514
|
const peg$e24 = peg$classExpectation([
|
|
515
|
+
["a", "z"],
|
|
516
|
+
["A", "Z"],
|
|
517
|
+
["0", "9"],
|
|
518
|
+
".",
|
|
519
|
+
"!",
|
|
520
|
+
"#",
|
|
521
|
+
"$",
|
|
522
|
+
"%",
|
|
523
|
+
"&",
|
|
524
|
+
"'",
|
|
525
|
+
"*",
|
|
526
|
+
"+",
|
|
527
|
+
"/",
|
|
528
|
+
"=",
|
|
529
|
+
"?",
|
|
530
|
+
"^",
|
|
531
|
+
"_",
|
|
532
|
+
"`",
|
|
533
|
+
"|",
|
|
534
|
+
"~",
|
|
535
|
+
"-"
|
|
536
|
+
], false, false, false);
|
|
537
|
+
const peg$e25 = peg$literalExpectation("@", false);
|
|
538
|
+
const peg$e26 = peg$classExpectation([
|
|
539
|
+
["a", "z"],
|
|
540
|
+
["A", "Z"],
|
|
541
|
+
["0", "9"],
|
|
542
|
+
".",
|
|
543
|
+
"-"
|
|
544
|
+
], false, false, false);
|
|
545
|
+
const peg$e27 = peg$classExpectation([
|
|
507
546
|
[" ", "\r"],
|
|
508
547
|
" ",
|
|
509
548
|
"/",
|
|
@@ -517,14 +556,14 @@ function peg$parse(input, options) {
|
|
|
517
556
|
" ",
|
|
518
557
|
""
|
|
519
558
|
], false, false, false);
|
|
520
|
-
const peg$
|
|
521
|
-
const peg$
|
|
559
|
+
const peg$e28 = peg$literalExpectation("</", false);
|
|
560
|
+
const peg$e29 = peg$classExpectation([
|
|
522
561
|
["a", "z"],
|
|
523
562
|
["A", "Z"],
|
|
524
563
|
["0", "9"],
|
|
525
564
|
"-"
|
|
526
565
|
], false, false, false);
|
|
527
|
-
const peg$
|
|
566
|
+
const peg$e30 = peg$classExpectation([
|
|
528
567
|
[" ", "\r"],
|
|
529
568
|
" ",
|
|
530
569
|
"\"",
|
|
@@ -542,13 +581,13 @@ function peg$parse(input, options) {
|
|
|
542
581
|
" ",
|
|
543
582
|
""
|
|
544
583
|
], false, false, false);
|
|
545
|
-
const peg$
|
|
546
|
-
const peg$
|
|
547
|
-
const peg$
|
|
548
|
-
const peg$
|
|
549
|
-
const peg$
|
|
550
|
-
const peg$
|
|
551
|
-
const peg$
|
|
584
|
+
const peg$e31 = peg$literalExpectation("=", false);
|
|
585
|
+
const peg$e32 = peg$literalExpectation("\"", false);
|
|
586
|
+
const peg$e33 = peg$classExpectation(["\""], true, false, false);
|
|
587
|
+
const peg$e34 = peg$literalExpectation("'", false);
|
|
588
|
+
const peg$e35 = peg$classExpectation(["'"], true, false, false);
|
|
589
|
+
const peg$e36 = peg$classExpectation(["\"", "'"], false, false, false);
|
|
590
|
+
const peg$e37 = peg$classExpectation([
|
|
552
591
|
" ",
|
|
553
592
|
" ",
|
|
554
593
|
"\n",
|
|
@@ -566,7 +605,7 @@ function peg$parse(input, options) {
|
|
|
566
605
|
"",
|
|
567
606
|
">"
|
|
568
607
|
], true, false, false);
|
|
569
|
-
const peg$
|
|
608
|
+
const peg$e38 = peg$classExpectation([
|
|
570
609
|
" ",
|
|
571
610
|
" ",
|
|
572
611
|
"\n",
|
|
@@ -859,16 +898,22 @@ function peg$parse(input, options) {
|
|
|
859
898
|
function peg$f67(s) {
|
|
860
899
|
fail("A closing tag starts with a letter after " + LB + "/", location());
|
|
861
900
|
}
|
|
862
|
-
function peg$f68() {
|
|
901
|
+
function peg$f68(value) {
|
|
902
|
+
return EMAIL_AUTOLINK.test(value);
|
|
903
|
+
}
|
|
904
|
+
function peg$f69(value) {
|
|
905
|
+
return lexeme("text", location(), { value });
|
|
906
|
+
}
|
|
907
|
+
function peg$f70() {
|
|
863
908
|
return !textMode;
|
|
864
909
|
}
|
|
865
|
-
function peg$
|
|
910
|
+
function peg$f71(tag) {
|
|
866
911
|
return VOID_TAGS.has(tag.lower);
|
|
867
912
|
}
|
|
868
|
-
function peg$
|
|
913
|
+
function peg$f72(tag) {
|
|
869
914
|
return null;
|
|
870
915
|
}
|
|
871
|
-
function peg$
|
|
916
|
+
function peg$f73(tag, list, slash) {
|
|
872
917
|
const lower = tag.toLowerCase();
|
|
873
918
|
return lexeme("html", location(), {
|
|
874
919
|
tag,
|
|
@@ -878,7 +923,7 @@ function peg$parse(input, options) {
|
|
|
878
923
|
isSelfClose: !!slash || VOID_TAGS.has(lower)
|
|
879
924
|
});
|
|
880
925
|
}
|
|
881
|
-
function peg$
|
|
926
|
+
function peg$f74(tag, bad) {
|
|
882
927
|
const c = input.charAt(bad);
|
|
883
928
|
if (!c) fail("Unclosed tag <" + tag + ": no > ends it (write < for a < that starts no tag)", location());
|
|
884
929
|
const at = {
|
|
@@ -896,7 +941,7 @@ function peg$parse(input, options) {
|
|
|
896
941
|
};
|
|
897
942
|
fail("Unexpected " + JSON.stringify(c) + " in the tag <" + tag + ">: expected an attribute, or > to end the tag", at);
|
|
898
943
|
}
|
|
899
|
-
function peg$
|
|
944
|
+
function peg$f75(tag) {
|
|
900
945
|
return lexeme("html", location(), {
|
|
901
946
|
tag,
|
|
902
947
|
lower: tag.toLowerCase(),
|
|
@@ -905,44 +950,44 @@ function peg$parse(input, options) {
|
|
|
905
950
|
isSelfClose: false
|
|
906
951
|
});
|
|
907
952
|
}
|
|
908
|
-
function peg$
|
|
953
|
+
function peg$f76(name) {
|
|
909
954
|
attrCode = hooks.isCodeAttribute(name);
|
|
910
955
|
return true;
|
|
911
956
|
}
|
|
912
|
-
function peg$
|
|
957
|
+
function peg$f77(name, v) {
|
|
913
958
|
return v;
|
|
914
959
|
}
|
|
915
|
-
function peg$
|
|
960
|
+
function peg$f78(name, value) {
|
|
916
961
|
return [name, value ?? ""];
|
|
917
962
|
}
|
|
918
|
-
function peg$
|
|
963
|
+
function peg$f79(v) {
|
|
919
964
|
return v;
|
|
920
965
|
}
|
|
921
|
-
function peg$
|
|
966
|
+
function peg$f80(v) {
|
|
922
967
|
return v;
|
|
923
968
|
}
|
|
924
|
-
function peg$
|
|
969
|
+
function peg$f81(q) {
|
|
925
970
|
fail("Unclosed attribute value: the " + q + " here has no closing " + q, location());
|
|
926
971
|
}
|
|
927
|
-
function peg$
|
|
972
|
+
function peg$f82() {
|
|
928
973
|
return !attrCode;
|
|
929
974
|
}
|
|
930
|
-
function peg$
|
|
975
|
+
function peg$f83(bs) {
|
|
931
976
|
return bs.length % 2 === 1;
|
|
932
977
|
}
|
|
933
|
-
function peg$
|
|
978
|
+
function peg$f84() {
|
|
934
979
|
return !attrCode;
|
|
935
980
|
}
|
|
936
|
-
function peg$
|
|
981
|
+
function peg$f85(start, nameEnd) {
|
|
937
982
|
return skipTo(hooks.closeBrace(input, nameEnd, start));
|
|
938
983
|
}
|
|
939
|
-
function peg$
|
|
984
|
+
function peg$f86(start, nameEnd) {
|
|
940
985
|
return skipEnd - offset();
|
|
941
986
|
}
|
|
942
|
-
function peg$
|
|
987
|
+
function peg$f87() {
|
|
943
988
|
return !attrCode;
|
|
944
989
|
}
|
|
945
|
-
function peg$
|
|
990
|
+
function peg$f88() {
|
|
946
991
|
return attrCode;
|
|
947
992
|
}
|
|
948
993
|
let peg$currPos = options.peg$currPos | 0;
|
|
@@ -1133,14 +1178,17 @@ function peg$parse(input, options) {
|
|
|
1133
1178
|
if (s0 === peg$FAILED) {
|
|
1134
1179
|
s0 = peg$parseLinkLexeme();
|
|
1135
1180
|
if (s0 === peg$FAILED) {
|
|
1136
|
-
s0 = peg$
|
|
1181
|
+
s0 = peg$parseEmailAutolink();
|
|
1137
1182
|
if (s0 === peg$FAILED) {
|
|
1138
|
-
s0 = peg$
|
|
1183
|
+
s0 = peg$parseHtmlElement();
|
|
1139
1184
|
if (s0 === peg$FAILED) {
|
|
1140
|
-
s0 = peg$
|
|
1185
|
+
s0 = peg$parseVoidCloser();
|
|
1141
1186
|
if (s0 === peg$FAILED) {
|
|
1142
|
-
s0 = peg$
|
|
1143
|
-
if (s0 === peg$FAILED)
|
|
1187
|
+
s0 = peg$parseValue();
|
|
1188
|
+
if (s0 === peg$FAILED) {
|
|
1189
|
+
s0 = peg$parseMacroElement();
|
|
1190
|
+
if (s0 === peg$FAILED) s0 = peg$parseLiteral();
|
|
1191
|
+
}
|
|
1144
1192
|
}
|
|
1145
1193
|
}
|
|
1146
1194
|
}
|
|
@@ -1488,35 +1536,18 @@ function peg$parse(input, options) {
|
|
|
1488
1536
|
if (s0 === peg$FAILED) {
|
|
1489
1537
|
s0 = peg$parseLinkLexeme();
|
|
1490
1538
|
if (s0 === peg$FAILED) {
|
|
1491
|
-
s0 = peg$
|
|
1492
|
-
peg$savedPos = peg$currPos;
|
|
1493
|
-
s1 = peg$f29();
|
|
1494
|
-
if (s1) s1 = void 0;
|
|
1495
|
-
else s1 = peg$FAILED;
|
|
1496
|
-
if (s1 !== peg$FAILED) {
|
|
1497
|
-
s2 = peg$parseHtmlOpen();
|
|
1498
|
-
if (s2 !== peg$FAILED) {
|
|
1499
|
-
peg$savedPos = s0;
|
|
1500
|
-
s0 = peg$f30(s2);
|
|
1501
|
-
} else {
|
|
1502
|
-
peg$currPos = s0;
|
|
1503
|
-
s0 = peg$FAILED;
|
|
1504
|
-
}
|
|
1505
|
-
} else {
|
|
1506
|
-
peg$currPos = s0;
|
|
1507
|
-
s0 = peg$FAILED;
|
|
1508
|
-
}
|
|
1539
|
+
s0 = peg$parseEmailAutolink();
|
|
1509
1540
|
if (s0 === peg$FAILED) {
|
|
1510
1541
|
s0 = peg$currPos;
|
|
1511
1542
|
peg$savedPos = peg$currPos;
|
|
1512
|
-
s1 = peg$
|
|
1543
|
+
s1 = peg$f29();
|
|
1513
1544
|
if (s1) s1 = void 0;
|
|
1514
1545
|
else s1 = peg$FAILED;
|
|
1515
1546
|
if (s1 !== peg$FAILED) {
|
|
1516
|
-
s2 = peg$
|
|
1547
|
+
s2 = peg$parseHtmlOpen();
|
|
1517
1548
|
if (s2 !== peg$FAILED) {
|
|
1518
1549
|
peg$savedPos = s0;
|
|
1519
|
-
s0 = peg$
|
|
1550
|
+
s0 = peg$f30(s2);
|
|
1520
1551
|
} else {
|
|
1521
1552
|
peg$currPos = s0;
|
|
1522
1553
|
s0 = peg$FAILED;
|
|
@@ -1526,37 +1557,57 @@ function peg$parse(input, options) {
|
|
|
1526
1557
|
s0 = peg$FAILED;
|
|
1527
1558
|
}
|
|
1528
1559
|
if (s0 === peg$FAILED) {
|
|
1529
|
-
s0 = peg$
|
|
1560
|
+
s0 = peg$currPos;
|
|
1561
|
+
peg$savedPos = peg$currPos;
|
|
1562
|
+
s1 = peg$f31();
|
|
1563
|
+
if (s1) s1 = void 0;
|
|
1564
|
+
else s1 = peg$FAILED;
|
|
1565
|
+
if (s1 !== peg$FAILED) {
|
|
1566
|
+
s2 = peg$parseHtmlClose();
|
|
1567
|
+
if (s2 !== peg$FAILED) {
|
|
1568
|
+
peg$savedPos = s0;
|
|
1569
|
+
s0 = peg$f32(s2);
|
|
1570
|
+
} else {
|
|
1571
|
+
peg$currPos = s0;
|
|
1572
|
+
s0 = peg$FAILED;
|
|
1573
|
+
}
|
|
1574
|
+
} else {
|
|
1575
|
+
peg$currPos = s0;
|
|
1576
|
+
s0 = peg$FAILED;
|
|
1577
|
+
}
|
|
1530
1578
|
if (s0 === peg$FAILED) {
|
|
1531
|
-
s0 = peg$
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
if (
|
|
1542
|
-
|
|
1543
|
-
|
|
1579
|
+
s0 = peg$parseValue();
|
|
1580
|
+
if (s0 === peg$FAILED) {
|
|
1581
|
+
s0 = peg$currPos;
|
|
1582
|
+
s1 = peg$parseMacroTag();
|
|
1583
|
+
if (s1 !== peg$FAILED) {
|
|
1584
|
+
s2 = peg$currPos;
|
|
1585
|
+
peg$savedPos = peg$currPos;
|
|
1586
|
+
s3 = peg$f33(s1);
|
|
1587
|
+
if (s3) s3 = void 0;
|
|
1588
|
+
else s3 = peg$FAILED;
|
|
1589
|
+
if (s3 !== peg$FAILED) {
|
|
1590
|
+
s4 = peg$parseRawTokens();
|
|
1591
|
+
if (s4 !== peg$FAILED) {
|
|
1592
|
+
peg$savedPos = s2;
|
|
1593
|
+
s2 = peg$f34(s1, s4);
|
|
1594
|
+
} else {
|
|
1595
|
+
peg$currPos = s2;
|
|
1596
|
+
s2 = peg$FAILED;
|
|
1597
|
+
}
|
|
1544
1598
|
} else {
|
|
1545
1599
|
peg$currPos = s2;
|
|
1546
1600
|
s2 = peg$FAILED;
|
|
1547
1601
|
}
|
|
1602
|
+
if (s2 === peg$FAILED) s2 = null;
|
|
1603
|
+
peg$savedPos = s0;
|
|
1604
|
+
s0 = peg$f35(s1, s2);
|
|
1548
1605
|
} else {
|
|
1549
|
-
peg$currPos =
|
|
1550
|
-
|
|
1606
|
+
peg$currPos = s0;
|
|
1607
|
+
s0 = peg$FAILED;
|
|
1551
1608
|
}
|
|
1552
|
-
if (
|
|
1553
|
-
peg$savedPos = s0;
|
|
1554
|
-
s0 = peg$f35(s1, s2);
|
|
1555
|
-
} else {
|
|
1556
|
-
peg$currPos = s0;
|
|
1557
|
-
s0 = peg$FAILED;
|
|
1609
|
+
if (s0 === peg$FAILED) s0 = peg$parseLiteral();
|
|
1558
1610
|
}
|
|
1559
|
-
if (s0 === peg$FAILED) s0 = peg$parseLiteral();
|
|
1560
1611
|
}
|
|
1561
1612
|
}
|
|
1562
1613
|
}
|
|
@@ -2698,23 +2749,136 @@ function peg$parse(input, options) {
|
|
|
2698
2749
|
else s0 = s1;
|
|
2699
2750
|
return s0;
|
|
2700
2751
|
}
|
|
2752
|
+
function peg$parseEmailAutolink() {
|
|
2753
|
+
let s0, s1, s2, s3, s4, s5, s6, s7;
|
|
2754
|
+
s0 = peg$currPos;
|
|
2755
|
+
s1 = peg$currPos;
|
|
2756
|
+
s2 = peg$currPos;
|
|
2757
|
+
if (input.charCodeAt(peg$currPos) === 60) {
|
|
2758
|
+
s3 = peg$c6;
|
|
2759
|
+
peg$currPos++;
|
|
2760
|
+
} else {
|
|
2761
|
+
s3 = peg$FAILED;
|
|
2762
|
+
if (peg$silentFails === 0) peg$fail(peg$e10);
|
|
2763
|
+
}
|
|
2764
|
+
if (s3 !== peg$FAILED) {
|
|
2765
|
+
s4 = [];
|
|
2766
|
+
s5 = input.charAt(peg$currPos);
|
|
2767
|
+
if (peg$r10.test(s5)) peg$currPos++;
|
|
2768
|
+
else {
|
|
2769
|
+
s5 = peg$FAILED;
|
|
2770
|
+
if (peg$silentFails === 0) peg$fail(peg$e24);
|
|
2771
|
+
}
|
|
2772
|
+
if (s5 !== peg$FAILED) while (s5 !== peg$FAILED) {
|
|
2773
|
+
s4.push(s5);
|
|
2774
|
+
s5 = input.charAt(peg$currPos);
|
|
2775
|
+
if (peg$r10.test(s5)) peg$currPos++;
|
|
2776
|
+
else {
|
|
2777
|
+
s5 = peg$FAILED;
|
|
2778
|
+
if (peg$silentFails === 0) peg$fail(peg$e24);
|
|
2779
|
+
}
|
|
2780
|
+
}
|
|
2781
|
+
else s4 = peg$FAILED;
|
|
2782
|
+
if (s4 !== peg$FAILED) {
|
|
2783
|
+
if (input.charCodeAt(peg$currPos) === 64) {
|
|
2784
|
+
s5 = peg$c13;
|
|
2785
|
+
peg$currPos++;
|
|
2786
|
+
} else {
|
|
2787
|
+
s5 = peg$FAILED;
|
|
2788
|
+
if (peg$silentFails === 0) peg$fail(peg$e25);
|
|
2789
|
+
}
|
|
2790
|
+
if (s5 !== peg$FAILED) {
|
|
2791
|
+
s6 = [];
|
|
2792
|
+
s7 = input.charAt(peg$currPos);
|
|
2793
|
+
if (peg$r11.test(s7)) peg$currPos++;
|
|
2794
|
+
else {
|
|
2795
|
+
s7 = peg$FAILED;
|
|
2796
|
+
if (peg$silentFails === 0) peg$fail(peg$e26);
|
|
2797
|
+
}
|
|
2798
|
+
if (s7 !== peg$FAILED) while (s7 !== peg$FAILED) {
|
|
2799
|
+
s6.push(s7);
|
|
2800
|
+
s7 = input.charAt(peg$currPos);
|
|
2801
|
+
if (peg$r11.test(s7)) peg$currPos++;
|
|
2802
|
+
else {
|
|
2803
|
+
s7 = peg$FAILED;
|
|
2804
|
+
if (peg$silentFails === 0) peg$fail(peg$e26);
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2807
|
+
else s6 = peg$FAILED;
|
|
2808
|
+
if (s6 !== peg$FAILED) {
|
|
2809
|
+
if (input.charCodeAt(peg$currPos) === 62) {
|
|
2810
|
+
s7 = peg$c1;
|
|
2811
|
+
peg$currPos++;
|
|
2812
|
+
} else {
|
|
2813
|
+
s7 = peg$FAILED;
|
|
2814
|
+
if (peg$silentFails === 0) peg$fail(peg$e3);
|
|
2815
|
+
}
|
|
2816
|
+
if (s7 !== peg$FAILED) {
|
|
2817
|
+
s3 = [
|
|
2818
|
+
s3,
|
|
2819
|
+
s4,
|
|
2820
|
+
s5,
|
|
2821
|
+
s6,
|
|
2822
|
+
s7
|
|
2823
|
+
];
|
|
2824
|
+
s2 = s3;
|
|
2825
|
+
} else {
|
|
2826
|
+
peg$currPos = s2;
|
|
2827
|
+
s2 = peg$FAILED;
|
|
2828
|
+
}
|
|
2829
|
+
} else {
|
|
2830
|
+
peg$currPos = s2;
|
|
2831
|
+
s2 = peg$FAILED;
|
|
2832
|
+
}
|
|
2833
|
+
} else {
|
|
2834
|
+
peg$currPos = s2;
|
|
2835
|
+
s2 = peg$FAILED;
|
|
2836
|
+
}
|
|
2837
|
+
} else {
|
|
2838
|
+
peg$currPos = s2;
|
|
2839
|
+
s2 = peg$FAILED;
|
|
2840
|
+
}
|
|
2841
|
+
} else {
|
|
2842
|
+
peg$currPos = s2;
|
|
2843
|
+
s2 = peg$FAILED;
|
|
2844
|
+
}
|
|
2845
|
+
if (s2 !== peg$FAILED) s1 = input.substring(s1, peg$currPos);
|
|
2846
|
+
else s1 = s2;
|
|
2847
|
+
if (s1 !== peg$FAILED) {
|
|
2848
|
+
peg$savedPos = peg$currPos;
|
|
2849
|
+
s2 = peg$f68(s1);
|
|
2850
|
+
if (s2) s2 = void 0;
|
|
2851
|
+
else s2 = peg$FAILED;
|
|
2852
|
+
if (s2 !== peg$FAILED) {
|
|
2853
|
+
peg$savedPos = s0;
|
|
2854
|
+
s0 = peg$f69(s1);
|
|
2855
|
+
} else {
|
|
2856
|
+
peg$currPos = s0;
|
|
2857
|
+
s0 = peg$FAILED;
|
|
2858
|
+
}
|
|
2859
|
+
} else {
|
|
2860
|
+
peg$currPos = s0;
|
|
2861
|
+
s0 = peg$FAILED;
|
|
2862
|
+
}
|
|
2863
|
+
return s0;
|
|
2864
|
+
}
|
|
2701
2865
|
function peg$parseVoidCloser() {
|
|
2702
2866
|
let s0, s1, s2, s3;
|
|
2703
2867
|
s0 = peg$currPos;
|
|
2704
2868
|
peg$savedPos = peg$currPos;
|
|
2705
|
-
s1 = peg$
|
|
2869
|
+
s1 = peg$f70();
|
|
2706
2870
|
if (s1) s1 = void 0;
|
|
2707
2871
|
else s1 = peg$FAILED;
|
|
2708
2872
|
if (s1 !== peg$FAILED) {
|
|
2709
2873
|
s2 = peg$parseHtmlClose();
|
|
2710
2874
|
if (s2 !== peg$FAILED) {
|
|
2711
2875
|
peg$savedPos = peg$currPos;
|
|
2712
|
-
s3 = peg$
|
|
2876
|
+
s3 = peg$f71(s2);
|
|
2713
2877
|
if (s3) s3 = void 0;
|
|
2714
2878
|
else s3 = peg$FAILED;
|
|
2715
2879
|
if (s3 !== peg$FAILED) {
|
|
2716
2880
|
peg$savedPos = s0;
|
|
2717
|
-
s0 = peg$
|
|
2881
|
+
s0 = peg$f72(s2);
|
|
2718
2882
|
} else {
|
|
2719
2883
|
peg$currPos = s0;
|
|
2720
2884
|
s0 = peg$FAILED;
|
|
@@ -2766,7 +2930,7 @@ function peg$parse(input, options) {
|
|
|
2766
2930
|
}
|
|
2767
2931
|
if (s6 !== peg$FAILED) {
|
|
2768
2932
|
peg$savedPos = s0;
|
|
2769
|
-
s0 = peg$
|
|
2933
|
+
s0 = peg$f73(s2, s3, s5);
|
|
2770
2934
|
} else {
|
|
2771
2935
|
peg$currPos = s0;
|
|
2772
2936
|
s0 = peg$FAILED;
|
|
@@ -2794,10 +2958,10 @@ function peg$parse(input, options) {
|
|
|
2794
2958
|
s3 = peg$currPos;
|
|
2795
2959
|
peg$silentFails++;
|
|
2796
2960
|
s4 = input.charAt(peg$currPos);
|
|
2797
|
-
if (peg$
|
|
2961
|
+
if (peg$r12.test(s4)) peg$currPos++;
|
|
2798
2962
|
else {
|
|
2799
2963
|
s4 = peg$FAILED;
|
|
2800
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
2964
|
+
if (peg$silentFails === 0) peg$fail(peg$e27);
|
|
2801
2965
|
}
|
|
2802
2966
|
if (s4 === peg$FAILED) {
|
|
2803
2967
|
s4 = peg$currPos;
|
|
@@ -2831,7 +2995,7 @@ function peg$parse(input, options) {
|
|
|
2831
2995
|
s5 = peg$parse_();
|
|
2832
2996
|
s6 = peg$parseHere();
|
|
2833
2997
|
peg$savedPos = s0;
|
|
2834
|
-
s0 = peg$
|
|
2998
|
+
s0 = peg$f74(s2, s6);
|
|
2835
2999
|
} else {
|
|
2836
3000
|
peg$currPos = s0;
|
|
2837
3001
|
s0 = peg$FAILED;
|
|
@@ -2850,12 +3014,12 @@ function peg$parse(input, options) {
|
|
|
2850
3014
|
function peg$parseHtmlClose() {
|
|
2851
3015
|
let s0, s1, s2, s4;
|
|
2852
3016
|
s0 = peg$currPos;
|
|
2853
|
-
if (input.substr(peg$currPos, 2) === peg$
|
|
2854
|
-
s1 = peg$
|
|
3017
|
+
if (input.substr(peg$currPos, 2) === peg$c14) {
|
|
3018
|
+
s1 = peg$c14;
|
|
2855
3019
|
peg$currPos += 2;
|
|
2856
3020
|
} else {
|
|
2857
3021
|
s1 = peg$FAILED;
|
|
2858
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
3022
|
+
if (peg$silentFails === 0) peg$fail(peg$e28);
|
|
2859
3023
|
}
|
|
2860
3024
|
if (s1 !== peg$FAILED) {
|
|
2861
3025
|
s2 = peg$parseTagName();
|
|
@@ -2870,7 +3034,7 @@ function peg$parse(input, options) {
|
|
|
2870
3034
|
}
|
|
2871
3035
|
if (s4 !== peg$FAILED) {
|
|
2872
3036
|
peg$savedPos = s0;
|
|
2873
|
-
s0 = peg$
|
|
3037
|
+
s0 = peg$f75(s2);
|
|
2874
3038
|
} else {
|
|
2875
3039
|
peg$currPos = s0;
|
|
2876
3040
|
s0 = peg$FAILED;
|
|
@@ -2898,18 +3062,18 @@ function peg$parse(input, options) {
|
|
|
2898
3062
|
if (s2 !== peg$FAILED) {
|
|
2899
3063
|
s3 = [];
|
|
2900
3064
|
s4 = input.charAt(peg$currPos);
|
|
2901
|
-
if (peg$
|
|
3065
|
+
if (peg$r13.test(s4)) peg$currPos++;
|
|
2902
3066
|
else {
|
|
2903
3067
|
s4 = peg$FAILED;
|
|
2904
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
3068
|
+
if (peg$silentFails === 0) peg$fail(peg$e29);
|
|
2905
3069
|
}
|
|
2906
3070
|
while (s4 !== peg$FAILED) {
|
|
2907
3071
|
s3.push(s4);
|
|
2908
3072
|
s4 = input.charAt(peg$currPos);
|
|
2909
|
-
if (peg$
|
|
3073
|
+
if (peg$r13.test(s4)) peg$currPos++;
|
|
2910
3074
|
else {
|
|
2911
3075
|
s4 = peg$FAILED;
|
|
2912
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
3076
|
+
if (peg$silentFails === 0) peg$fail(peg$e29);
|
|
2913
3077
|
}
|
|
2914
3078
|
}
|
|
2915
3079
|
s2 = [s2, s3];
|
|
@@ -2932,10 +3096,10 @@ function peg$parse(input, options) {
|
|
|
2932
3096
|
s5 = peg$currPos;
|
|
2933
3097
|
peg$silentFails++;
|
|
2934
3098
|
s6 = input.charAt(peg$currPos);
|
|
2935
|
-
if (peg$
|
|
3099
|
+
if (peg$r14.test(s6)) peg$currPos++;
|
|
2936
3100
|
else {
|
|
2937
3101
|
s6 = peg$FAILED;
|
|
2938
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
3102
|
+
if (peg$silentFails === 0) peg$fail(peg$e30);
|
|
2939
3103
|
}
|
|
2940
3104
|
peg$silentFails--;
|
|
2941
3105
|
if (s6 === peg$FAILED) s5 = void 0;
|
|
@@ -2968,10 +3132,10 @@ function peg$parse(input, options) {
|
|
|
2968
3132
|
s5 = peg$currPos;
|
|
2969
3133
|
peg$silentFails++;
|
|
2970
3134
|
s6 = input.charAt(peg$currPos);
|
|
2971
|
-
if (peg$
|
|
3135
|
+
if (peg$r14.test(s6)) peg$currPos++;
|
|
2972
3136
|
else {
|
|
2973
3137
|
s6 = peg$FAILED;
|
|
2974
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
3138
|
+
if (peg$silentFails === 0) peg$fail(peg$e30);
|
|
2975
3139
|
}
|
|
2976
3140
|
peg$silentFails--;
|
|
2977
3141
|
if (s6 === peg$FAILED) s5 = void 0;
|
|
@@ -3004,25 +3168,25 @@ function peg$parse(input, options) {
|
|
|
3004
3168
|
else s2 = s3;
|
|
3005
3169
|
if (s2 !== peg$FAILED) {
|
|
3006
3170
|
peg$savedPos = peg$currPos;
|
|
3007
|
-
s3 = peg$
|
|
3171
|
+
s3 = peg$f76(s2);
|
|
3008
3172
|
if (s3) s3 = void 0;
|
|
3009
3173
|
else s3 = peg$FAILED;
|
|
3010
3174
|
if (s3 !== peg$FAILED) {
|
|
3011
3175
|
s4 = peg$currPos;
|
|
3012
3176
|
s5 = peg$parse_();
|
|
3013
3177
|
if (input.charCodeAt(peg$currPos) === 61) {
|
|
3014
|
-
s6 = peg$
|
|
3178
|
+
s6 = peg$c15;
|
|
3015
3179
|
peg$currPos++;
|
|
3016
3180
|
} else {
|
|
3017
3181
|
s6 = peg$FAILED;
|
|
3018
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
3182
|
+
if (peg$silentFails === 0) peg$fail(peg$e31);
|
|
3019
3183
|
}
|
|
3020
3184
|
if (s6 !== peg$FAILED) {
|
|
3021
3185
|
peg$parse_();
|
|
3022
3186
|
s8 = peg$parseAttrValue();
|
|
3023
3187
|
if (s8 !== peg$FAILED) {
|
|
3024
3188
|
peg$savedPos = s4;
|
|
3025
|
-
s4 = peg$
|
|
3189
|
+
s4 = peg$f77(s2, s8);
|
|
3026
3190
|
} else {
|
|
3027
3191
|
peg$currPos = s4;
|
|
3028
3192
|
s4 = peg$FAILED;
|
|
@@ -3033,7 +3197,7 @@ function peg$parse(input, options) {
|
|
|
3033
3197
|
}
|
|
3034
3198
|
if (s4 === peg$FAILED) s4 = null;
|
|
3035
3199
|
peg$savedPos = s0;
|
|
3036
|
-
s0 = peg$
|
|
3200
|
+
s0 = peg$f78(s2, s4);
|
|
3037
3201
|
} else {
|
|
3038
3202
|
peg$currPos = s0;
|
|
3039
3203
|
s0 = peg$FAILED;
|
|
@@ -3048,11 +3212,11 @@ function peg$parse(input, options) {
|
|
|
3048
3212
|
let s0, s1, s2, s3, s4;
|
|
3049
3213
|
s0 = peg$currPos;
|
|
3050
3214
|
if (input.charCodeAt(peg$currPos) === 34) {
|
|
3051
|
-
s1 = peg$
|
|
3215
|
+
s1 = peg$c16;
|
|
3052
3216
|
peg$currPos++;
|
|
3053
3217
|
} else {
|
|
3054
3218
|
s1 = peg$FAILED;
|
|
3055
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
3219
|
+
if (peg$silentFails === 0) peg$fail(peg$e32);
|
|
3056
3220
|
}
|
|
3057
3221
|
if (s1 !== peg$FAILED) {
|
|
3058
3222
|
s2 = peg$currPos;
|
|
@@ -3060,10 +3224,10 @@ function peg$parse(input, options) {
|
|
|
3060
3224
|
s4 = peg$parseValuePart();
|
|
3061
3225
|
if (s4 === peg$FAILED) {
|
|
3062
3226
|
s4 = input.charAt(peg$currPos);
|
|
3063
|
-
if (peg$
|
|
3227
|
+
if (peg$r15.test(s4)) peg$currPos++;
|
|
3064
3228
|
else {
|
|
3065
3229
|
s4 = peg$FAILED;
|
|
3066
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
3230
|
+
if (peg$silentFails === 0) peg$fail(peg$e33);
|
|
3067
3231
|
}
|
|
3068
3232
|
}
|
|
3069
3233
|
while (s4 !== peg$FAILED) {
|
|
@@ -3071,24 +3235,24 @@ function peg$parse(input, options) {
|
|
|
3071
3235
|
s4 = peg$parseValuePart();
|
|
3072
3236
|
if (s4 === peg$FAILED) {
|
|
3073
3237
|
s4 = input.charAt(peg$currPos);
|
|
3074
|
-
if (peg$
|
|
3238
|
+
if (peg$r15.test(s4)) peg$currPos++;
|
|
3075
3239
|
else {
|
|
3076
3240
|
s4 = peg$FAILED;
|
|
3077
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
3241
|
+
if (peg$silentFails === 0) peg$fail(peg$e33);
|
|
3078
3242
|
}
|
|
3079
3243
|
}
|
|
3080
3244
|
}
|
|
3081
3245
|
s2 = input.substring(s2, peg$currPos);
|
|
3082
3246
|
if (input.charCodeAt(peg$currPos) === 34) {
|
|
3083
|
-
s3 = peg$
|
|
3247
|
+
s3 = peg$c16;
|
|
3084
3248
|
peg$currPos++;
|
|
3085
3249
|
} else {
|
|
3086
3250
|
s3 = peg$FAILED;
|
|
3087
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
3251
|
+
if (peg$silentFails === 0) peg$fail(peg$e32);
|
|
3088
3252
|
}
|
|
3089
3253
|
if (s3 !== peg$FAILED) {
|
|
3090
3254
|
peg$savedPos = s0;
|
|
3091
|
-
s0 = peg$
|
|
3255
|
+
s0 = peg$f79(s2);
|
|
3092
3256
|
} else {
|
|
3093
3257
|
peg$currPos = s0;
|
|
3094
3258
|
s0 = peg$FAILED;
|
|
@@ -3100,11 +3264,11 @@ function peg$parse(input, options) {
|
|
|
3100
3264
|
if (s0 === peg$FAILED) {
|
|
3101
3265
|
s0 = peg$currPos;
|
|
3102
3266
|
if (input.charCodeAt(peg$currPos) === 39) {
|
|
3103
|
-
s1 = peg$
|
|
3267
|
+
s1 = peg$c17;
|
|
3104
3268
|
peg$currPos++;
|
|
3105
3269
|
} else {
|
|
3106
3270
|
s1 = peg$FAILED;
|
|
3107
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
3271
|
+
if (peg$silentFails === 0) peg$fail(peg$e34);
|
|
3108
3272
|
}
|
|
3109
3273
|
if (s1 !== peg$FAILED) {
|
|
3110
3274
|
s2 = peg$currPos;
|
|
@@ -3112,10 +3276,10 @@ function peg$parse(input, options) {
|
|
|
3112
3276
|
s4 = peg$parseValuePart();
|
|
3113
3277
|
if (s4 === peg$FAILED) {
|
|
3114
3278
|
s4 = input.charAt(peg$currPos);
|
|
3115
|
-
if (peg$
|
|
3279
|
+
if (peg$r16.test(s4)) peg$currPos++;
|
|
3116
3280
|
else {
|
|
3117
3281
|
s4 = peg$FAILED;
|
|
3118
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
3282
|
+
if (peg$silentFails === 0) peg$fail(peg$e35);
|
|
3119
3283
|
}
|
|
3120
3284
|
}
|
|
3121
3285
|
while (s4 !== peg$FAILED) {
|
|
@@ -3123,24 +3287,24 @@ function peg$parse(input, options) {
|
|
|
3123
3287
|
s4 = peg$parseValuePart();
|
|
3124
3288
|
if (s4 === peg$FAILED) {
|
|
3125
3289
|
s4 = input.charAt(peg$currPos);
|
|
3126
|
-
if (peg$
|
|
3290
|
+
if (peg$r16.test(s4)) peg$currPos++;
|
|
3127
3291
|
else {
|
|
3128
3292
|
s4 = peg$FAILED;
|
|
3129
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
3293
|
+
if (peg$silentFails === 0) peg$fail(peg$e35);
|
|
3130
3294
|
}
|
|
3131
3295
|
}
|
|
3132
3296
|
}
|
|
3133
3297
|
s2 = input.substring(s2, peg$currPos);
|
|
3134
3298
|
if (input.charCodeAt(peg$currPos) === 39) {
|
|
3135
|
-
s3 = peg$
|
|
3299
|
+
s3 = peg$c17;
|
|
3136
3300
|
peg$currPos++;
|
|
3137
3301
|
} else {
|
|
3138
3302
|
s3 = peg$FAILED;
|
|
3139
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
3303
|
+
if (peg$silentFails === 0) peg$fail(peg$e34);
|
|
3140
3304
|
}
|
|
3141
3305
|
if (s3 !== peg$FAILED) {
|
|
3142
3306
|
peg$savedPos = s0;
|
|
3143
|
-
s0 = peg$
|
|
3307
|
+
s0 = peg$f80(s2);
|
|
3144
3308
|
} else {
|
|
3145
3309
|
peg$currPos = s0;
|
|
3146
3310
|
s0 = peg$FAILED;
|
|
@@ -3152,32 +3316,32 @@ function peg$parse(input, options) {
|
|
|
3152
3316
|
if (s0 === peg$FAILED) {
|
|
3153
3317
|
s0 = peg$currPos;
|
|
3154
3318
|
s1 = input.charAt(peg$currPos);
|
|
3155
|
-
if (peg$
|
|
3319
|
+
if (peg$r17.test(s1)) peg$currPos++;
|
|
3156
3320
|
else {
|
|
3157
3321
|
s1 = peg$FAILED;
|
|
3158
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
3322
|
+
if (peg$silentFails === 0) peg$fail(peg$e36);
|
|
3159
3323
|
}
|
|
3160
3324
|
if (s1 !== peg$FAILED) {
|
|
3161
3325
|
peg$savedPos = s0;
|
|
3162
|
-
s1 = peg$
|
|
3326
|
+
s1 = peg$f81(s1);
|
|
3163
3327
|
}
|
|
3164
3328
|
s0 = s1;
|
|
3165
3329
|
if (s0 === peg$FAILED) {
|
|
3166
3330
|
s0 = peg$currPos;
|
|
3167
3331
|
s1 = [];
|
|
3168
3332
|
s2 = input.charAt(peg$currPos);
|
|
3169
|
-
if (peg$
|
|
3333
|
+
if (peg$r18.test(s2)) peg$currPos++;
|
|
3170
3334
|
else {
|
|
3171
3335
|
s2 = peg$FAILED;
|
|
3172
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
3336
|
+
if (peg$silentFails === 0) peg$fail(peg$e37);
|
|
3173
3337
|
}
|
|
3174
3338
|
while (s2 !== peg$FAILED) {
|
|
3175
3339
|
s1.push(s2);
|
|
3176
3340
|
s2 = input.charAt(peg$currPos);
|
|
3177
|
-
if (peg$
|
|
3341
|
+
if (peg$r18.test(s2)) peg$currPos++;
|
|
3178
3342
|
else {
|
|
3179
3343
|
s2 = peg$FAILED;
|
|
3180
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
3344
|
+
if (peg$silentFails === 0) peg$fail(peg$e37);
|
|
3181
3345
|
}
|
|
3182
3346
|
}
|
|
3183
3347
|
s0 = input.substring(s0, peg$currPos);
|
|
@@ -3190,7 +3354,7 @@ function peg$parse(input, options) {
|
|
|
3190
3354
|
let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13;
|
|
3191
3355
|
s0 = peg$currPos;
|
|
3192
3356
|
peg$savedPos = peg$currPos;
|
|
3193
|
-
s1 = peg$
|
|
3357
|
+
s1 = peg$f82();
|
|
3194
3358
|
if (s1) s1 = void 0;
|
|
3195
3359
|
else s1 = peg$FAILED;
|
|
3196
3360
|
if (s1 !== peg$FAILED) {
|
|
@@ -3219,7 +3383,7 @@ function peg$parse(input, options) {
|
|
|
3219
3383
|
if (s2 !== peg$FAILED) {
|
|
3220
3384
|
s3 = peg$currPos;
|
|
3221
3385
|
peg$savedPos = peg$currPos;
|
|
3222
|
-
s4 = peg$
|
|
3386
|
+
s4 = peg$f83(s2);
|
|
3223
3387
|
if (s4) s4 = void 0;
|
|
3224
3388
|
else s4 = peg$FAILED;
|
|
3225
3389
|
if (s4 !== peg$FAILED) {
|
|
@@ -3258,7 +3422,7 @@ function peg$parse(input, options) {
|
|
|
3258
3422
|
if (s0 === peg$FAILED) {
|
|
3259
3423
|
s0 = peg$currPos;
|
|
3260
3424
|
peg$savedPos = peg$currPos;
|
|
3261
|
-
s1 = peg$
|
|
3425
|
+
s1 = peg$f84();
|
|
3262
3426
|
if (s1) s1 = void 0;
|
|
3263
3427
|
else s1 = peg$FAILED;
|
|
3264
3428
|
if (s1 !== peg$FAILED) {
|
|
@@ -3285,12 +3449,12 @@ function peg$parse(input, options) {
|
|
|
3285
3449
|
if (s6 !== peg$FAILED) {
|
|
3286
3450
|
s7 = peg$parseHere();
|
|
3287
3451
|
peg$savedPos = peg$currPos;
|
|
3288
|
-
s8 = peg$
|
|
3452
|
+
s8 = peg$f85(s4, s7);
|
|
3289
3453
|
if (s8) s8 = void 0;
|
|
3290
3454
|
else s8 = peg$FAILED;
|
|
3291
3455
|
if (s8 !== peg$FAILED) {
|
|
3292
3456
|
s9 = peg$currPos;
|
|
3293
|
-
s10 = peg$
|
|
3457
|
+
s10 = peg$f86(s4, s7);
|
|
3294
3458
|
s11 = peg$currPos;
|
|
3295
3459
|
s12 = [];
|
|
3296
3460
|
if (s12.length >= (s10 | 0)) s13 = peg$FAILED;
|
|
@@ -3372,7 +3536,7 @@ function peg$parse(input, options) {
|
|
|
3372
3536
|
if (s0 === peg$FAILED) {
|
|
3373
3537
|
s0 = peg$currPos;
|
|
3374
3538
|
peg$savedPos = peg$currPos;
|
|
3375
|
-
s1 = peg$
|
|
3539
|
+
s1 = peg$f87();
|
|
3376
3540
|
if (s1) s1 = void 0;
|
|
3377
3541
|
else s1 = peg$FAILED;
|
|
3378
3542
|
if (s1 !== peg$FAILED) {
|
|
@@ -3463,7 +3627,7 @@ function peg$parse(input, options) {
|
|
|
3463
3627
|
if (s0 === peg$FAILED) {
|
|
3464
3628
|
s0 = peg$currPos;
|
|
3465
3629
|
peg$savedPos = peg$currPos;
|
|
3466
|
-
s1 = peg$
|
|
3630
|
+
s1 = peg$f88();
|
|
3467
3631
|
if (s1) s1 = void 0;
|
|
3468
3632
|
else s1 = peg$FAILED;
|
|
3469
3633
|
if (s1 !== peg$FAILED) {
|
|
@@ -3545,10 +3709,10 @@ function peg$parse(input, options) {
|
|
|
3545
3709
|
function peg$parse_c() {
|
|
3546
3710
|
let s0;
|
|
3547
3711
|
s0 = input.charAt(peg$currPos);
|
|
3548
|
-
if (peg$
|
|
3712
|
+
if (peg$r19.test(s0)) peg$currPos++;
|
|
3549
3713
|
else {
|
|
3550
3714
|
s0 = peg$FAILED;
|
|
3551
|
-
if (peg$silentFails === 0) peg$fail(peg$
|
|
3715
|
+
if (peg$silentFails === 0) peg$fail(peg$e38);
|
|
3552
3716
|
}
|
|
3553
3717
|
return s0;
|
|
3554
3718
|
}
|
|
@@ -10122,13 +10286,35 @@ function parseDelay(str) {
|
|
|
10122
10286
|
return parseFloat(trimmed);
|
|
10123
10287
|
}
|
|
10124
10288
|
//#endregion
|
|
10289
|
+
//#region src/utils/listeners.ts
|
|
10290
|
+
/**
|
|
10291
|
+
* A set of listeners to call when something happens: `subscribe` adds one and
|
|
10292
|
+
* returns the function that removes it, `notify` calls each one. A listener
|
|
10293
|
+
* removed or added while they are called is called or not as the set was
|
|
10294
|
+
* when `notify` started.
|
|
10295
|
+
*/
|
|
10296
|
+
function createListeners() {
|
|
10297
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
10298
|
+
return {
|
|
10299
|
+
subscribe(listener) {
|
|
10300
|
+
listeners.add(listener);
|
|
10301
|
+
return () => {
|
|
10302
|
+
listeners.delete(listener);
|
|
10303
|
+
};
|
|
10304
|
+
},
|
|
10305
|
+
notify() {
|
|
10306
|
+
for (const listener of [...listeners]) listener();
|
|
10307
|
+
}
|
|
10308
|
+
};
|
|
10309
|
+
}
|
|
10310
|
+
//#endregion
|
|
10125
10311
|
//#region src/runtime-errors.ts
|
|
10126
10312
|
var errors = [];
|
|
10127
10313
|
var nextId = 1;
|
|
10128
|
-
var listeners$1 =
|
|
10314
|
+
var listeners$1 = createListeners();
|
|
10129
10315
|
function update(next) {
|
|
10130
10316
|
errors = next;
|
|
10131
|
-
|
|
10317
|
+
listeners$1.notify();
|
|
10132
10318
|
}
|
|
10133
10319
|
/**
|
|
10134
10320
|
* Show `error` on the page, after `context` (what failed). The same error
|
|
@@ -10164,12 +10350,7 @@ function getRuntimeErrors() {
|
|
|
10164
10350
|
return errors;
|
|
10165
10351
|
}
|
|
10166
10352
|
/** Call `listener` whenever the shown errors change; returns unsubscribe. */
|
|
10167
|
-
|
|
10168
|
-
listeners$1.add(listener);
|
|
10169
|
-
return () => {
|
|
10170
|
-
listeners$1.delete(listener);
|
|
10171
|
-
};
|
|
10172
|
-
}
|
|
10353
|
+
var subscribeRuntimeErrors = listeners$1.subscribe;
|
|
10173
10354
|
//#endregion
|
|
10174
10355
|
//#region src/components/macros/arg-utils.ts
|
|
10175
10356
|
/**
|
|
@@ -10890,7 +11071,7 @@ function getPRNGPull() {
|
|
|
10890
11071
|
* (see src/tooling.ts).
|
|
10891
11072
|
*/
|
|
10892
11073
|
var TRANSFORM_CACHE_MAX = 500;
|
|
10893
|
-
var NAMESPACES$
|
|
11074
|
+
var NAMESPACES$2 = {
|
|
10894
11075
|
$: "variables",
|
|
10895
11076
|
_: "temporary",
|
|
10896
11077
|
"@": "locals",
|
|
@@ -10923,7 +11104,7 @@ function transform(expr, goal = "expression") {
|
|
|
10923
11104
|
result += expr.slice(at, ref.start);
|
|
10924
11105
|
if (ref.shorthand) result += `${ref.name}: `;
|
|
10925
11106
|
else if (IDENT_END_RE.test(result.slice(-2))) result += " ";
|
|
10926
|
-
result += `${NAMESPACES$
|
|
11107
|
+
result += `${NAMESPACES$2[ref.sigil]}["${ref.name}"]`;
|
|
10927
11108
|
at = ref.end;
|
|
10928
11109
|
}
|
|
10929
11110
|
result += expr.slice(at);
|
|
@@ -11890,6 +12071,19 @@ var InlineContext = createContext(false);
|
|
|
11890
12071
|
*/
|
|
11891
12072
|
var RawTextContext = createContext(false);
|
|
11892
12073
|
/**
|
|
12074
|
+
* The view content is rendered in: '' for the story interface, and an id of
|
|
12075
|
+
* its own for each passage and dialog on display (see useViewScope). The
|
|
12076
|
+
* radiobuttons of a variable form a native group within their view only:
|
|
12077
|
+
* one group across views would let a dialog's checked button uncheck the
|
|
12078
|
+
* passage's when it mounts (#396).
|
|
12079
|
+
*/
|
|
12080
|
+
var ViewScopeContext = createContext("");
|
|
12081
|
+
var viewScopes = 0;
|
|
12082
|
+
/** A new view scope (see ViewScopeContext), kept while mounted. */
|
|
12083
|
+
function useViewScope() {
|
|
12084
|
+
return useState(() => `v${++viewScopes}`)[0];
|
|
12085
|
+
}
|
|
12086
|
+
/**
|
|
11893
12087
|
* True inside an `<svg>` element. SVG attributes are case-sensitive and have
|
|
11894
12088
|
* no live form properties, so they are set as written (see splitAttributes).
|
|
11895
12089
|
*/
|
|
@@ -13323,11 +13517,60 @@ function extraKeys(collection) {
|
|
|
13323
13517
|
const keys = Object.keys(collection);
|
|
13324
13518
|
return Array.isArray(collection) ? keys.filter((k) => !isIndexKey(k)) : keys;
|
|
13325
13519
|
}
|
|
13520
|
+
/** The entries of a Map, as the built-in iterator gives them. */
|
|
13521
|
+
function mapEntries(map) {
|
|
13522
|
+
return isDraft(map) ? map.entries() : Map.prototype.entries.call(map);
|
|
13523
|
+
}
|
|
13524
|
+
/** The members of a Set, as the built-in iterator gives them. */
|
|
13525
|
+
function setMembers(set) {
|
|
13526
|
+
return isDraft(set) ? set.values() : Set.prototype.values.call(set);
|
|
13527
|
+
}
|
|
13528
|
+
/** The number of entries of a Map or members of a Set. */
|
|
13529
|
+
function collectionSize(collection) {
|
|
13530
|
+
if (isDraft(collection)) return collection.size;
|
|
13531
|
+
const proto = collection instanceof Map ? Map.prototype : Set.prototype;
|
|
13532
|
+
return Reflect.get(proto, "size", collection);
|
|
13533
|
+
}
|
|
13534
|
+
/** The value a Map holds for `key`. */
|
|
13535
|
+
function mapGet(map, key) {
|
|
13536
|
+
return isDraft(map) ? map.get(key) : Map.prototype.get.call(map, key);
|
|
13537
|
+
}
|
|
13538
|
+
/** Make a Map hold `value` for `key`. */
|
|
13539
|
+
function mapSet(map, key, value) {
|
|
13540
|
+
if (isDraft(map)) map.set(key, value);
|
|
13541
|
+
else Map.prototype.set.call(map, key, value);
|
|
13542
|
+
}
|
|
13326
13543
|
//#endregion
|
|
13327
13544
|
//#region src/class-registry.ts
|
|
13328
13545
|
var registry = /* @__PURE__ */ new Map();
|
|
13329
13546
|
var ctorToName = /* @__PURE__ */ new Map();
|
|
13547
|
+
/**
|
|
13548
|
+
* Built-ins whose instances hold their value in internal slots that a save
|
|
13549
|
+
* cannot rebuild: a registered class cannot extend them. (Array, Map, Set,
|
|
13550
|
+
* Date, RegExp and Error can be extended, see classData.)
|
|
13551
|
+
*/
|
|
13552
|
+
var UNSUPPORTED_BASES = [
|
|
13553
|
+
ArrayBuffer,
|
|
13554
|
+
DataView,
|
|
13555
|
+
Object.getPrototypeOf(Int8Array),
|
|
13556
|
+
URL,
|
|
13557
|
+
URLSearchParams,
|
|
13558
|
+
Number,
|
|
13559
|
+
String,
|
|
13560
|
+
Boolean,
|
|
13561
|
+
Promise,
|
|
13562
|
+
WeakMap,
|
|
13563
|
+
WeakSet,
|
|
13564
|
+
Function
|
|
13565
|
+
];
|
|
13566
|
+
/**
|
|
13567
|
+
* Register `ctor` as `name`, so that its instances keep their class through
|
|
13568
|
+
* copies, history and saves. Throws for a class extending a built-in whose
|
|
13569
|
+
* instances cannot be saved (see UNSUPPORTED_BASES).
|
|
13570
|
+
*/
|
|
13330
13571
|
function registerClass(name, ctor) {
|
|
13572
|
+
const base = typeof ctor === "function" ? UNSUPPORTED_BASES.find((b) => ctor.prototype instanceof b) : void 0;
|
|
13573
|
+
if (base) throw new TypeError(`spindle: Cannot register class "${name}": it extends ${base.name}, whose instances cannot be saved (a registered class may extend Array, Map, Set, Date, RegExp or Error)`);
|
|
13331
13574
|
registry.set(name, ctor);
|
|
13332
13575
|
ctorToName.set(ctor, name);
|
|
13333
13576
|
}
|
|
@@ -13394,16 +13637,22 @@ function ownData(value, keys = Object.keys(value)) {
|
|
|
13394
13637
|
for (const key of keys) defineData(data, key, value[key]);
|
|
13395
13638
|
return data;
|
|
13396
13639
|
}
|
|
13397
|
-
/**
|
|
13398
|
-
|
|
13640
|
+
/**
|
|
13641
|
+
* The built-ins a registered class may extend whose value is not in its
|
|
13642
|
+
* keys, saved as their kind (see classData).
|
|
13643
|
+
*/
|
|
13644
|
+
var BUILTIN_KINDS = {
|
|
13399
13645
|
Array,
|
|
13400
13646
|
Map,
|
|
13401
|
-
Set
|
|
13647
|
+
Set,
|
|
13648
|
+
Date,
|
|
13649
|
+
RegExp
|
|
13402
13650
|
};
|
|
13403
13651
|
/**
|
|
13404
13652
|
* The saved form of a registered class instance: its own data (see
|
|
13405
|
-
* ownData), or for a
|
|
13406
|
-
* with the built-in methods, which a
|
|
13653
|
+
* ownData), or for a subclass of a built-in kind (see BUILTIN_KINDS) its
|
|
13654
|
+
* kind, contents and extra keys, read with the built-in methods, which a
|
|
13655
|
+
* subclass may override (#391, #393).
|
|
13407
13656
|
*/
|
|
13408
13657
|
function classData(value) {
|
|
13409
13658
|
const extra = () => ownData(value, extraKeys(value));
|
|
@@ -13418,12 +13667,26 @@ function classData(value) {
|
|
|
13418
13667
|
}
|
|
13419
13668
|
if (value instanceof Map) return [
|
|
13420
13669
|
"Map",
|
|
13421
|
-
Array.from(
|
|
13670
|
+
Array.from(mapEntries(value)),
|
|
13422
13671
|
extra()
|
|
13423
13672
|
];
|
|
13424
13673
|
if (value instanceof Set) return [
|
|
13425
13674
|
"Set",
|
|
13426
|
-
Array.from(
|
|
13675
|
+
Array.from(setMembers(value)),
|
|
13676
|
+
extra()
|
|
13677
|
+
];
|
|
13678
|
+
if (value instanceof Date) return [
|
|
13679
|
+
"Date",
|
|
13680
|
+
Date.prototype.getTime.call(value),
|
|
13681
|
+
extra()
|
|
13682
|
+
];
|
|
13683
|
+
if (value instanceof RegExp) return [
|
|
13684
|
+
"RegExp",
|
|
13685
|
+
[
|
|
13686
|
+
Reflect.get(RegExp.prototype, "source", value),
|
|
13687
|
+
Reflect.get(RegExp.prototype, "flags", value),
|
|
13688
|
+
value.lastIndex
|
|
13689
|
+
],
|
|
13427
13690
|
extra()
|
|
13428
13691
|
];
|
|
13429
13692
|
return ownData(value);
|
|
@@ -13459,22 +13722,44 @@ function reducers() {
|
|
|
13459
13722
|
return out;
|
|
13460
13723
|
}
|
|
13461
13724
|
/**
|
|
13462
|
-
* The
|
|
13463
|
-
*
|
|
13464
|
-
|
|
13465
|
-
|
|
13725
|
+
* The RegExp of a `[source, flags, lastIndex]` list (an `R` entry, or the
|
|
13726
|
+
* contents of a RegExp subclass), or undefined if the list is malformed.
|
|
13727
|
+
*/
|
|
13728
|
+
function newRegExp(data) {
|
|
13729
|
+
if (!Array.isArray(data) || typeof data[0] !== "string" || typeof data[1] !== "string" || !Number.isSafeInteger(data[2])) return;
|
|
13730
|
+
const re = new RegExp(data[0], data[1]);
|
|
13731
|
+
re.lastIndex = data[2];
|
|
13732
|
+
return re;
|
|
13733
|
+
}
|
|
13734
|
+
/**
|
|
13735
|
+
* A new Date or RegExp holding `contents` (see classData), or undefined if
|
|
13736
|
+
* they are malformed.
|
|
13737
|
+
*/
|
|
13738
|
+
function newAtomic(kind, contents) {
|
|
13739
|
+
if (kind === "RegExp") return newRegExp(contents);
|
|
13740
|
+
return typeof contents === "number" ? new Date(contents) : void 0;
|
|
13741
|
+
}
|
|
13742
|
+
/**
|
|
13743
|
+
* The built-in of a registered class that a `[kind, contents, keys]` list
|
|
13744
|
+
* holds (see classData). A cycle through a collection revives it before its
|
|
13745
|
+
* list is complete (devalue holds unread parts as holes), so the instance
|
|
13746
|
+
* is kept per list and filled with what the list holds so far. (The
|
|
13747
|
+
* contents of a Date or RegExp hold no objects, so they are complete.)
|
|
13466
13748
|
*/
|
|
13467
13749
|
var collections = /* @__PURE__ */ new WeakMap();
|
|
13468
|
-
function
|
|
13750
|
+
function reviveBuiltin(name, ctor, list) {
|
|
13469
13751
|
const [kind, contents, keys] = list;
|
|
13470
|
-
const base = typeof kind === "string" && hasOwn(
|
|
13471
|
-
|
|
13752
|
+
const base = typeof kind === "string" && hasOwn(BUILTIN_KINDS, kind) ? BUILTIN_KINDS[kind] : void 0;
|
|
13753
|
+
const atomic = kind === "Date" || kind === "RegExp";
|
|
13754
|
+
if (list.length !== 3 || !base || !(ctor.prototype instanceof base) || !atomic && hasOwn(list, 1) && !Array.isArray(contents) || hasOwn(list, 2) && !isPlainData(keys)) throw malformedClass(name);
|
|
13472
13755
|
let made = collections.get(list);
|
|
13473
13756
|
if (!made) {
|
|
13474
|
-
|
|
13757
|
+
const value = atomic ? newAtomic(kind, contents) : new base();
|
|
13758
|
+
if (!value) throw malformedClass(name);
|
|
13759
|
+
made = Object.setPrototypeOf(value, ctor.prototype);
|
|
13475
13760
|
collections.set(list, made);
|
|
13476
13761
|
}
|
|
13477
|
-
if (Array.isArray(contents)) fillCollection(made, contents);
|
|
13762
|
+
if (!atomic && Array.isArray(contents)) fillCollection(made, contents);
|
|
13478
13763
|
if (isPlainData(keys)) for (const key of Object.keys(keys)) defineData(made, key, keys[key]);
|
|
13479
13764
|
return made;
|
|
13480
13765
|
}
|
|
@@ -13498,13 +13783,13 @@ function fillCollection(made, contents) {
|
|
|
13498
13783
|
/** Restore a registered class instance in place, so cycles through it hold. */
|
|
13499
13784
|
function reviveClass(name) {
|
|
13500
13785
|
return (data) => {
|
|
13501
|
-
if (Array.isArray(data)) return
|
|
13786
|
+
if (Array.isArray(data)) return reviveBuiltin(name, registeredCtor(name), data);
|
|
13502
13787
|
if (!isPlainData(data)) {
|
|
13503
13788
|
if (isObject(data) && registeredClassName(data) === name) return data;
|
|
13504
13789
|
throw malformedClass(name);
|
|
13505
13790
|
}
|
|
13506
13791
|
const ctor = registeredCtor(name);
|
|
13507
|
-
if (Object.values(
|
|
13792
|
+
if (Object.values(BUILTIN_KINDS).some((c) => ctor.prototype instanceof c)) throw malformedClass(name);
|
|
13508
13793
|
Object.setPrototypeOf(data, ctor.prototype);
|
|
13509
13794
|
if (data instanceof Error) hideErrorKeys(data);
|
|
13510
13795
|
return data;
|
|
@@ -13566,9 +13851,8 @@ function reviverFor(key) {
|
|
|
13566
13851
|
};
|
|
13567
13852
|
if (key === KEYS_TAG) return reviveKeyed;
|
|
13568
13853
|
if (key === REGEXP_TAG) return (data) => {
|
|
13569
|
-
|
|
13570
|
-
|
|
13571
|
-
re.lastIndex = data[2];
|
|
13854
|
+
const re = newRegExp(data);
|
|
13855
|
+
if (!re) throw new TypeError("spindle: Malformed regular expression");
|
|
13572
13856
|
return re;
|
|
13573
13857
|
};
|
|
13574
13858
|
if (key.startsWith(CLASS_PREFIX)) return reviveClass(key.slice(2));
|
|
@@ -14170,10 +14454,12 @@ function shallowCopy(value) {
|
|
|
14170
14454
|
* written in place.
|
|
14171
14455
|
*
|
|
14172
14456
|
* The path goes through own properties of plain objects, class instances
|
|
14173
|
-
* and arrays (by index)
|
|
14174
|
-
*
|
|
14175
|
-
*
|
|
14176
|
-
*
|
|
14457
|
+
* and arrays (by index), and, outside a draft, any key of an instance of a
|
|
14458
|
+
* registered subclass of a built-in (#408); anything else throws a
|
|
14459
|
+
* TypeError rather than writing where no clone or save would see it: an
|
|
14460
|
+
* inherited property such as a method counts as missing, and Map, Set,
|
|
14461
|
+
* Date and RegExp values and other keys of arrays are refused, as is a
|
|
14462
|
+
* "__proto__" segment.
|
|
14177
14463
|
*/
|
|
14178
14464
|
function setByPath(root, segments, value, options = {}) {
|
|
14179
14465
|
const parent = walkToParent(root, segments, options.createMissing ?? false);
|
|
@@ -14208,8 +14494,15 @@ function deleteByPath(root, segments) {
|
|
|
14208
14494
|
function checkSegments(segments) {
|
|
14209
14495
|
if (segments.includes("__proto__")) throw new TypeError(`spindle: Cannot use "__proto__" in a variable path ("${segments.join(".")}")`);
|
|
14210
14496
|
}
|
|
14211
|
-
/**
|
|
14212
|
-
|
|
14497
|
+
/**
|
|
14498
|
+
* Throw unless `holder` can take `key` as story state (see setByPath). An
|
|
14499
|
+
* instance of a registered subclass of a built-in keeps its own fields
|
|
14500
|
+
* through clones and saves, so it takes any key (#408) when written in
|
|
14501
|
+
* place: a draft of one, or one a draft shares, is refused as other
|
|
14502
|
+
* built-ins are, and the caller writes the whole value instead.
|
|
14503
|
+
*/
|
|
14504
|
+
function checkHolder(holder, key, segments, depth, inPlace) {
|
|
14505
|
+
if (inPlace && registeredClassName(holder) !== void 0) return;
|
|
14213
14506
|
const kind = builtinName(holder) ?? (Array.isArray(holder) && !isArrayKey(key) ? "an array" : "");
|
|
14214
14507
|
if (kind) throw new TypeError(`spindle: Cannot set property "${key}" on ${kind} (at "${segments.slice(0, depth).join(".")}")`);
|
|
14215
14508
|
}
|
|
@@ -14225,7 +14518,7 @@ function walkToParent(root, segments, createMissing) {
|
|
|
14225
14518
|
let current = root;
|
|
14226
14519
|
for (let i = 0; i < segments.length - 1; i++) {
|
|
14227
14520
|
const seg = segments[i];
|
|
14228
|
-
checkHolder(current, seg, segments, i);
|
|
14521
|
+
checkHolder(current, seg, segments, i, !copyOnWrite);
|
|
14229
14522
|
let next = hasOwn(current, seg) ? current[seg] : void 0;
|
|
14230
14523
|
if (next == null || typeof next !== "object") {
|
|
14231
14524
|
if (!createMissing) throw new TypeError(`spindle: Cannot set property "${segments[i + 1]}" on ${next === null ? "null" : typeof next} (at "${segments.slice(0, i + 1).join(".")}")`);
|
|
@@ -14237,7 +14530,7 @@ function walkToParent(root, segments, createMissing) {
|
|
|
14237
14530
|
}
|
|
14238
14531
|
current = next;
|
|
14239
14532
|
}
|
|
14240
|
-
checkHolder(current, segments[segments.length - 1], segments, segments.length - 1);
|
|
14533
|
+
checkHolder(current, segments[segments.length - 1], segments, segments.length - 1, !copyOnWrite);
|
|
14241
14534
|
return current;
|
|
14242
14535
|
}
|
|
14243
14536
|
//#endregion
|
|
@@ -14248,13 +14541,13 @@ function isPlainObject(value) {
|
|
|
14248
14541
|
return proto === Object.prototype || proto === null;
|
|
14249
14542
|
}
|
|
14250
14543
|
/**
|
|
14251
|
-
* `empty`, a new
|
|
14252
|
-
* like it: an instance of a registered subclass keeps its class
|
|
14253
|
-
* extra keys (#391), with the values `value` gives for them;
|
|
14254
|
-
*
|
|
14544
|
+
* `empty`, a new built-in (an Array, Map, Set, Date or RegExp) standing for
|
|
14545
|
+
* `obj`, made like it: an instance of a registered subclass keeps its class
|
|
14546
|
+
* and its extra keys (#391, #393), with the values `value` gives for them;
|
|
14547
|
+
* other built-ins are plain. `made` gets it before its keys are filled, so
|
|
14255
14548
|
* that cycles through it find it.
|
|
14256
14549
|
*/
|
|
14257
|
-
function
|
|
14550
|
+
function builtinLike(obj, empty, made, value) {
|
|
14258
14551
|
made(empty);
|
|
14259
14552
|
if (registeredClassName(obj) === void 0) return empty;
|
|
14260
14553
|
Object.setPrototypeOf(empty, Object.getPrototypeOf(obj));
|
|
@@ -14287,11 +14580,11 @@ function deepClone(value, options = {}) {
|
|
|
14287
14580
|
return copy;
|
|
14288
14581
|
}
|
|
14289
14582
|
function cloneBuiltin(val) {
|
|
14290
|
-
if (val instanceof Date) return
|
|
14583
|
+
if (val instanceof Date) return builtin(val, new Date(Date.prototype.getTime.call(val)));
|
|
14291
14584
|
if (val instanceof RegExp) {
|
|
14292
|
-
const copy = new RegExp(
|
|
14585
|
+
const copy = new RegExp(Reflect.get(RegExp.prototype, "source", val), Reflect.get(RegExp.prototype, "flags", val));
|
|
14293
14586
|
copy.lastIndex = val.lastIndex;
|
|
14294
|
-
return
|
|
14587
|
+
return builtin(val, copy);
|
|
14295
14588
|
}
|
|
14296
14589
|
if (val instanceof ArrayBuffer) return keep(val, val.slice(0));
|
|
14297
14590
|
if (ArrayBuffer.isView(val)) {
|
|
@@ -14322,29 +14615,29 @@ function deepClone(value, options = {}) {
|
|
|
14322
14615
|
const settle = options.settle;
|
|
14323
14616
|
return settle && isObjectValue(copy) && isObjectValue(original) ? settle(copy, original) : copy;
|
|
14324
14617
|
}
|
|
14325
|
-
/** `empty`, made the copy of the
|
|
14326
|
-
const
|
|
14618
|
+
/** `empty`, made the copy of the built-in `obj` (see builtinLike). */
|
|
14619
|
+
const builtin = (obj, empty) => builtinLike(obj, empty, (copy) => keep(obj, copy), (key) => clone(obj[key]));
|
|
14327
14620
|
function clone(val) {
|
|
14328
14621
|
if (val === null || typeof val !== "object") return val;
|
|
14329
14622
|
const obj = val;
|
|
14330
14623
|
if (seen.has(obj)) return seen.get(obj);
|
|
14331
14624
|
if (Array.isArray(val)) {
|
|
14332
|
-
const arr =
|
|
14625
|
+
const arr = builtin(obj, new Array(val.length));
|
|
14333
14626
|
for (let i = 0; i < val.length; i++) if (i in val) arr[i] = clone(val[i]);
|
|
14334
14627
|
return arr;
|
|
14335
14628
|
}
|
|
14336
14629
|
if (val instanceof Map) {
|
|
14337
|
-
const copy =
|
|
14338
|
-
for (const [k, v] of val) Map.prototype.set.call(copy, settled(clone(k), k), clone(v));
|
|
14630
|
+
const copy = builtin(obj, /* @__PURE__ */ new Map());
|
|
14631
|
+
for (const [k, v] of mapEntries(val)) Map.prototype.set.call(copy, settled(clone(k), k), clone(v));
|
|
14339
14632
|
return copy;
|
|
14340
14633
|
}
|
|
14341
14634
|
if (val instanceof Set) {
|
|
14342
|
-
const copy =
|
|
14343
|
-
for (const v of val) Set.prototype.add.call(copy, settled(clone(v), v));
|
|
14635
|
+
const copy = builtin(obj, /* @__PURE__ */ new Set());
|
|
14636
|
+
for (const v of setMembers(val)) Set.prototype.add.call(copy, settled(clone(v), v));
|
|
14344
14637
|
return copy;
|
|
14345
14638
|
}
|
|
14346
|
-
const
|
|
14347
|
-
if (
|
|
14639
|
+
const copied = cloneBuiltin(obj);
|
|
14640
|
+
if (copied !== void 0) return copied;
|
|
14348
14641
|
const keepsProto = registeredClassName(obj) !== void 0 || isPlainObject(val);
|
|
14349
14642
|
if (!keepsProto && options.keepUnregistered) return val;
|
|
14350
14643
|
return copyKeys(obj, keep(obj, keepsProto ? Object.create(Object.getPrototypeOf(obj)) : {}));
|
|
@@ -14447,11 +14740,11 @@ function shareEqual(prev, curr) {
|
|
|
14447
14740
|
const cr = c;
|
|
14448
14741
|
/** What the result holds at `key` of `c`. */
|
|
14449
14742
|
const shareKey = (key) => share(hasOwn(pr, key) ? pr[key] : void 0, cr[key]);
|
|
14450
|
-
/** `empty`, made the result for the collection `c` (see
|
|
14451
|
-
const collection = (empty) =>
|
|
14743
|
+
/** `empty`, made the result for the collection `c` (see builtinLike). */
|
|
14744
|
+
const collection = (empty) => builtinLike(c, empty, (out) => done.set(c, out), shareKey);
|
|
14452
14745
|
if (c instanceof Map && p instanceof Map) {
|
|
14453
14746
|
const out = collection(/* @__PURE__ */ new Map());
|
|
14454
|
-
for (const [k, v] of c) Map.prototype.set.call(out, fresh(k), share(p
|
|
14747
|
+
for (const [k, v] of mapEntries(c)) Map.prototype.set.call(out, fresh(k), share(mapGet(p, k), v));
|
|
14455
14748
|
return out;
|
|
14456
14749
|
}
|
|
14457
14750
|
if (Array.isArray(c) && Array.isArray(p)) {
|
|
@@ -14479,8 +14772,14 @@ function equalBytes(a, b) {
|
|
|
14479
14772
|
}
|
|
14480
14773
|
/** Equality of the content of atomic built-ins (see isAtomic) but Map/Set. */
|
|
14481
14774
|
function equalBuiltin(a, b, assumed) {
|
|
14482
|
-
if (a instanceof Date)
|
|
14483
|
-
|
|
14775
|
+
if (a instanceof Date) {
|
|
14776
|
+
const time = Date.prototype.getTime;
|
|
14777
|
+
return Object.is(time.call(a), time.call(b)) && equalExtraKeys(a, b, assumed);
|
|
14778
|
+
}
|
|
14779
|
+
if (a instanceof RegExp) {
|
|
14780
|
+
const text = RegExp.prototype.toString;
|
|
14781
|
+
return text.call(a) === text.call(b) && a.lastIndex === b.lastIndex && equalExtraKeys(a, b, assumed);
|
|
14782
|
+
}
|
|
14484
14783
|
if (ArrayBuffer.isView(a)) {
|
|
14485
14784
|
const v = b;
|
|
14486
14785
|
return a.byteOffset === v.byteOffset && a.byteLength === v.byteLength && equal(a.buffer, v.buffer, assumed);
|
|
@@ -14499,18 +14798,20 @@ function equalKeys(a, b, assumed, keysOf = Object.keys) {
|
|
|
14499
14798
|
for (const key of keys) if (!hasOwn(bo, key) || !equal(ao[key], bo[key], assumed)) return false;
|
|
14500
14799
|
return true;
|
|
14501
14800
|
}
|
|
14502
|
-
/** Built-in
|
|
14503
|
-
var
|
|
14801
|
+
/** Built-in prototypes (see builtinLike), whose instances hold no extra keys. */
|
|
14802
|
+
var BUILTIN_PROTOS = new Set([
|
|
14504
14803
|
Array.prototype,
|
|
14505
14804
|
Map.prototype,
|
|
14506
|
-
Set.prototype
|
|
14805
|
+
Set.prototype,
|
|
14806
|
+
Date.prototype,
|
|
14807
|
+
RegExp.prototype
|
|
14507
14808
|
]);
|
|
14508
14809
|
/**
|
|
14509
|
-
* Equality of the extra keys (see extraKeys) of two
|
|
14810
|
+
* Equality of the extra keys (see extraKeys) of two built-ins of one
|
|
14510
14811
|
* class: those of a subclass instance are part of its value.
|
|
14511
14812
|
*/
|
|
14512
14813
|
function equalExtraKeys(a, b, assumed) {
|
|
14513
|
-
return
|
|
14814
|
+
return BUILTIN_PROTOS.has(Object.getPrototypeOf(a)) || equalKeys(a, b, assumed, extraKeys);
|
|
14514
14815
|
}
|
|
14515
14816
|
/** `assumed` tracks the pairs of objects met (see Pairs). */
|
|
14516
14817
|
function equal(a, b, assumed) {
|
|
@@ -14521,9 +14822,9 @@ function equal(a, b, assumed) {
|
|
|
14521
14822
|
if (met !== void 0) return met;
|
|
14522
14823
|
if (a instanceof Map || a instanceof Set) {
|
|
14523
14824
|
const bc = b;
|
|
14524
|
-
if (a
|
|
14525
|
-
const ai = a
|
|
14526
|
-
const bi = bc
|
|
14825
|
+
if (collectionSize(a) !== collectionSize(bc)) return false;
|
|
14826
|
+
const ai = a instanceof Map ? mapEntries(a) : setMembers(a);
|
|
14827
|
+
const bi = bc instanceof Map ? mapEntries(bc) : setMembers(bc);
|
|
14527
14828
|
for (let x = ai.next(), y = bi.next(); !x.done; x = ai.next(), y = bi.next()) if (!equal(x.value, y.value, assumed)) return false;
|
|
14528
14829
|
return equalExtraKeys(a, b, assumed);
|
|
14529
14830
|
}
|
|
@@ -14703,13 +15004,13 @@ function entryChildren(value) {
|
|
|
14703
15004
|
const children = [];
|
|
14704
15005
|
if (value instanceof Map) {
|
|
14705
15006
|
let index = 0;
|
|
14706
|
-
for (const [k, v] of value) {
|
|
15007
|
+
for (const [k, v] of mapEntries(value)) {
|
|
14707
15008
|
children.push([entryKey("k", index), k], [entryKey("v", index), v]);
|
|
14708
15009
|
index++;
|
|
14709
15010
|
}
|
|
14710
15011
|
} else if (value instanceof Set) {
|
|
14711
15012
|
let index = 0;
|
|
14712
|
-
for (const member of value) children.push([entryKey("s", index++), member]);
|
|
15013
|
+
for (const member of setMembers(value)) children.push([entryKey("s", index++), member]);
|
|
14713
15014
|
} else if (value instanceof Error) {
|
|
14714
15015
|
for (const key of ["cause", "errors"]) if (hasOwn(value, key)) children.push([entryKey(key === "cause" ? "c" : "e", 0), value[key]]);
|
|
14715
15016
|
} else if (ArrayBuffer.isView(value)) children.push([entryKey("b", 0), value.buffer]);
|
|
@@ -14741,8 +15042,9 @@ function setEntryValue(root, path, value) {
|
|
|
14741
15042
|
const holder = getByEntryPath(root, path.slice(0, -1));
|
|
14742
15043
|
const match = /^\0v(\d+)$/.exec(path[path.length - 1]);
|
|
14743
15044
|
if (!(holder instanceof Map) || !match) return false;
|
|
14744
|
-
const
|
|
14745
|
-
|
|
15045
|
+
const entry = [...mapEntries(holder)][Number(match[1])];
|
|
15046
|
+
if (!entry) return false;
|
|
15047
|
+
mapSet(holder, entry[0], value);
|
|
14746
15048
|
return true;
|
|
14747
15049
|
}
|
|
14748
15050
|
/**
|
|
@@ -14811,7 +15113,8 @@ function aliasMoved(x, y, at, earlier, later) {
|
|
|
14811
15113
|
if (xs && ys) {
|
|
14812
15114
|
if (Object.getPrototypeOf(x) !== Object.getPrototypeOf(y)) return false;
|
|
14813
15115
|
if (x instanceof Map || x instanceof Set) {
|
|
14814
|
-
|
|
15116
|
+
const ySize = collectionSize(y);
|
|
15117
|
+
if (collectionSize(x) !== ySize) return false;
|
|
14815
15118
|
}
|
|
14816
15119
|
const held = new Map(ys);
|
|
14817
15120
|
for (const [segment, a] of xs) if (held.has(segment)) pairs.push([
|
|
@@ -15382,11 +15685,13 @@ async function slotRecord(ifid, slot) {
|
|
|
15382
15685
|
async function fillSlot(ifid, slot, saveId) {
|
|
15383
15686
|
await (await getBackend()).setMeta(slotMetaKey(ifid, slot), saveId);
|
|
15384
15687
|
if (isNamedSlot(slot)) await updateSlotIndex(ifid, (slots) => slots.includes(slot) ? slots : [...slots, slot]);
|
|
15688
|
+
announceSlots(ifid);
|
|
15385
15689
|
}
|
|
15386
15690
|
/** Clear a slot: its pointer, and its entry in the slot index. */
|
|
15387
15691
|
async function emptySlot(ifid, slot) {
|
|
15388
15692
|
await (await getBackend()).deleteMeta(slotMetaKey(ifid, slot));
|
|
15389
15693
|
if (isNamedSlot(slot)) await updateSlotIndex(ifid, (slots) => slots.filter((s) => s !== slot));
|
|
15694
|
+
announceSlots(ifid);
|
|
15390
15695
|
}
|
|
15391
15696
|
/** Clear every slot holding a save whose ID passes `test`. */
|
|
15392
15697
|
async function emptySlotsHolding(ifid, test) {
|
|
@@ -15395,6 +15700,46 @@ async function emptySlotsHolding(ifid, test) {
|
|
|
15395
15700
|
if (id && test(id)) await emptySlot(ifid, slot);
|
|
15396
15701
|
}
|
|
15397
15702
|
}
|
|
15703
|
+
var SLOTS_CHANNEL = "spindle.slots";
|
|
15704
|
+
/** Every story's slots: what clearing all data announces. */
|
|
15705
|
+
var ALL_STORIES = "*";
|
|
15706
|
+
var slotsChannel;
|
|
15707
|
+
function getSlotsChannel() {
|
|
15708
|
+
if (slotsChannel === void 0) try {
|
|
15709
|
+
slotsChannel = new BroadcastChannel(SLOTS_CHANNEL);
|
|
15710
|
+
slotsChannel.unref?.();
|
|
15711
|
+
} catch {
|
|
15712
|
+
slotsChannel = null;
|
|
15713
|
+
}
|
|
15714
|
+
return slotsChannel;
|
|
15715
|
+
}
|
|
15716
|
+
/** Tell the story's other tabs that its slots changed. */
|
|
15717
|
+
function announceSlots(ifid) {
|
|
15718
|
+
try {
|
|
15719
|
+
getSlotsChannel()?.postMessage(ifid);
|
|
15720
|
+
} catch {}
|
|
15721
|
+
}
|
|
15722
|
+
/**
|
|
15723
|
+
* Call `onChange` when another tab may have filled or emptied the story's
|
|
15724
|
+
* slots: when it says so, and when this tab is shown again. Returns the
|
|
15725
|
+
* function that stops it.
|
|
15726
|
+
*/
|
|
15727
|
+
function watchSlotChanges(ifid, onChange) {
|
|
15728
|
+
const channel = getSlotsChannel();
|
|
15729
|
+
const onMessage = (event) => {
|
|
15730
|
+
if (event.data === ifid || event.data === ALL_STORIES) onChange();
|
|
15731
|
+
};
|
|
15732
|
+
const onShown = () => {
|
|
15733
|
+
if (document.visibilityState === "visible") onChange();
|
|
15734
|
+
};
|
|
15735
|
+
const doc = typeof document === "undefined" ? void 0 : document;
|
|
15736
|
+
channel?.addEventListener("message", onMessage);
|
|
15737
|
+
doc?.addEventListener("visibilitychange", onShown);
|
|
15738
|
+
return () => {
|
|
15739
|
+
channel?.removeEventListener("message", onMessage);
|
|
15740
|
+
doc?.removeEventListener("visibilitychange", onShown);
|
|
15741
|
+
};
|
|
15742
|
+
}
|
|
15398
15743
|
/** The `custom` keys that say which slot a save lives in. */
|
|
15399
15744
|
var slotCustom = (slot) => ({
|
|
15400
15745
|
isAutosave: !isNamedSlot(slot),
|
|
@@ -15648,6 +15993,7 @@ function clearGameData(ifid) {
|
|
|
15648
15993
|
await backend.deletePlaythroughsByIfid(ifid);
|
|
15649
15994
|
await backend.deleteMetaByIfid(ifid);
|
|
15650
15995
|
clearSession(ifid);
|
|
15996
|
+
announceSlots(ifid);
|
|
15651
15997
|
});
|
|
15652
15998
|
}
|
|
15653
15999
|
var clearAllData = queued(clearAllDataNow);
|
|
@@ -15662,6 +16008,7 @@ async function clearAllDataNow() {
|
|
|
15662
16008
|
}
|
|
15663
16009
|
for (const key of toRemove) sessionStorage.removeItem(key);
|
|
15664
16010
|
} catch {}
|
|
16011
|
+
announceSlots(ALL_STORIES);
|
|
15665
16012
|
}
|
|
15666
16013
|
/**
|
|
15667
16014
|
* Delete a playthrough with its saves, emptying the slots that held them.
|
|
@@ -15746,7 +16093,7 @@ function initializeStory(session) {
|
|
|
15746
16093
|
}
|
|
15747
16094
|
//#endregion
|
|
15748
16095
|
//#region src/execute-mutation.ts
|
|
15749
|
-
var NAMESPACES = [
|
|
16096
|
+
var NAMESPACES$1 = [
|
|
15750
16097
|
"variables",
|
|
15751
16098
|
"temporary",
|
|
15752
16099
|
"transient"
|
|
@@ -15827,9 +16174,9 @@ function deeplyFrozen(value, seen = /* @__PURE__ */ new Set()) {
|
|
|
15827
16174
|
if (!Object.isFrozen(value)) return false;
|
|
15828
16175
|
seen.add(value);
|
|
15829
16176
|
if (value instanceof Map) {
|
|
15830
|
-
for (const [key, entry] of value) if (!deeplyFrozen(key, seen) || !deeplyFrozen(entry, seen)) return false;
|
|
16177
|
+
for (const [key, entry] of mapEntries(value)) if (!deeplyFrozen(key, seen) || !deeplyFrozen(entry, seen)) return false;
|
|
15831
16178
|
} else if (value instanceof Set) {
|
|
15832
|
-
for (const member of value) if (!deeplyFrozen(member, seen)) return false;
|
|
16179
|
+
for (const member of setMembers(value)) if (!deeplyFrozen(member, seen)) return false;
|
|
15833
16180
|
}
|
|
15834
16181
|
return Reflect.ownKeys(value).every((key) => {
|
|
15835
16182
|
const desc = Object.getOwnPropertyDescriptor(value, key);
|
|
@@ -15869,7 +16216,7 @@ function mirror(draft, change, scopes = activeScopes, cloner = clonerOf) {
|
|
|
15869
16216
|
}
|
|
15870
16217
|
/** A cloner of a copy of its own (no references shared with others). */
|
|
15871
16218
|
var clonerOf = (target) => clonerFor(target);
|
|
15872
|
-
var NAMESPACE_KEYS$1 = new Set(NAMESPACES);
|
|
16219
|
+
var NAMESPACE_KEYS$1 = new Set(NAMESPACES$1);
|
|
15873
16220
|
/**
|
|
15874
16221
|
* Runs store updates on the running code's working copies. They stay the
|
|
15875
16222
|
* code's own, so nothing may freeze them.
|
|
@@ -15964,7 +16311,7 @@ function routeStoreUpdate(recipe) {
|
|
|
15964
16311
|
transient: inner.work.transient
|
|
15965
16312
|
};
|
|
15966
16313
|
const [next, patches] = scratch.produceWithPatches(view, recipe);
|
|
15967
|
-
const changes = NAMESPACES.flatMap((ns) => {
|
|
16314
|
+
const changes = NAMESPACES$1.flatMap((ns) => {
|
|
15968
16315
|
const own = patches.filter((p) => p.path[0] === ns);
|
|
15969
16316
|
return own.length ? writtenPaths(view[ns], next[ns], own).map((change) => ({
|
|
15970
16317
|
...change,
|
|
@@ -16375,11 +16722,28 @@ function connectTriggersToStore() {
|
|
|
16375
16722
|
function reinitTriggerState() {
|
|
16376
16723
|
for (const trigger of triggers) trigger.lastResult = evalCondition(trigger.condition);
|
|
16377
16724
|
}
|
|
16725
|
+
/**
|
|
16726
|
+
* Forget every watcher and close every dialog on display, whoever opened it
|
|
16727
|
+
* (restart): a `{dialog}` or menubar dialog of the story interface, which
|
|
16728
|
+
* stays mounted, would otherwise stay open over the new game (#397).
|
|
16729
|
+
*/
|
|
16378
16730
|
function resetTriggers() {
|
|
16379
16731
|
triggers = [];
|
|
16380
|
-
|
|
16381
|
-
|
|
16732
|
+
resets++;
|
|
16733
|
+
closeAllOpenDialogs();
|
|
16734
|
+
resetListeners.notify();
|
|
16382
16735
|
}
|
|
16736
|
+
var resets = 0;
|
|
16737
|
+
var resetListeners = createListeners();
|
|
16738
|
+
/** How many times resetTriggers has forgotten every watcher. */
|
|
16739
|
+
function triggerResets() {
|
|
16740
|
+
return resets;
|
|
16741
|
+
}
|
|
16742
|
+
/**
|
|
16743
|
+
* Call `listener` after each resetTriggers (a restart): a {watch} that stays
|
|
16744
|
+
* mounted, in the story interface, registers its watcher again (#402).
|
|
16745
|
+
*/
|
|
16746
|
+
var subscribeTriggerResets = resetListeners.subscribe;
|
|
16383
16747
|
function subscribeTriggerDialogs(cb) {
|
|
16384
16748
|
dialogNotify = cb;
|
|
16385
16749
|
if (dialogQueue.length > 0) cb();
|
|
@@ -16690,6 +17054,15 @@ function startVariables(defaults) {
|
|
|
16690
17054
|
return initialVars;
|
|
16691
17055
|
}
|
|
16692
17056
|
/**
|
|
17057
|
+
* Fresh transient variables from their declared defaults (init, restart,
|
|
17058
|
+
* load). Transients are never saved, so an instance of an unregistered
|
|
17059
|
+
* class (an engine, a library object) is kept as it is, as mutation code
|
|
17060
|
+
* keeps it (#321): a copy would lose its class and methods (#398).
|
|
17061
|
+
*/
|
|
17062
|
+
function freshTransients(defaults) {
|
|
17063
|
+
return createNamespace(deepClone(defaults, { keepUnregistered: true }));
|
|
17064
|
+
}
|
|
17065
|
+
/**
|
|
16693
17066
|
* Enter the start passage with `variables`, as the only history moment
|
|
16694
17067
|
* (init, restart). Call it inside a store update.
|
|
16695
17068
|
*/
|
|
@@ -16697,7 +17070,7 @@ function enterStart(state, passage, variables, transientDefaults) {
|
|
|
16697
17070
|
state.currentPassage = passage;
|
|
16698
17071
|
state.navigationId++;
|
|
16699
17072
|
state.variables = variables;
|
|
16700
|
-
state.transient =
|
|
17073
|
+
state.transient = freshTransients(transientDefaults);
|
|
16701
17074
|
state.temporary = createNamespace();
|
|
16702
17075
|
state.history = [{
|
|
16703
17076
|
passage,
|
|
@@ -16858,8 +17231,21 @@ var latestStateApplied = 0;
|
|
|
16858
17231
|
var slotLoadApplying = null;
|
|
16859
17232
|
/** A replacement of the game state applied at its call. */
|
|
16860
17233
|
function replaceStateNow() {
|
|
16861
|
-
|
|
17234
|
+
applyReplacement(++stateReplacementsIssued);
|
|
16862
17235
|
}
|
|
17236
|
+
var replacementListeners = createListeners();
|
|
17237
|
+
/** Record that replacement `n` is applied, and tell the listeners. */
|
|
17238
|
+
function applyReplacement(n) {
|
|
17239
|
+
latestStateApplied = n;
|
|
17240
|
+
replacementListeners.notify();
|
|
17241
|
+
}
|
|
17242
|
+
/**
|
|
17243
|
+
* Call `listener` whenever a boot, restart or load replaces the game state:
|
|
17244
|
+
* work the replaced game started that would write into the new one later (a
|
|
17245
|
+
* click body's timer in the story interface, which stays mounted) is to
|
|
17246
|
+
* stop (#401).
|
|
17247
|
+
*/
|
|
17248
|
+
var subscribeStateReplacement = replacementListeners.subscribe;
|
|
16863
17249
|
var runtimeUnsubs = [];
|
|
16864
17250
|
var inRuntimePhase = false;
|
|
16865
17251
|
/**
|
|
@@ -17091,6 +17477,16 @@ function recordKnownSave(set, slot, known) {
|
|
|
17091
17477
|
}
|
|
17092
17478
|
});
|
|
17093
17479
|
}
|
|
17480
|
+
/** Look up which slots hold a save again, as an operation queued now. */
|
|
17481
|
+
function refreshKnownSaves(set, ifid) {
|
|
17482
|
+
return populateKnownSaves(ifid).then((known) => {
|
|
17483
|
+
set((state) => {
|
|
17484
|
+
state.knownSaves = known;
|
|
17485
|
+
});
|
|
17486
|
+
});
|
|
17487
|
+
}
|
|
17488
|
+
/** Stops following the slot changes of other tabs (see init). */
|
|
17489
|
+
var stopWatchingSlots;
|
|
17094
17490
|
/**
|
|
17095
17491
|
* Queue the clearing of saved data, then restart now: the new playthrough
|
|
17096
17492
|
* is stored after it, and operations issued from here on belong to the new
|
|
@@ -17172,6 +17568,10 @@ var useStoryStore = create()(storyStore((set, get) => ({
|
|
|
17172
17568
|
console.error("spindle: failed to init save system", err);
|
|
17173
17569
|
return "";
|
|
17174
17570
|
}));
|
|
17571
|
+
stopWatchingSlots?.();
|
|
17572
|
+
stopWatchingSlots = watchSlotChanges(storyData.ifid, () => {
|
|
17573
|
+
refreshKnownSaves(set, storyData.ifid).catch(() => {});
|
|
17574
|
+
});
|
|
17175
17575
|
},
|
|
17176
17576
|
navigate: (passageName) => {
|
|
17177
17577
|
if (navigationTriggerPhase) {
|
|
@@ -17391,12 +17791,7 @@ var useStoryStore = create()(storyStore((set, get) => ({
|
|
|
17391
17791
|
});
|
|
17392
17792
|
if (playthroughId !== "" && playthroughId === current) switchToPlaythrough(replacementId, deletion);
|
|
17393
17793
|
else if (current === "") switchToLookedUpPlaythrough(deletion.then((replaced) => replaced ? replacementId : established, () => established));
|
|
17394
|
-
return reported(deletion.then(
|
|
17395
|
-
const known = await populateKnownSaves(storyData.ifid);
|
|
17396
|
-
set((state) => {
|
|
17397
|
-
state.knownSaves = known;
|
|
17398
|
-
});
|
|
17399
|
-
}), "spindle: failed to delete playthrough");
|
|
17794
|
+
return reported(deletion.then(() => refreshKnownSaves(set, storyData.ifid)), "spindle: failed to delete playthrough");
|
|
17400
17795
|
},
|
|
17401
17796
|
getSavePayload: () => {
|
|
17402
17797
|
const { currentPassage, variables, history, historyIndex, visitCounts, renderCounts } = get();
|
|
@@ -17433,7 +17828,7 @@ var useStoryStore = create()(storyStore((set, get) => ({
|
|
|
17433
17828
|
return;
|
|
17434
17829
|
}
|
|
17435
17830
|
assertPassagesExist(get().storyData, payload);
|
|
17436
|
-
|
|
17831
|
+
applyReplacement(replacement);
|
|
17437
17832
|
emit("beforeload", slot);
|
|
17438
17833
|
const ifid = get().storyData?.ifid;
|
|
17439
17834
|
if (playthroughId && ifid) switchToLoadedPlaythrough(ifid, playthroughId);
|
|
@@ -17456,7 +17851,7 @@ var useStoryStore = create()(storyStore((set, get) => ({
|
|
|
17456
17851
|
state.visitCounts = createCounts(payload.visitCounts);
|
|
17457
17852
|
state.renderCounts = createCounts(payload.renderCounts);
|
|
17458
17853
|
state.temporary = createNamespace();
|
|
17459
|
-
state.transient =
|
|
17854
|
+
state.transient = freshTransients(get().transientDefaults);
|
|
17460
17855
|
});
|
|
17461
17856
|
if (payload.watchers) restoreMacroWatchers(payload.watchers);
|
|
17462
17857
|
reinitTriggerState();
|
|
@@ -17686,6 +18081,7 @@ function PassageDialog({ passageName, fallbackMarkup, panelClass, onClose, dismi
|
|
|
17686
18081
|
}
|
|
17687
18082
|
}, [markup, nobr]);
|
|
17688
18083
|
const panelRef = useRef(null);
|
|
18084
|
+
const viewScope = useViewScope();
|
|
17689
18085
|
useModalFocus(panelRef, ".dialog-body", dismissible, stableOnClose);
|
|
17690
18086
|
useLayoutEffect(() => registerOpenDialog(stableOnClose), [stableOnClose]);
|
|
17691
18087
|
useLayoutEffect(() => {
|
|
@@ -17715,7 +18111,10 @@ function PassageDialog({ passageName, fallbackMarkup, panelClass, onClose, dismi
|
|
|
17715
18111
|
children: "✕"
|
|
17716
18112
|
}), /* @__PURE__ */ jsx("div", {
|
|
17717
18113
|
class: "dialog-body",
|
|
17718
|
-
children:
|
|
18114
|
+
children: /* @__PURE__ */ jsx(ViewScopeContext.Provider, {
|
|
18115
|
+
value: viewScope,
|
|
18116
|
+
children: content
|
|
18117
|
+
})
|
|
17719
18118
|
})]
|
|
17720
18119
|
})
|
|
17721
18120
|
})
|
|
@@ -18105,37 +18504,85 @@ var settings = {
|
|
|
18105
18504
|
//#endregion
|
|
18106
18505
|
//#region src/utils/control-edits.ts
|
|
18107
18506
|
/**
|
|
18108
|
-
* Records the edits
|
|
18109
|
-
*
|
|
18110
|
-
*
|
|
18111
|
-
*
|
|
18507
|
+
* Records the edits made to the items of a list from inside a {for}
|
|
18508
|
+
* iteration, which {for} tells apart from a list that is replaced:
|
|
18509
|
+
*
|
|
18510
|
+
* - a reader editing a variable through a control (`{textbox}`,
|
|
18511
|
+
* `{checkbox}`, ...): typing into a control inside an iteration changes
|
|
18512
|
+
* its item, but must not remount the iteration and drop the control's
|
|
18513
|
+
* focus (#369);
|
|
18514
|
+
* - mutation code an iteration runs as it renders (`{set $party[@i].hp +=
|
|
18515
|
+
* 1}`): remounting would run the iteration's mount-only macros, and so the
|
|
18516
|
+
* write, again for every write it makes (#400).
|
|
18517
|
+
*
|
|
18112
18518
|
* An edit is attributed to the variable path it wrote, so a replacement made
|
|
18113
|
-
* elsewhere (a watcher reacting to the edit
|
|
18519
|
+
* elsewhere (a watcher reacting to the edit, a button outside the loop)
|
|
18520
|
+
* still remounts.
|
|
18114
18521
|
*/
|
|
18115
18522
|
var version = 0;
|
|
18116
|
-
var MAX_LOG =
|
|
18523
|
+
var MAX_LOG = 4096;
|
|
18524
|
+
/** Edits in the order made: paths below the namespaces (`['variables', 'a']`). */
|
|
18117
18525
|
var log = [];
|
|
18118
|
-
function
|
|
18526
|
+
function note(path) {
|
|
18119
18527
|
log.push({
|
|
18120
18528
|
version: ++version,
|
|
18121
|
-
|
|
18529
|
+
path
|
|
18122
18530
|
});
|
|
18123
18531
|
if (log.length > MAX_LOG) log.shift();
|
|
18124
18532
|
}
|
|
18533
|
+
/** Note an edit a control made to the story variable at `segments`. */
|
|
18534
|
+
function noteControlEdit(segments) {
|
|
18535
|
+
note(["variables", ...segments]);
|
|
18536
|
+
}
|
|
18537
|
+
/**
|
|
18538
|
+
* Whether mutation code runs inside a {for} iteration: {for} provides true
|
|
18539
|
+
* around its iterations, and the writes of such code are noted as edits of
|
|
18540
|
+
* the items they reach (see runAsItemEdit).
|
|
18541
|
+
*/
|
|
18542
|
+
var ItemEditContext = createContext(false);
|
|
18543
|
+
var NAMESPACES = [
|
|
18544
|
+
"variables",
|
|
18545
|
+
"temporary",
|
|
18546
|
+
"transient"
|
|
18547
|
+
];
|
|
18548
|
+
/** Run `run`, noting each variable path it changes as an edit. */
|
|
18549
|
+
function runAsItemEdit(run) {
|
|
18550
|
+
const before = readState();
|
|
18551
|
+
try {
|
|
18552
|
+
run();
|
|
18553
|
+
} finally {
|
|
18554
|
+
const after = readState();
|
|
18555
|
+
for (const ns of NAMESPACES) {
|
|
18556
|
+
if (before[ns] === after[ns]) continue;
|
|
18557
|
+
for (const { path } of diffPaths(before[ns], after[ns], true)) note([ns, ...path]);
|
|
18558
|
+
}
|
|
18559
|
+
}
|
|
18560
|
+
}
|
|
18125
18561
|
function controlEditVersion() {
|
|
18126
18562
|
return version;
|
|
18127
18563
|
}
|
|
18128
18564
|
/**
|
|
18129
|
-
*
|
|
18130
|
-
* `list`: the path leads through the item (compared by reference
|
|
18131
|
-
* `
|
|
18132
|
-
*/
|
|
18133
|
-
function
|
|
18134
|
-
|
|
18135
|
-
|
|
18136
|
-
|
|
18137
|
-
|
|
18138
|
-
|
|
18565
|
+
* A test of whether an edit made since `since` wrote inside `item`, element
|
|
18566
|
+
* `index` of `list`: the path leads through the item (compared by reference
|
|
18567
|
+
* in `state`), or, for a primitive item, ends at its slot in the list.
|
|
18568
|
+
*/
|
|
18569
|
+
function editedItems(since, state) {
|
|
18570
|
+
const through = /* @__PURE__ */ new Set();
|
|
18571
|
+
const ends = /* @__PURE__ */ new Map();
|
|
18572
|
+
for (let i = log.length - 1; i >= 0 && log[i].version > since; i--) {
|
|
18573
|
+
const { path } = log[i];
|
|
18574
|
+
let node = state;
|
|
18575
|
+
path.forEach((seg, n) => {
|
|
18576
|
+
if (n === path.length - 1 && node !== null && typeof node === "object") {
|
|
18577
|
+
const keys = ends.get(node) ?? /* @__PURE__ */ new Set();
|
|
18578
|
+
keys.add(seg);
|
|
18579
|
+
ends.set(node, keys);
|
|
18580
|
+
}
|
|
18581
|
+
node = node !== null && typeof node === "object" ? getByPath(node, [seg]) : void 0;
|
|
18582
|
+
if (node !== null && typeof node === "object") through.add(node);
|
|
18583
|
+
});
|
|
18584
|
+
}
|
|
18585
|
+
return (list, item, index) => typeof item === "object" && item !== null ? through.has(item) : ends.get(list)?.has(String(index)) === true;
|
|
18139
18586
|
}
|
|
18140
18587
|
//#endregion
|
|
18141
18588
|
//#region src/action-registry.ts
|
|
@@ -18332,6 +18779,7 @@ function defineMacro(config, source = "builtin") {
|
|
|
18332
18779
|
id = resolve(id);
|
|
18333
18780
|
}
|
|
18334
18781
|
const { update, getValues } = useContext(LocalsUpdateContext);
|
|
18782
|
+
const inIteration = useContext(ItemEditContext);
|
|
18335
18783
|
const renderOptions = useRenderOptions();
|
|
18336
18784
|
const renderNodes$1 = (nodes, options) => renderNodes(nodes, {
|
|
18337
18785
|
...renderOptions,
|
|
@@ -18362,7 +18810,7 @@ function defineMacro(config, source = "builtin") {
|
|
|
18362
18810
|
id,
|
|
18363
18811
|
resolve,
|
|
18364
18812
|
cls: macroClass(config.name, className),
|
|
18365
|
-
mutate: (code) => executeMutation(code, getValues(), update),
|
|
18813
|
+
mutate: inIteration ? (code) => runAsItemEdit(() => executeMutation(code, getValues(), update)) : (code) => executeMutation(code, getValues(), update),
|
|
18366
18814
|
update,
|
|
18367
18815
|
getValues,
|
|
18368
18816
|
wrap: (content) => wrapContent(className, id, content)
|
|
@@ -18668,7 +19116,7 @@ function createStoryAPI() {
|
|
|
18668
19116
|
},
|
|
18669
19117
|
deferRender() {
|
|
18670
19118
|
useStoryStore.getState().deferRender();
|
|
18671
|
-
readyPromise
|
|
19119
|
+
readyPromise ??= new Promise((resolve) => {
|
|
18672
19120
|
readyResolve = resolve;
|
|
18673
19121
|
});
|
|
18674
19122
|
},
|
|
@@ -19227,16 +19675,25 @@ var PRIMITIVE_SAMPLES = {
|
|
|
19227
19675
|
number: Object(0),
|
|
19228
19676
|
boolean: Object(false)
|
|
19229
19677
|
};
|
|
19230
|
-
|
|
19678
|
+
/**
|
|
19679
|
+
* The schema of a default value. An object met again (a backreference, a
|
|
19680
|
+
* shared subtree) has the schema made for it the first time, so a cyclic
|
|
19681
|
+
* default gives a schema that refers to itself instead of recursing forever.
|
|
19682
|
+
*/
|
|
19683
|
+
function inferSchema(value, seen = /* @__PURE__ */ new Map()) {
|
|
19231
19684
|
if (Array.isArray(value)) return { type: "array" };
|
|
19232
19685
|
if (value === null) return { type: "null" };
|
|
19233
19686
|
if (typeof value === "object") {
|
|
19687
|
+
const known = seen.get(value);
|
|
19688
|
+
if (known) return known;
|
|
19234
19689
|
const fields = /* @__PURE__ */ new Map();
|
|
19235
|
-
|
|
19236
|
-
return {
|
|
19690
|
+
const schema = {
|
|
19237
19691
|
type: "object",
|
|
19238
19692
|
fields
|
|
19239
19693
|
};
|
|
19694
|
+
seen.set(value, schema);
|
|
19695
|
+
for (const [key, val] of Object.entries(value)) fields.set(key, inferSchema(val, seen));
|
|
19696
|
+
return schema;
|
|
19240
19697
|
}
|
|
19241
19698
|
const jsType = typeof value;
|
|
19242
19699
|
if (!VALID_VAR_TYPES.has(jsType)) throw new Error(`Unsupported type "${jsType}" for value ${String(value)}. Expected number, string, boolean, array, or object.`);
|
|
@@ -19734,23 +20191,32 @@ defineMacro({
|
|
|
19734
20191
|
* Content-derived string key for a value, used to remount components when
|
|
19735
20192
|
* the value's contents change (e.g. {for} iterations, #45).
|
|
19736
20193
|
*
|
|
19737
|
-
* JSON-compatible values (strings, finite numbers, booleans, null,
|
|
19738
|
-
* plain objects of those)
|
|
19739
|
-
* values get distinct, unambiguous markers so their contents
|
|
19740
|
-
* too: Map and Set entries (nested at any depth), Date,
|
|
19741
|
-
* undefined, NaN/±Infinity, symbols (by description),
|
|
19742
|
-
* and registered class instances
|
|
19743
|
-
*
|
|
19744
|
-
*
|
|
20194
|
+
* A tree of JSON-compatible values (strings, finite numbers, booleans, null,
|
|
20195
|
+
* arrays and plain objects of those) produces exactly its `JSON.stringify`
|
|
20196
|
+
* output. Other values get distinct, unambiguous markers so their contents
|
|
20197
|
+
* are reflected too: Map and Set entries (nested at any depth), Date,
|
|
20198
|
+
* RegExp, BigInt, undefined, NaN/±Infinity, symbols (by description),
|
|
20199
|
+
* functions (by name) and registered class instances, with the class name
|
|
20200
|
+
* and, for a subclass of a built-in, its own fields (#407). A hole in an
|
|
20201
|
+
* array reads as undefined.
|
|
20202
|
+
*
|
|
20203
|
+
* An object met again, through a cycle or a second reference to it, is a
|
|
20204
|
+
* marker naming where it was first met rather than another copy of its
|
|
20205
|
+
* contents, so the key grows with the objects a value holds, not with the
|
|
20206
|
+
* paths to them (#406). The function never throws.
|
|
19745
20207
|
*/
|
|
19746
20208
|
function stableKey(value) {
|
|
19747
20209
|
try {
|
|
19748
|
-
return keyOf(value,
|
|
20210
|
+
return keyOf(value, /* @__PURE__ */ new Map());
|
|
19749
20211
|
} catch {
|
|
19750
20212
|
return "<unkeyable>";
|
|
19751
20213
|
}
|
|
19752
20214
|
}
|
|
19753
|
-
|
|
20215
|
+
/**
|
|
20216
|
+
* The key of `val`. `seen` numbers the objects keyed so far, in the order
|
|
20217
|
+
* they were first met.
|
|
20218
|
+
*/
|
|
20219
|
+
function keyOf(val, seen) {
|
|
19754
20220
|
switch (typeof val) {
|
|
19755
20221
|
case "string": return JSON.stringify(val);
|
|
19756
20222
|
case "number": return Number.isFinite(val) ? JSON.stringify(val) : String(val);
|
|
@@ -19762,22 +20228,28 @@ function keyOf(val, ancestors) {
|
|
|
19762
20228
|
}
|
|
19763
20229
|
if (val === null) return "null";
|
|
19764
20230
|
const obj = val;
|
|
19765
|
-
const
|
|
19766
|
-
if (
|
|
19767
|
-
|
|
19768
|
-
|
|
19769
|
-
|
|
19770
|
-
|
|
19771
|
-
|
|
19772
|
-
|
|
19773
|
-
|
|
19774
|
-
|
|
19775
|
-
|
|
19776
|
-
const className = registeredClassName(obj);
|
|
19777
|
-
return className === void 0 ? `{${body}}` : `Class(${JSON.stringify(className)}){${body}}`;
|
|
19778
|
-
} finally {
|
|
19779
|
-
ancestors.pop();
|
|
20231
|
+
const first = seen.get(obj);
|
|
20232
|
+
if (first !== void 0) return `<ref ${first}>`;
|
|
20233
|
+
const className = registeredClassName(obj);
|
|
20234
|
+
const named = (key) => className === void 0 ? key : `Class(${JSON.stringify(className)})${key}`;
|
|
20235
|
+
const withFields = (key) => {
|
|
20236
|
+
const keys = className === void 0 ? [] : extraKeys(obj);
|
|
20237
|
+
return named(keys.length ? `${key}${fieldsOf(obj, keys, seen)}` : key);
|
|
20238
|
+
};
|
|
20239
|
+
if (val instanceof Date || val instanceof RegExp) {
|
|
20240
|
+
if (className !== void 0 && extraKeys(obj).length) seen.set(obj, seen.size);
|
|
20241
|
+
return withFields(val instanceof Date ? `Date(${Date.prototype.getTime.call(val)})` : `RegExp(${RegExp.prototype.toString.call(val)}@${val.lastIndex})`);
|
|
19780
20242
|
}
|
|
20243
|
+
seen.set(obj, seen.size);
|
|
20244
|
+
if (Array.isArray(val)) return withFields(`[${Array.from(val, (v) => keyOf(v, seen)).join(",")}]`);
|
|
20245
|
+
if (val instanceof Map) return withFields(`Map[${Array.from(mapEntries(val), ([k, v]) => `[${keyOf(k, seen)},${keyOf(v, seen)}]`).join(",")}]`);
|
|
20246
|
+
if (val instanceof Set) return withFields(`Set[${Array.from(setMembers(val), (v) => keyOf(v, seen)).join(",")}]`);
|
|
20247
|
+
return named(fieldsOf(obj, Object.keys(obj), seen));
|
|
20248
|
+
}
|
|
20249
|
+
/** `{"key":value,...}` for the `keys` of `obj`. */
|
|
20250
|
+
function fieldsOf(obj, keys, seen) {
|
|
20251
|
+
const record = obj;
|
|
20252
|
+
return `{${keys.map((k) => `${JSON.stringify(k)}:${keyOf(record[k], seen)}`).join(",")}}`;
|
|
19781
20253
|
}
|
|
19782
20254
|
//#endregion
|
|
19783
20255
|
//#region src/components/macros/For.tsx
|
|
@@ -19859,12 +20331,11 @@ defineMacro({
|
|
|
19859
20331
|
});
|
|
19860
20332
|
}
|
|
19861
20333
|
const { itemVar, indexVar } = loop;
|
|
19862
|
-
const
|
|
19863
|
-
const { variables } = readState();
|
|
20334
|
+
const edited = editedItems(keys.edits, readState());
|
|
19864
20335
|
keys.edits = controlEditVersion();
|
|
19865
20336
|
const generations = list.map((item, i) => {
|
|
19866
20337
|
const contents = stableKey(item);
|
|
19867
|
-
if (keys.generations[i] === void 0 || contents !== keys.contents[i] && !
|
|
20338
|
+
if (keys.generations[i] === void 0 || contents !== keys.contents[i] && !edited(list, item, i)) keys.generations[i] = keys.next++;
|
|
19868
20339
|
keys.contents[i] = contents;
|
|
19869
20340
|
return keys.generations[i];
|
|
19870
20341
|
});
|
|
@@ -19877,7 +20348,10 @@ defineMacro({
|
|
|
19877
20348
|
indexValue: i,
|
|
19878
20349
|
children
|
|
19879
20350
|
}, `${i}-${generations[i]}`));
|
|
19880
|
-
return ctx.wrap(
|
|
20351
|
+
return ctx.wrap(/* @__PURE__ */ jsx(ItemEditContext.Provider, {
|
|
20352
|
+
value: true,
|
|
20353
|
+
children: content
|
|
20354
|
+
}));
|
|
19881
20355
|
},
|
|
19882
20356
|
text({ rawArgs, children = [] }, ctx) {
|
|
19883
20357
|
const { itemVar, indexVar, listExpr } = loopArgs(rawArgs, ctx.args);
|
|
@@ -19968,7 +20442,9 @@ var frozenAlways = () => true;
|
|
|
19968
20442
|
* once it has rendered, so it runs once per click. It stays mounted
|
|
19969
20443
|
* until the owning macro unmounts (its passage changes, say), so work it
|
|
19970
20444
|
* starts in an effect, such as the timer of a {timed} or {repeat}, can
|
|
19971
|
-
* finish; the passage leaving cancels it
|
|
20445
|
+
* finish; the passage leaving cancels it, and so does a restart or a load
|
|
20446
|
+
* replacing the game, which a control of the story interface outlives
|
|
20447
|
+
* (#401).
|
|
19972
20448
|
*
|
|
19973
20449
|
* A detached render starts with no contexts, so the hook captures the ones
|
|
19974
20450
|
* the owning macro sees and provides them again: the locals scope (read
|
|
@@ -19990,8 +20466,17 @@ function useDetachedBody() {
|
|
|
19990
20466
|
const repeat = useContext(RepeatContext);
|
|
19991
20467
|
const closeDialog = useContext(DialogCloseContext);
|
|
19992
20468
|
const mounted = useRef([]);
|
|
19993
|
-
useEffect(() =>
|
|
19994
|
-
|
|
20469
|
+
useEffect(() => {
|
|
20470
|
+
const unsubscribe = subscribeStateReplacement(() => {
|
|
20471
|
+
const replaced = mounted.current.splice(0);
|
|
20472
|
+
queueMicrotask(() => {
|
|
20473
|
+
for (const container of replaced) render(null, container);
|
|
20474
|
+
});
|
|
20475
|
+
});
|
|
20476
|
+
return () => {
|
|
20477
|
+
unsubscribe();
|
|
20478
|
+
for (const container of mounted.current.splice(0)) render(null, container);
|
|
20479
|
+
};
|
|
19995
20480
|
}, []);
|
|
19996
20481
|
const run = (children) => {
|
|
19997
20482
|
const locals = liveLocalsView(updater.getValues);
|
|
@@ -21162,6 +21647,7 @@ defineMacro({
|
|
|
21162
21647
|
render(_props, ctx) {
|
|
21163
21648
|
const radioValue = ctx.args.value ?? "";
|
|
21164
21649
|
const label = ctx.args.label ?? "";
|
|
21650
|
+
const view = ctx.hooks.useContext(ViewScopeContext);
|
|
21165
21651
|
useVariableAction(ctx, {
|
|
21166
21652
|
type: "radiobutton",
|
|
21167
21653
|
key: `$${ctx.varName}:${radioValue}`,
|
|
@@ -21173,7 +21659,7 @@ defineMacro({
|
|
|
21173
21659
|
class: ctx.cls,
|
|
21174
21660
|
children: [/* @__PURE__ */ jsx("input", {
|
|
21175
21661
|
type: "radio",
|
|
21176
|
-
name: `radio-${ctx.varName}`,
|
|
21662
|
+
name: view ? `radio-${view}-${ctx.varName}` : `radio-${ctx.varName}`,
|
|
21177
21663
|
checked: ctx.value === radioValue,
|
|
21178
21664
|
onChange: () => ctx.setValue(radioValue)
|
|
21179
21665
|
}), label ? ` ${label}` : null]
|
|
@@ -21332,27 +21818,31 @@ function Passage({ passage, dataTransition, navigationId }) {
|
|
|
21332
21818
|
if (elRef.current) emitFromRender("passagerender", passage.name, elRef.current);
|
|
21333
21819
|
}, [passage.name, navigationId]);
|
|
21334
21820
|
const nobr = passage.tags.includes("nobr");
|
|
21335
|
-
const
|
|
21336
|
-
|
|
21337
|
-
|
|
21338
|
-
"
|
|
21339
|
-
|
|
21340
|
-
|
|
21341
|
-
|
|
21342
|
-
|
|
21343
|
-
|
|
21344
|
-
|
|
21345
|
-
|
|
21346
|
-
|
|
21347
|
-
|
|
21348
|
-
|
|
21349
|
-
|
|
21350
|
-
|
|
21351
|
-
|
|
21352
|
-
|
|
21353
|
-
|
|
21354
|
-
|
|
21355
|
-
|
|
21821
|
+
const viewScope = useViewScope();
|
|
21822
|
+
const inner = /* @__PURE__ */ jsx(ViewScopeContext.Provider, {
|
|
21823
|
+
value: viewScope,
|
|
21824
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
21825
|
+
ref: elRef,
|
|
21826
|
+
class: "passage",
|
|
21827
|
+
"data-passage": passage.name,
|
|
21828
|
+
"data-tags": passage.tags.join(" "),
|
|
21829
|
+
"data-transition": dataTransition,
|
|
21830
|
+
children: [
|
|
21831
|
+
headerContent && /* @__PURE__ */ jsx("div", {
|
|
21832
|
+
class: "passage-header",
|
|
21833
|
+
children: headerContent
|
|
21834
|
+
}),
|
|
21835
|
+
content,
|
|
21836
|
+
footerContent && /* @__PURE__ */ jsx("div", {
|
|
21837
|
+
class: "passage-footer",
|
|
21838
|
+
children: footerContent
|
|
21839
|
+
}),
|
|
21840
|
+
doneContent && /* @__PURE__ */ jsx("div", {
|
|
21841
|
+
hidden: true,
|
|
21842
|
+
children: doneContent
|
|
21843
|
+
})
|
|
21844
|
+
]
|
|
21845
|
+
})
|
|
21356
21846
|
});
|
|
21357
21847
|
return nobr ? /* @__PURE__ */ jsx(NobrContext.Provider, {
|
|
21358
21848
|
value: true,
|
|
@@ -21650,9 +22140,12 @@ defineMacro({
|
|
|
21650
22140
|
const { hooks } = ctx;
|
|
21651
22141
|
const { condition, options } = ctx.args;
|
|
21652
22142
|
if (condition === void 0) return null;
|
|
21653
|
-
const
|
|
21654
|
-
|
|
21655
|
-
|
|
22143
|
+
const frozen = hooks.useContext(FrozenStateContext);
|
|
22144
|
+
const [, rerender] = hooks.useState(0);
|
|
22145
|
+
hooks.useEffect(() => subscribeTriggerResets(() => rerender((n) => n + 1)), []);
|
|
22146
|
+
const registered = hooks.useRef(null);
|
|
22147
|
+
if (registered.current === null || registered.current !== triggerResets() && !frozen?.(useStoryStore.getState())) {
|
|
22148
|
+
registered.current = triggerResets();
|
|
21656
22149
|
addMacroTrigger(condition, options);
|
|
21657
22150
|
}
|
|
21658
22151
|
return null;
|