@orkestrel/markdown 0.0.13 → 0.0.14

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../../../src/core/constants.ts","../../../src/core/validators.ts","../../../src/core/parsers.ts","../../../src/core/helpers.ts","../../../src/core/compilers.ts","../../../src/core/shapers.ts","../../../src/core/Markdown.ts","../../../src/core/factories.ts"],"sourcesContent":["import type { MarkdownProjection } from './types.js'\n\n/**\n * Caps the recursion depth the parse pipeline (`parseDocument` and its\n * `parsers.ts` helpers), the `helpers.ts` traversal / projection functions\n * (`markdownToHTML`, `renderMarkdown`, `walkNodes`, `foldNode`, `rewriteDocument`),\n * and the `compilers.ts` renderer (`renderHTML`) honor before degrading. It bounds blockquote nesting, inline\n * nesting (emphasis / links), and traversal / projection recursion so pathological\n * or hostile input cannot exhaust the call stack. {@link htmlToMarkdown} is the\n * inherited exception: its fold and depth cap belong to `@orkestrel/html`.\n */\nexport const MAX_DEPTH = 64\n\n/**\n * Holds the frozen empty HTML-to-markdown projection from which projection factories\n * default every absent field.\n *\n * @example\n * ```ts\n * EMPTY_PROJECTION.blocks // []\n * Object.isFrozen(EMPTY_PROJECTION) // true\n * ```\n */\nexport const EMPTY_PROJECTION: MarkdownProjection = Object.freeze({\n\tblocks: Object.freeze([]),\n\tinlines: Object.freeze([]),\n\ttext: '',\n\tcells: Object.freeze([]),\n\trows: Object.freeze([]),\n})\n","import type { Guard } from '@orkestrel/contract'\nimport type {\n\tBlockNode,\n\tBlockquoteNode,\n\tCodeBlockNode,\n\tCodeSpanNode,\n\tEmphasisNode,\n\tHeadingNode,\n\tImageNode,\n\tInlineNode,\n\tLineBreakNode,\n\tLinkNode,\n\tListNode,\n\tMarkdownDocument,\n\tMarkdownNode,\n\tParagraphNode,\n\tTableNode,\n\tTextNode,\n\tThematicBreakNode,\n} from './types.js'\nimport {\n\tarrayOf,\n\tisBoolean,\n\tisNumber,\n\tisString,\n\tliteralOf,\n\tlazyOf,\n\tnullableOf,\n\trecordOf,\n\tunionOf,\n} from '@orkestrel/contract'\n\n// Guards are total. This file owns the type narrowers alone: node guards that\n// narrow a MarkdownNode to one parsed block / inline variant by its element tag,\n// and the from-unknown guards that validate an arbitrary value against the full\n// AST shape. The line / character structural predicates the parser tests raw\n// strings with narrow nothing, so they are pure leaves and live in helpers.ts.\n\n// === Block guards\n\n/**\n * Determines whether a node is a heading block.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link HeadingNode}; false otherwise\n *\n * @example\n * ```ts\n * isHeadingNode({ element: 'heading', level: 1, children: [] }) // true\n * ```\n */\nexport function isHeadingNode(node: MarkdownNode): node is HeadingNode {\n\treturn node.element === 'heading'\n}\n\n/**\n * Determines whether a node is a paragraph block.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link ParagraphNode}; false otherwise\n *\n * @example\n * ```ts\n * isParagraphNode({ element: 'paragraph', children: [] }) // true\n * ```\n */\nexport function isParagraphNode(node: MarkdownNode): node is ParagraphNode {\n\treturn node.element === 'paragraph'\n}\n\n/**\n * Determines whether a node is a list block.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link ListNode}; false otherwise\n *\n * @example\n * ```ts\n * isListNode({ element: 'list', ordered: false, start: 1, items: [] }) // true\n * ```\n */\nexport function isListNode(node: MarkdownNode): node is ListNode {\n\treturn node.element === 'list'\n}\n\n/**\n * Determines whether a node is a GFM table block.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link TableNode}; false otherwise\n *\n * @example\n * ```ts\n * isTableNode({ element: 'table', header: [], rows: [], align: [] }) // true\n * ```\n */\nexport function isTableNode(node: MarkdownNode): node is TableNode {\n\treturn node.element === 'table'\n}\n\n/**\n * Determines whether a node is a fenced code block.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link CodeBlockNode}; false otherwise\n *\n * @example\n * ```ts\n * isCodeBlockNode({ element: 'codeBlock', code: 'x' }) // true\n * ```\n */\nexport function isCodeBlockNode(node: MarkdownNode): node is CodeBlockNode {\n\treturn node.element === 'codeBlock'\n}\n\n/**\n * Determines whether a node is a blockquote block.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link BlockquoteNode}; false otherwise\n *\n * @example\n * ```ts\n * isBlockquoteNode({ element: 'blockquote', children: [] }) // true\n * ```\n */\nexport function isBlockquoteNode(node: MarkdownNode): node is BlockquoteNode {\n\treturn node.element === 'blockquote'\n}\n\n/**\n * Determines whether a node is a thematic break (horizontal rule) block.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link ThematicBreakNode}; false otherwise\n *\n * @example\n * ```ts\n * isThematicBreakNode({ element: 'thematicBreak' }) // true\n * ```\n */\nexport function isThematicBreakNode(node: MarkdownNode): node is ThematicBreakNode {\n\treturn node.element === 'thematicBreak'\n}\n\n// === Inline guards\n\n/**\n * Determines whether a node is a plain text run.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link TextNode}; false otherwise\n *\n * @example\n * ```ts\n * isTextNode({ element: 'text', value: 'hi' }) // true\n * ```\n */\nexport function isTextNode(node: MarkdownNode): node is TextNode {\n\treturn node.element === 'text'\n}\n\n/**\n * Determines whether a node is an emphasis run (`*em*` / `**strong**`).\n *\n * @param node - The AST node to test\n * @returns True if the node is an {@link EmphasisNode}; false otherwise\n *\n * @example\n * ```ts\n * isEmphasisNode({ element: 'emphasis', strong: false, children: [] }) // true\n * ```\n */\nexport function isEmphasisNode(node: MarkdownNode): node is EmphasisNode {\n\treturn node.element === 'emphasis'\n}\n\n/**\n * Determines whether a node is an inline code span.\n *\n * @remarks\n * Narrows to {@link CodeSpanNode} - the node whose `element` discriminant is\n * `'codeSpan'`.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link CodeSpanNode}; false otherwise\n *\n * @example\n * ```ts\n * isCodeSpanNode({ element: 'codeSpan', value: 'x' }) // true\n * ```\n */\nexport function isCodeSpanNode(node: MarkdownNode): node is CodeSpanNode {\n\treturn node.element === 'codeSpan'\n}\n\n/**\n * Determines whether a node is a GFM hard line break.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link LineBreakNode}; false otherwise\n *\n * @example\n * ```ts\n * isLineBreakNode({ element: 'break' }) // true\n * ```\n */\nexport function isLineBreakNode(node: MarkdownNode): node is LineBreakNode {\n\treturn node.element === 'break'\n}\n\n/**\n * Determines whether a node is a link.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link LinkNode}; false otherwise\n *\n * @example\n * ```ts\n * isLinkNode({ element: 'link', href: 'https://example.dev', children: [] }) // true\n * ```\n */\nexport function isLinkNode(node: MarkdownNode): node is LinkNode {\n\treturn node.element === 'link'\n}\n\n/**\n * Determines whether a node is an image.\n *\n * @param node - The AST node to test\n * @returns True if the node is an {@link ImageNode}; false otherwise\n *\n * @example\n * ```ts\n * isImageNode({ element: 'image', src: 'x.png', children: [] }) // true\n * ```\n */\nexport function isImageNode(node: MarkdownNode): node is ImageNode {\n\treturn node.element === 'image'\n}\n\n// === From-unknown AST guards\n//\n// The node guards above narrow an ALREADY-PARSED MarkdownNode by its `element`\n// tag. The guards below instead validate an arbitrary `unknown` value (untrusted\n// input - a deserialized AST, a value crossing a process/RPC boundary) against\n// the full node shape, field by field, composed from @orkestrel/contract\n// combinators. Each guard IS its own hoisted composed value (compiled once at\n// module init, not per call); inline<->block recursion (emphasis/link/image children,\n// list items, blockquote children) resolves through `lazyOf`, closing over the\n// exported guard names themselves - legal because `lazyOf`'s thunk resolves per\n// call, strictly after module init has assigned every export. @orkestrel/contract\n// guarantees guard totality: `lazyOf`, `unionOf`, `recordOf`, and\n// every built-in guard are throw-contained, so a hostile getter, a structural\n// cycle, or pathologically deep input returns `false` rather than throwing -\n// no additional `attempt` wrapping is needed here.\n\n/**\n * Determines whether an arbitrary value is a valid {@link InlineNode} - a text\n * run, emphasis, code span, hard break, link, or image, recursively validated.\n *\n * @remarks\n * Total: never throws, even on cyclic or pathologically deep input - every\n * combinator involved (`unionOf`, `recordOf`, `arrayOf`, `lazyOf`) is\n * throw-contained per the `@orkestrel/contract` guard contract.\n *\n * @param value - The value to test\n * @returns True if `value` is a well-formed {@link InlineNode}; false otherwise\n *\n * @example\n * ```ts\n * import { isInlineNode } from '@orkestrel/markdown'\n *\n * isInlineNode({ element: 'text', value: 'hi' }) // true\n * isInlineNode({ element: 'text' }) // false - missing `value`\n * ```\n */\nexport const isInlineNode: Guard<InlineNode> = unionOf(\n\trecordOf({ element: literalOf('text'), value: isString }),\n\trecordOf({\n\t\telement: literalOf('emphasis'),\n\t\tstrong: isBoolean,\n\t\tchildren: arrayOf(lazyOf(() => isInlineNode)),\n\t}),\n\trecordOf({ element: literalOf('codeSpan'), value: isString }),\n\trecordOf({ element: literalOf('break') }),\n\trecordOf({\n\t\telement: literalOf('link'),\n\t\thref: isString,\n\t\tchildren: arrayOf(lazyOf(() => isInlineNode)),\n\t}),\n\trecordOf({\n\t\telement: literalOf('image'),\n\t\tsrc: isString,\n\t\tchildren: arrayOf(lazyOf(() => isInlineNode)),\n\t}),\n)\n\n/**\n * Determines whether an arbitrary value is a valid {@link BlockNode} - a\n * heading, paragraph, list, table, code block, blockquote, or thematic break,\n * recursively validated.\n *\n * @remarks\n * Total: never throws, even on cyclic or pathologically deep input - every\n * combinator involved (`unionOf`, `recordOf`, `arrayOf`, `lazyOf`) is\n * throw-contained per the `@orkestrel/contract` guard contract.\n * A list item's shape is inlined here (and in {@link isMarkdownNode}) rather\n * than named separately - it is used at exactly these two sites.\n *\n * @param value - The value to test\n * @returns True if `value` is a well-formed {@link BlockNode}; false otherwise\n *\n * @example\n * ```ts\n * import { isBlockNode } from '@orkestrel/markdown'\n *\n * isBlockNode({ element: 'thematicBreak' }) // true\n * isBlockNode({ element: 'heading' }) // false - missing `level` / `children`\n * ```\n */\nexport const isBlockNode: Guard<BlockNode> = unionOf(\n\trecordOf({ element: literalOf('heading'), level: isNumber, children: arrayOf(isInlineNode) }),\n\trecordOf({ element: literalOf('paragraph'), children: arrayOf(isInlineNode) }),\n\trecordOf({\n\t\telement: literalOf('list'),\n\t\tordered: isBoolean,\n\t\tstart: isNumber,\n\t\titems: arrayOf(\n\t\t\trecordOf({ element: literalOf('listItem'), children: arrayOf(lazyOf(() => isBlockNode)) }),\n\t\t),\n\t}),\n\trecordOf({\n\t\telement: literalOf('table'),\n\t\theader: arrayOf(arrayOf(isInlineNode)),\n\t\trows: arrayOf(arrayOf(arrayOf(isInlineNode))),\n\t\talign: arrayOf(nullableOf(literalOf('left', 'right', 'center'))),\n\t}),\n\trecordOf({ element: literalOf('codeBlock'), lang: isString, code: isString }, ['lang']),\n\trecordOf({ element: literalOf('blockquote'), children: arrayOf(lazyOf(() => isBlockNode)) }),\n\trecordOf({ element: literalOf('thematicBreak') }),\n)\n\n/**\n * Determines whether an arbitrary value is a valid {@link MarkdownNode} - the\n * {@link MarkdownDocument} root, a {@link BlockNode}, a {@link ListItemNode}, or\n * an {@link InlineNode}, recursively validated.\n *\n * @remarks\n * Total: never throws, even on cyclic or pathologically deep input - every\n * combinator involved (`unionOf`, `recordOf`, `arrayOf`, `lazyOf`) is\n * throw-contained per the `@orkestrel/contract` guard contract.\n * A list item's shape is inlined here (and in {@link isBlockNode}) rather than\n * named separately - it is used at exactly these two sites.\n *\n * @param value - The value to test\n * @returns True if `value` is a well-formed {@link MarkdownNode}; false otherwise\n *\n * @example\n * ```ts\n * import { isMarkdownNode } from '@orkestrel/markdown'\n *\n * isMarkdownNode({ element: 'text', value: 'hi' }) // true\n * isMarkdownNode({ element: 'bogus' }) // false\n * ```\n */\nexport const isMarkdownNode: Guard<MarkdownNode> = unionOf(\n\tlazyOf(() => isMarkdownDocument),\n\tlazyOf(() => isBlockNode),\n\trecordOf({ element: literalOf('listItem'), children: arrayOf(lazyOf(() => isBlockNode)) }),\n\tlazyOf(() => isInlineNode),\n)\n\n/**\n * Determines whether an arbitrary value is a valid {@link MarkdownDocument} -\n * the parsed-AST root {@link parseDocument} returns, recursively\n * validated.\n *\n * @remarks\n * Total: never throws, even on cyclic or pathologically deep input - every\n * combinator involved (`recordOf`, `arrayOf`) is throw-contained per the\n * `@orkestrel/contract` guard contract.\n *\n * @param value - The value to test\n * @returns True if `value` is a well-formed {@link MarkdownDocument}; false otherwise\n *\n * @example\n * ```ts\n * import { isMarkdownDocument } from '@orkestrel/markdown'\n *\n * isMarkdownDocument({ element: 'document', children: [] }) // true\n * isMarkdownDocument({ element: 'document' }) // false - missing `children`\n * ```\n */\nexport const isMarkdownDocument: Guard<MarkdownDocument> = recordOf({\n\telement: literalOf('document'),\n\tchildren: arrayOf(isBlockNode),\n})\n","import type {\n\tBlockNode,\n\tInlineNode,\n\tMarkdownDocument,\n\tMarkdownNode,\n\tMarkdownParseResult,\n\tMarkdownSource,\n\tMarkdownSpan,\n} from './types.js'\nimport {\n\tcoalesceText,\n\tcollectList,\n\tcollectTable,\n\textractFence,\n\textractHeading,\n\textractListItem,\n\tisBlankLine,\n\tisFenceClose,\n\tisQuote,\n\tisTableStart,\n\tisThematicBreak,\n\tjoinSources,\n\tnormalizeParagraphLine,\n\tprojectSpan,\n\tscanInline,\n\tscanInlineSource,\n\tsliceSource,\n\tsplitLines,\n\tstartsBlock,\n\tstripQuote,\n} from './helpers.js'\nimport { MAX_DEPTH } from './constants.js'\nimport { isNonEmptyArray } from '@orkestrel/contract'\n\n/**\n * Parses a run of markdown lines into a block AST, recursing into nested\n * blockquotes, list items, and depth-capped degrade paragraphs.\n *\n * @param lines - The markdown lines to parse.\n * @param depth - The current recursion depth (blockquotes/lists increment it).\n * @param spans - The optional operation-owned node span recorder.\n * @param end - The original-source end of this line run, including a removed terminator.\n * @returns The parsed block nodes.\n *\n * @example\n * ```ts\n * parseBlocks(splitLines('# Hi'), 0) // [{ element: 'heading', level: 1, children: [...] }]\n * ```\n */\nexport function parseBlocks(\n\tlines: readonly MarkdownSource[],\n\tdepth: number,\n\tspans = new Map<MarkdownNode, MarkdownSpan>(),\n\tend?: number,\n): readonly BlockNode[] {\n\tconst text = lines.map((line) => line.text)\n\tif (depth >= MAX_DEPTH) {\n\t\tif (lines.length === 0) return []\n\t\tconst source = joinSources(lines, '\\n')\n\t\tconst inline: InlineNode = { element: 'text', value: source.text }\n\t\tconst paragraph: BlockNode = { element: 'paragraph', children: [inline] }\n\t\tconst span = projectSpan(source, 0, source.text.length)\n\t\tif (span !== undefined) {\n\t\t\tspans.set(inline, span)\n\t\t\tspans.set(paragraph, span)\n\t\t}\n\t\treturn [paragraph]\n\t}\n\tconst blocks: BlockNode[] = []\n\tlet index = 0\n\twhile (index < lines.length) {\n\t\tconst line = text[index] ?? ''\n\t\tif (isBlankLine(line)) {\n\t\t\tindex += 1\n\t\t\tcontinue\n\t\t}\n\t\tconst fence = extractFence(line)\n\t\tif (fence) {\n\t\t\tconst start = index\n\t\t\tconst body: MarkdownSource[] = []\n\t\t\tlet closed = false\n\t\t\tindex += 1\n\t\t\twhile (index < lines.length && !isFenceClose(text[index] ?? '', fence.marker)) {\n\t\t\t\tconst bodyLine = lines[index]\n\t\t\t\tif (bodyLine !== undefined) body.push(bodyLine)\n\t\t\t\tindex += 1\n\t\t\t}\n\t\t\tif (index < lines.length) {\n\t\t\t\tclosed = true\n\t\t\t\tindex += 1\n\t\t\t}\n\t\t\tconst node: BlockNode = {\n\t\t\t\telement: 'codeBlock',\n\t\t\t\t...(fence.lang === undefined ? {} : { lang: fence.lang }),\n\t\t\t\tcode: joinSources(body, '\\n').text,\n\t\t\t}\n\t\t\tconst source = joinSources(lines.slice(start, index), '\\n')\n\t\t\tconst span = projectSpan(source, 0, source.text.length)\n\t\t\tif (span !== undefined)\n\t\t\t\tspans.set(node, !closed && end !== undefined ? { start: span.start, end } : span)\n\t\t\tblocks.push(node)\n\t\t\tcontinue\n\t\t}\n\t\tif (isThematicBreak(line)) {\n\t\t\tconst node: BlockNode = { element: 'thematicBreak' }\n\t\t\tconst source = lines[index]\n\t\t\tconst span = source === undefined ? undefined : projectSpan(source, 0, source.text.length)\n\t\t\tif (span !== undefined) spans.set(node, span)\n\t\t\tblocks.push(node)\n\t\t\tindex += 1\n\t\t\tcontinue\n\t\t}\n\t\tconst heading = extractHeading(line)\n\t\tif (heading) {\n\t\t\tconst source = lines[index]\n\t\t\tconst content =\n\t\t\t\tsource === undefined\n\t\t\t\t\t? { text: heading.text, segments: [] }\n\t\t\t\t\t: sliceSource(source, heading.offset, heading.offset + heading.text.length)\n\t\t\tconst node: BlockNode = {\n\t\t\t\telement: 'heading',\n\t\t\t\tlevel: heading.level,\n\t\t\t\tchildren: coalesceText(scanInlineSource(content, 0, content.text.length, spans), spans),\n\t\t\t}\n\t\t\tconst span = source === undefined ? undefined : projectSpan(source, 0, source.text.length)\n\t\t\tif (span !== undefined) spans.set(node, span)\n\t\t\tblocks.push(node)\n\t\t\tindex += 1\n\t\t\tcontinue\n\t\t}\n\t\tif (isQuote(line)) {\n\t\t\tconst start = index\n\t\t\tconst quoted: MarkdownSource[] = []\n\t\t\twhile (index < lines.length && isQuote(text[index] ?? '')) {\n\t\t\t\tconst quotedLine = lines[index]\n\t\t\t\tif (quotedLine === undefined) break\n\t\t\t\tquoted.push(stripQuote(quotedLine))\n\t\t\t\tindex += 1\n\t\t\t}\n\t\t\tconst source = joinSources(lines.slice(start, index), '\\n')\n\t\t\tconst span = projectSpan(source, 0, source.text.length)\n\t\t\tconst node: BlockNode = {\n\t\t\t\telement: 'blockquote',\n\t\t\t\tchildren: parseBlocks(\n\t\t\t\t\tquoted,\n\t\t\t\t\tdepth + 1,\n\t\t\t\t\tspans,\n\t\t\t\t\tindex === lines.length && end !== undefined ? end : span?.end,\n\t\t\t\t),\n\t\t\t}\n\t\t\tif (span !== undefined) spans.set(node, span)\n\t\t\tblocks.push(node)\n\t\t\tcontinue\n\t\t}\n\t\tif (isTableStart(line, text[index + 1])) {\n\t\t\tconst table = collectTable(lines, index, spans)\n\t\t\tblocks.push(table.node)\n\t\t\tindex = table.next\n\t\t\tcontinue\n\t\t}\n\t\tif (extractListItem(line)) {\n\t\t\tconst list = collectList(lines, index, depth, spans, end)\n\t\t\tblocks.push(list.node)\n\t\t\tindex = list.next\n\t\t\tcontinue\n\t\t}\n\t\tconst start = index\n\t\tconst paragraph: MarkdownSource[] = []\n\t\twhile (\n\t\t\tindex < lines.length &&\n\t\t\t!isBlankLine(text[index] ?? '') &&\n\t\t\t!(isNonEmptyArray(paragraph) && startsBlock(text, index))\n\t\t) {\n\t\t\tconst paragraphLine = lines[index]\n\t\t\tif (paragraphLine !== undefined) paragraph.push(paragraphLine)\n\t\t\tindex += 1\n\t\t}\n\t\tconst source = joinSources(\n\t\t\tparagraph.map((paragraphLine, position) =>\n\t\t\t\tnormalizeParagraphLine(paragraphLine, position < paragraph.length - 1),\n\t\t\t),\n\t\t\t'\\n',\n\t\t)\n\t\tconst node: BlockNode = {\n\t\t\telement: 'paragraph',\n\t\t\tchildren: coalesceText(scanInlineSource(source, 0, source.text.length, spans), spans),\n\t\t}\n\t\tconst region = joinSources(lines.slice(start, index), '\\n')\n\t\tconst span = projectSpan(region, 0, region.text.length)\n\t\tif (span !== undefined) spans.set(node, span)\n\t\tblocks.push(node)\n\t}\n\treturn blocks\n}\n\n/**\n * Parses a markdown string into a typed {@link MarkdownDocument} AST through the\n * block phase.\n *\n * @param markdown - The markdown source to parse.\n * @returns The parsed document.\n *\n * @example\n * ```ts\n * parseDocument('# Hi') // { element: 'document', children: [{ element: 'heading', ... }] }\n * ```\n */\nexport function parseDocument(markdown: string): MarkdownDocument {\n\tconst [document] = parseProvenance(markdown)\n\treturn document\n}\n\n/**\n * Parses a markdown string into a document and its original-source spans.\n *\n * @param markdown - The markdown source to parse.\n * @returns The parsed document and its node-identity span map.\n *\n * @example\n * ```ts\n * const [document, spans] = parseProvenance('# Hi')\n * spans.get(document) // { start: 0, end: 4 }\n * ```\n */\nexport function parseProvenance(markdown: string): MarkdownParseResult {\n\tconst spans = new Map<MarkdownNode, MarkdownSpan>()\n\tconst document: MarkdownDocument = {\n\t\telement: 'document',\n\t\tchildren: parseBlocks(splitLines(markdown), 0, spans, markdown.length),\n\t}\n\tspans.set(document, { start: 0, end: markdown.length })\n\treturn [document, spans]\n}\n\n/**\n * Parses inline markdown text (emphasis, code spans, links, images, and hard\n * breaks) into inline AST nodes, coalescing adjacent text runs.\n *\n * @param text - The inline markdown text to parse.\n * @returns The parsed inline nodes.\n *\n * @example\n * ```ts\n * parseInline('a *b*') // [{ element: 'text', value: 'a ' }, { element: 'emphasis', ... }]\n * ```\n */\nexport function parseInline(text: string): readonly InlineNode[] {\n\treturn coalesceText(scanInline(text, 0, text.length))\n}\n","import type {\n\tCommentNode,\n\tDoctypeNode,\n\tElementNode,\n\tHTMLDocument,\n\tHTMLNode,\n\tTextNode as HTMLTextNode,\n} from '@orkestrel/html'\nimport type {\n\tBlockNode,\n\tCodeSpanMatch,\n\tEmphasisBounds,\n\tEmphasisScan,\n\tFenceMatch,\n\tHeadingMatch,\n\tInlineNode,\n\tLinkBounds,\n\tLinkScan,\n\tListCollection,\n\tListItemNode,\n\tListItemMatch,\n\tListNode,\n\tMarkdownCell,\n\tMarkdownDerivation,\n\tMarkdownDocument,\n\tMarkdownHandlerMap,\n\tMarkdownNode,\n\tMarkdownProjection,\n\tMarkdownRewriteHandler,\n\tMarkdownSegment,\n\tMarkdownSource,\n\tMarkdownSpan,\n\tTableAlign,\n\tTableCollection,\n\tTableNode,\n} from './types.js'\nimport { EMPTY_PROJECTION, MAX_DEPTH } from './constants.js'\nimport { isBlockNode, isInlineNode } from './validators.js'\nimport { parseBlocks } from './parsers.js'\nimport { isEmptyString, isNonEmptyArray, isNonEmptyString, parseInteger } from '@orkestrel/contract'\nimport {\n\tSAFE_URL_SCHEMES,\n\tTABLE_ALIGNMENTS,\n\tUNSAFE_ELEMENTS,\n\tattributeOf,\n\tcollapseSpace,\n\tfoldNode as foldHTMLNode,\n\trenderText,\n\tsanitizeURL,\n} from '@orkestrel/html'\n\n// Markdown parsing + rendering leaves (pure and total)\n//\n// The pure leaf primitives {@link parseDocument} composes: the line / character\n// structural predicates (blank lines, quotes, fence closers, thematic breaks, table\n// starts, escapable and whitespace characters), the line / block scanners (headings,\n// fences, list items, table rows), the `collect*` construct scanners (GFM tables and\n// lists), the inline `scan*` engine (emphasis / links / code with backslash escapes),\n// and the HTML AST projection the renderer composes with @orkestrel/html. A predicate\n// over a raw `string` is a leaf rather than a `Guard<T>`, so it lives here and not in\n// validators.ts. Every function is PURE, TOTAL, and referentially transparent -\n// malformed input degrades to text, never throws - so each is unit-tested in isolation.\n// The `parse*` ENTRY POINTS that thread these together (the block / inline phase\n// entries) live in parsers.ts: a helper is a functional-core leaf, a parser is the\n// phase it names. A construct scanner calls back into its phase entry, so helpers.ts\n// and parsers.ts are mutually recursive by design. Inline scanning is index-based (no\n// backtracking regex) so it is linear-time - no ReDoS on adversarial input.\n//\n// This file imports no implementation class: the class-driving renderer that composes\n// {@link markdownToHTML} with `@orkestrel/html`'s sanitizer lives in compilers.ts.\n\n// Text + line utilities\n\n/**\n * Splits a markdown document into offset-bearing lines while normalizing CRLF and\n * bare CR terminators at the line boundary. A single trailing terminator does not\n * yield a final empty line.\n *\n * @param markdown - The raw markdown source\n * @returns The document's lines with their original-string coordinates\n *\n * @example\n * ```ts\n * splitLines('a\\r\\nb') // [{ text: 'a', segments: [{ offset: 0, start: 0, end: 1 }] }, ...]\n * ```\n */\nexport function splitLines(markdown: string): readonly MarkdownSource[] {\n\tconst lines: MarkdownSource[] = []\n\tlet start = 0\n\tlet index = 0\n\twhile (index < markdown.length) {\n\t\tconst character = markdown[index]\n\t\tif (character !== '\\r' && character !== '\\n') {\n\t\t\tindex += 1\n\t\t\tcontinue\n\t\t}\n\t\tlines.push({\n\t\t\ttext: markdown.slice(start, index),\n\t\t\tsegments: [{ offset: 0, start, end: index }],\n\t\t})\n\t\tindex += character === '\\r' && markdown[index + 1] === '\\n' ? 2 : 1\n\t\tstart = index\n\t}\n\tlines.push({\n\t\ttext: markdown.slice(start),\n\t\tsegments: [{ offset: 0, start, end: markdown.length }],\n\t})\n\tif (lines.length > 1 && lines[lines.length - 1]?.text === '') lines.pop()\n\treturn lines\n}\n\n/**\n * Slices derived markdown text and narrows each intersecting source segment to the\n * same text-relative range.\n *\n * @param source - The offset-bearing source to slice\n * @param from - The inclusive text offset\n * @param to - The exclusive text offset\n * @returns The sliced text and its narrowed original-string segments\n *\n * @example\n * ```ts\n * sliceSource({ text: 'abc', segments: [{ offset: 0, start: 4, end: 7 }] }, 1, 3)\n * // { text: 'bc', segments: [{ offset: 0, start: 5, end: 7 }] }\n * ```\n */\nexport function sliceSource(source: MarkdownSource, from: number, to: number): MarkdownSource {\n\tconst start = Math.max(0, Math.min(from, source.text.length))\n\tconst end = Math.max(start, Math.min(to, source.text.length))\n\tconst segments: MarkdownSegment[] = []\n\tfor (let index = 0; index < source.segments.length; index += 1) {\n\t\tconst segment = source.segments[index]\n\t\tif (segment === undefined) continue\n\t\tconst next = source.segments[index + 1]\n\t\tconst limit = Math.min(\n\t\t\tsegment.offset + (segment.end - segment.start),\n\t\t\tnext === undefined ? source.text.length : next.offset,\n\t\t)\n\t\tconst overlapStart = Math.max(start, segment.offset)\n\t\tconst overlapEnd = Math.min(end, limit)\n\t\tconst empty = segment.offset === limit && overlapStart === segment.offset\n\t\tif (overlapStart >= overlapEnd && !empty) continue\n\t\tconst originalStart =\n\t\t\toverlapStart === limit\n\t\t\t\t? segment.end\n\t\t\t\t: Math.min(segment.end, segment.start + overlapStart - segment.offset)\n\t\tconst originalEnd =\n\t\t\toverlapEnd === limit\n\t\t\t\t? segment.end\n\t\t\t\t: Math.min(segment.end, segment.start + overlapEnd - segment.offset)\n\t\tsegments.push({\n\t\t\toffset: overlapStart - start,\n\t\t\tstart: originalStart,\n\t\t\tend: originalEnd,\n\t\t})\n\t}\n\treturn { text: source.text.slice(start, end), segments }\n}\n\n/**\n * Joins offset-bearing markdown sources while mapping a separator to the original\n * region between adjacent mapped sources.\n *\n * @param sources - The sources to join\n * @param separator - The derived text inserted between sources\n * @returns The joined text and every source-backed segment\n *\n * @example\n * ```ts\n * joinSources(splitLines('a\\nb'), '\\n')\n * // { text: 'a\\nb', segments: [...] }\n * ```\n */\nexport function joinSources(sources: readonly MarkdownSource[], separator: string): MarkdownSource {\n\tlet text = ''\n\tconst segments: MarkdownSegment[] = []\n\tfor (let index = 0; index < sources.length; index += 1) {\n\t\tconst source = sources[index]\n\t\tif (source === undefined) continue\n\t\tif (index > 0) {\n\t\t\tconst previous = sources[index - 1]\n\t\t\tconst left = previous?.segments[previous.segments.length - 1]\n\t\t\tconst right = source.segments[0]\n\t\t\tif (\n\t\t\t\tseparator.length > 0 &&\n\t\t\t\tleft !== undefined &&\n\t\t\t\tright !== undefined &&\n\t\t\t\tleft.end < right.start\n\t\t\t)\n\t\t\t\tsegments.push({ offset: text.length, start: left.end, end: right.start })\n\t\t\ttext += separator\n\t\t}\n\t\tfor (const segment of source.segments) {\n\t\t\tsegments.push({\n\t\t\t\toffset: text.length + segment.offset,\n\t\t\t\tstart: segment.start,\n\t\t\t\tend: segment.end,\n\t\t\t})\n\t\t}\n\t\ttext += source.text\n\t}\n\treturn { text, segments }\n}\n\n/**\n * Projects a derived text range through its segments to a half-open region of the\n * original markdown string.\n *\n * @param source - The offset-bearing source carrying the range\n * @param from - The inclusive derived-text boundary\n * @param to - The exclusive derived-text boundary\n * @returns The original-string span, or `undefined` when either boundary is unmapped\n *\n * @example\n * ```ts\n * projectSpan({ text: 'a', segments: [{ offset: 0, start: 4, end: 5 }] }, 0, 1)\n * // { start: 4, end: 5 }\n * ```\n */\nexport function projectSpan(\n\tsource: MarkdownSource,\n\tfrom: number,\n\tto: number,\n): MarkdownSpan | undefined {\n\tif (from < 0 || to < from || to > source.text.length) return undefined\n\tlet start: number | undefined\n\tlet end: number | undefined\n\tfor (let index = 0; index < source.segments.length; index += 1) {\n\t\tconst segment = source.segments[index]\n\t\tif (segment === undefined) continue\n\t\tconst next = source.segments[index + 1]\n\t\tconst limit = Math.min(\n\t\t\tsegment.offset + (segment.end - segment.start),\n\t\t\tnext === undefined ? source.text.length : next.offset,\n\t\t)\n\t\tif (from === to && from >= segment.offset && from <= limit) {\n\t\t\tif (next !== undefined && from === next.offset) continue\n\t\t\tconst position =\n\t\t\t\tfrom === limit ? segment.end : Math.min(segment.end, segment.start + from - segment.offset)\n\t\t\treturn { start: position, end: position }\n\t\t}\n\t\tif (start === undefined && from >= segment.offset && from < limit)\n\t\t\tstart = segment.start + from - segment.offset\n\t\tif (to > segment.offset && to <= limit)\n\t\t\tend = to === limit ? segment.end : Math.min(segment.end, segment.start + to - segment.offset)\n\t}\n\treturn start === undefined || end === undefined ? undefined : { start, end }\n}\n\n/**\n * Trims an offset-bearing source without losing the coordinates of its retained text.\n *\n * @param source - The source to trim\n * @returns The trimmed text and its narrowed original-string segments\n *\n * @example\n * ```ts\n * trimSource({ text: ' a ', segments: [{ offset: 0, start: 4, end: 7 }] })\n * // { text: 'a', segments: [{ offset: 0, start: 5, end: 6 }] }\n * ```\n */\nexport function trimSource(source: MarkdownSource): MarkdownSource {\n\tconst start = source.text.length - source.text.trimStart().length\n\tconst end = source.text.trimEnd().length\n\treturn sliceSource(source, start, Math.max(start, end))\n}\n\n/**\n * Normalizes one paragraph line while retaining the full source run consumed by a\n * trailing-space hard break.\n *\n * @param source - The offset-bearing paragraph line\n * @param breaks - If `true`, preserves a trailing run of at least two spaces as the\n * scanner's two-space hard-break syntax; if `false`, trims the line normally\n * @returns The normalized line and its original-string segments\n *\n * @example\n * ```ts\n * normalizeParagraphLine(splitLines('text \\nnext')[0], true).text // 'text '\n * ```\n */\nexport function normalizeParagraphLine(source: MarkdownSource, breaks: boolean): MarkdownSource {\n\tif (!breaks || !source.text.endsWith(' ')) return trimSource(source)\n\tconst contentEnd = source.text.trimEnd().length\n\tconst content = trimSource(sliceSource(source, 0, contentEnd))\n\tconst span = projectSpan(source, contentEnd, source.text.length)\n\tconst suffix: MarkdownSource = {\n\t\ttext: ' ',\n\t\tsegments: span === undefined ? [] : [{ offset: 0, start: span.start, end: span.end }],\n\t}\n\treturn joinSources([content, suffix], '')\n}\n\n/**\n * Counts the leading space / tab characters on `line` (a tab counts as one) - the\n * indent that decides whether a list item's continuation belongs to the item.\n *\n * @param line - The line to measure\n * @returns The number of leading space / tab characters\n *\n * @example\n * ```ts\n * countIndent(' text') // 2\n * ```\n */\nexport function countIndent(line: string): number {\n\tlet count = 0\n\tfor (const character of line) {\n\t\tif (character === ' ' || character === '\\t') count += 1\n\t\telse break\n\t}\n\treturn count\n}\n\n// Line + character structural predicates\n//\n// Boolean predicates over a raw `string` (or a character of one) that the block and\n// inline phases test lines with. None narrows a type, so none is a `Guard<T>` and none\n// belongs in validators.ts; `isFenceClose` and `isTableStart` take two arguments, which\n// no guard signature admits.\n\n/**\n * Checks whether `character` is whitespace under the emphasis flanking rule - a space, a\n * tab, or a newline.\n *\n * @param character - The character to test\n * @returns True if the flanking rule counts it as whitespace; false otherwise\n *\n * @example\n * ```ts\n * isFlankingWhitespace(' ') // true\n * isFlankingWhitespace('a') // false\n * ```\n */\nexport function isFlankingWhitespace(character: string): boolean {\n\treturn character === ' ' || character === '\\t' || character === '\\n'\n}\n\n/**\n * Checks whether `character` is escapable by a leading backslash - the ASCII punctuation\n * markdown gives meaning to (so `\\*` becomes `*` but `\\.` stays `\\.`).\n *\n * @param character - The single character after a backslash\n * @returns True if a backslash before it is an escape; false otherwise\n *\n * @example\n * ```ts\n * isEscapable('*') // true\n * isEscapable('a') // false\n * ```\n */\nexport function isEscapable(character: string): boolean {\n\treturn /[\\\\`*_{}[\\]()#+\\-.!>~|]/.test(character)\n}\n\n/**\n * Checks whether `line` is blank - empty, or containing only whitespace - the markdown\n * definition of a blank line that block parsing uses to separate paragraphs, skip\n * gaps, and end list continuations.\n *\n * @param line - The candidate line\n * @returns True if the line is blank; false otherwise\n *\n * @example\n * ```ts\n * isBlankLine(' ') // true\n * ```\n */\nexport function isBlankLine(line: string): boolean {\n\treturn isEmptyString(line.trim())\n}\n\n/**\n * Checks whether `line` is a blockquote line (`>` optionally indented up to three spaces) -\n * its content is de-quoted by {@link stripQuote}.\n *\n * @param line - The candidate line\n * @returns True if the line begins a blockquote; false otherwise\n *\n * @example\n * ```ts\n * isQuote('> quoted') // true\n * ```\n */\nexport function isQuote(line: string): boolean {\n\treturn /^\\s{0,3}>/.test(line)\n}\n\n/**\n * Checks whether `line` closes a fence opened by `marker` - the same fence character, a run\n * at least as long, and nothing else but surrounding whitespace.\n *\n * @param line - The candidate closing line\n * @param marker - The opening fence's marker run (from {@link extractFence})\n * @returns True if `line` closes the fence; false otherwise\n *\n * @example\n * ```ts\n * isFenceClose('```', '```') // true\n * ```\n */\nexport function isFenceClose(line: string, marker: string): boolean {\n\tconst character = marker[0] === '~' ? '~' : '`'\n\tlet index = 0\n\twhile (index < line.length && isFenceWhitespace(line[index])) index++\n\tlet run = 0\n\twhile (index < line.length && line[index] === character) {\n\t\trun++\n\t\tindex++\n\t}\n\tif (run < marker.length) return false\n\twhile (index < line.length && isFenceWhitespace(line[index])) index++\n\treturn index === line.length\n}\n\n/**\n * Checks whether `character` is a regex-`\\s`-equivalent whitespace character - the\n * character class {@link isFenceClose}'s scan treats as surrounding padding.\n *\n * @param character - The single character to test, or `undefined` past the end of a line\n * @returns True if it is whitespace; false otherwise\n *\n * @example\n * ```ts\n * isFenceWhitespace(' ') // true\n * isFenceWhitespace(undefined) // false\n * ```\n */\nexport function isFenceWhitespace(character: string | undefined): boolean {\n\treturn (\n\t\tcharacter === ' ' ||\n\t\tcharacter === '\\t' ||\n\t\tcharacter === '\\n' ||\n\t\tcharacter === '\\r' ||\n\t\tcharacter === '\\f' ||\n\t\tcharacter === '\\v'\n\t)\n}\n\n/**\n * Checks whether `line` is a thematic break (horizontal rule) - three or more of the SAME\n * marker `-`, `*`, or `_` (optionally space-separated) and nothing else (`---`,\n * `***`, `___`, `- - -`).\n *\n * @param line - The candidate line\n * @returns True if the line is a thematic break; false otherwise\n *\n * @example\n * ```ts\n * isThematicBreak('---') // true\n * ```\n */\nexport function isThematicBreak(line: string): boolean {\n\tconst stripped = line.trim().replace(/\\s+/g, '')\n\tif (stripped.length < 3) return false\n\tconst marker = stripped[0]\n\tif (marker !== '-' && marker !== '*' && marker !== '_') return false\n\treturn [...stripped].every((character) => character === marker)\n}\n\n/**\n * Checks whether the pair (`header`, `delimiter`) opens a GFM table - `delimiter` is a row of\n * `|`-separated cells each matching `:?-+:?`, the GFM rule that a table requires a\n * header row IMMEDIATELY followed by a delimiter row.\n *\n * @param header - The candidate header line\n * @param delimiter - The line after it (the candidate delimiter)\n * @returns True if the two lines open a table; false otherwise\n *\n * @example\n * ```ts\n * isTableStart('| a |', '| - |') // true\n * ```\n */\nexport function isTableStart(header: string, delimiter: string | undefined): boolean {\n\tif (delimiter === undefined || !header.includes('|')) return false\n\tconst cells = splitTableRow(delimiter)\n\tif (cells.length === 0) return false\n\treturn cells.every((cell) => /^:?-+:?$/.test(cell.trim()))\n}\n\n// Block-level detection\n\n/**\n * Extracts an ATX heading line (`#` … `######` followed by text) into its level,\n * trimmed text, and the text's offset inside the line. A run of more than 6 `#`s, or\n * `#`s not followed by whitespace + text, is not a heading; an optional closing\n * `###` run is stripped.\n *\n * @param line - The candidate line\n * @returns The heading level (1–6), raw inline text, and text offset, or `undefined`\n *\n * @example\n * ```ts\n * extractHeading('## Title') // { level: 2, text: 'Title', offset: 3 }\n * ```\n */\nexport function extractHeading(line: string): HeadingMatch | undefined {\n\tconst trimmed = line.trimStart()\n\tconst match = /^(#{1,6})(?:\\s+(.*))?$/.exec(trimmed)\n\tif (!match || match[1] === undefined) return undefined\n\tconst level = match[1].length\n\tconst raw = match[2] ?? ''\n\tconst withoutClosing = raw.replace(/\\s+#+\\s*$/, '')\n\tconst text = withoutClosing.trim()\n\tconst found = raw.length === 0 ? trimmed.length : trimmed.indexOf(raw, level)\n\tconst content = found < 0 ? trimmed.length : found\n\tconst offset =\n\t\tline.length -\n\t\ttrimmed.length +\n\t\tcontent +\n\t\twithoutClosing.length -\n\t\twithoutClosing.trimStart().length\n\treturn { level, text, offset }\n}\n\n/**\n * Extracts a fenced-code opening line (```` ``` ```` or `~~~`, optionally with an info\n * string) into its `{ marker, lang }`, or `undefined` when `line` is not a fence\n * opener. `marker` is the exact fence run (the closer must match the same character +\n * at least the same length); `lang` is the first word of the info string.\n *\n * @param line - The candidate line\n * @returns The fence marker run and its language tag, or `undefined`\n *\n * @example\n * ```ts\n * extractFence('```ts') // { marker: '```', lang: 'ts' }\n * ```\n */\nexport function extractFence(line: string): FenceMatch | undefined {\n\tconst match = /^\\s*(`{3,}|~{3,})\\s*(.*)$/.exec(line)\n\tif (!match || match[1] === undefined) return undefined\n\tconst info = (match[2] ?? '').trim()\n\t// A backtick in a backtick fence's info string is invalid (ambiguous with a span).\n\tif (match[1].startsWith('`') && info.includes('`')) return undefined\n\tconst lang = isNonEmptyString(info) ? info.split(/\\s+/)[0] : undefined\n\treturn { marker: match[1], lang }\n}\n\n/**\n * Extracts a list-item line (`-` / `*` / `+` bullet, or `1.` / `1)` ordinal, followed by\n * a space) into its {@link ListItemMatch}, or `undefined` when `line` is not a list\n * item. `content` is the text after the marker; `marker` is the full marker-plus-space\n * width (for measuring a continuation's indent).\n *\n * @param line - The candidate line\n * @returns The list-item parts, or `undefined` when not a list item\n *\n * @example\n * ```ts\n * extractListItem('- item') // { ordered: false, start: 1, content: 'item', indent: 0, marker: 2 }\n * ```\n */\nexport function extractListItem(line: string): ListItemMatch | undefined {\n\tconst unordered = /^(\\s*)([-*+])\\s+(.*)$/.exec(line)\n\tif (unordered && unordered[1] !== undefined) {\n\t\tconst indent = unordered[1].length\n\t\tconst content = unordered[3] ?? ''\n\t\treturn { ordered: false, start: 1, content, indent, marker: line.length - content.length }\n\t}\n\tconst ordered = /^(\\s*)(\\d{1,9})[.)]\\s+(.*)$/.exec(line)\n\tif (ordered && ordered[1] !== undefined && ordered[2] !== undefined) {\n\t\tconst indent = ordered[1].length\n\t\tconst content = ordered[3] ?? ''\n\t\treturn {\n\t\t\tordered: true,\n\t\t\tstart: parseInteger(ordered[2]) ?? 1,\n\t\t\tcontent,\n\t\t\tindent,\n\t\t\tmarker: line.length - content.length,\n\t\t}\n\t}\n\treturn undefined\n}\n\n/**\n * Strips one level of blockquote marker (`>` plus one optional following space) from\n * an offset-bearing blockquote line, so the de-quoted source re-parses as nested\n * blocks without losing its original coordinates.\n *\n * @param source - A blockquote line (per {@link isQuote})\n * @returns The source with its leading `>` and optional space removed\n *\n * @example\n * ```ts\n * stripQuote({ text: '> text', segments: [{ offset: 0, start: 0, end: 6 }] })\n * // { text: 'text', segments: [{ offset: 0, start: 2, end: 6 }] }\n * ```\n */\nexport function stripQuote(source: MarkdownSource): MarkdownSource {\n\tconst marker = /^\\s{0,3}>\\s?/.exec(source.text)?.[0] ?? ''\n\treturn sliceSource(source, marker.length, source.text.length)\n}\n\n/**\n * Splits one GFM table row into its cell strings - outer pipes are optional, an escaped\n * pipe (`\\|`) inside a cell is NOT a separator (it becomes a literal `|`), and the\n * empty leading / trailing cell produced by an outer `|` is dropped. Derives the string\n * form from {@link splitTableSources}, which owns the escaped-pipe splitting rule.\n *\n * @param row - The raw table row line\n * @returns The row's cells, in column order\n *\n * @example\n * ```ts\n * splitTableRow('|a|b|') // ['a', 'b']\n * ```\n */\nexport function splitTableRow(row: string): readonly string[] {\n\treturn splitTableSources({ text: row, segments: [] }).map((cell) => cell.text)\n}\n\n/**\n * Splits an offset-bearing GFM table row into offset-bearing cells, retaining the\n * complete source spelling of an escaped pipe while exposing its literal value.\n *\n * @param row - The offset-bearing table row\n * @returns The row's cells with their original-string coordinates\n *\n * @example\n * ```ts\n * splitTableSources(splitLines('| a\\\\|b |')[0]).map((cell) => cell.text) // [' a|b ']\n * ```\n */\nexport function splitTableSources(row: MarkdownSource): readonly MarkdownSource[] {\n\tconst source = trimSource(row)\n\tconst cells: MarkdownSource[] = []\n\tlet pieces: MarkdownSource[] = []\n\tlet start = 0\n\tfor (let index = 0; index < source.text.length; index += 1) {\n\t\tconst character = source.text[index]\n\t\tif (character === '\\\\' && source.text[index + 1] === '|') {\n\t\t\tpieces.push(sliceSource(source, start, index))\n\t\t\tconst span = projectSpan(source, index, index + 2)\n\t\t\tpieces.push({\n\t\t\t\ttext: '|',\n\t\t\t\tsegments: span === undefined ? [] : [{ offset: 0, start: span.start, end: span.end }],\n\t\t\t})\n\t\t\tindex += 1\n\t\t\tstart = index + 1\n\t\t\tcontinue\n\t\t}\n\t\tif (character !== '|') continue\n\t\tpieces.push(sliceSource(source, start, index))\n\t\tcells.push(joinSources(pieces, ''))\n\t\tpieces = []\n\t\tstart = index + 1\n\t}\n\tpieces.push(sliceSource(source, start, source.text.length))\n\tcells.push(joinSources(pieces, ''))\n\tif (isNonEmptyArray<MarkdownSource>(cells) && isEmptyString((cells[0]?.text ?? '').trim()))\n\t\tcells.shift()\n\tif (\n\t\tisNonEmptyArray<MarkdownSource>(cells) &&\n\t\tisEmptyString((cells[cells.length - 1]?.text ?? '').trim())\n\t)\n\t\tcells.pop()\n\treturn cells\n}\n\n/**\n * Derives the per-column {@link TableAlign} list from a GFM delimiter row - `:---`\n * left, `---:` right, `:---:` center, and `---` as the explicit no-alignment\n * marker represented by `null`.\n *\n * @param delimiter - The table's delimiter row\n * @returns One alignment per column, in column order\n *\n * @example\n * ```ts\n * delimiterToAlignments('| :--- | ---: |') // ['left', 'right']\n * ```\n */\nexport function delimiterToAlignments(delimiter: string): ReadonlyArray<TableAlign | null> {\n\treturn splitTableRow(delimiter).map((cell) => {\n\t\tconst text = cell.trim()\n\t\tconst left = text.startsWith(':')\n\t\tconst right = text.endsWith(':')\n\t\tif (left && right) return 'center'\n\t\tif (right) return 'right'\n\t\tif (left) return 'left'\n\t\treturn null\n\t})\n}\n\n// Block phase\n\n/**\n * Checks whether the line at `index` starts a NEW block kind (heading / fence / thematic\n * break / blockquote / list / table) - the paragraph collector stops at such a line\n * so a block following a paragraph without a blank line still parses (a trusted-input\n * caller writing a `##` heading directly under a paragraph, with no intervening blank\n * line).\n *\n * @param lines - The document's lines\n * @param index - The line index to test\n * @returns True if the line begins a different block; false otherwise\n *\n * @example\n * ```ts\n * startsBlock(['text', '## Heading'], 1) // true\n * ```\n */\nexport function startsBlock(lines: readonly string[], index: number): boolean {\n\tconst line = lines[index] ?? ''\n\treturn (\n\t\textractHeading(line) !== undefined ||\n\t\textractFence(line) !== undefined ||\n\t\tisThematicBreak(line) ||\n\t\tisQuote(line) ||\n\t\textractListItem(line) !== undefined ||\n\t\tisTableStart(line, lines[index + 1])\n\t)\n}\n\n// Inline phase\n\n/**\n * Resolves backslash escapes in a raw string to their literal characters - used for a\n * link `href` (which is not otherwise inline-parsed) and any plain text run.\n *\n * @param text - The raw text possibly carrying `\\x` escapes\n * @returns The text with escapable `\\x` reduced to `x`\n *\n * @example\n * ```ts\n * unescapeText('\\\\*hi\\\\*') // '*hi*'\n * ```\n */\nexport function unescapeText(text: string): string {\n\tlet out = ''\n\tfor (let index = 0; index < text.length; index += 1) {\n\t\tconst character = text[index] ?? ''\n\t\tif (character === '\\\\' && isEscapable(text[index + 1] ?? '')) {\n\t\t\tout += text[index + 1] ?? ''\n\t\t\tindex += 1\n\t\t} else {\n\t\t\tout += character\n\t\t}\n\t}\n\treturn out\n}\n\n/**\n * Merges adjacent text nodes into one - the inline scanner emits a text node per\n * unrecognized character, so coalescing keeps the AST clean and assertion-friendly.\n *\n * @param nodes - The inline nodes (possibly with adjacent text runs)\n * @param spans - The optional operation-owned node span recorder\n * @returns The nodes with consecutive text nodes concatenated\n *\n * @example\n * ```ts\n * coalesceText([{ element: 'text', value: 'a' }, { element: 'text', value: 'b' }])\n * // [{ element: 'text', value: 'ab' }]\n * ```\n */\nexport function coalesceText(\n\tnodes: readonly InlineNode[],\n\tspans?: Map<MarkdownNode, MarkdownSpan>,\n): readonly InlineNode[] {\n\tconst out: InlineNode[] = []\n\tfor (const node of nodes) {\n\t\tconst last = out[out.length - 1]\n\t\tif (node.element === 'text' && last !== undefined && last.element === 'text') {\n\t\t\tconst merged: InlineNode = { element: 'text', value: last.value + node.value }\n\t\t\tconst left = spans?.get(last)\n\t\t\tconst right = spans?.get(node)\n\t\t\tif (spans !== undefined) {\n\t\t\t\tspans.delete(last)\n\t\t\t\tspans.delete(node)\n\t\t\t\tif (left !== undefined && right !== undefined)\n\t\t\t\t\tspans.set(merged, { start: left.start, end: right.end })\n\t\t\t}\n\t\t\tout[out.length - 1] = merged\n\t\t} else {\n\t\t\tout.push(node)\n\t\t}\n\t}\n\treturn out\n}\n\n/**\n * Scans an inline code span at `start` (a `` ` ``-run … a matching `` ` ``-run of the\n * SAME length, the CommonMark rule that lets a span contain backticks). Returns the\n * span's literal text + end index, or `undefined` when no matching closer exists (it\n * then degrades to literal backticks).\n *\n * @param source - The inline source text\n * @param start - The index of the opening backtick\n * @param to - The exclusive end of the scan window\n * @returns The span text + end index, or `undefined`\n *\n * @example\n * ```ts\n * scanCode('`code`', 0, 6) // { value: 'code', end: 6 }\n * ```\n */\nexport function scanCode(source: string, start: number, to: number): CodeSpanMatch | undefined {\n\tlet run = 0\n\twhile (start + run < to && source[start + run] === '`') run += 1\n\tconst open = '`'.repeat(run)\n\tlet search = start + run\n\tfor (;;) {\n\t\tconst closeAt = source.indexOf(open, search)\n\t\tif (closeAt === -1 || closeAt + run > to) return undefined\n\t\t// The closer must be EXACTLY `run` backticks (not bordered by another backtick).\n\t\tif (source[closeAt - 1] !== '`' && source[closeAt + run] !== '`') {\n\t\t\tlet value = source.slice(start + run, closeAt)\n\t\t\tif (\n\t\t\t\tvalue.length > 2 &&\n\t\t\t\tvalue.startsWith(' ') &&\n\t\t\t\tvalue.endsWith(' ') &&\n\t\t\t\tvalue.trim().length > 0\n\t\t\t) {\n\t\t\t\tvalue = value.slice(1, -1)\n\t\t\t}\n\t\t\treturn { value, end: closeAt + run }\n\t\t}\n\t\tsearch = closeAt + 1\n\t}\n}\n\n/**\n * Locates a link `[text](href)` at `start` - the text runs to a BALANCED `]`, then `(`\n * must immediately follow and the destination runs to the matching `)` (both respect\n * nested delimiters + escapes). Returns the label close and syntax end, or `undefined` when the shape\n * does not hold (it then degrades to a literal `[`).\n *\n * @param source - The inline source text\n * @param start - The index of the opening `[`\n * @param to - The exclusive end of the scan window\n * @returns The label close and syntax end indices, or `undefined`\n *\n * @example\n * ```ts\n * locateLink('[text](url)', 0, 11) // { close: 5, end: 11 }\n * ```\n */\nexport function locateLink(source: string, start: number, to: number): LinkBounds | undefined {\n\tlet bracketDepth = 0\n\tlet close = -1\n\tfor (let index = start; index < to; index += 1) {\n\t\tconst character = source[index] ?? ''\n\t\tif (character === '\\\\') {\n\t\t\tindex += 1\n\t\t\tcontinue\n\t\t}\n\t\tif (character === '[') bracketDepth += 1\n\t\telse if (character === ']') {\n\t\t\tbracketDepth -= 1\n\t\t\tif (bracketDepth === 0) {\n\t\t\t\tclose = index\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\tif (close === -1 || source[close + 1] !== '(') return undefined\n\tlet parenDepth = 0\n\tlet parenClose = -1\n\tfor (let index = close + 1; index < to; index += 1) {\n\t\tconst character = source[index] ?? ''\n\t\tif (character === '\\\\') {\n\t\t\tindex += 1\n\t\t\tcontinue\n\t\t}\n\t\tif (character === '(') parenDepth += 1\n\t\telse if (character === ')') {\n\t\t\tparenDepth -= 1\n\t\t\tif (parenDepth === 0) {\n\t\t\t\tparenClose = index\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\tif (parenClose === -1) return undefined\n\treturn { close, end: parenClose + 1 }\n}\n\n/**\n * Scans a link `[text](href)` at `start` - the text runs to a BALANCED `]`, then `(`\n * must immediately follow and the destination runs to the matching `)` (both respect\n * nested delimiters + escapes) through {@link locateLink}, and returns the parsed node\n * and end index. Returns `undefined` when the shape does not hold (it then degrades to\n * a literal `[`).\n *\n * @param source - The inline source text\n * @param start - The index of the opening `[`\n * @param to - The exclusive end of the scan window\n * @param depth - The current inline-recursion depth, forwarded to {@link scanInline}\n * incremented by one for the link text's children. At {@link MAX_DEPTH} that\n * recursion emits the text as a single literal text node instead of scanning it.\n * @returns The parsed link and end index, or `undefined` when the shape does not hold\n *\n * @example\n * ```ts\n * scanLink('[text](url)', 0, 11)\n * // { node: { element: 'link', href: 'url', children: [{ element: 'text', value: 'text' }] }, end: 11 }\n * ```\n */\nexport function scanLink(\n\tsource: string,\n\tstart: number,\n\tto: number,\n\tdepth = 0,\n): LinkScan | undefined {\n\tconst located = locateLink(source, start, to)\n\tif (located === undefined) return undefined\n\tconst href = unescapeText(source.slice(located.close + 2, located.end - 1).trim())\n\tconst children = scanInline(source, start + 1, located.close, depth + 1)\n\treturn { node: { element: 'link', href, children }, end: located.end }\n}\n\n/**\n * Locates an emphasis run at `start` (`*` / `_`, doubled for strong) - finds the nearest\n * matching closing run of the same marker + width while skipping complete nested\n * runs from the other marker family, and requires non-space immediately inside both\n * delimiters (the CommonMark flanking simplification that blocks `* x *`). Returns\n * the content and syntax bounds, or `undefined` when no valid closer exists (it then degrades to\n * a literal marker).\n *\n * @param source - The inline source text\n * @param start - The index of the opening marker\n * @param to - The exclusive end of the scan window\n * @returns The content and syntax bounds, or `undefined`\n *\n * @example\n * ```ts\n * locateEmphasis('*em*', 0, 4) // { strong: false, open: 1, close: 3, end: 4 }\n * ```\n */\nexport function locateEmphasis(\n\tsource: string,\n\tstart: number,\n\tto: number,\n): EmphasisBounds | undefined {\n\tconst marker = source[start] ?? ''\n\tlet run = 0\n\twhile (start + run < to && source[start + run] === marker && run < 2) run += 1\n\tconst strong = run === 2\n\tconst openEnd = start + run\n\tif (openEnd >= to || isFlankingWhitespace(source[openEnd] ?? '')) return undefined\n\tlet index = openEnd\n\twhile (index < to) {\n\t\tconst character = source[index] ?? ''\n\t\tif (character === '\\\\') {\n\t\t\tindex += 2\n\t\t\tcontinue\n\t\t}\n\t\tif (character === '`') {\n\t\t\tconst span = scanCode(source, index, to)\n\t\t\tindex = span ? span.end : index + 1\n\t\t\tcontinue\n\t\t}\n\t\tif ((character === '*' || character === '_') && character !== marker) {\n\t\t\tconst nested = locateEmphasis(source, index, to)\n\t\t\tif (nested !== undefined) {\n\t\t\t\tindex = nested.end\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tif (character === marker) {\n\t\t\tlet closeRun = 0\n\t\t\twhile (index + closeRun < to && source[index + closeRun] === marker) closeRun += 1\n\t\t\tif (closeRun >= run && !isFlankingWhitespace(source[index - 1] ?? '')) {\n\t\t\t\treturn {\n\t\t\t\t\tstrong,\n\t\t\t\t\topen: openEnd,\n\t\t\t\t\tclose: index,\n\t\t\t\t\tend: index + run,\n\t\t\t\t}\n\t\t\t}\n\t\t\tindex += closeRun\n\t\t\tcontinue\n\t\t}\n\t\tindex += 1\n\t}\n\treturn undefined\n}\n\n/**\n * Scans an emphasis run at `start` (`*` / `_`, doubled for strong) - finds the nearest\n * matching closing run of the same marker + width while skipping complete nested runs\n * from the other marker family, and requires non-space immediately inside both\n * delimiters (the CommonMark flanking simplification that blocks `* x *`) through\n * {@link locateEmphasis}, and returns the parsed node and end index. Returns\n * `undefined` when no valid closer exists (it then degrades to a literal marker).\n *\n * @param source - The inline source text\n * @param start - The index of the opening marker\n * @param to - The exclusive end of the scan window\n * @param depth - The current inline-recursion depth, forwarded to {@link scanInline}\n * incremented by one for the run's children. At {@link MAX_DEPTH} that recursion\n * emits the content as a single literal text node instead of scanning it.\n * @returns The parsed emphasis and end index, or `undefined` when no closer exists\n *\n * @example\n * ```ts\n * scanEmphasis('*em*', 0, 4)\n * // { node: { element: 'emphasis', strong: false, children: [{ element: 'text', value: 'em' }] }, end: 4 }\n * ```\n */\nexport function scanEmphasis(\n\tsource: string,\n\tstart: number,\n\tto: number,\n\tdepth = 0,\n): EmphasisScan | undefined {\n\tconst located = locateEmphasis(source, start, to)\n\tif (located === undefined) return undefined\n\treturn {\n\t\tnode: {\n\t\t\telement: 'emphasis',\n\t\t\tstrong: located.strong,\n\t\t\tchildren: scanInline(source, located.open, located.close, depth + 1),\n\t\t},\n\t\tend: located.end,\n\t}\n}\n\n/**\n * Scans the window `[from, to)` of `source` into inline nodes - the single recursive\n * engine the inline phase runs on (emphasis, link text, and image alternative\n * content recurse through it). Linear:\n * each character is consumed once; a failed construct emits its opening character as\n * text and advances by one, so there is no re-scan (no ReDoS).\n *\n * @param source - The inline source text\n * @param from - The inclusive start of the scan window\n * @param to - The exclusive end of the scan window\n * @param depth - The current inline-recursion depth (defaults to 0 at the entry point);\n * incremented by one on every recursive descent {@link scanInlineSource} makes into\n * itself for a link's text, an image's alternative content, or an emphasis run's\n * children. At {@link MAX_DEPTH} the window is never scanned for markup - it emits as\n * a single literal text node - so pathological nesting (`[[[[…`, `****…`) cannot\n * exhaust the call stack.\n * @returns The parsed inline nodes (NOT yet coalesced)\n *\n * @example\n * ```ts\n * scanInline('hi *there*', 0, 10) // [{ element: 'text', value: 'hi ' }, { element: 'emphasis', ... }]\n * ```\n */\nexport function scanInline(\n\tsource: string,\n\tfrom: number,\n\tto: number,\n\tdepth = 0,\n): readonly InlineNode[] {\n\treturn scanInlineSource(\n\t\t{\n\t\t\ttext: source,\n\t\t\tsegments: [{ offset: 0, start: 0, end: source.length }],\n\t\t},\n\t\tfrom,\n\t\tto,\n\t\tnew Map<MarkdownNode, MarkdownSpan>(),\n\t\tdepth,\n\t)\n}\n\n/**\n * Scans an offset-bearing inline window with the same engine as {@link scanInline}\n * and records each emitted node against the original markdown string.\n *\n * @param source - The offset-bearing inline source\n * @param from - The inclusive start of the scan window\n * @param to - The exclusive end of the scan window\n * @param spans - The operation-owned node span recorder\n * @param depth - The current inline-recursion depth, incremented by one on every\n * recursive descent this function makes into itself for a link's text, an image's\n * alternative content, or an emphasis run's children\n * @returns The parsed inline nodes before adjacent text coalescing\n *\n * @example\n * ```ts\n * scanInlineSource(\n * \t{ text: 'hi *there*', segments: [{ offset: 0, start: 0, end: 10 }] },\n * \t0,\n * \t10,\n * \tnew Map(),\n * )\n * // [{ element: 'text', value: 'hi ' }, { element: 'emphasis', ... }]\n * ```\n */\nexport function scanInlineSource(\n\tsource: MarkdownSource,\n\tfrom: number,\n\tto: number,\n\tspans: Map<MarkdownNode, MarkdownSpan>,\n\tdepth = 0,\n): readonly InlineNode[] {\n\tif (depth >= MAX_DEPTH)\n\t\tif (from < to) {\n\t\t\tconst node: InlineNode = { element: 'text', value: source.text.slice(from, to) }\n\t\t\tconst span = projectSpan(source, from, to)\n\t\t\tif (span !== undefined) spans.set(node, span)\n\t\t\treturn [node]\n\t\t} else return []\n\tconst nodes: InlineNode[] = []\n\tlet index = from\n\tlet pending = ''\n\tlet pendingStart = from\n\twhile (index < to) {\n\t\tconst character = source.text[index] ?? ''\n\t\tif (character === '\\\\' && index + 1 < to && isEscapable(source.text[index + 1] ?? '')) {\n\t\t\tif (pending.length === 0) pendingStart = index\n\t\t\tpending += source.text[index + 1] ?? ''\n\t\t\tindex += 2\n\t\t\tcontinue\n\t\t}\n\t\tif (character === ' ') {\n\t\t\tlet spaceEnd = index\n\t\t\twhile (spaceEnd < to && source.text[spaceEnd] === ' ') spaceEnd += 1\n\t\t\tif (spaceEnd - index >= 2 && source.text[spaceEnd] === '\\n') {\n\t\t\t\tif (pending.length > 0) {\n\t\t\t\t\tconst node: InlineNode = { element: 'text', value: pending }\n\t\t\t\t\tconst span = projectSpan(source, pendingStart, index)\n\t\t\t\t\tif (span !== undefined) spans.set(node, span)\n\t\t\t\t\tnodes.push(node)\n\t\t\t\t\tpending = ''\n\t\t\t\t}\n\t\t\t\tconst node: InlineNode = { element: 'break' }\n\t\t\t\tconst span = projectSpan(source, index, spaceEnd + 1)\n\t\t\t\tif (span !== undefined) spans.set(node, span)\n\t\t\t\tnodes.push(node)\n\t\t\t\tindex = spaceEnd + 1\n\t\t\t\tpendingStart = index\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tlet scanned: InlineNode | undefined\n\t\tlet end = index\n\t\tif (character === '`') {\n\t\t\tconst span = scanCode(source.text, index, to)\n\t\t\tif (span) {\n\t\t\t\tscanned = { element: 'codeSpan', value: span.value }\n\t\t\t\tend = span.end\n\t\t\t}\n\t\t}\n\t\tif (character === '!' && source.text[index + 1] === '[') {\n\t\t\tconst link = locateLink(source.text, index + 1, to)\n\t\t\tif (link !== undefined) {\n\t\t\t\tscanned = {\n\t\t\t\t\telement: 'image',\n\t\t\t\t\tsrc: unescapeText(source.text.slice(link.close + 2, link.end - 1).trim()),\n\t\t\t\t\tchildren: coalesceText(\n\t\t\t\t\t\tscanInlineSource(source, index + 2, link.close, spans, depth + 1),\n\t\t\t\t\t\tspans,\n\t\t\t\t\t),\n\t\t\t\t}\n\t\t\t\tend = link.end\n\t\t\t}\n\t\t}\n\t\tif (character === '[') {\n\t\t\tconst link = locateLink(source.text, index, to)\n\t\t\tif (link !== undefined) {\n\t\t\t\tscanned = {\n\t\t\t\t\telement: 'link',\n\t\t\t\t\thref: unescapeText(source.text.slice(link.close + 2, link.end - 1).trim()),\n\t\t\t\t\tchildren: coalesceText(\n\t\t\t\t\t\tscanInlineSource(source, index + 1, link.close, spans, depth + 1),\n\t\t\t\t\t\tspans,\n\t\t\t\t\t),\n\t\t\t\t}\n\t\t\t\tend = link.end\n\t\t\t}\n\t\t}\n\t\tif (character === '*' || character === '_') {\n\t\t\tconst emphasis = locateEmphasis(source.text, index, to)\n\t\t\tif (emphasis !== undefined) {\n\t\t\t\tscanned = {\n\t\t\t\t\telement: 'emphasis',\n\t\t\t\t\tstrong: emphasis.strong,\n\t\t\t\t\tchildren: coalesceText(\n\t\t\t\t\t\tscanInlineSource(source, emphasis.open, emphasis.close, spans, depth + 1),\n\t\t\t\t\t\tspans,\n\t\t\t\t\t),\n\t\t\t\t}\n\t\t\t\tend = emphasis.end\n\t\t\t}\n\t\t}\n\t\tif (scanned !== undefined) {\n\t\t\tif (pending.length > 0) {\n\t\t\t\tconst node: InlineNode = { element: 'text', value: pending }\n\t\t\t\tconst span = projectSpan(source, pendingStart, index)\n\t\t\t\tif (span !== undefined) spans.set(node, span)\n\t\t\t\tnodes.push(node)\n\t\t\t\tpending = ''\n\t\t\t}\n\t\t\tconst span = projectSpan(source, index, end)\n\t\t\tif (span !== undefined) spans.set(scanned, span)\n\t\t\tnodes.push(scanned)\n\t\t\tindex = end\n\t\t\tpendingStart = index\n\t\t\tcontinue\n\t\t}\n\t\tif (pending.length === 0) pendingStart = index\n\t\tpending += character\n\t\tindex += 1\n\t}\n\tif (pending.length > 0) {\n\t\tconst node: InlineNode = { element: 'text', value: pending }\n\t\tconst span = projectSpan(source, pendingStart, index)\n\t\tif (span !== undefined) spans.set(node, span)\n\t\tnodes.push(node)\n\t}\n\treturn nodes\n}\n\n/**\n * Collects a GFM table starting at a header row, parsing the header, the\n * alignment row, and every contiguous body row that follows.\n *\n * @param lines - The markdown lines to scan.\n * @param start - The index of the header row.\n * @param spans - The optional operation-owned node span recorder.\n * @returns The parsed table node and the index of the first line after it.\n *\n * @example\n * ```ts\n * collectTable(splitLines('| a |\\n| - |'), 0) // { node: { element: 'table', ... }, next: 2 }\n * ```\n */\nexport function collectTable(\n\tlines: readonly MarkdownSource[],\n\tstart: number,\n\tspans = new Map<MarkdownNode, MarkdownSpan>(),\n): TableCollection {\n\tconst headerCells = splitTableSources(lines[start] ?? { text: '', segments: [] })\n\tconst columns = headerCells.length\n\tconst header = headerCells.map((cell) => {\n\t\tconst source = trimSource(cell)\n\t\treturn coalesceText(scanInlineSource(source, 0, source.text.length, spans), spans)\n\t})\n\tconst align = delimiterToAlignments(lines[start + 1]?.text ?? '')\n\tconst padded: Array<TableAlign | null> = []\n\tfor (let column = 0; column < columns; column += 1) padded.push(align[column] ?? null)\n\tconst rows: Array<Array<readonly InlineNode[]>> = []\n\tlet index = start + 2\n\twhile (\n\t\tindex < lines.length &&\n\t\t!isBlankLine(lines[index]?.text ?? '') &&\n\t\t(lines[index]?.text ?? '').includes('|')\n\t) {\n\t\tconst cells = splitTableSources(lines[index] ?? { text: '', segments: [] })\n\t\tconst row: Array<readonly InlineNode[]> = []\n\t\tfor (let column = 0; column < columns; column += 1) {\n\t\t\tconst source = trimSource(cells[column] ?? { text: '', segments: [] })\n\t\t\trow.push(coalesceText(scanInlineSource(source, 0, source.text.length, spans), spans))\n\t\t}\n\t\trows.push(row)\n\t\tindex += 1\n\t}\n\tconst node: TableNode = { element: 'table', header, rows, align: padded }\n\tconst source = joinSources(lines.slice(start, index), '\\n')\n\tconst span = projectSpan(source, 0, source.text.length)\n\tif (span !== undefined) spans.set(node, span)\n\treturn { node, next: index }\n}\n\n/**\n * Collects a list starting at the first item, gathering sibling items at the\n * same indent/ordering and recursing into each item's own block content.\n *\n * @param lines - The markdown lines to scan.\n * @param start - The index of the first list item.\n * @param depth - The current recursion depth (each item recurses at `depth + 1`).\n * @param spans - The optional operation-owned node span recorder.\n * @param end - The original-source end of this line run, including a removed terminator.\n * @returns The parsed list node and the index of the first line after it.\n *\n * @example\n * ```ts\n * collectList(splitLines('- item'), 0, 0) // { node: { element: 'list', ... }, next: 1 }\n * ```\n */\nexport function collectList(\n\tlines: readonly MarkdownSource[],\n\tstart: number,\n\tdepth: number,\n\tspans = new Map<MarkdownNode, MarkdownSpan>(),\n\tend?: number,\n): ListCollection {\n\tconst text = lines.map((line) => line.text)\n\tconst first = extractListItem(text[start] ?? '')\n\tconst ordered = first?.ordered ?? false\n\tconst startOrdinal = first?.start ?? 1\n\tconst topIndent = first?.indent ?? 0\n\tconst items: ListItemNode[] = []\n\t// A single nested-item chain would otherwise rescan and slice the whole suffix\n\t// once per level before reaching the cap. Recognize that shape in one pass and\n\t// build the same bounded AST bottom-up.\n\tconst chain: ListItemMatch[] = []\n\tlet nested = true\n\tfor (let cursor = start; cursor < lines.length; cursor += 1) {\n\t\tconst parsed = extractListItem(text[cursor] ?? '')\n\t\tconst previous = chain[chain.length - 1]\n\t\tif (\n\t\t\tparsed === undefined ||\n\t\t\t(previous !== undefined && (previous.content.length > 0 || parsed.indent !== previous.marker))\n\t\t) {\n\t\t\tnested = false\n\t\t\tbreak\n\t\t}\n\t\tchain.push(parsed)\n\t}\n\tconst remaining = MAX_DEPTH - depth\n\tif (nested && remaining > 0 && chain.length > remaining) {\n\t\tconst terminal = chain[remaining - 1]\n\t\tconst terminalLine = lines[start + remaining - 1]\n\t\tif (terminal !== undefined && terminalLine !== undefined) {\n\t\t\tconst sources: MarkdownSource[] = [\n\t\t\t\tsliceSource(terminalLine, terminal.marker, terminalLine.text.length),\n\t\t\t]\n\t\t\tfor (let cursor = start + remaining; cursor < lines.length; cursor += 1) {\n\t\t\t\tconst line = lines[cursor]\n\t\t\t\tif (line !== undefined) sources.push(sliceSource(line, terminal.marker, line.text.length))\n\t\t\t}\n\t\t\tconst source = joinSources(sources, '\\n')\n\t\t\tconst textNode: InlineNode = { element: 'text', value: source.text }\n\t\t\tconst paragraph: BlockNode = { element: 'paragraph', children: [textNode] }\n\t\t\tconst residualSpan = projectSpan(source, 0, source.text.length)\n\t\t\tif (residualSpan !== undefined) {\n\t\t\t\tspans.set(textNode, residualSpan)\n\t\t\t\tspans.set(paragraph, residualSpan)\n\t\t\t}\n\t\t\tlet children: readonly BlockNode[] = [paragraph]\n\t\t\tlet node: ListNode | undefined\n\t\t\tfor (let cursor = remaining - 1; cursor >= 0; cursor -= 1) {\n\t\t\t\tconst parsed = chain[cursor]\n\t\t\t\tif (parsed === undefined) continue\n\t\t\t\tconst item: ListItemNode = { element: 'listItem', children }\n\t\t\t\tnode = {\n\t\t\t\t\telement: 'list',\n\t\t\t\t\tordered: parsed.ordered,\n\t\t\t\t\tstart: parsed.start,\n\t\t\t\t\titems: [item],\n\t\t\t\t}\n\t\t\t\tconst region = joinSources(\n\t\t\t\t\tlines\n\t\t\t\t\t\t.slice(start + cursor)\n\t\t\t\t\t\t.map((line) => sliceSource(line, parsed.indent, line.text.length)),\n\t\t\t\t\t'\\n',\n\t\t\t\t)\n\t\t\t\tconst span = projectSpan(region, 0, region.text.length)\n\t\t\t\tif (span !== undefined) {\n\t\t\t\t\tspans.set(item, span)\n\t\t\t\t\tspans.set(node, span)\n\t\t\t\t}\n\t\t\t\tchildren = [node]\n\t\t\t}\n\t\t\tif (node !== undefined) return { node, next: lines.length }\n\t\t}\n\t}\n\tlet index = start\n\twhile (index < lines.length) {\n\t\tconst parsed = extractListItem(text[index] ?? '')\n\t\t// A sibling item shares the list's (top) indent + ordering; anything else stops\n\t\t// the top loop (a deeper item is a nested list, gathered as continuation below).\n\t\tif (!parsed || parsed.indent > topIndent || parsed.ordered !== ordered) break\n\t\tconst itemStart = index\n\t\tconst itemLine = lines[index]\n\t\tif (itemLine === undefined) break\n\t\tconst itemLines: MarkdownSource[] = [sliceSource(itemLine, parsed.marker, itemLine.text.length)]\n\t\tconst continuation = parsed.marker\n\t\tindex += 1\n\t\twhile (index < lines.length) {\n\t\t\tconst nextSource = lines[index]\n\t\t\tif (nextSource === undefined) break\n\t\t\tconst next = nextSource.text\n\t\t\tif (isBlankLine(next)) {\n\t\t\t\tconst after = lines[index + 1]?.text ?? ''\n\t\t\t\tif (index + 1 < lines.length && !isBlankLine(after) && countIndent(after) >= continuation) {\n\t\t\t\t\titemLines.push(sliceSource(nextSource, 0, 0))\n\t\t\t\t\tindex += 1\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif (countIndent(next) >= continuation) {\n\t\t\t\titemLines.push(sliceSource(nextSource, continuation, next.length))\n\t\t\t\tindex += 1\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (extractListItem(next) || startsBlock(text, index)) break\n\t\t\titemLines.push(trimSource(nextSource)) // a lazy paragraph-continuation line\n\t\t\tindex += 1\n\t\t}\n\t\tconst tail = itemLines[itemLines.length - 1]\n\t\tconst segment = tail?.segments[tail.segments.length - 1]\n\t\tconst itemEnd = index === lines.length && end !== undefined ? end : segment?.end\n\t\tconst item: ListItemNode = {\n\t\t\telement: 'listItem',\n\t\t\tchildren: parseBlocks(itemLines, depth + 1, spans, itemEnd),\n\t\t}\n\t\tconst source = joinSources(lines.slice(itemStart, index), '\\n')\n\t\tconst span = projectSpan(source, 0, source.text.length)\n\t\tif (span !== undefined) spans.set(item, span)\n\t\titems.push(item)\n\t}\n\tconst node: ListNode = { element: 'list', ordered, start: startOrdinal, items }\n\tconst source = joinSources(lines.slice(start, index), '\\n')\n\tconst span = projectSpan(source, 0, source.text.length)\n\tif (span !== undefined) spans.set(node, span)\n\treturn { node, next: index }\n}\n\n// Rendering (Markdown AST → HTML AST → sanitized HTML string)\n\n/**\n * Projects a {@link MarkdownNode} into an unsanitized {@link HTMLDocument}.\n *\n * @remarks\n * The projection is pure and iterative. Text and attribute values remain literal for\n * `@orkestrel/html` to encode, and URL values remain unsanitized so callers can choose\n * their own HTML policy. Projected HTML element depth, including generated `pre > code`\n * and table scaffolding, never exceeds {@link MAX_DEPTH}. At the cap a node carrying a\n * string `value` degrades to a text node and a structural node contributes nothing.\n *\n * @param node - The markdown document or bare node to project\n * @returns An unsanitized HTML document wrapping the projected node or nodes\n *\n * @example\n * ```ts\n * markdownToHTML({ element: 'text', value: 'a & b' })\n * // { category: 'document', children: [{ category: 'text', value: 'a & b' }] }\n * ```\n */\nexport function markdownToHTML(node: MarkdownNode): HTMLDocument {\n\tconst stack: Array<{\n\t\treadonly node: MarkdownNode\n\t\treadonly depth: number\n\t\treadonly expanded: boolean\n\t\treadonly count: number\n\t}> = [{ node, depth: 0, expanded: false, count: 0 }]\n\tconst values: Array<HTMLNode | undefined> = []\n\twhile (stack.length > 0) {\n\t\tconst frame = stack.pop()\n\t\tif (frame === undefined) continue\n\t\tconst current = frame.node\n\t\tif (!frame.expanded) {\n\t\t\tif (frame.depth >= MAX_DEPTH) {\n\t\t\t\tvalues.push(\n\t\t\t\t\t'value' in current && typeof current.value === 'string'\n\t\t\t\t\t\t? { category: 'text', value: current.value }\n\t\t\t\t\t\t: undefined,\n\t\t\t\t)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst children: MarkdownNode[] = []\n\t\t\tlet depth = frame.depth\n\t\t\tswitch (current.element) {\n\t\t\t\tcase 'document':\n\t\t\t\t\tfor (const child of current.children) if (child !== undefined) children.push(child)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'heading':\n\t\t\t\tcase 'paragraph':\n\t\t\t\tcase 'blockquote':\n\t\t\t\t\tfor (const child of current.children) if (child !== undefined) children.push(child)\n\t\t\t\t\tdepth += 1\n\t\t\t\t\tbreak\n\t\t\t\tcase 'listItem': {\n\t\t\t\t\tconst only = current.children[0]\n\t\t\t\t\tif (current.children.length === 1 && only !== undefined && only.element === 'paragraph') {\n\t\t\t\t\t\tfor (const child of only.children) if (child !== undefined) children.push(child)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor (const child of current.children) if (child !== undefined) children.push(child)\n\t\t\t\t\t}\n\t\t\t\t\tdepth += 1\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'emphasis':\n\t\t\t\tcase 'link':\n\t\t\t\t\tfor (const child of current.children) if (child !== undefined) children.push(child)\n\t\t\t\t\tdepth += 1\n\t\t\t\t\tbreak\n\t\t\t\tcase 'list':\n\t\t\t\t\tfor (const child of current.items) if (child !== undefined) children.push(child)\n\t\t\t\t\tdepth += 1\n\t\t\t\t\tbreak\n\t\t\t\tcase 'table':\n\t\t\t\t\tif (frame.depth + 4 > MAX_DEPTH) {\n\t\t\t\t\t\tvalues.push(undefined)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tfor (const cell of current.header)\n\t\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\t\tfor (const row of current.rows)\n\t\t\t\t\t\tif (row !== undefined)\n\t\t\t\t\t\t\tfor (const cell of row)\n\t\t\t\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\t\tdepth += 4\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t\tif (current.element === 'codeBlock' && frame.depth + 2 > MAX_DEPTH) {\n\t\t\t\tvalues.push(undefined)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tstack.push({ ...frame, expanded: true, count: children.length })\n\t\t\tfor (let index = children.length - 1; index >= 0; index -= 1) {\n\t\t\t\tconst child = children[index]\n\t\t\t\tif (child !== undefined) stack.push({ node: child, depth, expanded: false, count: 0 })\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tconst children =\n\t\t\tframe.count === 0 ? [] : values.splice(values.length - frame.count, frame.count)\n\t\tconst projected: HTMLNode[] = []\n\t\tfor (const child of children) if (child !== undefined) projected.push(child)\n\t\tlet value: HTMLNode | undefined\n\t\tswitch (current.element) {\n\t\t\tcase 'document':\n\t\t\t\tvalue = { category: 'document', children: projected }\n\t\t\t\tbreak\n\t\t\tcase 'heading':\n\t\t\t\tvalue = {\n\t\t\t\t\tcategory: 'element',\n\t\t\t\t\tname: `h${current.level}`,\n\t\t\t\t\tattributes: [],\n\t\t\t\t\tchildren: projected,\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'paragraph':\n\t\t\t\tvalue = { category: 'element', name: 'p', attributes: [], children: projected }\n\t\t\t\tbreak\n\t\t\tcase 'thematicBreak':\n\t\t\t\tvalue = { category: 'element', name: 'hr', attributes: [], children: [] }\n\t\t\t\tbreak\n\t\t\tcase 'blockquote':\n\t\t\t\tvalue = {\n\t\t\t\t\tcategory: 'element',\n\t\t\t\t\tname: 'blockquote',\n\t\t\t\t\tattributes: [],\n\t\t\t\t\tchildren: projected,\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'codeBlock':\n\t\t\t\tvalue = {\n\t\t\t\t\tcategory: 'element',\n\t\t\t\t\tname: 'pre',\n\t\t\t\t\tattributes: [],\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcategory: 'element',\n\t\t\t\t\t\t\tname: 'code',\n\t\t\t\t\t\t\tattributes:\n\t\t\t\t\t\t\t\tcurrent.lang === undefined\n\t\t\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t\t\t: [{ name: 'class', value: `language-${current.lang}` }],\n\t\t\t\t\t\t\tchildren: [{ category: 'text', value: current.code }],\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'list':\n\t\t\t\tvalue = {\n\t\t\t\t\tcategory: 'element',\n\t\t\t\t\tname: current.ordered ? 'ol' : 'ul',\n\t\t\t\t\tattributes:\n\t\t\t\t\t\tcurrent.ordered && current.start !== 1\n\t\t\t\t\t\t\t? [{ name: 'start', value: String(current.start) }]\n\t\t\t\t\t\t\t: [],\n\t\t\t\t\tchildren: projected,\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'listItem':\n\t\t\t\tvalue = { category: 'element', name: 'li', attributes: [], children: projected }\n\t\t\t\tbreak\n\t\t\tcase 'table': {\n\t\t\t\tlet offset = 0\n\t\t\t\tconst header: HTMLNode[] = []\n\t\t\t\tfor (const [column, cell] of current.header.entries()) {\n\t\t\t\t\tif (cell === undefined) continue\n\t\t\t\t\tconst align = current.align[column]\n\t\t\t\t\tconst attributes =\n\t\t\t\t\t\talign === 'left' || align === 'right' || align === 'center'\n\t\t\t\t\t\t\t? [{ name: 'align', value: align }]\n\t\t\t\t\t\t\t: []\n\t\t\t\t\tlet count = 0\n\t\t\t\t\tfor (const child of cell) if (child !== undefined) count += 1\n\t\t\t\t\tconst cellChildren: HTMLNode[] = []\n\t\t\t\t\tfor (const child of children.slice(offset, offset + count))\n\t\t\t\t\t\tif (child !== undefined) cellChildren.push(child)\n\t\t\t\t\theader.push({\n\t\t\t\t\t\tcategory: 'element',\n\t\t\t\t\t\tname: 'th',\n\t\t\t\t\t\tattributes,\n\t\t\t\t\t\tchildren: cellChildren,\n\t\t\t\t\t})\n\t\t\t\t\toffset += count\n\t\t\t\t}\n\t\t\t\tconst rows: HTMLNode[] = []\n\t\t\t\tfor (const row of current.rows) {\n\t\t\t\t\tconst cells: HTMLNode[] = []\n\t\t\t\t\tfor (const [column, cell] of row.entries()) {\n\t\t\t\t\t\tif (cell === undefined) continue\n\t\t\t\t\t\tconst align = current.align[column]\n\t\t\t\t\t\tconst attributes =\n\t\t\t\t\t\t\talign === 'left' || align === 'right' || align === 'center'\n\t\t\t\t\t\t\t\t? [{ name: 'align', value: align }]\n\t\t\t\t\t\t\t\t: []\n\t\t\t\t\t\tlet count = 0\n\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) count += 1\n\t\t\t\t\t\tconst cellChildren: HTMLNode[] = []\n\t\t\t\t\t\tfor (const child of children.slice(offset, offset + count))\n\t\t\t\t\t\t\tif (child !== undefined) cellChildren.push(child)\n\t\t\t\t\t\tcells.push({\n\t\t\t\t\t\t\tcategory: 'element',\n\t\t\t\t\t\t\tname: 'td',\n\t\t\t\t\t\t\tattributes,\n\t\t\t\t\t\t\tchildren: cellChildren,\n\t\t\t\t\t\t})\n\t\t\t\t\t\toffset += count\n\t\t\t\t\t}\n\t\t\t\t\trows.push({\n\t\t\t\t\t\tcategory: 'element',\n\t\t\t\t\t\tname: 'tr',\n\t\t\t\t\t\tattributes: [],\n\t\t\t\t\t\tchildren: cells,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tconst tableChildren: HTMLNode[] = [\n\t\t\t\t\t{\n\t\t\t\t\t\tcategory: 'element',\n\t\t\t\t\t\tname: 'thead',\n\t\t\t\t\t\tattributes: [],\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcategory: 'element',\n\t\t\t\t\t\t\t\tname: 'tr',\n\t\t\t\t\t\t\t\tattributes: [],\n\t\t\t\t\t\t\t\tchildren: header,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t\tif (isNonEmptyArray(current.rows)) {\n\t\t\t\t\ttableChildren.push({\n\t\t\t\t\t\tcategory: 'element',\n\t\t\t\t\t\tname: 'tbody',\n\t\t\t\t\t\tattributes: [],\n\t\t\t\t\t\tchildren: rows,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tvalue = {\n\t\t\t\t\tcategory: 'element',\n\t\t\t\t\tname: 'table',\n\t\t\t\t\tattributes: [],\n\t\t\t\t\tchildren: tableChildren,\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'text':\n\t\t\t\tvalue = { category: 'text', value: current.value }\n\t\t\t\tbreak\n\t\t\tcase 'emphasis':\n\t\t\t\tvalue = {\n\t\t\t\t\tcategory: 'element',\n\t\t\t\t\tname: current.strong ? 'strong' : 'em',\n\t\t\t\t\tattributes: [],\n\t\t\t\t\tchildren: projected,\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'codeSpan':\n\t\t\t\tvalue = {\n\t\t\t\t\tcategory: 'element',\n\t\t\t\t\tname: 'code',\n\t\t\t\t\tattributes: [],\n\t\t\t\t\tchildren: [{ category: 'text', value: current.value }],\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'link':\n\t\t\t\tvalue = {\n\t\t\t\t\tcategory: 'element',\n\t\t\t\t\tname: 'a',\n\t\t\t\t\tattributes: [{ name: 'href', value: current.href }],\n\t\t\t\t\tchildren: projected,\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'image':\n\t\t\t\tvalue = {\n\t\t\t\t\tcategory: 'element',\n\t\t\t\t\tname: 'img',\n\t\t\t\t\tattributes: [\n\t\t\t\t\t\t{ name: 'src', value: current.src },\n\t\t\t\t\t\t{ name: 'alt', value: flattenText(current) },\n\t\t\t\t\t],\n\t\t\t\t\tchildren: [],\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'break':\n\t\t\t\tvalue = { category: 'element', name: 'br', attributes: [], children: [] }\n\t\t\t\tbreak\n\t\t\tdefault:\n\t\t\t\tvalue = undefined\n\t\t\t\tbreak\n\t\t}\n\t\tvalues.push(value)\n\t}\n\tconst projected = values[0]\n\tif (projected?.category === 'document') return projected\n\treturn {\n\t\tcategory: 'document',\n\t\tchildren: projected === undefined ? [] : [projected],\n\t}\n}\n\n/**\n * Renders a {@link MarkdownNode} to its CANONICAL markdown source - the inverse\n * projection of `renderHTML`, and the serializer a `parse(renderMarkdown(doc))`\n * round-trip is built on. Canonical forms: `*` / `**` emphasis at even emphasis\n * nesting depths and `_` / `__` at odd depths, `- ` bullets, `N. ` sequential\n * ordinals (from the list's `start`), `---` thematic breaks, fenced code blocks\n * (backtick run widened past any 3+ backtick run inside the body), ATX headings,\n * `> `-prefixed blockquote lines, GFM tables (1-space-padded cells, `\\|`-escaped\n * pipes, an alignment delimiter row), `[text](href)` links, `![alt](src)` images,\n * and two-space hard breaks. A `text` node's literal content is backslash-escaped\n * wherever it would otherwise re-parse as markup, so parsing the rendered source\n * returns the node it was rendered from.\n *\n * @remarks\n * Total: never throws. At {@link MAX_DEPTH} a value-bearing node degrades to its\n * escaped `value`; any other node degrades to `''`. Blocks are joined by exactly one\n * blank line; a document with zero blocks renders `''`.\n *\n * @param node - The AST node to render (a full document, or any sub-node)\n * @returns The canonical markdown source\n *\n * @example\n * ```ts\n * renderMarkdown({ element: 'document', children: [\n * { element: 'heading', level: 2, children: [{ element: 'text', value: 'Hi' }] },\n * ] })\n * // '## Hi'\n * ```\n */\nexport function renderMarkdown(node: MarkdownNode): string {\n\tconst stack: Array<{\n\t\treadonly node: MarkdownNode\n\t\treadonly depth: number\n\t\treadonly expanded: boolean\n\t\treadonly count: number\n\t\treadonly escaped: string\n\t\treadonly escapeBang: boolean\n\t\treadonly nesting: number\n\t}> = [\n\t\t{\n\t\t\tnode,\n\t\t\tdepth: 0,\n\t\t\texpanded: false,\n\t\t\tcount: 0,\n\t\t\tescaped: '',\n\t\t\tescapeBang: false,\n\t\t\tnesting: 0,\n\t\t},\n\t]\n\tconst values: string[] = []\n\twhile (stack.length > 0) {\n\t\tconst frame = stack.pop()\n\t\tif (frame === undefined) continue\n\t\tconst current = frame.node\n\t\tif (!frame.expanded) {\n\t\t\tlet escaped = ''\n\t\t\tif (\n\t\t\t\t(frame.depth >= MAX_DEPTH || current.element === 'text') &&\n\t\t\t\t'value' in current &&\n\t\t\t\ttypeof current.value === 'string'\n\t\t\t) {\n\t\t\t\tfor (let index = 0; index < current.value.length; index += 1) {\n\t\t\t\t\tconst character = current.value[index] ?? ''\n\t\t\t\t\tconst atLineStart = index === 0 || current.value[index - 1] === '\\n'\n\t\t\t\t\tif (\n\t\t\t\t\t\tcurrent.element === 'text' &&\n\t\t\t\t\t\tcharacter === '!' &&\n\t\t\t\t\t\tindex === current.value.length - 1 &&\n\t\t\t\t\t\tframe.escapeBang\n\t\t\t\t\t) {\n\t\t\t\t\t\tescaped += '\\\\!'\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif (\n\t\t\t\t\t\tcharacter === '\\\\' ||\n\t\t\t\t\t\tcharacter === '*' ||\n\t\t\t\t\t\tcharacter === '_' ||\n\t\t\t\t\t\tcharacter === '`' ||\n\t\t\t\t\t\tcharacter === '[' ||\n\t\t\t\t\t\tcharacter === ']'\n\t\t\t\t\t) {\n\t\t\t\t\t\tescaped += `\\\\${character}`\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif (atLineStart) {\n\t\t\t\t\t\tif (character === '#' || character === '>') {\n\t\t\t\t\t\t\tescaped += `\\\\${character}`\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t(character === '-' || character === '~') &&\n\t\t\t\t\t\t\tcurrent.value[index + 1] === character &&\n\t\t\t\t\t\t\tcurrent.value[index + 2] === character\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tescaped += `\\\\${character}`\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t(character === '-' || character === '+') &&\n\t\t\t\t\t\t\t(current.value[index + 1] ?? ' ') === ' '\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tescaped += `\\\\${character}`\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (/[0-9]/.test(character)) {\n\t\t\t\t\t\t\tlet end = index\n\t\t\t\t\t\t\twhile (end < current.value.length && /[0-9]/.test(current.value[end] ?? '')) end += 1\n\t\t\t\t\t\t\tconst marker = current.value[end]\n\t\t\t\t\t\t\tif ((marker === '.' || marker === ')') && current.value[end + 1] === ' ') {\n\t\t\t\t\t\t\t\tescaped += `${current.value.slice(index, end)}\\\\${marker}`\n\t\t\t\t\t\t\t\tindex = end\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tescaped += character\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (frame.depth >= MAX_DEPTH) {\n\t\t\t\tvalues.push(escaped)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst groups: Array<readonly MarkdownNode[]> = []\n\t\t\tconst adjacent: boolean[] = []\n\t\t\tlet depth = frame.depth + 1\n\t\t\tswitch (current.element) {\n\t\t\t\tcase 'document':\n\t\t\t\tcase 'blockquote':\n\t\t\t\tcase 'listItem':\n\t\t\t\t\tgroups.push(current.children)\n\t\t\t\t\tadjacent.push(false)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'heading':\n\t\t\t\tcase 'paragraph':\n\t\t\t\tcase 'emphasis':\n\t\t\t\tcase 'link':\n\t\t\t\tcase 'image':\n\t\t\t\t\tgroups.push(current.children)\n\t\t\t\t\tadjacent.push(true)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'list':\n\t\t\t\t\tgroups.push(current.items)\n\t\t\t\t\tadjacent.push(false)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'table':\n\t\t\t\t\tfor (const cell of current.header)\n\t\t\t\t\t\tif (cell !== undefined) {\n\t\t\t\t\t\t\tgroups.push(cell)\n\t\t\t\t\t\t\tadjacent.push(true)\n\t\t\t\t\t\t}\n\t\t\t\t\tfor (const row of current.rows) {\n\t\t\t\t\t\tif (row === undefined) continue\n\t\t\t\t\t\tfor (let column = 0; column < current.header.length; column += 1) {\n\t\t\t\t\t\t\tconst cell = row[column]\n\t\t\t\t\t\t\tif (cell !== undefined) {\n\t\t\t\t\t\t\t\tgroups.push(cell)\n\t\t\t\t\t\t\t\tadjacent.push(true)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdepth += 1\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t\tconst children: MarkdownNode[] = []\n\t\t\tconst escapeBangs: boolean[] = []\n\t\t\tfor (let groupIndex = 0; groupIndex < groups.length; groupIndex += 1) {\n\t\t\t\tconst group = groups[groupIndex]\n\t\t\t\tif (group === undefined) continue\n\t\t\t\tfor (let position = 0; position < group.length; position += 1) {\n\t\t\t\t\tconst child = group[position]\n\t\t\t\t\tif (child === undefined) continue\n\t\t\t\t\tlet escapeBang = false\n\t\t\t\t\tif (adjacent[groupIndex] === true) {\n\t\t\t\t\t\tlet nextPosition = position + 1\n\t\t\t\t\t\tlet next = group[nextPosition]\n\t\t\t\t\t\twhile (next === undefined && nextPosition < group.length) {\n\t\t\t\t\t\t\tnextPosition += 1\n\t\t\t\t\t\t\tnext = group[nextPosition]\n\t\t\t\t\t\t}\n\t\t\t\t\t\tescapeBang = next?.element === 'link'\n\t\t\t\t\t}\n\t\t\t\t\tchildren.push(child)\n\t\t\t\t\tescapeBangs.push(escapeBang)\n\t\t\t\t}\n\t\t\t}\n\t\t\tstack.push({ ...frame, expanded: true, count: children.length, escaped })\n\t\t\tconst nesting = current.element === 'emphasis' ? frame.nesting + 1 : frame.nesting\n\t\t\tfor (let index = children.length - 1; index >= 0; index -= 1) {\n\t\t\t\tconst child = children[index]\n\t\t\t\tif (child !== undefined)\n\t\t\t\t\tstack.push({\n\t\t\t\t\t\tnode: child,\n\t\t\t\t\t\tdepth,\n\t\t\t\t\t\texpanded: false,\n\t\t\t\t\t\tcount: 0,\n\t\t\t\t\t\tescaped: '',\n\t\t\t\t\t\tescapeBang: escapeBangs[index] === true && depth < MAX_DEPTH,\n\t\t\t\t\t\tnesting,\n\t\t\t\t\t})\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tconst children =\n\t\t\tframe.count === 0 ? [] : values.splice(values.length - frame.count, frame.count)\n\t\tlet value = ''\n\t\tswitch (current.element) {\n\t\t\tcase 'codeBlock':\n\t\t\tcase 'codeSpan': {\n\t\t\t\tconst body = current.element === 'codeBlock' ? current.code : current.value\n\t\t\t\tlet longest = 0\n\t\t\t\tlet run = 0\n\t\t\t\tfor (const character of body) {\n\t\t\t\t\tif (character === '`') {\n\t\t\t\t\t\trun += 1\n\t\t\t\t\t\tlongest = Math.max(longest, run)\n\t\t\t\t\t} else {\n\t\t\t\t\t\trun = 0\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst fence = '`'.repeat(Math.max(current.element === 'codeBlock' ? 3 : 1, longest + 1))\n\t\t\t\tif (current.element === 'codeBlock') {\n\t\t\t\t\tconst lang = current.lang === undefined ? '' : current.lang\n\t\t\t\t\tvalue = `${fence}${lang}\\n${current.code}\\n${fence}`\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tconst pad = current.value.startsWith('`') || current.value.endsWith('`') ? ' ' : ''\n\t\t\t\tvalue = `${fence}${pad}${current.value}${pad}${fence}`\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'break':\n\t\t\t\tvalue = ' \\n'\n\t\t\t\tbreak\n\t\t\tcase 'document':\n\t\t\t\tvalue = children.join('\\n\\n')\n\t\t\t\tbreak\n\t\t\tcase 'heading': {\n\t\t\t\tconst text = children.join('')\n\t\t\t\tconst escaped = text.replace(/(^|[^\\\\])(#+)$/, (_match, before: string, hashes: string) => {\n\t\t\t\t\tconst first = hashes[0] ?? ''\n\t\t\t\t\treturn `${before}\\\\${first}${hashes.slice(1)}`\n\t\t\t\t})\n\t\t\t\tvalue = `${'#'.repeat(current.level)} ${escaped}`\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'paragraph':\n\t\t\t\tvalue = children.join('')\n\t\t\t\tbreak\n\t\t\tcase 'thematicBreak':\n\t\t\t\tvalue = '---'\n\t\t\t\tbreak\n\t\t\tcase 'blockquote':\n\t\t\t\tvalue = children\n\t\t\t\t\t.join('\\n\\n')\n\t\t\t\t\t.split('\\n')\n\t\t\t\t\t.map((line) => (line === '' ? '>' : `> ${line}`))\n\t\t\t\t\t.join('\\n')\n\t\t\t\tbreak\n\t\t\tcase 'list': {\n\t\t\t\tconst items: string[] = []\n\t\t\t\tlet ordinal = current.start\n\t\t\t\tfor (const [position, body] of children.entries()) {\n\t\t\t\t\tconst marker = current.ordered ? `${ordinal}. ` : '- '\n\t\t\t\t\tordinal += 1\n\t\t\t\t\tconst pad = ' '.repeat(marker.length)\n\t\t\t\t\tif (current.items[position]?.children[0]?.element === 'table') {\n\t\t\t\t\t\titems.push(\n\t\t\t\t\t\t\t`${marker}\\n${body\n\t\t\t\t\t\t\t\t.split('\\n')\n\t\t\t\t\t\t\t\t.map((line) => pad + line)\n\t\t\t\t\t\t\t\t.join('\\n')}`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\titems.push(\n\t\t\t\t\t\tbody\n\t\t\t\t\t\t\t.split('\\n')\n\t\t\t\t\t\t\t.map((line, index) => (index === 0 ? marker + line : line === '' ? '' : pad + line))\n\t\t\t\t\t\t\t.join('\\n'),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tvalue = items.join('\\n')\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'listItem':\n\t\t\t\tvalue = children.join('\\n\\n')\n\t\t\t\tbreak\n\t\t\tcase 'table': {\n\t\t\t\tlet offset = 0\n\t\t\t\tconst header: string[] = []\n\t\t\t\tfor (const cell of current.header) {\n\t\t\t\t\tif (cell === undefined) {\n\t\t\t\t\t\theader.push('')\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tlet count = 0\n\t\t\t\t\tfor (const child of cell) if (child !== undefined) count += 1\n\t\t\t\t\theader.push(\n\t\t\t\t\t\tchildren\n\t\t\t\t\t\t\t.slice(offset, offset + count)\n\t\t\t\t\t\t\t.join('')\n\t\t\t\t\t\t\t.replace(/\\|/g, '\\\\|'),\n\t\t\t\t\t)\n\t\t\t\t\toffset += count\n\t\t\t\t}\n\t\t\t\tconst delimiter = current.align.map((align) => {\n\t\t\t\t\tif (align === null) return '---'\n\t\t\t\t\tif (align === 'left') return ':---'\n\t\t\t\t\tif (align === 'right') return '---:'\n\t\t\t\t\tif (align === 'center') return ':---:'\n\t\t\t\t\treturn '---'\n\t\t\t\t})\n\t\t\t\tconst rows: string[] = []\n\t\t\t\tfor (const row of current.rows) {\n\t\t\t\t\tconst cells: string[] = []\n\t\t\t\t\tfor (let column = 0; column < current.header.length; column += 1) {\n\t\t\t\t\t\tconst cell = row[column]\n\t\t\t\t\t\tif (cell === undefined) {\n\t\t\t\t\t\t\tcells.push('')\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlet count = 0\n\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) count += 1\n\t\t\t\t\t\tcells.push(\n\t\t\t\t\t\t\tchildren\n\t\t\t\t\t\t\t\t.slice(offset, offset + count)\n\t\t\t\t\t\t\t\t.join('')\n\t\t\t\t\t\t\t\t.replace(/\\|/g, '\\\\|'),\n\t\t\t\t\t\t)\n\t\t\t\t\t\toffset += count\n\t\t\t\t\t}\n\t\t\t\t\trows.push(`| ${cells.join(' | ')} |`)\n\t\t\t\t}\n\t\t\t\tvalue = [`| ${header.join(' | ')} |`, `| ${delimiter.join(' | ')} |`, ...rows].join('\\n')\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'text':\n\t\t\t\tvalue = frame.escaped\n\t\t\t\tbreak\n\t\t\tcase 'emphasis': {\n\t\t\t\tconst marker =\n\t\t\t\t\tframe.nesting % 2 === 0 ? (current.strong ? '**' : '*') : current.strong ? '__' : '_'\n\t\t\t\tvalue = `${marker}${children.join('')}${marker}`\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'link':\n\t\t\tcase 'image': {\n\t\t\t\tconst destination = current.element === 'link' ? current.href : current.src\n\t\t\t\tconst escaped = destination.replace(/[\\\\()]/g, (character) => `\\\\${character}`)\n\t\t\t\tconst prefix = current.element === 'image' ? '!' : ''\n\t\t\t\tvalue = `${prefix}[${children.join('')}](${escaped})`\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tvalue = ''\n\t\t\t\tbreak\n\t\t}\n\t\tif (stack.length === 0) return value\n\t\tvalues.push(value)\n\t}\n\treturn ''\n}\n\n// Projection (HTML AST → Markdown AST)\n//\n// The inverse of {@link markdownToHTML}, and the reason markdown owns both\n// directions: what an HTML subtree becomes is markdown-format knowledge, not HTML\n// knowledge. The engine is `@orkestrel/html`'s own `foldNode` catamorphism - it\n// already owns depth capping, cycle safety, and bottom-up folding - so this file\n// contributes the projection ONLY: five pure leaves over {@link MarkdownProjection}\n// values ({@link trimInlines}, {@link normalizeInlines}, {@link mergeProjections},\n// {@link projectionToBlocks}, {@link projectionToInlines}), the two handlers that\n// map HTML to markdown ({@link projectHTMLLeaf}, {@link projectHTMLNode}), and the one\n// entry point that folds them ({@link htmlToMarkdown}). HTML is richer than\n// markdown, so the projection is lossy by construction; what it must never be is\n// WRONG, which is what the round-trip anchor law pins down. {@link createProjection}\n// builds those values: it constructs a plain record under an invariant rather than an\n// entity, so it is a leaf here and not a factory.\n\n/**\n * Builds an HTML-to-markdown projection with absent fields defaulted from\n * {@link EMPTY_PROJECTION} and the block/inline exclusivity invariant enforced.\n *\n * @remarks\n * A block-bearing projection cannot also expose inline content. Callers may provide\n * both views, but `inlines` is flushed whenever `blocks` is non-empty.\n *\n * @param parts - The projection fields to provide\n * @returns A complete invariant-preserving projection\n *\n * @example\n * ```ts\n * createProjection({\n * blocks: [{ element: 'thematicBreak' }],\n * inlines: [{ element: 'text', value: 'discarded' }],\n * })\n * // { blocks: [{ element: 'thematicBreak' }], inlines: [], text: '', cells: [], rows: [] }\n * ```\n */\nexport function createProjection(parts: Partial<MarkdownProjection> = {}): MarkdownProjection {\n\tconst blocks = parts.blocks ?? EMPTY_PROJECTION.blocks\n\treturn {\n\t\tblocks,\n\t\tinlines: blocks.length === 0 ? (parts.inlines ?? EMPTY_PROJECTION.inlines) : [],\n\t\ttext: parts.text ?? EMPTY_PROJECTION.text,\n\t\tcells: parts.cells ?? EMPTY_PROJECTION.cells,\n\t\trows: parts.rows ?? EMPTY_PROJECTION.rows,\n\t}\n}\n\n/**\n * Trims the whitespace at the two ends of an inline run - the leading whitespace of a\n * leading text node and the trailing whitespace of a trailing one - dropping either\n * node when nothing survives.\n *\n * @remarks\n * Markdown trims every line of a paragraph, a heading's text, and a table cell, so an\n * untrimmed run would come back from a re-parse a different AST. Expects a coalesced\n * run (see {@link coalesceText}): only the outermost node on each side is examined.\n *\n * @param nodes - The inline run to trim\n * @returns The run with its edge whitespace removed\n *\n * @example\n * ```ts\n * trimInlines([{ element: 'text', value: ' a ' }]) // [{ element: 'text', value: 'a' }]\n * ```\n */\nexport function trimInlines(nodes: readonly InlineNode[]): readonly InlineNode[] {\n\tconst out: InlineNode[] = []\n\tfor (const node of nodes) if (node !== undefined) out.push(node)\n\tconst first = out[0]\n\tif (first !== undefined && first.element === 'text') {\n\t\tconst value = first.value.replace(/^\\s+/, '')\n\t\tif (isEmptyString(value)) out.shift()\n\t\telse out[0] = { element: 'text', value }\n\t}\n\tconst last = out[out.length - 1]\n\tif (last !== undefined && last.element === 'text') {\n\t\tconst value = last.value.replace(/\\s+$/, '')\n\t\tif (isEmptyString(value)) out.pop()\n\t\telse out[out.length - 1] = { element: 'text', value }\n\t}\n\treturn out\n}\n\n/**\n * Reduces an inline run to the shape markdown can actually write back: adjacent text\n * coalesced, empty text dropped, and every hard break either kept as a real line\n * ending or spent as a space.\n *\n * @remarks\n * A hard break is ` \\n` in markdown source, so it survives a re-parse only BETWEEN\n * two lines of content and only with no whitespace touching it: a leading or trailing\n * break has no line to end, a run of breaks reads as one blank line (which would end\n * the paragraph), and a space beside one is eaten by the parser's line trimming. Where\n * a break cannot be written at all - a heading and a table cell are one line each - it\n * becomes the space it stood for.\n *\n * @param nodes - The inline run to normalize\n * @param breaks - If `true`, keeps each hard break as a real line ending; if `false`, spends\n * every break as the space it stood for, as a heading or a table cell requires\n * @returns The normalized run\n *\n * @example\n * ```ts\n * normalizeInlines([{ element: 'break' }, { element: 'text', value: 'a' }], true)\n * // [{ element: 'text', value: 'a' }] - a leading break has no line to end\n * ```\n */\nexport function normalizeInlines(\n\tnodes: readonly InlineNode[],\n\tbreaks: boolean,\n): readonly InlineNode[] {\n\tconst spent: InlineNode[] = []\n\tfor (const node of nodes) {\n\t\tif (node === undefined) continue\n\t\tif (node.element === 'break' && !breaks) spent.push({ element: 'text', value: ' ' })\n\t\telse spent.push(node)\n\t}\n\tconst out: InlineNode[] = []\n\tfor (const node of coalesceText(spent)) {\n\t\tif (node === undefined) continue\n\t\tconst previous = out[out.length - 1]\n\t\tif (node.element === 'text') {\n\t\t\tconst value = previous?.element === 'break' ? node.value.replace(/^\\s+/, '') : node.value\n\t\t\tif (!isEmptyString(value)) out.push({ element: 'text', value })\n\t\t\tcontinue\n\t\t}\n\t\tif (node.element === 'break') {\n\t\t\tif (previous === undefined || previous.element === 'break') continue\n\t\t\tif (previous.element === 'text') {\n\t\t\t\tconst value = previous.value.replace(/\\s+$/, '')\n\t\t\t\tif (isEmptyString(value)) out.pop()\n\t\t\t\telse out[out.length - 1] = { element: 'text', value }\n\t\t\t}\n\t\t\tif (out.length === 0) continue\n\t\t\tout.push(node)\n\t\t\tcontinue\n\t\t}\n\t\tout.push(node)\n\t}\n\twhile (out.length > 0 && out[out.length - 1]?.element === 'break') out.pop()\n\treturn coalesceText(out)\n}\n\n/**\n * Combines the projections of one node's children into the projection of that node -\n * the single place inline runs become paragraphs, so no ancestor has to decide it\n * twice.\n *\n * @remarks\n * A child is either inline or block, never both, so merging preserves source order\n * exactly: an inline run is held pending until a block arrives, then written out as a\n * paragraph BEFORE it. That is what keeps `<div>lead<p>a</p></div>` two paragraphs in\n * the order they were written rather than two lists that lost their interleaving. A\n * pending run carrying no text is dropped rather than becoming a blank paragraph.\n * Direct cells become one row before a later row, while cells/rows before a block\n * materialize as paragraphs at that exact source position.\n *\n * @param children - The children's projections, in source order\n * @returns Their combined projection\n *\n * @example\n * ```ts\n * mergeProjections([\n * createProjection({ inlines: [{ element: 'text', value: 'a' }], text: 'a' }),\n * createProjection({ blocks: [{ element: 'thematicBreak' }] }),\n * ]).blocks\n * // [{ element: 'paragraph', children: [...] }, { element: 'thematicBreak' }]\n * ```\n */\nexport function mergeProjections(children: readonly MarkdownProjection[]): MarkdownProjection {\n\tconst blocks: BlockNode[] = []\n\tconst cells: MarkdownCell[] = []\n\tconst rows: Array<readonly MarkdownCell[]> = []\n\tlet pending: InlineNode[] = []\n\tlet text = ''\n\tfor (const child of children) {\n\t\tif (child === undefined) continue\n\t\ttext += child.text\n\t\tif (isNonEmptyArray(child.blocks)) {\n\t\t\tconst flushed = trimInlines(normalizeInlines(pending, true))\n\t\t\tif (isNonEmptyArray(flushed)) blocks.push({ element: 'paragraph', children: flushed })\n\t\t\tpending = []\n\t\t\tfor (const row of rows) {\n\t\t\t\tfor (const cell of row) {\n\t\t\t\t\tif (cell !== undefined && isNonEmptyArray(cell.inlines))\n\t\t\t\t\t\tblocks.push({ element: 'paragraph', children: cell.inlines })\n\t\t\t\t}\n\t\t\t}\n\t\t\trows.length = 0\n\t\t\tfor (const cell of cells) {\n\t\t\t\tif (cell !== undefined && isNonEmptyArray(cell.inlines))\n\t\t\t\t\tblocks.push({ element: 'paragraph', children: cell.inlines })\n\t\t\t}\n\t\t\tcells.length = 0\n\t\t\tfor (const block of projectionToBlocks(child)) blocks.push(block)\n\t\t\tcontinue\n\t\t}\n\t\tif (isNonEmptyArray(child.rows)) {\n\t\t\tif (isNonEmptyArray(cells)) {\n\t\t\t\trows.push([...cells])\n\t\t\t\tcells.length = 0\n\t\t\t}\n\t\t\tfor (const row of child.rows) if (row !== undefined) rows.push(row)\n\t\t}\n\t\tfor (const cell of child.cells) if (cell !== undefined) cells.push(cell)\n\t\tfor (const inline of child.inlines) if (inline !== undefined) pending.push(inline)\n\t}\n\tif (isNonEmptyArray(rows) && isNonEmptyArray(cells)) {\n\t\trows.push([...cells])\n\t\tcells.length = 0\n\t}\n\tif (!isNonEmptyArray(blocks))\n\t\treturn createProjection({ inlines: coalesceText(pending), text, cells, rows })\n\tconst flushed = trimInlines(normalizeInlines(pending, true))\n\tif (isNonEmptyArray(flushed)) blocks.push({ element: 'paragraph', children: flushed })\n\treturn createProjection({ blocks, text, cells, rows })\n}\n\n/**\n * Reads a projection as BLOCK content - the view a document, a blockquote, and a list\n * item each need.\n *\n * @remarks\n * A bare inline run becomes one paragraph, and a run carrying no text becomes nothing\n * at all, because a blank paragraph is unwritable in markdown. A cell or a row that\n * never reached a table is unwrapped here rather than dropped: a stray `<td>` is still\n * someone's content.\n *\n * @param projection - The projection to read\n * @returns Its block content\n *\n * @example\n * ```ts\n * projectionToBlocks(createProjection({ inlines: [{ element: 'text', value: 'a' }], text: 'a' }))\n * // [{ element: 'paragraph', children: [{ element: 'text', value: 'a' }] }]\n * ```\n */\nexport function projectionToBlocks(projection: MarkdownProjection): readonly BlockNode[] {\n\tconst blocks: BlockNode[] = []\n\tfor (const block of projection.blocks) if (block !== undefined) blocks.push(block)\n\tfor (const row of projection.rows) {\n\t\tif (row === undefined) continue\n\t\tfor (const cell of row) {\n\t\t\tif (cell === undefined || !isNonEmptyArray(cell.inlines)) continue\n\t\t\tblocks.push({ element: 'paragraph', children: cell.inlines })\n\t\t}\n\t}\n\tfor (const cell of projection.cells) {\n\t\tif (cell === undefined || !isNonEmptyArray(cell.inlines)) continue\n\t\tblocks.push({ element: 'paragraph', children: cell.inlines })\n\t}\n\tconst paragraph = trimInlines(normalizeInlines(projection.inlines, true))\n\tif (isNonEmptyArray(paragraph)) blocks.push({ element: 'paragraph', children: paragraph })\n\treturn blocks\n}\n\n/**\n * Reads a projection as INLINE content - the view a link, an emphasis, and a table cell\n * each need.\n *\n * @remarks\n * Inline content passes through as itself. Block content cannot: markdown has no way to\n * put a paragraph inside a table cell, so it flattens to one text node of its own words,\n * joined and whitespace-collapsed. Content that carries no text flattens to nothing\n * rather than to an empty text node, which is a shape the parser never produces.\n *\n * @param projection - The projection to read\n * @returns Its inline content\n *\n * @example\n * ```ts\n * projectionToInlines(createProjection({ inlines: [{ element: 'break' }] }))\n * // [{ element: 'break' }]\n * ```\n */\nexport function projectionToInlines(projection: MarkdownProjection): readonly InlineNode[] {\n\tif (\n\t\t!isNonEmptyArray(projection.blocks) &&\n\t\t!isNonEmptyArray(projection.cells) &&\n\t\t!isNonEmptyArray(projection.rows)\n\t) {\n\t\treturn coalesceText(projection.inlines)\n\t}\n\tconst value = collapseSpace(projectionToBlocks(projection).map(flattenText).join(' '))\n\treturn isEmptyString(value) ? [] : [{ element: 'text', value }]\n}\n\n/**\n * Projects one HTML leaf - a text node, a comment, or a doctype - to its\n * {@link MarkdownProjection}.\n *\n * @remarks\n * Text collapses each whitespace run to one space, which is both what HTML means by it\n * and all markdown can write back; the raw value travels on in `text` for the two\n * places that need it verbatim, a code span and a `pre > code` body. A comment and a\n * doctype carry nothing into markdown and project to nothing.\n *\n * @param leaf - The leaf node to project\n * @returns Its projection\n *\n * @example\n * ```ts\n * projectHTMLLeaf({ category: 'text', value: 'a\\n b' }).inlines\n * // [{ element: 'text', value: 'a b' }]\n * ```\n */\nexport function projectHTMLLeaf(\n\tleaf: CommentNode | DoctypeNode | HTMLTextNode,\n): MarkdownProjection {\n\tif (leaf.category !== 'text') return createProjection()\n\tconst value = leaf.value.replace(/\\s+/g, ' ')\n\treturn createProjection({\n\t\tinlines: isEmptyString(value) ? [] : [{ element: 'text', value }],\n\t\ttext: leaf.value,\n\t})\n}\n\n/**\n * Projects one HTML container - the document root or an element - from its children's\n * already-computed projections. THE element mapping, and the only place that decides\n * what an HTML tag becomes in markdown.\n *\n * @remarks\n * `h1`-`h6` become headings; `p` a paragraph; `strong` / `b` and `em` / `i` emphasis;\n * `code` a code span; `pre` a code block, verbatim through a first `code` element child\n * (its `language-` class naming the language) and through `renderText` otherwise; `a`\n * and `img` a link and an image, each destination re-sanitized; `br` and `hr` a hard\n * break and a thematic break; `blockquote` and `li` their block content, with bare\n * inline runs wrapped in paragraphs; `ul` / `ol` a list, ordered from the tag and\n * numbered from `start`; `th` / `td`, `tr`, and `table` a GFM table whose column\n * alignment comes from each header-position cell's `align` attribute. Every\n * `UNSAFE_ELEMENTS` subtree contributes nothing at all, text included. Every OTHER\n * element unwraps to its children, so wrapper soup melts while its content keeps its\n * shape - `<div><p>a</p><p>b</p></div>` stays two paragraphs.\n *\n * Three mappings read their own node rather than only their children's projections,\n * because HTML puts the fact in a position rather than in a value: a `pre` takes its\n * body from its `code` child's raw text, and a list takes one item per `li` child - so\n * an empty `<li>` is still an item, while the whitespace between two of them is not.\n * A `tr` accepts only its own direct cells, and a table derives the first `th`-bearing\n * row from its own source structure.\n *\n * @param node - The document root or element to project\n * @param children - Its children's projections, in source order\n * @returns Its projection\n *\n * @example\n * ```ts\n * projectHTMLNode({ category: 'element', name: 'hr', attributes: [], children: [] }, []).blocks\n * // [{ element: 'thematicBreak' }]\n * ```\n */\nexport function projectHTMLNode(\n\tnode: ElementNode | HTMLDocument,\n\tchildren: readonly MarkdownProjection[],\n): MarkdownProjection {\n\tif (node.category === 'document') return mergeProjections(children)\n\tif (UNSAFE_ELEMENTS.includes(node.name)) return createProjection()\n\tconst merged = mergeProjections(children)\n\tconst level = /^h([1-6])$/.exec(node.name)\n\tif (level !== null) {\n\t\treturn createProjection({\n\t\t\tblocks: [\n\t\t\t\t{\n\t\t\t\t\telement: 'heading',\n\t\t\t\t\tlevel: parseInteger(level[1]) ?? 1,\n\t\t\t\t\tchildren: trimInlines(normalizeInlines(projectionToInlines(merged), false)),\n\t\t\t\t},\n\t\t\t],\n\t\t\ttext: merged.text,\n\t\t})\n\t}\n\tswitch (node.name) {\n\t\tcase 'p':\n\t\tcase 'li':\n\t\t\treturn createProjection({\n\t\t\t\tblocks: projectionToBlocks(merged),\n\t\t\t\ttext: merged.text,\n\t\t\t})\n\t\tcase 'blockquote':\n\t\t\treturn createProjection({\n\t\t\t\tblocks: [{ element: 'blockquote', children: projectionToBlocks(merged) }],\n\t\t\t\ttext: merged.text,\n\t\t\t})\n\t\tcase 'hr':\n\t\t\treturn createProjection({\n\t\t\t\tblocks: [{ element: 'thematicBreak' }],\n\t\t\t\ttext: '',\n\t\t\t})\n\t\tcase 'br':\n\t\t\treturn createProjection({ inlines: [{ element: 'break' }], text: '\\n' })\n\t\tcase 'strong':\n\t\tcase 'b':\n\t\tcase 'em':\n\t\tcase 'i': {\n\t\t\tconst content = projectionToInlines(merged)\n\t\t\tconst inner = trimInlines(normalizeInlines(content, true))\n\t\t\tif (!isNonEmptyArray(inner)) return createProjection({ text: merged.text })\n\t\t\t// Markdown refuses emphasis padded with whitespace (`* x *` is literal), so the\n\t\t\t// padding moves OUTSIDE the marker rather than being lost with the word boundary.\n\t\t\tconst first = content[0]\n\t\t\tconst last = content[content.length - 1]\n\t\t\tconst inlines: InlineNode[] = []\n\t\t\tif (first?.element === 'text' && /^\\s/.test(first.value))\n\t\t\t\tinlines.push({ element: 'text', value: ' ' })\n\t\t\tinlines.push({\n\t\t\t\telement: 'emphasis',\n\t\t\t\tstrong: node.name === 'strong' || node.name === 'b',\n\t\t\t\tchildren: inner,\n\t\t\t})\n\t\t\tif (last?.element === 'text' && /\\s$/.test(last.value))\n\t\t\t\tinlines.push({ element: 'text', value: ' ' })\n\t\t\treturn createProjection({ inlines, text: merged.text })\n\t\t}\n\t\tcase 'code': {\n\t\t\tconst body = merged.text.replace(/\\r\\n?/g, '\\n').replace(/\\s*\\n\\s*/g, ' ')\n\t\t\t// A span padded on BOTH sides is exactly what the parser strips back off, so the\n\t\t\t// canonical value is the stripped one.\n\t\t\tconst value =\n\t\t\t\tbody.length > 2 && body.startsWith(' ') && body.endsWith(' ') && !isEmptyString(body.trim())\n\t\t\t\t\t? body.trim()\n\t\t\t\t\t: body\n\t\t\treturn createProjection({\n\t\t\t\tinlines: isEmptyString(value) ? [] : [{ element: 'codeSpan', value }],\n\t\t\t\ttext: merged.text,\n\t\t\t})\n\t\t}\n\t\tcase 'pre': {\n\t\t\tlet position = -1\n\t\t\tfor (const [index, child] of node.children.entries()) {\n\t\t\t\tif (child?.category !== 'element') continue\n\t\t\t\tposition = index\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tconst source = position === -1 ? undefined : node.children[position]\n\t\t\tconst projected = position === -1 ? undefined : children[position]\n\t\t\tif (source?.category === 'element' && source.name === 'code' && projected !== undefined) {\n\t\t\t\tlet lang: string | undefined\n\t\t\t\tfor (const token of (attributeOf(source, 'class') ?? '').split(/\\s+/)) {\n\t\t\t\t\tif (!token.startsWith('language-') || token.length <= 9 || token.includes('`')) continue\n\t\t\t\t\tlang = token.slice(9)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\treturn createProjection({\n\t\t\t\t\tblocks: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\telement: 'codeBlock',\n\t\t\t\t\t\t\t...(lang === undefined ? {} : { lang }),\n\t\t\t\t\t\t\tcode: projected.text.replace(/\\r\\n?/g, '\\n'),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\ttext: merged.text,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn createProjection({\n\t\t\t\tblocks: [{ element: 'codeBlock', code: renderText(node).replace(/\\r\\n?/g, '\\n') }],\n\t\t\t\ttext: merged.text,\n\t\t\t})\n\t\t}\n\t\tcase 'a':\n\t\t\treturn createProjection({\n\t\t\t\tinlines: [\n\t\t\t\t\t{\n\t\t\t\t\t\telement: 'link',\n\t\t\t\t\t\thref: sanitizeURL(attributeOf(node, 'href') ?? '', SAFE_URL_SCHEMES),\n\t\t\t\t\t\tchildren: normalizeInlines(projectionToInlines(merged), true),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\ttext: merged.text,\n\t\t\t})\n\t\tcase 'img': {\n\t\t\tconst alt = collapseSpace(attributeOf(node, 'alt') ?? '')\n\t\t\treturn createProjection({\n\t\t\t\tinlines: [\n\t\t\t\t\t{\n\t\t\t\t\t\telement: 'image',\n\t\t\t\t\t\tsrc: sanitizeURL(attributeOf(node, 'src') ?? '', SAFE_URL_SCHEMES),\n\t\t\t\t\t\tchildren: isEmptyString(alt) ? [] : [{ element: 'text', value: alt }],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\ttext: '',\n\t\t\t})\n\t\t}\n\t\tcase 'th':\n\t\tcase 'td': {\n\t\t\t// html's set is the gate; the union is the bridge - an alignment markdown has no\n\t\t\t// delimiter for stays absent rather than becoming a decorative label.\n\t\t\tconst declared = (attributeOf(node, 'align') ?? '').trim().toLowerCase()\n\t\t\tconst align =\n\t\t\t\tTABLE_ALIGNMENTS.includes(declared) &&\n\t\t\t\t(declared === 'left' || declared === 'right' || declared === 'center')\n\t\t\t\t\t? declared\n\t\t\t\t\t: undefined\n\t\t\treturn createProjection({\n\t\t\t\ttext: merged.text,\n\t\t\t\tcells: [\n\t\t\t\t\t{\n\t\t\t\t\t\talign,\n\t\t\t\t\t\tinlines: trimInlines(normalizeInlines(projectionToInlines(merged), false)),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t})\n\t\t}\n\t\tcase 'tr': {\n\t\t\tconst cells: MarkdownCell[] = []\n\t\t\tfor (const [index, child] of children.entries()) {\n\t\t\t\tconst source = node.children[index]\n\t\t\t\tif (\n\t\t\t\t\tsource?.category !== 'element' ||\n\t\t\t\t\t(source.name !== 'th' && source.name !== 'td') ||\n\t\t\t\t\tchild === undefined\n\t\t\t\t) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tfor (const cell of child.cells) if (cell !== undefined) cells.push(cell)\n\t\t\t}\n\t\t\treturn createProjection({ text: merged.text, rows: [cells] })\n\t\t}\n\t\tcase 'ul':\n\t\tcase 'ol': {\n\t\t\tconst items: ListItemNode[] = []\n\t\t\tfor (const [index, child] of children.entries()) {\n\t\t\t\tif (child === undefined) continue\n\t\t\t\tconst source = node.children[index]\n\t\t\t\tconst blocks = projectionToBlocks(child)\n\t\t\t\tif (source?.category === 'element' && source.name === 'li') {\n\t\t\t\t\titems.push({ element: 'listItem', children: blocks })\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (isNonEmptyArray(blocks)) items.push({ element: 'listItem', children: blocks })\n\t\t\t}\n\t\t\tif (!isNonEmptyArray(items)) return createProjection({ text: merged.text })\n\t\t\tconst ordered = node.name === 'ol'\n\t\t\tconst declared = parseInteger(attributeOf(node, 'start'))\n\t\t\t// A start markdown cannot write as an ordinal (`\\d{1,9}`) is no start at all.\n\t\t\tconst start =\n\t\t\t\tordered && declared !== undefined && declared >= 0 && declared <= 999_999_999 ? declared : 1\n\t\t\treturn createProjection({\n\t\t\t\tblocks: [{ element: 'list', ordered, start, items }],\n\t\t\t\ttext: merged.text,\n\t\t\t})\n\t\t}\n\t\tcase 'table': {\n\t\t\tconst rows: Array<readonly MarkdownCell[]> = []\n\t\t\tfor (const row of merged.rows) if (row !== undefined) rows.push(row)\n\t\t\tif (isNonEmptyArray(merged.cells)) rows.push(merged.cells)\n\t\t\tconst headings: boolean[] = []\n\t\t\tconst rowed: boolean[] = []\n\t\t\tconst sources: Array<{\n\t\t\t\tchildren: readonly HTMLNode[]\n\t\t\t\tindex: number\n\t\t\t\tdirect: boolean\n\t\t\t}> = [{ children: node.children, index: 0, direct: false }]\n\t\t\twhile (sources.length > 0) {\n\t\t\t\tconst source = sources.pop()\n\t\t\t\tif (source === undefined) continue\n\t\t\t\tif (source.index >= source.children.length) continue\n\t\t\t\tconst child = source.children[source.index]\n\t\t\t\tsource.index += 1\n\t\t\t\tsources.push(source)\n\t\t\t\tif (child?.category !== 'element') continue\n\t\t\t\tif (child.name === 'th' || child.name === 'td') {\n\t\t\t\t\tif (!source.direct) {\n\t\t\t\t\t\theadings.push(false)\n\t\t\t\t\t\trowed.push(false)\n\t\t\t\t\t}\n\t\t\t\t\tsource.direct = true\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tsource.direct = false\n\t\t\t\tif (child.name === 'tr') {\n\t\t\t\t\tlet heading = false\n\t\t\t\t\tfor (const cell of child.children) {\n\t\t\t\t\t\tif (cell?.category === 'element' && cell.name === 'th') {\n\t\t\t\t\t\t\theading = true\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\theadings.push(heading)\n\t\t\t\t\trowed.push(true)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tsources.push({ children: child.children, index: 0, direct: false })\n\t\t\t}\n\t\t\t// The header is the first structurally th-bearing row, then the first explicit\n\t\t\t// row; a table made only of direct cells receives an empty synthetic header.\n\t\t\tlet position: number | undefined\n\t\t\tfor (const [index, heading] of headings.entries()) {\n\t\t\t\tif (!heading) continue\n\t\t\t\tposition = index\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif (position === undefined) {\n\t\t\t\tfor (const [index, structural] of rowed.entries()) {\n\t\t\t\t\tif (!structural) continue\n\t\t\t\t\tposition = index\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst headerRow = position === undefined ? undefined : rows[position]\n\t\t\tconst columns = headerRow?.length ?? rows[0]?.length ?? 0\n\t\t\tif (columns === 0) {\n\t\t\t\treturn createProjection({\n\t\t\t\t\tblocks: projectionToBlocks(merged),\n\t\t\t\t\ttext: merged.text,\n\t\t\t\t})\n\t\t\t}\n\t\t\tconst header: Array<readonly InlineNode[]> = []\n\t\t\tconst align: Array<TableAlign | null> = []\n\t\t\tfor (let column = 0; column < columns; column += 1) {\n\t\t\t\tconst cell = headerRow?.[column]\n\t\t\t\theader.push(cell?.inlines ?? [])\n\t\t\t\talign.push(cell?.align ?? null)\n\t\t\t}\n\t\t\tconst body: Array<ReadonlyArray<readonly InlineNode[]>> = []\n\t\t\tfor (const [index, row] of rows.entries()) {\n\t\t\t\tif (row === undefined || index === position) continue\n\t\t\t\tconst cells: Array<readonly InlineNode[]> = []\n\t\t\t\tfor (let column = 0; column < header.length; column += 1)\n\t\t\t\t\tcells.push(row[column]?.inlines ?? [])\n\t\t\t\tbody.push(cells)\n\t\t\t}\n\t\t\treturn createProjection({\n\t\t\t\tblocks: [{ element: 'table', header, rows: body, align }],\n\t\t\t\ttext: merged.text,\n\t\t\t})\n\t\t}\n\t}\n\treturn merged\n}\n\n/**\n * Projects an `@orkestrel/html` {@link HTMLNode} into a {@link MarkdownDocument} - the\n * HTML→markdown direction, and the inverse of {@link markdownToHTML}.\n *\n * @remarks\n * **Engine.** One total handler table - {@link projectHTMLNode} for the containers,\n * {@link projectHTMLLeaf} for the leaves - folded by `@orkestrel/html`'s own `foldNode`, so\n * depth capping, cycle safety, and bottom-up ordering are inherited rather than\n * rebuilt. Total: hostile, cyclic, and pathologically deep input degrades instead of\n * throwing.\n *\n * **Composed depth.** Both packages cap recursion at 64, and html's cap is reached\n * first: a document nested past it projects to a chain bounded by THAT cap, with the\n * content below it truncated before markdown ever sees it. Since the projected chain\n * can be a level or two deeper than {@link MAX_DEPTH}, the serializer's own cap can\n * then truncate again - so the anchor law below is a law within the depth budget, and\n * beyond it only totality is promised.\n *\n * **Safety.** Every `href` and `src` is re-sanitized through\n * `sanitizeURL(value, SAFE_URL_SCHEMES)` whether or not the AST was ever sanitized,\n * because a hand-built one never was. A refused destination empties to `''` and the\n * link or image is KEPT - `[text]()` - since a bad URL is no reason to lose the words\n * around it. An `UNSAFE_ELEMENTS` subtree contributes nothing at all, text included, so\n * a `script` body can never resurface as prose.\n *\n * **The anchor law.** HTML→markdown is lossy, so the fixpoint that matters is the\n * PROJECTED AST, not the input bytes:\n * `parseDocument(renderMarkdown(htmlToMarkdown(x)))` deep-equals `htmlToMarkdown(x)`.\n * The projection therefore emits canonical markdown shapes rather than literal\n * translations - whitespace collapsed, edges trimmed, a blank paragraph dropped, a hard\n * break only where a line can end - because a shape markdown cannot write back is a\n * shape this projection has no business producing.\n *\n * @param node - The HTML document or bare node to project\n * @returns The projected markdown document\n *\n * @example\n * ```ts\n * import { parseDocument } from '@orkestrel/html'\n *\n * htmlToMarkdown(parseDocument('<h1>Title</h1>'))\n * // { element: 'document', children: [{ element: 'heading', level: 1, children: [...] }] }\n * ```\n */\nexport function htmlToMarkdown(node: HTMLNode): MarkdownDocument {\n\treturn {\n\t\telement: 'document',\n\t\tchildren: projectionToBlocks(\n\t\t\tfoldHTMLNode<MarkdownProjection>(node, {\n\t\t\t\tdocument: projectHTMLNode,\n\t\t\t\telement: projectHTMLNode,\n\t\t\t\ttext: projectHTMLLeaf,\n\t\t\t\tcomment: projectHTMLLeaf,\n\t\t\t\tdoctype: projectHTMLLeaf,\n\t\t\t}),\n\t\t),\n\t}\n}\n\n/**\n * Walks a {@link MarkdownNode} depth-first, pre-order, root-inclusive - yields\n * the node itself, then recurses into its children (block children, list items,\n * image/link inline children, table header/row cells' inline nodes) in walk order.\n *\n * @remarks\n * Total: never throws. Descent stops at {@link MAX_DEPTH} (the node at the cap is\n * still yielded; its children are not) so pathologically deep input cannot exhaust\n * the call stack.\n *\n * @param node - The AST node to walk (a full document, or any sub-node)\n * @returns A generator yielding every visited node, pre-order\n *\n * @example\n * ```ts\n * const doc = { element: 'document', children: [{ element: 'thematicBreak' }] } as const\n * [...walkNodes(doc)].map((node) => node.element) // ['document', 'thematicBreak']\n * ```\n */\nexport function* walkNodes(node: MarkdownNode): Generator<MarkdownNode> {\n\tconst stack: Array<{ readonly node: MarkdownNode; readonly depth: number }> = [{ node, depth: 0 }]\n\twhile (stack.length > 0) {\n\t\tconst frame = stack.pop()\n\t\tif (frame === undefined) continue\n\t\tyield frame.node\n\t\tif (frame.depth >= MAX_DEPTH) continue\n\t\tconst children: MarkdownNode[] = []\n\t\tswitch (frame.node.element) {\n\t\t\tcase 'document':\n\t\t\tcase 'heading':\n\t\t\tcase 'paragraph':\n\t\t\tcase 'blockquote':\n\t\t\tcase 'listItem':\n\t\t\tcase 'emphasis':\n\t\t\tcase 'link':\n\t\t\tcase 'image':\n\t\t\t\tfor (const child of frame.node.children) if (child !== undefined) children.push(child)\n\t\t\t\tbreak\n\t\t\tcase 'list':\n\t\t\t\tfor (const child of frame.node.items) if (child !== undefined) children.push(child)\n\t\t\t\tbreak\n\t\t\tcase 'table':\n\t\t\t\tfor (const cell of frame.node.header)\n\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\tfor (const row of frame.node.rows)\n\t\t\t\t\tif (row !== undefined)\n\t\t\t\t\t\tfor (const cell of row)\n\t\t\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\tbreak\n\t\t}\n\t\tfor (let index = children.length - 1; index >= 0; index -= 1) {\n\t\t\tconst child = children[index]\n\t\t\tif (child !== undefined) stack.push({ node: child, depth: frame.depth + 1 })\n\t\t}\n\t}\n}\n\n/**\n * Folds a {@link MarkdownNode} into a `T` through a total catamorphism - children are\n * folded first (post-order), then the node's own {@link MarkdownHandler} is invoked\n * with the already-folded children.\n *\n * @remarks\n * **Table contract.** A {@link TableNode} has no single `children` array - its cells\n * live in `header` (one inline-node list per column) and `rows` (a list of such\n * rows). The `table` handler receives ONE folded `T` per inline node, flattened in\n * walk order across ALL cells - every header cell's inline nodes (column order), then\n * every body row's cells' inline nodes (row order, then column order) - and reads\n * `node.header[c].length` / `node.rows[r][c].length` off the table node itself to\n * recover cell boundaries within the flat list.\n *\n * Total: never throws. At `depth >= {@link MAX_DEPTH}` the node's handler is invoked\n * with an empty children list instead of recursing further.\n *\n * @param node - The AST node to fold\n * @param handlers - The total {@link MarkdownHandlerMap} table, one handler per element\n * @param depth - The starting recursion depth (pass `0` at the entry point)\n * @returns The folded `T`\n *\n * @example\n * ```ts\n * const countHandlers: MarkdownHandlerMap<number> = {\n * document: (_, children) => children.reduce((a, b) => a + b, 1),\n * // ...one handler per element, each summing its folded children\n * }\n * foldNode(document, countHandlers, 0) // total node count\n * ```\n */\nexport function foldNode<T>(node: MarkdownNode, handlers: MarkdownHandlerMap<T>, depth: number): T {\n\tconst stack: Array<{\n\t\treadonly node: MarkdownNode\n\t\treadonly depth: number\n\t\treadonly expanded: boolean\n\t\treadonly count: number\n\t}> = [{ node, depth, expanded: false, count: 0 }]\n\tconst values: T[] = []\n\twhile (stack.length > 0) {\n\t\tconst frame = stack.pop()\n\t\tif (frame === undefined) continue\n\t\tif (!frame.expanded) {\n\t\t\tconst children: MarkdownNode[] = []\n\t\t\tif (frame.depth < MAX_DEPTH) {\n\t\t\t\tswitch (frame.node.element) {\n\t\t\t\t\tcase 'document':\n\t\t\t\t\tcase 'heading':\n\t\t\t\t\tcase 'paragraph':\n\t\t\t\t\tcase 'blockquote':\n\t\t\t\t\tcase 'listItem':\n\t\t\t\t\tcase 'emphasis':\n\t\t\t\t\tcase 'link':\n\t\t\t\t\tcase 'image':\n\t\t\t\t\t\tfor (const child of frame.node.children) if (child !== undefined) children.push(child)\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase 'list':\n\t\t\t\t\t\tfor (const child of frame.node.items) if (child !== undefined) children.push(child)\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase 'table':\n\t\t\t\t\t\tfor (const cell of frame.node.header)\n\t\t\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\t\t\tfor (const row of frame.node.rows)\n\t\t\t\t\t\t\tif (row !== undefined)\n\t\t\t\t\t\t\t\tfor (const cell of row)\n\t\t\t\t\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tstack.push({ ...frame, expanded: true, count: children.length })\n\t\t\tfor (let index = children.length - 1; index >= 0; index -= 1) {\n\t\t\t\tconst child = children[index]\n\t\t\t\tif (child !== undefined) {\n\t\t\t\t\tstack.push({\n\t\t\t\t\t\tnode: child,\n\t\t\t\t\t\tdepth: frame.depth + 1,\n\t\t\t\t\t\texpanded: false,\n\t\t\t\t\t\tcount: 0,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tconst children =\n\t\t\tframe.count === 0 ? [] : values.splice(values.length - frame.count, frame.count)\n\t\tlet value: T\n\t\tswitch (frame.node.element) {\n\t\t\tcase 'document':\n\t\t\t\tvalue = handlers.document(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'heading':\n\t\t\t\tvalue = handlers.heading(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'paragraph':\n\t\t\t\tvalue = handlers.paragraph(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'thematicBreak':\n\t\t\t\tvalue = handlers.thematicBreak(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'blockquote':\n\t\t\t\tvalue = handlers.blockquote(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'codeBlock':\n\t\t\t\tvalue = handlers.codeBlock(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'list':\n\t\t\t\tvalue = handlers.list(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'listItem':\n\t\t\t\tvalue = handlers.listItem(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'table':\n\t\t\t\tvalue = handlers.table(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'text':\n\t\t\t\tvalue = handlers.text(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'emphasis':\n\t\t\t\tvalue = handlers.emphasis(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'codeSpan':\n\t\t\t\tvalue = handlers.codeSpan(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'break':\n\t\t\t\tvalue = handlers.break(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'link':\n\t\t\t\tvalue = handlers.link(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'image':\n\t\t\t\tvalue = handlers.image(frame.node, children)\n\t\t\t\tbreak\n\t\t}\n\t\tif (stack.length === 0) return value\n\t\tvalues.push(value)\n\t}\n\tswitch (node.element) {\n\t\tcase 'document':\n\t\t\treturn handlers.document(node, [])\n\t\tcase 'heading':\n\t\t\treturn handlers.heading(node, [])\n\t\tcase 'paragraph':\n\t\t\treturn handlers.paragraph(node, [])\n\t\tcase 'thematicBreak':\n\t\t\treturn handlers.thematicBreak(node, [])\n\t\tcase 'blockquote':\n\t\t\treturn handlers.blockquote(node, [])\n\t\tcase 'codeBlock':\n\t\t\treturn handlers.codeBlock(node, [])\n\t\tcase 'list':\n\t\t\treturn handlers.list(node, [])\n\t\tcase 'listItem':\n\t\t\treturn handlers.listItem(node, [])\n\t\tcase 'table':\n\t\t\treturn handlers.table(node, [])\n\t\tcase 'text':\n\t\t\treturn handlers.text(node, [])\n\t\tcase 'emphasis':\n\t\t\treturn handlers.emphasis(node, [])\n\t\tcase 'codeSpan':\n\t\t\treturn handlers.codeSpan(node, [])\n\t\tcase 'break':\n\t\t\treturn handlers.break(node, [])\n\t\tcase 'link':\n\t\t\treturn handlers.link(node, [])\n\t\tcase 'image':\n\t\t\treturn handlers.image(node, [])\n\t}\n}\n\n/**\n * Rewrites a {@link MarkdownDocument} bottom-up (copy-on-write) - each node's children\n * are rewritten first (post-order), then `rewrite` is applied to the node itself; the\n * document ROOT is never passed to `rewrite` (the `element: 'document'` invariant\n * always holds). A table's inline cells and a list's items ARE rewritten.\n *\n * @remarks\n * Never mutates `document`. An unchanged subtree keeps its input identity. A parent\n * is rebuilt only when an accepted child changes, and the returned derivation map\n * associates each rebuilt output with its input node. When `rewrite` returns a node\n * whose `element` does not fit the slot it was called for (a block slot handed a\n * non-{@link BlockNode}, an inline slot handed a non-{@link InlineNode}, a list-item\n * slot handed a non-`listItem`), the ill-fitting result is discarded and the accepted\n * input child is reused - `rewriteDocument` stays total and never produces a\n * structurally invalid document.\n *\n * Descent is capped at {@link MAX_DEPTH}, the same cap {@link walkNodes} and\n * {@link foldNode} observe: at `depth >= MAX_DEPTH` the subtree is passed through\n * UNCHANGED (by reference, not rebuilt, and `rewrite` is not invoked on it) instead of\n * recursing further, so a pathologically deep adopted document cannot exhaust the\n * call stack. {@link MarkdownInterface.map} inherits this cap since it delegates here.\n *\n * @param document - The document AST to rewrite\n * @param rewrite - The bottom-up {@link MarkdownRewriteHandler}\n * @returns The rewritten document and its output-to-input derivations\n *\n * @example\n * ```ts\n * const [rewritten, derivations] = rewriteDocument(document, (node) =>\n * node.element === 'text' ? { element: 'text', value: node.value.toUpperCase() } : node,\n * )\n * ```\n */\nexport function rewriteDocument(\n\tdocument: MarkdownDocument,\n\trewrite: MarkdownRewriteHandler,\n): MarkdownDerivation<MarkdownDocument> {\n\tconst stack: Array<{\n\t\treadonly node: MarkdownNode\n\t\treadonly depth: number\n\t\treadonly expanded: boolean\n\t\treadonly count: number\n\t}> = [{ node: document, depth: -1, expanded: false, count: 0 }]\n\tconst values: MarkdownNode[] = []\n\tconst derivations = new Map<MarkdownNode, MarkdownNode | undefined>()\n\twhile (stack.length > 0) {\n\t\tconst frame = stack.pop()\n\t\tif (frame === undefined) continue\n\t\tconst current = frame.node\n\t\tif (!frame.expanded) {\n\t\t\tif (current.element !== 'document' && frame.depth >= MAX_DEPTH) {\n\t\t\t\tvalues.push(current)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst children: MarkdownNode[] = []\n\t\t\tswitch (current.element) {\n\t\t\t\tcase 'document':\n\t\t\t\tcase 'heading':\n\t\t\t\tcase 'paragraph':\n\t\t\t\tcase 'blockquote':\n\t\t\t\tcase 'listItem':\n\t\t\t\tcase 'emphasis':\n\t\t\t\tcase 'link':\n\t\t\t\tcase 'image':\n\t\t\t\t\tfor (const child of current.children) if (child !== undefined) children.push(child)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'list':\n\t\t\t\t\tfor (const child of current.items) if (child !== undefined) children.push(child)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'table':\n\t\t\t\t\tfor (const cell of current.header)\n\t\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\t\tfor (const row of current.rows)\n\t\t\t\t\t\tif (row !== undefined)\n\t\t\t\t\t\t\tfor (const cell of row)\n\t\t\t\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t\tstack.push({ ...frame, expanded: true, count: children.length })\n\t\t\tconst depth = current.element === 'document' ? 0 : frame.depth + 1\n\t\t\tfor (let index = children.length - 1; index >= 0; index -= 1) {\n\t\t\t\tconst child = children[index]\n\t\t\t\tif (child !== undefined) stack.push({ node: child, depth, expanded: false, count: 0 })\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tconst children =\n\t\t\tframe.count === 0 ? [] : values.splice(values.length - frame.count, frame.count)\n\t\tlet rebuilt: MarkdownNode = current\n\t\tlet changed = false\n\t\tswitch (current.element) {\n\t\t\tcase 'document': {\n\t\t\t\tconst blocks: BlockNode[] = []\n\t\t\t\tlet offset = 0\n\t\t\t\tfor (const block of current.children) {\n\t\t\t\t\tif (block === undefined) continue\n\t\t\t\t\tconst child = children[offset]\n\t\t\t\t\tconst accepted = child !== undefined && isBlockNode(child) ? child : block\n\t\t\t\t\tblocks.push(accepted)\n\t\t\t\t\tif (accepted !== block) changed = true\n\t\t\t\t\toffset += 1\n\t\t\t\t}\n\t\t\t\tif (changed) rebuilt = { element: 'document', children: blocks }\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'heading':\n\t\t\tcase 'paragraph': {\n\t\t\t\tconst inlines: InlineNode[] = []\n\t\t\t\tlet offset = 0\n\t\t\t\tfor (const inline of current.children) {\n\t\t\t\t\tif (inline === undefined) continue\n\t\t\t\t\tconst child = children[offset]\n\t\t\t\t\tconst accepted = child !== undefined && isInlineNode(child) ? child : inline\n\t\t\t\t\tinlines.push(accepted)\n\t\t\t\t\tif (accepted !== inline) changed = true\n\t\t\t\t\toffset += 1\n\t\t\t\t}\n\t\t\t\tif (changed) rebuilt = { ...current, children: inlines }\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'blockquote': {\n\t\t\t\tconst blocks: BlockNode[] = []\n\t\t\t\tlet offset = 0\n\t\t\t\tfor (const block of current.children) {\n\t\t\t\t\tif (block === undefined) continue\n\t\t\t\t\tconst child = children[offset]\n\t\t\t\t\tconst accepted = child !== undefined && isBlockNode(child) ? child : block\n\t\t\t\t\tblocks.push(accepted)\n\t\t\t\t\tif (accepted !== block) changed = true\n\t\t\t\t\toffset += 1\n\t\t\t\t}\n\t\t\t\tif (changed) rebuilt = { ...current, children: blocks }\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'listItem': {\n\t\t\t\tconst blocks: BlockNode[] = []\n\t\t\t\tlet offset = 0\n\t\t\t\tfor (const block of current.children) {\n\t\t\t\t\tif (block === undefined) continue\n\t\t\t\t\tconst child = children[offset]\n\t\t\t\t\tconst accepted = child !== undefined && isBlockNode(child) ? child : block\n\t\t\t\t\tblocks.push(accepted)\n\t\t\t\t\tif (accepted !== block) changed = true\n\t\t\t\t\toffset += 1\n\t\t\t\t}\n\t\t\t\tif (changed) rebuilt = { element: 'listItem', children: blocks }\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'emphasis':\n\t\t\tcase 'link':\n\t\t\tcase 'image': {\n\t\t\t\tconst inlines: InlineNode[] = []\n\t\t\t\tlet offset = 0\n\t\t\t\tfor (const inline of current.children) {\n\t\t\t\t\tif (inline === undefined) continue\n\t\t\t\t\tconst child = children[offset]\n\t\t\t\t\tconst accepted = child !== undefined && isInlineNode(child) ? child : inline\n\t\t\t\t\tinlines.push(accepted)\n\t\t\t\t\tif (accepted !== inline) changed = true\n\t\t\t\t\toffset += 1\n\t\t\t\t}\n\t\t\t\tif (changed) rebuilt = { ...current, children: inlines }\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'list': {\n\t\t\t\tconst items: ListItemNode[] = []\n\t\t\t\tlet offset = 0\n\t\t\t\tfor (const item of current.items) {\n\t\t\t\t\tif (item === undefined) continue\n\t\t\t\t\tconst child = children[offset]\n\t\t\t\t\tconst accepted = child?.element === 'listItem' ? child : item\n\t\t\t\t\titems.push(accepted)\n\t\t\t\t\tif (accepted !== item) changed = true\n\t\t\t\t\toffset += 1\n\t\t\t\t}\n\t\t\t\tif (changed) rebuilt = { ...current, items }\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'table': {\n\t\t\t\tlet offset = 0\n\t\t\t\tconst header: Array<readonly InlineNode[]> = []\n\t\t\t\tfor (const cell of current.header) {\n\t\t\t\t\tif (cell === undefined) continue\n\t\t\t\t\tconst inlines: InlineNode[] = []\n\t\t\t\t\tfor (const inline of cell) {\n\t\t\t\t\t\tif (inline === undefined) continue\n\t\t\t\t\t\tconst child = children[offset]\n\t\t\t\t\t\tconst accepted = child !== undefined && isInlineNode(child) ? child : inline\n\t\t\t\t\t\tinlines.push(accepted)\n\t\t\t\t\t\tif (accepted !== inline) changed = true\n\t\t\t\t\t\toffset += 1\n\t\t\t\t\t}\n\t\t\t\t\theader.push(inlines)\n\t\t\t\t}\n\t\t\t\tconst rows: Array<ReadonlyArray<readonly InlineNode[]>> = []\n\t\t\t\tfor (const row of current.rows) {\n\t\t\t\t\tif (row === undefined) continue\n\t\t\t\t\tconst cells: Array<readonly InlineNode[]> = []\n\t\t\t\t\tfor (const cell of row) {\n\t\t\t\t\t\tif (cell === undefined) continue\n\t\t\t\t\t\tconst inlines: InlineNode[] = []\n\t\t\t\t\t\tfor (const inline of cell) {\n\t\t\t\t\t\t\tif (inline === undefined) continue\n\t\t\t\t\t\t\tconst child = children[offset]\n\t\t\t\t\t\t\tconst accepted = child !== undefined && isInlineNode(child) ? child : inline\n\t\t\t\t\t\t\tinlines.push(accepted)\n\t\t\t\t\t\t\tif (accepted !== inline) changed = true\n\t\t\t\t\t\t\toffset += 1\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcells.push(inlines)\n\t\t\t\t\t}\n\t\t\t\t\trows.push(cells)\n\t\t\t\t}\n\t\t\t\tif (changed) rebuilt = { ...current, header, rows }\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif (rebuilt !== current) derivations.set(rebuilt, current)\n\t\tif (current.element === 'document') {\n\t\t\tconst result = rebuilt.element === 'document' ? rebuilt : current\n\t\t\tconst output = new Set(walkNodes(result))\n\t\t\tconst retained = new Map<MarkdownNode, MarkdownNode | undefined>()\n\t\t\tfor (const [node, source] of derivations) if (output.has(node)) retained.set(node, source)\n\t\t\treturn [result, retained]\n\t\t}\n\t\tconst result = rewrite(rebuilt)\n\t\tlet accepted = rebuilt\n\t\tswitch (current.element) {\n\t\t\tcase 'text':\n\t\t\tcase 'emphasis':\n\t\t\tcase 'codeSpan':\n\t\t\tcase 'break':\n\t\t\tcase 'link':\n\t\t\tcase 'image':\n\t\t\t\tif (isInlineNode(result)) accepted = result\n\t\t\t\tbreak\n\t\t\tcase 'heading':\n\t\t\tcase 'paragraph':\n\t\t\tcase 'list':\n\t\t\tcase 'table':\n\t\t\tcase 'codeBlock':\n\t\t\tcase 'blockquote':\n\t\t\tcase 'thematicBreak':\n\t\t\t\tif (isBlockNode(result)) accepted = result\n\t\t\t\tbreak\n\t\t\tcase 'listItem':\n\t\t\t\tif (result.element === 'listItem') accepted = result\n\t\t\t\tbreak\n\t\t}\n\t\tif (accepted !== rebuilt && accepted !== current) {\n\t\t\tif (derivations.has(accepted) && derivations.get(accepted) !== current)\n\t\t\t\tderivations.set(accepted, undefined)\n\t\t\telse derivations.set(accepted, current)\n\t\t}\n\t\tvalues.push(accepted)\n\t}\n\treturn [document, new Map()]\n}\n\n/**\n * Concatenates the `value` / `code` content of every descendant text / code-span /\n * code-block node under `node`, including image alternative content, in walk order -\n * the plain-text projection of an AST (search indexing, word counts, a text-only\n * preview).\n *\n * @remarks\n * Total: never throws. Descent stops at {@link MAX_DEPTH} (contributes `''` past the\n * cap instead of recursing further).\n *\n * @param node - The AST node to flatten (a full document, or any sub-node)\n * @returns The concatenated text content\n *\n * @example\n * ```ts\n * flattenText({ element: 'paragraph', children: [\n * { element: 'text', value: 'a ' },\n * { element: 'codeSpan', value: 'b' },\n * ] })\n * // 'a b'\n * ```\n */\nexport function flattenText(node: MarkdownNode): string {\n\tconst stack: Array<{ readonly node: MarkdownNode; readonly depth: number }> = [{ node, depth: 0 }]\n\tlet value = ''\n\twhile (stack.length > 0) {\n\t\tconst frame = stack.pop()\n\t\tif (frame === undefined || frame.depth >= MAX_DEPTH) continue\n\t\tconst children: MarkdownNode[] = []\n\t\tswitch (frame.node.element) {\n\t\t\tcase 'text':\n\t\t\tcase 'codeSpan':\n\t\t\t\tvalue += frame.node.value\n\t\t\t\tbreak\n\t\t\tcase 'codeBlock':\n\t\t\t\tvalue += frame.node.code\n\t\t\t\tbreak\n\t\t\tcase 'document':\n\t\t\tcase 'heading':\n\t\t\tcase 'paragraph':\n\t\t\tcase 'blockquote':\n\t\t\tcase 'listItem':\n\t\t\tcase 'emphasis':\n\t\t\tcase 'link':\n\t\t\tcase 'image':\n\t\t\t\tfor (const child of frame.node.children) if (child !== undefined) children.push(child)\n\t\t\t\tbreak\n\t\t\tcase 'list':\n\t\t\t\tfor (const child of frame.node.items) if (child !== undefined) children.push(child)\n\t\t\t\tbreak\n\t\t\tcase 'table':\n\t\t\t\tfor (const cell of frame.node.header)\n\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\tfor (const row of frame.node.rows)\n\t\t\t\t\tif (row !== undefined)\n\t\t\t\t\t\tfor (const cell of row)\n\t\t\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\tbreak\n\t\t}\n\t\tfor (let index = children.length - 1; index >= 0; index -= 1) {\n\t\t\tconst child = children[index]\n\t\t\tif (child !== undefined) stack.push({ node: child, depth: frame.depth + 1 })\n\t\t}\n\t}\n\treturn value\n}\n","import type { MarkdownNode } from './types.js'\nimport { HTML, SAFE_ATTRIBUTES, renderHTML as renderHTMLDocument } from '@orkestrel/html'\nimport { markdownToHTML } from './helpers.js'\n\n// The class-driving half of the outbound direction. `helpers.ts` owns the pure\n// {@link markdownToHTML} projection, which imports no implementation class and stays a\n// leaf; the sanitize-and-serialize pipeline below constructs `@orkestrel/html`'s `HTML`\n// class, so it sits above the leaves and consumes them.\n\n/**\n * Renders a {@link MarkdownNode} to sanitized canonical HTML.\n *\n * @remarks\n * Markdown widens `@orkestrel/html`'s attribute floor by exactly `src`, because image\n * syntax is meaningless without its source. `src` is still a URL attribute, so the\n * floor refuses `javascript:`, `data:`, `vbscript:`, and `file:` values. A stricter\n * consumer can compose {@link markdownToHTML} with `@orkestrel/html`'s `HTML` class\n * directly.\n *\n * @param node - The markdown document or bare node to render\n * @returns Sanitized canonical HTML\n *\n * @example\n * ```ts\n * renderHTML({ element: 'paragraph', children: [{ element: 'text', value: 'a & b' }] })\n * // '<p>a &amp; b</p>'\n * ```\n */\nexport function renderHTML(node: MarkdownNode): string {\n\treturn renderHTMLDocument(\n\t\tnew HTML(markdownToHTML(node)).sanitize({ attributes: [...SAFE_ATTRIBUTES, 'src'] }).document,\n\t)\n}\n","import {\n\tbooleanShape,\n\tintegerShape,\n\tliteralShape,\n\tobjectShape,\n\toptionalShape,\n\tstringShape,\n} from '@orkestrel/contract'\n\n// Shapers are `ContractShape` VALUES, not functions\n// or types - a JSON-Schema blueprint the compilers (factories.ts) turn into a\n// guard / parser / schema / generator in lockstep. Only the NON-recursive\n// parts of the markdown AST (types.ts) can be expressed here: a shape tree has\n// no lazy/self-referential node, so any type whose fields recurse into\n// `BlockNode` / `InlineNode` / `MarkdownNode` (EmphasisNode, LinkNode, ImageNode,\n// HeadingNode, ParagraphNode, ListItemNode, ListNode, TableNode,\n// BlockquoteNode, MarkdownDocument) is skipped here and stays guard-only\n// (validators.ts) through `lazyOf`.\n\n/**\n * Describes the shape of a {@link TextNode} - a plain-text leaf inline run.\n *\n * @example\n * ```ts\n * import { createContract } from '@orkestrel/contract'\n * import { textShape } from '@src/core'\n *\n * const text = createContract(textShape)\n * text.is({ element: 'text', value: 'hi' }) // true\n * ```\n */\nexport const textShape = objectShape({\n\telement: literalShape(['text']),\n\tvalue: stringShape(),\n})\n\n/**\n * Describes the shape of a {@link CodeSpanNode} - an inline code span (`` `code` ``).\n *\n * @example\n * ```ts\n * import { createContract } from '@orkestrel/contract'\n * import { codeSpanShape } from '@src/core'\n *\n * const codeSpan = createContract(codeSpanShape)\n * codeSpan.is({ element: 'codeSpan', value: 'const x = 1' }) // true\n * ```\n */\nexport const codeSpanShape = objectShape({\n\telement: literalShape(['codeSpan']),\n\tvalue: stringShape(),\n})\n\n/**\n * Describes the shape of a {@link LineBreakNode} - a GFM hard line-break leaf.\n *\n * @example\n * ```ts\n * import { createContract } from '@orkestrel/contract'\n * import { lineBreakShape } from '@src/core'\n *\n * const lineBreak = createContract(lineBreakShape)\n * lineBreak.is({ element: 'break' }) // true\n * ```\n */\nexport const lineBreakShape = objectShape({\n\telement: literalShape(['break']),\n})\n\n/**\n * Describes the shape of a {@link CodeBlockNode} - a fenced code block. `lang` is\n * optional (absent when the opening fence carries no info-string).\n *\n * @example\n * ```ts\n * import { createContract } from '@orkestrel/contract'\n * import { codeBlockShape } from '@src/core'\n *\n * const codeBlock = createContract(codeBlockShape)\n * codeBlock.is({ element: 'codeBlock', code: 'x' }) // true\n * codeBlock.is({ element: 'codeBlock', code: 'x', lang: 'ts' }) // true\n * ```\n */\nexport const codeBlockShape = objectShape({\n\telement: literalShape(['codeBlock']),\n\tlang: optionalShape(stringShape()),\n\tcode: stringShape(),\n})\n\n/**\n * Describes the shape of a {@link ThematicBreakNode} - a horizontal rule. Carries no\n * fields beyond its `element` discriminant.\n *\n * @example\n * ```ts\n * import { createContract } from '@orkestrel/contract'\n * import { thematicBreakShape } from '@src/core'\n *\n * const thematicBreak = createContract(thematicBreakShape)\n * thematicBreak.is({ element: 'thematicBreak' }) // true\n * ```\n */\nexport const thematicBreakShape = objectShape({\n\telement: literalShape(['thematicBreak']),\n})\n\n/**\n * Describes the shape of a {@link TableAlign} - the per-column GFM table alignment\n * literal.\n *\n * @example\n * ```ts\n * import { createContract } from '@orkestrel/contract'\n * import { tableAlignShape } from '@src/core'\n *\n * const tableAlign = createContract(tableAlignShape)\n * tableAlign.is('left') // true\n * tableAlign.is('center') // true\n * tableAlign.is('top') // false\n * ```\n */\nexport const tableAlignShape = literalShape(['left', 'right', 'center'])\n\n/**\n * Describes the shape of {@link ListItemMatch} - the parsed parts of a single list-item\n * line the block phase's list detector returns. Fully non-recursive (no\n * nested node fields), so every field shapes directly.\n *\n * @example\n * ```ts\n * import { createContract } from '@orkestrel/contract'\n * import { listItemMatchShape } from '@src/core'\n *\n * const listItemParts = createContract(listItemMatchShape)\n * listItemParts.is({ ordered: false, start: 1, content: 'hi', indent: 0, marker: 2 }) // true\n * ```\n */\nexport const listItemMatchShape = objectShape({\n\tordered: booleanShape(),\n\tstart: integerShape(),\n\tcontent: stringShape(),\n\tindent: integerShape(),\n\tmarker: integerShape(),\n})\n","import type {\n\tBlockNode,\n\tMarkdownDocument,\n\tMarkdownHandlerMap,\n\tMarkdownInterface,\n\tMarkdownNode,\n\tMarkdownRewriteHandler,\n\tMarkdownSpan,\n} from './types.js'\nimport { foldNode, rewriteDocument, walkNodes } from './helpers.js'\nimport { parseProvenance } from './parsers.js'\n\n/**\n * Wraps a typed {@link MarkdownDocument} AST as a stateful, parsed markdown document\n * with the query (`find` / `filter` / `reduce` / iteration), rewrite (`map`), fold, and\n * streaming operations {@link MarkdownInterface} declares.\n *\n * @remarks\n * - **Construction.** Given a `string`, the constructor runs {@link parseProvenance} (the\n * block phase then the inline phase) once, keeping the AST and a COPY of the span map\n * that parse recorded. Given a {@link MarkdownDocument}, the document is adopted AS-IS\n * and is NOT re-validated - gate an untrusted value with `isMarkdownDocument` first.\n * - **Provenance.** {@link span} reads the region of the ORIGINAL constructor string a\n * node was produced from, and it is handle-relative: a string-constructed handle exposes\n * the regions of the nodes it parsed, an adopted document exposes none, and a node from\n * another handle reports `undefined` here whatever that handle reports. Each call\n * returns a fresh value. A node reports the region THIS handle holds for its identity,\n * else the region of the direct input a rewrite named for it, else `undefined`: a text\n * run the parse joined from adjacent scanner output reports the region enclosing its\n * parts, and only a rewrite output that holds no region of its own and was assembled\n * from separate source nodes reports `undefined`.\n * {@link map} carries provenance across the rewrite: an unchanged node keeps its\n * region, a one-source replacement takes the region of the node it replaced, and a\n * rebuilt parent takes its original's.\n * - **Immutable.** {@link map} never mutates the stored AST - it returns a NEW `Markdown`\n * instance; the document root invariant (`element: 'document'`) always holds. An\n * identity rewrite still returns a new handle, over the same document tree.\n * - **Traversal order.** {@link walk} and the `find` / `filter` / `reduce` queries built\n * on it walk the AST depth-first, pre-order, root-inclusive (through {@link walkNodes});\n * `stream` is shallow - only the document's direct block children.\n *\n * @example\n * ```ts\n * import { Markdown, isHeadingNode, renderMarkdown } from '@src/core'\n *\n * const markdown = new Markdown('# Title\\n\\nA **bold** [link](https://x.dev).')\n * const heading = markdown.find(isHeadingNode) // the HeadingNode, or undefined\n * const shouted = markdown.map((node) =>\n * node.element === 'text' ? { element: 'text', value: node.value.toUpperCase() } : node,\n * )\n * renderMarkdown(shouted.document) // '# TITLE\\n\\nA **BOLD** [LINK](https://x.dev).'\n * ```\n */\nexport class Markdown implements MarkdownInterface {\n\treadonly #document: MarkdownDocument\n\treadonly #spans: Map<MarkdownNode, MarkdownSpan>\n\n\tconstructor(input: string | MarkdownDocument) {\n\t\tif (typeof input === 'string') {\n\t\t\tconst [document, spans] = parseProvenance(input)\n\t\t\tthis.#document = document\n\t\t\tthis.#spans = new Map(spans)\n\t\t} else {\n\t\t\tthis.#document = input\n\t\t\tthis.#spans = new Map()\n\t\t}\n\t}\n\n\t/** Holds the stored {@link MarkdownDocument} AST root. */\n\tget document(): MarkdownDocument {\n\t\treturn this.#document\n\t}\n\n\t/**\n\t * Reads the region of the original markdown string a node of this handle's tree was\n\t * produced from.\n\t *\n\t * @param node - The node whose provenance to read\n\t * @returns A fresh {@link MarkdownSpan}, or `undefined` when this handle holds no\n\t * region for the node\n\t *\n\t * @example\n\t * ```ts\n\t * const source = '# Title\\n\\npara'\n\t * const markdown = new Markdown(source)\n\t * const heading = markdown.find(isHeadingNode)\n\t * const span = heading && markdown.span(heading)\n\t * span && source.slice(span.start, span.end) // '# Title'\n\t * ```\n\t */\n\tspan(node: MarkdownNode): MarkdownSpan | undefined {\n\t\tconst span = this.#spans.get(node)\n\t\treturn span === undefined ? undefined : { start: span.start, end: span.end }\n\t}\n\n\t/**\n\t * Returns THE deep traversal - a lazy, depth-first, pre-order, root-inclusive generator\n\t * over every {@link MarkdownNode} in the document. `find` / `filter` / `reduce`\n\t * all iterate this single traversal.\n\t *\n\t * @example\n\t * ```ts\n\t * for (const node of markdown.walk()) {\n\t * // every node, depth-first, pre-order, root-inclusive\n\t * }\n\t *\n\t * // also consumable by for-await - JS accepts a sync iterable in for-await\n\t * for await (const node of markdown.walk()) {\n\t * // same sequence, no separate async iterator needed\n\t * }\n\t * ```\n\t */\n\t*walk(): Generator<MarkdownNode> {\n\t\tyield* walkNodes(this.#document)\n\t}\n\n\t// Finds the first node (depth-first, pre-order) narrowed by a type guard.\n\tfind<T extends MarkdownNode>(guard: (node: MarkdownNode) => node is T): T | undefined\n\t// Finds the first node (depth-first, pre-order) matching a predicate.\n\tfind(predicate: (node: MarkdownNode) => boolean): MarkdownNode | undefined\n\tfind(predicate: (node: MarkdownNode) => boolean): MarkdownNode | undefined {\n\t\tfor (const node of this.walk()) if (predicate(node)) return node\n\t\treturn undefined\n\t}\n\n\t// Collects every node (depth-first, pre-order) narrowed by a type guard.\n\tfilter<T extends MarkdownNode>(guard: (node: MarkdownNode) => node is T): readonly T[]\n\t// Collects every node (depth-first, pre-order) matching a predicate.\n\tfilter(predicate: (node: MarkdownNode) => boolean): readonly MarkdownNode[]\n\tfilter(predicate: (node: MarkdownNode) => boolean): readonly MarkdownNode[] {\n\t\tconst out: MarkdownNode[] = []\n\t\tfor (const node of this.walk()) if (predicate(node)) out.push(node)\n\t\treturn out\n\t}\n\n\t/**\n\t * Rewrites the AST bottom-up (copy-on-write) and returns a new {@link Markdown},\n\t * carrying each output node's provenance across the rewrite. A rewrite that returns\n\t * its node unchanged shares that subtree instead of copying it, so an identity\n\t * rewrite copies no node and still returns a new handle.\n\t *\n\t * @param rewrite - The bottom-up node rewrite\n\t * @returns A new handle over the rewritten document\n\t */\n\tmap(rewrite: MarkdownRewriteHandler): MarkdownInterface {\n\t\tconst [document, derivations] = rewriteDocument(this.#document, rewrite)\n\t\treturn this.#derive(document, derivations)\n\t}\n\n\t/** Folds the AST depth-first, pre-order into an accumulator. */\n\treduce<T>(callback: (accumulator: T, node: MarkdownNode) => T, initial: T): T {\n\t\tlet accumulator = initial\n\t\tfor (const node of this.walk()) accumulator = callback(accumulator, node)\n\t\treturn accumulator\n\t}\n\n\t/** Runs a total catamorphism over the document using a {@link MarkdownHandlerMap} table. */\n\tfold<T>(handlers: MarkdownHandlerMap<T>): T {\n\t\treturn foldNode(this.#document, handlers, 0)\n\t}\n\n\t/**\n\t * Returns a web-standard {@link ReadableStream} over the document's top-level block nodes\n\t * (shallow, source order) - a fresh, pull-based source per call: one block is\n\t * enqueued per `pull`, so a slow reader's backpressure is respected. Cancellable,\n\t * async-iterable wherever the platform supports it (Node, Deno), and pipeable\n\t * through any {@link TransformStream} / {@link WritableStream}.\n\t *\n\t * @example\n\t * ```ts\n\t * // universal - works in every ReadableStream-supporting environment\n\t * const reader = markdown.stream().getReader()\n\t * for (let result = await reader.read(); !result.done; result = await reader.read()) {\n\t * console.log(result.value) // one BlockNode\n\t * }\n\t *\n\t * // Node / Deno / Firefox support async iteration of ReadableStream natively;\n\t * // other environments use the reader loop shown earlier.\n\t * for await (const block of markdown.stream()) {\n\t * console.log(block)\n\t * }\n\t * ```\n\t */\n\tstream(): ReadableStream<BlockNode> {\n\t\tconst blocks = this.#document.children\n\t\tlet index = 0\n\t\treturn new ReadableStream<BlockNode>({\n\t\t\tpull(controller) {\n\t\t\t\tif (index < blocks.length) {\n\t\t\t\t\tconst block = blocks[index]\n\t\t\t\t\tif (block === undefined) {\n\t\t\t\t\t\tcontroller.close()\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tcontroller.enqueue(block)\n\t\t\t\t\tindex += 1\n\t\t\t\t} else {\n\t\t\t\t\tcontroller.close()\n\t\t\t\t}\n\t\t\t},\n\t\t})\n\t}\n\n\t// Creates the operation's new handle and resolves each output against its own prior\n\t// span before its direct input's prior span. The source handle already resolved every\n\t// earlier rewrite, so following the input's separate output entry from this operation\n\t// would conflate two roles held by one identity.\n\t#derive(\n\t\tdocument: MarkdownDocument,\n\t\tderivations: ReadonlyMap<MarkdownNode, MarkdownNode | undefined>,\n\t): Markdown {\n\t\tconst derived = new Markdown(document)\n\t\tfor (const node of walkNodes(document)) {\n\t\t\tconst own = this.#spans.get(node)\n\t\t\tif (own !== undefined) {\n\t\t\t\tderived.#spans.set(node, own)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst source = derivations.get(node)\n\t\t\tif (source === undefined) continue\n\t\t\tconst span = this.#spans.get(source)\n\t\t\tif (span !== undefined) derived.#spans.set(node, span)\n\t\t}\n\t\treturn derived\n\t}\n}\n","import type { ContractInterface } from '@orkestrel/contract'\nimport type {\n\tCodeBlockNode,\n\tCodeSpanNode,\n\tLineBreakNode,\n\tMarkdownDocument,\n\tMarkdownInterface,\n\tTextNode,\n\tThematicBreakNode,\n} from './types.js'\nimport { createContract } from '@orkestrel/contract'\nimport { Markdown } from './Markdown.js'\nimport {\n\tcodeBlockShape,\n\tcodeSpanShape,\n\tlineBreakShape,\n\ttextShape,\n\tthematicBreakShape,\n} from './shapers.js'\n\n/**\n * Creates a stateful markdown handle from a markdown string or an already-parsed\n * {@link MarkdownDocument} - a typed AST plus the query, rewrite, and fold operations\n * {@link MarkdownInterface} exposes.\n *\n * @remarks\n * Given a `string`, runs a block phase (headings / paragraphs / lists / GFM tables /\n * fenced code / blockquotes / thematic breaks) then an inline phase (emphasis /\n * inline code / links / images / hard breaks) to build a render-agnostic\n * {@link MarkdownDocument}. Given a\n * {@link MarkdownDocument}, adopts it AS-IS without re-validation - gate an untrusted\n * value with `isMarkdownDocument` first. Pure + total parse (malformed markdown\n * degrades to text, never throws) and zero-dependency - a hand-written scanner, no\n * regex-only structural parse, linear-time (no ReDoS).\n *\n * @param input - A markdown string to parse, or an already-parsed {@link MarkdownDocument}\n * @returns A working {@link MarkdownInterface}\n *\n * @example\n * ```ts\n * import { createMarkdown } from '@src/core'\n *\n * const markdown = createMarkdown('# Hi\\n\\nRead the [guide](./guide.md).')\n * markdown.document.children[0] // { element: 'heading', ... }\n * ```\n */\nexport function createMarkdown(input: string | MarkdownDocument): MarkdownInterface {\n\treturn new Markdown(input)\n}\n\n/**\n * Compiles the {@link textShape} into a {@link ContractInterface} for\n * {@link TextNode} - a guard, coercing parser, JSON Schema, and seeded\n * generator from one shape declaration.\n *\n * @returns A `TextNode` contract bundling `schema` / `is` / `parse` / `generate`\n *\n * @example\n * ```ts\n * import { createTextContract } from '@src/core'\n *\n * const text = createTextContract()\n * text.is({ element: 'text', value: 'hi' }) // true\n * ```\n */\nexport function createTextContract(): ContractInterface<TextNode> {\n\treturn createContract(textShape)\n}\n\n/**\n * Compiles the {@link codeSpanShape} into a {@link ContractInterface} for\n * {@link CodeSpanNode} - a guard, coercing parser, JSON Schema, and seeded\n * generator from one shape declaration.\n *\n * @returns A `CodeSpanNode` contract bundling `schema` / `is` / `parse` / `generate`\n *\n * @example\n * ```ts\n * import { createCodeSpanContract } from '@src/core'\n *\n * const codeSpan = createCodeSpanContract()\n * codeSpan.is({ element: 'codeSpan', value: 'const x = 1' }) // true\n * ```\n */\nexport function createCodeSpanContract(): ContractInterface<CodeSpanNode> {\n\treturn createContract(codeSpanShape)\n}\n\n/**\n * Compiles the {@link lineBreakShape} into a {@link ContractInterface} for\n * {@link LineBreakNode}.\n *\n * @returns A `LineBreakNode` contract bundling `schema` / `is` / `parse` / `generate`\n *\n * @example\n * ```ts\n * import { createLineBreakContract } from '@src/core'\n *\n * createLineBreakContract().is({ element: 'break' }) // true\n * ```\n */\nexport function createLineBreakContract(): ContractInterface<LineBreakNode> {\n\treturn createContract(lineBreakShape)\n}\n\n/**\n * Compiles the {@link codeBlockShape} into a {@link ContractInterface} for\n * {@link CodeBlockNode} - a guard, coercing parser, JSON Schema, and seeded\n * generator from one shape declaration.\n *\n * @returns A `CodeBlockNode` contract bundling `schema` / `is` / `parse` / `generate`\n *\n * @example\n * ```ts\n * import { createCodeBlockContract } from '@src/core'\n *\n * const codeBlock = createCodeBlockContract()\n * codeBlock.is({ element: 'codeBlock', code: 'x' }) // true\n * ```\n */\nexport function createCodeBlockContract(): ContractInterface<CodeBlockNode> {\n\treturn createContract(codeBlockShape)\n}\n\n/**\n * Compiles the {@link thematicBreakShape} into a {@link ContractInterface} for\n * {@link ThematicBreakNode} - a guard, coercing parser, JSON Schema, and\n * seeded generator from one shape declaration.\n *\n * @returns A `ThematicBreakNode` contract bundling `schema` / `is` / `parse` / `generate`\n *\n * @example\n * ```ts\n * import { createThematicBreakContract } from '@src/core'\n *\n * const thematicBreak = createThematicBreakContract()\n * thematicBreak.is({ element: 'thematicBreak' }) // true\n * ```\n */\nexport function createThematicBreakContract(): ContractInterface<ThematicBreakNode> {\n\treturn createContract(thematicBreakShape)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../../../src/core/constants.ts","../../../src/core/validators.ts","../../../src/core/parsers.ts","../../../src/core/helpers.ts","../../../src/core/compilers.ts","../../../src/core/shapers.ts","../../../src/core/Markdown.ts","../../../src/core/factories.ts"],"sourcesContent":["import type { MarkdownProjection } from './types.js'\n\n/**\n * Caps the recursion depth the parse pipeline (`parseDocument` and its\n * `parsers.ts` helpers), the `helpers.ts` traversal / projection functions\n * (`markdownToHTML`, `renderMarkdown`, `walkNodes`, `foldNode`, `rewriteDocument`),\n * and the `compilers.ts` renderer (`renderHTML`) honor before degrading, at 64. It bounds blockquote nesting, inline\n * nesting (emphasis / links), and traversal / projection recursion so pathological\n * or hostile input cannot exhaust the call stack. {@link htmlToMarkdown} is the\n * inherited exception: its fold and depth cap belong to `@orkestrel/html`.\n */\nexport const MAX_DEPTH = 64\n\n/**\n * Holds the frozen empty HTML-to-markdown projection from which projection factories\n * default every absent field.\n *\n * @example\n * ```ts\n * EMPTY_PROJECTION.blocks // []\n * Object.isFrozen(EMPTY_PROJECTION) // true\n * ```\n */\nexport const EMPTY_PROJECTION: MarkdownProjection = Object.freeze({\n\tblocks: Object.freeze([]),\n\tinlines: Object.freeze([]),\n\ttext: '',\n\tcells: Object.freeze([]),\n\trows: Object.freeze([]),\n})\n","import type { Guard } from '@orkestrel/contract'\nimport type {\n\tBlockNode,\n\tBlockquoteNode,\n\tCodeBlockNode,\n\tCodeSpanNode,\n\tEmphasisNode,\n\tHeadingNode,\n\tImageNode,\n\tInlineNode,\n\tLineBreakNode,\n\tLinkNode,\n\tListNode,\n\tMarkdownDocument,\n\tMarkdownNode,\n\tParagraphNode,\n\tTableNode,\n\tTextNode,\n\tThematicBreakNode,\n} from './types.js'\nimport {\n\tarrayOf,\n\tisBoolean,\n\tisNumber,\n\tisString,\n\tliteralOf,\n\tlazyOf,\n\tnullableOf,\n\trecordOf,\n\tunionOf,\n} from '@orkestrel/contract'\n\n// Guards are total. This file owns the type narrowers alone: node guards that\n// narrow a MarkdownNode to one parsed block / inline variant by its element tag,\n// and the from-unknown guards that validate an arbitrary value against the full\n// AST shape. The line / character structural predicates the parser tests raw\n// strings with narrow nothing, so they are pure leaves and live in helpers.ts.\n\n// === Block guards\n\n/**\n * Determines whether a node is a heading block.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link HeadingNode}; false otherwise\n *\n * @example\n * ```ts\n * isHeadingNode({ element: 'heading', level: 1, children: [] }) // true\n * ```\n */\nexport function isHeadingNode(node: MarkdownNode): node is HeadingNode {\n\treturn node.element === 'heading'\n}\n\n/**\n * Determines whether a node is a paragraph block.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link ParagraphNode}; false otherwise\n *\n * @example\n * ```ts\n * isParagraphNode({ element: 'paragraph', children: [] }) // true\n * ```\n */\nexport function isParagraphNode(node: MarkdownNode): node is ParagraphNode {\n\treturn node.element === 'paragraph'\n}\n\n/**\n * Determines whether a node is a list block.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link ListNode}; false otherwise\n *\n * @example\n * ```ts\n * isListNode({ element: 'list', ordered: false, start: 1, items: [] }) // true\n * ```\n */\nexport function isListNode(node: MarkdownNode): node is ListNode {\n\treturn node.element === 'list'\n}\n\n/**\n * Determines whether a node is a GFM table block.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link TableNode}; false otherwise\n *\n * @example\n * ```ts\n * isTableNode({ element: 'table', header: [], rows: [], align: [] }) // true\n * ```\n */\nexport function isTableNode(node: MarkdownNode): node is TableNode {\n\treturn node.element === 'table'\n}\n\n/**\n * Determines whether a node is a fenced code block.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link CodeBlockNode}; false otherwise\n *\n * @example\n * ```ts\n * isCodeBlockNode({ element: 'codeBlock', code: 'x' }) // true\n * ```\n */\nexport function isCodeBlockNode(node: MarkdownNode): node is CodeBlockNode {\n\treturn node.element === 'codeBlock'\n}\n\n/**\n * Determines whether a node is a blockquote block.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link BlockquoteNode}; false otherwise\n *\n * @example\n * ```ts\n * isBlockquoteNode({ element: 'blockquote', children: [] }) // true\n * ```\n */\nexport function isBlockquoteNode(node: MarkdownNode): node is BlockquoteNode {\n\treturn node.element === 'blockquote'\n}\n\n/**\n * Determines whether a node is a thematic break (horizontal rule) block.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link ThematicBreakNode}; false otherwise\n *\n * @example\n * ```ts\n * isThematicBreakNode({ element: 'thematicBreak' }) // true\n * ```\n */\nexport function isThematicBreakNode(node: MarkdownNode): node is ThematicBreakNode {\n\treturn node.element === 'thematicBreak'\n}\n\n// === Inline guards\n\n/**\n * Determines whether a node is a plain text run.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link TextNode}; false otherwise\n *\n * @example\n * ```ts\n * isTextNode({ element: 'text', value: 'hi' }) // true\n * ```\n */\nexport function isTextNode(node: MarkdownNode): node is TextNode {\n\treturn node.element === 'text'\n}\n\n/**\n * Determines whether a node is an emphasis run (`*em*` / `**strong**`).\n *\n * @param node - The AST node to test\n * @returns True if the node is an {@link EmphasisNode}; false otherwise\n *\n * @example\n * ```ts\n * isEmphasisNode({ element: 'emphasis', strong: false, children: [] }) // true\n * ```\n */\nexport function isEmphasisNode(node: MarkdownNode): node is EmphasisNode {\n\treturn node.element === 'emphasis'\n}\n\n/**\n * Determines whether a node is an inline code span.\n *\n * @remarks\n * Narrows to {@link CodeSpanNode} — the node whose `element` discriminant is\n * `'codeSpan'`.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link CodeSpanNode}; false otherwise\n *\n * @example\n * ```ts\n * isCodeSpanNode({ element: 'codeSpan', value: 'x' }) // true\n * ```\n */\nexport function isCodeSpanNode(node: MarkdownNode): node is CodeSpanNode {\n\treturn node.element === 'codeSpan'\n}\n\n/**\n * Determines whether a node is a GFM hard line break.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link LineBreakNode}; false otherwise\n *\n * @example\n * ```ts\n * isLineBreakNode({ element: 'break' }) // true\n * ```\n */\nexport function isLineBreakNode(node: MarkdownNode): node is LineBreakNode {\n\treturn node.element === 'break'\n}\n\n/**\n * Determines whether a node is a link.\n *\n * @param node - The AST node to test\n * @returns True if the node is a {@link LinkNode}; false otherwise\n *\n * @example\n * ```ts\n * isLinkNode({ element: 'link', href: 'https://example.dev', children: [] }) // true\n * ```\n */\nexport function isLinkNode(node: MarkdownNode): node is LinkNode {\n\treturn node.element === 'link'\n}\n\n/**\n * Determines whether a node is an image.\n *\n * @param node - The AST node to test\n * @returns True if the node is an {@link ImageNode}; false otherwise\n *\n * @example\n * ```ts\n * isImageNode({ element: 'image', src: 'x.png', children: [] }) // true\n * ```\n */\nexport function isImageNode(node: MarkdownNode): node is ImageNode {\n\treturn node.element === 'image'\n}\n\n// === From-unknown AST guards\n//\n// The node guards above narrow an already-parsed MarkdownNode by its `element`\n// tag. The guards below instead validate an arbitrary `unknown` value (untrusted\n// input — a deserialized AST, a value crossing a process/RPC boundary) against\n// the full node shape, field by field, composed from @orkestrel/contract\n// combinators. Each guard is its own hoisted composed value (compiled once at\n// module init, not per call); inline<->block recursion (emphasis/link/image children,\n// list items, blockquote children) resolves through `lazyOf`, closing over the\n// exported guard names themselves — legal because `lazyOf`'s thunk resolves per\n// call, strictly after module init has assigned every export. @orkestrel/contract\n// guarantees guard totality: `lazyOf`, `unionOf`, `recordOf`, and\n// every built-in guard are throw-contained, so a hostile getter, a structural\n// cycle, or pathologically deep input returns `false` rather than throwing —\n// no additional `attempt` wrapping is needed here.\n\n/**\n * Determines whether an arbitrary value is a valid {@link InlineNode} — a text\n * run, emphasis, code span, hard break, link, or image, recursively validated.\n *\n * @remarks\n * Total: never throws, even on cyclic or pathologically deep input — every\n * combinator involved (`unionOf`, `recordOf`, `arrayOf`, `lazyOf`) is\n * throw-contained per the `@orkestrel/contract` guard contract.\n *\n * @param value - The value to test\n * @returns True if `value` is a well-formed {@link InlineNode}; false otherwise\n *\n * @example\n * ```ts\n * import { isInlineNode } from '@orkestrel/markdown'\n *\n * isInlineNode({ element: 'text', value: 'hi' }) // true\n * isInlineNode({ element: 'text' }) // false - missing `value`\n * ```\n */\nexport const isInlineNode: Guard<InlineNode> = unionOf(\n\trecordOf({ element: literalOf('text'), value: isString }),\n\trecordOf({\n\t\telement: literalOf('emphasis'),\n\t\tstrong: isBoolean,\n\t\tchildren: arrayOf(lazyOf(() => isInlineNode)),\n\t}),\n\trecordOf({ element: literalOf('codeSpan'), value: isString }),\n\trecordOf({ element: literalOf('break') }),\n\trecordOf({\n\t\telement: literalOf('link'),\n\t\thref: isString,\n\t\tchildren: arrayOf(lazyOf(() => isInlineNode)),\n\t}),\n\trecordOf({\n\t\telement: literalOf('image'),\n\t\tsrc: isString,\n\t\tchildren: arrayOf(lazyOf(() => isInlineNode)),\n\t}),\n)\n\n/**\n * Determines whether an arbitrary value is a valid {@link BlockNode} — a\n * heading, paragraph, list, table, code block, blockquote, or thematic break,\n * recursively validated.\n *\n * @remarks\n * Total: never throws, even on cyclic or pathologically deep input — every\n * combinator involved (`unionOf`, `recordOf`, `arrayOf`, `lazyOf`) is\n * throw-contained per the `@orkestrel/contract` guard contract.\n * A list item's shape is inlined here (and in {@link isMarkdownNode}) rather\n * than named separately — it is used at exactly these two sites.\n *\n * @param value - The value to test\n * @returns True if `value` is a well-formed {@link BlockNode}; false otherwise\n *\n * @example\n * ```ts\n * import { isBlockNode } from '@orkestrel/markdown'\n *\n * isBlockNode({ element: 'thematicBreak' }) // true\n * isBlockNode({ element: 'heading' }) // false - missing `level` / `children`\n * ```\n */\nexport const isBlockNode: Guard<BlockNode> = unionOf(\n\trecordOf({ element: literalOf('heading'), level: isNumber, children: arrayOf(isInlineNode) }),\n\trecordOf({ element: literalOf('paragraph'), children: arrayOf(isInlineNode) }),\n\trecordOf({\n\t\telement: literalOf('list'),\n\t\tordered: isBoolean,\n\t\tstart: isNumber,\n\t\titems: arrayOf(\n\t\t\trecordOf({ element: literalOf('listItem'), children: arrayOf(lazyOf(() => isBlockNode)) }),\n\t\t),\n\t}),\n\trecordOf({\n\t\telement: literalOf('table'),\n\t\theader: arrayOf(arrayOf(isInlineNode)),\n\t\trows: arrayOf(arrayOf(arrayOf(isInlineNode))),\n\t\talign: arrayOf(nullableOf(literalOf('left', 'right', 'center'))),\n\t}),\n\trecordOf({ element: literalOf('codeBlock'), lang: isString, code: isString }, ['lang']),\n\trecordOf({ element: literalOf('blockquote'), children: arrayOf(lazyOf(() => isBlockNode)) }),\n\trecordOf({ element: literalOf('thematicBreak') }),\n)\n\n/**\n * Determines whether an arbitrary value is a valid {@link MarkdownNode} — the\n * {@link MarkdownDocument} root, a {@link BlockNode}, a {@link ListItemNode}, or\n * an {@link InlineNode}, recursively validated.\n *\n * @remarks\n * Total: never throws, even on cyclic or pathologically deep input — every\n * combinator involved (`unionOf`, `recordOf`, `arrayOf`, `lazyOf`) is\n * throw-contained per the `@orkestrel/contract` guard contract.\n * A list item's shape is inlined here (and in {@link isBlockNode}) rather than\n * named separately — it is used at exactly these two sites.\n *\n * @param value - The value to test\n * @returns True if `value` is a well-formed {@link MarkdownNode}; false otherwise\n *\n * @example\n * ```ts\n * import { isMarkdownNode } from '@orkestrel/markdown'\n *\n * isMarkdownNode({ element: 'text', value: 'hi' }) // true\n * isMarkdownNode({ element: 'bogus' }) // false\n * ```\n */\nexport const isMarkdownNode: Guard<MarkdownNode> = unionOf(\n\tlazyOf(() => isMarkdownDocument),\n\tlazyOf(() => isBlockNode),\n\trecordOf({ element: literalOf('listItem'), children: arrayOf(lazyOf(() => isBlockNode)) }),\n\tlazyOf(() => isInlineNode),\n)\n\n/**\n * Determines whether an arbitrary value is a valid {@link MarkdownDocument} —\n * the parsed-AST root {@link parseDocument} returns, recursively\n * validated.\n *\n * @remarks\n * Total: never throws, even on cyclic or pathologically deep input — every\n * combinator involved (`recordOf`, `arrayOf`) is throw-contained per the\n * `@orkestrel/contract` guard contract.\n *\n * @param value - The value to test\n * @returns True if `value` is a well-formed {@link MarkdownDocument}; false otherwise\n *\n * @example\n * ```ts\n * import { isMarkdownDocument } from '@orkestrel/markdown'\n *\n * isMarkdownDocument({ element: 'document', children: [] }) // true\n * isMarkdownDocument({ element: 'document' }) // false - missing `children`\n * ```\n */\nexport const isMarkdownDocument: Guard<MarkdownDocument> = recordOf({\n\telement: literalOf('document'),\n\tchildren: arrayOf(isBlockNode),\n})\n","import type {\n\tBlockNode,\n\tInlineNode,\n\tMarkdownDocument,\n\tMarkdownNode,\n\tMarkdownParseResult,\n\tMarkdownSource,\n\tMarkdownSpan,\n} from './types.js'\nimport {\n\tcoalesceText,\n\tcollectList,\n\tcollectTable,\n\textractFence,\n\textractHeading,\n\textractListItem,\n\tisBlankLine,\n\tisFenceClose,\n\tisQuote,\n\tisTableStart,\n\tisThematicBreak,\n\tjoinSources,\n\tnormalizeParagraphLine,\n\tprojectSpan,\n\tscanInline,\n\tscanInlineSource,\n\tsliceSource,\n\tsplitLines,\n\tstartsBlock,\n\tstripQuote,\n} from './helpers.js'\nimport { MAX_DEPTH } from './constants.js'\nimport { isNonEmptyArray } from '@orkestrel/contract'\n\n/**\n * Parses a run of markdown lines into a block AST, recursing into nested\n * blockquotes, list items, and depth-capped degrade paragraphs.\n *\n * @param lines - The markdown lines to parse.\n * @param depth - The current recursion depth (blockquotes/lists increment it).\n * @param spans - The optional operation-owned node span recorder.\n * @param end - The original-source end of this line run, including a removed terminator.\n * @returns The parsed block nodes.\n *\n * @example\n * ```ts\n * parseBlocks(splitLines('# Hi'), 0) // [{ element: 'heading', level: 1, children: [...] }]\n * ```\n */\nexport function parseBlocks(\n\tlines: readonly MarkdownSource[],\n\tdepth: number,\n\tspans = new Map<MarkdownNode, MarkdownSpan>(),\n\tend?: number,\n): readonly BlockNode[] {\n\tconst text = lines.map((line) => line.text)\n\tif (depth >= MAX_DEPTH) {\n\t\tif (lines.length === 0) return []\n\t\tconst source = joinSources(lines, '\\n')\n\t\tconst inline: InlineNode = { element: 'text', value: source.text }\n\t\tconst paragraph: BlockNode = { element: 'paragraph', children: [inline] }\n\t\tconst span = projectSpan(source, 0, source.text.length)\n\t\tif (span !== undefined) {\n\t\t\tspans.set(inline, span)\n\t\t\tspans.set(paragraph, span)\n\t\t}\n\t\treturn [paragraph]\n\t}\n\tconst blocks: BlockNode[] = []\n\tlet index = 0\n\twhile (index < lines.length) {\n\t\tconst line = text[index] ?? ''\n\t\tif (isBlankLine(line)) {\n\t\t\tindex += 1\n\t\t\tcontinue\n\t\t}\n\t\tconst fence = extractFence(line)\n\t\tif (fence) {\n\t\t\tconst start = index\n\t\t\tconst body: MarkdownSource[] = []\n\t\t\tlet closed = false\n\t\t\tindex += 1\n\t\t\twhile (index < lines.length && !isFenceClose(text[index] ?? '', fence.marker)) {\n\t\t\t\tconst bodyLine = lines[index]\n\t\t\t\tif (bodyLine !== undefined) body.push(bodyLine)\n\t\t\t\tindex += 1\n\t\t\t}\n\t\t\tif (index < lines.length) {\n\t\t\t\tclosed = true\n\t\t\t\tindex += 1\n\t\t\t}\n\t\t\tconst node: BlockNode = {\n\t\t\t\telement: 'codeBlock',\n\t\t\t\t...(fence.lang === undefined ? {} : { lang: fence.lang }),\n\t\t\t\tcode: joinSources(body, '\\n').text,\n\t\t\t}\n\t\t\tconst source = joinSources(lines.slice(start, index), '\\n')\n\t\t\tconst span = projectSpan(source, 0, source.text.length)\n\t\t\tif (span !== undefined)\n\t\t\t\tspans.set(node, !closed && end !== undefined ? { start: span.start, end } : span)\n\t\t\tblocks.push(node)\n\t\t\tcontinue\n\t\t}\n\t\tif (isThematicBreak(line)) {\n\t\t\tconst node: BlockNode = { element: 'thematicBreak' }\n\t\t\tconst source = lines[index]\n\t\t\tconst span = source === undefined ? undefined : projectSpan(source, 0, source.text.length)\n\t\t\tif (span !== undefined) spans.set(node, span)\n\t\t\tblocks.push(node)\n\t\t\tindex += 1\n\t\t\tcontinue\n\t\t}\n\t\tconst heading = extractHeading(line)\n\t\tif (heading) {\n\t\t\tconst source = lines[index]\n\t\t\tconst content =\n\t\t\t\tsource === undefined\n\t\t\t\t\t? { text: heading.text, segments: [] }\n\t\t\t\t\t: sliceSource(source, heading.offset, heading.offset + heading.text.length)\n\t\t\tconst node: BlockNode = {\n\t\t\t\telement: 'heading',\n\t\t\t\tlevel: heading.level,\n\t\t\t\tchildren: coalesceText(scanInlineSource(content, 0, content.text.length, spans), spans),\n\t\t\t}\n\t\t\tconst span = source === undefined ? undefined : projectSpan(source, 0, source.text.length)\n\t\t\tif (span !== undefined) spans.set(node, span)\n\t\t\tblocks.push(node)\n\t\t\tindex += 1\n\t\t\tcontinue\n\t\t}\n\t\tif (isQuote(line)) {\n\t\t\tconst start = index\n\t\t\tconst quoted: MarkdownSource[] = []\n\t\t\twhile (index < lines.length && isQuote(text[index] ?? '')) {\n\t\t\t\tconst quotedLine = lines[index]\n\t\t\t\tif (quotedLine === undefined) break\n\t\t\t\tquoted.push(stripQuote(quotedLine))\n\t\t\t\tindex += 1\n\t\t\t}\n\t\t\tconst source = joinSources(lines.slice(start, index), '\\n')\n\t\t\tconst span = projectSpan(source, 0, source.text.length)\n\t\t\tconst node: BlockNode = {\n\t\t\t\telement: 'blockquote',\n\t\t\t\tchildren: parseBlocks(\n\t\t\t\t\tquoted,\n\t\t\t\t\tdepth + 1,\n\t\t\t\t\tspans,\n\t\t\t\t\tindex === lines.length && end !== undefined ? end : span?.end,\n\t\t\t\t),\n\t\t\t}\n\t\t\tif (span !== undefined) spans.set(node, span)\n\t\t\tblocks.push(node)\n\t\t\tcontinue\n\t\t}\n\t\tif (isTableStart(line, text[index + 1])) {\n\t\t\tconst table = collectTable(lines, index, spans)\n\t\t\tblocks.push(table.node)\n\t\t\tindex = table.next\n\t\t\tcontinue\n\t\t}\n\t\tif (extractListItem(line)) {\n\t\t\tconst list = collectList(lines, index, depth, spans, end)\n\t\t\tblocks.push(list.node)\n\t\t\tindex = list.next\n\t\t\tcontinue\n\t\t}\n\t\tconst start = index\n\t\tconst paragraph: MarkdownSource[] = []\n\t\twhile (\n\t\t\tindex < lines.length &&\n\t\t\t!isBlankLine(text[index] ?? '') &&\n\t\t\t!(isNonEmptyArray(paragraph) && startsBlock(text, index))\n\t\t) {\n\t\t\tconst paragraphLine = lines[index]\n\t\t\tif (paragraphLine !== undefined) paragraph.push(paragraphLine)\n\t\t\tindex += 1\n\t\t}\n\t\tconst source = joinSources(\n\t\t\tparagraph.map((paragraphLine, position) =>\n\t\t\t\tnormalizeParagraphLine(paragraphLine, position < paragraph.length - 1),\n\t\t\t),\n\t\t\t'\\n',\n\t\t)\n\t\tconst node: BlockNode = {\n\t\t\telement: 'paragraph',\n\t\t\tchildren: coalesceText(scanInlineSource(source, 0, source.text.length, spans), spans),\n\t\t}\n\t\tconst region = joinSources(lines.slice(start, index), '\\n')\n\t\tconst span = projectSpan(region, 0, region.text.length)\n\t\tif (span !== undefined) spans.set(node, span)\n\t\tblocks.push(node)\n\t}\n\treturn blocks\n}\n\n/**\n * Parses a markdown string into a typed {@link MarkdownDocument} AST through the\n * block phase — the document half of what {@link parseProvenance} returns. Malformed\n * markdown degrades to literal text, so the parse never throws.\n *\n * @param markdown - The markdown source to parse.\n * @returns The parsed document.\n *\n * @example\n * ```ts\n * parseDocument('# Hi') // { element: 'document', children: [{ element: 'heading', ... }] }\n * ```\n */\nexport function parseDocument(markdown: string): MarkdownDocument {\n\tconst [document] = parseProvenance(markdown)\n\treturn document\n}\n\n/**\n * Parses a markdown string into a document and its original-source spans. Malformed\n * markdown degrades to literal text, so the parse never throws.\n *\n * @param markdown - The markdown source to parse.\n * @returns The parsed document and its node-identity span map.\n *\n * @example\n * ```ts\n * const [document, spans] = parseProvenance('# Hi')\n * spans.get(document) // { start: 0, end: 4 }\n * ```\n */\nexport function parseProvenance(markdown: string): MarkdownParseResult {\n\tconst spans = new Map<MarkdownNode, MarkdownSpan>()\n\tconst document: MarkdownDocument = {\n\t\telement: 'document',\n\t\tchildren: parseBlocks(splitLines(markdown), 0, spans, markdown.length),\n\t}\n\tspans.set(document, { start: 0, end: markdown.length })\n\treturn [document, spans]\n}\n\n/**\n * Parses inline markdown text (emphasis, code spans, links, images, and hard\n * breaks) into inline AST nodes, coalescing adjacent text runs and reading no block\n * structure. Malformed markdown degrades to literal text, so the parse never throws.\n *\n * @param text - The inline markdown text to parse.\n * @returns The parsed inline nodes.\n *\n * @example\n * ```ts\n * parseInline('a *b*') // [{ element: 'text', value: 'a ' }, { element: 'emphasis', ... }]\n * ```\n */\nexport function parseInline(text: string): readonly InlineNode[] {\n\treturn coalesceText(scanInline(text, 0, text.length))\n}\n","import type {\n\tCommentNode,\n\tDoctypeNode,\n\tElementNode,\n\tHTMLDocument,\n\tHTMLNode,\n\tTextNode as HTMLTextNode,\n} from '@orkestrel/html'\nimport type {\n\tBlockNode,\n\tCodeSpanMatch,\n\tEmphasisBounds,\n\tEmphasisScan,\n\tFenceMatch,\n\tHeadingMatch,\n\tInlineNode,\n\tLinkBounds,\n\tLinkScan,\n\tListCollection,\n\tListItemNode,\n\tListItemMatch,\n\tListNode,\n\tMarkdownCell,\n\tMarkdownDerivation,\n\tMarkdownDocument,\n\tMarkdownHandlerMap,\n\tMarkdownNode,\n\tMarkdownProjection,\n\tMarkdownRewriteHandler,\n\tMarkdownSegment,\n\tMarkdownSource,\n\tMarkdownSpan,\n\tTableAlign,\n\tTableCollection,\n\tTableNode,\n} from './types.js'\nimport { EMPTY_PROJECTION, MAX_DEPTH } from './constants.js'\nimport { isBlockNode, isInlineNode } from './validators.js'\nimport { parseBlocks } from './parsers.js'\nimport { isEmptyString, isNonEmptyArray, isNonEmptyString, parseInteger } from '@orkestrel/contract'\nimport {\n\tSAFE_URL_SCHEMES,\n\tTABLE_ALIGNMENTS,\n\tUNSAFE_ELEMENTS,\n\tattributeOf,\n\tcollapseSpace,\n\tfoldNode as foldHTMLNode,\n\trenderText,\n\tsanitizeURL,\n} from '@orkestrel/html'\n\n// Markdown parsing + rendering leaves (pure and total)\n//\n// The pure leaf primitives {@link parseDocument} composes: the line / character\n// structural predicates (blank lines, quotes, fence closers, thematic breaks, table\n// starts, escapable and whitespace characters), the line / block scanners (headings,\n// fences, list items, table rows), the `collect*` construct scanners (GFM tables and\n// lists), the inline `scan*` engine (emphasis / links / code with backslash escapes),\n// and the HTML AST projection the renderer composes with @orkestrel/html. A predicate\n// over a raw `string` is a leaf rather than a `Guard<T>`, so it lives here and not in\n// validators.ts. Every function is pure, total, and referentially transparent —\n// malformed input degrades to text, never throws — so each is unit-tested in isolation.\n// The `parse*` entry points that thread these together (the block / inline phase\n// entries) live in parsers.ts: a helper is a functional-core leaf, a parser is the\n// phase it names. A construct scanner calls back into its phase entry, so helpers.ts\n// and parsers.ts are mutually recursive by design. Inline scanning is index-based (no\n// backtracking regex) so it is linear-time — no ReDoS on adversarial input.\n//\n// This file imports no implementation class: the class-driving renderer that composes\n// {@link markdownToHTML} with `@orkestrel/html`'s sanitizer lives in compilers.ts.\n\n// Text + line utilities\n\n/**\n * Splits a markdown document into offset-bearing lines while normalizing CRLF and\n * bare CR terminators at the line boundary. A single trailing terminator does not\n * yield a final empty line.\n *\n * @param markdown - The raw markdown source\n * @returns The document's lines with their original-string coordinates\n *\n * @example\n * ```ts\n * splitLines('a\\r\\nb') // [{ text: 'a', segments: [{ offset: 0, start: 0, end: 1 }] }, ...]\n * ```\n */\nexport function splitLines(markdown: string): readonly MarkdownSource[] {\n\tconst lines: MarkdownSource[] = []\n\tlet start = 0\n\tlet index = 0\n\twhile (index < markdown.length) {\n\t\tconst character = markdown[index]\n\t\tif (character !== '\\r' && character !== '\\n') {\n\t\t\tindex += 1\n\t\t\tcontinue\n\t\t}\n\t\tlines.push({\n\t\t\ttext: markdown.slice(start, index),\n\t\t\tsegments: [{ offset: 0, start, end: index }],\n\t\t})\n\t\tindex += character === '\\r' && markdown[index + 1] === '\\n' ? 2 : 1\n\t\tstart = index\n\t}\n\tlines.push({\n\t\ttext: markdown.slice(start),\n\t\tsegments: [{ offset: 0, start, end: markdown.length }],\n\t})\n\tif (lines.length > 1 && lines[lines.length - 1]?.text === '') lines.pop()\n\treturn lines\n}\n\n/**\n * Slices derived markdown text and narrows each intersecting source segment to the\n * same text-relative range.\n *\n * @param source - The offset-bearing source to slice\n * @param from - The inclusive text offset\n * @param to - The exclusive text offset\n * @returns The sliced text and its narrowed original-string segments\n *\n * @example\n * ```ts\n * sliceSource({ text: 'abc', segments: [{ offset: 0, start: 4, end: 7 }] }, 1, 3)\n * // { text: 'bc', segments: [{ offset: 0, start: 5, end: 7 }] }\n * ```\n */\nexport function sliceSource(source: MarkdownSource, from: number, to: number): MarkdownSource {\n\tconst start = Math.max(0, Math.min(from, source.text.length))\n\tconst end = Math.max(start, Math.min(to, source.text.length))\n\tconst segments: MarkdownSegment[] = []\n\tfor (let index = 0; index < source.segments.length; index += 1) {\n\t\tconst segment = source.segments[index]\n\t\tif (segment === undefined) continue\n\t\tconst next = source.segments[index + 1]\n\t\tconst limit = Math.min(\n\t\t\tsegment.offset + (segment.end - segment.start),\n\t\t\tnext === undefined ? source.text.length : next.offset,\n\t\t)\n\t\tconst overlapStart = Math.max(start, segment.offset)\n\t\tconst overlapEnd = Math.min(end, limit)\n\t\tconst empty = segment.offset === limit && overlapStart === segment.offset\n\t\tif (overlapStart >= overlapEnd && !empty) continue\n\t\tconst originalStart =\n\t\t\toverlapStart === limit\n\t\t\t\t? segment.end\n\t\t\t\t: Math.min(segment.end, segment.start + overlapStart - segment.offset)\n\t\tconst originalEnd =\n\t\t\toverlapEnd === limit\n\t\t\t\t? segment.end\n\t\t\t\t: Math.min(segment.end, segment.start + overlapEnd - segment.offset)\n\t\tsegments.push({\n\t\t\toffset: overlapStart - start,\n\t\t\tstart: originalStart,\n\t\t\tend: originalEnd,\n\t\t})\n\t}\n\treturn { text: source.text.slice(start, end), segments }\n}\n\n/**\n * Joins offset-bearing markdown sources while mapping a separator to the original\n * region between adjacent mapped sources.\n *\n * @param sources - The sources to join\n * @param separator - The derived text inserted between sources\n * @returns The joined text and every source-backed segment\n *\n * @example\n * ```ts\n * joinSources(splitLines('a\\nb'), '\\n')\n * // { text: 'a\\nb', segments: [...] }\n * ```\n */\nexport function joinSources(sources: readonly MarkdownSource[], separator: string): MarkdownSource {\n\tlet text = ''\n\tconst segments: MarkdownSegment[] = []\n\tfor (let index = 0; index < sources.length; index += 1) {\n\t\tconst source = sources[index]\n\t\tif (source === undefined) continue\n\t\tif (index > 0) {\n\t\t\tconst previous = sources[index - 1]\n\t\t\tconst left = previous?.segments[previous.segments.length - 1]\n\t\t\tconst right = source.segments[0]\n\t\t\tif (\n\t\t\t\tseparator.length > 0 &&\n\t\t\t\tleft !== undefined &&\n\t\t\t\tright !== undefined &&\n\t\t\t\tleft.end < right.start\n\t\t\t)\n\t\t\t\tsegments.push({ offset: text.length, start: left.end, end: right.start })\n\t\t\ttext += separator\n\t\t}\n\t\tfor (const segment of source.segments) {\n\t\t\tsegments.push({\n\t\t\t\toffset: text.length + segment.offset,\n\t\t\t\tstart: segment.start,\n\t\t\t\tend: segment.end,\n\t\t\t})\n\t\t}\n\t\ttext += source.text\n\t}\n\treturn { text, segments }\n}\n\n/**\n * Projects a derived text range through its segments to a half-open region of the\n * original markdown string.\n *\n * @param source - The offset-bearing source carrying the range\n * @param from - The inclusive derived-text boundary\n * @param to - The exclusive derived-text boundary\n * @returns The original-string span, or `undefined` when either boundary is unmapped\n *\n * @example\n * ```ts\n * projectSpan({ text: 'a', segments: [{ offset: 0, start: 4, end: 5 }] }, 0, 1)\n * // { start: 4, end: 5 }\n * ```\n */\nexport function projectSpan(\n\tsource: MarkdownSource,\n\tfrom: number,\n\tto: number,\n): MarkdownSpan | undefined {\n\tif (from < 0 || to < from || to > source.text.length) return undefined\n\tlet start: number | undefined\n\tlet end: number | undefined\n\tfor (let index = 0; index < source.segments.length; index += 1) {\n\t\tconst segment = source.segments[index]\n\t\tif (segment === undefined) continue\n\t\tconst next = source.segments[index + 1]\n\t\tconst limit = Math.min(\n\t\t\tsegment.offset + (segment.end - segment.start),\n\t\t\tnext === undefined ? source.text.length : next.offset,\n\t\t)\n\t\tif (from === to && from >= segment.offset && from <= limit) {\n\t\t\tif (next !== undefined && from === next.offset) continue\n\t\t\tconst position =\n\t\t\t\tfrom === limit ? segment.end : Math.min(segment.end, segment.start + from - segment.offset)\n\t\t\treturn { start: position, end: position }\n\t\t}\n\t\tif (start === undefined && from >= segment.offset && from < limit)\n\t\t\tstart = segment.start + from - segment.offset\n\t\tif (to > segment.offset && to <= limit)\n\t\t\tend = to === limit ? segment.end : Math.min(segment.end, segment.start + to - segment.offset)\n\t}\n\treturn start === undefined || end === undefined ? undefined : { start, end }\n}\n\n/**\n * Trims an offset-bearing source without losing the coordinates of its retained text.\n *\n * @param source - The source to trim\n * @returns The trimmed text and its narrowed original-string segments\n *\n * @example\n * ```ts\n * trimSource({ text: ' a ', segments: [{ offset: 0, start: 4, end: 7 }] })\n * // { text: 'a', segments: [{ offset: 0, start: 5, end: 6 }] }\n * ```\n */\nexport function trimSource(source: MarkdownSource): MarkdownSource {\n\tconst start = source.text.length - source.text.trimStart().length\n\tconst end = source.text.trimEnd().length\n\treturn sliceSource(source, start, Math.max(start, end))\n}\n\n/**\n * Normalizes one paragraph line while retaining the full source run consumed by a\n * trailing-space hard break.\n *\n * @param source - The offset-bearing paragraph line\n * @param breaks - If `true`, preserves a trailing run of at least two spaces as the\n * scanner's two-space hard-break syntax; if `false`, trims the line normally\n * @returns The normalized line and its original-string segments\n *\n * @example\n * ```ts\n * normalizeParagraphLine(splitLines('text \\nnext')[0], true).text // 'text '\n * ```\n */\nexport function normalizeParagraphLine(source: MarkdownSource, breaks: boolean): MarkdownSource {\n\tif (!breaks || !source.text.endsWith(' ')) return trimSource(source)\n\tconst contentEnd = source.text.trimEnd().length\n\tconst content = trimSource(sliceSource(source, 0, contentEnd))\n\tconst span = projectSpan(source, contentEnd, source.text.length)\n\tconst suffix: MarkdownSource = {\n\t\ttext: ' ',\n\t\tsegments: span === undefined ? [] : [{ offset: 0, start: span.start, end: span.end }],\n\t}\n\treturn joinSources([content, suffix], '')\n}\n\n/**\n * Counts the leading space / tab characters on `line` (a tab counts as one) — the\n * indent that decides whether a list item's continuation belongs to the item.\n *\n * @param line - The line to measure\n * @returns The number of leading space / tab characters\n *\n * @example\n * ```ts\n * countIndent(' text') // 2\n * ```\n */\nexport function countIndent(line: string): number {\n\tlet count = 0\n\tfor (const character of line) {\n\t\tif (character === ' ' || character === '\\t') count += 1\n\t\telse break\n\t}\n\treturn count\n}\n\n// Line + character structural predicates\n//\n// Boolean predicates over a raw `string` (or a character of one) that the block and\n// inline phases test lines with. None narrows a type, so none is a `Guard<T>` and none\n// belongs in validators.ts; `isFenceClose` and `isTableStart` take two arguments, which\n// no guard signature admits.\n\n/**\n * Checks whether `character` is whitespace under the emphasis flanking rule — a space, a\n * tab, or a newline.\n *\n * @param character - The character to test\n * @returns True if the flanking rule counts it as whitespace; false otherwise\n *\n * @example\n * ```ts\n * isFlankingWhitespace(' ') // true\n * isFlankingWhitespace('a') // false\n * ```\n */\nexport function isFlankingWhitespace(character: string): boolean {\n\treturn character === ' ' || character === '\\t' || character === '\\n'\n}\n\n/**\n * Checks whether `character` is escapable by a leading backslash — the ASCII punctuation\n * markdown gives meaning to (so `\\*` becomes `*` but `\\.` stays `\\.`).\n *\n * @param character - The single character after a backslash\n * @returns True if a backslash before it is an escape; false otherwise\n *\n * @example\n * ```ts\n * isEscapable('*') // true\n * isEscapable('a') // false\n * ```\n */\nexport function isEscapable(character: string): boolean {\n\treturn /[\\\\`*_{}[\\]()#+\\-.!>~|]/.test(character)\n}\n\n/**\n * Checks whether `line` is blank — empty, or containing only whitespace — the markdown\n * definition of a blank line that block parsing uses to separate paragraphs, skip\n * gaps, and end list continuations.\n *\n * @param line - The candidate line\n * @returns True if the line is blank; false otherwise\n *\n * @example\n * ```ts\n * isBlankLine(' ') // true\n * ```\n */\nexport function isBlankLine(line: string): boolean {\n\treturn isEmptyString(line.trim())\n}\n\n/**\n * Checks whether `line` is a blockquote line (`>` optionally indented up to three spaces) —\n * its content is de-quoted by {@link stripQuote}.\n *\n * @param line - The candidate line\n * @returns True if the line begins a blockquote; false otherwise\n *\n * @example\n * ```ts\n * isQuote('> quoted') // true\n * ```\n */\nexport function isQuote(line: string): boolean {\n\treturn /^\\s{0,3}>/.test(line)\n}\n\n/**\n * Checks whether `line` closes a fence opened by `marker` — the same fence character, a run\n * at least as long, and nothing else but surrounding whitespace.\n *\n * @param line - The candidate closing line\n * @param marker - The opening fence's marker run (from {@link extractFence})\n * @returns True if `line` closes the fence; false otherwise\n *\n * @example\n * ```ts\n * isFenceClose('```', '```') // true\n * ```\n */\nexport function isFenceClose(line: string, marker: string): boolean {\n\tconst character = marker[0] === '~' ? '~' : '`'\n\tlet index = 0\n\twhile (index < line.length && isFenceWhitespace(line[index])) index++\n\tlet run = 0\n\twhile (index < line.length && line[index] === character) {\n\t\trun++\n\t\tindex++\n\t}\n\tif (run < marker.length) return false\n\twhile (index < line.length && isFenceWhitespace(line[index])) index++\n\treturn index === line.length\n}\n\n/**\n * Checks whether `character` is a regex-`\\s`-equivalent whitespace character — the\n * character class {@link isFenceClose}'s scan treats as surrounding padding.\n *\n * @param character - The single character to test, or `undefined` past the end of a line\n * @returns True if it is whitespace; false otherwise\n *\n * @example\n * ```ts\n * isFenceWhitespace(' ') // true\n * isFenceWhitespace(undefined) // false\n * ```\n */\nexport function isFenceWhitespace(character: string | undefined): boolean {\n\treturn (\n\t\tcharacter === ' ' ||\n\t\tcharacter === '\\t' ||\n\t\tcharacter === '\\n' ||\n\t\tcharacter === '\\r' ||\n\t\tcharacter === '\\f' ||\n\t\tcharacter === '\\v'\n\t)\n}\n\n/**\n * Checks whether `line` is a thematic break (horizontal rule) — three or more of the same\n * marker `-`, `*`, or `_` (optionally space-separated) and nothing else (`---`,\n * `***`, `___`, `- - -`).\n *\n * @param line - The candidate line\n * @returns True if the line is a thematic break; false otherwise\n *\n * @example\n * ```ts\n * isThematicBreak('---') // true\n * ```\n */\nexport function isThematicBreak(line: string): boolean {\n\tconst stripped = line.trim().replace(/\\s+/g, '')\n\tif (stripped.length < 3) return false\n\tconst marker = stripped[0]\n\tif (marker !== '-' && marker !== '*' && marker !== '_') return false\n\treturn [...stripped].every((character) => character === marker)\n}\n\n/**\n * Checks whether the pair (`header`, `delimiter`) opens a GFM table — `delimiter` is a row of\n * `|`-separated cells each matching `:?-+:?`, the GFM rule that a table requires a\n * header row immediately followed by a delimiter row.\n *\n * @param header - The candidate header line\n * @param delimiter - The line after it (the candidate delimiter)\n * @returns True if the two lines open a table; false otherwise\n *\n * @example\n * ```ts\n * isTableStart('| a |', '| - |') // true\n * ```\n */\nexport function isTableStart(header: string, delimiter: string | undefined): boolean {\n\tif (delimiter === undefined || !header.includes('|')) return false\n\tconst cells = splitTableRow(delimiter)\n\tif (cells.length === 0) return false\n\treturn cells.every((cell) => /^:?-+:?$/.test(cell.trim()))\n}\n\n// Block-level detection\n\n/**\n * Extracts an ATX heading line (`#` … `######` followed by text) into its level,\n * trimmed text, and the text's offset inside the line. A run of more than 6 `#`s, or\n * `#`s not followed by whitespace + text, is not a heading; an optional closing\n * `###` run is stripped.\n *\n * @param line - The candidate line\n * @returns The heading level (1–6), raw inline text, and text offset, or `undefined`\n *\n * @example\n * ```ts\n * extractHeading('## Title') // { level: 2, text: 'Title', offset: 3 }\n * ```\n */\nexport function extractHeading(line: string): HeadingMatch | undefined {\n\tconst trimmed = line.trimStart()\n\tconst match = /^(#{1,6})(?:\\s+(.*))?$/.exec(trimmed)\n\tif (!match || match[1] === undefined) return undefined\n\tconst level = match[1].length\n\tconst raw = match[2] ?? ''\n\tconst withoutClosing = raw.replace(/\\s+#+\\s*$/, '')\n\tconst text = withoutClosing.trim()\n\tconst found = raw.length === 0 ? trimmed.length : trimmed.indexOf(raw, level)\n\tconst content = found < 0 ? trimmed.length : found\n\tconst offset =\n\t\tline.length -\n\t\ttrimmed.length +\n\t\tcontent +\n\t\twithoutClosing.length -\n\t\twithoutClosing.trimStart().length\n\treturn { level, text, offset }\n}\n\n/**\n * Extracts a fenced-code opening line (```` ``` ```` or `~~~`, optionally with an info\n * string) into its `{ marker, lang }`, or `undefined` when `line` is not a fence\n * opener. `marker` is the exact fence run (the closer must match the same character +\n * at least the same length); `lang` is the first word of the info string.\n *\n * @param line - The candidate line\n * @returns The fence marker run and its language tag, or `undefined`\n *\n * @example\n * ```ts\n * extractFence('```ts') // { marker: '```', lang: 'ts' }\n * ```\n */\nexport function extractFence(line: string): FenceMatch | undefined {\n\tconst match = /^\\s*(`{3,}|~{3,})\\s*(.*)$/.exec(line)\n\tif (!match || match[1] === undefined) return undefined\n\tconst info = (match[2] ?? '').trim()\n\t// A backtick in a backtick fence's info string is invalid (ambiguous with a span).\n\tif (match[1].startsWith('`') && info.includes('`')) return undefined\n\tconst lang = isNonEmptyString(info) ? info.split(/\\s+/)[0] : undefined\n\treturn { marker: match[1], lang }\n}\n\n/**\n * Extracts a list-item line (`-` / `*` / `+` bullet, or `1.` / `1)` ordinal, followed by\n * a space) into its {@link ListItemMatch}, or `undefined` when `line` is not a list\n * item. `content` is the text after the marker; `marker` is the full marker-plus-space\n * width (for measuring a continuation's indent).\n *\n * @param line - The candidate line\n * @returns The list-item parts, or `undefined` when not a list item\n *\n * @example\n * ```ts\n * extractListItem('- item') // { ordered: false, start: 1, content: 'item', indent: 0, marker: 2 }\n * ```\n */\nexport function extractListItem(line: string): ListItemMatch | undefined {\n\tconst unordered = /^(\\s*)([-*+])\\s+(.*)$/.exec(line)\n\tif (unordered && unordered[1] !== undefined) {\n\t\tconst indent = unordered[1].length\n\t\tconst content = unordered[3] ?? ''\n\t\treturn { ordered: false, start: 1, content, indent, marker: line.length - content.length }\n\t}\n\tconst ordered = /^(\\s*)(\\d{1,9})[.)]\\s+(.*)$/.exec(line)\n\tif (ordered && ordered[1] !== undefined && ordered[2] !== undefined) {\n\t\tconst indent = ordered[1].length\n\t\tconst content = ordered[3] ?? ''\n\t\treturn {\n\t\t\tordered: true,\n\t\t\tstart: parseInteger(ordered[2]) ?? 1,\n\t\t\tcontent,\n\t\t\tindent,\n\t\t\tmarker: line.length - content.length,\n\t\t}\n\t}\n\treturn undefined\n}\n\n/**\n * Strips one level of blockquote marker (`>` plus one optional following space) from\n * an offset-bearing blockquote line, so the de-quoted source re-parses as nested\n * blocks without losing its original coordinates.\n *\n * @param source - A blockquote line (per {@link isQuote})\n * @returns The source with its leading `>` and optional space removed\n *\n * @example\n * ```ts\n * stripQuote({ text: '> text', segments: [{ offset: 0, start: 0, end: 6 }] })\n * // { text: 'text', segments: [{ offset: 0, start: 2, end: 6 }] }\n * ```\n */\nexport function stripQuote(source: MarkdownSource): MarkdownSource {\n\tconst marker = /^\\s{0,3}>\\s?/.exec(source.text)?.[0] ?? ''\n\treturn sliceSource(source, marker.length, source.text.length)\n}\n\n/**\n * Splits one GFM table row into its cell strings — outer pipes are optional, a pipe\n * escaped by a leading backslash inside a cell is not a separator (it becomes a literal\n * pipe character), and the empty leading / trailing cell an outer pipe produces is\n * dropped. Derives the string form from {@link splitTableSources}, which owns the\n * escaped-pipe splitting rule.\n *\n * @param row - The raw table row line\n * @returns The row's cells, in column order\n *\n * @example\n * ```ts\n * splitTableRow('|a|b|') // ['a', 'b']\n * ```\n */\nexport function splitTableRow(row: string): readonly string[] {\n\treturn splitTableSources({ text: row, segments: [] }).map((cell) => cell.text)\n}\n\n/**\n * Splits an offset-bearing GFM table row into offset-bearing cells, retaining the\n * complete source spelling of an escaped pipe while exposing its literal value.\n *\n * @param row - The offset-bearing table row\n * @returns The row's cells with their original-string coordinates\n *\n * @example\n * ```ts\n * splitTableSources(splitLines('| a\\\\|b |')[0]).map((cell) => cell.text) // [' a|b ']\n * ```\n */\nexport function splitTableSources(row: MarkdownSource): readonly MarkdownSource[] {\n\tconst source = trimSource(row)\n\tconst cells: MarkdownSource[] = []\n\tlet pieces: MarkdownSource[] = []\n\tlet start = 0\n\tfor (let index = 0; index < source.text.length; index += 1) {\n\t\tconst character = source.text[index]\n\t\tif (character === '\\\\' && source.text[index + 1] === '|') {\n\t\t\tpieces.push(sliceSource(source, start, index))\n\t\t\tconst span = projectSpan(source, index, index + 2)\n\t\t\tpieces.push({\n\t\t\t\ttext: '|',\n\t\t\t\tsegments: span === undefined ? [] : [{ offset: 0, start: span.start, end: span.end }],\n\t\t\t})\n\t\t\tindex += 1\n\t\t\tstart = index + 1\n\t\t\tcontinue\n\t\t}\n\t\tif (character !== '|') continue\n\t\tpieces.push(sliceSource(source, start, index))\n\t\tcells.push(joinSources(pieces, ''))\n\t\tpieces = []\n\t\tstart = index + 1\n\t}\n\tpieces.push(sliceSource(source, start, source.text.length))\n\tcells.push(joinSources(pieces, ''))\n\tif (isNonEmptyArray<MarkdownSource>(cells) && isEmptyString((cells[0]?.text ?? '').trim()))\n\t\tcells.shift()\n\tif (\n\t\tisNonEmptyArray<MarkdownSource>(cells) &&\n\t\tisEmptyString((cells[cells.length - 1]?.text ?? '').trim())\n\t)\n\t\tcells.pop()\n\treturn cells\n}\n\n/**\n * Derives the per-column {@link TableAlign} list from a GFM delimiter row — `:---`\n * left, `---:` right, `:---:` center, and `---` as the explicit no-alignment\n * marker represented by `null`.\n *\n * @param delimiter - The table's delimiter row\n * @returns One alignment per column, in column order\n *\n * @example\n * ```ts\n * delimiterToAlignments('| :--- | ---: |') // ['left', 'right']\n * ```\n */\nexport function delimiterToAlignments(delimiter: string): ReadonlyArray<TableAlign | null> {\n\treturn splitTableRow(delimiter).map((cell) => {\n\t\tconst text = cell.trim()\n\t\tconst left = text.startsWith(':')\n\t\tconst right = text.endsWith(':')\n\t\tif (left && right) return 'center'\n\t\tif (right) return 'right'\n\t\tif (left) return 'left'\n\t\treturn null\n\t})\n}\n\n// Block phase\n\n/**\n * Checks whether the line at `index` starts a new block kind (heading / fence / thematic\n * break / blockquote / list / table) — the paragraph collector stops at such a line\n * so a block following a paragraph without a blank line still parses (a trusted-input\n * caller writing a `##` heading directly under a paragraph, with no intervening blank\n * line).\n *\n * @param lines - The document's lines\n * @param index - The line index to test\n * @returns True if the line begins a different block; false otherwise\n *\n * @example\n * ```ts\n * startsBlock(['text', '## Heading'], 1) // true\n * ```\n */\nexport function startsBlock(lines: readonly string[], index: number): boolean {\n\tconst line = lines[index] ?? ''\n\treturn (\n\t\textractHeading(line) !== undefined ||\n\t\textractFence(line) !== undefined ||\n\t\tisThematicBreak(line) ||\n\t\tisQuote(line) ||\n\t\textractListItem(line) !== undefined ||\n\t\tisTableStart(line, lines[index + 1])\n\t)\n}\n\n// Inline phase\n\n/**\n * Resolves backslash escapes in a raw string to their literal characters — used for a\n * link `href` (which is not otherwise inline-parsed) and any plain text run.\n *\n * @param text - The raw text possibly carrying `\\x` escapes\n * @returns The text with escapable `\\x` reduced to `x`\n *\n * @example\n * ```ts\n * unescapeText('\\\\*hi\\\\*') // '*hi*'\n * ```\n */\nexport function unescapeText(text: string): string {\n\tlet out = ''\n\tfor (let index = 0; index < text.length; index += 1) {\n\t\tconst character = text[index] ?? ''\n\t\tif (character === '\\\\' && isEscapable(text[index + 1] ?? '')) {\n\t\t\tout += text[index + 1] ?? ''\n\t\t\tindex += 1\n\t\t} else {\n\t\t\tout += character\n\t\t}\n\t}\n\treturn out\n}\n\n/**\n * Merges adjacent text nodes into one — the inline scanner emits a text node per\n * unrecognized character, so coalescing keeps the AST clean and assertion-friendly.\n *\n * @param nodes - The inline nodes (possibly with adjacent text runs)\n * @param spans - The optional operation-owned node span recorder\n * @returns The nodes with consecutive text nodes concatenated\n *\n * @example\n * ```ts\n * coalesceText([{ element: 'text', value: 'a' }, { element: 'text', value: 'b' }])\n * // [{ element: 'text', value: 'ab' }]\n * ```\n */\nexport function coalesceText(\n\tnodes: readonly InlineNode[],\n\tspans?: Map<MarkdownNode, MarkdownSpan>,\n): readonly InlineNode[] {\n\tconst out: InlineNode[] = []\n\tfor (const node of nodes) {\n\t\tconst last = out[out.length - 1]\n\t\tif (node.element === 'text' && last !== undefined && last.element === 'text') {\n\t\t\tconst merged: InlineNode = { element: 'text', value: last.value + node.value }\n\t\t\tconst left = spans?.get(last)\n\t\t\tconst right = spans?.get(node)\n\t\t\tif (spans !== undefined) {\n\t\t\t\tspans.delete(last)\n\t\t\t\tspans.delete(node)\n\t\t\t\tif (left !== undefined && right !== undefined)\n\t\t\t\t\tspans.set(merged, { start: left.start, end: right.end })\n\t\t\t}\n\t\t\tout[out.length - 1] = merged\n\t\t} else {\n\t\t\tout.push(node)\n\t\t}\n\t}\n\treturn out\n}\n\n/**\n * Scans an inline code span at `start` (a `` ` ``-run … a matching `` ` ``-run of the\n * same length, the CommonMark rule that lets a span contain backticks). Returns the\n * span's literal text + end index, or `undefined` when no matching closer exists (it\n * then degrades to literal backticks).\n *\n * @param source - The inline source text\n * @param start - The index of the opening backtick\n * @param to - The exclusive end of the scan window\n * @returns The span text + end index, or `undefined`\n *\n * @example\n * ```ts\n * scanCode('`code`', 0, 6) // { value: 'code', end: 6 }\n * ```\n */\nexport function scanCode(source: string, start: number, to: number): CodeSpanMatch | undefined {\n\tlet run = 0\n\twhile (start + run < to && source[start + run] === '`') run += 1\n\tconst open = '`'.repeat(run)\n\tlet search = start + run\n\tfor (;;) {\n\t\tconst closeAt = source.indexOf(open, search)\n\t\tif (closeAt === -1 || closeAt + run > to) return undefined\n\t\t// The closer must be exactly `run` backticks (not bordered by another backtick).\n\t\tif (source[closeAt - 1] !== '`' && source[closeAt + run] !== '`') {\n\t\t\tlet value = source.slice(start + run, closeAt)\n\t\t\tif (\n\t\t\t\tvalue.length > 2 &&\n\t\t\t\tvalue.startsWith(' ') &&\n\t\t\t\tvalue.endsWith(' ') &&\n\t\t\t\tvalue.trim().length > 0\n\t\t\t) {\n\t\t\t\tvalue = value.slice(1, -1)\n\t\t\t}\n\t\t\treturn { value, end: closeAt + run }\n\t\t}\n\t\tsearch = closeAt + 1\n\t}\n}\n\n/**\n * Locates a link `[text](href)` at `start` — the text runs to a balanced `]`, then `(`\n * must immediately follow and the destination runs to the matching `)` (both respect\n * nested delimiters + escapes). Returns the label close and syntax end, or `undefined` when the shape\n * does not hold (it then degrades to a literal `[`).\n *\n * @param source - The inline source text\n * @param start - The index of the opening `[`\n * @param to - The exclusive end of the scan window\n * @returns The label close and syntax end indices, or `undefined`\n *\n * @example\n * ```ts\n * locateLink('[text](url)', 0, 11) // { close: 5, end: 11 }\n * ```\n */\nexport function locateLink(source: string, start: number, to: number): LinkBounds | undefined {\n\tlet bracketDepth = 0\n\tlet close = -1\n\tfor (let index = start; index < to; index += 1) {\n\t\tconst character = source[index] ?? ''\n\t\tif (character === '\\\\') {\n\t\t\tindex += 1\n\t\t\tcontinue\n\t\t}\n\t\tif (character === '[') bracketDepth += 1\n\t\telse if (character === ']') {\n\t\t\tbracketDepth -= 1\n\t\t\tif (bracketDepth === 0) {\n\t\t\t\tclose = index\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\tif (close === -1 || source[close + 1] !== '(') return undefined\n\tlet parenDepth = 0\n\tlet parenClose = -1\n\tfor (let index = close + 1; index < to; index += 1) {\n\t\tconst character = source[index] ?? ''\n\t\tif (character === '\\\\') {\n\t\t\tindex += 1\n\t\t\tcontinue\n\t\t}\n\t\tif (character === '(') parenDepth += 1\n\t\telse if (character === ')') {\n\t\t\tparenDepth -= 1\n\t\t\tif (parenDepth === 0) {\n\t\t\t\tparenClose = index\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\tif (parenClose === -1) return undefined\n\treturn { close, end: parenClose + 1 }\n}\n\n/**\n * Scans a link `[text](href)` at `start` — the text runs to a balanced `]`, then `(`\n * must immediately follow and the destination runs to the matching `)` (both respect\n * nested delimiters + escapes) through {@link locateLink}, and returns the parsed node\n * and end index. Returns `undefined` when the shape does not hold (it then degrades to\n * a literal `[`).\n *\n * @param source - The inline source text\n * @param start - The index of the opening `[`\n * @param to - The exclusive end of the scan window\n * @param depth - The current inline-recursion depth, forwarded to {@link scanInline}\n * incremented by one for the link text's children. At {@link MAX_DEPTH} that\n * recursion emits the text as a single literal text node instead of scanning it.\n * @returns The parsed link and end index, or `undefined` when the shape does not hold\n *\n * @example\n * ```ts\n * scanLink('[text](url)', 0, 11)\n * // { node: { element: 'link', href: 'url', children: [{ element: 'text', value: 'text' }] }, end: 11 }\n * ```\n */\nexport function scanLink(\n\tsource: string,\n\tstart: number,\n\tto: number,\n\tdepth = 0,\n): LinkScan | undefined {\n\tconst located = locateLink(source, start, to)\n\tif (located === undefined) return undefined\n\tconst href = unescapeText(source.slice(located.close + 2, located.end - 1).trim())\n\tconst children = scanInline(source, start + 1, located.close, depth + 1)\n\treturn { node: { element: 'link', href, children }, end: located.end }\n}\n\n/**\n * Locates an emphasis run at `start` (`*` / `_`, doubled for strong) — finds the nearest\n * matching closing run of the same marker + width while skipping complete nested\n * runs from the other marker family, and requires non-space immediately inside both\n * delimiters (the CommonMark flanking simplification that blocks `* x *`). Returns\n * the content and syntax bounds, or `undefined` when no valid closer exists (it then degrades to\n * a literal marker).\n *\n * @param source - The inline source text\n * @param start - The index of the opening marker\n * @param to - The exclusive end of the scan window\n * @returns The content and syntax bounds, or `undefined`\n *\n * @example\n * ```ts\n * locateEmphasis('*em*', 0, 4) // { strong: false, open: 1, close: 3, end: 4 }\n * ```\n */\nexport function locateEmphasis(\n\tsource: string,\n\tstart: number,\n\tto: number,\n): EmphasisBounds | undefined {\n\tconst marker = source[start] ?? ''\n\tlet run = 0\n\twhile (start + run < to && source[start + run] === marker && run < 2) run += 1\n\tconst strong = run === 2\n\tconst openEnd = start + run\n\tif (openEnd >= to || isFlankingWhitespace(source[openEnd] ?? '')) return undefined\n\tlet index = openEnd\n\twhile (index < to) {\n\t\tconst character = source[index] ?? ''\n\t\tif (character === '\\\\') {\n\t\t\tindex += 2\n\t\t\tcontinue\n\t\t}\n\t\tif (character === '`') {\n\t\t\tconst span = scanCode(source, index, to)\n\t\t\tindex = span ? span.end : index + 1\n\t\t\tcontinue\n\t\t}\n\t\tif ((character === '*' || character === '_') && character !== marker) {\n\t\t\tconst nested = locateEmphasis(source, index, to)\n\t\t\tif (nested !== undefined) {\n\t\t\t\tindex = nested.end\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tif (character === marker) {\n\t\t\tlet closeRun = 0\n\t\t\twhile (index + closeRun < to && source[index + closeRun] === marker) closeRun += 1\n\t\t\tif (closeRun >= run && !isFlankingWhitespace(source[index - 1] ?? '')) {\n\t\t\t\treturn {\n\t\t\t\t\tstrong,\n\t\t\t\t\topen: openEnd,\n\t\t\t\t\tclose: index,\n\t\t\t\t\tend: index + run,\n\t\t\t\t}\n\t\t\t}\n\t\t\tindex += closeRun\n\t\t\tcontinue\n\t\t}\n\t\tindex += 1\n\t}\n\treturn undefined\n}\n\n/**\n * Scans an emphasis run at `start` (`*` / `_`, doubled for strong) — finds the nearest\n * matching closing run of the same marker + width while skipping complete nested runs\n * from the other marker family, and requires non-space immediately inside both\n * delimiters (the CommonMark flanking simplification that blocks `* x *`) through\n * {@link locateEmphasis}, and returns the parsed node and end index. Returns\n * `undefined` when no valid closer exists (it then degrades to a literal marker).\n *\n * @param source - The inline source text\n * @param start - The index of the opening marker\n * @param to - The exclusive end of the scan window\n * @param depth - The current inline-recursion depth, forwarded to {@link scanInline}\n * incremented by one for the run's children. At {@link MAX_DEPTH} that recursion\n * emits the content as a single literal text node instead of scanning it.\n * @returns The parsed emphasis and end index, or `undefined` when no closer exists\n *\n * @example\n * ```ts\n * scanEmphasis('*em*', 0, 4)\n * // { node: { element: 'emphasis', strong: false, children: [{ element: 'text', value: 'em' }] }, end: 4 }\n * ```\n */\nexport function scanEmphasis(\n\tsource: string,\n\tstart: number,\n\tto: number,\n\tdepth = 0,\n): EmphasisScan | undefined {\n\tconst located = locateEmphasis(source, start, to)\n\tif (located === undefined) return undefined\n\treturn {\n\t\tnode: {\n\t\t\telement: 'emphasis',\n\t\t\tstrong: located.strong,\n\t\t\tchildren: scanInline(source, located.open, located.close, depth + 1),\n\t\t},\n\t\tend: located.end,\n\t}\n}\n\n/**\n * Scans the window `[from, to)` of `source` into inline nodes — the single recursive\n * engine the inline phase runs on (emphasis, link text, and image alternative\n * content recurse through it). Linear:\n * each character is consumed once; a failed construct emits its opening character as\n * text and advances by one, so there is no re-scan (no ReDoS).\n *\n * @param source - The inline source text\n * @param from - The inclusive start of the scan window\n * @param to - The exclusive end of the scan window\n * @param depth - The current inline-recursion depth (defaults to 0 at the entry point);\n * incremented by one on every recursive descent {@link scanInlineSource} makes into\n * itself for a link's text, an image's alternative content, or an emphasis run's\n * children. At {@link MAX_DEPTH} the window is never scanned for markup — it emits as\n * a single literal text node — so pathological nesting (`[[[[…`, `****…`) cannot\n * exhaust the call stack.\n * @returns The parsed inline nodes (not yet coalesced)\n *\n * @example\n * ```ts\n * scanInline('hi *there*', 0, 10) // [{ element: 'text', value: 'hi ' }, { element: 'emphasis', ... }]\n * ```\n */\nexport function scanInline(\n\tsource: string,\n\tfrom: number,\n\tto: number,\n\tdepth = 0,\n): readonly InlineNode[] {\n\treturn scanInlineSource(\n\t\t{\n\t\t\ttext: source,\n\t\t\tsegments: [{ offset: 0, start: 0, end: source.length }],\n\t\t},\n\t\tfrom,\n\t\tto,\n\t\tnew Map<MarkdownNode, MarkdownSpan>(),\n\t\tdepth,\n\t)\n}\n\n/**\n * Scans an offset-bearing inline window with the same engine as {@link scanInline}\n * and records each emitted node against the original markdown string.\n *\n * @param source - The offset-bearing inline source\n * @param from - The inclusive start of the scan window\n * @param to - The exclusive end of the scan window\n * @param spans - The operation-owned node span recorder\n * @param depth - The current inline-recursion depth, incremented by one on every\n * recursive descent this function makes into itself for a link's text, an image's\n * alternative content, or an emphasis run's children\n * @returns The parsed inline nodes before adjacent text coalescing\n *\n * @example\n * ```ts\n * scanInlineSource(\n * \t{ text: 'hi *there*', segments: [{ offset: 0, start: 0, end: 10 }] },\n * \t0,\n * \t10,\n * \tnew Map(),\n * )\n * // [{ element: 'text', value: 'hi ' }, { element: 'emphasis', ... }]\n * ```\n */\nexport function scanInlineSource(\n\tsource: MarkdownSource,\n\tfrom: number,\n\tto: number,\n\tspans: Map<MarkdownNode, MarkdownSpan>,\n\tdepth = 0,\n): readonly InlineNode[] {\n\tif (depth >= MAX_DEPTH)\n\t\tif (from < to) {\n\t\t\tconst node: InlineNode = { element: 'text', value: source.text.slice(from, to) }\n\t\t\tconst span = projectSpan(source, from, to)\n\t\t\tif (span !== undefined) spans.set(node, span)\n\t\t\treturn [node]\n\t\t} else return []\n\tconst nodes: InlineNode[] = []\n\tlet index = from\n\tlet pending = ''\n\tlet pendingStart = from\n\twhile (index < to) {\n\t\tconst character = source.text[index] ?? ''\n\t\tif (character === '\\\\' && index + 1 < to && isEscapable(source.text[index + 1] ?? '')) {\n\t\t\tif (pending.length === 0) pendingStart = index\n\t\t\tpending += source.text[index + 1] ?? ''\n\t\t\tindex += 2\n\t\t\tcontinue\n\t\t}\n\t\tif (character === ' ') {\n\t\t\tlet spaceEnd = index\n\t\t\twhile (spaceEnd < to && source.text[spaceEnd] === ' ') spaceEnd += 1\n\t\t\tif (spaceEnd - index >= 2 && source.text[spaceEnd] === '\\n') {\n\t\t\t\tif (pending.length > 0) {\n\t\t\t\t\tconst node: InlineNode = { element: 'text', value: pending }\n\t\t\t\t\tconst span = projectSpan(source, pendingStart, index)\n\t\t\t\t\tif (span !== undefined) spans.set(node, span)\n\t\t\t\t\tnodes.push(node)\n\t\t\t\t\tpending = ''\n\t\t\t\t}\n\t\t\t\tconst node: InlineNode = { element: 'break' }\n\t\t\t\tconst span = projectSpan(source, index, spaceEnd + 1)\n\t\t\t\tif (span !== undefined) spans.set(node, span)\n\t\t\t\tnodes.push(node)\n\t\t\t\tindex = spaceEnd + 1\n\t\t\t\tpendingStart = index\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tlet scanned: InlineNode | undefined\n\t\tlet end = index\n\t\tif (character === '`') {\n\t\t\tconst span = scanCode(source.text, index, to)\n\t\t\tif (span) {\n\t\t\t\tscanned = { element: 'codeSpan', value: span.value }\n\t\t\t\tend = span.end\n\t\t\t}\n\t\t}\n\t\tif (character === '!' && source.text[index + 1] === '[') {\n\t\t\tconst link = locateLink(source.text, index + 1, to)\n\t\t\tif (link !== undefined) {\n\t\t\t\tscanned = {\n\t\t\t\t\telement: 'image',\n\t\t\t\t\tsrc: unescapeText(source.text.slice(link.close + 2, link.end - 1).trim()),\n\t\t\t\t\tchildren: coalesceText(\n\t\t\t\t\t\tscanInlineSource(source, index + 2, link.close, spans, depth + 1),\n\t\t\t\t\t\tspans,\n\t\t\t\t\t),\n\t\t\t\t}\n\t\t\t\tend = link.end\n\t\t\t}\n\t\t}\n\t\tif (character === '[') {\n\t\t\tconst link = locateLink(source.text, index, to)\n\t\t\tif (link !== undefined) {\n\t\t\t\tscanned = {\n\t\t\t\t\telement: 'link',\n\t\t\t\t\thref: unescapeText(source.text.slice(link.close + 2, link.end - 1).trim()),\n\t\t\t\t\tchildren: coalesceText(\n\t\t\t\t\t\tscanInlineSource(source, index + 1, link.close, spans, depth + 1),\n\t\t\t\t\t\tspans,\n\t\t\t\t\t),\n\t\t\t\t}\n\t\t\t\tend = link.end\n\t\t\t}\n\t\t}\n\t\tif (character === '*' || character === '_') {\n\t\t\tconst emphasis = locateEmphasis(source.text, index, to)\n\t\t\tif (emphasis !== undefined) {\n\t\t\t\tscanned = {\n\t\t\t\t\telement: 'emphasis',\n\t\t\t\t\tstrong: emphasis.strong,\n\t\t\t\t\tchildren: coalesceText(\n\t\t\t\t\t\tscanInlineSource(source, emphasis.open, emphasis.close, spans, depth + 1),\n\t\t\t\t\t\tspans,\n\t\t\t\t\t),\n\t\t\t\t}\n\t\t\t\tend = emphasis.end\n\t\t\t}\n\t\t}\n\t\tif (scanned !== undefined) {\n\t\t\tif (pending.length > 0) {\n\t\t\t\tconst node: InlineNode = { element: 'text', value: pending }\n\t\t\t\tconst span = projectSpan(source, pendingStart, index)\n\t\t\t\tif (span !== undefined) spans.set(node, span)\n\t\t\t\tnodes.push(node)\n\t\t\t\tpending = ''\n\t\t\t}\n\t\t\tconst span = projectSpan(source, index, end)\n\t\t\tif (span !== undefined) spans.set(scanned, span)\n\t\t\tnodes.push(scanned)\n\t\t\tindex = end\n\t\t\tpendingStart = index\n\t\t\tcontinue\n\t\t}\n\t\tif (pending.length === 0) pendingStart = index\n\t\tpending += character\n\t\tindex += 1\n\t}\n\tif (pending.length > 0) {\n\t\tconst node: InlineNode = { element: 'text', value: pending }\n\t\tconst span = projectSpan(source, pendingStart, index)\n\t\tif (span !== undefined) spans.set(node, span)\n\t\tnodes.push(node)\n\t}\n\treturn nodes\n}\n\n/**\n * Collects a GFM table starting at a header row, parsing the header, the\n * alignment row, and every contiguous body row that follows.\n *\n * @param lines - The markdown lines to scan.\n * @param start - The index of the header row.\n * @param spans - The optional operation-owned node span recorder.\n * @returns The parsed table node and the index of the first line after it.\n *\n * @example\n * ```ts\n * collectTable(splitLines('| a |\\n| - |'), 0) // { node: { element: 'table', ... }, next: 2 }\n * ```\n */\nexport function collectTable(\n\tlines: readonly MarkdownSource[],\n\tstart: number,\n\tspans = new Map<MarkdownNode, MarkdownSpan>(),\n): TableCollection {\n\tconst headerCells = splitTableSources(lines[start] ?? { text: '', segments: [] })\n\tconst columns = headerCells.length\n\tconst header = headerCells.map((cell) => {\n\t\tconst source = trimSource(cell)\n\t\treturn coalesceText(scanInlineSource(source, 0, source.text.length, spans), spans)\n\t})\n\tconst align = delimiterToAlignments(lines[start + 1]?.text ?? '')\n\tconst padded: Array<TableAlign | null> = []\n\tfor (let column = 0; column < columns; column += 1) padded.push(align[column] ?? null)\n\tconst rows: Array<Array<readonly InlineNode[]>> = []\n\tlet index = start + 2\n\twhile (\n\t\tindex < lines.length &&\n\t\t!isBlankLine(lines[index]?.text ?? '') &&\n\t\t(lines[index]?.text ?? '').includes('|')\n\t) {\n\t\tconst cells = splitTableSources(lines[index] ?? { text: '', segments: [] })\n\t\tconst row: Array<readonly InlineNode[]> = []\n\t\tfor (let column = 0; column < columns; column += 1) {\n\t\t\tconst source = trimSource(cells[column] ?? { text: '', segments: [] })\n\t\t\trow.push(coalesceText(scanInlineSource(source, 0, source.text.length, spans), spans))\n\t\t}\n\t\trows.push(row)\n\t\tindex += 1\n\t}\n\tconst node: TableNode = { element: 'table', header, rows, align: padded }\n\tconst source = joinSources(lines.slice(start, index), '\\n')\n\tconst span = projectSpan(source, 0, source.text.length)\n\tif (span !== undefined) spans.set(node, span)\n\treturn { node, next: index }\n}\n\n/**\n * Collects a list starting at the first item, gathering sibling items at the\n * same indent/ordering and recursing into each item's own block content.\n *\n * @param lines - The markdown lines to scan.\n * @param start - The index of the first list item.\n * @param depth - The current recursion depth (each item recurses at `depth + 1`).\n * @param spans - The optional operation-owned node span recorder.\n * @param end - The original-source end of this line run, including a removed terminator.\n * @returns The parsed list node and the index of the first line after it.\n *\n * @example\n * ```ts\n * collectList(splitLines('- item'), 0, 0) // { node: { element: 'list', ... }, next: 1 }\n * ```\n */\nexport function collectList(\n\tlines: readonly MarkdownSource[],\n\tstart: number,\n\tdepth: number,\n\tspans = new Map<MarkdownNode, MarkdownSpan>(),\n\tend?: number,\n): ListCollection {\n\tconst text = lines.map((line) => line.text)\n\tconst first = extractListItem(text[start] ?? '')\n\tconst ordered = first?.ordered ?? false\n\tconst startOrdinal = first?.start ?? 1\n\tconst topIndent = first?.indent ?? 0\n\tconst items: ListItemNode[] = []\n\t// A single nested-item chain would otherwise rescan and slice the whole suffix\n\t// once per level before reaching the cap. Recognize that shape in one pass and\n\t// build the same bounded AST bottom-up.\n\tconst chain: ListItemMatch[] = []\n\tlet nested = true\n\tfor (let cursor = start; cursor < lines.length; cursor += 1) {\n\t\tconst parsed = extractListItem(text[cursor] ?? '')\n\t\tconst previous = chain[chain.length - 1]\n\t\tif (\n\t\t\tparsed === undefined ||\n\t\t\t(previous !== undefined && (previous.content.length > 0 || parsed.indent !== previous.marker))\n\t\t) {\n\t\t\tnested = false\n\t\t\tbreak\n\t\t}\n\t\tchain.push(parsed)\n\t}\n\tconst remaining = MAX_DEPTH - depth\n\tif (nested && remaining > 0 && chain.length > remaining) {\n\t\tconst terminal = chain[remaining - 1]\n\t\tconst terminalLine = lines[start + remaining - 1]\n\t\tif (terminal !== undefined && terminalLine !== undefined) {\n\t\t\tconst sources: MarkdownSource[] = [\n\t\t\t\tsliceSource(terminalLine, terminal.marker, terminalLine.text.length),\n\t\t\t]\n\t\t\tfor (let cursor = start + remaining; cursor < lines.length; cursor += 1) {\n\t\t\t\tconst line = lines[cursor]\n\t\t\t\tif (line !== undefined) sources.push(sliceSource(line, terminal.marker, line.text.length))\n\t\t\t}\n\t\t\tconst source = joinSources(sources, '\\n')\n\t\t\tconst textNode: InlineNode = { element: 'text', value: source.text }\n\t\t\tconst paragraph: BlockNode = { element: 'paragraph', children: [textNode] }\n\t\t\tconst residualSpan = projectSpan(source, 0, source.text.length)\n\t\t\tif (residualSpan !== undefined) {\n\t\t\t\tspans.set(textNode, residualSpan)\n\t\t\t\tspans.set(paragraph, residualSpan)\n\t\t\t}\n\t\t\tlet children: readonly BlockNode[] = [paragraph]\n\t\t\tlet node: ListNode | undefined\n\t\t\tfor (let cursor = remaining - 1; cursor >= 0; cursor -= 1) {\n\t\t\t\tconst parsed = chain[cursor]\n\t\t\t\tif (parsed === undefined) continue\n\t\t\t\tconst item: ListItemNode = { element: 'listItem', children }\n\t\t\t\tnode = {\n\t\t\t\t\telement: 'list',\n\t\t\t\t\tordered: parsed.ordered,\n\t\t\t\t\tstart: parsed.start,\n\t\t\t\t\titems: [item],\n\t\t\t\t}\n\t\t\t\tconst region = joinSources(\n\t\t\t\t\tlines\n\t\t\t\t\t\t.slice(start + cursor)\n\t\t\t\t\t\t.map((line) => sliceSource(line, parsed.indent, line.text.length)),\n\t\t\t\t\t'\\n',\n\t\t\t\t)\n\t\t\t\tconst span = projectSpan(region, 0, region.text.length)\n\t\t\t\tif (span !== undefined) {\n\t\t\t\t\tspans.set(item, span)\n\t\t\t\t\tspans.set(node, span)\n\t\t\t\t}\n\t\t\t\tchildren = [node]\n\t\t\t}\n\t\t\tif (node !== undefined) return { node, next: lines.length }\n\t\t}\n\t}\n\tlet index = start\n\twhile (index < lines.length) {\n\t\tconst parsed = extractListItem(text[index] ?? '')\n\t\t// A sibling item shares the list's (top) indent + ordering; anything else stops\n\t\t// the top loop (a deeper item is a nested list, gathered as continuation below).\n\t\tif (!parsed || parsed.indent > topIndent || parsed.ordered !== ordered) break\n\t\tconst itemStart = index\n\t\tconst itemLine = lines[index]\n\t\tif (itemLine === undefined) break\n\t\tconst itemLines: MarkdownSource[] = [sliceSource(itemLine, parsed.marker, itemLine.text.length)]\n\t\tconst continuation = parsed.marker\n\t\tindex += 1\n\t\twhile (index < lines.length) {\n\t\t\tconst nextSource = lines[index]\n\t\t\tif (nextSource === undefined) break\n\t\t\tconst next = nextSource.text\n\t\t\tif (isBlankLine(next)) {\n\t\t\t\tconst after = lines[index + 1]?.text ?? ''\n\t\t\t\tif (index + 1 < lines.length && !isBlankLine(after) && countIndent(after) >= continuation) {\n\t\t\t\t\titemLines.push(sliceSource(nextSource, 0, 0))\n\t\t\t\t\tindex += 1\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif (countIndent(next) >= continuation) {\n\t\t\t\titemLines.push(sliceSource(nextSource, continuation, next.length))\n\t\t\t\tindex += 1\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (extractListItem(next) || startsBlock(text, index)) break\n\t\t\titemLines.push(trimSource(nextSource)) // a lazy paragraph-continuation line\n\t\t\tindex += 1\n\t\t}\n\t\tconst tail = itemLines[itemLines.length - 1]\n\t\tconst segment = tail?.segments[tail.segments.length - 1]\n\t\tconst itemEnd = index === lines.length && end !== undefined ? end : segment?.end\n\t\tconst item: ListItemNode = {\n\t\t\telement: 'listItem',\n\t\t\tchildren: parseBlocks(itemLines, depth + 1, spans, itemEnd),\n\t\t}\n\t\tconst source = joinSources(lines.slice(itemStart, index), '\\n')\n\t\tconst span = projectSpan(source, 0, source.text.length)\n\t\tif (span !== undefined) spans.set(item, span)\n\t\titems.push(item)\n\t}\n\tconst node: ListNode = { element: 'list', ordered, start: startOrdinal, items }\n\tconst source = joinSources(lines.slice(start, index), '\\n')\n\tconst span = projectSpan(source, 0, source.text.length)\n\tif (span !== undefined) spans.set(node, span)\n\treturn { node, next: index }\n}\n\n// Rendering (Markdown AST → HTML AST → sanitized HTML string)\n\n/**\n * Projects a {@link MarkdownNode} into an unsanitized {@link HTMLDocument}.\n *\n * @remarks\n * The projection is pure and iterative. Text and attribute values remain literal for\n * `@orkestrel/html` to encode, and URL values remain unsanitized so callers can choose\n * their own HTML policy. Projected HTML element depth, including generated `pre > code`\n * and table scaffolding, never exceeds {@link MAX_DEPTH}. At the cap a node carrying a\n * string `value` degrades to a text node and a structural node contributes nothing.\n *\n * @param node - The markdown document or bare node to project\n * @returns An unsanitized HTML document wrapping the projected node or nodes\n *\n * @example\n * ```ts\n * markdownToHTML({ element: 'text', value: 'a & b' })\n * // { category: 'document', children: [{ category: 'text', value: 'a & b' }] }\n * ```\n */\nexport function markdownToHTML(node: MarkdownNode): HTMLDocument {\n\tconst stack: Array<{\n\t\treadonly node: MarkdownNode\n\t\treadonly depth: number\n\t\treadonly expanded: boolean\n\t\treadonly count: number\n\t}> = [{ node, depth: 0, expanded: false, count: 0 }]\n\tconst values: Array<HTMLNode | undefined> = []\n\twhile (stack.length > 0) {\n\t\tconst frame = stack.pop()\n\t\tif (frame === undefined) continue\n\t\tconst current = frame.node\n\t\tif (!frame.expanded) {\n\t\t\tif (frame.depth >= MAX_DEPTH) {\n\t\t\t\tvalues.push(\n\t\t\t\t\t'value' in current && typeof current.value === 'string'\n\t\t\t\t\t\t? { category: 'text', value: current.value }\n\t\t\t\t\t\t: undefined,\n\t\t\t\t)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst children: MarkdownNode[] = []\n\t\t\tlet depth = frame.depth\n\t\t\tswitch (current.element) {\n\t\t\t\tcase 'document':\n\t\t\t\t\tfor (const child of current.children) if (child !== undefined) children.push(child)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'heading':\n\t\t\t\tcase 'paragraph':\n\t\t\t\tcase 'blockquote':\n\t\t\t\t\tfor (const child of current.children) if (child !== undefined) children.push(child)\n\t\t\t\t\tdepth += 1\n\t\t\t\t\tbreak\n\t\t\t\tcase 'listItem': {\n\t\t\t\t\tconst only = current.children[0]\n\t\t\t\t\tif (current.children.length === 1 && only !== undefined && only.element === 'paragraph') {\n\t\t\t\t\t\tfor (const child of only.children) if (child !== undefined) children.push(child)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor (const child of current.children) if (child !== undefined) children.push(child)\n\t\t\t\t\t}\n\t\t\t\t\tdepth += 1\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'emphasis':\n\t\t\t\tcase 'link':\n\t\t\t\t\tfor (const child of current.children) if (child !== undefined) children.push(child)\n\t\t\t\t\tdepth += 1\n\t\t\t\t\tbreak\n\t\t\t\tcase 'list':\n\t\t\t\t\tfor (const child of current.items) if (child !== undefined) children.push(child)\n\t\t\t\t\tdepth += 1\n\t\t\t\t\tbreak\n\t\t\t\tcase 'table':\n\t\t\t\t\tif (frame.depth + 4 > MAX_DEPTH) {\n\t\t\t\t\t\tvalues.push(undefined)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tfor (const cell of current.header)\n\t\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\t\tfor (const row of current.rows)\n\t\t\t\t\t\tif (row !== undefined)\n\t\t\t\t\t\t\tfor (const cell of row)\n\t\t\t\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\t\tdepth += 4\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t\tif (current.element === 'codeBlock' && frame.depth + 2 > MAX_DEPTH) {\n\t\t\t\tvalues.push(undefined)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tstack.push({ ...frame, expanded: true, count: children.length })\n\t\t\tfor (let index = children.length - 1; index >= 0; index -= 1) {\n\t\t\t\tconst child = children[index]\n\t\t\t\tif (child !== undefined) stack.push({ node: child, depth, expanded: false, count: 0 })\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tconst children =\n\t\t\tframe.count === 0 ? [] : values.splice(values.length - frame.count, frame.count)\n\t\tconst projected: HTMLNode[] = []\n\t\tfor (const child of children) if (child !== undefined) projected.push(child)\n\t\tlet value: HTMLNode | undefined\n\t\tswitch (current.element) {\n\t\t\tcase 'document':\n\t\t\t\tvalue = { category: 'document', children: projected }\n\t\t\t\tbreak\n\t\t\tcase 'heading':\n\t\t\t\tvalue = {\n\t\t\t\t\tcategory: 'element',\n\t\t\t\t\tname: `h${current.level}`,\n\t\t\t\t\tattributes: [],\n\t\t\t\t\tchildren: projected,\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'paragraph':\n\t\t\t\tvalue = { category: 'element', name: 'p', attributes: [], children: projected }\n\t\t\t\tbreak\n\t\t\tcase 'thematicBreak':\n\t\t\t\tvalue = { category: 'element', name: 'hr', attributes: [], children: [] }\n\t\t\t\tbreak\n\t\t\tcase 'blockquote':\n\t\t\t\tvalue = {\n\t\t\t\t\tcategory: 'element',\n\t\t\t\t\tname: 'blockquote',\n\t\t\t\t\tattributes: [],\n\t\t\t\t\tchildren: projected,\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'codeBlock':\n\t\t\t\tvalue = {\n\t\t\t\t\tcategory: 'element',\n\t\t\t\t\tname: 'pre',\n\t\t\t\t\tattributes: [],\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcategory: 'element',\n\t\t\t\t\t\t\tname: 'code',\n\t\t\t\t\t\t\tattributes:\n\t\t\t\t\t\t\t\tcurrent.lang === undefined\n\t\t\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t\t\t: [{ name: 'class', value: `language-${current.lang}` }],\n\t\t\t\t\t\t\tchildren: [{ category: 'text', value: current.code }],\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'list':\n\t\t\t\tvalue = {\n\t\t\t\t\tcategory: 'element',\n\t\t\t\t\tname: current.ordered ? 'ol' : 'ul',\n\t\t\t\t\tattributes:\n\t\t\t\t\t\tcurrent.ordered && current.start !== 1\n\t\t\t\t\t\t\t? [{ name: 'start', value: String(current.start) }]\n\t\t\t\t\t\t\t: [],\n\t\t\t\t\tchildren: projected,\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'listItem':\n\t\t\t\tvalue = { category: 'element', name: 'li', attributes: [], children: projected }\n\t\t\t\tbreak\n\t\t\tcase 'table': {\n\t\t\t\tlet offset = 0\n\t\t\t\tconst header: HTMLNode[] = []\n\t\t\t\tfor (const [column, cell] of current.header.entries()) {\n\t\t\t\t\tif (cell === undefined) continue\n\t\t\t\t\tconst align = current.align[column]\n\t\t\t\t\tconst attributes =\n\t\t\t\t\t\talign === 'left' || align === 'right' || align === 'center'\n\t\t\t\t\t\t\t? [{ name: 'align', value: align }]\n\t\t\t\t\t\t\t: []\n\t\t\t\t\tlet count = 0\n\t\t\t\t\tfor (const child of cell) if (child !== undefined) count += 1\n\t\t\t\t\tconst cellChildren: HTMLNode[] = []\n\t\t\t\t\tfor (const child of children.slice(offset, offset + count))\n\t\t\t\t\t\tif (child !== undefined) cellChildren.push(child)\n\t\t\t\t\theader.push({\n\t\t\t\t\t\tcategory: 'element',\n\t\t\t\t\t\tname: 'th',\n\t\t\t\t\t\tattributes,\n\t\t\t\t\t\tchildren: cellChildren,\n\t\t\t\t\t})\n\t\t\t\t\toffset += count\n\t\t\t\t}\n\t\t\t\tconst rows: HTMLNode[] = []\n\t\t\t\tfor (const row of current.rows) {\n\t\t\t\t\tconst cells: HTMLNode[] = []\n\t\t\t\t\tfor (const [column, cell] of row.entries()) {\n\t\t\t\t\t\tif (cell === undefined) continue\n\t\t\t\t\t\tconst align = current.align[column]\n\t\t\t\t\t\tconst attributes =\n\t\t\t\t\t\t\talign === 'left' || align === 'right' || align === 'center'\n\t\t\t\t\t\t\t\t? [{ name: 'align', value: align }]\n\t\t\t\t\t\t\t\t: []\n\t\t\t\t\t\tlet count = 0\n\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) count += 1\n\t\t\t\t\t\tconst cellChildren: HTMLNode[] = []\n\t\t\t\t\t\tfor (const child of children.slice(offset, offset + count))\n\t\t\t\t\t\t\tif (child !== undefined) cellChildren.push(child)\n\t\t\t\t\t\tcells.push({\n\t\t\t\t\t\t\tcategory: 'element',\n\t\t\t\t\t\t\tname: 'td',\n\t\t\t\t\t\t\tattributes,\n\t\t\t\t\t\t\tchildren: cellChildren,\n\t\t\t\t\t\t})\n\t\t\t\t\t\toffset += count\n\t\t\t\t\t}\n\t\t\t\t\trows.push({\n\t\t\t\t\t\tcategory: 'element',\n\t\t\t\t\t\tname: 'tr',\n\t\t\t\t\t\tattributes: [],\n\t\t\t\t\t\tchildren: cells,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tconst tableChildren: HTMLNode[] = [\n\t\t\t\t\t{\n\t\t\t\t\t\tcategory: 'element',\n\t\t\t\t\t\tname: 'thead',\n\t\t\t\t\t\tattributes: [],\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcategory: 'element',\n\t\t\t\t\t\t\t\tname: 'tr',\n\t\t\t\t\t\t\t\tattributes: [],\n\t\t\t\t\t\t\t\tchildren: header,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t\tif (isNonEmptyArray(current.rows)) {\n\t\t\t\t\ttableChildren.push({\n\t\t\t\t\t\tcategory: 'element',\n\t\t\t\t\t\tname: 'tbody',\n\t\t\t\t\t\tattributes: [],\n\t\t\t\t\t\tchildren: rows,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tvalue = {\n\t\t\t\t\tcategory: 'element',\n\t\t\t\t\tname: 'table',\n\t\t\t\t\tattributes: [],\n\t\t\t\t\tchildren: tableChildren,\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'text':\n\t\t\t\tvalue = { category: 'text', value: current.value }\n\t\t\t\tbreak\n\t\t\tcase 'emphasis':\n\t\t\t\tvalue = {\n\t\t\t\t\tcategory: 'element',\n\t\t\t\t\tname: current.strong ? 'strong' : 'em',\n\t\t\t\t\tattributes: [],\n\t\t\t\t\tchildren: projected,\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'codeSpan':\n\t\t\t\tvalue = {\n\t\t\t\t\tcategory: 'element',\n\t\t\t\t\tname: 'code',\n\t\t\t\t\tattributes: [],\n\t\t\t\t\tchildren: [{ category: 'text', value: current.value }],\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'link':\n\t\t\t\tvalue = {\n\t\t\t\t\tcategory: 'element',\n\t\t\t\t\tname: 'a',\n\t\t\t\t\tattributes: [{ name: 'href', value: current.href }],\n\t\t\t\t\tchildren: projected,\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'image':\n\t\t\t\tvalue = {\n\t\t\t\t\tcategory: 'element',\n\t\t\t\t\tname: 'img',\n\t\t\t\t\tattributes: [\n\t\t\t\t\t\t{ name: 'src', value: current.src },\n\t\t\t\t\t\t{ name: 'alt', value: flattenText(current) },\n\t\t\t\t\t],\n\t\t\t\t\tchildren: [],\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'break':\n\t\t\t\tvalue = { category: 'element', name: 'br', attributes: [], children: [] }\n\t\t\t\tbreak\n\t\t\tdefault:\n\t\t\t\tvalue = undefined\n\t\t\t\tbreak\n\t\t}\n\t\tvalues.push(value)\n\t}\n\tconst projected = values[0]\n\tif (projected?.category === 'document') return projected\n\treturn {\n\t\tcategory: 'document',\n\t\tchildren: projected === undefined ? [] : [projected],\n\t}\n}\n\n/**\n * Renders a {@link MarkdownNode} to its canonical markdown source — the inverse\n * projection of `renderHTML`. It is the serializer a `parse(renderMarkdown(doc))`\n * round-trip is built on. Canonical forms: `*` / `**` emphasis at even emphasis\n * nesting depths and `_` / `__` at odd depths, `- ` bullets, `N. ` sequential\n * ordinals (from the list's `start`), `---` thematic breaks, fenced code blocks\n * (backtick run widened past any 3+ backtick run inside the body), ATX headings,\n * `> `-prefixed blockquote lines, GFM tables (1-space-padded cells, a backslash\n * before each literal pipe, an alignment delimiter row), `[text](href)` links,\n * `![alt](src)` images, and two-space hard breaks. A `text` node's literal content is backslash-escaped\n * wherever it would otherwise re-parse as markup, so parsing the rendered source\n * returns the node it was rendered from.\n *\n * @remarks\n * Total: never throws. At {@link MAX_DEPTH} a value-bearing node degrades to its\n * escaped `value`; any other node degrades to `''`. Blocks are joined by exactly one\n * blank line; a document with zero blocks renders `''`.\n *\n * @param node - The AST node to render (a full document, or any sub-node)\n * @returns The canonical markdown source\n *\n * @example\n * ```ts\n * renderMarkdown({ element: 'document', children: [\n * { element: 'heading', level: 2, children: [{ element: 'text', value: 'Hi' }] },\n * ] })\n * // '## Hi'\n * ```\n */\nexport function renderMarkdown(node: MarkdownNode): string {\n\tconst stack: Array<{\n\t\treadonly node: MarkdownNode\n\t\treadonly depth: number\n\t\treadonly expanded: boolean\n\t\treadonly count: number\n\t\treadonly escaped: string\n\t\treadonly escapeBang: boolean\n\t\treadonly nesting: number\n\t}> = [\n\t\t{\n\t\t\tnode,\n\t\t\tdepth: 0,\n\t\t\texpanded: false,\n\t\t\tcount: 0,\n\t\t\tescaped: '',\n\t\t\tescapeBang: false,\n\t\t\tnesting: 0,\n\t\t},\n\t]\n\tconst values: string[] = []\n\twhile (stack.length > 0) {\n\t\tconst frame = stack.pop()\n\t\tif (frame === undefined) continue\n\t\tconst current = frame.node\n\t\tif (!frame.expanded) {\n\t\t\tlet escaped = ''\n\t\t\tif (\n\t\t\t\t(frame.depth >= MAX_DEPTH || current.element === 'text') &&\n\t\t\t\t'value' in current &&\n\t\t\t\ttypeof current.value === 'string'\n\t\t\t) {\n\t\t\t\tfor (let index = 0; index < current.value.length; index += 1) {\n\t\t\t\t\tconst character = current.value[index] ?? ''\n\t\t\t\t\tconst atLineStart = index === 0 || current.value[index - 1] === '\\n'\n\t\t\t\t\tif (\n\t\t\t\t\t\tcurrent.element === 'text' &&\n\t\t\t\t\t\tcharacter === '!' &&\n\t\t\t\t\t\tindex === current.value.length - 1 &&\n\t\t\t\t\t\tframe.escapeBang\n\t\t\t\t\t) {\n\t\t\t\t\t\tescaped += '\\\\!'\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif (\n\t\t\t\t\t\tcharacter === '\\\\' ||\n\t\t\t\t\t\tcharacter === '*' ||\n\t\t\t\t\t\tcharacter === '_' ||\n\t\t\t\t\t\tcharacter === '`' ||\n\t\t\t\t\t\tcharacter === '[' ||\n\t\t\t\t\t\tcharacter === ']'\n\t\t\t\t\t) {\n\t\t\t\t\t\tescaped += `\\\\${character}`\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif (atLineStart) {\n\t\t\t\t\t\tif (character === '#' || character === '>') {\n\t\t\t\t\t\t\tescaped += `\\\\${character}`\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t(character === '-' || character === '~') &&\n\t\t\t\t\t\t\tcurrent.value[index + 1] === character &&\n\t\t\t\t\t\t\tcurrent.value[index + 2] === character\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tescaped += `\\\\${character}`\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t(character === '-' || character === '+') &&\n\t\t\t\t\t\t\t(current.value[index + 1] ?? ' ') === ' '\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tescaped += `\\\\${character}`\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (/[0-9]/.test(character)) {\n\t\t\t\t\t\t\tlet end = index\n\t\t\t\t\t\t\twhile (end < current.value.length && /[0-9]/.test(current.value[end] ?? '')) end += 1\n\t\t\t\t\t\t\tconst marker = current.value[end]\n\t\t\t\t\t\t\tif ((marker === '.' || marker === ')') && current.value[end + 1] === ' ') {\n\t\t\t\t\t\t\t\tescaped += `${current.value.slice(index, end)}\\\\${marker}`\n\t\t\t\t\t\t\t\tindex = end\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tescaped += character\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (frame.depth >= MAX_DEPTH) {\n\t\t\t\tvalues.push(escaped)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst groups: Array<readonly MarkdownNode[]> = []\n\t\t\tconst adjacent: boolean[] = []\n\t\t\tlet depth = frame.depth + 1\n\t\t\tswitch (current.element) {\n\t\t\t\tcase 'document':\n\t\t\t\tcase 'blockquote':\n\t\t\t\tcase 'listItem':\n\t\t\t\t\tgroups.push(current.children)\n\t\t\t\t\tadjacent.push(false)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'heading':\n\t\t\t\tcase 'paragraph':\n\t\t\t\tcase 'emphasis':\n\t\t\t\tcase 'link':\n\t\t\t\tcase 'image':\n\t\t\t\t\tgroups.push(current.children)\n\t\t\t\t\tadjacent.push(true)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'list':\n\t\t\t\t\tgroups.push(current.items)\n\t\t\t\t\tadjacent.push(false)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'table':\n\t\t\t\t\tfor (const cell of current.header)\n\t\t\t\t\t\tif (cell !== undefined) {\n\t\t\t\t\t\t\tgroups.push(cell)\n\t\t\t\t\t\t\tadjacent.push(true)\n\t\t\t\t\t\t}\n\t\t\t\t\tfor (const row of current.rows) {\n\t\t\t\t\t\tif (row === undefined) continue\n\t\t\t\t\t\tfor (let column = 0; column < current.header.length; column += 1) {\n\t\t\t\t\t\t\tconst cell = row[column]\n\t\t\t\t\t\t\tif (cell !== undefined) {\n\t\t\t\t\t\t\t\tgroups.push(cell)\n\t\t\t\t\t\t\t\tadjacent.push(true)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdepth += 1\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t\tconst children: MarkdownNode[] = []\n\t\t\tconst escapeBangs: boolean[] = []\n\t\t\tfor (let groupIndex = 0; groupIndex < groups.length; groupIndex += 1) {\n\t\t\t\tconst group = groups[groupIndex]\n\t\t\t\tif (group === undefined) continue\n\t\t\t\tfor (let position = 0; position < group.length; position += 1) {\n\t\t\t\t\tconst child = group[position]\n\t\t\t\t\tif (child === undefined) continue\n\t\t\t\t\tlet escapeBang = false\n\t\t\t\t\tif (adjacent[groupIndex] === true) {\n\t\t\t\t\t\tlet nextPosition = position + 1\n\t\t\t\t\t\tlet next = group[nextPosition]\n\t\t\t\t\t\twhile (next === undefined && nextPosition < group.length) {\n\t\t\t\t\t\t\tnextPosition += 1\n\t\t\t\t\t\t\tnext = group[nextPosition]\n\t\t\t\t\t\t}\n\t\t\t\t\t\tescapeBang = next?.element === 'link'\n\t\t\t\t\t}\n\t\t\t\t\tchildren.push(child)\n\t\t\t\t\tescapeBangs.push(escapeBang)\n\t\t\t\t}\n\t\t\t}\n\t\t\tstack.push({ ...frame, expanded: true, count: children.length, escaped })\n\t\t\tconst nesting = current.element === 'emphasis' ? frame.nesting + 1 : frame.nesting\n\t\t\tfor (let index = children.length - 1; index >= 0; index -= 1) {\n\t\t\t\tconst child = children[index]\n\t\t\t\tif (child !== undefined)\n\t\t\t\t\tstack.push({\n\t\t\t\t\t\tnode: child,\n\t\t\t\t\t\tdepth,\n\t\t\t\t\t\texpanded: false,\n\t\t\t\t\t\tcount: 0,\n\t\t\t\t\t\tescaped: '',\n\t\t\t\t\t\tescapeBang: escapeBangs[index] === true && depth < MAX_DEPTH,\n\t\t\t\t\t\tnesting,\n\t\t\t\t\t})\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tconst children =\n\t\t\tframe.count === 0 ? [] : values.splice(values.length - frame.count, frame.count)\n\t\tlet value = ''\n\t\tswitch (current.element) {\n\t\t\tcase 'codeBlock':\n\t\t\tcase 'codeSpan': {\n\t\t\t\tconst body = current.element === 'codeBlock' ? current.code : current.value\n\t\t\t\tlet longest = 0\n\t\t\t\tlet run = 0\n\t\t\t\tfor (const character of body) {\n\t\t\t\t\tif (character === '`') {\n\t\t\t\t\t\trun += 1\n\t\t\t\t\t\tlongest = Math.max(longest, run)\n\t\t\t\t\t} else {\n\t\t\t\t\t\trun = 0\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst fence = '`'.repeat(Math.max(current.element === 'codeBlock' ? 3 : 1, longest + 1))\n\t\t\t\tif (current.element === 'codeBlock') {\n\t\t\t\t\tconst lang = current.lang === undefined ? '' : current.lang\n\t\t\t\t\tvalue = `${fence}${lang}\\n${current.code}\\n${fence}`\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tconst pad = current.value.startsWith('`') || current.value.endsWith('`') ? ' ' : ''\n\t\t\t\tvalue = `${fence}${pad}${current.value}${pad}${fence}`\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'break':\n\t\t\t\tvalue = ' \\n'\n\t\t\t\tbreak\n\t\t\tcase 'document':\n\t\t\t\tvalue = children.join('\\n\\n')\n\t\t\t\tbreak\n\t\t\tcase 'heading': {\n\t\t\t\tconst text = children.join('')\n\t\t\t\tconst escaped = text.replace(/(^|[^\\\\])(#+)$/, (_match, before: string, hashes: string) => {\n\t\t\t\t\tconst first = hashes[0] ?? ''\n\t\t\t\t\treturn `${before}\\\\${first}${hashes.slice(1)}`\n\t\t\t\t})\n\t\t\t\tvalue = `${'#'.repeat(current.level)} ${escaped}`\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'paragraph':\n\t\t\t\tvalue = children.join('')\n\t\t\t\tbreak\n\t\t\tcase 'thematicBreak':\n\t\t\t\tvalue = '---'\n\t\t\t\tbreak\n\t\t\tcase 'blockquote':\n\t\t\t\tvalue = children\n\t\t\t\t\t.join('\\n\\n')\n\t\t\t\t\t.split('\\n')\n\t\t\t\t\t.map((line) => (line === '' ? '>' : `> ${line}`))\n\t\t\t\t\t.join('\\n')\n\t\t\t\tbreak\n\t\t\tcase 'list': {\n\t\t\t\tconst items: string[] = []\n\t\t\t\tlet ordinal = current.start\n\t\t\t\tfor (const [position, body] of children.entries()) {\n\t\t\t\t\tconst marker = current.ordered ? `${ordinal}. ` : '- '\n\t\t\t\t\tordinal += 1\n\t\t\t\t\tconst pad = ' '.repeat(marker.length)\n\t\t\t\t\tif (current.items[position]?.children[0]?.element === 'table') {\n\t\t\t\t\t\titems.push(\n\t\t\t\t\t\t\t`${marker}\\n${body\n\t\t\t\t\t\t\t\t.split('\\n')\n\t\t\t\t\t\t\t\t.map((line) => pad + line)\n\t\t\t\t\t\t\t\t.join('\\n')}`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\titems.push(\n\t\t\t\t\t\tbody\n\t\t\t\t\t\t\t.split('\\n')\n\t\t\t\t\t\t\t.map((line, index) => (index === 0 ? marker + line : line === '' ? '' : pad + line))\n\t\t\t\t\t\t\t.join('\\n'),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tvalue = items.join('\\n')\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'listItem':\n\t\t\t\tvalue = children.join('\\n\\n')\n\t\t\t\tbreak\n\t\t\tcase 'table': {\n\t\t\t\tlet offset = 0\n\t\t\t\tconst header: string[] = []\n\t\t\t\tfor (const cell of current.header) {\n\t\t\t\t\tif (cell === undefined) {\n\t\t\t\t\t\theader.push('')\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tlet count = 0\n\t\t\t\t\tfor (const child of cell) if (child !== undefined) count += 1\n\t\t\t\t\theader.push(\n\t\t\t\t\t\tchildren\n\t\t\t\t\t\t\t.slice(offset, offset + count)\n\t\t\t\t\t\t\t.join('')\n\t\t\t\t\t\t\t.replace(/\\|/g, '\\\\|'),\n\t\t\t\t\t)\n\t\t\t\t\toffset += count\n\t\t\t\t}\n\t\t\t\tconst delimiter = current.align.map((align) => {\n\t\t\t\t\tif (align === null) return '---'\n\t\t\t\t\tif (align === 'left') return ':---'\n\t\t\t\t\tif (align === 'right') return '---:'\n\t\t\t\t\tif (align === 'center') return ':---:'\n\t\t\t\t\treturn '---'\n\t\t\t\t})\n\t\t\t\tconst rows: string[] = []\n\t\t\t\tfor (const row of current.rows) {\n\t\t\t\t\tconst cells: string[] = []\n\t\t\t\t\tfor (let column = 0; column < current.header.length; column += 1) {\n\t\t\t\t\t\tconst cell = row[column]\n\t\t\t\t\t\tif (cell === undefined) {\n\t\t\t\t\t\t\tcells.push('')\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlet count = 0\n\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) count += 1\n\t\t\t\t\t\tcells.push(\n\t\t\t\t\t\t\tchildren\n\t\t\t\t\t\t\t\t.slice(offset, offset + count)\n\t\t\t\t\t\t\t\t.join('')\n\t\t\t\t\t\t\t\t.replace(/\\|/g, '\\\\|'),\n\t\t\t\t\t\t)\n\t\t\t\t\t\toffset += count\n\t\t\t\t\t}\n\t\t\t\t\trows.push(`| ${cells.join(' | ')} |`)\n\t\t\t\t}\n\t\t\t\tvalue = [`| ${header.join(' | ')} |`, `| ${delimiter.join(' | ')} |`, ...rows].join('\\n')\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'text':\n\t\t\t\tvalue = frame.escaped\n\t\t\t\tbreak\n\t\t\tcase 'emphasis': {\n\t\t\t\tconst marker =\n\t\t\t\t\tframe.nesting % 2 === 0 ? (current.strong ? '**' : '*') : current.strong ? '__' : '_'\n\t\t\t\tvalue = `${marker}${children.join('')}${marker}`\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'link':\n\t\t\tcase 'image': {\n\t\t\t\tconst destination = current.element === 'link' ? current.href : current.src\n\t\t\t\tconst escaped = destination.replace(/[\\\\()]/g, (character) => `\\\\${character}`)\n\t\t\t\tconst prefix = current.element === 'image' ? '!' : ''\n\t\t\t\tvalue = `${prefix}[${children.join('')}](${escaped})`\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tvalue = ''\n\t\t\t\tbreak\n\t\t}\n\t\tif (stack.length === 0) return value\n\t\tvalues.push(value)\n\t}\n\treturn ''\n}\n\n// Projection (HTML AST → Markdown AST)\n//\n// The inverse of {@link markdownToHTML}, and the reason markdown owns both\n// directions: what an HTML subtree becomes is markdown-format knowledge, not HTML\n// knowledge. The engine is `@orkestrel/html`'s own `foldNode` catamorphism — it\n// already owns depth capping, cycle safety, and bottom-up folding — so this file\n// contributes only the projection: five pure leaves over {@link MarkdownProjection}\n// values ({@link trimInlines}, {@link normalizeInlines}, {@link mergeProjections},\n// {@link projectionToBlocks}, {@link projectionToInlines}), the two handlers that\n// map HTML to markdown ({@link projectHTMLLeaf}, {@link projectHTMLNode}), and the one\n// entry point that folds them ({@link htmlToMarkdown}). HTML is richer than\n// markdown, so the projection is lossy by construction; what it must never be is\n// wrong, which is what the round-trip anchor law pins down. {@link createProjection}\n// builds those values: it constructs a plain record under an invariant rather than an\n// entity, so it is a leaf here and not a factory.\n\n/**\n * Builds an HTML-to-markdown projection with absent fields defaulted from\n * {@link EMPTY_PROJECTION} and the block/inline exclusivity invariant enforced.\n *\n * @remarks\n * A block-bearing projection cannot also expose inline content. Callers may provide\n * both views, but `inlines` is flushed whenever `blocks` is non-empty.\n *\n * @param parts - The projection fields to provide\n * @returns A complete invariant-preserving projection\n *\n * @example\n * ```ts\n * createProjection({\n * blocks: [{ element: 'thematicBreak' }],\n * inlines: [{ element: 'text', value: 'discarded' }],\n * })\n * // { blocks: [{ element: 'thematicBreak' }], inlines: [], text: '', cells: [], rows: [] }\n * ```\n */\nexport function createProjection(parts: Partial<MarkdownProjection> = {}): MarkdownProjection {\n\tconst blocks = parts.blocks ?? EMPTY_PROJECTION.blocks\n\treturn {\n\t\tblocks,\n\t\tinlines: blocks.length === 0 ? (parts.inlines ?? EMPTY_PROJECTION.inlines) : [],\n\t\ttext: parts.text ?? EMPTY_PROJECTION.text,\n\t\tcells: parts.cells ?? EMPTY_PROJECTION.cells,\n\t\trows: parts.rows ?? EMPTY_PROJECTION.rows,\n\t}\n}\n\n/**\n * Trims the whitespace at the two ends of an inline run — the leading whitespace of a\n * leading text node and the trailing whitespace of a trailing one — dropping either\n * node when nothing survives.\n *\n * @remarks\n * Markdown trims every line of a paragraph, a heading's text, and a table cell, so an\n * untrimmed run would come back from a re-parse a different AST. Expects a coalesced\n * run (see {@link coalesceText}): only the outermost node on each side is examined.\n *\n * @param nodes - The inline run to trim\n * @returns The run with its edge whitespace removed\n *\n * @example\n * ```ts\n * trimInlines([{ element: 'text', value: ' a ' }]) // [{ element: 'text', value: 'a' }]\n * ```\n */\nexport function trimInlines(nodes: readonly InlineNode[]): readonly InlineNode[] {\n\tconst out: InlineNode[] = []\n\tfor (const node of nodes) if (node !== undefined) out.push(node)\n\tconst first = out[0]\n\tif (first !== undefined && first.element === 'text') {\n\t\tconst value = first.value.replace(/^\\s+/, '')\n\t\tif (isEmptyString(value)) out.shift()\n\t\telse out[0] = { element: 'text', value }\n\t}\n\tconst last = out[out.length - 1]\n\tif (last !== undefined && last.element === 'text') {\n\t\tconst value = last.value.replace(/\\s+$/, '')\n\t\tif (isEmptyString(value)) out.pop()\n\t\telse out[out.length - 1] = { element: 'text', value }\n\t}\n\treturn out\n}\n\n/**\n * Reduces an inline run to the shape markdown can actually write back: adjacent text\n * coalesced, empty text dropped, and every hard break either kept as a real line\n * ending or spent as a space.\n *\n * @remarks\n * A hard break is ` \\n` in markdown source, so it survives a re-parse only between\n * two lines of content and only with no whitespace touching it: a leading or trailing\n * break has no line to end, a run of breaks reads as one blank line (which would end\n * the paragraph), and a space beside one is eaten by the parser's line trimming. Where\n * a break cannot be written at all — a heading and a table cell are one line each — it\n * becomes the space it stood for.\n *\n * @param nodes - The inline run to normalize\n * @param breaks - If `true`, keeps each hard break as a real line ending; if `false`, spends\n * every break as the space it stood for, as a heading or a table cell requires\n * @returns The normalized run\n *\n * @example\n * ```ts\n * normalizeInlines([{ element: 'break' }, { element: 'text', value: 'a' }], true)\n * // [{ element: 'text', value: 'a' }] - a leading break has no line to end\n * ```\n */\nexport function normalizeInlines(\n\tnodes: readonly InlineNode[],\n\tbreaks: boolean,\n): readonly InlineNode[] {\n\tconst spent: InlineNode[] = []\n\tfor (const node of nodes) {\n\t\tif (node === undefined) continue\n\t\tif (node.element === 'break' && !breaks) spent.push({ element: 'text', value: ' ' })\n\t\telse spent.push(node)\n\t}\n\tconst out: InlineNode[] = []\n\tfor (const node of coalesceText(spent)) {\n\t\tif (node === undefined) continue\n\t\tconst previous = out[out.length - 1]\n\t\tif (node.element === 'text') {\n\t\t\tconst value = previous?.element === 'break' ? node.value.replace(/^\\s+/, '') : node.value\n\t\t\tif (!isEmptyString(value)) out.push({ element: 'text', value })\n\t\t\tcontinue\n\t\t}\n\t\tif (node.element === 'break') {\n\t\t\tif (previous === undefined || previous.element === 'break') continue\n\t\t\tif (previous.element === 'text') {\n\t\t\t\tconst value = previous.value.replace(/\\s+$/, '')\n\t\t\t\tif (isEmptyString(value)) out.pop()\n\t\t\t\telse out[out.length - 1] = { element: 'text', value }\n\t\t\t}\n\t\t\tif (out.length === 0) continue\n\t\t\tout.push(node)\n\t\t\tcontinue\n\t\t}\n\t\tout.push(node)\n\t}\n\twhile (out.length > 0 && out[out.length - 1]?.element === 'break') out.pop()\n\treturn coalesceText(out)\n}\n\n/**\n * Combines the projections of one node's children into the projection of that node —\n * the single place inline runs become paragraphs, so no ancestor has to decide it\n * twice.\n *\n * @remarks\n * A child is either inline or block, never both, so merging preserves source order\n * exactly: an inline run is held pending until a block arrives, then written out as a\n * paragraph before it. That is what keeps `<div>lead<p>a</p></div>` two paragraphs in\n * the order they were written rather than two lists that lost their interleaving. A\n * pending run carrying no text is dropped rather than becoming a blank paragraph.\n * Direct cells become one row before a later row, while cells/rows before a block\n * materialize as paragraphs at that exact source position.\n *\n * @param children - The children's projections, in source order\n * @returns Their combined projection\n *\n * @example\n * ```ts\n * mergeProjections([\n * createProjection({ inlines: [{ element: 'text', value: 'a' }], text: 'a' }),\n * createProjection({ blocks: [{ element: 'thematicBreak' }] }),\n * ]).blocks\n * // [{ element: 'paragraph', children: [...] }, { element: 'thematicBreak' }]\n * ```\n */\nexport function mergeProjections(children: readonly MarkdownProjection[]): MarkdownProjection {\n\tconst blocks: BlockNode[] = []\n\tconst cells: MarkdownCell[] = []\n\tconst rows: Array<readonly MarkdownCell[]> = []\n\tlet pending: InlineNode[] = []\n\tlet text = ''\n\tfor (const child of children) {\n\t\tif (child === undefined) continue\n\t\ttext += child.text\n\t\tif (isNonEmptyArray(child.blocks)) {\n\t\t\tconst flushed = trimInlines(normalizeInlines(pending, true))\n\t\t\tif (isNonEmptyArray(flushed)) blocks.push({ element: 'paragraph', children: flushed })\n\t\t\tpending = []\n\t\t\tfor (const row of rows) {\n\t\t\t\tfor (const cell of row) {\n\t\t\t\t\tif (cell !== undefined && isNonEmptyArray(cell.inlines))\n\t\t\t\t\t\tblocks.push({ element: 'paragraph', children: cell.inlines })\n\t\t\t\t}\n\t\t\t}\n\t\t\trows.length = 0\n\t\t\tfor (const cell of cells) {\n\t\t\t\tif (cell !== undefined && isNonEmptyArray(cell.inlines))\n\t\t\t\t\tblocks.push({ element: 'paragraph', children: cell.inlines })\n\t\t\t}\n\t\t\tcells.length = 0\n\t\t\tfor (const block of projectionToBlocks(child)) blocks.push(block)\n\t\t\tcontinue\n\t\t}\n\t\tif (isNonEmptyArray(child.rows)) {\n\t\t\tif (isNonEmptyArray(cells)) {\n\t\t\t\trows.push([...cells])\n\t\t\t\tcells.length = 0\n\t\t\t}\n\t\t\tfor (const row of child.rows) if (row !== undefined) rows.push(row)\n\t\t}\n\t\tfor (const cell of child.cells) if (cell !== undefined) cells.push(cell)\n\t\tfor (const inline of child.inlines) if (inline !== undefined) pending.push(inline)\n\t}\n\tif (isNonEmptyArray(rows) && isNonEmptyArray(cells)) {\n\t\trows.push([...cells])\n\t\tcells.length = 0\n\t}\n\tif (!isNonEmptyArray(blocks))\n\t\treturn createProjection({ inlines: coalesceText(pending), text, cells, rows })\n\tconst flushed = trimInlines(normalizeInlines(pending, true))\n\tif (isNonEmptyArray(flushed)) blocks.push({ element: 'paragraph', children: flushed })\n\treturn createProjection({ blocks, text, cells, rows })\n}\n\n/**\n * Reads a projection as block content — the view a document, a blockquote, and a list\n * item each need.\n *\n * @remarks\n * A bare inline run becomes one paragraph, and a run carrying no text becomes nothing\n * at all, because a blank paragraph is unwritable in markdown. A cell or a row that\n * never reached a table is unwrapped here rather than dropped: a stray `<td>` is still\n * someone's content.\n *\n * @param projection - The projection to read\n * @returns Its block content\n *\n * @example\n * ```ts\n * projectionToBlocks(createProjection({ inlines: [{ element: 'text', value: 'a' }], text: 'a' }))\n * // [{ element: 'paragraph', children: [{ element: 'text', value: 'a' }] }]\n * ```\n */\nexport function projectionToBlocks(projection: MarkdownProjection): readonly BlockNode[] {\n\tconst blocks: BlockNode[] = []\n\tfor (const block of projection.blocks) if (block !== undefined) blocks.push(block)\n\tfor (const row of projection.rows) {\n\t\tif (row === undefined) continue\n\t\tfor (const cell of row) {\n\t\t\tif (cell === undefined || !isNonEmptyArray(cell.inlines)) continue\n\t\t\tblocks.push({ element: 'paragraph', children: cell.inlines })\n\t\t}\n\t}\n\tfor (const cell of projection.cells) {\n\t\tif (cell === undefined || !isNonEmptyArray(cell.inlines)) continue\n\t\tblocks.push({ element: 'paragraph', children: cell.inlines })\n\t}\n\tconst paragraph = trimInlines(normalizeInlines(projection.inlines, true))\n\tif (isNonEmptyArray(paragraph)) blocks.push({ element: 'paragraph', children: paragraph })\n\treturn blocks\n}\n\n/**\n * Reads a projection as inline content — the view a link, an emphasis, and a table cell\n * each need.\n *\n * @remarks\n * Inline content passes through as itself. Block content cannot: markdown has no way to\n * put a paragraph inside a table cell, so it flattens to one text node of its own words,\n * joined and whitespace-collapsed. Content that carries no text flattens to nothing\n * rather than to an empty text node, which is a shape the parser never produces.\n *\n * @param projection - The projection to read\n * @returns Its inline content\n *\n * @example\n * ```ts\n * projectionToInlines(createProjection({ inlines: [{ element: 'break' }] }))\n * // [{ element: 'break' }]\n * ```\n */\nexport function projectionToInlines(projection: MarkdownProjection): readonly InlineNode[] {\n\tif (\n\t\t!isNonEmptyArray(projection.blocks) &&\n\t\t!isNonEmptyArray(projection.cells) &&\n\t\t!isNonEmptyArray(projection.rows)\n\t) {\n\t\treturn coalesceText(projection.inlines)\n\t}\n\tconst value = collapseSpace(projectionToBlocks(projection).map(flattenText).join(' '))\n\treturn isEmptyString(value) ? [] : [{ element: 'text', value }]\n}\n\n/**\n * Projects one HTML leaf — a text node, a comment, or a doctype — to its\n * {@link MarkdownProjection}.\n *\n * @remarks\n * Text collapses each whitespace run to one space, which is both what HTML means by it\n * and all markdown can write back; the raw value travels on in `text` for the two\n * places that need it verbatim, a code span and a `pre > code` body. A comment and a\n * doctype carry nothing into markdown and project to nothing.\n *\n * @param leaf - The leaf node to project\n * @returns Its projection\n *\n * @example\n * ```ts\n * projectHTMLLeaf({ category: 'text', value: 'a\\n b' }).inlines\n * // [{ element: 'text', value: 'a b' }]\n * ```\n */\nexport function projectHTMLLeaf(\n\tleaf: CommentNode | DoctypeNode | HTMLTextNode,\n): MarkdownProjection {\n\tif (leaf.category !== 'text') return createProjection()\n\tconst value = leaf.value.replace(/\\s+/g, ' ')\n\treturn createProjection({\n\t\tinlines: isEmptyString(value) ? [] : [{ element: 'text', value }],\n\t\ttext: leaf.value,\n\t})\n}\n\n/**\n * Projects one HTML container — the document root or an element — from its children's\n * already-computed projections. The element mapping, and the only place that decides\n * what an HTML tag becomes in markdown.\n *\n * @remarks\n * `h1`-`h6` become headings; `p` a paragraph; `strong` / `b` and `em` / `i` emphasis;\n * `code` a code span; `pre` a code block, verbatim through a first `code` element child\n * (its `language-` class naming the language) and through `renderText` otherwise; `a`\n * and `img` a link and an image, each destination re-sanitized; `br` and `hr` a hard\n * break and a thematic break; `blockquote` and `li` their block content, with bare\n * inline runs wrapped in paragraphs; `ul` / `ol` a list, ordered from the tag and\n * numbered from `start`; `th` / `td`, `tr`, and `table` a GFM table whose column\n * alignment comes from each header-position cell's `align` attribute. Every\n * `UNSAFE_ELEMENTS` subtree contributes nothing at all, text included. Every other\n * element unwraps to its children, so wrapper soup melts while its content keeps its\n * shape — `<div><p>a</p><p>b</p></div>` stays two paragraphs.\n *\n * Three mappings read their own node rather than only their children's projections,\n * because HTML puts the fact in a position rather than in a value: a `pre` takes its\n * body from its `code` child's raw text, and a list takes one item per `li` child — so\n * an empty `<li>` is still an item, while the whitespace between two of them is not.\n * A `tr` accepts only its own direct cells, and a table derives the first `th`-bearing\n * row from its own source structure.\n *\n * @param node - The document root or element to project\n * @param children - Its children's projections, in source order\n * @returns Its projection\n *\n * @example\n * ```ts\n * projectHTMLNode({ category: 'element', name: 'hr', attributes: [], children: [] }, []).blocks\n * // [{ element: 'thematicBreak' }]\n * ```\n */\nexport function projectHTMLNode(\n\tnode: ElementNode | HTMLDocument,\n\tchildren: readonly MarkdownProjection[],\n): MarkdownProjection {\n\tif (node.category === 'document') return mergeProjections(children)\n\tif (UNSAFE_ELEMENTS.includes(node.name)) return createProjection()\n\tconst merged = mergeProjections(children)\n\tconst level = /^h([1-6])$/.exec(node.name)\n\tif (level !== null) {\n\t\treturn createProjection({\n\t\t\tblocks: [\n\t\t\t\t{\n\t\t\t\t\telement: 'heading',\n\t\t\t\t\tlevel: parseInteger(level[1]) ?? 1,\n\t\t\t\t\tchildren: trimInlines(normalizeInlines(projectionToInlines(merged), false)),\n\t\t\t\t},\n\t\t\t],\n\t\t\ttext: merged.text,\n\t\t})\n\t}\n\tswitch (node.name) {\n\t\tcase 'p':\n\t\tcase 'li':\n\t\t\treturn createProjection({\n\t\t\t\tblocks: projectionToBlocks(merged),\n\t\t\t\ttext: merged.text,\n\t\t\t})\n\t\tcase 'blockquote':\n\t\t\treturn createProjection({\n\t\t\t\tblocks: [{ element: 'blockquote', children: projectionToBlocks(merged) }],\n\t\t\t\ttext: merged.text,\n\t\t\t})\n\t\tcase 'hr':\n\t\t\treturn createProjection({\n\t\t\t\tblocks: [{ element: 'thematicBreak' }],\n\t\t\t\ttext: '',\n\t\t\t})\n\t\tcase 'br':\n\t\t\treturn createProjection({ inlines: [{ element: 'break' }], text: '\\n' })\n\t\tcase 'strong':\n\t\tcase 'b':\n\t\tcase 'em':\n\t\tcase 'i': {\n\t\t\tconst content = projectionToInlines(merged)\n\t\t\tconst inner = trimInlines(normalizeInlines(content, true))\n\t\t\tif (!isNonEmptyArray(inner)) return createProjection({ text: merged.text })\n\t\t\t// Markdown refuses emphasis padded with whitespace (`* x *` is literal), so the\n\t\t\t// padding moves outside the marker rather than being lost with the word boundary.\n\t\t\tconst first = content[0]\n\t\t\tconst last = content[content.length - 1]\n\t\t\tconst inlines: InlineNode[] = []\n\t\t\tif (first?.element === 'text' && /^\\s/.test(first.value))\n\t\t\t\tinlines.push({ element: 'text', value: ' ' })\n\t\t\tinlines.push({\n\t\t\t\telement: 'emphasis',\n\t\t\t\tstrong: node.name === 'strong' || node.name === 'b',\n\t\t\t\tchildren: inner,\n\t\t\t})\n\t\t\tif (last?.element === 'text' && /\\s$/.test(last.value))\n\t\t\t\tinlines.push({ element: 'text', value: ' ' })\n\t\t\treturn createProjection({ inlines, text: merged.text })\n\t\t}\n\t\tcase 'code': {\n\t\t\tconst body = merged.text.replace(/\\r\\n?/g, '\\n').replace(/\\s*\\n\\s*/g, ' ')\n\t\t\t// A span padded on both sides is exactly what the parser strips back off, so the\n\t\t\t// canonical value is the stripped one.\n\t\t\tconst value =\n\t\t\t\tbody.length > 2 && body.startsWith(' ') && body.endsWith(' ') && !isEmptyString(body.trim())\n\t\t\t\t\t? body.trim()\n\t\t\t\t\t: body\n\t\t\treturn createProjection({\n\t\t\t\tinlines: isEmptyString(value) ? [] : [{ element: 'codeSpan', value }],\n\t\t\t\ttext: merged.text,\n\t\t\t})\n\t\t}\n\t\tcase 'pre': {\n\t\t\tlet position = -1\n\t\t\tfor (const [index, child] of node.children.entries()) {\n\t\t\t\tif (child?.category !== 'element') continue\n\t\t\t\tposition = index\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tconst source = position === -1 ? undefined : node.children[position]\n\t\t\tconst projected = position === -1 ? undefined : children[position]\n\t\t\tif (source?.category === 'element' && source.name === 'code' && projected !== undefined) {\n\t\t\t\tlet lang: string | undefined\n\t\t\t\tfor (const token of (attributeOf(source, 'class') ?? '').split(/\\s+/)) {\n\t\t\t\t\tif (!token.startsWith('language-') || token.length <= 9 || token.includes('`')) continue\n\t\t\t\t\tlang = token.slice(9)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\treturn createProjection({\n\t\t\t\t\tblocks: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\telement: 'codeBlock',\n\t\t\t\t\t\t\t...(lang === undefined ? {} : { lang }),\n\t\t\t\t\t\t\tcode: projected.text.replace(/\\r\\n?/g, '\\n'),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\ttext: merged.text,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn createProjection({\n\t\t\t\tblocks: [{ element: 'codeBlock', code: renderText(node).replace(/\\r\\n?/g, '\\n') }],\n\t\t\t\ttext: merged.text,\n\t\t\t})\n\t\t}\n\t\tcase 'a':\n\t\t\treturn createProjection({\n\t\t\t\tinlines: [\n\t\t\t\t\t{\n\t\t\t\t\t\telement: 'link',\n\t\t\t\t\t\thref: sanitizeURL(attributeOf(node, 'href') ?? '', SAFE_URL_SCHEMES),\n\t\t\t\t\t\tchildren: normalizeInlines(projectionToInlines(merged), true),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\ttext: merged.text,\n\t\t\t})\n\t\tcase 'img': {\n\t\t\tconst alt = collapseSpace(attributeOf(node, 'alt') ?? '')\n\t\t\treturn createProjection({\n\t\t\t\tinlines: [\n\t\t\t\t\t{\n\t\t\t\t\t\telement: 'image',\n\t\t\t\t\t\tsrc: sanitizeURL(attributeOf(node, 'src') ?? '', SAFE_URL_SCHEMES),\n\t\t\t\t\t\tchildren: isEmptyString(alt) ? [] : [{ element: 'text', value: alt }],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\ttext: '',\n\t\t\t})\n\t\t}\n\t\tcase 'th':\n\t\tcase 'td': {\n\t\t\t// html's set is the gate; the union is the bridge — an alignment markdown has no\n\t\t\t// delimiter for stays absent rather than becoming a decorative label.\n\t\t\tconst declared = (attributeOf(node, 'align') ?? '').trim().toLowerCase()\n\t\t\tconst align =\n\t\t\t\tTABLE_ALIGNMENTS.includes(declared) &&\n\t\t\t\t(declared === 'left' || declared === 'right' || declared === 'center')\n\t\t\t\t\t? declared\n\t\t\t\t\t: undefined\n\t\t\treturn createProjection({\n\t\t\t\ttext: merged.text,\n\t\t\t\tcells: [\n\t\t\t\t\t{\n\t\t\t\t\t\talign,\n\t\t\t\t\t\tinlines: trimInlines(normalizeInlines(projectionToInlines(merged), false)),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t})\n\t\t}\n\t\tcase 'tr': {\n\t\t\tconst cells: MarkdownCell[] = []\n\t\t\tfor (const [index, child] of children.entries()) {\n\t\t\t\tconst source = node.children[index]\n\t\t\t\tif (\n\t\t\t\t\tsource?.category !== 'element' ||\n\t\t\t\t\t(source.name !== 'th' && source.name !== 'td') ||\n\t\t\t\t\tchild === undefined\n\t\t\t\t) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tfor (const cell of child.cells) if (cell !== undefined) cells.push(cell)\n\t\t\t}\n\t\t\treturn createProjection({ text: merged.text, rows: [cells] })\n\t\t}\n\t\tcase 'ul':\n\t\tcase 'ol': {\n\t\t\tconst items: ListItemNode[] = []\n\t\t\tfor (const [index, child] of children.entries()) {\n\t\t\t\tif (child === undefined) continue\n\t\t\t\tconst source = node.children[index]\n\t\t\t\tconst blocks = projectionToBlocks(child)\n\t\t\t\tif (source?.category === 'element' && source.name === 'li') {\n\t\t\t\t\titems.push({ element: 'listItem', children: blocks })\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (isNonEmptyArray(blocks)) items.push({ element: 'listItem', children: blocks })\n\t\t\t}\n\t\t\tif (!isNonEmptyArray(items)) return createProjection({ text: merged.text })\n\t\t\tconst ordered = node.name === 'ol'\n\t\t\tconst declared = parseInteger(attributeOf(node, 'start'))\n\t\t\t// A start markdown cannot write as an ordinal (`\\d{1,9}`) is no start at all.\n\t\t\tconst start =\n\t\t\t\tordered && declared !== undefined && declared >= 0 && declared <= 999_999_999 ? declared : 1\n\t\t\treturn createProjection({\n\t\t\t\tblocks: [{ element: 'list', ordered, start, items }],\n\t\t\t\ttext: merged.text,\n\t\t\t})\n\t\t}\n\t\tcase 'table': {\n\t\t\tconst rows: Array<readonly MarkdownCell[]> = []\n\t\t\tfor (const row of merged.rows) if (row !== undefined) rows.push(row)\n\t\t\tif (isNonEmptyArray(merged.cells)) rows.push(merged.cells)\n\t\t\tconst headings: boolean[] = []\n\t\t\tconst rowed: boolean[] = []\n\t\t\tconst sources: Array<{\n\t\t\t\tchildren: readonly HTMLNode[]\n\t\t\t\tindex: number\n\t\t\t\tdirect: boolean\n\t\t\t}> = [{ children: node.children, index: 0, direct: false }]\n\t\t\twhile (sources.length > 0) {\n\t\t\t\tconst source = sources.pop()\n\t\t\t\tif (source === undefined) continue\n\t\t\t\tif (source.index >= source.children.length) continue\n\t\t\t\tconst child = source.children[source.index]\n\t\t\t\tsource.index += 1\n\t\t\t\tsources.push(source)\n\t\t\t\tif (child?.category !== 'element') continue\n\t\t\t\tif (child.name === 'th' || child.name === 'td') {\n\t\t\t\t\tif (!source.direct) {\n\t\t\t\t\t\theadings.push(false)\n\t\t\t\t\t\trowed.push(false)\n\t\t\t\t\t}\n\t\t\t\t\tsource.direct = true\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tsource.direct = false\n\t\t\t\tif (child.name === 'tr') {\n\t\t\t\t\tlet heading = false\n\t\t\t\t\tfor (const cell of child.children) {\n\t\t\t\t\t\tif (cell?.category === 'element' && cell.name === 'th') {\n\t\t\t\t\t\t\theading = true\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\theadings.push(heading)\n\t\t\t\t\trowed.push(true)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tsources.push({ children: child.children, index: 0, direct: false })\n\t\t\t}\n\t\t\t// The header is the first structurally th-bearing row, then the first explicit\n\t\t\t// row; a table made only of direct cells receives an empty synthetic header.\n\t\t\tlet position: number | undefined\n\t\t\tfor (const [index, heading] of headings.entries()) {\n\t\t\t\tif (!heading) continue\n\t\t\t\tposition = index\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif (position === undefined) {\n\t\t\t\tfor (const [index, structural] of rowed.entries()) {\n\t\t\t\t\tif (!structural) continue\n\t\t\t\t\tposition = index\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst headerRow = position === undefined ? undefined : rows[position]\n\t\t\tconst columns = headerRow?.length ?? rows[0]?.length ?? 0\n\t\t\tif (columns === 0) {\n\t\t\t\treturn createProjection({\n\t\t\t\t\tblocks: projectionToBlocks(merged),\n\t\t\t\t\ttext: merged.text,\n\t\t\t\t})\n\t\t\t}\n\t\t\tconst header: Array<readonly InlineNode[]> = []\n\t\t\tconst align: Array<TableAlign | null> = []\n\t\t\tfor (let column = 0; column < columns; column += 1) {\n\t\t\t\tconst cell = headerRow?.[column]\n\t\t\t\theader.push(cell?.inlines ?? [])\n\t\t\t\talign.push(cell?.align ?? null)\n\t\t\t}\n\t\t\tconst body: Array<ReadonlyArray<readonly InlineNode[]>> = []\n\t\t\tfor (const [index, row] of rows.entries()) {\n\t\t\t\tif (row === undefined || index === position) continue\n\t\t\t\tconst cells: Array<readonly InlineNode[]> = []\n\t\t\t\tfor (let column = 0; column < header.length; column += 1)\n\t\t\t\t\tcells.push(row[column]?.inlines ?? [])\n\t\t\t\tbody.push(cells)\n\t\t\t}\n\t\t\treturn createProjection({\n\t\t\t\tblocks: [{ element: 'table', header, rows: body, align }],\n\t\t\t\ttext: merged.text,\n\t\t\t})\n\t\t}\n\t}\n\treturn merged\n}\n\n/**\n * Projects an `@orkestrel/html` {@link HTMLNode} into a {@link MarkdownDocument} — the\n * HTML→markdown direction, and the inverse of {@link markdownToHTML}.\n *\n * @remarks\n * **Engine.** One total handler table — {@link projectHTMLNode} for the containers,\n * {@link projectHTMLLeaf} for the leaves — folded by `@orkestrel/html`'s own `foldNode`, so\n * depth capping, cycle safety, and bottom-up ordering are inherited rather than\n * rebuilt. Total: hostile, cyclic, and pathologically deep input degrades instead of\n * throwing.\n *\n * **Composed depth.** Both packages cap recursion at 64, and html's cap is reached\n * first: a document nested past it projects to a chain bounded by that cap, with the\n * content below it truncated before markdown ever sees it. Since the projected chain\n * can be a level or two deeper than {@link MAX_DEPTH}, the serializer's own cap can\n * then truncate again — so the anchor law that follows is a law within the depth budget, and\n * beyond it only totality is promised.\n *\n * **Safety.** Every `href` and `src` is re-sanitized through\n * `sanitizeURL(value, SAFE_URL_SCHEMES)` whether or not the AST was ever sanitized,\n * because a hand-built one never was. A refused destination empties to `''` and the\n * link or image is kept — `[text]()` — because a bad URL is no reason to lose the words\n * around it. An `UNSAFE_ELEMENTS` subtree contributes nothing at all, text included, so\n * a `script` body can never resurface as prose.\n *\n * **The anchor law.** HTML→markdown is lossy, so the fixpoint that matters is the\n * projected AST, not the input bytes:\n * `parseDocument(renderMarkdown(htmlToMarkdown(x)))` deep-equals `htmlToMarkdown(x)`.\n * The projection therefore emits canonical markdown shapes rather than literal\n * translations — whitespace collapsed, edges trimmed, a blank paragraph dropped, a hard\n * break only where a line can end — because a shape markdown cannot write back is a\n * shape this projection has no business producing.\n *\n * @param node - The HTML document or bare node to project\n * @returns The projected markdown document\n *\n * @example\n * ```ts\n * import { parseDocument } from '@orkestrel/html'\n *\n * htmlToMarkdown(parseDocument('<h1>Title</h1>'))\n * // { element: 'document', children: [{ element: 'heading', level: 1, children: [...] }] }\n * ```\n */\nexport function htmlToMarkdown(node: HTMLNode): MarkdownDocument {\n\treturn {\n\t\telement: 'document',\n\t\tchildren: projectionToBlocks(\n\t\t\tfoldHTMLNode<MarkdownProjection>(node, {\n\t\t\t\tdocument: projectHTMLNode,\n\t\t\t\telement: projectHTMLNode,\n\t\t\t\ttext: projectHTMLLeaf,\n\t\t\t\tcomment: projectHTMLLeaf,\n\t\t\t\tdoctype: projectHTMLLeaf,\n\t\t\t}),\n\t\t),\n\t}\n}\n\n/**\n * Walks a {@link MarkdownNode} depth-first, pre-order, root-inclusive — yields\n * the node itself, then recurses into its children (block children, list items,\n * image/link inline children, table header/row cells' inline nodes) in walk order.\n *\n * @remarks\n * Total: never throws. Descent stops at {@link MAX_DEPTH} (the node at the cap is\n * still yielded; its children are not) so pathologically deep input cannot exhaust\n * the call stack.\n *\n * @param node - The AST node to walk (a full document, or any sub-node)\n * @returns A generator yielding every visited node, pre-order\n *\n * @example\n * ```ts\n * const doc = { element: 'document', children: [{ element: 'thematicBreak' }] } as const\n * [...walkNodes(doc)].map((node) => node.element) // ['document', 'thematicBreak']\n * ```\n */\nexport function* walkNodes(node: MarkdownNode): Generator<MarkdownNode> {\n\tconst stack: Array<{ readonly node: MarkdownNode; readonly depth: number }> = [{ node, depth: 0 }]\n\twhile (stack.length > 0) {\n\t\tconst frame = stack.pop()\n\t\tif (frame === undefined) continue\n\t\tyield frame.node\n\t\tif (frame.depth >= MAX_DEPTH) continue\n\t\tconst children: MarkdownNode[] = []\n\t\tswitch (frame.node.element) {\n\t\t\tcase 'document':\n\t\t\tcase 'heading':\n\t\t\tcase 'paragraph':\n\t\t\tcase 'blockquote':\n\t\t\tcase 'listItem':\n\t\t\tcase 'emphasis':\n\t\t\tcase 'link':\n\t\t\tcase 'image':\n\t\t\t\tfor (const child of frame.node.children) if (child !== undefined) children.push(child)\n\t\t\t\tbreak\n\t\t\tcase 'list':\n\t\t\t\tfor (const child of frame.node.items) if (child !== undefined) children.push(child)\n\t\t\t\tbreak\n\t\t\tcase 'table':\n\t\t\t\tfor (const cell of frame.node.header)\n\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\tfor (const row of frame.node.rows)\n\t\t\t\t\tif (row !== undefined)\n\t\t\t\t\t\tfor (const cell of row)\n\t\t\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\tbreak\n\t\t}\n\t\tfor (let index = children.length - 1; index >= 0; index -= 1) {\n\t\t\tconst child = children[index]\n\t\t\tif (child !== undefined) stack.push({ node: child, depth: frame.depth + 1 })\n\t\t}\n\t}\n}\n\n/**\n * Folds a {@link MarkdownNode} into a `T` through a total catamorphism — children are\n * folded first (post-order), then the node's own {@link MarkdownHandler} is invoked\n * with the already-folded children.\n *\n * @remarks\n * **Table contract.** A {@link TableNode} has no single `children` array — its cells\n * live in `header` (one inline-node list per column) and `rows` (a list of such\n * rows). The `table` handler receives one folded `T` per inline node, flattened in\n * walk order across all cells — every header cell's inline nodes (column order), then\n * every body row's cells' inline nodes (row order, then column order) — and reads\n * `node.header[c].length` / `node.rows[r][c].length` off the table node itself to\n * recover cell boundaries within the flat list.\n *\n * Total: never throws. At `depth >= {@link MAX_DEPTH}` the node's handler is invoked\n * with an empty children list instead of recursing further.\n *\n * @param node - The AST node to fold\n * @param handlers - The total {@link MarkdownHandlerMap} table, one handler per element\n * @param depth - The starting recursion depth (pass `0` at the entry point)\n * @returns The folded `T`\n *\n * @example\n * ```ts\n * const countHandlers: MarkdownHandlerMap<number> = {\n * document: (_, children) => children.reduce((a, b) => a + b, 1),\n * // ...one handler per element, each summing its folded children\n * }\n * foldNode(document, countHandlers, 0) // total node count\n * ```\n */\nexport function foldNode<T>(node: MarkdownNode, handlers: MarkdownHandlerMap<T>, depth: number): T {\n\tconst stack: Array<{\n\t\treadonly node: MarkdownNode\n\t\treadonly depth: number\n\t\treadonly expanded: boolean\n\t\treadonly count: number\n\t}> = [{ node, depth, expanded: false, count: 0 }]\n\tconst values: T[] = []\n\twhile (stack.length > 0) {\n\t\tconst frame = stack.pop()\n\t\tif (frame === undefined) continue\n\t\tif (!frame.expanded) {\n\t\t\tconst children: MarkdownNode[] = []\n\t\t\tif (frame.depth < MAX_DEPTH) {\n\t\t\t\tswitch (frame.node.element) {\n\t\t\t\t\tcase 'document':\n\t\t\t\t\tcase 'heading':\n\t\t\t\t\tcase 'paragraph':\n\t\t\t\t\tcase 'blockquote':\n\t\t\t\t\tcase 'listItem':\n\t\t\t\t\tcase 'emphasis':\n\t\t\t\t\tcase 'link':\n\t\t\t\t\tcase 'image':\n\t\t\t\t\t\tfor (const child of frame.node.children) if (child !== undefined) children.push(child)\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase 'list':\n\t\t\t\t\t\tfor (const child of frame.node.items) if (child !== undefined) children.push(child)\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase 'table':\n\t\t\t\t\t\tfor (const cell of frame.node.header)\n\t\t\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\t\t\tfor (const row of frame.node.rows)\n\t\t\t\t\t\t\tif (row !== undefined)\n\t\t\t\t\t\t\t\tfor (const cell of row)\n\t\t\t\t\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tstack.push({ ...frame, expanded: true, count: children.length })\n\t\t\tfor (let index = children.length - 1; index >= 0; index -= 1) {\n\t\t\t\tconst child = children[index]\n\t\t\t\tif (child !== undefined) {\n\t\t\t\t\tstack.push({\n\t\t\t\t\t\tnode: child,\n\t\t\t\t\t\tdepth: frame.depth + 1,\n\t\t\t\t\t\texpanded: false,\n\t\t\t\t\t\tcount: 0,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tconst children =\n\t\t\tframe.count === 0 ? [] : values.splice(values.length - frame.count, frame.count)\n\t\tlet value: T\n\t\tswitch (frame.node.element) {\n\t\t\tcase 'document':\n\t\t\t\tvalue = handlers.document(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'heading':\n\t\t\t\tvalue = handlers.heading(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'paragraph':\n\t\t\t\tvalue = handlers.paragraph(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'thematicBreak':\n\t\t\t\tvalue = handlers.thematicBreak(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'blockquote':\n\t\t\t\tvalue = handlers.blockquote(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'codeBlock':\n\t\t\t\tvalue = handlers.codeBlock(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'list':\n\t\t\t\tvalue = handlers.list(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'listItem':\n\t\t\t\tvalue = handlers.listItem(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'table':\n\t\t\t\tvalue = handlers.table(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'text':\n\t\t\t\tvalue = handlers.text(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'emphasis':\n\t\t\t\tvalue = handlers.emphasis(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'codeSpan':\n\t\t\t\tvalue = handlers.codeSpan(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'break':\n\t\t\t\tvalue = handlers.break(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'link':\n\t\t\t\tvalue = handlers.link(frame.node, children)\n\t\t\t\tbreak\n\t\t\tcase 'image':\n\t\t\t\tvalue = handlers.image(frame.node, children)\n\t\t\t\tbreak\n\t\t}\n\t\tif (stack.length === 0) return value\n\t\tvalues.push(value)\n\t}\n\tswitch (node.element) {\n\t\tcase 'document':\n\t\t\treturn handlers.document(node, [])\n\t\tcase 'heading':\n\t\t\treturn handlers.heading(node, [])\n\t\tcase 'paragraph':\n\t\t\treturn handlers.paragraph(node, [])\n\t\tcase 'thematicBreak':\n\t\t\treturn handlers.thematicBreak(node, [])\n\t\tcase 'blockquote':\n\t\t\treturn handlers.blockquote(node, [])\n\t\tcase 'codeBlock':\n\t\t\treturn handlers.codeBlock(node, [])\n\t\tcase 'list':\n\t\t\treturn handlers.list(node, [])\n\t\tcase 'listItem':\n\t\t\treturn handlers.listItem(node, [])\n\t\tcase 'table':\n\t\t\treturn handlers.table(node, [])\n\t\tcase 'text':\n\t\t\treturn handlers.text(node, [])\n\t\tcase 'emphasis':\n\t\t\treturn handlers.emphasis(node, [])\n\t\tcase 'codeSpan':\n\t\t\treturn handlers.codeSpan(node, [])\n\t\tcase 'break':\n\t\t\treturn handlers.break(node, [])\n\t\tcase 'link':\n\t\t\treturn handlers.link(node, [])\n\t\tcase 'image':\n\t\t\treturn handlers.image(node, [])\n\t}\n}\n\n/**\n * Rewrites a {@link MarkdownDocument} bottom-up (copy-on-write) — each node's children\n * are rewritten first (post-order), then `rewrite` is applied to the node itself; the\n * document root is never passed to `rewrite` (the `element: 'document'` invariant\n * always holds). A table's inline cells and a list's items are rewritten too.\n *\n * @remarks\n * Never mutates `document`. An unchanged subtree keeps its input identity. A parent\n * is rebuilt only when an accepted child changes, and the returned derivation map\n * associates each rebuilt output with its input node. When `rewrite` returns a node\n * whose `element` does not fit the slot it was called for (a block slot handed a\n * non-{@link BlockNode}, an inline slot handed a non-{@link InlineNode}, a list-item\n * slot handed a non-`listItem`), the ill-fitting result is discarded and the accepted\n * input child is reused — `rewriteDocument` stays total and never produces a\n * structurally invalid document.\n *\n * Descent is capped at {@link MAX_DEPTH}, the same cap {@link walkNodes} and\n * {@link foldNode} observe: at `depth >= MAX_DEPTH` the subtree is passed through\n * unchanged (by reference, not rebuilt, and `rewrite` is not invoked on it) instead of\n * recursing further, so a pathologically deep adopted document cannot exhaust the\n * call stack. {@link MarkdownInterface.map} inherits this cap since it delegates here.\n *\n * @param document - The document AST to rewrite\n * @param rewrite - The bottom-up {@link MarkdownRewriteHandler}\n * @returns The rewritten document and its output-to-input derivations\n *\n * @example\n * ```ts\n * const [rewritten, derivations] = rewriteDocument(document, (node) =>\n * node.element === 'text' ? { element: 'text', value: node.value.toUpperCase() } : node,\n * )\n * ```\n */\nexport function rewriteDocument(\n\tdocument: MarkdownDocument,\n\trewrite: MarkdownRewriteHandler,\n): MarkdownDerivation<MarkdownDocument> {\n\tconst stack: Array<{\n\t\treadonly node: MarkdownNode\n\t\treadonly depth: number\n\t\treadonly expanded: boolean\n\t\treadonly count: number\n\t}> = [{ node: document, depth: -1, expanded: false, count: 0 }]\n\tconst values: MarkdownNode[] = []\n\tconst derivations = new Map<MarkdownNode, MarkdownNode | undefined>()\n\twhile (stack.length > 0) {\n\t\tconst frame = stack.pop()\n\t\tif (frame === undefined) continue\n\t\tconst current = frame.node\n\t\tif (!frame.expanded) {\n\t\t\tif (current.element !== 'document' && frame.depth >= MAX_DEPTH) {\n\t\t\t\tvalues.push(current)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst children: MarkdownNode[] = []\n\t\t\tswitch (current.element) {\n\t\t\t\tcase 'document':\n\t\t\t\tcase 'heading':\n\t\t\t\tcase 'paragraph':\n\t\t\t\tcase 'blockquote':\n\t\t\t\tcase 'listItem':\n\t\t\t\tcase 'emphasis':\n\t\t\t\tcase 'link':\n\t\t\t\tcase 'image':\n\t\t\t\t\tfor (const child of current.children) if (child !== undefined) children.push(child)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'list':\n\t\t\t\t\tfor (const child of current.items) if (child !== undefined) children.push(child)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'table':\n\t\t\t\t\tfor (const cell of current.header)\n\t\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\t\tfor (const row of current.rows)\n\t\t\t\t\t\tif (row !== undefined)\n\t\t\t\t\t\t\tfor (const cell of row)\n\t\t\t\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t\tstack.push({ ...frame, expanded: true, count: children.length })\n\t\t\tconst depth = current.element === 'document' ? 0 : frame.depth + 1\n\t\t\tfor (let index = children.length - 1; index >= 0; index -= 1) {\n\t\t\t\tconst child = children[index]\n\t\t\t\tif (child !== undefined) stack.push({ node: child, depth, expanded: false, count: 0 })\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tconst children =\n\t\t\tframe.count === 0 ? [] : values.splice(values.length - frame.count, frame.count)\n\t\tlet rebuilt: MarkdownNode = current\n\t\tlet changed = false\n\t\tswitch (current.element) {\n\t\t\tcase 'document': {\n\t\t\t\tconst blocks: BlockNode[] = []\n\t\t\t\tlet offset = 0\n\t\t\t\tfor (const block of current.children) {\n\t\t\t\t\tif (block === undefined) continue\n\t\t\t\t\tconst child = children[offset]\n\t\t\t\t\tconst accepted = child !== undefined && isBlockNode(child) ? child : block\n\t\t\t\t\tblocks.push(accepted)\n\t\t\t\t\tif (accepted !== block) changed = true\n\t\t\t\t\toffset += 1\n\t\t\t\t}\n\t\t\t\tif (changed) rebuilt = { element: 'document', children: blocks }\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'heading':\n\t\t\tcase 'paragraph': {\n\t\t\t\tconst inlines: InlineNode[] = []\n\t\t\t\tlet offset = 0\n\t\t\t\tfor (const inline of current.children) {\n\t\t\t\t\tif (inline === undefined) continue\n\t\t\t\t\tconst child = children[offset]\n\t\t\t\t\tconst accepted = child !== undefined && isInlineNode(child) ? child : inline\n\t\t\t\t\tinlines.push(accepted)\n\t\t\t\t\tif (accepted !== inline) changed = true\n\t\t\t\t\toffset += 1\n\t\t\t\t}\n\t\t\t\tif (changed) rebuilt = { ...current, children: inlines }\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'blockquote': {\n\t\t\t\tconst blocks: BlockNode[] = []\n\t\t\t\tlet offset = 0\n\t\t\t\tfor (const block of current.children) {\n\t\t\t\t\tif (block === undefined) continue\n\t\t\t\t\tconst child = children[offset]\n\t\t\t\t\tconst accepted = child !== undefined && isBlockNode(child) ? child : block\n\t\t\t\t\tblocks.push(accepted)\n\t\t\t\t\tif (accepted !== block) changed = true\n\t\t\t\t\toffset += 1\n\t\t\t\t}\n\t\t\t\tif (changed) rebuilt = { ...current, children: blocks }\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'listItem': {\n\t\t\t\tconst blocks: BlockNode[] = []\n\t\t\t\tlet offset = 0\n\t\t\t\tfor (const block of current.children) {\n\t\t\t\t\tif (block === undefined) continue\n\t\t\t\t\tconst child = children[offset]\n\t\t\t\t\tconst accepted = child !== undefined && isBlockNode(child) ? child : block\n\t\t\t\t\tblocks.push(accepted)\n\t\t\t\t\tif (accepted !== block) changed = true\n\t\t\t\t\toffset += 1\n\t\t\t\t}\n\t\t\t\tif (changed) rebuilt = { element: 'listItem', children: blocks }\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'emphasis':\n\t\t\tcase 'link':\n\t\t\tcase 'image': {\n\t\t\t\tconst inlines: InlineNode[] = []\n\t\t\t\tlet offset = 0\n\t\t\t\tfor (const inline of current.children) {\n\t\t\t\t\tif (inline === undefined) continue\n\t\t\t\t\tconst child = children[offset]\n\t\t\t\t\tconst accepted = child !== undefined && isInlineNode(child) ? child : inline\n\t\t\t\t\tinlines.push(accepted)\n\t\t\t\t\tif (accepted !== inline) changed = true\n\t\t\t\t\toffset += 1\n\t\t\t\t}\n\t\t\t\tif (changed) rebuilt = { ...current, children: inlines }\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'list': {\n\t\t\t\tconst items: ListItemNode[] = []\n\t\t\t\tlet offset = 0\n\t\t\t\tfor (const item of current.items) {\n\t\t\t\t\tif (item === undefined) continue\n\t\t\t\t\tconst child = children[offset]\n\t\t\t\t\tconst accepted = child?.element === 'listItem' ? child : item\n\t\t\t\t\titems.push(accepted)\n\t\t\t\t\tif (accepted !== item) changed = true\n\t\t\t\t\toffset += 1\n\t\t\t\t}\n\t\t\t\tif (changed) rebuilt = { ...current, items }\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'table': {\n\t\t\t\tlet offset = 0\n\t\t\t\tconst header: Array<readonly InlineNode[]> = []\n\t\t\t\tfor (const cell of current.header) {\n\t\t\t\t\tif (cell === undefined) continue\n\t\t\t\t\tconst inlines: InlineNode[] = []\n\t\t\t\t\tfor (const inline of cell) {\n\t\t\t\t\t\tif (inline === undefined) continue\n\t\t\t\t\t\tconst child = children[offset]\n\t\t\t\t\t\tconst accepted = child !== undefined && isInlineNode(child) ? child : inline\n\t\t\t\t\t\tinlines.push(accepted)\n\t\t\t\t\t\tif (accepted !== inline) changed = true\n\t\t\t\t\t\toffset += 1\n\t\t\t\t\t}\n\t\t\t\t\theader.push(inlines)\n\t\t\t\t}\n\t\t\t\tconst rows: Array<ReadonlyArray<readonly InlineNode[]>> = []\n\t\t\t\tfor (const row of current.rows) {\n\t\t\t\t\tif (row === undefined) continue\n\t\t\t\t\tconst cells: Array<readonly InlineNode[]> = []\n\t\t\t\t\tfor (const cell of row) {\n\t\t\t\t\t\tif (cell === undefined) continue\n\t\t\t\t\t\tconst inlines: InlineNode[] = []\n\t\t\t\t\t\tfor (const inline of cell) {\n\t\t\t\t\t\t\tif (inline === undefined) continue\n\t\t\t\t\t\t\tconst child = children[offset]\n\t\t\t\t\t\t\tconst accepted = child !== undefined && isInlineNode(child) ? child : inline\n\t\t\t\t\t\t\tinlines.push(accepted)\n\t\t\t\t\t\t\tif (accepted !== inline) changed = true\n\t\t\t\t\t\t\toffset += 1\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcells.push(inlines)\n\t\t\t\t\t}\n\t\t\t\t\trows.push(cells)\n\t\t\t\t}\n\t\t\t\tif (changed) rebuilt = { ...current, header, rows }\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif (rebuilt !== current) derivations.set(rebuilt, current)\n\t\tif (current.element === 'document') {\n\t\t\tconst result = rebuilt.element === 'document' ? rebuilt : current\n\t\t\tconst output = new Set(walkNodes(result))\n\t\t\tconst retained = new Map<MarkdownNode, MarkdownNode | undefined>()\n\t\t\tfor (const [node, source] of derivations) if (output.has(node)) retained.set(node, source)\n\t\t\treturn [result, retained]\n\t\t}\n\t\tconst result = rewrite(rebuilt)\n\t\tlet accepted = rebuilt\n\t\tswitch (current.element) {\n\t\t\tcase 'text':\n\t\t\tcase 'emphasis':\n\t\t\tcase 'codeSpan':\n\t\t\tcase 'break':\n\t\t\tcase 'link':\n\t\t\tcase 'image':\n\t\t\t\tif (isInlineNode(result)) accepted = result\n\t\t\t\tbreak\n\t\t\tcase 'heading':\n\t\t\tcase 'paragraph':\n\t\t\tcase 'list':\n\t\t\tcase 'table':\n\t\t\tcase 'codeBlock':\n\t\t\tcase 'blockquote':\n\t\t\tcase 'thematicBreak':\n\t\t\t\tif (isBlockNode(result)) accepted = result\n\t\t\t\tbreak\n\t\t\tcase 'listItem':\n\t\t\t\tif (result.element === 'listItem') accepted = result\n\t\t\t\tbreak\n\t\t}\n\t\tif (accepted !== rebuilt && accepted !== current) {\n\t\t\tif (derivations.has(accepted) && derivations.get(accepted) !== current)\n\t\t\t\tderivations.set(accepted, undefined)\n\t\t\telse derivations.set(accepted, current)\n\t\t}\n\t\tvalues.push(accepted)\n\t}\n\treturn [document, new Map()]\n}\n\n/**\n * Concatenates the `value` / `code` content of every descendant text / code-span /\n * code-block node under `node`, including image alternative content, in walk order —\n * the plain-text projection of an AST (search indexing, word counts, a text-only\n * preview).\n *\n * @remarks\n * Total: never throws. Descent stops at {@link MAX_DEPTH} (contributes `''` past the\n * cap instead of recursing further).\n *\n * @param node - The AST node to flatten (a full document, or any sub-node)\n * @returns The concatenated text content\n *\n * @example\n * ```ts\n * flattenText({ element: 'paragraph', children: [\n * { element: 'text', value: 'a ' },\n * { element: 'codeSpan', value: 'b' },\n * ] })\n * // 'a b'\n * ```\n */\nexport function flattenText(node: MarkdownNode): string {\n\tconst stack: Array<{ readonly node: MarkdownNode; readonly depth: number }> = [{ node, depth: 0 }]\n\tlet value = ''\n\twhile (stack.length > 0) {\n\t\tconst frame = stack.pop()\n\t\tif (frame === undefined || frame.depth >= MAX_DEPTH) continue\n\t\tconst children: MarkdownNode[] = []\n\t\tswitch (frame.node.element) {\n\t\t\tcase 'text':\n\t\t\tcase 'codeSpan':\n\t\t\t\tvalue += frame.node.value\n\t\t\t\tbreak\n\t\t\tcase 'codeBlock':\n\t\t\t\tvalue += frame.node.code\n\t\t\t\tbreak\n\t\t\tcase 'document':\n\t\t\tcase 'heading':\n\t\t\tcase 'paragraph':\n\t\t\tcase 'blockquote':\n\t\t\tcase 'listItem':\n\t\t\tcase 'emphasis':\n\t\t\tcase 'link':\n\t\t\tcase 'image':\n\t\t\t\tfor (const child of frame.node.children) if (child !== undefined) children.push(child)\n\t\t\t\tbreak\n\t\t\tcase 'list':\n\t\t\t\tfor (const child of frame.node.items) if (child !== undefined) children.push(child)\n\t\t\t\tbreak\n\t\t\tcase 'table':\n\t\t\t\tfor (const cell of frame.node.header)\n\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\tfor (const row of frame.node.rows)\n\t\t\t\t\tif (row !== undefined)\n\t\t\t\t\t\tfor (const cell of row)\n\t\t\t\t\t\t\tif (cell !== undefined)\n\t\t\t\t\t\t\t\tfor (const child of cell) if (child !== undefined) children.push(child)\n\t\t\t\tbreak\n\t\t}\n\t\tfor (let index = children.length - 1; index >= 0; index -= 1) {\n\t\t\tconst child = children[index]\n\t\t\tif (child !== undefined) stack.push({ node: child, depth: frame.depth + 1 })\n\t\t}\n\t}\n\treturn value\n}\n","import type { MarkdownNode } from './types.js'\nimport { HTML, SAFE_ATTRIBUTES, renderHTML as renderHTMLDocument } from '@orkestrel/html'\nimport { markdownToHTML } from './helpers.js'\n\n// The class-driving half of the outbound direction. `helpers.ts` owns the pure\n// {@link markdownToHTML} projection, which imports no implementation class and stays a\n// leaf; the sanitize-and-serialize pipeline below constructs `@orkestrel/html`'s `HTML`\n// class, so it sits above the leaves and consumes them.\n\n/**\n * Renders a {@link MarkdownNode} to sanitized canonical HTML.\n *\n * @remarks\n * Sanitization is unconditional: the function takes one argument and declares no\n * options, so no call shape opts out of it.\n *\n * Markdown widens `@orkestrel/html`'s attribute floor by exactly `src`, because image\n * syntax is meaningless without its source. `src` is still a URL attribute, so the\n * floor refuses `javascript:`, `data:`, `vbscript:`, and `file:` values. A stricter\n * consumer can compose {@link markdownToHTML} with `@orkestrel/html`'s `HTML` class\n * directly.\n *\n * @param node - The markdown document or bare node to render\n * @returns Sanitized canonical HTML\n *\n * @example\n * ```ts\n * renderHTML({ element: 'paragraph', children: [{ element: 'text', value: 'a & b' }] })\n * // '<p>a &amp; b</p>'\n * ```\n */\nexport function renderHTML(node: MarkdownNode): string {\n\treturn renderHTMLDocument(\n\t\tnew HTML(markdownToHTML(node)).sanitize({ attributes: [...SAFE_ATTRIBUTES, 'src'] }).document,\n\t)\n}\n","import {\n\tbooleanShape,\n\tintegerShape,\n\tliteralShape,\n\tobjectShape,\n\toptionalShape,\n\tstringShape,\n} from '@orkestrel/contract'\n\n// Shapers are `ContractShape` values, not functions\n// or types — a JSON-Schema blueprint the compilers (factories.ts) turn into a\n// guard / parser / schema / generator in lockstep. Only the non-recursive\n// parts of the markdown AST (types.ts) can be expressed here: a shape tree has\n// no lazy/self-referential node, so any type whose fields recurse into\n// `BlockNode` / `InlineNode` / `MarkdownNode` (EmphasisNode, LinkNode, ImageNode,\n// HeadingNode, ParagraphNode, ListItemNode, ListNode, TableNode,\n// BlockquoteNode, MarkdownDocument) is skipped here and stays guard-only\n// (validators.ts) through `lazyOf`.\n\n/**\n * Describes the shape of a {@link TextNode} — a plain-text leaf inline run.\n *\n * @example\n * ```ts\n * import { createContract } from '@orkestrel/contract'\n * import { textShape } from '@src/core'\n *\n * const text = createContract(textShape)\n * text.is({ element: 'text', value: 'hi' }) // true\n * ```\n */\nexport const textShape = objectShape({\n\telement: literalShape(['text']),\n\tvalue: stringShape(),\n})\n\n/**\n * Describes the shape of a {@link CodeSpanNode} — an inline code span (`` `code` ``).\n *\n * @example\n * ```ts\n * import { createContract } from '@orkestrel/contract'\n * import { codeSpanShape } from '@src/core'\n *\n * const codeSpan = createContract(codeSpanShape)\n * codeSpan.is({ element: 'codeSpan', value: 'const x = 1' }) // true\n * ```\n */\nexport const codeSpanShape = objectShape({\n\telement: literalShape(['codeSpan']),\n\tvalue: stringShape(),\n})\n\n/**\n * Describes the shape of a {@link LineBreakNode} — a GFM hard line-break leaf.\n *\n * @example\n * ```ts\n * import { createContract } from '@orkestrel/contract'\n * import { lineBreakShape } from '@src/core'\n *\n * const lineBreak = createContract(lineBreakShape)\n * lineBreak.is({ element: 'break' }) // true\n * ```\n */\nexport const lineBreakShape = objectShape({\n\telement: literalShape(['break']),\n})\n\n/**\n * Describes the shape of a {@link CodeBlockNode} — a fenced code block. `lang` is\n * optional (absent when the opening fence carries no info-string).\n *\n * @example\n * ```ts\n * import { createContract } from '@orkestrel/contract'\n * import { codeBlockShape } from '@src/core'\n *\n * const codeBlock = createContract(codeBlockShape)\n * codeBlock.is({ element: 'codeBlock', code: 'x' }) // true\n * codeBlock.is({ element: 'codeBlock', code: 'x', lang: 'ts' }) // true\n * ```\n */\nexport const codeBlockShape = objectShape({\n\telement: literalShape(['codeBlock']),\n\tlang: optionalShape(stringShape()),\n\tcode: stringShape(),\n})\n\n/**\n * Describes the shape of a {@link ThematicBreakNode} — a horizontal rule. Carries no\n * fields beyond its `element` discriminant.\n *\n * @example\n * ```ts\n * import { createContract } from '@orkestrel/contract'\n * import { thematicBreakShape } from '@src/core'\n *\n * const thematicBreak = createContract(thematicBreakShape)\n * thematicBreak.is({ element: 'thematicBreak' }) // true\n * ```\n */\nexport const thematicBreakShape = objectShape({\n\telement: literalShape(['thematicBreak']),\n})\n\n/**\n * Describes the shape of a {@link TableAlign} — the per-column GFM table alignment\n * literal. Absence is no member of it, so the shape refuses the `null` a bare `---`\n * delimiter takes in a `TableNode`'s `align` list.\n *\n * @example\n * ```ts\n * import { createContract } from '@orkestrel/contract'\n * import { tableAlignShape } from '@src/core'\n *\n * const tableAlign = createContract(tableAlignShape)\n * tableAlign.is('left') // true\n * tableAlign.is('center') // true\n * tableAlign.is('top') // false\n * ```\n */\nexport const tableAlignShape = literalShape(['left', 'right', 'center'])\n\n/**\n * Describes the shape of {@link ListItemMatch} — the parsed parts of a single list-item\n * line the block phase's list detector returns. Fully non-recursive (no\n * nested node fields), so every field shapes directly.\n *\n * @example\n * ```ts\n * import { createContract } from '@orkestrel/contract'\n * import { listItemMatchShape } from '@src/core'\n *\n * const listItemParts = createContract(listItemMatchShape)\n * listItemParts.is({ ordered: false, start: 1, content: 'hi', indent: 0, marker: 2 }) // true\n * ```\n */\nexport const listItemMatchShape = objectShape({\n\tordered: booleanShape(),\n\tstart: integerShape(),\n\tcontent: stringShape(),\n\tindent: integerShape(),\n\tmarker: integerShape(),\n})\n","import type {\n\tBlockNode,\n\tMarkdownDocument,\n\tMarkdownHandlerMap,\n\tMarkdownInterface,\n\tMarkdownNode,\n\tMarkdownRewriteHandler,\n\tMarkdownSpan,\n} from './types.js'\nimport { foldNode, rewriteDocument, walkNodes } from './helpers.js'\nimport { parseProvenance } from './parsers.js'\n\n/**\n * Wraps a typed {@link MarkdownDocument} AST as a stateful, parsed markdown document\n * with the query (`find` / `filter` / `reduce` / iteration), rewrite (`map`), fold, and\n * streaming operations {@link MarkdownInterface} declares.\n *\n * @remarks\n * - **Construction.** Given a `string`, the constructor runs {@link parseProvenance} (the\n * block phase then the inline phase) once, keeping the AST and a copy of the span map\n * that parse recorded. Given a {@link MarkdownDocument}, the document is adopted as-is\n * and is not re-validated — gate an untrusted value with `isMarkdownDocument` first.\n * - **Provenance.** {@link span} reads the region of the original constructor string a\n * node was produced from, and it is handle-relative: a string-constructed handle exposes\n * the regions of the nodes it parsed, an adopted document exposes none, and a node from\n * another handle reports `undefined` here whatever that handle reports. Each call\n * returns a fresh value. A node reports the region this handle holds for its identity,\n * else the region of the direct input a rewrite named for it, else `undefined`: a text\n * run the parse joined from adjacent scanner output reports the region enclosing its\n * parts, and only a rewrite output that holds no region of its own and was assembled\n * from separate source nodes reports `undefined`.\n * {@link map} carries provenance across the rewrite: an unchanged node keeps its\n * region, a one-source replacement takes the region of the node it replaced, and a\n * rebuilt parent takes its original's.\n * - **Immutable.** {@link map} never mutates the stored AST — it returns a new `Markdown`\n * instance; the document root invariant (`element: 'document'`) always holds. An\n * identity rewrite still returns a new handle, over the same document tree.\n * - **Traversal order.** {@link walk} and the `find` / `filter` / `reduce` queries built\n * on it walk the AST depth-first, pre-order, root-inclusive (through {@link walkNodes});\n * `stream` is shallow — only the document's direct block children.\n *\n * @example Construct from a string and narrow with a guard\n * ```ts\n * import { Markdown, isHeadingNode } from '@orkestrel/markdown'\n *\n * const markdown = new Markdown('# Title\\n\\nA **bold** [link](https://x.dev).')\n * markdown.document.children[0] // { element: 'heading', level: 1, children: [...] }\n *\n * const heading = markdown.find(isHeadingNode) // HeadingNode | undefined, narrowed\n * if (heading !== undefined) heading.level // number — narrowed to HeadingNode\n * ```\n */\nexport class Markdown implements MarkdownInterface {\n\treadonly #document: MarkdownDocument\n\treadonly #spans: Map<MarkdownNode, MarkdownSpan>\n\n\tconstructor(input: string | MarkdownDocument) {\n\t\tif (typeof input === 'string') {\n\t\t\tconst [document, spans] = parseProvenance(input)\n\t\t\tthis.#document = document\n\t\t\tthis.#spans = new Map(spans)\n\t\t} else {\n\t\t\tthis.#document = input\n\t\t\tthis.#spans = new Map()\n\t\t}\n\t}\n\n\t/** Holds the stored {@link MarkdownDocument} AST root. */\n\tget document(): MarkdownDocument {\n\t\treturn this.#document\n\t}\n\n\t/**\n\t * Reads the region of the original markdown string a node of this handle's tree was\n\t * produced from.\n\t *\n\t * @param node - The node whose provenance to read\n\t * @returns A fresh {@link MarkdownSpan}, or `undefined` when this handle holds no\n\t * region for the node\n\t *\n\t * @example\n\t * ```ts\n\t * const source = '# Title\\n\\npara'\n\t * const markdown = new Markdown(source)\n\t * const heading = markdown.find(isHeadingNode)\n\t * const span = heading && markdown.span(heading)\n\t * span && source.slice(span.start, span.end) // '# Title'\n\t * ```\n\t */\n\tspan(node: MarkdownNode): MarkdownSpan | undefined {\n\t\tconst span = this.#spans.get(node)\n\t\treturn span === undefined ? undefined : { start: span.start, end: span.end }\n\t}\n\n\t/**\n\t * Returns the deep traversal — a lazy, depth-first, pre-order, root-inclusive generator\n\t * over every {@link MarkdownNode} in the document. `find` / `filter` / `reduce`\n\t * all iterate this single traversal.\n\t *\n\t * @example\n\t * ```ts\n\t * for (const node of markdown.walk()) {\n\t * // every node, depth-first, pre-order, root-inclusive\n\t * }\n\t *\n\t * // also consumable by for-await - JS accepts a sync iterable in for-await\n\t * for await (const node of markdown.walk()) {\n\t * // same sequence, no separate async iterator needed\n\t * }\n\t * ```\n\t */\n\t*walk(): Generator<MarkdownNode> {\n\t\tyield* walkNodes(this.#document)\n\t}\n\n\t// Finds the first node (depth-first, pre-order) narrowed by a type guard.\n\tfind<T extends MarkdownNode>(guard: (node: MarkdownNode) => node is T): T | undefined\n\t// Finds the first node (depth-first, pre-order) matching a predicate.\n\tfind(predicate: (node: MarkdownNode) => boolean): MarkdownNode | undefined\n\tfind(predicate: (node: MarkdownNode) => boolean): MarkdownNode | undefined {\n\t\tfor (const node of this.walk()) if (predicate(node)) return node\n\t\treturn undefined\n\t}\n\n\t// Collects every node (depth-first, pre-order) narrowed by a type guard.\n\tfilter<T extends MarkdownNode>(guard: (node: MarkdownNode) => node is T): readonly T[]\n\t// Collects every node (depth-first, pre-order) matching a predicate.\n\tfilter(predicate: (node: MarkdownNode) => boolean): readonly MarkdownNode[]\n\tfilter(predicate: (node: MarkdownNode) => boolean): readonly MarkdownNode[] {\n\t\tconst out: MarkdownNode[] = []\n\t\tfor (const node of this.walk()) if (predicate(node)) out.push(node)\n\t\treturn out\n\t}\n\n\t/**\n\t * Rewrites the AST bottom-up (copy-on-write) and returns a new {@link Markdown},\n\t * carrying each output node's provenance across the rewrite. A rewrite that returns\n\t * its node unchanged shares that subtree instead of copying it, so an identity\n\t * rewrite copies no node and still returns a new handle.\n\t *\n\t * @param rewrite - The bottom-up node rewrite\n\t * @returns A new handle over the rewritten document\n\t */\n\tmap(rewrite: MarkdownRewriteHandler): MarkdownInterface {\n\t\tconst [document, derivations] = rewriteDocument(this.#document, rewrite)\n\t\treturn this.#derive(document, derivations)\n\t}\n\n\t/** Folds the AST depth-first, pre-order into an accumulator. */\n\treduce<T>(callback: (accumulator: T, node: MarkdownNode) => T, initial: T): T {\n\t\tlet accumulator = initial\n\t\tfor (const node of this.walk()) accumulator = callback(accumulator, node)\n\t\treturn accumulator\n\t}\n\n\t/** Runs a total catamorphism over the document using a {@link MarkdownHandlerMap} table. */\n\tfold<T>(handlers: MarkdownHandlerMap<T>): T {\n\t\treturn foldNode(this.#document, handlers, 0)\n\t}\n\n\t/**\n\t * Returns a web-standard {@link ReadableStream} over the document's top-level block nodes\n\t * (shallow, source order) — a fresh, pull-based source per call: one block is\n\t * enqueued per `pull`, so a slow reader's backpressure is respected. Cancellable,\n\t * async-iterable wherever the platform supports it (Node, Deno), and pipeable\n\t * through any {@link TransformStream} / {@link WritableStream}.\n\t *\n\t * @example\n\t * ```ts\n\t * // universal - works in every ReadableStream-supporting environment\n\t * const reader = markdown.stream().getReader()\n\t * for (let result = await reader.read(); !result.done; result = await reader.read()) {\n\t * console.log(result.value) // one BlockNode\n\t * }\n\t *\n\t * // Node / Deno / Firefox support async iteration of ReadableStream natively;\n\t * // other environments use the reader loop shown earlier.\n\t * for await (const block of markdown.stream()) {\n\t * console.log(block)\n\t * }\n\t * ```\n\t */\n\tstream(): ReadableStream<BlockNode> {\n\t\tconst blocks = this.#document.children\n\t\tlet index = 0\n\t\treturn new ReadableStream<BlockNode>({\n\t\t\tpull(controller) {\n\t\t\t\tif (index < blocks.length) {\n\t\t\t\t\tconst block = blocks[index]\n\t\t\t\t\tif (block === undefined) {\n\t\t\t\t\t\tcontroller.close()\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tcontroller.enqueue(block)\n\t\t\t\t\tindex += 1\n\t\t\t\t} else {\n\t\t\t\t\tcontroller.close()\n\t\t\t\t}\n\t\t\t},\n\t\t})\n\t}\n\n\t// Creates the operation's new handle and resolves each output against its own prior\n\t// span before its direct input's prior span. The source handle already resolved every\n\t// earlier rewrite, so following the input's separate output entry from this operation\n\t// would conflate two roles held by one identity.\n\t#derive(\n\t\tdocument: MarkdownDocument,\n\t\tderivations: ReadonlyMap<MarkdownNode, MarkdownNode | undefined>,\n\t): Markdown {\n\t\tconst derived = new Markdown(document)\n\t\tfor (const node of walkNodes(document)) {\n\t\t\tconst own = this.#spans.get(node)\n\t\t\tif (own !== undefined) {\n\t\t\t\tderived.#spans.set(node, own)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst source = derivations.get(node)\n\t\t\tif (source === undefined) continue\n\t\t\tconst span = this.#spans.get(source)\n\t\t\tif (span !== undefined) derived.#spans.set(node, span)\n\t\t}\n\t\treturn derived\n\t}\n}\n","import type { ContractInterface } from '@orkestrel/contract'\nimport type {\n\tCodeBlockNode,\n\tCodeSpanNode,\n\tLineBreakNode,\n\tMarkdownDocument,\n\tMarkdownInterface,\n\tTextNode,\n\tThematicBreakNode,\n} from './types.js'\nimport { createContract } from '@orkestrel/contract'\nimport { Markdown } from './Markdown.js'\nimport {\n\tcodeBlockShape,\n\tcodeSpanShape,\n\tlineBreakShape,\n\ttextShape,\n\tthematicBreakShape,\n} from './shapers.js'\n\n/**\n * Creates a stateful markdown handle from a markdown string or an already-parsed\n * {@link MarkdownDocument} — a typed AST plus the query, rewrite, and fold operations\n * {@link MarkdownInterface} exposes.\n *\n * @remarks\n * Given a `string`, runs a block phase (headings / paragraphs / lists / GFM tables /\n * fenced code / blockquotes / thematic breaks) then an inline phase (emphasis /\n * inline code / links / images / hard breaks) to build a render-agnostic\n * {@link MarkdownDocument}. Given a\n * {@link MarkdownDocument}, adopts it as-is without re-validation — gate an untrusted\n * value with `isMarkdownDocument` first. Pure + total parse (malformed markdown\n * degrades to text, never throws) and zero-dependency — a hand-written scanner, no\n * regex-only structural parse, linear-time (no ReDoS).\n *\n * @param input - A markdown string to parse, or an already-parsed {@link MarkdownDocument}\n * @returns A working {@link MarkdownInterface}\n *\n * @example\n * ```ts\n * import { createMarkdown } from '@src/core'\n *\n * const markdown = createMarkdown('# Hi\\n\\nRead the [guide](./guide.md).')\n * markdown.document.children[0] // { element: 'heading', ... }\n * ```\n */\nexport function createMarkdown(input: string | MarkdownDocument): MarkdownInterface {\n\treturn new Markdown(input)\n}\n\n/**\n * Compiles the {@link textShape} into a {@link ContractInterface} for\n * {@link TextNode} — a guard, coercing parser, JSON Schema, and seeded\n * generator from one shape declaration.\n *\n * @returns A `TextNode` contract bundling `schema` / `is` / `parse` / `generate`\n *\n * @example\n * ```ts\n * import { createTextContract } from '@src/core'\n *\n * const text = createTextContract()\n * text.is({ element: 'text', value: 'hi' }) // true\n * ```\n */\nexport function createTextContract(): ContractInterface<TextNode> {\n\treturn createContract(textShape)\n}\n\n/**\n * Compiles the {@link codeSpanShape} into a {@link ContractInterface} for\n * {@link CodeSpanNode} — a guard, coercing parser, JSON Schema, and seeded\n * generator from one shape declaration.\n *\n * @returns A `CodeSpanNode` contract bundling `schema` / `is` / `parse` / `generate`\n *\n * @example\n * ```ts\n * import { createCodeSpanContract } from '@src/core'\n *\n * const codeSpan = createCodeSpanContract()\n * codeSpan.is({ element: 'codeSpan', value: 'const x = 1' }) // true\n * ```\n */\nexport function createCodeSpanContract(): ContractInterface<CodeSpanNode> {\n\treturn createContract(codeSpanShape)\n}\n\n/**\n * Compiles the {@link lineBreakShape} into a {@link ContractInterface} for\n * {@link LineBreakNode}.\n *\n * @returns A `LineBreakNode` contract bundling `schema` / `is` / `parse` / `generate`\n *\n * @example\n * ```ts\n * import { createLineBreakContract } from '@src/core'\n *\n * createLineBreakContract().is({ element: 'break' }) // true\n * ```\n */\nexport function createLineBreakContract(): ContractInterface<LineBreakNode> {\n\treturn createContract(lineBreakShape)\n}\n\n/**\n * Compiles the {@link codeBlockShape} into a {@link ContractInterface} for\n * {@link CodeBlockNode} — a guard, coercing parser, JSON Schema, and seeded\n * generator from one shape declaration.\n *\n * @returns A `CodeBlockNode` contract bundling `schema` / `is` / `parse` / `generate`\n *\n * @example\n * ```ts\n * import { createCodeBlockContract } from '@src/core'\n *\n * const codeBlock = createCodeBlockContract()\n * codeBlock.is({ element: 'codeBlock', code: 'x' }) // true\n * ```\n */\nexport function createCodeBlockContract(): ContractInterface<CodeBlockNode> {\n\treturn createContract(codeBlockShape)\n}\n\n/**\n * Compiles the {@link thematicBreakShape} into a {@link ContractInterface} for\n * {@link ThematicBreakNode} — a guard, coercing parser, JSON Schema, and\n * seeded generator from one shape declaration.\n *\n * @returns A `ThematicBreakNode` contract bundling `schema` / `is` / `parse` / `generate`\n *\n * @example\n * ```ts\n * import { createThematicBreakContract } from '@src/core'\n *\n * const thematicBreak = createThematicBreakContract()\n * thematicBreak.is({ element: 'thematicBreak' }) // true\n * ```\n */\nexport function createThematicBreakContract(): ContractInterface<ThematicBreakNode> {\n\treturn createContract(thematicBreakShape)\n}\n"],"mappings":"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"}