@eigenpal/docx-editor-agents 0.0.28 → 0.0.30

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 (40) hide show
  1. package/dist/bridge.js +3 -1
  2. package/dist/bridge.js.map +1 -1
  3. package/dist/bridge.mjs +8 -0
  4. package/dist/bridge.mjs.map +1 -0
  5. package/dist/chunk-5D2V7VK3.js +976 -0
  6. package/dist/chunk-5D2V7VK3.js.map +1 -0
  7. package/dist/chunk-5E3CFYZ4.mjs +249 -0
  8. package/dist/chunk-5E3CFYZ4.mjs.map +1 -0
  9. package/dist/chunk-GACRQVPW.js +11680 -0
  10. package/dist/chunk-GACRQVPW.js.map +1 -0
  11. package/dist/chunk-OFUT6WUQ.mjs +969 -0
  12. package/dist/chunk-OFUT6WUQ.mjs.map +1 -0
  13. package/dist/chunk-Q2HHIVUL.js +266 -0
  14. package/dist/chunk-Q2HHIVUL.js.map +1 -0
  15. package/dist/chunk-R4MIGZEJ.mjs +11587 -0
  16. package/dist/chunk-R4MIGZEJ.mjs.map +1 -0
  17. package/dist/executor-6ZG2VUZS.mjs +3 -0
  18. package/dist/executor-6ZG2VUZS.mjs.map +1 -0
  19. package/dist/executor-ZRVQSXRT.js +16 -0
  20. package/dist/executor-ZRVQSXRT.js.map +1 -0
  21. package/dist/headless-O2RRWYCB.js +422 -0
  22. package/dist/headless-O2RRWYCB.js.map +1 -0
  23. package/dist/headless-UKRSG32U.mjs +5 -0
  24. package/dist/headless-UKRSG32U.mjs.map +1 -0
  25. package/dist/index.d.mts +2013 -0
  26. package/dist/index.d.ts +1776 -1
  27. package/dist/index.js +26 -19
  28. package/dist/index.js.map +1 -1
  29. package/dist/{index.cjs → index.mjs} +23 -26
  30. package/dist/index.mjs.map +1 -0
  31. package/dist/processTemplate-7M6KZ6GR.mjs +3 -0
  32. package/dist/processTemplate-7M6KZ6GR.mjs.map +1 -0
  33. package/dist/processTemplate-H4X2MH5R.js +54 -0
  34. package/dist/processTemplate-H4X2MH5R.js.map +1 -0
  35. package/package.json +11 -9
  36. package/dist/bridge.cjs +0 -10
  37. package/dist/bridge.cjs.map +0 -1
  38. package/dist/index.cjs.map +0 -1
  39. package/dist/index.d.cts +0 -238
  40. /package/dist/{bridge.d.cts → bridge.d.mts} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../core/src/docx/serializer/xmlUtils.ts","../../core/src/docx/serializer/runSerializer.ts","../../core/src/docx/serializer/paragraphSerializer.ts","../../core/src/docx/serializer/tableSerializer.ts","../../core/src/docx/serializer/documentSerializer.ts","../../core/src/docx/serializer/headerFooterSerializer.ts","../../core/src/docx/serializer/commentSerializer.ts","../../core/src/docx/xmlParser.ts","../../core/src/docx/relsParser.ts","../../core/src/docx/rezip.ts","../../core/src/docx/selectiveXmlPatch.ts","../../core/src/docx/selectiveSave.ts","../../core/src/utils/variableDetector.ts","../../core/src/docx/unzip.ts","../../core/src/docx/themeParser.ts","../../core/src/docx/styleParser.ts","../../core/src/docx/numberingParser.ts","../../core/src/docx/drawingUtils.ts","../../core/src/utils/units.ts","../../core/src/docx/textBoxParser.ts","../../core/src/docx/imageParser.ts","../../core/src/docx/runParser.ts","../../core/src/docx/hyperlinkParser.ts","../../core/src/docx/bookmarkParser.ts","../../core/src/docx/tableParser.ts","../../core/src/docx/headerFooterParser.ts","../../core/src/docx/footnoteParser.ts","../../core/src/docx/sectionParser.ts","../../core/src/docx/runConsolidator.ts","../../core/src/docx/paragraphParser.ts","../../core/src/docx/documentParser.ts","../../core/src/docx/commentParser.ts","../../core/src/utils/fontLoader.ts","../../core/src/utils/docxInput.ts","../../core/src/docx/parser.ts","../../core/src/agent/DocumentAgent.ts","../../core/src/agent/context.ts","../../core/src/agent/selectionContext.ts","../../core/src/agent/text-utils.ts","../../core/src/utils/createDocument.ts","../../core/src/utils/colorResolver.ts","../../core/src/core-plugins/types.ts","../../core/src/types/agentApi.ts","../../core/src/headless.ts"],"names":["serializeShading","serializeBorder","NAMESPACES","buildNamespaceDeclarations","serializeRunContent","serializeParagraph","xml2js","js2xml","JSZip","abstractNum","parseColorElement","wrap","parseParagraph","parseTable","parseColorValue","parseShadingProperties","parseRunProperties","getLocalName","parseBookmarkStart","parseBookmarkEnd","parseTableMeasurement","parsePropertyChangeInfo","parseBorderSpec","parseTableBorders","parseCellMargins","parseTableLook","parseTableProperties","parseTableRowProperties","parseTableCellProperties","parseNumberFormat","parseTabStops","parseParagraphProperties","parseTrackedChangeInfo","parseHyperlink","detectVariables","timeStage","document","processTemplate","executeCommands","executeCommand","hasTables","hasImages","hasHyperlinks","getParagraphText","buildSelectionContext","getTextBefore","getTextAfter","getFormattingAtPosition","countWords","getSuggestedActions","getRunText","getHyperlinkText","getTableWordCount","getTableCharacterCount","isPositionInHyperlink","isHeadingStyle","parseHeadingLevel","getDefaultSectionProperties","p","q"],"mappings":"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","file":"chunk-GACRQVPW.js","sourcesContent":["/**\n * Shared XML utility functions for serializers.\n */\n\nexport function escapeXml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n}\n","/**\n * Run Serializer - Serialize runs to OOXML XML\n *\n * Converts Run objects back to <w:r> XML format for DOCX files.\n * Handles all formatting properties and content types.\n *\n * OOXML Reference:\n * - Run: w:r\n * - Run properties: w:rPr\n * - Text content: w:t\n */\n\nimport type {\n Run,\n RunContent,\n TextContent,\n TabContent,\n BreakContent,\n SymbolContent,\n NoteReferenceContent,\n FieldCharContent,\n InstrTextContent,\n SoftHyphenContent,\n NoBreakHyphenContent,\n DrawingContent,\n ShapeContent,\n TextFormatting,\n ColorValue,\n ShadingProperties,\n Image,\n ShapeFill,\n ShapeOutline,\n ImagePosition,\n ImageWrap,\n Paragraph,\n RunPropertyChange,\n} from '../../types/document';\nimport { serializeParagraph } from './paragraphSerializer';\nimport { escapeXml } from './xmlUtils';\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\n/**\n * Auto-incrementing counter for generating unique image/shape IDs.\n * Used as a fallback when `image.id` or `shape.id` is undefined (e.g., pasted images).\n * Starts high (100000) to avoid collisions with IDs parsed from existing DOCX content.\n */\nlet nextAutoId = 100000;\n\n/**\n * Reset the auto-incrementing ID counter. Call before each serialization pass\n * to keep IDs deterministic across saves.\n */\nexport function resetAutoIdCounter(): void {\n nextAutoId = 100000;\n}\n\n/** Get a unique positive integer ID, using the provided value or generating one */\nfunction getUniqueId(id: string | number | undefined): string {\n if (id !== undefined && id !== null && id !== '' && id !== 0) {\n return String(id);\n }\n return String(nextAutoId++);\n}\n\n/** Valid OOXML highlight color names (ECMA-376 §17.18.40) */\nconst VALID_HIGHLIGHT_COLORS = new Set([\n 'black',\n 'blue',\n 'cyan',\n 'darkBlue',\n 'darkCyan',\n 'darkGray',\n 'darkGreen',\n 'darkMagenta',\n 'darkRed',\n 'darkYellow',\n 'green',\n 'lightGray',\n 'magenta',\n 'red',\n 'white',\n 'yellow',\n]);\n\n// ============================================================================\n// COLOR SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize a color element (w:color)\n */\nfunction serializeColorElement(color: ColorValue | undefined): string {\n if (!color) return '';\n\n const attrs: string[] = [];\n\n if (color.auto) {\n attrs.push('w:val=\"auto\"');\n } else if (color.rgb) {\n attrs.push(`w:val=\"${color.rgb}\"`);\n }\n\n if (color.themeColor) {\n attrs.push(`w:themeColor=\"${color.themeColor}\"`);\n }\n\n if (color.themeTint) {\n attrs.push(`w:themeTint=\"${color.themeTint}\"`);\n }\n\n if (color.themeShade) {\n attrs.push(`w:themeShade=\"${color.themeShade}\"`);\n }\n\n if (attrs.length === 0) return '';\n\n return `<w:color ${attrs.join(' ')}/>`;\n}\n\n// ============================================================================\n// SHADING SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize shading properties (w:shd)\n */\nfunction serializeShading(shading: ShadingProperties | undefined): string {\n if (!shading) return '';\n\n const attrs: string[] = [];\n\n // Pattern/val\n if (shading.pattern) {\n attrs.push(`w:val=\"${shading.pattern}\"`);\n } else {\n attrs.push('w:val=\"clear\"');\n }\n\n // Color (pattern color)\n if (shading.color?.rgb) {\n attrs.push(`w:color=\"${shading.color.rgb}\"`);\n } else if (shading.color?.auto) {\n attrs.push('w:color=\"auto\"');\n }\n\n // Fill (background color)\n if (shading.fill?.rgb) {\n attrs.push(`w:fill=\"${shading.fill.rgb}\"`);\n } else if (shading.fill?.auto) {\n attrs.push('w:fill=\"auto\"');\n }\n\n // Theme fill\n if (shading.fill?.themeColor) {\n attrs.push(`w:themeFill=\"${shading.fill.themeColor}\"`);\n }\n\n if (shading.fill?.themeTint) {\n attrs.push(`w:themeFillTint=\"${shading.fill.themeTint}\"`);\n }\n\n if (shading.fill?.themeShade) {\n attrs.push(`w:themeFillShade=\"${shading.fill.themeShade}\"`);\n }\n\n if (attrs.length === 0) return '';\n\n return `<w:shd ${attrs.join(' ')}/>`;\n}\n\n// ============================================================================\n// TEXT FORMATTING SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize text formatting properties to w:rPr XML\n */\nexport function serializeTextFormatting(formatting: TextFormatting | undefined): string {\n if (!formatting) return '';\n\n const parts: string[] = [];\n\n // Style reference (must be first)\n if (formatting.styleId) {\n parts.push(`<w:rStyle w:val=\"${escapeXml(formatting.styleId)}\"/>`);\n }\n\n // Font family (w:rFonts)\n if (formatting.fontFamily) {\n const fontAttrs: string[] = [];\n if (formatting.fontFamily.ascii) {\n fontAttrs.push(`w:ascii=\"${escapeXml(formatting.fontFamily.ascii)}\"`);\n }\n if (formatting.fontFamily.hAnsi) {\n fontAttrs.push(`w:hAnsi=\"${escapeXml(formatting.fontFamily.hAnsi)}\"`);\n }\n if (formatting.fontFamily.eastAsia) {\n fontAttrs.push(`w:eastAsia=\"${escapeXml(formatting.fontFamily.eastAsia)}\"`);\n }\n if (formatting.fontFamily.cs) {\n fontAttrs.push(`w:cs=\"${escapeXml(formatting.fontFamily.cs)}\"`);\n }\n if (formatting.fontFamily.asciiTheme) {\n fontAttrs.push(`w:asciiTheme=\"${formatting.fontFamily.asciiTheme}\"`);\n }\n if (formatting.fontFamily.hAnsiTheme) {\n fontAttrs.push(`w:hAnsiTheme=\"${formatting.fontFamily.hAnsiTheme}\"`);\n }\n if (formatting.fontFamily.eastAsiaTheme) {\n fontAttrs.push(`w:eastAsiaTheme=\"${formatting.fontFamily.eastAsiaTheme}\"`);\n }\n if (formatting.fontFamily.csTheme) {\n fontAttrs.push(`w:csTheme=\"${formatting.fontFamily.csTheme}\"`);\n }\n if (fontAttrs.length > 0) {\n parts.push(`<w:rFonts ${fontAttrs.join(' ')}/>`);\n }\n }\n\n // Bold\n if (formatting.bold === true) {\n parts.push('<w:b/>');\n } else if (formatting.bold === false) {\n parts.push('<w:b w:val=\"0\"/>');\n }\n\n if (formatting.boldCs === true) {\n parts.push('<w:bCs/>');\n } else if (formatting.boldCs === false) {\n parts.push('<w:bCs w:val=\"0\"/>');\n }\n\n // Italic\n if (formatting.italic === true) {\n parts.push('<w:i/>');\n } else if (formatting.italic === false) {\n parts.push('<w:i w:val=\"0\"/>');\n }\n\n if (formatting.italicCs === true) {\n parts.push('<w:iCs/>');\n } else if (formatting.italicCs === false) {\n parts.push('<w:iCs w:val=\"0\"/>');\n }\n\n // Caps\n if (formatting.allCaps) {\n parts.push('<w:caps/>');\n }\n\n if (formatting.smallCaps) {\n parts.push('<w:smallCaps/>');\n }\n\n // Strike\n if (formatting.strike) {\n parts.push('<w:strike/>');\n }\n\n if (formatting.doubleStrike) {\n parts.push('<w:dstrike/>');\n }\n\n // Outline\n if (formatting.outline) {\n parts.push('<w:outline/>');\n }\n\n // Shadow\n if (formatting.shadow) {\n parts.push('<w:shadow/>');\n }\n\n // Emboss\n if (formatting.emboss) {\n parts.push('<w:emboss/>');\n }\n\n // Imprint\n if (formatting.imprint) {\n parts.push('<w:imprint/>');\n }\n\n // Hidden\n if (formatting.hidden) {\n parts.push('<w:vanish/>');\n }\n\n // Color\n const colorXml = serializeColorElement(formatting.color);\n if (colorXml) {\n parts.push(colorXml);\n }\n\n // Spacing\n if (formatting.spacing !== undefined) {\n parts.push(`<w:spacing w:val=\"${formatting.spacing}\"/>`);\n }\n\n // Scale (w:w)\n if (formatting.scale !== undefined) {\n parts.push(`<w:w w:val=\"${formatting.scale}\"/>`);\n }\n\n // Kerning\n if (formatting.kerning !== undefined) {\n parts.push(`<w:kern w:val=\"${formatting.kerning}\"/>`);\n }\n\n // Position\n if (formatting.position !== undefined) {\n parts.push(`<w:position w:val=\"${formatting.position}\"/>`);\n }\n\n // Font size\n if (formatting.fontSize !== undefined) {\n parts.push(`<w:sz w:val=\"${formatting.fontSize}\"/>`);\n }\n\n if (formatting.fontSizeCs !== undefined) {\n parts.push(`<w:szCs w:val=\"${formatting.fontSizeCs}\"/>`);\n }\n\n // Highlight — emit valid OOXML named colors via w:highlight,\n // fall back to w:shd for custom hex colors\n if (formatting.highlight && formatting.highlight !== 'none') {\n if (VALID_HIGHLIGHT_COLORS.has(formatting.highlight)) {\n parts.push(`<w:highlight w:val=\"${formatting.highlight}\"/>`);\n } else if (!formatting.shading) {\n // Custom color not in OOXML predefined set — use w:shd as fallback.\n // Only emit if value looks like a valid hex color.\n const hex = formatting.highlight.replace(/^#/, '');\n if (/^[0-9a-fA-F]{6}$/.test(hex)) {\n parts.push(`<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"${hex}\"/>`);\n }\n }\n }\n\n // Underline\n if (formatting.underline) {\n const uAttrs: string[] = [`w:val=\"${formatting.underline.style}\"`];\n if (formatting.underline.color) {\n if (formatting.underline.color.rgb) {\n uAttrs.push(`w:color=\"${formatting.underline.color.rgb}\"`);\n }\n if (formatting.underline.color.themeColor) {\n uAttrs.push(`w:themeColor=\"${formatting.underline.color.themeColor}\"`);\n }\n if (formatting.underline.color.themeTint) {\n uAttrs.push(`w:themeTint=\"${formatting.underline.color.themeTint}\"`);\n }\n if (formatting.underline.color.themeShade) {\n uAttrs.push(`w:themeShade=\"${formatting.underline.color.themeShade}\"`);\n }\n }\n parts.push(`<w:u ${uAttrs.join(' ')}/>`);\n }\n\n // Effect\n if (formatting.effect && formatting.effect !== 'none') {\n parts.push(`<w:effect w:val=\"${formatting.effect}\"/>`);\n }\n\n // Emphasis mark\n if (formatting.emphasisMark && formatting.emphasisMark !== 'none') {\n parts.push(`<w:em w:val=\"${formatting.emphasisMark}\"/>`);\n }\n\n // Shading\n const shadingXml = serializeShading(formatting.shading);\n if (shadingXml) {\n parts.push(shadingXml);\n }\n\n // Vertical alignment\n if (formatting.vertAlign && formatting.vertAlign !== 'baseline') {\n parts.push(`<w:vertAlign w:val=\"${formatting.vertAlign}\"/>`);\n }\n\n // RTL and CS\n if (formatting.rtl) {\n parts.push('<w:rtl/>');\n }\n\n if (formatting.cs) {\n parts.push('<w:cs/>');\n }\n\n if (parts.length === 0) return '';\n\n return `<w:rPr>${parts.join('')}</w:rPr>`;\n}\n\nfunction extractRPrInner(rPrXml: string): string {\n if (!rPrXml.startsWith('<w:rPr>') || !rPrXml.endsWith('</w:rPr>')) {\n return '';\n }\n return rPrXml.slice('<w:rPr>'.length, -'</w:rPr>'.length);\n}\n\nfunction serializeRunPropertyChange(change: RunPropertyChange): string {\n const normalizedId = Number.isInteger(change.info.id) && change.info.id >= 0 ? change.info.id : 0;\n const authorCandidate = typeof change.info.author === 'string' ? change.info.author.trim() : '';\n const normalizedAuthor = authorCandidate.length > 0 ? authorCandidate : 'Unknown';\n const normalizedDate = typeof change.info.date === 'string' ? change.info.date.trim() : undefined;\n const normalizedRsid = typeof change.info.rsid === 'string' ? change.info.rsid.trim() : undefined;\n const attrs = [`w:id=\"${normalizedId}\"`, `w:author=\"${escapeXml(normalizedAuthor)}\"`];\n\n if (normalizedDate) {\n attrs.push(`w:date=\"${escapeXml(normalizedDate)}\"`);\n }\n if (normalizedRsid) {\n attrs.push(`w:rsid=\"${escapeXml(normalizedRsid)}\"`);\n }\n\n const previousRPrXml = serializeTextFormatting(change.previousFormatting) || '<w:rPr/>';\n return `<w:rPrChange ${attrs.join(' ')}>${previousRPrXml}</w:rPrChange>`;\n}\n\nfunction serializeRunProperties(\n formatting: TextFormatting | undefined,\n propertyChanges: RunPropertyChange[] | undefined\n): string {\n const currentRPrXml = serializeTextFormatting(formatting);\n const currentInner = currentRPrXml ? extractRPrInner(currentRPrXml) : '';\n const propertyChangeXml = (propertyChanges ?? []).map(serializeRunPropertyChange).join('');\n const combined = `${currentInner}${propertyChangeXml}`;\n\n if (!combined) {\n return '';\n }\n\n return `<w:rPr>${combined}</w:rPr>`;\n}\n\n// ============================================================================\n// RUN CONTENT SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize text content (w:t)\n */\nfunction serializeTextContent(content: TextContent): string {\n const needsPreserve =\n content.preserveSpace ||\n content.text.startsWith(' ') ||\n content.text.endsWith(' ') ||\n content.text.includes(' ');\n\n const spaceAttr = needsPreserve ? ' xml:space=\"preserve\"' : '';\n\n return `<w:t${spaceAttr}>${escapeXml(content.text)}</w:t>`;\n}\n\n/**\n * Serialize tab content (w:tab)\n */\nfunction serializeTabContent(_content: TabContent): string {\n return '<w:tab/>';\n}\n\n/**\n * Serialize break content (w:br)\n */\nfunction serializeBreakContent(content: BreakContent): string {\n const attrs: string[] = [];\n\n if (content.breakType === 'page') {\n attrs.push('w:type=\"page\"');\n } else if (content.breakType === 'column') {\n attrs.push('w:type=\"column\"');\n } else if (content.breakType === 'textWrapping') {\n attrs.push('w:type=\"textWrapping\"');\n if (content.clear && content.clear !== 'none') {\n attrs.push(`w:clear=\"${content.clear}\"`);\n }\n }\n\n if (attrs.length === 0) {\n return '<w:br/>';\n }\n\n return `<w:br ${attrs.join(' ')}/>`;\n}\n\n/**\n * Serialize symbol content (w:sym)\n */\nfunction serializeSymbolContent(content: SymbolContent): string {\n return `<w:sym w:font=\"${escapeXml(content.font)}\" w:char=\"${escapeXml(content.char)}\"/>`;\n}\n\n/**\n * Serialize footnote/endnote reference\n */\nfunction serializeNoteReference(content: NoteReferenceContent): string {\n if (content.type === 'footnoteRef') {\n return `<w:footnoteReference w:id=\"${content.id}\"/>`;\n } else {\n return `<w:endnoteReference w:id=\"${content.id}\"/>`;\n }\n}\n\n/**\n * Serialize field character (w:fldChar)\n */\nfunction serializeFieldChar(content: FieldCharContent): string {\n const attrs: string[] = [`w:fldCharType=\"${content.charType}\"`];\n\n if (content.fldLock) {\n attrs.push('w:fldLock=\"true\"');\n }\n\n if (content.dirty) {\n attrs.push('w:dirty=\"true\"');\n }\n\n return `<w:fldChar ${attrs.join(' ')}/>`;\n}\n\n/**\n * Serialize field instruction text (w:instrText)\n */\nfunction serializeInstrText(content: InstrTextContent): string {\n const needsPreserve =\n content.text.startsWith(' ') || content.text.endsWith(' ') || content.text.includes(' ');\n\n const spaceAttr = needsPreserve ? ' xml:space=\"preserve\"' : '';\n\n return `<w:instrText${spaceAttr}>${escapeXml(content.text)}</w:instrText>`;\n}\n\n/**\n * Serialize soft hyphen (w:softHyphen)\n */\nfunction serializeSoftHyphen(_content: SoftHyphenContent): string {\n return '<w:softHyphen/>';\n}\n\n/**\n * Serialize non-breaking hyphen (w:noBreakHyphen)\n */\nfunction serializeNoBreakHyphen(_content: NoBreakHyphenContent): string {\n return '<w:noBreakHyphen/>';\n}\n\n// ============================================================================\n// DRAWING / IMAGE / SHAPE SERIALIZATION\n// ============================================================================\n\n/** Serialize a color value to DrawingML a:srgbClr or a:schemeClr */\nfunction serializeDrawingColor(color: ColorValue | undefined): string {\n if (!color) return '';\n if (color.rgb) {\n return `<a:srgbClr val=\"${color.rgb.replace('#', '')}\"/>`;\n }\n if (color.themeColor) {\n let clr = `<a:schemeClr val=\"${color.themeColor}\"`;\n if (color.themeTint) {\n clr += `><a:tint val=\"${color.themeTint}\"/></a:schemeClr>`;\n } else if (color.themeShade) {\n clr += `><a:shade val=\"${color.themeShade}\"/></a:schemeClr>`;\n } else {\n clr += `/>`;\n }\n return clr;\n }\n return '';\n}\n\n/** Serialize shape fill to DrawingML */\nfunction serializeFill(fill: ShapeFill | undefined): string {\n if (!fill || fill.type === 'none') return '<a:noFill/>';\n if (fill.type === 'solid' && fill.color) {\n return `<a:solidFill>${serializeDrawingColor(fill.color)}</a:solidFill>`;\n }\n if (fill.type === 'gradient' && fill.gradient) {\n const g = fill.gradient;\n const stops = g.stops\n .map((s) => `<a:gs pos=\"${s.position}\">${serializeDrawingColor(s.color)}</a:gs>`)\n .join('');\n const direction =\n g.type === 'linear' ? `<a:lin ang=\"${(g.angle || 0) * 60000}\" scaled=\"1\"/>` : '';\n return `<a:gradFill><a:gsLst>${stops}</a:gsLst>${direction}</a:gradFill>`;\n }\n return '';\n}\n\n/** Serialize shape outline to DrawingML a:ln */\nfunction serializeOutline(outline: ShapeOutline | undefined): string {\n if (!outline) return '';\n const attrs: string[] = [];\n if (outline.width != null) attrs.push(`w=\"${outline.width}\"`);\n if (outline.cap) attrs.push(`cap=\"${outline.cap}\"`);\n\n const parts: string[] = [];\n if (outline.color) {\n parts.push(`<a:solidFill>${serializeDrawingColor(outline.color)}</a:solidFill>`);\n }\n if (outline.style && outline.style !== 'solid') {\n parts.push(`<a:prstDash val=\"${outline.style}\"/>`);\n }\n if (outline.headEnd) {\n parts.push(\n `<a:headEnd type=\"${outline.headEnd.type}\"${outline.headEnd.width ? ` w=\"${outline.headEnd.width}\"` : ''}${outline.headEnd.length ? ` len=\"${outline.headEnd.length}\"` : ''}/>`\n );\n }\n if (outline.tailEnd) {\n parts.push(\n `<a:tailEnd type=\"${outline.tailEnd.type}\"${outline.tailEnd.width ? ` w=\"${outline.tailEnd.width}\"` : ''}${outline.tailEnd.length ? ` len=\"${outline.tailEnd.length}\"` : ''}/>`\n );\n }\n\n if (parts.length === 0 && attrs.length === 0) return '';\n return `<a:ln${attrs.length ? ' ' + attrs.join(' ') : ''}>${parts.join('')}</a:ln>`;\n}\n\n/** Build wp:positionH and wp:positionV for floating drawings */\nfunction serializePosition(pos: ImagePosition): string {\n const parts: string[] = [];\n\n // Horizontal\n const h = pos.horizontal;\n parts.push(`<wp:positionH relativeFrom=\"${h.relativeTo}\">`);\n if (h.alignment) {\n parts.push(`<wp:align>${h.alignment}</wp:align>`);\n } else {\n parts.push(`<wp:posOffset>${h.posOffset || 0}</wp:posOffset>`);\n }\n parts.push('</wp:positionH>');\n\n // Vertical\n const v = pos.vertical;\n parts.push(`<wp:positionV relativeFrom=\"${v.relativeTo}\">`);\n if (v.alignment) {\n parts.push(`<wp:align>${v.alignment}</wp:align>`);\n } else {\n parts.push(`<wp:posOffset>${v.posOffset || 0}</wp:posOffset>`);\n }\n parts.push('</wp:positionV>');\n\n return parts.join('');\n}\n\n/** Serialize wrap type to wp:wrap* element */\nfunction serializeWrap(wrap: ImageWrap): string {\n const wrapText = wrap.wrapText ? ` wrapText=\"${wrap.wrapText}\"` : ' wrapText=\"bothSides\"';\n switch (wrap.type) {\n case 'square':\n return `<wp:wrapSquare${wrapText}/>`;\n case 'tight':\n return `<wp:wrapTight${wrapText}><wp:wrapPolygon edited=\"0\"><wp:start x=\"0\" y=\"0\"/><wp:lineTo x=\"0\" y=\"21600\"/><wp:lineTo x=\"21600\" y=\"21600\"/><wp:lineTo x=\"21600\" y=\"0\"/><wp:lineTo x=\"0\" y=\"0\"/></wp:wrapPolygon></wp:wrapTight>`;\n case 'through':\n return `<wp:wrapThrough${wrapText}><wp:wrapPolygon edited=\"0\"><wp:start x=\"0\" y=\"0\"/><wp:lineTo x=\"0\" y=\"21600\"/><wp:lineTo x=\"21600\" y=\"21600\"/><wp:lineTo x=\"21600\" y=\"0\"/><wp:lineTo x=\"0\" y=\"0\"/></wp:wrapPolygon></wp:wrapThrough>`;\n case 'topAndBottom':\n return '<wp:wrapTopAndBottom/>';\n case 'behind':\n case 'inFront':\n return '<wp:wrapNone/>';\n default:\n return '<wp:wrapNone/>';\n }\n}\n\n/** Build the common a:graphic > pic:pic element for images */\nfunction serializePicGraphic(image: Image, sharedId: string): string {\n const cx = image.size.width;\n const cy = image.size.height;\n const rId = image.rId || 'rId1';\n const id = sharedId;\n const name = image.filename || `image${id}`;\n\n let xfrmAttrs = '';\n if (image.transform?.rotation) {\n xfrmAttrs += ` rot=\"${Math.round(image.transform.rotation * 60000)}\"`;\n }\n if (image.transform?.flipH) xfrmAttrs += ' flipH=\"1\"';\n if (image.transform?.flipV) xfrmAttrs += ' flipV=\"1\"';\n\n return [\n '<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">',\n '<a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">',\n '<pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">',\n '<pic:nvPicPr>',\n `<pic:cNvPr id=\"${id}\" name=\"${escapeXml(name)}\"${image.alt ? ` descr=\"${escapeXml(image.alt)}\"` : ''}/>`,\n '<pic:cNvPicPr/>',\n '</pic:nvPicPr>',\n '<pic:blipFill>',\n `<a:blip r:embed=\"${rId}\"/>`,\n '<a:stretch><a:fillRect/></a:stretch>',\n '</pic:blipFill>',\n '<pic:spPr>',\n `<a:xfrm${xfrmAttrs}>`,\n '<a:off x=\"0\" y=\"0\"/>',\n `<a:ext cx=\"${cx}\" cy=\"${cy}\"/>`,\n '</a:xfrm>',\n '<a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom>',\n image.outline ? serializeOutline(image.outline) : '',\n '</pic:spPr>',\n '</pic:pic>',\n '</a:graphicData>',\n '</a:graphic>',\n ].join('');\n}\n\n/**\n * Serialize drawing/image content (w:drawing) to full DrawingML XML\n */\nfunction serializeDrawingContent(content: DrawingContent): string {\n const image = content.image;\n const isFloating = image.wrap.type !== 'inline';\n const cx = image.size.width;\n const cy = image.size.height;\n const distT = image.padding?.top ?? image.wrap.distT ?? 0;\n const distB = image.padding?.bottom ?? image.wrap.distB ?? 0;\n const distL = image.padding?.left ?? image.wrap.distL ?? 0;\n const distR = image.padding?.right ?? image.wrap.distR ?? 0;\n const docPrId = getUniqueId(image.id);\n const docPrName = image.title || image.filename || `Picture ${docPrId}`;\n\n const graphic = serializePicGraphic(image, docPrId);\n\n if (!isFloating) {\n // Inline image\n return [\n '<w:drawing>',\n `<wp:inline distT=\"${distT}\" distB=\"${distB}\" distL=\"${distL}\" distR=\"${distR}\">`,\n `<wp:extent cx=\"${cx}\" cy=\"${cy}\"/>`,\n '<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>',\n `<wp:docPr id=\"${docPrId}\" name=\"${escapeXml(docPrName)}\"${image.alt ? ` descr=\"${escapeXml(image.alt)}\"` : ''}${image.decorative ? ' hidden=\"1\"' : ''}/>`,\n '<wp:cNvGraphicFramePr><a:graphicFrameLocks xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" noChangeAspect=\"1\"/></wp:cNvGraphicFramePr>',\n graphic,\n '</wp:inline>',\n '</w:drawing>',\n ].join('');\n }\n\n // Floating (anchored) image\n const behindDoc = image.wrap.type === 'behind' ? '1' : '0';\n const position = image.position\n ? serializePosition(image.position)\n : '<wp:positionH relativeFrom=\"column\"><wp:posOffset>0</wp:posOffset></wp:positionH><wp:positionV relativeFrom=\"paragraph\"><wp:posOffset>0</wp:posOffset></wp:positionV>';\n const wrap = serializeWrap(image.wrap);\n\n return [\n '<w:drawing>',\n `<wp:anchor distT=\"${distT}\" distB=\"${distB}\" distL=\"${distL}\" distR=\"${distR}\" simplePos=\"0\" relativeHeight=\"251658240\" behindDoc=\"${behindDoc}\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">`,\n '<wp:simplePos x=\"0\" y=\"0\"/>',\n position,\n `<wp:extent cx=\"${cx}\" cy=\"${cy}\"/>`,\n '<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>',\n wrap,\n `<wp:docPr id=\"${docPrId}\" name=\"${escapeXml(docPrName)}\"${image.alt ? ` descr=\"${escapeXml(image.alt)}\"` : ''}/>`,\n '<wp:cNvGraphicFramePr><a:graphicFrameLocks xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" noChangeAspect=\"1\"/></wp:cNvGraphicFramePr>',\n graphic,\n '</wp:anchor>',\n '</w:drawing>',\n ].join('');\n}\n\n/** Serialize text body content for shapes/textboxes */\nfunction serializeShapeTextBody(paragraphs: Paragraph[]): string {\n return paragraphs.map((p) => serializeParagraph(p)).join('');\n}\n\n/**\n * Serialize shape content to full DrawingML XML (wps:wsp inside w:drawing)\n */\nfunction serializeShapeContent(content: ShapeContent): string {\n const shape = content.shape;\n const cx = shape.size.width;\n const cy = shape.size.height;\n const isTextBox = shape.shapeType === 'textBox';\n const isFloating = shape.wrap && shape.wrap.type !== 'inline';\n const distT = shape.wrap?.distT ?? 0;\n const distB = shape.wrap?.distB ?? 0;\n const distL = shape.wrap?.distL ?? 0;\n const distR = shape.wrap?.distR ?? 0;\n const docPrId = getUniqueId(shape.id);\n const docPrName = shape.name || (isTextBox ? `TextBox ${docPrId}` : `Shape ${docPrId}`);\n\n // Build xfrm\n let xfrmAttrs = '';\n if (shape.transform?.rotation) {\n xfrmAttrs += ` rot=\"${Math.round(shape.transform.rotation * 60000)}\"`;\n }\n if (shape.transform?.flipH) xfrmAttrs += ' flipH=\"1\"';\n if (shape.transform?.flipV) xfrmAttrs += ' flipV=\"1\"';\n\n // Build wps:spPr\n const spPr = [\n '<wps:spPr>',\n `<a:xfrm${xfrmAttrs}>`,\n '<a:off x=\"0\" y=\"0\"/>',\n `<a:ext cx=\"${cx}\" cy=\"${cy}\"/>`,\n '</a:xfrm>',\n `<a:prstGeom prst=\"${shape.shapeType === 'textBox' ? 'rect' : shape.shapeType}\"><a:avLst/></a:prstGeom>`,\n serializeFill(shape.fill),\n serializeOutline(shape.outline),\n '</wps:spPr>',\n ].join('');\n\n // Build text body if present\n let textBody = '';\n if (shape.textBody) {\n const tb = shape.textBody;\n const bpAttrs: string[] = ['rot=\"0\"', 'vert=\"horz\"'];\n if (tb.anchor) bpAttrs.push(`anchor=\"${tb.anchor === 'middle' ? 'ctr' : tb.anchor}\"`);\n if (tb.anchorCenter) bpAttrs.push('anchorCtr=\"1\"');\n if (tb.margins) {\n if (tb.margins.left != null) bpAttrs.push(`lIns=\"${tb.margins.left}\"`);\n if (tb.margins.top != null) bpAttrs.push(`tIns=\"${tb.margins.top}\"`);\n if (tb.margins.right != null) bpAttrs.push(`rIns=\"${tb.margins.right}\"`);\n if (tb.margins.bottom != null) bpAttrs.push(`bIns=\"${tb.margins.bottom}\"`);\n }\n\n if (isTextBox) {\n textBody = [\n '<wps:txbx><w:txbxContent>',\n serializeShapeTextBody(tb.content),\n '</w:txbxContent></wps:txbx>',\n `<wps:bodyPr ${bpAttrs.join(' ')}/>`,\n ].join('');\n } else {\n textBody = [`<wps:bodyPr ${bpAttrs.join(' ')}/>`].join('');\n }\n }\n\n // Build wps:wsp\n const wsp = [\n '<wps:wsp>',\n `<wps:cNvSpPr${isTextBox ? ' txBox=\"1\"' : ''}/>`,\n spPr,\n textBody,\n '</wps:wsp>',\n ].join('');\n\n // Wrap in a:graphic\n const graphic = [\n '<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">',\n '<a:graphicData uri=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\">',\n wsp,\n '</a:graphicData>',\n '</a:graphic>',\n ].join('');\n\n if (!isFloating) {\n return [\n '<w:drawing>',\n `<wp:inline distT=\"${distT}\" distB=\"${distB}\" distL=\"${distL}\" distR=\"${distR}\">`,\n `<wp:extent cx=\"${cx}\" cy=\"${cy}\"/>`,\n '<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>',\n `<wp:docPr id=\"${docPrId}\" name=\"${escapeXml(docPrName)}\"/>`,\n '<wp:cNvGraphicFramePr/>',\n graphic,\n '</wp:inline>',\n '</w:drawing>',\n ].join('');\n }\n\n // Floating shape\n const behindDoc = shape.wrap?.type === 'behind' ? '1' : '0';\n const position = shape.position\n ? serializePosition(shape.position)\n : '<wp:positionH relativeFrom=\"column\"><wp:posOffset>0</wp:posOffset></wp:positionH><wp:positionV relativeFrom=\"paragraph\"><wp:posOffset>0</wp:posOffset></wp:positionV>';\n const wrap = serializeWrap(shape.wrap!);\n\n return [\n '<w:drawing>',\n `<wp:anchor distT=\"${distT}\" distB=\"${distB}\" distL=\"${distL}\" distR=\"${distR}\" simplePos=\"0\" relativeHeight=\"251658240\" behindDoc=\"${behindDoc}\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">`,\n '<wp:simplePos x=\"0\" y=\"0\"/>',\n position,\n `<wp:extent cx=\"${cx}\" cy=\"${cy}\"/>`,\n '<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>',\n wrap,\n `<wp:docPr id=\"${docPrId}\" name=\"${escapeXml(docPrName)}\"/>`,\n '<wp:cNvGraphicFramePr/>',\n graphic,\n '</wp:anchor>',\n '</w:drawing>',\n ].join('');\n}\n\n/**\n * Serialize a single run content item\n */\nfunction serializeRunContent(content: RunContent): string {\n switch (content.type) {\n case 'text':\n return serializeTextContent(content);\n case 'tab':\n return serializeTabContent(content);\n case 'break':\n return serializeBreakContent(content);\n case 'symbol':\n return serializeSymbolContent(content);\n case 'footnoteRef':\n case 'endnoteRef':\n return serializeNoteReference(content);\n case 'fieldChar':\n return serializeFieldChar(content);\n case 'instrText':\n return serializeInstrText(content);\n case 'softHyphen':\n return serializeSoftHyphen(content);\n case 'noBreakHyphen':\n return serializeNoBreakHyphen(content);\n case 'drawing':\n return serializeDrawingContent(content);\n case 'shape':\n return serializeShapeContent(content);\n default:\n return '';\n }\n}\n\n// ============================================================================\n// MAIN SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize a run to OOXML XML (w:r)\n *\n * @param run - The run to serialize\n * @returns XML string for the run\n */\nexport function serializeRun(run: Run): string {\n const parts: string[] = [];\n\n // Add run properties if present\n const rPrXml = serializeRunProperties(run.formatting, run.propertyChanges);\n if (rPrXml) {\n parts.push(rPrXml);\n }\n\n // Add run content\n for (const content of run.content) {\n const contentXml = serializeRunContent(content);\n if (contentXml) {\n parts.push(contentXml);\n }\n }\n\n return `<w:r>${parts.join('')}</w:r>`;\n}\n\n/**\n * Serialize multiple runs to OOXML XML\n *\n * @param runs - The runs to serialize\n * @returns XML string for all runs\n */\nexport function serializeRuns(runs: Run[]): string {\n return runs.map(serializeRun).join('');\n}\n\n// ============================================================================\n// UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Check if a run has any content\n */\nexport function hasRunContent(run: Run): boolean {\n return run.content.length > 0;\n}\n\n/**\n * Check if a run has formatting\n */\nexport function hasRunFormatting(run: Run): boolean {\n return run.formatting !== undefined && Object.keys(run.formatting).length > 0;\n}\n\n/**\n * Get plain text from a run (for comparison/debugging)\n */\nexport function getRunPlainText(run: Run): string {\n return run.content\n .filter((c): c is TextContent => c.type === 'text')\n .map((c) => c.text)\n .join('');\n}\n\n/**\n * Create an empty run\n */\nexport function createEmptyRun(): Run {\n return {\n type: 'run',\n content: [],\n };\n}\n\n/**\n * Create a text run\n */\nexport function createTextRun(text: string, formatting?: TextFormatting): Run {\n return {\n type: 'run',\n formatting,\n content: [{ type: 'text', text }],\n };\n}\n\n/**\n * Create a break run\n */\nexport function createBreakRun(\n breakType?: 'page' | 'column' | 'textWrapping',\n formatting?: TextFormatting\n): Run {\n return {\n type: 'run',\n formatting,\n content: [{ type: 'break', breakType }],\n };\n}\n\n/**\n * Create a tab run\n */\nexport function createTabRun(formatting?: TextFormatting): Run {\n return {\n type: 'run',\n formatting,\n content: [{ type: 'tab' }],\n };\n}\n\nexport default serializeRun;\n","/**\n * Paragraph Serializer - Serialize paragraphs to OOXML XML\n *\n * Converts Paragraph objects back to <w:p> XML format for DOCX files.\n * Handles all paragraph properties and child content (runs, hyperlinks, fields, bookmarks).\n *\n * OOXML Reference:\n * - Paragraph: w:p\n * - Paragraph properties: w:pPr\n * - Runs, hyperlinks, bookmarks, fields as child elements\n */\n\nimport type {\n Paragraph,\n ParagraphContent,\n ParagraphFormatting,\n Run,\n Hyperlink,\n BookmarkStart,\n BookmarkEnd,\n SimpleField,\n ComplexField,\n InlineSdt,\n Insertion,\n Deletion,\n MoveFrom,\n MoveTo,\n MoveFromRangeStart,\n MoveToRangeStart,\n ParagraphPropertyChange,\n TabStop,\n BorderSpec,\n ShadingProperties,\n TextFormatting,\n} from '../../types/document';\n\nimport { serializeRun, serializeTextFormatting } from './runSerializer';\n\nimport { escapeXml } from './xmlUtils';\n\n// ============================================================================\n// BORDER SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize a single border element\n */\nfunction serializeBorder(border: BorderSpec | undefined, elementName: string): string {\n if (!border || border.style === 'none' || border.style === 'nil') {\n return '';\n }\n\n const attrs: string[] = [`w:val=\"${border.style}\"`];\n\n if (border.size !== undefined) {\n attrs.push(`w:sz=\"${border.size}\"`);\n }\n\n if (border.space !== undefined) {\n attrs.push(`w:space=\"${border.space}\"`);\n }\n\n // Color\n if (border.color) {\n if (border.color.auto) {\n attrs.push('w:color=\"auto\"');\n } else if (border.color.rgb) {\n attrs.push(`w:color=\"${border.color.rgb}\"`);\n }\n\n if (border.color.themeColor) {\n attrs.push(`w:themeColor=\"${border.color.themeColor}\"`);\n }\n\n if (border.color.themeTint) {\n attrs.push(`w:themeTint=\"${border.color.themeTint}\"`);\n }\n\n if (border.color.themeShade) {\n attrs.push(`w:themeShade=\"${border.color.themeShade}\"`);\n }\n }\n\n if (border.shadow) {\n attrs.push('w:shadow=\"true\"');\n }\n\n if (border.frame) {\n attrs.push('w:frame=\"true\"');\n }\n\n return `<w:${elementName} ${attrs.join(' ')}/>`;\n}\n\n/**\n * Serialize paragraph borders (w:pBdr)\n */\nfunction serializeParagraphBorders(borders: ParagraphFormatting['borders']): string {\n if (!borders) return '';\n\n const parts: string[] = [];\n\n if (borders.top) {\n const topXml = serializeBorder(borders.top, 'top');\n if (topXml) parts.push(topXml);\n }\n\n if (borders.left) {\n const leftXml = serializeBorder(borders.left, 'left');\n if (leftXml) parts.push(leftXml);\n }\n\n if (borders.bottom) {\n const bottomXml = serializeBorder(borders.bottom, 'bottom');\n if (bottomXml) parts.push(bottomXml);\n }\n\n if (borders.right) {\n const rightXml = serializeBorder(borders.right, 'right');\n if (rightXml) parts.push(rightXml);\n }\n\n if (borders.between) {\n const betweenXml = serializeBorder(borders.between, 'between');\n if (betweenXml) parts.push(betweenXml);\n }\n\n if (borders.bar) {\n const barXml = serializeBorder(borders.bar, 'bar');\n if (barXml) parts.push(barXml);\n }\n\n if (parts.length === 0) return '';\n\n return `<w:pBdr>${parts.join('')}</w:pBdr>`;\n}\n\n// ============================================================================\n// SHADING SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize shading properties (w:shd)\n */\nfunction serializeShading(shading: ShadingProperties | undefined): string {\n if (!shading) return '';\n\n const attrs: string[] = [];\n\n // Pattern/val\n if (shading.pattern) {\n attrs.push(`w:val=\"${shading.pattern}\"`);\n } else {\n attrs.push('w:val=\"clear\"');\n }\n\n // Color (pattern color)\n if (shading.color?.rgb) {\n attrs.push(`w:color=\"${shading.color.rgb}\"`);\n } else if (shading.color?.auto) {\n attrs.push('w:color=\"auto\"');\n }\n\n // Fill (background color)\n if (shading.fill?.rgb) {\n attrs.push(`w:fill=\"${shading.fill.rgb}\"`);\n } else if (shading.fill?.auto) {\n attrs.push('w:fill=\"auto\"');\n }\n\n // Theme fill\n if (shading.fill?.themeColor) {\n attrs.push(`w:themeFill=\"${shading.fill.themeColor}\"`);\n }\n\n if (shading.fill?.themeTint) {\n attrs.push(`w:themeFillTint=\"${shading.fill.themeTint}\"`);\n }\n\n if (shading.fill?.themeShade) {\n attrs.push(`w:themeFillShade=\"${shading.fill.themeShade}\"`);\n }\n\n if (attrs.length === 0) return '';\n\n return `<w:shd ${attrs.join(' ')}/>`;\n}\n\n// ============================================================================\n// TAB STOPS SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize tab stops (w:tabs)\n */\nfunction serializeTabStops(tabs: TabStop[] | undefined): string {\n if (!tabs || tabs.length === 0) return '';\n\n const tabElements = tabs.map((tab) => {\n const attrs: string[] = [`w:val=\"${tab.alignment}\"`, `w:pos=\"${tab.position}\"`];\n\n if (tab.leader && tab.leader !== 'none') {\n attrs.push(`w:leader=\"${tab.leader}\"`);\n }\n\n return `<w:tab ${attrs.join(' ')}/>`;\n });\n\n return `<w:tabs>${tabElements.join('')}</w:tabs>`;\n}\n\n// ============================================================================\n// SPACING SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize spacing properties (w:spacing)\n */\nfunction serializeSpacing(formatting: ParagraphFormatting): string {\n const attrs: string[] = [];\n\n if (formatting.spaceBefore !== undefined) {\n attrs.push(`w:before=\"${formatting.spaceBefore}\"`);\n }\n\n if (formatting.spaceAfter !== undefined) {\n attrs.push(`w:after=\"${formatting.spaceAfter}\"`);\n }\n\n if (formatting.lineSpacing !== undefined) {\n attrs.push(`w:line=\"${formatting.lineSpacing}\"`);\n }\n\n if (formatting.lineSpacingRule) {\n attrs.push(`w:lineRule=\"${formatting.lineSpacingRule}\"`);\n }\n\n if (formatting.beforeAutospacing) {\n attrs.push('w:beforeAutospacing=\"1\"');\n }\n\n if (formatting.afterAutospacing) {\n attrs.push('w:afterAutospacing=\"1\"');\n }\n\n if (attrs.length === 0) return '';\n\n return `<w:spacing ${attrs.join(' ')}/>`;\n}\n\n// ============================================================================\n// INDENTATION SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize indentation properties (w:ind)\n */\nfunction serializeIndentation(formatting: ParagraphFormatting): string {\n const attrs: string[] = [];\n\n if (formatting.indentLeft !== undefined) {\n attrs.push(`w:left=\"${formatting.indentLeft}\"`);\n }\n\n if (formatting.indentRight !== undefined) {\n attrs.push(`w:right=\"${formatting.indentRight}\"`);\n }\n\n if (formatting.indentFirstLine !== undefined) {\n if (formatting.hangingIndent) {\n // Hanging indent is stored as positive value but uses w:hanging attribute\n attrs.push(`w:hanging=\"${Math.abs(formatting.indentFirstLine)}\"`);\n } else if (formatting.indentFirstLine !== 0) {\n attrs.push(`w:firstLine=\"${formatting.indentFirstLine}\"`);\n }\n }\n\n if (attrs.length === 0) return '';\n\n return `<w:ind ${attrs.join(' ')}/>`;\n}\n\n// ============================================================================\n// NUMBERING SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize numbering properties (w:numPr)\n */\nfunction serializeNumbering(numPr: ParagraphFormatting['numPr']): string {\n if (!numPr) return '';\n\n const parts: string[] = [];\n\n if (numPr.ilvl !== undefined) {\n parts.push(`<w:ilvl w:val=\"${numPr.ilvl}\"/>`);\n }\n\n if (numPr.numId !== undefined) {\n parts.push(`<w:numId w:val=\"${numPr.numId}\"/>`);\n }\n\n if (parts.length === 0) return '';\n\n return `<w:numPr>${parts.join('')}</w:numPr>`;\n}\n\n// ============================================================================\n// FRAME PROPERTIES SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize frame properties (w:framePr)\n */\nfunction serializeFrameProperties(frame: ParagraphFormatting['frame']): string {\n if (!frame) return '';\n\n const attrs: string[] = [];\n\n if (frame.width !== undefined) {\n attrs.push(`w:w=\"${frame.width}\"`);\n }\n\n if (frame.height !== undefined) {\n attrs.push(`w:h=\"${frame.height}\"`);\n }\n\n if (frame.hAnchor) {\n attrs.push(`w:hAnchor=\"${frame.hAnchor}\"`);\n }\n\n if (frame.vAnchor) {\n attrs.push(`w:vAnchor=\"${frame.vAnchor}\"`);\n }\n\n if (frame.x !== undefined) {\n attrs.push(`w:x=\"${frame.x}\"`);\n }\n\n if (frame.y !== undefined) {\n attrs.push(`w:y=\"${frame.y}\"`);\n }\n\n if (frame.xAlign) {\n attrs.push(`w:xAlign=\"${frame.xAlign}\"`);\n }\n\n if (frame.yAlign) {\n attrs.push(`w:yAlign=\"${frame.yAlign}\"`);\n }\n\n if (frame.wrap) {\n attrs.push(`w:wrap=\"${frame.wrap}\"`);\n }\n\n if (attrs.length === 0) return '';\n\n return `<w:framePr ${attrs.join(' ')}/>`;\n}\n\n// ============================================================================\n// PARAGRAPH PROPERTIES SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize paragraph formatting properties to w:pPr XML\n */\nexport function serializeParagraphFormatting(\n formatting: ParagraphFormatting | undefined,\n propertyChanges?: ParagraphPropertyChange[]\n): string {\n const parts: string[] = [];\n\n if (formatting) {\n // Style reference (must be first)\n if (formatting.styleId) {\n parts.push(`<w:pStyle w:val=\"${escapeXml(formatting.styleId)}\"/>`);\n }\n\n // Keep next/lines/widow\n if (formatting.keepNext) {\n parts.push('<w:keepNext/>');\n }\n\n if (formatting.keepLines) {\n parts.push('<w:keepLines/>');\n }\n\n if (formatting.contextualSpacing) {\n parts.push('<w:contextualSpacing/>');\n }\n\n if (formatting.pageBreakBefore) {\n parts.push('<w:pageBreakBefore/>');\n }\n\n // Frame properties\n const frameXml = serializeFrameProperties(formatting.frame);\n if (frameXml) {\n parts.push(frameXml);\n }\n\n // Widow control\n if (formatting.widowControl === false) {\n parts.push('<w:widowControl w:val=\"0\"/>');\n } else if (formatting.widowControl === true) {\n parts.push('<w:widowControl/>');\n }\n\n // Numbering\n const numPrXml = serializeNumbering(formatting.numPr);\n if (numPrXml) {\n parts.push(numPrXml);\n }\n\n // Paragraph borders\n const bordersXml = serializeParagraphBorders(formatting.borders);\n if (bordersXml) {\n parts.push(bordersXml);\n }\n\n // Shading\n const shadingXml = serializeShading(formatting.shading);\n if (shadingXml) {\n parts.push(shadingXml);\n }\n\n // Tabs\n const tabsXml = serializeTabStops(formatting.tabs);\n if (tabsXml) {\n parts.push(tabsXml);\n }\n\n // Suppress line numbers\n if (formatting.suppressLineNumbers) {\n parts.push('<w:suppressLineNumbers/>');\n }\n\n // Suppress auto hyphens\n if (formatting.suppressAutoHyphens) {\n parts.push('<w:suppressAutoHyphens/>');\n }\n\n // Spacing\n const spacingXml = serializeSpacing(formatting);\n if (spacingXml) {\n parts.push(spacingXml);\n }\n\n // Indentation\n const indXml = serializeIndentation(formatting);\n if (indXml) {\n parts.push(indXml);\n }\n\n // Text direction (bidi)\n if (formatting.bidi) {\n parts.push('<w:bidi/>');\n }\n\n // Justification\n if (formatting.alignment) {\n parts.push(`<w:jc w:val=\"${formatting.alignment}\"/>`);\n }\n\n // Outline level\n if (formatting.outlineLevel !== undefined) {\n parts.push(`<w:outlineLvl w:val=\"${formatting.outlineLevel}\"/>`);\n }\n\n // Run properties (default run formatting for paragraph)\n if (formatting.runProperties) {\n const rPrXml = serializeTextFormatting(formatting.runProperties);\n if (rPrXml) {\n parts.push(rPrXml);\n }\n }\n }\n\n if (propertyChanges && propertyChanges.length > 0) {\n parts.push(...propertyChanges.map((change) => serializeParagraphPropertyChange(change)));\n }\n\n if (parts.length === 0) return '';\n\n return `<w:pPr>${parts.join('')}</w:pPr>`;\n}\n\nfunction extractPPrInner(pPrXml: string): string {\n if (!pPrXml.startsWith('<w:pPr>') || !pPrXml.endsWith('</w:pPr>')) {\n return '';\n }\n return pPrXml.slice('<w:pPr>'.length, -'</w:pPr>'.length);\n}\n\nfunction serializeParagraphPropertyChange(change: ParagraphPropertyChange): string {\n const normalizedId = Number.isInteger(change.info.id) && change.info.id >= 0 ? change.info.id : 0;\n const authorCandidate = typeof change.info.author === 'string' ? change.info.author.trim() : '';\n const normalizedAuthor = authorCandidate.length > 0 ? authorCandidate : 'Unknown';\n const normalizedDate = typeof change.info.date === 'string' ? change.info.date.trim() : undefined;\n const normalizedRsid = typeof change.info.rsid === 'string' ? change.info.rsid.trim() : undefined;\n const attrs = [`w:id=\"${normalizedId}\"`, `w:author=\"${escapeXml(normalizedAuthor)}\"`];\n if (normalizedDate) {\n attrs.push(`w:date=\"${escapeXml(normalizedDate)}\"`);\n }\n if (normalizedRsid) {\n attrs.push(`w:rsid=\"${escapeXml(normalizedRsid)}\"`);\n }\n\n const previousPPrXml = serializeParagraphFormatting(change.previousFormatting) || '<w:pPr/>';\n const previousPPrInner = extractPPrInner(previousPPrXml);\n const normalizedPreviousPPr =\n previousPPrInner.length > 0 ? `<w:pPr>${previousPPrInner}</w:pPr>` : '<w:pPr/>';\n return `<w:pPrChange ${attrs.join(' ')}>${normalizedPreviousPPr}</w:pPrChange>`;\n}\n\n// ============================================================================\n// CONTENT SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize a hyperlink (w:hyperlink)\n */\nfunction serializeHyperlink(hyperlink: Hyperlink): string {\n const attrs: string[] = [];\n\n if (hyperlink.rId) {\n attrs.push(`r:id=\"${hyperlink.rId}\"`);\n }\n\n if (hyperlink.anchor) {\n attrs.push(`w:anchor=\"${escapeXml(hyperlink.anchor)}\"`);\n }\n\n if (hyperlink.tooltip) {\n attrs.push(`w:tooltip=\"${escapeXml(hyperlink.tooltip)}\"`);\n }\n\n if (hyperlink.target) {\n attrs.push(`w:tgtFrame=\"${escapeXml(hyperlink.target)}\"`);\n }\n\n if (hyperlink.history === false) {\n attrs.push('w:history=\"0\"');\n }\n\n if (hyperlink.docLocation) {\n attrs.push(`w:docLocation=\"${escapeXml(hyperlink.docLocation)}\"`);\n }\n\n // Serialize children\n const childrenXml = hyperlink.children\n .map((child) => {\n if (child.type === 'run') {\n return serializeRun(child);\n } else if (child.type === 'bookmarkStart') {\n return serializeBookmarkStart(child);\n } else if (child.type === 'bookmarkEnd') {\n return serializeBookmarkEnd(child);\n }\n return '';\n })\n .join('');\n\n const attrsStr = attrs.length > 0 ? ' ' + attrs.join(' ') : '';\n return `<w:hyperlink${attrsStr}>${childrenXml}</w:hyperlink>`;\n}\n\n/**\n * Serialize bookmark start (w:bookmarkStart)\n */\nfunction serializeBookmarkStart(bookmark: BookmarkStart): string {\n const attrs: string[] = [`w:id=\"${bookmark.id}\"`, `w:name=\"${escapeXml(bookmark.name)}\"`];\n\n if (bookmark.colFirst !== undefined) {\n attrs.push(`w:colFirst=\"${bookmark.colFirst}\"`);\n }\n\n if (bookmark.colLast !== undefined) {\n attrs.push(`w:colLast=\"${bookmark.colLast}\"`);\n }\n\n return `<w:bookmarkStart ${attrs.join(' ')}/>`;\n}\n\n/**\n * Serialize bookmark end (w:bookmarkEnd)\n */\nfunction serializeBookmarkEnd(bookmark: BookmarkEnd): string {\n return `<w:bookmarkEnd w:id=\"${bookmark.id}\"/>`;\n}\n\n/**\n * Serialize a simple field as a complex field (fldChar begin/separate/end).\n * Complex field format is more widely supported by OOXML consumers\n * (Google Docs, Apple Pages) than w:fldSimple.\n */\nfunction serializeSimpleField(field: SimpleField): string {\n const parts: string[] = [];\n\n // Extract formatting from the first content run\n const firstRun = field.content.find((c): c is Run => c.type === 'run');\n const rPrXml = firstRun?.formatting ? serializeTextFormatting(firstRun.formatting) : '';\n\n // Begin field character\n const beginAttrs: string[] = ['w:fldCharType=\"begin\"'];\n if (field.fldLock) {\n beginAttrs.push('w:fldLock=\"true\"');\n }\n parts.push(`<w:r>${rPrXml}<w:fldChar ${beginAttrs.join(' ')}/></w:r>`);\n\n // Field code (instrText)\n const needsPreserve =\n field.instruction.startsWith(' ') ||\n field.instruction.endsWith(' ') ||\n field.instruction.includes(' ');\n const spaceAttr = needsPreserve ? ' xml:space=\"preserve\"' : '';\n parts.push(\n `<w:r>${rPrXml}<w:instrText${spaceAttr}>${escapeXml(field.instruction)}</w:instrText></w:r>`\n );\n\n // Separate field character\n parts.push(`<w:r>${rPrXml}<w:fldChar w:fldCharType=\"separate\"/></w:r>`);\n\n // Field result (the display runs)\n for (const item of field.content) {\n if (item.type === 'run') {\n parts.push(serializeRun(item));\n }\n }\n\n // End field character\n parts.push(`<w:r>${rPrXml}<w:fldChar w:fldCharType=\"end\"/></w:r>`);\n\n return parts.join('');\n}\n\n/**\n * Serialize a complex field\n * Complex fields are represented by multiple runs with fldChar elements,\n * so we convert them back to that structure\n */\nfunction serializeComplexField(field: ComplexField): string {\n const parts: string[] = [];\n\n // Extract formatting from the first result run to apply to structural runs\n // (begin/separate/end). OOXML consumers expect consistent formatting across\n // all runs in a complex field.\n const resultFormatting = field.fieldResult?.[0]?.formatting;\n const rPrXml = resultFormatting ? serializeTextFormatting(resultFormatting) : '';\n\n // Begin field character (never set dirty — dirty causes apps to recalculate\n // and potentially discard run formatting)\n const beginAttrs: string[] = ['w:fldCharType=\"begin\"'];\n if (field.fldLock) {\n beginAttrs.push('w:fldLock=\"true\"');\n }\n parts.push(`<w:r>${rPrXml}<w:fldChar ${beginAttrs.join(' ')}/></w:r>`);\n\n // Field code (instrText)\n if (field.fieldCode.length > 0) {\n parts.push(...field.fieldCode.map((run) => serializeRun(run)));\n } else {\n // Fallback: create instrText from instruction\n const needsPreserve =\n field.instruction.startsWith(' ') ||\n field.instruction.endsWith(' ') ||\n field.instruction.includes(' ');\n const spaceAttr = needsPreserve ? ' xml:space=\"preserve\"' : '';\n parts.push(\n `<w:r>${rPrXml}<w:instrText${spaceAttr}>${escapeXml(field.instruction)}</w:instrText></w:r>`\n );\n }\n\n // Separate field character\n parts.push(`<w:r>${rPrXml}<w:fldChar w:fldCharType=\"separate\"/></w:r>`);\n\n // Field result\n parts.push(...field.fieldResult.map((run) => serializeRun(run)));\n\n // End field character\n parts.push(`<w:r>${rPrXml}<w:fldChar w:fldCharType=\"end\"/></w:r>`);\n\n return parts.join('');\n}\n\n/**\n * Serialize an inline SDT (w:sdt)\n */\nfunction serializeInlineSdt(sdt: InlineSdt): string {\n const props = sdt.properties;\n const prParts: string[] = [];\n\n if (props.alias) prParts.push(`<w:alias w:val=\"${escapeXml(props.alias)}\"/>`);\n if (props.tag) prParts.push(`<w:tag w:val=\"${escapeXml(props.tag)}\"/>`);\n if (props.lock && props.lock !== 'unlocked') prParts.push(`<w:lock w:val=\"${props.lock}\"/>`);\n if (props.showingPlaceholder) prParts.push('<w:showingPlcHdr/>');\n\n // Type-specific properties\n switch (props.sdtType) {\n case 'plainText':\n prParts.push('<w:text/>');\n break;\n case 'date':\n if (props.dateFormat) {\n prParts.push(`<w:date w:fullDate=\"${escapeXml(props.dateFormat)}\"/>`);\n } else {\n prParts.push('<w:date/>');\n }\n break;\n case 'dropdown': {\n const items = (props.listItems ?? [])\n .map(\n (i) =>\n `<w:listItem w:displayText=\"${escapeXml(i.displayText)}\" w:value=\"${escapeXml(i.value)}\"/>`\n )\n .join('');\n prParts.push(`<w:dropDownList>${items}</w:dropDownList>`);\n break;\n }\n case 'comboBox': {\n const items = (props.listItems ?? [])\n .map(\n (i) =>\n `<w:listItem w:displayText=\"${escapeXml(i.displayText)}\" w:value=\"${escapeXml(i.value)}\"/>`\n )\n .join('');\n prParts.push(`<w:comboBox>${items}</w:comboBox>`);\n break;\n }\n case 'checkbox':\n prParts.push(\n `<w14:checkbox><w14:checked w14:val=\"${props.checked ? '1' : '0'}\"/></w14:checkbox>`\n );\n break;\n case 'picture':\n prParts.push('<w:picture/>');\n break;\n }\n\n const contentXml = sdt.content\n .map((item) => {\n if (item.type === 'run') return serializeRun(item);\n if (item.type === 'hyperlink') return serializeHyperlink(item);\n return '';\n })\n .join('');\n\n return `<w:sdt><w:sdtPr>${prParts.join('')}</w:sdtPr><w:sdtContent>${contentXml}</w:sdtContent></w:sdt>`;\n}\n\nfunction serializeMoveRangeStart(\n tag: 'moveFromRangeStart' | 'moveToRangeStart',\n marker: MoveFromRangeStart | MoveToRangeStart\n): string {\n const attrs = [`w:id=\"${marker.id}\"`, `w:name=\"${escapeXml(marker.name)}\"`];\n return `<w:${tag} ${attrs.join(' ')}/>`;\n}\n\n/**\n * Serialize a tracked change wrapper (ins/del/moveFrom/moveTo)\n */\nfunction serializeTrackedChange(\n tag: 'ins' | 'del' | 'moveFrom' | 'moveTo',\n change: Insertion | Deletion | MoveFrom | MoveTo\n): string {\n const info = change.info;\n const normalizedId = Number.isInteger(info.id) && info.id >= 0 ? info.id : 0;\n const authorCandidate = typeof info.author === 'string' ? info.author.trim() : '';\n const normalizedAuthor = authorCandidate.length > 0 ? authorCandidate : 'Unknown';\n const normalizedDate = typeof info.date === 'string' ? info.date.trim() : undefined;\n const attrs = [`w:id=\"${normalizedId}\"`, `w:author=\"${escapeXml(normalizedAuthor)}\"`];\n if (normalizedDate) attrs.push(`w:date=\"${escapeXml(normalizedDate)}\"`);\n\n const contentXml = change.content\n .map((item) => {\n if (item.type === 'run') {\n if (tag === 'del' || tag === 'moveFrom') {\n return serializeRun(item)\n .replace(/<w:t\\b/g, '<w:delText')\n .replace(/<\\/w:t>/g, '</w:delText>')\n .replace(/<w:instrText\\b/g, '<w:delInstrText')\n .replace(/<\\/w:instrText>/g, '</w:delInstrText>');\n }\n return serializeRun(item);\n }\n if (item.type === 'hyperlink') return serializeHyperlink(item);\n return '';\n })\n .join('');\n\n return `<w:${tag} ${attrs.join(' ')}>${contentXml}</w:${tag}>`;\n}\n\n/**\n * Serialize a single paragraph content item\n */\nfunction serializeParagraphContent(content: ParagraphContent): string {\n switch (content.type) {\n case 'run':\n return serializeRun(content);\n case 'hyperlink':\n return serializeHyperlink(content);\n case 'bookmarkStart':\n return serializeBookmarkStart(content);\n case 'bookmarkEnd':\n return serializeBookmarkEnd(content);\n case 'simpleField':\n return serializeSimpleField(content);\n case 'complexField':\n return serializeComplexField(content);\n case 'inlineSdt':\n return serializeInlineSdt(content);\n case 'commentRangeStart':\n return `<w:commentRangeStart w:id=\"${content.id}\"/>`;\n case 'commentRangeEnd':\n return (\n `<w:commentRangeEnd w:id=\"${content.id}\"/>` +\n `<w:r><w:rPr><w:rStyle w:val=\"CommentReference\"/></w:rPr><w:commentReference w:id=\"${content.id}\"/></w:r>`\n );\n case 'insertion':\n return serializeTrackedChange('ins', content);\n case 'deletion':\n return serializeTrackedChange('del', content);\n case 'moveFrom':\n return serializeTrackedChange('moveFrom', content);\n case 'moveTo':\n return serializeTrackedChange('moveTo', content);\n case 'moveFromRangeStart':\n return serializeMoveRangeStart('moveFromRangeStart', content as MoveFromRangeStart);\n case 'moveFromRangeEnd':\n return `<w:moveFromRangeEnd w:id=\"${content.id}\"/>`;\n case 'moveToRangeStart':\n return serializeMoveRangeStart('moveToRangeStart', content as MoveToRangeStart);\n case 'moveToRangeEnd':\n return `<w:moveToRangeEnd w:id=\"${content.id}\"/>`;\n case 'mathEquation':\n // Round-trip the raw OMML XML directly\n return content.ommlXml || '';\n default:\n return '';\n }\n}\n\n// ============================================================================\n// MAIN SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize a paragraph to OOXML XML (w:p)\n *\n * @param paragraph - The paragraph to serialize\n * @returns XML string for the paragraph\n */\nexport function serializeParagraph(paragraph: Paragraph): string {\n const parts: string[] = [];\n\n // Paragraph ID attributes\n const attrs: string[] = [];\n if (paragraph.paraId) {\n attrs.push(`w14:paraId=\"${paragraph.paraId}\"`);\n }\n if (paragraph.textId) {\n attrs.push(`w14:textId=\"${paragraph.textId}\"`);\n }\n const attrsStr = attrs.length > 0 ? ' ' + attrs.join(' ') : '';\n\n // Add paragraph properties if present\n const pPrXml = serializeParagraphFormatting(paragraph.formatting, paragraph.propertyChanges);\n if (pPrXml) {\n parts.push(pPrXml);\n }\n\n // Add paragraph content\n for (const content of paragraph.content) {\n const contentXml = serializeParagraphContent(content);\n if (contentXml) {\n parts.push(contentXml);\n }\n }\n\n return `<w:p${attrsStr}>${parts.join('')}</w:p>`;\n}\n\n/**\n * Serialize multiple paragraphs to OOXML XML\n *\n * @param paragraphs - The paragraphs to serialize\n * @returns XML string for all paragraphs\n */\nexport function serializeParagraphs(paragraphs: Paragraph[]): string {\n return paragraphs.map(serializeParagraph).join('');\n}\n\n// ============================================================================\n// UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Check if a paragraph has any content\n */\nexport function hasParagraphContent(paragraph: Paragraph): boolean {\n return paragraph.content.length > 0;\n}\n\n/**\n * Check if a paragraph has formatting\n */\nexport function hasParagraphFormatting(paragraph: Paragraph): boolean {\n return paragraph.formatting !== undefined && Object.keys(paragraph.formatting).length > 0;\n}\n\n/**\n * Get plain text from a paragraph (for comparison/debugging)\n */\nexport function getParagraphPlainText(paragraph: Paragraph): string {\n const texts: string[] = [];\n\n for (const content of paragraph.content) {\n if (content.type === 'run') {\n for (const item of content.content) {\n if (item.type === 'text') {\n texts.push(item.text);\n } else if (item.type === 'tab') {\n texts.push('\\t');\n } else if (item.type === 'break') {\n texts.push('\\n');\n }\n }\n } else if (content.type === 'hyperlink') {\n for (const child of content.children) {\n if (child.type === 'run') {\n for (const item of child.content) {\n if (item.type === 'text') {\n texts.push(item.text);\n }\n }\n }\n }\n } else if (content.type === 'simpleField') {\n for (const item of content.content) {\n if (item.type === 'run') {\n for (const subItem of item.content) {\n if (subItem.type === 'text') {\n texts.push(subItem.text);\n }\n }\n }\n }\n } else if (content.type === 'complexField') {\n for (const run of content.fieldResult) {\n for (const item of run.content) {\n if (item.type === 'text') {\n texts.push(item.text);\n }\n }\n }\n } else if (content.type === 'inlineSdt') {\n for (const item of content.content) {\n if (item.type === 'run') {\n for (const subItem of item.content) {\n if (subItem.type === 'text') {\n texts.push(subItem.text);\n }\n }\n }\n }\n } else if (\n content.type === 'insertion' ||\n content.type === 'deletion' ||\n content.type === 'moveFrom' ||\n content.type === 'moveTo'\n ) {\n for (const item of content.content) {\n if (item.type === 'run') {\n for (const subItem of item.content) {\n if (subItem.type === 'text') {\n texts.push(subItem.text);\n }\n }\n }\n }\n }\n }\n\n return texts.join('');\n}\n\n/**\n * Create an empty paragraph\n */\nexport function createEmptyParagraph(formatting?: ParagraphFormatting): Paragraph {\n return {\n type: 'paragraph',\n formatting,\n content: [],\n };\n}\n\n/**\n * Create a paragraph with a single text run\n */\nexport function createTextParagraph(\n text: string,\n paragraphFormatting?: ParagraphFormatting,\n textFormatting?: TextFormatting\n): Paragraph {\n return {\n type: 'paragraph',\n formatting: paragraphFormatting,\n content: [\n {\n type: 'run',\n formatting: textFormatting,\n content: [{ type: 'text', text }],\n },\n ],\n };\n}\n\n/**\n * Check if paragraph is a list item\n */\nexport function isListParagraph(paragraph: Paragraph): boolean {\n return paragraph.formatting?.numPr !== undefined;\n}\n\n/**\n * Get list level of a paragraph (0-8, or -1 if not a list)\n */\nexport function getListLevel(paragraph: Paragraph): number {\n return paragraph.formatting?.numPr?.ilvl ?? -1;\n}\n\nexport default serializeParagraph;\n","/**\n * Table Serializer - Serialize tables to OOXML XML\n *\n * Converts Table objects back to <w:tbl> XML format for DOCX files.\n * Handles all table, row, and cell properties including merged cells.\n *\n * OOXML Reference:\n * - Table: w:tbl\n * - Table properties: w:tblPr\n * - Table grid: w:tblGrid\n * - Table row: w:tr\n * - Row properties: w:trPr\n * - Table cell: w:tc\n * - Cell properties: w:tcPr\n */\n\nimport type {\n Table,\n TableRow,\n TableCell,\n TableFormatting,\n TableRowFormatting,\n TableCellFormatting,\n TablePropertyChange,\n TableRowPropertyChange,\n TableCellPropertyChange,\n TableStructuralChangeInfo,\n TableMeasurement,\n TableBorders,\n TableLook,\n CellMargins,\n FloatingTableProperties,\n ConditionalFormatStyle,\n BorderSpec,\n ShadingProperties,\n Paragraph,\n} from '../../types/document';\n\nimport { serializeParagraph } from './paragraphSerializer';\nimport { escapeXml } from './xmlUtils';\n\nfunction normalizeTrackedChangeInfo(info: { id: number; author: string; date?: string }): {\n id: number;\n author: string;\n date?: string;\n} {\n const normalizedId = Number.isInteger(info.id) && info.id >= 0 ? info.id : 0;\n const authorCandidate = typeof info.author === 'string' ? info.author.trim() : '';\n const normalizedAuthor = authorCandidate.length > 0 ? authorCandidate : 'Unknown';\n const normalizedDate = typeof info.date === 'string' ? info.date.trim() : undefined;\n\n return {\n id: normalizedId,\n author: normalizedAuthor,\n date: normalizedDate,\n };\n}\n\nfunction serializeTrackedChangeAttributes(\n info: { id: number; author: string; date?: string },\n rsid?: string\n): string {\n const normalized = normalizeTrackedChangeInfo(info);\n const attrs = [`w:id=\"${normalized.id}\"`, `w:author=\"${escapeXml(normalized.author)}\"`];\n if (normalized.date) {\n attrs.push(`w:date=\"${escapeXml(normalized.date)}\"`);\n }\n if (rsid && rsid.trim().length > 0) {\n attrs.push(`w:rsid=\"${escapeXml(rsid.trim())}\"`);\n }\n return attrs.join(' ');\n}\n\n// ============================================================================\n// MEASUREMENT SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize a table measurement (width, height)\n */\nfunction serializeMeasurement(\n measurement: TableMeasurement | undefined,\n elementName: string\n): string {\n if (!measurement) return '';\n\n const attrs: string[] = [`w:w=\"${measurement.value}\"`, `w:type=\"${measurement.type}\"`];\n\n return `<w:${elementName} ${attrs.join(' ')}/>`;\n}\n\n// ============================================================================\n// BORDER SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize a single border element\n */\nfunction serializeBorder(border: BorderSpec | undefined, elementName: string): string {\n if (!border || border.style === 'none' || border.style === 'nil') {\n return '';\n }\n\n const attrs: string[] = [`w:val=\"${border.style}\"`];\n\n if (border.size !== undefined) {\n attrs.push(`w:sz=\"${border.size}\"`);\n }\n\n if (border.space !== undefined) {\n attrs.push(`w:space=\"${border.space}\"`);\n }\n\n // Color\n if (border.color) {\n if (border.color.auto) {\n attrs.push('w:color=\"auto\"');\n } else if (border.color.rgb) {\n attrs.push(`w:color=\"${border.color.rgb}\"`);\n }\n\n if (border.color.themeColor) {\n attrs.push(`w:themeColor=\"${border.color.themeColor}\"`);\n }\n\n if (border.color.themeTint) {\n attrs.push(`w:themeTint=\"${border.color.themeTint}\"`);\n }\n\n if (border.color.themeShade) {\n attrs.push(`w:themeShade=\"${border.color.themeShade}\"`);\n }\n }\n\n if (border.shadow) {\n attrs.push('w:shadow=\"true\"');\n }\n\n if (border.frame) {\n attrs.push('w:frame=\"true\"');\n }\n\n return `<w:${elementName} ${attrs.join(' ')}/>`;\n}\n\n/**\n * Serialize table borders (w:tblBorders or w:tcBorders)\n */\nfunction serializeTableBorders(borders: TableBorders | undefined, elementName: string): string {\n if (!borders) return '';\n\n const parts: string[] = [];\n\n if (borders.top) {\n const topXml = serializeBorder(borders.top, 'top');\n if (topXml) parts.push(topXml);\n }\n\n if (borders.left) {\n const leftXml = serializeBorder(borders.left, 'left');\n if (leftXml) parts.push(leftXml);\n }\n\n if (borders.bottom) {\n const bottomXml = serializeBorder(borders.bottom, 'bottom');\n if (bottomXml) parts.push(bottomXml);\n }\n\n if (borders.right) {\n const rightXml = serializeBorder(borders.right, 'right');\n if (rightXml) parts.push(rightXml);\n }\n\n if (borders.insideH) {\n const insideHXml = serializeBorder(borders.insideH, 'insideH');\n if (insideHXml) parts.push(insideHXml);\n }\n\n if (borders.insideV) {\n const insideVXml = serializeBorder(borders.insideV, 'insideV');\n if (insideVXml) parts.push(insideVXml);\n }\n\n if (parts.length === 0) return '';\n\n return `<w:${elementName}>${parts.join('')}</w:${elementName}>`;\n}\n\n// ============================================================================\n// CELL MARGINS SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize cell margins (w:tblCellMar or w:tcMar)\n */\nfunction serializeCellMargins(margins: CellMargins | undefined, elementName: string): string {\n if (!margins) return '';\n\n const parts: string[] = [];\n\n if (margins.top) {\n parts.push(serializeMeasurement(margins.top, 'top'));\n }\n\n if (margins.left) {\n parts.push(serializeMeasurement(margins.left, 'left'));\n }\n\n if (margins.bottom) {\n parts.push(serializeMeasurement(margins.bottom, 'bottom'));\n }\n\n if (margins.right) {\n parts.push(serializeMeasurement(margins.right, 'right'));\n }\n\n if (parts.length === 0) return '';\n\n return `<w:${elementName}>${parts.join('')}</w:${elementName}>`;\n}\n\n// ============================================================================\n// SHADING SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize shading properties (w:shd)\n */\nfunction serializeShading(shading: ShadingProperties | undefined): string {\n if (!shading) return '';\n\n const attrs: string[] = [];\n\n // Pattern/val\n if (shading.pattern) {\n attrs.push(`w:val=\"${shading.pattern}\"`);\n } else {\n attrs.push('w:val=\"clear\"');\n }\n\n // Color (pattern color)\n if (shading.color?.rgb) {\n attrs.push(`w:color=\"${shading.color.rgb}\"`);\n } else if (shading.color?.auto) {\n attrs.push('w:color=\"auto\"');\n }\n\n // Fill (background color)\n if (shading.fill?.rgb) {\n attrs.push(`w:fill=\"${shading.fill.rgb}\"`);\n } else if (shading.fill?.auto) {\n attrs.push('w:fill=\"auto\"');\n }\n\n // Theme fill\n if (shading.fill?.themeColor) {\n attrs.push(`w:themeFill=\"${shading.fill.themeColor}\"`);\n }\n\n if (shading.fill?.themeTint) {\n attrs.push(`w:themeFillTint=\"${shading.fill.themeTint}\"`);\n }\n\n if (shading.fill?.themeShade) {\n attrs.push(`w:themeFillShade=\"${shading.fill.themeShade}\"`);\n }\n\n if (attrs.length === 0) return '';\n\n return `<w:shd ${attrs.join(' ')}/>`;\n}\n\n// ============================================================================\n// TABLE LOOK SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize table look flags (w:tblLook)\n */\nfunction serializeTableLook(look: TableLook | undefined): string {\n if (!look) return '';\n\n const attrs: string[] = [];\n\n if (look.firstRow) {\n attrs.push('w:firstRow=\"1\"');\n }\n\n if (look.lastRow) {\n attrs.push('w:lastRow=\"1\"');\n }\n\n if (look.firstColumn) {\n attrs.push('w:firstColumn=\"1\"');\n }\n\n if (look.lastColumn) {\n attrs.push('w:lastColumn=\"1\"');\n }\n\n if (look.noHBand) {\n attrs.push('w:noHBand=\"1\"');\n }\n\n if (look.noVBand) {\n attrs.push('w:noVBand=\"1\"');\n }\n\n if (attrs.length === 0) return '';\n\n return `<w:tblLook ${attrs.join(' ')}/>`;\n}\n\n// ============================================================================\n// FLOATING TABLE PROPERTIES SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize floating table properties (w:tblpPr)\n */\nfunction serializeFloatingTableProperties(floating: FloatingTableProperties | undefined): string {\n if (!floating) return '';\n\n const attrs: string[] = [];\n\n if (floating.horzAnchor) {\n attrs.push(`w:horzAnchor=\"${floating.horzAnchor}\"`);\n }\n\n if (floating.vertAnchor) {\n attrs.push(`w:vertAnchor=\"${floating.vertAnchor}\"`);\n }\n\n if (floating.tblpX !== undefined) {\n attrs.push(`w:tblpX=\"${floating.tblpX}\"`);\n }\n\n if (floating.tblpXSpec) {\n attrs.push(`w:tblpXSpec=\"${floating.tblpXSpec}\"`);\n }\n\n if (floating.tblpY !== undefined) {\n attrs.push(`w:tblpY=\"${floating.tblpY}\"`);\n }\n\n if (floating.tblpYSpec) {\n attrs.push(`w:tblpYSpec=\"${floating.tblpYSpec}\"`);\n }\n\n if (floating.topFromText !== undefined) {\n attrs.push(`w:topFromText=\"${floating.topFromText}\"`);\n }\n\n if (floating.bottomFromText !== undefined) {\n attrs.push(`w:bottomFromText=\"${floating.bottomFromText}\"`);\n }\n\n if (floating.leftFromText !== undefined) {\n attrs.push(`w:leftFromText=\"${floating.leftFromText}\"`);\n }\n\n if (floating.rightFromText !== undefined) {\n attrs.push(`w:rightFromText=\"${floating.rightFromText}\"`);\n }\n\n if (attrs.length === 0) return '';\n\n return `<w:tblpPr ${attrs.join(' ')}/>`;\n}\n\n// ============================================================================\n// TABLE PROPERTIES SERIALIZATION (w:tblPr)\n// ============================================================================\n\n/**\n * Serialize table formatting properties (w:tblPr)\n */\nexport function serializeTableFormatting(\n formatting: TableFormatting | undefined,\n propertyChanges?: TablePropertyChange[]\n): string {\n const parts: string[] = [];\n\n if (formatting) {\n // Table style (must be first)\n if (formatting.styleId) {\n parts.push(`<w:tblStyle w:val=\"${escapeXml(formatting.styleId)}\"/>`);\n }\n\n // Floating table properties\n const floatingXml = serializeFloatingTableProperties(formatting.floating);\n if (floatingXml) {\n parts.push(floatingXml);\n }\n\n // Bidirectional\n if (formatting.bidi) {\n parts.push('<w:bidiVisual/>');\n }\n\n // Table width\n const widthXml = serializeMeasurement(formatting.width, 'tblW');\n if (widthXml) {\n parts.push(widthXml);\n }\n\n // Table justification\n if (formatting.justification) {\n parts.push(`<w:jc w:val=\"${formatting.justification}\"/>`);\n }\n\n // Cell spacing\n const cellSpacingXml = serializeMeasurement(formatting.cellSpacing, 'tblCellSpacing');\n if (cellSpacingXml) {\n parts.push(cellSpacingXml);\n }\n\n // Table indent\n const indentXml = serializeMeasurement(formatting.indent, 'tblInd');\n if (indentXml) {\n parts.push(indentXml);\n }\n\n // Table borders\n const bordersXml = serializeTableBorders(formatting.borders, 'tblBorders');\n if (bordersXml) {\n parts.push(bordersXml);\n }\n\n // Default cell margins\n const marginsXml = serializeCellMargins(formatting.cellMargins, 'tblCellMar');\n if (marginsXml) {\n parts.push(marginsXml);\n }\n\n // Table layout\n if (formatting.layout) {\n parts.push(`<w:tblLayout w:type=\"${formatting.layout}\"/>`);\n }\n\n // Shading\n const shadingXml = serializeShading(formatting.shading);\n if (shadingXml) {\n parts.push(shadingXml);\n }\n\n // Table look\n const lookXml = serializeTableLook(formatting.look);\n if (lookXml) {\n parts.push(lookXml);\n }\n\n // Overlap\n if (formatting.overlap) {\n parts.push(`<w:tblOverlap w:val=\"${formatting.overlap}\"/>`);\n }\n }\n\n if (propertyChanges && propertyChanges.length > 0) {\n parts.push(...propertyChanges.map((change) => serializeTablePropertyChange(change)));\n }\n\n if (parts.length === 0) return '';\n\n return `<w:tblPr>${parts.join('')}</w:tblPr>`;\n}\n\nfunction extractTblPrInner(tblPrXml: string): string {\n if (!tblPrXml.startsWith('<w:tblPr>') || !tblPrXml.endsWith('</w:tblPr>')) {\n return '';\n }\n return tblPrXml.slice('<w:tblPr>'.length, -'</w:tblPr>'.length);\n}\n\nfunction serializeTablePropertyChange(change: TablePropertyChange): string {\n const attrs = serializeTrackedChangeAttributes(change.info, change.info.rsid);\n const previousTblPrXml = serializeTableFormatting(change.previousFormatting) || '<w:tblPr/>';\n const previousTblPrInner = extractTblPrInner(previousTblPrXml);\n const normalizedPreviousTblPr =\n previousTblPrInner.length > 0 ? `<w:tblPr>${previousTblPrInner}</w:tblPr>` : '<w:tblPr/>';\n\n return `<w:tblPrChange ${attrs}>${normalizedPreviousTblPr}</w:tblPrChange>`;\n}\n\n// ============================================================================\n// TABLE ROW PROPERTIES SERIALIZATION (w:trPr)\n// ============================================================================\n\n/**\n * Serialize table row formatting properties (w:trPr)\n */\nexport function serializeTableRowFormatting(\n formatting: TableRowFormatting | undefined,\n propertyChanges?: TableRowPropertyChange[],\n structuralChange?: TableStructuralChangeInfo\n): string {\n const parts: string[] = [];\n\n if (formatting) {\n // Can't split\n if (formatting.cantSplit) {\n parts.push('<w:cantSplit/>');\n }\n\n // Header row\n if (formatting.header) {\n parts.push('<w:tblHeader/>');\n }\n\n // Row height\n if (formatting.height) {\n const attrs: string[] = [`w:val=\"${formatting.height.value}\"`];\n\n if (formatting.heightRule) {\n attrs.push(`w:hRule=\"${formatting.heightRule}\"`);\n }\n\n parts.push(`<w:trHeight ${attrs.join(' ')}/>`);\n }\n\n // Row justification\n if (formatting.justification) {\n parts.push(`<w:jc w:val=\"${formatting.justification}\"/>`);\n }\n\n // Hidden\n if (formatting.hidden) {\n parts.push('<w:hidden/>');\n }\n }\n\n if (structuralChange) {\n if (structuralChange.type === 'tableRowInsertion') {\n parts.push(`<w:ins ${serializeTrackedChangeAttributes(structuralChange.info)}/>`);\n } else if (structuralChange.type === 'tableRowDeletion') {\n parts.push(`<w:del ${serializeTrackedChangeAttributes(structuralChange.info)}/>`);\n }\n }\n\n if (propertyChanges && propertyChanges.length > 0) {\n parts.push(...propertyChanges.map((change) => serializeTableRowPropertyChange(change)));\n }\n\n if (parts.length === 0) return '';\n\n return `<w:trPr>${parts.join('')}</w:trPr>`;\n}\n\nfunction extractTrPrInner(trPrXml: string): string {\n if (!trPrXml.startsWith('<w:trPr>') || !trPrXml.endsWith('</w:trPr>')) {\n return '';\n }\n return trPrXml.slice('<w:trPr>'.length, -'</w:trPr>'.length);\n}\n\nfunction serializeTableRowPropertyChange(change: TableRowPropertyChange): string {\n const attrs = serializeTrackedChangeAttributes(change.info, change.info.rsid);\n const previousTrPrXml = serializeTableRowFormatting(change.previousFormatting) || '<w:trPr/>';\n const previousTrPrInner = extractTrPrInner(previousTrPrXml);\n const normalizedPreviousTrPr =\n previousTrPrInner.length > 0 ? `<w:trPr>${previousTrPrInner}</w:trPr>` : '<w:trPr/>';\n\n return `<w:trPrChange ${attrs}>${normalizedPreviousTrPr}</w:trPrChange>`;\n}\n\n// ============================================================================\n// CONDITIONAL FORMAT STYLE SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize conditional format style (w:cnfStyle)\n */\nfunction serializeConditionalFormatStyle(style: ConditionalFormatStyle | undefined): string {\n if (!style) return '';\n\n // Build the 12-character binary string\n const bits = [\n style.firstRow ? '1' : '0',\n style.lastRow ? '1' : '0',\n style.firstColumn ? '1' : '0',\n style.lastColumn ? '1' : '0',\n style.oddVBand ? '1' : '0',\n style.evenVBand ? '1' : '0',\n style.oddHBand ? '1' : '0',\n style.evenHBand ? '1' : '0',\n style.nwCell ? '1' : '0',\n style.neCell ? '1' : '0',\n style.swCell ? '1' : '0',\n style.seCell ? '1' : '0',\n ];\n\n const val = bits.join('');\n\n // Only serialize if any bits are set\n if (val === '000000000000') return '';\n\n return `<w:cnfStyle w:val=\"${val}\"/>`;\n}\n\n// ============================================================================\n// TABLE CELL PROPERTIES SERIALIZATION (w:tcPr)\n// ============================================================================\n\n/**\n * Serialize table cell formatting properties (w:tcPr)\n */\nexport function serializeTableCellFormatting(\n formatting: TableCellFormatting | undefined,\n propertyChanges?: TableCellPropertyChange[],\n structuralChange?: TableStructuralChangeInfo\n): string {\n const parts: string[] = [];\n\n if (formatting) {\n // Conditional format style\n const cnfStyleXml = serializeConditionalFormatStyle(formatting.conditionalFormat);\n if (cnfStyleXml) {\n parts.push(cnfStyleXml);\n }\n\n // Cell width\n const widthXml = serializeMeasurement(formatting.width, 'tcW');\n if (widthXml) {\n parts.push(widthXml);\n }\n\n // Grid span (horizontal merge)\n if (formatting.gridSpan && formatting.gridSpan > 1) {\n parts.push(`<w:gridSpan w:val=\"${formatting.gridSpan}\"/>`);\n }\n\n // Vertical merge\n if (formatting.vMerge) {\n if (formatting.vMerge === 'restart') {\n parts.push('<w:vMerge w:val=\"restart\"/>');\n } else {\n // continue is the default when w:vMerge has no value\n parts.push('<w:vMerge/>');\n }\n }\n\n // Cell borders\n const bordersXml = serializeTableBorders(formatting.borders, 'tcBorders');\n if (bordersXml) {\n parts.push(bordersXml);\n }\n\n // Shading\n const shadingXml = serializeShading(formatting.shading);\n if (shadingXml) {\n parts.push(shadingXml);\n }\n\n // No wrap\n if (formatting.noWrap) {\n parts.push('<w:noWrap/>');\n }\n\n // Cell margins\n const marginsXml = serializeCellMargins(formatting.margins, 'tcMar');\n if (marginsXml) {\n parts.push(marginsXml);\n }\n\n // Text direction\n if (formatting.textDirection) {\n parts.push(`<w:textDirection w:val=\"${formatting.textDirection}\"/>`);\n }\n\n // Fit text\n if (formatting.fitText) {\n parts.push('<w:tcFitText/>');\n }\n\n // Vertical alignment\n if (formatting.verticalAlign) {\n parts.push(`<w:vAlign w:val=\"${formatting.verticalAlign}\"/>`);\n }\n\n // Hide mark\n if (formatting.hideMark) {\n parts.push('<w:hideMark/>');\n }\n }\n\n if (structuralChange) {\n if (structuralChange.type === 'tableCellInsertion') {\n parts.push(`<w:cellIns ${serializeTrackedChangeAttributes(structuralChange.info)}/>`);\n } else if (structuralChange.type === 'tableCellDeletion') {\n parts.push(`<w:cellDel ${serializeTrackedChangeAttributes(structuralChange.info)}/>`);\n } else if (structuralChange.type === 'tableCellMerge') {\n parts.push(`<w:cellMerge ${serializeTrackedChangeAttributes(structuralChange.info)}/>`);\n }\n }\n\n if (propertyChanges && propertyChanges.length > 0) {\n parts.push(...propertyChanges.map((change) => serializeTableCellPropertyChange(change)));\n }\n\n if (parts.length === 0) return '';\n\n return `<w:tcPr>${parts.join('')}</w:tcPr>`;\n}\n\nfunction extractTcPrInner(tcPrXml: string): string {\n if (!tcPrXml.startsWith('<w:tcPr>') || !tcPrXml.endsWith('</w:tcPr>')) {\n return '';\n }\n return tcPrXml.slice('<w:tcPr>'.length, -'</w:tcPr>'.length);\n}\n\nfunction serializeTableCellPropertyChange(change: TableCellPropertyChange): string {\n const attrs = serializeTrackedChangeAttributes(change.info, change.info.rsid);\n const previousTcPrXml = serializeTableCellFormatting(change.previousFormatting) || '<w:tcPr/>';\n const previousTcPrInner = extractTcPrInner(previousTcPrXml);\n const normalizedPreviousTcPr =\n previousTcPrInner.length > 0 ? `<w:tcPr>${previousTcPrInner}</w:tcPr>` : '<w:tcPr/>';\n\n return `<w:tcPrChange ${attrs}>${normalizedPreviousTcPr}</w:tcPrChange>`;\n}\n\n// ============================================================================\n// TABLE GRID SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize table grid (w:tblGrid)\n */\nfunction serializeTableGrid(columnWidths: number[] | undefined): string {\n if (!columnWidths || columnWidths.length === 0) return '';\n\n const cols = columnWidths.map((w) => `<w:gridCol w:w=\"${w}\"/>`);\n\n return `<w:tblGrid>${cols.join('')}</w:tblGrid>`;\n}\n\n// ============================================================================\n// CELL CONTENT SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize cell content (paragraphs, nested tables)\n */\nfunction serializeCellContent(content: (Paragraph | Table)[]): string {\n const parts: string[] = [];\n\n for (const item of content) {\n if (item.type === 'paragraph') {\n parts.push(serializeParagraph(item));\n } else if (item.type === 'table') {\n parts.push(serializeTable(item));\n }\n }\n\n // Ensure at least one empty paragraph (Word requires this)\n if (parts.length === 0) {\n parts.push('<w:p/>');\n }\n\n return parts.join('');\n}\n\n// ============================================================================\n// TABLE CELL SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize a table cell (w:tc)\n */\nexport function serializeTableCell(cell: TableCell): string {\n const parts: string[] = [];\n\n // Cell properties\n const tcPrXml = serializeTableCellFormatting(\n cell.formatting,\n cell.propertyChanges,\n cell.structuralChange\n );\n if (tcPrXml) {\n parts.push(tcPrXml);\n }\n\n // Cell content\n parts.push(serializeCellContent(cell.content));\n\n return `<w:tc>${parts.join('')}</w:tc>`;\n}\n\n// ============================================================================\n// TABLE ROW SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize a table row (w:tr)\n */\nexport function serializeTableRow(row: TableRow): string {\n const parts: string[] = [];\n\n // Row properties\n const trPrXml = serializeTableRowFormatting(\n row.formatting,\n row.propertyChanges,\n row.structuralChange\n );\n if (trPrXml) {\n parts.push(trPrXml);\n }\n\n // Cells\n for (const cell of row.cells) {\n parts.push(serializeTableCell(cell));\n }\n\n return `<w:tr>${parts.join('')}</w:tr>`;\n}\n\n// ============================================================================\n// MAIN TABLE SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize a table to OOXML XML (w:tbl)\n *\n * @param table - The table to serialize\n * @returns XML string for the table\n */\nexport function serializeTable(table: Table): string {\n const parts: string[] = [];\n\n // Table properties\n const tblPrXml = serializeTableFormatting(table.formatting, table.propertyChanges);\n if (tblPrXml) {\n parts.push(tblPrXml);\n }\n\n // Table grid\n const tblGridXml = serializeTableGrid(table.columnWidths);\n if (tblGridXml) {\n parts.push(tblGridXml);\n }\n\n // Rows\n for (const row of table.rows) {\n parts.push(serializeTableRow(row));\n }\n\n return `<w:tbl>${parts.join('')}</w:tbl>`;\n}\n\n/**\n * Serialize multiple tables to OOXML XML\n *\n * @param tables - The tables to serialize\n * @returns XML string for all tables\n */\nexport function serializeTables(tables: Table[]): string {\n return tables.map(serializeTable).join('');\n}\n\n// ============================================================================\n// UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Check if a table has any rows\n */\nexport function hasTableRows(table: Table): boolean {\n return table.rows.length > 0;\n}\n\n/**\n * Check if a table has formatting\n */\nexport function hasTableFormatting(table: Table): boolean {\n return table.formatting !== undefined && Object.keys(table.formatting).length > 0;\n}\n\n/**\n * Check if a row has any cells\n */\nexport function hasRowCells(row: TableRow): boolean {\n return row.cells.length > 0;\n}\n\n/**\n * Check if a row has formatting\n */\nexport function hasRowFormatting(row: TableRow): boolean {\n return row.formatting !== undefined && Object.keys(row.formatting).length > 0;\n}\n\n/**\n * Check if a cell has any content\n */\nexport function hasCellContent(cell: TableCell): boolean {\n return cell.content.length > 0;\n}\n\n/**\n * Check if a cell has formatting\n */\nexport function hasCellFormatting(cell: TableCell): boolean {\n return cell.formatting !== undefined && Object.keys(cell.formatting).length > 0;\n}\n\n/**\n * Get the number of columns in a table\n */\nexport function getTableColumnCount(table: Table): number {\n if (table.columnWidths && table.columnWidths.length > 0) {\n return table.columnWidths.length;\n }\n\n if (table.rows.length === 0) return 0;\n\n // Count cells in first row, accounting for grid span\n return table.rows[0].cells.reduce((count, cell) => {\n return count + (cell.formatting?.gridSpan ?? 1);\n }, 0);\n}\n\n/**\n * Get the number of rows in a table\n */\nexport function getTableRowCount(table: Table): number {\n return table.rows.length;\n}\n\n/**\n * Create an empty table\n */\nexport function createEmptyTable(rows: number = 1, cols: number = 1): Table {\n const tableRows: TableRow[] = [];\n\n for (let r = 0; r < rows; r++) {\n const cells: TableCell[] = [];\n for (let c = 0; c < cols; c++) {\n cells.push({\n type: 'tableCell',\n content: [{ type: 'paragraph', content: [] }],\n });\n }\n tableRows.push({\n type: 'tableRow',\n cells,\n });\n }\n\n return {\n type: 'table',\n rows: tableRows,\n };\n}\n\n/**\n * Create a table cell with text content\n */\nexport function createTextCell(text: string, formatting?: TableCellFormatting): TableCell {\n return {\n type: 'tableCell',\n formatting,\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'run',\n content: [{ type: 'text', text }],\n },\n ],\n },\n ],\n };\n}\n\nexport default serializeTable;\n","/**\n * Document Serializer - Serialize complete document.xml\n *\n * Converts Document objects back to valid document.xml OOXML format.\n * Combines all content (paragraphs, tables) with section properties\n * and proper namespace declarations.\n *\n * OOXML Reference:\n * - Document root: w:document\n * - Document body: w:body\n * - Section properties: w:sectPr\n */\n\nimport type {\n Document,\n DocumentBody,\n BlockContent,\n SectionProperties,\n HeaderReference,\n FooterReference,\n FootnoteProperties,\n EndnoteProperties,\n BorderSpec,\n} from '../../types/document';\n\nimport { serializeParagraph } from './paragraphSerializer';\nimport { resetAutoIdCounter } from './runSerializer';\nimport { serializeTable } from './tableSerializer';\n\n// ============================================================================\n// XML NAMESPACES\n// ============================================================================\n\n/**\n * Standard OOXML namespaces for document.xml\n */\nconst NAMESPACES = {\n wpc: 'http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas',\n cx: 'http://schemas.microsoft.com/office/drawing/2014/chartex',\n cx1: 'http://schemas.microsoft.com/office/drawing/2015/9/8/chartex',\n cx2: 'http://schemas.microsoft.com/office/drawing/2015/10/21/chartex',\n cx3: 'http://schemas.microsoft.com/office/drawing/2016/5/9/chartex',\n cx4: 'http://schemas.microsoft.com/office/drawing/2016/5/10/chartex',\n cx5: 'http://schemas.microsoft.com/office/drawing/2016/5/11/chartex',\n cx6: 'http://schemas.microsoft.com/office/drawing/2016/5/12/chartex',\n cx7: 'http://schemas.microsoft.com/office/drawing/2016/5/13/chartex',\n cx8: 'http://schemas.microsoft.com/office/drawing/2016/5/14/chartex',\n mc: 'http://schemas.openxmlformats.org/markup-compatibility/2006',\n aink: 'http://schemas.microsoft.com/office/drawing/2016/ink',\n am3d: 'http://schemas.microsoft.com/office/drawing/2017/model3d',\n o: 'urn:schemas-microsoft-com:office:office',\n oel: 'http://schemas.microsoft.com/office/2019/extlst',\n r: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships',\n m: 'http://schemas.openxmlformats.org/officeDocument/2006/math',\n v: 'urn:schemas-microsoft-com:vml',\n wp14: 'http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing',\n wp: 'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing',\n w10: 'urn:schemas-microsoft-com:office:word',\n w: 'http://schemas.openxmlformats.org/wordprocessingml/2006/main',\n w14: 'http://schemas.microsoft.com/office/word/2010/wordml',\n w15: 'http://schemas.microsoft.com/office/word/2012/wordml',\n w16cex: 'http://schemas.microsoft.com/office/word/2018/wordml/cex',\n w16cid: 'http://schemas.microsoft.com/office/word/2016/wordml/cid',\n w16: 'http://schemas.microsoft.com/office/word/2018/wordml',\n w16sdtdh: 'http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash',\n w16se: 'http://schemas.microsoft.com/office/word/2015/wordml/symex',\n wpg: 'http://schemas.microsoft.com/office/word/2010/wordprocessingGroup',\n wpi: 'http://schemas.microsoft.com/office/word/2010/wordprocessingInk',\n wne: 'http://schemas.microsoft.com/office/word/2006/wordml',\n wps: 'http://schemas.microsoft.com/office/word/2010/wordprocessingShape',\n};\n\n/**\n * Build namespace declaration string for document element\n */\nfunction buildNamespaceDeclarations(): string {\n // Minimal set of commonly used namespaces\n const minimalNamespaces = {\n wpc: NAMESPACES.wpc,\n mc: NAMESPACES.mc,\n o: NAMESPACES.o,\n r: NAMESPACES.r,\n m: NAMESPACES.m,\n v: NAMESPACES.v,\n wp14: NAMESPACES.wp14,\n wp: NAMESPACES.wp,\n w10: NAMESPACES.w10,\n w: NAMESPACES.w,\n w14: NAMESPACES.w14,\n w15: NAMESPACES.w15,\n wpg: NAMESPACES.wpg,\n wps: NAMESPACES.wps,\n };\n\n return Object.entries(minimalNamespaces)\n .map(([prefix, uri]) => `xmlns:${prefix}=\"${uri}\"`)\n .join(' ');\n}\n\n// ============================================================================\n// XML ESCAPING\n// ============================================================================\n\n// ============================================================================\n// BORDER SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize a border element\n */\nfunction serializeBorder(border: BorderSpec | undefined, elementName: string): string {\n if (!border || border.style === 'none' || border.style === 'nil') {\n return '';\n }\n\n const attrs: string[] = [`w:val=\"${border.style}\"`];\n\n if (border.size !== undefined) {\n attrs.push(`w:sz=\"${border.size}\"`);\n }\n\n if (border.space !== undefined) {\n attrs.push(`w:space=\"${border.space}\"`);\n }\n\n if (border.color) {\n if (border.color.auto) {\n attrs.push('w:color=\"auto\"');\n } else if (border.color.rgb) {\n attrs.push(`w:color=\"${border.color.rgb}\"`);\n }\n\n if (border.color.themeColor) {\n attrs.push(`w:themeColor=\"${border.color.themeColor}\"`);\n }\n\n if (border.color.themeTint) {\n attrs.push(`w:themeTint=\"${border.color.themeTint}\"`);\n }\n\n if (border.color.themeShade) {\n attrs.push(`w:themeShade=\"${border.color.themeShade}\"`);\n }\n }\n\n if (border.shadow) {\n attrs.push('w:shadow=\"true\"');\n }\n\n if (border.frame) {\n attrs.push('w:frame=\"true\"');\n }\n\n return `<w:${elementName} ${attrs.join(' ')}/>`;\n}\n\n// ============================================================================\n// SECTION PROPERTIES SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize header reference (w:headerReference)\n */\nfunction serializeHeaderReference(ref: HeaderReference): string {\n const attrs: string[] = [`w:type=\"${ref.type}\"`, `r:id=\"${ref.rId}\"`];\n\n return `<w:headerReference ${attrs.join(' ')}/>`;\n}\n\n/**\n * Serialize footer reference (w:footerReference)\n */\nfunction serializeFooterReference(ref: FooterReference): string {\n const attrs: string[] = [`w:type=\"${ref.type}\"`, `r:id=\"${ref.rId}\"`];\n\n return `<w:footerReference ${attrs.join(' ')}/>`;\n}\n\n/**\n * Serialize footnote properties (w:footnotePr)\n */\nfunction serializeFootnoteProperties(props: FootnoteProperties | undefined): string {\n if (!props) return '';\n\n const parts: string[] = [];\n\n if (props.position) {\n parts.push(`<w:pos w:val=\"${props.position}\"/>`);\n }\n\n if (props.numFmt) {\n parts.push(`<w:numFmt w:val=\"${props.numFmt}\"/>`);\n }\n\n if (props.numStart !== undefined) {\n parts.push(`<w:numStart w:val=\"${props.numStart}\"/>`);\n }\n\n if (props.numRestart) {\n parts.push(`<w:numRestart w:val=\"${props.numRestart}\"/>`);\n }\n\n if (parts.length === 0) return '';\n\n return `<w:footnotePr>${parts.join('')}</w:footnotePr>`;\n}\n\n/**\n * Serialize endnote properties (w:endnotePr)\n */\nfunction serializeEndnoteProperties(props: EndnoteProperties | undefined): string {\n if (!props) return '';\n\n const parts: string[] = [];\n\n if (props.position) {\n parts.push(`<w:pos w:val=\"${props.position}\"/>`);\n }\n\n if (props.numFmt) {\n parts.push(`<w:numFmt w:val=\"${props.numFmt}\"/>`);\n }\n\n if (props.numStart !== undefined) {\n parts.push(`<w:numStart w:val=\"${props.numStart}\"/>`);\n }\n\n if (props.numRestart) {\n parts.push(`<w:numRestart w:val=\"${props.numRestart}\"/>`);\n }\n\n if (parts.length === 0) return '';\n\n return `<w:endnotePr>${parts.join('')}</w:endnotePr>`;\n}\n\n/**\n * Serialize page size (w:pgSz)\n */\nfunction serializePageSize(props: SectionProperties): string {\n const attrs: string[] = [];\n\n if (props.pageWidth !== undefined) {\n attrs.push(`w:w=\"${props.pageWidth}\"`);\n }\n\n if (props.pageHeight !== undefined) {\n attrs.push(`w:h=\"${props.pageHeight}\"`);\n }\n\n if (props.orientation === 'landscape') {\n attrs.push('w:orient=\"landscape\"');\n }\n\n if (attrs.length === 0) return '';\n\n return `<w:pgSz ${attrs.join(' ')}/>`;\n}\n\n/**\n * Serialize page margins (w:pgMar)\n */\nfunction serializePageMargins(props: SectionProperties): string {\n const attrs: string[] = [];\n\n if (props.marginTop !== undefined) {\n attrs.push(`w:top=\"${props.marginTop}\"`);\n }\n\n if (props.marginRight !== undefined) {\n attrs.push(`w:right=\"${props.marginRight}\"`);\n }\n\n if (props.marginBottom !== undefined) {\n attrs.push(`w:bottom=\"${props.marginBottom}\"`);\n }\n\n if (props.marginLeft !== undefined) {\n attrs.push(`w:left=\"${props.marginLeft}\"`);\n }\n\n if (props.headerDistance !== undefined) {\n attrs.push(`w:header=\"${props.headerDistance}\"`);\n }\n\n if (props.footerDistance !== undefined) {\n attrs.push(`w:footer=\"${props.footerDistance}\"`);\n }\n\n if (props.gutter !== undefined) {\n attrs.push(`w:gutter=\"${props.gutter}\"`);\n }\n\n if (attrs.length === 0) return '';\n\n return `<w:pgMar ${attrs.join(' ')}/>`;\n}\n\n/**\n * Serialize columns (w:cols)\n */\nfunction serializeColumns(props: SectionProperties): string {\n if (!props.columnCount && !props.columns?.length) return '';\n\n const attrs: string[] = [];\n\n if (props.columnCount !== undefined && props.columnCount > 1) {\n attrs.push(`w:num=\"${props.columnCount}\"`);\n }\n\n if (props.columnSpace !== undefined) {\n attrs.push(`w:space=\"${props.columnSpace}\"`);\n }\n\n if (props.equalWidth !== undefined) {\n attrs.push(`w:equalWidth=\"${props.equalWidth ? '1' : '0'}\"`);\n }\n\n if (props.separator) {\n attrs.push('w:sep=\"1\"');\n }\n\n // Individual column definitions\n let colElements = '';\n if (props.columns && props.columns.length > 0) {\n colElements = props.columns\n .map((col) => {\n const colAttrs: string[] = [];\n if (col.width !== undefined) {\n colAttrs.push(`w:w=\"${col.width}\"`);\n }\n if (col.space !== undefined) {\n colAttrs.push(`w:space=\"${col.space}\"`);\n }\n return `<w:col ${colAttrs.join(' ')}/>`;\n })\n .join('');\n }\n\n if (attrs.length === 0 && !colElements) return '';\n\n const attrsStr = attrs.length > 0 ? ' ' + attrs.join(' ') : '';\n return `<w:cols${attrsStr}>${colElements}</w:cols>`;\n}\n\n/**\n * Serialize line numbers (w:lnNumType)\n */\nfunction serializeLineNumbers(props: SectionProperties): string {\n if (!props.lineNumbers) return '';\n\n const ln = props.lineNumbers;\n const attrs: string[] = [];\n\n if (ln.countBy !== undefined) {\n attrs.push(`w:countBy=\"${ln.countBy}\"`);\n }\n\n if (ln.start !== undefined) {\n attrs.push(`w:start=\"${ln.start}\"`);\n }\n\n if (ln.distance !== undefined) {\n attrs.push(`w:distance=\"${ln.distance}\"`);\n }\n\n if (ln.restart) {\n attrs.push(`w:restart=\"${ln.restart}\"`);\n }\n\n if (attrs.length === 0) return '';\n\n return `<w:lnNumType ${attrs.join(' ')}/>`;\n}\n\n/**\n * Serialize page borders (w:pgBorders)\n */\nfunction serializePageBorders(props: SectionProperties): string {\n if (!props.pageBorders) return '';\n\n const pb = props.pageBorders;\n const attrs: string[] = [];\n const borderElements: string[] = [];\n\n if (pb.display) {\n attrs.push(`w:display=\"${pb.display}\"`);\n }\n\n if (pb.offsetFrom) {\n attrs.push(`w:offsetFrom=\"${pb.offsetFrom}\"`);\n }\n\n if (pb.zOrder) {\n attrs.push(`w:zOrder=\"${pb.zOrder}\"`);\n }\n\n if (pb.top) {\n const topXml = serializeBorder(pb.top, 'top');\n if (topXml) borderElements.push(topXml);\n }\n\n if (pb.left) {\n const leftXml = serializeBorder(pb.left, 'left');\n if (leftXml) borderElements.push(leftXml);\n }\n\n if (pb.bottom) {\n const bottomXml = serializeBorder(pb.bottom, 'bottom');\n if (bottomXml) borderElements.push(bottomXml);\n }\n\n if (pb.right) {\n const rightXml = serializeBorder(pb.right, 'right');\n if (rightXml) borderElements.push(rightXml);\n }\n\n if (borderElements.length === 0) return '';\n\n const attrsStr = attrs.length > 0 ? ' ' + attrs.join(' ') : '';\n return `<w:pgBorders${attrsStr}>${borderElements.join('')}</w:pgBorders>`;\n}\n\n/**\n * Serialize document grid (w:docGrid)\n */\nfunction serializeDocGrid(props: SectionProperties): string {\n if (!props.docGrid) return '';\n\n const dg = props.docGrid;\n const attrs: string[] = [];\n\n if (dg.type) {\n attrs.push(`w:type=\"${dg.type}\"`);\n }\n\n if (dg.linePitch !== undefined) {\n attrs.push(`w:linePitch=\"${dg.linePitch}\"`);\n }\n\n if (dg.charSpace !== undefined) {\n attrs.push(`w:charSpace=\"${dg.charSpace}\"`);\n }\n\n if (attrs.length === 0) return '';\n\n return `<w:docGrid ${attrs.join(' ')}/>`;\n}\n\n/**\n * Serialize section properties (w:sectPr)\n */\nexport function serializeSectionProperties(props: SectionProperties | undefined): string {\n if (!props) return '';\n\n const parts: string[] = [];\n\n // Header references\n if (props.headerReferences) {\n for (const ref of props.headerReferences) {\n parts.push(serializeHeaderReference(ref));\n }\n }\n\n // Footer references\n if (props.footerReferences) {\n for (const ref of props.footerReferences) {\n parts.push(serializeFooterReference(ref));\n }\n }\n\n // Footnote properties\n const footnotePrXml = serializeFootnoteProperties(props.footnotePr);\n if (footnotePrXml) {\n parts.push(footnotePrXml);\n }\n\n // Endnote properties\n const endnotePrXml = serializeEndnoteProperties(props.endnotePr);\n if (endnotePrXml) {\n parts.push(endnotePrXml);\n }\n\n // Section type\n if (props.sectionStart) {\n parts.push(`<w:type w:val=\"${props.sectionStart}\"/>`);\n }\n\n // Page size\n const pgSzXml = serializePageSize(props);\n if (pgSzXml) {\n parts.push(pgSzXml);\n }\n\n // Page margins\n const pgMarXml = serializePageMargins(props);\n if (pgMarXml) {\n parts.push(pgMarXml);\n }\n\n // Paper source\n if (props.paperSrcFirst !== undefined || props.paperSrcOther !== undefined) {\n const attrs: string[] = [];\n if (props.paperSrcFirst !== undefined) {\n attrs.push(`w:first=\"${props.paperSrcFirst}\"`);\n }\n if (props.paperSrcOther !== undefined) {\n attrs.push(`w:other=\"${props.paperSrcOther}\"`);\n }\n parts.push(`<w:paperSrc ${attrs.join(' ')}/>`);\n }\n\n // Page borders\n const pgBordersXml = serializePageBorders(props);\n if (pgBordersXml) {\n parts.push(pgBordersXml);\n }\n\n // Line numbers\n const lnNumXml = serializeLineNumbers(props);\n if (lnNumXml) {\n parts.push(lnNumXml);\n }\n\n // Columns\n const colsXml = serializeColumns(props);\n if (colsXml) {\n parts.push(colsXml);\n }\n\n // Document grid\n const docGridXml = serializeDocGrid(props);\n if (docGridXml) {\n parts.push(docGridXml);\n }\n\n // Vertical alignment\n if (props.verticalAlign) {\n parts.push(`<w:vAlign w:val=\"${props.verticalAlign}\"/>`);\n }\n\n // Bidirectional\n if (props.bidi) {\n parts.push('<w:bidi/>');\n }\n\n // Title page (different first page header/footer)\n if (props.titlePg) {\n parts.push('<w:titlePg/>');\n }\n\n // Even and odd headers\n if (props.evenAndOddHeaders) {\n parts.push('<w:evenAndOddHeaders/>');\n }\n\n if (parts.length === 0) return '';\n\n return `<w:sectPr>${parts.join('')}</w:sectPr>`;\n}\n\n// ============================================================================\n// CONTENT SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize a single block content item (paragraph or table)\n */\nfunction serializeBlockContent(block: BlockContent): string {\n if (block.type === 'paragraph') {\n return serializeParagraph(block);\n } else if (block.type === 'table') {\n return serializeTable(block);\n } else if (block.type === 'blockSdt') {\n // Block-level SDT: wrap content in w:sdt\n const contentXml = block.content.map((b) => serializeBlockContent(b)).join('');\n const props = block.properties;\n const prParts: string[] = [];\n if (props.alias) prParts.push(`<w:alias w:val=\"${props.alias}\"/>`);\n if (props.tag) prParts.push(`<w:tag w:val=\"${props.tag}\"/>`);\n return `<w:sdt><w:sdtPr>${prParts.join('')}</w:sdtPr><w:sdtContent>${contentXml}</w:sdtContent></w:sdt>`;\n }\n return '';\n}\n\n/**\n * Serialize document body content\n */\nfunction serializeBodyContent(content: BlockContent[]): string {\n return content.map((block) => serializeBlockContent(block)).join('');\n}\n\n// ============================================================================\n// MAIN DOCUMENT SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize a DocumentBody to document.xml body content\n *\n * @param body - The document body to serialize\n * @returns XML string for the body element (without body tags)\n */\nexport function serializeDocumentBody(body: DocumentBody): string {\n const parts: string[] = [];\n\n // Serialize all content blocks\n parts.push(serializeBodyContent(body.content));\n\n // Final section properties (at the end of body)\n if (body.finalSectionProperties) {\n parts.push(serializeSectionProperties(body.finalSectionProperties));\n }\n\n return parts.join('');\n}\n\n/**\n * Serialize a complete Document to valid document.xml\n *\n * @param doc - The document to serialize\n * @returns Complete XML string for document.xml\n */\nexport function serializeDocument(doc: Document): string {\n // Reset auto-incrementing image/shape ID counter for this serialization pass\n resetAutoIdCounter();\n\n const parts: string[] = [];\n\n // XML declaration\n parts.push('<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>');\n\n // Document element with namespaces\n const nsDecl = buildNamespaceDeclarations();\n parts.push(`<w:document ${nsDecl} mc:Ignorable=\"w14 w15 wp14\">`);\n\n // Document body\n parts.push('<w:body>');\n parts.push(serializeDocumentBody(doc.package.document));\n parts.push('</w:body>');\n\n // Close document element\n parts.push('</w:document>');\n\n return parts.join('');\n}\n\n/**\n * Serialize just the document body (useful for partial updates)\n *\n * @param body - The document body to serialize\n * @returns XML string for the w:body element\n */\nexport function serializeDocumentBodyElement(body: DocumentBody): string {\n return `<w:body>${serializeDocumentBody(body)}</w:body>`;\n}\n\n// ============================================================================\n// UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Check if document has any content\n */\nexport function hasDocumentContent(doc: Document): boolean {\n return doc.package.document.content.length > 0;\n}\n\n/**\n * Check if document has sections\n */\nexport function hasDocumentSections(doc: Document): boolean {\n return (doc.package.document.sections?.length ?? 0) > 0;\n}\n\n/**\n * Check if document has section properties\n */\nexport function hasSectionProperties(doc: Document): boolean {\n return doc.package.document.finalSectionProperties !== undefined;\n}\n\n/**\n * Get document content count (paragraphs + tables)\n */\nexport function getDocumentContentCount(doc: Document): number {\n return doc.package.document.content.length;\n}\n\n/**\n * Get paragraph count in document\n */\nexport function getDocumentParagraphCount(doc: Document): number {\n return doc.package.document.content.filter((b) => b.type === 'paragraph').length;\n}\n\n/**\n * Get table count in document\n */\nexport function getDocumentTableCount(doc: Document): number {\n return doc.package.document.content.filter((b) => b.type === 'table').length;\n}\n\n/**\n * Get plain text from document (for comparison/debugging)\n */\nexport function getDocumentPlainText(doc: Document): string {\n const texts: string[] = [];\n\n for (const block of doc.package.document.content) {\n if (block.type === 'paragraph') {\n for (const content of block.content) {\n if (content.type === 'run') {\n for (const item of content.content) {\n if (item.type === 'text') {\n texts.push(item.text);\n } else if (item.type === 'tab') {\n texts.push('\\t');\n } else if (item.type === 'break') {\n texts.push('\\n');\n }\n }\n }\n }\n texts.push('\\n'); // Paragraph break\n }\n }\n\n return texts.join('');\n}\n\n/**\n * Create an empty document\n */\nexport function createEmptyDocument(): Document {\n return {\n package: {\n document: {\n content: [],\n },\n },\n };\n}\n\n/**\n * Create a simple document with text content\n */\nexport function createSimpleDocument(\n paragraphs: Array<{ text: string; styleId?: string }>\n): Document {\n return {\n package: {\n document: {\n content: paragraphs.map((p) => ({\n type: 'paragraph' as const,\n formatting: p.styleId ? { styleId: p.styleId } : undefined,\n content: [\n {\n type: 'run' as const,\n content: [{ type: 'text' as const, text: p.text }],\n },\n ],\n })),\n },\n },\n };\n}\n\nexport default serializeDocument;\n","/**\n * Header/Footer Serializer - Serialize headers/footers to OOXML XML\n *\n * Converts HeaderFooter objects back to valid header*.xml / footer*.xml format.\n * Reuses paragraph and table serializers for content.\n *\n * OOXML Reference:\n * - Header root: w:hdr\n * - Footer root: w:ftr\n * - Content: w:p, w:tbl (same as document body)\n */\n\nimport type { HeaderFooter, Paragraph, Table } from '../../types/document';\nimport { serializeParagraph } from './paragraphSerializer';\nimport { serializeTable } from './tableSerializer';\n\n// Minimal namespaces needed for header/footer XML\nconst NAMESPACES: Record<string, string> = {\n wpc: 'http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas',\n mc: 'http://schemas.openxmlformats.org/markup-compatibility/2006',\n o: 'urn:schemas-microsoft-com:office:office',\n r: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships',\n m: 'http://schemas.openxmlformats.org/officeDocument/2006/math',\n v: 'urn:schemas-microsoft-com:vml',\n wp14: 'http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing',\n wp: 'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing',\n w10: 'urn:schemas-microsoft-com:office:word',\n w: 'http://schemas.openxmlformats.org/wordprocessingml/2006/main',\n w14: 'http://schemas.microsoft.com/office/word/2010/wordml',\n w15: 'http://schemas.microsoft.com/office/word/2012/wordml',\n wpg: 'http://schemas.microsoft.com/office/word/2010/wordprocessingGroup',\n wps: 'http://schemas.microsoft.com/office/word/2010/wordprocessingShape',\n};\n\nfunction buildNamespaceDeclarations(): string {\n return Object.entries(NAMESPACES)\n .map(([prefix, uri]) => `xmlns:${prefix}=\"${uri}\"`)\n .join(' ');\n}\n\n/**\n * Serialize a block content item (paragraph or table) for header/footer\n */\nfunction serializeBlock(block: Paragraph | Table): string {\n if (block.type === 'paragraph') {\n return serializeParagraph(block);\n } else if (block.type === 'table') {\n return serializeTable(block);\n }\n return '';\n}\n\n/**\n * Serialize a HeaderFooter object to valid OOXML XML\n *\n * @param hf - HeaderFooter object to serialize\n * @returns Complete XML string for header*.xml or footer*.xml\n */\nexport function serializeHeaderFooter(hf: HeaderFooter): string {\n const rootTag = hf.type === 'header' ? 'w:hdr' : 'w:ftr';\n const nsDecl = buildNamespaceDeclarations();\n\n // Serialize content blocks\n let contentXml = hf.content.map((block) => serializeBlock(block)).join('');\n\n // Ensure at least one empty paragraph (required by OOXML spec)\n if (!contentXml) {\n contentXml = '<w:p><w:pPr/></w:p>';\n }\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n<${rootTag} ${nsDecl}>${contentXml}</${rootTag}>`;\n}\n","/**\n * Comment Serializer\n *\n * Serializes Comment[] to OOXML comments.xml format.\n */\n\nimport type { Comment, Paragraph, Run } from '../../types/content';\nimport { escapeXml } from './xmlUtils';\n\nfunction serializeRunContent(run: Run): string {\n let xml = '<w:r>';\n // Run properties (minimal — just preserve formatting basics)\n const rPr: string[] = [];\n if (run.formatting?.bold) rPr.push('<w:b/>');\n if (run.formatting?.italic) rPr.push('<w:i/>');\n if (rPr.length > 0) xml += `<w:rPr>${rPr.join('')}</w:rPr>`;\n\n for (const c of run.content) {\n if (c.type === 'text') {\n const preserveSpace = c.text !== c.text.trim() || c.text.includes(' ');\n xml += preserveSpace\n ? `<w:t xml:space=\"preserve\">${escapeXml(c.text)}</w:t>`\n : `<w:t>${escapeXml(c.text)}</w:t>`;\n } else if (c.type === 'break') {\n xml += '<w:br/>';\n }\n }\n xml += '</w:r>';\n return xml;\n}\n\nfunction serializeParagraph(p: Paragraph): string {\n let xml = '<w:p>';\n for (const item of p.content) {\n if (item.type === 'run') {\n xml += serializeRunContent(item);\n }\n }\n xml += '</w:p>';\n return xml;\n}\n\n/** Serialize a paragraph, prepending an annotationRef run (required by Word in first paragraph of a comment) */\nfunction serializeParagraphWithAnnotationRef(p: Paragraph): string {\n let xml = '<w:p>';\n xml += '<w:r><w:rPr><w:rStyle w:val=\"CommentReference\"/></w:rPr><w:annotationRef/></w:r>';\n for (const item of p.content) {\n if (item.type === 'run') {\n xml += serializeRunContent(item);\n }\n }\n xml += '</w:p>';\n return xml;\n}\n\nfunction serializeComment(comment: Comment): string {\n const attrs: string[] = [`w:id=\"${comment.id}\"`];\n if (comment.author) attrs.push(`w:author=\"${escapeXml(comment.author)}\"`);\n if (comment.initials) attrs.push(`w:initials=\"${escapeXml(comment.initials)}\"`);\n if (comment.date) attrs.push(`w:date=\"${escapeXml(comment.date)}\"`);\n\n let xml = `<w:comment ${attrs.join(' ')}>`;\n if (comment.content && comment.content.length > 0) {\n // First paragraph must contain an annotationRef run for Word to link the comment\n xml += serializeParagraphWithAnnotationRef(comment.content[0]);\n for (let i = 1; i < comment.content.length; i++) {\n xml += serializeParagraph(comment.content[i]);\n }\n } else {\n // Empty comment — still needs a paragraph with annotationRef\n xml +=\n '<w:p><w:r><w:rPr><w:rStyle w:val=\"CommentReference\"/></w:rPr><w:annotationRef/></w:r></w:p>';\n }\n xml += '</w:comment>';\n return xml;\n}\n\n/**\n * Serialize comments array to comments.xml content\n */\nexport function serializeComments(comments: Comment[]): string {\n if (!comments || comments.length === 0) return '';\n\n // Separate top-level comments and replies in a single pass\n const topLevel: Comment[] = [];\n const replies: Comment[] = [];\n for (const c of comments) {\n (c.parentId == null ? topLevel : replies).push(c);\n }\n\n let xml =\n '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n' +\n '<w:comments xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" ' +\n 'xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" ' +\n 'xmlns:o=\"urn:schemas-microsoft-com:office:office\" ' +\n 'xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" ' +\n 'xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" ' +\n 'xmlns:v=\"urn:schemas-microsoft-com:vml\" ' +\n 'xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" ' +\n 'xmlns:w10=\"urn:schemas-microsoft-com:office:word\" ' +\n 'xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" ' +\n 'xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" ' +\n 'xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" ' +\n 'xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" ' +\n 'xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" ' +\n 'xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" ' +\n 'mc:Ignorable=\"w14 wp14\">';\n\n // Serialize top-level comments first, then replies\n for (const comment of topLevel) {\n xml += serializeComment(comment);\n }\n for (const reply of replies) {\n xml += serializeComment(reply);\n }\n\n xml += '</w:comments>';\n return xml;\n}\n","/**\n * XML Parser Utilities for OOXML\n *\n * Provides helper functions for parsing Office Open XML (OOXML) content\n * with proper namespace handling.\n *\n * OOXML uses many namespaces:\n * - w: WordprocessingML (main document content)\n * - a: DrawingML (graphics)\n * - r: Relationships\n * - wp: Word Drawing positioning\n * - wps: Word Drawing shapes\n * - wpc: Word Drawing canvas\n * - wpg: Word Drawing group\n * - m: Math\n * - mc: Markup Compatibility\n * - v: VML (legacy vector graphics)\n * - o: Office (extensions)\n * - pic: Pictures\n */\n\nimport { xml2js, js2xml, type Element as XmlElement } from 'xml-js';\n\n// Re-export Element type for consumers\nexport type { Element as XmlElement } from 'xml-js';\n\n/**\n * Common OOXML namespace URIs\n */\nexport const NAMESPACES = {\n // Main namespaces\n w: 'http://schemas.openxmlformats.org/wordprocessingml/2006/main',\n a: 'http://schemas.openxmlformats.org/drawingml/2006/main',\n r: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships',\n\n // Drawing namespaces\n wp: 'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing',\n wp14: 'http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing',\n wps: 'http://schemas.microsoft.com/office/word/2010/wordprocessingShape',\n wpc: 'http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas',\n wpg: 'http://schemas.microsoft.com/office/word/2010/wordprocessingGroup',\n\n // Picture namespace\n pic: 'http://schemas.openxmlformats.org/drawingml/2006/picture',\n\n // Math namespace\n m: 'http://schemas.openxmlformats.org/officeDocument/2006/math',\n\n // Markup Compatibility\n mc: 'http://schemas.openxmlformats.org/markup-compatibility/2006',\n\n // Legacy VML\n v: 'urn:schemas-microsoft-com:vml',\n o: 'urn:schemas-microsoft-com:office:office',\n\n // Other\n w14: 'http://schemas.microsoft.com/office/word/2010/wordml',\n w15: 'http://schemas.microsoft.com/office/word/2012/wordml',\n\n // Content Types\n ct: 'http://schemas.openxmlformats.org/package/2006/content-types',\n\n // Relationships\n pr: 'http://schemas.openxmlformats.org/package/2006/relationships',\n} as const;\n\n/**\n * Parse XML string into element tree\n *\n * @param xml - XML string to parse\n * @returns Parsed element tree\n */\nexport function parseXml(xml: string): XmlElement {\n const result = xml2js(xml, {\n compact: false,\n ignoreComment: true,\n ignoreInstruction: true,\n ignoreDoctype: true,\n alwaysArray: false,\n // IMPORTANT: Do NOT trim whitespace - it strips significant spaces\n // around hyperlinks and other inline elements. DOCX uses xml:space=\"preserve\"\n // to indicate significant whitespace, but we need to preserve all text as-is.\n trim: false,\n // IMPORTANT: Without this, xml-js silently drops whitespace-only text nodes\n // (e.g. <w:t xml:space=\"preserve\"> </w:t> loses the space).\n captureSpacesBetweenElements: true,\n attributesKey: 'attributes',\n textKey: 'text',\n }) as XmlElement;\n\n return result;\n}\n\n/**\n * Serialize an XmlElement back to an XML string\n */\nexport function elementToXml(element: XmlElement): string {\n return js2xml({ elements: [element] }, { compact: false, spaces: 0 });\n}\n\n/**\n * Parse XML string to a more convenient format\n */\nexport function parseXmlDocument(xml: string): XmlElement | null {\n try {\n const parsed = parseXml(xml);\n\n // The root is typically the declaration + elements array\n if (parsed.elements && parsed.elements.length > 0) {\n // Return the first real element (skip declarations)\n return parsed.elements.find((e) => e.type === 'element') ?? null;\n }\n\n return parsed;\n } catch (error) {\n console.warn('Failed to parse XML:', error);\n return null;\n }\n}\n\n/**\n * Get local name from a prefixed element name\n * e.g., \"w:p\" -> \"p\", \"a:graphic\" -> \"graphic\"\n */\nexport function getLocalName(name: string): string {\n const colonIndex = name.indexOf(':');\n return colonIndex >= 0 ? name.substring(colonIndex + 1) : name;\n}\n\n/**\n * Get namespace prefix from an element name\n * e.g., \"w:p\" -> \"w\", \"a:graphic\" -> \"a\"\n */\nexport function getNamespacePrefix(name: string): string | null {\n const colonIndex = name.indexOf(':');\n return colonIndex >= 0 ? name.substring(0, colonIndex) : null;\n}\n\n/**\n * Check if an element matches a given namespaced name\n *\n * @param element - Element to check\n * @param namespace - Namespace prefix (e.g., \"w\", \"a\")\n * @param localName - Local element name (e.g., \"p\", \"r\")\n */\nexport function matchesName(element: XmlElement, namespace: string, localName: string): boolean {\n if (!element.name) return false;\n\n const fullName = `${namespace}:${localName}`;\n if (element.name === fullName) return true;\n\n // Also check just the local name if no namespace prefix in element\n if (getLocalName(element.name) === localName) return true;\n\n return false;\n}\n\n/**\n * Find first child element matching the given namespaced name\n *\n * @param parent - Parent element\n * @param namespace - Namespace prefix (e.g., \"w\")\n * @param localName - Local element name (e.g., \"p\")\n * @returns First matching child or null\n */\nexport function findChild(\n parent: XmlElement | null | undefined,\n namespace: string,\n localName: string\n): XmlElement | null {\n if (!parent || !parent.elements) return null;\n\n const fullName = `${namespace}:${localName}`;\n\n for (const child of parent.elements) {\n if (child.type !== 'element') continue;\n\n if (child.name === fullName) {\n return child;\n }\n\n // Check local name match\n if (getLocalName(child.name || '') === localName) {\n return child;\n }\n }\n\n return null;\n}\n\n/**\n * Find all child elements matching the given namespaced name\n *\n * @param parent - Parent element\n * @param namespace - Namespace prefix\n * @param localName - Local element name\n * @returns Array of matching children\n */\nexport function findChildren(\n parent: XmlElement | null | undefined,\n namespace: string,\n localName: string\n): XmlElement[] {\n if (!parent || !parent.elements) return [];\n\n const fullName = `${namespace}:${localName}`;\n const results: XmlElement[] = [];\n\n for (const child of parent.elements) {\n if (child.type !== 'element') continue;\n\n if (child.name === fullName || getLocalName(child.name || '') === localName) {\n results.push(child);\n }\n }\n\n return results;\n}\n\n/**\n * Find first child element by local name only (ignoring namespace)\n *\n * @param parent - Parent element\n * @param localName - Local element name\n * @returns First matching child or null\n */\nexport function findChildByLocalName(\n parent: XmlElement | null | undefined,\n localName: string\n): XmlElement | null {\n if (!parent || !parent.elements) return null;\n\n for (const child of parent.elements) {\n if (child.type !== 'element') continue;\n\n if (getLocalName(child.name || '') === localName) {\n return child;\n }\n }\n\n return null;\n}\n\n/**\n * Find all child elements by local name only\n *\n * @param parent - Parent element\n * @param localName - Local element name\n * @returns Array of matching children\n */\nexport function findChildrenByLocalName(\n parent: XmlElement | null | undefined,\n localName: string\n): XmlElement[] {\n if (!parent || !parent.elements) return [];\n\n return parent.elements.filter(\n (child) => child.type === 'element' && getLocalName(child.name || '') === localName\n );\n}\n\n/**\n * Find first child element by full name (including namespace prefix)\n *\n * @param parent - Parent element\n * @param fullName - Full element name with namespace prefix (e.g., 'wp:extent')\n * @returns First matching child or null\n */\nexport function findByFullName(\n parent: XmlElement | null | undefined,\n fullName: string\n): XmlElement | null {\n if (!parent || !parent.elements) return null;\n\n for (const child of parent.elements) {\n if (child.type !== 'element') continue;\n if (child.name === fullName) return child;\n }\n\n return null;\n}\n\n/**\n * Get all child elements (excludes text nodes, etc.)\n *\n * @param parent - Parent element\n * @returns Array of child elements\n */\nexport function getChildElements(parent: XmlElement | null | undefined): XmlElement[] {\n if (!parent || !parent.elements) return [];\n return parent.elements.filter((child) => child.type === 'element');\n}\n\n/**\n * Get an attribute value from an element\n *\n * @param element - Element to get attribute from\n * @param namespace - Namespace prefix for the attribute (or null for no namespace)\n * @param name - Attribute name\n * @returns Attribute value or null if not found\n */\nexport function getAttribute(\n element: XmlElement | null | undefined,\n namespace: string | null,\n name: string\n): string | null {\n if (!element || !element.attributes) return null;\n\n const attrs = element.attributes as Record<string, string>;\n\n // Try with namespace prefix first\n if (namespace) {\n const prefixedName = `${namespace}:${name}`;\n if (prefixedName in attrs) {\n return attrs[prefixedName];\n }\n }\n\n // Try without namespace\n if (name in attrs) {\n return attrs[name];\n }\n\n return null;\n}\n\n/**\n * Get an attribute value, trying multiple possible names\n *\n * @param element - Element to get attribute from\n * @param names - Array of possible attribute names (with or without namespace)\n * @returns First found attribute value or null\n */\nexport function getAttributeAny(\n element: XmlElement | null | undefined,\n names: string[]\n): string | null {\n if (!element || !element.attributes) return null;\n\n const attrs = element.attributes as Record<string, string>;\n\n for (const name of names) {\n if (name in attrs) {\n return attrs[name];\n }\n }\n\n return null;\n}\n\n/**\n * Get all attributes from an element\n *\n * @param element - Element to get attributes from\n * @returns Record of attribute name -> value\n */\nexport function getAttributes(element: XmlElement | null | undefined): Record<string, string> {\n if (!element || !element.attributes) return {};\n return element.attributes as Record<string, string>;\n}\n\n/**\n * Get the text content of an element (concatenates all text nodes)\n *\n * @param element - Element to get text from\n * @returns Text content or empty string\n */\nexport function getTextContent(element: XmlElement | null | undefined): string {\n if (!element) return '';\n\n // Check for direct text property\n if ('text' in element && typeof element.text === 'string') {\n return element.text;\n }\n\n // Check elements array for text nodes\n if (!element.elements) return '';\n\n let text = '';\n for (const child of element.elements) {\n if (child.type === 'text' && 'text' in child) {\n text += child.text ?? '';\n } else if (child.type === 'element') {\n // Recurse into child elements\n text += getTextContent(child);\n }\n }\n\n return text;\n}\n\n/**\n * Check if an element has a specific attribute with value \"true\" or \"1\"\n *\n * @param element - Element to check\n * @param namespace - Attribute namespace\n * @param name - Attribute name\n * @returns true if attribute exists and is truthy\n */\nexport function hasFlag(\n element: XmlElement | null | undefined,\n namespace: string | null,\n name: string\n): boolean {\n const value = getAttribute(element, namespace, name);\n\n // In OOXML, presence of element often means true, absence means false\n // If value is null, check if the element itself exists\n if (value === null) {\n return false;\n }\n\n // Explicitly false\n if (value === '0' || value === 'false' || value === 'off') {\n return false;\n }\n\n // Any other value (including \"1\", \"true\", \"on\", or empty string) means true\n return true;\n}\n\n/**\n * Check if a child element exists (used for boolean flags in OOXML)\n *\n * @param parent - Parent element\n * @param namespace - Namespace prefix\n * @param localName - Local element name\n * @returns true if child element exists\n */\nexport function hasChild(\n parent: XmlElement | null | undefined,\n namespace: string,\n localName: string\n): boolean {\n return findChild(parent, namespace, localName) !== null;\n}\n\n/**\n * Parse an OOXML color value\n *\n * @param element - Color element (e.g., w:color)\n * @returns Object with val, themeColor, themeTint, themeShade\n */\nexport function parseColorElement(element: XmlElement | null | undefined): {\n val?: string;\n themeColor?: string;\n themeTint?: string;\n themeShade?: string;\n} | null {\n if (!element) return null;\n\n return {\n val: getAttribute(element, 'w', 'val') ?? undefined,\n themeColor: getAttribute(element, 'w', 'themeColor') ?? undefined,\n themeTint: getAttribute(element, 'w', 'themeTint') ?? undefined,\n themeShade: getAttribute(element, 'w', 'themeShade') ?? undefined,\n };\n}\n\n/**\n * Parse a numeric value from an attribute, with optional scale\n *\n * @param element - Element containing the attribute\n * @param namespace - Attribute namespace\n * @param name - Attribute name\n * @param scale - Optional scale factor (e.g., 20 for twips to points)\n * @returns Parsed number or undefined\n */\nexport function parseNumericAttribute(\n element: XmlElement | null | undefined,\n namespace: string | null,\n name: string,\n scale: number = 1\n): number | undefined {\n const value = getAttribute(element, namespace, name);\n if (value === null) return undefined;\n\n const num = parseInt(value, 10);\n if (isNaN(num)) return undefined;\n\n return num * scale;\n}\n\n/**\n * Parse a boolean value from an attribute or element presence\n *\n * OOXML boolean conventions:\n * - Element presence with no val attribute = true\n * - w:val=\"true\" or w:val=\"1\" = true\n * - w:val=\"false\" or w:val=\"0\" = false\n *\n * @param element - Element to check\n * @param namespace - Namespace for val attribute\n * @returns boolean value\n */\nexport function parseBooleanElement(\n element: XmlElement | null | undefined,\n namespace: string = 'w'\n): boolean {\n if (!element) return false;\n\n const val = getAttribute(element, namespace, 'val');\n\n // No val attribute = true (element presence implies true)\n if (val === null) return true;\n\n // Explicit false values\n if (val === '0' || val === 'false' || val === 'off') {\n return false;\n }\n\n return true;\n}\n\n/**\n * Deep find - search recursively for an element\n *\n * @param root - Root element to search from\n * @param namespace - Namespace prefix\n * @param localName - Local element name\n * @returns First matching element found or null\n */\nexport function findDeep(\n root: XmlElement | null | undefined,\n namespace: string,\n localName: string\n): XmlElement | null {\n if (!root) return null;\n\n // Check if this element matches\n if (matchesName(root, namespace, localName)) {\n return root;\n }\n\n // Search children\n if (root.elements) {\n for (const child of root.elements) {\n if (child.type !== 'element') continue;\n\n const found = findDeep(child, namespace, localName);\n if (found) return found;\n }\n }\n\n return null;\n}\n\n/**\n * Find all elements matching name, searching recursively\n *\n * @param root - Root element to search from\n * @param namespace - Namespace prefix\n * @param localName - Local element name\n * @returns Array of all matching elements\n */\nexport function findAllDeep(\n root: XmlElement | null | undefined,\n namespace: string,\n localName: string\n): XmlElement[] {\n const results: XmlElement[] = [];\n\n function search(element: XmlElement | null | undefined): void {\n if (!element) return;\n\n if (matchesName(element, namespace, localName)) {\n results.push(element);\n }\n\n if (element.elements) {\n for (const child of element.elements) {\n if (child.type === 'element') {\n search(child);\n }\n }\n }\n }\n\n search(root);\n return results;\n}\n","/**\n * Relationship Parser\n *\n * Parses .rels files from DOCX packages to map relationship IDs (rId)\n * to their targets (images, hyperlinks, headers, footers, etc.).\n *\n * .rels files are XML with structure:\n * <Relationships xmlns=\"...\">\n * <Relationship Id=\"rId1\" Type=\"...\" Target=\"...\" TargetMode=\"External|Internal\"/>\n * </Relationships>\n *\n * Key relationship types:\n * - image: Embedded images (word/media/*)\n * - hyperlink: External URLs (TargetMode=\"External\")\n * - header: Header XML files\n * - footer: Footer XML files\n * - footnotes: Footnotes XML\n * - endnotes: Endnotes XML\n * - styles: styles.xml\n * - numbering: numbering.xml\n * - fontTable: fontTable.xml\n * - theme: theme/theme1.xml\n */\n\nimport { parseXmlDocument, getChildElements, getAttribute } from './xmlParser';\nimport type { Relationship, RelationshipMap, RelationshipType } from '../types';\n\n/**\n * Relationship type constants for common types\n */\nexport const RELATIONSHIP_TYPES = {\n image: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',\n hyperlink: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',\n header: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/header',\n footer: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer',\n footnotes: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes',\n endnotes: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes',\n styles: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles',\n numbering: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering',\n fontTable: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable',\n theme: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme',\n settings: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings',\n webSettings: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings',\n oleObject: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject',\n chart: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart',\n diagramData: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramData',\n officeDocument:\n 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument',\n coreProperties:\n 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties',\n extendedProperties:\n 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties',\n customProperties:\n 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties',\n customXml: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml',\n comments: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments',\n} as const;\n\n/**\n * Parse a .rels XML file into a RelationshipMap\n *\n * @param relsXml - XML content of a .rels file\n * @returns Map of relationship ID to Relationship object\n */\nexport function parseRelationships(relsXml: string): RelationshipMap {\n const map: RelationshipMap = new Map();\n\n if (!relsXml || relsXml.trim().length === 0) {\n return map;\n }\n\n const root = parseXmlDocument(relsXml);\n if (!root) {\n console.warn('Failed to parse relationships XML');\n return map;\n }\n\n // Get all Relationship elements\n const children = getChildElements(root);\n\n for (const child of children) {\n // Check if this is a Relationship element\n const name = child.name || '';\n if (!name.endsWith('Relationship') && !name.includes(':Relationship')) {\n continue;\n }\n\n // Extract attributes\n const id = getAttribute(child, null, 'Id');\n const type = getAttribute(child, null, 'Type');\n const target = getAttribute(child, null, 'Target');\n const targetMode = getAttribute(child, null, 'TargetMode');\n\n if (!id || !type || !target) {\n console.warn('Relationship missing required attributes:', { id, type, target });\n continue;\n }\n\n const relationship: Relationship = {\n id,\n type: type as RelationshipType,\n target,\n };\n\n if (targetMode === 'External') {\n relationship.targetMode = 'External';\n } else if (targetMode === 'Internal') {\n relationship.targetMode = 'Internal';\n }\n // If not specified, default is Internal (we don't set it explicitly)\n\n map.set(id, relationship);\n }\n\n return map;\n}\n\n/**\n * Get the short type name from a full relationship type URI\n *\n * @param typeUri - Full relationship type URI\n * @returns Short type name (e.g., \"image\", \"hyperlink\") or \"unknown\"\n */\nexport function getRelationshipTypeName(typeUri: string): string {\n for (const [name, uri] of Object.entries(RELATIONSHIP_TYPES)) {\n if (uri === typeUri) {\n return name;\n }\n }\n\n // Try to extract from URI\n const lastSlash = typeUri.lastIndexOf('/');\n if (lastSlash >= 0) {\n return typeUri.substring(lastSlash + 1);\n }\n\n return 'unknown';\n}\n\n/**\n * Check if a relationship type is an external link (hyperlink)\n *\n * @param rel - Relationship to check\n * @returns true if this is an external hyperlink\n */\nexport function isExternalHyperlink(rel: Relationship): boolean {\n return rel.type === RELATIONSHIP_TYPES.hyperlink && rel.targetMode === 'External';\n}\n\n/**\n * Check if a relationship type is an image\n *\n * @param rel - Relationship to check\n * @returns true if this is an image relationship\n */\nexport function isImageRelationship(rel: Relationship): boolean {\n return rel.type === RELATIONSHIP_TYPES.image;\n}\n\n/**\n * Check if a relationship type is a header\n *\n * @param rel - Relationship to check\n * @returns true if this is a header relationship\n */\nexport function isHeaderRelationship(rel: Relationship): boolean {\n return rel.type === RELATIONSHIP_TYPES.header;\n}\n\n/**\n * Check if a relationship type is a footer\n *\n * @param rel - Relationship to check\n * @returns true if this is a footer relationship\n */\nexport function isFooterRelationship(rel: Relationship): boolean {\n return rel.type === RELATIONSHIP_TYPES.footer;\n}\n\n/**\n * Filter relationships by type\n *\n * @param map - RelationshipMap to filter\n * @param type - Relationship type URI to filter by\n * @returns Array of matching relationships\n */\nexport function filterByType(map: RelationshipMap, type: RelationshipType): Relationship[] {\n const results: Relationship[] = [];\n for (const rel of map.values()) {\n if (rel.type === type) {\n results.push(rel);\n }\n }\n return results;\n}\n\n/**\n * Get all images from a relationship map\n *\n * @param map - RelationshipMap to search\n * @returns Array of image relationships\n */\nexport function getImages(map: RelationshipMap): Relationship[] {\n return filterByType(map, RELATIONSHIP_TYPES.image);\n}\n\n/**\n * Get all hyperlinks from a relationship map\n *\n * @param map - RelationshipMap to search\n * @returns Array of hyperlink relationships\n */\nexport function getHyperlinks(map: RelationshipMap): Relationship[] {\n return filterByType(map, RELATIONSHIP_TYPES.hyperlink);\n}\n\n/**\n * Get all headers from a relationship map\n *\n * @param map - RelationshipMap to search\n * @returns Array of header relationships\n */\nexport function getHeaders(map: RelationshipMap): Relationship[] {\n return filterByType(map, RELATIONSHIP_TYPES.header);\n}\n\n/**\n * Get all footers from a relationship map\n *\n * @param map - RelationshipMap to search\n * @returns Array of footer relationships\n */\nexport function getFooters(map: RelationshipMap): Relationship[] {\n return filterByType(map, RELATIONSHIP_TYPES.footer);\n}\n\n/**\n * Resolve a relationship ID to a target path\n *\n * @param map - RelationshipMap to search\n * @param rId - Relationship ID (e.g., \"rId1\")\n * @returns Target path or undefined if not found\n */\nexport function resolveTarget(map: RelationshipMap, rId: string): string | undefined {\n const rel = map.get(rId);\n return rel?.target;\n}\n\n/**\n * Resolve a relationship ID to a full relationship\n *\n * @param map - RelationshipMap to search\n * @param rId - Relationship ID (e.g., \"rId1\")\n * @returns Relationship or undefined if not found\n */\nexport function resolveRelationship(map: RelationshipMap, rId: string): Relationship | undefined {\n return map.get(rId);\n}\n\n/**\n * Resolve a relative target path to an absolute path within the DOCX\n *\n * For example, if basePath is \"word/_rels/document.xml.rels\" and\n * target is \"media/image1.png\", the result is \"word/media/image1.png\"\n *\n * @param basePath - Path of the .rels file\n * @param target - Relative target from the relationship\n * @returns Absolute path within the DOCX\n */\nexport function resolveRelativePath(basePath: string, target: string): string {\n // If target starts with /, it's already absolute\n if (target.startsWith('/')) {\n return target.substring(1); // Remove leading /\n }\n\n // Get the directory of the .rels file\n // e.g., \"word/_rels/document.xml.rels\" -> \"word/_rels\"\n const lastSlash = basePath.lastIndexOf('/');\n let directory = lastSlash >= 0 ? basePath.substring(0, lastSlash) : '';\n\n // The .rels file is in _rels subdirectory, go up one level\n // e.g., \"word/_rels\" -> \"word\"\n if (directory.endsWith('/_rels')) {\n directory = directory.substring(0, directory.length - 6);\n } else if (directory === '_rels') {\n directory = '';\n }\n\n // Handle ../ in target\n const parts = target.split('/');\n const dirParts = directory ? directory.split('/') : [];\n\n for (const part of parts) {\n if (part === '..') {\n dirParts.pop();\n } else if (part !== '.') {\n dirParts.push(part);\n }\n }\n\n return dirParts.join('/');\n}\n\n/**\n * Parse document.xml.rels specifically\n *\n * This is a convenience wrapper for the main document relationships.\n *\n * @param relsXml - XML content of word/_rels/document.xml.rels\n * @returns RelationshipMap\n */\nexport function parseDocumentRelationships(relsXml: string): RelationshipMap {\n return parseRelationships(relsXml);\n}\n\n/**\n * Parse package-level .rels\n *\n * This is a convenience wrapper for the package relationships (_rels/.rels)\n *\n * @param relsXml - XML content of _rels/.rels\n * @returns RelationshipMap\n */\nexport function parsePackageRelationships(relsXml: string): RelationshipMap {\n return parseRelationships(relsXml);\n}\n\n/**\n * Debug: Print all relationships in a map\n *\n * @param map - RelationshipMap to print\n */\nexport function printRelationships(map: RelationshipMap): void {\n /* eslint-disable no-console */\n console.log('Relationships:');\n for (const [id, rel] of map.entries()) {\n const typeName = getRelationshipTypeName(rel.type);\n console.log(\n ` ${id}: ${typeName} -> ${rel.target}${rel.targetMode === 'External' ? ' (External)' : ''}`\n );\n }\n /* eslint-enable no-console */\n}\n","/**\n * DOCX Repacker - Repack modified document into valid DOCX\n *\n * Takes a Document with modified content and creates a new DOCX file\n * by updating document.xml while preserving all other files from\n * the original ZIP archive.\n *\n * This ensures round-trip fidelity:\n * - styles.xml, theme1.xml, fontTable.xml remain untouched\n * - Media files preserved\n * - Relationships preserved\n * - Only document.xml is updated with new content\n *\n * OOXML Package Structure:\n * - [Content_Types].xml - Content type declarations\n * - _rels/.rels - Package relationships\n * - word/document.xml - Main document (modified)\n * - word/styles.xml - Styles (preserved)\n * - word/theme/theme1.xml - Theme (preserved)\n * - word/numbering.xml - Numbering (preserved)\n * - word/fontTable.xml - Font table (preserved)\n * - word/settings.xml - Settings (preserved)\n * - word/header*.xml - Headers (preserved)\n * - word/footer*.xml - Footers (preserved)\n * - word/footnotes.xml - Footnotes (preserved)\n * - word/endnotes.xml - Endnotes (preserved)\n * - word/media/* - Media files (preserved)\n * - word/_rels/document.xml.rels - Document relationships (preserved)\n * - docProps/* - Document properties (preserved)\n */\n\nimport JSZip from 'jszip';\nimport type { Document } from '../types/document';\nimport type { BlockContent, Image, Hyperlink } from '../types/content';\nimport { serializeDocument } from './serializer/documentSerializer';\nimport { serializeHeaderFooter } from './serializer/headerFooterSerializer';\nimport { serializeComments } from './serializer/commentSerializer';\nimport { RELATIONSHIP_TYPES } from './relsParser';\nimport { type RawDocxContent } from './unzip';\nimport { escapeXml } from './serializer/xmlUtils';\n\n/**\n * Find the highest rId number in a relationships XML string.\n */\nexport function findMaxRId(relsXml: string): number {\n let maxId = 0;\n for (const match of relsXml.matchAll(/Id=\"rId(\\d+)\"/g)) {\n const id = parseInt(match[1], 10);\n if (id > maxId) maxId = id;\n }\n return maxId;\n}\n\n// ============================================================================\n// COMMENTS SERIALIZATION\n// ============================================================================\n\nasync function serializeCommentsToZip(\n doc: Document,\n zip: JSZip,\n compressionLevel: number\n): Promise<void> {\n const comments = doc.package.document.comments;\n if (!comments || comments.length === 0) return;\n\n const commentsXml = serializeComments(comments);\n zip.file('word/comments.xml', commentsXml, {\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n\n await Promise.all([\n ensureCommentsContentType(zip, compressionLevel),\n ensureCommentsRelationship(zip, compressionLevel),\n ]);\n}\n\n// ============================================================================\n// NEW IMAGE HANDLING\n// ============================================================================\n\n/**\n * Collect all images with data-URL src from the document content.\n * These are newly inserted images that need to be added to the ZIP.\n */\nfunction collectNewImages(blocks: BlockContent[]): Image[] {\n const images: Image[] = [];\n\n for (const block of blocks) {\n if (block.type === 'paragraph') {\n for (const item of block.content) {\n if (item.type === 'run') {\n for (const c of item.content) {\n if (c.type === 'drawing' && c.image.src?.startsWith('data:')) {\n images.push(c.image);\n }\n }\n }\n }\n } else if (block.type === 'table') {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n images.push(...collectNewImages(cell.content));\n }\n }\n }\n }\n\n return images;\n}\n\n/** Map MIME type to file extension (inverse of getContentTypeForExtension) */\nconst MIME_TO_EXT: Record<string, string> = {\n 'image/png': 'png',\n 'image/jpeg': 'jpeg',\n 'image/gif': 'gif',\n 'image/bmp': 'bmp',\n 'image/tiff': 'tiff',\n 'image/webp': 'webp',\n 'image/svg+xml': 'svg',\n};\n\n/**\n * Decode a data URL to binary ArrayBuffer and file extension.\n */\nfunction decodeDataUrl(dataUrl: string): { data: ArrayBuffer; extension: string } {\n const match = dataUrl.match(/^data:([^;]+);base64,(.+)$/);\n if (!match) {\n throw new Error('Invalid data URL');\n }\n\n const binary = atob(match[2]);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n\n return { data: bytes.buffer, extension: MIME_TO_EXT[match[1]] || 'png' };\n}\n\n/**\n * Process newly inserted images: add binary data to ZIP, create relationships,\n * update content types, and rewrite rIds in the document model so the serializer\n * outputs correct references.\n *\n * Mutates the images' rId fields in-place.\n */\nasync function processNewImages(\n newImages: Image[],\n zip: JSZip,\n compressionLevel: number\n): Promise<void> {\n if (newImages.length === 0) return;\n\n // Read existing relationships\n const relsPath = 'word/_rels/document.xml.rels';\n const relsFile = zip.file(relsPath);\n if (!relsFile) return;\n let relsXml = await relsFile.async('text');\n\n // Find highest existing rId\n let maxId = findMaxRId(relsXml);\n\n // Find highest existing image number in word/media/\n let maxImageNum = 0;\n zip.forEach((relativePath) => {\n const m = relativePath.match(/^word\\/media\\/image(\\d+)\\./);\n if (m) {\n const num = parseInt(m[1], 10);\n if (num > maxImageNum) maxImageNum = num;\n }\n });\n\n const relEntries: string[] = [];\n const extensionsAdded = new Set<string>();\n\n for (const image of newImages) {\n const { data, extension } = decodeDataUrl(image.src!);\n\n maxImageNum++;\n maxId++;\n const mediaFilename = `image${maxImageNum}.${extension}`;\n const mediaPath = `word/media/${mediaFilename}`;\n const newRId = `rId${maxId}`;\n\n // Add binary to ZIP\n zip.file(mediaPath, data, {\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n\n // Build relationship entry\n relEntries.push(\n `<Relationship Id=\"${newRId}\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/${mediaFilename}\"/>`\n );\n\n extensionsAdded.add(extension);\n\n // Rewrite the image's rId so the serializer outputs the correct reference\n image.rId = newRId;\n }\n\n // Update relationships XML\n if (relEntries.length > 0) {\n relsXml = relsXml.replace('</Relationships>', relEntries.join('') + '</Relationships>');\n zip.file(relsPath, relsXml, {\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n }\n\n // Update [Content_Types].xml if new extensions were added\n if (extensionsAdded.size > 0) {\n const ctFile = zip.file('[Content_Types].xml');\n if (ctFile) {\n let ctXml = await ctFile.async('text');\n for (const ext of extensionsAdded) {\n if (!ctXml.includes(`Extension=\"${ext}\"`)) {\n const contentType = getContentTypeForExtension(ext, '');\n ctXml = ctXml.replace(\n '</Types>',\n `<Default Extension=\"${ext}\" ContentType=\"${contentType}\"/></Types>`\n );\n }\n }\n zip.file('[Content_Types].xml', ctXml, {\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n }\n }\n}\n\n// ============================================================================\n// NEW HYPERLINK HANDLING\n// ============================================================================\n\n/**\n * Collect all hyperlinks that have an href but no rId from block content.\n * These are newly created hyperlinks that need relationship entries.\n */\nfunction collectHyperlinksWithoutRId(blocks: BlockContent[]): Hyperlink[] {\n const hyperlinks: Hyperlink[] = [];\n\n for (const block of blocks) {\n if (block.type === 'paragraph') {\n for (const item of block.content) {\n if (item.type === 'hyperlink' && item.href && !item.rId && !item.anchor) {\n hyperlinks.push(item);\n }\n }\n } else if (block.type === 'table') {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n hyperlinks.push(...collectHyperlinksWithoutRId(cell.content));\n }\n }\n }\n }\n\n return hyperlinks;\n}\n\n/**\n * Process newly created hyperlinks: assign rIds and add relationship entries.\n * Mutates the hyperlinks' rId fields in-place.\n */\nasync function processNewHyperlinks(\n newHyperlinks: Hyperlink[],\n zip: JSZip,\n compressionLevel: number\n): Promise<void> {\n if (newHyperlinks.length === 0) return;\n\n const relsPath = 'word/_rels/document.xml.rels';\n const relsFile = zip.file(relsPath);\n if (!relsFile) return;\n let relsXml = await relsFile.async('text');\n\n let maxId = findMaxRId(relsXml);\n const relEntries: string[] = [];\n\n for (const hyperlink of newHyperlinks) {\n maxId++;\n const newRId = `rId${maxId}`;\n\n relEntries.push(\n `<Relationship Id=\"${newRId}\" Type=\"${RELATIONSHIP_TYPES.hyperlink}\" Target=\"${escapeXml(hyperlink.href!)}\" TargetMode=\"External\"/>`\n );\n\n // Rewrite the hyperlink's rId so the serializer outputs the correct reference\n hyperlink.rId = newRId;\n }\n\n if (relEntries.length > 0) {\n relsXml = relsXml.replace('</Relationships>', relEntries.join('') + '</Relationships>');\n zip.file(relsPath, relsXml, {\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n }\n}\n\n// ============================================================================\n// MAIN REPACKER\n// ============================================================================\n\n/**\n * Options for repacking DOCX\n */\nexport interface RepackOptions {\n /** Compression level (0-9, default: 6) */\n compressionLevel?: number;\n /** Whether to update modification date in docProps/core.xml */\n updateModifiedDate?: boolean;\n /** Custom modifier name for lastModifiedBy */\n modifiedBy?: string;\n}\n\n/**\n * Repack a Document into a valid DOCX file\n *\n * @param doc - Document with modified content\n * @param options - Optional repack options\n * @returns Promise resolving to DOCX as ArrayBuffer\n * @throws Error if document has no original buffer for round-trip\n */\nexport async function repackDocx(doc: Document, options: RepackOptions = {}): Promise<ArrayBuffer> {\n // Validate we have an original buffer to base on\n if (!doc.originalBuffer) {\n throw new Error(\n 'Cannot repack document: no original buffer for round-trip. ' +\n 'Use createDocx() for new documents.'\n );\n }\n\n const { compressionLevel = 6, updateModifiedDate = true, modifiedBy } = options;\n const exportDocument = doc;\n\n // Load the original ZIP\n const originalZip = await JSZip.loadAsync(doc.originalBuffer);\n\n // Create a new ZIP with all original files\n const newZip = new JSZip();\n\n // Copy all files from original ZIP\n for (const [path, file] of Object.entries(originalZip.files)) {\n // Skip directories\n if (file.dir) {\n newZip.folder(path.replace(/\\/$/, ''));\n continue;\n }\n\n // Get original file content\n const content = await file.async('arraybuffer');\n\n // Add to new ZIP (we'll update specific files below)\n newZip.file(path, content, {\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n }\n\n // Process newly inserted images (data URLs → binary media files + relationships).\n // This mutates image rIds in-place so the serializer outputs correct references.\n const newImages = collectNewImages(exportDocument.package.document.content);\n await processNewImages(newImages, newZip, compressionLevel);\n\n // Process newly created hyperlinks (assign rIds + add relationship entries).\n // This mutates hyperlink rIds in-place so the serializer outputs correct references.\n const newHyperlinks = collectHyperlinksWithoutRId(exportDocument.package.document.content);\n await processNewHyperlinks(newHyperlinks, newZip, compressionLevel);\n\n // Serialize and update document.xml (after image/hyperlink rIds have been rewritten)\n const documentXml = serializeDocument(exportDocument);\n newZip.file('word/document.xml', documentXml, {\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n\n // Serialize and update modified headers/footers\n serializeHeadersFootersToZip(exportDocument, newZip, compressionLevel);\n\n // Serialize comments\n await serializeCommentsToZip(exportDocument, newZip, compressionLevel);\n\n // Optionally update modification date in docProps/core.xml\n if (updateModifiedDate) {\n const corePropsPath = 'docProps/core.xml';\n const corePropsFile = originalZip.file(corePropsPath);\n\n if (corePropsFile) {\n const originalCoreProps = await corePropsFile.async('text');\n const updatedCoreProps = updateCoreProperties(originalCoreProps, {\n updateModifiedDate,\n modifiedBy,\n });\n\n newZip.file(corePropsPath, updatedCoreProps, {\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n }\n }\n\n // Generate the new DOCX file\n const arrayBuffer = await newZip.generateAsync({\n type: 'arraybuffer',\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n\n return arrayBuffer;\n}\n\n/**\n * Repack a Document using raw content for more control\n *\n * @param doc - Document with modified content\n * @param rawContent - Original raw content from unzipDocx\n * @param options - Optional repack options\n * @returns Promise resolving to DOCX as ArrayBuffer\n */\nexport async function repackDocxFromRaw(\n doc: Document,\n rawContent: RawDocxContent,\n options: RepackOptions = {}\n): Promise<ArrayBuffer> {\n const { compressionLevel = 6, updateModifiedDate = true, modifiedBy } = options;\n const exportDocument = doc;\n\n // Create a new ZIP with all original files\n const newZip = new JSZip();\n\n // Copy all files from original ZIP\n for (const [path, file] of Object.entries(rawContent.originalZip.files)) {\n // Skip directories\n if (file.dir) {\n newZip.folder(path.replace(/\\/$/, ''));\n continue;\n }\n\n // Get original file content\n const content = await file.async('arraybuffer');\n\n // Add to new ZIP\n newZip.file(path, content, {\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n }\n\n // Serialize and update document.xml\n const newImages = collectNewImages(exportDocument.package.document.content);\n await processNewImages(newImages, newZip, compressionLevel);\n\n const newHyperlinks = collectHyperlinksWithoutRId(exportDocument.package.document.content);\n await processNewHyperlinks(newHyperlinks, newZip, compressionLevel);\n\n const documentXml = serializeDocument(exportDocument);\n newZip.file('word/document.xml', documentXml, {\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n\n // Serialize and update modified headers/footers\n serializeHeadersFootersToZip(exportDocument, newZip, compressionLevel);\n\n // Serialize comments\n await serializeCommentsToZip(exportDocument, newZip, compressionLevel);\n\n // Optionally update core properties\n if (updateModifiedDate && rawContent.corePropsXml) {\n const updatedCoreProps = updateCoreProperties(rawContent.corePropsXml, {\n updateModifiedDate,\n modifiedBy,\n });\n\n newZip.file('docProps/core.xml', updatedCoreProps, {\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n }\n\n // Generate the new DOCX file\n const arrayBuffer = await newZip.generateAsync({\n type: 'arraybuffer',\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n\n return arrayBuffer;\n}\n\n// ============================================================================\n// COMMENT PACKAGING HELPERS\n// ============================================================================\n\nexport const COMMENTS_CONTENT_TYPE =\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml';\n\n/**\n * Ensure [Content_Types].xml contains an Override for word/comments.xml.\n * If the document already had comments, this is a no-op.\n */\nasync function ensureCommentsContentType(zip: JSZip, compressionLevel: number): Promise<void> {\n const ctFile = zip.file('[Content_Types].xml');\n if (!ctFile) return;\n\n let ctXml = await ctFile.async('text');\n if (ctXml.includes('/word/comments.xml')) return;\n\n // Insert before closing </Types>\n ctXml = ctXml.replace(\n '</Types>',\n `<Override PartName=\"/word/comments.xml\" ContentType=\"${COMMENTS_CONTENT_TYPE}\"/></Types>`\n );\n zip.file('[Content_Types].xml', ctXml, {\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n}\n\n/**\n * Ensure word/_rels/document.xml.rels contains a Relationship for comments.xml.\n * If the document already had comments, this is a no-op.\n */\nasync function ensureCommentsRelationship(zip: JSZip, compressionLevel: number): Promise<void> {\n const relsPath = 'word/_rels/document.xml.rels';\n const relsFile = zip.file(relsPath);\n if (!relsFile) return;\n\n let relsXml = await relsFile.async('text');\n if (relsXml.includes('comments.xml')) return;\n\n // Generate a unique rId\n const newRId = `rId${findMaxRId(relsXml) + 1}`;\n\n relsXml = relsXml.replace(\n '</Relationships>',\n `<Relationship Id=\"${newRId}\" Type=\"${RELATIONSHIP_TYPES.comments}\" Target=\"comments.xml\"/></Relationships>`\n );\n zip.file(relsPath, relsXml, {\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n}\n\n// ============================================================================\n// SELECTIVE UPDATES\n// ============================================================================\n\n/**\n * Update only document.xml in a DOCX buffer (minimal changes)\n *\n * @param originalBuffer - Original DOCX as ArrayBuffer\n * @param newDocumentXml - New document.xml content\n * @param options - Optional repack options\n * @returns Promise resolving to DOCX as ArrayBuffer\n */\nexport async function updateDocumentXml(\n originalBuffer: ArrayBuffer,\n newDocumentXml: string,\n options: RepackOptions = {}\n): Promise<ArrayBuffer> {\n const { compressionLevel = 6 } = options;\n\n // Load original ZIP\n const zip = await JSZip.loadAsync(originalBuffer);\n\n // Update document.xml\n zip.file('word/document.xml', newDocumentXml, {\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n\n // Generate new DOCX\n return zip.generateAsync({\n type: 'arraybuffer',\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n}\n\n/**\n * Update a specific XML file in a DOCX buffer\n *\n * @param originalBuffer - Original DOCX as ArrayBuffer\n * @param path - Path within the ZIP (e.g., \"word/styles.xml\")\n * @param content - New XML content\n * @param options - Optional repack options\n * @returns Promise resolving to DOCX as ArrayBuffer\n */\nexport async function updateXmlFile(\n originalBuffer: ArrayBuffer,\n path: string,\n content: string,\n options: RepackOptions = {}\n): Promise<ArrayBuffer> {\n const { compressionLevel = 6 } = options;\n\n const zip = await JSZip.loadAsync(originalBuffer);\n\n zip.file(path, content, {\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n\n return zip.generateAsync({\n type: 'arraybuffer',\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n}\n\n/**\n * Update multiple files in a DOCX buffer\n *\n * @param originalBuffer - Original DOCX as ArrayBuffer\n * @param updates - Map of path -> content for files to update\n * @param options - Optional repack options\n * @returns Promise resolving to DOCX as ArrayBuffer\n */\nexport async function updateMultipleFiles(\n originalBuffer: ArrayBuffer,\n updates: Map<string, string | ArrayBuffer>,\n options: RepackOptions = {}\n): Promise<ArrayBuffer> {\n const zip = await JSZip.loadAsync(originalBuffer);\n return applyUpdatesToZip(zip, updates, options);\n}\n\n/**\n * Apply file updates to an already-loaded JSZip instance and generate the output.\n * Use this when the zip is already loaded to avoid a redundant decompression pass.\n */\nexport async function applyUpdatesToZip(\n zip: JSZip,\n updates: Map<string, string | ArrayBuffer>,\n options: RepackOptions = {}\n): Promise<ArrayBuffer> {\n const { compressionLevel = 6 } = options;\n\n for (const [path, content] of updates) {\n zip.file(path, content, {\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n }\n\n return zip.generateAsync({\n type: 'arraybuffer',\n compression: 'DEFLATE',\n compressionOptions: { level: compressionLevel },\n });\n}\n\n// ============================================================================\n// RELATIONSHIP MANAGEMENT\n// ============================================================================\n\n/**\n * Add a new relationship to document.xml.rels\n *\n * @param originalBuffer - Original DOCX as ArrayBuffer\n * @param relationship - New relationship to add\n * @returns Promise resolving to { buffer: ArrayBuffer, rId: string }\n */\nexport async function addRelationship(\n originalBuffer: ArrayBuffer,\n relationship: {\n type: string;\n target: string;\n targetMode?: 'External' | 'Internal';\n }\n): Promise<{ buffer: ArrayBuffer; rId: string }> {\n const zip = await JSZip.loadAsync(originalBuffer);\n\n // Read existing relationships\n const relsPath = 'word/_rels/document.xml.rels';\n const relsFile = zip.file(relsPath);\n\n if (!relsFile) {\n throw new Error('document.xml.rels not found in DOCX');\n }\n\n const relsXml = await relsFile.async('text');\n\n // Generate new rId\n const newRId = `rId${findMaxRId(relsXml) + 1}`;\n\n // Build new relationship element\n const targetModeAttr = relationship.targetMode === 'External' ? ' TargetMode=\"External\"' : '';\n\n const newRelElement = `<Relationship Id=\"${newRId}\" Type=\"${relationship.type}\" Target=\"${escapeXml(relationship.target)}\"${targetModeAttr}/>`;\n\n // Insert before closing tag\n const updatedRelsXml = relsXml.replace('</Relationships>', `${newRelElement}</Relationships>`);\n\n // Update the ZIP\n zip.file(relsPath, updatedRelsXml);\n\n const buffer = await zip.generateAsync({\n type: 'arraybuffer',\n compression: 'DEFLATE',\n compressionOptions: { level: 6 },\n });\n\n return { buffer, rId: newRId };\n}\n\n/**\n * Add a media file to the DOCX\n *\n * @param originalBuffer - Original DOCX as ArrayBuffer\n * @param filename - Filename for the media (e.g., \"image1.png\")\n * @param data - Binary data for the media file\n * @param mimeType - MIME type (e.g., \"image/png\")\n * @returns Promise resolving to { buffer: ArrayBuffer, rId: string, path: string }\n */\nexport async function addMedia(\n originalBuffer: ArrayBuffer,\n filename: string,\n data: ArrayBuffer,\n mimeType: string\n): Promise<{ buffer: ArrayBuffer; rId: string; path: string }> {\n const zip = await JSZip.loadAsync(originalBuffer);\n\n // Determine media path\n const mediaPath = `word/media/${filename}`;\n\n // Add media file\n zip.file(mediaPath, data);\n\n // Add relationship\n const relResult = await addRelationship(await zip.generateAsync({ type: 'arraybuffer' }), {\n type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',\n target: `media/${filename}`,\n });\n\n // Update content types if needed\n const contentTypesFile = zip.file('[Content_Types].xml');\n if (contentTypesFile) {\n const contentTypesXml = await contentTypesFile.async('text');\n const extension = filename.split('.').pop()?.toLowerCase() || '';\n\n // Check if extension is already registered\n const hasExtension = contentTypesXml.includes(`Extension=\"${extension}\"`);\n\n if (!hasExtension && extension) {\n // Add content type for this extension\n const contentType = getContentTypeForExtension(extension, mimeType);\n const extensionElement = `<Default Extension=\"${extension}\" ContentType=\"${contentType}\"/>`;\n\n // Insert after other defaults\n const updatedContentTypes = contentTypesXml.replace(\n '</Types>',\n `${extensionElement}</Types>`\n );\n\n const finalZip = await JSZip.loadAsync(relResult.buffer);\n finalZip.file('[Content_Types].xml', updatedContentTypes);\n\n return {\n buffer: await finalZip.generateAsync({\n type: 'arraybuffer',\n compression: 'DEFLATE',\n compressionOptions: { level: 6 },\n }),\n rId: relResult.rId,\n path: mediaPath,\n };\n }\n }\n\n return {\n buffer: relResult.buffer,\n rId: relResult.rId,\n path: mediaPath,\n };\n}\n\n// ============================================================================\n// HEADER/FOOTER SERIALIZATION\n// ============================================================================\n\n/**\n * Collect serialized header/footer XML updates from the document model.\n * Uses the relationship map to resolve rId → filename.\n */\nexport function collectHeaderFooterUpdates(doc: Document): Map<string, string> {\n const updates = new Map<string, string>();\n const rels = doc.package.relationships;\n if (!rels) return updates;\n\n const parts: Array<{\n map: Map<string, import('../types/content').HeaderFooter> | undefined;\n type: string;\n }> = [\n { map: doc.package.headers, type: RELATIONSHIP_TYPES.header },\n { map: doc.package.footers, type: RELATIONSHIP_TYPES.footer },\n ];\n\n for (const { map, type } of parts) {\n if (!map) continue;\n for (const [rId, headerFooter] of map.entries()) {\n const rel = rels.get(rId);\n if (rel && rel.type === type && rel.target) {\n const filename = rel.target.startsWith('/') ? rel.target.slice(1) : `word/${rel.target}`;\n updates.set(filename, serializeHeaderFooter(headerFooter));\n }\n }\n }\n\n return updates;\n}\n\n/**\n * Serialize modified headers and footers into the ZIP\n */\nfunction serializeHeadersFootersToZip(doc: Document, zip: JSZip, compressionLevel: number): void {\n const compressionOptions = { level: compressionLevel };\n for (const [filename, xml] of collectHeaderFooterUpdates(doc)) {\n zip.file(filename, xml, { compression: 'DEFLATE', compressionOptions });\n }\n}\n\n// ============================================================================\n// UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Update core properties XML with new modification date\n */\nexport function updateCoreProperties(\n corePropsXml: string,\n options: { updateModifiedDate?: boolean; modifiedBy?: string }\n): string {\n let result = corePropsXml;\n\n if (options.updateModifiedDate) {\n const now = new Date().toISOString();\n\n // Update dcterms:modified\n if (result.includes('<dcterms:modified')) {\n result = result.replace(\n /<dcterms:modified[^>]*>[^<]*<\\/dcterms:modified>/,\n `<dcterms:modified xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:modified>`\n );\n } else {\n // Add modified date if not present\n result = result.replace(\n '</cp:coreProperties>',\n `<dcterms:modified xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:modified></cp:coreProperties>`\n );\n }\n }\n\n if (options.modifiedBy) {\n // Update cp:lastModifiedBy\n if (result.includes('<cp:lastModifiedBy')) {\n result = result.replace(\n /<cp:lastModifiedBy>[^<]*<\\/cp:lastModifiedBy>/,\n `<cp:lastModifiedBy>${escapeXml(options.modifiedBy)}</cp:lastModifiedBy>`\n );\n } else {\n // Add lastModifiedBy if not present\n result = result.replace(\n '</cp:coreProperties>',\n `<cp:lastModifiedBy>${escapeXml(options.modifiedBy)}</cp:lastModifiedBy></cp:coreProperties>`\n );\n }\n }\n\n return result;\n}\n\n/**\n * Get content type for a file extension\n */\nfunction getContentTypeForExtension(extension: string, mimeType: string): string {\n // Use provided mime type or fall back to common types\n if (mimeType) return mimeType;\n\n const contentTypes: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n gif: 'image/gif',\n bmp: 'image/bmp',\n tif: 'image/tiff',\n tiff: 'image/tiff',\n svg: 'image/svg+xml',\n webp: 'image/webp',\n wmf: 'image/x-wmf',\n emf: 'image/x-emf',\n };\n\n return contentTypes[extension] || 'application/octet-stream';\n}\n\n// ============================================================================\n// VALIDATION\n// ============================================================================\n\n/**\n * Validate that a buffer is a valid DOCX file\n *\n * @param buffer - Buffer to validate\n * @returns Promise resolving to validation result\n */\nexport async function validateDocx(buffer: ArrayBuffer): Promise<{\n valid: boolean;\n errors: string[];\n warnings: string[];\n}> {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n try {\n const zip = await JSZip.loadAsync(buffer);\n\n // Check for required files\n const requiredFiles = ['[Content_Types].xml', 'word/document.xml'];\n\n for (const file of requiredFiles) {\n if (!zip.file(file)) {\n errors.push(`Missing required file: ${file}`);\n }\n }\n\n // Check for recommended files\n const recommendedFiles = ['_rels/.rels', 'word/_rels/document.xml.rels', 'word/styles.xml'];\n\n for (const file of recommendedFiles) {\n if (!zip.file(file)) {\n warnings.push(`Missing recommended file: ${file}`);\n }\n }\n\n // Validate document.xml is valid XML\n const docFile = zip.file('word/document.xml');\n if (docFile) {\n const docXml = await docFile.async('text');\n\n // Basic XML validation\n if (!docXml.includes('<?xml')) {\n warnings.push('document.xml missing XML declaration');\n }\n\n if (!docXml.includes('<w:document')) {\n errors.push('document.xml missing w:document element');\n }\n\n if (!docXml.includes('<w:body>')) {\n errors.push('document.xml missing w:body element');\n }\n }\n\n // Validate Content_Types.xml\n const ctFile = zip.file('[Content_Types].xml');\n if (ctFile) {\n const ctXml = await ctFile.async('text');\n\n if (\n !ctXml.includes('word/document.xml') &&\n !ctXml.includes(\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml'\n )\n ) {\n warnings.push('Content_Types.xml may be missing document.xml type declaration');\n }\n }\n } catch (error) {\n errors.push(\n `Failed to read as ZIP: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Check if buffer looks like a DOCX file (quick check)\n *\n * @param buffer - Buffer to check\n * @returns true if buffer starts with ZIP signature\n */\nexport function isDocxBuffer(buffer: ArrayBuffer): boolean {\n if (buffer.byteLength < 4) return false;\n\n const view = new Uint8Array(buffer);\n\n // ZIP file signature: PK (0x50, 0x4B)\n return view[0] === 0x50 && view[1] === 0x4b;\n}\n\n// ============================================================================\n// CREATE NEW DOCX\n// ============================================================================\n\n/**\n * Create a new empty DOCX file\n *\n * @returns Promise resolving to minimal DOCX as ArrayBuffer\n */\nexport async function createEmptyDocx(): Promise<ArrayBuffer> {\n const zip = new JSZip();\n\n // Content Types\n zip.file(\n '[Content_Types].xml',\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">\n <Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>\n <Default Extension=\"xml\" ContentType=\"application/xml\"/>\n <Override PartName=\"/word/document.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\"/>\n <Override PartName=\"/word/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml\"/>\n <Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/>\n <Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/>\n</Types>`\n );\n\n // Package relationships\n zip.file(\n '_rels/.rels',\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"word/document.xml\"/>\n <Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties\" Target=\"docProps/core.xml\"/>\n <Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties\" Target=\"docProps/app.xml\"/>\n</Relationships>`\n );\n\n // Document relationships\n zip.file(\n 'word/_rels/document.xml.rels',\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>\n</Relationships>`\n );\n\n // Document\n zip.file(\n 'word/document.xml',\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:document xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">\n <w:body>\n <w:p>\n <w:r>\n <w:t></w:t>\n </w:r>\n </w:p>\n <w:sectPr>\n <w:pgSz w:w=\"12240\" w:h=\"15840\"/>\n <w:pgMar w:top=\"1440\" w:right=\"1440\" w:bottom=\"1440\" w:left=\"1440\" w:header=\"720\" w:footer=\"720\" w:gutter=\"0\"/>\n </w:sectPr>\n </w:body>\n</w:document>`\n );\n\n // Minimal styles\n zip.file(\n 'word/styles.xml',\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:styles xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n <w:docDefaults>\n <w:rPrDefault>\n <w:rPr>\n <w:rFonts w:ascii=\"Calibri\" w:hAnsi=\"Calibri\"/>\n <w:sz w:val=\"22\"/>\n </w:rPr>\n </w:rPrDefault>\n <w:pPrDefault>\n <w:pPr>\n <w:spacing w:after=\"200\" w:line=\"276\" w:lineRule=\"auto\"/>\n </w:pPr>\n </w:pPrDefault>\n </w:docDefaults>\n <w:style w:type=\"paragraph\" w:default=\"1\" w:styleId=\"Normal\">\n <w:name w:val=\"Normal\"/>\n </w:style>\n</w:styles>`\n );\n\n // Core properties\n const now = new Date().toISOString();\n zip.file(\n 'docProps/core.xml',\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n <dc:creator>EigenPal DOCX Editor</dc:creator>\n <dcterms:created xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:created>\n <dcterms:modified xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:modified>\n</cp:coreProperties>`\n );\n\n // App properties\n zip.file(\n 'docProps/app.xml',\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\">\n <Application>EigenPal DOCX Editor</Application>\n <AppVersion>1.0.0</AppVersion>\n</Properties>`\n );\n\n return zip.generateAsync({\n type: 'arraybuffer',\n compression: 'DEFLATE',\n compressionOptions: { level: 6 },\n });\n}\n\n/**\n * Create a new DOCX from a Document (without requiring original buffer)\n *\n * @param doc - Document to serialize\n * @returns Promise resolving to DOCX as ArrayBuffer\n */\nexport async function createDocx(doc: Document): Promise<ArrayBuffer> {\n // Start with an empty DOCX\n const emptyBuffer = await createEmptyDocx();\n\n // Add document as original buffer\n const docWithBuffer: Document = {\n ...doc,\n originalBuffer: emptyBuffer,\n };\n\n // Repack with the document content\n return repackDocx(docWithBuffer);\n}\n\n// ============================================================================\n// EXPORTS\n// ============================================================================\n\nexport default repackDocx;\n","/**\n * Selective XML Patch Module\n *\n * Patches only changed paragraphs in document.xml, preserving\n * unchanged content byte-for-byte. Uses string offset tracking\n * with proper tag depth counting (not regex) to handle nested elements.\n */\n\n/**\n * Find the exact string start and end offsets of a <w:p> element\n * identified by its w14:paraId attribute.\n *\n * Handles nested <w:p> elements (e.g. inside mc:AlternateContent)\n * via proper depth counting.\n *\n * Returns null if paraId not found or appears more than once (ambiguous).\n */\nexport function findParagraphOffsets(\n xml: string,\n paraId: string\n): { start: number; end: number } | null {\n // Find all <w:p elements that contain this paraId.\n // Pattern matches <w:p followed by whitespace or >, then any attrs, then the paraId.\n // This covers all attribute orderings since [^>]* matches any attributes before paraId.\n const escaped = escapeRegExp(paraId);\n const pattern = new RegExp(`<w:p[\\\\s][^>]*w14:paraId=\"${escaped}\"`, 'g');\n\n const matches: number[] = [];\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(xml)) !== null) {\n matches.push(match.index);\n }\n\n if (matches.length === 0) {\n return null;\n }\n if (matches.length > 1) {\n // Duplicate paraId — ambiguous, cannot safely patch\n return null;\n }\n\n const start = matches[0];\n\n // Now find the matching </w:p> by counting depth\n // Start after the <w:p opening\n let pos = start;\n let depth = 0;\n\n while (pos < xml.length) {\n // Find next tag\n const tagStart = xml.indexOf('<', pos);\n if (tagStart === -1) break;\n\n // Check if it's a <w:p or </w:p tag\n if (xml.startsWith('<w:p', tagStart)) {\n const charAfterTag = xml[tagStart + 4];\n // Must be <w:p> or <w:p or <w:p/ (not <w:pPr, <w:pStyle, etc.)\n if (charAfterTag === '>' || charAfterTag === ' ' || charAfterTag === '/') {\n // Check for self-closing: <w:p ... />\n const tagEnd = xml.indexOf('>', tagStart);\n if (tagEnd === -1) break;\n\n if (xml[tagEnd - 1] === '/') {\n // Self-closing <w:p ... /> — doesn't change depth\n if (depth === 0) {\n // This IS our paragraph and it's self-closing\n return { start, end: tagEnd + 1 };\n }\n pos = tagEnd + 1;\n } else {\n depth++;\n pos = tagEnd + 1;\n }\n } else {\n // It's something like <w:pPr — skip\n pos = tagStart + 1;\n }\n } else if (xml.startsWith('</w:p>', tagStart)) {\n depth--;\n if (depth === 0) {\n return { start, end: tagStart + 6 }; // 6 = '</w:p>'.length\n }\n pos = tagStart + 6;\n } else {\n pos = tagStart + 1;\n }\n }\n\n // Couldn't find matching close tag\n return null;\n}\n\n/**\n * Extract the serialized XML for a specific paragraph by paraId\n * from a fully serialized document.xml string.\n */\nexport function extractParagraphXml(serializedXml: string, paraId: string): string | null {\n const offsets = findParagraphOffsets(serializedXml, paraId);\n if (!offsets) return null;\n return serializedXml.substring(offsets.start, offsets.end);\n}\n\n/**\n * Count <w:p> elements in an XML string (top-level paragraph count).\n * Counts opening <w:p tags that are NOT self-closing.\n */\nexport function countParagraphElements(xml: string): number {\n let count = 0;\n const pattern = /<w:p[\\s>]/g;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(xml)) !== null) {\n // Verify this is actually <w:p and not <w:pPr etc.\n const idx = match.index;\n const charAfter = xml[idx + 4];\n if (charAfter === '>' || charAfter === ' ') {\n count++;\n }\n }\n return count;\n}\n\n/**\n * Find all paraIds in an XML string and return counts (to detect duplicates).\n */\nfunction collectParaIds(xml: string): Map<string, number> {\n const ids = new Map<string, number>();\n const pattern = /w14:paraId=\"([^\"]+)\"/g;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(xml)) !== null) {\n const id = match[1];\n ids.set(id, (ids.get(id) || 0) + 1);\n }\n return ids;\n}\n\nexport interface PatchValidationResult {\n safe: boolean;\n reason?: string;\n}\n\n/**\n * Validate that a selective patch can be safely applied.\n *\n * Checks:\n * - All changed paraIds exist in original XML (exactly once)\n * - All changed paraIds exist in serialized XML (exactly once)\n * - Paragraph count matches between original and serialized\n */\nexport function validatePatchSafety(\n originalXml: string,\n serializedXml: string,\n changedIds: Set<string>\n): PatchValidationResult {\n if (changedIds.size === 0) {\n return { safe: true };\n }\n\n const originalParaIds = collectParaIds(originalXml);\n const serializedParaIds = collectParaIds(serializedXml);\n\n // Check all changed IDs exist in original (exactly once)\n for (const id of changedIds) {\n const origCount = originalParaIds.get(id) || 0;\n if (origCount === 0) {\n return { safe: false, reason: `paraId-not-found-in-original: ${id}` };\n }\n if (origCount > 1) {\n return { safe: false, reason: `duplicate-paraId-in-original: ${id}` };\n }\n }\n\n // Check all changed IDs exist in serialized (exactly once)\n for (const id of changedIds) {\n const serCount = serializedParaIds.get(id) || 0;\n if (serCount === 0) {\n return { safe: false, reason: `paraId-not-found-in-serialized: ${id}` };\n }\n if (serCount > 1) {\n return { safe: false, reason: `duplicate-paraId-in-serialized: ${id}` };\n }\n }\n\n // Check paragraph counts match\n const originalCount = countParagraphElements(originalXml);\n const serializedCount = countParagraphElements(serializedXml);\n if (originalCount !== serializedCount) {\n return {\n safe: false,\n reason: `paragraph-count-mismatch: original=${originalCount}, serialized=${serializedCount}`,\n };\n }\n\n return { safe: true };\n}\n\n/**\n * Build a patched document.xml by splicing new paragraph XML into\n * the original at the correct offsets. Only changed paragraphs\n * are replaced; everything else is preserved byte-for-byte.\n *\n * Returns null if any step fails.\n */\nexport function buildPatchedDocumentXml(\n originalXml: string,\n serializedXml: string,\n changedIds: Set<string>\n): string | null {\n if (changedIds.size === 0) {\n return originalXml;\n }\n\n // Validate safety first\n const validation = validatePatchSafety(originalXml, serializedXml, changedIds);\n if (!validation.safe) {\n return null;\n }\n\n // Collect all replacements: { start, end, newXml }\n const replacements: Array<{ start: number; end: number; newXml: string }> = [];\n\n for (const paraId of changedIds) {\n const origOffsets = findParagraphOffsets(originalXml, paraId);\n if (!origOffsets) return null;\n\n const newXml = extractParagraphXml(serializedXml, paraId);\n if (!newXml) return null;\n\n replacements.push({\n start: origOffsets.start,\n end: origOffsets.end,\n newXml,\n });\n }\n\n // Sort by start offset descending so we can splice end-to-start\n // (this preserves earlier offsets when replacing later sections)\n replacements.sort((a, b) => b.start - a.start);\n\n let result = originalXml;\n for (const { start, end, newXml } of replacements) {\n result = result.substring(0, start) + newXml + result.substring(end);\n }\n\n return result;\n}\n\nfunction escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n","/**\n * Selective Save Module\n *\n * Orchestrates selective XML patching for the save flow.\n * Serializes full document.xml, validates patch safety, builds patched XML,\n * and calls applyUpdatesToZip() to produce the final DOCX.\n *\n * Returns null on any failure, signaling the caller to fall back to full repack.\n */\n\nimport type { Document, BlockContent } from '../types/document';\nimport { serializeDocument } from './serializer/documentSerializer';\nimport { serializeComments } from './serializer/commentSerializer';\nimport { buildPatchedDocumentXml } from './selectiveXmlPatch';\nimport {\n applyUpdatesToZip,\n findMaxRId,\n updateCoreProperties,\n collectHeaderFooterUpdates,\n COMMENTS_CONTENT_TYPE,\n} from './rezip';\nimport { RELATIONSHIP_TYPES } from './relsParser';\n\n/**\n * Check if document content has new images (data: URL without rId) or\n * new hyperlinks (href without rId). Combined into a single traversal\n * to avoid walking the block tree twice.\n */\nfunction hasNewImagesOrHyperlinks(blocks: BlockContent[]): boolean {\n for (const block of blocks) {\n if (block.type === 'paragraph') {\n for (const item of block.content) {\n if (item.type === 'run') {\n for (const c of item.content) {\n if (c.type === 'drawing' && c.image?.src?.startsWith('data:') && !c.image?.rId) {\n return true;\n }\n }\n } else if (item.type === 'hyperlink' && item.href && !item.rId && !item.anchor) {\n return true;\n }\n }\n } else if (block.type === 'table') {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n if (hasNewImagesOrHyperlinks(cell.content)) return true;\n }\n }\n }\n }\n return false;\n}\n\nexport interface SelectiveSaveOptions {\n /** Changed paragraph IDs to selectively patch */\n changedParaIds: Set<string>;\n /** Whether structural changes occurred (paragraph add/delete) */\n structuralChange: boolean;\n /** Whether any changes affected paragraphs without paraId */\n hasUntrackedChanges: boolean;\n}\n\n/**\n * Attempt a selective save — patch only changed paragraphs in document.xml.\n * Also updates comments, headers/footers, and core properties so that\n * all document parts stay in sync even when only paragraphs are patched.\n *\n * Returns the saved ArrayBuffer, or null if selective save is not possible\n * (caller should fall back to full repack).\n */\nexport async function attemptSelectiveSave(\n doc: Document,\n originalBuffer: ArrayBuffer,\n options: SelectiveSaveOptions\n): Promise<ArrayBuffer | null> {\n const { changedParaIds, structuralChange, hasUntrackedChanges } = options;\n\n // Bail out conditions — fall back to full repack\n if (structuralChange) return null;\n if (hasUntrackedChanges) return null;\n if (!originalBuffer) return null;\n\n // Check for new images/hyperlinks that need relationship management\n const content = doc.package.document.content;\n if (hasNewImagesOrHyperlinks(content)) return null;\n\n const comments = doc.package.document.comments;\n const hasComments = comments && comments.length > 0;\n const headerFooterUpdates = collectHeaderFooterUpdates(doc);\n\n try {\n const JSZip = (await import('jszip')).default;\n const zip = await JSZip.loadAsync(originalBuffer);\n const updates = new Map<string, string>();\n\n // Patch document.xml if paragraphs changed\n if (changedParaIds.size > 0) {\n const docXmlFile = zip.file('word/document.xml');\n if (!docXmlFile) return null;\n const originalDocXml = await docXmlFile.async('text');\n\n const serializedDocXml = serializeDocument(doc);\n const patchedDocXml = buildPatchedDocumentXml(\n originalDocXml,\n serializedDocXml,\n changedParaIds\n );\n if (!patchedDocXml) return null;\n updates.set('word/document.xml', patchedDocXml);\n }\n\n // Always serialize comments.xml when the document has comments\n if (hasComments) {\n updates.set('word/comments.xml', serializeComments(comments));\n\n // Ensure [Content_Types].xml has an Override for comments.xml\n const ctFile = zip.file('[Content_Types].xml');\n if (ctFile) {\n const ctXml = await ctFile.async('text');\n if (!ctXml.includes('/word/comments.xml')) {\n updates.set(\n '[Content_Types].xml',\n ctXml.replace(\n '</Types>',\n `<Override PartName=\"/word/comments.xml\" ContentType=\"${COMMENTS_CONTENT_TYPE}\"/></Types>`\n )\n );\n }\n }\n\n // Ensure word/_rels/document.xml.rels has a Relationship for comments.xml\n const relsPath = 'word/_rels/document.xml.rels';\n const relsFile = zip.file(relsPath);\n if (relsFile) {\n const relsXml = await relsFile.async('text');\n if (!relsXml.includes('comments.xml')) {\n const maxId = findMaxRId(relsXml);\n updates.set(\n relsPath,\n relsXml.replace(\n '</Relationships>',\n `<Relationship Id=\"rId${maxId + 1}\" Type=\"${RELATIONSHIP_TYPES.comments}\" Target=\"comments.xml\"/></Relationships>`\n )\n );\n }\n }\n }\n\n // Serialize modified headers/footers\n for (const [path, xml] of headerFooterUpdates) {\n updates.set(path, xml);\n }\n\n // Update modification date in docProps/core.xml\n const corePropsFile = zip.file('docProps/core.xml');\n if (corePropsFile) {\n const corePropsXml = await corePropsFile.async('text');\n updates.set(\n 'docProps/core.xml',\n updateCoreProperties(corePropsXml, { updateModifiedDate: true })\n );\n }\n\n // Use the already-loaded zip to avoid a redundant decompression pass\n return await applyUpdatesToZip(zip, updates);\n } catch {\n // Any error — fall back to full repack\n return null;\n }\n}\n","/**\n * Variable Detector Utility\n *\n * Scans a DOCX document for template variables in the format {variable_name}\n * (standard docxtemplater syntax).\n * Returns a unique, sorted list of variable names found in the document.\n */\n\nimport type {\n Document,\n DocumentBody,\n Paragraph,\n Table,\n TableCell,\n Run,\n Hyperlink,\n SimpleField,\n ComplexField,\n BlockContent,\n HeaderFooter,\n Footnote,\n Endnote,\n TextBox,\n} from '../types/document';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\n/**\n * Result of variable detection\n */\nexport interface VariableDetectionResult {\n /** Unique variable names sorted alphabetically */\n variables: string[];\n /** Total count of variable occurrences */\n totalOccurrences: number;\n /** Variables by location */\n byLocation: {\n body: string[];\n headers: string[];\n footers: string[];\n footnotes: string[];\n endnotes: string[];\n textBoxes: string[];\n };\n /** Variable occurrences with positions */\n occurrences: VariableOccurrence[];\n}\n\n/**\n * A single variable occurrence with location info\n */\nexport interface VariableOccurrence {\n /** Variable name (without braces) */\n name: string;\n /** Location type */\n location: 'body' | 'header' | 'footer' | 'footnote' | 'endnote' | 'textBox';\n /** Paragraph index within location */\n paragraphIndex?: number;\n /** Section index (for headers/footers) */\n sectionIndex?: number;\n}\n\n// ============================================================================\n// MAIN FUNCTIONS\n// ============================================================================\n\n/**\n * Detect all template variables in a document\n *\n * @param doc - The parsed document\n * @returns Array of unique variable names sorted alphabetically\n */\nexport function detectVariables(doc: Document): string[] {\n const result = detectVariablesDetailed(doc);\n return result.variables;\n}\n\n/**\n * Detect variables with detailed information\n *\n * @param doc - The parsed document\n * @returns Detailed detection result\n */\nexport function detectVariablesDetailed(doc: Document): VariableDetectionResult {\n const occurrences: VariableOccurrence[] = [];\n const byLocation: VariableDetectionResult['byLocation'] = {\n body: [],\n headers: [],\n footers: [],\n footnotes: [],\n endnotes: [],\n textBoxes: [],\n };\n\n // Scan main body\n if (doc.package?.document) {\n const bodyVars = detectVariablesInBody(doc.package.document);\n bodyVars.forEach((v) => {\n occurrences.push({ name: v, location: 'body' });\n });\n byLocation.body = Array.from(new Set(bodyVars)).sort();\n }\n\n // Scan headers and footers\n if (doc.package?.document?.sections) {\n doc.package.document.sections.forEach((section, _sectionIndex) => {\n // Headers\n if (section.properties.headerReferences) {\n section.properties.headerReferences.forEach((_headerRef) => {\n // If we have actual header content, scan it\n // Note: Headers are stored separately in the package\n });\n }\n });\n }\n\n // Scan footers from package\n // (Actual footer content would be accessed from pkg.headers/pkg.footers if available)\n\n // Scan footnotes\n if (doc.package?.footnotes) {\n const footnoteVars = detectVariablesInNotes(doc.package.footnotes);\n footnoteVars.forEach((v) => {\n occurrences.push({ name: v, location: 'footnote' });\n });\n byLocation.footnotes = Array.from(new Set(footnoteVars)).sort();\n }\n\n // Scan endnotes\n if (doc.package?.endnotes) {\n const endnoteVars = detectVariablesInNotes(doc.package.endnotes);\n endnoteVars.forEach((v) => {\n occurrences.push({ name: v, location: 'endnote' });\n });\n byLocation.endnotes = Array.from(new Set(endnoteVars)).sort();\n }\n\n // Also check templateVariables from document if already detected\n if (doc.templateVariables) {\n doc.templateVariables.forEach((v) => {\n if (!occurrences.some((o) => o.name === v)) {\n occurrences.push({ name: v, location: 'body' });\n }\n });\n }\n\n // Collect all unique variables\n const allVariables = new Set<string>();\n occurrences.forEach((o) => allVariables.add(o.name));\n\n return {\n variables: Array.from(allVariables).sort(),\n totalOccurrences: occurrences.length,\n byLocation,\n occurrences,\n };\n}\n\n/**\n * Detect variables in document body\n */\nexport function detectVariablesInBody(body: DocumentBody): string[] {\n const variables: string[] = [];\n\n // Scan content array\n if (body.content) {\n variables.push(...detectVariablesInBlockContent(body.content));\n }\n\n // Scan sections\n if (body.sections) {\n for (const section of body.sections) {\n if (section.content) {\n variables.push(...detectVariablesInBlockContent(section.content));\n }\n }\n }\n\n return variables;\n}\n\n/**\n * Detect variables in block content (paragraphs and tables)\n */\nexport function detectVariablesInBlockContent(content: BlockContent[]): string[] {\n const variables: string[] = [];\n\n for (const block of content) {\n if (block.type === 'paragraph') {\n variables.push(...detectVariablesInParagraph(block));\n } else if (block.type === 'table') {\n variables.push(...detectVariablesInTable(block));\n }\n }\n\n return variables;\n}\n\n/**\n * Detect variables in a paragraph\n */\nexport function detectVariablesInParagraph(paragraph: Paragraph): string[] {\n const variables: string[] = [];\n\n if (!paragraph.content) return variables;\n\n for (const item of paragraph.content) {\n if (item.type === 'run') {\n variables.push(...detectVariablesInRun(item));\n } else if (item.type === 'hyperlink') {\n variables.push(...detectVariablesInHyperlink(item));\n } else if (item.type === 'simpleField') {\n variables.push(...detectVariablesInSimpleField(item));\n } else if (item.type === 'complexField') {\n variables.push(...detectVariablesInComplexField(item));\n }\n }\n\n return variables;\n}\n\n/**\n * Detect variables in a text run\n */\nexport function detectVariablesInRun(run: Run): string[] {\n const variables: string[] = [];\n\n if (!run.content) return variables;\n\n for (const item of run.content) {\n if (item.type === 'text' && item.text) {\n variables.push(...extractVariablesFromText(item.text));\n }\n }\n\n return variables;\n}\n\n/**\n * Detect variables in a hyperlink\n */\nexport function detectVariablesInHyperlink(hyperlink: Hyperlink): string[] {\n const variables: string[] = [];\n\n if (!hyperlink.children) return variables;\n\n for (const child of hyperlink.children) {\n if (child.type === 'run') {\n variables.push(...detectVariablesInRun(child));\n }\n }\n\n return variables;\n}\n\n/**\n * Detect variables in a simple field\n */\nexport function detectVariablesInSimpleField(field: SimpleField): string[] {\n const variables: string[] = [];\n\n // Check field instruction\n if (field.instruction) {\n variables.push(...extractVariablesFromText(field.instruction));\n }\n\n // Check field content runs\n if (field.content) {\n for (const run of field.content) {\n if (run.type === 'run') {\n variables.push(...detectVariablesInRun(run));\n }\n }\n }\n\n return variables;\n}\n\n/**\n * Detect variables in a complex field\n */\nexport function detectVariablesInComplexField(field: ComplexField): string[] {\n const variables: string[] = [];\n\n // Check field code runs\n if (field.fieldCode) {\n for (const run of field.fieldCode) {\n if (run.type === 'run') {\n variables.push(...detectVariablesInRun(run));\n }\n }\n }\n\n // Check field result runs\n if (field.fieldResult) {\n for (const run of field.fieldResult) {\n if (run.type === 'run') {\n variables.push(...detectVariablesInRun(run));\n }\n }\n }\n\n return variables;\n}\n\n/**\n * Detect variables in a table\n */\nexport function detectVariablesInTable(table: Table): string[] {\n const variables: string[] = [];\n\n if (!table.rows) return variables;\n\n for (const row of table.rows) {\n if (!row.cells) continue;\n\n for (const cell of row.cells) {\n variables.push(...detectVariablesInCell(cell));\n }\n }\n\n return variables;\n}\n\n/**\n * Detect variables in a table cell\n */\nexport function detectVariablesInCell(cell: TableCell): string[] {\n const variables: string[] = [];\n\n if (!cell.content) return variables;\n\n for (const block of cell.content) {\n if (block.type === 'paragraph') {\n variables.push(...detectVariablesInParagraph(block));\n } else if (block.type === 'table') {\n // Nested tables\n variables.push(...detectVariablesInTable(block));\n }\n }\n\n return variables;\n}\n\n/**\n * Detect variables in footnotes/endnotes\n */\nexport function detectVariablesInNotes(notes: (Footnote | Endnote)[]): string[] {\n const variables: string[] = [];\n\n for (const note of notes) {\n if (!note.content) continue;\n\n for (const paragraph of note.content) {\n variables.push(...detectVariablesInParagraph(paragraph));\n }\n }\n\n return variables;\n}\n\n/**\n * Detect variables in headers/footers\n */\nexport function detectVariablesInHeaderFooter(hf: HeaderFooter): string[] {\n const variables: string[] = [];\n\n if (!hf.content) return variables;\n\n for (const block of hf.content) {\n if (block.type === 'paragraph') {\n variables.push(...detectVariablesInParagraph(block));\n } else if (block.type === 'table') {\n variables.push(...detectVariablesInTable(block));\n }\n }\n\n return variables;\n}\n\n/**\n * Detect variables in a text box\n */\nexport function detectVariablesInTextBox(textBox: TextBox): string[] {\n const variables: string[] = [];\n\n if (!textBox.content) return variables;\n\n // TextBox.content is Paragraph[]\n for (const paragraph of textBox.content) {\n variables.push(...detectVariablesInParagraph(paragraph));\n }\n\n return variables;\n}\n\n// ============================================================================\n// TEXT EXTRACTION\n// ============================================================================\n\n/**\n * Regular expression for matching template variables\n * Matches {variable_name} (standard docxtemplater syntax) where variable_name can contain:\n * - Letters (a-z, A-Z)\n * - Numbers (0-9)\n * - Underscores (_)\n * - Hyphens (-)\n * - Dots (.)\n */\nconst VARIABLE_PATTERN = /\\{([a-zA-Z_][a-zA-Z0-9_\\-\\.]*)\\}/g;\n\n/**\n * Alternative pattern allowing any content between braces\n */\nconst VARIABLE_PATTERN_RELAXED = /\\{(.+?)\\}/g;\n\n/**\n * Extract variable names from text\n *\n * @param text - The text to search\n * @returns Array of variable names (without braces)\n */\nexport function extractVariablesFromText(text: string): string[] {\n if (!text) return [];\n\n const variables: string[] = [];\n const pattern = new RegExp(VARIABLE_PATTERN);\n let match: RegExpExecArray | null;\n\n while ((match = pattern.exec(text)) !== null) {\n variables.push(match[1]);\n }\n\n return variables;\n}\n\n/**\n * Extract all variables from text (relaxed matching)\n * Allows any content between { and }\n */\nexport function extractVariablesFromTextRelaxed(text: string): string[] {\n if (!text) return [];\n\n const variables: string[] = [];\n const pattern = new RegExp(VARIABLE_PATTERN_RELAXED);\n let match: RegExpExecArray | null;\n\n while ((match = pattern.exec(text)) !== null) {\n const varName = match[1].trim();\n if (varName) {\n variables.push(varName);\n }\n }\n\n return variables;\n}\n\n/**\n * Check if text contains template variables\n */\nexport function hasTemplateVariables(text: string): boolean {\n return VARIABLE_PATTERN.test(text);\n}\n\n/**\n * Count template variables in text\n */\nexport function countVariables(text: string): number {\n const matches = text.match(VARIABLE_PATTERN);\n return matches ? matches.length : 0;\n}\n\n/**\n * Get unique variable names from text\n */\nexport function getUniqueVariables(text: string): string[] {\n const variables = extractVariablesFromText(text);\n return Array.from(new Set(variables)).sort();\n}\n\n// ============================================================================\n// VALIDATION\n// ============================================================================\n\n/**\n * Check if a variable name is valid\n */\nexport function isValidVariableName(name: string): boolean {\n if (!name || typeof name !== 'string') return false;\n if (name.length === 0 || name.length > 100) return false;\n\n // Must start with letter or underscore\n if (!/^[a-zA-Z_]/.test(name)) return false;\n\n // Can contain letters, numbers, underscores, hyphens, dots\n if (!/^[a-zA-Z_][a-zA-Z0-9_\\-\\.]*$/.test(name)) return false;\n\n return true;\n}\n\n/**\n * Sanitize a variable name\n */\nexport function sanitizeVariableName(name: string): string {\n if (!name) return '';\n\n // Replace spaces with underscores\n let sanitized = name.replace(/\\s+/g, '_');\n\n // Remove invalid characters\n sanitized = sanitized.replace(/[^a-zA-Z0-9_\\-\\.]/g, '');\n\n // Ensure starts with letter or underscore\n if (sanitized && !/^[a-zA-Z_]/.test(sanitized)) {\n sanitized = '_' + sanitized;\n }\n\n // Limit length\n return sanitized.substring(0, 100);\n}\n\n/**\n * Format a variable name with braces (standard docxtemplater syntax)\n */\nexport function formatVariable(name: string): string {\n return `{${name}}`;\n}\n\n/**\n * Parse a variable string to get the name\n */\nexport function parseVariable(variable: string): string | null {\n const match = variable.match(/^\\{(.+?)\\}$/);\n return match ? match[1] : null;\n}\n\n// ============================================================================\n// REPLACEMENT\n// ============================================================================\n\n/**\n * Replace variables in text with values\n *\n * @param text - The text containing variables\n * @param values - Map of variable name to replacement value\n * @returns Text with variables replaced\n */\nexport function replaceVariables(text: string, values: Record<string, string>): string {\n if (!text) return text;\n\n return text.replace(VARIABLE_PATTERN_RELAXED, (match, varName) => {\n const name = varName.trim();\n if (name in values) {\n return values[name];\n }\n return match; // Keep original if not in values\n });\n}\n\n/**\n * Replace all variables in text with a placeholder\n *\n * @param text - The text containing variables\n * @param placeholder - Placeholder to use (default: empty string)\n * @returns Text with variables replaced\n */\nexport function removeVariables(text: string, placeholder = ''): string {\n if (!text) return text;\n return text.replace(VARIABLE_PATTERN_RELAXED, placeholder);\n}\n\n/**\n * Highlight variables in text for display\n *\n * @param text - The text containing variables\n * @param wrapper - Function to wrap variable text\n * @returns Array of text segments\n */\nexport function highlightVariables(\n text: string,\n wrapper: (varName: string) => string = (v) => `[${v}]`\n): string {\n if (!text) return text;\n\n return text.replace(VARIABLE_PATTERN_RELAXED, (_match, varName) => {\n return wrapper(varName.trim());\n });\n}\n\n// ============================================================================\n// DOCUMENT-LEVEL HELPERS\n// ============================================================================\n\n/**\n * Get total variable count in document (including duplicates)\n */\nexport function getVariableCount(doc: Document): number {\n const result = detectVariablesDetailed(doc);\n return result.totalOccurrences;\n}\n\n/**\n * Get unique variable count in document\n */\nexport function getUniqueVariableCount(doc: Document): number {\n return detectVariables(doc).length;\n}\n\n/**\n * Check if document has any template variables\n */\nexport function documentHasVariables(doc: Document): boolean {\n return detectVariables(doc).length > 0;\n}\n\n/**\n * Get variables grouped by first letter for large lists\n */\nexport function groupVariablesByLetter(variables: string[]): Record<string, string[]> {\n const groups: Record<string, string[]> = {};\n\n for (const variable of variables) {\n const letter = variable.charAt(0).toUpperCase();\n if (!groups[letter]) {\n groups[letter] = [];\n }\n groups[letter].push(variable);\n }\n\n return groups;\n}\n\nexport default detectVariables;\n","/**\n * DOCX Unzipper\n *\n * Extracts all files from a DOCX ZIP archive and organizes them\n * into a structured format for further processing.\n *\n * A DOCX file is a ZIP archive containing:\n * - [Content_Types].xml - Content type declarations\n * - word/document.xml - Main document content\n * - word/styles.xml - Style definitions\n * - word/theme/theme1.xml - Theme colors and fonts\n * - word/numbering.xml - List/numbering definitions\n * - word/fontTable.xml - Font declarations\n * - word/settings.xml - Document settings\n * - word/webSettings.xml - Web settings\n * - word/header*.xml - Header content\n * - word/footer*.xml - Footer content\n * - word/footnotes.xml - Footnotes\n * - word/endnotes.xml - Endnotes\n * - word/media/* - Embedded images and media\n * - word/_rels/document.xml.rels - Relationships\n * - _rels/.rels - Package relationships\n * - docProps/core.xml - Core properties\n * - docProps/app.xml - Application properties\n */\n\nimport JSZip from 'jszip';\n\n/**\n * Raw extracted content from a DOCX file\n */\nexport interface RawDocxContent {\n // Main document\n documentXml: string | null;\n\n // Styles and formatting\n stylesXml: string | null;\n themeXml: string | null;\n numberingXml: string | null;\n fontTableXml: string | null;\n settingsXml: string | null;\n webSettingsXml: string | null;\n\n // Headers and footers (keyed by filename, e.g., \"header1.xml\")\n headers: Map<string, string>;\n footers: Map<string, string>;\n\n // Footnotes and endnotes\n footnotesXml: string | null;\n endnotesXml: string | null;\n\n // Comments\n commentsXml: string | null;\n commentsExtensibleXml: string | null;\n\n // Relationships\n documentRels: string | null;\n packageRels: string | null;\n\n // Content types\n contentTypesXml: string | null;\n\n // Document properties\n corePropsXml: string | null;\n appPropsXml: string | null;\n customPropsXml: string | null;\n\n // Media files (images, etc.) - keyed by path, e.g., \"word/media/image1.png\"\n media: Map<string, ArrayBuffer>;\n\n // Embedded fonts - keyed by path\n fonts: Map<string, ArrayBuffer>;\n\n // All XML files (for any we might have missed)\n allXml: Map<string, string>;\n\n // Original ZIP for round-trip preservation\n originalZip: JSZip;\n\n // Original buffer for round-trip\n originalBuffer: ArrayBuffer;\n}\n\n/**\n * Extract all content from a DOCX file\n *\n * @param buffer - DOCX file as ArrayBuffer\n * @returns Promise resolving to extracted content\n */\nexport async function unzipDocx(buffer: ArrayBuffer): Promise<RawDocxContent> {\n const zip = await JSZip.loadAsync(buffer);\n\n const content: RawDocxContent = {\n documentXml: null,\n stylesXml: null,\n themeXml: null,\n numberingXml: null,\n fontTableXml: null,\n settingsXml: null,\n webSettingsXml: null,\n headers: new Map(),\n footers: new Map(),\n footnotesXml: null,\n endnotesXml: null,\n commentsXml: null,\n commentsExtensibleXml: null,\n documentRels: null,\n packageRels: null,\n contentTypesXml: null,\n corePropsXml: null,\n appPropsXml: null,\n customPropsXml: null,\n media: new Map(),\n fonts: new Map(),\n allXml: new Map(),\n originalZip: zip,\n originalBuffer: buffer,\n };\n\n // Process each file in the ZIP\n for (const [path, file] of Object.entries(zip.files)) {\n // Skip directories\n if (file.dir) continue;\n\n const lowerPath = path.toLowerCase();\n\n // Determine file type and extract\n if (lowerPath.endsWith('.xml') || lowerPath.endsWith('.rels')) {\n const xmlContent = await file.async('text');\n content.allXml.set(path, xmlContent);\n\n // Categorize known XML files\n if (lowerPath === 'word/document.xml') {\n content.documentXml = xmlContent;\n } else if (lowerPath === 'word/styles.xml') {\n content.stylesXml = xmlContent;\n } else if (lowerPath === 'word/theme/theme1.xml') {\n content.themeXml = xmlContent;\n } else if (lowerPath === 'word/numbering.xml') {\n content.numberingXml = xmlContent;\n } else if (lowerPath === 'word/fonttable.xml') {\n content.fontTableXml = xmlContent;\n } else if (lowerPath === 'word/settings.xml') {\n content.settingsXml = xmlContent;\n } else if (lowerPath === 'word/websettings.xml') {\n content.webSettingsXml = xmlContent;\n } else if (lowerPath === 'word/footnotes.xml') {\n content.footnotesXml = xmlContent;\n } else if (lowerPath === 'word/endnotes.xml') {\n content.endnotesXml = xmlContent;\n } else if (lowerPath === 'word/comments.xml') {\n content.commentsXml = xmlContent;\n } else if (\n lowerPath === 'word/commentsextensible.xml' ||\n lowerPath === 'word/commentsextended.xml'\n ) {\n // Prefer commentsExtensible (Word 2016+), fall back to commentsExtended\n if (!content.commentsExtensibleXml) {\n content.commentsExtensibleXml = xmlContent;\n }\n } else if (lowerPath === 'word/_rels/document.xml.rels') {\n content.documentRels = xmlContent;\n } else if (lowerPath === '_rels/.rels') {\n content.packageRels = xmlContent;\n } else if (lowerPath === '[content_types].xml') {\n content.contentTypesXml = xmlContent;\n } else if (lowerPath === 'docprops/core.xml') {\n content.corePropsXml = xmlContent;\n } else if (lowerPath === 'docprops/app.xml') {\n content.appPropsXml = xmlContent;\n } else if (lowerPath === 'docprops/custom.xml') {\n content.customPropsXml = xmlContent;\n } else if (lowerPath.match(/^word\\/header\\d+\\.xml$/)) {\n const filename = path.split('/').pop() || path;\n content.headers.set(filename, xmlContent);\n } else if (lowerPath.match(/^word\\/footer\\d+\\.xml$/)) {\n const filename = path.split('/').pop() || path;\n content.footers.set(filename, xmlContent);\n }\n } else if (lowerPath.startsWith('word/media/')) {\n // Media files (images, etc.)\n const binaryContent = await file.async('arraybuffer');\n content.media.set(path, binaryContent);\n } else if (lowerPath.startsWith('word/fonts/')) {\n // Embedded fonts\n const binaryContent = await file.async('arraybuffer');\n content.fonts.set(path, binaryContent);\n }\n }\n\n return content;\n}\n\n/**\n * Get a list of all files in the DOCX\n *\n * @param content - Extracted DOCX content\n * @returns Array of file paths\n */\nexport function getFileList(content: RawDocxContent): string[] {\n const files: string[] = [];\n\n for (const path of Object.keys(content.originalZip.files)) {\n if (!content.originalZip.files[path].dir) {\n files.push(path);\n }\n }\n\n return files.sort();\n}\n\n/**\n * Get the MIME type for a media file based on extension\n *\n * @param path - File path\n * @returns MIME type string\n */\nexport function getMediaMimeType(path: string): string {\n const ext = path.toLowerCase().split('.').pop();\n\n switch (ext) {\n case 'png':\n return 'image/png';\n case 'jpg':\n case 'jpeg':\n return 'image/jpeg';\n case 'gif':\n return 'image/gif';\n case 'bmp':\n return 'image/bmp';\n case 'tif':\n case 'tiff':\n return 'image/tiff';\n case 'wmf':\n return 'image/x-wmf';\n case 'emf':\n return 'image/x-emf';\n case 'svg':\n return 'image/svg+xml';\n case 'webp':\n return 'image/webp';\n default:\n return 'application/octet-stream';\n }\n}\n\n/**\n * Convert media file to data URL\n *\n * @param data - Binary data\n * @param mimeType - MIME type\n * @returns Data URL string\n */\nexport function mediaToDataUrl(data: ArrayBuffer, mimeType: string): string {\n const bytes = new Uint8Array(data);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n const base64 = btoa(binary);\n return `data:${mimeType};base64,${base64}`;\n}\n\n/**\n * Extract a specific file from the original ZIP\n *\n * @param content - Extracted DOCX content\n * @param path - File path within the ZIP\n * @returns File content as string or ArrayBuffer, or null if not found\n */\nexport async function extractFile(\n content: RawDocxContent,\n path: string\n): Promise<string | ArrayBuffer | null> {\n const file = content.originalZip.file(path);\n if (!file) return null;\n\n const lowerPath = path.toLowerCase();\n if (lowerPath.endsWith('.xml') || lowerPath.endsWith('.rels')) {\n return file.async('text');\n } else {\n return file.async('arraybuffer');\n }\n}\n\n/**\n * Check if a file exists in the DOCX\n *\n * @param content - Extracted DOCX content\n * @param path - File path to check\n * @returns true if file exists\n */\nexport function hasFile(content: RawDocxContent, path: string): boolean {\n return content.originalZip.file(path) !== null;\n}\n\n/**\n * Get summary of DOCX content\n *\n * @param content - Extracted DOCX content\n * @returns Object with file counts and presence flags\n */\nexport function getContentSummary(content: RawDocxContent): {\n hasDocument: boolean;\n hasStyles: boolean;\n hasTheme: boolean;\n hasNumbering: boolean;\n hasFontTable: boolean;\n hasFootnotes: boolean;\n hasEndnotes: boolean;\n hasComments: boolean;\n headerCount: number;\n footerCount: number;\n mediaCount: number;\n fontCount: number;\n totalFiles: number;\n} {\n return {\n hasDocument: content.documentXml !== null,\n hasStyles: content.stylesXml !== null,\n hasTheme: content.themeXml !== null,\n hasNumbering: content.numberingXml !== null,\n hasFontTable: content.fontTableXml !== null,\n hasFootnotes: content.footnotesXml !== null,\n hasEndnotes: content.endnotesXml !== null,\n hasComments: content.commentsXml !== null,\n headerCount: content.headers.size,\n footerCount: content.footers.size,\n mediaCount: content.media.size,\n fontCount: content.fonts.size,\n totalFiles: Object.keys(content.originalZip.files).filter(\n (p) => !content.originalZip.files[p].dir\n ).length,\n };\n}\n","/**\n * Theme Parser - Parse theme1.xml for colors and fonts\n *\n * Extracts color scheme (dk1, lt1, dk2, lt2, accent1-6, hlink, folHlink)\n * and font scheme (majorFont, minorFont) from the theme.\n *\n * OOXML Reference:\n * - Theme file is at: word/theme/theme1.xml\n * - Uses DrawingML namespace (a:)\n * - Colors can be srgbClr, sysClr, or schemeClr\n */\n\nimport type { Theme, ThemeColorScheme, ThemeFontScheme, ThemeFont } from '../types/document';\nimport {\n parseXmlDocument,\n findChild,\n findChildren,\n getAttribute,\n getChildElements,\n getLocalName,\n type XmlElement,\n} from './xmlParser';\n\n/**\n * Default theme colors (Office 2016 default theme)\n * Used when theme1.xml is missing or malformed\n */\nconst DEFAULT_COLORS: ThemeColorScheme = {\n dk1: '000000', // Black\n lt1: 'FFFFFF', // White\n dk2: '44546A', // Dark blue-gray\n lt2: 'E7E6E6', // Light gray\n accent1: '4472C4', // Blue\n accent2: 'ED7D31', // Orange\n accent3: 'A5A5A5', // Gray\n accent4: 'FFC000', // Gold\n accent5: '5B9BD5', // Light blue\n accent6: '70AD47', // Green\n hlink: '0563C1', // Hyperlink blue\n folHlink: '954F72', // Followed hyperlink purple\n};\n\n/**\n * Default font scheme\n */\nconst DEFAULT_FONTS: ThemeFontScheme = {\n majorFont: {\n latin: 'Calibri Light',\n ea: '',\n cs: '',\n fonts: {},\n },\n minorFont: {\n latin: 'Calibri',\n ea: '',\n cs: '',\n fonts: {},\n },\n};\n\n/**\n * Default theme when no theme1.xml exists\n */\nconst DEFAULT_THEME: Theme = {\n name: 'Office Theme',\n colorScheme: DEFAULT_COLORS,\n fontScheme: DEFAULT_FONTS,\n};\n\n/**\n * Color slot names in theme\n */\nconst COLOR_SLOTS = [\n 'dk1',\n 'lt1',\n 'dk2',\n 'lt2',\n 'accent1',\n 'accent2',\n 'accent3',\n 'accent4',\n 'accent5',\n 'accent6',\n 'hlink',\n 'folHlink',\n] as const;\n\n/**\n * Parse a color element (srgbClr, sysClr, or schemeClr)\n *\n * @param element - Color child element\n * @returns Hex color value (6 characters, no #)\n */\nfunction parseColorElement(element: XmlElement | null): string | null {\n if (!element) return null;\n\n const localName = getLocalName(element.name || '');\n\n switch (localName) {\n case 'srgbClr': {\n // Direct RGB color: <a:srgbClr val=\"4472C4\"/>\n const val = getAttribute(element, 'a', 'val') ?? getAttribute(element, null, 'val');\n return val ?? null;\n }\n\n case 'sysClr': {\n // System color with fallback: <a:sysClr val=\"windowText\" lastClr=\"000000\"/>\n // Use lastClr as the fallback since we can't access actual system colors\n const lastClr =\n getAttribute(element, 'a', 'lastClr') ?? getAttribute(element, null, 'lastClr');\n if (lastClr) return lastClr;\n\n // Fallback based on common system color names\n const val = getAttribute(element, 'a', 'val') ?? getAttribute(element, null, 'val');\n switch (val) {\n case 'windowText':\n case 'menuText':\n case 'captionText':\n case 'btnText':\n return '000000';\n case 'window':\n case 'menu':\n case 'btnFace':\n case 'btnHighlight':\n return 'FFFFFF';\n case 'highlight':\n return '0078D7';\n case 'highlightText':\n return 'FFFFFF';\n case 'grayText':\n return '808080';\n default:\n return null;\n }\n }\n\n case 'schemeClr': {\n // Reference to another scheme color - rare in color scheme itself\n // Usually found in fill/line definitions with modifiers\n // For the color scheme, we just need the val\n const val = getAttribute(element, 'a', 'val') ?? getAttribute(element, null, 'val');\n // This is a reference, not a final color - return null for now\n // The actual resolution would need the full color scheme\n return val === 'phClr' ? null : null;\n }\n\n default:\n return null;\n }\n}\n\n/**\n * Parse the color scheme from a:clrScheme element\n *\n * @param clrScheme - The a:clrScheme element\n * @returns ThemeColorScheme with resolved hex colors\n */\nfunction parseColorScheme(clrScheme: XmlElement | null): ThemeColorScheme {\n const result: ThemeColorScheme = { ...DEFAULT_COLORS };\n\n if (!clrScheme) return result;\n\n // Each color slot has a child element with the slot name\n for (const slot of COLOR_SLOTS) {\n // Find the slot element (e.g., a:dk1, a:accent1)\n const slotElement = findChild(clrScheme, 'a', slot);\n\n if (slotElement) {\n // The actual color is a child (srgbClr, sysClr, or schemeClr)\n const children = getChildElements(slotElement);\n if (children.length > 0) {\n const color = parseColorElement(children[0]);\n if (color) {\n result[slot] = color;\n }\n }\n }\n }\n\n return result;\n}\n\n/**\n * Parse a font definition (majorFont or minorFont)\n *\n * @param fontElement - The a:majorFont or a:minorFont element\n * @returns ThemeFont with font family names\n */\nfunction parseThemeFonts(fontElement: XmlElement | null): ThemeFont {\n const result: ThemeFont = {\n latin: '',\n ea: '',\n cs: '',\n fonts: {},\n };\n\n if (!fontElement) return result;\n\n // Parse main font elements\n const latinEl = findChild(fontElement, 'a', 'latin');\n if (latinEl) {\n result.latin =\n getAttribute(latinEl, 'a', 'typeface') ?? getAttribute(latinEl, null, 'typeface') ?? '';\n }\n\n const eaEl = findChild(fontElement, 'a', 'ea');\n if (eaEl) {\n result.ea = getAttribute(eaEl, 'a', 'typeface') ?? getAttribute(eaEl, null, 'typeface') ?? '';\n }\n\n const csEl = findChild(fontElement, 'a', 'cs');\n if (csEl) {\n result.cs = getAttribute(csEl, 'a', 'typeface') ?? getAttribute(csEl, null, 'typeface') ?? '';\n }\n\n // Parse script-specific fonts (a:font elements with script attribute)\n const fontElements = findChildren(fontElement, 'a', 'font');\n for (const font of fontElements) {\n const script = getAttribute(font, 'a', 'script') ?? getAttribute(font, null, 'script');\n const typeface = getAttribute(font, 'a', 'typeface') ?? getAttribute(font, null, 'typeface');\n\n if (script && typeface) {\n result.fonts = result.fonts || {};\n result.fonts[script] = typeface;\n }\n }\n\n return result;\n}\n\n/**\n * Parse the font scheme from a:fontScheme element\n *\n * @param fontScheme - The a:fontScheme element\n * @returns ThemeFontScheme with major and minor fonts\n */\nfunction parseFontScheme(fontScheme: XmlElement | null): ThemeFontScheme {\n const result: ThemeFontScheme = { ...DEFAULT_FONTS };\n\n if (!fontScheme) return result;\n\n const majorFontEl = findChild(fontScheme, 'a', 'majorFont');\n if (majorFontEl) {\n result.majorFont = parseThemeFonts(majorFontEl);\n }\n\n const minorFontEl = findChild(fontScheme, 'a', 'minorFont');\n if (minorFontEl) {\n result.minorFont = parseThemeFonts(minorFontEl);\n }\n\n return result;\n}\n\n/**\n * Parse theme1.xml content\n *\n * @param themeXml - XML content of theme1.xml, or null if not present\n * @returns Parsed Theme object with colors and fonts\n */\nexport function parseTheme(themeXml: string | null): Theme {\n // Return defaults if no theme XML\n if (!themeXml) {\n return { ...DEFAULT_THEME };\n }\n\n try {\n const doc = parseXmlDocument(themeXml);\n if (!doc) {\n return { ...DEFAULT_THEME };\n }\n\n // Get theme name from root element\n const themeName =\n getAttribute(doc, 'a', 'name') ?? getAttribute(doc, null, 'name') ?? 'Office Theme';\n\n // Find a:themeElements which contains clrScheme and fontScheme\n const themeElements = findChild(doc, 'a', 'themeElements');\n\n // Parse color scheme\n const clrScheme = findChild(themeElements, 'a', 'clrScheme');\n const colorScheme = parseColorScheme(clrScheme);\n\n // Parse font scheme\n const fontSchemeEl = findChild(themeElements, 'a', 'fontScheme');\n const fontScheme = parseFontScheme(fontSchemeEl);\n\n return {\n name: themeName,\n colorScheme,\n fontScheme,\n };\n } catch (error) {\n console.warn('Failed to parse theme:', error);\n return { ...DEFAULT_THEME };\n }\n}\n\n/**\n * Get a color from the theme by slot name\n *\n * @param theme - Parsed theme\n * @param slot - Color slot name (dk1, lt1, accent1, etc.)\n * @returns Hex color value (6 characters, no #)\n */\nexport function getThemeColor(\n theme: Theme | null | undefined,\n slot: keyof ThemeColorScheme\n): string {\n if (!theme?.colorScheme) {\n return DEFAULT_COLORS[slot] ?? '000000';\n }\n\n return theme.colorScheme[slot] ?? DEFAULT_COLORS[slot] ?? '000000';\n}\n\n/**\n * Get the major font (heading font) from theme\n *\n * @param theme - Parsed theme\n * @param script - Optional script code (defaults to latin)\n * @returns Font family name\n */\nexport function getMajorFont(theme: Theme | null | undefined, script: string = 'latin'): string {\n if (!theme?.fontScheme?.majorFont) {\n return DEFAULT_FONTS.majorFont?.latin ?? 'Calibri Light';\n }\n\n const majorFont = theme.fontScheme.majorFont;\n\n if (script === 'latin') return majorFont.latin || 'Calibri Light';\n if (script === 'ea') return majorFont.ea || '';\n if (script === 'cs') return majorFont.cs || '';\n\n // Check script-specific fonts\n if (majorFont.fonts?.[script]) {\n return majorFont.fonts[script];\n }\n\n // Default to latin\n return majorFont.latin || 'Calibri Light';\n}\n\n/**\n * Get the minor font (body font) from theme\n *\n * @param theme - Parsed theme\n * @param script - Optional script code (defaults to latin)\n * @returns Font family name\n */\nexport function getMinorFont(theme: Theme | null | undefined, script: string = 'latin'): string {\n if (!theme?.fontScheme?.minorFont) {\n return DEFAULT_FONTS.minorFont?.latin ?? 'Calibri';\n }\n\n const minorFont = theme.fontScheme.minorFont;\n\n if (script === 'latin') return minorFont.latin || 'Calibri';\n if (script === 'ea') return minorFont.ea || '';\n if (script === 'cs') return minorFont.cs || '';\n\n // Check script-specific fonts\n if (minorFont.fonts?.[script]) {\n return minorFont.fonts[script];\n }\n\n // Default to latin\n return minorFont.latin || 'Calibri';\n}\n\n/**\n * Resolve a theme font reference to an actual font name\n *\n * Theme font references are like: majorAscii, majorHAnsi, minorAscii, minorHAnsi, etc.\n *\n * @param theme - Parsed theme\n * @param themeRef - Theme font reference\n * @returns Font family name\n */\nexport function resolveThemeFontRef(theme: Theme | null | undefined, themeRef: string): string {\n if (!themeRef) return 'Calibri';\n\n // Parse the reference: major/minor + script type\n const isMajor = themeRef.toLowerCase().includes('major');\n const isMinor = themeRef.toLowerCase().includes('minor');\n\n // Determine script from reference\n let script = 'latin';\n const lowerRef = themeRef.toLowerCase();\n\n if (lowerRef.includes('eastasia')) {\n script = 'ea';\n } else if (lowerRef.includes('bidi') || lowerRef.includes('cs')) {\n script = 'cs';\n }\n // ascii and hAnsi both map to latin\n\n if (isMajor) {\n return getMajorFont(theme, script);\n } else if (isMinor) {\n return getMinorFont(theme, script);\n }\n\n // Default to minor latin\n return getMinorFont(theme, 'latin');\n}\n\n/**\n * Get all font families from the theme for preloading\n *\n * @param theme - Parsed theme\n * @returns Array of unique font family names\n */\nexport function getThemeFonts(theme: Theme | null | undefined): string[] {\n const fonts = new Set<string>();\n\n if (theme?.fontScheme) {\n const { majorFont, minorFont } = theme.fontScheme;\n\n // Add main fonts\n if (majorFont?.latin) fonts.add(majorFont.latin);\n if (majorFont?.ea) fonts.add(majorFont.ea);\n if (majorFont?.cs) fonts.add(majorFont.cs);\n\n if (minorFont?.latin) fonts.add(minorFont.latin);\n if (minorFont?.ea) fonts.add(minorFont.ea);\n if (minorFont?.cs) fonts.add(minorFont.cs);\n\n // Add script-specific fonts\n if (majorFont?.fonts) {\n for (const font of Object.values(majorFont.fonts)) {\n if (font) fonts.add(font);\n }\n }\n\n if (minorFont?.fonts) {\n for (const font of Object.values(minorFont.fonts)) {\n if (font) fonts.add(font);\n }\n }\n }\n\n // Remove empty strings\n fonts.delete('');\n\n return Array.from(fonts);\n}\n\n/**\n * Get the default theme (Office 2016 theme)\n *\n * @returns Default Theme object\n */\nexport function getDefaultTheme(): Theme {\n return { ...DEFAULT_THEME };\n}\n","/**\n * Style Parser - Parse styles.xml with full inheritance resolution\n *\n * Parses all style types (paragraph, character, table, list) with\n * complete basedOn inheritance chain resolution.\n *\n * OOXML Reference:\n * - Style file is at: word/styles.xml\n * - Uses WordprocessingML namespace (w:)\n *\n * Style Cascade (lowest to highest priority):\n * 1. Document defaults (w:docDefaults)\n * 2. Parent style properties (w:basedOn chain)\n * 3. Current style properties\n * 4. Direct formatting in document\n */\n\nimport type {\n Theme,\n Style,\n StyleType,\n StyleDefinitions,\n DocDefaults,\n TextFormatting,\n ParagraphFormatting,\n TableFormatting,\n TableRowFormatting,\n TableCellFormatting,\n ColorValue,\n BorderSpec,\n ShadingProperties,\n TabStop,\n TabStopAlignment,\n TabLeader,\n UnderlineStyle,\n TableBorders,\n CellMargins,\n TableLook,\n TableMeasurement,\n} from '../types/document';\nimport {\n parseXmlDocument,\n findChild,\n findChildren,\n getAttribute,\n parseBooleanElement,\n parseNumericAttribute,\n type XmlElement,\n} from './xmlParser';\nimport { resolveThemeFontRef } from './themeParser';\n\n/**\n * Style map keyed by styleId\n */\nexport type StyleMap = Map<string, Style>;\n\n/**\n * Parse text formatting properties (w:rPr)\n */\nfunction parseRunProperties(\n rPr: XmlElement | null,\n theme: Theme | null\n): TextFormatting | undefined {\n if (!rPr) return undefined;\n\n const formatting: TextFormatting = {};\n\n // Bold\n const b = findChild(rPr, 'w', 'b');\n if (b) formatting.bold = parseBooleanElement(b);\n\n const bCs = findChild(rPr, 'w', 'bCs');\n if (bCs) formatting.boldCs = parseBooleanElement(bCs);\n\n // Italic\n const i = findChild(rPr, 'w', 'i');\n if (i) formatting.italic = parseBooleanElement(i);\n\n const iCs = findChild(rPr, 'w', 'iCs');\n if (iCs) formatting.italicCs = parseBooleanElement(iCs);\n\n // Underline\n const u = findChild(rPr, 'w', 'u');\n if (u) {\n const style = getAttribute(u, 'w', 'val') as UnderlineStyle | null;\n if (style) {\n formatting.underline = { style };\n const colorVal = getAttribute(u, 'w', 'color');\n const themeColor = getAttribute(u, 'w', 'themeColor');\n if (colorVal || themeColor) {\n formatting.underline.color = parseColorValue(\n colorVal,\n themeColor,\n getAttribute(u, 'w', 'themeTint'),\n getAttribute(u, 'w', 'themeShade')\n );\n }\n }\n }\n\n // Strikethrough\n const strike = findChild(rPr, 'w', 'strike');\n if (strike) formatting.strike = parseBooleanElement(strike);\n\n const dstrike = findChild(rPr, 'w', 'dstrike');\n if (dstrike) formatting.doubleStrike = parseBooleanElement(dstrike);\n\n // Vertical alignment (superscript/subscript)\n const vertAlign = findChild(rPr, 'w', 'vertAlign');\n if (vertAlign) {\n const val = getAttribute(vertAlign, 'w', 'val');\n if (val === 'superscript' || val === 'subscript' || val === 'baseline') {\n formatting.vertAlign = val;\n }\n }\n\n // Capitalization\n const smallCaps = findChild(rPr, 'w', 'smallCaps');\n if (smallCaps) formatting.smallCaps = parseBooleanElement(smallCaps);\n\n const caps = findChild(rPr, 'w', 'caps');\n if (caps) formatting.allCaps = parseBooleanElement(caps);\n\n // Hidden\n const vanish = findChild(rPr, 'w', 'vanish');\n if (vanish) formatting.hidden = parseBooleanElement(vanish);\n\n // Color\n const color = findChild(rPr, 'w', 'color');\n if (color) {\n formatting.color = parseColorValue(\n getAttribute(color, 'w', 'val'),\n getAttribute(color, 'w', 'themeColor'),\n getAttribute(color, 'w', 'themeTint'),\n getAttribute(color, 'w', 'themeShade')\n );\n }\n\n // Highlight\n const highlight = findChild(rPr, 'w', 'highlight');\n if (highlight) {\n const val = getAttribute(highlight, 'w', 'val');\n if (val) {\n formatting.highlight = val as TextFormatting['highlight'];\n }\n }\n\n // Character shading\n const shd = findChild(rPr, 'w', 'shd');\n if (shd) {\n formatting.shading = parseShadingProperties(shd);\n }\n\n // Font size (in half-points)\n const sz = findChild(rPr, 'w', 'sz');\n if (sz) {\n const val = parseNumericAttribute(sz, 'w', 'val');\n if (val !== undefined) formatting.fontSize = val;\n }\n\n const szCs = findChild(rPr, 'w', 'szCs');\n if (szCs) {\n const val = parseNumericAttribute(szCs, 'w', 'val');\n if (val !== undefined) formatting.fontSizeCs = val;\n }\n\n // Font family\n const rFonts = findChild(rPr, 'w', 'rFonts');\n if (rFonts) {\n formatting.fontFamily = {\n ascii: getAttribute(rFonts, 'w', 'ascii') ?? undefined,\n hAnsi: getAttribute(rFonts, 'w', 'hAnsi') ?? undefined,\n eastAsia: getAttribute(rFonts, 'w', 'eastAsia') ?? undefined,\n cs: getAttribute(rFonts, 'w', 'cs') ?? undefined,\n };\n\n // Theme font references - resolve to actual font names\n const asciiTheme = getAttribute(rFonts, 'w', 'asciiTheme');\n if (asciiTheme) {\n formatting.fontFamily.asciiTheme = asciiTheme as TextFormatting['fontFamily'] extends {\n asciiTheme?: infer T;\n }\n ? T\n : never;\n // Also resolve the actual font name for convenience\n if (theme && !formatting.fontFamily.ascii) {\n formatting.fontFamily.ascii = resolveThemeFontRef(theme, asciiTheme);\n }\n }\n const hAnsiTheme = getAttribute(rFonts, 'w', 'hAnsiTheme');\n if (hAnsiTheme) {\n formatting.fontFamily.hAnsiTheme = hAnsiTheme;\n if (theme && !formatting.fontFamily.hAnsi) {\n formatting.fontFamily.hAnsi = resolveThemeFontRef(theme, hAnsiTheme);\n }\n }\n const eastAsiaTheme = getAttribute(rFonts, 'w', 'eastAsiaTheme');\n if (eastAsiaTheme) {\n formatting.fontFamily.eastAsiaTheme = eastAsiaTheme;\n if (theme && !formatting.fontFamily.eastAsia) {\n formatting.fontFamily.eastAsia = resolveThemeFontRef(theme, eastAsiaTheme);\n }\n }\n const csTheme = getAttribute(rFonts, 'w', 'cstheme');\n if (csTheme) {\n formatting.fontFamily.csTheme = csTheme;\n if (theme && !formatting.fontFamily.cs) {\n formatting.fontFamily.cs = resolveThemeFontRef(theme, csTheme);\n }\n }\n }\n\n // Character spacing (in twips)\n const spacing = findChild(rPr, 'w', 'spacing');\n if (spacing) {\n const val = parseNumericAttribute(spacing, 'w', 'val');\n if (val !== undefined) formatting.spacing = val;\n }\n\n // Position (raised/lowered in half-points)\n const position = findChild(rPr, 'w', 'position');\n if (position) {\n const val = parseNumericAttribute(position, 'w', 'val');\n if (val !== undefined) formatting.position = val;\n }\n\n // Scale (horizontal text scale percentage)\n const w = findChild(rPr, 'w', 'w');\n if (w) {\n const val = parseNumericAttribute(w, 'w', 'val');\n if (val !== undefined) formatting.scale = val;\n }\n\n // Kerning\n const kern = findChild(rPr, 'w', 'kern');\n if (kern) {\n const val = parseNumericAttribute(kern, 'w', 'val');\n if (val !== undefined) formatting.kerning = val;\n }\n\n // Text effects\n const effect = findChild(rPr, 'w', 'effect');\n if (effect) {\n const val = getAttribute(effect, 'w', 'val');\n if (val) formatting.effect = val as TextFormatting['effect'];\n }\n\n // Emphasis mark\n const em = findChild(rPr, 'w', 'em');\n if (em) {\n const val = getAttribute(em, 'w', 'val');\n if (val) formatting.emphasisMark = val as TextFormatting['emphasisMark'];\n }\n\n // Other effects\n const emboss = findChild(rPr, 'w', 'emboss');\n if (emboss) formatting.emboss = parseBooleanElement(emboss);\n\n const imprint = findChild(rPr, 'w', 'imprint');\n if (imprint) formatting.imprint = parseBooleanElement(imprint);\n\n const outline = findChild(rPr, 'w', 'outline');\n if (outline) formatting.outline = parseBooleanElement(outline);\n\n const shadow = findChild(rPr, 'w', 'shadow');\n if (shadow) formatting.shadow = parseBooleanElement(shadow);\n\n // RTL and complex script\n const rtl = findChild(rPr, 'w', 'rtl');\n if (rtl) formatting.rtl = parseBooleanElement(rtl);\n\n const cs = findChild(rPr, 'w', 'cs');\n if (cs) formatting.cs = parseBooleanElement(cs);\n\n // Character style reference\n const rStyle = findChild(rPr, 'w', 'rStyle');\n if (rStyle) {\n const val = getAttribute(rStyle, 'w', 'val');\n if (val) formatting.styleId = val;\n }\n\n return Object.keys(formatting).length > 0 ? formatting : undefined;\n}\n\n/**\n * Parse color value from attributes\n */\nfunction parseColorValue(\n rgb: string | null,\n themeColor: string | null,\n themeTint: string | null,\n themeShade: string | null\n): ColorValue {\n const color: ColorValue = {};\n\n if (rgb && rgb !== 'auto') {\n color.rgb = rgb;\n } else if (rgb === 'auto') {\n color.auto = true;\n }\n\n if (themeColor) {\n color.themeColor = themeColor as ColorValue['themeColor'];\n }\n\n if (themeTint) {\n color.themeTint = themeTint;\n }\n\n if (themeShade) {\n color.themeShade = themeShade;\n }\n\n return color;\n}\n\n/**\n * Parse shading properties (w:shd)\n */\nfunction parseShadingProperties(shd: XmlElement | null): ShadingProperties | undefined {\n if (!shd) return undefined;\n\n const props: ShadingProperties = {};\n\n const color = getAttribute(shd, 'w', 'color');\n if (color && color !== 'auto') {\n props.color = { rgb: color };\n }\n\n const fill = getAttribute(shd, 'w', 'fill');\n if (fill && fill !== 'auto') {\n props.fill = { rgb: fill };\n }\n\n const themeFill = getAttribute(shd, 'w', 'themeFill');\n if (themeFill) {\n props.fill = props.fill || {};\n props.fill.themeColor = themeFill as ColorValue['themeColor'];\n }\n\n const themeFillTint = getAttribute(shd, 'w', 'themeFillTint');\n if (themeFillTint && props.fill) {\n props.fill.themeTint = themeFillTint;\n }\n\n const themeFillShade = getAttribute(shd, 'w', 'themeFillShade');\n if (themeFillShade && props.fill) {\n props.fill.themeShade = themeFillShade;\n }\n\n const pattern = getAttribute(shd, 'w', 'val');\n if (pattern) {\n props.pattern = pattern as ShadingProperties['pattern'];\n }\n\n return Object.keys(props).length > 0 ? props : undefined;\n}\n\n/**\n * Parse border specification\n */\nfunction parseBorderSpec(border: XmlElement | null): BorderSpec | undefined {\n if (!border) return undefined;\n\n const style = getAttribute(border, 'w', 'val');\n if (!style) return undefined;\n\n const spec: BorderSpec = {\n style: style as BorderSpec['style'],\n };\n\n const colorVal = getAttribute(border, 'w', 'color');\n const themeColor = getAttribute(border, 'w', 'themeColor');\n if (colorVal || themeColor) {\n spec.color = parseColorValue(\n colorVal,\n themeColor,\n getAttribute(border, 'w', 'themeTint'),\n getAttribute(border, 'w', 'themeShade')\n );\n }\n\n const sz = parseNumericAttribute(border, 'w', 'sz');\n if (sz !== undefined) spec.size = sz;\n\n const space = parseNumericAttribute(border, 'w', 'space');\n if (space !== undefined) spec.space = space;\n\n const shadowAttr = getAttribute(border, 'w', 'shadow');\n if (shadowAttr) spec.shadow = shadowAttr === '1' || shadowAttr === 'true';\n\n const frame = getAttribute(border, 'w', 'frame');\n if (frame) spec.frame = frame === '1' || frame === 'true';\n\n return spec;\n}\n\n/**\n * Parse tab stops (w:tabs)\n */\nfunction parseTabStops(tabs: XmlElement | null): TabStop[] | undefined {\n if (!tabs) return undefined;\n\n const tabElements = findChildren(tabs, 'w', 'tab');\n if (tabElements.length === 0) return undefined;\n\n const result: TabStop[] = [];\n\n for (const tab of tabElements) {\n const pos = parseNumericAttribute(tab, 'w', 'pos');\n const val = getAttribute(tab, 'w', 'val');\n\n if (pos !== undefined && val) {\n const tabStop: TabStop = {\n position: pos,\n alignment: val as TabStopAlignment,\n };\n\n const leader = getAttribute(tab, 'w', 'leader');\n if (leader) {\n tabStop.leader = leader as TabLeader;\n }\n\n result.push(tabStop);\n }\n }\n\n return result.length > 0 ? result : undefined;\n}\n\n/**\n * Parse paragraph formatting properties (w:pPr)\n */\nfunction parseParagraphProperties(\n pPr: XmlElement | null,\n theme: Theme | null\n): ParagraphFormatting | undefined {\n if (!pPr) return undefined;\n\n const formatting: ParagraphFormatting = {};\n\n // Alignment\n const jc = findChild(pPr, 'w', 'jc');\n if (jc) {\n const val = getAttribute(jc, 'w', 'val');\n if (val) formatting.alignment = val as ParagraphFormatting['alignment'];\n }\n\n // Bidi\n const bidi = findChild(pPr, 'w', 'bidi');\n if (bidi) formatting.bidi = parseBooleanElement(bidi);\n\n // Spacing\n const spacing = findChild(pPr, 'w', 'spacing');\n if (spacing) {\n const before = parseNumericAttribute(spacing, 'w', 'before');\n if (before !== undefined) formatting.spaceBefore = before;\n\n const after = parseNumericAttribute(spacing, 'w', 'after');\n if (after !== undefined) formatting.spaceAfter = after;\n\n const line = parseNumericAttribute(spacing, 'w', 'line');\n if (line !== undefined) formatting.lineSpacing = line;\n\n const lineRule = getAttribute(spacing, 'w', 'lineRule');\n if (lineRule) formatting.lineSpacingRule = lineRule as ParagraphFormatting['lineSpacingRule'];\n\n const beforeAuto = getAttribute(spacing, 'w', 'beforeAutospacing');\n if (beforeAuto) formatting.beforeAutospacing = beforeAuto === '1' || beforeAuto === 'true';\n\n const afterAuto = getAttribute(spacing, 'w', 'afterAutospacing');\n if (afterAuto) formatting.afterAutospacing = afterAuto === '1' || afterAuto === 'true';\n }\n\n // Indentation\n const ind = findChild(pPr, 'w', 'ind');\n if (ind) {\n const left = parseNumericAttribute(ind, 'w', 'left');\n if (left !== undefined) formatting.indentLeft = left;\n\n const right = parseNumericAttribute(ind, 'w', 'right');\n if (right !== undefined) formatting.indentRight = right;\n\n const firstLine = parseNumericAttribute(ind, 'w', 'firstLine');\n if (firstLine !== undefined) formatting.indentFirstLine = firstLine;\n\n const hanging = parseNumericAttribute(ind, 'w', 'hanging');\n if (hanging !== undefined) {\n formatting.indentFirstLine = -hanging;\n formatting.hangingIndent = true;\n }\n }\n\n // Borders\n const pBdr = findChild(pPr, 'w', 'pBdr');\n if (pBdr) {\n const borders: ParagraphFormatting['borders'] = {};\n const top = parseBorderSpec(findChild(pBdr, 'w', 'top'));\n if (top) borders.top = top;\n const bottom = parseBorderSpec(findChild(pBdr, 'w', 'bottom'));\n if (bottom) borders.bottom = bottom;\n const left = parseBorderSpec(findChild(pBdr, 'w', 'left'));\n if (left) borders.left = left;\n const right = parseBorderSpec(findChild(pBdr, 'w', 'right'));\n if (right) borders.right = right;\n const between = parseBorderSpec(findChild(pBdr, 'w', 'between'));\n if (between) borders.between = between;\n const bar = parseBorderSpec(findChild(pBdr, 'w', 'bar'));\n if (bar) borders.bar = bar;\n\n if (Object.keys(borders).length > 0) {\n formatting.borders = borders;\n }\n }\n\n // Shading\n const shd = findChild(pPr, 'w', 'shd');\n if (shd) {\n formatting.shading = parseShadingProperties(shd);\n }\n\n // Tab stops\n const tabs = findChild(pPr, 'w', 'tabs');\n if (tabs) {\n formatting.tabs = parseTabStops(tabs);\n }\n\n // Page break control\n const keepNext = findChild(pPr, 'w', 'keepNext');\n if (keepNext) formatting.keepNext = parseBooleanElement(keepNext);\n\n const keepLines = findChild(pPr, 'w', 'keepLines');\n if (keepLines) formatting.keepLines = parseBooleanElement(keepLines);\n\n const widowControl = findChild(pPr, 'w', 'widowControl');\n if (widowControl) formatting.widowControl = parseBooleanElement(widowControl);\n\n const pageBreakBefore = findChild(pPr, 'w', 'pageBreakBefore');\n if (pageBreakBefore) formatting.pageBreakBefore = parseBooleanElement(pageBreakBefore);\n\n const contextualSpacing = findChild(pPr, 'w', 'contextualSpacing');\n if (contextualSpacing) formatting.contextualSpacing = parseBooleanElement(contextualSpacing);\n\n // Numbering properties\n const numPr = findChild(pPr, 'w', 'numPr');\n if (numPr) {\n const numId = findChild(numPr, 'w', 'numId');\n const ilvl = findChild(numPr, 'w', 'ilvl');\n\n if (numId || ilvl) {\n formatting.numPr = {};\n if (numId) {\n const val = parseNumericAttribute(numId, 'w', 'val');\n if (val !== undefined) formatting.numPr.numId = val;\n }\n if (ilvl) {\n const val = parseNumericAttribute(ilvl, 'w', 'val');\n if (val !== undefined) formatting.numPr.ilvl = val;\n }\n }\n }\n\n // Outline level\n const outlineLvl = findChild(pPr, 'w', 'outlineLvl');\n if (outlineLvl) {\n const val = parseNumericAttribute(outlineLvl, 'w', 'val');\n if (val !== undefined) formatting.outlineLevel = val;\n }\n\n // Style reference\n const pStyle = findChild(pPr, 'w', 'pStyle');\n if (pStyle) {\n const val = getAttribute(pStyle, 'w', 'val');\n if (val) formatting.styleId = val;\n }\n\n // Suppress line numbers\n const suppressLineNumbers = findChild(pPr, 'w', 'suppressLineNumbers');\n if (suppressLineNumbers)\n formatting.suppressLineNumbers = parseBooleanElement(suppressLineNumbers);\n\n // Suppress auto hyphens\n const suppressAutoHyphens = findChild(pPr, 'w', 'suppressAutoHyphens');\n if (suppressAutoHyphens)\n formatting.suppressAutoHyphens = parseBooleanElement(suppressAutoHyphens);\n\n // Run properties for this paragraph (default run formatting)\n const rPr = findChild(pPr, 'w', 'rPr');\n if (rPr) {\n formatting.runProperties = parseRunProperties(rPr, theme);\n }\n\n return Object.keys(formatting).length > 0 ? formatting : undefined;\n}\n\n/**\n * Parse table measurement (width/height with type)\n */\nfunction parseTableMeasurement(element: XmlElement | null): TableMeasurement | undefined {\n if (!element) return undefined;\n\n const w = parseNumericAttribute(element, 'w', 'w');\n const type = getAttribute(element, 'w', 'type');\n\n if (w !== undefined && type) {\n return {\n value: w,\n type: type as TableMeasurement['type'],\n };\n }\n\n return undefined;\n}\n\n/**\n * Parse table borders\n */\nfunction parseTableBorders(tblBorders: XmlElement | null): TableBorders | undefined {\n if (!tblBorders) return undefined;\n\n const borders: TableBorders = {};\n\n const top = parseBorderSpec(findChild(tblBorders, 'w', 'top'));\n if (top) borders.top = top;\n\n const bottom = parseBorderSpec(findChild(tblBorders, 'w', 'bottom'));\n if (bottom) borders.bottom = bottom;\n\n const left = parseBorderSpec(findChild(tblBorders, 'w', 'left'));\n if (left) borders.left = left;\n\n const right = parseBorderSpec(findChild(tblBorders, 'w', 'right'));\n if (right) borders.right = right;\n\n const insideH = parseBorderSpec(findChild(tblBorders, 'w', 'insideH'));\n if (insideH) borders.insideH = insideH;\n\n const insideV = parseBorderSpec(findChild(tblBorders, 'w', 'insideV'));\n if (insideV) borders.insideV = insideV;\n\n return Object.keys(borders).length > 0 ? borders : undefined;\n}\n\n/**\n * Parse cell margins\n */\nfunction parseCellMargins(tblCellMar: XmlElement | null): CellMargins | undefined {\n if (!tblCellMar) return undefined;\n\n const margins: CellMargins = {};\n\n const top = parseTableMeasurement(findChild(tblCellMar, 'w', 'top'));\n if (top) margins.top = top;\n\n const bottom = parseTableMeasurement(findChild(tblCellMar, 'w', 'bottom'));\n if (bottom) margins.bottom = bottom;\n\n const left = parseTableMeasurement(findChild(tblCellMar, 'w', 'left'));\n if (left) margins.left = left;\n\n const right = parseTableMeasurement(findChild(tblCellMar, 'w', 'right'));\n if (right) margins.right = right;\n\n return Object.keys(margins).length > 0 ? margins : undefined;\n}\n\n/**\n * Parse table look flags\n */\nfunction parseTableLook(tblLook: XmlElement | null): TableLook | undefined {\n if (!tblLook) return undefined;\n\n const look: TableLook = {};\n\n // Can be specified as individual attributes or a single val attribute\n const val = getAttribute(tblLook, 'w', 'val');\n if (val) {\n // val is a hex bitmap: bit 0=firstRow, 1=lastRow, 2=firstCol, 3=lastCol, 4=noHBand, 5=noVBand\n const num = parseInt(val, 16);\n if (!isNaN(num)) {\n look.firstRow = (num & 0x0020) !== 0;\n look.lastRow = (num & 0x0040) !== 0;\n look.firstColumn = (num & 0x0080) !== 0;\n look.lastColumn = (num & 0x0100) !== 0;\n look.noHBand = (num & 0x0200) !== 0;\n look.noVBand = (num & 0x0400) !== 0;\n }\n }\n\n // Individual attributes override\n const firstColumn = getAttribute(tblLook, 'w', 'firstColumn');\n if (firstColumn) look.firstColumn = firstColumn === '1';\n\n const firstRow = getAttribute(tblLook, 'w', 'firstRow');\n if (firstRow) look.firstRow = firstRow === '1';\n\n const lastColumn = getAttribute(tblLook, 'w', 'lastColumn');\n if (lastColumn) look.lastColumn = lastColumn === '1';\n\n const lastRow = getAttribute(tblLook, 'w', 'lastRow');\n if (lastRow) look.lastRow = lastRow === '1';\n\n const noHBand = getAttribute(tblLook, 'w', 'noHBand');\n if (noHBand) look.noHBand = noHBand === '1';\n\n const noVBand = getAttribute(tblLook, 'w', 'noVBand');\n if (noVBand) look.noVBand = noVBand === '1';\n\n return Object.keys(look).length > 0 ? look : undefined;\n}\n\n/**\n * Parse table formatting properties (w:tblPr)\n */\nfunction parseTableProperties(\n tblPr: XmlElement | null,\n _theme: Theme | null\n): TableFormatting | undefined {\n if (!tblPr) return undefined;\n\n const formatting: TableFormatting = {};\n\n // Table width\n const tblW = findChild(tblPr, 'w', 'tblW');\n if (tblW) {\n formatting.width = parseTableMeasurement(tblW);\n }\n\n // Table alignment/justification\n const jc = findChild(tblPr, 'w', 'jc');\n if (jc) {\n const val = getAttribute(jc, 'w', 'val');\n if (val === 'left' || val === 'center' || val === 'right') {\n formatting.justification = val;\n }\n }\n\n // Cell spacing\n const tblCellSpacing = findChild(tblPr, 'w', 'tblCellSpacing');\n if (tblCellSpacing) {\n formatting.cellSpacing = parseTableMeasurement(tblCellSpacing);\n }\n\n // Table indent\n const tblInd = findChild(tblPr, 'w', 'tblInd');\n if (tblInd) {\n formatting.indent = parseTableMeasurement(tblInd);\n }\n\n // Table borders\n const tblBorders = findChild(tblPr, 'w', 'tblBorders');\n if (tblBorders) {\n formatting.borders = parseTableBorders(tblBorders);\n }\n\n // Cell margins\n const tblCellMar = findChild(tblPr, 'w', 'tblCellMar');\n if (tblCellMar) {\n formatting.cellMargins = parseCellMargins(tblCellMar);\n }\n\n // Table layout\n const tblLayout = findChild(tblPr, 'w', 'tblLayout');\n if (tblLayout) {\n const val = getAttribute(tblLayout, 'w', 'type');\n if (val === 'fixed' || val === 'autofit') {\n formatting.layout = val;\n }\n }\n\n // Table style\n const tblStyle = findChild(tblPr, 'w', 'tblStyle');\n if (tblStyle) {\n const val = getAttribute(tblStyle, 'w', 'val');\n if (val) formatting.styleId = val;\n }\n\n // Table look\n const tblLook = findChild(tblPr, 'w', 'tblLook');\n if (tblLook) {\n formatting.look = parseTableLook(tblLook);\n }\n\n // Shading\n const shd = findChild(tblPr, 'w', 'shd');\n if (shd) {\n formatting.shading = parseShadingProperties(shd);\n }\n\n // Bidi\n const bidiVisual = findChild(tblPr, 'w', 'bidiVisual');\n if (bidiVisual) formatting.bidi = parseBooleanElement(bidiVisual);\n\n return Object.keys(formatting).length > 0 ? formatting : undefined;\n}\n\n/**\n * Parse table row formatting properties (w:trPr)\n */\nfunction parseTableRowProperties(trPr: XmlElement | null): TableRowFormatting | undefined {\n if (!trPr) return undefined;\n\n const formatting: TableRowFormatting = {};\n\n // Row height\n const trHeight = findChild(trPr, 'w', 'trHeight');\n if (trHeight) {\n formatting.height = parseTableMeasurement(trHeight);\n const hRule = getAttribute(trHeight, 'w', 'hRule');\n if (hRule) {\n formatting.heightRule = hRule as TableRowFormatting['heightRule'];\n }\n }\n\n // Header row\n const tblHeader = findChild(trPr, 'w', 'tblHeader');\n if (tblHeader) formatting.header = parseBooleanElement(tblHeader);\n\n // Can't split\n const cantSplit = findChild(trPr, 'w', 'cantSplit');\n if (cantSplit) formatting.cantSplit = parseBooleanElement(cantSplit);\n\n // Row justification\n const jc = findChild(trPr, 'w', 'jc');\n if (jc) {\n const val = getAttribute(jc, 'w', 'val');\n if (val === 'left' || val === 'center' || val === 'right') {\n formatting.justification = val;\n }\n }\n\n // Hidden\n const hidden = findChild(trPr, 'w', 'hidden');\n if (hidden) formatting.hidden = parseBooleanElement(hidden);\n\n return Object.keys(formatting).length > 0 ? formatting : undefined;\n}\n\n/**\n * Parse table cell formatting properties (w:tcPr)\n */\nfunction parseTableCellProperties(\n tcPr: XmlElement | null,\n _theme: Theme | null\n): TableCellFormatting | undefined {\n if (!tcPr) return undefined;\n\n const formatting: TableCellFormatting = {};\n\n // Cell width\n const tcW = findChild(tcPr, 'w', 'tcW');\n if (tcW) {\n formatting.width = parseTableMeasurement(tcW);\n }\n\n // Cell borders\n const tcBorders = findChild(tcPr, 'w', 'tcBorders');\n if (tcBorders) {\n formatting.borders = parseTableBorders(tcBorders);\n }\n\n // Cell margins\n const tcMar = findChild(tcPr, 'w', 'tcMar');\n if (tcMar) {\n formatting.margins = parseCellMargins(tcMar);\n }\n\n // Shading\n const shd = findChild(tcPr, 'w', 'shd');\n if (shd) {\n formatting.shading = parseShadingProperties(shd);\n }\n\n // Vertical alignment\n const vAlign = findChild(tcPr, 'w', 'vAlign');\n if (vAlign) {\n const val = getAttribute(vAlign, 'w', 'val');\n if (val === 'top' || val === 'center' || val === 'bottom') {\n formatting.verticalAlign = val;\n }\n }\n\n // Text direction\n const textDirection = findChild(tcPr, 'w', 'textDirection');\n if (textDirection) {\n const val = getAttribute(textDirection, 'w', 'val');\n if (val) formatting.textDirection = val as TableCellFormatting['textDirection'];\n }\n\n // Grid span (horizontal merge)\n const gridSpan = findChild(tcPr, 'w', 'gridSpan');\n if (gridSpan) {\n const val = parseNumericAttribute(gridSpan, 'w', 'val');\n if (val !== undefined) formatting.gridSpan = val;\n }\n\n // Vertical merge\n const vMerge = findChild(tcPr, 'w', 'vMerge');\n if (vMerge) {\n const val = getAttribute(vMerge, 'w', 'val');\n formatting.vMerge = val === 'restart' ? 'restart' : 'continue';\n }\n\n // Fit text\n const tcFitText = findChild(tcPr, 'w', 'tcFitText');\n if (tcFitText) formatting.fitText = parseBooleanElement(tcFitText);\n\n // No wrap\n const noWrap = findChild(tcPr, 'w', 'noWrap');\n if (noWrap) formatting.noWrap = parseBooleanElement(noWrap);\n\n // Hide mark\n const hideMark = findChild(tcPr, 'w', 'hideMark');\n if (hideMark) formatting.hideMark = parseBooleanElement(hideMark);\n\n return Object.keys(formatting).length > 0 ? formatting : undefined;\n}\n\n/**\n * Parse a single style element (w:style)\n */\nfunction parseStyle(styleEl: XmlElement, theme: Theme | null): Style {\n const style: Style = {\n styleId: getAttribute(styleEl, 'w', 'styleId') ?? '',\n type: (getAttribute(styleEl, 'w', 'type') as StyleType) ?? 'paragraph',\n };\n\n // Default flag\n const defaultAttr = getAttribute(styleEl, 'w', 'default');\n if (defaultAttr) style.default = defaultAttr === '1' || defaultAttr === 'true';\n\n // Name\n const nameEl = findChild(styleEl, 'w', 'name');\n if (nameEl) {\n style.name = getAttribute(nameEl, 'w', 'val') ?? undefined;\n }\n\n // Based on (inheritance)\n const basedOn = findChild(styleEl, 'w', 'basedOn');\n if (basedOn) {\n style.basedOn = getAttribute(basedOn, 'w', 'val') ?? undefined;\n }\n\n // Next style\n const next = findChild(styleEl, 'w', 'next');\n if (next) {\n style.next = getAttribute(next, 'w', 'val') ?? undefined;\n }\n\n // Linked style\n const link = findChild(styleEl, 'w', 'link');\n if (link) {\n style.link = getAttribute(link, 'w', 'val') ?? undefined;\n }\n\n // UI Priority\n const uiPriority = findChild(styleEl, 'w', 'uiPriority');\n if (uiPriority) {\n const val = parseNumericAttribute(uiPriority, 'w', 'val');\n if (val !== undefined) style.uiPriority = val;\n }\n\n // Hidden/Semi-hidden\n const hidden = findChild(styleEl, 'w', 'hidden');\n if (hidden) style.hidden = parseBooleanElement(hidden);\n\n const semiHidden = findChild(styleEl, 'w', 'semiHidden');\n if (semiHidden) style.semiHidden = parseBooleanElement(semiHidden);\n\n // Unhide when used\n const unhideWhenUsed = findChild(styleEl, 'w', 'unhideWhenUsed');\n if (unhideWhenUsed) style.unhideWhenUsed = parseBooleanElement(unhideWhenUsed);\n\n // Quick format\n const qFormat = findChild(styleEl, 'w', 'qFormat');\n if (qFormat) style.qFormat = parseBooleanElement(qFormat);\n\n // Personal/custom style\n const personal = findChild(styleEl, 'w', 'personal');\n if (personal) style.personal = parseBooleanElement(personal);\n\n // Paragraph properties\n const pPr = findChild(styleEl, 'w', 'pPr');\n if (pPr) {\n style.pPr = parseParagraphProperties(pPr, theme);\n }\n\n // Run properties\n const rPr = findChild(styleEl, 'w', 'rPr');\n if (rPr) {\n style.rPr = parseRunProperties(rPr, theme);\n }\n\n // Table properties (for table styles)\n const tblPr = findChild(styleEl, 'w', 'tblPr');\n if (tblPr) {\n style.tblPr = parseTableProperties(tblPr, theme);\n }\n\n // Table row properties\n const trPr = findChild(styleEl, 'w', 'trPr');\n if (trPr) {\n style.trPr = parseTableRowProperties(trPr);\n }\n\n // Table cell properties\n const tcPr = findChild(styleEl, 'w', 'tcPr');\n if (tcPr) {\n style.tcPr = parseTableCellProperties(tcPr, theme);\n }\n\n // Table style conditional formatting (tblStylePr)\n const tblStylePrs = findChildren(styleEl, 'w', 'tblStylePr');\n if (tblStylePrs.length > 0) {\n style.tblStylePr = [];\n\n for (const tblStylePr of tblStylePrs) {\n const typeAttr = getAttribute(tblStylePr, 'w', 'type');\n if (typeAttr) {\n const conditionalStyle: NonNullable<Style['tblStylePr']>[number] = {\n type: typeAttr as any,\n };\n\n const condPPr = findChild(tblStylePr, 'w', 'pPr');\n if (condPPr) conditionalStyle.pPr = parseParagraphProperties(condPPr, theme);\n\n const condRPr = findChild(tblStylePr, 'w', 'rPr');\n if (condRPr) conditionalStyle.rPr = parseRunProperties(condRPr, theme);\n\n const condTblPr = findChild(tblStylePr, 'w', 'tblPr');\n if (condTblPr) conditionalStyle.tblPr = parseTableProperties(condTblPr, theme);\n\n const condTrPr = findChild(tblStylePr, 'w', 'trPr');\n if (condTrPr) conditionalStyle.trPr = parseTableRowProperties(condTrPr);\n\n const condTcPr = findChild(tblStylePr, 'w', 'tcPr');\n if (condTcPr) conditionalStyle.tcPr = parseTableCellProperties(condTcPr, theme);\n\n style.tblStylePr.push(conditionalStyle);\n }\n }\n }\n\n return style;\n}\n\n/**\n * Parse document defaults (w:docDefaults)\n */\nfunction parseDocDefaults(\n docDefaults: XmlElement | null,\n theme: Theme | null\n): DocDefaults | undefined {\n if (!docDefaults) return undefined;\n\n const result: DocDefaults = {};\n\n // Default run properties\n const rPrDefault = findChild(docDefaults, 'w', 'rPrDefault');\n if (rPrDefault) {\n const rPr = findChild(rPrDefault, 'w', 'rPr');\n if (rPr) {\n result.rPr = parseRunProperties(rPr, theme);\n }\n }\n\n // Default paragraph properties\n const pPrDefault = findChild(docDefaults, 'w', 'pPrDefault');\n if (pPrDefault) {\n const pPr = findChild(pPrDefault, 'w', 'pPr');\n if (pPr) {\n result.pPr = parseParagraphProperties(pPr, theme);\n }\n }\n\n return result.rPr || result.pPr ? result : undefined;\n}\n\n/**\n * Deep merge text formatting (source overrides target)\n */\nfunction mergeTextFormatting(\n target: TextFormatting | undefined,\n source: TextFormatting | undefined\n): TextFormatting | undefined {\n if (!source) return target;\n if (!target) return source ? { ...source } : undefined;\n\n const result = { ...target };\n\n // Copy all defined properties from source\n for (const key of Object.keys(source) as (keyof TextFormatting)[]) {\n const value = source[key];\n if (value !== undefined) {\n (result as any)[key] =\n typeof value === 'object' && value !== null\n ? { ...((result[key] as any) || {}), ...value }\n : value;\n }\n }\n\n return result;\n}\n\n/**\n * Deep merge paragraph formatting (source overrides target)\n */\nfunction mergeParagraphFormatting(\n target: ParagraphFormatting | undefined,\n source: ParagraphFormatting | undefined\n): ParagraphFormatting | undefined {\n if (!source) return target;\n if (!target) return source ? { ...source } : undefined;\n\n const result = { ...target };\n\n for (const key of Object.keys(source) as (keyof ParagraphFormatting)[]) {\n const value = source[key];\n if (value !== undefined) {\n if (key === 'runProperties') {\n result.runProperties = mergeTextFormatting(result.runProperties, source.runProperties);\n } else if (key === 'borders' || key === 'numPr' || key === 'frame') {\n const baseValue = result[key] as Record<string, unknown> | undefined;\n const sourceValue = value as Record<string, unknown> | undefined;\n (result as Record<string, unknown>)[key] = { ...(baseValue || {}), ...(sourceValue || {}) };\n } else if (key === 'tabs' && Array.isArray(value)) {\n result.tabs = [...value];\n } else {\n (result as any)[key] = value;\n }\n }\n }\n\n return result;\n}\n\n/**\n * Resolve style inheritance chain\n */\nfunction resolveStyleInheritance(\n style: Style,\n styleMap: StyleMap,\n theme: Theme | null,\n visited: Set<string> = new Set()\n): Style {\n // Prevent circular inheritance\n if (visited.has(style.styleId)) {\n return style;\n }\n visited.add(style.styleId);\n\n // If no basedOn, return as-is\n if (!style.basedOn) {\n return style;\n }\n\n // Get parent style\n const parentStyle = styleMap.get(style.basedOn);\n if (!parentStyle) {\n return style;\n }\n\n // Recursively resolve parent\n const resolvedParent = resolveStyleInheritance(parentStyle, styleMap, theme, visited);\n\n // Merge parent into this style (this style overrides parent)\n const resolved: Style = {\n ...style,\n pPr: mergeParagraphFormatting(resolvedParent.pPr, style.pPr),\n rPr: mergeTextFormatting(resolvedParent.rPr, style.rPr),\n };\n\n // Merge table properties if this is a table style\n if (style.type === 'table') {\n if (resolvedParent.tblPr || style.tblPr) {\n resolved.tblPr = { ...(resolvedParent.tblPr || {}), ...(style.tblPr || {}) };\n }\n if (resolvedParent.trPr || style.trPr) {\n resolved.trPr = { ...(resolvedParent.trPr || {}), ...(style.trPr || {}) };\n }\n if (resolvedParent.tcPr || style.tcPr) {\n resolved.tcPr = { ...(resolvedParent.tcPr || {}), ...(style.tcPr || {}) };\n }\n }\n\n return resolved;\n}\n\n/**\n * Parse styles.xml content\n *\n * @param stylesXml - XML content of styles.xml\n * @param theme - Parsed theme for resolving theme references\n * @returns StyleMap with resolved inheritance\n */\nexport function parseStyles(stylesXml: string, theme: Theme | null): StyleMap {\n const styleMap: StyleMap = new Map();\n\n try {\n const doc = parseXmlDocument(stylesXml);\n if (!doc) {\n return styleMap;\n }\n\n // First pass: parse all styles without inheritance resolution\n const styleElements = findChildren(doc, 'w', 'style');\n for (const styleEl of styleElements) {\n const style = parseStyle(styleEl, theme);\n if (style.styleId) {\n styleMap.set(style.styleId, style);\n }\n }\n\n // Second pass: resolve inheritance\n for (const [styleId, style] of styleMap) {\n const resolved = resolveStyleInheritance(style, styleMap, theme);\n styleMap.set(styleId, resolved);\n }\n } catch (error) {\n console.warn('Failed to parse styles:', error);\n }\n\n return styleMap;\n}\n\n/**\n * Parse complete style definitions including docDefaults\n *\n * @param stylesXml - XML content of styles.xml\n * @param theme - Parsed theme for resolving theme references\n * @returns StyleDefinitions with docDefaults and resolved styles\n */\nexport function parseStyleDefinitions(stylesXml: string, theme: Theme | null): StyleDefinitions {\n const result: StyleDefinitions = {\n styles: [],\n };\n\n try {\n const doc = parseXmlDocument(stylesXml);\n if (!doc) {\n return result;\n }\n\n // Parse document defaults\n const docDefaultsEl = findChild(doc, 'w', 'docDefaults');\n result.docDefaults = parseDocDefaults(docDefaultsEl, theme);\n\n // Parse latent styles\n const latentStylesEl = findChild(doc, 'w', 'latentStyles');\n if (latentStylesEl) {\n result.latentStyles = {\n defLockedState: getAttribute(latentStylesEl, 'w', 'defLockedState') === '1',\n defUIPriority: parseNumericAttribute(latentStylesEl, 'w', 'defUIPriority'),\n defSemiHidden: getAttribute(latentStylesEl, 'w', 'defSemiHidden') === '1',\n defUnhideWhenUsed: getAttribute(latentStylesEl, 'w', 'defUnhideWhenUsed') === '1',\n defQFormat: getAttribute(latentStylesEl, 'w', 'defQFormat') === '1',\n count: parseNumericAttribute(latentStylesEl, 'w', 'count'),\n };\n }\n\n // Parse styles with full inheritance resolution\n const styleMap = parseStyles(stylesXml, theme);\n result.styles = Array.from(styleMap.values());\n } catch (error) {\n console.warn('Failed to parse style definitions:', error);\n }\n\n return result;\n}\n\n/**\n * Get the resolved properties for a style\n *\n * @param styleId - Style ID to look up\n * @param styleMap - Style map from parseStyles\n * @returns Resolved style or undefined\n */\nexport function getResolvedStyle(styleId: string, styleMap: StyleMap): Style | undefined {\n return styleMap.get(styleId);\n}\n\n/**\n * Get the default paragraph style\n */\nexport function getDefaultParagraphStyle(styleMap: StyleMap): Style | undefined {\n for (const style of styleMap.values()) {\n if (style.type === 'paragraph' && style.default) {\n return style;\n }\n }\n // Fallback to \"Normal\" style\n return styleMap.get('Normal');\n}\n\n/**\n * Get the default character style\n */\nexport function getDefaultCharacterStyle(styleMap: StyleMap): Style | undefined {\n for (const style of styleMap.values()) {\n if (style.type === 'character' && style.default) {\n return style;\n }\n }\n return undefined;\n}\n\n/**\n * Get all styles of a specific type\n */\nexport function getStylesByType(styleMap: StyleMap, type: StyleType): Style[] {\n const result: Style[] = [];\n for (const style of styleMap.values()) {\n if (style.type === type) {\n result.push(style);\n }\n }\n return result;\n}\n","/**\n * Numbering/List Parser for DOCX\n *\n * Parses numbering.xml to extract:\n * - Abstract numbering definitions (templates with levels)\n * - Numbering instances (concrete references with optional overrides)\n *\n * OOXML Structure:\n * - w:abstractNum - Template definitions with 9 levels (0-8)\n * - w:num - Instances that reference abstractNum and can override levels\n * - w:lvl - Level definition with start, format, text pattern, etc.\n */\n\nimport type {\n NumberingDefinitions,\n AbstractNumbering,\n NumberingInstance,\n ListLevel,\n NumberFormat,\n LevelSuffix,\n ParagraphFormatting,\n TextFormatting,\n} from '../types/document';\n\nimport {\n parseXmlDocument,\n findChild,\n findChildren,\n getAttribute,\n parseBooleanElement,\n parseNumericAttribute,\n type XmlElement,\n} from './xmlParser';\n\n/**\n * Map of rId to numbering definitions\n */\nexport type NumberingMap = {\n definitions: NumberingDefinitions;\n /** Get level info for a numId and ilvl */\n getLevel: (numId: number, ilvl: number) => ListLevel | null;\n /** Get abstract numbering by ID */\n getAbstract: (abstractNumId: number) => AbstractNumbering | null;\n /** Check if numId exists */\n hasNumbering: (numId: number) => boolean;\n};\n\n/**\n * Parse numbering.xml into NumberingDefinitions\n *\n * @param numberingXml - Raw XML string from word/numbering.xml (or null if not present)\n * @returns NumberingMap with definitions and helper functions\n */\nexport function parseNumbering(numberingXml: string | null): NumberingMap {\n const definitions: NumberingDefinitions = {\n abstractNums: [],\n nums: [],\n };\n\n if (!numberingXml) {\n return createNumberingMap(definitions);\n }\n\n const root = parseXmlDocument(numberingXml);\n if (!root) {\n return createNumberingMap(definitions);\n }\n\n // Parse abstract numbering definitions\n const abstractNumElements = findChildren(root, 'w', 'abstractNum');\n for (const abstractNum of abstractNumElements) {\n const parsed = parseAbstractNumbering(abstractNum);\n if (parsed) {\n definitions.abstractNums.push(parsed);\n }\n }\n\n // Parse numbering instances\n const numElements = findChildren(root, 'w', 'num');\n for (const num of numElements) {\n const parsed = parseNumberingInstance(num);\n if (parsed) {\n definitions.nums.push(parsed);\n }\n }\n\n return createNumberingMap(definitions);\n}\n\n/**\n * Parse a single w:abstractNum element\n */\nfunction parseAbstractNumbering(element: XmlElement): AbstractNumbering | null {\n const abstractNumIdStr = getAttribute(element, 'w', 'abstractNumId');\n if (abstractNumIdStr === null) return null;\n\n const abstractNumId = parseInt(abstractNumIdStr, 10);\n if (isNaN(abstractNumId)) return null;\n\n const abstractNum: AbstractNumbering = {\n abstractNumId,\n levels: [],\n };\n\n // Parse optional attributes/children\n const multiLevelTypeEl = findChild(element, 'w', 'multiLevelType');\n if (multiLevelTypeEl) {\n const mlType = getAttribute(multiLevelTypeEl, 'w', 'val');\n if (mlType === 'hybridMultilevel' || mlType === 'multilevel' || mlType === 'singleLevel') {\n abstractNum.multiLevelType = mlType;\n }\n }\n\n // Parse name\n const nameEl = findChild(element, 'w', 'name');\n if (nameEl) {\n abstractNum.name = getAttribute(nameEl, 'w', 'val') ?? undefined;\n }\n\n // Parse style links\n const numStyleLinkEl = findChild(element, 'w', 'numStyleLink');\n if (numStyleLinkEl) {\n abstractNum.numStyleLink = getAttribute(numStyleLinkEl, 'w', 'val') ?? undefined;\n }\n\n const styleLinkEl = findChild(element, 'w', 'styleLink');\n if (styleLinkEl) {\n abstractNum.styleLink = getAttribute(styleLinkEl, 'w', 'val') ?? undefined;\n }\n\n // Parse levels (w:lvl)\n const levelElements = findChildren(element, 'w', 'lvl');\n for (const lvlEl of levelElements) {\n const level = parseListLevel(lvlEl);\n if (level) {\n abstractNum.levels.push(level);\n }\n }\n\n // Sort levels by ilvl\n abstractNum.levels.sort((a, b) => a.ilvl - b.ilvl);\n\n return abstractNum;\n}\n\n/**\n * Parse a single w:num element (numbering instance)\n */\nfunction parseNumberingInstance(element: XmlElement): NumberingInstance | null {\n const numIdStr = getAttribute(element, 'w', 'numId');\n if (numIdStr === null) return null;\n\n const numId = parseInt(numIdStr, 10);\n if (isNaN(numId)) return null;\n\n // Get abstract numbering reference\n const abstractNumIdEl = findChild(element, 'w', 'abstractNumId');\n if (!abstractNumIdEl) return null;\n\n const abstractNumIdStr = getAttribute(abstractNumIdEl, 'w', 'val');\n if (abstractNumIdStr === null) return null;\n\n const abstractNumId = parseInt(abstractNumIdStr, 10);\n if (isNaN(abstractNumId)) return null;\n\n const instance: NumberingInstance = {\n numId,\n abstractNumId,\n };\n\n // Parse level overrides (w:lvlOverride)\n const overrideElements = findChildren(element, 'w', 'lvlOverride');\n if (overrideElements.length > 0) {\n instance.levelOverrides = [];\n\n for (const overrideEl of overrideElements) {\n const ilvlStr = getAttribute(overrideEl, 'w', 'ilvl');\n if (ilvlStr === null) continue;\n\n const ilvl = parseInt(ilvlStr, 10);\n if (isNaN(ilvl)) continue;\n\n const override: {\n ilvl: number;\n startOverride?: number;\n lvl?: ListLevel;\n } = { ilvl };\n\n // Check for start override\n const startOverrideEl = findChild(overrideEl, 'w', 'startOverride');\n if (startOverrideEl) {\n const startVal = getAttribute(startOverrideEl, 'w', 'val');\n if (startVal !== null) {\n const startNum = parseInt(startVal, 10);\n if (!isNaN(startNum)) {\n override.startOverride = startNum;\n }\n }\n }\n\n // Check for full level redefinition\n const lvlEl = findChild(overrideEl, 'w', 'lvl');\n if (lvlEl) {\n override.lvl = parseListLevel(lvlEl) ?? undefined;\n }\n\n instance.levelOverrides.push(override);\n }\n }\n\n return instance;\n}\n\n/**\n * Parse a single w:lvl element (list level definition)\n */\nfunction parseListLevel(element: XmlElement): ListLevel | null {\n const ilvlStr = getAttribute(element, 'w', 'ilvl');\n if (ilvlStr === null) return null;\n\n const ilvl = parseInt(ilvlStr, 10);\n if (isNaN(ilvl) || ilvl < 0 || ilvl > 8) return null;\n\n const level: ListLevel = {\n ilvl,\n numFmt: 'decimal', // Default\n lvlText: '',\n };\n\n // Parse start value\n const startEl = findChild(element, 'w', 'start');\n if (startEl) {\n const startVal = getAttribute(startEl, 'w', 'val');\n if (startVal !== null) {\n const startNum = parseInt(startVal, 10);\n if (!isNaN(startNum)) {\n level.start = startNum;\n }\n }\n }\n\n // Parse number format\n const numFmtEl = findChild(element, 'w', 'numFmt');\n if (numFmtEl) {\n const fmtVal = getAttribute(numFmtEl, 'w', 'val');\n if (fmtVal) {\n level.numFmt = parseNumberFormat(fmtVal);\n }\n }\n\n // Parse level text (the pattern like \"%1.\" or \"•\")\n const lvlTextEl = findChild(element, 'w', 'lvlText');\n if (lvlTextEl) {\n level.lvlText = getAttribute(lvlTextEl, 'w', 'val') ?? '';\n }\n\n // Parse justification\n const lvlJcEl = findChild(element, 'w', 'lvlJc');\n if (lvlJcEl) {\n const jcVal = getAttribute(lvlJcEl, 'w', 'val');\n if (jcVal === 'left' || jcVal === 'center' || jcVal === 'right') {\n level.lvlJc = jcVal;\n }\n }\n\n // Parse suffix\n const suffEl = findChild(element, 'w', 'suff');\n if (suffEl) {\n const suffVal = getAttribute(suffEl, 'w', 'val');\n if (suffVal === 'tab' || suffVal === 'space' || suffVal === 'nothing') {\n level.suffix = suffVal as LevelSuffix;\n }\n }\n\n // Parse isLgl (legal numbering)\n const isLglEl = findChild(element, 'w', 'isLgl');\n if (isLglEl) {\n level.isLgl = parseBooleanElement(isLglEl);\n }\n\n // Parse lvlRestart (restart numbering from a higher level)\n const lvlRestartEl = findChild(element, 'w', 'lvlRestart');\n if (lvlRestartEl) {\n const restartVal = getAttribute(lvlRestartEl, 'w', 'val');\n if (restartVal !== null) {\n const restartNum = parseInt(restartVal, 10);\n if (!isNaN(restartNum)) {\n level.lvlRestart = restartNum;\n }\n }\n }\n\n // Parse legacy settings\n const legacyEl = findChild(element, 'w', 'legacy');\n if (legacyEl) {\n level.legacy = {\n legacy: parseBooleanElement(legacyEl),\n legacySpace: parseNumericAttribute(legacyEl, 'w', 'legacySpace'),\n legacyIndent: parseNumericAttribute(legacyEl, 'w', 'legacyIndent'),\n };\n }\n\n // Parse paragraph properties (w:pPr)\n const pPrEl = findChild(element, 'w', 'pPr');\n if (pPrEl) {\n level.pPr = parseLevelParagraphProps(pPrEl);\n }\n\n // Parse run properties (w:rPr)\n const rPrEl = findChild(element, 'w', 'rPr');\n if (rPrEl) {\n level.rPr = parseLevelRunProps(rPrEl);\n }\n\n return level;\n}\n\n/**\n * Parse number format string to NumberFormat type\n */\nfunction parseNumberFormat(format: string): NumberFormat {\n // Map of known formats\n const formatMap: Record<string, NumberFormat> = {\n decimal: 'decimal',\n upperRoman: 'upperRoman',\n lowerRoman: 'lowerRoman',\n upperLetter: 'upperLetter',\n lowerLetter: 'lowerLetter',\n ordinal: 'ordinal',\n cardinalText: 'cardinalText',\n ordinalText: 'ordinalText',\n hex: 'hex',\n chicago: 'chicago',\n bullet: 'bullet',\n none: 'none',\n decimalZero: 'decimalZero',\n ganada: 'ganada',\n chosung: 'chosung',\n // CJK formats\n ideographDigital: 'ideographDigital',\n japaneseCounting: 'japaneseCounting',\n aiueo: 'aiueo',\n iroha: 'iroha',\n decimalFullWidth: 'decimalFullWidth',\n decimalHalfWidth: 'decimalHalfWidth',\n japaneseLegal: 'japaneseLegal',\n japaneseDigitalTenThousand: 'japaneseDigitalTenThousand',\n decimalEnclosedCircle: 'decimalEnclosedCircle',\n decimalFullWidth2: 'decimalFullWidth2',\n aiueoFullWidth: 'aiueoFullWidth',\n irohaFullWidth: 'irohaFullWidth',\n decimalEnclosedFullstop: 'decimalEnclosedFullstop',\n decimalEnclosedParen: 'decimalEnclosedParen',\n decimalEnclosedCircleChinese: 'decimalEnclosedCircleChinese',\n ideographEnclosedCircle: 'ideographEnclosedCircle',\n ideographTraditional: 'ideographTraditional',\n ideographZodiac: 'ideographZodiac',\n ideographZodiacTraditional: 'ideographZodiacTraditional',\n taiwaneseCounting: 'taiwaneseCounting',\n ideographLegalTraditional: 'ideographLegalTraditional',\n taiwaneseCountingThousand: 'taiwaneseCountingThousand',\n taiwaneseDigital: 'taiwaneseDigital',\n chineseCounting: 'chineseCounting',\n chineseLegalSimplified: 'chineseLegalSimplified',\n chineseCountingThousand: 'chineseCountingThousand',\n koreanDigital: 'koreanDigital',\n koreanCounting: 'koreanCounting',\n koreanLegal: 'koreanLegal',\n koreanDigital2: 'koreanDigital2',\n vietnameseCounting: 'vietnameseCounting',\n russianLower: 'russianLower',\n russianUpper: 'russianUpper',\n numberInDash: 'numberInDash',\n hebrew1: 'hebrew1',\n hebrew2: 'hebrew2',\n arabicAlpha: 'arabicAlpha',\n arabicAbjad: 'arabicAbjad',\n hindiVowels: 'hindiVowels',\n hindiConsonants: 'hindiConsonants',\n hindiNumbers: 'hindiNumbers',\n hindiCounting: 'hindiCounting',\n thaiLetters: 'thaiLetters',\n thaiNumbers: 'thaiNumbers',\n thaiCounting: 'thaiCounting',\n };\n\n return formatMap[format] ?? 'decimal';\n}\n\n/**\n * Parse paragraph properties for a list level (subset of full pPr)\n * Main concern: indentation and tabs\n */\nfunction parseLevelParagraphProps(pPr: XmlElement): ParagraphFormatting {\n const formatting: ParagraphFormatting = {};\n\n // Parse indentation (w:ind)\n const indEl = findChild(pPr, 'w', 'ind');\n if (indEl) {\n const left = parseNumericAttribute(indEl, 'w', 'left');\n const right = parseNumericAttribute(indEl, 'w', 'right');\n const firstLine = parseNumericAttribute(indEl, 'w', 'firstLine');\n const hanging = parseNumericAttribute(indEl, 'w', 'hanging');\n\n if (left !== undefined) formatting.indentLeft = left;\n if (right !== undefined) formatting.indentRight = right;\n\n if (hanging !== undefined) {\n formatting.indentFirstLine = -hanging;\n formatting.hangingIndent = true;\n } else if (firstLine !== undefined) {\n formatting.indentFirstLine = firstLine;\n }\n }\n\n // Parse tabs (w:tabs)\n const tabsEl = findChild(pPr, 'w', 'tabs');\n if (tabsEl) {\n formatting.tabs = [];\n const tabElements = findChildren(tabsEl, 'w', 'tab');\n for (const tabEl of tabElements) {\n const pos = parseNumericAttribute(tabEl, 'w', 'pos');\n const val = getAttribute(tabEl, 'w', 'val');\n const leader = getAttribute(tabEl, 'w', 'leader');\n\n if (pos !== undefined && val) {\n formatting.tabs.push({\n position: pos,\n alignment: parseTabAlignment(val),\n leader: parseTabLeader(leader),\n });\n }\n }\n }\n\n return formatting;\n}\n\n/**\n * Parse tab alignment value\n */\nfunction parseTabAlignment(\n val: string\n): 'left' | 'center' | 'right' | 'decimal' | 'bar' | 'clear' | 'num' {\n switch (val) {\n case 'left':\n return 'left';\n case 'center':\n return 'center';\n case 'right':\n return 'right';\n case 'decimal':\n return 'decimal';\n case 'bar':\n return 'bar';\n case 'clear':\n return 'clear';\n case 'num':\n return 'num';\n default:\n return 'left';\n }\n}\n\n/**\n * Parse tab leader value\n */\nfunction parseTabLeader(\n val: string | null\n): 'none' | 'dot' | 'hyphen' | 'underscore' | 'heavy' | 'middleDot' | undefined {\n if (!val) return undefined;\n switch (val) {\n case 'none':\n return 'none';\n case 'dot':\n return 'dot';\n case 'hyphen':\n return 'hyphen';\n case 'underscore':\n return 'underscore';\n case 'heavy':\n return 'heavy';\n case 'middleDot':\n return 'middleDot';\n default:\n return undefined;\n }\n}\n\n/**\n * Parse run properties for a list level (subset of full rPr)\n * Main concern: fonts for bullet characters\n */\nfunction parseLevelRunProps(rPr: XmlElement): TextFormatting {\n const formatting: TextFormatting = {};\n\n // Parse fonts (w:rFonts) - important for bullet characters\n const rFontsEl = findChild(rPr, 'w', 'rFonts');\n if (rFontsEl) {\n formatting.fontFamily = {\n ascii: getAttribute(rFontsEl, 'w', 'ascii') ?? undefined,\n hAnsi: getAttribute(rFontsEl, 'w', 'hAnsi') ?? undefined,\n eastAsia: getAttribute(rFontsEl, 'w', 'eastAsia') ?? undefined,\n cs: getAttribute(rFontsEl, 'w', 'cs') ?? undefined,\n };\n }\n\n // Parse font size (w:sz)\n const szEl = findChild(rPr, 'w', 'sz');\n if (szEl) {\n const size = parseNumericAttribute(szEl, 'w', 'val');\n if (size !== undefined) {\n formatting.fontSize = size; // In half-points\n }\n }\n\n // Parse color (w:color)\n const colorEl = findChild(rPr, 'w', 'color');\n if (colorEl) {\n const val = getAttribute(colorEl, 'w', 'val');\n const themeColor = getAttribute(colorEl, 'w', 'themeColor');\n\n if (val === 'auto') {\n formatting.color = { auto: true };\n } else if (themeColor) {\n formatting.color = {\n themeColor: themeColor as any,\n themeTint: getAttribute(colorEl, 'w', 'themeTint') ?? undefined,\n themeShade: getAttribute(colorEl, 'w', 'themeShade') ?? undefined,\n };\n } else if (val) {\n formatting.color = { rgb: val };\n }\n }\n\n // Parse bold (w:b)\n const bEl = findChild(rPr, 'w', 'b');\n if (bEl) {\n formatting.bold = parseBooleanElement(bEl);\n }\n\n // Parse italic (w:i)\n const iEl = findChild(rPr, 'w', 'i');\n if (iEl) {\n formatting.italic = parseBooleanElement(iEl);\n }\n\n // Parse vanish / hidden (w:vanish) — hides the list indicator\n const vanishEl = findChild(rPr, 'w', 'vanish');\n if (vanishEl) {\n formatting.hidden = parseBooleanElement(vanishEl);\n }\n\n return formatting;\n}\n\n/**\n * Create a NumberingMap with helper functions\n */\nfunction createNumberingMap(definitions: NumberingDefinitions): NumberingMap {\n // Build lookup maps for efficient access\n const abstractMap = new Map<number, AbstractNumbering>();\n for (const abs of definitions.abstractNums) {\n abstractMap.set(abs.abstractNumId, abs);\n }\n\n const numMap = new Map<number, NumberingInstance>();\n for (const num of definitions.nums) {\n numMap.set(num.numId, num);\n }\n\n return {\n definitions,\n\n getLevel(numId: number, ilvl: number): ListLevel | null {\n const num = numMap.get(numId);\n if (!num) return null;\n\n // Check for level override first\n if (num.levelOverrides) {\n const override = num.levelOverrides.find((o) => o.ilvl === ilvl);\n if (override) {\n if (override.lvl) {\n // Full level redefinition\n return override.lvl;\n }\n // Start override - need to get base level and modify\n const abstractNum = abstractMap.get(num.abstractNumId);\n if (abstractNum) {\n const baseLevel = abstractNum.levels.find((l) => l.ilvl === ilvl);\n if (baseLevel && override.startOverride !== undefined) {\n return {\n ...baseLevel,\n start: override.startOverride,\n };\n }\n }\n }\n }\n\n // Get from abstract numbering\n let abstractNum = abstractMap.get(num.abstractNumId);\n if (!abstractNum) return null;\n\n // Follow numStyleLink: when an abstractNum has numStyleLink instead of\n // defining levels directly, find the abstractNum that owns that style\n // (has matching styleLink) and use its levels. Per ECMA-376 §17.9.21/22.\n if (abstractNum.numStyleLink && abstractNum.levels.length === 0) {\n for (const candidate of abstractMap.values()) {\n if (candidate.styleLink === abstractNum.numStyleLink && candidate.levels.length > 0) {\n abstractNum = candidate;\n break;\n }\n }\n }\n\n return abstractNum.levels.find((l) => l.ilvl === ilvl) ?? null;\n },\n\n getAbstract(abstractNumId: number): AbstractNumbering | null {\n return abstractMap.get(abstractNumId) ?? null;\n },\n\n hasNumbering(numId: number): boolean {\n return numMap.has(numId);\n },\n };\n}\n\n/**\n * Format a number according to the specified format\n *\n * @param num - The number to format\n * @param format - The number format\n * @returns Formatted string\n */\nexport function formatNumber(num: number, format: NumberFormat): string {\n switch (format) {\n case 'decimal':\n case 'decimalZero':\n return num.toString();\n\n case 'upperRoman':\n return toRoman(num).toUpperCase();\n\n case 'lowerRoman':\n return toRoman(num).toLowerCase();\n\n case 'upperLetter':\n return toLetter(num).toUpperCase();\n\n case 'lowerLetter':\n return toLetter(num).toLowerCase();\n\n case 'ordinal':\n return toOrdinal(num);\n\n case 'bullet':\n return '•'; // Default bullet\n\n case 'none':\n return '';\n\n case 'decimalEnclosedParen':\n return `(${num})`;\n\n case 'numberInDash':\n return `-${num}-`;\n\n default:\n // For CJK and other special formats, fall back to decimal\n return num.toString();\n }\n}\n\n/**\n * Convert number to Roman numerals\n */\nfunction toRoman(num: number): string {\n if (num <= 0 || num > 3999) return num.toString();\n\n const romanNumerals: [number, string][] = [\n [1000, 'm'],\n [900, 'cm'],\n [500, 'd'],\n [400, 'cd'],\n [100, 'c'],\n [90, 'xc'],\n [50, 'l'],\n [40, 'xl'],\n [10, 'x'],\n [9, 'ix'],\n [5, 'v'],\n [4, 'iv'],\n [1, 'i'],\n ];\n\n let result = '';\n let remaining = num;\n\n for (const [value, numeral] of romanNumerals) {\n while (remaining >= value) {\n result += numeral;\n remaining -= value;\n }\n }\n\n return result;\n}\n\n/**\n * Convert number to letter (a, b, c, ... z, aa, ab, ...)\n */\nfunction toLetter(num: number): string {\n if (num <= 0) return '';\n\n let result = '';\n let remaining = num;\n\n while (remaining > 0) {\n remaining--;\n result = String.fromCharCode(97 + (remaining % 26)) + result;\n remaining = Math.floor(remaining / 26);\n }\n\n return result;\n}\n\n/**\n * Convert number to ordinal (1st, 2nd, 3rd, ...)\n */\nfunction toOrdinal(num: number): string {\n const suffix = ['th', 'st', 'nd', 'rd'];\n const v = num % 100;\n return num + (suffix[(v - 20) % 10] || suffix[v] || suffix[0]);\n}\n\n/**\n * Render list marker text by replacing placeholders with formatted numbers\n *\n * @param lvlText - The level text pattern (e.g., \"%1.\", \"%1.%2\")\n * @param counters - Array of counter values for each level (index 0 = level 0, etc.)\n * @param formats - Array of number formats for each level\n * @returns Rendered marker text\n */\nexport function renderListMarker(\n lvlText: string,\n counters: number[],\n formats: NumberFormat[]\n): string {\n let result = lvlText;\n\n // Replace %1 through %9 with formatted counter values\n for (let i = 1; i <= 9; i++) {\n const placeholder = `%${i}`;\n if (result.includes(placeholder)) {\n const counterIndex = i - 1;\n const counter = counters[counterIndex] ?? 1;\n const format = formats[counterIndex] ?? 'decimal';\n const formatted = formatNumber(counter, format);\n result = result.replace(placeholder, formatted);\n }\n }\n\n return result;\n}\n\n/**\n * Get the bullet character for a bullet list level\n *\n * @param level - The list level definition\n * @returns The bullet character to display\n */\nexport function getBulletCharacter(level: ListLevel): string {\n // If lvlText is set and not empty, use it\n if (level.lvlText) {\n return level.lvlText;\n }\n\n // Check font for common bullet font mappings\n const fontFamily = level.rPr?.fontFamily?.ascii || level.rPr?.fontFamily?.hAnsi;\n\n if (fontFamily) {\n const fontLower = fontFamily.toLowerCase();\n\n // Symbol font common bullets\n if (fontLower === 'symbol') {\n return '•'; // Standard bullet\n }\n\n // Wingdings common bullets\n if (fontLower.includes('wingding')) {\n return '❑'; // Square bullet\n }\n }\n\n // Default bullet\n return '•';\n}\n\n/**\n * Check if a list level is a bullet (not numbered)\n */\nexport function isBulletLevel(level: ListLevel): boolean {\n return level.numFmt === 'bullet' || level.numFmt === 'none';\n}\n","/**\n * Shared DrawingML Parsing Utilities\n *\n * Common functions used by imageParser, textBoxParser, and shapeParser\n * for parsing DrawingML elements (positions, wrapping, colors, fills, outlines).\n */\n\nimport type {\n ImagePosition,\n ImageWrap,\n ShapeFill,\n ShapeOutline,\n ColorValue,\n} from '../types/document';\nimport {\n getChildElements,\n getAttribute,\n getTextContent,\n parseNumericAttribute,\n findByFullName,\n type XmlElement,\n} from './xmlParser';\n\n// ============================================================================\n// COLOR PARSING\n// ============================================================================\n\n/**\n * Map OOXML scheme names to standard theme color slots.\n * Used when parsing a:schemeClr elements in DrawingML.\n */\nconst SCHEME_TO_THEME_COLOR: Record<string, ColorValue['themeColor']> = {\n accent1: 'accent1',\n accent2: 'accent2',\n accent3: 'accent3',\n accent4: 'accent4',\n accent5: 'accent5',\n accent6: 'accent6',\n dk1: 'dk1',\n lt1: 'lt1',\n dk2: 'dk2',\n lt2: 'lt2',\n tx1: 'text1',\n tx2: 'text2',\n bg1: 'background1',\n bg2: 'background2',\n hlink: 'hlink',\n folHlink: 'folHlink',\n};\n\n/**\n * Common preset color names to RGB hex values.\n */\nconst PRESET_COLORS: Record<string, string> = {\n black: '000000',\n white: 'FFFFFF',\n red: 'FF0000',\n green: '00FF00',\n blue: '0000FF',\n yellow: 'FFFF00',\n cyan: '00FFFF',\n magenta: 'FF00FF',\n};\n\n/**\n * Apply color modifiers (shade, tint) from child elements of a color element.\n * Converts DrawingML 100000ths-scale values to hex (0-FF) for OOXML compatibility.\n */\nfunction applyColorModifiers(color: ColorValue, element: XmlElement): ColorValue {\n const children = getChildElements(element);\n\n const shade = children.find((el) => el.name === 'a:shade');\n if (shade) {\n const val = getAttribute(shade, null, 'val');\n if (val) {\n color.themeShade = Math.round((parseInt(val, 10) / 100000) * 255)\n .toString(16)\n .padStart(2, '0')\n .toUpperCase();\n }\n }\n\n const tint = children.find((el) => el.name === 'a:tint');\n if (tint) {\n const val = getAttribute(tint, null, 'val');\n if (val) {\n color.themeTint = Math.round((parseInt(val, 10) / 100000) * 255)\n .toString(16)\n .padStart(2, '0')\n .toUpperCase();\n }\n }\n\n return color;\n}\n\n/**\n * Parse a color value from a DrawingML element.\n * Handles: a:srgbClr, a:schemeClr, a:sysClr, a:prstClr\n * Applies shade/tint modifiers when present.\n */\nexport function parseColorElement(element: XmlElement | null): ColorValue | undefined {\n if (!element) return undefined;\n\n const children = getChildElements(element);\n\n // sRGB color: a:srgbClr[@val]\n const srgbClr = children.find((el) => el.name === 'a:srgbClr');\n if (srgbClr) {\n const val = getAttribute(srgbClr, null, 'val');\n if (val) {\n return applyColorModifiers({ rgb: val }, srgbClr);\n }\n }\n\n // Scheme color (theme): a:schemeClr[@val]\n const schemeClr = children.find((el) => el.name === 'a:schemeClr');\n if (schemeClr) {\n const val = getAttribute(schemeClr, null, 'val');\n if (val) {\n const color: ColorValue = {\n themeColor: SCHEME_TO_THEME_COLOR[val] ?? 'dk1',\n };\n return applyColorModifiers(color, schemeClr);\n }\n }\n\n // System color: a:sysClr[@lastClr]\n const sysClr = children.find((el) => el.name === 'a:sysClr');\n if (sysClr) {\n const lastClr = getAttribute(sysClr, null, 'lastClr');\n return { rgb: lastClr ?? '000000' };\n }\n\n // Preset color: a:prstClr[@val]\n const prstClr = children.find((el) => el.name === 'a:prstClr');\n if (prstClr) {\n const val = getAttribute(prstClr, null, 'val');\n if (val && PRESET_COLORS[val]) {\n return { rgb: PRESET_COLORS[val] };\n }\n }\n\n return undefined;\n}\n\n// ============================================================================\n// FILL & OUTLINE PARSING\n// ============================================================================\n\n/**\n * Parse fill from shape properties (a:solidFill, a:noFill, a:gradFill).\n */\nexport function parseFill(spPr: XmlElement | null): ShapeFill | undefined {\n if (!spPr) return undefined;\n\n const children = getChildElements(spPr);\n\n if (children.find((el) => el.name === 'a:noFill')) {\n return { type: 'none' };\n }\n\n const solidFill = children.find((el) => el.name === 'a:solidFill');\n if (solidFill) {\n return { type: 'solid', color: parseColorElement(solidFill) };\n }\n\n if (children.find((el) => el.name === 'a:gradFill')) {\n return { type: 'gradient' };\n }\n\n return undefined;\n}\n\n/**\n * Parse outline from shape properties (a:ln).\n */\nexport function parseOutline(spPr: XmlElement | null): ShapeOutline | undefined {\n const ln = spPr ? findByFullName(spPr, 'a:ln') : null;\n if (!ln) return undefined;\n\n const children = getChildElements(ln);\n\n if (children.find((el) => el.name === 'a:noFill')) {\n return undefined;\n }\n\n const outline: ShapeOutline = {};\n\n const w = getAttribute(ln, null, 'w');\n if (w) outline.width = parseInt(w, 10);\n\n const solidFill = children.find((el) => el.name === 'a:solidFill');\n if (solidFill) outline.color = parseColorElement(solidFill);\n\n const prstDash = children.find((el) => el.name === 'a:prstDash');\n if (prstDash) {\n const val = getAttribute(prstDash, null, 'val');\n if (val) outline.style = val as ShapeOutline['style'];\n }\n\n return outline;\n}\n\n// ============================================================================\n// POSITION PARSING\n// ============================================================================\n\n/**\n * Parse horizontal position from wp:positionH element.\n */\nexport function parsePositionH(posH: XmlElement | null): ImagePosition['horizontal'] | undefined {\n if (!posH) return undefined;\n\n const relativeTo = getAttribute(posH, null, 'relativeFrom') ?? 'column';\n\n const alignEl = findByFullName(posH, 'wp:align');\n if (alignEl) {\n const text = getTextContent(alignEl);\n return {\n relativeTo: relativeTo as ImagePosition['horizontal']['relativeTo'],\n alignment: text as ImagePosition['horizontal']['alignment'],\n };\n }\n\n const posOffsetEl = findByFullName(posH, 'wp:posOffset');\n if (posOffsetEl) {\n const text = getTextContent(posOffsetEl);\n const posOffset = parseInt(text, 10);\n return {\n relativeTo: relativeTo as ImagePosition['horizontal']['relativeTo'],\n posOffset: isNaN(posOffset) ? 0 : posOffset,\n };\n }\n\n return {\n relativeTo: relativeTo as ImagePosition['horizontal']['relativeTo'],\n };\n}\n\n/**\n * Parse vertical position from wp:positionV element.\n */\nexport function parsePositionV(posV: XmlElement | null): ImagePosition['vertical'] | undefined {\n if (!posV) return undefined;\n\n const relativeTo = getAttribute(posV, null, 'relativeFrom') ?? 'paragraph';\n\n const alignEl = findByFullName(posV, 'wp:align');\n if (alignEl) {\n const text = getTextContent(alignEl);\n return {\n relativeTo: relativeTo as ImagePosition['vertical']['relativeTo'],\n alignment: text as ImagePosition['vertical']['alignment'],\n };\n }\n\n const posOffsetEl = findByFullName(posV, 'wp:posOffset');\n if (posOffsetEl) {\n const text = getTextContent(posOffsetEl);\n const posOffset = parseInt(text, 10);\n return {\n relativeTo: relativeTo as ImagePosition['vertical']['relativeTo'],\n posOffset: isNaN(posOffset) ? 0 : posOffset,\n };\n }\n\n return {\n relativeTo: relativeTo as ImagePosition['vertical']['relativeTo'],\n };\n}\n\n/**\n * Parse position for anchored drawings (combines positionH + positionV).\n */\nexport function parseAnchorPosition(anchor: XmlElement): ImagePosition | undefined {\n const positionH = findByFullName(anchor, 'wp:positionH');\n const positionV = findByFullName(anchor, 'wp:positionV');\n\n if (!positionH && !positionV) return undefined;\n\n return {\n horizontal: parsePositionH(positionH) ?? { relativeTo: 'column' },\n vertical: parsePositionV(positionV) ?? { relativeTo: 'paragraph' },\n };\n}\n\n// ============================================================================\n// WRAP PARSING\n// ============================================================================\n\n/** Known wrap element names */\nexport const WRAP_ELEMENT_NAMES = [\n 'wp:wrapNone',\n 'wp:wrapSquare',\n 'wp:wrapTight',\n 'wp:wrapThrough',\n 'wp:wrapTopAndBottom',\n];\n\n/**\n * Parse wrap settings from a wrap element.\n *\n * Distance attributes (distT/distB/distL/distR) can appear on both\n * the anchor element and the wrap child. Wrap child values take priority;\n * anchor-level values are used as fallbacks.\n */\nexport function parseWrapElement(\n wrapEl: XmlElement | null,\n behindDoc: boolean,\n anchorDistances?: { distT?: number; distB?: number; distL?: number; distR?: number }\n): ImageWrap {\n if (!wrapEl) {\n const wrap: ImageWrap = { type: behindDoc ? 'behind' : 'inFront' };\n if (anchorDistances?.distT !== undefined) wrap.distT = anchorDistances.distT;\n if (anchorDistances?.distB !== undefined) wrap.distB = anchorDistances.distB;\n if (anchorDistances?.distL !== undefined) wrap.distL = anchorDistances.distL;\n if (anchorDistances?.distR !== undefined) wrap.distR = anchorDistances.distR;\n return wrap;\n }\n\n const wrapName = wrapEl.name || '';\n const wrapType = wrapName.replace('wp:', '');\n\n let type: ImageWrap['type'];\n switch (wrapType) {\n case 'wrapNone':\n type = behindDoc ? 'behind' : 'inFront';\n break;\n case 'wrapSquare':\n type = 'square';\n break;\n case 'wrapTight':\n type = 'tight';\n break;\n case 'wrapThrough':\n type = 'through';\n break;\n case 'wrapTopAndBottom':\n type = 'topAndBottom';\n break;\n default:\n type = 'square';\n }\n\n const wrap: ImageWrap = { type };\n\n const wrapText = getAttribute(wrapEl, null, 'wrapText');\n if (wrapText) wrap.wrapText = wrapText as ImageWrap['wrapText'];\n\n // Wrap child distances take priority, then anchor-level\n const distT = parseNumericAttribute(wrapEl, null, 'distT') ?? anchorDistances?.distT;\n const distB = parseNumericAttribute(wrapEl, null, 'distB') ?? anchorDistances?.distB;\n const distL = parseNumericAttribute(wrapEl, null, 'distL') ?? anchorDistances?.distL;\n const distR = parseNumericAttribute(wrapEl, null, 'distR') ?? anchorDistances?.distR;\n\n if (distT !== undefined) wrap.distT = distT;\n if (distB !== undefined) wrap.distB = distB;\n if (distL !== undefined) wrap.distL = distL;\n if (distR !== undefined) wrap.distR = distR;\n\n return wrap;\n}\n\n/**\n * Parse wrap from an anchor element (finds wrap child internally).\n */\nexport function parseAnchorWrap(anchor: XmlElement): ImageWrap | undefined {\n const children = getChildElements(anchor);\n const behindDoc = getAttribute(anchor, null, 'behindDoc') === '1';\n\n const wrapEl = children.find((el) => WRAP_ELEMENT_NAMES.includes(el.name ?? ''));\n\n // Read anchor-level distance fallbacks\n const anchorDistances = {\n distT: parseNumericAttribute(anchor, null, 'distT') ?? undefined,\n distB: parseNumericAttribute(anchor, null, 'distB') ?? undefined,\n distL: parseNumericAttribute(anchor, null, 'distL') ?? undefined,\n distR: parseNumericAttribute(anchor, null, 'distR') ?? undefined,\n };\n\n return parseWrapElement(wrapEl ?? null, behindDoc, anchorDistances);\n}\n\n// ============================================================================\n// COLOR RESOLUTION (for shapes/text boxes without theme context)\n// ============================================================================\n\n/**\n * Default theme color fallbacks (Office 2016 defaults).\n * Used when resolving theme colors without a Theme object.\n */\nconst DEFAULT_THEME_COLOR_HEX: Record<string, string> = {\n accent1: '5B9BD5',\n accent2: 'ED7D31',\n accent3: 'A5A5A5',\n accent4: 'FFC000',\n accent5: '4472C4',\n accent6: '70AD47',\n dk1: '000000',\n lt1: 'FFFFFF',\n dk2: '1F497D',\n lt2: 'EEECE1',\n text1: '000000',\n text2: '1F497D',\n background1: 'FFFFFF',\n background2: 'EEECE1',\n hlink: '0563C1',\n folHlink: '954F72',\n};\n\n/**\n * Resolve a ColorValue to a CSS hex string using default theme colors.\n * For use when no Theme object is available (e.g., shape/text box parsing).\n */\nexport function resolveColorValueToHex(color: ColorValue | undefined): string | undefined {\n if (!color) return undefined;\n\n if (color.rgb) return `#${color.rgb}`;\n\n if (color.themeColor) {\n return `#${DEFAULT_THEME_COLOR_HEX[color.themeColor] ?? '000000'}`;\n }\n\n return undefined;\n}\n","/**\n * Unit Conversion Utilities - Convert OOXML units to CSS/pixels\n *\n * OOXML uses various unit systems that need conversion for rendering:\n * - Twips: 1/20 of a point (1440 twips = 1 inch)\n * - EMUs (English Metric Units): 914400 EMUs = 1 inch\n * - Half-points: 1/2 of a point (144 half-points = 1 inch)\n * - Points: 72 points = 1 inch\n * - Eighths of a point: 1/8 of a point (576 eighths = 1 inch)\n *\n * Standard assumption: 96 DPI (pixels per inch)\n */\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\n/** Standard DPI for screen rendering */\nconst STANDARD_DPI = 96;\n\n/** Twips per inch (1 inch = 1440 twips) */\nexport const TWIPS_PER_INCH = 1440;\n\n/** EMUs per inch (1 inch = 914400 EMUs) */\nconst EMUS_PER_INCH = 914400;\n\n/** Points per inch (1 inch = 72 points) */\nconst POINTS_PER_INCH = 72;\n\n/** Half-points per inch (1 inch = 144 half-points) */\nconst HALF_POINTS_PER_INCH = 144;\n\n/** Eighths of a point per inch (1 inch = 576) */\nconst EIGHTHS_PER_INCH = 576;\n\n/** Pixels per inch at standard DPI */\nexport const PIXELS_PER_INCH = STANDARD_DPI;\n\n// ============================================================================\n// TWIPS CONVERSIONS\n// ============================================================================\n\n/**\n * Convert twips to pixels (at 96 DPI)\n *\n * 1 inch = 1440 twips = 96 pixels\n * → 1 twip = 96/1440 pixels = 1/15 pixels\n */\nexport function twipsToPixels(twips: number): number {\n return (twips / TWIPS_PER_INCH) * PIXELS_PER_INCH;\n}\n\n/**\n * Convert pixels to twips\n */\nexport function pixelsToTwips(px: number): number {\n return (px / PIXELS_PER_INCH) * TWIPS_PER_INCH;\n}\n\n// ============================================================================\n// EMU CONVERSIONS\n// ============================================================================\n\n/**\n * Convert EMUs to pixels (at 96 DPI)\n *\n * 1 inch = 914400 EMUs = 96 pixels\n * Returns 0 for null/undefined/NaN inputs.\n */\nexport function emuToPixels(emu: number | undefined | null): number {\n if (emu == null || isNaN(emu)) return 0;\n return Math.round((emu * PIXELS_PER_INCH) / EMUS_PER_INCH);\n}\n\n/**\n * Convert pixels to EMUs\n */\nexport function pixelsToEmu(px: number): number {\n return (px / PIXELS_PER_INCH) * EMUS_PER_INCH;\n}\n\n/**\n * Convert EMUs to twips\n */\nexport function emuToTwips(emu: number): number {\n return (emu / EMUS_PER_INCH) * TWIPS_PER_INCH;\n}\n\n/**\n * Convert twips to EMUs\n */\nexport function twipsToEmu(twips: number): number {\n return (twips / TWIPS_PER_INCH) * EMUS_PER_INCH;\n}\n\n// ============================================================================\n// POINT CONVERSIONS\n// ============================================================================\n\n/**\n * Convert points to pixels (at 96 DPI)\n *\n * 1 inch = 72 points = 96 pixels\n * → 1 point = 96/72 pixels = 4/3 pixels\n */\nexport function pointsToPixels(points: number): number {\n return (points / POINTS_PER_INCH) * PIXELS_PER_INCH;\n}\n\n// ============================================================================\n// HALF-POINT CONVERSIONS\n// ============================================================================\n\n/**\n * Convert half-points to pixels (at 96 DPI)\n *\n * Half-points are commonly used for font sizes in OOXML (w:sz).\n */\nexport function halfPointsToPixels(halfPoints: number): number {\n return (halfPoints / HALF_POINTS_PER_INCH) * PIXELS_PER_INCH;\n}\n\n/**\n * Convert half-points to points\n */\nexport function halfPointsToPoints(halfPoints: number): number {\n return halfPoints / 2;\n}\n\n/**\n * Convert points to half-points\n */\nexport function pointsToHalfPoints(points: number): number {\n return points * 2;\n}\n\n// ============================================================================\n// EIGHTHS OF A POINT CONVERSIONS\n// ============================================================================\n\n/**\n * Convert eighths of a point to pixels (at 96 DPI)\n *\n * Eighths of a point are used for border widths in OOXML.\n */\nexport function eighthsToPixels(eighths: number): number {\n return (eighths / EIGHTHS_PER_INCH) * PIXELS_PER_INCH;\n}\n\n// ============================================================================\n// UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Round a pixel value to avoid sub-pixel rendering issues\n */\nexport function roundPixels(px: number, decimalPlaces: number = 2): number {\n const factor = Math.pow(10, decimalPlaces);\n return Math.round(px * factor) / factor;\n}\n\n/**\n * Clamp a value between min and max\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n// ============================================================================\n// CSS VALUE FORMATTERS\n// ============================================================================\n\n/**\n * Format a pixel value as CSS string\n */\nexport function formatPx(px: number): string {\n return `${roundPixels(px)}px`;\n}\n","/**\n * Text Box Parser - Parse floating text box containers\n *\n * Text boxes in DOCX are implemented as shapes (wps:wsp) with text body content (wps:txbx).\n * The text body contains w:txbxContent which holds paragraphs and tables like the main document.\n *\n * OOXML Structure:\n * w:drawing\n * └── wp:inline or wp:anchor\n * └── a:graphic\n * └── a:graphicData\n * └── wps:wsp (shape)\n * ├── wps:cNvSpPr (non-visual properties)\n * ├── wps:spPr (shape properties)\n * │ ├── a:xfrm (transform: position, size)\n * │ ├── a:prstGeom (preset geometry - typically \"rect\" for text boxes)\n * │ ├── a:solidFill / a:noFill (fill)\n * │ └── a:ln (outline)\n * ├── wps:txbx (text box container)\n * │ └── w:txbxContent (text content)\n * │ ├── w:p (paragraphs)\n * │ └── w:tbl (tables)\n * └── wps:bodyPr (body properties - margins, text direction, etc.)\n *\n * EMU (English Metric Units): 914400 EMU = 1 inch\n */\n\nimport type {\n TextBox,\n Paragraph,\n Table,\n ImageSize,\n ImagePosition,\n ImageWrap,\n Theme,\n RelationshipMap,\n MediaFile,\n} from '../types/document';\nimport type { StyleMap } from './styleParser';\nimport type { NumberingMap } from './numberingParser';\nimport {\n getChildElements,\n getAttribute,\n parseNumericAttribute,\n findByFullName,\n findChildrenByLocalName,\n type XmlElement,\n} from './xmlParser';\nimport {\n parseFill,\n parseOutline,\n parseAnchorPosition,\n parseAnchorWrap,\n resolveColorValueToHex,\n} from './drawingUtils';\nimport { emuToPixels } from '../utils/units';\n\n// Re-export emuToPixels for backwards compatibility\nexport { emuToPixels } from '../utils/units';\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\n/** Default text box margins in EMUs (0.1 inch) */\nconst DEFAULT_MARGIN_EMU = 91440;\n\n// ============================================================================\n// BODY PROPERTIES PARSING\n// ============================================================================\n\n/**\n * Parse text body properties from wps:bodyPr\n * Returns margins/insets for the text box\n */\nfunction parseBodyProperties(bodyPr: XmlElement | null): {\n margins?: TextBox['margins'];\n} {\n if (!bodyPr) {\n return {};\n }\n\n const result: { margins?: TextBox['margins'] } = {};\n\n // Margins (insets) in EMUs\n const lIns = parseNumericAttribute(bodyPr, null, 'lIns');\n const rIns = parseNumericAttribute(bodyPr, null, 'rIns');\n const tIns = parseNumericAttribute(bodyPr, null, 'tIns');\n const bIns = parseNumericAttribute(bodyPr, null, 'bIns');\n\n if (lIns !== undefined || rIns !== undefined || tIns !== undefined || bIns !== undefined) {\n result.margins = {\n left: lIns,\n right: rIns,\n top: tIns,\n bottom: bIns,\n };\n }\n\n return result;\n}\n\n// ============================================================================\n// CONTENT EXTRACTION\n// ============================================================================\n\n/**\n * Extract raw paragraph elements from w:txbxContent\n * Actual parsing happens via document parser to avoid circular dependencies\n */\nexport function extractTextBoxContentElements(txbxContent: XmlElement | null): {\n paragraphElements: XmlElement[];\n tableElements: XmlElement[];\n} {\n if (!txbxContent) {\n return { paragraphElements: [], tableElements: [] };\n }\n\n const paragraphElements = findChildrenByLocalName(txbxContent, 'p');\n const tableElements = findChildrenByLocalName(txbxContent, 'tbl');\n\n return { paragraphElements, tableElements };\n}\n\n/**\n * Type for the paragraph parser function to avoid circular imports\n */\nexport type ParagraphParserFn = (\n node: XmlElement,\n styles: StyleMap | null,\n theme: Theme | null,\n numbering: NumberingMap | null,\n rels?: RelationshipMap | null\n) => Paragraph;\n\n/**\n * Type for the table parser function to avoid circular imports\n */\nexport type TableParserFn = (\n node: XmlElement,\n styles: StyleMap | null,\n theme: Theme | null,\n numbering: NumberingMap | null,\n rels?: RelationshipMap | null,\n media?: Map<string, MediaFile>\n) => Table;\n\n/**\n * Parse text box content with provided parser functions\n * This avoids circular dependencies by accepting parser functions as parameters\n */\nexport function parseTextBoxContent(\n txbxContent: XmlElement | null,\n parseParagraph: ParagraphParserFn,\n parseTable: TableParserFn | null,\n styles: StyleMap | null,\n theme: Theme | null,\n numbering: NumberingMap | null,\n rels?: RelationshipMap | null,\n _media?: Map<string, MediaFile>\n): Paragraph[] {\n if (!txbxContent) {\n return [];\n }\n\n const paragraphs: Paragraph[] = [];\n const children = getChildElements(txbxContent);\n\n for (const child of children) {\n const name = child.name || '';\n const colonIdx = name.indexOf(':');\n const localName = colonIdx >= 0 ? name.substring(colonIdx + 1) : name;\n\n if (localName === 'p') {\n // Parse paragraph\n const paragraph = parseParagraph(child, styles, theme, numbering, rels);\n paragraphs.push(paragraph);\n } else if (localName === 'tbl' && parseTable) {\n // Tables in text boxes - we can't directly include them in paragraphs array\n // but we could store them separately. For now, skip (most text boxes don't have tables)\n // Future enhancement: support BlockContent[] instead of just Paragraph[]\n }\n }\n\n return paragraphs;\n}\n\n// ============================================================================\n// TEXT BOX DETECTION\n// ============================================================================\n\n/**\n * Check if a drawing element contains a text box\n * Text boxes are shapes with wps:txbx content\n */\nexport function isTextBoxDrawing(drawingEl: XmlElement): boolean {\n const children = getChildElements(drawingEl);\n const container = children.find((el) => el.name === 'wp:inline' || el.name === 'wp:anchor');\n\n if (!container) return false;\n\n const graphic = findByFullName(container, 'a:graphic');\n if (!graphic) return false;\n\n const graphicData = findByFullName(graphic, 'a:graphicData');\n if (!graphicData) return false;\n\n // Check for wps:wsp (shape) with text box content\n const wsp = findByFullName(graphicData, 'wps:wsp');\n if (!wsp) return false;\n\n // Check for text box element\n const txbx = findByFullName(wsp, 'wps:txbx');\n return txbx !== null;\n}\n\n/**\n * Check if a wps:wsp element is a text box\n */\nexport function isShapeTextBox(wsp: XmlElement): boolean {\n const txbx = findByFullName(wsp, 'wps:txbx');\n return txbx !== null;\n}\n\n// ============================================================================\n// MAIN PARSING FUNCTIONS\n// ============================================================================\n\n/**\n * Parse a text box from a w:drawing element\n *\n * This creates a TextBox object with placeholder content.\n * The actual content parsing requires paragraph/table parsers which\n * creates a circular dependency. The document parser should call\n * parseTextBoxContent() separately with the required parsers.\n *\n * @param drawingEl - The w:drawing XML element\n * @returns TextBox object with placeholder content, or null if not a text box\n */\nexport function parseTextBox(drawingEl: XmlElement): TextBox | null {\n const children = getChildElements(drawingEl);\n\n // Find wp:inline or wp:anchor\n const container = children.find((el) => el.name === 'wp:inline' || el.name === 'wp:anchor');\n\n if (!container) return null;\n\n const isAnchor = container.name === 'wp:anchor';\n\n // Navigate to graphic data\n const graphic = findByFullName(container, 'a:graphic');\n if (!graphic) return null;\n\n const graphicData = findByFullName(graphic, 'a:graphicData');\n if (!graphicData) return null;\n\n // Check for wps:wsp (shape)\n const wsp = findByFullName(graphicData, 'wps:wsp');\n if (!wsp) return null;\n\n // Check for text box\n const txbx = findByFullName(wsp, 'wps:txbx');\n if (!txbx) return null;\n\n const wspChildren = getChildElements(wsp);\n\n // Get shape properties\n const spPr = wspChildren.find((el) => el.name === 'wps:spPr');\n\n // Get body properties\n const bodyPr = wspChildren.find((el) => el.name === 'wps:bodyPr');\n\n // Parse size from extent\n const extent = findByFullName(container, 'wp:extent');\n const cx = parseNumericAttribute(extent, null, 'cx') ?? 0;\n const cy = parseNumericAttribute(extent, null, 'cy') ?? 0;\n const size: ImageSize = { width: cx, height: cy };\n\n // Get document properties\n const docPr = findByFullName(container, 'wp:docPr');\n const id = docPr ? (getAttribute(docPr, null, 'id') ?? undefined) : undefined;\n\n // Parse fill\n const fill = parseFill(spPr ?? null);\n\n // Parse outline\n const outline = parseOutline(spPr ?? null);\n\n // Parse body properties (margins)\n const bodyProps = parseBodyProperties(bodyPr ?? null);\n\n // Build text box object with placeholder content\n const textBox: TextBox = {\n type: 'textBox',\n size,\n content: [], // Placeholder - will be filled by document parser\n };\n\n // Add optional properties\n if (id) textBox.id = id;\n if (fill) textBox.fill = fill;\n if (outline) textBox.outline = outline;\n if (bodyProps.margins) textBox.margins = bodyProps.margins;\n\n // Parse position for anchored text boxes\n if (isAnchor) {\n const position = parseAnchorPosition(container);\n if (position) {\n textBox.position = position;\n }\n\n const wrap = parseAnchorWrap(container);\n if (wrap) {\n textBox.wrap = wrap;\n }\n }\n\n return textBox;\n}\n\n/**\n * Parse text box content XML element\n * @param wsp - The wps:wsp element containing the text box\n * @returns The w:txbxContent element or null\n */\nexport function getTextBoxContentElement(wsp: XmlElement): XmlElement | null {\n const txbx = findByFullName(wsp, 'wps:txbx');\n if (!txbx) return null;\n\n return findByFullName(txbx, 'w:txbxContent');\n}\n\n/**\n * Parse text box from a wps:wsp element directly\n * Useful when you already have the shape element\n */\nexport function parseTextBoxFromShape(\n wsp: XmlElement,\n size: ImageSize,\n position?: ImagePosition,\n wrap?: ImageWrap\n): TextBox | null {\n const txbx = findByFullName(wsp, 'wps:txbx');\n if (!txbx) return null;\n\n const wspChildren = getChildElements(wsp);\n\n // Get shape properties\n const spPr = wspChildren.find((el) => el.name === 'wps:spPr');\n\n // Get body properties\n const bodyPr = wspChildren.find((el) => el.name === 'wps:bodyPr');\n\n // Get non-visual properties for ID\n const cNvPr = wspChildren.find((el) => el.name === 'wps:cNvPr');\n const id = cNvPr ? (getAttribute(cNvPr, null, 'id') ?? undefined) : undefined;\n\n // Parse fill\n const fill = parseFill(spPr ?? null);\n\n // Parse outline\n const outline = parseOutline(spPr ?? null);\n\n // Parse body properties (margins)\n const bodyProps = parseBodyProperties(bodyPr ?? null);\n\n // Build text box object\n const textBox: TextBox = {\n type: 'textBox',\n size,\n content: [], // Placeholder\n };\n\n if (id) textBox.id = id;\n if (fill) textBox.fill = fill;\n if (outline) textBox.outline = outline;\n if (bodyProps.margins) textBox.margins = bodyProps.margins;\n if (position) textBox.position = position;\n if (wrap) textBox.wrap = wrap;\n\n return textBox;\n}\n\n// ============================================================================\n// UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Get text box width in pixels\n */\nexport function getTextBoxWidthPx(textBox: TextBox): number {\n return emuToPixels(textBox.size.width);\n}\n\n/**\n * Get text box height in pixels\n */\nexport function getTextBoxHeightPx(textBox: TextBox): number {\n return emuToPixels(textBox.size.height);\n}\n\n/**\n * Get text box dimensions in pixels\n */\nexport function getTextBoxDimensionsPx(textBox: TextBox): { width: number; height: number } {\n return {\n width: emuToPixels(textBox.size.width),\n height: emuToPixels(textBox.size.height),\n };\n}\n\n/**\n * Get text box margins in pixels\n */\nexport function getTextBoxMarginsPx(textBox: TextBox): {\n top: number;\n bottom: number;\n left: number;\n right: number;\n} {\n const margins = textBox.margins;\n return {\n top: emuToPixels(margins?.top ?? DEFAULT_MARGIN_EMU),\n bottom: emuToPixels(margins?.bottom ?? DEFAULT_MARGIN_EMU),\n left: emuToPixels(margins?.left ?? DEFAULT_MARGIN_EMU),\n right: emuToPixels(margins?.right ?? DEFAULT_MARGIN_EMU),\n };\n}\n\n/**\n * Check if text box is floating (anchored)\n */\nexport function isFloatingTextBox(textBox: TextBox): boolean {\n return textBox.position !== undefined || textBox.wrap !== undefined;\n}\n\n/**\n * Check if text box has fill\n */\nexport function hasTextBoxFill(textBox: TextBox): boolean {\n return textBox.fill !== undefined && textBox.fill.type !== 'none';\n}\n\n/**\n * Check if text box has outline\n */\nexport function hasTextBoxOutline(textBox: TextBox): boolean {\n return textBox.outline !== undefined;\n}\n\n/**\n * Check if text box has content\n */\nexport function hasTextBoxContent(textBox: TextBox): boolean {\n return textBox.content.length > 0;\n}\n\n/**\n * Get plain text from text box (helper for search/indexing)\n */\nexport function getTextBoxText(textBox: TextBox): string {\n // This would require getParagraphText utility\n // For now, just join paragraph content\n const parts: string[] = [];\n\n for (const paragraph of textBox.content) {\n const runTexts: string[] = [];\n for (const item of paragraph.content) {\n if (item.type === 'run') {\n for (const content of item.content) {\n if (content.type === 'text') {\n runTexts.push(content.text);\n }\n }\n }\n }\n parts.push(runTexts.join(''));\n }\n\n return parts.join('\\n');\n}\n\n/**\n * Resolve fill color to CSS color string\n */\nexport function resolveTextBoxFillColor(textBox: TextBox): string | undefined {\n if (!textBox.fill || textBox.fill.type !== 'solid') return undefined;\n return resolveColorValueToHex(textBox.fill.color);\n}\n\n/**\n * Resolve outline color to CSS color string\n */\nexport function resolveTextBoxOutlineColor(textBox: TextBox): string | undefined {\n if (!textBox.outline?.color) return undefined;\n return resolveColorValueToHex(textBox.outline.color);\n}\n\n/**\n * Get outline width in pixels\n */\nexport function getTextBoxOutlineWidthPx(textBox: TextBox): number {\n if (!textBox.outline?.width) return 0;\n return emuToPixels(textBox.outline.width);\n}\n","/**\n * Image Parser - Parse embedded images from w:drawing elements\n *\n * DOCX images are contained in <w:drawing> elements with either:\n * - wp:inline - Inline images that flow with text\n * - wp:anchor - Floating/anchored images with text wrapping\n *\n * OOXML Structure:\n * w:drawing\n * ├── wp:inline or wp:anchor\n * │ ├── wp:extent (size: cx, cy in EMUs)\n * │ ├── wp:effectExtent (effect margins)\n * │ ├── wp:docPr (document properties: id, name, descr, title)\n * │ ├── wp:positionH / wp:positionV (for anchor only)\n * │ ├── wp:wrap* (wrapping mode for anchor: wrapNone, wrapSquare, etc.)\n * │ └── a:graphic\n * │ └── a:graphicData\n * │ └── pic:pic\n * │ ├── pic:nvPicPr (non-visual properties)\n * │ ├── pic:blipFill\n * │ │ └── a:blip (r:embed = rId)\n * │ └── pic:spPr\n * │ └── a:xfrm (transform: rotation, flip)\n *\n * EMU (English Metric Units): 914400 EMU = 1 inch\n * Conversion: pixels = (emu * 96) / 914400\n */\n\nimport type {\n Image,\n ImageSize,\n ImageWrap,\n ImagePosition,\n ImageTransform,\n ImagePadding,\n RelationshipMap,\n MediaFile,\n} from '../types/document';\nimport {\n findChild,\n getChildElements,\n getAttribute,\n parseNumericAttribute,\n findByFullName,\n type XmlElement,\n} from './xmlParser';\nimport { resolveTarget } from './relsParser';\nimport { isTextBoxDrawing } from './textBoxParser';\nimport { emuToPixels } from '../utils/units';\nimport {\n parsePositionH,\n parsePositionV,\n WRAP_ELEMENT_NAMES as WRAP_ELEMENTS,\n parseWrapElement,\n} from './drawingUtils';\n\n// Re-export for backwards compatibility\nexport { emuToPixels, pixelsToEmu } from '../utils/units';\n\n// ============================================================================\n// ROTATION CONVERSION\n// ============================================================================\n\n/**\n * Convert rotation value (1/60000 of a degree) to degrees\n *\n * @param rot - Rotation in 60000ths of a degree\n * @returns Rotation in degrees\n */\nfunction rotToDegrees(rot: string | null | undefined): number | undefined {\n if (!rot) return undefined;\n const val = parseInt(rot, 10);\n if (isNaN(val)) return undefined;\n return val / 60000;\n}\n\n// ============================================================================\n// ELEMENT FINDERS\n// ============================================================================\n\n/**\n * Find any of the specified elements\n */\nfunction findAnyOf(parent: XmlElement, names: string[]): XmlElement | null {\n const children = getChildElements(parent);\n for (const child of children) {\n if (names.includes(child.name || '')) {\n return child;\n }\n }\n return null;\n}\n\n// ============================================================================\n// SIZE PARSING\n// ============================================================================\n\n/**\n * Parse extent element for image size\n *\n * @param extent - wp:extent element\n * @returns ImageSize in EMUs\n */\nfunction parseExtent(extent: XmlElement | null): ImageSize {\n if (!extent) {\n return { width: 0, height: 0 };\n }\n\n const cx = parseNumericAttribute(extent, null, 'cx') ?? 0;\n const cy = parseNumericAttribute(extent, null, 'cy') ?? 0;\n\n return { width: cx, height: cy };\n}\n\n/**\n * Parse effect extent for shadow/effect margins\n *\n * @param effectExtent - wp:effectExtent element\n * @returns Padding for effects\n */\nfunction parseEffectExtent(effectExtent: XmlElement | null): ImagePadding | undefined {\n if (!effectExtent) return undefined;\n\n const l = parseNumericAttribute(effectExtent, null, 'l') ?? 0;\n const t = parseNumericAttribute(effectExtent, null, 't') ?? 0;\n const r = parseNumericAttribute(effectExtent, null, 'r') ?? 0;\n const b = parseNumericAttribute(effectExtent, null, 'b') ?? 0;\n\n if (l === 0 && t === 0 && r === 0 && b === 0) {\n return undefined;\n }\n\n return {\n left: l,\n top: t,\n right: r,\n bottom: b,\n };\n}\n\n// ============================================================================\n// DOCUMENT PROPERTIES PARSING\n// ============================================================================\n\n/**\n * Parse document properties (wp:docPr)\n *\n * @param docPr - wp:docPr element\n * @returns Object with id, name, description, title\n */\nfunction parseDocProps(docPr: XmlElement | null): {\n id?: string;\n name?: string;\n alt?: string;\n title?: string;\n decorative?: boolean;\n hlinkRId?: string;\n} {\n if (!docPr) return {};\n\n const id = getAttribute(docPr, null, 'id') ?? undefined;\n const name = getAttribute(docPr, null, 'name') ?? undefined;\n const descr = getAttribute(docPr, null, 'descr') ?? undefined;\n const title = getAttribute(docPr, null, 'title') ?? undefined;\n\n // Check for decorative flag (accessibility)\n // In newer OOXML, this is indicated by a:decorative element or attribute\n const decorative = getAttribute(docPr, null, 'decorative') === '1';\n\n // Check for hyperlink (a:hlinkClick) — clickable image\n const hlinkClickEl = findChild(docPr, 'a', 'hlinkClick');\n const hlinkRId = hlinkClickEl ? (getAttribute(hlinkClickEl, 'r', 'id') ?? undefined) : undefined;\n\n return {\n id,\n name,\n alt: descr,\n title,\n decorative: decorative || undefined,\n hlinkRId,\n };\n}\n\n// ============================================================================\n// TRANSFORM PARSING\n// ============================================================================\n\n/**\n * Parse transform properties from a:xfrm\n */\nfunction parseTransform(xfrm: XmlElement | null): ImageTransform | undefined {\n if (!xfrm) return undefined;\n\n const rot = getAttribute(xfrm, null, 'rot');\n const flipH = getAttribute(xfrm, null, 'flipH') === '1';\n const flipV = getAttribute(xfrm, null, 'flipV') === '1';\n\n const rotation = rotToDegrees(rot);\n\n if (rotation === undefined && !flipH && !flipV) {\n return undefined;\n }\n\n const transform: ImageTransform = {};\n if (rotation !== undefined) transform.rotation = rotation;\n if (flipH) transform.flipH = true;\n if (flipV) transform.flipV = true;\n\n return transform;\n}\n\n// ============================================================================\n// BLIP EXTRACTION (image relationship ID)\n// ============================================================================\n\n/**\n * Find the a:blip element and extract the relationship ID\n *\n * Path: a:graphic > a:graphicData > pic:pic > pic:blipFill > a:blip\n */\nfunction findBlipElement(container: XmlElement): XmlElement | null {\n // Find a:graphic\n const graphic = findByFullName(container, 'a:graphic');\n if (!graphic) return null;\n\n // Find a:graphicData\n const graphicData = findByFullName(graphic, 'a:graphicData');\n if (!graphicData) return null;\n\n // Find pic:pic\n const pic = findByFullName(graphicData, 'pic:pic');\n if (!pic) return null;\n\n // Find pic:blipFill\n const blipFill = findByFullName(pic, 'pic:blipFill');\n if (!blipFill) return null;\n\n // Find a:blip\n const blip = findByFullName(blipFill, 'a:blip');\n return blip;\n}\n\n/**\n * Extract rId from a:blip element\n */\nfunction extractBlipRId(blip: XmlElement | null): string {\n if (!blip) return '';\n\n // The rId is in r:embed attribute\n const rEmbed = getAttribute(blip, 'r', 'embed');\n if (rEmbed) return rEmbed;\n\n // Sometimes it's just \"embed\" without namespace\n const embed = getAttribute(blip, null, 'embed');\n if (embed) return embed;\n\n // Check r:link for linked (not embedded) images\n const rLink = getAttribute(blip, 'r', 'link');\n if (rLink) return rLink;\n\n return '';\n}\n\n/**\n * Find transform (a:xfrm) from picture shape properties\n *\n * Path: a:graphic > a:graphicData > pic:pic > pic:spPr > a:xfrm\n */\nfunction findPictureTransform(container: XmlElement): XmlElement | null {\n const graphic = findByFullName(container, 'a:graphic');\n if (!graphic) return null;\n\n const graphicData = findByFullName(graphic, 'a:graphicData');\n if (!graphicData) return null;\n\n const pic = findByFullName(graphicData, 'pic:pic');\n if (!pic) return null;\n\n const spPr = findByFullName(pic, 'pic:spPr');\n if (!spPr) return null;\n\n const xfrm = findByFullName(spPr, 'a:xfrm');\n return xfrm;\n}\n\n// ============================================================================\n// MEDIA RESOLUTION\n// ============================================================================\n\n/**\n * Normalize a target path to the standard word/media/... format\n */\nfunction normalizeMediaPath(targetPath: string): string {\n if (!targetPath) return targetPath;\n\n // Remove leading slashes\n let normalized = targetPath.replace(/^\\/+/, '');\n\n // Ensure word/ prefix for media files\n if (normalized.startsWith('media/')) {\n normalized = `word/${normalized}`;\n } else if (!normalized.startsWith('word/')) {\n normalized = `word/${normalized}`;\n }\n\n return normalized;\n}\n\n/**\n * Get MIME type from file extension\n */\nfunction getMimeType(path: string): string {\n const ext = path.split('.').pop()?.toLowerCase() ?? '';\n\n const mimeTypes: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n gif: 'image/gif',\n bmp: 'image/bmp',\n tiff: 'image/tiff',\n tif: 'image/tiff',\n webp: 'image/webp',\n svg: 'image/svg+xml',\n emf: 'image/x-emf',\n wmf: 'image/x-wmf',\n };\n\n return mimeTypes[ext] ?? 'application/octet-stream';\n}\n\n/**\n * Resolve image data from relationships and media map\n *\n * @param rId - Relationship ID (e.g., \"rId1\")\n * @param rels - Relationship map\n * @param media - Media files map\n * @returns Object with src (data URL or blob), mimeType, and filename\n */\nfunction resolveImageData(\n rId: string,\n rels: RelationshipMap | undefined,\n media: Map<string, MediaFile> | undefined\n): { src?: string; mimeType?: string; filename?: string } {\n if (!rId || !rels) {\n return {};\n }\n\n const rel = rels.get(rId);\n if (!rel) {\n return {};\n }\n\n // Get the target path\n const targetPath = rel.target;\n if (!targetPath) {\n return {};\n }\n\n // Normalize the path\n const normalizedPath = normalizeMediaPath(targetPath);\n const filename = targetPath.split('/').pop();\n\n // Case-insensitive lookup helper for media map\n const findMediaCaseInsensitive = (\n map: Map<string, MediaFile>,\n searchPath: string\n ): MediaFile | undefined => {\n const lowerPath = searchPath.toLowerCase();\n for (const [key, value] of map.entries()) {\n if (key.toLowerCase() === lowerPath) {\n return value;\n }\n }\n return undefined;\n };\n\n // Try to find the media file (case-insensitive)\n if (media) {\n // Try normalized path first\n const mediaFile = findMediaCaseInsensitive(media, normalizedPath);\n if (mediaFile) {\n return {\n src: mediaFile.dataUrl || mediaFile.base64, // Use data URL or base64\n mimeType: mediaFile.mimeType,\n filename,\n };\n }\n\n // Try without word/ prefix\n const altPath = targetPath.replace(/^\\/+/, '');\n const altMediaFile = findMediaCaseInsensitive(media, altPath);\n if (altMediaFile) {\n return {\n src: altMediaFile.dataUrl || altMediaFile.base64,\n mimeType: altMediaFile.mimeType,\n filename,\n };\n }\n\n // Try with word/ prefix added\n const withWordPrefix = `word/${altPath}`;\n const prefixedMediaFile = findMediaCaseInsensitive(media, withWordPrefix);\n if (prefixedMediaFile) {\n return {\n src: prefixedMediaFile.dataUrl || prefixedMediaFile.base64,\n mimeType: prefixedMediaFile.mimeType,\n filename,\n };\n }\n }\n\n // Return at least the MIME type based on extension\n return {\n mimeType: getMimeType(targetPath),\n filename,\n };\n}\n\n// ============================================================================\n// MAIN PARSING FUNCTIONS\n// ============================================================================\n\n/**\n * Parse a wp:inline element (inline image)\n *\n * @param inlineEl - The wp:inline element\n * @param rels - Relationship map for resolving rId\n * @param media - Media files map\n * @returns Parsed Image object\n */\nfunction parseInline(\n inlineEl: XmlElement,\n rels: RelationshipMap | undefined,\n media: Map<string, MediaFile> | undefined\n): Image {\n // Parse extent (size)\n const extent = findByFullName(inlineEl, 'wp:extent');\n const size = parseExtent(extent);\n\n // Parse effect extent\n const effectExtent = findByFullName(inlineEl, 'wp:effectExtent');\n const padding = parseEffectExtent(effectExtent);\n\n // Parse document properties\n const docPr = findByFullName(inlineEl, 'wp:docPr');\n const props = parseDocProps(docPr);\n\n // Find blip and extract rId\n const blip = findBlipElement(inlineEl);\n const rId = extractBlipRId(blip);\n\n // Resolve image data\n const imageData = resolveImageData(rId, rels, media);\n\n // Find transform\n const xfrm = findPictureTransform(inlineEl);\n const transform = parseTransform(xfrm);\n\n // Read distance attributes from wp:inline (OOXML spec: distT, distB, distL, distR)\n const distT = parseNumericAttribute(inlineEl, null, 'distT') ?? undefined;\n const distB = parseNumericAttribute(inlineEl, null, 'distB') ?? undefined;\n const distL = parseNumericAttribute(inlineEl, null, 'distL') ?? undefined;\n const distR = parseNumericAttribute(inlineEl, null, 'distR') ?? undefined;\n\n const wrap: ImageWrap = { type: 'inline' };\n if (distT !== undefined) wrap.distT = distT;\n if (distB !== undefined) wrap.distB = distB;\n if (distL !== undefined) wrap.distL = distL;\n if (distR !== undefined) wrap.distR = distR;\n\n const image: Image = {\n type: 'image',\n rId,\n size,\n wrap,\n };\n\n // Add optional properties\n if (props.id) image.id = props.id;\n if (props.alt) image.alt = props.alt;\n if (props.title) image.title = props.title;\n if (props.decorative) image.decorative = true;\n if (imageData.src) image.src = imageData.src;\n if (imageData.mimeType) image.mimeType = imageData.mimeType;\n if (imageData.filename) image.filename = imageData.filename;\n if (padding) image.padding = padding;\n if (transform) image.transform = transform;\n\n // Resolve image hyperlink (a:hlinkClick)\n if (props.hlinkRId && rels) {\n const href = resolveTarget(rels, props.hlinkRId);\n if (href) image.hlinkHref = href;\n }\n\n return image;\n}\n\n/**\n * Parse a wp:anchor element (floating/anchored image)\n *\n * @param anchorEl - The wp:anchor element\n * @param rels - Relationship map for resolving rId\n * @param media - Media files map\n * @returns Parsed Image object\n */\nfunction parseAnchor(\n anchorEl: XmlElement,\n rels: RelationshipMap | undefined,\n media: Map<string, MediaFile> | undefined\n): Image {\n // Parse extent (size)\n const extent = findByFullName(anchorEl, 'wp:extent');\n const size = parseExtent(extent);\n\n // Parse effect extent\n const effectExtent = findByFullName(anchorEl, 'wp:effectExtent');\n const padding = parseEffectExtent(effectExtent);\n\n // Parse document properties\n const docPr = findByFullName(anchorEl, 'wp:docPr');\n const props = parseDocProps(docPr);\n\n // Check behindDoc attribute\n const behindDoc = getAttribute(anchorEl, null, 'behindDoc') === '1';\n\n // Read distance attributes from the wp:anchor element itself (fallback values)\n const anchorDistances = {\n distT: parseNumericAttribute(anchorEl, null, 'distT') ?? undefined,\n distB: parseNumericAttribute(anchorEl, null, 'distB') ?? undefined,\n distL: parseNumericAttribute(anchorEl, null, 'distL') ?? undefined,\n distR: parseNumericAttribute(anchorEl, null, 'distR') ?? undefined,\n };\n\n // Parse wrap element (wrap child values take priority over anchor-level values)\n const wrapEl = findAnyOf(anchorEl, WRAP_ELEMENTS);\n const wrap = parseWrapElement(wrapEl, behindDoc, anchorDistances);\n\n // Parse position\n const posH = findByFullName(anchorEl, 'wp:positionH');\n const posV = findByFullName(anchorEl, 'wp:positionV');\n const horizontal = parsePositionH(posH);\n const vertical = parsePositionV(posV);\n\n let position: ImagePosition | undefined;\n if (horizontal || vertical) {\n position = {\n horizontal: horizontal ?? { relativeTo: 'column' },\n vertical: vertical ?? { relativeTo: 'paragraph' },\n };\n }\n\n // Find blip and extract rId\n const blip = findBlipElement(anchorEl);\n const rId = extractBlipRId(blip);\n\n // Resolve image data\n const imageData = resolveImageData(rId, rels, media);\n\n // Find transform\n const xfrm = findPictureTransform(anchorEl);\n const transform = parseTransform(xfrm);\n\n const image: Image = {\n type: 'image',\n rId,\n size,\n wrap,\n };\n\n // Add optional properties\n if (props.id) image.id = props.id;\n if (props.alt) image.alt = props.alt;\n if (props.title) image.title = props.title;\n if (props.decorative) image.decorative = true;\n if (imageData.src) image.src = imageData.src;\n if (imageData.mimeType) image.mimeType = imageData.mimeType;\n if (imageData.filename) image.filename = imageData.filename;\n if (position) image.position = position;\n if (padding) image.padding = padding;\n if (transform) image.transform = transform;\n\n // Resolve image hyperlink (a:hlinkClick)\n if (props.hlinkRId && rels) {\n const href = resolveTarget(rels, props.hlinkRId);\n if (href) image.hlinkHref = href;\n }\n\n return image;\n}\n\n/**\n * Parse a w:drawing element\n *\n * The drawing element contains either wp:inline or wp:anchor.\n *\n * @param drawingEl - The w:drawing element\n * @param rels - Relationship map for resolving rId\n * @param media - Media files map\n * @returns Parsed Image object or null if not an image\n */\nexport function parseDrawing(\n drawingEl: XmlElement,\n rels: RelationshipMap | undefined,\n media: Map<string, MediaFile> | undefined\n): Image | null {\n // Skip text box shapes — they are handled by textBoxParser, not as images\n if (isTextBoxDrawing(drawingEl)) return null;\n\n const children = getChildElements(drawingEl);\n\n for (const child of children) {\n const name = child.name || '';\n\n if (name === 'wp:inline' || name === 'wp:anchor') {\n return name === 'wp:inline'\n ? parseInline(child, rels, media)\n : parseAnchor(child, rels, media);\n }\n }\n\n return null;\n}\n\n/**\n * Parse an image from a w:drawing element\n *\n * This is the main entry point for image parsing.\n *\n * @param node - The w:drawing XML element\n * @param rels - Relationship map for resolving rId\n * @param media - Media files map\n * @returns Parsed Image object or null if parsing fails\n */\nexport function parseImage(\n node: XmlElement,\n rels: RelationshipMap | undefined,\n media: Map<string, MediaFile> | undefined\n): Image | null {\n return parseDrawing(node, rels, media);\n}\n\n// ============================================================================\n// UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Check if an image is inline (not floating)\n */\nexport function isInlineImage(image: Image): boolean {\n return image.wrap.type === 'inline';\n}\n\n/**\n * Check if an image is floating (anchored)\n */\nexport function isFloatingImage(image: Image): boolean {\n return image.wrap.type !== 'inline';\n}\n\n/**\n * Check if an image is behind text\n */\nexport function isBehindText(image: Image): boolean {\n return image.wrap.type === 'behind';\n}\n\n/**\n * Check if an image is in front of text\n */\nexport function isInFrontOfText(image: Image): boolean {\n return image.wrap.type === 'inFront';\n}\n\n/**\n * Get image width in pixels\n */\nexport function getImageWidthPx(image: Image): number {\n return emuToPixels(image.size.width);\n}\n\n/**\n * Get image height in pixels\n */\nexport function getImageHeightPx(image: Image): number {\n return emuToPixels(image.size.height);\n}\n\n/**\n * Get image dimensions in pixels\n */\nexport function getImageDimensionsPx(image: Image): { width: number; height: number } {\n return {\n width: emuToPixels(image.size.width),\n height: emuToPixels(image.size.height),\n };\n}\n\n/**\n * Check if image has alt text (for accessibility)\n */\nexport function hasAltText(image: Image): boolean {\n return !!image.alt && image.alt.trim().length > 0;\n}\n\n/**\n * Check if image is decorative (should be ignored by screen readers)\n */\nexport function isDecorativeImage(image: Image): boolean {\n return image.decorative === true;\n}\n\n/**\n * Get wrap distances in pixels\n */\nexport function getWrapDistancesPx(image: Image): {\n top: number;\n bottom: number;\n left: number;\n right: number;\n} {\n return {\n top: emuToPixels(image.wrap.distT),\n bottom: emuToPixels(image.wrap.distB),\n left: emuToPixels(image.wrap.distL),\n right: emuToPixels(image.wrap.distR),\n };\n}\n\n/**\n * Check if image needs text wrapping\n */\nexport function needsTextWrapping(image: Image): boolean {\n const wrapTypes = ['square', 'tight', 'through', 'topAndBottom'];\n return wrapTypes.includes(image.wrap.type);\n}\n","/**\n * Run Parser - Parse text runs (w:r) with complete formatting\n *\n * A run is a contiguous region of text with the same character formatting.\n * Runs can contain:\n * - Text (w:t)\n * - Tabs (w:tab)\n * - Line breaks (w:br)\n * - Symbols (w:sym)\n * - Footnote/endnote references\n * - Field characters\n * - Drawings/images (w:drawing)\n * - And more...\n *\n * OOXML Reference:\n * - Run: w:r\n * - Run properties: w:rPr\n * - Text content: w:t\n */\n\nimport type {\n Run,\n RunContent,\n TextContent,\n TabContent,\n BreakContent,\n SymbolContent,\n NoteReferenceContent,\n FieldCharContent,\n InstrTextContent,\n SoftHyphenContent,\n NoBreakHyphenContent,\n DrawingContent,\n RunPropertyChange,\n TextFormatting,\n ColorValue,\n ShadingProperties,\n UnderlineStyle,\n Theme,\n Image,\n RelationshipMap,\n MediaFile,\n} from '../types/document';\nimport type { StyleMap } from './styleParser';\nimport {\n findChild,\n findChildren,\n getAttribute,\n getChildElements,\n getTextContent,\n parseBooleanElement,\n parseNumericAttribute,\n type XmlElement,\n} from './xmlParser';\nimport { resolveThemeFontRef } from './themeParser';\nimport { parseImage } from './imageParser';\n\n/**\n * Parse color value from attributes\n */\nfunction parseColorValue(\n rgb: string | null,\n themeColor: string | null,\n themeTint: string | null,\n themeShade: string | null\n): ColorValue {\n const color: ColorValue = {};\n\n if (rgb && rgb !== 'auto') {\n color.rgb = rgb;\n } else if (rgb === 'auto') {\n color.auto = true;\n }\n\n if (themeColor) {\n color.themeColor = themeColor as ColorValue['themeColor'];\n }\n\n if (themeTint) {\n color.themeTint = themeTint;\n }\n\n if (themeShade) {\n color.themeShade = themeShade;\n }\n\n return color;\n}\n\n/**\n * Parse shading properties (w:shd)\n */\nfunction parseShadingProperties(shd: XmlElement | null): ShadingProperties | undefined {\n if (!shd) return undefined;\n\n const props: ShadingProperties = {};\n\n const color = getAttribute(shd, 'w', 'color');\n if (color && color !== 'auto') {\n props.color = { rgb: color };\n }\n\n const fill = getAttribute(shd, 'w', 'fill');\n if (fill && fill !== 'auto') {\n props.fill = { rgb: fill };\n }\n\n const themeFill = getAttribute(shd, 'w', 'themeFill');\n if (themeFill) {\n props.fill = props.fill || {};\n props.fill.themeColor = themeFill as ColorValue['themeColor'];\n }\n\n const themeFillTint = getAttribute(shd, 'w', 'themeFillTint');\n if (themeFillTint && props.fill) {\n props.fill.themeTint = themeFillTint;\n }\n\n const themeFillShade = getAttribute(shd, 'w', 'themeFillShade');\n if (themeFillShade && props.fill) {\n props.fill.themeShade = themeFillShade;\n }\n\n const pattern = getAttribute(shd, 'w', 'val');\n if (pattern) {\n props.pattern = pattern as ShadingProperties['pattern'];\n }\n\n return Object.keys(props).length > 0 ? props : undefined;\n}\n\n/**\n * Parse run formatting properties (w:rPr)\n *\n * Handles ALL rPr properties:\n * - w:b (bold), w:i (italic), w:u (underline with style)\n * - w:strike (strikethrough), w:dstrike (double strike)\n * - w:vertAlign (superscript/subscript)\n * - w:smallCaps, w:caps (capitalization)\n * - w:highlight (text highlight color)\n * - w:shd (character shading)\n * - w:color (text color with theme resolution)\n * - w:sz (font size in half-points)\n * - w:rFonts (font family with theme resolution)\n * - w:spacing (character spacing)\n * - w:effect (text effects)\n * - And more...\n */\nexport function parseRunProperties(\n rPr: XmlElement | null,\n theme: Theme | null,\n _styles?: StyleMap\n): TextFormatting | undefined {\n if (!rPr) return undefined;\n\n const formatting: TextFormatting = {};\n\n // Bold (w:b)\n const b = findChild(rPr, 'w', 'b');\n if (b) formatting.bold = parseBooleanElement(b);\n\n const bCs = findChild(rPr, 'w', 'bCs');\n if (bCs) formatting.boldCs = parseBooleanElement(bCs);\n\n // Italic (w:i)\n const i = findChild(rPr, 'w', 'i');\n if (i) formatting.italic = parseBooleanElement(i);\n\n const iCs = findChild(rPr, 'w', 'iCs');\n if (iCs) formatting.italicCs = parseBooleanElement(iCs);\n\n // Underline (w:u)\n const u = findChild(rPr, 'w', 'u');\n if (u) {\n const style = getAttribute(u, 'w', 'val') as UnderlineStyle | null;\n if (style) {\n formatting.underline = { style };\n const colorVal = getAttribute(u, 'w', 'color');\n const themeColor = getAttribute(u, 'w', 'themeColor');\n if (colorVal || themeColor) {\n formatting.underline.color = parseColorValue(\n colorVal,\n themeColor,\n getAttribute(u, 'w', 'themeTint'),\n getAttribute(u, 'w', 'themeShade')\n );\n }\n }\n }\n\n // Strikethrough (w:strike)\n const strike = findChild(rPr, 'w', 'strike');\n if (strike) formatting.strike = parseBooleanElement(strike);\n\n // Double strikethrough (w:dstrike)\n const dstrike = findChild(rPr, 'w', 'dstrike');\n if (dstrike) formatting.doubleStrike = parseBooleanElement(dstrike);\n\n // Vertical alignment - superscript/subscript (w:vertAlign)\n const vertAlign = findChild(rPr, 'w', 'vertAlign');\n if (vertAlign) {\n const val = getAttribute(vertAlign, 'w', 'val');\n if (val === 'superscript' || val === 'subscript' || val === 'baseline') {\n formatting.vertAlign = val;\n }\n }\n\n // Small caps (w:smallCaps)\n const smallCaps = findChild(rPr, 'w', 'smallCaps');\n if (smallCaps) formatting.smallCaps = parseBooleanElement(smallCaps);\n\n // All caps (w:caps)\n const caps = findChild(rPr, 'w', 'caps');\n if (caps) formatting.allCaps = parseBooleanElement(caps);\n\n // Hidden text (w:vanish)\n const vanish = findChild(rPr, 'w', 'vanish');\n if (vanish) formatting.hidden = parseBooleanElement(vanish);\n\n // Text color (w:color)\n const color = findChild(rPr, 'w', 'color');\n if (color) {\n formatting.color = parseColorValue(\n getAttribute(color, 'w', 'val'),\n getAttribute(color, 'w', 'themeColor'),\n getAttribute(color, 'w', 'themeTint'),\n getAttribute(color, 'w', 'themeShade')\n );\n }\n\n // Highlight color (w:highlight)\n const highlight = findChild(rPr, 'w', 'highlight');\n if (highlight) {\n const val = getAttribute(highlight, 'w', 'val');\n if (val) {\n formatting.highlight = val as TextFormatting['highlight'];\n }\n }\n\n // Character shading (w:shd)\n const shd = findChild(rPr, 'w', 'shd');\n if (shd) {\n formatting.shading = parseShadingProperties(shd);\n }\n\n // Font size in half-points (w:sz)\n const sz = findChild(rPr, 'w', 'sz');\n if (sz) {\n const val = parseNumericAttribute(sz, 'w', 'val');\n if (val !== undefined) formatting.fontSize = val;\n }\n\n // Font size complex script (w:szCs)\n const szCs = findChild(rPr, 'w', 'szCs');\n if (szCs) {\n const val = parseNumericAttribute(szCs, 'w', 'val');\n if (val !== undefined) formatting.fontSizeCs = val;\n }\n\n // Font family (w:rFonts)\n const rFonts = findChild(rPr, 'w', 'rFonts');\n if (rFonts) {\n formatting.fontFamily = {\n ascii: getAttribute(rFonts, 'w', 'ascii') ?? undefined,\n hAnsi: getAttribute(rFonts, 'w', 'hAnsi') ?? undefined,\n eastAsia: getAttribute(rFonts, 'w', 'eastAsia') ?? undefined,\n cs: getAttribute(rFonts, 'w', 'cs') ?? undefined,\n };\n\n // Theme font references\n const asciiTheme = getAttribute(rFonts, 'w', 'asciiTheme');\n if (asciiTheme) {\n formatting.fontFamily.asciiTheme = asciiTheme as TextFormatting['fontFamily'] extends {\n asciiTheme?: infer T;\n }\n ? T\n : never;\n // Also resolve the actual font name for convenience\n if (theme && !formatting.fontFamily.ascii) {\n formatting.fontFamily.ascii = resolveThemeFontRef(theme, asciiTheme);\n }\n }\n\n const hAnsiTheme = getAttribute(rFonts, 'w', 'hAnsiTheme');\n if (hAnsiTheme) {\n formatting.fontFamily.hAnsiTheme = hAnsiTheme;\n if (theme && !formatting.fontFamily.hAnsi) {\n formatting.fontFamily.hAnsi = resolveThemeFontRef(theme, hAnsiTheme);\n }\n }\n\n const eastAsiaTheme = getAttribute(rFonts, 'w', 'eastAsiaTheme');\n if (eastAsiaTheme) {\n formatting.fontFamily.eastAsiaTheme = eastAsiaTheme;\n if (theme && !formatting.fontFamily.eastAsia) {\n formatting.fontFamily.eastAsia = resolveThemeFontRef(theme, eastAsiaTheme);\n }\n }\n\n const csTheme = getAttribute(rFonts, 'w', 'cstheme');\n if (csTheme) {\n formatting.fontFamily.csTheme = csTheme;\n if (theme && !formatting.fontFamily.cs) {\n formatting.fontFamily.cs = resolveThemeFontRef(theme, csTheme);\n }\n }\n }\n\n // Character spacing in twips (w:spacing)\n const spacing = findChild(rPr, 'w', 'spacing');\n if (spacing) {\n const val = parseNumericAttribute(spacing, 'w', 'val');\n if (val !== undefined) formatting.spacing = val;\n }\n\n // Position - raised/lowered in half-points (w:position)\n const position = findChild(rPr, 'w', 'position');\n if (position) {\n const val = parseNumericAttribute(position, 'w', 'val');\n if (val !== undefined) formatting.position = val;\n }\n\n // Horizontal text scale percentage (w:w)\n const w = findChild(rPr, 'w', 'w');\n if (w) {\n const val = parseNumericAttribute(w, 'w', 'val');\n if (val !== undefined) formatting.scale = val;\n }\n\n // Kerning threshold in half-points (w:kern)\n const kern = findChild(rPr, 'w', 'kern');\n if (kern) {\n const val = parseNumericAttribute(kern, 'w', 'val');\n if (val !== undefined) formatting.kerning = val;\n }\n\n // Text effect animation (w:effect)\n const effect = findChild(rPr, 'w', 'effect');\n if (effect) {\n const val = getAttribute(effect, 'w', 'val');\n if (val) formatting.effect = val as TextFormatting['effect'];\n }\n\n // Emphasis mark (w:em)\n const em = findChild(rPr, 'w', 'em');\n if (em) {\n const val = getAttribute(em, 'w', 'val');\n if (val) formatting.emphasisMark = val as TextFormatting['emphasisMark'];\n }\n\n // Emboss effect (w:emboss)\n const emboss = findChild(rPr, 'w', 'emboss');\n if (emboss) formatting.emboss = parseBooleanElement(emboss);\n\n // Imprint/engrave effect (w:imprint)\n const imprint = findChild(rPr, 'w', 'imprint');\n if (imprint) formatting.imprint = parseBooleanElement(imprint);\n\n // Outline effect (w:outline)\n const outline = findChild(rPr, 'w', 'outline');\n if (outline) formatting.outline = parseBooleanElement(outline);\n\n // Shadow effect (w:shadow)\n const shadow = findChild(rPr, 'w', 'shadow');\n if (shadow) formatting.shadow = parseBooleanElement(shadow);\n\n // Right-to-left text (w:rtl)\n const rtl = findChild(rPr, 'w', 'rtl');\n if (rtl) formatting.rtl = parseBooleanElement(rtl);\n\n // Complex script formatting (w:cs)\n const cs = findChild(rPr, 'w', 'cs');\n if (cs) formatting.cs = parseBooleanElement(cs);\n\n // Character style reference (w:rStyle)\n const rStyle = findChild(rPr, 'w', 'rStyle');\n if (rStyle) {\n const val = getAttribute(rStyle, 'w', 'val');\n if (val) formatting.styleId = val;\n }\n\n return Object.keys(formatting).length > 0 ? formatting : undefined;\n}\n\nfunction parsePropertyChangeInfo(changeElement: XmlElement): RunPropertyChange['info'] {\n const rawId = getAttribute(changeElement, 'w', 'id');\n const parsedId = rawId ? parseInt(rawId, 10) : 0;\n const author = (getAttribute(changeElement, 'w', 'author') ?? '').trim();\n const date = (getAttribute(changeElement, 'w', 'date') ?? '').trim();\n const rsid = (getAttribute(changeElement, 'w', 'rsid') ?? '').trim();\n\n return {\n id: Number.isInteger(parsedId) && parsedId >= 0 ? parsedId : 0,\n author: author.length > 0 ? author : 'Unknown',\n date: date.length > 0 ? date : undefined,\n rsid: rsid.length > 0 ? rsid : undefined,\n };\n}\n\nfunction parseRunPropertyChanges(\n rPr: XmlElement | null,\n theme: Theme | null,\n styles: StyleMap | null,\n currentFormatting: TextFormatting | undefined\n): RunPropertyChange[] | undefined {\n if (!rPr) return undefined;\n\n const changes = findChildren(rPr, 'w', 'rPrChange')\n .map((changeElement): RunPropertyChange => {\n const previousRPr = findChild(changeElement, 'w', 'rPr');\n return {\n type: 'runPropertyChange',\n info: parsePropertyChangeInfo(changeElement),\n previousFormatting: parseRunProperties(previousRPr, theme, styles ?? undefined),\n currentFormatting,\n };\n })\n .filter((change) => change.previousFormatting || change.currentFormatting);\n\n return changes.length > 0 ? changes : undefined;\n}\n\n/**\n * Parse text content (w:t)\n */\nfunction parseTextContent(element: XmlElement): TextContent {\n const text = getTextContent(element);\n const preserveSpace = getAttribute(element, 'xml', 'space') === 'preserve';\n\n return {\n type: 'text',\n text,\n preserveSpace: preserveSpace || undefined,\n };\n}\n\n/**\n * Parse tab element (w:tab)\n */\nfunction parseTabContent(): TabContent {\n return { type: 'tab' };\n}\n\n/**\n * Parse break element (w:br)\n */\nfunction parseBreakContent(element: XmlElement): BreakContent {\n const breakType = getAttribute(element, 'w', 'type');\n const clear = getAttribute(element, 'w', 'clear');\n\n const content: BreakContent = { type: 'break' };\n\n if (breakType === 'page' || breakType === 'column' || breakType === 'textWrapping') {\n content.breakType = breakType;\n }\n\n if (clear === 'none' || clear === 'left' || clear === 'right' || clear === 'all') {\n content.clear = clear;\n }\n\n return content;\n}\n\n/**\n * Parse symbol element (w:sym)\n */\nfunction parseSymbolContent(element: XmlElement): SymbolContent {\n const font = getAttribute(element, 'w', 'font') ?? '';\n const char = getAttribute(element, 'w', 'char') ?? '';\n\n return {\n type: 'symbol',\n font,\n char,\n };\n}\n\n/**\n * Parse footnote reference (w:footnoteReference)\n */\nfunction parseFootnoteReference(element: XmlElement): NoteReferenceContent {\n const id = parseNumericAttribute(element, 'w', 'id') ?? 0;\n\n return {\n type: 'footnoteRef',\n id,\n };\n}\n\n/**\n * Parse endnote reference (w:endnoteReference)\n */\nfunction parseEndnoteReference(element: XmlElement): NoteReferenceContent {\n const id = parseNumericAttribute(element, 'w', 'id') ?? 0;\n\n return {\n type: 'endnoteRef',\n id,\n };\n}\n\n/**\n * Parse field character (w:fldChar)\n */\nfunction parseFieldChar(element: XmlElement): FieldCharContent {\n const fldCharType = getAttribute(element, 'w', 'fldCharType');\n const fldLock =\n getAttribute(element, 'w', 'fldLock') === 'true' ||\n getAttribute(element, 'w', 'fldLock') === '1';\n const dirty =\n getAttribute(element, 'w', 'dirty') === 'true' || getAttribute(element, 'w', 'dirty') === '1';\n\n let charType: FieldCharContent['charType'] = 'begin';\n if (fldCharType === 'separate') charType = 'separate';\n else if (fldCharType === 'end') charType = 'end';\n\n return {\n type: 'fieldChar',\n charType,\n fldLock: fldLock || undefined,\n dirty: dirty || undefined,\n };\n}\n\n/**\n * Parse instruction text (w:instrText)\n */\nfunction parseInstrText(element: XmlElement): InstrTextContent {\n const text = getTextContent(element);\n\n return {\n type: 'instrText',\n text,\n };\n}\n\n/**\n * Parse drawing content (w:drawing)\n *\n * Uses imageParser to fully parse the drawing element including\n * image data resolution from relationships and media files.\n */\nfunction parseDrawingContent(\n element: XmlElement,\n rels: RelationshipMap | null,\n media: Map<string, MediaFile> | null\n): DrawingContent | null {\n // Use the full imageParser to parse the drawing\n const image = parseImage(element, rels ?? undefined, media ?? undefined);\n\n if (!image) {\n return null;\n }\n\n return {\n type: 'drawing',\n image,\n };\n}\n\n/**\n * Get the local name of an element (without namespace prefix)\n */\nfunction getLocalName(name: string | undefined): string {\n if (!name) return '';\n const colonIndex = name.indexOf(':');\n return colonIndex >= 0 ? name.substring(colonIndex + 1) : name;\n}\n\n/**\n * Parse all content within a run element\n */\nfunction parseRunContents(\n runElement: XmlElement,\n rels: RelationshipMap | null,\n media: Map<string, MediaFile> | null\n): RunContent[] {\n const contents: RunContent[] = [];\n const children = getChildElements(runElement);\n\n for (const child of children) {\n const localName = getLocalName(child.name);\n\n switch (localName) {\n case 't':\n // Text content\n contents.push(parseTextContent(child));\n break;\n\n case 'tab':\n // Tab character\n contents.push(parseTabContent());\n break;\n\n case 'br':\n // Line/page/column break\n contents.push(parseBreakContent(child));\n break;\n\n case 'sym':\n // Symbol character\n contents.push(parseSymbolContent(child));\n break;\n\n case 'footnoteReference':\n // Footnote reference\n contents.push(parseFootnoteReference(child));\n break;\n\n case 'endnoteReference':\n // Endnote reference\n contents.push(parseEndnoteReference(child));\n break;\n\n case 'fldChar':\n // Field character (begin/separate/end)\n contents.push(parseFieldChar(child));\n break;\n\n case 'instrText':\n // Field instruction text\n contents.push(parseInstrText(child));\n break;\n\n case 'softHyphen':\n // Soft hyphen\n contents.push({ type: 'softHyphen' } as SoftHyphenContent);\n break;\n\n case 'noBreakHyphen':\n // Non-breaking hyphen\n contents.push({ type: 'noBreakHyphen' } as NoBreakHyphenContent);\n break;\n\n case 'drawing':\n // Drawing/image\n const drawing = parseDrawingContent(child, rels, media);\n if (drawing) {\n contents.push(drawing);\n }\n break;\n\n case 'pict':\n case 'object':\n // Legacy VML pictures/objects - will handle in shape parser\n // For now, skip these\n break;\n\n case 'rPr':\n // Run properties - already handled separately\n break;\n\n case 'lastRenderedPageBreak':\n // Marker for last rendered page break - informational only\n break;\n\n case 'cr':\n // Carriage return - treat as line break\n contents.push({ type: 'break', breakType: 'textWrapping' } as BreakContent);\n break;\n\n case 'footnoteRef':\n case 'endnoteRef':\n // These are the actual footnote/endnote content markers (different from Reference)\n // They appear in the footnote/endnote text itself\n break;\n\n case 'separator':\n case 'continuationSeparator':\n // Footnote/endnote separators\n break;\n\n default:\n // Unknown element - log for debugging if needed\n // console.log(`Unknown run content element: ${localName}`);\n break;\n }\n }\n\n return contents;\n}\n\n/**\n * Parse a run element (w:r)\n *\n * @param node - The w:r XML element\n * @param styles - Style map for resolving style references\n * @param theme - Theme for resolving theme colors/fonts\n * @param rels - Relationship map for resolving image references\n * @param media - Media files map for image data\n * @returns Parsed Run object\n */\nexport function parseRun(\n node: XmlElement,\n styles: StyleMap | null,\n theme: Theme | null,\n rels: RelationshipMap | null = null,\n media: Map<string, MediaFile> | null = null\n): Run {\n const run: Run = {\n type: 'run',\n content: [],\n };\n\n // Parse run properties (w:rPr)\n const rPr = findChild(node, 'w', 'rPr');\n if (rPr) {\n run.formatting = parseRunProperties(rPr, theme, styles ?? undefined);\n run.propertyChanges = parseRunPropertyChanges(rPr, theme, styles, run.formatting);\n }\n\n // Parse run contents (text, tabs, breaks, images, etc.)\n run.content = parseRunContents(node, rels, media);\n\n return run;\n}\n\n/**\n * Get plain text from a run\n *\n * @param run - Parsed Run object\n * @returns Concatenated text content\n */\nexport function getRunText(run: Run): string {\n let text = '';\n\n for (const content of run.content) {\n if (content.type === 'text') {\n text += content.text;\n } else if (content.type === 'tab') {\n text += '\\t';\n } else if (content.type === 'break') {\n if (content.breakType === 'page') {\n text += '\\f'; // Form feed for page break\n } else {\n text += '\\n';\n }\n } else if (content.type === 'softHyphen') {\n text += '\\u00AD'; // Soft hyphen Unicode\n } else if (content.type === 'noBreakHyphen') {\n text += '\\u2011'; // Non-breaking hyphen Unicode\n }\n }\n\n return text;\n}\n\n/**\n * Check if a run contains any actual content\n *\n * @param run - Parsed Run object\n * @returns true if run has visible content\n */\nexport function hasContent(run: Run): boolean {\n return run.content.length > 0;\n}\n\n/**\n * Check if a run contains a drawing/image\n *\n * @param run - Parsed Run object\n * @returns true if run contains an image\n */\nexport function hasImage(run: Run): boolean {\n return run.content.some((c) => c.type === 'drawing');\n}\n\n/**\n * Get all images from a run\n *\n * @param run - Parsed Run object\n * @returns Array of Image objects\n */\nexport function getImages(run: Run): Image[] {\n return run.content.filter((c): c is DrawingContent => c.type === 'drawing').map((c) => c.image);\n}\n\n/**\n * Check if a run is part of a complex field\n *\n * @param run - Parsed Run object\n * @returns true if run contains field characters\n */\nexport function hasFieldChar(run: Run): boolean {\n return run.content.some((c) => c.type === 'fieldChar');\n}\n\n/**\n * Get field character type if present\n *\n * @param run - Parsed Run object\n * @returns Field character type or null\n */\nexport function getFieldCharType(run: Run): 'begin' | 'separate' | 'end' | null {\n const fieldChar = run.content.find((c): c is FieldCharContent => c.type === 'fieldChar');\n return fieldChar?.charType ?? null;\n}\n","/**\n * Hyperlink Parser - Parse hyperlinks (w:hyperlink) with URL resolution\n *\n * OOXML Reference:\n * - Hyperlink element: w:hyperlink\n * - Attributes:\n * - r:id - Relationship ID for external link (resolves via .rels)\n * - w:anchor - Internal bookmark name\n * - w:tooltip - Tooltip/title text\n * - w:tgtFrame - Target frame (_blank, _self, etc.)\n * - w:history - Whether to add to history\n * - w:docLocation - Location within a document\n *\n * External links use r:id to reference a relationship in document.xml.rels\n * Internal links use w:anchor to reference a bookmark in the same document\n */\n\nimport type {\n Hyperlink,\n Run,\n BookmarkStart,\n BookmarkEnd,\n Theme,\n RelationshipMap,\n MediaFile,\n} from '../types/document';\nimport type { StyleMap } from './styleParser';\nimport {\n getAttribute,\n getChildElements,\n parseNumericAttribute,\n type XmlElement,\n} from './xmlParser';\nimport { parseRun } from './runParser';\nimport { isExternalHyperlink } from './relsParser';\n\n// ============================================================================\n// HYPERLINK PARSER\n// ============================================================================\n\n/**\n * Get the local name of an element (without namespace prefix)\n */\nfunction getLocalName(name: string | undefined): string {\n if (!name) return '';\n const colonIndex = name.indexOf(':');\n return colonIndex >= 0 ? name.substring(colonIndex + 1) : name;\n}\n\n/**\n * Parse bookmark start (w:bookmarkStart)\n *\n * Used for internal hyperlink targets within the document.\n */\nfunction parseBookmarkStart(node: XmlElement): BookmarkStart {\n const id = parseNumericAttribute(node, 'w', 'id') ?? 0;\n const name = getAttribute(node, 'w', 'name') ?? '';\n\n const bookmark: BookmarkStart = {\n type: 'bookmarkStart',\n id,\n name,\n };\n\n // Table column bookmarks\n const colFirst = parseNumericAttribute(node, 'w', 'colFirst');\n if (colFirst !== undefined) bookmark.colFirst = colFirst;\n\n const colLast = parseNumericAttribute(node, 'w', 'colLast');\n if (colLast !== undefined) bookmark.colLast = colLast;\n\n return bookmark;\n}\n\n/**\n * Parse bookmark end (w:bookmarkEnd)\n */\nfunction parseBookmarkEnd(node: XmlElement): BookmarkEnd {\n const id = parseNumericAttribute(node, 'w', 'id') ?? 0;\n\n return {\n type: 'bookmarkEnd',\n id,\n };\n}\n\n/**\n * Parse a hyperlink element (w:hyperlink)\n *\n * Handles both external links (via r:id relationship) and internal\n * links (via w:anchor bookmark reference).\n *\n * @param node - The w:hyperlink XML element\n * @param rels - Relationship map to resolve r:id references\n * @param styles - Style map for resolving run styles\n * @param theme - Theme for resolving colors/fonts\n * @param media - Media files map for image data\n * @returns Parsed Hyperlink object\n */\nexport function parseHyperlink(\n node: XmlElement,\n rels: RelationshipMap | null,\n styles: StyleMap | null = null,\n theme: Theme | null = null,\n media: Map<string, MediaFile> | null = null\n): Hyperlink {\n const hyperlink: Hyperlink = {\n type: 'hyperlink',\n children: [],\n };\n\n // === External Link (r:id) ===\n // Get relationship ID for external links\n const rId = getAttribute(node, 'r', 'id');\n if (rId) {\n hyperlink.rId = rId;\n\n // Resolve the relationship to get the actual URL\n if (rels) {\n const rel = rels.get(rId);\n if (rel) {\n // External hyperlinks have TargetMode=\"External\" and target is the URL\n if (isExternalHyperlink(rel)) {\n hyperlink.href = rel.target;\n } else {\n // Internal document link (to another part of the DOCX)\n hyperlink.href = rel.target;\n }\n }\n }\n }\n\n // === Internal Bookmark Link (w:anchor) ===\n // Get internal bookmark anchor\n const anchor = getAttribute(node, 'w', 'anchor');\n if (anchor) {\n hyperlink.anchor = anchor;\n // For internal links, create a fragment-style href\n if (!hyperlink.href) {\n hyperlink.href = `#${anchor}`;\n }\n }\n\n // === Tooltip ===\n const tooltip = getAttribute(node, 'w', 'tooltip');\n if (tooltip) {\n hyperlink.tooltip = tooltip;\n }\n\n // === Target Frame ===\n // Common values: _blank (new window), _self (same), _parent, _top\n const tgtFrame = getAttribute(node, 'w', 'tgtFrame');\n if (tgtFrame) {\n hyperlink.target = tgtFrame;\n }\n\n // === History ===\n // Whether to add to browser history\n const history = getAttribute(node, 'w', 'history');\n if (history === '1' || history === 'true') {\n hyperlink.history = true;\n }\n\n // === Document Location ===\n // Location within a linked document (like fragment for external doc)\n const docLocation = getAttribute(node, 'w', 'docLocation');\n if (docLocation) {\n hyperlink.docLocation = docLocation;\n }\n\n // === Parse Children ===\n // Hyperlinks contain runs for the display text, and possibly bookmarks\n const children = getChildElements(node);\n for (const child of children) {\n const localName = getLocalName(child.name);\n\n switch (localName) {\n case 'r':\n hyperlink.children.push(parseRun(child, styles, theme, rels, media));\n break;\n\n case 'bookmarkStart':\n hyperlink.children.push(parseBookmarkStart(child));\n break;\n\n case 'bookmarkEnd':\n hyperlink.children.push(parseBookmarkEnd(child));\n break;\n\n // Note: hyperlinks can technically contain other elements like\n // fldSimple, but these are rare. Add support as needed.\n }\n }\n\n return hyperlink;\n}\n\n// ============================================================================\n// UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Get the display text of a hyperlink\n *\n * Concatenates text from all child runs.\n *\n * @param hyperlink - Parsed Hyperlink object\n * @returns Display text string\n */\nexport function getHyperlinkText(hyperlink: Hyperlink): string {\n let text = '';\n\n for (const child of hyperlink.children) {\n if (child.type === 'run') {\n for (const content of child.content) {\n if (content.type === 'text') {\n text += content.text;\n } else if (content.type === 'tab') {\n text += '\\t';\n }\n }\n }\n }\n\n return text;\n}\n\n/**\n * Check if a hyperlink is an external link\n *\n * @param hyperlink - Parsed Hyperlink object\n * @returns true if this links to an external URL\n */\nexport function isExternalLink(hyperlink: Hyperlink): boolean {\n // Has rId and resolved href that starts with a protocol\n if (hyperlink.href) {\n return /^https?:\\/\\/|^mailto:|^tel:|^ftp:/i.test(hyperlink.href);\n }\n // Has rId but not resolved (still counts as external attempt)\n return !!hyperlink.rId && !hyperlink.anchor;\n}\n\n/**\n * Check if a hyperlink is an internal bookmark link\n *\n * @param hyperlink - Parsed Hyperlink object\n * @returns true if this links to an internal bookmark\n */\nexport function isInternalLink(hyperlink: Hyperlink): boolean {\n return !!hyperlink.anchor;\n}\n\n/**\n * Get the resolved URL of a hyperlink\n *\n * For external links, returns the full URL.\n * For internal links, returns the anchor prefixed with #.\n * Returns undefined if the link couldn't be resolved.\n *\n * @param hyperlink - Parsed Hyperlink object\n * @returns Resolved URL or undefined\n */\nexport function getHyperlinkUrl(hyperlink: Hyperlink): string | undefined {\n return hyperlink.href;\n}\n\n/**\n * Check if a hyperlink has any content (runs)\n *\n * @param hyperlink - Parsed Hyperlink object\n * @returns true if hyperlink has child runs\n */\nexport function hasContent(hyperlink: Hyperlink): boolean {\n return hyperlink.children.some((child) => child.type === 'run');\n}\n\n/**\n * Get all runs from a hyperlink\n *\n * @param hyperlink - Parsed Hyperlink object\n * @returns Array of Run objects\n */\nexport function getHyperlinkRuns(hyperlink: Hyperlink): Run[] {\n return hyperlink.children.filter((child): child is Run => child.type === 'run');\n}\n\n/**\n * Resolve a hyperlink's rId to a URL using a relationship map\n *\n * This is useful when you have a hyperlink that was parsed without\n * relationship context and need to resolve it later.\n *\n * @param hyperlink - Parsed Hyperlink object (will be modified)\n * @param rels - Relationship map to resolve against\n * @returns The resolved URL or undefined\n */\nexport function resolveHyperlinkUrl(\n hyperlink: Hyperlink,\n rels: RelationshipMap\n): string | undefined {\n if (hyperlink.rId) {\n const rel = rels.get(hyperlink.rId);\n if (rel) {\n if (isExternalHyperlink(rel)) {\n hyperlink.href = rel.target;\n } else {\n hyperlink.href = rel.target;\n }\n return hyperlink.href;\n }\n }\n\n // If there's an anchor but no href yet, set it\n if (hyperlink.anchor && !hyperlink.href) {\n hyperlink.href = `#${hyperlink.anchor}`;\n return hyperlink.href;\n }\n\n return hyperlink.href;\n}\n\n/**\n * Create an internal hyperlink to a bookmark\n *\n * Utility function for creating hyperlinks programmatically.\n *\n * @param anchor - Bookmark name to link to\n * @param children - Child runs for display text\n * @param options - Optional properties (tooltip, etc.)\n * @returns New Hyperlink object\n */\nexport function createInternalHyperlink(\n anchor: string,\n children: Run[],\n options?: {\n tooltip?: string;\n }\n): Hyperlink {\n return {\n type: 'hyperlink',\n anchor,\n href: `#${anchor}`,\n tooltip: options?.tooltip,\n children,\n };\n}\n\n/**\n * Create an external hyperlink\n *\n * Utility function for creating hyperlinks programmatically.\n * Note: The rId would need to be assigned when serializing.\n *\n * @param url - External URL\n * @param children - Child runs for display text\n * @param options - Optional properties (tooltip, target, etc.)\n * @returns New Hyperlink object\n */\nexport function createExternalHyperlink(\n url: string,\n children: Run[],\n options?: {\n tooltip?: string;\n target?: string;\n }\n): Hyperlink {\n return {\n type: 'hyperlink',\n href: url,\n tooltip: options?.tooltip,\n target: options?.target,\n children,\n };\n}\n","/**\n * Bookmark Parser - Parse bookmark markers (w:bookmarkStart, w:bookmarkEnd)\n *\n * Bookmarks are named locations in a document that can be targeted by internal\n * hyperlinks. They consist of a start and end marker with matching IDs.\n *\n * OOXML Reference:\n * - Bookmark start: w:bookmarkStart (id, name, colFirst?, colLast?)\n * - Bookmark end: w:bookmarkEnd (id)\n * - Internal hyperlinks reference bookmarks by name via w:anchor attribute\n *\n * Bookmark Structure:\n * - Each bookmark has a unique numeric ID within the document\n * - The name is used for hyperlink references\n * - Start and end markers can span multiple paragraphs or be point bookmarks\n * - Table column bookmarks have colFirst/colLast for column ranges\n */\n\nimport type { BookmarkStart, BookmarkEnd } from '../types/document';\nimport { getAttribute, parseNumericAttribute, type XmlElement } from './xmlParser';\n\n// ============================================================================\n// BOOKMARK PARSING\n// ============================================================================\n\n/**\n * Parse a bookmark start element (w:bookmarkStart)\n *\n * Extracts:\n * - id: Numeric identifier (required, matches with bookmarkEnd)\n * - name: Bookmark name (required, used by hyperlinks)\n * - colFirst: First column for table bookmarks (optional)\n * - colLast: Last column for table bookmarks (optional)\n *\n * @param node - The w:bookmarkStart XML element\n * @returns Parsed BookmarkStart object\n */\nexport function parseBookmarkStart(node: XmlElement): BookmarkStart {\n const id = parseNumericAttribute(node, 'w', 'id') ?? 0;\n const name = getAttribute(node, 'w', 'name') ?? '';\n\n const bookmark: BookmarkStart = {\n type: 'bookmarkStart',\n id,\n name,\n };\n\n // Table column bookmarks (for bookmarks spanning table columns)\n const colFirst = parseNumericAttribute(node, 'w', 'colFirst');\n if (colFirst !== undefined) {\n bookmark.colFirst = colFirst;\n }\n\n const colLast = parseNumericAttribute(node, 'w', 'colLast');\n if (colLast !== undefined) {\n bookmark.colLast = colLast;\n }\n\n return bookmark;\n}\n\n/**\n * Parse a bookmark end element (w:bookmarkEnd)\n *\n * Bookmark ends only contain an ID that matches the corresponding start marker.\n *\n * @param node - The w:bookmarkEnd XML element\n * @returns Parsed BookmarkEnd object\n */\nexport function parseBookmarkEnd(node: XmlElement): BookmarkEnd {\n const id = parseNumericAttribute(node, 'w', 'id') ?? 0;\n\n return {\n type: 'bookmarkEnd',\n id,\n };\n}\n\n// ============================================================================\n// BOOKMARK COLLECTION & UTILITIES\n// ============================================================================\n\n/**\n * Bookmark map for quick lookup by ID or name\n */\nexport interface BookmarkMap {\n /** Lookup bookmark start by ID */\n byId: Map<number, BookmarkStart>;\n /** Lookup bookmark start by name (for hyperlink resolution) */\n byName: Map<string, BookmarkStart>;\n /** All bookmark starts in document order */\n bookmarks: BookmarkStart[];\n}\n\n/**\n * Create an empty bookmark map\n */\nexport function createBookmarkMap(): BookmarkMap {\n return {\n byId: new Map(),\n byName: new Map(),\n bookmarks: [],\n };\n}\n\n/**\n * Add a bookmark to the map\n *\n * @param map - The bookmark map to update\n * @param bookmark - The bookmark start to add\n */\nexport function addBookmark(map: BookmarkMap, bookmark: BookmarkStart): void {\n map.byId.set(bookmark.id, bookmark);\n if (bookmark.name) {\n map.byName.set(bookmark.name, bookmark);\n }\n map.bookmarks.push(bookmark);\n}\n\n/**\n * Get a bookmark by name (for resolving internal hyperlinks)\n *\n * @param map - The bookmark map to search\n * @param name - Bookmark name to find\n * @returns The BookmarkStart or undefined if not found\n */\nexport function getBookmarkByName(map: BookmarkMap, name: string): BookmarkStart | undefined {\n return map.byName.get(name);\n}\n\n/**\n * Get a bookmark by ID (for matching start/end pairs)\n *\n * @param map - The bookmark map to search\n * @param id - Bookmark ID to find\n * @returns The BookmarkStart or undefined if not found\n */\nexport function getBookmarkById(map: BookmarkMap, id: number): BookmarkStart | undefined {\n return map.byId.get(id);\n}\n\n/**\n * Check if a bookmark exists by name\n *\n * @param map - The bookmark map to search\n * @param name - Bookmark name to check\n * @returns true if bookmark exists\n */\nexport function hasBookmark(map: BookmarkMap, name: string): boolean {\n return map.byName.has(name);\n}\n\n/**\n * Get all bookmark names in the document\n *\n * @param map - The bookmark map\n * @returns Array of bookmark names\n */\nexport function getAllBookmarkNames(map: BookmarkMap): string[] {\n return Array.from(map.byName.keys());\n}\n\n/**\n * Check if a bookmark is a point bookmark (start and end at same location)\n *\n * Point bookmarks have no content between start and end markers.\n * This is commonly used for insertion points.\n *\n * @param start - The bookmark start\n * @param end - The bookmark end\n * @param contents - Content between them\n * @returns true if this is a point bookmark\n */\nexport function isPointBookmark(\n start: BookmarkStart,\n end: BookmarkEnd,\n contents: unknown[]\n): boolean {\n return start.id === end.id && contents.length === 0;\n}\n\n/**\n * Check if a bookmark is a table column bookmark\n *\n * Table bookmarks have colFirst and colLast attributes indicating\n * they span specific table columns.\n *\n * @param bookmark - The bookmark to check\n * @returns true if bookmark has column range info\n */\nexport function isTableBookmark(bookmark: BookmarkStart): boolean {\n return bookmark.colFirst !== undefined || bookmark.colLast !== undefined;\n}\n\n/**\n * Generate an internal hyperlink href from a bookmark name\n *\n * Internal hyperlinks use #anchor format.\n *\n * @param bookmarkName - The bookmark name to link to\n * @returns Href string (e.g., \"#BookmarkName\")\n */\nexport function bookmarkToHref(bookmarkName: string): string {\n return `#${bookmarkName}`;\n}\n\n/**\n * Extract bookmark name from an internal hyperlink href\n *\n * @param href - The href string\n * @returns Bookmark name or null if not an internal link\n */\nexport function hrefToBookmarkName(href: string): string | null {\n if (href.startsWith('#')) {\n return href.substring(1);\n }\n return null;\n}\n\n// ============================================================================\n// SPECIAL BOOKMARK TYPES\n// ============================================================================\n\n/**\n * Check if a bookmark is a built-in Word bookmark\n *\n * Word uses certain reserved bookmark names for special purposes:\n * - _GoBack: Last editing position\n * - _Toc*: Table of contents entries\n * - _Ref*: Cross-reference anchors\n * - _Hlt*: Highlight ranges\n *\n * @param name - Bookmark name to check\n * @returns true if this is a built-in bookmark\n */\nexport function isBuiltInBookmark(name: string): boolean {\n if (!name) return false;\n\n // Check for underscore prefix (Word internal bookmarks)\n if (name.startsWith('_')) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Check if a bookmark is a TOC entry bookmark\n *\n * @param name - Bookmark name to check\n * @returns true if bookmark is for TOC\n */\nexport function isTocBookmark(name: string): boolean {\n return name.startsWith('_Toc');\n}\n\n/**\n * Check if a bookmark is a cross-reference anchor\n *\n * @param name - Bookmark name to check\n * @returns true if bookmark is for cross-reference\n */\nexport function isRefBookmark(name: string): boolean {\n return name.startsWith('_Ref');\n}\n\n/**\n * Get bookmark type category\n *\n * @param name - Bookmark name\n * @returns Bookmark type\n */\nexport function getBookmarkType(name: string): 'user' | 'toc' | 'ref' | 'goBack' | 'internal' {\n if (name === '_GoBack') {\n return 'goBack';\n }\n if (isTocBookmark(name)) {\n return 'toc';\n }\n if (isRefBookmark(name)) {\n return 'ref';\n }\n if (isBuiltInBookmark(name)) {\n return 'internal';\n }\n return 'user';\n}\n\n// ============================================================================\n// BOOKMARK VALIDATION\n// ============================================================================\n\n/**\n * Validate that all bookmark starts have matching ends\n *\n * @param starts - Array of bookmark starts\n * @param ends - Array of bookmark ends\n * @returns Object with validation results\n */\nexport function validateBookmarkPairs(\n starts: BookmarkStart[],\n ends: BookmarkEnd[]\n): {\n valid: boolean;\n unmatchedStarts: BookmarkStart[];\n unmatchedEnds: BookmarkEnd[];\n} {\n const startIds = new Set(starts.map((s) => s.id));\n const endIds = new Set(ends.map((e) => e.id));\n\n const unmatchedStarts = starts.filter((s) => !endIds.has(s.id));\n const unmatchedEnds = ends.filter((e) => !startIds.has(e.id));\n\n return {\n valid: unmatchedStarts.length === 0 && unmatchedEnds.length === 0,\n unmatchedStarts,\n unmatchedEnds,\n };\n}\n\n/**\n * Validate a bookmark name (for creating new bookmarks)\n *\n * Valid bookmark names:\n * - Cannot be empty\n * - Must start with a letter or underscore\n * - Can contain letters, digits, and underscores\n * - Cannot exceed 40 characters\n *\n * @param name - Name to validate\n * @returns Object with validation result and error message if invalid\n */\nexport function validateBookmarkName(name: string): { valid: boolean; error?: string } {\n if (!name) {\n return { valid: false, error: 'Bookmark name cannot be empty' };\n }\n\n if (name.length > 40) {\n return { valid: false, error: 'Bookmark name cannot exceed 40 characters' };\n }\n\n // Check first character (letter or underscore)\n if (!/^[a-zA-Z_]/.test(name)) {\n return {\n valid: false,\n error: 'Bookmark name must start with a letter or underscore',\n };\n }\n\n // Check remaining characters (letters, digits, underscores)\n if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {\n return {\n valid: false,\n error: 'Bookmark name can only contain letters, digits, and underscores',\n };\n }\n\n return { valid: true };\n}\n","/**\n * Table Parser - Parse tables with full OOXML structure\n *\n * OOXML tables consist of:\n * - w:tbl - Table element\n * - w:tblPr - Table properties (width, borders, style)\n * - w:tblGrid - Column width definitions\n * - w:tr - Table rows\n * - w:trPr - Row properties (height, header)\n * - w:tc - Table cells\n * - w:tcPr - Cell properties (width, borders, merge)\n *\n * Cell merging:\n * - Horizontal: w:gridSpan (how many grid columns this cell spans)\n * - Vertical: w:vMerge (restart = start of merge, continue = continuation)\n *\n * OOXML Reference:\n * - w:tbl contains w:tblPr, w:tblGrid, and w:tr elements\n * - w:tr contains w:trPr and w:tc elements\n * - w:tc contains w:tcPr and content (paragraphs, tables)\n */\n\nimport type {\n Table,\n TableRow,\n TableCell,\n TableFormatting,\n TableRowFormatting,\n TableCellFormatting,\n TablePropertyChange,\n TableRowPropertyChange,\n TableCellPropertyChange,\n TableStructuralChangeInfo,\n TableMeasurement,\n TableWidthType,\n TableBorders,\n TableLook,\n CellMargins,\n FloatingTableProperties,\n ConditionalFormatStyle,\n Paragraph,\n Theme,\n BorderSpec,\n ShadingProperties,\n ColorValue,\n RelationshipMap,\n MediaFile,\n} from '../types/document';\nimport type { StyleMap } from './styleParser';\nimport type { NumberingMap } from './numberingParser';\nimport { parseParagraph } from './paragraphParser';\nimport {\n findChild,\n findChildren,\n getAttribute,\n parseNumericAttribute,\n parseBooleanElement,\n type XmlElement,\n} from './xmlParser';\n\n// ============================================================================\n// TABLE MEASUREMENT PARSING\n// ============================================================================\n\n/**\n * Parse a table measurement (width, height, etc.)\n *\n * @param element - Element with w:w and w:type attributes\n * @returns Parsed measurement or undefined\n */\nexport function parseTableMeasurement(element: XmlElement | null): TableMeasurement | undefined {\n if (!element) return undefined;\n\n const value = parseNumericAttribute(element, 'w', 'w') ?? 0;\n const typeStr = getAttribute(element, 'w', 'type') ?? 'dxa';\n\n let type: TableWidthType = 'dxa';\n if (typeStr === 'auto' || typeStr === 'dxa' || typeStr === 'nil' || typeStr === 'pct') {\n type = typeStr;\n }\n\n return { value, type };\n}\n\n/**\n * Parse width from an element (shorthand for common case)\n */\nfunction parseWidth(element: XmlElement | null): TableMeasurement | undefined {\n return parseTableMeasurement(element);\n}\n\nfunction parseTrackedChangeInfo(node: XmlElement): TableStructuralChangeInfo['info'] {\n const rawId = getAttribute(node, 'w', 'id');\n const parsedId = rawId ? parseInt(rawId, 10) : 0;\n const author = (getAttribute(node, 'w', 'author') ?? '').trim();\n const date = (getAttribute(node, 'w', 'date') ?? '').trim();\n\n return {\n id: Number.isInteger(parsedId) && parsedId >= 0 ? parsedId : 0,\n author: author.length > 0 ? author : 'Unknown',\n date: date.length > 0 ? date : undefined,\n };\n}\n\nfunction parsePropertyChangeInfo(\n node: XmlElement\n): TablePropertyChange['info'] | TableRowPropertyChange['info'] | TableCellPropertyChange['info'] {\n const base = parseTrackedChangeInfo(node);\n const rsid = (getAttribute(node, 'w', 'rsid') ?? '').trim();\n return rsid.length > 0 ? { ...base, rsid } : base;\n}\n\n// ============================================================================\n// BORDER PARSING\n// ============================================================================\n\n/**\n * Parse a single border specification\n *\n * @param element - Border element (w:top, w:bottom, etc.)\n * @returns Parsed border or undefined\n */\nexport function parseBorderSpec(element: XmlElement | null): BorderSpec | undefined {\n if (!element) return undefined;\n\n const styleStr = getAttribute(element, 'w', 'val') ?? 'none';\n const style = styleStr as BorderSpec['style'];\n\n const border: BorderSpec = { style };\n\n // Size in eighths of a point\n const sz = parseNumericAttribute(element, 'w', 'sz');\n if (sz !== undefined) {\n border.size = sz;\n }\n\n // Space from text in points\n const space = parseNumericAttribute(element, 'w', 'space');\n if (space !== undefined) {\n border.space = space;\n }\n\n // Color (border uses w:color, not w:val)\n const color = getAttribute(element, 'w', 'color');\n const themeColor = getAttribute(element, 'w', 'themeColor');\n const themeTint = getAttribute(element, 'w', 'themeTint');\n const themeShade = getAttribute(element, 'w', 'themeShade');\n if (color || themeColor || themeTint || themeShade) {\n border.color = {\n rgb: color ?? undefined,\n themeColor: themeColor as ColorValue['themeColor'],\n themeTint: themeTint ?? undefined,\n themeShade: themeShade ?? undefined,\n };\n }\n\n // Shadow effect\n const shadow = getAttribute(element, 'w', 'shadow');\n if (shadow === '1' || shadow === 'true') {\n border.shadow = true;\n }\n\n // Frame effect\n const frame = getAttribute(element, 'w', 'frame');\n if (frame === '1' || frame === 'true') {\n border.frame = true;\n }\n\n return border;\n}\n\n/**\n * Parse table borders (w:tblBorders or w:tcBorders)\n *\n * @param bordersElement - The borders container element\n * @returns Parsed borders or undefined\n */\nexport function parseTableBorders(bordersElement: XmlElement | null): TableBorders | undefined {\n if (!bordersElement) return undefined;\n\n const borders: TableBorders = {};\n\n const top = parseBorderSpec(findChild(bordersElement, 'w', 'top'));\n if (top) borders.top = top;\n\n const bottom = parseBorderSpec(findChild(bordersElement, 'w', 'bottom'));\n if (bottom) borders.bottom = bottom;\n\n const left = parseBorderSpec(\n findChild(bordersElement, 'w', 'left') ?? findChild(bordersElement, 'w', 'start')\n );\n if (left) borders.left = left;\n\n const right = parseBorderSpec(\n findChild(bordersElement, 'w', 'right') ?? findChild(bordersElement, 'w', 'end')\n );\n if (right) borders.right = right;\n\n const insideH = parseBorderSpec(findChild(bordersElement, 'w', 'insideH'));\n if (insideH) borders.insideH = insideH;\n\n const insideV = parseBorderSpec(findChild(bordersElement, 'w', 'insideV'));\n if (insideV) borders.insideV = insideV;\n\n // Return undefined if no borders were parsed\n if (Object.keys(borders).length === 0) return undefined;\n\n return borders;\n}\n\n// ============================================================================\n// CELL MARGINS PARSING\n// ============================================================================\n\n/**\n * Parse cell margins (w:tblCellMar or w:tcMar)\n *\n * @param marginsElement - The margins container element\n * @returns Parsed margins or undefined\n */\nexport function parseCellMargins(marginsElement: XmlElement | null): CellMargins | undefined {\n if (!marginsElement) return undefined;\n\n const margins: CellMargins = {};\n\n const top = parseWidth(findChild(marginsElement, 'w', 'top'));\n if (top) margins.top = top;\n\n const bottom = parseWidth(findChild(marginsElement, 'w', 'bottom'));\n if (bottom) margins.bottom = bottom;\n\n const left = parseWidth(\n findChild(marginsElement, 'w', 'left') ?? findChild(marginsElement, 'w', 'start')\n );\n if (left) margins.left = left;\n\n const right = parseWidth(\n findChild(marginsElement, 'w', 'right') ?? findChild(marginsElement, 'w', 'end')\n );\n if (right) margins.right = right;\n\n if (Object.keys(margins).length === 0) return undefined;\n\n return margins;\n}\n\n// ============================================================================\n// SHADING PARSING\n// ============================================================================\n\n/**\n * Parse shading properties (w:shd)\n *\n * @param shdElement - The w:shd element\n * @returns Parsed shading or undefined\n */\nexport function parseShading(shdElement: XmlElement | null): ShadingProperties | undefined {\n if (!shdElement) return undefined;\n\n const shading: ShadingProperties = {};\n\n // Fill color (background)\n const fillStr = getAttribute(shdElement, 'w', 'fill');\n if (fillStr && fillStr !== 'auto') {\n shading.fill = { rgb: fillStr };\n }\n\n // Theme fill\n const themeFill = getAttribute(shdElement, 'w', 'themeFill');\n if (themeFill) {\n shading.fill = { themeColor: themeFill as any };\n\n const themeFillTint = getAttribute(shdElement, 'w', 'themeFillTint');\n if (themeFillTint && shading.fill) {\n shading.fill.themeTint = themeFillTint;\n }\n\n const themeFillShade = getAttribute(shdElement, 'w', 'themeFillShade');\n if (themeFillShade && shading.fill) {\n shading.fill.themeShade = themeFillShade;\n }\n }\n\n // Pattern color\n const colorStr = getAttribute(shdElement, 'w', 'color');\n if (colorStr && colorStr !== 'auto') {\n shading.color = { rgb: colorStr };\n }\n\n // Pattern value\n const pattern = getAttribute(shdElement, 'w', 'val');\n if (pattern) {\n shading.pattern = pattern as ShadingProperties['pattern'];\n }\n\n if (Object.keys(shading).length === 0) return undefined;\n\n return shading;\n}\n\n// ============================================================================\n// TABLE LOOK PARSING\n// ============================================================================\n\n/**\n * Parse table look flags (w:tblLook)\n *\n * @param lookElement - The w:tblLook element\n * @returns Parsed table look or undefined\n */\nexport function parseTableLook(lookElement: XmlElement | null): TableLook | undefined {\n if (!lookElement) return undefined;\n\n const look: TableLook = {};\n\n // Parse individual flags\n const firstRow = getAttribute(lookElement, 'w', 'firstRow');\n if (firstRow === '1' || firstRow === 'true') look.firstRow = true;\n\n const lastRow = getAttribute(lookElement, 'w', 'lastRow');\n if (lastRow === '1' || lastRow === 'true') look.lastRow = true;\n\n const firstColumn = getAttribute(lookElement, 'w', 'firstColumn');\n if (firstColumn === '1' || firstColumn === 'true') look.firstColumn = true;\n\n const lastColumn = getAttribute(lookElement, 'w', 'lastColumn');\n if (lastColumn === '1' || lastColumn === 'true') look.lastColumn = true;\n\n const noHBand = getAttribute(lookElement, 'w', 'noHBand');\n if (noHBand === '1' || noHBand === 'true') look.noHBand = true;\n\n const noVBand = getAttribute(lookElement, 'w', 'noVBand');\n if (noVBand === '1' || noVBand === 'true') look.noVBand = true;\n\n // Also check for the val attribute (hexadecimal flags)\n const val = getAttribute(lookElement, 'w', 'val');\n if (val) {\n const flags = parseInt(val, 16);\n if (!isNaN(flags)) {\n if (flags & 0x0020) look.firstRow = true;\n if (flags & 0x0040) look.lastRow = true;\n if (flags & 0x0080) look.firstColumn = true;\n if (flags & 0x0100) look.lastColumn = true;\n if (flags & 0x0200) look.noHBand = true;\n if (flags & 0x0400) look.noVBand = true;\n }\n }\n\n if (Object.keys(look).length === 0) return undefined;\n\n return look;\n}\n\n// ============================================================================\n// FLOATING TABLE PROPERTIES\n// ============================================================================\n\n/**\n * Parse floating table properties (w:tblpPr)\n *\n * @param tblpPrElement - The w:tblpPr element\n * @returns Parsed floating properties or undefined\n */\nexport function parseFloatingTableProperties(\n tblpPrElement: XmlElement | null\n): FloatingTableProperties | undefined {\n if (!tblpPrElement) return undefined;\n\n const floating: FloatingTableProperties = {};\n\n // Horizontal anchor\n const horzAnchor = getAttribute(tblpPrElement, 'w', 'horzAnchor');\n if (horzAnchor === 'margin' || horzAnchor === 'page' || horzAnchor === 'text') {\n floating.horzAnchor = horzAnchor;\n }\n\n // Vertical anchor\n const vertAnchor = getAttribute(tblpPrElement, 'w', 'vertAnchor');\n if (vertAnchor === 'margin' || vertAnchor === 'page' || vertAnchor === 'text') {\n floating.vertAnchor = vertAnchor;\n }\n\n // Horizontal position\n const tblpX = parseNumericAttribute(tblpPrElement, 'w', 'tblpX');\n if (tblpX !== undefined) floating.tblpX = tblpX;\n\n const tblpXSpec = getAttribute(tblpPrElement, 'w', 'tblpXSpec');\n if (tblpXSpec) {\n floating.tblpXSpec = tblpXSpec as FloatingTableProperties['tblpXSpec'];\n }\n\n // Vertical position\n const tblpY = parseNumericAttribute(tblpPrElement, 'w', 'tblpY');\n if (tblpY !== undefined) floating.tblpY = tblpY;\n\n const tblpYSpec = getAttribute(tblpPrElement, 'w', 'tblpYSpec');\n if (tblpYSpec) {\n floating.tblpYSpec = tblpYSpec as FloatingTableProperties['tblpYSpec'];\n }\n\n // Distance from text\n const topFromText = parseNumericAttribute(tblpPrElement, 'w', 'topFromText');\n if (topFromText !== undefined) floating.topFromText = topFromText;\n\n const bottomFromText = parseNumericAttribute(tblpPrElement, 'w', 'bottomFromText');\n if (bottomFromText !== undefined) floating.bottomFromText = bottomFromText;\n\n const leftFromText = parseNumericAttribute(tblpPrElement, 'w', 'leftFromText');\n if (leftFromText !== undefined) floating.leftFromText = leftFromText;\n\n const rightFromText = parseNumericAttribute(tblpPrElement, 'w', 'rightFromText');\n if (rightFromText !== undefined) floating.rightFromText = rightFromText;\n\n if (Object.keys(floating).length === 0) return undefined;\n\n return floating;\n}\n\n// ============================================================================\n// TABLE PROPERTIES PARSING (w:tblPr)\n// ============================================================================\n\n/**\n * Parse table properties (w:tblPr)\n *\n * @param tblPrElement - The w:tblPr element\n * @returns Parsed table formatting\n */\nexport function parseTableProperties(tblPrElement: XmlElement | null): TableFormatting | undefined {\n if (!tblPrElement) return undefined;\n\n const formatting: TableFormatting = {};\n\n // Table width (w:tblW)\n const width = parseWidth(findChild(tblPrElement, 'w', 'tblW'));\n if (width) formatting.width = width;\n\n // Table justification (w:jc)\n const jcElement = findChild(tblPrElement, 'w', 'jc');\n if (jcElement) {\n const jcVal = getAttribute(jcElement, 'w', 'val');\n if (jcVal === 'left' || jcVal === 'center' || jcVal === 'right' || jcVal === 'start') {\n formatting.justification = jcVal === 'start' ? 'left' : jcVal;\n }\n }\n\n // Cell spacing (w:tblCellSpacing)\n const cellSpacing = parseWidth(findChild(tblPrElement, 'w', 'tblCellSpacing'));\n if (cellSpacing) formatting.cellSpacing = cellSpacing;\n\n // Table indent (w:tblInd)\n const indent = parseWidth(findChild(tblPrElement, 'w', 'tblInd'));\n if (indent) formatting.indent = indent;\n\n // Table borders (w:tblBorders)\n const borders = parseTableBorders(findChild(tblPrElement, 'w', 'tblBorders'));\n if (borders) formatting.borders = borders;\n\n // Default cell margins (w:tblCellMar)\n const cellMargins = parseCellMargins(findChild(tblPrElement, 'w', 'tblCellMar'));\n if (cellMargins) formatting.cellMargins = cellMargins;\n\n // Table layout (w:tblLayout)\n const layoutElement = findChild(tblPrElement, 'w', 'tblLayout');\n if (layoutElement) {\n const layoutVal = getAttribute(layoutElement, 'w', 'type');\n if (layoutVal === 'fixed' || layoutVal === 'autofit') {\n formatting.layout = layoutVal;\n }\n }\n\n // Table style (w:tblStyle)\n const styleElement = findChild(tblPrElement, 'w', 'tblStyle');\n if (styleElement) {\n const styleId = getAttribute(styleElement, 'w', 'val');\n if (styleId) formatting.styleId = styleId;\n }\n\n // Table look (w:tblLook)\n const look = parseTableLook(findChild(tblPrElement, 'w', 'tblLook'));\n if (look) formatting.look = look;\n\n // Shading (w:shd)\n const shading = parseShading(findChild(tblPrElement, 'w', 'shd'));\n if (shading) formatting.shading = shading;\n\n // Table overlap (w:tblOverlap)\n const overlapElement = findChild(tblPrElement, 'w', 'tblOverlap');\n if (overlapElement) {\n const overlapVal = getAttribute(overlapElement, 'w', 'val');\n if (overlapVal === 'never' || overlapVal === 'overlap') {\n formatting.overlap = overlapVal;\n }\n }\n\n // Floating table (w:tblpPr)\n const floating = parseFloatingTableProperties(findChild(tblPrElement, 'w', 'tblpPr'));\n if (floating) formatting.floating = floating;\n\n // Bidirectional (w:bidiVisual)\n const bidi = parseBooleanElement(findChild(tblPrElement, 'w', 'bidiVisual'));\n if (bidi) formatting.bidi = true;\n\n if (Object.keys(formatting).length === 0) return undefined;\n\n return formatting;\n}\n\nfunction parseTablePropertyChanges(\n tblPrElement: XmlElement | null,\n currentFormatting: TableFormatting | undefined\n): TablePropertyChange[] | undefined {\n if (!tblPrElement) return undefined;\n\n const changes = findChildren(tblPrElement, 'w', 'tblPrChange')\n .map((changeElement): TablePropertyChange => {\n const previousTblPr = findChild(changeElement, 'w', 'tblPr');\n return {\n type: 'tablePropertyChange',\n info: parsePropertyChangeInfo(changeElement),\n previousFormatting: parseTableProperties(previousTblPr),\n currentFormatting,\n };\n })\n .filter((change) => change.previousFormatting || change.currentFormatting);\n\n return changes.length > 0 ? changes : undefined;\n}\n\nfunction parseTableRowPropertyChanges(\n trPrElement: XmlElement | null,\n currentFormatting: TableRowFormatting | undefined\n): TableRowPropertyChange[] | undefined {\n if (!trPrElement) return undefined;\n\n const changes = findChildren(trPrElement, 'w', 'trPrChange')\n .map((changeElement): TableRowPropertyChange => {\n const previousTrPr = findChild(changeElement, 'w', 'trPr');\n return {\n type: 'tableRowPropertyChange',\n info: parsePropertyChangeInfo(changeElement),\n previousFormatting: parseTableRowProperties(previousTrPr),\n currentFormatting,\n };\n })\n .filter((change) => change.previousFormatting || change.currentFormatting);\n\n return changes.length > 0 ? changes : undefined;\n}\n\nfunction parseTableCellPropertyChanges(\n tcPrElement: XmlElement | null,\n currentFormatting: TableCellFormatting | undefined\n): TableCellPropertyChange[] | undefined {\n if (!tcPrElement) return undefined;\n\n const changes = findChildren(tcPrElement, 'w', 'tcPrChange')\n .map((changeElement): TableCellPropertyChange => {\n const previousTcPr = findChild(changeElement, 'w', 'tcPr');\n return {\n type: 'tableCellPropertyChange',\n info: parsePropertyChangeInfo(changeElement),\n previousFormatting: parseTableCellProperties(previousTcPr),\n currentFormatting,\n };\n })\n .filter((change) => change.previousFormatting || change.currentFormatting);\n\n return changes.length > 0 ? changes : undefined;\n}\n\nfunction parseTableRowStructuralChange(\n trPrElement: XmlElement | null\n): TableStructuralChangeInfo | undefined {\n if (!trPrElement) return undefined;\n\n const insertion = findChild(trPrElement, 'w', 'ins');\n if (insertion) {\n return {\n type: 'tableRowInsertion',\n info: parseTrackedChangeInfo(insertion),\n };\n }\n\n const deletion = findChild(trPrElement, 'w', 'del');\n if (deletion) {\n return {\n type: 'tableRowDeletion',\n info: parseTrackedChangeInfo(deletion),\n };\n }\n\n return undefined;\n}\n\nfunction parseTableCellStructuralChange(\n tcPrElement: XmlElement | null\n): TableStructuralChangeInfo | undefined {\n if (!tcPrElement) return undefined;\n\n const insertion = findChild(tcPrElement, 'w', 'cellIns');\n if (insertion) {\n return {\n type: 'tableCellInsertion',\n info: parseTrackedChangeInfo(insertion),\n };\n }\n\n const deletion = findChild(tcPrElement, 'w', 'cellDel');\n if (deletion) {\n return {\n type: 'tableCellDeletion',\n info: parseTrackedChangeInfo(deletion),\n };\n }\n\n const merge = findChild(tcPrElement, 'w', 'cellMerge');\n if (merge) {\n return {\n type: 'tableCellMerge',\n info: parseTrackedChangeInfo(merge),\n };\n }\n\n return undefined;\n}\n\n// ============================================================================\n// TABLE ROW PROPERTIES PARSING (w:trPr)\n// ============================================================================\n\n/**\n * Parse table row properties (w:trPr)\n *\n * @param trPrElement - The w:trPr element\n * @returns Parsed row formatting\n */\nexport function parseTableRowProperties(\n trPrElement: XmlElement | null\n): TableRowFormatting | undefined {\n if (!trPrElement) return undefined;\n\n const formatting: TableRowFormatting = {};\n\n // Row height (w:trHeight)\n const heightElement = findChild(trPrElement, 'w', 'trHeight');\n if (heightElement) {\n const height = parseWidth(heightElement);\n if (height) formatting.height = height;\n\n const hRule = getAttribute(heightElement, 'w', 'hRule');\n if (hRule === 'auto' || hRule === 'atLeast' || hRule === 'exact') {\n formatting.heightRule = hRule;\n }\n }\n\n // Header row (w:tblHeader)\n const header = parseBooleanElement(findChild(trPrElement, 'w', 'tblHeader'));\n if (header) formatting.header = true;\n\n // Can't split (w:cantSplit)\n const cantSplit = parseBooleanElement(findChild(trPrElement, 'w', 'cantSplit'));\n if (cantSplit) formatting.cantSplit = true;\n\n // Row justification (w:jc)\n const jcElement = findChild(trPrElement, 'w', 'jc');\n if (jcElement) {\n const jcVal = getAttribute(jcElement, 'w', 'val');\n if (jcVal === 'left' || jcVal === 'center' || jcVal === 'right') {\n formatting.justification = jcVal;\n }\n }\n\n // Hidden row (w:hidden)\n const hidden = parseBooleanElement(findChild(trPrElement, 'w', 'hidden'));\n if (hidden) formatting.hidden = true;\n\n // Conditional format style (w:cnfStyle)\n const conditionalFormat = parseConditionalFormatStyle(findChild(trPrElement, 'w', 'cnfStyle'));\n if (conditionalFormat) formatting.conditionalFormat = conditionalFormat;\n\n if (Object.keys(formatting).length === 0) return undefined;\n\n return formatting;\n}\n\n// ============================================================================\n// TABLE CELL PROPERTIES PARSING (w:tcPr)\n// ============================================================================\n\n/**\n * Parse conditional format style (for table style conditional formatting)\n *\n * @param cnfElement - The w:cnfStyle element\n * @returns Parsed conditional format or undefined\n */\nexport function parseConditionalFormatStyle(\n cnfElement: XmlElement | null\n): ConditionalFormatStyle | undefined {\n if (!cnfElement) return undefined;\n\n const style: ConditionalFormatStyle = {};\n\n // Parse individual flags\n const firstRow = getAttribute(cnfElement, 'w', 'firstRow');\n if (firstRow === '1' || firstRow === 'true') style.firstRow = true;\n\n const lastRow = getAttribute(cnfElement, 'w', 'lastRow');\n if (lastRow === '1' || lastRow === 'true') style.lastRow = true;\n\n const firstColumn = getAttribute(cnfElement, 'w', 'firstColumn');\n if (firstColumn === '1' || firstColumn === 'true') style.firstColumn = true;\n\n const lastColumn = getAttribute(cnfElement, 'w', 'lastColumn');\n if (lastColumn === '1' || lastColumn === 'true') style.lastColumn = true;\n\n const oddHBand = getAttribute(cnfElement, 'w', 'oddHBand');\n if (oddHBand === '1' || oddHBand === 'true') style.oddHBand = true;\n\n const evenHBand = getAttribute(cnfElement, 'w', 'evenHBand');\n if (evenHBand === '1' || evenHBand === 'true') style.evenHBand = true;\n\n const oddVBand = getAttribute(cnfElement, 'w', 'oddVBand');\n if (oddVBand === '1' || oddVBand === 'true') style.oddVBand = true;\n\n const evenVBand = getAttribute(cnfElement, 'w', 'evenVBand');\n if (evenVBand === '1' || evenVBand === 'true') style.evenVBand = true;\n\n // Corner cells\n const nwCell = getAttribute(cnfElement, 'w', 'firstRowFirstColumn');\n if (nwCell === '1' || nwCell === 'true') style.nwCell = true;\n\n const neCell = getAttribute(cnfElement, 'w', 'firstRowLastColumn');\n if (neCell === '1' || neCell === 'true') style.neCell = true;\n\n const swCell = getAttribute(cnfElement, 'w', 'lastRowFirstColumn');\n if (swCell === '1' || swCell === 'true') style.swCell = true;\n\n const seCell = getAttribute(cnfElement, 'w', 'lastRowLastColumn');\n if (seCell === '1' || seCell === 'true') style.seCell = true;\n\n // Also check for the val attribute (binary flags string)\n const val = getAttribute(cnfElement, 'w', 'val');\n if (val && val.length === 12) {\n // Binary string format: XXXXXXXXXXXXXX\n // Position meanings from left to right\n if (val[0] === '1') style.firstRow = true;\n if (val[1] === '1') style.lastRow = true;\n if (val[2] === '1') style.firstColumn = true;\n if (val[3] === '1') style.lastColumn = true;\n if (val[4] === '1') style.oddVBand = true;\n if (val[5] === '1') style.evenVBand = true;\n if (val[6] === '1') style.oddHBand = true;\n if (val[7] === '1') style.evenHBand = true;\n if (val[8] === '1') style.nwCell = true;\n if (val[9] === '1') style.neCell = true;\n if (val[10] === '1') style.swCell = true;\n if (val[11] === '1') style.seCell = true;\n }\n\n if (Object.keys(style).length === 0) return undefined;\n\n return style;\n}\n\n/**\n * Parse table cell properties (w:tcPr)\n *\n * @param tcPrElement - The w:tcPr element\n * @returns Parsed cell formatting\n */\nexport function parseTableCellProperties(\n tcPrElement: XmlElement | null\n): TableCellFormatting | undefined {\n if (!tcPrElement) return undefined;\n\n const formatting: TableCellFormatting = {};\n\n // Cell width (w:tcW)\n const width = parseWidth(findChild(tcPrElement, 'w', 'tcW'));\n if (width) formatting.width = width;\n\n // Cell borders (w:tcBorders)\n const borders = parseTableBorders(findChild(tcPrElement, 'w', 'tcBorders'));\n if (borders) formatting.borders = borders;\n\n // Cell margins (w:tcMar)\n const margins = parseCellMargins(findChild(tcPrElement, 'w', 'tcMar'));\n if (margins) formatting.margins = margins;\n\n // Shading (w:shd)\n const shading = parseShading(findChild(tcPrElement, 'w', 'shd'));\n if (shading) formatting.shading = shading;\n\n // Vertical alignment (w:vAlign)\n const vAlignElement = findChild(tcPrElement, 'w', 'vAlign');\n if (vAlignElement) {\n const vAlign = getAttribute(vAlignElement, 'w', 'val');\n if (vAlign === 'top' || vAlign === 'center' || vAlign === 'bottom') {\n formatting.verticalAlign = vAlign;\n }\n }\n\n // Text direction (w:textDirection)\n const textDirElement = findChild(tcPrElement, 'w', 'textDirection');\n if (textDirElement) {\n const textDir = getAttribute(textDirElement, 'w', 'val');\n if (textDir) {\n formatting.textDirection = textDir as TableCellFormatting['textDirection'];\n }\n }\n\n // Grid span (horizontal merge) (w:gridSpan)\n const gridSpanElement = findChild(tcPrElement, 'w', 'gridSpan');\n if (gridSpanElement) {\n const gridSpan = parseNumericAttribute(gridSpanElement, 'w', 'val');\n if (gridSpan !== undefined && gridSpan > 1) {\n formatting.gridSpan = gridSpan;\n }\n }\n\n // Vertical merge (w:vMerge)\n const vMergeElement = findChild(tcPrElement, 'w', 'vMerge');\n if (vMergeElement) {\n const vMergeVal = getAttribute(vMergeElement, 'w', 'val');\n if (vMergeVal === 'restart') {\n formatting.vMerge = 'restart';\n } else {\n // No val attribute or val=\"continue\" means continuation\n formatting.vMerge = 'continue';\n }\n }\n\n // Fit text (w:tcFitText)\n const fitText = parseBooleanElement(findChild(tcPrElement, 'w', 'tcFitText'));\n if (fitText) formatting.fitText = true;\n\n // No wrap (w:noWrap)\n const noWrap = parseBooleanElement(findChild(tcPrElement, 'w', 'noWrap'));\n if (noWrap) formatting.noWrap = true;\n\n // Hide mark (w:hideMark)\n const hideMark = parseBooleanElement(findChild(tcPrElement, 'w', 'hideMark'));\n if (hideMark) formatting.hideMark = true;\n\n // Conditional format style (w:cnfStyle)\n const conditionalFormat = parseConditionalFormatStyle(findChild(tcPrElement, 'w', 'cnfStyle'));\n if (conditionalFormat) formatting.conditionalFormat = conditionalFormat;\n\n if (Object.keys(formatting).length === 0) return undefined;\n\n return formatting;\n}\n\n// ============================================================================\n// CELL CONTENT PARSING\n// ============================================================================\n\n/**\n * Parse table cell content (paragraphs, nested tables)\n *\n * @param tcElement - The w:tc element\n * @param styles - Style definitions\n * @param theme - Theme for color/font resolution\n * @param numbering - Numbering definitions for lists\n * @param rels - Relationships for hyperlinks\n * @param media - Media files for images\n * @returns Array of content blocks\n */\nfunction parseCellContent(\n tcElement: XmlElement,\n styles: StyleMap | null,\n theme: Theme | null,\n numbering: NumberingMap | null,\n rels: RelationshipMap | null,\n media: Map<string, MediaFile> | null\n): (Paragraph | Table)[] {\n const content: (Paragraph | Table)[] = [];\n\n // Get all child elements\n const elements = tcElement.elements || [];\n\n for (const child of elements) {\n if (!child.name) continue;\n\n const localName = child.name.split(':').pop();\n\n if (localName === 'p') {\n // Parse paragraph\n const para = parseParagraph(child, styles, theme, numbering, rels, media);\n content.push(para);\n } else if (localName === 'tbl') {\n // Parse nested table (recursive)\n const table = parseTable(child, styles, theme, numbering, rels, media);\n content.push(table);\n }\n // Other content types in cells are rare but could be added\n }\n\n // Ensure at least one empty paragraph (Word requires this)\n if (content.length === 0) {\n content.push({\n type: 'paragraph',\n content: [],\n });\n }\n\n return content;\n}\n\n// ============================================================================\n// TABLE CELL PARSING\n// ============================================================================\n\n/**\n * Parse a table cell (w:tc)\n *\n * @param tcElement - The w:tc element\n * @param styles - Style definitions\n * @param theme - Theme for color/font resolution\n * @param numbering - Numbering definitions for lists\n * @param rels - Relationships for hyperlinks\n * @param media - Media files for images\n * @returns Parsed table cell\n */\nexport function parseTableCell(\n tcElement: XmlElement,\n styles: StyleMap | null,\n theme: Theme | null,\n numbering: NumberingMap | null,\n rels: RelationshipMap | null,\n media: Map<string, MediaFile> | null\n): TableCell {\n const cell: TableCell = {\n type: 'tableCell',\n content: [],\n };\n\n // Parse cell properties (w:tcPr)\n const tcPrElement = findChild(tcElement, 'w', 'tcPr');\n const formatting = parseTableCellProperties(tcPrElement);\n if (formatting) {\n cell.formatting = formatting;\n }\n cell.propertyChanges = parseTableCellPropertyChanges(tcPrElement, formatting);\n cell.structuralChange = parseTableCellStructuralChange(tcPrElement);\n\n // Parse content\n cell.content = parseCellContent(tcElement, styles, theme, numbering, rels, media);\n\n return cell;\n}\n\n// ============================================================================\n// TABLE ROW PARSING\n// ============================================================================\n\n/**\n * Parse a table row (w:tr)\n *\n * @param trElement - The w:tr element\n * @param styles - Style definitions\n * @param theme - Theme for color/font resolution\n * @param numbering - Numbering definitions for lists\n * @param rels - Relationships for hyperlinks\n * @param media - Media files for images\n * @returns Parsed table row\n */\nexport function parseTableRow(\n trElement: XmlElement,\n styles: StyleMap | null,\n theme: Theme | null,\n numbering: NumberingMap | null,\n rels: RelationshipMap | null,\n media: Map<string, MediaFile> | null\n): TableRow {\n const row: TableRow = {\n type: 'tableRow',\n cells: [],\n };\n\n // Parse row properties (w:trPr)\n const trPrElement = findChild(trElement, 'w', 'trPr');\n const formatting = parseTableRowProperties(trPrElement);\n if (formatting) {\n row.formatting = formatting;\n }\n row.propertyChanges = parseTableRowPropertyChanges(trPrElement, formatting);\n row.structuralChange = parseTableRowStructuralChange(trPrElement);\n\n // Parse cells\n const cells = findChildren(trElement, 'w', 'tc');\n for (const cellElement of cells) {\n const cell = parseTableCell(cellElement, styles, theme, numbering, rels, media);\n row.cells.push(cell);\n }\n\n return row;\n}\n\n// ============================================================================\n// TABLE GRID PARSING\n// ============================================================================\n\n/**\n * Parse table grid (w:tblGrid) for column widths\n *\n * @param tblGridElement - The w:tblGrid element\n * @returns Array of column widths in twips\n */\nexport function parseTableGrid(tblGridElement: XmlElement | null): number[] | undefined {\n if (!tblGridElement) return undefined;\n\n const widths: number[] = [];\n\n const gridCols = findChildren(tblGridElement, 'w', 'gridCol');\n for (const col of gridCols) {\n const width = parseNumericAttribute(col, 'w', 'w') ?? 0;\n widths.push(width);\n }\n\n return widths.length > 0 ? widths : undefined;\n}\n\n// ============================================================================\n// MAIN TABLE PARSING\n// ============================================================================\n\n/**\n * Parse a table element (w:tbl)\n *\n * @param tblElement - The w:tbl element\n * @param styles - Style definitions\n * @param theme - Theme for color/font resolution\n * @param numbering - Numbering definitions for lists\n * @param rels - Relationships for hyperlinks\n * @param media - Media files for images\n * @returns Parsed table\n */\nexport function parseTable(\n tblElement: XmlElement,\n styles: StyleMap | null,\n theme: Theme | null,\n numbering: NumberingMap | null,\n rels: RelationshipMap | null,\n media: Map<string, MediaFile> | null\n): Table {\n const table: Table = {\n type: 'table',\n rows: [],\n };\n\n // Parse table properties (w:tblPr)\n const tblPrElement = findChild(tblElement, 'w', 'tblPr');\n const formatting = parseTableProperties(tblPrElement);\n if (formatting) {\n table.formatting = formatting;\n }\n table.propertyChanges = parseTablePropertyChanges(tblPrElement, formatting);\n\n // Parse table grid (w:tblGrid)\n const columnWidths = parseTableGrid(findChild(tblElement, 'w', 'tblGrid'));\n if (columnWidths) {\n table.columnWidths = columnWidths;\n }\n\n // Parse rows\n const rows = findChildren(tblElement, 'w', 'tr');\n for (const rowElement of rows) {\n const row = parseTableRow(rowElement, styles, theme, numbering, rels, media);\n table.rows.push(row);\n }\n\n return table;\n}\n\n// ============================================================================\n// TABLE UTILITIES\n// ============================================================================\n\n/**\n * Get the number of columns in a table\n *\n * Uses the table grid if available, otherwise counts cells in first row.\n *\n * @param table - The table to measure\n * @returns Number of columns\n */\nexport function getTableColumnCount(table: Table): number {\n if (table.columnWidths && table.columnWidths.length > 0) {\n return table.columnWidths.length;\n }\n\n if (table.rows.length === 0) return 0;\n\n // Count cells in first row, accounting for grid span\n return table.rows[0].cells.reduce((count, cell) => {\n return count + (cell.formatting?.gridSpan ?? 1);\n }, 0);\n}\n\n/**\n * Get the number of rows in a table\n *\n * @param table - The table to measure\n * @returns Number of rows\n */\nexport function getTableRowCount(table: Table): number {\n return table.rows.length;\n}\n\n/**\n * Check if a cell is part of a vertical merge\n *\n * @param cell - The cell to check\n * @returns true if cell continues a vertical merge\n */\nexport function isCellMergeContinuation(cell: TableCell): boolean {\n return cell.formatting?.vMerge === 'continue';\n}\n\n/**\n * Check if a cell starts a vertical merge\n *\n * @param cell - The cell to check\n * @returns true if cell starts a vertical merge\n */\nexport function isCellMergeStart(cell: TableCell): boolean {\n return cell.formatting?.vMerge === 'restart';\n}\n\n/**\n * Check if a cell spans multiple columns\n *\n * @param cell - The cell to check\n * @returns true if cell spans multiple columns\n */\nexport function isCellHorizontallyMerged(cell: TableCell): boolean {\n return (cell.formatting?.gridSpan ?? 1) > 1;\n}\n\n/**\n * Get the plain text content of a table\n *\n * @param table - The table to extract text from\n * @returns Plain text content\n */\nexport function getTableText(table: Table): string {\n const rows: string[] = [];\n\n for (const row of table.rows) {\n const cells: string[] = [];\n\n for (const cell of row.cells) {\n const cellText = cell.content\n .filter((c): c is Paragraph => c.type === 'paragraph')\n .map((p) => getParagraphText(p))\n .join('\\n');\n cells.push(cellText);\n }\n\n rows.push(cells.join('\\t'));\n }\n\n return rows.join('\\n');\n}\n\n/**\n * Helper to get paragraph text (simplified)\n */\nfunction getParagraphText(para: Paragraph): string {\n return para.content\n .filter((c) => 'content' in c)\n .flatMap((run) => {\n if (!('content' in run)) return [];\n return (run as any).content.filter((c: any) => c.type === 'text').map((c: any) => c.text);\n })\n .join('');\n}\n\n/**\n * Check if table has header row\n *\n * @param table - The table to check\n * @returns true if first row is marked as header\n */\nexport function hasHeaderRow(table: Table): boolean {\n if (table.rows.length === 0) return false;\n return table.rows[0].formatting?.header === true;\n}\n\n/**\n * Get all header rows from a table\n *\n * @param table - The table to search\n * @returns Array of header rows\n */\nexport function getHeaderRows(table: Table): TableRow[] {\n return table.rows.filter((row) => row.formatting?.header === true);\n}\n\n/**\n * Check if table is a floating table\n *\n * @param table - The table to check\n * @returns true if table has floating properties\n */\nexport function isFloatingTable(table: Table): boolean {\n return table.formatting?.floating !== undefined;\n}\n","/**\n * Header/Footer Parser - Parse header*.xml and footer*.xml files\n *\n * Headers and footers are stored in separate XML files within the DOCX package:\n * - word/header1.xml, word/header2.xml, etc.\n * - word/footer1.xml, word/footer2.xml, etc.\n *\n * Each header/footer is referenced from document.xml via:\n * - w:sectPr > w:headerReference (type=\"default|first|even\", r:id=\"rIdX\")\n * - w:sectPr > w:footerReference (type=\"default|first|even\", r:id=\"rIdX\")\n *\n * Header/footer types:\n * - default: Used for all pages unless first/even specified\n * - first: Used only for the first page of a section\n * - even: Used for even-numbered pages (when different odd/even enabled)\n *\n * Content structure:\n * - w:hdr or w:ftr root element\n * - Contains w:p (paragraphs) and w:tbl (tables)\n * - Can contain images, shapes, page numbers, etc.\n *\n * OOXML Reference:\n * - Root: w:hdr (header) or w:ftr (footer)\n * - Content: w:p, w:tbl\n */\n\nimport type {\n HeaderFooter,\n HeaderFooterType,\n HeaderReference,\n FooterReference,\n Paragraph,\n Table,\n Theme,\n RelationshipMap,\n MediaFile,\n} from '../types/document';\nimport type { StyleMap } from './styleParser';\nimport type { NumberingMap } from './numberingParser';\nimport { parseXml, findChildren, getAttribute, type XmlElement } from './xmlParser';\nimport { parseParagraph } from './paragraphParser';\nimport { parseTable } from './tableParser';\n\n// ============================================================================\n// HEADER/FOOTER MAP INTERFACE\n// ============================================================================\n\n/**\n * Map of header/footer ID to HeaderFooter content\n */\nexport interface HeaderFooterMap {\n /** Map of rId to HeaderFooter */\n byId: Map<string, HeaderFooter>;\n\n /** Get header/footer by rId */\n get(rId: string): HeaderFooter | undefined;\n\n /** Check if header/footer exists */\n has(rId: string): boolean;\n\n /** Get all headers/footers */\n getAll(): HeaderFooter[];\n\n /** Get by type */\n getByType(type: HeaderFooterType): HeaderFooter | undefined;\n}\n\n// ============================================================================\n// HEADER/FOOTER REFERENCE PARSING\n// ============================================================================\n\n/**\n * Parse header type attribute\n */\nfunction parseHeaderFooterType(typeAttr: string | null): HeaderFooterType {\n switch (typeAttr) {\n case 'first':\n return 'first';\n case 'even':\n return 'even';\n case 'default':\n default:\n return 'default';\n }\n}\n\n/**\n * Parse a header reference from sectPr (w:headerReference)\n *\n * @param element - The w:headerReference element\n * @returns HeaderReference with type and rId\n */\nexport function parseHeaderReference(element: XmlElement): HeaderReference {\n const typeAttr = getAttribute(element, 'w', 'type');\n const rId = getAttribute(element, 'r', 'id') ?? '';\n\n return {\n type: parseHeaderFooterType(typeAttr),\n rId,\n };\n}\n\n/**\n * Parse a footer reference from sectPr (w:footerReference)\n *\n * @param element - The w:footerReference element\n * @returns FooterReference with type and rId\n */\nexport function parseFooterReference(element: XmlElement): FooterReference {\n const typeAttr = getAttribute(element, 'w', 'type');\n const rId = getAttribute(element, 'r', 'id') ?? '';\n\n return {\n type: parseHeaderFooterType(typeAttr),\n rId,\n };\n}\n\n/**\n * Parse all header references from a sectPr element\n *\n * @param sectPr - The w:sectPr element\n * @returns Array of HeaderReference objects\n */\nexport function parseHeaderReferences(sectPr: XmlElement): HeaderReference[] {\n const refs: HeaderReference[] = [];\n const headerRefElements = findChildren(sectPr, 'w', 'headerReference');\n\n for (const el of headerRefElements) {\n refs.push(parseHeaderReference(el));\n }\n\n return refs;\n}\n\n/**\n * Parse all footer references from a sectPr element\n *\n * @param sectPr - The w:sectPr element\n * @returns Array of FooterReference objects\n */\nexport function parseFooterReferences(sectPr: XmlElement): FooterReference[] {\n const refs: FooterReference[] = [];\n const footerRefElements = findChildren(sectPr, 'w', 'footerReference');\n\n for (const el of footerRefElements) {\n refs.push(parseFooterReference(el));\n }\n\n return refs;\n}\n\n// ============================================================================\n// HEADER/FOOTER CONTENT PARSING\n// ============================================================================\n\n/**\n * Parse header/footer content (paragraphs and tables)\n *\n * @param root - Root element (w:hdr or w:ftr)\n * @param styles - Style map for applying styles\n * @param theme - Theme for color resolution\n * @param numbering - Numbering definitions for lists\n * @param rels - Relationships for resolving hyperlinks/images\n * @param media - Media files for images\n * @returns Array of content elements (Paragraph | Table)\n */\nfunction parseHeaderFooterContent(\n root: XmlElement,\n styles: StyleMap | null,\n theme: Theme | null,\n numbering: NumberingMap | null,\n rels: RelationshipMap | null,\n media: Map<string, MediaFile> | null\n): (Paragraph | Table)[] {\n const content: (Paragraph | Table)[] = [];\n\n // Get all child elements\n const elements = root.elements ?? [];\n\n for (const el of elements) {\n if (el.type !== 'element') continue;\n\n const name = el.name ?? '';\n\n // Parse paragraphs\n if (name === 'w:p' || name.endsWith(':p')) {\n const paragraph = parseParagraph(el, styles, theme, numbering, rels, media);\n content.push(paragraph);\n }\n // Parse tables\n else if (name === 'w:tbl' || name.endsWith(':tbl')) {\n const table = parseTable(el, styles, theme, numbering, rels, media);\n content.push(table);\n }\n // SDT (structured document tags) can contain paragraphs/tables\n else if (name === 'w:sdt' || name.endsWith(':sdt')) {\n // Find sdtContent\n const sdtContentEl = (el.elements ?? []).find(\n (child: XmlElement) =>\n child.type === 'element' &&\n (child.name === 'w:sdtContent' || child.name?.endsWith(':sdtContent'))\n );\n if (sdtContentEl) {\n // Recursively parse content inside SDT\n const sdtContent = parseHeaderFooterContent(\n sdtContentEl,\n styles,\n theme,\n numbering,\n rels,\n media\n );\n content.push(...sdtContent);\n }\n }\n }\n\n return content;\n}\n\n/**\n * Parse a header XML file (word/header*.xml)\n *\n * @param headerXml - The raw XML content of the header file\n * @param hdrFtrType - The type of header (default, first, even)\n * @param styles - Parsed style map for applying styles\n * @param theme - Parsed theme for color resolution\n * @param numbering - Parsed numbering definitions for lists\n * @param rels - Relationships for resolving hyperlinks/images\n * @param media - Media files for images\n * @returns HeaderFooter object\n */\nexport function parseHeader(\n headerXml: string,\n hdrFtrType: HeaderFooterType = 'default',\n styles: StyleMap | null = null,\n theme: Theme | null = null,\n numbering: NumberingMap | null = null,\n rels: RelationshipMap | null = null,\n media: Map<string, MediaFile> | null = null\n): HeaderFooter {\n const result: HeaderFooter = {\n type: 'header',\n hdrFtrType,\n content: [],\n };\n\n if (!headerXml) {\n return result;\n }\n\n const doc = parseXml(headerXml);\n if (!doc) {\n return result;\n }\n\n // Find the root header element (w:hdr)\n const rootElement = doc.elements?.find(\n (el: XmlElement) => el.type === 'element' && (el.name === 'w:hdr' || el.name?.endsWith(':hdr'))\n ) as XmlElement | undefined;\n\n if (!rootElement) {\n return result;\n }\n\n // Parse content\n result.content = parseHeaderFooterContent(rootElement, styles, theme, numbering, rels, media);\n\n return result;\n}\n\n/**\n * Parse a footer XML file (word/footer*.xml)\n *\n * @param footerXml - The raw XML content of the footer file\n * @param hdrFtrType - The type of footer (default, first, even)\n * @param styles - Parsed style map for applying styles\n * @param theme - Parsed theme for color resolution\n * @param numbering - Parsed numbering definitions for lists\n * @param rels - Relationships for resolving hyperlinks/images\n * @param media - Media files for images\n * @returns HeaderFooter object\n */\nexport function parseFooter(\n footerXml: string,\n hdrFtrType: HeaderFooterType = 'default',\n styles: StyleMap | null = null,\n theme: Theme | null = null,\n numbering: NumberingMap | null = null,\n rels: RelationshipMap | null = null,\n media: Map<string, MediaFile> | null = null\n): HeaderFooter {\n const result: HeaderFooter = {\n type: 'footer',\n hdrFtrType,\n content: [],\n };\n\n if (!footerXml) {\n return result;\n }\n\n const doc = parseXml(footerXml);\n if (!doc) {\n return result;\n }\n\n // Find the root footer element (w:ftr)\n const rootElement = doc.elements?.find(\n (el: XmlElement) => el.type === 'element' && (el.name === 'w:ftr' || el.name?.endsWith(':ftr'))\n ) as XmlElement | undefined;\n\n if (!rootElement) {\n return result;\n }\n\n // Parse content\n result.content = parseHeaderFooterContent(rootElement, styles, theme, numbering, rels, media);\n\n return result;\n}\n\n/**\n * Generic function to parse either header or footer\n *\n * @param xml - Raw XML content\n * @param isHeader - true for header, false for footer\n * @param hdrFtrType - The type (default, first, even)\n * @param styles - Style map\n * @param theme - Theme\n * @param numbering - Numbering definitions\n * @param rels - Relationships\n * @param media - Media files\n * @returns HeaderFooter object\n */\nexport function parseHeaderFooter(\n xml: string,\n isHeader: boolean,\n hdrFtrType: HeaderFooterType = 'default',\n styles: StyleMap | null = null,\n theme: Theme | null = null,\n numbering: NumberingMap | null = null,\n rels: RelationshipMap | null = null,\n media: Map<string, MediaFile> | null = null\n): HeaderFooter {\n if (isHeader) {\n return parseHeader(xml, hdrFtrType, styles, theme, numbering, rels, media);\n } else {\n return parseFooter(xml, hdrFtrType, styles, theme, numbering, rels, media);\n }\n}\n\n// ============================================================================\n// HEADER/FOOTER MAP CREATION\n// ============================================================================\n\n/**\n * Create a HeaderFooterMap from parsed headers/footers\n */\nfunction createHeaderFooterMap(byId: Map<string, HeaderFooter>): HeaderFooterMap {\n return {\n byId,\n\n get(rId: string): HeaderFooter | undefined {\n return byId.get(rId);\n },\n\n has(rId: string): boolean {\n return byId.has(rId);\n },\n\n getAll(): HeaderFooter[] {\n return Array.from(byId.values());\n },\n\n getByType(type: HeaderFooterType): HeaderFooter | undefined {\n for (const hf of byId.values()) {\n if (hf.hdrFtrType === type) {\n return hf;\n }\n }\n return undefined;\n },\n };\n}\n\n/**\n * Create an empty HeaderFooterMap\n */\nexport function createEmptyHeaderFooterMap(): HeaderFooterMap {\n return createHeaderFooterMap(new Map());\n}\n\n/**\n * Build a HeaderFooterMap from references and XML content\n *\n * @param references - Header or footer references from sectPr\n * @param xmlContents - Map of rId to XML content\n * @param isHeader - true for headers, false for footers\n * @param styles - Style map\n * @param theme - Theme\n * @param numbering - Numbering definitions\n * @param rels - Relationships\n * @param media - Media files\n * @returns HeaderFooterMap with all parsed headers/footers\n */\nexport function buildHeaderFooterMap(\n references: (HeaderReference | FooterReference)[],\n xmlContents: Map<string, string>,\n isHeader: boolean,\n styles: StyleMap | null = null,\n theme: Theme | null = null,\n numbering: NumberingMap | null = null,\n rels: RelationshipMap | null = null,\n media: Map<string, MediaFile> | null = null\n): HeaderFooterMap {\n const byId = new Map<string, HeaderFooter>();\n\n for (const ref of references) {\n const xml = xmlContents.get(ref.rId);\n if (xml) {\n const hf = parseHeaderFooter(xml, isHeader, ref.type, styles, theme, numbering, rels, media);\n byId.set(ref.rId, hf);\n }\n }\n\n return createHeaderFooterMap(byId);\n}\n\n// ============================================================================\n// UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Get plain text content of a header/footer\n */\nexport function getHeaderFooterText(hf: HeaderFooter): string {\n const texts: string[] = [];\n\n for (const item of hf.content) {\n if (item.type === 'paragraph') {\n const paraTexts: string[] = [];\n for (const content of item.content) {\n if (content.type === 'run') {\n for (const runContent of content.content) {\n if (runContent.type === 'text') {\n paraTexts.push(runContent.text);\n }\n }\n }\n }\n texts.push(paraTexts.join(''));\n } else if (item.type === 'table') {\n // Extract text from table cells\n for (const row of item.rows) {\n for (const cell of row.cells) {\n for (const cellContent of cell.content) {\n if (cellContent.type === 'paragraph') {\n const paraTexts: string[] = [];\n for (const content of cellContent.content) {\n if (content.type === 'run') {\n for (const runContent of content.content) {\n if (runContent.type === 'text') {\n paraTexts.push(runContent.text);\n }\n }\n }\n }\n texts.push(paraTexts.join(''));\n }\n }\n }\n }\n }\n }\n\n return texts.join('\\n');\n}\n\n/**\n * Check if header/footer is empty (no content)\n */\nexport function isEmptyHeaderFooter(hf: HeaderFooter): boolean {\n if (hf.content.length === 0) return true;\n\n // Check if all content is empty paragraphs\n for (const item of hf.content) {\n if (item.type === 'table') return false;\n if (item.type === 'paragraph' && item.content.length > 0) {\n // Check if paragraph has any actual content\n for (const content of item.content) {\n if (content.type !== 'run') return false;\n for (const rc of content.content) {\n if (rc.type === 'text' && rc.text.length > 0) return false;\n if (rc.type !== 'text') return false; // Has image, field, etc.\n }\n }\n }\n }\n\n return true;\n}\n\n/**\n * Check if header/footer has page number field\n */\nexport function hasPageNumberField(hf: HeaderFooter): boolean {\n for (const item of hf.content) {\n if (item.type === 'paragraph') {\n for (const content of item.content) {\n if (content.type === 'simpleField' || content.type === 'complexField') {\n if (content.fieldType === 'PAGE' || content.fieldType === 'NUMPAGES') {\n return true;\n }\n }\n if (content.type === 'run') {\n for (const rc of content.content) {\n if (rc.type === 'fieldChar' && rc.charType === 'begin') {\n // Part of a complex field - would need to check instruction\n // For simplicity, we'll check the field content in the paragraph\n continue;\n }\n }\n }\n }\n }\n }\n return false;\n}\n\n/**\n * Get the header for a given page considering type rules\n *\n * @param headers - Map of type to HeaderFooter\n * @param pageNumber - 1-based page number\n * @param isFirstPage - Whether this is the first page of the section\n * @param hasDifferentFirstPage - Whether different first page is enabled\n * @param hasDifferentOddEven - Whether different odd/even pages is enabled\n * @returns The appropriate HeaderFooter or undefined\n */\nexport function getHeaderForPage(\n headers: Map<HeaderFooterType, HeaderFooter>,\n pageNumber: number,\n isFirstPage: boolean,\n hasDifferentFirstPage: boolean,\n hasDifferentOddEven: boolean\n): HeaderFooter | undefined {\n // First page header takes priority if enabled\n if (isFirstPage && hasDifferentFirstPage) {\n const firstHeader = headers.get('first');\n if (firstHeader) return firstHeader;\n }\n\n // Even page header if enabled and page is even\n if (hasDifferentOddEven && pageNumber % 2 === 0) {\n const evenHeader = headers.get('even');\n if (evenHeader) return evenHeader;\n }\n\n // Default header for everything else\n return headers.get('default');\n}\n\n/**\n * Get the footer for a given page considering type rules\n * (Same logic as getHeaderForPage)\n */\nexport function getFooterForPage(\n footers: Map<HeaderFooterType, HeaderFooter>,\n pageNumber: number,\n isFirstPage: boolean,\n hasDifferentFirstPage: boolean,\n hasDifferentOddEven: boolean\n): HeaderFooter | undefined {\n if (isFirstPage && hasDifferentFirstPage) {\n const firstFooter = footers.get('first');\n if (firstFooter) return firstFooter;\n }\n\n if (hasDifferentOddEven && pageNumber % 2 === 0) {\n const evenFooter = footers.get('even');\n if (evenFooter) return evenFooter;\n }\n\n return footers.get('default');\n}\n\n/**\n * Convert HeaderFooterMap to type-indexed Map\n *\n * @param map - HeaderFooterMap\n * @returns Map indexed by HeaderFooterType\n */\nexport function headerFooterMapToTypeMap(\n map: HeaderFooterMap\n): Map<HeaderFooterType, HeaderFooter> {\n const result = new Map<HeaderFooterType, HeaderFooter>();\n\n for (const hf of map.getAll()) {\n // If there are multiple with same type, later ones overwrite\n result.set(hf.hdrFtrType, hf);\n }\n\n return result;\n}\n\n/**\n * Check if a HeaderFooter contains any images\n */\nexport function hasImages(hf: HeaderFooter): boolean {\n for (const item of hf.content) {\n if (item.type === 'paragraph') {\n for (const content of item.content) {\n if (content.type === 'run') {\n for (const rc of content.content) {\n if (rc.type === 'drawing') return true;\n }\n }\n }\n }\n }\n return false;\n}\n\n/**\n * Check if a HeaderFooter contains any tables\n */\nexport function hasTables(hf: HeaderFooter): boolean {\n for (const item of hf.content) {\n if (item.type === 'table') return true;\n }\n return false;\n}\n","/**\n * Footnote/Endnote Parser - Parse footnotes.xml and endnotes.xml\n *\n * Footnotes and endnotes are stored in separate XML files within the DOCX package:\n * - word/footnotes.xml - Contains all footnote definitions\n * - word/endnotes.xml - Contains all endnote definitions\n *\n * Each note contains:\n * - An ID that matches references in document.xml (w:footnoteReference, w:endnoteReference)\n * - A type (normal, separator, continuationSeparator, continuationNotice)\n * - Content (paragraphs)\n *\n * The references in the document body are parsed by runParser as NoteReferenceContent.\n *\n * OOXML Reference:\n * - Footnote: w:footnote[@w:id][@w:type]\n * - Endnote: w:endnote[@w:id][@w:type]\n * - Content: w:p (paragraphs)\n */\n\nimport type {\n Footnote,\n Endnote,\n FootnoteProperties,\n EndnoteProperties,\n FootnotePosition,\n EndnotePosition,\n NoteNumberRestart,\n NumberFormat,\n Paragraph,\n Theme,\n RelationshipMap,\n MediaFile,\n} from '../types/document';\nimport type { StyleMap } from './styleParser';\nimport type { NumberingMap } from './numberingParser';\nimport {\n parseXml,\n findChild,\n findChildren,\n getAttribute,\n parseNumericAttribute,\n type XmlElement,\n} from './xmlParser';\nimport { parseParagraph } from './paragraphParser';\n\n// ============================================================================\n// FOOTNOTE MAP INTERFACE\n// ============================================================================\n\n/**\n * Footnote map returned by parseFootnotes\n */\nexport interface FootnoteMap {\n /** All footnotes indexed by ID */\n byId: Map<number, Footnote>;\n\n /** Array of all footnotes in document order */\n footnotes: Footnote[];\n\n /** Get footnote by ID */\n getFootnote(id: number): Footnote | undefined;\n\n /** Check if footnote exists */\n hasFootnote(id: number): boolean;\n\n /** Get all normal (non-separator) footnotes */\n getNormalFootnotes(): Footnote[];\n\n /** Get separator footnote if exists */\n getSeparator(): Footnote | undefined;\n\n /** Get continuation separator if exists */\n getContinuationSeparator(): Footnote | undefined;\n}\n\n/**\n * Endnote map returned by parseEndnotes\n */\nexport interface EndnoteMap {\n /** All endnotes indexed by ID */\n byId: Map<number, Endnote>;\n\n /** Array of all endnotes in document order */\n endnotes: Endnote[];\n\n /** Get endnote by ID */\n getEndnote(id: number): Endnote | undefined;\n\n /** Check if endnote exists */\n hasEndnote(id: number): boolean;\n\n /** Get all normal (non-separator) endnotes */\n getNormalEndnotes(): Endnote[];\n\n /** Get separator endnote if exists */\n getSeparator(): Endnote | undefined;\n\n /** Get continuation separator if exists */\n getContinuationSeparator(): Endnote | undefined;\n}\n\n// ============================================================================\n// NOTE TYPE PARSING\n// ============================================================================\n\n/**\n * Parse note type attribute\n */\nfunction parseNoteType(\n typeAttr: string | null\n): 'normal' | 'separator' | 'continuationSeparator' | 'continuationNotice' {\n switch (typeAttr) {\n case 'separator':\n return 'separator';\n case 'continuationSeparator':\n return 'continuationSeparator';\n case 'continuationNotice':\n return 'continuationNotice';\n default:\n return 'normal';\n }\n}\n\n// ============================================================================\n// FOOTNOTE PARSING\n// ============================================================================\n\n/**\n * Parse a single footnote element (w:footnote)\n */\nfunction parseFootnote(\n element: XmlElement,\n styles: StyleMap | null,\n theme: Theme | null,\n numbering: NumberingMap | null,\n rels: RelationshipMap | null,\n _media: Map<string, MediaFile> | null\n): Footnote {\n const id = parseNumericAttribute(element, 'w', 'id') ?? 0;\n const typeAttr = getAttribute(element, 'w', 'type');\n const noteType = parseNoteType(typeAttr);\n\n // Parse content paragraphs\n const paragraphElements = findChildren(element, 'w', 'p');\n const content: Paragraph[] = paragraphElements.map((pEl) =>\n parseParagraph(pEl, styles, theme, numbering, rels)\n );\n\n return {\n type: 'footnote',\n id,\n noteType,\n content,\n };\n}\n\n/**\n * Parse footnotes.xml\n *\n * @param footnotesXml - The raw XML content of word/footnotes.xml\n * @param styles - Parsed style map for applying styles\n * @param theme - Parsed theme for color resolution\n * @param numbering - Parsed numbering definitions for lists\n * @param rels - Relationships for resolving hyperlinks\n * @param media - Media files for images\n * @returns FootnoteMap with all footnotes\n */\nexport function parseFootnotes(\n footnotesXml: string | null,\n styles: StyleMap | null = null,\n theme: Theme | null = null,\n numbering: NumberingMap | null = null,\n rels: RelationshipMap | null = null,\n media: Map<string, MediaFile> | null = null\n): FootnoteMap {\n const byId = new Map<number, Footnote>();\n const footnotes: Footnote[] = [];\n\n if (!footnotesXml) {\n return createFootnoteMap(byId, footnotes);\n }\n\n const doc = parseXml(footnotesXml);\n if (!doc) {\n return createFootnoteMap(byId, footnotes);\n }\n\n // Find the root footnotes element\n const rootElement = doc.elements?.find(\n (el: XmlElement) =>\n el.type === 'element' && (el.name === 'w:footnotes' || el.name?.endsWith(':footnotes'))\n ) as XmlElement | undefined;\n\n if (!rootElement) {\n return createFootnoteMap(byId, footnotes);\n }\n\n // Parse all footnote elements\n const footnoteElements = findChildren(rootElement, 'w', 'footnote');\n\n for (const fnEl of footnoteElements) {\n const footnote = parseFootnote(fnEl, styles, theme, numbering, rels, media);\n byId.set(footnote.id, footnote);\n footnotes.push(footnote);\n }\n\n return createFootnoteMap(byId, footnotes);\n}\n\n/**\n * Create FootnoteMap object with helper methods\n */\nfunction createFootnoteMap(byId: Map<number, Footnote>, footnotes: Footnote[]): FootnoteMap {\n return {\n byId,\n footnotes,\n\n getFootnote(id: number): Footnote | undefined {\n return byId.get(id);\n },\n\n hasFootnote(id: number): boolean {\n return byId.has(id);\n },\n\n getNormalFootnotes(): Footnote[] {\n return footnotes.filter((fn) => fn.noteType === 'normal');\n },\n\n getSeparator(): Footnote | undefined {\n return footnotes.find((fn) => fn.noteType === 'separator');\n },\n\n getContinuationSeparator(): Footnote | undefined {\n return footnotes.find((fn) => fn.noteType === 'continuationSeparator');\n },\n };\n}\n\n// ============================================================================\n// ENDNOTE PARSING\n// ============================================================================\n\n/**\n * Parse a single endnote element (w:endnote)\n */\nfunction parseEndnote(\n element: XmlElement,\n styles: StyleMap | null,\n theme: Theme | null,\n numbering: NumberingMap | null,\n rels: RelationshipMap | null,\n _media: Map<string, MediaFile> | null\n): Endnote {\n const id = parseNumericAttribute(element, 'w', 'id') ?? 0;\n const typeAttr = getAttribute(element, 'w', 'type');\n const noteType = parseNoteType(typeAttr);\n\n // Parse content paragraphs\n const paragraphElements = findChildren(element, 'w', 'p');\n const content: Paragraph[] = paragraphElements.map((pEl) =>\n parseParagraph(pEl, styles, theme, numbering, rels)\n );\n\n return {\n type: 'endnote',\n id,\n noteType,\n content,\n };\n}\n\n/**\n * Parse endnotes.xml\n *\n * @param endnotesXml - The raw XML content of word/endnotes.xml\n * @param styles - Parsed style map for applying styles\n * @param theme - Parsed theme for color resolution\n * @param numbering - Parsed numbering definitions for lists\n * @param rels - Relationships for resolving hyperlinks\n * @param media - Media files for images\n * @returns EndnoteMap with all endnotes\n */\nexport function parseEndnotes(\n endnotesXml: string | null,\n styles: StyleMap | null = null,\n theme: Theme | null = null,\n numbering: NumberingMap | null = null,\n rels: RelationshipMap | null = null,\n media: Map<string, MediaFile> | null = null\n): EndnoteMap {\n const byId = new Map<number, Endnote>();\n const endnotes: Endnote[] = [];\n\n if (!endnotesXml) {\n return createEndnoteMap(byId, endnotes);\n }\n\n const doc = parseXml(endnotesXml);\n if (!doc) {\n return createEndnoteMap(byId, endnotes);\n }\n\n // Find the root endnotes element\n const rootElement = doc.elements?.find(\n (el: XmlElement) =>\n el.type === 'element' && (el.name === 'w:endnotes' || el.name?.endsWith(':endnotes'))\n ) as XmlElement | undefined;\n\n if (!rootElement) {\n return createEndnoteMap(byId, endnotes);\n }\n\n // Parse all endnote elements\n const endnoteElements = findChildren(rootElement, 'w', 'endnote');\n\n for (const enEl of endnoteElements) {\n const endnote = parseEndnote(enEl, styles, theme, numbering, rels, media);\n byId.set(endnote.id, endnote);\n endnotes.push(endnote);\n }\n\n return createEndnoteMap(byId, endnotes);\n}\n\n/**\n * Create EndnoteMap object with helper methods\n */\nfunction createEndnoteMap(byId: Map<number, Endnote>, endnotes: Endnote[]): EndnoteMap {\n return {\n byId,\n endnotes,\n\n getEndnote(id: number): Endnote | undefined {\n return byId.get(id);\n },\n\n hasEndnote(id: number): boolean {\n return byId.has(id);\n },\n\n getNormalEndnotes(): Endnote[] {\n return endnotes.filter((en) => en.noteType === 'normal');\n },\n\n getSeparator(): Endnote | undefined {\n return endnotes.find((en) => en.noteType === 'separator');\n },\n\n getContinuationSeparator(): Endnote | undefined {\n return endnotes.find((en) => en.noteType === 'continuationSeparator');\n },\n };\n}\n\n// ============================================================================\n// FOOTNOTE/ENDNOTE PROPERTIES PARSING\n// ============================================================================\n\n/**\n * Parse number format from w:numFmt element\n */\nfunction parseNumberFormat(numFmtAttr: string | null): NumberFormat | undefined {\n if (!numFmtAttr) return undefined;\n\n // Map OOXML numFmt values to our NumberFormat type\n const formatMap: Record<string, NumberFormat> = {\n decimal: 'decimal',\n upperRoman: 'upperRoman',\n lowerRoman: 'lowerRoman',\n upperLetter: 'upperLetter',\n lowerLetter: 'lowerLetter',\n ordinal: 'ordinal',\n cardinalText: 'cardinalText',\n ordinalText: 'ordinalText',\n bullet: 'bullet',\n chicago: 'chicago',\n none: 'none',\n };\n\n return formatMap[numFmtAttr] as NumberFormat | undefined;\n}\n\n/**\n * Parse footnote position\n */\nfunction parseFootnotePosition(posAttr: string | null): FootnotePosition | undefined {\n switch (posAttr) {\n case 'pageBottom':\n return 'pageBottom';\n case 'beneathText':\n return 'beneathText';\n case 'sectEnd':\n return 'sectEnd';\n case 'docEnd':\n return 'docEnd';\n default:\n return undefined;\n }\n}\n\n/**\n * Parse endnote position\n */\nfunction parseEndnotePosition(posAttr: string | null): EndnotePosition | undefined {\n switch (posAttr) {\n case 'sectEnd':\n return 'sectEnd';\n case 'docEnd':\n return 'docEnd';\n default:\n return undefined;\n }\n}\n\n/**\n * Parse number restart type\n */\nfunction parseNumberRestart(restartAttr: string | null): NoteNumberRestart | undefined {\n switch (restartAttr) {\n case 'continuous':\n return 'continuous';\n case 'eachSect':\n return 'eachSect';\n case 'eachPage':\n return 'eachPage';\n default:\n return undefined;\n }\n}\n\n/**\n * Parse footnote properties from w:footnotePr element\n * (Can appear in w:sectPr or w:settings)\n */\nexport function parseFootnoteProperties(element: XmlElement | null): FootnoteProperties {\n const props: FootnoteProperties = {};\n\n if (!element) return props;\n\n // Position (w:pos)\n const posEl = findChild(element, 'w', 'pos');\n if (posEl) {\n const posAttr = getAttribute(posEl, 'w', 'val');\n props.position = parseFootnotePosition(posAttr);\n }\n\n // Number format (w:numFmt)\n const numFmtEl = findChild(element, 'w', 'numFmt');\n if (numFmtEl) {\n const fmtAttr = getAttribute(numFmtEl, 'w', 'val');\n props.numFmt = parseNumberFormat(fmtAttr);\n }\n\n // Start number (w:numStart)\n const numStartEl = findChild(element, 'w', 'numStart');\n if (numStartEl) {\n props.numStart = parseNumericAttribute(numStartEl, 'w', 'val') ?? undefined;\n }\n\n // Number restart (w:numRestart)\n const numRestartEl = findChild(element, 'w', 'numRestart');\n if (numRestartEl) {\n const restartAttr = getAttribute(numRestartEl, 'w', 'val');\n props.numRestart = parseNumberRestart(restartAttr);\n }\n\n return props;\n}\n\n/**\n * Parse endnote properties from w:endnotePr element\n * (Can appear in w:sectPr or w:settings)\n */\nexport function parseEndnoteProperties(element: XmlElement | null): EndnoteProperties {\n const props: EndnoteProperties = {};\n\n if (!element) return props;\n\n // Position (w:pos)\n const posEl = findChild(element, 'w', 'pos');\n if (posEl) {\n const posAttr = getAttribute(posEl, 'w', 'val');\n props.position = parseEndnotePosition(posAttr);\n }\n\n // Number format (w:numFmt)\n const numFmtEl = findChild(element, 'w', 'numFmt');\n if (numFmtEl) {\n const fmtAttr = getAttribute(numFmtEl, 'w', 'val');\n props.numFmt = parseNumberFormat(fmtAttr);\n }\n\n // Start number (w:numStart)\n const numStartEl = findChild(element, 'w', 'numStart');\n if (numStartEl) {\n props.numStart = parseNumericAttribute(numStartEl, 'w', 'val') ?? undefined;\n }\n\n // Number restart (w:numRestart)\n const numRestartEl = findChild(element, 'w', 'numRestart');\n if (numRestartEl) {\n const restartAttr = getAttribute(numRestartEl, 'w', 'val');\n props.numRestart = parseNumberRestart(restartAttr);\n }\n\n return props;\n}\n\n// ============================================================================\n// UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Get plain text content of a footnote\n */\nexport function getFootnoteText(footnote: Footnote): string {\n // Import getParagraphText dynamically to avoid circular dependency\n const texts: string[] = [];\n\n for (const para of footnote.content) {\n const paraTexts: string[] = [];\n for (const content of para.content) {\n if (content.type === 'run') {\n for (const runContent of content.content) {\n if (runContent.type === 'text') {\n paraTexts.push(runContent.text);\n }\n }\n }\n }\n texts.push(paraTexts.join(''));\n }\n\n return texts.join('\\n');\n}\n\n/**\n * Get plain text content of an endnote\n */\nexport function getEndnoteText(endnote: Endnote): string {\n const texts: string[] = [];\n\n for (const para of endnote.content) {\n const paraTexts: string[] = [];\n for (const content of para.content) {\n if (content.type === 'run') {\n for (const runContent of content.content) {\n if (runContent.type === 'text') {\n paraTexts.push(runContent.text);\n }\n }\n }\n }\n texts.push(paraTexts.join(''));\n }\n\n return texts.join('\\n');\n}\n\n/**\n * Check if a footnote is a separator (not regular content)\n */\nexport function isSeparatorFootnote(footnote: Footnote): boolean {\n return (\n footnote.noteType === 'separator' ||\n footnote.noteType === 'continuationSeparator' ||\n footnote.noteType === 'continuationNotice'\n );\n}\n\n/**\n * Check if an endnote is a separator (not regular content)\n */\nexport function isSeparatorEndnote(endnote: Endnote): boolean {\n return (\n endnote.noteType === 'separator' ||\n endnote.noteType === 'continuationSeparator' ||\n endnote.noteType === 'continuationNotice'\n );\n}\n\n/**\n * Get footnote number for display (excluding separators)\n * @param footnote - The footnote to get the number for\n * @param footnoteMap - The footnote map\n * @param startNumber - Starting number (default 1)\n * @returns The display number, or null for separator footnotes\n */\nexport function getFootnoteDisplayNumber(\n footnote: Footnote,\n footnoteMap: FootnoteMap,\n startNumber: number = 1\n): number | null {\n if (isSeparatorFootnote(footnote)) {\n return null;\n }\n\n const normalFootnotes = footnoteMap.getNormalFootnotes();\n const index = normalFootnotes.findIndex((fn) => fn.id === footnote.id);\n\n if (index === -1) {\n return null;\n }\n\n return startNumber + index;\n}\n\n/**\n * Get endnote number for display (excluding separators)\n * @param endnote - The endnote to get the number for\n * @param endnoteMap - The endnote map\n * @param startNumber - Starting number (default 1)\n * @returns The display number, or null for separator endnotes\n */\nexport function getEndnoteDisplayNumber(\n endnote: Endnote,\n endnoteMap: EndnoteMap,\n startNumber: number = 1\n): number | null {\n if (isSeparatorEndnote(endnote)) {\n return null;\n }\n\n const normalEndnotes = endnoteMap.getNormalEndnotes();\n const index = normalEndnotes.findIndex((en) => en.id === endnote.id);\n\n if (index === -1) {\n return null;\n }\n\n return startNumber + index;\n}\n\n/**\n * Create an empty footnote map\n */\nexport function createEmptyFootnoteMap(): FootnoteMap {\n return createFootnoteMap(new Map(), []);\n}\n\n/**\n * Create an empty endnote map\n */\nexport function createEmptyEndnoteMap(): EndnoteMap {\n return createEndnoteMap(new Map(), []);\n}\n\n/**\n * Merge multiple footnote maps (e.g., from different documents)\n */\nexport function mergeFootnoteMaps(...maps: FootnoteMap[]): FootnoteMap {\n const byId = new Map<number, Footnote>();\n const footnotes: Footnote[] = [];\n\n for (const map of maps) {\n for (const fn of map.footnotes) {\n if (!byId.has(fn.id)) {\n byId.set(fn.id, fn);\n footnotes.push(fn);\n }\n }\n }\n\n return createFootnoteMap(byId, footnotes);\n}\n\n/**\n * Merge multiple endnote maps (e.g., from different documents)\n */\nexport function mergeEndnoteMaps(...maps: EndnoteMap[]): EndnoteMap {\n const byId = new Map<number, Endnote>();\n const endnotes: Endnote[] = [];\n\n for (const map of maps) {\n for (const en of map.endnotes) {\n if (!byId.has(en.id)) {\n byId.set(en.id, en);\n endnotes.push(en);\n }\n }\n }\n\n return createEndnoteMap(byId, endnotes);\n}\n","/**\n * Section Properties Parser - Parse section properties (w:sectPr)\n *\n * Section properties define page layout and settings for a section of the document.\n * They appear in two places:\n * 1. Within a paragraph's properties (w:p/w:pPr/w:sectPr) - marks end of a section\n * 2. At the end of the document body (w:body/w:sectPr) - final section properties\n *\n * OOXML Reference:\n * - w:pgSz: Page size (width, height, orientation)\n * - w:pgMar: Page margins (top, bottom, left, right, header, footer, gutter)\n * - w:cols: Column definitions\n * - w:type: Section start type\n * - w:vAlign: Vertical alignment\n * - w:headerReference, w:footerReference: Header/footer references\n * - w:titlePg: Different first page\n * - w:lnNumType: Line numbering\n * - w:pgBorders: Page borders\n * - w:docGrid: Document grid\n * - w:footnotePr, w:endnotePr: Footnote/endnote properties\n */\n\nimport type {\n SectionProperties,\n PageOrientation,\n SectionStart,\n VerticalAlign,\n LineNumberRestart,\n Column,\n BorderSpec,\n ColorValue,\n ThemeColorSlot,\n RelationshipMap,\n} from '../types/document';\nimport {\n findChild,\n findChildren,\n getAttribute,\n parseNumericAttribute,\n parseBooleanElement,\n type XmlElement,\n} from './xmlParser';\nimport { parseHeaderReference, parseFooterReference } from './headerFooterParser';\nimport { parseFootnoteProperties, parseEndnoteProperties } from './footnoteParser';\n\n// ============================================================================\n// HELPER PARSERS\n// ============================================================================\n\n/**\n * Parse a color element/attribute for page borders/background\n */\nfunction parseColorValue(\n colorStr: string | null,\n themeColor: string | null,\n themeTint: string | null,\n themeShade: string | null\n): ColorValue | undefined {\n if (!colorStr && !themeColor) return undefined;\n\n const color: ColorValue = {};\n\n if (colorStr && colorStr !== 'auto') {\n color.rgb = colorStr;\n } else if (colorStr === 'auto') {\n color.auto = true;\n }\n\n if (themeColor) {\n color.themeColor = themeColor as ThemeColorSlot;\n }\n if (themeTint) {\n color.themeTint = themeTint;\n }\n if (themeShade) {\n color.themeShade = themeShade;\n }\n\n return Object.keys(color).length > 0 ? color : undefined;\n}\n\n/**\n * Parse a border element for page borders\n */\nfunction parseBorderSpec(element: XmlElement | null): BorderSpec | undefined {\n if (!element) return undefined;\n\n const styleStr = getAttribute(element, 'w', 'val') ?? 'none';\n const style = styleStr as BorderSpec['style'];\n\n const border: BorderSpec = { style };\n\n // Size in eighths of a point\n const sz = parseNumericAttribute(element, 'w', 'sz');\n if (sz !== undefined) {\n border.size = sz;\n }\n\n // Space from text/page edge in points\n const space = parseNumericAttribute(element, 'w', 'space');\n if (space !== undefined) {\n border.space = space;\n }\n\n // Color\n const colorVal = getAttribute(element, 'w', 'color');\n const themeColor = getAttribute(element, 'w', 'themeColor');\n const themeTint = getAttribute(element, 'w', 'themeTint');\n const themeShade = getAttribute(element, 'w', 'themeShade');\n const color = parseColorValue(colorVal, themeColor, themeTint, themeShade);\n if (color) {\n border.color = color;\n }\n\n // Shadow effect\n const shadow = getAttribute(element, 'w', 'shadow');\n if (shadow === '1' || shadow === 'true') {\n border.shadow = true;\n }\n\n // Frame effect\n const frame = getAttribute(element, 'w', 'frame');\n if (frame === '1' || frame === 'true') {\n border.frame = true;\n }\n\n return border;\n}\n\n/**\n * Parse page orientation\n */\nfunction parseOrientation(orient: string | null): PageOrientation | undefined {\n switch (orient) {\n case 'landscape':\n return 'landscape';\n case 'portrait':\n return 'portrait';\n default:\n return undefined;\n }\n}\n\n/**\n * Parse section start type\n */\nfunction parseSectionStart(type: string | null): SectionStart | undefined {\n switch (type) {\n case 'continuous':\n return 'continuous';\n case 'nextPage':\n return 'nextPage';\n case 'oddPage':\n return 'oddPage';\n case 'evenPage':\n return 'evenPage';\n case 'nextColumn':\n return 'nextColumn';\n default:\n return undefined;\n }\n}\n\n/**\n * Parse vertical alignment\n */\nfunction parseVerticalAlign(align: string | null): VerticalAlign | undefined {\n switch (align) {\n case 'top':\n return 'top';\n case 'center':\n return 'center';\n case 'both':\n return 'both';\n case 'bottom':\n return 'bottom';\n default:\n return undefined;\n }\n}\n\n/**\n * Parse line number restart type\n */\nfunction parseLineNumberRestart(restart: string | null): LineNumberRestart | undefined {\n switch (restart) {\n case 'continuous':\n return 'continuous';\n case 'newPage':\n return 'newPage';\n case 'newSection':\n return 'newSection';\n default:\n return undefined;\n }\n}\n\n// ============================================================================\n// MAIN PARSER\n// ============================================================================\n\n/**\n * Parse section properties (w:sectPr)\n *\n * @param sectPr - The w:sectPr element\n * @param rels - Optional relationships for resolving header/footer references\n * @returns SectionProperties object\n */\nexport function parseSectionProperties(\n sectPr: XmlElement | null,\n _rels?: RelationshipMap | null\n): SectionProperties {\n const props: SectionProperties = {};\n\n if (!sectPr) return props;\n\n // ============================================================================\n // PAGE SIZE (w:pgSz)\n // ============================================================================\n const pgSz = findChild(sectPr, 'w', 'pgSz');\n if (pgSz) {\n // Width in twips\n const w = parseNumericAttribute(pgSz, 'w', 'w');\n if (w !== undefined) {\n props.pageWidth = w;\n }\n\n // Height in twips\n const h = parseNumericAttribute(pgSz, 'w', 'h');\n if (h !== undefined) {\n props.pageHeight = h;\n }\n\n // Orientation\n const orient = getAttribute(pgSz, 'w', 'orient');\n const orientation = parseOrientation(orient);\n if (orientation) {\n props.orientation = orientation;\n }\n }\n\n // ============================================================================\n // PAGE MARGINS (w:pgMar)\n // ============================================================================\n const pgMar = findChild(sectPr, 'w', 'pgMar');\n if (pgMar) {\n // Top margin in twips\n const top = parseNumericAttribute(pgMar, 'w', 'top');\n if (top !== undefined) {\n props.marginTop = top;\n }\n\n // Bottom margin in twips\n const bottom = parseNumericAttribute(pgMar, 'w', 'bottom');\n if (bottom !== undefined) {\n props.marginBottom = bottom;\n }\n\n // Left margin in twips\n const left = parseNumericAttribute(pgMar, 'w', 'left');\n if (left !== undefined) {\n props.marginLeft = left;\n }\n\n // Right margin in twips\n const right = parseNumericAttribute(pgMar, 'w', 'right');\n if (right !== undefined) {\n props.marginRight = right;\n }\n\n // Header distance from top in twips\n const header = parseNumericAttribute(pgMar, 'w', 'header');\n if (header !== undefined) {\n props.headerDistance = header;\n }\n\n // Footer distance from bottom in twips\n const footer = parseNumericAttribute(pgMar, 'w', 'footer');\n if (footer !== undefined) {\n props.footerDistance = footer;\n }\n\n // Gutter margin in twips\n const gutter = parseNumericAttribute(pgMar, 'w', 'gutter');\n if (gutter !== undefined) {\n props.gutter = gutter;\n }\n }\n\n // ============================================================================\n // COLUMNS (w:cols)\n // ============================================================================\n const cols = findChild(sectPr, 'w', 'cols');\n if (cols) {\n // Number of columns\n const num = parseNumericAttribute(cols, 'w', 'num');\n if (num !== undefined) {\n props.columnCount = num;\n }\n\n // Space between columns in twips\n const space = parseNumericAttribute(cols, 'w', 'space');\n if (space !== undefined) {\n props.columnSpace = space;\n }\n\n // Equal width\n const equalWidth = getAttribute(cols, 'w', 'equalWidth');\n if (equalWidth === '1' || equalWidth === 'true') {\n props.equalWidth = true;\n } else if (equalWidth === '0' || equalWidth === 'false') {\n props.equalWidth = false;\n }\n\n // Separator line between columns\n const sep = getAttribute(cols, 'w', 'sep');\n if (sep === '1' || sep === 'true') {\n props.separator = true;\n }\n\n // Individual column definitions (w:col)\n const colElements = findChildren(cols, 'w', 'col');\n if (colElements.length > 0) {\n props.columns = [];\n for (const colEl of colElements) {\n const column: Column = {};\n\n const colWidth = parseNumericAttribute(colEl, 'w', 'w');\n if (colWidth !== undefined) {\n column.width = colWidth;\n }\n\n const colSpace = parseNumericAttribute(colEl, 'w', 'space');\n if (colSpace !== undefined) {\n column.space = colSpace;\n }\n\n props.columns.push(column);\n }\n\n // Infer column count from w:col entries when w:num is absent\n if (props.columnCount === undefined) {\n props.columnCount = colElements.length;\n }\n }\n }\n\n // ============================================================================\n // SECTION TYPE (w:type)\n // ============================================================================\n const typeEl = findChild(sectPr, 'w', 'type');\n if (typeEl) {\n const val = getAttribute(typeEl, 'w', 'val');\n const sectionStart = parseSectionStart(val);\n if (sectionStart) {\n props.sectionStart = sectionStart;\n }\n }\n\n // ============================================================================\n // VERTICAL ALIGNMENT (w:vAlign)\n // ============================================================================\n const vAlign = findChild(sectPr, 'w', 'vAlign');\n if (vAlign) {\n const val = getAttribute(vAlign, 'w', 'val');\n const verticalAlign = parseVerticalAlign(val);\n if (verticalAlign) {\n props.verticalAlign = verticalAlign;\n }\n }\n\n // ============================================================================\n // BIDIRECTIONAL (w:bidi)\n // ============================================================================\n const bidi = findChild(sectPr, 'w', 'bidi');\n if (bidi) {\n props.bidi = parseBooleanElement(bidi);\n }\n\n // ============================================================================\n // HEADER REFERENCES (w:headerReference)\n // ============================================================================\n const headerRefs = findChildren(sectPr, 'w', 'headerReference');\n if (headerRefs.length > 0) {\n props.headerReferences = headerRefs.map((el) => parseHeaderReference(el));\n }\n\n // ============================================================================\n // FOOTER REFERENCES (w:footerReference)\n // ============================================================================\n const footerRefs = findChildren(sectPr, 'w', 'footerReference');\n if (footerRefs.length > 0) {\n props.footerReferences = footerRefs.map((el) => parseFooterReference(el));\n }\n\n // ============================================================================\n // TITLE PAGE / DIFFERENT FIRST PAGE (w:titlePg)\n // ============================================================================\n const titlePg = findChild(sectPr, 'w', 'titlePg');\n if (titlePg) {\n props.titlePg = parseBooleanElement(titlePg);\n }\n\n // ============================================================================\n // DIFFERENT ODD/EVEN HEADERS (w:evenAndOddHeaders)\n // Note: This is typically in settings.xml, but can also be in sectPr\n // ============================================================================\n const evenAndOddHeaders = findChild(sectPr, 'w', 'evenAndOddHeaders');\n if (evenAndOddHeaders) {\n props.evenAndOddHeaders = parseBooleanElement(evenAndOddHeaders);\n }\n\n // ============================================================================\n // LINE NUMBERS (w:lnNumType)\n // ============================================================================\n const lnNumType = findChild(sectPr, 'w', 'lnNumType');\n if (lnNumType) {\n props.lineNumbers = {};\n\n const start = parseNumericAttribute(lnNumType, 'w', 'start');\n if (start !== undefined) {\n props.lineNumbers.start = start;\n }\n\n const countBy = parseNumericAttribute(lnNumType, 'w', 'countBy');\n if (countBy !== undefined) {\n props.lineNumbers.countBy = countBy;\n }\n\n const distance = parseNumericAttribute(lnNumType, 'w', 'distance');\n if (distance !== undefined) {\n props.lineNumbers.distance = distance;\n }\n\n const restart = getAttribute(lnNumType, 'w', 'restart');\n const restartValue = parseLineNumberRestart(restart);\n if (restartValue) {\n props.lineNumbers.restart = restartValue;\n }\n }\n\n // ============================================================================\n // PAGE BORDERS (w:pgBorders)\n // ============================================================================\n const pgBorders = findChild(sectPr, 'w', 'pgBorders');\n if (pgBorders) {\n props.pageBorders = {};\n\n // Top border\n const topBorder = parseBorderSpec(findChild(pgBorders, 'w', 'top'));\n if (topBorder) {\n props.pageBorders.top = topBorder;\n }\n\n // Bottom border\n const bottomBorder = parseBorderSpec(findChild(pgBorders, 'w', 'bottom'));\n if (bottomBorder) {\n props.pageBorders.bottom = bottomBorder;\n }\n\n // Left border\n const leftBorder = parseBorderSpec(findChild(pgBorders, 'w', 'left'));\n if (leftBorder) {\n props.pageBorders.left = leftBorder;\n }\n\n // Right border\n const rightBorder = parseBorderSpec(findChild(pgBorders, 'w', 'right'));\n if (rightBorder) {\n props.pageBorders.right = rightBorder;\n }\n\n // Display setting (allPages, firstPage, notFirstPage)\n const display = getAttribute(pgBorders, 'w', 'display');\n if (display === 'allPages' || display === 'firstPage' || display === 'notFirstPage') {\n props.pageBorders.display = display;\n }\n\n // Offset from (page or text)\n const offsetFrom = getAttribute(pgBorders, 'w', 'offsetFrom');\n if (offsetFrom === 'page' || offsetFrom === 'text') {\n props.pageBorders.offsetFrom = offsetFrom;\n }\n\n // Z-order (front or back)\n const zOrder = getAttribute(pgBorders, 'w', 'zOrder');\n if (zOrder === 'front' || zOrder === 'back') {\n props.pageBorders.zOrder = zOrder;\n }\n }\n\n // ============================================================================\n // PAGE BACKGROUND (w:background)\n // Note: Background is usually at document level, but checking here too\n // ============================================================================\n const background = findChild(sectPr, 'w', 'background');\n if (background) {\n props.background = {};\n\n const colorVal = getAttribute(background, 'w', 'color');\n if (colorVal && colorVal !== 'auto') {\n props.background.color = { rgb: colorVal };\n }\n\n const themeColor = getAttribute(background, 'w', 'themeColor');\n if (themeColor) {\n props.background.themeColor = themeColor as ThemeColorSlot;\n }\n\n const themeTint = getAttribute(background, 'w', 'themeTint');\n if (themeTint) {\n props.background.themeTint = themeTint;\n }\n\n const themeShade = getAttribute(background, 'w', 'themeShade');\n if (themeShade) {\n props.background.themeShade = themeShade;\n }\n }\n\n // ============================================================================\n // FOOTNOTE PROPERTIES (w:footnotePr)\n // ============================================================================\n const footnotePr = findChild(sectPr, 'w', 'footnotePr');\n if (footnotePr) {\n const fnProps = parseFootnoteProperties(footnotePr);\n if (Object.keys(fnProps).length > 0) {\n props.footnotePr = fnProps;\n }\n }\n\n // ============================================================================\n // ENDNOTE PROPERTIES (w:endnotePr)\n // ============================================================================\n const endnotePr = findChild(sectPr, 'w', 'endnotePr');\n if (endnotePr) {\n const enProps = parseEndnoteProperties(endnotePr);\n if (Object.keys(enProps).length > 0) {\n props.endnotePr = enProps;\n }\n }\n\n // ============================================================================\n // DOCUMENT GRID (w:docGrid)\n // ============================================================================\n const docGrid = findChild(sectPr, 'w', 'docGrid');\n if (docGrid) {\n props.docGrid = {};\n\n const gridType = getAttribute(docGrid, 'w', 'type');\n if (\n gridType === 'default' ||\n gridType === 'lines' ||\n gridType === 'linesAndChars' ||\n gridType === 'snapToChars'\n ) {\n props.docGrid.type = gridType;\n }\n\n const linePitch = parseNumericAttribute(docGrid, 'w', 'linePitch');\n if (linePitch !== undefined) {\n props.docGrid.linePitch = linePitch;\n }\n\n const charSpace = parseNumericAttribute(docGrid, 'w', 'charSpace');\n if (charSpace !== undefined) {\n props.docGrid.charSpace = charSpace;\n }\n }\n\n // ============================================================================\n // PAPER SOURCE (w:paperSrc)\n // ============================================================================\n const paperSrc = findChild(sectPr, 'w', 'paperSrc');\n if (paperSrc) {\n const first = parseNumericAttribute(paperSrc, 'w', 'first');\n if (first !== undefined) {\n props.paperSrcFirst = first;\n }\n\n const other = parseNumericAttribute(paperSrc, 'w', 'other');\n if (other !== undefined) {\n props.paperSrcOther = other;\n }\n }\n\n return props;\n}\n\n// ============================================================================\n// UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Get page width in pixels (96 DPI)\n *\n * @param props - Section properties\n * @param defaultWidth - Default width in twips (default: 12240 = 8.5 inches)\n * @returns Width in pixels\n */\nexport function getPageWidthPixels(props: SectionProperties, defaultWidth: number = 12240): number {\n const twips = props.pageWidth ?? defaultWidth;\n // 1 inch = 1440 twips, 1 inch = 96 pixels at 96 DPI\n return Math.round((twips / 1440) * 96);\n}\n\n/**\n * Get page height in pixels (96 DPI)\n *\n * @param props - Section properties\n * @param defaultHeight - Default height in twips (default: 15840 = 11 inches)\n * @returns Height in pixels\n */\nexport function getPageHeightPixels(\n props: SectionProperties,\n defaultHeight: number = 15840\n): number {\n const twips = props.pageHeight ?? defaultHeight;\n return Math.round((twips / 1440) * 96);\n}\n\n/**\n * Get content width (page width minus margins) in pixels\n *\n * @param props - Section properties\n * @returns Content width in pixels\n */\nexport function getContentWidthPixels(props: SectionProperties): number {\n const pageWidth = props.pageWidth ?? 12240;\n const marginLeft = props.marginLeft ?? 1440; // 1 inch default\n const marginRight = props.marginRight ?? 1440;\n const twips = pageWidth - marginLeft - marginRight;\n return Math.round((twips / 1440) * 96);\n}\n\n/**\n * Get content height (page height minus margins) in pixels\n *\n * @param props - Section properties\n * @returns Content height in pixels\n */\nexport function getContentHeightPixels(props: SectionProperties): number {\n const pageHeight = props.pageHeight ?? 15840;\n const marginTop = props.marginTop ?? 1440;\n const marginBottom = props.marginBottom ?? 1440;\n const twips = pageHeight - marginTop - marginBottom;\n return Math.round((twips / 1440) * 96);\n}\n\n/**\n * Get margins in pixels\n *\n * @param props - Section properties\n * @returns Object with all margins in pixels\n */\nexport function getMarginsPixels(props: SectionProperties): {\n top: number;\n bottom: number;\n left: number;\n right: number;\n header: number;\n footer: number;\n gutter: number;\n} {\n const twipsToPixels = (twips: number | undefined, defaultTwips: number) => {\n return Math.round(((twips ?? defaultTwips) / 1440) * 96);\n };\n\n return {\n top: twipsToPixels(props.marginTop, 1440),\n bottom: twipsToPixels(props.marginBottom, 1440),\n left: twipsToPixels(props.marginLeft, 1440),\n right: twipsToPixels(props.marginRight, 1440),\n header: twipsToPixels(props.headerDistance, 720), // 0.5 inch default\n footer: twipsToPixels(props.footerDistance, 720),\n gutter: twipsToPixels(props.gutter, 0),\n };\n}\n\n/**\n * Check if section has different first page header/footer\n */\nexport function hasDifferentFirstPage(props: SectionProperties): boolean {\n return props.titlePg === true;\n}\n\n/**\n * Check if section has different odd/even page headers/footers\n */\nexport function hasDifferentOddEven(props: SectionProperties): boolean {\n return props.evenAndOddHeaders === true;\n}\n\n/**\n * Get effective column count (minimum 1)\n */\nexport function getColumnCount(props: SectionProperties): number {\n return Math.max(1, props.columnCount ?? 1);\n}\n\n/**\n * Check if section is landscape\n */\nexport function isLandscape(props: SectionProperties): boolean {\n return props.orientation === 'landscape';\n}\n\n/**\n * Check if section has page borders\n */\nexport function hasPageBorders(props: SectionProperties): boolean {\n if (!props.pageBorders) return false;\n return !!(\n props.pageBorders.top ||\n props.pageBorders.bottom ||\n props.pageBorders.left ||\n props.pageBorders.right\n );\n}\n\n/**\n * Check if section has line numbers\n */\nexport function hasLineNumbers(props: SectionProperties): boolean {\n return !!props.lineNumbers;\n}\n\n/**\n * Get default section properties (US Letter size, 1 inch margins)\n */\nexport function getDefaultSectionProperties(): SectionProperties {\n return {\n pageWidth: 12240, // 8.5 inches\n pageHeight: 15840, // 11 inches\n orientation: 'portrait',\n marginTop: 1440, // 1 inch\n marginBottom: 1440,\n marginLeft: 1440,\n marginRight: 1440,\n headerDistance: 720, // 0.5 inch\n footerDistance: 720,\n gutter: 0,\n columnCount: 1,\n columnSpace: 720, // 0.5 inch\n equalWidth: true,\n sectionStart: 'nextPage',\n verticalAlign: 'top',\n };\n}\n\n/**\n * Merge section properties (later values override earlier)\n *\n * @param base - Base properties\n * @param override - Override properties\n * @returns Merged properties\n */\nexport function mergeSectionProperties(\n base: SectionProperties,\n override: SectionProperties\n): SectionProperties {\n const result: SectionProperties = { ...base };\n\n // Simple properties - override if present\n if (override.pageWidth !== undefined) result.pageWidth = override.pageWidth;\n if (override.pageHeight !== undefined) result.pageHeight = override.pageHeight;\n if (override.orientation !== undefined) result.orientation = override.orientation;\n if (override.marginTop !== undefined) result.marginTop = override.marginTop;\n if (override.marginBottom !== undefined) result.marginBottom = override.marginBottom;\n if (override.marginLeft !== undefined) result.marginLeft = override.marginLeft;\n if (override.marginRight !== undefined) result.marginRight = override.marginRight;\n if (override.headerDistance !== undefined) result.headerDistance = override.headerDistance;\n if (override.footerDistance !== undefined) result.footerDistance = override.footerDistance;\n if (override.gutter !== undefined) result.gutter = override.gutter;\n if (override.columnCount !== undefined) result.columnCount = override.columnCount;\n if (override.columnSpace !== undefined) result.columnSpace = override.columnSpace;\n if (override.equalWidth !== undefined) result.equalWidth = override.equalWidth;\n if (override.separator !== undefined) result.separator = override.separator;\n if (override.columns !== undefined) result.columns = override.columns;\n if (override.sectionStart !== undefined) result.sectionStart = override.sectionStart;\n if (override.verticalAlign !== undefined) result.verticalAlign = override.verticalAlign;\n if (override.bidi !== undefined) result.bidi = override.bidi;\n if (override.headerReferences !== undefined) result.headerReferences = override.headerReferences;\n if (override.footerReferences !== undefined) result.footerReferences = override.footerReferences;\n if (override.titlePg !== undefined) result.titlePg = override.titlePg;\n if (override.evenAndOddHeaders !== undefined)\n result.evenAndOddHeaders = override.evenAndOddHeaders;\n if (override.lineNumbers !== undefined) result.lineNumbers = override.lineNumbers;\n if (override.pageBorders !== undefined) result.pageBorders = override.pageBorders;\n if (override.background !== undefined) result.background = override.background;\n if (override.footnotePr !== undefined) result.footnotePr = override.footnotePr;\n if (override.endnotePr !== undefined) result.endnotePr = override.endnotePr;\n if (override.docGrid !== undefined) result.docGrid = override.docGrid;\n if (override.paperSrcFirst !== undefined) result.paperSrcFirst = override.paperSrcFirst;\n if (override.paperSrcOther !== undefined) result.paperSrcOther = override.paperSrcOther;\n\n return result;\n}\n","/**\n * Run Consolidator - Merge consecutive runs with identical formatting\n *\n * DOCX files often contain many small runs with the same formatting,\n * created by Word for various reasons (spell checking, revision tracking,\n * cursor positioning, etc.). This causes:\n * - 252+ tiny <span> elements instead of a few\n * - Poor editing UX (cursor jumps between spans)\n * - Performance issues\n *\n * This module provides utilities to consolidate runs with identical\n * formatting into single runs, reducing fragmentation.\n */\n\nimport type {\n Run,\n RunContent,\n TextContent,\n TextFormatting,\n ParagraphContent,\n Paragraph,\n Hyperlink,\n} from '../types/document';\n\n/**\n * Check if two TextFormatting objects are equivalent\n *\n * Uses deep comparison of all properties to determine if runs\n * can be merged without losing formatting information.\n */\nexport function formattingEquals(\n a: TextFormatting | undefined,\n b: TextFormatting | undefined\n): boolean {\n // Both undefined - equal\n if (!a && !b) return true;\n\n // One undefined - not equal\n if (!a || !b) return false;\n\n // Compare boolean properties\n if (a.bold !== b.bold) return false;\n if (a.boldCs !== b.boldCs) return false;\n if (a.italic !== b.italic) return false;\n if (a.italicCs !== b.italicCs) return false;\n if (a.strike !== b.strike) return false;\n if (a.doubleStrike !== b.doubleStrike) return false;\n if (a.smallCaps !== b.smallCaps) return false;\n if (a.allCaps !== b.allCaps) return false;\n if (a.hidden !== b.hidden) return false;\n if (a.emboss !== b.emboss) return false;\n if (a.imprint !== b.imprint) return false;\n if (a.outline !== b.outline) return false;\n if (a.shadow !== b.shadow) return false;\n if (a.rtl !== b.rtl) return false;\n if (a.cs !== b.cs) return false;\n\n // Compare numeric properties\n if (a.fontSize !== b.fontSize) return false;\n if (a.fontSizeCs !== b.fontSizeCs) return false;\n if (a.spacing !== b.spacing) return false;\n if (a.position !== b.position) return false;\n if (a.scale !== b.scale) return false;\n if (a.kerning !== b.kerning) return false;\n\n // Compare string properties\n if (a.vertAlign !== b.vertAlign) return false;\n if (a.highlight !== b.highlight) return false;\n if (a.effect !== b.effect) return false;\n if (a.emphasisMark !== b.emphasisMark) return false;\n if (a.styleId !== b.styleId) return false;\n\n // Compare underline (object with style and optional color)\n if (!underlineEquals(a.underline, b.underline)) return false;\n\n // Compare color (object with rgb, themeColor, etc.)\n if (!colorEquals(a.color, b.color)) return false;\n\n // Compare shading (object with color, fill, pattern)\n if (!shadingEquals(a.shading, b.shading)) return false;\n\n // Compare fontFamily (complex object with multiple properties)\n if (!fontFamilyEquals(a.fontFamily, b.fontFamily)) return false;\n\n return true;\n}\n\n/**\n * Compare underline settings\n */\nfunction underlineEquals(a: TextFormatting['underline'], b: TextFormatting['underline']): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n if (a.style !== b.style) return false;\n return colorEquals(a.color, b.color);\n}\n\n/**\n * Compare color values\n */\nfunction colorEquals(a: TextFormatting['color'], b: TextFormatting['color']): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n return (\n a.rgb === b.rgb &&\n a.auto === b.auto &&\n a.themeColor === b.themeColor &&\n a.themeTint === b.themeTint &&\n a.themeShade === b.themeShade\n );\n}\n\n/**\n * Compare shading properties\n */\nfunction shadingEquals(a: TextFormatting['shading'], b: TextFormatting['shading']): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n if (a.pattern !== b.pattern) return false;\n if (!colorEquals(a.color, b.color)) return false;\n if (!colorEquals(a.fill, b.fill)) return false;\n\n return true;\n}\n\n/**\n * Compare font family settings\n */\nfunction fontFamilyEquals(\n a: TextFormatting['fontFamily'],\n b: TextFormatting['fontFamily']\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n return (\n a.ascii === b.ascii &&\n a.hAnsi === b.hAnsi &&\n a.eastAsia === b.eastAsia &&\n a.cs === b.cs &&\n a.asciiTheme === b.asciiTheme &&\n a.hAnsiTheme === b.hAnsiTheme &&\n a.eastAsiaTheme === b.eastAsiaTheme &&\n a.csTheme === b.csTheme\n );\n}\n\n/**\n * Check if a run contains only text content\n * (runs with special content like images, fields, etc. should not be merged)\n */\nexport function isTextOnlyRun(run: Run): boolean {\n return run.content.every(\n (c) => c.type === 'text' || c.type === 'softHyphen' || c.type === 'noBreakHyphen'\n );\n}\n\n/**\n * Check if run content can be merged (simple text types)\n */\nfunction isMergeableContent(content: RunContent): boolean {\n return (\n content.type === 'text' || content.type === 'softHyphen' || content.type === 'noBreakHyphen'\n );\n}\n\n/**\n * Check if a run can be merged with another run\n * Runs with breaks, tabs, images, fields, etc. act as merge boundaries\n */\nexport function canMergeRun(run: Run): boolean {\n // Empty runs can be merged\n if (run.content.length === 0) return true;\n\n // Runs with only text/hyphen content can be merged\n return run.content.every(isMergeableContent);\n}\n\n/**\n * Merge the content of two runs into a single content array\n */\nfunction mergeRunContent(content1: RunContent[], content2: RunContent[]): RunContent[] {\n // Combine all content\n const result: RunContent[] = [];\n\n // Add all from first run\n for (const c of content1) {\n result.push(c);\n }\n\n // Merge text at boundary if possible\n if (\n result.length > 0 &&\n content2.length > 0 &&\n result[result.length - 1].type === 'text' &&\n content2[0].type === 'text'\n ) {\n // Merge the two text nodes\n const lastText = result[result.length - 1] as TextContent;\n const firstText = content2[0] as TextContent;\n\n result[result.length - 1] = {\n type: 'text',\n text: lastText.text + firstText.text,\n preserveSpace: lastText.preserveSpace || firstText.preserveSpace || undefined,\n };\n\n // Add rest of content2\n for (let i = 1; i < content2.length; i++) {\n result.push(content2[i]);\n }\n } else {\n // Just append all of content2\n for (const c of content2) {\n result.push(c);\n }\n }\n\n return result;\n}\n\n/**\n * Consolidate an array of runs by merging consecutive runs with identical formatting\n *\n * @param runs - Array of runs to consolidate\n * @returns Consolidated array with fewer, larger runs\n */\nexport function consolidateRuns(runs: Run[]): Run[] {\n if (runs.length <= 1) return runs;\n\n const result: Run[] = [];\n let current: Run | null = null;\n\n for (const run of runs) {\n // Skip empty runs\n if (run.content.length === 0) continue;\n\n // If no current run, start with this one\n if (current === null) {\n current = { ...run, content: [...run.content] };\n continue;\n }\n\n // Check if we can merge this run with current\n if (\n canMergeRun(current) &&\n canMergeRun(run) &&\n formattingEquals(current.formatting, run.formatting)\n ) {\n // Merge the runs\n current = {\n type: 'run',\n formatting: current.formatting,\n content: mergeRunContent(current.content, run.content),\n };\n } else {\n // Can't merge - save current and start new\n result.push(current);\n current = { ...run, content: [...run.content] };\n }\n }\n\n // Don't forget the last run\n if (current !== null) {\n result.push(current);\n }\n\n return result;\n}\n\n/**\n * Consolidate runs within a paragraph content array\n *\n * This handles the full paragraph structure, consolidating runs while\n * preserving hyperlinks, bookmarks, and fields as merge boundaries.\n */\nexport function consolidateParagraphContent(content: ParagraphContent[]): ParagraphContent[] {\n if (content.length <= 1) return content;\n\n const result: ParagraphContent[] = [];\n const pendingRuns: Run[] = [];\n\n function flushRuns(): void {\n if (pendingRuns.length > 0) {\n const consolidated = consolidateRuns(pendingRuns);\n result.push(...consolidated);\n pendingRuns.length = 0;\n }\n }\n\n for (const item of content) {\n if (item.type === 'run') {\n pendingRuns.push(item);\n } else {\n // Non-run content acts as a merge boundary\n flushRuns();\n\n // Handle hyperlinks - consolidate their internal runs\n if (item.type === 'hyperlink') {\n const hyperlink: Hyperlink = {\n ...item,\n children: consolidateParagraphContent(item.children) as Hyperlink['children'],\n };\n result.push(hyperlink);\n } else {\n result.push(item);\n }\n }\n }\n\n // Flush any remaining runs\n flushRuns();\n\n return result;\n}\n\n/**\n * Consolidate all runs within a paragraph\n *\n * @param paragraph - Paragraph to consolidate\n * @returns New paragraph with consolidated runs\n */\nexport function consolidateParagraph(paragraph: Paragraph): Paragraph {\n if (!paragraph.content || paragraph.content.length === 0) {\n return paragraph;\n }\n\n return {\n ...paragraph,\n content: consolidateParagraphContent(paragraph.content),\n };\n}\n\n/**\n * Get the number of runs in a paragraph (for debugging/metrics)\n */\nexport function countRuns(paragraph: Paragraph): number {\n let count = 0;\n\n function countInContent(content: ParagraphContent[]): void {\n for (const item of content) {\n if (item.type === 'run') {\n count++;\n } else if (item.type === 'hyperlink') {\n countInContent(item.children);\n }\n }\n }\n\n if (paragraph.content) {\n countInContent(paragraph.content);\n }\n\n return count;\n}\n\n/**\n * Calculate the consolidation ratio (reduction in number of runs)\n * Useful for debugging and metrics\n */\nexport function getConsolidationStats(\n originalParagraphs: Paragraph[],\n consolidatedParagraphs: Paragraph[]\n): {\n originalRunCount: number;\n consolidatedRunCount: number;\n reductionPercentage: number;\n} {\n const originalCount = originalParagraphs.reduce((sum, p) => sum + countRuns(p), 0);\n const consolidatedCount = consolidatedParagraphs.reduce((sum, p) => sum + countRuns(p), 0);\n\n const reduction =\n originalCount > 0 ? ((originalCount - consolidatedCount) / originalCount) * 100 : 0;\n\n return {\n originalRunCount: originalCount,\n consolidatedRunCount: consolidatedCount,\n reductionPercentage: Math.round(reduction * 10) / 10,\n };\n}\n","/**\n * Paragraph Parser - Parse paragraphs (w:p) with complete formatting\n *\n * A paragraph is the fundamental block-level element containing text runs,\n * hyperlinks, bookmarks, and fields.\n *\n * OOXML Reference:\n * - Paragraph: w:p\n * - Paragraph properties: w:pPr\n * - Content: runs, hyperlinks, bookmarks, fields\n */\n\nimport type {\n Paragraph,\n ParagraphContent,\n ParagraphFormatting,\n Run,\n Hyperlink,\n BookmarkStart,\n BookmarkEnd,\n SimpleField,\n ComplexField,\n FieldType,\n Theme,\n ColorValue,\n BorderSpec,\n ShadingProperties,\n TabStop,\n TabStopAlignment,\n TabLeader,\n LineSpacingRule,\n ParagraphAlignment,\n RelationshipMap,\n MediaFile,\n InlineSdt,\n SdtProperties,\n Insertion,\n Deletion,\n MoveFrom,\n MoveTo,\n ParagraphPropertyChange,\n TrackedChangeInfo,\n MathEquation,\n} from '../types/document';\nimport type { StyleMap } from './styleParser';\nimport type { NumberingMap } from './numberingParser';\nimport {\n findChild,\n findChildren,\n getAttribute,\n getChildElements,\n parseBooleanElement,\n parseNumericAttribute,\n elementToXml,\n type XmlElement,\n} from './xmlParser';\nimport { parseRun, parseRunProperties } from './runParser';\nimport { parseHyperlink as parseHyperlinkFromModule } from './hyperlinkParser';\nimport {\n parseBookmarkStart as parseBookmarkStartFromModule,\n parseBookmarkEnd as parseBookmarkEndFromModule,\n} from './bookmarkParser';\nimport { parseSectionProperties } from './sectionParser';\nimport { consolidateParagraphContent } from './runConsolidator';\n\n// ============================================================================\n// SDT PROPERTIES PARSER\n// ============================================================================\n\n/**\n * Parse SDT properties (w:sdtPr) element\n */\nfunction parseSdtProperties(sdtPr: XmlElement | null): SdtProperties {\n const props: SdtProperties = { sdtType: 'richText' };\n if (!sdtPr || !sdtPr.elements) return props;\n\n for (const el of sdtPr.elements) {\n if (el.type !== 'element') continue;\n const name = el.name?.replace(/^w:/, '') ?? '';\n\n switch (name) {\n case 'alias':\n props.alias = getAttribute(el, 'w', 'val') ?? undefined;\n break;\n case 'tag':\n props.tag = getAttribute(el, 'w', 'val') ?? undefined;\n break;\n case 'lock':\n props.lock = (getAttribute(el, 'w', 'val') ?? 'unlocked') as SdtProperties['lock'];\n break;\n case 'placeholder': {\n const docPart = findChild(el, 'w', 'docPart');\n if (docPart) {\n const valEl = findChild(docPart, 'w', 'val');\n props.placeholder = valEl ? (getAttribute(valEl, 'w', 'val') ?? undefined) : undefined;\n }\n break;\n }\n case 'showingPlcHdr':\n props.showingPlaceholder = true;\n break;\n case 'text':\n props.sdtType = 'plainText';\n break;\n case 'date':\n props.sdtType = 'date';\n props.dateFormat = getAttribute(el, 'w', 'fullDate') ?? undefined;\n break;\n case 'dropDownList':\n props.sdtType = 'dropdown';\n props.listItems = parseListItems(el);\n break;\n case 'comboBox':\n props.sdtType = 'comboBox';\n props.listItems = parseListItems(el);\n break;\n case 'checkbox': {\n props.sdtType = 'checkbox';\n const checked = findChild(el, 'w14', 'checked') ?? findChild(el, 'w', 'checked');\n props.checked = checked\n ? getAttribute(checked, 'w14', 'val') === '1' || getAttribute(checked, 'w', 'val') === '1'\n : false;\n break;\n }\n case 'picture':\n props.sdtType = 'picture';\n break;\n case 'docPartObj':\n props.sdtType = 'buildingBlockGallery';\n break;\n case 'group':\n props.sdtType = 'group';\n break;\n }\n }\n\n return props;\n}\n\nfunction parseListItems(el: XmlElement): { displayText: string; value: string }[] {\n const items: { displayText: string; value: string }[] = [];\n for (const child of el.elements ?? []) {\n if (\n child.type === 'element' &&\n (child.name === 'w:listItem' || child.name?.endsWith(':listItem'))\n ) {\n items.push({\n displayText: getAttribute(child, 'w', 'displayText') ?? '',\n value: getAttribute(child, 'w', 'value') ?? '',\n });\n }\n }\n return items;\n}\n\n/**\n * Extract plain text from a math element (recursive text content extraction)\n */\nfunction extractMathText(el: XmlElement): string {\n let text = '';\n if (el.type === 'text' && typeof el.text === 'string') {\n return el.text;\n }\n if (el.elements) {\n for (const child of el.elements) {\n // m:t elements contain the actual math text\n const childName = child.name?.replace(/^.*:/, '') ?? '';\n if (childName === 't' && child.elements) {\n for (const t of child.elements) {\n if (t.type === 'text' && typeof t.text === 'string') {\n text += t.text;\n }\n }\n } else {\n text += extractMathText(child);\n }\n }\n }\n return text;\n}\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Parse color value from attributes\n */\nfunction parseColorValue(\n rgb: string | null,\n themeColor: string | null,\n themeTint: string | null,\n themeShade: string | null\n): ColorValue {\n const color: ColorValue = {};\n\n if (rgb && rgb !== 'auto') {\n color.rgb = rgb;\n } else if (rgb === 'auto') {\n color.auto = true;\n }\n\n if (themeColor) {\n color.themeColor = themeColor as ColorValue['themeColor'];\n }\n\n if (themeTint) {\n color.themeTint = themeTint;\n }\n\n if (themeShade) {\n color.themeShade = themeShade;\n }\n\n return color;\n}\n\n/**\n * Parse shading properties (w:shd)\n */\nfunction parseShadingProperties(shd: XmlElement | null): ShadingProperties | undefined {\n if (!shd) return undefined;\n\n const props: ShadingProperties = {};\n\n const color = getAttribute(shd, 'w', 'color');\n if (color && color !== 'auto') {\n props.color = { rgb: color };\n }\n\n const fill = getAttribute(shd, 'w', 'fill');\n if (fill && fill !== 'auto') {\n props.fill = { rgb: fill };\n }\n\n const themeFill = getAttribute(shd, 'w', 'themeFill');\n if (themeFill) {\n props.fill = props.fill || {};\n props.fill.themeColor = themeFill as ColorValue['themeColor'];\n }\n\n const themeFillTint = getAttribute(shd, 'w', 'themeFillTint');\n if (themeFillTint && props.fill) {\n props.fill.themeTint = themeFillTint;\n }\n\n const themeFillShade = getAttribute(shd, 'w', 'themeFillShade');\n if (themeFillShade && props.fill) {\n props.fill.themeShade = themeFillShade;\n }\n\n const pattern = getAttribute(shd, 'w', 'val');\n if (pattern) {\n props.pattern = pattern as ShadingProperties['pattern'];\n }\n\n return Object.keys(props).length > 0 ? props : undefined;\n}\n\n/**\n * Parse border specification (w:top, w:bottom, w:left, w:right, etc.)\n */\nfunction parseBorderSpec(border: XmlElement | null): BorderSpec | undefined {\n if (!border) return undefined;\n\n const style = getAttribute(border, 'w', 'val');\n if (!style) return undefined;\n\n const spec: BorderSpec = {\n style: style as BorderSpec['style'],\n };\n\n const colorVal = getAttribute(border, 'w', 'color');\n const themeColor = getAttribute(border, 'w', 'themeColor');\n if (colorVal || themeColor) {\n spec.color = parseColorValue(\n colorVal,\n themeColor,\n getAttribute(border, 'w', 'themeTint'),\n getAttribute(border, 'w', 'themeShade')\n );\n }\n\n const sz = parseNumericAttribute(border, 'w', 'sz');\n if (sz !== undefined) spec.size = sz;\n\n const space = parseNumericAttribute(border, 'w', 'space');\n if (space !== undefined) spec.space = space;\n\n const shadowAttr = getAttribute(border, 'w', 'shadow');\n if (shadowAttr) spec.shadow = shadowAttr === '1' || shadowAttr === 'true';\n\n const frame = getAttribute(border, 'w', 'frame');\n if (frame) spec.frame = frame === '1' || frame === 'true';\n\n return spec;\n}\n\n/**\n * Parse tab stops (w:tabs)\n */\nfunction parseTabStops(tabs: XmlElement | null): TabStop[] | undefined {\n if (!tabs) return undefined;\n\n const tabElements = findChildren(tabs, 'w', 'tab');\n if (tabElements.length === 0) return undefined;\n\n const result: TabStop[] = [];\n\n for (const tab of tabElements) {\n const pos = parseNumericAttribute(tab, 'w', 'pos');\n const val = getAttribute(tab, 'w', 'val');\n\n if (pos !== undefined && val) {\n const tabStop: TabStop = {\n position: pos,\n alignment: val as TabStopAlignment,\n };\n\n const leader = getAttribute(tab, 'w', 'leader');\n if (leader) {\n tabStop.leader = leader as TabLeader;\n }\n\n result.push(tabStop);\n }\n }\n\n return result.length > 0 ? result : undefined;\n}\n\n/**\n * Parse frame properties (w:framePr)\n */\nfunction parseFrameProperties(\n framePr: XmlElement | null\n): ParagraphFormatting['frame'] | undefined {\n if (!framePr) return undefined;\n\n const frame: ParagraphFormatting['frame'] = {};\n\n const w = parseNumericAttribute(framePr, 'w', 'w');\n if (w !== undefined) frame.width = w;\n\n const h = parseNumericAttribute(framePr, 'w', 'h');\n if (h !== undefined) frame.height = h;\n\n const hAnchor = getAttribute(framePr, 'w', 'hAnchor');\n if (hAnchor === 'text' || hAnchor === 'margin' || hAnchor === 'page') {\n frame.hAnchor = hAnchor;\n }\n\n const vAnchor = getAttribute(framePr, 'w', 'vAnchor');\n if (vAnchor === 'text' || vAnchor === 'margin' || vAnchor === 'page') {\n frame.vAnchor = vAnchor;\n }\n\n const x = parseNumericAttribute(framePr, 'w', 'x');\n if (x !== undefined) frame.x = x;\n\n const y = parseNumericAttribute(framePr, 'w', 'y');\n if (y !== undefined) frame.y = y;\n\n const xAlign = getAttribute(framePr, 'w', 'xAlign');\n if (xAlign) {\n frame.xAlign = xAlign as NonNullable<ParagraphFormatting['frame']>['xAlign'];\n }\n\n const yAlign = getAttribute(framePr, 'w', 'yAlign');\n if (yAlign) {\n frame.yAlign = yAlign as NonNullable<ParagraphFormatting['frame']>['yAlign'];\n }\n\n const wrap = getAttribute(framePr, 'w', 'wrap');\n if (wrap) {\n frame.wrap = wrap as NonNullable<ParagraphFormatting['frame']>['wrap'];\n }\n\n return Object.keys(frame).length > 0 ? frame : undefined;\n}\n\n// ============================================================================\n// PARAGRAPH PROPERTIES PARSER\n// ============================================================================\n\n/**\n * Parse paragraph formatting properties (w:pPr)\n *\n * Handles ALL pPr properties:\n * - w:jc (alignment: left, center, right, both/justify)\n * - w:spacing (before, after, line, lineRule)\n * - w:ind (left, right, firstLine, hanging)\n * - w:pBdr (paragraph borders: top, bottom, left, right, between)\n * - w:shd (paragraph shading/background)\n * - w:tabs (tab stops with positions and types)\n * - w:keepNext, w:keepLines, w:widowControl, w:pageBreakBefore\n * - w:bidi (right-to-left)\n * - w:numPr (list info)\n * - w:pStyle (style reference)\n * - w:outlineLvl (outline level)\n * - w:framePr (frame properties)\n * - w:rPr (default run properties)\n */\nexport function parseParagraphProperties(\n pPr: XmlElement | null,\n theme: Theme | null,\n styles?: StyleMap\n): ParagraphFormatting | undefined {\n if (!pPr) return undefined;\n\n const formatting: ParagraphFormatting = {};\n\n // === Alignment ===\n const jc = findChild(pPr, 'w', 'jc');\n if (jc) {\n const val = getAttribute(jc, 'w', 'val');\n if (val) {\n formatting.alignment = val as ParagraphAlignment;\n }\n }\n\n // === Bidi (right-to-left) ===\n const bidi = findChild(pPr, 'w', 'bidi');\n if (bidi) {\n formatting.bidi = parseBooleanElement(bidi);\n }\n\n // === Spacing ===\n const spacing = findChild(pPr, 'w', 'spacing');\n if (spacing) {\n const before = parseNumericAttribute(spacing, 'w', 'before');\n if (before !== undefined) formatting.spaceBefore = before;\n\n const after = parseNumericAttribute(spacing, 'w', 'after');\n if (after !== undefined) formatting.spaceAfter = after;\n\n const line = parseNumericAttribute(spacing, 'w', 'line');\n if (line !== undefined) formatting.lineSpacing = line;\n\n const lineRule = getAttribute(spacing, 'w', 'lineRule');\n if (lineRule) {\n formatting.lineSpacingRule = lineRule as LineSpacingRule;\n }\n\n const beforeAuto = getAttribute(spacing, 'w', 'beforeAutospacing');\n if (beforeAuto) {\n formatting.beforeAutospacing = beforeAuto === '1' || beforeAuto === 'true';\n }\n\n const afterAuto = getAttribute(spacing, 'w', 'afterAutospacing');\n if (afterAuto) {\n formatting.afterAutospacing = afterAuto === '1' || afterAuto === 'true';\n }\n }\n\n // === Indentation ===\n const ind = findChild(pPr, 'w', 'ind');\n if (ind) {\n const left = parseNumericAttribute(ind, 'w', 'left');\n if (left !== undefined) formatting.indentLeft = left;\n\n const right = parseNumericAttribute(ind, 'w', 'right');\n if (right !== undefined) formatting.indentRight = right;\n\n const firstLine = parseNumericAttribute(ind, 'w', 'firstLine');\n if (firstLine !== undefined) formatting.indentFirstLine = firstLine;\n\n const hanging = parseNumericAttribute(ind, 'w', 'hanging');\n if (hanging !== undefined) {\n // Hanging indent is stored as negative first line indent\n formatting.indentFirstLine = -hanging;\n formatting.hangingIndent = true;\n }\n\n // Also check for w:start and w:end (alternative attributes)\n const start = parseNumericAttribute(ind, 'w', 'start');\n if (start !== undefined && formatting.indentLeft === undefined) {\n formatting.indentLeft = start;\n }\n\n const end = parseNumericAttribute(ind, 'w', 'end');\n if (end !== undefined && formatting.indentRight === undefined) {\n formatting.indentRight = end;\n }\n }\n\n // === Borders ===\n const pBdr = findChild(pPr, 'w', 'pBdr');\n if (pBdr) {\n const borders: ParagraphFormatting['borders'] = {};\n\n const top = parseBorderSpec(findChild(pBdr, 'w', 'top'));\n if (top) borders.top = top;\n\n const bottom = parseBorderSpec(findChild(pBdr, 'w', 'bottom'));\n if (bottom) borders.bottom = bottom;\n\n const left = parseBorderSpec(findChild(pBdr, 'w', 'left'));\n if (left) borders.left = left;\n\n const right = parseBorderSpec(findChild(pBdr, 'w', 'right'));\n if (right) borders.right = right;\n\n const between = parseBorderSpec(findChild(pBdr, 'w', 'between'));\n if (between) borders.between = between;\n\n const bar = parseBorderSpec(findChild(pBdr, 'w', 'bar'));\n if (bar) borders.bar = bar;\n\n if (Object.keys(borders).length > 0) {\n formatting.borders = borders;\n }\n }\n\n // === Shading ===\n const shd = findChild(pPr, 'w', 'shd');\n if (shd) {\n formatting.shading = parseShadingProperties(shd);\n }\n\n // === Tab Stops ===\n const tabs = findChild(pPr, 'w', 'tabs');\n if (tabs) {\n formatting.tabs = parseTabStops(tabs);\n }\n\n // === Page Break Control ===\n const keepNext = findChild(pPr, 'w', 'keepNext');\n if (keepNext) {\n formatting.keepNext = parseBooleanElement(keepNext);\n }\n\n const keepLines = findChild(pPr, 'w', 'keepLines');\n if (keepLines) {\n formatting.keepLines = parseBooleanElement(keepLines);\n }\n\n const widowControl = findChild(pPr, 'w', 'widowControl');\n if (widowControl) {\n formatting.widowControl = parseBooleanElement(widowControl);\n }\n\n const pageBreakBefore = findChild(pPr, 'w', 'pageBreakBefore');\n if (pageBreakBefore) {\n formatting.pageBreakBefore = parseBooleanElement(pageBreakBefore);\n }\n\n const contextualSpacing = findChild(pPr, 'w', 'contextualSpacing');\n if (contextualSpacing) {\n formatting.contextualSpacing = parseBooleanElement(contextualSpacing);\n }\n\n // === Numbering Properties (List Info) ===\n const numPr = findChild(pPr, 'w', 'numPr');\n if (numPr) {\n const numIdEl = findChild(numPr, 'w', 'numId');\n const ilvlEl = findChild(numPr, 'w', 'ilvl');\n\n if (numIdEl || ilvlEl) {\n formatting.numPr = {};\n\n if (numIdEl) {\n const val = parseNumericAttribute(numIdEl, 'w', 'val');\n if (val !== undefined) formatting.numPr.numId = val;\n }\n\n if (ilvlEl) {\n const val = parseNumericAttribute(ilvlEl, 'w', 'val');\n if (val !== undefined) formatting.numPr.ilvl = val;\n }\n }\n }\n\n // === Outline Level ===\n const outlineLvl = findChild(pPr, 'w', 'outlineLvl');\n if (outlineLvl) {\n const val = parseNumericAttribute(outlineLvl, 'w', 'val');\n if (val !== undefined) formatting.outlineLevel = val;\n }\n\n // === Style Reference ===\n const pStyle = findChild(pPr, 'w', 'pStyle');\n if (pStyle) {\n const val = getAttribute(pStyle, 'w', 'val');\n if (val) formatting.styleId = val;\n }\n\n // === Frame Properties ===\n const framePr = findChild(pPr, 'w', 'framePr');\n if (framePr) {\n formatting.frame = parseFrameProperties(framePr);\n }\n\n // === Suppress Line Numbers ===\n const suppressLineNumbers = findChild(pPr, 'w', 'suppressLineNumbers');\n if (suppressLineNumbers) {\n formatting.suppressLineNumbers = parseBooleanElement(suppressLineNumbers);\n }\n\n // === Suppress Auto Hyphens ===\n const suppressAutoHyphens = findChild(pPr, 'w', 'suppressAutoHyphens');\n if (suppressAutoHyphens) {\n formatting.suppressAutoHyphens = parseBooleanElement(suppressAutoHyphens);\n }\n\n // === Default Run Properties ===\n const rPr = findChild(pPr, 'w', 'rPr');\n if (rPr) {\n formatting.runProperties = parseRunProperties(rPr, theme, styles);\n }\n\n return Object.keys(formatting).length > 0 ? formatting : undefined;\n}\n\n// ============================================================================\n// PARAGRAPH CONTENT PARSERS\n// ============================================================================\n\n/**\n * Get the local name of an element (without namespace prefix)\n */\nfunction getLocalName(name: string | undefined): string {\n if (!name) return '';\n const colonIndex = name.indexOf(':');\n return colonIndex >= 0 ? name.substring(colonIndex + 1) : name;\n}\n\ntype TrackedChangeParseContext = 'default' | 'deletion';\n\nfunction replaceLocalName(name: string | undefined, localName: string): string {\n if (!name) {\n return `w:${localName}`;\n }\n const colonIndex = name.indexOf(':');\n if (colonIndex < 0) {\n return localName;\n }\n return `${name.substring(0, colonIndex + 1)}${localName}`;\n}\n\nfunction normalizeDeletionContentElement(node: XmlElement): XmlElement {\n if (node.type !== 'element') {\n return node;\n }\n\n const localName = getLocalName(node.name);\n let mappedName = node.name;\n\n if (localName === 'delText') {\n mappedName = replaceLocalName(node.name, 't');\n } else if (localName === 'delInstrText') {\n mappedName = replaceLocalName(node.name, 'instrText');\n }\n\n return {\n ...node,\n name: mappedName,\n elements: node.elements?.map(normalizeDeletionContentElement),\n };\n}\n\nfunction parseTrackedChangeInfo(node: XmlElement): TrackedChangeInfo {\n const rawId = getAttribute(node, 'w', 'id');\n const parsedId = rawId ? parseInt(rawId, 10) : 0;\n const rawAuthor = getAttribute(node, 'w', 'author');\n const rawDate = getAttribute(node, 'w', 'date');\n const author = rawAuthor?.trim() ?? '';\n const date = rawDate?.trim() ?? '';\n\n return {\n id: Number.isInteger(parsedId) && parsedId >= 0 ? parsedId : 0,\n author: author.length > 0 ? author : 'Unknown',\n date: date.length > 0 ? date : undefined,\n };\n}\n\nfunction parsePropertyChangeInfo(node: XmlElement): ParagraphPropertyChange['info'] {\n const base = parseTrackedChangeInfo(node);\n const rsid = (getAttribute(node, 'w', 'rsid') ?? '').trim();\n return rsid.length > 0 ? { ...base, rsid } : base;\n}\n\nfunction parseParagraphPropertyChanges(\n pPr: XmlElement | null,\n theme: Theme | null,\n styles: StyleMap | null,\n currentFormatting: ParagraphFormatting | undefined\n): ParagraphPropertyChange[] | undefined {\n if (!pPr) return undefined;\n\n const changes = findChildren(pPr, 'w', 'pPrChange')\n .map((changeElement): ParagraphPropertyChange => {\n const previousPPr = findChild(changeElement, 'w', 'pPr');\n return {\n type: 'paragraphPropertyChange',\n info: parsePropertyChangeInfo(changeElement),\n previousFormatting: parseParagraphProperties(previousPPr, theme, styles ?? undefined),\n currentFormatting,\n };\n })\n .filter((change) => change.previousFormatting || change.currentFormatting);\n\n return changes.length > 0 ? changes : undefined;\n}\n\n/**\n * Parse hyperlink element (w:hyperlink)\n *\n * Delegates to hyperlinkParser module which resolves URLs via relationships.\n */\nfunction parseHyperlink(\n node: XmlElement,\n rels: RelationshipMap | null,\n styles: StyleMap | null,\n theme: Theme | null,\n media: Map<string, MediaFile> | null\n): Hyperlink {\n return parseHyperlinkFromModule(node, rels, styles, theme, media);\n}\n\n/**\n * Parse bookmark start (w:bookmarkStart)\n * Delegates to bookmarkParser module.\n */\nfunction parseBookmarkStart(node: XmlElement): BookmarkStart {\n return parseBookmarkStartFromModule(node);\n}\n\n/**\n * Parse bookmark end (w:bookmarkEnd)\n * Delegates to bookmarkParser module.\n */\nfunction parseBookmarkEnd(node: XmlElement): BookmarkEnd {\n return parseBookmarkEndFromModule(node);\n}\n\n/**\n * Parse field type from instruction string\n */\nfunction parseFieldType(instruction: string): FieldType {\n // Extract the field name (first word)\n const match = instruction.trim().match(/^\\\\?([A-Z]+)/i);\n if (!match) return 'UNKNOWN';\n\n const fieldName = match[1].toUpperCase();\n\n const knownFields: FieldType[] = [\n 'PAGE',\n 'NUMPAGES',\n 'NUMWORDS',\n 'NUMCHARS',\n 'DATE',\n 'TIME',\n 'CREATEDATE',\n 'SAVEDATE',\n 'PRINTDATE',\n 'AUTHOR',\n 'TITLE',\n 'SUBJECT',\n 'KEYWORDS',\n 'COMMENTS',\n 'FILENAME',\n 'FILESIZE',\n 'TEMPLATE',\n 'DOCPROPERTY',\n 'DOCVARIABLE',\n 'REF',\n 'PAGEREF',\n 'NOTEREF',\n 'HYPERLINK',\n 'TOC',\n 'TOA',\n 'INDEX',\n 'SEQ',\n 'STYLEREF',\n 'AUTONUM',\n 'AUTONUMLGL',\n 'AUTONUMOUT',\n 'IF',\n 'MERGEFIELD',\n 'NEXT',\n 'NEXTIF',\n 'ASK',\n 'SET',\n 'QUOTE',\n 'INCLUDETEXT',\n 'INCLUDEPICTURE',\n 'SYMBOL',\n 'ADVANCE',\n 'EDITTIME',\n 'REVNUM',\n 'SECTION',\n 'SECTIONPAGES',\n 'USERADDRESS',\n 'USERNAME',\n 'USERINITIALS',\n ];\n\n if (knownFields.includes(fieldName as FieldType)) {\n return fieldName as FieldType;\n }\n\n return 'UNKNOWN';\n}\n\n/**\n * Parse simple field (w:fldSimple)\n */\nfunction parseSimpleField(\n node: XmlElement,\n styles: StyleMap | null,\n theme: Theme | null,\n rels: RelationshipMap | null,\n media: Map<string, MediaFile> | null\n): SimpleField {\n const instruction = getAttribute(node, 'w', 'instr') ?? '';\n const fieldType = parseFieldType(instruction);\n\n const field: SimpleField = {\n type: 'simpleField',\n instruction,\n fieldType,\n content: [],\n };\n\n // Check for fldLock\n const fldLock = getAttribute(node, 'w', 'fldLock');\n if (fldLock === '1' || fldLock === 'true') {\n field.fldLock = true;\n }\n\n // Check for dirty\n const dirty = getAttribute(node, 'w', 'dirty');\n if (dirty === '1' || dirty === 'true') {\n field.dirty = true;\n }\n\n // Parse child runs (the display value)\n const children = getChildElements(node);\n for (const child of children) {\n const localName = getLocalName(child.name);\n if (localName === 'r') {\n field.content.push(parseRun(child, styles, theme, rels, media));\n }\n }\n\n return field;\n}\n\n/**\n * Parse all content within a paragraph\n *\n * Returns the parsed content and any complex fields that span multiple runs\n */\nfunction parseParagraphContents(\n paraElement: XmlElement,\n styles: StyleMap | null,\n theme: Theme | null,\n _numbering: NumberingMap | null,\n rels: RelationshipMap | null,\n media: Map<string, MediaFile> | null,\n trackedContext: TrackedChangeParseContext = 'default'\n): ParagraphContent[] {\n const contents: ParagraphContent[] = [];\n const children = getChildElements(paraElement);\n\n // State for tracking complex fields\n let inComplexField = false;\n let complexFieldInstr = '';\n let complexFieldCodeRuns: Run[] = [];\n let complexFieldResultRuns: Run[] = [];\n let afterSeparator = false;\n let complexFieldLock = false;\n let complexFieldDirty = false;\n\n for (const child of children) {\n const localName = getLocalName(child.name);\n\n switch (localName) {\n case 'r': {\n // Check for field characters in this run\n const runElement =\n trackedContext === 'deletion' ? normalizeDeletionContentElement(child) : child;\n const run = parseRun(runElement, styles, theme, rels, media);\n\n // Look for field characters\n let hasFieldBegin = false;\n let hasFieldSeparate = false;\n let hasFieldEnd = false;\n let instrText = '';\n\n for (const content of run.content) {\n if (content.type === 'fieldChar') {\n if (content.charType === 'begin') {\n hasFieldBegin = true;\n if (content.fldLock) complexFieldLock = true;\n if (content.dirty) complexFieldDirty = true;\n } else if (content.charType === 'separate') {\n hasFieldSeparate = true;\n } else if (content.charType === 'end') {\n hasFieldEnd = true;\n }\n } else if (content.type === 'instrText') {\n instrText += content.text;\n }\n }\n\n if (hasFieldBegin) {\n // Starting a new complex field\n inComplexField = true;\n afterSeparator = false;\n complexFieldInstr = '';\n complexFieldCodeRuns = [];\n complexFieldResultRuns = [];\n complexFieldLock = false;\n complexFieldDirty = false;\n }\n\n if (inComplexField) {\n if (instrText) {\n complexFieldInstr += instrText;\n }\n\n if (hasFieldSeparate) {\n afterSeparator = true;\n }\n\n if (afterSeparator && !hasFieldEnd) {\n // Add to result runs (excluding the separator run itself)\n if (!hasFieldSeparate) {\n complexFieldResultRuns.push(run);\n }\n } else if (!afterSeparator && !hasFieldBegin) {\n // Add to code runs\n complexFieldCodeRuns.push(run);\n }\n\n if (hasFieldEnd) {\n // Close the complex field\n const complexField: ComplexField = {\n type: 'complexField',\n instruction: complexFieldInstr.trim(),\n fieldType: parseFieldType(complexFieldInstr),\n fieldCode: complexFieldCodeRuns,\n fieldResult: complexFieldResultRuns,\n };\n\n if (complexFieldLock) complexField.fldLock = true;\n if (complexFieldDirty) complexField.dirty = true;\n\n contents.push(complexField);\n inComplexField = false;\n }\n } else {\n // Regular run, not part of a field\n contents.push(run);\n }\n break;\n }\n\n case 'hyperlink':\n contents.push(parseHyperlink(child, rels, styles, theme, media));\n break;\n\n case 'bookmarkStart':\n contents.push(parseBookmarkStart(child));\n break;\n\n case 'bookmarkEnd':\n contents.push(parseBookmarkEnd(child));\n break;\n\n case 'fldSimple':\n contents.push(parseSimpleField(child, styles, theme, rels, media));\n break;\n\n case 'pPr':\n // Already handled separately\n break;\n\n case 'proofErr':\n case 'permStart':\n case 'permEnd':\n case 'customXml':\n // Skip these elements\n break;\n\n case 'sdt': {\n // Structured document tag - extract properties and content\n const sdtPr = (child.elements ?? []).find(\n (el: XmlElement) =>\n el.type === 'element' && (el.name === 'w:sdtPr' || el.name?.endsWith(':sdtPr'))\n );\n const sdtContentEl = (child.elements ?? []).find(\n (el: XmlElement) =>\n el.type === 'element' &&\n (el.name === 'w:sdtContent' || el.name?.endsWith(':sdtContent'))\n );\n if (sdtContentEl) {\n const sdtParsed = parseParagraphContents(\n sdtContentEl,\n styles,\n theme,\n null,\n rels,\n media,\n trackedContext\n );\n const properties = parseSdtProperties(sdtPr ?? null);\n const inlineSdt: InlineSdt = {\n type: 'inlineSdt',\n properties,\n content: sdtParsed.filter(\n (c): c is Run | Hyperlink => c.type === 'run' || c.type === 'hyperlink'\n ),\n };\n contents.push(inlineSdt);\n }\n break;\n }\n\n case 'ins': {\n // Track change: insertion — parse content and wrap\n const insInfo = parseTrackedChangeInfo(child);\n const insContent = parseParagraphContents(child, styles, theme, null, rels, media);\n const insertion: Insertion = {\n type: 'insertion',\n info: insInfo,\n content: insContent.filter(\n (c): c is Run | Hyperlink => c.type === 'run' || c.type === 'hyperlink'\n ),\n };\n contents.push(insertion);\n break;\n }\n case 'del': {\n // Track change: deletion — parse content and wrap\n const delInfo = parseTrackedChangeInfo(child);\n const delContent = parseParagraphContents(\n child,\n styles,\n theme,\n null,\n rels,\n media,\n 'deletion'\n );\n const deletion: Deletion = {\n type: 'deletion',\n info: delInfo,\n content: delContent.filter(\n (c): c is Run | Hyperlink => c.type === 'run' || c.type === 'hyperlink'\n ),\n };\n contents.push(deletion);\n break;\n }\n case 'moveFrom': {\n const moveFromInfo = parseTrackedChangeInfo(child);\n const moveFromContent = parseParagraphContents(\n child,\n styles,\n theme,\n null,\n rels,\n media,\n 'deletion'\n );\n const moveFrom: MoveFrom = {\n type: 'moveFrom',\n info: moveFromInfo,\n content: moveFromContent.filter(\n (c): c is Run | Hyperlink => c.type === 'run' || c.type === 'hyperlink'\n ),\n };\n contents.push(moveFrom);\n break;\n }\n\n case 'moveTo': {\n const moveToInfo = parseTrackedChangeInfo(child);\n const moveToContent = parseParagraphContents(child, styles, theme, null, rels, media);\n const moveTo: MoveTo = {\n type: 'moveTo',\n info: moveToInfo,\n content: moveToContent.filter(\n (c): c is Run | Hyperlink => c.type === 'run' || c.type === 'hyperlink'\n ),\n };\n contents.push(moveTo);\n break;\n }\n\n case 'smartTag':\n break;\n\n case 'moveFromRangeStart': {\n const id = parseInt(getAttribute(child, 'w', 'id') ?? '0', 10);\n const name = getAttribute(child, 'w', 'name') ?? '';\n contents.push({ type: 'moveFromRangeStart', id, name });\n break;\n }\n case 'moveFromRangeEnd': {\n const id = parseInt(getAttribute(child, 'w', 'id') ?? '0', 10);\n contents.push({ type: 'moveFromRangeEnd', id });\n break;\n }\n case 'moveToRangeStart': {\n const id = parseInt(getAttribute(child, 'w', 'id') ?? '0', 10);\n const name = getAttribute(child, 'w', 'name') ?? '';\n contents.push({ type: 'moveToRangeStart', id, name });\n break;\n }\n case 'moveToRangeEnd': {\n const id = parseInt(getAttribute(child, 'w', 'id') ?? '0', 10);\n contents.push({ type: 'moveToRangeEnd', id });\n break;\n }\n\n case 'commentRangeStart': {\n const commentId = parseInt(getAttribute(child, 'w', 'id') ?? '0', 10);\n contents.push({ type: 'commentRangeStart', id: commentId });\n break;\n }\n case 'commentRangeEnd': {\n const commentId = parseInt(getAttribute(child, 'w', 'id') ?? '0', 10);\n contents.push({ type: 'commentRangeEnd', id: commentId });\n break;\n }\n\n case 'oMath':\n case 'oMathPara': {\n // Math equations — store raw OMML XML and extract text fallback\n const isBlock = localName === 'oMathPara';\n const ommlXml = elementToXml(child);\n const plainText = extractMathText(child);\n const mathEq: MathEquation = {\n type: 'mathEquation',\n display: isBlock ? 'block' : 'inline',\n ommlXml,\n plainText: plainText || undefined,\n };\n contents.push(mathEq);\n break;\n }\n\n default:\n // Unknown element - skip\n break;\n }\n }\n\n return contents;\n}\n\n// ============================================================================\n// MAIN PARAGRAPH PARSER\n// ============================================================================\n\n/**\n * Parse a paragraph element (w:p)\n *\n * @param node - The w:p XML element\n * @param styles - Style map for resolving style references\n * @param theme - Theme for resolving theme colors/fonts\n * @param numbering - Numbering definitions for list info\n * @param rels - Relationship map for resolving hyperlink URLs\n * @param media - Media files map for image data\n * @returns Parsed Paragraph object\n */\nexport function parseParagraph(\n node: XmlElement,\n styles: StyleMap | null,\n theme: Theme | null,\n numbering: NumberingMap | null,\n rels: RelationshipMap | null = null,\n media: Map<string, MediaFile> | null = null\n): Paragraph {\n const paragraph: Paragraph = {\n type: 'paragraph',\n content: [],\n };\n\n // Get paragraph ID attributes (Word 2010+ uses these for collaboration)\n const paraId = getAttribute(node, 'w14', 'paraId') ?? getAttribute(node, 'w', 'paraId');\n if (paraId) {\n paragraph.paraId = paraId;\n }\n\n const textId = getAttribute(node, 'w14', 'textId') ?? getAttribute(node, 'w', 'textId');\n if (textId) {\n paragraph.textId = textId;\n }\n\n // Parse paragraph properties (w:pPr)\n const pPr = findChild(node, 'w', 'pPr');\n if (pPr) {\n paragraph.formatting = parseParagraphProperties(pPr, theme, styles ?? undefined);\n paragraph.propertyChanges = parseParagraphPropertyChanges(\n pPr,\n theme,\n styles,\n paragraph.formatting\n );\n\n // Check for section properties within paragraph (marks end of a section)\n const sectPr = findChild(pPr, 'w', 'sectPr');\n if (sectPr) {\n paragraph.sectionProperties = parseSectionProperties(sectPr, rels);\n }\n }\n\n // Parse paragraph contents (runs, hyperlinks, bookmarks, fields)\n const rawContent = parseParagraphContents(node, styles, theme, numbering, rels, media);\n\n // Consolidate consecutive runs with identical formatting\n // This reduces fragmentation (e.g., 252 tiny runs → a few larger runs)\n paragraph.content = consolidateParagraphContent(rawContent);\n\n // Compute list rendering if this is a list item.\n // numPr can come from inline pPr or from the referenced paragraph style.\n let effectiveNumPr = paragraph.formatting?.numPr;\n if (!effectiveNumPr && paragraph.formatting?.styleId && styles) {\n const style = styles.get(paragraph.formatting.styleId);\n if (style?.pPr?.numPr) {\n effectiveNumPr = style.pPr.numPr;\n // Store it on the paragraph formatting so downstream code sees it\n if (!paragraph.formatting) paragraph.formatting = {};\n paragraph.formatting.numPr = effectiveNumPr;\n }\n }\n\n if (effectiveNumPr && numbering) {\n const { numId, ilvl = 0 } = effectiveNumPr;\n if (numId !== undefined && numId !== 0) {\n const level = numbering.getLevel(numId, ilvl);\n if (level) {\n paragraph.listRendering = {\n level: ilvl,\n numId,\n marker: level.lvlText,\n isBullet: level.numFmt === 'bullet',\n numFmt: level.numFmt,\n markerHidden: level.rPr?.hidden || undefined,\n markerFontFamily:\n level.rPr?.fontFamily?.ascii || level.rPr?.fontFamily?.hAnsi || undefined,\n // w:sz is in half-points; convert to points for downstream use\n markerFontSize: level.rPr?.fontSize ? level.rPr.fontSize / 2 : undefined,\n };\n\n // Apply level's paragraph properties (indentation) as defaults.\n // Per OOXML spec, direct w:ind on the paragraph overrides numbering\n // level indent — only use numbering indent as fallback.\n if (level.pPr) {\n if (!paragraph.formatting) {\n paragraph.formatting = {};\n }\n const directInd = pPr ? findChild(pPr, 'w', 'ind') : null;\n const hasDirectLeft =\n directInd != null &&\n (getAttribute(directInd, 'w', 'left') !== null ||\n getAttribute(directInd, 'w', 'start') !== null);\n const hasDirectFirstLineOrHanging =\n directInd != null &&\n (getAttribute(directInd, 'w', 'firstLine') !== null ||\n getAttribute(directInd, 'w', 'hanging') !== null);\n\n if (!hasDirectLeft && level.pPr.indentLeft !== undefined) {\n paragraph.formatting.indentLeft = level.pPr.indentLeft;\n }\n if (!hasDirectFirstLineOrHanging) {\n if (level.pPr.indentFirstLine !== undefined) {\n paragraph.formatting.indentFirstLine = level.pPr.indentFirstLine;\n }\n if (level.pPr.hangingIndent !== undefined) {\n paragraph.formatting.hangingIndent = level.pPr.hangingIndent;\n }\n }\n }\n }\n }\n }\n\n return paragraph;\n}\n\n// ============================================================================\n// UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Get plain text from a paragraph\n *\n * @param paragraph - Parsed Paragraph object\n * @returns Concatenated text content\n */\nexport function getParagraphText(paragraph: Paragraph): string {\n let text = '';\n\n for (const content of paragraph.content) {\n if (content.type === 'run') {\n for (const runContent of content.content) {\n if (runContent.type === 'text') {\n text += runContent.text;\n } else if (runContent.type === 'tab') {\n text += '\\t';\n } else if (runContent.type === 'break') {\n if (runContent.breakType === 'page') {\n text += '\\f';\n } else {\n text += '\\n';\n }\n }\n }\n } else if (content.type === 'hyperlink') {\n for (const child of content.children) {\n if (child.type === 'run') {\n for (const runContent of child.content) {\n if (runContent.type === 'text') {\n text += runContent.text;\n }\n }\n }\n }\n } else if (content.type === 'simpleField') {\n for (const child of content.content) {\n if (child.type === 'run') {\n for (const runContent of child.content) {\n if (runContent.type === 'text') {\n text += runContent.text;\n }\n }\n }\n }\n } else if (content.type === 'complexField') {\n for (const run of content.fieldResult) {\n for (const runContent of run.content) {\n if (runContent.type === 'text') {\n text += runContent.text;\n }\n }\n }\n }\n }\n\n return text;\n}\n\n/**\n * Check if a paragraph is empty (no visible content)\n *\n * @param paragraph - Parsed Paragraph object\n * @returns true if paragraph has no visible content\n */\nexport function isEmptyParagraph(paragraph: Paragraph): boolean {\n return (\n getParagraphText(paragraph).trim() === '' &&\n !paragraph.content.some(\n (c) =>\n c.type === 'run' && c.content.some((rc) => rc.type === 'drawing' || rc.type === 'shape')\n )\n );\n}\n\n/**\n * Check if a paragraph is a list item\n *\n * @param paragraph - Parsed Paragraph object\n * @returns true if paragraph has numbering properties\n */\nexport function isListItem(paragraph: Paragraph): boolean {\n return (\n paragraph.formatting?.numPr !== undefined &&\n paragraph.formatting.numPr.numId !== undefined &&\n paragraph.formatting.numPr.numId !== 0\n );\n}\n\n/**\n * Get the list level of a paragraph (0-8)\n *\n * @param paragraph - Parsed Paragraph object\n * @returns List level or undefined if not a list item\n */\nexport function getListLevel(paragraph: Paragraph): number | undefined {\n if (!isListItem(paragraph)) return undefined;\n return paragraph.formatting?.numPr?.ilvl ?? 0;\n}\n\n/**\n * Check if paragraph has a specific style\n *\n * @param paragraph - Parsed Paragraph object\n * @param styleId - Style ID to check for\n * @returns true if paragraph has the specified style\n */\nexport function hasStyle(paragraph: Paragraph, styleId: string): boolean {\n return paragraph.formatting?.styleId === styleId;\n}\n\n/**\n * Check if paragraph starts with a template variable {{...}}\n *\n * @param paragraph - Parsed Paragraph object\n * @returns The variable name or null\n */\nexport function getTemplateVariable(paragraph: Paragraph): string | null {\n const text = getParagraphText(paragraph);\n const match = text.match(/\\{\\{([^}]+)\\}\\}/);\n return match ? match[1] : null;\n}\n","/**\n * Document Body Parser - Parse document.xml body content\n *\n * Parses the main document body (w:body) containing paragraphs, tables,\n * and section properties. Also detects template variables {{...}}.\n *\n * OOXML Reference:\n * - Root: w:document\n * - Body: w:body\n * - Content: w:p (paragraphs), w:tbl (tables), w:sdt (structured document tags)\n * - Final section properties: w:body/w:sectPr\n */\n\nimport type {\n DocumentBody,\n BlockContent,\n Section,\n Paragraph,\n Table,\n SectionProperties,\n Shape,\n ShapeContent,\n Theme,\n RelationshipMap,\n MediaFile,\n} from '../types/document';\nimport type { StyleMap } from './styleParser';\nimport type { NumberingMap } from './numberingParser';\nimport {\n parseXml,\n findChild,\n findDeep,\n getChildElements,\n getLocalName,\n type XmlElement,\n} from './xmlParser';\nimport { parseParagraph, getParagraphText } from './paragraphParser';\nimport { parseTable } from './tableParser';\nimport { parseSectionProperties, getDefaultSectionProperties } from './sectionParser';\nimport {\n isTextBoxDrawing,\n parseTextBox,\n getTextBoxContentElement,\n parseTextBoxContent,\n} from './textBoxParser';\n\n// ============================================================================\n// LIST MARKER COMPUTATION\n// ============================================================================\n\n/**\n * Convert Symbol font bullet characters to Unicode equivalents\n *\n * DOCX often uses characters from Symbol, Wingdings, or Webdings fonts\n * that don't render correctly without the font. This maps them to\n * standard Unicode bullets that work with any font.\n */\nfunction convertBulletToUnicode(bulletChar: string): string {\n // If empty or whitespace, use standard bullet\n if (!bulletChar || bulletChar.trim() === '') {\n return '•';\n }\n\n // Get the character code\n const charCode = bulletChar.charCodeAt(0);\n\n // Map common Symbol/Wingdings characters to Unicode\n // Symbol font mappings (often used for bullets)\n const symbolMap: Record<number, string> = {\n // Symbol font\n 0x00b7: '•', // Middle dot → bullet\n 0x006f: '○', // lowercase o → white circle (used in Symbol font)\n 0x00a7: '■', // Section sign → black square (Symbol)\n 0x00fc: '✓', // Checkmark in Symbol/Wingdings\n\n // Wingdings mappings (character codes when Wingdings not available)\n 0x006e: '■', // Wingdings n → black square\n 0x0071: '○', // Wingdings q → white circle\n 0x0075: '◆', // Wingdings u → black diamond\n 0x0076: '❖', // Wingdings v → diamond\n 0x00a8: '✓', // Wingdings checkmark\n 0x00fb: '✓', // Checkmark\n 0x00fe: '✓', // Checkmark variant\n\n // Common control characters that might appear\n 0xf0b7: '•', // Private use area bullet\n 0xf06e: '■', // Private use area square\n 0xf06f: '○', // Private use area circle\n 0xf0a7: '■', // Private use area\n 0xf0fc: '✓', // Private use area checkmark\n\n // Other common bullet-like characters\n 0x2022: '•', // Already a bullet\n 0x25cf: '●', // Black circle\n 0x25cb: '○', // White circle\n 0x25a0: '■', // Black square\n 0x25a1: '□', // White square\n 0x25c6: '◆', // Black diamond\n 0x25c7: '◇', // White diamond\n 0x2013: '–', // En dash\n 0x2014: '—', // Em dash\n 0x003e: '>', // Greater than (used as arrow)\n 0x002d: '-', // Hyphen\n };\n\n // Check if we have a mapping for this character\n if (symbolMap[charCode]) {\n return symbolMap[charCode];\n }\n\n // If it's in the private use area (often Symbol/Wingdings), use bullet\n if (charCode >= 0xe000 && charCode <= 0xf8ff) {\n return '•';\n }\n\n // If it's a control character or non-printable, use bullet\n if (charCode < 32 || (charCode >= 127 && charCode < 160)) {\n return '•';\n }\n\n // Otherwise, use the character as-is (might be a valid Unicode bullet)\n return bulletChar;\n}\n\n/**\n * Compute the actual list marker for a paragraph\n *\n * Replaces %1, %2, etc. in lvlText with actual counter values.\n * Tracks and increments counters as list items are encountered.\n *\n * @param paragraph - The paragraph to compute marker for\n * @param numbering - Numbering definitions\n * @param listCounters - Map tracking counters per numId\n */\nfunction computeListMarker(\n paragraph: Paragraph,\n numbering: NumberingMap | null,\n listCounters: Map<number, number[]>\n): void {\n const listRendering = paragraph.listRendering;\n if (!listRendering || !numbering) return;\n\n const { numId, level } = listRendering;\n if (numId === undefined || numId === 0) return;\n\n // Initialize counters for this numId if not exists\n if (!listCounters.has(numId)) {\n listCounters.set(numId, new Array(9).fill(0)); // Up to 9 levels\n }\n\n const counters = listCounters.get(numId)!;\n\n // Increment counter at current level\n counters[level] = (counters[level] || 0) + 1;\n\n // Reset all deeper level counters when we go to a shallower level\n for (let i = level + 1; i < counters.length; i++) {\n counters[i] = 0;\n }\n\n // Get the lvlText pattern (e.g., \"%1.%2.%3.\")\n const pattern = listRendering.marker;\n\n // For bullet lists, convert Symbol font characters to proper Unicode\n if (listRendering.isBullet) {\n // DOCX often uses Symbol font characters that don't render correctly\n // Map common Symbol font codes to Unicode equivalents\n const bulletChar = pattern || '';\n listRendering.marker = convertBulletToUnicode(bulletChar);\n return;\n }\n\n // Compute the actual marker by replacing %1, %2, etc.\n let computedMarker = pattern;\n\n // Replace %1, %2, etc. with actual counter values\n // Format each level according to its numFmt\n for (let lvl = 0; lvl <= level; lvl++) {\n const placeholder = `%${lvl + 1}`;\n if (computedMarker.includes(placeholder)) {\n const value = counters[lvl];\n const levelInfo = numbering.getLevel(numId, lvl);\n const formatted = formatNumber(value, levelInfo?.numFmt || 'decimal');\n computedMarker = computedMarker.replace(placeholder, formatted);\n }\n }\n\n // Update the marker with the computed value\n listRendering.marker = computedMarker;\n}\n\n/**\n * Format a number according to OOXML number format\n */\nfunction formatNumber(value: number, numFmt: string): string {\n switch (numFmt) {\n case 'decimal':\n case 'decimalZero':\n return String(value);\n case 'lowerLetter':\n return String.fromCharCode(96 + ((value - 1) % 26) + 1); // a, b, c...\n case 'upperLetter':\n return String.fromCharCode(64 + ((value - 1) % 26) + 1); // A, B, C...\n case 'lowerRoman':\n return toRoman(value).toLowerCase();\n case 'upperRoman':\n return toRoman(value);\n case 'bullet':\n return '•';\n default:\n return String(value);\n }\n}\n\n/**\n * Convert number to Roman numerals\n */\nfunction toRoman(num: number): string {\n const romanNumerals: [number, string][] = [\n [1000, 'M'],\n [900, 'CM'],\n [500, 'D'],\n [400, 'CD'],\n [100, 'C'],\n [90, 'XC'],\n [50, 'L'],\n [40, 'XL'],\n [10, 'X'],\n [9, 'IX'],\n [5, 'V'],\n [4, 'IV'],\n [1, 'I'],\n ];\n\n let result = '';\n for (const [value, symbol] of romanNumerals) {\n while (num >= value) {\n result += symbol;\n num -= value;\n }\n }\n return result;\n}\n\n// ============================================================================\n// TEMPLATE VARIABLE DETECTION\n// ============================================================================\n\n/**\n * Regular expression to match template variables {{...}}\n */\nconst TEMPLATE_VARIABLE_REGEX = /\\{([a-zA-Z_][a-zA-Z0-9_\\-\\.]*)\\}/g;\n\n/**\n * Extract template variables from text\n *\n * @param text - Text to search for variables\n * @returns Array of unique variable names (without braces)\n */\nexport function extractTemplateVariables(text: string): string[] {\n const variables: string[] = [];\n let match: RegExpExecArray | null;\n\n // Reset regex state\n TEMPLATE_VARIABLE_REGEX.lastIndex = 0;\n\n while ((match = TEMPLATE_VARIABLE_REGEX.exec(text)) !== null) {\n const varName = match[1].trim();\n if (varName && !variables.includes(varName)) {\n variables.push(varName);\n }\n }\n\n return variables;\n}\n\n/**\n * Extract all template variables from document content\n *\n * @param content - Array of paragraphs and tables\n * @returns Array of unique variable names\n */\nexport function extractAllTemplateVariables(content: BlockContent[]): string[] {\n const variables: string[] = [];\n\n for (const block of content) {\n if (block.type === 'paragraph') {\n const text = getParagraphText(block);\n const vars = extractTemplateVariables(text);\n for (const v of vars) {\n if (!variables.includes(v)) {\n variables.push(v);\n }\n }\n } else if (block.type === 'table') {\n // Recursively check table cells\n const tableVars = extractTableVariables(block);\n for (const v of tableVars) {\n if (!variables.includes(v)) {\n variables.push(v);\n }\n }\n }\n }\n\n return variables;\n}\n\n/**\n * Extract template variables from a table\n */\nfunction extractTableVariables(table: Table): string[] {\n const variables: string[] = [];\n\n for (const row of table.rows) {\n for (const cell of row.cells) {\n for (const cellContent of cell.content) {\n if (cellContent.type === 'paragraph') {\n const text = getParagraphText(cellContent);\n const vars = extractTemplateVariables(text);\n for (const v of vars) {\n if (!variables.includes(v)) {\n variables.push(v);\n }\n }\n } else if (cellContent.type === 'table') {\n // Nested table\n const nestedVars = extractTableVariables(cellContent);\n for (const v of nestedVars) {\n if (!variables.includes(v)) {\n variables.push(v);\n }\n }\n }\n }\n }\n }\n\n return variables;\n}\n\n// ============================================================================\n// TEXT BOX ENRICHMENT\n// ============================================================================\n\n/**\n * Enrich a parsed paragraph with text box content from its raw XML.\n *\n * During initial parsing, w:drawing elements containing text boxes (wps:wsp with wps:txbx)\n * are skipped because parseImage returns null for non-image drawings. This function does\n * a second pass over the raw XML to find text box drawings, parse them with their content,\n * and inject ShapeContent into the paragraph's runs.\n */\nfunction enrichParagraphTextBoxes(\n paragraph: Paragraph,\n paraXml: XmlElement,\n styles: StyleMap | null,\n theme: Theme | null,\n numbering: NumberingMap | null,\n rels: RelationshipMap | null,\n media: Map<string, MediaFile> | null\n): void {\n // Early exit: skip paragraphs with no runs (most paragraphs have no text boxes)\n if (paragraph.content.length === 0) return;\n\n const xmlChildren = getChildElements(paraXml);\n\n // Track which run we're on (to match XML runs with parsed runs)\n let runIndex = 0;\n\n for (const xmlChild of xmlChildren) {\n if (getLocalName(xmlChild.name ?? '') !== 'r') continue;\n\n // Find w:drawing children in this run\n const runElements = getChildElements(xmlChild);\n for (const runEl of runElements) {\n if (getLocalName(runEl.name ?? '') === 'drawing' && isTextBoxDrawing(runEl)) {\n // Parse the text box structure\n const textBox = parseTextBox(runEl);\n if (textBox) {\n // Navigate to wps:wsp to get the txbxContent element\n const wsp = findDeep(runEl, 'wps', 'wsp');\n if (wsp) {\n const txbxContentEl = getTextBoxContentElement(wsp);\n if (txbxContentEl) {\n textBox.content = parseTextBoxContent(\n txbxContentEl,\n parseParagraph,\n null, // table parser not needed for most text boxes\n styles,\n theme,\n numbering,\n rels ?? undefined,\n media ?? undefined\n );\n }\n }\n\n // Convert to Shape with textBody and inject as ShapeContent\n const shape: Shape = {\n type: 'shape',\n shapeType: 'rect',\n size: textBox.size,\n position: textBox.position,\n wrap: textBox.wrap,\n fill: textBox.fill,\n outline: textBox.outline,\n textBody: {\n content: textBox.content,\n margins: textBox.margins,\n },\n };\n if (textBox.id) shape.id = textBox.id;\n\n const shapeContent: ShapeContent = { type: 'shape', shape };\n\n // Find the matching parsed run and inject the ShapeContent\n if (runIndex < paragraph.content.length) {\n const parsedContent = paragraph.content[runIndex];\n if (parsedContent.type === 'run') {\n parsedContent.content.push(shapeContent);\n }\n }\n }\n }\n }\n\n runIndex++;\n }\n}\n\n// ============================================================================\n// CONTENT PARSING\n// ============================================================================\n\n/**\n * Parse block content from an element (body or SDT content)\n *\n * @param parent - Parent element containing content\n * @param styles - Style map\n * @param theme - Theme\n * @param numbering - Numbering definitions\n * @param rels - Relationships\n * @param media - Media files\n * @returns Array of block content (paragraphs, tables)\n */\nfunction parseBlockContent(\n parent: XmlElement,\n styles: StyleMap | null,\n theme: Theme | null,\n numbering: NumberingMap | null,\n rels: RelationshipMap | null,\n media: Map<string, MediaFile> | null\n): BlockContent[] {\n const content: BlockContent[] = [];\n const children = getChildElements(parent);\n\n // Track list counters for computing markers\n // Map: numId -> array of counters for each level\n const listCounters = new Map<number, number[]>();\n\n for (const child of children) {\n const name = child.name ?? '';\n\n // Paragraph (w:p)\n if (name === 'w:p' || name.endsWith(':p')) {\n const paragraph = parseParagraph(child, styles, theme, numbering, rels, media);\n // Enrich with text box content (parsed in a second pass to avoid circular deps)\n enrichParagraphTextBoxes(paragraph, child, styles, theme, numbering, rels, media);\n // Compute list marker if this is a list item\n computeListMarker(paragraph, numbering, listCounters);\n content.push(paragraph);\n }\n // Table (w:tbl)\n else if (name === 'w:tbl' || name.endsWith(':tbl')) {\n const table = parseTable(child, styles, theme, numbering, rels, media);\n content.push(table);\n }\n // Structured Document Tag (w:sdt) - container for content\n else if (name === 'w:sdt' || name.endsWith(':sdt')) {\n // Find the content element inside SDT\n const sdtContent = (child.elements ?? []).find(\n (el: XmlElement) =>\n el.type === 'element' && (el.name === 'w:sdtContent' || el.name?.endsWith(':sdtContent'))\n );\n if (sdtContent) {\n // Recursively parse content inside SDT\n const sdtBlockContent = parseBlockContent(\n sdtContent,\n styles,\n theme,\n numbering,\n rels,\n media\n );\n content.push(...sdtBlockContent);\n }\n }\n // Section properties (w:sectPr) - handled separately at body level\n // Skip here as we handle it after content parsing\n }\n\n return content;\n}\n\n// ============================================================================\n// SECTION BUILDING\n// ============================================================================\n\n/**\n * Build sections from content based on section properties in paragraphs\n *\n * In OOXML, sections are delimited by:\n * 1. w:pPr/w:sectPr within a paragraph (marks end of a section)\n * 2. w:body/w:sectPr (final section properties)\n *\n * @param content - All block content\n * @param finalSectPr - Final section properties from body\n * @returns Array of sections\n */\nfunction buildSections(\n content: BlockContent[],\n finalSectPr: SectionProperties | undefined\n): Section[] {\n const sections: Section[] = [];\n let currentSectionContent: BlockContent[] = [];\n\n for (const block of content) {\n currentSectionContent.push(block);\n\n // Check if this paragraph ends a section\n if (block.type === 'paragraph' && block.sectionProperties) {\n // This paragraph ends a section\n sections.push({\n properties: block.sectionProperties,\n content: currentSectionContent,\n });\n\n // Start new section\n currentSectionContent = [];\n }\n }\n\n // Add final section with remaining content\n if (currentSectionContent.length > 0 || sections.length === 0) {\n sections.push({\n properties: finalSectPr ?? getDefaultSectionProperties(),\n content: currentSectionContent,\n });\n }\n\n return sections;\n}\n\n// ============================================================================\n// MAIN PARSER\n// ============================================================================\n\n/**\n * Parse document.xml body content\n *\n * @param xml - Raw XML content of document.xml\n * @param styles - Parsed style map\n * @param theme - Parsed theme\n * @param numbering - Parsed numbering definitions\n * @param rels - Document relationships\n * @param media - Media files\n * @returns DocumentBody with content, sections, and template variables\n */\nexport function parseDocumentBody(\n xml: string,\n styles: StyleMap | null = null,\n theme: Theme | null = null,\n numbering: NumberingMap | null = null,\n rels: RelationshipMap | null = null,\n media: Map<string, MediaFile> | null = null\n): DocumentBody {\n const result: DocumentBody = {\n content: [],\n };\n\n if (!xml) {\n return result;\n }\n\n // Parse XML\n const doc = parseXml(xml);\n if (!doc) {\n return result;\n }\n\n // Find root document element (w:document)\n const documentEl = (doc.elements ?? []).find(\n (el: XmlElement) =>\n el.type === 'element' && (el.name === 'w:document' || el.name?.endsWith(':document'))\n );\n if (!documentEl) {\n return result;\n }\n\n // Find body element (w:body)\n const bodyEl = findChild(documentEl, 'w', 'body');\n if (!bodyEl) {\n return result;\n }\n\n // Parse all block content (paragraphs, tables)\n result.content = parseBlockContent(bodyEl, styles, theme, numbering, rels, media);\n\n // Parse final section properties (w:body/w:sectPr)\n const finalSectPr = findChild(bodyEl, 'w', 'sectPr');\n if (finalSectPr) {\n result.finalSectionProperties = parseSectionProperties(finalSectPr, rels);\n }\n\n // Build sections from content\n result.sections = buildSections(result.content, result.finalSectionProperties);\n\n return result;\n}\n\n// ============================================================================\n// UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Get all paragraphs from document body (flattened)\n */\nexport function getAllParagraphs(body: DocumentBody): Paragraph[] {\n const paragraphs: Paragraph[] = [];\n\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n paragraphs.push(block);\n } else if (block.type === 'table') {\n // Get paragraphs from table cells\n paragraphs.push(...getTableParagraphs(block));\n }\n }\n\n return paragraphs;\n}\n\n/**\n * Get all paragraphs from a table (recursively)\n */\nfunction getTableParagraphs(table: Table): Paragraph[] {\n const paragraphs: Paragraph[] = [];\n\n for (const row of table.rows) {\n for (const cell of row.cells) {\n for (const content of cell.content) {\n if (content.type === 'paragraph') {\n paragraphs.push(content);\n } else if (content.type === 'table') {\n paragraphs.push(...getTableParagraphs(content));\n }\n }\n }\n }\n\n return paragraphs;\n}\n\n/**\n * Get all tables from document body\n */\nexport function getAllTables(body: DocumentBody): Table[] {\n const tables: Table[] = [];\n\n for (const block of body.content) {\n if (block.type === 'table') {\n tables.push(block);\n // Also get nested tables\n tables.push(...getNestedTables(block));\n }\n }\n\n return tables;\n}\n\n/**\n * Get nested tables from a table (recursively)\n */\nfunction getNestedTables(table: Table): Table[] {\n const tables: Table[] = [];\n\n for (const row of table.rows) {\n for (const cell of row.cells) {\n for (const content of cell.content) {\n if (content.type === 'table') {\n tables.push(content);\n tables.push(...getNestedTables(content));\n }\n }\n }\n }\n\n return tables;\n}\n\n/**\n * Get plain text from entire document body\n */\nexport function getDocumentText(body: DocumentBody): string {\n const lines: string[] = [];\n\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n lines.push(getParagraphText(block));\n } else if (block.type === 'table') {\n lines.push(getTableText(block));\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Get plain text from a table\n */\nfunction getTableText(table: Table): string {\n const lines: string[] = [];\n\n for (const row of table.rows) {\n const rowTexts: string[] = [];\n for (const cell of row.cells) {\n const cellTexts: string[] = [];\n for (const content of cell.content) {\n if (content.type === 'paragraph') {\n cellTexts.push(getParagraphText(content));\n } else if (content.type === 'table') {\n cellTexts.push(getTableText(content));\n }\n }\n rowTexts.push(cellTexts.join('\\n'));\n }\n lines.push(rowTexts.join('\\t'));\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Count total paragraphs in document\n */\nexport function getParagraphCount(body: DocumentBody): number {\n return getAllParagraphs(body).length;\n}\n\n/**\n * Count total words in document (approximate)\n */\nexport function getWordCount(body: DocumentBody): number {\n const text = getDocumentText(body);\n // Simple word counting - split by whitespace\n const words = text.trim().split(/\\s+/);\n return words.length > 0 && words[0] !== '' ? words.length : 0;\n}\n\n/**\n * Count total characters in document\n */\nexport function getCharacterCount(body: DocumentBody): number {\n return getDocumentText(body).length;\n}\n\n/**\n * Get section count\n */\nexport function getSectionCount(body: DocumentBody): number {\n return body.sections?.length ?? 1;\n}\n\n/**\n * Check if document has template variables\n */\nexport function hasTemplateVariables(body: DocumentBody): boolean {\n return extractAllTemplateVariables(body.content).length > 0;\n}\n\n/**\n * Get document outline (first N characters of each paragraph)\n *\n * @param body - Document body\n * @param maxCharsPerPara - Max characters per paragraph (default: 100)\n * @param maxParagraphs - Max paragraphs to include (default: 50)\n * @returns Array of paragraph previews\n */\nexport function getDocumentOutline(\n body: DocumentBody,\n maxCharsPerPara: number = 100,\n maxParagraphs: number = 50\n): string[] {\n const outline: string[] = [];\n const paragraphs = getAllParagraphs(body);\n\n for (let i = 0; i < Math.min(paragraphs.length, maxParagraphs); i++) {\n const text = getParagraphText(paragraphs[i]).trim();\n if (text.length > 0) {\n outline.push(\n text.length > maxCharsPerPara ? text.substring(0, maxCharsPerPara) + '...' : text\n );\n }\n }\n\n return outline;\n}\n","/**\n * Comment Parser - Parse comments.xml and commentsExtensible.xml\n *\n * Parses OOXML comments (w:comment) from comments.xml file.\n * Cross-references with commentsExtensible.xml (or commentsExtended.xml)\n * to obtain reliable UTC timestamps via w16cex:dateUtc.\n *\n * Note: Microsoft Word stores w:date as local time WITHOUT timezone offset,\n * which is ambiguous. The reliable UTC timestamp lives in the separate\n * commentsExtensible.xml part (Word 2016+).\n *\n * OOXML Reference:\n * - Comments: w:comments\n * - Comment: w:comment (w:id, w:author, w:date, w:initials)\n * - Comment content: child w:p elements\n */\n\nimport type { Comment, Paragraph, Theme, RelationshipMap, MediaFile } from '../types/document';\nimport type { StyleMap } from './styleParser';\nimport { parseXml, findChild, getChildElements, getAttribute } from './xmlParser';\nimport { parseParagraph } from './paragraphParser';\n\n/**\n * Build a lookup from paraId → dateUtc from commentsExtensible.xml\n *\n * The XML structure is:\n * <w16cex:commentsExtensible>\n * <w16cex:comment w16cex:paraId=\"...\" w16cex:dateUtc=\"2024-02-10T14:30:45Z\"/>\n * </w16cex:commentsExtensible>\n */\nfunction parseCommentsExtensible(xml: string): Map<string, string> {\n const dateUtcByParaId = new Map<string, string>();\n\n const root = parseXml(xml);\n if (!root) return dateUtcByParaId;\n\n // Find the root element (may be w16cex:commentsExtensible or similar)\n const container = findChild(root, 'w16cex', 'commentsExtensible') ?? root;\n for (const child of getChildElements(container)) {\n const localName = child.name?.replace(/^.*:/, '') ?? '';\n if (localName !== 'comment') continue;\n\n // Try multiple namespace prefixes since they vary between Word versions\n const paraId =\n getAttribute(child, 'w16cex', 'paraId') ??\n getAttribute(child, 'w15', 'paraId') ??\n child.attributes?.['w16cex:paraId'] ??\n child.attributes?.['w15:paraId'];\n\n const dateUtc =\n getAttribute(child, 'w16cex', 'dateUtc') ??\n getAttribute(child, 'w15', 'dateUtc') ??\n child.attributes?.['w16cex:dateUtc'] ??\n child.attributes?.['w15:dateUtc'];\n\n if (paraId && dateUtc) {\n dateUtcByParaId.set(String(paraId).toUpperCase(), String(dateUtc));\n }\n }\n\n return dateUtcByParaId;\n}\n\n/**\n * Parse comments.xml into an array of Comment objects.\n *\n * If commentsExtensibleXml is provided, UTC timestamps are cross-referenced\n * via paraId and preferred over the ambiguous w:date local time.\n */\nexport function parseComments(\n commentsXml: string | null,\n styles: StyleMap | null,\n theme: Theme | null,\n rels: RelationshipMap,\n media: Map<string, MediaFile>,\n commentsExtensibleXml?: string | null\n): Comment[] {\n if (!commentsXml) return [];\n\n const root = parseXml(commentsXml);\n if (!root) return [];\n\n // Build UTC date lookup from extended comments (if available)\n const dateUtcByParaId = commentsExtensibleXml\n ? parseCommentsExtensible(commentsExtensibleXml)\n : new Map<string, string>();\n\n const commentsEl = findChild(root, 'w', 'comments') ?? root;\n const children = getChildElements(commentsEl);\n const comments: Comment[] = [];\n\n for (const child of children) {\n const localName = child.name?.replace(/^.*:/, '') ?? '';\n if (localName !== 'comment') continue;\n\n const id = parseInt(getAttribute(child, 'w', 'id') ?? '0', 10);\n const author = getAttribute(child, 'w', 'author') ?? 'Unknown';\n const rawInitials = getAttribute(child, 'w', 'initials');\n const initials = rawInitials != null ? String(rawInitials) : undefined;\n const rawDate = getAttribute(child, 'w', 'date');\n const localDate = rawDate != null ? String(rawDate) : undefined;\n\n // Try to find the UTC date from commentsExtensible.xml via paraId\n const paraId =\n getAttribute(child, 'w14', 'paraId') ??\n child.attributes?.['w14:paraId'] ??\n getAttribute(child, 'w', 'paraId');\n const dateUtc = paraId ? dateUtcByParaId.get(String(paraId).toUpperCase()) : undefined;\n\n // Prefer UTC date over ambiguous local date\n const date = dateUtc ?? localDate;\n\n // Parse comment content (paragraphs)\n const paragraphs: Paragraph[] = [];\n for (const contentChild of getChildElements(child)) {\n const contentName = contentChild.name?.replace(/^.*:/, '') ?? '';\n if (contentName === 'p') {\n const paragraph = parseParagraph(contentChild, styles, theme, null, rels, media);\n paragraphs.push(paragraph);\n }\n }\n\n comments.push({\n id,\n author,\n initials,\n date,\n content: paragraphs,\n });\n }\n\n return comments;\n}\n","/**\n * Google Fonts Loader\n *\n * Dynamically loads fonts from Google Fonts API with:\n * - Loading state tracking\n * - Duplicate prevention\n * - Callback notifications\n * - Font availability detection\n */\n\n// Track loaded fonts to avoid duplicate requests\nconst loadedFonts = new Set<string>();\n\n// Track fonts currently being loaded\nconst loadingFonts = new Map<string, Promise<boolean>>();\n\n// Callbacks to notify when fonts are loaded\nconst loadCallbacks = new Set<(fonts: string[]) => void>();\n\n// Track overall loading state\nlet isLoadingAny = false;\n\n/**\n * Generate Google Fonts CSS URL for a font family\n *\n * @param fontFamily - The font family name (e.g., \"Roboto\", \"Open Sans\")\n * @param weights - Font weights to load (default: 400, 700)\n * @param styles - Font styles to load (default: normal, italic)\n * @returns Google Fonts CSS URL\n */\nfunction getGoogleFontsUrl(\n fontFamily: string,\n weights: number[] = [400, 700],\n styles: ('normal' | 'italic')[] = ['normal', 'italic']\n): string {\n // Encode font family name for URL\n const encodedFamily = encodeURIComponent(fontFamily);\n\n // Build weight/style combinations\n // Format: ital,wght@0,400;0,700;1,400;1,700\n const combinations: string[] = [];\n\n for (const style of styles) {\n const italVal = style === 'italic' ? 1 : 0;\n for (const weight of weights) {\n combinations.push(`${italVal},${weight}`);\n }\n }\n\n // Sort and join\n combinations.sort();\n const spec = combinations.join(';');\n\n return `https://fonts.googleapis.com/css2?family=${encodedFamily}:ital,wght@${spec}&display=swap`;\n}\n\n/**\n * Load a font from Google Fonts\n *\n * @param fontFamily - The font family name to load\n * @param options - Optional configuration\n * @returns Promise resolving to true if font loaded successfully, false otherwise\n */\nexport async function loadFont(\n fontFamily: string,\n options?: {\n weights?: number[];\n styles?: ('normal' | 'italic')[];\n }\n): Promise<boolean> {\n // Skip font loading in non-browser environments (Node.js, SSR)\n if (typeof document === 'undefined') {\n return false;\n }\n\n // Normalize font family name\n const normalizedFamily = fontFamily.trim();\n\n // Already loaded?\n if (loadedFonts.has(normalizedFamily)) {\n return true;\n }\n\n // Currently loading? Return existing promise\n const existingLoad = loadingFonts.get(normalizedFamily);\n if (existingLoad) {\n return existingLoad;\n }\n\n // Create load promise\n const loadPromise = (async (): Promise<boolean> => {\n isLoadingAny = true;\n\n try {\n // Generate Google Fonts URL\n const url = getGoogleFontsUrl(normalizedFamily, options?.weights, options?.styles);\n\n // Create link element\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = url;\n\n // Wait for load or error\n const loaded = await new Promise<boolean>((resolve) => {\n link.onload = () => resolve(true);\n link.onerror = () => resolve(false);\n\n // Append to head\n document.head.appendChild(link);\n\n // Timeout after 5 seconds\n setTimeout(() => resolve(false), 5000);\n });\n\n if (loaded) {\n // Wait a bit for the font to be available\n await waitForFontAvailable(normalizedFamily, 3000);\n\n loadedFonts.add(normalizedFamily);\n\n // Notify callbacks\n notifyCallbacks([normalizedFamily]);\n\n return true;\n }\n\n return false;\n } catch (error) {\n console.warn(`Failed to load font \"${normalizedFamily}\":`, error);\n return false;\n } finally {\n loadingFonts.delete(normalizedFamily);\n\n // Check if still loading any fonts\n if (loadingFonts.size === 0) {\n isLoadingAny = false;\n }\n }\n })();\n\n loadingFonts.set(normalizedFamily, loadPromise);\n return loadPromise;\n}\n\n/**\n * Load multiple fonts from Google Fonts\n *\n * @param families - Array of font family names to load\n * @param options - Optional configuration\n * @returns Promise resolving when all fonts are loaded (or failed)\n */\nexport async function loadFonts(\n families: string[],\n options?: {\n weights?: number[];\n styles?: ('normal' | 'italic')[];\n }\n): Promise<void> {\n // Filter out already loaded fonts\n const toLoad = families.filter((family) => !loadedFonts.has(family.trim()));\n\n if (toLoad.length === 0) {\n return;\n }\n\n // Load all fonts in parallel\n await Promise.all(toLoad.map((family) => loadFont(family, options)));\n}\n\n/**\n * Check if a font is loaded\n *\n * @param fontFamily - The font family name to check\n * @returns true if the font is loaded, false otherwise\n */\nexport function isFontLoaded(fontFamily: string): boolean {\n return loadedFonts.has(fontFamily.trim());\n}\n\n/**\n * Check if any fonts are currently loading\n *\n * @returns true if any fonts are loading, false otherwise\n */\nexport function isLoading(): boolean {\n return isLoadingAny;\n}\n\n/**\n * Get list of all loaded fonts\n *\n * @returns Array of loaded font family names\n */\nexport function getLoadedFonts(): string[] {\n return Array.from(loadedFonts);\n}\n\n/**\n * Register a callback to be notified when fonts are loaded\n *\n * @param callback - Function to call when fonts are loaded\n * @returns Cleanup function to remove the callback\n */\nexport function onFontsLoaded(callback: (fonts: string[]) => void): () => void {\n loadCallbacks.add(callback);\n\n // Return cleanup function\n return () => {\n loadCallbacks.delete(callback);\n };\n}\n\n/**\n * Notify all registered callbacks\n */\nfunction notifyCallbacks(fonts: string[]): void {\n for (const callback of loadCallbacks) {\n try {\n callback(fonts);\n } catch (error) {\n console.warn('Font load callback error:', error);\n }\n }\n}\n\n/**\n * Wait for a font to be available using the CSS Font Loading API\n *\n * @param fontFamily - The font family to wait for\n * @param timeout - Maximum time to wait in milliseconds\n * @returns Promise resolving when font is available or timeout\n */\nasync function waitForFontAvailable(fontFamily: string, timeout: number): Promise<boolean> {\n // Use CSS Font Loading API if available\n if ('fonts' in document) {\n try {\n // Try to wait for the font\n const fontFace = `400 16px \"${fontFamily}\"`;\n await Promise.race([\n document.fonts.load(fontFace),\n new Promise((resolve) => setTimeout(resolve, timeout)),\n ]);\n\n return document.fonts.check(fontFace);\n } catch {\n // Fall through to fallback\n }\n }\n\n // Fallback: just wait a bit\n await new Promise((resolve) => setTimeout(resolve, 100));\n return true;\n}\n\n/**\n * Check if a font is available on the system using canvas measurement\n *\n * This uses the technique of comparing text width with the target font\n * vs a known fallback font. If they differ, the font is available.\n *\n * @param fontFamily - The font family name to check\n * @param fallbackFont - Fallback font to compare against\n * @returns true if font is available, false otherwise\n */\nexport function canRenderFont(fontFamily: string, fallbackFont: string = 'sans-serif'): boolean {\n // Skip if we're not in a browser\n if (typeof document === 'undefined') {\n return false;\n }\n\n const _canRenderFont = (fontName: string, fallback: string): boolean => {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n\n if (!ctx) {\n return false;\n }\n\n ctx.textBaseline = 'top';\n\n const text = 'abcdefghijklmnopqrstuvwxyz0123456789';\n\n // Measure with fallback font only\n ctx.font = `72px ${fallback}`;\n const fallbackWidth = ctx.measureText(text).width;\n\n // Measure with target font (with fallback)\n ctx.font = `72px \"${fontName}\", ${fallback}`;\n const customWidth = ctx.measureText(text).width;\n\n // If widths differ, the custom font was used\n return customWidth !== fallbackWidth;\n };\n\n // Check with primary fallback\n if (_canRenderFont(fontFamily, fallbackFont)) {\n return true;\n }\n\n // Check with opposite fallback (handles edge case where font name\n // matches the browser's default sans-serif or serif)\n const oppositeFallback = fallbackFont === 'sans-serif' ? 'serif' : 'sans-serif';\n return _canRenderFont(fontFamily, oppositeFallback);\n}\n\n/**\n * Load a font from a raw buffer (e.g., embedded in DOCX)\n *\n * @param fontFamily - The font family name\n * @param buffer - Font file buffer (TTF, OTF, WOFF, WOFF2)\n * @param options - Font options\n * @returns Promise resolving when font is loaded\n */\nexport async function loadFontFromBuffer(\n fontFamily: string,\n buffer: ArrayBuffer,\n options?: {\n weight?: number | string;\n style?: 'normal' | 'italic';\n }\n): Promise<boolean> {\n const normalizedFamily = fontFamily.trim();\n\n // Already loaded?\n if (loadedFonts.has(normalizedFamily)) {\n return true;\n }\n\n try {\n // Create blob URL\n const blob = new Blob([buffer], { type: 'font/ttf' });\n const url = URL.createObjectURL(blob);\n\n // Create @font-face CSS\n const style = document.createElement('style');\n style.textContent = `\n @font-face {\n font-family: \"${normalizedFamily}\";\n src: url(${url}) format('truetype');\n font-weight: ${options?.weight ?? 'normal'};\n font-style: ${options?.style ?? 'normal'};\n font-display: swap;\n }\n `;\n\n document.head.appendChild(style);\n\n // Wait for font to be available\n await waitForFontAvailable(normalizedFamily, 3000);\n\n loadedFonts.add(normalizedFamily);\n notifyCallbacks([normalizedFamily]);\n\n return true;\n } catch (error) {\n console.warn(`Failed to load font \"${normalizedFamily}\" from buffer:`, error);\n return false;\n }\n}\n\n/**\n * Mapping from common Office/system fonts to Google Fonts equivalents\n *\n * Google Fonts doesn't have exact matches for many Microsoft fonts,\n * but these are close alternatives that work well for document rendering.\n */\nexport const FONT_MAPPING: Record<string, string> = {\n // Microsoft Office fonts → Google Fonts equivalents\n Calibri: 'Carlito',\n Cambria: 'Caladea',\n Arial: 'Arimo',\n 'Times New Roman': 'Tinos',\n 'Courier New': 'Cousine',\n Garamond: 'EB Garamond',\n 'Book Antiqua': 'EB Garamond',\n Georgia: 'Tinos',\n Verdana: 'Open Sans',\n Tahoma: 'Open Sans',\n 'Trebuchet MS': 'Source Sans Pro',\n 'Century Gothic': 'Poppins',\n 'Franklin Gothic': 'Libre Franklin',\n Palatino: 'EB Garamond',\n 'Palatino Linotype': 'EB Garamond',\n 'Lucida Sans': 'Open Sans',\n 'Segoe UI': 'Open Sans',\n Impact: 'Anton',\n 'Comic Sans MS': 'Comic Neue',\n Consolas: 'Inconsolata',\n 'Lucida Console': 'Inconsolata',\n Monaco: 'Fira Code',\n};\n\n/**\n * Get the Google Fonts equivalent for a font name\n *\n * @param fontName - The original font name from the document\n * @returns The Google Fonts equivalent, or the original name if no mapping exists\n */\nexport function getGoogleFontEquivalent(fontName: string): string {\n const trimmed = fontName.trim();\n return FONT_MAPPING[trimmed] || trimmed;\n}\n\n/**\n * Load a font, automatically mapping to Google Fonts equivalent if needed.\n * If the font needs mapping, also creates a CSS alias so the original font\n * name works in stylesheets.\n *\n * @param fontFamily - The font family name (may be an Office font)\n * @returns Promise resolving to true if font loaded\n */\nexport async function loadFontWithMapping(fontFamily: string): Promise<boolean> {\n const trimmed = fontFamily.trim();\n const googleFont = getGoogleFontEquivalent(trimmed);\n\n // Load the Google Font under its own name (no aliasing).\n // The font resolver provides CSS fallback stacks that list both the\n // original DOCX font and the Google equivalent, so the browser will\n // use whichever is available without @font-face aliasing that would\n // hijack Canvas measurements.\n if (googleFont !== trimmed) {\n const result = await loadFont(googleFont);\n if (result) {\n loadedFonts.add(trimmed);\n }\n return result;\n }\n\n // No mapping needed, load directly\n return loadFont(googleFont);\n}\n\n/**\n * Load multiple fonts with automatic mapping to Google Fonts equivalents\n *\n * @param families - Array of font family names\n * @returns Promise resolving when all fonts are loaded\n */\nexport async function loadFontsWithMapping(families: string[]): Promise<void> {\n // Remove duplicates\n const uniqueFonts = [...new Set(families.map((f) => f.trim()))];\n // Load each font with mapping (creates aliases for Office → Google font mappings)\n await Promise.all(uniqueFonts.map((family) => loadFontWithMapping(family)));\n}\n\n/**\n * Preload a list of common document fonts\n *\n * This preloads fonts commonly used in DOCX documents that have\n * Google Fonts equivalents.\n */\nexport async function preloadCommonFonts(): Promise<void> {\n const commonFonts = [\n 'Carlito', // Calibri equivalent\n 'Caladea', // Cambria equivalent\n 'Arimo', // Arial equivalent\n 'Tinos', // Times New Roman equivalent\n 'Cousine', // Courier New equivalent\n 'EB Garamond', // Garamond equivalent\n ];\n\n await loadFonts(commonFonts);\n}\n\n/**\n * Extract all font families used in a document\n *\n * Uses loose typing to handle any document-like structure.\n *\n * @param document - The parsed document\n * @returns Set of unique font family names\n */\nexport function extractFontsFromDocument(document: unknown): Set<string> {\n const fonts = new Set<string>();\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const doc = document as any;\n if (!doc?.package) return fonts;\n\n // Extract from document content\n const content = doc.package?.document?.content;\n if (Array.isArray(content)) {\n for (const paragraph of content) {\n if (paragraph?.type === 'paragraph' && Array.isArray(paragraph.content)) {\n for (const run of paragraph.content) {\n if (run?.type === 'run' && run.formatting?.fontFamily) {\n const { ascii, hAnsi } = run.formatting.fontFamily;\n if (ascii) fonts.add(ascii);\n if (hAnsi && hAnsi !== ascii) fonts.add(hAnsi);\n }\n }\n }\n }\n }\n\n // Extract from styles\n const styles = doc.package?.styles?.styles;\n if (Array.isArray(styles)) {\n for (const style of styles) {\n if (style?.runProperties?.fontFamily) {\n const { ascii, hAnsi } = style.runProperties.fontFamily;\n if (ascii) fonts.add(ascii);\n if (hAnsi && hAnsi !== ascii) fonts.add(hAnsi);\n }\n }\n }\n\n return fonts;\n}\n\n/**\n * Extract fonts from a document and load them from Google Fonts\n *\n * @param document - The parsed document\n * @returns Promise resolving when fonts are loaded\n */\nexport async function loadDocumentFonts(document: unknown): Promise<void> {\n const fonts = extractFontsFromDocument(document);\n\n if (fonts.size === 0) {\n return;\n }\n\n // Loading document fonts\n await loadFontsWithMapping(Array.from(fonts));\n}\n","/**\n * Flexible input types for DOCX documents.\n *\n * Accepts any common binary format so consumers don't need to manually\n * convert before passing data to the editor or parser.\n */\n\n/**\n * Any binary representation of a DOCX file that the editor can consume.\n *\n * - `ArrayBuffer` — from `FileReader.readAsArrayBuffer()` or `fetch().arrayBuffer()`\n * - `Uint8Array` — from Node.js `fs.readFile()` or streaming APIs\n * - `Blob` — from drag-and-drop or `<input type=\"file\">`\n * - `File` — subclass of Blob, from `<input type=\"file\">`\n */\nexport type DocxInput = ArrayBuffer | Uint8Array | Blob | File;\n\n/**\n * Normalize any {@link DocxInput} into an `ArrayBuffer` for internal use.\n */\nexport async function toArrayBuffer(input: DocxInput): Promise<ArrayBuffer> {\n if (input instanceof ArrayBuffer) {\n return input;\n }\n if (input instanceof Uint8Array) {\n // Copy into a fresh ArrayBuffer (input may be a view over a larger or shared buffer)\n const copy = new ArrayBuffer(input.byteLength);\n new Uint8Array(copy).set(input);\n return copy;\n }\n if (input instanceof Blob) {\n // Blob and File both support arrayBuffer()\n return input.arrayBuffer();\n }\n // Exhaustive check — should never happen at runtime\n throw new TypeError(`Unsupported DocxInput type: ${typeof input}`);\n}\n","/**\n * Main Parser Orchestrator - Unified parseDocx function\n *\n * Coordinates all sub-parsers to produce a complete Document model.\n * Handles loading order, dependency resolution, and font preloading.\n *\n * Parsing order:\n * 1. Unzip DOCX package\n * 2. Parse relationships\n * 3. Parse theme (needed for style color/font resolution)\n * 4. Parse styles (depends on theme)\n * 5. Parse numbering\n * 6. Parse document body (depends on styles, theme, numbering, rels)\n * 7. Parse headers/footers (depends on styles, theme, numbering, rels)\n * 8. Parse footnotes/endnotes (depends on styles, theme, numbering, rels)\n * 9. Extract and load fonts\n * 10. Build media file map\n * 11. Assemble final Document\n */\n\nimport type {\n Document,\n DocxPackage,\n DocumentBody,\n Theme,\n Footnote,\n Endnote,\n HeaderFooter,\n RelationshipMap,\n MediaFile,\n StyleDefinitions,\n} from '../types/document';\nimport { unzipDocx, getMediaMimeType, type RawDocxContent } from './unzip';\nimport { parseRelationships, RELATIONSHIP_TYPES } from './relsParser';\nimport { parseTheme } from './themeParser';\nimport { parseStyles, parseStyleDefinitions, type StyleMap } from './styleParser';\nimport { parseNumbering, type NumberingMap } from './numberingParser';\nimport { parseDocumentBody, extractAllTemplateVariables } from './documentParser';\nimport { parseHeader, parseFooter } from './headerFooterParser';\nimport { parseFootnotes, parseEndnotes } from './footnoteParser';\nimport { parseComments } from './commentParser';\nimport { loadFontsWithMapping } from '../utils/fontLoader';\nimport { type DocxInput, toArrayBuffer } from '../utils/docxInput';\n\n// ============================================================================\n// PROGRESS CALLBACK\n// ============================================================================\n\n/**\n * Progress callback for tracking parsing stages\n */\nexport type ProgressCallback = (stage: string, percent: number) => void;\n\n/**\n * Parsing options\n */\nexport interface ParseOptions {\n /** Progress callback for tracking parsing stages */\n onProgress?: ProgressCallback;\n /** Whether to preload fonts (default: true) */\n preloadFonts?: boolean;\n /** Whether to parse headers/footers (default: true) */\n parseHeadersFooters?: boolean;\n /** Whether to parse footnotes/endnotes (default: true) */\n parseNotes?: boolean;\n /** Whether to detect template variables (default: true) */\n detectVariables?: boolean;\n}\n\n// ============================================================================\n// MAIN PARSER\n// ============================================================================\n\n/**\n * Parse a DOCX file into a complete Document model\n *\n * @param input - DOCX file as ArrayBuffer, Uint8Array, Blob, or File\n * @param options - Parsing options\n * @returns Promise resolving to Document\n * @throws Error if parsing fails\n */\nexport async function parseDocx(input: DocxInput, options: ParseOptions = {}): Promise<Document> {\n // Normalize any supported input type to ArrayBuffer\n const buffer = input instanceof ArrayBuffer ? input : await toArrayBuffer(input);\n const {\n onProgress = () => {},\n preloadFonts = true,\n parseHeadersFooters = true,\n parseNotes = true,\n detectVariables = true,\n } = options;\n\n const warnings: string[] = [];\n\n try {\n const parseStart = performance.now();\n const stageTimings: Array<{ stage: string; ms: number }> = [];\n\n function timeStage<T>(name: string, fn: () => T): T {\n const start = performance.now();\n const result = fn();\n const elapsed = performance.now() - start;\n stageTimings.push({ stage: name, ms: elapsed });\n if (elapsed > 1000) {\n console.warn(`[parseDocx] ${name} took ${Math.round(elapsed)}ms`);\n }\n return result;\n }\n\n async function timeStageAsync<T>(name: string, fn: () => Promise<T>): Promise<T> {\n const start = performance.now();\n const result = await fn();\n const elapsed = performance.now() - start;\n stageTimings.push({ stage: name, ms: elapsed });\n if (elapsed > 1000) {\n console.warn(`[parseDocx] ${name} took ${Math.round(elapsed)}ms`);\n }\n return result;\n }\n\n // ========================================================================\n // STAGE 1: Unzip DOCX package (0-10%)\n // ========================================================================\n onProgress('Extracting DOCX...', 0);\n const raw = await timeStageAsync('unzip', () => unzipDocx(buffer));\n onProgress('Extracted DOCX', 10);\n\n // ========================================================================\n // STAGE 2: Parse relationships (10-15%)\n // ========================================================================\n onProgress('Parsing relationships...', 10);\n const rels = timeStage('relationships', () =>\n raw.documentRels ? parseRelationships(raw.documentRels) : new Map()\n );\n onProgress('Parsed relationships', 15);\n\n // ========================================================================\n // STAGE 3: Parse theme (15-20%)\n // ========================================================================\n onProgress('Parsing theme...', 15);\n const theme = timeStage('theme', () => parseTheme(raw.themeXml));\n onProgress('Parsed theme', 20);\n\n // ========================================================================\n // STAGE 4: Parse styles (20-30%)\n // ========================================================================\n onProgress('Parsing styles...', 20);\n let styles: StyleMap | null = null;\n let styleDefinitions: StyleDefinitions | undefined;\n\n timeStage('styles', () => {\n if (raw.stylesXml) {\n styles = parseStyles(raw.stylesXml, theme);\n styleDefinitions = parseStyleDefinitions(raw.stylesXml, theme);\n }\n });\n onProgress('Parsed styles', 30);\n\n // ========================================================================\n // STAGE 5: Parse numbering (30-35%)\n // ========================================================================\n onProgress('Parsing numbering...', 30);\n const numbering = timeStage('numbering', () => parseNumbering(raw.numberingXml));\n onProgress('Parsed numbering', 35);\n\n // ========================================================================\n // STAGE 6: Build media file map (35-40%)\n // ========================================================================\n onProgress('Processing media files...', 35);\n const media = timeStage('media', () => buildMediaMap(raw, rels));\n onProgress('Processed media', 40);\n\n // ========================================================================\n // STAGE 7: Parse document body (40-55%)\n // ========================================================================\n onProgress('Parsing document body...', 40);\n let documentBody: DocumentBody = { content: [] };\n\n timeStage('documentBody', () => {\n if (raw.documentXml) {\n documentBody = parseDocumentBody(raw.documentXml, styles, theme, numbering, rels, media);\n } else {\n warnings.push('No document.xml found in DOCX');\n }\n });\n onProgress('Parsed document body', 55);\n\n // ========================================================================\n // STAGE 8: Parse headers/footers (55-65%)\n // ========================================================================\n let headers: Map<string, HeaderFooter> | undefined;\n let footers: Map<string, HeaderFooter> | undefined;\n\n if (parseHeadersFooters) {\n onProgress('Parsing headers/footers...', 55);\n const hf = timeStage('headersFooters', () =>\n parseHeadersAndFooters(raw, styles, theme, numbering, rels, media)\n );\n headers = hf.headers;\n footers = hf.footers;\n onProgress('Parsed headers/footers', 65);\n } else {\n onProgress('Skipping headers/footers', 65);\n }\n\n // ========================================================================\n // STAGE 9: Parse footnotes/endnotes (65-75%)\n // ========================================================================\n let footnotes: Footnote[] | undefined;\n let endnotes: Endnote[] | undefined;\n\n if (parseNotes) {\n onProgress('Parsing footnotes/endnotes...', 65);\n const notes = timeStage('footnotesEndnotes', () =>\n parseNotesContent(raw, styles, theme, numbering, rels, media)\n );\n footnotes = notes.footnotes;\n endnotes = notes.endnotes;\n onProgress('Parsed footnotes/endnotes', 75);\n } else {\n onProgress('Skipping footnotes/endnotes', 75);\n }\n\n // ========================================================================\n // STAGE 9b: Parse comments (75-77%)\n // ========================================================================\n onProgress('Parsing comments...', 75);\n const comments = timeStage('comments', () =>\n parseComments(raw.commentsXml, styles, theme, rels, media, raw.commentsExtensibleXml)\n );\n if (comments.length > 0) {\n documentBody.comments = comments;\n }\n\n // ========================================================================\n // STAGE 10: Detect template variables (77-80%)\n // ========================================================================\n let templateVariables: string[] | undefined;\n\n if (detectVariables) {\n onProgress('Detecting template variables...', 75);\n templateVariables = timeStage('variables', () =>\n extractAllTemplateVariables(documentBody.content)\n );\n onProgress('Detected variables', 80);\n } else {\n onProgress('Skipping variable detection', 80);\n }\n\n // ========================================================================\n // STAGE 11: Extract and load fonts (80-95%)\n // ========================================================================\n if (preloadFonts) {\n onProgress('Loading fonts...', 80);\n await timeStageAsync('fonts', () => loadDocumentFonts(theme, styleDefinitions, documentBody));\n onProgress('Loaded fonts', 95);\n } else {\n onProgress('Skipping font loading', 95);\n }\n\n // ========================================================================\n // STAGE 12: Assemble final Document (95-100%)\n // ========================================================================\n onProgress('Assembling document...', 95);\n\n const pkg: DocxPackage = {\n document: documentBody,\n styles: styleDefinitions,\n theme,\n numbering: numbering.definitions,\n headers,\n footers,\n footnotes,\n endnotes,\n relationships: rels,\n media,\n };\n\n const document: Document = {\n package: pkg,\n originalBuffer: buffer,\n templateVariables,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n\n const totalTime = performance.now() - parseStart;\n if (totalTime > 2000) {\n const breakdown = stageTimings\n .filter((s) => s.ms > 100)\n .map((s) => `${s.stage}: ${Math.round(s.ms)}ms`)\n .join(', ');\n console.warn(\n `[parseDocx] Total: ${Math.round(totalTime)}ms` + (breakdown ? ` (${breakdown})` : '')\n );\n }\n\n onProgress('Complete', 100);\n return document;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error('[parseDocx] Failed to parse DOCX:', message, error);\n throw new Error(`Failed to parse DOCX: ${message}`);\n }\n}\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Build media file map from raw content and relationships\n */\nfunction buildMediaMap(raw: RawDocxContent, _rels: RelationshipMap): Map<string, MediaFile> {\n const media = new Map<string, MediaFile>();\n\n // Process each media file\n for (const [path, data] of raw.media.entries()) {\n const filename = path.split('/').pop() || path;\n const mimeType = getMediaMimeType(path);\n\n // Create a data URL for the image\n const bytes = new Uint8Array(data);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n const base64 = btoa(binary);\n const dataUrl = `data:${mimeType};base64,${base64}`;\n\n const mediaFile: MediaFile = {\n path,\n filename,\n mimeType,\n data,\n dataUrl,\n };\n\n // Store by path and also by relationship target path\n media.set(path, mediaFile);\n\n // Also map normalized paths (without \"word/\" prefix)\n const normalizedPath = path.replace(/^word\\//, '');\n if (normalizedPath !== path) {\n media.set(normalizedPath, mediaFile);\n }\n }\n\n return media;\n}\n\n/**\n * Parse headers and footers from raw content\n */\n/**\n * Case-insensitive lookup in a Map\n * ZIP files may have inconsistent casing for paths/filenames\n */\nfunction getMapCaseInsensitive<T>(map: Map<string, T>, targetKey: string): T | undefined {\n const lowerTarget = targetKey.toLowerCase();\n for (const [key, value] of map.entries()) {\n if (key.toLowerCase() === lowerTarget) {\n return value;\n }\n }\n return undefined;\n}\n\nfunction parseHeadersAndFooters(\n raw: RawDocxContent,\n styles: StyleMap | null,\n theme: Theme | null,\n numbering: NumberingMap | null,\n rels: RelationshipMap,\n media: Map<string, MediaFile>\n): { headers: Map<string, HeaderFooter>; footers: Map<string, HeaderFooter> } {\n const headers = new Map<string, HeaderFooter>();\n const footers = new Map<string, HeaderFooter>();\n\n // We need to map the relationship IDs to header/footer files\n // The relationships tell us which rId maps to which header/footer file\n\n // Find header/footer references in relationships\n for (const [rId, rel] of rels.entries()) {\n if (rel.type === RELATIONSHIP_TYPES.header && rel.target) {\n // Get the header XML for this relationship\n // Use case-insensitive lookup since ZIP files may have inconsistent casing\n const filename = rel.target.split('/').pop() || rel.target;\n const headerXml = getMapCaseInsensitive(raw.headers, filename);\n\n if (headerXml) {\n // Get header-specific relationships (e.g., word/_rels/header1.xml.rels)\n const headerRelsPath = `word/_rels/${filename}.rels`;\n const headerRelsXml = getMapCaseInsensitive(raw.allXml, headerRelsPath);\n const headerRels = headerRelsXml ? parseRelationships(headerRelsXml) : rels;\n\n const header = parseHeader(\n headerXml,\n 'default', // We'll update this based on sectPr references\n styles,\n theme,\n numbering,\n headerRels,\n media\n );\n headers.set(rId, header);\n }\n } else if (rel.type === RELATIONSHIP_TYPES.footer && rel.target) {\n // Use case-insensitive lookup since ZIP files may have inconsistent casing\n const filename = rel.target.split('/').pop() || rel.target;\n const footerXml = getMapCaseInsensitive(raw.footers, filename);\n\n if (footerXml) {\n // Get footer-specific relationships (e.g., word/_rels/footer1.xml.rels)\n const footerRelsPath = `word/_rels/${filename}.rels`;\n const footerRelsXml = getMapCaseInsensitive(raw.allXml, footerRelsPath);\n const footerRels = footerRelsXml ? parseRelationships(footerRelsXml) : rels;\n\n const footer = parseFooter(\n footerXml,\n 'default',\n styles,\n theme,\n numbering,\n footerRels,\n media\n );\n footers.set(rId, footer);\n }\n }\n }\n\n return { headers, footers };\n}\n\n/**\n * Parse footnotes and endnotes from raw content\n */\nfunction parseNotesContent(\n raw: RawDocxContent,\n styles: StyleMap | null,\n theme: Theme | null,\n numbering: NumberingMap | null,\n rels: RelationshipMap,\n media: Map<string, MediaFile>\n): { footnotes: Footnote[]; endnotes: Endnote[] } {\n const footnoteMap = parseFootnotes(raw.footnotesXml, styles, theme, numbering, rels, media);\n\n const endnoteMap = parseEndnotes(raw.endnotesXml, styles, theme, numbering, rels, media);\n\n return {\n footnotes: footnoteMap.getNormalFootnotes(),\n endnotes: endnoteMap.getNormalEndnotes(),\n };\n}\n\n/**\n * Extract fonts from document and load them\n */\nasync function loadDocumentFonts(\n theme: Theme | null,\n styleDefinitions: StyleDefinitions | undefined,\n documentBody: DocumentBody\n): Promise<void> {\n const docxFonts = new Set<string>();\n\n // Extract fonts from theme\n if (theme?.fontScheme) {\n const { majorFont, minorFont } = theme.fontScheme;\n if (majorFont?.latin) docxFonts.add(majorFont.latin);\n if (minorFont?.latin) docxFonts.add(minorFont.latin);\n }\n\n // Extract fonts from style defaults\n if (styleDefinitions?.docDefaults?.rPr?.fontFamily?.ascii) {\n docxFonts.add(styleDefinitions.docDefaults.rPr.fontFamily.ascii);\n }\n\n // Extract fonts from styles\n if (styleDefinitions?.styles) {\n for (const style of styleDefinitions.styles) {\n if (style.rPr?.fontFamily?.ascii) {\n docxFonts.add(style.rPr.fontFamily.ascii);\n }\n if (style.rPr?.fontFamily?.hAnsi) {\n docxFonts.add(style.rPr.fontFamily.hAnsi);\n }\n }\n }\n\n // Extract fonts from document content (inline run formatting)\n if (documentBody.content) {\n for (const block of documentBody.content) {\n if (block.type === 'paragraph') {\n for (const item of block.content) {\n if (item.type === 'run' && item.formatting?.fontFamily) {\n if (item.formatting.fontFamily.ascii) {\n docxFonts.add(item.formatting.fontFamily.ascii);\n }\n if (item.formatting.fontFamily.hAnsi) {\n docxFonts.add(item.formatting.fontFamily.hAnsi);\n }\n }\n }\n }\n }\n }\n\n // Load fonts with mapping (creates aliases so original names work in CSS)\n if (docxFonts.size > 0) {\n try {\n await loadFontsWithMapping(Array.from(docxFonts));\n } catch (error) {\n // Font loading is non-critical, continue without fonts\n console.warn('Failed to load some fonts:', error);\n }\n }\n}\n\n// ============================================================================\n// CONVENIENCE FUNCTIONS\n// ============================================================================\n\n/**\n * Quick parse - parse a DOCX without font loading\n * Useful for quick content extraction or when fonts aren't needed\n */\nexport async function quickParseDocx(buffer: ArrayBuffer): Promise<Document> {\n return parseDocx(buffer, {\n preloadFonts: false,\n parseHeadersFooters: false,\n parseNotes: false,\n detectVariables: true,\n });\n}\n\n/**\n * Full parse - parse everything including fonts\n */\nexport async function fullParseDocx(\n buffer: ArrayBuffer,\n onProgress?: ProgressCallback\n): Promise<Document> {\n return parseDocx(buffer, {\n onProgress,\n preloadFonts: true,\n parseHeadersFooters: true,\n parseNotes: true,\n detectVariables: true,\n });\n}\n\n/**\n * Get template variables from a DOCX without full parsing\n * Faster than full parse when you only need variables\n */\nexport async function getDocxVariables(buffer: ArrayBuffer): Promise<string[]> {\n const raw = await unzipDocx(buffer);\n\n if (!raw.documentXml) {\n return [];\n }\n\n // Quick parse just the document body\n const documentBody = parseDocumentBody(raw.documentXml);\n return extractAllTemplateVariables(documentBody.content);\n}\n\n/**\n * Get document summary without full parsing\n */\nexport async function getDocxSummary(buffer: ArrayBuffer): Promise<{\n hasDocument: boolean;\n hasStyles: boolean;\n hasTheme: boolean;\n hasNumbering: boolean;\n headerCount: number;\n footerCount: number;\n mediaCount: number;\n variableCount: number;\n}> {\n const raw = await unzipDocx(buffer);\n const variables = raw.documentXml\n ? extractAllTemplateVariables(parseDocumentBody(raw.documentXml).content)\n : [];\n\n return {\n hasDocument: raw.documentXml !== null,\n hasStyles: raw.stylesXml !== null,\n hasTheme: raw.themeXml !== null,\n hasNumbering: raw.numberingXml !== null,\n headerCount: raw.headers.size,\n footerCount: raw.footers.size,\n mediaCount: raw.media.size,\n variableCount: variables.length,\n };\n}\n","/**\n * DocumentAgent - High-level fluent API for programmatic document manipulation\n *\n * Provides a convenient interface for:\n * - Reading document content and metadata\n * - Editing text with formatting\n * - Inserting tables, images, and hyperlinks\n * - Managing template variables\n * - Exporting to DOCX buffer\n *\n * All operations are immutable - they return a new DocumentAgent instance\n * or don't modify the underlying document.\n */\n\nimport type {\n Document,\n DocumentBody,\n Paragraph,\n Table,\n Run,\n TextFormatting,\n ParagraphFormatting,\n Style,\n Hyperlink,\n} from '../types/document';\n\nimport type {\n Position,\n Range,\n AgentContext,\n StyleInfo,\n ParagraphOutline,\n SectionInfo,\n} from '../types/agentApi';\n\nimport { executeCommand, executeCommands } from './executor';\nimport type { AgentCommand } from '../types/agentApi';\nimport { repackDocx, createDocx } from '../docx/rezip';\nimport { attemptSelectiveSave, type SelectiveSaveOptions } from '../docx/selectiveSave';\nimport { detectVariables } from '../utils/variableDetector';\nimport { parseDocx } from '../docx/parser';\nimport type { DocxInput } from '../utils/docxInput';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\n/**\n * Options for inserting text\n */\nexport interface InsertTextOptions {\n /** Text formatting */\n formatting?: TextFormatting;\n}\n\n/**\n * Options for inserting table\n */\nexport interface InsertTableOptions {\n /** Table data (2D array of strings) */\n data?: string[][];\n /** Whether first row is a header */\n hasHeader?: boolean;\n}\n\n/**\n * Options for inserting image\n */\nexport interface InsertImageOptions {\n /** Image width in pixels */\n width?: number;\n /** Image height in pixels */\n height?: number;\n /** Alt text for accessibility */\n alt?: string;\n}\n\n/**\n * Options for inserting hyperlink\n */\nexport interface InsertHyperlinkOptions {\n /** Display text (overrides selected text) */\n displayText?: string;\n /** Tooltip on hover */\n tooltip?: string;\n}\n\n/**\n * Formatted text segment\n */\nexport interface FormattedTextSegment {\n /** Text content */\n text: string;\n /** Applied formatting */\n formatting?: TextFormatting;\n /** Is part of a hyperlink */\n isHyperlink?: boolean;\n /** Hyperlink URL if applicable */\n hyperlinkUrl?: string;\n}\n\n// ============================================================================\n// DOCUMENT AGENT CLASS\n// ============================================================================\n\n/**\n * DocumentAgent provides a fluent API for document manipulation\n *\n * @example\n * ```ts\n * const agent = new DocumentAgent(buffer);\n *\n * // Read operations\n * const text = agent.getText();\n * const wordCount = agent.getWordCount();\n * const variables = agent.getVariables();\n *\n * // Write operations (returns new agent)\n * const newAgent = agent\n * .insertText({ paragraphIndex: 0, offset: 0 }, 'Hello ', { formatting: { bold: true } })\n * .applyStyle({ paragraphIndex: 0, offset: 0 }, { paragraphIndex: 0, offset: 5 }, 'Heading1');\n *\n * // Export\n * const newBuffer = await newAgent.toBuffer();\n * ```\n */\nexport class DocumentAgent {\n private _document: Document;\n private _pendingVariables: Record<string, string>;\n\n /**\n * Create a new DocumentAgent\n *\n * @param source - Document object or ArrayBuffer to parse\n */\n constructor(source: Document | ArrayBuffer) {\n if (source instanceof ArrayBuffer || ArrayBuffer.isView(source)) {\n // Will be loaded asynchronously - store buffer for now\n this._document = {\n package: {\n document: { content: [] },\n },\n originalBuffer: source instanceof ArrayBuffer ? source : (source.buffer as ArrayBuffer),\n };\n } else {\n this._document = source;\n }\n this._pendingVariables = {};\n }\n\n /**\n * Create a DocumentAgent from a DOCX buffer (async)\n *\n * @param buffer - DOCX file as ArrayBuffer, Uint8Array, Blob, or File\n * @returns Promise resolving to DocumentAgent\n */\n static async fromBuffer(buffer: DocxInput): Promise<DocumentAgent> {\n const document = await parseDocx(buffer);\n return new DocumentAgent(document);\n }\n\n /**\n * Create a DocumentAgent from a Document object\n *\n * @param document - Parsed Document\n * @returns DocumentAgent\n */\n static fromDocument(document: Document): DocumentAgent {\n return new DocumentAgent(document);\n }\n\n // ==========================================================================\n // READING METHODS\n // ==========================================================================\n\n /**\n * Get the underlying document\n */\n getDocument(): Document {\n return this._document;\n }\n\n /**\n * Get plain text content of the document\n *\n * @returns All document text concatenated\n */\n getText(): string {\n const body = this._document.package.document;\n return this._getBodyText(body);\n }\n\n /**\n * Get formatted text segments\n *\n * @returns Array of text segments with formatting info\n */\n getFormattedText(): FormattedTextSegment[] {\n const segments: FormattedTextSegment[] = [];\n const body = this._document.package.document;\n\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n this._extractParagraphSegments(block, segments);\n }\n }\n\n return segments;\n }\n\n /**\n * Get detected template variables\n *\n * @returns Array of variable names (without braces)\n */\n getVariables(): string[] {\n return detectVariables(this._document);\n }\n\n /**\n * Get available styles from the document\n *\n * @returns Array of style info\n */\n getStyles(): StyleInfo[] {\n const styleDefinitions = this._document.package.styles;\n if (!styleDefinitions?.styles) {\n return [];\n }\n\n const styleInfos: StyleInfo[] = [];\n\n for (const [styleId, style] of Object.entries(styleDefinitions.styles)) {\n if (typeof style === 'object' && style !== null) {\n const styleObj = style as Style;\n styleInfos.push({\n id: styleId,\n name: styleObj.name || styleId,\n type: styleObj.type === 'numbering' ? 'paragraph' : styleObj.type || 'paragraph',\n builtIn: styleObj.default, // Use default property as proxy for built-in\n });\n }\n }\n\n return styleInfos;\n }\n\n /**\n * Get approximate page count\n *\n * Note: This is an estimate based on content length.\n * Actual page count requires full layout computation.\n *\n * @returns Estimated page count\n */\n getPageCount(): number {\n // Estimate: ~500 words per page\n const wordCount = this.getWordCount();\n return Math.max(1, Math.ceil(wordCount / 500));\n }\n\n /**\n * Get word count\n *\n * @returns Number of words in the document\n */\n getWordCount(): number {\n const text = this.getText();\n // Split by whitespace and filter empty strings\n const words = text.split(/\\s+/).filter((w) => w.length > 0);\n return words.length;\n }\n\n /**\n * Get character count\n *\n * @param includeSpaces - Whether to include whitespace\n * @returns Number of characters\n */\n getCharacterCount(includeSpaces = true): number {\n const text = this.getText();\n if (includeSpaces) {\n return text.length;\n }\n return text.replace(/\\s/g, '').length;\n }\n\n /**\n * Get paragraph count\n *\n * @returns Number of paragraphs\n */\n getParagraphCount(): number {\n return this._document.package.document.content.filter((block) => block.type === 'paragraph')\n .length;\n }\n\n /**\n * Get table count\n *\n * @returns Number of tables\n */\n getTableCount(): number {\n return this._document.package.document.content.filter((block) => block.type === 'table').length;\n }\n\n /**\n * Get document context for AI agents\n *\n * @param outlineMaxChars - Max characters per paragraph in outline\n * @returns Agent context\n */\n getAgentContext(outlineMaxChars = 100): AgentContext {\n const body = this._document.package.document;\n const paragraphs = body.content.filter((b): b is Paragraph => b.type === 'paragraph');\n\n const outline: ParagraphOutline[] = paragraphs.map((para, index) => {\n const text = this._getParagraphText(para);\n const styleId = para.formatting?.styleId;\n\n return {\n index,\n preview: text.slice(0, outlineMaxChars),\n style: styleId,\n isHeading: styleId?.toLowerCase().includes('heading') || false,\n headingLevel: this._parseHeadingLevel(styleId),\n isListItem: !!para.listRendering,\n isEmpty: text.trim().length === 0,\n };\n });\n\n const sections: SectionInfo[] = (body.sections || []).map((section, index) => ({\n index,\n paragraphCount: section.content?.length || 0,\n pageSize:\n section.properties?.pageWidth && section.properties?.pageHeight\n ? {\n width: section.properties.pageWidth,\n height: section.properties.pageHeight,\n }\n : undefined,\n isLandscape: section.properties?.orientation === 'landscape',\n hasHeader: !!section.properties?.headerReferences?.length,\n hasFooter: !!section.properties?.footerReferences?.length,\n }));\n\n return {\n paragraphCount: paragraphs.length,\n wordCount: this.getWordCount(),\n characterCount: this.getCharacterCount(),\n variables: this.getVariables(),\n variableCount: this.getVariables().length,\n availableStyles: this.getStyles(),\n outline,\n sections,\n hasTables: this.getTableCount() > 0,\n hasImages: this._hasImages(),\n hasHyperlinks: this._hasHyperlinks(),\n };\n }\n\n // ==========================================================================\n // WRITING METHODS\n // ==========================================================================\n\n /**\n * Insert text at a position\n *\n * @param position - Where to insert\n * @param text - Text to insert\n * @param options - Insert options\n * @returns New DocumentAgent with text inserted\n */\n insertText(position: Position, text: string, options: InsertTextOptions = {}): DocumentAgent {\n const command: AgentCommand = {\n type: 'insertText',\n position,\n text,\n formatting: options.formatting,\n };\n return this._executeCommand(command);\n }\n\n /**\n * Replace text in a range\n *\n * @param range - Range to replace\n * @param text - Replacement text\n * @param options - Replace options\n * @returns New DocumentAgent with text replaced\n */\n replaceRange(range: Range, text: string, options: InsertTextOptions = {}): DocumentAgent {\n const command: AgentCommand = {\n type: 'replaceText',\n range,\n text,\n formatting: options.formatting,\n };\n return this._executeCommand(command);\n }\n\n /**\n * Delete text in a range\n *\n * @param range - Range to delete\n * @returns New DocumentAgent with text deleted\n */\n deleteRange(range: Range): DocumentAgent {\n const command: AgentCommand = {\n type: 'deleteText',\n range,\n };\n return this._executeCommand(command);\n }\n\n /**\n * Apply text formatting to a range\n *\n * @param range - Range to format\n * @param formatting - Formatting to apply\n * @returns New DocumentAgent with formatting applied\n */\n applyFormatting(range: Range, formatting: Partial<TextFormatting>): DocumentAgent {\n const command: AgentCommand = {\n type: 'formatText',\n range,\n formatting,\n };\n return this._executeCommand(command);\n }\n\n /**\n * Apply a named style to a paragraph\n *\n * @param paragraphIndex - Index of the paragraph\n * @param styleId - Style ID to apply\n * @returns New DocumentAgent with style applied\n */\n applyStyle(paragraphIndex: number, styleId: string): DocumentAgent {\n const command: AgentCommand = {\n type: 'applyStyle',\n paragraphIndex,\n styleId,\n };\n return this._executeCommand(command);\n }\n\n /**\n * Apply paragraph formatting\n *\n * @param paragraphIndex - Index of the paragraph\n * @param formatting - Formatting to apply\n * @returns New DocumentAgent with formatting applied\n */\n applyParagraphFormatting(\n paragraphIndex: number,\n formatting: Partial<ParagraphFormatting>\n ): DocumentAgent {\n const command: AgentCommand = {\n type: 'formatParagraph',\n paragraphIndex,\n formatting,\n };\n return this._executeCommand(command);\n }\n\n // ==========================================================================\n // COMPLEX OPERATIONS\n // ==========================================================================\n\n /**\n * Insert a table at a position\n *\n * @param position - Where to insert the table\n * @param rows - Number of rows\n * @param cols - Number of columns\n * @param options - Table options\n * @returns New DocumentAgent with table inserted\n */\n insertTable(\n position: Position,\n rows: number,\n cols: number,\n options: InsertTableOptions = {}\n ): DocumentAgent {\n const command: AgentCommand = {\n type: 'insertTable',\n position,\n rows,\n columns: cols,\n data: options.data,\n hasHeader: options.hasHeader,\n };\n return this._executeCommand(command);\n }\n\n /**\n * Insert an image at a position\n *\n * @param position - Where to insert the image\n * @param src - Image source (base64 data URL or URL)\n * @param options - Image options\n * @returns New DocumentAgent with image inserted\n */\n insertImage(position: Position, src: string, options: InsertImageOptions = {}): DocumentAgent {\n const command: AgentCommand = {\n type: 'insertImage',\n position,\n src,\n width: options.width,\n height: options.height,\n alt: options.alt,\n };\n return this._executeCommand(command);\n }\n\n /**\n * Insert a hyperlink\n *\n * @param range - Range to make into a hyperlink\n * @param url - URL of the hyperlink\n * @param options - Hyperlink options\n * @returns New DocumentAgent with hyperlink inserted\n */\n insertHyperlink(range: Range, url: string, options: InsertHyperlinkOptions = {}): DocumentAgent {\n const command: AgentCommand = {\n type: 'insertHyperlink',\n range,\n url,\n displayText: options.displayText,\n tooltip: options.tooltip,\n };\n return this._executeCommand(command);\n }\n\n /**\n * Remove a hyperlink but keep the text\n *\n * @param range - Range containing the hyperlink\n * @returns New DocumentAgent with hyperlink removed\n */\n removeHyperlink(range: Range): DocumentAgent {\n const command: AgentCommand = {\n type: 'removeHyperlink',\n range,\n };\n return this._executeCommand(command);\n }\n\n /**\n * Insert a paragraph break\n *\n * @param position - Where to break the paragraph\n * @returns New DocumentAgent with paragraph broken\n */\n insertParagraphBreak(position: Position): DocumentAgent {\n const command: AgentCommand = {\n type: 'insertParagraphBreak',\n position,\n };\n return this._executeCommand(command);\n }\n\n /**\n * Merge consecutive paragraphs\n *\n * @param startParagraphIndex - First paragraph index\n * @param count - Number of paragraphs to merge with the first\n * @returns New DocumentAgent with paragraphs merged\n */\n mergeParagraphs(startParagraphIndex: number, count: number): DocumentAgent {\n const command: AgentCommand = {\n type: 'mergeParagraphs',\n paragraphIndex: startParagraphIndex,\n count,\n };\n return this._executeCommand(command);\n }\n\n // ==========================================================================\n // TEMPLATE VARIABLE METHODS\n // ==========================================================================\n\n /**\n * Set a template variable value\n *\n * Note: Variables are not applied until `applyVariables()` is called\n *\n * @param name - Variable name (without braces)\n * @param value - Variable value\n * @returns This DocumentAgent (for chaining)\n */\n setVariable(name: string, value: string): DocumentAgent {\n this._pendingVariables[name] = value;\n return this;\n }\n\n /**\n * Set multiple template variables\n *\n * @param variables - Map of variable names to values\n * @returns This DocumentAgent (for chaining)\n */\n setVariables(variables: Record<string, string>): DocumentAgent {\n for (const [name, value] of Object.entries(variables)) {\n this._pendingVariables[name] = value;\n }\n return this;\n }\n\n /**\n * Get pending variable values\n *\n * @returns Map of pending variable values\n */\n getPendingVariables(): Record<string, string> {\n return { ...this._pendingVariables };\n }\n\n /**\n * Clear pending variables\n *\n * @returns This DocumentAgent (for chaining)\n */\n clearPendingVariables(): DocumentAgent {\n this._pendingVariables = {};\n return this;\n }\n\n /**\n * Apply all pending template variables\n *\n * Uses docxtemplater to substitute variables while preserving formatting.\n *\n * @param variables - Optional additional variables (merged with pending)\n * @returns New DocumentAgent with variables applied\n */\n async applyVariables(variables?: Record<string, string>): Promise<DocumentAgent> {\n const allVariables = { ...this._pendingVariables, ...variables };\n\n if (Object.keys(allVariables).length === 0) {\n // No variables to apply\n return this;\n }\n\n // Get the original buffer\n const buffer = this._document.originalBuffer;\n if (!buffer) {\n throw new Error('Cannot apply variables: no original buffer for processing');\n }\n\n // Process template using docxtemplater (dynamic import to keep it off critical path)\n const { processTemplate } = await import('../utils/processTemplate');\n const processedBuffer = processTemplate(buffer, allVariables);\n\n // Parse the processed document\n const processedDoc = await parseDocx(processedBuffer);\n\n // Create new agent with processed document\n const newAgent = new DocumentAgent(processedDoc);\n newAgent._pendingVariables = {};\n\n return newAgent;\n }\n\n // ==========================================================================\n // EXPORT METHODS\n // ==========================================================================\n\n /**\n * Export document to DOCX ArrayBuffer\n *\n * @returns Promise resolving to DOCX file as ArrayBuffer\n */\n async toBuffer(options?: { selective?: SelectiveSaveOptions }): Promise<ArrayBuffer> {\n if (this._document.originalBuffer) {\n // Try selective save if options provided\n if (options?.selective) {\n const result = await attemptSelectiveSave(\n this._document,\n this._document.originalBuffer,\n options.selective\n );\n if (result) {\n // Update originalBuffer so subsequent saves patch against the latest state\n this._document.originalBuffer = result;\n return result;\n }\n }\n // Fall back to full repack\n const repacked = await repackDocx(this._document);\n this._document.originalBuffer = repacked;\n return repacked;\n }\n return createDocx(this._document);\n }\n\n /**\n * Export document to Blob\n *\n * @param mimeType - MIME type for the blob\n * @returns Promise resolving to DOCX file as Blob\n */\n async toBlob(\n mimeType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'\n ): Promise<Blob> {\n const buffer = await this.toBuffer();\n return new Blob([buffer], { type: mimeType });\n }\n\n /**\n * Execute multiple commands in sequence\n *\n * @param commands - Commands to execute\n * @returns New DocumentAgent with all commands applied\n */\n executeCommands(commands: AgentCommand[]): DocumentAgent {\n return new DocumentAgent(executeCommands(this._document, commands));\n }\n\n // ==========================================================================\n // PRIVATE HELPERS\n // ==========================================================================\n\n /**\n * Execute a single command and return new agent\n */\n private _executeCommand(command: AgentCommand): DocumentAgent {\n const newAgent = new DocumentAgent(executeCommand(this._document, command));\n newAgent._pendingVariables = { ...this._pendingVariables };\n return newAgent;\n }\n\n /**\n * Get plain text from document body\n */\n private _getBodyText(body: DocumentBody): string {\n const texts: string[] = [];\n\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n texts.push(this._getParagraphText(block));\n } else if (block.type === 'table') {\n texts.push(this._getTableText(block));\n }\n }\n\n return texts.join('\\n');\n }\n\n /**\n * Get plain text from a paragraph\n */\n private _getParagraphText(paragraph: Paragraph): string {\n const texts: string[] = [];\n\n for (const item of paragraph.content) {\n if (item.type === 'run') {\n texts.push(this._getRunText(item));\n } else if (item.type === 'hyperlink') {\n texts.push(this._getHyperlinkText(item));\n }\n }\n\n return texts.join('');\n }\n\n /**\n * Get plain text from a run\n */\n private _getRunText(run: Run): string {\n return run.content\n .filter((c) => c.type === 'text')\n .map((c) => (c as { type: 'text'; text: string }).text)\n .join('');\n }\n\n /**\n * Get plain text from a hyperlink\n */\n private _getHyperlinkText(hyperlink: Hyperlink): string {\n const texts: string[] = [];\n for (const child of hyperlink.children) {\n if (child.type === 'run') {\n texts.push(this._getRunText(child));\n }\n }\n return texts.join('');\n }\n\n /**\n * Get plain text from a table\n */\n private _getTableText(table: Table): string {\n const texts: string[] = [];\n\n for (const row of table.rows) {\n for (const cell of row.cells) {\n for (const block of cell.content) {\n if (block.type === 'paragraph') {\n texts.push(this._getParagraphText(block));\n }\n }\n }\n }\n\n return texts.join('\\t');\n }\n\n /**\n * Extract formatted text segments from a paragraph\n */\n private _extractParagraphSegments(paragraph: Paragraph, segments: FormattedTextSegment[]): void {\n for (const item of paragraph.content) {\n if (item.type === 'run') {\n const text = this._getRunText(item);\n if (text) {\n segments.push({\n text,\n formatting: item.formatting,\n });\n }\n } else if (item.type === 'hyperlink') {\n const url = item.href || '';\n for (const child of item.children) {\n if (child.type === 'run') {\n const text = this._getRunText(child);\n if (text) {\n segments.push({\n text,\n formatting: child.formatting,\n isHyperlink: true,\n hyperlinkUrl: url,\n });\n }\n }\n }\n }\n }\n }\n\n /**\n * Parse heading level from style ID\n */\n private _parseHeadingLevel(styleId?: string): number | undefined {\n if (!styleId) return undefined;\n const match = styleId.match(/heading\\s*(\\d)/i);\n if (match) {\n return parseInt(match[1], 10);\n }\n return undefined;\n }\n\n /**\n * Check if document has images\n */\n private _hasImages(): boolean {\n const body = this._document.package.document;\n\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n for (const item of block.content) {\n if (item.type === 'run') {\n for (const content of item.content) {\n if (content.type === 'drawing') {\n return true;\n }\n }\n }\n }\n }\n }\n\n return false;\n }\n\n /**\n * Check if document has hyperlinks\n */\n private _hasHyperlinks(): boolean {\n const body = this._document.package.document;\n\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n for (const item of block.content) {\n if (item.type === 'hyperlink') {\n return true;\n }\n }\n }\n }\n\n return false;\n }\n}\n\n// ============================================================================\n// CONVENIENCE FUNCTIONS\n// ============================================================================\n\n/**\n * Create a DocumentAgent from a DOCX buffer\n *\n * @param buffer - DOCX file as ArrayBuffer\n * @returns Promise resolving to DocumentAgent\n */\nexport async function createAgent(buffer: ArrayBuffer): Promise<DocumentAgent> {\n return DocumentAgent.fromBuffer(buffer);\n}\n\n/**\n * Create a DocumentAgent from a parsed Document\n *\n * @param document - Parsed Document\n * @returns DocumentAgent\n */\nexport function createAgentFromDocument(document: Document): DocumentAgent {\n return DocumentAgent.fromDocument(document);\n}\n\n// ============================================================================\n// EXPORTS\n// ============================================================================\n\nexport default DocumentAgent;\n","/**\n * Agent Context Builder\n *\n * Generates context objects for AI/LLM consumption from DOCX documents.\n * The context provides a structured summary of the document that can be\n * used by AI agents to understand the document structure and content.\n *\n * All outputs are JSON serializable for easy transmission to AI backends.\n */\n\nimport type {\n Document,\n DocumentBody,\n Paragraph,\n Table,\n Run,\n Hyperlink,\n Style,\n} from '../types/document';\n\nimport type {\n AgentContext,\n StyleInfo,\n ParagraphOutline,\n SectionInfo,\n SelectionContext,\n ParagraphContext,\n SuggestedAction,\n Range,\n} from '../types/agentApi';\n\nimport { detectVariables } from '../utils/variableDetector';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\n/**\n * Options for building agent context\n */\nexport interface AgentContextOptions {\n /** Maximum characters per paragraph in outline (default: 100) */\n outlineMaxChars?: number;\n /** Maximum paragraphs to include in outline (default: 50) */\n maxOutlineParagraphs?: number;\n /** Include table content in context (default: false) */\n includeTableContent?: boolean;\n /** Include detailed formatting info (default: false) */\n includeFormatting?: boolean;\n}\n\n/**\n * Options for building selection context\n */\nexport interface SelectionContextOptions {\n /** Characters of context before/after selection (default: 200) */\n contextChars?: number;\n /** Include suggested actions (default: true) */\n includeSuggestions?: boolean;\n}\n\n// ============================================================================\n// MAIN FUNCTIONS\n// ============================================================================\n\n/**\n * Build agent context from a document\n *\n * @param doc - The parsed document\n * @param options - Context building options\n * @returns AgentContext object (JSON serializable)\n */\nexport function getAgentContext(doc: Document, options: AgentContextOptions = {}): AgentContext {\n const { outlineMaxChars = 100, maxOutlineParagraphs = 50 } = options;\n\n const body = doc.package.document;\n\n // Get paragraphs\n const paragraphs = body.content.filter((block): block is Paragraph => block.type === 'paragraph');\n\n // Build outline\n const outline = buildOutline(paragraphs, outlineMaxChars, maxOutlineParagraphs);\n\n // Get variables\n const variables = detectVariables(doc);\n\n // Get styles\n const availableStyles = getStylesFromDoc(doc);\n\n // Get sections\n const sections = getSectionsInfo(body);\n\n // Calculate counts\n const wordCount = calculateWordCount(body);\n const characterCount = calculateCharacterCount(body);\n\n // Check for features\n const hasTables = body.content.some((b) => b.type === 'table');\n const hasImages = hasDocImages(body);\n const hasHyperlinks = hasDocHyperlinks(body);\n\n return {\n paragraphCount: paragraphs.length,\n wordCount,\n characterCount,\n variables,\n variableCount: variables.length,\n availableStyles,\n outline,\n sections,\n hasTables,\n hasImages,\n hasHyperlinks,\n };\n}\n\n/**\n * Build selection context for AI operations\n *\n * @param doc - The parsed document\n * @param range - The selected range\n * @param options - Selection context options\n * @returns SelectionContext object (JSON serializable)\n */\nexport function buildSelectionContext(\n doc: Document,\n range: Range,\n options: SelectionContextOptions = {}\n): SelectionContext {\n const { contextChars = 200, includeSuggestions = true } = options;\n\n const body = doc.package.document;\n const paragraphs = body.content.filter((block): block is Paragraph => block.type === 'paragraph');\n\n // Get the paragraph at the start of the selection\n const paragraph = paragraphs[range.start.paragraphIndex];\n if (!paragraph) {\n throw new Error(`Paragraph not found at index ${range.start.paragraphIndex}`);\n }\n\n // Get paragraph text\n const paragraphText = getParagraphText(paragraph);\n\n // Extract selected text\n let selectedText = '';\n if (range.start.paragraphIndex === range.end.paragraphIndex) {\n selectedText = paragraphText.slice(range.start.offset, range.end.offset);\n } else {\n // Multi-paragraph selection\n const texts: string[] = [];\n for (let i = range.start.paragraphIndex; i <= range.end.paragraphIndex; i++) {\n const para = paragraphs[i];\n if (!para) continue;\n const text = getParagraphText(para);\n if (i === range.start.paragraphIndex) {\n texts.push(text.slice(range.start.offset));\n } else if (i === range.end.paragraphIndex) {\n texts.push(text.slice(0, range.end.offset));\n } else {\n texts.push(text);\n }\n }\n selectedText = texts.join('\\n');\n }\n\n // Get context before and after selection\n const textBefore = getTextBefore(\n paragraphs,\n range.start.paragraphIndex,\n range.start.offset,\n contextChars\n );\n const textAfter = getTextAfter(\n paragraphs,\n range.end.paragraphIndex,\n range.end.offset,\n contextChars\n );\n\n // Get formatting from first run in selection\n const formatting = getFormattingAtPosition(paragraph, range.start.offset);\n const paragraphFormatting = paragraph.formatting || {};\n\n // Build paragraph context\n const paragraphContext: ParagraphContext = {\n index: range.start.paragraphIndex,\n fullText: paragraphText,\n style: paragraph.formatting?.styleId,\n wordCount: countWords(paragraphText),\n };\n\n // Check if in table or hyperlink\n const inTable = false; // TODO: detect if selection is in a table\n const inHyperlink = isInHyperlink(paragraph, range.start.offset);\n\n // Build suggested actions\n const suggestedActions = includeSuggestions\n ? getSuggestedActions(selectedText, formatting, paragraphContext)\n : [];\n\n return {\n selectedText,\n range,\n formatting,\n paragraphFormatting,\n textBefore,\n textAfter,\n paragraph: paragraphContext,\n inTable,\n inHyperlink,\n suggestedActions,\n };\n}\n\n/**\n * Get a simple document summary for quick context\n *\n * @param doc - The parsed document\n * @returns Summary string\n */\nexport function getDocumentSummary(doc: Document): string {\n const context = getAgentContext(doc, {\n outlineMaxChars: 50,\n maxOutlineParagraphs: 10,\n });\n\n const parts: string[] = [\n `Document with ${context.paragraphCount} paragraphs, ${context.wordCount} words.`,\n ];\n\n if (context.hasTables) {\n parts.push('Contains tables.');\n }\n if (context.hasImages) {\n parts.push('Contains images.');\n }\n if (context.hasHyperlinks) {\n parts.push('Contains hyperlinks.');\n }\n if (context.variableCount > 0) {\n parts.push(`Has ${context.variableCount} template variables: ${context.variables.join(', ')}`);\n }\n\n // Add headings outline\n const headings = context.outline.filter((p) => p.isHeading);\n if (headings.length > 0) {\n parts.push('\\nHeadings:');\n for (const heading of headings.slice(0, 5)) {\n const level = heading.headingLevel || 1;\n parts.push(`${' '.repeat(level - 1)}- ${heading.preview}`);\n }\n if (headings.length > 5) {\n parts.push(` ... and ${headings.length - 5} more headings`);\n }\n }\n\n return parts.join(' ');\n}\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Build document outline\n */\nfunction buildOutline(\n paragraphs: Paragraph[],\n maxChars: number,\n maxParagraphs: number\n): ParagraphOutline[] {\n const outline: ParagraphOutline[] = [];\n\n for (let i = 0; i < Math.min(paragraphs.length, maxParagraphs); i++) {\n const para = paragraphs[i];\n const text = getParagraphText(para);\n const styleId = para.formatting?.styleId;\n\n outline.push({\n index: i,\n preview: text.slice(0, maxChars),\n style: styleId,\n isHeading: isHeadingStyle(styleId),\n headingLevel: parseHeadingLevel(styleId),\n isListItem: !!para.listRendering,\n isEmpty: text.trim().length === 0,\n });\n }\n\n return outline;\n}\n\n/**\n * Get styles from document\n */\nfunction getStylesFromDoc(doc: Document): StyleInfo[] {\n const styleDefinitions = doc.package.styles;\n if (!styleDefinitions?.styles) {\n return [];\n }\n\n const styleInfos: StyleInfo[] = [];\n\n for (const [styleId, style] of Object.entries(styleDefinitions.styles)) {\n if (typeof style === 'object' && style !== null) {\n const styleObj = style as Style;\n styleInfos.push({\n id: styleId,\n name: styleObj.name || styleId,\n type: styleObj.type === 'numbering' ? 'paragraph' : styleObj.type || 'paragraph',\n builtIn: styleObj.default, // Use default property as proxy for built-in\n });\n }\n }\n\n return styleInfos;\n}\n\n/**\n * Get sections info\n */\nfunction getSectionsInfo(body: DocumentBody): SectionInfo[] {\n if (!body.sections) {\n return [];\n }\n\n return body.sections.map((section, index) => ({\n index,\n paragraphCount: section.content?.length || 0,\n pageSize:\n section.properties?.pageWidth && section.properties?.pageHeight\n ? {\n width: section.properties.pageWidth,\n height: section.properties.pageHeight,\n }\n : undefined,\n isLandscape: section.properties?.orientation === 'landscape',\n hasHeader: !!section.properties?.headerReferences?.length,\n hasFooter: !!section.properties?.footerReferences?.length,\n }));\n}\n\n/**\n * Calculate word count for document body\n */\nfunction calculateWordCount(body: DocumentBody): number {\n let count = 0;\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n const text = getParagraphText(block);\n count += countWords(text);\n } else if (block.type === 'table') {\n count += getTableWordCount(block);\n }\n }\n return count;\n}\n\n/**\n * Count words in text\n */\nfunction countWords(text: string): number {\n const words = text.split(/\\s+/).filter((w) => w.length > 0);\n return words.length;\n}\n\n/**\n * Calculate character count for document body\n */\nfunction calculateCharacterCount(body: DocumentBody): number {\n let count = 0;\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n const text = getParagraphText(block);\n count += text.length;\n } else if (block.type === 'table') {\n count += getTableCharacterCount(block);\n }\n }\n return count;\n}\n\n/**\n * Get word count from table\n */\nfunction getTableWordCount(table: Table): number {\n let count = 0;\n for (const row of table.rows) {\n for (const cell of row.cells) {\n for (const block of cell.content) {\n if (block.type === 'paragraph') {\n const text = getParagraphText(block);\n count += countWords(text);\n }\n }\n }\n }\n return count;\n}\n\n/**\n * Get character count from table\n */\nfunction getTableCharacterCount(table: Table): number {\n let count = 0;\n for (const row of table.rows) {\n for (const cell of row.cells) {\n for (const block of cell.content) {\n if (block.type === 'paragraph') {\n const text = getParagraphText(block);\n count += text.length;\n }\n }\n }\n }\n return count;\n}\n\n/**\n * Get plain text from paragraph\n */\nfunction getParagraphText(paragraph: Paragraph): string {\n const texts: string[] = [];\n\n for (const item of paragraph.content) {\n if (item.type === 'run') {\n texts.push(getRunText(item));\n } else if (item.type === 'hyperlink') {\n texts.push(getHyperlinkText(item));\n }\n }\n\n return texts.join('');\n}\n\n/**\n * Get plain text from run\n */\nfunction getRunText(run: Run): string {\n return run.content\n .filter((c) => c.type === 'text')\n .map((c) => (c as { type: 'text'; text: string }).text)\n .join('');\n}\n\n/**\n * Get plain text from hyperlink\n */\nfunction getHyperlinkText(hyperlink: Hyperlink): string {\n const texts: string[] = [];\n for (const child of hyperlink.children) {\n if (child.type === 'run') {\n texts.push(getRunText(child));\n }\n }\n return texts.join('');\n}\n\n/**\n * Check if document has images\n */\nfunction hasDocImages(body: DocumentBody): boolean {\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n for (const item of block.content) {\n if (item.type === 'run') {\n for (const content of item.content) {\n if (content.type === 'drawing') {\n return true;\n }\n }\n }\n }\n }\n }\n return false;\n}\n\n/**\n * Check if document has hyperlinks\n */\nfunction hasDocHyperlinks(body: DocumentBody): boolean {\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n for (const item of block.content) {\n if (item.type === 'hyperlink') {\n return true;\n }\n }\n }\n }\n return false;\n}\n\n/**\n * Check if style is a heading\n */\nfunction isHeadingStyle(styleId?: string): boolean {\n if (!styleId) return false;\n return styleId.toLowerCase().includes('heading');\n}\n\n/**\n * Parse heading level from style ID\n */\nfunction parseHeadingLevel(styleId?: string): number | undefined {\n if (!styleId) return undefined;\n const match = styleId.match(/heading\\s*(\\d)/i);\n if (match) {\n return parseInt(match[1], 10);\n }\n return undefined;\n}\n\n/**\n * Get text before a position\n */\nfunction getTextBefore(\n paragraphs: Paragraph[],\n paragraphIndex: number,\n offset: number,\n maxChars: number\n): string {\n const texts: string[] = [];\n let totalChars = 0;\n\n // Get text before offset in current paragraph\n const currentPara = paragraphs[paragraphIndex];\n if (currentPara) {\n const text = getParagraphText(currentPara);\n const beforeText = text.slice(0, offset);\n texts.unshift(beforeText);\n totalChars += beforeText.length;\n }\n\n // Get text from previous paragraphs if needed\n for (let i = paragraphIndex - 1; i >= 0 && totalChars < maxChars; i--) {\n const para = paragraphs[i];\n if (!para) continue;\n const text = getParagraphText(para);\n texts.unshift(text);\n totalChars += text.length;\n }\n\n const combined = texts.join('\\n');\n if (combined.length > maxChars) {\n return '...' + combined.slice(-maxChars);\n }\n return combined;\n}\n\n/**\n * Get text after a position\n */\nfunction getTextAfter(\n paragraphs: Paragraph[],\n paragraphIndex: number,\n offset: number,\n maxChars: number\n): string {\n const texts: string[] = [];\n let totalChars = 0;\n\n // Get text after offset in current paragraph\n const currentPara = paragraphs[paragraphIndex];\n if (currentPara) {\n const text = getParagraphText(currentPara);\n const afterText = text.slice(offset);\n texts.push(afterText);\n totalChars += afterText.length;\n }\n\n // Get text from following paragraphs if needed\n for (let i = paragraphIndex + 1; i < paragraphs.length && totalChars < maxChars; i++) {\n const para = paragraphs[i];\n if (!para) continue;\n const text = getParagraphText(para);\n texts.push(text);\n totalChars += text.length;\n }\n\n const combined = texts.join('\\n');\n if (combined.length > maxChars) {\n return combined.slice(0, maxChars) + '...';\n }\n return combined;\n}\n\n/**\n * Get formatting at a specific position in a paragraph\n */\nfunction getFormattingAtPosition(\n paragraph: Paragraph,\n offset: number\n): Partial<import('../types/document').TextFormatting> {\n let currentOffset = 0;\n\n for (const item of paragraph.content) {\n if (item.type === 'run') {\n const text = getRunText(item);\n const runStart = currentOffset;\n const runEnd = currentOffset + text.length;\n\n if (offset >= runStart && offset < runEnd) {\n return item.formatting || {};\n }\n\n currentOffset = runEnd;\n } else if (item.type === 'hyperlink') {\n const text = getHyperlinkText(item);\n const linkStart = currentOffset;\n const linkEnd = currentOffset + text.length;\n\n if (offset >= linkStart && offset < linkEnd) {\n // Return formatting from first child run\n for (const child of item.children) {\n if (child.type === 'run') {\n return child.formatting || {};\n }\n }\n }\n\n currentOffset = linkEnd;\n }\n }\n\n return {};\n}\n\n/**\n * Check if position is within a hyperlink\n */\nfunction isInHyperlink(paragraph: Paragraph, offset: number): boolean {\n let currentOffset = 0;\n\n for (const item of paragraph.content) {\n if (item.type === 'run') {\n const text = getRunText(item);\n currentOffset += text.length;\n } else if (item.type === 'hyperlink') {\n const text = getHyperlinkText(item);\n const linkStart = currentOffset;\n const linkEnd = currentOffset + text.length;\n\n if (offset >= linkStart && offset < linkEnd) {\n return true;\n }\n\n currentOffset = linkEnd;\n }\n }\n\n return false;\n}\n\n/**\n * Get suggested actions for selection\n */\nfunction getSuggestedActions(\n selectedText: string,\n _formatting: Partial<import('../types/document').TextFormatting>,\n _paragraphContext: ParagraphContext\n): SuggestedAction[] {\n const actions: SuggestedAction[] = [];\n\n // Basic actions for any text\n if (selectedText.length > 0) {\n actions.push(\n { id: 'rewrite', label: 'Rewrite', description: 'Rewrite this text', priority: 10 },\n { id: 'summarize', label: 'Summarize', description: 'Summarize this text', priority: 9 }\n );\n\n // Long text suggestions\n if (selectedText.length > 200) {\n actions.push({\n id: 'summarize',\n label: 'Summarize',\n description: 'Create a shorter version',\n priority: 8,\n });\n }\n\n // Short text suggestions\n if (selectedText.length < 50 && selectedText.split(/\\s+/).length < 10) {\n actions.push({\n id: 'expand',\n label: 'Expand',\n description: 'Add more details',\n priority: 8,\n });\n }\n\n // Grammar fix is always useful\n actions.push({\n id: 'fixGrammar',\n label: 'Fix Grammar',\n description: 'Fix grammar and spelling',\n priority: 7,\n });\n\n // Translate\n actions.push({\n id: 'translate',\n label: 'Translate',\n description: 'Translate to another language',\n priority: 6,\n });\n\n // Tone adjustments\n actions.push(\n { id: 'makeFormal', label: 'Make Formal', description: 'Use formal tone', priority: 5 },\n { id: 'makeCasual', label: 'Make Casual', description: 'Use casual tone', priority: 4 }\n );\n }\n\n // Sort by priority (descending)\n actions.sort((a, b) => (b.priority || 0) - (a.priority || 0));\n\n return actions;\n}\n\n// ============================================================================\n// EXPORTS\n// ============================================================================\n\nexport {\n getAgentContext as default,\n getParagraphText,\n getRunText,\n calculateWordCount,\n calculateCharacterCount,\n countWords,\n};\n","/**\n * Selection Context Builder\n *\n * Builds rich context objects from document selections for AI operations.\n * Includes selected text, formatting, surrounding context, and suggested actions.\n */\n\nimport type {\n Document,\n DocumentBody,\n Paragraph,\n Run,\n Hyperlink,\n TextFormatting,\n} from '../types/document';\n\nimport type {\n SelectionContext,\n ParagraphContext,\n SuggestedAction,\n Range,\n Position,\n} from '../types/agentApi';\n\nimport { getDocumentSummary } from './context';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\n/**\n * Options for building selection context\n */\nexport interface SelectionContextOptions {\n /** Characters of context before selection (default: 200) */\n contextCharsBefore?: number;\n /** Characters of context after selection (default: 200) */\n contextCharsAfter?: number;\n /** Include suggested actions (default: true) */\n includeSuggestions?: boolean;\n /** Include document summary (default: true) */\n includeDocumentSummary?: boolean;\n /** Maximum suggested actions (default: 8) */\n maxSuggestions?: number;\n}\n\n/**\n * Extended selection context with additional details\n */\nexport interface ExtendedSelectionContext extends SelectionContext {\n /** Document summary for additional context */\n documentSummary?: string;\n /** Selection word count */\n wordCount?: number;\n /** Selection character count */\n characterCount?: number;\n /** Is selection multi-paragraph */\n isMultiParagraph?: boolean;\n /** Selected paragraph indices */\n paragraphIndices?: number[];\n /** Language detection hint */\n detectedLanguage?: string;\n /** Content type hints */\n contentType?: 'prose' | 'list' | 'heading' | 'table' | 'mixed';\n}\n\n/**\n * Selection formatting summary\n */\nexport interface FormattingSummary {\n /** Predominant formatting */\n predominant: Partial<TextFormatting>;\n /** Is formatting consistent across selection */\n isConsistent: boolean;\n /** All formatting found */\n allFormatting: Partial<TextFormatting>[];\n}\n\n// ============================================================================\n// MAIN FUNCTIONS\n// ============================================================================\n\n/**\n * Build selection context for AI operations\n *\n * @param doc - The parsed document\n * @param range - The selected range\n * @param options - Selection context options\n * @returns SelectionContext object\n */\nexport function buildSelectionContext(\n doc: Document,\n range: Range,\n options: SelectionContextOptions = {}\n): SelectionContext {\n const { contextCharsBefore = 200, contextCharsAfter = 200, includeSuggestions = true } = options;\n\n const body = doc.package.document;\n const paragraphs = body.content.filter((block): block is Paragraph => block.type === 'paragraph');\n\n // Validate range\n if (range.start.paragraphIndex >= paragraphs.length) {\n throw new Error(`Invalid start paragraph index: ${range.start.paragraphIndex}`);\n }\n\n const startParagraph = paragraphs[range.start.paragraphIndex];\n\n // Extract selected text\n const selectedText = extractSelectedText(paragraphs, range);\n\n // Get context before and after\n const textBefore = getTextBefore(paragraphs, range.start, contextCharsBefore);\n const textAfter = getTextAfter(paragraphs, range.end, contextCharsAfter);\n\n // Get formatting at selection start\n const formatting = getFormattingAtPosition(startParagraph, range.start.offset);\n const paragraphFormatting = startParagraph.formatting || {};\n\n // Build paragraph context\n const paragraphContext: ParagraphContext = {\n index: range.start.paragraphIndex,\n fullText: getParagraphText(startParagraph),\n style: startParagraph.formatting?.styleId,\n wordCount: countWords(getParagraphText(startParagraph)),\n };\n\n // Check special contexts\n const inTable = isPositionInTable(body, range.start);\n const inHyperlink = isPositionInHyperlink(startParagraph, range.start.offset);\n\n // Build suggested actions\n const suggestedActions = includeSuggestions\n ? getSuggestedActions(selectedText, formatting, paragraphContext)\n : [];\n\n return {\n selectedText,\n range,\n formatting,\n paragraphFormatting,\n textBefore,\n textAfter,\n paragraph: paragraphContext,\n inTable,\n inHyperlink,\n suggestedActions,\n };\n}\n\n/**\n * Build extended selection context with additional details\n *\n * @param doc - The parsed document\n * @param range - The selected range\n * @param options - Selection context options\n * @returns ExtendedSelectionContext object\n */\nexport function buildExtendedSelectionContext(\n doc: Document,\n range: Range,\n options: SelectionContextOptions = {}\n): ExtendedSelectionContext {\n const baseContext = buildSelectionContext(doc, range, options);\n\n const { includeDocumentSummary = true } = options;\n\n const body = doc.package.document;\n const paragraphs = body.content.filter((block): block is Paragraph => block.type === 'paragraph');\n\n // Calculate additional stats\n const wordCount = countWords(baseContext.selectedText);\n const characterCount = baseContext.selectedText.length;\n const isMultiParagraph = range.start.paragraphIndex !== range.end.paragraphIndex;\n\n // Get paragraph indices\n const paragraphIndices: number[] = [];\n for (let i = range.start.paragraphIndex; i <= range.end.paragraphIndex; i++) {\n paragraphIndices.push(i);\n }\n\n // Detect content type\n const contentType = detectContentType(paragraphs, range);\n\n // Get document summary if requested\n const documentSummary = includeDocumentSummary ? getDocumentSummary(doc) : undefined;\n\n // Detect language (simple heuristic)\n const detectedLanguage = detectLanguage(baseContext.selectedText);\n\n return {\n ...baseContext,\n documentSummary,\n wordCount,\n characterCount,\n isMultiParagraph,\n paragraphIndices,\n detectedLanguage,\n contentType,\n };\n}\n\n/**\n * Get formatting summary for a selection\n *\n * @param doc - The parsed document\n * @param range - The selected range\n * @returns FormattingSummary object\n */\nexport function getSelectionFormattingSummary(doc: Document, range: Range): FormattingSummary {\n const body = doc.package.document;\n const paragraphs = body.content.filter((block): block is Paragraph => block.type === 'paragraph');\n\n const allFormatting: Partial<TextFormatting>[] = [];\n\n for (let paraIdx = range.start.paragraphIndex; paraIdx <= range.end.paragraphIndex; paraIdx++) {\n const paragraph = paragraphs[paraIdx];\n if (!paragraph) continue;\n\n const startOffset = paraIdx === range.start.paragraphIndex ? range.start.offset : 0;\n const endOffset = paraIdx === range.end.paragraphIndex ? range.end.offset : Infinity;\n\n collectFormattingInRange(paragraph, startOffset, endOffset, allFormatting);\n }\n\n // Check if formatting is consistent\n const isConsistent =\n allFormatting.length <= 1 || allFormatting.every((f) => formatEqual(f, allFormatting[0]));\n\n // Get predominant formatting (first one or merge)\n const predominant = allFormatting.length > 0 ? allFormatting[0] : {};\n\n return {\n predominant,\n isConsistent,\n allFormatting,\n };\n}\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Extract selected text from paragraphs\n */\nfunction extractSelectedText(paragraphs: Paragraph[], range: Range): string {\n if (range.start.paragraphIndex === range.end.paragraphIndex) {\n const paragraph = paragraphs[range.start.paragraphIndex];\n if (!paragraph) return '';\n const text = getParagraphText(paragraph);\n return text.slice(range.start.offset, range.end.offset);\n }\n\n const texts: string[] = [];\n for (let i = range.start.paragraphIndex; i <= range.end.paragraphIndex; i++) {\n const paragraph = paragraphs[i];\n if (!paragraph) continue;\n const text = getParagraphText(paragraph);\n\n if (i === range.start.paragraphIndex) {\n texts.push(text.slice(range.start.offset));\n } else if (i === range.end.paragraphIndex) {\n texts.push(text.slice(0, range.end.offset));\n } else {\n texts.push(text);\n }\n }\n\n return texts.join('\\n');\n}\n\n/**\n * Get text before a position\n */\nfunction getTextBefore(paragraphs: Paragraph[], position: Position, maxChars: number): string {\n const texts: string[] = [];\n let totalChars = 0;\n\n // Text before offset in current paragraph\n const currentPara = paragraphs[position.paragraphIndex];\n if (currentPara) {\n const text = getParagraphText(currentPara);\n const beforeText = text.slice(0, position.offset);\n texts.unshift(beforeText);\n totalChars += beforeText.length;\n }\n\n // Text from previous paragraphs\n for (let i = position.paragraphIndex - 1; i >= 0 && totalChars < maxChars; i--) {\n const para = paragraphs[i];\n if (!para) continue;\n const text = getParagraphText(para);\n texts.unshift(text);\n totalChars += text.length;\n }\n\n const combined = texts.join('\\n');\n if (combined.length > maxChars) {\n return '...' + combined.slice(-maxChars);\n }\n return combined;\n}\n\n/**\n * Get text after a position\n */\nfunction getTextAfter(paragraphs: Paragraph[], position: Position, maxChars: number): string {\n const texts: string[] = [];\n let totalChars = 0;\n\n // Text after offset in current paragraph\n const currentPara = paragraphs[position.paragraphIndex];\n if (currentPara) {\n const text = getParagraphText(currentPara);\n const afterText = text.slice(position.offset);\n texts.push(afterText);\n totalChars += afterText.length;\n }\n\n // Text from following paragraphs\n for (let i = position.paragraphIndex + 1; i < paragraphs.length && totalChars < maxChars; i++) {\n const para = paragraphs[i];\n if (!para) continue;\n const text = getParagraphText(para);\n texts.push(text);\n totalChars += text.length;\n }\n\n const combined = texts.join('\\n');\n if (combined.length > maxChars) {\n return combined.slice(0, maxChars) + '...';\n }\n return combined;\n}\n\n/**\n * Get formatting at a specific position\n */\nfunction getFormattingAtPosition(paragraph: Paragraph, offset: number): Partial<TextFormatting> {\n let currentOffset = 0;\n\n for (const item of paragraph.content) {\n if (item.type === 'run') {\n const text = getRunText(item);\n const runEnd = currentOffset + text.length;\n\n if (offset >= currentOffset && offset < runEnd) {\n return item.formatting || {};\n }\n\n currentOffset = runEnd;\n } else if (item.type === 'hyperlink') {\n const text = getHyperlinkText(item);\n const linkEnd = currentOffset + text.length;\n\n if (offset >= currentOffset && offset < linkEnd) {\n for (const child of item.children) {\n if (child.type === 'run') {\n return child.formatting || {};\n }\n }\n }\n\n currentOffset = linkEnd;\n }\n }\n\n return {};\n}\n\n/**\n * Collect formatting in a range within a paragraph\n */\nfunction collectFormattingInRange(\n paragraph: Paragraph,\n startOffset: number,\n endOffset: number,\n result: Partial<TextFormatting>[]\n): void {\n let currentOffset = 0;\n\n for (const item of paragraph.content) {\n if (item.type === 'run') {\n const text = getRunText(item);\n const runStart = currentOffset;\n const runEnd = currentOffset + text.length;\n\n // Check if run overlaps with range\n if (runEnd > startOffset && runStart < endOffset) {\n if (item.formatting) {\n result.push({ ...item.formatting });\n }\n }\n\n currentOffset = runEnd;\n } else if (item.type === 'hyperlink') {\n const text = getHyperlinkText(item);\n const linkStart = currentOffset;\n const linkEnd = currentOffset + text.length;\n\n if (linkEnd > startOffset && linkStart < endOffset) {\n for (const child of item.children) {\n if (child.type === 'run' && child.formatting) {\n result.push({ ...child.formatting });\n }\n }\n }\n\n currentOffset = linkEnd;\n }\n }\n}\n\n/**\n * Check if position is in a table\n */\nfunction isPositionInTable(_body: DocumentBody, _position: Position): boolean {\n // Tables are block-level, so position in a table would be in cell paragraphs\n // For now, return false - full implementation would track paragraph sources\n return false;\n}\n\n/**\n * Check if position is in a hyperlink\n */\nfunction isPositionInHyperlink(paragraph: Paragraph, offset: number): boolean {\n let currentOffset = 0;\n\n for (const item of paragraph.content) {\n if (item.type === 'run') {\n const text = getRunText(item);\n currentOffset += text.length;\n } else if (item.type === 'hyperlink') {\n const text = getHyperlinkText(item);\n const linkStart = currentOffset;\n const linkEnd = currentOffset + text.length;\n\n if (offset >= linkStart && offset < linkEnd) {\n return true;\n }\n\n currentOffset = linkEnd;\n }\n }\n\n return false;\n}\n\n/**\n * Get suggested actions based on selection\n */\nfunction getSuggestedActions(\n selectedText: string,\n _formatting: Partial<TextFormatting>,\n _paragraphContext: ParagraphContext\n): SuggestedAction[] {\n const actions: SuggestedAction[] = [];\n\n if (!selectedText || selectedText.trim().length === 0) {\n return actions;\n }\n\n // Basic actions for any text\n actions.push(\n { id: 'askAI', label: 'Ask AI', description: 'Ask AI about this text', priority: 11 },\n { id: 'rewrite', label: 'Rewrite', description: 'Rewrite this text differently', priority: 10 }\n );\n\n // Length-based suggestions\n const wordCount = countWords(selectedText);\n\n if (wordCount > 50) {\n actions.push({\n id: 'summarize',\n label: 'Summarize',\n description: 'Create a shorter version',\n priority: 9,\n });\n }\n\n if (wordCount < 20) {\n actions.push({\n id: 'expand',\n label: 'Expand',\n description: 'Add more details',\n priority: 9,\n });\n }\n\n // Always useful\n actions.push(\n {\n id: 'fixGrammar',\n label: 'Fix Grammar',\n description: 'Fix grammar and spelling',\n priority: 7,\n },\n {\n id: 'translate',\n label: 'Translate',\n description: 'Translate to another language',\n priority: 6,\n },\n { id: 'explain', label: 'Explain', description: 'Explain what this means', priority: 5 }\n );\n\n // Tone adjustments\n actions.push(\n { id: 'makeFormal', label: 'Make Formal', description: 'Use formal tone', priority: 4 },\n { id: 'makeCasual', label: 'Make Casual', description: 'Use casual tone', priority: 3 }\n );\n\n // Sort by priority\n actions.sort((a, b) => (b.priority || 0) - (a.priority || 0));\n\n return actions;\n}\n\n/**\n * Detect content type of selection\n */\nfunction detectContentType(\n paragraphs: Paragraph[],\n range: Range\n): 'prose' | 'list' | 'heading' | 'table' | 'mixed' {\n const types = new Set<string>();\n\n for (let i = range.start.paragraphIndex; i <= range.end.paragraphIndex; i++) {\n const para = paragraphs[i];\n if (!para) continue;\n\n if (para.listRendering) {\n types.add('list');\n } else if (para.formatting?.styleId?.toLowerCase().includes('heading')) {\n types.add('heading');\n } else {\n types.add('prose');\n }\n }\n\n if (types.size > 1) return 'mixed';\n if (types.has('list')) return 'list';\n if (types.has('heading')) return 'heading';\n return 'prose';\n}\n\n/**\n * Simple language detection\n */\nfunction detectLanguage(text: string): string | undefined {\n // Very simple heuristic - in practice use a library\n if (/[а-яА-ЯёЁ]/.test(text)) return 'ru';\n if (/[一-龯]/.test(text)) return 'zh';\n if (/[ひらがなカタカナ]/.test(text) || /[\\u3040-\\u309F\\u30A0-\\u30FF]/.test(text)) return 'ja';\n if (/[가-힣]/.test(text)) return 'ko';\n if (/[àâäéèêëïîôùûüç]/i.test(text)) return 'fr';\n if (/[äöüß]/i.test(text)) return 'de';\n if (/[áéíóúñ]/i.test(text)) return 'es';\n return 'en'; // Default\n}\n\n/**\n * Get plain text from paragraph\n */\nfunction getParagraphText(paragraph: Paragraph): string {\n const texts: string[] = [];\n\n for (const item of paragraph.content) {\n if (item.type === 'run') {\n texts.push(getRunText(item));\n } else if (item.type === 'hyperlink') {\n texts.push(getHyperlinkText(item));\n }\n }\n\n return texts.join('');\n}\n\n/**\n * Get plain text from run\n */\nfunction getRunText(run: Run): string {\n return run.content\n .filter((c) => c.type === 'text')\n .map((c) => (c as { type: 'text'; text: string }).text)\n .join('');\n}\n\n/**\n * Get plain text from hyperlink\n */\nfunction getHyperlinkText(hyperlink: Hyperlink): string {\n const texts: string[] = [];\n for (const child of hyperlink.children) {\n if (child.type === 'run') {\n texts.push(getRunText(child));\n }\n }\n return texts.join('');\n}\n\n/**\n * Count words in text\n */\nfunction countWords(text: string): number {\n return text.split(/\\s+/).filter((w) => w.length > 0).length;\n}\n\n/**\n * Check if two formatting objects are equal\n */\nfunction formatEqual(a: Partial<TextFormatting>, b: Partial<TextFormatting>): boolean {\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n\n if (keysA.length !== keysB.length) return false;\n\n return keysA.every((key) => {\n const valA = (a as Record<string, unknown>)[key];\n const valB = (b as Record<string, unknown>)[key];\n return valA === valB;\n });\n}\n\n// ============================================================================\n// EXPORTS\n// ============================================================================\n\nexport {\n buildSelectionContext as default,\n extractSelectedText,\n getTextBefore,\n getTextAfter,\n getFormattingAtPosition,\n getSuggestedActions,\n detectContentType,\n detectLanguage,\n countWords,\n};\n","/**\n * Shared Text Utilities for Agent Module\n *\n * Common text extraction and manipulation utilities used by\n * context.ts, selectionContext.ts, and other agent-related code.\n *\n * Consolidates duplicated helper functions into a single location.\n */\n\nimport type {\n DocumentBody,\n Paragraph,\n Run,\n Hyperlink,\n Table,\n TextFormatting,\n} from '../types/document';\n\nimport type { Position } from '../types/agentApi';\n\n// ============================================================================\n// TEXT EXTRACTION\n// ============================================================================\n\n/**\n * Get plain text from a paragraph\n */\nexport function getParagraphText(paragraph: Paragraph): string {\n const texts: string[] = [];\n\n for (const item of paragraph.content) {\n if (item.type === 'run') {\n texts.push(getRunText(item));\n } else if (item.type === 'hyperlink') {\n texts.push(getHyperlinkText(item));\n }\n }\n\n return texts.join('');\n}\n\n/**\n * Get plain text from a run\n */\nexport function getRunText(run: Run): string {\n return run.content\n .filter((c) => c.type === 'text')\n .map((c) => (c as { type: 'text'; text: string }).text)\n .join('');\n}\n\n/**\n * Get plain text from a hyperlink\n */\nexport function getHyperlinkText(hyperlink: Hyperlink): string {\n const texts: string[] = [];\n for (const child of hyperlink.children) {\n if (child.type === 'run') {\n texts.push(getRunText(child));\n }\n }\n return texts.join('');\n}\n\n/**\n * Get plain text from a table\n */\nexport function getTableText(table: Table): string {\n const texts: string[] = [];\n\n for (const row of table.rows) {\n for (const cell of row.cells) {\n for (const block of cell.content) {\n if (block.type === 'paragraph') {\n texts.push(getParagraphText(block));\n }\n }\n }\n }\n\n return texts.join('\\t');\n}\n\n/**\n * Get plain text from document body\n */\nexport function getBodyText(body: DocumentBody): string {\n const texts: string[] = [];\n\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n texts.push(getParagraphText(block));\n } else if (block.type === 'table') {\n texts.push(getTableText(block));\n }\n }\n\n return texts.join('\\n');\n}\n\n// ============================================================================\n// WORD COUNTING\n// ============================================================================\n\n/**\n * Count words in text\n */\nexport function countWords(text: string): number {\n const words = text.split(/\\s+/).filter((w) => w.length > 0);\n return words.length;\n}\n\n/**\n * Count characters in text\n */\nexport function countCharacters(text: string, includeSpaces = true): number {\n if (includeSpaces) {\n return text.length;\n }\n return text.replace(/\\s/g, '').length;\n}\n\n/**\n * Get word count from document body\n */\nexport function getBodyWordCount(body: DocumentBody): number {\n let count = 0;\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n count += countWords(getParagraphText(block));\n } else if (block.type === 'table') {\n count += getTableWordCount(block);\n }\n }\n return count;\n}\n\n/**\n * Get word count from table\n */\nexport function getTableWordCount(table: Table): number {\n let count = 0;\n for (const row of table.rows) {\n for (const cell of row.cells) {\n for (const block of cell.content) {\n if (block.type === 'paragraph') {\n count += countWords(getParagraphText(block));\n }\n }\n }\n }\n return count;\n}\n\n/**\n * Get character count from document body\n */\nexport function getBodyCharacterCount(body: DocumentBody): number {\n let count = 0;\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n count += getParagraphText(block).length;\n } else if (block.type === 'table') {\n count += getTableCharacterCount(block);\n }\n }\n return count;\n}\n\n/**\n * Get character count from table\n */\nexport function getTableCharacterCount(table: Table): number {\n let count = 0;\n for (const row of table.rows) {\n for (const cell of row.cells) {\n for (const block of cell.content) {\n if (block.type === 'paragraph') {\n count += getParagraphText(block).length;\n }\n }\n }\n }\n return count;\n}\n\n// ============================================================================\n// CONTEXT EXTRACTION\n// ============================================================================\n\n/**\n * Get text before a position\n *\n * @param paragraphs - Array of paragraphs\n * @param position - Position to get text before\n * @param maxChars - Maximum characters to return\n * @returns Text before the position\n */\nexport function getTextBefore(\n paragraphs: Paragraph[],\n position: Position,\n maxChars: number\n): string {\n const texts: string[] = [];\n let totalChars = 0;\n\n // Text before offset in current paragraph\n const currentPara = paragraphs[position.paragraphIndex];\n if (currentPara) {\n const text = getParagraphText(currentPara);\n const beforeText = text.slice(0, position.offset);\n texts.unshift(beforeText);\n totalChars += beforeText.length;\n }\n\n // Text from previous paragraphs\n for (let i = position.paragraphIndex - 1; i >= 0 && totalChars < maxChars; i--) {\n const para = paragraphs[i];\n if (!para) continue;\n const text = getParagraphText(para);\n texts.unshift(text);\n totalChars += text.length;\n }\n\n const combined = texts.join('\\n');\n if (combined.length > maxChars) {\n return '...' + combined.slice(-maxChars);\n }\n return combined;\n}\n\n/**\n * Get text after a position\n *\n * @param paragraphs - Array of paragraphs\n * @param position - Position to get text after\n * @param maxChars - Maximum characters to return\n * @returns Text after the position\n */\nexport function getTextAfter(\n paragraphs: Paragraph[],\n position: Position,\n maxChars: number\n): string {\n const texts: string[] = [];\n let totalChars = 0;\n\n // Text after offset in current paragraph\n const currentPara = paragraphs[position.paragraphIndex];\n if (currentPara) {\n const text = getParagraphText(currentPara);\n const afterText = text.slice(position.offset);\n texts.push(afterText);\n totalChars += afterText.length;\n }\n\n // Text from following paragraphs\n for (let i = position.paragraphIndex + 1; i < paragraphs.length && totalChars < maxChars; i++) {\n const para = paragraphs[i];\n if (!para) continue;\n const text = getParagraphText(para);\n texts.push(text);\n totalChars += text.length;\n }\n\n const combined = texts.join('\\n');\n if (combined.length > maxChars) {\n return combined.slice(0, maxChars) + '...';\n }\n return combined;\n}\n\n// ============================================================================\n// FORMATTING QUERIES\n// ============================================================================\n\n/**\n * Get formatting at a specific position in a paragraph\n *\n * @param paragraph - The paragraph to check\n * @param offset - Character offset in the paragraph\n * @returns Formatting at that position\n */\nexport function getFormattingAtPosition(\n paragraph: Paragraph,\n offset: number\n): Partial<TextFormatting> {\n let currentOffset = 0;\n\n for (const item of paragraph.content) {\n if (item.type === 'run') {\n const text = getRunText(item);\n const runEnd = currentOffset + text.length;\n\n if (offset >= currentOffset && offset < runEnd) {\n return item.formatting || {};\n }\n\n currentOffset = runEnd;\n } else if (item.type === 'hyperlink') {\n const text = getHyperlinkText(item);\n const linkEnd = currentOffset + text.length;\n\n if (offset >= currentOffset && offset < linkEnd) {\n // Return formatting from first child run\n for (const child of item.children) {\n if (child.type === 'run') {\n return child.formatting || {};\n }\n }\n }\n\n currentOffset = linkEnd;\n }\n }\n\n return {};\n}\n\n/**\n * Check if position is within a hyperlink\n *\n * @param paragraph - The paragraph to check\n * @param offset - Character offset in the paragraph\n * @returns True if position is in a hyperlink\n */\nexport function isPositionInHyperlink(paragraph: Paragraph, offset: number): boolean {\n let currentOffset = 0;\n\n for (const item of paragraph.content) {\n if (item.type === 'run') {\n const text = getRunText(item);\n currentOffset += text.length;\n } else if (item.type === 'hyperlink') {\n const text = getHyperlinkText(item);\n const linkStart = currentOffset;\n const linkEnd = currentOffset + text.length;\n\n if (offset >= linkStart && offset < linkEnd) {\n return true;\n }\n\n currentOffset = linkEnd;\n }\n }\n\n return false;\n}\n\n/**\n * Get hyperlink at position\n *\n * @param paragraph - The paragraph to check\n * @param offset - Character offset in the paragraph\n * @returns The hyperlink at that position, or undefined\n */\nexport function getHyperlinkAtPosition(\n paragraph: Paragraph,\n offset: number\n): Hyperlink | undefined {\n let currentOffset = 0;\n\n for (const item of paragraph.content) {\n if (item.type === 'run') {\n const text = getRunText(item);\n currentOffset += text.length;\n } else if (item.type === 'hyperlink') {\n const text = getHyperlinkText(item);\n const linkStart = currentOffset;\n const linkEnd = currentOffset + text.length;\n\n if (offset >= linkStart && offset < linkEnd) {\n return item;\n }\n\n currentOffset = linkEnd;\n }\n }\n\n return undefined;\n}\n\n// ============================================================================\n// STYLE HELPERS\n// ============================================================================\n\n/**\n * Check if style ID represents a heading\n *\n * @param styleId - Style ID to check\n * @returns True if it's a heading style\n */\nexport function isHeadingStyle(styleId?: string): boolean {\n if (!styleId) return false;\n return styleId.toLowerCase().includes('heading');\n}\n\n/**\n * Parse heading level from style ID\n *\n * @param styleId - Style ID to parse\n * @returns Heading level (1-9) or undefined\n */\nexport function parseHeadingLevel(styleId?: string): number | undefined {\n if (!styleId) return undefined;\n const match = styleId.match(/heading\\s*(\\d)/i);\n if (match) {\n return parseInt(match[1], 10);\n }\n return undefined;\n}\n\n// ============================================================================\n// DOCUMENT QUERIES\n// ============================================================================\n\n/**\n * Check if document body has images\n *\n * @param body - Document body to check\n * @returns True if contains images\n */\nexport function hasImages(body: DocumentBody): boolean {\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n for (const item of block.content) {\n if (item.type === 'run') {\n for (const content of item.content) {\n if (content.type === 'drawing') {\n return true;\n }\n }\n }\n }\n }\n }\n return false;\n}\n\n/**\n * Check if document body has hyperlinks\n *\n * @param body - Document body to check\n * @returns True if contains hyperlinks\n */\nexport function hasHyperlinks(body: DocumentBody): boolean {\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n for (const item of block.content) {\n if (item.type === 'hyperlink') {\n return true;\n }\n }\n }\n }\n return false;\n}\n\n/**\n * Check if document body has tables\n *\n * @param body - Document body to check\n * @returns True if contains tables\n */\nexport function hasTables(body: DocumentBody): boolean {\n return body.content.some((block) => block.type === 'table');\n}\n\n// ============================================================================\n// PARAGRAPH HELPERS\n// ============================================================================\n\n/**\n * Get all paragraphs from document body\n *\n * @param body - Document body\n * @returns Array of paragraphs\n */\nexport function getParagraphs(body: DocumentBody): Paragraph[] {\n return body.content.filter((block): block is Paragraph => block.type === 'paragraph');\n}\n\n/**\n * Get paragraph at index from document body\n *\n * @param body - Document body\n * @param index - Paragraph index (0-indexed)\n * @returns Paragraph or undefined\n */\nexport function getParagraphAtIndex(body: DocumentBody, index: number): Paragraph | undefined {\n const paragraphs = getParagraphs(body);\n return paragraphs[index];\n}\n\n/**\n * Get block index for a paragraph index\n *\n * @param body - Document body\n * @param paragraphIndex - Paragraph index\n * @returns Block index or -1 if not found\n */\nexport function getBlockIndexForParagraph(body: DocumentBody, paragraphIndex: number): number {\n let currentParagraphIndex = 0;\n for (let i = 0; i < body.content.length; i++) {\n if (body.content[i].type === 'paragraph') {\n if (currentParagraphIndex === paragraphIndex) {\n return i;\n }\n currentParagraphIndex++;\n }\n }\n return -1;\n}\n\n// ============================================================================\n// EXPORTS\n// ============================================================================\n\nexport default {\n getParagraphText,\n getRunText,\n getHyperlinkText,\n getTableText,\n getBodyText,\n countWords,\n countCharacters,\n getBodyWordCount,\n getBodyCharacterCount,\n getTextBefore,\n getTextAfter,\n getFormattingAtPosition,\n isPositionInHyperlink,\n getHyperlinkAtPosition,\n isHeadingStyle,\n parseHeadingLevel,\n hasImages,\n hasHyperlinks,\n hasTables,\n getParagraphs,\n getParagraphAtIndex,\n getBlockIndexForParagraph,\n};\n","/**\n * Create Document Utility\n *\n * Provides functions to create new documents programmatically.\n */\n\nimport type {\n Document,\n DocxPackage,\n DocumentBody,\n Paragraph,\n Run,\n TextContent,\n SectionProperties,\n Style,\n} from '../types/document';\n\n// ============================================================================\n// DEFAULT STYLES\n// ============================================================================\n\n/**\n * Get default paragraph styles (matching Google Docs defaults)\n *\n * Font sizes are in half-points (e.g., 22 = 11pt, 40 = 20pt)\n * Colors are RGB hex without # prefix\n */\nfunction getDefaultStyles(): Style[] {\n return [\n // Normal - base style for body text (11pt Arial)\n {\n styleId: 'Normal',\n type: 'paragraph',\n name: 'Normal',\n default: true,\n qFormat: true,\n uiPriority: 0,\n rPr: {\n fontSize: 22, // 11pt\n fontFamily: {\n ascii: 'Arial',\n hAnsi: 'Arial',\n },\n },\n pPr: {\n lineSpacing: 276, // 1.15 spacing\n },\n },\n // Title - document title (26pt, bold)\n {\n styleId: 'Title',\n type: 'paragraph',\n name: 'Title',\n basedOn: 'Normal',\n next: 'Normal',\n qFormat: true,\n uiPriority: 10,\n rPr: {\n fontSize: 52, // 26pt\n bold: true,\n fontFamily: {\n ascii: 'Arial',\n hAnsi: 'Arial',\n },\n },\n pPr: {\n lineSpacing: 240, // Single spacing\n },\n },\n // Subtitle (15pt, gray)\n {\n styleId: 'Subtitle',\n type: 'paragraph',\n name: 'Subtitle',\n basedOn: 'Normal',\n next: 'Normal',\n qFormat: true,\n uiPriority: 11,\n rPr: {\n fontSize: 30, // 15pt\n color: { rgb: '666666' }, // Gray\n fontFamily: {\n ascii: 'Arial',\n hAnsi: 'Arial',\n },\n },\n pPr: {\n lineSpacing: 240,\n },\n },\n // Heading 1 (20pt, bold)\n {\n styleId: 'Heading1',\n type: 'paragraph',\n name: 'Heading 1',\n basedOn: 'Normal',\n next: 'Normal',\n qFormat: true,\n uiPriority: 9,\n rPr: {\n fontSize: 40, // 20pt\n bold: true,\n fontFamily: {\n ascii: 'Arial',\n hAnsi: 'Arial',\n },\n },\n pPr: {\n spaceBefore: 400, // 20pt before\n spaceAfter: 120, // 6pt after\n lineSpacing: 240,\n },\n },\n // Heading 2 (16pt, bold)\n {\n styleId: 'Heading2',\n type: 'paragraph',\n name: 'Heading 2',\n basedOn: 'Normal',\n next: 'Normal',\n qFormat: true,\n uiPriority: 9,\n rPr: {\n fontSize: 32, // 16pt\n bold: true,\n fontFamily: {\n ascii: 'Arial',\n hAnsi: 'Arial',\n },\n },\n pPr: {\n spaceBefore: 360, // 18pt before\n spaceAfter: 80, // 4pt after\n lineSpacing: 240,\n },\n },\n // Heading 3 (14pt, bold)\n {\n styleId: 'Heading3',\n type: 'paragraph',\n name: 'Heading 3',\n basedOn: 'Normal',\n next: 'Normal',\n qFormat: true,\n uiPriority: 9,\n rPr: {\n fontSize: 28, // 14pt\n bold: true,\n fontFamily: {\n ascii: 'Arial',\n hAnsi: 'Arial',\n },\n },\n pPr: {\n spaceBefore: 320, // 16pt before\n spaceAfter: 80, // 4pt after\n lineSpacing: 240,\n },\n },\n // Heading 4 (12pt, bold)\n {\n styleId: 'Heading4',\n type: 'paragraph',\n name: 'Heading 4',\n basedOn: 'Normal',\n next: 'Normal',\n qFormat: true,\n uiPriority: 9,\n rPr: {\n fontSize: 24, // 12pt\n bold: true,\n fontFamily: {\n ascii: 'Arial',\n hAnsi: 'Arial',\n },\n },\n pPr: {\n spaceBefore: 280, // 14pt before\n spaceAfter: 80, // 4pt after\n lineSpacing: 240,\n },\n },\n ];\n}\n\n// ============================================================================\n// DEFAULT SECTION PROPERTIES\n// ============================================================================\n\n/**\n * Get default section properties (US Letter, 1 inch margins)\n */\nfunction getDefaultSectionProperties(): SectionProperties {\n return {\n pageWidth: 12240, // 8.5 inches in twips\n pageHeight: 15840, // 11 inches in twips\n orientation: 'portrait',\n marginTop: 1440, // 1 inch\n marginBottom: 1440,\n marginLeft: 1440,\n marginRight: 1440,\n headerDistance: 720, // 0.5 inch\n footerDistance: 720,\n gutter: 0,\n columnCount: 1,\n columnSpace: 720,\n equalWidth: true,\n sectionStart: 'nextPage',\n verticalAlign: 'top',\n };\n}\n\n// ============================================================================\n// EMPTY DOCUMENT\n// ============================================================================\n\n/**\n * Options for creating an empty document\n */\nexport interface CreateEmptyDocumentOptions {\n /** Page width in twips (default: 12240 = 8.5 inches) */\n pageWidth?: number;\n /** Page height in twips (default: 15840 = 11 inches) */\n pageHeight?: number;\n /** Page orientation (default: 'portrait') */\n orientation?: 'portrait' | 'landscape';\n /** Top margin in twips (default: 1440 = 1 inch) */\n marginTop?: number;\n /** Bottom margin in twips (default: 1440 = 1 inch) */\n marginBottom?: number;\n /** Left margin in twips (default: 1440 = 1 inch) */\n marginLeft?: number;\n /** Right margin in twips (default: 1440 = 1 inch) */\n marginRight?: number;\n /** Initial text content (default: empty string) */\n initialText?: string;\n}\n\n/**\n * Create an empty document with a single paragraph\n *\n * @param options - Optional configuration for the document\n * @returns A new empty Document object\n *\n * @example\n * ```ts\n * // Create a blank document\n * const doc = createEmptyDocument();\n *\n * // Create with custom margins\n * const doc = createEmptyDocument({\n * marginTop: 720, // 0.5 inch\n * marginBottom: 720,\n * });\n *\n * // Create with initial text\n * const doc = createEmptyDocument({\n * initialText: 'Hello, World!'\n * });\n * ```\n */\nexport function createEmptyDocument(options: CreateEmptyDocumentOptions = {}): Document {\n const sectionProps = getDefaultSectionProperties();\n\n // Apply custom options\n if (options.pageWidth !== undefined) sectionProps.pageWidth = options.pageWidth;\n if (options.pageHeight !== undefined) sectionProps.pageHeight = options.pageHeight;\n if (options.orientation !== undefined) sectionProps.orientation = options.orientation;\n if (options.marginTop !== undefined) sectionProps.marginTop = options.marginTop;\n if (options.marginBottom !== undefined) sectionProps.marginBottom = options.marginBottom;\n if (options.marginLeft !== undefined) sectionProps.marginLeft = options.marginLeft;\n if (options.marginRight !== undefined) sectionProps.marginRight = options.marginRight;\n\n // Create initial paragraph content\n const textContent: TextContent = {\n type: 'text',\n text: options.initialText || '',\n };\n\n const run: Run = {\n type: 'run',\n content: options.initialText ? [textContent] : [],\n formatting: {\n fontSize: 22, // 11pt (half-points) - Google Docs default\n fontFamily: {\n ascii: 'Arial',\n hAnsi: 'Arial',\n },\n },\n };\n\n const paragraph: Paragraph = {\n type: 'paragraph',\n content: [run],\n formatting: {\n lineSpacing: 276, // 1.15 line spacing (default Word)\n },\n };\n\n // Create document body\n const documentBody: DocumentBody = {\n content: [paragraph],\n finalSectionProperties: sectionProps,\n };\n\n // Create package with default styles\n const docxPackage: DocxPackage = {\n document: documentBody,\n styles: {\n docDefaults: {\n rPr: {\n fontSize: 22, // 11pt (Google Docs default)\n fontFamily: {\n ascii: 'Arial',\n hAnsi: 'Arial',\n },\n },\n pPr: {\n lineSpacing: 276, // 1.15 line spacing\n },\n },\n styles: getDefaultStyles(),\n },\n };\n\n // Create document\n const document: Document = {\n package: docxPackage,\n templateVariables: [],\n warnings: [],\n };\n\n return document;\n}\n\n/**\n * Create a document with a single paragraph containing the given text\n *\n * @param text - The text content for the document\n * @param options - Optional configuration for the document\n * @returns A new Document object with the specified text\n */\nexport function createDocumentWithText(\n text: string,\n options: Omit<CreateEmptyDocumentOptions, 'initialText'> = {}\n): Document {\n return createEmptyDocument({ ...options, initialText: text });\n}\n","/**\n * Color Resolver - Convert OOXML colors to CSS\n *\n * Handles:\n * - Theme color references (accent1, dk1, etc.)\n * - RGB hex values\n * - \"auto\" colors (context-dependent)\n * - Tint/shade modifications\n *\n * OOXML Color References:\n * - w:color/@w:val - RGB hex or \"auto\"\n * - w:color/@w:themeColor - Theme color slot\n * - w:color/@w:themeTint - Tint modifier (0-255, hex)\n * - w:color/@w:themeShade - Shade modifier (0-255, hex)\n *\n * Tint/Shade Calculations:\n * - Tint makes color lighter (blend with white)\n * - Shade makes color darker (blend with black)\n * - Value is in hex (00-FF), converted to 0-1 for calculation\n */\n\nimport type { ColorValue, Theme, ThemeColorSlot, ThemeColorScheme } from '../types/document';\n\n/**\n * Default theme colors (Office 2016 default theme)\n */\nconst DEFAULT_THEME_COLORS: ThemeColorScheme = {\n dk1: '000000',\n lt1: 'FFFFFF',\n dk2: '44546A',\n lt2: 'E7E6E6',\n accent1: '4472C4',\n accent2: 'ED7D31',\n accent3: 'A5A5A5',\n accent4: 'FFC000',\n accent5: '5B9BD5',\n accent6: '70AD47',\n hlink: '0563C1',\n folHlink: '954F72',\n};\n\n/**\n * Highlight color mapping to hex values\n * These are the W3C standard colors for Word highlighting\n */\nconst HIGHLIGHT_COLORS: Record<string, string> = {\n black: '000000',\n blue: '0000FF',\n cyan: '00FFFF',\n darkBlue: '00008B',\n darkCyan: '008B8B',\n darkGray: 'A9A9A9',\n darkGreen: '006400',\n darkMagenta: '8B008B',\n darkRed: '8B0000',\n darkYellow: '808000',\n green: '00FF00',\n lightGray: 'D3D3D3',\n magenta: 'FF00FF',\n red: 'FF0000',\n white: 'FFFFFF',\n yellow: 'FFFF00',\n none: '',\n};\n\n/**\n * Map alternative theme color names to standard slots\n * OOXML uses different names in different contexts\n */\nconst THEME_COLOR_ALIASES: Record<string, ThemeColorSlot> = {\n // Standard names\n dk1: 'dk1',\n lt1: 'lt1',\n dk2: 'dk2',\n lt2: 'lt2',\n accent1: 'accent1',\n accent2: 'accent2',\n accent3: 'accent3',\n accent4: 'accent4',\n accent5: 'accent5',\n accent6: 'accent6',\n hlink: 'hlink',\n folHlink: 'folHlink',\n // Alternative names used in some OOXML contexts\n dark1: 'dk1',\n light1: 'lt1',\n dark2: 'dk2',\n light2: 'lt2',\n hyperlink: 'hlink',\n followedHyperlink: 'folHlink',\n // Background/text names (map to dk1/lt1)\n background1: 'lt1',\n text1: 'dk1',\n background2: 'lt2',\n text2: 'dk2',\n tx1: 'dk1',\n tx2: 'dk2',\n bg1: 'lt1',\n bg2: 'lt2',\n};\n\n/**\n * Parse a hex color modifier value (tint or shade)\n * OOXML stores tint/shade as hex string (00-FF) representing 0-255\n *\n * @param hexValue - Hex string like \"80\" or \"FF\"\n * @returns Decimal value 0-1\n */\nfunction parseModifierValue(hexValue: string | undefined): number {\n if (!hexValue) return 1;\n\n const parsed = parseInt(hexValue, 16);\n if (isNaN(parsed)) return 1;\n\n // Value is 0-255, convert to 0-1\n return parsed / 255;\n}\n\n/**\n * Parse RGB hex color to component values\n *\n * @param hex - 6-character hex color (no #)\n * @returns RGB object with r, g, b values 0-255\n */\nfunction hexToRgb(hex: string): { r: number; g: number; b: number } {\n // Ensure 6 characters\n const normalized = hex.padStart(6, '0').slice(0, 6);\n\n const r = parseInt(normalized.slice(0, 2), 16);\n const g = parseInt(normalized.slice(2, 4), 16);\n const b = parseInt(normalized.slice(4, 6), 16);\n\n return {\n r: isNaN(r) ? 0 : r,\n g: isNaN(g) ? 0 : g,\n b: isNaN(b) ? 0 : b,\n };\n}\n\n/**\n * Convert RGB values to hex color\n *\n * @param r - Red 0-255\n * @param g - Green 0-255\n * @param b - Blue 0-255\n * @returns 6-character hex color (no #)\n */\nfunction rgbToHex(r: number, g: number, b: number): string {\n const toHex = (n: number) =>\n Math.max(0, Math.min(255, Math.round(n)))\n .toString(16)\n .padStart(2, '0');\n\n return `${toHex(r)}${toHex(g)}${toHex(b)}`.toUpperCase();\n}\n\n/**\n * Convert RGB to HSL\n *\n * @param r - Red 0-255\n * @param g - Green 0-255\n * @param b - Blue 0-255\n * @returns HSL object with h (0-360), s (0-1), l (0-1)\n */\nfunction rgbToHsl(r: number, g: number, b: number): { h: number; s: number; l: number } {\n r /= 255;\n g /= 255;\n b /= 255;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n\n if (max === min) {\n return { h: 0, s: 0, l };\n }\n\n const d = max - min;\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n let h: number;\n switch (max) {\n case r:\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\n break;\n case g:\n h = ((b - r) / d + 2) / 6;\n break;\n case b:\n h = ((r - g) / d + 4) / 6;\n break;\n default:\n h = 0;\n }\n\n return { h: h * 360, s, l };\n}\n\n/**\n * Convert HSL to RGB\n *\n * @param h - Hue 0-360\n * @param s - Saturation 0-1\n * @param l - Lightness 0-1\n * @returns RGB object with r, g, b values 0-255\n */\nfunction hslToRgb(h: number, s: number, l: number): { r: number; g: number; b: number } {\n h = h / 360;\n\n if (s === 0) {\n const gray = Math.round(l * 255);\n return { r: gray, g: gray, b: gray };\n }\n\n const hue2rgb = (p: number, q: number, t: number) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n\n return {\n r: Math.round(hue2rgb(p, q, h + 1 / 3) * 255),\n g: Math.round(hue2rgb(p, q, h) * 255),\n b: Math.round(hue2rgb(p, q, h - 1 / 3) * 255),\n };\n}\n\n/**\n * Apply tint to a color (make lighter by blending with white)\n *\n * OOXML tint algorithm:\n * - Converts to HSL\n * - Adjusts luminance: newLum = lum + (1 - lum) * tint\n *\n * @param hex - 6-character hex color (no #)\n * @param tint - Tint value 0-1 (0 = no change, 1 = fully white)\n * @returns Modified hex color\n */\nfunction applyTint(hex: string, tint: number): string {\n if (tint <= 0 || tint >= 1) {\n return tint >= 1 ? 'FFFFFF' : hex;\n }\n\n const rgb = hexToRgb(hex);\n const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);\n\n // Apply tint: increase luminance toward white\n hsl.l = hsl.l + (1 - hsl.l) * tint;\n\n const newRgb = hslToRgb(hsl.h, hsl.s, hsl.l);\n return rgbToHex(newRgb.r, newRgb.g, newRgb.b);\n}\n\n/**\n * Apply shade to a color (make darker by blending with black)\n *\n * OOXML shade algorithm:\n * - Converts to HSL\n * - Adjusts luminance: newLum = lum * shade\n *\n * @param hex - 6-character hex color (no #)\n * @param shade - Shade value 0-1 (0 = fully black, 1 = no change)\n * @returns Modified hex color\n */\nfunction applyShade(hex: string, shade: number): string {\n if (shade <= 0 || shade >= 1) {\n return shade <= 0 ? '000000' : hex;\n }\n\n const rgb = hexToRgb(hex);\n const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);\n\n // Apply shade: decrease luminance toward black\n hsl.l = hsl.l * shade;\n\n const newRgb = hslToRgb(hsl.h, hsl.s, hsl.l);\n return rgbToHex(newRgb.r, newRgb.g, newRgb.b);\n}\n\n/**\n * Get a theme color by slot name\n *\n * @param theme - Theme object\n * @param slot - Color slot name\n * @returns Hex color (6 characters, no #)\n */\nfunction getThemeColorValue(theme: Theme | null | undefined, slot: ThemeColorSlot): string {\n // Map alias slots to actual color scheme keys\n const schemeKey = THEME_COLOR_ALIASES[slot] ?? slot;\n\n // Define the actual keys that exist on ThemeColorScheme\n const schemeKeys = [\n 'dk1',\n 'lt1',\n 'dk2',\n 'lt2',\n 'accent1',\n 'accent2',\n 'accent3',\n 'accent4',\n 'accent5',\n 'accent6',\n 'hlink',\n 'folHlink',\n ] as const;\n type SchemeKey = (typeof schemeKeys)[number];\n\n const isSchemeKey = (key: string): key is SchemeKey => schemeKeys.includes(key as SchemeKey);\n\n if (!theme?.colorScheme) {\n if (isSchemeKey(schemeKey)) {\n return DEFAULT_THEME_COLORS[schemeKey] ?? '000000';\n }\n return '000000';\n }\n\n if (isSchemeKey(schemeKey)) {\n return theme.colorScheme[schemeKey] ?? DEFAULT_THEME_COLORS[schemeKey] ?? '000000';\n }\n\n return '000000';\n}\n\n/**\n * Resolve a theme color name to a standard slot\n *\n * @param colorName - Theme color name (could be alias)\n * @returns Standard ThemeColorSlot or null if unknown\n */\nfunction resolveThemeColorSlot(colorName: string): ThemeColorSlot | null {\n if (!colorName) return null;\n\n const normalized = colorName.toLowerCase();\n const slot = THEME_COLOR_ALIASES[colorName] ?? THEME_COLOR_ALIASES[normalized];\n\n return slot ?? null;\n}\n\n/**\n * Resolve a ColorValue to a CSS color string\n *\n * @param color - ColorValue object with rgb, themeColor, tint/shade, or auto\n * @param theme - Theme for resolving theme colors\n * @param defaultColor - Default color if auto or undefined (default: black)\n * @returns CSS color string (e.g., \"#FF0000\" or \"inherit\")\n */\nexport function resolveColor(\n color: ColorValue | undefined | null,\n theme: Theme | null | undefined,\n defaultColor: string = '000000'\n): string {\n if (!color) {\n return `#${defaultColor}`;\n }\n\n // Handle \"auto\" color\n if (color.auto) {\n // Auto typically means black for text, but can be context-dependent\n return `#${defaultColor}`;\n }\n\n let hexColor: string;\n\n // Check for theme color first\n if (color.themeColor) {\n const slot = resolveThemeColorSlot(color.themeColor);\n if (slot) {\n hexColor = getThemeColorValue(theme, slot);\n } else {\n // Unknown theme color, use RGB if available or default\n hexColor = color.rgb ?? defaultColor;\n }\n\n // Apply tint/shade modifiers\n if (color.themeTint) {\n const tintValue = parseModifierValue(color.themeTint);\n hexColor = applyTint(hexColor, tintValue);\n } else if (color.themeShade) {\n const shadeValue = parseModifierValue(color.themeShade);\n hexColor = applyShade(hexColor, shadeValue);\n }\n } else if (color.rgb) {\n // \"auto\" in OOXML means automatic color (typically black)\n hexColor = color.rgb === 'auto' ? defaultColor : color.rgb;\n } else {\n // No color specified\n hexColor = defaultColor;\n }\n\n // Ensure proper format\n return `#${hexColor.toUpperCase().replace(/^#/, '')}`;\n}\n\n/**\n * Resolve a highlight color name to CSS\n *\n * @param highlight - Highlight color name (e.g., \"yellow\", \"cyan\")\n * @returns CSS color string or empty string for \"none\"\n */\nexport function resolveHighlightColor(highlight: string | undefined): string {\n if (!highlight || highlight === 'none') {\n return '';\n }\n\n const hex = HIGHLIGHT_COLORS[highlight];\n return hex ? `#${hex}` : '';\n}\n\n/**\n * Resolve a shading fill or pattern color to CSS\n *\n * @param color - ColorValue for fill\n * @param theme - Theme for resolving theme colors\n * @returns CSS color string\n */\nexport function resolveShadingColor(\n color: ColorValue | undefined | null,\n theme: Theme | null | undefined\n): string {\n if (!color) return '';\n\n // For shading, \"auto\" typically means transparent\n if (color.auto) {\n return 'transparent';\n }\n\n return resolveColor(color, theme);\n}\n\n/**\n * Check if a color is effectively black\n *\n * @param color - ColorValue object\n * @param theme - Theme for resolving theme colors\n * @returns True if color resolves to black or very dark\n */\nexport function isBlack(\n color: ColorValue | undefined | null,\n theme: Theme | null | undefined\n): boolean {\n if (!color) return false;\n if (color.auto) return true;\n\n const resolved = resolveColor(color, theme);\n const hex = resolved.replace(/^#/, '').toLowerCase();\n\n // Check if it's black or very dark\n const rgb = hexToRgb(hex);\n const luminance = (rgb.r + rgb.g + rgb.b) / 3;\n\n return luminance < 20;\n}\n\n/**\n * Check if a color is effectively white\n *\n * @param color - ColorValue object\n * @param theme - Theme for resolving theme colors\n * @returns True if color resolves to white or very light\n */\nexport function isWhite(\n color: ColorValue | undefined | null,\n theme: Theme | null | undefined\n): boolean {\n if (!color) return false;\n\n const resolved = resolveColor(color, theme);\n const hex = resolved.replace(/^#/, '').toLowerCase();\n\n // Check if it's white or very light\n const rgb = hexToRgb(hex);\n const luminance = (rgb.r + rgb.g + rgb.b) / 3;\n\n return luminance > 235;\n}\n\n/**\n * Get contrasting text color for a background\n *\n * @param backgroundColor - Background ColorValue\n * @param theme - Theme for resolving theme colors\n * @returns Black or white hex color for best contrast\n */\nexport function getContrastingColor(\n backgroundColor: ColorValue | undefined | null,\n theme: Theme | null | undefined\n): string {\n if (!backgroundColor) return '#000000';\n\n const bgResolved = resolveColor(backgroundColor, theme);\n const bgHex = bgResolved.replace(/^#/, '');\n const bgRgb = hexToRgb(bgHex);\n\n // Calculate relative luminance using sRGB formula\n const luminance = (0.299 * bgRgb.r + 0.587 * bgRgb.g + 0.114 * bgRgb.b) / 255;\n\n // Return black for light backgrounds, white for dark\n return luminance > 0.5 ? '#000000' : '#FFFFFF';\n}\n\n/**\n * Parse a color string (various formats) to ColorValue\n *\n * @param colorString - Color string like \"FF0000\", \"auto\", or theme color name\n * @returns ColorValue object\n */\nexport function parseColorString(colorString: string | undefined): ColorValue | undefined {\n if (!colorString) return undefined;\n\n const normalized = colorString.trim();\n\n if (normalized.toLowerCase() === 'auto') {\n return { auto: true };\n }\n\n // Check if it's a theme color name\n const themeSlot = resolveThemeColorSlot(normalized);\n if (themeSlot) {\n return { themeColor: themeSlot };\n }\n\n // Assume it's an RGB hex value\n // Remove # if present and normalize to 6 chars\n const hex = normalized.replace(/^#/, '').toUpperCase();\n\n // Validate hex format\n if (/^[0-9A-F]{6}$/i.test(hex)) {\n return { rgb: hex };\n }\n\n // 3-character shorthand\n if (/^[0-9A-F]{3}$/i.test(hex)) {\n const expanded = hex\n .split('')\n .map((c) => c + c)\n .join('');\n return { rgb: expanded };\n }\n\n // Unknown format, return as RGB anyway\n return { rgb: hex.padStart(6, '0').slice(0, 6) };\n}\n\n/**\n * Create a ColorValue from theme color reference\n *\n * @param themeColor - Theme color slot name\n * @param tint - Optional tint modifier\n * @param shade - Optional shade modifier\n * @returns ColorValue object\n */\nexport function createThemeColor(\n themeColor: ThemeColorSlot,\n tint?: number,\n shade?: number\n): ColorValue {\n const result: ColorValue = { themeColor };\n\n if (tint !== undefined && tint > 0 && tint < 1) {\n result.themeTint = Math.round(tint * 255)\n .toString(16)\n .toUpperCase()\n .padStart(2, '0');\n }\n\n if (shade !== undefined && shade > 0 && shade < 1) {\n result.themeShade = Math.round(shade * 255)\n .toString(16)\n .toUpperCase()\n .padStart(2, '0');\n }\n\n return result;\n}\n\n/**\n * Create a ColorValue from RGB hex\n *\n * @param hex - 6-character hex color (no #)\n * @returns ColorValue object\n */\nexport function createRgbColor(hex: string): ColorValue {\n return { rgb: hex.replace(/^#/, '').toUpperCase() };\n}\n\n/**\n * Darken a color by a percentage\n *\n * @param color - ColorValue to darken\n * @param theme - Theme for resolving\n * @param percent - Percentage to darken (0-100)\n * @returns CSS color string\n */\nexport function darkenColor(\n color: ColorValue | undefined | null,\n theme: Theme | null | undefined,\n percent: number\n): string {\n const resolved = resolveColor(color, theme);\n const hex = resolved.replace(/^#/, '');\n const shade = 1 - percent / 100;\n return `#${applyShade(hex, shade)}`;\n}\n\n/**\n * Lighten a color by a percentage\n *\n * @param color - ColorValue to lighten\n * @param theme - Theme for resolving\n * @param percent - Percentage to lighten (0-100)\n * @returns CSS color string\n */\nexport function lightenColor(\n color: ColorValue | undefined | null,\n theme: Theme | null | undefined,\n percent: number\n): string {\n const resolved = resolveColor(color, theme);\n const hex = resolved.replace(/^#/, '');\n const tint = percent / 100;\n return `#${applyTint(hex, tint)}`;\n}\n\n/**\n * Blend two colors together\n *\n * @param color1 - First color\n * @param color2 - Second color\n * @param ratio - Blend ratio (0 = all color1, 1 = all color2)\n * @param theme - Theme for resolving\n * @returns CSS color string\n */\nexport function blendColors(\n color1: ColorValue | undefined | null,\n color2: ColorValue | undefined | null,\n ratio: number,\n theme: Theme | null | undefined\n): string {\n const resolved1 = resolveColor(color1, theme).replace(/^#/, '');\n const resolved2 = resolveColor(color2, theme).replace(/^#/, '');\n\n const rgb1 = hexToRgb(resolved1);\n const rgb2 = hexToRgb(resolved2);\n\n const blended = {\n r: Math.round(rgb1.r * (1 - ratio) + rgb2.r * ratio),\n g: Math.round(rgb1.g * (1 - ratio) + rgb2.g * ratio),\n b: Math.round(rgb1.b * (1 - ratio) + rgb2.b * ratio),\n };\n\n return `#${rgbToHex(blended.r, blended.g, blended.b)}`;\n}\n\n// ============================================================================\n// HEX UTILITIES\n// ============================================================================\n\n/**\n * Ensure a hex color string has a '#' prefix.\n */\nexport function ensureHexPrefix(hex: string): string {\n return hex.startsWith('#') ? hex : `#${hex}`;\n}\n\n/**\n * Resolve a highlight color value to a CSS-ready string.\n * Tries OOXML named highlight first, then ensures hex prefix.\n */\nexport function resolveHighlightToCss(value: string): string {\n return resolveHighlightColor(value) || ensureHexPrefix(value);\n}\n\n// ============================================================================\n// THEME COLOR MATRIX FOR ADVANCED COLOR PICKER\n// ============================================================================\n\n/**\n * Theme color matrix cell\n */\nexport interface ThemeMatrixCell {\n /** Resolved hex color (6 chars, no #) */\n hex: string;\n /** Theme color slot */\n themeSlot: ThemeColorSlot;\n /** Tint hex modifier if applicable (e.g., \"CC\") */\n tint?: string;\n /** Shade hex modifier if applicable (e.g., \"BF\") */\n shade?: string;\n /** Human-readable label (e.g., \"Accent 1, Lighter 60%\") */\n label: string;\n}\n\n/**\n * Theme color column order matching Word's color picker:\n * Background 1 (lt1), Text 1 (dk1), Background 2 (lt2), Text 2 (dk2), Accent 1-6\n */\nconst THEME_MATRIX_COLUMNS: Array<{ slot: ThemeColorSlot; name: string }> = [\n { slot: 'lt1', name: 'Background 1' },\n { slot: 'dk1', name: 'Text 1' },\n { slot: 'lt2', name: 'Background 2' },\n { slot: 'dk2', name: 'Text 2' },\n { slot: 'accent1', name: 'Accent 1' },\n { slot: 'accent2', name: 'Accent 2' },\n { slot: 'accent3', name: 'Accent 3' },\n { slot: 'accent4', name: 'Accent 4' },\n { slot: 'accent5', name: 'Accent 5' },\n { slot: 'accent6', name: 'Accent 6' },\n];\n\n/**\n * Tint/shade row definitions matching Word's picker.\n * Row 0 = base, rows 1-3 = tints (lighter), rows 4-5 = shades (darker).\n */\nconst THEME_MATRIX_ROWS: Array<{\n type: 'base' | 'tint' | 'shade';\n value: number; // fraction 0-1\n hexValue: string; // OOXML hex modifier\n labelSuffix: string;\n}> = [\n { type: 'base', value: 0, hexValue: '', labelSuffix: '' },\n { type: 'tint', value: 0.8, hexValue: 'CC', labelSuffix: ', Lighter 80%' },\n { type: 'tint', value: 0.6, hexValue: '99', labelSuffix: ', Lighter 60%' },\n { type: 'tint', value: 0.4, hexValue: '66', labelSuffix: ', Lighter 40%' },\n { type: 'shade', value: 0.75, hexValue: 'BF', labelSuffix: ', Darker 25%' },\n { type: 'shade', value: 0.5, hexValue: '80', labelSuffix: ', Darker 50%' },\n];\n\n/**\n * Compute a single tinted or shaded hex color from a base color.\n *\n * @param baseHex - 6-character hex color (no #)\n * @param type - 'tint' to lighten, 'shade' to darken\n * @param fraction - Amount (0-1). For tint: 0=no change, 1=white. For shade: 0=black, 1=no change.\n * @returns 6-character hex color (no #)\n */\nexport function getThemeTintShadeHex(\n baseHex: string,\n type: 'tint' | 'shade',\n fraction: number\n): string {\n if (type === 'tint') {\n return applyTint(baseHex, fraction);\n }\n return applyShade(baseHex, fraction);\n}\n\n/**\n * Generate the 10×6 theme color matrix for an advanced color picker.\n *\n * Columns: lt1, dk1, lt2, dk2, accent1-6 (matches Word's order)\n * Rows: base, 80% tint, 60% tint, 40% tint, 25% shade, 50% shade\n *\n * @param colorScheme - Theme color scheme (falls back to Office 2016 defaults)\n * @returns 6 rows × 10 columns of ThemeMatrixCell\n */\nexport function generateThemeTintShadeMatrix(\n colorScheme?: ThemeColorScheme | null\n): ThemeMatrixCell[][] {\n const scheme = colorScheme ?? DEFAULT_THEME_COLORS;\n\n return THEME_MATRIX_ROWS.map((row) => {\n return THEME_MATRIX_COLUMNS.map((col) => {\n const baseHex =\n scheme[col.slot as keyof ThemeColorScheme] ??\n DEFAULT_THEME_COLORS[col.slot as keyof ThemeColorScheme] ??\n '000000';\n\n let hex: string;\n if (row.type === 'base') {\n hex = baseHex.toUpperCase();\n } else if (row.type === 'tint') {\n hex = applyTint(baseHex, row.value);\n } else {\n hex = applyShade(baseHex, row.value);\n }\n\n const cell: ThemeMatrixCell = {\n hex,\n themeSlot: col.slot,\n label: `${col.name}${row.labelSuffix}`,\n };\n\n if (row.type === 'tint' && row.hexValue) {\n cell.tint = row.hexValue;\n } else if (row.type === 'shade' && row.hexValue) {\n cell.shade = row.hexValue;\n }\n\n return cell;\n });\n });\n}\n\n/**\n * Check if two colors are equal\n *\n * @param color1 - First color\n * @param color2 - Second color\n * @param theme - Theme for resolving\n * @returns True if colors resolve to the same value\n */\nexport function colorsEqual(\n color1: ColorValue | undefined | null,\n color2: ColorValue | undefined | null,\n theme: Theme | null | undefined\n): boolean {\n if (!color1 && !color2) return true;\n if (!color1 || !color2) return false;\n\n const resolved1 = resolveColor(color1, theme).toUpperCase();\n const resolved2 = resolveColor(color2, theme).toUpperCase();\n\n return resolved1 === resolved2;\n}\n","/**\n * Core Plugin System Types\n *\n * Defines the interfaces for headless plugins that work in Node.js\n * without React/DOM dependencies. These plugins extend DocumentAgent\n * with additional commands and expose MCP tools for AI integration.\n */\n\nimport type { Document } from '../types/document';\nimport type { AgentCommand, Position, Range } from '../types/agentApi';\n\n// ============================================================================\n// PLUGIN INTERFACE\n// ============================================================================\n\n/**\n * Core plugin interface - headless, works in Node.js\n *\n * Plugins can:\n * - Register command handlers that DocumentAgent dispatches to\n * - Declare MCP tools that the MCP server exposes to AI clients\n * - Have optional initialization logic\n * - Declare dependencies on other plugins\n */\nexport interface CorePlugin {\n /** Unique plugin identifier */\n id: string;\n\n /** Human-readable plugin name */\n name: string;\n\n /** Plugin version (semver) */\n version?: string;\n\n /** Plugin description */\n description?: string;\n\n /**\n * Command handlers this plugin provides.\n * DocumentAgent dispatches commands to these handlers.\n *\n * @example\n * ```ts\n * commandHandlers: {\n * 'insertTemplateVariable': (doc, cmd) => {\n * // Transform document\n * return modifiedDoc;\n * },\n * }\n * ```\n */\n commandHandlers?: Record<string, CommandHandler>;\n\n /**\n * MCP tools this plugin exposes.\n * MCP server collects these from all plugins.\n */\n mcpTools?: McpToolDefinition[];\n\n /**\n * Optional setup when plugin is registered.\n * Called once during plugin registration.\n */\n initialize?: () => void | Promise<void>;\n\n /**\n * Optional cleanup when plugin is unregistered.\n */\n destroy?: () => void | Promise<void>;\n\n /**\n * Dependencies on other plugins (by ID).\n * The registry ensures dependencies are loaded first.\n */\n dependencies?: string[];\n}\n\n// ============================================================================\n// COMMAND TYPES\n// ============================================================================\n\n/**\n * Command handler function type\n *\n * Receives a document and a command, returns a modified document.\n * Must be pure/immutable - always return a new document.\n */\nexport type CommandHandler = (doc: Document, command: PluginCommand) => Document;\n\n/**\n * Extended command type for plugins\n *\n * Plugins can define custom command types beyond the built-in AgentCommand types.\n */\nexport interface PluginCommand {\n /** Command type identifier */\n type: string;\n\n /** Unique command ID (for undo tracking) */\n id?: string;\n\n /** Position for positional commands */\n position?: Position;\n\n /** Range for range-based commands */\n range?: Range;\n\n /** Additional command-specific data */\n [key: string]: unknown;\n}\n\n/**\n * Result of command execution\n */\nexport interface CommandResult {\n /** The modified document */\n document: Document;\n\n /** Whether the command succeeded */\n success: boolean;\n\n /** Error message if failed */\n error?: string;\n\n /** Metadata about the operation */\n metadata?: Record<string, unknown>;\n}\n\n// ============================================================================\n// MCP TOOL TYPES\n// ============================================================================\n\n/**\n * MCP tool definition\n *\n * Describes a tool that can be called by AI clients through the MCP server.\n */\nexport interface McpToolDefinition {\n /** Tool name (used in MCP protocol) */\n name: string;\n\n /** Human-readable description for AI */\n description: string;\n\n /**\n * JSON Schema for tool input validation.\n * Can be a Zod schema or plain JSON Schema object.\n */\n inputSchema: JsonSchema | ZodSchemaLike;\n\n /**\n * Handler function for the tool.\n * Receives validated input and returns a result.\n */\n handler: McpToolHandler;\n\n /**\n * Optional annotations for the tool\n */\n annotations?: McpToolAnnotations;\n}\n\n/**\n * MCP tool handler function\n */\nexport type McpToolHandler = (\n input: unknown,\n context: McpToolContext\n) => Promise<McpToolResult> | McpToolResult;\n\n/**\n * Context passed to MCP tool handlers\n */\nexport interface McpToolContext {\n /** Current document (if loaded) */\n document?: Document;\n\n /** Document buffer (if loaded) */\n documentBuffer?: ArrayBuffer;\n\n /** Session state */\n session: McpSession;\n\n /** Logger for debugging */\n log: (message: string, data?: unknown) => void;\n}\n\n/**\n * MCP session state\n *\n * Maintains state across tool calls within a session.\n */\nexport interface McpSession {\n /** Session ID */\n id: string;\n\n /** Loaded documents by ID */\n documents: Map<string, LoadedDocument>;\n\n /** Custom session data */\n data: Map<string, unknown>;\n}\n\n/**\n * A loaded document in the session\n */\nexport interface LoadedDocument {\n /** Document ID */\n id: string;\n\n /** Parsed document */\n document: Document;\n\n /** Original buffer (for repacking) */\n buffer?: ArrayBuffer;\n\n /** Source filename or path */\n source?: string;\n\n /** Last modified timestamp */\n lastModified: number;\n}\n\n/**\n * MCP tool result\n */\nexport interface McpToolResult {\n /** Result content */\n content: McpToolContent[];\n\n /** Whether this is an error result */\n isError?: boolean;\n}\n\n/**\n * MCP tool content types\n */\nexport type McpToolContent =\n | { type: 'text'; text: string }\n | { type: 'image'; data: string; mimeType: string }\n | { type: 'resource'; uri: string; mimeType?: string; text?: string };\n\n/**\n * MCP tool annotations\n */\nexport interface McpToolAnnotations {\n /** Tool category for organization */\n category?: string;\n\n /** Whether this tool modifies the document */\n readOnly?: boolean;\n\n /** Estimated cost/complexity */\n complexity?: 'low' | 'medium' | 'high';\n\n /** Example usage */\n examples?: McpToolExample[];\n}\n\n/**\n * MCP tool example\n */\nexport interface McpToolExample {\n /** Example description */\n description: string;\n\n /** Example input */\n input: unknown;\n\n /** Expected output description */\n output?: string;\n}\n\n// ============================================================================\n// JSON SCHEMA TYPES\n// ============================================================================\n\n/**\n * JSON Schema definition (subset)\n */\nexport interface JsonSchema {\n type?: string | string[];\n properties?: Record<string, JsonSchema>;\n items?: JsonSchema;\n required?: string[];\n description?: string;\n enum?: unknown[];\n default?: unknown;\n minimum?: number;\n maximum?: number;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n format?: string;\n additionalProperties?: boolean | JsonSchema;\n anyOf?: JsonSchema[];\n oneOf?: JsonSchema[];\n allOf?: JsonSchema[];\n $ref?: string;\n}\n\n/**\n * Zod-like schema interface for compatibility\n */\nexport interface ZodSchemaLike {\n _def?: unknown;\n parse?: (data: unknown) => unknown;\n safeParse?: (data: unknown) => { success: boolean; data?: unknown; error?: unknown };\n}\n\n/**\n * Check if a schema is Zod-like\n */\nexport function isZodSchema(schema: unknown): schema is ZodSchemaLike {\n return (\n typeof schema === 'object' &&\n schema !== null &&\n ('_def' in schema || 'parse' in schema || 'safeParse' in schema)\n );\n}\n\n// ============================================================================\n// PLUGIN EVENTS\n// ============================================================================\n\n/**\n * Plugin lifecycle events\n */\nexport type PluginEvent =\n | { type: 'registered'; plugin: CorePlugin }\n | { type: 'unregistered'; pluginId: string }\n | { type: 'error'; pluginId: string; error: Error };\n\n/**\n * Plugin event listener\n */\nexport type PluginEventListener = (event: PluginEvent) => void;\n\n// ============================================================================\n// UTILITY TYPES\n// ============================================================================\n\n/**\n * Extract command type from a union\n */\nexport type ExtractCommand<T extends AgentCommand, Type extends string> = T extends { type: Type }\n ? T\n : never;\n\n/**\n * Create a typed command handler\n */\nexport type TypedCommandHandler<T extends PluginCommand> = (doc: Document, command: T) => Document;\n\n/**\n * Plugin configuration options\n */\nexport interface PluginOptions {\n /** Enable debug logging */\n debug?: boolean;\n\n /** Custom configuration */\n config?: Record<string, unknown>;\n}\n\n/**\n * Result of plugin registration\n */\nexport interface PluginRegistrationResult {\n /** Whether registration succeeded */\n success: boolean;\n\n /** Registered plugin (if successful) */\n plugin?: CorePlugin;\n\n /** Error message (if failed) */\n error?: string;\n\n /** Warning messages */\n warnings?: string[];\n}\n\n// ============================================================================\n// EXPORTS\n// ============================================================================\n\nexport type {\n CorePlugin as Plugin,\n CommandHandler as PluginCommandHandler,\n McpToolDefinition as ToolDefinition,\n McpToolHandler as ToolHandler,\n McpToolResult as ToolResult,\n};\n","/**\n * Agent API Types\n *\n * TypeScript interfaces for the agent API:\n * - Position and Range types\n * - Command types for document manipulation\n * - Context types for AI agents\n */\n\nimport type { TextFormatting, ParagraphFormatting } from './document';\n\n// ============================================================================\n// POSITION & RANGE\n// ============================================================================\n\n/**\n * Position within a document\n */\nexport interface Position {\n /** Index of the paragraph (0-indexed) */\n paragraphIndex: number;\n /** Offset within the paragraph in characters */\n offset: number;\n /** Optional: Content index within paragraph (run, hyperlink, etc.) */\n contentIndex?: number;\n /** Optional: Section index */\n sectionIndex?: number;\n}\n\n/**\n * Range within a document\n */\nexport interface Range {\n /** Start position */\n start: Position;\n /** End position */\n end: Position;\n /** Whether the range is collapsed (cursor position) */\n collapsed?: boolean;\n}\n\n/**\n * Create a collapsed range (cursor) at a position\n */\nexport function createCollapsedRange(position: Position): Range {\n return {\n start: position,\n end: position,\n collapsed: true,\n };\n}\n\n/**\n * Create a range from two positions\n */\nexport function createRange(start: Position, end: Position): Range {\n return {\n start,\n end,\n collapsed: start.paragraphIndex === end.paragraphIndex && start.offset === end.offset,\n };\n}\n\n/**\n * Check if a position is within a range\n */\nexport function isPositionInRange(position: Position, range: Range): boolean {\n // Before range start\n if (\n position.paragraphIndex < range.start.paragraphIndex ||\n (position.paragraphIndex === range.start.paragraphIndex && position.offset < range.start.offset)\n ) {\n return false;\n }\n\n // After range end\n if (\n position.paragraphIndex > range.end.paragraphIndex ||\n (position.paragraphIndex === range.end.paragraphIndex && position.offset > range.end.offset)\n ) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Compare two positions\n * Returns: -1 if a < b, 0 if equal, 1 if a > b\n */\nexport function comparePositions(a: Position, b: Position): -1 | 0 | 1 {\n if (a.paragraphIndex < b.paragraphIndex) return -1;\n if (a.paragraphIndex > b.paragraphIndex) return 1;\n if (a.offset < b.offset) return -1;\n if (a.offset > b.offset) return 1;\n return 0;\n}\n\n// ============================================================================\n// COMMANDS\n// ============================================================================\n\n/**\n * Base command interface\n */\nexport interface BaseCommand {\n /** Command type */\n type: string;\n /** Unique command ID (for undo tracking) */\n id?: string;\n}\n\n/**\n * Insert text at a position\n */\nexport interface InsertTextCommand extends BaseCommand {\n type: 'insertText';\n /** Position to insert at */\n position: Position;\n /** Text to insert */\n text: string;\n /** Optional formatting for the inserted text */\n formatting?: TextFormatting;\n}\n\n/**\n * Replace text in a range\n */\nexport interface ReplaceTextCommand extends BaseCommand {\n type: 'replaceText';\n /** Range to replace */\n range: Range;\n /** Replacement text */\n text: string;\n /** Optional formatting for the new text */\n formatting?: TextFormatting;\n}\n\n/**\n * Delete text in a range\n */\nexport interface DeleteTextCommand extends BaseCommand {\n type: 'deleteText';\n /** Range to delete */\n range: Range;\n}\n\n/**\n * Apply formatting to a range\n */\nexport interface FormatTextCommand extends BaseCommand {\n type: 'formatText';\n /** Range to format */\n range: Range;\n /** Formatting to apply */\n formatting: Partial<TextFormatting>;\n}\n\n/**\n * Apply paragraph formatting\n */\nexport interface FormatParagraphCommand extends BaseCommand {\n type: 'formatParagraph';\n /** Paragraph index */\n paragraphIndex: number;\n /** Formatting to apply */\n formatting: Partial<ParagraphFormatting>;\n}\n\n/**\n * Apply a named style to a paragraph\n */\nexport interface ApplyStyleCommand extends BaseCommand {\n type: 'applyStyle';\n /** Paragraph index */\n paragraphIndex: number;\n /** Style ID to apply */\n styleId: string;\n}\n\n/**\n * Insert a table at a position\n */\nexport interface InsertTableCommand extends BaseCommand {\n type: 'insertTable';\n /** Position to insert at */\n position: Position;\n /** Number of rows */\n rows: number;\n /** Number of columns */\n columns: number;\n /** Optional table data */\n data?: string[][];\n /** Optional header row */\n hasHeader?: boolean;\n}\n\n/**\n * Insert an image at a position\n */\nexport interface InsertImageCommand extends BaseCommand {\n type: 'insertImage';\n /** Position to insert at */\n position: Position;\n /** Image source (base64 or URL) */\n src: string;\n /** Image width in pixels */\n width?: number;\n /** Image height in pixels */\n height?: number;\n /** Alt text */\n alt?: string;\n}\n\n/**\n * Insert a hyperlink at a range\n */\nexport interface InsertHyperlinkCommand extends BaseCommand {\n type: 'insertHyperlink';\n /** Range to make into a hyperlink */\n range: Range;\n /** URL of the hyperlink */\n url: string;\n /** Display text (replaces range text if provided) */\n displayText?: string;\n /** Tooltip */\n tooltip?: string;\n}\n\n/**\n * Remove a hyperlink but keep the text\n */\nexport interface RemoveHyperlinkCommand extends BaseCommand {\n type: 'removeHyperlink';\n /** Range containing the hyperlink */\n range: Range;\n}\n\n/**\n * Insert a paragraph break\n */\nexport interface InsertParagraphBreakCommand extends BaseCommand {\n type: 'insertParagraphBreak';\n /** Position to break at */\n position: Position;\n}\n\n/**\n * Merge paragraphs\n */\nexport interface MergeParagraphsCommand extends BaseCommand {\n type: 'mergeParagraphs';\n /** First paragraph index */\n paragraphIndex: number;\n /** Number of paragraphs to merge with */\n count: number;\n}\n\n/**\n * Split a paragraph\n */\nexport interface SplitParagraphCommand extends BaseCommand {\n type: 'splitParagraph';\n /** Position to split at */\n position: Position;\n}\n\n/**\n * Set template variable value\n */\nexport interface SetVariableCommand extends BaseCommand {\n type: 'setVariable';\n /** Variable name */\n name: string;\n /** Variable value */\n value: string;\n}\n\n/**\n * Apply all template variables\n */\nexport interface ApplyVariablesCommand extends BaseCommand {\n type: 'applyVariables';\n /** Variable values */\n values: Record<string, string>;\n}\n\n/**\n * Union of all command types\n */\nexport type AgentCommand =\n | InsertTextCommand\n | ReplaceTextCommand\n | DeleteTextCommand\n | FormatTextCommand\n | FormatParagraphCommand\n | ApplyStyleCommand\n | InsertTableCommand\n | InsertImageCommand\n | InsertHyperlinkCommand\n | RemoveHyperlinkCommand\n | InsertParagraphBreakCommand\n | MergeParagraphsCommand\n | SplitParagraphCommand\n | SetVariableCommand\n | ApplyVariablesCommand;\n\n/**\n * Get command type\n */\nexport type CommandType = AgentCommand['type'];\n\n// ============================================================================\n// CONTEXT\n// ============================================================================\n\n/**\n * Document context for AI agents\n */\nexport interface AgentContext {\n /** Total paragraph count */\n paragraphCount: number;\n /** Total word count (approximate) */\n wordCount: number;\n /** Total character count */\n characterCount: number;\n /** Detected template variables */\n variables: string[];\n /** Variable count */\n variableCount: number;\n /** Available styles */\n availableStyles: StyleInfo[];\n /** Content outline (first N chars per paragraph) */\n outline: ParagraphOutline[];\n /** Document sections info */\n sections: SectionInfo[];\n /** Has tables */\n hasTables: boolean;\n /** Has images */\n hasImages: boolean;\n /** Has hyperlinks */\n hasHyperlinks: boolean;\n /** Document language */\n language?: string;\n}\n\n/**\n * Style information for context\n */\nexport interface StyleInfo {\n /** Style ID */\n id: string;\n /** Display name */\n name: string;\n /** Style type */\n type: 'paragraph' | 'character' | 'table';\n /** Is built-in style */\n builtIn?: boolean;\n}\n\n/**\n * Paragraph outline for context\n */\nexport interface ParagraphOutline {\n /** Paragraph index */\n index: number;\n /** First N characters */\n preview: string;\n /** Paragraph style */\n style?: string;\n /** Is heading */\n isHeading?: boolean;\n /** Heading level (1-9) */\n headingLevel?: number;\n /** Is list item */\n isListItem?: boolean;\n /** Is empty paragraph */\n isEmpty?: boolean;\n}\n\n/**\n * Section information\n */\nexport interface SectionInfo {\n /** Section index */\n index: number;\n /** Number of paragraphs */\n paragraphCount: number;\n /** Page size */\n pageSize?: { width: number; height: number };\n /** Is landscape */\n isLandscape?: boolean;\n /** Has header */\n hasHeader?: boolean;\n /** Has footer */\n hasFooter?: boolean;\n}\n\n// ============================================================================\n// SELECTION CONTEXT\n// ============================================================================\n\n/**\n * Context about the current selection\n */\nexport interface SelectionContext {\n /** Selected text */\n selectedText: string;\n /** Selection range */\n range: Range;\n /** Current formatting of selection */\n formatting: Partial<TextFormatting>;\n /** Current paragraph formatting */\n paragraphFormatting: Partial<ParagraphFormatting>;\n /** Text before selection (context) */\n textBefore: string;\n /** Text after selection (context) */\n textAfter: string;\n /** Paragraph containing selection */\n paragraph: ParagraphContext;\n /** Is selection within a table */\n inTable?: boolean;\n /** Is selection within a hyperlink */\n inHyperlink?: boolean;\n /** Suggested actions based on selection */\n suggestedActions?: SuggestedAction[];\n}\n\n/**\n * Paragraph context for selection\n */\nexport interface ParagraphContext {\n /** Paragraph index */\n index: number;\n /** Full paragraph text */\n fullText: string;\n /** Paragraph style */\n style?: string;\n /** Word count */\n wordCount: number;\n}\n\n/**\n * Suggested action for context menu\n */\nexport interface SuggestedAction {\n /** Action ID */\n id: string;\n /** Display label */\n label: string;\n /** Description */\n description?: string;\n /** Icon name */\n icon?: string;\n /** Priority (higher = more prominent) */\n priority?: number;\n}\n\n// ============================================================================\n// RESPONSE\n// ============================================================================\n\n/**\n * Response from an agent action\n */\nexport interface AgentResponse {\n /** Success status */\n success: boolean;\n /** New text to insert (for rewrite/expand/etc.) */\n newText?: string;\n /** New formatted content */\n newContent?: AgentContent[];\n /** Commands to execute */\n commands?: AgentCommand[];\n /** Error message if failed */\n error?: string;\n /** Warning messages */\n warnings?: string[];\n /** Metadata about the response */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Content block in agent response\n */\nexport interface AgentContent {\n /** Content type */\n type: 'text' | 'paragraph' | 'table' | 'image';\n /** Text content */\n text?: string;\n /** Formatting */\n formatting?: Partial<TextFormatting>;\n /** Paragraph formatting */\n paragraphFormatting?: Partial<ParagraphFormatting>;\n /** Table data (for table type) */\n tableData?: string[][];\n /** Image src (for image type) */\n imageSrc?: string;\n}\n\n// ============================================================================\n// AI ACTIONS\n// ============================================================================\n\n/**\n * AI action types for context menu\n */\nexport type AIAction =\n | 'askAI'\n | 'rewrite'\n | 'expand'\n | 'summarize'\n | 'translate'\n | 'explain'\n | 'fixGrammar'\n | 'makeFormal'\n | 'makeCasual'\n | 'custom';\n\n/**\n * AI action request\n */\nexport interface AIActionRequest {\n /** Action type */\n action: AIAction;\n /** Selection context */\n context: SelectionContext;\n /** Custom prompt (for 'custom' action) */\n customPrompt?: string;\n /** Target language (for 'translate' action) */\n targetLanguage?: string;\n /** Additional options */\n options?: Record<string, unknown>;\n}\n\n/**\n * Get action label\n */\nexport function getActionLabel(action: AIAction): string {\n const labels: Record<AIAction, string> = {\n askAI: 'Ask AI',\n rewrite: 'Rewrite',\n expand: 'Expand',\n summarize: 'Summarize',\n translate: 'Translate',\n explain: 'Explain',\n fixGrammar: 'Fix Grammar',\n makeFormal: 'Make Formal',\n makeCasual: 'Make Casual',\n custom: 'Custom Prompt',\n };\n return labels[action];\n}\n\n/**\n * Get action description\n */\nexport function getActionDescription(action: AIAction): string {\n const descriptions: Record<AIAction, string> = {\n askAI: 'Ask AI a question about this text',\n rewrite: 'Rewrite this text in a different way',\n expand: 'Expand this text with more details',\n summarize: 'Summarize this text to be shorter',\n translate: 'Translate this text to another language',\n explain: 'Explain what this text means',\n fixGrammar: 'Fix grammar and spelling errors',\n makeFormal: 'Make the tone more formal',\n makeCasual: 'Make the tone more casual',\n custom: 'Enter a custom prompt',\n };\n return descriptions[action];\n}\n\n/**\n * Default AI actions for context menu\n */\nexport const DEFAULT_AI_ACTIONS: AIAction[] = [\n 'askAI',\n 'rewrite',\n 'expand',\n 'summarize',\n 'translate',\n 'explain',\n];\n\n// ============================================================================\n// UTILITY TYPES\n// ============================================================================\n\n/**\n * Command handler function type\n */\nexport type CommandHandler<T extends AgentCommand = AgentCommand> = (\n command: T\n) => Promise<boolean>;\n\n/**\n * AI request handler function type\n */\nexport type AIRequestHandler = (request: AIActionRequest) => Promise<AgentResponse>;\n\n/**\n * Create a command with generated ID\n */\nexport function createCommand<T extends AgentCommand>(command: Omit<T, 'id'>): T {\n return {\n ...command,\n id: generateCommandId(),\n } as T;\n}\n\n/**\n * Generate a unique command ID\n */\nfunction generateCommandId(): string {\n return `cmd_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n}\n\nexport default {\n createCollapsedRange,\n createRange,\n isPositionInRange,\n comparePositions,\n getActionLabel,\n getActionDescription,\n createCommand,\n DEFAULT_AI_ACTIONS,\n};\n","/**\n * Headless API Entry Point\n *\n * Provides document manipulation functionality without React/DOM dependencies.\n * Suitable for Node.js scripts, CLI tools, and server-side processing.\n *\n * @example\n * ```ts\n * import { DocumentAgent, parseDocx, pluginRegistry } from '@eigenpal/docx-editor/headless';\n * import { docxtemplaterPlugin } from '@eigenpal/docx-editor/core-plugins';\n *\n * // Register plugins\n * pluginRegistry.register(docxtemplaterPlugin);\n *\n * // Load and manipulate document\n * const buffer = fs.readFileSync('template.docx');\n * const agent = await DocumentAgent.fromBuffer(buffer);\n *\n * // Get document info\n * console.log('Word count:', agent.getWordCount());\n * console.log('Variables:', agent.getVariables());\n *\n * // Edit document\n * const newAgent = agent\n * .insertText({ paragraphIndex: 0, offset: 0 }, 'Hello ')\n * .applyStyle(0, 'Heading1');\n *\n * // Apply template variables\n * const finalAgent = await newAgent.applyVariables({\n * customer_name: 'Jane Doe',\n * date: '2024-02-15',\n * });\n *\n * // Export\n * const output = await finalAgent.toBuffer();\n * fs.writeFileSync('output.docx', Buffer.from(output));\n * ```\n */\n\n// ============================================================================\n// VERSION\n// ============================================================================\n\nexport const VERSION = '0.0.2';\n\n// ============================================================================\n// DOCUMENT AGENT\n// ============================================================================\n\nexport { DocumentAgent, createAgent, createAgentFromDocument } from './agent/DocumentAgent';\nexport type {\n InsertTextOptions,\n InsertTableOptions,\n InsertImageOptions,\n InsertHyperlinkOptions,\n FormattedTextSegment,\n} from './agent/DocumentAgent';\n\n// ============================================================================\n// COMMAND EXECUTION\n// ============================================================================\n\nexport { executeCommand, executeCommands } from './agent/executor';\n\n// ============================================================================\n// CONTEXT BUILDERS\n// ============================================================================\n\nexport {\n getAgentContext,\n getDocumentSummary,\n buildSelectionContext as buildSelectionContextFromContext,\n type AgentContextOptions,\n type SelectionContextOptions as ContextSelectionOptions,\n} from './agent/context';\n\nexport {\n buildSelectionContext,\n buildExtendedSelectionContext,\n getSelectionFormattingSummary,\n type SelectionContextOptions,\n type ExtendedSelectionContext,\n type FormattingSummary,\n} from './agent/selectionContext';\n\n// ============================================================================\n// TEXT UTILITIES\n// ============================================================================\n\nexport {\n getParagraphText,\n getRunText,\n getHyperlinkText,\n getTableText,\n getBodyText,\n countWords,\n countCharacters,\n getBodyWordCount,\n getBodyCharacterCount,\n getTextBefore,\n getTextAfter,\n getFormattingAtPosition,\n isPositionInHyperlink,\n getHyperlinkAtPosition,\n isHeadingStyle,\n parseHeadingLevel,\n hasImages,\n hasHyperlinks,\n hasTables,\n getParagraphs,\n getParagraphAtIndex,\n getBlockIndexForParagraph,\n} from './agent/text-utils';\n\n// ============================================================================\n// PARSER / SERIALIZER\n// ============================================================================\n\nexport { parseDocx } from './docx/parser';\nexport {\n serializeDocument as serializeDocx,\n serializeDocumentBody,\n serializeSectionProperties,\n} from './docx/serializer/documentSerializer';\nexport { repackDocx, createDocx, updateMultipleFiles } from './docx/rezip';\nexport { attemptSelectiveSave } from './docx/selectiveSave';\nexport { buildPatchedDocumentXml, validatePatchSafety } from './docx/selectiveXmlPatch';\n\n// ============================================================================\n// TEMPLATE PROCESSING\n// ============================================================================\n\nexport {\n processTemplate,\n processTemplateDetailed,\n processTemplateAsBlob,\n processTemplateAdvanced,\n getTemplateTags,\n validateTemplate,\n getMissingVariables,\n previewTemplate,\n createTemplateProcessor,\n type ProcessTemplateOptions,\n type ProcessTemplateResult,\n type TemplateError,\n} from './utils/processTemplate';\n\n// ============================================================================\n// VARIABLE DETECTION\n// ============================================================================\n\nexport {\n detectVariables,\n detectVariablesDetailed,\n detectVariablesInBody,\n detectVariablesInParagraph,\n extractVariablesFromText,\n hasTemplateVariables,\n isValidVariableName,\n sanitizeVariableName,\n formatVariable,\n parseVariable,\n replaceVariables,\n removeVariables,\n documentHasVariables,\n type VariableDetectionResult,\n type VariableOccurrence,\n} from './utils/variableDetector';\n\n// ============================================================================\n// DOCUMENT CREATION\n// ============================================================================\n\nexport {\n createEmptyDocument,\n createDocumentWithText,\n type CreateEmptyDocumentOptions,\n} from './utils/createDocument';\n\n// ============================================================================\n// UTILITIES\n// ============================================================================\n\nexport {\n twipsToPixels,\n pixelsToTwips,\n formatPx,\n emuToPixels,\n pointsToPixels,\n halfPointsToPixels,\n pixelsToEmu,\n emuToTwips,\n twipsToEmu,\n} from './utils/units';\n\nexport {\n resolveColor,\n resolveHighlightColor,\n resolveShadingColor,\n parseColorString,\n createThemeColor,\n createRgbColor,\n darkenColor,\n lightenColor,\n blendColors,\n getContrastingColor,\n isBlack,\n isWhite,\n colorsEqual,\n} from './utils/colorResolver';\n\n// ============================================================================\n// PLUGIN SYSTEM\n// ============================================================================\n\nexport {\n pluginRegistry,\n PluginRegistry,\n registerPlugins,\n createPluginRegistrar,\n isZodSchema,\n type CorePlugin,\n type Plugin,\n type PluginCommand,\n type CommandHandler,\n type PluginCommandHandler,\n type CommandResult,\n type PluginOptions,\n type PluginRegistrationResult,\n type McpToolDefinition,\n type ToolDefinition,\n type McpToolHandler,\n type ToolHandler,\n type McpToolResult,\n type ToolResult,\n type McpToolContent,\n type McpToolContext,\n type McpToolAnnotations,\n type McpSession,\n type LoadedDocument,\n type JsonSchema,\n type ZodSchemaLike,\n type PluginEvent,\n type PluginEventListener,\n} from './core-plugins';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\n// Document types\nexport type {\n Document,\n DocxPackage,\n DocumentBody,\n BlockContent,\n Paragraph,\n ParagraphContent,\n Run,\n RunContent,\n TextContent,\n Table,\n TableRow,\n TableCell,\n Image,\n Hyperlink,\n Theme,\n Style,\n StyleDefinitions,\n TextFormatting,\n ParagraphFormatting,\n SectionProperties,\n Footnote,\n Endnote,\n ListLevel,\n NumberingDefinitions,\n Relationship,\n // Track changes & comments\n Comment,\n CommentRangeStart,\n CommentRangeEnd,\n TrackedChangeInfo,\n TrackedRunChange,\n Insertion,\n Deletion,\n MoveFrom,\n MoveTo,\n} from './types/document';\n\n// Agent API types\nexport type {\n AIAction,\n AIActionRequest,\n AgentResponse,\n AgentContext,\n SelectionContext,\n Range,\n Position,\n ParagraphContext,\n ParagraphOutline,\n SectionInfo,\n StyleInfo,\n SuggestedAction,\n AgentCommand,\n InsertTextCommand,\n ReplaceTextCommand,\n DeleteTextCommand,\n FormatTextCommand,\n FormatParagraphCommand,\n InsertTableCommand,\n InsertImageCommand,\n InsertHyperlinkCommand,\n SetVariableCommand,\n ApplyStyleCommand,\n ApplyVariablesCommand,\n} from './types/agentApi';\n\n// API functions\nexport {\n createCollapsedRange,\n createRange,\n isPositionInRange,\n comparePositions,\n getActionLabel,\n getActionDescription,\n createCommand,\n DEFAULT_AI_ACTIONS,\n} from './types/agentApi';\n"]}