@temelj/mdx 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +468 -82
- package/dist/character-entities.d.mts +4 -0
- package/dist/character-entities.d.mts.map +1 -0
- package/dist/character-entities.mjs +2132 -0
- package/dist/character-entities.mjs.map +1 -0
- package/dist/character-reference.d.mts +6 -0
- package/dist/character-reference.d.mts.map +1 -0
- package/dist/character-reference.mjs +18 -0
- package/dist/character-reference.mjs.map +1 -0
- package/dist/compile-analysis.d.mts +28 -0
- package/dist/compile-analysis.d.mts.map +1 -0
- package/dist/compile-analysis.mjs +74 -0
- package/dist/compile-analysis.mjs.map +1 -0
- package/dist/compile-emit.d.mts +9 -0
- package/dist/compile-emit.d.mts.map +1 -0
- package/dist/compile-emit.mjs +187 -0
- package/dist/compile-emit.mjs.map +1 -0
- package/dist/compile-esm.d.mts +34 -0
- package/dist/compile-esm.d.mts.map +1 -0
- package/dist/compile-esm.mjs +187 -0
- package/dist/compile-esm.mjs.map +1 -0
- package/dist/compile-names.d.mts +13 -0
- package/dist/compile-names.d.mts.map +1 -0
- package/dist/compile-names.mjs +32 -0
- package/dist/compile-names.mjs.map +1 -0
- package/dist/compiler.d.mts +69 -85
- package/dist/compiler.d.mts.map +1 -1
- package/dist/compiler.mjs +185 -418
- package/dist/compiler.mjs.map +1 -1
- package/dist/diagnostics.d.mts +37 -0
- package/dist/diagnostics.d.mts.map +1 -0
- package/dist/diagnostics.mjs +57 -0
- package/dist/diagnostics.mjs.map +1 -0
- package/dist/errors.d.mts +157 -0
- package/dist/errors.d.mts.map +1 -0
- package/dist/errors.mjs +263 -0
- package/dist/errors.mjs.map +1 -0
- package/dist/footnote-numbering.d.mts +27 -0
- package/dist/footnote-numbering.d.mts.map +1 -0
- package/dist/footnote-numbering.mjs +49 -0
- package/dist/footnote-numbering.mjs.map +1 -0
- package/dist/format-context.d.mts +46 -0
- package/dist/format-context.d.mts.map +1 -0
- package/dist/format-context.mjs +26 -0
- package/dist/format-context.mjs.map +1 -0
- package/dist/format-directive.d.mts +9 -0
- package/dist/format-directive.d.mts.map +1 -0
- package/dist/format-directive.mjs +99 -0
- package/dist/format-directive.mjs.map +1 -0
- package/dist/format-jsx.d.mts +8 -0
- package/dist/format-jsx.d.mts.map +1 -0
- package/dist/format-jsx.mjs +47 -0
- package/dist/format-jsx.mjs.map +1 -0
- package/dist/format-math.d.mts +9 -0
- package/dist/format-math.d.mts.map +1 -0
- package/dist/format-math.mjs +79 -0
- package/dist/format-math.mjs.map +1 -0
- package/dist/format-safe.d.mts +25 -0
- package/dist/format-safe.d.mts.map +1 -0
- package/dist/format-safe.mjs +366 -0
- package/dist/format-safe.mjs.map +1 -0
- package/dist/format-table.d.mts +8 -0
- package/dist/format-table.d.mts.map +1 -0
- package/dist/format-table.mjs +55 -0
- package/dist/format-table.mjs.map +1 -0
- package/dist/format-track.d.mts +18 -0
- package/dist/format-track.d.mts.map +1 -0
- package/dist/format-track.mjs +34 -0
- package/dist/format-track.mjs.map +1 -0
- package/dist/format.d.mts +7 -0
- package/dist/format.d.mts.map +1 -0
- package/dist/format.mjs +549 -0
- package/dist/format.mjs.map +1 -0
- package/dist/frontmatter.d.mts +15 -0
- package/dist/frontmatter.d.mts.map +1 -0
- package/dist/frontmatter.mjs +187 -0
- package/dist/frontmatter.mjs.map +1 -0
- package/dist/heading.d.mts +6 -0
- package/dist/heading.d.mts.map +1 -0
- package/dist/heading.mjs +19 -0
- package/dist/heading.mjs.map +1 -0
- package/dist/html-format.d.mts +32 -0
- package/dist/html-format.d.mts.map +1 -0
- package/dist/html-format.mjs +127 -0
- package/dist/html-format.mjs.map +1 -0
- package/dist/html-lower.d.mts +78 -0
- package/dist/html-lower.d.mts.map +1 -0
- package/dist/html-lower.mjs +583 -0
- package/dist/html-lower.mjs.map +1 -0
- package/dist/html-stream.d.mts +13 -0
- package/dist/html-stream.d.mts.map +1 -0
- package/dist/html-stream.mjs +32 -0
- package/dist/html-stream.mjs.map +1 -0
- package/dist/html.d.mts +120 -0
- package/dist/html.d.mts.map +1 -0
- package/dist/html.mjs +77 -0
- package/dist/html.mjs.map +1 -0
- package/dist/identifier.d.mts +4 -0
- package/dist/identifier.d.mts.map +1 -0
- package/dist/identifier.mjs +8 -0
- package/dist/identifier.mjs.map +1 -0
- package/dist/javascript-ast.d.mts +16 -0
- package/dist/javascript-ast.d.mts.map +1 -0
- package/dist/javascript-ast.mjs +39 -0
- package/dist/javascript-ast.mjs.map +1 -0
- package/dist/javascript-jsx.d.mts +24 -0
- package/dist/javascript-jsx.d.mts.map +1 -0
- package/dist/javascript-jsx.mjs +189 -0
- package/dist/javascript-jsx.mjs.map +1 -0
- package/dist/javascript.d.mts +9 -0
- package/dist/javascript.d.mts.map +1 -0
- package/dist/javascript.mjs +31 -0
- package/dist/javascript.mjs.map +1 -0
- package/dist/jsx-reference.d.mts +15 -0
- package/dist/jsx-reference.d.mts.map +1 -0
- package/dist/jsx-reference.mjs +31 -0
- package/dist/jsx-reference.mjs.map +1 -0
- package/dist/mod.d.mts +25 -9
- package/dist/mod.mjs +19 -8
- package/dist/model.d.mts +196 -0
- package/dist/model.d.mts.map +1 -0
- package/dist/model.mjs +113 -0
- package/dist/model.mjs.map +1 -0
- package/dist/parser/block-container-recognizers.d.mts +40 -0
- package/dist/parser/block-container-recognizers.d.mts.map +1 -0
- package/dist/parser/block-container-recognizers.mjs +90 -0
- package/dist/parser/block-container-recognizers.mjs.map +1 -0
- package/dist/parser/block-directive-recognizers.d.mts +22 -0
- package/dist/parser/block-directive-recognizers.d.mts.map +1 -0
- package/dist/parser/block-directive-recognizers.mjs +77 -0
- package/dist/parser/block-directive-recognizers.mjs.map +1 -0
- package/dist/parser/block-leaf-recognizers.d.mts +53 -0
- package/dist/parser/block-leaf-recognizers.d.mts.map +1 -0
- package/dist/parser/block-leaf-recognizers.mjs +386 -0
- package/dist/parser/block-leaf-recognizers.mjs.map +1 -0
- package/dist/parser/block-parser.d.mts +38 -0
- package/dist/parser/block-parser.d.mts.map +1 -0
- package/dist/parser/block-parser.mjs +895 -0
- package/dist/parser/block-parser.mjs.map +1 -0
- package/dist/parser/block-syntax.d.mts +240 -0
- package/dist/parser/block-syntax.d.mts.map +1 -0
- package/dist/parser/characters.d.mts +19 -0
- package/dist/parser/characters.d.mts.map +1 -0
- package/dist/parser/characters.mjs +52 -0
- package/dist/parser/characters.mjs.map +1 -0
- package/dist/parser/config.d.mts +16 -0
- package/dist/parser/config.d.mts.map +1 -0
- package/dist/parser/config.mjs +25 -0
- package/dist/parser/config.mjs.map +1 -0
- package/dist/parser/directive-attributes.d.mts +9 -0
- package/dist/parser/directive-attributes.d.mts.map +1 -0
- package/dist/parser/directive-attributes.mjs +24 -0
- package/dist/parser/directive-attributes.mjs.map +1 -0
- package/dist/parser/embedded-scanner.d.mts +18 -0
- package/dist/parser/embedded-scanner.d.mts.map +1 -0
- package/dist/parser/embedded-scanner.mjs +199 -0
- package/dist/parser/embedded-scanner.mjs.map +1 -0
- package/dist/parser/inline-autolink.d.mts +7 -0
- package/dist/parser/inline-autolink.d.mts.map +1 -0
- package/dist/parser/inline-autolink.mjs +42 -0
- package/dist/parser/inline-autolink.mjs.map +1 -0
- package/dist/parser/inline-character-reference.d.mts +7 -0
- package/dist/parser/inline-character-reference.d.mts.map +1 -0
- package/dist/parser/inline-character-reference.mjs +22 -0
- package/dist/parser/inline-character-reference.mjs.map +1 -0
- package/dist/parser/inline-code.d.mts +7 -0
- package/dist/parser/inline-code.d.mts.map +1 -0
- package/dist/parser/inline-code.mjs +29 -0
- package/dist/parser/inline-code.mjs.map +1 -0
- package/dist/parser/inline-directive.d.mts +9 -0
- package/dist/parser/inline-directive.d.mts.map +1 -0
- package/dist/parser/inline-directive.mjs +45 -0
- package/dist/parser/inline-directive.mjs.map +1 -0
- package/dist/parser/inline-embedded.d.mts +19 -0
- package/dist/parser/inline-embedded.d.mts.map +1 -0
- package/dist/parser/inline-embedded.mjs +92 -0
- package/dist/parser/inline-embedded.mjs.map +1 -0
- package/dist/parser/inline-emphasis.d.mts +11 -0
- package/dist/parser/inline-emphasis.d.mts.map +1 -0
- package/dist/parser/inline-emphasis.mjs +79 -0
- package/dist/parser/inline-emphasis.mjs.map +1 -0
- package/dist/parser/inline-input.d.mts +46 -0
- package/dist/parser/inline-input.d.mts.map +1 -0
- package/dist/parser/inline-input.mjs +137 -0
- package/dist/parser/inline-input.mjs.map +1 -0
- package/dist/parser/inline-link.d.mts +12 -0
- package/dist/parser/inline-link.d.mts.map +1 -0
- package/dist/parser/inline-link.mjs +187 -0
- package/dist/parser/inline-link.mjs.map +1 -0
- package/dist/parser/inline-math.d.mts +10 -0
- package/dist/parser/inline-math.d.mts.map +1 -0
- package/dist/parser/inline-math.mjs +46 -0
- package/dist/parser/inline-math.mjs.map +1 -0
- package/dist/parser/inline-output.d.mts +34 -0
- package/dist/parser/inline-output.d.mts.map +1 -0
- package/dist/parser/inline-output.mjs +62 -0
- package/dist/parser/inline-output.mjs.map +1 -0
- package/dist/parser/inline-parser.d.mts +14 -0
- package/dist/parser/inline-parser.d.mts.map +1 -0
- package/dist/parser/inline-parser.mjs +328 -0
- package/dist/parser/inline-parser.mjs.map +1 -0
- package/dist/parser/inline-pending.d.mts +23 -0
- package/dist/parser/inline-pending.d.mts.map +1 -0
- package/dist/parser/inline-pending.mjs +100 -0
- package/dist/parser/inline-pending.mjs.map +1 -0
- package/dist/parser/inline-syntax.d.mts +118 -0
- package/dist/parser/inline-syntax.d.mts.map +1 -0
- package/dist/parser/inline-syntax.mjs +1 -0
- package/dist/parser/javascript-boundary.d.mts +16 -0
- package/dist/parser/javascript-boundary.d.mts.map +1 -0
- package/dist/parser/javascript-boundary.mjs +42 -0
- package/dist/parser/javascript-boundary.mjs.map +1 -0
- package/dist/parser/javascript-scanner.d.mts +22 -0
- package/dist/parser/javascript-scanner.d.mts.map +1 -0
- package/dist/parser/javascript-scanner.mjs +122 -0
- package/dist/parser/javascript-scanner.mjs.map +1 -0
- package/dist/parser/materialize-cache.d.mts +34 -0
- package/dist/parser/materialize-cache.d.mts.map +1 -0
- package/dist/parser/materialize-cache.mjs +12 -0
- package/dist/parser/materialize-cache.mjs.map +1 -0
- package/dist/parser/materialize-jsx.d.mts +14 -0
- package/dist/parser/materialize-jsx.d.mts.map +1 -0
- package/dist/parser/materialize-jsx.mjs +76 -0
- package/dist/parser/materialize-jsx.mjs.map +1 -0
- package/dist/parser/materialize.d.mts +61 -0
- package/dist/parser/materialize.d.mts.map +1 -0
- package/dist/parser/materialize.mjs +736 -0
- package/dist/parser/materialize.mjs.map +1 -0
- package/dist/parser/recognizer.d.mts +20 -0
- package/dist/parser/recognizer.d.mts.map +1 -0
- package/dist/parser/recognizer.mjs +24 -0
- package/dist/parser/recognizer.mjs.map +1 -0
- package/dist/parser/session.d.mts +42 -0
- package/dist/parser/session.d.mts.map +1 -0
- package/dist/parser/session.mjs +89 -0
- package/dist/parser/session.mjs.map +1 -0
- package/dist/parser.d.mts +25 -0
- package/dist/parser.d.mts.map +1 -0
- package/dist/parser.mjs +37 -0
- package/dist/parser.mjs.map +1 -0
- package/dist/plugin-internal.d.mts +25 -0
- package/dist/plugin-internal.d.mts.map +1 -0
- package/dist/plugin-internal.mjs +99 -0
- package/dist/plugin-internal.mjs.map +1 -0
- package/dist/plugin.d.mts +37 -0
- package/dist/plugin.d.mts.map +1 -0
- package/dist/plugin.mjs +1 -0
- package/dist/plugins/code-block-metadata.d.mts +42 -0
- package/dist/plugins/code-block-metadata.d.mts.map +1 -0
- package/dist/plugins/code-block-metadata.mjs +133 -0
- package/dist/plugins/code-block-metadata.mjs.map +1 -0
- package/dist/plugins/heading-id.d.mts +15 -0
- package/dist/plugins/heading-id.d.mts.map +1 -0
- package/dist/plugins/heading-id.mjs +45 -0
- package/dist/plugins/heading-id.mjs.map +1 -0
- package/dist/plugins/lower-heading.d.mts +16 -0
- package/dist/plugins/lower-heading.d.mts.map +1 -0
- package/dist/plugins/lower-heading.mjs +28 -0
- package/dist/plugins/lower-heading.mjs.map +1 -0
- package/dist/plugins/math-render.d.mts +26 -0
- package/dist/plugins/math-render.d.mts.map +1 -0
- package/dist/plugins/math-render.mjs +51 -0
- package/dist/plugins/math-render.mjs.map +1 -0
- package/dist/plugins/mod.d.mts +9 -6
- package/dist/plugins/mod.mjs +8 -6
- package/dist/plugins/remove-esm.d.mts +10 -0
- package/dist/plugins/remove-esm.d.mts.map +1 -0
- package/dist/plugins/remove-esm.mjs +12 -0
- package/dist/plugins/remove-esm.mjs.map +1 -0
- package/dist/plugins/shiki.d.mts +21 -0
- package/dist/plugins/shiki.d.mts.map +1 -0
- package/dist/plugins/shiki.mjs +144 -0
- package/dist/plugins/shiki.mjs.map +1 -0
- package/dist/plugins/syntax-highlight.d.mts +38 -0
- package/dist/plugins/syntax-highlight.d.mts.map +1 -0
- package/dist/plugins/syntax-highlight.mjs +106 -0
- package/dist/plugins/syntax-highlight.mjs.map +1 -0
- package/dist/processor.d.mts +60 -0
- package/dist/processor.d.mts.map +1 -0
- package/dist/processor.mjs +106 -0
- package/dist/processor.mjs.map +1 -0
- package/dist/ranges.d.mts +10 -0
- package/dist/ranges.d.mts.map +1 -0
- package/dist/ranges.mjs +22 -0
- package/dist/ranges.mjs.map +1 -0
- package/dist/source-map.d.mts +28 -0
- package/dist/source-map.d.mts.map +1 -0
- package/dist/source-map.mjs +90 -0
- package/dist/source-map.mjs.map +1 -0
- package/dist/source-text.d.mts +35 -0
- package/dist/source-text.d.mts.map +1 -0
- package/dist/source-text.mjs +132 -0
- package/dist/source-text.mjs.map +1 -0
- package/dist/source.d.mts +86 -0
- package/dist/source.d.mts.map +1 -0
- package/dist/source.mjs +264 -0
- package/dist/source.mjs.map +1 -0
- package/dist/stream-events.d.mts +59 -0
- package/dist/stream-events.d.mts.map +1 -0
- package/dist/stream-events.mjs +115 -0
- package/dist/stream-events.mjs.map +1 -0
- package/dist/stream-session.d.mts +79 -0
- package/dist/stream-session.d.mts.map +1 -0
- package/dist/stream-session.mjs +904 -0
- package/dist/stream-session.mjs.map +1 -0
- package/dist/stream-tail.d.mts +84 -0
- package/dist/stream-tail.d.mts.map +1 -0
- package/dist/stream-tail.mjs +359 -0
- package/dist/stream-tail.mjs.map +1 -0
- package/dist/stream-types.d.mts +89 -0
- package/dist/stream-types.d.mts.map +1 -0
- package/dist/stream-types.mjs +1 -0
- package/dist/stream.d.mts +28 -0
- package/dist/stream.d.mts.map +1 -0
- package/dist/stream.mjs +68 -0
- package/dist/stream.mjs.map +1 -0
- package/dist/syntax-options.d.mts +21 -0
- package/dist/syntax-options.d.mts.map +1 -0
- package/dist/syntax-options.mjs +26 -0
- package/dist/syntax-options.mjs.map +1 -0
- package/dist/traversal.d.mts +25 -0
- package/dist/traversal.d.mts.map +1 -0
- package/dist/traversal.mjs +136 -0
- package/dist/traversal.mjs.map +1 -0
- package/dist/tree.d.mts +18 -0
- package/dist/tree.d.mts.map +1 -0
- package/dist/tree.mjs +43 -0
- package/dist/tree.mjs.map +1 -0
- package/dist/unified/adapter.d.mts +24 -0
- package/dist/unified/adapter.d.mts.map +1 -0
- package/dist/unified/adapter.mjs +44 -0
- package/dist/unified/adapter.mjs.map +1 -0
- package/dist/unified/mod.d.mts +2 -0
- package/dist/unified/mod.mjs +1 -0
- package/dist/unified/runtime.d.mts +10 -0
- package/dist/unified/runtime.d.mts.map +1 -0
- package/dist/unified/runtime.mjs +115 -0
- package/dist/unified/runtime.mjs.map +1 -0
- package/dist/unified/tree-bridge.d.mts +63 -0
- package/dist/unified/tree-bridge.d.mts.map +1 -0
- package/dist/unified/tree-bridge.mjs +876 -0
- package/dist/unified/tree-bridge.mjs.map +1 -0
- package/dist/uri.d.mts +5 -0
- package/dist/uri.d.mts.map +1 -0
- package/dist/uri.mjs +32 -0
- package/dist/uri.mjs.map +1 -0
- package/package.json +56 -30
- package/dist/plugins/heading-id/plugin.d.mts +0 -17
- package/dist/plugins/heading-id/plugin.d.mts.map +0 -1
- package/dist/plugins/heading-id/plugin.mjs +0 -23
- package/dist/plugins/heading-id/plugin.mjs.map +0 -1
- package/dist/plugins/katex/plugin.d.mts +0 -39
- package/dist/plugins/katex/plugin.d.mts.map +0 -1
- package/dist/plugins/katex/plugin.mjs +0 -107
- package/dist/plugins/katex/plugin.mjs.map +0 -1
- package/dist/plugins/remove-imports-exports.d.mts +0 -10
- package/dist/plugins/remove-imports-exports.d.mts.map +0 -1
- package/dist/plugins/remove-imports-exports.mjs +0 -15
- package/dist/plugins/remove-imports-exports.mjs.map +0 -1
- package/dist/plugins/syntax-highlight/code-meta.d.mts +0 -22
- package/dist/plugins/syntax-highlight/code-meta.d.mts.map +0 -1
- package/dist/plugins/syntax-highlight/code-meta.mjs +0 -38
- package/dist/plugins/syntax-highlight/code-meta.mjs.map +0 -1
- package/dist/plugins/syntax-highlight/plugin.d.mts +0 -57
- package/dist/plugins/syntax-highlight/plugin.d.mts.map +0 -1
- package/dist/plugins/syntax-highlight/plugin.mjs +0 -93
- package/dist/plugins/syntax-highlight/plugin.mjs.map +0 -1
- package/dist/plugins/tree-processor/plugin.d.mts +0 -19
- package/dist/plugins/tree-processor/plugin.d.mts.map +0 -1
- package/dist/plugins/tree-processor/plugin.mjs +0 -21
- package/dist/plugins/tree-processor/plugin.mjs.map +0 -1
- package/dist/types.d.mts +0 -2
- /package/dist/{types.mjs → parser/block-syntax.mjs} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-session.mjs","names":[],"sources":["../src/stream-session.ts"],"sourcesContent":["import type { Diagnostic } from \"./diagnostics.ts\";\nimport type { FootnoteOccurrence } from \"./footnote-numbering.ts\";\nimport type { LoweringScope } from \"./html-lower.ts\";\nimport type { HtmlFootnoteSectionNode, HtmlNode } from \"./html.ts\";\nimport type {\n DefinitionNode,\n DocumentNode,\n FlowContent,\n FootnoteDefinitionNode,\n FootnoteReferenceNode,\n ListItemNode,\n ListNode,\n MdxNode,\n TextNode,\n} from \"./model.ts\";\nimport type { BlockSyntax, PendingBlockSyntax } from \"./parser/block-syntax.ts\";\nimport type { ParserLimit, ResolvedParserLimits } from \"./parser/config.ts\";\nimport type { DefinitionLookup } from \"./parser/inline-syntax.ts\";\nimport type { PhrasingCache } from \"./parser/materialize.ts\";\nimport type { SourceText } from \"./source-text.ts\";\nimport type {\n BlockId,\n CompletedBlock,\n MdxEdit,\n MdxStreamChange,\n MdxStreamCompletion,\n MdxStreamSnapshot,\n StreamBlock,\n StreamDependencies,\n} from \"./stream-types.ts\";\nimport type { SyntaxOptions } from \"./syntax-options.ts\";\n\nimport { createDiagnostic } from \"./diagnostics.ts\";\nimport { LimitError, ParseError } from \"./errors.ts\";\nimport { FootnoteNumbering } from \"./footnote-numbering.ts\";\nimport { createHtmlLoweringCache, lowerFootnoteSection, lowerNodes } from \"./html-lower.ts\";\nimport { mdxChildren } from \"./model.ts\";\nimport { createMaterializeCache } from \"./parser/materialize-cache.ts\";\nimport { materializeDocument } from \"./parser/materialize.ts\";\nimport { ParserSession } from \"./parser/session.ts\";\nimport { rangesIntersect, shiftRange, type SourceRange } from \"./ranges.ts\";\nimport { SourceBuffer, sourceText, type SourceFile } from \"./source.ts\";\nimport { FenceText, lowerOpenLeaf, OpenParagraph, trimOpenTail } from \"./stream-tail.ts\";\nimport { rewriteMdx } from \"./traversal.ts\";\n\nexport interface StreamSessionOptions {\n readonly name: string;\n readonly source: string;\n readonly syntax: SyntaxOptions | undefined;\n readonly limits: ResolvedParserLimits;\n readonly maximumPendingBlockLength: number;\n}\n\n/** Parser output for one top-level block, materialized once. */\ntype Materialized =\n | Readonly<{\n kind: \"ok\";\n node: FlowContent;\n nodeCount: number;\n references: readonly string[];\n diagnostics: readonly Diagnostic[];\n contents: BlockContents;\n }>\n | Readonly<{ kind: \"invalid\"; diagnostics: readonly Diagnostic[] }>\n | Readonly<{ kind: \"limitExceeded\"; limit: ParserLimit }>;\n\n/** References a block makes and definitions it contains, in document order. */\ninterface BlockContents {\n readonly definitionReferences: readonly string[];\n readonly footnoteReferences: readonly FootnoteReferenceNode[];\n readonly definitions: readonly DefinitionNode[];\n readonly footnotes: readonly FootnoteDefinitionNode[];\n}\n\ntype Occurrences = readonly (FootnoteOccurrence | undefined)[];\n\ninterface BlockEntry {\n readonly syntax: BlockSyntax;\n readonly id: BlockId;\n readonly origin: SourceRange;\n readonly materialized: Materialized;\n /** The open leaf the block rendered, which later input may extend. */\n readonly pending: PendingBlockSyntax | undefined;\n /** Nodes the open leaf materialized while rendering, for the node limit. */\n readonly pendingNodes: number;\n /** The numbering the block rendered with, aligned with its footnote references. */\n readonly occurrences: Occurrences;\n /** `undefined` until the block renders. */\n readonly block: StreamBlock | undefined;\n}\n\ntype RenderedEntry = BlockEntry & { readonly block: StreamBlock };\n\n/** Definitions by identifier, first per identifier in document order. */\ninterface Definitions {\n readonly links: ReadonlyMap<string, DefinitionNode>;\n readonly footnotes: ReadonlyMap<string, FootnoteDefinitionNode>;\n}\n\ninterface Settlement {\n readonly syntax: BlockSyntax;\n readonly index: number;\n}\n\ninterface LimitState {\n readonly limit: ParserLimit;\n readonly offset: number;\n}\n\nconst EMPTY_DEFINITIONS: Definitions = { links: new Map(), footnotes: new Map() };\n\nconst NO_OCCURRENCES: Occurrences = Object.freeze([]);\n\nconst NO_DEPENDENCIES: StreamDependencies = Object.freeze({\n definitions: Object.freeze([]),\n footnotes: Object.freeze([]),\n});\n\n/**\n * Owns the parser and the rendered blocks of one stream. A top-level block\n * settles once later input cannot change it, and then materializes and lowers\n * once. Each append renders only the open tail; a settled block renders again\n * only when a definition or footnote number it uses changes.\n */\nexport class StreamSession {\n readonly #limits: ResolvedParserLimits;\n readonly #maximumPendingBlockLength: number;\n readonly #parser: ParserSession;\n /** The stream owns its source; each version is an immutable file. */\n readonly #source: SourceBuffer;\n #file: SourceFile;\n\n /** Settled parser output that has not been rendered yet. */\n #queue: Settlement[] = [];\n #settled: BlockEntry[] = [];\n /** The settled blocks' renderings, kept beside the entries so a snapshot copies one array. */\n #blocks: StreamBlock[] = [];\n #tail: RenderedEntry[] = [];\n\n // Running totals over the settled blocks.\n #definitions: Definitions = EMPTY_DEFINITIONS;\n #dependents = new Map<string, Set<number>>();\n #nodes = 0;\n #diagnostics: Diagnostic[] = [];\n #limited: LimitState | undefined;\n readonly #referenceLimits = new Map<number, LimitState>();\n #numbering = new FootnoteNumbering();\n #occurrences = new WeakMap<FootnoteReferenceNode, FootnoteOccurrence>();\n\n // The open tail, rebuilt on every change.\n #tailDefinitions: Definitions = EMPTY_DEFINITIONS;\n #tailNumbering = new FootnoteNumbering();\n #tailOccurrences = new WeakMap<FootnoteReferenceNode, FootnoteOccurrence>();\n\n #definitionsVersion = 0;\n #footnotes: HtmlFootnoteSectionNode | undefined;\n #footnotesKey: readonly unknown[] = [];\n #materializeCache = createMaterializeCache();\n #loweringCache = createHtmlLoweringCache();\n readonly #fence = new FenceText();\n readonly #paragraph = new OpenParagraph();\n readonly #phrasing: PhrasingCache = new WeakMap();\n #nextId = 0;\n #current: MdxStreamChange;\n #lastValid: MdxStreamSnapshot | undefined;\n /** The settled numbering must restart, because settled blocks were dropped. */\n #renumber = false;\n #limitedPreview = false;\n\n public constructor(options: StreamSessionOptions) {\n this.#limits = options.limits;\n this.#maximumPendingBlockLength = options.maximumPendingBlockLength;\n this.#source = new SourceBuffer({ name: options.name, text: options.source });\n this.#file = this.#source.file;\n\n this.#parser = new ParserSession({\n source: this.#file,\n syntax: options.syntax,\n onSettled: (syntax, index) => this.#queue.push({ syntax, index }),\n });\n\n this.#current = this.update(0);\n }\n\n /** The latest change, whose snapshot is the current preview. */\n public get current(): MdxStreamChange {\n return this.#current;\n }\n\n public append(text: string): MdxStreamChange {\n const start = this.#settled.length;\n this.#file = this.#source.append(text);\n // The parser shares the file text, so the growing string is flattened only once.\n this.#parser.append(text, sourceText(this.#file));\n this.#current = this.update(start);\n\n return this.#current;\n }\n\n public edit(edit: MdxEdit): MdxStreamChange {\n const retired = this.retiredIds(edit);\n this.#file = this.#source.replace(edit.start, edit.end, edit.text);\n this.#parser.edit(edit);\n this.#current = this.update(this.#settled.length, retired);\n\n return this.#current;\n }\n\n /**\n * Finishes the tail strictly and assembles the document from the settled\n * blocks' nodes, so only the tail materializes again.\n */\n public complete(): MdxStreamCompletion {\n const limited = this.limitState();\n\n if (limited !== undefined && limited.limit !== \"maximumPendingBlockLength\") {\n throw this.limitError(limited);\n }\n\n // The tail draft finishes a copy, so a failed completion leaves the stream open.\n const tail = this.#parser.tailDraft().blocks;\n const settled = this.#settled;\n\n const diagnostics: Diagnostic[] = [];\n const errors: Diagnostic[] = [];\n const parts: CompletedPart[] = [];\n let nodes = 1 + this.#nodes;\n\n for (const entry of settled) {\n if (entry.materialized.kind === \"invalid\") {\n errors.push(...entry.materialized.diagnostics);\n } else if (entry.materialized.kind === \"ok\") {\n diagnostics.push(...entry.materialized.diagnostics);\n parts.push({ id: entry.id, origin: entry.origin, node: entry.materialized.node });\n }\n }\n\n const tailIds = new Map(this.#tail.map((entry) => [entry.origin.start, entry.id]));\n\n for (const syntax of tail) {\n const origin = blockOrigin(sourceText(this.#file), syntax);\n\n const materialized = materializeDocument(\n this.#file,\n [syntax],\n this.#parser.syntax,\n { ...this.#limits, maximumNodes: Math.max(1, this.#limits.maximumNodes - nodes + 1) },\n {\n keepReferences: true,\n cache: this.#materializeCache,\n definitionLookup: this.effectiveDefinitions().links,\n },\n );\n\n if (materialized.kind === \"limitExceeded\") {\n throw this.limitError({ limit: materialized.limit, offset: origin.end });\n }\n\n if (materialized.kind === \"invalid\") {\n errors.push(...materialized.diagnostics);\n continue;\n }\n\n diagnostics.push(...materialized.diagnostics);\n\n for (const block of materialized.blocks) {\n nodes += block.nodeCount;\n parts.push({ id: tailIds.get(origin.start) ?? this.newId(), origin, node: block.node });\n }\n }\n\n const [firstError, ...otherErrors] = errors;\n\n if (firstError !== undefined) {\n throw ParseError.invalidSyntax(this.#file, [firstError, ...otherErrors]);\n }\n\n if (nodes > this.#limits.maximumNodes) {\n throw this.limitError({ limit: \"maximumNodes\", offset: this.#file.length });\n }\n\n const definitions = collectDefinitions(parts.map((part) => part.node));\n\n const document: DocumentNode = {\n kind: \"document\",\n children: parts.map((part) => resolveReferences(part.node, definitions, this.#file)),\n origin: { start: 0, end: this.#file.length },\n };\n\n return Object.freeze({\n kind: \"complete\",\n file: this.#file,\n document,\n blocks: Object.freeze(\n parts.map((part): CompletedBlock => Object.freeze({ id: part.id, origin: part.origin })),\n ),\n diagnostics: Object.freeze(diagnostics),\n });\n }\n\n /**\n * Settles queued blocks, renders the blocks whose definitions or footnote\n * numbers changed, renders the open tail, and assembles the snapshot.\n */\n private update(previousSettled: number, retired?: ReadonlyMap<string, BlockId>): MdxStreamChange {\n if (this.#file.length > this.#limits.maximumSourceLength) {\n return this.limitChange({ limit: \"maximumSourceLength\", offset: this.#file.length });\n }\n\n const before = this.effectiveDefinitions();\n const previousTail = this.#tail;\n const start = Math.min(previousSettled, this.dropChangedSettled());\n const firstAdded = this.#settled.length;\n const adopted = this.settleQueued(previousTail, retired);\n\n const draft = this.#parser.tailDraft();\n const parts = draft.blocks.map((syntax) => this.materializeTail(syntax, draft.pending));\n this.#tailDefinitions = collectDefinitions(parts.flatMap(materializedNodes));\n const after = this.effectiveDefinitions();\n const changed = changedDefinitions(before, after);\n const refreshed = this.refreshSettled(changed, after, firstAdded, adopted, start);\n const settledDefinitions = this.effectiveDefinitions();\n\n const resolvedParts = parts.map((part) => {\n if (\n part.materialized.kind !== \"ok\" ||\n !part.materialized.references.some((id) => changed.links.has(id))\n ) {\n return part;\n }\n\n return {\n ...part,\n materialized: this.materialize(\n part.syntax,\n this.#limits.maximumNodes - 1 - this.#nodes,\n part.pending !== undefined && containsRange(part.syntax.range, part.pending.range)\n ? part.pending.range\n : undefined,\n settledDefinitions.links,\n ),\n };\n });\n\n this.#tailDefinitions = collectDefinitions(resolvedParts.flatMap(materializedNodes));\n const resolvedDefinitions = this.effectiveDefinitions();\n this.renderTail(resolvedParts, previousTail, retired, resolvedDefinitions, changed.links);\n\n const footnotes = this.footnoteSection(resolvedDefinitions);\n const limited = this.limitState(draft.pending);\n\n if (limited !== undefined) {\n return this.limitChange(limited);\n }\n\n const snapshot: MdxStreamSnapshot = Object.freeze({\n kind: \"preview\",\n file: this.#file,\n blocks: Object.freeze([...this.#blocks, ...this.#tail.map((entry) => entry.block)]),\n footnotes,\n diagnostics: Object.freeze([\n ...this.#diagnostics,\n ...this.#tail.flatMap((entry) => entry.block.diagnostics),\n ]),\n limit: undefined,\n });\n\n // After a limited preview, consumers hold the last valid blocks, which can be older.\n const continuous = !this.#limitedPreview;\n this.#limitedPreview = false;\n const previous = this.#lastValid;\n this.#lastValid = snapshot;\n\n return Object.freeze({\n snapshot,\n start: previous !== undefined && continuous ? start : 0,\n refreshed: Object.freeze(continuous ? refreshed : []),\n footnotesChanged: footnotes !== previous?.footnotes,\n });\n }\n\n /**\n * Drops settled blocks that an edit replaced, which settle again from the\n * queue, and returns how many settled blocks remain.\n */\n private dropChangedSettled(): number {\n const keep = Math.min(\n this.#settled.length,\n this.#parser.settledCount,\n this.#queue[0]?.index ?? Infinity,\n );\n\n if (keep < this.#settled.length) {\n this.truncate(keep);\n }\n\n return this.#settled.length;\n }\n\n /** Settles queued parser output and returns the indexes of blocks adopted from the tail. */\n private settleQueued(\n previousTail: readonly RenderedEntry[],\n retired: ReadonlyMap<string, BlockId> | undefined,\n ): ReadonlySet<number> {\n const adopted = new Set<number>();\n\n for (const settlement of this.#queue) {\n if (settlement.index !== this.#settled.length) {\n continue;\n }\n\n const entry = this.settle(settlement.syntax, previousTail, retired);\n\n if (entry.block !== undefined) {\n adopted.add(this.#settled.length);\n }\n\n this.addSettled(entry);\n }\n\n this.#queue = [];\n\n return adopted;\n }\n\n /**\n * Renders newly settled blocks, and settled blocks whose definitions or\n * footnote numbers changed. Returns the re-rendered blocks before `start`.\n */\n private refreshSettled(\n changed: DefinitionChanges,\n definitions: Definitions,\n firstAdded: number,\n adopted: ReadonlySet<number>,\n start: number,\n ): StreamBlock[] {\n const dirty = new Set<number>();\n\n if (changed.links.size > 0) {\n // Cached subtrees may contain references to the changed definitions.\n this.#loweringCache = createHtmlLoweringCache();\n this.#materializeCache = createMaterializeCache();\n this.#definitionsVersion++;\n\n for (const identifier of changed.links) {\n for (const index of this.#dependents.get(identifier) ?? []) {\n dirty.add(index);\n }\n }\n }\n\n for (let index = firstAdded; index < this.#settled.length; index++) {\n if (!adopted.has(index)) {\n dirty.add(index);\n }\n }\n\n let rematerializedFootnotes = false;\n\n for (const index of this.#referenceLimits.keys()) {\n dirty.add(index);\n }\n\n for (const index of dirty) {\n const entry = this.#settled[index];\n\n if (\n entry.materialized.kind === \"ok\" &&\n (entry.materialized.references.some((id) => changed.links.has(id)) ||\n this.#referenceLimits.has(index))\n ) {\n const old = entry.materialized;\n const oldCount = old.nodeCount;\n\n const materialized = this.materialize(\n entry.syntax,\n this.#limits.maximumNodes - 1 - this.#nodes + oldCount,\n undefined,\n definitions.links,\n );\n\n if (materialized.kind === \"limitExceeded\") {\n this.#referenceLimits.set(index, { limit: materialized.limit, offset: entry.origin.end });\n continue;\n }\n\n this.#referenceLimits.delete(index);\n\n if (materialized.kind === \"ok\") {\n this.#definitions = {\n links: replaceDefinitions(\n this.#definitions.links,\n old.contents.definitions,\n materialized.contents.definitions,\n ),\n footnotes: replaceDefinitions(\n this.#definitions.footnotes,\n old.contents.footnotes,\n materialized.contents.footnotes,\n ),\n };\n }\n\n this.#nodes += (materialized.kind === \"ok\" ? materialized.nodeCount : 0) - oldCount;\n\n for (const identifier of old.contents.definitionReferences) {\n this.#dependents.get(identifier)?.delete(index);\n }\n\n if (materialized.kind === \"ok\") {\n for (const identifier of materialized.contents.definitionReferences) {\n const dependents = this.#dependents.get(identifier) ?? new Set<number>();\n dependents.add(index);\n this.#dependents.set(identifier, dependents);\n }\n }\n\n this.#settled[index] = { ...entry, materialized };\n rematerializedFootnotes ||= old.contents.footnoteReferences.length > 0;\n }\n }\n\n definitions = this.effectiveDefinitions();\n const renumberAll = changed.footnotes || this.#renumber || rematerializedFootnotes;\n this.#renumber = false;\n\n for (const index of this.renumber(renumberAll ? 0 : firstAdded)) {\n dirty.add(index);\n }\n\n const refreshed: StreamBlock[] = [];\n\n for (const index of dirty) {\n this.#settled[index] = this.render(\n this.#settled[index],\n definitions,\n this.#occurrences,\n true,\n );\n this.#blocks[index] = renderedBlock(this.#settled[index]);\n\n if (index < start) {\n refreshed.push(renderedBlock(this.#settled[index]));\n }\n }\n\n // An adopted tail block keeps its rendering and only becomes settled.\n for (const index of adopted) {\n const entry = this.#settled[index];\n const block = renderedBlock(entry);\n\n if (!dirty.has(index) && !block.settled) {\n this.#settled[index] = { ...entry, block: Object.freeze({ ...block, settled: true }) };\n this.#blocks[index] = renderedBlock(this.#settled[index]);\n }\n }\n\n return refreshed;\n }\n\n /** Adopts the tail's rendering for a block that settled unchanged, or queues it to render. */\n private settle(\n syntax: BlockSyntax,\n previousTail: readonly RenderedEntry[],\n retired: ReadonlyMap<string, BlockId> | undefined,\n ): BlockEntry {\n const adopted = previousTail.find(\n (entry) => entry.syntax === syntax && entry.pending === undefined,\n );\n\n if (adopted !== undefined) {\n return adopted;\n }\n\n const origin = blockOrigin(sourceText(this.#file), syntax);\n\n return {\n syntax,\n id: this.blockId(origin, previousTail, retired),\n origin,\n materialized: this.materialize(syntax, this.#limits.maximumNodes - 1 - this.#nodes),\n pending: undefined,\n pendingNodes: 0,\n occurrences: NO_OCCURRENCES,\n block: undefined,\n };\n }\n\n private materializeTail(syntax: BlockSyntax, pending: PendingBlockSyntax | undefined): TailPart {\n const open =\n pending !== undefined && containsRange(syntax.range, pending.range) ? pending : undefined;\n\n return {\n syntax,\n origin: blockOrigin(sourceText(this.#file), syntax),\n materialized: this.materialize(\n syntax,\n this.#limits.maximumNodes - 1 - this.#nodes,\n open?.range,\n ),\n pending: open,\n };\n }\n\n private materialize(\n syntax: BlockSyntax,\n budget: number,\n open?: SourceRange,\n definitions: DefinitionLookup = this.effectiveDefinitions().links,\n ): Materialized {\n if (budget < 1) {\n return { kind: \"limitExceeded\", limit: \"maximumNodes\" };\n }\n\n const result = materializeDocument(\n this.#file,\n [syntax],\n this.#parser.syntax,\n // The stream counts the document node once.\n { ...this.#limits, maximumNodes: budget + 1 },\n {\n keepReferences: true,\n allowIncomplete: true,\n cache: this.#materializeCache,\n open,\n definitionLookup: definitions,\n },\n );\n\n if (result.kind === \"limitExceeded\") {\n return { kind: \"limitExceeded\", limit: result.limit };\n }\n\n if (result.kind === \"invalid\") {\n return { kind: \"invalid\", diagnostics: result.diagnostics };\n }\n\n const [block] = result.blocks;\n\n if (block === undefined) {\n throw new Error(\"A stream block materialized to no node\");\n }\n\n const contents = blockContents(block.node);\n\n return {\n kind: \"ok\",\n node: block.node,\n nodeCount: block.nodeCount,\n references: block.references,\n diagnostics: result.diagnostics,\n contents: {\n ...contents,\n definitionReferences: [...new Set([...contents.definitionReferences, ...block.references])],\n },\n };\n }\n\n /** Adds one settled block to the running totals. Its rendering may still be pending. */\n private addSettled(entry: BlockEntry): void {\n const index = this.#settled.length;\n this.#settled.push(entry);\n // An entry without a rendering renders before the update publishes a snapshot.\n this.#blocks.push(entry.block ?? unrendered);\n const { materialized } = entry;\n\n if (materialized.kind === \"limitExceeded\") {\n this.#limited ??= { limit: materialized.limit, offset: entry.origin.end };\n\n return;\n }\n\n this.#diagnostics.push(...materialized.diagnostics);\n\n if (materialized.kind === \"invalid\") {\n return;\n }\n\n const { contents } = materialized;\n this.#nodes += materialized.nodeCount;\n\n if (contents.definitions.length > 0 || contents.footnotes.length > 0) {\n const links = new Map(this.#definitions.links);\n const footnotes = new Map(this.#definitions.footnotes);\n addFirst(links, contents.definitions);\n addFirst(footnotes, contents.footnotes);\n this.#definitions = { links, footnotes };\n }\n\n for (const identifier of contents.definitionReferences) {\n let dependents = this.#dependents.get(identifier);\n\n if (dependents === undefined) {\n dependents = new Set();\n this.#dependents.set(identifier, dependents);\n }\n\n dependents.add(index);\n }\n }\n\n /** Drops the settled blocks from `length` on, after an edit before them. */\n private truncate(length: number): void {\n const kept = this.#settled.slice(0, length);\n this.#settled = [];\n this.#blocks = [];\n this.#definitions = EMPTY_DEFINITIONS;\n this.#dependents = new Map();\n this.#nodes = 0;\n this.#diagnostics = [];\n this.#limited = undefined;\n\n for (const index of this.#referenceLimits.keys()) {\n if (index >= length) {\n this.#referenceLimits.delete(index);\n }\n }\n\n for (const entry of kept) {\n this.addSettled(entry);\n }\n\n this.#renumber = true;\n }\n\n /**\n * Numbers footnote references in settled blocks from `from` on, continuing\n * the numbering before them, and returns the blocks whose numbers changed.\n */\n private renumber(from: number): number[] {\n if (from === 0) {\n this.#numbering = new FootnoteNumbering();\n this.#occurrences = new WeakMap();\n }\n\n const changed: number[] = [];\n\n for (let index = from; index < this.#settled.length; index++) {\n const entry = this.#settled[index];\n\n const occurrences = numberReferences(\n entry.materialized,\n this.#numbering,\n this.#occurrences,\n (identifier) => this.isFootnoteDefined(identifier),\n );\n\n if (!sameOccurrences(entry.occurrences, occurrences)) {\n changed.push(index);\n this.#settled[index] = { ...entry, occurrences };\n }\n }\n\n return changed;\n }\n\n private renderTail(\n parts: readonly TailPart[],\n previousTail: readonly RenderedEntry[],\n retired: ReadonlyMap<string, BlockId> | undefined,\n definitions: Definitions,\n changedLinks: ReadonlySet<string>,\n ): void {\n this.#tailNumbering = this.#numbering.fork();\n this.#tailOccurrences = new WeakMap();\n\n this.#tail = parts.map((part) => {\n const occurrences = numberReferences(\n part.materialized,\n this.#tailNumbering,\n this.#tailOccurrences,\n (identifier) => this.isFootnoteDefined(identifier),\n );\n\n const reusable = previousTail.find(\n (entry) =>\n entry.syntax === part.syntax &&\n entry.pending === undefined &&\n part.pending === undefined &&\n sameOccurrences(entry.occurrences, occurrences) &&\n !dependsOn(entry, changedLinks),\n );\n\n if (reusable !== undefined) {\n return reusable;\n }\n\n return this.render(\n {\n ...part,\n id: this.blockId(part.origin, previousTail, retired),\n pendingNodes: 0,\n occurrences,\n block: undefined,\n },\n definitions,\n this.#tailOccurrences,\n false,\n );\n });\n\n // The last block ends where input stopped, so a bare marker there can still become other syntax.\n const last = this.#tail.at(-1);\n\n if (last !== undefined) {\n const nodes = trimOpenTail(last.block.nodes);\n\n if (nodes !== last.block.nodes) {\n this.#tail[this.#tail.length - 1] = {\n ...last,\n block: Object.freeze({ ...last.block, nodes: Object.freeze(nodes) }),\n };\n }\n }\n }\n\n /** Lowers one block in the stream's scope. */\n private render(\n entry: BlockEntry,\n definitions: Definitions,\n occurrences: WeakMap<FootnoteReferenceNode, FootnoteOccurrence>,\n settled: boolean,\n ): RenderedEntry {\n const { materialized, pending } = entry;\n\n if (materialized.kind !== \"ok\") {\n const invalid = materialized.kind === \"invalid\";\n\n return {\n ...entry,\n block: Object.freeze({\n id: entry.id,\n origin: entry.origin,\n nodes: Object.freeze(invalid ? inertSource(this.#file, entry.origin) : []),\n status: invalid ? \"invalid\" : \"valid\",\n settled,\n diagnostics: invalid ? materialized.diagnostics : Object.freeze([]),\n dependencies: NO_DEPENDENCIES,\n }),\n };\n }\n\n let pendingNodes = 0;\n const references = new Set(materialized.references);\n\n const scope: LoweringScope = {\n definition: (identifier) => definitions.links.get(identifier),\n footnote: (identifier) => definitions.footnotes.get(identifier),\n occurrence: (node) => occurrences.get(node),\n options: { source: this.#file },\n provisional: true,\n cache: this.#loweringCache,\n };\n\n const nodes = lowerNodes(\n [materialized.node],\n pending === undefined\n ? scope\n : {\n ...scope,\n replace: (node) => {\n const open = lowerOpenLeaf(\n node,\n pending,\n {\n file: this.#file,\n definitions: definitions.links,\n references,\n syntax: this.#parser.syntax,\n limits: this.#limits,\n fence: this.#fence,\n paragraph: this.#paragraph,\n phrasing: this.#phrasing,\n lowering: this.#loweringCache,\n },\n (children, previous) => lowerNodes(children, scope, previous),\n );\n\n pendingNodes += open?.nodeCount ?? 0;\n\n return open?.nodes;\n },\n },\n );\n\n const contents = {\n ...materialized.contents,\n definitionReferences: [\n ...new Set([...materialized.contents.definitionReferences, ...references]),\n ],\n };\n\n return {\n ...entry,\n materialized: { ...materialized, contents, references: [...references] },\n pendingNodes,\n block: Object.freeze({\n id: entry.id,\n origin: entry.origin,\n nodes: Object.freeze(nodes),\n status: \"valid\",\n settled,\n diagnostics: materialized.diagnostics,\n dependencies: dependenciesOf(contents),\n }),\n };\n }\n\n private isFootnoteDefined(identifier: string): boolean {\n return (\n this.#definitions.footnotes.has(identifier) || this.#tailDefinitions.footnotes.has(identifier)\n );\n }\n\n private effectiveDefinitions(): Definitions {\n const tail = this.#tailDefinitions;\n\n if (tail.links.size === 0 && tail.footnotes.size === 0) {\n return this.#definitions;\n }\n\n const links = new Map(this.#definitions.links);\n const footnotes = new Map(this.#definitions.footnotes);\n addFirst(links, [...tail.links.values()]);\n addFirst(footnotes, [...tail.footnotes.values()]);\n\n return { links, footnotes };\n }\n\n /** The footnote section, rebuilt only when its numbering or definitions change. */\n private footnoteSection(definitions: Definitions): HtmlFootnoteSectionNode | undefined {\n const numbering = this.#tailNumbering;\n\n const key = [\n this.#definitionsVersion,\n ...numbering.order.flatMap((identifier) => [\n identifier,\n numbering.count(identifier),\n definitions.footnotes.get(identifier),\n ]),\n ];\n\n if (\n key.length === this.#footnotesKey.length &&\n key.every((value, index) => value === this.#footnotesKey[index])\n ) {\n return this.#footnotes;\n }\n\n this.#footnotesKey = key;\n this.#footnotes = lowerFootnoteSection(numbering, {\n definition: (identifier) => definitions.links.get(identifier),\n footnote: (identifier) => definitions.footnotes.get(identifier),\n occurrence: (node) => this.#occurrences.get(node) ?? this.#tailOccurrences.get(node),\n options: { source: this.#file },\n provisional: true,\n });\n\n return this.#footnotes;\n }\n\n /** The first limit the stream exceeds, if any. */\n private limitState(pending?: PendingBlockSyntax): LimitState | undefined {\n if (this.#file.length > this.#limits.maximumSourceLength) {\n return { limit: \"maximumSourceLength\", offset: this.#file.length };\n }\n\n if (this.#limited !== undefined) {\n return this.#limited;\n }\n\n const referenceLimit = this.#referenceLimits.values().next().value;\n\n if (referenceLimit !== undefined) {\n return referenceLimit;\n }\n\n let nodes = 1 + this.#nodes;\n\n for (const entry of this.#tail) {\n if (entry.materialized.kind === \"limitExceeded\") {\n return { limit: entry.materialized.limit, offset: entry.origin.end };\n }\n\n nodes +=\n (entry.materialized.kind === \"ok\" ? entry.materialized.nodeCount : 0) + entry.pendingNodes;\n }\n\n if (nodes > this.#limits.maximumNodes) {\n return { limit: \"maximumNodes\", offset: this.#tail.at(-1)?.origin.end ?? 0 };\n }\n\n const owner =\n pending === undefined ? undefined : this.#tail.find((entry) => entry.pending !== undefined);\n\n if (\n owner !== undefined &&\n owner.syntax.range.end - owner.syntax.range.start > this.#maximumPendingBlockLength\n ) {\n return { limit: \"maximumPendingBlockLength\", offset: owner.syntax.range.end };\n }\n\n return undefined;\n }\n\n /** Keeps the last preview within limits, with its block identities. */\n private limitChange(state: LimitState): MdxStreamChange {\n this.#limitedPreview = true;\n\n const snapshot: MdxStreamSnapshot = Object.freeze({\n kind: \"preview\",\n file: this.#file,\n blocks: this.#lastValid?.blocks ?? Object.freeze([]),\n footnotes: this.#lastValid?.footnotes,\n diagnostics: Object.freeze([limitDiagnostic(this.#file, state)]),\n limit: state.limit,\n });\n\n return Object.freeze({\n snapshot,\n start: snapshot.blocks.length,\n refreshed: Object.freeze([]),\n footnotesChanged: false,\n });\n }\n\n private limitError(state: LimitState): LimitError {\n const maximum =\n state.limit === \"maximumPendingBlockLength\"\n ? this.#maximumPendingBlockLength\n : this.#limits[state.limit];\n\n return LimitError.exceeded(\n this.#file,\n state.limit,\n maximum,\n { start: state.offset, end: state.offset },\n state.limit === \"maximumSourceLength\" ? this.#file.length : undefined,\n );\n }\n\n /** A block keeps its identity across appends, and across edits that do not touch it. */\n private blockId(\n origin: SourceRange,\n previousTail: readonly RenderedEntry[],\n retired: ReadonlyMap<string, BlockId> | undefined,\n ): BlockId {\n if (retired !== undefined) {\n return retired.get(rangeKey(origin)) ?? this.newId();\n }\n\n return previousTail.find((entry) => entry.origin.start === origin.start)?.id ?? this.newId();\n }\n\n /** Identities of blocks an edit does not touch, keyed by their range after the edit. */\n private retiredIds(edit: MdxEdit): ReadonlyMap<string, BlockId> {\n const retired = new Map<string, BlockId>();\n const delta = edit.text.length - (edit.end - edit.start);\n\n for (const entry of [...this.#settled, ...this.#tail]) {\n if (!rangesIntersect(entry.origin, edit)) {\n retired.set(\n rangeKey(entry.origin.start >= edit.end ? shiftRange(entry.origin, delta) : entry.origin),\n entry.id,\n );\n }\n }\n\n return retired;\n }\n\n private newId(): BlockId {\n const value = `block-${this.#nextId++}`;\n\n if (!isBlockId(value)) {\n throw new Error(\"Internal block identity invariant failed\");\n }\n\n return value;\n }\n}\n\ninterface CompletedPart {\n readonly id: BlockId;\n readonly origin: SourceRange;\n readonly node: FlowContent;\n}\n\n/** Link identifiers whose rendering changed, and whether the set of footnotes changed. */\ninterface DefinitionChanges {\n readonly links: ReadonlySet<string>;\n readonly footnotes: boolean;\n}\n\ninterface TailPart {\n readonly syntax: BlockSyntax;\n readonly origin: SourceRange;\n readonly materialized: Materialized;\n readonly pending: PendingBlockSyntax | undefined;\n}\n\n/** Stands in for a settled block until it renders later in the same update. */\nconst unrendered: StreamBlock = Object.freeze({\n id: placeholderId(),\n origin: Object.freeze({ start: 0, end: 0 }),\n nodes: Object.freeze([]),\n status: \"valid\",\n settled: true,\n diagnostics: Object.freeze([]),\n dependencies: NO_DEPENDENCIES,\n});\n\n/** Every settled entry renders before an update publishes its snapshot. */\nfunction renderedBlock(entry: BlockEntry): StreamBlock {\n if (entry.block === undefined) {\n throw new Error(\"A settled stream block was not rendered\");\n }\n\n return entry.block;\n}\n\nfunction materializedNodes(part: TailPart): FlowContent[] {\n return part.materialized.kind === \"ok\" ? [part.materialized.node] : [];\n}\n\nconst emptyContents: BlockContents = Object.freeze({\n definitionReferences: Object.freeze([]),\n footnoteReferences: Object.freeze([]),\n definitions: Object.freeze([]),\n footnotes: Object.freeze([]),\n});\n\n/** Contents by node identity. Trees are immutable, so a reused subtree is walked once. */\nconst contentsCache = new WeakMap<MdxNode, BlockContents>();\n\n/** The references a node makes and the definitions it contains, in document order. */\nfunction blockContents(node: MdxNode): BlockContents {\n const hit = contentsCache.get(node);\n\n if (hit !== undefined) {\n return hit;\n }\n\n if (node.kind === \"list\") {\n return listContents(node);\n }\n\n const parts = mdxChildren(node).map(blockContents);\n\n switch (node.kind) {\n case \"linkReference\":\n case \"imageReference\":\n parts.unshift({ ...emptyContents, definitionReferences: [node.identifier] });\n break;\n case \"footnoteReference\":\n parts.unshift({ ...emptyContents, footnoteReferences: [node] });\n break;\n case \"definition\":\n parts.unshift({ ...emptyContents, definitions: [node] });\n break;\n case \"footnoteDefinition\":\n parts.unshift({ ...emptyContents, footnotes: [node] });\n break;\n default:\n break;\n }\n\n const filled = parts.filter((part) => part !== emptyContents);\n\n const contents =\n filled.length === 0\n ? emptyContents\n : filled.length === 1\n ? filled[0]\n : {\n definitionReferences: [...new Set(filled.flatMap((part) => part.definitionReferences))],\n footnoteReferences: filled.flatMap((part) => part.footnoteReferences),\n definitions: filled.flatMap((part) => part.definitions),\n footnotes: filled.flatMap((part) => part.footnotes),\n };\n\n contentsCache.set(node, contents);\n\n return contents;\n}\n\n/** A list's contents after each of its last items, by item. */\nconst listContentsCache = new WeakMap<\n ListItemNode,\n Readonly<{ index: number; contents: BlockContents }>\n>();\n\n/** A growing list combines the contents of its unchanged leading items once. */\nfunction listContents(node: ListNode): BlockContents {\n const items = node.children;\n let start = 0;\n let contents = emptyContents;\n\n for (let index = items.length - 1; index >= Math.max(0, items.length - 8); index--) {\n const prefix = listContentsCache.get(items[index]);\n\n if (prefix?.index === index) {\n start = index + 1;\n contents = prefix.contents;\n break;\n }\n }\n\n for (let index = start; index < items.length; index++) {\n contents = mergeContents(contents, blockContents(items[index]));\n\n if (index >= items.length - 8) {\n listContentsCache.set(items[index], { index, contents });\n }\n }\n\n contentsCache.set(node, contents);\n\n return contents;\n}\n\nfunction mergeContents(left: BlockContents, right: BlockContents): BlockContents {\n if (right === emptyContents) {\n return left;\n }\n\n if (left === emptyContents) {\n return right;\n }\n\n return {\n definitionReferences: [\n ...new Set([...left.definitionReferences, ...right.definitionReferences]),\n ],\n footnoteReferences: [...left.footnoteReferences, ...right.footnoteReferences],\n definitions: [...left.definitions, ...right.definitions],\n footnotes: [...left.footnotes, ...right.footnotes],\n };\n}\n\nfunction collectDefinitions(nodes: readonly MdxNode[]): Definitions {\n const links = new Map<string, DefinitionNode>();\n const footnotes = new Map<string, FootnoteDefinitionNode>();\n\n for (const node of nodes) {\n const contents = blockContents(node);\n addFirst(links, contents.definitions);\n addFirst(footnotes, contents.footnotes);\n }\n\n return { links, footnotes };\n}\n\n/** Replaces re-materialized definitions only when their old node was the winning definition. */\nfunction replaceDefinitions<TNode extends DefinitionNode | FootnoteDefinitionNode>(\n current: ReadonlyMap<string, TNode>,\n previous: readonly TNode[],\n next: readonly TNode[],\n): ReadonlyMap<string, TNode> {\n if (previous.length === 0) {\n return current;\n }\n\n const old = new Set(previous);\n const updated = new Map(current);\n\n for (const node of next) {\n const winner = updated.get(node.identifier);\n\n if (winner !== undefined && old.has(winner)) {\n updated.set(node.identifier, node);\n }\n }\n\n return updated;\n}\n\nfunction addFirst<TNode extends DefinitionNode | FootnoteDefinitionNode>(\n target: Map<string, TNode>,\n nodes: readonly TNode[],\n): void {\n for (const node of nodes) {\n if (!target.has(node.identifier)) {\n target.set(node.identifier, node);\n }\n }\n}\n\nfunction changedDefinitions(before: Definitions, after: Definitions): DefinitionChanges {\n const links = new Set<string>();\n\n if (before.links !== after.links) {\n for (const identifier of new Set([...before.links.keys(), ...after.links.keys()])) {\n const previous = before.links.get(identifier);\n const next = after.links.get(identifier);\n\n if (previous?.url !== next?.url || previous?.title !== next?.title) {\n links.add(identifier);\n }\n }\n }\n\n let footnotes = before.footnotes.size !== after.footnotes.size;\n\n for (const identifier of after.footnotes.keys()) {\n footnotes ||= !before.footnotes.has(identifier);\n }\n\n return { links, footnotes };\n}\n\nfunction numberReferences(\n materialized: Materialized,\n numbering: FootnoteNumbering,\n occurrences: WeakMap<FootnoteReferenceNode, FootnoteOccurrence>,\n defined: (identifier: string) => boolean,\n): Occurrences {\n if (materialized.kind !== \"ok\" || materialized.contents.footnoteReferences.length === 0) {\n return NO_OCCURRENCES;\n }\n\n return materialized.contents.footnoteReferences.map((node): FootnoteOccurrence | undefined => {\n if (!defined(node.identifier)) {\n return;\n }\n\n const occurrence = numbering.reference(node.identifier);\n occurrences.set(node, occurrence);\n\n return occurrence;\n });\n}\n\nfunction sameOccurrences(left: Occurrences, right: Occurrences): boolean {\n return (\n left === right ||\n (left.length === right.length &&\n left.every(\n (occurrence, index) =>\n occurrence?.ordinal === right[index]?.ordinal &&\n occurrence?.occurrence === right[index]?.occurrence,\n ))\n );\n}\n\nfunction dependsOn(entry: BlockEntry, identifiers: ReadonlySet<string>): boolean {\n return (\n identifiers.size > 0 &&\n entry.materialized.kind === \"ok\" &&\n entry.materialized.contents.definitionReferences.some((identifier) =>\n identifiers.has(identifier),\n )\n );\n}\n\nfunction dependenciesOf(contents: BlockContents): StreamDependencies {\n if (contents.definitionReferences.length === 0 && contents.footnoteReferences.length === 0) {\n return NO_DEPENDENCIES;\n }\n\n return Object.freeze({\n definitions: Object.freeze([...contents.definitionReferences]),\n footnotes: Object.freeze([\n ...new Set(contents.footnoteReferences.map((node) => node.identifier)),\n ]),\n });\n}\n\n/** Turns references without definitions into their authored text, like batch parsing. */\nfunction resolveReferences(\n node: FlowContent,\n definitions: Definitions,\n file: SourceFile,\n): FlowContent {\n const contents = blockContents(node);\n\n const unresolved =\n contents.definitionReferences.some((identifier) => !definitions.links.has(identifier)) ||\n contents.footnoteReferences.some(\n (reference) => !definitions.footnotes.has(reference.identifier),\n );\n\n if (!unresolved) {\n return node;\n }\n\n const authored = (reference: MdxNode): TextNode | undefined =>\n reference.origin === undefined\n ? undefined\n : { kind: \"text\", value: file.slice(reference.origin), origin: reference.origin };\n\n const [result] = rewriteMdx(\n { kind: \"document\", children: [node] },\n {\n linkReference: ({ node: reference }) =>\n definitions.links.has(reference.identifier) ? undefined : authored(reference),\n imageReference: ({ node: reference }) =>\n definitions.links.has(reference.identifier) ? undefined : authored(reference),\n footnoteReference: ({ node: reference }) =>\n definitions.footnotes.has(reference.identifier) ? undefined : authored(reference),\n },\n ).children;\n\n if (result === undefined) {\n throw new Error(\"Reference resolution removed a stream block\");\n }\n\n return result;\n}\n\n/** Invalid authored source renders as inert text. */\nfunction inertSource(file: SourceFile, origin: SourceRange): HtmlNode[] {\n return [\n {\n kind: \"element\",\n tagName: \"p\",\n attributes: {},\n children: [{ kind: \"text\", value: file.semanticSlice(origin).trimEnd(), origin }],\n origin,\n },\n ];\n}\n\nfunction limitDiagnostic(file: SourceFile, state: LimitState): Diagnostic {\n return createDiagnostic({\n code: \"mdx-limit-exceeded\",\n severity: \"error\",\n message: `${state.limit} was exceeded at source offset ${state.offset}`,\n span: { file, start: state.offset, end: state.offset },\n });\n}\n\n/** A block starts at the start of its first physical line. */\nfunction blockOrigin(text: SourceText, syntax: BlockSyntax): SourceRange {\n let start = syntax.range.start;\n\n while (start > 0 && text.char(start - 1) !== \"\\n\" && text.char(start - 1) !== \"\\r\") {\n start--;\n }\n\n return { start, end: syntax.range.end };\n}\n\nfunction containsRange(outer: SourceRange, inner: SourceRange): boolean {\n return outer.start <= inner.start && inner.end <= outer.end;\n}\n\nfunction rangeKey(range: SourceRange): string {\n return `${range.start}:${range.end}`;\n}\n\n/** The placeholder never reaches a snapshot, so its identity never meets a real block. */\nfunction placeholderId(): BlockId {\n const value = \"block-0\";\n\n if (!isBlockId(value)) {\n throw new Error(\"Internal block identity invariant failed\");\n }\n\n return value;\n}\n\nfunction isBlockId(value: string): value is BlockId {\n return /^block-\\d+$/u.test(value);\n}\n"],"mappings":";;;;;;;;;;;;;AA6GA,MAAM,oBAAiC;CAAE,uBAAO,IAAI,IAAI;CAAG,2BAAW,IAAI,IAAI;AAAE;AAEhF,MAAM,iBAA8B,OAAO,OAAO,CAAC,CAAC;AAEpD,MAAM,kBAAsC,OAAO,OAAO;CACxD,aAAa,OAAO,OAAO,CAAC,CAAC;CAC7B,WAAW,OAAO,OAAO,CAAC,CAAC;AAC7B,CAAC;;;;;;;AAQD,IAAa,gBAAb,MAA2B;CACzB;CACA;CACA;;CAEA;CACA;;CAGA,SAAuB,CAAC;CACxB,WAAyB,CAAC;;CAE1B,UAAyB,CAAC;CAC1B,QAAyB,CAAC;CAG1B,eAA4B;CAC5B,8BAAc,IAAI,IAAyB;CAC3C,SAAS;CACT,eAA6B,CAAC;CAC9B;CACA,mCAA4B,IAAI,IAAwB;CACxD,aAAa,IAAI,kBAAkB;CACnC,+BAAe,IAAI,QAAmD;CAGtE,mBAAgC;CAChC,iBAAiB,IAAI,kBAAkB;CACvC,mCAAmB,IAAI,QAAmD;CAE1E,sBAAsB;CACtB;CACA,gBAAoC,CAAC;CACrC,oBAAoB,uBAAuB;CAC3C,iBAAiB,wBAAwB;CACzC,SAAkB,IAAI,UAAU;CAChC,aAAsB,IAAI,cAAc;CACxC,4BAAoC,IAAI,QAAQ;CAChD,UAAU;CACV;CACA;;CAEA,YAAY;CACZ,kBAAkB;CAElB,YAAmB,SAA+B;EAChD,KAAK,UAAU,QAAQ;EACvB,KAAK,6BAA6B,QAAQ;EAC1C,KAAK,UAAU,IAAI,aAAa;GAAE,MAAM,QAAQ;GAAM,MAAM,QAAQ;EAAO,CAAC;EAC5E,KAAK,QAAQ,KAAK,QAAQ;EAE1B,KAAK,UAAU,IAAI,cAAc;GAC/B,QAAQ,KAAK;GACb,QAAQ,QAAQ;GAChB,YAAY,QAAQ,UAAU,KAAK,OAAO,KAAK;IAAE;IAAQ;GAAM,CAAC;EAClE,CAAC;EAED,KAAK,WAAW,KAAK,OAAO,CAAC;CAC/B;;CAGA,IAAW,UAA2B;EACpC,OAAO,KAAK;CACd;CAEA,OAAc,MAA+B;EAC3C,MAAM,QAAQ,KAAK,SAAS;EAC5B,KAAK,QAAQ,KAAK,QAAQ,OAAO,IAAI;EAErC,KAAK,QAAQ,OAAO,MAAM,WAAW,KAAK,KAAK,CAAC;EAChD,KAAK,WAAW,KAAK,OAAO,KAAK;EAEjC,OAAO,KAAK;CACd;CAEA,KAAY,MAAgC;EAC1C,MAAM,UAAU,KAAK,WAAW,IAAI;EACpC,KAAK,QAAQ,KAAK,QAAQ,QAAQ,KAAK,OAAO,KAAK,KAAK,KAAK,IAAI;EACjE,KAAK,QAAQ,KAAK,IAAI;EACtB,KAAK,WAAW,KAAK,OAAO,KAAK,SAAS,QAAQ,OAAO;EAEzD,OAAO,KAAK;CACd;;;;;CAMA,WAAuC;EACrC,MAAM,UAAU,KAAK,WAAW;EAEhC,IAAI,YAAY,KAAA,KAAa,QAAQ,UAAU,6BAC7C,MAAM,KAAK,WAAW,OAAO;EAI/B,MAAM,OAAO,KAAK,QAAQ,UAAU,CAAC,CAAC;EACtC,MAAM,UAAU,KAAK;EAErB,MAAM,cAA4B,CAAC;EACnC,MAAM,SAAuB,CAAC;EAC9B,MAAM,QAAyB,CAAC;EAChC,IAAI,QAAQ,IAAI,KAAK;EAErB,KAAK,MAAM,SAAS,SAClB,IAAI,MAAM,aAAa,SAAS,WAC9B,OAAO,KAAK,GAAG,MAAM,aAAa,WAAW;OACxC,IAAI,MAAM,aAAa,SAAS,MAAM;GAC3C,YAAY,KAAK,GAAG,MAAM,aAAa,WAAW;GAClD,MAAM,KAAK;IAAE,IAAI,MAAM;IAAI,QAAQ,MAAM;IAAQ,MAAM,MAAM,aAAa;GAAK,CAAC;EAClF;EAGF,MAAM,UAAU,IAAI,IAAI,KAAK,MAAM,KAAK,UAAU,CAAC,MAAM,OAAO,OAAO,MAAM,EAAE,CAAC,CAAC;EAEjF,KAAK,MAAM,UAAU,MAAM;GACzB,MAAM,SAAS,YAAY,WAAW,KAAK,KAAK,GAAG,MAAM;GAEzD,MAAM,eAAe,oBACnB,KAAK,OACL,CAAC,MAAM,GACP,KAAK,QAAQ,QACb;IAAE,GAAG,KAAK;IAAS,cAAc,KAAK,IAAI,GAAG,KAAK,QAAQ,eAAe,QAAQ,CAAC;GAAE,GACpF;IACE,gBAAgB;IAChB,OAAO,KAAK;IACZ,kBAAkB,KAAK,qBAAqB,CAAC,CAAC;GAChD,CACF;GAEA,IAAI,aAAa,SAAS,iBACxB,MAAM,KAAK,WAAW;IAAE,OAAO,aAAa;IAAO,QAAQ,OAAO;GAAI,CAAC;GAGzE,IAAI,aAAa,SAAS,WAAW;IACnC,OAAO,KAAK,GAAG,aAAa,WAAW;IACvC;GACF;GAEA,YAAY,KAAK,GAAG,aAAa,WAAW;GAE5C,KAAK,MAAM,SAAS,aAAa,QAAQ;IACvC,SAAS,MAAM;IACf,MAAM,KAAK;KAAE,IAAI,QAAQ,IAAI,OAAO,KAAK,KAAK,KAAK,MAAM;KAAG;KAAQ,MAAM,MAAM;IAAK,CAAC;GACxF;EACF;EAEA,MAAM,CAAC,YAAY,GAAG,eAAe;EAErC,IAAI,eAAe,KAAA,GACjB,MAAM,WAAW,cAAc,KAAK,OAAO,CAAC,YAAY,GAAG,WAAW,CAAC;EAGzE,IAAI,QAAQ,KAAK,QAAQ,cACvB,MAAM,KAAK,WAAW;GAAE,OAAO;GAAgB,QAAQ,KAAK,MAAM;EAAO,CAAC;EAG5E,MAAM,cAAc,mBAAmB,MAAM,KAAK,SAAS,KAAK,IAAI,CAAC;EAErE,MAAM,WAAyB;GAC7B,MAAM;GACN,UAAU,MAAM,KAAK,SAAS,kBAAkB,KAAK,MAAM,aAAa,KAAK,KAAK,CAAC;GACnF,QAAQ;IAAE,OAAO;IAAG,KAAK,KAAK,MAAM;GAAO;EAC7C;EAEA,OAAO,OAAO,OAAO;GACnB,MAAM;GACN,MAAM,KAAK;GACX;GACA,QAAQ,OAAO,OACb,MAAM,KAAK,SAAyB,OAAO,OAAO;IAAE,IAAI,KAAK;IAAI,QAAQ,KAAK;GAAO,CAAC,CAAC,CACzF;GACA,aAAa,OAAO,OAAO,WAAW;EACxC,CAAC;CACH;;;;;CAMA,OAAe,iBAAyB,SAAyD;EAC/F,IAAI,KAAK,MAAM,SAAS,KAAK,QAAQ,qBACnC,OAAO,KAAK,YAAY;GAAE,OAAO;GAAuB,QAAQ,KAAK,MAAM;EAAO,CAAC;EAGrF,MAAM,SAAS,KAAK,qBAAqB;EACzC,MAAM,eAAe,KAAK;EAC1B,MAAM,QAAQ,KAAK,IAAI,iBAAiB,KAAK,mBAAmB,CAAC;EACjE,MAAM,aAAa,KAAK,SAAS;EACjC,MAAM,UAAU,KAAK,aAAa,cAAc,OAAO;EAEvD,MAAM,QAAQ,KAAK,QAAQ,UAAU;EACrC,MAAM,QAAQ,MAAM,OAAO,KAAK,WAAW,KAAK,gBAAgB,QAAQ,MAAM,OAAO,CAAC;EACtF,KAAK,mBAAmB,mBAAmB,MAAM,QAAQ,iBAAiB,CAAC;EAC3E,MAAM,QAAQ,KAAK,qBAAqB;EACxC,MAAM,UAAU,mBAAmB,QAAQ,KAAK;EAChD,MAAM,YAAY,KAAK,eAAe,SAAS,OAAO,YAAY,SAAS,KAAK;EAChF,MAAM,qBAAqB,KAAK,qBAAqB;EAErD,MAAM,gBAAgB,MAAM,KAAK,SAAS;GACxC,IACE,KAAK,aAAa,SAAS,QAC3B,CAAC,KAAK,aAAa,WAAW,MAAM,OAAO,QAAQ,MAAM,IAAI,EAAE,CAAC,GAEhE,OAAO;GAGT,OAAO;IACL,GAAG;IACH,cAAc,KAAK,YACjB,KAAK,QACL,KAAK,QAAQ,eAAe,IAAI,KAAK,QACrC,KAAK,YAAY,KAAA,KAAa,cAAc,KAAK,OAAO,OAAO,KAAK,QAAQ,KAAK,IAC7E,KAAK,QAAQ,QACb,KAAA,GACJ,mBAAmB,KACrB;GACF;EACF,CAAC;EAED,KAAK,mBAAmB,mBAAmB,cAAc,QAAQ,iBAAiB,CAAC;EACnF,MAAM,sBAAsB,KAAK,qBAAqB;EACtD,KAAK,WAAW,eAAe,cAAc,SAAS,qBAAqB,QAAQ,KAAK;EAExF,MAAM,YAAY,KAAK,gBAAgB,mBAAmB;EAC1D,MAAM,UAAU,KAAK,WAAW,MAAM,OAAO;EAE7C,IAAI,YAAY,KAAA,GACd,OAAO,KAAK,YAAY,OAAO;EAGjC,MAAM,WAA8B,OAAO,OAAO;GAChD,MAAM;GACN,MAAM,KAAK;GACX,QAAQ,OAAO,OAAO,CAAC,GAAG,KAAK,SAAS,GAAG,KAAK,MAAM,KAAK,UAAU,MAAM,KAAK,CAAC,CAAC;GAClF;GACA,aAAa,OAAO,OAAO,CACzB,GAAG,KAAK,cACR,GAAG,KAAK,MAAM,SAAS,UAAU,MAAM,MAAM,WAAW,CAC1D,CAAC;GACD,OAAO,KAAA;EACT,CAAC;EAGD,MAAM,aAAa,CAAC,KAAK;EACzB,KAAK,kBAAkB;EACvB,MAAM,WAAW,KAAK;EACtB,KAAK,aAAa;EAElB,OAAO,OAAO,OAAO;GACnB;GACA,OAAO,aAAa,KAAA,KAAa,aAAa,QAAQ;GACtD,WAAW,OAAO,OAAO,aAAa,YAAY,CAAC,CAAC;GACpD,kBAAkB,cAAc,UAAU;EAC5C,CAAC;CACH;;;;;CAMA,qBAAqC;EACnC,MAAM,OAAO,KAAK,IAChB,KAAK,SAAS,QACd,KAAK,QAAQ,cACb,KAAK,OAAO,EAAE,EAAE,SAAS,QAC3B;EAEA,IAAI,OAAO,KAAK,SAAS,QACvB,KAAK,SAAS,IAAI;EAGpB,OAAO,KAAK,SAAS;CACvB;;CAGA,aACE,cACA,SACqB;EACrB,MAAM,0BAAU,IAAI,IAAY;EAEhC,KAAK,MAAM,cAAc,KAAK,QAAQ;GACpC,IAAI,WAAW,UAAU,KAAK,SAAS,QACrC;GAGF,MAAM,QAAQ,KAAK,OAAO,WAAW,QAAQ,cAAc,OAAO;GAElE,IAAI,MAAM,UAAU,KAAA,GAClB,QAAQ,IAAI,KAAK,SAAS,MAAM;GAGlC,KAAK,WAAW,KAAK;EACvB;EAEA,KAAK,SAAS,CAAC;EAEf,OAAO;CACT;;;;;CAMA,eACE,SACA,aACA,YACA,SACA,OACe;EACf,MAAM,wBAAQ,IAAI,IAAY;EAE9B,IAAI,QAAQ,MAAM,OAAO,GAAG;GAE1B,KAAK,iBAAiB,wBAAwB;GAC9C,KAAK,oBAAoB,uBAAuB;GAChD,KAAK;GAEL,KAAK,MAAM,cAAc,QAAQ,OAC/B,KAAK,MAAM,SAAS,KAAK,YAAY,IAAI,UAAU,KAAK,CAAC,GACvD,MAAM,IAAI,KAAK;EAGrB;EAEA,KAAK,IAAI,QAAQ,YAAY,QAAQ,KAAK,SAAS,QAAQ,SACzD,IAAI,CAAC,QAAQ,IAAI,KAAK,GACpB,MAAM,IAAI,KAAK;EAInB,IAAI,0BAA0B;EAE9B,KAAK,MAAM,SAAS,KAAK,iBAAiB,KAAK,GAC7C,MAAM,IAAI,KAAK;EAGjB,KAAK,MAAM,SAAS,OAAO;GACzB,MAAM,QAAQ,KAAK,SAAS;GAE5B,IACE,MAAM,aAAa,SAAS,SAC3B,MAAM,aAAa,WAAW,MAAM,OAAO,QAAQ,MAAM,IAAI,EAAE,CAAC,KAC/D,KAAK,iBAAiB,IAAI,KAAK,IACjC;IACA,MAAM,MAAM,MAAM;IAClB,MAAM,WAAW,IAAI;IAErB,MAAM,eAAe,KAAK,YACxB,MAAM,QACN,KAAK,QAAQ,eAAe,IAAI,KAAK,SAAS,UAC9C,KAAA,GACA,YAAY,KACd;IAEA,IAAI,aAAa,SAAS,iBAAiB;KACzC,KAAK,iBAAiB,IAAI,OAAO;MAAE,OAAO,aAAa;MAAO,QAAQ,MAAM,OAAO;KAAI,CAAC;KACxF;IACF;IAEA,KAAK,iBAAiB,OAAO,KAAK;IAElC,IAAI,aAAa,SAAS,MACxB,KAAK,eAAe;KAClB,OAAO,mBACL,KAAK,aAAa,OAClB,IAAI,SAAS,aACb,aAAa,SAAS,WACxB;KACA,WAAW,mBACT,KAAK,aAAa,WAClB,IAAI,SAAS,WACb,aAAa,SAAS,SACxB;IACF;IAGF,KAAK,WAAW,aAAa,SAAS,OAAO,aAAa,YAAY,KAAK;IAE3E,KAAK,MAAM,cAAc,IAAI,SAAS,sBACpC,KAAK,YAAY,IAAI,UAAU,CAAC,EAAE,OAAO,KAAK;IAGhD,IAAI,aAAa,SAAS,MACxB,KAAK,MAAM,cAAc,aAAa,SAAS,sBAAsB;KACnE,MAAM,aAAa,KAAK,YAAY,IAAI,UAAU,qBAAK,IAAI,IAAY;KACvE,WAAW,IAAI,KAAK;KACpB,KAAK,YAAY,IAAI,YAAY,UAAU;IAC7C;IAGF,KAAK,SAAS,SAAS;KAAE,GAAG;KAAO;IAAa;IAChD,4BAA4B,IAAI,SAAS,mBAAmB,SAAS;GACvE;EACF;EAEA,cAAc,KAAK,qBAAqB;EACxC,MAAM,cAAc,QAAQ,aAAa,KAAK,aAAa;EAC3D,KAAK,YAAY;EAEjB,KAAK,MAAM,SAAS,KAAK,SAAS,cAAc,IAAI,UAAU,GAC5D,MAAM,IAAI,KAAK;EAGjB,MAAM,YAA2B,CAAC;EAElC,KAAK,MAAM,SAAS,OAAO;GACzB,KAAK,SAAS,SAAS,KAAK,OAC1B,KAAK,SAAS,QACd,aACA,KAAK,cACL,IACF;GACA,KAAK,QAAQ,SAAS,cAAc,KAAK,SAAS,MAAM;GAExD,IAAI,QAAQ,OACV,UAAU,KAAK,cAAc,KAAK,SAAS,MAAM,CAAC;EAEtD;EAGA,KAAK,MAAM,SAAS,SAAS;GAC3B,MAAM,QAAQ,KAAK,SAAS;GAC5B,MAAM,QAAQ,cAAc,KAAK;GAEjC,IAAI,CAAC,MAAM,IAAI,KAAK,KAAK,CAAC,MAAM,SAAS;IACvC,KAAK,SAAS,SAAS;KAAE,GAAG;KAAO,OAAO,OAAO,OAAO;MAAE,GAAG;MAAO,SAAS;KAAK,CAAC;IAAE;IACrF,KAAK,QAAQ,SAAS,cAAc,KAAK,SAAS,MAAM;GAC1D;EACF;EAEA,OAAO;CACT;;CAGA,OACE,QACA,cACA,SACY;EACZ,MAAM,UAAU,aAAa,MAC1B,UAAU,MAAM,WAAW,UAAU,MAAM,YAAY,KAAA,CAC1D;EAEA,IAAI,YAAY,KAAA,GACd,OAAO;EAGT,MAAM,SAAS,YAAY,WAAW,KAAK,KAAK,GAAG,MAAM;EAEzD,OAAO;GACL;GACA,IAAI,KAAK,QAAQ,QAAQ,cAAc,OAAO;GAC9C;GACA,cAAc,KAAK,YAAY,QAAQ,KAAK,QAAQ,eAAe,IAAI,KAAK,MAAM;GAClF,SAAS,KAAA;GACT,cAAc;GACd,aAAa;GACb,OAAO,KAAA;EACT;CACF;CAEA,gBAAwB,QAAqB,SAAmD;EAC9F,MAAM,OACJ,YAAY,KAAA,KAAa,cAAc,OAAO,OAAO,QAAQ,KAAK,IAAI,UAAU,KAAA;EAElF,OAAO;GACL;GACA,QAAQ,YAAY,WAAW,KAAK,KAAK,GAAG,MAAM;GAClD,cAAc,KAAK,YACjB,QACA,KAAK,QAAQ,eAAe,IAAI,KAAK,QACrC,MAAM,KACR;GACA,SAAS;EACX;CACF;CAEA,YACE,QACA,QACA,MACA,cAAgC,KAAK,qBAAqB,CAAC,CAAC,OAC9C;EACd,IAAI,SAAS,GACX,OAAO;GAAE,MAAM;GAAiB,OAAO;EAAe;EAGxD,MAAM,SAAS,oBACb,KAAK,OACL,CAAC,MAAM,GACP,KAAK,QAAQ,QAEb;GAAE,GAAG,KAAK;GAAS,cAAc,SAAS;EAAE,GAC5C;GACE,gBAAgB;GAChB,iBAAiB;GACjB,OAAO,KAAK;GACZ;GACA,kBAAkB;EACpB,CACF;EAEA,IAAI,OAAO,SAAS,iBAClB,OAAO;GAAE,MAAM;GAAiB,OAAO,OAAO;EAAM;EAGtD,IAAI,OAAO,SAAS,WAClB,OAAO;GAAE,MAAM;GAAW,aAAa,OAAO;EAAY;EAG5D,MAAM,CAAC,SAAS,OAAO;EAEvB,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,MAAM,wCAAwC;EAG1D,MAAM,WAAW,cAAc,MAAM,IAAI;EAEzC,OAAO;GACL,MAAM;GACN,MAAM,MAAM;GACZ,WAAW,MAAM;GACjB,YAAY,MAAM;GAClB,aAAa,OAAO;GACpB,UAAU;IACR,GAAG;IACH,sBAAsB,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAG,SAAS,sBAAsB,GAAG,MAAM,UAAU,CAAC,CAAC;GAC5F;EACF;CACF;;CAGA,WAAmB,OAAyB;EAC1C,MAAM,QAAQ,KAAK,SAAS;EAC5B,KAAK,SAAS,KAAK,KAAK;EAExB,KAAK,QAAQ,KAAK,MAAM,SAAS,UAAU;EAC3C,MAAM,EAAE,iBAAiB;EAEzB,IAAI,aAAa,SAAS,iBAAiB;GACzC,KAAK,aAAa;IAAE,OAAO,aAAa;IAAO,QAAQ,MAAM,OAAO;GAAI;GAExE;EACF;EAEA,KAAK,aAAa,KAAK,GAAG,aAAa,WAAW;EAElD,IAAI,aAAa,SAAS,WACxB;EAGF,MAAM,EAAE,aAAa;EACrB,KAAK,UAAU,aAAa;EAE5B,IAAI,SAAS,YAAY,SAAS,KAAK,SAAS,UAAU,SAAS,GAAG;GACpE,MAAM,QAAQ,IAAI,IAAI,KAAK,aAAa,KAAK;GAC7C,MAAM,YAAY,IAAI,IAAI,KAAK,aAAa,SAAS;GACrD,SAAS,OAAO,SAAS,WAAW;GACpC,SAAS,WAAW,SAAS,SAAS;GACtC,KAAK,eAAe;IAAE;IAAO;GAAU;EACzC;EAEA,KAAK,MAAM,cAAc,SAAS,sBAAsB;GACtD,IAAI,aAAa,KAAK,YAAY,IAAI,UAAU;GAEhD,IAAI,eAAe,KAAA,GAAW;IAC5B,6BAAa,IAAI,IAAI;IACrB,KAAK,YAAY,IAAI,YAAY,UAAU;GAC7C;GAEA,WAAW,IAAI,KAAK;EACtB;CACF;;CAGA,SAAiB,QAAsB;EACrC,MAAM,OAAO,KAAK,SAAS,MAAM,GAAG,MAAM;EAC1C,KAAK,WAAW,CAAC;EACjB,KAAK,UAAU,CAAC;EAChB,KAAK,eAAe;EACpB,KAAK,8BAAc,IAAI,IAAI;EAC3B,KAAK,SAAS;EACd,KAAK,eAAe,CAAC;EACrB,KAAK,WAAW,KAAA;EAEhB,KAAK,MAAM,SAAS,KAAK,iBAAiB,KAAK,GAC7C,IAAI,SAAS,QACX,KAAK,iBAAiB,OAAO,KAAK;EAItC,KAAK,MAAM,SAAS,MAClB,KAAK,WAAW,KAAK;EAGvB,KAAK,YAAY;CACnB;;;;;CAMA,SAAiB,MAAwB;EACvC,IAAI,SAAS,GAAG;GACd,KAAK,aAAa,IAAI,kBAAkB;GACxC,KAAK,+BAAe,IAAI,QAAQ;EAClC;EAEA,MAAM,UAAoB,CAAC;EAE3B,KAAK,IAAI,QAAQ,MAAM,QAAQ,KAAK,SAAS,QAAQ,SAAS;GAC5D,MAAM,QAAQ,KAAK,SAAS;GAE5B,MAAM,cAAc,iBAClB,MAAM,cACN,KAAK,YACL,KAAK,eACJ,eAAe,KAAK,kBAAkB,UAAU,CACnD;GAEA,IAAI,CAAC,gBAAgB,MAAM,aAAa,WAAW,GAAG;IACpD,QAAQ,KAAK,KAAK;IAClB,KAAK,SAAS,SAAS;KAAE,GAAG;KAAO;IAAY;GACjD;EACF;EAEA,OAAO;CACT;CAEA,WACE,OACA,cACA,SACA,aACA,cACM;EACN,KAAK,iBAAiB,KAAK,WAAW,KAAK;EAC3C,KAAK,mCAAmB,IAAI,QAAQ;EAEpC,KAAK,QAAQ,MAAM,KAAK,SAAS;GAC/B,MAAM,cAAc,iBAClB,KAAK,cACL,KAAK,gBACL,KAAK,mBACJ,eAAe,KAAK,kBAAkB,UAAU,CACnD;GAEA,MAAM,WAAW,aAAa,MAC3B,UACC,MAAM,WAAW,KAAK,UACtB,MAAM,YAAY,KAAA,KAClB,KAAK,YAAY,KAAA,KACjB,gBAAgB,MAAM,aAAa,WAAW,KAC9C,CAAC,UAAU,OAAO,YAAY,CAClC;GAEA,IAAI,aAAa,KAAA,GACf,OAAO;GAGT,OAAO,KAAK,OACV;IACE,GAAG;IACH,IAAI,KAAK,QAAQ,KAAK,QAAQ,cAAc,OAAO;IACnD,cAAc;IACd;IACA,OAAO,KAAA;GACT,GACA,aACA,KAAK,kBACL,KACF;EACF,CAAC;EAGD,MAAM,OAAO,KAAK,MAAM,GAAG,EAAE;EAE7B,IAAI,SAAS,KAAA,GAAW;GACtB,MAAM,QAAQ,aAAa,KAAK,MAAM,KAAK;GAE3C,IAAI,UAAU,KAAK,MAAM,OACvB,KAAK,MAAM,KAAK,MAAM,SAAS,KAAK;IAClC,GAAG;IACH,OAAO,OAAO,OAAO;KAAE,GAAG,KAAK;KAAO,OAAO,OAAO,OAAO,KAAK;IAAE,CAAC;GACrE;EAEJ;CACF;;CAGA,OACE,OACA,aACA,aACA,SACe;EACf,MAAM,EAAE,cAAc,YAAY;EAElC,IAAI,aAAa,SAAS,MAAM;GAC9B,MAAM,UAAU,aAAa,SAAS;GAEtC,OAAO;IACL,GAAG;IACH,OAAO,OAAO,OAAO;KACnB,IAAI,MAAM;KACV,QAAQ,MAAM;KACd,OAAO,OAAO,OAAO,UAAU,YAAY,KAAK,OAAO,MAAM,MAAM,IAAI,CAAC,CAAC;KACzE,QAAQ,UAAU,YAAY;KAC9B;KACA,aAAa,UAAU,aAAa,cAAc,OAAO,OAAO,CAAC,CAAC;KAClE,cAAc;IAChB,CAAC;GACH;EACF;EAEA,IAAI,eAAe;EACnB,MAAM,aAAa,IAAI,IAAI,aAAa,UAAU;EAElD,MAAM,QAAuB;GAC3B,aAAa,eAAe,YAAY,MAAM,IAAI,UAAU;GAC5D,WAAW,eAAe,YAAY,UAAU,IAAI,UAAU;GAC9D,aAAa,SAAS,YAAY,IAAI,IAAI;GAC1C,SAAS,EAAE,QAAQ,KAAK,MAAM;GAC9B,aAAa;GACb,OAAO,KAAK;EACd;EAEA,MAAM,QAAQ,WACZ,CAAC,aAAa,IAAI,GAClB,YAAY,KAAA,IACR,QACA;GACE,GAAG;GACH,UAAU,SAAS;IACjB,MAAM,OAAO,cACX,MACA,SACA;KACE,MAAM,KAAK;KACX,aAAa,YAAY;KACzB;KACA,QAAQ,KAAK,QAAQ;KACrB,QAAQ,KAAK;KACb,OAAO,KAAK;KACZ,WAAW,KAAK;KAChB,UAAU,KAAK;KACf,UAAU,KAAK;IACjB,IACC,UAAU,aAAa,WAAW,UAAU,OAAO,QAAQ,CAC9D;IAEA,gBAAgB,MAAM,aAAa;IAEnC,OAAO,MAAM;GACf;EACF,CACN;EAEA,MAAM,WAAW;GACf,GAAG,aAAa;GAChB,sBAAsB,CACpB,mBAAG,IAAI,IAAI,CAAC,GAAG,aAAa,SAAS,sBAAsB,GAAG,UAAU,CAAC,CAC3E;EACF;EAEA,OAAO;GACL,GAAG;GACH,cAAc;IAAE,GAAG;IAAc;IAAU,YAAY,CAAC,GAAG,UAAU;GAAE;GACvE;GACA,OAAO,OAAO,OAAO;IACnB,IAAI,MAAM;IACV,QAAQ,MAAM;IACd,OAAO,OAAO,OAAO,KAAK;IAC1B,QAAQ;IACR;IACA,aAAa,aAAa;IAC1B,cAAc,eAAe,QAAQ;GACvC,CAAC;EACH;CACF;CAEA,kBAA0B,YAA6B;EACrD,OACE,KAAK,aAAa,UAAU,IAAI,UAAU,KAAK,KAAK,iBAAiB,UAAU,IAAI,UAAU;CAEjG;CAEA,uBAA4C;EAC1C,MAAM,OAAO,KAAK;EAElB,IAAI,KAAK,MAAM,SAAS,KAAK,KAAK,UAAU,SAAS,GACnD,OAAO,KAAK;EAGd,MAAM,QAAQ,IAAI,IAAI,KAAK,aAAa,KAAK;EAC7C,MAAM,YAAY,IAAI,IAAI,KAAK,aAAa,SAAS;EACrD,SAAS,OAAO,CAAC,GAAG,KAAK,MAAM,OAAO,CAAC,CAAC;EACxC,SAAS,WAAW,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,CAAC;EAEhD,OAAO;GAAE;GAAO;EAAU;CAC5B;;CAGA,gBAAwB,aAA+D;EACrF,MAAM,YAAY,KAAK;EAEvB,MAAM,MAAM,CACV,KAAK,qBACL,GAAG,UAAU,MAAM,SAAS,eAAe;GACzC;GACA,UAAU,MAAM,UAAU;GAC1B,YAAY,UAAU,IAAI,UAAU;EACtC,CAAC,CACH;EAEA,IACE,IAAI,WAAW,KAAK,cAAc,UAClC,IAAI,OAAO,OAAO,UAAU,UAAU,KAAK,cAAc,MAAM,GAE/D,OAAO,KAAK;EAGd,KAAK,gBAAgB;EACrB,KAAK,aAAa,qBAAqB,WAAW;GAChD,aAAa,eAAe,YAAY,MAAM,IAAI,UAAU;GAC5D,WAAW,eAAe,YAAY,UAAU,IAAI,UAAU;GAC9D,aAAa,SAAS,KAAK,aAAa,IAAI,IAAI,KAAK,KAAK,iBAAiB,IAAI,IAAI;GACnF,SAAS,EAAE,QAAQ,KAAK,MAAM;GAC9B,aAAa;EACf,CAAC;EAED,OAAO,KAAK;CACd;;CAGA,WAAmB,SAAsD;EACvE,IAAI,KAAK,MAAM,SAAS,KAAK,QAAQ,qBACnC,OAAO;GAAE,OAAO;GAAuB,QAAQ,KAAK,MAAM;EAAO;EAGnE,IAAI,KAAK,aAAa,KAAA,GACpB,OAAO,KAAK;EAGd,MAAM,iBAAiB,KAAK,iBAAiB,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC;EAE7D,IAAI,mBAAmB,KAAA,GACrB,OAAO;EAGT,IAAI,QAAQ,IAAI,KAAK;EAErB,KAAK,MAAM,SAAS,KAAK,OAAO;GAC9B,IAAI,MAAM,aAAa,SAAS,iBAC9B,OAAO;IAAE,OAAO,MAAM,aAAa;IAAO,QAAQ,MAAM,OAAO;GAAI;GAGrE,UACG,MAAM,aAAa,SAAS,OAAO,MAAM,aAAa,YAAY,KAAK,MAAM;EAClF;EAEA,IAAI,QAAQ,KAAK,QAAQ,cACvB,OAAO;GAAE,OAAO;GAAgB,QAAQ,KAAK,MAAM,GAAG,EAAE,CAAC,EAAE,OAAO,OAAO;EAAE;EAG7E,MAAM,QACJ,YAAY,KAAA,IAAY,KAAA,IAAY,KAAK,MAAM,MAAM,UAAU,MAAM,YAAY,KAAA,CAAS;EAE5F,IACE,UAAU,KAAA,KACV,MAAM,OAAO,MAAM,MAAM,MAAM,OAAO,MAAM,QAAQ,KAAK,4BAEzD,OAAO;GAAE,OAAO;GAA6B,QAAQ,MAAM,OAAO,MAAM;EAAI;CAIhF;;CAGA,YAAoB,OAAoC;EACtD,KAAK,kBAAkB;EAEvB,MAAM,WAA8B,OAAO,OAAO;GAChD,MAAM;GACN,MAAM,KAAK;GACX,QAAQ,KAAK,YAAY,UAAU,OAAO,OAAO,CAAC,CAAC;GACnD,WAAW,KAAK,YAAY;GAC5B,aAAa,OAAO,OAAO,CAAC,gBAAgB,KAAK,OAAO,KAAK,CAAC,CAAC;GAC/D,OAAO,MAAM;EACf,CAAC;EAED,OAAO,OAAO,OAAO;GACnB;GACA,OAAO,SAAS,OAAO;GACvB,WAAW,OAAO,OAAO,CAAC,CAAC;GAC3B,kBAAkB;EACpB,CAAC;CACH;CAEA,WAAmB,OAA+B;EAChD,MAAM,UACJ,MAAM,UAAU,8BACZ,KAAK,6BACL,KAAK,QAAQ,MAAM;EAEzB,OAAO,WAAW,SAChB,KAAK,OACL,MAAM,OACN,SACA;GAAE,OAAO,MAAM;GAAQ,KAAK,MAAM;EAAO,GACzC,MAAM,UAAU,wBAAwB,KAAK,MAAM,SAAS,KAAA,CAC9D;CACF;;CAGA,QACE,QACA,cACA,SACS;EACT,IAAI,YAAY,KAAA,GACd,OAAO,QAAQ,IAAI,SAAS,MAAM,CAAC,KAAK,KAAK,MAAM;EAGrD,OAAO,aAAa,MAAM,UAAU,MAAM,OAAO,UAAU,OAAO,KAAK,CAAC,EAAE,MAAM,KAAK,MAAM;CAC7F;;CAGA,WAAmB,MAA6C;EAC9D,MAAM,0BAAU,IAAI,IAAqB;EACzC,MAAM,QAAQ,KAAK,KAAK,UAAU,KAAK,MAAM,KAAK;EAElD,KAAK,MAAM,SAAS,CAAC,GAAG,KAAK,UAAU,GAAG,KAAK,KAAK,GAClD,IAAI,CAAC,gBAAgB,MAAM,QAAQ,IAAI,GACrC,QAAQ,IACN,SAAS,MAAM,OAAO,SAAS,KAAK,MAAM,WAAW,MAAM,QAAQ,KAAK,IAAI,MAAM,MAAM,GACxF,MAAM,EACR;EAIJ,OAAO;CACT;CAEA,QAAyB;EACvB,MAAM,QAAQ,SAAS,KAAK;EAE5B,IAAI,CAAC,UAAU,KAAK,GAClB,MAAM,IAAI,MAAM,0CAA0C;EAG5D,OAAO;CACT;AACF;;AAsBA,MAAM,aAA0B,OAAO,OAAO;CAC5C,IAAI,cAAc;CAClB,QAAQ,OAAO,OAAO;EAAE,OAAO;EAAG,KAAK;CAAE,CAAC;CAC1C,OAAO,OAAO,OAAO,CAAC,CAAC;CACvB,QAAQ;CACR,SAAS;CACT,aAAa,OAAO,OAAO,CAAC,CAAC;CAC7B,cAAc;AAChB,CAAC;;AAGD,SAAS,cAAc,OAAgC;CACrD,IAAI,MAAM,UAAU,KAAA,GAClB,MAAM,IAAI,MAAM,yCAAyC;CAG3D,OAAO,MAAM;AACf;AAEA,SAAS,kBAAkB,MAA+B;CACxD,OAAO,KAAK,aAAa,SAAS,OAAO,CAAC,KAAK,aAAa,IAAI,IAAI,CAAC;AACvE;AAEA,MAAM,gBAA+B,OAAO,OAAO;CACjD,sBAAsB,OAAO,OAAO,CAAC,CAAC;CACtC,oBAAoB,OAAO,OAAO,CAAC,CAAC;CACpC,aAAa,OAAO,OAAO,CAAC,CAAC;CAC7B,WAAW,OAAO,OAAO,CAAC,CAAC;AAC7B,CAAC;;AAGD,MAAM,gCAAgB,IAAI,QAAgC;;AAG1D,SAAS,cAAc,MAA8B;CACnD,MAAM,MAAM,cAAc,IAAI,IAAI;CAElC,IAAI,QAAQ,KAAA,GACV,OAAO;CAGT,IAAI,KAAK,SAAS,QAChB,OAAO,aAAa,IAAI;CAG1B,MAAM,QAAQ,YAAY,IAAI,CAAC,CAAC,IAAI,aAAa;CAEjD,QAAQ,KAAK,MAAb;EACE,KAAK;EACL,KAAK;GACH,MAAM,QAAQ;IAAE,GAAG;IAAe,sBAAsB,CAAC,KAAK,UAAU;GAAE,CAAC;GAC3E;EACF,KAAK;GACH,MAAM,QAAQ;IAAE,GAAG;IAAe,oBAAoB,CAAC,IAAI;GAAE,CAAC;GAC9D;EACF,KAAK;GACH,MAAM,QAAQ;IAAE,GAAG;IAAe,aAAa,CAAC,IAAI;GAAE,CAAC;GACvD;EACF,KAAK,sBACH,MAAM,QAAQ;GAAE,GAAG;GAAe,WAAW,CAAC,IAAI;EAAE,CAAC;CAIzD;CAEA,MAAM,SAAS,MAAM,QAAQ,SAAS,SAAS,aAAa;CAE5D,MAAM,WACJ,OAAO,WAAW,IACd,gBACA,OAAO,WAAW,IAChB,OAAO,KACP;EACE,sBAAsB,CAAC,GAAG,IAAI,IAAI,OAAO,SAAS,SAAS,KAAK,oBAAoB,CAAC,CAAC;EACtF,oBAAoB,OAAO,SAAS,SAAS,KAAK,kBAAkB;EACpE,aAAa,OAAO,SAAS,SAAS,KAAK,WAAW;EACtD,WAAW,OAAO,SAAS,SAAS,KAAK,SAAS;CACpD;CAER,cAAc,IAAI,MAAM,QAAQ;CAEhC,OAAO;AACT;;AAGA,MAAM,oCAAoB,IAAI,QAG5B;;AAGF,SAAS,aAAa,MAA+B;CACnD,MAAM,QAAQ,KAAK;CACnB,IAAI,QAAQ;CACZ,IAAI,WAAW;CAEf,KAAK,IAAI,QAAQ,MAAM,SAAS,GAAG,SAAS,KAAK,IAAI,GAAG,MAAM,SAAS,CAAC,GAAG,SAAS;EAClF,MAAM,SAAS,kBAAkB,IAAI,MAAM,MAAM;EAEjD,IAAI,QAAQ,UAAU,OAAO;GAC3B,QAAQ,QAAQ;GAChB,WAAW,OAAO;GAClB;EACF;CACF;CAEA,KAAK,IAAI,QAAQ,OAAO,QAAQ,MAAM,QAAQ,SAAS;EACrD,WAAW,cAAc,UAAU,cAAc,MAAM,MAAM,CAAC;EAE9D,IAAI,SAAS,MAAM,SAAS,GAC1B,kBAAkB,IAAI,MAAM,QAAQ;GAAE;GAAO;EAAS,CAAC;CAE3D;CAEA,cAAc,IAAI,MAAM,QAAQ;CAEhC,OAAO;AACT;AAEA,SAAS,cAAc,MAAqB,OAAqC;CAC/E,IAAI,UAAU,eACZ,OAAO;CAGT,IAAI,SAAS,eACX,OAAO;CAGT,OAAO;EACL,sBAAsB,CACpB,mBAAG,IAAI,IAAI,CAAC,GAAG,KAAK,sBAAsB,GAAG,MAAM,oBAAoB,CAAC,CAC1E;EACA,oBAAoB,CAAC,GAAG,KAAK,oBAAoB,GAAG,MAAM,kBAAkB;EAC5E,aAAa,CAAC,GAAG,KAAK,aAAa,GAAG,MAAM,WAAW;EACvD,WAAW,CAAC,GAAG,KAAK,WAAW,GAAG,MAAM,SAAS;CACnD;AACF;AAEA,SAAS,mBAAmB,OAAwC;CAClE,MAAM,wBAAQ,IAAI,IAA4B;CAC9C,MAAM,4BAAY,IAAI,IAAoC;CAE1D,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,WAAW,cAAc,IAAI;EACnC,SAAS,OAAO,SAAS,WAAW;EACpC,SAAS,WAAW,SAAS,SAAS;CACxC;CAEA,OAAO;EAAE;EAAO;CAAU;AAC5B;;AAGA,SAAS,mBACP,SACA,UACA,MAC4B;CAC5B,IAAI,SAAS,WAAW,GACtB,OAAO;CAGT,MAAM,MAAM,IAAI,IAAI,QAAQ;CAC5B,MAAM,UAAU,IAAI,IAAI,OAAO;CAE/B,KAAK,MAAM,QAAQ,MAAM;EACvB,MAAM,SAAS,QAAQ,IAAI,KAAK,UAAU;EAE1C,IAAI,WAAW,KAAA,KAAa,IAAI,IAAI,MAAM,GACxC,QAAQ,IAAI,KAAK,YAAY,IAAI;CAErC;CAEA,OAAO;AACT;AAEA,SAAS,SACP,QACA,OACM;CACN,KAAK,MAAM,QAAQ,OACjB,IAAI,CAAC,OAAO,IAAI,KAAK,UAAU,GAC7B,OAAO,IAAI,KAAK,YAAY,IAAI;AAGtC;AAEA,SAAS,mBAAmB,QAAqB,OAAuC;CACtF,MAAM,wBAAQ,IAAI,IAAY;CAE9B,IAAI,OAAO,UAAU,MAAM,OACzB,KAAK,MAAM,8BAAc,IAAI,IAAI,CAAC,GAAG,OAAO,MAAM,KAAK,GAAG,GAAG,MAAM,MAAM,KAAK,CAAC,CAAC,GAAG;EACjF,MAAM,WAAW,OAAO,MAAM,IAAI,UAAU;EAC5C,MAAM,OAAO,MAAM,MAAM,IAAI,UAAU;EAEvC,IAAI,UAAU,QAAQ,MAAM,OAAO,UAAU,UAAU,MAAM,OAC3D,MAAM,IAAI,UAAU;CAExB;CAGF,IAAI,YAAY,OAAO,UAAU,SAAS,MAAM,UAAU;CAE1D,KAAK,MAAM,cAAc,MAAM,UAAU,KAAK,GAC5C,cAAc,CAAC,OAAO,UAAU,IAAI,UAAU;CAGhD,OAAO;EAAE;EAAO;CAAU;AAC5B;AAEA,SAAS,iBACP,cACA,WACA,aACA,SACa;CACb,IAAI,aAAa,SAAS,QAAQ,aAAa,SAAS,mBAAmB,WAAW,GACpF,OAAO;CAGT,OAAO,aAAa,SAAS,mBAAmB,KAAK,SAAyC;EAC5F,IAAI,CAAC,QAAQ,KAAK,UAAU,GAC1B;EAGF,MAAM,aAAa,UAAU,UAAU,KAAK,UAAU;EACtD,YAAY,IAAI,MAAM,UAAU;EAEhC,OAAO;CACT,CAAC;AACH;AAEA,SAAS,gBAAgB,MAAmB,OAA6B;CACvE,OACE,SAAS,SACR,KAAK,WAAW,MAAM,UACrB,KAAK,OACF,YAAY,UACX,YAAY,YAAY,MAAM,MAAM,EAAE,WACtC,YAAY,eAAe,MAAM,MAAM,EAAE,UAC7C;AAEN;AAEA,SAAS,UAAU,OAAmB,aAA2C;CAC/E,OACE,YAAY,OAAO,KACnB,MAAM,aAAa,SAAS,QAC5B,MAAM,aAAa,SAAS,qBAAqB,MAAM,eACrD,YAAY,IAAI,UAAU,CAC5B;AAEJ;AAEA,SAAS,eAAe,UAA6C;CACnE,IAAI,SAAS,qBAAqB,WAAW,KAAK,SAAS,mBAAmB,WAAW,GACvF,OAAO;CAGT,OAAO,OAAO,OAAO;EACnB,aAAa,OAAO,OAAO,CAAC,GAAG,SAAS,oBAAoB,CAAC;EAC7D,WAAW,OAAO,OAAO,CACvB,GAAG,IAAI,IAAI,SAAS,mBAAmB,KAAK,SAAS,KAAK,UAAU,CAAC,CACvE,CAAC;CACH,CAAC;AACH;;AAGA,SAAS,kBACP,MACA,aACA,MACa;CACb,MAAM,WAAW,cAAc,IAAI;CAQnC,IAAI,EALF,SAAS,qBAAqB,MAAM,eAAe,CAAC,YAAY,MAAM,IAAI,UAAU,CAAC,KACrF,SAAS,mBAAmB,MACzB,cAAc,CAAC,YAAY,UAAU,IAAI,UAAU,UAAU,CAChE,IAGA,OAAO;CAGT,MAAM,YAAY,cAChB,UAAU,WAAW,KAAA,IACjB,KAAA,IACA;EAAE,MAAM;EAAQ,OAAO,KAAK,MAAM,UAAU,MAAM;EAAG,QAAQ,UAAU;CAAO;CAEpF,MAAM,CAAC,UAAU,WACf;EAAE,MAAM;EAAY,UAAU,CAAC,IAAI;CAAE,GACrC;EACE,gBAAgB,EAAE,MAAM,gBACtB,YAAY,MAAM,IAAI,UAAU,UAAU,IAAI,KAAA,IAAY,SAAS,SAAS;EAC9E,iBAAiB,EAAE,MAAM,gBACvB,YAAY,MAAM,IAAI,UAAU,UAAU,IAAI,KAAA,IAAY,SAAS,SAAS;EAC9E,oBAAoB,EAAE,MAAM,gBAC1B,YAAY,UAAU,IAAI,UAAU,UAAU,IAAI,KAAA,IAAY,SAAS,SAAS;CACpF,CACF,CAAC,CAAC;CAEF,IAAI,WAAW,KAAA,GACb,MAAM,IAAI,MAAM,6CAA6C;CAG/D,OAAO;AACT;;AAGA,SAAS,YAAY,MAAkB,QAAiC;CACtE,OAAO,CACL;EACE,MAAM;EACN,SAAS;EACT,YAAY,CAAC;EACb,UAAU,CAAC;GAAE,MAAM;GAAQ,OAAO,KAAK,cAAc,MAAM,CAAC,CAAC,QAAQ;GAAG;EAAO,CAAC;EAChF;CACF,CACF;AACF;AAEA,SAAS,gBAAgB,MAAkB,OAA+B;CACxE,OAAO,iBAAiB;EACtB,MAAM;EACN,UAAU;EACV,SAAS,GAAG,MAAM,MAAM,iCAAiC,MAAM;EAC/D,MAAM;GAAE;GAAM,OAAO,MAAM;GAAQ,KAAK,MAAM;EAAO;CACvD,CAAC;AACH;;AAGA,SAAS,YAAY,MAAkB,QAAkC;CACvE,IAAI,QAAQ,OAAO,MAAM;CAEzB,OAAO,QAAQ,KAAK,KAAK,KAAK,QAAQ,CAAC,MAAM,QAAQ,KAAK,KAAK,QAAQ,CAAC,MAAM,MAC5E;CAGF,OAAO;EAAE;EAAO,KAAK,OAAO,MAAM;CAAI;AACxC;AAEA,SAAS,cAAc,OAAoB,OAA6B;CACtE,OAAO,MAAM,SAAS,MAAM,SAAS,MAAM,OAAO,MAAM;AAC1D;AAEA,SAAS,SAAS,OAA4B;CAC5C,OAAO,GAAG,MAAM,MAAM,GAAG,MAAM;AACjC;;AAGA,SAAS,gBAAyB;CAChC,MAAM,QAAQ;CAEd,IAAI,CAAC,UAAU,KAAK,GAClB,MAAM,IAAI,MAAM,0CAA0C;CAG5D,OAAO;AACT;AAEA,SAAS,UAAU,OAAiC;CAClD,OAAO,eAAe,KAAK,KAAK;AAClC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ResolvedSyntaxOptions } from "./syntax-options.mjs";
|
|
2
|
+
import { MdxNode, PhrasingContent } from "./model.mjs";
|
|
3
|
+
import { HtmlNode } from "./html.mjs";
|
|
4
|
+
import { SourceFile } from "./source.mjs";
|
|
5
|
+
import { HtmlLoweringCache } from "./html-lower.mjs";
|
|
6
|
+
import { ResolvedParserLimits } from "./parser/config.mjs";
|
|
7
|
+
import { InlineSegment } from "./parser/inline-input.mjs";
|
|
8
|
+
import { PendingBlockSyntax } from "./parser/block-syntax.mjs";
|
|
9
|
+
import { DefinitionLookup } from "./parser/inline-syntax.mjs";
|
|
10
|
+
import { InlineParser } from "./parser/inline-parser.mjs";
|
|
11
|
+
import { PhrasingCache } from "./parser/materialize.mjs";
|
|
12
|
+
//#region src/stream-tail.d.ts
|
|
13
|
+
/** Lowers MDX siblings in the scope of the block that contains the open leaf. */
|
|
14
|
+
export type LowerNodes = (nodes: readonly MdxNode[], previous?: MdxNode) => HtmlNode[];
|
|
15
|
+
export interface OpenLeafContext {
|
|
16
|
+
readonly definitions: DefinitionLookup;
|
|
17
|
+
readonly references: Set<string>;
|
|
18
|
+
readonly file: SourceFile;
|
|
19
|
+
readonly syntax: ResolvedSyntaxOptions;
|
|
20
|
+
readonly limits: ResolvedParserLimits;
|
|
21
|
+
/** Code text of the open fence, extended by later appends. */
|
|
22
|
+
readonly fence: FenceText;
|
|
23
|
+
/** Work on the open paragraph that later appends reuse. */
|
|
24
|
+
readonly paragraph: OpenParagraph;
|
|
25
|
+
readonly phrasing: PhrasingCache;
|
|
26
|
+
/** Lowering resolves references through this cache; a new one means new definitions. */
|
|
27
|
+
readonly lowering: HtmlLoweringCache;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The open paragraph's input, resumable inline parse, and the output of its
|
|
31
|
+
* leading inline nodes. The paragraph owns these arrays and truncates and
|
|
32
|
+
* extends them in place, so an append decodes, parses, materializes, and
|
|
33
|
+
* lowers only what changed.
|
|
34
|
+
*/
|
|
35
|
+
export declare class OpenParagraph {
|
|
36
|
+
#private;
|
|
37
|
+
/** Starts tracking the paragraph at `start`, dropping work done for another. */
|
|
38
|
+
open(start: number, lowering: HtmlLoweringCache): void;
|
|
39
|
+
parse(file: SourceFile, segments: readonly InlineSegment[], syntax: ResolvedSyntaxOptions, definitions: DefinitionLookup): ReturnType<InlineParser["parse"]>;
|
|
40
|
+
/** The last materialized node, which decides how text after a hard break renders. */
|
|
41
|
+
get lastNode(): PhrasingContent | undefined;
|
|
42
|
+
/** The unchanged prefix, capped where footnote numbering must be refreshed. */
|
|
43
|
+
reusable(changedFrom: number): number;
|
|
44
|
+
/** Keeps the first `length` groups and returns how many nodes they materialized. */
|
|
45
|
+
truncate(length: number): number;
|
|
46
|
+
push(node: PhrasingContent | undefined, html: readonly HtmlNode[], nodeEnd: number, numbered: boolean): void;
|
|
47
|
+
/**
|
|
48
|
+
* The rendered children for a snapshot.
|
|
49
|
+
* A long paragraph groups full chunks into fragments that keep their identity, so a snapshot copies only the
|
|
50
|
+
* chunk list and the last partial chunk.
|
|
51
|
+
*/
|
|
52
|
+
children(): HtmlNode[];
|
|
53
|
+
}
|
|
54
|
+
/** The open leaf's rendering, and the nodes it materialized for the node limit. */
|
|
55
|
+
export interface OpenLeafHtml {
|
|
56
|
+
readonly nodes: readonly HtmlNode[];
|
|
57
|
+
readonly nodeCount: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Renders the open leaf of a stream.
|
|
61
|
+
* The materializer leaves an empty placeholder with the leaf's origin, and lowering asks this function for the
|
|
62
|
+
* placeholder's HTML.
|
|
63
|
+
*/
|
|
64
|
+
export declare function lowerOpenLeaf(node: MdxNode, pending: PendingBlockSyntax, context: OpenLeafContext, lower: LowerNodes): OpenLeafHtml | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* The code of an open fence. Complete lines never change while the fence stays
|
|
67
|
+
* open, so each append decodes only the lines that arrived since the last one.
|
|
68
|
+
*/
|
|
69
|
+
export declare class FenceText {
|
|
70
|
+
#private;
|
|
71
|
+
text(file: SourceFile, start: number, segments: PendingFenceSegments): string;
|
|
72
|
+
}
|
|
73
|
+
type PendingFenceSegments = Extract<PendingBlockSyntax, {
|
|
74
|
+
kind: "fencedCode";
|
|
75
|
+
}>["value"];
|
|
76
|
+
/**
|
|
77
|
+
* Removes empty trailing containers from the open end of a stream. A bare list
|
|
78
|
+
* marker, heading marker, or quote marker can still become other syntax, so it
|
|
79
|
+
* renders nothing until content arrives.
|
|
80
|
+
*/
|
|
81
|
+
export declare function trimOpenTail(nodes: readonly HtmlNode[]): readonly HtmlNode[];
|
|
82
|
+
//#endregion
|
|
83
|
+
export {};
|
|
84
|
+
//# sourceMappingURL=stream-tail.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-tail.d.mts","names":[],"sources":["../src/stream-tail.ts"],"mappings":";;;;;;;;;;;;;YA6BY,cAAc,gBAAgB,WAAW,WAAW,YAAY;iBAE3D;WACN,aAAa;WACb,YAAY;WACZ,MAAM;WACN,QAAQ;WACR,QAAQ;;WAER,OAAO;;WAEP,WAAW;WACX,UAAU;;WAEV,UAAU;;;;;;;;qBAoBR;;;EAaJ,KAAK,eAAe,UAAU;EAa9B,MACL,MAAM,YACN,mBAAmB,iBACnB,QAAQ,uBACR,aAAa,mBACZ,WAAW;;MAQH,YAAY;;EAKhB,SAAS;;EAaT,SAAS;EAgBT,KACL,MAAM,6BACN,eAAe,YACf,iBACA;;;;;;EAeK,YAAY;;;iBAmBJ;WACN,gBAAgB;WAChB;;;;;;;wBAQK,cACd,MAAM,SACN,SAAS,oBACT,SAAS,iBACT,OAAO,aACN;;;;;qBA2RU;;EAMJ,KAAK,MAAM,YAAY,eAAe,UAAU;;KAgCpD,uBAAuB,QAAQ;EAAsB;;;;;;;wBAkC1C,aAAa,gBAAgB,sBAAsB"}
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import { sourceText } from "./source.mjs";
|
|
2
|
+
import { footnoteReferences } from "./html-lower.mjs";
|
|
3
|
+
import { parseFlowRange } from "./parser/block-parser.mjs";
|
|
4
|
+
import { InlineInput } from "./parser/inline-input.mjs";
|
|
5
|
+
import { InlineParser } from "./parser/inline-parser.mjs";
|
|
6
|
+
import { isFlowJsxChildren } from "./parser/materialize-jsx.mjs";
|
|
7
|
+
import { materializeDocument, materializePhrasing, materializePhrasingGroups } from "./parser/materialize.mjs";
|
|
8
|
+
//#region src/stream-tail.ts
|
|
9
|
+
/** Children of a long open paragraph are grouped into fragments of this size. */
|
|
10
|
+
const CHUNK_SIZE = 64;
|
|
11
|
+
/**
|
|
12
|
+
* The open paragraph's input, resumable inline parse, and the output of its
|
|
13
|
+
* leading inline nodes. The paragraph owns these arrays and truncates and
|
|
14
|
+
* extends them in place, so an append decodes, parses, materializes, and
|
|
15
|
+
* lowers only what changed.
|
|
16
|
+
*/
|
|
17
|
+
var OpenParagraph = class {
|
|
18
|
+
#start = -1;
|
|
19
|
+
#lowering;
|
|
20
|
+
#input;
|
|
21
|
+
#parser;
|
|
22
|
+
#groups = [];
|
|
23
|
+
#children = [];
|
|
24
|
+
/** Fragments of full chunks of `#children`, reused while their nodes are unchanged. */
|
|
25
|
+
#chunks = [];
|
|
26
|
+
/** Footnote numbers can change while the paragraph is open, so groups from here render again. */
|
|
27
|
+
#numbered = Infinity;
|
|
28
|
+
/** Starts tracking the paragraph at `start`, dropping work done for another. */
|
|
29
|
+
open(start, lowering) {
|
|
30
|
+
if (this.#start !== start) {
|
|
31
|
+
this.#start = start;
|
|
32
|
+
this.#input = void 0;
|
|
33
|
+
this.truncate(0);
|
|
34
|
+
}
|
|
35
|
+
if (this.#lowering !== lowering) {
|
|
36
|
+
this.#lowering = lowering;
|
|
37
|
+
this.truncate(0);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
parse(file, segments, syntax, definitions) {
|
|
41
|
+
this.#parser ??= new InlineParser(syntax);
|
|
42
|
+
this.#input = new InlineInput(file, segments, this.#input);
|
|
43
|
+
return this.#parser.parse(this.#input, definitions);
|
|
44
|
+
}
|
|
45
|
+
/** The last materialized node, which decides how text after a hard break renders. */
|
|
46
|
+
get lastNode() {
|
|
47
|
+
return this.#groups.at(-1)?.node;
|
|
48
|
+
}
|
|
49
|
+
/** The unchanged prefix, capped where footnote numbering must be refreshed. */
|
|
50
|
+
reusable(changedFrom) {
|
|
51
|
+
const groups = this.#groups;
|
|
52
|
+
let low = Math.min(groups.length, changedFrom, this.#numbered);
|
|
53
|
+
while (low > 0 && groups[low - 1].node?.kind === "hardBreak") low--;
|
|
54
|
+
return low;
|
|
55
|
+
}
|
|
56
|
+
/** Keeps the first `length` groups and returns how many nodes they materialized. */
|
|
57
|
+
truncate(length) {
|
|
58
|
+
this.#groups.length = length;
|
|
59
|
+
const last = this.#groups.at(-1);
|
|
60
|
+
this.#children.length = last?.htmlEnd ?? 0;
|
|
61
|
+
this.#chunks.length = Math.min(this.#chunks.length, Math.floor(this.#children.length / CHUNK_SIZE));
|
|
62
|
+
if (length === 0) this.#numbered = Infinity;
|
|
63
|
+
return last?.nodeEnd ?? 0;
|
|
64
|
+
}
|
|
65
|
+
push(node, html, nodeEnd, numbered) {
|
|
66
|
+
this.#children.push(...html);
|
|
67
|
+
this.#groups.push({
|
|
68
|
+
node,
|
|
69
|
+
htmlEnd: this.#children.length,
|
|
70
|
+
nodeEnd
|
|
71
|
+
});
|
|
72
|
+
if (numbered) this.#numbered = Math.min(this.#numbered, this.#groups.length - 1);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The rendered children for a snapshot.
|
|
76
|
+
* A long paragraph groups full chunks into fragments that keep their identity, so a snapshot copies only the
|
|
77
|
+
* chunk list and the last partial chunk.
|
|
78
|
+
*/
|
|
79
|
+
children() {
|
|
80
|
+
const children = this.#children;
|
|
81
|
+
if (children.length < 128) return [...children];
|
|
82
|
+
while ((this.#chunks.length + 1) * CHUNK_SIZE <= children.length) {
|
|
83
|
+
const start = this.#chunks.length * CHUNK_SIZE;
|
|
84
|
+
this.#chunks.push(Object.freeze({
|
|
85
|
+
kind: "root",
|
|
86
|
+
children: children.slice(start, start + CHUNK_SIZE)
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
return [...this.#chunks, ...children.slice(this.#chunks.length * CHUNK_SIZE)];
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Renders the open leaf of a stream.
|
|
94
|
+
* The materializer leaves an empty placeholder with the leaf's origin, and lowering asks this function for the
|
|
95
|
+
* placeholder's HTML.
|
|
96
|
+
*/
|
|
97
|
+
function lowerOpenLeaf(node, pending, context, lower) {
|
|
98
|
+
if (node.origin?.start !== pending.range.start || node.origin.end !== pending.range.end) return;
|
|
99
|
+
switch (pending.kind) {
|
|
100
|
+
case "paragraph": return node.kind === "paragraph" ? openParagraph(pending, context, lower) : void 0;
|
|
101
|
+
case "fencedCode": return node.kind === "codeBlock" ? {
|
|
102
|
+
nodes: [pendingNode("fence", context.file.slice(pending.range), pending.range, {
|
|
103
|
+
children: [text(context.fence.text(context.file, pending.range.start, pending.value))],
|
|
104
|
+
language: pending.language === void 0 ? void 0 : context.file.semanticSlice(pending.language),
|
|
105
|
+
meta: pending.meta === void 0 ? void 0 : context.file.semanticSlice(pending.meta)
|
|
106
|
+
})],
|
|
107
|
+
nodeCount: 0
|
|
108
|
+
} : void 0;
|
|
109
|
+
case "math": return node.kind === "displayMath" ? {
|
|
110
|
+
nodes: [pendingNode("displayMath", context.file.semanticSlice(pending.range), pending.range, { children: [text(new InlineInput(context.file, pending.value).toString().replace(/\r\n?|\n/gu, "\n").replace(/\n$/u, ""))] })],
|
|
111
|
+
nodeCount: 0
|
|
112
|
+
} : void 0;
|
|
113
|
+
case "jsx": return node.kind === "rawHtmlBlock" ? openJsx(pending, context, lower) : void 0;
|
|
114
|
+
case "expression": return node.kind === "rawHtmlBlock" ? {
|
|
115
|
+
nodes: [pendingNode("expression", context.file.semanticSlice(pending.range), pending.range, { children: [text(context.file.semanticSlice(pending.range))] })],
|
|
116
|
+
nodeCount: 0
|
|
117
|
+
} : void 0;
|
|
118
|
+
case "esm": return node.kind === "rawHtmlBlock" ? {
|
|
119
|
+
nodes: [pendingNode("esm", context.file.slice(pending.range), pending.range)],
|
|
120
|
+
nodeCount: 0
|
|
121
|
+
} : void 0;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/** A paragraph whose last construct is still open renders that construct as a pending node. */
|
|
125
|
+
function openParagraph(pending, context, lower) {
|
|
126
|
+
const cache = context.paragraph;
|
|
127
|
+
cache.open(pending.range.start, context.lowering);
|
|
128
|
+
const parsed = cache.parse(context.file, pending.input, context.syntax, context.definitions);
|
|
129
|
+
for (const identifier of parsed.references) context.references.add(identifier);
|
|
130
|
+
const open = parsed.pending;
|
|
131
|
+
const boundary = open?.range.start ?? Infinity;
|
|
132
|
+
const nodes = parsed.nodes;
|
|
133
|
+
const reused = cache.reusable(parsed.changedFrom);
|
|
134
|
+
let nodeCount = cache.truncate(reused);
|
|
135
|
+
const changed = [];
|
|
136
|
+
for (let index = reused; index < nodes.length; index++) {
|
|
137
|
+
const node = nodes[index];
|
|
138
|
+
if (node.range.start >= boundary) break;
|
|
139
|
+
if (node.range.end > boundary && node.kind !== "text") break;
|
|
140
|
+
const range = {
|
|
141
|
+
start: node.range.start,
|
|
142
|
+
end: boundary
|
|
143
|
+
};
|
|
144
|
+
const inline = node.range.end <= boundary ? node : {
|
|
145
|
+
kind: "text",
|
|
146
|
+
value: context.file.semanticSlice(range),
|
|
147
|
+
range
|
|
148
|
+
};
|
|
149
|
+
changed.push(inline);
|
|
150
|
+
}
|
|
151
|
+
const groups = materializePhrasingGroups(context.file, changed, context.syntax, context.limits, context.phrasing);
|
|
152
|
+
for (const materialized of groups) {
|
|
153
|
+
nodeCount += materialized.nodeCount;
|
|
154
|
+
cache.push(materialized.nodes.at(-1), lower(materialized.nodes, cache.lastNode), nodeCount, materialized.nodes.some((child) => footnoteReferences(child).length > 0));
|
|
155
|
+
}
|
|
156
|
+
const children = cache.children();
|
|
157
|
+
if (open !== void 0) {
|
|
158
|
+
const lowered = openInline(open, context, lower);
|
|
159
|
+
children.push(lowered.node);
|
|
160
|
+
nodeCount += lowered.nodeCount;
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
nodes: [{
|
|
164
|
+
kind: "element",
|
|
165
|
+
tagName: "p",
|
|
166
|
+
attributes: {},
|
|
167
|
+
children,
|
|
168
|
+
origin: pending.range
|
|
169
|
+
}],
|
|
170
|
+
nodeCount
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function openInline(open, context, lower) {
|
|
174
|
+
const source = context.file.slice(open.range);
|
|
175
|
+
switch (open.kind) {
|
|
176
|
+
case "strong":
|
|
177
|
+
case "emphasis":
|
|
178
|
+
case "delete":
|
|
179
|
+
case "link": {
|
|
180
|
+
const materialized = materializePhrasing(context.file, open.children, context.syntax, context.limits);
|
|
181
|
+
return {
|
|
182
|
+
node: pendingNode(open.kind, source, open.range, { children: lower(materialized.nodes) }),
|
|
183
|
+
nodeCount: materialized.nodeCount
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
case "code": return {
|
|
187
|
+
node: pendingNode("code", source, open.range, { children: [text(open.value)] }),
|
|
188
|
+
nodeCount: 0
|
|
189
|
+
};
|
|
190
|
+
case "image": return {
|
|
191
|
+
node: pendingNode("image", source, open.range, { children: [text(open.alt)] }),
|
|
192
|
+
nodeCount: 0
|
|
193
|
+
};
|
|
194
|
+
case "math": return {
|
|
195
|
+
node: pendingNode("inlineMath", context.file.semanticSlice(open.range), open.range, { children: [text(open.value)] }),
|
|
196
|
+
nodeCount: 0
|
|
197
|
+
};
|
|
198
|
+
case "expression": return {
|
|
199
|
+
node: pendingNode("expression", context.file.semanticSlice(open.range), open.range, { children: [text(context.file.semanticSlice(open.range))] }),
|
|
200
|
+
nodeCount: 0
|
|
201
|
+
};
|
|
202
|
+
case "jsx": return {
|
|
203
|
+
node: pendingNode("jsx", source, open.range),
|
|
204
|
+
nodeCount: 0
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Open flow JSX with a committed opening tag renders as pending JSX with its
|
|
210
|
+
* children so far. An opening tag with expression attributes stays inert.
|
|
211
|
+
*/
|
|
212
|
+
function openJsx(pending, context, lower) {
|
|
213
|
+
const authored = context.file.slice(pending.range);
|
|
214
|
+
const opening = pending.opening;
|
|
215
|
+
if (opening === void 0 || !opening.safe || opening.name === void 0) return {
|
|
216
|
+
nodes: [pendingNode("jsx", authored, pending.range)],
|
|
217
|
+
nodeCount: 0
|
|
218
|
+
};
|
|
219
|
+
const children = [];
|
|
220
|
+
let nodeCount = 0;
|
|
221
|
+
if (opening.end !== void 0 && opening.end < authored.length) {
|
|
222
|
+
const range = {
|
|
223
|
+
start: pending.range.start + opening.end,
|
|
224
|
+
end: pending.range.end
|
|
225
|
+
};
|
|
226
|
+
const flow = isFlowJsxChildren(context.file, range);
|
|
227
|
+
const drafts = flow ? parseFlowRange(sourceText(context.file).grammar(), range, context.syntax) : [{
|
|
228
|
+
kind: "paragraph",
|
|
229
|
+
range,
|
|
230
|
+
input: [{
|
|
231
|
+
kind: "source",
|
|
232
|
+
range
|
|
233
|
+
}]
|
|
234
|
+
}];
|
|
235
|
+
const materialized = materializeDocument(context.file, drafts, context.syntax, context.limits, {
|
|
236
|
+
keepReferences: true,
|
|
237
|
+
allowIncomplete: true
|
|
238
|
+
});
|
|
239
|
+
if (materialized.kind === "ok") {
|
|
240
|
+
const lowered = lower(materialized.document.children);
|
|
241
|
+
const paragraph = lowered[0];
|
|
242
|
+
children.push(...!flow && paragraph?.kind === "element" && paragraph.tagName === "p" ? paragraph.children : lowered);
|
|
243
|
+
nodeCount = materialized.blocks.reduce((count, block) => count + block.nodeCount, 0);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
nodes: [{
|
|
248
|
+
kind: "jsx",
|
|
249
|
+
state: "pending",
|
|
250
|
+
element: "flow",
|
|
251
|
+
name: opening.name,
|
|
252
|
+
attributes: committedAttributes(opening),
|
|
253
|
+
fallback: authored,
|
|
254
|
+
children,
|
|
255
|
+
origin: pending.range
|
|
256
|
+
}],
|
|
257
|
+
nodeCount
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
function committedAttributes(opening) {
|
|
261
|
+
return Object.entries(opening.attributes).flatMap(([name, value]) => value === false ? [] : [{
|
|
262
|
+
kind: "jsxAttribute",
|
|
263
|
+
name,
|
|
264
|
+
value: value === true ? void 0 : value
|
|
265
|
+
}]);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* The code of an open fence. Complete lines never change while the fence stays
|
|
269
|
+
* open, so each append decodes only the lines that arrived since the last one.
|
|
270
|
+
*/
|
|
271
|
+
var FenceText = class {
|
|
272
|
+
#start = -1;
|
|
273
|
+
#complete = 0;
|
|
274
|
+
#last;
|
|
275
|
+
#text = "";
|
|
276
|
+
text(file, start, segments) {
|
|
277
|
+
if (!(this.#start === start && this.#complete <= segments.length && (this.#complete === 0 || sameRange(segment(segments, this.#complete - 1), this.#last)))) {
|
|
278
|
+
this.#start = start;
|
|
279
|
+
this.#complete = 0;
|
|
280
|
+
this.#last = void 0;
|
|
281
|
+
this.#text = "";
|
|
282
|
+
}
|
|
283
|
+
const complete = Math.max(this.#complete, segments.length - 1);
|
|
284
|
+
if (complete > this.#complete) {
|
|
285
|
+
this.#text += normalizeLineEndings(new InlineInput(file, segments.slice(this.#complete, complete)).toString());
|
|
286
|
+
this.#complete = complete;
|
|
287
|
+
this.#last = segment(segments, complete - 1);
|
|
288
|
+
}
|
|
289
|
+
const tail = segments.slice(complete);
|
|
290
|
+
return tail.length === 0 ? this.#text : this.#text + normalizeLineEndings(new InlineInput(file, tail).toString());
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
function segment(segments, index) {
|
|
294
|
+
const value = segments[index];
|
|
295
|
+
return value?.kind === "source" ? value.range : void 0;
|
|
296
|
+
}
|
|
297
|
+
function sameRange(left, right) {
|
|
298
|
+
return left?.start === right?.start && left?.end === right?.end;
|
|
299
|
+
}
|
|
300
|
+
function normalizeLineEndings(value) {
|
|
301
|
+
return value.replace(/\r\n?/gu, "\n");
|
|
302
|
+
}
|
|
303
|
+
const TRIMMABLE_TAIL_TAGS = /* @__PURE__ */ new Set([
|
|
304
|
+
"blockquote",
|
|
305
|
+
"h1",
|
|
306
|
+
"h2",
|
|
307
|
+
"h3",
|
|
308
|
+
"h4",
|
|
309
|
+
"h5",
|
|
310
|
+
"h6",
|
|
311
|
+
"li",
|
|
312
|
+
"ol",
|
|
313
|
+
"ul"
|
|
314
|
+
]);
|
|
315
|
+
/**
|
|
316
|
+
* Removes empty trailing containers from the open end of a stream. A bare list
|
|
317
|
+
* marker, heading marker, or quote marker can still become other syntax, so it
|
|
318
|
+
* renders nothing until content arrives.
|
|
319
|
+
*/
|
|
320
|
+
function trimOpenTail(nodes) {
|
|
321
|
+
let index = nodes.length - 1;
|
|
322
|
+
while (index >= 0 && isWhitespaceText(nodes[index])) index--;
|
|
323
|
+
const last = nodes[index];
|
|
324
|
+
if (!(last?.kind === "root") && (last?.kind !== "element" || !TRIMMABLE_TAIL_TAGS.has(last.tagName))) return nodes;
|
|
325
|
+
const nested = trimOpenTail(last.children);
|
|
326
|
+
if (nested.every(isWhitespaceText)) return nodes.slice(0, index);
|
|
327
|
+
return nested === last.children ? nodes : [
|
|
328
|
+
...nodes.slice(0, index),
|
|
329
|
+
{
|
|
330
|
+
...last,
|
|
331
|
+
children: nested
|
|
332
|
+
},
|
|
333
|
+
...nodes.slice(index + 1)
|
|
334
|
+
];
|
|
335
|
+
}
|
|
336
|
+
function isWhitespaceText(node) {
|
|
337
|
+
return node?.kind === "text" && node.value.trim() === "";
|
|
338
|
+
}
|
|
339
|
+
function pendingNode(construct, source, origin, fields = {}) {
|
|
340
|
+
return {
|
|
341
|
+
kind: "pending",
|
|
342
|
+
construct,
|
|
343
|
+
source,
|
|
344
|
+
children: fields.children ?? [],
|
|
345
|
+
language: fields.language,
|
|
346
|
+
meta: fields.meta,
|
|
347
|
+
origin
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
function text(value) {
|
|
351
|
+
return {
|
|
352
|
+
kind: "text",
|
|
353
|
+
value
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
//#endregion
|
|
357
|
+
export { FenceText, OpenParagraph, lowerOpenLeaf, trimOpenTail };
|
|
358
|
+
|
|
359
|
+
//# sourceMappingURL=stream-tail.mjs.map
|