vde-open 0.1.4 → 0.1.6

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.
@@ -0,0 +1,1779 @@
1
+ import { D as escapeAttr, E as parseMarkdown, O as escapeHtml$2, k as footnoteReferenceId, n as renderedLinkOf, p as parseMarkdownDocument, r as MARKDOWN_PARSE_OPTIONS, t as localImagePath } from "./rendering-rules-DiE2jI7I.js";
2
+ //#region ../../node_modules/.pnpm/@tanstack+markdown@1.0.0_react@19.3.0/node_modules/@tanstack/markdown/dist/html.js
3
+ function renderHtml(input, options = {}) {
4
+ return (typeof input === "string" ? parseMarkdown(input, options) : input).children.map((node) => renderBlock(node, options)).join("\n");
5
+ }
6
+ function renderBlock(node, options = {}) {
7
+ const extension = renderExtension(node, options);
8
+ if (extension !== void 0) return extension;
9
+ switch (node.type) {
10
+ case "heading": {
11
+ const id = node.id ? ` id="${escapeAttr(node.id)}"` : "";
12
+ const framework = node.framework ? ` data-framework="${escapeAttr(node.framework)}"` : "";
13
+ return `<h${node.depth}${id}${framework}>${renderInlines(node.children, options)}${renderHeadingAnchor(node.id, options)}</h${node.depth}>`;
14
+ }
15
+ case "paragraph": return `<p>${renderInlines(node.children, options)}</p>`;
16
+ case "code": return renderCodeBlock(node, options);
17
+ case "list": {
18
+ const tag = node.ordered ? "ol" : "ul";
19
+ return `<${tag}${node.ordered && node.start !== void 0 && node.start !== 1 ? ` start="${node.start}"` : ""}>\n${node.items.map((item) => `<li>${renderListItemChildren(item.children, item.checked, node.loose, options)}</li>`).join("\n")}\n</${tag}>`;
20
+ }
21
+ case "blockquote": return `<blockquote>\n${node.children.map((child) => renderBlock(child, options)).join("\n")}\n</blockquote>`;
22
+ case "table": return `<table>${`<thead><tr>${node.header.map((cell, index) => renderTableCell("th", cell, node.align[index], options)).join("")}</tr></thead>`}${node.rows.length ? `<tbody>${node.rows.map((row) => `<tr>${row.map((cell, index) => renderTableCell("td", cell, node.align[index], options)).join("")}</tr>`).join("")}</tbody>` : ""}</table>`;
23
+ case "footnotes": return renderFootnotes(node.items, options);
24
+ case "thematicBreak": return "<hr>";
25
+ case "html": return options.allowHtml ? node.value : escapeHtml$2(node.value);
26
+ case "callout": return renderCallout(node, options);
27
+ case "component": return renderComponent(node, options);
28
+ }
29
+ }
30
+ function renderInline(node, options = {}) {
31
+ const extension = renderExtension(node, options);
32
+ if (extension !== void 0) return extension;
33
+ switch (node.type) {
34
+ case "text": return escapeHtml$2(node.value);
35
+ case "inlineCode": return `<code>${escapeHtml$2(node.value)}</code>`;
36
+ case "strong": return `<strong>${renderInlines(node.children, options)}</strong>`;
37
+ case "emphasis": return `<em>${renderInlines(node.children, options)}</em>`;
38
+ case "strike": return `<del>${renderInlines(node.children, options)}</del>`;
39
+ case "footnoteReference": return `<sup><a id="user-content-fnref-${escapeAttr(footnoteReferenceId(node.id, node.referenceIndex))}" data-footnote-ref="" aria-describedby="footnote-label" href="#user-content-fn-${escapeAttr(node.id)}">${node.number}</a></sup>`;
40
+ case "link": return `<a href="${escapeAttr(node.href)}"${node.title ? ` title="${escapeAttr(node.title)}"` : ""}>${renderInlines(node.children, options)}</a>`;
41
+ case "image": return `<img src="${escapeAttr(node.src)}" alt="${escapeAttr(node.alt)}"${node.title ? ` title="${escapeAttr(node.title)}"` : ""}>`;
42
+ case "break": return "<br>";
43
+ case "inlineHtml": return options.allowHtml ? node.value : escapeHtml$2(node.value);
44
+ case "inlineComponent": return renderComponent(node, options);
45
+ }
46
+ }
47
+ function renderDocument(document, options = {}) {
48
+ return renderHtml(document, options);
49
+ }
50
+ function renderInlines(nodes, options) {
51
+ return nodes.map((node) => renderInline(node, options)).join("");
52
+ }
53
+ function renderCodeBlock(node, options) {
54
+ const lang = node.lang ?? "plaintext";
55
+ const preAttrs = `class="tm-code${options.codeLineNumbers ? " tm-code--line-numbers" : ""}" data-lang="${escapeAttr(lang)}"` + (node.meta ? ` data-meta="${escapeAttr(node.meta)}"` : "") + (node.title ? ` data-code-title="${escapeAttr(node.title)}"` : "") + (node.file ? ` data-filename="${escapeAttr(node.file)}"` : "") + (node.framework ? ` data-framework="${escapeAttr(node.framework)}"` : "");
56
+ const html = options.highlighter?.(node.value, lang, {
57
+ ...node.meta && { meta: node.meta },
58
+ ...node.highlightLines && { highlightLines: node.highlightLines },
59
+ ...options.codeLineNumbers !== void 0 && { lineNumbers: options.codeLineNumbers }
60
+ }) ?? escapeHtml$2(node.value);
61
+ const pre = `<pre ${preAttrs}><code class="language-${escapeAttr(lang)}">${html}</code></pre>`;
62
+ if (!node.title) return pre;
63
+ return `<figure class="tm-code-frame" data-lang="${escapeAttr(lang)}"><figcaption>${escapeHtml$2(node.title)}</figcaption>${pre}</figure>`;
64
+ }
65
+ function renderListItemChildren(children, checked, loose, options) {
66
+ let result = checked === void 0 ? "" : `<input type="checkbox" disabled${checked ? " checked" : ""}> `;
67
+ for (let index = 0; index < children.length; index++) {
68
+ const child = children[index];
69
+ if (child.type === "paragraph" && (!loose || index === 0)) {
70
+ result += renderInlines(child.children, options);
71
+ if (loose) result = `<p>${result}</p>`;
72
+ } else result += (index ? "\n" : "") + renderBlock(child, options);
73
+ }
74
+ return result;
75
+ }
76
+ function renderCallout(node, options) {
77
+ const kind = node.kind.toLowerCase();
78
+ const children = node.children.map((child) => renderBlock(child, options)).join("\n");
79
+ return `<div class="markdown-alert markdown-alert-${escapeAttr(kind)}"><p class="markdown-alert-title">${escapeHtml$2(node.title)}</p><div class="markdown-alert-content">${children}</div></div>`;
80
+ }
81
+ function renderFootnotes(items, options) {
82
+ const renderedItems = items.map((item) => `<li id="user-content-fn-${escapeAttr(item.id)}">\n${renderFootnoteItem(item, options)}\n</li>`).join("\n");
83
+ return `<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes${renderHeadingAnchor("footnote-label", options)}</h2>\n<ol>\n${renderedItems}\n</ol>\n</section>`;
84
+ }
85
+ function renderFootnoteItem(item, options) {
86
+ const backref = renderFootnoteBackrefs(item);
87
+ const lastIndex = item.children.length - 1;
88
+ const result = item.children.map((child, index) => {
89
+ if (index === lastIndex && child.type === "paragraph") return `<p>${renderInlines(child.children, options)}${backref}</p>`;
90
+ return renderBlock(child, options);
91
+ });
92
+ if (item.children[lastIndex]?.type !== "paragraph") result.push(`<p>${backref.trimStart()}</p>`);
93
+ return result.join("\n");
94
+ }
95
+ function renderFootnoteBackrefs(item) {
96
+ let result = "";
97
+ for (let index = 1; index <= (item.referenceCount ?? 1); index++) {
98
+ const referenceId = footnoteReferenceId(item.id, index);
99
+ const label = index === 1 ? `${item.number}` : `${item.number}-${index}`;
100
+ result += ` <a data-footnote-backref="" aria-label="Back to reference ${label}" class="data-footnote-backref" href="#user-content-fnref-${escapeAttr(referenceId)}">&#8617;</a>`;
101
+ }
102
+ return result;
103
+ }
104
+ function renderComponent(node, options) {
105
+ const tag = node.tagName ?? (node.type === "inlineComponent" ? "span" : "md-comment-component");
106
+ return `<${tag}${renderComponentAttrs(node)}>${node.type === "inlineComponent" ? renderInlines(node.children, options) : node.children.map((child) => renderBlock(child, options)).join("\n")}</${tag}>`;
107
+ }
108
+ function renderTableCell(tag, cell, align, options) {
109
+ return `<${tag}${align ? ` style="text-align:${align}"` : ""}>${renderInlines(cell.children, options)}</${tag}>`;
110
+ }
111
+ function renderExtension(node, options) {
112
+ for (const extension of options.extensions ?? []) {
113
+ const rendered = extension.renderHtml?.(node, {
114
+ options,
115
+ renderBlock: (block) => renderBlock(block, options),
116
+ renderInline: (inline) => renderInline(inline, options)
117
+ });
118
+ if (rendered !== void 0) return rendered;
119
+ }
120
+ }
121
+ function renderHeadingAnchor(id, options) {
122
+ const headingAnchors = options.headingAnchors;
123
+ if (!id || !headingAnchors) return "";
124
+ const anchorOptions = typeof headingAnchors === "object" ? headingAnchors : {};
125
+ return `<a href="#${escapeAttr(id)}" aria-hidden="${anchorOptions.ariaHidden ?? true}" class="${escapeAttr(anchorOptions.className ?? "anchor-heading anchor-heading-link")}" tabindex="${anchorOptions.tabIndex ?? -1}">${escapeHtml$2(anchorOptions.content ?? "#")}</a>`;
126
+ }
127
+ function renderComponentAttrs(node) {
128
+ const props = { ...node.properties };
129
+ if (!node.tagName) {
130
+ props["data-component"] = node.name;
131
+ if (!props["data-attributes"]) props["data-attributes"] = JSON.stringify(node.attributes);
132
+ }
133
+ return Object.entries(props).map(([key, value]) => ` ${key}="${escapeAttr(value)}"`).join("");
134
+ }
135
+ //#endregion
136
+ //#region ../../node_modules/.pnpm/@tanstack+highlight@1.0.0/node_modules/@tanstack/highlight/dist/core.js
137
+ function defineLanguage(definition) {
138
+ return definition;
139
+ }
140
+ function createHighlighter({ fallbackLanguage = "plaintext", languages }) {
141
+ const definitions = /* @__PURE__ */ new Map();
142
+ const aliases = /* @__PURE__ */ new Map();
143
+ for (const definition of languages) {
144
+ const name = normalizeName(definition.name);
145
+ definitions.set(name, definition);
146
+ aliases.set(name, name);
147
+ for (const alias of definition.aliases || []) aliases.set(normalizeName(alias), name);
148
+ }
149
+ const fallback = normalizeName(fallbackLanguage);
150
+ function normalizeLanguage(lang) {
151
+ return aliases.get(normalizeName(lang || fallback)) || fallback;
152
+ }
153
+ function tokenizeRanges(code, lang, depth = 0) {
154
+ const definition = definitions.get(normalizeLanguage(lang));
155
+ if (!definition || depth > 24) return [];
156
+ return normalizeTokenRanges(code.length, definition.tokenize(code, {
157
+ hasLanguage(candidate) {
158
+ const resolved = aliases.get(normalizeName(candidate));
159
+ return Boolean(resolved && definitions.has(resolved));
160
+ },
161
+ tokenize(embeddedCode, embeddedLanguage) {
162
+ return tokenizeRanges(embeddedCode, embeddedLanguage, depth + 1);
163
+ }
164
+ }));
165
+ }
166
+ function tokenize(code, options = {}) {
167
+ const lang = normalizeLanguage(options.lang);
168
+ const ranges = tokenizeRanges(code, lang);
169
+ return {
170
+ code,
171
+ lang,
172
+ tokens: ranges.length ? rangesToTokens(code, ranges) : [{ value: code }]
173
+ };
174
+ }
175
+ function highlight(code, options = {}) {
176
+ const result = tokenize(code, options);
177
+ const innerHtml = renderNodesToHtml(renderTokens(result.tokens, options));
178
+ return {
179
+ ...result,
180
+ html: `<pre class="th-code th-code--${escapeHtml$1(result.lang)}${options.lineNumbers ? " th-code--line-numbers" : ""}" data-language="${escapeHtml$1(result.lang)}"><code>${innerHtml}</code></pre>`
181
+ };
182
+ }
183
+ function renderCodeBlockData({ code, decorations, lang, lineNumbers, title }) {
184
+ const copyText = code.trimEnd();
185
+ const result = highlight(copyText, {
186
+ decorations,
187
+ lang,
188
+ lineNumbers
189
+ });
190
+ return {
191
+ copyText,
192
+ htmlMarkup: result.html,
193
+ lang: result.lang,
194
+ title,
195
+ tokens: result.tokens
196
+ };
197
+ }
198
+ return {
199
+ highlight,
200
+ highlightToHtml(code, options = {}) {
201
+ return highlight(code, options).html;
202
+ },
203
+ listLanguages() {
204
+ return [...definitions.keys()];
205
+ },
206
+ normalizeLanguage,
207
+ renderCodeBlockData,
208
+ tokenize
209
+ };
210
+ }
211
+ function renderTokens(tokens, options = {}) {
212
+ const rangeDecorations = [];
213
+ const lineDecorations = [];
214
+ for (const decoration of options.decorations || []) if (decoration.range) rangeDecorations.push(decoration);
215
+ else lineDecorations.push(decoration);
216
+ const wrapLines = Boolean(options.lineNumbers || lineDecorations.length);
217
+ const cursor = {
218
+ index: 0,
219
+ offset: 0
220
+ };
221
+ if (!wrapLines) return renderTokenSlice(tokens, 0, Infinity, rangeDecorations, cursor);
222
+ const code = tokens.map((token) => token.value).join("");
223
+ const nodes = [];
224
+ const lineStarts = getLineStarts(code);
225
+ for (let index = 0; index < lineStarts.length; index++) {
226
+ const line = index + 1;
227
+ const start = lineStarts[index];
228
+ const nextStart = lineStarts[index + 1] ?? code.length;
229
+ const hasNewline = nextStart > start && code[nextStart - 1] === "\n";
230
+ const end = hasNewline ? nextStart - 1 : nextStart;
231
+ const active = lineDecorations.filter((decoration) => includesLine(decoration.lines, line));
232
+ nodes.push({
233
+ type: "element",
234
+ classNames: ["th-line", ...active.flatMap((decoration) => splitClassNames(decoration.className))],
235
+ data: {
236
+ ...mergeData(active),
237
+ line: String(line)
238
+ },
239
+ children: renderTokenSlice(tokens, start, end, rangeDecorations, cursor)
240
+ });
241
+ if (hasNewline) nodes.push({
242
+ type: "text",
243
+ value: "\n"
244
+ });
245
+ }
246
+ return nodes;
247
+ }
248
+ function renderNodesToHtml(nodes) {
249
+ let html = "";
250
+ for (const node of nodes) {
251
+ if (node.type === "text") {
252
+ html += escapeHtml$1(node.value);
253
+ continue;
254
+ }
255
+ const className = escapeHtml$1(node.classNames.join(" "));
256
+ let data = "";
257
+ if (node.data) for (const [key, value] of Object.entries(node.data)) data += ` data-${normalizeDataKey(key)}="${escapeHtml$1(value)}"`;
258
+ html += `<span${className ? ` class="${className}"` : ""}${data}>${renderNodesToHtml(node.children)}</span>`;
259
+ }
260
+ return html;
261
+ }
262
+ const htmlEscapes = {
263
+ "&": "&amp;",
264
+ "<": "&lt;",
265
+ ">": "&gt;",
266
+ "\"": "&quot;",
267
+ "'": "&#39;"
268
+ };
269
+ function escapeHtml$1(value) {
270
+ return value.replace(/[&<>"']/g, (character) => htmlEscapes[character]);
271
+ }
272
+ function normalizeName(value) {
273
+ return value.trim().toLowerCase();
274
+ }
275
+ function normalizeTokenRanges(codeLength, input) {
276
+ const ranges = [];
277
+ let sorted = true;
278
+ let previousStart = 0;
279
+ for (const candidate of input) {
280
+ if (!Number.isInteger(candidate.start) || !Number.isInteger(candidate.end)) continue;
281
+ const start = Math.max(0, Math.min(codeLength, candidate.start));
282
+ const end = Math.max(0, Math.min(codeLength, candidate.end));
283
+ if (start >= end) continue;
284
+ if (start < previousStart) sorted = false;
285
+ previousStart = start;
286
+ ranges.push({
287
+ className: candidate.className,
288
+ start,
289
+ end
290
+ });
291
+ }
292
+ if (!sorted) ranges.sort((a, b) => a.start - b.start);
293
+ let end = 0;
294
+ let count = 0;
295
+ for (const candidate of ranges) {
296
+ if (candidate.start < end) continue;
297
+ ranges[count++] = candidate;
298
+ end = candidate.end;
299
+ }
300
+ ranges.length = count;
301
+ return ranges;
302
+ }
303
+ function rangesToTokens(code, ranges) {
304
+ const tokens = [];
305
+ let index = 0;
306
+ for (const range of ranges) {
307
+ if (range.start > index) tokens.push({ value: code.slice(index, range.start) });
308
+ tokens.push({
309
+ className: range.className,
310
+ value: code.slice(range.start, range.end)
311
+ });
312
+ index = range.end;
313
+ }
314
+ if (index < code.length) tokens.push({ value: code.slice(index) });
315
+ return tokens;
316
+ }
317
+ function renderTokenSlice(tokens, start, end, decorations, cursor) {
318
+ const nodes = [];
319
+ for (; cursor.index < tokens.length; cursor.index++) {
320
+ const token = tokens[cursor.index];
321
+ const tokenStart = cursor.offset;
322
+ const tokenEnd = tokenStart + token.value.length;
323
+ const sliceStart = Math.max(start, tokenStart);
324
+ const sliceEnd = Math.min(end, tokenEnd);
325
+ if (sliceStart < sliceEnd) {
326
+ let sorted = [sliceStart, sliceEnd];
327
+ if (decorations.length) {
328
+ const boundaries = new Set(sorted);
329
+ for (const decoration of decorations) {
330
+ const [decorationStart, decorationEnd] = decoration.range;
331
+ if (decorationEnd <= sliceStart || decorationStart >= sliceEnd) continue;
332
+ boundaries.add(Math.max(sliceStart, decorationStart));
333
+ boundaries.add(Math.min(sliceEnd, decorationEnd));
334
+ }
335
+ sorted = [...boundaries].sort((a, b) => a - b);
336
+ }
337
+ for (let index = 0; index < sorted.length - 1; index++) {
338
+ const segmentStart = sorted[index];
339
+ const segmentEnd = sorted[index + 1];
340
+ let node = {
341
+ type: "text",
342
+ value: token.value.slice(segmentStart - tokenStart, segmentEnd - tokenStart)
343
+ };
344
+ if (token.className) node = {
345
+ type: "element",
346
+ classNames: ["th-token", `th-${token.className}`],
347
+ children: [node]
348
+ };
349
+ for (const decoration of decorations) {
350
+ if (decoration.range[0] > segmentStart || decoration.range[1] < segmentEnd) continue;
351
+ node = {
352
+ type: "element",
353
+ classNames: ["th-decoration", ...splitClassNames(decoration.className)],
354
+ data: stringifyData(decoration.data),
355
+ children: [node]
356
+ };
357
+ }
358
+ nodes.push(node);
359
+ }
360
+ }
361
+ if (tokenEnd > end) break;
362
+ cursor.offset = tokenEnd;
363
+ }
364
+ return nodes;
365
+ }
366
+ function getLineStarts(code) {
367
+ const starts = [0];
368
+ for (let index = 0; index < code.length; index++) if (code[index] === "\n" && index + 1 < code.length) starts.push(index + 1);
369
+ return starts;
370
+ }
371
+ function includesLine(lines, line) {
372
+ return typeof lines === "number" ? lines === line : line >= lines[0] && line <= lines[1];
373
+ }
374
+ function mergeData(decorations) {
375
+ const data = {};
376
+ for (const decoration of decorations) Object.assign(data, stringifyData(decoration.data));
377
+ return data;
378
+ }
379
+ function stringifyData(data) {
380
+ if (!data) return void 0;
381
+ return Object.fromEntries(Object.entries(data).map(([key, value]) => [normalizeDataKey(key), String(value)]));
382
+ }
383
+ function normalizeDataKey(value) {
384
+ return toKebabCase(value).replace(/[^a-z0-9_.:-]/gi, "-");
385
+ }
386
+ function splitClassNames(className) {
387
+ return className?.trim().split(/\s+/).filter(Boolean) || [];
388
+ }
389
+ function toKebabCase(value) {
390
+ return value.replace(/[A-Z]/g, (character) => `-${character.toLowerCase()}`);
391
+ }
392
+ //#endregion
393
+ //#region ../../node_modules/.pnpm/@tanstack+highlight@1.0.0/node_modules/@tanstack/highlight/dist/internal/patterns.js
394
+ function patternTokenizer(patterns) {
395
+ return (code) => collectPatternRanges(code, patterns);
396
+ }
397
+ function collectPatternRanges(code, patterns, initial = [], occupied = new Uint8Array(code.length)) {
398
+ const ranges = [...initial];
399
+ for (const range of initial) occupied.fill(1, range.start, range.end);
400
+ for (const pattern of patterns) {
401
+ if ("collect" in pattern) {
402
+ for (const range of pattern.collect(code)) addRange(ranges, occupied, range);
403
+ continue;
404
+ }
405
+ const regex = cloneRegex(pattern.regex);
406
+ let match;
407
+ while (match = regex.exec(code)) {
408
+ const value = pattern.group ? match[pattern.group] : match[0];
409
+ if (!value) {
410
+ if (!match[0].length) regex.lastIndex++;
411
+ continue;
412
+ }
413
+ const offset = pattern.group ? match[0].length - value.length : 0;
414
+ const start = match.index + offset;
415
+ addRange(ranges, occupied, {
416
+ start,
417
+ end: start + value.length,
418
+ className: typeof pattern.className === "function" ? pattern.className(match) : pattern.className
419
+ });
420
+ }
421
+ }
422
+ return ranges;
423
+ }
424
+ function offsetRanges(ranges, offset) {
425
+ return ranges.map((range) => ({
426
+ ...range,
427
+ start: range.start + offset,
428
+ end: range.end + offset
429
+ }));
430
+ }
431
+ function addRange(ranges, occupied, range) {
432
+ if (range.start >= range.end || range.start < 0 || range.end > occupied.length || hasOverlap(occupied, range.start, range.end)) return false;
433
+ ranges.push(range);
434
+ occupied.fill(1, range.start, range.end);
435
+ return true;
436
+ }
437
+ function cloneRegex(regex) {
438
+ return new RegExp(regex.source, regex.global ? regex.flags : `${regex.flags}g`);
439
+ }
440
+ function hasOverlap(occupied, start, end) {
441
+ for (let index = start; index < end; index++) if (occupied[index]) return true;
442
+ return false;
443
+ }
444
+ //#endregion
445
+ //#region ../../node_modules/.pnpm/@tanstack+highlight@1.0.0/node_modules/@tanstack/highlight/dist/languages/css.js
446
+ const css = defineLanguage({
447
+ name: "css",
448
+ tokenize: patternTokenizer([
449
+ {
450
+ className: (match) => match[0].startsWith("/*") ? "comment" : "string",
451
+ regex: /\/\*[\s\S]*?\*\/|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/g
452
+ },
453
+ {
454
+ className: "variable",
455
+ regex: /--[A-Za-z0-9_-]+/g
456
+ },
457
+ {
458
+ className: "selector",
459
+ regex: /(^|[}\n])\s*([^@{}\n][^{}\n]*)(?=\s*\{)/g,
460
+ group: 2
461
+ },
462
+ {
463
+ className: "property",
464
+ regex: /(?:^|[;{]\s*)([A-Za-z-]+)(?=\s*:)/gm,
465
+ group: 1
466
+ },
467
+ {
468
+ className: "function",
469
+ regex: /\b[A-Za-z-]+(?=\()/g
470
+ },
471
+ {
472
+ className: "number",
473
+ regex: /\b\d+(?:\.\d+)?(?:px|rem|em|%|s|ms|vh|vw|deg)?\b/g
474
+ }
475
+ ])
476
+ });
477
+ //#endregion
478
+ //#region ../../node_modules/.pnpm/@tanstack+highlight@1.0.0/node_modules/@tanstack/highlight/dist/internal/markup.js
479
+ const rawTextClosing = {
480
+ script: /<\/script(?=[\s/>])/gi,
481
+ style: /<\/style(?=[\s/>])/gi
482
+ };
483
+ function collectMarkupRanges(code, context, mode = "html") {
484
+ const ranges = [];
485
+ const regions = [];
486
+ let index = 0;
487
+ while ((index = code.indexOf("<", index)) >= 0) {
488
+ if (code.startsWith("<!--", index)) {
489
+ const close = code.indexOf("-->", index + 4);
490
+ const end = close < 0 ? code.length : close + 3;
491
+ ranges.push({
492
+ start: index,
493
+ end,
494
+ className: "comment"
495
+ });
496
+ index = end;
497
+ continue;
498
+ }
499
+ if (mode === "ejs" && code.startsWith("<%", index)) {
500
+ const close = code.indexOf("%>", index + 2);
501
+ const end = close < 0 ? code.length : close;
502
+ regions.push({
503
+ start: index + 2,
504
+ end,
505
+ lang: "js"
506
+ });
507
+ index = close < 0 ? code.length : close + 2;
508
+ continue;
509
+ }
510
+ const closing = code[index + 1] === "/";
511
+ const nameStart = index + (closing ? 2 : 1);
512
+ const nameMatch = /^[A-Za-z][\w:.-]*/.exec(code.slice(nameStart));
513
+ if (!nameMatch) {
514
+ index++;
515
+ continue;
516
+ }
517
+ const tagEnd = findTagEnd(code, nameStart + nameMatch[0].length);
518
+ if (tagEnd < 0) {
519
+ index++;
520
+ continue;
521
+ }
522
+ const tagName = nameMatch[0].toLowerCase();
523
+ ranges.push({
524
+ start: nameStart,
525
+ end: nameStart + nameMatch[0].length,
526
+ className: "tag"
527
+ });
528
+ if (!closing) collectAttributes(code, nameStart + nameMatch[0].length, tagEnd, ranges);
529
+ if (!closing && (tagName === "script" || tagName === "style")) {
530
+ const rawTextClose = rawTextClosing[tagName];
531
+ rawTextClose.lastIndex = tagEnd + 1;
532
+ const contentEnd = rawTextClose.exec(code)?.index ?? code.length;
533
+ const lang = getEmbeddedLanguage(tagName, code.slice(index, tagEnd + 1));
534
+ regions.push({
535
+ start: tagEnd + 1,
536
+ end: contentEnd,
537
+ lang
538
+ });
539
+ index = contentEnd;
540
+ continue;
541
+ }
542
+ index = tagEnd + 1;
543
+ }
544
+ if (mode === "vue") collectDelimitedRegions(code, "{{", "}}", "js", regions);
545
+ if (mode === "svelte") collectBraceRegions(code, regions);
546
+ for (const region of regions) {
547
+ if (region.start >= region.end || !context.hasLanguage(region.lang)) continue;
548
+ ranges.push(...offsetRanges(context.tokenize(code.slice(region.start, region.end), region.lang), region.start));
549
+ }
550
+ return ranges;
551
+ }
552
+ function collectAttributes(code, start, end, ranges) {
553
+ const source = code.slice(start, end);
554
+ const attributes = /\s([:@A-Za-z_][\w:.-]*)(?=\s*(?:=|\/?>))/g;
555
+ let match;
556
+ while (match = attributes.exec(source)) {
557
+ const offset = match[0].indexOf(match[1]);
558
+ const attributeStart = start + match.index + offset;
559
+ ranges.push({
560
+ start: attributeStart,
561
+ end: attributeStart + match[1].length,
562
+ className: "attr"
563
+ });
564
+ }
565
+ let index = start;
566
+ while (index < end) {
567
+ const quote = code[index];
568
+ if (quote !== "\"" && quote !== "'") {
569
+ index++;
570
+ continue;
571
+ }
572
+ const close = findQuoteEnd(code, index, quote, end);
573
+ ranges.push({
574
+ start: index,
575
+ end: close,
576
+ className: "string"
577
+ });
578
+ index = close;
579
+ }
580
+ }
581
+ function getEmbeddedLanguage(tag, openingTag) {
582
+ if (tag === "style") return "css";
583
+ const lang = /\blang\s*=\s*["']?([\w-]+)/i.exec(openingTag)?.[1];
584
+ return lang === "ts" || lang === "typescript" ? "ts" : "js";
585
+ }
586
+ function collectDelimitedRegions(code, open, close, lang, regions) {
587
+ let index = 0;
588
+ while ((index = code.indexOf(open, index)) >= 0) {
589
+ const end = code.indexOf(close, index + open.length);
590
+ if (end < 0) return;
591
+ regions.push({
592
+ start: index + open.length,
593
+ end,
594
+ lang
595
+ });
596
+ index = end + close.length;
597
+ }
598
+ }
599
+ function collectBraceRegions(code, regions) {
600
+ let index = 0;
601
+ while (index < code.length) {
602
+ if (code[index] !== "{" || code[index + 1] === "#") {
603
+ index++;
604
+ continue;
605
+ }
606
+ const end = code.indexOf("}", index + 1);
607
+ if (end < 0) return;
608
+ regions.push({
609
+ start: index + 1,
610
+ end,
611
+ lang: "js"
612
+ });
613
+ index = end + 1;
614
+ }
615
+ }
616
+ function findTagEnd(code, start) {
617
+ let index = start;
618
+ while (index < code.length) if (code[index] === "\"" || code[index] === "'") index = findQuoteEnd(code, index, code[index], code.length);
619
+ else if (code[index] === ">") return index;
620
+ else index++;
621
+ return -1;
622
+ }
623
+ function findQuoteEnd(code, start, quote, limit) {
624
+ let index = start + 1;
625
+ while (index < limit) if (code[index] === "\\") index += 2;
626
+ else if (code[index] === quote) return index + 1;
627
+ else index++;
628
+ return limit;
629
+ }
630
+ //#endregion
631
+ //#region ../../node_modules/.pnpm/@tanstack+highlight@1.0.0/node_modules/@tanstack/highlight/dist/languages/html.js
632
+ const html = defineLanguage({
633
+ name: "html",
634
+ aliases: [
635
+ "htm",
636
+ "xml",
637
+ "angular-html"
638
+ ],
639
+ tokenize: (code, context) => collectMarkupRanges(code, context)
640
+ });
641
+ //#endregion
642
+ //#region ../../node_modules/.pnpm/@tanstack+highlight@1.0.0/node_modules/@tanstack/highlight/dist/internal/script.js
643
+ const semanticPatterns = [
644
+ {
645
+ className: "property",
646
+ regex: /(?<!\.)\.([A-Za-z_$][\w$]*)/g,
647
+ group: 1
648
+ },
649
+ {
650
+ className: "function",
651
+ regex: /@[A-Za-z_$][\w$]*/g
652
+ },
653
+ {
654
+ className: "keyword",
655
+ regex: new RegExp(`\\b(?:abstract|as|asserts|async|await|break|case|catch|class|const|continue|debugger|declare|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|infer|instanceof|interface|is|keyof|let|module|namespace|new|of|override|package|private|protected|public|readonly|return|satisfies|set|static|super|switch|this|throw|try|type|typeof|using|var|while|with|yield)\\b`, "g")
656
+ },
657
+ {
658
+ className: "literal",
659
+ regex: /\b(?:false|null|true|undefined|NaN|Infinity)\b/g
660
+ },
661
+ {
662
+ className: "number",
663
+ regex: /\b(?:0x[\da-f](?:_?[\da-f])*n?|0b[01](?:_?[01])*n?|0o[0-7](?:_?[0-7])*n?|\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:e[+-]?\d(?:_?\d)*)?n?)\b/gi
664
+ },
665
+ {
666
+ className: "function",
667
+ regex: /\bfunction\s*\*?\s*([A-Za-z_$][\w$]*)/g,
668
+ group: 1
669
+ },
670
+ {
671
+ className: "function",
672
+ regex: /(^|[^.A-Za-z0-9_$])([A-Za-z_$][\w$]*)(?=\s*\()/g,
673
+ group: 2
674
+ },
675
+ {
676
+ className: "type",
677
+ regex: /\b(?:Array|Record|Promise|Readonly|Set|Map|WeakMap|WeakSet|string|number|boolean|bigint|symbol|object|unknown|never|void|any|[A-Z][A-Za-z0-9_$]*)\b/g
678
+ }
679
+ ];
680
+ function collectScriptRanges(code, jsx = false, jsxAtLineStart = false) {
681
+ const jsxText = jsx ? new Uint8Array(code.length) : void 0;
682
+ const initial = [];
683
+ collectScriptInitialRanges(code, jsx, jsxAtLineStart, jsxText, initial);
684
+ return collectPatternRanges(code, semanticPatterns, initial, jsxText);
685
+ }
686
+ function collectScriptInitialRanges(code, jsx, jsxAtLineStart, jsxText, ranges, index = 0, limit = code.length, tagBody = false) {
687
+ const objectBraces = [];
688
+ const expressions = [];
689
+ let jsxDepth = 0;
690
+ while (index < limit) {
691
+ const expression = expressions.at(-1);
692
+ const inJsxText = jsxDepth > (expression || 0);
693
+ const character = code[index];
694
+ const next = code[index + 1];
695
+ if (inJsxText) {
696
+ if (character === "{") {
697
+ expressions.push(jsxDepth);
698
+ index++;
699
+ continue;
700
+ }
701
+ if (character !== "<") {
702
+ const start = index;
703
+ while (index < code.length && code[index] !== "<" && code[index] !== "{") index++;
704
+ jsxText.fill(1, start, index);
705
+ continue;
706
+ }
707
+ }
708
+ if (tagBody && !expressions.length && !jsxDepth && character === ">") return index;
709
+ if (character === "/" && next === "/") {
710
+ const end = findLineEnd(code, index + 2);
711
+ ranges.push({
712
+ start: index,
713
+ end,
714
+ className: "comment"
715
+ });
716
+ index = end;
717
+ continue;
718
+ }
719
+ if (character === "/" && next === "*") {
720
+ const close = code.indexOf("*/", index + 2);
721
+ const end = close < 0 ? code.length : close + 2;
722
+ ranges.push({
723
+ start: index,
724
+ end,
725
+ className: "comment"
726
+ });
727
+ index = end;
728
+ continue;
729
+ }
730
+ if (character === "'" || character === "\"") {
731
+ const end = findQuotedEnd(code, index, character, tagBody && !expressions.length);
732
+ ranges.push({
733
+ start: index,
734
+ end,
735
+ className: "string"
736
+ });
737
+ index = end;
738
+ continue;
739
+ }
740
+ if (character === "`") {
741
+ index = collectTemplateRanges(code, index, ranges, jsx, jsxAtLineStart);
742
+ continue;
743
+ }
744
+ if (character === "/" && !(jsx && code[index - 1] === "<") && isRegexStart(code, index)) {
745
+ const end = findRegexEnd(code, index);
746
+ if (end > index + 1) {
747
+ ranges.push({
748
+ start: index,
749
+ end,
750
+ className: "literal"
751
+ });
752
+ index = end;
753
+ continue;
754
+ }
755
+ }
756
+ if (character === "{") {
757
+ const before = previousCodeIndex(code, index, ranges);
758
+ let wordStart = before;
759
+ while (wordStart >= 0 && /[\w$]/.test(code[wordStart])) wordStart--;
760
+ const word = code.slice(wordStart + 1, before + 1);
761
+ objectBraces.push("=(:,[".includes(code[before] || "\0") || /^(?:return|yield|const|let|var)$/.test(word));
762
+ } else if (character === "}") objectBraces.pop();
763
+ else if (objectBraces.at(-1) && /[A-Za-z_$]/.test(character)) {
764
+ const before = previousCodeIndex(code, index, ranges);
765
+ if ("{,;".includes(code[before] || "\0")) {
766
+ let end = index + 1;
767
+ while (end < limit && /[\w$]/.test(code[end])) end++;
768
+ if (code[end + (code.slice(end).match(/^(?:\s|\/\*[\s\S]*?\*\/|\/\/[^\n]*(?:\n|$))*/)?.[0].length || 0)] === ":") {
769
+ ranges.push({
770
+ start: index,
771
+ end,
772
+ className: "property"
773
+ });
774
+ index = end;
775
+ continue;
776
+ }
777
+ }
778
+ }
779
+ if (!jsx) {
780
+ index++;
781
+ continue;
782
+ }
783
+ if (!inJsxText && character === "{" && (expressions.length || tagBody)) {
784
+ expressions.push(expressions.length ? expression : jsxDepth);
785
+ index++;
786
+ continue;
787
+ }
788
+ if (!inJsxText && expressions.length && character === "}") {
789
+ expressions.pop();
790
+ index++;
791
+ continue;
792
+ }
793
+ if (character !== "<") {
794
+ index++;
795
+ continue;
796
+ }
797
+ if (code.startsWith("</>", index)) {
798
+ jsxDepth--;
799
+ index += 3;
800
+ continue;
801
+ }
802
+ if (code.startsWith("<>", index) && (inJsxText || isJsxStart(code, index, jsxAtLineStart))) {
803
+ jsxDepth++;
804
+ index += 2;
805
+ continue;
806
+ }
807
+ const closing = code[index + 1] === "/";
808
+ const nameStart = index + (closing ? 2 : 1);
809
+ const nameMatch = /^[A-Za-z][\w:.-]*/.exec(code.slice(nameStart));
810
+ if (!nameMatch || !closing && !inJsxText && !isJsxStart(code, index, jsxAtLineStart)) {
811
+ index++;
812
+ continue;
813
+ }
814
+ const end = collectScriptInitialRanges(code, true, jsxAtLineStart, jsxText, ranges, nameStart + nameMatch[0].length, limit, true);
815
+ if (end < 0 || isTypeParameter(code, index, end, closing)) {
816
+ index++;
817
+ continue;
818
+ }
819
+ ranges.push({
820
+ start: nameStart,
821
+ end: nameStart + nameMatch[0].length,
822
+ className: "tag"
823
+ });
824
+ if (!closing) collectJsxAttributes(code, nameStart + nameMatch[0].length, end, ranges);
825
+ const selfClosing = /\/\s*$/.test(code.slice(nameStart, end));
826
+ if (closing) jsxDepth--;
827
+ else if (!selfClosing) jsxDepth++;
828
+ index = end + 1;
829
+ }
830
+ return -1;
831
+ }
832
+ function collectTemplateRanges(code, start, ranges, jsx, jsxAtLineStart) {
833
+ let segmentStart = start;
834
+ let index = start + 1;
835
+ while (index < code.length) {
836
+ if (code[index] === "\\") {
837
+ index += 2;
838
+ continue;
839
+ }
840
+ if (code[index] === "`") {
841
+ ranges.push({
842
+ start: segmentStart,
843
+ end: index + 1,
844
+ className: "string"
845
+ });
846
+ return index + 1;
847
+ }
848
+ if (code[index] === "$" && code[index + 1] === "{") {
849
+ if (segmentStart < index) ranges.push({
850
+ start: segmentStart,
851
+ end: index,
852
+ className: "string"
853
+ });
854
+ ranges.push({
855
+ start: index,
856
+ end: index + 2,
857
+ className: "operator"
858
+ });
859
+ const end = findInterpolationEnd(code, index + 2);
860
+ const expressionEnd = end < 0 ? code.length : end;
861
+ const expression = code.slice(index + 2, expressionEnd);
862
+ ranges.push(...offsetRanges(collectScriptRanges(expression, jsx, jsxAtLineStart), index + 2));
863
+ if (end < 0) return code.length;
864
+ ranges.push({
865
+ start: end,
866
+ end: end + 1,
867
+ className: "operator"
868
+ });
869
+ index = end + 1;
870
+ segmentStart = index;
871
+ continue;
872
+ }
873
+ index++;
874
+ }
875
+ if (segmentStart < code.length) ranges.push({
876
+ start: segmentStart,
877
+ end: code.length,
878
+ className: "string"
879
+ });
880
+ return code.length;
881
+ }
882
+ function findInterpolationEnd(code, start) {
883
+ let depth = 1;
884
+ let index = start;
885
+ while (index < code.length) {
886
+ const character = code[index];
887
+ const next = code[index + 1];
888
+ if (character === "'" || character === "\"") {
889
+ index = findQuotedEnd(code, index, character);
890
+ continue;
891
+ }
892
+ if (character === "`") {
893
+ index = skipTemplate(code, index);
894
+ continue;
895
+ }
896
+ if (character === "/" && next === "/") {
897
+ index = findLineEnd(code, index + 2);
898
+ continue;
899
+ }
900
+ if (character === "/" && next === "*") {
901
+ const close = code.indexOf("*/", index + 2);
902
+ index = close < 0 ? code.length : close + 2;
903
+ continue;
904
+ }
905
+ if (character === "/" && isRegexStart(code, index)) {
906
+ index = findRegexEnd(code, index);
907
+ continue;
908
+ }
909
+ if (character === "{") depth++;
910
+ if (character === "}" && --depth === 0) return index;
911
+ index++;
912
+ }
913
+ return -1;
914
+ }
915
+ function skipTemplate(code, start) {
916
+ let index = start + 1;
917
+ while (index < code.length) if (code[index] === "\\") index += 2;
918
+ else if (code[index] === "`") return index + 1;
919
+ else if (code[index] === "$" && code[index + 1] === "{") {
920
+ const end = findInterpolationEnd(code, index + 2);
921
+ index = end < 0 ? code.length : end + 1;
922
+ } else index++;
923
+ return code.length;
924
+ }
925
+ function collectJsxAttributes(code, start, end, ranges) {
926
+ const source = code.slice(start, end);
927
+ const regex = /\s([:@A-Za-z_$][\w$:.-]*)(?=\s*(?:=|\/?>))/g;
928
+ let match;
929
+ while (match = regex.exec(source)) {
930
+ const attributeStart = start + match.index + 1;
931
+ ranges.push({
932
+ start: attributeStart,
933
+ end: attributeStart + match[1].length,
934
+ className: "attr"
935
+ });
936
+ }
937
+ }
938
+ function isJsxStart(code, index, jsxAtLineStart) {
939
+ if (jsxAtLineStart && /^\s*$/.test(code.slice(code.lastIndexOf("\n", index - 1) + 1, index))) return true;
940
+ const before = code.slice(0, index).trimEnd();
941
+ if (!before) return true;
942
+ if (/\b(?:return|case|yield)$/.test(before)) return true;
943
+ return /(?:[=([{,:;!&|?]|>)$/.test(before);
944
+ }
945
+ function isTypeParameter(code, start, end, closing) {
946
+ if (closing) return false;
947
+ const inside = code.slice(start + 1, end);
948
+ const after = code.slice(end + 1).trimStart();
949
+ return /\s+extends\s+/.test(inside) || after[0] === "(" && !inside.trimEnd().endsWith("/");
950
+ }
951
+ function isRegexStart(code, index) {
952
+ const before = code.slice(0, index).trimEnd();
953
+ if (!before) return true;
954
+ if (/\b(?:case|delete|in|instanceof|of|return|throw|typeof|void|yield)$/.test(before)) return true;
955
+ return /[=([{,:;!&|?~+*%^<>-]$/.test(before);
956
+ }
957
+ function findRegexEnd(code, start) {
958
+ let inClass = false;
959
+ let index = start + 1;
960
+ while (index < code.length && code[index] !== "\n") if (code[index] === "\\") index += 2;
961
+ else if (code[index] === "[") {
962
+ inClass = true;
963
+ index++;
964
+ } else if (code[index] === "]") {
965
+ inClass = false;
966
+ index++;
967
+ } else if (code[index] === "/" && !inClass) {
968
+ index++;
969
+ while (/[a-z]/i.test(code[index] || "")) index++;
970
+ return index;
971
+ } else index++;
972
+ return start + 1;
973
+ }
974
+ function findQuotedEnd(code, start, quote, multiline = false) {
975
+ let index = start + 1;
976
+ while (index < code.length) if (code[index] === "\\") index += 2;
977
+ else if (code[index] === quote) return index + 1;
978
+ else if (!multiline && code[index] === "\n") return index;
979
+ else index++;
980
+ return code.length;
981
+ }
982
+ function findLineEnd(code, start) {
983
+ const end = code.indexOf("\n", start);
984
+ return end < 0 ? code.length : end;
985
+ }
986
+ function previousCodeIndex(code, index, ranges) {
987
+ let before = index - 1;
988
+ let rangeIndex = ranges.length - 1;
989
+ while (before >= 0) {
990
+ if (/\s/.test(code[before])) {
991
+ before--;
992
+ continue;
993
+ }
994
+ const range = ranges[rangeIndex];
995
+ if (range && range.end > before) {
996
+ rangeIndex--;
997
+ if (range.className === "comment" && range.start <= before) {
998
+ before = range.start - 1;
999
+ continue;
1000
+ }
1001
+ } else break;
1002
+ }
1003
+ return before;
1004
+ }
1005
+ //#endregion
1006
+ //#region ../../node_modules/.pnpm/@tanstack+highlight@1.0.0/node_modules/@tanstack/highlight/dist/languages/js.js
1007
+ const js = defineLanguage({
1008
+ name: "js",
1009
+ aliases: [
1010
+ "javascript",
1011
+ "mjs",
1012
+ "cjs",
1013
+ "js-vue"
1014
+ ],
1015
+ tokenize: (code) => collectScriptRanges(code)
1016
+ });
1017
+ //#endregion
1018
+ //#region ../../node_modules/.pnpm/@tanstack+highlight@1.0.0/node_modules/@tanstack/highlight/dist/languages/json.js
1019
+ const json = defineLanguage({
1020
+ name: "json",
1021
+ aliases: ["jsonc", "json5"],
1022
+ tokenize: patternTokenizer([
1023
+ {
1024
+ className: (match) => match[0].startsWith("//") || match[0].startsWith("/*") ? "comment" : match[1] ? "property" : "string",
1025
+ regex: /\/\/[^\n]*|\/\*[\s\S]*?\*\/|("(?:\\.|[^"\\])*")(?=\s*:)|"(?:\\.|[^"\\])*"/g
1026
+ },
1027
+ {
1028
+ className: "literal",
1029
+ regex: /\b(?:false|null|true)\b/g
1030
+ },
1031
+ {
1032
+ className: "number",
1033
+ regex: /-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/gi
1034
+ }
1035
+ ])
1036
+ });
1037
+ //#endregion
1038
+ //#region ../../node_modules/.pnpm/@tanstack+highlight@1.0.0/node_modules/@tanstack/highlight/dist/languages/jsx.js
1039
+ const jsx = defineLanguage({
1040
+ name: "jsx",
1041
+ tokenize: (code) => collectScriptRanges(code, true)
1042
+ });
1043
+ //#endregion
1044
+ //#region ../../node_modules/.pnpm/@tanstack+highlight@1.0.0/node_modules/@tanstack/highlight/dist/languages/markdown.js
1045
+ const markdown = defineLanguage({
1046
+ name: "markdown",
1047
+ aliases: ["md"],
1048
+ tokenize(code, context) {
1049
+ return collectPatternRanges(code, [
1050
+ {
1051
+ className: "heading",
1052
+ regex: /^#{1,6}\s.*$/gm
1053
+ },
1054
+ {
1055
+ className: "heading",
1056
+ regex: /^.+\n(?:=+|-+)\s*$/gm
1057
+ },
1058
+ {
1059
+ className: "code-inline",
1060
+ regex: /`[^`\n]+`/g
1061
+ },
1062
+ {
1063
+ className: "link",
1064
+ regex: /!?\[[^\]]+\]\([^)]+\)/g
1065
+ },
1066
+ {
1067
+ className: "meta",
1068
+ regex: /^\s{0,3}(?:>|[-*+] |\d+\. )/gm
1069
+ }
1070
+ ], collectFencedCode(code, context));
1071
+ }
1072
+ });
1073
+ function collectFencedCode(code, context) {
1074
+ const ranges = [];
1075
+ const opening = /^( {0,3})(`{3,}|~{3,})\s*([^\n]*)$/gm;
1076
+ let match;
1077
+ while (match = opening.exec(code)) {
1078
+ const marker = match[2];
1079
+ const contentStart = code.indexOf("\n", match.index + match[0].length);
1080
+ if (contentStart < 0) break;
1081
+ const closing = new RegExp(`^ {0,3}${marker[0]}{${marker.length},}\\s*$`, "gm");
1082
+ closing.lastIndex = contentStart + 1;
1083
+ const close = closing.exec(code);
1084
+ const contentEnd = close?.index ?? code.length;
1085
+ const info = match[3].trim().split(/\s+/)[0];
1086
+ const embedded = info && context.hasLanguage(info) ? offsetRanges(context.tokenize(code.slice(contentStart + 1, contentEnd), info), contentStart + 1) : [];
1087
+ ranges.push({
1088
+ start: match.index,
1089
+ end: contentStart,
1090
+ className: "meta"
1091
+ });
1092
+ ranges.push(...fillCodeRange(contentStart + 1, contentEnd, embedded));
1093
+ if (close) ranges.push({
1094
+ start: close.index,
1095
+ end: close.index + close[0].length,
1096
+ className: "meta"
1097
+ });
1098
+ opening.lastIndex = close ? close.index + close[0].length : code.length;
1099
+ }
1100
+ return ranges;
1101
+ }
1102
+ function fillCodeRange(start, end, embedded) {
1103
+ const ranges = [];
1104
+ let index = start;
1105
+ for (const range of embedded) {
1106
+ if (range.start > index) ranges.push({
1107
+ start: index,
1108
+ end: range.start,
1109
+ className: "code-inline"
1110
+ });
1111
+ ranges.push(range);
1112
+ index = range.end;
1113
+ }
1114
+ if (index < end) ranges.push({
1115
+ start: index,
1116
+ end,
1117
+ className: "code-inline"
1118
+ });
1119
+ return ranges;
1120
+ }
1121
+ //#endregion
1122
+ //#region ../../node_modules/.pnpm/@tanstack+highlight@1.0.0/node_modules/@tanstack/highlight/dist/languages/plaintext.js
1123
+ const plaintext = defineLanguage({
1124
+ name: "plaintext",
1125
+ aliases: [
1126
+ "text",
1127
+ "txt",
1128
+ "-->"
1129
+ ],
1130
+ tokenize: () => []
1131
+ });
1132
+ //#endregion
1133
+ //#region ../../node_modules/.pnpm/@tanstack+highlight@1.0.0/node_modules/@tanstack/highlight/dist/languages/shell.js
1134
+ const shell = defineLanguage({
1135
+ name: "shell",
1136
+ aliases: [
1137
+ "bash",
1138
+ "sh",
1139
+ "zsh",
1140
+ "cmd",
1141
+ "console"
1142
+ ],
1143
+ tokenize: patternTokenizer([
1144
+ { collect: collectShellLexicalRanges },
1145
+ {
1146
+ className: "variable",
1147
+ regex: /\$[A-Za-z_][A-Za-z0-9_]*|\b[A-Z_][A-Z0-9_]*(?==)/g
1148
+ },
1149
+ {
1150
+ className: "keyword",
1151
+ regex: /\b(?:case|do|done|elif|else|esac|export|fi|for|function|if|in|select|then|time|until|while)\b/g
1152
+ },
1153
+ {
1154
+ className: "command",
1155
+ regex: /(^|[\n;|&])\s*([A-Za-z0-9_./-]+)(?=\s|$)/g,
1156
+ group: 2
1157
+ }
1158
+ ])
1159
+ });
1160
+ function collectShellLexicalRanges(code) {
1161
+ const heredocs = [];
1162
+ collectHeredocs(code, heredocs);
1163
+ const ranges = [...heredocs];
1164
+ let heredocIndex = 0;
1165
+ let index = 0;
1166
+ while (index < code.length) {
1167
+ while (heredocIndex < heredocs.length && heredocs[heredocIndex].end <= index) heredocIndex++;
1168
+ const heredoc = heredocs[heredocIndex];
1169
+ if (heredoc && heredoc.start <= index) {
1170
+ index = heredoc.end;
1171
+ continue;
1172
+ }
1173
+ const character = code[index];
1174
+ if (character === "\"" || character === "'") {
1175
+ const quote = character;
1176
+ let end = index + 1;
1177
+ while (end < code.length) if (code[end] === "\\" && quote === "\"") end += 2;
1178
+ else if (code[end] === quote) {
1179
+ end++;
1180
+ break;
1181
+ } else end++;
1182
+ end = Math.min(end, code.length);
1183
+ ranges.push({
1184
+ start: index,
1185
+ end,
1186
+ className: "string"
1187
+ });
1188
+ index = end;
1189
+ continue;
1190
+ }
1191
+ if (character === "$" && code[index + 1] === "{") {
1192
+ const close = code.indexOf("}", index + 2);
1193
+ const end = close < 0 ? code.length : close + 1;
1194
+ ranges.push({
1195
+ start: index,
1196
+ end,
1197
+ className: "variable"
1198
+ });
1199
+ index = end;
1200
+ continue;
1201
+ }
1202
+ if (character === "#" && (index === 0 || code[index - 1] === "\n" || /[\s;|&()]/.test(code[index - 1]))) {
1203
+ const newline = code.indexOf("\n", index);
1204
+ const end = newline < 0 ? code.length : newline;
1205
+ ranges.push({
1206
+ start: index,
1207
+ end,
1208
+ className: "comment"
1209
+ });
1210
+ index = end;
1211
+ continue;
1212
+ }
1213
+ index++;
1214
+ }
1215
+ return ranges;
1216
+ }
1217
+ function collectHeredocs(code, ranges) {
1218
+ const regex = /<<-?\s*(['"]?)([A-Za-z_][A-Za-z0-9_]*)\1/g;
1219
+ let match;
1220
+ while (match = regex.exec(code)) {
1221
+ if (code[match.index - 1] === "<" || isInsideQuote(code, match.index)) continue;
1222
+ const bodyStartLine = code.indexOf("\n", match.index + match[0].length);
1223
+ if (bodyStartLine < 0) continue;
1224
+ const bodyStart = bodyStartLine + 1;
1225
+ const closingMatch = new RegExp(`^\\t*${match[2]}\\s*$`, "m").exec(code.slice(bodyStart));
1226
+ if (!closingMatch) {
1227
+ ranges.push({
1228
+ start: bodyStart,
1229
+ end: code.length,
1230
+ className: "string"
1231
+ });
1232
+ continue;
1233
+ }
1234
+ const end = bodyStart + closingMatch.index;
1235
+ if (end > bodyStart) ranges.push({
1236
+ start: bodyStart,
1237
+ end,
1238
+ className: "string"
1239
+ });
1240
+ const closingStart = bodyStart + closingMatch.index;
1241
+ ranges.push({
1242
+ start: closingStart,
1243
+ end: closingStart + closingMatch[0].length,
1244
+ className: "meta"
1245
+ });
1246
+ }
1247
+ }
1248
+ function isInsideQuote(code, index) {
1249
+ const lineStart = code.lastIndexOf("\n", index - 1) + 1;
1250
+ let quote = "";
1251
+ for (let cursor = lineStart; cursor < index; cursor++) if (code[cursor] === "\\" && quote !== "'") cursor++;
1252
+ else if (quote && code[cursor] === quote) quote = "";
1253
+ else if (!quote && (code[cursor] === "\"" || code[cursor] === "'")) quote = code[cursor];
1254
+ return Boolean(quote);
1255
+ }
1256
+ //#endregion
1257
+ //#region ../../node_modules/.pnpm/@tanstack+highlight@1.0.0/node_modules/@tanstack/highlight/dist/languages/ts.js
1258
+ const ts = defineLanguage({
1259
+ name: "ts",
1260
+ aliases: ["typescript", "angular-ts"],
1261
+ tokenize: (code) => collectScriptRanges(code)
1262
+ });
1263
+ //#endregion
1264
+ //#region ../../node_modules/.pnpm/@tanstack+highlight@1.0.0/node_modules/@tanstack/highlight/dist/languages/tsx.js
1265
+ const tsx = defineLanguage({
1266
+ name: "tsx",
1267
+ tokenize: (code) => collectScriptRanges(code, true)
1268
+ });
1269
+ //#endregion
1270
+ //#region ../../node_modules/.pnpm/@tanstack+highlight@1.0.0/node_modules/@tanstack/highlight/dist/languages/yaml.js
1271
+ const yaml = defineLanguage({
1272
+ name: "yaml",
1273
+ aliases: ["yml"],
1274
+ tokenize(code) {
1275
+ const lexical = [...collectYamlBlockScalars(code), ...collectYamlLexicalRanges(code)];
1276
+ return collectPatternRanges(code, [
1277
+ {
1278
+ className: "property",
1279
+ regex: /^[ \t-]*([A-Za-z0-9_.-]+)(?=\s*:)/gm,
1280
+ group: 1
1281
+ },
1282
+ { collect: collectYamlValues },
1283
+ {
1284
+ className: "literal",
1285
+ regex: /\b(?:false|null|true|yes|no|on|off|~)\b/gi
1286
+ },
1287
+ {
1288
+ className: "number",
1289
+ regex: /\b\d+(?:\.\d+)?\b/g
1290
+ }
1291
+ ], lexical);
1292
+ }
1293
+ });
1294
+ function collectYamlBlockScalars(code) {
1295
+ const ranges = [];
1296
+ const opening = /^(\s*)[\w.-]+:\s*[>|][+-]?\s*(?:#.*)?$/gm;
1297
+ let match;
1298
+ while (match = opening.exec(code)) {
1299
+ const start = code.indexOf("\n", match.index + match[0].length);
1300
+ if (start < 0) continue;
1301
+ const indentation = match[1].length;
1302
+ let end = start + 1;
1303
+ while (end < code.length) {
1304
+ const lineEnd = code.indexOf("\n", end);
1305
+ const next = lineEnd < 0 ? code.length : lineEnd;
1306
+ const line = code.slice(end, next);
1307
+ if (line.trim() && (line.match(/^\s*/)?.[0].length || 0) <= indentation) break;
1308
+ end = lineEnd < 0 ? code.length : lineEnd + 1;
1309
+ }
1310
+ if (end > start + 1) ranges.push({
1311
+ start: start + 1,
1312
+ end,
1313
+ className: "string"
1314
+ });
1315
+ }
1316
+ return ranges;
1317
+ }
1318
+ function collectYamlLexicalRanges(code) {
1319
+ const ranges = [];
1320
+ let index = 0;
1321
+ while (index < code.length) {
1322
+ const character = code[index];
1323
+ if (character === "\"" || character === "'") {
1324
+ const quote = character;
1325
+ let end = index + 1;
1326
+ while (end < code.length && code[end] !== "\n") if (code[end] === "\\" && quote === "\"") end += 2;
1327
+ else if (code[end] === quote) {
1328
+ end++;
1329
+ break;
1330
+ } else end++;
1331
+ ranges.push({
1332
+ start: index,
1333
+ end,
1334
+ className: "string"
1335
+ });
1336
+ index = end;
1337
+ continue;
1338
+ }
1339
+ if (character === "#" && (index === 0 || code[index - 1] === "\n" || /\s/.test(code[index - 1]))) {
1340
+ const newline = code.indexOf("\n", index);
1341
+ const end = newline < 0 ? code.length : newline;
1342
+ ranges.push({
1343
+ start: index,
1344
+ end,
1345
+ className: "comment"
1346
+ });
1347
+ index = end;
1348
+ continue;
1349
+ }
1350
+ index++;
1351
+ }
1352
+ return ranges;
1353
+ }
1354
+ function collectYamlValues(code) {
1355
+ const ranges = [];
1356
+ const regex = /:\s*([^\n]*)/g;
1357
+ let match;
1358
+ while (match = regex.exec(code)) {
1359
+ const value = match[1];
1360
+ const trimmed = value.trimEnd();
1361
+ if (!trimmed) continue;
1362
+ const start = match.index + match[0].indexOf(value);
1363
+ let end = start + trimmed.length;
1364
+ const comment = /\s+#/.exec(trimmed);
1365
+ if (comment) end = start + comment.index;
1366
+ while (end > start && /\s/.test(code[end - 1])) end--;
1367
+ if (end > start) ranges.push({
1368
+ start,
1369
+ end,
1370
+ className: "string"
1371
+ });
1372
+ }
1373
+ return ranges;
1374
+ }
1375
+ //#endregion
1376
+ //#region ../../node_modules/.pnpm/@tanstack+highlight@1.0.0/node_modules/@tanstack/highlight/dist/internal/code-fence.js
1377
+ const codeDiffNotation = /(?:(?:\/\/|#)[ \t]*\[!code[ \t]+(\+\+|--)\]|\/\*[ \t]*\[!code[ \t]+(\+\+|--)\][ \t]*\*\/|<!--[ \t]*\[!code[ \t]+(\+\+|--)\][ \t]*-->)[ \t]*\r?$/;
1378
+ function parseCodeDiffNotation(code) {
1379
+ const decorations = [];
1380
+ if (!code.includes("[!code")) return {
1381
+ code,
1382
+ decorations
1383
+ };
1384
+ const lines = code.split("\n");
1385
+ for (let index = 0; index < lines.length; index++) {
1386
+ const line = lines[index];
1387
+ const match = codeDiffNotation.exec(line);
1388
+ if (!match) continue;
1389
+ const notation = match[1] || match[2] || match[3];
1390
+ decorations.push({
1391
+ className: notation === "++" ? "th-line--inserted" : "th-line--deleted",
1392
+ lines: index + 1
1393
+ });
1394
+ lines[index] = line.slice(0, match.index).replace(/[ \t]+$/, "") + (line.endsWith("\r") ? "\r" : "");
1395
+ }
1396
+ return {
1397
+ code: lines.join("\n"),
1398
+ decorations
1399
+ };
1400
+ }
1401
+ //#endregion
1402
+ //#region ../../node_modules/.pnpm/@tanstack+highlight@1.0.0/node_modules/@tanstack/highlight/dist/markdown.js
1403
+ function createTanStackMarkdownHighlighter(highlighter) {
1404
+ return (code, lang = "plaintext", options = {}) => {
1405
+ const annotated = parseCodeDiffNotation(code);
1406
+ const result = highlighter.tokenize(annotated.code, { lang });
1407
+ for (const lines of options.highlightLines || []) annotated.decorations.push({
1408
+ className: "th-line--highlighted",
1409
+ lines
1410
+ });
1411
+ return renderNodesToHtml(renderTokens(result.tokens, {
1412
+ lineNumbers: options.lineNumbers,
1413
+ decorations: annotated.decorations
1414
+ }));
1415
+ };
1416
+ }
1417
+ //#endregion
1418
+ //#region ../../packages/document/src/highlight.ts
1419
+ const MAX_HIGHLIGHT_CHARS = 262144;
1420
+ const highlighter = createHighlighter({ languages: [
1421
+ js,
1422
+ jsx,
1423
+ ts,
1424
+ tsx,
1425
+ json,
1426
+ yaml,
1427
+ html,
1428
+ css,
1429
+ shell,
1430
+ markdown,
1431
+ plaintext
1432
+ ] });
1433
+ const registered = new Set(highlighter.listLanguages());
1434
+ const highlightAdapter = createTanStackMarkdownHighlighter(highlighter);
1435
+ const safeHighlighter = (code, lang, options) => {
1436
+ const normalized = lang ? highlighter.normalizeLanguage(lang) : "plaintext";
1437
+ const usable = registered.has(normalized) && code.length <= MAX_HIGHLIGHT_CHARS;
1438
+ return highlightAdapter(code, usable ? normalized : "plaintext", options);
1439
+ };
1440
+ //#endregion
1441
+ //#region ../../packages/document/src/print-style.ts
1442
+ const SANS = [
1443
+ "-apple-system",
1444
+ "BlinkMacSystemFont",
1445
+ "'Hiragino Sans'",
1446
+ "'Hiragino Kaku Gothic ProN'",
1447
+ "'Segoe UI'",
1448
+ "'Yu Gothic Medium'",
1449
+ "'Yu Gothic'",
1450
+ "Meiryo",
1451
+ "'Noto Sans CJK JP'",
1452
+ "'Noto Sans JP'",
1453
+ "sans-serif"
1454
+ ].join(", ");
1455
+ const MONO = [
1456
+ "ui-monospace",
1457
+ "'SF Mono'",
1458
+ "SFMono-Regular",
1459
+ "Menlo",
1460
+ "Consolas",
1461
+ "'Liberation Mono'",
1462
+ "'Hiragino Sans'",
1463
+ "'Yu Gothic Medium'",
1464
+ "'Noto Sans CJK JP'",
1465
+ "monospace"
1466
+ ].join(", ");
1467
+ function printPageStyle(cssTitle) {
1468
+ return `@page {
1469
+ size: A4;
1470
+ margin: 20mm;
1471
+ @top-left {
1472
+ content: ${cssTitle};
1473
+ vertical-align: bottom;
1474
+ padding-bottom: 6mm;
1475
+ font: 8pt/1.4 ${SANS};
1476
+ color: #57606a;
1477
+ }
1478
+ @bottom-center {
1479
+ content: counter(page) " / " counter(pages);
1480
+ vertical-align: top;
1481
+ padding-top: 6mm;
1482
+ font: 8pt/1.4 ${SANS};
1483
+ color: #57606a;
1484
+ }
1485
+ }`;
1486
+ }
1487
+ const PRINT_STYLE = `
1488
+ :root {
1489
+ color-scheme: light;
1490
+ print-color-adjust: exact;
1491
+ -webkit-print-color-adjust: exact;
1492
+ }
1493
+ *, *::before, *::after {
1494
+ box-sizing: border-box;
1495
+ }
1496
+ html, body {
1497
+ margin: 0;
1498
+ padding: 0;
1499
+ background: #ffffff;
1500
+ }
1501
+ body {
1502
+ font-family: ${SANS};
1503
+ font-size: 10.5pt;
1504
+ line-height: 1.75;
1505
+ color: #1f2328;
1506
+ font-kerning: normal;
1507
+ overflow-wrap: anywhere;
1508
+ }
1509
+ .document > :first-child {
1510
+ margin-top: 0;
1511
+ }
1512
+ h1, h2, h3, h4, h5, h6 {
1513
+ margin: 1.7em 0 0.6em;
1514
+ font-weight: 600;
1515
+ line-height: 1.35;
1516
+ color: #111418;
1517
+ break-after: avoid;
1518
+ }
1519
+ h1 {
1520
+ font-size: 20pt;
1521
+ font-weight: 700;
1522
+ padding-bottom: 0.3em;
1523
+ border-bottom: 1.5pt solid #1f2328;
1524
+ }
1525
+ h2 {
1526
+ font-size: 14.5pt;
1527
+ padding-bottom: 0.25em;
1528
+ border-bottom: 0.75pt solid #d0d7de;
1529
+ }
1530
+ h3 {
1531
+ font-size: 12pt;
1532
+ }
1533
+ h4 {
1534
+ font-size: 10.5pt;
1535
+ }
1536
+ h5, h6 {
1537
+ font-size: 10pt;
1538
+ color: #57606a;
1539
+ }
1540
+ p, ul, ol, table, pre, blockquote, figure, .keep-together {
1541
+ margin: 0.8em 0;
1542
+ }
1543
+ p, li, blockquote {
1544
+ orphans: 3;
1545
+ widows: 3;
1546
+ }
1547
+ ul, ol {
1548
+ padding-left: 1.6em;
1549
+ }
1550
+ ul {
1551
+ list-style: disc;
1552
+ }
1553
+ ol {
1554
+ list-style: decimal;
1555
+ }
1556
+ li + li, li > ul, li > ol {
1557
+ margin-top: 0.2em;
1558
+ }
1559
+ li > ul, li > ol, li > p:last-child {
1560
+ margin-bottom: 0;
1561
+ }
1562
+ li > p:first-child {
1563
+ margin-top: 0;
1564
+ }
1565
+ li:has(> input[type='checkbox']), li:has(> p:first-child > input[type='checkbox']) {
1566
+ list-style: none;
1567
+ margin-left: -1.4em;
1568
+ }
1569
+ input[type='checkbox'] {
1570
+ appearance: none;
1571
+ width: 0.95em;
1572
+ height: 0.95em;
1573
+ margin: 0 0.45em 0 0;
1574
+ border: 1pt solid #57606a;
1575
+ border-radius: 2pt;
1576
+ vertical-align: -0.12em;
1577
+ background: #ffffff;
1578
+ }
1579
+ input[type='checkbox']:checked {
1580
+ border-color: #1f2328;
1581
+ background: #1f2328 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23ffffff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 90% no-repeat;
1582
+ }
1583
+ a {
1584
+ color: #0969da;
1585
+ text-decoration: underline;
1586
+ text-decoration-color: #9cc3ec;
1587
+ text-underline-offset: 2px;
1588
+ }
1589
+ strong {
1590
+ font-weight: 600;
1591
+ }
1592
+ hr {
1593
+ margin: 1.8em 0;
1594
+ border: 0;
1595
+ border-top: 0.75pt solid #d0d7de;
1596
+ }
1597
+ img {
1598
+ display: block;
1599
+ max-width: 100%;
1600
+ max-height: 230mm;
1601
+ height: auto;
1602
+ margin: 0 auto;
1603
+ break-inside: avoid;
1604
+ }
1605
+ .blocked-image {
1606
+ color: #57606a;
1607
+ font-size: 0.9em;
1608
+ }
1609
+ blockquote {
1610
+ margin-left: 0;
1611
+ margin-right: 0;
1612
+ padding: 0.1em 1em;
1613
+ border-left: 3pt solid #d0d7de;
1614
+ color: #57606a;
1615
+ }
1616
+ blockquote > :first-child {
1617
+ margin-top: 0;
1618
+ }
1619
+ blockquote > :last-child {
1620
+ margin-bottom: 0;
1621
+ }
1622
+ table {
1623
+ display: table;
1624
+ width: 100%;
1625
+ border-collapse: collapse;
1626
+ font-size: 9.5pt;
1627
+ line-height: 1.55;
1628
+ }
1629
+ thead {
1630
+ display: table-header-group;
1631
+ }
1632
+ tr {
1633
+ break-inside: avoid;
1634
+ }
1635
+ th, td {
1636
+ padding: 0.45em 0.75em;
1637
+ border: 0.75pt solid #d0d7de;
1638
+ text-align: left;
1639
+ vertical-align: top;
1640
+ }
1641
+ th {
1642
+ background: #f3f5f7;
1643
+ font-weight: 600;
1644
+ }
1645
+ code, pre {
1646
+ font-family: ${MONO};
1647
+ }
1648
+ :not(pre) > code {
1649
+ padding: 0.1em 0.35em;
1650
+ border-radius: 3pt;
1651
+ background: #eff2f5;
1652
+ font-size: 0.88em;
1653
+ }
1654
+ pre {
1655
+ padding: 0.8em 1em;
1656
+ border: 0.75pt solid #d8dee4;
1657
+ border-radius: 4pt;
1658
+ background: #f6f8fa;
1659
+ font-size: 8.8pt;
1660
+ line-height: 1.55;
1661
+ white-space: pre-wrap;
1662
+ overflow-wrap: anywhere;
1663
+ box-decoration-break: clone;
1664
+ -webkit-box-decoration-break: clone;
1665
+ }
1666
+ .keep-together {
1667
+ break-inside: avoid;
1668
+ }
1669
+ .keep-together > pre, .keep-together > figure {
1670
+ margin: 0;
1671
+ }
1672
+ figure.tm-code-frame > figcaption {
1673
+ margin-bottom: 0.3em;
1674
+ break-after: avoid;
1675
+ font-family: ${MONO};
1676
+ font-size: 8.5pt;
1677
+ color: #57606a;
1678
+ }
1679
+ figure.tm-code-frame > pre {
1680
+ margin: 0;
1681
+ }
1682
+ .th-keyword { color: #cf222e; font-weight: 600; }
1683
+ .th-string, .th-code-inline, .th-inserted { color: #0a3069; }
1684
+ .th-number, .th-literal { color: #0550ae; }
1685
+ .th-comment, .th-meta { color: #59636e; }
1686
+ .th-function, .th-command, .th-property, .th-link { color: #6639ba; }
1687
+ .th-tag { color: #116329; }
1688
+ .th-type, .th-attr, .th-selector, .th-variable { color: #953800; }
1689
+ .th-heading { color: #0550ae; font-weight: 600; }
1690
+ .th-deleted { color: #82071e; }
1691
+ .footnotes {
1692
+ margin-top: 2em;
1693
+ padding-top: 0.6em;
1694
+ border-top: 0.75pt solid #d0d7de;
1695
+ font-size: 9pt;
1696
+ color: #57606a;
1697
+ }
1698
+ .footnotes ol {
1699
+ margin: 0;
1700
+ }
1701
+ /* The hidden "Footnotes" heading of the renderer would appear in the PDF outline. */
1702
+ .sr-only {
1703
+ display: none;
1704
+ }
1705
+ .data-footnote-backref {
1706
+ text-decoration: none;
1707
+ font-variant-emoji: text;
1708
+ }
1709
+ `;
1710
+ //#endregion
1711
+ //#region ../../packages/document/src/print.ts
1712
+ const PRINT_CSP = "default-src 'none'; img-src data:; style-src 'unsafe-inline'; base-uri 'none'; form-action 'none'";
1713
+ const KANA = /[\u3041-\u3096\u30a1-\u30fa]/;
1714
+ const HANGUL = /[\uac00-\ud7af]/;
1715
+ const IMAGE_SLOT = /^[0-9a-f]{32,}$/;
1716
+ const KEEP_TOGETHER_LINES = 25;
1717
+ const HEADER_TITLE_LENGTH = 60;
1718
+ function escapeHtml(value) {
1719
+ return value.replace(/[&<>"'`]/g, (character) => `&#${String(character.charCodeAt(0))};`);
1720
+ }
1721
+ function cssString(value) {
1722
+ let escaped = "";
1723
+ for (const character of value) escaped += /^[A-Za-z0-9 ]$/.test(character) ? character : `\\${(character.codePointAt(0) ?? 65533).toString(16)} `;
1724
+ return `"${escaped}"`;
1725
+ }
1726
+ function headerTitle(title) {
1727
+ const characters = Array.from(title);
1728
+ return characters.length > HEADER_TITLE_LENGTH ? `${characters.slice(0, 59).join("")}…` : title;
1729
+ }
1730
+ function printNodes(input, baseOptions) {
1731
+ const images = new Map(input.images.map((logicalPath, index) => [logicalPath, index]));
1732
+ return {
1733
+ name: "vde-open-print",
1734
+ renderHtml(node, context) {
1735
+ if (node.type === "image") {
1736
+ const logicalPath = localImagePath(node.src, input.documentLogicalPath);
1737
+ const index = logicalPath === null ? void 0 : images.get(logicalPath);
1738
+ if (index === void 0) return `<span class="blocked-image">${escapeHtml(node.alt ? `[image: ${node.alt}]` : "[image]")}</span>`;
1739
+ const title = node.title ? ` title="${escapeHtml(node.title)}"` : "";
1740
+ return `<img src="${input.imageSlot}-${String(index)}" alt="${escapeHtml(node.alt)}"${title}>`;
1741
+ }
1742
+ if (node.type === "link") {
1743
+ const children = node.children.map((child) => context.renderInline(child)).join("");
1744
+ const kind = renderedLinkOf(node.href);
1745
+ if (kind !== "fragment" && kind !== "external") return children;
1746
+ const title = node.title ? ` title="${escapeHtml(node.title)}"` : "";
1747
+ return `<a href="${escapeHtml(node.href)}"${title}>${children}</a>`;
1748
+ }
1749
+ if (node.type === "code" && node.value.split("\n").length <= KEEP_TOGETHER_LINES) return `<div class="keep-together">${renderBlock(node, baseOptions)}</div>`;
1750
+ }
1751
+ };
1752
+ }
1753
+ function renderPrintDocument(input) {
1754
+ if (!IMAGE_SLOT.test(input.imageSlot)) throw new Error("The image slot must be random hexadecimal.");
1755
+ const baseOptions = {
1756
+ ...MARKDOWN_PARSE_OPTIONS,
1757
+ allowHtml: false,
1758
+ highlighter: safeHighlighter
1759
+ };
1760
+ const body = renderDocument(parseMarkdownDocument(input.source), {
1761
+ ...baseOptions,
1762
+ extensions: [printNodes(input, baseOptions)]
1763
+ });
1764
+ return [
1765
+ "<!doctype html>",
1766
+ `<html${KANA.test(input.source) ? " lang=\"ja\"" : HANGUL.test(input.source) ? " lang=\"ko\"" : ""}>`,
1767
+ "<head>",
1768
+ "<meta charset=\"utf-8\">",
1769
+ `<meta http-equiv="Content-Security-Policy" content="${PRINT_CSP}">`,
1770
+ `<title>${escapeHtml(input.title)}</title>`,
1771
+ `<style>${printPageStyle(cssString(headerTitle(input.title)))}${PRINT_STYLE}</style>`,
1772
+ "</head>",
1773
+ `<body><main class="document">${body}</main></body>`,
1774
+ "</html>",
1775
+ ""
1776
+ ].join("\n");
1777
+ }
1778
+ //#endregion
1779
+ export { cssString, headerTitle, renderPrintDocument };