@aglyn/aglyn 1.0.0-beta.197 → 1.0.0-beta.199

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.
Files changed (80) hide show
  1. package/package.json +11 -11
  2. package/src/lib/app-utils/docs-help.generated.d.ts +1 -1
  3. package/src/lib/app-utils/docs-help.generated.js +1 -0
  4. package/src/lib/app-utils/docs-help.generated.js.map +1 -1
  5. package/src/lib/app-utils/docs-index.generated.js +3 -3
  6. package/src/lib/app-utils/docs-index.generated.js.map +1 -1
  7. package/src/lib/app-utils/media-embedded-fields.d.ts +471 -0
  8. package/src/lib/app-utils/media-embedded-fields.js +619 -0
  9. package/src/lib/app-utils/media-embedded-fields.js.map +1 -0
  10. package/src/lib/app-utils/media-embedded-metadata/exif.d.ts +160 -0
  11. package/src/lib/app-utils/media-embedded-metadata/exif.js +1267 -0
  12. package/src/lib/app-utils/media-embedded-metadata/exif.js.map +1 -0
  13. package/src/lib/app-utils/media-embedded-metadata/gif.d.ts +44 -0
  14. package/src/lib/app-utils/media-embedded-metadata/gif.js +134 -0
  15. package/src/lib/app-utils/media-embedded-metadata/gif.js.map +1 -0
  16. package/src/lib/app-utils/media-embedded-metadata/heif.d.ts +23 -0
  17. package/src/lib/app-utils/media-embedded-metadata/heif.js +354 -0
  18. package/src/lib/app-utils/media-embedded-metadata/heif.js.map +1 -0
  19. package/src/lib/app-utils/media-embedded-metadata/icc.d.ts +22 -0
  20. package/src/lib/app-utils/media-embedded-metadata/icc.js +85 -0
  21. package/src/lib/app-utils/media-embedded-metadata/icc.js.map +1 -0
  22. package/src/lib/app-utils/media-embedded-metadata/image-blocks.d.ts +145 -0
  23. package/src/lib/app-utils/media-embedded-metadata/image-blocks.js +200 -0
  24. package/src/lib/app-utils/media-embedded-metadata/image-blocks.js.map +1 -0
  25. package/src/lib/app-utils/media-embedded-metadata/index.d.ts +93 -0
  26. package/src/lib/app-utils/media-embedded-metadata/index.js +744 -0
  27. package/src/lib/app-utils/media-embedded-metadata/index.js.map +1 -0
  28. package/src/lib/app-utils/media-embedded-metadata/iptc.d.ts +59 -0
  29. package/src/lib/app-utils/media-embedded-metadata/iptc.js +529 -0
  30. package/src/lib/app-utils/media-embedded-metadata/iptc.js.map +1 -0
  31. package/src/lib/app-utils/media-embedded-metadata/jpeg.d.ts +43 -0
  32. package/src/lib/app-utils/media-embedded-metadata/jpeg.js +456 -0
  33. package/src/lib/app-utils/media-embedded-metadata/jpeg.js.map +1 -0
  34. package/src/lib/app-utils/media-embedded-metadata/mp4.d.ts +37 -0
  35. package/src/lib/app-utils/media-embedded-metadata/mp4.js +621 -0
  36. package/src/lib/app-utils/media-embedded-metadata/mp4.js.map +1 -0
  37. package/src/lib/app-utils/media-embedded-metadata/ooxml.d.ts +131 -0
  38. package/src/lib/app-utils/media-embedded-metadata/ooxml.js +1058 -0
  39. package/src/lib/app-utils/media-embedded-metadata/ooxml.js.map +1 -0
  40. package/src/lib/app-utils/media-embedded-metadata/pdf-objects.d.ts +223 -0
  41. package/src/lib/app-utils/media-embedded-metadata/pdf-objects.js +936 -0
  42. package/src/lib/app-utils/media-embedded-metadata/pdf-objects.js.map +1 -0
  43. package/src/lib/app-utils/media-embedded-metadata/pdf.d.ts +82 -0
  44. package/src/lib/app-utils/media-embedded-metadata/pdf.js +1167 -0
  45. package/src/lib/app-utils/media-embedded-metadata/pdf.js.map +1 -0
  46. package/src/lib/app-utils/media-embedded-metadata/png.d.ts +41 -0
  47. package/src/lib/app-utils/media-embedded-metadata/png.js +512 -0
  48. package/src/lib/app-utils/media-embedded-metadata/png.js.map +1 -0
  49. package/src/lib/app-utils/media-embedded-metadata/svg.d.ts +30 -0
  50. package/src/lib/app-utils/media-embedded-metadata/svg.js +154 -0
  51. package/src/lib/app-utils/media-embedded-metadata/svg.js.map +1 -0
  52. package/src/lib/app-utils/media-embedded-metadata/tiff.d.ts +40 -0
  53. package/src/lib/app-utils/media-embedded-metadata/tiff.js +158 -0
  54. package/src/lib/app-utils/media-embedded-metadata/tiff.js.map +1 -0
  55. package/src/lib/app-utils/media-embedded-metadata/types.d.ts +60 -0
  56. package/src/lib/app-utils/media-embedded-metadata/types.js +32 -0
  57. package/src/lib/app-utils/media-embedded-metadata/types.js.map +1 -0
  58. package/src/lib/app-utils/media-embedded-metadata/webm.d.ts +26 -0
  59. package/src/lib/app-utils/media-embedded-metadata/webm.js +417 -0
  60. package/src/lib/app-utils/media-embedded-metadata/webm.js.map +1 -0
  61. package/src/lib/app-utils/media-embedded-metadata/webp.d.ts +37 -0
  62. package/src/lib/app-utils/media-embedded-metadata/webp.js +272 -0
  63. package/src/lib/app-utils/media-embedded-metadata/webp.js.map +1 -0
  64. package/src/lib/app-utils/media-embedded-metadata/xml.d.ts +231 -0
  65. package/src/lib/app-utils/media-embedded-metadata/xml.js +598 -0
  66. package/src/lib/app-utils/media-embedded-metadata/xml.js.map +1 -0
  67. package/src/lib/app-utils/media-embedded-metadata/xmp.d.ts +100 -0
  68. package/src/lib/app-utils/media-embedded-metadata/xmp.js +1475 -0
  69. package/src/lib/app-utils/media-embedded-metadata/xmp.js.map +1 -0
  70. package/src/lib/app-utils/media-embedded-metadata/zip.d.ts +93 -0
  71. package/src/lib/app-utils/media-embedded-metadata/zip.js +531 -0
  72. package/src/lib/app-utils/media-embedded-metadata/zip.js.map +1 -0
  73. package/src/lib/app-utils/name-search.d.ts +12 -0
  74. package/src/lib/app-utils/name-search.js +11 -0
  75. package/src/lib/app-utils/name-search.js.map +1 -1
  76. package/src/lib/foundation/definitions/platform.types.d.ts +11 -0
  77. package/src/lib/foundation/definitions/platform.types.js.map +1 -1
  78. package/src/server.d.ts +1 -0
  79. package/src/server.js +7 -0
  80. package/src/server.js.map +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/aglyn/src/lib/app-utils/media-embedded-metadata/ooxml.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * The document properties of a Word, Excel or PowerPoint file (AGL-3331):\n * read from, and written back into, the package's property parts.\n *\n * An Office file is an Open Packaging Conventions package — a ZIP whose\n * parts are found through relationships (ECMA-376 Part 2). Three parts carry\n * what Explorer, Finder and Office's own Info pane show:\n *\n * - core properties (ECMA-376 Part 2, \"Core Properties\"): title, subject,\n * author, keywords, comments, category, last modified by, the two dates.\n * Readable and writable.\n * - extended properties (Part 1 §22.2): the application, the company, the\n * page or slide count. Read-only — the application recomputes them.\n * - custom properties (Part 1 §22.3): named, typed values. Read; a text one\n * can be edited or removed, not added.\n *\n * Each part is found through the package relationships in `_rels/.rels`,\n * never by its usual name — `docProps/core.xml` is a convention, not a rule.\n *\n * ## Lossless writing\n *\n * An edited part is changed as TEXT at the exact offsets the parser\n * recorded: one element's content replaced, one element removed, one\n * inserted before the root's end tag. Every other byte of the part stays as\n * it was, and every other part of the package is copied through byte for\n * byte by `rewriteZip` — the document, the images, the styles, the\n * signatures' parts.\n *\n * ## The XML parser\n *\n * A small, strict, non-validating one (`scanXml`, `parseXml`), because the\n * parts are tiny and the only safe DTD is none: OPC forbids DTD declarations\n * in package XML, so a DOCTYPE here is refused outright rather than\n * skipped, and no entity beyond the five predefined ones and character\n * references is ever expanded. `svg.ts` reuses it, allowing an inert\n * external-id DOCTYPE and nothing more.\n */\n\nimport {\n embeddedFieldLabel,\n otherEmbeddedKey,\n parseOtherEmbeddedKey,\n} from '../media-embedded-fields'\nimport { findZipEntry, readZip, readZipEntry, rewriteZip } from './zip'\nimport type { ZipArchive, ZipEntry } from './zip'\nimport {\n EmbeddedWriteError,\n type EmbeddedCandidate,\n type EmbeddedPatch,\n} from './types'\n\n// ---------------------------------------------------------------------------\n// XML\n// ---------------------------------------------------------------------------\n\nconst NS_XML = 'http://www.w3.org/XML/1998/namespace'\nconst NS_XMLNS = 'http://www.w3.org/2000/xmlns/'\n\nexport interface XmlAttribute {\n /** The qualified name as written. */\n name: string\n prefix: string | null\n local: string\n /**\n * The resolved namespace URI. An unprefixed attribute is in NO namespace\n * (Namespaces in XML 1.0 §6.2), whatever the default namespace is.\n */\n ns: string | null\n /** The value with entities and character references decoded. */\n value: string\n /** Offsets of the raw value, between its quotes. */\n valueStart: number\n valueEnd: number\n}\n\nexport interface XmlStartTag {\n /** The qualified name as written. */\n name: string\n prefix: string | null\n local: string\n ns: string | null\n attributes: XmlAttribute[]\n /** Every namespace binding in scope here, by prefix (`''` = default). */\n namespaces: ReadonlyMap<string, string>\n /** The root element is depth 0. */\n depth: number\n /** Offset of the `<` that opens the start tag. */\n start: number\n /** Offset just past the start tag's `>`. */\n openEnd: number\n selfClosing: boolean\n}\n\nexport interface XmlScanHandlers {\n open?(tag: XmlStartTag): void\n /**\n * Called for every element, a self-closing one included (its\n * `closeStart` and `end` are then both its `openEnd`).\n */\n close?(tag: XmlStartTag, closeStart: number, end: number): void\n /** Character data, decoded; a CDATA section's content arrives verbatim. */\n text?(text: string, start: number, end: number): void\n}\n\nexport interface XmlScanOptions {\n /**\n * Accept a DOCTYPE that has no internal subset, and skip it — nothing it\n * names is ever fetched. A DOCTYPE with an internal subset, and any\n * `<!ENTITY>`, is refused either way, because entity definitions are what\n * turn a small file into a billion laughs.\n */\n allowExternalDoctype?: boolean\n /** Deeper nesting is refused. */\n maxDepth?: number\n /** More elements are refused. */\n maxElements?: number\n}\n\nconst XML_ENTITY =\n /&(?:#x([0-9a-fA-F]{1,6})|#([0-9]{1,7})|(amp|lt|gt|quot|apos));/g\nconst PREDEFINED: Record<string, string> = {\n amp: '&',\n lt: '<',\n gt: '>',\n quot: '\"',\n apos: \"'\",\n}\n\n/** XML 1.0 §2.2 `Char`. */\nfunction isXmlChar(code: number): boolean {\n return (\n code === 0x9 ||\n code === 0xa ||\n code === 0xd ||\n (code >= 0x20 && code <= 0xd7ff) ||\n (code >= 0xe000 && code <= 0xfffd) ||\n (code >= 0x10000 && code <= 0x10ffff)\n )\n}\n\n/**\n * Expand the five predefined entities and character references (XML 1.0\n * §4.1, §4.6). Anything else — an undeclared entity, a stray `&` — is left\n * as written: there is no DTD to define it, and guessing is worse.\n */\nfunction decodeEntities(raw: string): string {\n if (!raw.includes('&')) return raw\n return raw.replace(\n XML_ENTITY,\n (whole, hex?: string, dec?: string, name?: string) => {\n if (name) return PREDEFINED[name] ?? whole\n const code = hex ? parseInt(hex, 16) : parseInt(dec ?? '', 10)\n return isXmlChar(code) ? String.fromCodePoint(code) : whole\n },\n )\n}\n\n/** Character data: line ends normalized (§2.11), then entities. */\nexport function decodeXmlText(raw: string): string {\n return decodeEntities(raw.includes('\\r') ? raw.replace(/\\r\\n?/g, '\\n') : raw)\n}\n\n/** An attribute value, normalized as §3.3.3 does for CDATA attributes. */\nfunction decodeXmlAttribute(raw: string): string {\n return decodeEntities(raw.replace(/\\r\\n|[\\t\\n\\r]/g, ' '))\n}\n\n/** Characters XML 1.0 cannot carry at all, even escaped. */\nconst NOT_XML_CHAR =\n // eslint-disable-next-line no-control-regex\n /[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\ufffe\\uffff]|[\\ud800-\\udbff](?![\\udc00-\\udfff])|(?<![\\ud800-\\udbff])[\\udc00-\\udfff]/g\n\n/** Escape text content; drops what XML cannot represent. */\nexport function escapeXmlText(value: string): string {\n return value\n .replace(NOT_XML_CHAR, '')\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n}\n\n/** Escape a double-quoted attribute value. */\nexport function escapeXmlAttribute(value: string): string {\n return escapeXmlText(value)\n .replace(/\"/g, '&quot;')\n .replace(/\\t/g, '&#9;')\n .replace(/\\n/g, '&#10;')\n .replace(/\\r/g, '&#13;')\n}\n\nconst isSpace = (code: number) =>\n code === 0x20 || code === 0x09 || code === 0x0a || code === 0x0d\n\n/** A name runs until whitespace or markup punctuation. */\nconst endsName = (code: number) =>\n isSpace(code) ||\n code === 0x2f || // /\n code === 0x3e || // >\n code === 0x3d || // =\n code === 0x3c || // <\n code === 0x22 || // \"\n code === 0x27 || // '\n Number.isNaN(code)\n\nfunction splitName(\n name: string,\n): { prefix: string | null; local: string } | null {\n const colon = name.indexOf(':')\n if (colon < 0) return { prefix: null, local: name }\n if (\n colon === 0 ||\n colon === name.length - 1 ||\n name.indexOf(':', colon + 1) >= 0\n )\n return null\n return { prefix: name.slice(0, colon), local: name.slice(colon + 1) }\n}\n\n/**\n * Walk a document start to end, reporting elements and text.\n *\n * Returns false — having possibly reported a prefix of the document — on\n * anything that is not a well-formed, namespace-well-formed document with\n * one root element: mismatched or unclosed tags, a duplicate attribute, an\n * unbound prefix, text outside the root, a refused DOCTYPE or `<!ENTITY>`,\n * or a bound exceeded. Never throws.\n */\nexport function scanXml(\n source: string,\n handlers: XmlScanHandlers,\n options: XmlScanOptions = {},\n): boolean {\n const maxDepth = options.maxDepth ?? 256\n const maxElements = options.maxElements ?? 1_000_000\n const baseNamespaces: ReadonlyMap<string, string> = new Map([['xml', NS_XML]])\n const stack: XmlStartTag[] = []\n const n = source.length\n let rootSeen = false\n let elements = 0\n // A byte-order mark decoded into the string is not content.\n let i = source.charCodeAt(0) === 0xfeff ? 1 : 0\n\n while (i < n) {\n const lt = source.indexOf('<', i)\n const textEnd = lt < 0 ? n : lt\n if (textEnd > i) {\n if (stack.length) {\n handlers.text?.(decodeXmlText(source.slice(i, textEnd)), i, textEnd)\n } else {\n for (let k = i; k < textEnd; k++) {\n if (!isSpace(source.charCodeAt(k))) return false\n }\n }\n }\n if (lt < 0) break\n\n if (source.startsWith('<!--', lt)) {\n const end = source.indexOf('-->', lt + 4)\n if (end < 0) return false\n i = end + 3\n continue\n }\n if (source.startsWith('<![CDATA[', lt)) {\n if (!stack.length) return false\n const end = source.indexOf(']]>', lt + 9)\n if (end < 0) return false\n handlers.text?.(source.slice(lt + 9, end), lt + 9, end)\n i = end + 3\n continue\n }\n if (source.startsWith('<!DOCTYPE', lt)) {\n if (!options.allowExternalDoctype || rootSeen) return false\n let j = lt + 9\n let quote = 0\n for (; j < n; j++) {\n const code = source.charCodeAt(j)\n if (quote) {\n if (code === quote) quote = 0\n } else if (code === 0x22 || code === 0x27) {\n quote = code\n } else if (code === 0x5b) {\n // `[` opens an internal subset: entity definitions.\n return false\n } else if (code === 0x3e) {\n break\n }\n }\n if (j >= n) return false\n i = j + 1\n continue\n }\n // `<!ENTITY`, `<!ELEMENT`, … are only legal inside a DTD.\n if (source.startsWith('<!', lt)) return false\n if (source.startsWith('<?', lt)) {\n const end = source.indexOf('?>', lt + 2)\n if (end < 0) return false\n i = end + 2\n continue\n }\n\n if (source.startsWith('</', lt)) {\n const gt = source.indexOf('>', lt + 2)\n if (gt < 0) return false\n const open = stack.pop()\n if (!open || open.name !== source.slice(lt + 2, gt).trimEnd())\n return false\n handlers.close?.(open, lt, gt + 1)\n i = gt + 1\n continue\n }\n\n // A start tag.\n if (!stack.length && rootSeen) return false\n if (stack.length >= maxDepth || ++elements > maxElements) return false\n let j = lt + 1\n while (j < n && !endsName(source.charCodeAt(j))) j++\n const name = source.slice(lt + 1, j)\n const parts = splitName(name)\n if (!name || !parts) return false\n\n const raw: Array<{\n name: string\n value: string\n start: number\n end: number\n }> = []\n const seen = new Set<string>()\n let selfClosing = false\n for (;;) {\n const before = j\n while (j < n && isSpace(source.charCodeAt(j))) j++\n if (j >= n) return false\n const code = source.charCodeAt(j)\n if (code === 0x3e) {\n j++\n break\n }\n if (code === 0x2f) {\n if (source.charCodeAt(j + 1) !== 0x3e) return false\n selfClosing = true\n j += 2\n break\n }\n // Attributes are separated from the name and each other by space.\n if (j === before) return false\n const nameStart = j\n while (j < n && !endsName(source.charCodeAt(j))) j++\n const attributeName = source.slice(nameStart, j)\n if (!attributeName || seen.has(attributeName)) return false\n seen.add(attributeName)\n while (j < n && isSpace(source.charCodeAt(j))) j++\n if (source.charCodeAt(j) !== 0x3d) return false\n j++\n while (j < n && isSpace(source.charCodeAt(j))) j++\n const quote = source[j]\n if (quote !== '\"' && quote !== \"'\") return false\n const valueEnd = source.indexOf(quote, j + 1)\n if (valueEnd < 0) return false\n const value = source.slice(j + 1, valueEnd)\n if (value.includes('<')) return false\n raw.push({ name: attributeName, value, start: j + 1, end: valueEnd })\n j = valueEnd + 1\n }\n\n const parent = stack.at(-1)\n const inherited = parent?.namespaces ?? baseNamespaces\n let namespaces = inherited\n for (const attribute of raw) {\n if (attribute.name !== 'xmlns' && !attribute.name.startsWith('xmlns:'))\n continue\n if (namespaces === inherited) namespaces = new Map(inherited)\n const prefix = attribute.name === 'xmlns' ? '' : attribute.name.slice(6)\n const uri = decodeXmlAttribute(attribute.value)\n const map = namespaces as Map<string, string>\n if (uri) map.set(prefix, uri)\n else if (prefix) return false\n else map.delete('')\n }\n const ns =\n parts.prefix === null ? namespaces.get('') : namespaces.get(parts.prefix)\n if (parts.prefix !== null && ns === undefined) return false\n\n const attributes: XmlAttribute[] = []\n for (const attribute of raw) {\n const split = splitName(attribute.name)\n if (!split) return false\n let attributeNs: string | null = null\n if (attribute.name === 'xmlns' || split.prefix === 'xmlns') {\n attributeNs = NS_XMLNS\n } else if (split.prefix !== null) {\n const bound = namespaces.get(split.prefix)\n if (bound === undefined) return false\n attributeNs = bound\n }\n attributes.push({\n name: attribute.name,\n prefix: split.prefix,\n local: split.local,\n ns: attributeNs,\n value: decodeXmlAttribute(attribute.value),\n valueStart: attribute.start,\n valueEnd: attribute.end,\n })\n }\n\n const tag: XmlStartTag = {\n name,\n prefix: parts.prefix,\n local: parts.local,\n ns: ns ?? null,\n attributes,\n namespaces,\n depth: stack.length,\n start: lt,\n openEnd: j,\n selfClosing,\n }\n rootSeen = true\n handlers.open?.(tag)\n if (selfClosing) handlers.close?.(tag, j, j)\n else stack.push(tag)\n i = j\n }\n return rootSeen && stack.length === 0\n}\n\nexport interface XmlElement extends XmlStartTag {\n parent: XmlElement | null\n children: XmlElement[]\n /** Child elements and decoded text, in document order. */\n content: Array<XmlElement | string>\n /** Offset of the end tag's `<`; `openEnd` when self-closing. */\n closeStart: number\n /** Offset just past the element. */\n end: number\n}\n\n/** Parse a whole document into a tree. Null when `scanXml` refuses it. */\nexport function parseXml(\n source: string,\n options: XmlScanOptions = {},\n): XmlElement | null {\n const state: { root: XmlElement | null; stack: XmlElement[] } = {\n root: null,\n stack: [],\n }\n const ok = scanXml(\n source,\n {\n open(tag) {\n const parent = state.stack.at(-1) ?? null\n const element: XmlElement = {\n ...tag,\n parent,\n children: [],\n content: [],\n closeStart: tag.openEnd,\n end: tag.openEnd,\n }\n parent?.children.push(element)\n parent?.content.push(element)\n state.root ??= element\n state.stack.push(element)\n },\n close(_tag, closeStart, end) {\n const element = state.stack.pop()\n if (!element) return\n element.closeStart = closeStart\n element.end = end\n },\n text(text) {\n state.stack.at(-1)?.content.push(text)\n },\n },\n options,\n )\n return ok ? state.root : null\n}\n\n/** Every character of text inside an element, descendants included. */\nexport function xmlTextContent(element: XmlElement): string {\n return element.content\n .map((node) => (typeof node === 'string' ? node : xmlTextContent(node)))\n .join('')\n}\n\n/** An attribute's value by local name and namespace (null = no namespace). */\nexport function xmlAttribute(\n element: XmlStartTag,\n local: string,\n ns: string | null = null,\n): XmlAttribute | undefined {\n return element.attributes.find(\n (attribute) => attribute.local === local && attribute.ns === ns,\n )\n}\n\n/** A prefix bound to `ns` in scope at `element`; `''` for the default. */\nfunction prefixFor(element: XmlStartTag, ns: string): string | undefined {\n let fallback: string | undefined\n for (const [prefix, uri] of element.namespaces) {\n if (uri !== ns) continue\n if (prefix) return prefix\n fallback = prefix\n }\n return fallback\n}\n\ninterface TextEdit {\n start: number\n end: number\n text: string\n}\n\nfunction applyEdits(source: string, edits: TextEdit[]): string {\n const ordered = [...edits].sort((a, b) => b.start - a.start || b.end - a.end)\n let out = source\n let floor = Infinity\n for (const edit of ordered) {\n if (edit.end > floor) {\n throw new EmbeddedWriteError(\n 'The document properties could not be edited safely.',\n )\n }\n out = out.slice(0, edit.start) + edit.text + out.slice(edit.end)\n floor = edit.start\n }\n return out\n}\n\n// ---------------------------------------------------------------------------\n// Package\n// ---------------------------------------------------------------------------\n\nconst NS_CP =\n 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties'\nconst NS_DC = 'http://purl.org/dc/elements/1.1/'\nconst NS_DCTERMS = 'http://purl.org/dc/terms/'\nconst NS_DCMITYPE = 'http://purl.org/dc/dcmitype/'\nconst NS_XSI = 'http://www.w3.org/2001/XMLSchema-instance'\n/** Transitional and Strict (ISO/IEC 29500) spellings of the same idea. */\nconst NS_EXTENDED = new Set([\n 'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties',\n 'http://purl.oclc.org/ooxml/officeDocument/extendedProperties',\n])\nconst NS_CUSTOM = new Set([\n 'http://schemas.openxmlformats.org/officeDocument/2006/custom-properties',\n 'http://purl.oclc.org/ooxml/officeDocument/customProperties',\n])\nconst NS_VT = new Set([\n 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes',\n 'http://purl.oclc.org/ooxml/officeDocument/docPropsVTypes',\n])\nconst NS_RELATIONSHIPS =\n 'http://schemas.openxmlformats.org/package/2006/relationships'\nconst NS_CONTENT_TYPES =\n 'http://schemas.openxmlformats.org/package/2006/content-types'\n\nconst CONTENT_TYPES_PART = '[Content_Types].xml'\nconst ROOT_RELATIONSHIPS_PART = '_rels/.rels'\nconst CORE_RELATIONSHIP =\n 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties'\nconst CORE_CONTENT_TYPE =\n 'application/vnd.openxmlformats-package.core-properties+xml'\nconst DEFAULT_CORE_PART = 'docProps/core.xml'\n\n/** A property part is a few KB; this is generous and still bounded. */\nconst PART_MAX_BYTES = 8 * 1024 * 1024\n\n/**\n * The relationship a part is reached by, matched on its tail and without\n * case or hyphens: Transitional says `extended-properties`, Strict says\n * `extendedProperties`, and a few old writers put core properties under the\n * `officeDocument` namespace instead of `package`.\n */\ntype PropertyRole = 'core' | 'extended' | 'custom'\nfunction roleOf(type: string): PropertyRole | null {\n const tail = type.toLowerCase().replace(/-/g, '')\n if (tail.endsWith('/metadata/coreproperties')) return 'core'\n if (tail.endsWith('/extendedproperties')) return 'extended'\n if (tail.endsWith('/customproperties')) return 'custom'\n return null\n}\n\n/** Resolve a root relationship's target to a ZIP entry name (Part 2 §9.3). */\nfunction resolveTarget(target: string): string {\n const segments: string[] = []\n for (const segment of target.split(/[?#]/)[0]?.split('/') ?? []) {\n if (!segment || segment === '.') continue\n if (segment === '..') segments.pop()\n else segments.push(segment)\n }\n return segments.join('/')\n}\n\n/**\n * A part by name. Part names compare case-insensitively (Part 2 §9.1.1.1),\n * and a target may be percent-encoded where the ZIP item name is not.\n */\nfunction findPart(archive: ZipArchive, name: string): ZipEntry | undefined {\n const exact = findZipEntry(archive, name)\n if (exact) return exact\n let decoded = name\n try {\n decoded = decodeURIComponent(name)\n } catch {\n // Not percent-encoded after all.\n }\n const wanted = [name.toLowerCase(), decoded.toLowerCase()]\n return archive.entries.find((entry) =>\n wanted.includes(entry.name.toLowerCase()),\n )\n}\n\ninterface PartText {\n text: string\n /** The part opened with a UTF-8 byte-order mark, to be written back. */\n bom: boolean\n}\n\n/**\n * Decode a part for reading. OPC allows UTF-8 and UTF-16 (Part 2, \"XML\n * Usage\"); the byte-order mark decides, and UTF-8 is the default.\n */\nfunction decodeForRead(bytes: Uint8Array): string {\n if (bytes[0] === 0xfe && bytes[1] === 0xff)\n return new TextDecoder('utf-16be').decode(bytes)\n if (bytes[0] === 0xff && bytes[1] === 0xfe)\n return new TextDecoder('utf-16le').decode(bytes)\n return new TextDecoder('utf-8').decode(bytes)\n}\n\n/**\n * Decode a part for editing: strict UTF-8 only, so that re-encoding the\n * untouched text reproduces the untouched bytes exactly.\n */\nfunction decodeForEdit(bytes: Uint8Array): PartText {\n if (\n (bytes[0] === 0xfe && bytes[1] === 0xff) ||\n (bytes[0] === 0xff && bytes[1] === 0xfe)\n ) {\n throw new EmbeddedWriteError(\n 'This file stores its properties as UTF-16, which cannot be edited here.',\n )\n }\n const bom = bytes[0] === 0xef && bytes[1] === 0xbb && bytes[2] === 0xbf\n try {\n return {\n text: new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(\n bom ? bytes.subarray(3) : bytes,\n ),\n bom,\n }\n } catch {\n throw new EmbeddedWriteError(\n 'The properties in this file are not valid text.',\n )\n }\n}\n\nfunction encodePart(part: PartText): Uint8Array {\n const body = new TextEncoder().encode(part.text)\n if (!part.bom) return body\n const out = new Uint8Array(body.length + 3)\n out.set([0xef, 0xbb, 0xbf])\n out.set(body, 3)\n return out\n}\n\nfunction readPartText(\n archive: ZipArchive,\n entry: ZipEntry | undefined,\n): string | null {\n if (!entry) return null\n const bytes = readZipEntry(archive, entry, PART_MAX_BYTES)\n return bytes ? decodeForRead(bytes) : null\n}\n\ninterface PackageLayout {\n /** Entry names by role, from the root relationships. */\n parts: Partial<Record<PropertyRole, string>>\n relationships: ZipEntry | undefined\n}\n\nfunction packageLayout(archive: ZipArchive): PackageLayout {\n const relationships = findPart(archive, ROOT_RELATIONSHIPS_PART)\n const parts: Partial<Record<PropertyRole, string>> = {}\n const text = readPartText(archive, relationships)\n const root = text === null ? null : parseXml(text)\n if (!root || root.local !== 'Relationships' || root.ns !== NS_RELATIONSHIPS) {\n return { parts, relationships }\n }\n for (const child of root.children) {\n if (child.local !== 'Relationship' || child.ns !== NS_RELATIONSHIPS)\n continue\n if (xmlAttribute(child, 'TargetMode')?.value === 'External') continue\n const role = roleOf(xmlAttribute(child, 'Type')?.value ?? '')\n const target = xmlAttribute(child, 'Target')?.value\n if (role && target && !parts[role]) parts[role] = resolveTarget(target)\n }\n return { parts, relationships }\n}\n\n// ---------------------------------------------------------------------------\n// Reading\n// ---------------------------------------------------------------------------\n\ntype CoreKey =\n | 'title'\n | 'subject'\n | 'creator'\n | 'keywords'\n | 'description'\n | 'category'\n | 'lastModifiedBy'\n | 'createdAt'\n | 'modifiedAt'\n\n/** Where each canonical key lives in the core properties part. */\nconst CORE_FIELDS: Record<\n CoreKey,\n { ns: string; local: string; prefix: string }\n> = {\n title: { ns: NS_DC, local: 'title', prefix: 'dc' },\n subject: { ns: NS_DC, local: 'subject', prefix: 'dc' },\n creator: { ns: NS_DC, local: 'creator', prefix: 'dc' },\n keywords: { ns: NS_CP, local: 'keywords', prefix: 'cp' },\n description: { ns: NS_DC, local: 'description', prefix: 'dc' },\n category: { ns: NS_CP, local: 'category', prefix: 'cp' },\n lastModifiedBy: { ns: NS_CP, local: 'lastModifiedBy', prefix: 'cp' },\n createdAt: { ns: NS_DCTERMS, local: 'created', prefix: 'dcterms' },\n modifiedAt: { ns: NS_DCTERMS, local: 'modified', prefix: 'dcterms' },\n}\n\n/** The core keys an edit may set. The dates and last-modified-by are facts. */\nconst CORE_WRITABLE = new Set<CoreKey>([\n 'title',\n 'subject',\n 'creator',\n 'keywords',\n 'description',\n 'category',\n])\n\nconst isCoreKey = (key: string): key is CoreKey =>\n Object.prototype.hasOwnProperty.call(CORE_FIELDS, key)\n\nconst splitList = (value: string, separator: RegExp) =>\n value\n .split(separator)\n .map((item) => item.trim())\n .filter(Boolean)\n\n/**\n * A W3CDTF date (the profile of ISO 8601 `dcterms:W3CDTF` names) in the\n * catalog's form: seconds kept, a fraction cut to milliseconds, the zone as\n * `Z` or `±HH:MM` and only when one was written. Anything else is returned\n * trimmed, as found.\n */\nfunction normalizeW3cdtf(raw: string): string {\n const value = raw.trim()\n const match =\n /^(\\d{4}-\\d{2}-\\d{2})T(\\d{2}:\\d{2}(?::\\d{2})?)(?:[.,](\\d+))?(Z|[+-]\\d{2}:\\d{2})?$/.exec(\n value,\n )\n if (!match) return value\n const [, date, time, fraction, zone] = match\n return `${date}T${time}${fraction ? `.${fraction.slice(0, 3)}` : ''}${zone ?? ''}`\n}\n\nfunction readCore(text: string): EmbeddedCandidate[] {\n const root = parseXml(text)\n if (!root || root.ns !== NS_CP || root.local !== 'coreProperties') return []\n const out: EmbeddedCandidate[] = []\n const creators: string[] = []\n const keywords: string[] = []\n const seen = new Set<CoreKey>()\n for (const child of root.children) {\n const key = (Object.keys(CORE_FIELDS) as CoreKey[]).find(\n (candidate) =>\n CORE_FIELDS[candidate].ns === child.ns &&\n CORE_FIELDS[candidate].local === child.local,\n )\n if (!key) continue\n const value = xmlTextContent(child).trim()\n if (!value) continue\n // Office writes several authors into one `dc:creator`, joined by `;`.\n if (key === 'creator') creators.push(...splitList(value, /;/))\n else if (key === 'keywords') keywords.push(...splitList(value, /[,;]/))\n else if (!seen.has(key)) {\n seen.add(key)\n out.push({\n key,\n value:\n key === 'createdAt' || key === 'modifiedAt'\n ? normalizeW3cdtf(value)\n : value,\n source: 'ooxml',\n })\n }\n }\n if (creators.length)\n out.push({ key: 'creator', value: creators, source: 'ooxml' })\n if (keywords.length)\n out.push({ key: 'keywords', value: keywords, source: 'ooxml' })\n return out\n}\n\nfunction readExtended(text: string): EmbeddedCandidate[] {\n const root = parseXml(text)\n if (\n !root ||\n !root.ns ||\n !NS_EXTENDED.has(root.ns) ||\n root.local !== 'Properties'\n )\n return []\n const value = (local: string) => {\n const child = root.children.find(\n (element) => element.local === local && element.ns === root.ns,\n )\n return child ? xmlTextContent(child).trim() : ''\n }\n const out: EmbeddedCandidate[] = []\n const application = value('Application')\n if (application)\n out.push({ key: 'software', value: application, source: 'ooxml' })\n const company = value('Company')\n if (company) out.push({ key: 'company', value: company, source: 'ooxml' })\n // Word counts pages and PowerPoint slides; a workbook has neither.\n const count = [value('Pages'), value('Slides')].find((item) =>\n /^\\d+$/.test(item),\n )\n if (count) out.push({ key: 'pageCount', value: count, source: 'ooxml' })\n return out\n}\n\n/** Text-valued variant types — the only ones an edit can write (§22.4). */\nconst VT_TEXT = new Set(['lpwstr', 'lpstr'])\nconst VT_READ_ONLY_TEXT = new Set(['bstr'])\nconst VT_NUMBER = new Set([\n 'i1',\n 'i2',\n 'i4',\n 'i8',\n 'int',\n 'ui1',\n 'ui2',\n 'ui4',\n 'ui8',\n 'uint',\n 'r4',\n 'r8',\n 'decimal',\n])\nconst VT_DATE = new Set(['filetime', 'date'])\n\n/** A custom property's name, from its `name` attribute. */\nconst propertyName = (property: XmlElement) =>\n xmlAttribute(property, 'name')?.value ?? ''\n\n/** The one `vt:` value child of a custom `property` (§22.3.2.2). */\nconst propertyValue = (property: XmlElement) =>\n property.children.find((child) => child.ns !== null && NS_VT.has(child.ns))\n\nfunction customProperties(root: XmlElement): XmlElement[] {\n return root.children.filter(\n (child) => child.local === 'property' && child.ns === root.ns,\n )\n}\n\nfunction readCustom(text: string): EmbeddedCandidate[] {\n const root = parseXml(text)\n if (\n !root ||\n !root.ns ||\n !NS_CUSTOM.has(root.ns) ||\n root.local !== 'Properties'\n )\n return []\n const out: EmbeddedCandidate[] = []\n const seen = new Set<string>()\n for (const property of customProperties(root)) {\n const name = propertyName(property)\n const valueElement = propertyValue(property)\n if (!name || !valueElement || seen.has(name)) continue\n const type = valueElement.local\n const raw = xmlTextContent(valueElement)\n let value: string\n if (VT_TEXT.has(type) || VT_READ_ONLY_TEXT.has(type)) value = raw\n else if (VT_NUMBER.has(type)) value = raw.trim()\n else if (type === 'bool') {\n const flag = raw.trim().toLowerCase()\n value = flag === '1' ? 'true' : flag === '0' ? 'false' : flag\n } else if (VT_DATE.has(type)) value = normalizeW3cdtf(raw)\n // Vectors, arrays, blobs, currency and the rest are not shown.\n else continue\n if (!value.trim()) continue\n seen.add(name)\n out.push({\n key: otherEmbeddedKey('ooxml', name),\n value,\n source: 'ooxml',\n label: name,\n ...(VT_TEXT.has(type) ? {} : { editable: false }),\n })\n }\n return out\n}\n\n/**\n * Read an Office file's document properties.\n *\n * Null when the bytes are not an OPC package — not a ZIP, or a ZIP with no\n * `[Content_Types].xml`. A package whose property parts are missing or\n * unreadable reads as an empty list: a damaged part costs its own fields,\n * not the others'. A part with a DOCTYPE is unreadable by design.\n */\nexport function readOoxml(\n bytes: Uint8Array,\n): { candidates: EmbeddedCandidate[] } | null {\n const archive = readZip(bytes)\n if (!archive || !findPart(archive, CONTENT_TYPES_PART)) return null\n const { parts } = packageLayout(archive)\n const candidates: EmbeddedCandidate[] = []\n const part = (role: PropertyRole) => {\n const name = parts[role]\n return name === undefined\n ? null\n : readPartText(archive, findPart(archive, name))\n }\n const core = part('core')\n if (core !== null) candidates.push(...readCore(core))\n const extended = part('extended')\n if (extended !== null) candidates.push(...readExtended(extended))\n const custom = part('custom')\n if (custom !== null) candidates.push(...readCustom(custom))\n return { candidates }\n}\n\n// ---------------------------------------------------------------------------\n// Writing\n// ---------------------------------------------------------------------------\n\n/** Office's own serialization of `dcterms:modified`: seconds, UTC. */\nconst w3cdtfNow = (now: Date) => now.toISOString().replace(/\\.\\d{3}Z$/, 'Z')\n\nfunction patchText(key: string, value: string | string[]): string {\n if (!Array.isArray(value)) return value.trim()\n const items = value.map((item) => item.trim()).filter(Boolean)\n // Office joins authors with \";\" and keywords with \",\"; both read back.\n return items.join(key === 'creator' ? '; ' : ', ')\n}\n\nfunction parsePart(text: string): XmlElement {\n const root = parseXml(text)\n if (!root) {\n throw new EmbeddedWriteError(\n 'The document properties in this file are damaged, so they cannot be edited.',\n )\n }\n return root\n}\n\n/**\n * The qualified name, and any declaration it needs, for a new element or\n * attribute. An attribute cannot use the default namespace — unprefixed, it\n * would be in none — so it always gets a prefix.\n */\nfunction qualify(\n scope: XmlStartTag,\n ns: string,\n local: string,\n conventional: string,\n attribute = false,\n): { name: string; declare: string } {\n const prefix = prefixFor(scope, ns)\n if (prefix !== undefined && !(attribute && prefix === '')) {\n return { name: prefix ? `${prefix}:${local}` : local, declare: '' }\n }\n return {\n name: `${conventional}:${local}`,\n declare: ` xmlns:${conventional}=\"${escapeXmlAttribute(ns)}\"`,\n }\n}\n\n/** Replace an element's content, expanding it first if it was self-closing. */\nfunction replaceContent(\n source: string,\n element: XmlElement,\n escaped: string,\n): TextEdit {\n if (!element.selfClosing) {\n return { start: element.openEnd, end: element.closeStart, text: escaped }\n }\n const openTag = source\n .slice(element.start, element.openEnd)\n .replace(/\\s*\\/>$/, '>')\n return {\n start: element.start,\n end: element.end,\n text: `${openTag}${escaped}</${element.name}>`,\n }\n}\n\n/** Insert markup as the last content of `root`. */\nfunction appendTo(source: string, root: XmlElement, markup: string): TextEdit {\n if (!root.selfClosing) {\n return { start: root.closeStart, end: root.closeStart, text: markup }\n }\n const openTag = source.slice(root.start, root.openEnd).replace(/\\s*\\/>$/, '>')\n return {\n start: root.start,\n end: root.end,\n text: `${openTag}${markup}</${root.name}>`,\n }\n}\n\nfunction editCore(\n source: string,\n values: Map<CoreKey, string | null>,\n now: Date,\n): string {\n const root = parsePart(source)\n if (root.ns !== NS_CP || root.local !== 'coreProperties') {\n throw new EmbeddedWriteError(\n 'The document properties in this file are damaged, so they cannot be edited.',\n )\n }\n const edits: TextEdit[] = []\n const appended: string[] = []\n const all = new Map(values)\n all.set('modifiedAt', w3cdtfNow(now))\n for (const [key, value] of all) {\n const field = CORE_FIELDS[key]\n const found = root.children.filter(\n (child) => child.ns === field.ns && child.local === field.local,\n )\n const [first, ...rest] = found\n if (value === null) {\n for (const element of found) {\n edits.push({ start: element.start, end: element.end, text: '' })\n }\n continue\n }\n const escaped = escapeXmlText(value)\n if (first) {\n edits.push(replaceContent(source, first, escaped))\n // One value per property: a duplicate would be read instead of it.\n for (const element of rest) {\n edits.push({ start: element.start, end: element.end, text: '' })\n }\n continue\n }\n const { name, declare } = qualify(root, field.ns, field.local, field.prefix)\n let attributes = declare\n if (key === 'modifiedAt') {\n // `xsi:type` names W3CDTF by QName, so its prefix must be in scope.\n const xsi = qualify(root, NS_XSI, 'type', 'xsi', true)\n const dctermsPrefix = name.includes(':')\n ? name.slice(0, name.indexOf(':'))\n : ''\n attributes += `${xsi.declare} ${xsi.name}=\"${dctermsPrefix ? `${dctermsPrefix}:` : ''}W3CDTF\"`\n }\n appended.push(`<${name}${attributes}>${escaped}</${name}>`)\n }\n if (appended.length) edits.push(appendTo(source, root, appended.join('')))\n return applyEdits(source, edits)\n}\n\nfunction editCustom(\n source: string,\n values: Map<string, string | null>,\n): string {\n const root = parsePart(source)\n if (!root.ns || !NS_CUSTOM.has(root.ns) || root.local !== 'Properties') {\n throw new EmbeddedWriteError(\n 'The custom properties in this file are damaged, so they cannot be edited.',\n )\n }\n const properties = customProperties(root)\n const edits: TextEdit[] = []\n const removed = new Set<XmlElement>()\n for (const [name, value] of values) {\n const property = properties.find(\n (element) => propertyName(element) === name,\n )\n if (!property) {\n throw new EmbeddedWriteError(\n `\"${name}\" is not a custom property of this file.`,\n )\n }\n if (value === null) {\n edits.push({ start: property.start, end: property.end, text: '' })\n removed.add(property)\n continue\n }\n const valueElement = propertyValue(property)\n if (!valueElement || !VT_TEXT.has(valueElement.local)) {\n throw new EmbeddedWriteError(\n `\"${name}\" is not a text property, so it cannot be edited here.`,\n )\n }\n edits.push(replaceContent(source, valueElement, escapeXmlText(value)))\n }\n\n // A `pid` must be an integer of at least 2, unique in the part\n // (§22.3.2.2). Removing a property cannot break that, so only a pid that\n // was already broken is renumbered; a valid one never moves.\n const remaining = properties.filter((property) => !removed.has(property))\n const pidOf = (property: XmlElement) => {\n const raw = xmlAttribute(property, 'pid')?.value.trim() ?? ''\n return /^\\d+$/.test(raw) ? Number(raw) : NaN\n }\n let next = Math.max(1, ...remaining.map(pidOf).filter((pid) => pid >= 2))\n const used = new Set<number>()\n for (const property of remaining) {\n const pid = pidOf(property)\n if (pid >= 2 && !used.has(pid)) {\n used.add(pid)\n continue\n }\n next += 1\n const attribute = xmlAttribute(property, 'pid')\n if (attribute) {\n edits.push({\n start: attribute.valueStart,\n end: attribute.valueEnd,\n text: String(next),\n })\n } else {\n const at = property.start + 1 + property.name.length\n edits.push({ start: at, end: at, text: ` pid=\"${next}\"` })\n }\n }\n return applyEdits(source, edits)\n}\n\n/** Add the core part's content-type override, if it has none (Part 2 §10.1.2). */\nfunction editContentTypes(source: string, partName: string): string {\n const root = parsePart(source)\n if (root.ns !== NS_CONTENT_TYPES || root.local !== 'Types') {\n throw new EmbeddedWriteError('The package index of this file is damaged.')\n }\n const wanted = `/${partName}`.toLowerCase()\n const has = root.children.some(\n (child) =>\n child.local === 'Override' &&\n xmlAttribute(child, 'PartName')?.value.toLowerCase() === wanted,\n )\n if (has) return source\n const name = root.prefix ? `${root.prefix}:Override` : 'Override'\n return applyEdits(source, [\n appendTo(\n source,\n root,\n `<${name} PartName=\"/${escapeXmlAttribute(partName)}\" ContentType=\"${CORE_CONTENT_TYPE}\"/>`,\n ),\n ])\n}\n\n/** Add the package relationship to a new core part (Part 2 §9.3). */\nfunction editRelationships(source: string, partName: string): string {\n const root = parsePart(source)\n if (root.ns !== NS_RELATIONSHIPS || root.local !== 'Relationships') {\n throw new EmbeddedWriteError(\n 'The package relationships of this file are damaged.',\n )\n }\n const ids = new Set(\n root.children.map((child) => xmlAttribute(child, 'Id')?.value),\n )\n let index = root.children.length + 1\n while (ids.has(`rId${index}`)) index++\n const name = root.prefix ? `${root.prefix}:Relationship` : 'Relationship'\n return applyEdits(source, [\n appendTo(\n source,\n root,\n `<${name} Id=\"rId${index}\" Type=\"${CORE_RELATIONSHIP}\" Target=\"${escapeXmlAttribute(partName)}\"/>`,\n ),\n ])\n}\n\n/** An empty core properties part, declared the way Office declares it. */\nconst EMPTY_CORE =\n '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\r\\n' +\n `<cp:coreProperties xmlns:cp=\"${NS_CP}\" xmlns:dc=\"${NS_DC}\" xmlns:dcterms=\"${NS_DCTERMS}\" xmlns:dcmitype=\"${NS_DCMITYPE}\" xmlns:xsi=\"${NS_XSI}\"></cp:coreProperties>`\n\nfunction readEditable(archive: ZipArchive, entry: ZipEntry): PartText {\n if (entry.encrypted) {\n throw new EmbeddedWriteError(\n 'This file is encrypted, so its details can only be read.',\n )\n }\n const bytes = readZipEntry(archive, entry, PART_MAX_BYTES)\n if (!bytes) {\n throw new EmbeddedWriteError(\n 'The document properties in this file are damaged, so they cannot be edited.',\n )\n }\n return decodeForEdit(bytes)\n}\n\n/**\n * Write an edit into an Office file's properties.\n *\n * Takes the canonical keys `title`, `subject`, `creator` (joined `\"; \"`),\n * `keywords` (joined `\", \"`), `description` and `category`, and\n * `ooxml|<name>` for a custom text property the file already holds; `null`\n * removes. `dcterms:modified` is always set to `now`. A file with no core\n * part gets one — plus its content-type override and package relationship.\n *\n * Throws {@link EmbeddedWriteError} for any other key, a custom property the\n * file lacks or that is not text, and a package it cannot edit safely.\n */\nexport function writeOoxml(\n bytes: Uint8Array,\n patch: EmbeddedPatch,\n options: { now: Date },\n): Uint8Array {\n const archive = readZip(bytes)\n if (!archive || !findPart(archive, CONTENT_TYPES_PART)) {\n throw new EmbeddedWriteError('This file is not an Office document.')\n }\n\n const core = new Map<CoreKey, string | null>()\n const custom = new Map<string, string | null>()\n for (const [key, raw] of Object.entries(patch)) {\n const value = raw === null ? null : patchText(key, raw) || null\n if (isCoreKey(key) && CORE_WRITABLE.has(key)) {\n core.set(key, value)\n continue\n }\n const other = parseOtherEmbeddedKey(key)\n if (other?.namespace === 'ooxml') {\n custom.set(other.parts.join('|'), value)\n continue\n }\n throw new EmbeddedWriteError(\n `${embeddedFieldLabel(key, 'ooxml')} cannot be written into an Office document.`,\n )\n }\n\n const layout = packageLayout(archive)\n const changes = new Map<string, Uint8Array>()\n const verify = (name: string, part: PartText) => {\n if (!parseXml(part.text)) {\n throw new EmbeddedWriteError(\n 'The edited properties did not verify, so nothing was saved.',\n )\n }\n changes.set(name, encodePart(part))\n }\n\n if (custom.size) {\n const name = layout.parts.custom\n const entry = name === undefined ? undefined : findPart(archive, name)\n if (!entry) {\n const [first] = custom.keys()\n throw new EmbeddedWriteError(\n `\"${first}\" is not a custom property of this file.`,\n )\n }\n const part = readEditable(archive, entry)\n verify(entry.name, { ...part, text: editCustom(part.text, custom) })\n }\n\n const coreName = layout.parts.core\n const coreEntry =\n coreName === undefined ? undefined : findPart(archive, coreName)\n if (coreEntry) {\n const part = readEditable(archive, coreEntry)\n verify(coreEntry.name, {\n ...part,\n text: editCore(part.text, core, options.now),\n })\n } else {\n // No core part: create one, declare its type, and relate it to the\n // package — or, when a relationship already names a missing part,\n // create the part it names.\n let name = coreName\n if (name === undefined) {\n name = DEFAULT_CORE_PART\n for (let index = 1; findPart(archive, name); index++) {\n name = `docProps/core${index}.xml`\n }\n if (!layout.relationships) {\n throw new EmbeddedWriteError(\n 'This Office file has no package relationships.',\n )\n }\n const rels = readEditable(archive, layout.relationships)\n verify(layout.relationships.name, {\n ...rels,\n text: editRelationships(rels.text, name),\n })\n }\n const types = findPart(archive, CONTENT_TYPES_PART)\n if (!types)\n throw new EmbeddedWriteError('This file is not an Office document.')\n const typesPart = readEditable(archive, types)\n verify(types.name, {\n ...typesPart,\n text: editContentTypes(typesPart.text, name),\n })\n verify(name, { text: editCore(EMPTY_CORE, core, options.now), bom: false })\n }\n\n return rewriteZip(archive, changes, { now: options.now })\n}\n"],"names":["embeddedFieldLabel","otherEmbeddedKey","parseOtherEmbeddedKey","findZipEntry","readZip","readZipEntry","rewriteZip","EmbeddedWriteError","NS_XML","NS_XMLNS","XML_ENTITY","PREDEFINED","amp","lt","gt","quot","apos","isXmlChar","code","decodeEntities","raw","includes","replace","whole","hex","dec","name","parseInt","String","fromCodePoint","decodeXmlText","decodeXmlAttribute","NOT_XML_CHAR","escapeXmlText","value","escapeXmlAttribute","isSpace","endsName","Number","isNaN","splitName","colon","indexOf","prefix","local","length","slice","scanXml","source","handlers","options","maxDepth","maxElements","baseNamespaces","Map","stack","n","rootSeen","elements","i","charCodeAt","textEnd","text","k","startsWith","end","allowExternalDoctype","j","quote","open","pop","trimEnd","close","parts","seen","Set","selfClosing","before","nameStart","attributeName","has","add","valueEnd","push","start","parent","at","inherited","namespaces","attribute","uri","map","set","delete","ns","get","undefined","attributes","split","attributeNs","bound","valueStart","tag","depth","openEnd","parseXml","state","root","ok","element","children","content","closeStart","_tag","xmlTextContent","node","join","xmlAttribute","find","prefixFor","fallback","applyEdits","edits","ordered","sort","a","b","out","floor","Infinity","edit","NS_CP","NS_DC","NS_DCTERMS","NS_DCMITYPE","NS_XSI","NS_EXTENDED","NS_CUSTOM","NS_VT","NS_RELATIONSHIPS","NS_CONTENT_TYPES","CONTENT_TYPES_PART","ROOT_RELATIONSHIPS_PART","CORE_RELATIONSHIP","CORE_CONTENT_TYPE","DEFAULT_CORE_PART","PART_MAX_BYTES","roleOf","type","tail","toLowerCase","endsWith","resolveTarget","target","segments","segment","findPart","archive","exact","decoded","decodeURIComponent","wanted","entries","entry","decodeForRead","bytes","TextDecoder","decode","decodeForEdit","bom","fatal","ignoreBOM","subarray","encodePart","part","body","TextEncoder","encode","Uint8Array","readPartText","packageLayout","relationships","child","role","CORE_FIELDS","title","subject","creator","keywords","description","category","lastModifiedBy","createdAt","modifiedAt","CORE_WRITABLE","isCoreKey","key","Object","prototype","hasOwnProperty","call","splitList","separator","item","trim","filter","Boolean","normalizeW3cdtf","match","exec","date","time","fraction","zone","readCore","creators","keys","candidate","readExtended","application","company","count","test","VT_TEXT","VT_READ_ONLY_TEXT","VT_NUMBER","VT_DATE","propertyName","property","propertyValue","customProperties","readCustom","valueElement","flag","label","editable","readOoxml","candidates","core","extended","custom","w3cdtfNow","now","toISOString","patchText","Array","isArray","items","parsePart","qualify","scope","conventional","declare","replaceContent","escaped","openTag","appendTo","markup","editCore","values","appended","all","field","found","first","rest","xsi","dctermsPrefix","editCustom","properties","removed","remaining","pidOf","NaN","next","Math","max","pid","used","editContentTypes","partName","some","editRelationships","ids","index","EMPTY_CORE","readEditable","encrypted","writeOoxml","patch","other","namespace","layout","changes","verify","size","coreName","coreEntry","rels","types","typesPart"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoCC,GAED,SACEA,kBAAkB,EAClBC,gBAAgB,EAChBC,qBAAqB,QAChB,8BAA0B;AACjC,SAASC,YAAY,EAAEC,OAAO,EAAEC,YAAY,EAAEC,UAAU,QAAQ,WAAO;AAEvE,SACEC,kBAAkB,QAGb,aAAS;AAEhB,8EAA8E;AAC9E,MAAM;AACN,8EAA8E;AAE9E,MAAMC,SAAS;AACf,MAAMC,WAAW;AA8DjB,MAAMC,aACJ;AACF,MAAMC,aAAqC;IACzCC,KAAK;IACLC,IAAI;IACJC,IAAI;IACJC,MAAM;IACNC,MAAM;AACR;AAEA,yBAAyB,GACzB,SAASC,UAAUC,IAAY;IAC7B,OACEA,SAAS,OACTA,SAAS,OACTA,SAAS,OACRA,QAAQ,QAAQA,QAAQ,UACxBA,QAAQ,UAAUA,QAAQ,UAC1BA,QAAQ,WAAWA,QAAQ;AAEhC;AAEA;;;;CAIC,GACD,SAASC,eAAeC,GAAW;IACjC,IAAI,CAACA,IAAIC,QAAQ,CAAC,MAAM,OAAOD;IAC/B,OAAOA,IAAIE,OAAO,CAChBZ,YACA,CAACa,OAAOC,KAAcC,KAAcC;YACjBf;QAAjB,IAAIe,MAAM,QAAOf,mBAAAA,UAAU,CAACe,KAAK,YAAhBf,mBAAoBY;QACrC,MAAML,OAAOM,MAAMG,SAASH,KAAK,MAAMG,SAASF,cAAAA,MAAO,IAAI;QAC3D,OAAOR,UAAUC,QAAQU,OAAOC,aAAa,CAACX,QAAQK;IACxD;AAEJ;AAEA,iEAAiE,GACjE,OAAO,SAASO,cAAcV,GAAW;IACvC,OAAOD,eAAeC,IAAIC,QAAQ,CAAC,QAAQD,IAAIE,OAAO,CAAC,UAAU,QAAQF;AAC3E;AAEA,wEAAwE,GACxE,SAASW,mBAAmBX,GAAW;IACrC,OAAOD,eAAeC,IAAIE,OAAO,CAAC,kBAAkB;AACtD;AAEA,0DAA0D,GAC1D,MAAMU,eACJ,4CAA4C;AAC5C;AAEF,0DAA0D,GAC1D,OAAO,SAASC,cAAcC,KAAa;IACzC,OAAOA,MACJZ,OAAO,CAACU,cAAc,IACtBV,OAAO,CAAC,MAAM,SACdA,OAAO,CAAC,MAAM,QACdA,OAAO,CAAC,MAAM;AACnB;AAEA,4CAA4C,GAC5C,OAAO,SAASa,mBAAmBD,KAAa;IAC9C,OAAOD,cAAcC,OAClBZ,OAAO,CAAC,MAAM,UACdA,OAAO,CAAC,OAAO,QACfA,OAAO,CAAC,OAAO,SACfA,OAAO,CAAC,OAAO;AACpB;AAEA,MAAMc,UAAU,CAAClB,OACfA,SAAS,QAAQA,SAAS,QAAQA,SAAS,QAAQA,SAAS;AAE9D,wDAAwD,GACxD,MAAMmB,WAAW,CAACnB,OAChBkB,QAAQlB,SACRA,SAAS,QAAQ,IAAI;IACrBA,SAAS,QAAQ,IAAI;IACrBA,SAAS,QAAQ,IAAI;IACrBA,SAAS,QAAQ,IAAI;IACrBA,SAAS,QAAQ,IAAI;IACrBA,SAAS,QAAQ,IAAI;IACrBoB,OAAOC,KAAK,CAACrB;AAEf,SAASsB,UACPd,IAAY;IAEZ,MAAMe,QAAQf,KAAKgB,OAAO,CAAC;IAC3B,IAAID,QAAQ,GAAG,OAAO;QAAEE,QAAQ;QAAMC,OAAOlB;IAAK;IAClD,IACEe,UAAU,KACVA,UAAUf,KAAKmB,MAAM,GAAG,KACxBnB,KAAKgB,OAAO,CAAC,KAAKD,QAAQ,MAAM,GAEhC,OAAO;IACT,OAAO;QAAEE,QAAQjB,KAAKoB,KAAK,CAAC,GAAGL;QAAQG,OAAOlB,KAAKoB,KAAK,CAACL,QAAQ;IAAG;AACtE;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASM,QACdC,MAAc,EACdC,QAAyB,EACzBC,UAA0B,CAAC,CAAC;QAEXA,mBACGA;IADpB,MAAMC,YAAWD,oBAAAA,QAAQC,QAAQ,YAAhBD,oBAAoB;IACrC,MAAME,eAAcF,uBAAAA,QAAQE,WAAW,YAAnBF,uBAAuB;IAC3C,MAAMG,iBAA8C,IAAIC,IAAI;QAAC;YAAC;YAAO9C;SAAO;KAAC;IAC7E,MAAM+C,QAAuB,EAAE;IAC/B,MAAMC,IAAIR,OAAOH,MAAM;IACvB,IAAIY,WAAW;IACf,IAAIC,WAAW;IACf,4DAA4D;IAC5D,IAAIC,IAAIX,OAAOY,UAAU,CAAC,OAAO,SAAS,IAAI;IAE9C,MAAOD,IAAIH,EAAG;;QACZ,MAAM3C,KAAKmC,OAAON,OAAO,CAAC,KAAKiB;QAC/B,MAAME,UAAUhD,KAAK,IAAI2C,IAAI3C;QAC7B,IAAIgD,UAAUF,GAAG;YACf,IAAIJ,MAAMV,MAAM,EAAE;gBAChBI,SAASa,IAAI,oBAAbb,SAASa,IAAI,MAAbb,UAAgBnB,cAAckB,OAAOF,KAAK,CAACa,GAAGE,WAAWF,GAAGE;YAC9D,OAAO;gBACL,IAAK,IAAIE,IAAIJ,GAAGI,IAAIF,SAASE,IAAK;oBAChC,IAAI,CAAC3B,QAAQY,OAAOY,UAAU,CAACG,KAAK,OAAO;gBAC7C;YACF;QACF;QACA,IAAIlD,KAAK,GAAG;QAEZ,IAAImC,OAAOgB,UAAU,CAAC,QAAQnD,KAAK;YACjC,MAAMoD,MAAMjB,OAAON,OAAO,CAAC,OAAO7B,KAAK;YACvC,IAAIoD,MAAM,GAAG,OAAO;YACpBN,IAAIM,MAAM;YACV;QACF;QACA,IAAIjB,OAAOgB,UAAU,CAAC,aAAanD,KAAK;YACtC,IAAI,CAAC0C,MAAMV,MAAM,EAAE,OAAO;YAC1B,MAAMoB,MAAMjB,OAAON,OAAO,CAAC,OAAO7B,KAAK;YACvC,IAAIoD,MAAM,GAAG,OAAO;YACpBhB,SAASa,IAAI,oBAAbb,SAASa,IAAI,MAAbb,UAAgBD,OAAOF,KAAK,CAACjC,KAAK,GAAGoD,MAAMpD,KAAK,GAAGoD;YACnDN,IAAIM,MAAM;YACV;QACF;QACA,IAAIjB,OAAOgB,UAAU,CAAC,aAAanD,KAAK;YACtC,IAAI,CAACqC,QAAQgB,oBAAoB,IAAIT,UAAU,OAAO;YACtD,IAAIU,IAAItD,KAAK;YACb,IAAIuD,QAAQ;YACZ,MAAOD,IAAIX,GAAGW,IAAK;gBACjB,MAAMjD,OAAO8B,OAAOY,UAAU,CAACO;gBAC/B,IAAIC,OAAO;oBACT,IAAIlD,SAASkD,OAAOA,QAAQ;gBAC9B,OAAO,IAAIlD,SAAS,QAAQA,SAAS,MAAM;oBACzCkD,QAAQlD;gBACV,OAAO,IAAIA,SAAS,MAAM;oBACxB,oDAAoD;oBACpD,OAAO;gBACT,OAAO,IAAIA,SAAS,MAAM;oBACxB;gBACF;YACF;YACA,IAAIiD,KAAKX,GAAG,OAAO;YACnBG,IAAIQ,IAAI;YACR;QACF;QACA,0DAA0D;QAC1D,IAAInB,OAAOgB,UAAU,CAAC,MAAMnD,KAAK,OAAO;QACxC,IAAImC,OAAOgB,UAAU,CAAC,MAAMnD,KAAK;YAC/B,MAAMoD,MAAMjB,OAAON,OAAO,CAAC,MAAM7B,KAAK;YACtC,IAAIoD,MAAM,GAAG,OAAO;YACpBN,IAAIM,MAAM;YACV;QACF;QAEA,IAAIjB,OAAOgB,UAAU,CAAC,MAAMnD,KAAK;YAC/B,MAAMC,KAAKkC,OAAON,OAAO,CAAC,KAAK7B,KAAK;YACpC,IAAIC,KAAK,GAAG,OAAO;YACnB,MAAMuD,OAAOd,MAAMe,GAAG;YACtB,IAAI,CAACD,QAAQA,KAAK3C,IAAI,KAAKsB,OAAOF,KAAK,CAACjC,KAAK,GAAGC,IAAIyD,OAAO,IACzD,OAAO;YACTtB,SAASuB,KAAK,oBAAdvB,SAASuB,KAAK,MAAdvB,UAAiBoB,MAAMxD,IAAIC,KAAK;YAChC6C,IAAI7C,KAAK;YACT;QACF;QAEA,eAAe;QACf,IAAI,CAACyC,MAAMV,MAAM,IAAIY,UAAU,OAAO;QACtC,IAAIF,MAAMV,MAAM,IAAIM,YAAY,EAAEO,WAAWN,aAAa,OAAO;QACjE,IAAIe,IAAItD,KAAK;QACb,MAAOsD,IAAIX,KAAK,CAACnB,SAASW,OAAOY,UAAU,CAACO,IAAKA;QACjD,MAAMzC,OAAOsB,OAAOF,KAAK,CAACjC,KAAK,GAAGsD;QAClC,MAAMM,QAAQjC,UAAUd;QACxB,IAAI,CAACA,QAAQ,CAAC+C,OAAO,OAAO;QAE5B,MAAMrD,MAKD,EAAE;QACP,MAAMsD,OAAO,IAAIC;QACjB,IAAIC,cAAc;QAClB,OAAS;YACP,MAAMC,SAASV;YACf,MAAOA,IAAIX,KAAKpB,QAAQY,OAAOY,UAAU,CAACO,IAAKA;YAC/C,IAAIA,KAAKX,GAAG,OAAO;YACnB,MAAMtC,OAAO8B,OAAOY,UAAU,CAACO;YAC/B,IAAIjD,SAAS,MAAM;gBACjBiD;gBACA;YACF;YACA,IAAIjD,SAAS,MAAM;gBACjB,IAAI8B,OAAOY,UAAU,CAACO,IAAI,OAAO,MAAM,OAAO;gBAC9CS,cAAc;gBACdT,KAAK;gBACL;YACF;YACA,kEAAkE;YAClE,IAAIA,MAAMU,QAAQ,OAAO;YACzB,MAAMC,YAAYX;YAClB,MAAOA,IAAIX,KAAK,CAACnB,SAASW,OAAOY,UAAU,CAACO,IAAKA;YACjD,MAAMY,gBAAgB/B,OAAOF,KAAK,CAACgC,WAAWX;YAC9C,IAAI,CAACY,iBAAiBL,KAAKM,GAAG,CAACD,gBAAgB,OAAO;YACtDL,KAAKO,GAAG,CAACF;YACT,MAAOZ,IAAIX,KAAKpB,QAAQY,OAAOY,UAAU,CAACO,IAAKA;YAC/C,IAAInB,OAAOY,UAAU,CAACO,OAAO,MAAM,OAAO;YAC1CA;YACA,MAAOA,IAAIX,KAAKpB,QAAQY,OAAOY,UAAU,CAACO,IAAKA;YAC/C,MAAMC,QAAQpB,MAAM,CAACmB,EAAE;YACvB,IAAIC,UAAU,OAAOA,UAAU,KAAK,OAAO;YAC3C,MAAMc,WAAWlC,OAAON,OAAO,CAAC0B,OAAOD,IAAI;YAC3C,IAAIe,WAAW,GAAG,OAAO;YACzB,MAAMhD,QAAQc,OAAOF,KAAK,CAACqB,IAAI,GAAGe;YAClC,IAAIhD,MAAMb,QAAQ,CAAC,MAAM,OAAO;YAChCD,IAAI+D,IAAI,CAAC;gBAAEzD,MAAMqD;gBAAe7C;gBAAOkD,OAAOjB,IAAI;gBAAGF,KAAKiB;YAAS;YACnEf,IAAIe,WAAW;QACjB;QAEA,MAAMG,SAAS9B,MAAM+B,EAAE,CAAC,CAAC;QACzB,MAAMC,oBAAYF,0BAAAA,OAAQG,UAAU,mBAAInC;QACxC,IAAImC,aAAaD;QACjB,KAAK,MAAME,aAAarE,IAAK;YAC3B,IAAIqE,UAAU/D,IAAI,KAAK,WAAW,CAAC+D,UAAU/D,IAAI,CAACsC,UAAU,CAAC,WAC3D;YACF,IAAIwB,eAAeD,WAAWC,aAAa,IAAIlC,IAAIiC;YACnD,MAAM5C,SAAS8C,UAAU/D,IAAI,KAAK,UAAU,KAAK+D,UAAU/D,IAAI,CAACoB,KAAK,CAAC;YACtE,MAAM4C,MAAM3D,mBAAmB0D,UAAUvD,KAAK;YAC9C,MAAMyD,MAAMH;YACZ,IAAIE,KAAKC,IAAIC,GAAG,CAACjD,QAAQ+C;iBACpB,IAAI/C,QAAQ,OAAO;iBACnBgD,IAAIE,MAAM,CAAC;QAClB;QACA,MAAMC,KACJrB,MAAM9B,MAAM,KAAK,OAAO6C,WAAWO,GAAG,CAAC,MAAMP,WAAWO,GAAG,CAACtB,MAAM9B,MAAM;QAC1E,IAAI8B,MAAM9B,MAAM,KAAK,QAAQmD,OAAOE,WAAW,OAAO;QAEtD,MAAMC,aAA6B,EAAE;QACrC,KAAK,MAAMR,aAAarE,IAAK;YAC3B,MAAM8E,QAAQ1D,UAAUiD,UAAU/D,IAAI;YACtC,IAAI,CAACwE,OAAO,OAAO;YACnB,IAAIC,cAA6B;YACjC,IAAIV,UAAU/D,IAAI,KAAK,WAAWwE,MAAMvD,MAAM,KAAK,SAAS;gBAC1DwD,cAAc1F;YAChB,OAAO,IAAIyF,MAAMvD,MAAM,KAAK,MAAM;gBAChC,MAAMyD,QAAQZ,WAAWO,GAAG,CAACG,MAAMvD,MAAM;gBACzC,IAAIyD,UAAUJ,WAAW,OAAO;gBAChCG,cAAcC;YAChB;YACAH,WAAWd,IAAI,CAAC;gBACdzD,MAAM+D,UAAU/D,IAAI;gBACpBiB,QAAQuD,MAAMvD,MAAM;gBACpBC,OAAOsD,MAAMtD,KAAK;gBAClBkD,IAAIK;gBACJjE,OAAOH,mBAAmB0D,UAAUvD,KAAK;gBACzCmE,YAAYZ,UAAUL,KAAK;gBAC3BF,UAAUO,UAAUxB,GAAG;YACzB;QACF;QAEA,MAAMqC,MAAmB;YACvB5E;YACAiB,QAAQ8B,MAAM9B,MAAM;YACpBC,OAAO6B,MAAM7B,KAAK;YAClBkD,EAAE,EAAEA,aAAAA,KAAM;YACVG;YACAT;YACAe,OAAOhD,MAAMV,MAAM;YACnBuC,OAAOvE;YACP2F,SAASrC;YACTS;QACF;QACAnB,WAAW;QACXR,SAASoB,IAAI,oBAAbpB,SAASoB,IAAI,MAAbpB,UAAgBqD;QAChB,IAAI1B,aAAa3B,SAASuB,KAAK,oBAAdvB,SAASuB,KAAK,MAAdvB,UAAiBqD,KAAKnC,GAAGA;aACrCZ,MAAM4B,IAAI,CAACmB;QAChB3C,IAAIQ;IACN;IACA,OAAOV,YAAYF,MAAMV,MAAM,KAAK;AACtC;AAaA,wEAAwE,GACxE,OAAO,SAAS4D,SACdzD,MAAc,EACdE,UAA0B,CAAC,CAAC;IAE5B,MAAMwD,QAA0D;QAC9DC,MAAM;QACNpD,OAAO,EAAE;IACX;IACA,MAAMqD,KAAK7D,QACTC,QACA;QACEqB,MAAKiC,GAAG;gBACSI,iBAWfA,QAAAA;YAXA,MAAMrB,UAASqB,kBAAAA,MAAMnD,KAAK,CAAC+B,EAAE,CAAC,CAAC,cAAhBoB,kBAAsB;YACrC,MAAMG,UAAsB,aACvBP;gBACHjB;gBACAyB,UAAU,EAAE;gBACZC,SAAS,EAAE;gBACXC,YAAYV,IAAIE,OAAO;gBACvBvC,KAAKqC,IAAIE,OAAO;;YAElBnB,0BAAAA,OAAQyB,QAAQ,CAAC3B,IAAI,CAAC0B;YACtBxB,0BAAAA,OAAQ0B,OAAO,CAAC5B,IAAI,CAAC0B;aACrBH,QAAAA,CAAAA,SAAAA,OAAMC,IAAI,YAAVD,QAAAA,OAAMC,IAAI,GAAKE;YACfH,MAAMnD,KAAK,CAAC4B,IAAI,CAAC0B;QACnB;QACArC,OAAMyC,IAAI,EAAED,UAAU,EAAE/C,GAAG;YACzB,MAAM4C,UAAUH,MAAMnD,KAAK,CAACe,GAAG;YAC/B,IAAI,CAACuC,SAAS;YACdA,QAAQG,UAAU,GAAGA;YACrBH,QAAQ5C,GAAG,GAAGA;QAChB;QACAH,MAAKA,IAAI;gBACP4C;aAAAA,kBAAAA,MAAMnD,KAAK,CAAC+B,EAAE,CAAC,CAAC,uBAAhBoB,gBAAoBK,OAAO,CAAC5B,IAAI,CAACrB;QACnC;IACF,GACAZ;IAEF,OAAO0D,KAAKF,MAAMC,IAAI,GAAG;AAC3B;AAEA,qEAAqE,GACrE,OAAO,SAASO,eAAeL,OAAmB;IAChD,OAAOA,QAAQE,OAAO,CACnBpB,GAAG,CAAC,CAACwB,OAAU,OAAOA,SAAS,WAAWA,OAAOD,eAAeC,OAChEC,IAAI,CAAC;AACV;AAEA,4EAA4E,GAC5E,OAAO,SAASC,aACdR,OAAoB,EACpBjE,KAAa,EACbkD,KAAoB,IAAI;IAExB,OAAOe,QAAQZ,UAAU,CAACqB,IAAI,CAC5B,CAAC7B,YAAcA,UAAU7C,KAAK,KAAKA,SAAS6C,UAAUK,EAAE,KAAKA;AAEjE;AAEA,wEAAwE,GACxE,SAASyB,UAAUV,OAAoB,EAAEf,EAAU;IACjD,IAAI0B;IACJ,KAAK,MAAM,CAAC7E,QAAQ+C,IAAI,IAAImB,QAAQrB,UAAU,CAAE;QAC9C,IAAIE,QAAQI,IAAI;QAChB,IAAInD,QAAQ,OAAOA;QACnB6E,WAAW7E;IACb;IACA,OAAO6E;AACT;AAQA,SAASC,WAAWzE,MAAc,EAAE0E,KAAiB;IACnD,MAAMC,UAAU;WAAID;KAAM,CAACE,IAAI,CAAC,CAACC,GAAGC,IAAMA,EAAE1C,KAAK,GAAGyC,EAAEzC,KAAK,IAAI0C,EAAE7D,GAAG,GAAG4D,EAAE5D,GAAG;IAC5E,IAAI8D,MAAM/E;IACV,IAAIgF,QAAQC;IACZ,KAAK,MAAMC,QAAQP,QAAS;QAC1B,IAAIO,KAAKjE,GAAG,GAAG+D,OAAO;YACpB,MAAM,IAAIzH,mBACR;QAEJ;QACAwH,MAAMA,IAAIjF,KAAK,CAAC,GAAGoF,KAAK9C,KAAK,IAAI8C,KAAKpE,IAAI,GAAGiE,IAAIjF,KAAK,CAACoF,KAAKjE,GAAG;QAC/D+D,QAAQE,KAAK9C,KAAK;IACpB;IACA,OAAO2C;AACT;AAEA,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,MAAMI,QACJ;AACF,MAAMC,QAAQ;AACd,MAAMC,aAAa;AACnB,MAAMC,cAAc;AACpB,MAAMC,SAAS;AACf,wEAAwE,GACxE,MAAMC,cAAc,IAAI7D,IAAI;IAC1B;IACA;CACD;AACD,MAAM8D,YAAY,IAAI9D,IAAI;IACxB;IACA;CACD;AACD,MAAM+D,QAAQ,IAAI/D,IAAI;IACpB;IACA;CACD;AACD,MAAMgE,mBACJ;AACF,MAAMC,mBACJ;AAEF,MAAMC,qBAAqB;AAC3B,MAAMC,0BAA0B;AAChC,MAAMC,oBACJ;AACF,MAAMC,oBACJ;AACF,MAAMC,oBAAoB;AAE1B,qEAAqE,GACrE,MAAMC,iBAAiB,IAAI,OAAO;AASlC,SAASC,OAAOC,IAAY;IAC1B,MAAMC,OAAOD,KAAKE,WAAW,GAAGhI,OAAO,CAAC,MAAM;IAC9C,IAAI+H,KAAKE,QAAQ,CAAC,6BAA6B,OAAO;IACtD,IAAIF,KAAKE,QAAQ,CAAC,wBAAwB,OAAO;IACjD,IAAIF,KAAKE,QAAQ,CAAC,sBAAsB,OAAO;IAC/C,OAAO;AACT;AAEA,4EAA4E,GAC5E,SAASC,cAAcC,MAAc;;QAEbA;IADtB,MAAMC,WAAqB,EAAE;IAC7B,KAAK,MAAMC,oBAAWF,iBAAAA,OAAOvD,KAAK,CAAC,OAAO,CAAC,EAAE,qBAAvBuD,eAAyBvD,KAAK,CAAC,uBAAQ,EAAE,CAAE;QAC/D,IAAI,CAACyD,WAAWA,YAAY,KAAK;QACjC,IAAIA,YAAY,MAAMD,SAASpF,GAAG;aAC7BoF,SAASvE,IAAI,CAACwE;IACrB;IACA,OAAOD,SAAStC,IAAI,CAAC;AACvB;AAEA;;;CAGC,GACD,SAASwC,SAASC,OAAmB,EAAEnI,IAAY;IACjD,MAAMoI,QAAQ3J,aAAa0J,SAASnI;IACpC,IAAIoI,OAAO,OAAOA;IAClB,IAAIC,UAAUrI;IACd,IAAI;QACFqI,UAAUC,mBAAmBtI;IAC/B,EAAE,eAAM;IACN,iCAAiC;IACnC;IACA,MAAMuI,SAAS;QAACvI,KAAK4H,WAAW;QAAIS,QAAQT,WAAW;KAAG;IAC1D,OAAOO,QAAQK,OAAO,CAAC5C,IAAI,CAAC,CAAC6C,QAC3BF,OAAO5I,QAAQ,CAAC8I,MAAMzI,IAAI,CAAC4H,WAAW;AAE1C;AAQA;;;CAGC,GACD,SAASc,cAAcC,KAAiB;IACtC,IAAIA,KAAK,CAAC,EAAE,KAAK,QAAQA,KAAK,CAAC,EAAE,KAAK,MACpC,OAAO,IAAIC,YAAY,YAAYC,MAAM,CAACF;IAC5C,IAAIA,KAAK,CAAC,EAAE,KAAK,QAAQA,KAAK,CAAC,EAAE,KAAK,MACpC,OAAO,IAAIC,YAAY,YAAYC,MAAM,CAACF;IAC5C,OAAO,IAAIC,YAAY,SAASC,MAAM,CAACF;AACzC;AAEA;;;CAGC,GACD,SAASG,cAAcH,KAAiB;IACtC,IACE,AAACA,KAAK,CAAC,EAAE,KAAK,QAAQA,KAAK,CAAC,EAAE,KAAK,QAClCA,KAAK,CAAC,EAAE,KAAK,QAAQA,KAAK,CAAC,EAAE,KAAK,MACnC;QACA,MAAM,IAAI9J,mBACR;IAEJ;IACA,MAAMkK,MAAMJ,KAAK,CAAC,EAAE,KAAK,QAAQA,KAAK,CAAC,EAAE,KAAK,QAAQA,KAAK,CAAC,EAAE,KAAK;IACnE,IAAI;QACF,OAAO;YACLvG,MAAM,IAAIwG,YAAY,SAAS;gBAAEI,OAAO;gBAAMC,WAAW;YAAK,GAAGJ,MAAM,CACrEE,MAAMJ,MAAMO,QAAQ,CAAC,KAAKP;YAE5BI;QACF;IACF,EAAE,eAAM;QACN,MAAM,IAAIlK,mBACR;IAEJ;AACF;AAEA,SAASsK,WAAWC,IAAc;IAChC,MAAMC,OAAO,IAAIC,cAAcC,MAAM,CAACH,KAAKhH,IAAI;IAC/C,IAAI,CAACgH,KAAKL,GAAG,EAAE,OAAOM;IACtB,MAAMhD,MAAM,IAAImD,WAAWH,KAAKlI,MAAM,GAAG;IACzCkF,IAAInC,GAAG,CAAC;QAAC;QAAM;QAAM;KAAK;IAC1BmC,IAAInC,GAAG,CAACmF,MAAM;IACd,OAAOhD;AACT;AAEA,SAASoD,aACPtB,OAAmB,EACnBM,KAA2B;IAE3B,IAAI,CAACA,OAAO,OAAO;IACnB,MAAME,QAAQhK,aAAawJ,SAASM,OAAOjB;IAC3C,OAAOmB,QAAQD,cAAcC,SAAS;AACxC;AAQA,SAASe,cAAcvB,OAAmB;IACxC,MAAMwB,gBAAgBzB,SAASC,SAASf;IACxC,MAAMrE,QAA+C,CAAC;IACtD,MAAMX,OAAOqH,aAAatB,SAASwB;IACnC,MAAM1E,OAAO7C,SAAS,OAAO,OAAO2C,SAAS3C;IAC7C,IAAI,CAAC6C,QAAQA,KAAK/D,KAAK,KAAK,mBAAmB+D,KAAKb,EAAE,KAAK6C,kBAAkB;QAC3E,OAAO;YAAElE;YAAO4G;QAAc;IAChC;IACA,KAAK,MAAMC,SAAS3E,KAAKG,QAAQ,CAAE;;YAG7BO,eACgBA,gBACLA;QAJf,IAAIiE,MAAM1I,KAAK,KAAK,kBAAkB0I,MAAMxF,EAAE,KAAK6C,kBACjD;QACF,IAAItB,EAAAA,gBAAAA,aAAaiE,OAAO,kCAApBjE,cAAmCnF,KAAK,MAAK,YAAY;QAC7D,MAAMqJ,OAAOpC,gBAAO9B,iBAAAA,aAAaiE,OAAO,4BAApBjE,eAA6BnF,KAAK,mBAAI;QAC1D,MAAMuH,UAASpC,iBAAAA,aAAaiE,OAAO,8BAApBjE,eAA+BnF,KAAK;QACnD,IAAIqJ,QAAQ9B,UAAU,CAAChF,KAAK,CAAC8G,KAAK,EAAE9G,KAAK,CAAC8G,KAAK,GAAG/B,cAAcC;IAClE;IACA,OAAO;QAAEhF;QAAO4G;IAAc;AAChC;AAiBA,gEAAgE,GAChE,MAAMG,cAGF;IACFC,OAAO;QAAE3F,IAAIsC;QAAOxF,OAAO;QAASD,QAAQ;IAAK;IACjD+I,SAAS;QAAE5F,IAAIsC;QAAOxF,OAAO;QAAWD,QAAQ;IAAK;IACrDgJ,SAAS;QAAE7F,IAAIsC;QAAOxF,OAAO;QAAWD,QAAQ;IAAK;IACrDiJ,UAAU;QAAE9F,IAAIqC;QAAOvF,OAAO;QAAYD,QAAQ;IAAK;IACvDkJ,aAAa;QAAE/F,IAAIsC;QAAOxF,OAAO;QAAeD,QAAQ;IAAK;IAC7DmJ,UAAU;QAAEhG,IAAIqC;QAAOvF,OAAO;QAAYD,QAAQ;IAAK;IACvDoJ,gBAAgB;QAAEjG,IAAIqC;QAAOvF,OAAO;QAAkBD,QAAQ;IAAK;IACnEqJ,WAAW;QAAElG,IAAIuC;QAAYzF,OAAO;QAAWD,QAAQ;IAAU;IACjEsJ,YAAY;QAAEnG,IAAIuC;QAAYzF,OAAO;QAAYD,QAAQ;IAAU;AACrE;AAEA,6EAA6E,GAC7E,MAAMuJ,gBAAgB,IAAIvH,IAAa;IACrC;IACA;IACA;IACA;IACA;IACA;CACD;AAED,MAAMwH,YAAY,CAACC,MACjBC,OAAOC,SAAS,CAACC,cAAc,CAACC,IAAI,CAAChB,aAAaY;AAEpD,MAAMK,YAAY,CAACvK,OAAewK,YAChCxK,MACGgE,KAAK,CAACwG,WACN/G,GAAG,CAAC,CAACgH,OAASA,KAAKC,IAAI,IACvBC,MAAM,CAACC;AAEZ;;;;;CAKC,GACD,SAASC,gBAAgB3L,GAAW;IAClC,MAAMc,QAAQd,IAAIwL,IAAI;IACtB,MAAMI,QACJ,mFAAmFC,IAAI,CACrF/K;IAEJ,IAAI,CAAC8K,OAAO,OAAO9K;IACnB,MAAM,GAAGgL,MAAMC,MAAMC,UAAUC,KAAK,GAAGL;IACvC,OAAO,GAAGE,KAAK,CAAC,EAAEC,OAAOC,WAAW,CAAC,CAAC,EAAEA,SAAStK,KAAK,CAAC,GAAG,IAAI,GAAG,KAAKuK,eAAAA,OAAQ,IAAI;AACpF;AAEA,SAASC,SAASxJ,IAAY;IAC5B,MAAM6C,OAAOF,SAAS3C;IACtB,IAAI,CAAC6C,QAAQA,KAAKb,EAAE,KAAKqC,SAASxB,KAAK/D,KAAK,KAAK,kBAAkB,OAAO,EAAE;IAC5E,MAAMmF,MAA2B,EAAE;IACnC,MAAMwF,WAAqB,EAAE;IAC7B,MAAM3B,WAAqB,EAAE;IAC7B,MAAMlH,OAAO,IAAIC;IACjB,KAAK,MAAM2G,SAAS3E,KAAKG,QAAQ,CAAE;QACjC,MAAMsF,MAAM,AAACC,OAAOmB,IAAI,CAAChC,aAA2BlE,IAAI,CACtD,CAACmG,YACCjC,WAAW,CAACiC,UAAU,CAAC3H,EAAE,KAAKwF,MAAMxF,EAAE,IACtC0F,WAAW,CAACiC,UAAU,CAAC7K,KAAK,KAAK0I,MAAM1I,KAAK;QAEhD,IAAI,CAACwJ,KAAK;QACV,MAAMlK,QAAQgF,eAAeoE,OAAOsB,IAAI;QACxC,IAAI,CAAC1K,OAAO;QACZ,sEAAsE;QACtE,IAAIkK,QAAQ,WAAWmB,SAASpI,IAAI,IAAIsH,UAAUvK,OAAO;aACpD,IAAIkK,QAAQ,YAAYR,SAASzG,IAAI,IAAIsH,UAAUvK,OAAO;aAC1D,IAAI,CAACwC,KAAKM,GAAG,CAACoH,MAAM;YACvB1H,KAAKO,GAAG,CAACmH;YACTrE,IAAI5C,IAAI,CAAC;gBACPiH;gBACAlK,OACEkK,QAAQ,eAAeA,QAAQ,eAC3BW,gBAAgB7K,SAChBA;gBACNc,QAAQ;YACV;QACF;IACF;IACA,IAAIuK,SAAS1K,MAAM,EACjBkF,IAAI5C,IAAI,CAAC;QAAEiH,KAAK;QAAWlK,OAAOqL;QAAUvK,QAAQ;IAAQ;IAC9D,IAAI4I,SAAS/I,MAAM,EACjBkF,IAAI5C,IAAI,CAAC;QAAEiH,KAAK;QAAYlK,OAAO0J;QAAU5I,QAAQ;IAAQ;IAC/D,OAAO+E;AACT;AAEA,SAAS2F,aAAa5J,IAAY;IAChC,MAAM6C,OAAOF,SAAS3C;IACtB,IACE,CAAC6C,QACD,CAACA,KAAKb,EAAE,IACR,CAAC0C,YAAYxD,GAAG,CAAC2B,KAAKb,EAAE,KACxBa,KAAK/D,KAAK,KAAK,cAEf,OAAO,EAAE;IACX,MAAMV,QAAQ,CAACU;QACb,MAAM0I,QAAQ3E,KAAKG,QAAQ,CAACQ,IAAI,CAC9B,CAACT,UAAYA,QAAQjE,KAAK,KAAKA,SAASiE,QAAQf,EAAE,KAAKa,KAAKb,EAAE;QAEhE,OAAOwF,QAAQpE,eAAeoE,OAAOsB,IAAI,KAAK;IAChD;IACA,MAAM7E,MAA2B,EAAE;IACnC,MAAM4F,cAAczL,MAAM;IAC1B,IAAIyL,aACF5F,IAAI5C,IAAI,CAAC;QAAEiH,KAAK;QAAYlK,OAAOyL;QAAa3K,QAAQ;IAAQ;IAClE,MAAM4K,UAAU1L,MAAM;IACtB,IAAI0L,SAAS7F,IAAI5C,IAAI,CAAC;QAAEiH,KAAK;QAAWlK,OAAO0L;QAAS5K,QAAQ;IAAQ;IACxE,mEAAmE;IACnE,MAAM6K,QAAQ;QAAC3L,MAAM;QAAUA,MAAM;KAAU,CAACoF,IAAI,CAAC,CAACqF,OACpD,QAAQmB,IAAI,CAACnB;IAEf,IAAIkB,OAAO9F,IAAI5C,IAAI,CAAC;QAAEiH,KAAK;QAAalK,OAAO2L;QAAO7K,QAAQ;IAAQ;IACtE,OAAO+E;AACT;AAEA,yEAAyE,GACzE,MAAMgG,UAAU,IAAIpJ,IAAI;IAAC;IAAU;CAAQ;AAC3C,MAAMqJ,oBAAoB,IAAIrJ,IAAI;IAAC;CAAO;AAC1C,MAAMsJ,YAAY,IAAItJ,IAAI;IACxB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD;AACD,MAAMuJ,UAAU,IAAIvJ,IAAI;IAAC;IAAY;CAAO;AAE5C,yDAAyD,GACzD,MAAMwJ,eAAe,CAACC;;QACpB/G;oBAAAA,gBAAAA,aAAa+G,UAAU,4BAAvB/G,cAAgCnF,KAAK,mBAAI;;AAE3C,kEAAkE,GAClE,MAAMmM,gBAAgB,CAACD,WACrBA,SAAStH,QAAQ,CAACQ,IAAI,CAAC,CAACgE,QAAUA,MAAMxF,EAAE,KAAK,QAAQ4C,MAAM1D,GAAG,CAACsG,MAAMxF,EAAE;AAE3E,SAASwI,iBAAiB3H,IAAgB;IACxC,OAAOA,KAAKG,QAAQ,CAAC+F,MAAM,CACzB,CAACvB,QAAUA,MAAM1I,KAAK,KAAK,cAAc0I,MAAMxF,EAAE,KAAKa,KAAKb,EAAE;AAEjE;AAEA,SAASyI,WAAWzK,IAAY;IAC9B,MAAM6C,OAAOF,SAAS3C;IACtB,IACE,CAAC6C,QACD,CAACA,KAAKb,EAAE,IACR,CAAC2C,UAAUzD,GAAG,CAAC2B,KAAKb,EAAE,KACtBa,KAAK/D,KAAK,KAAK,cAEf,OAAO,EAAE;IACX,MAAMmF,MAA2B,EAAE;IACnC,MAAMrD,OAAO,IAAIC;IACjB,KAAK,MAAMyJ,YAAYE,iBAAiB3H,MAAO;QAC7C,MAAMjF,OAAOyM,aAAaC;QAC1B,MAAMI,eAAeH,cAAcD;QACnC,IAAI,CAAC1M,QAAQ,CAAC8M,gBAAgB9J,KAAKM,GAAG,CAACtD,OAAO;QAC9C,MAAM0H,OAAOoF,aAAa5L,KAAK;QAC/B,MAAMxB,MAAM8F,eAAesH;QAC3B,IAAItM;QACJ,IAAI6L,QAAQ/I,GAAG,CAACoE,SAAS4E,kBAAkBhJ,GAAG,CAACoE,OAAOlH,QAAQd;aACzD,IAAI6M,UAAUjJ,GAAG,CAACoE,OAAOlH,QAAQd,IAAIwL,IAAI;aACzC,IAAIxD,SAAS,QAAQ;YACxB,MAAMqF,OAAOrN,IAAIwL,IAAI,GAAGtD,WAAW;YACnCpH,QAAQuM,SAAS,MAAM,SAASA,SAAS,MAAM,UAAUA;QAC3D,OAAO,IAAIP,QAAQlJ,GAAG,CAACoE,OAAOlH,QAAQ6K,gBAAgB3L;aAEjD;QACL,IAAI,CAACc,MAAM0K,IAAI,IAAI;QACnBlI,KAAKO,GAAG,CAACvD;QACTqG,IAAI5C,IAAI,CAAC;YACPiH,KAAKnM,iBAAiB,SAASyB;YAC/BQ;YACAc,QAAQ;YACR0L,OAAOhN;WACHqM,QAAQ/I,GAAG,CAACoE,QAAQ,CAAC,IAAI;YAAEuF,UAAU;QAAM;IAEnD;IACA,OAAO5G;AACT;AAEA;;;;;;;CAOC,GACD,OAAO,SAAS6G,UACdvE,KAAiB;IAEjB,MAAMR,UAAUzJ,QAAQiK;IACxB,IAAI,CAACR,WAAW,CAACD,SAASC,SAAShB,qBAAqB,OAAO;IAC/D,MAAM,EAAEpE,KAAK,EAAE,GAAG2G,cAAcvB;IAChC,MAAMgF,aAAkC,EAAE;IAC1C,MAAM/D,OAAO,CAACS;QACZ,MAAM7J,OAAO+C,KAAK,CAAC8G,KAAK;QACxB,OAAO7J,SAASsE,YACZ,OACAmF,aAAatB,SAASD,SAASC,SAASnI;IAC9C;IACA,MAAMoN,OAAOhE,KAAK;IAClB,IAAIgE,SAAS,MAAMD,WAAW1J,IAAI,IAAImI,SAASwB;IAC/C,MAAMC,WAAWjE,KAAK;IACtB,IAAIiE,aAAa,MAAMF,WAAW1J,IAAI,IAAIuI,aAAaqB;IACvD,MAAMC,SAASlE,KAAK;IACpB,IAAIkE,WAAW,MAAMH,WAAW1J,IAAI,IAAIoJ,WAAWS;IACnD,OAAO;QAAEH;IAAW;AACtB;AAEA,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,oEAAoE,GACpE,MAAMI,YAAY,CAACC,MAAcA,IAAIC,WAAW,GAAG7N,OAAO,CAAC,aAAa;AAExE,SAAS8N,UAAUhD,GAAW,EAAElK,KAAwB;IACtD,IAAI,CAACmN,MAAMC,OAAO,CAACpN,QAAQ,OAAOA,MAAM0K,IAAI;IAC5C,MAAM2C,QAAQrN,MAAMyD,GAAG,CAAC,CAACgH,OAASA,KAAKC,IAAI,IAAIC,MAAM,CAACC;IACtD,uEAAuE;IACvE,OAAOyC,MAAMnI,IAAI,CAACgF,QAAQ,YAAY,OAAO;AAC/C;AAEA,SAASoD,UAAU1L,IAAY;IAC7B,MAAM6C,OAAOF,SAAS3C;IACtB,IAAI,CAAC6C,MAAM;QACT,MAAM,IAAIpG,mBACR;IAEJ;IACA,OAAOoG;AACT;AAEA;;;;CAIC,GACD,SAAS8I,QACPC,KAAkB,EAClB5J,EAAU,EACVlD,KAAa,EACb+M,YAAoB,EACpBlK,YAAY,KAAK;IAEjB,MAAM9C,SAAS4E,UAAUmI,OAAO5J;IAChC,IAAInD,WAAWqD,aAAa,CAAEP,CAAAA,aAAa9C,WAAW,EAAC,GAAI;QACzD,OAAO;YAAEjB,MAAMiB,SAAS,GAAGA,OAAO,CAAC,EAAEC,OAAO,GAAGA;YAAOgN,SAAS;QAAG;IACpE;IACA,OAAO;QACLlO,MAAM,GAAGiO,aAAa,CAAC,EAAE/M,OAAO;QAChCgN,SAAS,CAAC,OAAO,EAAED,aAAa,EAAE,EAAExN,mBAAmB2D,IAAI,CAAC,CAAC;IAC/D;AACF;AAEA,6EAA6E,GAC7E,SAAS+J,eACP7M,MAAc,EACd6D,OAAmB,EACnBiJ,OAAe;IAEf,IAAI,CAACjJ,QAAQjC,WAAW,EAAE;QACxB,OAAO;YAAEQ,OAAOyB,QAAQL,OAAO;YAAEvC,KAAK4C,QAAQG,UAAU;YAAElD,MAAMgM;QAAQ;IAC1E;IACA,MAAMC,UAAU/M,OACbF,KAAK,CAAC+D,QAAQzB,KAAK,EAAEyB,QAAQL,OAAO,EACpClF,OAAO,CAAC,WAAW;IACtB,OAAO;QACL8D,OAAOyB,QAAQzB,KAAK;QACpBnB,KAAK4C,QAAQ5C,GAAG;QAChBH,MAAM,GAAGiM,UAAUD,QAAQ,EAAE,EAAEjJ,QAAQnF,IAAI,CAAC,CAAC,CAAC;IAChD;AACF;AAEA,iDAAiD,GACjD,SAASsO,SAAShN,MAAc,EAAE2D,IAAgB,EAAEsJ,MAAc;IAChE,IAAI,CAACtJ,KAAK/B,WAAW,EAAE;QACrB,OAAO;YAAEQ,OAAOuB,KAAKK,UAAU;YAAE/C,KAAK0C,KAAKK,UAAU;YAAElD,MAAMmM;QAAO;IACtE;IACA,MAAMF,UAAU/M,OAAOF,KAAK,CAAC6D,KAAKvB,KAAK,EAAEuB,KAAKH,OAAO,EAAElF,OAAO,CAAC,WAAW;IAC1E,OAAO;QACL8D,OAAOuB,KAAKvB,KAAK;QACjBnB,KAAK0C,KAAK1C,GAAG;QACbH,MAAM,GAAGiM,UAAUE,OAAO,EAAE,EAAEtJ,KAAKjF,IAAI,CAAC,CAAC,CAAC;IAC5C;AACF;AAEA,SAASwO,SACPlN,MAAc,EACdmN,MAAmC,EACnCjB,GAAS;IAET,MAAMvI,OAAO6I,UAAUxM;IACvB,IAAI2D,KAAKb,EAAE,KAAKqC,SAASxB,KAAK/D,KAAK,KAAK,kBAAkB;QACxD,MAAM,IAAIrC,mBACR;IAEJ;IACA,MAAMmH,QAAoB,EAAE;IAC5B,MAAM0I,WAAqB,EAAE;IAC7B,MAAMC,MAAM,IAAI/M,IAAI6M;IACpBE,IAAIzK,GAAG,CAAC,cAAcqJ,UAAUC;IAChC,KAAK,MAAM,CAAC9C,KAAKlK,MAAM,IAAImO,IAAK;QAC9B,MAAMC,QAAQ9E,WAAW,CAACY,IAAI;QAC9B,MAAMmE,QAAQ5J,KAAKG,QAAQ,CAAC+F,MAAM,CAChC,CAACvB,QAAUA,MAAMxF,EAAE,KAAKwK,MAAMxK,EAAE,IAAIwF,MAAM1I,KAAK,KAAK0N,MAAM1N,KAAK;QAEjE,MAAM,CAAC4N,OAAO,GAAGC,KAAK,GAAGF;QACzB,IAAIrO,UAAU,MAAM;YAClB,KAAK,MAAM2E,WAAW0J,MAAO;gBAC3B7I,MAAMvC,IAAI,CAAC;oBAAEC,OAAOyB,QAAQzB,KAAK;oBAAEnB,KAAK4C,QAAQ5C,GAAG;oBAAEH,MAAM;gBAAG;YAChE;YACA;QACF;QACA,MAAMgM,UAAU7N,cAAcC;QAC9B,IAAIsO,OAAO;YACT9I,MAAMvC,IAAI,CAAC0K,eAAe7M,QAAQwN,OAAOV;YACzC,mEAAmE;YACnE,KAAK,MAAMjJ,WAAW4J,KAAM;gBAC1B/I,MAAMvC,IAAI,CAAC;oBAAEC,OAAOyB,QAAQzB,KAAK;oBAAEnB,KAAK4C,QAAQ5C,GAAG;oBAAEH,MAAM;gBAAG;YAChE;YACA;QACF;QACA,MAAM,EAAEpC,IAAI,EAAEkO,OAAO,EAAE,GAAGH,QAAQ9I,MAAM2J,MAAMxK,EAAE,EAAEwK,MAAM1N,KAAK,EAAE0N,MAAM3N,MAAM;QAC3E,IAAIsD,aAAa2J;QACjB,IAAIxD,QAAQ,cAAc;YACxB,oEAAoE;YACpE,MAAMsE,MAAMjB,QAAQ9I,MAAM4B,QAAQ,QAAQ,OAAO;YACjD,MAAMoI,gBAAgBjP,KAAKL,QAAQ,CAAC,OAChCK,KAAKoB,KAAK,CAAC,GAAGpB,KAAKgB,OAAO,CAAC,QAC3B;YACJuD,cAAc,GAAGyK,IAAId,OAAO,CAAC,CAAC,EAAEc,IAAIhP,IAAI,CAAC,EAAE,EAAEiP,gBAAgB,GAAGA,cAAc,CAAC,CAAC,GAAG,GAAG,OAAO,CAAC;QAChG;QACAP,SAASjL,IAAI,CAAC,CAAC,CAAC,EAAEzD,OAAOuE,WAAW,CAAC,EAAE6J,QAAQ,EAAE,EAAEpO,KAAK,CAAC,CAAC;IAC5D;IACA,IAAI0O,SAASvN,MAAM,EAAE6E,MAAMvC,IAAI,CAAC6K,SAAShN,QAAQ2D,MAAMyJ,SAAShJ,IAAI,CAAC;IACrE,OAAOK,WAAWzE,QAAQ0E;AAC5B;AAEA,SAASkJ,WACP5N,MAAc,EACdmN,MAAkC;IAElC,MAAMxJ,OAAO6I,UAAUxM;IACvB,IAAI,CAAC2D,KAAKb,EAAE,IAAI,CAAC2C,UAAUzD,GAAG,CAAC2B,KAAKb,EAAE,KAAKa,KAAK/D,KAAK,KAAK,cAAc;QACtE,MAAM,IAAIrC,mBACR;IAEJ;IACA,MAAMsQ,aAAavC,iBAAiB3H;IACpC,MAAMe,QAAoB,EAAE;IAC5B,MAAMoJ,UAAU,IAAInM;IACpB,KAAK,MAAM,CAACjD,MAAMQ,MAAM,IAAIiO,OAAQ;QAClC,MAAM/B,WAAWyC,WAAWvJ,IAAI,CAC9B,CAACT,UAAYsH,aAAatH,aAAanF;QAEzC,IAAI,CAAC0M,UAAU;YACb,MAAM,IAAI7N,mBACR,CAAC,CAAC,EAAEmB,KAAK,wCAAwC,CAAC;QAEtD;QACA,IAAIQ,UAAU,MAAM;YAClBwF,MAAMvC,IAAI,CAAC;gBAAEC,OAAOgJ,SAAShJ,KAAK;gBAAEnB,KAAKmK,SAASnK,GAAG;gBAAEH,MAAM;YAAG;YAChEgN,QAAQ7L,GAAG,CAACmJ;YACZ;QACF;QACA,MAAMI,eAAeH,cAAcD;QACnC,IAAI,CAACI,gBAAgB,CAACT,QAAQ/I,GAAG,CAACwJ,aAAa5L,KAAK,GAAG;YACrD,MAAM,IAAIrC,mBACR,CAAC,CAAC,EAAEmB,KAAK,sDAAsD,CAAC;QAEpE;QACAgG,MAAMvC,IAAI,CAAC0K,eAAe7M,QAAQwL,cAAcvM,cAAcC;IAChE;IAEA,+DAA+D;IAC/D,yEAAyE;IACzE,6DAA6D;IAC7D,MAAM6O,YAAYF,WAAWhE,MAAM,CAAC,CAACuB,WAAa,CAAC0C,QAAQ9L,GAAG,CAACoJ;IAC/D,MAAM4C,QAAQ,CAAC5C;;YACD/G;QAAZ,MAAMjG,eAAMiG,gBAAAA,aAAa+G,UAAU,2BAAvB/G,cAA+BnF,KAAK,CAAC0K,IAAI,qBAAM;QAC3D,OAAO,QAAQkB,IAAI,CAAC1M,OAAOkB,OAAOlB,OAAO6P;IAC3C;IACA,IAAIC,OAAOC,KAAKC,GAAG,CAAC,MAAML,UAAUpL,GAAG,CAACqL,OAAOnE,MAAM,CAAC,CAACwE,MAAQA,OAAO;IACtE,MAAMC,OAAO,IAAI3M;IACjB,KAAK,MAAMyJ,YAAY2C,UAAW;QAChC,MAAMM,MAAML,MAAM5C;QAClB,IAAIiD,OAAO,KAAK,CAACC,KAAKtM,GAAG,CAACqM,MAAM;YAC9BC,KAAKrM,GAAG,CAACoM;YACT;QACF;QACAH,QAAQ;QACR,MAAMzL,YAAY4B,aAAa+G,UAAU;QACzC,IAAI3I,WAAW;YACbiC,MAAMvC,IAAI,CAAC;gBACTC,OAAOK,UAAUY,UAAU;gBAC3BpC,KAAKwB,UAAUP,QAAQ;gBACvBpB,MAAMlC,OAAOsP;YACf;QACF,OAAO;YACL,MAAM5L,KAAK8I,SAAShJ,KAAK,GAAG,IAAIgJ,SAAS1M,IAAI,CAACmB,MAAM;YACpD6E,MAAMvC,IAAI,CAAC;gBAAEC,OAAOE;gBAAIrB,KAAKqB;gBAAIxB,MAAM,CAAC,MAAM,EAAEoN,KAAK,CAAC,CAAC;YAAC;QAC1D;IACF;IACA,OAAOzJ,WAAWzE,QAAQ0E;AAC5B;AAEA,gFAAgF,GAChF,SAAS6J,iBAAiBvO,MAAc,EAAEwO,QAAgB;IACxD,MAAM7K,OAAO6I,UAAUxM;IACvB,IAAI2D,KAAKb,EAAE,KAAK8C,oBAAoBjC,KAAK/D,KAAK,KAAK,SAAS;QAC1D,MAAM,IAAIrC,mBAAmB;IAC/B;IACA,MAAM0J,SAAS,CAAC,CAAC,EAAEuH,UAAU,CAAClI,WAAW;IACzC,MAAMtE,MAAM2B,KAAKG,QAAQ,CAAC2K,IAAI,CAC5B,CAACnG;YAECjE;eADAiE,MAAM1I,KAAK,KAAK,cAChByE,EAAAA,gBAAAA,aAAaiE,OAAO,gCAApBjE,cAAiCnF,KAAK,CAACoH,WAAW,QAAOW;;IAE7D,IAAIjF,KAAK,OAAOhC;IAChB,MAAMtB,OAAOiF,KAAKhE,MAAM,GAAG,GAAGgE,KAAKhE,MAAM,CAAC,SAAS,CAAC,GAAG;IACvD,OAAO8E,WAAWzE,QAAQ;QACxBgN,SACEhN,QACA2D,MACA,CAAC,CAAC,EAAEjF,KAAK,YAAY,EAAES,mBAAmBqP,UAAU,eAAe,EAAExI,kBAAkB,GAAG,CAAC;KAE9F;AACH;AAEA,mEAAmE,GACnE,SAAS0I,kBAAkB1O,MAAc,EAAEwO,QAAgB;IACzD,MAAM7K,OAAO6I,UAAUxM;IACvB,IAAI2D,KAAKb,EAAE,KAAK6C,oBAAoBhC,KAAK/D,KAAK,KAAK,iBAAiB;QAClE,MAAM,IAAIrC,mBACR;IAEJ;IACA,MAAMoR,MAAM,IAAIhN,IACdgC,KAAKG,QAAQ,CAACnB,GAAG,CAAC,CAAC2F;YAAUjE;gBAAAA,gBAAAA,aAAaiE,OAAO,0BAApBjE,cAA2BnF,KAAK;;IAE/D,IAAI0P,QAAQjL,KAAKG,QAAQ,CAACjE,MAAM,GAAG;IACnC,MAAO8O,IAAI3M,GAAG,CAAC,CAAC,GAAG,EAAE4M,OAAO,EAAGA;IAC/B,MAAMlQ,OAAOiF,KAAKhE,MAAM,GAAG,GAAGgE,KAAKhE,MAAM,CAAC,aAAa,CAAC,GAAG;IAC3D,OAAO8E,WAAWzE,QAAQ;QACxBgN,SACEhN,QACA2D,MACA,CAAC,CAAC,EAAEjF,KAAK,QAAQ,EAAEkQ,MAAM,QAAQ,EAAE7I,kBAAkB,UAAU,EAAE5G,mBAAmBqP,UAAU,GAAG,CAAC;KAErG;AACH;AAEA,wEAAwE,GACxE,MAAMK,aACJ,gEACA,CAAC,6BAA6B,EAAE1J,MAAM,YAAY,EAAEC,MAAM,iBAAiB,EAAEC,WAAW,kBAAkB,EAAEC,YAAY,aAAa,EAAEC,OAAO,sBAAsB,CAAC;AAEvK,SAASuJ,aAAajI,OAAmB,EAAEM,KAAe;IACxD,IAAIA,MAAM4H,SAAS,EAAE;QACnB,MAAM,IAAIxR,mBACR;IAEJ;IACA,MAAM8J,QAAQhK,aAAawJ,SAASM,OAAOjB;IAC3C,IAAI,CAACmB,OAAO;QACV,MAAM,IAAI9J,mBACR;IAEJ;IACA,OAAOiK,cAAcH;AACvB;AAEA;;;;;;;;;;;CAWC,GACD,OAAO,SAAS2H,WACd3H,KAAiB,EACjB4H,KAAoB,EACpB/O,OAAsB;IAEtB,MAAM2G,UAAUzJ,QAAQiK;IACxB,IAAI,CAACR,WAAW,CAACD,SAASC,SAAShB,qBAAqB;QACtD,MAAM,IAAItI,mBAAmB;IAC/B;IAEA,MAAMuO,OAAO,IAAIxL;IACjB,MAAM0L,SAAS,IAAI1L;IACnB,KAAK,MAAM,CAAC8I,KAAKhL,IAAI,IAAIiL,OAAOnC,OAAO,CAAC+H,OAAQ;QAC9C,MAAM/P,QAAQd,QAAQ,OAAO,OAAOgO,UAAUhD,KAAKhL,QAAQ;QAC3D,IAAI+K,UAAUC,QAAQF,cAAclH,GAAG,CAACoH,MAAM;YAC5C0C,KAAKlJ,GAAG,CAACwG,KAAKlK;YACd;QACF;QACA,MAAMgQ,QAAQhS,sBAAsBkM;QACpC,IAAI8F,CAAAA,yBAAAA,MAAOC,SAAS,MAAK,SAAS;YAChCnD,OAAOpJ,GAAG,CAACsM,MAAMzN,KAAK,CAAC2C,IAAI,CAAC,MAAMlF;YAClC;QACF;QACA,MAAM,IAAI3B,mBACR,GAAGP,mBAAmBoM,KAAK,SAAS,2CAA2C,CAAC;IAEpF;IAEA,MAAMgG,SAAShH,cAAcvB;IAC7B,MAAMwI,UAAU,IAAI/O;IACpB,MAAMgP,SAAS,CAAC5Q,MAAcoJ;QAC5B,IAAI,CAACrE,SAASqE,KAAKhH,IAAI,GAAG;YACxB,MAAM,IAAIvD,mBACR;QAEJ;QACA8R,QAAQzM,GAAG,CAAClE,MAAMmJ,WAAWC;IAC/B;IAEA,IAAIkE,OAAOuD,IAAI,EAAE;QACf,MAAM7Q,OAAO0Q,OAAO3N,KAAK,CAACuK,MAAM;QAChC,MAAM7E,QAAQzI,SAASsE,YAAYA,YAAY4D,SAASC,SAASnI;QACjE,IAAI,CAACyI,OAAO;YACV,MAAM,CAACqG,MAAM,GAAGxB,OAAOxB,IAAI;YAC3B,MAAM,IAAIjN,mBACR,CAAC,CAAC,EAAEiQ,MAAM,wCAAwC,CAAC;QAEvD;QACA,MAAM1F,OAAOgH,aAAajI,SAASM;QACnCmI,OAAOnI,MAAMzI,IAAI,EAAE,aAAKoJ;YAAMhH,MAAM8M,WAAW9F,KAAKhH,IAAI,EAAEkL;;IAC5D;IAEA,MAAMwD,WAAWJ,OAAO3N,KAAK,CAACqK,IAAI;IAClC,MAAM2D,YACJD,aAAaxM,YAAYA,YAAY4D,SAASC,SAAS2I;IACzD,IAAIC,WAAW;QACb,MAAM3H,OAAOgH,aAAajI,SAAS4I;QACnCH,OAAOG,UAAU/Q,IAAI,EAAE,aAClBoJ;YACHhH,MAAMoM,SAASpF,KAAKhH,IAAI,EAAEgL,MAAM5L,QAAQgM,GAAG;;IAE/C,OAAO;QACL,mEAAmE;QACnE,kEAAkE;QAClE,4BAA4B;QAC5B,IAAIxN,OAAO8Q;QACX,IAAI9Q,SAASsE,WAAW;YACtBtE,OAAOuH;YACP,IAAK,IAAI2I,QAAQ,GAAGhI,SAASC,SAASnI,OAAOkQ,QAAS;gBACpDlQ,OAAO,CAAC,aAAa,EAAEkQ,MAAM,IAAI,CAAC;YACpC;YACA,IAAI,CAACQ,OAAO/G,aAAa,EAAE;gBACzB,MAAM,IAAI9K,mBACR;YAEJ;YACA,MAAMmS,OAAOZ,aAAajI,SAASuI,OAAO/G,aAAa;YACvDiH,OAAOF,OAAO/G,aAAa,CAAC3J,IAAI,EAAE,aAC7BgR;gBACH5O,MAAM4N,kBAAkBgB,KAAK5O,IAAI,EAAEpC;;QAEvC;QACA,MAAMiR,QAAQ/I,SAASC,SAAShB;QAChC,IAAI,CAAC8J,OACH,MAAM,IAAIpS,mBAAmB;QAC/B,MAAMqS,YAAYd,aAAajI,SAAS8I;QACxCL,OAAOK,MAAMjR,IAAI,EAAE,aACdkR;YACH9O,MAAMyN,iBAAiBqB,UAAU9O,IAAI,EAAEpC;;QAEzC4Q,OAAO5Q,MAAM;YAAEoC,MAAMoM,SAAS2B,YAAY/C,MAAM5L,QAAQgM,GAAG;YAAGzE,KAAK;QAAM;IAC3E;IAEA,OAAOnK,WAAWuJ,SAASwI,SAAS;QAAEnD,KAAKhM,QAAQgM,GAAG;IAAC;AACzD"}
@@ -0,0 +1,223 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ export interface PdfNull {
18
+ kind: 'null';
19
+ }
20
+ export interface PdfBoolean {
21
+ kind: 'boolean';
22
+ value: boolean;
23
+ }
24
+ export interface PdfNumber {
25
+ kind: 'number';
26
+ value: number;
27
+ /** As written, so `0.50` reserializes as `0.50` rather than `0.5`. */
28
+ text: string;
29
+ }
30
+ export interface PdfString {
31
+ kind: 'string';
32
+ /** The string's bytes after escape processing (§7.3.4). */
33
+ bytes: Uint8Array;
34
+ /** Written as `<…>` rather than `(…)`; kept so reserializing is faithful. */
35
+ hex: boolean;
36
+ }
37
+ export interface PdfName {
38
+ kind: 'name';
39
+ /**
40
+ * The name's BYTES after `#xx` decoding (§7.3.5), one char per byte.
41
+ * {@link pdfNameText} turns it into display text.
42
+ */
43
+ name: string;
44
+ }
45
+ export interface PdfArray {
46
+ kind: 'array';
47
+ items: PdfObject[];
48
+ }
49
+ export interface PdfDict {
50
+ kind: 'dict';
51
+ /** Keyed by name bytes like {@link PdfName.name}; insertion-ordered. */
52
+ entries: Map<string, PdfObject>;
53
+ }
54
+ export interface PdfRef {
55
+ kind: 'ref';
56
+ num: number;
57
+ gen: number;
58
+ }
59
+ export interface PdfStream {
60
+ kind: 'stream';
61
+ dict: PdfDict;
62
+ /** The ENCODED data, a view into the buffer it was parsed from. */
63
+ data: Uint8Array;
64
+ }
65
+ /** A PDF object as parsed (ISO 32000-2 §7.3). */
66
+ export type PdfObject = PdfNull | PdfBoolean | PdfNumber | PdfString | PdfName | PdfArray | PdfDict | PdfRef | PdfStream;
67
+ export declare const PDF_NULL: PdfNull;
68
+ /** Deepest array/dictionary nesting the parser follows. */
69
+ export declare const PDF_MAX_DEPTH = 64;
70
+ /** Tokens one object may consume before the parser gives up on it. */
71
+ export declare const PDF_MAX_TOKENS = 2000000;
72
+ export declare function isPdfWhitespace(b: number): boolean;
73
+ /** Bytes as a binary string, one char per byte. */
74
+ export declare function latin1Text(bytes: Uint8Array): string;
75
+ /** A binary string (chars 0–255) as bytes. */
76
+ export declare function latin1Bytes(text: string): Uint8Array;
77
+ /** The first index of `needle` in `bytes[from, to)`, or -1. */
78
+ export declare function indexOfBytes(bytes: Uint8Array, needle: Uint8Array, from?: number, to?: number): number;
79
+ /** The last index of `needle` in `bytes` starting at or before `from`. */
80
+ export declare function lastIndexOfBytes(bytes: Uint8Array, needle: Uint8Array, from?: number): number;
81
+ export type PdfToken = {
82
+ type: 'eof';
83
+ } | {
84
+ type: 'number';
85
+ value: number;
86
+ text: string;
87
+ } | {
88
+ type: 'keyword';
89
+ text: string;
90
+ } | {
91
+ type: 'name';
92
+ name: string;
93
+ } | {
94
+ type: 'string';
95
+ bytes: Uint8Array;
96
+ hex: boolean;
97
+ } | {
98
+ type: 'punct';
99
+ text: '[' | ']' | '<<' | '>>' | '{' | '}';
100
+ };
101
+ /** The §7.2 tokenizer. `end` is exclusive; nothing is read past it. */
102
+ export declare class PdfLexer {
103
+ readonly bytes: Uint8Array;
104
+ pos: number;
105
+ readonly end: number;
106
+ constructor(bytes: Uint8Array, pos?: number, end?: number);
107
+ private at;
108
+ /** Skips white-space and `%` comments (§7.2.4). */
109
+ skipSpace(): void;
110
+ /** Whether `word` is the next token, as a whole keyword. */
111
+ peekKeyword(word: string): boolean;
112
+ next(): PdfToken;
113
+ /** §7.3.5: a name, with `#xx` escapes decoded to bytes. */
114
+ private name;
115
+ /**
116
+ * §7.3.4.2: a literal string. Balanced parentheses nest; `\` escapes
117
+ * `n r t b f ( ) \`, one to three octal digits, and an end-of-line (a
118
+ * line continuation, which contributes nothing). An unescaped CR, LF or
119
+ * CRLF reads as a single LF. An unterminated string ends at the buffer.
120
+ */
121
+ private literalString;
122
+ /**
123
+ * §7.3.4.3: a hexadecimal string. White-space is ignored, an odd final
124
+ * digit is followed by an implied 0, and any other stray byte is skipped
125
+ * rather than ending the string.
126
+ */
127
+ private hexString;
128
+ }
129
+ export interface PdfParseOptions {
130
+ /** Resolves an indirect stream `/Length` (§7.3.8.2) to a number. */
131
+ resolveLength?: (ref: PdfRef) => number | null;
132
+ }
133
+ export interface PdfIndirectObject {
134
+ num: number;
135
+ gen: number;
136
+ obj: PdfObject;
137
+ }
138
+ /**
139
+ * The §7.3 object parser over {@link PdfLexer}. Returns `null` for what it
140
+ * cannot read rather than throwing; see the module doc for the limits.
141
+ */
142
+ export declare class PdfParser {
143
+ readonly bytes: Uint8Array;
144
+ private readonly options;
145
+ readonly lexer: PdfLexer;
146
+ private budget;
147
+ private failed;
148
+ constructor(bytes: Uint8Array, pos?: number, options?: PdfParseOptions, end?: number);
149
+ get pos(): number;
150
+ /** One direct object at the current position. */
151
+ parseObject(): PdfObject | null;
152
+ /**
153
+ * `num gen obj … endobj` at the current position (§7.3.10). A dictionary
154
+ * followed by `stream` becomes a {@link PdfStream} (§7.3.8). `endobj` is
155
+ * not required: plenty of writers forget it, and nothing depends on it.
156
+ */
157
+ parseIndirectObject(): PdfIndirectObject | null;
158
+ private object;
159
+ private array;
160
+ private dict;
161
+ /**
162
+ * §7.3.8.1: the data starts after the EOL that ends the `stream` keyword
163
+ * (CRLF or LF; a lone CR is tolerated) and runs for `/Length` bytes. When
164
+ * `/Length` is missing, unresolvable or does not land on `endstream`, the
165
+ * data runs to the next `endstream` instead, less the EOL before it.
166
+ */
167
+ private streamBody;
168
+ private streamLength;
169
+ }
170
+ /** §7.3.5: regular characters 0x21–0x7E other than `#` are written as-is. */
171
+ export declare function serializePdfName(name: string): string;
172
+ /**
173
+ * A string as a literal (§7.3.4.2) or, when it was read as one, a hex
174
+ * string (§7.3.4.3). Literal bytes outside printable ASCII are written as
175
+ * three-digit octal escapes so the output is 7-bit clean and byte-exact.
176
+ */
177
+ export declare function serializePdfString(value: PdfString): string;
178
+ /**
179
+ * An object as PDF syntax, in a binary string (one char per byte). Streams
180
+ * cannot be nested inside another object (§7.3.8.1), so one met here is
181
+ * written as `null`; a top-level stream is laid out by its writer.
182
+ */
183
+ export declare function serializePdfObject(obj: PdfObject, depth?: number): string;
184
+ /**
185
+ * A text string's bytes as text (§7.9.2.2): UTF-16BE after a FE FF byte
186
+ * order mark, UTF-8 after EF BB BF (PDF 2.0), PDFDocEncoding otherwise.
187
+ * UTF-16LE after FF FE is not in the standard but is written by enough
188
+ * software that reading it as PDFDocEncoding ("ÿþ…") helps nobody.
189
+ * Language escapes (ESC lang ESC, §7.9.2.2.1) and trailing NULs are removed.
190
+ */
191
+ export declare function decodePdfTextString(bytes: Uint8Array): string;
192
+ /**
193
+ * Text as a text string: a literal when every char is printable ASCII (or
194
+ * tab, CR, LF, which escape cleanly and mean the same in PDFDocEncoding),
195
+ * otherwise UTF-16BE with a byte order mark, written as hex (§7.9.2.2).
196
+ */
197
+ export declare function encodePdfTextString(text: string): PdfString;
198
+ /**
199
+ * A name's bytes as display text: UTF-8 when they are valid UTF-8 (PDF 2.0
200
+ * §7.3.5 recommends it), Latin-1 otherwise.
201
+ */
202
+ export declare function pdfNameText(name: string): string;
203
+ /** Display text as name bytes (UTF-8), the inverse of {@link pdfNameText}. */
204
+ export declare function pdfNameFromText(text: string): string;
205
+ export type PdfResolver = (obj: PdfObject | undefined) => PdfObject | undefined;
206
+ /**
207
+ * zlib inflation capped at `maxOutputLength`. A strict pass first; a stream
208
+ * truncated or missing its Adler-32 (common, and harmless to the data) is
209
+ * retried with a sync flush, and one written without a zlib header as raw
210
+ * deflate. `null` when none of them produces anything.
211
+ */
212
+ export declare function inflatePdf(data: Uint8Array, maxOutputLength: number): Uint8Array | null;
213
+ /**
214
+ * §7.4.4.4: undo a TIFF (2) or PNG (10–15) predictor. PNG rows each carry
215
+ * their own filter-type byte, so the Predictor value past 10 is only a hint.
216
+ * `null` for parameters this cannot honor.
217
+ */
218
+ export declare function unpredict(data: Uint8Array, params: PdfDict | null): Uint8Array | null;
219
+ /**
220
+ * A stream's decoded data, or `null` when it uses a filter other than
221
+ * FlateDecode (§7.4.4) or does not decode within `maxOutputLength`.
222
+ */
223
+ export declare function decodePdfStream(stream: PdfStream, resolve: PdfResolver, maxOutputLength: number): Uint8Array | null;