@ai-react-markdown/core 1.3.0 → 1.4.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 +72 -10
- package/dist/index.cjs +1211 -89
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +156 -3
- package/dist/index.d.ts +156 -3
- package/dist/index.js +1211 -91
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/index.tsx
|
|
4
|
-
import { useMemo as
|
|
4
|
+
import { useMemo as useMemo6, memo as memo4, useId as useId3 } from "react";
|
|
5
5
|
|
|
6
6
|
// src/context.tsx
|
|
7
7
|
import { createContext, useContext, useId, useMemo } from "react";
|
|
@@ -129,8 +129,8 @@ var root = freeGlobal_default || freeSelf || Function("return this")();
|
|
|
129
129
|
var root_default = root;
|
|
130
130
|
|
|
131
131
|
// ../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_Symbol.js
|
|
132
|
-
var
|
|
133
|
-
var Symbol_default =
|
|
132
|
+
var Symbol2 = root_default.Symbol;
|
|
133
|
+
var Symbol_default = Symbol2;
|
|
134
134
|
|
|
135
135
|
// ../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_getRawTag.js
|
|
136
136
|
var objectProto = Object.prototype;
|
|
@@ -1067,7 +1067,8 @@ var defaultAIMarkdownRenderConfig = Object.freeze({
|
|
|
1067
1067
|
"SMARTYPANTS" /* SMARTYPANTS */,
|
|
1068
1068
|
"PANGU" /* PANGU */
|
|
1069
1069
|
]),
|
|
1070
|
-
blockMemoEnabled: true
|
|
1070
|
+
blockMemoEnabled: true,
|
|
1071
|
+
preserveOrphanReferences: true
|
|
1071
1072
|
});
|
|
1072
1073
|
|
|
1073
1074
|
// src/context.tsx
|
|
@@ -1119,6 +1120,13 @@ var AIMarkdownRenderStateProvider = ({
|
|
|
1119
1120
|
variant,
|
|
1120
1121
|
colorScheme,
|
|
1121
1122
|
documentId: resolvedDocumentId,
|
|
1123
|
+
// URI-fragment safe per-document prefix derived once here so downstream
|
|
1124
|
+
// consumers (MarkdownContent, cross-chunk placeholder components) read
|
|
1125
|
+
// from one canonical source. `encodeURIComponent` runs at the prefix
|
|
1126
|
+
// construction site, not at the documentId storage site, so consumers
|
|
1127
|
+
// accessing `documentId` directly still see the raw React-native value
|
|
1128
|
+
// (e.g. `useId()`'s `_r_0_`) while id="..."/href="#..." bytes are safe.
|
|
1129
|
+
clobberPrefix: `${encodeURIComponent(resolvedDocumentId)}-user-content-`,
|
|
1122
1130
|
config: mergedConfig
|
|
1123
1131
|
}),
|
|
1124
1132
|
[streaming, fontSize, variant, colorScheme, resolvedDocumentId, mergedConfig]
|
|
@@ -1439,7 +1447,7 @@ function preprocessAIMDContent(content, extraPreprocessors = defaultExtraPreproc
|
|
|
1439
1447
|
}
|
|
1440
1448
|
|
|
1441
1449
|
// src/components/MarkdownContent.tsx
|
|
1442
|
-
import { Fragment as
|
|
1450
|
+
import { Fragment as Fragment3, memo as memo2, useCallback as useCallback2, useEffect, useId as useId2, useMemo as useMemo4, useRef as useRef2, useState, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
1443
1451
|
|
|
1444
1452
|
// src/components/markdown/Markdown.tsx
|
|
1445
1453
|
import { unreachable as unreachable2 } from "devlop";
|
|
@@ -1585,10 +1593,10 @@ function validateOptions(options) {
|
|
|
1585
1593
|
}
|
|
1586
1594
|
function parseStage(options) {
|
|
1587
1595
|
validateOptions(options);
|
|
1588
|
-
const
|
|
1596
|
+
const processor2 = createProcessor(options);
|
|
1589
1597
|
const file = createFile(options);
|
|
1590
|
-
const mdast =
|
|
1591
|
-
return { processor, file, mdast };
|
|
1598
|
+
const mdast = processor2.parse(file);
|
|
1599
|
+
return { processor: processor2, file, mdast };
|
|
1592
1600
|
}
|
|
1593
1601
|
function transformStage(parsed) {
|
|
1594
1602
|
return parsed.processor.runSync(parsed.mdast, parsed.file);
|
|
@@ -1644,12 +1652,16 @@ function mergeClassNameAllowlist(existing, extraClassNames) {
|
|
|
1644
1652
|
entries[idx] = merged;
|
|
1645
1653
|
return entries;
|
|
1646
1654
|
}
|
|
1655
|
+
var crossChunkTags = ["cross-chunk-link", "cross-chunk-image", "footnote-sup"];
|
|
1647
1656
|
var sanitizeSchema = {
|
|
1648
1657
|
...defaultSchema,
|
|
1649
|
-
tagNames: [...defaultSchema.tagNames || [], "mark"],
|
|
1658
|
+
tagNames: [...defaultSchema.tagNames || [], "mark", ...crossChunkTags],
|
|
1650
1659
|
attributes: {
|
|
1651
1660
|
...defaultSchema.attributes,
|
|
1652
|
-
code: mergeClassNameAllowlist(defaultSchema.attributes?.code, ["math-inline", "math-display"])
|
|
1661
|
+
code: mergeClassNameAllowlist(defaultSchema.attributes?.code, ["math-inline", "math-display"]),
|
|
1662
|
+
"cross-chunk-link": ["label", "referenceType", "documentId"],
|
|
1663
|
+
"cross-chunk-image": ["label", "referenceType", "documentId", "alt"],
|
|
1664
|
+
"footnote-sup": ["label", "localOccurrence", "documentId"]
|
|
1653
1665
|
}
|
|
1654
1666
|
};
|
|
1655
1667
|
|
|
@@ -1671,12 +1683,51 @@ var rehypeRebaseHashLinks = (options) => {
|
|
|
1671
1683
|
};
|
|
1672
1684
|
var rehypeRebaseHashLinks_default = rehypeRebaseHashLinks;
|
|
1673
1685
|
|
|
1686
|
+
// src/components/rehypeFooterAdorn.ts
|
|
1687
|
+
import { visit as visit3 } from "unist-util-visit";
|
|
1688
|
+
var FOOTNOTE_LABEL_ID_RE = /(?:^|-)footnote-label$/;
|
|
1689
|
+
function isFootnoteLabelH2(node) {
|
|
1690
|
+
if (node.type !== "element") return false;
|
|
1691
|
+
const el = node;
|
|
1692
|
+
if (el.tagName !== "h2") return false;
|
|
1693
|
+
const id = el.properties?.id;
|
|
1694
|
+
return typeof id === "string" && FOOTNOTE_LABEL_ID_RE.test(id);
|
|
1695
|
+
}
|
|
1696
|
+
function isHr(node) {
|
|
1697
|
+
if (node.type !== "element") return false;
|
|
1698
|
+
return node.tagName === "hr";
|
|
1699
|
+
}
|
|
1700
|
+
function rehypeFooterAdorn() {
|
|
1701
|
+
return (tree) => {
|
|
1702
|
+
visit3(tree, "element", (n) => {
|
|
1703
|
+
const el = n;
|
|
1704
|
+
if (el.tagName !== "section") return;
|
|
1705
|
+
if (!(el.properties && "dataFootnotes" in el.properties)) return;
|
|
1706
|
+
const filtered = el.children.filter((c) => !isFootnoteLabelH2(c));
|
|
1707
|
+
if (!filtered.some(isHr)) {
|
|
1708
|
+
const hr = {
|
|
1709
|
+
type: "element",
|
|
1710
|
+
tagName: "hr",
|
|
1711
|
+
properties: {},
|
|
1712
|
+
children: []
|
|
1713
|
+
};
|
|
1714
|
+
filtered.unshift(hr);
|
|
1715
|
+
}
|
|
1716
|
+
el.children = filtered;
|
|
1717
|
+
if (!el.properties) el.properties = {};
|
|
1718
|
+
if (!("ariaLabel" in el.properties)) {
|
|
1719
|
+
el.properties.ariaLabel = "Footnotes";
|
|
1720
|
+
}
|
|
1721
|
+
});
|
|
1722
|
+
};
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1674
1725
|
// src/components/MarkdownContent.tsx
|
|
1675
1726
|
import remarkBreaks from "remark-breaks";
|
|
1676
1727
|
import remarkCjkFriendly from "remark-cjk-friendly";
|
|
1677
1728
|
import remarkCjkFriendlyGfmStrikethrough from "remark-cjk-friendly-gfm-strikethrough";
|
|
1678
1729
|
import remarkEmoji from "remark-emoji";
|
|
1679
|
-
import
|
|
1730
|
+
import remarkGfm2 from "remark-gfm";
|
|
1680
1731
|
import remarkMath from "remark-math";
|
|
1681
1732
|
import { remarkDefinitionList, defListHastHandlers } from "remark-definition-list";
|
|
1682
1733
|
import { remarkMark as remarkMarkHighlight } from "remark-mark-highlight";
|
|
@@ -1686,7 +1737,17 @@ import remarkPangu from "remark-pangu";
|
|
|
1686
1737
|
import remarkRemoveComments from "remark-remove-comments";
|
|
1687
1738
|
|
|
1688
1739
|
// src/components/blockMemo.ts
|
|
1689
|
-
import { visit as
|
|
1740
|
+
import { visit as visit4 } from "unist-util-visit";
|
|
1741
|
+
|
|
1742
|
+
// src/components/normalizeId.ts
|
|
1743
|
+
function normalizeId(s) {
|
|
1744
|
+
return s.replace(/\s+/g, " ").toUpperCase();
|
|
1745
|
+
}
|
|
1746
|
+
function normalizeForMatch(s) {
|
|
1747
|
+
return s.replace(/\\(.)/g, "$1").replace(/\s+/g, " ").toUpperCase();
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
// src/components/blockMemo.ts
|
|
1690
1751
|
var TAINT_TYPES = /* @__PURE__ */ new Set([
|
|
1691
1752
|
"footnoteReference",
|
|
1692
1753
|
"footnoteDefinition",
|
|
@@ -1713,14 +1774,41 @@ function hasMdastSource(node) {
|
|
|
1713
1774
|
var FOOTNOTE_SECTION_KEY = "__footnote_section__";
|
|
1714
1775
|
function buildBlocks(mdast, hast, source) {
|
|
1715
1776
|
const mdastByOffset = /* @__PURE__ */ new Map();
|
|
1777
|
+
const mdastRanges = [];
|
|
1716
1778
|
for (const child of mdast.children) {
|
|
1717
1779
|
const off = child.position?.start.offset;
|
|
1780
|
+
const endOff = child.position?.end.offset;
|
|
1718
1781
|
if (off !== void 0) {
|
|
1719
1782
|
mdastByOffset.set(off, child);
|
|
1720
1783
|
}
|
|
1784
|
+
if (off !== void 0 && endOff !== void 0) {
|
|
1785
|
+
mdastRanges.push({ start: off, end: endOff, node: child });
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1789
|
+
for (let i = 1; i < mdastRanges.length; i++) {
|
|
1790
|
+
if (mdastRanges[i].start < mdastRanges[i - 1].start) {
|
|
1791
|
+
throw new Error(
|
|
1792
|
+
"block-memo: mdast.children not sorted by source offset \u2014 a remark plugin is reordering top-level children."
|
|
1793
|
+
);
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
function findContainingMdast(offset) {
|
|
1798
|
+
let lo = 0;
|
|
1799
|
+
let hi = mdastRanges.length;
|
|
1800
|
+
while (lo < hi) {
|
|
1801
|
+
const mid = lo + hi >>> 1;
|
|
1802
|
+
if (mdastRanges[mid].start <= offset) lo = mid + 1;
|
|
1803
|
+
else hi = mid;
|
|
1804
|
+
}
|
|
1805
|
+
const idx = lo - 1;
|
|
1806
|
+
if (idx < 0) return void 0;
|
|
1807
|
+
const r = mdastRanges[idx];
|
|
1808
|
+
return offset < r.end ? r.node : void 0;
|
|
1721
1809
|
}
|
|
1722
1810
|
const ctxParts = [];
|
|
1723
|
-
|
|
1811
|
+
visit4(mdast, (n) => {
|
|
1724
1812
|
if (!CTX_TYPES.has(n.type)) return;
|
|
1725
1813
|
if (n.type === "footnoteReference") ctxParts.push(["fr", n.identifier]);
|
|
1726
1814
|
else if (n.type === "footnoteDefinition") ctxParts.push(["fd", n.identifier, extractRaw(n, source)]);
|
|
@@ -1754,11 +1842,7 @@ function buildBlocks(mdast, hast, source) {
|
|
|
1754
1842
|
}
|
|
1755
1843
|
let mdastNode = mdastByOffset.get(hastOffset);
|
|
1756
1844
|
if (!mdastNode) {
|
|
1757
|
-
mdastNode =
|
|
1758
|
-
const startOff = child.position?.start.offset;
|
|
1759
|
-
const endOff = child.position?.end.offset;
|
|
1760
|
-
return startOff !== void 0 && endOff !== void 0 && startOff <= hastOffset && hastOffset < endOff;
|
|
1761
|
-
});
|
|
1845
|
+
mdastNode = findContainingMdast(hastOffset);
|
|
1762
1846
|
}
|
|
1763
1847
|
if (!mdastNode) {
|
|
1764
1848
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -1774,12 +1858,19 @@ function buildBlocks(mdast, hast, source) {
|
|
|
1774
1858
|
continue;
|
|
1775
1859
|
}
|
|
1776
1860
|
let hasReference = false;
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1861
|
+
const footnoteRefLabels = [];
|
|
1862
|
+
const linkRefLabels = [];
|
|
1863
|
+
const imageRefLabels = [];
|
|
1864
|
+
const footnoteDefLabels = [];
|
|
1865
|
+
visit4(mdastNode, (n) => {
|
|
1866
|
+
if (!TAINT_TYPES.has(n.type)) return;
|
|
1867
|
+
hasReference = true;
|
|
1868
|
+
const id = "identifier" in n ? normalizeId(String(n.identifier)) : null;
|
|
1869
|
+
if (id === null) return;
|
|
1870
|
+
if (n.type === "footnoteReference") footnoteRefLabels.push(id);
|
|
1871
|
+
else if (n.type === "linkReference") linkRefLabels.push(id);
|
|
1872
|
+
else if (n.type === "imageReference") imageRefLabels.push(id);
|
|
1873
|
+
else if (n.type === "footnoteDefinition") footnoteDefLabels.push(id);
|
|
1783
1874
|
});
|
|
1784
1875
|
const mdastPos = mdastNode.position;
|
|
1785
1876
|
if (!mdastPos || mdastPos.start.offset === void 0 || mdastPos.end.offset === void 0) {
|
|
@@ -1791,7 +1882,10 @@ function buildBlocks(mdast, hast, source) {
|
|
|
1791
1882
|
endOffset: mdastPos.end.offset,
|
|
1792
1883
|
startLine: mdastPos.start.line,
|
|
1793
1884
|
startColumn: mdastPos.start.column,
|
|
1794
|
-
hasReference
|
|
1885
|
+
hasReference,
|
|
1886
|
+
...hasReference ? {
|
|
1887
|
+
taintLabels: { footnoteRefLabels, linkRefLabels, imageRefLabels, footnoteDefLabels }
|
|
1888
|
+
} : {}
|
|
1795
1889
|
};
|
|
1796
1890
|
blocks.push(info);
|
|
1797
1891
|
blockHasts.push(el);
|
|
@@ -1799,6 +1893,25 @@ function buildBlocks(mdast, hast, source) {
|
|
|
1799
1893
|
}
|
|
1800
1894
|
return { plan, globalCtx, blocks, blockHasts, synthetic };
|
|
1801
1895
|
}
|
|
1896
|
+
function computeBlockFingerprint(taintLabels, registry, thisChunkSym, clobberPrefix) {
|
|
1897
|
+
const parts = [clobberPrefix];
|
|
1898
|
+
for (const label of taintLabels.footnoteRefLabels) {
|
|
1899
|
+
parts.push(`fn:${label}=${registry.globalNumber(label) ?? "null"}`);
|
|
1900
|
+
}
|
|
1901
|
+
for (const label of taintLabels.linkRefLabels) {
|
|
1902
|
+
const def = registry.resolveLinkDef(label);
|
|
1903
|
+
parts.push(`lr:${label}=${def?.url ?? "null"}|${def?.title ?? ""}`);
|
|
1904
|
+
}
|
|
1905
|
+
for (const label of taintLabels.imageRefLabels) {
|
|
1906
|
+
const def = registry.resolveLinkDef(label);
|
|
1907
|
+
parts.push(`ir:${label}=${def?.url ?? "null"}|${def?.title ?? ""}`);
|
|
1908
|
+
}
|
|
1909
|
+
for (const label of taintLabels.footnoteDefLabels) {
|
|
1910
|
+
const isCanonical = registry.canonicalFootnoteFor(label) === thisChunkSym ? 1 : 0;
|
|
1911
|
+
parts.push(`fd:${label}=${isCanonical}/${registry.getRefsForLabel(label)}`);
|
|
1912
|
+
}
|
|
1913
|
+
return parts.join("|");
|
|
1914
|
+
}
|
|
1802
1915
|
function renderBlocksWithCache(cacheRef, plan, globalCtx, postOptions) {
|
|
1803
1916
|
const prev = cacheRef.current;
|
|
1804
1917
|
const next = { blocks: /* @__PURE__ */ new Map() };
|
|
@@ -1821,10 +1934,18 @@ function renderBlocksWithCache(cacheRef, plan, globalCtx, postOptions) {
|
|
|
1821
1934
|
continue;
|
|
1822
1935
|
}
|
|
1823
1936
|
if (item.kind === "synthetic") {
|
|
1937
|
+
if (postOptions.registry && postOptions.thisChunkSymbol) {
|
|
1938
|
+
continue;
|
|
1939
|
+
}
|
|
1824
1940
|
const cached = prev.footnoteSection;
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1941
|
+
let node;
|
|
1942
|
+
if (cached && cached.ctx === globalCtx) {
|
|
1943
|
+
node = cached.node;
|
|
1944
|
+
} else {
|
|
1945
|
+
node = renderHastSubtree(item.el, postOptions);
|
|
1946
|
+
}
|
|
1947
|
+
next.footnoteSection = { ctx: globalCtx, node };
|
|
1948
|
+
rendered.push({ node, reactKey: item.reactKey });
|
|
1828
1949
|
continue;
|
|
1829
1950
|
}
|
|
1830
1951
|
const block = item.info;
|
|
@@ -1834,25 +1955,832 @@ function renderBlocksWithCache(cacheRef, plan, globalCtx, postOptions) {
|
|
|
1834
1955
|
next.blocks.set(block.raw, bucket);
|
|
1835
1956
|
}
|
|
1836
1957
|
const occ = bucket.length;
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
startColumn
|
|
1847
|
-
|
|
1848
|
-
|
|
1958
|
+
if (block.hasReference) {
|
|
1959
|
+
const useFingerprint = postOptions.registry && block.taintLabels && postOptions.thisChunkSymbol && postOptions.clobberPrefix !== void 0;
|
|
1960
|
+
const blockCtx = useFingerprint ? computeBlockFingerprint(
|
|
1961
|
+
block.taintLabels,
|
|
1962
|
+
postOptions.registry,
|
|
1963
|
+
postOptions.thisChunkSymbol,
|
|
1964
|
+
postOptions.clobberPrefix
|
|
1965
|
+
) : globalCtx;
|
|
1966
|
+
const entry = prev.blocks.get(block.raw)?.[occ];
|
|
1967
|
+
const valid = entry !== void 0 && entry.ctx === blockCtx && entry.startOffset === block.startOffset && entry.startLine === block.startLine && entry.startColumn === block.startColumn;
|
|
1968
|
+
let node;
|
|
1969
|
+
if (valid) {
|
|
1970
|
+
node = entry.node;
|
|
1971
|
+
} else {
|
|
1972
|
+
node = renderHastSubtree(item.el, postOptions);
|
|
1973
|
+
}
|
|
1974
|
+
bucket.push({
|
|
1975
|
+
node,
|
|
1976
|
+
ctx: blockCtx,
|
|
1977
|
+
startOffset: block.startOffset,
|
|
1978
|
+
startLine: block.startLine,
|
|
1979
|
+
startColumn: block.startColumn
|
|
1980
|
+
});
|
|
1981
|
+
rendered.push({ node, reactKey: item.reactKey });
|
|
1982
|
+
continue;
|
|
1983
|
+
}
|
|
1984
|
+
{
|
|
1985
|
+
const entry = prev.blocks.get(block.raw)?.[occ];
|
|
1986
|
+
const valid = entry !== void 0 && entry.ctx === "" && entry.startOffset === block.startOffset && entry.startLine === block.startLine && entry.startColumn === block.startColumn;
|
|
1987
|
+
const node = valid ? entry.node : renderHastSubtree(item.el, postOptions);
|
|
1988
|
+
bucket.push({
|
|
1989
|
+
node,
|
|
1990
|
+
ctx: "",
|
|
1991
|
+
startOffset: block.startOffset,
|
|
1992
|
+
startLine: block.startLine,
|
|
1993
|
+
startColumn: block.startColumn
|
|
1994
|
+
});
|
|
1995
|
+
rendered.push({ node, reactKey: item.reactKey });
|
|
1996
|
+
}
|
|
1849
1997
|
}
|
|
1850
1998
|
cacheRef.current = next;
|
|
1851
1999
|
return rendered;
|
|
1852
2000
|
}
|
|
1853
2001
|
|
|
2002
|
+
// src/components/collectDefLabels.ts
|
|
2003
|
+
import { unified as unified2 } from "unified";
|
|
2004
|
+
import remarkParse2 from "remark-parse";
|
|
2005
|
+
import remarkGfm from "remark-gfm";
|
|
2006
|
+
import { visit as visit5 } from "unist-util-visit";
|
|
2007
|
+
function buildProcessor() {
|
|
2008
|
+
return unified2().use(remarkParse2).use(remarkGfm);
|
|
2009
|
+
}
|
|
2010
|
+
var _processor = null;
|
|
2011
|
+
function processor() {
|
|
2012
|
+
if (!_processor) _processor = buildProcessor();
|
|
2013
|
+
return _processor;
|
|
2014
|
+
}
|
|
2015
|
+
function collectDefLabels(source) {
|
|
2016
|
+
if (!source) {
|
|
2017
|
+
return { footnoteLabels: /* @__PURE__ */ new Set(), linkLabels: /* @__PURE__ */ new Set() };
|
|
2018
|
+
}
|
|
2019
|
+
const mdast = processor().parse(source);
|
|
2020
|
+
const footnoteLabels = /* @__PURE__ */ new Set();
|
|
2021
|
+
const linkLabels = /* @__PURE__ */ new Set();
|
|
2022
|
+
visit5(mdast, (node) => {
|
|
2023
|
+
if (node.type === "footnoteDefinition" && "identifier" in node) {
|
|
2024
|
+
footnoteLabels.add(normalizeId(node.identifier));
|
|
2025
|
+
} else if (node.type === "definition" && "identifier" in node) {
|
|
2026
|
+
linkLabels.add(normalizeId(node.identifier));
|
|
2027
|
+
}
|
|
2028
|
+
});
|
|
2029
|
+
return { footnoteLabels, linkLabels };
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
// src/components/AIMarkdownDocuments.tsx
|
|
2033
|
+
import { createContext as createContext2, useContext as useContext2, useMemo as useMemo2, useRef } from "react";
|
|
2034
|
+
|
|
2035
|
+
// src/components/documentRegistry.ts
|
|
2036
|
+
function createRegistry(onEmpty) {
|
|
2037
|
+
const reg = {
|
|
2038
|
+
chunkOrder: [],
|
|
2039
|
+
chunkData: /* @__PURE__ */ new Map(),
|
|
2040
|
+
labelSet: { footnoteLabels: /* @__PURE__ */ new Set(), linkLabels: /* @__PURE__ */ new Set() },
|
|
2041
|
+
version: 0,
|
|
2042
|
+
_reactIdMap: /* @__PURE__ */ new Map(),
|
|
2043
|
+
_subscribers: /* @__PURE__ */ new Set(),
|
|
2044
|
+
_notifyScheduled: false,
|
|
2045
|
+
allocateSymbol(reactId) {
|
|
2046
|
+
const existing = this._reactIdMap.get(reactId);
|
|
2047
|
+
if (existing) {
|
|
2048
|
+
existing.refcount++;
|
|
2049
|
+
return existing.symbol;
|
|
2050
|
+
}
|
|
2051
|
+
const sym = Symbol(reactId);
|
|
2052
|
+
this._reactIdMap.set(reactId, { symbol: sym, refcount: 1 });
|
|
2053
|
+
this.chunkOrder.push(sym);
|
|
2054
|
+
this._notify();
|
|
2055
|
+
return sym;
|
|
2056
|
+
},
|
|
2057
|
+
registerChunk(reactId, footnotes, links) {
|
|
2058
|
+
const sym = this.allocateSymbol(reactId);
|
|
2059
|
+
this.contributeLabels(sym, footnotes, links);
|
|
2060
|
+
return sym;
|
|
2061
|
+
},
|
|
2062
|
+
releaseSymbol(reactId) {
|
|
2063
|
+
const entry = this._reactIdMap.get(reactId);
|
|
2064
|
+
if (!entry) return;
|
|
2065
|
+
entry.refcount--;
|
|
2066
|
+
if (entry.refcount === 0) {
|
|
2067
|
+
queueMicrotask(() => {
|
|
2068
|
+
const latest = this._reactIdMap.get(reactId);
|
|
2069
|
+
if (latest && latest.refcount === 0) {
|
|
2070
|
+
this._reactIdMap.delete(reactId);
|
|
2071
|
+
const idx = this.chunkOrder.indexOf(entry.symbol);
|
|
2072
|
+
if (idx !== -1) this.chunkOrder.splice(idx, 1);
|
|
2073
|
+
this.chunkData.delete(entry.symbol);
|
|
2074
|
+
const nextFn = /* @__PURE__ */ new Set();
|
|
2075
|
+
const nextLink = /* @__PURE__ */ new Set();
|
|
2076
|
+
for (const cd of this.chunkData.values()) {
|
|
2077
|
+
for (const l of cd.ownFootnoteLabels) nextFn.add(l);
|
|
2078
|
+
for (const l of cd.ownLinkLabels) nextLink.add(l);
|
|
2079
|
+
}
|
|
2080
|
+
this.labelSet.footnoteLabels = nextFn;
|
|
2081
|
+
this.labelSet.linkLabels = nextLink;
|
|
2082
|
+
this._notify();
|
|
2083
|
+
if (this.chunkOrder.length === 0 && this.chunkData.size === 0 && onEmpty) {
|
|
2084
|
+
onEmpty();
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
});
|
|
2088
|
+
}
|
|
2089
|
+
},
|
|
2090
|
+
contributeLabels(symbol, footnotes, links) {
|
|
2091
|
+
const data = this.chunkData.get(symbol);
|
|
2092
|
+
if (data) {
|
|
2093
|
+
data.ownFootnoteLabels = footnotes;
|
|
2094
|
+
data.ownLinkLabels = links;
|
|
2095
|
+
} else {
|
|
2096
|
+
this.chunkData.set(symbol, {
|
|
2097
|
+
refs: [],
|
|
2098
|
+
defs: /* @__PURE__ */ new Map(),
|
|
2099
|
+
linkDefs: /* @__PURE__ */ new Map(),
|
|
2100
|
+
ownFootnoteLabels: footnotes,
|
|
2101
|
+
ownLinkLabels: links
|
|
2102
|
+
});
|
|
2103
|
+
}
|
|
2104
|
+
const newFn = /* @__PURE__ */ new Set();
|
|
2105
|
+
const newLink = /* @__PURE__ */ new Set();
|
|
2106
|
+
for (const cd of this.chunkData.values()) {
|
|
2107
|
+
for (const l of cd.ownFootnoteLabels) newFn.add(l);
|
|
2108
|
+
for (const l of cd.ownLinkLabels) newLink.add(l);
|
|
2109
|
+
}
|
|
2110
|
+
this.labelSet.footnoteLabels = newFn;
|
|
2111
|
+
this.labelSet.linkLabels = newLink;
|
|
2112
|
+
this._notify();
|
|
2113
|
+
},
|
|
2114
|
+
contributeChunkData(symbol, data) {
|
|
2115
|
+
this.chunkData.set(symbol, data);
|
|
2116
|
+
this.labelSet.footnoteLabels = /* @__PURE__ */ new Set();
|
|
2117
|
+
this.labelSet.linkLabels = /* @__PURE__ */ new Set();
|
|
2118
|
+
for (const cd of this.chunkData.values()) {
|
|
2119
|
+
for (const l of cd.ownFootnoteLabels) this.labelSet.footnoteLabels.add(l);
|
|
2120
|
+
for (const l of cd.ownLinkLabels) this.labelSet.linkLabels.add(l);
|
|
2121
|
+
}
|
|
2122
|
+
this._notify();
|
|
2123
|
+
},
|
|
2124
|
+
subscribe(cb) {
|
|
2125
|
+
this._subscribers.add(cb);
|
|
2126
|
+
return () => {
|
|
2127
|
+
this._subscribers.delete(cb);
|
|
2128
|
+
};
|
|
2129
|
+
},
|
|
2130
|
+
canonicalFootnoteFor(label) {
|
|
2131
|
+
const id = normalizeId(label);
|
|
2132
|
+
for (const sym of this.chunkOrder) {
|
|
2133
|
+
const data = this.chunkData.get(sym);
|
|
2134
|
+
if (data?.defs.has(id)) return sym;
|
|
2135
|
+
}
|
|
2136
|
+
return null;
|
|
2137
|
+
},
|
|
2138
|
+
canonicalLinkFor(label) {
|
|
2139
|
+
const id = normalizeId(label);
|
|
2140
|
+
for (const sym of this.chunkOrder) {
|
|
2141
|
+
const data = this.chunkData.get(sym);
|
|
2142
|
+
if (data?.linkDefs.has(id)) return sym;
|
|
2143
|
+
}
|
|
2144
|
+
return null;
|
|
2145
|
+
},
|
|
2146
|
+
globalNumber(label) {
|
|
2147
|
+
const id = normalizeId(label);
|
|
2148
|
+
let n = 0;
|
|
2149
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2150
|
+
for (const sym of this.chunkOrder) {
|
|
2151
|
+
const data = this.chunkData.get(sym);
|
|
2152
|
+
if (!data) continue;
|
|
2153
|
+
for (const ref of data.refs) {
|
|
2154
|
+
if (ref.kind !== "footnote") continue;
|
|
2155
|
+
if (!seen.has(ref.label)) {
|
|
2156
|
+
seen.add(ref.label);
|
|
2157
|
+
n++;
|
|
2158
|
+
if (ref.label === id) return n;
|
|
2159
|
+
}
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2162
|
+
return null;
|
|
2163
|
+
},
|
|
2164
|
+
resolveLinkDef(label) {
|
|
2165
|
+
const sym = this.canonicalLinkFor(label);
|
|
2166
|
+
if (!sym) return null;
|
|
2167
|
+
return this.chunkData.get(sym)?.linkDefs.get(normalizeId(label)) ?? null;
|
|
2168
|
+
},
|
|
2169
|
+
getRefsForLabel(label) {
|
|
2170
|
+
const id = normalizeId(label);
|
|
2171
|
+
let n = 0;
|
|
2172
|
+
for (const sym of this.chunkOrder) {
|
|
2173
|
+
const data = this.chunkData.get(sym);
|
|
2174
|
+
if (!data) continue;
|
|
2175
|
+
for (const ref of data.refs) {
|
|
2176
|
+
if (ref.kind === "footnote" && ref.label === id) n++;
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
return n;
|
|
2180
|
+
},
|
|
2181
|
+
globalOccurrenceForRef(chunkSym, label, localOccurrence) {
|
|
2182
|
+
const id = normalizeId(label);
|
|
2183
|
+
let global2 = 0;
|
|
2184
|
+
for (const sym of this.chunkOrder) {
|
|
2185
|
+
const data = this.chunkData.get(sym);
|
|
2186
|
+
if (!data) continue;
|
|
2187
|
+
let localCount = 0;
|
|
2188
|
+
for (const ref of data.refs) {
|
|
2189
|
+
if (ref.kind !== "footnote") continue;
|
|
2190
|
+
if (ref.label !== id) continue;
|
|
2191
|
+
localCount++;
|
|
2192
|
+
global2++;
|
|
2193
|
+
if (sym === chunkSym && localCount === localOccurrence) return global2;
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
return null;
|
|
2197
|
+
},
|
|
2198
|
+
_notify() {
|
|
2199
|
+
this.version++;
|
|
2200
|
+
if (this._notifyScheduled) return;
|
|
2201
|
+
this._notifyScheduled = true;
|
|
2202
|
+
queueMicrotask(() => {
|
|
2203
|
+
this._notifyScheduled = false;
|
|
2204
|
+
for (const cb of [...this._subscribers]) cb();
|
|
2205
|
+
});
|
|
2206
|
+
}
|
|
2207
|
+
};
|
|
2208
|
+
return reg;
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2211
|
+
// src/components/AIMarkdownDocuments.tsx
|
|
2212
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
2213
|
+
var AIMarkdownDocumentsContext = createContext2(null);
|
|
2214
|
+
var AIMarkdownDocuments = ({ preserveOrphanReferences = true, children }) => {
|
|
2215
|
+
const parent = useContext2(AIMarkdownDocumentsContext);
|
|
2216
|
+
if (parent !== null) {
|
|
2217
|
+
throw new Error(
|
|
2218
|
+
"<AIMarkdownDocuments> must not be nested inside another <AIMarkdownDocuments>. Use a single top-level wrapper per coordinated scope."
|
|
2219
|
+
);
|
|
2220
|
+
}
|
|
2221
|
+
const registriesRef = useRef(/* @__PURE__ */ new Map());
|
|
2222
|
+
const value = useMemo2(
|
|
2223
|
+
() => ({
|
|
2224
|
+
preserveOrphanReferences,
|
|
2225
|
+
getRegistry(documentId) {
|
|
2226
|
+
let r = registriesRef.current.get(documentId);
|
|
2227
|
+
if (!r) {
|
|
2228
|
+
const created = createRegistry(() => {
|
|
2229
|
+
if (registriesRef.current.get(documentId) === created) {
|
|
2230
|
+
registriesRef.current.delete(documentId);
|
|
2231
|
+
}
|
|
2232
|
+
});
|
|
2233
|
+
r = created;
|
|
2234
|
+
registriesRef.current.set(documentId, r);
|
|
2235
|
+
}
|
|
2236
|
+
return r;
|
|
2237
|
+
}
|
|
2238
|
+
}),
|
|
2239
|
+
[preserveOrphanReferences]
|
|
2240
|
+
);
|
|
2241
|
+
return /* @__PURE__ */ jsx3(AIMarkdownDocumentsContext.Provider, { value, children });
|
|
2242
|
+
};
|
|
2243
|
+
function useDocumentRegistry(documentId) {
|
|
2244
|
+
const ctx = useContext2(AIMarkdownDocumentsContext);
|
|
2245
|
+
if (!ctx || !documentId) return null;
|
|
2246
|
+
return ctx.getRegistry(documentId);
|
|
2247
|
+
}
|
|
2248
|
+
function usePreserveOrphanReferences(fallback) {
|
|
2249
|
+
const ctx = useContext2(AIMarkdownDocumentsContext);
|
|
2250
|
+
return ctx?.preserveOrphanReferences ?? fallback;
|
|
2251
|
+
}
|
|
2252
|
+
|
|
2253
|
+
// src/components/remarkInjectPhantomDefs.ts
|
|
2254
|
+
var SENTINEL_LINK_URL = "__aimd_sentinel_link__";
|
|
2255
|
+
var SENTINEL_FN_CONTENT = "__aimd_sentinel_fn__";
|
|
2256
|
+
function augmentSourceWithPhantoms(source, phantoms) {
|
|
2257
|
+
if (phantoms.missingFootnotes.size === 0 && phantoms.missingLinks.size === 0) {
|
|
2258
|
+
return source;
|
|
2259
|
+
}
|
|
2260
|
+
let suffix = "\n\n";
|
|
2261
|
+
for (const label of phantoms.missingLinks) {
|
|
2262
|
+
suffix += `[${label}]: ${SENTINEL_LINK_URL}
|
|
2263
|
+
`;
|
|
2264
|
+
}
|
|
2265
|
+
for (const label of phantoms.missingFootnotes) {
|
|
2266
|
+
suffix += `[^${label}]: ${SENTINEL_FN_CONTENT}
|
|
2267
|
+
`;
|
|
2268
|
+
}
|
|
2269
|
+
return source + suffix;
|
|
2270
|
+
}
|
|
2271
|
+
|
|
2272
|
+
// src/components/customMdastHandlers.ts
|
|
2273
|
+
function buildCrossChunkHandlers() {
|
|
2274
|
+
return {
|
|
2275
|
+
footnoteDefinition: (state, node) => {
|
|
2276
|
+
const s = state;
|
|
2277
|
+
const id = normalizeId(node.identifier);
|
|
2278
|
+
if (s.options.phantomFootnoteLabels.has(id)) {
|
|
2279
|
+
return void 0;
|
|
2280
|
+
}
|
|
2281
|
+
if (s.options.preserveOrphan && !s.footnoteOrder.includes(id)) {
|
|
2282
|
+
s.footnoteOrder.push(id);
|
|
2283
|
+
}
|
|
2284
|
+
return void 0;
|
|
2285
|
+
},
|
|
2286
|
+
linkReference: ((state, node) => {
|
|
2287
|
+
const s = state;
|
|
2288
|
+
const id = normalizeId(node.identifier);
|
|
2289
|
+
const resolved = s.definitionById.has(id);
|
|
2290
|
+
if (!resolved) {
|
|
2291
|
+
return void 0;
|
|
2292
|
+
}
|
|
2293
|
+
return {
|
|
2294
|
+
type: "element",
|
|
2295
|
+
tagName: "cross-chunk-link",
|
|
2296
|
+
properties: {
|
|
2297
|
+
// `label` is the ORIGINAL source text (mdast's `label` field), NOT
|
|
2298
|
+
// the normalized `identifier`. The placeholder uses it to construct
|
|
2299
|
+
// hrefs that line up with mdast-util-to-hast's default `<li id>`
|
|
2300
|
+
// which also preserves source case. Registry lookups normalize
|
|
2301
|
+
// internally, so cross-chunk case-insensitive matching still works.
|
|
2302
|
+
label: node.label ?? node.identifier,
|
|
2303
|
+
referenceType: node.referenceType,
|
|
2304
|
+
documentId: s.options.documentId
|
|
2305
|
+
},
|
|
2306
|
+
children: s.all(node)
|
|
2307
|
+
};
|
|
2308
|
+
}),
|
|
2309
|
+
imageReference: ((state, node) => {
|
|
2310
|
+
const s = state;
|
|
2311
|
+
const id = normalizeId(node.identifier);
|
|
2312
|
+
const resolved = s.definitionById.has(id);
|
|
2313
|
+
if (!resolved) return void 0;
|
|
2314
|
+
return {
|
|
2315
|
+
type: "element",
|
|
2316
|
+
tagName: "cross-chunk-image",
|
|
2317
|
+
properties: {
|
|
2318
|
+
label: node.label ?? node.identifier,
|
|
2319
|
+
referenceType: node.referenceType,
|
|
2320
|
+
alt: node.alt ?? "",
|
|
2321
|
+
documentId: s.options.documentId
|
|
2322
|
+
},
|
|
2323
|
+
children: []
|
|
2324
|
+
};
|
|
2325
|
+
}),
|
|
2326
|
+
footnoteReference: ((state, node) => {
|
|
2327
|
+
const s = state;
|
|
2328
|
+
const id = normalizeId(node.identifier);
|
|
2329
|
+
const localOccurrence = (s.footnoteCounts.get(id) ?? 0) + 1;
|
|
2330
|
+
s.footnoteCounts.set(id, localOccurrence);
|
|
2331
|
+
if (s.options.phantomFootnoteLabels.has(id)) {
|
|
2332
|
+
return {
|
|
2333
|
+
type: "element",
|
|
2334
|
+
tagName: "footnote-sup",
|
|
2335
|
+
properties: {
|
|
2336
|
+
label: node.identifier,
|
|
2337
|
+
localOccurrence,
|
|
2338
|
+
documentId: s.options.documentId
|
|
2339
|
+
},
|
|
2340
|
+
children: []
|
|
2341
|
+
};
|
|
2342
|
+
}
|
|
2343
|
+
if (!s.footnoteOrder.includes(id)) s.footnoteOrder.push(id);
|
|
2344
|
+
return {
|
|
2345
|
+
type: "element",
|
|
2346
|
+
tagName: "footnote-sup",
|
|
2347
|
+
properties: {
|
|
2348
|
+
label: node.identifier,
|
|
2349
|
+
localOccurrence,
|
|
2350
|
+
documentId: s.options.documentId
|
|
2351
|
+
},
|
|
2352
|
+
children: []
|
|
2353
|
+
};
|
|
2354
|
+
})
|
|
2355
|
+
};
|
|
2356
|
+
}
|
|
2357
|
+
|
|
2358
|
+
// src/components/crossChunkPlaceholders.tsx
|
|
2359
|
+
import { isValidElement, useCallback, useContext as useContext3, useSyncExternalStore } from "react";
|
|
2360
|
+
|
|
2361
|
+
// src/components/chunkSymbolContext.ts
|
|
2362
|
+
import { createContext as createContext3 } from "react";
|
|
2363
|
+
var ChunkSymbolContext = createContext3(null);
|
|
2364
|
+
|
|
2365
|
+
// src/components/crossChunkPlaceholders.tsx
|
|
2366
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
2367
|
+
var SSR_NUM_SNAPSHOT = () => 0;
|
|
2368
|
+
var SSR_DEF_SNAPSHOT = () => null;
|
|
2369
|
+
function coerceLocalOccurrence(v) {
|
|
2370
|
+
if (v === void 0) return null;
|
|
2371
|
+
if (typeof v === "number") return Number.isFinite(v) && v >= 1 ? Math.trunc(v) : null;
|
|
2372
|
+
const n = Number(v);
|
|
2373
|
+
return Number.isFinite(n) && n >= 1 ? Math.trunc(n) : null;
|
|
2374
|
+
}
|
|
2375
|
+
function FootnoteSupNumber({ label, localOccurrence: localOccurrenceRaw }) {
|
|
2376
|
+
const localOccurrence = coerceLocalOccurrence(localOccurrenceRaw);
|
|
2377
|
+
const { documentId, clobberPrefix } = useAIMarkdownRenderState();
|
|
2378
|
+
const registry = useDocumentRegistry(documentId);
|
|
2379
|
+
const chunkSym = useContext3(ChunkSymbolContext);
|
|
2380
|
+
const subscribe = useCallback((cb) => registry ? registry.subscribe(cb) : () => {
|
|
2381
|
+
}, [registry]);
|
|
2382
|
+
const getSnapshot = useCallback(() => registry?.version ?? 0, [registry]);
|
|
2383
|
+
useSyncExternalStore(subscribe, getSnapshot, SSR_NUM_SNAPSHOT);
|
|
2384
|
+
const num = registry?.globalNumber(label) ?? null;
|
|
2385
|
+
if (num === null) return null;
|
|
2386
|
+
if (localOccurrence !== null && !chunkSym) return null;
|
|
2387
|
+
const globalOcc = registry && chunkSym && localOccurrence !== null ? registry.globalOccurrenceForRef(chunkSym, label, localOccurrence) : null;
|
|
2388
|
+
if (localOccurrence !== null && globalOcc === null) return null;
|
|
2389
|
+
const occSuffix = globalOcc !== null && globalOcc > 1 ? `-${globalOcc}` : "";
|
|
2390
|
+
return /* @__PURE__ */ jsx4("sup", { children: /* @__PURE__ */ jsx4("a", { href: `#${clobberPrefix}fn-${label}`, id: `${clobberPrefix}fnref-${label}${occSuffix}`, "data-footnote-ref": true, children: num }) });
|
|
2391
|
+
}
|
|
2392
|
+
function reactNodeToText(node) {
|
|
2393
|
+
if (node === null || node === void 0 || typeof node === "boolean") return "";
|
|
2394
|
+
if (typeof node === "string") return node;
|
|
2395
|
+
if (typeof node === "number" || typeof node === "bigint") return String(node);
|
|
2396
|
+
if (Array.isArray(node)) return node.map(reactNodeToText).join("");
|
|
2397
|
+
if (isValidElement(node)) {
|
|
2398
|
+
return reactNodeToText(node.props.children);
|
|
2399
|
+
}
|
|
2400
|
+
return "";
|
|
2401
|
+
}
|
|
2402
|
+
function literalLink(rt, label, children) {
|
|
2403
|
+
const text = reactNodeToText(children);
|
|
2404
|
+
switch (rt) {
|
|
2405
|
+
case "full":
|
|
2406
|
+
return `[${text}][${label}]`;
|
|
2407
|
+
case "collapsed":
|
|
2408
|
+
return `[${label}][]`;
|
|
2409
|
+
case "shortcut":
|
|
2410
|
+
default:
|
|
2411
|
+
return `[${label}]`;
|
|
2412
|
+
}
|
|
2413
|
+
}
|
|
2414
|
+
function CrossChunkLink({ label, referenceType, children }) {
|
|
2415
|
+
const { documentId } = useAIMarkdownRenderState();
|
|
2416
|
+
const registry = useDocumentRegistry(documentId);
|
|
2417
|
+
const subscribe = useCallback((cb) => registry ? registry.subscribe(cb) : () => {
|
|
2418
|
+
}, [registry]);
|
|
2419
|
+
const getSnapshot = useCallback(() => registry?.resolveLinkDef(label) ?? null, [registry, label]);
|
|
2420
|
+
const def = useSyncExternalStore(subscribe, getSnapshot, SSR_DEF_SNAPSHOT);
|
|
2421
|
+
if (!def) {
|
|
2422
|
+
return literalLink(referenceType, label, children);
|
|
2423
|
+
}
|
|
2424
|
+
return /* @__PURE__ */ jsx4("a", { href: def.url, title: def.title, children });
|
|
2425
|
+
}
|
|
2426
|
+
function literalImage(rt, label, alt) {
|
|
2427
|
+
switch (rt) {
|
|
2428
|
+
case "full":
|
|
2429
|
+
return `![${alt}][${label}]`;
|
|
2430
|
+
case "collapsed":
|
|
2431
|
+
return `![${alt}][]`;
|
|
2432
|
+
case "shortcut":
|
|
2433
|
+
default:
|
|
2434
|
+
return `![${label}]`;
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2437
|
+
function CrossChunkImage({ label, referenceType, alt = "" }) {
|
|
2438
|
+
const { documentId } = useAIMarkdownRenderState();
|
|
2439
|
+
const registry = useDocumentRegistry(documentId);
|
|
2440
|
+
const subscribe = useCallback((cb) => registry ? registry.subscribe(cb) : () => {
|
|
2441
|
+
}, [registry]);
|
|
2442
|
+
const getSnapshot = useCallback(() => registry?.resolveLinkDef(label) ?? null, [registry, label]);
|
|
2443
|
+
const def = useSyncExternalStore(subscribe, getSnapshot, SSR_DEF_SNAPSHOT);
|
|
2444
|
+
if (!def) {
|
|
2445
|
+
return literalImage(referenceType, label, alt);
|
|
2446
|
+
}
|
|
2447
|
+
return /* @__PURE__ */ jsx4("img", { src: def.url, alt, title: def.title });
|
|
2448
|
+
}
|
|
2449
|
+
var crossChunkComponents = {
|
|
2450
|
+
"footnote-sup": FootnoteSupNumber,
|
|
2451
|
+
"cross-chunk-link": CrossChunkLink,
|
|
2452
|
+
"cross-chunk-image": CrossChunkImage
|
|
2453
|
+
};
|
|
2454
|
+
|
|
2455
|
+
// src/components/extractContributions.ts
|
|
2456
|
+
import { SKIP, visit as visit6 } from "unist-util-visit";
|
|
2457
|
+
function* extractContributions(mdast, options = {}) {
|
|
2458
|
+
const phantomFn = options.phantomFootnoteLabels;
|
|
2459
|
+
const out = [];
|
|
2460
|
+
visit6(mdast, (n) => {
|
|
2461
|
+
if (n.type === "footnoteReference") {
|
|
2462
|
+
out.push({
|
|
2463
|
+
kind: "ref",
|
|
2464
|
+
refKind: "footnote",
|
|
2465
|
+
label: normalizeId(n.identifier)
|
|
2466
|
+
});
|
|
2467
|
+
} else if (n.type === "linkReference") {
|
|
2468
|
+
const r = n;
|
|
2469
|
+
out.push({ kind: "ref", refKind: "link", label: normalizeId(r.identifier), referenceType: r.referenceType });
|
|
2470
|
+
} else if (n.type === "imageReference") {
|
|
2471
|
+
const r = n;
|
|
2472
|
+
out.push({ kind: "ref", refKind: "image", label: normalizeId(r.identifier), referenceType: r.referenceType });
|
|
2473
|
+
} else if (n.type === "footnoteDefinition") {
|
|
2474
|
+
const d = n;
|
|
2475
|
+
const label = normalizeId(d.identifier);
|
|
2476
|
+
if (phantomFn?.has(label)) return SKIP;
|
|
2477
|
+
const content = JSON.stringify(d.children ?? []);
|
|
2478
|
+
out.push({ kind: "fnDef", label, sourceIdentifier: d.identifier, content });
|
|
2479
|
+
return SKIP;
|
|
2480
|
+
} else if (n.type === "definition") {
|
|
2481
|
+
const d = n;
|
|
2482
|
+
if (d.url === SENTINEL_LINK_URL) return;
|
|
2483
|
+
out.push({ kind: "linkDef", label: normalizeId(d.identifier), url: d.url, title: d.title });
|
|
2484
|
+
}
|
|
2485
|
+
});
|
|
2486
|
+
for (const c of out) yield c;
|
|
2487
|
+
}
|
|
2488
|
+
|
|
2489
|
+
// src/components/extractDefBodiesFromHast.ts
|
|
2490
|
+
import { SKIP as SKIP2, visit as visit7 } from "unist-util-visit";
|
|
2491
|
+
var FN_LI_ID_RE = /(?:^|-)user-content-fn-(.+)$/;
|
|
2492
|
+
function sourceIdFromFootnoteLiId(idProp, clobberPrefix) {
|
|
2493
|
+
let raw = null;
|
|
2494
|
+
if (clobberPrefix !== void 0) {
|
|
2495
|
+
const exactPrefix = `${clobberPrefix}fn-`;
|
|
2496
|
+
if (idProp.startsWith(exactPrefix)) raw = idProp.slice(exactPrefix.length);
|
|
2497
|
+
}
|
|
2498
|
+
if (raw === null) {
|
|
2499
|
+
const m = idProp.match(FN_LI_ID_RE);
|
|
2500
|
+
raw = m ? m[1] : null;
|
|
2501
|
+
}
|
|
2502
|
+
if (raw === null) return null;
|
|
2503
|
+
try {
|
|
2504
|
+
return decodeURIComponent(raw);
|
|
2505
|
+
} catch {
|
|
2506
|
+
return raw;
|
|
2507
|
+
}
|
|
2508
|
+
}
|
|
2509
|
+
function isBackrefAnchor(c) {
|
|
2510
|
+
if (c.type !== "element") return false;
|
|
2511
|
+
const el = c;
|
|
2512
|
+
if (el.tagName !== "a") return false;
|
|
2513
|
+
return Boolean(el.properties && "dataFootnoteBackref" in el.properties);
|
|
2514
|
+
}
|
|
2515
|
+
function isWhitespaceText(c) {
|
|
2516
|
+
if (c.type !== "text") return false;
|
|
2517
|
+
return /^\s*$/.test(c.value);
|
|
2518
|
+
}
|
|
2519
|
+
function lastMeaningfulIdx(children) {
|
|
2520
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
2521
|
+
if (!isWhitespaceText(children[i])) return i;
|
|
2522
|
+
}
|
|
2523
|
+
return -1;
|
|
2524
|
+
}
|
|
2525
|
+
function dropTrailingBackrefs(children) {
|
|
2526
|
+
let trailingWsStart = children.length;
|
|
2527
|
+
while (trailingWsStart > 0 && isWhitespaceText(children[trailingWsStart - 1])) {
|
|
2528
|
+
trailingWsStart--;
|
|
2529
|
+
}
|
|
2530
|
+
let scan = trailingWsStart;
|
|
2531
|
+
let peeledAny = false;
|
|
2532
|
+
while (scan > 0) {
|
|
2533
|
+
const t = children[scan - 1];
|
|
2534
|
+
if (!isBackrefAnchor(t)) break;
|
|
2535
|
+
peeledAny = true;
|
|
2536
|
+
scan -= 1;
|
|
2537
|
+
if (scan > 0 && children[scan - 1].type === "text" && children[scan - 1].value === " ") {
|
|
2538
|
+
scan -= 1;
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
if (!peeledAny) return children;
|
|
2542
|
+
const trailing = children.slice(trailingWsStart);
|
|
2543
|
+
if (scan > 0) {
|
|
2544
|
+
const last = children[scan - 1];
|
|
2545
|
+
if (last.type === "text") {
|
|
2546
|
+
const v = last.value;
|
|
2547
|
+
if (v.endsWith(" ") && !/^\s*$/.test(v)) {
|
|
2548
|
+
return [...children.slice(0, scan - 1), { ...last, value: v.slice(0, -1) }, ...trailing];
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
return [...children.slice(0, scan), ...trailing];
|
|
2553
|
+
}
|
|
2554
|
+
function stripBackrefs(liChildren) {
|
|
2555
|
+
if (liChildren.length === 0) return liChildren;
|
|
2556
|
+
const lastIdx = lastMeaningfulIdx(liChildren);
|
|
2557
|
+
if (lastIdx < 0) return liChildren;
|
|
2558
|
+
const last = liChildren[lastIdx];
|
|
2559
|
+
if (isBackrefAnchor(last)) {
|
|
2560
|
+
return dropTrailingBackrefs(liChildren);
|
|
2561
|
+
}
|
|
2562
|
+
if (last.type === "element" && last.tagName === "p") {
|
|
2563
|
+
const p = last;
|
|
2564
|
+
const newPChildren = dropTrailingBackrefs(p.children);
|
|
2565
|
+
if (newPChildren === p.children) return liChildren;
|
|
2566
|
+
return liChildren.map((c, i) => i === lastIdx ? { ...p, children: newPChildren } : c);
|
|
2567
|
+
}
|
|
2568
|
+
return liChildren;
|
|
2569
|
+
}
|
|
2570
|
+
function stripLocalOccurrenceFromFootnoteSups(children) {
|
|
2571
|
+
let changed = false;
|
|
2572
|
+
const out = [];
|
|
2573
|
+
for (const c of children) {
|
|
2574
|
+
if (c.type === "element") {
|
|
2575
|
+
const el = c;
|
|
2576
|
+
let nextEl = el;
|
|
2577
|
+
if (el.tagName === "footnote-sup" && el.properties && "localOccurrence" in el.properties) {
|
|
2578
|
+
const { localOccurrence: _drop, ...rest } = el.properties;
|
|
2579
|
+
nextEl = { ...el, properties: rest };
|
|
2580
|
+
changed = true;
|
|
2581
|
+
}
|
|
2582
|
+
const newChildren = stripLocalOccurrenceFromFootnoteSups(nextEl.children);
|
|
2583
|
+
if (newChildren !== nextEl.children) {
|
|
2584
|
+
nextEl = { ...nextEl, children: newChildren };
|
|
2585
|
+
changed = true;
|
|
2586
|
+
}
|
|
2587
|
+
out.push(nextEl);
|
|
2588
|
+
} else {
|
|
2589
|
+
out.push(c);
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
return changed ? out : children;
|
|
2593
|
+
}
|
|
2594
|
+
function extractDefBodiesFromHast(hast, clobberPrefix) {
|
|
2595
|
+
const out = /* @__PURE__ */ new Map();
|
|
2596
|
+
visit7(hast, "element", (sectionNode) => {
|
|
2597
|
+
const sec = sectionNode;
|
|
2598
|
+
if (sec.tagName !== "section") return;
|
|
2599
|
+
if (!(sec.properties && "dataFootnotes" in sec.properties)) return;
|
|
2600
|
+
visit7(sec, "element", (liNode) => {
|
|
2601
|
+
const li = liNode;
|
|
2602
|
+
if (li.tagName !== "li") return;
|
|
2603
|
+
const idProp = li.properties?.id;
|
|
2604
|
+
if (typeof idProp !== "string") return;
|
|
2605
|
+
const sourceId = sourceIdFromFootnoteLiId(idProp, clobberPrefix);
|
|
2606
|
+
if (sourceId === null) return;
|
|
2607
|
+
const normalized = normalizeId(sourceId);
|
|
2608
|
+
const stripped = stripBackrefs(li.children);
|
|
2609
|
+
out.set(normalized, stripLocalOccurrenceFromFootnoteSups(stripped));
|
|
2610
|
+
});
|
|
2611
|
+
return SKIP2;
|
|
2612
|
+
});
|
|
2613
|
+
return out;
|
|
2614
|
+
}
|
|
2615
|
+
|
|
2616
|
+
// src/components/aggregateFootnotesIfLast.tsx
|
|
2617
|
+
import { memo, useMemo as useMemo3 } from "react";
|
|
2618
|
+
import { Fragment as Fragment2, jsx as jsx5 } from "react/jsx-runtime";
|
|
2619
|
+
function cloneHast(node) {
|
|
2620
|
+
return JSON.parse(JSON.stringify(node));
|
|
2621
|
+
}
|
|
2622
|
+
function isWhitespaceText2(c) {
|
|
2623
|
+
return c.type === "text" && /^\s*$/.test(c.value);
|
|
2624
|
+
}
|
|
2625
|
+
function lastMeaningfulIdx2(children) {
|
|
2626
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
2627
|
+
if (!isWhitespaceText2(children[i])) return i;
|
|
2628
|
+
}
|
|
2629
|
+
return -1;
|
|
2630
|
+
}
|
|
2631
|
+
function buildBackref(href, occurrence, globalNumber) {
|
|
2632
|
+
const children = [{ type: "text", value: "\u21A9" }];
|
|
2633
|
+
if (occurrence > 1) {
|
|
2634
|
+
children.push({
|
|
2635
|
+
type: "element",
|
|
2636
|
+
tagName: "sup",
|
|
2637
|
+
properties: {},
|
|
2638
|
+
children: [{ type: "text", value: String(occurrence) }]
|
|
2639
|
+
});
|
|
2640
|
+
}
|
|
2641
|
+
const ariaLabel = occurrence === 1 ? `Back to reference ${globalNumber}` : `Back to reference ${globalNumber}-${occurrence}`;
|
|
2642
|
+
return {
|
|
2643
|
+
type: "element",
|
|
2644
|
+
tagName: "a",
|
|
2645
|
+
properties: {
|
|
2646
|
+
href,
|
|
2647
|
+
dataFootnoteBackref: "",
|
|
2648
|
+
className: ["data-footnote-backref"],
|
|
2649
|
+
ariaLabel
|
|
2650
|
+
},
|
|
2651
|
+
children
|
|
2652
|
+
};
|
|
2653
|
+
}
|
|
2654
|
+
function buildAggregateTree(registry, clobberPrefix, preserveOrphanReferences = false) {
|
|
2655
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2656
|
+
const ordered = [];
|
|
2657
|
+
for (const sym of registry.chunkOrder) {
|
|
2658
|
+
const data = registry.chunkData.get(sym);
|
|
2659
|
+
if (!data) continue;
|
|
2660
|
+
for (const ref of data.refs) {
|
|
2661
|
+
if (ref.kind !== "footnote") continue;
|
|
2662
|
+
if (seen.has(ref.label)) continue;
|
|
2663
|
+
seen.add(ref.label);
|
|
2664
|
+
const canonicalSym = registry.canonicalFootnoteFor(ref.label);
|
|
2665
|
+
if (!canonicalSym) continue;
|
|
2666
|
+
const def = registry.chunkData.get(canonicalSym)?.defs.get(ref.label);
|
|
2667
|
+
if (!def) continue;
|
|
2668
|
+
const n = registry.globalNumber(ref.label);
|
|
2669
|
+
if (n === null) continue;
|
|
2670
|
+
const sourceIdentifier = def.sourceIdentifier ?? ref.label;
|
|
2671
|
+
ordered.push({
|
|
2672
|
+
normalizedLabel: ref.label,
|
|
2673
|
+
sourceIdentifier,
|
|
2674
|
+
bodyHast: def.bodyHast ?? [],
|
|
2675
|
+
n,
|
|
2676
|
+
withBackref: true
|
|
2677
|
+
});
|
|
2678
|
+
}
|
|
2679
|
+
}
|
|
2680
|
+
if (preserveOrphanReferences) {
|
|
2681
|
+
for (const sym of registry.chunkOrder) {
|
|
2682
|
+
const data = registry.chunkData.get(sym);
|
|
2683
|
+
if (!data) continue;
|
|
2684
|
+
for (const [label, def] of data.defs) {
|
|
2685
|
+
if (seen.has(label)) continue;
|
|
2686
|
+
if (registry.canonicalFootnoteFor(label) !== sym) continue;
|
|
2687
|
+
seen.add(label);
|
|
2688
|
+
ordered.push({
|
|
2689
|
+
normalizedLabel: label,
|
|
2690
|
+
sourceIdentifier: def.sourceIdentifier ?? label,
|
|
2691
|
+
bodyHast: def.bodyHast ?? [],
|
|
2692
|
+
n: null,
|
|
2693
|
+
withBackref: false
|
|
2694
|
+
});
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
}
|
|
2698
|
+
if (ordered.length === 0) return null;
|
|
2699
|
+
const liElements = ordered.map(({ normalizedLabel, sourceIdentifier, bodyHast, n, withBackref }) => {
|
|
2700
|
+
const liChildren = bodyHast.map((c) => cloneHast(c));
|
|
2701
|
+
if (withBackref) {
|
|
2702
|
+
const totalRefs = registry.getRefsForLabel(normalizedLabel);
|
|
2703
|
+
const tailIdx = lastMeaningfulIdx2(liChildren);
|
|
2704
|
+
const tail = tailIdx !== -1 ? liChildren[tailIdx] : null;
|
|
2705
|
+
const dest = tail && tail.type === "element" && tail.tagName === "p" ? tail : null;
|
|
2706
|
+
const appended = [];
|
|
2707
|
+
for (let i = 1; i <= Math.max(totalRefs, 1); i++) {
|
|
2708
|
+
appended.push({ type: "text", value: " " });
|
|
2709
|
+
const href = i === 1 ? `#${clobberPrefix}fnref-${sourceIdentifier}` : `#${clobberPrefix}fnref-${sourceIdentifier}-${i}`;
|
|
2710
|
+
appended.push(buildBackref(href, i, n ?? 0));
|
|
2711
|
+
}
|
|
2712
|
+
if (dest) {
|
|
2713
|
+
dest.children = [...dest.children, ...appended];
|
|
2714
|
+
} else if (tailIdx !== -1) {
|
|
2715
|
+
liChildren.splice(tailIdx + 1, 0, ...appended);
|
|
2716
|
+
} else {
|
|
2717
|
+
liChildren.push(...appended);
|
|
2718
|
+
}
|
|
2719
|
+
}
|
|
2720
|
+
return {
|
|
2721
|
+
type: "element",
|
|
2722
|
+
tagName: "li",
|
|
2723
|
+
properties: {
|
|
2724
|
+
id: `${clobberPrefix}fn-${sourceIdentifier}`,
|
|
2725
|
+
...n !== null ? { value: n } : {}
|
|
2726
|
+
},
|
|
2727
|
+
children: liChildren
|
|
2728
|
+
};
|
|
2729
|
+
});
|
|
2730
|
+
return {
|
|
2731
|
+
type: "element",
|
|
2732
|
+
tagName: "section",
|
|
2733
|
+
properties: {
|
|
2734
|
+
className: ["footnotes"],
|
|
2735
|
+
dataFootnotes: true,
|
|
2736
|
+
// a11y: name the section landmark so screen readers still announce it
|
|
2737
|
+
// even though the visible "Footnotes" h2 is omitted in coordinated mode.
|
|
2738
|
+
ariaLabel: "Footnotes"
|
|
2739
|
+
},
|
|
2740
|
+
children: [
|
|
2741
|
+
// Conventional separator above the footnote list. The default
|
|
2742
|
+
// mdast-util-to-hast footer doesn't emit one (GitHub renders the
|
|
2743
|
+
// separation via CSS `border-top` on `.footnotes`); we render a literal
|
|
2744
|
+
// `<hr>` so the visual break is preserved without sanitize-friendly CSS.
|
|
2745
|
+
{
|
|
2746
|
+
type: "element",
|
|
2747
|
+
tagName: "hr",
|
|
2748
|
+
properties: {},
|
|
2749
|
+
children: []
|
|
2750
|
+
},
|
|
2751
|
+
{
|
|
2752
|
+
type: "element",
|
|
2753
|
+
tagName: "ol",
|
|
2754
|
+
properties: {},
|
|
2755
|
+
children: liElements
|
|
2756
|
+
}
|
|
2757
|
+
]
|
|
2758
|
+
};
|
|
2759
|
+
}
|
|
2760
|
+
var AggregateFootnotesIfLastImpl = ({
|
|
2761
|
+
registry,
|
|
2762
|
+
thisChunkSym,
|
|
2763
|
+
clobberPrefix,
|
|
2764
|
+
postOptions,
|
|
2765
|
+
preserveOrphanReferences = false
|
|
2766
|
+
}) => {
|
|
2767
|
+
const tree = useMemo3(
|
|
2768
|
+
() => buildAggregateTree(registry, clobberPrefix, preserveOrphanReferences),
|
|
2769
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2770
|
+
[registry, registry.version, clobberPrefix, preserveOrphanReferences]
|
|
2771
|
+
);
|
|
2772
|
+
const order = registry.chunkOrder;
|
|
2773
|
+
if (order.length === 0) return null;
|
|
2774
|
+
if (order[order.length - 1] !== thisChunkSym) return null;
|
|
2775
|
+
if (!tree) return null;
|
|
2776
|
+
return /* @__PURE__ */ jsx5(Fragment2, { children: renderHastSubtree(cloneHast(tree), postOptions) });
|
|
2777
|
+
};
|
|
2778
|
+
var AggregateFootnotesIfLast = memo(AggregateFootnotesIfLastImpl);
|
|
2779
|
+
AggregateFootnotesIfLast.displayName = "AggregateFootnotesIfLast";
|
|
2780
|
+
|
|
1854
2781
|
// src/components/MarkdownContent.tsx
|
|
1855
|
-
import {
|
|
2782
|
+
import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2783
|
+
var REGISTRY_SSR_SNAPSHOT = () => 0;
|
|
1856
2784
|
var DisplayOptimizeRemarkPluginMap = {
|
|
1857
2785
|
["REMOVE_COMMENTS" /* REMOVE_COMMENTS */]: remarkRemoveComments,
|
|
1858
2786
|
["SMARTYPANTS" /* SMARTYPANTS */]: remarkSmartypants,
|
|
@@ -1863,7 +2791,7 @@ var ExtraSyntaxRemarkPluginMap = {
|
|
|
1863
2791
|
["DEFINITION_LIST" /* DEFINITION_LIST */]: remarkDefinitionList
|
|
1864
2792
|
};
|
|
1865
2793
|
var DefaultCustomComponents = {};
|
|
1866
|
-
var BlockMemoizedRenderer =
|
|
2794
|
+
var BlockMemoizedRenderer = memo2(
|
|
1867
2795
|
({ content, usedComponents, remarkPlugins, rehypePlugins, remarkRehypeOptions }) => {
|
|
1868
2796
|
const urlTransform = void 0;
|
|
1869
2797
|
const allowedElements = void 0;
|
|
@@ -1871,8 +2799,30 @@ var BlockMemoizedRenderer = memo(
|
|
|
1871
2799
|
const allowElement = void 0;
|
|
1872
2800
|
const skipHtml = void 0;
|
|
1873
2801
|
const unwrapDisallowed = void 0;
|
|
1874
|
-
const
|
|
1875
|
-
const
|
|
2802
|
+
const { documentId, clobberPrefix, config } = useAIMarkdownRenderState();
|
|
2803
|
+
const reactId = useId2();
|
|
2804
|
+
const registry = useDocumentRegistry(documentId);
|
|
2805
|
+
const [allocation, setAllocation] = useState(null);
|
|
2806
|
+
const sym = allocation && allocation.registry === registry ? allocation.sym : null;
|
|
2807
|
+
const subscribeRegistry = useCallback2(
|
|
2808
|
+
(cb) => registry ? registry.subscribe(cb) : () => {
|
|
2809
|
+
},
|
|
2810
|
+
[registry]
|
|
2811
|
+
);
|
|
2812
|
+
const getRegistryVersion = useCallback2(() => registry?.version ?? 0, [registry]);
|
|
2813
|
+
useSyncExternalStore2(subscribeRegistry, getRegistryVersion, REGISTRY_SSR_SNAPSHOT);
|
|
2814
|
+
const ownLabels = useMemo4(() => collectDefLabels(content ?? ""), [content]);
|
|
2815
|
+
useEffect(() => {
|
|
2816
|
+
if (!registry) return;
|
|
2817
|
+
const s = registry.registerChunk(reactId, ownLabels.footnoteLabels, ownLabels.linkLabels);
|
|
2818
|
+
setAllocation({ registry, sym: s });
|
|
2819
|
+
return () => {
|
|
2820
|
+
registry.releaseSymbol(reactId);
|
|
2821
|
+
setAllocation(null);
|
|
2822
|
+
};
|
|
2823
|
+
}, [reactId, registry, ownLabels]);
|
|
2824
|
+
const cacheRef = useRef2(createCache());
|
|
2825
|
+
const depsRef = useRef2({
|
|
1876
2826
|
usedComponents,
|
|
1877
2827
|
remarkPlugins,
|
|
1878
2828
|
rehypePlugins,
|
|
@@ -1882,9 +2832,11 @@ var BlockMemoizedRenderer = memo(
|
|
|
1882
2832
|
disallowedElements,
|
|
1883
2833
|
allowElement,
|
|
1884
2834
|
skipHtml,
|
|
1885
|
-
unwrapDisallowed
|
|
2835
|
+
unwrapDisallowed,
|
|
2836
|
+
registry,
|
|
2837
|
+
symbol: sym
|
|
1886
2838
|
});
|
|
1887
|
-
if (depsRef.current.usedComponents !== usedComponents || depsRef.current.remarkPlugins !== remarkPlugins || depsRef.current.rehypePlugins !== rehypePlugins || depsRef.current.remarkRehypeOptions !== remarkRehypeOptions || depsRef.current.urlTransform !== urlTransform || depsRef.current.allowedElements !== allowedElements || depsRef.current.disallowedElements !== disallowedElements || depsRef.current.allowElement !== allowElement || depsRef.current.skipHtml !== skipHtml || depsRef.current.unwrapDisallowed !== unwrapDisallowed) {
|
|
2839
|
+
if (depsRef.current.usedComponents !== usedComponents || depsRef.current.remarkPlugins !== remarkPlugins || depsRef.current.rehypePlugins !== rehypePlugins || depsRef.current.remarkRehypeOptions !== remarkRehypeOptions || depsRef.current.urlTransform !== urlTransform || depsRef.current.allowedElements !== allowedElements || depsRef.current.disallowedElements !== disallowedElements || depsRef.current.allowElement !== allowElement || depsRef.current.skipHtml !== skipHtml || depsRef.current.unwrapDisallowed !== unwrapDisallowed || depsRef.current.registry !== registry || depsRef.current.symbol !== sym) {
|
|
1888
2840
|
cacheRef.current = createCache();
|
|
1889
2841
|
depsRef.current = {
|
|
1890
2842
|
usedComponents,
|
|
@@ -1896,39 +2848,201 @@ var BlockMemoizedRenderer = memo(
|
|
|
1896
2848
|
disallowedElements,
|
|
1897
2849
|
allowElement,
|
|
1898
2850
|
skipHtml,
|
|
1899
|
-
unwrapDisallowed
|
|
2851
|
+
unwrapDisallowed,
|
|
2852
|
+
registry,
|
|
2853
|
+
symbol: sym
|
|
1900
2854
|
};
|
|
1901
2855
|
}
|
|
1902
|
-
const
|
|
1903
|
-
|
|
1904
|
-
|
|
2856
|
+
const targetPhantomsRef = useRef2({
|
|
2857
|
+
missingFootnotes: /* @__PURE__ */ new Set(),
|
|
2858
|
+
missingLinks: /* @__PURE__ */ new Set()
|
|
2859
|
+
});
|
|
2860
|
+
const targetPhantoms = useMemo4(() => {
|
|
2861
|
+
let nextFootnotes;
|
|
2862
|
+
let nextLinks;
|
|
2863
|
+
if (!registry) {
|
|
2864
|
+
nextFootnotes = /* @__PURE__ */ new Set();
|
|
2865
|
+
nextLinks = /* @__PURE__ */ new Set();
|
|
2866
|
+
} else {
|
|
2867
|
+
const normalized = normalizeForMatch(content ?? "");
|
|
2868
|
+
nextFootnotes = /* @__PURE__ */ new Set();
|
|
2869
|
+
nextLinks = /* @__PURE__ */ new Set();
|
|
2870
|
+
for (const label of registry.labelSet.footnoteLabels) {
|
|
2871
|
+
if (ownLabels.footnoteLabels.has(label)) continue;
|
|
2872
|
+
if (normalized.includes(label)) nextFootnotes.add(label);
|
|
2873
|
+
}
|
|
2874
|
+
for (const label of registry.labelSet.linkLabels) {
|
|
2875
|
+
if (ownLabels.linkLabels.has(label)) continue;
|
|
2876
|
+
if (normalized.includes(label)) nextLinks.add(label);
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2879
|
+
const prev = targetPhantomsRef.current;
|
|
2880
|
+
if (nextFootnotes.size === prev.missingFootnotes.size && nextLinks.size === prev.missingLinks.size && [...nextFootnotes].every((l) => prev.missingFootnotes.has(l)) && [...nextLinks].every((l) => prev.missingLinks.has(l))) {
|
|
2881
|
+
return prev;
|
|
2882
|
+
}
|
|
2883
|
+
const next = { missingFootnotes: nextFootnotes, missingLinks: nextLinks };
|
|
2884
|
+
targetPhantomsRef.current = next;
|
|
2885
|
+
return next;
|
|
2886
|
+
}, [registry, registry?.version, content, ownLabels]);
|
|
2887
|
+
const effectivePreserveOrphan = usePreserveOrphanReferences(config.preserveOrphanReferences);
|
|
2888
|
+
const preserveForBodyHarvest = effectivePreserveOrphan || Boolean(registry && sym);
|
|
2889
|
+
const handlers = useMemo4(() => {
|
|
2890
|
+
if (registry) return buildCrossChunkHandlers();
|
|
2891
|
+
if (effectivePreserveOrphan) {
|
|
2892
|
+
const { footnoteDefinition } = buildCrossChunkHandlers();
|
|
2893
|
+
return { footnoteDefinition };
|
|
2894
|
+
}
|
|
2895
|
+
return void 0;
|
|
2896
|
+
}, [registry, effectivePreserveOrphan]);
|
|
2897
|
+
const parsed = useMemo4(() => {
|
|
2898
|
+
const augmented = augmentSourceWithPhantoms(content ?? "", targetPhantoms);
|
|
2899
|
+
const baseHandlers = remarkRehypeOptions?.handlers ?? {};
|
|
2900
|
+
const mergedRemarkRehypeOptions = handlers ? {
|
|
2901
|
+
...remarkRehypeOptions,
|
|
2902
|
+
handlers: { ...baseHandlers, ...handlers },
|
|
2903
|
+
// Phantom label sets are empty in standalone mode (no PASS 0.5
|
|
2904
|
+
// injection happened); the footnoteDefinition handler still reads
|
|
2905
|
+
// them via `state.options.phantomFootnoteLabels.has(id)`, which
|
|
2906
|
+
// returns false for every id → orphan-protect path proceeds.
|
|
2907
|
+
phantomFootnoteLabels: targetPhantoms.missingFootnotes,
|
|
2908
|
+
phantomLinkLabels: targetPhantoms.missingLinks,
|
|
2909
|
+
preserveOrphan: preserveForBodyHarvest,
|
|
2910
|
+
documentId
|
|
2911
|
+
} : {
|
|
2912
|
+
...remarkRehypeOptions
|
|
2913
|
+
};
|
|
2914
|
+
return parseStage({
|
|
2915
|
+
children: augmented,
|
|
1905
2916
|
remarkPlugins,
|
|
1906
2917
|
rehypePlugins,
|
|
1907
|
-
remarkRehypeOptions
|
|
1908
|
-
})
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
2918
|
+
remarkRehypeOptions: mergedRemarkRehypeOptions
|
|
2919
|
+
});
|
|
2920
|
+
}, [
|
|
2921
|
+
content,
|
|
2922
|
+
targetPhantoms,
|
|
2923
|
+
remarkPlugins,
|
|
2924
|
+
rehypePlugins,
|
|
2925
|
+
remarkRehypeOptions,
|
|
2926
|
+
handlers,
|
|
2927
|
+
preserveForBodyHarvest,
|
|
2928
|
+
documentId
|
|
2929
|
+
]);
|
|
2930
|
+
const hast = useMemo4(() => transformStage(parsed), [parsed]);
|
|
2931
|
+
const built = useMemo4(() => buildBlocks(parsed.mdast, hast, content ?? ""), [parsed.mdast, hast, content]);
|
|
2932
|
+
const postOptions = useMemo4(
|
|
1914
2933
|
() => ({
|
|
1915
|
-
components: usedComponents,
|
|
2934
|
+
components: { ...crossChunkComponents, ...usedComponents },
|
|
1916
2935
|
urlTransform,
|
|
1917
2936
|
allowedElements,
|
|
1918
2937
|
disallowedElements,
|
|
1919
2938
|
allowElement,
|
|
1920
2939
|
skipHtml,
|
|
1921
|
-
unwrapDisallowed
|
|
2940
|
+
unwrapDisallowed,
|
|
2941
|
+
// v6 fingerprint cache fields:
|
|
2942
|
+
registry: registry ?? void 0,
|
|
2943
|
+
thisChunkSymbol: sym ?? void 0,
|
|
2944
|
+
clobberPrefix
|
|
1922
2945
|
}),
|
|
1923
|
-
|
|
2946
|
+
// `sym` is now real state (setSym after allocateSymbol), so it's a
|
|
2947
|
+
// proper dep and postOptions refreshes when allocation completes.
|
|
2948
|
+
// `registry?.version` stays in deps so the per-block fingerprint cache
|
|
2949
|
+
// path sees the latest registry version on every coordinated update.
|
|
2950
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2951
|
+
[
|
|
2952
|
+
usedComponents,
|
|
2953
|
+
urlTransform,
|
|
2954
|
+
allowedElements,
|
|
2955
|
+
disallowedElements,
|
|
2956
|
+
allowElement,
|
|
2957
|
+
skipHtml,
|
|
2958
|
+
unwrapDisallowed,
|
|
2959
|
+
registry,
|
|
2960
|
+
registry?.version,
|
|
2961
|
+
sym,
|
|
2962
|
+
clobberPrefix
|
|
2963
|
+
]
|
|
1924
2964
|
);
|
|
2965
|
+
const lastContributionRef = useRef2(null);
|
|
2966
|
+
useEffect(() => {
|
|
2967
|
+
if (!registry || !sym) return;
|
|
2968
|
+
const refs = [];
|
|
2969
|
+
const defMeta = /* @__PURE__ */ new Map();
|
|
2970
|
+
const linkDefs = /* @__PURE__ */ new Map();
|
|
2971
|
+
for (const node of extractContributions(parsed.mdast, {
|
|
2972
|
+
phantomFootnoteLabels: targetPhantoms.missingFootnotes
|
|
2973
|
+
})) {
|
|
2974
|
+
if (node.kind === "ref") {
|
|
2975
|
+
refs.push({ label: node.label, kind: node.refKind, referenceType: node.referenceType });
|
|
2976
|
+
} else if (node.kind === "fnDef") {
|
|
2977
|
+
defMeta.set(node.label, {
|
|
2978
|
+
identifier: node.label,
|
|
2979
|
+
sourceIdentifier: node.sourceIdentifier,
|
|
2980
|
+
contentSource: node.content
|
|
2981
|
+
});
|
|
2982
|
+
} else if (node.kind === "linkDef") {
|
|
2983
|
+
linkDefs.set(node.label, { identifier: node.label, url: node.url, title: node.title });
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2986
|
+
const fp = JSON.stringify({
|
|
2987
|
+
r: refs,
|
|
2988
|
+
d: Array.from(defMeta.entries()).map(([k, v]) => [k, v.sourceIdentifier, v.contentSource]),
|
|
2989
|
+
l: Array.from(linkDefs.entries()).map(([k, v]) => [k, v.url, v.title ?? ""]),
|
|
2990
|
+
ofn: Array.from(ownLabels.footnoteLabels).sort(),
|
|
2991
|
+
ol: Array.from(ownLabels.linkLabels).sort(),
|
|
2992
|
+
// Include targetPhantoms in the fingerprint: a phantom→resolved
|
|
2993
|
+
// transition (another chunk publishes a def for a label this chunk
|
|
2994
|
+
// references inside one of its OWN def bodies) changes the rendered
|
|
2995
|
+
// hast — the `<cross-chunk-link>` / `<cross-chunk-image>` placeholder
|
|
2996
|
+
// disappears and a real `<a>` / `<img>` takes its place — without
|
|
2997
|
+
// touching this chunk's refs / defMeta / linkDefs / ownLabels. Without
|
|
2998
|
+
// including the phantom snapshot in the fingerprint, the fp check
|
|
2999
|
+
// would short-circuit and the registry would keep stale bodyHast
|
|
3000
|
+
// forever, leaving the aggregate footer rendering the placeholder
|
|
3001
|
+
// long after the label was resolved.
|
|
3002
|
+
tpfn: Array.from(targetPhantoms.missingFootnotes).sort(),
|
|
3003
|
+
tpl: Array.from(targetPhantoms.missingLinks).sort()
|
|
3004
|
+
});
|
|
3005
|
+
if (lastContributionRef.current?.registry === registry && lastContributionRef.current.symbol === sym && lastContributionRef.current.fp === fp) {
|
|
3006
|
+
return;
|
|
3007
|
+
}
|
|
3008
|
+
const bodiesByLabel = extractDefBodiesFromHast(hast, clobberPrefix);
|
|
3009
|
+
const defs = /* @__PURE__ */ new Map();
|
|
3010
|
+
for (const [label, meta] of defMeta) {
|
|
3011
|
+
defs.set(label, {
|
|
3012
|
+
identifier: meta.identifier,
|
|
3013
|
+
sourceIdentifier: meta.sourceIdentifier,
|
|
3014
|
+
contentSource: meta.contentSource,
|
|
3015
|
+
bodyHast: bodiesByLabel.get(label) ?? []
|
|
3016
|
+
});
|
|
3017
|
+
}
|
|
3018
|
+
lastContributionRef.current = { registry, symbol: sym, fp };
|
|
3019
|
+
registry.contributeChunkData(sym, {
|
|
3020
|
+
refs,
|
|
3021
|
+
defs,
|
|
3022
|
+
linkDefs,
|
|
3023
|
+
ownFootnoteLabels: ownLabels.footnoteLabels,
|
|
3024
|
+
ownLinkLabels: ownLabels.linkLabels
|
|
3025
|
+
});
|
|
3026
|
+
}, [parsed, ownLabels, registry, targetPhantoms, sym, hast, clobberPrefix]);
|
|
1925
3027
|
const rendered = renderBlocksWithCache(cacheRef, built.plan, built.globalCtx, postOptions);
|
|
1926
|
-
return /* @__PURE__ */
|
|
3028
|
+
return /* @__PURE__ */ jsxs2(ChunkSymbolContext.Provider, { value: sym, children: [
|
|
3029
|
+
rendered.map(({ node, reactKey }) => /* @__PURE__ */ jsx6(Fragment3, { children: node }, reactKey)),
|
|
3030
|
+
registry && sym ? /* @__PURE__ */ jsx6(
|
|
3031
|
+
AggregateFootnotesIfLast,
|
|
3032
|
+
{
|
|
3033
|
+
registry,
|
|
3034
|
+
thisChunkSym: sym,
|
|
3035
|
+
clobberPrefix,
|
|
3036
|
+
postOptions,
|
|
3037
|
+
preserveOrphanReferences: effectivePreserveOrphan
|
|
3038
|
+
}
|
|
3039
|
+
) : null
|
|
3040
|
+
] });
|
|
1927
3041
|
}
|
|
1928
3042
|
);
|
|
1929
3043
|
BlockMemoizedRenderer.displayName = "BlockMemoizedRenderer";
|
|
1930
|
-
var LegacyRenderer =
|
|
1931
|
-
({ content, usedComponents, remarkPlugins, rehypePlugins, remarkRehypeOptions }) => /* @__PURE__ */
|
|
3044
|
+
var LegacyRenderer = memo2(
|
|
3045
|
+
({ content, usedComponents, remarkPlugins, rehypePlugins, remarkRehypeOptions }) => /* @__PURE__ */ jsx6(
|
|
1932
3046
|
Markdown_default,
|
|
1933
3047
|
{
|
|
1934
3048
|
remarkPlugins,
|
|
@@ -1940,26 +3054,25 @@ var LegacyRenderer = memo(
|
|
|
1940
3054
|
)
|
|
1941
3055
|
);
|
|
1942
3056
|
LegacyRenderer.displayName = "LegacyRenderer";
|
|
1943
|
-
var AIMarkdownContent =
|
|
1944
|
-
const { config,
|
|
1945
|
-
const
|
|
1946
|
-
const { extraSyntaxRemarkPlugins, enableDefinitionList } = useMemo2(
|
|
3057
|
+
var AIMarkdownContent = memo2(({ content, customComponents }) => {
|
|
3058
|
+
const { config, clobberPrefix } = useAIMarkdownRenderState();
|
|
3059
|
+
const { extraSyntaxRemarkPlugins, enableDefinitionList } = useMemo4(
|
|
1947
3060
|
() => ({
|
|
1948
3061
|
extraSyntaxRemarkPlugins: config.extraSyntaxSupported.map((syntax) => ExtraSyntaxRemarkPluginMap[syntax]),
|
|
1949
3062
|
enableDefinitionList: config.extraSyntaxSupported.includes("DEFINITION_LIST" /* DEFINITION_LIST */)
|
|
1950
3063
|
}),
|
|
1951
3064
|
[config.extraSyntaxSupported]
|
|
1952
3065
|
);
|
|
1953
|
-
const displayOptimizeRemarkPlugins =
|
|
3066
|
+
const displayOptimizeRemarkPlugins = useMemo4(() => {
|
|
1954
3067
|
return config.displayOptimizeAbilities.map((ability) => DisplayOptimizeRemarkPluginMap[ability]);
|
|
1955
3068
|
}, [config.displayOptimizeAbilities]);
|
|
1956
|
-
const usedComponents =
|
|
3069
|
+
const usedComponents = useMemo4(() => {
|
|
1957
3070
|
return customComponents ? { ...DefaultCustomComponents, ...customComponents } : DefaultCustomComponents;
|
|
1958
3071
|
}, [customComponents]);
|
|
1959
|
-
const remarkPlugins =
|
|
3072
|
+
const remarkPlugins = useMemo4(
|
|
1960
3073
|
() => [
|
|
1961
3074
|
// --- Core plugins (always active) ---
|
|
1962
|
-
|
|
3075
|
+
remarkGfm2,
|
|
1963
3076
|
[
|
|
1964
3077
|
remarkMath,
|
|
1965
3078
|
{
|
|
@@ -1981,7 +3094,7 @@ var AIMarkdownContent = memo(({ content, customComponents }) => {
|
|
|
1981
3094
|
],
|
|
1982
3095
|
[extraSyntaxRemarkPlugins, displayOptimizeRemarkPlugins]
|
|
1983
3096
|
);
|
|
1984
|
-
const rehypePlugins =
|
|
3097
|
+
const rehypePlugins = useMemo4(
|
|
1985
3098
|
() => [
|
|
1986
3099
|
// Allow raw HTML through so rehype-sanitize can handle it.
|
|
1987
3100
|
[rehypeRaw, { passThrough: [] }],
|
|
@@ -1989,6 +3102,11 @@ var AIMarkdownContent = memo(({ content, customComponents }) => {
|
|
|
1989
3102
|
// Override `clobberPrefix` with the instance-scoped value so every id
|
|
1990
3103
|
// and clobberable attribute is namespaced to this `<AIMarkdown>` instance.
|
|
1991
3104
|
[rehypeSanitize, { ...sanitizeSchema, clobberPrefix }],
|
|
3105
|
+
// Normalize the auto-generated `<section data-footnotes>`: strip the
|
|
3106
|
+
// sr-only `<h2>Footnotes</h2>` label and prepend `<hr>`. Keeps standalone
|
|
3107
|
+
// single-doc rendering visually consistent with the cross-chunk aggregate
|
|
3108
|
+
// footer (which builds the same shape from scratch).
|
|
3109
|
+
rehypeFooterAdorn,
|
|
1992
3110
|
// Re-prefix intra-document hash hrefs so they match the ids that
|
|
1993
3111
|
// rehype-sanitize just clobbered. Must use the SAME prefix as the schema
|
|
1994
3112
|
// above — that's why both read from `clobberPrefix`.
|
|
@@ -1998,7 +3116,7 @@ var AIMarkdownContent = memo(({ content, customComponents }) => {
|
|
|
1998
3116
|
],
|
|
1999
3117
|
[clobberPrefix]
|
|
2000
3118
|
);
|
|
2001
|
-
const remarkRehypeOptions =
|
|
3119
|
+
const remarkRehypeOptions = useMemo4(
|
|
2002
3120
|
() => ({
|
|
2003
3121
|
allowDangerousHtml: true,
|
|
2004
3122
|
// Suppress mdast-util-to-hast's `user-content-` prefix on footnote
|
|
@@ -2015,7 +3133,7 @@ var AIMarkdownContent = memo(({ content, customComponents }) => {
|
|
|
2015
3133
|
[enableDefinitionList]
|
|
2016
3134
|
);
|
|
2017
3135
|
const Renderer = config.blockMemoEnabled ? BlockMemoizedRenderer : LegacyRenderer;
|
|
2018
|
-
return /* @__PURE__ */
|
|
3136
|
+
return /* @__PURE__ */ jsx6(
|
|
2019
3137
|
Renderer,
|
|
2020
3138
|
{
|
|
2021
3139
|
content,
|
|
@@ -2030,7 +3148,7 @@ AIMarkdownContent.displayName = "AIMarkdownContent";
|
|
|
2030
3148
|
var MarkdownContent_default = AIMarkdownContent;
|
|
2031
3149
|
|
|
2032
3150
|
// src/hooks/useStableValue.ts
|
|
2033
|
-
import { useRef as
|
|
3151
|
+
import { useRef as useRef3, useLayoutEffect, useEffect as useEffect2 } from "react";
|
|
2034
3152
|
|
|
2035
3153
|
// ../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_setCacheAdd.js
|
|
2036
3154
|
var HASH_UNDEFINED3 = "__lodash_hash_undefined__";
|
|
@@ -2450,9 +3568,9 @@ function isEqual(value, other) {
|
|
|
2450
3568
|
var isEqual_default = isEqual;
|
|
2451
3569
|
|
|
2452
3570
|
// src/hooks/useStableValue.ts
|
|
2453
|
-
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect :
|
|
3571
|
+
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect2;
|
|
2454
3572
|
function useStableValue(value) {
|
|
2455
|
-
const ref =
|
|
3573
|
+
const ref = useRef3(value);
|
|
2456
3574
|
const prev = ref.current;
|
|
2457
3575
|
const stableValue = isEqual_default(prev, value) ? prev : value;
|
|
2458
3576
|
useIsomorphicLayoutEffect(() => {
|
|
@@ -2462,21 +3580,21 @@ function useStableValue(value) {
|
|
|
2462
3580
|
}
|
|
2463
3581
|
|
|
2464
3582
|
// src/components/typography/Default.tsx
|
|
2465
|
-
import { memo as
|
|
2466
|
-
import { jsx as
|
|
2467
|
-
var DefaultTypography =
|
|
2468
|
-
const className =
|
|
3583
|
+
import { memo as memo3, useMemo as useMemo5 } from "react";
|
|
3584
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
3585
|
+
var DefaultTypography = memo3(({ children, fontSize, variant, colorScheme, style }) => {
|
|
3586
|
+
const className = useMemo5(
|
|
2469
3587
|
() => ["aim-typography-root", variant, colorScheme].filter(Boolean).join(" "),
|
|
2470
3588
|
[variant, colorScheme]
|
|
2471
3589
|
);
|
|
2472
|
-
const mergedStyle =
|
|
2473
|
-
return /* @__PURE__ */
|
|
3590
|
+
const mergedStyle = useMemo5(() => ({ width: "100%", fontSize, ...style }), [fontSize, style]);
|
|
3591
|
+
return /* @__PURE__ */ jsx7("div", { className, style: mergedStyle, children });
|
|
2474
3592
|
});
|
|
2475
3593
|
DefaultTypography.displayName = "DefaultTypography";
|
|
2476
3594
|
var Default_default = DefaultTypography;
|
|
2477
3595
|
|
|
2478
3596
|
// src/index.tsx
|
|
2479
|
-
import { jsx as
|
|
3597
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
2480
3598
|
var AIMarkdownComponent = ({
|
|
2481
3599
|
streaming = false,
|
|
2482
3600
|
content,
|
|
@@ -2493,18 +3611,18 @@ var AIMarkdownComponent = ({
|
|
|
2493
3611
|
documentId
|
|
2494
3612
|
}) => {
|
|
2495
3613
|
const usedFontSize = fontSize === void 0 ? "0.9375rem" : typeof fontSize === "number" ? `${fontSize}px` : fontSize;
|
|
2496
|
-
const generatedId =
|
|
3614
|
+
const generatedId = useId3();
|
|
2497
3615
|
const usedDocumentId = documentId && documentId.length > 0 ? documentId : generatedId;
|
|
2498
3616
|
const stableDefaultConfig = useStableValue(defaultConfig);
|
|
2499
3617
|
const stableConfig = useStableValue(config);
|
|
2500
3618
|
const stablePreprocessors = useStableValue(contentPreprocessors);
|
|
2501
3619
|
const stableCustomComponents = useStableValue(customComponents);
|
|
2502
|
-
const usedContent =
|
|
3620
|
+
const usedContent = useMemo6(
|
|
2503
3621
|
() => content ? preprocessAIMDContent(content, stablePreprocessors) : content,
|
|
2504
3622
|
[content, stablePreprocessors]
|
|
2505
3623
|
);
|
|
2506
|
-
const typographyStyle =
|
|
2507
|
-
return /* @__PURE__ */
|
|
3624
|
+
const typographyStyle = useMemo6(() => ({ "--aim-font-size-root": usedFontSize }), [usedFontSize]);
|
|
3625
|
+
return /* @__PURE__ */ jsx8(AIMarkdownMetadataProvider, { metadata, children: /* @__PURE__ */ jsx8(
|
|
2508
3626
|
context_default,
|
|
2509
3627
|
{
|
|
2510
3628
|
streaming,
|
|
@@ -2514,29 +3632,31 @@ var AIMarkdownComponent = ({
|
|
|
2514
3632
|
documentId: usedDocumentId,
|
|
2515
3633
|
defaultConfig: stableDefaultConfig,
|
|
2516
3634
|
config: stableConfig,
|
|
2517
|
-
children: /* @__PURE__ */
|
|
3635
|
+
children: /* @__PURE__ */ jsx8(
|
|
2518
3636
|
Typography,
|
|
2519
3637
|
{
|
|
2520
3638
|
fontSize: usedFontSize,
|
|
2521
3639
|
variant,
|
|
2522
3640
|
colorScheme,
|
|
2523
3641
|
style: typographyStyle,
|
|
2524
|
-
children: ExtraStyles ? /* @__PURE__ */
|
|
3642
|
+
children: ExtraStyles ? /* @__PURE__ */ jsx8(ExtraStyles, { children: /* @__PURE__ */ jsx8(MarkdownContent_default, { content: usedContent, customComponents: stableCustomComponents }) }) : /* @__PURE__ */ jsx8(MarkdownContent_default, { content: usedContent, customComponents: stableCustomComponents })
|
|
2525
3643
|
}
|
|
2526
3644
|
)
|
|
2527
3645
|
}
|
|
2528
3646
|
) });
|
|
2529
3647
|
};
|
|
2530
|
-
var AIMarkdown =
|
|
3648
|
+
var AIMarkdown = memo4(AIMarkdownComponent);
|
|
2531
3649
|
AIMarkdown.displayName = "AIMarkdown";
|
|
2532
3650
|
var index_default = AIMarkdown;
|
|
2533
3651
|
export {
|
|
3652
|
+
AIMarkdownDocuments,
|
|
2534
3653
|
AIMarkdownRenderDisplayOptimizeAbility,
|
|
2535
3654
|
AIMarkdownRenderExtraSyntax,
|
|
2536
3655
|
index_default as default,
|
|
2537
3656
|
defaultAIMarkdownRenderConfig,
|
|
2538
3657
|
useAIMarkdownMetadata,
|
|
2539
3658
|
useAIMarkdownRenderState,
|
|
3659
|
+
useDocumentRegistry,
|
|
2540
3660
|
useStableValue
|
|
2541
3661
|
};
|
|
2542
3662
|
//# sourceMappingURL=index.js.map
|