@forevka/wordcanvas 0.7.0 → 0.7.2

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 (66) hide show
  1. package/README.md +48 -1
  2. package/dist-lib/assets/{worker-BsOsK39A.js → worker-4HYrkNrG.js} +12276 -11981
  3. package/dist-lib/assets/worker-CJpwUzKh.js +2403 -0
  4. package/dist-lib/blockFactory-B_CLnkUh.js +106 -0
  5. package/dist-lib/browser-p_rkUcqE.js +1339 -0
  6. package/dist-lib/builder.js +365 -109
  7. package/dist-lib/editorApp-mTD0YNv-.js +9863 -0
  8. package/dist-lib/export.js +4670 -4567
  9. package/dist-lib/generate-toc.js +5 -5
  10. package/dist-lib/import.js +4 -1538
  11. package/dist-lib/{lists-BegzmTmD.js → lists-Sc5I40JO.js} +2 -2
  12. package/dist-lib/measure.js +2 -2
  13. package/dist-lib/{measureHost-CMiJKdlk.js → measureHost-B2aKX7lF.js} +1 -1
  14. package/dist-lib/metrics-BUMIC9Mv.js +164 -0
  15. package/dist-lib/pipeline-DD0nxAYM.js +1850 -0
  16. package/dist-lib/recalc-docx.js +2 -2
  17. package/dist-lib/recalcToc-CFCGCgij.js +3985 -0
  18. package/dist-lib/styleProps-DhqDEfvc.js +149 -0
  19. package/dist-lib/stylesheet-B6oczA-L.js +141 -0
  20. package/dist-lib/toc-Dj57zdz-.js +213 -0
  21. package/dist-lib/{webmcp-B7Gvd58E.js → webmcp-CXghUon_.js} +2 -2
  22. package/dist-lib/{wordcanvas-BAxBeErX.js → wordcanvas-D5DI9ZR1.js} +49 -23
  23. package/dist-lib/wordcanvas.js +1 -1
  24. package/dist-node/{chunk-GXFDF7UY.js → chunk-57L5XMCL.js} +327 -59
  25. package/dist-node/chunk-57L5XMCL.js.map +7 -0
  26. package/dist-node/{chunk-TBSXA2I4.js → chunk-EGSAVPCC.js} +1 -1
  27. package/dist-node/chunk-EGSAVPCC.js.map +7 -0
  28. package/dist-node/{chunk-4PDVRJF6.js → chunk-EMY2P524.js} +32 -2
  29. package/dist-node/chunk-EMY2P524.js.map +7 -0
  30. package/dist-node/{chunk-2RCPB7UZ.js → chunk-KJV7GJ3H.js} +1 -1
  31. package/dist-node/chunk-KJV7GJ3H.js.map +7 -0
  32. package/dist-node/{chunk-XDUDPPJW.js → chunk-PIMVQULL.js} +93 -24
  33. package/dist-node/chunk-PIMVQULL.js.map +7 -0
  34. package/dist-node/{chunk-BRAPV465.js → chunk-SA26UVIJ.js} +2 -2
  35. package/dist-node/{chunk-IJLL6IFJ.js → chunk-T3253N22.js} +202 -13
  36. package/dist-node/{chunk-IJLL6IFJ.js.map → chunk-T3253N22.js.map} +2 -2
  37. package/dist-node/{chunk-4ICCHZX4.js → chunk-U27EBKBG.js} +37 -1
  38. package/dist-node/chunk-U27EBKBG.js.map +7 -0
  39. package/dist-node/{engine-FRCX7PXF.js → engine-5F7DUU4W.js} +4 -4
  40. package/dist-node/export.js +178 -52
  41. package/dist-node/export.js.map +2 -2
  42. package/dist-node/generate-toc.js +7 -7
  43. package/dist-node/import.js +3 -3
  44. package/dist-node/measure.js +2 -2
  45. package/dist-node/recalc-docx.js +5 -5
  46. package/dist-node/recalc-docx.js.map +1 -1
  47. package/package.json +1 -1
  48. package/types/model.d.ts +277 -225
  49. package/types/recalc-docx.d.ts +27 -27
  50. package/types/wordcanvas.d.ts +212 -157
  51. package/dist-lib/assets/worker-BbFAIxdy.js +0 -2163
  52. package/dist-lib/blockFactory-Bcy0U40y.js +0 -178
  53. package/dist-lib/browser-5Sv4CuNy.js +0 -1284
  54. package/dist-lib/editorApp-DvjFPHiy.js +0 -7582
  55. package/dist-lib/metrics-CkAo4zh8.js +0 -143
  56. package/dist-lib/recalcToc-uaLWt59L.js +0 -3835
  57. package/dist-lib/styleProps-Db5pEkG8.js +0 -127
  58. package/dist-lib/toc-CZel_Kk3.js +0 -127
  59. package/dist-node/chunk-2RCPB7UZ.js.map +0 -7
  60. package/dist-node/chunk-4ICCHZX4.js.map +0 -7
  61. package/dist-node/chunk-4PDVRJF6.js.map +0 -7
  62. package/dist-node/chunk-GXFDF7UY.js.map +0 -7
  63. package/dist-node/chunk-TBSXA2I4.js.map +0 -7
  64. package/dist-node/chunk-XDUDPPJW.js.map +0 -7
  65. /package/dist-node/{chunk-BRAPV465.js.map → chunk-SA26UVIJ.js.map} +0 -0
  66. /package/dist-node/{engine-FRCX7PXF.js.map → engine-5F7DUU4W.js.map} +0 -0
