jssm 5.158.2 → 5.159.1
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 +7 -7
- package/dist/cdn/instance.js +1 -1
- package/dist/cdn/viz.js +1 -1
- package/dist/cli/fsl-export-system-prompt.cjs +1 -1
- package/dist/cli/fsl-render.cjs +1 -1
- package/dist/cli/fsl.cjs +1 -1
- package/dist/cli/lib.cjs +1 -1
- package/dist/cli/lib.mjs +1 -1
- package/dist/deno/README.md +7 -7
- package/dist/deno/fsl_gif.d.ts +3 -2
- package/dist/deno/jssm.js +1 -1
- package/dist/deno/jssm_viz.d.ts +65 -1
- package/dist/fence/fence.js +424 -155
- package/dist/jssm.es5.cjs +1 -1
- package/dist/jssm.es5.iife.js +1 -1
- package/dist/jssm.es6.mjs +1 -1
- package/dist/jssm_viz.cjs +1 -1
- package/dist/jssm_viz.iife.cjs +1 -1
- package/dist/jssm_viz.mjs +1 -1
- package/jssm.cli.d.cts +15 -3
- package/jssm.cli.d.ts +15 -3
- package/jssm.es5.d.cts +11 -1
- package/jssm.es6.d.ts +11 -1
- package/jssm.fence.d.ts +3 -2
- package/jssm_viz.es5.d.cts +65 -1
- package/jssm_viz.es6.d.ts +65 -1
- package/package.json +1 -1
package/dist/fence/fence.js
CHANGED
|
@@ -359,10 +359,20 @@ function peg$parse(input, options) {
|
|
|
359
359
|
node.loc = location();
|
|
360
360
|
}
|
|
361
361
|
return node;
|
|
362
|
-
}, peg$c1235 = "milliseconds", peg$c1236 = peg$literalExpectation("milliseconds", false), peg$c1237 = function () { return 1; }, peg$c1238 = "millisecond", peg$c1239 = peg$literalExpectation("millisecond", false), peg$c1240 = "msecs", peg$c1241 = peg$literalExpectation("msecs", false), peg$c1242 = "msec", peg$c1243 = peg$literalExpectation("msec", false), peg$c1244 = "ms", peg$c1245 = peg$literalExpectation("ms", false), peg$c1246 = "seconds", peg$c1247 = peg$literalExpectation("seconds", false), peg$c1248 = function () { return 1000; }, peg$c1249 = "second", peg$c1250 = peg$literalExpectation("second", false), peg$c1251 = "secs", peg$c1252 = peg$literalExpectation("secs", false), peg$c1253 = "sec", peg$c1254 = peg$literalExpectation("sec", false), peg$c1255 = "s", peg$c1256 = peg$literalExpectation("s", false), peg$c1257 = "minutes", peg$c1258 = peg$literalExpectation("minutes", false), peg$c1259 = function () { return 1000 * 60; }, peg$c1260 = "minute", peg$c1261 = peg$literalExpectation("minute", false), peg$c1262 = "mins", peg$c1263 = peg$literalExpectation("mins", false), peg$c1264 = "min", peg$c1265 = peg$literalExpectation("min", false), peg$c1266 = "m", peg$c1267 = peg$literalExpectation("m", false), peg$c1268 = "hours", peg$c1269 = peg$literalExpectation("hours", false), peg$c1270 = function () { return 1000 * 60 * 60; }, peg$c1271 = "hour", peg$c1272 = peg$literalExpectation("hour", false), peg$c1273 = "hrs", peg$c1274 = peg$literalExpectation("hrs", false), peg$c1275 = "hr", peg$c1276 = peg$literalExpectation("hr", false), peg$c1277 = "h", peg$c1278 = peg$literalExpectation("h", false), peg$c1279 = "days", peg$c1280 = peg$literalExpectation("days", false), peg$c1281 = function () { return 1000 * 60 * 60 * 24; }, peg$c1282 = "day", peg$c1283 = peg$literalExpectation("day", false), peg$c1284 = "d", peg$c1285 = peg$literalExpectation("d", false), peg$c1286 = "weeks", peg$c1287 = peg$literalExpectation("weeks", false), peg$c1288 = function () { return 1000 * 60 * 60 * 24 * 7; }, peg$c1289 = "week", peg$c1290 = peg$literalExpectation("week", false), peg$c1291 = "wks", peg$c1292 = peg$literalExpectation("wks", false), peg$c1293 = "wk", peg$c1294 = peg$literalExpectation("wk", false), peg$c1295 = "w", peg$c1296 = peg$literalExpectation("w", false), peg$c1297 = "after", peg$c1298 = peg$literalExpectation("after", false), peg$c1299 = function (value, timescale) { return value * (timescale || 1000); }, peg$c1300 = function (names) { return names.map(i => i[0]); }, peg$c1301 = peg$otherExpectation("group reference"), peg$c1302 = "&", peg$c1303 = peg$literalExpectation("&", false), peg$c1304 = function (name) { return { key: 'group_ref', name }; }, peg$c1305 = "...", peg$c1306 = peg$literalExpectation("...", false), peg$c1307 = function (name) {
|
|
362
|
+
}, peg$c1235 = "milliseconds", peg$c1236 = peg$literalExpectation("milliseconds", false), peg$c1237 = function () { return 1; }, peg$c1238 = "millisecond", peg$c1239 = peg$literalExpectation("millisecond", false), peg$c1240 = "msecs", peg$c1241 = peg$literalExpectation("msecs", false), peg$c1242 = "msec", peg$c1243 = peg$literalExpectation("msec", false), peg$c1244 = "ms", peg$c1245 = peg$literalExpectation("ms", false), peg$c1246 = "seconds", peg$c1247 = peg$literalExpectation("seconds", false), peg$c1248 = function () { return 1000; }, peg$c1249 = "second", peg$c1250 = peg$literalExpectation("second", false), peg$c1251 = "secs", peg$c1252 = peg$literalExpectation("secs", false), peg$c1253 = "sec", peg$c1254 = peg$literalExpectation("sec", false), peg$c1255 = "s", peg$c1256 = peg$literalExpectation("s", false), peg$c1257 = "minutes", peg$c1258 = peg$literalExpectation("minutes", false), peg$c1259 = function () { return 1000 * 60; }, peg$c1260 = "minute", peg$c1261 = peg$literalExpectation("minute", false), peg$c1262 = "mins", peg$c1263 = peg$literalExpectation("mins", false), peg$c1264 = "min", peg$c1265 = peg$literalExpectation("min", false), peg$c1266 = "m", peg$c1267 = peg$literalExpectation("m", false), peg$c1268 = "hours", peg$c1269 = peg$literalExpectation("hours", false), peg$c1270 = function () { return 1000 * 60 * 60; }, peg$c1271 = "hour", peg$c1272 = peg$literalExpectation("hour", false), peg$c1273 = "hrs", peg$c1274 = peg$literalExpectation("hrs", false), peg$c1275 = "hr", peg$c1276 = peg$literalExpectation("hr", false), peg$c1277 = "h", peg$c1278 = peg$literalExpectation("h", false), peg$c1279 = "days", peg$c1280 = peg$literalExpectation("days", false), peg$c1281 = function () { return 1000 * 60 * 60 * 24; }, peg$c1282 = "day", peg$c1283 = peg$literalExpectation("day", false), peg$c1284 = "d", peg$c1285 = peg$literalExpectation("d", false), peg$c1286 = "weeks", peg$c1287 = peg$literalExpectation("weeks", false), peg$c1288 = function () { return 1000 * 60 * 60 * 24 * 7; }, peg$c1289 = "week", peg$c1290 = peg$literalExpectation("week", false), peg$c1291 = "wks", peg$c1292 = peg$literalExpectation("wks", false), peg$c1293 = "wk", peg$c1294 = peg$literalExpectation("wk", false), peg$c1295 = "w", peg$c1296 = peg$literalExpectation("w", false), peg$c1297 = "after", peg$c1298 = peg$literalExpectation("after", false), peg$c1299 = function (value, timescale) { return value * (timescale || 1000); }, peg$c1300 = function (names) { return names.map(i => i[0]); }, peg$c1301 = peg$otherExpectation("group reference"), peg$c1302 = "&", peg$c1303 = peg$literalExpectation("&", false), peg$c1304 = function (name) { return { key: 'group_ref', name }; }, peg$c1305 = "...", peg$c1306 = peg$literalExpectation("...", false), peg$c1307 = function (name) { const m = { kind: 'group', name, mode: 'spread' }; if (options.locations) {
|
|
363
|
+
m.__loc = location();
|
|
364
|
+
} return m; }, peg$c1308 = function (name) { const m = { kind: 'group', name, mode: 'nest' }; if (options.locations) {
|
|
365
|
+
m.__loc = location();
|
|
366
|
+
} return m; }, peg$c1309 = function (name) { const m = { kind: 'state', name }; if (options.locations) {
|
|
367
|
+
m.__loc = location();
|
|
368
|
+
} return m; }, peg$c1310 = function (members) {
|
|
363
369
|
const items = members.map(m => m[0]);
|
|
364
370
|
const has_group = items.some(m => m.kind === 'group');
|
|
365
|
-
|
|
371
|
+
const collapsed = has_group ? items : items.map(m => m.name);
|
|
372
|
+
if (options.locations) {
|
|
373
|
+
collapsed.__member_locs = items.map((m) => m.__loc);
|
|
374
|
+
}
|
|
375
|
+
return collapsed;
|
|
366
376
|
}, peg$c1311 = "+|", peg$c1312 = peg$literalExpectation("+|", false), peg$c1313 = function (n) {
|
|
367
377
|
const node = { key: 'stripe', value: parseInt(n, 10) };
|
|
368
378
|
if (options.locations) {
|
|
@@ -812,69 +822,96 @@ function peg$parse(input, options) {
|
|
|
812
822
|
const node = { key: 'named_list', name, value };
|
|
813
823
|
if (options.locations) {
|
|
814
824
|
node.loc = location();
|
|
825
|
+
node.value_locs = value.__member_locs;
|
|
826
|
+
delete value.__member_locs;
|
|
827
|
+
}
|
|
828
|
+
return node;
|
|
829
|
+
}, peg$c1549 = function (name, value) {
|
|
830
|
+
const node = { key: 'named_list', name, value: value.name };
|
|
831
|
+
if (options.locations) {
|
|
832
|
+
node.loc = location();
|
|
833
|
+
node.value_locs = [value.__loc];
|
|
815
834
|
}
|
|
816
835
|
return node;
|
|
817
|
-
}, peg$
|
|
836
|
+
}, peg$c1550 = function (name) {
|
|
837
|
+
const m = { name };
|
|
838
|
+
if (options.locations) {
|
|
839
|
+
m.__loc = location();
|
|
840
|
+
}
|
|
841
|
+
return m;
|
|
842
|
+
}, peg$c1551 = peg$otherExpectation("hook event (enter/exit)"), peg$c1552 = "enter", peg$c1553 = peg$literalExpectation("enter", false), peg$c1554 = "exit", peg$c1555 = peg$literalExpectation("exit", false), peg$c1556 = peg$otherExpectation("hook declaration"), peg$c1557 = "on", peg$c1558 = peg$literalExpectation("on", false), peg$c1559 = "do", peg$c1560 = peg$literalExpectation("do", false), peg$c1561 = function (event, subject, action) {
|
|
818
843
|
const node = { key: 'hook_decl', event, subject, action };
|
|
844
|
+
if (subject.key === 'hook_state_subject') {
|
|
845
|
+
node.subject = subject.name;
|
|
846
|
+
if (options.locations) {
|
|
847
|
+
node.subject_loc = subject.__loc;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
819
850
|
if (options.locations) {
|
|
820
851
|
node.loc = location();
|
|
821
852
|
}
|
|
822
853
|
return node;
|
|
823
|
-
}, peg$
|
|
854
|
+
}, peg$c1562 = function (name) {
|
|
855
|
+
const m = { key: 'hook_state_subject', name };
|
|
856
|
+
if (options.locations) {
|
|
857
|
+
m.__loc = location();
|
|
858
|
+
}
|
|
859
|
+
return m;
|
|
860
|
+
}, peg$c1563 = function (name, default_value) {
|
|
824
861
|
const node = { key: 'property_definition', name, default_value, required: true };
|
|
825
862
|
if (options.locations) {
|
|
826
863
|
node.loc = location();
|
|
827
864
|
}
|
|
828
865
|
return node;
|
|
829
|
-
}, peg$
|
|
866
|
+
}, peg$c1564 = function (name) {
|
|
830
867
|
const node = { key: 'property_definition', name, required: true };
|
|
831
868
|
if (options.locations) {
|
|
832
869
|
node.loc = location();
|
|
833
870
|
}
|
|
834
871
|
return node;
|
|
835
|
-
}, peg$
|
|
872
|
+
}, peg$c1565 = function (name, default_value) {
|
|
836
873
|
const node = { key: 'property_definition', name, default_value };
|
|
837
874
|
if (options.locations) {
|
|
838
875
|
node.loc = location();
|
|
839
876
|
}
|
|
840
877
|
return node;
|
|
841
|
-
}, peg$
|
|
878
|
+
}, peg$c1566 = function (name) {
|
|
842
879
|
const node = { key: 'property_definition', name };
|
|
843
880
|
if (options.locations) {
|
|
844
881
|
node.loc = location();
|
|
845
882
|
}
|
|
846
883
|
return node;
|
|
847
|
-
}, peg$
|
|
884
|
+
}, peg$c1567 = "arrange", peg$c1568 = peg$literalExpectation("arrange", false), peg$c1569 = function (value) {
|
|
848
885
|
const node = { key: 'arrange_declaration', value };
|
|
849
886
|
if (options.locations) {
|
|
850
887
|
node.loc = location();
|
|
851
888
|
}
|
|
852
889
|
return node;
|
|
853
|
-
}, peg$
|
|
890
|
+
}, peg$c1570 = "arrange-start", peg$c1571 = peg$literalExpectation("arrange-start", false), peg$c1572 = function (value) {
|
|
854
891
|
const node = { key: 'arrange_start_declaration', value };
|
|
855
892
|
if (options.locations) {
|
|
856
893
|
node.loc = location();
|
|
857
894
|
}
|
|
858
895
|
return node;
|
|
859
|
-
}, peg$
|
|
896
|
+
}, peg$c1573 = "arrange-end", peg$c1574 = peg$literalExpectation("arrange-end", false), peg$c1575 = function (value) {
|
|
860
897
|
const node = { key: 'arrange_end_declaration', value };
|
|
861
898
|
if (options.locations) {
|
|
862
899
|
node.loc = location();
|
|
863
900
|
}
|
|
864
901
|
return node;
|
|
865
|
-
}, peg$
|
|
902
|
+
}, peg$c1576 = peg$otherExpectation("oarrange declaration"), peg$c1577 = "oarrange", peg$c1578 = peg$literalExpectation("oarrange", false), peg$c1579 = function (value) {
|
|
866
903
|
const node = { key: 'oarrange_declaration', value };
|
|
867
904
|
if (options.locations) {
|
|
868
905
|
node.loc = location();
|
|
869
906
|
}
|
|
870
907
|
return node;
|
|
871
|
-
}, peg$
|
|
908
|
+
}, peg$c1580 = peg$otherExpectation("farrange declaration"), peg$c1581 = "farrange", peg$c1582 = peg$literalExpectation("farrange", false), peg$c1583 = function (value) {
|
|
872
909
|
const node = { key: 'farrange_declaration', value };
|
|
873
910
|
if (options.locations) {
|
|
874
911
|
node.loc = location();
|
|
875
912
|
}
|
|
876
913
|
return node;
|
|
877
|
-
}, peg$
|
|
914
|
+
}, peg$c1584 = peg$otherExpectation("arrange declaration"), peg$currPos = 0, peg$savedPos = 0, peg$posDetailsCache = [{ line: 1, column: 1 }], peg$maxFailPos = 0, peg$maxFailExpected = [], peg$silentFails = 0, peg$result;
|
|
878
915
|
if ("startRule" in options) {
|
|
879
916
|
if (!(options.startRule in peg$startRuleFunctions)) {
|
|
880
917
|
throw new Error("Can't start parsing from rule \"" + options.startRule + "\".");
|
|
@@ -19498,7 +19535,7 @@ function peg$parse(input, options) {
|
|
|
19498
19535
|
s7 = null;
|
|
19499
19536
|
}
|
|
19500
19537
|
if (s7 !== peg$FAILED) {
|
|
19501
|
-
s8 = peg$
|
|
19538
|
+
s8 = peg$parseGroupAliasMember();
|
|
19502
19539
|
if (s8 !== peg$FAILED) {
|
|
19503
19540
|
s9 = peg$parseWS();
|
|
19504
19541
|
if (s9 === peg$FAILED) {
|
|
@@ -19522,7 +19559,7 @@ function peg$parse(input, options) {
|
|
|
19522
19559
|
}
|
|
19523
19560
|
if (s11 !== peg$FAILED) {
|
|
19524
19561
|
peg$savedPos = s0;
|
|
19525
|
-
s1 = peg$
|
|
19562
|
+
s1 = peg$c1549(s4, s8);
|
|
19526
19563
|
s0 = s1;
|
|
19527
19564
|
}
|
|
19528
19565
|
else {
|
|
@@ -19582,35 +19619,46 @@ function peg$parse(input, options) {
|
|
|
19582
19619
|
}
|
|
19583
19620
|
return s0;
|
|
19584
19621
|
}
|
|
19622
|
+
function peg$parseGroupAliasMember() {
|
|
19623
|
+
var s0, s1;
|
|
19624
|
+
s0 = peg$currPos;
|
|
19625
|
+
s1 = peg$parseLabel();
|
|
19626
|
+
if (s1 !== peg$FAILED) {
|
|
19627
|
+
peg$savedPos = s0;
|
|
19628
|
+
s1 = peg$c1550(s1);
|
|
19629
|
+
}
|
|
19630
|
+
s0 = s1;
|
|
19631
|
+
return s0;
|
|
19632
|
+
}
|
|
19585
19633
|
function peg$parseHookEvent() {
|
|
19586
19634
|
var s0;
|
|
19587
19635
|
peg$silentFails++;
|
|
19588
|
-
if (input.substr(peg$currPos, 5) === peg$
|
|
19589
|
-
s0 = peg$
|
|
19636
|
+
if (input.substr(peg$currPos, 5) === peg$c1552) {
|
|
19637
|
+
s0 = peg$c1552;
|
|
19590
19638
|
peg$currPos += 5;
|
|
19591
19639
|
}
|
|
19592
19640
|
else {
|
|
19593
19641
|
s0 = peg$FAILED;
|
|
19594
19642
|
if (peg$silentFails === 0 && peg$currPos >= peg$maxFailPos) {
|
|
19595
|
-
peg$fail(peg$
|
|
19643
|
+
peg$fail(peg$c1553);
|
|
19596
19644
|
}
|
|
19597
19645
|
}
|
|
19598
19646
|
if (s0 === peg$FAILED) {
|
|
19599
|
-
if (input.substr(peg$currPos, 4) === peg$
|
|
19600
|
-
s0 = peg$
|
|
19647
|
+
if (input.substr(peg$currPos, 4) === peg$c1554) {
|
|
19648
|
+
s0 = peg$c1554;
|
|
19601
19649
|
peg$currPos += 4;
|
|
19602
19650
|
}
|
|
19603
19651
|
else {
|
|
19604
19652
|
s0 = peg$FAILED;
|
|
19605
19653
|
if (peg$silentFails === 0 && peg$currPos >= peg$maxFailPos) {
|
|
19606
|
-
peg$fail(peg$
|
|
19654
|
+
peg$fail(peg$c1555);
|
|
19607
19655
|
}
|
|
19608
19656
|
}
|
|
19609
19657
|
}
|
|
19610
19658
|
peg$silentFails--;
|
|
19611
19659
|
if (s0 === peg$FAILED) {
|
|
19612
19660
|
if (peg$silentFails === 0 && peg$currPos >= peg$maxFailPos) {
|
|
19613
|
-
peg$fail(peg$
|
|
19661
|
+
peg$fail(peg$c1551);
|
|
19614
19662
|
}
|
|
19615
19663
|
}
|
|
19616
19664
|
return s0;
|
|
@@ -19624,14 +19672,14 @@ function peg$parse(input, options) {
|
|
|
19624
19672
|
s1 = null;
|
|
19625
19673
|
}
|
|
19626
19674
|
if (s1 !== peg$FAILED) {
|
|
19627
|
-
if (input.substr(peg$currPos, 2) === peg$
|
|
19628
|
-
s2 = peg$
|
|
19675
|
+
if (input.substr(peg$currPos, 2) === peg$c1557) {
|
|
19676
|
+
s2 = peg$c1557;
|
|
19629
19677
|
peg$currPos += 2;
|
|
19630
19678
|
}
|
|
19631
19679
|
else {
|
|
19632
19680
|
s2 = peg$FAILED;
|
|
19633
19681
|
if (peg$silentFails === 0 && peg$currPos >= peg$maxFailPos) {
|
|
19634
|
-
peg$fail(peg$
|
|
19682
|
+
peg$fail(peg$c1558);
|
|
19635
19683
|
}
|
|
19636
19684
|
}
|
|
19637
19685
|
if (s2 !== peg$FAILED) {
|
|
@@ -19643,19 +19691,19 @@ function peg$parse(input, options) {
|
|
|
19643
19691
|
if (s5 !== peg$FAILED) {
|
|
19644
19692
|
s6 = peg$parseGroupRef();
|
|
19645
19693
|
if (s6 === peg$FAILED) {
|
|
19646
|
-
s6 = peg$
|
|
19694
|
+
s6 = peg$parseHookStateSubject();
|
|
19647
19695
|
}
|
|
19648
19696
|
if (s6 !== peg$FAILED) {
|
|
19649
19697
|
s7 = peg$parseWS();
|
|
19650
19698
|
if (s7 !== peg$FAILED) {
|
|
19651
|
-
if (input.substr(peg$currPos, 2) === peg$
|
|
19652
|
-
s8 = peg$
|
|
19699
|
+
if (input.substr(peg$currPos, 2) === peg$c1559) {
|
|
19700
|
+
s8 = peg$c1559;
|
|
19653
19701
|
peg$currPos += 2;
|
|
19654
19702
|
}
|
|
19655
19703
|
else {
|
|
19656
19704
|
s8 = peg$FAILED;
|
|
19657
19705
|
if (peg$silentFails === 0 && peg$currPos >= peg$maxFailPos) {
|
|
19658
|
-
peg$fail(peg$
|
|
19706
|
+
peg$fail(peg$c1560);
|
|
19659
19707
|
}
|
|
19660
19708
|
}
|
|
19661
19709
|
if (s8 !== peg$FAILED) {
|
|
@@ -19685,7 +19733,7 @@ function peg$parse(input, options) {
|
|
|
19685
19733
|
}
|
|
19686
19734
|
if (s13 !== peg$FAILED) {
|
|
19687
19735
|
peg$savedPos = s0;
|
|
19688
|
-
s1 = peg$
|
|
19736
|
+
s1 = peg$c1561(s4, s6, s10);
|
|
19689
19737
|
s0 = s1;
|
|
19690
19738
|
}
|
|
19691
19739
|
else {
|
|
@@ -19756,11 +19804,22 @@ function peg$parse(input, options) {
|
|
|
19756
19804
|
if (s0 === peg$FAILED) {
|
|
19757
19805
|
s1 = peg$FAILED;
|
|
19758
19806
|
if (peg$silentFails === 0 && peg$currPos >= peg$maxFailPos) {
|
|
19759
|
-
peg$fail(peg$
|
|
19807
|
+
peg$fail(peg$c1556);
|
|
19760
19808
|
}
|
|
19761
19809
|
}
|
|
19762
19810
|
return s0;
|
|
19763
19811
|
}
|
|
19812
|
+
function peg$parseHookStateSubject() {
|
|
19813
|
+
var s0, s1;
|
|
19814
|
+
s0 = peg$currPos;
|
|
19815
|
+
s1 = peg$parseLabel();
|
|
19816
|
+
if (s1 !== peg$FAILED) {
|
|
19817
|
+
peg$savedPos = s0;
|
|
19818
|
+
s1 = peg$c1562(s1);
|
|
19819
|
+
}
|
|
19820
|
+
s0 = s1;
|
|
19821
|
+
return s0;
|
|
19822
|
+
}
|
|
19764
19823
|
function peg$parseMachineProperty() {
|
|
19765
19824
|
var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13;
|
|
19766
19825
|
s0 = peg$currPos;
|
|
@@ -19836,7 +19895,7 @@ function peg$parse(input, options) {
|
|
|
19836
19895
|
}
|
|
19837
19896
|
if (s13 !== peg$FAILED) {
|
|
19838
19897
|
peg$savedPos = s0;
|
|
19839
|
-
s1 = peg$
|
|
19898
|
+
s1 = peg$c1563(s4, s8);
|
|
19840
19899
|
s0 = s1;
|
|
19841
19900
|
}
|
|
19842
19901
|
else {
|
|
@@ -19960,7 +20019,7 @@ function peg$parse(input, options) {
|
|
|
19960
20019
|
}
|
|
19961
20020
|
if (s9 !== peg$FAILED) {
|
|
19962
20021
|
peg$savedPos = s0;
|
|
19963
|
-
s1 = peg$
|
|
20022
|
+
s1 = peg$c1564(s4);
|
|
19964
20023
|
s0 = s1;
|
|
19965
20024
|
}
|
|
19966
20025
|
else {
|
|
@@ -20068,7 +20127,7 @@ function peg$parse(input, options) {
|
|
|
20068
20127
|
}
|
|
20069
20128
|
if (s11 !== peg$FAILED) {
|
|
20070
20129
|
peg$savedPos = s0;
|
|
20071
|
-
s1 = peg$
|
|
20130
|
+
s1 = peg$c1565(s4, s8);
|
|
20072
20131
|
s0 = s1;
|
|
20073
20132
|
}
|
|
20074
20133
|
else {
|
|
@@ -20169,7 +20228,7 @@ function peg$parse(input, options) {
|
|
|
20169
20228
|
}
|
|
20170
20229
|
if (s7 !== peg$FAILED) {
|
|
20171
20230
|
peg$savedPos = s0;
|
|
20172
|
-
s1 = peg$
|
|
20231
|
+
s1 = peg$c1566(s4);
|
|
20173
20232
|
s0 = s1;
|
|
20174
20233
|
}
|
|
20175
20234
|
else {
|
|
@@ -20214,14 +20273,14 @@ function peg$parse(input, options) {
|
|
|
20214
20273
|
function peg$parseRegularArrangeDeclaration() {
|
|
20215
20274
|
var s0, s1, s2, s3, s4, s5, s6;
|
|
20216
20275
|
s0 = peg$currPos;
|
|
20217
|
-
if (input.substr(peg$currPos, 7) === peg$
|
|
20218
|
-
s1 = peg$
|
|
20276
|
+
if (input.substr(peg$currPos, 7) === peg$c1567) {
|
|
20277
|
+
s1 = peg$c1567;
|
|
20219
20278
|
peg$currPos += 7;
|
|
20220
20279
|
}
|
|
20221
20280
|
else {
|
|
20222
20281
|
s1 = peg$FAILED;
|
|
20223
20282
|
if (peg$silentFails === 0 && peg$currPos >= peg$maxFailPos) {
|
|
20224
|
-
peg$fail(peg$
|
|
20283
|
+
peg$fail(peg$c1568);
|
|
20225
20284
|
}
|
|
20226
20285
|
}
|
|
20227
20286
|
if (s1 !== peg$FAILED) {
|
|
@@ -20254,7 +20313,7 @@ function peg$parse(input, options) {
|
|
|
20254
20313
|
}
|
|
20255
20314
|
if (s6 !== peg$FAILED) {
|
|
20256
20315
|
peg$savedPos = s0;
|
|
20257
|
-
s1 = peg$
|
|
20316
|
+
s1 = peg$c1569(s3);
|
|
20258
20317
|
s0 = s1;
|
|
20259
20318
|
}
|
|
20260
20319
|
else {
|
|
@@ -20291,14 +20350,14 @@ function peg$parse(input, options) {
|
|
|
20291
20350
|
function peg$parseArrangeStartDeclaration() {
|
|
20292
20351
|
var s0, s1, s2, s3, s4, s5, s6;
|
|
20293
20352
|
s0 = peg$currPos;
|
|
20294
|
-
if (input.substr(peg$currPos, 13) === peg$
|
|
20295
|
-
s1 = peg$
|
|
20353
|
+
if (input.substr(peg$currPos, 13) === peg$c1570) {
|
|
20354
|
+
s1 = peg$c1570;
|
|
20296
20355
|
peg$currPos += 13;
|
|
20297
20356
|
}
|
|
20298
20357
|
else {
|
|
20299
20358
|
s1 = peg$FAILED;
|
|
20300
20359
|
if (peg$silentFails === 0 && peg$currPos >= peg$maxFailPos) {
|
|
20301
|
-
peg$fail(peg$
|
|
20360
|
+
peg$fail(peg$c1571);
|
|
20302
20361
|
}
|
|
20303
20362
|
}
|
|
20304
20363
|
if (s1 !== peg$FAILED) {
|
|
@@ -20331,7 +20390,7 @@ function peg$parse(input, options) {
|
|
|
20331
20390
|
}
|
|
20332
20391
|
if (s6 !== peg$FAILED) {
|
|
20333
20392
|
peg$savedPos = s0;
|
|
20334
|
-
s1 = peg$
|
|
20393
|
+
s1 = peg$c1572(s3);
|
|
20335
20394
|
s0 = s1;
|
|
20336
20395
|
}
|
|
20337
20396
|
else {
|
|
@@ -20368,14 +20427,14 @@ function peg$parse(input, options) {
|
|
|
20368
20427
|
function peg$parseArrangeEndDeclaration() {
|
|
20369
20428
|
var s0, s1, s2, s3, s4, s5, s6;
|
|
20370
20429
|
s0 = peg$currPos;
|
|
20371
|
-
if (input.substr(peg$currPos, 11) === peg$
|
|
20372
|
-
s1 = peg$
|
|
20430
|
+
if (input.substr(peg$currPos, 11) === peg$c1573) {
|
|
20431
|
+
s1 = peg$c1573;
|
|
20373
20432
|
peg$currPos += 11;
|
|
20374
20433
|
}
|
|
20375
20434
|
else {
|
|
20376
20435
|
s1 = peg$FAILED;
|
|
20377
20436
|
if (peg$silentFails === 0 && peg$currPos >= peg$maxFailPos) {
|
|
20378
|
-
peg$fail(peg$
|
|
20437
|
+
peg$fail(peg$c1574);
|
|
20379
20438
|
}
|
|
20380
20439
|
}
|
|
20381
20440
|
if (s1 !== peg$FAILED) {
|
|
@@ -20408,7 +20467,7 @@ function peg$parse(input, options) {
|
|
|
20408
20467
|
}
|
|
20409
20468
|
if (s6 !== peg$FAILED) {
|
|
20410
20469
|
peg$savedPos = s0;
|
|
20411
|
-
s1 = peg$
|
|
20470
|
+
s1 = peg$c1575(s3);
|
|
20412
20471
|
s0 = s1;
|
|
20413
20472
|
}
|
|
20414
20473
|
else {
|
|
@@ -20446,14 +20505,14 @@ function peg$parse(input, options) {
|
|
|
20446
20505
|
var s0, s1, s2, s3, s4, s5, s6;
|
|
20447
20506
|
peg$silentFails++;
|
|
20448
20507
|
s0 = peg$currPos;
|
|
20449
|
-
if (input.substr(peg$currPos, 8) === peg$
|
|
20450
|
-
s1 = peg$
|
|
20508
|
+
if (input.substr(peg$currPos, 8) === peg$c1577) {
|
|
20509
|
+
s1 = peg$c1577;
|
|
20451
20510
|
peg$currPos += 8;
|
|
20452
20511
|
}
|
|
20453
20512
|
else {
|
|
20454
20513
|
s1 = peg$FAILED;
|
|
20455
20514
|
if (peg$silentFails === 0 && peg$currPos >= peg$maxFailPos) {
|
|
20456
|
-
peg$fail(peg$
|
|
20515
|
+
peg$fail(peg$c1578);
|
|
20457
20516
|
}
|
|
20458
20517
|
}
|
|
20459
20518
|
if (s1 !== peg$FAILED) {
|
|
@@ -20486,7 +20545,7 @@ function peg$parse(input, options) {
|
|
|
20486
20545
|
}
|
|
20487
20546
|
if (s6 !== peg$FAILED) {
|
|
20488
20547
|
peg$savedPos = s0;
|
|
20489
|
-
s1 = peg$
|
|
20548
|
+
s1 = peg$c1579(s3);
|
|
20490
20549
|
s0 = s1;
|
|
20491
20550
|
}
|
|
20492
20551
|
else {
|
|
@@ -20522,7 +20581,7 @@ function peg$parse(input, options) {
|
|
|
20522
20581
|
if (s0 === peg$FAILED) {
|
|
20523
20582
|
s1 = peg$FAILED;
|
|
20524
20583
|
if (peg$silentFails === 0 && peg$currPos >= peg$maxFailPos) {
|
|
20525
|
-
peg$fail(peg$
|
|
20584
|
+
peg$fail(peg$c1576);
|
|
20526
20585
|
}
|
|
20527
20586
|
}
|
|
20528
20587
|
return s0;
|
|
@@ -20531,14 +20590,14 @@ function peg$parse(input, options) {
|
|
|
20531
20590
|
var s0, s1, s2, s3, s4, s5, s6;
|
|
20532
20591
|
peg$silentFails++;
|
|
20533
20592
|
s0 = peg$currPos;
|
|
20534
|
-
if (input.substr(peg$currPos, 8) === peg$
|
|
20535
|
-
s1 = peg$
|
|
20593
|
+
if (input.substr(peg$currPos, 8) === peg$c1581) {
|
|
20594
|
+
s1 = peg$c1581;
|
|
20536
20595
|
peg$currPos += 8;
|
|
20537
20596
|
}
|
|
20538
20597
|
else {
|
|
20539
20598
|
s1 = peg$FAILED;
|
|
20540
20599
|
if (peg$silentFails === 0 && peg$currPos >= peg$maxFailPos) {
|
|
20541
|
-
peg$fail(peg$
|
|
20600
|
+
peg$fail(peg$c1582);
|
|
20542
20601
|
}
|
|
20543
20602
|
}
|
|
20544
20603
|
if (s1 !== peg$FAILED) {
|
|
@@ -20571,7 +20630,7 @@ function peg$parse(input, options) {
|
|
|
20571
20630
|
}
|
|
20572
20631
|
if (s6 !== peg$FAILED) {
|
|
20573
20632
|
peg$savedPos = s0;
|
|
20574
|
-
s1 = peg$
|
|
20633
|
+
s1 = peg$c1583(s3);
|
|
20575
20634
|
s0 = s1;
|
|
20576
20635
|
}
|
|
20577
20636
|
else {
|
|
@@ -20607,7 +20666,7 @@ function peg$parse(input, options) {
|
|
|
20607
20666
|
if (s0 === peg$FAILED) {
|
|
20608
20667
|
s1 = peg$FAILED;
|
|
20609
20668
|
if (peg$silentFails === 0 && peg$currPos >= peg$maxFailPos) {
|
|
20610
|
-
peg$fail(peg$
|
|
20669
|
+
peg$fail(peg$c1580);
|
|
20611
20670
|
}
|
|
20612
20671
|
}
|
|
20613
20672
|
return s0;
|
|
@@ -20631,7 +20690,7 @@ function peg$parse(input, options) {
|
|
|
20631
20690
|
peg$silentFails--;
|
|
20632
20691
|
if (s0 === peg$FAILED) {
|
|
20633
20692
|
if (peg$silentFails === 0 && peg$currPos >= peg$maxFailPos) {
|
|
20634
|
-
peg$fail(peg$
|
|
20693
|
+
peg$fail(peg$c1584);
|
|
20635
20694
|
}
|
|
20636
20695
|
}
|
|
20637
20696
|
return s0;
|
|
@@ -23625,7 +23684,8 @@ var constants = /*#__PURE__*/Object.freeze({
|
|
|
23625
23684
|
const HEX8 = /^#[0-9a-f]{8}$/i;
|
|
23626
23685
|
/** AST keys that hold source locations, not child nodes to recurse into. */
|
|
23627
23686
|
const LOC_KEYS = new Set(['loc', 'value_loc', 'name_loc', 'from_loc', 'to_loc',
|
|
23628
|
-
'r_action_loc', 'l_action_loc'
|
|
23687
|
+
'r_action_loc', 'l_action_loc', 'value_locs',
|
|
23688
|
+
'subject_loc', '__loc']);
|
|
23629
23689
|
/** State-declaration item keys whose value is an enum lacking a value-precise loc. */
|
|
23630
23690
|
const ENUM_VALUE_KEYS = new Set(['shape']);
|
|
23631
23691
|
/** Locate a value substring inside a node's full-statement `loc` span. The
|
|
@@ -23662,6 +23722,31 @@ function collect(node, text, out) {
|
|
|
23662
23722
|
if (ENUM_VALUE_KEYS.has(n.key) && typeof n.value === 'string' && n.loc && !n.value_loc) {
|
|
23663
23723
|
out.push(Object.assign(Object.assign({}, valueSpanWithin(text, n.loc, n.value)), { kind: 'enum' }));
|
|
23664
23724
|
}
|
|
23725
|
+
// group declarations (`&G : [a b c];` / `&G : a;`): every plain member is a
|
|
23726
|
+
// state reference. The grammar supplies value_locs parallel to value, so
|
|
23727
|
+
// positions come from the parser, never from text search. Nest/spread
|
|
23728
|
+
// entries (`&child` / `...&child`) are group references, not states, and
|
|
23729
|
+
// the group's own NAME is deliberately not a state span either.
|
|
23730
|
+
if (n.key === 'named_list') {
|
|
23731
|
+
const members = Array.isArray(n.value) ? n.value : [n.value];
|
|
23732
|
+
members.forEach((member, i) => {
|
|
23733
|
+
const m = member;
|
|
23734
|
+
const name = typeof m === 'string' ? m
|
|
23735
|
+
: m.kind === 'state' ? m.name
|
|
23736
|
+
: null;
|
|
23737
|
+
if (name !== null) {
|
|
23738
|
+
const at = n.value_locs[i];
|
|
23739
|
+
out.push({ from: at.start.offset, to: at.end.offset, kind: 'state', value: name });
|
|
23740
|
+
}
|
|
23741
|
+
});
|
|
23742
|
+
}
|
|
23743
|
+
// hook declarations (`on enter x do 'act';`): a plain-label subject is a
|
|
23744
|
+
// state reference and carries a grammar-supplied subject_loc. Group-ref
|
|
23745
|
+
// subjects (`on exit &G …`) are group references, not states — no
|
|
23746
|
+
// subject_loc, no span.
|
|
23747
|
+
if (n.key === 'hook_decl' && n.subject_loc) {
|
|
23748
|
+
out.push({ from: n.subject_loc.start.offset, to: n.subject_loc.end.offset, kind: 'state', value: n.subject });
|
|
23749
|
+
}
|
|
23665
23750
|
for (const key of Object.keys(n)) {
|
|
23666
23751
|
if (!LOC_KEYS.has(key)) {
|
|
23667
23752
|
collect(n[key], text, out);
|
|
@@ -23669,11 +23754,21 @@ function collect(node, text, out) {
|
|
|
23669
23754
|
}
|
|
23670
23755
|
}
|
|
23671
23756
|
/**
|
|
23672
|
-
* Collect color / state / shape-enum semantic spans from `text`.
|
|
23757
|
+
* Collect color / state / shape-enum semantic spans from `text`. State spans
|
|
23758
|
+
* cover transition endpoints, state-declaration subjects, group-list members
|
|
23759
|
+
* (`&G : [a b c];` — but not the group's own name, nor `&`/`...&` nested
|
|
23760
|
+
* group references), and plain-label hook subjects (`on enter x do 'act';` —
|
|
23761
|
+
* but not `&group` subjects). Every state span's `value` is the parser's
|
|
23762
|
+
* resolved name (unquoted, unescaped), while `from`/`to` cover the source
|
|
23763
|
+
* spelling including any quotes.
|
|
23673
23764
|
*
|
|
23674
23765
|
* @example
|
|
23675
23766
|
* fslSemanticSpans('state s : { color: crimson; };')
|
|
23676
23767
|
* .find(s => s.kind === 'color')?.value; // => '#dc143cff'
|
|
23768
|
+
*
|
|
23769
|
+
* @example
|
|
23770
|
+
* fslSemanticSpans('&G : [a b];\na -> b;')
|
|
23771
|
+
* .filter(s => s.kind === 'state').length; // => 4 (two members + two endpoints)
|
|
23677
23772
|
*/
|
|
23678
23773
|
function fslSemanticSpans(text) {
|
|
23679
23774
|
let tree;
|
|
@@ -23694,7 +23789,7 @@ function fslSemanticSpans(text) {
|
|
|
23694
23789
|
* Useful for runtime diagnostics and for embedding in serialized machine
|
|
23695
23790
|
* snapshots so that deserializers can detect version-skew.
|
|
23696
23791
|
*/
|
|
23697
|
-
const version = "5.
|
|
23792
|
+
const version = "5.159.1";
|
|
23698
23793
|
|
|
23699
23794
|
/**
|
|
23700
23795
|
* The FSL Markdown fence convention parser — pure, host-agnostic logic that
|
|
@@ -29379,6 +29474,26 @@ function vc(col) {
|
|
|
29379
29474
|
function doublequote(txt) {
|
|
29380
29475
|
return txt.replace(/"/g, '\\"');
|
|
29381
29476
|
}
|
|
29477
|
+
/**
|
|
29478
|
+
* Reverse {@link doublequote}: turn DOT's `\"` escape back into the literal
|
|
29479
|
+
* `"` that graphviz renders into SVG `<text>` content. Used by
|
|
29480
|
+
* {@link state_svg_label_texts} to reconstruct a node's on-screen label from
|
|
29481
|
+
* the DOT label it was handed, so the fence renderer keys against exactly what
|
|
29482
|
+
* was drawn.
|
|
29483
|
+
*
|
|
29484
|
+
* ```typescript
|
|
29485
|
+
* undoublequote('a\\"b'); // 'a"b'
|
|
29486
|
+
* undoublequote('safe'); // 'safe'
|
|
29487
|
+
* ```
|
|
29488
|
+
*
|
|
29489
|
+
* @param txt A DOT-escaped attribute string (as produced by `doublequote`).
|
|
29490
|
+
* @returns The string with every `\"` collapsed back to `"`.
|
|
29491
|
+
*
|
|
29492
|
+
* @internal
|
|
29493
|
+
*/
|
|
29494
|
+
function undoublequote(txt) {
|
|
29495
|
+
return txt.replace(/\\"/g, '"');
|
|
29496
|
+
}
|
|
29382
29497
|
/**
|
|
29383
29498
|
* Convert a state name into a URL-friendly slug suitable for use as the
|
|
29384
29499
|
* body of a dot/SVG node identifier. The transformation is:
|
|
@@ -30262,6 +30377,71 @@ function node_block_for(u_jssm, l_states, state_index, state_kinds, hide_labels,
|
|
|
30262
30377
|
const { clusters, ungrouped_nodes } = groups_to_subgraph_string(u_jssm, l_states, state_index, state_kinds, hide_labels);
|
|
30263
30378
|
return `${clusters}${(clusters && ungrouped_nodes) ? ' ' : ''}${ungrouped_nodes}`;
|
|
30264
30379
|
}
|
|
30380
|
+
/**
|
|
30381
|
+
* The per-state group-chip map that {@link node_block_for} appends to labels
|
|
30382
|
+
* in a given render mode. Mirrors that function's mode dispatch and calls the
|
|
30383
|
+
* very same chip sources — {@link chips_for_all_groups} for `'chips'`,
|
|
30384
|
+
* {@link plan_cluster_groups} (with identical inputs) for `'cluster'` — so a
|
|
30385
|
+
* reconstructed label can never disagree with the one graphviz was handed.
|
|
30386
|
+
* `'off'`, and any machine that declares no groups, yields an empty map.
|
|
30387
|
+
*
|
|
30388
|
+
* @internal
|
|
30389
|
+
*/
|
|
30390
|
+
function chips_for_render_mode(u_jssm, l_states, mode) {
|
|
30391
|
+
if ((mode === 'off') || (u_jssm.groups().length === 0)) {
|
|
30392
|
+
return new Map();
|
|
30393
|
+
}
|
|
30394
|
+
if (mode === 'chips') {
|
|
30395
|
+
return chips_for_all_groups(u_jssm, l_states);
|
|
30396
|
+
}
|
|
30397
|
+
const order = u_jssm.groups();
|
|
30398
|
+
const parents = group_parent_map(u_jssm._group_registry, order);
|
|
30399
|
+
return plan_cluster_groups(u_jssm, l_states, order, parents).chips;
|
|
30400
|
+
}
|
|
30401
|
+
/**
|
|
30402
|
+
* The exact text graphviz places in each state's SVG `<text>` element(s) when
|
|
30403
|
+
* a machine is rendered via {@link machine_to_dot} / {@link fsl_to_svg_string}:
|
|
30404
|
+
* the state's display text plus any group chips the node builder appends, with
|
|
30405
|
+
* DOT's `\"` escaping undone (SVG carries the literal character). A label that
|
|
30406
|
+
* wraps across lines becomes several `<text>` elements; this returns the lines
|
|
30407
|
+
* joined by `\n`, exactly how {@link extract_state_fills} reads them back — so
|
|
30408
|
+
* the derived key and the extracted key meet at the same string.
|
|
30409
|
+
*
|
|
30410
|
+
* This is the single source of truth the static fence renderer keys its
|
|
30411
|
+
* highlight and recolor lookups against, so those lookups can never drift from
|
|
30412
|
+
* what was actually drawn — plain labels, group chips, and multi-line wraps
|
|
30413
|
+
* alike. It is built by running the node builder's own
|
|
30414
|
+
* `label_with_chips(doublequote(display_text), chips)` and inverting the one
|
|
30415
|
+
* escaping step, so it follows any change to the label format for free.
|
|
30416
|
+
*
|
|
30417
|
+
* @param u_jssm The machine being rendered.
|
|
30418
|
+
* @param opts Render flags; only `render_groups` affects the label text
|
|
30419
|
+
* (default `'cluster'`, matching `fsl_to_svg_string`).
|
|
30420
|
+
* @returns A map from each state name to its rendered SVG label text.
|
|
30421
|
+
*
|
|
30422
|
+
* ```typescript
|
|
30423
|
+
* import { sm } from 'jssm';
|
|
30424
|
+
* import { state_svg_label_texts } from 'jssm/viz';
|
|
30425
|
+
*
|
|
30426
|
+
* // a state in two groups renders a chip suffix in its node label
|
|
30427
|
+
* state_svg_label_texts(sm`&g1 : [a b]; &g2 : [a]; a -> b;`).get('a'); // 'a [g1]'
|
|
30428
|
+
* state_svg_label_texts(sm`a -> b;`).get('a'); // 'a'
|
|
30429
|
+
* ```
|
|
30430
|
+
*
|
|
30431
|
+
* @see extract_state_fills
|
|
30432
|
+
*/
|
|
30433
|
+
function state_svg_label_texts(u_jssm, opts = {}) {
|
|
30434
|
+
var _a, _b;
|
|
30435
|
+
const l_states = u_jssm.states();
|
|
30436
|
+
const mode = (_a = opts.render_groups) !== null && _a !== void 0 ? _a : 'cluster';
|
|
30437
|
+
const chips = chips_for_render_mode(u_jssm, l_states, mode);
|
|
30438
|
+
const out = new Map();
|
|
30439
|
+
for (const s of l_states) {
|
|
30440
|
+
const dot_label = label_with_chips(doublequote(u_jssm.display_text(s)), (_b = chips.get(s)) !== null && _b !== void 0 ? _b : []);
|
|
30441
|
+
out.set(s, undoublequote(dot_label));
|
|
30442
|
+
}
|
|
30443
|
+
return out;
|
|
30444
|
+
}
|
|
30265
30445
|
/**
|
|
30266
30446
|
* Render a {@link jssm.Machine} as a graphviz dot string.
|
|
30267
30447
|
*
|
|
@@ -30378,6 +30558,17 @@ async function fsl_to_svg_string(fsl, opts = {}) {
|
|
|
30378
30558
|
return dot_to_svg(fsl_to_dot(fsl, opts), opts);
|
|
30379
30559
|
}
|
|
30380
30560
|
|
|
30561
|
+
/**
|
|
30562
|
+
* The render targets supported in v1, in canonical order (the CLI `--target`
|
|
30563
|
+
* enum and `--help` list order). This tuple is the single runtime source of
|
|
30564
|
+
* truth: both the {@link RenderTarget} type and the `fsl-render` CLI's
|
|
30565
|
+
* `--target` enum derive from it, so a new target is declared in exactly one
|
|
30566
|
+
* place. Future targets (mermaid, plantuml, scxml, ascii, fsl) land here in
|
|
30567
|
+
* v0.2+.
|
|
30568
|
+
*
|
|
30569
|
+
* @example
|
|
30570
|
+
* RENDER_TARGETS.includes('gif' as RenderTarget); // true
|
|
30571
|
+
*/
|
|
30381
30572
|
/**
|
|
30382
30573
|
* Base error class for render-time failures.
|
|
30383
30574
|
*/
|
|
@@ -31235,8 +31426,22 @@ function xml_unescape(s) {
|
|
|
31235
31426
|
}
|
|
31236
31427
|
/** Match one graphviz node group; capture [1] the group body. @internal */
|
|
31237
31428
|
const NODE_GROUP_RE = /<g[^>]*\bclass="node"[^>]*>([\s\S]*?)<\/g>/g;
|
|
31238
|
-
const
|
|
31429
|
+
const TEXT_RE_G = /<text[^>]*>([\s\S]*?)<\/text>/g;
|
|
31239
31430
|
const SHAPE_FILL_RE = /(<(?:ellipse|polygon|path)\b[^>]*\bfill=")([^"]*)(")/;
|
|
31431
|
+
/**
|
|
31432
|
+
* The state key for one node group: the XML-unescaped content of *every* one
|
|
31433
|
+
* of its `<text>` elements, joined by `\n`. Graphviz splits a label that
|
|
31434
|
+
* wraps across lines into one `<text>` per line, so reading only the first
|
|
31435
|
+
* would key on a truncated string; joining the lines with `\n` reconstructs
|
|
31436
|
+
* the machine's display text exactly (matching `state_svg_label_texts`).
|
|
31437
|
+
* Returns `null` for a node group carrying no `<text>` element at all.
|
|
31438
|
+
*
|
|
31439
|
+
* @internal
|
|
31440
|
+
*/
|
|
31441
|
+
function node_label_text(body) {
|
|
31442
|
+
const lines = [...body.matchAll(TEXT_RE_G)].map(m => xml_unescape(m[1]));
|
|
31443
|
+
return lines.length === 0 ? null : lines.join('\n');
|
|
31444
|
+
}
|
|
31240
31445
|
/**
|
|
31241
31446
|
* Read each state's current fill color out of a graphviz-rendered machine
|
|
31242
31447
|
* SVG, keyed by state name. States whose shape carries no `fill` attribute
|
|
@@ -31253,13 +31458,10 @@ function extract_state_fills(svg) {
|
|
|
31253
31458
|
const out = new Map();
|
|
31254
31459
|
for (const group of svg.matchAll(NODE_GROUP_RE)) {
|
|
31255
31460
|
const body = group[1];
|
|
31256
|
-
const
|
|
31461
|
+
const label = node_label_text(body);
|
|
31257
31462
|
const shape = body.match(SHAPE_FILL_RE);
|
|
31258
|
-
if (shape !== null &&
|
|
31259
|
-
|
|
31260
|
-
if (state_name) {
|
|
31261
|
-
out.set(state_name, shape[2]);
|
|
31262
|
-
}
|
|
31463
|
+
if (shape !== null && label !== null && label !== '') {
|
|
31464
|
+
out.set(label, shape[2]);
|
|
31263
31465
|
}
|
|
31264
31466
|
}
|
|
31265
31467
|
return out;
|
|
@@ -31284,11 +31486,11 @@ function patch_state_fill(svg, state, fill) {
|
|
|
31284
31486
|
if (done) {
|
|
31285
31487
|
return whole;
|
|
31286
31488
|
}
|
|
31287
|
-
const
|
|
31288
|
-
if (
|
|
31489
|
+
const label = node_label_text(body);
|
|
31490
|
+
if (label === null) {
|
|
31289
31491
|
return whole;
|
|
31290
31492
|
}
|
|
31291
|
-
if (
|
|
31493
|
+
if (label !== state) {
|
|
31292
31494
|
return whole;
|
|
31293
31495
|
}
|
|
31294
31496
|
// Function-form replacements: `fill` is caller-supplied and may itself
|
|
@@ -48763,7 +48965,8 @@ function quantize(rgba, max_colors = 256) {
|
|
|
48763
48965
|
throw new JssmError(undefined, 'quantize: max_colors must be 2..256');
|
|
48764
48966
|
}
|
|
48765
48967
|
const pixel_count = rgba.length / 4;
|
|
48766
|
-
// composite over white, build histogram of packed rgb keys
|
|
48968
|
+
// composite over white, build histogram of packed rgb keys (packed[] retained
|
|
48969
|
+
// so the per-pixel index step below need not recompute the keys)
|
|
48767
48970
|
const packed = new Uint32Array(pixel_count);
|
|
48768
48971
|
const histogram = new Map();
|
|
48769
48972
|
for (let i = 0; i < pixel_count; ++i) {
|
|
@@ -48771,6 +48974,48 @@ function quantize(rgba, max_colors = 256) {
|
|
|
48771
48974
|
packed[i] = key;
|
|
48772
48975
|
histogram.set(key, ((_a = histogram.get(key)) !== null && _a !== void 0 ? _a : 0) + 1);
|
|
48773
48976
|
}
|
|
48977
|
+
const { palette, palette_count, index_of } = palette_from_histogram(histogram, max_colors);
|
|
48978
|
+
const indices = new Uint8Array(pixel_count);
|
|
48979
|
+
for (let i = 0; i < pixel_count; ++i) {
|
|
48980
|
+
indices[i] = index_of.get(packed[i]);
|
|
48981
|
+
}
|
|
48982
|
+
return { palette, palette_count, indices };
|
|
48983
|
+
}
|
|
48984
|
+
/**
|
|
48985
|
+
* Accumulate one RGBA frame's composited-over-white colors into a shared
|
|
48986
|
+
* packed-rgb histogram, so an animation's union palette can be built by
|
|
48987
|
+
* streaming frame-by-frame instead of concatenating every frame's pixels into
|
|
48988
|
+
* one buffer first. Iterating frames in order reproduces the exact key/count
|
|
48989
|
+
* sequence a concatenated buffer would yield, so the resulting palette is
|
|
48990
|
+
* byte-identical to quantizing the concatenation.
|
|
48991
|
+
*
|
|
48992
|
+
* @param rgba - Straight RGBA bytes; length must be a multiple of 4.
|
|
48993
|
+
* @param histogram - Packed 0xRRGGBB key → count, mutated in place.
|
|
48994
|
+
*
|
|
48995
|
+
* @example
|
|
48996
|
+
* const h = new Map<number, number>();
|
|
48997
|
+
* accumulate_histogram(new Uint8Array([255,0,0,255]), h); // h: { 0xff0000 => 1 }
|
|
48998
|
+
*
|
|
48999
|
+
* @internal
|
|
49000
|
+
*/
|
|
49001
|
+
function accumulate_histogram(rgba, histogram) {
|
|
49002
|
+
var _a;
|
|
49003
|
+
const pixel_count = rgba.length / 4;
|
|
49004
|
+
for (let i = 0; i < pixel_count; ++i) {
|
|
49005
|
+
const key = packed_over_white(rgba, i);
|
|
49006
|
+
histogram.set(key, ((_a = histogram.get(key)) !== null && _a !== void 0 ? _a : 0) + 1);
|
|
49007
|
+
}
|
|
49008
|
+
}
|
|
49009
|
+
/**
|
|
49010
|
+
* Derive a color palette from a packed-rgb histogram: when the histogram holds
|
|
49011
|
+
* `max_colors` or fewer distinct colors they are preserved exactly (in
|
|
49012
|
+
* insertion order); otherwise a median-cut partition supplies the palette.
|
|
49013
|
+
* Returned alongside the palette is `index_of`, mapping each source color key
|
|
49014
|
+
* to its palette slot, so callers can translate their own pixels.
|
|
49015
|
+
*
|
|
49016
|
+
* @internal
|
|
49017
|
+
*/
|
|
49018
|
+
function palette_from_histogram(histogram, max_colors) {
|
|
48774
49019
|
const distinct = [...histogram.keys()];
|
|
48775
49020
|
if (distinct.length <= max_colors) {
|
|
48776
49021
|
const index_of = new Map();
|
|
@@ -48781,13 +49026,9 @@ function quantize(rgba, max_colors = 256) {
|
|
|
48781
49026
|
palette[i * 3 + 1] = (key >> 8) & 0xff;
|
|
48782
49027
|
palette[i * 3 + 2] = key & 0xff;
|
|
48783
49028
|
});
|
|
48784
|
-
|
|
48785
|
-
for (let i = 0; i < pixel_count; ++i) {
|
|
48786
|
-
indices[i] = index_of.get(packed[i]);
|
|
48787
|
-
}
|
|
48788
|
-
return { palette, palette_count: distinct.length, indices };
|
|
49029
|
+
return { palette, palette_count: distinct.length, index_of };
|
|
48789
49030
|
}
|
|
48790
|
-
return
|
|
49031
|
+
return median_cut_palette(histogram, max_colors);
|
|
48791
49032
|
}
|
|
48792
49033
|
/** Channel extractors for packed 0xRRGGBB keys. @internal */
|
|
48793
49034
|
const CHANNELS = [
|
|
@@ -48796,13 +49037,15 @@ const CHANNELS = [
|
|
|
48796
49037
|
key => key & 0xff,
|
|
48797
49038
|
];
|
|
48798
49039
|
/**
|
|
48799
|
-
* Median-cut
|
|
48800
|
-
*
|
|
48801
|
-
*
|
|
49040
|
+
* Median-cut palette over a pre-built histogram. Splits the box with the
|
|
49041
|
+
* widest channel range at its count-weighted median until `max_colors` boxes
|
|
49042
|
+
* exist, then averages each box into a palette entry. Returns the palette and
|
|
49043
|
+
* the color→slot map only; per-pixel indices are the caller's concern (the
|
|
49044
|
+
* animation encoder maps each frame separately, so it never needs them here).
|
|
48802
49045
|
*
|
|
48803
49046
|
* @internal
|
|
48804
49047
|
*/
|
|
48805
|
-
function
|
|
49048
|
+
function median_cut_palette(histogram, max_colors) {
|
|
48806
49049
|
const boxes = [[...histogram.keys()]];
|
|
48807
49050
|
while (boxes.length < max_colors) {
|
|
48808
49051
|
// pick the box with the widest single-channel range
|
|
@@ -48859,11 +49102,7 @@ function median_cut(packed, histogram, max_colors) {
|
|
|
48859
49102
|
palette[bi * 3 + 1] = Math.round(g / n);
|
|
48860
49103
|
palette[bi * 3 + 2] = Math.round(b / n);
|
|
48861
49104
|
});
|
|
48862
|
-
|
|
48863
|
-
for (let i = 0; i < packed.length; ++i) {
|
|
48864
|
-
indices[i] = index_of.get(packed[i]);
|
|
48865
|
-
}
|
|
48866
|
-
return { palette, palette_count: boxes.length, indices };
|
|
49105
|
+
return { palette, palette_count: boxes.length, index_of };
|
|
48867
49106
|
}
|
|
48868
49107
|
/**
|
|
48869
49108
|
* GIF-variant LZW compression: emits a leading clear code, grows code width
|
|
@@ -48941,8 +49180,9 @@ function lzw_encode(indices, min_code_size) {
|
|
|
48941
49180
|
* @param frames - At least one frame; all with identical width/height and
|
|
48942
49181
|
* `rgba.length === 4 · width · height`.
|
|
48943
49182
|
*
|
|
48944
|
-
* @throws {JssmError} on zero frames,
|
|
48945
|
-
* buffer whose length contradicts its
|
|
49183
|
+
* @throws {JssmError} on zero frames, a zero-width or zero-height frame,
|
|
49184
|
+
* mismatched dimensions, or an rgba buffer whose length contradicts its
|
|
49185
|
+
* stated dimensions.
|
|
48946
49186
|
*
|
|
48947
49187
|
* @example
|
|
48948
49188
|
* const red = { rgba: new Uint8Array([255,0,0,255]), width: 1, height: 1 };
|
|
@@ -48955,6 +49195,12 @@ function encode_gif(frames, opts = {}) {
|
|
|
48955
49195
|
throw new JssmError(undefined, 'encode_gif: at least one frame is required');
|
|
48956
49196
|
}
|
|
48957
49197
|
const { width, height } = frames[0];
|
|
49198
|
+
if (width === 0 || height === 0) {
|
|
49199
|
+
// A 0×0 (or 0×h / w×0) frame passes the `4·w·h === rgba.length` check with
|
|
49200
|
+
// an empty buffer, then reaches lzw_encode where `indices[0]!` coerces
|
|
49201
|
+
// undefined into a bogus code 0 — a silently-corrupt GIF. Fail loudly here.
|
|
49202
|
+
throw new JssmError(undefined, `encode_gif: frame dimensions must be non-zero (got ${width}x${height})`);
|
|
49203
|
+
}
|
|
48958
49204
|
for (const f of frames) {
|
|
48959
49205
|
if (f.width !== width || f.height !== height) {
|
|
48960
49206
|
throw new JssmError(undefined, `encode_gif: frame dimensions differ (${f.width}x${f.height} vs ${width}x${height})`);
|
|
@@ -48965,25 +49211,30 @@ function encode_gif(frames, opts = {}) {
|
|
|
48965
49211
|
}
|
|
48966
49212
|
const delay_cs = (_a = opts.delay_cs) !== null && _a !== void 0 ? _a : 70;
|
|
48967
49213
|
const loop = (_b = opts.loop) !== null && _b !== void 0 ? _b : 0;
|
|
48968
|
-
//
|
|
48969
|
-
|
|
48970
|
-
|
|
49214
|
+
// Global palette over the UNION of every frame, built by streaming each
|
|
49215
|
+
// frame's histogram rather than concatenating all frames into one buffer
|
|
49216
|
+
// first (64 frames × w×h×4 can reach hundreds of MB on a big machine).
|
|
49217
|
+
// Frames are visited in order, so the key/count sequence — and therefore the
|
|
49218
|
+
// palette — is byte-identical to quantizing the concatenation.
|
|
49219
|
+
const union_histogram = new Map();
|
|
48971
49220
|
for (const f of frames) {
|
|
48972
|
-
|
|
48973
|
-
pos += f.rgba.length;
|
|
49221
|
+
accumulate_histogram(f.rgba, union_histogram);
|
|
48974
49222
|
}
|
|
48975
|
-
const
|
|
48976
|
-
const gct_bits = Math.max(1, Math.ceil(Math.log2(Math.max(2,
|
|
49223
|
+
const { palette, palette_count } = palette_from_histogram(union_histogram, 256);
|
|
49224
|
+
const gct_bits = Math.max(1, Math.ceil(Math.log2(Math.max(2, palette_count))));
|
|
48977
49225
|
const gct_size = 1 << gct_bits;
|
|
48978
49226
|
const min_code_size = Math.max(2, gct_bits);
|
|
48979
|
-
|
|
49227
|
+
// One nearest-color cache for the whole encode: the global palette is
|
|
49228
|
+
// identical across frames, so a color's best index never changes frame to
|
|
49229
|
+
// frame — rebuilding the cache per frame only re-did the same work.
|
|
49230
|
+
const palette_cache = new Map();
|
|
49231
|
+
/** Map a frame's pixels to nearest entries of the union global palette. @internal */
|
|
48980
49232
|
const map_to_palette = (rgba) => {
|
|
48981
49233
|
const n = rgba.length / 4;
|
|
48982
49234
|
const out = new Uint8Array(n);
|
|
48983
|
-
const cache = new Map();
|
|
48984
49235
|
for (let i = 0; i < n; ++i) {
|
|
48985
49236
|
const key = packed_over_white(rgba, i);
|
|
48986
|
-
const hit =
|
|
49237
|
+
const hit = palette_cache.get(key);
|
|
48987
49238
|
if (hit !== undefined) {
|
|
48988
49239
|
out[i] = hit;
|
|
48989
49240
|
continue;
|
|
@@ -48992,67 +49243,83 @@ function encode_gif(frames, opts = {}) {
|
|
|
48992
49243
|
const g = (key >> 8) & 0xff;
|
|
48993
49244
|
const b = key & 0xff;
|
|
48994
49245
|
let best = 0, best_d = Infinity;
|
|
48995
|
-
for (let p = 0; p <
|
|
48996
|
-
const dr = r -
|
|
48997
|
-
const dg = g -
|
|
48998
|
-
const db = b -
|
|
49246
|
+
for (let p = 0; p < palette_count; ++p) {
|
|
49247
|
+
const dr = r - palette[p * 3];
|
|
49248
|
+
const dg = g - palette[p * 3 + 1];
|
|
49249
|
+
const db = b - palette[p * 3 + 2];
|
|
48999
49250
|
const d = dr * dr + dg * dg + db * db;
|
|
49000
49251
|
if (d < best_d) {
|
|
49001
49252
|
best_d = d;
|
|
49002
49253
|
best = p;
|
|
49003
49254
|
}
|
|
49004
49255
|
}
|
|
49005
|
-
|
|
49256
|
+
palette_cache.set(key, best);
|
|
49006
49257
|
out[i] = best;
|
|
49007
49258
|
}
|
|
49008
49259
|
return out;
|
|
49009
49260
|
};
|
|
49010
|
-
|
|
49011
|
-
|
|
49261
|
+
// Output accumulates into a growable Uint8Array (doubling on demand) rather
|
|
49262
|
+
// than a boxed-integer number[]; the final GIF is `out.subarray(0, len)`.
|
|
49263
|
+
let out = new Uint8Array(1024);
|
|
49264
|
+
let len = 0;
|
|
49265
|
+
const need = (extra) => {
|
|
49266
|
+
if (len + extra > out.length) {
|
|
49267
|
+
const bigger = new Uint8Array(Math.max(out.length * 2, len + extra));
|
|
49268
|
+
bigger.set(out.subarray(0, len));
|
|
49269
|
+
out = bigger;
|
|
49270
|
+
}
|
|
49271
|
+
};
|
|
49272
|
+
const push = (...vals) => {
|
|
49273
|
+
need(vals.length);
|
|
49274
|
+
for (let k = 0; k < vals.length; ++k) {
|
|
49275
|
+
out[len++] = vals[k] & 0xff;
|
|
49276
|
+
}
|
|
49277
|
+
};
|
|
49278
|
+
const push_u16 = (v) => { push(v & 0xff, (v >> 8) & 0xff); };
|
|
49012
49279
|
// header + logical screen descriptor
|
|
49013
|
-
|
|
49280
|
+
push(0x47, 0x49, 0x46, 0x38, 0x39, 0x61); // "GIF89a"
|
|
49014
49281
|
push_u16(width);
|
|
49015
49282
|
push_u16(height);
|
|
49016
|
-
|
|
49017
|
-
|
|
49283
|
+
push(0x80 | 0x70 | (gct_bits - 1)); // GCT present, color res 8-bit, size
|
|
49284
|
+
push(0, 0); // background index, aspect
|
|
49018
49285
|
// global color table, padded to 2^gct_bits entries
|
|
49019
49286
|
for (let p = 0; p < gct_size; ++p) {
|
|
49020
|
-
if (p <
|
|
49021
|
-
|
|
49287
|
+
if (p < palette_count) {
|
|
49288
|
+
push(palette[p * 3], palette[p * 3 + 1], palette[p * 3 + 2]);
|
|
49022
49289
|
}
|
|
49023
49290
|
else {
|
|
49024
|
-
|
|
49291
|
+
push(0, 0, 0);
|
|
49025
49292
|
}
|
|
49026
49293
|
}
|
|
49027
49294
|
// Netscape looping extension
|
|
49028
|
-
|
|
49029
|
-
|
|
49030
|
-
|
|
49295
|
+
push(0x21, 0xFF, 0x0B);
|
|
49296
|
+
push(...'NETSCAPE2.0'.split('').map(c => c.charCodeAt(0)));
|
|
49297
|
+
push(0x03, 0x01);
|
|
49031
49298
|
push_u16(loop);
|
|
49032
|
-
|
|
49299
|
+
push(0x00);
|
|
49033
49300
|
for (let fi = 0; fi < frames.length; ++fi) {
|
|
49034
49301
|
// graphics control extension: disposal 1 (leave in place), no transparency
|
|
49035
|
-
|
|
49302
|
+
push(0x21, 0xF9, 0x04, 0x04);
|
|
49036
49303
|
push_u16(delay_cs);
|
|
49037
|
-
|
|
49304
|
+
push(0x00, 0x00);
|
|
49038
49305
|
// image descriptor: full frame, no local color table
|
|
49039
|
-
|
|
49306
|
+
push(0x2C);
|
|
49040
49307
|
push_u16(0);
|
|
49041
49308
|
push_u16(0);
|
|
49042
49309
|
push_u16(width);
|
|
49043
49310
|
push_u16(height);
|
|
49044
|
-
|
|
49311
|
+
push(0x00);
|
|
49045
49312
|
const indices = map_to_palette(frames[fi].rgba);
|
|
49046
|
-
const
|
|
49047
|
-
|
|
49048
|
-
for (let at = 0; at <
|
|
49049
|
-
const chunk =
|
|
49050
|
-
|
|
49313
|
+
const packed_lzw = lzw_encode(indices, min_code_size);
|
|
49314
|
+
push(min_code_size);
|
|
49315
|
+
for (let at = 0; at < packed_lzw.length; at += 255) {
|
|
49316
|
+
const chunk = packed_lzw.slice(at, at + 255);
|
|
49317
|
+
push(chunk.length, ...chunk);
|
|
49051
49318
|
}
|
|
49052
|
-
|
|
49319
|
+
push(0x00); // block terminator
|
|
49053
49320
|
}
|
|
49054
|
-
|
|
49055
|
-
return
|
|
49321
|
+
push(0x3B); // trailer
|
|
49322
|
+
return out.slice(0, len);
|
|
49056
49323
|
}
|
|
49057
49324
|
|
|
49058
49325
|
/**
|
|
@@ -49083,32 +49350,33 @@ function error_box(source, message) {
|
|
|
49083
49350
|
/** Note comment, invisible but inspectable. @internal */
|
|
49084
49351
|
const note_comment = (note) => `<!-- fsl-fence: ${escape_html(note)} -->`;
|
|
49085
49352
|
/**
|
|
49086
|
-
* Remap
|
|
49087
|
-
* {@link extract_state_fills} from a rendered SVG) to be keyed by state
|
|
49088
|
-
*
|
|
49089
|
-
*
|
|
49090
|
-
*
|
|
49091
|
-
*
|
|
49092
|
-
*
|
|
49093
|
-
*
|
|
49094
|
-
*
|
|
49095
|
-
*
|
|
49096
|
-
*
|
|
49097
|
-
*
|
|
49098
|
-
*
|
|
49099
|
-
*
|
|
49100
|
-
* @param
|
|
49101
|
-
*
|
|
49353
|
+
* Remap an SVG-label-keyed fill map (as produced by
|
|
49354
|
+
* {@link extract_state_fills} from a rendered SVG) to be keyed by state NAME
|
|
49355
|
+
* instead. Graphviz labels each node with its full rendered label text —
|
|
49356
|
+
* display text, plus any group chips, plus any multi-line wrap — while
|
|
49357
|
+
* `highlight_fsl_html`'s `state_colors` option is keyed by the state's own
|
|
49358
|
+
* name (the code highlighter's semantic spans carry names, not labels).
|
|
49359
|
+
* Without this remap, any state whose label diverges from its name silently
|
|
49360
|
+
* fails to carry its diagram color to its code span.
|
|
49361
|
+
*
|
|
49362
|
+
* Both sides of the join derive the SVG label text from the same source:
|
|
49363
|
+
* `label_texts` comes from {@link state_svg_label_texts} (the viz's own label
|
|
49364
|
+
* builder) and `fills`'s keys are read straight off the SVG, so group chips
|
|
49365
|
+
* and multi-line labels are handled without either side drifting.
|
|
49366
|
+
*
|
|
49367
|
+
* @param label_texts - State name → its rendered SVG label text, from
|
|
49368
|
+
* `state_svg_label_texts`.
|
|
49369
|
+
* @param fills - SVG-label-keyed fills, from `extract_state_fills`.
|
|
49102
49370
|
* @returns Fills re-keyed by state name; states with no matching fill are omitted.
|
|
49103
49371
|
*
|
|
49104
49372
|
* @internal
|
|
49105
49373
|
*/
|
|
49106
|
-
function state_colors_by_name(
|
|
49374
|
+
function state_colors_by_name(label_texts, fills) {
|
|
49107
49375
|
const out = new Map();
|
|
49108
|
-
for (const
|
|
49109
|
-
const fill = fills.get(
|
|
49376
|
+
for (const [state, label] of label_texts) {
|
|
49377
|
+
const fill = fills.get(label);
|
|
49110
49378
|
if (fill !== undefined) {
|
|
49111
|
-
out.set(
|
|
49379
|
+
out.set(state, fill);
|
|
49112
49380
|
}
|
|
49113
49381
|
}
|
|
49114
49382
|
return out;
|
|
@@ -49151,7 +49419,7 @@ async function render_fence_html(source, info, opts = {}) {
|
|
|
49151
49419
|
}
|
|
49152
49420
|
const svg = await fsl_to_svg_string(source);
|
|
49153
49421
|
const fills = extract_state_fills(svg);
|
|
49154
|
-
const state_colors = state_colors_by_name(machine, fills);
|
|
49422
|
+
const state_colors = state_colors_by_name(state_svg_label_texts(machine), fills);
|
|
49155
49423
|
const chunks = desc.notes.map(note_comment);
|
|
49156
49424
|
for (const part of desc.parts) {
|
|
49157
49425
|
if (INTERACTIVE_PARTS.has(part)) {
|
|
@@ -49286,14 +49554,15 @@ async function render_fence_gif(source, opts = {}) {
|
|
|
49286
49554
|
const base_svg = await fsl_to_svg_string(source);
|
|
49287
49555
|
const highlight = (_b = opts.highlight_fill) !== null && _b !== void 0 ? _b : '#ff9930';
|
|
49288
49556
|
const scale = (_c = opts.scale) !== null && _c !== void 0 ? _c : 100;
|
|
49557
|
+
const label_texts = state_svg_label_texts(machine);
|
|
49289
49558
|
const frames = [];
|
|
49290
49559
|
for (const state of walk) {
|
|
49291
|
-
// base_svg's nodes are labeled with
|
|
49292
|
-
//
|
|
49293
|
-
//
|
|
49294
|
-
//
|
|
49295
|
-
//
|
|
49296
|
-
const patched = patch_state_fill(base_svg,
|
|
49560
|
+
// base_svg's nodes are labeled with their full SVG label text (display
|
|
49561
|
+
// text + any group chips + any multi-line wrap), not the walk's state
|
|
49562
|
+
// NAME — patch by the shared derivation or a labeled/chipped/wrapped
|
|
49563
|
+
// state's frame silently no-ops. `walk` is drawn from the machine's own
|
|
49564
|
+
// states, so every entry has a label_texts key.
|
|
49565
|
+
const patched = patch_state_fill(base_svg, label_texts.get(state), highlight);
|
|
49297
49566
|
const raster = await rasterizeRgba(patched, { scale });
|
|
49298
49567
|
frames.push({ rgba: raster.rgba, width: raster.width, height: raster.height });
|
|
49299
49568
|
}
|