parseman 0.23.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/combinators/keywords.d.ts.map +1 -1
- package/dist/combinators/literal.d.ts.map +1 -1
- package/dist/combinators/parser.d.ts +6 -0
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/combinators/regex.d.ts.map +1 -1
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/cst/relative-spans.d.ts +32 -0
- package/dist/cst/relative-spans.d.ts.map +1 -1
- package/dist/functional/doc.d.ts +53 -3
- package/dist/functional/doc.d.ts.map +1 -1
- package/dist/index.cjs +475 -139
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +475 -139
- package/dist/index.js.map +4 -4
- package/dist/plugin/index.cjs +156 -39
- package/dist/plugin/index.cjs.map +3 -3
- package/dist/plugin/index.js +156 -39
- package/dist/plugin/index.js.map +3 -3
- package/dist/spec/ebnf.d.ts +13 -0
- package/dist/spec/ebnf.d.ts.map +1 -0
- package/dist/spec/index.cjs +1038 -0
- package/dist/spec/index.cjs.map +7 -0
- package/dist/spec/index.d.ts +23 -0
- package/dist/spec/index.d.ts.map +1 -0
- package/dist/spec/index.js +1015 -0
- package/dist/spec/index.js.map +7 -0
- package/dist/spec/model.d.ts +117 -0
- package/dist/spec/model.d.ts.map +1 -0
- package/dist/spec/railroad-lib.d.ts +11 -0
- package/dist/spec/railroad-lib.d.ts.map +1 -0
- package/dist/spec/railroad.d.ts +30 -0
- package/dist/spec/railroad.d.ts.map +1 -0
- package/package.json +8 -2
package/dist/index.cjs
CHANGED
|
@@ -22,7 +22,9 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
OffsetIndex: () => OffsetIndex,
|
|
24
24
|
absoluteSpanAt: () => absoluteSpanAt,
|
|
25
|
+
absoluteSpanCST: () => absoluteSpanCST,
|
|
25
26
|
absolutize: () => absolutize,
|
|
27
|
+
absolutizeCST: () => absolutizeCST,
|
|
26
28
|
annotateSpan: () => annotateSpan,
|
|
27
29
|
applyEdit: () => applyEdit,
|
|
28
30
|
balanced: () => balanced,
|
|
@@ -67,6 +69,7 @@ __export(index_exports, {
|
|
|
67
69
|
ref: () => ref,
|
|
68
70
|
regex: () => regex,
|
|
69
71
|
relativize: () => relativize,
|
|
72
|
+
relativizeCST: () => relativizeCST,
|
|
70
73
|
rules: () => rules,
|
|
71
74
|
run: () => run,
|
|
72
75
|
scanTo: () => scanTo,
|
|
@@ -431,24 +434,35 @@ function literal(value, opts = {}) {
|
|
|
431
434
|
{ lo: firstUpper, hi: firstUpper }
|
|
432
435
|
] } : firstSet2;
|
|
433
436
|
}
|
|
437
|
+
const expected = [JSON.stringify(value)];
|
|
438
|
+
const parse2 = !caseInsensitive && value.length === 1 ? (() => {
|
|
439
|
+
const code = value.charCodeAt(0);
|
|
440
|
+
return function parse3(input, pos, ctx) {
|
|
441
|
+
if (input.charCodeAt(pos) === code) {
|
|
442
|
+
const span = { start: pos, end: pos + 1 };
|
|
443
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
444
|
+
return { ok: true, value, span };
|
|
445
|
+
}
|
|
446
|
+
return failAt(ctx, expected, pos);
|
|
447
|
+
};
|
|
448
|
+
})() : function parse3(input, pos, ctx) {
|
|
449
|
+
const end = pos + value.length;
|
|
450
|
+
if (end > input.length) {
|
|
451
|
+
return failAt(ctx, expected, pos);
|
|
452
|
+
}
|
|
453
|
+
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
454
|
+
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
455
|
+
const span = { start: pos, end };
|
|
456
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: matchedValue, span });
|
|
457
|
+
return { ok: true, value: matchedValue, span };
|
|
458
|
+
}
|
|
459
|
+
return failAt(ctx, expected, pos);
|
|
460
|
+
};
|
|
434
461
|
return {
|
|
435
462
|
_tag: "literal",
|
|
436
463
|
_meta: meta,
|
|
437
464
|
_def: { tag: "literal", value, caseInsensitive },
|
|
438
|
-
parse
|
|
439
|
-
const end = pos + value.length;
|
|
440
|
-
if (end > input.length) {
|
|
441
|
-
return failAt(ctx, [JSON.stringify(value)], pos);
|
|
442
|
-
}
|
|
443
|
-
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
444
|
-
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
445
|
-
const span = { start: pos, end };
|
|
446
|
-
const leaf = { _tag: "leaf", value: matchedValue, span };
|
|
447
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
448
|
-
return { ok: true, value: matchedValue, span };
|
|
449
|
-
}
|
|
450
|
-
return failAt(ctx, [JSON.stringify(value)], pos);
|
|
451
|
-
}
|
|
465
|
+
parse: parse2
|
|
452
466
|
};
|
|
453
467
|
}
|
|
454
468
|
|
|
@@ -583,8 +597,7 @@ function regex(pattern, flags = "") {
|
|
|
583
597
|
if (scanEnd === null) return failAt(ctx, [`/${source}/`], pos);
|
|
584
598
|
const value = input.slice(pos, scanEnd);
|
|
585
599
|
const span2 = { start: pos, end: scanEnd };
|
|
586
|
-
|
|
587
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf2);
|
|
600
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: span2 });
|
|
588
601
|
return { ok: true, value, span: span2 };
|
|
589
602
|
}
|
|
590
603
|
anchored.lastIndex = pos;
|
|
@@ -593,8 +606,7 @@ function regex(pattern, flags = "") {
|
|
|
593
606
|
return failAt(ctx, [`/${source}/`], pos);
|
|
594
607
|
}
|
|
595
608
|
const span = { start: pos, end: pos + m[0].length };
|
|
596
|
-
|
|
597
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
609
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: m[0], span });
|
|
598
610
|
return { ok: true, value: m[0], span };
|
|
599
611
|
}
|
|
600
612
|
};
|
|
@@ -902,8 +914,7 @@ function keywords(words, opts = {}) {
|
|
|
902
914
|
}
|
|
903
915
|
const value = m[0];
|
|
904
916
|
const span = { start: pos, end: pos + value.length };
|
|
905
|
-
|
|
906
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
917
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
907
918
|
return { ok: true, value, span };
|
|
908
919
|
}
|
|
909
920
|
};
|
|
@@ -1393,33 +1404,136 @@ function loopScanner(arms) {
|
|
|
1393
1404
|
}
|
|
1394
1405
|
function regexTriviaScanner(parser2) {
|
|
1395
1406
|
if (parser2._def.tag !== "regex" || parser2._def.flags) return null;
|
|
1396
|
-
const
|
|
1397
|
-
|
|
1398
|
-
return blockCommentSource(parser2._def.source) ? scanBlockComment : null;
|
|
1407
|
+
const source = parser2._def.source;
|
|
1408
|
+
return classRunSource(source) ?? altStarSource(source) ?? (blockCommentSource(source) ? scanBlockComment : null);
|
|
1399
1409
|
}
|
|
1400
|
-
function
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1410
|
+
function inRanges2(cp, ranges) {
|
|
1411
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
1412
|
+
const r = ranges[i];
|
|
1413
|
+
if (cp >= r[0] && cp <= r[1]) return true;
|
|
1414
|
+
}
|
|
1415
|
+
return false;
|
|
1416
|
+
}
|
|
1417
|
+
function classScanner(classBody) {
|
|
1418
|
+
const ranges = parseClassRanges(classBody);
|
|
1419
|
+
if (!ranges) return null;
|
|
1420
|
+
return (input, cur) => {
|
|
1421
|
+
let pos = cur;
|
|
1422
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1423
|
+
return pos;
|
|
1424
|
+
};
|
|
1425
|
+
}
|
|
1426
|
+
function lineCommentScanner(commentCode) {
|
|
1427
|
+
return (input, cur) => {
|
|
1428
|
+
if (input.charCodeAt(cur) !== commentCode) return cur;
|
|
1429
|
+
let pos = cur + 1;
|
|
1430
|
+
while (pos < input.length) {
|
|
1431
|
+
const cc = input.charCodeAt(pos);
|
|
1432
|
+
if (cc === 10 || cc === 13) break;
|
|
1433
|
+
pos++;
|
|
1409
1434
|
}
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1435
|
+
return pos;
|
|
1436
|
+
};
|
|
1437
|
+
}
|
|
1438
|
+
function classRunSource(source) {
|
|
1439
|
+
const m = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]$/.exec(source);
|
|
1440
|
+
return m ? classScanner(m[1]) : null;
|
|
1441
|
+
}
|
|
1442
|
+
function classifyTriviaArm(arm) {
|
|
1443
|
+
const cls = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]?$/.exec(arm);
|
|
1444
|
+
if (cls) {
|
|
1445
|
+
const ranges = parseClassRanges(cls[1]);
|
|
1446
|
+
return ranges ? { kind: "class", ranges } : null;
|
|
1416
1447
|
}
|
|
1448
|
+
const lc = /^(\\?.)\[\^\\n\\r\]\*$/.exec(arm);
|
|
1449
|
+
if (lc) {
|
|
1450
|
+
const marker = lc[1];
|
|
1451
|
+
return { kind: "comment", code: (marker.length === 2 ? marker[1] : marker[0]).charCodeAt(0) };
|
|
1452
|
+
}
|
|
1453
|
+
return null;
|
|
1454
|
+
}
|
|
1455
|
+
function armScanner(arm) {
|
|
1456
|
+
if (arm.kind === "comment") return lineCommentScanner(arm.code);
|
|
1457
|
+
const ranges = arm.ranges;
|
|
1417
1458
|
return (input, cur) => {
|
|
1418
1459
|
let pos = cur;
|
|
1419
|
-
while (pos < input.length &&
|
|
1460
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1420
1461
|
return pos;
|
|
1421
1462
|
};
|
|
1422
1463
|
}
|
|
1464
|
+
function fusedTriviaScanner(ranges, commentCodes) {
|
|
1465
|
+
const c0 = commentCodes[0];
|
|
1466
|
+
const single = commentCodes.length === 1;
|
|
1467
|
+
return (input, cur) => {
|
|
1468
|
+
let pos = cur;
|
|
1469
|
+
const len = input.length;
|
|
1470
|
+
for (; ; ) {
|
|
1471
|
+
const c = input.charCodeAt(pos);
|
|
1472
|
+
if (pos < len && inRanges2(c, ranges)) {
|
|
1473
|
+
pos++;
|
|
1474
|
+
continue;
|
|
1475
|
+
}
|
|
1476
|
+
if (single ? c === c0 : commentCodes.includes(c)) {
|
|
1477
|
+
pos++;
|
|
1478
|
+
while (pos < len) {
|
|
1479
|
+
const cc = input.charCodeAt(pos);
|
|
1480
|
+
if (cc === 10 || cc === 13) break;
|
|
1481
|
+
pos++;
|
|
1482
|
+
}
|
|
1483
|
+
continue;
|
|
1484
|
+
}
|
|
1485
|
+
break;
|
|
1486
|
+
}
|
|
1487
|
+
return pos;
|
|
1488
|
+
};
|
|
1489
|
+
}
|
|
1490
|
+
function splitTopLevelAlts(body) {
|
|
1491
|
+
const arms = [];
|
|
1492
|
+
let inClass = false;
|
|
1493
|
+
let start = 0;
|
|
1494
|
+
for (let i = 0; i < body.length; i++) {
|
|
1495
|
+
const c = body[i];
|
|
1496
|
+
if (c === "\\") {
|
|
1497
|
+
i++;
|
|
1498
|
+
continue;
|
|
1499
|
+
}
|
|
1500
|
+
if (inClass) {
|
|
1501
|
+
if (c === "]") inClass = false;
|
|
1502
|
+
continue;
|
|
1503
|
+
}
|
|
1504
|
+
if (c === "[") inClass = true;
|
|
1505
|
+
else if (c === "(") return null;
|
|
1506
|
+
else if (c === "|") {
|
|
1507
|
+
arms.push(body.slice(start, i));
|
|
1508
|
+
start = i + 1;
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
arms.push(body.slice(start));
|
|
1512
|
+
return arms;
|
|
1513
|
+
}
|
|
1514
|
+
function altStarSource(source) {
|
|
1515
|
+
const m = /^\(\?:(.*)\)[*+]$/.exec(source);
|
|
1516
|
+
if (!m) return null;
|
|
1517
|
+
const armSrcs = splitTopLevelAlts(m[1]);
|
|
1518
|
+
if (!armSrcs || armSrcs.length < 2) return null;
|
|
1519
|
+
const arms = [];
|
|
1520
|
+
for (const src of armSrcs) {
|
|
1521
|
+
const arm = classifyTriviaArm(src);
|
|
1522
|
+
if (!arm) return null;
|
|
1523
|
+
arms.push(arm);
|
|
1524
|
+
}
|
|
1525
|
+
const ranges = [];
|
|
1526
|
+
const commentCodes = [];
|
|
1527
|
+
for (const arm of arms) {
|
|
1528
|
+
if (arm.kind === "class") ranges.push(...arm.ranges);
|
|
1529
|
+
else commentCodes.push(arm.code);
|
|
1530
|
+
}
|
|
1531
|
+
if (commentCodes.some((code) => inRanges2(code, ranges))) {
|
|
1532
|
+
return loopScanner(arms.map(armScanner));
|
|
1533
|
+
}
|
|
1534
|
+
if (commentCodes.length === 0) return armScanner({ kind: "class", ranges });
|
|
1535
|
+
return fusedTriviaScanner(ranges, commentCodes);
|
|
1536
|
+
}
|
|
1423
1537
|
function blockCommentSource(source) {
|
|
1424
1538
|
return source === "\\/\\*(?:[^*]|\\*(?!\\/))*\\*\\/" || source === "\\/\\*[^]*?\\*\\/";
|
|
1425
1539
|
}
|
|
@@ -1773,6 +1887,7 @@ function markUnusedValues(root) {
|
|
|
1773
1887
|
}
|
|
1774
1888
|
|
|
1775
1889
|
// src/combinators/parser.ts
|
|
1890
|
+
var RULE_ORDER = "__parsemanRuleOrder";
|
|
1776
1891
|
function tagRule(r, key) {
|
|
1777
1892
|
;
|
|
1778
1893
|
r._ruleName = key;
|
|
@@ -1817,6 +1932,11 @@ function rules(a, b) {
|
|
|
1817
1932
|
for (const key of Object.keys(definitions)) {
|
|
1818
1933
|
markUnusedValues(cache[key]);
|
|
1819
1934
|
}
|
|
1935
|
+
Object.defineProperty(cache, RULE_ORDER, {
|
|
1936
|
+
value: Object.keys(definitions),
|
|
1937
|
+
enumerable: false,
|
|
1938
|
+
configurable: true
|
|
1939
|
+
});
|
|
1820
1940
|
return cache;
|
|
1821
1941
|
}
|
|
1822
1942
|
|
|
@@ -6364,17 +6484,159 @@ function manyRecover(item, until) {
|
|
|
6364
6484
|
return many(tolerantElement(item, until, until));
|
|
6365
6485
|
}
|
|
6366
6486
|
|
|
6487
|
+
// src/cst/relative-spans.ts
|
|
6488
|
+
function relativize(node2, parentBase = 0) {
|
|
6489
|
+
return {
|
|
6490
|
+
start: node2.start - parentBase,
|
|
6491
|
+
end: node2.end - parentBase,
|
|
6492
|
+
children: node2.children.map((c) => relativize(c, node2.start))
|
|
6493
|
+
};
|
|
6494
|
+
}
|
|
6495
|
+
function absolutize(node2, parentBase = 0) {
|
|
6496
|
+
const start = parentBase + node2.start;
|
|
6497
|
+
return {
|
|
6498
|
+
start,
|
|
6499
|
+
end: parentBase + node2.end,
|
|
6500
|
+
children: node2.children.map((c) => absolutize(c, start))
|
|
6501
|
+
};
|
|
6502
|
+
}
|
|
6503
|
+
function absoluteSpanAt(root, path) {
|
|
6504
|
+
let base = 0;
|
|
6505
|
+
let node2 = root;
|
|
6506
|
+
for (const idx of path) {
|
|
6507
|
+
base += node2.start;
|
|
6508
|
+
const child = node2.children[idx];
|
|
6509
|
+
if (!child) throw new RangeError(`absoluteSpanAt: no child ${idx} on path ${path.join(".")}`);
|
|
6510
|
+
node2 = child;
|
|
6511
|
+
}
|
|
6512
|
+
return { start: base + node2.start, end: base + node2.end };
|
|
6513
|
+
}
|
|
6514
|
+
function relativizeCST(node2, parentBase = 0) {
|
|
6515
|
+
const span = { start: node2.span.start - parentBase, end: node2.span.end - parentBase };
|
|
6516
|
+
if (node2.children) {
|
|
6517
|
+
const base = node2.span.start;
|
|
6518
|
+
return { ...node2, span, children: node2.children.map((c) => relativizeCST(c, base)) };
|
|
6519
|
+
}
|
|
6520
|
+
return { ...node2, span };
|
|
6521
|
+
}
|
|
6522
|
+
function absolutizeCST(node2, parentBase = 0) {
|
|
6523
|
+
const start = parentBase + node2.span.start;
|
|
6524
|
+
const span = { start, end: parentBase + node2.span.end };
|
|
6525
|
+
if (node2.children) {
|
|
6526
|
+
return { ...node2, span, children: node2.children.map((c) => absolutizeCST(c, start)) };
|
|
6527
|
+
}
|
|
6528
|
+
return { ...node2, span };
|
|
6529
|
+
}
|
|
6530
|
+
function absoluteSpanCST(root, path) {
|
|
6531
|
+
let base = 0;
|
|
6532
|
+
let node2 = root;
|
|
6533
|
+
for (const idx of path) {
|
|
6534
|
+
base += node2.span.start;
|
|
6535
|
+
const child = node2.children?.[idx];
|
|
6536
|
+
if (!child) throw new RangeError(`absoluteSpanCST: no child ${idx} on path ${path.join(".")}`);
|
|
6537
|
+
node2 = child;
|
|
6538
|
+
}
|
|
6539
|
+
return { start: base + node2.span.start, end: base + node2.span.end };
|
|
6540
|
+
}
|
|
6541
|
+
function shiftAbsolute(node2, at, delta) {
|
|
6542
|
+
const s = node2.start >= at ? node2.start + delta : node2.start;
|
|
6543
|
+
const e = node2.end >= at ? node2.end + delta : node2.end;
|
|
6544
|
+
return {
|
|
6545
|
+
start: s,
|
|
6546
|
+
end: e,
|
|
6547
|
+
children: node2.children.map((c) => shiftAbsolute(c, at, delta))
|
|
6548
|
+
};
|
|
6549
|
+
}
|
|
6550
|
+
function applyEdit(root, at, delta, stats) {
|
|
6551
|
+
return editNode(root, at, delta, 0, 0, stats);
|
|
6552
|
+
}
|
|
6553
|
+
function editNode(node2, at, delta, parentBase, parentShift, stats) {
|
|
6554
|
+
const absStart = parentBase + node2.start;
|
|
6555
|
+
const absEnd = parentBase + node2.end;
|
|
6556
|
+
if (absEnd < at) return node2;
|
|
6557
|
+
const startShifts = absStart >= at;
|
|
6558
|
+
if (startShifts && parentShift === delta) return node2;
|
|
6559
|
+
if (stats) stats.allocated++;
|
|
6560
|
+
const newAbsStart = startShifts ? absStart + delta : absStart;
|
|
6561
|
+
const newAbsEnd = absEnd + delta;
|
|
6562
|
+
const newParentBase = parentBase + parentShift;
|
|
6563
|
+
const newStart = newAbsStart - newParentBase;
|
|
6564
|
+
const newEnd = newAbsEnd - newParentBase;
|
|
6565
|
+
const ownShift = newAbsStart - absStart;
|
|
6566
|
+
let changed = false;
|
|
6567
|
+
const newChildren = [];
|
|
6568
|
+
for (const c of node2.children) {
|
|
6569
|
+
const nc = editNode(c, at, delta, absStart, ownShift, stats);
|
|
6570
|
+
if (nc !== c) changed = true;
|
|
6571
|
+
newChildren.push(nc);
|
|
6572
|
+
}
|
|
6573
|
+
return {
|
|
6574
|
+
start: newStart,
|
|
6575
|
+
end: newEnd,
|
|
6576
|
+
children: changed ? newChildren : node2.children
|
|
6577
|
+
};
|
|
6578
|
+
}
|
|
6579
|
+
|
|
6367
6580
|
// src/functional/doc.ts
|
|
6581
|
+
function asRuleFn(entry) {
|
|
6582
|
+
return typeof entry === "function" ? entry : (input, pos, ctx) => entry.parse(input, pos, ctx);
|
|
6583
|
+
}
|
|
6584
|
+
function defOf(entry) {
|
|
6585
|
+
return typeof entry === "object" && entry !== null && "_def" in entry ? entry._def : void 0;
|
|
6586
|
+
}
|
|
6587
|
+
function producesRepetition(def, depth = 0) {
|
|
6588
|
+
if (!def || depth > 24) return false;
|
|
6589
|
+
const d = def;
|
|
6590
|
+
switch (d.tag) {
|
|
6591
|
+
case "sepBy":
|
|
6592
|
+
case "many":
|
|
6593
|
+
case "oneOrMore":
|
|
6594
|
+
return true;
|
|
6595
|
+
// Rule entries and `ref`s wrap their body in a `lazy` thunk — resolve it. The
|
|
6596
|
+
// `depth` cap bounds any self-referential cycle (a repetition, if present, is
|
|
6597
|
+
// found shallowly before recursion goes deep).
|
|
6598
|
+
case "lazy": {
|
|
6599
|
+
const thunk = d.thunk;
|
|
6600
|
+
let inner;
|
|
6601
|
+
try {
|
|
6602
|
+
inner = typeof thunk === "function" ? thunk() : void 0;
|
|
6603
|
+
} catch {
|
|
6604
|
+
return false;
|
|
6605
|
+
}
|
|
6606
|
+
return producesRepetition(inner?._def, depth + 1);
|
|
6607
|
+
}
|
|
6608
|
+
// Transparent wrappers — look through to the inner parser.
|
|
6609
|
+
case "node":
|
|
6610
|
+
case "transform":
|
|
6611
|
+
case "token":
|
|
6612
|
+
case "label":
|
|
6613
|
+
case "field":
|
|
6614
|
+
case "expect":
|
|
6615
|
+
case "withCtx":
|
|
6616
|
+
case "grammar":
|
|
6617
|
+
case "optional":
|
|
6618
|
+
return producesRepetition(defOf(d.parser), depth + 1);
|
|
6619
|
+
case "skip":
|
|
6620
|
+
return producesRepetition(defOf(d.main), depth + 1);
|
|
6621
|
+
// A bracketed/anchored list is a sequence whose element run is a repetition.
|
|
6622
|
+
case "sequence":
|
|
6623
|
+
return d.parsers.some((p) => producesRepetition(defOf(p), depth + 1));
|
|
6624
|
+
default:
|
|
6625
|
+
return false;
|
|
6626
|
+
}
|
|
6627
|
+
}
|
|
6368
6628
|
var REENTRY_MAX_SPAN_FRACTION = 0.5;
|
|
6369
6629
|
function isNode(x) {
|
|
6370
6630
|
return typeof x === "object" && x !== null && x._tag === "node";
|
|
6371
6631
|
}
|
|
6372
|
-
function findContaining(node2, pos, path = []) {
|
|
6632
|
+
function findContaining(node2, nodeAbsStart, pos, path = []) {
|
|
6373
6633
|
for (let i = 0; i < node2.children.length; i++) {
|
|
6374
6634
|
const child = node2.children[i];
|
|
6375
6635
|
if (!isNode(child)) continue;
|
|
6376
|
-
|
|
6377
|
-
|
|
6636
|
+
const childAbsStart = nodeAbsStart + child.span.start;
|
|
6637
|
+
const childAbsEnd = nodeAbsStart + child.span.end;
|
|
6638
|
+
if (childAbsStart <= pos && pos < childAbsEnd) {
|
|
6639
|
+
const inner = findContaining(child, childAbsStart, pos, [...path, i]);
|
|
6378
6640
|
return inner ?? { node: child, path: [...path, i] };
|
|
6379
6641
|
}
|
|
6380
6642
|
}
|
|
@@ -6401,24 +6663,20 @@ function replaceAtPath(rebuild, root, path, newNode) {
|
|
|
6401
6663
|
function defaultRebuild(node2, children) {
|
|
6402
6664
|
return { ...node2, children };
|
|
6403
6665
|
}
|
|
6404
|
-
function
|
|
6666
|
+
function shiftRelStart(child, delta) {
|
|
6405
6667
|
const c = child;
|
|
6406
|
-
|
|
6407
|
-
if (Array.isArray(c.children)) {
|
|
6408
|
-
return { ...c, span, children: c.children.map((g) => shiftSpans(g, delta)) };
|
|
6409
|
-
}
|
|
6410
|
-
return { ...c, span };
|
|
6668
|
+
return { ...c, span: { start: c.span.start + delta, end: c.span.end + delta } };
|
|
6411
6669
|
}
|
|
6412
|
-
function
|
|
6670
|
+
function graftRelative(root, path, newNode, delta) {
|
|
6413
6671
|
if (path.length === 0) return newNode;
|
|
6414
6672
|
const [idx, ...rest] = path;
|
|
6415
6673
|
const oldChildren = root.children;
|
|
6416
6674
|
const newChildren = oldChildren.map((child, i) => {
|
|
6417
6675
|
if (i < idx) return child;
|
|
6418
6676
|
if (i === idx) {
|
|
6419
|
-
return rest.length === 0 ? newNode :
|
|
6677
|
+
return rest.length === 0 ? newNode : graftRelative(child, rest, newNode, delta);
|
|
6420
6678
|
}
|
|
6421
|
-
return
|
|
6679
|
+
return shiftRelStart(child, delta);
|
|
6422
6680
|
});
|
|
6423
6681
|
return {
|
|
6424
6682
|
...root,
|
|
@@ -6426,6 +6684,96 @@ function graftAndShift(root, path, newNode, delta) {
|
|
|
6426
6684
|
children: newChildren
|
|
6427
6685
|
};
|
|
6428
6686
|
}
|
|
6687
|
+
function parseMiddle(input, reStart, reEnd, cStart, ruleFn, separator, build) {
|
|
6688
|
+
const ctx = { trackLines: false, state: null, build };
|
|
6689
|
+
const out = [];
|
|
6690
|
+
let pos = reStart;
|
|
6691
|
+
let guard2 = 0;
|
|
6692
|
+
while (pos < reEnd) {
|
|
6693
|
+
if (++guard2 > reEnd - reStart + 2) return null;
|
|
6694
|
+
if (separator && out.length > 0 && out[out.length - 1]._tag === "node") {
|
|
6695
|
+
if (pos + separator.length > reEnd || !input.startsWith(separator, pos)) return null;
|
|
6696
|
+
out.push({ _tag: "leaf", value: separator, span: { start: pos - cStart, end: pos + separator.length - cStart } });
|
|
6697
|
+
pos += separator.length;
|
|
6698
|
+
continue;
|
|
6699
|
+
}
|
|
6700
|
+
let r;
|
|
6701
|
+
try {
|
|
6702
|
+
r = ruleFn(input, pos, ctx);
|
|
6703
|
+
} catch {
|
|
6704
|
+
return null;
|
|
6705
|
+
}
|
|
6706
|
+
if (!r.ok || r.span.end <= pos || r.span.end > reEnd) return null;
|
|
6707
|
+
out.push(relativizeCST(r.value, cStart));
|
|
6708
|
+
pos = r.span.end;
|
|
6709
|
+
}
|
|
6710
|
+
return pos === reEnd ? out : null;
|
|
6711
|
+
}
|
|
6712
|
+
function tryListSplice(root, path, C, cStart, newInput, from, to, delta, registry, build) {
|
|
6713
|
+
const kids = C.children;
|
|
6714
|
+
if (kids.length === 0) return null;
|
|
6715
|
+
let h = 0;
|
|
6716
|
+
while (h < kids.length && cStart + kids[h].span.end <= from) h++;
|
|
6717
|
+
while (h > 0 && kids[h - 1]._tag === "node") h--;
|
|
6718
|
+
let t = kids.length;
|
|
6719
|
+
while (t > h && cStart + kids[t - 1].span.start >= to) t--;
|
|
6720
|
+
while (t < kids.length && kids[t]._tag !== "node") t++;
|
|
6721
|
+
if (t >= kids.length) return null;
|
|
6722
|
+
for (let i = t; i < kids.length; i++) {
|
|
6723
|
+
if (kids[i]._tag === "node" && kids[i].state != null) return null;
|
|
6724
|
+
}
|
|
6725
|
+
let elemType;
|
|
6726
|
+
let elemCount = 0;
|
|
6727
|
+
for (const k of kids) {
|
|
6728
|
+
if (k._tag !== "node") continue;
|
|
6729
|
+
elemCount++;
|
|
6730
|
+
if (elemType === void 0) elemType = k.type;
|
|
6731
|
+
else if (k.type !== elemType) return null;
|
|
6732
|
+
}
|
|
6733
|
+
if (elemType === void 0 || elemCount < 2) return null;
|
|
6734
|
+
const ruleFn = registry[elemType];
|
|
6735
|
+
if (!ruleFn) return null;
|
|
6736
|
+
let separator = null;
|
|
6737
|
+
for (let i = 1; i < kids.length - 1; i++) {
|
|
6738
|
+
if (kids[i - 1]._tag === "node" && kids[i + 1]._tag === "node") {
|
|
6739
|
+
if (kids[i]._tag !== "leaf") return null;
|
|
6740
|
+
const sep = kids[i].value ?? null;
|
|
6741
|
+
if (separator === null) separator = sep;
|
|
6742
|
+
else if (sep !== separator) return null;
|
|
6743
|
+
}
|
|
6744
|
+
}
|
|
6745
|
+
if (separator === null) return null;
|
|
6746
|
+
const first = kids[0];
|
|
6747
|
+
const last = kids[kids.length - 1];
|
|
6748
|
+
if (first._tag === "leaf" && first.value !== separator && from < cStart + first.span.end) return null;
|
|
6749
|
+
if (last._tag === "leaf" && last.value !== separator && to > cStart + last.span.start) return null;
|
|
6750
|
+
const reStart = h > 0 ? cStart + kids[h - 1].span.end : cStart;
|
|
6751
|
+
const reEnd = cStart + kids[t].span.start + delta;
|
|
6752
|
+
if (reEnd < reStart) return null;
|
|
6753
|
+
const middle = parseMiddle(newInput, reStart, reEnd, cStart, ruleFn, separator, build);
|
|
6754
|
+
if (!middle) return null;
|
|
6755
|
+
if (middle.length > 0) {
|
|
6756
|
+
const last2 = middle[middle.length - 1];
|
|
6757
|
+
if (!(last2._tag === "leaf" && last2.value === separator)) return null;
|
|
6758
|
+
}
|
|
6759
|
+
if (reEnd < newInput.length) {
|
|
6760
|
+
for (const sentinel of [" ", "\uFFFF"]) {
|
|
6761
|
+
if (newInput[reEnd] === sentinel) continue;
|
|
6762
|
+
const probed = newInput.slice(0, reEnd) + sentinel.repeat(newInput.length - reEnd);
|
|
6763
|
+
const probe = parseMiddle(probed, reStart, reEnd, cStart, ruleFn, separator, build);
|
|
6764
|
+
if (!probe || probe.length !== middle.length) return null;
|
|
6765
|
+
for (let i = 0; i < middle.length; i++) if (!structurallyEqual(probe[i], middle[i])) return null;
|
|
6766
|
+
}
|
|
6767
|
+
}
|
|
6768
|
+
const head = kids.slice(0, h);
|
|
6769
|
+
const tail = kids.slice(t).map((k) => shiftRelStart(k, delta));
|
|
6770
|
+
const newC = {
|
|
6771
|
+
...C,
|
|
6772
|
+
span: { start: C.span.start, end: C.span.end + delta },
|
|
6773
|
+
children: [...head, ...middle, ...tail]
|
|
6774
|
+
};
|
|
6775
|
+
return graftRelative(root, path, newC, delta);
|
|
6776
|
+
}
|
|
6429
6777
|
function structurallyEqual(a, b) {
|
|
6430
6778
|
if (a === b) return true;
|
|
6431
6779
|
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
|
|
@@ -6469,27 +6817,68 @@ function boundaryIsSafe(ruleFn, newInput, start, boundary, state, build, produce
|
|
|
6469
6817
|
}
|
|
6470
6818
|
var ParseDocImpl = class _ParseDocImpl {
|
|
6471
6819
|
_registry;
|
|
6820
|
+
/** Registry entries normalized to callable parse functions (memoized once). */
|
|
6821
|
+
_fns;
|
|
6822
|
+
/** Rule names the grammar proves are genuine repetitions — the ONLY splice-safe types. */
|
|
6823
|
+
_reps;
|
|
6472
6824
|
_rootRule;
|
|
6473
6825
|
_opts;
|
|
6474
|
-
|
|
6826
|
+
/**
|
|
6827
|
+
* The tree, held in whichever coordinate system it arrived in. A fresh parse
|
|
6828
|
+
* arrives ABSOLUTE (`_abs` set); an incremental graft arrives PARENT-RELATIVE
|
|
6829
|
+
* (`_rel` set). The public `tree` is always the RELATIVE form (so untouched
|
|
6830
|
+
* subtrees stay shared by identity across edits and reads are O(1)); it's
|
|
6831
|
+
* materialized from `_abs` once, on demand, and memoized. `undefined` = not yet
|
|
6832
|
+
* computed; `null` = failed parse. A fresh parse that's never edited nor
|
|
6833
|
+
* tree-read pays no conversion — important for the full-reparse fallback path.
|
|
6834
|
+
*/
|
|
6835
|
+
_abs;
|
|
6836
|
+
_rel;
|
|
6475
6837
|
errors;
|
|
6476
6838
|
input;
|
|
6477
|
-
constructor(registry, rootRule, opts,
|
|
6839
|
+
constructor(registry, rootRule, opts, trees, errors, input) {
|
|
6478
6840
|
this._registry = registry;
|
|
6841
|
+
this._fns = {};
|
|
6842
|
+
this._reps = /* @__PURE__ */ new Set();
|
|
6843
|
+
for (const [name, entry] of Object.entries(registry)) {
|
|
6844
|
+
this._fns[name] = asRuleFn(entry);
|
|
6845
|
+
if (producesRepetition(defOf(entry))) this._reps.add(name);
|
|
6846
|
+
}
|
|
6479
6847
|
this._rootRule = rootRule;
|
|
6480
6848
|
this._opts = opts;
|
|
6481
|
-
this.
|
|
6849
|
+
this._abs = trees.abs;
|
|
6850
|
+
this._rel = trees.rel;
|
|
6482
6851
|
this.errors = errors;
|
|
6483
6852
|
this.input = input;
|
|
6484
6853
|
}
|
|
6854
|
+
/**
|
|
6855
|
+
* The parse tree with PARENT-RELATIVE spans — a node's `span` is relative to
|
|
6856
|
+
* its parent's start (root base 0). This is the shareable representation:
|
|
6857
|
+
* untouched subtrees keep the same identity across `.edit()`s, and reading the
|
|
6858
|
+
* tree after a length-changing edit is O(1) (no offset rewrite). For absolute
|
|
6859
|
+
* positions use the O(depth) cursor `spanAt(path)`, or `absolutizeCST(tree)` to
|
|
6860
|
+
* materialize the whole absolute tree. (A fresh non-incremental `node().parse()`
|
|
6861
|
+
* result is unchanged — still absolute.)
|
|
6862
|
+
*/
|
|
6863
|
+
get tree() {
|
|
6864
|
+
if (this._rel === void 0) {
|
|
6865
|
+
this._rel = this._abs ? relativizeCST(this._abs, 0) : null;
|
|
6866
|
+
}
|
|
6867
|
+
return this._rel;
|
|
6868
|
+
}
|
|
6869
|
+
spanAt(path) {
|
|
6870
|
+
const rel = this.tree;
|
|
6871
|
+
if (!rel) throw new Error("spanAt on a failed parse (tree is null)");
|
|
6872
|
+
return absoluteSpanCST(rel, path);
|
|
6873
|
+
}
|
|
6485
6874
|
edit(from, to, replacement) {
|
|
6486
6875
|
const newInput = this.input.slice(0, from) + replacement + this.input.slice(to);
|
|
6487
6876
|
const reparse = () => parseDoc(this._registry, this._rootRule, newInput, this._opts);
|
|
6488
|
-
|
|
6877
|
+
const root = this.tree;
|
|
6878
|
+
if (!root) return reparse();
|
|
6489
6879
|
const delta = replacement.length - (to - from);
|
|
6490
|
-
const found = findContaining(
|
|
6491
|
-
|
|
6492
|
-
const ancestors = ancestorsAt(this.tree, found.path);
|
|
6880
|
+
const found = findContaining(root, 0, from) ?? { node: root, path: [] };
|
|
6881
|
+
const ancestors = ancestorsAt(root, found.path);
|
|
6493
6882
|
const candidates = [found];
|
|
6494
6883
|
const pathCopy = [...found.path];
|
|
6495
6884
|
for (let i = ancestors.length - 2; i >= 0; i--) {
|
|
@@ -6498,37 +6887,50 @@ var ParseDocImpl = class _ParseDocImpl {
|
|
|
6498
6887
|
}
|
|
6499
6888
|
const rebuild = this._opts.rebuild ?? defaultRebuild;
|
|
6500
6889
|
for (const { node: node2, path } of candidates) {
|
|
6501
|
-
|
|
6502
|
-
|
|
6890
|
+
const { start: absStart, end: absEnd } = absoluteSpanCST(root, path);
|
|
6891
|
+
if (absEnd - absStart > this.input.length * REENTRY_MAX_SPAN_FRACTION) break;
|
|
6892
|
+
const ruleFn = this._fns[node2.type];
|
|
6503
6893
|
if (!ruleFn) continue;
|
|
6504
|
-
if (!(
|
|
6894
|
+
if (!(absStart <= from && to <= absEnd)) continue;
|
|
6505
6895
|
const ctx = { trackLines: false, state: node2.state, build: this._opts.build };
|
|
6506
|
-
const r = ruleFn(newInput,
|
|
6896
|
+
const r = ruleFn(newInput, absStart, ctx);
|
|
6507
6897
|
if (!r.ok) continue;
|
|
6508
|
-
if (r.span.end !==
|
|
6509
|
-
if (!boundaryIsSafe(ruleFn, newInput,
|
|
6898
|
+
if (r.span.end !== absEnd + delta) continue;
|
|
6899
|
+
if (!boundaryIsSafe(ruleFn, newInput, absStart, absEnd + delta, node2.state, this._opts.build, r)) {
|
|
6510
6900
|
continue;
|
|
6511
6901
|
}
|
|
6902
|
+
const parentBase = absStart - node2.span.start;
|
|
6903
|
+
const newRel = relativizeCST(r.value, parentBase);
|
|
6512
6904
|
if (delta === 0) {
|
|
6513
|
-
const newTree2 = replaceAtPath(rebuild,
|
|
6514
|
-
return new _ParseDocImpl(this._registry, this._rootRule, this._opts, newTree2, [], newInput);
|
|
6905
|
+
const newTree2 = replaceAtPath(rebuild, root, path, newRel);
|
|
6906
|
+
return new _ParseDocImpl(this._registry, this._rootRule, this._opts, { rel: newTree2 }, [], newInput);
|
|
6515
6907
|
}
|
|
6516
6908
|
if (this._opts.rebuild) return reparse();
|
|
6517
|
-
const newTree =
|
|
6518
|
-
return new _ParseDocImpl(this._registry, this._rootRule, this._opts, newTree, [], newInput);
|
|
6909
|
+
const newTree = graftRelative(root, path, newRel, delta);
|
|
6910
|
+
return new _ParseDocImpl(this._registry, this._rootRule, this._opts, { rel: newTree }, [], newInput);
|
|
6911
|
+
}
|
|
6912
|
+
if (this._opts.structuralReuse && delta !== 0 && !this._opts.rebuild) {
|
|
6913
|
+
const spliceCandidates = [...candidates, { node: root, path: [] }];
|
|
6914
|
+
for (const { node: node2, path } of spliceCandidates) {
|
|
6915
|
+
if (!this._reps.has(node2.type)) continue;
|
|
6916
|
+
const { start: cStart, end: cEnd } = absoluteSpanCST(root, path);
|
|
6917
|
+
if (!(cStart <= from && to <= cEnd)) continue;
|
|
6918
|
+
const spliced = tryListSplice(root, path, node2, cStart, newInput, from, to, delta, this._fns, this._opts.build);
|
|
6919
|
+
if (spliced) return new _ParseDocImpl(this._registry, this._rootRule, this._opts, { rel: spliced }, [], newInput);
|
|
6920
|
+
}
|
|
6519
6921
|
}
|
|
6520
6922
|
return reparse();
|
|
6521
6923
|
}
|
|
6522
6924
|
};
|
|
6523
6925
|
function parseDoc(registry, rootRule, input, opts = {}) {
|
|
6524
|
-
const
|
|
6525
|
-
if (!
|
|
6926
|
+
const entry = registry[rootRule];
|
|
6927
|
+
if (!entry) throw new Error(`No rule '${rootRule}' in registry`);
|
|
6526
6928
|
const ctx = { trackLines: false, state: opts.state, build: opts.build };
|
|
6527
|
-
const r =
|
|
6929
|
+
const r = asRuleFn(entry)(input, 0, ctx);
|
|
6528
6930
|
if (r.ok) {
|
|
6529
|
-
return new ParseDocImpl(registry, rootRule, opts, r.value, [], input);
|
|
6931
|
+
return new ParseDocImpl(registry, rootRule, opts, { abs: r.value }, [], input);
|
|
6530
6932
|
}
|
|
6531
|
-
return new ParseDocImpl(registry, rootRule, opts, null, [{ ok: false, expected: r.expected, span: r.span }], input);
|
|
6933
|
+
return new ParseDocImpl(registry, rootRule, opts, { abs: null }, [{ ok: false, expected: r.expected, span: r.span }], input);
|
|
6532
6934
|
}
|
|
6533
6935
|
|
|
6534
6936
|
// src/functional/run.ts
|
|
@@ -6897,72 +7299,6 @@ function buildOffsetIndex(root, input = "") {
|
|
|
6897
7299
|
return new OffsetIndex(collectLeafSlots(root), 0, input.length);
|
|
6898
7300
|
}
|
|
6899
7301
|
|
|
6900
|
-
// src/cst/relative-spans.ts
|
|
6901
|
-
function relativize(node2, parentBase = 0) {
|
|
6902
|
-
return {
|
|
6903
|
-
start: node2.start - parentBase,
|
|
6904
|
-
end: node2.end - parentBase,
|
|
6905
|
-
children: node2.children.map((c) => relativize(c, node2.start))
|
|
6906
|
-
};
|
|
6907
|
-
}
|
|
6908
|
-
function absolutize(node2, parentBase = 0) {
|
|
6909
|
-
const start = parentBase + node2.start;
|
|
6910
|
-
return {
|
|
6911
|
-
start,
|
|
6912
|
-
end: parentBase + node2.end,
|
|
6913
|
-
children: node2.children.map((c) => absolutize(c, start))
|
|
6914
|
-
};
|
|
6915
|
-
}
|
|
6916
|
-
function absoluteSpanAt(root, path) {
|
|
6917
|
-
let base = 0;
|
|
6918
|
-
let node2 = root;
|
|
6919
|
-
for (const idx of path) {
|
|
6920
|
-
base += node2.start;
|
|
6921
|
-
const child = node2.children[idx];
|
|
6922
|
-
if (!child) throw new RangeError(`absoluteSpanAt: no child ${idx} on path ${path.join(".")}`);
|
|
6923
|
-
node2 = child;
|
|
6924
|
-
}
|
|
6925
|
-
return { start: base + node2.start, end: base + node2.end };
|
|
6926
|
-
}
|
|
6927
|
-
function shiftAbsolute(node2, at, delta) {
|
|
6928
|
-
const s = node2.start >= at ? node2.start + delta : node2.start;
|
|
6929
|
-
const e = node2.end >= at ? node2.end + delta : node2.end;
|
|
6930
|
-
return {
|
|
6931
|
-
start: s,
|
|
6932
|
-
end: e,
|
|
6933
|
-
children: node2.children.map((c) => shiftAbsolute(c, at, delta))
|
|
6934
|
-
};
|
|
6935
|
-
}
|
|
6936
|
-
function applyEdit(root, at, delta, stats) {
|
|
6937
|
-
return editNode(root, at, delta, 0, 0, stats);
|
|
6938
|
-
}
|
|
6939
|
-
function editNode(node2, at, delta, parentBase, parentShift, stats) {
|
|
6940
|
-
const absStart = parentBase + node2.start;
|
|
6941
|
-
const absEnd = parentBase + node2.end;
|
|
6942
|
-
if (absEnd < at) return node2;
|
|
6943
|
-
const startShifts = absStart >= at;
|
|
6944
|
-
if (startShifts && parentShift === delta) return node2;
|
|
6945
|
-
if (stats) stats.allocated++;
|
|
6946
|
-
const newAbsStart = startShifts ? absStart + delta : absStart;
|
|
6947
|
-
const newAbsEnd = absEnd + delta;
|
|
6948
|
-
const newParentBase = parentBase + parentShift;
|
|
6949
|
-
const newStart = newAbsStart - newParentBase;
|
|
6950
|
-
const newEnd = newAbsEnd - newParentBase;
|
|
6951
|
-
const ownShift = newAbsStart - absStart;
|
|
6952
|
-
let changed = false;
|
|
6953
|
-
const newChildren = [];
|
|
6954
|
-
for (const c of node2.children) {
|
|
6955
|
-
const nc = editNode(c, at, delta, absStart, ownShift, stats);
|
|
6956
|
-
if (nc !== c) changed = true;
|
|
6957
|
-
newChildren.push(nc);
|
|
6958
|
-
}
|
|
6959
|
-
return {
|
|
6960
|
-
start: newStart,
|
|
6961
|
-
end: newEnd,
|
|
6962
|
-
children: changed ? newChildren : node2.children
|
|
6963
|
-
};
|
|
6964
|
-
}
|
|
6965
|
-
|
|
6966
7302
|
// src/index.ts
|
|
6967
7303
|
registerRegexAnalyzer(firstSetFromRegex);
|
|
6968
7304
|
//# sourceMappingURL=index.cjs.map
|