@silicajs/core 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-3BJGLARO.js → chunk-7KWXP3FM.js} +13 -47
- package/dist/chunk-7KWXP3FM.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +7 -5
- package/dist/index.js.map +1 -1
- package/dist/runtime.d.ts +3 -3
- package/dist/runtime.js +1 -1
- package/dist/{theme-BDcLPLzP.d.ts → theme-DF-R1di4.d.ts} +5 -5
- package/dist/theme.d.ts +1 -1
- package/package.json +1 -1
- package/dist/chunk-3BJGLARO.js.map +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/path.ts
|
|
2
2
|
import path from "path";
|
|
3
3
|
var NUMERIC_PREFIX_RE = /^(\d+)[\s._-]+(.+)$/;
|
|
4
|
+
var DOCUMENT_EXTENSION_RE = /\.(md|markdown|mdx)$/i;
|
|
4
5
|
var UNORDERED_SEGMENT_SORT_PREFIX = "~~~~~~~~~~";
|
|
5
6
|
function asFilePath(value) {
|
|
6
7
|
return normalizePath(value);
|
|
@@ -24,12 +25,11 @@ function hasNumericPrefix(segment) {
|
|
|
24
25
|
return NUMERIC_PREFIX_RE.test(segment);
|
|
25
26
|
}
|
|
26
27
|
function slugifySegment(segment, options = {}) {
|
|
27
|
-
const
|
|
28
|
-
const displaySegment = options.numericPrefixes ? stripNumericPrefix(stem) : stem;
|
|
28
|
+
const displaySegment = options.numericPrefixes ? stripNumericPrefix(segment) : segment;
|
|
29
29
|
return displaySegment.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").trim().toLowerCase().replace(/['"]/g, "").replace(/[^a-z0-9/_-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
30
30
|
}
|
|
31
31
|
function normalizeSlug(value, options = {}) {
|
|
32
|
-
const cleaned = normalizePath(value).replace(/^\.\//, "").replace(
|
|
32
|
+
const cleaned = normalizePath(value).replace(/^\.\//, "").replace(DOCUMENT_EXTENSION_RE, "");
|
|
33
33
|
const parts = cleaned.split("/").filter(Boolean).map((part) => slugifySegment(part, options));
|
|
34
34
|
return (parts.join("/") || "index").replace(/\/index\/index$/, "/index");
|
|
35
35
|
}
|
|
@@ -40,10 +40,10 @@ function slugifyFilePath(filePath, contentDir = "content", options = {}) {
|
|
|
40
40
|
return asFullSlug(normalizeSlug(relative, options));
|
|
41
41
|
}
|
|
42
42
|
function hasNumericPrefixInPath(filePath) {
|
|
43
|
-
return normalizePath(filePath).split("/").some((segment) => hasNumericPrefix(segment
|
|
43
|
+
return normalizePath(filePath).replace(DOCUMENT_EXTENSION_RE, "").split("/").some((segment) => hasNumericPrefix(segment));
|
|
44
44
|
}
|
|
45
45
|
function numericPrefixSortKey(filePath) {
|
|
46
|
-
return normalizePath(filePath).replace(
|
|
46
|
+
return normalizePath(filePath).replace(DOCUMENT_EXTENSION_RE, "").split("/").filter(Boolean).map(numericPrefixSortSegment).join("/");
|
|
47
47
|
}
|
|
48
48
|
function simplifySlug(slug) {
|
|
49
49
|
const normalized = normalizeSlug(slug);
|
|
@@ -92,10 +92,9 @@ function joinSegments(...segments) {
|
|
|
92
92
|
return normalizePath(segments.filter(Boolean).join("/"));
|
|
93
93
|
}
|
|
94
94
|
function numericPrefixSortSegment(segment) {
|
|
95
|
-
const
|
|
96
|
-
const match = NUMERIC_PREFIX_RE.exec(stem);
|
|
95
|
+
const match = NUMERIC_PREFIX_RE.exec(segment);
|
|
97
96
|
if (!match) {
|
|
98
|
-
return `${UNORDERED_SEGMENT_SORT_PREFIX}:${slugifySegment(
|
|
97
|
+
return `${UNORDERED_SEGMENT_SORT_PREFIX}:${slugifySegment(segment)}`;
|
|
99
98
|
}
|
|
100
99
|
const order = match[1].padStart(10, "0");
|
|
101
100
|
return `${order}:${slugifySegment(match[2])}`;
|
|
@@ -676,17 +675,6 @@ function getDataArray(data, key) {
|
|
|
676
675
|
const value = data[key];
|
|
677
676
|
return Array.isArray(value) ? value : [];
|
|
678
677
|
}
|
|
679
|
-
function mergeBrokenLinks(a, b) {
|
|
680
|
-
const seen = /* @__PURE__ */ new Set();
|
|
681
|
-
const merged = [];
|
|
682
|
-
for (const item of [...a, ...b]) {
|
|
683
|
-
const key = `${item.source}\0${item.target}`;
|
|
684
|
-
if (seen.has(key)) continue;
|
|
685
|
-
seen.add(key);
|
|
686
|
-
merged.push(item);
|
|
687
|
-
}
|
|
688
|
-
return merged;
|
|
689
|
-
}
|
|
690
678
|
function isHeading(node) {
|
|
691
679
|
return node.type === "element" && /^h[1-6]$/.test(node.tagName ?? "");
|
|
692
680
|
}
|
|
@@ -901,7 +889,6 @@ var sanitizeSchema = {
|
|
|
901
889
|
};
|
|
902
890
|
async function renderMarkdown(raw, context) {
|
|
903
891
|
const parsed = matter(raw);
|
|
904
|
-
const inlineTags = context.tags?.inline ?? true;
|
|
905
892
|
const processor = baseProcessor(context).use(rehypeUnwrapSilicaEmbeds).use(rehypeRaw).use(rehypeSanitize, sanitizeSchema).use(rehypeRestoreObsidianBlockIds).use(rehypeUnwrapSilicaEmbeds).use(rehypeKatex);
|
|
906
893
|
if (hasCodeFence(parsed.content)) {
|
|
907
894
|
processor.use(rehypeShiki, {
|
|
@@ -928,27 +915,10 @@ async function renderMarkdown(raw, context) {
|
|
|
928
915
|
components: context.components
|
|
929
916
|
});
|
|
930
917
|
const file = await processor.process(parsed.content);
|
|
931
|
-
const frontmatter = parsed.data;
|
|
932
|
-
const obsidianBrokenLinks = getDataArray(
|
|
933
|
-
file.data,
|
|
934
|
-
"silicaObsidianBrokenLinks"
|
|
935
|
-
).map((link) => ({ source: String(context.slug), target: link.target }));
|
|
936
|
-
const links = unique([
|
|
937
|
-
...getDataArray(file.data, "silicaObsidianLinks"),
|
|
938
|
-
...getDataArray(file.data, "links")
|
|
939
|
-
]);
|
|
940
918
|
const toc = getDataArray(file.data, "toc");
|
|
941
|
-
const plainText = extractPlainText(parsed.content);
|
|
942
919
|
return {
|
|
943
920
|
content: file.result,
|
|
944
|
-
|
|
945
|
-
toc,
|
|
946
|
-
links,
|
|
947
|
-
brokenLinks: mergeBrokenLinks(obsidianBrokenLinks, []),
|
|
948
|
-
plainText,
|
|
949
|
-
title: getTitle(frontmatter, plainText),
|
|
950
|
-
description: getDescription(frontmatter),
|
|
951
|
-
tags: getTags(frontmatter, parsed.content, { inline: inlineTags })
|
|
921
|
+
toc
|
|
952
922
|
};
|
|
953
923
|
}
|
|
954
924
|
async function renderMarkdownHtml(raw, context) {
|
|
@@ -983,21 +953,19 @@ async function analyzeMarkdown(raw, context) {
|
|
|
983
953
|
const description = getDescription(frontmatter);
|
|
984
954
|
return {
|
|
985
955
|
frontmatter,
|
|
986
|
-
toc: [],
|
|
987
956
|
links: getDataArray(file.data, "silicaObsidianLinks"),
|
|
988
957
|
brokenLinks,
|
|
989
958
|
plainText,
|
|
990
|
-
title: getTitle(frontmatter
|
|
959
|
+
title: getTitle(frontmatter),
|
|
991
960
|
description,
|
|
992
961
|
generatedDescription: description ? void 0 : generateDescriptionFromContent(parsed.content),
|
|
993
962
|
tags: getTags(frontmatter, parsed.content, { inline: inlineTags })
|
|
994
963
|
};
|
|
995
964
|
}
|
|
996
|
-
function getTitle(frontmatter
|
|
965
|
+
function getTitle(frontmatter) {
|
|
997
966
|
if (typeof frontmatter.title === "string" && frontmatter.title.trim())
|
|
998
967
|
return frontmatter.title.trim();
|
|
999
|
-
|
|
1000
|
-
return heading?.replace(/^#+\s*/, "");
|
|
968
|
+
return void 0;
|
|
1001
969
|
}
|
|
1002
970
|
function getDescription(frontmatter) {
|
|
1003
971
|
if (typeof frontmatter.description === "string" && frontmatter.description.trim()) {
|
|
@@ -1067,9 +1035,6 @@ function normalizePlainText(text) {
|
|
|
1067
1035
|
function hasCodeFence(markdown) {
|
|
1068
1036
|
return /(^|\n)(```|~~~)/.test(markdown);
|
|
1069
1037
|
}
|
|
1070
|
-
function unique(values) {
|
|
1071
|
-
return [...new Set(values.filter(Boolean))];
|
|
1072
|
-
}
|
|
1073
1038
|
|
|
1074
1039
|
export {
|
|
1075
1040
|
asFilePath,
|
|
@@ -1077,6 +1042,7 @@ export {
|
|
|
1077
1042
|
asSimpleSlug,
|
|
1078
1043
|
asRelativeURL,
|
|
1079
1044
|
normalizePath,
|
|
1045
|
+
stripNumericPrefix,
|
|
1080
1046
|
slugifySegment,
|
|
1081
1047
|
normalizeSlug,
|
|
1082
1048
|
slugifyFilePath,
|
|
@@ -1102,4 +1068,4 @@ export {
|
|
|
1102
1068
|
generateDescriptionFromContent,
|
|
1103
1069
|
getMetaDescription
|
|
1104
1070
|
};
|
|
1105
|
-
//# sourceMappingURL=chunk-
|
|
1071
|
+
//# sourceMappingURL=chunk-7KWXP3FM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/path.ts","../src/pipeline/frontmatter.ts","../src/tags.ts","../src/pipeline/index.ts","../src/pipeline/code-block.ts","../src/pipeline/obsidian.ts","../src/pipeline/plugins.ts"],"sourcesContent":["import path from \"node:path\";\n\ndeclare const filePathBrand: unique symbol;\ndeclare const fullSlugBrand: unique symbol;\ndeclare const simpleSlugBrand: unique symbol;\ndeclare const relativeUrlBrand: unique symbol;\n\nexport type FilePath = string & { readonly [filePathBrand]: \"FilePath\" };\nexport type FullSlug = string & { readonly [fullSlugBrand]: \"FullSlug\" };\nexport type SimpleSlug = string & { readonly [simpleSlugBrand]: \"SimpleSlug\" };\nexport type RelativeURL = string & {\n readonly [relativeUrlBrand]: \"RelativeURL\";\n};\n\nexport type SlugifyOptions = {\n numericPrefixes?: boolean;\n};\n\nconst NUMERIC_PREFIX_RE = /^(\\d+)[\\s._-]+(.+)$/;\nconst DOCUMENT_EXTENSION_RE = /\\.(md|markdown|mdx)$/i;\nconst UNORDERED_SEGMENT_SORT_PREFIX = \"~~~~~~~~~~\";\n\nexport function asFilePath(value: string): FilePath {\n return normalizePath(value) as FilePath;\n}\n\nexport function asFullSlug(value: string): FullSlug {\n return normalizeSlug(value) as FullSlug;\n}\n\nexport function asSimpleSlug(value: string): SimpleSlug {\n return simplifySlug(asFullSlug(value)) as SimpleSlug;\n}\n\nexport function asRelativeURL(value: string): RelativeURL {\n return value as RelativeURL;\n}\n\nexport function normalizePath(value: string): string {\n return value.replace(/\\\\/g, \"/\").replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n}\n\nexport function stripNumericPrefix(segment: string): string {\n return segment.replace(NUMERIC_PREFIX_RE, \"$2\");\n}\n\nexport function hasNumericPrefix(segment: string): boolean {\n return NUMERIC_PREFIX_RE.test(segment);\n}\n\nexport function slugifySegment(\n segment: string,\n options: SlugifyOptions = {},\n): string {\n const displaySegment = options.numericPrefixes\n ? stripNumericPrefix(segment)\n : segment;\n return displaySegment\n .normalize(\"NFKD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .trim()\n .toLowerCase()\n .replace(/['\"]/g, \"\")\n .replace(/[^a-z0-9/_-]+/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n}\n\nexport function normalizeSlug(\n value: string,\n options: SlugifyOptions = {},\n): string {\n const cleaned = normalizePath(value)\n .replace(/^\\.\\//, \"\")\n .replace(DOCUMENT_EXTENSION_RE, \"\");\n const parts = cleaned\n .split(\"/\")\n .filter(Boolean)\n .map((part) => slugifySegment(part, options));\n return (parts.join(\"/\") || \"index\").replace(/\\/index\\/index$/, \"/index\");\n}\n\nexport function slugifyFilePath(\n filePath: FilePath | string,\n contentDir = \"content\",\n options: SlugifyOptions = {},\n): FullSlug {\n const normalizedFile = normalizePath(filePath);\n const normalizedContent = normalizePath(contentDir);\n const relative = normalizedFile.startsWith(`${normalizedContent}/`)\n ? normalizedFile.slice(normalizedContent.length + 1)\n : normalizedFile;\n\n return asFullSlug(normalizeSlug(relative, options));\n}\n\nexport function hasNumericPrefixInPath(filePath: string): boolean {\n return normalizePath(filePath)\n .replace(DOCUMENT_EXTENSION_RE, \"\")\n .split(\"/\")\n .some((segment) => hasNumericPrefix(segment));\n}\n\nexport function numericPrefixSortKey(filePath: string): string {\n return normalizePath(filePath)\n .replace(DOCUMENT_EXTENSION_RE, \"\")\n .split(\"/\")\n .filter(Boolean)\n .map(numericPrefixSortSegment)\n .join(\"/\");\n}\n\nexport function simplifySlug(slug: FullSlug | string): SimpleSlug {\n const normalized = normalizeSlug(slug);\n if (normalized === \"index\") return \"\" as SimpleSlug;\n return normalized.replace(/\\/index$/, \"\") as SimpleSlug;\n}\n\nexport function slugToHref(slug: FullSlug | string): string {\n const simple = simplifySlug(slug).toString();\n return simple ? `/${simple}` : \"/\";\n}\n\nexport function hrefToSlug(href: string): FullSlug {\n const normalized = normalizePath(href.split(\"#\")[0] ?? \"\");\n return asFullSlug(normalized === \"\" ? \"index\" : normalized);\n}\n\nexport function pathToRoot(slug: FullSlug | string): RelativeURL {\n const simple = simplifySlug(slug).toString();\n const depth = simple ? simple.split(\"/\").length - 1 : 0;\n return asRelativeURL(depth === 0 ? \".\" : Array(depth).fill(\"..\").join(\"/\"));\n}\n\nexport function resolveRelative(\n currentSlug: FullSlug | string,\n target: string,\n options: SlugifyOptions = {},\n): FullSlug {\n const currentDir = normalizePath(currentSlug)\n .split(\"/\")\n .slice(0, -1)\n .join(\"/\");\n return asFullSlug(\n normalizeSlug(path.posix.join(currentDir, target), options),\n );\n}\n\nexport function resolveWikiLink(\n currentSlug: FullSlug | string,\n target: string,\n allSlugs: readonly string[],\n strategy: \"absolute\" | \"relative\" | \"shortest\" = \"shortest\",\n options: SlugifyOptions = {},\n): FullSlug | undefined {\n const [rawPath] = target.split(\"#\");\n const normalizedTarget = normalizeSlug(rawPath ?? target, options);\n const candidates = new Set(allSlugs.map((slug) => normalizeSlug(slug)));\n\n if (strategy === \"absolute\" && candidates.has(normalizedTarget))\n return asFullSlug(normalizedTarget);\n\n if (strategy === \"relative\") {\n const relative = resolveRelative(currentSlug, normalizedTarget, options);\n if (candidates.has(relative)) return relative;\n }\n\n if (candidates.has(normalizedTarget)) return asFullSlug(normalizedTarget);\n if (candidates.has(`${normalizedTarget}/index`))\n return asFullSlug(`${normalizedTarget}/index`);\n\n const byBasename = [...candidates].filter((slug) => {\n const simplified = simplifySlug(slug).toString();\n return simplified.split(\"/\").at(-1) === normalizedTarget.split(\"/\").at(-1);\n });\n\n return byBasename.length === 1 ? asFullSlug(byBasename[0]!) : undefined;\n}\n\nexport function joinSegments(...segments: string[]): string {\n return normalizePath(segments.filter(Boolean).join(\"/\"));\n}\n\nfunction numericPrefixSortSegment(segment: string): string {\n const match = NUMERIC_PREFIX_RE.exec(segment);\n if (!match) {\n return `${UNORDERED_SEGMENT_SORT_PREFIX}:${slugifySegment(segment)}`;\n }\n\n const order = match[1]!.padStart(10, \"0\");\n return `${order}:${slugifySegment(match[2]!)}`;\n}\n","export type PageProperty = {\n key: string;\n label: string;\n value: string;\n};\n\nconst RESERVED_FRONTMATTER_KEYS = new Set([\n \"aliases\",\n \"alias\",\n \"created\",\n \"cssclass\",\n \"cssclasses\",\n \"date\",\n \"description\",\n \"draft\",\n \"listed\",\n \"menu_label\",\n \"modified\",\n \"permalink\",\n \"publish\",\n \"tag\",\n \"tags\",\n \"title\",\n]);\n\nexport function getMenuLabel(\n frontmatter: Record<string, unknown>,\n title: string,\n): string {\n if (\n typeof frontmatter.menu_label === \"string\" &&\n frontmatter.menu_label.trim()\n ) {\n return frontmatter.menu_label.trim();\n }\n return title;\n}\n\nexport function getPageProperties(\n frontmatter: Record<string, unknown>,\n): PageProperty[] {\n return Object.entries(frontmatter)\n .filter(([key]) => !RESERVED_FRONTMATTER_KEYS.has(key.toLowerCase()))\n .map(([key, value]) => {\n const formatted = formatPropertyValue(value);\n if (formatted === undefined) return undefined;\n return {\n key,\n label: formatPropertyLabel(key),\n value: formatted,\n };\n })\n .filter((property): property is PageProperty => property !== undefined)\n .sort((a, b) => a.key.localeCompare(b.key));\n}\n\nexport function formatPropertyLabel(key: string): string {\n return key\n .replace(/[_-]+/g, \" \")\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .toLowerCase();\n}\n\nexport function formatPropertyValue(value: unknown): string | undefined {\n if (value === null || value === undefined) return undefined;\n\n if (value instanceof Date) {\n return value.toISOString().slice(0, 10);\n }\n\n if (typeof value === \"string\") {\n const trimmed = value.trim();\n return trimmed || undefined;\n }\n\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n\n if (Array.isArray(value)) {\n const items = value\n .map((item) => formatPropertyValue(item))\n .filter((item): item is string => item !== undefined);\n return items.length ? items.join(\", \") : undefined;\n }\n\n if (typeof value === \"object\") {\n return JSON.stringify(value);\n }\n\n return String(value);\n}\n","import { normalizeTag } from \"@silicajs/remark-obsidian\";\n\nexport function tagToHref(tag: string): string {\n const normalized = normalizeTag(tag);\n if (!normalized) return \"/tags\";\n const encoded = normalized\n .split(\"/\")\n .map((segment) => encodeURIComponent(segment))\n .join(\"/\");\n return `/tags/${encoded}`;\n}\n","import matter from \"gray-matter\";\nimport { unified } from \"unified\";\nimport remarkParse from \"remark-parse\";\nimport remarkFrontmatter from \"remark-frontmatter\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport remarkRehype from \"remark-rehype\";\nimport rehypeRaw from \"rehype-raw\";\nimport rehypeSanitize, { defaultSchema } from \"rehype-sanitize\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeSlug from \"rehype-slug\";\nimport rehypeAutolinkHeadings from \"rehype-autolink-headings\";\nimport rehypeShiki from \"@shikijs/rehype\";\nimport rehypeReact from \"rehype-react\";\nimport rehypeStringify from \"rehype-stringify\";\nimport { getTags, remarkObsidian } from \"@silicajs/remark-obsidian\";\nimport { Fragment, jsx, jsxs } from \"react/jsx-runtime\";\nimport type {\n AnalyzeResult,\n RenderContext,\n RenderResult,\n TocItem,\n} from \"../types.js\";\nimport { rehypeShikiCodeBlockWrapper } from \"./code-block.js\";\nimport {\n createSilicaObsidianHandlers,\n remarkSilicaObsidian,\n} from \"./obsidian.js\";\nimport {\n getDataArray,\n rehypeCleanFootnoteHeadings,\n rehypeCollectTocAndLinks,\n rehypeExternalLinks,\n rehypeRestoreObsidianBlockIds,\n rehypeUnwrapSilicaEmbeds,\n} from \"./plugins.js\";\n\ntype MdastNode = {\n type: string;\n value?: string;\n raw?: string;\n tag?: string;\n children?: MdastNode[];\n};\n\ntype PlainTextOptions = {\n skipLeadingHeading?: boolean;\n};\n\nconst plainTextSkipTypes = new Set([\n \"code\",\n \"definition\",\n \"footnoteDefinition\",\n \"footnoteReference\",\n \"image\",\n \"imageReference\",\n \"inlineMath\",\n \"math\",\n \"obsidianBlockId\",\n \"obsidianComment\",\n \"obsidianWikiEmbed\",\n \"thematicBreak\",\n \"yaml\",\n]);\n\nconst headingLinkIcon = {\n type: \"element\",\n tagName: \"svg\",\n properties: {\n ariaHidden: \"true\",\n className: [\"silica-heading-link-icon\"],\n fill: \"none\",\n stroke: \"currentColor\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n strokeWidth: 2,\n viewBox: \"0 0 24 24\",\n },\n children: [\n {\n type: \"element\",\n tagName: \"path\",\n properties: {\n d: \"M9 17H7A5 5 0 0 1 7 7h2\",\n },\n children: [],\n },\n {\n type: \"element\",\n tagName: \"path\",\n properties: {\n d: \"M15 7h2a5 5 0 1 1 0 10h-2\",\n },\n children: [],\n },\n {\n type: \"element\",\n tagName: \"line\",\n properties: {\n x1: 8,\n x2: 16,\n y1: 12,\n y2: 12,\n },\n children: [],\n },\n ],\n} as const;\n\nconst sanitizeSchema = {\n ...defaultSchema,\n attributes: {\n ...defaultSchema.attributes,\n span: [\n ...(defaultSchema.attributes?.span ?? []),\n [\"className\", \"silica-broken-link\"],\n [\"className\", \"silica-block-id\"],\n [\"dataSilicaBlockId\"],\n [\"data-silica-block-id\"],\n [\"ariaHidden\"],\n [\"aria-hidden\"],\n ],\n sup: [\n ...(defaultSchema.attributes?.sup ?? []),\n [\"className\", \"silica-inline-footnote\"],\n ],\n img: [...(defaultSchema.attributes?.img ?? []), [\"width\"], [\"height\"]],\n audio: [[\"src\"], [\"controls\"], [\"width\"], [\"height\"]],\n video: [[\"src\"], [\"controls\"], [\"width\"], [\"height\"]],\n source: [[\"src\"], [\"type\"]],\n figure: [\n ...(defaultSchema.attributes?.figure ?? []),\n [\"className\", \"silica-embed\", \"silica-note-embed\"],\n [\"dataEmbedKind\"],\n [\"data-embed-kind\"],\n [\"dataEmbedTarget\"],\n [\"data-embed-target\"],\n ],\n strong: [\n ...(defaultSchema.attributes?.strong ?? []),\n [\"className\", \"silica-callout-title\"],\n [\"dataCallout\"],\n [\"data-callout\"],\n [\"dataCalloutFold\"],\n [\"data-callout-fold\"],\n ],\n \"silica-callout\": [\n [\"className\", \"silica-callout\"],\n [\"dataCallout\"],\n [\"data-callout\"],\n [\"dataCalloutTitle\"],\n [\"data-callout-title\"],\n [\"dataCalloutFoldable\"],\n [\"data-callout-foldable\"],\n [\"dataCalloutOpen\"],\n [\"data-callout-open\"],\n ],\n \"silica-embed\": [\n [\"src\"],\n [\"width\"],\n [\"height\"],\n [\"dataEmbedKind\"],\n [\"data-embed-kind\"],\n [\"dataEmbedTarget\"],\n [\"data-embed-target\"],\n ],\n \"silica-mermaid\": [\n [\"dataSource\"],\n [\"data-source\"],\n [\"dataLanguage\"],\n [\"data-language\"],\n [\"dataLanguageLabel\"],\n [\"data-language-label\"],\n ],\n mark: defaultSchema.attributes?.mark ?? [],\n },\n tagNames: [\n ...(defaultSchema.tagNames ?? []),\n \"mark\",\n \"audio\",\n \"video\",\n \"source\",\n \"figure\",\n \"silica-callout\",\n \"silica-embed\",\n \"silica-mermaid\",\n ],\n};\n\nexport async function renderMarkdown(\n raw: string,\n context: RenderContext,\n): Promise<RenderResult> {\n const parsed = matter(raw);\n const processor = baseProcessor(context)\n .use(rehypeUnwrapSilicaEmbeds)\n .use(rehypeRaw)\n .use(rehypeSanitize, sanitizeSchema)\n .use(rehypeRestoreObsidianBlockIds)\n .use(rehypeUnwrapSilicaEmbeds)\n .use(rehypeKatex);\n\n if (hasCodeFence(parsed.content)) {\n processor.use(rehypeShiki, {\n themes: {\n light: \"github-light\",\n dark: \"github-dark\",\n },\n defaultColor: \"light-dark()\",\n // Ensure unlabeled fences still flow through Shiki so they pick up the\n // wrapper transformer below (just without a language header).\n defaultLanguage: \"text\",\n rootStyle: false,\n transformers: [rehypeShikiCodeBlockWrapper()],\n });\n }\n\n processor\n .use(rehypeSlug)\n .use(rehypeAutolinkHeadings, {\n behavior: \"wrap\",\n content: headingLinkIcon,\n properties: { className: [\"silica-heading-link\"] },\n })\n .use(rehypeCleanFootnoteHeadings)\n .use(rehypeCollectTocAndLinks)\n .use(rehypeExternalLinks)\n .use(rehypeReact, {\n Fragment,\n jsx,\n jsxs,\n components: context.components,\n });\n\n const file = await processor.process(parsed.content);\n const toc = getDataArray<TocItem>(file.data, \"toc\");\n\n return {\n content: file.result,\n toc,\n };\n}\n\nexport async function renderMarkdownHtml(\n raw: string,\n context: RenderContext,\n): Promise<string> {\n const parsed = matter(raw);\n const processor = baseProcessor(context)\n .use(rehypeUnwrapSilicaEmbeds)\n .use(rehypeRaw)\n .use(rehypeSanitize, sanitizeSchema)\n .use(rehypeRestoreObsidianBlockIds)\n .use(rehypeUnwrapSilicaEmbeds)\n .use(rehypeKatex);\n\n if (hasCodeFence(parsed.content)) {\n processor.use(rehypeShiki, {\n themes: {\n light: \"github-light\",\n dark: \"github-dark\",\n },\n defaultColor: \"light-dark()\",\n defaultLanguage: \"text\",\n rootStyle: false,\n transformers: [rehypeShikiCodeBlockWrapper()],\n });\n }\n\n processor.use(rehypeExternalLinks).use(rehypeStringify);\n\n const file = await processor.process(parsed.content);\n return String(file);\n}\n\nexport async function analyzeMarkdown(\n raw: string,\n context: RenderContext,\n): Promise<AnalyzeResult> {\n const parsed = matter(raw);\n const inlineTags = context.tags?.inline ?? true;\n const file = await runRemarkObsidian(parsed.content, context);\n const plainText = extractPlainText(parsed.content);\n const frontmatter = parsed.data;\n const brokenLinks = getDataArray<{ target: string }>(\n file.data,\n \"silicaObsidianBrokenLinks\",\n ).map((link) => ({ source: String(context.slug), target: link.target }));\n const description = getDescription(frontmatter);\n\n return {\n frontmatter,\n links: getDataArray<string>(file.data, \"silicaObsidianLinks\"),\n brokenLinks,\n plainText,\n title: getTitle(frontmatter),\n description,\n generatedDescription: description\n ? undefined\n : generateDescriptionFromContent(parsed.content),\n tags: getTags(frontmatter, parsed.content, { inline: inlineTags }),\n };\n}\n\nexport function getTitle(\n frontmatter: Record<string, unknown>,\n): string | undefined {\n if (typeof frontmatter.title === \"string\" && frontmatter.title.trim())\n return frontmatter.title.trim();\n return undefined;\n}\n\nexport function getDescription(\n frontmatter: Record<string, unknown>,\n): string | undefined {\n if (\n typeof frontmatter.description === \"string\" &&\n frontmatter.description.trim()\n ) {\n return cleanPlainText(frontmatter.description.trim());\n }\n return undefined;\n}\n\nexport function generateDescriptionFromContent(\n markdown: string,\n maxLength = 160,\n): string | undefined {\n return cleanPlainText(markdown, maxLength, { skipLeadingHeading: true });\n}\n\nexport function getMetaDescription(\n entry: {\n description?: string;\n generatedDescription?: string;\n },\n maxLength = 160,\n): string | undefined {\n const text = entry.description ?? entry.generatedDescription;\n if (!text) return undefined;\n if (text.length <= maxLength) return text;\n return cleanPlainText(text, maxLength);\n}\n\nfunction cleanPlainText(\n text: string,\n maxLength?: number,\n options: PlainTextOptions = {},\n): string | undefined {\n const cleaned = extractPlainText(text, options).trim();\n if (!cleaned) return undefined;\n if (maxLength === undefined) return cleaned;\n const truncated = cleaned.slice(0, maxLength).trim();\n return truncated || undefined;\n}\n\nfunction baseProcessor(context: RenderContext) {\n return unified()\n .use(remarkParse)\n .use(remarkFrontmatter, [\"yaml\"])\n .use(remarkGfm)\n .use(remarkMath)\n .use(remarkObsidian, { inlineTags: context.tags?.inline ?? true })\n .use(remarkSilicaObsidian, context)\n .use(remarkRehype, {\n allowDangerousHtml: true,\n handlers: createSilicaObsidianHandlers(context),\n });\n}\n\nasync function runRemarkObsidian(markdown: string, context: RenderContext) {\n const processor = unified()\n .use(remarkParse)\n .use(remarkFrontmatter, [\"yaml\"])\n .use(remarkGfm)\n .use(remarkMath)\n .use(remarkObsidian, { inlineTags: context.tags?.inline ?? true })\n .use(remarkSilicaObsidian, context);\n const tree = processor.parse(markdown);\n const file = { data: {} };\n await processor.run(tree, file);\n return file;\n}\n\nfunction extractPlainText(\n markdown: string,\n options: PlainTextOptions = {},\n): string {\n const tree = parsePlainTextMarkdown(markdown);\n const children =\n options.skipLeadingHeading && tree.children?.[0]?.type === \"heading\"\n ? tree.children.slice(1)\n : (tree.children ?? []);\n const parts: string[] = [];\n\n for (const child of children) {\n collectPlainText(child, parts);\n }\n\n return normalizePlainText(parts.join(\" \"));\n}\n\nfunction parsePlainTextMarkdown(markdown: string): MdastNode {\n return unified()\n .use(remarkParse)\n .use(remarkFrontmatter, [\"yaml\"])\n .use(remarkGfm)\n .use(remarkMath)\n .use(remarkObsidian)\n .parse(markdown) as MdastNode;\n}\n\nfunction collectPlainText(node: MdastNode, parts: string[]): void {\n if (plainTextSkipTypes.has(node.type)) return;\n\n if (node.type === \"obsidianTag\") {\n const raw = node.raw?.replace(/^#/, \"\");\n const tag = raw || node.tag;\n if (tag) parts.push(tag);\n return;\n }\n\n if (typeof node.value === \"string\") {\n parts.push(node.value);\n }\n\n for (const child of node.children ?? []) {\n collectPlainText(child, parts);\n }\n}\n\nfunction normalizePlainText(text: string): string {\n return text\n .replace(/\\s+/g, \" \")\n .replace(/\\s+([.,;:!?])/g, \"$1\")\n .trim();\n}\n\nfunction hasCodeFence(markdown: string): boolean {\n return /(^|\\n)(```|~~~)/.test(markdown);\n}\n","import type { Element, Root } from \"hast\";\nimport type { ShikiTransformer } from \"shiki\";\n\nconst LANGUAGE_LABELS: Record<string, string> = {\n bash: \"Bash\",\n c: \"C\",\n cpp: \"C++\",\n cs: \"C#\",\n css: \"CSS\",\n diff: \"Diff\",\n docker: \"Dockerfile\",\n dockerfile: \"Dockerfile\",\n go: \"Go\",\n graphql: \"GraphQL\",\n html: \"HTML\",\n ini: \"INI\",\n java: \"Java\",\n javascript: \"JavaScript\",\n js: \"JavaScript\",\n json: \"JSON\",\n jsonc: \"JSON\",\n jsx: \"JSX\",\n kotlin: \"Kotlin\",\n less: \"Less\",\n lua: \"Lua\",\n markdown: \"Markdown\",\n md: \"Markdown\",\n mdx: \"MDX\",\n objc: \"Objective-C\",\n php: \"PHP\",\n ps: \"PowerShell\",\n ps1: \"PowerShell\",\n powershell: \"PowerShell\",\n py: \"Python\",\n python: \"Python\",\n r: \"R\",\n rb: \"Ruby\",\n ruby: \"Ruby\",\n rs: \"Rust\",\n rust: \"Rust\",\n scala: \"Scala\",\n scss: \"SCSS\",\n sh: \"Shell\",\n shell: \"Shell\",\n sql: \"SQL\",\n svelte: \"Svelte\",\n swift: \"Swift\",\n toml: \"TOML\",\n ts: \"TypeScript\",\n tsx: \"TSX\",\n typescript: \"TypeScript\",\n vue: \"Vue\",\n xml: \"XML\",\n yaml: \"YAML\",\n yml: \"YAML\",\n zig: \"Zig\",\n zsh: \"Zsh\",\n};\n\nconst HIDDEN_LANGUAGES = new Set([\n \"\",\n \"text\",\n \"plain\",\n \"plaintext\",\n \"txt\",\n \"ansi\",\n]);\n\nfunction formatLanguage(lang: string | undefined): string | null {\n if (!lang) return null;\n const lower = lang.toLowerCase();\n if (HIDDEN_LANGUAGES.has(lower)) return null;\n return LANGUAGE_LABELS[lower] ?? lang;\n}\n\n/**\n * Wraps every Shiki-rendered `<pre>` in a semantic custom element. Shiki keeps\n * owning highlighting, while themes can map the element to their code chrome.\n */\nexport function rehypeShikiCodeBlockWrapper(): ShikiTransformer {\n return {\n name: \"silica:code-block-wrapper\",\n root(hast: Root): Root {\n const pre = hast.children.find(\n (child): child is Element =>\n child.type === \"element\" && child.tagName === \"pre\",\n );\n if (!pre) return hast;\n\n const rawLang =\n typeof this.options.lang === \"string\" ? this.options.lang : undefined;\n const label = formatLanguage(rawLang);\n const isMermaid = rawLang?.toLowerCase() === \"mermaid\";\n\n const wrapper: Element = {\n type: \"element\",\n tagName: isMermaid ? \"silica-mermaid\" : \"silica-code-block\",\n properties: {\n ...(rawLang ? { \"data-language\": rawLang } : {}),\n ...(isMermaid ? { \"data-source\": toText(pre) } : {}),\n ...(label ? { \"data-language-label\": label } : {}),\n },\n children: [pre],\n };\n\n hast.children = [wrapper];\n return hast;\n },\n };\n}\n\nfunction toText(node: Element): string {\n return node.children\n .map((child) => {\n if (child.type === \"text\") return child.value;\n if (child.type === \"element\") return toText(child);\n return \"\";\n })\n .join(\"\");\n}\n","import { visit } from \"unist-util-visit\";\nimport type {\n ObsidianBlockId,\n ObsidianCallout,\n ObsidianComment,\n ObsidianEmbedSize,\n ObsidianHighlight,\n ObsidianInlineFootnote,\n ObsidianTag,\n ObsidianWikiEmbed,\n ObsidianWikilink,\n} from \"@silicajs/remark-obsidian\";\nimport type { Nodes, PhrasingContent, Root, RootContent } from \"mdast\";\nimport type { Properties } from \"hast\";\nimport { slug as slugifyHeading } from \"github-slugger\";\nimport { tagToHref } from \"../tags.js\";\nimport { resolveWikiLink, slugToHref } from \"../path.js\";\nimport type { RenderContext } from \"../types.js\";\n\ndeclare module \"mdast\" {\n interface Data {\n silicaBroken?: boolean;\n silicaResolvedSlug?: string;\n silicaEmbedHtml?: string;\n hProperties?: Properties;\n }\n}\n\ntype VFileLike = {\n data: Record<string, unknown>;\n};\n\ntype SilicaMdastNode = Nodes;\n\ntype MdastParent = Extract<Nodes, { children: unknown[] }>;\n\ntype HastNode = {\n type: \"element\" | \"text\" | \"raw\";\n tagName?: string;\n value?: string;\n properties?: Record<string, unknown>;\n children?: HastNode[];\n};\n\ntype HandlerState = {\n all: (node: Nodes) => HastNode[];\n};\n\nexport function remarkSilicaObsidian(context: RenderContext) {\n return async (tree: Root, file: VFileLike) => {\n const links = new Set<string>();\n const brokenLinks: Array<{ target: string }> = [];\n const assetBaseUrl = context.assetBaseUrl ?? \"/silica\";\n const embedPromises: Array<Promise<void>> = [];\n\n transformInlineFootnotes(tree);\n\n visit(tree, (node: SilicaMdastNode) => {\n if (node.type === \"image\" && typeof node.url === \"string\") {\n node.url = rewriteAssetUrl(node.url, assetBaseUrl);\n applyImageSize(node);\n return;\n }\n\n if (!isWikiNode(node)) return;\n if (node.type === \"obsidianWikiEmbed\" && !isAssetTarget(node.rawTarget)) {\n embedPromises.push(resolveEmbedNode(node, context));\n }\n\n const targetPath = node.linkTarget.path || String(context.slug);\n if (node.type === \"obsidianWikiEmbed\" && isAssetTarget(node.rawTarget)) {\n return;\n }\n\n const resolved = resolveWikiLink(\n context.slug,\n targetPath,\n context.allSlugs,\n context.wikilinkStrategy ?? \"shortest\",\n context.ordering,\n );\n\n node.data = { ...node.data };\n if (!resolved) {\n node.data.silicaBroken = true;\n brokenLinks.push({ target: node.rawTarget });\n return;\n }\n\n node.data.silicaResolvedSlug = resolved;\n links.add(resolved);\n });\n\n await Promise.all(embedPromises);\n file.data.silicaObsidianLinks = [...links];\n file.data.silicaObsidianBrokenLinks = brokenLinks;\n };\n}\n\nexport function createSilicaObsidianHandlers(context: RenderContext) {\n return {\n obsidianWikilink(\n state: HandlerState,\n node: ObsidianWikilink & { data?: Record<string, unknown> },\n ) {\n return wikilinkToHast(state, node);\n },\n obsidianWikiEmbed(\n state: HandlerState,\n node: ObsidianWikiEmbed & { data?: Record<string, unknown> },\n ) {\n if (node.rawTarget && isAssetTarget(node.rawTarget)) {\n return assetEmbedToHast(context, node);\n }\n const embedHtml = getStringData(node, \"silicaEmbedHtml\");\n if (embedHtml) {\n return {\n type: \"element\",\n tagName: \"figure\",\n properties: {\n className: [\"silica-embed\", \"silica-note-embed\"],\n \"data-embed-kind\": \"note\",\n \"data-embed-target\": node.rawTarget,\n },\n children: [{ type: \"raw\", value: embedHtml }],\n };\n }\n return wikilinkToHast(state, node);\n },\n obsidianHighlight(state: HandlerState, node: ObsidianHighlight) {\n return {\n type: \"element\",\n tagName: \"mark\",\n properties: {},\n children: state.all(node),\n };\n },\n obsidianCallout(state: HandlerState, node: ObsidianCallout) {\n return {\n type: \"element\",\n tagName: \"silica-callout\",\n properties: {\n className: [\"silica-callout\"],\n \"data-callout\": node.kind ?? \"note\",\n \"data-callout-title\": node.title ?? titleCase(node.kind ?? \"note\"),\n ...(node.fold\n ? {\n \"data-callout-foldable\": \"true\",\n \"data-callout-open\": node.fold === \"open\" ? \"true\" : \"false\",\n }\n : {}),\n },\n children: state.all(node),\n };\n },\n obsidianTag(state: HandlerState, node: ObsidianTag) {\n return {\n type: \"element\",\n tagName: \"a\",\n properties: { href: tagToHref(node.tag ?? \"\") },\n children: state.all(node),\n };\n },\n obsidianComment(_state: HandlerState, _node: ObsidianComment) {\n return { type: \"text\", value: \"\" };\n },\n obsidianBlockId(_state: HandlerState, node: ObsidianBlockId) {\n return {\n type: \"element\",\n tagName: \"span\",\n properties: {\n id: `^${node.id}`,\n className: [\"silica-block-id\"],\n \"data-silica-block-id\": node.id,\n ariaHidden: \"true\",\n },\n children: [],\n };\n },\n };\n}\n\nfunction transformInlineFootnotes(tree: Root) {\n const definitions: RootContent[] = [];\n let nextIndex = 1;\n\n visit(\n tree,\n \"obsidianInlineFootnote\",\n (node: ObsidianInlineFootnote, index, parent: MdastParent | undefined) => {\n if (index === undefined || !parent) return;\n const identifier = `obsidian-inline-${nextIndex++}`;\n parent.children[index] = {\n type: \"footnoteReference\",\n identifier,\n label: identifier,\n } as PhrasingContent;\n definitions.push({\n type: \"footnoteDefinition\",\n identifier,\n label: identifier,\n children: [\n {\n type: \"paragraph\",\n children: node.children.length\n ? node.children\n : [{ type: \"text\", value: node.value }],\n },\n ],\n } as RootContent);\n },\n );\n\n tree.children.push(...definitions);\n}\n\nfunction wikilinkToHast(\n _state: HandlerState,\n node: (ObsidianWikilink | ObsidianWikiEmbed) & {\n data?: Record<string, unknown>;\n },\n): HastNode {\n const label = node.alias || node.target || \"\";\n const resolved = getResolvedSlug(node);\n if (!resolved) {\n return {\n type: \"element\",\n tagName: \"span\",\n properties: { className: [\"silica-broken-link\"] },\n children: [{ type: \"text\", value: label }],\n };\n }\n\n return {\n type: \"element\",\n tagName: \"a\",\n properties: { href: `${slugToHref(resolved)}${targetFragment(node)}` },\n children: [{ type: \"text\", value: label }],\n };\n}\n\nfunction isWikiNode(node: SilicaMdastNode): node is (\n | ObsidianWikilink\n | ObsidianWikiEmbed\n) & {\n data?: Record<string, unknown>;\n} {\n return (\n (node.type === \"obsidianWikilink\" || node.type === \"obsidianWikiEmbed\") &&\n typeof node.rawTarget === \"string\"\n );\n}\n\nfunction getResolvedSlug(node: SilicaMdastNode): string | undefined {\n const value = node.data?.silicaResolvedSlug;\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction getStringData(node: SilicaMdastNode, key: string): string | undefined {\n const value = (node.data as Record<string, unknown> | undefined)?.[key];\n return typeof value === \"string\" ? value : undefined;\n}\n\nasync function resolveEmbedNode(\n node: ObsidianWikiEmbed & { data?: Record<string, unknown> },\n context: RenderContext,\n): Promise<void> {\n if (!context.resolveEmbed) return;\n const maxDepth = context.maxEmbedDepth ?? 3;\n const depth = context.embedDepth ?? 0;\n if (depth >= maxDepth) return;\n const html = await context.resolveEmbed(node.linkTarget);\n if (!html) return;\n node.data = {\n ...node.data,\n silicaEmbedHtml: html,\n };\n}\n\nfunction assetEmbedToHast(\n context: RenderContext,\n node: ObsidianWikiEmbed,\n): HastNode {\n const kind = assetKind(node.rawTarget);\n const src = assetUrl(context.assetBaseUrl ?? \"/silica\", node.rawTarget);\n const label =\n node.alias || node.rawTarget.split(\"/\").at(-1) || node.rawTarget;\n const dimensions = sizeProperties(\n node.embedSize ?? sizeFromParams(node.linkTarget.params),\n );\n\n if (kind === \"image\") {\n return {\n type: \"element\",\n tagName: \"img\",\n properties: {\n src,\n alt: label,\n ...dimensions,\n },\n children: [],\n };\n }\n\n if (kind === \"audio\" || kind === \"video\") {\n return {\n type: \"element\",\n tagName: kind,\n properties: {\n src,\n controls: true,\n ...dimensions,\n },\n children: [],\n };\n }\n\n return {\n type: \"element\",\n tagName: \"silica-embed\",\n properties: {\n src,\n \"data-embed-kind\": kind,\n \"data-embed-target\": node.rawTarget,\n ...dimensions,\n },\n children: [{ type: \"text\", value: label }],\n };\n}\n\nfunction targetFragment(node: ObsidianWikilink | ObsidianWikiEmbed): string {\n if (node.linkTarget.blockId) {\n return `#^${encodeURIComponent(node.linkTarget.blockId)}`;\n }\n if (node.linkTarget.heading) {\n return `#${slugifyHeading(node.linkTarget.heading)}`;\n }\n return \"\";\n}\n\nfunction applyImageSize(node: SilicaMdastNode) {\n const size = node.data?.obsidianEmbedSize as ObsidianEmbedSize | undefined;\n if (!size) return;\n node.data = {\n ...node.data,\n hProperties: {\n ...(node.data?.hProperties ?? {}),\n ...sizeProperties(size),\n },\n };\n}\n\nfunction sizeFromParams(\n params: Record<string, string> | undefined,\n): ObsidianEmbedSize | undefined {\n const height = Number(params?.height);\n if (!Number.isFinite(height) || height <= 0) return;\n return { width: 0, height };\n}\n\nfunction sizeProperties(size: ObsidianEmbedSize | undefined) {\n if (!size) return {};\n return {\n ...(size.width > 0 ? { width: size.width } : {}),\n ...(size.height ? { height: size.height } : {}),\n };\n}\n\nfunction rewriteAssetUrl(url: string, assetBaseUrl: string): string {\n if (!isAssetTarget(url)) return url;\n if (/^(?:https?:|#|\\/)/.test(url)) return url;\n return `${assetBaseUrl}/${url.replace(/^\\.?\\//, \"\")}`;\n}\n\nfunction isAssetTarget(target: string): boolean {\n return /\\.(png|jpe?g|gif|webp|svg|pdf|mp4|mov|mp3|wav|ogg|canvas)(?:[?#].*)?$/i.test(\n target,\n );\n}\n\nfunction isImageTarget(target: string): boolean {\n return /\\.(png|jpe?g|gif|webp|svg)(?:[?#].*)?$/i.test(target);\n}\n\nfunction assetKind(\n target: string,\n): \"image\" | \"audio\" | \"video\" | \"pdf\" | \"canvas\" | \"file\" {\n if (isImageTarget(target)) return \"image\";\n if (/\\.(mp3|wav|ogg)(?:[?#].*)?$/i.test(target)) return \"audio\";\n if (/\\.(mp4|mov)(?:[?#].*)?$/i.test(target)) return \"video\";\n if (/\\.pdf(?:[?#].*)?$/i.test(target)) return \"pdf\";\n if (/\\.canvas(?:[?#].*)?$/i.test(target)) return \"canvas\";\n return \"file\";\n}\n\nfunction assetUrl(assetBaseUrl: string, target: string): string {\n const cleaned = stripEmbedOnlyParams(target);\n if (/^(?:https?:|#|\\/)/.test(cleaned)) return cleaned;\n return `${assetBaseUrl}/${cleaned.replace(/^\\/+/, \"\")}`;\n}\n\nfunction stripEmbedOnlyParams(target: string): string {\n const hashIndex = target.indexOf(\"#\");\n if (hashIndex === -1) return target;\n const before = target.slice(0, hashIndex);\n const fragment = target.slice(hashIndex + 1);\n if (!fragment.includes(\"=\")) return target;\n const params = new URLSearchParams(fragment);\n params.delete(\"height\");\n const remaining = params.toString();\n return remaining ? `${before}#${remaining}` : before;\n}\n\nfunction titleCase(value: string): string {\n return value\n .split(/[-_\\s]+/)\n .filter(Boolean)\n .map((part) => part[0]!.toUpperCase() + part.slice(1))\n .join(\" \");\n}\n","import Slugger from \"github-slugger\";\nimport { toString } from \"hast-util-to-string\";\nimport { visit } from \"unist-util-visit\";\nimport type { BrokenLink, TocItem } from \"../types.js\";\nimport { hrefToSlug } from \"../path.js\";\n\ntype VFileLike = {\n data: Record<string, unknown>;\n};\n\ntype HastNode = {\n type: string;\n tagName?: string;\n value?: string;\n properties?: Record<string, unknown>;\n children?: HastNode[];\n};\n\nexport function rehypeCollectTocAndLinks() {\n return (tree: HastNode, file: VFileLike) => {\n const toc: TocItem[] = [];\n const links = new Set<string>();\n const slugger = new Slugger();\n\n visit(tree, \"element\", (node: HastNode) => {\n if (isHeading(node)) {\n const text = toString(node as never);\n const id = String(node.properties?.id ?? slugger.slug(text));\n node.properties = { ...node.properties, id };\n if (id !== \"footnote-label\") {\n toc.push({ id, text, depth: Number(node.tagName?.slice(1) ?? 2) });\n }\n }\n\n if (node.tagName === \"a\" && typeof node.properties?.href === \"string\") {\n const href = node.properties.href;\n if (href.startsWith(\"/\") && !href.startsWith(\"/silica/\")) {\n links.add(hrefToSlug(href));\n }\n }\n });\n\n file.data.toc = toc;\n file.data.links = [...links];\n };\n}\n\nexport function rehypeCleanFootnoteHeadings() {\n return (tree: HastNode) => {\n visit(tree, \"element\", (node: HastNode) => {\n if (node.properties?.id !== \"footnote-label\") return;\n const child = node.children?.[0];\n if (child?.tagName !== \"a\") return;\n node.children = child.children ?? [];\n });\n };\n}\n\nexport function rehypeExternalLinks() {\n return (tree: HastNode) => {\n visit(tree, \"element\", (node: HastNode) => {\n if (node.tagName !== \"a\" || typeof node.properties?.href !== \"string\")\n return;\n if (!/^https?:\\/\\//.test(node.properties.href)) return;\n node.properties = {\n ...node.properties,\n rel: \"noreferrer noopener\",\n target: \"_blank\",\n };\n });\n };\n}\n\nexport function rehypeUnwrapSilicaEmbeds() {\n return (tree: HastNode) => {\n unwrapStandaloneEmbeds(tree);\n };\n}\n\nexport function rehypeRestoreObsidianBlockIds() {\n return (tree: HastNode) => {\n restoreGeneratedFootnoteIds(tree);\n\n visit(tree, \"element\", (node: HastNode) => {\n if (node.tagName !== \"span\") return;\n const blockId = getStringProperty(\n node,\n \"dataSilicaBlockId\",\n \"data-silica-block-id\",\n );\n if (!blockId) return;\n node.properties = { ...node.properties, id: `^${blockId}` };\n });\n };\n}\n\nexport function getDataArray<T>(\n data: Record<string, unknown>,\n key: string,\n): T[] {\n const value = data[key];\n return Array.isArray(value) ? (value as T[]) : [];\n}\n\nexport function mergeBrokenLinks(\n a: BrokenLink[],\n b: BrokenLink[],\n): BrokenLink[] {\n const seen = new Set<string>();\n const merged: BrokenLink[] = [];\n for (const item of [...a, ...b]) {\n const key = `${item.source}\\0${item.target}`;\n if (seen.has(key)) continue;\n seen.add(key);\n merged.push(item);\n }\n return merged;\n}\n\nfunction isHeading(node: HastNode): boolean {\n return node.type === \"element\" && /^h[1-6]$/.test(node.tagName ?? \"\");\n}\n\nfunction getStringProperty(\n node: HastNode,\n camelCaseKey: string,\n kebabCaseKey: string,\n): string | undefined {\n const value =\n node.properties?.[camelCaseKey] ?? node.properties?.[kebabCaseKey];\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction restoreGeneratedFootnoteIds(node: HastNode, inFootnotes = false) {\n const isFootnotes = inFootnotes || isFootnotesSection(node);\n if (isFootnotes || isFootnoteReference(node)) {\n normalizeGeneratedFootnoteProperties(node);\n }\n\n for (const child of node.children ?? []) {\n restoreGeneratedFootnoteIds(child, isFootnotes);\n }\n}\n\nfunction normalizeGeneratedFootnoteProperties(node: HastNode) {\n if (!node.properties) return;\n normalizeProperty(node, \"id\");\n normalizeProperty(node, \"href\");\n normalizeProperty(node, \"ariaDescribedBy\");\n normalizeProperty(node, \"aria-describedby\");\n}\n\nfunction normalizeProperty(node: HastNode, key: string) {\n const value = node.properties?.[key];\n if (typeof value !== \"string\") return;\n node.properties = {\n ...node.properties,\n [key]: normalizeGeneratedFootnoteReference(value),\n };\n}\n\nfunction normalizeGeneratedFootnoteReference(value: string): string {\n const prefix = value.startsWith(\"#\") ? \"#\" : \"\";\n const id = prefix ? value.slice(1) : value;\n if (id === \"user-content-footnote-label\") return `${prefix}footnote-label`;\n if (id.startsWith(\"user-content-user-content-fn\")) {\n return `${prefix}${id.replace(/^user-content-/, \"\")}`;\n }\n return value;\n}\n\nfunction isFootnotesSection(node: HastNode): boolean {\n return (\n node.tagName === \"section\" &&\n hasProperty(node, \"dataFootnotes\", \"data-footnotes\")\n );\n}\n\nfunction isFootnoteReference(node: HastNode): boolean {\n return (\n node.tagName === \"a\" &&\n hasProperty(node, \"dataFootnoteRef\", \"data-footnote-ref\")\n );\n}\n\nfunction hasProperty(\n node: HastNode,\n camelCaseKey: string,\n kebabCaseKey: string,\n): boolean {\n return (\n node.properties?.[camelCaseKey] !== undefined ||\n node.properties?.[kebabCaseKey] !== undefined\n );\n}\n\nfunction unwrapStandaloneEmbeds(parent: HastNode) {\n if (!parent.children) return;\n\n parent.children = parent.children.map((child) => {\n unwrapStandaloneEmbeds(child);\n if (child.tagName !== \"p\") return child;\n\n const renderedChildren = child.children?.filter(\n (candidate) => !isWhitespaceText(candidate),\n );\n const onlyChild = renderedChildren?.[0];\n if (renderedChildren?.length === 1 && isStandaloneEmbed(onlyChild)) {\n return onlyChild;\n }\n return child;\n });\n}\n\nfunction isStandaloneEmbed(node: HastNode | undefined): node is HastNode {\n if (node?.tagName === \"silica-embed\") return true;\n if (node?.tagName !== \"figure\") return false;\n const kind =\n node.properties?.dataEmbedKind ?? node.properties?.[\"data-embed-kind\"];\n return kind === \"note\";\n}\n\nfunction isWhitespaceText(node: HastNode): boolean {\n return node.type === \"text\" && /^\\s*$/.test(node.value ?? \"\");\n}\n"],"mappings":"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","names":["visit","visit"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { j as SilicaConfig, g as ResolvedSilicaConfig, P as PrecomputeResult } from './theme-
|
|
2
|
-
export { A as AnalyzeResult, B as BrokenLink, F as FilePath, a as FullSlug, G as Graph, M as Manifest, b as ManifestEntry, c as MarkdownComponents, N as Navigation, d as NavigationEntry, R as RelativeURL, e as RenderContext, f as RenderResult, S as SilicaAuthConfig, h as SilicaCalloutProps, i as SilicaCodeBlockProps, k as SilicaEmbedProps, l as SilicaMermaidProps, m as SilicaTheme, n as SimpleSlug, T as ThemeBacklink, o as ThemeBreadcrumb, p as ThemeConfig, q as ThemeLayoutConfig, r as ThemePage, s as ThemePageProps, t as ThemeProviderComponent, u as ThemeRootLayoutProps, v as ThemeSiteLayoutProps, w as TocItem, x as asFilePath, y as asFullSlug, z as asRelativeURL, C as asSimpleSlug, D as hrefToSlug, E as joinSegments, H as normalizePath, I as normalizeSlug, J as pathToRoot, K as resolveRelative, L as resolveWikiLink, O as simplifySlug, Q as slugToHref, U as slugifyFilePath, V as slugifySegment } from './theme-
|
|
1
|
+
import { j as SilicaConfig, g as ResolvedSilicaConfig, P as PrecomputeResult } from './theme-DF-R1di4.js';
|
|
2
|
+
export { A as AnalyzeResult, B as BrokenLink, F as FilePath, a as FullSlug, G as Graph, M as Manifest, b as ManifestEntry, c as MarkdownComponents, N as Navigation, d as NavigationEntry, R as RelativeURL, e as RenderContext, f as RenderResult, S as SilicaAuthConfig, h as SilicaCalloutProps, i as SilicaCodeBlockProps, k as SilicaEmbedProps, l as SilicaMermaidProps, m as SilicaTheme, n as SimpleSlug, T as ThemeBacklink, o as ThemeBreadcrumb, p as ThemeConfig, q as ThemeLayoutConfig, r as ThemePage, s as ThemePageProps, t as ThemeProviderComponent, u as ThemeRootLayoutProps, v as ThemeSiteLayoutProps, w as TocItem, x as asFilePath, y as asFullSlug, z as asRelativeURL, C as asSimpleSlug, D as hrefToSlug, E as joinSegments, H as normalizePath, I as normalizeSlug, J as pathToRoot, K as resolveRelative, L as resolveWikiLink, O as simplifySlug, Q as slugToHref, U as slugifyFilePath, V as slugifySegment } from './theme-DF-R1di4.js';
|
|
3
3
|
export { PageProperty, analyzeMarkdown, formatPropertyLabel, formatPropertyValue, generateDescriptionFromContent, getDescription, getMenuLabel, getMetaDescription, getPageProperties, getTitle, renderMarkdown, renderMarkdownHtml, tagToHref } from './runtime.js';
|
|
4
4
|
import 'react';
|
|
5
5
|
import '@silicajs/search';
|
package/dist/index.js
CHANGED
|
@@ -27,8 +27,9 @@ import {
|
|
|
27
27
|
slugToHref,
|
|
28
28
|
slugifyFilePath,
|
|
29
29
|
slugifySegment,
|
|
30
|
+
stripNumericPrefix,
|
|
30
31
|
tagToHref
|
|
31
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-7KWXP3FM.js";
|
|
32
33
|
|
|
33
34
|
// src/config.ts
|
|
34
35
|
import path from "path";
|
|
@@ -209,7 +210,7 @@ async function precompute(options = {}) {
|
|
|
209
210
|
tags: config.tags,
|
|
210
211
|
ordering: config.ordering
|
|
211
212
|
});
|
|
212
|
-
const title = analysis.title ??
|
|
213
|
+
const title = analysis.title ?? titleFromFilePath(file.relativePath, config.ordering);
|
|
213
214
|
const menuLabel = getMenuLabel(file.frontmatter, title);
|
|
214
215
|
const sortKey = config.ordering.numericPrefixes && hasNumericPrefixInPath(file.relativePath) ? numericPrefixSortKey(file.relativePath) : void 0;
|
|
215
216
|
const entry = {
|
|
@@ -461,9 +462,10 @@ function isListedEntry(entry) {
|
|
|
461
462
|
function stringifyDate(value) {
|
|
462
463
|
return value?.toISOString();
|
|
463
464
|
}
|
|
464
|
-
function
|
|
465
|
-
const
|
|
466
|
-
|
|
465
|
+
function titleFromFilePath(relativePath, ordering) {
|
|
466
|
+
const stem = path3.posix.basename(normalizeGitPath(relativePath)).replace(/\.(md|markdown|mdx)$/i, "");
|
|
467
|
+
const title = ordering.numericPrefixes ? stripNumericPrefix(stem) : stem;
|
|
468
|
+
return /^index$/i.test(title) ? "Home" : title;
|
|
467
469
|
}
|
|
468
470
|
export {
|
|
469
471
|
analyzeMarkdown,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts","../src/logo.ts","../src/files.ts","../src/precompute.ts"],"sourcesContent":["import path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { createJiti } from \"jiti\";\nimport { resolvePublicAssetPath } from \"./logo.js\";\nimport type { ResolvedSilicaConfig, SilicaConfig } from \"./types.js\";\n\nexport function defineConfig(config: SilicaConfig): SilicaConfig {\n return config;\n}\n\nexport async function loadConfig(\n projectRoot = process.cwd(),\n): Promise<ResolvedSilicaConfig> {\n const configPath = path.join(projectRoot, \"silica.config.ts\");\n const jsConfigPath = path.join(projectRoot, \"silica.config.js\");\n const configFile = existsSync(configPath)\n ? configPath\n : existsSync(jsConfigPath)\n ? jsConfigPath\n : undefined;\n\n let userConfig: SilicaConfig = {};\n if (configFile) {\n const jiti = createJiti(projectRoot, { interopDefault: true });\n const loaded = await jiti.import<SilicaConfig | { default: SilicaConfig }>(\n configFile,\n );\n userConfig = \"default\" in loaded ? loaded.default : loaded;\n }\n\n return resolveConfig(userConfig, projectRoot);\n}\n\nexport function resolveConfig(\n config: SilicaConfig = {},\n projectRoot = process.cwd(),\n): ResolvedSilicaConfig {\n const auth = config.auth === false ? undefined : config.auth;\n const authEnabled = Boolean(\n auth?.enabled ??\n auth?.provider ??\n auth?.allowedDomains?.length ??\n auth?.allowedEmails?.length,\n );\n const allowedDomains = auth?.allowedDomains ?? [];\n const allowedEmails = auth?.allowedEmails ?? [];\n\n if (\n authEnabled &&\n allowedDomains.length === 0 &&\n allowedEmails.length === 0\n ) {\n throw new Error(\n \"Silica auth requires at least one allowedDomains or allowedEmails entry.\",\n );\n }\n\n return {\n projectRoot,\n title: config.title ?? \"Silica\",\n description: config.description ?? \"A Silica knowledge site\",\n logo: resolvePublicAssetPath(config.logo),\n baseUrl: config.baseUrl,\n contentDir: config.contentDir ?? \"content\",\n theme: config.theme ?? \"default\",\n auth: authEnabled\n ? {\n provider: auth?.provider ?? \"google\",\n enabled: true,\n allowedDomains,\n allowedEmails,\n }\n : undefined,\n wikilinks: {\n strategy: config.wikilinks?.strategy ?? \"shortest\",\n strict: config.wikilinks?.strict ?? false,\n },\n tags: {\n inline: config.tags?.inline ?? true,\n },\n ordering: {\n numericPrefixes: config.ordering?.numericPrefixes ?? true,\n },\n filters: {\n removeDrafts: config.filters?.removeDrafts ?? true,\n explicitPublish: config.filters?.explicitPublish ?? false,\n },\n };\n}\n","/** Normalize a public asset path or pass through absolute URLs. */\nexport function resolvePublicAssetPath(asset?: string): string | undefined {\n const trimmed = asset?.trim();\n if (!trimmed) return undefined;\n if (trimmed.startsWith(\"http://\") || trimmed.startsWith(\"https://\")) {\n return trimmed;\n }\n return trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`;\n}\n","import path from \"node:path\";\nimport fg from \"fast-glob\";\nimport fs from \"fs-extra\";\nimport matter from \"gray-matter\";\nimport type { ResolvedSilicaConfig } from \"./types.js\";\nimport { asFilePath, slugifyFilePath } from \"./path.js\";\n\nexport type ContentMarkdownFile = {\n absolutePath: string;\n relativePath: string;\n slug: string;\n raw: string;\n body: string;\n frontmatter: Record<string, unknown>;\n stats: {\n birthtime?: Date;\n mtime?: Date;\n };\n};\n\nexport type ContentAssetFile = {\n absolutePath: string;\n relativePath: string;\n};\n\nexport type ContentScan = {\n markdown: ContentMarkdownFile[];\n assets: ContentAssetFile[];\n};\n\nexport async function scanContent(\n projectRoot: string,\n config: ResolvedSilicaConfig,\n): Promise<ContentScan> {\n const contentRoot = path.join(projectRoot, config.contentDir);\n const realContentRoot = await fs.realpath(contentRoot);\n const entries = await fg(\"**/*\", {\n cwd: contentRoot,\n dot: false,\n followSymbolicLinks: false,\n onlyFiles: true,\n unique: true,\n });\n\n const markdown: ContentMarkdownFile[] = [];\n const assets: ContentAssetFile[] = [];\n\n for (const relativePath of entries.sort()) {\n const absolutePath = path.join(contentRoot, relativePath);\n const stats = await fs.lstat(absolutePath);\n if (!stats.isFile()) continue;\n if (!(await isWithinRoot(absolutePath, realContentRoot))) continue;\n\n if (isMarkdownFile(relativePath)) {\n const raw = await fs.readFile(absolutePath, \"utf8\");\n const parsed = matter(raw);\n markdown.push({\n absolutePath,\n relativePath: relativePath.replace(/\\\\/g, \"/\"),\n slug: slugifyFilePath(\n asFilePath(relativePath),\n config.contentDir,\n config.ordering,\n ),\n raw,\n body: parsed.content,\n frontmatter: parsed.data,\n stats: {\n birthtime: stats.birthtime,\n mtime: stats.mtime,\n },\n });\n } else {\n assets.push({\n absolutePath,\n relativePath: relativePath.replace(/\\\\/g, \"/\"),\n });\n }\n }\n\n return { markdown, assets };\n}\n\nasync function isWithinRoot(\n absolutePath: string,\n realRoot: string,\n): Promise<boolean> {\n const realPath = await fs.realpath(absolutePath);\n const relative = path.relative(realRoot, realPath);\n return (\n relative === \"\" ||\n (!relative.startsWith(\"..\") && !path.isAbsolute(relative))\n );\n}\n\nexport function isMarkdownFile(filePath: string): boolean {\n return /\\.(md|markdown|mdx)$/i.test(filePath);\n}\n","import crypto from \"node:crypto\";\nimport { execFile } from \"node:child_process\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport fs from \"fs-extra\";\nimport {\n buildSearchDatabase,\n SEARCH_DATABASE_FILENAME,\n type SearchRecord,\n} from \"@silicajs/search\";\nimport { loadConfig } from \"./config.js\";\nimport { scanContent, type ContentMarkdownFile } from \"./files.js\";\nimport {\n asFullSlug,\n hasNumericPrefixInPath,\n numericPrefixSortKey,\n slugToHref,\n} from \"./path.js\";\nimport { getMenuLabel } from \"./pipeline/frontmatter.js\";\nimport { analyzeMarkdown } from \"./pipeline/index.js\";\nimport type {\n BrokenLink,\n Graph,\n Manifest,\n ManifestEntry,\n Navigation,\n PrecomputeResult,\n ResolvedSilicaConfig,\n} from \"./types.js\";\n\nconst execFileAsync = promisify(execFile);\n\nexport type PrecomputeOptions = {\n projectRoot?: string;\n config?: ResolvedSilicaConfig;\n};\n\nexport async function precompute(\n options: PrecomputeOptions = {},\n): Promise<PrecomputeResult> {\n const projectRoot = options.projectRoot ?? process.cwd();\n const config = options.config ?? (await loadConfig(projectRoot));\n const scan = await scanContent(projectRoot, config);\n const markdownFiles = filterPublished(scan.markdown, config);\n const allSlugs = markdownFiles.map((file) => file.slug);\n const entries: ManifestEntry[] = [];\n const graphLinks: Record<string, string[]> = {};\n const brokenLinks: BrokenLink[] = [];\n const searchRecords: SearchRecord[] = [];\n const runtimeContentRoot = path.join(projectRoot, \".silica/content\");\n const relativeGitPaths = markdownFiles.map((file) =>\n normalizeGitPath(path.join(config.contentDir, file.relativePath)),\n );\n const gitDatesByPath = await getGitDatesForFiles(\n projectRoot,\n relativeGitPaths,\n );\n\n await fs.ensureDir(path.join(projectRoot, \".silica\"));\n await fs.ensureDir(path.join(projectRoot, \".silica/next/public/silica\"));\n await writeRuntimeMarkdown(runtimeContentRoot, markdownFiles);\n\n for (const file of markdownFiles) {\n const gitDates =\n gitDatesByPath.get(\n normalizeGitPath(path.join(config.contentDir, file.relativePath)),\n ) ?? {};\n const analysis = await analyzeMarkdown(file.raw, {\n slug: asFullSlug(file.slug),\n allSlugs,\n assetBaseUrl: \"/silica\",\n wikilinkStrategy: config.wikilinks.strategy,\n tags: config.tags,\n ordering: config.ordering,\n });\n\n const title = analysis.title ?? titleFromSlug(file.slug);\n const menuLabel = getMenuLabel(file.frontmatter, title);\n const sortKey =\n config.ordering.numericPrefixes &&\n hasNumericPrefixInPath(file.relativePath)\n ? numericPrefixSortKey(file.relativePath)\n : undefined;\n const entry: ManifestEntry = {\n slug: file.slug,\n title,\n menuLabel,\n description: analysis.description,\n generatedDescription: analysis.generatedDescription,\n tags: analysis.tags,\n file: normalizeGitPath(path.join(\".silica/content\", file.relativePath)),\n relativeFile: file.relativePath,\n sortKey,\n created: stringifyDate(\n getDate(file.frontmatter.created) ??\n getDate(file.frontmatter.date) ??\n gitDates.created ??\n file.stats.birthtime,\n ),\n modified: stringifyDate(\n getDate(file.frontmatter.modified) ??\n gitDates.modified ??\n file.stats.mtime,\n ),\n frontmatter: file.frontmatter,\n };\n entries.push(entry);\n graphLinks[file.slug] = analysis.links;\n brokenLinks.push(...analysis.brokenLinks);\n if (isListedEntry(entry)) {\n searchRecords.push({\n id: file.slug,\n slug: file.slug,\n title,\n content: analysis.plainText,\n description: analysis.description,\n tags: analysis.tags,\n });\n }\n }\n\n await copyAssets(projectRoot, config, scan.assets);\n\n const manifest = makeManifest(config, entries);\n const graph = makeGraph(graphLinks, brokenLinks);\n const buildId = crypto.randomUUID();\n await buildSearchDatabase(\n searchRecords,\n path.join(projectRoot, \".silica\", SEARCH_DATABASE_FILENAME),\n );\n await fs.remove(path.join(projectRoot, \".silica/search-index.json\"));\n\n await writeJson(\n path.join(projectRoot, \".silica/manifest.json\"),\n serializeManifest(manifest),\n );\n await writeJson(\n path.join(projectRoot, \".silica/navigation.json\"),\n makeNavigation(manifest),\n );\n await writeJson(path.join(projectRoot, \".silica/graph.json\"), graph);\n await writeJson(path.join(projectRoot, \".silica/config.json\"), config);\n await fs.writeFile(\n path.join(projectRoot, \".silica/build-id.txt\"),\n `${buildId}\\n`,\n );\n await writeSitemapAndRobots(projectRoot, config, manifest);\n\n if (config.wikilinks.strict && brokenLinks.length > 0) {\n const message = brokenLinks\n .map((link) => `${link.source} -> ${link.target}`)\n .join(\"\\n\");\n throw new Error(`Broken wikilinks detected:\\n${message}`);\n }\n\n return {\n manifest,\n graph,\n searchRecords,\n buildId,\n brokenLinks,\n };\n}\n\nasync function writeRuntimeMarkdown(\n runtimeContentRoot: string,\n files: ContentMarkdownFile[],\n): Promise<void> {\n await fs.emptyDir(runtimeContentRoot);\n for (const file of files) {\n const destination = path.join(runtimeContentRoot, file.relativePath);\n await fs.ensureDir(path.dirname(destination));\n await fs.writeFile(destination, file.raw);\n }\n}\n\nfunction serializeManifest(\n manifest: Manifest,\n): Omit<Manifest, \"allSlugs\" | \"bySlug\"> {\n return {\n version: manifest.version,\n generatedAt: manifest.generatedAt,\n contentDir: manifest.contentDir,\n entries: manifest.entries,\n };\n}\n\nfunction makeNavigation(manifest: Manifest): Navigation {\n return {\n version: 1,\n entries: manifest.entries.filter(isListedEntry).map((entry) => ({\n slug: entry.slug,\n title: entry.menuLabel,\n sortKey: entry.sortKey,\n })),\n };\n}\n\nexport async function getGitDates(\n projectRoot: string,\n relativePath: string,\n): Promise<{ created?: Date; modified?: Date }> {\n return (\n (\n await getGitDatesForFiles(projectRoot, [normalizeGitPath(relativePath)])\n ).get(normalizeGitPath(relativePath)) ?? {}\n );\n}\n\nasync function getGitDatesForFiles(\n projectRoot: string,\n relativePaths: string[],\n): Promise<Map<string, { created?: Date; modified?: Date }>> {\n const wanted = new Set(relativePaths.map(normalizeGitPath));\n const datesByPath = new Map<string, { created?: Date; modified?: Date }>();\n if (wanted.size === 0) return datesByPath;\n\n try {\n const { stdout } = await execFileAsync(\n \"git\",\n [\"log\", \"--format=__SILICA_COMMIT__%aI\", \"--name-only\", \"--\", ...wanted],\n {\n cwd: projectRoot,\n timeout: 2_000,\n },\n );\n let commitDate: Date | undefined;\n for (const line of stdout.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n if (trimmed.startsWith(\"__SILICA_COMMIT__\")) {\n const parsed = new Date(trimmed.slice(\"__SILICA_COMMIT__\".length));\n commitDate = Number.isNaN(parsed.valueOf()) ? undefined : parsed;\n continue;\n }\n const relativePath = normalizeGitPath(trimmed);\n if (!commitDate || !wanted.has(relativePath)) continue;\n const dates = datesByPath.get(relativePath) ?? {};\n dates.modified ??= commitDate;\n dates.created = commitDate;\n datesByPath.set(relativePath, dates);\n }\n } catch {\n return datesByPath;\n }\n return datesByPath;\n}\n\nfunction normalizeGitPath(relativePath: string): string {\n return relativePath.replace(/\\\\/g, \"/\");\n}\n\nfunction filterPublished(\n files: ContentMarkdownFile[],\n config: ResolvedSilicaConfig,\n): ContentMarkdownFile[] {\n return files.filter((file) => {\n if (config.filters.removeDrafts && file.frontmatter.draft === true)\n return false;\n if (config.filters.explicitPublish && file.frontmatter.publish !== true)\n return false;\n return true;\n });\n}\n\nfunction makeManifest(\n config: ResolvedSilicaConfig,\n entries: ManifestEntry[],\n): Manifest {\n const sorted = [...entries].sort(compareManifestEntries);\n return {\n version: 1,\n generatedAt: new Date().toISOString(),\n contentDir: config.contentDir,\n allSlugs: sorted.map((entry) => entry.slug),\n entries: sorted,\n bySlug: Object.fromEntries(sorted.map((entry) => [entry.slug, entry])),\n };\n}\n\nfunction compareManifestEntries(a: ManifestEntry, b: ManifestEntry): number {\n if (a.sortKey || b.sortKey) {\n return (\n (a.sortKey ?? fallbackSortKey(a.slug)).localeCompare(\n b.sortKey ?? fallbackSortKey(b.slug),\n ) || a.slug.localeCompare(b.slug)\n );\n }\n\n return a.slug.localeCompare(b.slug);\n}\n\nfunction fallbackSortKey(slug: string): string {\n return slug\n .split(\"/\")\n .map((segment) => `~~~~~~~~~~:${segment}`)\n .join(\"/\");\n}\n\nfunction makeGraph(\n links: Record<string, string[]>,\n brokenLinks: BrokenLink[],\n): Graph {\n const backlinks: Record<string, string[]> = {};\n for (const [source, targets] of Object.entries(links)) {\n links[source] = [...new Set(targets)].sort();\n for (const target of targets) {\n backlinks[target] ??= [];\n backlinks[target]!.push(source);\n }\n }\n\n for (const [target, sources] of Object.entries(backlinks)) {\n backlinks[target] = [...new Set(sources)].sort();\n }\n\n return {\n version: 1,\n links,\n backlinks,\n brokenLinks,\n };\n}\n\nasync function copyAssets(\n projectRoot: string,\n config: ResolvedSilicaConfig,\n assets: Array<{ absolutePath: string; relativePath: string }>,\n): Promise<void> {\n const destinationRoot = path.join(projectRoot, \".silica/next/public/silica\");\n await fs.emptyDir(destinationRoot);\n for (const asset of assets) {\n await fs.ensureDir(\n path.dirname(path.join(destinationRoot, asset.relativePath)),\n );\n await fs.copyFile(\n asset.absolutePath,\n path.join(destinationRoot, asset.relativePath),\n );\n }\n\n await fs.ensureDir(path.join(projectRoot, \".silica/next/public\"));\n await fs.writeFile(path.join(destinationRoot, \".gitkeep\"), \"\");\n}\n\nasync function writeSitemapAndRobots(\n projectRoot: string,\n config: ResolvedSilicaConfig,\n manifest: Manifest,\n): Promise<void> {\n const publicRoot = path.join(projectRoot, \".silica/next/public\");\n await fs.ensureDir(publicRoot);\n const baseUrl = (config.baseUrl ?? \"http://localhost:3000\").replace(\n /\\/$/,\n \"\",\n );\n const urls = manifest.entries\n .filter(isListedEntry)\n .map(\n (entry) => ` <url><loc>${baseUrl}${slugToHref(entry.slug)}</loc></url>`,\n )\n .join(\"\\n\");\n if (!(await fs.pathExists(path.join(projectRoot, \"public/sitemap.xml\")))) {\n await fs.writeFile(\n path.join(publicRoot, \"sitemap.xml\"),\n `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\\n${urls}\\n</urlset>\\n`,\n );\n }\n if (!(await fs.pathExists(path.join(projectRoot, \"public/robots.txt\")))) {\n await fs.writeFile(\n path.join(publicRoot, \"robots.txt\"),\n `User-agent: *\\nAllow: /\\nSitemap: ${baseUrl}/sitemap.xml\\n`,\n );\n }\n}\n\nasync function writeJson(filePath: string, value: unknown): Promise<void> {\n await fs.ensureDir(path.dirname(filePath));\n await fs.writeJson(filePath, value, { spaces: 2 });\n}\n\nfunction getDate(value: unknown): Date | undefined {\n if (value instanceof Date) return value;\n if (typeof value === \"string\" || typeof value === \"number\") {\n const parsed = new Date(value);\n if (!Number.isNaN(parsed.valueOf())) return parsed;\n }\n return undefined;\n}\n\nexport function isListedEntry(entry: ManifestEntry): boolean {\n return entry.frontmatter.listed !== false;\n}\n\nfunction stringifyDate(value?: Date): string | undefined {\n return value?.toISOString();\n}\n\nfunction titleFromSlug(slug: string): string {\n const leaf = slug.split(\"/\").at(-1) ?? slug;\n return leaf\n .replace(/-/g, \" \")\n .replace(/\\b\\w/g, (letter) => letter.toUpperCase())\n .replace(/^Index$/, \"Home\");\n}\n"],"mappings":"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","names":["path","path","path","fs","path","fs"]}
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/logo.ts","../src/files.ts","../src/precompute.ts"],"sourcesContent":["import path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { createJiti } from \"jiti\";\nimport { resolvePublicAssetPath } from \"./logo.js\";\nimport type { ResolvedSilicaConfig, SilicaConfig } from \"./types.js\";\n\nexport function defineConfig(config: SilicaConfig): SilicaConfig {\n return config;\n}\n\nexport async function loadConfig(\n projectRoot = process.cwd(),\n): Promise<ResolvedSilicaConfig> {\n const configPath = path.join(projectRoot, \"silica.config.ts\");\n const jsConfigPath = path.join(projectRoot, \"silica.config.js\");\n const configFile = existsSync(configPath)\n ? configPath\n : existsSync(jsConfigPath)\n ? jsConfigPath\n : undefined;\n\n let userConfig: SilicaConfig = {};\n if (configFile) {\n const jiti = createJiti(projectRoot, { interopDefault: true });\n const loaded = await jiti.import<SilicaConfig | { default: SilicaConfig }>(\n configFile,\n );\n userConfig = \"default\" in loaded ? loaded.default : loaded;\n }\n\n return resolveConfig(userConfig, projectRoot);\n}\n\nexport function resolveConfig(\n config: SilicaConfig = {},\n projectRoot = process.cwd(),\n): ResolvedSilicaConfig {\n const auth = config.auth === false ? undefined : config.auth;\n const authEnabled = Boolean(\n auth?.enabled ??\n auth?.provider ??\n auth?.allowedDomains?.length ??\n auth?.allowedEmails?.length,\n );\n const allowedDomains = auth?.allowedDomains ?? [];\n const allowedEmails = auth?.allowedEmails ?? [];\n\n if (\n authEnabled &&\n allowedDomains.length === 0 &&\n allowedEmails.length === 0\n ) {\n throw new Error(\n \"Silica auth requires at least one allowedDomains or allowedEmails entry.\",\n );\n }\n\n return {\n projectRoot,\n title: config.title ?? \"Silica\",\n description: config.description ?? \"A Silica knowledge site\",\n logo: resolvePublicAssetPath(config.logo),\n baseUrl: config.baseUrl,\n contentDir: config.contentDir ?? \"content\",\n theme: config.theme ?? \"default\",\n auth: authEnabled\n ? {\n provider: auth?.provider ?? \"google\",\n enabled: true,\n allowedDomains,\n allowedEmails,\n }\n : undefined,\n wikilinks: {\n strategy: config.wikilinks?.strategy ?? \"shortest\",\n strict: config.wikilinks?.strict ?? false,\n },\n tags: {\n inline: config.tags?.inline ?? true,\n },\n ordering: {\n numericPrefixes: config.ordering?.numericPrefixes ?? true,\n },\n filters: {\n removeDrafts: config.filters?.removeDrafts ?? true,\n explicitPublish: config.filters?.explicitPublish ?? false,\n },\n };\n}\n","/** Normalize a public asset path or pass through absolute URLs. */\nexport function resolvePublicAssetPath(asset?: string): string | undefined {\n const trimmed = asset?.trim();\n if (!trimmed) return undefined;\n if (trimmed.startsWith(\"http://\") || trimmed.startsWith(\"https://\")) {\n return trimmed;\n }\n return trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`;\n}\n","import path from \"node:path\";\nimport fg from \"fast-glob\";\nimport fs from \"fs-extra\";\nimport matter from \"gray-matter\";\nimport type { ResolvedSilicaConfig } from \"./types.js\";\nimport { asFilePath, slugifyFilePath } from \"./path.js\";\n\nexport type ContentMarkdownFile = {\n absolutePath: string;\n relativePath: string;\n slug: string;\n raw: string;\n body: string;\n frontmatter: Record<string, unknown>;\n stats: {\n birthtime?: Date;\n mtime?: Date;\n };\n};\n\nexport type ContentAssetFile = {\n absolutePath: string;\n relativePath: string;\n};\n\nexport type ContentScan = {\n markdown: ContentMarkdownFile[];\n assets: ContentAssetFile[];\n};\n\nexport async function scanContent(\n projectRoot: string,\n config: ResolvedSilicaConfig,\n): Promise<ContentScan> {\n const contentRoot = path.join(projectRoot, config.contentDir);\n const realContentRoot = await fs.realpath(contentRoot);\n const entries = await fg(\"**/*\", {\n cwd: contentRoot,\n dot: false,\n followSymbolicLinks: false,\n onlyFiles: true,\n unique: true,\n });\n\n const markdown: ContentMarkdownFile[] = [];\n const assets: ContentAssetFile[] = [];\n\n for (const relativePath of entries.sort()) {\n const absolutePath = path.join(contentRoot, relativePath);\n const stats = await fs.lstat(absolutePath);\n if (!stats.isFile()) continue;\n if (!(await isWithinRoot(absolutePath, realContentRoot))) continue;\n\n if (isMarkdownFile(relativePath)) {\n const raw = await fs.readFile(absolutePath, \"utf8\");\n const parsed = matter(raw);\n markdown.push({\n absolutePath,\n relativePath: relativePath.replace(/\\\\/g, \"/\"),\n slug: slugifyFilePath(\n asFilePath(relativePath),\n config.contentDir,\n config.ordering,\n ),\n raw,\n body: parsed.content,\n frontmatter: parsed.data,\n stats: {\n birthtime: stats.birthtime,\n mtime: stats.mtime,\n },\n });\n } else {\n assets.push({\n absolutePath,\n relativePath: relativePath.replace(/\\\\/g, \"/\"),\n });\n }\n }\n\n return { markdown, assets };\n}\n\nasync function isWithinRoot(\n absolutePath: string,\n realRoot: string,\n): Promise<boolean> {\n const realPath = await fs.realpath(absolutePath);\n const relative = path.relative(realRoot, realPath);\n return (\n relative === \"\" ||\n (!relative.startsWith(\"..\") && !path.isAbsolute(relative))\n );\n}\n\nexport function isMarkdownFile(filePath: string): boolean {\n return /\\.(md|markdown|mdx)$/i.test(filePath);\n}\n","import crypto from \"node:crypto\";\nimport { execFile } from \"node:child_process\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport fs from \"fs-extra\";\nimport {\n buildSearchDatabase,\n SEARCH_DATABASE_FILENAME,\n type SearchRecord,\n} from \"@silicajs/search\";\nimport { loadConfig } from \"./config.js\";\nimport { scanContent, type ContentMarkdownFile } from \"./files.js\";\nimport {\n asFullSlug,\n hasNumericPrefixInPath,\n numericPrefixSortKey,\n stripNumericPrefix,\n slugToHref,\n} from \"./path.js\";\nimport { getMenuLabel } from \"./pipeline/frontmatter.js\";\nimport { analyzeMarkdown } from \"./pipeline/index.js\";\nimport type {\n BrokenLink,\n Graph,\n Manifest,\n ManifestEntry,\n Navigation,\n PrecomputeResult,\n ResolvedSilicaConfig,\n} from \"./types.js\";\n\nconst execFileAsync = promisify(execFile);\n\nexport type PrecomputeOptions = {\n projectRoot?: string;\n config?: ResolvedSilicaConfig;\n};\n\nexport async function precompute(\n options: PrecomputeOptions = {},\n): Promise<PrecomputeResult> {\n const projectRoot = options.projectRoot ?? process.cwd();\n const config = options.config ?? (await loadConfig(projectRoot));\n const scan = await scanContent(projectRoot, config);\n const markdownFiles = filterPublished(scan.markdown, config);\n const allSlugs = markdownFiles.map((file) => file.slug);\n const entries: ManifestEntry[] = [];\n const graphLinks: Record<string, string[]> = {};\n const brokenLinks: BrokenLink[] = [];\n const searchRecords: SearchRecord[] = [];\n const runtimeContentRoot = path.join(projectRoot, \".silica/content\");\n const relativeGitPaths = markdownFiles.map((file) =>\n normalizeGitPath(path.join(config.contentDir, file.relativePath)),\n );\n const gitDatesByPath = await getGitDatesForFiles(\n projectRoot,\n relativeGitPaths,\n );\n\n await fs.ensureDir(path.join(projectRoot, \".silica\"));\n await fs.ensureDir(path.join(projectRoot, \".silica/next/public/silica\"));\n await writeRuntimeMarkdown(runtimeContentRoot, markdownFiles);\n\n for (const file of markdownFiles) {\n const gitDates =\n gitDatesByPath.get(\n normalizeGitPath(path.join(config.contentDir, file.relativePath)),\n ) ?? {};\n const analysis = await analyzeMarkdown(file.raw, {\n slug: asFullSlug(file.slug),\n allSlugs,\n assetBaseUrl: \"/silica\",\n wikilinkStrategy: config.wikilinks.strategy,\n tags: config.tags,\n ordering: config.ordering,\n });\n\n const title =\n analysis.title ?? titleFromFilePath(file.relativePath, config.ordering);\n const menuLabel = getMenuLabel(file.frontmatter, title);\n const sortKey =\n config.ordering.numericPrefixes &&\n hasNumericPrefixInPath(file.relativePath)\n ? numericPrefixSortKey(file.relativePath)\n : undefined;\n const entry: ManifestEntry = {\n slug: file.slug,\n title,\n menuLabel,\n description: analysis.description,\n generatedDescription: analysis.generatedDescription,\n tags: analysis.tags,\n file: normalizeGitPath(path.join(\".silica/content\", file.relativePath)),\n relativeFile: file.relativePath,\n sortKey,\n created: stringifyDate(\n getDate(file.frontmatter.created) ??\n getDate(file.frontmatter.date) ??\n gitDates.created ??\n file.stats.birthtime,\n ),\n modified: stringifyDate(\n getDate(file.frontmatter.modified) ??\n gitDates.modified ??\n file.stats.mtime,\n ),\n frontmatter: file.frontmatter,\n };\n entries.push(entry);\n graphLinks[file.slug] = analysis.links;\n brokenLinks.push(...analysis.brokenLinks);\n if (isListedEntry(entry)) {\n searchRecords.push({\n id: file.slug,\n slug: file.slug,\n title,\n content: analysis.plainText,\n description: analysis.description,\n tags: analysis.tags,\n });\n }\n }\n\n await copyAssets(projectRoot, config, scan.assets);\n\n const manifest = makeManifest(config, entries);\n const graph = makeGraph(graphLinks, brokenLinks);\n const buildId = crypto.randomUUID();\n await buildSearchDatabase(\n searchRecords,\n path.join(projectRoot, \".silica\", SEARCH_DATABASE_FILENAME),\n );\n await fs.remove(path.join(projectRoot, \".silica/search-index.json\"));\n\n await writeJson(\n path.join(projectRoot, \".silica/manifest.json\"),\n serializeManifest(manifest),\n );\n await writeJson(\n path.join(projectRoot, \".silica/navigation.json\"),\n makeNavigation(manifest),\n );\n await writeJson(path.join(projectRoot, \".silica/graph.json\"), graph);\n await writeJson(path.join(projectRoot, \".silica/config.json\"), config);\n await fs.writeFile(\n path.join(projectRoot, \".silica/build-id.txt\"),\n `${buildId}\\n`,\n );\n await writeSitemapAndRobots(projectRoot, config, manifest);\n\n if (config.wikilinks.strict && brokenLinks.length > 0) {\n const message = brokenLinks\n .map((link) => `${link.source} -> ${link.target}`)\n .join(\"\\n\");\n throw new Error(`Broken wikilinks detected:\\n${message}`);\n }\n\n return {\n manifest,\n graph,\n searchRecords,\n buildId,\n brokenLinks,\n };\n}\n\nasync function writeRuntimeMarkdown(\n runtimeContentRoot: string,\n files: ContentMarkdownFile[],\n): Promise<void> {\n await fs.emptyDir(runtimeContentRoot);\n for (const file of files) {\n const destination = path.join(runtimeContentRoot, file.relativePath);\n await fs.ensureDir(path.dirname(destination));\n await fs.writeFile(destination, file.raw);\n }\n}\n\nfunction serializeManifest(\n manifest: Manifest,\n): Omit<Manifest, \"allSlugs\" | \"bySlug\"> {\n return {\n version: manifest.version,\n generatedAt: manifest.generatedAt,\n contentDir: manifest.contentDir,\n entries: manifest.entries,\n };\n}\n\nfunction makeNavigation(manifest: Manifest): Navigation {\n return {\n version: 1,\n entries: manifest.entries.filter(isListedEntry).map((entry) => ({\n slug: entry.slug,\n title: entry.menuLabel,\n sortKey: entry.sortKey,\n })),\n };\n}\n\nexport async function getGitDates(\n projectRoot: string,\n relativePath: string,\n): Promise<{ created?: Date; modified?: Date }> {\n return (\n (\n await getGitDatesForFiles(projectRoot, [normalizeGitPath(relativePath)])\n ).get(normalizeGitPath(relativePath)) ?? {}\n );\n}\n\nasync function getGitDatesForFiles(\n projectRoot: string,\n relativePaths: string[],\n): Promise<Map<string, { created?: Date; modified?: Date }>> {\n const wanted = new Set(relativePaths.map(normalizeGitPath));\n const datesByPath = new Map<string, { created?: Date; modified?: Date }>();\n if (wanted.size === 0) return datesByPath;\n\n try {\n const { stdout } = await execFileAsync(\n \"git\",\n [\"log\", \"--format=__SILICA_COMMIT__%aI\", \"--name-only\", \"--\", ...wanted],\n {\n cwd: projectRoot,\n timeout: 2_000,\n },\n );\n let commitDate: Date | undefined;\n for (const line of stdout.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n if (trimmed.startsWith(\"__SILICA_COMMIT__\")) {\n const parsed = new Date(trimmed.slice(\"__SILICA_COMMIT__\".length));\n commitDate = Number.isNaN(parsed.valueOf()) ? undefined : parsed;\n continue;\n }\n const relativePath = normalizeGitPath(trimmed);\n if (!commitDate || !wanted.has(relativePath)) continue;\n const dates = datesByPath.get(relativePath) ?? {};\n dates.modified ??= commitDate;\n dates.created = commitDate;\n datesByPath.set(relativePath, dates);\n }\n } catch {\n return datesByPath;\n }\n return datesByPath;\n}\n\nfunction normalizeGitPath(relativePath: string): string {\n return relativePath.replace(/\\\\/g, \"/\");\n}\n\nfunction filterPublished(\n files: ContentMarkdownFile[],\n config: ResolvedSilicaConfig,\n): ContentMarkdownFile[] {\n return files.filter((file) => {\n if (config.filters.removeDrafts && file.frontmatter.draft === true)\n return false;\n if (config.filters.explicitPublish && file.frontmatter.publish !== true)\n return false;\n return true;\n });\n}\n\nfunction makeManifest(\n config: ResolvedSilicaConfig,\n entries: ManifestEntry[],\n): Manifest {\n const sorted = [...entries].sort(compareManifestEntries);\n return {\n version: 1,\n generatedAt: new Date().toISOString(),\n contentDir: config.contentDir,\n allSlugs: sorted.map((entry) => entry.slug),\n entries: sorted,\n bySlug: Object.fromEntries(sorted.map((entry) => [entry.slug, entry])),\n };\n}\n\nfunction compareManifestEntries(a: ManifestEntry, b: ManifestEntry): number {\n if (a.sortKey || b.sortKey) {\n return (\n (a.sortKey ?? fallbackSortKey(a.slug)).localeCompare(\n b.sortKey ?? fallbackSortKey(b.slug),\n ) || a.slug.localeCompare(b.slug)\n );\n }\n\n return a.slug.localeCompare(b.slug);\n}\n\nfunction fallbackSortKey(slug: string): string {\n return slug\n .split(\"/\")\n .map((segment) => `~~~~~~~~~~:${segment}`)\n .join(\"/\");\n}\n\nfunction makeGraph(\n links: Record<string, string[]>,\n brokenLinks: BrokenLink[],\n): Graph {\n const backlinks: Record<string, string[]> = {};\n for (const [source, targets] of Object.entries(links)) {\n links[source] = [...new Set(targets)].sort();\n for (const target of targets) {\n backlinks[target] ??= [];\n backlinks[target]!.push(source);\n }\n }\n\n for (const [target, sources] of Object.entries(backlinks)) {\n backlinks[target] = [...new Set(sources)].sort();\n }\n\n return {\n version: 1,\n links,\n backlinks,\n brokenLinks,\n };\n}\n\nasync function copyAssets(\n projectRoot: string,\n config: ResolvedSilicaConfig,\n assets: Array<{ absolutePath: string; relativePath: string }>,\n): Promise<void> {\n const destinationRoot = path.join(projectRoot, \".silica/next/public/silica\");\n await fs.emptyDir(destinationRoot);\n for (const asset of assets) {\n await fs.ensureDir(\n path.dirname(path.join(destinationRoot, asset.relativePath)),\n );\n await fs.copyFile(\n asset.absolutePath,\n path.join(destinationRoot, asset.relativePath),\n );\n }\n\n await fs.ensureDir(path.join(projectRoot, \".silica/next/public\"));\n await fs.writeFile(path.join(destinationRoot, \".gitkeep\"), \"\");\n}\n\nasync function writeSitemapAndRobots(\n projectRoot: string,\n config: ResolvedSilicaConfig,\n manifest: Manifest,\n): Promise<void> {\n const publicRoot = path.join(projectRoot, \".silica/next/public\");\n await fs.ensureDir(publicRoot);\n const baseUrl = (config.baseUrl ?? \"http://localhost:3000\").replace(\n /\\/$/,\n \"\",\n );\n const urls = manifest.entries\n .filter(isListedEntry)\n .map(\n (entry) => ` <url><loc>${baseUrl}${slugToHref(entry.slug)}</loc></url>`,\n )\n .join(\"\\n\");\n if (!(await fs.pathExists(path.join(projectRoot, \"public/sitemap.xml\")))) {\n await fs.writeFile(\n path.join(publicRoot, \"sitemap.xml\"),\n `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\\n${urls}\\n</urlset>\\n`,\n );\n }\n if (!(await fs.pathExists(path.join(projectRoot, \"public/robots.txt\")))) {\n await fs.writeFile(\n path.join(publicRoot, \"robots.txt\"),\n `User-agent: *\\nAllow: /\\nSitemap: ${baseUrl}/sitemap.xml\\n`,\n );\n }\n}\n\nasync function writeJson(filePath: string, value: unknown): Promise<void> {\n await fs.ensureDir(path.dirname(filePath));\n await fs.writeJson(filePath, value, { spaces: 2 });\n}\n\nfunction getDate(value: unknown): Date | undefined {\n if (value instanceof Date) return value;\n if (typeof value === \"string\" || typeof value === \"number\") {\n const parsed = new Date(value);\n if (!Number.isNaN(parsed.valueOf())) return parsed;\n }\n return undefined;\n}\n\nexport function isListedEntry(entry: ManifestEntry): boolean {\n return entry.frontmatter.listed !== false;\n}\n\nfunction stringifyDate(value?: Date): string | undefined {\n return value?.toISOString();\n}\n\nfunction titleFromFilePath(\n relativePath: string,\n ordering: ResolvedSilicaConfig[\"ordering\"],\n): string {\n const stem = path.posix\n .basename(normalizeGitPath(relativePath))\n .replace(/\\.(md|markdown|mdx)$/i, \"\");\n const title = ordering.numericPrefixes ? stripNumericPrefix(stem) : stem;\n return /^index$/i.test(title) ? \"Home\" : title;\n}\n"],"mappings":"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","names":["path","path","path","fs","path","fs"]}
|
package/dist/runtime.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { e as RenderContext, A as AnalyzeResult, f as RenderResult } from './theme-
|
|
2
|
-
export { B as BrokenLink, G as Graph, M as Manifest, b as ManifestEntry, c as MarkdownComponents, N as Navigation, d as NavigationEntry, g as ResolvedSilicaConfig, h as SilicaCalloutProps, i as SilicaCodeBlockProps, k as SilicaEmbedProps, l as SilicaMermaidProps, m as SilicaTheme, T as ThemeBacklink, o as ThemeBreadcrumb, q as ThemeLayoutConfig, r as ThemePage, s as ThemePageProps, t as ThemeProviderComponent, u as ThemeRootLayoutProps, v as ThemeSiteLayoutProps, w as TocItem, D as hrefToSlug, L as resolveWikiLink, O as simplifySlug, Q as slugToHref } from './theme-
|
|
1
|
+
import { e as RenderContext, A as AnalyzeResult, f as RenderResult } from './theme-DF-R1di4.js';
|
|
2
|
+
export { B as BrokenLink, G as Graph, M as Manifest, b as ManifestEntry, c as MarkdownComponents, N as Navigation, d as NavigationEntry, g as ResolvedSilicaConfig, h as SilicaCalloutProps, i as SilicaCodeBlockProps, k as SilicaEmbedProps, l as SilicaMermaidProps, m as SilicaTheme, T as ThemeBacklink, o as ThemeBreadcrumb, q as ThemeLayoutConfig, r as ThemePage, s as ThemePageProps, t as ThemeProviderComponent, u as ThemeRootLayoutProps, v as ThemeSiteLayoutProps, w as TocItem, D as hrefToSlug, L as resolveWikiLink, O as simplifySlug, Q as slugToHref } from './theme-DF-R1di4.js';
|
|
3
3
|
import 'react';
|
|
4
4
|
import '@silicajs/search';
|
|
5
5
|
import '@silicajs/remark-obsidian';
|
|
@@ -17,7 +17,7 @@ declare function formatPropertyValue(value: unknown): string | undefined;
|
|
|
17
17
|
declare function renderMarkdown(raw: string, context: RenderContext): Promise<RenderResult>;
|
|
18
18
|
declare function renderMarkdownHtml(raw: string, context: RenderContext): Promise<string>;
|
|
19
19
|
declare function analyzeMarkdown(raw: string, context: RenderContext): Promise<AnalyzeResult>;
|
|
20
|
-
declare function getTitle(frontmatter: Record<string, unknown
|
|
20
|
+
declare function getTitle(frontmatter: Record<string, unknown>): string | undefined;
|
|
21
21
|
declare function getDescription(frontmatter: Record<string, unknown>): string | undefined;
|
|
22
22
|
declare function generateDescriptionFromContent(markdown: string, maxLength?: number): string | undefined;
|
|
23
23
|
declare function getMetaDescription(entry: {
|
package/dist/runtime.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { ComponentType, AnchorHTMLAttributes, HTMLAttributes, ReactNode } from 'react';
|
|
2
2
|
import { SearchRecord } from '@silicajs/search';
|
|
3
3
|
import { ObsidianLinkTarget } from '@silicajs/remark-obsidian';
|
|
4
4
|
|
|
@@ -184,17 +184,17 @@ type MarkdownComponents = {
|
|
|
184
184
|
};
|
|
185
185
|
type RenderResult = {
|
|
186
186
|
content: ReactNode;
|
|
187
|
-
frontmatter: Record<string, unknown>;
|
|
188
187
|
toc: TocItem[];
|
|
188
|
+
};
|
|
189
|
+
type AnalyzeResult = {
|
|
190
|
+
frontmatter: Record<string, unknown>;
|
|
189
191
|
links: string[];
|
|
190
192
|
brokenLinks: BrokenLink[];
|
|
191
193
|
plainText: string;
|
|
192
194
|
title?: string;
|
|
193
195
|
description?: string;
|
|
194
|
-
tags: string[];
|
|
195
|
-
};
|
|
196
|
-
type AnalyzeResult = Omit<RenderResult, "content"> & {
|
|
197
196
|
generatedDescription?: string;
|
|
197
|
+
tags: string[];
|
|
198
198
|
};
|
|
199
199
|
type PrecomputeResult = {
|
|
200
200
|
manifest: Manifest;
|
package/dist/theme.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import 'react';
|
|
2
|
-
export { c as MarkdownComponents, h as SilicaCalloutProps, i as SilicaCodeBlockProps, k as SilicaEmbedProps, l as SilicaMermaidProps, m as SilicaTheme, T as ThemeBacklink, o as ThemeBreadcrumb, q as ThemeLayoutConfig, r as ThemePage, s as ThemePageProps, t as ThemeProviderComponent, u as ThemeRootLayoutProps, v as ThemeSiteLayoutProps } from './theme-
|
|
2
|
+
export { c as MarkdownComponents, h as SilicaCalloutProps, i as SilicaCodeBlockProps, k as SilicaEmbedProps, l as SilicaMermaidProps, m as SilicaTheme, T as ThemeBacklink, o as ThemeBreadcrumb, q as ThemeLayoutConfig, r as ThemePage, s as ThemePageProps, t as ThemeProviderComponent, u as ThemeRootLayoutProps, v as ThemeSiteLayoutProps } from './theme-DF-R1di4.js';
|
|
3
3
|
import '@silicajs/search';
|
|
4
4
|
import '@silicajs/remark-obsidian';
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/path.ts","../src/pipeline/frontmatter.ts","../src/tags.ts","../src/pipeline/index.ts","../src/pipeline/code-block.ts","../src/pipeline/obsidian.ts","../src/pipeline/plugins.ts"],"sourcesContent":["import path from \"node:path\";\n\ndeclare const filePathBrand: unique symbol;\ndeclare const fullSlugBrand: unique symbol;\ndeclare const simpleSlugBrand: unique symbol;\ndeclare const relativeUrlBrand: unique symbol;\n\nexport type FilePath = string & { readonly [filePathBrand]: \"FilePath\" };\nexport type FullSlug = string & { readonly [fullSlugBrand]: \"FullSlug\" };\nexport type SimpleSlug = string & { readonly [simpleSlugBrand]: \"SimpleSlug\" };\nexport type RelativeURL = string & {\n readonly [relativeUrlBrand]: \"RelativeURL\";\n};\n\nexport type SlugifyOptions = {\n numericPrefixes?: boolean;\n};\n\nconst NUMERIC_PREFIX_RE = /^(\\d+)[\\s._-]+(.+)$/;\nconst UNORDERED_SEGMENT_SORT_PREFIX = \"~~~~~~~~~~\";\n\nexport function asFilePath(value: string): FilePath {\n return normalizePath(value) as FilePath;\n}\n\nexport function asFullSlug(value: string): FullSlug {\n return normalizeSlug(value) as FullSlug;\n}\n\nexport function asSimpleSlug(value: string): SimpleSlug {\n return simplifySlug(asFullSlug(value)) as SimpleSlug;\n}\n\nexport function asRelativeURL(value: string): RelativeURL {\n return value as RelativeURL;\n}\n\nexport function normalizePath(value: string): string {\n return value.replace(/\\\\/g, \"/\").replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n}\n\nexport function stripNumericPrefix(segment: string): string {\n return segment.replace(NUMERIC_PREFIX_RE, \"$2\");\n}\n\nexport function hasNumericPrefix(segment: string): boolean {\n return NUMERIC_PREFIX_RE.test(segment);\n}\n\nexport function slugifySegment(\n segment: string,\n options: SlugifyOptions = {},\n): string {\n const stem = segment.replace(/\\.[^.]+$/, \"\");\n const displaySegment = options.numericPrefixes\n ? stripNumericPrefix(stem)\n : stem;\n return displaySegment\n .normalize(\"NFKD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .trim()\n .toLowerCase()\n .replace(/['\"]/g, \"\")\n .replace(/[^a-z0-9/_-]+/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n}\n\nexport function normalizeSlug(\n value: string,\n options: SlugifyOptions = {},\n): string {\n const cleaned = normalizePath(value)\n .replace(/^\\.\\//, \"\")\n .replace(/\\.(md|markdown|mdx)$/i, \"\");\n const parts = cleaned\n .split(\"/\")\n .filter(Boolean)\n .map((part) => slugifySegment(part, options));\n return (parts.join(\"/\") || \"index\").replace(/\\/index\\/index$/, \"/index\");\n}\n\nexport function slugifyFilePath(\n filePath: FilePath | string,\n contentDir = \"content\",\n options: SlugifyOptions = {},\n): FullSlug {\n const normalizedFile = normalizePath(filePath);\n const normalizedContent = normalizePath(contentDir);\n const relative = normalizedFile.startsWith(`${normalizedContent}/`)\n ? normalizedFile.slice(normalizedContent.length + 1)\n : normalizedFile;\n\n return asFullSlug(normalizeSlug(relative, options));\n}\n\nexport function hasNumericPrefixInPath(filePath: string): boolean {\n return normalizePath(filePath)\n .split(\"/\")\n .some((segment) => hasNumericPrefix(segment.replace(/\\.[^.]+$/, \"\")));\n}\n\nexport function numericPrefixSortKey(filePath: string): string {\n return normalizePath(filePath)\n .replace(/\\.(md|markdown|mdx)$/i, \"\")\n .split(\"/\")\n .filter(Boolean)\n .map(numericPrefixSortSegment)\n .join(\"/\");\n}\n\nexport function simplifySlug(slug: FullSlug | string): SimpleSlug {\n const normalized = normalizeSlug(slug);\n if (normalized === \"index\") return \"\" as SimpleSlug;\n return normalized.replace(/\\/index$/, \"\") as SimpleSlug;\n}\n\nexport function slugToHref(slug: FullSlug | string): string {\n const simple = simplifySlug(slug).toString();\n return simple ? `/${simple}` : \"/\";\n}\n\nexport function hrefToSlug(href: string): FullSlug {\n const normalized = normalizePath(href.split(\"#\")[0] ?? \"\");\n return asFullSlug(normalized === \"\" ? \"index\" : normalized);\n}\n\nexport function pathToRoot(slug: FullSlug | string): RelativeURL {\n const simple = simplifySlug(slug).toString();\n const depth = simple ? simple.split(\"/\").length - 1 : 0;\n return asRelativeURL(depth === 0 ? \".\" : Array(depth).fill(\"..\").join(\"/\"));\n}\n\nexport function resolveRelative(\n currentSlug: FullSlug | string,\n target: string,\n options: SlugifyOptions = {},\n): FullSlug {\n const currentDir = normalizePath(currentSlug)\n .split(\"/\")\n .slice(0, -1)\n .join(\"/\");\n return asFullSlug(\n normalizeSlug(path.posix.join(currentDir, target), options),\n );\n}\n\nexport function resolveWikiLink(\n currentSlug: FullSlug | string,\n target: string,\n allSlugs: readonly string[],\n strategy: \"absolute\" | \"relative\" | \"shortest\" = \"shortest\",\n options: SlugifyOptions = {},\n): FullSlug | undefined {\n const [rawPath] = target.split(\"#\");\n const normalizedTarget = normalizeSlug(rawPath ?? target, options);\n const candidates = new Set(allSlugs.map((slug) => normalizeSlug(slug)));\n\n if (strategy === \"absolute\" && candidates.has(normalizedTarget))\n return asFullSlug(normalizedTarget);\n\n if (strategy === \"relative\") {\n const relative = resolveRelative(currentSlug, normalizedTarget, options);\n if (candidates.has(relative)) return relative;\n }\n\n if (candidates.has(normalizedTarget)) return asFullSlug(normalizedTarget);\n if (candidates.has(`${normalizedTarget}/index`))\n return asFullSlug(`${normalizedTarget}/index`);\n\n const byBasename = [...candidates].filter((slug) => {\n const simplified = simplifySlug(slug).toString();\n return simplified.split(\"/\").at(-1) === normalizedTarget.split(\"/\").at(-1);\n });\n\n return byBasename.length === 1 ? asFullSlug(byBasename[0]!) : undefined;\n}\n\nexport function joinSegments(...segments: string[]): string {\n return normalizePath(segments.filter(Boolean).join(\"/\"));\n}\n\nfunction numericPrefixSortSegment(segment: string): string {\n const stem = segment.replace(/\\.[^.]+$/, \"\");\n const match = NUMERIC_PREFIX_RE.exec(stem);\n if (!match) {\n return `${UNORDERED_SEGMENT_SORT_PREFIX}:${slugifySegment(stem)}`;\n }\n\n const order = match[1]!.padStart(10, \"0\");\n return `${order}:${slugifySegment(match[2]!)}`;\n}\n","export type PageProperty = {\n key: string;\n label: string;\n value: string;\n};\n\nconst RESERVED_FRONTMATTER_KEYS = new Set([\n \"aliases\",\n \"alias\",\n \"created\",\n \"cssclass\",\n \"cssclasses\",\n \"date\",\n \"description\",\n \"draft\",\n \"listed\",\n \"menu_label\",\n \"modified\",\n \"permalink\",\n \"publish\",\n \"tag\",\n \"tags\",\n \"title\",\n]);\n\nexport function getMenuLabel(\n frontmatter: Record<string, unknown>,\n title: string,\n): string {\n if (\n typeof frontmatter.menu_label === \"string\" &&\n frontmatter.menu_label.trim()\n ) {\n return frontmatter.menu_label.trim();\n }\n return title;\n}\n\nexport function getPageProperties(\n frontmatter: Record<string, unknown>,\n): PageProperty[] {\n return Object.entries(frontmatter)\n .filter(([key]) => !RESERVED_FRONTMATTER_KEYS.has(key.toLowerCase()))\n .map(([key, value]) => {\n const formatted = formatPropertyValue(value);\n if (formatted === undefined) return undefined;\n return {\n key,\n label: formatPropertyLabel(key),\n value: formatted,\n };\n })\n .filter((property): property is PageProperty => property !== undefined)\n .sort((a, b) => a.key.localeCompare(b.key));\n}\n\nexport function formatPropertyLabel(key: string): string {\n return key\n .replace(/[_-]+/g, \" \")\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .toLowerCase();\n}\n\nexport function formatPropertyValue(value: unknown): string | undefined {\n if (value === null || value === undefined) return undefined;\n\n if (value instanceof Date) {\n return value.toISOString().slice(0, 10);\n }\n\n if (typeof value === \"string\") {\n const trimmed = value.trim();\n return trimmed || undefined;\n }\n\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n\n if (Array.isArray(value)) {\n const items = value\n .map((item) => formatPropertyValue(item))\n .filter((item): item is string => item !== undefined);\n return items.length ? items.join(\", \") : undefined;\n }\n\n if (typeof value === \"object\") {\n return JSON.stringify(value);\n }\n\n return String(value);\n}\n","import { normalizeTag } from \"@silicajs/remark-obsidian\";\n\nexport function tagToHref(tag: string): string {\n const normalized = normalizeTag(tag);\n if (!normalized) return \"/tags\";\n const encoded = normalized\n .split(\"/\")\n .map((segment) => encodeURIComponent(segment))\n .join(\"/\");\n return `/tags/${encoded}`;\n}\n","import matter from \"gray-matter\";\nimport { unified } from \"unified\";\nimport remarkParse from \"remark-parse\";\nimport remarkFrontmatter from \"remark-frontmatter\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport remarkRehype from \"remark-rehype\";\nimport rehypeRaw from \"rehype-raw\";\nimport rehypeSanitize, { defaultSchema } from \"rehype-sanitize\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeSlug from \"rehype-slug\";\nimport rehypeAutolinkHeadings from \"rehype-autolink-headings\";\nimport rehypeShiki from \"@shikijs/rehype\";\nimport rehypeReact from \"rehype-react\";\nimport rehypeStringify from \"rehype-stringify\";\nimport { getTags, remarkObsidian } from \"@silicajs/remark-obsidian\";\nimport { Fragment, jsx, jsxs } from \"react/jsx-runtime\";\nimport type {\n AnalyzeResult,\n RenderContext,\n RenderResult,\n TocItem,\n} from \"../types.js\";\nimport { rehypeShikiCodeBlockWrapper } from \"./code-block.js\";\nimport {\n createSilicaObsidianHandlers,\n remarkSilicaObsidian,\n} from \"./obsidian.js\";\nimport {\n getDataArray,\n mergeBrokenLinks,\n rehypeCleanFootnoteHeadings,\n rehypeCollectTocAndLinks,\n rehypeExternalLinks,\n rehypeRestoreObsidianBlockIds,\n rehypeUnwrapSilicaEmbeds,\n} from \"./plugins.js\";\n\ntype MdastNode = {\n type: string;\n value?: string;\n raw?: string;\n tag?: string;\n children?: MdastNode[];\n};\n\ntype PlainTextOptions = {\n skipLeadingHeading?: boolean;\n};\n\nconst plainTextSkipTypes = new Set([\n \"code\",\n \"definition\",\n \"footnoteDefinition\",\n \"footnoteReference\",\n \"image\",\n \"imageReference\",\n \"inlineMath\",\n \"math\",\n \"obsidianBlockId\",\n \"obsidianComment\",\n \"obsidianWikiEmbed\",\n \"thematicBreak\",\n \"yaml\",\n]);\n\nconst headingLinkIcon = {\n type: \"element\",\n tagName: \"svg\",\n properties: {\n ariaHidden: \"true\",\n className: [\"silica-heading-link-icon\"],\n fill: \"none\",\n stroke: \"currentColor\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n strokeWidth: 2,\n viewBox: \"0 0 24 24\",\n },\n children: [\n {\n type: \"element\",\n tagName: \"path\",\n properties: {\n d: \"M9 17H7A5 5 0 0 1 7 7h2\",\n },\n children: [],\n },\n {\n type: \"element\",\n tagName: \"path\",\n properties: {\n d: \"M15 7h2a5 5 0 1 1 0 10h-2\",\n },\n children: [],\n },\n {\n type: \"element\",\n tagName: \"line\",\n properties: {\n x1: 8,\n x2: 16,\n y1: 12,\n y2: 12,\n },\n children: [],\n },\n ],\n} as const;\n\nconst sanitizeSchema = {\n ...defaultSchema,\n attributes: {\n ...defaultSchema.attributes,\n span: [\n ...(defaultSchema.attributes?.span ?? []),\n [\"className\", \"silica-broken-link\"],\n [\"className\", \"silica-block-id\"],\n [\"dataSilicaBlockId\"],\n [\"data-silica-block-id\"],\n [\"ariaHidden\"],\n [\"aria-hidden\"],\n ],\n sup: [\n ...(defaultSchema.attributes?.sup ?? []),\n [\"className\", \"silica-inline-footnote\"],\n ],\n img: [...(defaultSchema.attributes?.img ?? []), [\"width\"], [\"height\"]],\n audio: [[\"src\"], [\"controls\"], [\"width\"], [\"height\"]],\n video: [[\"src\"], [\"controls\"], [\"width\"], [\"height\"]],\n source: [[\"src\"], [\"type\"]],\n figure: [\n ...(defaultSchema.attributes?.figure ?? []),\n [\"className\", \"silica-embed\", \"silica-note-embed\"],\n [\"dataEmbedKind\"],\n [\"data-embed-kind\"],\n [\"dataEmbedTarget\"],\n [\"data-embed-target\"],\n ],\n strong: [\n ...(defaultSchema.attributes?.strong ?? []),\n [\"className\", \"silica-callout-title\"],\n [\"dataCallout\"],\n [\"data-callout\"],\n [\"dataCalloutFold\"],\n [\"data-callout-fold\"],\n ],\n \"silica-callout\": [\n [\"className\", \"silica-callout\"],\n [\"dataCallout\"],\n [\"data-callout\"],\n [\"dataCalloutTitle\"],\n [\"data-callout-title\"],\n [\"dataCalloutFoldable\"],\n [\"data-callout-foldable\"],\n [\"dataCalloutOpen\"],\n [\"data-callout-open\"],\n ],\n \"silica-embed\": [\n [\"src\"],\n [\"width\"],\n [\"height\"],\n [\"dataEmbedKind\"],\n [\"data-embed-kind\"],\n [\"dataEmbedTarget\"],\n [\"data-embed-target\"],\n ],\n \"silica-mermaid\": [\n [\"dataSource\"],\n [\"data-source\"],\n [\"dataLanguage\"],\n [\"data-language\"],\n [\"dataLanguageLabel\"],\n [\"data-language-label\"],\n ],\n mark: defaultSchema.attributes?.mark ?? [],\n },\n tagNames: [\n ...(defaultSchema.tagNames ?? []),\n \"mark\",\n \"audio\",\n \"video\",\n \"source\",\n \"figure\",\n \"silica-callout\",\n \"silica-embed\",\n \"silica-mermaid\",\n ],\n};\n\nexport async function renderMarkdown(\n raw: string,\n context: RenderContext,\n): Promise<RenderResult> {\n const parsed = matter(raw);\n const inlineTags = context.tags?.inline ?? true;\n const processor = baseProcessor(context)\n .use(rehypeUnwrapSilicaEmbeds)\n .use(rehypeRaw)\n .use(rehypeSanitize, sanitizeSchema)\n .use(rehypeRestoreObsidianBlockIds)\n .use(rehypeUnwrapSilicaEmbeds)\n .use(rehypeKatex);\n\n if (hasCodeFence(parsed.content)) {\n processor.use(rehypeShiki, {\n themes: {\n light: \"github-light\",\n dark: \"github-dark\",\n },\n defaultColor: \"light-dark()\",\n // Ensure unlabeled fences still flow through Shiki so they pick up the\n // wrapper transformer below (just without a language header).\n defaultLanguage: \"text\",\n rootStyle: false,\n transformers: [rehypeShikiCodeBlockWrapper()],\n });\n }\n\n processor\n .use(rehypeSlug)\n .use(rehypeAutolinkHeadings, {\n behavior: \"wrap\",\n content: headingLinkIcon,\n properties: { className: [\"silica-heading-link\"] },\n })\n .use(rehypeCleanFootnoteHeadings)\n .use(rehypeCollectTocAndLinks)\n .use(rehypeExternalLinks)\n .use(rehypeReact, {\n Fragment,\n jsx,\n jsxs,\n components: context.components,\n });\n\n const file = await processor.process(parsed.content);\n const frontmatter = parsed.data;\n const obsidianBrokenLinks = getDataArray<{ target: string }>(\n file.data,\n \"silicaObsidianBrokenLinks\",\n ).map((link) => ({ source: String(context.slug), target: link.target }));\n const links = unique([\n ...getDataArray<string>(file.data, \"silicaObsidianLinks\"),\n ...getDataArray<string>(file.data, \"links\"),\n ]);\n const toc = getDataArray<TocItem>(file.data, \"toc\");\n const plainText = extractPlainText(parsed.content);\n\n return {\n content: file.result,\n frontmatter,\n toc,\n links,\n brokenLinks: mergeBrokenLinks(obsidianBrokenLinks, []),\n plainText,\n title: getTitle(frontmatter, plainText),\n description: getDescription(frontmatter),\n tags: getTags(frontmatter, parsed.content, { inline: inlineTags }),\n };\n}\n\nexport async function renderMarkdownHtml(\n raw: string,\n context: RenderContext,\n): Promise<string> {\n const parsed = matter(raw);\n const processor = baseProcessor(context)\n .use(rehypeUnwrapSilicaEmbeds)\n .use(rehypeRaw)\n .use(rehypeSanitize, sanitizeSchema)\n .use(rehypeRestoreObsidianBlockIds)\n .use(rehypeUnwrapSilicaEmbeds)\n .use(rehypeKatex);\n\n if (hasCodeFence(parsed.content)) {\n processor.use(rehypeShiki, {\n themes: {\n light: \"github-light\",\n dark: \"github-dark\",\n },\n defaultColor: \"light-dark()\",\n defaultLanguage: \"text\",\n rootStyle: false,\n transformers: [rehypeShikiCodeBlockWrapper()],\n });\n }\n\n processor.use(rehypeExternalLinks).use(rehypeStringify);\n\n const file = await processor.process(parsed.content);\n return String(file);\n}\n\nexport async function analyzeMarkdown(\n raw: string,\n context: RenderContext,\n): Promise<AnalyzeResult> {\n const parsed = matter(raw);\n const inlineTags = context.tags?.inline ?? true;\n const file = await runRemarkObsidian(parsed.content, context);\n const plainText = extractPlainText(parsed.content);\n const frontmatter = parsed.data;\n const brokenLinks = getDataArray<{ target: string }>(\n file.data,\n \"silicaObsidianBrokenLinks\",\n ).map((link) => ({ source: String(context.slug), target: link.target }));\n const description = getDescription(frontmatter);\n\n return {\n frontmatter,\n toc: [],\n links: getDataArray<string>(file.data, \"silicaObsidianLinks\"),\n brokenLinks,\n plainText,\n title: getTitle(frontmatter, plainText),\n description,\n generatedDescription: description\n ? undefined\n : generateDescriptionFromContent(parsed.content),\n tags: getTags(frontmatter, parsed.content, { inline: inlineTags }),\n };\n}\n\nexport function getTitle(\n frontmatter: Record<string, unknown>,\n plainText: string,\n): string | undefined {\n if (typeof frontmatter.title === \"string\" && frontmatter.title.trim())\n return frontmatter.title.trim();\n const heading = plainText\n .split(\"\\n\")\n .map((line) => line.trim())\n .find(Boolean);\n return heading?.replace(/^#+\\s*/, \"\");\n}\n\nexport function getDescription(\n frontmatter: Record<string, unknown>,\n): string | undefined {\n if (\n typeof frontmatter.description === \"string\" &&\n frontmatter.description.trim()\n ) {\n return cleanPlainText(frontmatter.description.trim());\n }\n return undefined;\n}\n\nexport function generateDescriptionFromContent(\n markdown: string,\n maxLength = 160,\n): string | undefined {\n return cleanPlainText(markdown, maxLength, { skipLeadingHeading: true });\n}\n\nexport function getMetaDescription(\n entry: {\n description?: string;\n generatedDescription?: string;\n },\n maxLength = 160,\n): string | undefined {\n const text = entry.description ?? entry.generatedDescription;\n if (!text) return undefined;\n if (text.length <= maxLength) return text;\n return cleanPlainText(text, maxLength);\n}\n\nfunction cleanPlainText(\n text: string,\n maxLength?: number,\n options: PlainTextOptions = {},\n): string | undefined {\n const cleaned = extractPlainText(text, options).trim();\n if (!cleaned) return undefined;\n if (maxLength === undefined) return cleaned;\n const truncated = cleaned.slice(0, maxLength).trim();\n return truncated || undefined;\n}\n\nfunction baseProcessor(context: RenderContext) {\n return unified()\n .use(remarkParse)\n .use(remarkFrontmatter, [\"yaml\"])\n .use(remarkGfm)\n .use(remarkMath)\n .use(remarkObsidian, { inlineTags: context.tags?.inline ?? true })\n .use(remarkSilicaObsidian, context)\n .use(remarkRehype, {\n allowDangerousHtml: true,\n handlers: createSilicaObsidianHandlers(context),\n });\n}\n\nasync function runRemarkObsidian(markdown: string, context: RenderContext) {\n const processor = unified()\n .use(remarkParse)\n .use(remarkFrontmatter, [\"yaml\"])\n .use(remarkGfm)\n .use(remarkMath)\n .use(remarkObsidian, { inlineTags: context.tags?.inline ?? true })\n .use(remarkSilicaObsidian, context);\n const tree = processor.parse(markdown);\n const file = { data: {} };\n await processor.run(tree, file);\n return file;\n}\n\nfunction extractPlainText(\n markdown: string,\n options: PlainTextOptions = {},\n): string {\n const tree = parsePlainTextMarkdown(markdown);\n const children =\n options.skipLeadingHeading && tree.children?.[0]?.type === \"heading\"\n ? tree.children.slice(1)\n : (tree.children ?? []);\n const parts: string[] = [];\n\n for (const child of children) {\n collectPlainText(child, parts);\n }\n\n return normalizePlainText(parts.join(\" \"));\n}\n\nfunction parsePlainTextMarkdown(markdown: string): MdastNode {\n return unified()\n .use(remarkParse)\n .use(remarkFrontmatter, [\"yaml\"])\n .use(remarkGfm)\n .use(remarkMath)\n .use(remarkObsidian)\n .parse(markdown) as MdastNode;\n}\n\nfunction collectPlainText(node: MdastNode, parts: string[]): void {\n if (plainTextSkipTypes.has(node.type)) return;\n\n if (node.type === \"obsidianTag\") {\n const raw = node.raw?.replace(/^#/, \"\");\n const tag = raw || node.tag;\n if (tag) parts.push(tag);\n return;\n }\n\n if (typeof node.value === \"string\") {\n parts.push(node.value);\n }\n\n for (const child of node.children ?? []) {\n collectPlainText(child, parts);\n }\n}\n\nfunction normalizePlainText(text: string): string {\n return text\n .replace(/\\s+/g, \" \")\n .replace(/\\s+([.,;:!?])/g, \"$1\")\n .trim();\n}\n\nfunction hasCodeFence(markdown: string): boolean {\n return /(^|\\n)(```|~~~)/.test(markdown);\n}\n\nfunction unique(values: string[]): string[] {\n return [...new Set(values.filter(Boolean))];\n}\n","import type { Element, Root } from \"hast\";\nimport type { ShikiTransformer } from \"shiki\";\n\nconst LANGUAGE_LABELS: Record<string, string> = {\n bash: \"Bash\",\n c: \"C\",\n cpp: \"C++\",\n cs: \"C#\",\n css: \"CSS\",\n diff: \"Diff\",\n docker: \"Dockerfile\",\n dockerfile: \"Dockerfile\",\n go: \"Go\",\n graphql: \"GraphQL\",\n html: \"HTML\",\n ini: \"INI\",\n java: \"Java\",\n javascript: \"JavaScript\",\n js: \"JavaScript\",\n json: \"JSON\",\n jsonc: \"JSON\",\n jsx: \"JSX\",\n kotlin: \"Kotlin\",\n less: \"Less\",\n lua: \"Lua\",\n markdown: \"Markdown\",\n md: \"Markdown\",\n mdx: \"MDX\",\n objc: \"Objective-C\",\n php: \"PHP\",\n ps: \"PowerShell\",\n ps1: \"PowerShell\",\n powershell: \"PowerShell\",\n py: \"Python\",\n python: \"Python\",\n r: \"R\",\n rb: \"Ruby\",\n ruby: \"Ruby\",\n rs: \"Rust\",\n rust: \"Rust\",\n scala: \"Scala\",\n scss: \"SCSS\",\n sh: \"Shell\",\n shell: \"Shell\",\n sql: \"SQL\",\n svelte: \"Svelte\",\n swift: \"Swift\",\n toml: \"TOML\",\n ts: \"TypeScript\",\n tsx: \"TSX\",\n typescript: \"TypeScript\",\n vue: \"Vue\",\n xml: \"XML\",\n yaml: \"YAML\",\n yml: \"YAML\",\n zig: \"Zig\",\n zsh: \"Zsh\",\n};\n\nconst HIDDEN_LANGUAGES = new Set([\n \"\",\n \"text\",\n \"plain\",\n \"plaintext\",\n \"txt\",\n \"ansi\",\n]);\n\nfunction formatLanguage(lang: string | undefined): string | null {\n if (!lang) return null;\n const lower = lang.toLowerCase();\n if (HIDDEN_LANGUAGES.has(lower)) return null;\n return LANGUAGE_LABELS[lower] ?? lang;\n}\n\n/**\n * Wraps every Shiki-rendered `<pre>` in a semantic custom element. Shiki keeps\n * owning highlighting, while themes can map the element to their code chrome.\n */\nexport function rehypeShikiCodeBlockWrapper(): ShikiTransformer {\n return {\n name: \"silica:code-block-wrapper\",\n root(hast: Root): Root {\n const pre = hast.children.find(\n (child): child is Element =>\n child.type === \"element\" && child.tagName === \"pre\",\n );\n if (!pre) return hast;\n\n const rawLang =\n typeof this.options.lang === \"string\" ? this.options.lang : undefined;\n const label = formatLanguage(rawLang);\n const isMermaid = rawLang?.toLowerCase() === \"mermaid\";\n\n const wrapper: Element = {\n type: \"element\",\n tagName: isMermaid ? \"silica-mermaid\" : \"silica-code-block\",\n properties: {\n ...(rawLang ? { \"data-language\": rawLang } : {}),\n ...(isMermaid ? { \"data-source\": toText(pre) } : {}),\n ...(label ? { \"data-language-label\": label } : {}),\n },\n children: [pre],\n };\n\n hast.children = [wrapper];\n return hast;\n },\n };\n}\n\nfunction toText(node: Element): string {\n return node.children\n .map((child) => {\n if (child.type === \"text\") return child.value;\n if (child.type === \"element\") return toText(child);\n return \"\";\n })\n .join(\"\");\n}\n","import { visit } from \"unist-util-visit\";\nimport type {\n ObsidianBlockId,\n ObsidianCallout,\n ObsidianComment,\n ObsidianEmbedSize,\n ObsidianHighlight,\n ObsidianInlineFootnote,\n ObsidianTag,\n ObsidianWikiEmbed,\n ObsidianWikilink,\n} from \"@silicajs/remark-obsidian\";\nimport type { Nodes, PhrasingContent, Root, RootContent } from \"mdast\";\nimport type { Properties } from \"hast\";\nimport { slug as slugifyHeading } from \"github-slugger\";\nimport { tagToHref } from \"../tags.js\";\nimport { resolveWikiLink, slugToHref } from \"../path.js\";\nimport type { RenderContext } from \"../types.js\";\n\ndeclare module \"mdast\" {\n interface Data {\n silicaBroken?: boolean;\n silicaResolvedSlug?: string;\n silicaEmbedHtml?: string;\n hProperties?: Properties;\n }\n}\n\ntype VFileLike = {\n data: Record<string, unknown>;\n};\n\ntype SilicaMdastNode = Nodes;\n\ntype MdastParent = Extract<Nodes, { children: unknown[] }>;\n\ntype HastNode = {\n type: \"element\" | \"text\" | \"raw\";\n tagName?: string;\n value?: string;\n properties?: Record<string, unknown>;\n children?: HastNode[];\n};\n\ntype HandlerState = {\n all: (node: Nodes) => HastNode[];\n};\n\nexport function remarkSilicaObsidian(context: RenderContext) {\n return async (tree: Root, file: VFileLike) => {\n const links = new Set<string>();\n const brokenLinks: Array<{ target: string }> = [];\n const assetBaseUrl = context.assetBaseUrl ?? \"/silica\";\n const embedPromises: Array<Promise<void>> = [];\n\n transformInlineFootnotes(tree);\n\n visit(tree, (node: SilicaMdastNode) => {\n if (node.type === \"image\" && typeof node.url === \"string\") {\n node.url = rewriteAssetUrl(node.url, assetBaseUrl);\n applyImageSize(node);\n return;\n }\n\n if (!isWikiNode(node)) return;\n if (node.type === \"obsidianWikiEmbed\" && !isAssetTarget(node.rawTarget)) {\n embedPromises.push(resolveEmbedNode(node, context));\n }\n\n const targetPath = node.linkTarget.path || String(context.slug);\n if (node.type === \"obsidianWikiEmbed\" && isAssetTarget(node.rawTarget)) {\n return;\n }\n\n const resolved = resolveWikiLink(\n context.slug,\n targetPath,\n context.allSlugs,\n context.wikilinkStrategy ?? \"shortest\",\n context.ordering,\n );\n\n node.data = { ...node.data };\n if (!resolved) {\n node.data.silicaBroken = true;\n brokenLinks.push({ target: node.rawTarget });\n return;\n }\n\n node.data.silicaResolvedSlug = resolved;\n links.add(resolved);\n });\n\n await Promise.all(embedPromises);\n file.data.silicaObsidianLinks = [...links];\n file.data.silicaObsidianBrokenLinks = brokenLinks;\n };\n}\n\nexport function createSilicaObsidianHandlers(context: RenderContext) {\n return {\n obsidianWikilink(\n state: HandlerState,\n node: ObsidianWikilink & { data?: Record<string, unknown> },\n ) {\n return wikilinkToHast(state, node);\n },\n obsidianWikiEmbed(\n state: HandlerState,\n node: ObsidianWikiEmbed & { data?: Record<string, unknown> },\n ) {\n if (node.rawTarget && isAssetTarget(node.rawTarget)) {\n return assetEmbedToHast(context, node);\n }\n const embedHtml = getStringData(node, \"silicaEmbedHtml\");\n if (embedHtml) {\n return {\n type: \"element\",\n tagName: \"figure\",\n properties: {\n className: [\"silica-embed\", \"silica-note-embed\"],\n \"data-embed-kind\": \"note\",\n \"data-embed-target\": node.rawTarget,\n },\n children: [{ type: \"raw\", value: embedHtml }],\n };\n }\n return wikilinkToHast(state, node);\n },\n obsidianHighlight(state: HandlerState, node: ObsidianHighlight) {\n return {\n type: \"element\",\n tagName: \"mark\",\n properties: {},\n children: state.all(node),\n };\n },\n obsidianCallout(state: HandlerState, node: ObsidianCallout) {\n return {\n type: \"element\",\n tagName: \"silica-callout\",\n properties: {\n className: [\"silica-callout\"],\n \"data-callout\": node.kind ?? \"note\",\n \"data-callout-title\": node.title ?? titleCase(node.kind ?? \"note\"),\n ...(node.fold\n ? {\n \"data-callout-foldable\": \"true\",\n \"data-callout-open\": node.fold === \"open\" ? \"true\" : \"false\",\n }\n : {}),\n },\n children: state.all(node),\n };\n },\n obsidianTag(state: HandlerState, node: ObsidianTag) {\n return {\n type: \"element\",\n tagName: \"a\",\n properties: { href: tagToHref(node.tag ?? \"\") },\n children: state.all(node),\n };\n },\n obsidianComment(_state: HandlerState, _node: ObsidianComment) {\n return { type: \"text\", value: \"\" };\n },\n obsidianBlockId(_state: HandlerState, node: ObsidianBlockId) {\n return {\n type: \"element\",\n tagName: \"span\",\n properties: {\n id: `^${node.id}`,\n className: [\"silica-block-id\"],\n \"data-silica-block-id\": node.id,\n ariaHidden: \"true\",\n },\n children: [],\n };\n },\n };\n}\n\nfunction transformInlineFootnotes(tree: Root) {\n const definitions: RootContent[] = [];\n let nextIndex = 1;\n\n visit(\n tree,\n \"obsidianInlineFootnote\",\n (node: ObsidianInlineFootnote, index, parent: MdastParent | undefined) => {\n if (index === undefined || !parent) return;\n const identifier = `obsidian-inline-${nextIndex++}`;\n parent.children[index] = {\n type: \"footnoteReference\",\n identifier,\n label: identifier,\n } as PhrasingContent;\n definitions.push({\n type: \"footnoteDefinition\",\n identifier,\n label: identifier,\n children: [\n {\n type: \"paragraph\",\n children: node.children.length\n ? node.children\n : [{ type: \"text\", value: node.value }],\n },\n ],\n } as RootContent);\n },\n );\n\n tree.children.push(...definitions);\n}\n\nfunction wikilinkToHast(\n _state: HandlerState,\n node: (ObsidianWikilink | ObsidianWikiEmbed) & {\n data?: Record<string, unknown>;\n },\n): HastNode {\n const label = node.alias || node.target || \"\";\n const resolved = getResolvedSlug(node);\n if (!resolved) {\n return {\n type: \"element\",\n tagName: \"span\",\n properties: { className: [\"silica-broken-link\"] },\n children: [{ type: \"text\", value: label }],\n };\n }\n\n return {\n type: \"element\",\n tagName: \"a\",\n properties: { href: `${slugToHref(resolved)}${targetFragment(node)}` },\n children: [{ type: \"text\", value: label }],\n };\n}\n\nfunction isWikiNode(node: SilicaMdastNode): node is (\n | ObsidianWikilink\n | ObsidianWikiEmbed\n) & {\n data?: Record<string, unknown>;\n} {\n return (\n (node.type === \"obsidianWikilink\" || node.type === \"obsidianWikiEmbed\") &&\n typeof node.rawTarget === \"string\"\n );\n}\n\nfunction getResolvedSlug(node: SilicaMdastNode): string | undefined {\n const value = node.data?.silicaResolvedSlug;\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction getStringData(node: SilicaMdastNode, key: string): string | undefined {\n const value = (node.data as Record<string, unknown> | undefined)?.[key];\n return typeof value === \"string\" ? value : undefined;\n}\n\nasync function resolveEmbedNode(\n node: ObsidianWikiEmbed & { data?: Record<string, unknown> },\n context: RenderContext,\n): Promise<void> {\n if (!context.resolveEmbed) return;\n const maxDepth = context.maxEmbedDepth ?? 3;\n const depth = context.embedDepth ?? 0;\n if (depth >= maxDepth) return;\n const html = await context.resolveEmbed(node.linkTarget);\n if (!html) return;\n node.data = {\n ...node.data,\n silicaEmbedHtml: html,\n };\n}\n\nfunction assetEmbedToHast(\n context: RenderContext,\n node: ObsidianWikiEmbed,\n): HastNode {\n const kind = assetKind(node.rawTarget);\n const src = assetUrl(context.assetBaseUrl ?? \"/silica\", node.rawTarget);\n const label =\n node.alias || node.rawTarget.split(\"/\").at(-1) || node.rawTarget;\n const dimensions = sizeProperties(\n node.embedSize ?? sizeFromParams(node.linkTarget.params),\n );\n\n if (kind === \"image\") {\n return {\n type: \"element\",\n tagName: \"img\",\n properties: {\n src,\n alt: label,\n ...dimensions,\n },\n children: [],\n };\n }\n\n if (kind === \"audio\" || kind === \"video\") {\n return {\n type: \"element\",\n tagName: kind,\n properties: {\n src,\n controls: true,\n ...dimensions,\n },\n children: [],\n };\n }\n\n return {\n type: \"element\",\n tagName: \"silica-embed\",\n properties: {\n src,\n \"data-embed-kind\": kind,\n \"data-embed-target\": node.rawTarget,\n ...dimensions,\n },\n children: [{ type: \"text\", value: label }],\n };\n}\n\nfunction targetFragment(node: ObsidianWikilink | ObsidianWikiEmbed): string {\n if (node.linkTarget.blockId) {\n return `#^${encodeURIComponent(node.linkTarget.blockId)}`;\n }\n if (node.linkTarget.heading) {\n return `#${slugifyHeading(node.linkTarget.heading)}`;\n }\n return \"\";\n}\n\nfunction applyImageSize(node: SilicaMdastNode) {\n const size = node.data?.obsidianEmbedSize as ObsidianEmbedSize | undefined;\n if (!size) return;\n node.data = {\n ...node.data,\n hProperties: {\n ...(node.data?.hProperties ?? {}),\n ...sizeProperties(size),\n },\n };\n}\n\nfunction sizeFromParams(\n params: Record<string, string> | undefined,\n): ObsidianEmbedSize | undefined {\n const height = Number(params?.height);\n if (!Number.isFinite(height) || height <= 0) return;\n return { width: 0, height };\n}\n\nfunction sizeProperties(size: ObsidianEmbedSize | undefined) {\n if (!size) return {};\n return {\n ...(size.width > 0 ? { width: size.width } : {}),\n ...(size.height ? { height: size.height } : {}),\n };\n}\n\nfunction rewriteAssetUrl(url: string, assetBaseUrl: string): string {\n if (!isAssetTarget(url)) return url;\n if (/^(?:https?:|#|\\/)/.test(url)) return url;\n return `${assetBaseUrl}/${url.replace(/^\\.?\\//, \"\")}`;\n}\n\nfunction isAssetTarget(target: string): boolean {\n return /\\.(png|jpe?g|gif|webp|svg|pdf|mp4|mov|mp3|wav|ogg|canvas)(?:[?#].*)?$/i.test(\n target,\n );\n}\n\nfunction isImageTarget(target: string): boolean {\n return /\\.(png|jpe?g|gif|webp|svg)(?:[?#].*)?$/i.test(target);\n}\n\nfunction assetKind(\n target: string,\n): \"image\" | \"audio\" | \"video\" | \"pdf\" | \"canvas\" | \"file\" {\n if (isImageTarget(target)) return \"image\";\n if (/\\.(mp3|wav|ogg)(?:[?#].*)?$/i.test(target)) return \"audio\";\n if (/\\.(mp4|mov)(?:[?#].*)?$/i.test(target)) return \"video\";\n if (/\\.pdf(?:[?#].*)?$/i.test(target)) return \"pdf\";\n if (/\\.canvas(?:[?#].*)?$/i.test(target)) return \"canvas\";\n return \"file\";\n}\n\nfunction assetUrl(assetBaseUrl: string, target: string): string {\n const cleaned = stripEmbedOnlyParams(target);\n if (/^(?:https?:|#|\\/)/.test(cleaned)) return cleaned;\n return `${assetBaseUrl}/${cleaned.replace(/^\\/+/, \"\")}`;\n}\n\nfunction stripEmbedOnlyParams(target: string): string {\n const hashIndex = target.indexOf(\"#\");\n if (hashIndex === -1) return target;\n const before = target.slice(0, hashIndex);\n const fragment = target.slice(hashIndex + 1);\n if (!fragment.includes(\"=\")) return target;\n const params = new URLSearchParams(fragment);\n params.delete(\"height\");\n const remaining = params.toString();\n return remaining ? `${before}#${remaining}` : before;\n}\n\nfunction titleCase(value: string): string {\n return value\n .split(/[-_\\s]+/)\n .filter(Boolean)\n .map((part) => part[0]!.toUpperCase() + part.slice(1))\n .join(\" \");\n}\n","import Slugger from \"github-slugger\";\nimport { toString } from \"hast-util-to-string\";\nimport { visit } from \"unist-util-visit\";\nimport type { BrokenLink, TocItem } from \"../types.js\";\nimport { hrefToSlug } from \"../path.js\";\n\ntype VFileLike = {\n data: Record<string, unknown>;\n};\n\ntype HastNode = {\n type: string;\n tagName?: string;\n value?: string;\n properties?: Record<string, unknown>;\n children?: HastNode[];\n};\n\nexport function rehypeCollectTocAndLinks() {\n return (tree: HastNode, file: VFileLike) => {\n const toc: TocItem[] = [];\n const links = new Set<string>();\n const slugger = new Slugger();\n\n visit(tree, \"element\", (node: HastNode) => {\n if (isHeading(node)) {\n const text = toString(node as never);\n const id = String(node.properties?.id ?? slugger.slug(text));\n node.properties = { ...node.properties, id };\n if (id !== \"footnote-label\") {\n toc.push({ id, text, depth: Number(node.tagName?.slice(1) ?? 2) });\n }\n }\n\n if (node.tagName === \"a\" && typeof node.properties?.href === \"string\") {\n const href = node.properties.href;\n if (href.startsWith(\"/\") && !href.startsWith(\"/silica/\")) {\n links.add(hrefToSlug(href));\n }\n }\n });\n\n file.data.toc = toc;\n file.data.links = [...links];\n };\n}\n\nexport function rehypeCleanFootnoteHeadings() {\n return (tree: HastNode) => {\n visit(tree, \"element\", (node: HastNode) => {\n if (node.properties?.id !== \"footnote-label\") return;\n const child = node.children?.[0];\n if (child?.tagName !== \"a\") return;\n node.children = child.children ?? [];\n });\n };\n}\n\nexport function rehypeExternalLinks() {\n return (tree: HastNode) => {\n visit(tree, \"element\", (node: HastNode) => {\n if (node.tagName !== \"a\" || typeof node.properties?.href !== \"string\")\n return;\n if (!/^https?:\\/\\//.test(node.properties.href)) return;\n node.properties = {\n ...node.properties,\n rel: \"noreferrer noopener\",\n target: \"_blank\",\n };\n });\n };\n}\n\nexport function rehypeUnwrapSilicaEmbeds() {\n return (tree: HastNode) => {\n unwrapStandaloneEmbeds(tree);\n };\n}\n\nexport function rehypeRestoreObsidianBlockIds() {\n return (tree: HastNode) => {\n restoreGeneratedFootnoteIds(tree);\n\n visit(tree, \"element\", (node: HastNode) => {\n if (node.tagName !== \"span\") return;\n const blockId = getStringProperty(\n node,\n \"dataSilicaBlockId\",\n \"data-silica-block-id\",\n );\n if (!blockId) return;\n node.properties = { ...node.properties, id: `^${blockId}` };\n });\n };\n}\n\nexport function getDataArray<T>(\n data: Record<string, unknown>,\n key: string,\n): T[] {\n const value = data[key];\n return Array.isArray(value) ? (value as T[]) : [];\n}\n\nexport function mergeBrokenLinks(\n a: BrokenLink[],\n b: BrokenLink[],\n): BrokenLink[] {\n const seen = new Set<string>();\n const merged: BrokenLink[] = [];\n for (const item of [...a, ...b]) {\n const key = `${item.source}\\0${item.target}`;\n if (seen.has(key)) continue;\n seen.add(key);\n merged.push(item);\n }\n return merged;\n}\n\nfunction isHeading(node: HastNode): boolean {\n return node.type === \"element\" && /^h[1-6]$/.test(node.tagName ?? \"\");\n}\n\nfunction getStringProperty(\n node: HastNode,\n camelCaseKey: string,\n kebabCaseKey: string,\n): string | undefined {\n const value =\n node.properties?.[camelCaseKey] ?? node.properties?.[kebabCaseKey];\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction restoreGeneratedFootnoteIds(node: HastNode, inFootnotes = false) {\n const isFootnotes = inFootnotes || isFootnotesSection(node);\n if (isFootnotes || isFootnoteReference(node)) {\n normalizeGeneratedFootnoteProperties(node);\n }\n\n for (const child of node.children ?? []) {\n restoreGeneratedFootnoteIds(child, isFootnotes);\n }\n}\n\nfunction normalizeGeneratedFootnoteProperties(node: HastNode) {\n if (!node.properties) return;\n normalizeProperty(node, \"id\");\n normalizeProperty(node, \"href\");\n normalizeProperty(node, \"ariaDescribedBy\");\n normalizeProperty(node, \"aria-describedby\");\n}\n\nfunction normalizeProperty(node: HastNode, key: string) {\n const value = node.properties?.[key];\n if (typeof value !== \"string\") return;\n node.properties = {\n ...node.properties,\n [key]: normalizeGeneratedFootnoteReference(value),\n };\n}\n\nfunction normalizeGeneratedFootnoteReference(value: string): string {\n const prefix = value.startsWith(\"#\") ? \"#\" : \"\";\n const id = prefix ? value.slice(1) : value;\n if (id === \"user-content-footnote-label\") return `${prefix}footnote-label`;\n if (id.startsWith(\"user-content-user-content-fn\")) {\n return `${prefix}${id.replace(/^user-content-/, \"\")}`;\n }\n return value;\n}\n\nfunction isFootnotesSection(node: HastNode): boolean {\n return (\n node.tagName === \"section\" &&\n hasProperty(node, \"dataFootnotes\", \"data-footnotes\")\n );\n}\n\nfunction isFootnoteReference(node: HastNode): boolean {\n return (\n node.tagName === \"a\" &&\n hasProperty(node, \"dataFootnoteRef\", \"data-footnote-ref\")\n );\n}\n\nfunction hasProperty(\n node: HastNode,\n camelCaseKey: string,\n kebabCaseKey: string,\n): boolean {\n return (\n node.properties?.[camelCaseKey] !== undefined ||\n node.properties?.[kebabCaseKey] !== undefined\n );\n}\n\nfunction unwrapStandaloneEmbeds(parent: HastNode) {\n if (!parent.children) return;\n\n parent.children = parent.children.map((child) => {\n unwrapStandaloneEmbeds(child);\n if (child.tagName !== \"p\") return child;\n\n const renderedChildren = child.children?.filter(\n (candidate) => !isWhitespaceText(candidate),\n );\n const onlyChild = renderedChildren?.[0];\n if (renderedChildren?.length === 1 && isStandaloneEmbed(onlyChild)) {\n return onlyChild;\n }\n return child;\n });\n}\n\nfunction isStandaloneEmbed(node: HastNode | undefined): node is HastNode {\n if (node?.tagName === \"silica-embed\") return true;\n if (node?.tagName !== \"figure\") return false;\n const kind =\n node.properties?.dataEmbedKind ?? node.properties?.[\"data-embed-kind\"];\n return kind === \"note\";\n}\n\nfunction isWhitespaceText(node: HastNode): boolean {\n return node.type === \"text\" && /^\\s*$/.test(node.value ?? \"\");\n}\n"],"mappings":";AAAA,OAAO,UAAU;AAkBjB,IAAM,oBAAoB;AAC1B,IAAM,gCAAgC;AAE/B,SAAS,WAAW,OAAyB;AAClD,SAAO,cAAc,KAAK;AAC5B;AAEO,SAAS,WAAW,OAAyB;AAClD,SAAO,cAAc,KAAK;AAC5B;AAEO,SAAS,aAAa,OAA2B;AACtD,SAAO,aAAa,WAAW,KAAK,CAAC;AACvC;AAEO,SAAS,cAAc,OAA4B;AACxD,SAAO;AACT;AAEO,SAAS,cAAc,OAAuB;AACnD,SAAO,MAAM,QAAQ,OAAO,GAAG,EAAE,QAAQ,QAAQ,EAAE,EAAE,QAAQ,QAAQ,EAAE;AACzE;AAEO,SAAS,mBAAmB,SAAyB;AAC1D,SAAO,QAAQ,QAAQ,mBAAmB,IAAI;AAChD;AAEO,SAAS,iBAAiB,SAA0B;AACzD,SAAO,kBAAkB,KAAK,OAAO;AACvC;AAEO,SAAS,eACd,SACA,UAA0B,CAAC,GACnB;AACR,QAAM,OAAO,QAAQ,QAAQ,YAAY,EAAE;AAC3C,QAAM,iBAAiB,QAAQ,kBAC3B,mBAAmB,IAAI,IACvB;AACJ,SAAO,eACJ,UAAU,MAAM,EAChB,QAAQ,oBAAoB,EAAE,EAC9B,KAAK,EACL,YAAY,EACZ,QAAQ,SAAS,EAAE,EACnB,QAAQ,kBAAkB,GAAG,EAC7B,QAAQ,OAAO,GAAG,EAClB,QAAQ,UAAU,EAAE;AACzB;AAEO,SAAS,cACd,OACA,UAA0B,CAAC,GACnB;AACR,QAAM,UAAU,cAAc,KAAK,EAChC,QAAQ,SAAS,EAAE,EACnB,QAAQ,yBAAyB,EAAE;AACtC,QAAM,QAAQ,QACX,MAAM,GAAG,EACT,OAAO,OAAO,EACd,IAAI,CAAC,SAAS,eAAe,MAAM,OAAO,CAAC;AAC9C,UAAQ,MAAM,KAAK,GAAG,KAAK,SAAS,QAAQ,mBAAmB,QAAQ;AACzE;AAEO,SAAS,gBACd,UACA,aAAa,WACb,UAA0B,CAAC,GACjB;AACV,QAAM,iBAAiB,cAAc,QAAQ;AAC7C,QAAM,oBAAoB,cAAc,UAAU;AAClD,QAAM,WAAW,eAAe,WAAW,GAAG,iBAAiB,GAAG,IAC9D,eAAe,MAAM,kBAAkB,SAAS,CAAC,IACjD;AAEJ,SAAO,WAAW,cAAc,UAAU,OAAO,CAAC;AACpD;AAEO,SAAS,uBAAuB,UAA2B;AAChE,SAAO,cAAc,QAAQ,EAC1B,MAAM,GAAG,EACT,KAAK,CAAC,YAAY,iBAAiB,QAAQ,QAAQ,YAAY,EAAE,CAAC,CAAC;AACxE;AAEO,SAAS,qBAAqB,UAA0B;AAC7D,SAAO,cAAc,QAAQ,EAC1B,QAAQ,yBAAyB,EAAE,EACnC,MAAM,GAAG,EACT,OAAO,OAAO,EACd,IAAI,wBAAwB,EAC5B,KAAK,GAAG;AACb;AAEO,SAAS,aAAa,MAAqC;AAChE,QAAM,aAAa,cAAc,IAAI;AACrC,MAAI,eAAe,QAAS,QAAO;AACnC,SAAO,WAAW,QAAQ,YAAY,EAAE;AAC1C;AAEO,SAAS,WAAW,MAAiC;AAC1D,QAAM,SAAS,aAAa,IAAI,EAAE,SAAS;AAC3C,SAAO,SAAS,IAAI,MAAM,KAAK;AACjC;AAEO,SAAS,WAAW,MAAwB;AACjD,QAAM,aAAa,cAAc,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK,EAAE;AACzD,SAAO,WAAW,eAAe,KAAK,UAAU,UAAU;AAC5D;AAEO,SAAS,WAAW,MAAsC;AAC/D,QAAM,SAAS,aAAa,IAAI,EAAE,SAAS;AAC3C,QAAM,QAAQ,SAAS,OAAO,MAAM,GAAG,EAAE,SAAS,IAAI;AACtD,SAAO,cAAc,UAAU,IAAI,MAAM,MAAM,KAAK,EAAE,KAAK,IAAI,EAAE,KAAK,GAAG,CAAC;AAC5E;AAEO,SAAS,gBACd,aACA,QACA,UAA0B,CAAC,GACjB;AACV,QAAM,aAAa,cAAc,WAAW,EACzC,MAAM,GAAG,EACT,MAAM,GAAG,EAAE,EACX,KAAK,GAAG;AACX,SAAO;AAAA,IACL,cAAc,KAAK,MAAM,KAAK,YAAY,MAAM,GAAG,OAAO;AAAA,EAC5D;AACF;AAEO,SAAS,gBACd,aACA,QACA,UACA,WAAiD,YACjD,UAA0B,CAAC,GACL;AACtB,QAAM,CAAC,OAAO,IAAI,OAAO,MAAM,GAAG;AAClC,QAAM,mBAAmB,cAAc,WAAW,QAAQ,OAAO;AACjE,QAAM,aAAa,IAAI,IAAI,SAAS,IAAI,CAAC,SAAS,cAAc,IAAI,CAAC,CAAC;AAEtE,MAAI,aAAa,cAAc,WAAW,IAAI,gBAAgB;AAC5D,WAAO,WAAW,gBAAgB;AAEpC,MAAI,aAAa,YAAY;AAC3B,UAAM,WAAW,gBAAgB,aAAa,kBAAkB,OAAO;AACvE,QAAI,WAAW,IAAI,QAAQ,EAAG,QAAO;AAAA,EACvC;AAEA,MAAI,WAAW,IAAI,gBAAgB,EAAG,QAAO,WAAW,gBAAgB;AACxE,MAAI,WAAW,IAAI,GAAG,gBAAgB,QAAQ;AAC5C,WAAO,WAAW,GAAG,gBAAgB,QAAQ;AAE/C,QAAM,aAAa,CAAC,GAAG,UAAU,EAAE,OAAO,CAAC,SAAS;AAClD,UAAM,aAAa,aAAa,IAAI,EAAE,SAAS;AAC/C,WAAO,WAAW,MAAM,GAAG,EAAE,GAAG,EAAE,MAAM,iBAAiB,MAAM,GAAG,EAAE,GAAG,EAAE;AAAA,EAC3E,CAAC;AAED,SAAO,WAAW,WAAW,IAAI,WAAW,WAAW,CAAC,CAAE,IAAI;AAChE;AAEO,SAAS,gBAAgB,UAA4B;AAC1D,SAAO,cAAc,SAAS,OAAO,OAAO,EAAE,KAAK,GAAG,CAAC;AACzD;AAEA,SAAS,yBAAyB,SAAyB;AACzD,QAAM,OAAO,QAAQ,QAAQ,YAAY,EAAE;AAC3C,QAAM,QAAQ,kBAAkB,KAAK,IAAI;AACzC,MAAI,CAAC,OAAO;AACV,WAAO,GAAG,6BAA6B,IAAI,eAAe,IAAI,CAAC;AAAA,EACjE;AAEA,QAAM,QAAQ,MAAM,CAAC,EAAG,SAAS,IAAI,GAAG;AACxC,SAAO,GAAG,KAAK,IAAI,eAAe,MAAM,CAAC,CAAE,CAAC;AAC9C;;;ACzLA,IAAM,4BAA4B,oBAAI,IAAI;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,SAAS,aACd,aACA,OACQ;AACR,MACE,OAAO,YAAY,eAAe,YAClC,YAAY,WAAW,KAAK,GAC5B;AACA,WAAO,YAAY,WAAW,KAAK;AAAA,EACrC;AACA,SAAO;AACT;AAEO,SAAS,kBACd,aACgB;AAChB,SAAO,OAAO,QAAQ,WAAW,EAC9B,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,0BAA0B,IAAI,IAAI,YAAY,CAAC,CAAC,EACnE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;AACrB,UAAM,YAAY,oBAAoB,KAAK;AAC3C,QAAI,cAAc,OAAW,QAAO;AACpC,WAAO;AAAA,MACL;AAAA,MACA,OAAO,oBAAoB,GAAG;AAAA,MAC9B,OAAO;AAAA,IACT;AAAA,EACF,CAAC,EACA,OAAO,CAAC,aAAuC,aAAa,MAAS,EACrE,KAAK,CAAC,GAAG,MAAM,EAAE,IAAI,cAAc,EAAE,GAAG,CAAC;AAC9C;AAEO,SAAS,oBAAoB,KAAqB;AACvD,SAAO,IACJ,QAAQ,UAAU,GAAG,EACrB,QAAQ,sBAAsB,OAAO,EACrC,YAAY;AACjB;AAEO,SAAS,oBAAoB,OAAoC;AACtE,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAElD,MAAI,iBAAiB,MAAM;AACzB,WAAO,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE;AAAA,EACxC;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,UAAU,MAAM,KAAK;AAC3B,WAAO,WAAW;AAAA,EACpB;AAEA,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW;AAC3D,WAAO,OAAO,KAAK;AAAA,EACrB;AAEA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,UAAM,QAAQ,MACX,IAAI,CAAC,SAAS,oBAAoB,IAAI,CAAC,EACvC,OAAO,CAAC,SAAyB,SAAS,MAAS;AACtD,WAAO,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI;AAAA,EAC3C;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B;AAEA,SAAO,OAAO,KAAK;AACrB;;;AC3FA,SAAS,oBAAoB;AAEtB,SAAS,UAAU,KAAqB;AAC7C,QAAM,aAAa,aAAa,GAAG;AACnC,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,UAAU,WACb,MAAM,GAAG,EACT,IAAI,CAAC,YAAY,mBAAmB,OAAO,CAAC,EAC5C,KAAK,GAAG;AACX,SAAO,SAAS,OAAO;AACzB;;;ACVA,OAAO,YAAY;AACnB,SAAS,eAAe;AACxB,OAAO,iBAAiB;AACxB,OAAO,uBAAuB;AAC9B,OAAO,eAAe;AACtB,OAAO,gBAAgB;AACvB,OAAO,kBAAkB;AACzB,OAAO,eAAe;AACtB,OAAO,kBAAkB,qBAAqB;AAC9C,OAAO,iBAAiB;AACxB,OAAO,gBAAgB;AACvB,OAAO,4BAA4B;AACnC,OAAO,iBAAiB;AACxB,OAAO,iBAAiB;AACxB,OAAO,qBAAqB;AAC5B,SAAS,SAAS,sBAAsB;AACxC,SAAS,UAAU,KAAK,YAAY;;;ACbpC,IAAM,kBAA0C;AAAA,EAC9C,MAAM;AAAA,EACN,GAAG;AAAA,EACH,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,OAAO;AAAA,EACP,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,KAAK;AAAA,EACL,UAAU;AAAA,EACV,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,YAAY;AAAA,EACZ,IAAI;AAAA,EACJ,QAAQ;AAAA,EACR,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,YAAY;AAAA,EACZ,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;AAEA,IAAM,mBAAmB,oBAAI,IAAI;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,eAAe,MAAyC;AAC/D,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,QAAQ,KAAK,YAAY;AAC/B,MAAI,iBAAiB,IAAI,KAAK,EAAG,QAAO;AACxC,SAAO,gBAAgB,KAAK,KAAK;AACnC;AAMO,SAAS,8BAAgD;AAC9D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,KAAK,MAAkB;AACrB,YAAM,MAAM,KAAK,SAAS;AAAA,QACxB,CAAC,UACC,MAAM,SAAS,aAAa,MAAM,YAAY;AAAA,MAClD;AACA,UAAI,CAAC,IAAK,QAAO;AAEjB,YAAM,UACJ,OAAO,KAAK,QAAQ,SAAS,WAAW,KAAK,QAAQ,OAAO;AAC9D,YAAM,QAAQ,eAAe,OAAO;AACpC,YAAM,YAAY,SAAS,YAAY,MAAM;AAE7C,YAAM,UAAmB;AAAA,QACvB,MAAM;AAAA,QACN,SAAS,YAAY,mBAAmB;AAAA,QACxC,YAAY;AAAA,UACV,GAAI,UAAU,EAAE,iBAAiB,QAAQ,IAAI,CAAC;AAAA,UAC9C,GAAI,YAAY,EAAE,eAAe,OAAO,GAAG,EAAE,IAAI,CAAC;AAAA,UAClD,GAAI,QAAQ,EAAE,uBAAuB,MAAM,IAAI,CAAC;AAAA,QAClD;AAAA,QACA,UAAU,CAAC,GAAG;AAAA,MAChB;AAEA,WAAK,WAAW,CAAC,OAAO;AACxB,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,SAAS,OAAO,MAAuB;AACrC,SAAO,KAAK,SACT,IAAI,CAAC,UAAU;AACd,QAAI,MAAM,SAAS,OAAQ,QAAO,MAAM;AACxC,QAAI,MAAM,SAAS,UAAW,QAAO,OAAO,KAAK;AACjD,WAAO;AAAA,EACT,CAAC,EACA,KAAK,EAAE;AACZ;;;ACvHA,SAAS,aAAa;AActB,SAAS,QAAQ,sBAAsB;AAkChC,SAAS,qBAAqB,SAAwB;AAC3D,SAAO,OAAO,MAAY,SAAoB;AAC5C,UAAM,QAAQ,oBAAI,IAAY;AAC9B,UAAM,cAAyC,CAAC;AAChD,UAAM,eAAe,QAAQ,gBAAgB;AAC7C,UAAM,gBAAsC,CAAC;AAE7C,6BAAyB,IAAI;AAE7B,UAAM,MAAM,CAAC,SAA0B;AACrC,UAAI,KAAK,SAAS,WAAW,OAAO,KAAK,QAAQ,UAAU;AACzD,aAAK,MAAM,gBAAgB,KAAK,KAAK,YAAY;AACjD,uBAAe,IAAI;AACnB;AAAA,MACF;AAEA,UAAI,CAAC,WAAW,IAAI,EAAG;AACvB,UAAI,KAAK,SAAS,uBAAuB,CAAC,cAAc,KAAK,SAAS,GAAG;AACvE,sBAAc,KAAK,iBAAiB,MAAM,OAAO,CAAC;AAAA,MACpD;AAEA,YAAM,aAAa,KAAK,WAAW,QAAQ,OAAO,QAAQ,IAAI;AAC9D,UAAI,KAAK,SAAS,uBAAuB,cAAc,KAAK,SAAS,GAAG;AACtE;AAAA,MACF;AAEA,YAAM,WAAW;AAAA,QACf,QAAQ;AAAA,QACR;AAAA,QACA,QAAQ;AAAA,QACR,QAAQ,oBAAoB;AAAA,QAC5B,QAAQ;AAAA,MACV;AAEA,WAAK,OAAO,EAAE,GAAG,KAAK,KAAK;AAC3B,UAAI,CAAC,UAAU;AACb,aAAK,KAAK,eAAe;AACzB,oBAAY,KAAK,EAAE,QAAQ,KAAK,UAAU,CAAC;AAC3C;AAAA,MACF;AAEA,WAAK,KAAK,qBAAqB;AAC/B,YAAM,IAAI,QAAQ;AAAA,IACpB,CAAC;AAED,UAAM,QAAQ,IAAI,aAAa;AAC/B,SAAK,KAAK,sBAAsB,CAAC,GAAG,KAAK;AACzC,SAAK,KAAK,4BAA4B;AAAA,EACxC;AACF;AAEO,SAAS,6BAA6B,SAAwB;AACnE,SAAO;AAAA,IACL,iBACE,OACA,MACA;AACA,aAAO,eAAe,OAAO,IAAI;AAAA,IACnC;AAAA,IACA,kBACE,OACA,MACA;AACA,UAAI,KAAK,aAAa,cAAc,KAAK,SAAS,GAAG;AACnD,eAAO,iBAAiB,SAAS,IAAI;AAAA,MACvC;AACA,YAAM,YAAY,cAAc,MAAM,iBAAiB;AACvD,UAAI,WAAW;AACb,eAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS;AAAA,UACT,YAAY;AAAA,YACV,WAAW,CAAC,gBAAgB,mBAAmB;AAAA,YAC/C,mBAAmB;AAAA,YACnB,qBAAqB,KAAK;AAAA,UAC5B;AAAA,UACA,UAAU,CAAC,EAAE,MAAM,OAAO,OAAO,UAAU,CAAC;AAAA,QAC9C;AAAA,MACF;AACA,aAAO,eAAe,OAAO,IAAI;AAAA,IACnC;AAAA,IACA,kBAAkB,OAAqB,MAAyB;AAC9D,aAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS;AAAA,QACT,YAAY,CAAC;AAAA,QACb,UAAU,MAAM,IAAI,IAAI;AAAA,MAC1B;AAAA,IACF;AAAA,IACA,gBAAgB,OAAqB,MAAuB;AAC1D,aAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS;AAAA,QACT,YAAY;AAAA,UACV,WAAW,CAAC,gBAAgB;AAAA,UAC5B,gBAAgB,KAAK,QAAQ;AAAA,UAC7B,sBAAsB,KAAK,SAAS,UAAU,KAAK,QAAQ,MAAM;AAAA,UACjE,GAAI,KAAK,OACL;AAAA,YACE,yBAAyB;AAAA,YACzB,qBAAqB,KAAK,SAAS,SAAS,SAAS;AAAA,UACvD,IACA,CAAC;AAAA,QACP;AAAA,QACA,UAAU,MAAM,IAAI,IAAI;AAAA,MAC1B;AAAA,IACF;AAAA,IACA,YAAY,OAAqB,MAAmB;AAClD,aAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS;AAAA,QACT,YAAY,EAAE,MAAM,UAAU,KAAK,OAAO,EAAE,EAAE;AAAA,QAC9C,UAAU,MAAM,IAAI,IAAI;AAAA,MAC1B;AAAA,IACF;AAAA,IACA,gBAAgB,QAAsB,OAAwB;AAC5D,aAAO,EAAE,MAAM,QAAQ,OAAO,GAAG;AAAA,IACnC;AAAA,IACA,gBAAgB,QAAsB,MAAuB;AAC3D,aAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS;AAAA,QACT,YAAY;AAAA,UACV,IAAI,IAAI,KAAK,EAAE;AAAA,UACf,WAAW,CAAC,iBAAiB;AAAA,UAC7B,wBAAwB,KAAK;AAAA,UAC7B,YAAY;AAAA,QACd;AAAA,QACA,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,yBAAyB,MAAY;AAC5C,QAAM,cAA6B,CAAC;AACpC,MAAI,YAAY;AAEhB;AAAA,IACE;AAAA,IACA;AAAA,IACA,CAAC,MAA8B,OAAO,WAAoC;AACxE,UAAI,UAAU,UAAa,CAAC,OAAQ;AACpC,YAAM,aAAa,mBAAmB,WAAW;AACjD,aAAO,SAAS,KAAK,IAAI;AAAA,QACvB,MAAM;AAAA,QACN;AAAA,QACA,OAAO;AAAA,MACT;AACA,kBAAY,KAAK;AAAA,QACf,MAAM;AAAA,QACN;AAAA,QACA,OAAO;AAAA,QACP,UAAU;AAAA,UACR;AAAA,YACE,MAAM;AAAA,YACN,UAAU,KAAK,SAAS,SACpB,KAAK,WACL,CAAC,EAAE,MAAM,QAAQ,OAAO,KAAK,MAAM,CAAC;AAAA,UAC1C;AAAA,QACF;AAAA,MACF,CAAgB;AAAA,IAClB;AAAA,EACF;AAEA,OAAK,SAAS,KAAK,GAAG,WAAW;AACnC;AAEA,SAAS,eACP,QACA,MAGU;AACV,QAAM,QAAQ,KAAK,SAAS,KAAK,UAAU;AAC3C,QAAM,WAAW,gBAAgB,IAAI;AACrC,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,MACT,YAAY,EAAE,WAAW,CAAC,oBAAoB,EAAE;AAAA,MAChD,UAAU,CAAC,EAAE,MAAM,QAAQ,OAAO,MAAM,CAAC;AAAA,IAC3C;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,YAAY,EAAE,MAAM,GAAG,WAAW,QAAQ,CAAC,GAAG,eAAe,IAAI,CAAC,GAAG;AAAA,IACrE,UAAU,CAAC,EAAE,MAAM,QAAQ,OAAO,MAAM,CAAC;AAAA,EAC3C;AACF;AAEA,SAAS,WAAW,MAKlB;AACA,UACG,KAAK,SAAS,sBAAsB,KAAK,SAAS,wBACnD,OAAO,KAAK,cAAc;AAE9B;AAEA,SAAS,gBAAgB,MAA2C;AAClE,QAAM,QAAQ,KAAK,MAAM;AACzB,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEA,SAAS,cAAc,MAAuB,KAAiC;AAC7E,QAAM,QAAS,KAAK,OAA+C,GAAG;AACtE,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEA,eAAe,iBACb,MACA,SACe;AACf,MAAI,CAAC,QAAQ,aAAc;AAC3B,QAAM,WAAW,QAAQ,iBAAiB;AAC1C,QAAM,QAAQ,QAAQ,cAAc;AACpC,MAAI,SAAS,SAAU;AACvB,QAAM,OAAO,MAAM,QAAQ,aAAa,KAAK,UAAU;AACvD,MAAI,CAAC,KAAM;AACX,OAAK,OAAO;AAAA,IACV,GAAG,KAAK;AAAA,IACR,iBAAiB;AAAA,EACnB;AACF;AAEA,SAAS,iBACP,SACA,MACU;AACV,QAAM,OAAO,UAAU,KAAK,SAAS;AACrC,QAAM,MAAM,SAAS,QAAQ,gBAAgB,WAAW,KAAK,SAAS;AACtE,QAAM,QACJ,KAAK,SAAS,KAAK,UAAU,MAAM,GAAG,EAAE,GAAG,EAAE,KAAK,KAAK;AACzD,QAAM,aAAa;AAAA,IACjB,KAAK,aAAa,eAAe,KAAK,WAAW,MAAM;AAAA,EACzD;AAEA,MAAI,SAAS,SAAS;AACpB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,MACT,YAAY;AAAA,QACV;AAAA,QACA,KAAK;AAAA,QACL,GAAG;AAAA,MACL;AAAA,MACA,UAAU,CAAC;AAAA,IACb;AAAA,EACF;AAEA,MAAI,SAAS,WAAW,SAAS,SAAS;AACxC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,MACT,YAAY;AAAA,QACV;AAAA,QACA,UAAU;AAAA,QACV,GAAG;AAAA,MACL;AAAA,MACA,UAAU,CAAC;AAAA,IACb;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,YAAY;AAAA,MACV;AAAA,MACA,mBAAmB;AAAA,MACnB,qBAAqB,KAAK;AAAA,MAC1B,GAAG;AAAA,IACL;AAAA,IACA,UAAU,CAAC,EAAE,MAAM,QAAQ,OAAO,MAAM,CAAC;AAAA,EAC3C;AACF;AAEA,SAAS,eAAe,MAAoD;AAC1E,MAAI,KAAK,WAAW,SAAS;AAC3B,WAAO,KAAK,mBAAmB,KAAK,WAAW,OAAO,CAAC;AAAA,EACzD;AACA,MAAI,KAAK,WAAW,SAAS;AAC3B,WAAO,IAAI,eAAe,KAAK,WAAW,OAAO,CAAC;AAAA,EACpD;AACA,SAAO;AACT;AAEA,SAAS,eAAe,MAAuB;AAC7C,QAAM,OAAO,KAAK,MAAM;AACxB,MAAI,CAAC,KAAM;AACX,OAAK,OAAO;AAAA,IACV,GAAG,KAAK;AAAA,IACR,aAAa;AAAA,MACX,GAAI,KAAK,MAAM,eAAe,CAAC;AAAA,MAC/B,GAAG,eAAe,IAAI;AAAA,IACxB;AAAA,EACF;AACF;AAEA,SAAS,eACP,QAC+B;AAC/B,QAAM,SAAS,OAAO,QAAQ,MAAM;AACpC,MAAI,CAAC,OAAO,SAAS,MAAM,KAAK,UAAU,EAAG;AAC7C,SAAO,EAAE,OAAO,GAAG,OAAO;AAC5B;AAEA,SAAS,eAAe,MAAqC;AAC3D,MAAI,CAAC,KAAM,QAAO,CAAC;AACnB,SAAO;AAAA,IACL,GAAI,KAAK,QAAQ,IAAI,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,IAC9C,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,EAC/C;AACF;AAEA,SAAS,gBAAgB,KAAa,cAA8B;AAClE,MAAI,CAAC,cAAc,GAAG,EAAG,QAAO;AAChC,MAAI,oBAAoB,KAAK,GAAG,EAAG,QAAO;AAC1C,SAAO,GAAG,YAAY,IAAI,IAAI,QAAQ,UAAU,EAAE,CAAC;AACrD;AAEA,SAAS,cAAc,QAAyB;AAC9C,SAAO,yEAAyE;AAAA,IAC9E;AAAA,EACF;AACF;AAEA,SAAS,cAAc,QAAyB;AAC9C,SAAO,0CAA0C,KAAK,MAAM;AAC9D;AAEA,SAAS,UACP,QACyD;AACzD,MAAI,cAAc,MAAM,EAAG,QAAO;AAClC,MAAI,+BAA+B,KAAK,MAAM,EAAG,QAAO;AACxD,MAAI,2BAA2B,KAAK,MAAM,EAAG,QAAO;AACpD,MAAI,qBAAqB,KAAK,MAAM,EAAG,QAAO;AAC9C,MAAI,wBAAwB,KAAK,MAAM,EAAG,QAAO;AACjD,SAAO;AACT;AAEA,SAAS,SAAS,cAAsB,QAAwB;AAC9D,QAAM,UAAU,qBAAqB,MAAM;AAC3C,MAAI,oBAAoB,KAAK,OAAO,EAAG,QAAO;AAC9C,SAAO,GAAG,YAAY,IAAI,QAAQ,QAAQ,QAAQ,EAAE,CAAC;AACvD;AAEA,SAAS,qBAAqB,QAAwB;AACpD,QAAM,YAAY,OAAO,QAAQ,GAAG;AACpC,MAAI,cAAc,GAAI,QAAO;AAC7B,QAAM,SAAS,OAAO,MAAM,GAAG,SAAS;AACxC,QAAM,WAAW,OAAO,MAAM,YAAY,CAAC;AAC3C,MAAI,CAAC,SAAS,SAAS,GAAG,EAAG,QAAO;AACpC,QAAM,SAAS,IAAI,gBAAgB,QAAQ;AAC3C,SAAO,OAAO,QAAQ;AACtB,QAAM,YAAY,OAAO,SAAS;AAClC,SAAO,YAAY,GAAG,MAAM,IAAI,SAAS,KAAK;AAChD;AAEA,SAAS,UAAU,OAAuB;AACxC,SAAO,MACJ,MAAM,SAAS,EACf,OAAO,OAAO,EACd,IAAI,CAAC,SAAS,KAAK,CAAC,EAAG,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,EACpD,KAAK,GAAG;AACb;;;ACnaA,OAAO,aAAa;AACpB,SAAS,gBAAgB;AACzB,SAAS,SAAAA,cAAa;AAgBf,SAAS,2BAA2B;AACzC,SAAO,CAAC,MAAgB,SAAoB;AAC1C,UAAM,MAAiB,CAAC;AACxB,UAAM,QAAQ,oBAAI,IAAY;AAC9B,UAAM,UAAU,IAAI,QAAQ;AAE5B,IAAAC,OAAM,MAAM,WAAW,CAAC,SAAmB;AACzC,UAAI,UAAU,IAAI,GAAG;AACnB,cAAM,OAAO,SAAS,IAAa;AACnC,cAAM,KAAK,OAAO,KAAK,YAAY,MAAM,QAAQ,KAAK,IAAI,CAAC;AAC3D,aAAK,aAAa,EAAE,GAAG,KAAK,YAAY,GAAG;AAC3C,YAAI,OAAO,kBAAkB;AAC3B,cAAI,KAAK,EAAE,IAAI,MAAM,OAAO,OAAO,KAAK,SAAS,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AAAA,QACnE;AAAA,MACF;AAEA,UAAI,KAAK,YAAY,OAAO,OAAO,KAAK,YAAY,SAAS,UAAU;AACrE,cAAM,OAAO,KAAK,WAAW;AAC7B,YAAI,KAAK,WAAW,GAAG,KAAK,CAAC,KAAK,WAAW,UAAU,GAAG;AACxD,gBAAM,IAAI,WAAW,IAAI,CAAC;AAAA,QAC5B;AAAA,MACF;AAAA,IACF,CAAC;AAED,SAAK,KAAK,MAAM;AAChB,SAAK,KAAK,QAAQ,CAAC,GAAG,KAAK;AAAA,EAC7B;AACF;AAEO,SAAS,8BAA8B;AAC5C,SAAO,CAAC,SAAmB;AACzB,IAAAA,OAAM,MAAM,WAAW,CAAC,SAAmB;AACzC,UAAI,KAAK,YAAY,OAAO,iBAAkB;AAC9C,YAAM,QAAQ,KAAK,WAAW,CAAC;AAC/B,UAAI,OAAO,YAAY,IAAK;AAC5B,WAAK,WAAW,MAAM,YAAY,CAAC;AAAA,IACrC,CAAC;AAAA,EACH;AACF;AAEO,SAAS,sBAAsB;AACpC,SAAO,CAAC,SAAmB;AACzB,IAAAA,OAAM,MAAM,WAAW,CAAC,SAAmB;AACzC,UAAI,KAAK,YAAY,OAAO,OAAO,KAAK,YAAY,SAAS;AAC3D;AACF,UAAI,CAAC,eAAe,KAAK,KAAK,WAAW,IAAI,EAAG;AAChD,WAAK,aAAa;AAAA,QAChB,GAAG,KAAK;AAAA,QACR,KAAK;AAAA,QACL,QAAQ;AAAA,MACV;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,SAAS,2BAA2B;AACzC,SAAO,CAAC,SAAmB;AACzB,2BAAuB,IAAI;AAAA,EAC7B;AACF;AAEO,SAAS,gCAAgC;AAC9C,SAAO,CAAC,SAAmB;AACzB,gCAA4B,IAAI;AAEhC,IAAAA,OAAM,MAAM,WAAW,CAAC,SAAmB;AACzC,UAAI,KAAK,YAAY,OAAQ;AAC7B,YAAM,UAAU;AAAA,QACd;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,UAAI,CAAC,QAAS;AACd,WAAK,aAAa,EAAE,GAAG,KAAK,YAAY,IAAI,IAAI,OAAO,GAAG;AAAA,IAC5D,CAAC;AAAA,EACH;AACF;AAEO,SAAS,aACd,MACA,KACK;AACL,QAAM,QAAQ,KAAK,GAAG;AACtB,SAAO,MAAM,QAAQ,KAAK,IAAK,QAAgB,CAAC;AAClD;AAEO,SAAS,iBACd,GACA,GACc;AACd,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,SAAuB,CAAC;AAC9B,aAAW,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG;AAC/B,UAAM,MAAM,GAAG,KAAK,MAAM,KAAK,KAAK,MAAM;AAC1C,QAAI,KAAK,IAAI,GAAG,EAAG;AACnB,SAAK,IAAI,GAAG;AACZ,WAAO,KAAK,IAAI;AAAA,EAClB;AACA,SAAO;AACT;AAEA,SAAS,UAAU,MAAyB;AAC1C,SAAO,KAAK,SAAS,aAAa,WAAW,KAAK,KAAK,WAAW,EAAE;AACtE;AAEA,SAAS,kBACP,MACA,cACA,cACoB;AACpB,QAAM,QACJ,KAAK,aAAa,YAAY,KAAK,KAAK,aAAa,YAAY;AACnE,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEA,SAAS,4BAA4B,MAAgB,cAAc,OAAO;AACxE,QAAM,cAAc,eAAe,mBAAmB,IAAI;AAC1D,MAAI,eAAe,oBAAoB,IAAI,GAAG;AAC5C,yCAAqC,IAAI;AAAA,EAC3C;AAEA,aAAW,SAAS,KAAK,YAAY,CAAC,GAAG;AACvC,gCAA4B,OAAO,WAAW;AAAA,EAChD;AACF;AAEA,SAAS,qCAAqC,MAAgB;AAC5D,MAAI,CAAC,KAAK,WAAY;AACtB,oBAAkB,MAAM,IAAI;AAC5B,oBAAkB,MAAM,MAAM;AAC9B,oBAAkB,MAAM,iBAAiB;AACzC,oBAAkB,MAAM,kBAAkB;AAC5C;AAEA,SAAS,kBAAkB,MAAgB,KAAa;AACtD,QAAM,QAAQ,KAAK,aAAa,GAAG;AACnC,MAAI,OAAO,UAAU,SAAU;AAC/B,OAAK,aAAa;AAAA,IAChB,GAAG,KAAK;AAAA,IACR,CAAC,GAAG,GAAG,oCAAoC,KAAK;AAAA,EAClD;AACF;AAEA,SAAS,oCAAoC,OAAuB;AAClE,QAAM,SAAS,MAAM,WAAW,GAAG,IAAI,MAAM;AAC7C,QAAM,KAAK,SAAS,MAAM,MAAM,CAAC,IAAI;AACrC,MAAI,OAAO,8BAA+B,QAAO,GAAG,MAAM;AAC1D,MAAI,GAAG,WAAW,8BAA8B,GAAG;AACjD,WAAO,GAAG,MAAM,GAAG,GAAG,QAAQ,kBAAkB,EAAE,CAAC;AAAA,EACrD;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,MAAyB;AACnD,SACE,KAAK,YAAY,aACjB,YAAY,MAAM,iBAAiB,gBAAgB;AAEvD;AAEA,SAAS,oBAAoB,MAAyB;AACpD,SACE,KAAK,YAAY,OACjB,YAAY,MAAM,mBAAmB,mBAAmB;AAE5D;AAEA,SAAS,YACP,MACA,cACA,cACS;AACT,SACE,KAAK,aAAa,YAAY,MAAM,UACpC,KAAK,aAAa,YAAY,MAAM;AAExC;AAEA,SAAS,uBAAuB,QAAkB;AAChD,MAAI,CAAC,OAAO,SAAU;AAEtB,SAAO,WAAW,OAAO,SAAS,IAAI,CAAC,UAAU;AAC/C,2BAAuB,KAAK;AAC5B,QAAI,MAAM,YAAY,IAAK,QAAO;AAElC,UAAM,mBAAmB,MAAM,UAAU;AAAA,MACvC,CAAC,cAAc,CAAC,iBAAiB,SAAS;AAAA,IAC5C;AACA,UAAM,YAAY,mBAAmB,CAAC;AACtC,QAAI,kBAAkB,WAAW,KAAK,kBAAkB,SAAS,GAAG;AAClE,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,kBAAkB,MAA8C;AACvE,MAAI,MAAM,YAAY,eAAgB,QAAO;AAC7C,MAAI,MAAM,YAAY,SAAU,QAAO;AACvC,QAAM,OACJ,KAAK,YAAY,iBAAiB,KAAK,aAAa,iBAAiB;AACvE,SAAO,SAAS;AAClB;AAEA,SAAS,iBAAiB,MAAyB;AACjD,SAAO,KAAK,SAAS,UAAU,QAAQ,KAAK,KAAK,SAAS,EAAE;AAC9D;;;AH9KA,IAAM,qBAAqB,oBAAI,IAAI;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,kBAAkB;AAAA,EACtB,MAAM;AAAA,EACN,SAAS;AAAA,EACT,YAAY;AAAA,IACV,YAAY;AAAA,IACZ,WAAW,CAAC,0BAA0B;AAAA,IACtC,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AAAA,EACA,UAAU;AAAA,IACR;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,MACT,YAAY;AAAA,QACV,GAAG;AAAA,MACL;AAAA,MACA,UAAU,CAAC;AAAA,IACb;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,MACT,YAAY;AAAA,QACV,GAAG;AAAA,MACL;AAAA,MACA,UAAU,CAAC;AAAA,IACb;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,MACT,YAAY;AAAA,QACV,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN;AAAA,MACA,UAAU,CAAC;AAAA,IACb;AAAA,EACF;AACF;AAEA,IAAM,iBAAiB;AAAA,EACrB,GAAG;AAAA,EACH,YAAY;AAAA,IACV,GAAG,cAAc;AAAA,IACjB,MAAM;AAAA,MACJ,GAAI,cAAc,YAAY,QAAQ,CAAC;AAAA,MACvC,CAAC,aAAa,oBAAoB;AAAA,MAClC,CAAC,aAAa,iBAAiB;AAAA,MAC/B,CAAC,mBAAmB;AAAA,MACpB,CAAC,sBAAsB;AAAA,MACvB,CAAC,YAAY;AAAA,MACb,CAAC,aAAa;AAAA,IAChB;AAAA,IACA,KAAK;AAAA,MACH,GAAI,cAAc,YAAY,OAAO,CAAC;AAAA,MACtC,CAAC,aAAa,wBAAwB;AAAA,IACxC;AAAA,IACA,KAAK,CAAC,GAAI,cAAc,YAAY,OAAO,CAAC,GAAI,CAAC,OAAO,GAAG,CAAC,QAAQ,CAAC;AAAA,IACrE,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,UAAU,GAAG,CAAC,OAAO,GAAG,CAAC,QAAQ,CAAC;AAAA,IACpD,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,UAAU,GAAG,CAAC,OAAO,GAAG,CAAC,QAAQ,CAAC;AAAA,IACpD,QAAQ,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC;AAAA,IAC1B,QAAQ;AAAA,MACN,GAAI,cAAc,YAAY,UAAU,CAAC;AAAA,MACzC,CAAC,aAAa,gBAAgB,mBAAmB;AAAA,MACjD,CAAC,eAAe;AAAA,MAChB,CAAC,iBAAiB;AAAA,MAClB,CAAC,iBAAiB;AAAA,MAClB,CAAC,mBAAmB;AAAA,IACtB;AAAA,IACA,QAAQ;AAAA,MACN,GAAI,cAAc,YAAY,UAAU,CAAC;AAAA,MACzC,CAAC,aAAa,sBAAsB;AAAA,MACpC,CAAC,aAAa;AAAA,MACd,CAAC,cAAc;AAAA,MACf,CAAC,iBAAiB;AAAA,MAClB,CAAC,mBAAmB;AAAA,IACtB;AAAA,IACA,kBAAkB;AAAA,MAChB,CAAC,aAAa,gBAAgB;AAAA,MAC9B,CAAC,aAAa;AAAA,MACd,CAAC,cAAc;AAAA,MACf,CAAC,kBAAkB;AAAA,MACnB,CAAC,oBAAoB;AAAA,MACrB,CAAC,qBAAqB;AAAA,MACtB,CAAC,uBAAuB;AAAA,MACxB,CAAC,iBAAiB;AAAA,MAClB,CAAC,mBAAmB;AAAA,IACtB;AAAA,IACA,gBAAgB;AAAA,MACd,CAAC,KAAK;AAAA,MACN,CAAC,OAAO;AAAA,MACR,CAAC,QAAQ;AAAA,MACT,CAAC,eAAe;AAAA,MAChB,CAAC,iBAAiB;AAAA,MAClB,CAAC,iBAAiB;AAAA,MAClB,CAAC,mBAAmB;AAAA,IACtB;AAAA,IACA,kBAAkB;AAAA,MAChB,CAAC,YAAY;AAAA,MACb,CAAC,aAAa;AAAA,MACd,CAAC,cAAc;AAAA,MACf,CAAC,eAAe;AAAA,MAChB,CAAC,mBAAmB;AAAA,MACpB,CAAC,qBAAqB;AAAA,IACxB;AAAA,IACA,MAAM,cAAc,YAAY,QAAQ,CAAC;AAAA,EAC3C;AAAA,EACA,UAAU;AAAA,IACR,GAAI,cAAc,YAAY,CAAC;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAsB,eACpB,KACA,SACuB;AACvB,QAAM,SAAS,OAAO,GAAG;AACzB,QAAM,aAAa,QAAQ,MAAM,UAAU;AAC3C,QAAM,YAAY,cAAc,OAAO,EACpC,IAAI,wBAAwB,EAC5B,IAAI,SAAS,EACb,IAAI,gBAAgB,cAAc,EAClC,IAAI,6BAA6B,EACjC,IAAI,wBAAwB,EAC5B,IAAI,WAAW;AAElB,MAAI,aAAa,OAAO,OAAO,GAAG;AAChC,cAAU,IAAI,aAAa;AAAA,MACzB,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,MACR;AAAA,MACA,cAAc;AAAA;AAAA;AAAA,MAGd,iBAAiB;AAAA,MACjB,WAAW;AAAA,MACX,cAAc,CAAC,4BAA4B,CAAC;AAAA,IAC9C,CAAC;AAAA,EACH;AAEA,YACG,IAAI,UAAU,EACd,IAAI,wBAAwB;AAAA,IAC3B,UAAU;AAAA,IACV,SAAS;AAAA,IACT,YAAY,EAAE,WAAW,CAAC,qBAAqB,EAAE;AAAA,EACnD,CAAC,EACA,IAAI,2BAA2B,EAC/B,IAAI,wBAAwB,EAC5B,IAAI,mBAAmB,EACvB,IAAI,aAAa;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,QAAQ;AAAA,EACtB,CAAC;AAEH,QAAM,OAAO,MAAM,UAAU,QAAQ,OAAO,OAAO;AACnD,QAAM,cAAc,OAAO;AAC3B,QAAM,sBAAsB;AAAA,IAC1B,KAAK;AAAA,IACL;AAAA,EACF,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,OAAO,QAAQ,IAAI,GAAG,QAAQ,KAAK,OAAO,EAAE;AACvE,QAAM,QAAQ,OAAO;AAAA,IACnB,GAAG,aAAqB,KAAK,MAAM,qBAAqB;AAAA,IACxD,GAAG,aAAqB,KAAK,MAAM,OAAO;AAAA,EAC5C,CAAC;AACD,QAAM,MAAM,aAAsB,KAAK,MAAM,KAAK;AAClD,QAAM,YAAY,iBAAiB,OAAO,OAAO;AAEjD,SAAO;AAAA,IACL,SAAS,KAAK;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,iBAAiB,qBAAqB,CAAC,CAAC;AAAA,IACrD;AAAA,IACA,OAAO,SAAS,aAAa,SAAS;AAAA,IACtC,aAAa,eAAe,WAAW;AAAA,IACvC,MAAM,QAAQ,aAAa,OAAO,SAAS,EAAE,QAAQ,WAAW,CAAC;AAAA,EACnE;AACF;AAEA,eAAsB,mBACpB,KACA,SACiB;AACjB,QAAM,SAAS,OAAO,GAAG;AACzB,QAAM,YAAY,cAAc,OAAO,EACpC,IAAI,wBAAwB,EAC5B,IAAI,SAAS,EACb,IAAI,gBAAgB,cAAc,EAClC,IAAI,6BAA6B,EACjC,IAAI,wBAAwB,EAC5B,IAAI,WAAW;AAElB,MAAI,aAAa,OAAO,OAAO,GAAG;AAChC,cAAU,IAAI,aAAa;AAAA,MACzB,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,MACR;AAAA,MACA,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,WAAW;AAAA,MACX,cAAc,CAAC,4BAA4B,CAAC;AAAA,IAC9C,CAAC;AAAA,EACH;AAEA,YAAU,IAAI,mBAAmB,EAAE,IAAI,eAAe;AAEtD,QAAM,OAAO,MAAM,UAAU,QAAQ,OAAO,OAAO;AACnD,SAAO,OAAO,IAAI;AACpB;AAEA,eAAsB,gBACpB,KACA,SACwB;AACxB,QAAM,SAAS,OAAO,GAAG;AACzB,QAAM,aAAa,QAAQ,MAAM,UAAU;AAC3C,QAAM,OAAO,MAAM,kBAAkB,OAAO,SAAS,OAAO;AAC5D,QAAM,YAAY,iBAAiB,OAAO,OAAO;AACjD,QAAM,cAAc,OAAO;AAC3B,QAAM,cAAc;AAAA,IAClB,KAAK;AAAA,IACL;AAAA,EACF,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,OAAO,QAAQ,IAAI,GAAG,QAAQ,KAAK,OAAO,EAAE;AACvE,QAAM,cAAc,eAAe,WAAW;AAE9C,SAAO;AAAA,IACL;AAAA,IACA,KAAK,CAAC;AAAA,IACN,OAAO,aAAqB,KAAK,MAAM,qBAAqB;AAAA,IAC5D;AAAA,IACA;AAAA,IACA,OAAO,SAAS,aAAa,SAAS;AAAA,IACtC;AAAA,IACA,sBAAsB,cAClB,SACA,+BAA+B,OAAO,OAAO;AAAA,IACjD,MAAM,QAAQ,aAAa,OAAO,SAAS,EAAE,QAAQ,WAAW,CAAC;AAAA,EACnE;AACF;AAEO,SAAS,SACd,aACA,WACoB;AACpB,MAAI,OAAO,YAAY,UAAU,YAAY,YAAY,MAAM,KAAK;AAClE,WAAO,YAAY,MAAM,KAAK;AAChC,QAAM,UAAU,UACb,MAAM,IAAI,EACV,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,KAAK,OAAO;AACf,SAAO,SAAS,QAAQ,UAAU,EAAE;AACtC;AAEO,SAAS,eACd,aACoB;AACpB,MACE,OAAO,YAAY,gBAAgB,YACnC,YAAY,YAAY,KAAK,GAC7B;AACA,WAAO,eAAe,YAAY,YAAY,KAAK,CAAC;AAAA,EACtD;AACA,SAAO;AACT;AAEO,SAAS,+BACd,UACA,YAAY,KACQ;AACpB,SAAO,eAAe,UAAU,WAAW,EAAE,oBAAoB,KAAK,CAAC;AACzE;AAEO,SAAS,mBACd,OAIA,YAAY,KACQ;AACpB,QAAM,OAAO,MAAM,eAAe,MAAM;AACxC,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,KAAK,UAAU,UAAW,QAAO;AACrC,SAAO,eAAe,MAAM,SAAS;AACvC;AAEA,SAAS,eACP,MACA,WACA,UAA4B,CAAC,GACT;AACpB,QAAM,UAAU,iBAAiB,MAAM,OAAO,EAAE,KAAK;AACrD,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,cAAc,OAAW,QAAO;AACpC,QAAM,YAAY,QAAQ,MAAM,GAAG,SAAS,EAAE,KAAK;AACnD,SAAO,aAAa;AACtB;AAEA,SAAS,cAAc,SAAwB;AAC7C,SAAO,QAAQ,EACZ,IAAI,WAAW,EACf,IAAI,mBAAmB,CAAC,MAAM,CAAC,EAC/B,IAAI,SAAS,EACb,IAAI,UAAU,EACd,IAAI,gBAAgB,EAAE,YAAY,QAAQ,MAAM,UAAU,KAAK,CAAC,EAChE,IAAI,sBAAsB,OAAO,EACjC,IAAI,cAAc;AAAA,IACjB,oBAAoB;AAAA,IACpB,UAAU,6BAA6B,OAAO;AAAA,EAChD,CAAC;AACL;AAEA,eAAe,kBAAkB,UAAkB,SAAwB;AACzE,QAAM,YAAY,QAAQ,EACvB,IAAI,WAAW,EACf,IAAI,mBAAmB,CAAC,MAAM,CAAC,EAC/B,IAAI,SAAS,EACb,IAAI,UAAU,EACd,IAAI,gBAAgB,EAAE,YAAY,QAAQ,MAAM,UAAU,KAAK,CAAC,EAChE,IAAI,sBAAsB,OAAO;AACpC,QAAM,OAAO,UAAU,MAAM,QAAQ;AACrC,QAAM,OAAO,EAAE,MAAM,CAAC,EAAE;AACxB,QAAM,UAAU,IAAI,MAAM,IAAI;AAC9B,SAAO;AACT;AAEA,SAAS,iBACP,UACA,UAA4B,CAAC,GACrB;AACR,QAAM,OAAO,uBAAuB,QAAQ;AAC5C,QAAM,WACJ,QAAQ,sBAAsB,KAAK,WAAW,CAAC,GAAG,SAAS,YACvD,KAAK,SAAS,MAAM,CAAC,IACpB,KAAK,YAAY,CAAC;AACzB,QAAM,QAAkB,CAAC;AAEzB,aAAW,SAAS,UAAU;AAC5B,qBAAiB,OAAO,KAAK;AAAA,EAC/B;AAEA,SAAO,mBAAmB,MAAM,KAAK,GAAG,CAAC;AAC3C;AAEA,SAAS,uBAAuB,UAA6B;AAC3D,SAAO,QAAQ,EACZ,IAAI,WAAW,EACf,IAAI,mBAAmB,CAAC,MAAM,CAAC,EAC/B,IAAI,SAAS,EACb,IAAI,UAAU,EACd,IAAI,cAAc,EAClB,MAAM,QAAQ;AACnB;AAEA,SAAS,iBAAiB,MAAiB,OAAuB;AAChE,MAAI,mBAAmB,IAAI,KAAK,IAAI,EAAG;AAEvC,MAAI,KAAK,SAAS,eAAe;AAC/B,UAAM,MAAM,KAAK,KAAK,QAAQ,MAAM,EAAE;AACtC,UAAM,MAAM,OAAO,KAAK;AACxB,QAAI,IAAK,OAAM,KAAK,GAAG;AACvB;AAAA,EACF;AAEA,MAAI,OAAO,KAAK,UAAU,UAAU;AAClC,UAAM,KAAK,KAAK,KAAK;AAAA,EACvB;AAEA,aAAW,SAAS,KAAK,YAAY,CAAC,GAAG;AACvC,qBAAiB,OAAO,KAAK;AAAA,EAC/B;AACF;AAEA,SAAS,mBAAmB,MAAsB;AAChD,SAAO,KACJ,QAAQ,QAAQ,GAAG,EACnB,QAAQ,kBAAkB,IAAI,EAC9B,KAAK;AACV;AAEA,SAAS,aAAa,UAA2B;AAC/C,SAAO,kBAAkB,KAAK,QAAQ;AACxC;AAEA,SAAS,OAAO,QAA4B;AAC1C,SAAO,CAAC,GAAG,IAAI,IAAI,OAAO,OAAO,OAAO,CAAC,CAAC;AAC5C;","names":["visit","visit"]}
|