@@ -77,6 +77,7 @@ var hexColor = (c) => c.replace(/^#/, "").toLowerCase();
77
77
  function runPropsXml(s) {
78
78
  const family = (s.fontFamily.split(",")[0] ?? "").trim();
79
79
  const children = [];
80
+ if (s.charStyleId) children.push(el("w:rStyle", { "w:val": s.charStyleId }));
80
81
  if (family) children.push(el("w:rFonts", { "w:ascii": family, "w:hAnsi": family, "w:cs": family }));
81
82
  children.push(el("w:b", { "w:val": s.bold ? "1" : "0" }));
82
83
  children.push(el("w:i", { "w:val": s.italic ? "1" : "0" }));
@@ -177,6 +178,34 @@ function partialPPrXml(p) {
177
178
  }
178
179
  return out.length > 0 ? el("w:pPr", void 0, out.join("")) : "";
179
180
  }
181
+ function condBordersXml(tag, b) {
182
+ const edge = (name, spec) => {
183
+ if (!spec) return "";
184
+ const val = spec.style === "double" ? "double" : spec.style === "dashed" ? "dashed" : spec.style === "dotted" ? "dotted" : "single";
185
+ return el("w:" + name, { "w:val": val, "w:sz": pxToEighthPoints(spec.widthPx), "w:space": 0, "w:color": hexColor(spec.color) });
186
+ };
187
+ return el(tag, void 0, edge("top", b.top) + edge("left", b.left) + edge("bottom", b.bottom) + edge("right", b.right));
188
+ }
189
+ var shdFillXml = (fill) => el("w:shd", { "w:val": "clear", "w:color": "auto", "w:fill": hexColor(fill) });
190
+ function tblStylePrXml(cond, props) {
191
+ const tc = [];
192
+ if (props.borders) tc.push(condBordersXml("w:tcBorders", props.borders));
193
+ if (props.shading) tc.push(shdFillXml(props.shading));
194
+ const tcPr = tc.length > 0 ? el("w:tcPr", void 0, tc.join("")) : "";
195
+ return el("w:tblStylePr", { "w:type": cond }, partialRPrXml(props.char ?? {}) + partialPPrXml(props.para ?? {}) + tcPr);
196
+ }
197
+ function tableStyleXml(style) {
198
+ const base = style.conds.wholeTable ?? {};
199
+ const tblPrKids = [];
200
+ if (style.rowBandSize !== void 0) tblPrKids.push(el("w:tblStyleRowBandSize", { "w:val": style.rowBandSize }));
201
+ if (style.colBandSize !== void 0) tblPrKids.push(el("w:tblStyleColBandSize", { "w:val": style.colBandSize }));
202
+ if (base.borders) tblPrKids.push(condBordersXml("w:tblBorders", base.borders));
203
+ if (base.shading) tblPrKids.push(shdFillXml(base.shading));
204
+ const tblPr = tblPrKids.length > 0 ? el("w:tblPr", void 0, tblPrKids.join("")) : "";
205
+ const conds = Object.entries(style.conds).filter(([c]) => c !== "wholeTable").map(([c, p]) => tblStylePrXml(c, p)).join("");
206
+ const body = el("w:name", { "w:val": style.name }) + (style.basedOn ? el("w:basedOn", { "w:val": style.basedOn }) : "") + partialRPrXml(base.char ?? {}) + partialPPrXml(base.para ?? {}) + tblPr + conds;
207
+ return el("w:style", { "w:type": "table", "w:styleId": style.id }, body);
208
+ }
180
209
 
181
210
  export {
182
211
  pxToTwips,
@@ -191,6 +220,7 @@ export {
191
220
  runPropsXml,
192
221
  paraCoreXml,
193
222
  partialRPrXml,
194
- partialPPrXml
223
+ partialPPrXml,
224
+ tableStyleXml
195
225
  };
196
- //# sourceMappingURL=chunk-4PDVRJF6.js.map
226
+ //# sourceMappingURL=chunk-EMY2P524.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/export/docx/xmlWrite.ts", "../src/export/units.ts", "../src/export/docx/mappings.ts", "../src/export/docx/styleProps.ts"],
4
+ "sourcesContent": ["// Minimal, dependency-free XML string emitter for OOXML parts. Attribute order is\n// insertion order (Word doesn't care); empty children collapse to self-closing.\n\nexport type Attrs = Record<string, string | number | boolean | undefined>;\n\nexport function escapeText(s: string): string {\n return s.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n\nfunction escapeAttr(s: string): string {\n return escapeText(s).replace(/\"/g, \"&quot;\");\n}\n\nfunction serializeAttrs(attrs: Attrs | undefined): string {\n if (!attrs) return \"\";\n let out = \"\";\n for (const [k, v] of Object.entries(attrs)) {\n if (v === undefined || v === false) continue;\n out += ` ${k}=\"${escapeAttr(String(v))}\"`;\n }\n return out;\n}\n\n/** An element. `children` is pre-serialized XML (caller joins arrays). Pass \"\"\n * or undefined for an empty element (self-closing). */\nexport function el(tag: string, attrs?: Attrs, children?: string): string {\n const a = serializeAttrs(attrs);\n if (children === undefined || children === \"\") return `<${tag}${a}/>`;\n return `<${tag}${a}>${children}</${tag}>`;\n}\n\n/** A w:t, preserving leading/trailing whitespace when present. */\nexport function textEl(text: string): string {\n const needsPreserve = /^\\s|\\s$|\\s\\s/.test(text) || text.includes(\"\\t\");\n return el(\"w:t\", needsPreserve ? { \"xml:space\": \"preserve\" } : undefined, escapeText(text));\n}\n\nexport const XML_DECL = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n';\n\n/** The w: + relationships + drawing namespaces Word expects on a document root. */\nexport const WML_NS = {\n \"xmlns:w\": \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\",\n \"xmlns:r\": \"http://schemas.openxmlformats.org/officeDocument/2006/relationships\",\n \"xmlns:wp\": \"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\",\n \"xmlns:a\": \"http://schemas.openxmlformats.org/drawingml/2006/main\",\n \"xmlns:pic\": \"http://schemas.openxmlformats.org/drawingml/2006/picture\",\n \"xmlns:w14\": \"http://schemas.microsoft.com/office/word/2010/wordml\",\n \"xmlns:mc\": \"http://schemas.openxmlformats.org/markup-compatibility/2006\",\n} as const;\n", "// px (CSS, 96dpi) -> OOXML units. Exact inverses of src/import/docx/units.ts.\r\n\r\n// A non-finite value (NaN/Infinity from an undefined style field) would serialize\r\n// to an invalid w:val=\"NaN\" and corrupt the .docx. Coerce to 0 so output stays\r\n// well-formed \u2014 these are pure unit conversions, so NaN never legitimately occurs.\r\nconst finite = (n: number): number => (Number.isFinite(n) ? n : 0);\r\n\r\n/** px -> twips: px \u00D7 15 (twip = 1/20pt, px = tw/15). */\r\nexport const pxToTwips = (px: number): number => Math.round(finite(px) * 15);\r\n\r\n/** px -> half-points: px \u00D7 1.5 (w:sz; px = hp \u00D7 2/3). */\r\nexport const pxToHalfPoints = (px: number): number => Math.round(finite(px) * 1.5);\r\n\r\n/** px -> EMU: px \u00D7 9525 (image extents; 914400 EMU/in \u00F7 96). */\r\nexport const pxToEmu = (px: number): number => Math.round(finite(px) * 9525);\r\n\r\n/** px -> eighth-points: px \u00D7 6 (border w:sz; px = sz/6). */\r\nexport const pxToEighthPoints = (px: number): number => Math.max(2, Math.round(finite(px) * 6));\r\n\r\n/** line-height multiplier -> w:line 240ths (lineRule=\"auto\"). */\r\nexport const multiplierToLine = (m: number): number => Math.round(finite(m) * 240);\r\n", "// Single source for model \u2192 WordprocessingML value mappings shared across the\r\n// exporter (documentXml, styleProps) and the headless TOC generator. Keeping\r\n// these in one place prevents the maps from drifting apart (they already had).\r\n\r\nimport type { ParaStyle } from \"@cw/shared\";\r\n\r\n/** highlight hex \u2192 Word highlight color name (w:highlight w:val). */\r\nexport const HIGHLIGHT_NAME: Record<string, string> = {\r\n \"#ffff00\": \"yellow\", \"#00ff00\": \"green\", \"#00ffff\": \"cyan\", \"#ff00ff\": \"magenta\",\r\n \"#0000ff\": \"blue\", \"#ff0000\": \"red\", \"#000080\": \"darkBlue\", \"#008080\": \"darkCyan\",\r\n \"#008000\": \"darkGreen\", \"#800080\": \"darkMagenta\", \"#800000\": \"darkRed\", \"#808000\": \"darkYellow\",\r\n \"#808080\": \"darkGray\", \"#c0c0c0\": \"lightGray\", \"#000000\": \"black\", \"#ffffff\": \"white\",\r\n};\r\n\r\n/** paragraph align \u2192 w:jc w:val. */\r\nexport const JC: Record<ParaStyle[\"align\"], string> = { left: \"left\", center: \"center\", right: \"right\", justify: \"both\" };\r\n\r\n/** tab align \u2192 w:tab w:val. */\r\nexport const TAB_VAL: Record<string, string> = { left: \"left\", center: \"center\", right: \"right\", decimal: \"decimal\" };\r\n\r\n/** tab leader \u2192 w:tab w:leader. */\r\nexport const TAB_LEADER: Record<string, string> = { dot: \"dot\", dash: \"hyphen\", underscore: \"underscore\" };\r\n\r\n/** strip a leading \"#\" and lowercase a hex color for OOXML w:val attributes. */\r\nexport const hexColor = (c: string): string => c.replace(/^#/, \"\").toLowerCase();\r\n", "// Partial rPr/pPr emitters for style-gallery patches (NamedStyle.char/.para) and\r\n// list-marker run props. Only DEFINED fields are written \u2014 the importer reads\r\n// each w:* element into a patch field, so absent elements stay absent.\r\n\r\nimport type { CellBorders, CharStyle, ParaStyle, TableCond, TableCondProps, TableStyle } from \"@cw/shared\";\r\nimport { multiplierToLine, pxToEighthPoints, pxToHalfPoints, pxToTwips } from \"../units\";\r\nimport { HIGHLIGHT_NAME, hexColor as hex, JC, TAB_LEADER, TAB_VAL } from \"./mappings\";\r\nimport { el } from \"./xmlWrite\";\r\n\r\n// Full rPr serializer: every toggle written explicitly (on/off) so a run's\r\n// direct formatting fully overrides any inherited paragraph/named style on\r\n// re-import. Shared by the main exporter (documentXml) and the headless TOC\r\n// generator (recalc/generateTocDocx) so they can't drift.\r\nexport function runPropsXml(s: CharStyle): string {\r\n const family = (s.fontFamily.split(\",\")[0] ?? \"\").trim();\r\n const children: string[] = [];\r\n // w:rStyle (character-style reference) must be the first child of w:rPr; the\r\n // concrete props below still override it on re-import (Word semantics).\r\n if (s.charStyleId) children.push(el(\"w:rStyle\", { \"w:val\": s.charStyleId }));\r\n if (family) children.push(el(\"w:rFonts\", { \"w:ascii\": family, \"w:hAnsi\": family, \"w:cs\": family }));\r\n children.push(el(\"w:b\", { \"w:val\": s.bold ? \"1\" : \"0\" }));\r\n children.push(el(\"w:i\", { \"w:val\": s.italic ? \"1\" : \"0\" }));\r\n if (s.strikethrough) children.push(el(\"w:strike\", { \"w:val\": \"1\" }));\r\n if (s.hidden) children.push(el(\"w:vanish\", { \"w:val\": \"1\" })); // preserved hidden text\r\n children.push(el(\"w:color\", { \"w:val\": hex(s.color) }));\r\n children.push(el(\"w:sz\", { \"w:val\": pxToHalfPoints(s.fontSizePx) }));\r\n children.push(el(\"w:szCs\", { \"w:val\": pxToHalfPoints(s.fontSizePx) }));\r\n children.push(el(\"w:u\", { \"w:val\": s.underline ? \"single\" : \"none\" }));\r\n if (s.letterSpacingPx !== undefined) children.push(el(\"w:spacing\", { \"w:val\": pxToTwips(s.letterSpacingPx) }));\r\n if (s.highlightColor) {\r\n const name = HIGHLIGHT_NAME[s.highlightColor.toLowerCase()];\r\n if (name) children.push(el(\"w:highlight\", { \"w:val\": name }));\r\n }\r\n if (s.verticalAlign) children.push(el(\"w:vertAlign\", { \"w:val\": s.verticalAlign === \"super\" ? \"superscript\" : \"subscript\" }));\r\n return el(\"w:rPr\", undefined, children.join(\"\"));\r\n}\r\n\r\n// The spacing/indent/jc/tabs core shared by every full pPr: returned as\r\n// concatenated child elements (NOT wrapped in w:pPr) so the main exporter can\r\n// interleave it with pStyle/numPr/breaks/section props, while the TOC generator\r\n// wraps it directly. Emission order matches OOXML's tolerant exporter convention.\r\nexport function paraCoreXml(style: ParaStyle): string {\r\n const c: string[] = [];\r\n c.push(el(\"w:spacing\", {\r\n \"w:before\": pxToTwips(style.spaceBeforePx),\r\n \"w:after\": pxToTwips(style.spaceAfterPx),\r\n \"w:line\": multiplierToLine(style.lineHeight),\r\n \"w:lineRule\": \"auto\",\r\n }));\r\n const ind: Record<string, number> = {};\r\n if (style.indentLeftPx) ind[\"w:left\"] = pxToTwips(style.indentLeftPx);\r\n if (style.indentRightPx) ind[\"w:right\"] = pxToTwips(style.indentRightPx);\r\n if (style.indentFirstLinePx > 0) ind[\"w:firstLine\"] = pxToTwips(style.indentFirstLinePx);\r\n else if (style.indentFirstLinePx < 0) ind[\"w:hanging\"] = pxToTwips(-style.indentFirstLinePx);\r\n if (Object.keys(ind).length > 0) c.push(el(\"w:ind\", ind));\r\n c.push(el(\"w:jc\", { \"w:val\": JC[style.align] }));\r\n if (style.tabStops && style.tabStops.length > 0) {\r\n const tabs = style.tabStops\r\n .map((t) =>\r\n el(\"w:tab\", {\r\n \"w:val\": t.align ? (TAB_VAL[t.align] ?? \"left\") : \"left\",\r\n \"w:pos\": pxToTwips(t.posPx),\r\n \"w:leader\": t.leader && t.leader !== \"none\" ? TAB_LEADER[t.leader] : undefined,\r\n }),\r\n )\r\n .join(\"\");\r\n c.push(el(\"w:tabs\", undefined, tabs));\r\n }\r\n return c.join(\"\");\r\n}\r\n\r\nexport function partialRPrXml(c: Partial<CharStyle>): string {\r\n const out: string[] = [];\r\n if (c.fontFamily) {\r\n const fam = (c.fontFamily.split(\",\")[0] ?? \"\").trim();\r\n if (fam) out.push(el(\"w:rFonts\", { \"w:ascii\": fam, \"w:hAnsi\": fam, \"w:cs\": fam }));\r\n }\r\n if (c.bold !== undefined) out.push(el(\"w:b\", { \"w:val\": c.bold ? \"1\" : \"0\" }));\r\n if (c.italic !== undefined) out.push(el(\"w:i\", { \"w:val\": c.italic ? \"1\" : \"0\" }));\r\n if (c.strikethrough !== undefined) out.push(el(\"w:strike\", { \"w:val\": c.strikethrough ? \"1\" : \"0\" }));\r\n if (c.color) out.push(el(\"w:color\", { \"w:val\": hex(c.color) }));\r\n if (c.fontSizePx !== undefined) {\r\n const sz = Math.round(c.fontSizePx * 1.5);\r\n out.push(el(\"w:sz\", { \"w:val\": sz }));\r\n out.push(el(\"w:szCs\", { \"w:val\": sz }));\r\n }\r\n if (c.underline !== undefined) out.push(el(\"w:u\", { \"w:val\": c.underline ? \"single\" : \"none\" }));\r\n if (c.highlightColor) {\r\n const name = HIGHLIGHT_NAME[c.highlightColor.toLowerCase()];\r\n if (name) out.push(el(\"w:highlight\", { \"w:val\": name }));\r\n }\r\n if (c.verticalAlign) out.push(el(\"w:vertAlign\", { \"w:val\": c.verticalAlign === \"super\" ? \"superscript\" : \"subscript\" }));\r\n return out.length > 0 ? el(\"w:rPr\", undefined, out.join(\"\")) : \"\";\r\n}\r\n\r\nexport function partialPPrXml(p: Partial<ParaStyle>): string {\r\n const out: string[] = [];\r\n if (p.align) out.push(el(\"w:jc\", { \"w:val\": JC[p.align] ?? \"left\" }));\r\n const sp: Record<string, number | string> = {};\r\n if (p.spaceBeforePx !== undefined) sp[\"w:before\"] = pxToTwips(p.spaceBeforePx);\r\n if (p.spaceAfterPx !== undefined) sp[\"w:after\"] = pxToTwips(p.spaceAfterPx);\r\n if (p.lineHeight !== undefined) {\r\n sp[\"w:line\"] = multiplierToLine(p.lineHeight);\r\n sp[\"w:lineRule\"] = \"auto\";\r\n }\r\n if (Object.keys(sp).length > 0) out.push(el(\"w:spacing\", sp));\r\n const ind: Record<string, number> = {};\r\n if (p.indentLeftPx !== undefined) ind[\"w:left\"] = pxToTwips(p.indentLeftPx);\r\n if (p.indentRightPx !== undefined) ind[\"w:right\"] = pxToTwips(p.indentRightPx);\r\n if (p.indentFirstLinePx !== undefined) {\r\n if (p.indentFirstLinePx >= 0) ind[\"w:firstLine\"] = pxToTwips(p.indentFirstLinePx);\r\n else ind[\"w:hanging\"] = pxToTwips(-p.indentFirstLinePx);\r\n }\r\n if (Object.keys(ind).length > 0) out.push(el(\"w:ind\", ind));\r\n if (p.keepWithNext) out.push(el(\"w:keepNext\"));\r\n if (p.keepLinesTogether) out.push(el(\"w:keepLines\"));\r\n if (p.tabStops && p.tabStops.length > 0) {\r\n const tabs = p.tabStops\r\n .map((t) =>\r\n el(\"w:tab\", {\r\n \"w:val\": t.align ? (TAB_VAL[t.align] ?? \"left\") : \"left\",\r\n \"w:pos\": pxToTwips(t.posPx),\r\n \"w:leader\": t.leader && t.leader !== \"none\" ? TAB_LEADER[t.leader] : undefined,\r\n }),\r\n )\r\n .join(\"\");\r\n out.push(el(\"w:tabs\", undefined, tabs));\r\n }\r\n return out.length > 0 ? el(\"w:pPr\", undefined, out.join(\"\")) : \"\";\r\n}\r\n\n// ---------------------------------------------------------------------------\n// Table styles \u2192 w:style[@w:type=\"table\"] with conditional formatting.\n\nfunction condBordersXml(tag: string, b: CellBorders): string {\n const edge = (name: string, spec: CellBorders[\"top\"]): string => {\n if (!spec) return \"\";\n const val = spec.style === \"double\" ? \"double\" : spec.style === \"dashed\" ? \"dashed\" : spec.style === \"dotted\" ? \"dotted\" : \"single\";\n return el(\"w:\" + name, { \"w:val\": val, \"w:sz\": pxToEighthPoints(spec.widthPx), \"w:space\": 0, \"w:color\": hex(spec.color) });\n };\n return el(tag, undefined, edge(\"top\", b.top) + edge(\"left\", b.left) + edge(\"bottom\", b.bottom) + edge(\"right\", b.right));\n}\n\nconst shdFillXml = (fill: string): string => el(\"w:shd\", { \"w:val\": \"clear\", \"w:color\": \"auto\", \"w:fill\": hex(fill) });\n\nfunction tblStylePrXml(cond: TableCond, props: TableCondProps): string {\n const tc: string[] = [];\n if (props.borders) tc.push(condBordersXml(\"w:tcBorders\", props.borders));\n if (props.shading) tc.push(shdFillXml(props.shading));\n const tcPr = tc.length > 0 ? el(\"w:tcPr\", undefined, tc.join(\"\")) : \"\";\n return el(\"w:tblStylePr\", { \"w:type\": cond }, partialRPrXml(props.char ?? {}) + partialPPrXml(props.para ?? {}) + tcPr);\n}\n\n/** One table style. Base (wholeTable) \u2192 rPr/pPr + tblPr(borders/shd/band sizes);\n * each other condition \u2192 a w:tblStylePr. */\nexport function tableStyleXml(style: TableStyle): string {\n const base = style.conds.wholeTable ?? {};\n const tblPrKids: string[] = [];\n if (style.rowBandSize !== undefined) tblPrKids.push(el(\"w:tblStyleRowBandSize\", { \"w:val\": style.rowBandSize }));\n if (style.colBandSize !== undefined) tblPrKids.push(el(\"w:tblStyleColBandSize\", { \"w:val\": style.colBandSize }));\n if (base.borders) tblPrKids.push(condBordersXml(\"w:tblBorders\", base.borders));\n if (base.shading) tblPrKids.push(shdFillXml(base.shading));\n const tblPr = tblPrKids.length > 0 ? el(\"w:tblPr\", undefined, tblPrKids.join(\"\")) : \"\";\n const conds = (Object.entries(style.conds) as [TableCond, TableCondProps][])\n .filter(([c]) => c !== \"wholeTable\")\n .map(([c, p]) => tblStylePrXml(c, p))\n .join(\"\");\n const body =\n el(\"w:name\", { \"w:val\": style.name }) +\n (style.basedOn ? el(\"w:basedOn\", { \"w:val\": style.basedOn }) : \"\") +\n partialRPrXml(base.char ?? {}) +\n partialPPrXml(base.para ?? {}) +\n tblPr +\n conds;\n return el(\"w:style\", { \"w:type\": \"table\", \"w:styleId\": style.id }, body);\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -276,4 +276,4 @@ export {
276
276
  numAttr,
277
277
  findMainDocumentPart
278
278
  };
279
- //# sourceMappingURL=chunk-2RCPB7UZ.js.map
279
+ //# sourceMappingURL=chunk-KJV7GJ3H.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/import/docx/types.ts", "../../node_modules/txml/dist/txml.mjs", "../src/import/docx/xml.ts", "../src/import/docx/contentTypes.ts"],
4
+ "sourcesContent": ["// .docx import \u2014 shared types.\r\n//\r\n// The pipeline is: zip \u2192 XML parts \u2192 IR (intermediate representation) \u2192 model.\r\n// The IR is a faithful-but-minimal decode of document.xml: the parser keeps\r\n// everything it understands (even what the model can't hold yet); mapToModel\r\n// decides what survives and emits an ImportWarning for every lossy decision.\r\n\r\nimport type { Document, FieldDef } from \"@cw/shared\";\r\n\r\nexport type ImportPhase = \"unzip\" | \"styles\" | \"parse\" | \"map\";\r\n\r\nexport type ImportErrorCode = \"NOT_ZIP\" | \"ENCRYPTED\" | \"NO_DOCUMENT_PART\" | \"MALFORMED_XML\";\r\n\r\nexport class ImportError extends Error {\r\n readonly code: ImportErrorCode;\r\n constructor(code: ImportErrorCode, message: string) {\r\n super(message);\r\n this.name = \"ImportError\";\r\n this.code = code;\r\n }\r\n}\r\n\r\nexport interface ImportWarning {\r\n code: string;\r\n message: string;\r\n}\r\n\r\n/** Deduplicating warning collector \u2014 a 70-page doc with 400 tabs should say\r\n * \"tabs converted\" once, not 400 times. */\r\nexport class WarningSink {\r\n readonly list: ImportWarning[] = [];\r\n private readonly seen = new Set<string>();\r\n add(code: string, message: string): void {\r\n if (this.seen.has(code)) return;\r\n this.seen.add(code);\r\n this.list.push({ code, message });\r\n }\r\n}\r\n\r\nexport interface ImportResult {\r\n doc: Document;\r\n /** Every lossy mapping decision \u2014 surfaced, not swallowed. */\r\n warnings: ImportWarning[];\r\n /** blob: URLs created for embedded media; caller revokes when the doc is discarded. */\r\n mediaUrls: string[];\r\n /** Raw embedded image bytes, populated only when runImport is called with\r\n * { collectMediaBytes: true } \u2014 the Node/backend path, which content-addresses\r\n * them into its own media store instead of minting blob: URLs. Each `src`\r\n * matches the ImageBlock.src the mapper assigned, so the caller can swap in a\r\n * mediaId. Empty (and mediaUrls carry blob: URLs) in the browser path. */\r\n media: ImportMedia[];\r\n}\r\n\r\n/** A collected embedded image (Node/backend path). */\r\nexport interface ImportMedia {\r\n /** The synthetic src the mapper put on the ImageBlock (e.g. \"cw-media:0\"). */\r\n src: string;\r\n bytes: Uint8Array;\r\n mime: string;\r\n}\r\n\r\n/** Sink the media store routes raw image bytes to instead of creating a blob:\r\n * URL. Returns the src string to stamp on the ImageBlock. */\r\nexport interface MediaCollector {\r\n add(bytes: Uint8Array, mime: string): string;\r\n}\r\n\r\nexport interface RunImportOpts {\r\n onProgress?: (phase: ImportPhase, pct: number) => void;\r\n /** Collect raw image bytes (and skip blob: URL creation) for Node/backend\r\n * callers that content-address media themselves. */\r\n collectMediaBytes?: boolean;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Worker protocol\r\n\r\nexport interface ToWorker {\r\n id: number;\r\n buf: ArrayBuffer; // transferred, not cloned\r\n}\r\n\r\nexport type FromWorker =\r\n | { id: number; type: \"progress\"; phase: ImportPhase; pct: number }\r\n | { id: number; type: \"done\"; result: ImportResult }\r\n | { id: number; type: \"error\"; code: ImportErrorCode; message: string };\r\n\r\n// ---------------------------------------------------------------------------\r\n// IR \u2014 what documentParser produces. Units stay as OOXML units (twips,\r\n// half-points); conversion to px happens in mapToModel via units.ts.\r\n\r\n/** Direct run formatting decoded from w:rPr. Absent field = \"inherit\" \u2014\r\n * resolved through the style cascade in milestone 2, from defaults today. */\r\nexport interface IRRunProps {\r\n /** w:rStyle reference \u2014 recorded now, resolved when StyleResolver lands. */\r\n styleId?: string;\r\n bold?: boolean;\r\n italic?: boolean;\r\n underline?: boolean;\r\n strikethrough?: boolean;\r\n /** Raw w:color value: hex without '#' (\"FF0000\") or \"auto\". */\r\n color?: string;\r\n /** w:sz \u2014 half-points. */\r\n sizeHalfPoints?: number;\r\n /** w:rFonts w:ascii. */\r\n fontAscii?: string;\r\n /** w:rFonts w:asciiTheme \u2014 theme font slot (\"minorHAnsi\", \"majorHAnsi\", \u2026). */\r\n fontThemeAscii?: string;\r\n /** w:color w:themeColor \u2014 theme color slot (\"accent1\", \"text1\", \u2026). */\r\n colorTheme?: string;\r\n /** w:highlight w:val \u2014 named highlight color (\"yellow\", \"green\", \u2026). */\r\n highlight?: string;\r\n /** w:vertAlign w:val \u2014 \"superscript\" | \"subscript\" | \"baseline\". */\r\n vertAlign?: string;\r\n /** w:vanish \u2014 hidden text (Word shows it only with \u00B6 marks on). */\r\n vanish?: boolean;\r\n /** Hyperlink membership (set on runs inside a w:hyperlink). Resolved to a URL\r\n * in mapToModel: relId via the part's rels (external target), or anchor for\r\n * an in-document bookmark (kept as \"#name\"). */\r\n linkRelId?: string;\r\n linkAnchor?: string;\r\n /** w:footnoteReference w:id \u2014 this run is a footnote marker. mapToModel sets\r\n * the run text to the sequential note number and CharStyle.footnoteRef. */\r\n footnoteId?: string;\r\n}\r\n\r\n/** w:sdtPr \u2014 content-control properties, decoded faithfully (mapToModel turns\r\n * these into the model's SdtProps; runs inside the control carry the sdtId). */\r\nexport interface IRSdtProps {\r\n type: \"richText\" | \"plainText\" | \"checkbox\" | \"dropDown\" | \"comboBox\" | \"date\";\r\n alias?: string;\r\n tag?: string;\r\n /** w:showingPlcHdr \u2014 the content is currently the gray placeholder. */\r\n placeholder?: boolean;\r\n listItems?: { display: string; value: string }[];\r\n dateFormat?: string;\r\n checked?: boolean;\r\n lockContent?: boolean;\r\n lockControl?: boolean;\r\n}\r\n\r\nexport type IRInline =\r\n | { kind: \"run\"; text: string; props: IRRunProps; sdtId?: string; fieldId?: string }\r\n /** w:br / w:cr \u2014 soft line break (model has none; mapToModel splits the\r\n * paragraph). page=true for w:br w:type=\"page\" (\u2192 pageBreakBefore on the\r\n * follower); column=true for w:br w:type=\"column\" (\u2192 columnBreakBefore). */\r\n | { kind: \"break\"; page?: boolean; column?: boolean }\r\n /** w:drawing / w:pict \u2014 becomes a block-level ImageBlock (model has no inline images). */\r\n | {\r\n kind: \"image\";\r\n relId: string;\r\n widthEmu?: number;\r\n heightEmu?: number;\r\n anchored: boolean;\r\n /** For wp:anchor: square = text wraps around (maps to ImageBlock.wrap);\r\n * block = wrap mode the model can't express (none/topAndBottom). */\r\n anchorWrap?: \"square\" | \"block\";\r\n /** wp:positionH/wp:align when present. */\r\n anchorAlign?: \"left\" | \"right\" | \"center\";\r\n /** Set for wrapNone anchors (image sits behind/in-front of text, not in\r\n * the flow). Maps to ImageBlock.anchor \u2014 positioned absolutely, no flow\r\n * height, no text reflow. */\r\n anchorFloat?: {\r\n behind: boolean;\r\n offsetXEmu: number;\r\n offsetYEmu: number;\r\n relFromH: \"page\" | \"margin\" | \"column\" | \"leftMargin\" | \"rightMargin\" | \"character\";\r\n relFromV: \"page\" | \"margin\" | \"paragraph\" | \"line\" | \"topMargin\" | \"bottomMargin\";\r\n decorative?: boolean;\r\n /** wp:anchor @relativeHeight \u2014 stacking order within the layer. */\r\n z?: number;\r\n };\r\n };\r\n\r\nexport interface IRParaProps {\r\n /** w:pStyle reference \u2014 recorded now, resolved when StyleResolver lands. */\r\n styleId?: string;\r\n align?: \"left\" | \"center\" | \"right\" | \"justify\";\r\n spaceBeforeTwips?: number;\r\n spaceAfterTwips?: number;\r\n /** Multiplier \u2014 only set when lineRule is \"auto\" (or absent). */\r\n lineHeight?: number;\r\n indentLeftTwips?: number;\r\n /** w:ind/@w:right|@w:end \u2014 right-edge indent. */\r\n indentRightTwips?: number;\r\n /** Negative = hanging indent (w:hanging). */\r\n indentFirstLineTwips?: number;\r\n /** w:keepNext \u2014 maps onto ParaStyle.keepWithNext. */\r\n keepWithNext?: boolean;\r\n /** w:keepLines \u2014 maps onto ParaStyle.keepLinesTogether. */\r\n keepLinesTogether?: boolean;\r\n /** w:pPr/w:tabs \u2014 raw tab stops (pos in twips; val/leader raw OOXML names). */\r\n tabStops?: { posTwips: number; val?: string; leader?: string }[];\r\n /** w:pageBreakBefore \u2014 this paragraph starts a new page. */\r\n pageBreakBefore?: boolean;\r\n /** w:outlineLvl \u2014 0-8. Heading styles set it; drives TOC `\\u`/heading detection. */\r\n outlineLevel?: number;\r\n /** w:numPr \u2014 list membership. numId \"0\" / null = explicitly NOT a list\r\n * (overrides an inherited list from the paragraph style). */\r\n list?: { numId: string; level: number } | null;\r\n /** w:pPr/w:sectPr \u2014 this paragraph ENDS a section. \"page\" (nextPage/odd/even)\r\n * implies the following content starts a new page; \"continuous\" doesn't. */\r\n sectionBreak?: \"page\" | \"continuous\";\r\n /** The ending section's page size (twips), when its w:sectPr declares pgSz.\r\n * A \"page\" break only forces a new page when this differs from the document's\r\n * page size \u2014 geometry-preserving breaks (footer/header switches, which these\r\n * generated reports emit by the dozen) flow instead of leaving half-empty\r\n * pages, matching Word. */\r\n sectionPgSize?: { w: number; h: number };\r\n /** The ending section's margins (twips) \u2014 for a SectionPatch when geometry differs. */\r\n sectionMarginTwips?: { top: number; right: number; bottom: number; left: number };\r\n /** The ending section's newspaper columns (count > 1). */\r\n sectionColumns?: { count: number; spaceTwips?: number; sep?: boolean; cols?: { wTwips: number; spaceTwips: number }[] };\r\n /** The ending section's w:pgNumType w:start (page-number restart). */\r\n sectionPageNumberStart?: number;\r\n /** The ending section's w:pgMar header/footer band distances (twips). */\r\n sectionHeaderDistTwips?: number;\r\n sectionFooterDistTwips?: number;\r\n /** The ending section's w:pgBorders (raw, mapped downstream). */\r\n sectionPgBorders?: IRPageBorders;\r\n /** The ending section's sectPr declares its own header/footer references \u2014\r\n * when such a section is flowed (not page-broken) its bands aren't applied. */\r\n sectionHasBands?: boolean;\r\n /** w:pPr/w:rPr \u2014 the paragraph MARK's run formatting. Word styles empty\r\n * paragraphs (and the \u00B6 itself) with this; we use it for empty-run style. */\r\n markRunProps?: IRRunProps;\r\n}\r\n\r\n/** A w:bookmarkStart / w:bookmarkEnd seen while walking a paragraph: its w:id\r\n * (pairs start\u2194end, possibly across paragraphs), w:name (start only), and the\r\n * UTF-16 offset within the paragraph text where it sits. */\r\nexport interface BookmarkMarker {\r\n id: string;\r\n name?: string;\r\n kind: \"start\" | \"end\";\r\n offset: number;\r\n}\r\n\r\nexport interface IRParagraph {\r\n kind: \"paragraph\";\r\n props: IRParaProps;\r\n inlines: IRInline[];\r\n /** w:bookmarkStart names anchored in this paragraph (TOC/cross-ref heuristics). */\r\n bookmarks?: string[];\r\n /** Start/end markers with offsets \u2014 resolved to model ranges in mapToModel. */\r\n bookmarkMarkers?: BookmarkMarker[];\r\n /** Custom-field result membership \u2014 mapped onto Block.fieldId. */\r\n fieldId?: string;\r\n /** Set when this paragraph holds a `TOC` field \u2014 its verbatim instrText. Lets a\r\n * headless render anchor a freshly-built TOC at this exact block (mapToModel\r\n * records the resulting block id), instead of fragile ordinal counting. */\r\n tocField?: string;\r\n}\r\n\r\n/** One raw border edge (w:top/w:left/\u2026 inside w:tblBorders or w:tcBorders).\r\n * Kept raw (OOXML units) until mapToModel collapses the cascade to px. */\r\nexport interface IRRawBorder {\r\n /** w:val \u2014 \"single\", \"double\", \"dashed\", \"nil\"/\"none\", \u2026 */\r\n val: string;\r\n /** w:sz \u2014 eighths of a point. */\r\n sizeEighthPt?: number;\r\n /** w:color \u2014 hex without '#', or \"auto\". */\r\n color?: string;\r\n}\r\n\r\nexport interface IRBorders {\r\n top?: IRRawBorder;\r\n left?: IRRawBorder;\r\n bottom?: IRRawBorder;\r\n right?: IRRawBorder;\r\n /** Interior horizontal/vertical edges (w:tblBorders only). */\r\n insideH?: IRRawBorder;\r\n insideV?: IRRawBorder;\r\n}\r\n\r\n/** Cell margins in twips, per side. Any side may be absent (inherits the next\r\n * level of the cascade: cell \u2192 table \u2192 Word default). w:tcMar / w:tblCellMar. */\r\nexport interface IRCellMargin {\r\n top?: number;\r\n right?: number;\r\n bottom?: number;\r\n left?: number;\r\n}\r\n\r\nexport interface IRTableCell {\r\n /** Full block content: paragraphs, images (inside paragraphs), nested tables. */\r\n blocks: IRBlock[];\r\n /** w:gridSpan \u2014 columns this cell covers (1 = normal). Maps to TableCell.colSpan. */\r\n gridSpan: number;\r\n /** w:vMerge continuation \u2014 this cell is swallowed by the cell above. */\r\n vMergeContinue: boolean;\r\n /** w:tcPr/w:tcBorders. */\r\n borders?: IRBorders;\r\n /** A w:tcBorders element is present \u2014 even if empty (all edges nil/absent), the\r\n * author explicitly chose this cell's borders, so it must NOT fall back to the\r\n * renderer's default grid. */\r\n bordersSpecified?: boolean;\r\n /** w:tcPr/w:shd \u2192 CSS fill. */\r\n shd?: string;\r\n /** w:tcPr/w:tcMar \u2014 per-side inner padding override (twips). */\r\n marginTwips?: IRCellMargin;\r\n}\r\n\r\nexport interface IRTableRow {\r\n cells: IRTableCell[];\r\n}\r\n\r\nexport interface IRTable {\r\n kind: \"table\";\r\n rows: IRTableRow[];\r\n /** w:tblGrid/w:gridCol widths \u2014 become TableBlock.colFractions. */\r\n colWidthsTwips?: number[];\r\n /** w:tblPr/w:tblStyle \u2014 table style id (its borders/shd are the cascade base). */\r\n styleId?: string;\r\n /** w:tblPr/w:tblLook \u2014 which conditional bands of the table style are active. */\r\n look?: { firstRow?: boolean; lastRow?: boolean; firstCol?: boolean; lastCol?: boolean; bandRows?: boolean; bandCols?: boolean };\r\n /** w:tblPr/w:tblBorders. */\r\n borders?: IRBorders;\r\n /** A w:tblBorders element is present \u2014 even if empty, the table explicitly\r\n * declares its borders (e.g. \"no borders\"), suppressing the default grid. */\r\n bordersSpecified?: boolean;\r\n /** w:tblPr/w:shd \u2192 CSS fill applied to every cell unless overridden. */\r\n shd?: string;\r\n /** w:tblPr/w:tblCellMar \u2014 table-wide cell-margin default (twips), the base each\r\n * cell's own w:tcMar overrides per side. */\r\n cellMarginTwips?: IRCellMargin;\r\n /** Custom-field result membership \u2014 mapped onto Block.fieldId. */\r\n fieldId?: string;\r\n}\r\n\r\nexport type IRBlock = IRParagraph | IRTable;\r\n\r\n// ---------------------------------------------------------------------------\r\n// Numbering (numbering.xml) \u2014 raw decode; mapToModel converts to model lists.\r\n\r\nexport interface IRListLevel {\r\n /** Raw w:numFmt w:val (\"decimal\", \"bullet\", \"lowerRoman\", \"none\", \u2026). */\r\n format: string;\r\n /** Raw w:lvlText w:val \u2014 \"%1.\" pattern, or the bullet glyph for bullets. */\r\n lvlText: string;\r\n start: number;\r\n indentLeftTwips?: number;\r\n hangingTwips?: number;\r\n /** w:lvl/w:rPr \u2014 marker glyph styling (esp. the bullet font). */\r\n markerRunProps?: IRRunProps;\r\n}\r\n\r\nexport interface IRListDefinition {\r\n /** numId (the id space paragraphs reference via w:numPr/w:numId). */\r\n id: string;\r\n levels: IRListLevel[];\r\n}\r\n\r\nexport interface IRSection {\r\n pageWidthTwips?: number;\r\n pageHeightTwips?: number;\r\n marginTwips?: { top: number; right: number; bottom: number; left: number };\r\n /** w:pgMar/@w:header and @w:footer \u2014 band distances from the page edges (twips). */\r\n headerDistTwips?: number;\r\n footerDistTwips?: number;\r\n /** w:headerReference / w:footerReference by type \u2014 r:id into the document\r\n * part's rels; the referenced parts are parsed separately. Variants are\r\n * gated downstream (first by w:titlePg, even by settings evenAndOdd). */\r\n headerRefs?: BandRefs;\r\n footerRefs?: BandRefs;\r\n /** w:titlePg \u2014 this section has a distinct first-page header/footer. */\r\n titlePg?: boolean;\r\n /** w:cols \u2014 newspaper columns (only count > 1 is meaningful). `sep` = a\r\n * separator line; `cols` = explicit per-column widths (w:equalWidth=\"0\"). */\r\n columns?: {\r\n count: number;\r\n spaceTwips?: number;\r\n sep?: boolean;\r\n cols?: { wTwips: number; spaceTwips: number }[];\r\n };\r\n /** w:pgNumType w:start \u2014 restart page numbering at this value. */\r\n pageNumberStart?: number;\r\n /** w:pgBorders \u2014 page border box (raw twips/eighth-points, mapped downstream). */\r\n pageBorders?: IRPageBorders;\r\n}\r\n\r\n/** w:pgBorders edge as parsed (w:sz eighth-points, w:space points). */\r\nexport interface IRPageBorderEdge {\r\n style: string;\r\n sz?: number;\r\n space?: number;\r\n color?: string;\r\n}\r\nexport interface IRPageBorders {\r\n top?: IRPageBorderEdge;\r\n right?: IRPageBorderEdge;\r\n bottom?: IRPageBorderEdge;\r\n left?: IRPageBorderEdge;\r\n offsetFrom?: \"page\" | \"text\";\r\n}\r\n\r\n/** Header/footer relationship ids by Word variant. */\r\nexport interface BandRefs {\r\n default?: string;\r\n first?: string;\r\n even?: string;\r\n}\r\n\r\nexport interface IRDocument {\r\n blocks: IRBlock[];\r\n section: IRSection | null;\r\n /** Content controls found in the body (header/footer parsing extends it). */\r\n sdts: Record<string, IRSdtProps>;\r\n /** Custom (non-built-in) complex fields captured in the body, keyed by id. */\r\n fields?: Record<string, FieldDef>;\r\n /** w:document/w:background @w:color \u2014 document-global page fill (\"RRGGBB\"). */\r\n pageColorHex?: string;\r\n}\r\n", "function t(t){return t.replace(/&(#x[0-9a-fA-F]+|#\\d+|amp|lt|gt|quot|apos);/g,function(t,r){if(\"amp\"===r)return\"&\";if(\"lt\"===r)return\"<\";if(\"gt\"===r)return\">\";if(\"quot\"===r)return'\"';if(\"apos\"===r)return\"'\";if(\"#\"===r[0]){var e=\"x\"===r[1]||\"X\"===r[1],a=parseInt(r.slice(e?2:1),e?16:10);if(!Number.isNaN(a)&&a>=0&&a<=1114111)try{return String.fromCodePoint(a)}catch(r){return t}}return t})}function r(t){return t.replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\")}function e(t){return t.replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/\"/g,\"&quot;\").replace(/'/g,\"&apos;\")}function a(r,e){var a=(e=e||{}).pos||0,i=!!e.keepComments,c=!!e.keepWhitespace,f=!!e.decodeEntities,s=\"<\".charCodeAt(0),u=\">\".charCodeAt(0),h=\"-\".charCodeAt(0),l=\"/\".charCodeAt(0),d=\"!\".charCodeAt(0),g=\"?\".charCodeAt(0),A=\"'\".charCodeAt(0),p='\"'.charCodeAt(0),C=\"=\".charCodeAt(0),v=\"[\".charCodeAt(0),y=\"]\".charCodeAt(0),m=\"?\".charCodeAt(0);function b(t){for(var e=[];r[a];)if(r.charCodeAt(a)==s){if(r.charCodeAt(a+1)===l){var n=a+2;if(a=r.indexOf(\">\",a),-1==r.substring(n,a).indexOf(t)){var o=r.substring(0,a).split(\"\\n\");throw new Error(\"Unexpected close tag\\nLine: \"+(o.length-1)+\"\\nColumn: \"+(o[o.length-1].length+1)+\"\\nChar: \"+r[a])}return a+1&&(a+=1),e}if(r.charCodeAt(a+1)===d){if(r.charCodeAt(a+2)==h){const t=a;for(;-1!==a&&(r.charCodeAt(a)!==u||r.charCodeAt(a-1)!=h||r.charCodeAt(a-2)!=h||-1==a);)a=r.indexOf(\">\",a+1);-1===a&&(a=r.length),i&&e.push(r.substring(t,a+1))}else{if(r.charCodeAt(a+2)===v&&r.charCodeAt(a+8)===v&&\"cdata\"===r.substr(a+3,5).toLowerCase()){var f=r.indexOf(\"]]>\",a);-1==f?(e.push(r.substr(a+9)),a=r.length):(e.push(r.substring(a+9,f)),a=f+3);continue}{const t=a+1;a+=2;for(var g=!1;(r.charCodeAt(a)!==u||!0===g)&&r[a];)r.charCodeAt(a)===v?g=!0:!0===g&&r.charCodeAt(a)===y&&(g=!1),a++;e.push(r.substring(t,a))}}a++;continue}var A=k();e.push(A)}else{var p=N();if(c)p.length>0&&e.push(p);else{var C=p.trim();C.length>0&&e.push(C)}a++}return e}function N(){var e=a;-2===(a=r.indexOf(\"<\",a)-1)&&(a=r.length);var n=r.slice(e,a+1);return f?t(n):n}var x=\"\\r\\n\\t>/= \";function O(){for(var t=a;-1===x.indexOf(r[a])&&r[a];)a++;return r.slice(t,a)}var j,E=e.selfClosingTags||e.noChildNodes||[\"img\",\"br\",\"input\",\"meta\",\"link\",\"hr\"];function k(){a++;const e=O(),n=\"?\"===e[0],i=a,o={};let c=[];for(;r[a]&&r.charCodeAt(a)!==u&&(!n||r.charCodeAt(a)!==g||r.charCodeAt(a+1)!==u);){var s=r.charCodeAt(a);if(s>64&&s<91||s>96&&s<123){for(var h=O(),d=null;32===r.charCodeAt(a)||9===r.charCodeAt(a)||10===r.charCodeAt(a)||13===r.charCodeAt(a);)a++;if(r.charCodeAt(a)===C){for(a++;32===r.charCodeAt(a)||9===r.charCodeAt(a)||10===r.charCodeAt(a)||13===r.charCodeAt(a);)a++;var v=r.charCodeAt(a);if(v===A||v===p){if(d=w(),-1===a)return{tagName:e,attributes:o,children:c}}else if(v&&v!==u){for(var y=a;r[a]&&-1===x.indexOf(r[a]);)a++;d=r.slice(y,a),f&&(d=t(d))}}o[h]=d}else a++}if(n){var N=r.slice(i,a).trim();return N.length>0&&0===Object.keys(o).length&&(c=[N]),r.charCodeAt(a)===g&&r.charCodeAt(a+1)===u?a+=2:r.charCodeAt(a)===u&&(a+=1),{tagName:e,attributes:o,children:c}}if(r.charCodeAt(a-1)!==l&&r.charCodeAt(a-1)!==m)if(\"script\"==e){var j=a+1;a=r.indexOf(\"<\\/script>\",a),c=[r.slice(j,a)],a+=9}else if(\"style\"==e){j=a+1;a=r.indexOf(\"</style>\",a),c=[r.slice(j,a)],a+=8}else-1===E.indexOf(e)?(a++,c=b(e)):a++;else a++;return{tagName:e,attributes:o,children:c}}function w(){var e=r[a],n=a+1;a=r.indexOf(e,n);var i=r.slice(n,a);return f?t(i):i}function V(){if(!e||!e.attrName||!e.attrValue)return-1;var t=new RegExp(\"\\\\s\"+e.attrName+\"\\\\s*=['\\\"]\"+e.attrValue+\"['\\\"]\").exec(r);return t?t.index:-1}if(void 0!==e.attrValue)for(e.attrName=e.attrName||\"id\",j=[];-1!==(a=V());)-1!==(a=r.lastIndexOf(\"<\",a))&&j.push(k()),r=r.substr(a),a=0;else j=e.parseNode?k():b(\"\");if(e.filter&&Array.isArray(j)&&(j=o(j,e.filter)),e.simplify){return n(Array.isArray(j)?j:[j])}return e.setPos&&\"object\"==typeof j&&!Array.isArray(j)&&(j.pos=a),j}function n(t){if(\"string\"==typeof t)return n(a(t));if(!Array.isArray(t))throw new TypeError(\"simplify() expects parsed node array or XML string\");var r={};if(!t.length)return\"\";if(1===t.length&&\"string\"==typeof t[0])return t[0];for(var e in t.forEach(function(t){if(\"object\"==typeof t){r[t.tagName]||(r[t.tagName]=[]);var e=n(t.children);r[t.tagName].push(e),Object.keys(t.attributes).length&&\"object\"==typeof e&&!Array.isArray(e)&&(e._attributes=t.attributes)}}),r)1==r[e].length&&(r[e]=r[e][0]);return r}function i(t,r={}){var e={};return t.length?1===t.length&&\"string\"==typeof t[0]?Object.keys(r).length?{_attributes:r,value:t[0]}:t[0]:(t.forEach(function(t){if(\"object\"==typeof t){e[t.tagName]||(e[t.tagName]=[]);var r=i(t.children||[],t.attributes);e[t.tagName].push(r),Object.keys(t.attributes).length&&\"object\"==typeof r&&!Array.isArray(r)&&(r._attributes=t.attributes)}}),e):e}function o(t,r,e=0,a=\"\"){var n=[];return t.forEach(function(t,i){if(\"object\"==typeof t&&r(t,i,e,a)&&n.push(t),\"object\"==typeof t&&t.children){var c=o(t.children,r,e+1,(a?a+\".\":\"\")+i+\".\"+t.tagName);n=n.concat(c)}}),n}function c(t,a){if(!t)return\"\";var n=!!(a=a||{}).encodeEntities,i=\"\";function o(t){if(t)for(var e=0;e<t.length;e++){var a=t[e];if(\"string\"==typeof a){var o=a.trim();i+=n?r(o):o}else a&&c(a)}}function c(t){if(t){for(var r in i+=\"<\"+t.tagName,t.attributes){var a=t.attributes[r];null===a?i+=\" \"+r:n?i+=\" \"+r+'=\"'+e(a.trim())+'\"':-1===a.indexOf('\"')?i+=\" \"+r+'=\"'+a.trim()+'\"':i+=\" \"+r+\"='\"+a.trim()+\"'\"}if(\"?\"!==t.tagName[0])i+=\">\",o(t.children),i+=\"</\"+t.tagName+\">\";else{if(t.children&&t.children.length){var c=t.children.filter(function(t){return\"string\"==typeof t}).join(\" \").trim();c.length>0&&(i+=\" \"+c)}i+=\"?>\"}}}return o(Array.isArray(t)?t:[t]),i}function f(t){if(Array.isArray(t)){var r=\"\";return t.forEach(function(t){r=(r+=\" \"+f(t)).trim()}),r}return\"object\"==typeof t&&null!==t?f(t.children):\" \"+t}function s(t,r,e){var i=a(t,{attrValue:r});return e?n(i):i[0]}function u(t,r,e){const i=a(t,{attrName:\"class\",attrValue:\"[a-zA-Z0-9- ]*\"+r+\"[a-zA-Z0-9- ]*\"});return e?n(i):i}function h(t){return\"string\"==typeof t}function l(t){return\"object\"==typeof t&&null!==t&&\"tagName\"in t}export{o as filter,s as getElementById,u as getElementsByClassName,l as isElementNode,h as isTextNode,a as parse,n as simplify,i as simplifyLostLess,c as stringify,f as toContentString};\n", "// txml helpers. DOMParser is window-only (not available in workers), so we use\n// txml \u2014 a tiny pure-JS parser that returns an ORDERED node tree. Order matters:\n// in document.xml, run order IS the text.\n//\n// OOXML namespace handling: prefixes (w:, a:, wp:) are technically remappable,\n// but Word always emits the conventional ones, so we match qualified names\n// directly \u2014 the same pragmatic choice docx-preview and mammoth make.\n\nimport { isElementNode, parse, type TNode } from \"txml/txml\";\nimport { ImportError } from \"./types\";\n\nexport type XmlNode = TNode;\n\n/** Parse an XML part. keepWhitespace matters: a run whose text is a single\n * space (`<w:t xml:space=\"preserve\"> </w:t>`) must not be dropped. */\nexport function parseXml(text: string, partName: string): XmlNode[] {\n try {\n return parse(text, { keepWhitespace: true, decodeEntities: true }).filter(isElementNode);\n } catch (e) {\n throw new ImportError(\n \"MALFORMED_XML\",\n `Failed to parse ${partName}: ${e instanceof Error ? e.message : String(e)}`,\n );\n }\n}\n\n/** Top-level element by qualified name (skips the XML declaration / PIs). */\nexport function rootEl(nodes: XmlNode[], tagName: string): XmlNode | undefined {\n return nodes.find((n) => n.tagName === tagName);\n}\n\n/** Element children only (text nodes filtered out). */\nexport function children(node: XmlNode): XmlNode[] {\n return node.children.filter(isElementNode);\n}\n\n/** First child element with the given qualified name. */\nexport function el(node: XmlNode, tagName: string): XmlNode | undefined {\n return node.children.find((c): c is XmlNode => isElementNode(c) && c.tagName === tagName);\n}\n\n/** All child elements with the given qualified name. */\nexport function els(node: XmlNode, tagName: string): XmlNode[] {\n return node.children.filter((c): c is XmlNode => isElementNode(c) && c.tagName === tagName);\n}\n\n/** Attribute value by qualified name; valueless attributes read as \"\". */\nexport function attr(node: XmlNode, name: string): string | undefined {\n const v = node.attributes[name];\n return v === undefined ? undefined : (v ?? \"\");\n}\n\n/** Depth-first search for a descendant element. Used where the exact nesting\n * is deep and producer-dependent (e.g. a:blip inside w:drawing). */\nexport function findDeep(node: XmlNode, tagName: string): XmlNode | undefined {\n for (const c of node.children) {\n if (!isElementNode(c)) continue;\n if (c.tagName === tagName) return c;\n const found = findDeep(c, tagName);\n if (found) return found;\n }\n return undefined;\n}\n\n/** Concatenated text content (direct string children \u2014 w:t never nests). */\nexport function textOf(node: XmlNode): string {\n let out = \"\";\n for (const c of node.children) if (typeof c === \"string\") out += c;\n return out;\n}\n\n/** Shorthand for the ubiquitous `<w:x w:val=\"\u2026\"/>` child-element pattern. */\nexport function val(node: XmlNode, tagName: string): string | undefined {\n const child = el(node, tagName);\n return child ? attr(child, \"w:val\") : undefined;\n}\n\n/** OOXML on/off property: `<w:b/>` is on; w:val of 0/false/none/off is off. */\nexport function onOff(node: XmlNode | undefined): boolean | undefined {\n if (!node) return undefined;\n const v = attr(node, \"w:val\");\n if (v === undefined) return true;\n return ![\"0\", \"false\", \"none\", \"off\"].includes(v);\n}\n\n/** Numeric attribute (OOXML writes plain decimal integers). */\nexport function numAttr(node: XmlNode | undefined, name: string): number | undefined {\n if (!node) return undefined;\n const v = attr(node, name);\n if (v === undefined) return undefined;\n const n = Number(v);\n return Number.isFinite(n) ? n : undefined;\n}\n", "// [Content_Types].xml \u2192 locate the main document part. Usually\n// \"word/document.xml\", but the spec allows any part name (and macro-enabled\n// .docm uses a different content type), so don't hardcode.\n\nimport { attr, children, parseXml, rootEl } from \"./xml\";\n\nconst MAIN_CONTENT_TYPES = new Set([\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\",\n \"application/vnd.ms-word.document.macroEnabled.main+xml\",\n]);\n\nexport function findMainDocumentPart(contentTypesXml: string): string | undefined {\n const types = rootEl(parseXml(contentTypesXml, \"[Content_Types].xml\"), \"Types\");\n if (!types) return undefined;\n for (const child of children(types)) {\n if (child.tagName !== \"Override\") continue;\n const ct = attr(child, \"ContentType\");\n const partName = attr(child, \"PartName\");\n if (ct && partName && MAIN_CONTENT_TYPES.has(ct)) {\n return partName.replace(/^\\//, \"\"); // OPC part names are /-rooted; zip entries aren't\n }\n }\n return undefined;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["t", "a", "r", "a", "l", "t", "e", "n", "o", "f", "g", "A", "p", "C", "i", "c", "s", "h", "d", "v", "y", "N", "j", "t", "a", "n", "t", "n"]
7
+ }
@@ -93,7 +93,8 @@ function markerText(def, level, counters) {
93
93
  function styleEq(a, b) {
94
94
  return a.fontFamily === b.fontFamily && a.fontSizePx === b.fontSizePx && a.bold === b.bold && a.italic === b.italic && a.underline === b.underline && a.strikethrough === b.strikethrough && a.color === b.color && !!a.hidden === !!b.hidden && // hidden runs must never merge with visible ones
95
95
  (a.letterSpacingPx ?? 0) === (b.letterSpacingPx ?? 0) && a.highlightColor === b.highlightColor && a.verticalAlign === b.verticalAlign && a.link === b.link && a.footnoteRef === b.footnoteRef && // adjacent refs must never merge into one run
96
- a.sdtId === b.sdtId;
96
+ a.sdtId === b.sdtId && // content-control boundaries survive normalization
97
+ a.fieldId === b.fieldId;
97
98
  }
98
99
  function normalizeRuns(runs, fallback) {
99
100
  const nonEmpty = runs.filter((r) => r.text.length > 0);
@@ -151,6 +152,17 @@ function effectiveFractions(t) {
151
152
  return Array.from({ length: n }, () => 1 / n);
152
153
  }
153
154
 
155
+ // ../shared/src/ids.ts
156
+ function createIdGenerator(siteId, start = 0) {
157
+ let n = start;
158
+ return {
159
+ siteId,
160
+ next: () => `${siteId}-${(n++).toString(36)}`,
161
+ count: () => n
162
+ };
163
+ }
164
+ var active = createIdGenerator("local");
165
+
154
166
  // ../shared/src/toc.ts
155
167
  var rangeOf = (s) => {
156
168
  if (!s) return void 0;
@@ -254,34 +266,46 @@ var TOC_BASE_CHAR = {
254
266
  strikethrough: false,
255
267
  color: "#202124"
256
268
  };
257
- function tocEntryStyle(opts, level, contentWidthPx) {
269
+ function tocEntryStyle(opts, level, contentWidthPx, inherit) {
258
270
  const indentStep = opts.indentStepPx ?? 20;
259
271
  const leader = opts.leader ?? "dot";
260
- const base = { ...TOC_BASE_CHAR, ...opts.baseChar };
261
- const char = { ...base, fontSizePx: level === 1 ? 14 : 13, bold: level === 1, ...opts.levels?.[level]?.char };
262
- const para = {
263
- align: "left",
264
- lineHeight: 1.5,
265
- spaceBeforePx: 0,
266
- spaceAfterPx: 2,
267
- indentFirstLinePx: 0,
268
- indentLeftPx: (level - 1) * indentStep,
269
- ...opts.levels?.[level]?.para
270
- };
272
+ let char;
273
+ let para;
274
+ if (inherit && (inherit.char || inherit.para)) {
275
+ char = { ...TOC_BASE_CHAR, ...inherit.char, ...opts.baseChar, ...opts.levels?.[level]?.char };
276
+ const baseIndent = inherit.para?.indentLeftPx ?? 0;
277
+ para = {
278
+ align: "left",
279
+ lineHeight: 1.5,
280
+ spaceBeforePx: 0,
281
+ spaceAfterPx: 2,
282
+ indentFirstLinePx: 0,
283
+ ...inherit.para,
284
+ indentLeftPx: baseIndent + (level - 1) * indentStep,
285
+ ...opts.levels?.[level]?.para
286
+ };
287
+ } else {
288
+ const base = { ...TOC_BASE_CHAR, ...opts.baseChar };
289
+ char = { ...base, fontSizePx: level === 1 ? 14 : 13, bold: level === 1, ...opts.levels?.[level]?.char };
290
+ para = {
291
+ align: "left",
292
+ lineHeight: 1.5,
293
+ spaceBeforePx: 0,
294
+ spaceAfterPx: 2,
295
+ indentFirstLinePx: 0,
296
+ indentLeftPx: (level - 1) * indentStep,
297
+ ...opts.levels?.[level]?.para
298
+ };
299
+ }
271
300
  if (leader !== "none" && contentWidthPx > 0) para.tabStops = [{ posPx: contentWidthPx, align: "right", leader }];
301
+ else delete para.tabStops;
272
302
  return { char, para };
273
303
  }
274
304
 
275
- // ../shared/src/ids.ts
276
- function createIdGenerator(siteId, start = 0) {
277
- let n = start;
278
- return {
279
- siteId,
280
- next: () => `${siteId}-${(n++).toString(36)}`,
281
- count: () => n
282
- };
305
+ // ../shared/src/model/stylesheet.ts
306
+ function styleType(s) {
307
+ return s.type ?? "paragraph";
283
308
  }
284
- var active = createIdGenerator("local");
285
309
 
286
310
  // ../shared/src/fields.ts
287
311
  var BUILTIN_FIELDS = /* @__PURE__ */ new Set([
@@ -364,9 +388,53 @@ function isCustomFieldInstruction(instr) {
364
388
  return name.length > 0 && !isBuiltinField(name);
365
389
  }
366
390
 
391
+ // ../shared/src/fieldEval.ts
392
+ var IF_OPS = /* @__PURE__ */ new Set(["=", "<>", "<", ">", "<=", ">="]);
393
+ function numFmtFromInstr(raw) {
394
+ if (/\\\*\s*ROMAN\b/.test(raw)) return "Roman";
395
+ if (/\\\*\s*roman\b/.test(raw)) return "roman";
396
+ if (/\\\*\s*ALPHABETIC\b/.test(raw)) return "Alpha";
397
+ if (/\\\*\s*alphabetic\b/.test(raw)) return "alpha";
398
+ return void 0;
399
+ }
400
+ function atFormat(raw) {
401
+ return raw.match(/\\@\s*"([^"]*)"/)?.[1] ?? raw.match(/\\@\s*(\S+)/)?.[1];
402
+ }
403
+ function parseFieldSpec(parsed, baseStyle) {
404
+ switch (parsed.name) {
405
+ case "PAGE": {
406
+ const f = numFmtFromInstr(parsed.raw);
407
+ return f ? { type: "PAGE", numFmt: f } : { type: "PAGE" };
408
+ }
409
+ case "NUMPAGES": {
410
+ const f = numFmtFromInstr(parsed.raw);
411
+ return f ? { type: "NUMPAGES", numFmt: f } : { type: "NUMPAGES" };
412
+ }
413
+ case "DATE":
414
+ return { type: "DATE", format: atFormat(parsed.raw) ?? "M/d/yyyy" };
415
+ case "TIME":
416
+ return { type: "TIME", format: atFormat(parsed.raw) ?? "h:mm AM/PM" };
417
+ case "IF": {
418
+ const [operandA, op, operandB, trueText, falseText] = parsed.args;
419
+ if (operandA === void 0 || op === void 0 || operandB === void 0 || !IF_OPS.has(op)) return void 0;
420
+ return {
421
+ type: "IF",
422
+ operandA,
423
+ op,
424
+ operandB,
425
+ trueRuns: [{ text: trueText ?? "", style: { ...baseStyle } }],
426
+ falseRuns: [{ text: falseText ?? "", style: { ...baseStyle } }]
427
+ };
428
+ }
429
+ default:
430
+ return void 0;
431
+ }
432
+ }
433
+
367
434
  export {
368
435
  isHiddenParagraph,
369
436
  textOfRuns,
437
+ styleType,
370
438
  formatListNumber,
371
439
  markerText,
372
440
  normalizeRuns,
@@ -377,6 +445,7 @@ export {
377
445
  markImportedTocEntries,
378
446
  tocEntryStyle,
379
447
  parseFieldInstruction,
380
- isCustomFieldInstruction
448
+ isCustomFieldInstruction,
449
+ parseFieldSpec
381
450
  };
382
- //# sourceMappingURL=chunk-XDUDPPJW.js.map
451
+ //# sourceMappingURL=chunk-PIMVQULL.js.map