vantage-md 0.1.7 → 0.5.4
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 +24 -9
- package/dist/index.cjs +862 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +440 -14
- package/dist/index.d.ts +440 -14
- package/dist/index.js +840 -47
- package/dist/index.js.map +1 -1
- package/dist/prose.css +2 -1
- package/dist/react.cjs +1063 -117
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +260 -14
- package/dist/react.d.ts +260 -14
- package/dist/react.js +1056 -118
- package/dist/react.js.map +1 -1
- package/dist/styles.css +240 -0
- package/package.json +18 -8
package/dist/react.js
CHANGED
|
@@ -36,25 +36,503 @@ var BLOCK_TAGS = /* @__PURE__ */ new Set([
|
|
|
36
36
|
"hr",
|
|
37
37
|
"div"
|
|
38
38
|
]);
|
|
39
|
-
function visit(node) {
|
|
39
|
+
function visit(node, offset) {
|
|
40
40
|
if ("children" in node) {
|
|
41
41
|
for (const child of node.children) {
|
|
42
42
|
if (child.type === "element") {
|
|
43
43
|
if (BLOCK_TAGS.has(child.tagName) && child.position?.start?.line) {
|
|
44
44
|
child.properties = child.properties || {};
|
|
45
|
-
child.properties["dataSourceLine"] = child.position.start.line;
|
|
45
|
+
child.properties["dataSourceLine"] = child.position.start.line + offset;
|
|
46
46
|
}
|
|
47
|
-
visit(child);
|
|
47
|
+
visit(child, offset);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
var rehypeSourceLines = () => {
|
|
52
|
+
var rehypeSourceLines = (options) => {
|
|
53
|
+
const offset = options?.offset ?? 0;
|
|
53
54
|
return (tree) => {
|
|
54
|
-
visit(tree);
|
|
55
|
+
visit(tree, offset);
|
|
55
56
|
};
|
|
56
57
|
};
|
|
57
58
|
var rehypeSourceLines_default = rehypeSourceLines;
|
|
59
|
+
|
|
60
|
+
// src/vantageDirectives.ts
|
|
61
|
+
var VANTAGE_TONES = [
|
|
62
|
+
"note",
|
|
63
|
+
"tip",
|
|
64
|
+
"important",
|
|
65
|
+
"warning",
|
|
66
|
+
"caution",
|
|
67
|
+
"muted"
|
|
68
|
+
];
|
|
69
|
+
var VANTAGE_EMPHASIS = ["strong", "normal", "quiet"];
|
|
70
|
+
var VANTAGE_BADGES = [
|
|
71
|
+
"draft",
|
|
72
|
+
"stale",
|
|
73
|
+
"blocked",
|
|
74
|
+
"done",
|
|
75
|
+
"wip"
|
|
76
|
+
];
|
|
77
|
+
var VANTAGE_COLLAPSED = ["true", "false"];
|
|
78
|
+
var VANTAGE_RUNS = ["start", "middle", "end", "only"];
|
|
79
|
+
var VANTAGE_STYLE_TARGETS = [
|
|
80
|
+
"p",
|
|
81
|
+
"h1",
|
|
82
|
+
"h2",
|
|
83
|
+
"h3",
|
|
84
|
+
"h4",
|
|
85
|
+
"h5",
|
|
86
|
+
"h6",
|
|
87
|
+
"li",
|
|
88
|
+
"blockquote",
|
|
89
|
+
"pre",
|
|
90
|
+
"table",
|
|
91
|
+
"tr",
|
|
92
|
+
"ul",
|
|
93
|
+
"ol",
|
|
94
|
+
"hr",
|
|
95
|
+
"div"
|
|
96
|
+
];
|
|
97
|
+
var VANTAGE_ANCHOR_TARGETS = [
|
|
98
|
+
"p",
|
|
99
|
+
"h1",
|
|
100
|
+
"h2",
|
|
101
|
+
"h3",
|
|
102
|
+
"h4",
|
|
103
|
+
"h5",
|
|
104
|
+
"h6",
|
|
105
|
+
"li",
|
|
106
|
+
"blockquote",
|
|
107
|
+
"pre",
|
|
108
|
+
"table"
|
|
109
|
+
];
|
|
110
|
+
var STYLE_KEYS = {
|
|
111
|
+
tone: VANTAGE_TONES,
|
|
112
|
+
emphasis: VANTAGE_EMPHASIS,
|
|
113
|
+
badge: VANTAGE_BADGES,
|
|
114
|
+
collapsed: VANTAGE_COLLAPSED
|
|
115
|
+
};
|
|
116
|
+
var DIRECTIVE_VOCABULARY = {
|
|
117
|
+
section: STYLE_KEYS,
|
|
118
|
+
block: STYLE_KEYS,
|
|
119
|
+
oq: { id: null, leaning: null }
|
|
120
|
+
};
|
|
121
|
+
var WS = /[ \t\r\n]*/y;
|
|
122
|
+
var SENTINEL_PREFIX = /^[ \t\r\n]*vantage:/;
|
|
123
|
+
var NAME = /[a-z][a-z0-9-]*/y;
|
|
124
|
+
var UNQUOTED = /[A-Za-z0-9_.:#-]+/y;
|
|
125
|
+
var QUOTED = /"[^"]*"/y;
|
|
126
|
+
function token(comment, offset) {
|
|
127
|
+
const rest = comment.slice(offset);
|
|
128
|
+
const end = rest.search(/[ \t\r\n]/);
|
|
129
|
+
const word = end === -1 ? rest : rest.slice(0, end);
|
|
130
|
+
return word.length > 24 ? `${word.slice(0, 24)}\u2026` : word;
|
|
131
|
+
}
|
|
132
|
+
function matchAt(pattern, comment, offset) {
|
|
133
|
+
pattern.lastIndex = offset;
|
|
134
|
+
const match = pattern.exec(comment);
|
|
135
|
+
return match === null ? null : match[0];
|
|
136
|
+
}
|
|
137
|
+
function skipWhitespace(comment, offset) {
|
|
138
|
+
return matchAt(WS, comment, offset)?.length ?? 0;
|
|
139
|
+
}
|
|
140
|
+
function malformed(reason, offset) {
|
|
141
|
+
return { kind: "malformed", reason, offset };
|
|
142
|
+
}
|
|
143
|
+
function parseVantageDirective(comment) {
|
|
144
|
+
const sentinel = SENTINEL_PREFIX.exec(comment);
|
|
145
|
+
if (sentinel === null) return null;
|
|
146
|
+
let at = sentinel[0].length;
|
|
147
|
+
at += skipWhitespace(comment, at);
|
|
148
|
+
const nameOffset = at;
|
|
149
|
+
const name = matchAt(NAME, comment, at);
|
|
150
|
+
if (name === null) {
|
|
151
|
+
return malformed("no directive name after `vantage:`", at);
|
|
152
|
+
}
|
|
153
|
+
at += name.length;
|
|
154
|
+
const pairs = [];
|
|
155
|
+
while (at < comment.length) {
|
|
156
|
+
const gap = skipWhitespace(comment, at);
|
|
157
|
+
at += gap;
|
|
158
|
+
if (at >= comment.length) break;
|
|
159
|
+
if (gap === 0) {
|
|
160
|
+
return malformed(`\`${token(comment, at)}\` needs a space before it`, at);
|
|
161
|
+
}
|
|
162
|
+
const keyOffset = at;
|
|
163
|
+
const key = matchAt(NAME, comment, at);
|
|
164
|
+
if (key === null) {
|
|
165
|
+
return malformed(
|
|
166
|
+
`\`${token(comment, at)}\` is not a \`key=value\` pair`,
|
|
167
|
+
at
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
at += key.length;
|
|
171
|
+
if (comment[at] !== "=") {
|
|
172
|
+
return malformed(`\`${key}\` is not followed by \`=value\``, at);
|
|
173
|
+
}
|
|
174
|
+
at += 1;
|
|
175
|
+
const valueOffset = at;
|
|
176
|
+
const quoted = matchAt(QUOTED, comment, at);
|
|
177
|
+
if (quoted !== null) {
|
|
178
|
+
at += quoted.length;
|
|
179
|
+
pairs.push({
|
|
180
|
+
key,
|
|
181
|
+
value: quoted.slice(1, -1),
|
|
182
|
+
keyOffset,
|
|
183
|
+
valueOffset,
|
|
184
|
+
quoted: true
|
|
185
|
+
});
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const unquoted = matchAt(UNQUOTED, comment, at);
|
|
189
|
+
if (unquoted === null) {
|
|
190
|
+
const found = token(comment, at);
|
|
191
|
+
return malformed(
|
|
192
|
+
found === "" ? `\`${key}=\` has no value` : `\`${found}\` is not a valid value for \`${key}\``,
|
|
193
|
+
at
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
at += unquoted.length;
|
|
197
|
+
pairs.push({ key, value: unquoted, keyOffset, valueOffset, quoted: false });
|
|
198
|
+
}
|
|
199
|
+
return { kind: "directive", name, nameOffset, pairs };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// src/rehypeVantageDirectives.ts
|
|
203
|
+
var STYLE_TARGET_TAGS = new Set(VANTAGE_STYLE_TARGETS);
|
|
204
|
+
var ANCHOR_TARGET_TAGS = new Set(VANTAGE_ANCHOR_TARGETS);
|
|
205
|
+
var HEADING_DEPTHS = /* @__PURE__ */ new Map([
|
|
206
|
+
["h1", 1],
|
|
207
|
+
["h2", 2],
|
|
208
|
+
["h3", 3],
|
|
209
|
+
["h4", 4],
|
|
210
|
+
["h5", 5],
|
|
211
|
+
["h6", 6]
|
|
212
|
+
]);
|
|
213
|
+
var RANGE_PROPERTIES = /* @__PURE__ */ new Map([
|
|
214
|
+
["tone", "dataVantageTone"],
|
|
215
|
+
["emphasis", "dataVantageEmphasis"]
|
|
216
|
+
]);
|
|
217
|
+
var POINT_PROPERTIES = /* @__PURE__ */ new Map([["badge", "dataVantageBadge"]]);
|
|
218
|
+
var RUN_PROPERTY = "dataVantageRun";
|
|
219
|
+
var OQ_PROPERTY = "dataVantageOq";
|
|
220
|
+
var LEANING_PROPERTY = "dataVantageLeaning";
|
|
221
|
+
var COLLAPSED_PROPERTY = "dataVantageCollapsed";
|
|
222
|
+
var COLLAPSE_GROUP_PROPERTY = "dataVantageCollapseGroup";
|
|
223
|
+
var COLLAPSE_TOGGLE_PROPERTY = "dataVantageCollapseToggle";
|
|
224
|
+
var MAX_LEANING = 500;
|
|
225
|
+
function isSkippable(node) {
|
|
226
|
+
if (node.type === "comment" || node.type === "doctype") return true;
|
|
227
|
+
if (node.type === "text") return node.value.trim() === "";
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
function headingDepth(node) {
|
|
231
|
+
if (node.type !== "element") return void 0;
|
|
232
|
+
return HEADING_DEPTHS.get(node.tagName);
|
|
233
|
+
}
|
|
234
|
+
function setProperty(element, property, value) {
|
|
235
|
+
element.properties = element.properties ?? {};
|
|
236
|
+
element.properties[property] = value;
|
|
237
|
+
}
|
|
238
|
+
function runValue(index, length) {
|
|
239
|
+
if (length === 1) return "only";
|
|
240
|
+
if (index === 0) return "start";
|
|
241
|
+
return index === length - 1 ? "end" : "middle";
|
|
242
|
+
}
|
|
243
|
+
function vocabularyOf(name, key) {
|
|
244
|
+
return DIRECTIVE_VOCABULARY[name]?.[key];
|
|
245
|
+
}
|
|
246
|
+
function accepts(name, key, value) {
|
|
247
|
+
const values = vocabularyOf(name, key);
|
|
248
|
+
if (values === void 0) return false;
|
|
249
|
+
return values === null || values.includes(value);
|
|
250
|
+
}
|
|
251
|
+
function styleRange(children, targetIndex, name) {
|
|
252
|
+
const range = [targetIndex];
|
|
253
|
+
const depth = name === "section" ? headingDepth(children[targetIndex]) : void 0;
|
|
254
|
+
if (depth === void 0) return range;
|
|
255
|
+
for (let i = targetIndex + 1; i < children.length; i++) {
|
|
256
|
+
const node = children[i];
|
|
257
|
+
const nodeDepth = headingDepth(node);
|
|
258
|
+
if (nodeDepth !== void 0 && nodeDepth <= depth) break;
|
|
259
|
+
if (node.type === "element" && STYLE_TARGET_TAGS.has(node.tagName)) {
|
|
260
|
+
range.push(i);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return range;
|
|
264
|
+
}
|
|
265
|
+
function collapsesSection(name, pairs, target) {
|
|
266
|
+
if (name !== "section") return false;
|
|
267
|
+
if (pairs.get("collapsed") !== "true") return false;
|
|
268
|
+
return headingDepth(target) !== void 0;
|
|
269
|
+
}
|
|
270
|
+
function stampStyle(children, targetIndex, name, pairs, state) {
|
|
271
|
+
const target = children[targetIndex];
|
|
272
|
+
if (!STYLE_TARGET_TAGS.has(target.tagName)) return;
|
|
273
|
+
const rangeStamps = [];
|
|
274
|
+
const targetStamps = [];
|
|
275
|
+
for (const [key, value] of pairs) {
|
|
276
|
+
if (!accepts(name, key, value)) continue;
|
|
277
|
+
const rangeProperty = RANGE_PROPERTIES.get(key);
|
|
278
|
+
if (rangeProperty !== void 0) {
|
|
279
|
+
rangeStamps.push([rangeProperty, value]);
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
const pointProperty = POINT_PROPERTIES.get(key);
|
|
283
|
+
if (pointProperty !== void 0) targetStamps.push([pointProperty, value]);
|
|
284
|
+
}
|
|
285
|
+
const collapses = collapsesSection(name, pairs, target);
|
|
286
|
+
if (rangeStamps.length === 0 && targetStamps.length === 0 && !collapses) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
const range = styleRange(children, targetIndex, name);
|
|
290
|
+
const group = collapses && range.length > 1 ? String(state.nextGroup++) : void 0;
|
|
291
|
+
for (let i = 0; i < range.length; i++) {
|
|
292
|
+
const element = children[range[i]];
|
|
293
|
+
for (const [property, value] of rangeStamps) {
|
|
294
|
+
setProperty(element, property, value);
|
|
295
|
+
}
|
|
296
|
+
if (i === 0) {
|
|
297
|
+
for (const [property, value] of targetStamps) {
|
|
298
|
+
setProperty(element, property, value);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (rangeStamps.length > 0) {
|
|
302
|
+
setProperty(element, RUN_PROPERTY, runValue(i, range.length));
|
|
303
|
+
}
|
|
304
|
+
if (group === void 0) continue;
|
|
305
|
+
if (i === 0) {
|
|
306
|
+
setProperty(element, COLLAPSE_TOGGLE_PROPERTY, group);
|
|
307
|
+
} else {
|
|
308
|
+
setProperty(element, COLLAPSED_PROPERTY, "true");
|
|
309
|
+
setProperty(element, COLLAPSE_GROUP_PROPERTY, group);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
function stampOq(target, pairs) {
|
|
314
|
+
setProperty(target, OQ_PROPERTY, "true");
|
|
315
|
+
const leaning = pairs.get("leaning");
|
|
316
|
+
if (leaning === void 0) return;
|
|
317
|
+
const text = leaning.replace(/\s+/g, " ").trim().slice(0, MAX_LEANING);
|
|
318
|
+
if (text !== "") setProperty(target, LEANING_PROPERTY, text);
|
|
319
|
+
}
|
|
320
|
+
function stampRun(children, targetIndex, run, state) {
|
|
321
|
+
const target = children[targetIndex];
|
|
322
|
+
const style = /* @__PURE__ */ new Map();
|
|
323
|
+
const oq = /* @__PURE__ */ new Map();
|
|
324
|
+
let styleName;
|
|
325
|
+
let hasOq = false;
|
|
326
|
+
for (const directive of run) {
|
|
327
|
+
if (directive.name === "section" || directive.name === "block") {
|
|
328
|
+
styleName = directive.name;
|
|
329
|
+
for (const pair of directive.pairs) style.set(pair.key, pair.value);
|
|
330
|
+
} else if (directive.name === "oq") {
|
|
331
|
+
hasOq = true;
|
|
332
|
+
for (const pair of directive.pairs) oq.set(pair.key, pair.value);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
if (styleName !== void 0) {
|
|
336
|
+
stampStyle(children, targetIndex, styleName, style, state);
|
|
337
|
+
}
|
|
338
|
+
if (hasOq && ANCHOR_TARGET_TAGS.has(target.tagName)) {
|
|
339
|
+
stampOq(target, oq);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
function directiveOf(node) {
|
|
343
|
+
if (node.type !== "comment") return void 0;
|
|
344
|
+
const parsed = parseVantageDirective(node.value);
|
|
345
|
+
return parsed !== null && parsed.kind === "directive" ? parsed : void 0;
|
|
346
|
+
}
|
|
347
|
+
function processChildren(parent, state) {
|
|
348
|
+
const children = parent.children;
|
|
349
|
+
let i = 0;
|
|
350
|
+
while (i < children.length) {
|
|
351
|
+
const node = children[i];
|
|
352
|
+
if (node.type === "element") {
|
|
353
|
+
processChildren(node, state);
|
|
354
|
+
i++;
|
|
355
|
+
continue;
|
|
356
|
+
}
|
|
357
|
+
const first = directiveOf(node);
|
|
358
|
+
if (first === void 0) {
|
|
359
|
+
i++;
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
const run = [first];
|
|
363
|
+
let j = i + 1;
|
|
364
|
+
let targetIndex = -1;
|
|
365
|
+
for (; j < children.length; j++) {
|
|
366
|
+
const next = children[j];
|
|
367
|
+
if (next.type === "element") {
|
|
368
|
+
targetIndex = j;
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
371
|
+
if (!isSkippable(next)) break;
|
|
372
|
+
const directive = directiveOf(next);
|
|
373
|
+
if (directive !== void 0) run.push(directive);
|
|
374
|
+
}
|
|
375
|
+
if (targetIndex >= 0) stampRun(children, targetIndex, run, state);
|
|
376
|
+
i = j;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
var rehypeVantageDirectives = () => {
|
|
380
|
+
return (tree) => {
|
|
381
|
+
processChildren(tree, { nextGroup: 1 });
|
|
382
|
+
};
|
|
383
|
+
};
|
|
384
|
+
var rehypeVantageDirectives_default = rehypeVantageDirectives;
|
|
385
|
+
|
|
386
|
+
// src/rehypeVantageMathStamps.ts
|
|
387
|
+
var CARRIED_KEY = "vantageDisplayMathStamps";
|
|
388
|
+
function classNames(node) {
|
|
389
|
+
const value = node.properties?.className;
|
|
390
|
+
return Array.isArray(value) ? value.map(String) : [];
|
|
391
|
+
}
|
|
392
|
+
function isDisplayMath(node) {
|
|
393
|
+
if (node.type !== "element" || node.tagName !== "pre") return false;
|
|
394
|
+
return node.children.some(
|
|
395
|
+
(child) => child.type === "element" && child.tagName === "code" && classNames(child).includes("language-math")
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
function carriedProperties(properties) {
|
|
399
|
+
const carried = {};
|
|
400
|
+
for (const [key, value] of Object.entries(properties ?? {})) {
|
|
401
|
+
if (key === "dataSourceLine" || key.startsWith("dataVantage")) {
|
|
402
|
+
carried[key] = value;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
return carried;
|
|
406
|
+
}
|
|
407
|
+
function collect(parent, out) {
|
|
408
|
+
const children = parent.children;
|
|
409
|
+
for (let i = 0; i < children.length; i++) {
|
|
410
|
+
const node = children[i];
|
|
411
|
+
if (node.type !== "element") continue;
|
|
412
|
+
if (isDisplayMath(node)) {
|
|
413
|
+
const properties = carriedProperties(node.properties);
|
|
414
|
+
if (Object.keys(properties).length > 0) {
|
|
415
|
+
out.push({
|
|
416
|
+
parent,
|
|
417
|
+
anchor: i === 0 ? void 0 : children[i - 1],
|
|
418
|
+
properties
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
continue;
|
|
422
|
+
}
|
|
423
|
+
collect(node, out);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
function reapply(carried) {
|
|
427
|
+
for (const { parent, anchor, properties } of carried) {
|
|
428
|
+
const siblings = parent.children;
|
|
429
|
+
let index = 0;
|
|
430
|
+
if (anchor !== void 0) {
|
|
431
|
+
const at = siblings.indexOf(anchor);
|
|
432
|
+
if (at === -1) continue;
|
|
433
|
+
index = at + 1;
|
|
434
|
+
}
|
|
435
|
+
const replacement = siblings[index];
|
|
436
|
+
if (replacement === void 0 || replacement.type !== "element") continue;
|
|
437
|
+
if (!classNames(replacement).some((name) => name.startsWith("katex"))) {
|
|
438
|
+
continue;
|
|
439
|
+
}
|
|
440
|
+
replacement.properties ??= {};
|
|
441
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
442
|
+
replacement.properties[key] ??= value;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
var rehypeCaptureMathStamps = () => {
|
|
447
|
+
return (tree, file) => {
|
|
448
|
+
const carried = [];
|
|
449
|
+
collect(tree, carried);
|
|
450
|
+
file.data[CARRIED_KEY] = carried;
|
|
451
|
+
};
|
|
452
|
+
};
|
|
453
|
+
var rehypeRestoreMathStamps = () => {
|
|
454
|
+
return (_tree, file) => {
|
|
455
|
+
const carried = file.data[CARRIED_KEY];
|
|
456
|
+
delete file.data[CARRIED_KEY];
|
|
457
|
+
if (Array.isArray(carried)) reapply(carried);
|
|
458
|
+
};
|
|
459
|
+
};
|
|
460
|
+
var SAFE_STYLE_PROPERTIES = [
|
|
461
|
+
// Box metrics. `top`/`right`/`bottom`/`left` are inert now that `position` is
|
|
462
|
+
// banned, and they stay only because dropping them would fail the whole
|
|
463
|
+
// attribute for a document that writes one — the all-or-nothing rule below
|
|
464
|
+
// makes every removal a behaviour change. They buy an attacker nothing that
|
|
465
|
+
// negative `margin` does not already buy.
|
|
466
|
+
"height",
|
|
467
|
+
"min-height",
|
|
468
|
+
"max-height",
|
|
469
|
+
"width",
|
|
470
|
+
"min-width",
|
|
471
|
+
"max-width",
|
|
472
|
+
"top",
|
|
473
|
+
"bottom",
|
|
474
|
+
"left",
|
|
475
|
+
"right",
|
|
476
|
+
"margin",
|
|
477
|
+
"margin-top",
|
|
478
|
+
"margin-right",
|
|
479
|
+
"margin-bottom",
|
|
480
|
+
"margin-left",
|
|
481
|
+
"padding",
|
|
482
|
+
"padding-top",
|
|
483
|
+
"padding-right",
|
|
484
|
+
"padding-bottom",
|
|
485
|
+
"padding-left",
|
|
486
|
+
// Rules and boxes.
|
|
487
|
+
"border",
|
|
488
|
+
"border-style",
|
|
489
|
+
"border-color",
|
|
490
|
+
"border-width",
|
|
491
|
+
"border-top-width",
|
|
492
|
+
"border-right-width",
|
|
493
|
+
"border-bottom-width",
|
|
494
|
+
"border-left-width",
|
|
495
|
+
"border-top-style",
|
|
496
|
+
"border-right-style",
|
|
497
|
+
"border-bottom-style",
|
|
498
|
+
"border-left-style",
|
|
499
|
+
"border-top-color",
|
|
500
|
+
"border-right-color",
|
|
501
|
+
"border-bottom-color",
|
|
502
|
+
"border-left-color",
|
|
503
|
+
"border-radius",
|
|
504
|
+
// Typography.
|
|
505
|
+
"color",
|
|
506
|
+
"background-color",
|
|
507
|
+
"font",
|
|
508
|
+
"font-size",
|
|
509
|
+
"font-style",
|
|
510
|
+
"font-weight",
|
|
511
|
+
"font-family",
|
|
512
|
+
"font-variant",
|
|
513
|
+
"line-height",
|
|
514
|
+
"letter-spacing",
|
|
515
|
+
"word-spacing",
|
|
516
|
+
"text-align",
|
|
517
|
+
"text-decoration",
|
|
518
|
+
"text-indent",
|
|
519
|
+
"white-space",
|
|
520
|
+
"vertical-align",
|
|
521
|
+
"list-style-type",
|
|
522
|
+
// Flow.
|
|
523
|
+
"display",
|
|
524
|
+
"float",
|
|
525
|
+
"clear",
|
|
526
|
+
"opacity",
|
|
527
|
+
"overflow"
|
|
528
|
+
];
|
|
529
|
+
var VALUE = `[^;:()"'\\\\]*`;
|
|
530
|
+
var DECLARATION = `(?:(?:${SAFE_STYLE_PROPERTIES.join("|")})\\s*:${VALUE})`;
|
|
531
|
+
var SAFE_STYLE = new RegExp(
|
|
532
|
+
`^\\s*(?:${DECLARATION};\\s*)*${DECLARATION}?$`,
|
|
533
|
+
"i"
|
|
534
|
+
);
|
|
535
|
+
var COLLAPSE_GROUP_ID = /^[0-9]+$/;
|
|
58
536
|
var sanitizeSchema = {
|
|
59
537
|
...defaultSchema,
|
|
60
538
|
tagNames: [
|
|
@@ -90,20 +568,94 @@ var sanitizeSchema = {
|
|
|
90
568
|
"*": [
|
|
91
569
|
...defaultSchema.attributes?.["*"] || [],
|
|
92
570
|
"className",
|
|
93
|
-
"style",
|
|
94
|
-
"dataSourceLine"
|
|
571
|
+
["style", SAFE_STYLE],
|
|
572
|
+
"dataSourceLine",
|
|
573
|
+
// What `rehypeVantageDirectives` compiles a `<!-- vantage: … -->` comment
|
|
574
|
+
// into, named individually — never by a `data-vantage-*` wildcard, which
|
|
575
|
+
// would readmit whatever a future bug emits and whatever a document
|
|
576
|
+
// hand-writes as raw HTML.
|
|
577
|
+
//
|
|
578
|
+
// The value lists are the belt to the plugin's braces: the vocabulary is
|
|
579
|
+
// closed in the plugin *and* here, imported from the one module that
|
|
580
|
+
// defines it, so even if a refactor let an unvalidated value reach the
|
|
581
|
+
// tree the sanitiser still refuses it.
|
|
582
|
+
["dataVantageTone", ...VANTAGE_TONES],
|
|
583
|
+
["dataVantageEmphasis", ...VANTAGE_EMPHASIS],
|
|
584
|
+
["dataVantageBadge", ...VANTAGE_BADGES],
|
|
585
|
+
["dataVantageCollapsed", ...VANTAGE_COLLAPSED],
|
|
586
|
+
// The other half of `collapsed`: which group a hidden block belongs to,
|
|
587
|
+
// and which group a heading toggles. Both are plugin-minted counters with
|
|
588
|
+
// no vocabulary to allowlist, so they take a pattern instead —
|
|
589
|
+
// `hast-util-sanitize` accepts a `RegExp` in place of a literal value.
|
|
590
|
+
// A pattern rather than a bare name because the JS interpolates the value
|
|
591
|
+
// into a selector: anything but digits has no business reaching it.
|
|
592
|
+
["dataVantageCollapseGroup", COLLAPSE_GROUP_ID],
|
|
593
|
+
["dataVantageCollapseToggle", COLLAPSE_GROUP_ID],
|
|
594
|
+
["dataVantageRun", ...VANTAGE_RUNS],
|
|
595
|
+
["dataVantageOq", "true"],
|
|
596
|
+
// The design's one genuinely free-text value: the body of a review
|
|
597
|
+
// comment, so it cannot be value-allowlisted and this entry is name-only.
|
|
598
|
+
// Two defences remain rather than three — `hast` escapes the value on
|
|
599
|
+
// serialisation and React sets it through the DOM property path, so it
|
|
600
|
+
// cannot break out of the attribute — and the honest record of that is in
|
|
601
|
+
// the design doc rather than a third layer implied here.
|
|
602
|
+
"dataVantageLeaning"
|
|
95
603
|
],
|
|
96
604
|
code: [...defaultSchema.attributes?.code || [], "className"],
|
|
97
|
-
span: [
|
|
98
|
-
|
|
605
|
+
span: [
|
|
606
|
+
...defaultSchema.attributes?.span || [],
|
|
607
|
+
"className",
|
|
608
|
+
["style", SAFE_STYLE]
|
|
609
|
+
],
|
|
610
|
+
div: [
|
|
611
|
+
...defaultSchema.attributes?.div || [],
|
|
612
|
+
"className",
|
|
613
|
+
["style", SAFE_STYLE]
|
|
614
|
+
],
|
|
99
615
|
a: [...defaultSchema.attributes?.a || [], "id", "className"],
|
|
100
616
|
math: ["xmlns"],
|
|
101
617
|
annotation: ["encoding"],
|
|
102
618
|
img: [...defaultSchema.attributes?.img || [], "loading"],
|
|
103
|
-
td: [...defaultSchema.attributes?.td || [], "style"],
|
|
104
|
-
th: [...defaultSchema.attributes?.th || [], "style"]
|
|
619
|
+
td: [...defaultSchema.attributes?.td || [], ["style", SAFE_STYLE]],
|
|
620
|
+
th: [...defaultSchema.attributes?.th || [], ["style", SAFE_STYLE]]
|
|
105
621
|
}
|
|
106
622
|
};
|
|
623
|
+
|
|
624
|
+
// src/pipeline.ts
|
|
625
|
+
function buildRemarkPlugins(options = {}) {
|
|
626
|
+
const { gfm = true, math = true } = options;
|
|
627
|
+
const plugins = [];
|
|
628
|
+
if (gfm) plugins.push([remarkGfm, { singleTilde: false }]);
|
|
629
|
+
if (math) plugins.push([remarkMath, { singleDollarTextMath: false }]);
|
|
630
|
+
return plugins;
|
|
631
|
+
}
|
|
632
|
+
function buildRehypePlugins(options = {}) {
|
|
633
|
+
const {
|
|
634
|
+
math = true,
|
|
635
|
+
highlight = true,
|
|
636
|
+
sourceLines = true,
|
|
637
|
+
sanitize = true,
|
|
638
|
+
bodyLineOffset = 0
|
|
639
|
+
} = options;
|
|
640
|
+
const plugins = [rehypeRaw];
|
|
641
|
+
if (sourceLines) {
|
|
642
|
+
plugins.push([rehypeSourceLines_default, { offset: bodyLineOffset }]);
|
|
643
|
+
}
|
|
644
|
+
plugins.push(rehypeVantageDirectives_default);
|
|
645
|
+
if (sanitize) plugins.push([rehypeSanitize, sanitizeSchema]);
|
|
646
|
+
plugins.push(rehypeSlug);
|
|
647
|
+
if (highlight) plugins.push(rehypeHighlight);
|
|
648
|
+
if (math) {
|
|
649
|
+
plugins.push(rehypeCaptureMathStamps, rehypeKatex, rehypeRestoreMathStamps);
|
|
650
|
+
}
|
|
651
|
+
return plugins;
|
|
652
|
+
}
|
|
653
|
+
function buildPipeline(options = {}) {
|
|
654
|
+
return {
|
|
655
|
+
remarkPlugins: buildRemarkPlugins(options),
|
|
656
|
+
rehypePlugins: buildRehypePlugins(options)
|
|
657
|
+
};
|
|
658
|
+
}
|
|
107
659
|
function parseFrontmatter(content) {
|
|
108
660
|
if (content.startsWith("+++")) {
|
|
109
661
|
return parseFrontmatterWithDelimiter(content, "+++", "toml");
|
|
@@ -111,24 +663,74 @@ function parseFrontmatter(content) {
|
|
|
111
663
|
if (content.startsWith("---")) {
|
|
112
664
|
return parseFrontmatterWithDelimiter(content, "---", "yaml");
|
|
113
665
|
}
|
|
114
|
-
return
|
|
666
|
+
return withOffset(content, {
|
|
667
|
+
frontmatter: {},
|
|
668
|
+
body: content,
|
|
669
|
+
format: "none"
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
function withOffset(content, parsed) {
|
|
673
|
+
const stripped = content.slice(0, content.length - parsed.body.length);
|
|
674
|
+
let bodyLineOffset = 0;
|
|
675
|
+
for (const ch of stripped) {
|
|
676
|
+
if (ch === "\n") bodyLineOffset++;
|
|
677
|
+
}
|
|
678
|
+
return { ...parsed, bodyLineOffset };
|
|
115
679
|
}
|
|
116
680
|
function parseFrontmatterWithDelimiter(content, delimiter, format) {
|
|
117
681
|
const searchStart = delimiter.length;
|
|
118
682
|
const endIndex = content.indexOf(`
|
|
119
683
|
${delimiter}`, searchStart);
|
|
120
684
|
if (endIndex === -1) {
|
|
121
|
-
return
|
|
685
|
+
return withOffset(content, {
|
|
686
|
+
frontmatter: {},
|
|
687
|
+
body: content,
|
|
688
|
+
format: "none",
|
|
689
|
+
problem: { kind: "unterminated", delimiter }
|
|
690
|
+
});
|
|
122
691
|
}
|
|
123
692
|
const raw = content.slice(searchStart + 1, endIndex).trim();
|
|
124
693
|
const bodyStart = endIndex + 1 + delimiter.length;
|
|
125
694
|
const body = content.slice(bodyStart).replace(/^\n/, "");
|
|
126
695
|
try {
|
|
127
|
-
const
|
|
128
|
-
return
|
|
129
|
-
|
|
130
|
-
|
|
696
|
+
const parsed = format === "toml" ? parse(raw) : YAML.parse(raw);
|
|
697
|
+
return withOffset(content, {
|
|
698
|
+
frontmatter: parsed || {},
|
|
699
|
+
body,
|
|
700
|
+
format,
|
|
701
|
+
...isMapping(parsed) ? {} : { problem: { kind: "not-a-mapping", delimiter } }
|
|
702
|
+
});
|
|
703
|
+
} catch (error) {
|
|
704
|
+
return withOffset(content, {
|
|
705
|
+
frontmatter: {},
|
|
706
|
+
body: content,
|
|
707
|
+
format: "none",
|
|
708
|
+
problem: { kind: "invalid", delimiter, ...errorPosition(error) }
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
function isMapping(value) {
|
|
713
|
+
return value === null || value === void 0 || typeof value === "object" && !Array.isArray(value);
|
|
714
|
+
}
|
|
715
|
+
function errorPosition(error) {
|
|
716
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
717
|
+
const source = error;
|
|
718
|
+
const yamlPosition = source?.linePos?.[0];
|
|
719
|
+
if (typeof yamlPosition?.line === "number") {
|
|
720
|
+
return {
|
|
721
|
+
message,
|
|
722
|
+
line: yamlPosition.line,
|
|
723
|
+
...typeof yamlPosition.col === "number" ? { column: yamlPosition.col } : {}
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
if (typeof source?.line === "number") {
|
|
727
|
+
return {
|
|
728
|
+
message,
|
|
729
|
+
line: source.line,
|
|
730
|
+
...typeof source.column === "number" ? { column: source.column } : {}
|
|
731
|
+
};
|
|
131
732
|
}
|
|
733
|
+
return { message };
|
|
132
734
|
}
|
|
133
735
|
|
|
134
736
|
// src/mermaidCache.ts
|
|
@@ -155,23 +757,286 @@ async function getMermaid() {
|
|
|
155
757
|
}
|
|
156
758
|
return mermaidLoading;
|
|
157
759
|
}
|
|
158
|
-
var AlertTriangleIcon = () => /* @__PURE__ */ jsxs(
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
]
|
|
760
|
+
var AlertTriangleIcon = () => /* @__PURE__ */ jsxs(
|
|
761
|
+
"svg",
|
|
762
|
+
{
|
|
763
|
+
width: "16",
|
|
764
|
+
height: "16",
|
|
765
|
+
viewBox: "0 0 24 24",
|
|
766
|
+
fill: "none",
|
|
767
|
+
stroke: "currentColor",
|
|
768
|
+
strokeWidth: "2",
|
|
769
|
+
strokeLinecap: "round",
|
|
770
|
+
strokeLinejoin: "round",
|
|
771
|
+
className: "w-4 h-4 shrink-0",
|
|
772
|
+
children: [
|
|
773
|
+
/* @__PURE__ */ jsx("path", { d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" }),
|
|
774
|
+
/* @__PURE__ */ jsx("path", { d: "M12 9v4" }),
|
|
775
|
+
/* @__PURE__ */ jsx("path", { d: "M12 17h.01" })
|
|
776
|
+
]
|
|
777
|
+
}
|
|
778
|
+
);
|
|
779
|
+
var ChevronDownIcon = () => /* @__PURE__ */ jsx(
|
|
780
|
+
"svg",
|
|
781
|
+
{
|
|
782
|
+
width: "12",
|
|
783
|
+
height: "12",
|
|
784
|
+
viewBox: "0 0 24 24",
|
|
785
|
+
fill: "none",
|
|
786
|
+
stroke: "currentColor",
|
|
787
|
+
strokeWidth: "2",
|
|
788
|
+
strokeLinecap: "round",
|
|
789
|
+
strokeLinejoin: "round",
|
|
790
|
+
className: "w-3 h-3",
|
|
791
|
+
children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" })
|
|
792
|
+
}
|
|
793
|
+
);
|
|
794
|
+
var ChevronUpIcon = () => /* @__PURE__ */ jsx(
|
|
795
|
+
"svg",
|
|
796
|
+
{
|
|
797
|
+
width: "12",
|
|
798
|
+
height: "12",
|
|
799
|
+
viewBox: "0 0 24 24",
|
|
800
|
+
fill: "none",
|
|
801
|
+
stroke: "currentColor",
|
|
802
|
+
strokeWidth: "2",
|
|
803
|
+
strokeLinecap: "round",
|
|
804
|
+
strokeLinejoin: "round",
|
|
805
|
+
className: "w-3 h-3",
|
|
806
|
+
children: /* @__PURE__ */ jsx("path", { d: "m18 15-6-6-6 6" })
|
|
807
|
+
}
|
|
808
|
+
);
|
|
809
|
+
var MaximizeIcon = () => /* @__PURE__ */ jsxs(
|
|
810
|
+
"svg",
|
|
811
|
+
{
|
|
812
|
+
width: "16",
|
|
813
|
+
height: "16",
|
|
814
|
+
viewBox: "0 0 24 24",
|
|
815
|
+
fill: "none",
|
|
816
|
+
stroke: "currentColor",
|
|
817
|
+
strokeWidth: "2",
|
|
818
|
+
strokeLinecap: "round",
|
|
819
|
+
strokeLinejoin: "round",
|
|
820
|
+
className: "w-4 h-4 text-gray-600",
|
|
821
|
+
children: [
|
|
822
|
+
/* @__PURE__ */ jsx("polyline", { points: "15 3 21 3 21 9" }),
|
|
823
|
+
/* @__PURE__ */ jsx("polyline", { points: "9 21 3 21 3 15" }),
|
|
824
|
+
/* @__PURE__ */ jsx("line", { x1: "21", x2: "14", y1: "3", y2: "10" }),
|
|
825
|
+
/* @__PURE__ */ jsx("line", { x1: "3", x2: "10", y1: "21", y2: "14" })
|
|
826
|
+
]
|
|
827
|
+
}
|
|
828
|
+
);
|
|
829
|
+
var CloseIcon = () => /* @__PURE__ */ jsxs(
|
|
830
|
+
"svg",
|
|
831
|
+
{
|
|
832
|
+
width: "20",
|
|
833
|
+
height: "20",
|
|
834
|
+
viewBox: "0 0 24 24",
|
|
835
|
+
fill: "none",
|
|
836
|
+
stroke: "currentColor",
|
|
837
|
+
strokeWidth: "2",
|
|
838
|
+
strokeLinecap: "round",
|
|
839
|
+
strokeLinejoin: "round",
|
|
840
|
+
className: "w-5 h-5",
|
|
841
|
+
children: [
|
|
842
|
+
/* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
|
|
843
|
+
/* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
|
|
844
|
+
]
|
|
845
|
+
}
|
|
846
|
+
);
|
|
847
|
+
var PlusIcon = () => /* @__PURE__ */ jsxs(
|
|
848
|
+
"svg",
|
|
849
|
+
{
|
|
850
|
+
width: "16",
|
|
851
|
+
height: "16",
|
|
852
|
+
viewBox: "0 0 24 24",
|
|
853
|
+
fill: "none",
|
|
854
|
+
stroke: "currentColor",
|
|
855
|
+
strokeWidth: "2",
|
|
856
|
+
strokeLinecap: "round",
|
|
857
|
+
strokeLinejoin: "round",
|
|
858
|
+
className: "w-4 h-4",
|
|
859
|
+
children: [
|
|
860
|
+
/* @__PURE__ */ jsx("path", { d: "M5 12h14" }),
|
|
861
|
+
/* @__PURE__ */ jsx("path", { d: "M12 5v14" })
|
|
862
|
+
]
|
|
863
|
+
}
|
|
864
|
+
);
|
|
865
|
+
var MinusIcon = () => /* @__PURE__ */ jsx(
|
|
866
|
+
"svg",
|
|
867
|
+
{
|
|
868
|
+
width: "16",
|
|
869
|
+
height: "16",
|
|
870
|
+
viewBox: "0 0 24 24",
|
|
871
|
+
fill: "none",
|
|
872
|
+
stroke: "currentColor",
|
|
873
|
+
strokeWidth: "2",
|
|
874
|
+
strokeLinecap: "round",
|
|
875
|
+
strokeLinejoin: "round",
|
|
876
|
+
className: "w-4 h-4",
|
|
877
|
+
children: /* @__PURE__ */ jsx("path", { d: "M5 12h14" })
|
|
878
|
+
}
|
|
879
|
+
);
|
|
880
|
+
var ResetIcon = () => /* @__PURE__ */ jsxs(
|
|
881
|
+
"svg",
|
|
882
|
+
{
|
|
883
|
+
width: "16",
|
|
884
|
+
height: "16",
|
|
885
|
+
viewBox: "0 0 24 24",
|
|
886
|
+
fill: "none",
|
|
887
|
+
stroke: "currentColor",
|
|
888
|
+
strokeWidth: "2",
|
|
889
|
+
strokeLinecap: "round",
|
|
890
|
+
strokeLinejoin: "round",
|
|
891
|
+
className: "w-4 h-4",
|
|
892
|
+
children: [
|
|
893
|
+
/* @__PURE__ */ jsx("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
|
|
894
|
+
/* @__PURE__ */ jsx("path", { d: "M3 3v5h5" })
|
|
895
|
+
]
|
|
896
|
+
}
|
|
897
|
+
);
|
|
898
|
+
var MIN_SCALE = 0.2;
|
|
899
|
+
var MAX_SCALE = 8;
|
|
900
|
+
function ZoomableSvg({ svg }) {
|
|
901
|
+
const [scale, setScale] = useState(1);
|
|
902
|
+
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
|
903
|
+
const dragRef = useRef(null);
|
|
904
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
905
|
+
const viewportRef = useRef(null);
|
|
906
|
+
const reset = useCallback(() => {
|
|
907
|
+
setScale(1);
|
|
908
|
+
setOffset({ x: 0, y: 0 });
|
|
909
|
+
}, []);
|
|
910
|
+
const zoomBy = useCallback(
|
|
911
|
+
(factor, anchor) => {
|
|
912
|
+
setScale((prev) => {
|
|
913
|
+
const next = Math.min(MAX_SCALE, Math.max(MIN_SCALE, prev * factor));
|
|
914
|
+
if (next === prev) return prev;
|
|
915
|
+
const rect = viewportRef.current?.getBoundingClientRect();
|
|
916
|
+
if (rect) {
|
|
917
|
+
const ax = (anchor?.x ?? rect.width / 2) - rect.width / 2;
|
|
918
|
+
const ay = (anchor?.y ?? rect.height / 2) - rect.height / 2;
|
|
919
|
+
setOffset((o) => ({
|
|
920
|
+
x: ax - (ax - o.x) * next / prev,
|
|
921
|
+
y: ay - (ay - o.y) * next / prev
|
|
922
|
+
}));
|
|
923
|
+
}
|
|
924
|
+
return next;
|
|
925
|
+
});
|
|
926
|
+
},
|
|
927
|
+
[]
|
|
928
|
+
);
|
|
929
|
+
const handleWheel = useCallback(
|
|
930
|
+
(e) => {
|
|
931
|
+
e.preventDefault();
|
|
932
|
+
const rect = viewportRef.current?.getBoundingClientRect();
|
|
933
|
+
const anchor = rect ? { x: e.clientX - rect.left, y: e.clientY - rect.top } : void 0;
|
|
934
|
+
zoomBy(e.deltaY < 0 ? 1.15 : 1 / 1.15, anchor);
|
|
935
|
+
},
|
|
936
|
+
[zoomBy]
|
|
937
|
+
);
|
|
938
|
+
const handlePointerDown = (e) => {
|
|
939
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
940
|
+
dragRef.current = {
|
|
941
|
+
startX: e.clientX,
|
|
942
|
+
startY: e.clientY,
|
|
943
|
+
originX: offset.x,
|
|
944
|
+
originY: offset.y
|
|
945
|
+
};
|
|
946
|
+
setIsDragging(true);
|
|
947
|
+
};
|
|
948
|
+
const handlePointerMove = (e) => {
|
|
949
|
+
const d = dragRef.current;
|
|
950
|
+
if (!d) return;
|
|
951
|
+
setOffset({
|
|
952
|
+
x: d.originX + (e.clientX - d.startX),
|
|
953
|
+
y: d.originY + (e.clientY - d.startY)
|
|
954
|
+
});
|
|
955
|
+
};
|
|
956
|
+
const endDrag = (e) => {
|
|
957
|
+
if (dragRef.current) {
|
|
958
|
+
try {
|
|
959
|
+
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
960
|
+
} catch {
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
dragRef.current = null;
|
|
964
|
+
setIsDragging(false);
|
|
965
|
+
};
|
|
966
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative w-full h-full", children: [
|
|
967
|
+
/* @__PURE__ */ jsx(
|
|
968
|
+
"div",
|
|
969
|
+
{
|
|
970
|
+
ref: viewportRef,
|
|
971
|
+
onWheel: handleWheel,
|
|
972
|
+
onPointerDown: handlePointerDown,
|
|
973
|
+
onPointerMove: handlePointerMove,
|
|
974
|
+
onPointerUp: endDrag,
|
|
975
|
+
onPointerLeave: endDrag,
|
|
976
|
+
onDoubleClick: reset,
|
|
977
|
+
className: "w-full h-full overflow-hidden touch-none select-none",
|
|
978
|
+
style: { cursor: isDragging ? "grabbing" : "grab" },
|
|
979
|
+
children: /* @__PURE__ */ jsx(
|
|
980
|
+
"div",
|
|
981
|
+
{
|
|
982
|
+
className: "mermaid-zoom flex items-center justify-center w-full h-full",
|
|
983
|
+
style: {
|
|
984
|
+
transform: `translate(${offset.x}px, ${offset.y}px) scale(${scale})`,
|
|
985
|
+
transformOrigin: "center center",
|
|
986
|
+
transition: isDragging ? "none" : "transform 0.08s ease-out"
|
|
987
|
+
},
|
|
988
|
+
dangerouslySetInnerHTML: { __html: svg }
|
|
989
|
+
}
|
|
990
|
+
)
|
|
991
|
+
}
|
|
992
|
+
),
|
|
993
|
+
/* @__PURE__ */ jsxs("div", { className: "absolute bottom-4 right-4 flex items-center gap-1 rounded-lg bg-white/95 shadow-md border border-gray-200 px-1.5 py-1", children: [
|
|
994
|
+
/* @__PURE__ */ jsx(
|
|
995
|
+
"button",
|
|
996
|
+
{
|
|
997
|
+
onClick: () => zoomBy(1 / 1.3),
|
|
998
|
+
className: "p-1.5 rounded hover:bg-gray-100 text-gray-600",
|
|
999
|
+
"aria-label": "Zoom out",
|
|
1000
|
+
title: "Zoom out",
|
|
1001
|
+
children: /* @__PURE__ */ jsx(MinusIcon, {})
|
|
1002
|
+
}
|
|
1003
|
+
),
|
|
1004
|
+
/* @__PURE__ */ jsxs(
|
|
1005
|
+
"button",
|
|
1006
|
+
{
|
|
1007
|
+
onClick: reset,
|
|
1008
|
+
className: "px-2 py-1 text-xs font-medium rounded hover:bg-gray-100 text-gray-600 min-w-[3rem]",
|
|
1009
|
+
title: "Reset zoom (or double-click)",
|
|
1010
|
+
children: [
|
|
1011
|
+
Math.round(scale * 100),
|
|
1012
|
+
"%"
|
|
1013
|
+
]
|
|
1014
|
+
}
|
|
1015
|
+
),
|
|
1016
|
+
/* @__PURE__ */ jsx(
|
|
1017
|
+
"button",
|
|
1018
|
+
{
|
|
1019
|
+
onClick: () => zoomBy(1.3),
|
|
1020
|
+
className: "p-1.5 rounded hover:bg-gray-100 text-gray-600",
|
|
1021
|
+
"aria-label": "Zoom in",
|
|
1022
|
+
title: "Zoom in",
|
|
1023
|
+
children: /* @__PURE__ */ jsx(PlusIcon, {})
|
|
1024
|
+
}
|
|
1025
|
+
),
|
|
1026
|
+
/* @__PURE__ */ jsx("div", { className: "w-px h-5 bg-gray-200 mx-0.5" }),
|
|
1027
|
+
/* @__PURE__ */ jsx(
|
|
1028
|
+
"button",
|
|
1029
|
+
{
|
|
1030
|
+
onClick: reset,
|
|
1031
|
+
className: "p-1.5 rounded hover:bg-gray-100 text-gray-600",
|
|
1032
|
+
"aria-label": "Reset view",
|
|
1033
|
+
title: "Reset view",
|
|
1034
|
+
children: /* @__PURE__ */ jsx(ResetIcon, {})
|
|
1035
|
+
}
|
|
1036
|
+
)
|
|
1037
|
+
] })
|
|
1038
|
+
] });
|
|
1039
|
+
}
|
|
175
1040
|
function extractErrorMessage(err) {
|
|
176
1041
|
if (err instanceof Error) {
|
|
177
1042
|
const msg = err.message;
|
|
@@ -210,12 +1075,12 @@ function DiagramModal({
|
|
|
210
1075
|
children: /* @__PURE__ */ jsxs(
|
|
211
1076
|
"div",
|
|
212
1077
|
{
|
|
213
|
-
className: "bg-white rounded-lg shadow-xl w-
|
|
1078
|
+
className: "bg-white rounded-lg shadow-xl w-[96vw] h-[94vh] flex flex-col overflow-hidden",
|
|
214
1079
|
role: "dialog",
|
|
215
1080
|
"aria-modal": "true",
|
|
216
1081
|
onClick: (e) => e.stopPropagation(),
|
|
217
1082
|
children: [
|
|
218
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-4 border-b", children: [
|
|
1083
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-4 border-b shrink-0", children: [
|
|
219
1084
|
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: "Mermaid Diagram" }),
|
|
220
1085
|
/* @__PURE__ */ jsx(
|
|
221
1086
|
"button",
|
|
@@ -227,7 +1092,7 @@ function DiagramModal({
|
|
|
227
1092
|
}
|
|
228
1093
|
)
|
|
229
1094
|
] }),
|
|
230
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
1095
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden bg-gray-50", children })
|
|
231
1096
|
]
|
|
232
1097
|
}
|
|
233
1098
|
)
|
|
@@ -346,33 +1211,114 @@ var MermaidDiagramInner = ({ code }) => {
|
|
|
346
1211
|
]
|
|
347
1212
|
}
|
|
348
1213
|
),
|
|
349
|
-
/* @__PURE__ */ jsx(
|
|
350
|
-
DiagramModal,
|
|
351
|
-
{
|
|
352
|
-
isOpen: isModalOpen,
|
|
353
|
-
onClose: () => setIsModalOpen(false),
|
|
354
|
-
children: /* @__PURE__ */ jsx(
|
|
355
|
-
"div",
|
|
356
|
-
{
|
|
357
|
-
className: "flex justify-center items-center min-h-[50vh]",
|
|
358
|
-
dangerouslySetInnerHTML: { __html: svg }
|
|
359
|
-
}
|
|
360
|
-
)
|
|
361
|
-
}
|
|
362
|
-
)
|
|
1214
|
+
/* @__PURE__ */ jsx(DiagramModal, { isOpen: isModalOpen, onClose: () => setIsModalOpen(false), children: /* @__PURE__ */ jsx(ZoomableSvg, { svg }) })
|
|
363
1215
|
] });
|
|
364
1216
|
};
|
|
365
1217
|
var MermaidDiagram = memo(
|
|
366
1218
|
MermaidDiagramInner,
|
|
367
1219
|
(prevProps, nextProps) => prevProps.code === nextProps.code
|
|
368
1220
|
);
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
1221
|
+
|
|
1222
|
+
// src/vantageFrontmatter.ts
|
|
1223
|
+
var DOC_STATUSES = [
|
|
1224
|
+
"draft",
|
|
1225
|
+
"in-review",
|
|
1226
|
+
"accepted",
|
|
1227
|
+
"deprecated"
|
|
1228
|
+
];
|
|
1229
|
+
var VANTAGE_FRONTMATTER_KEYS = ["status-chip"];
|
|
1230
|
+
var DOC_STATUS_TONES = {
|
|
1231
|
+
draft: "muted",
|
|
1232
|
+
"in-review": "warning",
|
|
1233
|
+
accepted: "tip",
|
|
1234
|
+
deprecated: "caution"
|
|
1235
|
+
};
|
|
1236
|
+
var STATUS_CHIP_VALUES = [
|
|
1237
|
+
...DOC_STATUSES,
|
|
1238
|
+
"true",
|
|
1239
|
+
"false"
|
|
1240
|
+
];
|
|
1241
|
+
function isDocStatus(value) {
|
|
1242
|
+
return typeof value === "string" && DOC_STATUSES.includes(value);
|
|
1243
|
+
}
|
|
1244
|
+
function isTable(value) {
|
|
1245
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof Date);
|
|
1246
|
+
}
|
|
1247
|
+
function readVantageFrontmatter(frontmatter) {
|
|
1248
|
+
const issues = [];
|
|
1249
|
+
if (!Object.hasOwn(frontmatter, "vantage")) return { issues };
|
|
1250
|
+
const value = frontmatter["vantage"];
|
|
1251
|
+
if (!isTable(value)) {
|
|
1252
|
+
issues.push({ kind: "not-a-table", value });
|
|
1253
|
+
return { issues };
|
|
1254
|
+
}
|
|
1255
|
+
let statusChip;
|
|
1256
|
+
for (const key of Object.keys(value)) {
|
|
1257
|
+
if (!VANTAGE_FRONTMATTER_KEYS.includes(key)) {
|
|
1258
|
+
issues.push({ kind: "unknown-key", key });
|
|
1259
|
+
continue;
|
|
1260
|
+
}
|
|
1261
|
+
if (key === "status-chip") {
|
|
1262
|
+
statusChip = readStatusChip(frontmatter, value[key], issues);
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
return { ...statusChip === void 0 ? {} : { statusChip }, issues };
|
|
1266
|
+
}
|
|
1267
|
+
function readStatusChip(frontmatter, raw, issues) {
|
|
1268
|
+
const status = frontmatter["status"];
|
|
1269
|
+
if (raw === false) return void 0;
|
|
1270
|
+
if (raw === true) {
|
|
1271
|
+
if (isDocStatus(status)) return status;
|
|
1272
|
+
issues.push({ kind: "status-chip-orphan", status });
|
|
1273
|
+
return void 0;
|
|
1274
|
+
}
|
|
1275
|
+
if (isDocStatus(raw)) {
|
|
1276
|
+
if (isDocStatus(status) && status !== raw) {
|
|
1277
|
+
issues.push({ kind: "status-chip-disagrees", chip: raw, status });
|
|
1278
|
+
}
|
|
1279
|
+
return raw;
|
|
1280
|
+
}
|
|
1281
|
+
issues.push({
|
|
1282
|
+
kind: "bad-value",
|
|
1283
|
+
key: "status-chip",
|
|
1284
|
+
value: raw,
|
|
1285
|
+
legal: STATUS_CHIP_VALUES
|
|
1286
|
+
});
|
|
1287
|
+
return void 0;
|
|
1288
|
+
}
|
|
1289
|
+
var DocumentStatusChipInner = ({
|
|
1290
|
+
status
|
|
1291
|
+
}) => /* @__PURE__ */ jsx(
|
|
1292
|
+
"span",
|
|
1293
|
+
{
|
|
1294
|
+
className: `vantage-chip vantage-chip--${DOC_STATUS_TONES[status]}`,
|
|
1295
|
+
"data-vantage-status": status,
|
|
1296
|
+
title: `Document status: ${status}`,
|
|
1297
|
+
children: status
|
|
1298
|
+
}
|
|
1299
|
+
);
|
|
1300
|
+
var DocumentStatusChip = memo(DocumentStatusChipInner);
|
|
1301
|
+
var FileTextIcon = () => /* @__PURE__ */ jsxs(
|
|
1302
|
+
"svg",
|
|
1303
|
+
{
|
|
1304
|
+
width: "14",
|
|
1305
|
+
height: "14",
|
|
1306
|
+
viewBox: "0 0 24 24",
|
|
1307
|
+
fill: "none",
|
|
1308
|
+
stroke: "currentColor",
|
|
1309
|
+
strokeWidth: "2",
|
|
1310
|
+
strokeLinecap: "round",
|
|
1311
|
+
strokeLinejoin: "round",
|
|
1312
|
+
className: "text-slate-400",
|
|
1313
|
+
children: [
|
|
1314
|
+
/* @__PURE__ */ jsx("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
1315
|
+
/* @__PURE__ */ jsx("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" }),
|
|
1316
|
+
/* @__PURE__ */ jsx("path", { d: "M10 9H8" }),
|
|
1317
|
+
/* @__PURE__ */ jsx("path", { d: "M16 13H8" }),
|
|
1318
|
+
/* @__PURE__ */ jsx("path", { d: "M16 17H8" })
|
|
1319
|
+
]
|
|
1320
|
+
}
|
|
1321
|
+
);
|
|
376
1322
|
function isStringArray(value) {
|
|
377
1323
|
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
378
1324
|
}
|
|
@@ -416,6 +1362,7 @@ function ValueCell({ value }) {
|
|
|
416
1362
|
function flattenEntries(entries) {
|
|
417
1363
|
const result = [];
|
|
418
1364
|
for (const [key, value] of entries) {
|
|
1365
|
+
if (key === "vantage") continue;
|
|
419
1366
|
if (key === "taxonomies" && isPlainObject(value)) {
|
|
420
1367
|
for (const [taxKey, taxVal] of Object.entries(value)) {
|
|
421
1368
|
result.push([taxKey, taxVal]);
|
|
@@ -433,31 +1380,33 @@ function flattenEntries(entries) {
|
|
|
433
1380
|
var FrontmatterDisplayInner = ({
|
|
434
1381
|
frontmatter
|
|
435
1382
|
}) => {
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
return /* @__PURE__ */ jsxs(
|
|
440
|
-
/* @__PURE__ */
|
|
441
|
-
|
|
442
|
-
/* @__PURE__ */
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
{
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
1383
|
+
const entries = flattenEntries(Object.entries(frontmatter));
|
|
1384
|
+
const { statusChip } = readVantageFrontmatter(frontmatter);
|
|
1385
|
+
if (entries.length === 0 && statusChip === void 0) return null;
|
|
1386
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1387
|
+
statusChip !== void 0 && /* @__PURE__ */ jsx("div", { className: "vantage-chrome", children: /* @__PURE__ */ jsx(DocumentStatusChip, { status: statusChip }) }),
|
|
1388
|
+
entries.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-8 rounded-lg overflow-hidden bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-800 dark:to-slate-800/80 border border-slate-200 dark:border-slate-700 shadow-sm", children: [
|
|
1389
|
+
/* @__PURE__ */ jsxs("div", { className: "px-4 py-2.5 bg-white/60 dark:bg-slate-900/40 border-b border-slate-200 dark:border-slate-700 flex items-center gap-2", children: [
|
|
1390
|
+
/* @__PURE__ */ jsx(FileTextIcon, {}),
|
|
1391
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-slate-500 dark:text-slate-400 uppercase tracking-wider", children: "Metadata" })
|
|
1392
|
+
] }),
|
|
1393
|
+
/* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx("table", { className: "w-full text-sm", children: /* @__PURE__ */ jsx("tbody", { children: entries.map(([key, value]) => /* @__PURE__ */ jsxs(
|
|
1394
|
+
"tr",
|
|
1395
|
+
{
|
|
1396
|
+
className: "border-b border-slate-200/60 dark:border-slate-700/60 last:border-0",
|
|
1397
|
+
children: [
|
|
1398
|
+
/* @__PURE__ */ jsx("td", { className: "py-2 pr-4 font-medium text-slate-500 dark:text-slate-400 whitespace-nowrap align-top w-1/4 min-w-[100px]", children: key }),
|
|
1399
|
+
/* @__PURE__ */ jsx("td", { className: "py-2 text-slate-800 dark:text-slate-200 align-top", children: /* @__PURE__ */ jsx(ValueCell, { value }) })
|
|
1400
|
+
]
|
|
1401
|
+
},
|
|
1402
|
+
key
|
|
1403
|
+
)) }) }) })
|
|
1404
|
+
] })
|
|
455
1405
|
] });
|
|
456
1406
|
};
|
|
457
1407
|
var FrontmatterDisplay = memo(FrontmatterDisplayInner);
|
|
458
1408
|
|
|
459
|
-
// src/
|
|
460
|
-
var HIGHLIGHT_CLASS = "line-anchor-highlight";
|
|
1409
|
+
// src/lineAnchor.ts
|
|
461
1410
|
function parseLineAnchor(hash) {
|
|
462
1411
|
if (!hash) return null;
|
|
463
1412
|
const frag = hash.startsWith("#") ? hash.slice(1) : hash;
|
|
@@ -467,6 +1416,9 @@ function parseLineAnchor(hash) {
|
|
|
467
1416
|
const end = match[2] ? parseInt(match[2], 10) : start;
|
|
468
1417
|
return { start: Math.min(start, end), end: Math.max(start, end) };
|
|
469
1418
|
}
|
|
1419
|
+
|
|
1420
|
+
// src/scrollToLineAnchor.ts
|
|
1421
|
+
var HIGHLIGHT_CLASS = "line-anchor-highlight";
|
|
470
1422
|
function clearLineAnchorHighlights(container) {
|
|
471
1423
|
container.querySelectorAll(`.${HIGHLIGHT_CLASS}`).forEach((node) => {
|
|
472
1424
|
node.classList.remove(HIGHLIGHT_CLASS);
|
|
@@ -479,10 +1431,7 @@ function scrollToLineAnchor(container, hash) {
|
|
|
479
1431
|
const blocks = container.querySelectorAll("[data-source-line]");
|
|
480
1432
|
let firstMatch = null;
|
|
481
1433
|
for (const block of blocks) {
|
|
482
|
-
const line = parseInt(
|
|
483
|
-
block.dataset.sourceLine || "0",
|
|
484
|
-
10
|
|
485
|
-
);
|
|
1434
|
+
const line = parseInt(block.dataset.sourceLine || "0", 10);
|
|
486
1435
|
if (line >= range.start && line <= range.end) {
|
|
487
1436
|
block.classList.add(HIGHLIGHT_CLASS);
|
|
488
1437
|
if (!firstMatch) firstMatch = block;
|
|
@@ -629,9 +1578,13 @@ var MarkdownViewerInner = ({
|
|
|
629
1578
|
}) => {
|
|
630
1579
|
const containerRef = useRef(null);
|
|
631
1580
|
useLineAnchor(containerRef, hash);
|
|
632
|
-
const { frontmatter, body } = useMemo(() => {
|
|
1581
|
+
const { frontmatter, body, bodyLineOffset } = useMemo(() => {
|
|
633
1582
|
return parseFrontmatter(content);
|
|
634
1583
|
}, [content]);
|
|
1584
|
+
const { remarkPlugins, rehypePlugins } = useMemo(
|
|
1585
|
+
() => buildPipeline({ bodyLineOffset }),
|
|
1586
|
+
[bodyLineOffset]
|
|
1587
|
+
);
|
|
635
1588
|
const handleLinkClick = useCallback(
|
|
636
1589
|
(e, href) => {
|
|
637
1590
|
if (href.startsWith("#")) {
|
|
@@ -754,18 +1707,8 @@ var MarkdownViewerInner = ({
|
|
|
754
1707
|
/* @__PURE__ */ jsx(
|
|
755
1708
|
ReactMarkdown,
|
|
756
1709
|
{
|
|
757
|
-
remarkPlugins
|
|
758
|
-
|
|
759
|
-
[remarkMath, { singleDollarTextMath: false }]
|
|
760
|
-
],
|
|
761
|
-
rehypePlugins: [
|
|
762
|
-
rehypeRaw,
|
|
763
|
-
rehypeSourceLines_default,
|
|
764
|
-
[rehypeSanitize, sanitizeSchema],
|
|
765
|
-
rehypeSlug,
|
|
766
|
-
rehypeHighlight,
|
|
767
|
-
rehypeKatex
|
|
768
|
-
],
|
|
1710
|
+
remarkPlugins,
|
|
1711
|
+
rehypePlugins,
|
|
769
1712
|
urlTransform: transformImageUri,
|
|
770
1713
|
components: markdownComponents,
|
|
771
1714
|
children: body
|
|
@@ -792,27 +1735,22 @@ async function renderMarkdown(content, options = {}) {
|
|
|
792
1735
|
if (parseFm) {
|
|
793
1736
|
parsed = parseFrontmatter(content);
|
|
794
1737
|
} else {
|
|
795
|
-
parsed = {
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
}
|
|
811
|
-
processor = processor.use(remarkRehype, { allowDangerousHtml: true });
|
|
812
|
-
for (const [plugin, ...args] of rehypePlugins) {
|
|
813
|
-
processor = processor.use(plugin, ...args);
|
|
814
|
-
}
|
|
815
|
-
processor = processor.use(rehypeStringify);
|
|
1738
|
+
parsed = {
|
|
1739
|
+
frontmatter: {},
|
|
1740
|
+
body: content,
|
|
1741
|
+
format: "none",
|
|
1742
|
+
bodyLineOffset: 0
|
|
1743
|
+
};
|
|
1744
|
+
}
|
|
1745
|
+
const { remarkPlugins, rehypePlugins } = buildPipeline({
|
|
1746
|
+
gfm,
|
|
1747
|
+
math,
|
|
1748
|
+
highlight,
|
|
1749
|
+
sourceLines,
|
|
1750
|
+
sanitize,
|
|
1751
|
+
bodyLineOffset: parsed.bodyLineOffset
|
|
1752
|
+
});
|
|
1753
|
+
const processor = unified().use(remarkParse).use(remarkPlugins).use(remarkRehype, { allowDangerousHtml: true }).use(rehypePlugins).use(rehypeStringify);
|
|
816
1754
|
const result = await processor.process(parsed.body);
|
|
817
1755
|
return {
|
|
818
1756
|
html: String(result),
|
|
@@ -893,6 +1831,6 @@ function resolveLinks(html, options = {}) {
|
|
|
893
1831
|
);
|
|
894
1832
|
}
|
|
895
1833
|
|
|
896
|
-
export { FrontmatterDisplay, MarkdownViewer, MermaidDiagram, clearLineAnchorHighlights, parseFrontmatter, parseLineAnchor, rehypeSourceLines_default as rehypeSourceLines, renderMarkdown, renderMermaidBlocks, resolveLinks, sanitizeSchema, scrollToLineAnchor, useLineAnchor };
|
|
1834
|
+
export { DOC_STATUSES, DOC_STATUS_TONES, DocumentStatusChip, FrontmatterDisplay, MarkdownViewer, MermaidDiagram, VANTAGE_FRONTMATTER_KEYS, buildPipeline, buildRemarkPlugins, clearLineAnchorHighlights, isDocStatus, parseFrontmatter, parseLineAnchor, readVantageFrontmatter, rehypeSourceLines_default as rehypeSourceLines, renderMarkdown, renderMermaidBlocks, resolveLinks, sanitizeSchema, scrollToLineAnchor, useLineAnchor };
|
|
897
1835
|
//# sourceMappingURL=react.js.map
|
|
898
1836
|
//# sourceMappingURL=react.js.map
|