@rohal12/twee-ts 1.16.0 → 1.17.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 +1 -1
- package/dist/bin/twee-ts.js +1540 -796
- package/dist/bin/twee-ts.js.map +1 -1
- package/dist/{compiler-BiDNwR9q.js → diagnostics-DZNS7W41.js} +692 -289
- package/dist/diagnostics-DZNS7W41.js.map +1 -0
- package/dist/index.cjs +1462 -704
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +93 -15
- package/dist/index.d.ts +93 -15
- package/dist/index.js +1464 -706
- package/dist/index.js.map +1 -1
- package/dist/plugins/rollup.d.ts +20 -1
- package/dist/plugins/rollup.js +34 -8
- package/dist/plugins/rollup.js.map +1 -1
- package/dist/plugins/vite.js +46 -33
- package/dist/plugins/vite.js.map +1 -1
- package/package.json +2 -1
- package/dist/compiler-BiDNwR9q.js.map +0 -1
package/dist/bin/twee-ts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"twee-ts.js","names":["_exhaustive","fsWatch","parsePath","CharCodes","isTag","Text","Comment","CDATA","isTagRaw","CREATOR_NAME","CREATOR_NAME","watch","_exhaustive","LINE_TERMINATOR_RE","searchFrom","_exhaustive","watch"],"sources":["../../src/ifid.ts","../../src/escape.ts","../../src/passage.ts","../../src/story.ts","../../src/media-types.ts","../../src/filesystem.ts","../../src/util.ts","../../src/formats.ts","../../src/types.ts","../../src/lexer.ts","../../src/twee2-compat.ts","../../src/parser.ts","../../node_modules/.pnpm/entities@8.1.0/node_modules/entities/dist/decode-codepoint.js","../../node_modules/.pnpm/entities@8.1.0/node_modules/entities/dist/internal/decode-shared.js","../../node_modules/.pnpm/entities@8.1.0/node_modules/entities/dist/generated/decode-data-html.js","../../node_modules/.pnpm/entities@8.1.0/node_modules/entities/dist/generated/decode-data-xml.js","../../node_modules/.pnpm/entities@8.1.0/node_modules/entities/dist/internal/bin-trie-flags.js","../../node_modules/.pnpm/entities@8.1.0/node_modules/entities/dist/decode.js","../../node_modules/.pnpm/htmlparser2@12.0.0/node_modules/htmlparser2/dist/Tokenizer.js","../../node_modules/.pnpm/htmlparser2@12.0.0/node_modules/htmlparser2/dist/Parser.js","../../node_modules/.pnpm/domelementtype@3.0.0/node_modules/domelementtype/dist/index.js","../../node_modules/.pnpm/domhandler@6.0.1/node_modules/domhandler/dist/node.js","../../node_modules/.pnpm/domhandler@6.0.1/node_modules/domhandler/dist/index.js","../../node_modules/.pnpm/htmlparser2@12.0.0/node_modules/htmlparser2/dist/index.js","../../src/html-parser.ts","../../src/loader.ts","../../src/version.ts","../../src/output-twine2.ts","../../src/output-twine1.ts","../../src/output-twee.ts","../../src/modules.ts","../../src/remote-formats.ts","../../src/compiler.ts","../../src/javascript-strings.ts","../../src/sugarcube-macros.ts","../../src/inspect.ts","../../src/lint.ts","../../src/config.ts","../../bin/twee-ts.ts"],"sourcesContent":["/**\n * IFID (Interactive Fiction IDentifier) generation and validation.\n * Ported from ifid.go.\n */\nimport { randomUUID } from 'node:crypto';\nimport type { IFID } from './types.js';\n\n/** Generate a new IFID (UUID v4, uppercase). */\nexport function generateIFID(): IFID {\n return randomUUID().toUpperCase() as IFID;\n}\n\n/** Validate and brand an IFID string. Throws on invalid input. */\nexport function createIFID(value: string): IFID {\n const err = validateIFID(value);\n if (err) throw new Error(`Invalid IFID: ${err}`);\n return value.toUpperCase() as IFID;\n}\n\n/**\n * Validate an IFID string.\n * Accepts both bare UUIDs and UUID://...// wrapped format.\n * Returns null if valid, or an error message string.\n */\nexport function validateIFID(ifid: string): string | null {\n let uuid = ifid;\n\n switch (ifid.length) {\n case 36:\n break;\n case 45: {\n if (ifid.slice(0, 7).toUpperCase() !== 'UUID://' || ifid.slice(43) !== '//') {\n return 'invalid IFID UUID://...// format';\n }\n uuid = ifid.slice(7, 43);\n break;\n }\n default:\n return `invalid IFID length: ${ifid.length}`;\n }\n\n for (let i = 0; i < uuid.length; i++) {\n const ch = uuid[i]!;\n switch (i) {\n case 8:\n case 13:\n case 18:\n case 23:\n if (ch !== '-') {\n return `invalid IFID character '${ch}' at position ${i + 1}`;\n }\n break;\n case 14:\n if (ch < '1' || ch > '5') {\n return `invalid version '${ch}' at position ${i + 1}`;\n }\n break;\n case 19:\n if (!['8', '9', 'a', 'A', 'b', 'B'].includes(ch)) {\n return `invalid variant '${ch}' at position ${i + 1}`;\n }\n break;\n default:\n if (!/^[0-9a-fA-F]$/.test(ch)) {\n return `invalid IFID hex value '${ch}' at position ${i + 1}`;\n }\n break;\n }\n }\n\n return null;\n}\n","/**\n * HTML, attribute, tiddler, and twee escaping/unescaping utilities.\n * Ported from escaping.go.\n */\n\n/** Escape the minimum characters required for HTML attribute values. */\nexport function attrEscape(s: string): string {\n if (s.length === 0) return s;\n return s.replace(/&/g, '&').replace(/\"/g, '"').replace(/'/g, ''');\n}\n\n/** Escape for HTML attribute values including < and > (for spec-compliant output). */\nexport function fullAttrEscape(s: string): string {\n if (s.length === 0) return s;\n return s\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\n/** Escape the minimum characters required for general HTML content. */\nexport function htmlEscape(s: string): string {\n if (s.length === 0) return s;\n return s\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\n/** Escape for Twine 1 tiddler format. */\nexport function tiddlerEscape(s: string): string {\n if (s.length === 0) return s;\n return s\n .replace(/\\\\/g, '\\\\s')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/\\t/g, '\\\\t')\n .replace(/\\n/g, '\\\\n');\n}\n\n/** Unescape from Twine 1 tiddler format. */\nexport function tiddlerUnescape(s: string): string {\n if (s.length === 0) return s;\n return s.replace(/\\\\n/g, '\\n').replace(/\\\\t/g, '\\t').replace(/\\\\s/g, '\\\\');\n}\n\n/** Escape characters that are special in Twee passage names/tags. */\nexport function tweeEscape(s: string): string {\n if (s.length === 0) return s;\n return s.replace(/[\\\\[\\]{}]/g, (ch) => '\\\\' + ch);\n}\n\n/** Escape a string for safe inclusion in a JavaScript string literal. */\nexport function jsStringEscape(s: string): string {\n if (s.length === 0) return s;\n return s\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\n/g, '\\\\n')\n .replace(/\\r/g, '\\\\r')\n .replace(/\\t/g, '\\\\t');\n}\n\n/** Sanitize a string for safe inclusion in a CSS or JS block comment. */\nexport function commentSanitize(s: string): string {\n return s.replace(/\\*\\//g, '* /');\n}\n\n/** Sanitize a string for safe inclusion in an HTML comment. */\nexport function htmlCommentSanitize(s: string): string {\n return s.replace(/-->/g, '-- >');\n}\n\n/** Apply ROT13 encoding to a string (only affects [A-Za-z]). */\nexport function rot13(s: string): string {\n if (s.length === 0) return s;\n return s.replace(/[A-Za-z]/g, (ch) => {\n const base = ch <= 'Z' ? 65 : 97;\n return String.fromCharCode(((ch.charCodeAt(0) - base + 13) % 26) + base);\n });\n}\n\n/** Unescape backslash-escaped Twee characters. */\nexport function tweeUnescape(s: string): string {\n if (s.length === 0) return s;\n let result = '';\n for (let i = 0; i < s.length; i++) {\n if (s[i] === '\\\\') {\n i++;\n if (i >= s.length) {\n result += '\\\\';\n break;\n }\n }\n result += s[i];\n }\n return result;\n}\n","/**\n * Passage helpers and output methods.\n * Ported from passage.go / passagedata.go.\n */\nimport type { Passage, PassageMetadata, OutputMode, WordCountMethod } from './types.js';\nimport { attrEscape, fullAttrEscape, htmlEscape, tiddlerEscape, tweeEscape, rot13, commentSanitize } from './escape.js';\n\n// Info passages contain structural data, metadata, and code rather than story content.\nconst INFO_PASSAGE_NAMES = new Set([\n 'StoryAuthor',\n 'StoryInit',\n 'StoryMenu',\n 'StorySubtitle',\n 'StoryTitle',\n 'PassageReady',\n 'PassageDone',\n 'PassageHeader',\n 'PassageFooter',\n 'StoryBanner',\n 'StoryCaption',\n 'MenuOptions',\n 'MenuShare',\n 'MenuStory',\n 'StoryInterface',\n 'StoryShare',\n 'StorySettings',\n 'StoryData',\n 'StoryIncludes',\n]);\n\nconst INFO_TAGS = ['annotation', 'script', 'stylesheet', 'widget'];\n\nexport function hasTag(p: Passage, tag: string): boolean {\n return p.tags.includes(tag);\n}\n\nexport function hasAnyTag(p: Passage, ...tags: string[]): boolean {\n return p.tags.some((t) => tags.includes(t));\n}\n\nexport function hasTagStartingWith(p: Passage, prefix: string): boolean {\n return p.tags.some((t) => t.startsWith(prefix));\n}\n\nexport function hasInfoTags(p: Passage): boolean {\n return hasAnyTag(p, ...INFO_TAGS) || hasTagStartingWith(p, 'Twine.');\n}\n\nexport function hasInfoName(p: Passage): boolean {\n return INFO_PASSAGE_NAMES.has(p.name);\n}\n\nexport function isInfoPassage(p: Passage): boolean {\n return hasInfoName(p) || hasInfoTags(p);\n}\n\nexport function isStoryPassage(p: Passage): boolean {\n return !hasInfoName(p) && !hasInfoTags(p);\n}\n\nexport function hasMetadataPosition(p: Passage): boolean {\n return p.metadata != null && p.metadata.position != null && p.metadata.position !== '';\n}\n\nexport function hasMetadataSize(p: Passage): boolean {\n return p.metadata != null && p.metadata.size != null && p.metadata.size !== '';\n}\n\nexport function hasAnyMetadata(p: Passage): boolean {\n if (!p.metadata) return false;\n return Object.values(p.metadata).some((v) => v != null && v !== '');\n}\n\nexport function marshalMetadata(meta: PassageMetadata): string {\n const obj: Record<string, string> = {};\n for (const [key, value] of Object.entries(meta)) {\n if (typeof value === 'string' && value) obj[key] = value;\n }\n return JSON.stringify(obj);\n}\n\nexport function unmarshalMetadata(json: string): PassageMetadata {\n const raw: unknown = JSON.parse(json);\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n return {};\n }\n const parsed = raw as Record<string, unknown>;\n const meta: PassageMetadata = {};\n for (const [key, value] of Object.entries(parsed)) {\n if (typeof value === 'string') meta[key] = value;\n }\n return meta;\n}\n\n/** Convert passage to Twee source. */\nexport function passageToTwee(p: Passage, outMode: OutputMode): string {\n let output: string;\n if (outMode === 'twee3') {\n output = ':: ' + tweeEscape(p.name);\n if (p.tags.length > 0) {\n output += ' [' + tweeEscape(p.tags.join(' ')) + ']';\n }\n if (hasAnyMetadata(p) && p.metadata) {\n output += ' ' + marshalMetadata(p.metadata);\n }\n } else {\n output = ':: ' + p.name;\n if (p.tags.length > 0) {\n output += ' [' + p.tags.join(' ') + ']';\n }\n }\n output += '\\n';\n if (p.text.length > 0) {\n output += p.text + '\\n';\n }\n output += '\\n\\n';\n return output;\n}\n\n/** Generate `<tw-passagedata>` HTML for Twine 2. */\nexport function passageToPassagedata(p: Passage, pid: number, options?: { readonly sourceInfo?: boolean }): string {\n let position: string;\n let size: string;\n\n if (hasMetadataPosition(p)) {\n position = p.metadata?.position ?? '';\n } else {\n const x = pid % 10;\n const y = Math.floor(pid / 10);\n const xp = x === 0 ? 10 : x;\n const yp = x === 0 ? y : y + 1;\n position = `${xp * 125 - 25},${yp * 125 - 25}`;\n }\n\n if (hasMetadataSize(p)) {\n size = p.metadata?.size ?? '';\n } else {\n size = '100,100';\n }\n\n let attrs = `<tw-passagedata pid=\"${pid}\" name=${quote(fullAttrEscape(p.name))} tags=${quote(attrEscape(p.tags.join(' ')))} position=${quote(attrEscape(position))} size=${quote(attrEscape(size))}`;\n if (options?.sourceInfo && p.source) {\n attrs += ` data-source-file=${quote(attrEscape(p.source.file))} data-source-line=\"${p.source.line}\"`;\n }\n return `${attrs}>${htmlEscape(p.text)}</tw-passagedata>`;\n}\n\n/** Generate `<div tiddler>` HTML for Twine 1. */\nexport function passageToTiddler(p: Passage, pid: number, obfuscateRot13 = false): string {\n let position: string;\n\n if (hasMetadataPosition(p)) {\n position = p.metadata?.position ?? '';\n } else {\n const x = pid % 10;\n const y = Math.floor(pid / 10);\n const xp = x === 0 ? 10 : x;\n const yp = x === 0 ? y : y + 1;\n position = `${xp * 140 - 130},${yp * 140 - 130}`;\n }\n\n const created = new Date().toISOString().replace(/[-:T]/g, '').slice(0, 12);\n const content = obfuscateRot13 && p.name !== 'StorySettings' ? tiddlerEscape(rot13(p.text)) : tiddlerEscape(p.text);\n const nameComment = obfuscateRot13 ? `<!-- ${commentSanitize(p.name)} -->` : '';\n return `<div tiddler=${quote(attrEscape(p.name))} tags=${quote(attrEscape(p.tags.join(' ')))} created=${quote(created)} modifier=${quote('twee')} twine-position=${quote(attrEscape(position))}>${nameComment}${content}</div>`;\n}\n\n/**\n * Count words in a passage.\n *\n * - `'tweego'` (default): Strip newlines, strip comments, count NFKD-normalized characters, divide by 5.\n * - `'whitespace'`: Strip comments and markup, split on whitespace, count tokens.\n */\nexport function countWords(p: Passage, method: WordCountMethod = 'tweego'): number {\n switch (method) {\n case 'tweego': {\n let text = p.text;\n text = text.replace(/\\n/g, '');\n text = text.replace(/(?:\\/%.+?%\\/|\\/\\*.+?\\*\\/|<!--.+?-->)/gs, '');\n const normalized = text.normalize('NFKD');\n const count = [...normalized].length;\n if (count === 0) return 0;\n const words = Math.floor(count / 5);\n return count % 5 > 0 ? words + 1 : words;\n }\n case 'whitespace': {\n let text = p.text;\n // Strip comments\n text = text.replace(/(?:\\/%.+?%\\/|\\/\\*.+?\\*\\/|<!--.+?-->)/gs, '');\n // Strip Twine macros <<...>>\n text = text.replace(/<<[^>]*>>/g, '');\n // Strip Twine links [[...]] — keep display text\n text = text.replace(/\\[\\[([^\\]|]*?)(?:\\|[^\\]]*?)?\\]\\]/g, '$1');\n // Strip HTML tags\n text = text.replace(/<[^>]+>/g, '');\n const tokens = text.split(/\\s+/).filter((t) => t.length > 0);\n return tokens.length;\n }\n default: {\n const _exhaustive: never = method;\n throw new Error(`Unhandled word count method: ${_exhaustive as string}`);\n }\n }\n}\n\n/**\n * Apply tag aliases: for each passage carrying an alias tag, add the canonical\n * tag if not already present. Returns new passage objects where tags changed;\n * unchanged passages are returned as-is. Idempotent — safe to call multiple times.\n */\nexport function applyTagAliases(passages: readonly Passage[], aliases: Record<string, string>): Passage[] {\n const entries = Object.entries(aliases);\n if (entries.length === 0) return [...passages];\n return passages.map((p) => {\n const original = p.tags;\n const added: string[] = [];\n for (const [alias, canonical] of entries) {\n if (original.includes(alias) && !original.includes(canonical) && !added.includes(canonical)) {\n added.push(canonical);\n }\n }\n return added.length > 0 ? { ...p, tags: [...original, ...added] } : p;\n });\n}\n\nfunction quote(s: string): string {\n return `\"${s}\"`;\n}\n","/**\n * Story model + StoryData JSON marshal/unmarshal.\n * Ported from story.go + storydata.go.\n */\nimport type { Story, ReadonlyStory, Passage, Diagnostic, WordCountMethod, IFID } from './types.js';\nimport { validateIFID } from './ifid.js';\nimport { isStoryPassage, countWords } from './passage.js';\n\n/** Module-level index: maps passage names to their array indices for O(1) lookups. */\nconst passageIndex = new WeakMap<Story, Map<string, number>>();\n\nfunction getIndex(story: Story): Map<string, number> {\n let index = passageIndex.get(story);\n if (!index) {\n // Rebuild for stories not created via createStory() (e.g., tests, external code)\n index = new Map();\n for (let i = 0; i < story.passages.length; i++) {\n const passage = story.passages[i];\n if (passage) index.set(passage.name, i);\n }\n passageIndex.set(story, index);\n }\n return index;\n}\n\nexport function createStory(): Story {\n const story: Story = {\n name: '',\n ifid: '' as IFID,\n passages: [],\n legacyIFID: '' as IFID,\n twine1: { settings: new Map() },\n twine2: {\n format: '',\n formatVersion: '',\n options: new Map(),\n start: '',\n tags: '',\n tagColors: new Map(),\n zoom: 1,\n },\n };\n passageIndex.set(story, new Map());\n return story;\n}\n\nexport function storyHas(story: Story, name: string): boolean {\n return getIndex(story).has(name);\n}\n\nexport function storyIndex(story: Story, name: string): number {\n return getIndex(story).get(name) ?? -1;\n}\n\nexport function storyGet(story: Story, name: string): Passage | undefined {\n const i = storyIndex(story, name);\n return i === -1 ? undefined : story.passages[i];\n}\n\nexport function storyAppend(story: Story, p: Passage, diagnostics: Diagnostic[]): void {\n const index = getIndex(story);\n const i = index.get(p.name) ?? -1;\n if (i === -1) {\n index.set(p.name, story.passages.length);\n story.passages.push(p);\n } else {\n diagnostics.push({\n level: 'warning',\n message: `Replacing existing passage \"${p.name}\" with duplicate.`,\n });\n story.passages[i] = p;\n }\n}\n\nexport function storyPrepend(story: Story, p: Passage, diagnostics: Diagnostic[]): void {\n const index = getIndex(story);\n const i = index.get(p.name) ?? -1;\n if (i === -1) {\n story.passages.unshift(p);\n // Rebuild index: unshift shifts all existing indices by 1\n index.clear();\n for (let j = 0; j < story.passages.length; j++) {\n const passage = story.passages[j];\n if (passage) index.set(passage.name, j);\n }\n } else {\n diagnostics.push({\n level: 'warning',\n message: `Replacing existing passage \"${p.name}\" with duplicate.`,\n });\n story.passages[i] = p;\n }\n}\n\n// --- StoryData JSON ---\n\ninterface StoryDataJSON {\n ifid?: string;\n format?: string;\n 'format-version'?: string;\n options?: string[];\n start?: string;\n tags?: string;\n 'tag-colors'?: Record<string, string>;\n zoom?: number;\n}\n\nexport function marshalStoryData(story: Story): string {\n const data: StoryDataJSON = {};\n if (story.ifid) data.ifid = story.ifid;\n if (story.twine2.format) data.format = story.twine2.format;\n if (story.twine2.formatVersion) data['format-version'] = story.twine2.formatVersion;\n\n const options: string[] = [];\n for (const [opt, val] of story.twine2.options) {\n if (val) options.push(opt);\n }\n if (options.length > 0) data.options = options;\n\n if (story.twine2.start) data.start = story.twine2.start;\n if (story.twine2.tags) data.tags = story.twine2.tags;\n\n if (story.twine2.tagColors.size > 0) {\n data['tag-colors'] = Object.fromEntries(story.twine2.tagColors);\n }\n if (story.twine2.zoom !== 1) data.zoom = story.twine2.zoom;\n\n return JSON.stringify(data, null, '\\t');\n}\n\nexport function unmarshalStoryData(story: Story, json: string): string | null {\n let raw: unknown;\n try {\n raw = JSON.parse(json) as unknown;\n } catch (e) {\n return `Cannot unmarshal \"StoryData\"; ${e instanceof Error ? e.message : String(e)}`;\n }\n\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n return 'Cannot unmarshal \"StoryData\"; expected a JSON object';\n }\n const data = raw as StoryDataJSON;\n\n if (typeof data.ifid === 'string' && data.ifid) story.ifid = data.ifid.toUpperCase() as IFID;\n if (typeof data.format === 'string' && data.format) story.twine2.format = data.format;\n if (typeof data['format-version'] === 'string' && data['format-version'])\n story.twine2.formatVersion = data['format-version'];\n if (Array.isArray(data.options)) {\n for (const opt of data.options) {\n if (typeof opt === 'string') story.twine2.options.set(opt, true);\n }\n }\n if (typeof data.start === 'string' && data.start) story.twine2.start = data.start;\n if (typeof data.tags === 'string') story.twine2.tags = data.tags;\n if (typeof data['tag-colors'] === 'object' && data['tag-colors'] !== null && !Array.isArray(data['tag-colors'])) {\n for (const [tag, color] of Object.entries(data['tag-colors'])) {\n if (typeof color === 'string') story.twine2.tagColors.set(tag, color);\n }\n }\n if (typeof data.zoom === 'number' && data.zoom !== 0) story.twine2.zoom = data.zoom;\n\n return null;\n}\n\n// --- StorySettings (legacy) ---\n\nexport function unmarshalStorySettings(story: Story, text: string, diagnostics: Diagnostic[]): void {\n const obsolete: string[] = [];\n\n for (const rawLine of text.split('\\n')) {\n const line = rawLine.trim();\n if (line.length === 0) continue;\n\n const colonIdx = line.indexOf(':');\n if (colonIdx === -1) {\n diagnostics.push({\n level: 'warning',\n message: `Malformed \"StorySettings\" entry; skipping \"${line}\".`,\n });\n continue;\n }\n\n const key = line.slice(0, colonIdx).trim().toLowerCase();\n const val = line\n .slice(colonIdx + 1)\n .trim()\n .toLowerCase();\n\n switch (key) {\n case 'ifid': {\n const err = validateIFID(val);\n if (err === null) {\n story.legacyIFID = val.toUpperCase() as IFID;\n }\n obsolete.push('\"ifid\"');\n continue;\n }\n case 'zoom':\n obsolete.push('\"zoom\"');\n continue;\n }\n\n story.twine1.settings.set(key, val);\n }\n\n if (obsolete.length > 0) {\n const entries = obsolete.length === 1 ? 'entry' : 'entries';\n const pronoun = obsolete.length === 1 ? 'it' : 'them';\n diagnostics.push({\n level: 'warning',\n message:\n `Detected obsolete \"StorySettings\" ${entries}: ${obsolete.join(', ')}. ` +\n `Please remove ${pronoun} from the \"StorySettings\" special passage.`,\n });\n }\n}\n\n/**\n * Process a passage and add it to the story, handling special passages.\n * Creates new passage objects where text is modified rather than mutating the input.\n */\nexport function storyAdd(story: Story, p: Passage, diagnostics: Diagnostic[]): void {\n let processed = p;\n\n switch (p.name) {\n case 'StoryIncludes':\n diagnostics.push({\n level: 'warning',\n message:\n 'Ignoring \"StoryIncludes\" compiler special passage; twee-ts allows you to specify project files and/or directories to recursively search.',\n });\n break;\n\n case 'StoryData': {\n const err = unmarshalStoryData(story, p.text);\n if (err === null) {\n // Validate the IFID if present.\n if (story.ifid.length > 0) {\n const vErr = validateIFID(story.ifid);\n if (vErr !== null) {\n diagnostics.push({\n level: 'error',\n message: `Cannot validate IFID; ${vErr}.`,\n });\n }\n }\n // Rebuild passage contents to normalize.\n processed = { ...p, text: marshalStoryData(story) };\n } else {\n diagnostics.push({\n level: 'warning',\n message: `Cannot unmarshal \"StoryData\" compiler special passage; ${err}.`,\n });\n }\n break;\n }\n\n case 'StorySettings':\n unmarshalStorySettings(story, p.text, diagnostics);\n break;\n\n case 'StoryTitle': {\n const trimmed = p.text.trim();\n processed = { ...p, text: trimmed };\n story.name = trimmed;\n break;\n }\n }\n\n storyAppend(story, processed, diagnostics);\n}\n\n/** Get story passage count and word count stats. */\nexport function getStoryStats(\n story: Story,\n wordCountMethod: WordCountMethod = 'tweego',\n): { passages: number; storyPassages: number; words: number } {\n let storyPassages = 0;\n let words = 0;\n for (const p of story.passages) {\n if (isStoryPassage(p)) {\n storyPassages++;\n words += countWords(p, wordCountMethod);\n }\n }\n return { passages: story.passages.length, storyPassages, words };\n}\n\n/**\n * Builder that separates the mutable construction phase from the immutable consumption phase.\n * During construction, the internal `Story` is mutable via `add()` and direct access.\n * After `build()`, the story is returned as `ReadonlyStory`.\n */\nexport class StoryBuilder {\n /** The mutable story, accessible during construction for loader functions. */\n readonly story: Story;\n\n constructor() {\n this.story = createStory();\n }\n\n /** Add a passage, handling special passages (StoryData, StoryTitle, etc.). */\n add(passage: Passage, diagnostics: Diagnostic[]): void {\n storyAdd(this.story, passage, diagnostics);\n }\n\n /** Check if a passage name exists. */\n has(name: string): boolean {\n return storyHas(this.story, name);\n }\n\n /** Finalize and return the story as read-only. */\n build(): ReadonlyStory {\n return this.story;\n }\n}\n","/**\n * Extension → MIME type mapping.\n * Ported from util.go:mediaTypeFromExt().\n */\n\nimport { extname } from 'node:path';\n\nconst MEDIA_TYPE_MAP: Record<string, string> = {\n // Audio\n aac: 'audio/aac',\n flac: 'audio/flac',\n ogg: 'audio/ogg',\n wav: 'audio/wav',\n mp3: 'audio/mpeg',\n m4a: 'audio/mp4',\n oga: 'audio/ogg',\n opus: 'audio/ogg',\n wave: 'audio/wav',\n weba: 'audio/webm',\n\n // Fonts\n otf: 'font/otf',\n ttf: 'font/ttf',\n woff: 'font/woff',\n woff2: 'font/woff2',\n\n // Images\n gif: 'image/gif',\n jpeg: 'image/jpeg',\n jpg: 'image/jpeg',\n png: 'image/png',\n svg: 'image/svg+xml',\n tif: 'image/tiff',\n tiff: 'image/tiff',\n webp: 'image/webp',\n\n // Metadata\n vtt: 'text/vtt',\n\n // Video\n mp4: 'video/mp4',\n ogv: 'video/ogg',\n webm: 'video/webm',\n};\n\nexport function mediaTypeFromExt(ext: string): string {\n return MEDIA_TYPE_MAP[ext] ?? 'application/octet-stream';\n}\n\nexport function mediaTypeFromFilename(filename: string): string {\n return mediaTypeFromExt(normalizedFileExt(filename));\n}\n\nexport function normalizedFileExt(filename: string): string {\n const ext = extname(filename);\n if (!ext) return '';\n return ext.slice(1).toLowerCase();\n}\n\n/** Slugify a string for safe use as a DOM ID. */\nexport function slugify(original: string): string {\n return original.replace(/[\\x00-\\x20!-/:-@[-^`{-\\x9f]+/g, '_');\n}\n\n/** Check if a file has a known type that should be processed. */\nexport function isKnownFileType(filename: string): boolean {\n const ext = normalizedFileExt(filename);\n return KNOWN_EXTENSIONS.has(ext);\n}\n\nconst KNOWN_EXTENSIONS = new Set([\n 'tw',\n 'twee',\n 'tw2',\n 'twee2',\n 'htm',\n 'html',\n 'css',\n 'js',\n 'otf',\n 'ttf',\n 'woff',\n 'woff2',\n 'gif',\n 'jpeg',\n 'jpg',\n 'png',\n 'svg',\n 'tif',\n 'tiff',\n 'webp',\n 'aac',\n 'flac',\n 'm4a',\n 'mp3',\n 'oga',\n 'ogg',\n 'opus',\n 'wav',\n 'wave',\n 'weba',\n 'mp4',\n 'ogv',\n 'webm',\n 'vtt',\n]);\n\n/** Font format hint for @font-face. */\nexport function fontFormatHint(ext: string): string {\n switch (ext) {\n case 'ttf':\n return 'truetype';\n case 'otf':\n return 'opentype';\n default:\n return ext;\n }\n}\n","/**\n * File system utilities: path walking, file type detection, watch mode.\n * Ported from filesystem.go.\n */\nimport { readdirSync, statSync, watch as fsWatch } from 'node:fs';\nimport * as nodePath from 'node:path';\nimport { resolve, relative, join } from 'node:path';\nimport { isKnownFileType } from './media-types.js';\nimport type { Diagnostic } from './types.js';\n\n/**\n * Whether `filename` matches one of the `exclude` globs. The globs are matched\n * against the file's path relative to the working directory, the path\n * getFilenames reports; an absolute `filename` is made relative first. A leading\n * `./` in a glob is dropped. Matching is Node's `path.matchesGlob`.\n */\nexport function isExcluded(filename: string, exclude: readonly string[]): boolean {\n if (exclude.length === 0) return false;\n // Read from the namespace, not imported by name: path.matchesGlob arrived in\n // Node 22.5, and a named import would stop this module loading on 22.0-22.4.\n const { matchesGlob } = nodePath;\n if (typeof matchesGlob !== 'function') {\n throw new Error(`The exclude option needs Node.js 22.5 or newer (found ${process.version}).`);\n }\n const rel = relative(process.cwd(), resolve(filename)) || filename;\n return exclude.some((pattern) => matchesGlob(rel, pattern.replace(/^\\.\\//, '')));\n}\n\nexport interface FilenamesResult {\n readonly filenames: string[];\n /** One warning per path that could not be read. */\n readonly diagnostics: Diagnostic[];\n}\n\n/**\n * Recursively walk directories, collecting regular file paths.\n * Filters out the output file to prevent circular compilation, and the files\n * that match an `exclude` glob (see isExcluded).\n * Like Tweego, a path that cannot be read is reported as a warning and skipped.\n */\nexport function getFilenames(\n pathnames: string[],\n outFilename?: string,\n exclude: readonly string[] = [],\n): FilenamesResult {\n const filenames: string[] = [];\n const diagnostics: Diagnostic[] = [];\n const absOutFile = outFilename ? resolve(outFilename) : '';\n\n function warn(pathname: string, e: unknown): void {\n diagnostics.push({ level: 'warning', message: `path ${pathname}: ${e instanceof Error ? e.message : String(e)}` });\n }\n\n function walk(pathname: string): void {\n let stat;\n try {\n stat = statSync(pathname);\n } catch (e) {\n warn(pathname, e);\n return;\n }\n\n if (stat.isFile()) {\n const abs = resolve(pathname);\n if (abs === absOutFile) return;\n const rel = relative(process.cwd(), abs);\n if (isExcluded(rel || abs, exclude)) return;\n filenames.push(rel || abs);\n } else if (stat.isDirectory()) {\n let entries;\n try {\n entries = readdirSync(pathname);\n } catch (e) {\n warn(pathname, e);\n return;\n }\n for (const entry of entries) {\n walk(join(pathname, entry));\n }\n }\n }\n\n for (const pathname of pathnames) {\n walk(pathname);\n }\n\n return { filenames, diagnostics };\n}\n\nexport interface WatchHandle {\n close(): void;\n}\n\n/**\n * Watch paths for changes, calling the build callback on known file type changes.\n * A change to a file `ignore` returns true for (given the path relative to the\n * working directory) schedules no build.\n * Uses debouncing to avoid rapid rebuilds.\n */\nexport function watchFilesystem(\n pathnames: string[],\n outFilename: string,\n callback: (changedFiles?: ReadonlySet<string>) => void,\n ignore: (filename: string) => boolean = () => false,\n): WatchHandle {\n const absOutFile = resolve(outFilename);\n const watchers: ReturnType<typeof fsWatch>[] = [];\n let buildTimer: ReturnType<typeof setTimeout> | null = null;\n const BUILD_DEBOUNCE = 500;\n const pendingFiles = new Set<string>();\n\n function scheduleBuild(changedFile?: string): void {\n if (changedFile) pendingFiles.add(changedFile);\n if (buildTimer) clearTimeout(buildTimer);\n buildTimer = setTimeout(() => {\n buildTimer = null;\n const files = pendingFiles.size > 0 ? new Set(pendingFiles) : undefined;\n pendingFiles.clear();\n callback(files);\n }, BUILD_DEBOUNCE);\n }\n\n for (const pathname of pathnames) {\n try {\n const watcher = fsWatch(pathname, { recursive: true }, (_event, filename) => {\n if (!filename) return;\n const abs = resolve(pathname, filename);\n if (abs === absOutFile) return;\n if (isKnownFileType(filename)) {\n const rel = relative(process.cwd(), abs);\n if (!ignore(rel || abs)) scheduleBuild(rel || abs);\n }\n });\n watchers.push(watcher);\n } catch {\n // Ignore inaccessible paths\n }\n }\n\n // Build once initially (no changedFiles = full build).\n callback();\n\n return {\n close() {\n if (buildTimer) clearTimeout(buildTimer);\n for (const w of watchers) w.close();\n },\n };\n}\n","/**\n * Shared file I/O utilities.\n */\nimport { readFileSync } from 'node:fs';\nimport { parse as parsePath } from 'node:path';\n\n/** Read a file as UTF-8 with BOM stripping and line ending normalization. */\nexport function readUTF8(filename: string): string {\n let content = readFileSync(filename, 'utf-8');\n if (content.charCodeAt(0) === 0xfeff) content = content.slice(1);\n content = content.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n return content;\n}\n\n/** Read a file as base64. */\nexport function readBase64(filename: string): string {\n return readFileSync(filename).toString('base64');\n}\n\n/** Get the filename without extension, falling back to the full basename for dotfiles. */\nexport function baseNameWithoutExt(filename: string): string {\n const { name, ext } = parsePath(filename);\n return name || ext;\n}\n","/**\n * Story format discovery, loading, and SemVer matching.\n * Ported from formats.go + config.go.\n */\nimport { readdirSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport type { StoryFormatInfo, Twine2FormatJSON } from './types.js';\nimport { readUTF8 } from './util.js';\n\n/**\n * Attempt to fix non-strict JSON (trailing commas, single quotes, unquoted keys).\n */\nfunction relaxedJSONParse(json: string): unknown {\n // First try standard parse\n try {\n return JSON.parse(json);\n } catch {\n // fall through to relaxed parsing\n }\n\n let fixed = json;\n\n // Replace single-quoted string values with double-quoted\n // Match single-quoted strings: 'value' -> \"value\"\n fixed = fixed.replace(/'([^'\\\\]*(?:\\\\.[^'\\\\]*)*)'/g, '\"$1\"');\n\n // Add quotes around unquoted property names\n // Match word chars before a colon that aren't already quoted\n fixed = fixed.replace(/(?<=^|[{,]\\s*)([A-Za-z_$][A-Za-z0-9_$]*)\\s*:/gm, '\"$1\":');\n\n // Remove trailing commas before } or ]\n fixed = fixed.replace(/,\\s*([}\\]])/g, '$1');\n\n return JSON.parse(fixed);\n}\n\n/**\n * Parse the Twine 2 format.js JSON chunk.\n * Handles Harlowe's malformed JSON by stripping the \"setup\" function property.\n * Per spec, the name key is Optional.\n */\nexport function parseFormatJSON(source: string, formatId: string): Twine2FormatJSON | null {\n const first = source.indexOf('{');\n const last = source.lastIndexOf('}');\n if (first === -1 || last === -1) return null;\n\n let chunk = source.slice(first, last + 1);\n\n const parse = (json: string): Twine2FormatJSON | null => {\n const raw: unknown = relaxedJSONParse(json);\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) return null;\n const obj = raw as Record<string, unknown>;\n // version and source are required; name is optional per spec\n if (typeof obj.version !== 'string' || typeof obj.source !== 'string') return null;\n // Validate version is semver\n if (!parseSemver(obj.version)) return null;\n const name = typeof obj.name === 'string' ? obj.name : 'Untitled Story Format';\n const result: Twine2FormatJSON = {\n name,\n version: obj.version,\n source: obj.source,\n proofing: obj.proofing === true,\n };\n if (typeof obj.author === 'string') result.author = obj.author;\n if (typeof obj.description === 'string') result.description = obj.description;\n if (typeof obj.image === 'string') result.image = obj.image;\n if (typeof obj.url === 'string') result.url = obj.url;\n if (typeof obj.license === 'string') result.license = obj.license;\n return result;\n };\n\n try {\n return parse(chunk);\n } catch {\n // Harlowe workaround: strip the \"setup\" function property\n if (formatId.toLowerCase().startsWith('harlowe')) {\n const setupIdx = chunk.lastIndexOf(',\"setup\": function');\n if (setupIdx !== -1) {\n chunk = chunk.slice(0, setupIdx) + '}';\n try {\n return parse(chunk);\n } catch {\n // fall through\n }\n }\n }\n return null;\n }\n}\n\n/**\n * Discover all story formats in the given search directories.\n * Implements SemVer-based version pruning: within each (name, major) group,\n * only the highest minor.patch survives.\n */\nexport function discoverFormats(searchDirs: string[]): Map<string, StoryFormatInfo> {\n const formats = new Map<string, StoryFormatInfo>();\n const baseFilenames = ['format.js', 'header.html'];\n\n for (const searchDir of searchDirs) {\n try {\n const stat = statSync(searchDir);\n if (!stat.isDirectory()) continue;\n } catch {\n continue;\n }\n\n let entries;\n try {\n entries = readdirSync(searchDir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const formatDir = join(searchDir, entry);\n try {\n if (!statSync(formatDir).isDirectory()) continue;\n } catch {\n continue;\n }\n\n for (const baseFilename of baseFilenames) {\n const formatFilename = join(formatDir, baseFilename);\n try {\n const stat = statSync(formatFilename);\n if (!stat.isFile()) continue;\n } catch {\n continue;\n }\n\n const isTwine2 = baseFilename === 'format.js';\n const format: StoryFormatInfo = {\n id: entry,\n filename: formatFilename,\n isTwine2,\n name: '',\n version: '',\n proofing: false,\n };\n\n if (isTwine2) {\n try {\n const source = readUTF8(formatFilename);\n const data = parseFormatJSON(source, entry);\n if (!data) continue;\n format.name = data.name;\n format.version = data.version;\n format.proofing = data.proofing ?? false;\n if (data.author) format.author = data.author;\n if (data.description) format.description = data.description;\n if (data.image) format.image = data.image;\n if (data.url) format.url = data.url;\n if (data.license) format.license = data.license;\n } catch {\n continue;\n }\n } else {\n // Twine 1 format: use folder name as default name\n format.name = entry;\n }\n\n formats.set(entry, format);\n break; // Found format file for this directory\n }\n }\n }\n\n // SemVer pruning: for formats with the same name, within each major version\n // keep only the highest minor.patch. Also, same name+version from different\n // directories: keep the first one found.\n pruneFormats(formats);\n\n return formats;\n}\n\n/**\n * Prune formats by SemVer: within each (name, major) group,\n * keep only the highest version. First-found wins for same name+version.\n */\nfunction pruneFormats(formats: Map<string, StoryFormatInfo>): void {\n // Group by (name, major) -> best entry\n const bestByNameMajor = new Map<string, { id: string; version: [number, number, number] }>();\n // Track seen name+version combos (first wins)\n const seenNameVersion = new Set<string>();\n\n for (const [id, f] of formats) {\n if (!f.isTwine2 || !f.name || !f.version) continue;\n const v = parseSemver(f.version);\n if (!v) continue;\n\n const nameVersionKey = `${f.name}@${f.version}`;\n if (seenNameVersion.has(nameVersionKey)) {\n // Duplicate name+version: remove the later one\n formats.delete(id);\n continue;\n }\n seenNameVersion.add(nameVersionKey);\n\n const groupKey = `${f.name}@${v[0]}`;\n const existing = bestByNameMajor.get(groupKey);\n if (!existing || semverCompare(v, existing.version) > 0) {\n bestByNameMajor.set(groupKey, { id, version: v });\n }\n }\n\n // Remove all non-best entries within each group\n for (const [id, f] of [...formats]) {\n if (!f.isTwine2 || !f.name || !f.version) continue;\n const v = parseSemver(f.version);\n if (!v) continue;\n\n const groupKey = `${f.name}@${v[0]}`;\n const best = bestByNameMajor.get(groupKey);\n if (best && best.id !== id) {\n formats.delete(id);\n }\n }\n}\n\n/**\n * Get the default format search directories.\n */\nexport function getFormatSearchDirs(extraPaths: string[] = [], useTweegoPath = true): string[] {\n const subdirNames = ['storyformats', '.storyformats', 'story-formats', 'storyFormats', 'targets'];\n const basePaths = new Set<string>();\n\n // Home directory\n try {\n basePaths.add(homedir());\n } catch {\n // ignore\n }\n\n // Working directory\n basePaths.add(process.cwd());\n\n const dirs: string[] = [];\n for (const base of basePaths) {\n for (const sub of subdirNames) {\n const dir = join(base, sub);\n try {\n if (statSync(dir).isDirectory()) {\n dirs.push(dir);\n }\n } catch {\n // skip\n }\n }\n }\n\n // Extra user-provided paths\n dirs.push(...extraPaths);\n\n // TWEEGO_PATH environment variable\n if (useTweegoPath) {\n const tweegoPath = process.env.TWEEGO_PATH;\n if (tweegoPath) {\n dirs.push(...tweegoPath.split(process.platform === 'win32' ? ';' : ':'));\n }\n }\n\n return dirs;\n}\n\n/** Parse a simple semver string into [major, minor, patch]. */\nexport function parseSemver(v: string): [number, number, number] | null {\n const m = /^(\\d+)\\.(\\d+)\\.(\\d+)/.exec(v);\n if (!m) return null;\n return [Number(m[1]), Number(m[2]), Number(m[3])];\n}\n\nexport function semverCompare(a: [number, number, number], b: [number, number, number]): number {\n const [aMajor, aMinor, aPatch] = a;\n const [bMajor, bMinor, bPatch] = b;\n if (aMajor !== bMajor) return aMajor - bMajor;\n if (aMinor !== bMinor) return aMinor - bMinor;\n if (aPatch !== bPatch) return aPatch - bPatch;\n return 0;\n}\n\n/** Get format ID from Twine 2 name, picking the greatest version. */\nexport function getFormatIdByName(formats: Map<string, StoryFormatInfo>, name: string): string | undefined {\n let bestVersion: [number, number, number] | null = null;\n let bestId: string | undefined;\n\n for (const [id, f] of formats) {\n if (!f.isTwine2 || f.name !== name) continue;\n const v = parseSemver(f.version);\n if (!v) continue;\n if (!bestVersion || semverCompare(v, bestVersion) > 0) {\n bestVersion = v;\n bestId = id;\n }\n }\n\n return bestId;\n}\n\n/** Get format ID from Twine 2 name and version, using SemVer major matching. */\nexport function getFormatIdByNameAndVersion(\n formats: Map<string, StoryFormatInfo>,\n name: string,\n version: string,\n): string | undefined {\n const wanted = parseSemver(version);\n let bestVersion: [number, number, number] | null = null;\n let bestId: string | undefined;\n\n for (const [id, f] of formats) {\n if (!f.isTwine2 || f.name !== name) continue;\n const have = parseSemver(f.version);\n if (!have) continue;\n\n if (wanted === null || (have[0] === wanted[0] && semverCompare(have, wanted) >= 0)) {\n if (!bestVersion || semverCompare(have, bestVersion) > 0) {\n bestVersion = have;\n bestId = id;\n }\n }\n }\n\n return bestId;\n}\n\n/** Read the story format source (for Twine 2, extract the `source` property from JSON). */\nexport function readFormatSource(format: StoryFormatInfo): string {\n const source = readUTF8(format.filename);\n if (format.isTwine2) {\n const data = parseFormatJSON(source, format.id);\n if (!data) throw new Error(`Cannot parse format ${format.id} JSON`);\n return data.source;\n }\n return source;\n}\n\n/** Read a file as UTF-8 (re-exported for loader use). */\nexport { readUTF8 as readFileUTF8 } from './util.js';\n","/**\n * All public interfaces for twee-ts.\n */\n\n// --- Output modes ---\n\nexport type OutputMode = 'html' | 'twee3' | 'twee1' | 'twine2-archive' | 'twine1-archive' | 'json';\n\n// --- Word count ---\n\nexport type WordCountMethod = 'tweego' | 'whitespace';\n\n// --- Source input ---\n\nexport type InlineSource = { filename: string; content: string | Buffer };\nexport type SourceInput = string | InlineSource;\n\n// --- Compile options ---\n\nexport interface CompileOptions {\n /** Files, directories, or inline sources to compile. */\n sources: SourceInput[];\n /**\n * Glob patterns for files to leave out of `sources`, matched against each file's\n * path relative to the working directory (as `stats.files` lists it). Modules are not affected.\n */\n exclude?: string[];\n /** Output mode. Default: 'html'. */\n outputMode?: OutputMode;\n /** Story format directory ID (e.g. 'sugarcube-2'). */\n formatId?: string;\n /** Name of the starting passage. Default: 'Start'. */\n startPassage?: string;\n /** Extra directories to search for story formats. */\n formatPaths?: string[];\n /** Also search TWEEGO_PATH env for formats. Default: true. */\n useTweegoPath?: boolean;\n /** Module files to inject into <head>. */\n modules?: string[];\n /** Raw HTML file to append to <head>. */\n headFile?: string;\n /** Trim passage whitespace. Default: true. */\n trim?: boolean;\n /** Twee2 compatibility mode. Default: false. */\n twee2Compat?: boolean;\n /** Enable debug/test mode option. Default: false. */\n testMode?: boolean;\n /** URLs to SFA-compatible index.json files for remote format lookup. */\n formatIndices?: string[];\n /** Direct URLs to format.js files. */\n formatUrls?: string[];\n /** Disable remote format fetching. Default: false. */\n noRemote?: boolean;\n /** Map alias tags to canonical special tags (e.g. { library: 'script' }). */\n tagAliases?: Record<string, string>;\n /** Emit source file and line as data- attributes on passage elements. Default: false. */\n sourceInfo?: boolean;\n /** Word counting method. Default: 'tweego'. */\n wordCountMethod?: WordCountMethod;\n}\n\nexport interface CompileToFileOptions extends CompileOptions {\n /** Output file path. */\n outFile: string;\n}\n\nexport interface WatchOptions extends CompileToFileOptions {\n /** Called after each successful rebuild. */\n onBuild?: (result: CompileResult) => void;\n /** Called on build errors. */\n onError?: (error: Error) => void;\n}\n\n// --- Compile result ---\n\nexport type Diagnostic =\n | { level: 'warning'; message: string; file?: string; line?: number }\n | { level: 'error'; message: string; file?: string; line?: number; fatal?: boolean };\n\nexport interface CompileResult {\n /** The compiled output string (HTML, Twee, JSON, etc.). */\n output: string;\n /** The parsed story model (read-only after compilation). */\n story: ReadonlyStory;\n /** The format used for compilation (undefined for non-HTML modes). */\n format?: StoryFormatInfo;\n /** Collected diagnostics. */\n diagnostics: Diagnostic[];\n /** Compilation statistics. */\n stats: CompileStats;\n}\n\nexport interface CompileStats {\n passages: number;\n storyPassages: number;\n words: number;\n files: string[];\n}\n\n// --- Passage ---\n\nexport interface SourceLocation {\n readonly file: string;\n readonly line: number;\n}\n\nexport interface PassageMetadata {\n position?: string;\n size?: string;\n [key: string]: string | undefined;\n}\n\nexport interface Passage {\n name: string;\n tags: string[];\n text: string;\n metadata?: PassageMetadata;\n source?: SourceLocation;\n}\n\n// --- Branded types ---\n\nexport type IFID = string & { readonly __brand: 'IFID' };\n\n// --- Story ---\n\nexport interface Twine1Metadata {\n settings: Map<string, string>;\n}\n\nexport interface Twine2Metadata {\n format: string;\n formatVersion: string;\n options: Map<string, boolean>;\n start: string;\n tags: string;\n tagColors: Map<string, string>;\n zoom: number;\n}\n\nexport interface Story {\n name: string;\n ifid: IFID;\n passages: Passage[];\n legacyIFID: IFID;\n twine1: Twine1Metadata;\n twine2: Twine2Metadata;\n}\n\n// --- Readonly story (post-construction) ---\n\nexport type ReadonlyPassage = Readonly<Passage> & {\n readonly tags: readonly string[];\n};\n\nexport type ReadonlyStory = Readonly<Omit<Story, 'passages' | 'twine1' | 'twine2'>> & {\n readonly passages: readonly ReadonlyPassage[];\n readonly twine1: Readonly<Omit<Twine1Metadata, 'settings'>> & {\n readonly settings: ReadonlyMap<string, string>;\n };\n readonly twine2: Readonly<Omit<Twine2Metadata, 'options' | 'tagColors'>> & {\n readonly options: ReadonlyMap<string, boolean>;\n readonly tagColors: ReadonlyMap<string, string>;\n };\n};\n\n// --- Story format ---\n\nexport interface StoryFormatInfo {\n id: string;\n filename: string;\n isTwine2: boolean;\n name: string;\n version: string;\n proofing: boolean;\n author?: string;\n description?: string;\n image?: string;\n url?: string;\n license?: string;\n}\n\nexport interface Twine2FormatJSON {\n name: string;\n version: string;\n proofing?: boolean;\n source: string;\n author?: string;\n description?: string;\n image?: string;\n url?: string;\n license?: string;\n}\n\n// --- Lexer ---\n\nexport const ItemType = {\n Error: 0,\n EOF: 1,\n Header: 2,\n Name: 3,\n Tags: 4,\n Metadata: 5,\n Content: 6,\n} as const;\nexport type ItemType = (typeof ItemType)[keyof typeof ItemType];\n\nexport interface LexerItem {\n type: ItemType;\n line: number;\n pos: number;\n val: string;\n}\n\n// --- Story Format Archive (SFA) ---\n\nexport interface SFAIndexEntry {\n name: string;\n version: string;\n proofing: boolean;\n files: string[];\n checksums: Record<string, string>;\n}\n\nexport interface SFAIndex {\n twine1: SFAIndexEntry[];\n twine2: SFAIndexEntry[];\n}\n\n// --- Incremental compilation cache ---\n\nexport interface FileCacheEntry {\n readonly mtimeMs: number;\n readonly passages: readonly Passage[];\n readonly diagnostics: readonly Diagnostic[];\n}\n\n// --- Config file ---\n\nexport interface TweeTsConfig {\n sources?: string[];\n exclude?: string[];\n output?: string;\n outputMode?: OutputMode;\n formatId?: string;\n startPassage?: string;\n formatPaths?: string[];\n formatIndices?: string[];\n formatUrls?: string[];\n useTweegoPath?: boolean;\n modules?: string[];\n headFile?: string;\n trim?: boolean;\n twee2Compat?: boolean;\n testMode?: boolean;\n noRemote?: boolean;\n tagAliases?: Record<string, string>;\n sourceInfo?: boolean;\n wordCountMethod?: WordCountMethod;\n}\n","/**\n * Twee 3 state-machine lexer implemented as a synchronous generator.\n * Ported from tweelexer.go — Go channels become `yield`.\n */\nimport type { LexerItem } from './types.js';\nimport { ItemType } from './types.js';\n\nconst EOF = -1;\nconst HEADER_DELIM = '::';\nconst NEWLINE_HEADER_DELIM = '\\n::';\n\ntype StateFn = ((ctx: LexerContext) => StateFn | null) | null;\n\nclass LexerContext {\n readonly input: string;\n line = 1;\n start = 0;\n pos = 0;\n private items: LexerItem[] = [];\n\n constructor(input: string) {\n this.input = input;\n }\n\n next(): number {\n if (this.pos >= this.input.length) return EOF;\n const ch = this.input.charCodeAt(this.pos);\n this.pos++;\n if (ch === 0x0a) this.line++;\n return ch;\n }\n\n peek(): number {\n if (this.pos >= this.input.length) return EOF;\n return this.input.charCodeAt(this.pos);\n }\n\n backup(): void {\n if (this.pos > this.start) {\n this.pos--;\n if (this.input.charCodeAt(this.pos) === 0x0a) this.line--;\n } else {\n throw new Error('backup would leave pos < start');\n }\n }\n\n // Line-counting invariant: next() increments this.line for each newline during\n // character-by-character scanning. However, Content items are produced by jumping\n // this.pos directly (e.g. via indexOf) without calling next(), so those newlines\n // haven't been counted yet. emit() re-counts newlines in [start, pos) for Content\n // items to compensate. This is safe because this.start is reset to this.pos after\n // every emit(), so no range is ever counted twice.\n emit(type: ItemType): void {\n const val = this.input.slice(this.start, this.pos);\n this.items.push({ type, line: this.line, pos: this.start, val });\n if (type === ItemType.Content) {\n for (let i = this.start; i < this.pos; i++) {\n if (this.input.charCodeAt(i) === 0x0a) this.line++;\n }\n }\n this.start = this.pos;\n }\n\n ignore(): void {\n for (let i = this.start; i < this.pos; i++) {\n if (this.input.charCodeAt(i) === 0x0a) this.line++;\n }\n this.start = this.pos;\n }\n\n acceptRun(valid: string): void {\n let ch: number;\n for (ch = this.next(); ch !== EOF && valid.includes(String.fromCharCode(ch)); ch = this.next()) {\n // consume\n }\n if (ch !== EOF) this.backup();\n }\n\n errorf(message: string): null {\n this.items.push({\n type: ItemType.Error,\n line: this.line,\n pos: this.start,\n val: message,\n });\n return null;\n }\n\n /** Drain all pending items and return them. */\n drainItems(): LexerItem[] {\n const result = this.items;\n this.items = [];\n return result;\n }\n}\n\nfunction acceptQuoted(ctx: LexerContext, quote: number): string | null {\n for (;;) {\n const ch = ctx.next();\n switch (ch) {\n case 0x5c: {\n // backslash\n const r = ctx.next();\n if (r !== 0x0a && r !== EOF) break;\n // fall through\n }\n // falls through\n case 0x0a:\n case EOF:\n return 'unterminated quoted string';\n default:\n if (ch === quote) return null;\n break;\n }\n }\n}\n\n// --- State functions ---\n\nfunction lexProlog(ctx: LexerContext): StateFn {\n if (ctx.input.startsWith(HEADER_DELIM, ctx.pos)) {\n return lexHeaderDelim;\n }\n const i = ctx.input.indexOf(NEWLINE_HEADER_DELIM, ctx.pos);\n if (i > -1) {\n ctx.pos = i + 1; // skip to the newline, then past it\n ctx.ignore();\n return lexHeaderDelim;\n }\n ctx.emit(ItemType.EOF);\n return null;\n}\n\nfunction lexContent(ctx: LexerContext): StateFn {\n if (ctx.input.startsWith(HEADER_DELIM, ctx.pos)) {\n return lexHeaderDelim;\n }\n const i = ctx.input.indexOf(NEWLINE_HEADER_DELIM, ctx.pos);\n if (i > -1) {\n ctx.pos = i + 1;\n ctx.emit(ItemType.Content);\n return lexHeaderDelim;\n }\n ctx.pos = ctx.input.length;\n if (ctx.pos > ctx.start) {\n ctx.emit(ItemType.Content);\n }\n ctx.emit(ItemType.EOF);\n return null;\n}\n\nfunction lexHeaderDelim(ctx: LexerContext): StateFn {\n ctx.pos += HEADER_DELIM.length;\n ctx.emit(ItemType.Header);\n return lexName;\n}\n\nfunction lexName(ctx: LexerContext): StateFn {\n let r: number;\n outer: for (;;) {\n r = ctx.next();\n switch (r) {\n case 0x5c: {\n // backslash\n const next = ctx.next();\n if (next !== 0x0a && next !== EOF) break;\n // fall through to terminators\n r = next;\n }\n // falls through\n case 0x5b: // [\n case 0x5d: // ]\n case 0x7b: // {\n case 0x7d: // }\n case 0x0a: // \\n\n case EOF:\n if (r !== EOF) ctx.backup();\n break outer;\n }\n }\n // Always emit a name item, even if empty.\n ctx.emit(ItemType.Name);\n\n switch (r) {\n case 0x5b:\n return lexTags; // [\n case 0x5d:\n return ctx.errorf(`unexpected right square bracket ']'`);\n case 0x7b:\n return lexMetadata; // {\n case 0x7d:\n return ctx.errorf(`unexpected right curly brace '}'`);\n case 0x0a: // newline\n ctx.pos++;\n ctx.ignore();\n return lexContent;\n }\n ctx.emit(ItemType.EOF);\n return null;\n}\n\nfunction lexNextOptionalBlock(ctx: LexerContext): StateFn {\n // Consume whitespace.\n ctx.acceptRun(' \\t');\n ctx.ignore();\n\n const r = ctx.peek();\n switch (r) {\n case 0x5b:\n return lexTags; // [\n case 0x5d:\n return ctx.errorf(`unexpected right square bracket ']'`);\n case 0x7b:\n return lexMetadata; // {\n case 0x7d:\n return ctx.errorf(`unexpected right curly brace '}'`);\n case 0x0a: // newline\n ctx.pos++;\n ctx.ignore();\n return lexContent;\n case EOF:\n ctx.emit(ItemType.EOF);\n return null;\n }\n return ctx.errorf(`illegal character '${String.fromCharCode(r)}' amid the optional blocks`);\n}\n\nfunction lexTags(ctx: LexerContext): StateFn {\n // Consume the left delimiter '['.\n ctx.pos++;\n\n for (;;) {\n const r = ctx.next();\n switch (r) {\n case 0x5c: {\n // backslash\n const next = ctx.next();\n if (next !== 0x0a && next !== EOF) break;\n // fall through\n }\n // falls through\n case 0x0a:\n case EOF:\n if (r === 0x0a) ctx.backup();\n return ctx.errorf('unterminated tag block');\n case 0x5d: // ]\n if (ctx.pos > ctx.start) ctx.emit(ItemType.Tags);\n return lexNextOptionalBlock;\n case 0x5b: // [\n return ctx.errorf(`unexpected left square bracket '['`);\n case 0x7b: // {\n return ctx.errorf(`unexpected left curly brace '{'`);\n case 0x7d: // }\n return ctx.errorf(`unexpected right curly brace '}'`);\n }\n }\n}\n\nfunction lexMetadata(ctx: LexerContext): StateFn {\n // Consume the left delimiter '{'.\n ctx.pos++;\n\n let depth = 1;\n for (;;) {\n const r = ctx.next();\n switch (r) {\n case 0x22: {\n // double quote\n const err = acceptQuoted(ctx, 0x22);\n if (err) return ctx.errorf(err);\n break;\n }\n case 0x0a: // newline\n ctx.backup();\n // falls through\n case EOF:\n return ctx.errorf('unterminated metadata block');\n case 0x7b: // {\n depth++;\n break;\n case 0x7d: // }\n depth--;\n if (depth === 0) {\n if (ctx.pos > ctx.start) ctx.emit(ItemType.Metadata);\n return lexNextOptionalBlock;\n }\n break;\n }\n }\n}\n\n/**\n * Twee 3 lexer — yields LexerItem tokens from Twee source text.\n *\n * In the Go reference, this uses goroutines and channels.\n * Here we use a synchronous generator that accumulates items per state step.\n */\nexport function* tweeLexer(input: string): Generator<LexerItem, void, undefined> {\n const ctx = new LexerContext(input);\n let state: StateFn = lexProlog;\n while (state !== null) {\n state = state(ctx);\n const items = ctx.drainItems();\n for (const item of items) {\n yield item;\n }\n }\n // Drain any remaining items.\n const remaining = ctx.drainItems();\n for (const item of remaining) {\n yield item;\n }\n}\n\n/** Convenience class wrapper for the lexer generator. */\nexport class TweeLexer {\n private gen: Generator<LexerItem, void, undefined>;\n\n constructor(input: string) {\n this.gen = tweeLexer(input);\n }\n\n nextItem(): { item: LexerItem; done: boolean } {\n const result = this.gen.next();\n if (result.done) {\n return { item: { type: ItemType.EOF, line: 0, pos: 0, val: '' }, done: true };\n }\n return { item: result.value, done: false };\n }\n\n *[Symbol.iterator](): Generator<LexerItem, void, undefined> {\n yield* this.gen;\n }\n}\n","/**\n * Twee2 to Twee3 header syntax conversion.\n * Ported from twee2compat.go.\n */\n\nconst twee2DetectRe = /^:: *[^[]*?(?: *\\[.*?\\])? *<(.*?)> *$/m;\nconst twee2HeaderRe = /^(:: *[^[]*?)( *\\[.*?\\])?(?: *<(.*?)>)? *$/gm;\nconst twee2BadPosRe = /^(::.*?) *\\{\"position\":\" *\"\\}$/gm;\n\nfunction hasTwee2Syntax(s: string): boolean {\n return twee2DetectRe.test(s);\n}\n\n/**\n * Convert Twee2-style position blocks `<x,y>` to Twee3 metadata blocks `{\"position\":\"x,y\"}`.\n */\nexport function twee2ToV3(s: string): string {\n if (!hasTwee2Syntax(s)) return s;\n let result = s.replace(twee2HeaderRe, (_, p1: string, p2: string | undefined, p3: string | undefined) => {\n const tags = p2 ?? '';\n const pos = p3 ?? '';\n return `${p1}${tags} {\"position\":\"${pos}\"}`;\n });\n result = result.replace(twee2BadPosRe, '$1');\n return result;\n}\n","/**\n * Parse lexer items into Passage[].\n * Ported from storyload.go:loadTwee().\n */\nimport type { Passage, PassageMetadata, Diagnostic } from './types.js';\nimport { ItemType } from './types.js';\nimport { tweeLexer } from './lexer.js';\nimport { tweeUnescape } from './escape.js';\nimport { twee2ToV3 } from './twee2-compat.js';\n\nexport interface ParseOptions {\n /** Filename for diagnostics. */\n filename?: string;\n /** Trim whitespace from passage content. Default: true. */\n trim?: boolean;\n /** Enable Twee2 compatibility. Default: false. */\n twee2Compat?: boolean;\n}\n\nexport interface ParseResult {\n passages: Passage[];\n diagnostics: Diagnostic[];\n}\n\n/**\n * Parse Twee source text into passages.\n */\nexport function parseTwee(source: string, options: ParseOptions = {}): ParseResult {\n const { filename = '<inline>', trim = true, twee2Compat = false } = options;\n const diagnostics: Diagnostic[] = [];\n\n if (twee2Compat) {\n source = twee2ToV3(source);\n }\n\n const passages: Passage[] = [];\n let current: Passage | null = null;\n let pCount = 0;\n let lastType: ItemType = ItemType.EOF;\n\n for (const item of tweeLexer(source)) {\n switch (item.type) {\n case ItemType.Error:\n diagnostics.push({\n level: 'error',\n message: `line ${item.line}: Malformed twee source; ${item.val}.`,\n file: filename,\n line: item.line,\n });\n // Fatal: return what we have\n return { passages, diagnostics };\n\n case ItemType.EOF:\n if (pCount > 0 && current) {\n passages.push(current);\n }\n return { passages, diagnostics };\n\n case ItemType.Header:\n pCount++;\n if (pCount > 1 && current) {\n passages.push(current);\n }\n current = { name: '', tags: [], text: '', source: { file: filename, line: item.line } };\n break;\n\n case ItemType.Name: {\n if (!current) break;\n const name = tweeUnescape(item.val).trim();\n if (name.length === 0) {\n diagnostics.push({\n level: 'error',\n message: `line ${item.line}: Malformed twee source; passage with no name.`,\n file: filename,\n line: item.line,\n });\n return { passages, diagnostics };\n }\n current.name = name;\n break;\n }\n\n case ItemType.Tags: {\n if (!current) break;\n if (lastType !== ItemType.Name) {\n diagnostics.push({\n level: 'error',\n message: `line ${item.line}: Malformed twee source; optional tags block must immediately follow the passage name.`,\n file: filename,\n line: item.line,\n });\n return { passages, diagnostics };\n }\n // Strip the surrounding [ and ]\n const inner = item.val.slice(1, -1);\n current.tags = tweeUnescape(inner).split(/\\s+/).filter(Boolean);\n break;\n }\n\n case ItemType.Metadata: {\n if (!current) break;\n if (lastType !== ItemType.Name && lastType !== ItemType.Tags) {\n diagnostics.push({\n level: 'error',\n message: `line ${item.line}: Malformed twee source; optional metadata block must immediately follow the passage name or tags block.`,\n file: filename,\n line: item.line,\n });\n return { passages, diagnostics };\n }\n try {\n const raw: unknown = JSON.parse(item.val);\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n throw new Error('expected a JSON object');\n }\n const parsed = raw as Record<string, unknown>;\n const meta: PassageMetadata = {};\n for (const [key, value] of Object.entries(parsed)) {\n if (typeof value === 'string') {\n meta[key] = value;\n }\n }\n current.metadata = meta;\n } catch (e) {\n diagnostics.push({\n level: 'warning',\n message: `load ${filename}: line ${item.line}: Malformed twee source; could not decode metadata (reason: ${e instanceof Error ? e.message : String(e)}).`,\n file: filename,\n line: item.line,\n });\n }\n break;\n }\n\n case ItemType.Content: {\n if (!current) break;\n if (trim) {\n current.text = item.val.trim();\n } else {\n // Per spec: trailing blank lines MUST be stripped regardless of trim option\n current.text = item.val.replace(/\\n\\s*$/, '');\n }\n break;\n }\n\n default: {\n const _exhaustive: never = item.type;\n diagnostics.push({\n level: 'error',\n message: `line ${item.line}: Unhandled lexer item type: ${_exhaustive}.`,\n file: filename,\n line: item.line,\n });\n return { passages, diagnostics };\n }\n }\n\n lastType = item.type;\n }\n\n // Shouldn't reach here (EOF is always emitted), but just in case:\n if (pCount > 0 && current) {\n passages.push(current);\n }\n return { passages, diagnostics };\n}\n","// Adapted from https://github.com/mathiasbynens/he/blob/36afe179392226cf1b6ccdb16ebbb7a5a844d93a/src/he.js#L106-L134\n/**\n * C1 Unicode control character reference replacements (code points 128–159).\n * Index i gives the replacement for code point 128+i; 0 means \"no replacement\".\n */\nconst c1 = [\n 8364, 0, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249, 338, 0,\n 381, 0, 0, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250,\n 339, 0, 382, 376,\n];\n/**\n * True for NUL, UTF-16 surrogates, and values past U+10FFFF.\n * @param codePoint Unicode code point to check.\n */\nfunction isInvalidCodePoint(codePoint) {\n return (codePoint === 0 ||\n (codePoint >= 0xd8_00 && codePoint <= 0xdf_ff) ||\n codePoint > 0x10_ff_ff);\n}\n/**\n * Replace the given code point with U+FFFD if it is NUL (0), a surrogate, or\n * outside the valid Unicode range. Code points in the C1 controls range\n * (128–159) are remapped to their Windows-1252 equivalents, following the\n * HTML spec. All other code points are returned unchanged.\n * @param codePoint Unicode code point to convert.\n */\nexport function replaceCodePoint(codePoint) {\n if (isInvalidCodePoint(codePoint)) {\n return 0xff_fd;\n }\n if (codePoint >= 128 && codePoint <= 159) {\n return c1[codePoint - 128] || codePoint;\n }\n return codePoint;\n}\n/**\n * XML numeric character references are the referenced Unicode code point.\n * Invalid values still become U+FFFD; the HTML Windows-1252 C1 remap is not\n * applied.\n * @see https://www.w3.org/TR/xml/#NT-CharRef\n * @param codePoint Unicode code point to convert.\n */\nexport function replaceCodePointXML(codePoint) {\n return isInvalidCodePoint(codePoint) ? 0xff_fd : codePoint;\n}\n/**\n * Convert the code point of a decoded numeric entity to a string, replacing\n * invalid values.\n *\n * Fast path for plain BMP code points: [1..0x7F] and [0xA0..0xD7FF] pass\n * `replaceCodePoint` unchanged (no NUL, C1 remap, surrogate, or out-of-range\n * handling) and fit a single charCode. 0xd760 = 0xD800 (the first surrogate)\n * - 0xA0.\n * @param codePoint Unicode code point to convert.\n */\nexport function codePointToString(codePoint) {\n return (codePoint - 1) >>> 0 < 0x7f || (codePoint - 0xa0) >>> 0 < 0xd7_60\n ? String.fromCharCode(codePoint)\n : String.fromCodePoint(replaceCodePoint(codePoint));\n}\n//# sourceMappingURL=decode-codepoint.js.map","/*\n * Inverse of the encoder's SAFE alphabet (0x21..0x7E minus 0x22, 0x24, 0x5C),\n * precomputed once at module load. Entries for excluded chars stay 0 but\n * are never read.\n */\nconst BASE91_INVERSE = /* #__PURE__ */ (() => {\n const table = new Uint8Array(127);\n let code = 0;\n for (let char = 0x21; char <= 0x7e; char++) {\n if (char !== 0x22 && char !== 0x24 && char !== 0x5c) {\n table[char] = code++;\n }\n }\n return table;\n})();\n/**\n * Decode a dictionary-encoded trie string back into its Uint16Array.\n *\n * Stream layout (consumed in this order):\n * 1. dict1 atoms — `dict1AtomCount` uint16 values, delta+RLE encoded.\n * 2. dict2 atoms — `atomCount - dict1AtomCount` values, delta+RLE.\n * 3. dict2 ngrams — `ngramCount - (dictSize - dict1AtomCount)` entries,\n * each a pair of slot codes that resolve to earlier slots.\n * 4. dict1 ngrams — `dictSize - dict1AtomCount` entries, same shape.\n * 5. data — slot codes, each expanding to one or more uint16 values.\n *\n * Codes use a 91-char base (printable ASCII minus `\"`, `$`, `\\`):\n * - char1 < dictSize → 1-char code, slot = char1\n * - char1 ≥ dictSize → 2-char code, slot = dictSize + (char1 - dictSize)*91 + char2\n *\n * Slot index → token kind:\n * [0, A) dict1 atoms (1-char codes)\n * [A, dictSize) dict1 ngrams (1-char codes)\n * [dictSize, dictSize+D) dict2 atoms (2-char codes)\n * [dictSize+D, end) dict2 ngrams (2-char codes)\n *\n * Both atom dicts decode before any ngram, and dict2 ngrams decode before\n * dict1 ngrams. So every ngram entry references slots whose contents are\n * already filled — no forward references to handle.\n *\n * This runs on library import. Flat typed arrays store each slot as either\n * a plain value (`single`, covering every atom) or a range in a shared\n * `pool` (ngrams).\n * @param input Packed trie string.\n * @param resultLength Expected number of uint16 values in the output.\n * @param atomCount Total number of distinct uint16 values in the trie.\n * @param dict1AtomCount Atoms in the 1-char range (`A` above).\n * @param ngramCount Total number of ngram entries (dict1 + dict2).\n * @param dictSize Number of 1-char code slots; the rest of `BASE - dictSize`\n * first-byte values are 2-char codes.\n */\nexport function decodeTrieDict(input, resultLength, atomCount, dict1AtomCount, ngramCount, dictSize) {\n const base = 91;\n const inputLength = input.length;\n // For 2-char codes, slot = char1 * base - twoCharBias + char2.\n const twoCharBias = dictSize * (base - 1);\n let pos = 0;\n /** Read one slot code at `pos` and return its slot index, advancing pos. */\n const readSlotCode = () => {\n const c1 = BASE91_INVERSE[input.charCodeAt(pos++)];\n return c1 < dictSize\n ? c1\n : c1 * base - twoCharBias + BASE91_INVERSE[input.charCodeAt(pos++)];\n };\n const dict2AtomCount = atomCount - dict1AtomCount;\n const slotCount = atomCount + ngramCount;\n /*\n * Per-slot contents: atoms (always a single value) live directly in\n * `single`; ngram slots hold -1 there and expand to\n * `pool[start[slot] .. start[slot] + length[slot])`.\n */\n const single = new Int32Array(slotCount);\n single.fill(-1, dict1AtomCount, dictSize);\n single.fill(-1, dictSize + dict2AtomCount, slotCount);\n const start = new Int32Array(slotCount);\n const length = new Int32Array(slotCount);\n /**\n * Decode `count` ascending uint16 values from a delta+RLE stream into\n * `single[off..off+count)`.\n *\n * code < 89 → delta = code\n * code == 89 → run-length: next char encodes runLength-2; emit `runLength` consecutive +1 values\n * code == 90, next < 90 → escape: delta = 89 + next * BASE + after-next\n * code == 90, next == 90 → double-escape: extra char for very large deltas\n * @param count\n * @param off\n */\n function decodeDelta(count, off) {\n let previous = 0;\n let slot = off;\n const end = off + count;\n while (slot < end) {\n const code = BASE91_INVERSE[input.charCodeAt(pos++)];\n if (code < 89) {\n previous += code;\n single[slot++] = previous;\n }\n else if (code === 89) {\n let runLength = BASE91_INVERSE[input.charCodeAt(pos++)] + 2;\n while (runLength--)\n single[slot++] = ++previous;\n }\n else {\n const next = BASE91_INVERSE[input.charCodeAt(pos++)];\n previous +=\n 89 +\n // eslint-disable-next-line unicorn/prefer-minimal-ternary -- branches read a different number of side-effecting input bytes\n (next < 90\n ? next * base + BASE91_INVERSE[input.charCodeAt(pos++)]\n : BASE91_INVERSE[input.charCodeAt(pos++)] * 8281 +\n BASE91_INVERSE[input.charCodeAt(pos++)] * base +\n BASE91_INVERSE[input.charCodeAt(pos++)]);\n single[slot++] = previous;\n }\n }\n }\n // Streams 1 & 2: atoms decoded into their slot ranges.\n decodeDelta(dict1AtomCount, 0);\n decodeDelta(dict2AtomCount, dictSize);\n /*\n * Streams 3 & 4 are read in two passes: first collect every ngram's two\n * references and derive its expanded length (each ref resolves to an earlier\n * slot, so lengths are already known), which sizes the shared pool.\n * Pool ranges are handed out in decode order, so the second pass fills\n * the pool contiguously with a single write cursor.\n */\n const references = new Int32Array(ngramCount * 2);\n let poolSize = 0;\n let ngramIndex = 0;\n /**\n * Read `count` ngram entries (each = 2 slot-code references) for the slots\n * starting at `startSlot`, recording references and assigning pool ranges.\n * @param count\n * @param startSlot\n */\n function readNgramReferences(count, startSlot) {\n for (let index = 0; index < count; index++) {\n const slot = startSlot + index;\n const a = readSlotCode();\n const b = readSlotCode();\n references[ngramIndex * 2] = a;\n references[ngramIndex * 2 + 1] = b;\n ngramIndex += 1;\n start[slot] = poolSize;\n const entryLength = (single[a] < 0 ? length[a] : 1) +\n (single[b] < 0 ? length[b] : 1);\n length[slot] = entryLength;\n poolSize += entryLength;\n }\n }\n readNgramReferences(ngramCount - dictSize + dict1AtomCount, dictSize + dict2AtomCount);\n readNgramReferences(dictSize - dict1AtomCount, dict1AtomCount);\n // Second pass: concatenate each ngram's two halves into the pool.\n const pool = new Uint16Array(poolSize);\n let write = 0;\n for (let index = 0; index < ngramIndex; index++) {\n for (let half = 0; half < 2; half++) {\n const source = references[index * 2 + half];\n const value = single[source];\n if (value < 0) {\n let read = start[source];\n const readEnd = read + length[source];\n while (read < readEnd)\n pool[write++] = pool[read++];\n }\n else {\n pool[write++] = value;\n }\n }\n }\n // Stream 5: data. Each code expands to its slot's stored values.\n const out = new Uint16Array(resultLength);\n let outIndex = 0;\n while (pos < inputLength) {\n let slot = BASE91_INVERSE[input.charCodeAt(pos++)];\n if (slot >= dictSize) {\n slot =\n slot * base -\n twoCharBias +\n BASE91_INVERSE[input.charCodeAt(pos++)];\n }\n const value = single[slot];\n if (value < 0) {\n let read = start[slot];\n const readEnd = read + length[slot];\n while (read < readEnd)\n out[outIndex++] = pool[read++];\n }\n else {\n out[outIndex++] = value;\n }\n }\n return out;\n}\n//# sourceMappingURL=decode-shared.js.map","// Generated using scripts/write-decode-map.ts\nimport { decodeTrieDict } from \"../internal/decode-shared.js\";\n/** Packed HTML decode trie data. */\nexport const htmlDecodeTree = /* #__PURE__ */ decodeTrieDict(\"!}.&u%}'&}*'~!6*)%&,~!J~!J~%L~y<~!R,~~%Lu~~#GD~~#|)1#%}^%}2%+#.##%##%}&%##%'#%##&%#%#'%#&#%#&#'#%%#&#%##%#)%''%&%#%#'%#%%#%%}%%%#%#&(23#%%#&-%0%('1#(##%#'##+%'*.:1}#%#6-+(%'%%#%%%}#L'2351&('%}&/N'(0(/*-%(%%}#'+&T%7.2}#&%&#%#36/5##%&%%#&#%%#))2%%##%&&'0~!#*+&'%1~!%).'3q?&%'1~!.##%6(~!+%%%(Gw'rT~!E#<nA%#jZ~!H%(~!42##~!*31&~!G%U~#)5~#`3~!J~!Z~%]~%Y~%C~!q~!u~#kz~%#~!6'~!D~!U~!?~#T~!c%~!G#'~%7|~!G~!J~!G&~#pb~(Df}#%}*&}#%##%##%##&#-}&'#'&%#.++}%mI,#,@&(}*%}*'%&##&#%##%}&0}#.},U},%}+%}&%}#%##&}B%(}(%}+%)})%##%#&}&%##%&}<%}>%#%&}*%}(%}9%}/%})%}*%}*%}?&}&%}3%}&*#%})%#%#)}#&#-#+*%E%%'%'#%}#*V##&##I}#&&##%&%#&&Qf%%))w/0+&%#(#.%-''''++++7}>%4'',##1,#%#&%##&#'##&#*#9)%&%}#*}%,#+P(%A&%#'&##wSD',9E00#y#@}(+}&%&>~!#~!X}#*}(&&}(&}(,%}%&#+&}#&}I%#%}%)#(},'%#*}4%%#%}(''}#/##(##),%-##%%)#&}(.}&%#&}%%}*&#%},&&}&%}#%*'#%})%}D&}&%}-&}6&#&}-,%}#%})-(~+`~,=?~I9'9%~!,#%})%})%}@%}?%}(~!?~#<~#pP~#BG~#=1#%K+~#?#~%;)~#A~#mF1~#A'~'X%'~#lR~#N~'N~#r~#m#-~#i'?%#'%~#B%##%,%#~#_%#0%~#]732~,w~2+#:&#%&'0%&>%}#>##F+)#%&&#(+_}4&}-%}(&}@&}O7Fdf0@+/v4}&WU##&/0#&'('B#%}.%}'+#%}#%%&#&%#%##+#&#)#6#'#.},%}c%},%#%##%&#&%#&~#>'*-.%##%##%}#%%}%'~#)D1}#%*&~#_%%'(~#S2%'.}#~#=##*'*-%}&'%'##&&~'E%.#&~#M4}%%##&'%#~#O1##%&#'+~#<B%##%%'%+~#;#@%}#&%#&&%#(~#H1}'%'##&&~#?A}&'~#D#%32}'&&&&~#[}'(#%}'~#;C})&}%%#%~#=&%,3}%'(#%%~#^'#&&)#%'~#Y%-~#d-%'~#^%%&#&&&}#~#b~2t*&'~&(~&@~0%~e~3}%*''0})&}+~!9##-}#%-hD*)1fC#%/&/fB#40~!+#)*4~!+~!K'&:~!/*7~!.#~!H~!L':~%x&~!H#~!*~%1~!I#~!+A~#p'~!F~~#-#~,,(~.Z~!V~%;'B'mq-W~!N~%I%#&&#&}#%},%%}'%}+X#%}#&}(%}'%}<%}#%}%%'}'%}:~![)9@~%>~#UA%-%##&~!C%~!-.9:~!1~!-^2/:a~!y,D*J#-5)/4~%23,~#G~!L1~!0X3`~!2+~!!0-~&E~!W~!o,>Y&]~%cZx_&~#O*9#A#'#+I'%#)~!0B*-5A+-((F&*M#)(-7-5+'-3a5Vi~!Y~!?+[)%3),ERHm~!+:D,VG.+)?fB%%*(%)'(#&80%1'8`K8?`+'Z#&O&'H5#*9)A%%5&3))0%39+.*7#()&&*=4@**L)<'_&*+..;(#*+)./&0#3)%')-8(4ixD(&.}%,('aI:,)%,k2231T)I'#/-W7,/'Q#.'Y24+h')37</31&83##&0#),H(?'&?/1##%#&&#%''-%&&&#(&''&#.-'%#%%(,')*'&#&#'##%(%(#%('#&##%%%%('%#%#%%#%#&%##h>w+v<ayvyvcg.uuhKr}g/v|g>u9i[~>g5uI~=RvdwEg;v/g;uk!!TTSx]@RT!U!#!@VBRUU!'UTe-d0c`e&gSdicedFcrdTaqb.kYcAohdYd@a3e+d}dMdtd.aJ#bqcK`dle/e.e'dwdPdodddjbEb}ogd^ofdpduc6j?l%d{drdqc)d7bacOdQ%T#Y)X.sR[yH>6Vyv3[xwLu>vo'!*.[yBacahoj>6Rew3[xqdZa#!a&#^(X-[yG>6Vyu3[xvg3sEr|g.u/Ri9db0T#^(Xa)!-[y;>6Vylg4wKs{JwNZt3@3r=c4Z([xlg;wKt!cpq's@v7A'*a(a+!-a#[y<3Dt?3Dt'>6Vym3[xmg9rxsNJwLZt4~?r?db1T#`-!(Xa,!0[yS>6Vz%NuQs.g4wKtnJwNZtS@3r>c4Z([y%g;wKtrdga8!a(!#&T*Y-Xa#!a0<or[yc3Dtq>6Vz43[y3JwNZtf@3s!Ju}!%Dti:pm3c_%X#tjB5pkd6q!r]u?voC'*-a.a2!0a&a+[yI3DtI3Ds~3DtH>6Vyw3[xx;:s#~<5pKJwNZtE@3r~d`a)!a2T#a.(!+U.X1[yT3Dt`3Dtv>6Vz&3[y&g9rxwzcxstPu.<rAJwLZtT~?r@dZa%!a.&^*Za(/Reu[ya>6Vz23[y1g3sEr}wkg{NuQRg{ci(U#5@b`~,cg#U(2WnH5wugcRh7dX#T(Y,a'Ta!!a,[yZ<]mj>6Vz,3[y+Pv#5ReZKu+=,%!H}7ABwkaS?Rh:BcW(X#<]mrj:ubv/ARekdg%!(!a.*Ta(Y.X1!#sP>Rl*Dt6[y>>6Vyo3Wf*jOvuumvuRgRJuq*!:9<B@bX~3jVv&v@s@5Re[d/rQt{uAvo&a&a*)a2!,0Wf!3Dt0=Bs'>6Re}3[xy~<5s%JwJZt1~Gs)c;&!#2sJkNuXvzq7rxu,Re8dka4!a8(aEZ+a@Y.X1Xa)[yd=Bs(3DtP>6Vz53[y4cX#X&Re:avRe9~<5s&JwJZtQ~Gs*i^rzvdRg+Jv{%!2sbB@bX}kdga,!Za?&^*T1/!a'Dt+[y6>6Vyf3Wf%g/u;s4hGu6?Rh-JvZ,!c%#&RoX54Rivj7uyvf8RgTKvZB%*!2sGh<vu5Rgq<=C::9bb~#dZ#T&Ta6Y.X*Dt>[y93Wf)coZ(T,6VyifluvRgC@95@B@bX~/hFu34cC#T,k/unq8w8Q5RkUklwQuzunq8w8Q5Rk8d/rJu?v8w9)-&!a0a;a&aIWejg3sEr/h1s<DtDJvyZqY5aws3Jvy!&Wei~Hr1:au5@Bag>23E~5c:Z&bX};kKv?w&unuVu5Rjc;>bs)#~@:Rh.=ay<a]C;b`}Vd6s/t{uAvoaxa()!a,a7%-a#a2Dt,[yF2Wo[>6Vyt3[xuNuPRi&NuPwpi#RoWh?vf8Ri%Jv]!%Ri:KvxD!.'2WeAjZu`q9rxu,Re7woeAg-unLq(qA_/*2Wg_g3u5q^9:4E}/jTrxrzv=Wkkd~0UX#^^Xa-a1a5T&a=U1a'*aEa]!a*aPaA-adok[y54Rn>;:p3~Dp5g9rpsFNvZqjg3uJp4~<5p0Pw;5qlJwNZt*@3p1Pw:5p/Ou!5p2JvG'!6Vye=<qnJvh_[xhg3v,Rh3kOwOw-sDuev/Re^dha[a%!%!a+#Ta7)-5TaCaO!aka!a)sf[yb2>Rl!9ARiq5E}Qg=ucRkBE|oJrJ_@Wk~@Wk{JrJ_@Wk|@WkyJrJ_@Wk}@WkzJvO_[y2g-vMRmiKuYC!)&>Ri;>Ri<@3RkNc](X#@9Rk=g5vuRmhKvDB!+'=]meg3u4Rmgd)#Y'Vz3CARmfd`a+!%T'!+#Ta1Ta6TaM-sTDt9[yA9sYd'%Y#s[[xpj:ueunaXRgEjRq,v-vuqdd2'`#6Rev<32@5>:2<E}5xIo9a*X#Y(;5RePJvD_g>vyRgNj8w)v8<wggs:RgXiZt|vjx,hSq3ah!-(~@:Ro/Ou!5RhWj^v(pyw8unRhUdx-UY#^Ua.a3a70!)%UX1TaDa)'omRiRRhE[y:3Dsz=Br,>6Vyj3[xkg6ruwjcqsrPw;5r*Ku]D'Zt-@3r(~?r.i[vwv]dU1a--U#`a4(g/vsRhPOu!5RhLj:rmu9Wo!~@:wdh@g/vsRiTjXuvvNr}:RhBj^v(pyw8unRn]dz1UYa'a+^Y(!aETZalaRY.Ta?a4[yDJw1!#qLsW>6Vyrfzq-pLflpwRe|Js>%!Dt@3Dt&Jvy_[xs~HrnjMuwpsw'RecKu+D#'!t<~Grl~?rjg5u-x,gwp{ah!-(~@:Rg~Ou!5Rh'jXuvvNr}:Rh#cW#X/c;&!#2sLi[v7u7RgpJv)(!iLrxu,Re6j7v@s@5Se[e7d`aW!Za(a`T.a#!a3!&aDa-!9)Dt_=6s+3[x~~DR|h~DS6avhGun5RkZj3w)v-]mkKunB!&*]kb97R|i<ARk<c:Z(6Vy}Juh'!wziMRoS:F|vkLuauJv5vtvQRh1d='T+Y#VyO~DR|jcF#T'7R|g97R|kJv3'!ay<Rj,Jvh&!:ReXcsa6*a+#a#_aIRf9aLRf?c,Z&Rf5Rf7c.Z&Rf;Rf>cQ#%T'p-Rf8Rf=ct#%'(*!,p,Rf4p+Rf6Rf:Rf<d~'Ua%U*^UYa(!a,-!#a4YaTalaEX0a8a<Weo3Dt/3Dsx=Br93Wen~Dr;~<5p<JwNZt2@3p=Pw:5p;Ou!5r3c7&!#:p>3Ds}KvGB)_6Vyk2sM=<r7x'eovA(!hFu1ARf}cV#X&@r5j6rvwQa^Rf3c=Za'wkghJv__g;unRggA53B9=b^}%j6uduo5Jq;!(hIv%2Re`Ou4ARe_e%a#^^^Xa&!a*a2!&a6YaP!*ad!#a:aE/5Rn?[y@>6Vyp;:pE~DrY~<5pBJwNZt8@3pCh=rt3rWPw:5pAJup_[xoNuPpF9c!#'45pD5ARn)d8#X'X*3@rU72s]h>v<<sSjJpqvewOJq/(!hNw'5ReBk0s2u3w/w'5ReE5@Jq.!a+JQ!&WeU23d(#Y&RjG5]jBk!u7w&u0udARjEe#+^^^Ub#!a2/a`Z(agT1!a-a;|@TaG!aS[yV=Re~fow'RguNuPRe?bz#'>RoUWeL>:Cbb|?JwPZtVg6ruRmzJvD'!6Vz(g/vmRh~Jvy_[y(g9voRgyx*cy(#2>Ri2B9b]~9kIw9u7rluJu3Rg]dI#a%UY'@=p%CAx.gQZ&RhwwygtRm{x5g_Z'+ABqR9Woa=Bp&dV#^*Xa'!&@o{g4v]Rk;Jv{!%Rk[wkkiA5RkiwwfUB=x,fUuqC&*!>RfTg8v0RfV~ARfSd;rJsAuAv9wR'ae+/aO!a@aza/a#[yQ@Wg!2Wemg3sEr0JvB_g>uvReWg2v+Re=KupB_+[y!2AbY~-~Hr2AJwD!(h<~El>h<~El?Kun@+_:9b`}Kg-v/Ri3g;vtwyk_9]k_d=&T#*U.6qh@Ab`|K9:H|CJv[!&3Dtex'fDwC%!Rf[9WlMd[(^X,!a%Z06Vz!@WgBg=v~Rgvg,QRe@awd,#Y+jTv|Q~EfWj]uNr|~FRfXdy#Y&^Ua%!aO.!(a)Ua;=!a@aKap!a-,a!Ta]a[rSa]p?[y82sK=Bq~;:p:~<5p8Pw:5p7d'#Y'Wf(;RnRi[u4w&RgJJvG'!6Vyh=<r#ijuuv/sIKuYD'ZtG@3p9~Gr&d2#`(g<vtRgFj`u5w&rqpxRf2CJuY!+:wfnTOu!5Rg}jNs1ucv&RfwJvA!&3@q|BDcC#T,k/unq8w8Q5RkTklwQuzunq8w8Q5Rk9dga#!a'!a=#a0!:+Tb*b@aO.a4!aba8aFJv^}?!VyR~Dr<g;u%Rn.~<5p[x'e`wNZtR@3p]Pw:5pZhNvjBp.woe_g5u-r4JwF!%DtO3:ooc7&!#:p^3DtpLuGw(!+%)Dtk6Vz#2sd=<r8d'#Y([y#<x3gJt`w@!)%}MRiowzikRij=]ilxAf3,U(#B2Rf#g0v-Rm[ck{`U#]giKv3>)!&6Ri154s,KuGB_%@r68r:dJ|t`#X(9<E|u2@H|rx3gJu?w'!+'1Nu7Reg4=H~+9<wxgY95Rm]xLggZ-`(X}U2:Ri4h<uOawRmsJv__5@bb{jbV~3dka#a'a]!,#a+U=a>b6a3b%!/aKa/)!arwve^VyJ;:pR~DpTg3uJpS~<5pOPw;5qmPw:5pNOu!5pQJvG'!6Vyx=<qoJvA!{~Jup!%@qk7Rn/KvyD!}''[xz;>wkh'?Rh,x8gyt`w5D!&),(SgyccRgztJ@3pPB5p#d'(Y#<]mmifubw&RgoJvE&!82s^JvF&!8Rf,ADb]~;x=h'rNu]vK!,%'*0RnORh)4Rh*AqQg-vaRnNg;wHwkh'ba~4cE#Ta*x3gctyw@'!+%RnFRnD<4Rn@hFvK5RnCxWg[#`&a0Ua()`1Rm75Rg[c]%X#qi8Rg^NvdRj>BwzgZauwji7Rm6A4wgg]d1#&(*,.0a#Rm;Rm<Rm=Rm>Rm?Rm@RmARmBe%#^^^Xaea?aC/b+(,!a+a#!a/!>a&Ta<aKbD!2wphBRnk[yPw}hE|.=Br-3Dtm>6Vy~g6urRf.x,hPrNav!%'RnqRo%Ro#Nu;q[Pw;5r+JwNZtM@3r)d'#Y'Weh;xChL#`&RnmRnoKu}>%(!Rne~Bs-;2wjcussJv+'!aYSO}6@B<5?ba~8LrNvj!.%*ROwungw~ng~:9;Ri^>wtnig;wHRnixDh@|(UZ.x1h@|)!#:2<H|*xHn]#-UX'3Ro)z=iT}6ARns=Bwsn_wpnaRncw]aR(#UXa&Ua*a/=]iPd'#Y&Ro'WnXf{QRm2hNvj]nZd`'T~&1`{|`#9b]{}c:'!#Wl{>@=be}]?cl{{U#:5Abb}Jds#^YaF!a*b4a#a3aPa>&Tb!bH!*a_!Eau?/a&RjY<]gj>6Vz*;:pe~DrZg,QRj1JwNZtX@wihspcJvZ&!VyX9WmOJu|!|N2WmHJvh&!]ht~Bpbcn&T(!#RmQ<s7Nu;padH#X'`+WmJ@>RmKCARhnKup=!)&Wf+:RhqNuPpf9c!#'45pd5AwghpARn(Ls@w!%,)!RmP@Wfe<E|IJva!&WmNg8vsRmLd`*.`#Y'Xa!axRn*]hrA8Rhug5s@rXg8u!RmMd8#X'X*3@rV72smdI*#UY&RmICARho~GsgxVgd)Ta'U-Y&Xa!T#RnEWnA@Wffg1uDRi0hFvK5RnBxGnG&#`%owp)@wsf+bX}Ze-*1!a*^^^Ua|!#a.aq&Ya2!a>.a6!a:aO`aJDtL[y`@Wg#>6Vz12@wzoYRoZNuPRi!NuPRhzg=ucRi,@=b`{Yg=ucRi-ACJvB!&Sh[ebSh]ebi`wUuFRm4Jw2_[y0JvB!.<Ju(!&SoG}6Shd}6<Ju(!&SoH}6She}6Kur@._g5vHRieJvx!{L2G{Kx6gd'T#?Rh82Wi5cZ#X(g1w)Rm5dW-Y(Ta#!a)!#aYa=wnfE=su2>>bU{0j9udv:<svj8uQv-7RgHdE%#^'sq9sp=>Bb_{TJv`!&g/r|snj6v(us5d,#Y(56H}[978H}]Jw5!&g1rushJvB!+j;v{u5?zDhd}6}bj;v{u5?zDhe}6}ce*#`(^^^a[aea!=!a6a*aoXb1a.!aAbL!b>,b'aL!aV@Wf|2Wlg3[y/JwNZt^@3piPw:5pgJunZou3@rsJva&!Vy_g<v~Rm#JvG'!6Vz0=<r{Ju{%!:pj@WfsiXuJu3Rm:JvZ&!WfA~Bph@c4Z&Dtwax5rubx(#:awRk1@d,#Y&RfjRfid1#,Y(@Wfp2Wlrg5s@ryKu[@!,'=]ig9wlk?Rk>g5u-rqJvy'!@9RkQcH(T#=>Ri~@<wkj(Wj(KuZB*!&<7rw@9RkRcH(T#=>Ri}@<wkj)Wj)dg(Ta2Xa9X#`-!a*CARhg@@=I}d9x;c~#X%so=<sj>2@@=aybb}XjWv0Q~EfEj3vLv;<d,#Y(56H}`978H}_dgaPaFa'a/!#a3Y0a_a;a|!1(a7-[yE3[xt;:pJNvZrrg3uJrvJwNZt=@3pIh=rt3rxPw:5pGOu!5rpJvG'!6Vys=<rz@c4Z&Dt(ax5rtJvZ!&~BpH@wsfNg-vaRlNci*U#=<wei<F}a5@Jq.!a*JQ!%@qZ23d(#Y&RjH5]jCk!u7w&u0udARjFd/prq=tyvpaEa(a:.!a1aZ(@@=I}:9wpd%=<sX55w_h}@@=I{t=ay<aU@@=I}T=ay<2@@=I})?C9:9au@9Cb]}DP~=x-fAZ(2Wl1=ay<aU@@=I}>5@d##Y+jTv|vV~EfFj]uNpn~FRfGdgaK!Z2&!a8a-Tb({E!acTbM*!a(DtY[yYd'%Y#sl[y*hHvh>Re5x2c{Z}.j4uCvcawRiMd+#X+_x&d!},<5RkX;2Hzw@x,gavfB-!{CcF&T#Roe;RodwWbBg5urRgaKvHC*_6Vz+<4opieuew&Rmq@d]&Y)X,T#X0Rh}<BqP=4qS9:ReMg/ujReNJw0!/<Jui%!bd{kawwnemRelAxUa?a3#*.&UX(Ya+a/RhvRnQ<o}9Wmtd-#Y&RgSRmw9;Rmxay=Rmyg-vaRmuxEhSrNu,v-voC!%(aR.a(a7+1Ro1>Ro5CE{A9b]{@;5x#eO{:g;urRi+KrNA!%(Ro3>Ro79;Ri_Ku@>{;&!x%gX|{KunA_+g5QRj/g3u5Rj#g>uERj%wio/xRhS&!,!#^1U}wba{8>>@=be}qC@:D5ba{7Ku+A&!}x?ba}t>>@=be}se(aA^^^Uat!b0#{pa+awUazbGa#aLb9bgaWac'a5TbS=Br!d1#`%scp_Jvl!#rT>Re0JvX&!VyN=H{Fcm#U&:pY=ReaJv2&!]h0=]nUJvG'!6Vy|=<r%JrM_=]h2@Wlud'#)U'Wf'b]{i=]h/Jvh!&~BpWg=v]RnMx+ny#'Nu;pVwjnu=]nwxJnx,T#`&Reqwjnt=]nvieu9vrRjLLuYwP(#+!th@wih5pX~Gr'g5v/Rh4KunA'!-CARnP@wwiN:Rm_9x'cvw>!|l=<saKvAA!0&3@q}>w^e1bp#&Re2Re3BDx7gH#T|f5H|eKuZ>!%(:qNAH{]Jv6!+3B2B9=b^{X<5<B92:E{ZLvhwA(a;a%!igQuyRmad+#Y}m@3Rh5d8#X'X*:AqUAHzmaxwbh<aXRnVcF}RT#Nw&cj#U(BWnug/vsRntdka)(a3+.Zb7aYYan1!bVa@Xa}[y^@b[{G=H{+hFu73Rj&Pv#5ReQcK%T#sig1v{Rj'Ku+D#'!t]~Grm~?rkKuMB!01d5#`'Vy.ta3Dtu~Hroc8#'{^45s85AwZbP&!#Rn!wghxWn#KvEA!)&2RlA2RlBx:h|#(T,=]j09Wobz>x]z/@awRoTd+#Y(az]hFhCrm4d,#Y+jTv|Q~EfMj]uNr|~FRfOdCa!Xa9_X#@<plJvf!%b`{(9;Rgwc;.!#2x7cw#T|UDb]|T5Ju={(!=@E{&Jv)&!Ab`{'awJvf!~*>>@=be{#KuY>!+&4Ezyi[ugv&RjIdea+T)#UXa&T-T&a!Rh9auRmW=]kLg5vuRn+g3u4Rn-Ow6ARn,hHus5xNk?#UX(U~)/g8v0RkD~AwkkF?Ri.OuNBwkkA?Ri/d|a2`a*^UYa.!aBTZaTa'Xa;!(!2!-a#b2[yC>6Vyq3[xr2Wi?g1rusVh%s?DtF~<5rbJs;%!DtBfswKtCj[uvuSsEu3RgVx3o:u+wN'*Zt;@3rd~Grh~?rfg8w)Lq)qE&-a%!>bI|`jWv0vV~EfCjTv|vV~Ef@j]uNpn~FRfBcK#T']gWNu7x,k7q4ai(0!hHv8<RhmkMu9vrsBuev/RhlCJvB!,g<v{wchh~@:Rhji[vrv{wchi~@:RhkdS&a5UY#Ta!RgPwwiI5BwciI~@:Rh`x'iJvj'!5]iJPu8Bwch]~@:Rhach)U#h3rp]gLh@t|Ax,hTq3ah!-(~@:Ro0Ou!5RhXj^v(pyw8unRhVd|)`,^UYas!a?/a2Z'a^Ta{Tb7Ta(a#!a,Wf&9sZ3DtAadamov=Bqt3[xig8vsRm~>waiL2b`{QJv*_Ouv2qgj<v]v2BqfdR'X*X#Y-@3qr~Gqv~?p6hHv-]glPup5Lq+q?_%*b_{qF{n9b^{rOu4ARhpKvCD!+&~Bqp:5Dbb}nwoiKl&unuTuBv]v+ueunaXRf0=Jvh!0nKufu8v1w&w7q%w&uHrz:Rgnj5w,uxDJq/(!hNw'5ReCk0s2u3w/w'5ReFd>Za&!*UaA=<wkgsRnSJv^!%Refifw3vyRgOKu_B'!,<]gkiiu:w&Rh<=C@a^<B57@2F{[<B5@aW:=3away9A5aW=<B=C@a^<B57@2F{Ie-#`(^^^bCara.b8aza6!/bZ,!adTbnTbOb+aFaS!aAT9@Wf~2Wli3Dtl2@d,#Y&RfnRfmJwJZtN~GqyJva&!VyMg<v~Rm%iXuJu3Rm9Jv[_=]ih9wlkDRkCd1#`(@Wg>2Wls3cH#T(@<Rj*=>Ri|b~'#23s9h<~El.d'#Y&Dtxi^rzvdRl#d*#U%(o|B2s`hJwSaxRmDKv4B&!1:Rmdd5#`'Vx}to~Hq{x'f1v3(!BA5ba|bJv_&!Wfug1v]ReIdO+U/Y#&G}-8wze=Rh{g1v]ReHg/uQRf/by#)ibQwERl/cH#T(@<Rj+=>Ri{cNu+vlax-!(#a0qa9<Rii2;;bU{H;x<i=&X#Rk`<4wwi=C9H~8xAI(Y#<azRi@45wXI<B9;5bb~7dL(X#Xa(+!aL6Vy{g5QqOau:5au2@ay547EzbxOcU(UX-T#Ta#:Cbb|A?wjh/b_|SOw6ARgtihr}u7Rhy<d1#T)X1@@=I|~=ay<2@@=aybb}Sj3vLv;<d,#Y(56H}A978H}@dGpvs@uAu`vcw9*!aFa+ai%(b!aXa8.a?a[ozWey=sU2@G}Nch&U#Rf_WexKu+D#'!t:~Gr`~?r^j]uNr|~FRg*j^psurwJt|RmcKv)@&!)7Rkv~Br[@wxfO:Rl3co#U'6Rezj_q#vIuavjRltwzeyh@vr5JqD0!>aY?C9:9au@9Cb]}9cl#U*5;5<H||jbuus1ucv&Rfvg1v~d/pppzqFr^a--a~!aMat1(hFv;Wiz@@=Izoj5uuv-7Rix~Cw`fk2WlVcZ#X,k)u3vWs@u2]ktg;wEx'fBq(_2Wg/jTv|vV~EfoJv]!15x'hzqG!(P~EfU~CRl_j6v(us5x4i-#T(2WmZ?C2F|d>Kq<aj1!*jTqIsBv=Wl`~Cw`fi2WlWj`v0u*~>RlR=c>Z,k#u3vWs@u2]kr<c1Z+jTqIsBv=Wla~Cw`fm2WlXdmb3!a{(arZa`bkTa%TbQTa-a9+c'!aM!/[yL=Bqug.w'RifhFvyDRj.g>vgwyk^9]k^Jv3_@WfbAARkhJw2_[x|JvB_wkoIRoKwkoJRoLd'(Y#<]gm=<9<H|yd'%_X#skDtb3awwqkgNulRkgdB#^',9:p'hJwSaxRmEBwVb8@4=H|qLu+w50&!)@3qs~?pU>Awwn;;Rn=c:Z'ARn<=<qwKvC@!/&~BqqJv6!&]eVb^z^xRge'/a%+^`#Sge}6<4Rn3=]n0Pw2>Rn8Jw0!&>Rn:>Rn6cY#a7+!a&=<wkaNw~h3z_c5Z{=wjh#=]nLKv^D!&)Vyz=bW|swYb<WetcG#T(2wxa@qVx@gD#Y&b^|V5JwG&!5bb|pg/w&RgD@x=kHs=uAvn!a%%/'+RmSRh694Ro`g-vaRmRhHv-]mlxCcS#`&ba~.5cD#Ta)P~=d,#Y(56H{>978H{Dd_#{2^Y%_+qbbb{6g3sERhsbU{?dfa.,`a(Xa<!aiX#(55RiG54RiHcI#T'WiU3RiVNvdwtfcRlKNvdd,#Y&RlHRlExQgf.1*^T'X#Sgf}6Wn4=]hfPrk>Rn7Jw0!&>Rn5>Rn9Lunw?&a2!,5<oq@@wqfdRlJj5Q~=d,#Y(~ARfcOuN]fdDKw;ay(}i!547E}j?cI#T(@5bV}iCbV}hdv(^^Tb?a40,b##Tbo!a*bR!a<b|a/!aKai!aU[yK=]o^g:v>ReGJwPZtK<7Rh+h<~El,Pv#5ReR@awwxjCg,ulRjDJv6&!]j!z?aQeeg>w=Sh<eeJw;!&axEzOg,Qosc!#*:wkeJ]eJ>x'h-u(!%Ro.w~h.zPdNZ(X,Ya![x{;9ReY;wkgxRiF:x?ap#Y&RmUg<s2Rkod]+UY0TZ'!a&A9sw<=bczLNvuw{gqzNhJwSaxRmCKuLay!#&s_Rf-55b^{uJvZa!!c%#(55Ri654wmiu5RiuawLu,vp!+}^%b_}Y9;wkgxba}o>A9:=b^}zKuh=a''!3awRk3c*'!#aHRk6c+Z&Rk5Rk4Jv)&!awRjSawd9*`#0?C2@EzMj8u<uJ5RmbjQrquJu3x,k>uq@_+=ayb^|W~ARkEOuN]k@7dhzV^X/X&a-#zRzSb`zXcJzTT#2WkVKvDBzW!%FzY9;5bbzWjQrquJu3Jw3%!b`zU=ayb^zQd:#X(T-a!6Vyywxh}=b]{Jg=u1RiAdGp~qHtzv!w(wA+a+a;<!aJaYai'anasb(=azRmV:Cbb{MLq2vb!%')RjuRjrRjtRjqx3jnqCw3!%')Rk(Rk+Rk&Rk)Lq2vb!%')Rj{RjxRjzRjwLq2vb!%')RjsRjpRjfRjex3jcqCw3!%')Rk'Rk*RjkRjl9<CbbzfOu4ARhxLq2vb!%')RjyRjvRjhRjgx=joq*uKvb!%')+-Rk.Rk%Rj~Rk-Rk#Rj}x=jdq*uKvb!%')+-Rk,Rk!Rj|RjmRjjRjidAq&qKs@uAv8Aa.'*-a@a&0!aM@a5[y73Dsy3Ds|3Dt):wxgI2sHJwJZt.~Gqxwsf0ikrzt}Rl0Jvy_[xj~HqzKv_A|D!&WfP8axRoVcf,U#k(v]v+ueunaXRf1Ju}'!g8u#Ri=jQw!sCunLprq>!,')~<5qeGzq9F{W=c##%s5au:5aU3CBE|;d4#X(D!a&6Vygx(b;#(=]ed?C2F{N<capoq2r[a&!aPa9,'Pw;5s:@@=I|,55w_h|@@=IzcP~=x'fCqB_2Wl2>aU@@=I|1OuNBc1Z+jTqIsBv=Wlc~Cw`fl2WlZ~AcTa%!Z+jTqIsBv=Wlb~Cw`fh2WlYk+uNqJsBv=WlSg,u3dca3#UXaMYa)TaB-=cM|7T#<bI}l5@B932:aV2G{BOuNBJq:|M!5Ezt=<B=C@a^<B57@2F{v>cB{/T#=ay<bI{3Jv6!a.6BKq0ah&+!5E}HP~Ef{978BaU@@=Iza<7d#.Y#978BaU@@=IzH~AJq0!(@@=IzG978BaU@@=IzFe,aU*Y&^^^bvJb,b:bFad!a,c2Ta>aL.bo6!a#CbTa'T#Re{2Wlh2@G{yg6t~Ro_NvdRfticuRQRllJv3&!x&c|zs@Jw3!%RflwpfkRlpKuL;%(!Re<@G|C2GzdhIvuBwgjAg-u0RjAKQB%!(GzZ@G|5NuuRl7d='T+Y#Vy[g<v~Rm!==G|>JvA!)@wma=]m1ifuaw&RmnLs@vT'!|/+[y,g:v>ReTJw1!#qX=x!eC{bLu+wT&)ZtZauq_~Graci&U#F|89:r_Lupvq!.)&2RlG8RfaC=x!eF{_h?rpWlmd&'!#X|&]k::xJey#`'T|+<E|&2@H|%dE#(^,g;u.RiEg6vjRiC9xCkA{O|zY#g=ucRmXKs0@!&*@G|m@awRknJuh!,3d(}gY}eJvj!%Rm):Jw3!%Rm+Rm-Ls0w(&!a(a#@b[|6cZ#X'7RkxWgAOu4ARn'dH'U#Y*Vz-Wm'CARm}d]*#a%^a*T'aK!a<9bV{PC=p*Jw4!&SgxcbB5r]idw(wBRmF7xFkt#&`(Rm/Rm8E|!JuY_9:Rl5=wrgr2:bbxd@xXfB(a*#T+!.X0X1Ta/a'T&RlDRfL>RlyARl9b[z[>RfZ:RlL:RfRwlg/ARl;9;RlxKv,A/!%7s69<74=BA5ba{-8Bde#`a<XaKYa1,a'P~=wxfB2bZ}}?C972@@=I}r8@55B9;5bb}G978B2@@=aybb}3j3vLv;<Jw3&!>Rfk=ayb^}4~Ad1#`*@@=aybb{w2@>==<bbz]dx+UY#^UaF!a9!bB'Ya1.!ajXa#%olRhD[y=3Dt#Ov5BrHKuMB%!(Rf^Wep~HrJwkiQjKr|~FRg)Ku+D#'!t5~GrF~?rDdV)UY,Z/_7RkuG{<~BrBg,rlsO:235B@bX}|d?a1!#`(6Vyn5@d##Y+jTv|vV~EfIj]uNpn~FRfH7Lq2vb1!a9-978BaU@@=Iz9978BbU}#~AJq0!(@@=Iz8978BaU@@=Iz7~AJQ|}!978BbU}!JvkaK!AdUa21-U#`a+(g/vsRn~Ou!5RPj:rmu9WhOjXuvvNr}:RhAj^v(pyw8unRn[kPr}p|u7vwv]RiSBd;pppzq@qHQa?(b.!a.a`@.|xa(hFv;Wiyj5uuv-7Riw~Cw`fg2WlU978BbU|wOuNBJqG!(P~EfD~CRlQcZ#X,k)u3vWs@u2]ksg;wEx'f@q1_2Wg.j]uNpn~FRfqJv]!15x'h{qG!(@@=IzK~CRl^j6v(us5x4i,#T(2WmY?C2F{1>Kq<aj1!*jTqIsBv=Wld~Cw`fj2Wl[j`v0u*~>RlT=c>Z,k#u3vWs@u2]kq<c1Z+jTqIsBv=Wle~Cw`fn2Wl]dn1#c(a(b^a2!b/bAT(bj!aDa7bu,a_a{c0!2T0g:v>ReD2@G{42@G{5~DpM~<5rc=Bx6i>{RT#RnI@zCx]y]z:2Jv[!zr5Awyk]9]k]dD(Y+X#6Vz.g=wKtgwhaCwgmTWj2Lu,w%_+/[y-B;b^xeg3u3Rj-2@bX{*KrJ<!+'@Wg(g?QRlC@Jv`!%b[zIwsfII}8JQ_@w|kW|=Jv(%!AqcOuNBJvEzh!bYzjLs@wP#(0!oy@>RkdJwMZtc3Dtd@BcG#T'9bWxg2@2Fznd*#Y+;2x'c}w<zizixNgwa#Z'U+!/!a'!a+w~g~z6wcn{Rn}wcnzRn|5Rh%=]nJg5vuRmvNvdRlvcprJu}w*az*a#!%.a.'Bot9qT]kj@Wg'ay2Gzv@Jv`!%b[zEwsfHI}1;ck#Ux`<Cbbx_Lu+w!a&0*!wko*wwo,So,}6Juqxf!E}PigQuyRm`d3(`#8>Rn%:A5B;bZ~%KvhCa!a2!x>k7#Uxb@b{#xaRk7Jw0!)>wwhlShl}6>wwhmShm}6CJvB!.x'hhvj{!!5Bwkhhbaz}x'hivjz~!5Bwkhibaz|xEhTrNu,v-vpD!a%&/)a3a.,%Ro2t[CE{)@3re9b]{%wjo09:rgc:Z&Ro6=<riifuaw&RmoKrNA!%(Ro4>Ro89;Ri`dSaL'UYzxZb)7Rka3xRhT&!,!#^1U}vbaz{>>@=be}yC@:D5bazzKu+A&!}{?ba}y>>@=be}wxBh[t`u~vJvr!%a!a()a,a0a4RoC=]o;Ju(!%RoGRhdwjh`=]oAg>w#Ro?g5vuRo=NvdRl|Ku]C.!&;RoEJvB!%RoORoMBx'h[v+_?w~h`}~5?w~hd~!xKh]oiptu-utv.vp!#%&a30a@a'a+(a/aOp(o~p!RoDJu(!%RoHRhewjha=]oBNvdRl}g>w#Ro@g5vuRo>c[#X']o<CauRoRAd-#Y':RkpauRoQKu]C.!&;RoFJvB!%RoNRoPBx'h]v+_?w~ha}t5?w~he}ue!/UbhYacXaW^Tc&a;b:a-c/#b&aja1(!cL+!bKbt!bmcRc9aIc?8[yW3Dtt94Rg`Jv}!&SiRMzBhEebShEMNuPRe>x7gL#TzuwjirRipc<Z&>on;>z=h-MSh.Mwqczx'a7vj&!>Re4@=ResJt__NuPRi*NuPRi)j]uNr|~FRfzKrJ>_+@Wfy@Wf]2WocKrJ<!+'@Wg%g/QRl@@Jv`!&awRl<wsfFIzgLu(w*!.*&ShBMwvhIRhI9;RhNx1hK'!#Sn]Mx1hK~0!#:2<H~7cNu+w7D*'1ZtW>Rn1~?rOc:Z&Rn2=<rQ<7wjh&=BSnLMc]#X(6Vz)w[b=a!U#9wzgMc3#&(RgMRitRis<x,gKt`ax!&+SioM=BSilMc3#&(RgKRinRimKurB,!&SiQMzBhDebShDM6BJQ!(P~Efx978B2@@=I}WLrJw!!,a*&@G}O@9wkibRid@@x'fKwC!&SlDMSfLMjUv~Q~EfKKv3@a+!(hFv-]mpx/hYZ(C5RiWz<o/MwkhY?So/M@x,gbvfB*&!SgEM:SoeeehFu3:Rgbda(,^TZa)X/7Sg[eb:2RgI~BrMC@wgkc:wwkcRerx3h(uUvK!&*,SnOM4Sh*MArRg;wHRh(x=h;rJvPwI!a4',a'0@Wg&=BSh/Mg>w=Rh=g3w*wwgGRgGcW(X#;Sg}M2Gzk@Jv`!&awRl=wsfGIz`dKZ*T'Y-:RhR7RhQg5u-p`j6v(us5d,#Y+~Awkia?RicOuNBwkibba}Ld6p~tyu_vbAa'a+!a/'a3aEa8a!>Sh,ebJv{!&Sh@ebSaReb9;SgwebNuPRi(NvdRl)NuPRi'hHu^<Rm^Jvv_@Wl(g;u1Si/ebKu'B&!*Sh?eb@Wl'z@aPeb95Si.ebcpputyvjB)!,&a+0a%ShAMWeK@G}C@WfJ9;RhMwvhH9w{ia}ix,hJvRA1(!zAn[MRhHx1hJ~*!#hFv(BSn[MBJQ!(@@=I~'978B2@@=I}2db.Ua<'X}+T#a0XaG2G}E;wkg|wuh!Rh!x,hZu,@)!&So0MVy)C5RiXACJvB!&5RiY5RiZg8w)cG}*T#2@bU}=KsA>(!a.3wkhZba~(x,h^u(A!&(SoCMRhb5Bz=h[eb?w~hb~6x,h_u(A!&(SoDMRhc5Bz=h]eb?w~hc~6e)aA1T#T,^^^c-bMb&blcPaP(a/!0!bA=b5c@a(!bfbrc#2afwmhARnjwchORnp2Wlf3DtsNvdRl-2@wpa<]m0bx(#:awRk2@Jw3!%RfhwpfgRlnKQB%!(G{V@G|'NuuRl6d='T+Y#VyUg<v~Rl~==G|<Jv+'!aYShC}6@B<5?ba~8@Jw3'!g2QRljhLrpWlOd+#Y'g.w'rIg>w*wgj@g-u0Rj@Lu+wT&)ZtUauq]~GrGci&U#F|39:rELrNvj!.%*RhCwunfw~nf~:9;Ri]>wtnhg;wHRnhx3hDs@v~!/+'@Wfr@9RkSNu&Rlo=@<5GzoKs0@_+@Wl+@awRkmJuh!-3d(}pY#qWJvj!%Rm(:Jw3!%Rm,Rm*de&!1U-U#`)Re;@G|.@9Ri82@wjfvRlq=@<5GzpLvOvr!).&2RlF8Rf`C=x!eE{.Jw3_g2QRlkhLrpWlPde(!#U{s,UXa*Ta'[y'g:v>ReS;x0PZ&RnlRnn~HrKJw1}f!=x!eB|2w]aP(#Xa&a*Ta.Ua2a7=]iOd'#Y&Ro&WnWg;u.RiDg6vjRiBNvdRlzhNvj]nYJuW_2Wm3x)kFze{9d])!a.!,Y01!#&aC!a3RndC=ox~BrC@2b^{pg,rlse7x'ksuq!%Rm.E{xidw(wBRmGx9o+)X#wwo-So-}69:Rl4@xSf@a#XZ'X)X,Ta(/ARl8b[xc>RfY:RlI:RfQwlg.ARl:9;Rlwdn'#^XafaQa1X1TaHTa)@b[{zcZ#X'7RkwWg@Ou4ARn&x)kG#{,g7u/RkGdH'U#Y*Vz'Wm&CARm|bx#(A]gUbUzJj9Q~=d,#Y(56H}l978H{U7d,0#U*2>ABb_xZ978BbU{e~AJQ{g!978BbU{hxMh?ad{oUYZ.x1h?{l!#:2<H{mx3n[t{vl!,&a%3Ro(z=iS}6ARnr=Bwsn^wvn`Rnbd`*T}B0!#^X'BG{c9b]{a>>@=be}F?JvS!&BG{d7BG}(Bde#`a1X,Ya@!a'P~=wxf@2bZ}I56B2@@=aybb}08@55B9;5bb}<j3vLv;<Jw3&!>Rfg=ayb^}&OuNBKuLA!)a!P~=x#fD{f2@>==<bbzl?C972@@=Ix^d6rSu,v7w*C(0a)a6#B+a%!sQ[y?3Dt%3[xn~<5rLOu!5p@Ku+D#'!t7~GrP~?rNKvlaya7'!h+v-5qMg=t|cd,U#5AAaa5Abb{S@52B5@a[@52B5Gx[iXueu;d<#`a(!/549C;ag>23ExY5@Dah89b^~689Jv)!~2b[~1Lv'w(%*!a#bX|aPrmawRe]keu7uhv-q6rxu,q`xTo]/a5aU!bNaDXbi!b-!ao!b<bwA!#5@B932:aV2G|:d-)Y#hJrL>RhG<7@C5<H|_=Cau:5aj5@B932:bJ|ng>vIbs)#?C2F|9jPv0w.vISh-MKvUaz(.!9ABbb|[5;5<H|Eg>unwfh;9:4E|YjQsBt|vjx'hYq3!(?C2F|J:2<BaY?C2F|GOu!5x,g|p{ah!-(?C2F|c9:4E|OjXuvvNr}:Rh&i[w*t|cd+U#jJvsu)vsSn~Mkfrmu9p}u7vwv]So!McW#Xa!ax5@A5aY:5;5<H|>kJv~vYrquJu3x4ib#T)2@SmZM?C2F|Bj:rmu9@xPhI(a*a#U#`a3-5Abb|L~@:RhK9:4E|0@52B5G|#C::aY?C2F|-:2<BaY?C2F|.5Jvk!a)javYrquJu3x4ia#T)2@SmYM?C2F|HAxPhH(!a#U#`a*-5Abb|4~@:RhJ9:4E|R@52B5G|F:2<BaY?C2F|Sc^#Xa2j=Qq5CJvB!-g<v{z;hhM?C2F|Zi[vrv{z;hiM?C2F|XKsA>!a)-g<v{z;h[eb?C2F|]i[vrv{z;h]eb?C2F|^iZu.vix,hZq3ah!.(?C2F|QOu!5ShXM:2<BaY?C2F|P\", 13_494, 2713, 49, 25, 61);\n//# sourceMappingURL=decode-data-html.js.map","// Generated using scripts/write-decode-map.ts\n/** Packed XML decode trie data. */\nexport const xmlDecodeTree = /* #__PURE__ */ new Uint16Array([\n 512, 26_465, 29_036, 7, 0, 2, 4, 116, 24_638, 116, 24_636, 8693, 29_807,\n 24_610, 621, 1, 0, 0, 3, 112, 24_614, 111, 115, 24_615,\n]);\n//# sourceMappingURL=decode-data-xml.js.map","/**\n * Bit flags & masks for the binary trie encoding used for entity decoding.\n *\n * The trie is a flat `Uint16Array`. Every node starts with one header word:\n *\n * 15..14 VALUE_LENGTH Number of words the value occupies, +1.\n * 0 = no value; 1 = value inline in bits 12..0;\n * 2/3 = value in the 1/2 words after the header.\n * 13 FLAG13 If VALUE_LENGTH > 0: semicolon required (\"strict\"\n * entity; `;` is never stored as a branch).\n * If VALUE_LENGTH == 0: this node is a compact run.\n * 12..7 BRANCH_LENGTH Number of branches (or run length for runs).\n * 6..0 JUMP_TABLE Jump-table offset / single-branch char / first\n * run char (see below).\n *\n * Branch data follows the header and any value words. Its shape is selected\n * by (JUMP_TABLE, BRANCH_LENGTH) in the header:\n *\n * Single branch JUMP_TABLE = the only child's char, BRANCH_LENGTH = 0.\n * No branch words; the child node follows immediately.\n * Jump table JUMP_TABLE = first covered char (> 0), BRANCH_LENGTH =\n * table length. One word per covered char: 0 = no branch,\n * otherwise the child's offset from the END of the table,\n * +1 (so 0 stays the no-branch sentinel).\n * Dictionary JUMP_TABLE = 0, BRANCH_LENGTH = number of branches.\n * ceil(n/2) words of sorted keys packed two per word\n * (low byte first), then n pointer words storing the\n * child's offset from the END of the branch data.\n * Compact run VALUE_LENGTH = 0, FLAG13 set. BRANCH_LENGTH = run\n * length (3..63), JUMP_TABLE = first char; remaining run\n * chars packed two per word after the header. The target\n * node follows the packed words immediately.\n *\n * Pointers are end-relative (rather than relative to the pointer's own\n * position) because that makes the common \"child encoded right after the\n * branch data\" case a small constant, which compresses far better. Offsets\n * to already-encoded (shared) nodes wrap via uint16 modulo arithmetic; the\n * decoder masks navigation results with `& 0xff_ff` to match.\n */\nexport var BinTrieFlags;\n(function (BinTrieFlags) {\n BinTrieFlags[BinTrieFlags[\"VALUE_LENGTH\"] = 49152] = \"VALUE_LENGTH\";\n BinTrieFlags[BinTrieFlags[\"FLAG13\"] = 8192] = \"FLAG13\";\n BinTrieFlags[BinTrieFlags[\"BRANCH_LENGTH\"] = 8064] = \"BRANCH_LENGTH\";\n BinTrieFlags[BinTrieFlags[\"JUMP_TABLE\"] = 127] = \"JUMP_TABLE\";\n /** Bits 12..0: the inline value of a VALUE_LENGTH = 1 header word. */\n BinTrieFlags[BinTrieFlags[\"VALUE_MASK\"] = 8191] = \"VALUE_MASK\";\n})(BinTrieFlags || (BinTrieFlags = {}));\n//# sourceMappingURL=bin-trie-flags.js.map","import { codePointToString, replaceCodePoint, replaceCodePointXML, } from \"./decode-codepoint.js\";\nimport { htmlDecodeTree } from \"./generated/decode-data-html.js\";\nimport { xmlDecodeTree } from \"./generated/decode-data-xml.js\";\nimport { BinTrieFlags } from \"./internal/bin-trie-flags.js\";\nvar CharCodes;\n(function (CharCodes) {\n CharCodes[CharCodes[\"AMP\"] = 38] = \"AMP\";\n CharCodes[CharCodes[\"NUM\"] = 35] = \"NUM\";\n CharCodes[CharCodes[\"SEMI\"] = 59] = \"SEMI\";\n CharCodes[CharCodes[\"EQUALS\"] = 61] = \"EQUALS\";\n CharCodes[CharCodes[\"ZERO\"] = 48] = \"ZERO\";\n CharCodes[CharCodes[\"NINE\"] = 57] = \"NINE\";\n CharCodes[CharCodes[\"LOWER_A\"] = 97] = \"LOWER_A\";\n CharCodes[CharCodes[\"LOWER_X\"] = 120] = \"LOWER_X\";\n})(CharCodes || (CharCodes = {}));\n/** Bit that needs to be set to convert an upper case ASCII character to lower case */\nconst TO_LOWER_BIT = 0b10_0000;\n/*\n * `parseNumericEntity` packs its two results into one 32-bit integer:\n * `(consumed << CONSUMED_SHIFT) | codePoint`. The 21-bit code point field\n * fits any valid Unicode value (max 0x10FFFF, clamped before packing); the\n * consumed count excludes `&` and gets the remaining 11 bits. Extract it\n * with `>>>` so the topmost bit isn't treated as a sign.\n *\n * Plain consts rather than a `const enum`: with `isolatedModules`, enum\n * member reads compile to runtime property loads.\n */\nconst CONSUMED_SHIFT = 21;\nconst CODE_POINT_MASK = 0x1f_ff_ff;\n/**\n * Reserved consumed field for counts of at least 2047 characters after `&`.\n * The true count is in `longNumericConsumed`.\n */\nconst CONSUMED_OVERFLOW = 0x7_ff;\n/**\n * Side channel for numeric entities of at least 2048 characters including\n * `&`. Set by `parseNumericEntity` when its consumed count reaches the\n * reserved value `CONSUMED_OVERFLOW`; callers read the true count from here.\n * A module-level slot avoids a tuple allocation on the hot path.\n */\nlet longNumericConsumed = 0;\n/**\n * Extract the consumed count from a `parseNumericEntity` packed result,\n * recovering the true length from `longNumericConsumed` when the packed\n * field contains the sentinel. Read it before the next `parseNumericEntity`\n * call, which may overwrite the side channel. This helper owns that protocol.\n * @param packed Packed result of `parseNumericEntity`.\n */\nfunction unpackConsumed(packed) {\n const consumed = packed >>> CONSUMED_SHIFT;\n return consumed === CONSUMED_OVERFLOW ? longNumericConsumed : consumed;\n}\n/**\n * Unsigned subtraction trick: (code - lo) >>> 0 wraps negatives to large\n * values, so a single `<=` covers the entire [lo..hi] range check.\n * @param code Code point to check.\n */\nfunction isNumber(code) {\n return (code - CharCodes.ZERO) >>> 0 <= 9;\n}\nfunction isHexadecimalCharacter(code) {\n return ((code | TO_LOWER_BIT) - CharCodes.LOWER_A) >>> 0 <= 5; // F - a\n}\nfunction isAlpha(code) {\n return ((code | TO_LOWER_BIT) - CharCodes.LOWER_A) >>> 0 <= 25; // Z - a\n}\n/**\n * Checks if the given character is a valid end character for an entity in an attribute.\n *\n * Attribute values that aren't terminated properly aren't parsed, and shouldn't lead to a parser error.\n * See the example in https://html.spec.whatwg.org/multipage/parsing.html#named-character-reference-state\n * @param code Code point to check.\n */\nfunction isEntityInAttributeInvalidEnd(code) {\n return code === CharCodes.EQUALS || isAlpha(code) || isNumber(code);\n}\nvar EntityDecoderState;\n(function (EntityDecoderState) {\n EntityDecoderState[EntityDecoderState[\"EntityStart\"] = 0] = \"EntityStart\";\n EntityDecoderState[EntityDecoderState[\"NumericStart\"] = 1] = \"NumericStart\";\n EntityDecoderState[EntityDecoderState[\"NumericDecimal\"] = 2] = \"NumericDecimal\";\n EntityDecoderState[EntityDecoderState[\"NumericHex\"] = 3] = \"NumericHex\";\n EntityDecoderState[EntityDecoderState[\"NamedEntity\"] = 4] = \"NamedEntity\";\n})(EntityDecoderState || (EntityDecoderState = {}));\n/**\n * Decoding mode for named entities.\n */\nexport var DecodingMode;\n(function (DecodingMode) {\n /** Entities in text nodes that can end with any character. */\n DecodingMode[DecodingMode[\"Legacy\"] = 0] = \"Legacy\";\n /** Only allow entities terminated with a semicolon. */\n DecodingMode[DecodingMode[\"Strict\"] = 1] = \"Strict\";\n /** Entities in attributes have limitations on ending characters. */\n DecodingMode[DecodingMode[\"Attribute\"] = 2] = \"Attribute\";\n})(DecodingMode || (DecodingMode = {}));\n/**\n * Token decoder with support of writing partial entities.\n */\nexport class EntityDecoder {\n decodeTree;\n emitCodePoint;\n errors;\n /** The current state of the decoder. */\n state = EntityDecoderState.EntityStart;\n /** Characters that were consumed while parsing an entity. */\n consumed = 1;\n /**\n * The result of the entity.\n *\n * For named entities: the trie index of the best legacy match so far\n * (0 = none). For numeric entities: the accumulated code point.\n */\n result = 0;\n /** The current index in the decode tree. */\n treeIndex = 0;\n /**\n * Characters consumed since the last recorded legacy match, plus one.\n * Invariant at the top of the `stateNamedEntity` loop: `excess` equals\n * the number of unrecorded consumed characters + 1.\n */\n // biome-ignore lint/correctness/noUnusedPrivateClassMembers: False positive (read via destructuring)\n excess = 1;\n /** The mode in which the decoder is operating. */\n decodeMode = DecodingMode.Strict;\n /** The number of characters that have been consumed in the current run. */\n // biome-ignore lint/correctness/noUnusedPrivateClassMembers: False positive\n runConsumed = 0;\n constructor(\n /** The predefined HTML or XML decode tree. */\n decodeTree, \n /**\n * The function that is called when a codepoint is decoded.\n *\n * For named entities that decode to multiple code points, this will\n * be called multiple times, with the second codepoint, and the same\n * `consumed` value.\n * @param codepoint The decoded codepoint.\n * @param consumed The number of characters consumed by the decoder.\n */\n emitCodePoint, \n /** An object that is used to produce errors. */\n errors) {\n this.decodeTree = decodeTree;\n this.emitCodePoint = emitCodePoint;\n this.errors = errors;\n }\n /**\n * Resets the instance to make it reusable.\n * @param decodeMode Entity decoding mode to use.\n */\n startEntity(decodeMode) {\n this.decodeMode = decodeMode;\n this.state = EntityDecoderState.EntityStart;\n this.result = 0;\n this.treeIndex = 0;\n this.excess = 1;\n this.consumed = 1;\n this.runConsumed = 0;\n }\n /**\n * Write an entity to the decoder. This can be called multiple times with partial entities.\n * If the entity is incomplete, the decoder will return -1.\n *\n * Mirrors the non-streaming `decodeWithTrie`, but with the ability to stop decoding if the\n * entity is incomplete, and resume when the next string is written.\n * @param input The string containing the entity (or a continuation of the entity).\n * @param offset The offset at which the entity begins. Should be 0 if this is not the first call.\n * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n */\n write(input, offset) {\n switch (this.state) {\n case EntityDecoderState.EntityStart: {\n if (input.charCodeAt(offset) === CharCodes.NUM) {\n this.state = EntityDecoderState.NumericStart;\n this.consumed += 1;\n return this.stateNumericStart(input, offset + 1);\n }\n this.state = EntityDecoderState.NamedEntity;\n return this.stateNamedEntity(input, offset);\n }\n case EntityDecoderState.NumericStart: {\n return this.stateNumericStart(input, offset);\n }\n case EntityDecoderState.NumericDecimal: {\n return this.stateNumericDecimal(input, offset);\n }\n case EntityDecoderState.NumericHex: {\n return this.stateNumericHex(input, offset);\n }\n default: {\n // NamedEntity — the only remaining state.\n return this.stateNamedEntity(input, offset);\n }\n }\n }\n /**\n * Switches between the numeric decimal and hexadecimal states.\n *\n * Equivalent to the `Numeric character reference state` in the HTML spec.\n * @param input The string containing the entity (or a continuation of the entity).\n * @param offset The current offset.\n * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n */\n // eslint-disable-next-line unicorn/consistent-class-member-order\n stateNumericStart(input, offset) {\n if (offset >= input.length) {\n return -1;\n }\n if ((input.charCodeAt(offset) | TO_LOWER_BIT) === CharCodes.LOWER_X) {\n this.state = EntityDecoderState.NumericHex;\n this.consumed += 1;\n return this.stateNumericHex(input, offset + 1);\n }\n this.state = EntityDecoderState.NumericDecimal;\n return this.stateNumericDecimal(input, offset);\n }\n /**\n * Parses a hexadecimal numeric entity.\n *\n * Equivalent to the `Hexademical character reference state` in the HTML\n * spec. Digit parsing matches the hex loop in `parseNumericEntity`.\n * The accumulated value is preserved for numeric validation callbacks.\n * @param input The string containing the entity (or a continuation of the entity).\n * @param offset The current offset.\n * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n */\n stateNumericHex(input, offset) {\n const inputLength = input.length;\n // Local accumulators; flushed before any exit (see stateNamedEntity).\n let { result } = this;\n let { consumed } = this;\n while (offset < inputLength) {\n const char = input.charCodeAt(offset);\n if (isNumber(char) || isHexadecimalCharacter(char)) {\n // Convert hex digit to value (0-15); 'a'/'A' -> 10.\n const digit = char <= CharCodes.NINE\n ? char - CharCodes.ZERO\n : (char | TO_LOWER_BIT) - CharCodes.LOWER_A + 10;\n result = result * 16 + digit;\n consumed += 1;\n offset += 1;\n }\n else {\n this.result = result;\n this.consumed = consumed;\n return this.emitNumericEntity(char, 3);\n }\n }\n this.result = result;\n this.consumed = consumed;\n return -1; // Incomplete entity\n }\n /**\n * Parses a decimal numeric entity.\n *\n * Equivalent to the `Decimal character reference state` in the HTML\n * spec. Digit parsing matches the decimal loop in `parseNumericEntity`.\n * The accumulated value is preserved for numeric validation callbacks.\n * @param input The string containing the entity (or a continuation of the entity).\n * @param offset The current offset.\n * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n */\n stateNumericDecimal(input, offset) {\n const inputLength = input.length;\n // Local accumulators; flushed before any exit (see stateNamedEntity).\n let { result } = this;\n let { consumed } = this;\n while (offset < inputLength) {\n const digit = input.charCodeAt(offset) - CharCodes.ZERO;\n if (digit >>> 0 > 9) {\n this.result = result;\n this.consumed = consumed;\n return this.emitNumericEntity(digit + CharCodes.ZERO, 2);\n }\n result = result * 10 + digit;\n consumed += 1;\n offset += 1;\n }\n this.result = result;\n this.consumed = consumed;\n return -1; // Incomplete entity\n }\n /**\n * Validate and emit a numeric entity.\n *\n * Implements the logic from the `Hexademical character reference start\n * state` and `Numeric character reference end state` in the HTML spec.\n * @param lastCp The last code point of the entity. Used to see if the\n * entity was terminated with a semicolon.\n * @param expectedLength The minimum number of characters that should be\n * consumed. Used to validate that at least one digit\n * was consumed.\n * @returns The number of characters that were consumed.\n */\n emitNumericEntity(lastCp, expectedLength) {\n // Ensure we consumed at least one digit.\n if (this.consumed <= expectedLength) {\n this.errors?.absenceOfDigitsInNumericCharacterReference(this.consumed);\n return 0;\n }\n // Figure out if this is a legit end of the entity\n if (lastCp === CharCodes.SEMI) {\n this.consumed += 1;\n }\n else if (this.decodeMode === DecodingMode.Strict) {\n return 0;\n }\n this.emitCodePoint((this.decodeTree === xmlDecodeTree\n ? replaceCodePointXML\n : replaceCodePoint)(this.result), this.consumed);\n if (this.errors) {\n if (lastCp !== CharCodes.SEMI) {\n this.errors.missingSemicolonAfterCharacterReference();\n }\n this.errors.validateNumericCharacterReference(this.result);\n }\n return this.consumed;\n }\n /**\n * Flush locally-tracked walk state back to the fields, then emit the\n * recorded legacy match or reject (cold path — at most once per\n * entity). Called after failed navigation (leaf node, branch miss, or\n * compact-run mismatch). In attribute mode, reject if no legacy was\n * recorded at the current node, if we descended past it, or if the\n * pending input character is an invalid attribute terminator.\n * @param consumed Locally-tracked consumed count.\n * @param excess Locally-tracked excess count.\n * @param char Pending input character (may be the mismatching char).\n * @param valueLength Value length at the current trie node.\n */\n flushAndEmitLegacyOrReject(consumed, excess, char, valueLength) {\n this.consumed = consumed;\n this.excess = excess;\n return this.result === 0 ||\n (this.decodeMode === DecodingMode.Attribute &&\n (valueLength === 0 ||\n excess > 1 ||\n isEntityInAttributeInvalidEnd(char)))\n ? 0\n : this.emitNotTerminatedNamedEntity();\n }\n /**\n * Parses a named entity.\n *\n * Equivalent to the `Named character reference state` in the HTML spec.\n * @param input The string containing the entity (or a continuation of the entity).\n * @param offset The current offset.\n * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n */\n stateNamedEntity(input, offset) {\n const { decodeTree } = this;\n const inputLength = input.length;\n const isStrict = this.decodeMode === DecodingMode.Strict;\n /*\n * Local copies of the resumable walk state avoid per-character\n * field writes. They are flushed back to the fields\n * on every exit (chunk end, and before any emit helper that reads\n * them). `this.result` is only written at the (rare) record points,\n * so it stays a direct field write.\n *\n * Legacy-match recording happens in two idempotent places: at the\n * loop top when sitting on a value node, and in the chunk-end\n * epilogue (so `end()` sees matches that land exactly on a chunk\n * boundary). Recording applies `consumed += excess - 1; excess = 1`,\n * which is a no-op when repeated — the loop-top invariant is\n * `excess` = unrecorded consumed characters + 1.\n */\n let { treeIndex } = this;\n let { excess } = this;\n let { consumed } = this;\n let current = decodeTree[treeIndex];\n while (offset < inputLength) {\n /*\n * Descend through value-less jump-table nodes (including the\n * single-branch encoding) inline, mirroring `decodeWithTrie`:\n * this avoids a `determineBranch` call per level for the\n * dominant node shape — including the root on the first write.\n */\n while ((current &\n (BinTrieFlags.VALUE_LENGTH | BinTrieFlags.FLAG13)) ===\n 0 &&\n (current & BinTrieFlags.JUMP_TABLE) !== 0) {\n const char = input.charCodeAt(offset);\n const jumpOffset = current & BinTrieFlags.JUMP_TABLE;\n const branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;\n if (branchCount === 0) {\n // Single branch encoded inline in the jump offset bits.\n if (char !== jumpOffset) {\n return this.flushAndEmitLegacyOrReject(consumed, excess, char, 0);\n }\n treeIndex += 1;\n }\n else {\n const slot = char - jumpOffset;\n if (slot >>> 0 >= branchCount) {\n return this.flushAndEmitLegacyOrReject(consumed, excess, char, 0);\n }\n const stored = decodeTree[treeIndex + 1 + slot];\n if (stored === 0) {\n return this.flushAndEmitLegacyOrReject(consumed, excess, char, 0);\n }\n // End-relative: branch data ends at treeIndex+1+branchCount.\n treeIndex = (treeIndex + branchCount + stored) & 0xff_ff;\n }\n current = decodeTree[treeIndex];\n offset += 1;\n excess += 1;\n /*\n * `charCodeAt` past the end returns NaN, which would alias\n * to slot 0 after `>>> 0` — bail out explicitly.\n */\n // eslint-disable-next-line unicorn/no-break-in-nested-loop\n if (offset >= inputLength)\n break;\n }\n if (offset >= inputLength)\n break;\n // Handle compact runs (resumable across chunks).\n if ((current &\n (BinTrieFlags.VALUE_LENGTH | BinTrieFlags.FLAG13)) ===\n BinTrieFlags.FLAG13) {\n const runLength = (current & BinTrieFlags.BRANCH_LENGTH) >> 7; /* 3..63 */\n let { runConsumed } = this;\n // If we are starting a run, check the first char.\n if (runConsumed === 0) {\n const char = input.charCodeAt(offset);\n if (char !== (current & BinTrieFlags.JUMP_TABLE)) {\n return this.flushAndEmitLegacyOrReject(consumed, excess, char, 0);\n }\n offset += 1;\n excess += 1;\n runConsumed = 1;\n }\n // Check remaining characters in the run (packed two per uint16 word).\n while (runConsumed < runLength) {\n if (offset >= inputLength) {\n this.treeIndex = treeIndex;\n this.excess = excess;\n this.consumed = consumed;\n this.runConsumed = runConsumed;\n return -1;\n }\n const charIndexInPacked = runConsumed - 1;\n const packedWord = decodeTree[treeIndex + 1 + (charIndexInPacked >> 1)];\n const expectedChar = (packedWord >> ((charIndexInPacked & 1) << 3)) & 0xff;\n const char = input.charCodeAt(offset);\n if (char !== expectedChar) {\n this.runConsumed = 0;\n return this.flushAndEmitLegacyOrReject(consumed, excess, char, 0);\n }\n offset += 1;\n excess += 1;\n runConsumed += 1;\n }\n this.runConsumed = 0;\n treeIndex += 1 + (runLength >> 1);\n current = decodeTree[treeIndex];\n // Loop top handles the landed-on node (record/emit/branch).\n continue;\n }\n // Header plus out-of-line value words; 0 means no value.\n const valueLength = current >>> 14;\n const char = input.charCodeAt(offset);\n if (valueLength !== 0) {\n // Record a legacy match (FLAG13 clear = semicolon optional).\n if (!isStrict && (current & BinTrieFlags.FLAG13) === 0) {\n this.result = treeIndex;\n consumed += excess - 1;\n excess = 1;\n }\n /*\n * Implicit semicolon handling: emit immediately. Covers both\n * strict (FLAG13 set) and legacy entities — neither stores\n * an explicit `;` branch in the trie.\n */\n if (char === CharCodes.SEMI) {\n return this.emitNamedEntityData(treeIndex, valueLength, consumed + excess);\n }\n /*\n * `valueLength === 1` packs the codepoint into the header\n * word's low 13 bits, where branch metadata also lives. Skip\n * the branch lookup on leaves so those value bits aren't\n * reinterpreted as branch offsets.\n */\n if (valueLength === 1) {\n return this.flushAndEmitLegacyOrReject(consumed, excess, char, valueLength);\n }\n }\n // Value-bearing or dictionary node: dispatch through determineBranch.\n const next = determineBranch(decodeTree, current, treeIndex + (valueLength || 1), char);\n if (next < 0) {\n return this.flushAndEmitLegacyOrReject(consumed, excess, char, valueLength);\n }\n treeIndex = next;\n current = decodeTree[treeIndex];\n offset += 1;\n excess += 1;\n }\n /*\n * Chunk exhausted. Record a legacy match we may be sitting on, so a\n * subsequent `end()` emits it, then persist the walk state.\n */\n if (!isStrict &&\n current >>> 14 !== 0 &&\n (current & BinTrieFlags.FLAG13) === 0) {\n this.result = treeIndex;\n consumed += excess - 1;\n excess = 1;\n }\n this.treeIndex = treeIndex;\n this.excess = excess;\n this.consumed = consumed;\n return -1;\n }\n /**\n * Emit a named entity that was not terminated with a semicolon.\n * @returns The number of characters consumed.\n */\n emitNotTerminatedNamedEntity() {\n const { result, decodeTree } = this;\n const valueLength = decodeTree[result] >>> 14;\n this.emitNamedEntityData(result, valueLength, this.consumed);\n this.errors?.missingSemicolonAfterCharacterReference();\n return this.consumed;\n }\n /**\n * Emit a named entity.\n * @param result The index of the entity in the decode tree.\n * @param valueLength Encoded value length (header plus any value words).\n * @param consumed The number of characters consumed.\n * @returns The number of characters consumed.\n */\n emitNamedEntityData(result, valueLength, consumed) {\n const { decodeTree } = this;\n this.emitCodePoint(valueLength === 1\n ? decodeTree[result] & BinTrieFlags.VALUE_MASK\n : decodeTree[result + 1], consumed);\n if (valueLength === 3) {\n // Emit the second UTF-16 code unit.\n this.emitCodePoint(decodeTree[result + 2], consumed);\n }\n return consumed;\n }\n /**\n * Signal to the parser that the end of the input was reached.\n *\n * Remaining data will be emitted and relevant errors will be produced.\n * @returns The number of characters consumed.\n */\n end() {\n switch (this.state) {\n case EntityDecoderState.NamedEntity: {\n // Emit a named entity if we have one.\n return this.result !== 0 &&\n (this.decodeMode !== DecodingMode.Attribute ||\n this.result === this.treeIndex)\n ? this.emitNotTerminatedNamedEntity()\n : 0;\n }\n // Otherwise, emit a numeric entity if we have one.\n case EntityDecoderState.NumericDecimal: {\n return this.emitNumericEntity(0, 2);\n }\n case EntityDecoderState.NumericHex: {\n return this.emitNumericEntity(0, 3);\n }\n case EntityDecoderState.NumericStart: {\n this.errors?.absenceOfDigitsInNumericCharacterReference(this.consumed);\n return 0;\n }\n default: {\n // EntityStart or unknown — return 0.\n return 0;\n }\n }\n }\n}\n/**\n * Determines the branch of the current node that is taken given the current\n * character. This function is used to traverse the trie.\n *\n * See `BinTrieFlags` for the branch-data layouts handled here.\n * @param decodeTree The trie.\n * @param current The current node's header word.\n * @param nodeIndex Index of the node's first branch-data word (the header\n * plus any value words have been skipped by the caller).\n * @param char The current character.\n * @returns The index of the next node, or -1 if no branch is taken.\n */\nexport function determineBranch(decodeTree, current, nodeIndex, char) {\n const branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;\n const jumpOffset = current & BinTrieFlags.JUMP_TABLE;\n // Case 1: Single branch or jump table (jumpOffset encodes the first/only char code).\n if (jumpOffset) {\n if (branchCount === 0) {\n // Single branch encoded inline in the jump offset bits.\n return char === jumpOffset ? nodeIndex : -1;\n }\n /*\n * Jump table: branchCount consecutive slots starting at jumpOffset.\n * Unsigned comparison handles both < 0 and >= branchCount in one check.\n */\n const slot = char - jumpOffset;\n if (slot >>> 0 >= branchCount)\n return -1;\n const stored = decodeTree[nodeIndex + slot];\n /*\n * 0 = empty slot (no branch); otherwise the child's offset from the\n * end of the branch array, +1 (end-relative pointers compress\n * better). `& 0xff_ff` mirrors the encoder's uint16 wrap for\n * backreferences to already-encoded nodes.\n */\n return stored === 0\n ? -1\n : (nodeIndex + branchCount + stored - 1) & 0xff_ff;\n }\n /*\n * Case 2: Packed dictionary. Linear scan — over 90% of dict nodes have\n * <= 4 branches in the HTML trie, where the constant-factor savings\n * dominate over binary search's asymptotic edge.\n */\n if (branchCount === 0)\n return -1;\n const packedKeySlots = (branchCount + 1) >> 1;\n const branchEnd = nodeIndex + packedKeySlots + branchCount;\n for (let index = 0; index < branchCount; index++) {\n const packed = decodeTree[nodeIndex + (index >> 1)];\n const key = (packed >> ((index & 1) << 3)) & 0xff;\n if (key === char) {\n const pointerIndex = nodeIndex + packedKeySlots + index;\n // Pointers are relative to the end of the branch data.\n return (branchEnd + decodeTree[pointerIndex]) & 0xff_ff;\n }\n // Keys are sorted; if we've passed `char`, no match is possible.\n if (key > char)\n return -1;\n }\n return -1;\n}\n/**\n * Read the decoded value from a trie node.\n * @param decodeTree The trie.\n * @param nodeIndex The index of the node.\n * @param valueLength The length of the value (1, 2, or 3).\n * @returns The decoded string.\n */\nfunction readTrieValue(decodeTree, nodeIndex, valueLength) {\n if (valueLength === 1) {\n return String.fromCharCode(decodeTree[nodeIndex] & BinTrieFlags.VALUE_MASK);\n }\n if (valueLength === 2) {\n return String.fromCharCode(decodeTree[nodeIndex + 1]);\n }\n return String.fromCharCode(decodeTree[nodeIndex + 1], decodeTree[nodeIndex + 2]);\n}\n/**\n * Parse a numeric entity (`&#DDD;` or `&#xHHH;`).\n *\n * Encodes the result as `(consumed << CONSUMED_SHIFT) | codepoint` (see\n * the packing comment at the top of the file; overlong entities spill\n * their length into `longNumericConsumed`). Returns 0 when no digits were\n * found.\n *\n * This is the sync counterpart of the streaming\n * `EntityDecoder#stateNumericDecimal` / `#stateNumericHex`. Digit parsing\n * matches those methods; only this packed result needs a value clamp.\n * @param input The input string.\n * @param numberStart Index of the `#` character.\n * @param inputLength Cached `input.length`.\n */\nfunction parseNumericEntity(input, numberStart, inputLength) {\n let offset = numberStart + 1; // Skip \"#\"\n let cp = 0;\n let digitStart = offset;\n /*\n * Separate decimal and hexadecimal loops: each multiplies by a constant\n * and runs a single digit test, instead of a per-character base check.\n */\n if (offset < inputLength &&\n (input.charCodeAt(offset) | TO_LOWER_BIT) === CharCodes.LOWER_X) {\n offset += 1;\n digitStart = offset;\n while (offset < inputLength) {\n const char = input.charCodeAt(offset);\n if (isNumber(char)) {\n cp = cp * 16 + (char - CharCodes.ZERO);\n }\n else if (isHexadecimalCharacter(char)) {\n cp = cp * 16 + ((char | TO_LOWER_BIT) - CharCodes.LOWER_A + 10);\n }\n else {\n break;\n }\n offset += 1;\n }\n }\n else {\n while (offset < inputLength) {\n const digit = input.charCodeAt(offset) - CharCodes.ZERO;\n if (digit >>> 0 > 9)\n break;\n cp = cp * 10 + digit;\n offset += 1;\n }\n }\n if (offset === digitStart)\n return 0;\n // Include the semicolon in consumed when present.\n if (offset < inputLength && input.charCodeAt(offset) === CharCodes.SEMI) {\n offset += 1;\n }\n /*\n * Clamp out-of-range values to 0x110000 so they fit the 21-bit field\n * and decode to U+FFFD. Lengths at or above CONSUMED_OVERFLOW use the\n * side channel described with the packing constants.\n */\n if (cp > 0x10_ff_ff)\n cp = 0x11_00_00;\n let consumed = offset - numberStart;\n if (consumed >= CONSUMED_OVERFLOW) {\n // eslint-disable-next-line unicorn/no-top-level-assignment-in-function -- deliberate side channel, see `longNumericConsumed`\n longNumericConsumed = consumed;\n consumed = CONSUMED_OVERFLOW;\n }\n return (consumed << CONSUMED_SHIFT) | cp;\n}\n/**\n * Decode all entities in `input` using the HTML trie.\n *\n * Hard-wired to `htmlDecodeTree`: the inline root navigation below assumes\n * the HTML root's jump-table shape, so this must not be generalized to\n * other tries (the XML trie's dictionary root would silently match no\n * entities — `decodeXML` has its own hand-coded fast path instead).\n * @param input The string to decode.\n * @param isStrict Only match semicolon-terminated entities.\n * @param isAttribute Whether to apply attribute-specific parsing rules (disallowing certain non-semicolon terminators).\n * @returns The decoded string.\n */\nfunction decodeWithTrie(input, isStrict, isAttribute) {\n const decodeTree = htmlDecodeTree;\n // Fast path: no entities at all — return input without any allocation.\n let offset = input.indexOf(\"&\");\n if (offset < 0)\n return input;\n const inputLength = input.length;\n /*\n * `chunkStart` marks the start of the next pending slice. Rejected\n * entities don't advance it, so consecutive rejections are stitched\n * into a single `slice` once a real match (or end of input) is hit.\n */\n let chunkStart = 0;\n let result = \"\";\n /*\n * Root navigation fields, hoisted out of the per-entity loop. The HTML\n * root is a multi-branch jump-table covering [A-Za-z]; see the inline\n * first-iteration comment below.\n */\n const root = decodeTree[0];\n const rootJumpOffset = root & BinTrieFlags.JUMP_TABLE;\n const rootBranchCount = (root & BinTrieFlags.BRANCH_LENGTH) >> 7;\n do {\n const entityStart = offset + 1;\n // Quick check: entity names must start with [A-Za-z], numeric with #.\n const firstChar = input.charCodeAt(entityStart);\n let consumed;\n let value;\n if (firstChar === CharCodes.NUM) {\n const packed = parseNumericEntity(input, entityStart, inputLength);\n consumed = unpackConsumed(packed);\n // In strict mode, require semicolon termination.\n if (isStrict &&\n consumed > 0 &&\n input.charCodeAt(entityStart + consumed - 1) !== CharCodes.SEMI) {\n consumed = 0;\n }\n value =\n consumed === 0\n ? \"\"\n : codePointToString(packed & CODE_POINT_MASK);\n }\n else if (isAlpha(firstChar)) {\n consumed = 0;\n value = \"\";\n /*\n * The generator guarantees a jump-table root. Consume the first\n * character directly, then walk from its child.\n */\n const rootSlotIndex = firstChar - rootJumpOffset;\n let nodeIndex;\n if (rootSlotIndex >>> 0 < rootBranchCount) {\n const stored = decodeTree[1 + rootSlotIndex];\n nodeIndex =\n stored === 0 ? -1 : (rootBranchCount + stored) & 0xff_ff;\n }\n else {\n nodeIndex = -1;\n }\n /*\n * Best legacy (no-semicolon) match so far, as trie coordinates.\n * Deferring `readTrieValue` to the end avoids allocating a\n * string for matches that longer matches supersede.\n */\n let bestNodeIndex = 0;\n let bestValueLength = 0;\n let current = nodeIndex < 0 ? 0 : decodeTree[nodeIndex];\n let index = entityStart + 1;\n /*\n * Walk the trie from the root child. The `trie` label lets the\n * inner descent and compact-run loops abandon the entity (and\n * fall through to the legacy/reject handling) directly.\n */\n trie: while (index < inputLength) {\n /*\n * Inline value-less jump tables and single branches. A miss\n * falls through to the recorded legacy match or rejection.\n */\n while (\n // Value-less, non-run node with a nonzero jump offset.\n (current &\n (BinTrieFlags.VALUE_LENGTH | BinTrieFlags.FLAG13)) ===\n 0 &&\n (current & BinTrieFlags.JUMP_TABLE) !== 0) {\n const jumpOffset = current & BinTrieFlags.JUMP_TABLE;\n const branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;\n if (branchCount === 0) {\n // Single branch encoded inline in the jump offset bits.\n if (input.charCodeAt(index) !== jumpOffset)\n break trie;\n nodeIndex += 1;\n }\n else {\n const slot = input.charCodeAt(index) - jumpOffset;\n if (slot >>> 0 >= branchCount)\n break trie;\n const stored = decodeTree[nodeIndex + 1 + slot];\n if (stored === 0)\n break trie;\n // End-relative: branch data ends at nodeIndex+1+branchCount.\n nodeIndex =\n (nodeIndex + branchCount + stored) & 0xff_ff;\n }\n current = decodeTree[nodeIndex];\n index += 1;\n /*\n * `charCodeAt` past the end returns NaN, which would\n * alias to slot 0 after `>>> 0` — bail out explicitly.\n */\n if (index >= inputLength)\n break trie;\n }\n // FLAG13 without a value marks a compact run.\n if ((current &\n (BinTrieFlags.VALUE_LENGTH | BinTrieFlags.FLAG13)) ===\n BinTrieFlags.FLAG13) {\n const runLength = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;\n // Check first char (stored in JUMP_TABLE bits).\n if (input.charCodeAt(index) !==\n (current & BinTrieFlags.JUMP_TABLE)) {\n // eslint-disable-next-line unicorn/no-break-in-nested-loop\n break;\n }\n index += 1;\n // Check remaining characters (packed two per uint16 word).\n const remaining = runLength - 1;\n let wordIndex = nodeIndex + 1;\n let charIndexInPacked = 0;\n /*\n * Process pairs: read one packed word, compare low byte then high byte.\n * No explicit bounds check needed — charCodeAt returns NaN for OOB,\n * which never equals an integer, so the mismatch break fires naturally.\n */\n for (; charIndexInPacked + 1 < remaining; charIndexInPacked += 2) {\n const packed = decodeTree[wordIndex];\n if (input.charCodeAt(index) !== (packed & 0xff))\n break trie;\n index += 1;\n if (input.charCodeAt(index) !== ((packed >> 8) & 0xff))\n break trie;\n index += 1;\n wordIndex += 1;\n }\n // Handle odd trailing char.\n if (charIndexInPacked < remaining) {\n if (input.charCodeAt(index) !==\n (decodeTree[wordIndex] & 0xff))\n // eslint-disable-next-line unicorn/no-break-in-nested-loop\n break;\n index += 1;\n }\n nodeIndex += 1 + (runLength >> 1);\n current = decodeTree[nodeIndex];\n // eslint-disable-next-line unicorn/no-break-in-nested-loop\n continue;\n }\n // Header plus out-of-line value words; 0 means no value.\n const valueLength = current >>> 14;\n const char = input.charCodeAt(index);\n /*\n * Check current node for a value before navigating.\n * This handles both: (a) values reached via compact runs on the\n * previous iteration, and (b) values at regular branch targets.\n */\n if (valueLength !== 0) {\n // If char is `;`, emit immediately.\n if (char === CharCodes.SEMI) {\n consumed = index - entityStart + 1;\n // Inline leaves carry the value in the low 13 bits.\n value =\n valueLength === 1\n ? String.fromCharCode(current & BinTrieFlags.VALUE_MASK)\n : readTrieValue(decodeTree, nodeIndex, valueLength);\n // eslint-disable-next-line unicorn/no-break-in-nested-loop\n break;\n }\n // Record non-terminated (legacy) match (FLAG13 clear = semicolon optional).\n if (!isStrict && (current & BinTrieFlags.FLAG13) === 0) {\n consumed = index - entityStart;\n bestNodeIndex = nodeIndex;\n bestValueLength = valueLength;\n }\n /*\n * A valueLength of 1 means the value is packed inline in the header\n * word — these are always leaf nodes with no branches, so we can\n * stop walking the trie.\n */\n // eslint-disable-next-line unicorn/no-break-in-nested-loop\n if (valueLength === 1)\n break;\n }\n // Navigate to the next node (valueLength || 1: skip past value words, minimum 1 for header).\n const next = determineBranch(decodeTree, current, nodeIndex + (valueLength || 1), char);\n // eslint-disable-next-line unicorn/no-break-in-nested-loop\n if (next < 0)\n break;\n nodeIndex = next;\n current = decodeTree[nodeIndex];\n index += 1;\n }\n /*\n * Post-loop: if the semicolon path didn't set value,\n * check for a final legacy match. The last navigation may\n * have landed on a legacy node whose value hasn't been\n * recorded yet (loop exited before the top-of-loop check\n * could run).\n */\n if (value === \"\") {\n const finalVL = current >>> 14;\n if (finalVL !== 0 &&\n !isStrict &&\n (current & BinTrieFlags.FLAG13) === 0) {\n consumed = index - entityStart;\n bestNodeIndex = nodeIndex;\n bestValueLength = finalVL;\n }\n if (consumed > 0) {\n value = readTrieValue(decodeTree, bestNodeIndex, bestValueLength);\n }\n }\n }\n else {\n consumed = 0;\n value = \"\";\n }\n /*\n * The attribute end-char rule (HTML spec §13.2.5.73) only applies to\n * unterminated *named* references. Semicolon-terminated entities and\n * numeric entities are always accepted, matching EntityDecoder behavior.\n *\n * When `attribute` is false (the common case), short-circuit skips all\n * the unterminated-named checks entirely.\n */\n if (consumed === 0 ||\n (isAttribute &&\n firstChar !== CharCodes.NUM &&\n input.charCodeAt(entityStart + consumed - 1) !==\n CharCodes.SEMI &&\n entityStart + consumed < inputLength &&\n isEntityInAttributeInvalidEnd(input.charCodeAt(entityStart + consumed)))) {\n // Rejected: leave `&` in the pending chunk, scan past it.\n offset = entityStart;\n }\n else {\n if (chunkStart < offset) {\n result += input.slice(chunkStart, offset);\n }\n result += value;\n offset = chunkStart = entityStart + consumed;\n }\n /*\n * Adjacent entities (`&x;&y;`) are common in entity-dense input;\n * checking the single character at `offset` first skips the\n * `indexOf` call (and its per-call overhead) for that case.\n */\n if (input.charCodeAt(offset) !== CharCodes.AMP) {\n offset = input.indexOf(\"&\", offset);\n }\n } while (offset >= 0);\n return result + input.slice(chunkStart);\n}\n/**\n * Decodes an HTML string.\n * @param htmlString The string to decode.\n * @param mode The decoding mode.\n * @returns The decoded string.\n */\nexport function decodeHTML(htmlString, mode = DecodingMode.Legacy) {\n return decodeWithTrie(htmlString, mode === DecodingMode.Strict, mode === DecodingMode.Attribute);\n}\n/**\n * Decodes an HTML string in an attribute.\n * @param htmlAttribute The string to decode.\n * @returns The decoded string.\n */\nexport function decodeHTMLAttribute(htmlAttribute) {\n return decodeWithTrie(htmlAttribute, false, true);\n}\n/**\n * Decodes an HTML string, requiring all entities to be terminated by a semicolon.\n * @param htmlString The string to decode.\n * @returns The decoded string.\n */\nexport function decodeHTMLStrict(htmlString) {\n return decodeWithTrie(htmlString, true, false);\n}\n/**\n * Decodes an XML string, requiring all entities to be terminated by a semicolon.\n *\n * Uses a hand-coded fast path for the 5 XML named entities (amp, lt, gt,\n * quot, apos) plus numeric entities, bypassing the trie entirely.\n * @param xmlString The string to decode.\n * @returns The decoded string.\n */\nexport function decodeXML(xmlString) {\n let offset = xmlString.indexOf(\"&\");\n if (offset < 0)\n return xmlString;\n let lastIndex = 0;\n let result = \"\";\n do {\n const start = offset + 1;\n let consumed = 0;\n let value = \"\";\n const c1 = xmlString.charCodeAt(start);\n if (c1 === CharCodes.NUM) {\n const packed = parseNumericEntity(xmlString, start, xmlString.length);\n consumed = unpackConsumed(packed);\n // XML is always strict — require semicolon.\n if (consumed === 0 ||\n xmlString.charCodeAt(start + consumed - 1) !== CharCodes.SEMI) {\n consumed = 0;\n }\n else {\n const codePoint = packed & CODE_POINT_MASK;\n // Nonzero BMP values below the surrogate range need no replacement.\n value =\n (codePoint - 1) >>> 0 < 0xd7_ff\n ? String.fromCharCode(codePoint)\n : String.fromCodePoint(replaceCodePointXML(codePoint));\n }\n }\n else {\n /* eslint-disable unicorn/no-break-in-nested-loop -- Keep XML name dispatch inline with the decode loop. */\n switch (c1) {\n // < / >\n case 0x6c:\n case 0x67: {\n if (xmlString.charCodeAt(start + 1) === 0x74 &&\n xmlString.charCodeAt(start + 2) === CharCodes.SEMI) {\n consumed = 3;\n value = c1 === 0x6c ? \"<\" : \">\";\n }\n break;\n }\n // & / '\n case 0x61: {\n const c2 = xmlString.charCodeAt(start + 1);\n if (c2 === 0x6d &&\n xmlString.charCodeAt(start + 2) === 0x70 &&\n xmlString.charCodeAt(start + 3) === CharCodes.SEMI) {\n consumed = 4;\n value = \"&\";\n }\n else if (c2 === 0x70 &&\n xmlString.charCodeAt(start + 2) === 0x6f &&\n xmlString.charCodeAt(start + 3) === 0x73 &&\n xmlString.charCodeAt(start + 4) === CharCodes.SEMI) {\n consumed = 5;\n value = \"'\";\n }\n break;\n }\n // "\n case 0x71: {\n if (xmlString.charCodeAt(start + 1) === 0x75 &&\n xmlString.charCodeAt(start + 2) === 0x6f &&\n xmlString.charCodeAt(start + 3) === 0x74 &&\n xmlString.charCodeAt(start + 4) === CharCodes.SEMI) {\n consumed = 5;\n value = '\"';\n }\n break;\n }\n }\n /* eslint-enable unicorn/no-break-in-nested-loop */\n }\n if (consumed > 0) {\n if (lastIndex < offset)\n result += xmlString.slice(lastIndex, offset);\n result += value;\n offset = lastIndex = start + consumed;\n }\n else {\n offset = start;\n }\n /*\n * Adjacent entities (`&x;&y;`) are common in entity-dense input;\n * checking the single character at `lastIndex` first skips the\n * `indexOf` call (and its per-call overhead) for that case.\n */\n offset =\n xmlString.charCodeAt(offset) === CharCodes.AMP\n ? offset\n : xmlString.indexOf(\"&\", offset);\n } while (offset >= 0);\n return result + xmlString.slice(lastIndex);\n}\nexport { replaceCodePoint, replaceCodePointXML, } from \"./decode-codepoint.js\";\n// Re-export for use by eg. htmlparser2\nexport { htmlDecodeTree } from \"./generated/decode-data-html.js\";\nexport { xmlDecodeTree } from \"./generated/decode-data-xml.js\";\n//# sourceMappingURL=decode.js.map","import { DecodingMode, EntityDecoder, htmlDecodeTree, xmlDecodeTree, } from \"entities/decode\";\nvar CharCodes;\n(function (CharCodes) {\n CharCodes[CharCodes[\"Tab\"] = 9] = \"Tab\";\n CharCodes[CharCodes[\"NewLine\"] = 10] = \"NewLine\";\n CharCodes[CharCodes[\"FormFeed\"] = 12] = \"FormFeed\";\n CharCodes[CharCodes[\"CarriageReturn\"] = 13] = \"CarriageReturn\";\n CharCodes[CharCodes[\"Space\"] = 32] = \"Space\";\n CharCodes[CharCodes[\"ExclamationMark\"] = 33] = \"ExclamationMark\";\n CharCodes[CharCodes[\"Number\"] = 35] = \"Number\";\n CharCodes[CharCodes[\"Amp\"] = 38] = \"Amp\";\n CharCodes[CharCodes[\"SingleQuote\"] = 39] = \"SingleQuote\";\n CharCodes[CharCodes[\"DoubleQuote\"] = 34] = \"DoubleQuote\";\n CharCodes[CharCodes[\"Dash\"] = 45] = \"Dash\";\n CharCodes[CharCodes[\"Slash\"] = 47] = \"Slash\";\n CharCodes[CharCodes[\"Zero\"] = 48] = \"Zero\";\n CharCodes[CharCodes[\"Nine\"] = 57] = \"Nine\";\n CharCodes[CharCodes[\"Semi\"] = 59] = \"Semi\";\n CharCodes[CharCodes[\"Lt\"] = 60] = \"Lt\";\n CharCodes[CharCodes[\"Eq\"] = 61] = \"Eq\";\n CharCodes[CharCodes[\"Gt\"] = 62] = \"Gt\";\n CharCodes[CharCodes[\"Questionmark\"] = 63] = \"Questionmark\";\n CharCodes[CharCodes[\"UpperA\"] = 65] = \"UpperA\";\n CharCodes[CharCodes[\"LowerA\"] = 97] = \"LowerA\";\n CharCodes[CharCodes[\"UpperF\"] = 70] = \"UpperF\";\n CharCodes[CharCodes[\"LowerF\"] = 102] = \"LowerF\";\n CharCodes[CharCodes[\"UpperZ\"] = 90] = \"UpperZ\";\n CharCodes[CharCodes[\"LowerZ\"] = 122] = \"LowerZ\";\n CharCodes[CharCodes[\"LowerX\"] = 120] = \"LowerX\";\n CharCodes[CharCodes[\"OpeningSquareBracket\"] = 91] = \"OpeningSquareBracket\";\n})(CharCodes || (CharCodes = {}));\n/** All the states the tokenizer can be in. */\nvar State;\n(function (State) {\n State[State[\"Text\"] = 1] = \"Text\";\n State[State[\"BeforeTagName\"] = 2] = \"BeforeTagName\";\n State[State[\"InTagName\"] = 3] = \"InTagName\";\n State[State[\"InSelfClosingTag\"] = 4] = \"InSelfClosingTag\";\n State[State[\"BeforeClosingTagName\"] = 5] = \"BeforeClosingTagName\";\n State[State[\"InClosingTagName\"] = 6] = \"InClosingTagName\";\n State[State[\"AfterClosingTagName\"] = 7] = \"AfterClosingTagName\";\n // Attributes\n State[State[\"BeforeAttributeName\"] = 8] = \"BeforeAttributeName\";\n State[State[\"InAttributeName\"] = 9] = \"InAttributeName\";\n State[State[\"AfterAttributeName\"] = 10] = \"AfterAttributeName\";\n State[State[\"BeforeAttributeValue\"] = 11] = \"BeforeAttributeValue\";\n State[State[\"InAttributeValueDq\"] = 12] = \"InAttributeValueDq\";\n State[State[\"InAttributeValueSq\"] = 13] = \"InAttributeValueSq\";\n State[State[\"InAttributeValueNq\"] = 14] = \"InAttributeValueNq\";\n // Declarations\n State[State[\"BeforeDeclaration\"] = 15] = \"BeforeDeclaration\";\n State[State[\"InDeclaration\"] = 16] = \"InDeclaration\";\n // Processing instructions\n State[State[\"InProcessingInstruction\"] = 17] = \"InProcessingInstruction\";\n // Comments & CDATA\n State[State[\"BeforeComment\"] = 18] = \"BeforeComment\";\n State[State[\"CDATASequence\"] = 19] = \"CDATASequence\";\n State[State[\"DeclarationSequence\"] = 20] = \"DeclarationSequence\";\n State[State[\"InSpecialComment\"] = 21] = \"InSpecialComment\";\n State[State[\"InCommentLike\"] = 22] = \"InCommentLike\";\n // Special tags\n State[State[\"SpecialStartSequence\"] = 23] = \"SpecialStartSequence\";\n State[State[\"InSpecialTag\"] = 24] = \"InSpecialTag\";\n State[State[\"InPlainText\"] = 25] = \"InPlainText\";\n State[State[\"InEntity\"] = 26] = \"InEntity\";\n})(State || (State = {}));\nfunction isWhitespace(c) {\n return (c === CharCodes.Space ||\n c === CharCodes.NewLine ||\n c === CharCodes.Tab ||\n c === CharCodes.FormFeed ||\n c === CharCodes.CarriageReturn);\n}\nfunction isEndOfTagSection(c) {\n return c === CharCodes.Slash || c === CharCodes.Gt || isWhitespace(c);\n}\nfunction isASCIIAlpha(c) {\n return ((c >= CharCodes.LowerA && c <= CharCodes.LowerZ) ||\n (c >= CharCodes.UpperA && c <= CharCodes.UpperZ));\n}\n/**\n * Quote style used for parsed attributes.\n */\nexport var QuoteType;\n(function (QuoteType) {\n QuoteType[QuoteType[\"NoValue\"] = 0] = \"NoValue\";\n QuoteType[QuoteType[\"Unquoted\"] = 1] = \"Unquoted\";\n QuoteType[QuoteType[\"Single\"] = 2] = \"Single\";\n QuoteType[QuoteType[\"Double\"] = 3] = \"Double\";\n})(QuoteType || (QuoteType = {}));\n/**\n * Sequences used to match longer strings.\n *\n * We don't have `Script`, `Style`, or `Title` here. Instead, we re-use the *End\n * sequences with an increased offset.\n */\nconst Sequences = {\n Empty: new Uint8Array(0),\n Cdata: new Uint8Array([0x43, 0x44, 0x41, 0x54, 0x41, 0x5b]), // CDATA[\n CdataEnd: new Uint8Array([0x5d, 0x5d, 0x3e]), // ]]>\n CommentEnd: new Uint8Array([0x2d, 0x2d, 0x21, 0x3e]), // `--!>`\n Doctype: new Uint8Array([0x64, 0x6f, 0x63, 0x74, 0x79, 0x70, 0x65]), // `doctype`\n IframeEnd: new Uint8Array([0x3c, 0x2f, 0x69, 0x66, 0x72, 0x61, 0x6d, 0x65]), // `</iframe`\n NoembedEnd: new Uint8Array([\n 0x3c, 0x2f, 0x6e, 0x6f, 0x65, 0x6d, 0x62, 0x65, 0x64,\n ]), // `</noembed`\n NoframesEnd: new Uint8Array([\n 0x3c, 0x2f, 0x6e, 0x6f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73,\n ]), // `</noframes`\n Plaintext: new Uint8Array([\n 0x3c, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74,\n ]), // `</plaintext`\n ScriptEnd: new Uint8Array([0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74]), // `</script`\n StyleEnd: new Uint8Array([0x3c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65]), // `</style`\n TitleEnd: new Uint8Array([0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65]), // `</title`\n TextareaEnd: new Uint8Array([\n 0x3c, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61,\n ]), // `</textarea`\n XmpEnd: new Uint8Array([0x3c, 0x2f, 0x78, 0x6d, 0x70]), // `</xmp`\n};\n/**\n * Maps the first lowercase character of an HTML tag name to the sequence\n * used for special-tag detection. All sequences share a common layout\n * where index 2 is the first tag-name character, so matching always\n * continues from offset 3.\n */\nconst specialStartSequences = new Map([\n [Sequences.IframeEnd[2], Sequences.IframeEnd],\n [Sequences.NoembedEnd[2], Sequences.NoembedEnd],\n [Sequences.Plaintext[2], Sequences.Plaintext],\n [Sequences.ScriptEnd[2], Sequences.ScriptEnd],\n [Sequences.TitleEnd[2], Sequences.TitleEnd],\n [Sequences.XmpEnd[2], Sequences.XmpEnd],\n]);\n/**\n * Tokenizer implementation used by `Parser`.\n */\nexport default class Tokenizer {\n cbs;\n /** The current state the tokenizer is in. */\n state = State.Text;\n /** The read buffer. */\n buffer = \"\";\n /** The beginning of the section that is currently being read. */\n sectionStart = 0;\n /** The index within the buffer that we are currently looking at. */\n index = 0;\n /** The start of the last entity. */\n entityStart = 0;\n /** Some behavior, eg. when decoding entities, is done while we are in another state. This keeps track of the other state type. */\n baseState = State.Text;\n /** For special parsing behavior inside of script and style tags. */\n isSpecial = false;\n /** Indicates whether the tokenizer has been paused. */\n running = true;\n /** The offset of the current buffer. */\n offset = 0;\n xmlMode;\n decodeEntities;\n recognizeSelfClosing;\n entityDecoder;\n constructor({ xmlMode = false, decodeEntities = true, recognizeSelfClosing = xmlMode, }, cbs) {\n this.cbs = cbs;\n this.xmlMode = xmlMode;\n this.decodeEntities = decodeEntities;\n this.recognizeSelfClosing = recognizeSelfClosing;\n this.entityDecoder = new EntityDecoder(xmlMode ? xmlDecodeTree : htmlDecodeTree, (cp, consumed) => this.emitCodePoint(cp, consumed));\n }\n reset() {\n this.state = State.Text;\n this.buffer = \"\";\n this.sectionStart = 0;\n this.index = 0;\n this.baseState = State.Text;\n this.isSpecial = false;\n this.currentSequence = Sequences.Empty;\n this.sequenceIndex = 0;\n this.running = true;\n this.offset = 0;\n }\n write(chunk) {\n this.offset += this.buffer.length;\n this.buffer = chunk;\n this.parse();\n }\n end() {\n if (this.running)\n this.finish();\n }\n pause() {\n this.running = false;\n }\n resume() {\n this.running = true;\n if (this.index < this.buffer.length + this.offset) {\n this.parse();\n }\n }\n stateText(c) {\n if (c === CharCodes.Lt ||\n (!this.decodeEntities && this.fastForwardTo(CharCodes.Lt))) {\n if (this.index > this.sectionStart) {\n this.cbs.ontext(this.sectionStart, this.index);\n }\n this.state = State.BeforeTagName;\n this.sectionStart = this.index;\n }\n else if (this.decodeEntities && c === CharCodes.Amp) {\n this.startEntity();\n }\n }\n currentSequence = Sequences.Empty;\n sequenceIndex = 0;\n enterTagBody() {\n if (this.currentSequence === Sequences.Plaintext) {\n this.currentSequence = Sequences.Empty;\n this.state = State.InPlainText;\n }\n else if (this.isSpecial) {\n this.state = State.InSpecialTag;\n this.sequenceIndex = 0;\n }\n else {\n this.state = State.Text;\n }\n }\n /**\n * Match the opening tag name against an HTML text-only tag sequence.\n *\n * Some tags share an initial prefix (`script`/`style`, `title`/`textarea`,\n * `noembed`/`noframes`), so we may switch to an alternate sequence at the\n * first distinguishing byte. On a successful full match we fall back to\n * the normal tag-name state; a later `>` will enter raw-text, RCDATA, or\n * plaintext mode based on `currentSequence` / `isSpecial`.\n * @param c Current character code point.\n */\n stateSpecialStartSequence(c) {\n const lower = c | 0x20;\n // Still matching — check for an alternate sequence at branch points.\n if (this.sequenceIndex < this.currentSequence.length) {\n if (lower === this.currentSequence[this.sequenceIndex]) {\n this.sequenceIndex++;\n return;\n }\n if (this.sequenceIndex === 3) {\n if (this.currentSequence === Sequences.ScriptEnd &&\n lower === Sequences.StyleEnd[3]) {\n this.currentSequence = Sequences.StyleEnd;\n this.sequenceIndex = 4;\n return;\n }\n if (this.currentSequence === Sequences.TitleEnd &&\n lower === Sequences.TextareaEnd[3]) {\n this.currentSequence = Sequences.TextareaEnd;\n this.sequenceIndex = 4;\n return;\n }\n }\n else if (this.sequenceIndex === 4 &&\n this.currentSequence === Sequences.NoembedEnd &&\n lower === Sequences.NoframesEnd[4]) {\n this.currentSequence = Sequences.NoframesEnd;\n this.sequenceIndex = 5;\n return;\n }\n }\n else if (isEndOfTagSection(c)) {\n // Full match on a valid tag boundary — keep the sequence.\n this.sequenceIndex = 0;\n this.state = State.InTagName;\n this.stateInTagName(c);\n return;\n }\n // No match — abandon special-tag detection.\n this.isSpecial = false;\n this.currentSequence = Sequences.Empty;\n this.sequenceIndex = 0;\n this.state = State.InTagName;\n this.stateInTagName(c);\n }\n stateCDATASequence(c) {\n if (c === Sequences.Cdata[this.sequenceIndex]) {\n if (++this.sequenceIndex === Sequences.Cdata.length) {\n this.state = State.InCommentLike;\n this.currentSequence = Sequences.CdataEnd;\n this.sequenceIndex = 0;\n this.sectionStart = this.index + 1;\n }\n }\n else {\n this.sequenceIndex = 0;\n if (this.xmlMode) {\n this.state = State.InDeclaration;\n this.stateInDeclaration(c); // Reconsume the character\n }\n else {\n this.state = State.InSpecialComment;\n this.stateInSpecialComment(c); // Reconsume the character\n }\n }\n }\n /**\n * When we wait for one specific character, we can speed things up\n * by skipping through the buffer until we find it.\n * @param c Current character code point.\n * @returns Whether the character was found.\n */\n fastForwardTo(c) {\n while (++this.index < this.buffer.length + this.offset) {\n if (this.buffer.charCodeAt(this.index - this.offset) === c) {\n return true;\n }\n }\n /*\n * We increment the index at the end of the `parse` loop,\n * so set it to `buffer.length - 1` here.\n *\n * TODO: Refactor `parse` to increment index before calling states.\n */\n this.index = this.buffer.length + this.offset - 1;\n return false;\n }\n /**\n * Emit a comment token and return to the text state.\n * @param offset Number of characters in the end sequence that have already been matched.\n */\n emitComment(offset) {\n this.cbs.oncomment(this.sectionStart, this.index, offset);\n this.sequenceIndex = 0;\n this.sectionStart = this.index + 1;\n this.state = State.Text;\n }\n /**\n * Comments and CDATA end with `-->` and `]]>`.\n *\n * Their common qualities are:\n * - Their end sequences have a distinct character they start with.\n * - That character is then repeated, so we have to check multiple repeats.\n * - All characters but the start character of the sequence can be skipped.\n * @param c Current character code point.\n */\n stateInCommentLike(c) {\n if (!this.xmlMode &&\n this.currentSequence === Sequences.CommentEnd &&\n this.sequenceIndex <= 1 &&\n /*\n * We're still at the very start of the comment: the only\n * characters consumed since `<!--` are the dashes that\n * advanced sequenceIndex (0 for `<!-->`, 1 for `<!--->`).\n */\n this.index === this.sectionStart + this.sequenceIndex &&\n c === CharCodes.Gt) {\n // Abruptly closed empty HTML comment.\n this.emitComment(this.sequenceIndex);\n }\n else if (this.currentSequence === Sequences.CommentEnd &&\n this.sequenceIndex === 2 &&\n c === CharCodes.Gt) {\n // `!` is optional here, so the same sequence also accepts `-->`.\n this.emitComment(2);\n }\n else if (this.currentSequence === Sequences.CommentEnd &&\n this.sequenceIndex === this.currentSequence.length - 1 &&\n c !== CharCodes.Gt) {\n this.sequenceIndex = Number(c === CharCodes.Dash);\n }\n else if (c === this.currentSequence[this.sequenceIndex]) {\n if (++this.sequenceIndex === this.currentSequence.length) {\n if (this.currentSequence === Sequences.CdataEnd) {\n this.cbs.oncdata(this.sectionStart, this.index, 2);\n }\n else {\n this.cbs.oncomment(this.sectionStart, this.index, 3);\n }\n this.sequenceIndex = 0;\n this.sectionStart = this.index + 1;\n this.state = State.Text;\n }\n }\n else if (this.sequenceIndex === 0) {\n // Fast-forward to the first character of the sequence\n if (this.fastForwardTo(this.currentSequence[0])) {\n this.sequenceIndex = 1;\n }\n }\n else if (c !== this.currentSequence[this.sequenceIndex - 1]) {\n // Allow long sequences, eg. --->, ]]]>\n this.sequenceIndex = 0;\n }\n }\n /**\n * HTML only allows ASCII alpha characters (a-z and A-Z) at the beginning of a tag name.\n *\n * XML allows a lot more characters here (@see https://www.w3.org/TR/REC-xml/#NT-NameStartChar).\n * We allow anything that wouldn't end the tag.\n * @param c Current character code point.\n */\n isTagStartChar(c) {\n return this.xmlMode ? !isEndOfTagSection(c) : isASCIIAlpha(c);\n }\n /**\n * Scan raw-text / RCDATA content for the matching end tag.\n *\n * For RCDATA tags (`<title>`, `<textarea>`) entities are decoded inline.\n * For raw-text tags (`<script>`, `<style>`, etc.) we fast-forward to `<`.\n * @param c Current character code point.\n */\n stateInSpecialTag(c) {\n if (this.sequenceIndex === this.currentSequence.length) {\n if (isEndOfTagSection(c)) {\n const endOfText = this.index - this.currentSequence.length;\n if (this.sectionStart < endOfText) {\n // Spoof the index so that reported locations match up.\n const actualIndex = this.index;\n this.index = endOfText;\n this.cbs.ontext(this.sectionStart, endOfText);\n this.index = actualIndex;\n }\n this.isSpecial = false;\n this.sectionStart = endOfText + 2; // Skip over the `</`\n this.stateInClosingTagName(c);\n return; // We are done; skip the rest of the function.\n }\n this.sequenceIndex = 0;\n }\n if ((c | 0x20) === this.currentSequence[this.sequenceIndex]) {\n this.sequenceIndex += 1;\n }\n else if (this.sequenceIndex === 0) {\n if (this.currentSequence === Sequences.TitleEnd ||\n this.currentSequence === Sequences.TextareaEnd) {\n // RCDATA tags have to parse entities while still looking for their end tag.\n if (this.decodeEntities && c === CharCodes.Amp) {\n this.startEntity();\n }\n }\n else if (this.fastForwardTo(CharCodes.Lt)) {\n // Outside of RCDATA tags, we can fast-forward.\n this.sequenceIndex = 1;\n }\n }\n else {\n // If we see a `<`, set the sequence index to 1; useful for eg. `<</script>`.\n this.sequenceIndex = Number(c === CharCodes.Lt);\n }\n }\n stateBeforeTagName(c) {\n if (c === CharCodes.ExclamationMark) {\n this.state = State.BeforeDeclaration;\n this.sectionStart = this.index + 1;\n }\n else if (c === CharCodes.Questionmark) {\n if (this.xmlMode) {\n this.state = State.InProcessingInstruction;\n this.sequenceIndex = 0;\n this.sectionStart = this.index + 1;\n }\n else {\n this.state = State.InSpecialComment;\n this.sectionStart = this.index;\n }\n }\n else if (this.isTagStartChar(c)) {\n this.sectionStart = this.index;\n const special = this.xmlMode || this.cbs.isInForeignContext?.()\n ? undefined\n : specialStartSequences.get(c | 0x20);\n if (special === undefined) {\n this.state = State.InTagName;\n }\n else {\n this.isSpecial = true;\n this.currentSequence = special;\n this.sequenceIndex = 3;\n this.state = State.SpecialStartSequence;\n }\n }\n else if (c === CharCodes.Slash) {\n this.state = State.BeforeClosingTagName;\n }\n else {\n this.state = State.Text;\n this.stateText(c);\n }\n }\n stateInTagName(c) {\n if (isEndOfTagSection(c)) {\n this.cbs.onopentagname(this.sectionStart, this.index);\n this.sectionStart = -1;\n this.state = State.BeforeAttributeName;\n this.stateBeforeAttributeName(c);\n }\n }\n stateBeforeClosingTagName(c) {\n if (isWhitespace(c)) {\n if (this.xmlMode) {\n // Ignore\n }\n else {\n this.state = State.InSpecialComment;\n this.sectionStart = this.index;\n }\n }\n else if (c === CharCodes.Gt) {\n this.state = State.Text;\n if (!this.xmlMode) {\n this.sectionStart = this.index + 1;\n }\n }\n else {\n this.state = this.isTagStartChar(c)\n ? State.InClosingTagName\n : State.InSpecialComment;\n this.sectionStart = this.index;\n }\n }\n stateInClosingTagName(c) {\n if (isEndOfTagSection(c)) {\n this.cbs.onclosetag(this.sectionStart, this.index);\n this.sectionStart = -1;\n this.state = State.AfterClosingTagName;\n this.stateAfterClosingTagName(c);\n }\n }\n stateAfterClosingTagName(c) {\n // Skip everything until \">\"\n if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {\n this.state = State.Text;\n this.sectionStart = this.index + 1;\n }\n }\n stateBeforeAttributeName(c) {\n if (c === CharCodes.Gt) {\n this.cbs.onopentagend(this.index);\n this.enterTagBody();\n this.sectionStart = this.index + 1;\n }\n else if (c === CharCodes.Slash) {\n this.state = State.InSelfClosingTag;\n }\n else if (!isWhitespace(c)) {\n this.state = State.InAttributeName;\n this.sectionStart = this.index;\n }\n }\n /**\n * Handle `/` before `>` in an opening tag.\n *\n * In HTML mode, text-only tags ignore the self-closing flag and still enter\n * their raw-text/RCDATA/plaintext state unless self-closing tags are being\n * recognized. In XML mode, or for ordinary tags, the tokenizer returns to\n * regular text parsing after emitting the self-closing callback.\n * @param c Current character code point.\n */\n stateInSelfClosingTag(c) {\n if (c === CharCodes.Gt) {\n this.cbs.onselfclosingtag(this.index);\n this.sectionStart = this.index + 1;\n if (!this.recognizeSelfClosing) {\n this.enterTagBody();\n return;\n }\n this.state = State.Text;\n this.isSpecial = false; // Reset special state, in case of self-closing special tags\n this.currentSequence = Sequences.Empty;\n }\n else if (!isWhitespace(c)) {\n this.state = State.BeforeAttributeName;\n this.stateBeforeAttributeName(c);\n }\n }\n stateInAttributeName(c) {\n if (c === CharCodes.Eq || isEndOfTagSection(c)) {\n this.cbs.onattribname(this.sectionStart, this.index);\n this.sectionStart = this.index;\n this.state = State.AfterAttributeName;\n this.stateAfterAttributeName(c);\n }\n }\n stateAfterAttributeName(c) {\n if (c === CharCodes.Eq) {\n this.state = State.BeforeAttributeValue;\n }\n else if (c === CharCodes.Slash || c === CharCodes.Gt) {\n this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);\n this.sectionStart = -1;\n this.state = State.BeforeAttributeName;\n this.stateBeforeAttributeName(c);\n }\n else if (!isWhitespace(c)) {\n this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);\n this.state = State.InAttributeName;\n this.sectionStart = this.index;\n }\n }\n stateBeforeAttributeValue(c) {\n if (c === CharCodes.DoubleQuote) {\n this.state = State.InAttributeValueDq;\n this.sectionStart = this.index + 1;\n }\n else if (c === CharCodes.SingleQuote) {\n this.state = State.InAttributeValueSq;\n this.sectionStart = this.index + 1;\n }\n else if (!isWhitespace(c)) {\n this.sectionStart = this.index;\n this.state = State.InAttributeValueNq;\n this.stateInAttributeValueNoQuotes(c); // Reconsume token\n }\n }\n handleInAttributeValue(c, quote) {\n if (c === quote ||\n (!this.decodeEntities && this.fastForwardTo(quote))) {\n this.cbs.onattribdata(this.sectionStart, this.index);\n this.sectionStart = -1;\n this.cbs.onattribend(quote === CharCodes.DoubleQuote\n ? QuoteType.Double\n : QuoteType.Single, this.index + 1);\n this.state = State.BeforeAttributeName;\n }\n else if (this.decodeEntities && c === CharCodes.Amp) {\n this.startEntity();\n }\n }\n stateInAttributeValueDoubleQuotes(c) {\n this.handleInAttributeValue(c, CharCodes.DoubleQuote);\n }\n stateInAttributeValueSingleQuotes(c) {\n this.handleInAttributeValue(c, CharCodes.SingleQuote);\n }\n stateInAttributeValueNoQuotes(c) {\n if (isWhitespace(c) || c === CharCodes.Gt) {\n this.cbs.onattribdata(this.sectionStart, this.index);\n this.sectionStart = -1;\n this.cbs.onattribend(QuoteType.Unquoted, this.index);\n this.state = State.BeforeAttributeName;\n this.stateBeforeAttributeName(c);\n }\n else if (this.decodeEntities && c === CharCodes.Amp) {\n this.startEntity();\n }\n }\n /**\n * Distinguish between CDATA, declarations, HTML comments, and HTML bogus\n * comments after `<!`.\n *\n * In HTML mode, only real comments and doctypes stay on declaration paths;\n * everything else becomes a bogus comment terminated by the next `>`.\n * @param c Current character code point.\n */\n stateBeforeDeclaration(c) {\n if (c === CharCodes.OpeningSquareBracket) {\n this.state = State.CDATASequence;\n this.sequenceIndex = 0;\n }\n else if (this.xmlMode) {\n this.state =\n c === CharCodes.Dash\n ? State.BeforeComment\n : State.InDeclaration;\n }\n else if ((c | 0x20) === Sequences.Doctype[0]) {\n this.state = State.DeclarationSequence;\n this.currentSequence = Sequences.Doctype;\n this.sequenceIndex = 1;\n }\n else if (c === CharCodes.Gt) {\n this.cbs.oncomment(this.sectionStart, this.index, 0);\n this.state = State.Text;\n this.sectionStart = this.index + 1;\n }\n else if (c === CharCodes.Dash) {\n this.state = State.BeforeComment;\n }\n else {\n this.state = State.InSpecialComment;\n }\n }\n /**\n * Continue matching `doctype` after `<!d`.\n *\n * A full `doctype` match stays on the declaration path; any other name falls\n * back to an HTML bogus comment, which matches browser behavior for\n * non-doctype `<!...>` constructs.\n * @param c Current character code point.\n */\n stateDeclarationSequence(c) {\n if (this.sequenceIndex === this.currentSequence.length) {\n this.state = State.InDeclaration;\n this.stateInDeclaration(c);\n }\n else if ((c | 0x20) === this.currentSequence[this.sequenceIndex]) {\n this.sequenceIndex += 1;\n }\n else if (c === CharCodes.Gt) {\n this.cbs.oncomment(this.sectionStart, this.index, 0);\n this.state = State.Text;\n this.sectionStart = this.index + 1;\n }\n else {\n this.state = State.InSpecialComment;\n }\n }\n stateInDeclaration(c) {\n if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {\n this.cbs.ondeclaration(this.sectionStart, this.index);\n this.state = State.Text;\n this.sectionStart = this.index + 1;\n }\n }\n /**\n * XML processing instructions (`<?...?>`).\n *\n * In HTML mode `<?` is routed to `InSpecialComment` instead, so this\n * state is only reachable in XML mode.\n * @param c Current character code point.\n */\n stateInProcessingInstruction(c) {\n if (c === CharCodes.Questionmark) {\n // Remember that we just consumed `?`, so the next `>` closes the PI.\n this.sequenceIndex = 1;\n }\n else if (c === CharCodes.Gt && this.sequenceIndex === 1) {\n this.cbs.onprocessinginstruction(this.sectionStart, this.index - 1);\n this.sequenceIndex = 0;\n this.state = State.Text;\n this.sectionStart = this.index + 1;\n }\n else {\n // Keep scanning for the next `?`, which can start a closing `?>`.\n this.sequenceIndex = Number(this.fastForwardTo(CharCodes.Questionmark));\n }\n }\n stateBeforeComment(c) {\n if (c === CharCodes.Dash) {\n this.state = State.InCommentLike;\n this.currentSequence = Sequences.CommentEnd;\n this.sequenceIndex = 0;\n this.sectionStart = this.index + 1;\n }\n else if (this.xmlMode) {\n this.state = State.InDeclaration;\n }\n else if (c === CharCodes.Gt) {\n this.cbs.oncomment(this.sectionStart, this.index, 0);\n this.state = State.Text;\n this.sectionStart = this.index + 1;\n }\n else {\n this.state = State.InSpecialComment;\n }\n }\n stateInSpecialComment(c) {\n if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {\n this.cbs.oncomment(this.sectionStart, this.index, 0);\n this.state = State.Text;\n this.sectionStart = this.index + 1;\n }\n }\n startEntity() {\n this.baseState = this.state;\n this.state = State.InEntity;\n this.entityStart = this.index;\n this.entityDecoder.startEntity(this.xmlMode\n ? DecodingMode.Strict\n : this.baseState === State.Text ||\n this.baseState === State.InSpecialTag\n ? DecodingMode.Legacy\n : DecodingMode.Attribute);\n }\n stateInEntity() {\n const indexInBuffer = this.index - this.offset;\n const length = this.entityDecoder.write(this.buffer, indexInBuffer);\n // If `length` is positive, we are done with the entity.\n if (length >= 0) {\n this.state = this.baseState;\n if (length === 0) {\n this.index -= 1;\n }\n }\n else {\n if (indexInBuffer < this.buffer.length &&\n this.buffer.charCodeAt(indexInBuffer) === CharCodes.Amp) {\n this.state = this.baseState;\n this.index -= 1;\n return;\n }\n // Mark buffer as consumed.\n this.index = this.offset + this.buffer.length - 1;\n }\n }\n /**\n * Remove data that has already been consumed from the buffer.\n */\n cleanup() {\n // If we are inside of text or attributes, emit what we already have.\n if (this.running && this.sectionStart !== this.index) {\n if (this.state === State.Text ||\n this.state === State.InPlainText ||\n (this.state === State.InSpecialTag && this.sequenceIndex === 0)) {\n this.cbs.ontext(this.sectionStart, this.index);\n this.sectionStart = this.index;\n }\n else if (this.state === State.InAttributeValueDq ||\n this.state === State.InAttributeValueSq ||\n this.state === State.InAttributeValueNq) {\n this.cbs.onattribdata(this.sectionStart, this.index);\n this.sectionStart = this.index;\n }\n }\n }\n shouldContinue() {\n return this.index < this.buffer.length + this.offset && this.running;\n }\n /**\n * Iterates through the buffer, calling the function corresponding to the current state.\n *\n * States that are more likely to be hit are higher up, as a performance improvement.\n */\n parse() {\n while (this.shouldContinue()) {\n const c = this.buffer.charCodeAt(this.index - this.offset);\n switch (this.state) {\n case State.Text: {\n this.stateText(c);\n break;\n }\n case State.InPlainText: {\n // Skip to end of buffer; cleanup() emits the text.\n this.index = this.buffer.length + this.offset - 1;\n break;\n }\n case State.SpecialStartSequence: {\n this.stateSpecialStartSequence(c);\n break;\n }\n case State.InSpecialTag: {\n this.stateInSpecialTag(c);\n break;\n }\n case State.CDATASequence: {\n this.stateCDATASequence(c);\n break;\n }\n case State.DeclarationSequence: {\n this.stateDeclarationSequence(c);\n break;\n }\n case State.InAttributeValueDq: {\n this.stateInAttributeValueDoubleQuotes(c);\n break;\n }\n case State.InAttributeName: {\n this.stateInAttributeName(c);\n break;\n }\n case State.InCommentLike: {\n this.stateInCommentLike(c);\n break;\n }\n case State.InSpecialComment: {\n this.stateInSpecialComment(c);\n break;\n }\n case State.BeforeAttributeName: {\n this.stateBeforeAttributeName(c);\n break;\n }\n case State.InTagName: {\n this.stateInTagName(c);\n break;\n }\n case State.InClosingTagName: {\n this.stateInClosingTagName(c);\n break;\n }\n case State.BeforeTagName: {\n this.stateBeforeTagName(c);\n break;\n }\n case State.AfterAttributeName: {\n this.stateAfterAttributeName(c);\n break;\n }\n case State.InAttributeValueSq: {\n this.stateInAttributeValueSingleQuotes(c);\n break;\n }\n case State.BeforeAttributeValue: {\n this.stateBeforeAttributeValue(c);\n break;\n }\n case State.BeforeClosingTagName: {\n this.stateBeforeClosingTagName(c);\n break;\n }\n case State.AfterClosingTagName: {\n this.stateAfterClosingTagName(c);\n break;\n }\n case State.InAttributeValueNq: {\n this.stateInAttributeValueNoQuotes(c);\n break;\n }\n case State.InSelfClosingTag: {\n this.stateInSelfClosingTag(c);\n break;\n }\n case State.InDeclaration: {\n this.stateInDeclaration(c);\n break;\n }\n case State.BeforeDeclaration: {\n this.stateBeforeDeclaration(c);\n break;\n }\n case State.BeforeComment: {\n this.stateBeforeComment(c);\n break;\n }\n case State.InProcessingInstruction: {\n this.stateInProcessingInstruction(c);\n break;\n }\n case State.InEntity: {\n this.stateInEntity();\n break;\n }\n }\n this.index++;\n }\n this.cleanup();\n }\n finish() {\n if (this.state === State.InEntity) {\n this.entityDecoder.end();\n this.state = this.baseState;\n }\n this.handleTrailingData();\n this.cbs.onend();\n }\n handleTrailingCommentLikeData(endIndex) {\n if (this.state !== State.InCommentLike) {\n return false;\n }\n if (this.currentSequence === Sequences.CdataEnd) {\n if (this.xmlMode) {\n if (this.sectionStart < endIndex) {\n this.cbs.oncdata(this.sectionStart, endIndex, 0);\n }\n }\n else {\n /* In HTML mode, unclosed CDATA is a bogus comment. */\n const cdataStart = this.sectionStart - Sequences.Cdata.length - 1;\n this.cbs.oncomment(cdataStart, endIndex, 0);\n }\n }\n else {\n const offset = this.xmlMode\n ? 0\n : Math.min(this.sequenceIndex, Sequences.CommentEnd.length - 1);\n this.cbs.oncomment(this.sectionStart, endIndex, offset);\n }\n return true;\n }\n handleTrailingMarkupDeclaration(endIndex) {\n if (this.xmlMode) {\n switch (this.state) {\n case State.InSpecialComment:\n case State.BeforeComment:\n case State.CDATASequence:\n case State.DeclarationSequence:\n case State.InDeclaration: {\n this.cbs.ontext(this.sectionStart, endIndex);\n return true;\n }\n default: {\n return false;\n }\n }\n }\n switch (this.state) {\n case State.BeforeDeclaration:\n case State.InSpecialComment:\n case State.BeforeComment:\n case State.CDATASequence: {\n this.cbs.oncomment(this.sectionStart, endIndex, 0);\n return true;\n }\n case State.DeclarationSequence: {\n if (this.sequenceIndex !== Sequences.Doctype.length) {\n this.cbs.oncomment(this.sectionStart, endIndex, 0);\n }\n return true;\n }\n case State.InDeclaration: {\n return true;\n }\n default: {\n return false;\n }\n }\n }\n /** Handle any trailing data. */\n handleTrailingData() {\n const endIndex = this.buffer.length + this.offset;\n if (this.handleTrailingCommentLikeData(endIndex) ||\n this.handleTrailingMarkupDeclaration(endIndex)) {\n return;\n }\n // If there is no remaining data, we are done.\n if (this.sectionStart >= endIndex) {\n return;\n }\n switch (this.state) {\n case State.InTagName:\n case State.BeforeAttributeName:\n case State.BeforeAttributeValue:\n case State.AfterAttributeName:\n case State.InAttributeName:\n case State.InAttributeValueSq:\n case State.InAttributeValueDq:\n case State.InAttributeValueNq:\n case State.InClosingTagName: {\n /*\n * If we are currently in an opening or closing tag, us not calling the\n * respective callback signals that the tag should be ignored.\n */\n break;\n }\n default: {\n this.cbs.ontext(this.sectionStart, endIndex);\n }\n }\n }\n emitCodePoint(cp, consumed) {\n if (this.baseState !== State.Text &&\n this.baseState !== State.InSpecialTag) {\n if (this.sectionStart < this.entityStart) {\n this.cbs.onattribdata(this.sectionStart, this.entityStart);\n }\n this.sectionStart = this.entityStart + consumed;\n this.index = this.sectionStart - 1;\n this.cbs.onattribentity(cp);\n }\n else {\n if (this.sectionStart < this.entityStart) {\n this.cbs.ontext(this.sectionStart, this.entityStart);\n }\n this.sectionStart = this.entityStart + consumed;\n this.index = this.sectionStart - 1;\n this.cbs.ontextentity(cp, this.sectionStart);\n }\n }\n}\n//# sourceMappingURL=Tokenizer.js.map","const { fromCodePoint } = String;\nimport Tokenizer, { QuoteType } from \"./Tokenizer.js\";\nconst formTags = new Set([\n \"input\",\n \"option\",\n \"optgroup\",\n \"select\",\n \"button\",\n \"datalist\",\n \"textarea\",\n]);\nconst pTag = new Set([\"p\"]);\nconst headingTags = new Set([\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"p\"]);\nconst tableSectionTags = new Set([\"thead\", \"tbody\"]);\nconst ddtTags = new Set([\"dd\", \"dt\"]);\nconst rtpTags = new Set([\"rt\", \"rp\"]);\nconst openImpliesClose = new Map([\n [\"tr\", new Set([\"tr\", \"th\", \"td\"])],\n [\"th\", new Set([\"th\"])],\n [\"td\", new Set([\"thead\", \"th\", \"td\"])],\n [\"body\", new Set([\"head\", \"link\", \"script\"])],\n [\"a\", new Set([\"a\"])],\n [\"li\", new Set([\"li\"])],\n [\"p\", pTag],\n [\"h1\", headingTags],\n [\"h2\", headingTags],\n [\"h3\", headingTags],\n [\"h4\", headingTags],\n [\"h5\", headingTags],\n [\"h6\", headingTags],\n [\"select\", formTags],\n [\"input\", formTags],\n [\"output\", formTags],\n [\"button\", formTags],\n [\"datalist\", formTags],\n [\"textarea\", formTags],\n [\"option\", new Set([\"option\"])],\n [\"optgroup\", new Set([\"optgroup\", \"option\"])],\n [\"dd\", ddtTags],\n [\"dt\", ddtTags],\n [\"address\", pTag],\n [\"article\", pTag],\n [\"aside\", pTag],\n [\"blockquote\", pTag],\n [\"details\", pTag],\n [\"div\", pTag],\n [\"dl\", pTag],\n [\"fieldset\", pTag],\n [\"figcaption\", pTag],\n [\"figure\", pTag],\n [\"footer\", pTag],\n [\"form\", pTag],\n [\"header\", pTag],\n [\"hr\", pTag],\n [\"main\", pTag],\n [\"nav\", pTag],\n [\"ol\", pTag],\n [\"pre\", pTag],\n [\"section\", pTag],\n [\"table\", pTag],\n [\"ul\", pTag],\n [\"rt\", rtpTags],\n [\"rp\", rtpTags],\n [\"tbody\", tableSectionTags],\n [\"tfoot\", tableSectionTags],\n]);\nconst DOCUMENT_TYPE = \"doctype\";\nconst voidElements = new Set([\n \"area\",\n \"base\",\n \"basefont\",\n \"br\",\n \"col\",\n \"command\",\n \"embed\",\n \"frame\",\n \"hr\",\n \"img\",\n \"input\",\n \"isindex\",\n \"keygen\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\",\n]);\nconst foreignContextElements = new Set([\"math\", \"svg\"]);\n/**\n * Elements that can be used to integrate HTML content within foreign namespaces (e.g., SVG or MathML).\n *\n * Entries must use the SVG-adjusted casing (e.g. \"foreignObject\" not\n * \"foreignobject\") since they are compared against adjusted tag names.\n */\nconst htmlIntegrationElements = new Set([\n \"mi\",\n \"mo\",\n \"mn\",\n \"ms\",\n \"mtext\",\n \"annotation-xml\",\n \"foreignObject\",\n \"desc\",\n \"title\",\n]);\nconst svgTagNameAdjustments = new Map([\n [\"altglyph\", \"altGlyph\"],\n [\"altglyphdef\", \"altGlyphDef\"],\n [\"altglyphitem\", \"altGlyphItem\"],\n [\"animatecolor\", \"animateColor\"],\n [\"animatemotion\", \"animateMotion\"],\n [\"animatetransform\", \"animateTransform\"],\n [\"clippath\", \"clipPath\"],\n [\"feblend\", \"feBlend\"],\n [\"fecolormatrix\", \"feColorMatrix\"],\n [\"fecomponenttransfer\", \"feComponentTransfer\"],\n [\"fecomposite\", \"feComposite\"],\n [\"feconvolvematrix\", \"feConvolveMatrix\"],\n [\"fediffuselighting\", \"feDiffuseLighting\"],\n [\"fedisplacementmap\", \"feDisplacementMap\"],\n [\"fedistantlight\", \"feDistantLight\"],\n [\"fedropshadow\", \"feDropShadow\"],\n [\"feflood\", \"feFlood\"],\n [\"fefunca\", \"feFuncA\"],\n [\"fefuncb\", \"feFuncB\"],\n [\"fefuncg\", \"feFuncG\"],\n [\"fefuncr\", \"feFuncR\"],\n [\"fegaussianblur\", \"feGaussianBlur\"],\n [\"feimage\", \"feImage\"],\n [\"femerge\", \"feMerge\"],\n [\"femergenode\", \"feMergeNode\"],\n [\"femorphology\", \"feMorphology\"],\n [\"feoffset\", \"feOffset\"],\n [\"fepointlight\", \"fePointLight\"],\n [\"fespecularlighting\", \"feSpecularLighting\"],\n [\"fespotlight\", \"feSpotLight\"],\n [\"fetile\", \"feTile\"],\n [\"feturbulence\", \"feTurbulence\"],\n [\"foreignobject\", \"foreignObject\"],\n [\"glyphref\", \"glyphRef\"],\n [\"lineargradient\", \"linearGradient\"],\n [\"radialgradient\", \"radialGradient\"],\n [\"textpath\", \"textPath\"],\n]);\nvar ForeignContext;\n(function (ForeignContext) {\n ForeignContext[ForeignContext[\"None\"] = 0] = \"None\";\n ForeignContext[ForeignContext[\"Svg\"] = 1] = \"Svg\";\n ForeignContext[ForeignContext[\"MathML\"] = 2] = \"MathML\";\n})(ForeignContext || (ForeignContext = {}));\nconst reNameEnd = /\\s|\\//;\n/**\n * Incremental parser implementation.\n */\nexport class Parser {\n options;\n /** The start index of the last event. */\n startIndex = 0;\n /** The end index of the last event. */\n endIndex = 0;\n /**\n * Store the start index of the current open tag,\n * so we can update the start index for attributes.\n */\n openTagStart = 0;\n tagname = \"\";\n attribname = \"\";\n attribvalue = \"\";\n attribs = null;\n stack = [];\n foreignContext;\n cbs;\n lowerCaseTagNames;\n lowerCaseAttributeNames;\n recognizeSelfClosing;\n /** We are parsing HTML. Inverse of the `xmlMode` option. */\n htmlMode;\n tokenizer;\n buffers = [];\n bufferOffset = 0;\n /** The index of the last written buffer. Used when resuming after a `pause()`. */\n writeIndex = 0;\n /** Indicates whether the parser has finished running / `.end` has been called. */\n ended = false;\n constructor(cbs, options = {}) {\n this.options = options;\n this.cbs = cbs ?? {};\n this.htmlMode = !this.options.xmlMode;\n this.lowerCaseTagNames = options.lowerCaseTags ?? this.htmlMode;\n this.lowerCaseAttributeNames =\n options.lowerCaseAttributeNames ?? this.htmlMode;\n this.recognizeSelfClosing =\n options.recognizeSelfClosing ?? !this.htmlMode;\n this.tokenizer = new (options.Tokenizer ?? Tokenizer)(this.options, this);\n this.foreignContext = [ForeignContext.None];\n this.cbs.onparserinit?.(this);\n }\n // Tokenizer event handlers\n /**\n * @param start Start index for the current parser event.\n * @param endIndex End index for the current parser event.\n * @internal\n */\n ontext(start, endIndex) {\n const data = this.getSlice(start, endIndex);\n this.endIndex = endIndex - 1;\n this.cbs.ontext?.(data);\n this.startIndex = endIndex;\n }\n /**\n * @param cp Current Unicode code point.\n * @param endIndex End index for the current parser event.\n * @internal\n */\n ontextentity(cp, endIndex) {\n this.endIndex = endIndex - 1;\n this.cbs.ontext?.(fromCodePoint(cp));\n this.startIndex = endIndex;\n }\n /** @internal */\n isInForeignContext() {\n return this.foreignContext[0] !== ForeignContext.None;\n }\n /**\n * Checks if the current tag is a void element. Override this if you want\n * to specify your own additional void elements.\n * @param name Name of the pseudo selector.\n */\n isVoidElement(name) {\n return this.htmlMode && voidElements.has(name);\n }\n /**\n * Read a tag name from the buffer.\n *\n * When `lowerCaseTagNames` is enabled (the default in HTML mode), the name\n * is lowercased and may be adjusted for SVG casing or the `image` → `img`\n * alias.\n * @param start Start index of the tag name in the buffer.\n * @param endIndex End index of the tag name in the buffer.\n */\n readTagName(start, endIndex) {\n const name = this.lowerCaseTagNames\n ? this.getSlice(start, endIndex).toLowerCase()\n : this.getSlice(start, endIndex);\n if (!(this.lowerCaseTagNames && this.htmlMode)) {\n return name;\n }\n if (this.foreignContext[0] === ForeignContext.Svg) {\n return svgTagNameAdjustments.get(name) ?? name;\n }\n /*\n * Closing tags for SVG elements inside HTML integration points\n * (e.g. </foreignObject> while inside its own content) need case\n * adjustment so the name matches what was pushed to the stack.\n * `foreignContext.length > 1` means a foreign ancestor exists —\n * the base [None] entry plus at least one pushed context.\n */\n if (this.foreignContext.length > 1) {\n const adjusted = svgTagNameAdjustments.get(name);\n if (adjusted !== undefined && this.stack.includes(adjusted)) {\n return adjusted;\n }\n }\n if (!this.isInForeignContext()) {\n return name === \"image\" ? \"img\" : name;\n }\n return name;\n }\n /**\n * @param start Start index for the current parser event.\n * @param endIndex End index for the current parser event.\n * @internal\n */\n onopentagname(start, endIndex) {\n this.endIndex = endIndex;\n this.emitOpenTag(this.readTagName(start, endIndex));\n }\n emitOpenTag(name) {\n this.openTagStart = this.startIndex;\n this.tagname = name;\n /*\n * The spec ignores a second <form> when one is already open.\n * Setting tagname to \"\" suppresses all downstream effects: attribs\n * stays null so endOpenTag is a no-op, and closeCurrentTag can't\n * match \"\" on the stack.\n */\n if (this.htmlMode && name === \"form\" && this.stack.includes(\"form\")) {\n this.tagname = \"\";\n return;\n }\n const impliesClose = this.htmlMode && openImpliesClose.get(name);\n if (impliesClose) {\n while (this.stack.length > 0 && impliesClose.has(this.stack[0])) {\n this.popElement(true);\n }\n }\n if (!this.isVoidElement(name)) {\n this.stack.unshift(name);\n if (this.htmlMode) {\n if (name === \"svg\") {\n this.foreignContext.unshift(ForeignContext.Svg);\n }\n else if (name === \"math\") {\n this.foreignContext.unshift(ForeignContext.MathML);\n }\n else if (htmlIntegrationElements.has(name)) {\n this.foreignContext.unshift(ForeignContext.None);\n }\n }\n }\n this.cbs.onopentagname?.(name);\n if (this.cbs.onopentag)\n this.attribs = {};\n }\n endOpenTag(isImplied) {\n this.startIndex = this.openTagStart;\n if (this.attribs) {\n this.cbs.onopentag?.(this.tagname, this.attribs, isImplied);\n this.attribs = null;\n }\n if (this.cbs.onclosetag && this.isVoidElement(this.tagname)) {\n this.cbs.onclosetag(this.tagname, true);\n }\n this.tagname = \"\";\n }\n /**\n * @param endIndex End index for the current parser event.\n * @internal\n */\n onopentagend(endIndex) {\n this.endIndex = endIndex;\n this.endOpenTag(false);\n // Set `startIndex` for next node\n this.startIndex = endIndex + 1;\n }\n /**\n * @param start Start index for the current parser event.\n * @param endIndex End index for the current parser event.\n * @internal\n */\n onclosetag(start, endIndex) {\n this.endIndex = endIndex;\n const name = this.readTagName(start, endIndex);\n if (!this.isVoidElement(name)) {\n const pos = this.stack.indexOf(name);\n if (pos !== -1) {\n for (let index = 0; index < pos; index++) {\n this.popElement(true);\n }\n this.popElement(false);\n }\n else if (this.htmlMode && name === \"p\") {\n // Implicit open before close\n this.emitOpenTag(\"p\");\n this.closeCurrentTag(true);\n }\n }\n else if (this.htmlMode && name === \"br\") {\n // We can't use `emitOpenTag` for implicit open, as `br` would be implicitly closed.\n this.cbs.onopentagname?.(\"br\");\n this.cbs.onopentag?.(\"br\", {}, true);\n this.cbs.onclosetag?.(\"br\", false);\n }\n // Set `startIndex` for next node\n this.startIndex = endIndex + 1;\n }\n /**\n * @param endIndex End index for the current parser event.\n * @internal\n */\n onselfclosingtag(endIndex) {\n this.endIndex = endIndex;\n if (this.recognizeSelfClosing || this.isInForeignContext()) {\n this.closeCurrentTag(false);\n // Set `startIndex` for next node\n this.startIndex = endIndex + 1;\n }\n else {\n // Ignore the fact that the tag is self-closing.\n this.onopentagend(endIndex);\n }\n }\n /**\n * Pop the top element off the stack, emit a close event, and maintain\n * the foreign context stack.\n * @param implied Whether this close is implied (not from an explicit end tag).\n */\n popElement(implied) {\n // biome-ignore lint/style/noNonNullAssertion: The element is guaranteed to exist.\n const element = this.stack.shift();\n if (this.htmlMode &&\n (foreignContextElements.has(element) ||\n htmlIntegrationElements.has(element))) {\n this.foreignContext.shift();\n }\n this.cbs.onclosetag?.(element, implied);\n }\n closeCurrentTag(isOpenImplied) {\n const name = this.tagname;\n this.endOpenTag(isOpenImplied);\n // Self-closing tags will be on the top of the stack\n if (this.stack[0] === name) {\n this.popElement(!isOpenImplied);\n }\n }\n /**\n * @param start Start index for the current parser event.\n * @param endIndex End index for the current parser event.\n * @internal\n */\n onattribname(start, endIndex) {\n this.startIndex = start;\n const name = this.getSlice(start, endIndex);\n this.attribname = this.lowerCaseAttributeNames\n ? name.toLowerCase()\n : name;\n }\n /**\n * @param start Start index for the current parser event.\n * @param endIndex End index for the current parser event.\n * @internal\n */\n onattribdata(start, endIndex) {\n this.attribvalue += this.getSlice(start, endIndex);\n }\n /**\n * @param cp Current Unicode code point.\n * @internal\n */\n onattribentity(cp) {\n this.attribvalue += fromCodePoint(cp);\n }\n /**\n * @param quote Quote type used for the current attribute.\n * @param endIndex End index for the current parser event.\n * @internal\n */\n onattribend(quote, endIndex) {\n this.endIndex = endIndex;\n this.cbs.onattribute?.(this.attribname, this.attribvalue, quote === QuoteType.Double\n ? '\"'\n : quote === QuoteType.Single\n ? \"'\"\n : quote === QuoteType.NoValue\n ? undefined\n : null);\n if (this.attribs && !Object.hasOwn(this.attribs, this.attribname)) {\n this.attribs[this.attribname] = this.attribvalue;\n }\n this.attribvalue = \"\";\n }\n getInstructionName(value) {\n const index = value.search(reNameEnd);\n let name = index < 0 ? value : value.substr(0, index);\n if (this.lowerCaseTagNames) {\n name = name.toLowerCase();\n }\n return name;\n }\n /**\n * @param start Start index for the current parser event.\n * @param endIndex End index for the current parser event.\n * @internal\n */\n ondeclaration(start, endIndex) {\n this.endIndex = endIndex;\n const value = this.getSlice(start, endIndex);\n if (this.cbs.onprocessinginstruction) {\n /*\n * In HTML mode, ondeclaration is only reached for DOCTYPE\n * (the tokenizer routes everything else to bogus comments).\n */\n const name = this.htmlMode\n ? this.lowerCaseTagNames\n ? DOCUMENT_TYPE\n : value.slice(0, DOCUMENT_TYPE.length)\n : this.getInstructionName(value);\n this.cbs.onprocessinginstruction(`!${name}`, `!${value}`);\n }\n // Set `startIndex` for next node\n this.startIndex = endIndex + 1;\n }\n /**\n * @param start Start index for the current parser event.\n * @param endIndex End index for the current parser event.\n * @internal\n */\n onprocessinginstruction(start, endIndex) {\n this.endIndex = endIndex;\n const value = this.getSlice(start, endIndex);\n if (this.cbs.onprocessinginstruction) {\n const name = this.getInstructionName(value);\n this.cbs.onprocessinginstruction(`?${name}`, `?${value}`);\n }\n // Set `startIndex` for next node\n this.startIndex = endIndex + 1;\n }\n /**\n * @param start Start index for the current parser event.\n * @param endIndex End index for the current parser event.\n * @param offset Offset applied when computing parser indices.\n * @internal\n */\n oncomment(start, endIndex, offset) {\n this.endIndex = endIndex;\n this.cbs.oncomment?.(this.getSlice(start, endIndex - offset));\n this.cbs.oncommentend?.();\n // Set `startIndex` for next node\n this.startIndex = endIndex + 1;\n }\n /**\n * @param start Start index for the current parser event.\n * @param endIndex End index for the current parser event.\n * @param offset Offset applied when computing parser indices.\n * @internal\n */\n oncdata(start, endIndex, offset) {\n this.endIndex = endIndex;\n const value = this.getSlice(start, endIndex - offset);\n if (!this.htmlMode || this.options.recognizeCDATA) {\n this.cbs.oncdatastart?.();\n this.cbs.ontext?.(value);\n this.cbs.oncdataend?.();\n }\n else if (this.isInForeignContext()) {\n this.cbs.ontext?.(value);\n }\n else {\n this.cbs.oncomment?.(`[CDATA[${value}]]`);\n this.cbs.oncommentend?.();\n }\n // Set `startIndex` for next node\n this.startIndex = endIndex + 1;\n }\n /** @internal */\n onend() {\n if (this.cbs.onclosetag) {\n // Set the end index for all remaining tags\n this.endIndex = this.startIndex;\n for (let index = 0; index < this.stack.length; index++) {\n this.cbs.onclosetag(this.stack[index], true);\n }\n }\n this.cbs.onend?.();\n }\n /**\n * Resets the parser to a blank state, ready to parse a new HTML document\n */\n reset() {\n this.cbs.onreset?.();\n this.tokenizer.reset();\n this.tagname = \"\";\n this.attribname = \"\";\n this.attribvalue = \"\";\n this.attribs = null;\n this.stack.length = 0;\n this.startIndex = 0;\n this.endIndex = 0;\n this.cbs.onparserinit?.(this);\n this.buffers.length = 0;\n this.foreignContext.length = 0;\n this.foreignContext.unshift(ForeignContext.None);\n this.bufferOffset = 0;\n this.writeIndex = 0;\n this.ended = false;\n }\n /**\n * Resets the parser, then parses a complete document and\n * pushes it to the handler.\n * @param data Document to parse.\n */\n parseComplete(data) {\n this.reset();\n this.end(data);\n }\n getSlice(start, end) {\n if (start === end) {\n return \"\";\n }\n while (start - this.bufferOffset >= this.buffers[0].length) {\n this.shiftBuffer();\n }\n let slice = this.buffers[0].slice(start - this.bufferOffset, end - this.bufferOffset);\n while (end - this.bufferOffset > this.buffers[0].length) {\n this.shiftBuffer();\n slice += this.buffers[0].slice(0, end - this.bufferOffset);\n }\n return slice;\n }\n shiftBuffer() {\n this.bufferOffset += this.buffers[0].length;\n this.writeIndex--;\n this.buffers.shift();\n }\n /**\n * Parses a chunk of data and calls the corresponding callbacks.\n * @param chunk Chunk to parse.\n */\n write(chunk) {\n if (this.ended) {\n this.cbs.onerror?.(new Error(\".write() after done!\"));\n return;\n }\n this.buffers.push(chunk);\n if (this.tokenizer.running) {\n this.tokenizer.write(chunk);\n this.writeIndex++;\n }\n }\n /**\n * Parses the end of the buffer and clears the stack, calls onend.\n * @param chunk Optional final chunk to parse.\n */\n end(chunk) {\n if (this.ended) {\n this.cbs.onerror?.(new Error(\".end() after done!\"));\n return;\n }\n if (chunk)\n this.write(chunk);\n this.ended = true;\n this.tokenizer.end();\n }\n /**\n * Pauses parsing. The parser won't emit events until `resume` is called.\n */\n pause() {\n this.tokenizer.pause();\n }\n /**\n * Resumes parsing after `pause` was called.\n */\n resume() {\n this.tokenizer.resume();\n while (this.tokenizer.running &&\n this.writeIndex < this.buffers.length) {\n this.tokenizer.write(this.buffers[this.writeIndex++]);\n }\n if (this.ended)\n this.tokenizer.end();\n }\n}\n//# sourceMappingURL=Parser.js.map","/** Types of elements found in htmlparser2's DOM */\nexport var ElementType;\n(function (ElementType) {\n /** Type for the root element of a document */\n ElementType[\"Root\"] = \"root\";\n /** Type for Text */\n ElementType[\"Text\"] = \"text\";\n /** Type for <? ... ?> */\n ElementType[\"Directive\"] = \"directive\";\n /** Type for <!-- ... --> */\n ElementType[\"Comment\"] = \"comment\";\n /** Type for <script> tags */\n ElementType[\"Script\"] = \"script\";\n /** Type for <style> tags */\n ElementType[\"Style\"] = \"style\";\n /** Type for Any tag */\n ElementType[\"Tag\"] = \"tag\";\n /** Type for <![CDATA[ ... ]]> */\n ElementType[\"CDATA\"] = \"cdata\";\n /** Type for <!doctype ...> */\n ElementType[\"Doctype\"] = \"doctype\";\n})(ElementType || (ElementType = {}));\n/**\n * Tests whether an element is a tag or not.\n * @param element Element to test\n * @param element.type Node type discriminator to check.\n */\nexport function isTag(element) {\n return (element.type === ElementType.Tag ||\n element.type === ElementType.Script ||\n element.type === ElementType.Style);\n}\n// Exports for backwards compatibility\n/** Type for the root element of a document */\n// eslint-disable-next-line prefer-destructuring\nexport const Root = ElementType.Root;\n/** Type for Text */\n// eslint-disable-next-line prefer-destructuring\nexport const Text = ElementType.Text;\n/** Type for <? ... ?> */\n// eslint-disable-next-line prefer-destructuring\nexport const Directive = ElementType.Directive;\n/** Type for <!-- ... --> */\n// eslint-disable-next-line prefer-destructuring\nexport const Comment = ElementType.Comment;\n/** Type for <script> tags */\n// eslint-disable-next-line prefer-destructuring\nexport const Script = ElementType.Script;\n/** Type for <style> tags */\n// eslint-disable-next-line prefer-destructuring\nexport const Style = ElementType.Style;\n/** Type for Any tag */\n// eslint-disable-next-line prefer-destructuring\nexport const Tag = ElementType.Tag;\n/** Type for <![CDATA[ ... ]]> */\n// eslint-disable-next-line prefer-destructuring\nexport const CDATA = ElementType.CDATA;\n/** Type for <!doctype ...> */\n// eslint-disable-next-line prefer-destructuring\nexport const Doctype = ElementType.Doctype;\n","import { ElementType, isTag as isTagRaw } from \"domelementtype\";\n/**\n * This object will be used as the prototype for Nodes when creating a\n * DOM-Level-1-compliant structure.\n */\nexport class Node {\n /** Parent of the node */\n parent = null;\n /** Previous sibling */\n prev = null;\n /** Next sibling */\n next = null;\n /** The start index of the node. Requires `withStartIndices` on the handler to be `true. */\n startIndex = null;\n /** The end index of the node. Requires `withEndIndices` on the handler to be `true. */\n endIndex = null;\n // Read-write aliases for properties\n /**\n * Same as {@link parent}.\n * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n */\n get parentNode() {\n return this.parent;\n }\n set parentNode(parent) {\n this.parent = parent;\n }\n /**\n * Same as {@link prev}.\n * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n */\n get previousSibling() {\n return this.prev;\n }\n set previousSibling(previous) {\n this.prev = previous;\n }\n /**\n * Same as {@link next}.\n * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n */\n get nextSibling() {\n return this.next;\n }\n set nextSibling(next) {\n this.next = next;\n }\n /**\n * Clone this node, and optionally its children.\n * @param recursive Clone child nodes as well.\n * @returns A clone of the node.\n */\n cloneNode(recursive = false) {\n return cloneNode(this, recursive);\n }\n}\n/**\n * A node that contains some data.\n */\nexport class DataNode extends Node {\n data;\n /**\n * @param data The content of the data node\n */\n constructor(data) {\n super();\n this.data = data;\n }\n /**\n * Same as {@link data}.\n * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n */\n get nodeValue() {\n return this.data;\n }\n set nodeValue(data) {\n this.data = data;\n }\n}\n/**\n * Text within the document.\n */\nexport class Text extends DataNode {\n type = ElementType.Text;\n get nodeType() {\n return 3;\n }\n}\n/**\n * Comments within the document.\n */\nexport class Comment extends DataNode {\n type = ElementType.Comment;\n get nodeType() {\n return 8;\n }\n}\n/**\n * Processing instructions, including doc types.\n */\nexport class ProcessingInstruction extends DataNode {\n type = ElementType.Directive;\n name;\n constructor(name, data) {\n super(data);\n this.name = name;\n }\n get nodeType() {\n return 1;\n }\n /** If this is a doctype, the document type name (parse5 only). */\n \"x-name\";\n /** If this is a doctype, the document type public identifier (parse5 only). */\n \"x-publicId\";\n /** If this is a doctype, the document type system identifier (parse5 only). */\n \"x-systemId\";\n}\n/**\n * A node that can have children.\n */\nexport class NodeWithChildren extends Node {\n children;\n /**\n * @param children Children of the node. Only certain node types can have children.\n */\n constructor(children) {\n super();\n this.children = children;\n }\n // Aliases\n /** First child of the node. */\n get firstChild() {\n return this.children[0] ?? null;\n }\n /** Last child of the node. */\n get lastChild() {\n return this.children.length > 0\n ? this.children[this.children.length - 1]\n : null;\n }\n /**\n * Same as {@link children}.\n * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n */\n get childNodes() {\n return this.children;\n }\n set childNodes(children) {\n this.children = children;\n }\n}\n/**\n * CDATA nodes.\n */\nexport class CDATA extends NodeWithChildren {\n type = ElementType.CDATA;\n get nodeType() {\n return 4;\n }\n}\n/**\n * The root node of the document.\n */\nexport class Document extends NodeWithChildren {\n type = ElementType.Root;\n get nodeType() {\n return 9;\n }\n}\n/**\n * An element within the DOM.\n */\nexport class Element extends NodeWithChildren {\n name;\n attribs;\n type;\n /**\n * @param name Name of the tag, eg. `div`, `span`.\n * @param attribs Object mapping attribute names to attribute values.\n * @param children Children of the node.\n * @param type Node type used for the new node instance.\n */\n constructor(name, attribs, children = [], type = name === \"script\"\n ? ElementType.Script\n : name === \"style\"\n ? ElementType.Style\n : ElementType.Tag) {\n super(children);\n this.name = name;\n this.attribs = attribs;\n this.type = type;\n }\n get nodeType() {\n return 1;\n }\n // DOM Level 1 aliases\n /**\n * Same as {@link name}.\n * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n */\n get tagName() {\n return this.name;\n }\n set tagName(name) {\n this.name = name;\n }\n get attributes() {\n return Object.keys(this.attribs).map((name) => ({\n name,\n value: this.attribs[name],\n namespace: this[\"x-attribsNamespace\"]?.[name],\n prefix: this[\"x-attribsPrefix\"]?.[name],\n }));\n }\n /** Element namespace (parse5 only). */\n namespace;\n /** Element attribute namespaces (parse5 only). */\n \"x-attribsNamespace\";\n /** Element attribute namespace-related prefixes (parse5 only). */\n \"x-attribsPrefix\";\n}\n/**\n * Checks if `node` is an element node.\n * @param node Node to check.\n * @returns `true` if the node is an element node.\n */\nexport function isTag(node) {\n return isTagRaw(node);\n}\n/**\n * Checks if `node` is a CDATA node.\n * @param node Node to check.\n * @returns `true` if the node is a CDATA node.\n */\nexport function isCDATA(node) {\n return node.type === ElementType.CDATA;\n}\n/**\n * Checks if `node` is a text node.\n * @param node Node to check.\n * @returns `true` if the node is a text node.\n */\nexport function isText(node) {\n return node.type === ElementType.Text;\n}\n/**\n * Checks if `node` is a comment node.\n * @param node Node to check.\n * @returns `true` if the node is a comment node.\n */\nexport function isComment(node) {\n return node.type === ElementType.Comment;\n}\n/**\n * Checks if `node` is a directive node.\n * @param node Node to check.\n * @returns `true` if the node is a directive node.\n */\nexport function isDirective(node) {\n return node.type === ElementType.Directive;\n}\n/**\n * Checks if `node` is a document node.\n * @param node Node to check.\n * @returns `true` if the node is a document node.\n */\nexport function isDocument(node) {\n return node.type === ElementType.Root;\n}\n/**\n * Checks if `node` has children.\n * @param node Node to check.\n * @returns `true` if the node has children.\n */\nexport function hasChildren(node) {\n return Object.hasOwn(node, \"children\");\n}\n/**\n * Clone a node, and optionally its children.\n * @param node Node to clone.\n * @param recursive Clone child nodes as well.\n * @returns A clone of the node.\n */\nexport function cloneNode(node, recursive = false) {\n let result;\n if (isText(node)) {\n result = new Text(node.data);\n }\n else if (isComment(node)) {\n result = new Comment(node.data);\n }\n else if (isTag(node)) {\n const children = recursive ? cloneChildren(node.children) : [];\n const clone = new Element(node.name, { ...node.attribs }, children);\n for (const child of children) {\n child.parent = clone;\n }\n if (node.namespace != null) {\n clone.namespace = node.namespace;\n }\n if (node[\"x-attribsNamespace\"]) {\n clone[\"x-attribsNamespace\"] = { ...node[\"x-attribsNamespace\"] };\n }\n if (node[\"x-attribsPrefix\"]) {\n clone[\"x-attribsPrefix\"] = { ...node[\"x-attribsPrefix\"] };\n }\n result = clone;\n }\n else if (isCDATA(node)) {\n const children = recursive ? cloneChildren(node.children) : [];\n const clone = new CDATA(children);\n for (const child of children) {\n child.parent = clone;\n }\n result = clone;\n }\n else if (isDocument(node)) {\n const children = recursive ? cloneChildren(node.children) : [];\n const clone = new Document(children);\n for (const child of children) {\n child.parent = clone;\n }\n if (node[\"x-mode\"]) {\n clone[\"x-mode\"] = node[\"x-mode\"];\n }\n result = clone;\n }\n else if (isDirective(node)) {\n const instruction = new ProcessingInstruction(node.name, node.data);\n if (node[\"x-name\"] != null) {\n instruction[\"x-name\"] = node[\"x-name\"];\n instruction[\"x-publicId\"] = node[\"x-publicId\"];\n instruction[\"x-systemId\"] = node[\"x-systemId\"];\n }\n result = instruction;\n }\n else {\n throw new Error(`Not implemented yet: ${node.type}`);\n }\n result.startIndex = node.startIndex;\n result.endIndex = node.endIndex;\n if (node.sourceCodeLocation != null) {\n result.sourceCodeLocation = node.sourceCodeLocation;\n }\n return result;\n}\n/**\n * Clone a list of child nodes.\n * @param childs The child nodes to clone.\n * @returns A list of cloned child nodes.\n */\nfunction cloneChildren(childs) {\n const children = childs.map((child) => cloneNode(child, true));\n for (let index = 1; index < children.length; index++) {\n children[index].prev = children[index - 1];\n children[index - 1].next = children[index];\n }\n return children;\n}\n","import { ElementType } from \"domelementtype\";\nimport { CDATA, Comment, Document, Element, ProcessingInstruction, Text, } from \"./node.js\";\nexport * from \"./node.js\";\n// Default options\nconst defaultOptions = {\n withStartIndices: false,\n withEndIndices: false,\n xmlMode: false,\n};\n/**\n * Event-based handler that builds a DOM tree from parser callbacks.\n */\nexport class DomHandler {\n /** The elements of the DOM */\n dom = [];\n /** The root element for the DOM */\n root = new Document(this.dom);\n /** Called once parsing has completed. */\n callback;\n /** Settings for the handler. */\n options;\n /** Callback whenever a tag is closed. */\n elementCB;\n /** Indicated whether parsing has been completed. */\n done = false;\n /** Stack of open tags. */\n tagStack = [this.root];\n /** A data node that is still being written to. */\n lastNode = null;\n /** Reference to the parser instance. Used for location information. */\n parser = null;\n /**\n * @param callback Called once parsing has completed.\n * @param options Settings for the handler.\n * @param elementCB Callback whenever a tag is closed.\n */\n constructor(callback, options, elementCB) {\n // Make it possible to skip arguments, for backwards-compatibility\n if (typeof options === \"function\") {\n elementCB = options;\n options = defaultOptions;\n }\n if (typeof callback === \"object\") {\n options = callback;\n callback = undefined;\n }\n this.callback = callback ?? null;\n this.options = options ?? defaultOptions;\n this.elementCB = elementCB ?? null;\n }\n onparserinit(parser) {\n this.parser = parser;\n }\n // Resets the handler back to starting state\n onreset() {\n this.dom = [];\n this.root = new Document(this.dom);\n this.done = false;\n this.tagStack = [this.root];\n this.lastNode = null;\n this.parser = null;\n }\n // Signals the handler that parsing is done\n onend() {\n if (this.done)\n return;\n this.done = true;\n this.parser = null;\n this.handleCallback(null);\n }\n onerror(error) {\n this.handleCallback(error);\n }\n onclosetag() {\n this.lastNode = null;\n const element = this.tagStack.pop();\n if (this.options.withEndIndices && this.parser) {\n element.endIndex = this.parser.endIndex;\n }\n if (this.elementCB)\n this.elementCB(element);\n }\n onopentag(name, attribs) {\n const type = this.options.xmlMode ? ElementType.Tag : undefined;\n const element = new Element(name, attribs, undefined, type);\n this.addNode(element);\n this.tagStack.push(element);\n }\n ontext(data) {\n const { lastNode } = this;\n if (lastNode && lastNode.type === ElementType.Text) {\n lastNode.data += data;\n if (this.options.withEndIndices && this.parser) {\n lastNode.endIndex = this.parser.endIndex;\n }\n }\n else {\n const node = new Text(data);\n this.addNode(node);\n this.lastNode = node;\n }\n }\n oncomment(data) {\n if (this.lastNode && this.lastNode.type === ElementType.Comment) {\n this.lastNode.data += data;\n return;\n }\n const node = new Comment(data);\n this.addNode(node);\n this.lastNode = node;\n }\n oncommentend() {\n this.lastNode = null;\n }\n oncdatastart() {\n const text = new Text(\"\");\n const node = new CDATA([text]);\n this.addNode(node);\n text.parent = node;\n this.lastNode = text;\n }\n oncdataend() {\n this.lastNode = null;\n }\n onprocessinginstruction(name, data) {\n const node = new ProcessingInstruction(name, data);\n this.addNode(node);\n }\n handleCallback(error) {\n if (typeof this.callback === \"function\") {\n this.callback(error, this.dom);\n }\n else if (error) {\n throw error;\n }\n }\n addNode(node) {\n const parent = this.tagStack[this.tagStack.length - 1];\n const previousSibling = parent.children[parent.children.length - 1];\n if (this.options.withStartIndices && this.parser) {\n node.startIndex = this.parser.startIndex;\n }\n if (this.options.withEndIndices && this.parser) {\n node.endIndex = this.parser.endIndex;\n }\n parent.children.push(node);\n if (previousSibling) {\n node.prev = previousSibling;\n previousSibling.next = node;\n }\n node.parent = parent;\n this.lastNode = null;\n }\n}\nexport default DomHandler;\n","import { Parser } from \"./Parser.js\";\nexport { Parser } from \"./Parser.js\";\nimport { DomHandler, } from \"domhandler\";\nexport { DomHandler, \n// Old name for DomHandler\nDomHandler as DefaultHandler, } from \"domhandler\";\n// Helper methods\n/**\n * Parses the data, returns the resulting document.\n * @param data The data that should be parsed.\n * @param options Optional options for the parser and DOM handler.\n */\nexport function parseDocument(data, options) {\n const handler = new DomHandler(undefined, options);\n new Parser(handler, options).end(data);\n return handler.root;\n}\n/**\n * Creates a parser instance, with an attached DOM handler.\n * @param callback A callback that will be called once parsing has been completed, with the resulting document.\n * @param options Optional options for the parser and DOM handler.\n * @param elementCallback An optional callback that will be called every time a tag has been completed inside of the DOM.\n */\nexport function createDocumentStream(callback, options, elementCallback) {\n const handler = new DomHandler((error) => callback(error, handler.root), options, elementCallback);\n return new Parser(handler, options);\n}\n/*\n * All of the following exports exist for backwards-compatibility.\n * They should probably be removed eventually.\n */\nexport * as ElementType from \"domelementtype\";\nexport { default as Tokenizer, QuoteType, } from \"./Tokenizer.js\";\nimport { getFeed } from \"domutils\";\nexport { getFeed } from \"domutils\";\nconst parseFeedDefaultOptions = { xmlMode: true };\n/**\n * Parse a feed.\n * @param feed The feed that should be parsed, as a string.\n * @param options Optionally, options for parsing. When using this, you should set `xmlMode` to `true`.\n */\nexport function parseFeed(feed, options = parseFeedDefaultOptions) {\n return getFeed(parseDocument(feed, options).children);\n}\nexport * as DomUtils from \"domutils\";\n//# sourceMappingURL=index.js.map","/**\n * Twine HTML decompiler: parse compiled Twine 2 or Twine 1 HTML back into a Story model.\n * Ported from storyload.go:loadHTML().\n */\nimport { parseDocument } from 'htmlparser2';\nimport type { Passage, PassageMetadata, Diagnostic, IFID } from './types.js';\nimport { createStory, storyAdd, storyPrepend, marshalStoryData } from './story.js';\nimport { tiddlerUnescape } from './escape.js';\n\nexport interface DecompileResult {\n story: import('./types.js').Story;\n diagnostics: Diagnostic[];\n}\n\n// Structural types matching domhandler's API (avoids direct import of domhandler).\ninterface HtmlNode {\n type: string;\n name?: string;\n attribs?: Record<string, string>;\n children?: HtmlNode[];\n data?: string;\n}\n\n/**\n * Parse a Twine 2 or Twine 1 compiled HTML file back into a Story model.\n */\nexport function decompileHTML(html: string): DecompileResult {\n const diagnostics: Diagnostic[] = [];\n const story = createStory();\n\n const doc = parseDocument(html) as unknown as HtmlNode;\n\n // Try Twine 2 first (<tw-storydata>), then Twine 1 (<div id=\"store-area\"> or <div id=\"storeArea\">).\n const twine2Data = findElement(doc, 'tw-storydata');\n if (twine2Data) {\n decompileTwine2(twine2Data, story, diagnostics);\n return { story, diagnostics };\n }\n\n const twine1Data = findElementByIdPattern(doc, /^store(?:-a|A)rea$/);\n if (twine1Data) {\n decompileTwine1(twine1Data, story, diagnostics);\n return { story, diagnostics };\n }\n\n diagnostics.push({ level: 'error', message: 'Malformed HTML source; story data not found.' });\n return { story, diagnostics };\n}\n\nfunction decompileTwine2(storyData: HtmlNode, story: import('./types.js').Story, diagnostics: Diagnostic[]): void {\n // Parse tw-storydata attributes.\n let startnode = 0;\n const attrs = storyData.attribs ?? {};\n\n if (attrs['name']) story.name = attrs['name'];\n if (attrs['startnode']) {\n const parsed = parseInt(attrs['startnode'], 10);\n if (Number.isNaN(parsed)) {\n diagnostics.push({\n level: 'warning',\n message: `Cannot parse \"tw-storydata\" content attribute \"startnode\" as an integer; value \"${attrs['startnode']}\".`,\n });\n } else {\n startnode = parsed;\n }\n }\n if (attrs['ifid']) story.ifid = attrs['ifid'].toUpperCase() as IFID;\n if (attrs['zoom']) {\n const parsed = parseFloat(attrs['zoom']);\n if (Number.isNaN(parsed)) {\n diagnostics.push({\n level: 'warning',\n message: `Cannot parse \"tw-storydata\" content attribute \"zoom\" as a float; value \"${attrs['zoom']}\".`,\n });\n } else {\n story.twine2.zoom = parsed;\n }\n }\n if (attrs['format']) story.twine2.format = attrs['format'];\n if (attrs['format-version']) story.twine2.formatVersion = attrs['format-version'];\n if (attrs['options']) {\n for (const opt of attrs['options'].split(/\\s+/).filter((s: string) => s.length > 0)) {\n story.twine2.options.set(opt, true);\n }\n }\n\n // Process child elements.\n // htmlparser2 uses type 'style'/'script' for those elements instead of 'tag'.\n for (const node of storyData.children ?? []) {\n if (node.type !== 'tag' && node.type !== 'style' && node.type !== 'script') continue;\n\n switch (node.name) {\n case 'style':\n case 'script': {\n const text = getTextContent(node).trim();\n if (text.length === 0) continue;\n const name = node.name === 'style' ? 'Story Stylesheet' : 'Story JavaScript';\n const tags = node.name === 'style' ? ['stylesheet'] : ['script'];\n storyAdd(story, { name, tags, text }, diagnostics);\n break;\n }\n\n case 'tw-tag': {\n const tagAttrs = node.attribs ?? {};\n const tagName = tagAttrs['name'] ?? '';\n const tagColor = tagAttrs['color'] ?? '';\n if (tagName) story.twine2.tagColors.set(tagName, tagColor);\n break;\n }\n\n case 'tw-passagedata': {\n let pid = 0;\n const pAttrs = node.attribs ?? {};\n const name = pAttrs['name'] ?? '';\n const tags = pAttrs['tags'] ? pAttrs['tags'].split(/\\s+/).filter((s: string) => s.length > 0) : [];\n const metadata: PassageMetadata = {};\n\n if (pAttrs['pid']) {\n const parsed = parseInt(pAttrs['pid'], 10);\n if (Number.isNaN(parsed)) {\n diagnostics.push({\n level: 'warning',\n message: `Cannot parse \"tw-passagedata\" content attribute \"pid\" as an integer; value \"${pAttrs['pid']}\".`,\n });\n } else {\n pid = parsed;\n }\n }\n\n if (pAttrs['position']) metadata.position = pAttrs['position'];\n if (pAttrs['size']) metadata.size = pAttrs['size'];\n\n if (pid === startnode && pid !== 0) {\n story.twine2.start = name;\n }\n\n const text = getTextContent(node).trim();\n const passage: Passage = { name, tags, text };\n if (metadata.position || metadata.size) {\n passage.metadata = metadata;\n }\n storyAdd(story, passage, diagnostics);\n break;\n }\n }\n }\n\n // Prepend StoryData passage with serialized metadata.\n storyPrepend(story, { name: 'StoryData', tags: [], text: marshalStoryData(story) }, diagnostics);\n}\n\nfunction decompileTwine1(storeArea: HtmlNode, story: import('./types.js').Story, diagnostics: Diagnostic[]): void {\n for (const node of storeArea.children ?? []) {\n if (node.type !== 'tag' || node.name !== 'div') continue;\n const nodeAttrs = node.attribs ?? {};\n if (!('tiddler' in nodeAttrs)) continue;\n\n const name = nodeAttrs['tiddler'] ?? '';\n const tags = nodeAttrs['tags'] ? nodeAttrs['tags'].split(/\\s+/).filter((s: string) => s.length > 0) : [];\n const metadata: PassageMetadata = {};\n\n if (nodeAttrs['twine-position']) metadata.position = nodeAttrs['twine-position'];\n\n const rawContent = getTextContent(node);\n const text = tiddlerUnescape(rawContent).trim();\n\n const passage: Passage = { name, tags, text };\n if (metadata.position) {\n passage.metadata = metadata;\n }\n storyAdd(story, passage, diagnostics);\n }\n}\n\nfunction findElement(node: HtmlNode, tagName: string): HtmlNode | undefined {\n if (node.type === 'tag' && node.name === tagName) return node;\n for (const child of node.children ?? []) {\n const found = findElement(child, tagName);\n if (found) return found;\n }\n return undefined;\n}\n\nfunction findElementByIdPattern(node: HtmlNode, idPattern: RegExp): HtmlNode | undefined {\n if (node.type === 'tag' && node.attribs?.['id'] && idPattern.test(node.attribs['id'])) return node;\n for (const child of node.children ?? []) {\n const found = findElementByIdPattern(child, idPattern);\n if (found) return found;\n }\n return undefined;\n}\n\nfunction getTextContent(el: HtmlNode): string {\n let text = '';\n for (const child of el.children ?? []) {\n if (child.type === 'text' && child.data) {\n text += child.data;\n }\n }\n return text;\n}\n","/**\n * File loading: dispatch by file extension.\n * Ported from storyload.go.\n */\nimport { basename } from 'node:path';\nimport { statSync } from 'node:fs';\nimport type { Story, Diagnostic, InlineSource, Passage, FileCacheEntry } from './types.js';\nimport { normalizedFileExt, mediaTypeFromFilename, mediaTypeFromExt, fontFormatHint } from './media-types.js';\nimport { storyAdd, storyPrepend } from './story.js';\nimport { parseTwee } from './parser.js';\nimport { decompileHTML } from './html-parser.js';\nimport { readUTF8, readBase64, baseNameWithoutExt } from './util.js';\n\ninterface LoadOptions {\n trim?: boolean;\n twee2Compat?: boolean;\n}\n\n/**\n * Load all source files into a story.\n */\nexport function loadSources(\n story: Story,\n filenames: string[],\n opts: LoadOptions,\n diagnostics: Diagnostic[],\n processedFiles: Set<string>,\n): void {\n for (const filename of filenames) {\n if (processedFiles.has(filename)) {\n diagnostics.push({ level: 'warning', message: `load ${filename}: Skipping duplicate.` });\n continue;\n }\n\n const ext = normalizedFileExt(filename);\n try {\n switch (ext) {\n case 'tw':\n case 'twee':\n loadTwee(story, filename, opts, diagnostics);\n break;\n case 'tw2':\n case 'twee2':\n loadTwee(story, filename, { ...opts, twee2Compat: true }, diagnostics);\n break;\n case 'htm':\n case 'html':\n loadHTML(story, filename, diagnostics);\n break;\n case 'css':\n loadTagged(story, 'stylesheet', filename, diagnostics);\n break;\n case 'js':\n loadTagged(story, 'script', filename, diagnostics);\n break;\n case 'otf':\n case 'ttf':\n case 'woff':\n case 'woff2':\n loadFont(story, filename, diagnostics);\n break;\n case 'gif':\n case 'jpeg':\n case 'jpg':\n case 'png':\n case 'svg':\n case 'tif':\n case 'tiff':\n case 'webp':\n loadMedia(story, 'Twine.image', filename, diagnostics);\n break;\n case 'aac':\n case 'flac':\n case 'm4a':\n case 'mp3':\n case 'oga':\n case 'ogg':\n case 'opus':\n case 'wav':\n case 'wave':\n case 'weba':\n loadMedia(story, 'Twine.audio', filename, diagnostics);\n break;\n case 'mp4':\n case 'ogv':\n case 'webm':\n loadMedia(story, 'Twine.video', filename, diagnostics);\n break;\n case 'vtt':\n loadMedia(story, 'Twine.vtt', filename, diagnostics);\n break;\n default:\n continue;\n }\n } catch (e) {\n diagnostics.push({\n level: 'error',\n message: `load ${filename}: ${e instanceof Error ? e.message : String(e)}`,\n file: filename,\n });\n continue;\n }\n processedFiles.add(filename);\n }\n\n // Prepend StoryTitle if we have a name but no StoryTitle passage.\n if (story.name !== '' && !story.passages.some((p) => p.name === 'StoryTitle')) {\n storyPrepend(story, { name: 'StoryTitle', tags: [], text: story.name }, diagnostics);\n }\n}\n\n/**\n * Load inline sources (string content or InlineSource objects).\n */\nexport function loadInlineSources(\n story: Story,\n sources: (string | InlineSource)[],\n opts: LoadOptions,\n diagnostics: Diagnostic[],\n): void {\n for (const source of sources) {\n if (typeof source === 'string') {\n // Treat as a file path — handled externally\n continue;\n }\n const content = typeof source.content === 'string' ? source.content : source.content.toString('utf-8');\n\n const ext = normalizedFileExt(source.filename);\n switch (ext) {\n case '':\n case 'tw':\n case 'twee':\n case 'tw2':\n case 'twee2': {\n const twee2 = ext === 'tw2' || ext === 'twee2' || opts.twee2Compat;\n const result = parseTwee(content, {\n filename: source.filename,\n trim: opts.trim ?? true,\n twee2Compat: twee2,\n });\n diagnostics.push(...result.diagnostics);\n for (const p of result.passages) {\n storyAdd(story, p, diagnostics);\n }\n break;\n }\n case 'css':\n storyAdd(story, { name: basename(source.filename), tags: ['stylesheet'], text: content }, diagnostics);\n break;\n case 'js':\n storyAdd(story, { name: basename(source.filename), tags: ['script'], text: content }, diagnostics);\n break;\n default:\n diagnostics.push({\n level: 'warning',\n message: `load ${source.filename}: in-memory sources of type .${ext} are not supported; skipped.`,\n });\n }\n }\n}\n\ninterface ParseResult {\n passages: Passage[];\n diagnostics: Diagnostic[];\n}\n\nfunction parseTweeFile(filename: string, opts: LoadOptions): ParseResult {\n const source = readUTF8(filename);\n const result = parseTwee(source, {\n filename,\n trim: opts.trim ?? true,\n twee2Compat: opts.twee2Compat ?? false,\n });\n return { passages: result.passages, diagnostics: [...result.diagnostics] };\n}\n\nfunction parseTaggedFile(tag: string, filename: string): ParseResult {\n const source = readUTF8(filename);\n return { passages: [{ name: basename(filename), tags: [tag], text: source }], diagnostics: [] };\n}\n\nfunction parseMediaFile(tag: string, filename: string): ParseResult {\n const source = readBase64(filename);\n const name = baseNameWithoutExt(filename);\n return {\n passages: [{ name, tags: [tag], text: `data:${mediaTypeFromFilename(filename)};base64,${source}` }],\n diagnostics: [],\n };\n}\n\nfunction parseFontFile(filename: string): ParseResult {\n const source = readBase64(filename);\n const name = basename(filename);\n const family = baseNameWithoutExt(filename);\n const ext = normalizedFileExt(filename);\n const mediaType = mediaTypeFromExt(ext);\n const hint = fontFormatHint(ext);\n return {\n passages: [\n {\n name,\n tags: ['stylesheet'],\n text: `@font-face {\\n\\tfont-family: \"${family}\";\\n\\tsrc: url(\"data:${mediaType};base64,${source}\") format(\"${hint}\");\\n}`,\n },\n ],\n diagnostics: [],\n };\n}\n\nfunction parseHTMLFile(filename: string): ParseResult {\n const source = readUTF8(filename);\n const result = decompileHTML(source);\n return { passages: result.story.passages, diagnostics: [...result.diagnostics] };\n}\n\nfunction parseFile(filename: string, opts: LoadOptions): ParseResult | undefined {\n const ext = normalizedFileExt(filename);\n switch (ext) {\n case 'tw':\n case 'twee':\n return parseTweeFile(filename, opts);\n case 'tw2':\n case 'twee2':\n return parseTweeFile(filename, { ...opts, twee2Compat: true });\n case 'htm':\n case 'html':\n return parseHTMLFile(filename);\n case 'css':\n return parseTaggedFile('stylesheet', filename);\n case 'js':\n return parseTaggedFile('script', filename);\n case 'otf':\n case 'ttf':\n case 'woff':\n case 'woff2':\n return parseFontFile(filename);\n case 'gif':\n case 'jpeg':\n case 'jpg':\n case 'png':\n case 'svg':\n case 'tif':\n case 'tiff':\n case 'webp':\n return parseMediaFile('Twine.image', filename);\n case 'aac':\n case 'flac':\n case 'm4a':\n case 'mp3':\n case 'oga':\n case 'ogg':\n case 'opus':\n case 'wav':\n case 'wave':\n case 'weba':\n return parseMediaFile('Twine.audio', filename);\n case 'mp4':\n case 'ogv':\n case 'webm':\n return parseMediaFile('Twine.video', filename);\n case 'vtt':\n return parseMediaFile('Twine.vtt', filename);\n default:\n return undefined;\n }\n}\n\nfunction loadHTML(story: Story, filename: string, diagnostics: Diagnostic[]): void {\n const result = parseHTMLFile(filename);\n diagnostics.push(...result.diagnostics);\n for (const p of result.passages) {\n storyAdd(story, p, diagnostics);\n }\n}\n\nfunction loadTwee(story: Story, filename: string, opts: LoadOptions, diagnostics: Diagnostic[]): void {\n const result = parseTweeFile(filename, opts);\n diagnostics.push(...result.diagnostics);\n for (const p of result.passages) {\n storyAdd(story, p, diagnostics);\n }\n}\n\nfunction loadTagged(story: Story, tag: string, filename: string, diagnostics: Diagnostic[]): void {\n const result = parseTaggedFile(tag, filename);\n for (const p of result.passages) {\n storyAdd(story, p, diagnostics);\n }\n}\n\nfunction loadMedia(story: Story, tag: string, filename: string, diagnostics: Diagnostic[]): void {\n const result = parseMediaFile(tag, filename);\n for (const p of result.passages) {\n storyAdd(story, p, diagnostics);\n }\n}\n\nfunction loadFont(story: Story, filename: string, diagnostics: Diagnostic[]): void {\n const result = parseFontFile(filename);\n for (const p of result.passages) {\n storyAdd(story, p, diagnostics);\n }\n}\n\n/**\n * Load sources with mtime-based caching for incremental rebuilds.\n * Always creates a fresh Story; cached passages are replayed via storyAdd().\n */\nexport function loadSourcesCached(\n story: Story,\n filenames: string[],\n opts: LoadOptions,\n diagnostics: Diagnostic[],\n processedFiles: Set<string>,\n cache: Map<string, FileCacheEntry>,\n changedFiles?: ReadonlySet<string>,\n): void {\n const currentFiles = new Set<string>();\n\n for (const filename of filenames) {\n if (processedFiles.has(filename)) {\n diagnostics.push({ level: 'warning', message: `load ${filename}: Skipping duplicate.` });\n continue;\n }\n\n currentFiles.add(filename);\n const cached = cache.get(filename);\n\n // If changedFiles is provided and this file isn't changed and we have a cache hit, skip stat\n if (changedFiles && cached && !changedFiles.has(filename)) {\n diagnostics.push(...cached.diagnostics);\n for (const p of cached.passages) {\n storyAdd(story, p, diagnostics);\n }\n processedFiles.add(filename);\n continue;\n }\n\n // stat the file to check mtime\n let mtimeMs: number;\n try {\n mtimeMs = statSync(filename).mtimeMs;\n } catch {\n // File may have been deleted between getFilenames and here\n continue;\n }\n\n // Cache hit with matching mtime: replay\n if (cached && cached.mtimeMs === mtimeMs) {\n diagnostics.push(...cached.diagnostics);\n for (const p of cached.passages) {\n storyAdd(story, p, diagnostics);\n }\n processedFiles.add(filename);\n continue;\n }\n\n // Cache miss: parse and store\n try {\n const result = parseFile(filename, opts);\n if (!result) continue;\n\n cache.set(filename, {\n mtimeMs,\n passages: result.passages,\n diagnostics: result.diagnostics,\n });\n\n diagnostics.push(...result.diagnostics);\n for (const p of result.passages) {\n storyAdd(story, p, diagnostics);\n }\n } catch (e) {\n diagnostics.push({\n level: 'error',\n message: `load ${filename}: ${e instanceof Error ? e.message : String(e)}`,\n file: filename,\n });\n continue;\n }\n processedFiles.add(filename);\n }\n\n // Purge cache entries for deleted files\n for (const key of cache.keys()) {\n if (!currentFiles.has(key)) {\n cache.delete(key);\n }\n }\n\n // Prepend StoryTitle if we have a name but no StoryTitle passage.\n if (story.name !== '' && !story.passages.some((p) => p.name === 'StoryTitle')) {\n storyPrepend(story, { name: 'StoryTitle', tags: [], text: story.name }, diagnostics);\n }\n}\n","/**\n * The twee-ts version, read at runtime from the package's own package.json.\n *\n * The release workflow (semantic-release) writes the new version into the\n * published package.json only; git keeps the old one. Reading it at runtime\n * is the only way the CLI and `creator-version` report the published version.\n */\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst PACKAGE_NAME = '@rohal12/twee-ts';\n\n/** Walks up from `startDir` to the nearest package.json named @rohal12/twee-ts and returns its version. */\nexport function findPackageVersion(startDir: string): string | undefined {\n let dir = startDir;\n for (;;) {\n try {\n const pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf-8')) as { name?: unknown; version?: unknown };\n if (pkg.name === PACKAGE_NAME && typeof pkg.version === 'string') return pkg.version;\n } catch {\n // No readable package.json here; keep walking up.\n }\n const parent = dirname(dir);\n if (parent === dir) return undefined;\n dir = parent;\n }\n}\n\n/** This module's directory: `__dirname` in the CJS build, `import.meta.url` in ESM and in source. */\nfunction moduleDir(): string {\n return typeof __dirname === 'string' ? __dirname : dirname(fileURLToPath(import.meta.url));\n}\n\nexport const VERSION: string = findPackageVersion(moduleDir()) ?? '0.0.0';\n","/**\n * Twine 2 HTML and archive output.\n * Ported from storyout.go.\n */\nimport type { ReadonlyStory, ReadonlyPassage, StoryFormatInfo } from './types.js';\nimport { attrEscape, htmlEscape, commentSanitize, htmlCommentSanitize } from './escape.js';\nimport { passageToPassagedata, hasTag, hasAnyTag } from './passage.js';\nimport { readFormatSource } from './formats.js';\nimport { VERSION } from './version.js';\n\nconst CREATOR_NAME = 'Twee-ts';\n\nexport function toTwine2Archive(\n story: ReadonlyStory,\n startName: string,\n options?: { readonly sourceInfo?: boolean },\n): string {\n return getTwine2DataChunk(story, startName, options) + '\\n';\n}\n\nexport function toTwine2HTML(\n story: ReadonlyStory,\n format: StoryFormatInfo,\n startName: string,\n options?: { readonly sourceInfo?: boolean },\n): string {\n let template = readFormatSource(format);\n\n if (template.includes('{{STORY_NAME}}')) {\n const name = htmlEscape(story.name);\n template = template.replaceAll('{{STORY_NAME}}', () => name);\n }\n if (template.includes('{{STORY_DATA}}')) {\n const data = getTwine2DataChunk(story, startName, options);\n template = template.replace('{{STORY_DATA}}', () => data);\n }\n\n return template;\n}\n\nfunction getTwine2DataChunk(\n story: ReadonlyStory,\n startName: string,\n options?: { readonly sourceInfo?: boolean },\n): string {\n const parts: string[] = [];\n let startID = '';\n let pid = 0;\n\n // Gather script and stylesheet passages.\n const scripts: ReadonlyPassage[] = [];\n const stylesheets: ReadonlyPassage[] = [];\n for (const p of story.passages) {\n if (hasTag(p, 'Twine.private')) continue;\n if (hasTag(p, 'script')) scripts.push(p);\n else if (hasTag(p, 'stylesheet')) stylesheets.push(p);\n }\n\n // Style element\n let styleContent = '';\n if (stylesheets.length === 1) {\n styleContent = stylesheets[0]?.text ?? '';\n } else if (stylesheets.length > 1) {\n let pidS = 1;\n for (const p of stylesheets) {\n if (pidS > 1 && !styleContent.endsWith('\\n')) styleContent += '\\n';\n styleContent += `/* twine-user-stylesheet #${pidS}: \"${commentSanitize(p.name)}\" */\\n`;\n styleContent += p.text;\n pidS++;\n }\n }\n parts.push(`<style role=\"stylesheet\" id=\"twine-user-stylesheet\" type=\"text/twine-css\">${styleContent}</style>`);\n\n // Script element\n let scriptContent = '';\n if (scripts.length === 1) {\n scriptContent = scripts[0]?.text ?? '';\n } else if (scripts.length > 1) {\n let pidS = 1;\n for (const p of scripts) {\n if (pidS > 1 && !scriptContent.endsWith('\\n')) scriptContent += '\\n';\n scriptContent += `/* twine-user-script #${pidS}: \"${commentSanitize(p.name)}\" */\\n`;\n scriptContent += p.text;\n pidS++;\n }\n }\n parts.push(`<script role=\"script\" id=\"twine-user-script\" type=\"text/twine-javascript\">${scriptContent}</script>`);\n\n // Tag color elements (only spec-valid colors: 7 named colors or hex values)\n const validTagColors = new Set(['gray', 'red', 'orange', 'yellow', 'green', 'blue', 'purple']);\n const hexColorPattern = /^#[0-9a-fA-F]{3,8}$/;\n for (const [tag, color] of story.twine2.tagColors) {\n if (validTagColors.has(color) || hexColorPattern.test(color)) {\n parts.push(`<tw-tag name=\"${attrEscape(tag)}\" color=\"${attrEscape(color)}\"></tw-tag>`);\n }\n }\n\n // Normal passage elements\n pid = 1;\n for (const p of story.passages) {\n if (p.name === 'StoryTitle' || p.name === 'StoryData' || hasAnyTag(p, 'script', 'stylesheet', 'Twine.private')) {\n continue;\n }\n // Drop empty StorySettings\n if (p.name === 'StorySettings' && story.twine1.settings.size === 0) {\n continue;\n }\n\n parts.push(passageToPassagedata(p, pid, options));\n if (startName === p.name) {\n startID = String(pid);\n }\n pid++;\n }\n\n // Build options string\n const opts: string[] = [];\n for (const [opt, val] of story.twine2.options) {\n if (val) opts.push(opt);\n }\n const optionsStr = opts.join(' ');\n\n // Wrap in tw-storydata\n const zoom = String(story.twine2.zoom);\n\n const wrapper =\n `<!-- UUID://${htmlCommentSanitize(story.ifid)}// -->` +\n `<tw-storydata name=\"${attrEscape(story.name)}\" startnode=\"${attrEscape(startID)}\" ` +\n `creator=\"${attrEscape(CREATOR_NAME)}\" creator-version=\"${attrEscape(VERSION)}\" ` +\n `ifid=\"${attrEscape(story.ifid)}\" zoom=\"${attrEscape(zoom)}\" ` +\n `format=\"${attrEscape(story.twine2.format)}\" ` +\n `format-version=\"${attrEscape(story.twine2.formatVersion)}\" ` +\n `options=\"${attrEscape(optionsStr)}\" tags=\"${attrEscape(story.twine2.tags)}\" hidden>`;\n\n return wrapper + parts.join('') + '</tw-storydata>';\n}\n","/**\n * Twine 1 HTML and archive output.\n * Ported from storyout.go.\n */\nimport { readFileSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport type { ReadonlyStory, StoryFormatInfo } from './types.js';\nimport { hasTag, passageToTiddler } from './passage.js';\nimport { readFormatSource } from './formats.js';\nimport { jsStringEscape, htmlCommentSanitize } from './escape.js';\nimport { VERSION } from './version.js';\n\nconst CREATOR_NAME = 'twee-ts';\n\nexport function toTwine1Archive(story: ReadonlyStory, _startName: string): string {\n const { data, count } = getTwine1PassageChunk(story);\n return `<div id=\"storeArea\" data-size=\"${count}\">${data}</div>\\n`;\n}\n\nexport function toTwine1HTML(story: ReadonlyStory, format: StoryFormatInfo, startName: string): string {\n const formatDir = dirname(format.filename);\n const parentDir = dirname(formatDir);\n let template = readFormatSource(format);\n const { data, count } = getTwine1PassageChunk(story);\n\n // Component replacements\n template = tryReplaceComponent(template, '\"USER_LIB\"', join(formatDir, 'userlib.js'), false);\n template = tryReplaceComponent(template, '\"ENGINE\"', join(parentDir, 'engine.js'), true);\n template = tryReplaceComponent(template, '\"SUGARCANE\"', join(formatDir, 'code.js'), true);\n template = tryReplaceComponent(template, '\"JONAH\"', join(formatDir, 'code.js'), true);\n\n if (story.twine1.settings.get('jquery') === 'on') {\n template = tryReplaceComponent(template, '\"JQUERY\"', join(parentDir, 'jquery.js'), true);\n }\n if (story.twine1.settings.get('modernizr') === 'on') {\n template = tryReplaceComponent(template, '\"MODERNIZR\"', join(parentDir, 'modernizr.js'), true);\n }\n\n // Story instance replacements\n const displayStart = startName === 'Start' ? '' : startName;\n template = template.replace('\"VERSION\"', `Compiled with ${CREATOR_NAME}, ${VERSION}`);\n template = template.replace('\"TIME\"', `Built on ${new Date().toUTCString()}`);\n const startAtValue = `\"${jsStringEscape(displayStart)}\"`;\n template = template.replace('\"START_AT\"', () => startAtValue);\n template = template.replace('\"STORY_SIZE\"', `\"${count}\"`);\n\n if (template.includes('\"STORY\"')) {\n template = template.replace('\"STORY\"', () => data);\n } else {\n // Pre-1.4 format: append data + footer\n let footer: string;\n try {\n footer = readFileSync(join(formatDir, 'footer.html'), 'utf-8');\n } catch {\n footer = '</div>\\n</body>\\n</html>\\n';\n }\n template += data + footer;\n }\n\n // IFID replacement\n if (story.ifid) {\n const safeIfid = htmlCommentSanitize(story.ifid);\n if (template.includes('<div id=\"store-area\"')) {\n template = template.replace('<div id=\"store-area\"', `<!-- UUID://${safeIfid}// --><div id=\"store-area\"`);\n } else {\n template = template.replace('<div id=\"storeArea\"', `<!-- UUID://${safeIfid}// --><div id=\"storeArea\"`);\n }\n }\n\n return template;\n}\n\nfunction getTwine1PassageChunk(story: ReadonlyStory): { data: string; count: number } {\n const obfuscateRot13 = story.twine1.settings.get('obfuscate') === 'rot13';\n let data = '';\n let count = 0;\n\n for (const p of story.passages) {\n if (hasTag(p, 'Twine.private')) continue;\n count++;\n data += passageToTiddler(p, count, obfuscateRot13);\n }\n\n return { data, count };\n}\n\nfunction tryReplaceComponent(template: string, placeholder: string, componentPath: string, required: boolean): string {\n if (!template.includes(placeholder)) return template;\n try {\n let content = readFileSync(componentPath, 'utf-8');\n if (content.charCodeAt(0) === 0xfeff) content = content.slice(1);\n return template.replace(placeholder, () => content);\n } catch (e) {\n if (required) {\n throw new Error(\n `Required format component not found: ${componentPath}: ${e instanceof Error ? e.message : String(e)}`,\n );\n }\n return template;\n }\n}\n","/**\n * Twee 3/1 decompile output.\n * Ported from storyout.go.\n */\nimport type { ReadonlyStory, OutputMode } from './types.js';\nimport { passageToTwee } from './passage.js';\n\nexport function toTwee(story: ReadonlyStory, outMode: OutputMode): string {\n let data = '';\n for (const p of story.passages) {\n data += passageToTwee(p, outMode);\n }\n return data;\n}\n","/**\n * Module/head injection into <head>.\n * Ported from module.go + io.go:modifyHead().\n */\nimport type { Diagnostic } from './types.js';\nimport { normalizedFileExt, mediaTypeFromExt, fontFormatHint, slugify } from './media-types.js';\nimport { readUTF8, readBase64, baseNameWithoutExt } from './util.js';\n\n/**\n * Load modules and return HTML tags to inject before </head>.\n */\nexport function loadModules(filenames: string[]): string {\n const processed = new Set<string>();\n const headTags: string[] = [];\n\n for (const filename of filenames) {\n if (processed.has(filename)) continue;\n\n const ext = normalizedFileExt(filename);\n let tag: string | null = null;\n\n switch (ext) {\n case 'css':\n tag = loadModuleTagged('style', filename);\n break;\n case 'js':\n tag = loadModuleTagged('script', filename);\n break;\n case 'otf':\n case 'ttf':\n case 'woff':\n case 'woff2':\n tag = loadModuleFont(filename);\n break;\n default:\n continue;\n }\n\n if (tag) headTags.push(tag);\n processed.add(filename);\n }\n\n return headTags.join('\\n');\n}\n\nfunction loadModuleTagged(tag: string, filename: string): string | null {\n const source = readUTF8(filename).trim();\n if (source.length === 0) return null;\n\n const family = baseNameWithoutExt(filename);\n const idSlug = `${tag}-module-${slugify(family)}`;\n const mimeType = tag === 'script' ? 'text/javascript' : 'text/css';\n\n return `<${tag} id=\"${idSlug}\" type=\"${mimeType}\">${source}</${tag}>`;\n}\n\nfunction loadModuleFont(filename: string): string | null {\n const source = readBase64(filename);\n const family = baseNameWithoutExt(filename);\n const idSlug = `style-module-${slugify(family)}`;\n const ext = normalizedFileExt(filename);\n const mediaType = mediaTypeFromExt(ext);\n const hint = fontFormatHint(ext);\n\n return `<style id=\"${idSlug}\" type=\"text/css\">@font-face {\\n\\tfont-family: \"${family}\";\\n\\tsrc: url(\"data:${mediaType};base64,${source}\") format(\"${hint}\");\\n}</style>`;\n}\n\n/**\n * Inject modules and head file content before </head>.\n */\nexport function modifyHead(html: string, modulePaths: string[], headFile?: string, diagnostics?: Diagnostic[]): string {\n const parts: string[] = [];\n\n if (modulePaths.length > 0) {\n const modules = loadModules(modulePaths).trim();\n if (modules.length > 0) parts.push(modules);\n }\n\n if (headFile) {\n try {\n const source = readUTF8(headFile).trim();\n if (source.length > 0) parts.push(source);\n } catch (e) {\n diagnostics?.push({\n level: 'warning',\n message: `Failed to read head file \"${headFile}\": ${e instanceof Error ? e.message : String(e)}`,\n });\n }\n }\n\n if (parts.length > 0) {\n parts.push('</head>');\n const replacement = parts.join('\\n');\n return html.replace('</head>', () => replacement);\n }\n return html;\n}\n","/**\n * Remote story format fetching, caching, and checksum verification.\n * Uses the Story Formats Archive (SFA) as the default source.\n */\nimport { mkdirSync, readFileSync, writeFileSync, existsSync, readdirSync, statSync, rmSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport type { SFAIndex, SFAIndexEntry, StoryFormatInfo } from './types.js';\nimport { parseSemver, semverCompare, parseFormatJSON } from './formats.js';\n\nconst DEFAULT_SFA_INDICES = [\n 'https://videlais.github.io/story-formats-archive/official/index.json',\n 'https://videlais.github.io/story-formats-archive/unofficial/index.json',\n];\n\n/** Get the cache directory for downloaded story formats. */\nexport function getCacheDir(): string {\n const xdg = process.env['XDG_CACHE_HOME'];\n const base = xdg || join(homedir(), '.cache');\n return join(base, 'twee-ts', 'storyformats');\n}\n\n/** In-memory index cache, keyed by URL. Cleared each compile. */\nconst indexCache = new Map<string, SFAIndex>();\n\n/** Clear the in-memory index cache. */\nexport function clearIndexCache(): void {\n indexCache.clear();\n}\n\n/** Validate that a JSON value is a valid SFAIndexEntry. */\nfunction isValidEntry(val: unknown): val is SFAIndexEntry {\n if (typeof val !== 'object' || val === null || Array.isArray(val)) return false;\n const obj = val as Record<string, unknown>;\n return (\n typeof obj.name === 'string' &&\n typeof obj.version === 'string' &&\n typeof obj.checksums === 'object' &&\n obj.checksums !== null &&\n !Array.isArray(obj.checksums)\n );\n}\n\n/** Validate that a JSON value conforms to the SFAIndex shape. */\nfunction validateSFAIndex(json: unknown): SFAIndex {\n if (typeof json !== 'object' || json === null) {\n throw new Error('SFA index is not an object');\n }\n const obj = json as Record<string, unknown>;\n const twine1 = Array.isArray(obj['twine1']) ? (obj['twine1'] as unknown[]).filter(isValidEntry) : [];\n const twine2 = Array.isArray(obj['twine2']) ? (obj['twine2'] as unknown[]).filter(isValidEntry) : [];\n return { twine1, twine2 };\n}\n\n/** Generate a format ID from name and version. */\nfunction makeFormatId(name: string, version: string): string {\n const major = parseSemver(version)?.[0] ?? '0';\n return `${name.toLowerCase().replace(/\\s+/g, '-')}-${major}`;\n}\n\n/** Fetch and parse an SFA index.json, with in-memory caching. */\nexport async function fetchIndex(url: string): Promise<SFAIndex> {\n const cached = indexCache.get(url);\n if (cached) return cached;\n\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`Failed to fetch format index from ${url}: ${res.status} ${res.statusText}`);\n }\n const data = validateSFAIndex(await res.json());\n indexCache.set(url, data);\n return data;\n}\n\ninterface FindEntryResult {\n entry: SFAIndexEntry;\n formatType: 'twine1' | 'twine2';\n}\n\n/**\n * Find the best matching entry in an SFA index.\n * Exact version preferred, then highest version with same major.\n */\nexport function findEntry(index: SFAIndex, name: string, version: string): FindEntryResult | undefined {\n const wanted = parseSemver(version);\n\n const searchArrays: Array<{ entries: SFAIndexEntry[]; formatType: 'twine1' | 'twine2' }> = [\n { entries: index.twine2 ?? [], formatType: 'twine2' },\n { entries: index.twine1 ?? [], formatType: 'twine1' },\n ];\n\n let bestResult: FindEntryResult | undefined;\n let bestVersion: [number, number, number] | null = null;\n\n for (const { entries, formatType } of searchArrays) {\n for (const entry of entries) {\n if (entry.name.toLowerCase() !== name.toLowerCase()) continue;\n const have = parseSemver(entry.version);\n if (!have) continue;\n\n // Exact match — return immediately\n if (wanted && semverCompare(have, wanted) === 0) return { entry, formatType };\n\n // Same-major, highest version\n if (wanted === null || (have[0] === wanted[0] && semverCompare(have, wanted) >= 0)) {\n if (!bestVersion || semverCompare(have, bestVersion) > 0) {\n bestVersion = have;\n bestResult = { entry, formatType };\n }\n }\n }\n }\n\n return bestResult;\n}\n\n/** Verify SHA-256 checksum using Web Crypto API (Node 22 built-in). */\nexport async function verifySHA256(content: Uint8Array<ArrayBuffer>, expectedHex: string): Promise<boolean> {\n const digest = await crypto.subtle.digest('SHA-256', content);\n const hex = Array.from(new Uint8Array(digest))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n return hex === expectedHex.toLowerCase();\n}\n\n/** Derive the download URL for a format.js from the index URL and entry. */\nfunction getDownloadUrl(indexUrl: string, entry: SFAIndexEntry, formatType: 'twine1' | 'twine2'): string {\n const base = indexUrl.replace(/\\/index\\.json$/, '');\n return `${base}/${formatType}/${entry.name}/${entry.version}/format.js`;\n}\n\n/** Download a format, verify its checksum, write to cache, and return StoryFormatInfo. */\nexport async function fetchAndCacheFormat(entry: SFAIndexEntry, downloadUrl: string): Promise<StoryFormatInfo> {\n const res = await fetch(downloadUrl);\n if (!res.ok) {\n throw new Error(`Failed to download format from ${downloadUrl}: ${res.status} ${res.statusText}`);\n }\n const text = await res.text();\n\n // Verify checksum if available\n const checksumKey = Object.keys(entry.checksums ?? {}).find((k) => k.endsWith('format.js'));\n if (checksumKey) {\n const expected = entry.checksums[checksumKey];\n if (!expected) throw new Error(`Missing checksum value for key \"${checksumKey}\"`);\n const encoder = new TextEncoder();\n const valid = await verifySHA256(encoder.encode(text), expected);\n if (!valid) {\n throw new Error(`Checksum verification failed for ${entry.name} ${entry.version}`);\n }\n }\n\n // Parse format JSON to extract name/version/source\n const id = makeFormatId(entry.name, entry.version);\n const data = parseFormatJSON(text, id);\n if (!data) {\n throw new Error(`Failed to parse format JSON from ${downloadUrl}`);\n }\n\n // Write to cache\n const cacheDir = getCacheDir();\n const formatDir = join(cacheDir, entry.name, entry.version);\n mkdirSync(formatDir, { recursive: true });\n const formatPath = join(formatDir, 'format.js');\n writeFileSync(formatPath, text, 'utf-8');\n\n return {\n id,\n filename: formatPath,\n isTwine2: true,\n name: data.name,\n version: data.version,\n proofing: data.proofing ?? false,\n };\n}\n\n/** Download a direct format.js URL, parse its JSON, cache it, and return StoryFormatInfo. */\nexport async function fetchDirectFormat(url: string): Promise<StoryFormatInfo> {\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`Failed to download format from ${url}: ${res.status} ${res.statusText}`);\n }\n const text = await res.text();\n\n const tempId = 'direct-url';\n const data = parseFormatJSON(text, tempId);\n if (!data) {\n throw new Error(`Failed to parse format JSON from ${url}`);\n }\n\n const id = makeFormatId(data.name, data.version);\n\n // Write to cache\n const cacheDir = getCacheDir();\n const formatDir = join(cacheDir, data.name, data.version);\n mkdirSync(formatDir, { recursive: true });\n const formatPath = join(formatDir, 'format.js');\n writeFileSync(formatPath, text, 'utf-8');\n\n return {\n id,\n filename: formatPath,\n isTwine2: true,\n name: data.name,\n version: data.version,\n proofing: data.proofing ?? false,\n };\n}\n\n/**\n * Try to resolve a remote story format by name and version.\n * 1. Try direct format URLs\n * 2. Try custom index URLs\n * 3. Try default SFA indices\n */\nexport async function resolveRemoteFormat(\n name: string,\n version: string,\n indices?: string[],\n urls?: string[],\n): Promise<StoryFormatInfo | undefined> {\n let lastError: Error | undefined;\n\n // 1. Try direct URLs — check if any match by name\n if (urls) {\n for (const url of urls) {\n try {\n const info = await fetchDirectFormat(url);\n if (info.name.toLowerCase() === name.toLowerCase()) {\n const wanted = parseSemver(version);\n const have = parseSemver(info.version);\n if (!wanted || (have && have[0] === wanted[0] && semverCompare(have, wanted) >= 0)) {\n return info;\n }\n }\n } catch (e) {\n lastError = e instanceof Error ? e : new Error(String(e));\n }\n }\n }\n\n // 2. Try custom indices, then default SFA indices\n const allIndices = [...(indices ?? []), ...DEFAULT_SFA_INDICES];\n for (const indexUrl of allIndices) {\n try {\n const index = await fetchIndex(indexUrl);\n const result = findEntry(index, name, version);\n if (result) {\n // Check cache first\n const cached = getCachedFormat(result.entry.name, result.entry.version);\n if (cached) return cached;\n\n const downloadUrl = getDownloadUrl(indexUrl, result.entry, result.formatType);\n return await fetchAndCacheFormat(result.entry, downloadUrl);\n }\n } catch (e) {\n lastError = e instanceof Error ? e : new Error(String(e));\n }\n }\n\n // If all sources failed with errors, propagate the last one\n if (lastError) throw lastError;\n return undefined;\n}\n\n/** Check if a format is already in the local cache. */\nfunction getCachedFormat(name: string, version: string): StoryFormatInfo | undefined {\n const formatPath = join(getCacheDir(), name, version, 'format.js');\n try {\n if (!existsSync(formatPath)) return undefined;\n const source = readFileSync(formatPath, 'utf-8');\n const id = makeFormatId(name, version);\n const data = parseFormatJSON(source, id);\n if (!data) return undefined;\n return {\n id,\n filename: formatPath,\n isTwine2: true,\n name: data.name,\n version: data.version,\n proofing: data.proofing ?? false,\n };\n } catch {\n return undefined;\n }\n}\n\n/** Discover all cached remote formats. Returns a Map like discoverFormats(). */\nexport function discoverCachedFormats(): Map<string, StoryFormatInfo> {\n const formats = new Map<string, StoryFormatInfo>();\n const cacheDir = getCacheDir();\n\n try {\n if (!existsSync(cacheDir)) return formats;\n } catch {\n return formats;\n }\n\n let names: string[];\n try {\n names = readdirSync(cacheDir);\n } catch {\n return formats;\n }\n\n for (const name of names) {\n const nameDir = join(cacheDir, name);\n try {\n if (!statSync(nameDir).isDirectory()) continue;\n } catch {\n continue;\n }\n\n let versions: string[];\n try {\n versions = readdirSync(nameDir);\n } catch {\n continue;\n }\n\n for (const version of versions) {\n const info = getCachedFormat(name, version);\n if (info) {\n formats.set(`${info.id}-${version}`, info);\n }\n }\n }\n\n return formats;\n}\n\n/** Info about a cached format entry with size and modification date. */\nexport interface CachedFormatEntry {\n readonly name: string;\n readonly version: string;\n readonly sizeBytes: number;\n readonly modifiedAt: Date;\n}\n\n/** List all cached formats with size and modification date. */\nexport function listCachedFormats(): readonly CachedFormatEntry[] {\n const cacheDir = getCacheDir();\n const entries: CachedFormatEntry[] = [];\n\n try {\n if (!existsSync(cacheDir)) return entries;\n } catch {\n return entries;\n }\n\n let names: string[];\n try {\n names = readdirSync(cacheDir);\n } catch {\n return entries;\n }\n\n for (const name of names) {\n const nameDir = join(cacheDir, name);\n try {\n if (!statSync(nameDir).isDirectory()) continue;\n } catch {\n continue;\n }\n\n let versions: string[];\n try {\n versions = readdirSync(nameDir);\n } catch {\n continue;\n }\n\n for (const version of versions) {\n const formatPath = join(nameDir, version, 'format.js');\n try {\n const stat = statSync(formatPath);\n entries.push({\n name,\n version,\n sizeBytes: stat.size,\n modifiedAt: stat.mtime,\n });\n } catch {\n // Skip entries without a valid format.js\n }\n }\n }\n\n return entries;\n}\n\n/** Clear all cached formats, or only those matching a given name. Returns the number of entries removed. */\nexport function clearCachedFormats(name?: string): number {\n const cacheDir = getCacheDir();\n if (!existsSync(cacheDir)) return 0;\n\n if (!name) {\n const entries = listCachedFormats();\n const count = entries.length;\n rmSync(cacheDir, { recursive: true, force: true });\n return count;\n }\n\n const nameDir = join(cacheDir, name);\n if (!existsSync(nameDir)) return 0;\n\n let versions: string[];\n try {\n versions = readdirSync(nameDir);\n } catch {\n return 0;\n }\n const count = versions.length;\n rmSync(nameDir, { recursive: true, force: true });\n return count;\n}\n\n/** Get total cache size in bytes and format count. */\nexport function getCacheSize(): { totalBytes: number; count: number } {\n const entries = listCachedFormats();\n const totalBytes = entries.reduce((sum, e) => sum + e.sizeBytes, 0);\n return { totalBytes, count: entries.length };\n}\n","/**\n * Main compiler orchestrator.\n * compile(), compileToFile(), watch().\n * Ported from tweego.go + config.go.\n */\nimport { writeFileSync } from 'node:fs';\nimport { resolve, sep } from 'node:path';\nimport type {\n CompileOptions,\n CompileToFileOptions,\n WatchOptions,\n CompileResult,\n CompileStats,\n Diagnostic,\n Story,\n StoryFormatInfo,\n OutputMode,\n InlineSource,\n FileCacheEntry,\n} from './types.js';\nimport { createStory, storyHas, getStoryStats } from './story.js';\nimport { getFilenames, isExcluded, watchFilesystem } from './filesystem.js';\nimport { discoverFormats, getFormatSearchDirs, getFormatIdByNameAndVersion } from './formats.js';\nimport { loadSources, loadInlineSources, loadSourcesCached } from './loader.js';\nimport { applyTagAliases, hasTag } from './passage.js';\nimport { generateIFID } from './ifid.js';\nimport { toTwine2HTML, toTwine2Archive } from './output-twine2.js';\nimport { toTwine1HTML, toTwine1Archive } from './output-twine1.js';\nimport { toTwee } from './output-twee.js';\nimport { modifyHead } from './modules.js';\nimport { resolveRemoteFormat, clearIndexCache } from './remote-formats.js';\nimport { VERSION } from './version.js';\n\nconst CREATOR_NAME = 'Twee-ts';\n\nconst DEFAULT_FORMAT_ID = 'sugarcube-2';\nconst DEFAULT_START_NAME = 'Start';\n\nexport class TweeTsError extends Error {\n constructor(\n message: string,\n public diagnostics: Diagnostic[] = [],\n ) {\n super(message);\n this.name = 'TweeTsError';\n }\n}\n\n/**\n * Compile Twee sources to HTML, Twee, or JSON.\n */\nexport async function compile(options: CompileOptions): Promise<CompileResult> {\n return buildOutput(options);\n}\n\n/**\n * Compile and write to a file.\n */\nexport async function compileToFile(options: CompileToFileOptions): Promise<CompileResult> {\n const result = await compile(options);\n writeFileSync(options.outFile, result.output, 'utf-8');\n return result;\n}\n\n/**\n * Compile with incremental caching support.\n * Plugins and advanced users can manage their own cache and changed-file tracking.\n */\nexport async function compileIncremental(\n options: CompileOptions,\n cache: Map<string, FileCacheEntry>,\n changedFiles?: ReadonlySet<string>,\n): Promise<CompileResult> {\n return buildOutput(options, cache, changedFiles);\n}\n\n/**\n * Watch for file changes and recompile.\n */\nexport async function watch(options: WatchOptions): Promise<AbortController> {\n const controller = new AbortController();\n const cache = new Map<string, FileCacheEntry>();\n\n // Separate file paths from inline sources\n const filePaths = options.sources.filter((s): s is string => typeof s === 'string');\n const modulePaths = options.modules ?? [];\n const allPaths = [...filePaths, ...modulePaths];\n\n // A change to an excluded source builds nothing. `exclude` leaves modules alone,\n // so a module (or a file in a module folder) still rebuilds when a glob matches it.\n const exclude = options.exclude ?? [];\n const moduleRoots = modulePaths.map((p) => resolve(p));\n const ignore = (filename: string): boolean => {\n if (!isExcluded(filename, exclude)) return false;\n const abs = resolve(filename);\n return !moduleRoots.some((root) => abs === root || abs.startsWith(root + sep));\n };\n\n const handle = watchFilesystem(\n allPaths,\n options.outFile,\n (changedFiles) => {\n buildOutput(options, cache, changedFiles)\n .then((result) => {\n writeFileSync(options.outFile, result.output, 'utf-8');\n options.onBuild?.(result);\n })\n .catch((e) => {\n options.onError?.(e instanceof Error ? e : new Error(String(e)));\n });\n },\n ignore,\n );\n\n controller.signal.addEventListener('abort', () => handle.close());\n return controller;\n}\n\nasync function buildOutput(\n options: CompileOptions,\n cache?: Map<string, FileCacheEntry>,\n changedFiles?: ReadonlySet<string>,\n): Promise<CompileResult> {\n const diagnostics: Diagnostic[] = [];\n const outputMode: OutputMode = options.outputMode ?? 'html';\n const trim = options.trim ?? true;\n const twee2Compat = options.twee2Compat ?? false;\n const testMode = options.testMode ?? false;\n const noRemote = options.noRemote ?? false;\n const sourceInfo = options.sourceInfo ?? false;\n\n // Clear per-compile index cache\n clearIndexCache();\n\n // Separate file paths from inline sources\n const filePaths: string[] = [];\n const inlineSources: InlineSource[] = [];\n for (const source of options.sources) {\n if (typeof source === 'string') {\n filePaths.push(source);\n } else {\n inlineSources.push(source);\n }\n }\n\n // Walk file paths to get all source filenames\n const { filenames: sourceFilenames, diagnostics: sourcePathDiagnostics } = getFilenames(\n filePaths,\n undefined,\n options.exclude,\n );\n diagnostics.push(...sourcePathDiagnostics);\n\n // Create story and load sources\n const story = createStory();\n const processedFiles = new Set<string>();\n\n if (cache) {\n loadSourcesCached(story, sourceFilenames, { trim, twee2Compat }, diagnostics, processedFiles, cache, changedFiles);\n } else {\n loadSources(story, sourceFilenames, { trim, twee2Compat }, diagnostics, processedFiles);\n }\n loadInlineSources(story, inlineSources, { trim, twee2Compat }, diagnostics);\n\n // Apply tag aliases (e.g. library → script)\n if (options.tagAliases) {\n story.passages = applyTagAliases(story.passages, options.tagAliases);\n }\n\n // Resolve format\n let format: StoryFormatInfo | undefined;\n let formatId = options.formatId ?? '';\n\n if (outputMode === 'html') {\n const formatSearchDirs = getFormatSearchDirs(options.formatPaths, options.useTweegoPath ?? true);\n const formats = discoverFormats(formatSearchDirs);\n\n if (!formatId && story.twine2.format) {\n formatId = getFormatIdByNameAndVersion(formats, story.twine2.format, story.twine2.formatVersion) ?? '';\n }\n if (!formatId) {\n formatId = DEFAULT_FORMAT_ID;\n }\n\n format = formats.get(formatId);\n\n // Remote format fallback\n if (!format && !noRemote) {\n // Determine the format name and version for remote lookup\n const remoteName = story.twine2.format || formatId;\n const remoteVersion = story.twine2.formatVersion || '';\n\n try {\n format = await resolveRemoteFormat(remoteName, remoteVersion, options.formatIndices, options.formatUrls);\n } catch (e) {\n diagnostics.push({\n level: 'warning',\n message: `Remote format fetch failed for \"${remoteName}\": ${e instanceof Error ? e.message : String(e)}`,\n });\n }\n }\n\n if (!format) {\n const reason = noRemote ? ' (remote fetching disabled)' : '';\n diagnostics.push({\n level: 'error',\n message: `Story format \"${formatId}\" is not available${reason}. Found: ${[...formats.keys()].join(', ') || 'none'}`,\n });\n }\n }\n\n // Merge config from StoryData: command-line > StoryData > default\n const startName = options.startPassage || story.twine2.start || DEFAULT_START_NAME;\n\n // Apply test mode\n if (testMode) {\n story.twine2.options.set('debug', true);\n }\n\n // Ensure IFID is set before output generation\n ensureIFID(story, diagnostics);\n\n // Generate output\n let output: string;\n\n switch (outputMode) {\n case 'twee3':\n case 'twee1':\n output = toTwee(story, outputMode);\n break;\n\n case 'twine2-archive':\n output = toTwine2Archive(story, startName, { sourceInfo });\n break;\n\n case 'twine1-archive':\n output = toTwine1Archive(story, startName);\n break;\n\n case 'json':\n output = storyToJSON(story);\n break;\n\n case 'html': {\n // Sanity checks for HTML mode\n if (!storyHas(story, startName)) {\n diagnostics.push({\n level: 'error',\n message: `Starting passage \"${startName}\" not found.`,\n });\n }\n\n if (!format) {\n throw new TweeTsError('No story format available for HTML output.', diagnostics);\n }\n\n if (format.isTwine2) {\n output = toTwine2HTML(story, format, startName, { sourceInfo });\n } else {\n if (story.name === '' && !storyHas(story, 'StoryTitle')) {\n diagnostics.push({\n level: 'error',\n message: 'Special passage \"StoryTitle\" not found.',\n });\n }\n output = toTwine1HTML(story, format, startName);\n }\n\n // Inject modules and head file\n const modules = getFilenames(options.modules ?? []);\n diagnostics.push(...modules.diagnostics);\n output = modifyHead(output, modules.filenames, options.headFile, diagnostics);\n break;\n }\n\n default: {\n const _exhaustive: never = outputMode;\n throw new TweeTsError(`Unhandled output mode: ${_exhaustive as string}`, diagnostics);\n }\n }\n\n // Compute stats\n const stats: CompileStats = {\n ...getStoryStats(story, options.wordCountMethod),\n files: [...processedFiles],\n };\n\n return { output, story, format, diagnostics, stats };\n}\n\nfunction ensureIFID(story: Story, diagnostics: Diagnostic[]): void {\n if (story.ifid !== '') return;\n\n if (story.legacyIFID !== '') {\n story.ifid = story.legacyIFID;\n diagnostics.push({\n level: 'warning',\n message: 'Story IFID not found; reusing \"ifid\" entry from the \"StorySettings\" special passage.',\n });\n } else {\n const ifid = generateIFID();\n story.ifid = ifid;\n diagnostics.push({\n level: 'error',\n message: `Story IFID not found. Add an IFID to your story: {\"ifid\":\"${ifid}\"}`,\n });\n }\n}\n\n/**\n * Serialize a Story to JSON per the Twine 2 JSON Output Specification (v1.0):\n * https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-jsonoutput-doc.md\n */\nfunction storyToJSON(story: Story): string {\n // Gather script and stylesheet content, excluding them from passages.\n const scripts: string[] = [];\n const stylesheets: string[] = [];\n const storyPassages: { name: string; tags: string[]; text: string; metadata?: Record<string, string> }[] = [];\n\n for (const p of story.passages) {\n if (p.name === 'StoryTitle' || p.name === 'StoryData') continue;\n if (hasTag(p, 'Twine.private')) continue;\n\n if (hasTag(p, 'script')) {\n scripts.push(p.text);\n } else if (hasTag(p, 'stylesheet')) {\n stylesheets.push(p.text);\n } else {\n const entry: { name: string; tags: string[]; text: string; metadata?: Record<string, string> } = {\n name: p.name,\n tags: p.tags,\n text: p.text,\n };\n if (p.metadata) {\n const meta: Record<string, string> = {};\n for (const [key, value] of Object.entries(p.metadata)) {\n if (typeof value === 'string') meta[key] = value;\n }\n if (Object.keys(meta).length > 0) {\n entry.metadata = meta;\n }\n }\n storyPassages.push(entry);\n }\n }\n\n const obj: Record<string, unknown> = {\n name: story.name,\n };\n\n if (story.ifid) obj.ifid = story.ifid;\n if (story.twine2.format) obj.format = story.twine2.format;\n if (story.twine2.formatVersion) obj['format-version'] = story.twine2.formatVersion;\n if (story.twine2.start) obj.start = story.twine2.start;\n if (story.twine2.tagColors.size > 0) obj['tag-colors'] = Object.fromEntries(story.twine2.tagColors);\n if (story.twine2.zoom !== 1) obj.zoom = story.twine2.zoom;\n obj.creator = CREATOR_NAME;\n obj['creator-version'] = VERSION;\n obj.style = stylesheets.join('\\n');\n obj.script = scripts.join('\\n');\n obj.passages = storyPassages;\n\n return JSON.stringify(obj, null, 2);\n}\n","/**\n * Reads the strings in JavaScript source, as the link check needs them: SugarCube evaluates\n * quoted macro arguments as strict-mode JavaScript, and stories build macro calls in the strings\n * of their scripts (`$.wiki('<<goto \"Room\">>')`).\n */\n\n/**\n * Stands in for each `${…}` substitution in a template literal's value: a Unicode noncharacter,\n * which text doesn't contain. A passage name that includes it is known only in play.\n */\nexport const SUBSTITUTION = '\\ufdd0';\n\nconst SINGLE_ESCAPES: ReadonlyMap<string, string> = new Map([\n ['b', '\\b'],\n ['f', '\\f'],\n ['n', '\\n'],\n ['r', '\\r'],\n ['t', '\\t'],\n ['v', '\\v'],\n]);\nconst HEX_RE = /^[0-9A-Fa-f]+$/;\nconst DIGIT_RE = /^[0-9]$/;\nconst LINE_TERMINATORS = '\\n\\r\\u2028\\u2029';\n\n/**\n * The value of a quoted JavaScript string literal (quotes included), as strict-mode JavaScript\n * evaluates it: `\\\"`, `\\'`, `\\\\`, `\\n`, `\\xHH`, `\\uHHHH`, `\\u{H…}`, line continuations, and a\n * backslash before any other character gives that character. Returns `undefined` for what\n * strict mode rejects, such as `\\1` or a raw carriage return.\n */\nexport function evalStringLiteral(literal: string): string | undefined {\n const quote = literal[0];\n const last = literal.length - 1;\n if ((quote !== '\"' && quote !== \"'\") || last < 1 || literal[last] !== quote) {\n return undefined;\n }\n return cookEscapes(literal.slice(1, last), quote);\n}\n\n/**\n * Decodes the body of a string literal, given its quote, or a piece of a template literal\n * (`quote` undefined), as strict-mode JavaScript does. A string may not hold its own quote or a\n * raw line feed or carriage return; a template piece may, and turns `\\r\\n` and `\\r` into `\\n`.\n */\nfunction cookEscapes(body: string, quote: string | undefined): string | undefined {\n let value = '';\n let i = 0;\n while (i < body.length) {\n const ch = body.charAt(i);\n if (ch !== '\\\\') {\n if (quote !== undefined && (ch === quote || ch === '\\n' || ch === '\\r')) {\n return undefined;\n }\n if (ch === '\\r') {\n value += '\\n';\n i += body.charAt(i + 1) === '\\n' ? 2 : 1;\n } else {\n value += ch;\n i += 1;\n }\n continue;\n }\n if (i + 1 >= body.length) {\n // In a string, the backslash would escape the closing quote.\n return undefined;\n }\n const escaped = body.charAt(i + 1);\n i += 2;\n const single = SINGLE_ESCAPES.get(escaped);\n if (single !== undefined) {\n value += single;\n continue;\n }\n switch (escaped) {\n case '0':\n if (DIGIT_RE.test(body.charAt(i))) {\n return undefined;\n }\n value += '\\0';\n break;\n case '1':\n case '2':\n case '3':\n case '4':\n case '5':\n case '6':\n case '7':\n case '8':\n case '9':\n return undefined;\n case 'x': {\n const hex = body.slice(i, i + 2);\n if (hex.length !== 2 || !HEX_RE.test(hex)) {\n return undefined;\n }\n value += String.fromCharCode(parseInt(hex, 16));\n i += 2;\n break;\n }\n case 'u': {\n const unicode = readUnicodeEscape(body, i);\n if (unicode === undefined) {\n return undefined;\n }\n value += unicode.char;\n i = unicode.end;\n break;\n }\n case '\\r':\n // A line continuation; `\\r\\n` counts as one line break.\n if (body[i] === '\\n') {\n i += 1;\n }\n break;\n case '\\n':\n case '\\u2028':\n case '\\u2029':\n break;\n default:\n value += escaped;\n }\n }\n return value;\n}\n\n/** Reads the part of `\\uHHHH` or `\\u{H…}` after the `u`. */\nfunction readUnicodeEscape(body: string, from: number): { char: string; end: number } | undefined {\n if (body[from] === '{') {\n const close = body.indexOf('}', from + 1);\n if (close === -1) {\n return undefined;\n }\n const hex = body.slice(from + 1, close);\n if (!HEX_RE.test(hex)) {\n return undefined;\n }\n const codePoint = parseInt(hex, 16);\n return codePoint > 0x10ffff ? undefined : { char: String.fromCodePoint(codePoint), end: close + 1 };\n }\n const hex = body.slice(from, from + 4);\n if (hex.length !== 4 || !HEX_RE.test(hex)) {\n return undefined;\n }\n return { char: String.fromCharCode(parseInt(hex, 16)), end: from + 4 };\n}\n\n// Words after which a `/` starts a regular expression rather than a division.\nconst REGEX_KEYWORDS: ReadonlySet<string> = new Set([\n 'await',\n 'case',\n 'delete',\n 'do',\n 'else',\n 'in',\n 'instanceof',\n 'new',\n 'of',\n 'return',\n 'throw',\n 'typeof',\n 'void',\n 'yield',\n]);\nconst WORD_RE = /[$\\p{ID_Continue}\\u200c\\u200d]+/uy;\nconst WHITESPACE_RE = /\\s/;\nconst LINE_TERMINATOR_RE = /[\\n\\r\\u2028\\u2029]/g;\n\n/** A template literal being read: its value so far, and where its current piece starts. */\ninterface TemplateFrame {\n readonly kind: 'template';\n readonly value: string;\n readonly pieceStart: number;\n /** False once a piece holds an escape that strict mode rejects. */\n readonly valid: boolean;\n}\n\n/** Code: the whole source, or a template's `${…}` substitution, with its open `{` count. */\ninterface CodeFrame {\n readonly kind: 'code';\n readonly braces: number;\n}\n\ntype Frame = TemplateFrame | CodeFrame;\n\n/**\n * The values of the string and template literals in JavaScript source. A template literal's\n * value keeps its text and has `SUBSTITUTION` where each `${…}` was; the strings inside a\n * substitution are values of their own. Comments and regular expression literals are skipped;\n * whether a `/` starts a regular expression is judged from the token before it. Malformed\n * source is read on as far as it can be.\n */\nexport function javaScriptStrings(source: string): string[] {\n const strings: string[] = [];\n // The bottom frame is the source itself, which is never closed.\n const frames: Frame[] = [{ kind: 'code', braces: 0 }];\n let regexAllowed = true;\n let afterDot = false;\n // Where a string of each quote, or a regular expression, is known not to close.\n const failedUntil = new Map<string, number>();\n let i = 0;\n while (i < source.length) {\n const frame = frames[frames.length - 1];\n if (frame === undefined) {\n // The bottom frame is never popped.\n break;\n }\n const ch = source.charAt(i);\n const next = source.charAt(i + 1);\n\n if (frame.kind === 'template') {\n if (ch === '`' || (ch === '$' && next === '{')) {\n const piece = cookEscapes(source.slice(frame.pieceStart, i), undefined);\n const value = frame.value + (piece ?? '');\n const valid = frame.valid && piece !== undefined;\n frames.pop();\n if (ch === '`') {\n if (valid) {\n strings.push(value);\n }\n i += 1;\n regexAllowed = false;\n afterDot = false;\n } else {\n frames.push({ kind: 'template', value: value + SUBSTITUTION, pieceStart: -1, valid });\n frames.push({ kind: 'code', braces: 0 });\n i += 2;\n regexAllowed = true;\n afterDot = false;\n }\n } else {\n i += ch === '\\\\' ? 2 : 1;\n }\n continue;\n }\n\n if (ch === '/' && next === '/') {\n const lineEnd = searchFrom(LINE_TERMINATOR_RE, source, i + 2);\n i = lineEnd === -1 ? source.length : lineEnd;\n continue;\n }\n if (ch === '/' && next === '*') {\n const close = source.indexOf('*/', i + 2);\n i = close === -1 ? source.length : close + 2;\n continue;\n }\n if (ch === '/' && regexAllowed && i >= (failedUntil.get('/') ?? 0)) {\n const end = endOfRegularExpression(source, i);\n if (end.end !== undefined) {\n i = end.end;\n regexAllowed = false;\n afterDot = false;\n continue;\n }\n failedUntil.set('/', end.stop);\n }\n if ((ch === '\"' || ch === \"'\") && i >= (failedUntil.get(ch) ?? 0)) {\n const end = endOfJavaScriptString(source, i);\n if (end.end !== undefined) {\n const value = evalStringLiteral(source.slice(i, end.end));\n if (value !== undefined) {\n strings.push(value);\n }\n i = end.end;\n regexAllowed = false;\n afterDot = false;\n continue;\n }\n failedUntil.set(ch, end.stop);\n }\n if (ch === '`') {\n frames.push({ kind: 'template', value: '', pieceStart: i + 1, valid: true });\n i += 1;\n continue;\n }\n const word = wordAt(source, i);\n if (word !== null) {\n // A keyword after a `.` is a property name, which a `/` divides.\n regexAllowed = !afterDot && REGEX_KEYWORDS.has(word[0]);\n afterDot = false;\n i += word[0].length;\n continue;\n }\n if ((ch === '+' || ch === '-') && next === ch) {\n // After `x++` or `x--`, a `/` divides.\n regexAllowed = false;\n afterDot = false;\n i += 2;\n continue;\n }\n if (frame.kind === 'code' && frames.length > 1 && (ch === '{' || ch === '}')) {\n if (ch === '{') {\n frames[frames.length - 1] = { kind: 'code', braces: frame.braces + 1 };\n } else if (frame.braces > 0) {\n frames[frames.length - 1] = { kind: 'code', braces: frame.braces - 1 };\n } else {\n // The `}` that closes a substitution: the template goes on after it.\n frames.pop();\n const template = frames.pop();\n if (template?.kind === 'template') {\n frames.push({ ...template, pieceStart: i + 1 });\n }\n i += 1;\n continue;\n }\n }\n if (!WHITESPACE_RE.test(ch)) {\n // After a closing bracket, as after a name or a number, a `/` divides.\n regexAllowed = !')]}'.includes(ch);\n afterDot = ch === '.';\n }\n i += 1;\n }\n return strings;\n}\n\n/** The name, keyword or number that starts at `pos`, if one does. */\nfunction wordAt(source: string, pos: number): RegExpExecArray | null {\n const code = source.charCodeAt(pos);\n const ascii = code < 0x80;\n // Only ASCII letters, digits, `_` and `$` start a word below U+0080.\n if (\n ascii &&\n !(\n (code >= 0x30 && code <= 0x39) ||\n ((code | 0x20) >= 0x61 && (code | 0x20) <= 0x7a) ||\n code === 0x5f ||\n code === 0x24\n )\n ) {\n return null;\n }\n WORD_RE.lastIndex = pos;\n return WORD_RE.exec(source);\n}\n\n/** Index of the first match of a global `re` at or after `from`, or -1. */\nfunction searchFrom(re: RegExp, text: string, from: number): number {\n re.lastIndex = from;\n const m = re.exec(text);\n return m === null ? -1 : m.index;\n}\n\n/**\n * Where a string literal that opens at `pos` ends, or, if it doesn't close on its line, where\n * the scan stopped. A string with the same quote that starts before that stop, inside this one,\n * doesn't close either.\n */\nfunction endOfJavaScriptString(source: string, pos: number): { end: number | undefined; stop: number } {\n const quote = source.charAt(pos);\n let i = pos + 1;\n while (i < source.length) {\n const ch = source.charAt(i);\n if (ch === quote) {\n return { end: i + 1, stop: i };\n }\n if (ch === '\\n' || ch === '\\r') {\n return { end: undefined, stop: i };\n }\n if (ch === '\\\\') {\n // A backslash before a line break continues the string; `\\r\\n` is one line break.\n i += source.startsWith('\\r\\n', i + 1) ? 3 : 2;\n } else {\n i += 1;\n }\n }\n return { end: undefined, stop: source.length };\n}\n\n/**\n * Where a regular expression literal that opens at `pos` ends, flags included, or, if none\n * closes on the line, where the line ends. A `/` before that is then read as a division.\n */\nfunction endOfRegularExpression(source: string, pos: number): { end: number | undefined; stop: number } {\n let inClass = false;\n let i = pos + 1;\n while (i < source.length) {\n const ch = source.charAt(i);\n if (LINE_TERMINATORS.includes(ch)) {\n return { end: undefined, stop: i };\n }\n if (ch === '\\\\') {\n const escaped = source.charAt(i + 1);\n if (escaped === '' || LINE_TERMINATORS.includes(escaped)) {\n return { end: undefined, stop: i + 1 };\n }\n i += 2;\n continue;\n }\n if (ch === '[') {\n inClass = true;\n } else if (ch === ']') {\n inClass = false;\n } else if (ch === '/' && !inClass) {\n WORD_RE.lastIndex = i + 1;\n const flags = WORD_RE.exec(source);\n return { end: i + 1 + (flags === null ? 0 : flags[0].length), stop: i };\n }\n i += 1;\n }\n return { end: undefined, stop: source.length };\n}\n","/**\n * Reads SugarCube 2 macro calls the way SugarCube 2.37.3 does, so the link check sees the same\n * passage names that `<<link>>` and `<<goto>>` use when the story plays.\n *\n * Each step follows a part of SugarCube's macro parser:\n * - `findMacroTags` finds where a tag starts and ends (the parser's `lookahead` pattern);\n * - `parseMacroArgs` splits the text after the macro name into arguments (`parseArgs`);\n * - quoted arguments are evaluated as strict-mode JavaScript strings (`evalStringLiteral`).\n *\n * Of the rest of the wikifier, only comments, `<script>` elements and `<<script>>` bodies are\n * told apart; other markup, such as verbatim text, is read as markup (see\n * `findMacroPassageLinks`).\n */\nimport { SUBSTITUTION, evalStringLiteral, javaScriptStrings } from './javascript-strings.js';\n\n/** A macro tag: `<<name args>>`, or a closing tag `<</name>>`. */\nexport interface MacroTag {\n /** The macro name, with a leading `/` for a closing tag. */\n readonly name: string;\n /** The text between the name (and the spaces after it) and the closing `>>`. */\n readonly args: string;\n /** Index of the opening `<<`. */\n readonly start: number;\n /** Index just past the closing `>>`. */\n readonly end: number;\n}\n\n/** What a macro argument evaluates to, as far as that is known without playing the story. */\nexport type MacroArg =\n /** A quoted string, or a bare word SugarCube keeps as text. */\n | { readonly type: 'string'; readonly value: string }\n /** A bare word SugarCube converts to a number. */\n | { readonly type: 'number'; readonly value: number }\n /** Link or image markup: `[[…]]` or `[img[…]]`. */\n | { readonly type: 'markup' }\n | { readonly type: 'null' }\n /** A variable, an expression, `setup`/`settings`, a boolean or `undefined`. */\n | { readonly type: 'other' };\n\n/** A passage named by a `<<link>>` or `<<goto>>` call. */\nexport interface MacroPassageLink {\n readonly macro: 'goto' | 'link';\n readonly passage: string;\n}\n\n/** An argument as SugarCube's lexer splits it, before its value is worked out. */\ntype LexedArg =\n | { readonly kind: 'string'; readonly value: string }\n | { readonly kind: 'expression'; readonly code: string }\n | { readonly kind: 'markup' }\n | { readonly kind: 'word'; readonly text: string };\n\n/** A tag, and where a `<<link` or `<<goto` first appears unquoted in its arguments, if it does. */\nexport interface ScannedTag {\n readonly tag: MacroTag;\n readonly innerCall: number | undefined;\n}\n\n// SugarCube's `Patterns.macroName`, preceded by the optional `/` of a closing tag.\nconst NAME_RE = /\\/?[A-Za-z][\\w-]*|[=-]/y;\nconst SPACES_RE = /\\s*/y;\nconst LINE_TERMINATOR_RE = /[\\n\\r\\u2028\\u2029]/g;\nconst SQUARE_BRACKET_OPEN_RE = /\\[(?:[<>]?[Ii][Mm][Gg])?\\[/y;\n\n// SugarCube's `Patterns.space` and `Patterns.notSpace`: JavaScript's `\\s` plus U+180E, which\n// `\\s` no longer matches.\nconst SPACE_RE = /[\\s\\u180e]/g;\nconst NOT_SPACE_RE = /[^\\s\\u180e]/g;\nconst VARIABLE_RE = /^[$_][$A-Z_a-z][$0-9A-Z_a-z]*/;\nconst SETTINGS_OR_SETUP_RE = /^(?:settings|setup)[.[]/;\nconst IMAGE_MARKUP_CHARS = '<>IiMmGg';\n\n/**\n * Macros that SugarCube doesn't split into arguments (`skipArgs` in 2.37.3), with their child\n * tags that do the same: `<<elseif>>` and `<<else>>` of `<<if>>`, and `<<optionsfrom>>` of\n * `<<cycle>>` and `<<listbox>>`. Their argument text is TwineScript, or for `<<capture>>`,\n * `<<unset>>` and `<<for>>` a syntax of their own; either way its strings are JavaScript strings.\n */\nconst RAW_ARGUMENT_MACROS: ReadonlySet<string> = new Set([\n 'break',\n 'capture',\n 'continue',\n 'done',\n 'else',\n 'elseif',\n 'for',\n 'if',\n 'nobr',\n 'optionsfrom',\n 'print',\n '=',\n '-',\n 'run',\n 'set',\n 'silent',\n 'silently',\n 'stop',\n 'switch',\n 'unset',\n 'waitforaudio',\n]);\n\n/**\n * How deep strings inside macro arguments are read for further calls. Stories nest two or three\n * levels; the limit keeps the work linear in the size of the text on any input.\n */\nconst MAX_STRING_DEPTH = 10;\n\n/**\n * What one reading of a passage carries down into the strings it reads: how deep it is, and how\n * much the `<<script>>` closer search has left to read (see `scriptBodyCloser`).\n */\ninterface ReadContext {\n readonly depth: number;\n readonly budget: { left: number };\n}\n\n/** A context for reading `text`: the closer search may read four times it, plus an allowance. */\nfunction readContext(text: string): ReadContext {\n return { depth: 0, budget: { left: 4 * text.length + 100_000 } };\n}\n\nfunction deeper(context: ReadContext): ReadContext {\n return { depth: context.depth + 1, budget: context.budget };\n}\n\n/** Index of the first match of a global `re` at or after `from`, or -1. */\nfunction searchFrom(re: RegExp, text: string, from: number): number {\n re.lastIndex = from;\n const m = re.exec(text);\n return m === null ? -1 : m.index;\n}\n\n/**\n * Finds the macro tags in text, in order, trying a tag at every `<<` as SugarCube's macro\n * parser does. A tag that doesn't parse is skipped, and the search goes on after its `<<`.\n *\n * Gives the same tags as SugarCube's pattern, without its backtracking: that pattern takes\n * exponential time when no `>>` follows a `<<name`, which a script passage can contain (`1<<n`).\n */\nexport function findMacroTags(text: string): MacroTag[] {\n return scanTags(text).map((scanned) => scanned.tag);\n}\n\nfunction scanTags(text: string): ScannedTag[] {\n const matchTagAt = tagMatcher(text);\n const tags: ScannedTag[] = [];\n let start = text.indexOf('<<');\n while (start !== -1) {\n const scanned = matchTagAt(start);\n if (scanned === undefined) {\n start = text.indexOf('<<', start + 2);\n } else {\n tags.push(scanned);\n start = text.indexOf('<<', scanned.tag.end);\n }\n }\n return tags;\n}\n\n/** A kind of argument part in which a `>>` doesn't end the tag, named by how it opens. */\ntype ArgumentPartKind = '/*' | '//' | '`' | '\"' | \"'\" | '[';\n\n/** How far an argument part reaches. */\ninterface ArgumentPartScan {\n /** Index just past the part, or `undefined` if it is never closed. */\n readonly end: number | undefined;\n /**\n * Where the scan stopped: at the part's closing quote, `*` + `/`, line end or `]]`, or where\n * it failed. A part of the same kind that starts inside this one, before this index, ends or\n * fails no earlier.\n */\n readonly stop: number;\n}\n\n/**\n * Returns a function that matches a tag at a `<<` in `text`. It must be called for positions in\n * increasing order.\n *\n * The arguments may contain comments, backquoted expressions, quoted strings and link markup,\n * whose `>>` doesn't end the tag. SugarCube's pattern treats such a part as a unit only if a\n * `>>` still follows it, and otherwise as plain characters; `lastClose`, the last `>>` in the\n * text, answers that in constant time. Once a part is read as plain characters, a part of the\n * same kind that starts inside it can't end before `lastClose` either, in this tag or a later\n * one, so it isn't scanned again: `scanFrom` records where each kind may next be scanned. This\n * keeps the search linear. `onWork` is told how many characters each step reads. (Exported for\n * tests; the module is not part of the package's API.)\n */\nexport function tagMatcher(\n text: string,\n lastClose = text.lastIndexOf('>>'),\n onWork: (characters: number) => void = () => {},\n): (start: number) => ScannedTag | undefined {\n const scanFrom = new Map<ArgumentPartKind, number>();\n return (start) => {\n NAME_RE.lastIndex = start + 2;\n const nameMatch = NAME_RE.exec(text);\n if (nameMatch === null) {\n onWork(2);\n return undefined;\n }\n SPACES_RE.lastIndex = NAME_RE.lastIndex;\n SPACES_RE.exec(text);\n const argsStart = SPACES_RE.lastIndex;\n onWork(argsStart - start);\n\n let innerCall: number | undefined;\n let pos = argsStart;\n while (pos <= lastClose) {\n if (text.startsWith('>>', pos)) {\n const tag = { name: nameMatch[0], args: text.slice(argsStart, pos), start, end: pos + 2 };\n return { tag, innerCall };\n }\n const kind = argumentPartKindAt(text, pos);\n const from = kind === undefined ? undefined : scanFrom.get(kind);\n if (kind !== undefined && (from === undefined || pos >= from)) {\n const part = scanArgumentPart(text, pos, kind);\n onWork(part.stop - pos);\n if (part.end !== undefined && part.end <= lastClose) {\n pos = part.end;\n continue;\n }\n scanFrom.set(kind, part.stop);\n }\n if (innerCall === undefined && startsPassageLinkCall(text, pos)) {\n innerCall = pos;\n }\n onWork(1);\n pos += 1;\n }\n return undefined;\n };\n}\n\n/** Whether a `<<link` or `<<goto` tag, and not a longer macro name, starts at `pos`. */\nfunction startsPassageLinkCall(text: string, pos: number): boolean {\n if (!text.startsWith('<<', pos)) {\n return false;\n }\n NAME_RE.lastIndex = pos + 2;\n const name = NAME_RE.exec(text)?.[0];\n return name === 'link' || name === 'goto';\n}\n\n/** The kind of argument part that opens at `pos`, if one does. */\nfunction argumentPartKindAt(text: string, pos: number): ArgumentPartKind | undefined {\n const ch = text[pos];\n switch (ch) {\n case '/': {\n const next = text[pos + 1];\n return next === '*' ? '/*' : next === '/' ? '//' : undefined;\n }\n case '`':\n case '\"':\n case \"'\":\n case '[':\n return ch;\n default:\n return undefined;\n }\n}\n\nfunction scanArgumentPart(text: string, pos: number, kind: ArgumentPartKind): ArgumentPartScan {\n switch (kind) {\n case '/*': {\n const close = text.indexOf('*/', pos + 2);\n return close === -1 ? { end: undefined, stop: text.length } : { end: close + 2, stop: close };\n }\n case '//': {\n // `//.*\\n`: the comment must end at a line feed, not at any other line terminator.\n const lineEnd = searchFrom(LINE_TERMINATOR_RE, text, pos + 2);\n if (lineEnd === -1) {\n return { end: undefined, stop: text.length };\n }\n return { end: text[lineEnd] === '\\n' ? lineEnd + 1 : undefined, stop: lineEnd };\n }\n case '`':\n case '\"':\n case \"'\":\n return scanQuoted(text, pos, kind);\n case '[':\n return scanSquareBracketed(text, pos);\n default: {\n const _exhaustive: never = kind;\n throw new Error(`unhandled argument part: ${String(_exhaustive)}`);\n }\n }\n}\n\n/** A quoted part of a tag: a backslash escapes any character except a line terminator. */\nfunction scanQuoted(text: string, pos: number, quote: string): ArgumentPartScan {\n let i = pos + 1;\n while (i < text.length) {\n const ch = text[i];\n if (ch === quote) {\n return { end: i + 1, stop: i };\n }\n if (ch === '\\\\') {\n const next = text[i + 1];\n if (next === undefined || '\\n\\r\\u2028\\u2029'.includes(next)) {\n return { end: undefined, stop: i };\n }\n i += 2;\n } else {\n i += 1;\n }\n }\n return { end: undefined, stop: text.length };\n}\n\n/** Link or image markup in a tag: up to the first `]]` on the same line, plus any further `]`. */\nfunction scanSquareBracketed(text: string, pos: number): ArgumentPartScan {\n SQUARE_BRACKET_OPEN_RE.lastIndex = pos;\n if (!SQUARE_BRACKET_OPEN_RE.test(text)) {\n return { end: undefined, stop: pos + 1 };\n }\n for (let i = SQUARE_BRACKET_OPEN_RE.lastIndex; i < text.length; i++) {\n const ch = text[i];\n if (ch === '\\n' || ch === '\\r') {\n return { end: undefined, stop: i };\n }\n if (ch === ']' && text[i + 1] === ']') {\n let end = i + 2;\n while (text[end] === ']') {\n end += 1;\n }\n return { end, stop: i };\n }\n }\n return { end: undefined, stop: text.length };\n}\n\n/**\n * Splits a tag's argument text into arguments, as SugarCube's `parseArgs` does. Returns\n * `undefined` where SugarCube throws while splitting the text or reading a string, so the macro\n * call does nothing. (SugarCube also parses link markup a second time and rejects some that it\n * split without trouble, such as `[[\"x]]`; that is still returned as markup here.)\n */\nexport function parseMacroArgs(raw: string): MacroArg[] | undefined {\n return lexMacroArgs(raw)?.map(argValue);\n}\n\nfunction lexMacroArgs(raw: string): LexedArg[] | undefined {\n const args: LexedArg[] = [];\n let pos = searchFrom(NOT_SPACE_RE, raw, 0);\n while (pos !== -1) {\n const lexed = lexArgument(raw, pos);\n if (lexed === undefined) {\n return undefined;\n }\n args.push(lexed.arg);\n pos = searchFrom(NOT_SPACE_RE, raw, lexed.end);\n }\n return args;\n}\n\nfunction lexArgument(raw: string, pos: number): { arg: LexedArg; end: number } | undefined {\n const first = raw[pos];\n switch (first) {\n case '`': {\n const end = slurpQuote(raw, pos + 1, '`');\n return end === undefined ? undefined : { arg: { kind: 'expression', code: raw.slice(pos + 1, end - 1) }, end };\n }\n case '\"':\n case \"'\": {\n const end = slurpQuote(raw, pos + 1, first);\n if (end === undefined) {\n return undefined;\n }\n const value = evalStringLiteral(raw.slice(pos, end));\n return value === undefined ? undefined : { arg: { kind: 'string', value }, end };\n }\n case '[': {\n const end = lexSquareBracketed(raw, pos + 1);\n return end === undefined ? undefined : { arg: { kind: 'markup' }, end };\n }\n default: {\n const space = searchFrom(SPACE_RE, raw, pos + 1);\n const end = space === -1 ? raw.length : space;\n return { arg: { kind: 'word', text: raw.slice(pos, end) }, end };\n }\n }\n}\n\n/**\n * Reads a quoted argument from just after its opening quote. A newline, or a backslash before a\n * newline, ends it unterminated. Returns the index after the closing quote.\n */\nfunction slurpQuote(raw: string, from: number, endQuote: string): number | undefined {\n let i = from;\n while (i < raw.length) {\n const ch = raw[i];\n if (ch === endQuote) {\n return i + 1;\n }\n if (ch === '\\n') {\n return undefined;\n }\n if (ch === '\\\\') {\n const next = raw[i + 1];\n if (next === undefined || next === '\\n') {\n return undefined;\n }\n i += 2;\n } else {\n i += 1;\n }\n }\n return undefined;\n}\n\n/**\n * Reads link or image markup from just after its first `[`, counting nested brackets.\n * Returns the index after the closing `]]`.\n */\nfunction lexSquareBracketed(raw: string, from: number): number | undefined {\n let i = from;\n while (i < raw.length && IMAGE_MARKUP_CHARS.includes(raw.charAt(i))) {\n i += 1;\n }\n if (raw[i] !== '[') {\n return undefined;\n }\n i += 1;\n let depth = 2;\n while (i < raw.length) {\n const ch = raw[i];\n i += 1;\n switch (ch) {\n case '\\\\': {\n const next = raw[i];\n if (next === undefined || next === '\\n') {\n return undefined;\n }\n i += 1;\n break;\n }\n case '\\n':\n return undefined;\n case '[':\n depth += 1;\n break;\n case ']':\n depth -= 1;\n if (depth < 0) {\n return undefined;\n }\n if (depth === 1 && raw[i] === ']') {\n return i + 1;\n }\n break;\n default:\n break;\n }\n }\n return undefined;\n}\n\n/** An argument's value, following SugarCube's conversions. */\nfunction argValue(arg: LexedArg): MacroArg {\n switch (arg.kind) {\n case 'string':\n return { type: 'string', value: arg.value };\n case 'expression':\n // Its value is known only in play.\n return { type: 'other' };\n case 'markup':\n return { type: 'markup' };\n case 'word':\n return bareWord(arg.text);\n default: {\n const _exhaustive: never = arg;\n throw new Error(`unhandled macro argument: ${JSON.stringify(_exhaustive)}`);\n }\n }\n}\n\n/** A bare word's value, following SugarCube's conversions. */\nfunction bareWord(word: string): MacroArg {\n if (VARIABLE_RE.test(word) || SETTINGS_OR_SETUP_RE.test(word)) {\n return { type: 'other' };\n }\n switch (word) {\n case 'null':\n return { type: 'null' };\n case 'undefined':\n case 'true':\n case 'false':\n return { type: 'other' };\n case 'NaN':\n return { type: 'number', value: NaN };\n default: {\n const value = Number(word);\n return Number.isNaN(value) ? { type: 'string', value: word } : { type: 'number', value };\n }\n }\n}\n\n/** The passage name an argument gives, if it can be known without playing the story. */\nfunction passageName(arg: MacroArg): string | undefined {\n switch (arg.type) {\n case 'string':\n // A template literal's `${…}` makes the name known only in play.\n return arg.value.includes(SUBSTITUTION) ? undefined : arg.value;\n case 'number':\n // SugarCube looks a number up as a passage name by its string form.\n return String(arg.value);\n case 'markup':\n // Markup names its passage in `[[…]]`, which the link check reads on its own.\n case 'null':\n case 'other':\n return undefined;\n default: {\n const _exhaustive: never = arg;\n throw new Error(`unhandled macro argument: ${JSON.stringify(_exhaustive)}`);\n }\n }\n}\n\n/**\n * The argument that names the passage in a `<<link>>` or `<<goto>>` call:\n * - `<<link linkText [passageName]>>`, unless the first argument is link or image markup, which\n * then names the passage itself and any further argument is ignored;\n * - `<<goto passageName>>`.\n *\n * In text built from a template literal, a bare word with a `${…}` in it may become several\n * words in play, so no argument after it is known.\n */\nfunction passageArgument(macro: MacroPassageLink['macro'], lexed: readonly LexedArg[]): MacroArg | undefined {\n const index = macro === 'link' ? 1 : 0;\n if (lexed.slice(0, index + 1).some((arg) => arg.kind === 'word' && arg.text.includes(SUBSTITUTION))) {\n return undefined;\n }\n const args = lexed.map(argValue);\n switch (macro) {\n case 'link': {\n const [label, passage] = args;\n // A `null` label makes SugarCube throw, as it reads `null` as markup.\n return label === undefined || label.type === 'markup' || label.type === 'null' ? undefined : passage;\n }\n case 'goto':\n return args[0];\n default: {\n const _exhaustive: never = macro;\n throw new Error(`unhandled macro: ${String(_exhaustive)}`);\n }\n }\n}\n\nfunction isPassageLinkMacro(name: string): name is MacroPassageLink['macro'] {\n return name === 'goto' || name === 'link';\n}\n\n/** The passage a `<<link>>` or `<<goto>>` tag names itself, if it can be known before play. */\nfunction ownPassageLink(tag: MacroTag, lexed: readonly LexedArg[]): MacroPassageLink | undefined {\n if (!isPassageLinkMacro(tag.name)) {\n return undefined;\n }\n const arg = passageArgument(tag.name, lexed);\n const passage = arg === undefined ? undefined : passageName(arg);\n return passage === undefined ? undefined : { macro: tag.name, passage };\n}\n\n/**\n * The passages a tag names: its own, if it is a `<<link>>` or `<<goto>>` call, then those of the\n * calls inside the strings of its arguments, which the macro may print or pass on\n * (`<<set _out to '<<link \"Go\" \"Room\">><</link>>'>>`). The arguments of the macros SugarCube\n * doesn't split are read as JavaScript; in others, a backquoted expression is.\n */\nfunction tagPassageLinks(tag: MacroTag, context: ReadContext): MacroPassageLink[] {\n if (RAW_ARGUMENT_MACROS.has(tag.name)) {\n return javaScriptPassageLinks(tag.args, context);\n }\n const lexed = lexMacroArgs(tag.args);\n if (lexed === undefined) {\n // SugarCube throws, so the call does nothing.\n return [];\n }\n const own = ownPassageLink(tag, lexed);\n const inner = lexed.flatMap((arg): MacroPassageLink[] => {\n switch (arg.kind) {\n case 'string':\n return markupPassageLinks(arg.value, deeper(context));\n case 'expression':\n return javaScriptPassageLinks(arg.code, context);\n case 'markup':\n case 'word':\n return [];\n default: {\n const _exhaustive: never = arg;\n throw new Error(`unhandled macro argument: ${JSON.stringify(_exhaustive)}`);\n }\n }\n });\n return own === undefined ? inner : [own, ...inner];\n}\n\n/**\n * The passage named by a `<<link>>` or `<<goto>>` that appears unquoted inside another tag's\n * arguments, at `start`. SugarCube never sees such an outer \"tag\" when its `<<` lies in text it\n * reads as something else, such as link markup (`[[<<-- Back|Prev]]`); the call inside it then\n * runs. The call ends where the outer tag ends.\n */\nfunction innerPassageLink(\n matchTagAt: (start: number) => ScannedTag | undefined,\n start: number,\n): MacroPassageLink | undefined {\n const inner = matchTagAt(start)?.tag;\n const lexed = inner === undefined ? undefined : lexMacroArgs(inner.args);\n return inner === undefined || lexed === undefined ? undefined : ownPassageLink(inner, lexed);\n}\n\n// Where a comment, a `<script>` element or italics can start: the other markup whose text holds\n// no call. `//` is here only because it comes first, as in SugarCube: `//*` is italics.\nconst REGION_OPEN_RE = /\\/\\/|\\/\\*|\\/%|<!--|<[Ss][Cc][Rr][Ii][Pp][Tt]/g;\nconst HAS_SCRIPT_OPEN_RE = /<[Ss][Cc][Rr][Ii][Pp][Tt]/;\n// SugarCube's `(?:.|\\n)*?` doesn't cross the other line terminators.\nconst SCRIPT_CLOSE_RE = /<\\/[Ss][Cc][Rr][Ii][Pp][Tt]>|[\\r\\u2028\\u2029]/g;\nconst COMMENT_CLOSE_RES: Readonly<Record<CommentKind, RegExp>> = {\n '/*': /\\*\\/|[\\r\\u2028\\u2029]/g,\n '/%': /%\\/|[\\r\\u2028\\u2029]/g,\n '<!--': /-->|[\\r\\u2028\\u2029]/g,\n};\ntype CommentKind = '/*' | '/%' | '<!--';\n\n/**\n * Returns a function that finds where a comment that opens at `start` ends, as SugarCube's\n * `commentByBlock` parser reads it, or `undefined` if it isn't closed. Calls of one kind must come\n * in increasing order: a search that fails stops at a line terminator or the end, and a later one\n * of the same kind that starts before that stop fails too, so it isn't made.\n */\nfunction commentReader(text: string): (kind: CommentKind, start: number) => number | undefined {\n const failedUntil = new Map<CommentKind, number>();\n return (kind, start) => {\n if (start < (failedUntil.get(kind) ?? -1)) {\n return undefined;\n }\n const re = COMMENT_CLOSE_RES[kind];\n re.lastIndex = start + kind.length;\n const m = re.exec(text);\n if (m !== null && m[0].length > 1) {\n return m.index + m[0].length;\n }\n failedUntil.set(kind, m === null ? text.length : m.index);\n return undefined;\n };\n}\n\n/** Where a `<script>` element's opener ends and its content ends, if it is complete. */\ninterface ScriptElementScan {\n /** Index just past the opener's `>`, or `undefined` if no `>` follows. */\n readonly openerEnd: number | undefined;\n /** Index of the closing `</script>`, or `undefined` if the element isn't closed. */\n readonly close: number | undefined;\n}\n\n/**\n * Returns a function that reads a `<script>` element whose opener starts at a position, as\n * SugarCube's `verbatimScriptTag` parser reads it: the opener up to its `>`, then the content\n * up to the first `</script>`. Calls must come in increasing order; each part of the text is\n * searched once.\n */\nfunction scriptElementReader(text: string): (start: number) => ScriptElementScan {\n let angle = -1;\n let noAngleAfter = Infinity;\n let failedBefore = -1;\n let noCloseAfter = Infinity;\n return (start) => {\n if (start + 7 >= noAngleAfter) {\n return { openerEnd: undefined, close: undefined };\n }\n if (angle < start + 7) {\n angle = text.indexOf('>', start + 7);\n if (angle === -1) {\n noAngleAfter = start + 7;\n return { openerEnd: undefined, close: undefined };\n }\n }\n const openerEnd = angle + 1;\n if (openerEnd < failedBefore || openerEnd >= noCloseAfter) {\n // The content would run into the line terminator where an earlier element failed.\n return { openerEnd, close: undefined };\n }\n SCRIPT_CLOSE_RE.lastIndex = openerEnd;\n const m = SCRIPT_CLOSE_RE.exec(text);\n if (m === null) {\n noCloseAfter = openerEnd;\n return { openerEnd, close: undefined };\n }\n if (m[0].length === 1) {\n failedBefore = m.index;\n return { openerEnd, close: undefined };\n }\n return { openerEnd, close: m.index };\n };\n}\n\n/**\n * Returns a function that finds the tag closing the `<<script>>` body that `opener` opens, as\n * SugarCube's `parseBody` finds it: scanning tags from every `<<` after the opener, without\n * skipping anything, for the first `<</script>>` or `<<endscript>>` that isn't matched by a\n * later `<<script>>`. (It doesn't reproduce parseBody's rejection of a closing tag with\n * arguments, nor its resuming inside the arguments of a tag whose name starts with `/` or\n * `end`.)\n *\n * The tags found from the start of the text are those parseBody finds from any opener among\n * them, so for such an opener the answer takes constant time. An opener the walk reached after\n * a comment may not be among them, when a tag that starts in the comment runs over it; then the\n * scan starts at the body and goes on until it finds the closer or reaches a tag of that list,\n * whose answers it then uses. All such scans in one reading of a passage, strings included, stop\n * once they have read four times as many characters as the passage has, plus a fixed allowance\n * (`budget`, see `readContext`); on input built to make them read more, the openers after that\n * are taken as unclosed. That keeps the time linear. (Exported for tests; the module is not part\n * of the package's API.)\n */\nexport function scriptBodyCloser(text: string, budget: { left: number }): (opener: MacroTag) => MacroTag | undefined {\n const tags = findMacroTags(text);\n const indexByStart = new Map(tags.map((tag, index) => [tag.start, index]));\n const lastClose = text.lastIndexOf('>>');\n const spend = (characters: number): void => {\n budget.left -= characters;\n };\n const step = (tag: MacroTag): number =>\n tag.name === 'script' ? 1 : tag.name === '/script' || tag.name === 'endscript' ? -1 : 0;\n // balance[k]: openers minus closers among the first k tags.\n const balance: number[] = [0];\n tags.forEach((tag, k) => balance.push((balance[k] ?? 0) + step(tag)));\n // firstBelow[k]: the first j > k with balance[j] < balance[k], if any.\n const firstBelow: (number | undefined)[] = [];\n const candidates: number[] = [];\n for (let k = balance.length - 1; k >= 0; k--) {\n const here = balance[k] ?? 0;\n let top = candidates[candidates.length - 1];\n while (top !== undefined && (balance[top] ?? 0) >= here) {\n candidates.pop();\n top = candidates[candidates.length - 1];\n }\n firstBelow[k] = top;\n candidates.push(k);\n }\n /**\n * The closer when `open` bodies are open just before `tags[index]`: each hop to\n * `firstBelow` closes one. `open` is at most one more than the openers scanned to get here.\n */\n const closeFrom = (index: number, open: number): MacroTag | undefined => {\n let k: number | undefined = index;\n for (let left = open; left > 0 && k !== undefined; left--) {\n k = firstBelow[k];\n }\n return k === undefined ? undefined : tags[k - 1];\n };\n return (opener) => {\n const index = indexByStart.get(opener.start);\n if (index !== undefined) {\n return closeFrom(index + 1, 1);\n }\n const matchTagAt = tagMatcher(text, lastClose, spend);\n let open = 1;\n let from = opener.end;\n while (budget.left >= 0) {\n const start = text.indexOf('<<', from);\n spend((start === -1 ? text.length : start) - from);\n if (start === -1) {\n return undefined;\n }\n const known = indexByStart.get(start);\n if (known !== undefined) {\n return closeFrom(known, open);\n }\n const tag = matchTagAt(start)?.tag;\n if (tag === undefined) {\n from = start + 2;\n continue;\n }\n open += step(tag);\n if (open === 0) {\n return tag;\n }\n from = tag.end;\n }\n return undefined;\n };\n}\n\n/** Adds `more` to the end of `links`, without spreading, which fails for very long lists. */\nfunction append(links: MacroPassageLink[], more: readonly MacroPassageLink[]): void {\n for (const link of more) {\n links.push(link);\n }\n}\n\n/**\n * The passages that `<<link>>` and `<<goto>>` calls in passage markup name. Calls whose passage\n * is known only in play (a variable or an expression) are left out. A tag's own passage comes\n * before those of the calls inside its arguments' strings.\n *\n * The markup is walked in order, as SugarCube's wikifier walks it, with a tag tried at each\n * `<<` the walk reaches. Of the wikifier's other parsers, only those whose text holds no call\n * are told apart: comments (`/* … *` + `/`, `/% … %/`, `<!-- … -->`), whose calls never run,\n * and `<script>` elements and `<<script>>` bodies, which are JavaScript: only the calls in their\n * strings are read (see `findJavaScriptPassageLinks`). Everything else, verbatim text included,\n * is read as markup.\n *\n * Where this differs from SugarCube:\n * - a comment or a `<<script>>` body is skipped whole, even where `parseBody` ends a container\n * such as `<<if>>` at a closing tag inside it and the rest then runs;\n * - a `/*`, `<!--` or `<script` inside other markup that holds no call, such as link markup or a\n * `<style>` element, still starts a comment or an element;\n * - a `<<` in such other markup still starts a tag. When that tag runs over a `<<link` or\n * `<<goto` outside the parts of its arguments that the tag pattern reads as units, that call\n * is still read (see `innerPassageLink`), even where the tag's arguments would be JavaScript,\n * as the check always read it. One that such a part covers is lost: a quoted string, or a `//`\n * part up to a line feed (italics, a URL) when a `>>` follows later; and a `<<script>>` body\n * the tag runs over is read as markup. The same recovery also reads a call inside a stray tag\n * that SugarCube does see, and rejects as an unknown macro (`<<Back <<goto R>>`);\n * - a `<<script>>` body's end is found as `parseBody` finds it, except that parseBody rejects a\n * closing tag with arguments, and resumes inside the arguments of a tag whose name starts with\n * `/` or `end`;\n * - the lines of a `<<nobr>>` body, and of every passage when a story sets\n * `Config.passages.nobr`, are not joined before they are read (see `storyInspect` for passages\n * tagged `nobr`).\n */\nexport function findMacroPassageLinks(text: string): MacroPassageLink[] {\n return markupPassageLinks(text, readContext(text));\n}\n\nfunction markupPassageLinks(text: string, context: ReadContext): MacroPassageLink[] {\n if (context.depth > MAX_STRING_DEPTH || (!text.includes('<<') && !HAS_SCRIPT_OPEN_RE.test(text))) {\n return [];\n }\n const matchTagAt = tagMatcher(text);\n // For the calls inside tags' arguments, which also come in increasing order.\n const matchInnerTagAt = tagMatcher(text);\n const readComment = commentReader(text);\n const readScriptElement = scriptElementReader(text);\n let findScriptCloser: ((opener: MacroTag) => MacroTag | undefined) | undefined;\n const links: MacroPassageLink[] = [];\n\n /** Reads the region `opener` opens, adding the calls in a `<script>` element; returns where the walk goes on. */\n const regionEnd = (opener: RegExpExecArray): number => {\n const start = opener.index;\n const kind = opener[0];\n switch (kind) {\n case '//':\n // Italics, whose text is read on; `//*` is not a comment.\n return start + 2;\n case '/*':\n case '/%':\n case '<!--':\n return readComment(kind, start) ?? start + kind.length;\n default: {\n const element = readScriptElement(start);\n if (element.openerEnd === undefined) {\n // Not an opener SugarCube reads.\n return start + 1;\n }\n if (element.close === undefined) {\n // SugarCube reads the opener and nothing more; the content is markup.\n return element.openerEnd;\n }\n append(links, javaScriptPassageLinks(text.slice(element.openerEnd, element.close), context));\n return element.close + 9;\n }\n }\n };\n\n // The next `<<` and region opener at or after `pos`, searched again only once `pos` passes them.\n let macro = -2;\n let region: RegExpExecArray | null | undefined;\n let pos = 0;\n for (;;) {\n if (macro !== -1 && macro < pos) {\n macro = text.indexOf('<<', pos);\n }\n if (region !== null && (region === undefined || region.index < pos)) {\n REGION_OPEN_RE.lastIndex = pos;\n region = REGION_OPEN_RE.exec(text);\n }\n if (region !== null && (macro === -1 || region.index < macro)) {\n pos = regionEnd(region);\n continue;\n }\n if (macro === -1) {\n return links;\n }\n const scanned = matchTagAt(macro);\n if (scanned === undefined) {\n pos = macro + 2;\n continue;\n }\n const { tag, innerCall } = scanned;\n append(links, tagPassageLinks(tag, context));\n if (innerCall !== undefined) {\n const inner = innerPassageLink(matchInnerTagAt, innerCall);\n if (inner !== undefined) {\n links.push(inner);\n }\n }\n pos = tag.end;\n if (tag.name === 'script') {\n findScriptCloser ??= scriptBodyCloser(text, context.budget);\n const closer = findScriptCloser(tag);\n if (closer !== undefined) {\n append(links, javaScriptPassageLinks(text.slice(tag.end, closer.start), context));\n pos = closer.end;\n }\n }\n }\n}\n\n/**\n * The passages that `<<link>>` and `<<goto>>` calls in the strings of JavaScript source name,\n * such as a script passage or a `<<script>>` body: `$.wiki('<<goto \"Room\">>')`. Code outside\n * the strings isn't markup, so a call put together while the story plays, such as\n * `'<<goto \"' + target + '\">>'`, names no passage here.\n */\nexport function findJavaScriptPassageLinks(source: string): MacroPassageLink[] {\n return javaScriptPassageLinks(source, readContext(source));\n}\n\n/**\n * What JavaScript source must contain for one of its string or template literals to hold a call\n * that is read. A value holding `<<`: each `<` in it is written as `<`, `\\<`, `\\x3c`, `\\u003c` or\n * `\\u{…}`, two can be next to each other with only line continuations between, and the first\n * is `<` or `\\<` (then the source holds `<<` or `<\\`) or one of the others. Or a value holding a\n * `<script>` element, whose own strings can make `<<` from escapes the outer string encodes.\n */\nconst MAY_HOLD_MACRO_RE = /<<|<\\\\|\\\\x3c|\\\\u003c|\\\\u\\{|<script/i;\n\nfunction javaScriptPassageLinks(source: string, context: ReadContext): MacroPassageLink[] {\n if (context.depth >= MAX_STRING_DEPTH || !MAY_HOLD_MACRO_RE.test(source)) {\n // No string in it can hold a macro call.\n return [];\n }\n const inner = deeper(context);\n const links: MacroPassageLink[] = [];\n for (const value of javaScriptStrings(source)) {\n append(links, markupPassageLinks(value, inner));\n }\n return links;\n}\n","/**\n * Story inspection utilities for unit testing.\n *\n * Extracts structural information from a compiled story:\n * passage names, tags, link graph, broken links, dead ends, orphans.\n *\n * Usage:\n * const result = await compile({ sources: ['./story'] });\n * const map = storyInspect(result.story);\n * expect(map.passages).toContain('Start');\n * expect(map.brokenLinks).toHaveLength(0);\n */\nimport type { ReadonlyPassage, ReadonlyStory } from './types.js';\nimport { hasTag, isInfoPassage, isStoryPassage } from './passage.js';\nimport { findJavaScriptPassageLinks, findMacroPassageLinks } from './sugarcube-macros.js';\n\nexport interface StoryMap {\n /** All passage names, in source order. */\n passages: string[];\n /** Only story passages (excludes StoryData, StoryTitle, scripts, stylesheets, etc.). */\n storyPassages: string[];\n /** Only info/special passages. */\n infoPassages: string[];\n /** All unique tags used across the story, sorted alphabetically. */\n tags: string[];\n /** Map of tag → passage names that carry that tag. */\n passagesByTag: Map<string, string[]>;\n /** Map of passage name → tags on that passage. */\n tagsByPassage: Map<string, string[]>;\n /**\n * Map of passage name → passage names it links to.\n * Parses `[[target]]`, `[[display->target]]`, `[[display|target]]`,\n * and SugarCube's `<<goto \"target\">>` / `<<link \"display\" \"target\">>`,\n * whose arguments are read as SugarCube 2 reads them (see `sugarcube-macros.ts`).\n */\n links: Map<string, string[]>;\n /** Broken links: `{ from, to }` pairs where `to` doesn't exist as a passage. */\n brokenLinks: BrokenLink[];\n /** Story passages with no outgoing links (potential dead ends). */\n deadEnds: string[];\n /** Story passages that no other passage links to (excluding the start passage). */\n orphans: string[];\n /** The configured start passage name, if any. */\n start: string;\n}\n\nexport interface BrokenLink {\n from: string;\n to: string;\n}\n\n/**\n * Extract all [[wiki-style links]] from passage text.\n *\n * Supported syntaxes:\n * - `[[PassageName]]`\n * - `[[Display Text->PassageName]]` (Twine 2 / SugarCube arrow)\n * - `[[Display Text|PassageName]]` (Twine 1 / Harlowe pipe)\n * - `<<goto \"PassageName\">>` (SugarCube macro)\n * - `<<link \"Display\" \"PassageName\">>` (SugarCube macro)\n *\n * SugarCube macro arguments may be double- or single-quoted, with backslash escapes, or bare\n * words; a passage named by a variable or an expression is known only in play and is skipped.\n * Macro calls are also read inside the quoted strings of other macros' arguments, and inside the\n * strings of `<<script>>` bodies and `<script>` elements; calls in comments are not read. A\n * script passage (`isScript`) is JavaScript, so its macro calls are read only inside its strings.\n * See `sugarcube-macros.ts` for the details and the known differences from SugarCube.\n */\nfunction extractLinksFromText(text: string, isScript: boolean): string[] {\n const targets = new Set<string>();\n\n // [[...]] links\n const wikiLinkRe = /\\[\\[([^\\]]+)\\]\\]/g;\n let m;\n while ((m = wikiLinkRe.exec(text)) !== null) {\n const content = m[1]!;\n\n // [[display->target]]\n const arrowIdx = content.indexOf('->');\n if (arrowIdx !== -1) {\n targets.add(content.slice(arrowIdx + 2).trim());\n continue;\n }\n\n // [[display|target]]\n const pipeIdx = content.indexOf('|');\n if (pipeIdx !== -1) {\n targets.add(content.slice(pipeIdx + 1).trim());\n continue;\n }\n\n // [[target]]\n targets.add(content.trim());\n }\n\n // <<goto \"target\">> and <<link \"display\" \"target\">>. Gotos come before links, the order\n // this list has always had.\n const macroLinks = isScript ? findJavaScriptPassageLinks(text) : findMacroPassageLinks(text);\n for (const macro of ['goto', 'link'] as const) {\n for (const link of macroLinks) {\n if (link.macro === macro) {\n targets.add(link.passage);\n }\n }\n }\n\n return [...targets];\n}\n\n/** Passages SugarCube runs from their raw text, never joining their lines. */\nconst RAW_TEXT_PASSAGES: ReadonlySet<string> = new Set(['StoryInit', 'PassageReady', 'PassageDone']);\n\n/**\n * A passage's text as SugarCube reads it for its links. A passage tagged `nobr` has its line\n * breaks joined (`Passage.processText`): leading and trailing ones removed, each run inside made\n * one space. Script passages, `init`-tagged passages, StoryInit, PassageReady and PassageDone are\n * run from their raw text, so they keep theirs.\n */\nfunction textAsRead(p: ReadonlyPassage): string {\n const joined = hasTag(p, 'nobr') && !hasTag(p, 'script') && !hasTag(p, 'init') && !RAW_TEXT_PASSAGES.has(p.name);\n return joined ? joinLines(p.text) : p.text;\n}\n\n/**\n * What SugarCube's `text.replace(/^\\n+|\\n+$/g, '').replace(/\\n+/g, ' ')` gives, without that\n * pattern's backtracking, which takes quadratic time on a long run of line feeds.\n */\nfunction joinLines(text: string): string {\n let start = 0;\n while (text[start] === '\\n') {\n start += 1;\n }\n let end = text.length;\n while (end > start && text[end - 1] === '\\n') {\n end -= 1;\n }\n return text.slice(start, end).replace(/\\n+/g, ' ');\n}\n\n/**\n * Inspect a story and return its full structural map.\n *\n * Designed for story authors to use in unit tests:\n * ```ts\n * const result = await compile({ sources: ['./story'] });\n * const map = storyInspect(result.story);\n *\n * // Assert structure\n * expect(map.passages).toContain('Start');\n * expect(map.tags).toContain('location');\n * expect(map.passagesByTag.get('location')).toContain('Kitchen');\n * expect(map.brokenLinks).toEqual([]);\n * expect(map.deadEnds).not.toContain('Start');\n * ```\n */\nexport function storyInspect(story: ReadonlyStory): StoryMap {\n const allNames = new Set(story.passages.map((p) => p.name));\n\n const passages: string[] = [];\n const storyPassages: string[] = [];\n const infoPassages: string[] = [];\n const tagSet = new Set<string>();\n const passagesByTag = new Map<string, string[]>();\n const tagsByPassage = new Map<string, string[]>();\n const links = new Map<string, string[]>();\n\n for (const p of story.passages) {\n passages.push(p.name);\n\n if (isStoryPassage(p)) {\n storyPassages.push(p.name);\n }\n if (isInfoPassage(p)) {\n infoPassages.push(p.name);\n }\n\n // Tags\n tagsByPassage.set(p.name, [...p.tags]);\n for (const tag of p.tags) {\n tagSet.add(tag);\n let list = passagesByTag.get(tag);\n if (!list) {\n list = [];\n passagesByTag.set(tag, list);\n }\n list.push(p.name);\n }\n\n // Links\n const targets = extractLinksFromText(textAsRead(p), hasTag(p, 'script'));\n links.set(p.name, targets);\n }\n\n // Broken links: link targets that don't exist as passages\n const brokenLinks: BrokenLink[] = [];\n for (const [from, targets] of links) {\n for (const to of targets) {\n if (!allNames.has(to)) {\n brokenLinks.push({ from, to });\n }\n }\n }\n\n // Dead ends: story passages with no outgoing links\n const deadEnds: string[] = [];\n for (const name of storyPassages) {\n const targets = links.get(name);\n if (!targets || targets.length === 0) {\n deadEnds.push(name);\n }\n }\n\n // Orphans: story passages nobody links to (excluding start)\n const start = story.twine2.start || 'Start';\n const linkedTo = new Set<string>();\n for (const targets of links.values()) {\n for (const t of targets) {\n linkedTo.add(t);\n }\n }\n const orphans: string[] = [];\n for (const name of storyPassages) {\n if (name !== start && !linkedTo.has(name)) {\n orphans.push(name);\n }\n }\n\n return {\n passages,\n storyPassages,\n infoPassages,\n tags: [...tagSet].sort(),\n passagesByTag,\n tagsByPassage,\n links,\n brokenLinks,\n deadEnds,\n orphans,\n start,\n };\n}\n","/**\n * Lint mode: compile + inspect story structure without producing output.\n * Surfaces broken links, dead ends, orphans, and compilation diagnostics.\n */\nimport type { CompileOptions, CompileStats, Diagnostic } from './types.js';\nimport type { BrokenLink } from './inspect.js';\nimport { compile } from './compiler.js';\nimport { storyInspect } from './inspect.js';\n\nexport interface LintResult {\n /** Compilation diagnostics (errors and warnings). */\n diagnostics: Diagnostic[];\n /** Compilation statistics. */\n stats: CompileStats;\n /** Story format name from StoryData (e.g. \"SugarCube\"). */\n formatName: string;\n /** Story format version from StoryData (e.g. \"2.37.3\"). */\n formatVersion: string;\n /** The configured start passage name. */\n start: string;\n /** Total passage count. */\n passages: number;\n /** Story passage count (excludes StoryData, StoryTitle, scripts, etc.). */\n storyPassages: number;\n /** Info/special passage count. */\n infoPassages: number;\n /** Broken links: link targets that don't exist as passages. */\n brokenLinks: BrokenLink[];\n /** Story passages with no outgoing links. */\n deadEnds: string[];\n /** Story passages that no other passage links to. */\n orphans: string[];\n}\n\n/**\n * Lint a story: compile without output rendering, then inspect structure.\n * Uses JSON output mode internally to avoid format resolution.\n */\nexport async function lint(options: Omit<CompileOptions, 'outputMode'>): Promise<LintResult> {\n const result = await compile({ ...options, outputMode: 'json' });\n const map = storyInspect(result.story);\n\n return {\n diagnostics: result.diagnostics,\n stats: result.stats,\n formatName: result.story.twine2.format,\n formatVersion: result.story.twine2.formatVersion,\n start: map.start,\n passages: map.passages.length,\n storyPassages: map.storyPassages.length,\n infoPassages: map.infoPassages.length,\n brokenLinks: map.brokenLinks,\n deadEnds: map.deadEnds,\n orphans: map.orphans,\n };\n}\n\n/**\n * Format a lint result as a human-readable report string.\n */\nexport function formatLintReport(result: LintResult): string {\n const lines: string[] = [];\n\n // Header: format and stats\n const formatStr = result.formatName\n ? `${result.formatName}${result.formatVersion ? ' ' + result.formatVersion : ''}`\n : 'unknown';\n lines.push(`Format: ${formatStr}`);\n lines.push(\n `Passages: ${result.passages} total (${result.storyPassages} story, ${result.infoPassages} info), ${result.stats.words.toLocaleString()} words, ${result.stats.files.length} files`,\n );\n lines.push(`Start: ${result.start}`);\n\n // Broken links (errors)\n if (result.brokenLinks.length > 0) {\n lines.push('');\n lines.push(`Broken links (${result.brokenLinks.length}):`);\n for (const link of result.brokenLinks) {\n lines.push(` ${link.from} -> ${link.to} (passage \"${link.to}\" does not exist)`);\n }\n }\n\n // Dead ends (warnings)\n if (result.deadEnds.length > 0) {\n lines.push('');\n lines.push(`Dead ends (${result.deadEnds.length}): ${result.deadEnds.join(', ')}`);\n }\n\n // Orphans (warnings)\n if (result.orphans.length > 0) {\n lines.push('');\n lines.push(`Orphans (${result.orphans.length}): ${result.orphans.join(', ')}`);\n }\n\n // Compilation diagnostics\n const errors = result.diagnostics.filter((d) => d.level === 'error');\n const warnings = result.diagnostics.filter((d) => d.level === 'warning');\n\n if (errors.length > 0 || warnings.length > 0) {\n lines.push('');\n lines.push(`Diagnostics: ${errors.length} error(s), ${warnings.length} warning(s)`);\n for (const d of errors) {\n lines.push(` error: ${d.message}`);\n }\n for (const d of warnings) {\n lines.push(` warning: ${d.message}`);\n }\n }\n\n // Summary line\n lines.push('');\n const hasErrors = errors.length > 0 || result.brokenLinks.length > 0;\n if (hasErrors) {\n lines.push('Lint failed.');\n } else {\n lines.push('Lint passed.');\n }\n\n return lines.join('\\n');\n}\n","/**\n * Config file loading and validation for twee-ts.\n */\nimport { readFileSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { TweeTsConfig, OutputMode, WordCountMethod } from './types.js';\n\nexport const CONFIG_FILENAME = 'twee-ts.config.json';\n\nconst VALID_OUTPUT_MODES: OutputMode[] = ['html', 'twee3', 'twee1', 'twine2-archive', 'twine1-archive', 'json'];\nconst VALID_WORD_COUNT_METHODS: WordCountMethod[] = ['tweego', 'whitespace'];\n\n/** Load a config file from the given directory (default: cwd). Returns null if not found. */\nexport function loadConfig(dir?: string): TweeTsConfig | null {\n const base = dir ?? process.cwd();\n const configPath = join(base, CONFIG_FILENAME);\n\n if (!existsSync(configPath)) return null;\n\n let raw: string;\n try {\n raw = readFileSync(configPath, 'utf-8');\n } catch {\n return null;\n }\n\n let data: unknown;\n try {\n data = JSON.parse(raw);\n } catch (e) {\n throw new Error(`Invalid JSON in ${configPath}: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n const errors = validateConfig(data);\n if (errors.length > 0) {\n throw new Error(`Invalid config in ${configPath}:\\n ${errors.join('\\n ')}`);\n }\n\n return data as TweeTsConfig;\n}\n\n/** Load a config from a specific file path. */\nexport function loadConfigFile(filePath: string): TweeTsConfig {\n let raw: string;\n try {\n raw = readFileSync(filePath, 'utf-8');\n } catch (e) {\n throw new Error(`Cannot read config file ${filePath}: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n let data: unknown;\n try {\n data = JSON.parse(raw);\n } catch (e) {\n throw new Error(`Invalid JSON in ${filePath}: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n const errors = validateConfig(data);\n if (errors.length > 0) {\n throw new Error(`Invalid config in ${filePath}:\\n ${errors.join('\\n ')}`);\n }\n\n return data as TweeTsConfig;\n}\n\n/** Validate a config object. Returns an array of error strings (empty = valid). */\nexport function validateConfig(data: unknown): string[] {\n const errors: string[] = [];\n\n if (typeof data !== 'object' || data === null || Array.isArray(data)) {\n errors.push('Config must be a JSON object.');\n return errors;\n }\n\n const obj = data as Record<string, unknown>;\n\n // String fields\n for (const key of ['output', 'formatId', 'startPassage', 'headFile'] as const) {\n if (key in obj && typeof obj[key] !== 'string') {\n errors.push(`\"${key}\" must be a string.`);\n }\n }\n\n // Boolean fields\n for (const key of ['useTweegoPath', 'trim', 'twee2Compat', 'testMode', 'noRemote', 'sourceInfo'] as const) {\n if (key in obj && typeof obj[key] !== 'boolean') {\n errors.push(`\"${key}\" must be a boolean.`);\n }\n }\n\n // String array fields\n for (const key of ['sources', 'exclude', 'formatPaths', 'formatIndices', 'formatUrls', 'modules'] as const) {\n if (key in obj) {\n if (!Array.isArray(obj[key])) {\n errors.push(`\"${key}\" must be an array.`);\n } else if (!(obj[key] as unknown[]).every((v) => typeof v === 'string')) {\n errors.push(`\"${key}\" must be an array of strings.`);\n }\n }\n }\n\n // tagAliases validation\n if ('tagAliases' in obj) {\n if (typeof obj['tagAliases'] !== 'object' || obj['tagAliases'] === null || Array.isArray(obj['tagAliases'])) {\n errors.push('\"tagAliases\" must be an object.');\n } else {\n const aliases = obj['tagAliases'] as Record<string, unknown>;\n for (const [key, val] of Object.entries(aliases)) {\n if (typeof val !== 'string') {\n errors.push(`\"tagAliases.${key}\" must be a string.`);\n }\n }\n }\n }\n\n // OutputMode validation\n if ('outputMode' in obj) {\n if (typeof obj['outputMode'] !== 'string' || !VALID_OUTPUT_MODES.includes(obj['outputMode'] as OutputMode)) {\n errors.push(`\"outputMode\" must be one of: ${VALID_OUTPUT_MODES.join(', ')}.`);\n }\n }\n\n // WordCountMethod validation\n if ('wordCountMethod' in obj) {\n if (\n typeof obj['wordCountMethod'] !== 'string' ||\n !VALID_WORD_COUNT_METHODS.includes(obj['wordCountMethod'] as WordCountMethod)\n ) {\n errors.push(`\"wordCountMethod\" must be one of: ${VALID_WORD_COUNT_METHODS.join(', ')}.`);\n }\n }\n\n return errors;\n}\n\n/** Return a default config JSON string for --init scaffolding. */\nexport function scaffoldConfig(): string {\n const config = {\n $schema: 'https://unpkg.com/@rohal12/twee-ts/schemas/twee-ts.config.schema.json',\n sources: ['src/'],\n output: 'story.html',\n };\n return JSON.stringify(config, null, 2) + '\\n';\n}\n","/**\n * twee-ts CLI entry point.\n * Uses node:util.parseArgs() for argument parsing.\n */\nimport { parseArgs } from 'node:util';\nimport { writeFileSync, mkdirSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { compile, compileToFile, watch } from '../src/compiler.js';\nimport { lint, formatLintReport } from '../src/lint.js';\nimport { discoverFormats, getFormatSearchDirs } from '../src/formats.js';\nimport { loadConfig, loadConfigFile, scaffoldConfig, CONFIG_FILENAME } from '../src/config.js';\nimport {\n discoverCachedFormats,\n getCacheDir,\n listCachedFormats,\n clearCachedFormats,\n getCacheSize,\n} from '../src/remote-formats.js';\nimport type { TweeTsConfig, OutputMode, WordCountMethod } from '../src/types.js';\n\nimport { VERSION } from '../src/version.js';\n\nconst { values, positionals } = parseArgs({\n allowPositionals: true,\n options: {\n output: { type: 'string', short: 'o' },\n format: { type: 'string', short: 'f' },\n start: { type: 'string', short: 's' },\n module: { type: 'string', short: 'm', multiple: true },\n head: { type: 'string' },\n 'decompile-twee3': { type: 'boolean', short: 'd' },\n 'decompile-twee1': { type: 'boolean' },\n 'archive-twine2': { type: 'boolean', short: 'a' },\n 'archive-twine1': { type: 'boolean' },\n 'twee2-compat': { type: 'boolean' },\n 'no-trim': { type: 'boolean' },\n lint: { type: 'boolean' },\n test: { type: 'boolean', short: 't' },\n watch: { type: 'boolean', short: 'w' },\n 'log-stats': { type: 'boolean', short: 'l' },\n 'log-files': { type: 'boolean' },\n 'list-formats': { type: 'boolean' },\n json: { type: 'boolean' },\n init: { type: 'boolean' },\n help: { type: 'boolean', short: 'h' },\n version: { type: 'boolean', short: 'v' },\n // New flags\n 'format-index': { type: 'string', multiple: true },\n 'format-url': { type: 'string', multiple: true },\n 'no-remote': { type: 'boolean' },\n 'tag-alias': { type: 'string', multiple: true },\n exclude: { type: 'string', multiple: true },\n 'source-info': { type: 'boolean' },\n 'word-count-method': { type: 'string' },\n config: { type: 'string', short: 'c' },\n 'no-config': { type: 'boolean' },\n },\n});\n\nasync function main(): Promise<void> {\n if (values.version) {\n console.log(`twee-ts v${VERSION}`);\n return;\n }\n\n if (values.help) {\n printUsage();\n return;\n }\n\n if (values['list-formats']) {\n listFormats();\n return;\n }\n\n if (values.init) {\n runInit();\n return;\n }\n\n if (positionals[0] === 'cache') {\n runCache(positionals.slice(1));\n return;\n }\n\n // Load config file (unless --no-config)\n let config: TweeTsConfig | null = null;\n if (!values['no-config']) {\n if (values.config) {\n config = loadConfigFile(values.config);\n } else {\n config = loadConfig();\n }\n }\n\n // Merge sources: positionals > config.sources\n const sources = positionals.length > 0 ? positionals : config?.sources;\n if (!sources || sources.length === 0) {\n console.error('Error: No input sources specified.');\n printUsage();\n process.exit(1);\n }\n\n // Determine output mode: CLI flag > config > default\n let outputMode: OutputMode = config?.outputMode ?? 'html';\n if (values['decompile-twee3']) outputMode = 'twee3';\n else if (values['decompile-twee1']) outputMode = 'twee1';\n else if (values['archive-twine2']) outputMode = 'twine2-archive';\n else if (values['archive-twine1']) outputMode = 'twine1-archive';\n else if (values.json) outputMode = 'json';\n\n // Parse --tag-alias flags (format: alias=target)\n let tagAliases: Record<string, string> | undefined;\n if (values['tag-alias'] || config?.tagAliases) {\n tagAliases = { ...config?.tagAliases };\n for (const pair of values['tag-alias'] ?? []) {\n const eq = pair.indexOf('=');\n if (eq < 1) {\n console.error(`Error: Invalid --tag-alias \"${pair}\". Expected format: alias=target`);\n process.exit(1);\n }\n tagAliases[pair.slice(0, eq)] = pair.slice(eq + 1);\n }\n }\n\n // Word count method: CLI flag > config > default\n const VALID_WORD_COUNT_METHODS: WordCountMethod[] = ['tweego', 'whitespace'];\n const wordCountMethod: WordCountMethod | undefined = (() => {\n const raw = values['word-count-method'] ?? config?.wordCountMethod;\n if (raw === undefined) return undefined;\n if (!VALID_WORD_COUNT_METHODS.includes(raw as WordCountMethod)) {\n console.error(`Error: Invalid --word-count-method \"${raw}\". Expected: ${VALID_WORD_COUNT_METHODS.join(', ')}`);\n process.exit(1);\n }\n return raw as WordCountMethod;\n })();\n\n // Lint mode: compile + inspect, no output\n if (values.lint) {\n const lintResult = await lint({\n sources,\n exclude: values.exclude ?? config?.exclude,\n formatId: values.format ?? config?.formatId,\n startPassage: values.start ?? config?.startPassage,\n formatPaths: config?.formatPaths,\n modules: values.module ?? config?.modules,\n headFile: values.head ?? config?.headFile,\n trim: values['no-trim'] ? false : (config?.trim ?? true),\n twee2Compat: values['twee2-compat'] ?? config?.twee2Compat ?? false,\n testMode: values.test ?? config?.testMode ?? false,\n formatIndices: values['format-index'] ?? config?.formatIndices,\n formatUrls: values['format-url'] ?? config?.formatUrls,\n noRemote: values['no-remote'] ?? config?.noRemote ?? false,\n tagAliases,\n sourceInfo: values['source-info'] ?? config?.sourceInfo ?? false,\n wordCountMethod,\n });\n console.log(formatLintReport(lintResult));\n const hasErrors = lintResult.brokenLinks.length > 0 || lintResult.diagnostics.some((d) => d.level === 'error');\n process.exit(hasErrors ? 1 : 0);\n }\n\n const compileOptions = {\n sources,\n exclude: values.exclude ?? config?.exclude,\n outputMode,\n formatId: values.format ?? config?.formatId,\n startPassage: values.start ?? config?.startPassage,\n formatPaths: config?.formatPaths,\n modules: values.module ?? config?.modules,\n headFile: values.head ?? config?.headFile,\n trim: values['no-trim'] ? false : (config?.trim ?? true),\n twee2Compat: values['twee2-compat'] ?? config?.twee2Compat ?? false,\n testMode: values.test ?? config?.testMode ?? false,\n useTweegoPath: config?.useTweegoPath,\n formatIndices: values['format-index'] ?? config?.formatIndices,\n formatUrls: values['format-url'] ?? config?.formatUrls,\n noRemote: values['no-remote'] ?? config?.noRemote ?? false,\n tagAliases,\n sourceInfo: values['source-info'] ?? config?.sourceInfo ?? false,\n wordCountMethod,\n };\n\n const outFile = values.output ?? config?.output ?? '-';\n\n if (values.watch) {\n if (outFile === '-') {\n console.error('Error: Watch mode requires an output file (-o).');\n process.exit(1);\n }\n console.log('Watch mode started. Press CTRL+C to stop.');\n await watch({\n ...compileOptions,\n outFile,\n onBuild(result) {\n console.log(`Built: ${result.stats.passages} passages, ${result.stats.words} words`);\n logDiagnostics(result.diagnostics);\n },\n onError(error) {\n console.error(`Build error: ${error.message}`);\n },\n });\n } else {\n if (outFile === '-') {\n const result = await compile(compileOptions);\n process.stdout.write(result.output);\n logDiagnostics(result.diagnostics);\n if (values['log-stats']) logStats(result);\n } else {\n const result = await compileToFile({ ...compileOptions, outFile });\n logDiagnostics(result.diagnostics);\n if (values['log-files']) {\n console.log(`\\nFiles: ${result.stats.files.join(', ')}`);\n }\n if (values['log-stats']) logStats(result);\n }\n }\n}\n\nfunction listFormats(): void {\n const dirs = getFormatSearchDirs();\n const formats = discoverFormats(dirs);\n\n console.log('Local story formats:');\n if (formats.size === 0) {\n console.log(' (none)');\n } else {\n for (const [id, f] of formats) {\n const type = f.isTwine2 ? 'Twine 2' : 'Twine 1';\n console.log(` ${id}: ${f.name || id} ${f.version} (${type})`);\n }\n }\n\n const cached = discoverCachedFormats();\n if (cached.size > 0) {\n console.log('\\nCached remote formats:');\n for (const [id, f] of cached) {\n console.log(` ${id}: ${f.name} ${f.version}`);\n }\n }\n}\n\nfunction logDiagnostics(diagnostics: Array<{ level: string; message: string }>): void {\n for (const d of diagnostics) {\n if (d.level === 'error') console.error(`error: ${d.message}`);\n else console.warn(`warning: ${d.message}`);\n }\n}\n\nfunction logStats(result: {\n stats: { passages: number; storyPassages?: number; words: number; files: string[] };\n}): void {\n const s = result.stats;\n console.log(`\\nStatistics:`);\n console.log(` Passages: ${s.passages}`);\n console.log(` Words: ${s.words}`);\n console.log(` Files: ${s.files.length}`);\n}\n\nfunction runInit(): void {\n console.log('Initializing new twee-ts project...');\n mkdirSync('src', { recursive: true });\n\n writeFileSync(\n join('src', 'StoryData.tw'),\n `:: StoryData\n{\n\\t\"ifid\": \"${crypto.randomUUID().toUpperCase()}\"\n}\n`,\n );\n\n writeFileSync(\n join('src', 'Start.tw'),\n `:: Start\nWelcome to your new Twine story!\n\nThis is the starting passage. Edit this file to begin writing your story.\n`,\n );\n\n // Scaffold config file if it doesn't exist\n if (!existsSync(CONFIG_FILENAME)) {\n writeFileSync(CONFIG_FILENAME, scaffoldConfig());\n console.log(`Created: ${CONFIG_FILENAME}`);\n }\n\n console.log('Created:');\n console.log(' src/StoryData.tw');\n console.log(' src/Start.tw');\n console.log('\\nRun: npx @rohal12/twee-ts');\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes}B`;\n const kb = bytes / 1024;\n if (kb < 1024) return `${Math.round(kb)}K`;\n const mb = kb / 1024;\n return `${mb.toFixed(1)}M`;\n}\n\nfunction runCache(args: string[]): void {\n const subcommand = args[0];\n\n switch (subcommand) {\n case 'list': {\n const entries = listCachedFormats();\n if (entries.length === 0) {\n console.log('No cached formats.');\n return;\n }\n for (const e of entries) {\n const date = e.modifiedAt.toISOString().slice(0, 10);\n console.log(`${e.name.padEnd(16)} ${e.version.padEnd(10)} ${formatBytes(e.sizeBytes).padStart(6)} ${date}`);\n }\n return;\n }\n case 'clear': {\n const name = args[1];\n const count = clearCachedFormats(name);\n if (count === 0) {\n console.log(name ? `No cached formats matching \"${name}\".` : 'Cache is already empty.');\n } else {\n console.log(`Cleared ${count} cached format${count === 1 ? '' : 's'}.`);\n }\n return;\n }\n case 'size': {\n const { totalBytes, count } = getCacheSize();\n if (count === 0) {\n console.log('Cache is empty.');\n } else {\n console.log(`Total: ${formatBytes(totalBytes)} (${count} format${count === 1 ? '' : 's'})`);\n }\n return;\n }\n case 'path': {\n console.log(getCacheDir());\n return;\n }\n default: {\n console.error(`Usage: twee-ts cache <list|clear|size|path>\n\n list List cached formats with name, version, size\n clear Delete all cached formats\n clear <name> Delete cached formats matching name\n size Show total cache size\n path Print cache directory path`);\n process.exit(subcommand ? 1 : 0);\n }\n }\n}\n\nfunction printUsage(): void {\n console.log(`twee-ts v${VERSION} — TypeScript Twee-to-HTML compiler\n\nUsage: twee-ts [options] <sources...>\n\nOptions:\n -o, --output <file> Output file (default: stdout)\n -f, --format <id> Story format ID (default: sugarcube-2)\n -s, --start <name> Starting passage (default: Start)\n -m, --module <file> Module file to inject into <head> (repeatable)\n --head <file> Raw HTML file to append to <head>\n -d, --decompile-twee3 Output as Twee 3 source\n --decompile-twee1 Output as Twee 1 source\n -a, --archive-twine2 Output as Twine 2 archive\n --archive-twine1 Output as Twine 1 archive\n --json Output as JSON\n --twee2-compat Enable Twee2 syntax compatibility\n --lint Lint story structure (broken links, dead ends, orphans)\n --no-trim Don't trim passage whitespace\n -t, --test Enable test/debug mode\n -w, --watch Watch for changes and rebuild\n -l, --log-stats Log compilation statistics\n --log-files Log input file list\n --list-formats List available story formats\n --init Initialize a new project\n --format-index <url> SFA-compatible format index URL (repeatable)\n --format-url <url> Direct format.js URL (repeatable)\n --tag-alias <alias=target> Map a tag to a special tag (repeatable)\n --exclude <glob> Leave out source files matching a glob (repeatable)\n --source-info Emit source file/line as data- attributes on passages\n --word-count-method <m> Word counting method: tweego (default), whitespace\n --no-remote Disable remote format fetching\n -c, --config <file> Config file path (default: ${CONFIG_FILENAME})\n --no-config Skip config file loading\n -h, --help Show this help\n -v, --version Show version\n\nSubcommands:\n cache list List cached remote formats\n cache clear [name] Clear cached formats (all or by name)\n cache size Show total cache size\n cache path Print cache directory path`);\n}\n\nmain().catch((err: unknown) => {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n"],"x_google_ignoreList":[12,13,14,15,16,17,18,19,20,21,22,23],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"twee-ts.js","names":["_exhaustive","fsWatch","parsePath","_exhaustive","_exhaustive","CharCodes","isTag","Text","Comment","CDATA","isTagRaw","CREATOR_NAME","CREATOR_NAME","_exhaustive","_exhaustive","LINE_TERMINATOR_RE","searchFrom","_exhaustive"],"sources":["../../src/ifid.ts","../../src/escape.ts","../../src/passage.ts","../../src/story.ts","../../src/media-types.ts","../../src/filesystem.ts","../../src/source-text.ts","../../src/util.ts","../../src/formats.ts","../../src/remote-formats.ts","../../src/format-resolution.ts","../../src/types.ts","../../src/lexer.ts","../../src/twee2-compat.ts","../../src/parser.ts","../../node_modules/.pnpm/entities@8.1.0/node_modules/entities/dist/decode-codepoint.js","../../node_modules/.pnpm/entities@8.1.0/node_modules/entities/dist/internal/decode-shared.js","../../node_modules/.pnpm/entities@8.1.0/node_modules/entities/dist/generated/decode-data-html.js","../../node_modules/.pnpm/entities@8.1.0/node_modules/entities/dist/generated/decode-data-xml.js","../../node_modules/.pnpm/entities@8.1.0/node_modules/entities/dist/internal/bin-trie-flags.js","../../node_modules/.pnpm/entities@8.1.0/node_modules/entities/dist/decode.js","../../node_modules/.pnpm/htmlparser2@12.0.0/node_modules/htmlparser2/dist/Tokenizer.js","../../node_modules/.pnpm/htmlparser2@12.0.0/node_modules/htmlparser2/dist/Parser.js","../../node_modules/.pnpm/domelementtype@3.0.0/node_modules/domelementtype/dist/index.js","../../node_modules/.pnpm/domhandler@6.0.1/node_modules/domhandler/dist/node.js","../../node_modules/.pnpm/domhandler@6.0.1/node_modules/domhandler/dist/index.js","../../node_modules/.pnpm/htmlparser2@12.0.0/node_modules/htmlparser2/dist/index.js","../../src/html-parser.ts","../../src/loader.ts","../../src/version.ts","../../src/output-twine2.ts","../../src/output-twine1.ts","../../src/output-twee.ts","../../src/modules.ts","../../src/passage-omission.ts","../../src/start-passage.ts","../../src/compiler.ts","../../src/javascript-strings.ts","../../src/link-markup.ts","../../src/sugarcube-macros.ts","../../src/inspect.ts","../../src/lint.ts","../../src/config.ts","../../bin/twee-ts.ts"],"sourcesContent":["/**\n * IFID (Interactive Fiction IDentifier) generation and validation.\n * Ported from ifid.go.\n */\nimport { randomUUID } from 'node:crypto';\nimport type { IFID } from './types.js';\n\n/** Generate a new IFID (UUID v4, uppercase). */\nexport function generateIFID(): IFID {\n return randomUUID().toUpperCase() as IFID;\n}\n\n/** Validate and brand an IFID string. Throws on invalid input. */\nexport function createIFID(value: string): IFID {\n const err = validateIFID(value);\n if (err) throw new Error(`Invalid IFID: ${err}`);\n return value.toUpperCase() as IFID;\n}\n\n/**\n * Validate an IFID string.\n * Accepts both bare UUIDs and UUID://...// wrapped format.\n * Returns null if valid, or an error message string.\n */\nexport function validateIFID(ifid: string): string | null {\n let uuid = ifid;\n\n switch (ifid.length) {\n case 36:\n break;\n case 45: {\n if (ifid.slice(0, 7).toUpperCase() !== 'UUID://' || ifid.slice(43) !== '//') {\n return 'invalid IFID UUID://...// format';\n }\n uuid = ifid.slice(7, 43);\n break;\n }\n default:\n return `invalid IFID length: ${ifid.length}`;\n }\n\n for (let i = 0; i < uuid.length; i++) {\n const ch = uuid[i]!;\n switch (i) {\n case 8:\n case 13:\n case 18:\n case 23:\n if (ch !== '-') {\n return `invalid IFID character '${ch}' at position ${i + 1}`;\n }\n break;\n case 14:\n if (ch < '1' || ch > '5') {\n return `invalid version '${ch}' at position ${i + 1}`;\n }\n break;\n case 19:\n if (!['8', '9', 'a', 'A', 'b', 'B'].includes(ch)) {\n return `invalid variant '${ch}' at position ${i + 1}`;\n }\n break;\n default:\n if (!/^[0-9a-fA-F]$/.test(ch)) {\n return `invalid IFID hex value '${ch}' at position ${i + 1}`;\n }\n break;\n }\n }\n\n return null;\n}\n","/**\n * HTML, attribute, tiddler, and twee escaping/unescaping utilities.\n * Ported from escaping.go.\n */\n\n/** Escape the minimum characters required for HTML attribute values. */\nexport function attrEscape(s: string): string {\n if (s.length === 0) return s;\n return s.replace(/&/g, '&').replace(/\"/g, '"').replace(/'/g, ''');\n}\n\n/** Escape for HTML attribute values including < and > (for spec-compliant output). */\nexport function fullAttrEscape(s: string): string {\n if (s.length === 0) return s;\n return s\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\n/** Escape the minimum characters required for general HTML content. */\nexport function htmlEscape(s: string): string {\n if (s.length === 0) return s;\n return s\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\n/** Escape for Twine 1 tiddler format. */\nexport function tiddlerEscape(s: string): string {\n if (s.length === 0) return s;\n return s\n .replace(/\\\\/g, '\\\\s')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/\\t/g, '\\\\t')\n .replace(/\\n/g, '\\\\n');\n}\n\n/** Unescape from Twine 1 tiddler format. */\nexport function tiddlerUnescape(s: string): string {\n if (s.length === 0) return s;\n return s.replace(/\\\\n/g, '\\n').replace(/\\\\t/g, '\\t').replace(/\\\\s/g, '\\\\');\n}\n\n/** Escape characters that are special in Twee passage names/tags. */\nexport function tweeEscape(s: string): string {\n if (s.length === 0) return s;\n return s.replace(/[\\\\[\\]{}]/g, (ch) => '\\\\' + ch);\n}\n\n/** Escape a string for safe inclusion in a JavaScript string literal. */\nexport function jsStringEscape(s: string): string {\n if (s.length === 0) return s;\n return s\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\n/g, '\\\\n')\n .replace(/\\r/g, '\\\\r')\n .replace(/\\t/g, '\\\\t');\n}\n\n/** Sanitize a string for safe inclusion in a CSS or JS block comment. */\nexport function commentSanitize(s: string): string {\n return s.replace(/\\*\\//g, '* /');\n}\n\n/** Sanitize a string for safe inclusion in an HTML comment. */\nexport function htmlCommentSanitize(s: string): string {\n return s.replace(/-->/g, '-- >');\n}\n\n/**\n * Escape JavaScript for the content of an HTML `<script>` element, so that the HTML parser reads all of it as\n * the element's text and ends the element at the end tag written after it.\n *\n * - Every `</script` (in any letter case) becomes `<\\/script`. HTML ends a script element at the first\n * `</script` followed by whitespace, `/` or `>`, wherever it is in the JavaScript, even inside a string.\n * - Every `<!--` becomes `<\\!--`, but only if the text would otherwise end in the HTML tokenizer's \"script\n * data double escaped\" state: after a `<!--` and then a `<script` start tag with no `-->` between them, the\n * end tag after the text would not end the element.\n *\n * Inserting a backslash after `<` keeps the value of every string, template, and regular expression literal\n * and every comment where these sequences can be written (`\\/` and `\\!` are identity escapes; a backslash\n * already before the `<` escapes the `<`, as it did before); `<\\/script` is also how minifiers such as Terser\n * write inline scripts. It only changes code that uses them outside literals (`a </script/ b`, an HTML-like `<!--`\n * comment that is escaped because of a later `<script`), the raw text of a tagged template, and a `<!--` in a\n * regular expression with the `u` or `v` flag. The result is unchanged by escaping it again.\n */\nexport function scriptContentEscape(s: string): string {\n const escaped = s.replace(/<(?=\\/script)/gi, '<\\\\');\n return endsDoubleEscaped(escaped) ? escaped.replace(/<(?=!--)/g, '<\\\\') : escaped;\n}\n\n/**\n * Whether the HTML tokenizer, reading `s` as script element content with no `</script` in it, ends in the\n * \"script data double escaped\" state, where an end tag after `s` would not end the element.\n * See https://html.spec.whatwg.org/multipage/parsing.html#script-data-escaped-state.\n */\nfunction endsDoubleEscaped(s: string): boolean {\n const scriptStartTag = /<script[\\t\\n\\f\\r />]/gi;\n let pos = 0;\n for (;;) {\n // Script data: a `<!--` enters the escaped state.\n const open = s.indexOf('<!--', pos);\n if (open === -1) return false;\n // Escaped: a `-->` leaves it (the dashes of `<!--` count, so `<!-->` leaves at once); a `<script` start\n // tag enters the double escaped state.\n const escapedFrom = open + 2;\n const close = s.indexOf('-->', escapedFrom);\n scriptStartTag.lastIndex = escapedFrom;\n const start = scriptStartTag.exec(s);\n if (start === null || (close !== -1 && close < start.index)) {\n if (close === -1) return false;\n pos = close + 3;\n continue;\n }\n // Double escaped: only a `</script` (none are left) or a `-->` leaves it.\n const end = s.indexOf('-->', start.index + start[0].length);\n if (end === -1) return true;\n pos = end + 3;\n }\n}\n\n/**\n * Escape CSS for the content of an HTML `<style>` element: every `</style` (in any letter case) becomes\n * `<\\/style`, since HTML ends a style element at the first `</style` followed by whitespace, `/` or `>`.\n * `\\/` stands for `/` in CSS strings and URLs, and comments don't matter; `</style` anywhere else isn't valid\n * CSS anyway.\n */\nexport function styleContentEscape(s: string): string {\n return s.replace(/<(?=\\/style)/gi, '<\\\\');\n}\n\n/** Apply ROT13 encoding to a string (only affects [A-Za-z]). */\nexport function rot13(s: string): string {\n if (s.length === 0) return s;\n return s.replace(/[A-Za-z]/g, (ch) => {\n const base = ch <= 'Z' ? 65 : 97;\n return String.fromCharCode(((ch.charCodeAt(0) - base + 13) % 26) + base);\n });\n}\n\n/** Unescape backslash-escaped Twee characters. */\nexport function tweeUnescape(s: string): string {\n if (s.length === 0) return s;\n let result = '';\n for (let i = 0; i < s.length; i++) {\n if (s[i] === '\\\\') {\n i++;\n if (i >= s.length) {\n result += '\\\\';\n break;\n }\n }\n result += s[i];\n }\n return result;\n}\n","/**\n * Passage helpers and output methods.\n * Ported from passage.go / passagedata.go.\n */\nimport type { Passage, PassageMetadata, OutputMode, WordCountMethod } from './types.js';\nimport { attrEscape, fullAttrEscape, htmlEscape, tiddlerEscape, tweeEscape, rot13, commentSanitize } from './escape.js';\n\n// Info passages contain structural data, metadata, and code rather than story content.\nconst INFO_PASSAGE_NAMES = new Set([\n 'StoryAuthor',\n 'StoryInit',\n 'StoryMenu',\n 'StorySubtitle',\n 'StoryTitle',\n 'PassageReady',\n 'PassageDone',\n 'PassageHeader',\n 'PassageFooter',\n 'StoryBanner',\n 'StoryCaption',\n 'MenuOptions',\n 'MenuShare',\n 'MenuStory',\n 'StoryInterface',\n 'StoryShare',\n 'StorySettings',\n 'StoryData',\n 'StoryIncludes',\n]);\n\nconst INFO_TAGS = ['annotation', 'script', 'stylesheet', 'widget'];\n\nexport function hasTag(p: Passage, tag: string): boolean {\n return p.tags.includes(tag);\n}\n\nexport function hasAnyTag(p: Passage, ...tags: string[]): boolean {\n return p.tags.some((t) => tags.includes(t));\n}\n\nexport function hasTagStartingWith(p: Passage, prefix: string): boolean {\n return p.tags.some((t) => t.startsWith(prefix));\n}\n\nexport function hasInfoTags(p: Passage): boolean {\n return hasAnyTag(p, ...INFO_TAGS) || hasTagStartingWith(p, 'Twine.');\n}\n\nexport function hasInfoName(p: Passage): boolean {\n return INFO_PASSAGE_NAMES.has(p.name);\n}\n\nexport function isInfoPassage(p: Passage): boolean {\n return hasInfoName(p) || hasInfoTags(p);\n}\n\nexport function isStoryPassage(p: Passage): boolean {\n return !hasInfoName(p) && !hasInfoTags(p);\n}\n\nexport function hasMetadataPosition(p: Passage): boolean {\n return p.metadata != null && p.metadata.position != null && p.metadata.position !== '';\n}\n\nexport function hasMetadataSize(p: Passage): boolean {\n return p.metadata != null && p.metadata.size != null && p.metadata.size !== '';\n}\n\nexport function hasAnyMetadata(p: Passage): boolean {\n if (!p.metadata) return false;\n return Object.values(p.metadata).some((v) => v != null && v !== '');\n}\n\nexport function marshalMetadata(meta: PassageMetadata): string {\n const obj: Record<string, string> = {};\n for (const [key, value] of Object.entries(meta)) {\n if (typeof value === 'string' && value) obj[key] = value;\n }\n return JSON.stringify(obj);\n}\n\nexport function unmarshalMetadata(json: string): PassageMetadata {\n const raw: unknown = JSON.parse(json);\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n return {};\n }\n const parsed = raw as Record<string, unknown>;\n const meta: PassageMetadata = {};\n for (const [key, value] of Object.entries(parsed)) {\n if (typeof value === 'string') meta[key] = value;\n }\n return meta;\n}\n\n/** Convert passage to Twee source. */\nexport function passageToTwee(p: Passage, outMode: OutputMode): string {\n let output: string;\n if (outMode === 'twee3') {\n output = ':: ' + tweeEscape(p.name);\n if (p.tags.length > 0) {\n output += ' [' + tweeEscape(p.tags.join(' ')) + ']';\n }\n if (hasAnyMetadata(p) && p.metadata) {\n output += ' ' + marshalMetadata(p.metadata);\n }\n } else {\n output = ':: ' + p.name;\n if (p.tags.length > 0) {\n output += ' [' + p.tags.join(' ') + ']';\n }\n }\n output += '\\n';\n if (p.text.length > 0) {\n output += p.text + '\\n';\n }\n output += '\\n\\n';\n return output;\n}\n\n/** Generate `<tw-passagedata>` HTML for Twine 2. */\nexport function passageToPassagedata(p: Passage, pid: number, options?: { readonly sourceInfo?: boolean }): string {\n let position: string;\n let size: string;\n\n if (hasMetadataPosition(p)) {\n position = p.metadata?.position ?? '';\n } else {\n const x = pid % 10;\n const y = Math.floor(pid / 10);\n const xp = x === 0 ? 10 : x;\n const yp = x === 0 ? y : y + 1;\n position = `${xp * 125 - 25},${yp * 125 - 25}`;\n }\n\n if (hasMetadataSize(p)) {\n size = p.metadata?.size ?? '';\n } else {\n size = '100,100';\n }\n\n let attrs = `<tw-passagedata pid=\"${pid}\" name=${quote(fullAttrEscape(p.name))} tags=${quote(attrEscape(p.tags.join(' ')))} position=${quote(attrEscape(position))} size=${quote(attrEscape(size))}`;\n if (options?.sourceInfo && p.source) {\n attrs += ` data-source-file=${quote(attrEscape(p.source.file))} data-source-line=\"${p.source.line}\"`;\n }\n return `${attrs}>${htmlEscape(p.text)}</tw-passagedata>`;\n}\n\n/** Generate `<div tiddler>` HTML for Twine 1. */\nexport function passageToTiddler(p: Passage, pid: number, obfuscateRot13 = false): string {\n let position: string;\n\n if (hasMetadataPosition(p)) {\n position = p.metadata?.position ?? '';\n } else {\n const x = pid % 10;\n const y = Math.floor(pid / 10);\n const xp = x === 0 ? 10 : x;\n const yp = x === 0 ? y : y + 1;\n position = `${xp * 140 - 130},${yp * 140 - 130}`;\n }\n\n const created = new Date().toISOString().replace(/[-:T]/g, '').slice(0, 12);\n const content = obfuscateRot13 && p.name !== 'StorySettings' ? tiddlerEscape(rot13(p.text)) : tiddlerEscape(p.text);\n const nameComment = obfuscateRot13 ? `<!-- ${commentSanitize(p.name)} -->` : '';\n return `<div tiddler=${quote(attrEscape(p.name))} tags=${quote(attrEscape(p.tags.join(' ')))} created=${quote(created)} modifier=${quote('twee')} twine-position=${quote(attrEscape(position))}>${nameComment}${content}</div>`;\n}\n\n/**\n * Count words in a passage.\n *\n * - `'tweego'` (default): Strip newlines, strip comments, count NFKD-normalized characters, divide by 5.\n * - `'whitespace'`: Strip comments and markup, split on whitespace, count tokens.\n */\nexport function countWords(p: Passage, method: WordCountMethod = 'tweego'): number {\n switch (method) {\n case 'tweego': {\n let text = p.text;\n text = text.replace(/\\n/g, '');\n text = text.replace(/(?:\\/%.+?%\\/|\\/\\*.+?\\*\\/|<!--.+?-->)/gs, '');\n const normalized = text.normalize('NFKD');\n const count = [...normalized].length;\n if (count === 0) return 0;\n const words = Math.floor(count / 5);\n return count % 5 > 0 ? words + 1 : words;\n }\n case 'whitespace': {\n let text = p.text;\n // Strip comments\n text = text.replace(/(?:\\/%.+?%\\/|\\/\\*.+?\\*\\/|<!--.+?-->)/gs, '');\n // Strip Twine macros <<...>>\n text = text.replace(/<<[^>]*>>/g, '');\n // Strip Twine links [[...]] — keep display text\n text = text.replace(/\\[\\[([^\\]|]*?)(?:\\|[^\\]]*?)?\\]\\]/g, '$1');\n // Strip HTML tags\n text = text.replace(/<[^>]+>/g, '');\n const tokens = text.split(/\\s+/).filter((t) => t.length > 0);\n return tokens.length;\n }\n default: {\n const _exhaustive: never = method;\n throw new Error(`Unhandled word count method: ${_exhaustive as string}`);\n }\n }\n}\n\n/**\n * Apply tag aliases: for each passage carrying an alias tag, add the canonical\n * tag if not already present. Returns new passage objects where tags changed;\n * unchanged passages are returned as-is. Idempotent — safe to call multiple times.\n */\nexport function applyTagAliases(passages: readonly Passage[], aliases: Record<string, string>): Passage[] {\n const entries = Object.entries(aliases);\n if (entries.length === 0) return [...passages];\n return passages.map((p) => {\n const original = p.tags;\n const added: string[] = [];\n for (const [alias, canonical] of entries) {\n if (original.includes(alias) && !original.includes(canonical) && !added.includes(canonical)) {\n added.push(canonical);\n }\n }\n return added.length > 0 ? { ...p, tags: [...original, ...added] } : p;\n });\n}\n\nfunction quote(s: string): string {\n return `\"${s}\"`;\n}\n","/**\n * Story model + StoryData JSON marshal/unmarshal.\n * Ported from story.go + storydata.go.\n */\nimport type { Story, ReadonlyStory, Passage, Diagnostic, WordCountMethod, IFID } from './types.js';\nimport { validateIFID } from './ifid.js';\nimport { isStoryPassage, countWords } from './passage.js';\n\n/** Module-level index: maps passage names to their array indices for O(1) lookups. */\nconst passageIndex = new WeakMap<Story, Map<string, number>>();\n\nfunction getIndex(story: Story): Map<string, number> {\n let index = passageIndex.get(story);\n if (!index) {\n // Rebuild for stories not created via createStory() (e.g., tests, external code)\n index = new Map();\n for (let i = 0; i < story.passages.length; i++) {\n const passage = story.passages[i];\n if (passage) index.set(passage.name, i);\n }\n passageIndex.set(story, index);\n }\n return index;\n}\n\nexport function createStory(): Story {\n const story: Story = {\n name: '',\n ifid: '' as IFID,\n passages: [],\n legacyIFID: '' as IFID,\n twine1: { settings: new Map() },\n twine2: {\n format: '',\n formatVersion: '',\n options: new Map(),\n start: '',\n tags: '',\n tagColors: new Map(),\n zoom: 1,\n },\n };\n passageIndex.set(story, new Map());\n return story;\n}\n\nexport function storyHas(story: Story, name: string): boolean {\n return getIndex(story).has(name);\n}\n\nexport function storyIndex(story: Story, name: string): number {\n return getIndex(story).get(name) ?? -1;\n}\n\nexport function storyGet(story: Story, name: string): Passage | undefined {\n const i = storyIndex(story, name);\n return i === -1 ? undefined : story.passages[i];\n}\n\nexport function storyAppend(story: Story, p: Passage, diagnostics: Diagnostic[]): void {\n const index = getIndex(story);\n const i = index.get(p.name) ?? -1;\n if (i === -1) {\n index.set(p.name, story.passages.length);\n story.passages.push(p);\n } else {\n diagnostics.push({\n level: 'warning',\n message: `Replacing existing passage \"${p.name}\" with duplicate.`,\n });\n story.passages[i] = p;\n }\n}\n\nexport function storyPrepend(story: Story, p: Passage, diagnostics: Diagnostic[]): void {\n const index = getIndex(story);\n const i = index.get(p.name) ?? -1;\n if (i === -1) {\n story.passages.unshift(p);\n // Rebuild index: unshift shifts all existing indices by 1\n index.clear();\n for (let j = 0; j < story.passages.length; j++) {\n const passage = story.passages[j];\n if (passage) index.set(passage.name, j);\n }\n } else {\n diagnostics.push({\n level: 'warning',\n message: `Replacing existing passage \"${p.name}\" with duplicate.`,\n });\n story.passages[i] = p;\n }\n}\n\n// --- StoryData JSON ---\n\ninterface StoryDataJSON {\n ifid?: string;\n format?: string;\n 'format-version'?: string;\n options?: string[];\n start?: string;\n tags?: string;\n 'tag-colors'?: Record<string, string>;\n zoom?: number;\n}\n\nexport function marshalStoryData(story: ReadonlyStory): string {\n const data: StoryDataJSON = {};\n if (story.ifid) data.ifid = story.ifid;\n if (story.twine2.format) data.format = story.twine2.format;\n if (story.twine2.formatVersion) data['format-version'] = story.twine2.formatVersion;\n\n const options: string[] = [];\n for (const [opt, val] of story.twine2.options) {\n if (val) options.push(opt);\n }\n if (options.length > 0) data.options = options;\n\n if (story.twine2.start) data.start = story.twine2.start;\n if (story.twine2.tags) data.tags = story.twine2.tags;\n\n if (story.twine2.tagColors.size > 0) {\n data['tag-colors'] = Object.fromEntries(story.twine2.tagColors);\n }\n if (story.twine2.zoom !== 1) data.zoom = story.twine2.zoom;\n\n return JSON.stringify(data, null, '\\t');\n}\n\nexport function unmarshalStoryData(story: Story, json: string): string | null {\n let raw: unknown;\n try {\n raw = JSON.parse(json) as unknown;\n } catch (e) {\n return `Cannot unmarshal \"StoryData\"; ${e instanceof Error ? e.message : String(e)}`;\n }\n\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n return 'Cannot unmarshal \"StoryData\"; expected a JSON object';\n }\n const data = raw as StoryDataJSON;\n\n if (typeof data.ifid === 'string' && data.ifid) story.ifid = data.ifid.toUpperCase() as IFID;\n if (typeof data.format === 'string' && data.format) story.twine2.format = data.format;\n if (typeof data['format-version'] === 'string' && data['format-version'])\n story.twine2.formatVersion = data['format-version'];\n if (Array.isArray(data.options)) {\n for (const opt of data.options) {\n if (typeof opt === 'string') story.twine2.options.set(opt, true);\n }\n }\n if (typeof data.start === 'string' && data.start) story.twine2.start = data.start;\n if (typeof data.tags === 'string') story.twine2.tags = data.tags;\n if (typeof data['tag-colors'] === 'object' && data['tag-colors'] !== null && !Array.isArray(data['tag-colors'])) {\n for (const [tag, color] of Object.entries(data['tag-colors'])) {\n if (typeof color === 'string') story.twine2.tagColors.set(tag, color);\n }\n }\n if (typeof data.zoom === 'number' && data.zoom !== 0) story.twine2.zoom = data.zoom;\n\n return null;\n}\n\n// --- StorySettings (legacy) ---\n\nexport function unmarshalStorySettings(story: Story, text: string, diagnostics: Diagnostic[]): void {\n const obsolete: string[] = [];\n\n for (const rawLine of text.split('\\n')) {\n const line = rawLine.trim();\n if (line.length === 0) continue;\n\n const colonIdx = line.indexOf(':');\n if (colonIdx === -1) {\n diagnostics.push({\n level: 'warning',\n message: `Malformed \"StorySettings\" entry; skipping \"${line}\".`,\n });\n continue;\n }\n\n const key = line.slice(0, colonIdx).trim().toLowerCase();\n const val = line\n .slice(colonIdx + 1)\n .trim()\n .toLowerCase();\n\n switch (key) {\n case 'ifid': {\n const err = validateIFID(val);\n if (err === null) {\n story.legacyIFID = val.toUpperCase() as IFID;\n }\n obsolete.push('\"ifid\"');\n continue;\n }\n case 'zoom':\n obsolete.push('\"zoom\"');\n continue;\n }\n\n story.twine1.settings.set(key, val);\n }\n\n if (obsolete.length > 0) {\n const entries = obsolete.length === 1 ? 'entry' : 'entries';\n const pronoun = obsolete.length === 1 ? 'it' : 'them';\n diagnostics.push({\n level: 'warning',\n message:\n `Detected obsolete \"StorySettings\" ${entries}: ${obsolete.join(', ')}. ` +\n `Please remove ${pronoun} from the \"StorySettings\" special passage.`,\n });\n }\n}\n\n/**\n * Process a passage and add it to the story, handling special passages.\n * Creates new passage objects where text is modified rather than mutating the input.\n */\nexport function storyAdd(story: Story, p: Passage, diagnostics: Diagnostic[]): void {\n let processed = p;\n\n switch (p.name) {\n case 'StoryIncludes':\n diagnostics.push({\n level: 'warning',\n message:\n 'Ignoring \"StoryIncludes\" compiler special passage; twee-ts allows you to specify project files and/or directories to recursively search.',\n });\n break;\n\n case 'StoryData': {\n const err = unmarshalStoryData(story, p.text);\n if (err === null) {\n // Validate the IFID if present.\n if (story.ifid.length > 0) {\n const vErr = validateIFID(story.ifid);\n if (vErr !== null) {\n diagnostics.push({\n level: 'error',\n message: `Cannot validate IFID; ${vErr}.`,\n });\n }\n }\n // Rebuild passage contents to normalize.\n processed = { ...p, text: marshalStoryData(story) };\n } else {\n diagnostics.push({\n level: 'warning',\n message: `Cannot unmarshal \"StoryData\" compiler special passage; ${err}.`,\n });\n }\n break;\n }\n\n case 'StorySettings':\n unmarshalStorySettings(story, p.text, diagnostics);\n break;\n\n case 'StoryTitle': {\n const trimmed = p.text.trim();\n processed = { ...p, text: trimmed };\n story.name = trimmed;\n break;\n }\n }\n\n storyAppend(story, processed, diagnostics);\n}\n\n/** Get story passage count and word count stats. */\nexport function getStoryStats(\n story: Story,\n wordCountMethod: WordCountMethod = 'tweego',\n): { passages: number; storyPassages: number; words: number } {\n let storyPassages = 0;\n let words = 0;\n for (const p of story.passages) {\n if (isStoryPassage(p)) {\n storyPassages++;\n words += countWords(p, wordCountMethod);\n }\n }\n return { passages: story.passages.length, storyPassages, words };\n}\n\n/**\n * Builder that separates the mutable construction phase from the immutable consumption phase.\n * During construction, the internal `Story` is mutable via `add()` and direct access.\n * After `build()`, the story is returned as `ReadonlyStory`.\n */\nexport class StoryBuilder {\n /** The mutable story, accessible during construction for loader functions. */\n readonly story: Story;\n\n constructor() {\n this.story = createStory();\n }\n\n /** Add a passage, handling special passages (StoryData, StoryTitle, etc.). */\n add(passage: Passage, diagnostics: Diagnostic[]): void {\n storyAdd(this.story, passage, diagnostics);\n }\n\n /** Check if a passage name exists. */\n has(name: string): boolean {\n return storyHas(this.story, name);\n }\n\n /** Finalize and return the story as read-only. */\n build(): ReadonlyStory {\n return this.story;\n }\n}\n","/**\n * Extension → MIME type mapping.\n * Ported from util.go:mediaTypeFromExt().\n */\n\nimport { extname } from 'node:path';\n\nconst MEDIA_TYPE_MAP: Record<string, string> = {\n // Audio\n aac: 'audio/aac',\n flac: 'audio/flac',\n ogg: 'audio/ogg',\n wav: 'audio/wav',\n mp3: 'audio/mpeg',\n m4a: 'audio/mp4',\n oga: 'audio/ogg',\n opus: 'audio/ogg',\n wave: 'audio/wav',\n weba: 'audio/webm',\n\n // Fonts\n otf: 'font/otf',\n ttf: 'font/ttf',\n woff: 'font/woff',\n woff2: 'font/woff2',\n\n // Images\n gif: 'image/gif',\n jpeg: 'image/jpeg',\n jpg: 'image/jpeg',\n png: 'image/png',\n svg: 'image/svg+xml',\n tif: 'image/tiff',\n tiff: 'image/tiff',\n webp: 'image/webp',\n\n // Metadata\n vtt: 'text/vtt',\n\n // Video\n mp4: 'video/mp4',\n ogv: 'video/ogg',\n webm: 'video/webm',\n};\n\nexport function mediaTypeFromExt(ext: string): string {\n return MEDIA_TYPE_MAP[ext] ?? 'application/octet-stream';\n}\n\nexport function mediaTypeFromFilename(filename: string): string {\n return mediaTypeFromExt(normalizedFileExt(filename));\n}\n\nexport function normalizedFileExt(filename: string): string {\n const ext = extname(filename);\n if (!ext) return '';\n return ext.slice(1).toLowerCase();\n}\n\n/** Slugify a string for safe use as a DOM ID. */\nexport function slugify(original: string): string {\n return original.replace(/[\\x00-\\x20!-/:-@[-^`{-\\x9f]+/g, '_');\n}\n\n/** Check if a file has a known type that should be processed. */\nexport function isKnownFileType(filename: string): boolean {\n const ext = normalizedFileExt(filename);\n return KNOWN_EXTENSIONS.has(ext);\n}\n\nconst KNOWN_EXTENSIONS = new Set([\n 'tw',\n 'twee',\n 'tw2',\n 'twee2',\n 'htm',\n 'html',\n 'css',\n 'js',\n 'otf',\n 'ttf',\n 'woff',\n 'woff2',\n 'gif',\n 'jpeg',\n 'jpg',\n 'png',\n 'svg',\n 'tif',\n 'tiff',\n 'webp',\n 'aac',\n 'flac',\n 'm4a',\n 'mp3',\n 'oga',\n 'ogg',\n 'opus',\n 'wav',\n 'wave',\n 'weba',\n 'mp4',\n 'ogv',\n 'webm',\n 'vtt',\n]);\n\n/** Font format hint for @font-face. */\nexport function fontFormatHint(ext: string): string {\n switch (ext) {\n case 'ttf':\n return 'truetype';\n case 'otf':\n return 'opentype';\n default:\n return ext;\n }\n}\n","/**\n * File system utilities: path walking, file type detection, watch mode.\n * Ported from filesystem.go.\n */\nimport { readdirSync, statSync, watch as fsWatch } from 'node:fs';\nimport * as nodePath from 'node:path';\nimport { dirname, resolve, relative, join, sep } from 'node:path';\nimport { isKnownFileType } from './media-types.js';\nimport type { Diagnostic } from './types.js';\n\n/**\n * Whether `filename` matches one of the `exclude` globs. The globs are matched\n * against the file's path relative to the working directory, the path\n * getFilenames reports; an absolute `filename` is made relative first. A leading\n * `./` in a glob is dropped. Matching is Node's `path.matchesGlob`.\n */\nexport function isExcluded(filename: string, exclude: readonly string[]): boolean {\n if (exclude.length === 0) return false;\n // Read from the namespace, not imported by name: path.matchesGlob arrived in\n // Node 22.5, and a named import would stop this module loading on 22.0-22.4.\n const { matchesGlob } = nodePath;\n if (typeof matchesGlob !== 'function') {\n throw new Error(`The exclude option needs Node.js 22.5 or newer (found ${process.version}).`);\n }\n const rel = relative(process.cwd(), resolve(filename)) || filename;\n return exclude.some((pattern) => matchesGlob(rel, pattern.replace(/^\\.\\//, '')));\n}\n\nexport interface FilenamesResult {\n readonly filenames: string[];\n /** One warning per path that could not be read. */\n readonly diagnostics: Diagnostic[];\n}\n\n/**\n * Recursively walk directories, collecting regular file paths.\n * Filters out the output file to prevent circular compilation, and the files\n * that match an `exclude` glob (see isExcluded).\n * Like Tweego, a path that cannot be read is reported as a warning and skipped.\n */\nexport function getFilenames(\n pathnames: string[],\n outFilename?: string,\n exclude: readonly string[] = [],\n): FilenamesResult {\n const filenames: string[] = [];\n const diagnostics: Diagnostic[] = [];\n const absOutFile = outFilename ? resolve(outFilename) : '';\n\n function warn(pathname: string, e: unknown): void {\n diagnostics.push({ level: 'warning', message: `path ${pathname}: ${e instanceof Error ? e.message : String(e)}` });\n }\n\n function walk(pathname: string): void {\n let stat;\n try {\n stat = statSync(pathname);\n } catch (e) {\n warn(pathname, e);\n return;\n }\n\n if (stat.isFile()) {\n const abs = resolve(pathname);\n if (abs === absOutFile) return;\n const rel = relative(process.cwd(), abs);\n if (isExcluded(rel || abs, exclude)) return;\n filenames.push(rel || abs);\n } else if (stat.isDirectory()) {\n let entries;\n try {\n entries = readdirSync(pathname);\n } catch (e) {\n warn(pathname, e);\n return;\n }\n for (const entry of entries) {\n walk(join(pathname, entry));\n }\n }\n }\n\n for (const pathname of pathnames) {\n walk(pathname);\n }\n\n return { filenames, diagnostics };\n}\n\nexport interface WatchHandle {\n close(): void;\n}\n\n/** Whether the absolute path `file` is the absolute path `dir` or inside it. */\nfunction isInsideDir(file: string, dir: string): boolean {\n return file === dir || file.startsWith(dir.endsWith(sep) ? dir : dir + sep);\n}\n\n/**\n * The watched paths split into folders (as given) and files (absolute). A path\n * that cannot be read counts as a folder, which fs.watch then fails to watch.\n */\nfunction splitWatchRoots(pathnames: readonly string[]): { dirs: string[]; files: Set<string> } {\n const dirs: string[] = [];\n const files = new Set<string>();\n for (const pathname of pathnames) {\n let isFile = false;\n try {\n isFile = statSync(pathname).isFile();\n } catch {\n // Unreadable: left to fs.watch, as a folder.\n }\n if (isFile) files.add(resolve(pathname));\n else dirs.push(pathname);\n }\n return { dirs, files };\n}\n\n/**\n * Watch paths for changes, calling the build callback on known file type changes.\n * A folder is watched recursively; a file is watched on its own and counts\n * whatever its type (a head file, say). A change to a file `ignore` returns true\n * for (given the path relative to the working directory) schedules no build.\n * Uses debouncing to avoid rapid rebuilds.\n */\nexport function watchFilesystem(\n pathnames: string[],\n outFilename: string,\n callback: (changedFiles?: ReadonlySet<string>) => void,\n ignore: (filename: string) => boolean = () => false,\n): WatchHandle {\n const absOutFile = resolve(outFilename);\n const watchers: ReturnType<typeof fsWatch>[] = [];\n let buildTimer: ReturnType<typeof setTimeout> | null = null;\n const BUILD_DEBOUNCE = 500;\n const pendingFiles = new Set<string>();\n\n function scheduleBuild(changedFile?: string): void {\n if (changedFile) pendingFiles.add(changedFile);\n if (buildTimer) clearTimeout(buildTimer);\n buildTimer = setTimeout(() => {\n buildTimer = null;\n const files = pendingFiles.size > 0 ? new Set(pendingFiles) : undefined;\n pendingFiles.clear();\n callback(files);\n }, BUILD_DEBOUNCE);\n }\n\n // A changed file, as an absolute path. `named`: it is one of the watched paths\n // itself, so it counts whatever its type. Reported relative to the working\n // directory, the form getFilenames gives and the incremental cache is keyed by.\n function fileChanged(abs: string, named: boolean): void {\n if (abs === absOutFile) return;\n if (!named && !isKnownFileType(abs)) return;\n const rel = relative(process.cwd(), abs);\n if (!ignore(rel || abs)) scheduleBuild(rel || abs);\n }\n\n function watchPath(pathname: string, recursive: boolean, listener: (filename: string) => void): void {\n try {\n watchers.push(\n fsWatch(pathname, { recursive }, (_event, filename) => {\n if (filename) listener(filename);\n }),\n );\n } catch {\n // Ignore inaccessible paths\n }\n }\n\n const { dirs, files } = splitWatchRoots(pathnames);\n const absDirs = dirs.map((dir) => resolve(dir));\n for (const dir of dirs) {\n watchPath(dir, true, (filename) => {\n const abs = resolve(dir, filename);\n fileChanged(abs, files.has(abs));\n });\n }\n\n // A file is watched through its folder, not on its own: the OS reports only the\n // file's name for a watch on the file, and an editor that saves by replacing the\n // file would leave such a watch on the old one. A file inside a watched folder is\n // seen by that folder's watcher.\n const fileDirs = new Set(\n [...files].filter((file) => !absDirs.some((dir) => isInsideDir(file, dir))).map((file) => dirname(file)),\n );\n for (const dir of fileDirs) {\n watchPath(dir, false, (filename) => {\n const abs = resolve(dir, filename);\n if (files.has(abs)) fileChanged(abs, true);\n });\n }\n\n // Build once initially (no changedFiles = full build).\n callback();\n\n return {\n close() {\n if (buildTimer) clearTimeout(buildTimer);\n for (const w of watchers) w.close();\n },\n };\n}\n","/**\n * Source text normalization shared by every input path (files, in-memory sources, `parseTwee`).\n */\n\n/**\n * Strip a leading UTF-8 byte order mark and convert CRLF and bare CR line endings to LF.\n * Idempotent, so text that is already normalized passes through unchanged.\n */\nexport function normalizeSourceText(text: string): string {\n const withoutBOM = text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;\n return withoutBOM.replace(/\\r\\n?/g, '\\n');\n}\n","/**\n * Shared file I/O utilities.\n */\nimport { readFileSync } from 'node:fs';\nimport { parse as parsePath } from 'node:path';\nimport { normalizeSourceText } from './source-text.js';\n\n/** Read a file as UTF-8 with BOM stripping and line ending normalization. */\nexport function readUTF8(filename: string): string {\n return normalizeSourceText(readFileSync(filename, 'utf-8'));\n}\n\n/** Read a file as base64. */\nexport function readBase64(filename: string): string {\n return readFileSync(filename).toString('base64');\n}\n\n/** Get the filename without extension, falling back to the full basename for dotfiles. */\nexport function baseNameWithoutExt(filename: string): string {\n const { name, ext } = parsePath(filename);\n return name || ext;\n}\n","/**\n * Story format discovery, loading, and SemVer matching.\n * Ported from formats.go + config.go.\n */\nimport { readdirSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport type { FormatRequest, StoryFormatInfo, Twine2FormatJSON } from './types.js';\nimport { readUTF8 } from './util.js';\n\n/**\n * Attempt to fix non-strict JSON (trailing commas, single quotes, unquoted keys).\n */\nfunction relaxedJSONParse(json: string): unknown {\n // First try standard parse\n try {\n return JSON.parse(json);\n } catch {\n // fall through to relaxed parsing\n }\n\n let fixed = json;\n\n // Replace single-quoted string values with double-quoted\n // Match single-quoted strings: 'value' -> \"value\"\n fixed = fixed.replace(/'([^'\\\\]*(?:\\\\.[^'\\\\]*)*)'/g, '\"$1\"');\n\n // Add quotes around unquoted property names\n // Match word chars before a colon that aren't already quoted\n fixed = fixed.replace(/(?<=^|[{,]\\s*)([A-Za-z_$][A-Za-z0-9_$]*)\\s*:/gm, '\"$1\":');\n\n // Remove trailing commas before } or ]\n fixed = fixed.replace(/,\\s*([}\\]])/g, '$1');\n\n return JSON.parse(fixed);\n}\n\n/** A `\"setup\": function` property, which Harlowe appends to its otherwise-JSON format object. */\nconst SETUP_FUNCTION_PROPERTY = /,\\s*\"setup\"\\s*:\\s*function\\b/g;\n\n/** Drop a trailing `\"setup\": function(){…}` property from a format object, if it has one. */\nfunction stripSetupFunction(chunk: string): string | undefined {\n let lastIndex = -1;\n for (const match of chunk.matchAll(SETUP_FUNCTION_PROPERTY)) lastIndex = match.index;\n return lastIndex === -1 ? undefined : chunk.slice(0, lastIndex) + '}';\n}\n\n/**\n * Parse the Twine 2 format.js JSON chunk.\n * Handles Harlowe's malformed JSON by stripping the \"setup\" function property. The workaround\n * keys on the property itself, so the same bytes parse whether they come from a `harlowe-3`\n * directory or a direct download.\n * Per spec, the name key is Optional.\n *\n * @param _formatId No longer used; kept so existing callers keep compiling.\n */\nexport function parseFormatJSON(source: string, _formatId?: string): Twine2FormatJSON | null {\n const first = source.indexOf('{');\n const last = source.lastIndexOf('}');\n if (first === -1 || last === -1) return null;\n\n const chunk = source.slice(first, last + 1);\n\n const parse = (json: string): Twine2FormatJSON | null => {\n const raw: unknown = relaxedJSONParse(json);\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) return null;\n const obj = raw as Record<string, unknown>;\n // version and source are required; name is optional per spec\n if (typeof obj.version !== 'string' || typeof obj.source !== 'string') return null;\n // Validate version is semver\n if (!parseSemver(obj.version)) return null;\n const name = typeof obj.name === 'string' ? obj.name : 'Untitled Story Format';\n const result: Twine2FormatJSON = {\n name,\n version: obj.version,\n source: obj.source,\n proofing: obj.proofing === true,\n };\n if (typeof obj.author === 'string') result.author = obj.author;\n if (typeof obj.description === 'string') result.description = obj.description;\n if (typeof obj.image === 'string') result.image = obj.image;\n if (typeof obj.url === 'string') result.url = obj.url;\n if (typeof obj.license === 'string') result.license = obj.license;\n return result;\n };\n\n try {\n return parse(chunk);\n } catch {\n // Harlowe workaround: strip the \"setup\" function property\n const stripped = stripSetupFunction(chunk);\n if (stripped === undefined) return null;\n try {\n return parse(stripped);\n } catch {\n return null;\n }\n }\n}\n\n/**\n * Discover all story formats in the given search directories.\n * Implements SemVer-based version pruning: within each (name, major) group,\n * only the highest minor.patch survives.\n */\nexport function discoverFormats(searchDirs: string[]): Map<string, StoryFormatInfo> {\n const formats = new Map<string, StoryFormatInfo>();\n const baseFilenames = ['format.js', 'header.html'];\n\n for (const searchDir of searchDirs) {\n try {\n const stat = statSync(searchDir);\n if (!stat.isDirectory()) continue;\n } catch {\n continue;\n }\n\n let entries;\n try {\n entries = readdirSync(searchDir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const formatDir = join(searchDir, entry);\n try {\n if (!statSync(formatDir).isDirectory()) continue;\n } catch {\n continue;\n }\n\n for (const baseFilename of baseFilenames) {\n const formatFilename = join(formatDir, baseFilename);\n try {\n const stat = statSync(formatFilename);\n if (!stat.isFile()) continue;\n } catch {\n continue;\n }\n\n const isTwine2 = baseFilename === 'format.js';\n const format: StoryFormatInfo = {\n id: entry,\n filename: formatFilename,\n isTwine2,\n name: '',\n version: '',\n proofing: false,\n };\n\n if (isTwine2) {\n try {\n const source = readUTF8(formatFilename);\n const data = parseFormatJSON(source, entry);\n if (!data) continue;\n format.name = data.name;\n format.version = data.version;\n format.proofing = data.proofing ?? false;\n if (data.author) format.author = data.author;\n if (data.description) format.description = data.description;\n if (data.image) format.image = data.image;\n if (data.url) format.url = data.url;\n if (data.license) format.license = data.license;\n } catch {\n continue;\n }\n } else {\n // Twine 1 format: use folder name as default name\n format.name = entry;\n }\n\n formats.set(entry, format);\n break; // Found format file for this directory\n }\n }\n }\n\n // SemVer pruning: for formats with the same name, within each major version\n // keep only the highest minor.patch. Also, same name+version from different\n // directories: keep the first one found.\n pruneFormats(formats);\n\n return formats;\n}\n\n/**\n * Prune formats by SemVer: within each (name, major) group,\n * keep only the highest version. First-found wins for same name+version.\n */\nfunction pruneFormats(formats: Map<string, StoryFormatInfo>): void {\n // Group by (name, major) -> best entry\n const bestByNameMajor = new Map<string, { id: string; version: [number, number, number] }>();\n // Track seen name+version combos (first wins)\n const seenNameVersion = new Set<string>();\n\n for (const [id, f] of formats) {\n if (!f.isTwine2 || !f.name || !f.version) continue;\n const v = parseSemver(f.version);\n if (!v) continue;\n\n const nameVersionKey = `${f.name}@${f.version}`;\n if (seenNameVersion.has(nameVersionKey)) {\n // Duplicate name+version: remove the later one\n formats.delete(id);\n continue;\n }\n seenNameVersion.add(nameVersionKey);\n\n const groupKey = `${f.name}@${v[0]}`;\n const existing = bestByNameMajor.get(groupKey);\n if (!existing || semverCompare(v, existing.version) > 0) {\n bestByNameMajor.set(groupKey, { id, version: v });\n }\n }\n\n // Remove all non-best entries within each group\n for (const [id, f] of [...formats]) {\n if (!f.isTwine2 || !f.name || !f.version) continue;\n const v = parseSemver(f.version);\n if (!v) continue;\n\n const groupKey = `${f.name}@${v[0]}`;\n const best = bestByNameMajor.get(groupKey);\n if (best && best.id !== id) {\n formats.delete(id);\n }\n }\n}\n\n/**\n * Get the default format search directories.\n */\nexport function getFormatSearchDirs(extraPaths: string[] = [], useTweegoPath = true): string[] {\n const subdirNames = ['storyformats', '.storyformats', 'story-formats', 'storyFormats', 'targets'];\n const basePaths = new Set<string>();\n\n // Home directory\n try {\n basePaths.add(homedir());\n } catch {\n // ignore\n }\n\n // Working directory\n basePaths.add(process.cwd());\n\n const dirs: string[] = [];\n for (const base of basePaths) {\n for (const sub of subdirNames) {\n const dir = join(base, sub);\n try {\n if (statSync(dir).isDirectory()) {\n dirs.push(dir);\n }\n } catch {\n // skip\n }\n }\n }\n\n // Extra user-provided paths\n dirs.push(...extraPaths);\n\n // TWEEGO_PATH environment variable\n if (useTweegoPath) {\n const tweegoPath = process.env.TWEEGO_PATH;\n if (tweegoPath) {\n dirs.push(...tweegoPath.split(process.platform === 'win32' ? ';' : ':'));\n }\n }\n\n return dirs;\n}\n\n/** Parse a simple semver string into [major, minor, patch]. */\nexport function parseSemver(v: string): [number, number, number] | null {\n const m = /^(\\d+)\\.(\\d+)\\.(\\d+)/.exec(v);\n if (!m) return null;\n return [Number(m[1]), Number(m[2]), Number(m[3])];\n}\n\nexport function semverCompare(a: [number, number, number], b: [number, number, number]): number {\n const [aMajor, aMinor, aPatch] = a;\n const [bMajor, bMinor, bPatch] = b;\n if (aMajor !== bMajor) return aMajor - bMajor;\n if (aMinor !== bMinor) return aMinor - bMinor;\n if (aPatch !== bPatch) return aPatch - bPatch;\n return 0;\n}\n\n/** Build a directory-style format ID from a name and version, e.g. ('SugarCube', '2.37.3') → 'sugarcube-2'. */\nexport function makeFormatId(name: string, version: string): string {\n const major = parseSemver(version)?.[0] ?? 0;\n return `${name.toLowerCase().replace(/\\s+/g, '-')}-${major}`;\n}\n\n/** Describe a format request for diagnostics. */\nexport function describeFormatRequest(request: FormatRequest): string {\n switch (request.kind) {\n case 'id':\n return `\"${request.id}\"`;\n case 'name':\n return request.version ? `\"${request.name}\" at version \"${request.version}\"` : `\"${request.name}\"`;\n default: {\n const _exhaustive: never = request;\n throw new Error(`unhandled format request: ${JSON.stringify(_exhaustive)}`);\n }\n }\n}\n\n/** Options for {@link selectFormatCandidate}. */\nexport interface SelectFormatOptions {\n /** For a name request, also accept a version older than the one asked for (same major only). */\n readonly allowOlder?: boolean;\n}\n\n/**\n * Pick the candidate that best answers a format request.\n *\n * - An ID request ('sugarcube-2') matches a candidate whose name and major version build that ID,\n * and takes the greatest such version.\n * - A name request matches the name case-insensitively. An exact version wins outright; otherwise\n * the greatest version with the same major that is not older than the one asked for (or, with\n * `allowOlder`, the greatest same-major version). An unparseable requested version takes the\n * greatest version of any major.\n */\nexport function selectFormatCandidate<T>(\n request: FormatRequest,\n candidates: readonly T[],\n describe: (candidate: T) => { readonly name: string; readonly version: string },\n options: SelectFormatOptions = {},\n): T | undefined {\n const allowOlder = options.allowOlder ?? false;\n const wanted = request.kind === 'name' ? parseSemver(request.version) : null;\n let best: { readonly candidate: T; readonly version: [number, number, number] } | undefined;\n\n for (const candidate of candidates) {\n const { name, version } = describe(candidate);\n const have = parseSemver(version);\n if (!have) continue;\n\n if (request.kind === 'id') {\n if (makeFormatId(name, version) !== request.id.toLowerCase()) continue;\n } else {\n if (name.toLowerCase() !== request.name.toLowerCase()) continue;\n if (wanted) {\n if (semverCompare(have, wanted) === 0) return candidate;\n if (have[0] !== wanted[0]) continue;\n if (!allowOlder && semverCompare(have, wanted) < 0) continue;\n }\n }\n\n if (!best || semverCompare(have, best.version) > 0) best = { candidate, version: have };\n }\n\n return best?.candidate;\n}\n\n/** Get format ID from Twine 2 name, picking the greatest version. */\nexport function getFormatIdByName(formats: Map<string, StoryFormatInfo>, name: string): string | undefined {\n let bestVersion: [number, number, number] | null = null;\n let bestId: string | undefined;\n\n for (const [id, f] of formats) {\n if (!f.isTwine2 || f.name !== name) continue;\n const v = parseSemver(f.version);\n if (!v) continue;\n if (!bestVersion || semverCompare(v, bestVersion) > 0) {\n bestVersion = v;\n bestId = id;\n }\n }\n\n return bestId;\n}\n\n/** Get format ID from Twine 2 name and version, using SemVer major matching. */\nexport function getFormatIdByNameAndVersion(\n formats: Map<string, StoryFormatInfo>,\n name: string,\n version: string,\n): string | undefined {\n const wanted = parseSemver(version);\n let bestVersion: [number, number, number] | null = null;\n let bestId: string | undefined;\n\n for (const [id, f] of formats) {\n if (!f.isTwine2 || f.name !== name) continue;\n const have = parseSemver(f.version);\n if (!have) continue;\n\n if (wanted === null || (have[0] === wanted[0] && semverCompare(have, wanted) >= 0)) {\n if (!bestVersion || semverCompare(have, bestVersion) > 0) {\n bestVersion = have;\n bestId = id;\n }\n }\n }\n\n return bestId;\n}\n\n/** Read the story format source (for Twine 2, extract the `source` property from JSON). */\nexport function readFormatSource(format: StoryFormatInfo): string {\n const source = readUTF8(format.filename);\n if (format.isTwine2) {\n const data = parseFormatJSON(source, format.id);\n if (!data) throw new Error(`Cannot parse format ${format.id} JSON`);\n return data.source;\n }\n return source;\n}\n\n/** Read a file as UTF-8 (re-exported for loader use). */\nexport { readUTF8 as readFileUTF8 } from './util.js';\n","/**\n * Remote story format fetching, caching, and checksum verification.\n * Uses the Story Formats Archive (SFA) as the default source.\n */\nimport { mkdirSync, readFileSync, writeFileSync, existsSync, readdirSync, statSync, rmSync, lstatSync } from 'node:fs';\nimport { isAbsolute, join, relative, resolve, sep } from 'node:path';\nimport { homedir } from 'node:os';\nimport type { FormatRequest, SFAIndex, SFAIndexEntry, StoryFormatInfo } from './types.js';\nimport { parseSemver, parseFormatJSON, makeFormatId, selectFormatCandidate } from './formats.js';\nimport type { SelectFormatOptions } from './formats.js';\n\nconst DEFAULT_SFA_INDICES = [\n 'https://videlais.github.io/story-formats-archive/official/index.json',\n 'https://videlais.github.io/story-formats-archive/unofficial/index.json',\n];\n\n/** Get the cache directory for downloaded story formats. */\nexport function getCacheDir(): string {\n const xdg = process.env['XDG_CACHE_HOME'];\n const base = xdg || join(homedir(), '.cache');\n return join(base, 'twee-ts', 'storyformats');\n}\n\n/**\n * Whether a string can serve as one directory name inside the cache: not empty, not `.` or `..`,\n * and free of path separators. Format names and versions come from downloaded metadata, so they\n * are untrusted path input.\n */\nfunction isSafeSegment(segment: string): boolean {\n return segment !== '' && segment !== '.' && segment !== '..' && !/[/\\\\\\0]/.test(segment);\n}\n\n/** Whether absolute path `target` lies strictly inside absolute path `root`. */\nfunction isInside(root: string, target: string): boolean {\n const rel = relative(root, target);\n return rel !== '' && !isAbsolute(rel) && rel.split(sep)[0] !== '..';\n}\n\n/** The cache directory for one format version. Throws when the name or version could leave the cache. */\nfunction cachedFormatDir(name: string, version: string): string {\n if (!isSafeSegment(name)) {\n throw new Error(`Refusing to cache a story format with an unsafe name: ${JSON.stringify(name)}`);\n }\n if (!isSafeSegment(version) || !parseSemver(version)) {\n throw new Error(`Refusing to cache story format \"${name}\" with an unsafe version: ${JSON.stringify(version)}`);\n }\n const root = resolve(getCacheDir());\n const dir = resolve(root, name, version);\n if (!isInside(root, dir)) {\n throw new Error(`Refusing to cache a story format outside the cache directory ${root}: ${dir}`);\n }\n return dir;\n}\n\n/** Create `dir` as a plain directory, or check that it already is one (a symlink could lead out of the cache). */\nfunction ensurePlainDirectory(dir: string): void {\n const stat = lstatSync(dir, { throwIfNoEntry: false });\n if (stat === undefined) {\n mkdirSync(dir);\n return;\n }\n if (stat.isSymbolicLink() || !stat.isDirectory()) {\n throw new Error(`Refusing to write a story format outside the cache directory: ${dir} is not a plain directory`);\n }\n}\n\n/** Write a downloaded format.js to `<cache>/<name>/<version>/format.js` and return its path. */\nfunction writeCachedFormat(name: string, version: string, text: string): string {\n const dir = cachedFormatDir(name, version);\n const root = resolve(getCacheDir());\n mkdirSync(root, { recursive: true });\n ensurePlainDirectory(join(root, name));\n ensurePlainDirectory(dir);\n\n const formatPath = join(dir, 'format.js');\n if (lstatSync(formatPath, { throwIfNoEntry: false })?.isSymbolicLink()) {\n throw new Error(`Refusing to write a story format outside the cache directory: ${formatPath} is a symlink`);\n }\n writeFileSync(formatPath, text, 'utf-8');\n return formatPath;\n}\n\n/** In-memory index cache, keyed by URL. Cleared each compile. */\nconst indexCache = new Map<string, SFAIndex>();\n\n/** Clear the in-memory index cache. */\nexport function clearIndexCache(): void {\n indexCache.clear();\n}\n\n/** Validate that a JSON value is a valid SFAIndexEntry. */\nfunction isValidEntry(val: unknown): val is SFAIndexEntry {\n if (typeof val !== 'object' || val === null || Array.isArray(val)) return false;\n const obj = val as Record<string, unknown>;\n return (\n typeof obj.name === 'string' &&\n typeof obj.version === 'string' &&\n typeof obj.checksums === 'object' &&\n obj.checksums !== null &&\n !Array.isArray(obj.checksums)\n );\n}\n\n/** Validate that a JSON value conforms to the SFAIndex shape. */\nfunction validateSFAIndex(json: unknown): SFAIndex {\n if (typeof json !== 'object' || json === null) {\n throw new Error('SFA index is not an object');\n }\n const obj = json as Record<string, unknown>;\n const twine1 = Array.isArray(obj['twine1']) ? (obj['twine1'] as unknown[]).filter(isValidEntry) : [];\n const twine2 = Array.isArray(obj['twine2']) ? (obj['twine2'] as unknown[]).filter(isValidEntry) : [];\n return { twine1, twine2 };\n}\n\n/** Fetch and parse an SFA index.json, with in-memory caching. */\nexport async function fetchIndex(url: string): Promise<SFAIndex> {\n const cached = indexCache.get(url);\n if (cached) return cached;\n\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`Failed to fetch format index from ${url}: ${res.status} ${res.statusText}`);\n }\n const data = validateSFAIndex(await res.json());\n indexCache.set(url, data);\n return data;\n}\n\ninterface FindEntryResult {\n entry: SFAIndexEntry;\n formatType: 'twine1' | 'twine2';\n}\n\n/**\n * Find the best matching entry in an SFA index.\n * Exact version preferred, then highest version with same major.\n */\nexport function findEntry(index: SFAIndex, name: string, version: string): FindEntryResult | undefined {\n return findEntryForRequest(index, { kind: 'name', name, version });\n}\n\n/** Find the best matching entry in an SFA index for a name or ID request (twine2 entries first). */\nfunction findEntryForRequest(index: SFAIndex, request: FormatRequest): FindEntryResult | undefined {\n const candidates: FindEntryResult[] = [\n ...(index.twine2 ?? []).map((entry) => ({ entry, formatType: 'twine2' as const })),\n ...(index.twine1 ?? []).map((entry) => ({ entry, formatType: 'twine1' as const })),\n ];\n return selectFormatCandidate(request, candidates, (c) => c.entry);\n}\n\n/** Verify SHA-256 checksum using Web Crypto API (Node 22 built-in). */\nexport async function verifySHA256(content: Uint8Array<ArrayBuffer>, expectedHex: string): Promise<boolean> {\n const digest = await crypto.subtle.digest('SHA-256', content);\n const hex = Array.from(new Uint8Array(digest))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n return hex === expectedHex.toLowerCase();\n}\n\n/** Derive the download URL for a format.js from the index URL and entry. */\nfunction getDownloadUrl(indexUrl: string, entry: SFAIndexEntry, formatType: 'twine1' | 'twine2'): string {\n const base = indexUrl.replace(/\\/index\\.json$/, '');\n return `${base}/${formatType}/${entry.name}/${entry.version}/format.js`;\n}\n\n/** Download a format, verify its checksum, write to cache, and return StoryFormatInfo. */\nexport async function fetchAndCacheFormat(entry: SFAIndexEntry, downloadUrl: string): Promise<StoryFormatInfo> {\n // Index metadata is untrusted: reject a name or version that would leave the cache before downloading.\n cachedFormatDir(entry.name, entry.version);\n\n const res = await fetch(downloadUrl);\n if (!res.ok) {\n throw new Error(`Failed to download format from ${downloadUrl}: ${res.status} ${res.statusText}`);\n }\n const text = await res.text();\n\n // Verify checksum if available\n const checksumKey = Object.keys(entry.checksums ?? {}).find((k) => k.endsWith('format.js'));\n if (checksumKey) {\n const expected = entry.checksums[checksumKey];\n if (!expected) throw new Error(`Missing checksum value for key \"${checksumKey}\"`);\n const encoder = new TextEncoder();\n const valid = await verifySHA256(encoder.encode(text), expected);\n if (!valid) {\n throw new Error(`Checksum verification failed for ${entry.name} ${entry.version}`);\n }\n }\n\n // Parse format JSON to extract name/version/source\n const id = makeFormatId(entry.name, entry.version);\n const data = parseFormatJSON(text, id);\n if (!data) {\n throw new Error(`Failed to parse format JSON from ${downloadUrl}`);\n }\n\n const formatPath = writeCachedFormat(entry.name, entry.version, text);\n\n return {\n id,\n filename: formatPath,\n isTwine2: true,\n name: data.name,\n version: data.version,\n proofing: data.proofing ?? false,\n };\n}\n\n/** Download a direct format.js URL, parse its JSON, cache it, and return StoryFormatInfo. */\nexport async function fetchDirectFormat(url: string): Promise<StoryFormatInfo> {\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`Failed to download format from ${url}: ${res.status} ${res.statusText}`);\n }\n const text = await res.text();\n\n const data = parseFormatJSON(text);\n if (!data) {\n throw new Error(`Failed to parse format JSON from ${url}`);\n }\n\n const id = makeFormatId(data.name, data.version);\n const formatPath = writeCachedFormat(data.name, data.version, text);\n\n return {\n id,\n filename: formatPath,\n isTwine2: true,\n name: data.name,\n version: data.version,\n proofing: data.proofing ?? false,\n };\n}\n\n/**\n * Try to resolve a remote story format by name and version.\n * 0. Use an exactly matching cached download, without touching the network\n * 1. Try direct format URLs\n * 2. Try custom index URLs\n * 3. Try default SFA indices\n * 4. Fall back to a compatible cached download (e.g. when offline)\n */\nexport async function resolveRemoteFormat(\n name: string,\n version: string,\n indices?: string[],\n urls?: string[],\n): Promise<StoryFormatInfo | undefined> {\n return resolveRemoteFormatRequest({ kind: 'name', name, version }, indices, urls);\n}\n\n/**\n * Resolve a story format request remotely, in the same order as {@link resolveRemoteFormat}.\n * An ID request such as 'sugarcube-2' matches the format whose name and major version build that ID\n * (SugarCube 2.x), taking the greatest version available.\n */\nexport async function resolveRemoteFormatRequest(\n request: FormatRequest,\n indices?: string[],\n urls?: string[],\n): Promise<StoryFormatInfo | undefined> {\n let lastError: Error | undefined;\n\n // 0. An exact version already downloaded needs no network access.\n const cached = findCachedFormat(request);\n if (cached && request.kind === 'name' && isExactVersion(cached.version, request.version)) return cached;\n\n // 1. Try direct URLs — use the first that answers the request\n for (const url of urls ?? []) {\n try {\n const info = await fetchDirectFormat(url);\n if (selectFormatCandidate(request, [info], (f) => f)) return info;\n } catch (e) {\n lastError = e instanceof Error ? e : new Error(String(e));\n }\n }\n\n // 2. Try custom indices, then default SFA indices\n const allIndices = [...(indices ?? []), ...DEFAULT_SFA_INDICES];\n for (const indexUrl of allIndices) {\n try {\n const index = await fetchIndex(indexUrl);\n const result = findEntryForRequest(index, request);\n if (result) {\n // Check cache first\n const hit = getCachedFormat(result.entry.name, result.entry.version);\n if (hit) return hit;\n\n const downloadUrl = getDownloadUrl(indexUrl, result.entry, result.formatType);\n return await fetchAndCacheFormat(result.entry, downloadUrl);\n }\n } catch (e) {\n lastError = e instanceof Error ? e : new Error(String(e));\n }\n }\n\n // 3. No source had it (or none could be reached): a compatible cached download still answers the request.\n if (cached) return cached;\n\n // If all sources failed with errors, propagate the last one\n if (lastError) throw lastError;\n return undefined;\n}\n\n/** Whether two version strings name the same SemVer version. */\nfunction isExactVersion(have: string, wanted: string): boolean {\n const a = parseSemver(have);\n const b = parseSemver(wanted);\n return a !== null && b !== null && a[0] === b[0] && a[1] === b[1] && a[2] === b[2];\n}\n\n/**\n * Find the cached download that best answers a format request, without network access.\n * Matching follows {@link selectFormatCandidate}.\n */\nexport function findCachedFormat(\n request: FormatRequest,\n options: SelectFormatOptions = {},\n): StoryFormatInfo | undefined {\n return selectFormatCandidate(request, [...discoverCachedFormats().values()], (f) => f, options);\n}\n\n/** Check if a format is already in the local cache. */\nfunction getCachedFormat(name: string, version: string): StoryFormatInfo | undefined {\n if (!isSafeSegment(name) || !isSafeSegment(version)) return undefined;\n const formatPath = join(getCacheDir(), name, version, 'format.js');\n try {\n if (!existsSync(formatPath)) return undefined;\n const source = readFileSync(formatPath, 'utf-8');\n const id = makeFormatId(name, version);\n const data = parseFormatJSON(source, id);\n if (!data) return undefined;\n return {\n id,\n filename: formatPath,\n isTwine2: true,\n name: data.name,\n version: data.version,\n proofing: data.proofing ?? false,\n };\n } catch {\n return undefined;\n }\n}\n\n/** Discover all cached remote formats. Returns a Map like discoverFormats(). */\nexport function discoverCachedFormats(): Map<string, StoryFormatInfo> {\n const formats = new Map<string, StoryFormatInfo>();\n const cacheDir = getCacheDir();\n\n try {\n if (!existsSync(cacheDir)) return formats;\n } catch {\n return formats;\n }\n\n let names: string[];\n try {\n names = readdirSync(cacheDir);\n } catch {\n return formats;\n }\n\n for (const name of names) {\n const nameDir = join(cacheDir, name);\n try {\n if (!statSync(nameDir).isDirectory()) continue;\n } catch {\n continue;\n }\n\n let versions: string[];\n try {\n versions = readdirSync(nameDir);\n } catch {\n continue;\n }\n\n for (const version of versions) {\n const info = getCachedFormat(name, version);\n if (info) {\n formats.set(`${info.id}-${version}`, info);\n }\n }\n }\n\n return formats;\n}\n\n/** Info about a cached format entry with size and modification date. */\nexport interface CachedFormatEntry {\n readonly name: string;\n readonly version: string;\n readonly sizeBytes: number;\n readonly modifiedAt: Date;\n}\n\n/** List all cached formats with size and modification date. */\nexport function listCachedFormats(): readonly CachedFormatEntry[] {\n const cacheDir = getCacheDir();\n const entries: CachedFormatEntry[] = [];\n\n try {\n if (!existsSync(cacheDir)) return entries;\n } catch {\n return entries;\n }\n\n let names: string[];\n try {\n names = readdirSync(cacheDir);\n } catch {\n return entries;\n }\n\n for (const name of names) {\n const nameDir = join(cacheDir, name);\n try {\n if (!statSync(nameDir).isDirectory()) continue;\n } catch {\n continue;\n }\n\n let versions: string[];\n try {\n versions = readdirSync(nameDir);\n } catch {\n continue;\n }\n\n for (const version of versions) {\n const formatPath = join(nameDir, version, 'format.js');\n try {\n const stat = statSync(formatPath);\n entries.push({\n name,\n version,\n sizeBytes: stat.size,\n modifiedAt: stat.mtime,\n });\n } catch {\n // Skip entries without a valid format.js\n }\n }\n }\n\n return entries;\n}\n\n/**\n * Clear all cached formats, or only those matching a given name. Returns the number of entries removed.\n * A name must be a single cache entry name (as `listCachedFormats()` reports it); anything with a\n * path separator or `.`/`..` throws instead of deleting outside the format's own directory.\n */\nexport function clearCachedFormats(name?: string): number {\n if (name && !isSafeSegment(name)) {\n throw new Error(\n `Refusing to clear ${JSON.stringify(name)}: it is not a cached format name. Use a name as \"cache list\" shows it.`,\n );\n }\n\n const cacheDir = getCacheDir();\n if (!existsSync(cacheDir)) return 0;\n\n if (!name) {\n const entries = listCachedFormats();\n const count = entries.length;\n rmSync(cacheDir, { recursive: true, force: true });\n return count;\n }\n\n const root = resolve(cacheDir);\n const nameDir = resolve(root, name);\n if (!isInside(root, nameDir)) {\n throw new Error(`Refusing to clear ${JSON.stringify(name)}: it is not a cached format name.`);\n }\n // lstat, so a symlinked entry is never followed out of the cache: only plain directories are entries.\n if (!lstatSync(nameDir, { throwIfNoEntry: false })?.isDirectory()) return 0;\n\n let versions: string[];\n try {\n versions = readdirSync(nameDir);\n } catch {\n return 0;\n }\n const count = versions.length;\n rmSync(nameDir, { recursive: true, force: true });\n return count;\n}\n\n/** Get total cache size in bytes and format count. */\nexport function getCacheSize(): { totalBytes: number; count: number } {\n const entries = listCachedFormats();\n const totalBytes = entries.reduce((sum, e) => sum + e.sizeBytes, 0);\n return { totalBytes, count: entries.length };\n}\n","/**\n * Story format selection for a compile.\n *\n * The request comes from the explicit `formatId` option, else the StoryData format name and\n * version, else the default ID. That one request is then looked up in the local format\n * directories, the download cache, and (unless disabled) remote sources. A request that none of\n * them can answer is reported as an error rather than swapped for a different story format.\n */\nimport type { Diagnostic, FormatRequest, StoryFormatInfo } from './types.js';\nimport {\n describeFormatRequest,\n discoverFormats,\n getFormatIdByNameAndVersion,\n getFormatSearchDirs,\n selectFormatCandidate,\n} from './formats.js';\nimport { findCachedFormat, resolveRemoteFormatRequest } from './remote-formats.js';\n\n/** Where to look for story formats. */\nexport interface FormatResolutionOptions {\n readonly formatPaths?: string[];\n readonly useTweegoPath?: boolean;\n readonly noRemote?: boolean;\n readonly formatIndices?: string[];\n readonly formatUrls?: string[];\n}\n\n/** Choose the format request: explicit format ID > StoryData format > default ID. */\nexport function formatRequestFor(\n formatId: string | undefined,\n storyFormat: string,\n storyFormatVersion: string,\n defaultId: string,\n): FormatRequest {\n if (formatId) return { kind: 'id', id: formatId };\n if (storyFormat) return { kind: 'name', name: storyFormat, version: storyFormatVersion };\n return { kind: 'id', id: defaultId };\n}\n\n/** Look a request up among the formats found in local format directories. */\nfunction findLocalFormat(formats: Map<string, StoryFormatInfo>, request: FormatRequest): StoryFormatInfo | undefined {\n switch (request.kind) {\n case 'id':\n return formats.get(request.id);\n case 'name': {\n const id = getFormatIdByNameAndVersion(formats, request.name, request.version);\n return id === undefined ? undefined : formats.get(id);\n }\n default: {\n const _exhaustive: never = request;\n throw new Error(`unhandled format request: ${JSON.stringify(_exhaustive)}`);\n }\n }\n}\n\n/**\n * Resolve a format request to a story format.\n *\n * Order: local format directories, then the download cache, then remote sources (unless\n * `noRemote`). When a StoryData request names a version that none of them has, an older version of\n * the same format and major version is used with a warning. Anything else is an error diagnostic,\n * and the result is `undefined`.\n */\nexport async function resolveStoryFormat(\n request: FormatRequest,\n options: FormatResolutionOptions,\n diagnostics: Diagnostic[],\n): Promise<StoryFormatInfo | undefined> {\n const noRemote = options.noRemote ?? false;\n const formats = discoverFormats(getFormatSearchDirs(options.formatPaths, options.useTweegoPath ?? true));\n const wanted = describeFormatRequest(request);\n\n const local = findLocalFormat(formats, request);\n if (local) return local;\n\n const cached = findCachedFormat(request);\n if (cached) return cached;\n\n if (!noRemote) {\n try {\n const remote = await resolveRemoteFormatRequest(request, options.formatIndices, options.formatUrls);\n if (remote) return remote;\n } catch (e) {\n diagnostics.push({\n level: 'warning',\n message: `Remote format fetch failed for ${wanted}: ${e instanceof Error ? e.message : String(e)}`,\n });\n }\n }\n\n // A same-major older version keeps the story in its own format; it never crosses majors.\n if (request.kind === 'name') {\n const older =\n selectFormatCandidate(\n request,\n [...formats.values()].filter((f) => f.isTwine2),\n (f) => f,\n { allowOlder: true },\n ) ?? findCachedFormat(request, { allowOlder: true });\n if (older) {\n diagnostics.push({\n level: 'warning',\n message: `Story format ${wanted} is not available; using ${older.name} ${older.version} instead.`,\n });\n return older;\n }\n }\n\n const reason = noRemote ? ' (remote fetching disabled)' : '';\n diagnostics.push({\n level: 'error',\n message: `Story format ${wanted} is not available${reason}. Found: ${[...formats.keys()].join(', ') || 'none'}`,\n });\n return undefined;\n}\n","/**\n * All public interfaces for twee-ts.\n */\n\n// --- Output modes ---\n\nexport type OutputMode = 'html' | 'twee3' | 'twee1' | 'twine2-archive' | 'twine1-archive' | 'json';\n\n// --- Word count ---\n\nexport type WordCountMethod = 'tweego' | 'whitespace';\n\n// --- Source input ---\n\nexport type InlineSource = { filename: string; content: string | Buffer };\nexport type SourceInput = string | InlineSource;\n\n// --- Compile options ---\n\nexport interface CompileOptions {\n /** Files, directories, or inline sources to compile. */\n sources: SourceInput[];\n /**\n * Glob patterns for files to leave out of `sources`, matched against each file's\n * path relative to the working directory (as `stats.files` lists it). Modules are not affected.\n */\n exclude?: string[];\n /** Output mode. Default: 'html'. */\n outputMode?: OutputMode;\n /** Story format directory ID (e.g. 'sugarcube-2'). */\n formatId?: string;\n /** Name of the starting passage. Default: 'Start'. */\n startPassage?: string;\n /** Extra directories to search for story formats. */\n formatPaths?: string[];\n /** Also search TWEEGO_PATH env for formats. Default: true. */\n useTweegoPath?: boolean;\n /** Module files to inject into <head>. */\n modules?: string[];\n /** Raw HTML file to append to <head>. */\n headFile?: string;\n /** Trim passage whitespace. Default: true. */\n trim?: boolean;\n /** Twee2 compatibility mode. Default: false. */\n twee2Compat?: boolean;\n /** Enable debug/test mode option. Default: false. */\n testMode?: boolean;\n /** URLs to SFA-compatible index.json files for remote format lookup. */\n formatIndices?: string[];\n /** Direct URLs to format.js files. */\n formatUrls?: string[];\n /** Disable remote format fetching. Default: false. */\n noRemote?: boolean;\n /** Map alias tags to canonical special tags (e.g. { library: 'script' }). */\n tagAliases?: Record<string, string>;\n /** Emit source file and line as data- attributes on passage elements. Default: false. */\n sourceInfo?: boolean;\n /** Word counting method. Default: 'tweego'. */\n wordCountMethod?: WordCountMethod;\n}\n\nexport interface CompileToFileOptions extends CompileOptions {\n /** Output file path. */\n outFile: string;\n}\n\nexport interface WatchOptions extends CompileToFileOptions {\n /** Called after each build is written, including one whose diagnostics report errors. */\n onBuild?: (result: CompileResult) => void;\n /** Called when a build fails with a fatal error (nothing is written). */\n onError?: (error: Error) => void;\n}\n\n// --- Compile result ---\n\nexport type Diagnostic =\n | { level: 'warning'; message: string; file?: string; line?: number }\n | { level: 'error'; message: string; file?: string; line?: number; fatal?: boolean };\n\nexport interface CompileResult {\n /** The compiled output string (HTML, Twee, JSON, etc.). */\n output: string;\n /** The parsed story model (read-only after compilation). */\n story: ReadonlyStory;\n /** The format used for compilation (undefined for non-HTML modes). */\n format?: StoryFormatInfo;\n /** Collected diagnostics. */\n diagnostics: Diagnostic[];\n /** Compilation statistics. */\n stats: CompileStats;\n}\n\nexport interface CompileStats {\n passages: number;\n storyPassages: number;\n words: number;\n files: string[];\n}\n\n// --- Passage ---\n\nexport interface SourceLocation {\n readonly file: string;\n readonly line: number;\n}\n\nexport interface PassageMetadata {\n position?: string;\n size?: string;\n [key: string]: string | undefined;\n}\n\nexport interface Passage {\n name: string;\n tags: string[];\n text: string;\n metadata?: PassageMetadata;\n source?: SourceLocation;\n}\n\n// --- Branded types ---\n\nexport type IFID = string & { readonly __brand: 'IFID' };\n\n// --- Story ---\n\nexport interface Twine1Metadata {\n settings: Map<string, string>;\n}\n\nexport interface Twine2Metadata {\n format: string;\n formatVersion: string;\n options: Map<string, boolean>;\n start: string;\n tags: string;\n tagColors: Map<string, string>;\n zoom: number;\n}\n\nexport interface Story {\n name: string;\n ifid: IFID;\n passages: Passage[];\n legacyIFID: IFID;\n twine1: Twine1Metadata;\n twine2: Twine2Metadata;\n}\n\n// --- Readonly story (post-construction) ---\n\nexport type ReadonlyPassage = Readonly<Passage> & {\n readonly tags: readonly string[];\n};\n\nexport type ReadonlyStory = Readonly<Omit<Story, 'passages' | 'twine1' | 'twine2'>> & {\n readonly passages: readonly ReadonlyPassage[];\n readonly twine1: Readonly<Omit<Twine1Metadata, 'settings'>> & {\n readonly settings: ReadonlyMap<string, string>;\n };\n readonly twine2: Readonly<Omit<Twine2Metadata, 'options' | 'tagColors'>> & {\n readonly options: ReadonlyMap<string, boolean>;\n readonly tagColors: ReadonlyMap<string, string>;\n };\n};\n\n// --- Passage omission (why an output leaves a passage out) ---\n\nexport type OmittingTag = 'Twine.private' | 'script' | 'stylesheet';\n\nexport type PassageOmission =\n | { readonly kind: 'special-name'; readonly name: 'StoryData' | 'StoryTitle' }\n | { readonly kind: 'tag'; readonly tag: OmittingTag }\n | { readonly kind: 'empty-story-settings' };\n\n/** The output whose rules decide which passages a story emits as passages. */\nexport type PassageOutputTarget = 'twine1' | 'twine2';\n\n// --- HTML decompile ---\n\nexport interface DecompileOptions {\n /**\n * Trim whitespace at both ends of passage text (and of the Twine 2 story stylesheet and script),\n * as the Twee lexer does. When false, the stored text is kept exactly. Default: true.\n */\n readonly trim?: boolean;\n}\n\n// --- Story inspection ---\n\nexport interface InspectOptions {\n /**\n * Check link destinations against this output's passage rules. A link to a passage that the\n * output leaves out (in Twine 2: `script`, `stylesheet` and `Twine.private` passages,\n * StoryData, StoryTitle and an empty StorySettings; in Twine 1: `Twine.private` passages) is\n * then a broken link, and says why. Without a target, a link is broken only when no passage\n * has its name.\n */\n readonly target?: PassageOutputTarget;\n}\n\n// --- Story format ---\n\nexport interface StoryFormatInfo {\n id: string;\n filename: string;\n isTwine2: boolean;\n name: string;\n version: string;\n proofing: boolean;\n author?: string;\n description?: string;\n image?: string;\n url?: string;\n license?: string;\n}\n\n/**\n * The story format a compile asks for: a directory-style ID (e.g. 'sugarcube-2', which names\n * a format and a major version) or a Twine 2 format name with a version (as StoryData has it).\n */\nexport type FormatRequest =\n | { readonly kind: 'id'; readonly id: string }\n | { readonly kind: 'name'; readonly name: string; readonly version: string };\n\nexport interface Twine2FormatJSON {\n name: string;\n version: string;\n proofing?: boolean;\n source: string;\n author?: string;\n description?: string;\n image?: string;\n url?: string;\n license?: string;\n}\n\n// --- Lexer ---\n\nexport const ItemType = {\n Error: 0,\n EOF: 1,\n Header: 2,\n Name: 3,\n Tags: 4,\n Metadata: 5,\n Content: 6,\n} as const;\nexport type ItemType = (typeof ItemType)[keyof typeof ItemType];\n\nexport interface LexerItem {\n type: ItemType;\n line: number;\n pos: number;\n val: string;\n}\n\n// --- Story Format Archive (SFA) ---\n\nexport interface SFAIndexEntry {\n name: string;\n version: string;\n proofing: boolean;\n files: string[];\n checksums: Record<string, string>;\n}\n\nexport interface SFAIndex {\n twine1: SFAIndexEntry[];\n twine2: SFAIndexEntry[];\n}\n\n// --- Incremental compilation cache ---\n\nexport interface FileCacheEntry {\n readonly mtimeMs: number;\n /**\n * Identity of the parse options (`trim`, `twee2Compat`) the entry was parsed with. An entry is\n * reused only when this matches the current options; an entry without it is treated as stale\n * and reparsed. The value is opaque: leave it to twee-ts to set.\n */\n readonly parseOptionsKey?: string;\n readonly passages: readonly Passage[];\n readonly diagnostics: readonly Diagnostic[];\n}\n\n// --- Config file ---\n\nexport interface TweeTsConfig {\n sources?: string[];\n exclude?: string[];\n output?: string;\n outputMode?: OutputMode;\n formatId?: string;\n startPassage?: string;\n formatPaths?: string[];\n formatIndices?: string[];\n formatUrls?: string[];\n useTweegoPath?: boolean;\n modules?: string[];\n headFile?: string;\n trim?: boolean;\n twee2Compat?: boolean;\n testMode?: boolean;\n noRemote?: boolean;\n tagAliases?: Record<string, string>;\n sourceInfo?: boolean;\n wordCountMethod?: WordCountMethod;\n}\n","/**\n * Twee 3 state-machine lexer implemented as a synchronous generator.\n * Ported from tweelexer.go — Go channels become `yield`.\n */\nimport type { LexerItem } from './types.js';\nimport { ItemType } from './types.js';\n\nconst EOF = -1;\nconst HEADER_DELIM = '::';\nconst NEWLINE_HEADER_DELIM = '\\n::';\n\ntype StateFn = ((ctx: LexerContext) => StateFn | null) | null;\n\nclass LexerContext {\n readonly input: string;\n line = 1;\n start = 0;\n pos = 0;\n private items: LexerItem[] = [];\n\n constructor(input: string) {\n this.input = input;\n }\n\n next(): number {\n if (this.pos >= this.input.length) return EOF;\n const ch = this.input.charCodeAt(this.pos);\n this.pos++;\n if (ch === 0x0a) this.line++;\n return ch;\n }\n\n peek(): number {\n if (this.pos >= this.input.length) return EOF;\n return this.input.charCodeAt(this.pos);\n }\n\n backup(): void {\n if (this.pos > this.start) {\n this.pos--;\n if (this.input.charCodeAt(this.pos) === 0x0a) this.line--;\n } else {\n throw new Error('backup would leave pos < start');\n }\n }\n\n // Line-counting invariant: next() increments this.line for each newline during\n // character-by-character scanning. However, Content items are produced by jumping\n // this.pos directly (e.g. via indexOf) without calling next(), so those newlines\n // haven't been counted yet. emit() re-counts newlines in [start, pos) for Content\n // items to compensate. This is safe because this.start is reset to this.pos after\n // every emit(), so no range is ever counted twice.\n emit(type: ItemType): void {\n const val = this.input.slice(this.start, this.pos);\n this.items.push({ type, line: this.line, pos: this.start, val });\n if (type === ItemType.Content) {\n for (let i = this.start; i < this.pos; i++) {\n if (this.input.charCodeAt(i) === 0x0a) this.line++;\n }\n }\n this.start = this.pos;\n }\n\n ignore(): void {\n for (let i = this.start; i < this.pos; i++) {\n if (this.input.charCodeAt(i) === 0x0a) this.line++;\n }\n this.start = this.pos;\n }\n\n acceptRun(valid: string): void {\n let ch: number;\n for (ch = this.next(); ch !== EOF && valid.includes(String.fromCharCode(ch)); ch = this.next()) {\n // consume\n }\n if (ch !== EOF) this.backup();\n }\n\n errorf(message: string): null {\n this.items.push({\n type: ItemType.Error,\n line: this.line,\n pos: this.start,\n val: message,\n });\n return null;\n }\n\n /** Drain all pending items and return them. */\n drainItems(): LexerItem[] {\n const result = this.items;\n this.items = [];\n return result;\n }\n}\n\nfunction acceptQuoted(ctx: LexerContext, quote: number): string | null {\n for (;;) {\n const ch = ctx.next();\n switch (ch) {\n case 0x5c: {\n // backslash\n const r = ctx.next();\n if (r !== 0x0a && r !== EOF) break;\n // fall through\n }\n // falls through\n case 0x0a:\n case EOF:\n return 'unterminated quoted string';\n default:\n if (ch === quote) return null;\n break;\n }\n }\n}\n\n// --- State functions ---\n\nfunction lexProlog(ctx: LexerContext): StateFn {\n if (ctx.input.startsWith(HEADER_DELIM, ctx.pos)) {\n return lexHeaderDelim;\n }\n const i = ctx.input.indexOf(NEWLINE_HEADER_DELIM, ctx.pos);\n if (i > -1) {\n ctx.pos = i + 1; // skip to the newline, then past it\n ctx.ignore();\n return lexHeaderDelim;\n }\n ctx.emit(ItemType.EOF);\n return null;\n}\n\nfunction lexContent(ctx: LexerContext): StateFn {\n if (ctx.input.startsWith(HEADER_DELIM, ctx.pos)) {\n return lexHeaderDelim;\n }\n const i = ctx.input.indexOf(NEWLINE_HEADER_DELIM, ctx.pos);\n if (i > -1) {\n ctx.pos = i + 1;\n ctx.emit(ItemType.Content);\n return lexHeaderDelim;\n }\n ctx.pos = ctx.input.length;\n if (ctx.pos > ctx.start) {\n ctx.emit(ItemType.Content);\n }\n ctx.emit(ItemType.EOF);\n return null;\n}\n\nfunction lexHeaderDelim(ctx: LexerContext): StateFn {\n ctx.pos += HEADER_DELIM.length;\n ctx.emit(ItemType.Header);\n return lexName;\n}\n\nfunction lexName(ctx: LexerContext): StateFn {\n let r: number;\n outer: for (;;) {\n r = ctx.next();\n switch (r) {\n case 0x5c: {\n // backslash\n const next = ctx.next();\n if (next !== 0x0a && next !== EOF) break;\n // fall through to terminators\n r = next;\n }\n // falls through\n case 0x5b: // [\n case 0x5d: // ]\n case 0x7b: // {\n case 0x7d: // }\n case 0x0a: // \\n\n case EOF:\n if (r !== EOF) ctx.backup();\n break outer;\n }\n }\n // Always emit a name item, even if empty.\n ctx.emit(ItemType.Name);\n\n switch (r) {\n case 0x5b:\n return lexTags; // [\n case 0x5d:\n return ctx.errorf(`unexpected right square bracket ']'`);\n case 0x7b:\n return lexMetadata; // {\n case 0x7d:\n return ctx.errorf(`unexpected right curly brace '}'`);\n case 0x0a: // newline\n ctx.pos++;\n ctx.ignore();\n return lexContent;\n }\n ctx.emit(ItemType.EOF);\n return null;\n}\n\nfunction lexNextOptionalBlock(ctx: LexerContext): StateFn {\n // Consume whitespace.\n ctx.acceptRun(' \\t');\n ctx.ignore();\n\n const r = ctx.peek();\n switch (r) {\n case 0x5b:\n return lexTags; // [\n case 0x5d:\n return ctx.errorf(`unexpected right square bracket ']'`);\n case 0x7b:\n return lexMetadata; // {\n case 0x7d:\n return ctx.errorf(`unexpected right curly brace '}'`);\n case 0x0a: // newline\n ctx.pos++;\n ctx.ignore();\n return lexContent;\n case EOF:\n ctx.emit(ItemType.EOF);\n return null;\n }\n return ctx.errorf(`illegal character '${String.fromCharCode(r)}' amid the optional blocks`);\n}\n\nfunction lexTags(ctx: LexerContext): StateFn {\n // Consume the left delimiter '['.\n ctx.pos++;\n\n for (;;) {\n const r = ctx.next();\n switch (r) {\n case 0x5c: {\n // backslash\n const next = ctx.next();\n if (next !== 0x0a && next !== EOF) break;\n // fall through\n }\n // falls through\n case 0x0a:\n case EOF:\n if (r === 0x0a) ctx.backup();\n return ctx.errorf('unterminated tag block');\n case 0x5d: // ]\n if (ctx.pos > ctx.start) ctx.emit(ItemType.Tags);\n return lexNextOptionalBlock;\n case 0x5b: // [\n return ctx.errorf(`unexpected left square bracket '['`);\n case 0x7b: // {\n return ctx.errorf(`unexpected left curly brace '{'`);\n case 0x7d: // }\n return ctx.errorf(`unexpected right curly brace '}'`);\n }\n }\n}\n\nfunction lexMetadata(ctx: LexerContext): StateFn {\n // Consume the left delimiter '{'.\n ctx.pos++;\n\n let depth = 1;\n for (;;) {\n const r = ctx.next();\n switch (r) {\n case 0x22: {\n // double quote\n const err = acceptQuoted(ctx, 0x22);\n if (err) return ctx.errorf(err);\n break;\n }\n case 0x0a: // newline\n ctx.backup();\n // falls through\n case EOF:\n return ctx.errorf('unterminated metadata block');\n case 0x7b: // {\n depth++;\n break;\n case 0x7d: // }\n depth--;\n if (depth === 0) {\n if (ctx.pos > ctx.start) ctx.emit(ItemType.Metadata);\n return lexNextOptionalBlock;\n }\n break;\n }\n }\n}\n\n/**\n * Twee 3 lexer — yields LexerItem tokens from Twee source text.\n *\n * In the Go reference, this uses goroutines and channels.\n * Here we use a synchronous generator that accumulates items per state step.\n */\nexport function* tweeLexer(input: string): Generator<LexerItem, void, undefined> {\n const ctx = new LexerContext(input);\n let state: StateFn = lexProlog;\n while (state !== null) {\n state = state(ctx);\n const items = ctx.drainItems();\n for (const item of items) {\n yield item;\n }\n }\n // Drain any remaining items.\n const remaining = ctx.drainItems();\n for (const item of remaining) {\n yield item;\n }\n}\n\n/** Convenience class wrapper for the lexer generator. */\nexport class TweeLexer {\n private gen: Generator<LexerItem, void, undefined>;\n\n constructor(input: string) {\n this.gen = tweeLexer(input);\n }\n\n nextItem(): { item: LexerItem; done: boolean } {\n const result = this.gen.next();\n if (result.done) {\n return { item: { type: ItemType.EOF, line: 0, pos: 0, val: '' }, done: true };\n }\n return { item: result.value, done: false };\n }\n\n *[Symbol.iterator](): Generator<LexerItem, void, undefined> {\n yield* this.gen;\n }\n}\n","/**\n * Twee2 to Twee3 header syntax conversion.\n * Ported from twee2compat.go.\n */\n\nconst twee2DetectRe = /^:: *[^[]*?(?: *\\[.*?\\])? *<(.*?)> *$/m;\nconst twee2HeaderRe = /^(:: *[^[]*?)( *\\[.*?\\])?(?: *<(.*?)>)? *$/gm;\nconst twee2BadPosRe = /^(::.*?) *\\{\"position\":\" *\"\\}$/gm;\n\nfunction hasTwee2Syntax(s: string): boolean {\n return twee2DetectRe.test(s);\n}\n\n/**\n * Convert Twee2-style position blocks `<x,y>` to Twee3 metadata blocks `{\"position\":\"x,y\"}`.\n */\nexport function twee2ToV3(s: string): string {\n if (!hasTwee2Syntax(s)) return s;\n let result = s.replace(twee2HeaderRe, (_, p1: string, p2: string | undefined, p3: string | undefined) => {\n const tags = p2 ?? '';\n const pos = p3 ?? '';\n return `${p1}${tags} {\"position\":\"${pos}\"}`;\n });\n result = result.replace(twee2BadPosRe, '$1');\n return result;\n}\n","/**\n * Parse lexer items into Passage[].\n * Ported from storyload.go:loadTwee().\n */\nimport type { Passage, PassageMetadata, Diagnostic } from './types.js';\nimport { ItemType } from './types.js';\nimport { tweeLexer } from './lexer.js';\nimport { tweeUnescape } from './escape.js';\nimport { twee2ToV3 } from './twee2-compat.js';\nimport { normalizeSourceText } from './source-text.js';\n\nexport interface ParseOptions {\n /** Filename for diagnostics. */\n filename?: string;\n /** Trim whitespace from passage content. Default: true. */\n trim?: boolean;\n /** Enable Twee2 compatibility. Default: false. */\n twee2Compat?: boolean;\n}\n\nexport interface ParseResult {\n passages: Passage[];\n diagnostics: Diagnostic[];\n}\n\n/**\n * Parse Twee source text into passages.\n *\n * The source is normalized first, as files are when they are read: a leading UTF-8 BOM is\n * removed and CRLF and bare CR line endings become LF.\n */\nexport function parseTwee(source: string, options: ParseOptions = {}): ParseResult {\n const { filename = '<inline>', trim = true, twee2Compat = false } = options;\n const diagnostics: Diagnostic[] = [];\n\n const normalized = normalizeSourceText(source);\n const tweeSource = twee2Compat ? twee2ToV3(normalized) : normalized;\n\n const passages: Passage[] = [];\n let current: Passage | null = null;\n let pCount = 0;\n let lastType: ItemType = ItemType.EOF;\n\n for (const item of tweeLexer(tweeSource)) {\n switch (item.type) {\n case ItemType.Error:\n diagnostics.push({\n level: 'error',\n message: `line ${item.line}: Malformed twee source; ${item.val}.`,\n file: filename,\n line: item.line,\n });\n // Fatal: return what we have\n return { passages, diagnostics };\n\n case ItemType.EOF:\n if (pCount > 0 && current) {\n passages.push(current);\n }\n return { passages, diagnostics };\n\n case ItemType.Header:\n pCount++;\n if (pCount > 1 && current) {\n passages.push(current);\n }\n current = { name: '', tags: [], text: '', source: { file: filename, line: item.line } };\n break;\n\n case ItemType.Name: {\n if (!current) break;\n const name = tweeUnescape(item.val).trim();\n if (name.length === 0) {\n diagnostics.push({\n level: 'error',\n message: `line ${item.line}: Malformed twee source; passage with no name.`,\n file: filename,\n line: item.line,\n });\n return { passages, diagnostics };\n }\n current.name = name;\n break;\n }\n\n case ItemType.Tags: {\n if (!current) break;\n if (lastType !== ItemType.Name) {\n diagnostics.push({\n level: 'error',\n message: `line ${item.line}: Malformed twee source; optional tags block must immediately follow the passage name.`,\n file: filename,\n line: item.line,\n });\n return { passages, diagnostics };\n }\n // Strip the surrounding [ and ]\n const inner = item.val.slice(1, -1);\n current.tags = tweeUnescape(inner).split(/\\s+/).filter(Boolean);\n break;\n }\n\n case ItemType.Metadata: {\n if (!current) break;\n if (lastType !== ItemType.Name && lastType !== ItemType.Tags) {\n diagnostics.push({\n level: 'error',\n message: `line ${item.line}: Malformed twee source; optional metadata block must immediately follow the passage name or tags block.`,\n file: filename,\n line: item.line,\n });\n return { passages, diagnostics };\n }\n try {\n const raw: unknown = JSON.parse(item.val);\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n throw new Error('expected a JSON object');\n }\n const parsed = raw as Record<string, unknown>;\n const meta: PassageMetadata = {};\n for (const [key, value] of Object.entries(parsed)) {\n if (typeof value === 'string') {\n meta[key] = value;\n }\n }\n current.metadata = meta;\n } catch (e) {\n diagnostics.push({\n level: 'warning',\n message: `load ${filename}: line ${item.line}: Malformed twee source; could not decode metadata (reason: ${e instanceof Error ? e.message : String(e)}).`,\n file: filename,\n line: item.line,\n });\n }\n break;\n }\n\n case ItemType.Content: {\n if (!current) break;\n if (trim) {\n current.text = item.val.trim();\n } else {\n // Per spec: trailing blank lines MUST be stripped regardless of trim option\n current.text = item.val.replace(/\\n\\s*$/, '');\n }\n break;\n }\n\n default: {\n const _exhaustive: never = item.type;\n diagnostics.push({\n level: 'error',\n message: `line ${item.line}: Unhandled lexer item type: ${_exhaustive}.`,\n file: filename,\n line: item.line,\n });\n return { passages, diagnostics };\n }\n }\n\n lastType = item.type;\n }\n\n // Shouldn't reach here (EOF is always emitted), but just in case:\n if (pCount > 0 && current) {\n passages.push(current);\n }\n return { passages, diagnostics };\n}\n","// Adapted from https://github.com/mathiasbynens/he/blob/36afe179392226cf1b6ccdb16ebbb7a5a844d93a/src/he.js#L106-L134\n/**\n * C1 Unicode control character reference replacements (code points 128–159).\n * Index i gives the replacement for code point 128+i; 0 means \"no replacement\".\n */\nconst c1 = [\n 8364, 0, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249, 338, 0,\n 381, 0, 0, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250,\n 339, 0, 382, 376,\n];\n/**\n * True for NUL, UTF-16 surrogates, and values past U+10FFFF.\n * @param codePoint Unicode code point to check.\n */\nfunction isInvalidCodePoint(codePoint) {\n return (codePoint === 0 ||\n (codePoint >= 0xd8_00 && codePoint <= 0xdf_ff) ||\n codePoint > 0x10_ff_ff);\n}\n/**\n * Replace the given code point with U+FFFD if it is NUL (0), a surrogate, or\n * outside the valid Unicode range. Code points in the C1 controls range\n * (128–159) are remapped to their Windows-1252 equivalents, following the\n * HTML spec. All other code points are returned unchanged.\n * @param codePoint Unicode code point to convert.\n */\nexport function replaceCodePoint(codePoint) {\n if (isInvalidCodePoint(codePoint)) {\n return 0xff_fd;\n }\n if (codePoint >= 128 && codePoint <= 159) {\n return c1[codePoint - 128] || codePoint;\n }\n return codePoint;\n}\n/**\n * XML numeric character references are the referenced Unicode code point.\n * Invalid values still become U+FFFD; the HTML Windows-1252 C1 remap is not\n * applied.\n * @see https://www.w3.org/TR/xml/#NT-CharRef\n * @param codePoint Unicode code point to convert.\n */\nexport function replaceCodePointXML(codePoint) {\n return isInvalidCodePoint(codePoint) ? 0xff_fd : codePoint;\n}\n/**\n * Convert the code point of a decoded numeric entity to a string, replacing\n * invalid values.\n *\n * Fast path for plain BMP code points: [1..0x7F] and [0xA0..0xD7FF] pass\n * `replaceCodePoint` unchanged (no NUL, C1 remap, surrogate, or out-of-range\n * handling) and fit a single charCode. 0xd760 = 0xD800 (the first surrogate)\n * - 0xA0.\n * @param codePoint Unicode code point to convert.\n */\nexport function codePointToString(codePoint) {\n return (codePoint - 1) >>> 0 < 0x7f || (codePoint - 0xa0) >>> 0 < 0xd7_60\n ? String.fromCharCode(codePoint)\n : String.fromCodePoint(replaceCodePoint(codePoint));\n}\n//# sourceMappingURL=decode-codepoint.js.map","/*\n * Inverse of the encoder's SAFE alphabet (0x21..0x7E minus 0x22, 0x24, 0x5C),\n * precomputed once at module load. Entries for excluded chars stay 0 but\n * are never read.\n */\nconst BASE91_INVERSE = /* #__PURE__ */ (() => {\n const table = new Uint8Array(127);\n let code = 0;\n for (let char = 0x21; char <= 0x7e; char++) {\n if (char !== 0x22 && char !== 0x24 && char !== 0x5c) {\n table[char] = code++;\n }\n }\n return table;\n})();\n/**\n * Decode a dictionary-encoded trie string back into its Uint16Array.\n *\n * Stream layout (consumed in this order):\n * 1. dict1 atoms — `dict1AtomCount` uint16 values, delta+RLE encoded.\n * 2. dict2 atoms — `atomCount - dict1AtomCount` values, delta+RLE.\n * 3. dict2 ngrams — `ngramCount - (dictSize - dict1AtomCount)` entries,\n * each a pair of slot codes that resolve to earlier slots.\n * 4. dict1 ngrams — `dictSize - dict1AtomCount` entries, same shape.\n * 5. data — slot codes, each expanding to one or more uint16 values.\n *\n * Codes use a 91-char base (printable ASCII minus `\"`, `$`, `\\`):\n * - char1 < dictSize → 1-char code, slot = char1\n * - char1 ≥ dictSize → 2-char code, slot = dictSize + (char1 - dictSize)*91 + char2\n *\n * Slot index → token kind:\n * [0, A) dict1 atoms (1-char codes)\n * [A, dictSize) dict1 ngrams (1-char codes)\n * [dictSize, dictSize+D) dict2 atoms (2-char codes)\n * [dictSize+D, end) dict2 ngrams (2-char codes)\n *\n * Both atom dicts decode before any ngram, and dict2 ngrams decode before\n * dict1 ngrams. So every ngram entry references slots whose contents are\n * already filled — no forward references to handle.\n *\n * This runs on library import. Flat typed arrays store each slot as either\n * a plain value (`single`, covering every atom) or a range in a shared\n * `pool` (ngrams).\n * @param input Packed trie string.\n * @param resultLength Expected number of uint16 values in the output.\n * @param atomCount Total number of distinct uint16 values in the trie.\n * @param dict1AtomCount Atoms in the 1-char range (`A` above).\n * @param ngramCount Total number of ngram entries (dict1 + dict2).\n * @param dictSize Number of 1-char code slots; the rest of `BASE - dictSize`\n * first-byte values are 2-char codes.\n */\nexport function decodeTrieDict(input, resultLength, atomCount, dict1AtomCount, ngramCount, dictSize) {\n const base = 91;\n const inputLength = input.length;\n // For 2-char codes, slot = char1 * base - twoCharBias + char2.\n const twoCharBias = dictSize * (base - 1);\n let pos = 0;\n /** Read one slot code at `pos` and return its slot index, advancing pos. */\n const readSlotCode = () => {\n const c1 = BASE91_INVERSE[input.charCodeAt(pos++)];\n return c1 < dictSize\n ? c1\n : c1 * base - twoCharBias + BASE91_INVERSE[input.charCodeAt(pos++)];\n };\n const dict2AtomCount = atomCount - dict1AtomCount;\n const slotCount = atomCount + ngramCount;\n /*\n * Per-slot contents: atoms (always a single value) live directly in\n * `single`; ngram slots hold -1 there and expand to\n * `pool[start[slot] .. start[slot] + length[slot])`.\n */\n const single = new Int32Array(slotCount);\n single.fill(-1, dict1AtomCount, dictSize);\n single.fill(-1, dictSize + dict2AtomCount, slotCount);\n const start = new Int32Array(slotCount);\n const length = new Int32Array(slotCount);\n /**\n * Decode `count` ascending uint16 values from a delta+RLE stream into\n * `single[off..off+count)`.\n *\n * code < 89 → delta = code\n * code == 89 → run-length: next char encodes runLength-2; emit `runLength` consecutive +1 values\n * code == 90, next < 90 → escape: delta = 89 + next * BASE + after-next\n * code == 90, next == 90 → double-escape: extra char for very large deltas\n * @param count\n * @param off\n */\n function decodeDelta(count, off) {\n let previous = 0;\n let slot = off;\n const end = off + count;\n while (slot < end) {\n const code = BASE91_INVERSE[input.charCodeAt(pos++)];\n if (code < 89) {\n previous += code;\n single[slot++] = previous;\n }\n else if (code === 89) {\n let runLength = BASE91_INVERSE[input.charCodeAt(pos++)] + 2;\n while (runLength--)\n single[slot++] = ++previous;\n }\n else {\n const next = BASE91_INVERSE[input.charCodeAt(pos++)];\n previous +=\n 89 +\n // eslint-disable-next-line unicorn/prefer-minimal-ternary -- branches read a different number of side-effecting input bytes\n (next < 90\n ? next * base + BASE91_INVERSE[input.charCodeAt(pos++)]\n : BASE91_INVERSE[input.charCodeAt(pos++)] * 8281 +\n BASE91_INVERSE[input.charCodeAt(pos++)] * base +\n BASE91_INVERSE[input.charCodeAt(pos++)]);\n single[slot++] = previous;\n }\n }\n }\n // Streams 1 & 2: atoms decoded into their slot ranges.\n decodeDelta(dict1AtomCount, 0);\n decodeDelta(dict2AtomCount, dictSize);\n /*\n * Streams 3 & 4 are read in two passes: first collect every ngram's two\n * references and derive its expanded length (each ref resolves to an earlier\n * slot, so lengths are already known), which sizes the shared pool.\n * Pool ranges are handed out in decode order, so the second pass fills\n * the pool contiguously with a single write cursor.\n */\n const references = new Int32Array(ngramCount * 2);\n let poolSize = 0;\n let ngramIndex = 0;\n /**\n * Read `count` ngram entries (each = 2 slot-code references) for the slots\n * starting at `startSlot`, recording references and assigning pool ranges.\n * @param count\n * @param startSlot\n */\n function readNgramReferences(count, startSlot) {\n for (let index = 0; index < count; index++) {\n const slot = startSlot + index;\n const a = readSlotCode();\n const b = readSlotCode();\n references[ngramIndex * 2] = a;\n references[ngramIndex * 2 + 1] = b;\n ngramIndex += 1;\n start[slot] = poolSize;\n const entryLength = (single[a] < 0 ? length[a] : 1) +\n (single[b] < 0 ? length[b] : 1);\n length[slot] = entryLength;\n poolSize += entryLength;\n }\n }\n readNgramReferences(ngramCount - dictSize + dict1AtomCount, dictSize + dict2AtomCount);\n readNgramReferences(dictSize - dict1AtomCount, dict1AtomCount);\n // Second pass: concatenate each ngram's two halves into the pool.\n const pool = new Uint16Array(poolSize);\n let write = 0;\n for (let index = 0; index < ngramIndex; index++) {\n for (let half = 0; half < 2; half++) {\n const source = references[index * 2 + half];\n const value = single[source];\n if (value < 0) {\n let read = start[source];\n const readEnd = read + length[source];\n while (read < readEnd)\n pool[write++] = pool[read++];\n }\n else {\n pool[write++] = value;\n }\n }\n }\n // Stream 5: data. Each code expands to its slot's stored values.\n const out = new Uint16Array(resultLength);\n let outIndex = 0;\n while (pos < inputLength) {\n let slot = BASE91_INVERSE[input.charCodeAt(pos++)];\n if (slot >= dictSize) {\n slot =\n slot * base -\n twoCharBias +\n BASE91_INVERSE[input.charCodeAt(pos++)];\n }\n const value = single[slot];\n if (value < 0) {\n let read = start[slot];\n const readEnd = read + length[slot];\n while (read < readEnd)\n out[outIndex++] = pool[read++];\n }\n else {\n out[outIndex++] = value;\n }\n }\n return out;\n}\n//# sourceMappingURL=decode-shared.js.map","// Generated using scripts/write-decode-map.ts\nimport { decodeTrieDict } from \"../internal/decode-shared.js\";\n/** Packed HTML decode trie data. */\nexport const htmlDecodeTree = /* #__PURE__ */ decodeTrieDict(\"!}.&u%}'&}*'~!6*)%&,~!J~!J~%L~y<~!R,~~%Lu~~#GD~~#|)1#%}^%}2%+#.##%##%}&%##%'#%##&%#%#'%#&#%#&#'#%%#&#%##%#)%''%&%#%#'%#%%#%%}%%%#%#&(23#%%#&-%0%('1#(##%#'##+%'*.:1}#%#6-+(%'%%#%%%}#L'2351&('%}&/N'(0(/*-%(%%}#'+&T%7.2}#&%&#%#36/5##%&%%#&#%%#))2%%##%&&'0~!#*+&'%1~!%).'3q?&%'1~!.##%6(~!+%%%(Gw'rT~!E#<nA%#jZ~!H%(~!42##~!*31&~!G%U~#)5~#`3~!J~!Z~%]~%Y~%C~!q~!u~#kz~%#~!6'~!D~!U~!?~#T~!c%~!G#'~%7|~!G~!J~!G&~#pb~(Df}#%}*&}#%##%##%##&#-}&'#'&%#.++}%mI,#,@&(}*%}*'%&##&#%##%}&0}#.},U},%}+%}&%}#%##&}B%(}(%}+%)})%##%#&}&%##%&}<%}>%#%&}*%}(%}9%}/%})%}*%}*%}?&}&%}3%}&*#%})%#%#)}#&#-#+*%E%%'%'#%}#*V##&##I}#&&##%&%#&&Qf%%))w/0+&%#(#.%-''''++++7}>%4'',##1,#%#&%##&#'##&#*#9)%&%}#*}%,#+P(%A&%#'&##wSD',9E00#y#@}(+}&%&>~!#~!X}#*}(&&}(&}(,%}%&#+&}#&}I%#%}%)#(},'%#*}4%%#%}(''}#/##(##),%-##%%)#&}(.}&%#&}%%}*&#%},&&}&%}#%*'#%})%}D&}&%}-&}6&#&}-,%}#%})-(~+`~,=?~I9'9%~!,#%})%})%}@%}?%}(~!?~#<~#pP~#BG~#=1#%K+~#?#~%;)~#A~#mF1~#A'~'X%'~#lR~#N~'N~#r~#m#-~#i'?%#'%~#B%##%,%#~#_%#0%~#]732~,w~2+#:&#%&'0%&>%}#>##F+)#%&&#(+_}4&}-%}(&}@&}O7Fdf0@+/v4}&WU##&/0#&'('B#%}.%}'+#%}#%%&#&%#%##+#&#)#6#'#.},%}c%},%#%##%&#&%#&~#>'*-.%##%##%}#%%}%'~#)D1}#%*&~#_%%'(~#S2%'.}#~#=##*'*-%}&'%'##&&~'E%.#&~#M4}%%##&'%#~#O1##%&#'+~#<B%##%%'%+~#;#@%}#&%#&&%#(~#H1}'%'##&&~#?A}&'~#D#%32}'&&&&~#[}'(#%}'~#;C})&}%%#%~#=&%,3}%'(#%%~#^'#&&)#%'~#Y%-~#d-%'~#^%%&#&&&}#~#b~2t*&'~&(~&@~0%~e~3}%*''0})&}+~!9##-}#%-hD*)1fC#%/&/fB#40~!+#)*4~!+~!K'&:~!/*7~!.#~!H~!L':~%x&~!H#~!*~%1~!I#~!+A~#p'~!F~~#-#~,,(~.Z~!V~%;'B'mq-W~!N~%I%#&&#&}#%},%%}'%}+X#%}#&}(%}'%}<%}#%}%%'}'%}:~![)9@~%>~#UA%-%##&~!C%~!-.9:~!1~!-^2/:a~!y,D*J#-5)/4~%23,~#G~!L1~!0X3`~!2+~!!0-~&E~!W~!o,>Y&]~%cZx_&~#O*9#A#'#+I'%#)~!0B*-5A+-((F&*M#)(-7-5+'-3a5Vi~!Y~!?+[)%3),ERHm~!+:D,VG.+)?fB%%*(%)'(#&80%1'8`K8?`+'Z#&O&'H5#*9)A%%5&3))0%39+.*7#()&&*=4@**L)<'_&*+..;(#*+)./&0#3)%')-8(4ixD(&.}%,('aI:,)%,k2231T)I'#/-W7,/'Q#.'Y24+h')37</31&83##&0#),H(?'&?/1##%#&&#%''-%&&&#(&''&#.-'%#%%(,')*'&#&#'##%(%(#%('#&##%%%%('%#%#%%#%#&%##h>w+v<ayvyvcg.uuhKr}g/v|g>u9i[~>g5uI~=RvdwEg;v/g;uk!!TTSx]@RT!U!#!@VBRUU!'UTe-d0c`e&gSdicedFcrdTaqb.kYcAohdYd@a3e+d}dMdtd.aJ#bqcK`dle/e.e'dwdPdodddjbEb}ogd^ofdpduc6j?l%d{drdqc)d7bacOdQ%T#Y)X.sR[yH>6Vyv3[xwLu>vo'!*.[yBacahoj>6Rew3[xqdZa#!a&#^(X-[yG>6Vyu3[xvg3sEr|g.u/Ri9db0T#^(Xa)!-[y;>6Vylg4wKs{JwNZt3@3r=c4Z([xlg;wKt!cpq's@v7A'*a(a+!-a#[y<3Dt?3Dt'>6Vym3[xmg9rxsNJwLZt4~?r?db1T#`-!(Xa,!0[yS>6Vz%NuQs.g4wKtnJwNZtS@3r>c4Z([y%g;wKtrdga8!a(!#&T*Y-Xa#!a0<or[yc3Dtq>6Vz43[y3JwNZtf@3s!Ju}!%Dti:pm3c_%X#tjB5pkd6q!r]u?voC'*-a.a2!0a&a+[yI3DtI3Ds~3DtH>6Vyw3[xx;:s#~<5pKJwNZtE@3r~d`a)!a2T#a.(!+U.X1[yT3Dt`3Dtv>6Vz&3[y&g9rxwzcxstPu.<rAJwLZtT~?r@dZa%!a.&^*Za(/Reu[ya>6Vz23[y1g3sEr}wkg{NuQRg{ci(U#5@b`~,cg#U(2WnH5wugcRh7dX#T(Y,a'Ta!!a,[yZ<]mj>6Vz,3[y+Pv#5ReZKu+=,%!H}7ABwkaS?Rh:BcW(X#<]mrj:ubv/ARekdg%!(!a.*Ta(Y.X1!#sP>Rl*Dt6[y>>6Vyo3Wf*jOvuumvuRgRJuq*!:9<B@bX~3jVv&v@s@5Re[d/rQt{uAvo&a&a*)a2!,0Wf!3Dt0=Bs'>6Re}3[xy~<5s%JwJZt1~Gs)c;&!#2sJkNuXvzq7rxu,Re8dka4!a8(aEZ+a@Y.X1Xa)[yd=Bs(3DtP>6Vz53[y4cX#X&Re:avRe9~<5s&JwJZtQ~Gs*i^rzvdRg+Jv{%!2sbB@bX}kdga,!Za?&^*T1/!a'Dt+[y6>6Vyf3Wf%g/u;s4hGu6?Rh-JvZ,!c%#&RoX54Rivj7uyvf8RgTKvZB%*!2sGh<vu5Rgq<=C::9bb~#dZ#T&Ta6Y.X*Dt>[y93Wf)coZ(T,6VyifluvRgC@95@B@bX~/hFu34cC#T,k/unq8w8Q5RkUklwQuzunq8w8Q5Rk8d/rJu?v8w9)-&!a0a;a&aIWejg3sEr/h1s<DtDJvyZqY5aws3Jvy!&Wei~Hr1:au5@Bag>23E~5c:Z&bX};kKv?w&unuVu5Rjc;>bs)#~@:Rh.=ay<a]C;b`}Vd6s/t{uAvoaxa()!a,a7%-a#a2Dt,[yF2Wo[>6Vyt3[xuNuPRi&NuPwpi#RoWh?vf8Ri%Jv]!%Ri:KvxD!.'2WeAjZu`q9rxu,Re7woeAg-unLq(qA_/*2Wg_g3u5q^9:4E}/jTrxrzv=Wkkd~0UX#^^Xa-a1a5T&a=U1a'*aEa]!a*aPaA-adok[y54Rn>;:p3~Dp5g9rpsFNvZqjg3uJp4~<5p0Pw;5qlJwNZt*@3p1Pw:5p/Ou!5p2JvG'!6Vye=<qnJvh_[xhg3v,Rh3kOwOw-sDuev/Re^dha[a%!%!a+#Ta7)-5TaCaO!aka!a)sf[yb2>Rl!9ARiq5E}Qg=ucRkBE|oJrJ_@Wk~@Wk{JrJ_@Wk|@WkyJrJ_@Wk}@WkzJvO_[y2g-vMRmiKuYC!)&>Ri;>Ri<@3RkNc](X#@9Rk=g5vuRmhKvDB!+'=]meg3u4Rmgd)#Y'Vz3CARmfd`a+!%T'!+#Ta1Ta6TaM-sTDt9[yA9sYd'%Y#s[[xpj:ueunaXRgEjRq,v-vuqdd2'`#6Rev<32@5>:2<E}5xIo9a*X#Y(;5RePJvD_g>vyRgNj8w)v8<wggs:RgXiZt|vjx,hSq3ah!-(~@:Ro/Ou!5RhWj^v(pyw8unRhUdx-UY#^Ua.a3a70!)%UX1TaDa)'omRiRRhE[y:3Dsz=Br,>6Vyj3[xkg6ruwjcqsrPw;5r*Ku]D'Zt-@3r(~?r.i[vwv]dU1a--U#`a4(g/vsRhPOu!5RhLj:rmu9Wo!~@:wdh@g/vsRiTjXuvvNr}:RhBj^v(pyw8unRn]dz1UYa'a+^Y(!aETZalaRY.Ta?a4[yDJw1!#qLsW>6Vyrfzq-pLflpwRe|Js>%!Dt@3Dt&Jvy_[xs~HrnjMuwpsw'RecKu+D#'!t<~Grl~?rjg5u-x,gwp{ah!-(~@:Rg~Ou!5Rh'jXuvvNr}:Rh#cW#X/c;&!#2sLi[v7u7RgpJv)(!iLrxu,Re6j7v@s@5Se[e7d`aW!Za(a`T.a#!a3!&aDa-!9)Dt_=6s+3[x~~DR|h~DS6avhGun5RkZj3w)v-]mkKunB!&*]kb97R|i<ARk<c:Z(6Vy}Juh'!wziMRoS:F|vkLuauJv5vtvQRh1d='T+Y#VyO~DR|jcF#T'7R|g97R|kJv3'!ay<Rj,Jvh&!:ReXcsa6*a+#a#_aIRf9aLRf?c,Z&Rf5Rf7c.Z&Rf;Rf>cQ#%T'p-Rf8Rf=ct#%'(*!,p,Rf4p+Rf6Rf:Rf<d~'Ua%U*^UYa(!a,-!#a4YaTalaEX0a8a<Weo3Dt/3Dsx=Br93Wen~Dr;~<5p<JwNZt2@3p=Pw:5p;Ou!5r3c7&!#:p>3Ds}KvGB)_6Vyk2sM=<r7x'eovA(!hFu1ARf}cV#X&@r5j6rvwQa^Rf3c=Za'wkghJv__g;unRggA53B9=b^}%j6uduo5Jq;!(hIv%2Re`Ou4ARe_e%a#^^^Xa&!a*a2!&a6YaP!*ad!#a:aE/5Rn?[y@>6Vyp;:pE~DrY~<5pBJwNZt8@3pCh=rt3rWPw:5pAJup_[xoNuPpF9c!#'45pD5ARn)d8#X'X*3@rU72s]h>v<<sSjJpqvewOJq/(!hNw'5ReBk0s2u3w/w'5ReE5@Jq.!a+JQ!&WeU23d(#Y&RjG5]jBk!u7w&u0udARjEe#+^^^Ub#!a2/a`Z(agT1!a-a;|@TaG!aS[yV=Re~fow'RguNuPRe?bz#'>RoUWeL>:Cbb|?JwPZtVg6ruRmzJvD'!6Vz(g/vmRh~Jvy_[y(g9voRgyx*cy(#2>Ri2B9b]~9kIw9u7rluJu3Rg]dI#a%UY'@=p%CAx.gQZ&RhwwygtRm{x5g_Z'+ABqR9Woa=Bp&dV#^*Xa'!&@o{g4v]Rk;Jv{!%Rk[wkkiA5RkiwwfUB=x,fUuqC&*!>RfTg8v0RfV~ARfSd;rJsAuAv9wR'ae+/aO!a@aza/a#[yQ@Wg!2Wemg3sEr0JvB_g>uvReWg2v+Re=KupB_+[y!2AbY~-~Hr2AJwD!(h<~El>h<~El?Kun@+_:9b`}Kg-v/Ri3g;vtwyk_9]k_d=&T#*U.6qh@Ab`|K9:H|CJv[!&3Dtex'fDwC%!Rf[9WlMd[(^X,!a%Z06Vz!@WgBg=v~Rgvg,QRe@awd,#Y+jTv|Q~EfWj]uNr|~FRfXdy#Y&^Ua%!aO.!(a)Ua;=!a@aKap!a-,a!Ta]a[rSa]p?[y82sK=Bq~;:p:~<5p8Pw:5p7d'#Y'Wf(;RnRi[u4w&RgJJvG'!6Vyh=<r#ijuuv/sIKuYD'ZtG@3p9~Gr&d2#`(g<vtRgFj`u5w&rqpxRf2CJuY!+:wfnTOu!5Rg}jNs1ucv&RfwJvA!&3@q|BDcC#T,k/unq8w8Q5RkTklwQuzunq8w8Q5Rk9dga#!a'!a=#a0!:+Tb*b@aO.a4!aba8aFJv^}?!VyR~Dr<g;u%Rn.~<5p[x'e`wNZtR@3p]Pw:5pZhNvjBp.woe_g5u-r4JwF!%DtO3:ooc7&!#:p^3DtpLuGw(!+%)Dtk6Vz#2sd=<r8d'#Y([y#<x3gJt`w@!)%}MRiowzikRij=]ilxAf3,U(#B2Rf#g0v-Rm[ck{`U#]giKv3>)!&6Ri154s,KuGB_%@r68r:dJ|t`#X(9<E|u2@H|rx3gJu?w'!+'1Nu7Reg4=H~+9<wxgY95Rm]xLggZ-`(X}U2:Ri4h<uOawRmsJv__5@bb{jbV~3dka#a'a]!,#a+U=a>b6a3b%!/aKa/)!arwve^VyJ;:pR~DpTg3uJpS~<5pOPw;5qmPw:5pNOu!5pQJvG'!6Vyx=<qoJvA!{~Jup!%@qk7Rn/KvyD!}''[xz;>wkh'?Rh,x8gyt`w5D!&),(SgyccRgztJ@3pPB5p#d'(Y#<]mmifubw&RgoJvE&!82s^JvF&!8Rf,ADb]~;x=h'rNu]vK!,%'*0RnORh)4Rh*AqQg-vaRnNg;wHwkh'ba~4cE#Ta*x3gctyw@'!+%RnFRnD<4Rn@hFvK5RnCxWg[#`&a0Ua()`1Rm75Rg[c]%X#qi8Rg^NvdRj>BwzgZauwji7Rm6A4wgg]d1#&(*,.0a#Rm;Rm<Rm=Rm>Rm?Rm@RmARmBe%#^^^Xaea?aC/b+(,!a+a#!a/!>a&Ta<aKbD!2wphBRnk[yPw}hE|.=Br-3Dtm>6Vy~g6urRf.x,hPrNav!%'RnqRo%Ro#Nu;q[Pw;5r+JwNZtM@3r)d'#Y'Weh;xChL#`&RnmRnoKu}>%(!Rne~Bs-;2wjcussJv+'!aYSO}6@B<5?ba~8LrNvj!.%*ROwungw~ng~:9;Ri^>wtnig;wHRnixDh@|(UZ.x1h@|)!#:2<H|*xHn]#-UX'3Ro)z=iT}6ARns=Bwsn_wpnaRncw]aR(#UXa&Ua*a/=]iPd'#Y&Ro'WnXf{QRm2hNvj]nZd`'T~&1`{|`#9b]{}c:'!#Wl{>@=be}]?cl{{U#:5Abb}Jds#^YaF!a*b4a#a3aPa>&Tb!bH!*a_!Eau?/a&RjY<]gj>6Vz*;:pe~DrZg,QRj1JwNZtX@wihspcJvZ&!VyX9WmOJu|!|N2WmHJvh&!]ht~Bpbcn&T(!#RmQ<s7Nu;padH#X'`+WmJ@>RmKCARhnKup=!)&Wf+:RhqNuPpf9c!#'45pd5AwghpARn(Ls@w!%,)!RmP@Wfe<E|IJva!&WmNg8vsRmLd`*.`#Y'Xa!axRn*]hrA8Rhug5s@rXg8u!RmMd8#X'X*3@rV72smdI*#UY&RmICARho~GsgxVgd)Ta'U-Y&Xa!T#RnEWnA@Wffg1uDRi0hFvK5RnBxGnG&#`%owp)@wsf+bX}Ze-*1!a*^^^Ua|!#a.aq&Ya2!a>.a6!a:aO`aJDtL[y`@Wg#>6Vz12@wzoYRoZNuPRi!NuPRhzg=ucRi,@=b`{Yg=ucRi-ACJvB!&Sh[ebSh]ebi`wUuFRm4Jw2_[y0JvB!.<Ju(!&SoG}6Shd}6<Ju(!&SoH}6She}6Kur@._g5vHRieJvx!{L2G{Kx6gd'T#?Rh82Wi5cZ#X(g1w)Rm5dW-Y(Ta#!a)!#aYa=wnfE=su2>>bU{0j9udv:<svj8uQv-7RgHdE%#^'sq9sp=>Bb_{TJv`!&g/r|snj6v(us5d,#Y(56H}[978H}]Jw5!&g1rushJvB!+j;v{u5?zDhd}6}bj;v{u5?zDhe}6}ce*#`(^^^a[aea!=!a6a*aoXb1a.!aAbL!b>,b'aL!aV@Wf|2Wlg3[y/JwNZt^@3piPw:5pgJunZou3@rsJva&!Vy_g<v~Rm#JvG'!6Vz0=<r{Ju{%!:pj@WfsiXuJu3Rm:JvZ&!WfA~Bph@c4Z&Dtwax5rubx(#:awRk1@d,#Y&RfjRfid1#,Y(@Wfp2Wlrg5s@ryKu[@!,'=]ig9wlk?Rk>g5u-rqJvy'!@9RkQcH(T#=>Ri~@<wkj(Wj(KuZB*!&<7rw@9RkRcH(T#=>Ri}@<wkj)Wj)dg(Ta2Xa9X#`-!a*CARhg@@=I}d9x;c~#X%so=<sj>2@@=aybb}XjWv0Q~EfEj3vLv;<d,#Y(56H}`978H}_dgaPaFa'a/!#a3Y0a_a;a|!1(a7-[yE3[xt;:pJNvZrrg3uJrvJwNZt=@3pIh=rt3rxPw:5pGOu!5rpJvG'!6Vys=<rz@c4Z&Dt(ax5rtJvZ!&~BpH@wsfNg-vaRlNci*U#=<wei<F}a5@Jq.!a*JQ!%@qZ23d(#Y&RjH5]jCk!u7w&u0udARjFd/prq=tyvpaEa(a:.!a1aZ(@@=I}:9wpd%=<sX55w_h}@@=I{t=ay<aU@@=I}T=ay<2@@=I})?C9:9au@9Cb]}DP~=x-fAZ(2Wl1=ay<aU@@=I}>5@d##Y+jTv|vV~EfFj]uNpn~FRfGdgaK!Z2&!a8a-Tb({E!acTbM*!a(DtY[yYd'%Y#sl[y*hHvh>Re5x2c{Z}.j4uCvcawRiMd+#X+_x&d!},<5RkX;2Hzw@x,gavfB-!{CcF&T#Roe;RodwWbBg5urRgaKvHC*_6Vz+<4opieuew&Rmq@d]&Y)X,T#X0Rh}<BqP=4qS9:ReMg/ujReNJw0!/<Jui%!bd{kawwnemRelAxUa?a3#*.&UX(Ya+a/RhvRnQ<o}9Wmtd-#Y&RgSRmw9;Rmxay=Rmyg-vaRmuxEhSrNu,v-voC!%(aR.a(a7+1Ro1>Ro5CE{A9b]{@;5x#eO{:g;urRi+KrNA!%(Ro3>Ro79;Ri_Ku@>{;&!x%gX|{KunA_+g5QRj/g3u5Rj#g>uERj%wio/xRhS&!,!#^1U}wba{8>>@=be}qC@:D5ba{7Ku+A&!}x?ba}t>>@=be}se(aA^^^Uat!b0#{pa+awUazbGa#aLb9bgaWac'a5TbS=Br!d1#`%scp_Jvl!#rT>Re0JvX&!VyN=H{Fcm#U&:pY=ReaJv2&!]h0=]nUJvG'!6Vy|=<r%JrM_=]h2@Wlud'#)U'Wf'b]{i=]h/Jvh!&~BpWg=v]RnMx+ny#'Nu;pVwjnu=]nwxJnx,T#`&Reqwjnt=]nvieu9vrRjLLuYwP(#+!th@wih5pX~Gr'g5v/Rh4KunA'!-CARnP@wwiN:Rm_9x'cvw>!|l=<saKvAA!0&3@q}>w^e1bp#&Re2Re3BDx7gH#T|f5H|eKuZ>!%(:qNAH{]Jv6!+3B2B9=b^{X<5<B92:E{ZLvhwA(a;a%!igQuyRmad+#Y}m@3Rh5d8#X'X*:AqUAHzmaxwbh<aXRnVcF}RT#Nw&cj#U(BWnug/vsRntdka)(a3+.Zb7aYYan1!bVa@Xa}[y^@b[{G=H{+hFu73Rj&Pv#5ReQcK%T#sig1v{Rj'Ku+D#'!t]~Grm~?rkKuMB!01d5#`'Vy.ta3Dtu~Hroc8#'{^45s85AwZbP&!#Rn!wghxWn#KvEA!)&2RlA2RlBx:h|#(T,=]j09Wobz>x]z/@awRoTd+#Y(az]hFhCrm4d,#Y+jTv|Q~EfMj]uNr|~FRfOdCa!Xa9_X#@<plJvf!%b`{(9;Rgwc;.!#2x7cw#T|UDb]|T5Ju={(!=@E{&Jv)&!Ab`{'awJvf!~*>>@=be{#KuY>!+&4Ezyi[ugv&RjIdea+T)#UXa&T-T&a!Rh9auRmW=]kLg5vuRn+g3u4Rn-Ow6ARn,hHus5xNk?#UX(U~)/g8v0RkD~AwkkF?Ri.OuNBwkkA?Ri/d|a2`a*^UYa.!aBTZaTa'Xa;!(!2!-a#b2[yC>6Vyq3[xr2Wi?g1rusVh%s?DtF~<5rbJs;%!DtBfswKtCj[uvuSsEu3RgVx3o:u+wN'*Zt;@3rd~Grh~?rfg8w)Lq)qE&-a%!>bI|`jWv0vV~EfCjTv|vV~Ef@j]uNpn~FRfBcK#T']gWNu7x,k7q4ai(0!hHv8<RhmkMu9vrsBuev/RhlCJvB!,g<v{wchh~@:Rhji[vrv{wchi~@:RhkdS&a5UY#Ta!RgPwwiI5BwciI~@:Rh`x'iJvj'!5]iJPu8Bwch]~@:Rhach)U#h3rp]gLh@t|Ax,hTq3ah!-(~@:Ro0Ou!5RhXj^v(pyw8unRhVd|)`,^UYas!a?/a2Z'a^Ta{Tb7Ta(a#!a,Wf&9sZ3DtAadamov=Bqt3[xig8vsRm~>waiL2b`{QJv*_Ouv2qgj<v]v2BqfdR'X*X#Y-@3qr~Gqv~?p6hHv-]glPup5Lq+q?_%*b_{qF{n9b^{rOu4ARhpKvCD!+&~Bqp:5Dbb}nwoiKl&unuTuBv]v+ueunaXRf0=Jvh!0nKufu8v1w&w7q%w&uHrz:Rgnj5w,uxDJq/(!hNw'5ReCk0s2u3w/w'5ReFd>Za&!*UaA=<wkgsRnSJv^!%Refifw3vyRgOKu_B'!,<]gkiiu:w&Rh<=C@a^<B57@2F{[<B5@aW:=3away9A5aW=<B=C@a^<B57@2F{Ie-#`(^^^bCara.b8aza6!/bZ,!adTbnTbOb+aFaS!aAT9@Wf~2Wli3Dtl2@d,#Y&RfnRfmJwJZtN~GqyJva&!VyMg<v~Rm%iXuJu3Rm9Jv[_=]ih9wlkDRkCd1#`(@Wg>2Wls3cH#T(@<Rj*=>Ri|b~'#23s9h<~El.d'#Y&Dtxi^rzvdRl#d*#U%(o|B2s`hJwSaxRmDKv4B&!1:Rmdd5#`'Vx}to~Hq{x'f1v3(!BA5ba|bJv_&!Wfug1v]ReIdO+U/Y#&G}-8wze=Rh{g1v]ReHg/uQRf/by#)ibQwERl/cH#T(@<Rj+=>Ri{cNu+vlax-!(#a0qa9<Rii2;;bU{H;x<i=&X#Rk`<4wwi=C9H~8xAI(Y#<azRi@45wXI<B9;5bb~7dL(X#Xa(+!aL6Vy{g5QqOau:5au2@ay547EzbxOcU(UX-T#Ta#:Cbb|A?wjh/b_|SOw6ARgtihr}u7Rhy<d1#T)X1@@=I|~=ay<2@@=aybb}Sj3vLv;<d,#Y(56H}A978H}@dGpvs@uAu`vcw9*!aFa+ai%(b!aXa8.a?a[ozWey=sU2@G}Nch&U#Rf_WexKu+D#'!t:~Gr`~?r^j]uNr|~FRg*j^psurwJt|RmcKv)@&!)7Rkv~Br[@wxfO:Rl3co#U'6Rezj_q#vIuavjRltwzeyh@vr5JqD0!>aY?C9:9au@9Cb]}9cl#U*5;5<H||jbuus1ucv&Rfvg1v~d/pppzqFr^a--a~!aMat1(hFv;Wiz@@=Izoj5uuv-7Rix~Cw`fk2WlVcZ#X,k)u3vWs@u2]ktg;wEx'fBq(_2Wg/jTv|vV~EfoJv]!15x'hzqG!(P~EfU~CRl_j6v(us5x4i-#T(2WmZ?C2F|d>Kq<aj1!*jTqIsBv=Wl`~Cw`fi2WlWj`v0u*~>RlR=c>Z,k#u3vWs@u2]kr<c1Z+jTqIsBv=Wla~Cw`fm2WlXdmb3!a{(arZa`bkTa%TbQTa-a9+c'!aM!/[yL=Bqug.w'RifhFvyDRj.g>vgwyk^9]k^Jv3_@WfbAARkhJw2_[x|JvB_wkoIRoKwkoJRoLd'(Y#<]gm=<9<H|yd'%_X#skDtb3awwqkgNulRkgdB#^',9:p'hJwSaxRmEBwVb8@4=H|qLu+w50&!)@3qs~?pU>Awwn;;Rn=c:Z'ARn<=<qwKvC@!/&~BqqJv6!&]eVb^z^xRge'/a%+^`#Sge}6<4Rn3=]n0Pw2>Rn8Jw0!&>Rn:>Rn6cY#a7+!a&=<wkaNw~h3z_c5Z{=wjh#=]nLKv^D!&)Vyz=bW|swYb<WetcG#T(2wxa@qVx@gD#Y&b^|V5JwG&!5bb|pg/w&RgD@x=kHs=uAvn!a%%/'+RmSRh694Ro`g-vaRmRhHv-]mlxCcS#`&ba~.5cD#Ta)P~=d,#Y(56H{>978H{Dd_#{2^Y%_+qbbb{6g3sERhsbU{?dfa.,`a(Xa<!aiX#(55RiG54RiHcI#T'WiU3RiVNvdwtfcRlKNvdd,#Y&RlHRlExQgf.1*^T'X#Sgf}6Wn4=]hfPrk>Rn7Jw0!&>Rn5>Rn9Lunw?&a2!,5<oq@@wqfdRlJj5Q~=d,#Y(~ARfcOuN]fdDKw;ay(}i!547E}j?cI#T(@5bV}iCbV}hdv(^^Tb?a40,b##Tbo!a*bR!a<b|a/!aKai!aU[yK=]o^g:v>ReGJwPZtK<7Rh+h<~El,Pv#5ReR@awwxjCg,ulRjDJv6&!]j!z?aQeeg>w=Sh<eeJw;!&axEzOg,Qosc!#*:wkeJ]eJ>x'h-u(!%Ro.w~h.zPdNZ(X,Ya![x{;9ReY;wkgxRiF:x?ap#Y&RmUg<s2Rkod]+UY0TZ'!a&A9sw<=bczLNvuw{gqzNhJwSaxRmCKuLay!#&s_Rf-55b^{uJvZa!!c%#(55Ri654wmiu5RiuawLu,vp!+}^%b_}Y9;wkgxba}o>A9:=b^}zKuh=a''!3awRk3c*'!#aHRk6c+Z&Rk5Rk4Jv)&!awRjSawd9*`#0?C2@EzMj8u<uJ5RmbjQrquJu3x,k>uq@_+=ayb^|W~ARkEOuN]k@7dhzV^X/X&a-#zRzSb`zXcJzTT#2WkVKvDBzW!%FzY9;5bbzWjQrquJu3Jw3%!b`zU=ayb^zQd:#X(T-a!6Vyywxh}=b]{Jg=u1RiAdGp~qHtzv!w(wA+a+a;<!aJaYai'anasb(=azRmV:Cbb{MLq2vb!%')RjuRjrRjtRjqx3jnqCw3!%')Rk(Rk+Rk&Rk)Lq2vb!%')Rj{RjxRjzRjwLq2vb!%')RjsRjpRjfRjex3jcqCw3!%')Rk'Rk*RjkRjl9<CbbzfOu4ARhxLq2vb!%')RjyRjvRjhRjgx=joq*uKvb!%')+-Rk.Rk%Rj~Rk-Rk#Rj}x=jdq*uKvb!%')+-Rk,Rk!Rj|RjmRjjRjidAq&qKs@uAv8Aa.'*-a@a&0!aM@a5[y73Dsy3Ds|3Dt):wxgI2sHJwJZt.~Gqxwsf0ikrzt}Rl0Jvy_[xj~HqzKv_A|D!&WfP8axRoVcf,U#k(v]v+ueunaXRf1Ju}'!g8u#Ri=jQw!sCunLprq>!,')~<5qeGzq9F{W=c##%s5au:5aU3CBE|;d4#X(D!a&6Vygx(b;#(=]ed?C2F{N<capoq2r[a&!aPa9,'Pw;5s:@@=I|,55w_h|@@=IzcP~=x'fCqB_2Wl2>aU@@=I|1OuNBc1Z+jTqIsBv=Wlc~Cw`fl2WlZ~AcTa%!Z+jTqIsBv=Wlb~Cw`fh2WlYk+uNqJsBv=WlSg,u3dca3#UXaMYa)TaB-=cM|7T#<bI}l5@B932:aV2G{BOuNBJq:|M!5Ezt=<B=C@a^<B57@2F{v>cB{/T#=ay<bI{3Jv6!a.6BKq0ah&+!5E}HP~Ef{978BaU@@=Iza<7d#.Y#978BaU@@=IzH~AJq0!(@@=IzG978BaU@@=IzFe,aU*Y&^^^bvJb,b:bFad!a,c2Ta>aL.bo6!a#CbTa'T#Re{2Wlh2@G{yg6t~Ro_NvdRfticuRQRllJv3&!x&c|zs@Jw3!%RflwpfkRlpKuL;%(!Re<@G|C2GzdhIvuBwgjAg-u0RjAKQB%!(GzZ@G|5NuuRl7d='T+Y#Vy[g<v~Rm!==G|>JvA!)@wma=]m1ifuaw&RmnLs@vT'!|/+[y,g:v>ReTJw1!#qX=x!eC{bLu+wT&)ZtZauq_~Graci&U#F|89:r_Lupvq!.)&2RlG8RfaC=x!eF{_h?rpWlmd&'!#X|&]k::xJey#`'T|+<E|&2@H|%dE#(^,g;u.RiEg6vjRiC9xCkA{O|zY#g=ucRmXKs0@!&*@G|m@awRknJuh!,3d(}gY}eJvj!%Rm):Jw3!%Rm+Rm-Ls0w(&!a(a#@b[|6cZ#X'7RkxWgAOu4ARn'dH'U#Y*Vz-Wm'CARm}d]*#a%^a*T'aK!a<9bV{PC=p*Jw4!&SgxcbB5r]idw(wBRmF7xFkt#&`(Rm/Rm8E|!JuY_9:Rl5=wrgr2:bbxd@xXfB(a*#T+!.X0X1Ta/a'T&RlDRfL>RlyARl9b[z[>RfZ:RlL:RfRwlg/ARl;9;RlxKv,A/!%7s69<74=BA5ba{-8Bde#`a<XaKYa1,a'P~=wxfB2bZ}}?C972@@=I}r8@55B9;5bb}G978B2@@=aybb}3j3vLv;<Jw3&!>Rfk=ayb^}4~Ad1#`*@@=aybb{w2@>==<bbz]dx+UY#^UaF!a9!bB'Ya1.!ajXa#%olRhD[y=3Dt#Ov5BrHKuMB%!(Rf^Wep~HrJwkiQjKr|~FRg)Ku+D#'!t5~GrF~?rDdV)UY,Z/_7RkuG{<~BrBg,rlsO:235B@bX}|d?a1!#`(6Vyn5@d##Y+jTv|vV~EfIj]uNpn~FRfH7Lq2vb1!a9-978BaU@@=Iz9978BbU}#~AJq0!(@@=Iz8978BaU@@=Iz7~AJQ|}!978BbU}!JvkaK!AdUa21-U#`a+(g/vsRn~Ou!5RPj:rmu9WhOjXuvvNr}:RhAj^v(pyw8unRn[kPr}p|u7vwv]RiSBd;pppzq@qHQa?(b.!a.a`@.|xa(hFv;Wiyj5uuv-7Riw~Cw`fg2WlU978BbU|wOuNBJqG!(P~EfD~CRlQcZ#X,k)u3vWs@u2]ksg;wEx'f@q1_2Wg.j]uNpn~FRfqJv]!15x'h{qG!(@@=IzK~CRl^j6v(us5x4i,#T(2WmY?C2F{1>Kq<aj1!*jTqIsBv=Wld~Cw`fj2Wl[j`v0u*~>RlT=c>Z,k#u3vWs@u2]kq<c1Z+jTqIsBv=Wle~Cw`fn2Wl]dn1#c(a(b^a2!b/bAT(bj!aDa7bu,a_a{c0!2T0g:v>ReD2@G{42@G{5~DpM~<5rc=Bx6i>{RT#RnI@zCx]y]z:2Jv[!zr5Awyk]9]k]dD(Y+X#6Vz.g=wKtgwhaCwgmTWj2Lu,w%_+/[y-B;b^xeg3u3Rj-2@bX{*KrJ<!+'@Wg(g?QRlC@Jv`!%b[zIwsfII}8JQ_@w|kW|=Jv(%!AqcOuNBJvEzh!bYzjLs@wP#(0!oy@>RkdJwMZtc3Dtd@BcG#T'9bWxg2@2Fznd*#Y+;2x'c}w<zizixNgwa#Z'U+!/!a'!a+w~g~z6wcn{Rn}wcnzRn|5Rh%=]nJg5vuRmvNvdRlvcprJu}w*az*a#!%.a.'Bot9qT]kj@Wg'ay2Gzv@Jv`!%b[zEwsfHI}1;ck#Ux`<Cbbx_Lu+w!a&0*!wko*wwo,So,}6Juqxf!E}PigQuyRm`d3(`#8>Rn%:A5B;bZ~%KvhCa!a2!x>k7#Uxb@b{#xaRk7Jw0!)>wwhlShl}6>wwhmShm}6CJvB!.x'hhvj{!!5Bwkhhbaz}x'hivjz~!5Bwkhibaz|xEhTrNu,v-vpD!a%&/)a3a.,%Ro2t[CE{)@3re9b]{%wjo09:rgc:Z&Ro6=<riifuaw&RmoKrNA!%(Ro4>Ro89;Ri`dSaL'UYzxZb)7Rka3xRhT&!,!#^1U}vbaz{>>@=be}yC@:D5bazzKu+A&!}{?ba}y>>@=be}wxBh[t`u~vJvr!%a!a()a,a0a4RoC=]o;Ju(!%RoGRhdwjh`=]oAg>w#Ro?g5vuRo=NvdRl|Ku]C.!&;RoEJvB!%RoORoMBx'h[v+_?w~h`}~5?w~hd~!xKh]oiptu-utv.vp!#%&a30a@a'a+(a/aOp(o~p!RoDJu(!%RoHRhewjha=]oBNvdRl}g>w#Ro@g5vuRo>c[#X']o<CauRoRAd-#Y':RkpauRoQKu]C.!&;RoFJvB!%RoNRoPBx'h]v+_?w~ha}t5?w~he}ue!/UbhYacXaW^Tc&a;b:a-c/#b&aja1(!cL+!bKbt!bmcRc9aIc?8[yW3Dtt94Rg`Jv}!&SiRMzBhEebShEMNuPRe>x7gL#TzuwjirRipc<Z&>on;>z=h-MSh.Mwqczx'a7vj&!>Re4@=ResJt__NuPRi*NuPRi)j]uNr|~FRfzKrJ>_+@Wfy@Wf]2WocKrJ<!+'@Wg%g/QRl@@Jv`!&awRl<wsfFIzgLu(w*!.*&ShBMwvhIRhI9;RhNx1hK'!#Sn]Mx1hK~0!#:2<H~7cNu+w7D*'1ZtW>Rn1~?rOc:Z&Rn2=<rQ<7wjh&=BSnLMc]#X(6Vz)w[b=a!U#9wzgMc3#&(RgMRitRis<x,gKt`ax!&+SioM=BSilMc3#&(RgKRinRimKurB,!&SiQMzBhDebShDM6BJQ!(P~Efx978B2@@=I}WLrJw!!,a*&@G}O@9wkibRid@@x'fKwC!&SlDMSfLMjUv~Q~EfKKv3@a+!(hFv-]mpx/hYZ(C5RiWz<o/MwkhY?So/M@x,gbvfB*&!SgEM:SoeeehFu3:Rgbda(,^TZa)X/7Sg[eb:2RgI~BrMC@wgkc:wwkcRerx3h(uUvK!&*,SnOM4Sh*MArRg;wHRh(x=h;rJvPwI!a4',a'0@Wg&=BSh/Mg>w=Rh=g3w*wwgGRgGcW(X#;Sg}M2Gzk@Jv`!&awRl=wsfGIz`dKZ*T'Y-:RhR7RhQg5u-p`j6v(us5d,#Y+~Awkia?RicOuNBwkibba}Ld6p~tyu_vbAa'a+!a/'a3aEa8a!>Sh,ebJv{!&Sh@ebSaReb9;SgwebNuPRi(NvdRl)NuPRi'hHu^<Rm^Jvv_@Wl(g;u1Si/ebKu'B&!*Sh?eb@Wl'z@aPeb95Si.ebcpputyvjB)!,&a+0a%ShAMWeK@G}C@WfJ9;RhMwvhH9w{ia}ix,hJvRA1(!zAn[MRhHx1hJ~*!#hFv(BSn[MBJQ!(@@=I~'978B2@@=I}2db.Ua<'X}+T#a0XaG2G}E;wkg|wuh!Rh!x,hZu,@)!&So0MVy)C5RiXACJvB!&5RiY5RiZg8w)cG}*T#2@bU}=KsA>(!a.3wkhZba~(x,h^u(A!&(SoCMRhb5Bz=h[eb?w~hb~6x,h_u(A!&(SoDMRhc5Bz=h]eb?w~hc~6e)aA1T#T,^^^c-bMb&blcPaP(a/!0!bA=b5c@a(!bfbrc#2afwmhARnjwchORnp2Wlf3DtsNvdRl-2@wpa<]m0bx(#:awRk2@Jw3!%RfhwpfgRlnKQB%!(G{V@G|'NuuRl6d='T+Y#VyUg<v~Rl~==G|<Jv+'!aYShC}6@B<5?ba~8@Jw3'!g2QRljhLrpWlOd+#Y'g.w'rIg>w*wgj@g-u0Rj@Lu+wT&)ZtUauq]~GrGci&U#F|39:rELrNvj!.%*RhCwunfw~nf~:9;Ri]>wtnhg;wHRnhx3hDs@v~!/+'@Wfr@9RkSNu&Rlo=@<5GzoKs0@_+@Wl+@awRkmJuh!-3d(}pY#qWJvj!%Rm(:Jw3!%Rm,Rm*de&!1U-U#`)Re;@G|.@9Ri82@wjfvRlq=@<5GzpLvOvr!).&2RlF8Rf`C=x!eE{.Jw3_g2QRlkhLrpWlPde(!#U{s,UXa*Ta'[y'g:v>ReS;x0PZ&RnlRnn~HrKJw1}f!=x!eB|2w]aP(#Xa&a*Ta.Ua2a7=]iOd'#Y&Ro&WnWg;u.RiDg6vjRiBNvdRlzhNvj]nYJuW_2Wm3x)kFze{9d])!a.!,Y01!#&aC!a3RndC=ox~BrC@2b^{pg,rlse7x'ksuq!%Rm.E{xidw(wBRmGx9o+)X#wwo-So-}69:Rl4@xSf@a#XZ'X)X,Ta(/ARl8b[xc>RfY:RlI:RfQwlg.ARl:9;Rlwdn'#^XafaQa1X1TaHTa)@b[{zcZ#X'7RkwWg@Ou4ARn&x)kG#{,g7u/RkGdH'U#Y*Vz'Wm&CARm|bx#(A]gUbUzJj9Q~=d,#Y(56H}l978H{U7d,0#U*2>ABb_xZ978BbU{e~AJQ{g!978BbU{hxMh?ad{oUYZ.x1h?{l!#:2<H{mx3n[t{vl!,&a%3Ro(z=iS}6ARnr=Bwsn^wvn`Rnbd`*T}B0!#^X'BG{c9b]{a>>@=be}F?JvS!&BG{d7BG}(Bde#`a1X,Ya@!a'P~=wxf@2bZ}I56B2@@=aybb}08@55B9;5bb}<j3vLv;<Jw3&!>Rfg=ayb^}&OuNBKuLA!)a!P~=x#fD{f2@>==<bbzl?C972@@=Ix^d6rSu,v7w*C(0a)a6#B+a%!sQ[y?3Dt%3[xn~<5rLOu!5p@Ku+D#'!t7~GrP~?rNKvlaya7'!h+v-5qMg=t|cd,U#5AAaa5Abb{S@52B5@a[@52B5Gx[iXueu;d<#`a(!/549C;ag>23ExY5@Dah89b^~689Jv)!~2b[~1Lv'w(%*!a#bX|aPrmawRe]keu7uhv-q6rxu,q`xTo]/a5aU!bNaDXbi!b-!ao!b<bwA!#5@B932:aV2G|:d-)Y#hJrL>RhG<7@C5<H|_=Cau:5aj5@B932:bJ|ng>vIbs)#?C2F|9jPv0w.vISh-MKvUaz(.!9ABbb|[5;5<H|Eg>unwfh;9:4E|YjQsBt|vjx'hYq3!(?C2F|J:2<BaY?C2F|GOu!5x,g|p{ah!-(?C2F|c9:4E|OjXuvvNr}:Rh&i[w*t|cd+U#jJvsu)vsSn~Mkfrmu9p}u7vwv]So!McW#Xa!ax5@A5aY:5;5<H|>kJv~vYrquJu3x4ib#T)2@SmZM?C2F|Bj:rmu9@xPhI(a*a#U#`a3-5Abb|L~@:RhK9:4E|0@52B5G|#C::aY?C2F|-:2<BaY?C2F|.5Jvk!a)javYrquJu3x4ia#T)2@SmYM?C2F|HAxPhH(!a#U#`a*-5Abb|4~@:RhJ9:4E|R@52B5G|F:2<BaY?C2F|Sc^#Xa2j=Qq5CJvB!-g<v{z;hhM?C2F|Zi[vrv{z;hiM?C2F|XKsA>!a)-g<v{z;h[eb?C2F|]i[vrv{z;h]eb?C2F|^iZu.vix,hZq3ah!.(?C2F|QOu!5ShXM:2<BaY?C2F|P\", 13_494, 2713, 49, 25, 61);\n//# sourceMappingURL=decode-data-html.js.map","// Generated using scripts/write-decode-map.ts\n/** Packed XML decode trie data. */\nexport const xmlDecodeTree = /* #__PURE__ */ new Uint16Array([\n 512, 26_465, 29_036, 7, 0, 2, 4, 116, 24_638, 116, 24_636, 8693, 29_807,\n 24_610, 621, 1, 0, 0, 3, 112, 24_614, 111, 115, 24_615,\n]);\n//# sourceMappingURL=decode-data-xml.js.map","/**\n * Bit flags & masks for the binary trie encoding used for entity decoding.\n *\n * The trie is a flat `Uint16Array`. Every node starts with one header word:\n *\n * 15..14 VALUE_LENGTH Number of words the value occupies, +1.\n * 0 = no value; 1 = value inline in bits 12..0;\n * 2/3 = value in the 1/2 words after the header.\n * 13 FLAG13 If VALUE_LENGTH > 0: semicolon required (\"strict\"\n * entity; `;` is never stored as a branch).\n * If VALUE_LENGTH == 0: this node is a compact run.\n * 12..7 BRANCH_LENGTH Number of branches (or run length for runs).\n * 6..0 JUMP_TABLE Jump-table offset / single-branch char / first\n * run char (see below).\n *\n * Branch data follows the header and any value words. Its shape is selected\n * by (JUMP_TABLE, BRANCH_LENGTH) in the header:\n *\n * Single branch JUMP_TABLE = the only child's char, BRANCH_LENGTH = 0.\n * No branch words; the child node follows immediately.\n * Jump table JUMP_TABLE = first covered char (> 0), BRANCH_LENGTH =\n * table length. One word per covered char: 0 = no branch,\n * otherwise the child's offset from the END of the table,\n * +1 (so 0 stays the no-branch sentinel).\n * Dictionary JUMP_TABLE = 0, BRANCH_LENGTH = number of branches.\n * ceil(n/2) words of sorted keys packed two per word\n * (low byte first), then n pointer words storing the\n * child's offset from the END of the branch data.\n * Compact run VALUE_LENGTH = 0, FLAG13 set. BRANCH_LENGTH = run\n * length (3..63), JUMP_TABLE = first char; remaining run\n * chars packed two per word after the header. The target\n * node follows the packed words immediately.\n *\n * Pointers are end-relative (rather than relative to the pointer's own\n * position) because that makes the common \"child encoded right after the\n * branch data\" case a small constant, which compresses far better. Offsets\n * to already-encoded (shared) nodes wrap via uint16 modulo arithmetic; the\n * decoder masks navigation results with `& 0xff_ff` to match.\n */\nexport var BinTrieFlags;\n(function (BinTrieFlags) {\n BinTrieFlags[BinTrieFlags[\"VALUE_LENGTH\"] = 49152] = \"VALUE_LENGTH\";\n BinTrieFlags[BinTrieFlags[\"FLAG13\"] = 8192] = \"FLAG13\";\n BinTrieFlags[BinTrieFlags[\"BRANCH_LENGTH\"] = 8064] = \"BRANCH_LENGTH\";\n BinTrieFlags[BinTrieFlags[\"JUMP_TABLE\"] = 127] = \"JUMP_TABLE\";\n /** Bits 12..0: the inline value of a VALUE_LENGTH = 1 header word. */\n BinTrieFlags[BinTrieFlags[\"VALUE_MASK\"] = 8191] = \"VALUE_MASK\";\n})(BinTrieFlags || (BinTrieFlags = {}));\n//# sourceMappingURL=bin-trie-flags.js.map","import { codePointToString, replaceCodePoint, replaceCodePointXML, } from \"./decode-codepoint.js\";\nimport { htmlDecodeTree } from \"./generated/decode-data-html.js\";\nimport { xmlDecodeTree } from \"./generated/decode-data-xml.js\";\nimport { BinTrieFlags } from \"./internal/bin-trie-flags.js\";\nvar CharCodes;\n(function (CharCodes) {\n CharCodes[CharCodes[\"AMP\"] = 38] = \"AMP\";\n CharCodes[CharCodes[\"NUM\"] = 35] = \"NUM\";\n CharCodes[CharCodes[\"SEMI\"] = 59] = \"SEMI\";\n CharCodes[CharCodes[\"EQUALS\"] = 61] = \"EQUALS\";\n CharCodes[CharCodes[\"ZERO\"] = 48] = \"ZERO\";\n CharCodes[CharCodes[\"NINE\"] = 57] = \"NINE\";\n CharCodes[CharCodes[\"LOWER_A\"] = 97] = \"LOWER_A\";\n CharCodes[CharCodes[\"LOWER_X\"] = 120] = \"LOWER_X\";\n})(CharCodes || (CharCodes = {}));\n/** Bit that needs to be set to convert an upper case ASCII character to lower case */\nconst TO_LOWER_BIT = 0b10_0000;\n/*\n * `parseNumericEntity` packs its two results into one 32-bit integer:\n * `(consumed << CONSUMED_SHIFT) | codePoint`. The 21-bit code point field\n * fits any valid Unicode value (max 0x10FFFF, clamped before packing); the\n * consumed count excludes `&` and gets the remaining 11 bits. Extract it\n * with `>>>` so the topmost bit isn't treated as a sign.\n *\n * Plain consts rather than a `const enum`: with `isolatedModules`, enum\n * member reads compile to runtime property loads.\n */\nconst CONSUMED_SHIFT = 21;\nconst CODE_POINT_MASK = 0x1f_ff_ff;\n/**\n * Reserved consumed field for counts of at least 2047 characters after `&`.\n * The true count is in `longNumericConsumed`.\n */\nconst CONSUMED_OVERFLOW = 0x7_ff;\n/**\n * Side channel for numeric entities of at least 2048 characters including\n * `&`. Set by `parseNumericEntity` when its consumed count reaches the\n * reserved value `CONSUMED_OVERFLOW`; callers read the true count from here.\n * A module-level slot avoids a tuple allocation on the hot path.\n */\nlet longNumericConsumed = 0;\n/**\n * Extract the consumed count from a `parseNumericEntity` packed result,\n * recovering the true length from `longNumericConsumed` when the packed\n * field contains the sentinel. Read it before the next `parseNumericEntity`\n * call, which may overwrite the side channel. This helper owns that protocol.\n * @param packed Packed result of `parseNumericEntity`.\n */\nfunction unpackConsumed(packed) {\n const consumed = packed >>> CONSUMED_SHIFT;\n return consumed === CONSUMED_OVERFLOW ? longNumericConsumed : consumed;\n}\n/**\n * Unsigned subtraction trick: (code - lo) >>> 0 wraps negatives to large\n * values, so a single `<=` covers the entire [lo..hi] range check.\n * @param code Code point to check.\n */\nfunction isNumber(code) {\n return (code - CharCodes.ZERO) >>> 0 <= 9;\n}\nfunction isHexadecimalCharacter(code) {\n return ((code | TO_LOWER_BIT) - CharCodes.LOWER_A) >>> 0 <= 5; // F - a\n}\nfunction isAlpha(code) {\n return ((code | TO_LOWER_BIT) - CharCodes.LOWER_A) >>> 0 <= 25; // Z - a\n}\n/**\n * Checks if the given character is a valid end character for an entity in an attribute.\n *\n * Attribute values that aren't terminated properly aren't parsed, and shouldn't lead to a parser error.\n * See the example in https://html.spec.whatwg.org/multipage/parsing.html#named-character-reference-state\n * @param code Code point to check.\n */\nfunction isEntityInAttributeInvalidEnd(code) {\n return code === CharCodes.EQUALS || isAlpha(code) || isNumber(code);\n}\nvar EntityDecoderState;\n(function (EntityDecoderState) {\n EntityDecoderState[EntityDecoderState[\"EntityStart\"] = 0] = \"EntityStart\";\n EntityDecoderState[EntityDecoderState[\"NumericStart\"] = 1] = \"NumericStart\";\n EntityDecoderState[EntityDecoderState[\"NumericDecimal\"] = 2] = \"NumericDecimal\";\n EntityDecoderState[EntityDecoderState[\"NumericHex\"] = 3] = \"NumericHex\";\n EntityDecoderState[EntityDecoderState[\"NamedEntity\"] = 4] = \"NamedEntity\";\n})(EntityDecoderState || (EntityDecoderState = {}));\n/**\n * Decoding mode for named entities.\n */\nexport var DecodingMode;\n(function (DecodingMode) {\n /** Entities in text nodes that can end with any character. */\n DecodingMode[DecodingMode[\"Legacy\"] = 0] = \"Legacy\";\n /** Only allow entities terminated with a semicolon. */\n DecodingMode[DecodingMode[\"Strict\"] = 1] = \"Strict\";\n /** Entities in attributes have limitations on ending characters. */\n DecodingMode[DecodingMode[\"Attribute\"] = 2] = \"Attribute\";\n})(DecodingMode || (DecodingMode = {}));\n/**\n * Token decoder with support of writing partial entities.\n */\nexport class EntityDecoder {\n decodeTree;\n emitCodePoint;\n errors;\n /** The current state of the decoder. */\n state = EntityDecoderState.EntityStart;\n /** Characters that were consumed while parsing an entity. */\n consumed = 1;\n /**\n * The result of the entity.\n *\n * For named entities: the trie index of the best legacy match so far\n * (0 = none). For numeric entities: the accumulated code point.\n */\n result = 0;\n /** The current index in the decode tree. */\n treeIndex = 0;\n /**\n * Characters consumed since the last recorded legacy match, plus one.\n * Invariant at the top of the `stateNamedEntity` loop: `excess` equals\n * the number of unrecorded consumed characters + 1.\n */\n // biome-ignore lint/correctness/noUnusedPrivateClassMembers: False positive (read via destructuring)\n excess = 1;\n /** The mode in which the decoder is operating. */\n decodeMode = DecodingMode.Strict;\n /** The number of characters that have been consumed in the current run. */\n // biome-ignore lint/correctness/noUnusedPrivateClassMembers: False positive\n runConsumed = 0;\n constructor(\n /** The predefined HTML or XML decode tree. */\n decodeTree, \n /**\n * The function that is called when a codepoint is decoded.\n *\n * For named entities that decode to multiple code points, this will\n * be called multiple times, with the second codepoint, and the same\n * `consumed` value.\n * @param codepoint The decoded codepoint.\n * @param consumed The number of characters consumed by the decoder.\n */\n emitCodePoint, \n /** An object that is used to produce errors. */\n errors) {\n this.decodeTree = decodeTree;\n this.emitCodePoint = emitCodePoint;\n this.errors = errors;\n }\n /**\n * Resets the instance to make it reusable.\n * @param decodeMode Entity decoding mode to use.\n */\n startEntity(decodeMode) {\n this.decodeMode = decodeMode;\n this.state = EntityDecoderState.EntityStart;\n this.result = 0;\n this.treeIndex = 0;\n this.excess = 1;\n this.consumed = 1;\n this.runConsumed = 0;\n }\n /**\n * Write an entity to the decoder. This can be called multiple times with partial entities.\n * If the entity is incomplete, the decoder will return -1.\n *\n * Mirrors the non-streaming `decodeWithTrie`, but with the ability to stop decoding if the\n * entity is incomplete, and resume when the next string is written.\n * @param input The string containing the entity (or a continuation of the entity).\n * @param offset The offset at which the entity begins. Should be 0 if this is not the first call.\n * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n */\n write(input, offset) {\n switch (this.state) {\n case EntityDecoderState.EntityStart: {\n if (input.charCodeAt(offset) === CharCodes.NUM) {\n this.state = EntityDecoderState.NumericStart;\n this.consumed += 1;\n return this.stateNumericStart(input, offset + 1);\n }\n this.state = EntityDecoderState.NamedEntity;\n return this.stateNamedEntity(input, offset);\n }\n case EntityDecoderState.NumericStart: {\n return this.stateNumericStart(input, offset);\n }\n case EntityDecoderState.NumericDecimal: {\n return this.stateNumericDecimal(input, offset);\n }\n case EntityDecoderState.NumericHex: {\n return this.stateNumericHex(input, offset);\n }\n default: {\n // NamedEntity — the only remaining state.\n return this.stateNamedEntity(input, offset);\n }\n }\n }\n /**\n * Switches between the numeric decimal and hexadecimal states.\n *\n * Equivalent to the `Numeric character reference state` in the HTML spec.\n * @param input The string containing the entity (or a continuation of the entity).\n * @param offset The current offset.\n * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n */\n // eslint-disable-next-line unicorn/consistent-class-member-order\n stateNumericStart(input, offset) {\n if (offset >= input.length) {\n return -1;\n }\n if ((input.charCodeAt(offset) | TO_LOWER_BIT) === CharCodes.LOWER_X) {\n this.state = EntityDecoderState.NumericHex;\n this.consumed += 1;\n return this.stateNumericHex(input, offset + 1);\n }\n this.state = EntityDecoderState.NumericDecimal;\n return this.stateNumericDecimal(input, offset);\n }\n /**\n * Parses a hexadecimal numeric entity.\n *\n * Equivalent to the `Hexademical character reference state` in the HTML\n * spec. Digit parsing matches the hex loop in `parseNumericEntity`.\n * The accumulated value is preserved for numeric validation callbacks.\n * @param input The string containing the entity (or a continuation of the entity).\n * @param offset The current offset.\n * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n */\n stateNumericHex(input, offset) {\n const inputLength = input.length;\n // Local accumulators; flushed before any exit (see stateNamedEntity).\n let { result } = this;\n let { consumed } = this;\n while (offset < inputLength) {\n const char = input.charCodeAt(offset);\n if (isNumber(char) || isHexadecimalCharacter(char)) {\n // Convert hex digit to value (0-15); 'a'/'A' -> 10.\n const digit = char <= CharCodes.NINE\n ? char - CharCodes.ZERO\n : (char | TO_LOWER_BIT) - CharCodes.LOWER_A + 10;\n result = result * 16 + digit;\n consumed += 1;\n offset += 1;\n }\n else {\n this.result = result;\n this.consumed = consumed;\n return this.emitNumericEntity(char, 3);\n }\n }\n this.result = result;\n this.consumed = consumed;\n return -1; // Incomplete entity\n }\n /**\n * Parses a decimal numeric entity.\n *\n * Equivalent to the `Decimal character reference state` in the HTML\n * spec. Digit parsing matches the decimal loop in `parseNumericEntity`.\n * The accumulated value is preserved for numeric validation callbacks.\n * @param input The string containing the entity (or a continuation of the entity).\n * @param offset The current offset.\n * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n */\n stateNumericDecimal(input, offset) {\n const inputLength = input.length;\n // Local accumulators; flushed before any exit (see stateNamedEntity).\n let { result } = this;\n let { consumed } = this;\n while (offset < inputLength) {\n const digit = input.charCodeAt(offset) - CharCodes.ZERO;\n if (digit >>> 0 > 9) {\n this.result = result;\n this.consumed = consumed;\n return this.emitNumericEntity(digit + CharCodes.ZERO, 2);\n }\n result = result * 10 + digit;\n consumed += 1;\n offset += 1;\n }\n this.result = result;\n this.consumed = consumed;\n return -1; // Incomplete entity\n }\n /**\n * Validate and emit a numeric entity.\n *\n * Implements the logic from the `Hexademical character reference start\n * state` and `Numeric character reference end state` in the HTML spec.\n * @param lastCp The last code point of the entity. Used to see if the\n * entity was terminated with a semicolon.\n * @param expectedLength The minimum number of characters that should be\n * consumed. Used to validate that at least one digit\n * was consumed.\n * @returns The number of characters that were consumed.\n */\n emitNumericEntity(lastCp, expectedLength) {\n // Ensure we consumed at least one digit.\n if (this.consumed <= expectedLength) {\n this.errors?.absenceOfDigitsInNumericCharacterReference(this.consumed);\n return 0;\n }\n // Figure out if this is a legit end of the entity\n if (lastCp === CharCodes.SEMI) {\n this.consumed += 1;\n }\n else if (this.decodeMode === DecodingMode.Strict) {\n return 0;\n }\n this.emitCodePoint((this.decodeTree === xmlDecodeTree\n ? replaceCodePointXML\n : replaceCodePoint)(this.result), this.consumed);\n if (this.errors) {\n if (lastCp !== CharCodes.SEMI) {\n this.errors.missingSemicolonAfterCharacterReference();\n }\n this.errors.validateNumericCharacterReference(this.result);\n }\n return this.consumed;\n }\n /**\n * Flush locally-tracked walk state back to the fields, then emit the\n * recorded legacy match or reject (cold path — at most once per\n * entity). Called after failed navigation (leaf node, branch miss, or\n * compact-run mismatch). In attribute mode, reject if no legacy was\n * recorded at the current node, if we descended past it, or if the\n * pending input character is an invalid attribute terminator.\n * @param consumed Locally-tracked consumed count.\n * @param excess Locally-tracked excess count.\n * @param char Pending input character (may be the mismatching char).\n * @param valueLength Value length at the current trie node.\n */\n flushAndEmitLegacyOrReject(consumed, excess, char, valueLength) {\n this.consumed = consumed;\n this.excess = excess;\n return this.result === 0 ||\n (this.decodeMode === DecodingMode.Attribute &&\n (valueLength === 0 ||\n excess > 1 ||\n isEntityInAttributeInvalidEnd(char)))\n ? 0\n : this.emitNotTerminatedNamedEntity();\n }\n /**\n * Parses a named entity.\n *\n * Equivalent to the `Named character reference state` in the HTML spec.\n * @param input The string containing the entity (or a continuation of the entity).\n * @param offset The current offset.\n * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n */\n stateNamedEntity(input, offset) {\n const { decodeTree } = this;\n const inputLength = input.length;\n const isStrict = this.decodeMode === DecodingMode.Strict;\n /*\n * Local copies of the resumable walk state avoid per-character\n * field writes. They are flushed back to the fields\n * on every exit (chunk end, and before any emit helper that reads\n * them). `this.result` is only written at the (rare) record points,\n * so it stays a direct field write.\n *\n * Legacy-match recording happens in two idempotent places: at the\n * loop top when sitting on a value node, and in the chunk-end\n * epilogue (so `end()` sees matches that land exactly on a chunk\n * boundary). Recording applies `consumed += excess - 1; excess = 1`,\n * which is a no-op when repeated — the loop-top invariant is\n * `excess` = unrecorded consumed characters + 1.\n */\n let { treeIndex } = this;\n let { excess } = this;\n let { consumed } = this;\n let current = decodeTree[treeIndex];\n while (offset < inputLength) {\n /*\n * Descend through value-less jump-table nodes (including the\n * single-branch encoding) inline, mirroring `decodeWithTrie`:\n * this avoids a `determineBranch` call per level for the\n * dominant node shape — including the root on the first write.\n */\n while ((current &\n (BinTrieFlags.VALUE_LENGTH | BinTrieFlags.FLAG13)) ===\n 0 &&\n (current & BinTrieFlags.JUMP_TABLE) !== 0) {\n const char = input.charCodeAt(offset);\n const jumpOffset = current & BinTrieFlags.JUMP_TABLE;\n const branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;\n if (branchCount === 0) {\n // Single branch encoded inline in the jump offset bits.\n if (char !== jumpOffset) {\n return this.flushAndEmitLegacyOrReject(consumed, excess, char, 0);\n }\n treeIndex += 1;\n }\n else {\n const slot = char - jumpOffset;\n if (slot >>> 0 >= branchCount) {\n return this.flushAndEmitLegacyOrReject(consumed, excess, char, 0);\n }\n const stored = decodeTree[treeIndex + 1 + slot];\n if (stored === 0) {\n return this.flushAndEmitLegacyOrReject(consumed, excess, char, 0);\n }\n // End-relative: branch data ends at treeIndex+1+branchCount.\n treeIndex = (treeIndex + branchCount + stored) & 0xff_ff;\n }\n current = decodeTree[treeIndex];\n offset += 1;\n excess += 1;\n /*\n * `charCodeAt` past the end returns NaN, which would alias\n * to slot 0 after `>>> 0` — bail out explicitly.\n */\n // eslint-disable-next-line unicorn/no-break-in-nested-loop\n if (offset >= inputLength)\n break;\n }\n if (offset >= inputLength)\n break;\n // Handle compact runs (resumable across chunks).\n if ((current &\n (BinTrieFlags.VALUE_LENGTH | BinTrieFlags.FLAG13)) ===\n BinTrieFlags.FLAG13) {\n const runLength = (current & BinTrieFlags.BRANCH_LENGTH) >> 7; /* 3..63 */\n let { runConsumed } = this;\n // If we are starting a run, check the first char.\n if (runConsumed === 0) {\n const char = input.charCodeAt(offset);\n if (char !== (current & BinTrieFlags.JUMP_TABLE)) {\n return this.flushAndEmitLegacyOrReject(consumed, excess, char, 0);\n }\n offset += 1;\n excess += 1;\n runConsumed = 1;\n }\n // Check remaining characters in the run (packed two per uint16 word).\n while (runConsumed < runLength) {\n if (offset >= inputLength) {\n this.treeIndex = treeIndex;\n this.excess = excess;\n this.consumed = consumed;\n this.runConsumed = runConsumed;\n return -1;\n }\n const charIndexInPacked = runConsumed - 1;\n const packedWord = decodeTree[treeIndex + 1 + (charIndexInPacked >> 1)];\n const expectedChar = (packedWord >> ((charIndexInPacked & 1) << 3)) & 0xff;\n const char = input.charCodeAt(offset);\n if (char !== expectedChar) {\n this.runConsumed = 0;\n return this.flushAndEmitLegacyOrReject(consumed, excess, char, 0);\n }\n offset += 1;\n excess += 1;\n runConsumed += 1;\n }\n this.runConsumed = 0;\n treeIndex += 1 + (runLength >> 1);\n current = decodeTree[treeIndex];\n // Loop top handles the landed-on node (record/emit/branch).\n continue;\n }\n // Header plus out-of-line value words; 0 means no value.\n const valueLength = current >>> 14;\n const char = input.charCodeAt(offset);\n if (valueLength !== 0) {\n // Record a legacy match (FLAG13 clear = semicolon optional).\n if (!isStrict && (current & BinTrieFlags.FLAG13) === 0) {\n this.result = treeIndex;\n consumed += excess - 1;\n excess = 1;\n }\n /*\n * Implicit semicolon handling: emit immediately. Covers both\n * strict (FLAG13 set) and legacy entities — neither stores\n * an explicit `;` branch in the trie.\n */\n if (char === CharCodes.SEMI) {\n return this.emitNamedEntityData(treeIndex, valueLength, consumed + excess);\n }\n /*\n * `valueLength === 1` packs the codepoint into the header\n * word's low 13 bits, where branch metadata also lives. Skip\n * the branch lookup on leaves so those value bits aren't\n * reinterpreted as branch offsets.\n */\n if (valueLength === 1) {\n return this.flushAndEmitLegacyOrReject(consumed, excess, char, valueLength);\n }\n }\n // Value-bearing or dictionary node: dispatch through determineBranch.\n const next = determineBranch(decodeTree, current, treeIndex + (valueLength || 1), char);\n if (next < 0) {\n return this.flushAndEmitLegacyOrReject(consumed, excess, char, valueLength);\n }\n treeIndex = next;\n current = decodeTree[treeIndex];\n offset += 1;\n excess += 1;\n }\n /*\n * Chunk exhausted. Record a legacy match we may be sitting on, so a\n * subsequent `end()` emits it, then persist the walk state.\n */\n if (!isStrict &&\n current >>> 14 !== 0 &&\n (current & BinTrieFlags.FLAG13) === 0) {\n this.result = treeIndex;\n consumed += excess - 1;\n excess = 1;\n }\n this.treeIndex = treeIndex;\n this.excess = excess;\n this.consumed = consumed;\n return -1;\n }\n /**\n * Emit a named entity that was not terminated with a semicolon.\n * @returns The number of characters consumed.\n */\n emitNotTerminatedNamedEntity() {\n const { result, decodeTree } = this;\n const valueLength = decodeTree[result] >>> 14;\n this.emitNamedEntityData(result, valueLength, this.consumed);\n this.errors?.missingSemicolonAfterCharacterReference();\n return this.consumed;\n }\n /**\n * Emit a named entity.\n * @param result The index of the entity in the decode tree.\n * @param valueLength Encoded value length (header plus any value words).\n * @param consumed The number of characters consumed.\n * @returns The number of characters consumed.\n */\n emitNamedEntityData(result, valueLength, consumed) {\n const { decodeTree } = this;\n this.emitCodePoint(valueLength === 1\n ? decodeTree[result] & BinTrieFlags.VALUE_MASK\n : decodeTree[result + 1], consumed);\n if (valueLength === 3) {\n // Emit the second UTF-16 code unit.\n this.emitCodePoint(decodeTree[result + 2], consumed);\n }\n return consumed;\n }\n /**\n * Signal to the parser that the end of the input was reached.\n *\n * Remaining data will be emitted and relevant errors will be produced.\n * @returns The number of characters consumed.\n */\n end() {\n switch (this.state) {\n case EntityDecoderState.NamedEntity: {\n // Emit a named entity if we have one.\n return this.result !== 0 &&\n (this.decodeMode !== DecodingMode.Attribute ||\n this.result === this.treeIndex)\n ? this.emitNotTerminatedNamedEntity()\n : 0;\n }\n // Otherwise, emit a numeric entity if we have one.\n case EntityDecoderState.NumericDecimal: {\n return this.emitNumericEntity(0, 2);\n }\n case EntityDecoderState.NumericHex: {\n return this.emitNumericEntity(0, 3);\n }\n case EntityDecoderState.NumericStart: {\n this.errors?.absenceOfDigitsInNumericCharacterReference(this.consumed);\n return 0;\n }\n default: {\n // EntityStart or unknown — return 0.\n return 0;\n }\n }\n }\n}\n/**\n * Determines the branch of the current node that is taken given the current\n * character. This function is used to traverse the trie.\n *\n * See `BinTrieFlags` for the branch-data layouts handled here.\n * @param decodeTree The trie.\n * @param current The current node's header word.\n * @param nodeIndex Index of the node's first branch-data word (the header\n * plus any value words have been skipped by the caller).\n * @param char The current character.\n * @returns The index of the next node, or -1 if no branch is taken.\n */\nexport function determineBranch(decodeTree, current, nodeIndex, char) {\n const branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;\n const jumpOffset = current & BinTrieFlags.JUMP_TABLE;\n // Case 1: Single branch or jump table (jumpOffset encodes the first/only char code).\n if (jumpOffset) {\n if (branchCount === 0) {\n // Single branch encoded inline in the jump offset bits.\n return char === jumpOffset ? nodeIndex : -1;\n }\n /*\n * Jump table: branchCount consecutive slots starting at jumpOffset.\n * Unsigned comparison handles both < 0 and >= branchCount in one check.\n */\n const slot = char - jumpOffset;\n if (slot >>> 0 >= branchCount)\n return -1;\n const stored = decodeTree[nodeIndex + slot];\n /*\n * 0 = empty slot (no branch); otherwise the child's offset from the\n * end of the branch array, +1 (end-relative pointers compress\n * better). `& 0xff_ff` mirrors the encoder's uint16 wrap for\n * backreferences to already-encoded nodes.\n */\n return stored === 0\n ? -1\n : (nodeIndex + branchCount + stored - 1) & 0xff_ff;\n }\n /*\n * Case 2: Packed dictionary. Linear scan — over 90% of dict nodes have\n * <= 4 branches in the HTML trie, where the constant-factor savings\n * dominate over binary search's asymptotic edge.\n */\n if (branchCount === 0)\n return -1;\n const packedKeySlots = (branchCount + 1) >> 1;\n const branchEnd = nodeIndex + packedKeySlots + branchCount;\n for (let index = 0; index < branchCount; index++) {\n const packed = decodeTree[nodeIndex + (index >> 1)];\n const key = (packed >> ((index & 1) << 3)) & 0xff;\n if (key === char) {\n const pointerIndex = nodeIndex + packedKeySlots + index;\n // Pointers are relative to the end of the branch data.\n return (branchEnd + decodeTree[pointerIndex]) & 0xff_ff;\n }\n // Keys are sorted; if we've passed `char`, no match is possible.\n if (key > char)\n return -1;\n }\n return -1;\n}\n/**\n * Read the decoded value from a trie node.\n * @param decodeTree The trie.\n * @param nodeIndex The index of the node.\n * @param valueLength The length of the value (1, 2, or 3).\n * @returns The decoded string.\n */\nfunction readTrieValue(decodeTree, nodeIndex, valueLength) {\n if (valueLength === 1) {\n return String.fromCharCode(decodeTree[nodeIndex] & BinTrieFlags.VALUE_MASK);\n }\n if (valueLength === 2) {\n return String.fromCharCode(decodeTree[nodeIndex + 1]);\n }\n return String.fromCharCode(decodeTree[nodeIndex + 1], decodeTree[nodeIndex + 2]);\n}\n/**\n * Parse a numeric entity (`&#DDD;` or `&#xHHH;`).\n *\n * Encodes the result as `(consumed << CONSUMED_SHIFT) | codepoint` (see\n * the packing comment at the top of the file; overlong entities spill\n * their length into `longNumericConsumed`). Returns 0 when no digits were\n * found.\n *\n * This is the sync counterpart of the streaming\n * `EntityDecoder#stateNumericDecimal` / `#stateNumericHex`. Digit parsing\n * matches those methods; only this packed result needs a value clamp.\n * @param input The input string.\n * @param numberStart Index of the `#` character.\n * @param inputLength Cached `input.length`.\n */\nfunction parseNumericEntity(input, numberStart, inputLength) {\n let offset = numberStart + 1; // Skip \"#\"\n let cp = 0;\n let digitStart = offset;\n /*\n * Separate decimal and hexadecimal loops: each multiplies by a constant\n * and runs a single digit test, instead of a per-character base check.\n */\n if (offset < inputLength &&\n (input.charCodeAt(offset) | TO_LOWER_BIT) === CharCodes.LOWER_X) {\n offset += 1;\n digitStart = offset;\n while (offset < inputLength) {\n const char = input.charCodeAt(offset);\n if (isNumber(char)) {\n cp = cp * 16 + (char - CharCodes.ZERO);\n }\n else if (isHexadecimalCharacter(char)) {\n cp = cp * 16 + ((char | TO_LOWER_BIT) - CharCodes.LOWER_A + 10);\n }\n else {\n break;\n }\n offset += 1;\n }\n }\n else {\n while (offset < inputLength) {\n const digit = input.charCodeAt(offset) - CharCodes.ZERO;\n if (digit >>> 0 > 9)\n break;\n cp = cp * 10 + digit;\n offset += 1;\n }\n }\n if (offset === digitStart)\n return 0;\n // Include the semicolon in consumed when present.\n if (offset < inputLength && input.charCodeAt(offset) === CharCodes.SEMI) {\n offset += 1;\n }\n /*\n * Clamp out-of-range values to 0x110000 so they fit the 21-bit field\n * and decode to U+FFFD. Lengths at or above CONSUMED_OVERFLOW use the\n * side channel described with the packing constants.\n */\n if (cp > 0x10_ff_ff)\n cp = 0x11_00_00;\n let consumed = offset - numberStart;\n if (consumed >= CONSUMED_OVERFLOW) {\n // eslint-disable-next-line unicorn/no-top-level-assignment-in-function -- deliberate side channel, see `longNumericConsumed`\n longNumericConsumed = consumed;\n consumed = CONSUMED_OVERFLOW;\n }\n return (consumed << CONSUMED_SHIFT) | cp;\n}\n/**\n * Decode all entities in `input` using the HTML trie.\n *\n * Hard-wired to `htmlDecodeTree`: the inline root navigation below assumes\n * the HTML root's jump-table shape, so this must not be generalized to\n * other tries (the XML trie's dictionary root would silently match no\n * entities — `decodeXML` has its own hand-coded fast path instead).\n * @param input The string to decode.\n * @param isStrict Only match semicolon-terminated entities.\n * @param isAttribute Whether to apply attribute-specific parsing rules (disallowing certain non-semicolon terminators).\n * @returns The decoded string.\n */\nfunction decodeWithTrie(input, isStrict, isAttribute) {\n const decodeTree = htmlDecodeTree;\n // Fast path: no entities at all — return input without any allocation.\n let offset = input.indexOf(\"&\");\n if (offset < 0)\n return input;\n const inputLength = input.length;\n /*\n * `chunkStart` marks the start of the next pending slice. Rejected\n * entities don't advance it, so consecutive rejections are stitched\n * into a single `slice` once a real match (or end of input) is hit.\n */\n let chunkStart = 0;\n let result = \"\";\n /*\n * Root navigation fields, hoisted out of the per-entity loop. The HTML\n * root is a multi-branch jump-table covering [A-Za-z]; see the inline\n * first-iteration comment below.\n */\n const root = decodeTree[0];\n const rootJumpOffset = root & BinTrieFlags.JUMP_TABLE;\n const rootBranchCount = (root & BinTrieFlags.BRANCH_LENGTH) >> 7;\n do {\n const entityStart = offset + 1;\n // Quick check: entity names must start with [A-Za-z], numeric with #.\n const firstChar = input.charCodeAt(entityStart);\n let consumed;\n let value;\n if (firstChar === CharCodes.NUM) {\n const packed = parseNumericEntity(input, entityStart, inputLength);\n consumed = unpackConsumed(packed);\n // In strict mode, require semicolon termination.\n if (isStrict &&\n consumed > 0 &&\n input.charCodeAt(entityStart + consumed - 1) !== CharCodes.SEMI) {\n consumed = 0;\n }\n value =\n consumed === 0\n ? \"\"\n : codePointToString(packed & CODE_POINT_MASK);\n }\n else if (isAlpha(firstChar)) {\n consumed = 0;\n value = \"\";\n /*\n * The generator guarantees a jump-table root. Consume the first\n * character directly, then walk from its child.\n */\n const rootSlotIndex = firstChar - rootJumpOffset;\n let nodeIndex;\n if (rootSlotIndex >>> 0 < rootBranchCount) {\n const stored = decodeTree[1 + rootSlotIndex];\n nodeIndex =\n stored === 0 ? -1 : (rootBranchCount + stored) & 0xff_ff;\n }\n else {\n nodeIndex = -1;\n }\n /*\n * Best legacy (no-semicolon) match so far, as trie coordinates.\n * Deferring `readTrieValue` to the end avoids allocating a\n * string for matches that longer matches supersede.\n */\n let bestNodeIndex = 0;\n let bestValueLength = 0;\n let current = nodeIndex < 0 ? 0 : decodeTree[nodeIndex];\n let index = entityStart + 1;\n /*\n * Walk the trie from the root child. The `trie` label lets the\n * inner descent and compact-run loops abandon the entity (and\n * fall through to the legacy/reject handling) directly.\n */\n trie: while (index < inputLength) {\n /*\n * Inline value-less jump tables and single branches. A miss\n * falls through to the recorded legacy match or rejection.\n */\n while (\n // Value-less, non-run node with a nonzero jump offset.\n (current &\n (BinTrieFlags.VALUE_LENGTH | BinTrieFlags.FLAG13)) ===\n 0 &&\n (current & BinTrieFlags.JUMP_TABLE) !== 0) {\n const jumpOffset = current & BinTrieFlags.JUMP_TABLE;\n const branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;\n if (branchCount === 0) {\n // Single branch encoded inline in the jump offset bits.\n if (input.charCodeAt(index) !== jumpOffset)\n break trie;\n nodeIndex += 1;\n }\n else {\n const slot = input.charCodeAt(index) - jumpOffset;\n if (slot >>> 0 >= branchCount)\n break trie;\n const stored = decodeTree[nodeIndex + 1 + slot];\n if (stored === 0)\n break trie;\n // End-relative: branch data ends at nodeIndex+1+branchCount.\n nodeIndex =\n (nodeIndex + branchCount + stored) & 0xff_ff;\n }\n current = decodeTree[nodeIndex];\n index += 1;\n /*\n * `charCodeAt` past the end returns NaN, which would\n * alias to slot 0 after `>>> 0` — bail out explicitly.\n */\n if (index >= inputLength)\n break trie;\n }\n // FLAG13 without a value marks a compact run.\n if ((current &\n (BinTrieFlags.VALUE_LENGTH | BinTrieFlags.FLAG13)) ===\n BinTrieFlags.FLAG13) {\n const runLength = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;\n // Check first char (stored in JUMP_TABLE bits).\n if (input.charCodeAt(index) !==\n (current & BinTrieFlags.JUMP_TABLE)) {\n // eslint-disable-next-line unicorn/no-break-in-nested-loop\n break;\n }\n index += 1;\n // Check remaining characters (packed two per uint16 word).\n const remaining = runLength - 1;\n let wordIndex = nodeIndex + 1;\n let charIndexInPacked = 0;\n /*\n * Process pairs: read one packed word, compare low byte then high byte.\n * No explicit bounds check needed — charCodeAt returns NaN for OOB,\n * which never equals an integer, so the mismatch break fires naturally.\n */\n for (; charIndexInPacked + 1 < remaining; charIndexInPacked += 2) {\n const packed = decodeTree[wordIndex];\n if (input.charCodeAt(index) !== (packed & 0xff))\n break trie;\n index += 1;\n if (input.charCodeAt(index) !== ((packed >> 8) & 0xff))\n break trie;\n index += 1;\n wordIndex += 1;\n }\n // Handle odd trailing char.\n if (charIndexInPacked < remaining) {\n if (input.charCodeAt(index) !==\n (decodeTree[wordIndex] & 0xff))\n // eslint-disable-next-line unicorn/no-break-in-nested-loop\n break;\n index += 1;\n }\n nodeIndex += 1 + (runLength >> 1);\n current = decodeTree[nodeIndex];\n // eslint-disable-next-line unicorn/no-break-in-nested-loop\n continue;\n }\n // Header plus out-of-line value words; 0 means no value.\n const valueLength = current >>> 14;\n const char = input.charCodeAt(index);\n /*\n * Check current node for a value before navigating.\n * This handles both: (a) values reached via compact runs on the\n * previous iteration, and (b) values at regular branch targets.\n */\n if (valueLength !== 0) {\n // If char is `;`, emit immediately.\n if (char === CharCodes.SEMI) {\n consumed = index - entityStart + 1;\n // Inline leaves carry the value in the low 13 bits.\n value =\n valueLength === 1\n ? String.fromCharCode(current & BinTrieFlags.VALUE_MASK)\n : readTrieValue(decodeTree, nodeIndex, valueLength);\n // eslint-disable-next-line unicorn/no-break-in-nested-loop\n break;\n }\n // Record non-terminated (legacy) match (FLAG13 clear = semicolon optional).\n if (!isStrict && (current & BinTrieFlags.FLAG13) === 0) {\n consumed = index - entityStart;\n bestNodeIndex = nodeIndex;\n bestValueLength = valueLength;\n }\n /*\n * A valueLength of 1 means the value is packed inline in the header\n * word — these are always leaf nodes with no branches, so we can\n * stop walking the trie.\n */\n // eslint-disable-next-line unicorn/no-break-in-nested-loop\n if (valueLength === 1)\n break;\n }\n // Navigate to the next node (valueLength || 1: skip past value words, minimum 1 for header).\n const next = determineBranch(decodeTree, current, nodeIndex + (valueLength || 1), char);\n // eslint-disable-next-line unicorn/no-break-in-nested-loop\n if (next < 0)\n break;\n nodeIndex = next;\n current = decodeTree[nodeIndex];\n index += 1;\n }\n /*\n * Post-loop: if the semicolon path didn't set value,\n * check for a final legacy match. The last navigation may\n * have landed on a legacy node whose value hasn't been\n * recorded yet (loop exited before the top-of-loop check\n * could run).\n */\n if (value === \"\") {\n const finalVL = current >>> 14;\n if (finalVL !== 0 &&\n !isStrict &&\n (current & BinTrieFlags.FLAG13) === 0) {\n consumed = index - entityStart;\n bestNodeIndex = nodeIndex;\n bestValueLength = finalVL;\n }\n if (consumed > 0) {\n value = readTrieValue(decodeTree, bestNodeIndex, bestValueLength);\n }\n }\n }\n else {\n consumed = 0;\n value = \"\";\n }\n /*\n * The attribute end-char rule (HTML spec §13.2.5.73) only applies to\n * unterminated *named* references. Semicolon-terminated entities and\n * numeric entities are always accepted, matching EntityDecoder behavior.\n *\n * When `attribute` is false (the common case), short-circuit skips all\n * the unterminated-named checks entirely.\n */\n if (consumed === 0 ||\n (isAttribute &&\n firstChar !== CharCodes.NUM &&\n input.charCodeAt(entityStart + consumed - 1) !==\n CharCodes.SEMI &&\n entityStart + consumed < inputLength &&\n isEntityInAttributeInvalidEnd(input.charCodeAt(entityStart + consumed)))) {\n // Rejected: leave `&` in the pending chunk, scan past it.\n offset = entityStart;\n }\n else {\n if (chunkStart < offset) {\n result += input.slice(chunkStart, offset);\n }\n result += value;\n offset = chunkStart = entityStart + consumed;\n }\n /*\n * Adjacent entities (`&x;&y;`) are common in entity-dense input;\n * checking the single character at `offset` first skips the\n * `indexOf` call (and its per-call overhead) for that case.\n */\n if (input.charCodeAt(offset) !== CharCodes.AMP) {\n offset = input.indexOf(\"&\", offset);\n }\n } while (offset >= 0);\n return result + input.slice(chunkStart);\n}\n/**\n * Decodes an HTML string.\n * @param htmlString The string to decode.\n * @param mode The decoding mode.\n * @returns The decoded string.\n */\nexport function decodeHTML(htmlString, mode = DecodingMode.Legacy) {\n return decodeWithTrie(htmlString, mode === DecodingMode.Strict, mode === DecodingMode.Attribute);\n}\n/**\n * Decodes an HTML string in an attribute.\n * @param htmlAttribute The string to decode.\n * @returns The decoded string.\n */\nexport function decodeHTMLAttribute(htmlAttribute) {\n return decodeWithTrie(htmlAttribute, false, true);\n}\n/**\n * Decodes an HTML string, requiring all entities to be terminated by a semicolon.\n * @param htmlString The string to decode.\n * @returns The decoded string.\n */\nexport function decodeHTMLStrict(htmlString) {\n return decodeWithTrie(htmlString, true, false);\n}\n/**\n * Decodes an XML string, requiring all entities to be terminated by a semicolon.\n *\n * Uses a hand-coded fast path for the 5 XML named entities (amp, lt, gt,\n * quot, apos) plus numeric entities, bypassing the trie entirely.\n * @param xmlString The string to decode.\n * @returns The decoded string.\n */\nexport function decodeXML(xmlString) {\n let offset = xmlString.indexOf(\"&\");\n if (offset < 0)\n return xmlString;\n let lastIndex = 0;\n let result = \"\";\n do {\n const start = offset + 1;\n let consumed = 0;\n let value = \"\";\n const c1 = xmlString.charCodeAt(start);\n if (c1 === CharCodes.NUM) {\n const packed = parseNumericEntity(xmlString, start, xmlString.length);\n consumed = unpackConsumed(packed);\n // XML is always strict — require semicolon.\n if (consumed === 0 ||\n xmlString.charCodeAt(start + consumed - 1) !== CharCodes.SEMI) {\n consumed = 0;\n }\n else {\n const codePoint = packed & CODE_POINT_MASK;\n // Nonzero BMP values below the surrogate range need no replacement.\n value =\n (codePoint - 1) >>> 0 < 0xd7_ff\n ? String.fromCharCode(codePoint)\n : String.fromCodePoint(replaceCodePointXML(codePoint));\n }\n }\n else {\n /* eslint-disable unicorn/no-break-in-nested-loop -- Keep XML name dispatch inline with the decode loop. */\n switch (c1) {\n // < / >\n case 0x6c:\n case 0x67: {\n if (xmlString.charCodeAt(start + 1) === 0x74 &&\n xmlString.charCodeAt(start + 2) === CharCodes.SEMI) {\n consumed = 3;\n value = c1 === 0x6c ? \"<\" : \">\";\n }\n break;\n }\n // & / '\n case 0x61: {\n const c2 = xmlString.charCodeAt(start + 1);\n if (c2 === 0x6d &&\n xmlString.charCodeAt(start + 2) === 0x70 &&\n xmlString.charCodeAt(start + 3) === CharCodes.SEMI) {\n consumed = 4;\n value = \"&\";\n }\n else if (c2 === 0x70 &&\n xmlString.charCodeAt(start + 2) === 0x6f &&\n xmlString.charCodeAt(start + 3) === 0x73 &&\n xmlString.charCodeAt(start + 4) === CharCodes.SEMI) {\n consumed = 5;\n value = \"'\";\n }\n break;\n }\n // "\n case 0x71: {\n if (xmlString.charCodeAt(start + 1) === 0x75 &&\n xmlString.charCodeAt(start + 2) === 0x6f &&\n xmlString.charCodeAt(start + 3) === 0x74 &&\n xmlString.charCodeAt(start + 4) === CharCodes.SEMI) {\n consumed = 5;\n value = '\"';\n }\n break;\n }\n }\n /* eslint-enable unicorn/no-break-in-nested-loop */\n }\n if (consumed > 0) {\n if (lastIndex < offset)\n result += xmlString.slice(lastIndex, offset);\n result += value;\n offset = lastIndex = start + consumed;\n }\n else {\n offset = start;\n }\n /*\n * Adjacent entities (`&x;&y;`) are common in entity-dense input;\n * checking the single character at `lastIndex` first skips the\n * `indexOf` call (and its per-call overhead) for that case.\n */\n offset =\n xmlString.charCodeAt(offset) === CharCodes.AMP\n ? offset\n : xmlString.indexOf(\"&\", offset);\n } while (offset >= 0);\n return result + xmlString.slice(lastIndex);\n}\nexport { replaceCodePoint, replaceCodePointXML, } from \"./decode-codepoint.js\";\n// Re-export for use by eg. htmlparser2\nexport { htmlDecodeTree } from \"./generated/decode-data-html.js\";\nexport { xmlDecodeTree } from \"./generated/decode-data-xml.js\";\n//# sourceMappingURL=decode.js.map","import { DecodingMode, EntityDecoder, htmlDecodeTree, xmlDecodeTree, } from \"entities/decode\";\nvar CharCodes;\n(function (CharCodes) {\n CharCodes[CharCodes[\"Tab\"] = 9] = \"Tab\";\n CharCodes[CharCodes[\"NewLine\"] = 10] = \"NewLine\";\n CharCodes[CharCodes[\"FormFeed\"] = 12] = \"FormFeed\";\n CharCodes[CharCodes[\"CarriageReturn\"] = 13] = \"CarriageReturn\";\n CharCodes[CharCodes[\"Space\"] = 32] = \"Space\";\n CharCodes[CharCodes[\"ExclamationMark\"] = 33] = \"ExclamationMark\";\n CharCodes[CharCodes[\"Number\"] = 35] = \"Number\";\n CharCodes[CharCodes[\"Amp\"] = 38] = \"Amp\";\n CharCodes[CharCodes[\"SingleQuote\"] = 39] = \"SingleQuote\";\n CharCodes[CharCodes[\"DoubleQuote\"] = 34] = \"DoubleQuote\";\n CharCodes[CharCodes[\"Dash\"] = 45] = \"Dash\";\n CharCodes[CharCodes[\"Slash\"] = 47] = \"Slash\";\n CharCodes[CharCodes[\"Zero\"] = 48] = \"Zero\";\n CharCodes[CharCodes[\"Nine\"] = 57] = \"Nine\";\n CharCodes[CharCodes[\"Semi\"] = 59] = \"Semi\";\n CharCodes[CharCodes[\"Lt\"] = 60] = \"Lt\";\n CharCodes[CharCodes[\"Eq\"] = 61] = \"Eq\";\n CharCodes[CharCodes[\"Gt\"] = 62] = \"Gt\";\n CharCodes[CharCodes[\"Questionmark\"] = 63] = \"Questionmark\";\n CharCodes[CharCodes[\"UpperA\"] = 65] = \"UpperA\";\n CharCodes[CharCodes[\"LowerA\"] = 97] = \"LowerA\";\n CharCodes[CharCodes[\"UpperF\"] = 70] = \"UpperF\";\n CharCodes[CharCodes[\"LowerF\"] = 102] = \"LowerF\";\n CharCodes[CharCodes[\"UpperZ\"] = 90] = \"UpperZ\";\n CharCodes[CharCodes[\"LowerZ\"] = 122] = \"LowerZ\";\n CharCodes[CharCodes[\"LowerX\"] = 120] = \"LowerX\";\n CharCodes[CharCodes[\"OpeningSquareBracket\"] = 91] = \"OpeningSquareBracket\";\n})(CharCodes || (CharCodes = {}));\n/** All the states the tokenizer can be in. */\nvar State;\n(function (State) {\n State[State[\"Text\"] = 1] = \"Text\";\n State[State[\"BeforeTagName\"] = 2] = \"BeforeTagName\";\n State[State[\"InTagName\"] = 3] = \"InTagName\";\n State[State[\"InSelfClosingTag\"] = 4] = \"InSelfClosingTag\";\n State[State[\"BeforeClosingTagName\"] = 5] = \"BeforeClosingTagName\";\n State[State[\"InClosingTagName\"] = 6] = \"InClosingTagName\";\n State[State[\"AfterClosingTagName\"] = 7] = \"AfterClosingTagName\";\n // Attributes\n State[State[\"BeforeAttributeName\"] = 8] = \"BeforeAttributeName\";\n State[State[\"InAttributeName\"] = 9] = \"InAttributeName\";\n State[State[\"AfterAttributeName\"] = 10] = \"AfterAttributeName\";\n State[State[\"BeforeAttributeValue\"] = 11] = \"BeforeAttributeValue\";\n State[State[\"InAttributeValueDq\"] = 12] = \"InAttributeValueDq\";\n State[State[\"InAttributeValueSq\"] = 13] = \"InAttributeValueSq\";\n State[State[\"InAttributeValueNq\"] = 14] = \"InAttributeValueNq\";\n // Declarations\n State[State[\"BeforeDeclaration\"] = 15] = \"BeforeDeclaration\";\n State[State[\"InDeclaration\"] = 16] = \"InDeclaration\";\n // Processing instructions\n State[State[\"InProcessingInstruction\"] = 17] = \"InProcessingInstruction\";\n // Comments & CDATA\n State[State[\"BeforeComment\"] = 18] = \"BeforeComment\";\n State[State[\"CDATASequence\"] = 19] = \"CDATASequence\";\n State[State[\"DeclarationSequence\"] = 20] = \"DeclarationSequence\";\n State[State[\"InSpecialComment\"] = 21] = \"InSpecialComment\";\n State[State[\"InCommentLike\"] = 22] = \"InCommentLike\";\n // Special tags\n State[State[\"SpecialStartSequence\"] = 23] = \"SpecialStartSequence\";\n State[State[\"InSpecialTag\"] = 24] = \"InSpecialTag\";\n State[State[\"InPlainText\"] = 25] = \"InPlainText\";\n State[State[\"InEntity\"] = 26] = \"InEntity\";\n})(State || (State = {}));\nfunction isWhitespace(c) {\n return (c === CharCodes.Space ||\n c === CharCodes.NewLine ||\n c === CharCodes.Tab ||\n c === CharCodes.FormFeed ||\n c === CharCodes.CarriageReturn);\n}\nfunction isEndOfTagSection(c) {\n return c === CharCodes.Slash || c === CharCodes.Gt || isWhitespace(c);\n}\nfunction isASCIIAlpha(c) {\n return ((c >= CharCodes.LowerA && c <= CharCodes.LowerZ) ||\n (c >= CharCodes.UpperA && c <= CharCodes.UpperZ));\n}\n/**\n * Quote style used for parsed attributes.\n */\nexport var QuoteType;\n(function (QuoteType) {\n QuoteType[QuoteType[\"NoValue\"] = 0] = \"NoValue\";\n QuoteType[QuoteType[\"Unquoted\"] = 1] = \"Unquoted\";\n QuoteType[QuoteType[\"Single\"] = 2] = \"Single\";\n QuoteType[QuoteType[\"Double\"] = 3] = \"Double\";\n})(QuoteType || (QuoteType = {}));\n/**\n * Sequences used to match longer strings.\n *\n * We don't have `Script`, `Style`, or `Title` here. Instead, we re-use the *End\n * sequences with an increased offset.\n */\nconst Sequences = {\n Empty: new Uint8Array(0),\n Cdata: new Uint8Array([0x43, 0x44, 0x41, 0x54, 0x41, 0x5b]), // CDATA[\n CdataEnd: new Uint8Array([0x5d, 0x5d, 0x3e]), // ]]>\n CommentEnd: new Uint8Array([0x2d, 0x2d, 0x21, 0x3e]), // `--!>`\n Doctype: new Uint8Array([0x64, 0x6f, 0x63, 0x74, 0x79, 0x70, 0x65]), // `doctype`\n IframeEnd: new Uint8Array([0x3c, 0x2f, 0x69, 0x66, 0x72, 0x61, 0x6d, 0x65]), // `</iframe`\n NoembedEnd: new Uint8Array([\n 0x3c, 0x2f, 0x6e, 0x6f, 0x65, 0x6d, 0x62, 0x65, 0x64,\n ]), // `</noembed`\n NoframesEnd: new Uint8Array([\n 0x3c, 0x2f, 0x6e, 0x6f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73,\n ]), // `</noframes`\n Plaintext: new Uint8Array([\n 0x3c, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74,\n ]), // `</plaintext`\n ScriptEnd: new Uint8Array([0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74]), // `</script`\n StyleEnd: new Uint8Array([0x3c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65]), // `</style`\n TitleEnd: new Uint8Array([0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65]), // `</title`\n TextareaEnd: new Uint8Array([\n 0x3c, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61,\n ]), // `</textarea`\n XmpEnd: new Uint8Array([0x3c, 0x2f, 0x78, 0x6d, 0x70]), // `</xmp`\n};\n/**\n * Maps the first lowercase character of an HTML tag name to the sequence\n * used for special-tag detection. All sequences share a common layout\n * where index 2 is the first tag-name character, so matching always\n * continues from offset 3.\n */\nconst specialStartSequences = new Map([\n [Sequences.IframeEnd[2], Sequences.IframeEnd],\n [Sequences.NoembedEnd[2], Sequences.NoembedEnd],\n [Sequences.Plaintext[2], Sequences.Plaintext],\n [Sequences.ScriptEnd[2], Sequences.ScriptEnd],\n [Sequences.TitleEnd[2], Sequences.TitleEnd],\n [Sequences.XmpEnd[2], Sequences.XmpEnd],\n]);\n/**\n * Tokenizer implementation used by `Parser`.\n */\nexport default class Tokenizer {\n cbs;\n /** The current state the tokenizer is in. */\n state = State.Text;\n /** The read buffer. */\n buffer = \"\";\n /** The beginning of the section that is currently being read. */\n sectionStart = 0;\n /** The index within the buffer that we are currently looking at. */\n index = 0;\n /** The start of the last entity. */\n entityStart = 0;\n /** Some behavior, eg. when decoding entities, is done while we are in another state. This keeps track of the other state type. */\n baseState = State.Text;\n /** For special parsing behavior inside of script and style tags. */\n isSpecial = false;\n /** Indicates whether the tokenizer has been paused. */\n running = true;\n /** The offset of the current buffer. */\n offset = 0;\n xmlMode;\n decodeEntities;\n recognizeSelfClosing;\n entityDecoder;\n constructor({ xmlMode = false, decodeEntities = true, recognizeSelfClosing = xmlMode, }, cbs) {\n this.cbs = cbs;\n this.xmlMode = xmlMode;\n this.decodeEntities = decodeEntities;\n this.recognizeSelfClosing = recognizeSelfClosing;\n this.entityDecoder = new EntityDecoder(xmlMode ? xmlDecodeTree : htmlDecodeTree, (cp, consumed) => this.emitCodePoint(cp, consumed));\n }\n reset() {\n this.state = State.Text;\n this.buffer = \"\";\n this.sectionStart = 0;\n this.index = 0;\n this.baseState = State.Text;\n this.isSpecial = false;\n this.currentSequence = Sequences.Empty;\n this.sequenceIndex = 0;\n this.running = true;\n this.offset = 0;\n }\n write(chunk) {\n this.offset += this.buffer.length;\n this.buffer = chunk;\n this.parse();\n }\n end() {\n if (this.running)\n this.finish();\n }\n pause() {\n this.running = false;\n }\n resume() {\n this.running = true;\n if (this.index < this.buffer.length + this.offset) {\n this.parse();\n }\n }\n stateText(c) {\n if (c === CharCodes.Lt ||\n (!this.decodeEntities && this.fastForwardTo(CharCodes.Lt))) {\n if (this.index > this.sectionStart) {\n this.cbs.ontext(this.sectionStart, this.index);\n }\n this.state = State.BeforeTagName;\n this.sectionStart = this.index;\n }\n else if (this.decodeEntities && c === CharCodes.Amp) {\n this.startEntity();\n }\n }\n currentSequence = Sequences.Empty;\n sequenceIndex = 0;\n enterTagBody() {\n if (this.currentSequence === Sequences.Plaintext) {\n this.currentSequence = Sequences.Empty;\n this.state = State.InPlainText;\n }\n else if (this.isSpecial) {\n this.state = State.InSpecialTag;\n this.sequenceIndex = 0;\n }\n else {\n this.state = State.Text;\n }\n }\n /**\n * Match the opening tag name against an HTML text-only tag sequence.\n *\n * Some tags share an initial prefix (`script`/`style`, `title`/`textarea`,\n * `noembed`/`noframes`), so we may switch to an alternate sequence at the\n * first distinguishing byte. On a successful full match we fall back to\n * the normal tag-name state; a later `>` will enter raw-text, RCDATA, or\n * plaintext mode based on `currentSequence` / `isSpecial`.\n * @param c Current character code point.\n */\n stateSpecialStartSequence(c) {\n const lower = c | 0x20;\n // Still matching — check for an alternate sequence at branch points.\n if (this.sequenceIndex < this.currentSequence.length) {\n if (lower === this.currentSequence[this.sequenceIndex]) {\n this.sequenceIndex++;\n return;\n }\n if (this.sequenceIndex === 3) {\n if (this.currentSequence === Sequences.ScriptEnd &&\n lower === Sequences.StyleEnd[3]) {\n this.currentSequence = Sequences.StyleEnd;\n this.sequenceIndex = 4;\n return;\n }\n if (this.currentSequence === Sequences.TitleEnd &&\n lower === Sequences.TextareaEnd[3]) {\n this.currentSequence = Sequences.TextareaEnd;\n this.sequenceIndex = 4;\n return;\n }\n }\n else if (this.sequenceIndex === 4 &&\n this.currentSequence === Sequences.NoembedEnd &&\n lower === Sequences.NoframesEnd[4]) {\n this.currentSequence = Sequences.NoframesEnd;\n this.sequenceIndex = 5;\n return;\n }\n }\n else if (isEndOfTagSection(c)) {\n // Full match on a valid tag boundary — keep the sequence.\n this.sequenceIndex = 0;\n this.state = State.InTagName;\n this.stateInTagName(c);\n return;\n }\n // No match — abandon special-tag detection.\n this.isSpecial = false;\n this.currentSequence = Sequences.Empty;\n this.sequenceIndex = 0;\n this.state = State.InTagName;\n this.stateInTagName(c);\n }\n stateCDATASequence(c) {\n if (c === Sequences.Cdata[this.sequenceIndex]) {\n if (++this.sequenceIndex === Sequences.Cdata.length) {\n this.state = State.InCommentLike;\n this.currentSequence = Sequences.CdataEnd;\n this.sequenceIndex = 0;\n this.sectionStart = this.index + 1;\n }\n }\n else {\n this.sequenceIndex = 0;\n if (this.xmlMode) {\n this.state = State.InDeclaration;\n this.stateInDeclaration(c); // Reconsume the character\n }\n else {\n this.state = State.InSpecialComment;\n this.stateInSpecialComment(c); // Reconsume the character\n }\n }\n }\n /**\n * When we wait for one specific character, we can speed things up\n * by skipping through the buffer until we find it.\n * @param c Current character code point.\n * @returns Whether the character was found.\n */\n fastForwardTo(c) {\n while (++this.index < this.buffer.length + this.offset) {\n if (this.buffer.charCodeAt(this.index - this.offset) === c) {\n return true;\n }\n }\n /*\n * We increment the index at the end of the `parse` loop,\n * so set it to `buffer.length - 1` here.\n *\n * TODO: Refactor `parse` to increment index before calling states.\n */\n this.index = this.buffer.length + this.offset - 1;\n return false;\n }\n /**\n * Emit a comment token and return to the text state.\n * @param offset Number of characters in the end sequence that have already been matched.\n */\n emitComment(offset) {\n this.cbs.oncomment(this.sectionStart, this.index, offset);\n this.sequenceIndex = 0;\n this.sectionStart = this.index + 1;\n this.state = State.Text;\n }\n /**\n * Comments and CDATA end with `-->` and `]]>`.\n *\n * Their common qualities are:\n * - Their end sequences have a distinct character they start with.\n * - That character is then repeated, so we have to check multiple repeats.\n * - All characters but the start character of the sequence can be skipped.\n * @param c Current character code point.\n */\n stateInCommentLike(c) {\n if (!this.xmlMode &&\n this.currentSequence === Sequences.CommentEnd &&\n this.sequenceIndex <= 1 &&\n /*\n * We're still at the very start of the comment: the only\n * characters consumed since `<!--` are the dashes that\n * advanced sequenceIndex (0 for `<!-->`, 1 for `<!--->`).\n */\n this.index === this.sectionStart + this.sequenceIndex &&\n c === CharCodes.Gt) {\n // Abruptly closed empty HTML comment.\n this.emitComment(this.sequenceIndex);\n }\n else if (this.currentSequence === Sequences.CommentEnd &&\n this.sequenceIndex === 2 &&\n c === CharCodes.Gt) {\n // `!` is optional here, so the same sequence also accepts `-->`.\n this.emitComment(2);\n }\n else if (this.currentSequence === Sequences.CommentEnd &&\n this.sequenceIndex === this.currentSequence.length - 1 &&\n c !== CharCodes.Gt) {\n this.sequenceIndex = Number(c === CharCodes.Dash);\n }\n else if (c === this.currentSequence[this.sequenceIndex]) {\n if (++this.sequenceIndex === this.currentSequence.length) {\n if (this.currentSequence === Sequences.CdataEnd) {\n this.cbs.oncdata(this.sectionStart, this.index, 2);\n }\n else {\n this.cbs.oncomment(this.sectionStart, this.index, 3);\n }\n this.sequenceIndex = 0;\n this.sectionStart = this.index + 1;\n this.state = State.Text;\n }\n }\n else if (this.sequenceIndex === 0) {\n // Fast-forward to the first character of the sequence\n if (this.fastForwardTo(this.currentSequence[0])) {\n this.sequenceIndex = 1;\n }\n }\n else if (c !== this.currentSequence[this.sequenceIndex - 1]) {\n // Allow long sequences, eg. --->, ]]]>\n this.sequenceIndex = 0;\n }\n }\n /**\n * HTML only allows ASCII alpha characters (a-z and A-Z) at the beginning of a tag name.\n *\n * XML allows a lot more characters here (@see https://www.w3.org/TR/REC-xml/#NT-NameStartChar).\n * We allow anything that wouldn't end the tag.\n * @param c Current character code point.\n */\n isTagStartChar(c) {\n return this.xmlMode ? !isEndOfTagSection(c) : isASCIIAlpha(c);\n }\n /**\n * Scan raw-text / RCDATA content for the matching end tag.\n *\n * For RCDATA tags (`<title>`, `<textarea>`) entities are decoded inline.\n * For raw-text tags (`<script>`, `<style>`, etc.) we fast-forward to `<`.\n * @param c Current character code point.\n */\n stateInSpecialTag(c) {\n if (this.sequenceIndex === this.currentSequence.length) {\n if (isEndOfTagSection(c)) {\n const endOfText = this.index - this.currentSequence.length;\n if (this.sectionStart < endOfText) {\n // Spoof the index so that reported locations match up.\n const actualIndex = this.index;\n this.index = endOfText;\n this.cbs.ontext(this.sectionStart, endOfText);\n this.index = actualIndex;\n }\n this.isSpecial = false;\n this.sectionStart = endOfText + 2; // Skip over the `</`\n this.stateInClosingTagName(c);\n return; // We are done; skip the rest of the function.\n }\n this.sequenceIndex = 0;\n }\n if ((c | 0x20) === this.currentSequence[this.sequenceIndex]) {\n this.sequenceIndex += 1;\n }\n else if (this.sequenceIndex === 0) {\n if (this.currentSequence === Sequences.TitleEnd ||\n this.currentSequence === Sequences.TextareaEnd) {\n // RCDATA tags have to parse entities while still looking for their end tag.\n if (this.decodeEntities && c === CharCodes.Amp) {\n this.startEntity();\n }\n }\n else if (this.fastForwardTo(CharCodes.Lt)) {\n // Outside of RCDATA tags, we can fast-forward.\n this.sequenceIndex = 1;\n }\n }\n else {\n // If we see a `<`, set the sequence index to 1; useful for eg. `<</script>`.\n this.sequenceIndex = Number(c === CharCodes.Lt);\n }\n }\n stateBeforeTagName(c) {\n if (c === CharCodes.ExclamationMark) {\n this.state = State.BeforeDeclaration;\n this.sectionStart = this.index + 1;\n }\n else if (c === CharCodes.Questionmark) {\n if (this.xmlMode) {\n this.state = State.InProcessingInstruction;\n this.sequenceIndex = 0;\n this.sectionStart = this.index + 1;\n }\n else {\n this.state = State.InSpecialComment;\n this.sectionStart = this.index;\n }\n }\n else if (this.isTagStartChar(c)) {\n this.sectionStart = this.index;\n const special = this.xmlMode || this.cbs.isInForeignContext?.()\n ? undefined\n : specialStartSequences.get(c | 0x20);\n if (special === undefined) {\n this.state = State.InTagName;\n }\n else {\n this.isSpecial = true;\n this.currentSequence = special;\n this.sequenceIndex = 3;\n this.state = State.SpecialStartSequence;\n }\n }\n else if (c === CharCodes.Slash) {\n this.state = State.BeforeClosingTagName;\n }\n else {\n this.state = State.Text;\n this.stateText(c);\n }\n }\n stateInTagName(c) {\n if (isEndOfTagSection(c)) {\n this.cbs.onopentagname(this.sectionStart, this.index);\n this.sectionStart = -1;\n this.state = State.BeforeAttributeName;\n this.stateBeforeAttributeName(c);\n }\n }\n stateBeforeClosingTagName(c) {\n if (isWhitespace(c)) {\n if (this.xmlMode) {\n // Ignore\n }\n else {\n this.state = State.InSpecialComment;\n this.sectionStart = this.index;\n }\n }\n else if (c === CharCodes.Gt) {\n this.state = State.Text;\n if (!this.xmlMode) {\n this.sectionStart = this.index + 1;\n }\n }\n else {\n this.state = this.isTagStartChar(c)\n ? State.InClosingTagName\n : State.InSpecialComment;\n this.sectionStart = this.index;\n }\n }\n stateInClosingTagName(c) {\n if (isEndOfTagSection(c)) {\n this.cbs.onclosetag(this.sectionStart, this.index);\n this.sectionStart = -1;\n this.state = State.AfterClosingTagName;\n this.stateAfterClosingTagName(c);\n }\n }\n stateAfterClosingTagName(c) {\n // Skip everything until \">\"\n if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {\n this.state = State.Text;\n this.sectionStart = this.index + 1;\n }\n }\n stateBeforeAttributeName(c) {\n if (c === CharCodes.Gt) {\n this.cbs.onopentagend(this.index);\n this.enterTagBody();\n this.sectionStart = this.index + 1;\n }\n else if (c === CharCodes.Slash) {\n this.state = State.InSelfClosingTag;\n }\n else if (!isWhitespace(c)) {\n this.state = State.InAttributeName;\n this.sectionStart = this.index;\n }\n }\n /**\n * Handle `/` before `>` in an opening tag.\n *\n * In HTML mode, text-only tags ignore the self-closing flag and still enter\n * their raw-text/RCDATA/plaintext state unless self-closing tags are being\n * recognized. In XML mode, or for ordinary tags, the tokenizer returns to\n * regular text parsing after emitting the self-closing callback.\n * @param c Current character code point.\n */\n stateInSelfClosingTag(c) {\n if (c === CharCodes.Gt) {\n this.cbs.onselfclosingtag(this.index);\n this.sectionStart = this.index + 1;\n if (!this.recognizeSelfClosing) {\n this.enterTagBody();\n return;\n }\n this.state = State.Text;\n this.isSpecial = false; // Reset special state, in case of self-closing special tags\n this.currentSequence = Sequences.Empty;\n }\n else if (!isWhitespace(c)) {\n this.state = State.BeforeAttributeName;\n this.stateBeforeAttributeName(c);\n }\n }\n stateInAttributeName(c) {\n if (c === CharCodes.Eq || isEndOfTagSection(c)) {\n this.cbs.onattribname(this.sectionStart, this.index);\n this.sectionStart = this.index;\n this.state = State.AfterAttributeName;\n this.stateAfterAttributeName(c);\n }\n }\n stateAfterAttributeName(c) {\n if (c === CharCodes.Eq) {\n this.state = State.BeforeAttributeValue;\n }\n else if (c === CharCodes.Slash || c === CharCodes.Gt) {\n this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);\n this.sectionStart = -1;\n this.state = State.BeforeAttributeName;\n this.stateBeforeAttributeName(c);\n }\n else if (!isWhitespace(c)) {\n this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);\n this.state = State.InAttributeName;\n this.sectionStart = this.index;\n }\n }\n stateBeforeAttributeValue(c) {\n if (c === CharCodes.DoubleQuote) {\n this.state = State.InAttributeValueDq;\n this.sectionStart = this.index + 1;\n }\n else if (c === CharCodes.SingleQuote) {\n this.state = State.InAttributeValueSq;\n this.sectionStart = this.index + 1;\n }\n else if (!isWhitespace(c)) {\n this.sectionStart = this.index;\n this.state = State.InAttributeValueNq;\n this.stateInAttributeValueNoQuotes(c); // Reconsume token\n }\n }\n handleInAttributeValue(c, quote) {\n if (c === quote ||\n (!this.decodeEntities && this.fastForwardTo(quote))) {\n this.cbs.onattribdata(this.sectionStart, this.index);\n this.sectionStart = -1;\n this.cbs.onattribend(quote === CharCodes.DoubleQuote\n ? QuoteType.Double\n : QuoteType.Single, this.index + 1);\n this.state = State.BeforeAttributeName;\n }\n else if (this.decodeEntities && c === CharCodes.Amp) {\n this.startEntity();\n }\n }\n stateInAttributeValueDoubleQuotes(c) {\n this.handleInAttributeValue(c, CharCodes.DoubleQuote);\n }\n stateInAttributeValueSingleQuotes(c) {\n this.handleInAttributeValue(c, CharCodes.SingleQuote);\n }\n stateInAttributeValueNoQuotes(c) {\n if (isWhitespace(c) || c === CharCodes.Gt) {\n this.cbs.onattribdata(this.sectionStart, this.index);\n this.sectionStart = -1;\n this.cbs.onattribend(QuoteType.Unquoted, this.index);\n this.state = State.BeforeAttributeName;\n this.stateBeforeAttributeName(c);\n }\n else if (this.decodeEntities && c === CharCodes.Amp) {\n this.startEntity();\n }\n }\n /**\n * Distinguish between CDATA, declarations, HTML comments, and HTML bogus\n * comments after `<!`.\n *\n * In HTML mode, only real comments and doctypes stay on declaration paths;\n * everything else becomes a bogus comment terminated by the next `>`.\n * @param c Current character code point.\n */\n stateBeforeDeclaration(c) {\n if (c === CharCodes.OpeningSquareBracket) {\n this.state = State.CDATASequence;\n this.sequenceIndex = 0;\n }\n else if (this.xmlMode) {\n this.state =\n c === CharCodes.Dash\n ? State.BeforeComment\n : State.InDeclaration;\n }\n else if ((c | 0x20) === Sequences.Doctype[0]) {\n this.state = State.DeclarationSequence;\n this.currentSequence = Sequences.Doctype;\n this.sequenceIndex = 1;\n }\n else if (c === CharCodes.Gt) {\n this.cbs.oncomment(this.sectionStart, this.index, 0);\n this.state = State.Text;\n this.sectionStart = this.index + 1;\n }\n else if (c === CharCodes.Dash) {\n this.state = State.BeforeComment;\n }\n else {\n this.state = State.InSpecialComment;\n }\n }\n /**\n * Continue matching `doctype` after `<!d`.\n *\n * A full `doctype` match stays on the declaration path; any other name falls\n * back to an HTML bogus comment, which matches browser behavior for\n * non-doctype `<!...>` constructs.\n * @param c Current character code point.\n */\n stateDeclarationSequence(c) {\n if (this.sequenceIndex === this.currentSequence.length) {\n this.state = State.InDeclaration;\n this.stateInDeclaration(c);\n }\n else if ((c | 0x20) === this.currentSequence[this.sequenceIndex]) {\n this.sequenceIndex += 1;\n }\n else if (c === CharCodes.Gt) {\n this.cbs.oncomment(this.sectionStart, this.index, 0);\n this.state = State.Text;\n this.sectionStart = this.index + 1;\n }\n else {\n this.state = State.InSpecialComment;\n }\n }\n stateInDeclaration(c) {\n if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {\n this.cbs.ondeclaration(this.sectionStart, this.index);\n this.state = State.Text;\n this.sectionStart = this.index + 1;\n }\n }\n /**\n * XML processing instructions (`<?...?>`).\n *\n * In HTML mode `<?` is routed to `InSpecialComment` instead, so this\n * state is only reachable in XML mode.\n * @param c Current character code point.\n */\n stateInProcessingInstruction(c) {\n if (c === CharCodes.Questionmark) {\n // Remember that we just consumed `?`, so the next `>` closes the PI.\n this.sequenceIndex = 1;\n }\n else if (c === CharCodes.Gt && this.sequenceIndex === 1) {\n this.cbs.onprocessinginstruction(this.sectionStart, this.index - 1);\n this.sequenceIndex = 0;\n this.state = State.Text;\n this.sectionStart = this.index + 1;\n }\n else {\n // Keep scanning for the next `?`, which can start a closing `?>`.\n this.sequenceIndex = Number(this.fastForwardTo(CharCodes.Questionmark));\n }\n }\n stateBeforeComment(c) {\n if (c === CharCodes.Dash) {\n this.state = State.InCommentLike;\n this.currentSequence = Sequences.CommentEnd;\n this.sequenceIndex = 0;\n this.sectionStart = this.index + 1;\n }\n else if (this.xmlMode) {\n this.state = State.InDeclaration;\n }\n else if (c === CharCodes.Gt) {\n this.cbs.oncomment(this.sectionStart, this.index, 0);\n this.state = State.Text;\n this.sectionStart = this.index + 1;\n }\n else {\n this.state = State.InSpecialComment;\n }\n }\n stateInSpecialComment(c) {\n if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {\n this.cbs.oncomment(this.sectionStart, this.index, 0);\n this.state = State.Text;\n this.sectionStart = this.index + 1;\n }\n }\n startEntity() {\n this.baseState = this.state;\n this.state = State.InEntity;\n this.entityStart = this.index;\n this.entityDecoder.startEntity(this.xmlMode\n ? DecodingMode.Strict\n : this.baseState === State.Text ||\n this.baseState === State.InSpecialTag\n ? DecodingMode.Legacy\n : DecodingMode.Attribute);\n }\n stateInEntity() {\n const indexInBuffer = this.index - this.offset;\n const length = this.entityDecoder.write(this.buffer, indexInBuffer);\n // If `length` is positive, we are done with the entity.\n if (length >= 0) {\n this.state = this.baseState;\n if (length === 0) {\n this.index -= 1;\n }\n }\n else {\n if (indexInBuffer < this.buffer.length &&\n this.buffer.charCodeAt(indexInBuffer) === CharCodes.Amp) {\n this.state = this.baseState;\n this.index -= 1;\n return;\n }\n // Mark buffer as consumed.\n this.index = this.offset + this.buffer.length - 1;\n }\n }\n /**\n * Remove data that has already been consumed from the buffer.\n */\n cleanup() {\n // If we are inside of text or attributes, emit what we already have.\n if (this.running && this.sectionStart !== this.index) {\n if (this.state === State.Text ||\n this.state === State.InPlainText ||\n (this.state === State.InSpecialTag && this.sequenceIndex === 0)) {\n this.cbs.ontext(this.sectionStart, this.index);\n this.sectionStart = this.index;\n }\n else if (this.state === State.InAttributeValueDq ||\n this.state === State.InAttributeValueSq ||\n this.state === State.InAttributeValueNq) {\n this.cbs.onattribdata(this.sectionStart, this.index);\n this.sectionStart = this.index;\n }\n }\n }\n shouldContinue() {\n return this.index < this.buffer.length + this.offset && this.running;\n }\n /**\n * Iterates through the buffer, calling the function corresponding to the current state.\n *\n * States that are more likely to be hit are higher up, as a performance improvement.\n */\n parse() {\n while (this.shouldContinue()) {\n const c = this.buffer.charCodeAt(this.index - this.offset);\n switch (this.state) {\n case State.Text: {\n this.stateText(c);\n break;\n }\n case State.InPlainText: {\n // Skip to end of buffer; cleanup() emits the text.\n this.index = this.buffer.length + this.offset - 1;\n break;\n }\n case State.SpecialStartSequence: {\n this.stateSpecialStartSequence(c);\n break;\n }\n case State.InSpecialTag: {\n this.stateInSpecialTag(c);\n break;\n }\n case State.CDATASequence: {\n this.stateCDATASequence(c);\n break;\n }\n case State.DeclarationSequence: {\n this.stateDeclarationSequence(c);\n break;\n }\n case State.InAttributeValueDq: {\n this.stateInAttributeValueDoubleQuotes(c);\n break;\n }\n case State.InAttributeName: {\n this.stateInAttributeName(c);\n break;\n }\n case State.InCommentLike: {\n this.stateInCommentLike(c);\n break;\n }\n case State.InSpecialComment: {\n this.stateInSpecialComment(c);\n break;\n }\n case State.BeforeAttributeName: {\n this.stateBeforeAttributeName(c);\n break;\n }\n case State.InTagName: {\n this.stateInTagName(c);\n break;\n }\n case State.InClosingTagName: {\n this.stateInClosingTagName(c);\n break;\n }\n case State.BeforeTagName: {\n this.stateBeforeTagName(c);\n break;\n }\n case State.AfterAttributeName: {\n this.stateAfterAttributeName(c);\n break;\n }\n case State.InAttributeValueSq: {\n this.stateInAttributeValueSingleQuotes(c);\n break;\n }\n case State.BeforeAttributeValue: {\n this.stateBeforeAttributeValue(c);\n break;\n }\n case State.BeforeClosingTagName: {\n this.stateBeforeClosingTagName(c);\n break;\n }\n case State.AfterClosingTagName: {\n this.stateAfterClosingTagName(c);\n break;\n }\n case State.InAttributeValueNq: {\n this.stateInAttributeValueNoQuotes(c);\n break;\n }\n case State.InSelfClosingTag: {\n this.stateInSelfClosingTag(c);\n break;\n }\n case State.InDeclaration: {\n this.stateInDeclaration(c);\n break;\n }\n case State.BeforeDeclaration: {\n this.stateBeforeDeclaration(c);\n break;\n }\n case State.BeforeComment: {\n this.stateBeforeComment(c);\n break;\n }\n case State.InProcessingInstruction: {\n this.stateInProcessingInstruction(c);\n break;\n }\n case State.InEntity: {\n this.stateInEntity();\n break;\n }\n }\n this.index++;\n }\n this.cleanup();\n }\n finish() {\n if (this.state === State.InEntity) {\n this.entityDecoder.end();\n this.state = this.baseState;\n }\n this.handleTrailingData();\n this.cbs.onend();\n }\n handleTrailingCommentLikeData(endIndex) {\n if (this.state !== State.InCommentLike) {\n return false;\n }\n if (this.currentSequence === Sequences.CdataEnd) {\n if (this.xmlMode) {\n if (this.sectionStart < endIndex) {\n this.cbs.oncdata(this.sectionStart, endIndex, 0);\n }\n }\n else {\n /* In HTML mode, unclosed CDATA is a bogus comment. */\n const cdataStart = this.sectionStart - Sequences.Cdata.length - 1;\n this.cbs.oncomment(cdataStart, endIndex, 0);\n }\n }\n else {\n const offset = this.xmlMode\n ? 0\n : Math.min(this.sequenceIndex, Sequences.CommentEnd.length - 1);\n this.cbs.oncomment(this.sectionStart, endIndex, offset);\n }\n return true;\n }\n handleTrailingMarkupDeclaration(endIndex) {\n if (this.xmlMode) {\n switch (this.state) {\n case State.InSpecialComment:\n case State.BeforeComment:\n case State.CDATASequence:\n case State.DeclarationSequence:\n case State.InDeclaration: {\n this.cbs.ontext(this.sectionStart, endIndex);\n return true;\n }\n default: {\n return false;\n }\n }\n }\n switch (this.state) {\n case State.BeforeDeclaration:\n case State.InSpecialComment:\n case State.BeforeComment:\n case State.CDATASequence: {\n this.cbs.oncomment(this.sectionStart, endIndex, 0);\n return true;\n }\n case State.DeclarationSequence: {\n if (this.sequenceIndex !== Sequences.Doctype.length) {\n this.cbs.oncomment(this.sectionStart, endIndex, 0);\n }\n return true;\n }\n case State.InDeclaration: {\n return true;\n }\n default: {\n return false;\n }\n }\n }\n /** Handle any trailing data. */\n handleTrailingData() {\n const endIndex = this.buffer.length + this.offset;\n if (this.handleTrailingCommentLikeData(endIndex) ||\n this.handleTrailingMarkupDeclaration(endIndex)) {\n return;\n }\n // If there is no remaining data, we are done.\n if (this.sectionStart >= endIndex) {\n return;\n }\n switch (this.state) {\n case State.InTagName:\n case State.BeforeAttributeName:\n case State.BeforeAttributeValue:\n case State.AfterAttributeName:\n case State.InAttributeName:\n case State.InAttributeValueSq:\n case State.InAttributeValueDq:\n case State.InAttributeValueNq:\n case State.InClosingTagName: {\n /*\n * If we are currently in an opening or closing tag, us not calling the\n * respective callback signals that the tag should be ignored.\n */\n break;\n }\n default: {\n this.cbs.ontext(this.sectionStart, endIndex);\n }\n }\n }\n emitCodePoint(cp, consumed) {\n if (this.baseState !== State.Text &&\n this.baseState !== State.InSpecialTag) {\n if (this.sectionStart < this.entityStart) {\n this.cbs.onattribdata(this.sectionStart, this.entityStart);\n }\n this.sectionStart = this.entityStart + consumed;\n this.index = this.sectionStart - 1;\n this.cbs.onattribentity(cp);\n }\n else {\n if (this.sectionStart < this.entityStart) {\n this.cbs.ontext(this.sectionStart, this.entityStart);\n }\n this.sectionStart = this.entityStart + consumed;\n this.index = this.sectionStart - 1;\n this.cbs.ontextentity(cp, this.sectionStart);\n }\n }\n}\n//# sourceMappingURL=Tokenizer.js.map","const { fromCodePoint } = String;\nimport Tokenizer, { QuoteType } from \"./Tokenizer.js\";\nconst formTags = new Set([\n \"input\",\n \"option\",\n \"optgroup\",\n \"select\",\n \"button\",\n \"datalist\",\n \"textarea\",\n]);\nconst pTag = new Set([\"p\"]);\nconst headingTags = new Set([\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"p\"]);\nconst tableSectionTags = new Set([\"thead\", \"tbody\"]);\nconst ddtTags = new Set([\"dd\", \"dt\"]);\nconst rtpTags = new Set([\"rt\", \"rp\"]);\nconst openImpliesClose = new Map([\n [\"tr\", new Set([\"tr\", \"th\", \"td\"])],\n [\"th\", new Set([\"th\"])],\n [\"td\", new Set([\"thead\", \"th\", \"td\"])],\n [\"body\", new Set([\"head\", \"link\", \"script\"])],\n [\"a\", new Set([\"a\"])],\n [\"li\", new Set([\"li\"])],\n [\"p\", pTag],\n [\"h1\", headingTags],\n [\"h2\", headingTags],\n [\"h3\", headingTags],\n [\"h4\", headingTags],\n [\"h5\", headingTags],\n [\"h6\", headingTags],\n [\"select\", formTags],\n [\"input\", formTags],\n [\"output\", formTags],\n [\"button\", formTags],\n [\"datalist\", formTags],\n [\"textarea\", formTags],\n [\"option\", new Set([\"option\"])],\n [\"optgroup\", new Set([\"optgroup\", \"option\"])],\n [\"dd\", ddtTags],\n [\"dt\", ddtTags],\n [\"address\", pTag],\n [\"article\", pTag],\n [\"aside\", pTag],\n [\"blockquote\", pTag],\n [\"details\", pTag],\n [\"div\", pTag],\n [\"dl\", pTag],\n [\"fieldset\", pTag],\n [\"figcaption\", pTag],\n [\"figure\", pTag],\n [\"footer\", pTag],\n [\"form\", pTag],\n [\"header\", pTag],\n [\"hr\", pTag],\n [\"main\", pTag],\n [\"nav\", pTag],\n [\"ol\", pTag],\n [\"pre\", pTag],\n [\"section\", pTag],\n [\"table\", pTag],\n [\"ul\", pTag],\n [\"rt\", rtpTags],\n [\"rp\", rtpTags],\n [\"tbody\", tableSectionTags],\n [\"tfoot\", tableSectionTags],\n]);\nconst DOCUMENT_TYPE = \"doctype\";\nconst voidElements = new Set([\n \"area\",\n \"base\",\n \"basefont\",\n \"br\",\n \"col\",\n \"command\",\n \"embed\",\n \"frame\",\n \"hr\",\n \"img\",\n \"input\",\n \"isindex\",\n \"keygen\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\",\n]);\nconst foreignContextElements = new Set([\"math\", \"svg\"]);\n/**\n * Elements that can be used to integrate HTML content within foreign namespaces (e.g., SVG or MathML).\n *\n * Entries must use the SVG-adjusted casing (e.g. \"foreignObject\" not\n * \"foreignobject\") since they are compared against adjusted tag names.\n */\nconst htmlIntegrationElements = new Set([\n \"mi\",\n \"mo\",\n \"mn\",\n \"ms\",\n \"mtext\",\n \"annotation-xml\",\n \"foreignObject\",\n \"desc\",\n \"title\",\n]);\nconst svgTagNameAdjustments = new Map([\n [\"altglyph\", \"altGlyph\"],\n [\"altglyphdef\", \"altGlyphDef\"],\n [\"altglyphitem\", \"altGlyphItem\"],\n [\"animatecolor\", \"animateColor\"],\n [\"animatemotion\", \"animateMotion\"],\n [\"animatetransform\", \"animateTransform\"],\n [\"clippath\", \"clipPath\"],\n [\"feblend\", \"feBlend\"],\n [\"fecolormatrix\", \"feColorMatrix\"],\n [\"fecomponenttransfer\", \"feComponentTransfer\"],\n [\"fecomposite\", \"feComposite\"],\n [\"feconvolvematrix\", \"feConvolveMatrix\"],\n [\"fediffuselighting\", \"feDiffuseLighting\"],\n [\"fedisplacementmap\", \"feDisplacementMap\"],\n [\"fedistantlight\", \"feDistantLight\"],\n [\"fedropshadow\", \"feDropShadow\"],\n [\"feflood\", \"feFlood\"],\n [\"fefunca\", \"feFuncA\"],\n [\"fefuncb\", \"feFuncB\"],\n [\"fefuncg\", \"feFuncG\"],\n [\"fefuncr\", \"feFuncR\"],\n [\"fegaussianblur\", \"feGaussianBlur\"],\n [\"feimage\", \"feImage\"],\n [\"femerge\", \"feMerge\"],\n [\"femergenode\", \"feMergeNode\"],\n [\"femorphology\", \"feMorphology\"],\n [\"feoffset\", \"feOffset\"],\n [\"fepointlight\", \"fePointLight\"],\n [\"fespecularlighting\", \"feSpecularLighting\"],\n [\"fespotlight\", \"feSpotLight\"],\n [\"fetile\", \"feTile\"],\n [\"feturbulence\", \"feTurbulence\"],\n [\"foreignobject\", \"foreignObject\"],\n [\"glyphref\", \"glyphRef\"],\n [\"lineargradient\", \"linearGradient\"],\n [\"radialgradient\", \"radialGradient\"],\n [\"textpath\", \"textPath\"],\n]);\nvar ForeignContext;\n(function (ForeignContext) {\n ForeignContext[ForeignContext[\"None\"] = 0] = \"None\";\n ForeignContext[ForeignContext[\"Svg\"] = 1] = \"Svg\";\n ForeignContext[ForeignContext[\"MathML\"] = 2] = \"MathML\";\n})(ForeignContext || (ForeignContext = {}));\nconst reNameEnd = /\\s|\\//;\n/**\n * Incremental parser implementation.\n */\nexport class Parser {\n options;\n /** The start index of the last event. */\n startIndex = 0;\n /** The end index of the last event. */\n endIndex = 0;\n /**\n * Store the start index of the current open tag,\n * so we can update the start index for attributes.\n */\n openTagStart = 0;\n tagname = \"\";\n attribname = \"\";\n attribvalue = \"\";\n attribs = null;\n stack = [];\n foreignContext;\n cbs;\n lowerCaseTagNames;\n lowerCaseAttributeNames;\n recognizeSelfClosing;\n /** We are parsing HTML. Inverse of the `xmlMode` option. */\n htmlMode;\n tokenizer;\n buffers = [];\n bufferOffset = 0;\n /** The index of the last written buffer. Used when resuming after a `pause()`. */\n writeIndex = 0;\n /** Indicates whether the parser has finished running / `.end` has been called. */\n ended = false;\n constructor(cbs, options = {}) {\n this.options = options;\n this.cbs = cbs ?? {};\n this.htmlMode = !this.options.xmlMode;\n this.lowerCaseTagNames = options.lowerCaseTags ?? this.htmlMode;\n this.lowerCaseAttributeNames =\n options.lowerCaseAttributeNames ?? this.htmlMode;\n this.recognizeSelfClosing =\n options.recognizeSelfClosing ?? !this.htmlMode;\n this.tokenizer = new (options.Tokenizer ?? Tokenizer)(this.options, this);\n this.foreignContext = [ForeignContext.None];\n this.cbs.onparserinit?.(this);\n }\n // Tokenizer event handlers\n /**\n * @param start Start index for the current parser event.\n * @param endIndex End index for the current parser event.\n * @internal\n */\n ontext(start, endIndex) {\n const data = this.getSlice(start, endIndex);\n this.endIndex = endIndex - 1;\n this.cbs.ontext?.(data);\n this.startIndex = endIndex;\n }\n /**\n * @param cp Current Unicode code point.\n * @param endIndex End index for the current parser event.\n * @internal\n */\n ontextentity(cp, endIndex) {\n this.endIndex = endIndex - 1;\n this.cbs.ontext?.(fromCodePoint(cp));\n this.startIndex = endIndex;\n }\n /** @internal */\n isInForeignContext() {\n return this.foreignContext[0] !== ForeignContext.None;\n }\n /**\n * Checks if the current tag is a void element. Override this if you want\n * to specify your own additional void elements.\n * @param name Name of the pseudo selector.\n */\n isVoidElement(name) {\n return this.htmlMode && voidElements.has(name);\n }\n /**\n * Read a tag name from the buffer.\n *\n * When `lowerCaseTagNames` is enabled (the default in HTML mode), the name\n * is lowercased and may be adjusted for SVG casing or the `image` → `img`\n * alias.\n * @param start Start index of the tag name in the buffer.\n * @param endIndex End index of the tag name in the buffer.\n */\n readTagName(start, endIndex) {\n const name = this.lowerCaseTagNames\n ? this.getSlice(start, endIndex).toLowerCase()\n : this.getSlice(start, endIndex);\n if (!(this.lowerCaseTagNames && this.htmlMode)) {\n return name;\n }\n if (this.foreignContext[0] === ForeignContext.Svg) {\n return svgTagNameAdjustments.get(name) ?? name;\n }\n /*\n * Closing tags for SVG elements inside HTML integration points\n * (e.g. </foreignObject> while inside its own content) need case\n * adjustment so the name matches what was pushed to the stack.\n * `foreignContext.length > 1` means a foreign ancestor exists —\n * the base [None] entry plus at least one pushed context.\n */\n if (this.foreignContext.length > 1) {\n const adjusted = svgTagNameAdjustments.get(name);\n if (adjusted !== undefined && this.stack.includes(adjusted)) {\n return adjusted;\n }\n }\n if (!this.isInForeignContext()) {\n return name === \"image\" ? \"img\" : name;\n }\n return name;\n }\n /**\n * @param start Start index for the current parser event.\n * @param endIndex End index for the current parser event.\n * @internal\n */\n onopentagname(start, endIndex) {\n this.endIndex = endIndex;\n this.emitOpenTag(this.readTagName(start, endIndex));\n }\n emitOpenTag(name) {\n this.openTagStart = this.startIndex;\n this.tagname = name;\n /*\n * The spec ignores a second <form> when one is already open.\n * Setting tagname to \"\" suppresses all downstream effects: attribs\n * stays null so endOpenTag is a no-op, and closeCurrentTag can't\n * match \"\" on the stack.\n */\n if (this.htmlMode && name === \"form\" && this.stack.includes(\"form\")) {\n this.tagname = \"\";\n return;\n }\n const impliesClose = this.htmlMode && openImpliesClose.get(name);\n if (impliesClose) {\n while (this.stack.length > 0 && impliesClose.has(this.stack[0])) {\n this.popElement(true);\n }\n }\n if (!this.isVoidElement(name)) {\n this.stack.unshift(name);\n if (this.htmlMode) {\n if (name === \"svg\") {\n this.foreignContext.unshift(ForeignContext.Svg);\n }\n else if (name === \"math\") {\n this.foreignContext.unshift(ForeignContext.MathML);\n }\n else if (htmlIntegrationElements.has(name)) {\n this.foreignContext.unshift(ForeignContext.None);\n }\n }\n }\n this.cbs.onopentagname?.(name);\n if (this.cbs.onopentag)\n this.attribs = {};\n }\n endOpenTag(isImplied) {\n this.startIndex = this.openTagStart;\n if (this.attribs) {\n this.cbs.onopentag?.(this.tagname, this.attribs, isImplied);\n this.attribs = null;\n }\n if (this.cbs.onclosetag && this.isVoidElement(this.tagname)) {\n this.cbs.onclosetag(this.tagname, true);\n }\n this.tagname = \"\";\n }\n /**\n * @param endIndex End index for the current parser event.\n * @internal\n */\n onopentagend(endIndex) {\n this.endIndex = endIndex;\n this.endOpenTag(false);\n // Set `startIndex` for next node\n this.startIndex = endIndex + 1;\n }\n /**\n * @param start Start index for the current parser event.\n * @param endIndex End index for the current parser event.\n * @internal\n */\n onclosetag(start, endIndex) {\n this.endIndex = endIndex;\n const name = this.readTagName(start, endIndex);\n if (!this.isVoidElement(name)) {\n const pos = this.stack.indexOf(name);\n if (pos !== -1) {\n for (let index = 0; index < pos; index++) {\n this.popElement(true);\n }\n this.popElement(false);\n }\n else if (this.htmlMode && name === \"p\") {\n // Implicit open before close\n this.emitOpenTag(\"p\");\n this.closeCurrentTag(true);\n }\n }\n else if (this.htmlMode && name === \"br\") {\n // We can't use `emitOpenTag` for implicit open, as `br` would be implicitly closed.\n this.cbs.onopentagname?.(\"br\");\n this.cbs.onopentag?.(\"br\", {}, true);\n this.cbs.onclosetag?.(\"br\", false);\n }\n // Set `startIndex` for next node\n this.startIndex = endIndex + 1;\n }\n /**\n * @param endIndex End index for the current parser event.\n * @internal\n */\n onselfclosingtag(endIndex) {\n this.endIndex = endIndex;\n if (this.recognizeSelfClosing || this.isInForeignContext()) {\n this.closeCurrentTag(false);\n // Set `startIndex` for next node\n this.startIndex = endIndex + 1;\n }\n else {\n // Ignore the fact that the tag is self-closing.\n this.onopentagend(endIndex);\n }\n }\n /**\n * Pop the top element off the stack, emit a close event, and maintain\n * the foreign context stack.\n * @param implied Whether this close is implied (not from an explicit end tag).\n */\n popElement(implied) {\n // biome-ignore lint/style/noNonNullAssertion: The element is guaranteed to exist.\n const element = this.stack.shift();\n if (this.htmlMode &&\n (foreignContextElements.has(element) ||\n htmlIntegrationElements.has(element))) {\n this.foreignContext.shift();\n }\n this.cbs.onclosetag?.(element, implied);\n }\n closeCurrentTag(isOpenImplied) {\n const name = this.tagname;\n this.endOpenTag(isOpenImplied);\n // Self-closing tags will be on the top of the stack\n if (this.stack[0] === name) {\n this.popElement(!isOpenImplied);\n }\n }\n /**\n * @param start Start index for the current parser event.\n * @param endIndex End index for the current parser event.\n * @internal\n */\n onattribname(start, endIndex) {\n this.startIndex = start;\n const name = this.getSlice(start, endIndex);\n this.attribname = this.lowerCaseAttributeNames\n ? name.toLowerCase()\n : name;\n }\n /**\n * @param start Start index for the current parser event.\n * @param endIndex End index for the current parser event.\n * @internal\n */\n onattribdata(start, endIndex) {\n this.attribvalue += this.getSlice(start, endIndex);\n }\n /**\n * @param cp Current Unicode code point.\n * @internal\n */\n onattribentity(cp) {\n this.attribvalue += fromCodePoint(cp);\n }\n /**\n * @param quote Quote type used for the current attribute.\n * @param endIndex End index for the current parser event.\n * @internal\n */\n onattribend(quote, endIndex) {\n this.endIndex = endIndex;\n this.cbs.onattribute?.(this.attribname, this.attribvalue, quote === QuoteType.Double\n ? '\"'\n : quote === QuoteType.Single\n ? \"'\"\n : quote === QuoteType.NoValue\n ? undefined\n : null);\n if (this.attribs && !Object.hasOwn(this.attribs, this.attribname)) {\n this.attribs[this.attribname] = this.attribvalue;\n }\n this.attribvalue = \"\";\n }\n getInstructionName(value) {\n const index = value.search(reNameEnd);\n let name = index < 0 ? value : value.substr(0, index);\n if (this.lowerCaseTagNames) {\n name = name.toLowerCase();\n }\n return name;\n }\n /**\n * @param start Start index for the current parser event.\n * @param endIndex End index for the current parser event.\n * @internal\n */\n ondeclaration(start, endIndex) {\n this.endIndex = endIndex;\n const value = this.getSlice(start, endIndex);\n if (this.cbs.onprocessinginstruction) {\n /*\n * In HTML mode, ondeclaration is only reached for DOCTYPE\n * (the tokenizer routes everything else to bogus comments).\n */\n const name = this.htmlMode\n ? this.lowerCaseTagNames\n ? DOCUMENT_TYPE\n : value.slice(0, DOCUMENT_TYPE.length)\n : this.getInstructionName(value);\n this.cbs.onprocessinginstruction(`!${name}`, `!${value}`);\n }\n // Set `startIndex` for next node\n this.startIndex = endIndex + 1;\n }\n /**\n * @param start Start index for the current parser event.\n * @param endIndex End index for the current parser event.\n * @internal\n */\n onprocessinginstruction(start, endIndex) {\n this.endIndex = endIndex;\n const value = this.getSlice(start, endIndex);\n if (this.cbs.onprocessinginstruction) {\n const name = this.getInstructionName(value);\n this.cbs.onprocessinginstruction(`?${name}`, `?${value}`);\n }\n // Set `startIndex` for next node\n this.startIndex = endIndex + 1;\n }\n /**\n * @param start Start index for the current parser event.\n * @param endIndex End index for the current parser event.\n * @param offset Offset applied when computing parser indices.\n * @internal\n */\n oncomment(start, endIndex, offset) {\n this.endIndex = endIndex;\n this.cbs.oncomment?.(this.getSlice(start, endIndex - offset));\n this.cbs.oncommentend?.();\n // Set `startIndex` for next node\n this.startIndex = endIndex + 1;\n }\n /**\n * @param start Start index for the current parser event.\n * @param endIndex End index for the current parser event.\n * @param offset Offset applied when computing parser indices.\n * @internal\n */\n oncdata(start, endIndex, offset) {\n this.endIndex = endIndex;\n const value = this.getSlice(start, endIndex - offset);\n if (!this.htmlMode || this.options.recognizeCDATA) {\n this.cbs.oncdatastart?.();\n this.cbs.ontext?.(value);\n this.cbs.oncdataend?.();\n }\n else if (this.isInForeignContext()) {\n this.cbs.ontext?.(value);\n }\n else {\n this.cbs.oncomment?.(`[CDATA[${value}]]`);\n this.cbs.oncommentend?.();\n }\n // Set `startIndex` for next node\n this.startIndex = endIndex + 1;\n }\n /** @internal */\n onend() {\n if (this.cbs.onclosetag) {\n // Set the end index for all remaining tags\n this.endIndex = this.startIndex;\n for (let index = 0; index < this.stack.length; index++) {\n this.cbs.onclosetag(this.stack[index], true);\n }\n }\n this.cbs.onend?.();\n }\n /**\n * Resets the parser to a blank state, ready to parse a new HTML document\n */\n reset() {\n this.cbs.onreset?.();\n this.tokenizer.reset();\n this.tagname = \"\";\n this.attribname = \"\";\n this.attribvalue = \"\";\n this.attribs = null;\n this.stack.length = 0;\n this.startIndex = 0;\n this.endIndex = 0;\n this.cbs.onparserinit?.(this);\n this.buffers.length = 0;\n this.foreignContext.length = 0;\n this.foreignContext.unshift(ForeignContext.None);\n this.bufferOffset = 0;\n this.writeIndex = 0;\n this.ended = false;\n }\n /**\n * Resets the parser, then parses a complete document and\n * pushes it to the handler.\n * @param data Document to parse.\n */\n parseComplete(data) {\n this.reset();\n this.end(data);\n }\n getSlice(start, end) {\n if (start === end) {\n return \"\";\n }\n while (start - this.bufferOffset >= this.buffers[0].length) {\n this.shiftBuffer();\n }\n let slice = this.buffers[0].slice(start - this.bufferOffset, end - this.bufferOffset);\n while (end - this.bufferOffset > this.buffers[0].length) {\n this.shiftBuffer();\n slice += this.buffers[0].slice(0, end - this.bufferOffset);\n }\n return slice;\n }\n shiftBuffer() {\n this.bufferOffset += this.buffers[0].length;\n this.writeIndex--;\n this.buffers.shift();\n }\n /**\n * Parses a chunk of data and calls the corresponding callbacks.\n * @param chunk Chunk to parse.\n */\n write(chunk) {\n if (this.ended) {\n this.cbs.onerror?.(new Error(\".write() after done!\"));\n return;\n }\n this.buffers.push(chunk);\n if (this.tokenizer.running) {\n this.tokenizer.write(chunk);\n this.writeIndex++;\n }\n }\n /**\n * Parses the end of the buffer and clears the stack, calls onend.\n * @param chunk Optional final chunk to parse.\n */\n end(chunk) {\n if (this.ended) {\n this.cbs.onerror?.(new Error(\".end() after done!\"));\n return;\n }\n if (chunk)\n this.write(chunk);\n this.ended = true;\n this.tokenizer.end();\n }\n /**\n * Pauses parsing. The parser won't emit events until `resume` is called.\n */\n pause() {\n this.tokenizer.pause();\n }\n /**\n * Resumes parsing after `pause` was called.\n */\n resume() {\n this.tokenizer.resume();\n while (this.tokenizer.running &&\n this.writeIndex < this.buffers.length) {\n this.tokenizer.write(this.buffers[this.writeIndex++]);\n }\n if (this.ended)\n this.tokenizer.end();\n }\n}\n//# sourceMappingURL=Parser.js.map","/** Types of elements found in htmlparser2's DOM */\nexport var ElementType;\n(function (ElementType) {\n /** Type for the root element of a document */\n ElementType[\"Root\"] = \"root\";\n /** Type for Text */\n ElementType[\"Text\"] = \"text\";\n /** Type for <? ... ?> */\n ElementType[\"Directive\"] = \"directive\";\n /** Type for <!-- ... --> */\n ElementType[\"Comment\"] = \"comment\";\n /** Type for <script> tags */\n ElementType[\"Script\"] = \"script\";\n /** Type for <style> tags */\n ElementType[\"Style\"] = \"style\";\n /** Type for Any tag */\n ElementType[\"Tag\"] = \"tag\";\n /** Type for <![CDATA[ ... ]]> */\n ElementType[\"CDATA\"] = \"cdata\";\n /** Type for <!doctype ...> */\n ElementType[\"Doctype\"] = \"doctype\";\n})(ElementType || (ElementType = {}));\n/**\n * Tests whether an element is a tag or not.\n * @param element Element to test\n * @param element.type Node type discriminator to check.\n */\nexport function isTag(element) {\n return (element.type === ElementType.Tag ||\n element.type === ElementType.Script ||\n element.type === ElementType.Style);\n}\n// Exports for backwards compatibility\n/** Type for the root element of a document */\n// eslint-disable-next-line prefer-destructuring\nexport const Root = ElementType.Root;\n/** Type for Text */\n// eslint-disable-next-line prefer-destructuring\nexport const Text = ElementType.Text;\n/** Type for <? ... ?> */\n// eslint-disable-next-line prefer-destructuring\nexport const Directive = ElementType.Directive;\n/** Type for <!-- ... --> */\n// eslint-disable-next-line prefer-destructuring\nexport const Comment = ElementType.Comment;\n/** Type for <script> tags */\n// eslint-disable-next-line prefer-destructuring\nexport const Script = ElementType.Script;\n/** Type for <style> tags */\n// eslint-disable-next-line prefer-destructuring\nexport const Style = ElementType.Style;\n/** Type for Any tag */\n// eslint-disable-next-line prefer-destructuring\nexport const Tag = ElementType.Tag;\n/** Type for <![CDATA[ ... ]]> */\n// eslint-disable-next-line prefer-destructuring\nexport const CDATA = ElementType.CDATA;\n/** Type for <!doctype ...> */\n// eslint-disable-next-line prefer-destructuring\nexport const Doctype = ElementType.Doctype;\n","import { ElementType, isTag as isTagRaw } from \"domelementtype\";\n/**\n * This object will be used as the prototype for Nodes when creating a\n * DOM-Level-1-compliant structure.\n */\nexport class Node {\n /** Parent of the node */\n parent = null;\n /** Previous sibling */\n prev = null;\n /** Next sibling */\n next = null;\n /** The start index of the node. Requires `withStartIndices` on the handler to be `true. */\n startIndex = null;\n /** The end index of the node. Requires `withEndIndices` on the handler to be `true. */\n endIndex = null;\n // Read-write aliases for properties\n /**\n * Same as {@link parent}.\n * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n */\n get parentNode() {\n return this.parent;\n }\n set parentNode(parent) {\n this.parent = parent;\n }\n /**\n * Same as {@link prev}.\n * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n */\n get previousSibling() {\n return this.prev;\n }\n set previousSibling(previous) {\n this.prev = previous;\n }\n /**\n * Same as {@link next}.\n * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n */\n get nextSibling() {\n return this.next;\n }\n set nextSibling(next) {\n this.next = next;\n }\n /**\n * Clone this node, and optionally its children.\n * @param recursive Clone child nodes as well.\n * @returns A clone of the node.\n */\n cloneNode(recursive = false) {\n return cloneNode(this, recursive);\n }\n}\n/**\n * A node that contains some data.\n */\nexport class DataNode extends Node {\n data;\n /**\n * @param data The content of the data node\n */\n constructor(data) {\n super();\n this.data = data;\n }\n /**\n * Same as {@link data}.\n * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n */\n get nodeValue() {\n return this.data;\n }\n set nodeValue(data) {\n this.data = data;\n }\n}\n/**\n * Text within the document.\n */\nexport class Text extends DataNode {\n type = ElementType.Text;\n get nodeType() {\n return 3;\n }\n}\n/**\n * Comments within the document.\n */\nexport class Comment extends DataNode {\n type = ElementType.Comment;\n get nodeType() {\n return 8;\n }\n}\n/**\n * Processing instructions, including doc types.\n */\nexport class ProcessingInstruction extends DataNode {\n type = ElementType.Directive;\n name;\n constructor(name, data) {\n super(data);\n this.name = name;\n }\n get nodeType() {\n return 1;\n }\n /** If this is a doctype, the document type name (parse5 only). */\n \"x-name\";\n /** If this is a doctype, the document type public identifier (parse5 only). */\n \"x-publicId\";\n /** If this is a doctype, the document type system identifier (parse5 only). */\n \"x-systemId\";\n}\n/**\n * A node that can have children.\n */\nexport class NodeWithChildren extends Node {\n children;\n /**\n * @param children Children of the node. Only certain node types can have children.\n */\n constructor(children) {\n super();\n this.children = children;\n }\n // Aliases\n /** First child of the node. */\n get firstChild() {\n return this.children[0] ?? null;\n }\n /** Last child of the node. */\n get lastChild() {\n return this.children.length > 0\n ? this.children[this.children.length - 1]\n : null;\n }\n /**\n * Same as {@link children}.\n * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n */\n get childNodes() {\n return this.children;\n }\n set childNodes(children) {\n this.children = children;\n }\n}\n/**\n * CDATA nodes.\n */\nexport class CDATA extends NodeWithChildren {\n type = ElementType.CDATA;\n get nodeType() {\n return 4;\n }\n}\n/**\n * The root node of the document.\n */\nexport class Document extends NodeWithChildren {\n type = ElementType.Root;\n get nodeType() {\n return 9;\n }\n}\n/**\n * An element within the DOM.\n */\nexport class Element extends NodeWithChildren {\n name;\n attribs;\n type;\n /**\n * @param name Name of the tag, eg. `div`, `span`.\n * @param attribs Object mapping attribute names to attribute values.\n * @param children Children of the node.\n * @param type Node type used for the new node instance.\n */\n constructor(name, attribs, children = [], type = name === \"script\"\n ? ElementType.Script\n : name === \"style\"\n ? ElementType.Style\n : ElementType.Tag) {\n super(children);\n this.name = name;\n this.attribs = attribs;\n this.type = type;\n }\n get nodeType() {\n return 1;\n }\n // DOM Level 1 aliases\n /**\n * Same as {@link name}.\n * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n */\n get tagName() {\n return this.name;\n }\n set tagName(name) {\n this.name = name;\n }\n get attributes() {\n return Object.keys(this.attribs).map((name) => ({\n name,\n value: this.attribs[name],\n namespace: this[\"x-attribsNamespace\"]?.[name],\n prefix: this[\"x-attribsPrefix\"]?.[name],\n }));\n }\n /** Element namespace (parse5 only). */\n namespace;\n /** Element attribute namespaces (parse5 only). */\n \"x-attribsNamespace\";\n /** Element attribute namespace-related prefixes (parse5 only). */\n \"x-attribsPrefix\";\n}\n/**\n * Checks if `node` is an element node.\n * @param node Node to check.\n * @returns `true` if the node is an element node.\n */\nexport function isTag(node) {\n return isTagRaw(node);\n}\n/**\n * Checks if `node` is a CDATA node.\n * @param node Node to check.\n * @returns `true` if the node is a CDATA node.\n */\nexport function isCDATA(node) {\n return node.type === ElementType.CDATA;\n}\n/**\n * Checks if `node` is a text node.\n * @param node Node to check.\n * @returns `true` if the node is a text node.\n */\nexport function isText(node) {\n return node.type === ElementType.Text;\n}\n/**\n * Checks if `node` is a comment node.\n * @param node Node to check.\n * @returns `true` if the node is a comment node.\n */\nexport function isComment(node) {\n return node.type === ElementType.Comment;\n}\n/**\n * Checks if `node` is a directive node.\n * @param node Node to check.\n * @returns `true` if the node is a directive node.\n */\nexport function isDirective(node) {\n return node.type === ElementType.Directive;\n}\n/**\n * Checks if `node` is a document node.\n * @param node Node to check.\n * @returns `true` if the node is a document node.\n */\nexport function isDocument(node) {\n return node.type === ElementType.Root;\n}\n/**\n * Checks if `node` has children.\n * @param node Node to check.\n * @returns `true` if the node has children.\n */\nexport function hasChildren(node) {\n return Object.hasOwn(node, \"children\");\n}\n/**\n * Clone a node, and optionally its children.\n * @param node Node to clone.\n * @param recursive Clone child nodes as well.\n * @returns A clone of the node.\n */\nexport function cloneNode(node, recursive = false) {\n let result;\n if (isText(node)) {\n result = new Text(node.data);\n }\n else if (isComment(node)) {\n result = new Comment(node.data);\n }\n else if (isTag(node)) {\n const children = recursive ? cloneChildren(node.children) : [];\n const clone = new Element(node.name, { ...node.attribs }, children);\n for (const child of children) {\n child.parent = clone;\n }\n if (node.namespace != null) {\n clone.namespace = node.namespace;\n }\n if (node[\"x-attribsNamespace\"]) {\n clone[\"x-attribsNamespace\"] = { ...node[\"x-attribsNamespace\"] };\n }\n if (node[\"x-attribsPrefix\"]) {\n clone[\"x-attribsPrefix\"] = { ...node[\"x-attribsPrefix\"] };\n }\n result = clone;\n }\n else if (isCDATA(node)) {\n const children = recursive ? cloneChildren(node.children) : [];\n const clone = new CDATA(children);\n for (const child of children) {\n child.parent = clone;\n }\n result = clone;\n }\n else if (isDocument(node)) {\n const children = recursive ? cloneChildren(node.children) : [];\n const clone = new Document(children);\n for (const child of children) {\n child.parent = clone;\n }\n if (node[\"x-mode\"]) {\n clone[\"x-mode\"] = node[\"x-mode\"];\n }\n result = clone;\n }\n else if (isDirective(node)) {\n const instruction = new ProcessingInstruction(node.name, node.data);\n if (node[\"x-name\"] != null) {\n instruction[\"x-name\"] = node[\"x-name\"];\n instruction[\"x-publicId\"] = node[\"x-publicId\"];\n instruction[\"x-systemId\"] = node[\"x-systemId\"];\n }\n result = instruction;\n }\n else {\n throw new Error(`Not implemented yet: ${node.type}`);\n }\n result.startIndex = node.startIndex;\n result.endIndex = node.endIndex;\n if (node.sourceCodeLocation != null) {\n result.sourceCodeLocation = node.sourceCodeLocation;\n }\n return result;\n}\n/**\n * Clone a list of child nodes.\n * @param childs The child nodes to clone.\n * @returns A list of cloned child nodes.\n */\nfunction cloneChildren(childs) {\n const children = childs.map((child) => cloneNode(child, true));\n for (let index = 1; index < children.length; index++) {\n children[index].prev = children[index - 1];\n children[index - 1].next = children[index];\n }\n return children;\n}\n","import { ElementType } from \"domelementtype\";\nimport { CDATA, Comment, Document, Element, ProcessingInstruction, Text, } from \"./node.js\";\nexport * from \"./node.js\";\n// Default options\nconst defaultOptions = {\n withStartIndices: false,\n withEndIndices: false,\n xmlMode: false,\n};\n/**\n * Event-based handler that builds a DOM tree from parser callbacks.\n */\nexport class DomHandler {\n /** The elements of the DOM */\n dom = [];\n /** The root element for the DOM */\n root = new Document(this.dom);\n /** Called once parsing has completed. */\n callback;\n /** Settings for the handler. */\n options;\n /** Callback whenever a tag is closed. */\n elementCB;\n /** Indicated whether parsing has been completed. */\n done = false;\n /** Stack of open tags. */\n tagStack = [this.root];\n /** A data node that is still being written to. */\n lastNode = null;\n /** Reference to the parser instance. Used for location information. */\n parser = null;\n /**\n * @param callback Called once parsing has completed.\n * @param options Settings for the handler.\n * @param elementCB Callback whenever a tag is closed.\n */\n constructor(callback, options, elementCB) {\n // Make it possible to skip arguments, for backwards-compatibility\n if (typeof options === \"function\") {\n elementCB = options;\n options = defaultOptions;\n }\n if (typeof callback === \"object\") {\n options = callback;\n callback = undefined;\n }\n this.callback = callback ?? null;\n this.options = options ?? defaultOptions;\n this.elementCB = elementCB ?? null;\n }\n onparserinit(parser) {\n this.parser = parser;\n }\n // Resets the handler back to starting state\n onreset() {\n this.dom = [];\n this.root = new Document(this.dom);\n this.done = false;\n this.tagStack = [this.root];\n this.lastNode = null;\n this.parser = null;\n }\n // Signals the handler that parsing is done\n onend() {\n if (this.done)\n return;\n this.done = true;\n this.parser = null;\n this.handleCallback(null);\n }\n onerror(error) {\n this.handleCallback(error);\n }\n onclosetag() {\n this.lastNode = null;\n const element = this.tagStack.pop();\n if (this.options.withEndIndices && this.parser) {\n element.endIndex = this.parser.endIndex;\n }\n if (this.elementCB)\n this.elementCB(element);\n }\n onopentag(name, attribs) {\n const type = this.options.xmlMode ? ElementType.Tag : undefined;\n const element = new Element(name, attribs, undefined, type);\n this.addNode(element);\n this.tagStack.push(element);\n }\n ontext(data) {\n const { lastNode } = this;\n if (lastNode && lastNode.type === ElementType.Text) {\n lastNode.data += data;\n if (this.options.withEndIndices && this.parser) {\n lastNode.endIndex = this.parser.endIndex;\n }\n }\n else {\n const node = new Text(data);\n this.addNode(node);\n this.lastNode = node;\n }\n }\n oncomment(data) {\n if (this.lastNode && this.lastNode.type === ElementType.Comment) {\n this.lastNode.data += data;\n return;\n }\n const node = new Comment(data);\n this.addNode(node);\n this.lastNode = node;\n }\n oncommentend() {\n this.lastNode = null;\n }\n oncdatastart() {\n const text = new Text(\"\");\n const node = new CDATA([text]);\n this.addNode(node);\n text.parent = node;\n this.lastNode = text;\n }\n oncdataend() {\n this.lastNode = null;\n }\n onprocessinginstruction(name, data) {\n const node = new ProcessingInstruction(name, data);\n this.addNode(node);\n }\n handleCallback(error) {\n if (typeof this.callback === \"function\") {\n this.callback(error, this.dom);\n }\n else if (error) {\n throw error;\n }\n }\n addNode(node) {\n const parent = this.tagStack[this.tagStack.length - 1];\n const previousSibling = parent.children[parent.children.length - 1];\n if (this.options.withStartIndices && this.parser) {\n node.startIndex = this.parser.startIndex;\n }\n if (this.options.withEndIndices && this.parser) {\n node.endIndex = this.parser.endIndex;\n }\n parent.children.push(node);\n if (previousSibling) {\n node.prev = previousSibling;\n previousSibling.next = node;\n }\n node.parent = parent;\n this.lastNode = null;\n }\n}\nexport default DomHandler;\n","import { Parser } from \"./Parser.js\";\nexport { Parser } from \"./Parser.js\";\nimport { DomHandler, } from \"domhandler\";\nexport { DomHandler, \n// Old name for DomHandler\nDomHandler as DefaultHandler, } from \"domhandler\";\n// Helper methods\n/**\n * Parses the data, returns the resulting document.\n * @param data The data that should be parsed.\n * @param options Optional options for the parser and DOM handler.\n */\nexport function parseDocument(data, options) {\n const handler = new DomHandler(undefined, options);\n new Parser(handler, options).end(data);\n return handler.root;\n}\n/**\n * Creates a parser instance, with an attached DOM handler.\n * @param callback A callback that will be called once parsing has been completed, with the resulting document.\n * @param options Optional options for the parser and DOM handler.\n * @param elementCallback An optional callback that will be called every time a tag has been completed inside of the DOM.\n */\nexport function createDocumentStream(callback, options, elementCallback) {\n const handler = new DomHandler((error) => callback(error, handler.root), options, elementCallback);\n return new Parser(handler, options);\n}\n/*\n * All of the following exports exist for backwards-compatibility.\n * They should probably be removed eventually.\n */\nexport * as ElementType from \"domelementtype\";\nexport { default as Tokenizer, QuoteType, } from \"./Tokenizer.js\";\nimport { getFeed } from \"domutils\";\nexport { getFeed } from \"domutils\";\nconst parseFeedDefaultOptions = { xmlMode: true };\n/**\n * Parse a feed.\n * @param feed The feed that should be parsed, as a string.\n * @param options Optionally, options for parsing. When using this, you should set `xmlMode` to `true`.\n */\nexport function parseFeed(feed, options = parseFeedDefaultOptions) {\n return getFeed(parseDocument(feed, options).children);\n}\nexport * as DomUtils from \"domutils\";\n//# sourceMappingURL=index.js.map","/**\n * Twine HTML decompiler: parse compiled Twine 2 or Twine 1 HTML back into a Story model.\n * Ported from storyload.go:loadHTML().\n */\nimport { parseDocument } from 'htmlparser2';\nimport type { Passage, PassageMetadata, Diagnostic, IFID, DecompileOptions } from './types.js';\nimport { createStory, storyAdd, storyPrepend, marshalStoryData, unmarshalStorySettings } from './story.js';\nimport { rot13, tiddlerUnescape } from './escape.js';\n\nexport interface DecompileResult {\n story: import('./types.js').Story;\n diagnostics: Diagnostic[];\n}\n\n// Structural types matching domhandler's API (avoids direct import of domhandler).\ninterface HtmlNode {\n type: string;\n name?: string;\n attribs?: Record<string, string>;\n children?: HtmlNode[];\n data?: string;\n}\n\n/**\n * Parse a Twine 2 or Twine 1 compiled HTML file back into a Story model.\n * Tweego always trims passage text; here `trim: false` keeps it exactly, as for Twee sources.\n */\nexport function decompileHTML(html: string, options: DecompileOptions = {}): DecompileResult {\n const diagnostics: Diagnostic[] = [];\n const story = createStory();\n const passageText = options.trim === false ? (text: string) => text : (text: string) => text.trim();\n\n const doc = parseDocument(html) as unknown as HtmlNode;\n\n // Try Twine 2 first (<tw-storydata>), then Twine 1 (<div id=\"store-area\"> or <div id=\"storeArea\">).\n const twine2Data = findElement(doc, 'tw-storydata');\n if (twine2Data) {\n decompileTwine2(twine2Data, story, passageText, diagnostics);\n return { story, diagnostics };\n }\n\n const twine1Data = findElementByIdPattern(doc, /^store(?:-a|A)rea$/);\n if (twine1Data) {\n decompileTwine1(twine1Data, story, passageText, diagnostics);\n return { story, diagnostics };\n }\n\n diagnostics.push({ level: 'error', message: 'Malformed HTML source; story data not found.' });\n return { story, diagnostics };\n}\n\n/** Turns stored passage text into passage text: trimmed at both ends, or kept as is. */\ntype PassageText = (text: string) => string;\n\nfunction decompileTwine2(\n storyData: HtmlNode,\n story: import('./types.js').Story,\n passageText: PassageText,\n diagnostics: Diagnostic[],\n): void {\n // Parse tw-storydata attributes.\n let startnode = 0;\n const attrs = storyData.attribs ?? {};\n\n if (attrs['name']) story.name = attrs['name'];\n if (attrs['startnode']) {\n const parsed = parseInt(attrs['startnode'], 10);\n if (Number.isNaN(parsed)) {\n diagnostics.push({\n level: 'warning',\n message: `Cannot parse \"tw-storydata\" content attribute \"startnode\" as an integer; value \"${attrs['startnode']}\".`,\n });\n } else {\n startnode = parsed;\n }\n }\n if (attrs['ifid']) story.ifid = attrs['ifid'].toUpperCase() as IFID;\n if (attrs['zoom']) {\n const parsed = parseFloat(attrs['zoom']);\n if (Number.isNaN(parsed)) {\n diagnostics.push({\n level: 'warning',\n message: `Cannot parse \"tw-storydata\" content attribute \"zoom\" as a float; value \"${attrs['zoom']}\".`,\n });\n } else {\n story.twine2.zoom = parsed;\n }\n }\n if (attrs['tags']) story.twine2.tags = attrs['tags'];\n if (attrs['format']) story.twine2.format = attrs['format'];\n if (attrs['format-version']) story.twine2.formatVersion = attrs['format-version'];\n if (attrs['options']) {\n for (const opt of attrs['options'].split(/\\s+/).filter((s: string) => s.length > 0)) {\n story.twine2.options.set(opt, true);\n }\n }\n\n // Process child elements.\n // htmlparser2 uses type 'style'/'script' for those elements instead of 'tag'.\n for (const node of storyData.children ?? []) {\n if (node.type !== 'tag' && node.type !== 'style' && node.type !== 'script') continue;\n\n switch (node.name) {\n case 'style':\n case 'script': {\n const content = getTextContent(node);\n // Whitespace alone is no stylesheet or script, whether or not the text is trimmed.\n if (content.trim().length === 0) continue;\n const text = passageText(content);\n const name = node.name === 'style' ? 'Story Stylesheet' : 'Story JavaScript';\n const tags = node.name === 'style' ? ['stylesheet'] : ['script'];\n storyAdd(story, { name, tags, text }, diagnostics);\n break;\n }\n\n case 'tw-tag': {\n const tagAttrs = node.attribs ?? {};\n const tagName = tagAttrs['name'] ?? '';\n const tagColor = tagAttrs['color'] ?? '';\n if (tagName) story.twine2.tagColors.set(tagName, tagColor);\n break;\n }\n\n case 'tw-passagedata': {\n let pid = 0;\n const pAttrs = node.attribs ?? {};\n const name = pAttrs['name'] ?? '';\n const tags = pAttrs['tags'] ? pAttrs['tags'].split(/\\s+/).filter((s: string) => s.length > 0) : [];\n const metadata: PassageMetadata = {};\n\n if (pAttrs['pid']) {\n const parsed = parseInt(pAttrs['pid'], 10);\n if (Number.isNaN(parsed)) {\n diagnostics.push({\n level: 'warning',\n message: `Cannot parse \"tw-passagedata\" content attribute \"pid\" as an integer; value \"${pAttrs['pid']}\".`,\n });\n } else {\n pid = parsed;\n }\n }\n\n if (pAttrs['position']) metadata.position = pAttrs['position'];\n if (pAttrs['size']) metadata.size = pAttrs['size'];\n\n if (pid === startnode && pid !== 0) {\n story.twine2.start = name;\n }\n\n const text = passageText(getTextContent(node));\n const passage: Passage = { name, tags, text };\n if (metadata.position || metadata.size) {\n passage.metadata = metadata;\n }\n storyAdd(story, passage, diagnostics);\n break;\n }\n }\n }\n\n // Prepend StoryData passage with serialized metadata.\n storyPrepend(story, { name: 'StoryData', tags: [], text: marshalStoryData(story) }, diagnostics);\n}\n\nfunction decompileTwine1(\n storeArea: HtmlNode,\n story: import('./types.js').Story,\n passageText: PassageText,\n diagnostics: Diagnostic[],\n): void {\n const passages = (storeArea.children ?? []).filter(isTiddler).map((node) => tiddlerToPassage(node, passageText));\n\n // The Twine 1 writer ROT13-encodes every tiddler but StorySettings when StorySettings says\n // `obfuscate:rot13`, so read the settings before adding (and so interpreting) anything else.\n const obfuscated = isRot13Obfuscated(passages);\n for (const p of passages) {\n const passage = obfuscated && p.name !== 'StorySettings' ? { ...p, text: rot13(p.text) } : p;\n storyAdd(story, passage, diagnostics);\n }\n}\n\nfunction isTiddler(node: HtmlNode): boolean {\n return node.type === 'tag' && node.name === 'div' && node.attribs !== undefined && 'tiddler' in node.attribs;\n}\n\nfunction tiddlerToPassage(node: HtmlNode, passageText: PassageText): Passage {\n const nodeAttrs = node.attribs ?? {};\n const name = nodeAttrs['tiddler'] ?? '';\n const tags = nodeAttrs['tags'] ? nodeAttrs['tags'].split(/\\s+/).filter((s: string) => s.length > 0) : [];\n const text = passageText(tiddlerUnescape(getTextContent(node)));\n\n const passage: Passage = { name, tags, text };\n const position = nodeAttrs['twine-position'];\n if (position) {\n passage.metadata = { position };\n }\n return passage;\n}\n\n/** Whether the StorySettings tiddlers turn on ROT13 obfuscation, read the way the writer reads them. */\nfunction isRot13Obfuscated(passages: readonly Passage[]): boolean {\n const settings = createStory();\n for (const p of passages) {\n // Diagnostics are dropped here; storyAdd() reports them when the passage is added.\n if (p.name === 'StorySettings') unmarshalStorySettings(settings, p.text, []);\n }\n return settings.twine1.settings.get('obfuscate') === 'rot13';\n}\n\nfunction findElement(node: HtmlNode, tagName: string): HtmlNode | undefined {\n if (node.type === 'tag' && node.name === tagName) return node;\n for (const child of node.children ?? []) {\n const found = findElement(child, tagName);\n if (found) return found;\n }\n return undefined;\n}\n\nfunction findElementByIdPattern(node: HtmlNode, idPattern: RegExp): HtmlNode | undefined {\n if (node.type === 'tag' && node.attribs?.['id'] && idPattern.test(node.attribs['id'])) return node;\n for (const child of node.children ?? []) {\n const found = findElementByIdPattern(child, idPattern);\n if (found) return found;\n }\n return undefined;\n}\n\nfunction getTextContent(el: HtmlNode): string {\n let text = '';\n for (const child of el.children ?? []) {\n if (child.type === 'text' && child.data) {\n text += child.data;\n }\n }\n return text;\n}\n","/**\n * File loading: dispatch by file extension.\n * Ported from storyload.go.\n */\nimport { basename } from 'node:path';\nimport { statSync } from 'node:fs';\nimport type { Story, Diagnostic, InlineSource, Passage, FileCacheEntry } from './types.js';\nimport { normalizedFileExt, mediaTypeFromFilename, mediaTypeFromExt, fontFormatHint } from './media-types.js';\nimport { storyAdd, storyHas, storyPrepend } from './story.js';\nimport { parseTwee } from './parser.js';\nimport { decompileHTML } from './html-parser.js';\nimport { readUTF8, readBase64, baseNameWithoutExt } from './util.js';\nimport { normalizeSourceText } from './source-text.js';\n\ninterface LoadOptions {\n trim?: boolean;\n twee2Compat?: boolean;\n}\n\n/**\n * Load all source files into a story.\n */\nexport function loadSources(\n story: Story,\n filenames: string[],\n opts: LoadOptions,\n diagnostics: Diagnostic[],\n processedFiles: Set<string>,\n): void {\n for (const filename of filenames) {\n if (processedFiles.has(filename)) {\n diagnostics.push({ level: 'warning', message: `load ${filename}: Skipping duplicate.` });\n continue;\n }\n\n const ext = normalizedFileExt(filename);\n try {\n switch (ext) {\n case 'tw':\n case 'twee':\n loadTwee(story, filename, opts, diagnostics);\n break;\n case 'tw2':\n case 'twee2':\n loadTwee(story, filename, { ...opts, twee2Compat: true }, diagnostics);\n break;\n case 'htm':\n case 'html':\n loadHTML(story, filename, opts, diagnostics);\n break;\n case 'css':\n loadTagged(story, 'stylesheet', filename, diagnostics);\n break;\n case 'js':\n loadTagged(story, 'script', filename, diagnostics);\n break;\n case 'otf':\n case 'ttf':\n case 'woff':\n case 'woff2':\n loadFont(story, filename, diagnostics);\n break;\n case 'gif':\n case 'jpeg':\n case 'jpg':\n case 'png':\n case 'svg':\n case 'tif':\n case 'tiff':\n case 'webp':\n loadMedia(story, 'Twine.image', filename, diagnostics);\n break;\n case 'aac':\n case 'flac':\n case 'm4a':\n case 'mp3':\n case 'oga':\n case 'ogg':\n case 'opus':\n case 'wav':\n case 'wave':\n case 'weba':\n loadMedia(story, 'Twine.audio', filename, diagnostics);\n break;\n case 'mp4':\n case 'ogv':\n case 'webm':\n loadMedia(story, 'Twine.video', filename, diagnostics);\n break;\n case 'vtt':\n loadMedia(story, 'Twine.vtt', filename, diagnostics);\n break;\n default:\n continue;\n }\n } catch (e) {\n diagnostics.push({\n level: 'error',\n message: `load ${filename}: ${e instanceof Error ? e.message : String(e)}`,\n file: filename,\n });\n continue;\n }\n processedFiles.add(filename);\n }\n\n // Prepend StoryTitle if we have a name but no StoryTitle passage.\n if (story.name !== '' && !story.passages.some((p) => p.name === 'StoryTitle')) {\n storyPrepend(story, { name: 'StoryTitle', tags: [], text: story.name }, diagnostics);\n }\n}\n\n/**\n * Load inline sources (string content or InlineSource objects).\n */\nexport function loadInlineSources(\n story: Story,\n sources: (string | InlineSource)[],\n opts: LoadOptions,\n diagnostics: Diagnostic[],\n): void {\n for (const source of sources) {\n if (typeof source === 'string') {\n // Treat as a file path — handled externally\n continue;\n }\n // Normalize like readUTF8() does for files, so in-memory and on-disk sources load the same.\n const content = normalizeSourceText(\n typeof source.content === 'string' ? source.content : source.content.toString('utf-8'),\n );\n\n const ext = normalizedFileExt(source.filename);\n switch (ext) {\n case '':\n case 'tw':\n case 'twee':\n case 'tw2':\n case 'twee2': {\n const twee2 = ext === 'tw2' || ext === 'twee2' || opts.twee2Compat;\n const result = parseTwee(content, {\n filename: source.filename,\n trim: opts.trim ?? true,\n twee2Compat: twee2,\n });\n diagnostics.push(...result.diagnostics);\n for (const p of result.passages) {\n storyAdd(story, p, diagnostics);\n }\n break;\n }\n case 'css':\n storyAdd(story, { name: basename(source.filename), tags: ['stylesheet'], text: content }, diagnostics);\n break;\n case 'js':\n storyAdd(story, { name: basename(source.filename), tags: ['script'], text: content }, diagnostics);\n break;\n default:\n diagnostics.push({\n level: 'warning',\n message: `load ${source.filename}: in-memory sources of type .${ext} are not supported; skipped.`,\n });\n }\n }\n}\n\ninterface ParseResult {\n passages: Passage[];\n diagnostics: Diagnostic[];\n}\n\nfunction parseTweeFile(filename: string, opts: LoadOptions): ParseResult {\n const source = readUTF8(filename);\n const result = parseTwee(source, {\n filename,\n trim: opts.trim ?? true,\n twee2Compat: opts.twee2Compat ?? false,\n });\n return { passages: result.passages, diagnostics: [...result.diagnostics] };\n}\n\nfunction parseTaggedFile(tag: string, filename: string): ParseResult {\n const source = readUTF8(filename);\n return { passages: [{ name: basename(filename), tags: [tag], text: source }], diagnostics: [] };\n}\n\nfunction parseMediaFile(tag: string, filename: string): ParseResult {\n const source = readBase64(filename);\n const name = baseNameWithoutExt(filename);\n return {\n passages: [{ name, tags: [tag], text: `data:${mediaTypeFromFilename(filename)};base64,${source}` }],\n diagnostics: [],\n };\n}\n\nfunction parseFontFile(filename: string): ParseResult {\n const source = readBase64(filename);\n const name = basename(filename);\n const family = baseNameWithoutExt(filename);\n const ext = normalizedFileExt(filename);\n const mediaType = mediaTypeFromExt(ext);\n const hint = fontFormatHint(ext);\n return {\n passages: [\n {\n name,\n tags: ['stylesheet'],\n text: `@font-face {\\n\\tfont-family: \"${family}\";\\n\\tsrc: url(\"data:${mediaType};base64,${source}\") format(\"${hint}\");\\n}`,\n },\n ],\n diagnostics: [],\n };\n}\n\nfunction parseHTMLFile(filename: string, opts: LoadOptions): ParseResult {\n const { story, diagnostics } = decompileHTML(readUTF8(filename), { trim: opts.trim ?? true });\n // Twine 2 HTML keeps the story name in an attribute, not a passage. Only passages reach the\n // outer story (and the cache), so carry the name as a StoryTitle passage, as Twine 1 HTML does.\n const passages =\n story.name !== '' && !storyHas(story, 'StoryTitle')\n ? [{ name: 'StoryTitle', tags: [], text: story.name }, ...story.passages]\n : story.passages;\n return { passages, diagnostics: [...diagnostics] };\n}\n\n/**\n * Identity of the options that affect how a file parses, stored on its cache entry.\n * Twee files depend on `trim` and `twee2Compat`, HTML files on `trim`; every other file type\n * yields the same key for all options.\n */\nfunction parseOptionsKey(filename: string, opts: LoadOptions): string {\n const ext = normalizedFileExt(filename);\n const trim = opts.trim ?? true;\n if (ext === 'htm' || ext === 'html') return JSON.stringify({ trim });\n const twee2File = ext === 'tw2' || ext === 'twee2';\n if (!twee2File && ext !== 'tw' && ext !== 'twee') return '';\n return JSON.stringify({ trim, twee2Compat: twee2File || (opts.twee2Compat ?? false) });\n}\n\nfunction parseFile(filename: string, opts: LoadOptions): ParseResult | undefined {\n const ext = normalizedFileExt(filename);\n switch (ext) {\n case 'tw':\n case 'twee':\n return parseTweeFile(filename, opts);\n case 'tw2':\n case 'twee2':\n return parseTweeFile(filename, { ...opts, twee2Compat: true });\n case 'htm':\n case 'html':\n return parseHTMLFile(filename, opts);\n case 'css':\n return parseTaggedFile('stylesheet', filename);\n case 'js':\n return parseTaggedFile('script', filename);\n case 'otf':\n case 'ttf':\n case 'woff':\n case 'woff2':\n return parseFontFile(filename);\n case 'gif':\n case 'jpeg':\n case 'jpg':\n case 'png':\n case 'svg':\n case 'tif':\n case 'tiff':\n case 'webp':\n return parseMediaFile('Twine.image', filename);\n case 'aac':\n case 'flac':\n case 'm4a':\n case 'mp3':\n case 'oga':\n case 'ogg':\n case 'opus':\n case 'wav':\n case 'wave':\n case 'weba':\n return parseMediaFile('Twine.audio', filename);\n case 'mp4':\n case 'ogv':\n case 'webm':\n return parseMediaFile('Twine.video', filename);\n case 'vtt':\n return parseMediaFile('Twine.vtt', filename);\n default:\n return undefined;\n }\n}\n\nfunction loadHTML(story: Story, filename: string, opts: LoadOptions, diagnostics: Diagnostic[]): void {\n const result = parseHTMLFile(filename, opts);\n diagnostics.push(...result.diagnostics);\n for (const p of result.passages) {\n storyAdd(story, p, diagnostics);\n }\n}\n\nfunction loadTwee(story: Story, filename: string, opts: LoadOptions, diagnostics: Diagnostic[]): void {\n const result = parseTweeFile(filename, opts);\n diagnostics.push(...result.diagnostics);\n for (const p of result.passages) {\n storyAdd(story, p, diagnostics);\n }\n}\n\nfunction loadTagged(story: Story, tag: string, filename: string, diagnostics: Diagnostic[]): void {\n const result = parseTaggedFile(tag, filename);\n for (const p of result.passages) {\n storyAdd(story, p, diagnostics);\n }\n}\n\nfunction loadMedia(story: Story, tag: string, filename: string, diagnostics: Diagnostic[]): void {\n const result = parseMediaFile(tag, filename);\n for (const p of result.passages) {\n storyAdd(story, p, diagnostics);\n }\n}\n\nfunction loadFont(story: Story, filename: string, diagnostics: Diagnostic[]): void {\n const result = parseFontFile(filename);\n for (const p of result.passages) {\n storyAdd(story, p, diagnostics);\n }\n}\n\n/**\n * Load sources with mtime-based caching for incremental rebuilds.\n * Always creates a fresh Story; cached passages are replayed via storyAdd().\n */\nexport function loadSourcesCached(\n story: Story,\n filenames: string[],\n opts: LoadOptions,\n diagnostics: Diagnostic[],\n processedFiles: Set<string>,\n cache: Map<string, FileCacheEntry>,\n changedFiles?: ReadonlySet<string>,\n): void {\n const currentFiles = new Set<string>();\n\n for (const filename of filenames) {\n if (processedFiles.has(filename)) {\n diagnostics.push({ level: 'warning', message: `load ${filename}: Skipping duplicate.` });\n continue;\n }\n\n currentFiles.add(filename);\n const optionsKey = parseOptionsKey(filename, opts);\n // An entry parsed under other options (or without a recorded key) is stale.\n const entry = cache.get(filename);\n const cached = entry?.parseOptionsKey === optionsKey ? entry : undefined;\n // A file changedFiles names is always reparsed: a save can keep the modification time\n // (a timestamp-preserving write, or a filesystem with coarse timestamps).\n const changed = changedFiles?.has(filename) ?? false;\n\n // If changedFiles is provided and this file isn't changed and we have a cache hit, skip stat\n if (changedFiles && cached && !changed) {\n diagnostics.push(...cached.diagnostics);\n for (const p of cached.passages) {\n storyAdd(story, p, diagnostics);\n }\n processedFiles.add(filename);\n continue;\n }\n\n // stat the file to check mtime\n let mtimeMs: number;\n try {\n mtimeMs = statSync(filename).mtimeMs;\n } catch {\n // File may have been deleted between getFilenames and here\n continue;\n }\n\n // Cache hit with matching mtime, for a file not known to have changed: replay\n if (cached && !changed && cached.mtimeMs === mtimeMs) {\n diagnostics.push(...cached.diagnostics);\n for (const p of cached.passages) {\n storyAdd(story, p, diagnostics);\n }\n processedFiles.add(filename);\n continue;\n }\n\n // Cache miss: parse and store\n try {\n const result = parseFile(filename, opts);\n if (!result) continue;\n\n cache.set(filename, {\n mtimeMs,\n parseOptionsKey: optionsKey,\n passages: result.passages,\n diagnostics: result.diagnostics,\n });\n\n diagnostics.push(...result.diagnostics);\n for (const p of result.passages) {\n storyAdd(story, p, diagnostics);\n }\n } catch (e) {\n diagnostics.push({\n level: 'error',\n message: `load ${filename}: ${e instanceof Error ? e.message : String(e)}`,\n file: filename,\n });\n continue;\n }\n processedFiles.add(filename);\n }\n\n // Purge cache entries for deleted files\n for (const key of cache.keys()) {\n if (!currentFiles.has(key)) {\n cache.delete(key);\n }\n }\n\n // Prepend StoryTitle if we have a name but no StoryTitle passage.\n if (story.name !== '' && !story.passages.some((p) => p.name === 'StoryTitle')) {\n storyPrepend(story, { name: 'StoryTitle', tags: [], text: story.name }, diagnostics);\n }\n}\n","/**\n * The twee-ts version, read at runtime from the package's own package.json.\n *\n * The release workflow (semantic-release) writes the new version into the\n * published package.json only; git keeps the old one. Reading it at runtime\n * is the only way the CLI and `creator-version` report the published version.\n */\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst PACKAGE_NAME = '@rohal12/twee-ts';\n\n/** Walks up from `startDir` to the nearest package.json named @rohal12/twee-ts and returns its version. */\nexport function findPackageVersion(startDir: string): string | undefined {\n let dir = startDir;\n for (;;) {\n try {\n const pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf-8')) as { name?: unknown; version?: unknown };\n if (pkg.name === PACKAGE_NAME && typeof pkg.version === 'string') return pkg.version;\n } catch {\n // No readable package.json here; keep walking up.\n }\n const parent = dirname(dir);\n if (parent === dir) return undefined;\n dir = parent;\n }\n}\n\n/** This module's directory: `__dirname` in the CJS build, `import.meta.url` in ESM and in source. */\nfunction moduleDir(): string {\n return typeof __dirname === 'string' ? __dirname : dirname(fileURLToPath(import.meta.url));\n}\n\nexport const VERSION: string = findPackageVersion(moduleDir()) ?? '0.0.0';\n","/**\n * Twine 2 HTML and archive output.\n * Ported from storyout.go.\n */\nimport type { OmittingTag, PassageOmission, ReadonlyStory, ReadonlyPassage, StoryFormatInfo } from './types.js';\nimport {\n attrEscape,\n htmlEscape,\n commentSanitize,\n htmlCommentSanitize,\n scriptContentEscape,\n styleContentEscape,\n} from './escape.js';\nimport { passageToPassagedata, hasTag } from './passage.js';\nimport { readFormatSource } from './formats.js';\nimport { VERSION } from './version.js';\n\nconst CREATOR_NAME = 'Twee-ts';\n\nexport function toTwine2Archive(\n story: ReadonlyStory,\n startName: string,\n options?: { readonly sourceInfo?: boolean },\n): string {\n return getTwine2DataChunk(story, startName, options) + '\\n';\n}\n\nexport function toTwine2HTML(\n story: ReadonlyStory,\n format: StoryFormatInfo,\n startName: string,\n options?: { readonly sourceInfo?: boolean },\n): string {\n let template = readFormatSource(format);\n\n if (template.includes('{{STORY_NAME}}')) {\n const name = htmlEscape(story.name);\n template = template.replaceAll('{{STORY_NAME}}', () => name);\n }\n if (template.includes('{{STORY_DATA}}')) {\n // Advertise the format this HTML was built with (as Tweego does), not whatever StoryData named.\n const built = { ...story, twine2: { ...story.twine2, format: format.name, formatVersion: format.version } };\n const data = getTwine2DataChunk(built, startName, options);\n template = template.replace('{{STORY_DATA}}', () => data);\n }\n\n return template;\n}\n\nconst OMITTING_TAGS: readonly OmittingTag[] = ['Twine.private', 'script', 'stylesheet'];\n\n/**\n * Why Twine 2 output leaves a passage out of its `<tw-passagedata>` elements,\n * or `undefined` when the passage is emitted (and so can be the starting passage).\n */\nexport function twine2PassageOmission(story: ReadonlyStory, p: ReadonlyPassage): PassageOmission | undefined {\n if (p.name === 'StoryTitle' || p.name === 'StoryData') return { kind: 'special-name', name: p.name };\n const tag = OMITTING_TAGS.find((t) => hasTag(p, t));\n if (tag !== undefined) return { kind: 'tag', tag };\n // Drop empty StorySettings\n if (p.name === 'StorySettings' && story.twine1.settings.size === 0) return { kind: 'empty-story-settings' };\n return undefined;\n}\n\nfunction getTwine2DataChunk(\n story: ReadonlyStory,\n startName: string,\n options?: { readonly sourceInfo?: boolean },\n): string {\n const parts: string[] = [];\n let startID = '';\n let pid = 0;\n\n // Gather script and stylesheet passages.\n const scripts: ReadonlyPassage[] = [];\n const stylesheets: ReadonlyPassage[] = [];\n for (const p of story.passages) {\n if (hasTag(p, 'Twine.private')) continue;\n if (hasTag(p, 'script')) scripts.push(p);\n else if (hasTag(p, 'stylesheet')) stylesheets.push(p);\n }\n\n // Style element\n let styleContent = '';\n if (stylesheets.length === 1) {\n styleContent = stylesheets[0]?.text ?? '';\n } else if (stylesheets.length > 1) {\n let pidS = 1;\n for (const p of stylesheets) {\n if (pidS > 1 && !styleContent.endsWith('\\n')) styleContent += '\\n';\n styleContent += `/* twine-user-stylesheet #${pidS}: \"${commentSanitize(p.name)}\" */\\n`;\n styleContent += p.text;\n pidS++;\n }\n }\n parts.push(\n `<style role=\"stylesheet\" id=\"twine-user-stylesheet\" type=\"text/twine-css\">${styleContentEscape(styleContent)}</style>`,\n );\n\n // Script element\n let scriptContent = '';\n if (scripts.length === 1) {\n scriptContent = scripts[0]?.text ?? '';\n } else if (scripts.length > 1) {\n let pidS = 1;\n for (const p of scripts) {\n if (pidS > 1 && !scriptContent.endsWith('\\n')) scriptContent += '\\n';\n scriptContent += `/* twine-user-script #${pidS}: \"${commentSanitize(p.name)}\" */\\n`;\n scriptContent += p.text;\n pidS++;\n }\n }\n parts.push(\n `<script role=\"script\" id=\"twine-user-script\" type=\"text/twine-javascript\">${scriptContentEscape(scriptContent)}</script>`,\n );\n\n // Tag color elements (only spec-valid colors: 7 named colors or hex values)\n const validTagColors = new Set(['gray', 'red', 'orange', 'yellow', 'green', 'blue', 'purple']);\n const hexColorPattern = /^#[0-9a-fA-F]{3,8}$/;\n for (const [tag, color] of story.twine2.tagColors) {\n if (validTagColors.has(color) || hexColorPattern.test(color)) {\n parts.push(`<tw-tag name=\"${attrEscape(tag)}\" color=\"${attrEscape(color)}\"></tw-tag>`);\n }\n }\n\n // Normal passage elements\n pid = 1;\n for (const p of story.passages) {\n if (twine2PassageOmission(story, p) !== undefined) continue;\n\n parts.push(passageToPassagedata(p, pid, options));\n if (startName === p.name) {\n startID = String(pid);\n }\n pid++;\n }\n\n // Build options string\n const opts: string[] = [];\n for (const [opt, val] of story.twine2.options) {\n if (val) opts.push(opt);\n }\n const optionsStr = opts.join(' ');\n\n // Wrap in tw-storydata\n const zoom = String(story.twine2.zoom);\n\n const wrapper =\n `<!-- UUID://${htmlCommentSanitize(story.ifid)}// -->` +\n `<tw-storydata name=\"${attrEscape(story.name)}\" startnode=\"${attrEscape(startID)}\" ` +\n `creator=\"${attrEscape(CREATOR_NAME)}\" creator-version=\"${attrEscape(VERSION)}\" ` +\n `ifid=\"${attrEscape(story.ifid)}\" zoom=\"${attrEscape(zoom)}\" ` +\n `format=\"${attrEscape(story.twine2.format)}\" ` +\n `format-version=\"${attrEscape(story.twine2.formatVersion)}\" ` +\n `options=\"${attrEscape(optionsStr)}\" tags=\"${attrEscape(story.twine2.tags)}\" hidden>`;\n\n return wrapper + parts.join('') + '</tw-storydata>';\n}\n","/**\n * Twine 1 HTML and archive output.\n * Ported from storyout.go.\n */\nimport { readFileSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport type { PassageOmission, ReadonlyPassage, ReadonlyStory, StoryFormatInfo } from './types.js';\nimport { hasTag, passageToTiddler } from './passage.js';\nimport { readFormatSource } from './formats.js';\nimport { jsStringEscape, htmlCommentSanitize } from './escape.js';\nimport { VERSION } from './version.js';\n\nconst CREATOR_NAME = 'twee-ts';\n\nexport function toTwine1Archive(story: ReadonlyStory, _startName: string): string {\n const { data, count } = getTwine1PassageChunk(story);\n return `<div id=\"storeArea\" data-size=\"${count}\">${data}</div>\\n`;\n}\n\nexport function toTwine1HTML(story: ReadonlyStory, format: StoryFormatInfo, startName: string): string {\n const formatDir = dirname(format.filename);\n const parentDir = dirname(formatDir);\n let template = readFormatSource(format);\n const { data, count } = getTwine1PassageChunk(story);\n\n // Component replacements\n template = tryReplaceComponent(template, '\"USER_LIB\"', join(formatDir, 'userlib.js'), false);\n template = tryReplaceComponent(template, '\"ENGINE\"', join(parentDir, 'engine.js'), true);\n template = tryReplaceComponent(template, '\"SUGARCANE\"', join(formatDir, 'code.js'), true);\n template = tryReplaceComponent(template, '\"JONAH\"', join(formatDir, 'code.js'), true);\n\n if (story.twine1.settings.get('jquery') === 'on') {\n template = tryReplaceComponent(template, '\"JQUERY\"', join(parentDir, 'jquery.js'), true);\n }\n if (story.twine1.settings.get('modernizr') === 'on') {\n template = tryReplaceComponent(template, '\"MODERNIZR\"', join(parentDir, 'modernizr.js'), true);\n }\n\n // Story instance replacements\n const displayStart = startName === 'Start' ? '' : startName;\n template = template.replace('\"VERSION\"', `Compiled with ${CREATOR_NAME}, ${VERSION}`);\n template = template.replace('\"TIME\"', `Built on ${new Date().toUTCString()}`);\n const startAtValue = `\"${jsStringEscape(displayStart)}\"`;\n template = template.replace('\"START_AT\"', () => startAtValue);\n template = template.replace('\"STORY_SIZE\"', `\"${count}\"`);\n\n if (template.includes('\"STORY\"')) {\n template = template.replace('\"STORY\"', () => data);\n } else {\n // Pre-1.4 format: append data + footer\n let footer: string;\n try {\n footer = readFileSync(join(formatDir, 'footer.html'), 'utf-8');\n } catch {\n footer = '</div>\\n</body>\\n</html>\\n';\n }\n template += data + footer;\n }\n\n // IFID replacement\n if (story.ifid) {\n const safeIfid = htmlCommentSanitize(story.ifid);\n if (template.includes('<div id=\"store-area\"')) {\n template = template.replace('<div id=\"store-area\"', `<!-- UUID://${safeIfid}// --><div id=\"store-area\"`);\n } else {\n template = template.replace('<div id=\"storeArea\"', `<!-- UUID://${safeIfid}// --><div id=\"storeArea\"`);\n }\n }\n\n return template;\n}\n\n/**\n * Why Twine 1 output leaves a passage out of its tiddlers, or `undefined` when the passage is emitted.\n */\nexport function twine1PassageOmission(p: ReadonlyPassage): PassageOmission | undefined {\n return hasTag(p, 'Twine.private') ? { kind: 'tag', tag: 'Twine.private' } : undefined;\n}\n\nfunction getTwine1PassageChunk(story: ReadonlyStory): { data: string; count: number } {\n const obfuscateRot13 = story.twine1.settings.get('obfuscate') === 'rot13';\n let data = '';\n let count = 0;\n\n for (const p of story.passages) {\n if (twine1PassageOmission(p) !== undefined) continue;\n count++;\n data += passageToTiddler(p, count, obfuscateRot13);\n }\n\n return { data, count };\n}\n\nfunction tryReplaceComponent(template: string, placeholder: string, componentPath: string, required: boolean): string {\n if (!template.includes(placeholder)) return template;\n try {\n let content = readFileSync(componentPath, 'utf-8');\n if (content.charCodeAt(0) === 0xfeff) content = content.slice(1);\n return template.replace(placeholder, () => content);\n } catch (e) {\n if (required) {\n throw new Error(\n `Required format component not found: ${componentPath}: ${e instanceof Error ? e.message : String(e)}`,\n );\n }\n return template;\n }\n}\n","/**\n * Twee 3/1 decompile output.\n * Ported from storyout.go.\n */\nimport type { ReadonlyStory, ReadonlyPassage, OutputMode } from './types.js';\nimport { passageToTwee } from './passage.js';\nimport { createStory, marshalStoryData, unmarshalStoryData } from './story.js';\n\n/**\n * Serialize the story as Twee. The StoryData passage is written from the story model rather than\n * from its loaded text, so changes made after loading (a start passage override, test mode) are kept.\n * Tweego writes the loaded text; its own normalization makes the two the same for an unchanged story.\n *\n * `addStoryData`: add a StoryData passage when the story has none, so that StoryData fields the\n * compile options set are recorded. Default: false.\n */\nexport function toTwee(\n story: ReadonlyStory,\n outMode: OutputMode,\n options: { readonly addStoryData?: boolean } = {},\n): string {\n return withEffectiveStoryData(story, options.addStoryData ?? false)\n .map((p) => passageToTwee(p, outMode))\n .join('');\n}\n\nfunction withEffectiveStoryData(story: ReadonlyStory, addStoryData: boolean): readonly ReadonlyPassage[] {\n const storyData: ReadonlyPassage = { name: 'StoryData', tags: [], text: marshalStoryData(story) };\n const index = story.passages.findIndex((p) => p.name === 'StoryData');\n if (index !== -1) {\n return story.passages.map((p, i) => (i === index && isStoryDataJSON(p.text) ? { ...p, text: storyData.text } : p));\n }\n if (!addStoryData) return story.passages;\n // Place it where Twine and the HTML decompiler do: first, or right after a leading StoryTitle.\n const at = story.passages[0]?.name === 'StoryTitle' ? 1 : 0;\n return [...story.passages.slice(0, at), storyData, ...story.passages.slice(at)];\n}\n\n/** Whether the text loaded as StoryData. Text that did not is kept as written, for the author to fix. */\nfunction isStoryDataJSON(text: string): boolean {\n return unmarshalStoryData(createStory(), text) === null;\n}\n","/**\n * Module/head injection into <head>.\n * Ported from module.go + io.go:modifyHead().\n */\nimport type { Diagnostic } from './types.js';\nimport { normalizedFileExt, mediaTypeFromExt, fontFormatHint, slugify } from './media-types.js';\nimport { readUTF8, readBase64, baseNameWithoutExt } from './util.js';\nimport { scriptContentEscape, styleContentEscape } from './escape.js';\n\n/**\n * Load modules and return HTML tags to inject before </head>.\n */\nexport function loadModules(filenames: string[]): string {\n const processed = new Set<string>();\n const headTags: string[] = [];\n\n for (const filename of filenames) {\n if (processed.has(filename)) continue;\n\n const ext = normalizedFileExt(filename);\n let tag: string | null = null;\n\n switch (ext) {\n case 'css':\n tag = loadModuleTagged('style', filename);\n break;\n case 'js':\n tag = loadModuleTagged('script', filename);\n break;\n case 'otf':\n case 'ttf':\n case 'woff':\n case 'woff2':\n tag = loadModuleFont(filename);\n break;\n default:\n continue;\n }\n\n if (tag) headTags.push(tag);\n processed.add(filename);\n }\n\n return headTags.join('\\n');\n}\n\nfunction loadModuleTagged(tag: 'script' | 'style', filename: string): string | null {\n const source = readUTF8(filename).trim();\n if (source.length === 0) return null;\n\n const family = baseNameWithoutExt(filename);\n const idSlug = `${tag}-module-${slugify(family)}`;\n const mimeType = tag === 'script' ? 'text/javascript' : 'text/css';\n const content = tag === 'script' ? scriptContentEscape(source) : styleContentEscape(source);\n\n return `<${tag} id=\"${idSlug}\" type=\"${mimeType}\">${content}</${tag}>`;\n}\n\nfunction loadModuleFont(filename: string): string | null {\n const source = readBase64(filename);\n const family = baseNameWithoutExt(filename);\n const idSlug = `style-module-${slugify(family)}`;\n const ext = normalizedFileExt(filename);\n const mediaType = mediaTypeFromExt(ext);\n const hint = fontFormatHint(ext);\n\n return `<style id=\"${idSlug}\" type=\"text/css\">@font-face {\\n\\tfont-family: \"${family}\";\\n\\tsrc: url(\"data:${mediaType};base64,${source}\") format(\"${hint}\");\\n}</style>`;\n}\n\n/**\n * Inject modules and head file content before </head>.\n */\nexport function modifyHead(html: string, modulePaths: string[], headFile?: string, diagnostics?: Diagnostic[]): string {\n const parts: string[] = [];\n\n if (modulePaths.length > 0) {\n const modules = loadModules(modulePaths).trim();\n if (modules.length > 0) parts.push(modules);\n }\n\n if (headFile) {\n try {\n const source = readUTF8(headFile).trim();\n if (source.length > 0) parts.push(source);\n } catch (e) {\n diagnostics?.push({\n level: 'warning',\n message: `Failed to read head file \"${headFile}\": ${e instanceof Error ? e.message : String(e)}`,\n });\n }\n }\n\n if (parts.length > 0) {\n parts.push('</head>');\n const replacement = parts.join('\\n');\n return html.replace('</head>', () => replacement);\n }\n return html;\n}\n","/**\n * Which passages an output leaves out of its passage elements, and how to say why.\n * The rules themselves live with each output renderer; this module picks one by target.\n */\nimport type { PassageOmission, PassageOutputTarget, ReadonlyPassage, ReadonlyStory } from './types.js';\nimport { twine2PassageOmission } from './output-twine2.js';\nimport { twine1PassageOmission } from './output-twine1.js';\n\n/**\n * Why the `target` output leaves `passage` out of its passage elements, or `undefined` when it\n * emits the passage (and so a link or the start can name it).\n */\nexport function passageOmission(\n story: ReadonlyStory,\n passage: ReadonlyPassage,\n target: PassageOutputTarget,\n): PassageOmission | undefined {\n switch (target) {\n case 'twine2':\n return twine2PassageOmission(story, passage);\n case 'twine1':\n return twine1PassageOmission(passage);\n default: {\n const _exhaustive: never = target;\n throw new Error(`unhandled passage output target: ${String(_exhaustive)}`);\n }\n }\n}\n\n/** Why a passage is left out, as a predicate: `Passage \"X\" ${describeOmission(o)}`. */\nexport function describeOmission(omission: PassageOmission): string {\n switch (omission.kind) {\n case 'special-name':\n return `is the special \"${omission.name}\" passage`;\n case 'tag':\n return `is tagged \"${omission.tag}\"`;\n case 'empty-story-settings':\n return 'is an empty \"StorySettings\" passage';\n default: {\n const _exhaustive: never = omission;\n throw new Error(`unhandled passage omission: ${JSON.stringify(_exhaustive)}`);\n }\n }\n}\n","/**\n * Starting passage validation: the effective start must exist and be a\n * passage that the output actually emits, or the story has nowhere to begin.\n */\nimport type { Diagnostic, PassageOutputTarget, ReadonlyStory } from './types.js';\nimport { describeOmission, passageOmission } from './passage-omission.js';\n\n/**\n * Check that `startName` names a passage the `target` output emits.\n * Returns the error diagnostics to report (empty when the start is usable).\n */\nexport function startPassageDiagnostics(\n story: ReadonlyStory,\n startName: string,\n target: PassageOutputTarget,\n): readonly Diagnostic[] {\n const passage = story.passages.find((p) => p.name === startName);\n if (passage === undefined) {\n return [{ level: 'error', message: `Starting passage \"${startName}\" not found.` }];\n }\n const omission = passageOmission(story, passage, target);\n if (omission === undefined) return [];\n return [\n {\n level: 'error',\n message: `Starting passage \"${startName}\" ${describeOmission(omission)}, so it is left out of the story data. Choose a story passage.`,\n },\n ];\n}\n","/**\n * Main compiler orchestrator.\n * compile(), compileToFile(), watch().\n * Ported from tweego.go + config.go.\n */\nimport { writeFileSync } from 'node:fs';\nimport { resolve, sep } from 'node:path';\nimport type {\n CompileOptions,\n CompileToFileOptions,\n WatchOptions,\n CompileResult,\n CompileStats,\n Diagnostic,\n Story,\n StoryFormatInfo,\n OutputMode,\n InlineSource,\n FileCacheEntry,\n} from './types.js';\nimport { createStory, storyHas, getStoryStats } from './story.js';\nimport { getFilenames, isExcluded, watchFilesystem } from './filesystem.js';\nimport { formatRequestFor, resolveStoryFormat } from './format-resolution.js';\nimport { loadSources, loadInlineSources, loadSourcesCached } from './loader.js';\nimport { applyTagAliases, hasTag } from './passage.js';\nimport { generateIFID } from './ifid.js';\nimport { toTwine2HTML, toTwine2Archive } from './output-twine2.js';\nimport { toTwine1HTML, toTwine1Archive } from './output-twine1.js';\nimport { toTwee } from './output-twee.js';\nimport { modifyHead } from './modules.js';\nimport { startPassageDiagnostics } from './start-passage.js';\nimport { clearIndexCache } from './remote-formats.js';\nimport { VERSION } from './version.js';\n\nconst CREATOR_NAME = 'Twee-ts';\n\nconst DEFAULT_FORMAT_ID = 'sugarcube-2';\nconst DEFAULT_START_NAME = 'Start';\n\nexport class TweeTsError extends Error {\n constructor(\n message: string,\n public diagnostics: Diagnostic[] = [],\n ) {\n super(message);\n this.name = 'TweeTsError';\n }\n}\n\n/**\n * Compile Twee sources to HTML, Twee, or JSON.\n */\nexport async function compile(options: CompileOptions): Promise<CompileResult> {\n return buildOutput(options);\n}\n\n/**\n * Compile and write to a file.\n */\nexport async function compileToFile(options: CompileToFileOptions): Promise<CompileResult> {\n const result = await compileForOutputFile(options, options.outFile);\n writeFileSync(options.outFile, result.output, 'utf-8');\n return result;\n}\n\n/**\n * Builds as compileToFile() does for `outFile`, without writing it: the output may sit\n * inside a source folder, so its last build is left out of the sources and modules and\n * never read back. The caller decides whether the result is written. With no `outFile`\n * (output to stdout, or none), this is compile().\n *\n * Internal, for the CLI; not part of the public API.\n */\nexport async function compileForOutputFile(\n options: CompileOptions,\n outFile: string | undefined,\n): Promise<CompileResult> {\n return buildOutput(options, undefined, undefined, outFile);\n}\n\n/**\n * Compile with incremental caching support.\n * Plugins and advanced users can manage their own cache and changed-file tracking.\n *\n * Without `changedFiles`, a cached file is reused while its modification time is unchanged.\n * With it, a file it names (by the path source discovery gives it, relative to the working\n * directory) is always reparsed, whatever its modification time, and every other cached\n * file is reused as it is.\n */\nexport async function compileIncremental(\n options: CompileOptions,\n cache: Map<string, FileCacheEntry>,\n changedFiles?: ReadonlySet<string>,\n): Promise<CompileResult> {\n return buildOutput(options, cache, changedFiles);\n}\n\n/**\n * Watch for file changes and recompile. Every build is written to `outFile`, including\n * one whose diagnostics report errors.\n */\nexport async function watch(options: WatchOptions): Promise<AbortController> {\n return watchWithWriteFilter(options, () => true);\n}\n\n/**\n * watch(), writing to `outFile` only the builds `shouldWrite` accepts. A rejected build\n * leaves the output file as it was; `onBuild` receives every build either way.\n *\n * Internal, for the CLI, which keeps the last good output when a rebuild reports errors;\n * not part of the public API.\n */\nexport async function watchWithWriteFilter(\n options: WatchOptions,\n shouldWrite: (result: CompileResult) => boolean,\n): Promise<AbortController> {\n const controller = new AbortController();\n const cache = new Map<string, FileCacheEntry>();\n\n // Separate file paths from inline sources\n const filePaths = options.sources.filter((s): s is string => typeof s === 'string');\n const modulePaths = options.modules ?? [];\n const headPaths = options.headFile ? [options.headFile] : [];\n const allPaths = [...filePaths, ...modulePaths, ...headPaths];\n\n // A change to an excluded source builds nothing. `exclude` leaves modules and the\n // head file alone, so a module (or a file in a module folder) or the head file\n // still rebuilds when a glob matches it.\n const exclude = options.exclude ?? [];\n const notExcludable = [...modulePaths, ...headPaths].map((p) => resolve(p));\n const ignore = (filename: string): boolean => {\n if (!isExcluded(filename, exclude)) return false;\n const abs = resolve(filename);\n return !notExcludable.some((root) => abs === root || abs.startsWith(root + sep));\n };\n\n const handle = watchFilesystem(\n allPaths,\n options.outFile,\n (changedFiles) => {\n buildOutput(options, cache, changedFiles, options.outFile)\n .then((result) => {\n if (shouldWrite(result)) writeFileSync(options.outFile, result.output, 'utf-8');\n options.onBuild?.(result);\n })\n .catch((e) => {\n options.onError?.(e instanceof Error ? e : new Error(String(e)));\n });\n },\n ignore,\n );\n\n controller.signal.addEventListener('abort', () => handle.close());\n return controller;\n}\n\n/**\n * `outFile`: the file the build is written to, which source and module discovery\n * skip (as Tweego does), so an output inside a source folder is never loaded back.\n */\nasync function buildOutput(\n options: CompileOptions,\n cache?: Map<string, FileCacheEntry>,\n changedFiles?: ReadonlySet<string>,\n outFile?: string,\n): Promise<CompileResult> {\n const diagnostics: Diagnostic[] = [];\n const outputMode: OutputMode = options.outputMode ?? 'html';\n const trim = options.trim ?? true;\n const twee2Compat = options.twee2Compat ?? false;\n const testMode = options.testMode ?? false;\n const noRemote = options.noRemote ?? false;\n const sourceInfo = options.sourceInfo ?? false;\n\n // Clear per-compile index cache\n clearIndexCache();\n\n // Separate file paths from inline sources\n const filePaths: string[] = [];\n const inlineSources: InlineSource[] = [];\n for (const source of options.sources) {\n if (typeof source === 'string') {\n filePaths.push(source);\n } else {\n inlineSources.push(source);\n }\n }\n\n // Walk file paths to get all source filenames\n const { filenames: sourceFilenames, diagnostics: sourcePathDiagnostics } = getFilenames(\n filePaths,\n outFile,\n options.exclude,\n );\n diagnostics.push(...sourcePathDiagnostics);\n\n // Create story and load sources\n const story = createStory();\n const processedFiles = new Set<string>();\n\n if (cache) {\n loadSourcesCached(story, sourceFilenames, { trim, twee2Compat }, diagnostics, processedFiles, cache, changedFiles);\n } else {\n loadSources(story, sourceFilenames, { trim, twee2Compat }, diagnostics, processedFiles);\n }\n loadInlineSources(story, inlineSources, { trim, twee2Compat }, diagnostics);\n\n // Apply tag aliases (e.g. library → script)\n if (options.tagAliases) {\n story.passages = applyTagAliases(story.passages, options.tagAliases);\n }\n\n // Resolve format: explicit formatId > StoryData format > default, looked up locally,\n // in the download cache, then remotely. An unavailable request is an error, never another format.\n let format: StoryFormatInfo | undefined;\n\n if (outputMode === 'html') {\n const request = formatRequestFor(\n options.formatId,\n story.twine2.format,\n story.twine2.formatVersion,\n DEFAULT_FORMAT_ID,\n );\n format = await resolveStoryFormat(request, { ...options, noRemote }, diagnostics);\n }\n\n // Merge config from StoryData: command-line > StoryData > default.\n // An explicit override is recorded on the story so JSON output and inspection see it too.\n if (options.startPassage) story.twine2.start = options.startPassage;\n const startName = story.twine2.start || DEFAULT_START_NAME;\n\n // Apply test mode\n if (testMode) {\n story.twine2.options.set('debug', true);\n }\n\n // Ensure IFID is set before output generation\n ensureIFID(story, diagnostics);\n\n // Generate output\n let output: string;\n\n switch (outputMode) {\n case 'twee3':\n case 'twee1':\n // Without a StoryData passage, add one only to record what the options changed.\n output = toTwee(story, outputMode, { addStoryData: Boolean(options.startPassage) || testMode });\n break;\n\n case 'twine2-archive':\n output = toTwine2Archive(story, startName, { sourceInfo });\n break;\n\n case 'twine1-archive':\n output = toTwine1Archive(story, startName);\n break;\n\n case 'json':\n output = storyToJSON(story);\n break;\n\n case 'html': {\n // Sanity checks for HTML mode\n diagnostics.push(...startPassageDiagnostics(story, startName, format?.isTwine2 === false ? 'twine1' : 'twine2'));\n\n if (!format) {\n throw new TweeTsError('No story format available for HTML output.', diagnostics);\n }\n\n if (format.isTwine2) {\n output = toTwine2HTML(story, format, startName, { sourceInfo });\n } else {\n if (story.name === '' && !storyHas(story, 'StoryTitle')) {\n diagnostics.push({\n level: 'error',\n message: 'Special passage \"StoryTitle\" not found.',\n });\n }\n output = toTwine1HTML(story, format, startName);\n }\n\n // Inject modules and head file\n const modules = getFilenames(options.modules ?? [], outFile);\n diagnostics.push(...modules.diagnostics);\n output = modifyHead(output, modules.filenames, options.headFile, diagnostics);\n break;\n }\n\n default: {\n const _exhaustive: never = outputMode;\n throw new TweeTsError(`Unhandled output mode: ${_exhaustive as string}`, diagnostics);\n }\n }\n\n // Compute stats\n const stats: CompileStats = {\n ...getStoryStats(story, options.wordCountMethod),\n files: [...processedFiles],\n };\n\n return { output, story, format, diagnostics, stats };\n}\n\nfunction ensureIFID(story: Story, diagnostics: Diagnostic[]): void {\n if (story.ifid !== '') return;\n\n if (story.legacyIFID !== '') {\n story.ifid = story.legacyIFID;\n diagnostics.push({\n level: 'warning',\n message: 'Story IFID not found; reusing \"ifid\" entry from the \"StorySettings\" special passage.',\n });\n } else {\n const ifid = generateIFID();\n story.ifid = ifid;\n diagnostics.push({\n level: 'error',\n message: `Story IFID not found. Add an IFID to your story: {\"ifid\":\"${ifid}\"}`,\n });\n }\n}\n\n/**\n * Serialize a Story to JSON per the Twine 2 JSON Output Specification (v1.0):\n * https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-jsonoutput-doc.md\n */\nfunction storyToJSON(story: Story): string {\n // Gather script and stylesheet content, excluding them from passages.\n const scripts: string[] = [];\n const stylesheets: string[] = [];\n const storyPassages: { name: string; tags: string[]; text: string; metadata?: Record<string, string> }[] = [];\n\n for (const p of story.passages) {\n if (p.name === 'StoryTitle' || p.name === 'StoryData') continue;\n if (hasTag(p, 'Twine.private')) continue;\n\n if (hasTag(p, 'script')) {\n scripts.push(p.text);\n } else if (hasTag(p, 'stylesheet')) {\n stylesheets.push(p.text);\n } else {\n const entry: { name: string; tags: string[]; text: string; metadata?: Record<string, string> } = {\n name: p.name,\n tags: p.tags,\n text: p.text,\n };\n if (p.metadata) {\n const meta: Record<string, string> = {};\n for (const [key, value] of Object.entries(p.metadata)) {\n if (typeof value === 'string') meta[key] = value;\n }\n if (Object.keys(meta).length > 0) {\n entry.metadata = meta;\n }\n }\n storyPassages.push(entry);\n }\n }\n\n const obj: Record<string, unknown> = {\n name: story.name,\n };\n\n if (story.ifid) obj.ifid = story.ifid;\n if (story.twine2.format) obj.format = story.twine2.format;\n if (story.twine2.formatVersion) obj['format-version'] = story.twine2.formatVersion;\n if (story.twine2.start) obj.start = story.twine2.start;\n if (story.twine2.tagColors.size > 0) obj['tag-colors'] = Object.fromEntries(story.twine2.tagColors);\n if (story.twine2.zoom !== 1) obj.zoom = story.twine2.zoom;\n obj.creator = CREATOR_NAME;\n obj['creator-version'] = VERSION;\n obj.style = stylesheets.join('\\n');\n obj.script = scripts.join('\\n');\n obj.passages = storyPassages;\n\n return JSON.stringify(obj, null, 2);\n}\n","/**\n * Reads the strings in JavaScript source, as the link check needs them: SugarCube evaluates\n * quoted macro arguments as strict-mode JavaScript, and stories build macro calls in the strings\n * of their scripts (`$.wiki('<<goto \"Room\">>')`).\n */\n\n/**\n * Stands in for each `${…}` substitution in a template literal's value: a Unicode noncharacter,\n * which text doesn't contain. A passage name that includes it is known only in play.\n */\nexport const SUBSTITUTION = '\\ufdd0';\n\nconst SINGLE_ESCAPES: ReadonlyMap<string, string> = new Map([\n ['b', '\\b'],\n ['f', '\\f'],\n ['n', '\\n'],\n ['r', '\\r'],\n ['t', '\\t'],\n ['v', '\\v'],\n]);\nconst HEX_RE = /^[0-9A-Fa-f]+$/;\nconst DIGIT_RE = /^[0-9]$/;\nconst LINE_TERMINATORS = '\\n\\r\\u2028\\u2029';\n\n/**\n * The value of a quoted JavaScript string literal (quotes included), as strict-mode JavaScript\n * evaluates it: `\\\"`, `\\'`, `\\\\`, `\\n`, `\\xHH`, `\\uHHHH`, `\\u{H…}`, line continuations, and a\n * backslash before any other character gives that character. Returns `undefined` for what\n * strict mode rejects, such as `\\1` or a raw carriage return.\n */\nexport function evalStringLiteral(literal: string): string | undefined {\n const quote = literal[0];\n const last = literal.length - 1;\n if ((quote !== '\"' && quote !== \"'\") || last < 1 || literal[last] !== quote) {\n return undefined;\n }\n return cookEscapes(literal.slice(1, last), quote);\n}\n\n/**\n * Decodes the body of a string literal, given its quote, or a piece of a template literal\n * (`quote` undefined), as strict-mode JavaScript does. A string may not hold its own quote or a\n * raw line feed or carriage return; a template piece may, and turns `\\r\\n` and `\\r` into `\\n`.\n */\nfunction cookEscapes(body: string, quote: string | undefined): string | undefined {\n let value = '';\n let i = 0;\n while (i < body.length) {\n const ch = body.charAt(i);\n if (ch !== '\\\\') {\n if (quote !== undefined && (ch === quote || ch === '\\n' || ch === '\\r')) {\n return undefined;\n }\n if (ch === '\\r') {\n value += '\\n';\n i += body.charAt(i + 1) === '\\n' ? 2 : 1;\n } else {\n value += ch;\n i += 1;\n }\n continue;\n }\n if (i + 1 >= body.length) {\n // In a string, the backslash would escape the closing quote.\n return undefined;\n }\n const escaped = body.charAt(i + 1);\n i += 2;\n const single = SINGLE_ESCAPES.get(escaped);\n if (single !== undefined) {\n value += single;\n continue;\n }\n switch (escaped) {\n case '0':\n if (DIGIT_RE.test(body.charAt(i))) {\n return undefined;\n }\n value += '\\0';\n break;\n case '1':\n case '2':\n case '3':\n case '4':\n case '5':\n case '6':\n case '7':\n case '8':\n case '9':\n return undefined;\n case 'x': {\n const hex = body.slice(i, i + 2);\n if (hex.length !== 2 || !HEX_RE.test(hex)) {\n return undefined;\n }\n value += String.fromCharCode(parseInt(hex, 16));\n i += 2;\n break;\n }\n case 'u': {\n const unicode = readUnicodeEscape(body, i);\n if (unicode === undefined) {\n return undefined;\n }\n value += unicode.char;\n i = unicode.end;\n break;\n }\n case '\\r':\n // A line continuation; `\\r\\n` counts as one line break.\n if (body[i] === '\\n') {\n i += 1;\n }\n break;\n case '\\n':\n case '\\u2028':\n case '\\u2029':\n break;\n default:\n value += escaped;\n }\n }\n return value;\n}\n\n/** Reads the part of `\\uHHHH` or `\\u{H…}` after the `u`. */\nfunction readUnicodeEscape(body: string, from: number): { char: string; end: number } | undefined {\n if (body[from] === '{') {\n const close = body.indexOf('}', from + 1);\n if (close === -1) {\n return undefined;\n }\n const hex = body.slice(from + 1, close);\n if (!HEX_RE.test(hex)) {\n return undefined;\n }\n const codePoint = parseInt(hex, 16);\n return codePoint > 0x10ffff ? undefined : { char: String.fromCodePoint(codePoint), end: close + 1 };\n }\n const hex = body.slice(from, from + 4);\n if (hex.length !== 4 || !HEX_RE.test(hex)) {\n return undefined;\n }\n return { char: String.fromCharCode(parseInt(hex, 16)), end: from + 4 };\n}\n\n// Words after which a `/` starts a regular expression rather than a division.\nconst REGEX_KEYWORDS: ReadonlySet<string> = new Set([\n 'await',\n 'case',\n 'delete',\n 'do',\n 'else',\n 'in',\n 'instanceof',\n 'new',\n 'of',\n 'return',\n 'throw',\n 'typeof',\n 'void',\n 'yield',\n]);\nconst WORD_RE = /[$\\p{ID_Continue}\\u200c\\u200d]+/uy;\nconst WHITESPACE_RE = /\\s/;\nconst LINE_TERMINATOR_RE = /[\\n\\r\\u2028\\u2029]/g;\n\n/** A template literal being read: its value so far, and where its current piece starts. */\ninterface TemplateFrame {\n readonly kind: 'template';\n readonly value: string;\n readonly pieceStart: number;\n /** False once a piece holds an escape that strict mode rejects. */\n readonly valid: boolean;\n}\n\n/** Code: the whole source, or a template's `${…}` substitution, with its open `{` count. */\ninterface CodeFrame {\n readonly kind: 'code';\n readonly braces: number;\n}\n\ntype Frame = TemplateFrame | CodeFrame;\n\n/**\n * The values of the string and template literals in JavaScript source. A template literal's\n * value keeps its text and has `SUBSTITUTION` where each `${…}` was; the strings inside a\n * substitution are values of their own. Comments and regular expression literals are skipped;\n * whether a `/` starts a regular expression is judged from the token before it. Malformed\n * source is read on as far as it can be.\n */\nexport function javaScriptStrings(source: string): string[] {\n const strings: string[] = [];\n // The bottom frame is the source itself, which is never closed.\n const frames: Frame[] = [{ kind: 'code', braces: 0 }];\n let regexAllowed = true;\n let afterDot = false;\n // Where a string of each quote, or a regular expression, is known not to close.\n const failedUntil = new Map<string, number>();\n let i = 0;\n while (i < source.length) {\n const frame = frames[frames.length - 1];\n if (frame === undefined) {\n // The bottom frame is never popped.\n break;\n }\n const ch = source.charAt(i);\n const next = source.charAt(i + 1);\n\n if (frame.kind === 'template') {\n if (ch === '`' || (ch === '$' && next === '{')) {\n const piece = cookEscapes(source.slice(frame.pieceStart, i), undefined);\n const value = frame.value + (piece ?? '');\n const valid = frame.valid && piece !== undefined;\n frames.pop();\n if (ch === '`') {\n if (valid) {\n strings.push(value);\n }\n i += 1;\n regexAllowed = false;\n afterDot = false;\n } else {\n frames.push({ kind: 'template', value: value + SUBSTITUTION, pieceStart: -1, valid });\n frames.push({ kind: 'code', braces: 0 });\n i += 2;\n regexAllowed = true;\n afterDot = false;\n }\n } else {\n i += ch === '\\\\' ? 2 : 1;\n }\n continue;\n }\n\n if (ch === '/' && next === '/') {\n const lineEnd = searchFrom(LINE_TERMINATOR_RE, source, i + 2);\n i = lineEnd === -1 ? source.length : lineEnd;\n continue;\n }\n if (ch === '/' && next === '*') {\n const close = source.indexOf('*/', i + 2);\n i = close === -1 ? source.length : close + 2;\n continue;\n }\n if (ch === '/' && regexAllowed && i >= (failedUntil.get('/') ?? 0)) {\n const end = endOfRegularExpression(source, i);\n if (end.end !== undefined) {\n i = end.end;\n regexAllowed = false;\n afterDot = false;\n continue;\n }\n failedUntil.set('/', end.stop);\n }\n if ((ch === '\"' || ch === \"'\") && i >= (failedUntil.get(ch) ?? 0)) {\n const end = endOfJavaScriptString(source, i);\n if (end.end !== undefined) {\n const value = evalStringLiteral(source.slice(i, end.end));\n if (value !== undefined) {\n strings.push(value);\n }\n i = end.end;\n regexAllowed = false;\n afterDot = false;\n continue;\n }\n failedUntil.set(ch, end.stop);\n }\n if (ch === '`') {\n frames.push({ kind: 'template', value: '', pieceStart: i + 1, valid: true });\n i += 1;\n continue;\n }\n const word = wordAt(source, i);\n if (word !== null) {\n // A keyword after a `.` is a property name, which a `/` divides.\n regexAllowed = !afterDot && REGEX_KEYWORDS.has(word[0]);\n afterDot = false;\n i += word[0].length;\n continue;\n }\n if ((ch === '+' || ch === '-') && next === ch) {\n // After `x++` or `x--`, a `/` divides.\n regexAllowed = false;\n afterDot = false;\n i += 2;\n continue;\n }\n if (frame.kind === 'code' && frames.length > 1 && (ch === '{' || ch === '}')) {\n if (ch === '{') {\n frames[frames.length - 1] = { kind: 'code', braces: frame.braces + 1 };\n } else if (frame.braces > 0) {\n frames[frames.length - 1] = { kind: 'code', braces: frame.braces - 1 };\n } else {\n // The `}` that closes a substitution: the template goes on after it.\n frames.pop();\n const template = frames.pop();\n if (template?.kind === 'template') {\n frames.push({ ...template, pieceStart: i + 1 });\n }\n i += 1;\n continue;\n }\n }\n if (!WHITESPACE_RE.test(ch)) {\n // After a closing bracket, as after a name or a number, a `/` divides.\n regexAllowed = !')]}'.includes(ch);\n afterDot = ch === '.';\n }\n i += 1;\n }\n return strings;\n}\n\n/** The name, keyword or number that starts at `pos`, if one does. */\nfunction wordAt(source: string, pos: number): RegExpExecArray | null {\n const code = source.charCodeAt(pos);\n const ascii = code < 0x80;\n // Only ASCII letters, digits, `_` and `$` start a word below U+0080.\n if (\n ascii &&\n !(\n (code >= 0x30 && code <= 0x39) ||\n ((code | 0x20) >= 0x61 && (code | 0x20) <= 0x7a) ||\n code === 0x5f ||\n code === 0x24\n )\n ) {\n return null;\n }\n WORD_RE.lastIndex = pos;\n return WORD_RE.exec(source);\n}\n\n/** Index of the first match of a global `re` at or after `from`, or -1. */\nfunction searchFrom(re: RegExp, text: string, from: number): number {\n re.lastIndex = from;\n const m = re.exec(text);\n return m === null ? -1 : m.index;\n}\n\n/**\n * Where a string literal that opens at `pos` ends, or, if it doesn't close on its line, where\n * the scan stopped. A string with the same quote that starts before that stop, inside this one,\n * doesn't close either.\n */\nfunction endOfJavaScriptString(source: string, pos: number): { end: number | undefined; stop: number } {\n const quote = source.charAt(pos);\n let i = pos + 1;\n while (i < source.length) {\n const ch = source.charAt(i);\n if (ch === quote) {\n return { end: i + 1, stop: i };\n }\n if (ch === '\\n' || ch === '\\r') {\n return { end: undefined, stop: i };\n }\n if (ch === '\\\\') {\n // A backslash before a line break continues the string; `\\r\\n` is one line break.\n i += source.startsWith('\\r\\n', i + 1) ? 3 : 2;\n } else {\n i += 1;\n }\n }\n return { end: undefined, stop: source.length };\n}\n\n/**\n * Where a regular expression literal that opens at `pos` ends, flags included, or, if none\n * closes on the line, where the line ends. A `/` before that is then read as a division.\n */\nfunction endOfRegularExpression(source: string, pos: number): { end: number | undefined; stop: number } {\n let inClass = false;\n let i = pos + 1;\n while (i < source.length) {\n const ch = source.charAt(i);\n if (LINE_TERMINATORS.includes(ch)) {\n return { end: undefined, stop: i };\n }\n if (ch === '\\\\') {\n const escaped = source.charAt(i + 1);\n if (escaped === '' || LINE_TERMINATORS.includes(escaped)) {\n return { end: undefined, stop: i + 1 };\n }\n i += 2;\n continue;\n }\n if (ch === '[') {\n inClass = true;\n } else if (ch === ']') {\n inClass = false;\n } else if (ch === '/' && !inClass) {\n WORD_RE.lastIndex = i + 1;\n const flags = WORD_RE.exec(source);\n return { end: i + 1 + (flags === null ? 0 : flags[0].length), stop: i };\n }\n i += 1;\n }\n return { end: undefined, stop: source.length };\n}\n","/**\n * Reads SugarCube 2 link and image markup the way SugarCube 2.37.3's\n * `Wikifier.helpers.parseSquareBracketedMarkup` does:\n *\n * - `[[Link]]`, `[[Text|Link]]`, `[[Text->Link]]` and `[[Link<-Text]]`, each with an optional\n * setter: `[[Text|Link][$x to 1]]`;\n * - `[img[Source]]`, `[img[Title|Source]]` and `[img[Source<-Title]]`, with an optional link and\n * setter: `[img[Source][Link][$x to 1]]`, and `[<img[` or `[>img[` for alignment.\n *\n * The first `|`, `->` or `<-` divides the text from the link; any later one is part of the link\n * or the text. Square brackets nest; a double-quoted string, or in a setter a single-quoted one\n * too, is read as a unit, so a `]` or a delimiter in it counts for nothing. The markup must end\n * on the line it starts on.\n */\n\n/** Link or image markup, as far as finding the passage it links to needs. */\nexport interface SquareBracketedMarkup {\n readonly type: 'link' | 'image';\n /**\n * What the markup links to, trimmed and without the `~` that forces an internal link: a link's\n * destination, or an image's link component, if it has one. SugarCube reads it as a passage name\n * if a passage has that name, and otherwise evaluates it.\n */\n readonly link: string | undefined;\n /** Index just past the closing `]]`. */\n readonly end: number;\n}\n\n/** A component of the markup ends here, and the next one starts at `next`. */\ninterface ComponentEnd {\n /** Index just past the component's text. */\n readonly textEnd: number;\n /** Where the next part starts: after `][` or after `]]`. */\n readonly next: number;\n /** Whether `]]` ended the markup; otherwise `][` opened another component. */\n readonly last: boolean;\n}\n\n/**\n * Characters a reading may still look at: it stops, as having failed, when they run out.\n * `scanned` is how far it has looked so far: the index just past the last character it read.\n */\ninterface Reader {\n readonly text: string;\n readonly limit: number;\n scanned: number;\n}\n\n/** Records that the reading has looked at the characters before `pos`, and returns `result`. */\nfunction readTo<T>(reader: Reader, pos: number, result: T): T {\n reader.scanned = Math.max(reader.scanned, pos);\n return result;\n}\n\n/**\n * Reads link or image markup that starts at `start` in `text`, or returns `undefined` where\n * SugarCube rejects it (and so prints the text instead).\n *\n * `budget.left`, if given, is how many characters the reading may look at; it is reduced by as\n * many as were read, and once it runs out, every reading fails. Unclosed markup is read to the end\n * of its line, so reading every `[[` of a long line that never closes one would otherwise take\n * quadratic time. A reading is charged for the characters it looked at, up to where it ended or\n * failed (a line feed, say), and no more, so markup left unclosed on short lines costs little.\n */\nexport function readSquareBracketedMarkup(\n text: string,\n start: number,\n budget: { left: number } = { left: Infinity },\n): SquareBracketedMarkup | undefined {\n const reader: Reader = { text, limit: Math.min(text.length, start + Math.max(budget.left, 0)), scanned: start };\n const markup = readMarkup(reader, start);\n budget.left -= Math.max(reader.scanned, markup?.end ?? start) - start;\n return markup;\n}\n\nfunction readMarkup(reader: Reader, start: number): SquareBracketedMarkup | undefined {\n const { text } = reader;\n if (text[start] !== '[') {\n return undefined;\n }\n let pos = start + 1;\n let type: SquareBracketedMarkup['type'];\n if (text[pos] === '[') {\n type = 'link';\n pos += 1;\n } else {\n if (text[pos] === '<' || text[pos] === '>') {\n pos += 1;\n }\n if (!/^[Ii][Mm][Gg]\\[/.test(text.slice(pos, pos + 4))) {\n return undefined;\n }\n type = 'image';\n pos += 4;\n }\n\n const core = readCoreComponents(reader, pos);\n if (core === undefined) {\n return undefined;\n }\n if (type === 'link') {\n if (!core.end.last) {\n const setterEnd = readSetter(reader, core.end.next);\n if (setterEnd === undefined) {\n return undefined;\n }\n return { type, link: linkName(core.link), end: setterEnd };\n }\n return { type, link: linkName(core.link), end: core.end.next };\n }\n if (core.end.last) {\n return { type, link: undefined, end: core.end.next };\n }\n // An image's link component, then perhaps a setter.\n const linkEnd = readComponent(reader, core.end.next, false);\n if (linkEnd === undefined) {\n return undefined;\n }\n const link = linkName(text.slice(core.end.next, linkEnd.textEnd));\n if (linkEnd.last) {\n return { type, link, end: linkEnd.next };\n }\n const setterEnd = readSetter(reader, linkEnd.next);\n return setterEnd === undefined ? undefined : { type, link, end: setterEnd };\n}\n\n/** The link component as SugarCube keeps it: trimmed, and without a leading `~`. */\nfunction linkName(component: string): string {\n const trimmed = component.trim();\n return trimmed.startsWith('~') ? trimmed.slice(1) : trimmed;\n}\n\n/**\n * Reads the first components: the text and the link of link markup, or the title and the source\n * of image markup, divided by the first delimiter. `link` is the text of the link (or source)\n * component, untrimmed.\n */\nfunction readCoreComponents(reader: Reader, from: number): { link: string; end: ComponentEnd } | undefined {\n const { text } = reader;\n let delimiter: 'none' | 'ltr' | 'rtl' = 'none';\n let componentStart = from;\n let link: string | undefined;\n let depth = 2;\n let pos = from;\n while (pos < reader.limit) {\n const ch = text[pos];\n pos += 1;\n switch (ch) {\n case '\\n':\n return readTo(reader, pos, undefined);\n case '\"': {\n const end = readQuoted(reader, pos, '\"');\n if (end === undefined) {\n return undefined;\n }\n pos = end;\n break;\n }\n case '|':\n if (delimiter === 'none') {\n delimiter = 'ltr';\n componentStart = pos;\n }\n break;\n case '-':\n if (delimiter === 'none' && text[pos] === '>') {\n delimiter = 'ltr';\n pos += 1;\n componentStart = pos;\n }\n break;\n case '<':\n if (delimiter === 'none' && text[pos] === '-') {\n delimiter = 'rtl';\n link = text.slice(componentStart, pos - 1);\n pos += 1;\n componentStart = pos;\n }\n break;\n case '[':\n depth += 1;\n break;\n case ']': {\n depth -= 1;\n if (depth === 1) {\n const end = componentEnd(reader, pos);\n if (end === undefined) {\n return undefined;\n }\n // With `<-`, the link came first and this component is the text.\n return { link: link ?? text.slice(componentStart, end.textEnd), end };\n }\n break;\n }\n default:\n break;\n }\n }\n return readTo(reader, pos, undefined);\n}\n\n/**\n * Reads a component after `][` that holds no delimiter: an image's link (`setter` false) or a\n * setter, in which single quotes also quote.\n */\nfunction readComponent(reader: Reader, from: number, setter: boolean): ComponentEnd | undefined {\n const { text } = reader;\n let depth = 2;\n let pos = from;\n while (pos < reader.limit) {\n const ch = text[pos];\n pos += 1;\n switch (ch) {\n case '\\n':\n return readTo(reader, pos, undefined);\n case '\"':\n case \"'\": {\n if (ch === \"'\" && !setter) {\n break;\n }\n const end = readQuoted(reader, pos, ch);\n if (end === undefined) {\n return undefined;\n }\n pos = end;\n break;\n }\n case '[':\n depth += 1;\n break;\n case ']':\n depth -= 1;\n if (depth === 1) {\n return componentEnd(reader, pos);\n }\n break;\n default:\n break;\n }\n }\n return readTo(reader, pos, undefined);\n}\n\n/** Reads a setter, the last component; returns the index after its closing `]]`. */\nfunction readSetter(reader: Reader, from: number): number | undefined {\n const end = readComponent(reader, from, true);\n return end?.last === true ? end.next : undefined;\n}\n\n/** What the `]` just before `pos`, which brings the depth back to one, ends; `undefined` if malformed. */\nfunction componentEnd(reader: Reader, pos: number): ComponentEnd | undefined {\n // Whatever it holds, the character at `pos` has been looked at.\n switch (reader.text[pos]) {\n case '[':\n return readTo(reader, pos + 1, { textEnd: pos - 1, next: pos + 1, last: false });\n case ']':\n return readTo(reader, pos + 1, { textEnd: pos - 1, next: pos + 1, last: true });\n default:\n return readTo(reader, pos + 1, undefined);\n }\n}\n\n/**\n * Reads a quoted string from just after its opening quote; a backslash escapes the character\n * after it. A line feed, or the end of the text, ends it unterminated. Returns the index after the\n * closing quote.\n */\nfunction readQuoted(reader: Reader, from: number, quote: string): number | undefined {\n const { text } = reader;\n let pos = from;\n while (pos < reader.limit) {\n const ch = text[pos];\n pos += 1;\n if (ch === quote) {\n return pos;\n }\n if (ch === '\\n') {\n return readTo(reader, pos, undefined);\n }\n if (ch === '\\\\') {\n if (pos >= reader.limit || text[pos] === '\\n') {\n return readTo(reader, Math.min(pos + 1, reader.limit), undefined);\n }\n pos += 1;\n }\n }\n return readTo(reader, pos, undefined);\n}\n","/**\n * Reads SugarCube 2 macro calls and link markup the way SugarCube 2.37.3 does, so the link check\n * sees the same passage names that `[[…]]` links, `<<link>>` and `<<goto>>` use when the story\n * plays.\n *\n * Each step follows a part of SugarCube's macro parser:\n * - `findMacroTags` finds where a tag starts and ends (the parser's `lookahead` pattern);\n * - `parseMacroArgs` splits the text after the macro name into arguments (`parseArgs`);\n * - quoted arguments are evaluated as strict-mode JavaScript strings (`evalStringLiteral`).\n *\n * Link and image markup is read as `parseSquareBracketedMarkup` reads it (see `link-markup.ts`).\n * Of the rest of the wikifier, only comments, `<script>` elements and `<<script>>` bodies are\n * told apart; other markup, such as verbatim text, is read as markup (see `findPassageLinks`).\n */\nimport { SUBSTITUTION, evalStringLiteral, javaScriptStrings } from './javascript-strings.js';\nimport { readSquareBracketedMarkup } from './link-markup.js';\n\n/** A macro tag: `<<name args>>`, or a closing tag `<</name>>`. */\nexport interface MacroTag {\n /** The macro name, with a leading `/` for a closing tag. */\n readonly name: string;\n /** The text between the name (and the spaces after it) and the closing `>>`. */\n readonly args: string;\n /** Index of the opening `<<`. */\n readonly start: number;\n /** Index just past the closing `>>`. */\n readonly end: number;\n}\n\n/** What a macro argument evaluates to, as far as that is known without playing the story. */\nexport type MacroArg =\n /** A quoted string, or a bare word SugarCube keeps as text. */\n | { readonly type: 'string'; readonly value: string }\n /** A bare word SugarCube converts to a number. */\n | { readonly type: 'number'; readonly value: number }\n /** Link or image markup: `[[…]]` or `[img[…]]`. */\n | { readonly type: 'markup' }\n | { readonly type: 'null' }\n /** A variable, an expression, `setup`/`settings`, a boolean or `undefined`. */\n | { readonly type: 'other' };\n\n/** The macros whose calls name a passage. */\ntype PassageLinkMacro = 'goto' | 'link';\n\n/** A passage named by link markup (`[[…]]`) or by a `<<link>>` or `<<goto>>` call. */\nexport interface PassageLink {\n /** What names it: link markup, or a call of that macro. */\n readonly via: 'markup' | PassageLinkMacro;\n readonly passage: string;\n}\n\n/** An argument as SugarCube's lexer splits it, before its value is worked out. */\ntype LexedArg =\n | { readonly kind: 'string'; readonly value: string }\n | { readonly kind: 'expression'; readonly code: string }\n | { readonly kind: 'markup'; readonly text: string }\n | { readonly kind: 'word'; readonly text: string };\n\n/** A tag, and where a `<<link` or `<<goto` first appears unquoted in its arguments, if it does. */\nexport interface ScannedTag {\n readonly tag: MacroTag;\n readonly innerCall: number | undefined;\n}\n\n// SugarCube's `Patterns.macroName`, preceded by the optional `/` of a closing tag.\nconst NAME_RE = /\\/?[A-Za-z][\\w-]*|[=-]/y;\nconst SPACES_RE = /\\s*/y;\nconst LINE_TERMINATOR_RE = /[\\n\\r\\u2028\\u2029]/g;\nconst SQUARE_BRACKET_OPEN_RE = /\\[(?:[<>]?[Ii][Mm][Gg])?\\[/y;\n\n// SugarCube's `Patterns.space` and `Patterns.notSpace`: JavaScript's `\\s` plus U+180E, which\n// `\\s` no longer matches.\nconst SPACE_RE = /[\\s\\u180e]/g;\nconst NOT_SPACE_RE = /[^\\s\\u180e]/g;\nconst VARIABLE_RE = /^[$_][$A-Z_a-z][$0-9A-Z_a-z]*/;\nconst SETTINGS_OR_SETUP_RE = /^(?:settings|setup)[.[]/;\nconst IMAGE_MARKUP_CHARS = '<>IiMmGg';\n\n/**\n * Macros that SugarCube doesn't split into arguments (`skipArgs` in 2.37.3), with their child\n * tags that do the same: `<<elseif>>` and `<<else>>` of `<<if>>`, and `<<optionsfrom>>` of\n * `<<cycle>>` and `<<listbox>>`. Their argument text is TwineScript, or for `<<capture>>`,\n * `<<unset>>` and `<<for>>` a syntax of their own; either way its strings are JavaScript strings.\n */\nconst RAW_ARGUMENT_MACROS: ReadonlySet<string> = new Set([\n 'break',\n 'capture',\n 'continue',\n 'done',\n 'else',\n 'elseif',\n 'for',\n 'if',\n 'nobr',\n 'optionsfrom',\n 'print',\n '=',\n '-',\n 'run',\n 'set',\n 'silent',\n 'silently',\n 'stop',\n 'switch',\n 'unset',\n 'waitforaudio',\n]);\n\n/**\n * How deep strings inside macro arguments are read for further calls. Stories nest two or three\n * levels; the limit keeps the work linear in the size of the text on any input.\n */\nconst MAX_STRING_DEPTH = 10;\n\n/**\n * What one reading of a passage carries down into the strings it reads: how deep it is, how much\n * the `<<script>>` closer search has left to read (see `scriptBodyCloser`), and how much the\n * reading of link and image markup has (see `readSquareBracketedMarkup`).\n */\ninterface ReadContext {\n readonly depth: number;\n readonly budget: { left: number };\n readonly markupBudget: { left: number };\n}\n\n/**\n * A context for reading `text`: the closer search, and the markup reading, may each read four\n * times it, plus an allowance.\n */\nfunction readContext(text: string): ReadContext {\n const allowance = (): { left: number } => ({ left: 4 * text.length + 100_000 });\n return { depth: 0, budget: allowance(), markupBudget: allowance() };\n}\n\nfunction deeper(context: ReadContext): ReadContext {\n return { ...context, depth: context.depth + 1 };\n}\n\n/** Index of the first match of a global `re` at or after `from`, or -1. */\nfunction searchFrom(re: RegExp, text: string, from: number): number {\n re.lastIndex = from;\n const m = re.exec(text);\n return m === null ? -1 : m.index;\n}\n\n/**\n * Finds the macro tags in text, in order, trying a tag at every `<<` as SugarCube's macro\n * parser does. A tag that doesn't parse is skipped, and the search goes on after its `<<`.\n *\n * Gives the same tags as SugarCube's pattern, without its backtracking: that pattern takes\n * exponential time when no `>>` follows a `<<name`, which a script passage can contain (`1<<n`).\n */\nexport function findMacroTags(text: string): MacroTag[] {\n return scanTags(text).map((scanned) => scanned.tag);\n}\n\nfunction scanTags(text: string): ScannedTag[] {\n const matchTagAt = tagMatcher(text);\n const tags: ScannedTag[] = [];\n let start = text.indexOf('<<');\n while (start !== -1) {\n const scanned = matchTagAt(start);\n if (scanned === undefined) {\n start = text.indexOf('<<', start + 2);\n } else {\n tags.push(scanned);\n start = text.indexOf('<<', scanned.tag.end);\n }\n }\n return tags;\n}\n\n/** A kind of argument part in which a `>>` doesn't end the tag, named by how it opens. */\ntype ArgumentPartKind = '/*' | '//' | '`' | '\"' | \"'\" | '[';\n\n/** How far an argument part reaches. */\ninterface ArgumentPartScan {\n /** Index just past the part, or `undefined` if it is never closed. */\n readonly end: number | undefined;\n /**\n * Where the scan stopped: at the part's closing quote, `*` + `/`, line end or `]]`, or where\n * it failed. A part of the same kind that starts inside this one, before this index, ends or\n * fails no earlier.\n */\n readonly stop: number;\n}\n\n/**\n * Returns a function that matches a tag at a `<<` in `text`. It must be called for positions in\n * increasing order.\n *\n * The arguments may contain comments, backquoted expressions, quoted strings and link markup,\n * whose `>>` doesn't end the tag. SugarCube's pattern treats such a part as a unit only if a\n * `>>` still follows it, and otherwise as plain characters; `lastClose`, the last `>>` in the\n * text, answers that in constant time. Once a part is read as plain characters, a part of the\n * same kind that starts inside it can't end before `lastClose` either, in this tag or a later\n * one, so it isn't scanned again: `scanFrom` records where each kind may next be scanned. This\n * keeps the search linear. `onWork` is told how many characters each step reads. (Exported for\n * tests; the module is not part of the package's API.)\n */\nexport function tagMatcher(\n text: string,\n lastClose = text.lastIndexOf('>>'),\n onWork: (characters: number) => void = () => {},\n): (start: number) => ScannedTag | undefined {\n const scanFrom = new Map<ArgumentPartKind, number>();\n return (start) => {\n NAME_RE.lastIndex = start + 2;\n const nameMatch = NAME_RE.exec(text);\n if (nameMatch === null) {\n onWork(2);\n return undefined;\n }\n SPACES_RE.lastIndex = NAME_RE.lastIndex;\n SPACES_RE.exec(text);\n const argsStart = SPACES_RE.lastIndex;\n onWork(argsStart - start);\n\n let innerCall: number | undefined;\n let pos = argsStart;\n while (pos <= lastClose) {\n if (text.startsWith('>>', pos)) {\n const tag = { name: nameMatch[0], args: text.slice(argsStart, pos), start, end: pos + 2 };\n return { tag, innerCall };\n }\n const kind = argumentPartKindAt(text, pos);\n const from = kind === undefined ? undefined : scanFrom.get(kind);\n if (kind !== undefined && (from === undefined || pos >= from)) {\n const part = scanArgumentPart(text, pos, kind);\n onWork(part.stop - pos);\n if (part.end !== undefined && part.end <= lastClose) {\n pos = part.end;\n continue;\n }\n scanFrom.set(kind, part.stop);\n }\n if (innerCall === undefined && startsPassageLinkCall(text, pos)) {\n innerCall = pos;\n }\n onWork(1);\n pos += 1;\n }\n return undefined;\n };\n}\n\n/** Whether a `<<link` or `<<goto` tag, and not a longer macro name, starts at `pos`. */\nfunction startsPassageLinkCall(text: string, pos: number): boolean {\n if (!text.startsWith('<<', pos)) {\n return false;\n }\n NAME_RE.lastIndex = pos + 2;\n const name = NAME_RE.exec(text)?.[0];\n return name === 'link' || name === 'goto';\n}\n\n/** The kind of argument part that opens at `pos`, if one does. */\nfunction argumentPartKindAt(text: string, pos: number): ArgumentPartKind | undefined {\n const ch = text[pos];\n switch (ch) {\n case '/': {\n const next = text[pos + 1];\n return next === '*' ? '/*' : next === '/' ? '//' : undefined;\n }\n case '`':\n case '\"':\n case \"'\":\n case '[':\n return ch;\n default:\n return undefined;\n }\n}\n\nfunction scanArgumentPart(text: string, pos: number, kind: ArgumentPartKind): ArgumentPartScan {\n switch (kind) {\n case '/*': {\n const close = text.indexOf('*/', pos + 2);\n return close === -1 ? { end: undefined, stop: text.length } : { end: close + 2, stop: close };\n }\n case '//': {\n // `//.*\\n`: the comment must end at a line feed, not at any other line terminator.\n const lineEnd = searchFrom(LINE_TERMINATOR_RE, text, pos + 2);\n if (lineEnd === -1) {\n return { end: undefined, stop: text.length };\n }\n return { end: text[lineEnd] === '\\n' ? lineEnd + 1 : undefined, stop: lineEnd };\n }\n case '`':\n case '\"':\n case \"'\":\n return scanQuoted(text, pos, kind);\n case '[':\n return scanSquareBracketed(text, pos);\n default: {\n const _exhaustive: never = kind;\n throw new Error(`unhandled argument part: ${String(_exhaustive)}`);\n }\n }\n}\n\n/** A quoted part of a tag: a backslash escapes any character except a line terminator. */\nfunction scanQuoted(text: string, pos: number, quote: string): ArgumentPartScan {\n let i = pos + 1;\n while (i < text.length) {\n const ch = text[i];\n if (ch === quote) {\n return { end: i + 1, stop: i };\n }\n if (ch === '\\\\') {\n const next = text[i + 1];\n if (next === undefined || '\\n\\r\\u2028\\u2029'.includes(next)) {\n return { end: undefined, stop: i };\n }\n i += 2;\n } else {\n i += 1;\n }\n }\n return { end: undefined, stop: text.length };\n}\n\n/** Link or image markup in a tag: up to the first `]]` on the same line, plus any further `]`. */\nfunction scanSquareBracketed(text: string, pos: number): ArgumentPartScan {\n SQUARE_BRACKET_OPEN_RE.lastIndex = pos;\n if (!SQUARE_BRACKET_OPEN_RE.test(text)) {\n return { end: undefined, stop: pos + 1 };\n }\n for (let i = SQUARE_BRACKET_OPEN_RE.lastIndex; i < text.length; i++) {\n const ch = text[i];\n if (ch === '\\n' || ch === '\\r') {\n return { end: undefined, stop: i };\n }\n if (ch === ']' && text[i + 1] === ']') {\n let end = i + 2;\n while (text[end] === ']') {\n end += 1;\n }\n return { end, stop: i };\n }\n }\n return { end: undefined, stop: text.length };\n}\n\n/**\n * Splits a tag's argument text into arguments, as SugarCube's `parseArgs` does. Returns\n * `undefined` where SugarCube throws while splitting the text or reading a string, so the macro\n * call does nothing. (SugarCube also parses link markup a second time and rejects some that it\n * split without trouble, such as `[[\"x]]`; that is still returned as markup here.)\n */\nexport function parseMacroArgs(raw: string): MacroArg[] | undefined {\n return lexMacroArgs(raw)?.map(argValue);\n}\n\nfunction lexMacroArgs(raw: string): LexedArg[] | undefined {\n const args: LexedArg[] = [];\n let pos = searchFrom(NOT_SPACE_RE, raw, 0);\n while (pos !== -1) {\n const lexed = lexArgument(raw, pos);\n if (lexed === undefined) {\n return undefined;\n }\n args.push(lexed.arg);\n pos = searchFrom(NOT_SPACE_RE, raw, lexed.end);\n }\n return args;\n}\n\nfunction lexArgument(raw: string, pos: number): { arg: LexedArg; end: number } | undefined {\n const first = raw[pos];\n switch (first) {\n case '`': {\n const end = slurpQuote(raw, pos + 1, '`');\n return end === undefined ? undefined : { arg: { kind: 'expression', code: raw.slice(pos + 1, end - 1) }, end };\n }\n case '\"':\n case \"'\": {\n const end = slurpQuote(raw, pos + 1, first);\n if (end === undefined) {\n return undefined;\n }\n const value = evalStringLiteral(raw.slice(pos, end));\n return value === undefined ? undefined : { arg: { kind: 'string', value }, end };\n }\n case '[': {\n const end = lexSquareBracketed(raw, pos + 1);\n return end === undefined ? undefined : { arg: { kind: 'markup', text: raw.slice(pos, end) }, end };\n }\n default: {\n const space = searchFrom(SPACE_RE, raw, pos + 1);\n const end = space === -1 ? raw.length : space;\n return { arg: { kind: 'word', text: raw.slice(pos, end) }, end };\n }\n }\n}\n\n/**\n * Reads a quoted argument from just after its opening quote. A newline, or a backslash before a\n * newline, ends it unterminated. Returns the index after the closing quote.\n */\nfunction slurpQuote(raw: string, from: number, endQuote: string): number | undefined {\n let i = from;\n while (i < raw.length) {\n const ch = raw[i];\n if (ch === endQuote) {\n return i + 1;\n }\n if (ch === '\\n') {\n return undefined;\n }\n if (ch === '\\\\') {\n const next = raw[i + 1];\n if (next === undefined || next === '\\n') {\n return undefined;\n }\n i += 2;\n } else {\n i += 1;\n }\n }\n return undefined;\n}\n\n/**\n * Reads link or image markup from just after its first `[`, counting nested brackets.\n * Returns the index after the closing `]]`.\n */\nfunction lexSquareBracketed(raw: string, from: number): number | undefined {\n let i = from;\n while (i < raw.length && IMAGE_MARKUP_CHARS.includes(raw.charAt(i))) {\n i += 1;\n }\n if (raw[i] !== '[') {\n return undefined;\n }\n i += 1;\n let depth = 2;\n while (i < raw.length) {\n const ch = raw[i];\n i += 1;\n switch (ch) {\n case '\\\\': {\n const next = raw[i];\n if (next === undefined || next === '\\n') {\n return undefined;\n }\n i += 1;\n break;\n }\n case '\\n':\n return undefined;\n case '[':\n depth += 1;\n break;\n case ']':\n depth -= 1;\n if (depth < 0) {\n return undefined;\n }\n if (depth === 1 && raw[i] === ']') {\n return i + 1;\n }\n break;\n default:\n break;\n }\n }\n return undefined;\n}\n\n/** An argument's value, following SugarCube's conversions. */\nfunction argValue(arg: LexedArg): MacroArg {\n switch (arg.kind) {\n case 'string':\n return { type: 'string', value: arg.value };\n case 'expression':\n // Its value is known only in play.\n return { type: 'other' };\n case 'markup':\n return { type: 'markup' };\n case 'word':\n return bareWord(arg.text);\n default: {\n const _exhaustive: never = arg;\n throw new Error(`unhandled macro argument: ${JSON.stringify(_exhaustive)}`);\n }\n }\n}\n\n/** A bare word's value, following SugarCube's conversions. */\nfunction bareWord(word: string): MacroArg {\n if (VARIABLE_RE.test(word) || SETTINGS_OR_SETUP_RE.test(word)) {\n return { type: 'other' };\n }\n switch (word) {\n case 'null':\n return { type: 'null' };\n case 'undefined':\n case 'true':\n case 'false':\n return { type: 'other' };\n case 'NaN':\n return { type: 'number', value: NaN };\n default: {\n const value = Number(word);\n return Number.isNaN(value) ? { type: 'string', value: word } : { type: 'number', value };\n }\n }\n}\n\n/** The passage name an argument gives, if it can be known without playing the story. */\nfunction passageName(arg: MacroArg): string | undefined {\n switch (arg.type) {\n case 'string':\n // A template literal's `${…}` makes the name known only in play.\n return arg.value.includes(SUBSTITUTION) ? undefined : arg.value;\n case 'number':\n // SugarCube looks a number up as a passage name by its string form.\n return String(arg.value);\n case 'markup':\n // Markup names its passage in `[[…]]`, which the link check reads on its own.\n case 'null':\n case 'other':\n return undefined;\n default: {\n const _exhaustive: never = arg;\n throw new Error(`unhandled macro argument: ${JSON.stringify(_exhaustive)}`);\n }\n }\n}\n\n/**\n * The argument that names the passage in a `<<link>>` or `<<goto>>` call:\n * - `<<link linkText [passageName]>>`, unless the first argument is link or image markup, which\n * then names the passage itself and any further argument is ignored;\n * - `<<goto passageName>>`.\n *\n * In text built from a template literal, a bare word with a `${…}` in it may become several\n * words in play, so no argument after it is known.\n */\nfunction passageArgument(macro: PassageLinkMacro, lexed: readonly LexedArg[]): MacroArg | undefined {\n const index = macro === 'link' ? 1 : 0;\n if (lexed.slice(0, index + 1).some((arg) => arg.kind === 'word' && arg.text.includes(SUBSTITUTION))) {\n return undefined;\n }\n const args = lexed.map(argValue);\n switch (macro) {\n case 'link': {\n const [label, passage] = args;\n // A `null` label makes SugarCube throw, as it reads `null` as markup.\n return label === undefined || label.type === 'markup' || label.type === 'null' ? undefined : passage;\n }\n case 'goto':\n return args[0];\n default: {\n const _exhaustive: never = macro;\n throw new Error(`unhandled macro: ${String(_exhaustive)}`);\n }\n }\n}\n\nfunction isPassageLinkMacro(name: string): name is PassageLinkMacro {\n return name === 'goto' || name === 'link';\n}\n\n/** The passage a `<<link>>` or `<<goto>>` tag names itself, if it can be known before play. */\nfunction ownPassageLink(tag: MacroTag, lexed: readonly LexedArg[]): PassageLink | undefined {\n if (!isPassageLinkMacro(tag.name)) {\n return undefined;\n }\n const arg = passageArgument(tag.name, lexed);\n const passage = arg === undefined ? undefined : passageName(arg);\n return passage === undefined ? undefined : { via: tag.name, passage };\n}\n\n/**\n * The passage a link's destination names. SugarCube evaluates a destination that no passage is\n * named by, and a quoted string gives its value (`[[Go|\"Room\"]]`), unless that is blank.\n */\nfunction linkDestination(link: string): string {\n const value = evalStringLiteral(link);\n return value === undefined || value.trim() === '' ? link : value;\n}\n\n/**\n * The passage that link markup from `start` in `text` names, and where the markup ends, or\n * `undefined` where SugarCube rejects the markup. Image markup names none here, nor does markup\n * with a template literal's `${…}` in it, whose passage is known only in play.\n */\nfunction linkMarkupAt(\n text: string,\n start: number,\n budget?: { left: number },\n): { link: PassageLink | undefined; end: number } | undefined {\n const markup = readSquareBracketedMarkup(text, start, budget);\n if (markup === undefined) {\n return undefined;\n }\n const passage =\n markup.type === 'link' && !text.slice(start, markup.end).includes(SUBSTITUTION) ? markup.link : undefined;\n return {\n link: passage === undefined ? undefined : { via: 'markup', passage: linkDestination(passage) },\n end: markup.end,\n };\n}\n\n/** The passage that a link markup argument names, if SugarCube reads the whole argument as markup. */\nfunction markupArgumentLinks(raw: string): PassageLink[] {\n const markup = linkMarkupAt(raw, 0);\n return markup?.link === undefined || markup.end !== raw.length ? [] : [markup.link];\n}\n\n/**\n * The passages a tag names: its own, if it is a `<<link>>` or `<<goto>>` call, then those of its\n * link markup arguments (`<<button [[Go|Room]]>>`), and those of the links and calls inside the\n * strings of its arguments, which the macro may print or pass on\n * (`<<set _out to '<<link \"Go\" \"Room\">><</link>>'>>`). The arguments of the macros SugarCube\n * doesn't split are read as JavaScript; in others, a backquoted expression is.\n */\nfunction tagPassageLinks(tag: MacroTag, context: ReadContext): PassageLink[] {\n if (RAW_ARGUMENT_MACROS.has(tag.name)) {\n return javaScriptPassageLinks(tag.args, context);\n }\n const lexed = lexMacroArgs(tag.args);\n if (lexed === undefined) {\n // SugarCube throws, so the call does nothing.\n return [];\n }\n const own = ownPassageLink(tag, lexed);\n const inner = lexed.flatMap((arg): PassageLink[] => {\n switch (arg.kind) {\n case 'string':\n return markupPassageLinks(arg.value, deeper(context));\n case 'expression':\n return javaScriptPassageLinks(arg.code, context);\n case 'markup':\n return markupArgumentLinks(arg.text);\n case 'word':\n return [];\n default: {\n const _exhaustive: never = arg;\n throw new Error(`unhandled macro argument: ${JSON.stringify(_exhaustive)}`);\n }\n }\n });\n return own === undefined ? inner : [own, ...inner];\n}\n\n/**\n * The passage named by a `<<link>>` or `<<goto>>` that appears unquoted inside another tag's\n * arguments, at `start`. SugarCube never sees such an outer \"tag\" when its `<<` lies in text it\n * reads as something else, such as verbatim text (`{{{<<if}}}`); the call inside it then runs.\n * The call ends where the outer tag ends.\n */\nfunction innerPassageLink(\n matchTagAt: (start: number) => ScannedTag | undefined,\n start: number,\n): PassageLink | undefined {\n const inner = matchTagAt(start)?.tag;\n const lexed = inner === undefined ? undefined : lexMacroArgs(inner.args);\n return inner === undefined || lexed === undefined ? undefined : ownPassageLink(inner, lexed);\n}\n\n// Where link or image markup, a comment, a `<script>` element or italics can start, as SugarCube's\n// parsers match them: the markup whose text is read apart from the walk. `//` is here only because\n// it comes first, as in SugarCube: `//*` is italics.\nconst REGION_OPEN_RE = /\\[\\[[^[]|\\[[<>]?[Ii][Mm][Gg]\\[|\\/\\/|\\/\\*|\\/%|<!--|<[Ss][Cc][Rr][Ii][Pp][Tt]/g;\nconst HAS_SCRIPT_OPEN_RE = /<[Ss][Cc][Rr][Ii][Pp][Tt]/;\ntype RegionKind = 'markup' | '//' | CommentKind | 'script';\n\nfunction regionKind(opener: string): RegionKind {\n if (opener.startsWith('[')) {\n return 'markup';\n }\n switch (opener) {\n case '//':\n case '/*':\n case '/%':\n case '<!--':\n return opener;\n default:\n return 'script';\n }\n}\n\n// SugarCube's `(?:.|\\n)*?` doesn't cross the other line terminators.\nconst SCRIPT_CLOSE_RE = /<\\/[Ss][Cc][Rr][Ii][Pp][Tt]>|[\\r\\u2028\\u2029]/g;\nconst COMMENT_CLOSE_RES: Readonly<Record<CommentKind, RegExp>> = {\n '/*': /\\*\\/|[\\r\\u2028\\u2029]/g,\n '/%': /%\\/|[\\r\\u2028\\u2029]/g,\n '<!--': /-->|[\\r\\u2028\\u2029]/g,\n};\ntype CommentKind = '/*' | '/%' | '<!--';\n\n/**\n * Returns a function that finds where a comment that opens at `start` ends, as SugarCube's\n * `commentByBlock` parser reads it, or `undefined` if it isn't closed. Calls of one kind must come\n * in increasing order: a search that fails stops at a line terminator or the end, and a later one\n * of the same kind that starts before that stop fails too, so it isn't made.\n */\nfunction commentReader(text: string): (kind: CommentKind, start: number) => number | undefined {\n const failedUntil = new Map<CommentKind, number>();\n return (kind, start) => {\n if (start < (failedUntil.get(kind) ?? -1)) {\n return undefined;\n }\n const re = COMMENT_CLOSE_RES[kind];\n re.lastIndex = start + kind.length;\n const m = re.exec(text);\n if (m !== null && m[0].length > 1) {\n return m.index + m[0].length;\n }\n failedUntil.set(kind, m === null ? text.length : m.index);\n return undefined;\n };\n}\n\n/** Where a `<script>` element's opener ends and its content ends, if it is complete. */\ninterface ScriptElementScan {\n /** Index just past the opener's `>`, or `undefined` if no `>` follows. */\n readonly openerEnd: number | undefined;\n /** Index of the closing `</script>`, or `undefined` if the element isn't closed. */\n readonly close: number | undefined;\n}\n\n/**\n * Returns a function that reads a `<script>` element whose opener starts at a position, as\n * SugarCube's `verbatimScriptTag` parser reads it: the opener up to its `>`, then the content\n * up to the first `</script>`. Calls must come in increasing order; each part of the text is\n * searched once.\n */\nfunction scriptElementReader(text: string): (start: number) => ScriptElementScan {\n let angle = -1;\n let noAngleAfter = Infinity;\n let failedBefore = -1;\n let noCloseAfter = Infinity;\n return (start) => {\n if (start + 7 >= noAngleAfter) {\n return { openerEnd: undefined, close: undefined };\n }\n if (angle < start + 7) {\n angle = text.indexOf('>', start + 7);\n if (angle === -1) {\n noAngleAfter = start + 7;\n return { openerEnd: undefined, close: undefined };\n }\n }\n const openerEnd = angle + 1;\n if (openerEnd < failedBefore || openerEnd >= noCloseAfter) {\n // The content would run into the line terminator where an earlier element failed.\n return { openerEnd, close: undefined };\n }\n SCRIPT_CLOSE_RE.lastIndex = openerEnd;\n const m = SCRIPT_CLOSE_RE.exec(text);\n if (m === null) {\n noCloseAfter = openerEnd;\n return { openerEnd, close: undefined };\n }\n if (m[0].length === 1) {\n failedBefore = m.index;\n return { openerEnd, close: undefined };\n }\n return { openerEnd, close: m.index };\n };\n}\n\n/**\n * Returns a function that finds the tag closing the `<<script>>` body that `opener` opens, as\n * SugarCube's `parseBody` finds it: scanning tags from every `<<` after the opener, without\n * skipping anything, for the first `<</script>>` or `<<endscript>>` that isn't matched by a\n * later `<<script>>`. (It doesn't reproduce parseBody's rejection of a closing tag with\n * arguments, nor its resuming inside the arguments of a tag whose name starts with `/` or\n * `end`.)\n *\n * The tags found from the start of the text are those parseBody finds from any opener among\n * them, so for such an opener the answer takes constant time. An opener the walk reached after\n * a comment may not be among them, when a tag that starts in the comment runs over it; then the\n * scan starts at the body and goes on until it finds the closer or reaches a tag of that list,\n * whose answers it then uses. All such scans in one reading of a passage, strings included, stop\n * once they have read four times as many characters as the passage has, plus a fixed allowance\n * (`budget`, see `readContext`); on input built to make them read more, the openers after that\n * are taken as unclosed. That keeps the time linear. (Exported for tests; the module is not part\n * of the package's API.)\n */\nexport function scriptBodyCloser(text: string, budget: { left: number }): (opener: MacroTag) => MacroTag | undefined {\n const tags = findMacroTags(text);\n const indexByStart = new Map(tags.map((tag, index) => [tag.start, index]));\n const lastClose = text.lastIndexOf('>>');\n const spend = (characters: number): void => {\n budget.left -= characters;\n };\n const step = (tag: MacroTag): number =>\n tag.name === 'script' ? 1 : tag.name === '/script' || tag.name === 'endscript' ? -1 : 0;\n // balance[k]: openers minus closers among the first k tags.\n const balance: number[] = [0];\n tags.forEach((tag, k) => balance.push((balance[k] ?? 0) + step(tag)));\n // firstBelow[k]: the first j > k with balance[j] < balance[k], if any.\n const firstBelow: (number | undefined)[] = [];\n const candidates: number[] = [];\n for (let k = balance.length - 1; k >= 0; k--) {\n const here = balance[k] ?? 0;\n let top = candidates[candidates.length - 1];\n while (top !== undefined && (balance[top] ?? 0) >= here) {\n candidates.pop();\n top = candidates[candidates.length - 1];\n }\n firstBelow[k] = top;\n candidates.push(k);\n }\n /**\n * The closer when `open` bodies are open just before `tags[index]`: each hop to\n * `firstBelow` closes one. `open` is at most one more than the openers scanned to get here.\n */\n const closeFrom = (index: number, open: number): MacroTag | undefined => {\n let k: number | undefined = index;\n for (let left = open; left > 0 && k !== undefined; left--) {\n k = firstBelow[k];\n }\n return k === undefined ? undefined : tags[k - 1];\n };\n return (opener) => {\n const index = indexByStart.get(opener.start);\n if (index !== undefined) {\n return closeFrom(index + 1, 1);\n }\n const matchTagAt = tagMatcher(text, lastClose, spend);\n let open = 1;\n let from = opener.end;\n while (budget.left >= 0) {\n const start = text.indexOf('<<', from);\n spend((start === -1 ? text.length : start) - from);\n if (start === -1) {\n return undefined;\n }\n const known = indexByStart.get(start);\n if (known !== undefined) {\n return closeFrom(known, open);\n }\n const tag = matchTagAt(start)?.tag;\n if (tag === undefined) {\n from = start + 2;\n continue;\n }\n open += step(tag);\n if (open === 0) {\n return tag;\n }\n from = tag.end;\n }\n return undefined;\n };\n}\n\n/** Adds `more` to the end of `links`, without spreading, which fails for very long lists. */\nfunction append(links: PassageLink[], more: readonly PassageLink[]): void {\n for (const link of more) {\n links.push(link);\n }\n}\n\n/**\n * The passages that link markup (`[[…]]`) and `<<link>>` and `<<goto>>` calls in passage markup\n * name, in the order they come. Calls whose passage is known only in play (a variable or an\n * expression) are left out. A tag's own passage comes before those that its arguments name, as\n * link markup or inside strings.\n *\n * The markup is walked in order, as SugarCube's wikifier walks it, with a tag tried at each\n * `<<` the walk reaches, and link or image markup read at each `[[` or `[img[`; markup SugarCube\n * rejects is read on from just after its opener, and so is markup after a limit on how much\n * markup a reading may scan, which only input built to take quadratic time reaches (see\n * `readSquareBracketedMarkup`). Image markup names no passage here. Of the wikifier's other\n * parsers, only those whose text holds no link or call are told apart: comments (`/* … *` + `/`,\n * `/% … %/`, `<!-- … -->`), whose links and calls never run, and `<script>` elements and\n * `<<script>>` bodies, which are JavaScript: only the links and calls in their strings are read\n * (see `findJavaScriptPassageLinks`). Everything else, verbatim text included, is read as markup.\n *\n * Where this differs from SugarCube:\n * - a link whose passage SugarCube evaluates, because no passage has its name, is taken by its\n * name, `[[Go|$next]]` naming the passage `$next`, unless it is a quoted string, which is taken\n * by its value even when a passage has the name with the quotes;\n * - a link SugarCube takes for a URL, because no passage has its name and it looks like one or\n * holds a `/`, `.`, `?` or `#`, is still read as naming a passage;\n * - a comment or a `<<script>>` body is skipped whole, even where `parseBody` ends a container\n * such as `<<if>>` at a closing tag inside it and the rest then runs;\n * - a `[[`, `/*`, `<!--` or `<script` inside other markup that holds no call, such as verbatim\n * text or a `<style>` element, still starts link markup, a comment or an element;\n * - a `<<` in such other markup still starts a tag. When that tag runs over a `<<link` or\n * `<<goto` outside the parts of its arguments that the tag pattern reads as units, that call\n * is still read (see `innerPassageLink`), even where the tag's arguments would be JavaScript,\n * as the check always read it. One that such a part covers is lost: a quoted string, or a `//`\n * part up to a line feed (italics, a URL) when a `>>` follows later; and a `<<script>>` body\n * the tag runs over is read as markup. The same recovery also reads a call inside a stray tag\n * that SugarCube does see, and rejects as an unknown macro (`<<Back <<goto R>>`);\n * - a `<<script>>` body's end is found as `parseBody` finds it, except that parseBody rejects a\n * closing tag with arguments, and resumes inside the arguments of a tag whose name starts with\n * `/` or `end`;\n * - the lines of a `<<nobr>>` body, and of every passage when a story sets\n * `Config.passages.nobr`, are not joined before they are read (see `storyInspect` for passages\n * tagged `nobr`).\n */\nexport function findPassageLinks(text: string): PassageLink[] {\n return markupPassageLinks(text, readContext(text));\n}\n\nfunction markupPassageLinks(text: string, context: ReadContext): PassageLink[] {\n if (\n context.depth > MAX_STRING_DEPTH ||\n (!text.includes('<<') && !text.includes('[[') && !HAS_SCRIPT_OPEN_RE.test(text))\n ) {\n return [];\n }\n const matchTagAt = tagMatcher(text);\n // For the calls inside tags' arguments, which also come in increasing order.\n const matchInnerTagAt = tagMatcher(text);\n const readComment = commentReader(text);\n const readScriptElement = scriptElementReader(text);\n let findScriptCloser: ((opener: MacroTag) => MacroTag | undefined) | undefined;\n const links: PassageLink[] = [];\n\n /**\n * Reads the region `opener` opens, adding the passage that link markup names and the links and\n * calls in a `<script>` element; returns where the walk goes on.\n */\n const regionEnd = (opener: RegExpExecArray): number => {\n const start = opener.index;\n const kind = regionKind(opener[0]);\n switch (kind) {\n case 'markup': {\n const markup = linkMarkupAt(text, start, context.markupBudget);\n if (markup === undefined) {\n // SugarCube prints the opener it matched and reads on after it.\n return start + opener[0].length;\n }\n if (markup.link !== undefined) {\n links.push(markup.link);\n }\n return markup.end;\n }\n case '//':\n // Italics, whose text is read on; `//*` is not a comment.\n return start + 2;\n case '/*':\n case '/%':\n case '<!--':\n return readComment(kind, start) ?? start + kind.length;\n case 'script': {\n const element = readScriptElement(start);\n if (element.openerEnd === undefined) {\n // Not an opener SugarCube reads.\n return start + 1;\n }\n if (element.close === undefined) {\n // SugarCube reads the opener and nothing more; the content is markup.\n return element.openerEnd;\n }\n append(links, javaScriptPassageLinks(text.slice(element.openerEnd, element.close), context));\n return element.close + 9;\n }\n default: {\n const _exhaustive: never = kind;\n throw new Error(`unhandled region: ${String(_exhaustive)}`);\n }\n }\n };\n\n // The next `<<` and region opener at or after `pos`, searched again only once `pos` passes them.\n let macro = -2;\n let region: RegExpExecArray | null | undefined;\n let pos = 0;\n for (;;) {\n if (macro !== -1 && macro < pos) {\n macro = text.indexOf('<<', pos);\n }\n if (region !== null && (region === undefined || region.index < pos)) {\n REGION_OPEN_RE.lastIndex = pos;\n region = REGION_OPEN_RE.exec(text);\n }\n if (region !== null && (macro === -1 || region.index < macro)) {\n pos = regionEnd(region);\n continue;\n }\n if (macro === -1) {\n return links;\n }\n const scanned = matchTagAt(macro);\n if (scanned === undefined) {\n pos = macro + 2;\n continue;\n }\n const { tag, innerCall } = scanned;\n append(links, tagPassageLinks(tag, context));\n if (innerCall !== undefined) {\n const inner = innerPassageLink(matchInnerTagAt, innerCall);\n if (inner !== undefined) {\n links.push(inner);\n }\n }\n pos = tag.end;\n if (tag.name === 'script') {\n findScriptCloser ??= scriptBodyCloser(text, context.budget);\n const closer = findScriptCloser(tag);\n if (closer !== undefined) {\n append(links, javaScriptPassageLinks(text.slice(tag.end, closer.start), context));\n pos = closer.end;\n }\n }\n }\n}\n\n/**\n * The passages that link markup and `<<link>>` and `<<goto>>` calls in the strings of JavaScript\n * source name, such as a script passage or a `<<script>>` body: `$.wiki('<<goto \"Room\">>')`.\n * Code outside the strings isn't markup, so a call put together while the story plays, such as\n * `'<<goto \"' + target + '\">>'`, names no passage here, nor does an array of arrays (`[[0, 1]]`).\n */\nexport function findJavaScriptPassageLinks(source: string): PassageLink[] {\n return javaScriptPassageLinks(source, readContext(source));\n}\n\n/**\n * What JavaScript source must contain for one of its string or template literals to hold a call\n * or link markup that is read. A value holding `<<`: each `<` in it is written as `<`, `\\<`,\n * `\\x3c`, `\\u003c` or `\\u{…}`, two can be next to each other with only line continuations\n * between, and the first is `<` or `\\<` (then the source holds `<<` or `<\\`) or one of the others.\n * A value holding `[[`, likewise: the source holds `[[`, a `[` before `\\[` or a line continuation,\n * `\\x5b`, `\\u005b` or `\\u{`. Or a value holding a `<script>` element, whose own strings can make\n * `<<` or `[[` from escapes the outer string encodes.\n */\nconst MAY_HOLD_LINK_RE = /<<|<\\\\|\\\\x3c|\\\\u003c|\\\\u\\{|<script|\\[\\[|\\[\\\\[[\\n\\r\\u2028\\u2029]|\\\\x5b|\\\\u005b/i;\n\nfunction javaScriptPassageLinks(source: string, context: ReadContext): PassageLink[] {\n if (context.depth >= MAX_STRING_DEPTH || !MAY_HOLD_LINK_RE.test(source)) {\n // No string in it can hold a link or a macro call.\n return [];\n }\n const inner = deeper(context);\n const links: PassageLink[] = [];\n for (const value of javaScriptStrings(source)) {\n append(links, markupPassageLinks(value, inner));\n }\n return links;\n}\n","/**\n * Story inspection utilities for unit testing.\n *\n * Extracts structural information from a compiled story:\n * passage names, tags, link graph, broken links, dead ends, orphans.\n *\n * Usage:\n * const result = await compile({ sources: ['./story'] });\n * const map = storyInspect(result.story);\n * expect(map.passages).toContain('Start');\n * expect(map.brokenLinks).toHaveLength(0);\n */\nimport type { InspectOptions, PassageOmission, ReadonlyPassage, ReadonlyStory } from './types.js';\nimport { hasTag, isInfoPassage, isStoryPassage } from './passage.js';\nimport { passageOmission } from './passage-omission.js';\nimport { findJavaScriptPassageLinks, findPassageLinks } from './sugarcube-macros.js';\n\nexport interface StoryMap {\n /** All passage names, in source order. */\n passages: string[];\n /** Only story passages (excludes StoryData, StoryTitle, scripts, stylesheets, etc.). */\n storyPassages: string[];\n /** Only info/special passages. */\n infoPassages: string[];\n /** All unique tags used across the story, sorted alphabetically. */\n tags: string[];\n /** Map of tag → passage names that carry that tag. */\n passagesByTag: Map<string, string[]>;\n /** Map of passage name → tags on that passage. */\n tagsByPassage: Map<string, string[]>;\n /**\n * Map of passage name → passage names it links to.\n * Parses `[[target]]`, `[[display->target]]`, `[[target<-display]]`, `[[display|target]]`,\n * each with or without a setter (`[[display|target][$x to 1]]`), and SugarCube's\n * `<<goto \"target\">>` / `<<link \"display\" \"target\">>`, read as SugarCube 2 reads them\n * (see `sugarcube-macros.ts`). Links and calls in comments are not read. A script passage is\n * read for links only in its strings; a stylesheet passage (including a loaded `.css` file) is\n * CSS and links to nothing.\n */\n links: Map<string, string[]>;\n /**\n * Broken links: `{ from, to }` pairs where `to` doesn't exist as a passage, or, with a `target`\n * (see `InspectOptions`), where that output leaves the `to` passage out (`omission` says why).\n */\n brokenLinks: BrokenLink[];\n /** Story passages with no outgoing links (potential dead ends). */\n deadEnds: string[];\n /** Story passages that no other passage links to (excluding the start passage). */\n orphans: string[];\n /** The configured start passage name, if any. */\n start: string;\n}\n\nexport interface BrokenLink {\n from: string;\n to: string;\n /**\n * Set when a passage named `to` exists, but the inspected output leaves it out of the story\n * (only with a `target`): why it is left out. Absent when no passage has the name.\n */\n omission?: PassageOmission;\n}\n\n/**\n * Extract the passages that passage text links to, read as SugarCube 2 reads them.\n *\n * Supported syntaxes:\n * - `[[PassageName]]`\n * - `[[Display Text|PassageName]]`\n * - `[[Display Text->PassageName]]`\n * - `[[PassageName<-Display Text]]`\n * - any of those with a setter: `[[Display Text|PassageName][$x to 1]]`\n * - `<<goto \"PassageName\">>` (SugarCube macro)\n * - `<<link \"Display\" \"PassageName\">>` (SugarCube macro)\n *\n * In link markup, the first `|`, `->` or `<-` divides the text from the passage name; image\n * markup (`[img[…][PassageName]]`) is not read. SugarCube macro arguments may be double- or\n * single-quoted, with backslash escapes, or bare words; a passage named by a variable or an\n * expression is known only in play and is skipped. Links and macro calls are also read inside the\n * quoted strings of macros' arguments, and inside the strings of `<<script>>` bodies and\n * `<script>` elements; links and calls in comments are not read. A script passage (`isScript`) is\n * JavaScript, so its links and calls are read only inside its strings. See `sugarcube-macros.ts`\n * for the details and the known differences from SugarCube.\n */\nfunction extractLinksFromText(text: string, isScript: boolean): string[] {\n const found = isScript ? findJavaScriptPassageLinks(text) : findPassageLinks(text);\n // Link markup, then gotos, then links: the order this list has always had.\n const ordered = (['markup', 'goto', 'link'] as const).flatMap((via) =>\n found.filter((link) => link.via === via).map((link) => link.passage),\n );\n return [...new Set(ordered)];\n}\n\n/**\n * The passages that `p` links to. A script passage is JavaScript, read for links only in its\n * strings. A stylesheet is CSS, which the story puts in a style element and never wikifies, so it\n * links nowhere; a passage tagged both is a script, as Twine 2 output takes it.\n */\nfunction passageLinks(p: ReadonlyPassage): string[] {\n if (hasTag(p, 'script')) return extractLinksFromText(textAsRead(p), true);\n if (hasTag(p, 'stylesheet')) return [];\n return extractLinksFromText(textAsRead(p), false);\n}\n\n/**\n * Each passage name, mapped to why the `target` output leaves that passage out, or to `undefined`\n * when a link can reach it: always without a target, and otherwise when the output emits a\n * passage of that name.\n */\nfunction destinationOmissions(\n story: ReadonlyStory,\n { target }: InspectOptions,\n): ReadonlyMap<string, PassageOmission | undefined> {\n const omissions = new Map<string, PassageOmission | undefined>();\n for (const p of story.passages) {\n const omission = target === undefined ? undefined : passageOmission(story, p, target);\n // One emitted passage of a name is enough for a link to reach it.\n if (!omissions.has(p.name) || omission === undefined) {\n omissions.set(p.name, omission);\n }\n }\n return omissions;\n}\n\n/** Passages SugarCube runs from their raw text, never joining their lines. */\nconst RAW_TEXT_PASSAGES: ReadonlySet<string> = new Set(['StoryInit', 'PassageReady', 'PassageDone']);\n\n/**\n * A passage's text as SugarCube reads it for its links. A passage tagged `nobr` has its line\n * breaks joined (`Passage.processText`): leading and trailing ones removed, each run inside made\n * one space. Script passages, `init`-tagged passages, StoryInit, PassageReady and PassageDone are\n * run from their raw text, so they keep theirs.\n */\nfunction textAsRead(p: ReadonlyPassage): string {\n const joined = hasTag(p, 'nobr') && !hasTag(p, 'script') && !hasTag(p, 'init') && !RAW_TEXT_PASSAGES.has(p.name);\n return joined ? joinLines(p.text) : p.text;\n}\n\n/**\n * What SugarCube's `text.replace(/^\\n+|\\n+$/g, '').replace(/\\n+/g, ' ')` gives, without that\n * pattern's backtracking, which takes quadratic time on a long run of line feeds.\n */\nfunction joinLines(text: string): string {\n let start = 0;\n while (text[start] === '\\n') {\n start += 1;\n }\n let end = text.length;\n while (end > start && text[end - 1] === '\\n') {\n end -= 1;\n }\n return text.slice(start, end).replace(/\\n+/g, ' ');\n}\n\n/**\n * Inspect a story and return its full structural map.\n *\n * Designed for story authors to use in unit tests:\n * ```ts\n * const result = await compile({ sources: ['./story'] });\n * const map = storyInspect(result.story);\n *\n * // Assert structure\n * expect(map.passages).toContain('Start');\n * expect(map.tags).toContain('location');\n * expect(map.passagesByTag.get('location')).toContain('Kitchen');\n * expect(map.brokenLinks).toEqual([]);\n * expect(map.deadEnds).not.toContain('Start');\n * ```\n *\n * By default, a link is broken only when no passage has its name. Pass a `target` to check links\n * against what that output emits: `storyInspect(result.story, { target: 'twine2' })` also reports\n * links to passages Twine 2 output leaves out, such as script, stylesheet and `Twine.private`\n * passages.\n */\nexport function storyInspect(story: ReadonlyStory, options: InspectOptions = {}): StoryMap {\n const destinations = destinationOmissions(story, options);\n\n const passages: string[] = [];\n const storyPassages: string[] = [];\n const infoPassages: string[] = [];\n const tagSet = new Set<string>();\n const passagesByTag = new Map<string, string[]>();\n const tagsByPassage = new Map<string, string[]>();\n const links = new Map<string, string[]>();\n\n for (const p of story.passages) {\n passages.push(p.name);\n\n if (isStoryPassage(p)) {\n storyPassages.push(p.name);\n }\n if (isInfoPassage(p)) {\n infoPassages.push(p.name);\n }\n\n // Tags\n tagsByPassage.set(p.name, [...p.tags]);\n for (const tag of p.tags) {\n tagSet.add(tag);\n let list = passagesByTag.get(tag);\n if (!list) {\n list = [];\n passagesByTag.set(tag, list);\n }\n list.push(p.name);\n }\n\n // Links\n links.set(p.name, passageLinks(p));\n }\n\n // Broken links: link targets that don't exist as passages, or that the target output leaves out\n const brokenLinks: BrokenLink[] = [];\n for (const [from, targets] of links) {\n for (const to of targets) {\n if (!destinations.has(to)) {\n brokenLinks.push({ from, to });\n continue;\n }\n const omission = destinations.get(to);\n if (omission !== undefined) {\n brokenLinks.push({ from, to, omission });\n }\n }\n }\n\n // Dead ends: story passages with no outgoing links\n const deadEnds: string[] = [];\n for (const name of storyPassages) {\n const targets = links.get(name);\n if (!targets || targets.length === 0) {\n deadEnds.push(name);\n }\n }\n\n // Orphans: story passages nobody links to (excluding start)\n const start = story.twine2.start || 'Start';\n const linkedTo = new Set<string>();\n for (const targets of links.values()) {\n for (const t of targets) {\n linkedTo.add(t);\n }\n }\n const orphans: string[] = [];\n for (const name of storyPassages) {\n if (name !== start && !linkedTo.has(name)) {\n orphans.push(name);\n }\n }\n\n return {\n passages,\n storyPassages,\n infoPassages,\n tags: [...tagSet].sort(),\n passagesByTag,\n tagsByPassage,\n links,\n brokenLinks,\n deadEnds,\n orphans,\n start,\n };\n}\n","/**\n * Lint mode: compile + inspect story structure without producing output.\n * Surfaces broken links, dead ends, orphans, and compilation diagnostics.\n */\nimport type { CompileOptions, CompileStats, Diagnostic } from './types.js';\nimport type { BrokenLink } from './inspect.js';\nimport { compileForOutputFile } from './compiler.js';\nimport { storyInspect } from './inspect.js';\nimport { describeOmission } from './passage-omission.js';\nimport { startPassageDiagnostics } from './start-passage.js';\n\nexport interface LintResult {\n /** Compilation diagnostics (errors and warnings). */\n diagnostics: Diagnostic[];\n /** Compilation statistics. */\n stats: CompileStats;\n /** Story format name from StoryData (e.g. \"SugarCube\"). */\n formatName: string;\n /** Story format version from StoryData (e.g. \"2.37.3\"). */\n formatVersion: string;\n /** The configured start passage name. */\n start: string;\n /** Total passage count. */\n passages: number;\n /** Story passage count (excludes StoryData, StoryTitle, scripts, etc.). */\n storyPassages: number;\n /** Info/special passage count. */\n infoPassages: number;\n /**\n * Broken links: link targets that don't exist as passages, or that Twine 2 output leaves out\n * (script, stylesheet and `Twine.private` passages, StoryData, StoryTitle, an empty\n * StorySettings); for those, `omission` says why.\n */\n brokenLinks: BrokenLink[];\n /** Story passages with no outgoing links. */\n deadEnds: string[];\n /** Story passages that no other passage links to. */\n orphans: string[];\n}\n\n/**\n * Lint a story: compile without output rendering, then inspect structure.\n * Uses JSON output mode internally to avoid format resolution, so it checks\n * the starting passage itself, against the Twine 2 passage rules. Link\n * destinations are checked against the same rules: a link to a passage that\n * Twine 2 output leaves out is broken.\n */\nexport async function lint(options: Omit<CompileOptions, 'outputMode'>): Promise<LintResult> {\n return lintForOutputFile(options, undefined);\n}\n\n/**\n * lint() for a project whose builds are written to `outFile`: like a build for that file,\n * it leaves `outFile` out of the sources and modules, so an earlier build inside a source\n * folder is not linted as a source.\n *\n * Internal, for the CLI; not part of the public API.\n */\nexport async function lintForOutputFile(\n options: Omit<CompileOptions, 'outputMode'>,\n outFile: string | undefined,\n): Promise<LintResult> {\n const result = await compileForOutputFile({ ...options, outputMode: 'json' }, outFile);\n const map = storyInspect(result.story, { target: 'twine2' });\n\n return {\n diagnostics: [...result.diagnostics, ...startPassageDiagnostics(result.story, map.start, 'twine2')],\n stats: result.stats,\n formatName: result.story.twine2.format,\n formatVersion: result.story.twine2.formatVersion,\n start: map.start,\n passages: map.passages.length,\n storyPassages: map.storyPassages.length,\n infoPassages: map.infoPassages.length,\n brokenLinks: map.brokenLinks,\n deadEnds: map.deadEnds,\n orphans: map.orphans,\n };\n}\n\n/**\n * Format a lint result as a human-readable report string.\n */\nexport function formatLintReport(result: LintResult): string {\n const lines: string[] = [];\n\n // Header: format and stats\n const formatStr = result.formatName\n ? `${result.formatName}${result.formatVersion ? ' ' + result.formatVersion : ''}`\n : 'unknown';\n lines.push(`Format: ${formatStr}`);\n lines.push(\n `Passages: ${result.passages} total (${result.storyPassages} story, ${result.infoPassages} info), ${result.stats.words.toLocaleString()} words, ${result.stats.files.length} files`,\n );\n lines.push(`Start: ${result.start}`);\n\n // Broken links (errors)\n if (result.brokenLinks.length > 0) {\n lines.push('');\n lines.push(`Broken links (${result.brokenLinks.length}):`);\n for (const link of result.brokenLinks) {\n const why =\n link.omission === undefined\n ? 'does not exist'\n : `${describeOmission(link.omission)}, so it is left out of the story data`;\n lines.push(` ${link.from} -> ${link.to} (passage \"${link.to}\" ${why})`);\n }\n }\n\n // Dead ends (warnings)\n if (result.deadEnds.length > 0) {\n lines.push('');\n lines.push(`Dead ends (${result.deadEnds.length}): ${result.deadEnds.join(', ')}`);\n }\n\n // Orphans (warnings)\n if (result.orphans.length > 0) {\n lines.push('');\n lines.push(`Orphans (${result.orphans.length}): ${result.orphans.join(', ')}`);\n }\n\n // Compilation diagnostics\n const errors = result.diagnostics.filter((d) => d.level === 'error');\n const warnings = result.diagnostics.filter((d) => d.level === 'warning');\n\n if (errors.length > 0 || warnings.length > 0) {\n lines.push('');\n lines.push(`Diagnostics: ${errors.length} error(s), ${warnings.length} warning(s)`);\n for (const d of errors) {\n lines.push(` error: ${d.message}`);\n }\n for (const d of warnings) {\n lines.push(` warning: ${d.message}`);\n }\n }\n\n // Summary line\n lines.push('');\n const hasErrors = errors.length > 0 || result.brokenLinks.length > 0;\n if (hasErrors) {\n lines.push('Lint failed.');\n } else {\n lines.push('Lint passed.');\n }\n\n return lines.join('\\n');\n}\n","/**\n * Config file loading and validation for twee-ts.\n */\nimport { readFileSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { TweeTsConfig, OutputMode, WordCountMethod } from './types.js';\n\nexport const CONFIG_FILENAME = 'twee-ts.config.json';\n\nconst VALID_OUTPUT_MODES: OutputMode[] = ['html', 'twee3', 'twee1', 'twine2-archive', 'twine1-archive', 'json'];\nconst VALID_WORD_COUNT_METHODS: WordCountMethod[] = ['tweego', 'whitespace'];\n\n/** Load a config file from the given directory (default: cwd). Returns null if not found. */\nexport function loadConfig(dir?: string): TweeTsConfig | null {\n const base = dir ?? process.cwd();\n const configPath = join(base, CONFIG_FILENAME);\n\n if (!existsSync(configPath)) return null;\n\n let raw: string;\n try {\n raw = readFileSync(configPath, 'utf-8');\n } catch {\n return null;\n }\n\n let data: unknown;\n try {\n data = JSON.parse(raw);\n } catch (e) {\n throw new Error(`Invalid JSON in ${configPath}: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n const errors = validateConfig(data);\n if (errors.length > 0) {\n throw new Error(`Invalid config in ${configPath}:\\n ${errors.join('\\n ')}`);\n }\n\n return data as TweeTsConfig;\n}\n\n/** Load a config from a specific file path. */\nexport function loadConfigFile(filePath: string): TweeTsConfig {\n let raw: string;\n try {\n raw = readFileSync(filePath, 'utf-8');\n } catch (e) {\n throw new Error(`Cannot read config file ${filePath}: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n let data: unknown;\n try {\n data = JSON.parse(raw);\n } catch (e) {\n throw new Error(`Invalid JSON in ${filePath}: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n const errors = validateConfig(data);\n if (errors.length > 0) {\n throw new Error(`Invalid config in ${filePath}:\\n ${errors.join('\\n ')}`);\n }\n\n return data as TweeTsConfig;\n}\n\n/** Validate a config object. Returns an array of error strings (empty = valid). */\nexport function validateConfig(data: unknown): string[] {\n const errors: string[] = [];\n\n if (typeof data !== 'object' || data === null || Array.isArray(data)) {\n errors.push('Config must be a JSON object.');\n return errors;\n }\n\n const obj = data as Record<string, unknown>;\n\n // String fields\n for (const key of ['output', 'formatId', 'startPassage', 'headFile'] as const) {\n if (key in obj && typeof obj[key] !== 'string') {\n errors.push(`\"${key}\" must be a string.`);\n }\n }\n\n // Boolean fields\n for (const key of ['useTweegoPath', 'trim', 'twee2Compat', 'testMode', 'noRemote', 'sourceInfo'] as const) {\n if (key in obj && typeof obj[key] !== 'boolean') {\n errors.push(`\"${key}\" must be a boolean.`);\n }\n }\n\n // String array fields\n for (const key of ['sources', 'exclude', 'formatPaths', 'formatIndices', 'formatUrls', 'modules'] as const) {\n if (key in obj) {\n if (!Array.isArray(obj[key])) {\n errors.push(`\"${key}\" must be an array.`);\n } else if (!(obj[key] as unknown[]).every((v) => typeof v === 'string')) {\n errors.push(`\"${key}\" must be an array of strings.`);\n }\n }\n }\n\n // tagAliases validation\n if ('tagAliases' in obj) {\n if (typeof obj['tagAliases'] !== 'object' || obj['tagAliases'] === null || Array.isArray(obj['tagAliases'])) {\n errors.push('\"tagAliases\" must be an object.');\n } else {\n const aliases = obj['tagAliases'] as Record<string, unknown>;\n for (const [key, val] of Object.entries(aliases)) {\n if (typeof val !== 'string') {\n errors.push(`\"tagAliases.${key}\" must be a string.`);\n }\n }\n }\n }\n\n // OutputMode validation\n if ('outputMode' in obj) {\n if (typeof obj['outputMode'] !== 'string' || !VALID_OUTPUT_MODES.includes(obj['outputMode'] as OutputMode)) {\n errors.push(`\"outputMode\" must be one of: ${VALID_OUTPUT_MODES.join(', ')}.`);\n }\n }\n\n // WordCountMethod validation\n if ('wordCountMethod' in obj) {\n if (\n typeof obj['wordCountMethod'] !== 'string' ||\n !VALID_WORD_COUNT_METHODS.includes(obj['wordCountMethod'] as WordCountMethod)\n ) {\n errors.push(`\"wordCountMethod\" must be one of: ${VALID_WORD_COUNT_METHODS.join(', ')}.`);\n }\n }\n\n return errors;\n}\n\n/** Return a default config JSON string for --init scaffolding. */\nexport function scaffoldConfig(): string {\n const config = {\n $schema: 'https://unpkg.com/@rohal12/twee-ts/schemas/twee-ts.config.schema.json',\n sources: ['src/'],\n output: 'story.html',\n };\n return JSON.stringify(config, null, 2) + '\\n';\n}\n","/**\n * twee-ts CLI entry point.\n * Uses node:util.parseArgs() for argument parsing.\n */\nimport { parseArgs } from 'node:util';\nimport { writeFileSync, mkdirSync } from 'node:fs';\nimport { compileForOutputFile, watchWithWriteFilter } from '../src/compiler.js';\nimport { lintForOutputFile, formatLintReport } from '../src/lint.js';\nimport { discoverFormats, getFormatSearchDirs } from '../src/formats.js';\nimport { loadConfig, loadConfigFile, scaffoldConfig, CONFIG_FILENAME } from '../src/config.js';\nimport {\n discoverCachedFormats,\n getCacheDir,\n listCachedFormats,\n clearCachedFormats,\n getCacheSize,\n} from '../src/remote-formats.js';\nimport type { Diagnostic, TweeTsConfig, OutputMode, WordCountMethod } from '../src/types.js';\n\nimport { VERSION } from '../src/version.js';\n\nconst { values, positionals } = parseArgs({\n allowPositionals: true,\n options: {\n output: { type: 'string', short: 'o' },\n format: { type: 'string', short: 'f' },\n start: { type: 'string', short: 's' },\n module: { type: 'string', short: 'm', multiple: true },\n head: { type: 'string' },\n 'decompile-twee3': { type: 'boolean', short: 'd' },\n 'decompile-twee1': { type: 'boolean' },\n 'archive-twine2': { type: 'boolean', short: 'a' },\n 'archive-twine1': { type: 'boolean' },\n 'twee2-compat': { type: 'boolean' },\n 'no-trim': { type: 'boolean' },\n lint: { type: 'boolean' },\n test: { type: 'boolean', short: 't' },\n watch: { type: 'boolean', short: 'w' },\n 'log-stats': { type: 'boolean', short: 'l' },\n 'log-files': { type: 'boolean' },\n 'list-formats': { type: 'boolean' },\n json: { type: 'boolean' },\n init: { type: 'boolean' },\n help: { type: 'boolean', short: 'h' },\n version: { type: 'boolean', short: 'v' },\n // New flags\n 'format-index': { type: 'string', multiple: true },\n 'format-url': { type: 'string', multiple: true },\n 'no-remote': { type: 'boolean' },\n 'tag-alias': { type: 'string', multiple: true },\n exclude: { type: 'string', multiple: true },\n 'source-info': { type: 'boolean' },\n 'word-count-method': { type: 'string' },\n config: { type: 'string', short: 'c' },\n 'no-config': { type: 'boolean' },\n },\n});\n\nasync function main(): Promise<void> {\n if (values.version) {\n console.log(`twee-ts v${VERSION}`);\n return;\n }\n\n if (values.help) {\n printUsage();\n return;\n }\n\n if (values['list-formats']) {\n listFormats();\n return;\n }\n\n if (values.init) {\n runInit();\n return;\n }\n\n if (positionals[0] === 'cache') {\n runCache(positionals.slice(1));\n return;\n }\n\n // Load config file (unless --no-config)\n let config: TweeTsConfig | null = null;\n if (!values['no-config']) {\n if (values.config) {\n config = loadConfigFile(values.config);\n } else {\n config = loadConfig();\n }\n }\n\n // Merge sources: positionals > config.sources\n const sources = positionals.length > 0 ? positionals : config?.sources;\n if (!sources || sources.length === 0) {\n console.error('Error: No input sources specified.');\n printUsage();\n process.exit(1);\n }\n\n // Determine output mode: CLI flag > config > default\n let outputMode: OutputMode = config?.outputMode ?? 'html';\n if (values['decompile-twee3']) outputMode = 'twee3';\n else if (values['decompile-twee1']) outputMode = 'twee1';\n else if (values['archive-twine2']) outputMode = 'twine2-archive';\n else if (values['archive-twine1']) outputMode = 'twine1-archive';\n else if (values.json) outputMode = 'json';\n\n // Parse --tag-alias flags (format: alias=target)\n let tagAliases: Record<string, string> | undefined;\n if (values['tag-alias'] || config?.tagAliases) {\n tagAliases = { ...config?.tagAliases };\n for (const pair of values['tag-alias'] ?? []) {\n const eq = pair.indexOf('=');\n if (eq < 1) {\n console.error(`Error: Invalid --tag-alias \"${pair}\". Expected format: alias=target`);\n process.exit(1);\n }\n tagAliases[pair.slice(0, eq)] = pair.slice(eq + 1);\n }\n }\n\n // Word count method: CLI flag > config > default\n const VALID_WORD_COUNT_METHODS: WordCountMethod[] = ['tweego', 'whitespace'];\n const wordCountMethod: WordCountMethod | undefined = (() => {\n const raw = values['word-count-method'] ?? config?.wordCountMethod;\n if (raw === undefined) return undefined;\n if (!VALID_WORD_COUNT_METHODS.includes(raw as WordCountMethod)) {\n console.error(`Error: Invalid --word-count-method \"${raw}\". Expected: ${VALID_WORD_COUNT_METHODS.join(', ')}`);\n process.exit(1);\n }\n return raw as WordCountMethod;\n })();\n\n const outFile = values.output ?? config?.output ?? '-';\n // The output file, which every build (and lint) leaves out of the sources and modules,\n // so an earlier build inside a source folder is never read back as a source.\n const outPath = outFile === '-' ? undefined : outFile;\n\n // Lint mode: compile + inspect, no output\n if (values.lint) {\n const lintResult = await lintForOutputFile(\n {\n sources,\n exclude: values.exclude ?? config?.exclude,\n formatId: values.format ?? config?.formatId,\n startPassage: values.start ?? config?.startPassage,\n formatPaths: config?.formatPaths,\n modules: values.module ?? config?.modules,\n headFile: values.head ?? config?.headFile,\n trim: values['no-trim'] ? false : (config?.trim ?? true),\n twee2Compat: values['twee2-compat'] ?? config?.twee2Compat ?? false,\n testMode: values.test ?? config?.testMode ?? false,\n formatIndices: values['format-index'] ?? config?.formatIndices,\n formatUrls: values['format-url'] ?? config?.formatUrls,\n noRemote: values['no-remote'] ?? config?.noRemote ?? false,\n tagAliases,\n sourceInfo: values['source-info'] ?? config?.sourceInfo ?? false,\n wordCountMethod,\n },\n outPath,\n );\n console.log(formatLintReport(lintResult));\n const hasErrors = lintResult.brokenLinks.length > 0 || lintResult.diagnostics.some((d) => d.level === 'error');\n process.exit(hasErrors ? 1 : 0);\n }\n\n const compileOptions = {\n sources,\n exclude: values.exclude ?? config?.exclude,\n outputMode,\n formatId: values.format ?? config?.formatId,\n startPassage: values.start ?? config?.startPassage,\n formatPaths: config?.formatPaths,\n modules: values.module ?? config?.modules,\n headFile: values.head ?? config?.headFile,\n trim: values['no-trim'] ? false : (config?.trim ?? true),\n twee2Compat: values['twee2-compat'] ?? config?.twee2Compat ?? false,\n testMode: values.test ?? config?.testMode ?? false,\n useTweegoPath: config?.useTweegoPath,\n formatIndices: values['format-index'] ?? config?.formatIndices,\n formatUrls: values['format-url'] ?? config?.formatUrls,\n noRemote: values['no-remote'] ?? config?.noRemote ?? false,\n tagAliases,\n sourceInfo: values['source-info'] ?? config?.sourceInfo ?? false,\n wordCountMethod,\n };\n\n if (values.watch) {\n if (outPath === undefined) {\n console.error('Error: Watch mode requires an output file (-o).');\n process.exit(1);\n }\n console.log('Watch mode started. Press CTRL+C to stop.');\n // As in a one-shot build, a build with errors is not written: the output file keeps\n // the last good build until a save fixes the errors.\n await watchWithWriteFilter(\n {\n ...compileOptions,\n outFile: outPath,\n onBuild(result) {\n console.log(`Built: ${result.stats.passages} passages, ${result.stats.words} words`);\n logDiagnostics(result.diagnostics);\n // A failed build must not stop the watcher: report it and wait for the next change.\n const errors = countErrors(result.diagnostics);\n if (errors > 0) {\n console.error(`Build has ${pluralize(errors, 'error')}; output not written. Still watching for changes.`);\n }\n },\n onError(error) {\n console.error(`Build error: ${error.message}`);\n },\n },\n (result) => countErrors(result.diagnostics) === 0,\n );\n } else {\n const result = await compileForOutputFile(compileOptions, outPath);\n logDiagnostics(result.diagnostics);\n\n // Like Tweego, a build with errors produces no output: the output file (or stdout)\n // is left untouched and the exit status is 1, so scripts and CI can detect it.\n const errors = countErrors(result.diagnostics);\n if (errors > 0) {\n console.error(`Compilation failed with ${pluralize(errors, 'error')}; output not written.`);\n process.exitCode = 1;\n } else if (outPath === undefined) {\n process.stdout.write(result.output);\n } else {\n writeFileSync(outPath, result.output, 'utf-8');\n }\n\n if (outPath !== undefined && values['log-files']) {\n console.log(`\\nFiles: ${result.stats.files.join(', ')}`);\n }\n if (values['log-stats']) logStats(result);\n }\n}\n\nfunction countErrors(diagnostics: readonly Diagnostic[]): number {\n return diagnostics.filter((d) => d.level === 'error').length;\n}\n\nfunction pluralize(count: number, noun: string): string {\n return `${count} ${noun}${count === 1 ? '' : 's'}`;\n}\n\nfunction listFormats(): void {\n const dirs = getFormatSearchDirs();\n const formats = discoverFormats(dirs);\n\n console.log('Local story formats:');\n if (formats.size === 0) {\n console.log(' (none)');\n } else {\n for (const [id, f] of formats) {\n const type = f.isTwine2 ? 'Twine 2' : 'Twine 1';\n console.log(` ${id}: ${f.name || id} ${f.version} (${type})`);\n }\n }\n\n const cached = discoverCachedFormats();\n if (cached.size > 0) {\n console.log('\\nCached remote formats:');\n for (const [id, f] of cached) {\n console.log(` ${id}: ${f.name} ${f.version}`);\n }\n }\n}\n\nfunction logDiagnostics(diagnostics: Array<{ level: string; message: string }>): void {\n for (const d of diagnostics) {\n if (d.level === 'error') console.error(`error: ${d.message}`);\n else console.warn(`warning: ${d.message}`);\n }\n}\n\nfunction logStats(result: {\n stats: { passages: number; storyPassages?: number; words: number; files: string[] };\n}): void {\n const s = result.stats;\n console.log(`\\nStatistics:`);\n console.log(` Passages: ${s.passages}`);\n console.log(` Words: ${s.words}`);\n console.log(` Files: ${s.files.length}`);\n}\n\ninterface ScaffoldFile {\n readonly path: string;\n readonly content: () => string;\n}\n\nconst SCAFFOLD_FILES: readonly ScaffoldFile[] = [\n { path: CONFIG_FILENAME, content: scaffoldConfig },\n {\n path: 'src/StoryData.tw',\n content: () => `:: StoryData\n{\n\\t\"ifid\": \"${crypto.randomUUID().toUpperCase()}\"\n}\n`,\n },\n {\n path: 'src/Start.tw',\n content: () => `:: Start\nWelcome to your new Twine story!\n\nThis is the starting passage. Edit this file to begin writing your story.\n`,\n },\n];\n\n/**\n * Writes `content` to `path` unless the file already exists.\n * The exclusive flag makes the check and the write one step, so an existing file is never truncated.\n * Returns false when the file was already there.\n */\nfunction writeNewFile(path: string, content: string): boolean {\n try {\n writeFileSync(path, content, { flag: 'wx' });\n return true;\n } catch (e) {\n if (e instanceof Error && 'code' in e && e.code === 'EEXIST') return false;\n throw new Error(`Cannot create ${path}: ${e instanceof Error ? e.message : String(e)}`, { cause: e });\n }\n}\n\nfunction runInit(): void {\n console.log('Initializing new twee-ts project...');\n mkdirSync('src', { recursive: true });\n\n // Existing files are kept as they are: --init never overwrites a story, its IFID, or a config.\n const results = SCAFFOLD_FILES.map((file) => ({ path: file.path, created: writeNewFile(file.path, file.content()) }));\n const created = results.filter((r) => r.created).map((r) => r.path);\n const skipped = results.filter((r) => !r.created).map((r) => r.path);\n\n if (created.length > 0) {\n console.log('Created:');\n for (const path of created) console.log(` ${path}`);\n }\n for (const path of skipped) console.log(`Skipped (already exists): ${path}`);\n console.log('\\nRun: npx @rohal12/twee-ts');\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes}B`;\n const kb = bytes / 1024;\n if (kb < 1024) return `${Math.round(kb)}K`;\n const mb = kb / 1024;\n return `${mb.toFixed(1)}M`;\n}\n\nfunction runCache(args: string[]): void {\n const subcommand = args[0];\n\n switch (subcommand) {\n case 'list': {\n const entries = listCachedFormats();\n if (entries.length === 0) {\n console.log('No cached formats.');\n return;\n }\n for (const e of entries) {\n const date = e.modifiedAt.toISOString().slice(0, 10);\n console.log(`${e.name.padEnd(16)} ${e.version.padEnd(10)} ${formatBytes(e.sizeBytes).padStart(6)} ${date}`);\n }\n return;\n }\n case 'clear': {\n const name = args[1];\n const count = clearCachedFormats(name);\n if (count === 0) {\n console.log(name ? `No cached formats matching \"${name}\".` : 'Cache is already empty.');\n } else {\n console.log(`Cleared ${count} cached format${count === 1 ? '' : 's'}.`);\n }\n return;\n }\n case 'size': {\n const { totalBytes, count } = getCacheSize();\n if (count === 0) {\n console.log('Cache is empty.');\n } else {\n console.log(`Total: ${formatBytes(totalBytes)} (${count} format${count === 1 ? '' : 's'})`);\n }\n return;\n }\n case 'path': {\n console.log(getCacheDir());\n return;\n }\n default: {\n console.error(`Usage: twee-ts cache <list|clear|size|path>\n\n list List cached formats with name, version, size\n clear Delete all cached formats\n clear <name> Delete cached formats matching name\n size Show total cache size\n path Print cache directory path`);\n process.exit(subcommand ? 1 : 0);\n }\n }\n}\n\nfunction printUsage(): void {\n console.log(`twee-ts v${VERSION} — TypeScript Twee-to-HTML compiler\n\nUsage: twee-ts [options] <sources...>\n\nOptions:\n -o, --output <file> Output file (default: stdout)\n -f, --format <id> Story format ID (default: sugarcube-2)\n -s, --start <name> Starting passage (default: Start)\n -m, --module <file> Module file to inject into <head> (repeatable)\n --head <file> Raw HTML file to append to <head>\n -d, --decompile-twee3 Output as Twee 3 source\n --decompile-twee1 Output as Twee 1 source\n -a, --archive-twine2 Output as Twine 2 archive\n --archive-twine1 Output as Twine 1 archive\n --json Output as JSON\n --twee2-compat Enable Twee2 syntax compatibility\n --lint Lint story structure (broken links, dead ends, orphans)\n --no-trim Don't trim passage whitespace\n -t, --test Enable test/debug mode\n -w, --watch Watch for changes and rebuild\n -l, --log-stats Log compilation statistics\n --log-files Log input file list\n --list-formats List available story formats\n --init Initialize a new project\n --format-index <url> SFA-compatible format index URL (repeatable)\n --format-url <url> Direct format.js URL (repeatable)\n --tag-alias <alias=target> Map a tag to a special tag (repeatable)\n --exclude <glob> Leave out source files matching a glob (repeatable)\n --source-info Emit source file/line as data- attributes on passages\n --word-count-method <m> Word counting method: tweego (default), whitespace\n --no-remote Disable remote format fetching\n -c, --config <file> Config file path (default: ${CONFIG_FILENAME})\n --no-config Skip config file loading\n -h, --help Show this help\n -v, --version Show version\n\nSubcommands:\n cache list List cached remote formats\n cache clear [name] Clear cached formats (all or by name)\n cache size Show total cache size\n cache path Print cache directory path`);\n}\n\nmain().catch((err: unknown) => {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n"],"x_google_ignoreList":[15,16,17,18,19,20,21,22,23,24,25,26],"mappings":"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"}
|