@ai-react-markdown/engine 2.4.3 → 2.5.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/dist/index.dev.js CHANGED
@@ -176,6 +176,74 @@ var defaultUrlTransform = (value) => {
176
176
  import { htmlBlockNames } from "micromark-util-html-tag-name";
177
177
  import { normalizeIdentifier } from "micromark-util-normalize-identifier";
178
178
  var TYPE6_NAMES = new Set(htmlBlockNames);
179
+ var TABLE_PART_NAMES = /* @__PURE__ */ new Set(["td", "th", "tr", "tbody", "thead", "tfoot", "caption", "col", "colgroup"]);
180
+ var HTML_BREAKOUT_TAGS = /* @__PURE__ */ new Set([
181
+ "b",
182
+ "big",
183
+ "blockquote",
184
+ "body",
185
+ "br",
186
+ "center",
187
+ "code",
188
+ "dd",
189
+ "div",
190
+ "dl",
191
+ "dt",
192
+ "em",
193
+ "embed",
194
+ "h1",
195
+ "h2",
196
+ "h3",
197
+ "h4",
198
+ "h5",
199
+ "h6",
200
+ "head",
201
+ "hr",
202
+ "i",
203
+ "img",
204
+ "li",
205
+ "listing",
206
+ "menu",
207
+ "meta",
208
+ "nobr",
209
+ "ol",
210
+ "p",
211
+ "pre",
212
+ "ruby",
213
+ "s",
214
+ "small",
215
+ "span",
216
+ "strong",
217
+ "strike",
218
+ "sub",
219
+ "sup",
220
+ "table",
221
+ "tt",
222
+ "u",
223
+ "ul",
224
+ "var"
225
+ ]);
226
+ var HTML_INTEGRATION_POINTS = ["foreignobject", "desc", "mi", "mo", "mn", "ms", "mtext", "annotation-xml"];
227
+ var TYPE1_NAMES = /* @__PURE__ */ new Set(["script", "pre", "style", "textarea"]);
228
+ var RAW_TEXT_ELEMENTS = /* @__PURE__ */ new Set([
229
+ "script",
230
+ "style",
231
+ "textarea",
232
+ "title",
233
+ "xmp",
234
+ "iframe",
235
+ "noembed",
236
+ "noframes",
237
+ // NOT `noscript`: hast-util-raw constructs parse5 with
238
+ // `scriptingEnabled: false`, under which `<noscript>` content is ordinary
239
+ // HTML — modelling it as raw text ignored a `<b>` inside and under-blocked
240
+ // (oracle review of the r2 batch; regression caught before release).
241
+ "plaintext"
242
+ ]);
243
+ var TYPE6_START_RE = /^<\/?([A-Za-z][A-Za-z0-9-]*)(?:[ \t\r]|\/?>|$)/;
244
+ var TYPE1_START_RE = /^<(script|pre|style|textarea)(?:[ \t\r]|>|$)/i;
245
+ var TYPE7_LINE_RE = /^(?:<[A-Za-z][A-Za-z0-9-]*(?:[ \t\r][^>]*|\/)?>|<\/[A-Za-z][A-Za-z0-9-]*[ \t\r]*>)[ \t\r]*$/;
246
+ var t7Name = (line) => /^<\/?([A-Za-z][A-Za-z0-9-]*)/.exec(line)[1];
179
247
  var VOID_TAGS = /* @__PURE__ */ new Set([
180
248
  "area",
181
249
  "base",
@@ -199,7 +267,35 @@ var DEF_RE = /^ {0,3}\[((?:[^[\]\\]|\\.)+)\]:/;
199
267
  var FENCE_RE = /^ {0,3}(`{3,}|~{3,})/;
200
268
  var MATH_RUN_RE = /^ {0,3}(\$\$+)/;
201
269
  var TAG_OR_COMMENT_RE = /<(\/?)([A-Za-z][A-Za-z0-9-]*)(?=[\s/>])([^>]*)>|<!--|-->|--!>/g;
202
- var TRUNCATED_TAG_RE = /<(\/?)([A-Za-z][A-Za-z0-9-]*)([^<>]*)$/;
270
+ var TRUNCATED_TAG_RE = /<(\/?)([A-Za-z][A-Za-z0-9-]*)([^>]*)$/;
271
+ var TAG_START_LT_RE = /<\/?[A-Za-z]/g;
272
+ function scanTagAttrs(text, from, to, out) {
273
+ let st = out.state;
274
+ for (let i = from; i < to; i++) {
275
+ const c = text[i];
276
+ if (st === '"' || st === "'") {
277
+ if (c === st) st = "outside";
278
+ continue;
279
+ }
280
+ const ws = c === " " || c === " " || c === "\n" || c === "\r" || c === "\f";
281
+ if (st === "afterEq") {
282
+ if (ws) continue;
283
+ if (c === '"' || c === "'") st = c;
284
+ else if (c === ">") return i;
285
+ else st = "unquoted";
286
+ continue;
287
+ }
288
+ if (st === "unquoted") {
289
+ if (ws) st = "outside";
290
+ else if (c === ">") return i;
291
+ continue;
292
+ }
293
+ if (c === "=") st = "afterEq";
294
+ else if (c === ">") return i;
295
+ }
296
+ out.state = st;
297
+ return -1;
298
+ }
203
299
  var REF_RE = /!?\[((?:[^[\]\\]|\\.)*)\]/g;
204
300
  var BACKTICK_RUN_RE = /`+/g;
205
301
  var MD_BLANK_RE = /^[ \t\r]*$/;
@@ -294,6 +390,8 @@ function freshCheckpoint(defListEnabled, mathFlow, referenceTaint) {
294
390
  openTotal: 0,
295
391
  commentOpen: false,
296
392
  piOpen: false,
393
+ bogusOpen: false,
394
+ rawTextOpen: null,
297
395
  declOpen: false,
298
396
  cdataOpen: false,
299
397
  inFence: false,
@@ -314,7 +412,12 @@ function freshCheckpoint(defListEnabled, mathFlow, referenceTaint) {
314
412
  htmlFlowSinceBlank: false,
315
413
  htmlSeamPending: false,
316
414
  phasePoisonedAt: Infinity,
317
- pendingTruncatedTags: []
415
+ pendingTruncatedTags: [],
416
+ pendingTruncatedCloses: [],
417
+ tagAcrossLines: false,
418
+ tagAcrossLinesIndent: 0,
419
+ tagAcrossLinesState: "outside",
420
+ htmlFlowReal: false
318
421
  };
319
422
  }
320
423
  function isPlausibleLinkDefRest(rest) {
@@ -413,11 +516,21 @@ function computeFreezeBoundary(text, options, resume) {
413
516
  let start = cp.confirmedOffset;
414
517
  let tailLine = null;
415
518
  while (start < text.length) {
416
- let end = text.indexOf("\n", start);
417
- if (end === -1) end = text.length;
418
- const confirmed = end < text.length;
419
- const rawLine = text.slice(start, end);
420
- const lineText = rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine;
519
+ let end = text.length;
520
+ let textEnd = text.length;
521
+ {
522
+ const nl = text.indexOf("\n", start);
523
+ const cr = text.indexOf("\r", start);
524
+ if (cr !== -1 && (nl === -1 || cr < nl)) {
525
+ textEnd = cr;
526
+ end = text.charCodeAt(cr + 1) === 10 ? cr + 1 : cr;
527
+ } else if (nl !== -1) {
528
+ textEnd = nl;
529
+ end = nl;
530
+ }
531
+ }
532
+ const confirmed = end < text.length && !(end === text.length - 1 && text.charCodeAt(end) === 13);
533
+ const lineText = text.slice(start, textEnd);
421
534
  const ln = {
422
535
  start,
423
536
  end,
@@ -509,14 +622,33 @@ function processConfirmedLine(cp, ln, text) {
509
622
  newest.defListSettled = ln.blank ? true : !canBecomeDdLine(ln.text, true);
510
623
  }
511
624
  const isBlockStart = cp.prevLineBlank;
512
- if (cp.htmlSeamPending && !ln.blank && !cp.htmlFlowSinceBlank && !(cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen)) {
625
+ if (cp.htmlSeamPending && !ln.blank && !cp.htmlFlowSinceBlank && !(cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen || cp.bogusOpen)) {
513
626
  const defShapedLine = DEF_RE.test(ln.text) || FOOTNOTE_DEF_RE.test(ln.text);
514
627
  const commentOnly = ln.text.replace(/<!--[\s\S]*?-->/g, " ").replace(/<!--[\s\S]*$/, " ").replace(/[ \t\r]/g, "") === "";
515
628
  if (!defShapedLine && !commentOnly) {
516
629
  cp.htmlSeamPending = false;
517
630
  }
518
631
  }
632
+ const inForeignContent = () => (cp.tagBalance.get("svg") ?? 0) > 0 || (cp.tagBalance.get("math") ?? 0) > 0;
633
+ const honoursSelfClosing = (tag) => {
634
+ if (tag === "svg" || tag === "math") return true;
635
+ if (!inForeignContent() || HTML_BREAKOUT_TAGS.has(tag)) return false;
636
+ for (const ip of HTML_INTEGRATION_POINTS) if ((cp.tagBalance.get(ip) ?? 0) > 0) return false;
637
+ return true;
638
+ };
639
+ const htmlRulesApply = () => {
640
+ if (!inForeignContent()) return true;
641
+ for (const ip of HTML_INTEGRATION_POINTS) if ((cp.tagBalance.get(ip) ?? 0) > 0) return true;
642
+ return false;
643
+ };
519
644
  const applyTag = (tag, closing) => {
645
+ if (cp.rawTextOpen !== null) {
646
+ if (!(closing && tag === cp.rawTextOpen)) return;
647
+ cp.rawTextOpen = null;
648
+ } else if (!closing && RAW_TEXT_ELEMENTS.has(tag) && htmlRulesApply()) {
649
+ cp.rawTextOpen = tag;
650
+ if (tag === "plaintext") cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
651
+ }
520
652
  if (closing) {
521
653
  const count = cp.tagBalance.get(tag) ?? 0;
522
654
  if (count > 0) {
@@ -529,7 +661,7 @@ function processConfirmedLine(cp, ln, text) {
529
661
  }
530
662
  };
531
663
  const commentOpenAtLineStart = cp.commentOpen;
532
- const rawOpenAtLineStart = cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen;
664
+ const rawOpenAtLineStart = cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen || cp.bogusOpen;
533
665
  if (cp.inFence) {
534
666
  const close = FENCE_RE.exec(ln.text);
535
667
  if (close && close[1][0] === cp.fenceChar && close[1].length >= cp.fenceLen && isMdBlank(ln.text.slice(close[0].length))) {
@@ -611,12 +743,22 @@ function processConfirmedLine(cp, ln, text) {
611
743
  for (const tag of cp.pendingTruncatedTags) applyTag(tag, true);
612
744
  cp.pendingTruncatedTags = [];
613
745
  }
746
+ cp.pendingTruncatedCloses = [];
747
+ if (cp.tagAcrossLines && (cp.tagAcrossLinesState === '"' || cp.tagAcrossLinesState === "'")) {
748
+ cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
749
+ }
750
+ cp.tagAcrossLines = false;
751
+ cp.tagAcrossLinesState = "outside";
752
+ if (cp.bogusOpen) {
753
+ cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
754
+ cp.bogusOpen = false;
755
+ }
614
756
  cp.blankRun += 1;
615
757
  cp.lastBlankStart = ln.start;
616
758
  cp.candidates.push({
617
759
  offset: Math.min(ln.end + 1, text.length),
618
760
  blankRun: cp.blankRun,
619
- htmlBalanced: cp.openTotal === 0 && !cp.commentOpen && !cp.piOpen && !cp.declOpen && !cp.cdataOpen,
761
+ htmlBalanced: cp.openTotal === 0 && !cp.commentOpen && !cp.piOpen && !cp.declOpen && !cp.cdataOpen && !cp.bogusOpen,
620
762
  hazard: cp.hazardVerdict,
621
763
  seamRisk: cp.htmlSeamPending,
622
764
  defListSettled: null
@@ -624,6 +766,7 @@ function processConfirmedLine(cp, ln, text) {
624
766
  cp.paragraphHasUnpairedRun = false;
625
767
  cp.openBracket = null;
626
768
  cp.htmlFlowSinceBlank = false;
769
+ cp.htmlFlowReal = false;
627
770
  cp.prevLineBlank = true;
628
771
  cp.prevLineWasText = false;
629
772
  cp.prevLineWasValidDef = false;
@@ -639,6 +782,16 @@ function processConfirmedLine(cp, ln, text) {
639
782
  if (tagStart) {
640
783
  cp.htmlFlowSinceBlank = true;
641
784
  if (!TYPE6_NAMES.has(tagStart[1].toLowerCase())) cp.hazardVerdict = true;
785
+ if (!cp.htmlFlowReal) {
786
+ const t = mdTrimStart(ln.text);
787
+ const t6 = TYPE6_START_RE.exec(t);
788
+ const t7 = TYPE7_LINE_RE.exec(t);
789
+ if (t6 !== null && TYPE6_NAMES.has(t6[1].toLowerCase()) || TYPE1_START_RE.test(t) || // Type 7 cannot interrupt a paragraph, and excludes the raw-text
790
+ // names (those are type 1 as start tags, paragraph as end tags).
791
+ t7 !== null && !cp.prevLineWasText && !TYPE1_NAMES.has(t7Name(t).toLowerCase())) {
792
+ cp.htmlFlowReal = true;
793
+ }
794
+ }
642
795
  }
643
796
  const inRawText = cp.htmlFlowSinceBlank || rawOpenAtLineStart;
644
797
  const rawFlowStart = ln.indent <= 3 && /^<(?:!--|\?|![A-Za-z]|!\[CDATA\[)/.test(mdTrimStart(ln.text));
@@ -737,7 +890,7 @@ ${cont(scanText)}` };
737
890
  pos = c + 3;
738
891
  continue;
739
892
  }
740
- if (cp.declOpen) {
893
+ if (cp.declOpen || cp.bogusOpen) {
741
894
  const c = scanText.indexOf(">", pos);
742
895
  if (c === -1) {
743
896
  rawSpans.push([pos, scanText.length]);
@@ -745,6 +898,7 @@ ${cont(scanText)}` };
745
898
  }
746
899
  rawSpans.push([pos, c + 1]);
747
900
  cp.declOpen = false;
901
+ cp.bogusOpen = false;
748
902
  pos = c + 1;
749
903
  continue;
750
904
  }
@@ -752,10 +906,16 @@ ${cont(scanText)}` };
752
906
  const cd = scanText.indexOf("<![CDATA[", pos);
753
907
  const dm = scanText.slice(pos).search(/<![A-Za-z]/);
754
908
  const decl = dm === -1 ? -1 : pos + dm;
755
- const starts = [pi, cd, decl].filter((x) => x !== -1);
909
+ const bm = cp.htmlFlowReal ? scanText.slice(pos).search(/<!(?!--|[A-Za-z]|\[CDATA\[)|<\/(?![A-Za-z])/) : -1;
910
+ const bogus = bm === -1 ? -1 : pos + bm;
911
+ const starts = [pi, cd, decl, bogus].filter((x) => x !== -1);
756
912
  if (starts.length === 0) break;
757
913
  const first = Math.min(...starts);
758
- if (first === cd) {
914
+ if (first === bogus) {
915
+ rawSpans.push([bogus, bogus + 2]);
916
+ cp.bogusOpen = true;
917
+ pos = bogus + 2;
918
+ } else if (first === cd) {
759
919
  rawSpans.push([cd, cd + 9]);
760
920
  cp.cdataOpen = true;
761
921
  pos = cd + 9;
@@ -779,11 +939,30 @@ ${cont(scanText)}` };
779
939
  for (const [from, to] of rawSpans) {
780
940
  tagText = tagText.slice(0, from) + " ".repeat(to - from) + tagText.slice(to);
781
941
  }
782
- {
942
+ let skipTagScan = false;
943
+ if (cp.tagAcrossLines) {
944
+ if (ln.indent < cp.tagAcrossLinesIndent) poisonRawDivergence();
945
+ const attrs = { state: cp.tagAcrossLinesState };
946
+ const gt = scanTagAttrs(ln.text, 0, ln.text.length, attrs);
947
+ if (gt === -1) {
948
+ scanTagAttrs("\n", 0, 1, attrs);
949
+ cp.tagAcrossLinesState = attrs.state;
950
+ skipTagScan = true;
951
+ } else {
952
+ for (const tag of cp.pendingTruncatedCloses) applyTag(tag, true);
953
+ cp.pendingTruncatedCloses = [];
954
+ cp.tagAcrossLines = false;
955
+ cp.tagAcrossLinesState = "outside";
956
+ tagText = " ".repeat(gt + 1) + tagText.slice(gt + 1);
957
+ }
958
+ }
959
+ let tagHandledAsTruncated = false;
960
+ if (!skipTagScan) {
783
961
  TAG_OR_COMMENT_RE.lastIndex = 0;
784
962
  let m;
785
963
  let lastCommentOpenerIdx = -1;
786
964
  while ((m = TAG_OR_COMMENT_RE.exec(tagText)) !== null) {
965
+ if (cp.rawTextOpen !== null && (m[0] === "<!--" || m[0] === "-->" || m[0] === "--!>")) continue;
787
966
  if (m[0] === "<!--") {
788
967
  const next = tagText.slice(m.index + 4, m.index + 6);
789
968
  if (cp.commentOpen) {
@@ -809,8 +988,32 @@ ${cont(scanText)}` };
809
988
  if (cp.commentOpen) continue;
810
989
  const closing = m[1] === "/";
811
990
  const tag = m[2].toLowerCase();
812
- const selfClosing = m[3] !== void 0 && /\/\s*$/.test(m[3]);
813
- if (VOID_TAGS.has(tag) || selfClosing) continue;
991
+ if (TABLE_PART_NAMES.has(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + m.index);
992
+ let attrs = m[3] ?? "";
993
+ if (cp.htmlFlowReal && (cp.rawTextOpen === null || closing && tag === cp.rawTextOpen)) {
994
+ const attrStart = m.index + 1 + (closing ? 1 : 0) + m[2].length;
995
+ const st = { state: "outside" };
996
+ const gt = scanTagAttrs(tagText, attrStart, tagText.length, st);
997
+ if (gt === -1) {
998
+ if (!VOID_TAGS.has(tag)) {
999
+ if (closing) cp.pendingTruncatedCloses.push(tag);
1000
+ else applyTag(tag, false);
1001
+ }
1002
+ scanTagAttrs("\n", 0, 1, st);
1003
+ cp.tagAcrossLines = true;
1004
+ cp.tagAcrossLinesIndent = ln.indent;
1005
+ cp.tagAcrossLinesState = st.state;
1006
+ tagHandledAsTruncated = true;
1007
+ break;
1008
+ }
1009
+ if (gt + 1 !== m.index + m[0].length) {
1010
+ attrs = tagText.slice(attrStart, gt);
1011
+ TAG_OR_COMMENT_RE.lastIndex = gt + 1;
1012
+ }
1013
+ }
1014
+ if (closing && !cp.htmlFlowReal && !/^\s*$/.test(attrs)) continue;
1015
+ const selfClosing = /\/\s*$/.test(attrs);
1016
+ if (VOID_TAGS.has(tag) || selfClosing && honoursSelfClosing(tag)) continue;
814
1017
  applyTag(tag, closing);
815
1018
  }
816
1019
  if (cp.commentOpen && lastCommentOpenerIdx !== -1 && !inRawText) {
@@ -829,22 +1032,44 @@ ${cont(scanText)}` };
829
1032
  if (startMasked || wholeVisible || inRaw(mr.index) || cp.commentOpen) continue;
830
1033
  const closing = mr[1] === "/";
831
1034
  const tag = mr[2].toLowerCase();
1035
+ if (TABLE_PART_NAMES.has(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + mr.index);
1036
+ if (closing && mr[3] !== void 0 && !/^\s*$/.test(mr[3])) continue;
832
1037
  const selfClosing = mr[3] !== void 0 && /\/\s*$/.test(mr[3]);
833
- if (VOID_TAGS.has(tag) || selfClosing) continue;
1038
+ if (VOID_TAGS.has(tag) || selfClosing && honoursSelfClosing(tag)) continue;
834
1039
  applyTag(tag, closing);
835
1040
  }
836
1041
  }
837
1042
  if (cp.pendingTruncatedTags.length > 0 && ln.text.includes(">")) {
1043
+ if (cp.pendingTruncatedTags.some((t) => TABLE_PART_NAMES.has(t))) {
1044
+ cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
1045
+ }
838
1046
  cp.pendingTruncatedTags = [];
839
1047
  }
840
- if (!cp.commentOpen) {
841
- const lastLt = tagText.lastIndexOf("<");
1048
+ if (!cp.commentOpen && !tagHandledAsTruncated) {
1049
+ let lastLt = -1;
1050
+ TAG_START_LT_RE.lastIndex = 0;
1051
+ for (let ms = TAG_START_LT_RE.exec(tagText); ms !== null; ms = TAG_START_LT_RE.exec(tagText)) {
1052
+ lastLt = ms.index;
1053
+ TAG_START_LT_RE.lastIndex = ms.index + 1;
1054
+ }
842
1055
  if (lastLt !== -1 && !tagText.includes(">", lastLt)) {
843
1056
  const m2 = TRUNCATED_TAG_RE.exec(tagText.slice(lastLt));
844
1057
  if (m2) {
845
1058
  const closing = m2[1] === "/";
846
1059
  const tag = m2[2].toLowerCase();
847
- if (!VOID_TAGS.has(tag)) {
1060
+ if (TABLE_PART_NAMES.has(tag) && cp.htmlFlowReal) {
1061
+ cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + lastLt);
1062
+ }
1063
+ if (cp.htmlFlowReal) {
1064
+ cp.tagAcrossLines = true;
1065
+ cp.tagAcrossLinesIndent = ln.indent;
1066
+ const attrs = { state: "outside" };
1067
+ scanTagAttrs(m2[3] + "\n", 0, m2[3].length + 1, attrs);
1068
+ cp.tagAcrossLinesState = attrs.state;
1069
+ }
1070
+ if (closing) {
1071
+ if (!VOID_TAGS.has(tag) && cp.htmlFlowReal) cp.pendingTruncatedCloses.push(tag);
1072
+ } else if (!VOID_TAGS.has(tag)) {
848
1073
  applyTag(tag, closing);
849
1074
  const rawLastLt = ln.text.lastIndexOf("<");
850
1075
  const rawTruncated = rawLastLt !== -1 && !ln.text.includes(">", rawLastLt);
@@ -1387,6 +1612,9 @@ function countTrailingNewlines(value) {
1387
1612
  function countNewlines(text, end = text.length) {
1388
1613
  let count = 0;
1389
1614
  for (let i = text.indexOf("\n"); i !== -1 && i < end; i = text.indexOf("\n", i + 1)) count += 1;
1615
+ for (let i = text.indexOf("\r"); i !== -1 && i < end; i = text.indexOf("\r", i + 1)) {
1616
+ if (text.charCodeAt(i + 1) !== 10) count += 1;
1617
+ }
1390
1618
  return count;
1391
1619
  }
1392
1620
 
@@ -1506,7 +1734,7 @@ function normalizeId(s) {
1506
1734
  return normalizeIdentifier3(s);
1507
1735
  }
1508
1736
  function normalizeForMatch(s) {
1509
- return normalizeIdentifier3(s.replace(/\\(.)/g, "$1"));
1737
+ return normalizeIdentifier3(s);
1510
1738
  }
1511
1739
 
1512
1740
  // src/components/collectDefLabels.ts
@@ -1824,22 +2052,68 @@ function createRegistry(onEmpty) {
1824
2052
  labelSet: { footnoteLabels: /* @__PURE__ */ new Set(), linkLabels: /* @__PURE__ */ new Set() },
1825
2053
  version: 0,
1826
2054
  _reactIdMap: /* @__PURE__ */ new Map(),
2055
+ /** Symbol → its `documentIndex`, for chunks that supplied one. */
2056
+ _chunkIndex: /* @__PURE__ */ new Map(),
1827
2057
  _subscribers: /* @__PURE__ */ new Set(),
1828
2058
  _notifyScheduled: false,
1829
- allocateSymbol(reactId) {
2059
+ allocateSymbol(reactId, rawDocumentIndex) {
2060
+ const documentIndex = rawDocumentIndex !== void 0 && Number.isFinite(rawDocumentIndex) ? rawDocumentIndex : void 0;
2061
+ if (rawDocumentIndex !== void 0 && documentIndex === void 0) {
2062
+ console.warn(
2063
+ `[ai-react-markdown] documentIndex must be a finite number \u2014 received ${String(rawDocumentIndex)}; ignoring it for this chunk.`
2064
+ );
2065
+ }
1830
2066
  const existing = this._reactIdMap.get(reactId);
1831
2067
  if (existing) {
1832
2068
  existing.refcount++;
2069
+ const moved = documentIndex !== void 0 ? this._chunkIndex.get(existing.symbol) !== documentIndex : this._chunkIndex.has(existing.symbol);
2070
+ if (moved) {
2071
+ const at = this.chunkOrder.indexOf(existing.symbol);
2072
+ if (at !== -1) this.chunkOrder.splice(at, 1);
2073
+ this._placeChunk(existing.symbol, documentIndex);
2074
+ this._notify();
2075
+ }
1833
2076
  return existing.symbol;
1834
2077
  }
1835
2078
  const sym = Symbol(reactId);
1836
2079
  this._reactIdMap.set(reactId, { symbol: sym, refcount: 1 });
1837
- this.chunkOrder.push(sym);
2080
+ this._placeChunk(sym, documentIndex);
1838
2081
  this._notify();
1839
2082
  return sym;
1840
2083
  },
1841
- registerChunk(reactId, footnotes, links) {
1842
- const sym = this.allocateSymbol(reactId);
2084
+ /** Put `sym` into `chunkOrder` at its document position. Without an index
2085
+ * it goes last (mount order — the historical behaviour); with one it
2086
+ * sorts before the first chunk that sits later, where a chunk WITHOUT an
2087
+ * index counts as "later" so an indexed chunk never lands behind one
2088
+ * whose position is unknown. */
2089
+ _placeChunk(sym, documentIndex) {
2090
+ if (this.chunkOrder.length > 0) {
2091
+ const anyIndexed = documentIndex !== void 0 || this.chunkOrder.some((s) => this._chunkIndex.has(s));
2092
+ const anyPlain = documentIndex === void 0 || this.chunkOrder.some((s) => !this._chunkIndex.has(s));
2093
+ if (anyIndexed && anyPlain) {
2094
+ console.warn(
2095
+ "[ai-react-markdown] Some chunks of this document supply `documentIndex` and some do not. Indexed chunks always sort ahead of un-indexed ones, so footnote numbering and aggregate-footer placement will not follow document order. Pass `documentIndex` to every chunk, or to none."
2096
+ );
2097
+ }
2098
+ }
2099
+ if (documentIndex === void 0) {
2100
+ this._chunkIndex.delete(sym);
2101
+ this.chunkOrder.push(sym);
2102
+ return;
2103
+ }
2104
+ this._chunkIndex.set(sym, documentIndex);
2105
+ let at = this.chunkOrder.length;
2106
+ for (let i = 0; i < this.chunkOrder.length; i++) {
2107
+ const other = this._chunkIndex.get(this.chunkOrder[i]);
2108
+ if (other === void 0 || other > documentIndex) {
2109
+ at = i;
2110
+ break;
2111
+ }
2112
+ }
2113
+ this.chunkOrder.splice(at, 0, sym);
2114
+ },
2115
+ registerChunk(reactId, footnotes, links, documentIndex) {
2116
+ const sym = this.allocateSymbol(reactId, documentIndex);
1843
2117
  this.contributeLabels(sym, footnotes, links);
1844
2118
  return sym;
1845
2119
  },
@@ -1862,6 +2136,7 @@ function createRegistry(onEmpty) {
1862
2136
  this._reactIdMap.delete(reactId);
1863
2137
  const idx = this.chunkOrder.indexOf(entry.symbol);
1864
2138
  if (idx !== -1) this.chunkOrder.splice(idx, 1);
2139
+ this._chunkIndex.delete(entry.symbol);
1865
2140
  this.chunkData.delete(entry.symbol);
1866
2141
  const nextFn = /* @__PURE__ */ new Set();
1867
2142
  const nextLink = /* @__PURE__ */ new Set();
@@ -3488,17 +3763,28 @@ function mergeClassNameAllowlist(existing, extraClassNames) {
3488
3763
  return entries;
3489
3764
  }
3490
3765
  var crossChunkTags = ["cross-chunk-link", "cross-chunk-image", "footnote-sup"];
3491
- var sanitizeSchema = cloneDeep_default({
3492
- ...defaultSchema,
3493
- tagNames: [...defaultSchema.tagNames || [], "mark", ...crossChunkTags],
3494
- attributes: {
3495
- ...defaultSchema.attributes,
3496
- code: mergeClassNameAllowlist(defaultSchema.attributes?.code, ["math-inline", "math-display"]),
3497
- "cross-chunk-link": ["label", "referenceType", "documentId", "localUrl", "localTitle"],
3498
- "cross-chunk-image": ["label", "referenceType", "documentId", "alt", "localUrl", "localTitle"],
3499
- "footnote-sup": ["label", "localOccurrence", "localNumber", "documentId"]
3500
- }
3501
- });
3766
+ function deepFreeze(value) {
3767
+ if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
3768
+ Object.freeze(value);
3769
+ for (const key of Object.keys(value)) deepFreeze(value[key]);
3770
+ }
3771
+ return value;
3772
+ }
3773
+ var STRIPPED_TAGS = ["script", "style", "title", "textarea", "noframes", "noembed", "xmp", "iframe", "plaintext"];
3774
+ var sanitizeSchema = deepFreeze(
3775
+ cloneDeep_default({
3776
+ ...defaultSchema,
3777
+ tagNames: [...defaultSchema.tagNames || [], "mark", ...crossChunkTags],
3778
+ attributes: {
3779
+ ...defaultSchema.attributes,
3780
+ code: mergeClassNameAllowlist(defaultSchema.attributes?.code, ["math-inline", "math-display"]),
3781
+ "cross-chunk-link": ["label", "referenceType", "documentId", "localUrl", "localTitle"],
3782
+ "cross-chunk-image": ["label", "referenceType", "documentId", "alt", "localUrl", "localTitle"],
3783
+ "footnote-sup": ["label", "localOccurrence", "localNumber", "documentId"]
3784
+ },
3785
+ strip: [.../* @__PURE__ */ new Set([...defaultSchema.strip || [], ...STRIPPED_TAGS])]
3786
+ })
3787
+ );
3502
3788
 
3503
3789
  // src/components/crossChunkUrlSanitize.ts
3504
3790
  function fakeElement(tagName, key, url) {
@@ -3821,7 +4107,12 @@ var createSmoothStreamController = (options = {}) => {
3821
4107
  return;
3822
4108
  }
3823
4109
  tentativeEnd = ends[ends.length - 1];
3824
- const confirmedEnds = finished ? ends : ends.slice(0, -1);
4110
+ let hold = 1;
4111
+ if (!finished && ends.length > 1) {
4112
+ const last = source.charCodeAt(source.length - 1);
4113
+ if (last >= 55296 && last <= 56319) hold = 2;
4114
+ }
4115
+ const confirmedEnds = finished ? ends : ends.slice(0, -hold);
3825
4116
  for (const end of confirmedEnds) pending.push(end);
3826
4117
  };
3827
4118
  const snap = (next) => {
@@ -3944,10 +4235,17 @@ function lineIndentBefore(content, pos) {
3944
4235
  function findClosingBacktickRun(content, start, n) {
3945
4236
  let i = start;
3946
4237
  while (i < content.length) {
3947
- if (content[i] === "`") {
4238
+ const ch = content[i];
4239
+ if (ch === "`") {
3948
4240
  const runLen = getRepeatedMarkerLength(content, i, "`");
3949
4241
  if (runLen === n) return i;
3950
4242
  i += runLen;
4243
+ } else if (ch === "\n" || ch === "\r") {
4244
+ let j = i + 1;
4245
+ if (ch === "\r" && content[j] === "\n") j += 1;
4246
+ while (j < content.length && (content[j] === " " || content[j] === " ")) j += 1;
4247
+ if (j >= content.length || content[j] === "\n" || content[j] === "\r") return -1;
4248
+ i += 1;
3951
4249
  } else {
3952
4250
  i += 1;
3953
4251
  }
@@ -4047,47 +4345,85 @@ function escapeMhchemCommands(text) {
4047
4345
  return text.replaceAll("$\\ce{", "$\\\\ce{").replaceAll("$\\pu{", "$\\\\pu{");
4048
4346
  }
4049
4347
  var CURRENCY_REGEX = /(?<![\\$])\$(?!\$)(?=\d+(?:,\d{3})*(?:\.\d+)?(?:[KMBkmb])?(?:\s|$|[^a-zA-Z\d]))/g;
4050
- var NO_ESCAPED_DOLLAR_REGEX = /(?<![\\$])\$(?!\$)/g;
4051
4348
  var DELIMITERS_REGEX = /(?<!!)\\\[([\S\s]*?[^\\])\\](?!\()|\\\((.*?)\\\)/g;
4052
4349
  var ARRAY_COL_SPEC_OR_PIPE_REGEX = /(\\begin\{(?:array|tabular[x*]?)\}\{[^}]*\})|(?<!\\)\|/g;
4053
- var LATEX_BLOCK_REGEX = /\$\$([\S\s]*?)\$\$|(?<![\\$])\$(?!\$)((?:[^$\n]|\\\$)*?)(?<![\\`])\$(?!\$)/g;
4350
+ var EVEN_BACKSLASHES = String.raw`(?<=(?:^|[^\\])(?:\\\\)*)`;
4351
+ var LATEX_BLOCK_REGEX = new RegExp(
4352
+ String.raw`${EVEN_BACKSLASHES}\$\$([\S\s]*?)${EVEN_BACKSLASHES}\$\$|(?<![\\$])\$(?!\$)((?:[^$\n]|\\\$)*?)(?<![\\` + "`" + String.raw`])\$(?!\$)`,
4353
+ "g"
4354
+ );
4054
4355
  var TEXT_COMMAND = "\\text{";
4055
4356
  var SINGLE_DOLLAR_REGEX = /(?<![\\$])\$(?!\$)((?:[^$\n]|\\[$])+?)(?<!\\)(?<!`)\$(?!\$)/g;
4357
+ function countBareDollars(str, from, to, prev, next) {
4358
+ let n = 0;
4359
+ for (let j = from; j < to; j++) {
4360
+ if (str.charCodeAt(j) !== 36) continue;
4361
+ const before = j > from ? str[j - 1] : prev;
4362
+ const after = j + 1 < to ? str[j + 1] : next;
4363
+ if (before !== "\\" && before !== "$" && after !== "$") n += 1;
4364
+ }
4365
+ return n;
4366
+ }
4056
4367
  function escapeCurrencyDollarSigns(text) {
4057
4368
  const parts = [];
4058
4369
  let lastIndex = 0;
4059
4370
  const currencyMatches = Array.from(text.matchAll(CURRENCY_REGEX));
4060
4371
  let currentLineProcessed = "";
4372
+ let currentLineDollars = 0;
4373
+ const appendToLine = (piece) => {
4374
+ if (piece.length === 0) return;
4375
+ const prevLast = currentLineProcessed.length > 0 ? currentLineProcessed[currentLineProcessed.length - 1] : "";
4376
+ const prevBeforeLast = currentLineProcessed.length > 1 ? currentLineProcessed[currentLineProcessed.length - 2] : "";
4377
+ const prevLastCounted = prevLast === "$" && prevBeforeLast !== "\\" && prevBeforeLast !== "$";
4378
+ if (prevLastCounted && piece[0] === "$") currentLineDollars -= 1;
4379
+ currentLineDollars += countBareDollars(piece, 0, piece.length, prevLast, "");
4380
+ currentLineProcessed += piece;
4381
+ };
4382
+ const resetLine = (rest) => {
4383
+ currentLineProcessed = "";
4384
+ currentLineDollars = 0;
4385
+ appendToLine(rest);
4386
+ };
4061
4387
  for (let i = 0; i < currencyMatches.length; i++) {
4062
4388
  const match = currencyMatches[i];
4063
4389
  const segment = text.substring(lastIndex, match.index);
4064
4390
  parts.push(segment);
4065
4391
  const newlineIdx = Math.max(segment.lastIndexOf("\n"), segment.lastIndexOf("\r"));
4066
4392
  if (newlineIdx !== -1) {
4067
- currentLineProcessed = segment.substring(newlineIdx + 1);
4393
+ resetLine(segment.substring(newlineIdx + 1));
4068
4394
  } else {
4069
- currentLineProcessed += segment;
4395
+ appendToLine(segment);
4070
4396
  }
4071
4397
  let needEscape = true;
4072
- let restBeforeNextMatchOrEnd = "";
4073
- if (i < currencyMatches.length - 1) {
4074
- const nextMatch = currencyMatches[i + 1];
4075
- if (nextMatch.index - match.index > 1) {
4076
- restBeforeNextMatchOrEnd = text.substring(match.index + 1, nextMatch.index);
4398
+ const restStart = match.index + 1;
4399
+ const restEnd = i < currencyMatches.length - 1 ? currencyMatches[i + 1].index : text.length;
4400
+ let firstLineBeforeNextMatch = "";
4401
+ if (restEnd - restStart > 0) {
4402
+ let eol = restEnd;
4403
+ for (let k = restStart; k < restEnd; k++) {
4404
+ const c = text.charCodeAt(k);
4405
+ if (c === 10 || c === 13) {
4406
+ eol = k;
4407
+ break;
4408
+ }
4077
4409
  }
4078
- } else {
4079
- restBeforeNextMatchOrEnd = text.substring(match.index + 1);
4410
+ firstLineBeforeNextMatch = text.substring(restStart, eol);
4080
4411
  }
4081
- const firstLineBeforeNextMatch = restBeforeNextMatchOrEnd.split(/\r\n|\r|\n/g)[0];
4082
- if (Array.from(firstLineBeforeNextMatch.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {
4083
- const wholeLineBeforeNextMatchWithoutCurrentDollar = currentLineProcessed + firstLineBeforeNextMatch;
4084
- if (Array.from(wholeLineBeforeNextMatchWithoutCurrentDollar.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {
4085
- needEscape = false;
4086
- }
4412
+ const restDollars = countBareDollars(firstLineBeforeNextMatch, 0, firstLineBeforeNextMatch.length, "", "");
4413
+ if (restDollars % 2 !== 0) {
4414
+ const L = currentLineProcessed;
4415
+ const lLast = L.length > 0 ? L[L.length - 1] : "";
4416
+ const lBeforeLast = L.length > 1 ? L[L.length - 2] : "";
4417
+ const lLastCounted = lLast === "$" && lBeforeLast !== "\\" && lBeforeLast !== "$";
4418
+ const f0 = firstLineBeforeNextMatch[0];
4419
+ let whole = currentLineDollars + restDollars;
4420
+ if (lLastCounted && f0 === "$") whole -= 1;
4421
+ if (f0 === "$" && (lLast === "\\" || lLast === "$") && firstLineBeforeNextMatch[1] !== "$") whole -= 1;
4422
+ if (whole % 2 !== 0) needEscape = false;
4087
4423
  }
4088
4424
  const replacement = needEscape ? "\\$" : "$";
4089
4425
  parts.push(replacement);
4090
- currentLineProcessed += replacement;
4426
+ appendToLine(replacement);
4091
4427
  lastIndex = match.index + 1;
4092
4428
  }
4093
4429
  parts.push(text.substring(lastIndex));
@@ -4155,8 +4491,7 @@ function escapeLatexPipesInUnclosed(text) {
4155
4491
  const tail = text.substring(unclosedStart + delimLen);
4156
4492
  return before + delim + replaceUnescapedPipes(tail);
4157
4493
  }
4158
- function truncateUnclosedLatexBlock(text) {
4159
- const unclosedStart = findUnclosedDelimiterStart(text, "double-only");
4494
+ function truncateUnclosedLatexBlock(text, unclosedStart = findUnclosedDelimiterStart(text, "double-only")) {
4160
4495
  if (unclosedStart === -1) return text;
4161
4496
  return text.substring(0, unclosedStart).trimEnd();
4162
4497
  }
@@ -4244,39 +4579,50 @@ function hasUnclosedTextCommand(text) {
4244
4579
  return false;
4245
4580
  }
4246
4581
  var RESIDUAL_OPEN_BRACKET_RE = /(?<!!)\\\[/;
4247
- function processSliceInstrumented(slice) {
4582
+ var LEADING_DOUBLE_DOLLAR_RE = /^\s*\$\$/;
4583
+ function processSliceInstrumented(slice, probe = true) {
4248
4584
  const segments = splitByProtectedRegions(slice);
4249
- let out = "";
4585
+ const parts = [];
4250
4586
  let quiescent = true;
4251
4587
  let truncatedAtSeamStart = false;
4252
4588
  for (let index = 0; index < segments.length; index++) {
4253
4589
  const segment = segments[index];
4254
4590
  if (segment.isCode) {
4255
- out += segment.text;
4591
+ parts.push(segment.text);
4256
4592
  continue;
4257
4593
  }
4258
4594
  let text = segment.text;
4259
4595
  text = escapeMhchemCommands(text);
4260
4596
  text = escapeCurrencyDollarSigns(text);
4261
4597
  text = convertLatexDelimiters(text);
4262
- if (RESIDUAL_OPEN_BRACKET_RE.test(text)) quiescent = false;
4598
+ if (probe && RESIDUAL_OPEN_BRACKET_RE.test(text)) quiescent = false;
4263
4599
  text = escapeLatexPipes(text);
4264
- if (findUnclosedDelimiterStart(text, "both") !== -1) quiescent = false;
4600
+ if (probe && findUnclosedDelimiterStart(text, "both") !== -1) quiescent = false;
4265
4601
  text = escapeLatexPipesInUnclosed(text);
4266
- if (hasUnclosedTextCommand(text)) quiescent = false;
4602
+ if (probe && hasUnclosedTextCommand(text)) quiescent = false;
4267
4603
  text = escapeTextUnderscores(text);
4268
4604
  text = convertSingleToDoubleDollar(text);
4269
- const unclosedDouble = findUnclosedDelimiterStart(text, "double-only");
4270
- if (unclosedDouble !== -1) {
4271
- quiescent = false;
4272
- if (index === 0 && text.slice(0, unclosedDouble).trim() === "") {
4273
- truncatedAtSeamStart = true;
4605
+ let unclosedDouble;
4606
+ if (probe || index === 0 && LEADING_DOUBLE_DOLLAR_RE.test(text)) {
4607
+ unclosedDouble = findUnclosedDelimiterStart(text, "double-only");
4608
+ if (unclosedDouble !== -1) {
4609
+ quiescent = false;
4610
+ if (index === 0 && text.slice(0, unclosedDouble).trim() === "") {
4611
+ truncatedAtSeamStart = true;
4612
+ }
4274
4613
  }
4275
4614
  }
4276
- text = truncateUnclosedLatexBlock(text);
4277
- out += text;
4615
+ text = truncateUnclosedLatexBlock(text, unclosedDouble);
4616
+ parts.push(text);
4278
4617
  }
4279
- return { out, quiescent, truncatedAtSeamStart };
4618
+ return { out: parts.join(""), quiescent, truncatedAtSeamStart };
4619
+ }
4620
+ function isBlankRawLine(text, from, to) {
4621
+ for (let i = from; i < to; i++) {
4622
+ const c = text.charCodeAt(i);
4623
+ if (c !== 32 && c !== 9 && c !== 13) return false;
4624
+ }
4625
+ return true;
4280
4626
  }
4281
4627
  function findRawSafeCut(active) {
4282
4628
  const segments = splitByProtectedRegions(active);
@@ -4291,10 +4637,12 @@ function findRawSafeCut(active) {
4291
4637
  continue;
4292
4638
  }
4293
4639
  const text = segment.text;
4640
+ let atLineStart = offset === 0 || active.charCodeAt(offset - 1) === 10;
4294
4641
  let lineStart = 0;
4295
4642
  while (lineStart <= text.length) {
4296
4643
  const nl = text.indexOf("\n", lineStart);
4297
4644
  const lineEnd = nl === -1 ? text.length : nl;
4645
+ if (atLineStart && nl !== -1 && isBlankRawLine(text, lineStart, lineEnd)) backtickHazard = false;
4298
4646
  for (let i = lineStart; i < lineEnd; i++) {
4299
4647
  const ch = text[i];
4300
4648
  if (ch === "`") backtickHazard = true;
@@ -4307,6 +4655,7 @@ function findRawSafeCut(active) {
4307
4655
  if (nl === -1) break;
4308
4656
  if (!backtickHazard && !latentLt) lastCut = offset + nl + 1;
4309
4657
  lineStart = nl + 1;
4658
+ atLineStart = true;
4310
4659
  }
4311
4660
  offset += text.length;
4312
4661
  }
@@ -4315,11 +4664,14 @@ function findRawSafeCut(active) {
4315
4664
  var DEFAULT_FREEZE_ATTEMPT_THRESHOLD = 512;
4316
4665
  function createIncrementalLatexPreprocessor(options) {
4317
4666
  const freezeThreshold = options?.freezeThreshold ?? DEFAULT_FREEZE_ATTEMPT_THRESHOLD;
4667
+ const onAttempt = options?.onAttempt;
4668
+ const backoff = options?.backoff ?? true;
4318
4669
  let prevSource = "";
4319
4670
  let prevOutput = "";
4320
4671
  let frozenSrcEnd = 0;
4321
4672
  let frozenOut = "";
4322
4673
  let triggered = false;
4674
+ let nextAttemptLen = 0;
4323
4675
  return function incrementalPreprocessLaTeX(source) {
4324
4676
  if (source === prevSource) return prevOutput;
4325
4677
  const isAppend = source.length > prevSource.length && source.startsWith(prevSource);
@@ -4327,6 +4679,7 @@ function createIncrementalLatexPreprocessor(options) {
4327
4679
  frozenSrcEnd = 0;
4328
4680
  frozenOut = "";
4329
4681
  triggered = false;
4682
+ nextAttemptLen = 0;
4330
4683
  }
4331
4684
  if (!triggered) {
4332
4685
  const checkFrom = isAppend ? Math.max(0, prevSource.length - 1) : 0;
@@ -4338,18 +4691,26 @@ function createIncrementalLatexPreprocessor(options) {
4338
4691
  triggered = true;
4339
4692
  }
4340
4693
  let active = source.slice(frozenSrcEnd);
4341
- if (active.length > freezeThreshold) {
4694
+ if (active.length > freezeThreshold && active.length >= nextAttemptLen) {
4695
+ const activeLength = active.length;
4696
+ let advanced = false;
4697
+ let frozenBytes = 0;
4698
+ const freeze = (cut2, slice) => {
4699
+ frozenOut += slice.out;
4700
+ frozenSrcEnd += cut2;
4701
+ active = source.slice(frozenSrcEnd);
4702
+ advanced = true;
4703
+ frozenBytes = cut2;
4704
+ };
4342
4705
  const cut = findRawSafeCut(active);
4343
4706
  if (cut > 0) {
4344
4707
  const candidate = processSliceInstrumented(active.slice(0, cut));
4345
- if (candidate.quiescent) {
4346
- frozenOut += candidate.out;
4347
- frozenSrcEnd += cut;
4348
- active = source.slice(frozenSrcEnd);
4349
- }
4708
+ if (candidate.quiescent) freeze(cut, candidate);
4350
4709
  }
4710
+ nextAttemptLen = advanced || !backoff ? 0 : active.length * 2;
4711
+ onAttempt?.({ activeLength, frozenBytes });
4351
4712
  }
4352
- const tail = processSliceInstrumented(active);
4713
+ const tail = processSliceInstrumented(active, false);
4353
4714
  const head = tail.truncatedAtSeamStart ? frozenOut.replace(/\s+$/, "") : frozenOut;
4354
4715
  const out = head + tail.out;
4355
4716
  prevSource = source;
@@ -4379,7 +4740,6 @@ function createRemendPreprocessor(options) {
4379
4740
  }
4380
4741
  export {
4381
4742
  DEFAULT_PAYLOAD,
4382
- DEF_LINE_START_RE,
4383
4743
  PIPELINE_STAGES,
4384
4744
  SENTINEL_FN_CONTENT,
4385
4745
  SENTINEL_LINK_URL,
@@ -4414,7 +4774,6 @@ export {
4414
4774
  hasLoneSurrogate,
4415
4775
  highlight,
4416
4776
  isFootnoteSection,
4417
- lastRegionStart,
4418
4777
  measureStage,
4419
4778
  mergeClassNameAllowlist,
4420
4779
  normalizeForMatch,