@office-open/docx 0.9.8 → 0.10.1

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.
@@ -1,5 +1,5 @@
1
- import { DOCX_PARTS, Relationships, TargetModeType, ThemeColor, blipDesc, buildContentTypeOverrides, convertEmuToPixels, convertInchesToTwip, convertPixelsToEmu, convertToEmu, convertToTwip, convertUniversalMeasureToEmu, customGeometryDesc, decimalNumber, derivePasswordHash, effectListDesc, eighthPointMeasureValue, fillDesc, hexColorValue, hpsMeasureValue, measurementOrPercentValue, outlineDesc, parseColorChoice, pointMeasureValue, signedTwipsMeasureValue, toUint8Array, twipsMeasureValue, uCharHexNumber, uniqueId, uniqueNumericIdCreator, uniqueUuid, xsdVerticalMergeRev } from "@office-open/core";
2
- import { attr, attrBool, attrNum, children, colorAttr, element, escapeXml, findChild, findDeep, stringify, textOf } from "@office-open/xml";
1
+ import { DOCX_PARTS, Relationships, TargetModeType, ThemeColor, appPropertiesDesc, blipDesc, buildContentTypeOverrides, convertEmuToPixels, convertInchesToTwip, convertPixelsToEmu, convertToEmu, convertToTwip, convertUniversalMeasureToEmu, customGeometryDesc, customPropertiesDesc, decimalNumber, derivePasswordHash, effectListDesc, eighthPointMeasureValue, fillDesc, hexColorValue, hpsMeasureValue, measurementOrPercentValue, outlineDesc, parseColorChoice, pointMeasureValue, signedTwipsMeasureValue, toUint8Array, twipsMeasureValue, uCharHexNumber, uniqueId, uniqueNumericIdCreator, uniqueUuid, xsdVerticalMergeRev } from "@office-open/core";
2
+ import { attr, attrBool, attrMeasure, attrNum, children, colorAttr, element, escapeXml, findChild, findDeep, stringify, textOf } from "@office-open/xml";
3
3
  import { calculateEffectExtent, createColorElement, createEffectDag, createScene3D, createShape3D, customGeometryDesc as customGeometryDesc$1, effectListDesc as effectListDesc$1, extractBlipFillMedia, fillDesc as fillDesc$1, outlineDesc as outlineDesc$1, scene3DDesc, shape3DDesc, transform2DDesc } from "@office-open/core/drawingml";
4
4
  import { chartSpaceDesc } from "@office-open/core/chart";
5
5
  import { createDataModel } from "@office-open/core/smartart";
@@ -76,16 +76,6 @@ const AlignmentType = {
76
76
  //#endregion
77
77
  //#region src/parts/paragraph/formatting/spacing.ts
78
78
  /**
79
- * Paragraph spacing module for WordprocessingML documents.
80
- *
81
- * This module provides spacing options for paragraphs including space before,
82
- * space after, and line spacing.
83
- *
84
- * Reference: http://officeopenxml.com/WPspacing.php
85
- *
86
- * @module
87
- */
88
- /**
89
79
  * Line spacing rule types.
90
80
  *
91
81
  * Specifies how the line height is calculated.
@@ -177,6 +167,18 @@ const TextboxTightWrapType = {
177
167
  //#endregion
178
168
  //#region src/parts/paragraph/run/run.ts
179
169
  /**
170
+ * Serialize a break option (count shorthand or structured with clear) to one or
171
+ * more `<w:br/>` tags.
172
+ */
173
+ function breakXml(breakOpt) {
174
+ if (!breakOpt) return "";
175
+ const count = typeof breakOpt === "number" ? breakOpt : breakOpt.count ?? 1;
176
+ if (count <= 0) return "";
177
+ const clear = typeof breakOpt === "object" ? breakOpt.clear : void 0;
178
+ const one = clear ? `<w:br w:clear="${clear}"/>` : "<w:br/>";
179
+ return count === 1 ? one : one.repeat(count);
180
+ }
181
+ /**
180
182
  * Constants for page number field types.
181
183
  *
182
184
  * These values are used to insert dynamic page number fields into a document.
@@ -570,13 +572,13 @@ const parseBodyProperties = (el) => {
570
572
  if (vert !== void 0) result.vert = vert;
571
573
  const wrap = attr(el, "wrap");
572
574
  if (wrap !== void 0) result.wrap = wrap;
573
- const lIns = attrNum(el, "lIns");
575
+ const lIns = attrMeasure(el, "lIns");
574
576
  if (lIns !== void 0) result.lIns = lIns;
575
- const tIns = attrNum(el, "tIns");
577
+ const tIns = attrMeasure(el, "tIns");
576
578
  if (tIns !== void 0) result.tIns = tIns;
577
- const rIns = attrNum(el, "rIns");
579
+ const rIns = attrMeasure(el, "rIns");
578
580
  if (rIns !== void 0) result.rIns = rIns;
579
- const bIns = attrNum(el, "bIns");
581
+ const bIns = attrMeasure(el, "bIns");
580
582
  if (bIns !== void 0) result.bIns = bIns;
581
583
  const numCol = attrNum(el, "numCol");
582
584
  if (numCol !== void 0) result.numCol = numCol;
@@ -1328,6 +1330,149 @@ const WidthType = {
1328
1330
  PERCENTAGE: "pct"
1329
1331
  };
1330
1332
  //#endregion
1333
+ //#region src/parts/object/object-element.ts
1334
+ /**
1335
+ * Object element for WordprocessingML documents — w:object.
1336
+ *
1337
+ * Embeds an OLE object (e.g. an Excel sheet) in a run via a VML preview shape and
1338
+ * exactly one of objectEmbed / objectLink / control / movie. The OLE binary is
1339
+ * registered as word/embeddings/oleObjectN.bin (EmbeddingCollection); the optional
1340
+ * preview icon as word/media/imageN.<type> (Media). Relationship ids are emitted
1341
+ * as `{fileName}` placeholders and rewritten by the compiler's media bridge.
1342
+ *
1343
+ * Reference: OOXML transitional, wml.xsd, CT_Object / CT_ObjectEmbed / CT_ObjectLink
1344
+ *
1345
+ * @module
1346
+ */
1347
+ let objectShapeCounter = 1025;
1348
+ const objectDesc = {
1349
+ kind: "custom",
1350
+ stringify(opts, ctx) {
1351
+ const inner = [];
1352
+ const shapeId = opts.shapeId ?? `_x0000_i${objectShapeCounter++}`;
1353
+ const widthVal = opts.width ?? 100;
1354
+ const heightVal = opts.height ?? 100;
1355
+ const styleWidth = typeof widthVal === "number" ? `${widthVal}px` : widthVal;
1356
+ const styleHeight = typeof heightVal === "number" ? `${heightVal}px` : heightVal;
1357
+ const shapeChildren = [];
1358
+ if (opts.iconImage) {
1359
+ const iconFileName = ctx.file.media.nextMediaName(opts.iconImage.type);
1360
+ const iconMediaData = {
1361
+ type: opts.iconImage.type,
1362
+ ...createImageData$1(toUint8Array(opts.iconImage.data), {
1363
+ width: widthVal,
1364
+ height: heightVal
1365
+ }, iconFileName)
1366
+ };
1367
+ ctx.file.media.addImage(iconFileName, iconMediaData);
1368
+ const titleAttr = opts.iconImage.title ? ` o:title="${opts.iconImage.title}"` : "";
1369
+ shapeChildren.push(`<v:imagedata r:id="{${iconFileName}}"${titleAttr}/>`);
1370
+ }
1371
+ inner.push(`<v:shape id="${shapeId}" type="#_x0000_t75" style="width:${styleWidth};height:${styleHeight}">${shapeChildren.join("")}</v:shape>`);
1372
+ if (opts.embed) {
1373
+ const fileName = registerEmbedding(opts.embed, ctx);
1374
+ inner.push(`<w:objectEmbed r:id="{${fileName}}"${embedAttrs(opts.embed)}/>`);
1375
+ } else if (opts.link) {
1376
+ const fileName = registerEmbedding(opts.link, ctx);
1377
+ const locked = opts.link.lockedField ? ` w:lockedField="true"` : "";
1378
+ inner.push(`<w:objectLink r:id="{${fileName}}"${embedAttrs(opts.link)} w:updateMode="${opts.link.updateMode}"${locked}/>`);
1379
+ } else if (opts.control) {
1380
+ const c = opts.control;
1381
+ const cAttrs = [` r:id="${c.rId}"`];
1382
+ if (c.name) cAttrs.push(` w:name="${c.name}"`);
1383
+ if (c.shapeid) cAttrs.push(` w:shapeid="${c.shapeid}"`);
1384
+ inner.push(`<w:control${cAttrs.join("")}/>`);
1385
+ } else if (opts.movie) inner.push(`<w:movie r:id="${opts.movie}"/>`);
1386
+ const objAttrs = [];
1387
+ if (opts.dxaOrig !== void 0) objAttrs.push(` w:dxaOrig="${opts.dxaOrig}"`);
1388
+ if (opts.dyaOrig !== void 0) objAttrs.push(` w:dyaOrig="${opts.dyaOrig}"`);
1389
+ return `<w:object${objAttrs.join("")}>${inner.join("")}</w:object>`;
1390
+ },
1391
+ parse(el, _ctx) {
1392
+ const result = {};
1393
+ const dxaOrig = attrNum(el, "w:dxaOrig");
1394
+ if (dxaOrig !== void 0) result.dxaOrig = dxaOrig;
1395
+ const dyaOrig = attrNum(el, "w:dyaOrig");
1396
+ if (dyaOrig !== void 0) result.dyaOrig = dyaOrig;
1397
+ const shape = findChild(el, "v:shape");
1398
+ if (shape) {
1399
+ const id = attr(shape, "id");
1400
+ if (id) result.shapeId = id;
1401
+ const style = attr(shape, "style");
1402
+ if (style) {
1403
+ const w = style.match(/width:([^;]+)/);
1404
+ const h = style.match(/height:([^;]+)/);
1405
+ if (w) result.width = w[1].trim();
1406
+ if (h) result.height = h[1].trim();
1407
+ }
1408
+ }
1409
+ const embedEl = findChild(el, "w:objectEmbed");
1410
+ if (embedEl) result.embed = parseEmbed(embedEl);
1411
+ const linkEl = findChild(el, "w:objectLink");
1412
+ if (linkEl) {
1413
+ const base = parseEmbed(linkEl);
1414
+ const updateMode = attr(linkEl, "w:updateMode");
1415
+ const lockedField = attr(linkEl, "w:lockedField");
1416
+ result.link = {
1417
+ ...base,
1418
+ ...updateMode ? { updateMode } : {},
1419
+ ...lockedField !== void 0 ? { lockedField: lockedField === "true" || lockedField === "1" } : {}
1420
+ };
1421
+ }
1422
+ const controlEl = findChild(el, "w:control");
1423
+ if (controlEl) {
1424
+ const rId = attr(controlEl, "r:id") ?? "";
1425
+ const name = attr(controlEl, "w:name");
1426
+ const shapeid = attr(controlEl, "w:shapeid");
1427
+ result.control = {
1428
+ rId,
1429
+ ...name ? { name } : {},
1430
+ ...shapeid ? { shapeid } : {}
1431
+ };
1432
+ }
1433
+ const movieEl = findChild(el, "w:movie");
1434
+ if (movieEl) {
1435
+ const rId = attr(movieEl, "r:id");
1436
+ if (rId) result.movie = rId;
1437
+ }
1438
+ return result;
1439
+ }
1440
+ };
1441
+ /** Register an OLE embedding and return its allocated file name. */
1442
+ function registerEmbedding(opts, ctx) {
1443
+ const fileName = ctx.file.embeddings.nextEmbeddingName();
1444
+ const data = {
1445
+ fileName,
1446
+ data: toUint8Array(opts.data),
1447
+ ...opts.progId ? { progId: opts.progId } : {}
1448
+ };
1449
+ ctx.file.embeddings.addEmbedding(fileName, data);
1450
+ return fileName;
1451
+ }
1452
+ /** Build the common objectEmbed/objectLink attribute string (excludes r:id). */
1453
+ function embedAttrs(opts) {
1454
+ const attrs = [];
1455
+ if (opts.drawAspect) attrs.push(` w:drawAspect="${opts.drawAspect}"`);
1456
+ if (opts.progId) attrs.push(` w:progId="${opts.progId}"`);
1457
+ if (opts.shapeId) attrs.push(` w:shapeId="${opts.shapeId}"`);
1458
+ if (opts.fieldCodes) attrs.push(` w:fieldCodes="${opts.fieldCodes}"`);
1459
+ return attrs.join("");
1460
+ }
1461
+ /** Parse common objectEmbed/objectLink attributes (excludes r:id — external on parse). */
1462
+ function parseEmbed(el) {
1463
+ const opts = {};
1464
+ const drawAspect = attr(el, "w:drawAspect");
1465
+ if (drawAspect === "content" || drawAspect === "icon") opts.drawAspect = drawAspect;
1466
+ const progId = attr(el, "w:progId");
1467
+ if (progId) opts.progId = progId;
1468
+ const shapeId = attr(el, "w:shapeId");
1469
+ if (shapeId) opts.shapeId = shapeId;
1470
+ const fieldCodes = attr(el, "w:fieldCodes");
1471
+ if (fieldCodes) opts.fieldCodes = fieldCodes;
1472
+ opts.data = new Uint8Array();
1473
+ return opts;
1474
+ }
1475
+ //#endregion
1331
1476
  //#region src/util/stringify-element.ts
1332
1477
  /**
1333
1478
  * Element-to-XML serialization helpers shared across the parse layer.
@@ -1375,8 +1520,12 @@ function parseRunProperties(el) {
1375
1520
  const eastAsia = attr(font, "w:eastAsia");
1376
1521
  const hAnsi = attr(font, "w:hAnsi");
1377
1522
  const cs = attr(font, "w:cs");
1523
+ const asciiTheme = attr(font, "w:asciiTheme");
1524
+ const eastAsiaTheme = attr(font, "w:eastAsiaTheme");
1525
+ const hAnsiTheme = attr(font, "w:hAnsiTheme");
1526
+ const cstheme = attr(font, "w:cstheme");
1378
1527
  const hint = attr(font, "w:hint");
1379
- if (ascii && !eastAsia && !hAnsi && !cs) opts.font = hint ? {
1528
+ if (ascii && !eastAsia && !hAnsi && !cs && !asciiTheme && !eastAsiaTheme && !hAnsiTheme && !cstheme) opts.font = hint ? {
1380
1529
  name: ascii,
1381
1530
  hint
1382
1531
  } : ascii;
@@ -1386,6 +1535,10 @@ function parseRunProperties(el) {
1386
1535
  if (eastAsia) fontObj.eastAsia = eastAsia;
1387
1536
  if (hAnsi) fontObj.hAnsi = hAnsi;
1388
1537
  if (cs) fontObj.cs = cs;
1538
+ if (asciiTheme) fontObj.asciiTheme = asciiTheme;
1539
+ if (eastAsiaTheme) fontObj.eastAsiaTheme = eastAsiaTheme;
1540
+ if (hAnsiTheme) fontObj.hAnsiTheme = hAnsiTheme;
1541
+ if (cstheme) fontObj.cstheme = cstheme;
1389
1542
  if (hint) fontObj.hint = hint;
1390
1543
  opts.font = fontObj;
1391
1544
  }
@@ -1481,7 +1634,7 @@ function parseRunProperties(el) {
1481
1634
  }
1482
1635
  const spacing = findChild(el, "w:spacing");
1483
1636
  if (spacing) {
1484
- const val = attrNum(spacing, "w:val");
1637
+ const val = attrMeasure(spacing, "w:val");
1485
1638
  if (val !== void 0) opts.characterSpacing = val;
1486
1639
  }
1487
1640
  const scale = findChild(el, "w:w");
@@ -1638,8 +1791,10 @@ const PARSED_LAST_RENDERED_PAGE_BREAK = Symbol("LastRenderedPageBreak");
1638
1791
  function parseRun(el, _ctx) {
1639
1792
  const rPr = findChild(el, "w:rPr");
1640
1793
  const properties = rPr ? parseRunProperties(rPr) : void 0;
1641
- const rPrRawXml = rPr ? stringifyElement(rPr) : void 0;
1642
1794
  const children = [];
1795
+ const rsid = attr(el, "w:rsidR");
1796
+ const runPropertiesRsid = attr(el, "w:rsidRPr");
1797
+ const deletionRsid = attr(el, "w:rsidDel");
1643
1798
  for (const child of el.elements ?? []) switch (child.name) {
1644
1799
  case "w:rPr": break;
1645
1800
  case "w:t": {
@@ -1656,8 +1811,13 @@ function parseRun(el, _ctx) {
1656
1811
  }
1657
1812
  case "w:br": {
1658
1813
  const brType = attr(child, "w:type");
1814
+ const brClear = attr(child, "w:clear");
1659
1815
  if (brType === "page") children.push(PARSED_PAGE_BREAK);
1660
1816
  else if (brType === "column") children.push(PARSED_COLUMN_BREAK);
1817
+ else if (brClear) children.push({ break: {
1818
+ count: 1,
1819
+ clear: brClear
1820
+ } });
1661
1821
  else children.push(PARSED_LINE_BREAK);
1662
1822
  break;
1663
1823
  }
@@ -1680,6 +1840,9 @@ function parseRun(el, _ctx) {
1680
1840
  }
1681
1841
  case "w:drawing":
1682
1842
  case "w:pict": break;
1843
+ case "w:object":
1844
+ children.push({ object: objectDesc.parse(child, _ctx) });
1845
+ break;
1683
1846
  case "w:sym": {
1684
1847
  const charVal = attr(child, "w:char");
1685
1848
  const fontVal = attr(child, "w:font");
@@ -1691,12 +1854,24 @@ function parseRun(el, _ctx) {
1691
1854
  }
1692
1855
  case "w:footnoteReference": {
1693
1856
  const id = attrNum(child, "w:id");
1694
- if (id !== void 0) children.push({ footnoteReference: id });
1857
+ if (id !== void 0) {
1858
+ const customMarkFollows = attrBool(child, "w:customMarkFollows") === true;
1859
+ children.push(customMarkFollows ? { footnoteReference: {
1860
+ id,
1861
+ customMarkFollows: true
1862
+ } } : { footnoteReference: id });
1863
+ }
1695
1864
  break;
1696
1865
  }
1697
1866
  case "w:endnoteReference": {
1698
1867
  const id = attrNum(child, "w:id");
1699
- if (id !== void 0) children.push({ endnoteReference: id });
1868
+ if (id !== void 0) {
1869
+ const customMarkFollows = attrBool(child, "w:customMarkFollows") === true;
1870
+ children.push(customMarkFollows ? { endnoteReference: {
1871
+ id,
1872
+ customMarkFollows: true
1873
+ } } : { endnoteReference: id });
1874
+ }
1700
1875
  break;
1701
1876
  }
1702
1877
  case "w:footnoteRef":
@@ -1740,8 +1915,10 @@ function parseRun(el, _ctx) {
1740
1915
  }
1741
1916
  return {
1742
1917
  properties,
1743
- rPrRawXml,
1744
- children
1918
+ children,
1919
+ rsid,
1920
+ runPropertiesRsid,
1921
+ deletionRsid
1745
1922
  };
1746
1923
  }
1747
1924
  /**
@@ -1775,15 +1952,26 @@ function parsedRunToOptions(parsed) {
1775
1952
  const contentChildren = parsed.children.filter((c) => c !== PARSED_FOOTNOTE_REF);
1776
1953
  if (contentChildren.length === 0 && parsed.children.some((c) => c === PARSED_FOOTNOTE_REF)) return null;
1777
1954
  const opts = { ...parsed.properties };
1778
- if (parsed.rPrRawXml) opts.rPrRawXml = parsed.rPrRawXml;
1955
+ if (parsed.rsid) opts.rsid = parsed.rsid;
1956
+ if (parsed.runPropertiesRsid) opts.runPropertiesRsid = parsed.runPropertiesRsid;
1957
+ if (parsed.deletionRsid) opts.deletionRsid = parsed.deletionRsid;
1779
1958
  const isRefChild = (c) => typeof c === "object" && c !== null && ("commentReference" in c || "footnoteReference" in c || "endnoteReference" in c);
1780
1959
  const refChildren = contentChildren.filter(isRefChild);
1781
1960
  const nonRefChildren = contentChildren.filter((c) => !isRefChild(c));
1782
1961
  if (refChildren.length > 0 && nonRefChildren.length === 0) return refChildren[0];
1783
1962
  const symbolIdx = nonRefChildren.findIndex((c) => typeof c === "object" && c !== null && "symbolRun" in c);
1784
1963
  if (symbolIdx >= 0 && nonRefChildren.length === 1 && !parsed.properties) return nonRefChildren[symbolIdx];
1964
+ const objectIdx = nonRefChildren.findIndex((c) => typeof c === "object" && c !== null && "object" in c);
1965
+ if (objectIdx >= 0) {
1966
+ const objectChild = nonRefChildren[objectIdx];
1967
+ return {
1968
+ ...parsed.properties,
1969
+ ...objectChild
1970
+ };
1971
+ }
1785
1972
  const textParts = [];
1786
1973
  let breakCount = 0;
1974
+ const structuredBreaks = [];
1787
1975
  let hasPageBreak = false;
1788
1976
  let hasColumnBreak = false;
1789
1977
  const extraChildren = [];
@@ -1791,16 +1979,19 @@ function parsedRunToOptions(parsed) {
1791
1979
  else if (child === PARSED_LINE_BREAK) breakCount++;
1792
1980
  else if (child === PARSED_PAGE_BREAK) hasPageBreak = true;
1793
1981
  else if (child === PARSED_COLUMN_BREAK) hasColumnBreak = true;
1982
+ else if (typeof child === "object" && child !== null && "break" in child) structuredBreaks.push(child.break);
1794
1983
  else {
1795
1984
  const mapped = SYMBOL_TO_CHILD.get(child);
1796
1985
  if (mapped) extraChildren.push(mapped);
1797
1986
  }
1798
- if (extraChildren.length > 0) {
1987
+ const hasStructuredBreaks = structuredBreaks.length > 0;
1988
+ if (extraChildren.length > 0 || hasStructuredBreaks && (breakCount > 0 || structuredBreaks.length > 1 || hasPageBreak || hasColumnBreak)) {
1799
1989
  const children = [];
1800
1990
  for (const child of nonRefChildren) if (typeof child === "string") children.push(child);
1801
1991
  else if (child === PARSED_LINE_BREAK) children.push({ break: 1 });
1802
1992
  else if (child === PARSED_PAGE_BREAK) children.push({ pageBreak: true });
1803
1993
  else if (child === PARSED_COLUMN_BREAK) children.push({ columnBreak: true });
1994
+ else if (typeof child === "object" && child !== null && "break" in child) children.push({ break: child.break });
1804
1995
  else {
1805
1996
  const mapped = SYMBOL_TO_CHILD.get(child);
1806
1997
  if (mapped) children.push(mapped);
@@ -1809,6 +2000,7 @@ function parsedRunToOptions(parsed) {
1809
2000
  } else {
1810
2001
  if (textParts.length > 0) opts.text = textParts.join("");
1811
2002
  if (breakCount > 0) opts.break = breakCount;
2003
+ else if (hasStructuredBreaks) opts.break = structuredBreaks[0];
1812
2004
  if (hasPageBreak) opts.pageBreak = true;
1813
2005
  if (hasColumnBreak) opts.columnBreak = true;
1814
2006
  }
@@ -1864,13 +2056,13 @@ function shadingStr(opts) {
1864
2056
  }
1865
2057
  function spacingStr(opts) {
1866
2058
  return `<w:spacing ${attrParts({
1867
- "w:after": opts.after,
2059
+ "w:after": opts.after !== void 0 ? twipsMeasureValue(opts.after) : void 0,
1868
2060
  "w:afterAutospacing": opts.afterAutoSpacing !== void 0 ? opts.afterAutoSpacing ? 1 : 0 : void 0,
1869
2061
  "w:afterLines": opts.afterLines !== void 0 ? decimalNumber(opts.afterLines) : void 0,
1870
- "w:before": opts.before,
2062
+ "w:before": opts.before !== void 0 ? twipsMeasureValue(opts.before) : void 0,
1871
2063
  "w:beforeAutospacing": opts.beforeAutoSpacing !== void 0 ? opts.beforeAutoSpacing ? 1 : 0 : void 0,
1872
2064
  "w:beforeLines": opts.beforeLines !== void 0 ? decimalNumber(opts.beforeLines) : void 0,
1873
- "w:line": opts.line,
2065
+ "w:line": opts.line !== void 0 ? twipsMeasureValue(opts.line) : void 0,
1874
2066
  "w:lineRule": opts.lineRule
1875
2067
  })}/>`;
1876
2068
  }
@@ -2133,9 +2325,9 @@ function stringifyRunPropertiesInner(opts) {
2133
2325
  else if ("name" in opts.font) parts.push(runFontsStr(opts.font.name, opts.font.hint));
2134
2326
  else parts.push(runFontsStr(opts.font));
2135
2327
  if (opts.bold !== void 0) parts.push(onOff$1("w:b", opts.bold));
2136
- if ((opts.boldComplexScript === void 0 && opts.bold !== void 0 || opts.boldComplexScript) !== void 0) parts.push(onOff$1("w:bCs", opts.boldComplexScript ?? opts.bold));
2328
+ if (opts.boldComplexScript !== void 0) parts.push(onOff$1("w:bCs", opts.boldComplexScript));
2137
2329
  if (opts.italic !== void 0) parts.push(onOff$1("w:i", opts.italic));
2138
- if ((opts.italicComplexScript === void 0 && opts.italic !== void 0 || opts.italicComplexScript) !== void 0) parts.push(onOff$1("w:iCs", opts.italicComplexScript ?? opts.italic));
2330
+ if (opts.italicComplexScript !== void 0) parts.push(onOff$1("w:iCs", opts.italicComplexScript));
2139
2331
  if (opts.smallCaps !== void 0) parts.push(onOff$1("w:smallCaps", opts.smallCaps));
2140
2332
  else if (opts.allCaps !== void 0) parts.push(onOff$1("w:caps", opts.allCaps));
2141
2333
  if (opts.strike !== void 0) parts.push(onOff$1("w:strike", opts.strike));
@@ -2154,12 +2346,9 @@ function stringifyRunPropertiesInner(opts) {
2154
2346
  if (opts.kern !== void 0) parts.push(`<w:kern w:val="${hpsMeasureValue(opts.kern)}"/>`);
2155
2347
  if (opts.position) parts.push(`<w:position w:val="${opts.position}"/>`);
2156
2348
  if (opts.size !== void 0) parts.push(`<w:sz w:val="${hpsMeasureValue(opts.size * 2)}"/>`);
2157
- const szCs = opts.sizeComplexScript === void 0 || opts.sizeComplexScript === true ? opts.size : opts.sizeComplexScript;
2158
- if (szCs) parts.push(`<w:szCs w:val="${hpsMeasureValue(szCs * 2)}"/>`);
2349
+ if (opts.sizeComplexScript !== void 0) parts.push(`<w:szCs w:val="${hpsMeasureValue(opts.sizeComplexScript * 2)}"/>`);
2159
2350
  if (opts.highlight) parts.push(`<w:highlight w:val="${opts.highlight}"/>`);
2160
- if (opts.highlightComplexScript === true) {
2161
- if (opts.highlight) parts.push(`<w:highlightCs w:val="${opts.highlight}"/>`);
2162
- } else if (opts.highlightComplexScript !== void 0 && opts.highlightComplexScript !== false) parts.push(`<w:highlightCs w:val="${opts.highlightComplexScript}"/>`);
2351
+ if (opts.highlightComplexScript !== void 0) parts.push(`<w:highlightCs w:val="${opts.highlightComplexScript}"/>`);
2163
2352
  if (opts.underline) parts.push(underlineStr(opts.underline.type, opts.underline.color));
2164
2353
  if (opts.effect) parts.push(`<w:effect w:val="${opts.effect}"/>`);
2165
2354
  if (opts.border) parts.push(borderStr("w:bdr", opts.border));
@@ -3284,32 +3473,6 @@ const PageOrientation = {
3284
3473
  */
3285
3474
  LANDSCAPE: "landscape"
3286
3475
  };
3287
- /**
3288
- * This element specifies the properties (size and orientation) for all pages in the current section.
3289
- *
3290
- * Reference: https://c-rex.net/samples/ooxml/e1/Part4/OOXML_P4_DOCX_pgSz_topic_ID0ENEDT.html?hl=pgsz%2Cpage%2Csize
3291
- *
3292
- * ## XSD Schema
3293
- *
3294
- * ```xml
3295
- * <xsd:complexType name="CT_PageSz">
3296
- * <xsd:attribute name="w" type="s:ST_TwipsMeasure"/>
3297
- * <xsd:attribute name="h" type="s:ST_TwipsMeasure"/>
3298
- * <xsd:attribute name="orient" type="ST_PageOrientation" use="optional"/>
3299
- * <xsd:attribute name="code" type="ST_DecimalNumber" use="optional"/>
3300
- * </xsd:complexType>
3301
- * ```
3302
- */
3303
- const createPageSize = ({ width = 11906, height = 16838, orientation, code }) => {
3304
- const widthTwips = twipsMeasureValue(width);
3305
- const heightTwips = twipsMeasureValue(height);
3306
- return element("w:pgSz", {
3307
- "w:code": code,
3308
- "w:h": orientation === PageOrientation.LANDSCAPE ? widthTwips : heightTwips,
3309
- "w:orient": orientation,
3310
- "w:w": orientation === PageOrientation.LANDSCAPE ? heightTwips : widthTwips
3311
- });
3312
- };
3313
3476
  //#endregion
3314
3477
  //#region src/parts/document/body/section-properties/properties/page-text-direction.ts
3315
3478
  /**
@@ -3484,8 +3647,10 @@ function stringifySectionPropertiesInner(opts) {
3484
3647
  if (opts.footnotePr) parts.push(footnotePrXml("w:footnotePr", opts.footnotePr));
3485
3648
  if (opts.endnotePr) parts.push(footnotePrXml("w:endnotePr", opts.endnotePr));
3486
3649
  if (opts.type) parts.push(sectionTypeXml(opts.type));
3487
- const pgW = orientation === "landscape" ? convertToTwip(height) : width;
3488
- const pgH = orientation === "landscape" ? convertToTwip(width) : height;
3650
+ const wTwips = convertToTwip(width);
3651
+ const hTwips = convertToTwip(height);
3652
+ const pgW = orientation === "landscape" ? hTwips : wTwips;
3653
+ const pgH = orientation === "landscape" ? wTwips : hTwips;
3489
3654
  parts.push(pageSizeXml(pgW, pgH, orientation, code));
3490
3655
  parts.push(pageMarginXml(top, right, bottom, left, header, footer, gutter));
3491
3656
  if (borders) parts.push(pageBordersXml(borders));
@@ -3535,20 +3700,20 @@ const sectionPropertiesDesc = {
3535
3700
  function stringifySectionPropertiesXml(opts) {
3536
3701
  const inner = stringifySectionPropertiesInner(opts);
3537
3702
  const attrs = [];
3538
- if (opts.rsidRPr !== void 0) attrs.push(`w:rsidRPr="${opts.rsidRPr}"`);
3539
- if (opts.rsidDel !== void 0) attrs.push(`w:rsidDel="${opts.rsidDel}"`);
3540
- if (opts.rsidR !== void 0) attrs.push(`w:rsidR="${opts.rsidR}"`);
3541
- if (opts.rsidSect !== void 0) attrs.push(`w:rsidSect="${opts.rsidSect}"`);
3703
+ if (opts.runPropertiesRsid !== void 0) attrs.push(`w:rsidRPr="${opts.runPropertiesRsid}"`);
3704
+ if (opts.deletionRsid !== void 0) attrs.push(`w:rsidDel="${opts.deletionRsid}"`);
3705
+ if (opts.rsid !== void 0) attrs.push(`w:rsidR="${opts.rsid}"`);
3706
+ if (opts.sectionRsid !== void 0) attrs.push(`w:rsidSect="${opts.sectionRsid}"`);
3542
3707
  return `<w:sectPr${attrs.length ? " " + attrs.join(" ") : ""}>${inner}</w:sectPr>`;
3543
3708
  }
3544
3709
  /** Parse a w:sectPr element into SectionPropertiesOptions. */
3545
3710
  function parseSectionPropertiesEl(el) {
3546
3711
  const opts = {};
3547
3712
  for (const [attrName, optKey] of [
3548
- ["w:rsidR", "rsidR"],
3549
- ["w:rsidRPr", "rsidRPr"],
3550
- ["w:rsidDel", "rsidDel"],
3551
- ["w:rsidSect", "rsidSect"]
3713
+ ["w:rsidR", "rsid"],
3714
+ ["w:rsidRPr", "runPropertiesRsid"],
3715
+ ["w:rsidDel", "deletionRsid"],
3716
+ ["w:rsidSect", "sectionRsid"]
3552
3717
  ]) {
3553
3718
  const val = attr(el, attrName);
3554
3719
  if (val) opts[optKey] = val;
@@ -3608,7 +3773,7 @@ function parseSectionPropertiesEl(el) {
3608
3773
  const column = {};
3609
3774
  const count = attrNum(cols, "w:num");
3610
3775
  if (count !== void 0) column.count = count;
3611
- const space = attrNum(cols, "w:space");
3776
+ const space = attrMeasure(cols, "w:space");
3612
3777
  if (space !== void 0) column.space = space;
3613
3778
  const separate = attrBool(cols, "w:sep");
3614
3779
  if (separate !== void 0) column.separate = separate;
@@ -3617,10 +3782,10 @@ function parseSectionPropertiesEl(el) {
3617
3782
  const colChildren = [];
3618
3783
  for (const colEl of cols.elements ?? []) {
3619
3784
  if (colEl.name !== "w:col") continue;
3620
- const width = attrNum(colEl, "w:w");
3785
+ const width = attrMeasure(colEl, "w:w");
3621
3786
  if (width === void 0) continue;
3622
3787
  const colAttr = { width };
3623
- const colSpace = attrNum(colEl, "w:space");
3788
+ const colSpace = attrMeasure(colEl, "w:space");
3624
3789
  if (colSpace !== void 0) colAttr.space = colSpace;
3625
3790
  colChildren.push(colAttr);
3626
3791
  }
@@ -3747,6 +3912,19 @@ function parseSectionPropertiesEl(el) {
3747
3912
  }
3748
3913
  if (Object.keys(headerGroup).length > 0) opts.headerWrapperGroup = headerGroup;
3749
3914
  if (Object.keys(footerGroup).length > 0) opts.footerWrapperGroup = footerGroup;
3915
+ const sectPrChange = findChild(el, "w:sectPrChange");
3916
+ if (sectPrChange) {
3917
+ const rev = {};
3918
+ const author = attr(sectPrChange, "w:author");
3919
+ if (author) rev.author = author;
3920
+ const revDate = attr(sectPrChange, "w:date");
3921
+ if (revDate) rev.date = revDate;
3922
+ const revId = attrNum(sectPrChange, "w:id");
3923
+ if (revId !== void 0) rev.id = revId;
3924
+ const innerSectPr = findChild(sectPrChange, "w:sectPr");
3925
+ if (innerSectPr) Object.assign(rev, parseSectionPropertiesEl(innerSectPr));
3926
+ if (Object.keys(rev).length > 0) opts.revision = rev;
3927
+ }
3750
3928
  return opts;
3751
3929
  }
3752
3930
  function parseNotePropertiesEl(el) {
@@ -4056,7 +4234,7 @@ function stringifyMathInput(value) {
4056
4234
  if (typeof value !== "object" || value === null) return "";
4057
4235
  if ("subSuperScript" in value) {
4058
4236
  const opts = value.subSuperScript;
4059
- return `<m:sSubSup><m:sSubSupPr/><m:e>${stringifyChildren(opts.children)}</m:e><m:sub>${stringifyChildren(opts.subScript)}</m:sub><m:sup>${stringifyChildren(opts.superScript)}</m:sup></m:sSubSup>`;
4237
+ return `<m:sSubSup>${opts.alignScript ? "<m:sSubSupPr><m:alnScr m:val=\"1\"/></m:sSubSupPr>" : "<m:sSubSupPr/>"}<m:e>${stringifyChildren(opts.children)}</m:e><m:sub>${stringifyChildren(opts.subScript)}</m:sub><m:sup>${stringifyChildren(opts.superScript)}</m:sup></m:sSubSup>`;
4060
4238
  }
4061
4239
  if ("preSubSuperScript" in value) {
4062
4240
  const opts = value.preSubSuperScript;
@@ -4072,7 +4250,10 @@ function stringifyMathInput(value) {
4072
4250
  }
4073
4251
  if ("fraction" in value) {
4074
4252
  const opts = value.fraction;
4075
- return `<m:f>${opts.fractionType ? `<m:fPr><m:type m:val="${opts.fractionType}"/></m:fPr>` : ""}<m:num>${stringifyChildren(opts.numerator)}</m:num><m:den>${stringifyChildren(opts.denominator)}</m:den></m:f>`;
4253
+ const pr = opts.fractionType ? `<m:fPr><m:type m:val="${opts.fractionType}"/></m:fPr>` : "";
4254
+ const numArgPr = argPrXml(opts.numeratorArgumentSize);
4255
+ const denArgPr = argPrXml(opts.denominatorArgumentSize);
4256
+ return `<m:f>${pr}<m:num>${numArgPr}${stringifyChildren(opts.numerator)}</m:num><m:den>${denArgPr}${stringifyChildren(opts.denominator)}</m:den></m:f>`;
4076
4257
  }
4077
4258
  if ("radical" in value) {
4078
4259
  const opts = value.radical;
@@ -4115,10 +4296,22 @@ function stringifyMathInput(value) {
4115
4296
  }
4116
4297
  return `<m:m>${pr}${rows}</m:m>`;
4117
4298
  }
4118
- if ("roundBrackets" in value) return stringifyDelimiters(bracketChildren(value.roundBrackets), "(", ")");
4119
- if ("curlyBrackets" in value) return stringifyDelimiters(bracketChildren(value.curlyBrackets), "{", "}");
4120
- if ("angledBrackets" in value) return stringifyDelimiters(bracketChildren(value.angledBrackets), "", "");
4121
- if ("squareBrackets" in value) return stringifyDelimiters(bracketChildren(value.squareBrackets), "[", "]");
4299
+ if ("roundBrackets" in value) {
4300
+ const spec = bracketSpec(value.roundBrackets);
4301
+ return stringifyDelimiters(spec.children, "(", ")", spec.properties);
4302
+ }
4303
+ if ("curlyBrackets" in value) {
4304
+ const spec = bracketSpec(value.curlyBrackets);
4305
+ return stringifyDelimiters(spec.children, "{", "}", spec.properties);
4306
+ }
4307
+ if ("angledBrackets" in value) {
4308
+ const spec = bracketSpec(value.angledBrackets);
4309
+ return stringifyDelimiters(spec.children, "〈", "〉", spec.properties);
4310
+ }
4311
+ if ("squareBrackets" in value) {
4312
+ const spec = bracketSpec(value.squareBrackets);
4313
+ return stringifyDelimiters(spec.children, "[", "]", spec.properties);
4314
+ }
4122
4315
  if ("borderBox" in value) {
4123
4316
  const opts = value.borderBox;
4124
4317
  let pr = "";
@@ -4210,16 +4403,31 @@ function stringifyNAry(opts, chr) {
4210
4403
  const hasSub = opts.subScript && opts.subScript.length > 0;
4211
4404
  const hasSup = opts.superScript && opts.superScript.length > 0;
4212
4405
  const prParts = [`<m:chr m:val="${chr}"/>`];
4406
+ if (opts.properties?.limitLocation) prParts.push(`<m:limLoc m:val="${opts.properties.limitLocation}"/>`);
4407
+ if (opts.properties?.grow !== void 0) prParts.push(`<m:grow m:val="${opts.properties.grow ? 1 : 0}"/>`);
4213
4408
  if (!hasSub) prParts.push("<m:subHide m:val=\"1\"/>");
4214
4409
  if (!hasSup) prParts.push("<m:supHide m:val=\"1\"/>");
4215
4410
  return `<m:nary>${`<m:naryPr>${prParts.join("")}</m:naryPr>`}${hasSub ? `<m:sub>${stringifyChildren(opts.subScript)}</m:sub>` : "<m:sub/>"}${hasSup ? `<m:sup>${stringifyChildren(opts.superScript)}</m:sup>` : "<m:sup/>"}<m:e>${stringifyChildren(opts.children)}</m:e></m:nary>`;
4216
4411
  }
4217
- function stringifyDelimiters(children, begChr, endChr) {
4218
- return `<m:d><m:dPr><m:begChr m:val="${begChr}"/><m:endChr m:val="${endChr}"/></m:dPr><m:e>${stringifyChildren(children)}</m:e></m:d>`;
4219
- }
4220
- function bracketChildren(v) {
4221
- if (Array.isArray(v)) return v;
4222
- return v.children;
4412
+ function stringifyDelimiters(children, begChr, endChr, properties) {
4413
+ const prParts = [`<m:begChr m:val="${properties?.beginCharacter ?? begChr}"/>`];
4414
+ if (properties?.separatorCharacter) prParts.push(`<m:sepChr m:val="${properties.separatorCharacter}"/>`);
4415
+ prParts.push(`<m:endChr m:val="${properties?.endCharacter ?? endChr}"/>`);
4416
+ if (properties?.grow !== void 0) prParts.push(`<m:grow m:val="${properties.grow ? 1 : 0}"/>`);
4417
+ if (properties?.shape) prParts.push(`<m:shp m:val="${properties.shape}"/>`);
4418
+ return `<m:d><m:dPr>${prParts.join("")}</m:dPr><m:e>${stringifyChildren(children)}</m:e></m:d>`;
4419
+ }
4420
+ /** Build an m:argPr/m:argSz block for an argument size scaling value. */
4421
+ function argPrXml(size) {
4422
+ return size !== void 0 ? `<m:argPr><m:argSz m:val="${size}"/></m:argPr>` : "";
4423
+ }
4424
+ /** Split a bracket shorthand into children + optional delimiter properties. */
4425
+ function bracketSpec(v) {
4426
+ if (Array.isArray(v)) return { children: v };
4427
+ return {
4428
+ children: v.children,
4429
+ properties: v.properties
4430
+ };
4223
4431
  }
4224
4432
  function stringifyMath(children) {
4225
4433
  return `<m:oMath>${children.map((c) => stringifyMathInput(c)).join("")}</m:oMath>`;
@@ -4282,10 +4490,33 @@ function parseMathElement(el) {
4282
4490
  function parseMathRun(el) {
4283
4491
  return textOf(findChild(el, "m:t")) ?? "";
4284
4492
  }
4493
+ /** Read an m:val on/off attribute (1/0/true/false; empty element = on). */
4494
+ function readOnOff$1(el) {
4495
+ if (!el) return void 0;
4496
+ const v = attr(el, "m:val");
4497
+ return v === void 0 ? true : v === "1" || v === "true" || v === "on";
4498
+ }
4499
+ /** Read an m:val numeric attribute. */
4500
+ function readNum$1(el) {
4501
+ if (!el) return void 0;
4502
+ const v = attr(el, "m:val");
4503
+ if (v === void 0 || v === "") return void 0;
4504
+ const n = Number(v);
4505
+ return Number.isFinite(n) ? n : void 0;
4506
+ }
4507
+ /** Read an m:argSz scaling value from an m:argPr-bearing argument element. */
4508
+ function readArgSize(argEl) {
4509
+ if (!argEl) return void 0;
4510
+ return readNum$1(findChild(argEl, "m:argSz"));
4511
+ }
4285
4512
  function parseMathFraction(el) {
4513
+ const numeratorArgumentSize = readArgSize(findChild(el, "m:num"));
4514
+ const denominatorArgumentSize = readArgSize(findChild(el, "m:den"));
4286
4515
  return { fraction: {
4287
4516
  numerator: parseMathArg(el, "m:num"),
4288
- denominator: parseMathArg(el, "m:den")
4517
+ denominator: parseMathArg(el, "m:den"),
4518
+ ...numeratorArgumentSize !== void 0 ? { numeratorArgumentSize } : {},
4519
+ ...denominatorArgumentSize !== void 0 ? { denominatorArgumentSize } : {}
4289
4520
  } };
4290
4521
  }
4291
4522
  function parseMathRadical(el) {
@@ -4308,10 +4539,13 @@ function parseMathSubScript(el) {
4308
4539
  } };
4309
4540
  }
4310
4541
  function parseMathSubSuperScript(el) {
4542
+ const pr = findChild(el, "m:sSubSupPr");
4543
+ const alignScript = pr ? readOnOff$1(findChild(pr, "m:alnScr")) : void 0;
4311
4544
  return { subSuperScript: {
4312
4545
  children: parseMathArg(el, "m:e"),
4313
4546
  subScript: parseMathArg(el, "m:sub"),
4314
- superScript: parseMathArg(el, "m:sup")
4547
+ superScript: parseMathArg(el, "m:sup"),
4548
+ ...alignScript !== void 0 ? { alignScript } : {}
4315
4549
  } };
4316
4550
  }
4317
4551
  function parseMathNAry(el) {
@@ -4321,10 +4555,21 @@ function parseMathNAry(el) {
4321
4555
  const baseChildren = parseMathArg(el, "m:e");
4322
4556
  const sub = parseMathArg(el, "m:sub");
4323
4557
  const sup = parseMathArg(el, "m:sup");
4558
+ const properties = {};
4559
+ if (naryPr) {
4560
+ const limLocEl = findChild(naryPr, "m:limLoc");
4561
+ if (limLocEl) {
4562
+ const limLoc = attr(limLocEl, "m:val");
4563
+ if (limLoc === "subSup" || limLoc === "undOvr") properties.limitLocation = limLoc;
4564
+ }
4565
+ const grow = readOnOff$1(findChild(naryPr, "m:grow"));
4566
+ if (grow !== void 0) properties.grow = grow;
4567
+ }
4324
4568
  const common = {
4325
4569
  children: baseChildren,
4326
4570
  ...sub.length > 0 ? { subScript: sub } : {},
4327
- ...sup.length > 0 ? { superScript: sup } : {}
4571
+ ...sup.length > 0 ? { superScript: sup } : {},
4572
+ ...Object.keys(properties).length > 0 ? { properties } : {}
4328
4573
  };
4329
4574
  if (chrVal === "∑") return { sum: common };
4330
4575
  return { integral: common };
@@ -4340,12 +4585,31 @@ function parseMathDelimiter(el) {
4340
4585
  const begChrEl = dPr ? findChild(dPr, "m:begChr") : void 0;
4341
4586
  const begChr = begChrEl ? attr(begChrEl, "m:val") : "(";
4342
4587
  const mathChildren = parseMathArg(el, "m:e");
4588
+ const properties = {};
4589
+ if (dPr) {
4590
+ if (begChrEl) properties.beginCharacter = begChr;
4591
+ const endChrEl = findChild(dPr, "m:endChr");
4592
+ if (endChrEl) properties.endCharacter = attr(endChrEl, "m:val");
4593
+ const sepChrEl = findChild(dPr, "m:sepChr");
4594
+ if (sepChrEl) properties.separatorCharacter = attr(sepChrEl, "m:val");
4595
+ const grow = readOnOff$1(findChild(dPr, "m:grow"));
4596
+ if (grow !== void 0) properties.grow = grow;
4597
+ const shpEl = findChild(dPr, "m:shp");
4598
+ if (shpEl) {
4599
+ const shp = attr(shpEl, "m:val");
4600
+ if (shp === "centered" || shp === "match") properties.shape = shp;
4601
+ }
4602
+ }
4603
+ const value = Object.keys(properties).length > 0 ? {
4604
+ children: mathChildren,
4605
+ properties
4606
+ } : mathChildren;
4343
4607
  switch (begChr) {
4344
- case "[": return { squareBrackets: mathChildren };
4345
- case "{": return { curlyBrackets: mathChildren };
4608
+ case "[": return { squareBrackets: value };
4609
+ case "{": return { curlyBrackets: value };
4346
4610
  case "<":
4347
- case "⟨": return { angledBrackets: mathChildren };
4348
- default: return { roundBrackets: mathChildren };
4611
+ case "⟨": return { angledBrackets: value };
4612
+ default: return { roundBrackets: value };
4349
4613
  }
4350
4614
  }
4351
4615
  function parseMathMatrix(el) {
@@ -4465,13 +4729,12 @@ function stringifyRun(opts, ctx) {
4465
4729
  break;
4466
4730
  }
4467
4731
  }
4468
- const runOpts = commentRefStyle ? {
4732
+ const rPr = stringifyRunProperties(commentRefStyle ? {
4469
4733
  ...opts,
4470
4734
  style: "CommentReference"
4471
- } : opts;
4472
- const rPr = runOpts.rPrRawXml ?? stringifyRunProperties(runOpts);
4735
+ } : opts);
4473
4736
  if (rPr) parts.push(rPr);
4474
- if (opts.break) for (let i = 0; i < opts.break; i++) parts.push("<w:br/>");
4737
+ if (opts.break) parts.push(breakXml(opts.break));
4475
4738
  if (opts.children) {
4476
4739
  for (const child of opts.children) if (typeof child === "string") parts.push(`<w:t xml:space="preserve">${escapeXml(child)}</w:t>`);
4477
4740
  else if (typeof child === "object" && child !== null) {
@@ -4487,6 +4750,10 @@ function stringifyRun(opts, ctx) {
4487
4750
  parts.push("<w:br w:type=\"column\"/>");
4488
4751
  continue;
4489
4752
  }
4753
+ if ("break" in child) {
4754
+ parts.push(breakXml(child.break));
4755
+ continue;
4756
+ }
4490
4757
  if ("commentReference" in child) {
4491
4758
  parts.push(`<w:commentReference w:id="${Number(child.commentReference)}"/>`);
4492
4759
  continue;
@@ -4496,6 +4763,10 @@ function stringifyRun(opts, ctx) {
4496
4763
  parts.push(emptyXml);
4497
4764
  continue;
4498
4765
  }
4766
+ if ("object" in child) {
4767
+ parts.push(objectDesc.stringify(child.object, ctx) ?? "");
4768
+ continue;
4769
+ }
4499
4770
  const jsonResult = stringifyChildDispatch(child, ctx);
4500
4771
  if (jsonResult !== void 0) if (Array.isArray(jsonResult)) parts.push(...jsonResult);
4501
4772
  else parts.push(jsonResult);
@@ -4503,8 +4774,9 @@ function stringifyRun(opts, ctx) {
4503
4774
  }
4504
4775
  } else if (opts.text !== void 0) parts.push(`<w:t xml:space="preserve">${escapeXml(String(opts.text))}</w:t>`);
4505
4776
  const rsidAttrs = [];
4506
- if (opts.rsidRPr) rsidAttrs.push(` w:rsidRPr="${opts.rsidRPr}"`);
4507
- if (opts.rsidDel) rsidAttrs.push(` w:rsidDel="${opts.rsidDel}"`);
4777
+ if (opts.rsid) rsidAttrs.push(` w:rsidR="${opts.rsid}"`);
4778
+ if (opts.runPropertiesRsid) rsidAttrs.push(` w:rsidRPr="${opts.runPropertiesRsid}"`);
4779
+ if (opts.deletionRsid) rsidAttrs.push(` w:rsidDel="${opts.deletionRsid}"`);
4508
4780
  const attr = rsidAttrs.join("");
4509
4781
  const body = parts.join("");
4510
4782
  return body.length === 0 ? attr ? `<w:r${attr}/>` : "<w:r/>" : `<w:r${attr}>${body}</w:r>`;
@@ -4533,7 +4805,16 @@ function stringifyParagraph(opts, ctx, sectionPropertiesXml) {
4533
4805
  }
4534
4806
  }
4535
4807
  const body = parts.join("");
4536
- return body ? `<w:p>${body}</w:p>` : "<w:p/>";
4808
+ const paraAttrs = [];
4809
+ if (resolved.paraId) paraAttrs.push(` w14:paraId="${resolved.paraId}"`);
4810
+ if (resolved.textId) paraAttrs.push(` w14:textId="${resolved.textId}"`);
4811
+ if (resolved.rsid) paraAttrs.push(` w:rsidR="${resolved.rsid}"`);
4812
+ if (resolved.defaultRunRsid) paraAttrs.push(` w:rsidRDefault="${resolved.defaultRunRsid}"`);
4813
+ if (resolved.propertiesRsid) paraAttrs.push(` w:rsidP="${resolved.propertiesRsid}"`);
4814
+ if (resolved.runPropertiesRsid) paraAttrs.push(` w:rsidRPr="${resolved.runPropertiesRsid}"`);
4815
+ if (resolved.deletionRsid) paraAttrs.push(` w:rsidDel="${resolved.deletionRsid}"`);
4816
+ const attr = paraAttrs.join("");
4817
+ return body ? `<w:p${attr}>${body}</w:p>` : `<w:p${attr}/>`;
4537
4818
  }
4538
4819
  /**
4539
4820
  * Stringify a body-level child element.
@@ -4553,8 +4834,16 @@ function stringifyBodyChild(child, ctx) {
4553
4834
  if ("altChunk" in child) return altChunkDesc.stringify(child.altChunk, ctx) ?? "";
4554
4835
  if ("subDoc" in child) return subDocDesc.stringify(child.subDoc, ctx) ?? "";
4555
4836
  if ("customXml" in child) return customXmlBlockDesc.stringify(child.customXml, ctx) ?? "";
4556
- if ("bookmarkStart" in child) return `<w:bookmarkStart w:id="${child.bookmarkStart.id}" w:name="${child.bookmarkStart.name}"/>`;
4557
- if ("bookmarkEnd" in child) return `<w:bookmarkEnd w:id="${child.bookmarkEnd}"/>`;
4837
+ if ("bookmarkStart" in child) {
4838
+ const bs = child.bookmarkStart;
4839
+ const bsDisp = bs.displacedByCustomXml ? ` w:displacedByCustomXml="${bs.displacedByCustomXml}"` : "";
4840
+ return `<w:bookmarkStart w:id="${bs.id}" w:name="${bs.name}"${bsDisp}/>`;
4841
+ }
4842
+ if ("bookmarkEnd" in child) {
4843
+ const be = child.bookmarkEnd;
4844
+ const beDisp = be.displacedByCustomXml ? ` w:displacedByCustomXml="${be.displacedByCustomXml}"` : "";
4845
+ return `<w:bookmarkEnd w:id="${be.id}"${beDisp}/>`;
4846
+ }
4558
4847
  if ("rawXml" in child) return child.rawXml;
4559
4848
  throw new Error("Unknown section child type");
4560
4849
  }
@@ -4635,7 +4924,8 @@ function stringifyDocumentXml(ctx, docCtx) {
4635
4924
  const sections = ctx._options.sections;
4636
4925
  const bodySections = ctx.sectionProperties;
4637
4926
  const parts = [];
4638
- parts.push(`<w:document ${DOC_NS} mc:Ignorable="w14 w15 wp14">`);
4927
+ const conformanceAttr = ctx._options.conformance ? ` w:conformance="${ctx._options.conformance}"` : "";
4928
+ parts.push(`<w:document ${DOC_NS} mc:Ignorable="w14 w15 wp14"${conformanceAttr}>`);
4639
4929
  if (ctx._options.background) parts.push(stringifyDocumentBackground(ctx._options.background, docCtx));
4640
4930
  const bodyParts = [];
4641
4931
  for (let si = 0; si < sections.length; si++) {
@@ -4696,11 +4986,11 @@ function parseParagraphProperties(el, ctx) {
4696
4986
  const spacing = findChild(el, "w:spacing");
4697
4987
  if (spacing) {
4698
4988
  const sp = {};
4699
- const before = attrNum(spacing, "w:before");
4989
+ const before = attrMeasure(spacing, "w:before");
4700
4990
  if (before !== void 0) sp.before = before;
4701
- const after = attrNum(spacing, "w:after");
4991
+ const after = attrMeasure(spacing, "w:after");
4702
4992
  if (after !== void 0) sp.after = after;
4703
- const line = attrNum(spacing, "w:line");
4993
+ const line = attrMeasure(spacing, "w:line");
4704
4994
  if (line !== void 0) sp.line = line;
4705
4995
  const lineRule = attr(spacing, "w:lineRule");
4706
4996
  if (lineRule && LINE_RULES.includes(lineRule)) sp.lineRule = lineRule;
@@ -4717,27 +5007,27 @@ function parseParagraphProperties(el, ctx) {
4717
5007
  const ind = findChild(el, "w:ind");
4718
5008
  if (ind) {
4719
5009
  const indentObj = {};
4720
- const left = attrNum(ind, "w:left");
5010
+ const left = attrMeasure(ind, "w:left");
4721
5011
  if (left !== void 0) indentObj.left = left;
4722
5012
  const leftChars = attrNum(ind, "w:leftChars");
4723
5013
  if (leftChars !== void 0) indentObj.leftChars = leftChars;
4724
- const right = attrNum(ind, "w:right");
5014
+ const right = attrMeasure(ind, "w:right");
4725
5015
  if (right !== void 0) indentObj.right = right;
4726
5016
  const rightChars = attrNum(ind, "w:rightChars");
4727
5017
  if (rightChars !== void 0) indentObj.rightChars = rightChars;
4728
- const start = attrNum(ind, "w:start");
5018
+ const start = attrMeasure(ind, "w:start");
4729
5019
  if (start !== void 0) indentObj.start = start;
4730
5020
  const startChars = attrNum(ind, "w:startChars");
4731
5021
  if (startChars !== void 0) indentObj.startChars = startChars;
4732
- const end = attrNum(ind, "w:end");
5022
+ const end = attrMeasure(ind, "w:end");
4733
5023
  if (end !== void 0) indentObj.end = end;
4734
5024
  const endChars = attrNum(ind, "w:endChars");
4735
5025
  if (endChars !== void 0) indentObj.endChars = endChars;
4736
- const hanging = attrNum(ind, "w:hanging");
5026
+ const hanging = attrMeasure(ind, "w:hanging");
4737
5027
  if (hanging !== void 0) indentObj.hanging = hanging;
4738
5028
  const hangingChars = attrNum(ind, "w:hangingChars");
4739
5029
  if (hangingChars !== void 0) indentObj.hangingChars = hangingChars;
4740
- const firstLine = attrNum(ind, "w:firstLine");
5030
+ const firstLine = attrMeasure(ind, "w:firstLine");
4741
5031
  if (firstLine !== void 0) indentObj.firstLine = firstLine;
4742
5032
  const firstLineChars = attrNum(ind, "w:firstLineChars");
4743
5033
  if (firstLineChars !== void 0) indentObj.firstLineChars = firstLineChars;
@@ -4761,12 +5051,25 @@ function parseParagraphProperties(el, ctx) {
4761
5051
  break;
4762
5052
  }
4763
5053
  }
4764
- if (abstractNumId !== void 0) opts.numbering = {
4765
- reference: `list_${numId}`,
4766
- level,
4767
- custom: true
4768
- };
4769
- else opts.bullet = { level };
5054
+ if (abstractNumId !== void 0) {
5055
+ const numberingOpts = {
5056
+ reference: `list_${numId}`,
5057
+ level,
5058
+ custom: true
5059
+ };
5060
+ const numberingChangeEl = findChild(numPr, "w:numberingChange");
5061
+ if (numberingChangeEl) {
5062
+ const nc = {
5063
+ original: attr(numberingChangeEl, "w:original") ?? "",
5064
+ id: attr(numberingChangeEl, "w:id") ?? "",
5065
+ author: attr(numberingChangeEl, "w:author") ?? ""
5066
+ };
5067
+ const ncDate = attr(numberingChangeEl, "w:date");
5068
+ if (ncDate) nc.date = ncDate;
5069
+ numberingOpts.numberingChange = nc;
5070
+ }
5071
+ opts.numbering = numberingOpts;
5072
+ } else opts.bullet = { level };
4770
5073
  } else opts.bullet = { level };
4771
5074
  } else opts.bullet = { level };
4772
5075
  }
@@ -4910,6 +5213,19 @@ function parseParagraphProperties(el, ctx) {
4910
5213
  if (h !== void 0) frame.height = h;
4911
5214
  if (Object.keys(frame).length > 0) opts.frame = frame;
4912
5215
  }
5216
+ const pPrChange = findChild(el, "w:pPrChange");
5217
+ if (pPrChange) {
5218
+ const rev = {};
5219
+ const author = attr(pPrChange, "w:author");
5220
+ if (author) rev.author = author;
5221
+ const revDate = attr(pPrChange, "w:date");
5222
+ if (revDate) rev.date = revDate;
5223
+ const revId = attrNum(pPrChange, "w:id");
5224
+ if (revId !== void 0) rev.id = revId;
5225
+ const innerPPr = findChild(pPrChange, "w:pPr");
5226
+ if (innerPPr) Object.assign(rev, parseParagraphProperties(innerPPr, ctx));
5227
+ if (Object.keys(rev).length > 0) opts.revision = rev;
5228
+ }
4913
5229
  return opts;
4914
5230
  }
4915
5231
  /**
@@ -4919,6 +5235,16 @@ function parseParagraphProperties(el, ctx) {
4919
5235
  * (the runs between the `separate` and `end` fldChars). Only `<w:t>` is read —
4920
5236
  * `<w:tab>`/`<w:br>` in results are ignored as rare for user-entered text.
4921
5237
  */
5238
+ /** Parse the w:r children of a track-change wrapper (w:ins/w:moveFrom/w:moveTo). */
5239
+ function parseTrackChangeRuns(el, ctx) {
5240
+ const runs = [];
5241
+ for (const sub of el.elements ?? []) {
5242
+ if (sub.name !== "w:r") continue;
5243
+ const runOpts = parsedRunToOptions(parseRun(sub, ctx));
5244
+ if (runOpts !== null && typeof runOpts === "object" && !("commentReference" in runOpts)) runs.push(runOpts);
5245
+ }
5246
+ return runs;
5247
+ }
4922
5248
  function collectRunText(el) {
4923
5249
  let text = "";
4924
5250
  for (const c of el.elements ?? []) if (c.name === "w:t") text += textOf(c);
@@ -5119,7 +5445,7 @@ function parseRunLevelChildren(elements, ctx) {
5119
5445
  const drawingChild = parseDrawingRun(drawingEl, ctx);
5120
5446
  if (drawingChild) {
5121
5447
  const rPrEl = findChild(child, "w:rPr");
5122
- const runPropertiesRawXml = rPrEl ? stringifyElement(rPrEl) : void 0;
5448
+ const runProperties = rPrEl ? parseRunProperties(rPrEl) : void 0;
5123
5449
  if (altFallback) {
5124
5450
  if ("wpsShape" in drawingChild) {
5125
5451
  drawingChild.wpsShape.vmlFallback = altFallback;
@@ -5131,10 +5457,10 @@ function parseRunLevelChildren(elements, ctx) {
5131
5457
  if (altRequires) drawingChild.wpgGroup.mcChoiceRequires = altRequires;
5132
5458
  }
5133
5459
  }
5134
- if (runPropertiesRawXml) {
5135
- if ("image" in drawingChild) drawingChild.image.runPropertiesRawXml = runPropertiesRawXml;
5136
- else if ("wpsShape" in drawingChild) drawingChild.wpsShape.runPropertiesRawXml = runPropertiesRawXml;
5137
- else if ("wpgGroup" in drawingChild) drawingChild.wpgGroup.runPropertiesRawXml = runPropertiesRawXml;
5460
+ if (runProperties) {
5461
+ if ("image" in drawingChild) drawingChild.image.runProperties = runProperties;
5462
+ else if ("wpsShape" in drawingChild) drawingChild.wpsShape.runProperties = runProperties;
5463
+ else if ("wpgGroup" in drawingChild) drawingChild.wpgGroup.runProperties = runProperties;
5138
5464
  }
5139
5465
  childList.push(drawingChild);
5140
5466
  break;
@@ -5155,6 +5481,12 @@ function parseRunLevelChildren(elements, ctx) {
5155
5481
  if (anchor) hl.anchor = anchor;
5156
5482
  const tooltip = attr(child, "w:tooltip");
5157
5483
  if (tooltip) hl.tooltip = tooltip;
5484
+ const tgtFrame = attr(child, "w:tgtFrame");
5485
+ if (tgtFrame) hl.tgtFrame = tgtFrame;
5486
+ const docLocation = attr(child, "w:docLocation");
5487
+ if (docLocation) hl.docLocation = docLocation;
5488
+ const history = attrBool(child, "w:history");
5489
+ if (history !== void 0) hl.history = history;
5158
5490
  const linkRuns = [];
5159
5491
  for (const sub of child.elements ?? []) if (sub.name === "w:r") {
5160
5492
  const runOpts = parsedRunToOptions(parseRun(sub, ctx));
@@ -5169,15 +5501,25 @@ function parseRunLevelChildren(elements, ctx) {
5169
5501
  case "w:bookmarkStart": {
5170
5502
  const id = attrNum(child, "w:id");
5171
5503
  const name = attr(child, "w:name");
5172
- if (id !== void 0 && name) childList.push({ bookmarkStart: {
5173
- id,
5174
- name
5175
- } });
5504
+ if (id !== void 0 && name) {
5505
+ const bookmarkStart = {
5506
+ id,
5507
+ name
5508
+ };
5509
+ const disp = attr(child, "w:displacedByCustomXml");
5510
+ if (disp === "before" || disp === "after") bookmarkStart.displacedByCustomXml = disp;
5511
+ childList.push({ bookmarkStart });
5512
+ }
5176
5513
  break;
5177
5514
  }
5178
5515
  case "w:bookmarkEnd": {
5179
5516
  const id = attrNum(child, "w:id");
5180
- if (id !== void 0) childList.push({ bookmarkEnd: id });
5517
+ if (id !== void 0) {
5518
+ const bookmarkEnd = { id };
5519
+ const disp = attr(child, "w:displacedByCustomXml");
5520
+ if (disp === "before" || disp === "after") bookmarkEnd.displacedByCustomXml = disp;
5521
+ childList.push({ bookmarkEnd });
5522
+ }
5181
5523
  break;
5182
5524
  }
5183
5525
  case "w:commentRangeStart": {
@@ -5201,73 +5543,56 @@ function parseRunLevelChildren(elements, ctx) {
5201
5543
  break;
5202
5544
  }
5203
5545
  case "w:ins": {
5204
- const insRun = findChild(child, "w:r");
5205
- if (insRun) {
5206
- const runOpts = parsedRunToOptions(parseRun(insRun, ctx));
5207
- if (runOpts !== null && typeof runOpts === "object" && !("commentReference" in runOpts)) childList.push({ insertion: {
5208
- id: attrNum(child, "w:id") ?? 0,
5209
- author: attr(child, "w:author") ?? "",
5210
- date: attr(child, "w:date") ?? "",
5211
- ...runOpts
5212
- } });
5213
- }
5546
+ const children = parseTrackChangeRuns(child, ctx);
5547
+ if (children.length > 0) childList.push({ insertion: {
5548
+ id: attrNum(child, "w:id") ?? 0,
5549
+ author: attr(child, "w:author") ?? "",
5550
+ date: attr(child, "w:date") ?? "",
5551
+ children
5552
+ } });
5214
5553
  break;
5215
5554
  }
5216
5555
  case "w:del": {
5217
- let delFieldPlaceholder;
5556
+ const children = [];
5218
5557
  for (const sub of child.elements ?? []) {
5219
5558
  if (sub.name !== "w:r") continue;
5220
5559
  const delInstrEl = findChild(sub, "w:delInstrText");
5221
5560
  if (delInstrEl) {
5222
- delFieldPlaceholder = DELETED_PAGE_FIELD[(textOf(delInstrEl) ?? "").trim()];
5223
- if (delFieldPlaceholder) break;
5561
+ const placeholder = DELETED_PAGE_FIELD[(textOf(delInstrEl) ?? "").trim()];
5562
+ if (placeholder) {
5563
+ children.push(placeholder);
5564
+ continue;
5565
+ }
5224
5566
  }
5567
+ const runOpts = parsedRunToOptions(parseRun(sub, ctx));
5568
+ if (runOpts !== null && typeof runOpts === "object" && !("commentReference" in runOpts)) children.push(runOpts);
5225
5569
  }
5226
- if (delFieldPlaceholder) {
5227
- childList.push({ deletion: {
5228
- id: attrNum(child, "w:id") ?? 0,
5229
- author: attr(child, "w:author") ?? "",
5230
- date: attr(child, "w:date") ?? "",
5231
- children: [delFieldPlaceholder]
5232
- } });
5233
- break;
5234
- }
5235
- const delRun = findChild(child, "w:r");
5236
- if (delRun) {
5237
- const runOpts = parsedRunToOptions(parseRun(delRun, ctx));
5238
- if (runOpts !== null && typeof runOpts === "object" && !("commentReference" in runOpts)) childList.push({ deletion: {
5239
- id: attrNum(child, "w:id") ?? 0,
5240
- author: attr(child, "w:author") ?? "",
5241
- date: attr(child, "w:date") ?? "",
5242
- ...runOpts
5243
- } });
5244
- }
5570
+ if (children.length > 0) childList.push({ deletion: {
5571
+ id: attrNum(child, "w:id") ?? 0,
5572
+ author: attr(child, "w:author") ?? "",
5573
+ date: attr(child, "w:date") ?? "",
5574
+ children
5575
+ } });
5245
5576
  break;
5246
5577
  }
5247
5578
  case "w:moveFrom": {
5248
- const runEl = findChild(child, "w:r");
5249
- if (runEl) {
5250
- const runOpts = parsedRunToOptions(parseRun(runEl, ctx));
5251
- if (runOpts !== null && typeof runOpts === "object" && !("commentReference" in runOpts)) childList.push({ movedFrom: {
5252
- id: attrNum(child, "w:id") ?? 0,
5253
- author: attr(child, "w:author") ?? "",
5254
- date: attr(child, "w:date") ?? "",
5255
- ...runOpts
5256
- } });
5257
- }
5579
+ const children = parseTrackChangeRuns(child, ctx);
5580
+ if (children.length > 0) childList.push({ movedFrom: {
5581
+ id: attrNum(child, "w:id") ?? 0,
5582
+ author: attr(child, "w:author") ?? "",
5583
+ date: attr(child, "w:date") ?? "",
5584
+ children
5585
+ } });
5258
5586
  break;
5259
5587
  }
5260
5588
  case "w:moveTo": {
5261
- const runEl = findChild(child, "w:r");
5262
- if (runEl) {
5263
- const runOpts = parsedRunToOptions(parseRun(runEl, ctx));
5264
- if (runOpts !== null && typeof runOpts === "object" && !("commentReference" in runOpts)) childList.push({ movedTo: {
5265
- id: attrNum(child, "w:id") ?? 0,
5266
- author: attr(child, "w:author") ?? "",
5267
- date: attr(child, "w:date") ?? "",
5268
- ...runOpts
5269
- } });
5270
- }
5589
+ const children = parseTrackChangeRuns(child, ctx);
5590
+ if (children.length > 0) childList.push({ movedTo: {
5591
+ id: attrNum(child, "w:id") ?? 0,
5592
+ author: attr(child, "w:author") ?? "",
5593
+ date: attr(child, "w:date") ?? "",
5594
+ children
5595
+ } });
5271
5596
  break;
5272
5597
  }
5273
5598
  case "w:fldSimple": {
@@ -5277,6 +5602,10 @@ function parseRunLevelChildren(elements, ctx) {
5277
5602
  let cachedValue = "";
5278
5603
  for (const sub of child.elements ?? []) if (sub.name === "w:r") cachedValue += collectRunText(sub);
5279
5604
  if (cachedValue) sf.cachedValue = cachedValue;
5605
+ const sfLock = attrBool(child, "w:fldLock");
5606
+ if (sfLock !== void 0) sf.fldLock = sfLock;
5607
+ const sfDirty = attrBool(child, "w:dirty");
5608
+ if (sfDirty !== void 0) sf.dirty = sfDirty;
5280
5609
  childList.push({ simpleField: sf });
5281
5610
  }
5282
5611
  break;
@@ -5462,13 +5791,31 @@ function parseRunLevelChildren(elements, ctx) {
5462
5791
  }
5463
5792
  return childList;
5464
5793
  }
5794
+ /** True when a child is a single-field `{ text: string }` run (simple text). */
5795
+ function isTextOnlyRun(c) {
5796
+ return typeof c === "object" && c !== null && "text" in c && Object.keys(c).length === 1;
5797
+ }
5465
5798
  function parseParagraph(el, ctx) {
5466
5799
  const opts = {};
5800
+ const paraId = attr(el, "w14:paraId");
5801
+ if (paraId) opts.paraId = paraId;
5802
+ const textId = attr(el, "w14:textId");
5803
+ if (textId) opts.textId = textId;
5804
+ const rsid = attr(el, "w:rsidR");
5805
+ if (rsid) opts.rsid = rsid;
5806
+ const defaultRunRsid = attr(el, "w:rsidRDefault");
5807
+ if (defaultRunRsid) opts.defaultRunRsid = defaultRunRsid;
5808
+ const propertiesRsid = attr(el, "w:rsidP");
5809
+ if (propertiesRsid) opts.propertiesRsid = propertiesRsid;
5810
+ const runPropertiesRsid = attr(el, "w:rsidRPr");
5811
+ if (runPropertiesRsid) opts.runPropertiesRsid = runPropertiesRsid;
5812
+ const deletionRsid = attr(el, "w:rsidDel");
5813
+ if (deletionRsid) opts.deletionRsid = deletionRsid;
5467
5814
  const pPr = findChild(el, "w:pPr");
5468
5815
  if (pPr) Object.assign(opts, parseParagraphProperties(pPr, ctx));
5469
5816
  const childList = parseRunLevelChildren(el.elements, ctx);
5470
5817
  if (childList.length > 0) {
5471
- if (childList.every((c) => typeof c === "object" && c !== null && "text" in c && Object.keys(c).length === 1)) {
5818
+ if (childList.every(isTextOnlyRun)) {
5472
5819
  const combined = childList.map((c) => c.text).join("");
5473
5820
  if (combined && Object.keys(opts).length === 0) return combined;
5474
5821
  if (combined) {
@@ -6864,11 +7211,32 @@ const createEnd = (dirty) => createFieldChar(FieldCharacterType.END, dirty);
6864
7211
  *
6865
7212
  * @module
6866
7213
  */
7214
+ /** Serialize a deleted run: rPr + delText (or field delInstrText). */
7215
+ function stringifyDeletedRun(c) {
7216
+ const opts = typeof c === "string" ? { text: c } : c;
7217
+ const parts = [];
7218
+ const rPr = stringifyRunProperties(opts);
7219
+ if (rPr) parts.push(rPr);
7220
+ if (opts.break) parts.push(breakXml(opts.break));
7221
+ const fieldMap = {
7222
+ CURRENT: "PAGE",
7223
+ TOTAL_PAGES: "NUMPAGES",
7224
+ TOTAL_PAGES_IN_SECTION: "SECTIONPAGES"
7225
+ };
7226
+ if (opts.children) {
7227
+ for (const cc of opts.children) if (typeof cc === "string") {
7228
+ const instrText = fieldMap[cc];
7229
+ if (instrText) parts.push(`<w:fldChar w:fldCharType="begin"/><w:delInstrText xml:space="preserve">${instrText}</w:delInstrText><w:fldChar w:fldCharType="separate"/><w:fldChar w:fldCharType="end"/>`);
7230
+ else parts.push(`<w:delText xml:space="preserve">${escapeXml(cc)}</w:delText>`);
7231
+ }
7232
+ } else if (opts.text) parts.push(`<w:delText xml:space="preserve">${escapeXml(String(opts.text))}</w:delText>`);
7233
+ return `<w:r>${parts.join("")}</w:r>`;
7234
+ }
6867
7235
  function stringifyRunInline(opts, ctx) {
6868
7236
  const parts = [];
6869
7237
  const rPr = stringifyRunProperties(opts);
6870
7238
  if (rPr) parts.push(rPr);
6871
- if (opts.break) for (let i = 0; i < opts.break; i++) parts.push("<w:br/>");
7239
+ if (opts.break) parts.push(breakXml(opts.break));
6872
7240
  if (opts.children) for (const child of opts.children) if (typeof child === "string") parts.push(`<w:t xml:space="preserve">${escapeXml(child)}</w:t>`);
6873
7241
  else {
6874
7242
  const jsonResult = stringifyChildDispatch(child, ctx);
@@ -6878,8 +7246,9 @@ function stringifyRunInline(opts, ctx) {
6878
7246
  }
6879
7247
  else if (opts.text !== void 0) parts.push(`<w:t xml:space="preserve">${escapeXml(String(opts.text))}</w:t>`);
6880
7248
  const rsidAttrs = [];
6881
- if (opts.rsidRPr) rsidAttrs.push(` w:rsidRPr="${opts.rsidRPr}"`);
6882
- if (opts.rsidDel) rsidAttrs.push(` w:rsidDel="${opts.rsidDel}"`);
7249
+ if (opts.rsid) rsidAttrs.push(` w:rsidR="${opts.rsid}"`);
7250
+ if (opts.runPropertiesRsid) rsidAttrs.push(` w:rsidRPr="${opts.runPropertiesRsid}"`);
7251
+ if (opts.deletionRsid) rsidAttrs.push(` w:rsidDel="${opts.deletionRsid}"`);
6883
7252
  const attr = rsidAttrs.join("");
6884
7253
  const body = parts.join("");
6885
7254
  return body.length === 0 ? attr ? `<w:r${attr}/>` : "<w:r/>" : `<w:r${attr}>${body}</w:r>`;
@@ -6909,7 +7278,7 @@ let nextChartId = 1;
6909
7278
  */
6910
7279
  function wrapDrawingRun(drawingXml, opts) {
6911
7280
  const xml = drawingXml ?? "";
6912
- const rPr = opts.runPropertiesRawXml ?? "";
7281
+ const rPr = stringifyRunProperties(opts.runProperties) ?? "";
6913
7282
  if (opts.vmlFallback) return `<w:r>${rPr}<mc:AlternateContent><mc:Choice Requires="${opts.mcChoiceRequires ?? "wps"}">${xml}</mc:Choice>${opts.vmlFallback}</mc:AlternateContent></w:r>`;
6914
7283
  return `<w:r>${rPr}${xml}</w:r>`;
6915
7284
  }
@@ -6949,25 +7318,36 @@ function registerVmlFallbackMedia(opts, ctx) {
6949
7318
  }
6950
7319
  }
6951
7320
  /**
6952
- * Resolve a break/tab run's rPr: prefer the raw rPr carried from parse (verbatim,
6953
- * no b/bCs, sz/szCs pairing), else regenerate from the structured fields.
7321
+ * Build the rPr XML for a break/tab run from its structured run properties.
6954
7322
  */
6955
- function runPrOrRaw(child) {
6956
- const raw = child.rPrRawXml;
6957
- if (raw) return raw;
7323
+ function runPropertiesXml(child) {
6958
7324
  return stringifyRunProperties(child) ?? "";
6959
7325
  }
6960
7326
  function stringifyChildDispatch(child, ctx) {
6961
- if ("pageBreak" in child) return `<w:r>${runPrOrRaw(child)}<w:br w:type="page"/></w:r>`;
6962
- if ("columnBreak" in child) return `<w:r>${runPrOrRaw(child)}<w:br w:type="column"/></w:r>`;
6963
- if ("tab" in child) return `<w:r>${runPrOrRaw(child)}<w:tab/></w:r>`;
6964
- if ("footnoteReference" in child) return `<w:r><w:rPr><w:rStyle w:val="FootnoteReference"/></w:rPr><w:footnoteReference w:id="${child.footnoteReference}"/></w:r>`;
6965
- if ("endnoteReference" in child) return `<w:r><w:rPr><w:rStyle w:val="EndnoteReference"/></w:rPr><w:endnoteReference w:id="${child.endnoteReference}"/></w:r>`;
7327
+ if ("pageBreak" in child) return `<w:r>${runPropertiesXml(child)}<w:br w:type="page"/></w:r>`;
7328
+ if ("columnBreak" in child) return `<w:r>${runPropertiesXml(child)}<w:br w:type="column"/></w:r>`;
7329
+ if ("tab" in child) return `<w:r>${runPropertiesXml(child)}<w:tab/></w:r>`;
7330
+ if ("footnoteReference" in child) {
7331
+ const ref = child.footnoteReference;
7332
+ return `<w:r><w:rPr><w:rStyle w:val="FootnoteReference"/></w:rPr><w:footnoteReference w:id="${typeof ref === "number" ? ref : ref.id}"${typeof ref === "object" && ref.customMarkFollows ? " w:customMarkFollows=\"true\"" : ""}/></w:r>`;
7333
+ }
7334
+ if ("endnoteReference" in child) {
7335
+ const ref = child.endnoteReference;
7336
+ return `<w:r><w:rPr><w:rStyle w:val="EndnoteReference"/></w:rPr><w:endnoteReference w:id="${typeof ref === "number" ? ref : ref.id}"${typeof ref === "object" && ref.customMarkFollows ? " w:customMarkFollows=\"true\"" : ""}/></w:r>`;
7337
+ }
6966
7338
  if ("commentRangeStart" in child) return `<w:commentRangeStart w:id="${child.commentRangeStart}"/>`;
6967
7339
  if ("commentRangeEnd" in child) return `<w:commentRangeEnd w:id="${child.commentRangeEnd}"/>`;
6968
7340
  if ("commentReference" in child) return `<w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr><w:commentReference w:id="${child.commentReference}"/></w:r>`;
6969
- if ("bookmarkStart" in child) return `<w:bookmarkStart w:id="${child.bookmarkStart.id}" w:name="${child.bookmarkStart.name}"/>`;
6970
- if ("bookmarkEnd" in child) return `<w:bookmarkEnd w:id="${child.bookmarkEnd}"/>`;
7341
+ if ("bookmarkStart" in child) {
7342
+ const bs = child.bookmarkStart;
7343
+ const bsDisp = bs.displacedByCustomXml ? ` w:displacedByCustomXml="${bs.displacedByCustomXml}"` : "";
7344
+ return `<w:bookmarkStart w:id="${bs.id}" w:name="${bs.name}"${bsDisp}/>`;
7345
+ }
7346
+ if ("bookmarkEnd" in child) {
7347
+ const be = child.bookmarkEnd;
7348
+ const beDisp = be.displacedByCustomXml ? ` w:displacedByCustomXml="${be.displacedByCustomXml}"` : "";
7349
+ return `<w:bookmarkEnd w:id="${be.id}"${beDisp}/>`;
7350
+ }
6971
7351
  if ("symbolRun" in child) {
6972
7352
  const opts = child.symbolRun;
6973
7353
  return `<w:r>${stringifyRunProperties(opts) ?? ""}<w:sym w:char="${opts.char}" w:font="${opts.symbolfont ?? "Wingdings"}"/></w:r>`;
@@ -7150,29 +7530,14 @@ function stringifyChildDispatch(child, ctx) {
7150
7530
  }
7151
7531
  if ("math" in child && typeof child.math === "object" && child.math !== null) return stringifyMath(child.math.children ?? []);
7152
7532
  if ("insertion" in child) {
7153
- const { id, author, date, ...runOpts } = child.insertion;
7154
- const runXml = stringifyRunInline(runOpts, ctx);
7155
- return `<w:ins w:id="${id}" w:author="${escapeXml(String(author))}" w:date="${date}">${runXml}</w:ins>`;
7533
+ const { id, author, date, children } = child.insertion;
7534
+ const body = children.map((c) => stringifyRunInline(typeof c === "string" ? { text: c } : c, ctx)).join("");
7535
+ return `<w:ins w:id="${id}" w:author="${escapeXml(String(author))}" w:date="${date}">${body}</w:ins>`;
7156
7536
  }
7157
7537
  if ("deletion" in child) {
7158
- const { id, author, date, ...runOpts } = child.deletion;
7159
- const parts = [];
7160
- const rPr = stringifyRunProperties(runOpts);
7161
- if (rPr) parts.push(rPr);
7162
- if (runOpts.break) for (let i = 0; i < runOpts.break; i++) parts.push("<w:br/>");
7163
- if (runOpts.children) {
7164
- for (const c of runOpts.children) if (typeof c === "string") {
7165
- const instrText = {
7166
- CURRENT: "PAGE",
7167
- TOTAL_PAGES: "NUMPAGES",
7168
- TOTAL_PAGES_IN_SECTION: "SECTIONPAGES"
7169
- }[c];
7170
- if (instrText) parts.push(`<w:fldChar w:fldCharType="begin"/><w:delInstrText xml:space="preserve">${instrText}</w:delInstrText><w:fldChar w:fldCharType="separate"/><w:fldChar w:fldCharType="end"/>`);
7171
- else parts.push(`<w:delText xml:space="preserve">${escapeXml(c)}</w:delText>`);
7172
- }
7173
- } else if (runOpts.text) parts.push(`<w:delText xml:space="preserve">${escapeXml(String(runOpts.text))}</w:delText>`);
7174
- const runBody = parts.join("");
7175
- return `<w:del w:id="${id}" w:author="${escapeXml(String(author))}" w:date="${date}"><w:r>${runBody}</w:r></w:del>`;
7538
+ const { id, author, date, children } = child.deletion;
7539
+ const body = children.map((c) => stringifyDeletedRun(c)).join("");
7540
+ return `<w:del w:id="${id}" w:author="${escapeXml(String(author))}" w:date="${date}">${body}</w:del>`;
7176
7541
  }
7177
7542
  if ("hyperlink" in child) {
7178
7543
  const hl = child.hyperlink;
@@ -7180,16 +7545,22 @@ function stringifyChildDispatch(child, ctx) {
7180
7545
  if (hl.children) for (const rc of hl.children) if (typeof rc === "string") childParts.push(stringifyRunInline({ text: rc }, ctx));
7181
7546
  else childParts.push(stringifyRunInline(rc, ctx));
7182
7547
  const body = childParts.join("");
7548
+ const pushHlAttrs = (attrs) => {
7549
+ if (hl.history !== false) attrs.push("w:history=\"1\"");
7550
+ if (hl.tooltip) attrs.push(`w:tooltip="${escapeXml(hl.tooltip)}"`);
7551
+ if (hl.tgtFrame) attrs.push(`w:tgtFrame="${escapeXml(hl.tgtFrame)}"`);
7552
+ if (hl.docLocation) attrs.push(`w:docLocation="${escapeXml(hl.docLocation)}"`);
7553
+ };
7183
7554
  if (hl.link) {
7184
7555
  const linkId = uniqueId();
7185
7556
  ctx.viewWrapper.relationships.addRelationship(linkId, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", hl.link, TargetModeType.EXTERNAL);
7186
- const attrs = [`r:id="rId${linkId}"`, "w:history=\"1\""];
7187
- if (hl.tooltip) attrs.push(`w:tooltip="${escapeXml(hl.tooltip)}"`);
7557
+ const attrs = [`r:id="rId${linkId}"`];
7558
+ pushHlAttrs(attrs);
7188
7559
  return `<w:hyperlink ${attrs.join(" ")}>${body}</w:hyperlink>`;
7189
7560
  }
7190
7561
  if (hl.anchor) {
7191
- const attrs = [`w:anchor="${escapeXml(hl.anchor)}"`, "w:history=\"1\""];
7192
- if (hl.tooltip) attrs.push(`w:tooltip="${escapeXml(hl.tooltip)}"`);
7562
+ const attrs = [`w:anchor="${escapeXml(hl.anchor)}"`];
7563
+ pushHlAttrs(attrs);
7193
7564
  return `<w:hyperlink ${attrs.join(" ")}>${body}</w:hyperlink>`;
7194
7565
  }
7195
7566
  return "";
@@ -7228,14 +7599,14 @@ function stringifyChildDispatch(child, ctx) {
7228
7599
  }
7229
7600
  if ("moveToRangeEnd" in child) return `<w:moveToRangeEnd w:id="${child.moveToRangeEnd}"/>`;
7230
7601
  if ("movedFrom" in child) {
7231
- const { id, author, date, ...runOpts } = child.movedFrom;
7232
- const runXml = stringifyRunInline(runOpts, ctx);
7233
- return `<w:moveFrom w:id="${id}" w:author="${escapeXml(String(author))}" w:date="${date}">${runXml}</w:moveFrom>`;
7602
+ const { id, author, date, children } = child.movedFrom;
7603
+ const body = children.map((c) => stringifyRunInline(typeof c === "string" ? { text: c } : c, ctx)).join("");
7604
+ return `<w:moveFrom w:id="${id}" w:author="${escapeXml(String(author))}" w:date="${date}">${body}</w:moveFrom>`;
7234
7605
  }
7235
7606
  if ("movedTo" in child) {
7236
- const { id, author, date, ...runOpts } = child.movedTo;
7237
- const runXml = stringifyRunInline(runOpts, ctx);
7238
- return `<w:moveTo w:id="${id}" w:author="${escapeXml(String(author))}" w:date="${date}">${runXml}</w:moveTo>`;
7607
+ const { id, author, date, children } = child.movedTo;
7608
+ const body = children.map((c) => stringifyRunInline(typeof c === "string" ? { text: c } : c, ctx)).join("");
7609
+ return `<w:moveTo w:id="${id}" w:author="${escapeXml(String(author))}" w:date="${date}">${body}</w:moveTo>`;
7239
7610
  }
7240
7611
  if ("customXmlInsRangeStart" in child) {
7241
7612
  const o = child.customXmlInsRangeStart;
@@ -7259,8 +7630,11 @@ function stringifyChildDispatch(child, ctx) {
7259
7630
  if ("customXmlMoveToRangeEnd" in child) return `<w:customXmlMoveToRangeEnd w:id="${child.customXmlMoveToRangeEnd}"/>`;
7260
7631
  if ("simpleField" in child) {
7261
7632
  const sf = child.simpleField;
7262
- if (sf.cachedValue !== void 0) return `<w:fldSimple w:instr="${escapeXml(sf.instruction)}"><w:r><w:t>${escapeXml(sf.cachedValue)}</w:t></w:r></w:fldSimple>`;
7263
- return `<w:fldSimple w:instr="${escapeXml(sf.instruction)}"/>`;
7633
+ const sfAttrs = [`w:instr="${escapeXml(sf.instruction)}"`];
7634
+ if (sf.fldLock !== void 0) sfAttrs.push(`w:fldLock="${sf.fldLock ? 1 : 0}"`);
7635
+ if (sf.dirty !== void 0) sfAttrs.push(`w:dirty="${sf.dirty ? 1 : 0}"`);
7636
+ if (sf.cachedValue !== void 0) return `<w:fldSimple ${sfAttrs.join(" ")}><w:r><w:t>${escapeXml(sf.cachedValue)}</w:t></w:r></w:fldSimple>`;
7637
+ return `<w:fldSimple ${sfAttrs.join(" ")}/>`;
7264
7638
  }
7265
7639
  if ("complexField" in child) {
7266
7640
  const cf = child.complexField;
@@ -7746,10 +8120,10 @@ function stringifyTableRow(row, ctx, extraCells) {
7746
8120
  parts.splice(insertIdx, 0, stringifyTableCell(cell, ctx));
7747
8121
  }
7748
8122
  const rsidAttrs = [];
7749
- if (row.rsidRPr) rsidAttrs.push(` w:rsidRPr="${row.rsidRPr}"`);
7750
- if (row.rsidR) rsidAttrs.push(` w:rsidR="${row.rsidR}"`);
7751
- if (row.rsidDel) rsidAttrs.push(` w:rsidDel="${row.rsidDel}"`);
7752
- if (row.rsidTr) rsidAttrs.push(` w:rsidTr="${row.rsidTr}"`);
8123
+ if (row.runPropertiesRsid) rsidAttrs.push(` w:rsidRPr="${row.runPropertiesRsid}"`);
8124
+ if (row.rsid) rsidAttrs.push(` w:rsidR="${row.rsid}"`);
8125
+ if (row.deletionRsid) rsidAttrs.push(` w:rsidDel="${row.deletionRsid}"`);
8126
+ if (row.tableRowRsid) rsidAttrs.push(` w:rsidTr="${row.tableRowRsid}"`);
7753
8127
  const attr = rsidAttrs.join("");
7754
8128
  const body = parts.join("");
7755
8129
  return body ? `<w:tr${attr}>${body}</w:tr>` : attr ? `<w:tr${attr}/>` : "<w:tr/>";
@@ -7819,14 +8193,12 @@ function parseCellMargins(marginEl) {
7819
8193
  ]) {
7820
8194
  const sideEl = findChild(marginEl, `w:${side}`);
7821
8195
  if (sideEl) {
7822
- const size = attrNum(sideEl, "w:w");
7823
- if (size !== void 0) {
7824
- const type = attr(sideEl, "w:type");
7825
- margins[side] = type ? {
7826
- size,
7827
- type
7828
- } : { size };
7829
- }
8196
+ const type = attr(sideEl, "w:type");
8197
+ const size = attrMeasure(sideEl, "w:w", type);
8198
+ if (size !== void 0) margins[side] = type ? {
8199
+ size,
8200
+ type
8201
+ } : { size };
7830
8202
  }
7831
8203
  }
7832
8204
  if (Object.keys(margins).length === 0) return void 0;
@@ -7902,7 +8274,7 @@ function parseTablePropertyExceptions(el) {
7902
8274
  if (base.borders !== void 0) opts.borders = base.borders;
7903
8275
  if (base.shading !== void 0) opts.shading = base.shading;
7904
8276
  if (base.alignment !== void 0) opts.alignment = base.alignment;
7905
- if (base.margins !== void 0) opts.cellMargin = base.margins;
8277
+ if (base.cellMargin !== void 0) opts.cellMargin = base.cellMargin;
7906
8278
  if (base.tableLook !== void 0) opts.tableLook = base.tableLook;
7907
8279
  if (base.cellSpacing !== void 0) opts.cellSpacing = base.cellSpacing;
7908
8280
  const tblPrExChange = findChild(el, "w:tblPrExChange");
@@ -8001,9 +8373,8 @@ function parseTablePropertiesEl(el) {
8001
8373
  }
8002
8374
  const tblW = findChild(el, "w:tblW");
8003
8375
  if (tblW) {
8004
- const rawSize = attr(tblW, "w:w");
8005
8376
  const type = attr(tblW, "w:type");
8006
- const size = type === "pct" ? rawSize : attrNum(tblW, "w:w");
8377
+ const size = attrMeasure(tblW, "w:w", type);
8007
8378
  if (size !== void 0 || type) opts.width = {
8008
8379
  size: size ?? 0,
8009
8380
  ...type ? { type } : {}
@@ -8059,7 +8430,7 @@ function parseTablePropertiesEl(el) {
8059
8430
  const tblCellMar = findChild(el, "w:tblCellMar");
8060
8431
  if (tblCellMar) {
8061
8432
  const margins = parseCellMargins(tblCellMar);
8062
- if (margins) opts.margins = margins;
8433
+ if (margins) opts.cellMargin = margins;
8063
8434
  }
8064
8435
  const shd = findChild(el, "w:shd");
8065
8436
  if (shd) {
@@ -8105,8 +8476,8 @@ function parseTablePropertiesEl(el) {
8105
8476
  }
8106
8477
  const tblInd = findChild(el, "w:tblInd");
8107
8478
  if (tblInd) {
8108
- const size = attrNum(tblInd, "w:w");
8109
8479
  const type = attr(tblInd, "w:type");
8480
+ const size = attrMeasure(tblInd, "w:w", type);
8110
8481
  if (size !== void 0) opts.indent = {
8111
8482
  size,
8112
8483
  ...type ? { type } : {}
@@ -8132,7 +8503,7 @@ function parseTablePropertiesEl(el) {
8132
8503
  const tblCellSpacing = findChild(el, "w:tblCellSpacing");
8133
8504
  if (tblCellSpacing) {
8134
8505
  const type = attr(tblCellSpacing, "w:type");
8135
- const w = attrNum(tblCellSpacing, "w:w");
8506
+ const w = attrMeasure(tblCellSpacing, "w:w", type);
8136
8507
  if (w !== void 0) opts.cellSpacing = {
8137
8508
  size: w,
8138
8509
  ...type ? { type } : {}
@@ -8175,7 +8546,7 @@ function parseColumnWidthsEl(el) {
8175
8546
  const tblGrid = findChild(el, "w:tblGrid");
8176
8547
  if (!tblGrid) return { widths };
8177
8548
  for (const col of children(tblGrid, "w:gridCol")) {
8178
- const w = attrNum(col, "w:w");
8549
+ const w = attrMeasure(col, "w:w");
8179
8550
  widths.push(w ?? 100);
8180
8551
  }
8181
8552
  const tblGridChange = findChild(tblGrid, "w:tblGridChange");
@@ -8184,7 +8555,7 @@ function parseColumnWidthsEl(el) {
8184
8555
  const innerGrid = findChild(tblGridChange, "w:tblGrid");
8185
8556
  const revWidths = [];
8186
8557
  if (innerGrid) for (const col of children(innerGrid, "w:gridCol")) {
8187
- const w = attrNum(col, "w:w");
8558
+ const w = attrMeasure(col, "w:w");
8188
8559
  revWidths.push(w ?? 100);
8189
8560
  }
8190
8561
  if (id !== void 0) return {
@@ -8201,7 +8572,7 @@ function parseTableRowPropertiesEl(el) {
8201
8572
  const opts = {};
8202
8573
  const trHeight = findChild(el, "w:trHeight");
8203
8574
  if (trHeight) {
8204
- const val = attrNum(trHeight, "w:val");
8575
+ const val = attrMeasure(trHeight, "w:val");
8205
8576
  const rule = attr(trHeight, "w:hRule");
8206
8577
  if (val !== void 0) opts.height = {
8207
8578
  value: val,
@@ -8230,9 +8601,8 @@ function parseTableRowPropertiesEl(el) {
8230
8601
  }
8231
8602
  const wBefore = findChild(el, "w:wBefore");
8232
8603
  if (wBefore) {
8233
- const rawSize = attr(wBefore, "w:w");
8234
8604
  const type = attr(wBefore, "w:type");
8235
- const size = type === "pct" ? rawSize : attrNum(wBefore, "w:w");
8605
+ const size = attrMeasure(wBefore, "w:w", type);
8236
8606
  if (size !== void 0) opts.widthBefore = {
8237
8607
  size,
8238
8608
  ...type ? { type } : {}
@@ -8240,9 +8610,8 @@ function parseTableRowPropertiesEl(el) {
8240
8610
  }
8241
8611
  const wAfter = findChild(el, "w:wAfter");
8242
8612
  if (wAfter) {
8243
- const rawSize = attr(wAfter, "w:w");
8244
8613
  const type = attr(wAfter, "w:type");
8245
- const size = type === "pct" ? rawSize : attrNum(wAfter, "w:w");
8614
+ const size = attrMeasure(wAfter, "w:w", type);
8246
8615
  if (size !== void 0) opts.widthAfter = {
8247
8616
  size,
8248
8617
  ...type ? { type } : {}
@@ -8258,7 +8627,7 @@ function parseTableRowPropertiesEl(el) {
8258
8627
  const tblCellSpacing = findChild(el, "w:tblCellSpacing");
8259
8628
  if (tblCellSpacing) {
8260
8629
  const type = attr(tblCellSpacing, "w:type");
8261
- const w = attrNum(tblCellSpacing, "w:w");
8630
+ const w = attrMeasure(tblCellSpacing, "w:w", type);
8262
8631
  if (w !== void 0) opts.cellSpacing = {
8263
8632
  size: w,
8264
8633
  ...type ? { type } : {}
@@ -8296,8 +8665,8 @@ function parseTableCellPropertiesEl(el) {
8296
8665
  }
8297
8666
  const tcW = findChild(el, "w:tcW");
8298
8667
  if (tcW) {
8299
- const size = attrNum(tcW, "w:w");
8300
8668
  const type = attr(tcW, "w:type");
8669
+ const size = attrMeasure(tcW, "w:w", type);
8301
8670
  if (size !== void 0) opts.width = {
8302
8671
  size,
8303
8672
  ...type ? { type } : {}
@@ -8443,10 +8812,10 @@ function parseTableRowEl(el, ctx) {
8443
8812
  if (Object.keys(exceptions).length > 0) opts.propertyExceptions = exceptions;
8444
8813
  }
8445
8814
  for (const [attrName, optKey] of [
8446
- ["w:rsidRPr", "rsidRPr"],
8447
- ["w:rsidR", "rsidR"],
8448
- ["w:rsidDel", "rsidDel"],
8449
- ["w:rsidTr", "rsidTr"]
8815
+ ["w:rsidRPr", "runPropertiesRsid"],
8816
+ ["w:rsidR", "rsid"],
8817
+ ["w:rsidDel", "deletionRsid"],
8818
+ ["w:rsidTr", "tableRowRsid"]
8450
8819
  ]) {
8451
8820
  const val = attr(el, attrName);
8452
8821
  if (val) opts[optKey] = val;
@@ -8487,7 +8856,11 @@ function parseTableRowEl(el, ctx) {
8487
8856
  function parseTableEl(el, ctx) {
8488
8857
  const opts = {};
8489
8858
  const tblPr = findChild(el, "w:tblPr");
8490
- if (tblPr) Object.assign(opts, parseTablePropertiesEl(tblPr));
8859
+ if (tblPr) {
8860
+ const tblPrParsed = parseTablePropertiesEl(tblPr);
8861
+ Object.assign(opts, tblPrParsed);
8862
+ if (tblPrParsed.cellMargin !== void 0) opts.margins = tblPrParsed.cellMargin;
8863
+ }
8491
8864
  const grid = parseColumnWidthsEl(el);
8492
8865
  if (grid.widths.length > 0) opts.columnWidths = grid.widths;
8493
8866
  if (grid.revision) opts.columnWidthsRevision = grid.revision;
@@ -8901,10 +9274,15 @@ function stringifyLevel(opts) {
8901
9274
  if (opts.lvlRestart !== void 0) children.push(`<w:lvlRestart w:val="${decimalNumber(opts.lvlRestart)}"/>`);
8902
9275
  if (opts.suffix) children.push(`<w:suff w:val="${opts.suffix}"/>`);
8903
9276
  if (opts.isLegalNumberingStyle) children.push("<w:isLgl/>");
8904
- if (opts.text) children.push(`<w:lvlText w:val="${opts.text}"/>`);
9277
+ if (opts.text !== void 0 || opts.textNull) {
9278
+ const lvlTextAttrs = [];
9279
+ if (opts.text !== void 0) lvlTextAttrs.push(`w:val="${opts.text}"`);
9280
+ if (opts.textNull) lvlTextAttrs.push("w:null=\"1\"");
9281
+ children.push(`<w:lvlText ${lvlTextAttrs.join(" ")}/>`);
9282
+ }
8905
9283
  if (opts.lvlPicBulletId !== void 0) children.push(`<w:lvlPicBulletId w:val="${decimalNumber(opts.lvlPicBulletId)}"/>`);
8906
9284
  if (opts.legacy !== void 0) {
8907
- const legacyAttrs = [];
9285
+ const legacyAttrs = [`w:legacy="${opts.legacy.enabled ?? true ? 1 : 0}"`];
8908
9286
  if (opts.legacy.space !== void 0) legacyAttrs.push(`w:legacySpace="${opts.legacy.space}"`);
8909
9287
  if (opts.legacy.indent !== void 0) legacyAttrs.push(`w:legacyIndent="${opts.legacy.indent}"`);
8910
9288
  children.push(`<w:legacy ${legacyAttrs.join(" ")}/>`);
@@ -9006,6 +9384,8 @@ function parseLevelEl(el, parseParagraphProperties, ctx) {
9006
9384
  if (lvlText) {
9007
9385
  const val = attr(lvlText, "w:val");
9008
9386
  if (val) opts.text = val;
9387
+ const isNull = attrBool(lvlText, "w:null");
9388
+ if (isNull) opts.textNull = isNull;
9009
9389
  }
9010
9390
  const lvlPicBulletId = findChild(el, "w:lvlPicBulletId");
9011
9391
  if (lvlPicBulletId) {
@@ -9015,11 +9395,13 @@ function parseLevelEl(el, parseParagraphProperties, ctx) {
9015
9395
  const legacyEl = findChild(el, "w:legacy");
9016
9396
  if (legacyEl) {
9017
9397
  const legacy = {};
9398
+ const enabled = attrBool(legacyEl, "w:legacy");
9399
+ if (enabled !== void 0) legacy.enabled = enabled;
9018
9400
  const space = attrNum(legacyEl, "w:legacySpace");
9019
9401
  if (space !== void 0) legacy.space = space;
9020
9402
  const indent = attrNum(legacyEl, "w:legacyIndent");
9021
9403
  if (indent !== void 0) legacy.indent = indent;
9022
- if (Object.keys(legacy).length > 0) opts.legacy = legacy;
9404
+ opts.legacy = legacy;
9023
9405
  }
9024
9406
  const lvlJc = findChild(el, "w:lvlJc");
9025
9407
  if (lvlJc) {
@@ -9441,23 +9823,34 @@ const createHeaderFooterReference = (type, options) => `<${type} r:id="rId${opti
9441
9823
  function esc(s) {
9442
9824
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
9443
9825
  }
9826
+ /**
9827
+ * Build CT_Style style-level children (name…rsid), shared by paragraph/character/table styles.
9828
+ * Order follows CT_Style sequence: name, aliases, basedOn, next, link, autoRedefine, hidden,
9829
+ * uiPriority, semiHidden, unhideWhenUsed, qFormat, locked, personal, personalCompose,
9830
+ * personalReply, rsid.
9831
+ */
9832
+ function stringifyStyleLevelChildren(opts) {
9833
+ const parts = [`<w:name w:val="${esc(opts.name ?? opts.id ?? "")}"/>`];
9834
+ if (opts.aliases) parts.push(`<w:aliases w:val="${esc(opts.aliases)}"/>`);
9835
+ if (opts.basedOn) parts.push(`<w:basedOn w:val="${esc(opts.basedOn)}"/>`);
9836
+ if (opts.next) parts.push(`<w:next w:val="${esc(opts.next)}"/>`);
9837
+ if (opts.link) parts.push(`<w:link w:val="${esc(opts.link)}"/>`);
9838
+ if (opts.autoRedefine) parts.push("<w:autoRedefine/>");
9839
+ if (opts.hidden) parts.push("<w:hidden/>");
9840
+ if (opts.uiPriority !== void 0) parts.push(`<w:uiPriority w:val="${opts.uiPriority}"/>`);
9841
+ if (opts.semiHidden) parts.push("<w:semiHidden/>");
9842
+ if (opts.unhideWhenUsed) parts.push("<w:unhideWhenUsed/>");
9843
+ if (opts.quickFormat) parts.push("<w:qFormat/>");
9844
+ if (opts.locked) parts.push("<w:locked/>");
9845
+ if (opts.personal) parts.push("<w:personal/>");
9846
+ if (opts.personalCompose) parts.push("<w:personalCompose/>");
9847
+ if (opts.personalReply) parts.push("<w:personalReply/>");
9848
+ if (opts.rsid) parts.push(`<w:rsid w:val="${opts.rsid}"/>`);
9849
+ return parts.join("");
9850
+ }
9444
9851
  /** Build `<w:style>` XML for a paragraph style. */
9445
9852
  function stringifyParagraphStyle(opts) {
9446
- const children = [];
9447
- children.push(`<w:name w:val="${esc(opts.name ?? opts.id)}"/>`);
9448
- if (opts.aliases) children.push(`<w:aliases w:val="${esc(opts.aliases)}"/>`);
9449
- if (opts.basedOn) children.push(`<w:basedOn w:val="${esc(opts.basedOn)}"/>`);
9450
- if (opts.next) children.push(`<w:next w:val="${esc(opts.next)}"/>`);
9451
- if (opts.link) children.push(`<w:link w:val="${esc(opts.link)}"/>`);
9452
- if (opts.autoRedefine) children.push("<w:autoRedefine/>");
9453
- if (opts.uiPriority !== void 0) children.push(`<w:uiPriority w:val="${opts.uiPriority}"/>`);
9454
- if (opts.semiHidden) children.push("<w:semiHidden/>");
9455
- if (opts.unhideWhenUsed) children.push("<w:unhideWhenUsed/>");
9456
- if (opts.quickFormat) children.push("<w:qFormat/>");
9457
- if (opts.locked) children.push("<w:locked/>");
9458
- if (opts.personal) children.push("<w:personal/>");
9459
- if (opts.personalCompose) children.push("<w:personalCompose/>");
9460
- if (opts.personalReply) children.push("<w:personalReply/>");
9853
+ const children = [stringifyStyleLevelChildren(opts)];
9461
9854
  const pPr = stringifyParagraphProperties(opts.paragraph).xml;
9462
9855
  if (pPr) children.push(pPr);
9463
9856
  const rPr = stringifyRunProperties(opts.run);
@@ -9466,23 +9859,108 @@ function stringifyParagraphStyle(opts) {
9466
9859
  }
9467
9860
  /** Build `<w:style>` XML for a character style. */
9468
9861
  function stringifyCharacterStyle(opts) {
9469
- const children = [];
9470
- children.push(`<w:name w:val="${esc(opts.name ?? opts.id)}"/>`);
9471
- if (opts.aliases) children.push(`<w:aliases w:val="${esc(opts.aliases)}"/>`);
9472
- if (opts.basedOn) children.push(`<w:basedOn w:val="${esc(opts.basedOn)}"/>`);
9473
- if (opts.link) children.push(`<w:link w:val="${esc(opts.link)}"/>`);
9474
- if (opts.autoRedefine) children.push("<w:autoRedefine/>");
9475
- if (opts.uiPriority !== void 0) children.push(`<w:uiPriority w:val="${opts.uiPriority}"/>`);
9476
- if (opts.semiHidden) children.push("<w:semiHidden/>");
9477
- if (opts.unhideWhenUsed) children.push("<w:unhideWhenUsed/>");
9478
- if (opts.locked) children.push("<w:locked/>");
9479
- if (opts.personal) children.push("<w:personal/>");
9480
- if (opts.personalCompose) children.push("<w:personalCompose/>");
9481
- if (opts.personalReply) children.push("<w:personalReply/>");
9862
+ const children = [stringifyStyleLevelChildren(opts)];
9482
9863
  const rPr = stringifyRunProperties(opts.run);
9483
9864
  if (rPr) children.push(rPr);
9484
9865
  return `<w:style w:type="character" w:styleId="${esc(opts.id)}">${children.join("")}</w:style>`;
9485
9866
  }
9867
+ /** Build `<w:tblStylePr>` XML for a conditional table style format. */
9868
+ function stringifyConditionalTableStyle(opts) {
9869
+ const children = [];
9870
+ const pPr = stringifyParagraphProperties(opts.paragraph).xml;
9871
+ if (pPr) children.push(pPr);
9872
+ const rPr = stringifyRunProperties(opts.run);
9873
+ if (rPr) children.push(rPr);
9874
+ if (opts.table) {
9875
+ const tblPr = stringifyTableProperties(opts.table);
9876
+ if (tblPr) children.push(tblPr);
9877
+ }
9878
+ if (opts.row) {
9879
+ const trPr = stringifyTableRowProperties(opts.row);
9880
+ if (trPr) children.push(trPr);
9881
+ }
9882
+ if (opts.cell) {
9883
+ const tcPr = stringifyTableCellProperties(opts.cell);
9884
+ if (tcPr) children.push(tcPr);
9885
+ }
9886
+ return `<w:tblStylePr w:type="${opts.type}">${children.join("")}</w:tblStylePr>`;
9887
+ }
9888
+ /** Build `<w:style type="table">` XML for a table style. */
9889
+ function stringifyTableStyle(opts) {
9890
+ const children = [stringifyStyleLevelChildren(opts)];
9891
+ const pPr = stringifyParagraphProperties(opts.paragraph).xml;
9892
+ if (pPr) children.push(pPr);
9893
+ const rPr = stringifyRunProperties(opts.run);
9894
+ if (rPr) children.push(rPr);
9895
+ if (opts.table) {
9896
+ const tblPr = stringifyTableProperties(opts.table);
9897
+ if (tblPr) children.push(tblPr);
9898
+ }
9899
+ if (opts.row) {
9900
+ const trPr = stringifyTableRowProperties(opts.row);
9901
+ if (trPr) children.push(trPr);
9902
+ }
9903
+ if (opts.cell) {
9904
+ const tcPr = stringifyTableCellProperties(opts.cell);
9905
+ if (tcPr) children.push(tcPr);
9906
+ }
9907
+ for (const cf of opts.conditionalFormats ?? []) children.push(stringifyConditionalTableStyle(cf));
9908
+ return `<w:style w:type="table" w:styleId="${esc(opts.id)}">${children.join("")}</w:style>`;
9909
+ }
9910
+ /** Resolve a user override for heading level N (1-9) from default styles options. */
9911
+ function headingOverride(options, level) {
9912
+ switch (level) {
9913
+ case 1: return options.heading1;
9914
+ case 2: return options.heading2;
9915
+ case 3: return options.heading3;
9916
+ case 4: return options.heading4;
9917
+ case 5: return options.heading5;
9918
+ case 6: return options.heading6;
9919
+ case 7: return options.heading7;
9920
+ case 8: return options.heading8;
9921
+ case 9: return options.heading9;
9922
+ default: return;
9923
+ }
9924
+ }
9925
+ /**
9926
+ * Maps DefaultStylesOptions override fields to every built-in styleId the
9927
+ * factory (re)emits when that field is provided — the main style plus its
9928
+ * linked character style (e.g. heading1 -> Heading1 + Heading1Char).
9929
+ */
9930
+ const DEFAULT_STYLE_FIELDS = [
9931
+ ["title", ["Title", "TitleChar"]],
9932
+ ["subtitle", ["Subtitle", "SubtitleChar"]],
9933
+ ["heading1", ["Heading1", "Heading1Char"]],
9934
+ ["heading2", ["Heading2", "Heading2Char"]],
9935
+ ["heading3", ["Heading3", "Heading3Char"]],
9936
+ ["heading4", ["Heading4", "Heading4Char"]],
9937
+ ["heading5", ["Heading5", "Heading5Char"]],
9938
+ ["heading6", ["Heading6", "Heading6Char"]],
9939
+ ["heading7", ["Heading7", "Heading7Char"]],
9940
+ ["heading8", ["Heading8", "Heading8Char"]],
9941
+ ["heading9", ["Heading9", "Heading9Char"]],
9942
+ ["listParagraph", ["ListParagraph"]],
9943
+ ["quote", ["Quote", "QuoteChar"]],
9944
+ ["strong", ["Strong"]],
9945
+ ["emphasis", ["Emphasis"]]
9946
+ ];
9947
+ /**
9948
+ * Reverse map: main built-in styleId -> the DefaultStylesOptions field that
9949
+ * overrides it. Linked char ids (Heading1Char, TitleChar, ...) are excluded —
9950
+ * they ride along with their main style.
9951
+ */
9952
+ const STYLE_ID_TO_DEFAULT_FIELD = Object.fromEntries(DEFAULT_STYLE_FIELDS.map(([field, [mainId]]) => [mainId, field]));
9953
+ /**
9954
+ * Collect every styleId the factory (re)emits for the default-styles fields the
9955
+ * user explicitly provided — including linked character styles, so the
9956
+ * round-trip path drops the matching verbatim entries (no duplicate styleId).
9957
+ */
9958
+ function collectDefaultOverrideIds(defaultOpts) {
9959
+ const ids = /* @__PURE__ */ new Set();
9960
+ if (!defaultOpts) return ids;
9961
+ for (const [field, styleIds] of DEFAULT_STYLE_FIELDS) if (defaultOpts[field] !== void 0) for (const id of styleIds) ids.add(id);
9962
+ return ids;
9963
+ }
9486
9964
  /** Build `<w:docDefaults>` XML matching Word's default settings. */
9487
9965
  function stringifyDocDefaults(opts) {
9488
9966
  const children = [];
@@ -9522,7 +10000,7 @@ var DefaultStylesFactory = class {
9522
10000
  importedStyles.push({ _raw: stringifyDocDefaults(options.document ?? {}) });
9523
10001
  importedStyles.push({ _raw: "<w:latentStyles w:defLockedState=\"0\" w:defUIPriority=\"99\" w:defSemiHidden=\"0\" w:defUnhideWhenUsed=\"0\" w:defQFormat=\"0\" w:count=\"376\"><w:lsdException w:name=\"Normal\" w:uiPriority=\"0\" w:qFormat=\"1\"/><w:lsdException w:name=\"heading 1\" w:uiPriority=\"9\" w:qFormat=\"1\"/><w:lsdException w:name=\"heading 2\" w:semiHidden=\"1\" w:uiPriority=\"9\" w:unhideWhenUsed=\"1\" w:qFormat=\"1\"/><w:lsdException w:name=\"heading 3\" w:semiHidden=\"1\" w:uiPriority=\"9\" w:unhideWhenUsed=\"1\" w:qFormat=\"1\"/><w:lsdException w:name=\"heading 4\" w:semiHidden=\"1\" w:uiPriority=\"9\" w:unhideWhenUsed=\"1\" w:qFormat=\"1\"/><w:lsdException w:name=\"heading 5\" w:semiHidden=\"1\" w:uiPriority=\"9\" w:unhideWhenUsed=\"1\" w:qFormat=\"1\"/><w:lsdException w:name=\"heading 6\" w:semiHidden=\"1\" w:uiPriority=\"9\" w:unhideWhenUsed=\"1\" w:qFormat=\"1\"/><w:lsdException w:name=\"heading 7\" w:semiHidden=\"1\" w:uiPriority=\"9\" w:unhideWhenUsed=\"1\" w:qFormat=\"1\"/><w:lsdException w:name=\"heading 8\" w:semiHidden=\"1\" w:uiPriority=\"9\" w:unhideWhenUsed=\"1\" w:qFormat=\"1\"/><w:lsdException w:name=\"heading 9\" w:semiHidden=\"1\" w:uiPriority=\"9\" w:unhideWhenUsed=\"1\" w:qFormat=\"1\"/><w:lsdException w:name=\"Default Paragraph Font\" w:semiHidden=\"1\" w:uiPriority=\"1\" w:unhideWhenUsed=\"1\"/><w:lsdException w:name=\"Normal Table\" w:semiHidden=\"1\" w:uiPriority=\"99\" w:unhideWhenUsed=\"1\"/><w:lsdException w:name=\"No List\" w:semiHidden=\"1\" w:uiPriority=\"99\" w:unhideWhenUsed=\"1\"/><w:lsdException w:name=\"Subtitle\" w:uiPriority=\"11\" w:qFormat=\"1\"/><w:lsdException w:name=\"Strong\" w:uiPriority=\"22\" w:qFormat=\"1\"/><w:lsdException w:name=\"Emphasis\" w:uiPriority=\"20\" w:qFormat=\"1\"/><w:lsdException w:name=\"Hyperlink\" w:semiHidden=\"1\" w:unhideWhenUsed=\"1\"/><w:lsdException w:name=\"FollowedHyperlink\" w:semiHidden=\"1\" w:unhideWhenUsed=\"1\"/><w:lsdException w:name=\"No Spacing\" w:uiPriority=\"1\" w:qFormat=\"1\"/><w:lsdException w:name=\"Revision\" w:semiHidden=\"1\"/></w:latentStyles>" });
9524
10002
  importedStyles.push({ _raw: "<w:style w:type=\"paragraph\" w:default=\"1\" w:styleId=\"Normal\"><w:name w:val=\"Normal\"/><w:qFormat/><w:pPr><w:widowControl w:val=\"0\"/></w:pPr></w:style>" });
9525
- for (const h of [
10003
+ const headings = [
9526
10004
  {
9527
10005
  id: "Heading1",
9528
10006
  name: "heading 1",
@@ -9604,7 +10082,36 @@ var DefaultStylesFactory = class {
9604
10082
  after: "0",
9605
10083
  outlineLvl: "8"
9606
10084
  }
9607
- ]) {
10085
+ ];
10086
+ for (let headingIdx = 0; headingIdx < headings.length; headingIdx++) {
10087
+ const h = headings[headingIdx];
10088
+ const headingOverrideOpts = headingOverride(options, headingIdx + 1);
10089
+ if (headingOverrideOpts) {
10090
+ importedStyles.push({ _raw: stringifyParagraphStyle({
10091
+ id: h.id,
10092
+ name: headingOverrideOpts.name ?? h.name,
10093
+ basedOn: headingOverrideOpts.basedOn ?? "Normal",
10094
+ next: headingOverrideOpts.next ?? "Normal",
10095
+ link: headingOverrideOpts.link ?? h.link,
10096
+ uiPriority: headingOverrideOpts.uiPriority ?? 9,
10097
+ quickFormat: headingOverrideOpts.quickFormat ?? true,
10098
+ semiHidden: headingOverrideOpts.semiHidden,
10099
+ unhideWhenUsed: headingOverrideOpts.unhideWhenUsed,
10100
+ paragraph: {
10101
+ outlineLevel: headingIdx,
10102
+ ...headingOverrideOpts.paragraph
10103
+ },
10104
+ run: headingOverrideOpts.run
10105
+ }) });
10106
+ importedStyles.push({ _raw: stringifyCharacterStyle({
10107
+ id: h.link,
10108
+ name: `${h.name} Char`,
10109
+ basedOn: "DefaultParagraphFont",
10110
+ link: h.id,
10111
+ run: headingOverrideOpts.run
10112
+ }) });
10113
+ continue;
10114
+ }
9608
10115
  const pPrParts = [`<w:keepNext/>`, `<w:keepLines/>`];
9609
10116
  if (h.before || h.after) {
9610
10117
  const sp = [];
@@ -9629,13 +10136,103 @@ var DefaultStylesFactory = class {
9629
10136
  importedStyles.push({ _raw: "<w:style w:type=\"character\" w:default=\"1\" w:styleId=\"DefaultParagraphFont\"><w:name w:val=\"Default Paragraph Font\"/><w:uiPriority w:val=\"1\"/><w:semiHidden/><w:unhideWhenUsed/></w:style>" });
9630
10137
  importedStyles.push({ _raw: "<w:style w:type=\"table\" w:default=\"1\" w:styleId=\"NormalTable\"><w:name w:val=\"Normal Table\"/><w:uiPriority w:val=\"99\"/><w:semiHidden/><w:unhideWhenUsed/><w:tblPr><w:tblInd w:w=\"0\" w:type=\"dxa\"/><w:tblCellMar><w:top w:w=\"0\" w:type=\"dxa\"/><w:left w:w=\"108\" w:type=\"dxa\"/><w:bottom w:w=\"0\" w:type=\"dxa\"/><w:right w:w=\"108\" w:type=\"dxa\"/></w:tblCellMar></w:tblPr></w:style>" });
9631
10138
  importedStyles.push({ _raw: "<w:style w:type=\"numbering\" w:default=\"1\" w:styleId=\"NoList\"><w:name w:val=\"No List\"/><w:uiPriority w:val=\"99\"/><w:semiHidden/><w:unhideWhenUsed/></w:style>" });
9632
- importedStyles.push({ _raw: "<w:style w:type=\"paragraph\" w:styleId=\"Title\"><w:name w:val=\"Title\"/><w:basedOn w:val=\"Normal\"/><w:next w:val=\"Normal\"/><w:link w:val=\"TitleChar\"/><w:uiPriority w:val=\"10\"/><w:qFormat/><w:pPr><w:spacing w:after=\"80\" w:line=\"240\" w:lineRule=\"auto\"/><w:contextualSpacing/><w:jc w:val=\"center\"/></w:pPr><w:rPr><w:rFonts w:asciiTheme=\"majorHAnsi\" w:eastAsiaTheme=\"majorEastAsia\" w:hAnsiTheme=\"majorHAnsi\" w:cstheme=\"majorBidi\"/><w:spacing w:val=\"-10\"/><w:kern w:val=\"28\"/><w:sz w:val=\"56\"/><w:szCs w:val=\"56\"/></w:rPr></w:style>" });
9633
- importedStyles.push({ _raw: "<w:style w:type=\"character\" w:styleId=\"TitleChar\"><w:name w:val=\"Title Char\"/><w:basedOn w:val=\"DefaultParagraphFont\"/><w:link w:val=\"Title\"/><w:uiPriority w:val=\"10\"/><w:rPr><w:rFonts w:asciiTheme=\"majorHAnsi\" w:eastAsiaTheme=\"majorEastAsia\" w:hAnsiTheme=\"majorHAnsi\" w:cstheme=\"majorBidi\"/><w:spacing w:val=\"-10\"/><w:kern w:val=\"28\"/><w:sz w:val=\"56\"/><w:szCs w:val=\"56\"/></w:rPr></w:style>" });
9634
- importedStyles.push({ _raw: "<w:style w:type=\"paragraph\" w:styleId=\"Subtitle\"><w:name w:val=\"Subtitle\"/><w:basedOn w:val=\"Normal\"/><w:next w:val=\"Normal\"/><w:link w:val=\"SubtitleChar\"/><w:uiPriority w:val=\"11\"/><w:qFormat/><w:pPr><w:jc w:val=\"center\"/></w:pPr><w:rPr><w:rFonts w:asciiTheme=\"majorHAnsi\" w:eastAsiaTheme=\"majorEastAsia\" w:hAnsiTheme=\"majorHAnsi\" w:cstheme=\"majorBidi\"/><w:color w:val=\"595959\" w:themeColor=\"text1\" w:themeTint=\"A6\"/><w:spacing w:val=\"15\"/><w:sz w:val=\"28\"/><w:szCs w:val=\"28\"/></w:rPr></w:style>" });
9635
- importedStyles.push({ _raw: "<w:style w:type=\"character\" w:styleId=\"SubtitleChar\"><w:name w:val=\"Subtitle Char\"/><w:basedOn w:val=\"DefaultParagraphFont\"/><w:link w:val=\"Subtitle\"/><w:uiPriority w:val=\"11\"/><w:rPr><w:rFonts w:asciiTheme=\"majorHAnsi\" w:eastAsiaTheme=\"majorEastAsia\" w:hAnsiTheme=\"majorHAnsi\" w:cstheme=\"majorBidi\"/><w:color w:val=\"595959\" w:themeColor=\"text1\" w:themeTint=\"A6\"/><w:spacing w:val=\"15\"/><w:sz w:val=\"28\"/><w:szCs w:val=\"28\"/></w:rPr></w:style>" });
9636
- importedStyles.push({ _raw: "<w:style w:type=\"paragraph\" w:styleId=\"ListParagraph\"><w:name w:val=\"List Paragraph\"/><w:basedOn w:val=\"Normal\"/><w:uiPriority w:val=\"34\"/><w:qFormat/><w:pPr><w:ind w:left=\"720\"/><w:contextualSpacing/></w:pPr></w:style>" });
9637
- importedStyles.push({ _raw: "<w:style w:type=\"paragraph\" w:styleId=\"Quote\"><w:name w:val=\"Quote\"/><w:basedOn w:val=\"Normal\"/><w:next w:val=\"Normal\"/><w:link w:val=\"QuoteChar\"/><w:uiPriority w:val=\"29\"/><w:qFormat/><w:pPr><w:spacing w:before=\"160\"/><w:jc w:val=\"center\"/></w:pPr><w:rPr><w:i/><w:iCs/><w:color w:val=\"404040\" w:themeColor=\"text1\" w:themeTint=\"BF\"/></w:rPr></w:style>" });
9638
- importedStyles.push({ _raw: "<w:style w:type=\"character\" w:styleId=\"QuoteChar\"><w:name w:val=\"Quote Char\"/><w:basedOn w:val=\"DefaultParagraphFont\"/><w:link w:val=\"Quote\"/><w:uiPriority w:val=\"29\"/><w:rPr><w:i/><w:iCs/><w:color w:val=\"404040\" w:themeColor=\"text1\" w:themeTint=\"BF\"/></w:rPr></w:style>" });
10139
+ if (options.title) {
10140
+ importedStyles.push({ _raw: stringifyParagraphStyle({
10141
+ id: "Title",
10142
+ name: options.title.name ?? "Title",
10143
+ basedOn: options.title.basedOn ?? "Normal",
10144
+ next: options.title.next ?? "Normal",
10145
+ link: options.title.link ?? "TitleChar",
10146
+ uiPriority: options.title.uiPriority ?? 10,
10147
+ quickFormat: options.title.quickFormat ?? true,
10148
+ paragraph: options.title.paragraph,
10149
+ run: options.title.run
10150
+ }) });
10151
+ importedStyles.push({ _raw: stringifyCharacterStyle({
10152
+ id: "TitleChar",
10153
+ name: "Title Char",
10154
+ basedOn: "DefaultParagraphFont",
10155
+ link: "Title",
10156
+ run: options.title.run
10157
+ }) });
10158
+ } else {
10159
+ importedStyles.push({ _raw: "<w:style w:type=\"paragraph\" w:styleId=\"Title\"><w:name w:val=\"Title\"/><w:basedOn w:val=\"Normal\"/><w:next w:val=\"Normal\"/><w:link w:val=\"TitleChar\"/><w:uiPriority w:val=\"10\"/><w:qFormat/><w:pPr><w:spacing w:after=\"80\" w:line=\"240\" w:lineRule=\"auto\"/><w:contextualSpacing/><w:jc w:val=\"center\"/></w:pPr><w:rPr><w:rFonts w:asciiTheme=\"majorHAnsi\" w:eastAsiaTheme=\"majorEastAsia\" w:hAnsiTheme=\"majorHAnsi\" w:cstheme=\"majorBidi\"/><w:spacing w:val=\"-10\"/><w:kern w:val=\"28\"/><w:sz w:val=\"56\"/><w:szCs w:val=\"56\"/></w:rPr></w:style>" });
10160
+ importedStyles.push({ _raw: "<w:style w:type=\"character\" w:styleId=\"TitleChar\"><w:name w:val=\"Title Char\"/><w:basedOn w:val=\"DefaultParagraphFont\"/><w:link w:val=\"Title\"/><w:uiPriority w:val=\"10\"/><w:rPr><w:rFonts w:asciiTheme=\"majorHAnsi\" w:eastAsiaTheme=\"majorEastAsia\" w:hAnsiTheme=\"majorHAnsi\" w:cstheme=\"majorBidi\"/><w:spacing w:val=\"-10\"/><w:kern w:val=\"28\"/><w:sz w:val=\"56\"/><w:szCs w:val=\"56\"/></w:rPr></w:style>" });
10161
+ }
10162
+ if (options.subtitle) {
10163
+ importedStyles.push({ _raw: stringifyParagraphStyle({
10164
+ id: "Subtitle",
10165
+ name: options.subtitle.name ?? "Subtitle",
10166
+ basedOn: options.subtitle.basedOn ?? "Normal",
10167
+ next: options.subtitle.next ?? "Normal",
10168
+ link: options.subtitle.link ?? "SubtitleChar",
10169
+ uiPriority: options.subtitle.uiPriority ?? 11,
10170
+ quickFormat: options.subtitle.quickFormat ?? true,
10171
+ paragraph: options.subtitle.paragraph,
10172
+ run: options.subtitle.run
10173
+ }) });
10174
+ importedStyles.push({ _raw: stringifyCharacterStyle({
10175
+ id: "SubtitleChar",
10176
+ name: "Subtitle Char",
10177
+ basedOn: "DefaultParagraphFont",
10178
+ link: "Subtitle",
10179
+ run: options.subtitle.run
10180
+ }) });
10181
+ } else {
10182
+ importedStyles.push({ _raw: "<w:style w:type=\"paragraph\" w:styleId=\"Subtitle\"><w:name w:val=\"Subtitle\"/><w:basedOn w:val=\"Normal\"/><w:next w:val=\"Normal\"/><w:link w:val=\"SubtitleChar\"/><w:uiPriority w:val=\"11\"/><w:qFormat/><w:pPr><w:jc w:val=\"center\"/></w:pPr><w:rPr><w:rFonts w:asciiTheme=\"majorHAnsi\" w:eastAsiaTheme=\"majorEastAsia\" w:hAnsiTheme=\"majorHAnsi\" w:cstheme=\"majorBidi\"/><w:color w:val=\"595959\" w:themeColor=\"text1\" w:themeTint=\"A6\"/><w:spacing w:val=\"15\"/><w:sz w:val=\"28\"/><w:szCs w:val=\"28\"/></w:rPr></w:style>" });
10183
+ importedStyles.push({ _raw: "<w:style w:type=\"character\" w:styleId=\"SubtitleChar\"><w:name w:val=\"Subtitle Char\"/><w:basedOn w:val=\"DefaultParagraphFont\"/><w:link w:val=\"Subtitle\"/><w:uiPriority w:val=\"11\"/><w:rPr><w:rFonts w:asciiTheme=\"majorHAnsi\" w:eastAsiaTheme=\"majorEastAsia\" w:hAnsiTheme=\"majorHAnsi\" w:cstheme=\"majorBidi\"/><w:color w:val=\"595959\" w:themeColor=\"text1\" w:themeTint=\"A6\"/><w:spacing w:val=\"15\"/><w:sz w:val=\"28\"/><w:szCs w:val=\"28\"/></w:rPr></w:style>" });
10184
+ }
10185
+ if (options.listParagraph) importedStyles.push({ _raw: stringifyParagraphStyle({
10186
+ id: "ListParagraph",
10187
+ name: options.listParagraph.name ?? "List Paragraph",
10188
+ basedOn: options.listParagraph.basedOn ?? "Normal",
10189
+ uiPriority: options.listParagraph.uiPriority ?? 34,
10190
+ quickFormat: options.listParagraph.quickFormat ?? true,
10191
+ paragraph: options.listParagraph.paragraph,
10192
+ run: options.listParagraph.run
10193
+ }) });
10194
+ else importedStyles.push({ _raw: "<w:style w:type=\"paragraph\" w:styleId=\"ListParagraph\"><w:name w:val=\"List Paragraph\"/><w:basedOn w:val=\"Normal\"/><w:uiPriority w:val=\"34\"/><w:qFormat/><w:pPr><w:ind w:left=\"720\"/><w:contextualSpacing/></w:pPr></w:style>" });
10195
+ if (options.strong) importedStyles.push({ _raw: stringifyParagraphStyle({
10196
+ id: "Strong",
10197
+ name: options.strong.name ?? "Strong",
10198
+ basedOn: options.strong.basedOn ?? "Normal",
10199
+ next: options.strong.next ?? "Normal",
10200
+ quickFormat: options.strong.quickFormat ?? true,
10201
+ paragraph: options.strong.paragraph,
10202
+ run: options.strong.run
10203
+ }) });
10204
+ if (options.emphasis) importedStyles.push({ _raw: stringifyParagraphStyle({
10205
+ id: "Emphasis",
10206
+ name: options.emphasis.name ?? "Emphasis",
10207
+ basedOn: options.emphasis.basedOn ?? "Normal",
10208
+ next: options.emphasis.next ?? "Normal",
10209
+ quickFormat: options.emphasis.quickFormat ?? true,
10210
+ paragraph: options.emphasis.paragraph,
10211
+ run: options.emphasis.run
10212
+ }) });
10213
+ if (options.quote) {
10214
+ importedStyles.push({ _raw: stringifyParagraphStyle({
10215
+ id: "Quote",
10216
+ name: options.quote.name ?? "Quote",
10217
+ basedOn: options.quote.basedOn ?? "Normal",
10218
+ next: options.quote.next ?? "Normal",
10219
+ link: options.quote.link ?? "QuoteChar",
10220
+ uiPriority: options.quote.uiPriority ?? 29,
10221
+ quickFormat: options.quote.quickFormat ?? true,
10222
+ paragraph: options.quote.paragraph,
10223
+ run: options.quote.run
10224
+ }) });
10225
+ importedStyles.push({ _raw: stringifyCharacterStyle({
10226
+ id: "QuoteChar",
10227
+ name: "Quote Char",
10228
+ basedOn: "DefaultParagraphFont",
10229
+ link: "Quote",
10230
+ run: options.quote.run
10231
+ }) });
10232
+ } else {
10233
+ importedStyles.push({ _raw: "<w:style w:type=\"paragraph\" w:styleId=\"Quote\"><w:name w:val=\"Quote\"/><w:basedOn w:val=\"Normal\"/><w:next w:val=\"Normal\"/><w:link w:val=\"QuoteChar\"/><w:uiPriority w:val=\"29\"/><w:qFormat/><w:pPr><w:spacing w:before=\"160\"/><w:jc w:val=\"center\"/></w:pPr><w:rPr><w:i/><w:iCs/><w:color w:val=\"404040\" w:themeColor=\"text1\" w:themeTint=\"BF\"/></w:rPr></w:style>" });
10234
+ importedStyles.push({ _raw: "<w:style w:type=\"character\" w:styleId=\"QuoteChar\"><w:name w:val=\"Quote Char\"/><w:basedOn w:val=\"DefaultParagraphFont\"/><w:link w:val=\"Quote\"/><w:uiPriority w:val=\"29\"/><w:rPr><w:i/><w:iCs/><w:color w:val=\"404040\" w:themeColor=\"text1\" w:themeTint=\"BF\"/></w:rPr></w:style>" });
10235
+ }
9639
10236
  importedStyles.push({ _raw: "<w:style w:type=\"paragraph\" w:styleId=\"IntenseQuote\"><w:name w:val=\"Intense Quote\"/><w:basedOn w:val=\"Normal\"/><w:next w:val=\"Normal\"/><w:link w:val=\"IntenseQuoteChar\"/><w:uiPriority w:val=\"30\"/><w:qFormat/><w:pPr><w:pBdr><w:top w:val=\"single\" w:sz=\"4\" w:space=\"10\" w:color=\"0F4761\" w:themeColor=\"accent1\" w:themeShade=\"BF\"/><w:bottom w:val=\"single\" w:sz=\"4\" w:space=\"10\" w:color=\"0F4761\" w:themeColor=\"accent1\" w:themeShade=\"BF\"/></w:pBdr><w:spacing w:before=\"360\" w:after=\"360\"/><w:ind w:left=\"864\" w:right=\"864\"/><w:jc w:val=\"center\"/></w:pPr><w:rPr><w:i/><w:iCs/><w:color w:val=\"0F4761\" w:themeColor=\"accent1\" w:themeShade=\"BF\"/></w:rPr></w:style>" });
9640
10237
  importedStyles.push({ _raw: "<w:style w:type=\"character\" w:styleId=\"IntenseQuoteChar\"><w:name w:val=\"Intense Quote Char\"/><w:basedOn w:val=\"DefaultParagraphFont\"/><w:link w:val=\"IntenseQuote\"/><w:uiPriority w:val=\"30\"/><w:rPr><w:i/><w:iCs/><w:color w:val=\"0F4761\" w:themeColor=\"accent1\" w:themeShade=\"BF\"/></w:rPr></w:style>" });
9641
10238
  importedStyles.push({ _raw: stringifyCharacterStyle({
@@ -9738,6 +10335,16 @@ var DefaultStylesFactory = class {
9738
10335
  * @module
9739
10336
  */
9740
10337
  /**
10338
+ * Extract the `w:styleId` from a raw `<w:style>` XML string, if present.
10339
+ *
10340
+ * Returns `undefined` for non-style elements (docDefaults / latentStyles),
10341
+ * whose raw XML carries no `w:styleId` attribute.
10342
+ */
10343
+ function extractStyleId(raw) {
10344
+ const m = raw.match(/w:styleId="([^"]+)"/);
10345
+ return m ? m[1] : void 0;
10346
+ }
10347
+ /**
9741
10348
  * Represents the styles definitions in a WordprocessingML document.
9742
10349
  *
9743
10350
  * Pure collector — no XmlComponent inheritance.
@@ -9748,8 +10355,17 @@ var Styles = class {
9748
10355
  parts = [];
9749
10356
  constructor(options) {
9750
10357
  if (options.initialAttributes) this.attributes = options.initialAttributes;
9751
- if (options.importedStyles) {
9752
- for (const style of options.importedStyles) if (style._raw) this.parts.push(style._raw);
10358
+ const customStyleIds = /* @__PURE__ */ new Set();
10359
+ for (const s of options.paragraphStyles ?? []) customStyleIds.add(s.id);
10360
+ for (const s of options.characterStyles ?? []) customStyleIds.add(s.id);
10361
+ for (const s of options.tableStyles ?? []) customStyleIds.add(s.id);
10362
+ if (options.importedStyles) for (const style of options.importedStyles) {
10363
+ if (!style._raw) continue;
10364
+ if (customStyleIds.size > 0) {
10365
+ const id = extractStyleId(style._raw);
10366
+ if (id && customStyleIds.has(id)) continue;
10367
+ }
10368
+ this.parts.push(style._raw);
9753
10369
  }
9754
10370
  if (options.paragraphStyles) for (const style of options.paragraphStyles) this.parts.push(stringifyParagraphStyle({
9755
10371
  id: style.id,
@@ -9786,6 +10402,7 @@ var Styles = class {
9786
10402
  personalReply: style.personalReply,
9787
10403
  run: style.run
9788
10404
  }));
10405
+ if (options.tableStyles) for (const style of options.tableStyles) this.parts.push(stringifyTableStyle(style));
9789
10406
  }
9790
10407
  /**
9791
10408
  * Serialize to word/styles.xml content (with XML declaration).
@@ -9851,6 +10468,7 @@ function parseStyleDefinitions(el, parseParagraphProperties, ctx) {
9851
10468
  const opts = {};
9852
10469
  const paragraphStyles = [];
9853
10470
  const characterStyles = [];
10471
+ const tableStyles = [];
9854
10472
  for (const child of el.elements ?? []) if (child.name === "w:docDefaults") {
9855
10473
  const defOpts = parseDocDefaults(child, parseParagraphProperties, ctx);
9856
10474
  if (defOpts) opts.default = defOpts;
@@ -9859,7 +10477,19 @@ function parseStyleDefinitions(el, parseParagraphProperties, ctx) {
9859
10477
  else if (child.name === "w:style") {
9860
10478
  const styleOpts = parseStyleElement(child, parseParagraphProperties, ctx);
9861
10479
  if (!styleOpts?._type || !styleOpts.id) continue;
10480
+ if (styleOpts._type === "table") {
10481
+ delete styleOpts._type;
10482
+ tableStyles.push(styleOpts);
10483
+ continue;
10484
+ }
9862
10485
  (opts.importedStyles ??= []).push({ _raw: stringifyElement(child) });
10486
+ const defaultField = STYLE_ID_TO_DEFAULT_FIELD[styleOpts.id];
10487
+ if (defaultField) {
10488
+ const { _type: _omitType, id: _omitId, ...rest } = styleOpts;
10489
+ opts.default ??= {};
10490
+ opts.default[defaultField] = rest;
10491
+ continue;
10492
+ }
9863
10493
  if (BUILTIN_STYLE_IDS.has(styleOpts.id)) continue;
9864
10494
  const type = styleOpts._type;
9865
10495
  delete styleOpts._type;
@@ -9868,6 +10498,7 @@ function parseStyleDefinitions(el, parseParagraphProperties, ctx) {
9868
10498
  }
9869
10499
  if (paragraphStyles.length > 0) opts.paragraphStyles = paragraphStyles;
9870
10500
  if (characterStyles.length > 0) opts.characterStyles = characterStyles;
10501
+ if (tableStyles.length > 0) opts.tableStyles = tableStyles;
9871
10502
  return Object.keys(opts).length > 0 ? opts : void 0;
9872
10503
  }
9873
10504
  function parseDocDefaults(el, parseParagraphProperties, ctx) {
@@ -9931,6 +10562,12 @@ function parseStyleElement(el, parseParagraphProperties, ctx) {
9931
10562
  if (findChild(el, "w:personal")) opts.personal = true;
9932
10563
  if (findChild(el, "w:personalCompose")) opts.personalCompose = true;
9933
10564
  if (findChild(el, "w:personalReply")) opts.personalReply = true;
10565
+ if (findChild(el, "w:hidden")) opts.hidden = true;
10566
+ const rsidEl = findChild(el, "w:rsid");
10567
+ if (rsidEl) {
10568
+ const val = attr(rsidEl, "w:val");
10569
+ if (val) opts.rsid = val;
10570
+ }
9934
10571
  const aliases = findChild(el, "w:aliases");
9935
10572
  if (aliases) {
9936
10573
  const val = attr(aliases, "w:val");
@@ -9946,6 +10583,55 @@ function parseStyleElement(el, parseParagraphProperties, ctx) {
9946
10583
  const runOpts = parseRunProperties(rPr);
9947
10584
  if (Object.keys(runOpts).length > 0) opts.run = runOpts;
9948
10585
  }
10586
+ const tblPr = findChild(el, "w:tblPr");
10587
+ if (tblPr) {
10588
+ const tableOpts = parseTablePropertiesEl(tblPr);
10589
+ if (Object.keys(tableOpts).length > 0) opts.table = tableOpts;
10590
+ }
10591
+ const trPr = findChild(el, "w:trPr");
10592
+ if (trPr) {
10593
+ const rowOpts = parseTableRowPropertiesEl(trPr);
10594
+ if (Object.keys(rowOpts).length > 0) opts.row = rowOpts;
10595
+ }
10596
+ const tcPr = findChild(el, "w:tcPr");
10597
+ if (tcPr) {
10598
+ const cellOpts = parseTableCellPropertiesEl(tcPr);
10599
+ if (Object.keys(cellOpts).length > 0) opts.cell = cellOpts;
10600
+ }
10601
+ const conditionalFormats = [];
10602
+ for (const child of el.elements ?? []) {
10603
+ if (child.name !== "w:tblStylePr") continue;
10604
+ const type = attr(child, "w:type");
10605
+ if (!type) continue;
10606
+ const cf = { type };
10607
+ const cfPPr = findChild(child, "w:pPr");
10608
+ if (cfPPr) {
10609
+ const paraOpts = parseParagraphProperties(cfPPr, ctx);
10610
+ if (Object.keys(paraOpts).length > 0) cf.paragraph = paraOpts;
10611
+ }
10612
+ const cfRPr = findChild(child, "w:rPr");
10613
+ if (cfRPr) {
10614
+ const runOpts = parseRunProperties(cfRPr);
10615
+ if (Object.keys(runOpts).length > 0) cf.run = runOpts;
10616
+ }
10617
+ const cfTblPr = findChild(child, "w:tblPr");
10618
+ if (cfTblPr) {
10619
+ const tableOpts = parseTablePropertiesEl(cfTblPr);
10620
+ if (Object.keys(tableOpts).length > 0) cf.table = tableOpts;
10621
+ }
10622
+ const cfTrPr = findChild(child, "w:trPr");
10623
+ if (cfTrPr) {
10624
+ const rowOpts = parseTableRowPropertiesEl(cfTrPr);
10625
+ if (Object.keys(rowOpts).length > 0) cf.row = rowOpts;
10626
+ }
10627
+ const cfTcPr = findChild(child, "w:tcPr");
10628
+ if (cfTcPr) {
10629
+ const cellOpts = parseTableCellPropertiesEl(cfTcPr);
10630
+ if (Object.keys(cellOpts).length > 0) cf.cell = cellOpts;
10631
+ }
10632
+ conditionalFormats.push(cf);
10633
+ }
10634
+ if (conditionalFormats.length > 0) opts.conditionalFormats = conditionalFormats;
9949
10635
  return opts;
9950
10636
  }
9951
10637
  //#endregion
@@ -9986,8 +10672,443 @@ function attrEl(tag, attrs) {
9986
10672
  const a = attrStr(attrs);
9987
10673
  return a ? `<${tag} ${a}/>` : `<${tag}/>`;
9988
10674
  }
9989
- function compatSetting(name, val) {
9990
- return `<w:compatSetting w:name="${escapeAttr$1(name)}" w:uri="http://schemas.microsoft.com/office/word" w:val="${val}"/>`;
10675
+ function compatSetting(name, val, uri) {
10676
+ const u = uri ?? "http://schemas.microsoft.com/office/word";
10677
+ return `<w:compatSetting w:name="${escapeAttr$1(name)}" w:uri="${u}" w:val="${val}"/>`;
10678
+ }
10679
+ /** Read a CT_OnOff child as boolean (presence true unless val is explicitly false). */
10680
+ function readOnOff(el) {
10681
+ if (!el || !el.name) return void 0;
10682
+ const v = attr(el, valAttr(el.name));
10683
+ return v !== "false" && v !== "0" && v !== "off";
10684
+ }
10685
+ /** Read an attribute as a number, or undefined if absent/unparseable. */
10686
+ function readNum(el, name) {
10687
+ if (!el) return void 0;
10688
+ const v = attr(el, name);
10689
+ if (v === void 0 || v === "") return void 0;
10690
+ const n = parseInt(v, 10);
10691
+ return Number.isNaN(n) ? void 0 : n;
10692
+ }
10693
+ /** Read an attribute as a string, or undefined if absent. */
10694
+ function readStr(el, name) {
10695
+ if (!el) return void 0;
10696
+ const v = attr(el, name);
10697
+ return v === void 0 || v === "" ? void 0 : v;
10698
+ }
10699
+ /** Read an attribute constrained to an enum; undefined if absent or not allowed. */
10700
+ function readEnum(el, name, allowed) {
10701
+ const v = readStr(el, name);
10702
+ return v !== void 0 && allowed.includes(v) ? v : void 0;
10703
+ }
10704
+ /** Shared password/crypto attributes (AG_TransitionalPassword) → options keys. */
10705
+ const PASSWORD_ATTR_MAP = [
10706
+ [
10707
+ "hashValue",
10708
+ "w:hashValue",
10709
+ false
10710
+ ],
10711
+ [
10712
+ "saltValue",
10713
+ "w:saltValue",
10714
+ false
10715
+ ],
10716
+ [
10717
+ "hash",
10718
+ "w:hash",
10719
+ false
10720
+ ],
10721
+ [
10722
+ "salt",
10723
+ "w:salt",
10724
+ false
10725
+ ],
10726
+ [
10727
+ "spinCount",
10728
+ "w:spinCount",
10729
+ true
10730
+ ],
10731
+ [
10732
+ "algorithmName",
10733
+ "w:algorithmName",
10734
+ false
10735
+ ],
10736
+ [
10737
+ "cryptoAlgorithmClass",
10738
+ "w:cryptAlgorithmClass",
10739
+ false
10740
+ ],
10741
+ [
10742
+ "cryptoAlgorithmSid",
10743
+ "w:cryptAlgorithmSid",
10744
+ true
10745
+ ],
10746
+ [
10747
+ "cryptoAlgorithmType",
10748
+ "w:cryptAlgorithmType",
10749
+ false
10750
+ ],
10751
+ [
10752
+ "cryptoProvider",
10753
+ "w:cryptProvider",
10754
+ false
10755
+ ],
10756
+ [
10757
+ "cryptoProviderType",
10758
+ "w:cryptProviderType",
10759
+ false
10760
+ ],
10761
+ [
10762
+ "cryptoProviderTypeExtension",
10763
+ "w:cryptProviderTypeExt",
10764
+ true
10765
+ ],
10766
+ [
10767
+ "cryptoProviderTypeExtensionSource",
10768
+ "w:cryptProviderTypeExtSource",
10769
+ false
10770
+ ],
10771
+ [
10772
+ "algorithmExtensionId",
10773
+ "w:algIdExt",
10774
+ true
10775
+ ],
10776
+ [
10777
+ "algorithmExtensionSource",
10778
+ "w:algIdExtSource",
10779
+ false
10780
+ ],
10781
+ [
10782
+ "cryptoSpinCount",
10783
+ "w:cryptSpinCount",
10784
+ true
10785
+ ]
10786
+ ];
10787
+ /** Read shared password/crypto attributes into an options object. */
10788
+ function readPasswordAttrs(el) {
10789
+ const out = {};
10790
+ for (const [key, xmlAttr, isNum] of PASSWORD_ATTR_MAP) {
10791
+ const v = attr(el, xmlAttr);
10792
+ if (v === void 0 || v === "") continue;
10793
+ out[key] = isNum ? parseInt(v, 10) : v;
10794
+ }
10795
+ return out;
10796
+ }
10797
+ /**
10798
+ * CT_OnOff compat flag elements → CompatibilityOptions keys. The XML tag often
10799
+ * differs from the option key (e.g. wordPerfectJustification → w:wpJustification).
10800
+ * Order mirrors stringifyCompatibility so round-trip preserves element order.
10801
+ */
10802
+ const COMPAT_FLAG_MAP = [
10803
+ ["useSingleBorderforContiguousCells", "w:useSingleBorderforContiguousCells"],
10804
+ ["wordPerfectJustification", "w:wpJustification"],
10805
+ ["noTabStopForHangingIndent", "w:noTabHangInd"],
10806
+ ["noLeading", "w:noLeading"],
10807
+ ["spaceForUnderline", "w:spaceForUL"],
10808
+ ["noColumnBalance", "w:noColumnBalance"],
10809
+ ["balanceSingleByteDoubleByteWidth", "w:balanceSingleByteDoubleByteWidth"],
10810
+ ["noExtraLineSpacing", "w:noExtraLineSpacing"],
10811
+ ["doNotLeaveBackslashAlone", "w:doNotLeaveBackslashAlone"],
10812
+ ["underlineTrailingSpaces", "w:ulTrailSpace"],
10813
+ ["doNotExpandShiftReturn", "w:doNotExpandShiftReturn"],
10814
+ ["spacingInWholePoints", "w:spacingInWholePoints"],
10815
+ ["lineWrapLikeWord6", "w:lineWrapLikeWord6"],
10816
+ ["printBodyTextBeforeHeader", "w:printBodyTextBeforeHeader"],
10817
+ ["printColorsBlack", "w:printColBlack"],
10818
+ ["spaceWidth", "w:wpSpaceWidth"],
10819
+ ["showBreaksInFrames", "w:showBreaksInFrames"],
10820
+ ["subFontBySize", "w:subFontBySize"],
10821
+ ["suppressBottomSpacing", "w:suppressBottomSpacing"],
10822
+ ["suppressTopSpacing", "w:suppressTopSpacing"],
10823
+ ["suppressSpacingAtTopOfPage", "w:suppressSpacingAtTopOfPage"],
10824
+ ["suppressTopSpacingWP", "w:suppressTopSpacingWP"],
10825
+ ["suppressSpBfAfterPgBrk", "w:suppressSpBfAfterPgBrk"],
10826
+ ["swapBordersFacingPages", "w:swapBordersFacingPages"],
10827
+ ["convertMailMergeEsc", "w:convMailMergeEsc"],
10828
+ ["truncateFontHeightsLikeWP6", "w:truncateFontHeightsLikeWP6"],
10829
+ ["macWordSmallCaps", "w:mwSmallCaps"],
10830
+ ["usePrinterMetrics", "w:usePrinterMetrics"],
10831
+ ["doNotSuppressParagraphBorders", "w:doNotSuppressParagraphBorders"],
10832
+ ["wrapTrailSpaces", "w:wrapTrailSpaces"],
10833
+ ["footnoteLayoutLikeWW8", "w:footnoteLayoutLikeWW8"],
10834
+ ["shapeLayoutLikeWW8", "w:shapeLayoutLikeWW8"],
10835
+ ["alignTablesRowByRow", "w:alignTablesRowByRow"],
10836
+ ["forgetLastTabAlignment", "w:forgetLastTabAlignment"],
10837
+ ["adjustLineHeightInTable", "w:adjustLineHeightInTable"],
10838
+ ["autoSpaceLikeWord95", "w:autoSpaceLikeWord95"],
10839
+ ["noSpaceRaiseLower", "w:noSpaceRaiseLower"],
10840
+ ["doNotUseHTMLParagraphAutoSpacing", "w:doNotUseHTMLParagraphAutoSpacing"],
10841
+ ["layoutRawTableWidth", "w:layoutRawTableWidth"],
10842
+ ["layoutTableRowsApart", "w:layoutTableRowsApart"],
10843
+ ["useWord97LineBreakRules", "w:useWord97LineBreakRules"],
10844
+ ["doNotBreakWrappedTables", "w:doNotBreakWrappedTables"],
10845
+ ["doNotSnapToGridInCell", "w:doNotSnapToGridInCell"],
10846
+ ["selectFieldWithFirstOrLastCharacter", "w:selectFldWithFirstOrLastChar"],
10847
+ ["applyBreakingRules", "w:applyBreakingRules"],
10848
+ ["doNotWrapTextWithPunctuation", "w:doNotWrapTextWithPunct"],
10849
+ ["doNotUseEastAsianBreakRules", "w:doNotUseEastAsianBreakRules"],
10850
+ ["useWord2002TableStyleRules", "w:useWord2002TableStyleRules"],
10851
+ ["growAutofit", "w:growAutofit"],
10852
+ ["useFELayout", "w:useFELayout"],
10853
+ ["useNormalStyleForList", "w:useNormalStyleForList"],
10854
+ ["doNotUseIndentAsNumberingTabStop", "w:doNotUseIndentAsNumberingTabStop"],
10855
+ ["useAlternateEastAsianLineBreakRules", "w:useAltKinsokuLineBreakRules"],
10856
+ ["allowSpaceOfSameStyleInTable", "w:allowSpaceOfSameStyleInTable"],
10857
+ ["doNotSuppressIndentation", "w:doNotSuppressIndentation"],
10858
+ ["doNotAutofitConstrainedTables", "w:doNotAutofitConstrainedTables"],
10859
+ ["autofitToFirstFixedWidthCell", "w:autofitToFirstFixedWidthCell"],
10860
+ ["underlineTabInNumberingList", "w:underlineTabInNumList"],
10861
+ ["displayHangulFixedWidth", "w:displayHangulFixedWidth"],
10862
+ ["splitPgBreakAndParaMark", "w:splitPgBreakAndParaMark"],
10863
+ ["doNotVerticallyAlignCellWithSp", "w:doNotVertAlignCellWithSp"],
10864
+ ["doNotBreakConstrainedForcedTable", "w:doNotBreakConstrainedForcedTable"],
10865
+ ["ignoreVerticalAlignmentInTextboxes", "w:doNotVertAlignInTxbx"],
10866
+ ["useAnsiKerningPairs", "w:useAnsiKerningPairs"],
10867
+ ["cachedColumnBalance", "w:cachedColBalance"]
10868
+ ];
10869
+ /** compatSetting names that map to dedicated sugar fields (not into compatSettings[]). */
10870
+ const COMPAT_SETTING_SUGAR = {
10871
+ compatibilityMode: "version",
10872
+ overrideTableStyleFontSizeAndJustification: "overrideTableStyleFontSizeAndJustification",
10873
+ enableOpenTypeFeatures: "enableOpenTypeFeatures",
10874
+ doNotFlipMirrorIndents: "doNotFlipMirrorIndents"
10875
+ };
10876
+ /** Parse w:footnotePr / w:endnotePr (CT_FtnDocProps / CT_EdnDocProps). */
10877
+ function parseFtnEdnPr(el) {
10878
+ const o = {};
10879
+ const pos = readStr(findChild(el, "w:pos"), "w:val");
10880
+ if (pos) o.pos = pos;
10881
+ const numFmtEl = findChild(el, "w:numFmt");
10882
+ if (numFmtEl) {
10883
+ const v = readStr(numFmtEl, "w:val");
10884
+ if (v) o.numFmt = v;
10885
+ const format = readStr(numFmtEl, "w:format");
10886
+ if (format) o.format = format;
10887
+ }
10888
+ const numStart = readNum(findChild(el, "w:numStart"), "w:val");
10889
+ if (numStart !== void 0) o.numStart = numStart;
10890
+ const numRestart = readStr(findChild(el, "w:numRestart"), "w:val");
10891
+ if (numRestart) o.numRestart = numRestart;
10892
+ return Object.keys(o).length > 0 ? o : void 0;
10893
+ }
10894
+ /** Parse w:compat (CT_Compat): on/off flag elements + w:compatSetting entries. */
10895
+ function parseCompatibility(el) {
10896
+ const o = {};
10897
+ const flagMap = Object.fromEntries(COMPAT_FLAG_MAP.map(([key, tag]) => [tag, key]));
10898
+ const extras = [];
10899
+ for (const child of el.elements ?? []) {
10900
+ if (child.type !== "element" || !child.name) continue;
10901
+ const key = flagMap[child.name];
10902
+ if (key !== void 0) {
10903
+ o[key] = true;
10904
+ continue;
10905
+ }
10906
+ if (child.name === "w:compatSetting") {
10907
+ const name = attr(child, "w:name");
10908
+ const val = attr(child, "w:val");
10909
+ if (name === void 0 || val === void 0) continue;
10910
+ const sugar = COMPAT_SETTING_SUGAR[name];
10911
+ if (sugar === "version") {
10912
+ const n = parseInt(val, 10);
10913
+ if (!Number.isNaN(n)) o.version = n;
10914
+ } else if (sugar !== void 0) o[sugar] = val !== "0" && val !== "false";
10915
+ else extras.push({
10916
+ name,
10917
+ val,
10918
+ uri: attr(child, "w:uri")
10919
+ });
10920
+ }
10921
+ }
10922
+ if (extras.length > 0) o.compatSettings = extras;
10923
+ return Object.keys(o).length > 0 ? o : void 0;
10924
+ }
10925
+ /** Parse m:mathPr (CT_MathPr). */
10926
+ function parseMathPr(el) {
10927
+ const o = {};
10928
+ const mathFont = readStr(findChild(el, "m:mathFont"), "m:val");
10929
+ if (mathFont) o.mathFont = mathFont;
10930
+ const binaryOperatorBreak = readEnum(findChild(el, "m:brkBin"), "m:val", [
10931
+ "before",
10932
+ "after",
10933
+ "repeat"
10934
+ ]);
10935
+ if (binaryOperatorBreak) o.binaryOperatorBreak = binaryOperatorBreak;
10936
+ const binaryOperatorBreakSubtraction = readEnum(findChild(el, "m:brkBinSub"), "m:val", [
10937
+ "--",
10938
+ "-+",
10939
+ "+-"
10940
+ ]);
10941
+ if (binaryOperatorBreakSubtraction) o.binaryOperatorBreakSubtraction = binaryOperatorBreakSubtraction;
10942
+ const smallFractions = readOnOff(findChild(el, "m:smallFrac"));
10943
+ if (smallFractions !== void 0) o.smallFractions = smallFractions;
10944
+ const displayDefaults = readOnOff(findChild(el, "m:dispDef"));
10945
+ if (displayDefaults !== void 0) o.displayDefaults = displayDefaults;
10946
+ const leftMargin = readNum(findChild(el, "m:lMargin"), "m:val");
10947
+ if (leftMargin !== void 0) o.leftMargin = leftMargin;
10948
+ const rightMargin = readNum(findChild(el, "m:rMargin"), "m:val");
10949
+ if (rightMargin !== void 0) o.rightMargin = rightMargin;
10950
+ const defaultJustification = readEnum(findChild(el, "m:defJc"), "m:val", [
10951
+ "left",
10952
+ "right",
10953
+ "center",
10954
+ "centerGroup"
10955
+ ]);
10956
+ if (defaultJustification) o.defaultJustification = defaultJustification;
10957
+ const preSpacing = readNum(findChild(el, "m:preSp"), "m:val");
10958
+ if (preSpacing !== void 0) o.preSpacing = preSpacing;
10959
+ const postSpacing = readNum(findChild(el, "m:postSp"), "m:val");
10960
+ if (postSpacing !== void 0) o.postSpacing = postSpacing;
10961
+ const interSpacing = readNum(findChild(el, "m:interSp"), "m:val");
10962
+ if (interSpacing !== void 0) o.interSpacing = interSpacing;
10963
+ const intraSpacing = readNum(findChild(el, "m:intraSp"), "m:val");
10964
+ if (intraSpacing !== void 0) o.intraSpacing = intraSpacing;
10965
+ const wrapIndent = readNum(findChild(el, "m:wrapIndent"), "m:val");
10966
+ if (wrapIndent !== void 0) o.wrapIndent = wrapIndent;
10967
+ const wrapRight = readOnOff(findChild(el, "m:wrapRight"));
10968
+ if (wrapRight !== void 0) o.wrapRight = wrapRight;
10969
+ const integralLimitLocation = readEnum(findChild(el, "m:intLim"), "m:val", ["subSup", "undOvr"]);
10970
+ if (integralLimitLocation) o.integralLimitLocation = integralLimitLocation;
10971
+ const naryLimitLocation = readEnum(findChild(el, "m:naryLim"), "m:val", ["subSup", "undOvr"]);
10972
+ if (naryLimitLocation) o.naryLimitLocation = naryLimitLocation;
10973
+ return Object.keys(o).length > 0 ? o : void 0;
10974
+ }
10975
+ /** Parse w:captions (CT_Captions). */
10976
+ function parseCaptions(el) {
10977
+ const captions = [];
10978
+ const autoCaptions = [];
10979
+ for (const child of el.elements ?? []) {
10980
+ if (child.type !== "element") continue;
10981
+ if (child.name === "w:caption") {
10982
+ const c = { name: attr(child, "w:name") ?? "" };
10983
+ const pos = attr(child, "w:pos");
10984
+ if (pos) c.pos = pos;
10985
+ const chapNum = attr(child, "w:chapNum");
10986
+ if (chapNum !== void 0) c.chapNum = chapNum === "1";
10987
+ const heading = attr(child, "w:heading");
10988
+ if (heading !== void 0) c.heading = parseInt(heading, 10);
10989
+ const noLabel = attr(child, "w:noLabel");
10990
+ if (noLabel !== void 0) c.noLabel = noLabel === "1";
10991
+ const numFmt = attr(child, "w:numFmt");
10992
+ if (numFmt) c.numFmt = numFmt;
10993
+ const sep = attr(child, "w:sep");
10994
+ if (sep) c.sep = sep;
10995
+ captions.push(c);
10996
+ } else if (child.name === "w:autoCaptions") for (const ac of child.elements ?? []) {
10997
+ if (ac.name !== "w:autoCaption") continue;
10998
+ const name = attr(ac, "w:name");
10999
+ const caption = attr(ac, "w:caption");
11000
+ if (name && caption) autoCaptions.push({
11001
+ name,
11002
+ caption
11003
+ });
11004
+ }
11005
+ }
11006
+ if (captions.length === 0) return void 0;
11007
+ const o = { captions };
11008
+ if (autoCaptions.length > 0) o.autoCaptions = autoCaptions;
11009
+ return o;
11010
+ }
11011
+ /** Parse w:odso (CT_Odso). */
11012
+ function parseOdso(el) {
11013
+ const o = {};
11014
+ const udl = readStr(findChild(el, "w:udl"), "w:val");
11015
+ if (udl) o.udl = udl;
11016
+ const table = readStr(findChild(el, "w:table"), "w:val");
11017
+ if (table) o.table = table;
11018
+ const srcEl = findChild(el, "w:src");
11019
+ if (srcEl) {
11020
+ const rid = attr(srcEl, "r:id");
11021
+ if (rid) o.src = rid;
11022
+ }
11023
+ const colDelim = readNum(findChild(el, "w:colDelim"), "w:val");
11024
+ if (colDelim !== void 0) o.colDelim = colDelim;
11025
+ const type = readStr(findChild(el, "w:type"), "w:val");
11026
+ if (type) o.type = type;
11027
+ const fHdr = readOnOff(findChild(el, "w:fHdr"));
11028
+ if (fHdr !== void 0) o.fHdr = fHdr;
11029
+ const fieldMapData = [];
11030
+ for (const child of el.elements ?? []) {
11031
+ if (child.name !== "w:fieldMapData") continue;
11032
+ const fm = {};
11033
+ const t = readStr(findChild(child, "w:type"), "w:val");
11034
+ if (t) fm.type = t;
11035
+ const n = readStr(findChild(child, "w:name"), "w:val");
11036
+ if (n) fm.name = n;
11037
+ const mn = readStr(findChild(child, "w:mappedName"), "w:val");
11038
+ if (mn) fm.mappedName = mn;
11039
+ const col = readNum(findChild(child, "w:column"), "w:val");
11040
+ if (col !== void 0) fm.column = col;
11041
+ const lid = readStr(findChild(child, "w:lid"), "w:val");
11042
+ if (lid) fm.lid = lid;
11043
+ const dyn = readOnOff(findChild(child, "w:dynamicAddress"));
11044
+ if (dyn !== void 0) fm.dynamicAddress = dyn;
11045
+ if (Object.keys(fm).length > 0) fieldMapData.push(fm);
11046
+ }
11047
+ if (fieldMapData.length > 0) o.fieldMapData = fieldMapData;
11048
+ const recipientData = [];
11049
+ for (const child of el.elements ?? []) {
11050
+ if (child.name !== "w:recipientData") continue;
11051
+ const rid = attr(child, "r:id");
11052
+ if (rid) recipientData.push(rid);
11053
+ }
11054
+ if (recipientData.length > 0) o.recipientData = recipientData;
11055
+ const uniqueTag = readStr(findChild(el, "w:uniqueTag"), "w:val");
11056
+ if (uniqueTag) o.uniqueTag = uniqueTag;
11057
+ return Object.keys(o).length > 0 ? o : void 0;
11058
+ }
11059
+ /** Parse w:mailMerge (CT_MailMerge). */
11060
+ function parseMailMerge(el) {
11061
+ const o = {};
11062
+ const mdt = readStr(findChild(el, "w:mainDocumentType"), "w:val");
11063
+ if (mdt) o.mainDocumentType = mdt;
11064
+ const dataType = readStr(findChild(el, "w:dataType"), "w:val");
11065
+ if (dataType) o.dataType = dataType;
11066
+ const dest = readStr(findChild(el, "w:destination"), "w:val");
11067
+ if (dest) o.destination = dest;
11068
+ const connectString = readStr(findChild(el, "w:connectString"), "w:val");
11069
+ if (connectString) o.connectString = connectString;
11070
+ const query = readStr(findChild(el, "w:query"), "w:val");
11071
+ if (query) o.query = query;
11072
+ const dsEl = findChild(el, "w:dataSource");
11073
+ if (dsEl) {
11074
+ const rid = attr(dsEl, "r:id");
11075
+ if (rid) o.dataSource = rid;
11076
+ }
11077
+ const hsEl = findChild(el, "w:headerSource");
11078
+ if (hsEl) {
11079
+ const rid = attr(hsEl, "r:id");
11080
+ if (rid) o.headerSource = rid;
11081
+ }
11082
+ const linkToQuery = readOnOff(findChild(el, "w:linkToQuery"));
11083
+ if (linkToQuery !== void 0) o.linkToQuery = linkToQuery;
11084
+ const doNotSuppress = readOnOff(findChild(el, "w:doNotSuppressBlankLines"));
11085
+ if (doNotSuppress !== void 0) o.doNotSuppressBlankLines = doNotSuppress;
11086
+ const addressFieldName = readStr(findChild(el, "w:addressFieldName"), "w:val");
11087
+ if (addressFieldName) o.addressFieldName = addressFieldName;
11088
+ const mailSubject = readStr(findChild(el, "w:mailSubject"), "w:val");
11089
+ if (mailSubject) o.mailSubject = mailSubject;
11090
+ const mailAsAttachment = readOnOff(findChild(el, "w:mailAsAttachment"));
11091
+ if (mailAsAttachment !== void 0) o.mailAsAttachment = mailAsAttachment;
11092
+ const viewMergedData = readOnOff(findChild(el, "w:viewMergedData"));
11093
+ if (viewMergedData !== void 0) o.viewMergedData = viewMergedData;
11094
+ const activeRecord = readNum(findChild(el, "w:activeRecord"), "w:val");
11095
+ if (activeRecord !== void 0) o.activeRecord = activeRecord;
11096
+ const checkErrors = readNum(findChild(el, "w:checkErrors"), "w:val");
11097
+ if (checkErrors !== void 0) o.checkErrors = checkErrors;
11098
+ const active = readOnOff(findChild(el, "w:active"));
11099
+ if (active !== void 0) o.active = active;
11100
+ const recipientsEl = findChild(el, "w:recipients");
11101
+ if (recipientsEl) {
11102
+ const rid = attr(recipientsEl, "r:id");
11103
+ if (rid) o.recipients = rid;
11104
+ }
11105
+ const odsoEl = findChild(el, "w:odso");
11106
+ if (odsoEl) {
11107
+ const odso = parseOdso(odsoEl);
11108
+ if (odso) o.odso = odso;
11109
+ }
11110
+ if (Object.keys(o).length === 0) return void 0;
11111
+ return o;
9991
11112
  }
9992
11113
  function maybeDerive(password, hashValue) {
9993
11114
  return password !== void 0 && hashValue === void 0 ? derivePasswordHash(password) : void 0;
@@ -10163,16 +11284,21 @@ function stringifyCaptions(opts) {
10163
11284
  function stringifyMathPr(opts) {
10164
11285
  const p = [];
10165
11286
  if (opts.mathFont !== void 0) p.push(attrEl("m:mathFont", { "m:val": opts.mathFont }));
10166
- if (opts.brkBin !== void 0) p.push(attrEl("m:brkBin", { "m:val": opts.brkBin }));
10167
- if (opts.brkBinSub !== void 0) p.push(attrEl("m:brkBinSub", { "m:val": opts.brkBinSub }));
10168
- p.push(onOff("m:smallFrac", opts.smallFrac));
10169
- p.push(onOff("m:dispDef", opts.dispDef));
10170
- p.push(numVal("m:lMargin", opts.lMargin));
10171
- p.push(numVal("m:rMargin", opts.rMargin));
10172
- if (opts.defJc !== void 0) p.push(attrEl("m:defJc", { "m:val": opts.defJc }));
11287
+ if (opts.binaryOperatorBreak !== void 0) p.push(attrEl("m:brkBin", { "m:val": opts.binaryOperatorBreak }));
11288
+ if (opts.binaryOperatorBreakSubtraction !== void 0) p.push(attrEl("m:brkBinSub", { "m:val": opts.binaryOperatorBreakSubtraction }));
11289
+ p.push(onOff("m:smallFrac", opts.smallFractions));
11290
+ p.push(onOff("m:dispDef", opts.displayDefaults));
11291
+ p.push(numVal("m:lMargin", opts.leftMargin));
11292
+ p.push(numVal("m:rMargin", opts.rightMargin));
11293
+ if (opts.defaultJustification !== void 0) p.push(attrEl("m:defJc", { "m:val": opts.defaultJustification }));
11294
+ p.push(numVal("m:preSp", opts.preSpacing));
11295
+ p.push(numVal("m:postSp", opts.postSpacing));
11296
+ p.push(numVal("m:interSp", opts.interSpacing));
11297
+ p.push(numVal("m:intraSp", opts.intraSpacing));
10173
11298
  p.push(numVal("m:wrapIndent", opts.wrapIndent));
10174
- if (opts.intLim !== void 0) p.push(attrEl("m:intLim", { "m:val": opts.intLim }));
10175
- if (opts.naryLim !== void 0) p.push(attrEl("m:naryLim", { "m:val": opts.naryLim }));
11299
+ p.push(onOff("m:wrapRight", opts.wrapRight));
11300
+ if (opts.integralLimitLocation !== void 0) p.push(attrEl("m:intLim", { "m:val": opts.integralLimitLocation }));
11301
+ if (opts.naryLimitLocation !== void 0) p.push(attrEl("m:naryLim", { "m:val": opts.naryLimitLocation }));
10176
11302
  return `<m:mathPr>${p.join("")}</m:mathPr>`;
10177
11303
  }
10178
11304
  function stringifyColorSchemeMapping(opts) {
@@ -10262,6 +11388,18 @@ function stringifyCompatibility(opts) {
10262
11388
  if (opts.overrideTableStyleFontSizeAndJustification) p.push(compatSetting("overrideTableStyleFontSizeAndJustification", 1));
10263
11389
  if (opts.enableOpenTypeFeatures) p.push(compatSetting("enableOpenTypeFeatures", 1));
10264
11390
  if (opts.doNotFlipMirrorIndents) p.push(compatSetting("doNotFlipMirrorIndents", 1));
11391
+ if (opts.compatSettings) {
11392
+ const emitted = /* @__PURE__ */ new Set();
11393
+ if (opts.version) emitted.add("compatibilityMode");
11394
+ if (opts.overrideTableStyleFontSizeAndJustification) emitted.add("overrideTableStyleFontSizeAndJustification");
11395
+ if (opts.enableOpenTypeFeatures) emitted.add("enableOpenTypeFeatures");
11396
+ if (opts.doNotFlipMirrorIndents) emitted.add("doNotFlipMirrorIndents");
11397
+ for (const cs of opts.compatSettings) {
11398
+ if (emitted.has(cs.name)) continue;
11399
+ p.push(compatSetting(cs.name, cs.val, cs.uri));
11400
+ emitted.add(cs.name);
11401
+ }
11402
+ }
10265
11403
  return p.length ? `<w:compat>${p.join("")}</w:compat>` : "";
10266
11404
  }
10267
11405
  const SETTINGS_NS = "xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" mc:Ignorable=\"w14 w15 wp14\"";
@@ -10331,7 +11469,8 @@ const settingsDesc = {
10331
11469
  ["clearFormatting", "w:clearFormatting"],
10332
11470
  ["top3HeadingStyles", "w:top3HeadingStyles"],
10333
11471
  ["visibleStyles", "w:visibleStyles"],
10334
- ["alternateStyleNames", "w:alternateStyleNames"]
11472
+ ["alternateStyleNames", "w:alternateStyleNames"],
11473
+ ["latentStyles", "w:latentStyles"]
10335
11474
  ]) if (f[prop] !== void 0) attrs[xmlKey] = f[prop] ? "1" : "0";
10336
11475
  p.push(attrEl("w:stylePaneFormatFilter", attrs));
10337
11476
  }
@@ -10401,7 +11540,7 @@ const settingsDesc = {
10401
11540
  p.push(onOff("w:showXMLTags", opts.showXMLTags));
10402
11541
  p.push(onOff("w:alwaysMergeEmptyNamespace", opts.alwaysMergeEmptyNamespace));
10403
11542
  p.push(onOff("w:updateFields", opts.updateFields));
10404
- if (opts.hdrShapeDefaults !== void 0) p.push("<w:hdrShapeDefaults/>");
11543
+ if (opts.hdrShapeDefaults !== void 0) p.push(`<w:hdrShapeDefaults>${opts.hdrShapeDefaults}</w:hdrShapeDefaults>`);
10405
11544
  if (opts.footnotePr !== void 0) p.push(stringifyFootnotePr(opts.footnotePr));
10406
11545
  if (opts.endnotePr !== void 0) p.push(stringifyEndnotePr(opts.endnotePr));
10407
11546
  const compatXml = stringifyCompatibility({
@@ -10420,7 +11559,13 @@ const settingsDesc = {
10420
11559
  if (opts.mathPr !== void 0) p.push(stringifyMathPr(opts.mathPr));
10421
11560
  if (opts.attachedSchema !== void 0) for (const schema of opts.attachedSchema) p.push(strVal("w:attachedSchema", schema));
10422
11561
  if (opts.colorSchemeMapping !== void 0) p.push(stringifyColorSchemeMapping(opts.colorSchemeMapping));
10423
- if (opts.themeFontLang !== void 0) p.push(attrEl("w:themeFontLang", { "w:val": opts.themeFontLang }));
11562
+ if (opts.themeFontLang !== void 0) {
11563
+ const a = {};
11564
+ if (opts.themeFontLang.val !== void 0) a["w:val"] = opts.themeFontLang.val;
11565
+ if (opts.themeFontLang.eastAsia !== void 0) a["w:eastAsia"] = opts.themeFontLang.eastAsia;
11566
+ if (opts.themeFontLang.bidi !== void 0) a["w:bidi"] = opts.themeFontLang.bidi;
11567
+ p.push(attrEl("w:themeFontLang", a));
11568
+ }
10424
11569
  p.push(onOff("w:doNotIncludeSubdocsInStats", opts.doNotIncludeSubdocsInStats));
10425
11570
  p.push(onOff("w:doNotAutoCompressPictures", opts.doNotAutoCompressPictures));
10426
11571
  if (opts.forceUpgrade !== void 0) p.push("<w:forceUpgrade/>");
@@ -10435,168 +11580,84 @@ const settingsDesc = {
10435
11580
  p.push(attrEl("w:smartTagType", attrs));
10436
11581
  }
10437
11582
  p.push(onOff("w:doNotEmbedSmartTags", opts.doNotEmbedSmartTags));
10438
- if (opts.shapeDefaults !== void 0) p.push("<w:shapeDefaults/>");
11583
+ if (opts.shapeDefaults !== void 0) p.push(`<w:shapeDefaults>${opts.shapeDefaults}</w:shapeDefaults>`);
10439
11584
  p.push(strVal("w:decimalSymbol", opts.decimalSymbol));
10440
11585
  p.push(strVal("w:listSeparator", opts.listSeparator));
10441
11586
  return `<w:settings ${SETTINGS_NS}>${p.join("")}</w:settings>`;
10442
11587
  },
10443
11588
  parse(el, _ctx) {
10444
11589
  const opts = {};
10445
- const eohEl = findChild(el, "w:evenAndOddHeaders");
10446
- if (eohEl) {
10447
- const val = attr(eohEl, "w:val");
10448
- opts.evenAndOddHeaderAndFooters = val !== "false" && val !== "0" && val !== "off";
10449
- }
10450
- const viewEl = findChild(el, "w:view");
10451
- if (viewEl) {
10452
- const val = attr(viewEl, "w:val");
10453
- if (val) opts.view = val;
10454
- }
11590
+ const wpEl = findChild(el, "w:writeProtection");
11591
+ if (wpEl) {
11592
+ const wp = readPasswordAttrs(wpEl);
11593
+ const recommended = attr(wpEl, "w:recommended");
11594
+ if (recommended !== void 0) wp.recommended = recommended === "1" || recommended === "true";
11595
+ if (Object.keys(wp).length > 0) opts.writeProtection = wp;
11596
+ }
11597
+ const viewVal = readStr(findChild(el, "w:view"), "w:val");
11598
+ if (viewVal) opts.view = viewVal;
10455
11599
  const zoomEl = findChild(el, "w:zoom");
10456
11600
  if (zoomEl) {
10457
11601
  const zoom = {};
10458
11602
  const percent = attr(zoomEl, "w:percent");
10459
11603
  if (percent) zoom.percent = parseInt(percent, 10);
10460
- const val = attr(zoomEl, "w:val");
10461
- if (val) zoom.val = val;
11604
+ const zval = attr(zoomEl, "w:val");
11605
+ if (zval) zoom.val = zval;
10462
11606
  if (Object.keys(zoom).length > 0) opts.zoom = zoom;
10463
11607
  }
10464
- const tabStopEl = findChild(el, "w:defaultTabStop");
10465
- if (tabStopEl) {
10466
- const val = attr(tabStopEl, "w:val");
10467
- if (val) opts.defaultTabStop = parseInt(val, 10);
10468
- }
10469
- const trackRevEl = findChild(el, "w:trackRevisions");
10470
- if (trackRevEl) {
10471
- const features = opts.features ?? {};
10472
- features.trackRevisions = attrBool(trackRevEl, "w:val") ?? true;
10473
- opts.features = features;
10474
- }
10475
- const updateFieldsEl = findChild(el, "w:updateFields");
10476
- if (updateFieldsEl) {
10477
- const features = opts.features ?? {};
10478
- features.updateFields = attrBool(updateFieldsEl, "w:val") ?? true;
10479
- opts.features = features;
10480
- }
10481
- const compatEl = findChild(el, "w:compat");
10482
- if (compatEl) {
10483
- for (const child of compatEl.elements ?? []) if (child.name === "w:compatSetting") {
10484
- if (attr(child, "w:name") === "compatibilityMode") {
10485
- const val = attr(child, "w:val");
10486
- if (val) opts.compatabilityModeVersion = parseInt(val, 10);
10487
- }
10488
- }
10489
- }
10490
- const docVarsEl = findChild(el, "w:docVars");
10491
- if (docVarsEl) {
10492
- const vars = [];
10493
- for (const child of docVarsEl.elements ?? []) if (child.name === "w:docVar") {
10494
- const name = attr(child, "w:name");
10495
- const val = attr(child, "w:val");
10496
- if (name && val) vars.push({
10497
- name,
10498
- val
10499
- });
10500
- }
10501
- if (vars.length > 0) opts.docVars = vars;
10502
- }
10503
- const cscEl = findChild(el, "w:characterSpacingControl");
10504
- if (cscEl) {
10505
- const val = attr(cscEl, "w:val");
10506
- if (val) opts.characterSpacingControl = val;
10507
- }
10508
- if (findChild(el, "w:displayBackgroundShape")) opts.displayBackgroundShape = true;
10509
- if (findChild(el, "w:embedTrueTypeFonts")) opts.embedTrueTypeFonts = true;
10510
- if (findChild(el, "w:embedSystemFonts")) opts.embedSystemFonts = true;
10511
- if (findChild(el, "w:saveSubsetFonts")) opts.saveSubsetFonts = true;
10512
- if (findChild(el, "w:removePersonalInformation")) opts.removePersonalInformation = true;
10513
- if (findChild(el, "w:removeDateAndTime")) opts.removeDateAndTime = true;
10514
- if (findChild(el, "w:hideSpellingErrors")) opts.hideSpellingErrors = true;
10515
- if (findChild(el, "w:hideGrammaticalErrors")) opts.hideGrammaticalErrors = true;
10516
- if (findChild(el, "w:mirrorMargins")) opts.mirrorMargins = true;
10517
- if (findChild(el, "w:saveFormsData")) opts.saveFormsData = true;
10518
- if (findChild(el, "w:alignBordersAndEdges")) opts.alignBordersAndEdges = true;
10519
- if (findChild(el, "w:bordersDoNotSurroundHeader")) opts.bordersDoNotSurroundHeader = true;
10520
- if (findChild(el, "w:bordersDoNotSurroundFooter")) opts.bordersDoNotSurroundFooter = true;
10521
- if (findChild(el, "w:gutterAtTop")) opts.gutterAtTop = true;
10522
- if (findChild(el, "w:formsDesign")) opts.formsDesign = true;
10523
- if (findChild(el, "w:linkStyles")) opts.linkStyles = true;
10524
- if (findChild(el, "w:autoHyphenation")) {
10525
- const hyphenation = opts.hyphenation ?? {};
10526
- hyphenation.autoHyphenation = true;
10527
- opts.hyphenation = hyphenation;
10528
- }
10529
- if (findChild(el, "w:doNotHyphenateCaps")) {
10530
- const hyphenation = opts.hyphenation ?? {};
10531
- hyphenation.doNotHyphenateCaps = true;
10532
- opts.hyphenation = hyphenation;
10533
- }
10534
- const consHyphEl = findChild(el, "w:consecutiveHyphenLimit");
10535
- if (consHyphEl) {
10536
- const val = attr(consHyphEl, "w:val");
10537
- if (val) {
10538
- const hyphenation = opts.hyphenation ?? {};
10539
- hyphenation.consecutiveHyphenLimit = parseInt(val, 10);
10540
- opts.hyphenation = hyphenation;
10541
- }
10542
- }
10543
- const hyphZoneEl = findChild(el, "w:hyphenationZone");
10544
- if (hyphZoneEl) {
10545
- const val = attr(hyphZoneEl, "w:val");
10546
- if (val) {
10547
- const hyphenation = opts.hyphenation ?? {};
10548
- hyphenation.hyphenationZone = parseInt(val, 10);
10549
- opts.hyphenation = hyphenation;
10550
- }
10551
- }
10552
- const attachedTplEl = findChild(el, "w:attachedTemplate");
10553
- if (attachedTplEl) {
10554
- const val = attr(attachedTplEl, "r:id");
10555
- if (val) opts.attachedTemplate = val;
10556
- }
10557
- const spsmEl = findChild(el, "w:stylePaneSortMethod");
10558
- if (spsmEl) {
10559
- const val = attr(spsmEl, "w:val");
10560
- if (val) opts.stylePaneSortMethod = val;
10561
- }
10562
- const docTypeEl = findChild(el, "w:documentType");
10563
- if (docTypeEl) {
10564
- const val = attr(docTypeEl, "w:val");
10565
- if (val) opts.documentType = val;
10566
- }
10567
- const defTblStyleEl = findChild(el, "w:defaultTableStyle");
10568
- if (defTblStyleEl) {
10569
- const val = attr(defTblStyleEl, "w:val");
10570
- if (val) opts.defaultTableStyle = val;
10571
- }
10572
- const spffEl = findChild(el, "w:stylePaneFormatFilter");
10573
- if (spffEl) {
10574
- const filter = {};
10575
- for (const [prop, xmlKey] of [
10576
- ["allStyles", "w:allStyles"],
10577
- ["customStyles", "w:customStyles"],
10578
- ["stylesInUse", "w:stylesInUse"],
10579
- ["headingStyles", "w:headingStyles"],
10580
- ["numberingStyles", "w:numberingStyles"],
10581
- ["tableStyles", "w:tableStyles"],
10582
- ["directFormattingOnRuns", "w:directFormattingOnRuns"],
10583
- ["directFormattingOnParagraphs", "w:directFormattingOnParagraphs"],
10584
- ["directFormattingOnNumbering", "w:directFormattingOnNumbering"],
10585
- ["directFormattingOnTables", "w:directFormattingOnTables"],
10586
- ["clearFormatting", "w:clearFormatting"],
10587
- ["top3HeadingStyles", "w:top3HeadingStyles"],
10588
- ["visibleStyles", "w:visibleStyles"],
10589
- ["alternateStyleNames", "w:alternateStyleNames"]
10590
- ]) {
10591
- const v = attr(spffEl, xmlKey);
10592
- if (v !== void 0) filter[prop] = v !== "0" && v !== "false" && v !== "off";
10593
- }
10594
- if (Object.keys(filter).length > 0) opts.stylePaneFormatFilter = filter;
10595
- }
10596
- const catEl = findChild(el, "w:clickAndTypeStyle");
10597
- if (catEl) {
10598
- const val = attr(catEl, "w:val");
10599
- if (val) opts.clickAndTypeStyle = val;
11608
+ for (const [key, tag] of [
11609
+ ["removePersonalInformation", "w:removePersonalInformation"],
11610
+ ["removeDateAndTime", "w:removeDateAndTime"],
11611
+ ["doNotDisplayPageBoundaries", "w:doNotDisplayPageBoundaries"],
11612
+ ["displayBackgroundShape", "w:displayBackgroundShape"],
11613
+ ["printPostScriptOverText", "w:printPostScriptOverText"],
11614
+ ["printFractionalCharacterWidth", "w:printFractionalCharacterWidth"],
11615
+ ["printFormsData", "w:printFormsData"],
11616
+ ["embedTrueTypeFonts", "w:embedTrueTypeFonts"],
11617
+ ["embedSystemFonts", "w:embedSystemFonts"],
11618
+ ["saveSubsetFonts", "w:saveSubsetFonts"],
11619
+ ["saveFormsData", "w:saveFormsData"],
11620
+ ["mirrorMargins", "w:mirrorMargins"],
11621
+ ["alignBordersAndEdges", "w:alignBordersAndEdges"],
11622
+ ["bordersDoNotSurroundHeader", "w:bordersDoNotSurroundHeader"],
11623
+ ["bordersDoNotSurroundFooter", "w:bordersDoNotSurroundFooter"],
11624
+ ["gutterAtTop", "w:gutterAtTop"],
11625
+ ["hideSpellingErrors", "w:hideSpellingErrors"],
11626
+ ["hideGrammaticalErrors", "w:hideGrammaticalErrors"],
11627
+ ["formsDesign", "w:formsDesign"],
11628
+ ["linkStyles", "w:linkStyles"],
11629
+ ["trackRevisions", "w:trackRevisions"],
11630
+ ["doNotTrackMoves", "w:doNotTrackMoves"],
11631
+ ["doNotTrackFormatting", "w:doNotTrackFormatting"],
11632
+ ["autoFormatOverride", "w:autoFormatOverride"],
11633
+ ["styleLockTheme", "w:styleLockTheme"],
11634
+ ["styleLockQFSet", "w:styleLockQFSet"],
11635
+ ["showEnvelope", "w:showEnvelope"],
11636
+ ["evenAndOddHeaders", "w:evenAndOddHeaders"],
11637
+ ["bookFoldRevPrinting", "w:bookFoldRevPrinting"],
11638
+ ["bookFoldPrinting", "w:bookFoldPrinting"],
11639
+ ["doNotUseMarginsForDrawingGridOrigin", "w:doNotUseMarginsForDrawingGridOrigin"],
11640
+ ["doNotShadeFormData", "w:doNotShadeFormData"],
11641
+ ["noPunctuationKerning", "w:noPunctuationKerning"],
11642
+ ["printTwoOnOne", "w:printTwoOnOne"],
11643
+ ["strictFirstAndLastChars", "w:strictFirstAndLastChars"],
11644
+ ["savePreviewPicture", "w:savePreviewPicture"],
11645
+ ["doNotValidateAgainstSchema", "w:doNotValidateAgainstSchema"],
11646
+ ["saveInvalidXml", "w:saveInvalidXml"],
11647
+ ["ignoreMixedContent", "w:ignoreMixedContent"],
11648
+ ["alwaysShowPlaceholderText", "w:alwaysShowPlaceholderText"],
11649
+ ["doNotDemarcateInvalidXml", "w:doNotDemarcateInvalidXml"],
11650
+ ["saveXmlDataOnly", "w:saveXmlDataOnly"],
11651
+ ["useXSLTWhenSaving", "w:useXSLTWhenSaving"],
11652
+ ["showXMLTags", "w:showXMLTags"],
11653
+ ["alwaysMergeEmptyNamespace", "w:alwaysMergeEmptyNamespace"],
11654
+ ["updateFields", "w:updateFields"],
11655
+ ["doNotIncludeSubdocsInStats", "w:doNotIncludeSubdocsInStats"],
11656
+ ["doNotAutoCompressPictures", "w:doNotAutoCompressPictures"],
11657
+ ["doNotEmbedSmartTags", "w:doNotEmbedSmartTags"]
11658
+ ]) {
11659
+ const v = readOnOff(findChild(el, tag));
11660
+ if (v !== void 0) opts[key] = v;
10600
11661
  }
10601
11662
  const awsList = [];
10602
11663
  for (const child of el.elements ?? []) {
@@ -10628,49 +11689,252 @@ const settingsDesc = {
10628
11689
  if (grammar) proof.grammar = grammar;
10629
11690
  if (Object.keys(proof).length > 0) opts.proofState = proof;
10630
11691
  }
11692
+ const attachedTplEl = findChild(el, "w:attachedTemplate");
11693
+ if (attachedTplEl) {
11694
+ const rid = attr(attachedTplEl, "r:id");
11695
+ if (rid) opts.attachedTemplate = rid;
11696
+ }
11697
+ const spffEl = findChild(el, "w:stylePaneFormatFilter");
11698
+ if (spffEl) {
11699
+ const filter = {};
11700
+ for (const [prop, xmlKey] of [
11701
+ ["allStyles", "w:allStyles"],
11702
+ ["customStyles", "w:customStyles"],
11703
+ ["stylesInUse", "w:stylesInUse"],
11704
+ ["headingStyles", "w:headingStyles"],
11705
+ ["numberingStyles", "w:numberingStyles"],
11706
+ ["tableStyles", "w:tableStyles"],
11707
+ ["directFormattingOnRuns", "w:directFormattingOnRuns"],
11708
+ ["directFormattingOnParagraphs", "w:directFormattingOnParagraphs"],
11709
+ ["directFormattingOnNumbering", "w:directFormattingOnNumbering"],
11710
+ ["directFormattingOnTables", "w:directFormattingOnTables"],
11711
+ ["clearFormatting", "w:clearFormatting"],
11712
+ ["top3HeadingStyles", "w:top3HeadingStyles"],
11713
+ ["visibleStyles", "w:visibleStyles"],
11714
+ ["alternateStyleNames", "w:alternateStyleNames"],
11715
+ ["latentStyles", "w:latentStyles"]
11716
+ ]) {
11717
+ const v = attr(spffEl, xmlKey);
11718
+ if (v !== void 0) filter[prop] = v !== "0" && v !== "false" && v !== "off";
11719
+ }
11720
+ if (Object.keys(filter).length > 0) opts.stylePaneFormatFilter = filter;
11721
+ }
11722
+ const stylePaneSortMethod = readStr(findChild(el, "w:stylePaneSortMethod"), "w:val");
11723
+ if (stylePaneSortMethod) opts.stylePaneSortMethod = stylePaneSortMethod;
11724
+ const documentType = readStr(findChild(el, "w:documentType"), "w:val");
11725
+ if (documentType) opts.documentType = documentType;
11726
+ const clickAndTypeStyle = readStr(findChild(el, "w:clickAndTypeStyle"), "w:val");
11727
+ if (clickAndTypeStyle) opts.clickAndTypeStyle = clickAndTypeStyle;
11728
+ const defaultTableStyle = readStr(findChild(el, "w:defaultTableStyle"), "w:val");
11729
+ if (defaultTableStyle) opts.defaultTableStyle = defaultTableStyle;
11730
+ const mailMergeEl = findChild(el, "w:mailMerge");
11731
+ if (mailMergeEl) {
11732
+ const mm = parseMailMerge(mailMergeEl);
11733
+ if (mm) opts.mailMerge = mm;
11734
+ }
11735
+ const revViewEl = findChild(el, "w:revisionView");
11736
+ if (revViewEl) {
11737
+ const rv = {};
11738
+ for (const [k, a] of [
11739
+ ["markup", "w:markup"],
11740
+ ["comments", "w:comments"],
11741
+ ["insDel", "w:insDel"],
11742
+ ["formatting", "w:formatting"],
11743
+ ["inkAnnotations", "w:inkAnnotations"]
11744
+ ]) {
11745
+ const v = attr(revViewEl, a);
11746
+ if (v !== void 0) rv[k] = v !== "false" && v !== "0";
11747
+ }
11748
+ if (Object.keys(rv).length > 0) opts.revisionView = rv;
11749
+ }
10631
11750
  const docProtEl = findChild(el, "w:documentProtection");
10632
11751
  if (docProtEl) {
10633
11752
  const prot = {};
10634
11753
  const edit = attr(docProtEl, "w:edit");
10635
11754
  if (edit && DOC_PROTECT_EDITS.includes(edit)) prot.edit = edit;
10636
11755
  if (attr(docProtEl, "w:enforcement") !== void 0) {
10637
- const hash = attr(docProtEl, "w:hash");
10638
- if (hash) prot.hash = hash;
10639
- const salt = attr(docProtEl, "w:salt");
10640
- if (salt) prot.salt = salt;
10641
- const cryptProviderType = attr(docProtEl, "w:cryptProviderType");
10642
- if (cryptProviderType) prot.cryptoProviderType = cryptProviderType;
10643
- const cryptAlgorithmClass = attr(docProtEl, "w:cryptAlgorithmClass");
10644
- if (cryptAlgorithmClass) prot.cryptoAlgorithmClass = cryptAlgorithmClass;
10645
- const cryptAlgorithmType = attr(docProtEl, "w:cryptAlgorithmType");
10646
- if (cryptAlgorithmType) prot.cryptoAlgorithmType = cryptAlgorithmType;
10647
- const cryptAlgorithmSid = attr(docProtEl, "w:cryptAlgorithmSid");
10648
- if (cryptAlgorithmSid) prot.cryptoAlgorithmSid = parseInt(cryptAlgorithmSid, 10);
10649
- const cryptSpinCount = attr(docProtEl, "w:cryptSpinCount");
10650
- if (cryptSpinCount) prot.cryptoSpinCount = parseInt(cryptSpinCount, 10);
10651
- const hashValue = attr(docProtEl, "w:hashValue");
10652
- if (hashValue) prot.hashValue = hashValue;
10653
- const saltValue = attr(docProtEl, "w:saltValue");
10654
- if (saltValue) prot.saltValue = saltValue;
10655
- const spinCount = attr(docProtEl, "w:spinCount");
10656
- if (spinCount) prot.spinCount = parseInt(spinCount, 10);
10657
- const algorithmName = attr(docProtEl, "w:algorithmName");
10658
- if (algorithmName) prot.algorithmName = algorithmName;
11756
+ Object.assign(prot, readPasswordAttrs(docProtEl));
10659
11757
  const formatting = attr(docProtEl, "w:formatting");
10660
11758
  if (formatting !== void 0) prot.formatting = formatting === "1" || formatting === "true";
10661
11759
  }
10662
- if (Object.keys(prot).length > 0) {
10663
- const features = opts.features ?? {};
10664
- features.documentProtection = prot;
10665
- opts.features = features;
11760
+ if (Object.keys(prot).length > 0) opts.documentProtection = prot;
11761
+ }
11762
+ const defaultTabStop = readNum(findChild(el, "w:defaultTabStop"), "w:val");
11763
+ if (defaultTabStop !== void 0) opts.defaultTabStop = defaultTabStop;
11764
+ if (findChild(el, "w:autoHyphenation") || findChild(el, "w:doNotHyphenateCaps") || findChild(el, "w:consecutiveHyphenLimit") || findChild(el, "w:hyphenationZone")) {
11765
+ const hyphenation = {};
11766
+ const autoHyph = readOnOff(findChild(el, "w:autoHyphenation"));
11767
+ if (autoHyph !== void 0) hyphenation.autoHyphenation = autoHyph;
11768
+ const noHyphCaps = readOnOff(findChild(el, "w:doNotHyphenateCaps"));
11769
+ if (noHyphCaps !== void 0) hyphenation.doNotHyphenateCaps = noHyphCaps;
11770
+ const consLimit = readNum(findChild(el, "w:consecutiveHyphenLimit"), "w:val");
11771
+ if (consLimit !== void 0) hyphenation.consecutiveHyphenLimit = consLimit;
11772
+ const zone = readNum(findChild(el, "w:hyphenationZone"), "w:val");
11773
+ if (zone !== void 0) hyphenation.hyphenationZone = zone;
11774
+ if (Object.keys(hyphenation).length > 0) opts.hyphenation = hyphenation;
11775
+ }
11776
+ const summaryLength = readNum(findChild(el, "w:summaryLength"), "w:val");
11777
+ if (summaryLength !== void 0) opts.summaryLength = summaryLength;
11778
+ const bookFoldSheets = readNum(findChild(el, "w:bookFoldPrintingSheets"), "w:val");
11779
+ if (bookFoldSheets !== void 0) opts.bookFoldPrintingSheets = bookFoldSheets;
11780
+ for (const [key, tag] of [
11781
+ ["drawingGridHorizontalSpacing", "w:drawingGridHorizontalSpacing"],
11782
+ ["drawingGridVerticalSpacing", "w:drawingGridVerticalSpacing"],
11783
+ ["displayHorizontalDrawingGridEvery", "w:displayHorizontalDrawingGridEvery"],
11784
+ ["displayVerticalDrawingGridEvery", "w:displayVerticalDrawingGridEvery"],
11785
+ ["drawingGridHorizontalOrigin", "w:drawingGridHorizontalOrigin"],
11786
+ ["drawingGridVerticalOrigin", "w:drawingGridVerticalOrigin"]
11787
+ ]) {
11788
+ const v = readNum(findChild(el, tag), "w:val");
11789
+ if (v !== void 0) opts[key] = v;
11790
+ }
11791
+ const characterSpacingControl = readStr(findChild(el, "w:characterSpacingControl"), "w:val");
11792
+ if (characterSpacingControl) opts.characterSpacingControl = characterSpacingControl;
11793
+ for (const [key, tag] of [["noLineBreaksAfter", "w:noLineBreaksAfter"], ["noLineBreaksBefore", "w:noLineBreaksBefore"]]) {
11794
+ const lbEl = findChild(el, tag);
11795
+ if (!lbEl) continue;
11796
+ const entry = {};
11797
+ const lang = attr(lbEl, "w:lang");
11798
+ if (lang) entry.lang = lang;
11799
+ const val = attr(lbEl, "w:val");
11800
+ if (val) entry.val = val;
11801
+ if (Object.keys(entry).length > 0) opts[key] = entry;
11802
+ }
11803
+ const stxEl = findChild(el, "w:saveThroughXslt");
11804
+ if (stxEl) {
11805
+ const stx = {};
11806
+ const id = attr(stxEl, "r:id");
11807
+ if (id) stx.id = id;
11808
+ const val = attr(stxEl, "w:val");
11809
+ if (val) stx.val = val;
11810
+ const solutionID = attr(stxEl, "w:solutionID");
11811
+ if (solutionID) stx.solutionID = solutionID;
11812
+ if (Object.keys(stx).length > 0) opts.saveThroughXslt = stx;
11813
+ }
11814
+ const hdrSdEl = findChild(el, "w:hdrShapeDefaults");
11815
+ if (hdrSdEl) opts.hdrShapeDefaults = stringify(hdrSdEl);
11816
+ const sdEl = findChild(el, "w:shapeDefaults");
11817
+ if (sdEl) opts.shapeDefaults = stringify(sdEl);
11818
+ const fnPrEl = findChild(el, "w:footnotePr");
11819
+ if (fnPrEl) {
11820
+ const fn = parseFtnEdnPr(fnPrEl);
11821
+ if (fn) opts.footnotePr = fn;
11822
+ }
11823
+ const enPrEl = findChild(el, "w:endnotePr");
11824
+ if (enPrEl) {
11825
+ const en = parseFtnEdnPr(enPrEl);
11826
+ if (en) opts.endnotePr = en;
11827
+ }
11828
+ const compatEl = findChild(el, "w:compat");
11829
+ if (compatEl) {
11830
+ const compat = parseCompatibility(compatEl);
11831
+ if (compat) opts.compatibility = compat;
11832
+ }
11833
+ const docVarsEl = findChild(el, "w:docVars");
11834
+ if (docVarsEl) {
11835
+ const vars = [];
11836
+ for (const child of docVarsEl.elements ?? []) {
11837
+ if (child.name !== "w:docVar") continue;
11838
+ const name = attr(child, "w:name");
11839
+ const val = attr(child, "w:val");
11840
+ if (name !== void 0 && val !== void 0) vars.push({
11841
+ name,
11842
+ val
11843
+ });
11844
+ }
11845
+ if (vars.length > 0) opts.docVars = vars;
11846
+ }
11847
+ const rsidsEl = findChild(el, "w:rsids");
11848
+ if (rsidsEl) {
11849
+ const rsids = {};
11850
+ const root = readStr(findChild(rsidsEl, "w:rsidRoot"), "w:val");
11851
+ if (root) rsids.rsidRoot = root;
11852
+ const list = [];
11853
+ for (const child of rsidsEl.elements ?? []) {
11854
+ if (child.name !== "w:rsid") continue;
11855
+ const val = attr(child, "w:val");
11856
+ if (val) list.push(val);
10666
11857
  }
11858
+ if (list.length > 0) rsids.rsids = list;
11859
+ if (Object.keys(rsids).length > 0) opts.rsids = rsids;
11860
+ }
11861
+ const mathPrEl = findChild(el, "m:mathPr");
11862
+ if (mathPrEl) {
11863
+ const mp = parseMathPr(mathPrEl);
11864
+ if (mp) opts.mathPr = mp;
10667
11865
  }
10668
- const noMovesEl = findChild(el, "w:doNotTrackMoves");
10669
- if (noMovesEl) opts.doNotTrackMoves = attrBool(noMovesEl, "w:val") ?? true;
10670
- const noFmtEl = findChild(el, "w:doNotTrackFormatting");
10671
- if (noFmtEl) opts.doNotTrackFormatting = attrBool(noFmtEl, "w:val") ?? true;
10672
- opts.rawXml = stringify(el);
10673
- if (el.attributes) opts.rootAttributes = { ...el.attributes };
11866
+ const attachedSchemas = [];
11867
+ for (const child of el.elements ?? []) {
11868
+ if (child.name !== "w:attachedSchema") continue;
11869
+ const val = attr(child, "w:val");
11870
+ if (val) attachedSchemas.push(val);
11871
+ }
11872
+ if (attachedSchemas.length > 0) opts.attachedSchema = attachedSchemas;
11873
+ const tflEl = findChild(el, "w:themeFontLang");
11874
+ if (tflEl) {
11875
+ const tfl = {};
11876
+ const val = attr(tflEl, "w:val");
11877
+ if (val) tfl.val = val;
11878
+ const eastAsia = attr(tflEl, "w:eastAsia");
11879
+ if (eastAsia) tfl.eastAsia = eastAsia;
11880
+ const bidi = attr(tflEl, "w:bidi");
11881
+ if (bidi) tfl.bidi = bidi;
11882
+ if (Object.keys(tfl).length > 0) opts.themeFontLang = tfl;
11883
+ }
11884
+ const csmEl = findChild(el, "w:clrSchemeMapping");
11885
+ if (csmEl) {
11886
+ const csm = {};
11887
+ for (const [key, xmlAttr] of [
11888
+ ["bg1", "w:bg1"],
11889
+ ["t1", "w:t1"],
11890
+ ["bg2", "w:bg2"],
11891
+ ["t2", "w:t2"],
11892
+ ["accent1", "w:accent1"],
11893
+ ["accent2", "w:accent2"],
11894
+ ["accent3", "w:accent3"],
11895
+ ["accent4", "w:accent4"],
11896
+ ["accent5", "w:accent5"],
11897
+ ["accent6", "w:accent6"],
11898
+ ["hyperlink", "w:hyperlink"],
11899
+ ["followedHyperlink", "w:followedHyperlink"]
11900
+ ]) {
11901
+ const v = attr(csmEl, xmlAttr);
11902
+ if (v) csm[key] = v;
11903
+ }
11904
+ if (Object.keys(csm).length > 0) opts.colorSchemeMapping = csm;
11905
+ }
11906
+ if (findChild(el, "w:forceUpgrade")) opts.forceUpgrade = true;
11907
+ const captionsEl = findChild(el, "w:captions");
11908
+ if (captionsEl) {
11909
+ const captions = parseCaptions(captionsEl);
11910
+ if (captions) opts.captions = captions;
11911
+ }
11912
+ const rmilEl = findChild(el, "w:readModeInkLockDown");
11913
+ if (rmilEl) opts.readModeInkLockDown = {
11914
+ actualPg: attr(rmilEl, "w:actualPg") !== "0",
11915
+ w: parseInt(attr(rmilEl, "w:w") ?? "0", 10),
11916
+ h: parseInt(attr(rmilEl, "w:h") ?? "0", 10),
11917
+ fontSz: parseInt(attr(rmilEl, "w:fontSz") ?? "0", 10)
11918
+ };
11919
+ const smartTags = [];
11920
+ for (const child of el.elements ?? []) {
11921
+ if (child.name !== "w:smartTagType") continue;
11922
+ const entry = {};
11923
+ const ns = attr(child, "w:namespace");
11924
+ if (ns) entry.namespace = ns;
11925
+ const nsuri = attr(child, "w:namespaceuri");
11926
+ if (nsuri) entry.namespaceuri = nsuri;
11927
+ const name = attr(child, "w:name");
11928
+ if (name) entry.name = name;
11929
+ const url = attr(child, "w:url");
11930
+ if (url) entry.url = url;
11931
+ if (Object.keys(entry).length > 0) smartTags.push(entry);
11932
+ }
11933
+ if (smartTags.length > 0) opts.smartTagType = smartTags;
11934
+ const decimalSymbol = readStr(findChild(el, "w:decimalSymbol"), "w:val");
11935
+ if (decimalSymbol) opts.decimalSymbol = decimalSymbol;
11936
+ const listSeparator = readStr(findChild(el, "w:listSeparator"), "w:val");
11937
+ if (listSeparator) opts.listSeparator = listSeparator;
10674
11938
  return opts;
10675
11939
  }
10676
11940
  };
@@ -10827,6 +12091,25 @@ function parseTocFieldInstruction(instruction, opts) {
10827
12091
  if ("z" in switches) opts.hideTabAndPageNumbersInWebView = true;
10828
12092
  }
10829
12093
  /**
12094
+ * Extract TOC options from the elements of a captured TOC field (SDT content or
12095
+ * a bare cross-paragraph field). Feeds every w:instrText to the instruction
12096
+ * parser; non-TOC fields (HYPERLINK/PAGEREF inside the rendered entries) are
12097
+ * ignored — parseTocFieldInstruction only acts on instructions starting "TOC".
12098
+ */
12099
+ function parseTocFieldFromElements(els) {
12100
+ const opts = {};
12101
+ for (const el of els) collectTocInstructions(el, opts);
12102
+ return opts;
12103
+ }
12104
+ /** Recursively feed every w:instrText to the TOC instruction parser. */
12105
+ function collectTocInstructions(el, opts) {
12106
+ if (el.name === "w:instrText") {
12107
+ const instruction = textOf(el)?.trim();
12108
+ if (instruction) parseTocFieldInstruction(instruction, opts);
12109
+ }
12110
+ for (const c of el.elements ?? []) if (c.type === "element") collectTocInstructions(c, opts);
12111
+ }
12112
+ /**
10830
12113
  * Parse field switches like \o "1-3" \h \z into a map.
10831
12114
  */
10832
12115
  function parseFieldSwitches(text) {
@@ -11061,14 +12344,22 @@ function fontXml(font) {
11061
12344
  const parts = [`<w:font w:name="${escapeXml(font.name)}">`];
11062
12345
  if (font.altName) parts.push(`<w:altName w:val="${escapeXml(font.altName)}"/>`);
11063
12346
  if (font.panose1) parts.push(`<w:panose1 w:val="${escapeXml(font.panose1)}"/>`);
11064
- if (font.characterSet) parts.push(`<w:charset w:val="${escapeXml(font.characterSet)}"/>`);
12347
+ if (font.characterSet || font.characterSetName) {
12348
+ const valAttr = font.characterSet ? ` w:val="${escapeXml(font.characterSet)}"` : "";
12349
+ const csAttr = font.characterSetName ? ` w:characterSet="${escapeXml(font.characterSetName)}"` : "";
12350
+ parts.push(`<w:charset${valAttr}${csAttr}/>`);
12351
+ }
11065
12352
  const family = font.family ?? (font.embedRid ? "auto" : void 0);
11066
12353
  if (family) parts.push(`<w:family w:val="${escapeXml(family)}"/>`);
11067
12354
  const pitch = font.pitch ?? (font.embedRid ? "variable" : void 0);
11068
12355
  if (pitch) parts.push(`<w:pitch w:val="${escapeXml(pitch)}"/>`);
11069
12356
  const sig = font.sig ?? (font.embedRid ? DEFAULT_SIG : void 0);
11070
12357
  if (sig) parts.push(`<w:sig w:usb0="${sig.usb0}" w:usb1="${sig.usb1}" w:usb2="${sig.usb2}" w:usb3="${sig.usb3}" w:csb0="${sig.csb0}" w:csb1="${sig.csb1}"/>`);
11071
- if (font.embedRid) parts.push(`<w:embedRegular r:id="${font.embedRid}" w:fontKey="{${font.fontKey}}"/>`);
12358
+ if (font.embedRid) {
12359
+ const embedAttrs = [`r:id="${font.embedRid}"`, `w:fontKey="{${font.fontKey}}"`];
12360
+ if (font.subsetted !== void 0) embedAttrs.push(`w:subsetted="${font.subsetted ? 1 : 0}"`);
12361
+ parts.push(`<w:embedRegular ${embedAttrs.join(" ")}/>`);
12362
+ }
11072
12363
  parts.push("</w:font>");
11073
12364
  return parts.join("");
11074
12365
  }
@@ -11101,6 +12392,8 @@ const fontTableDesc = {
11101
12392
  if (charsetEl) {
11102
12393
  const val = attr(charsetEl, "w:val");
11103
12394
  if (val) font.characterSet = val;
12395
+ const csName = attr(charsetEl, "w:characterSet");
12396
+ if (csName) font.characterSetName = csName;
11104
12397
  }
11105
12398
  const familyEl = findChild(child, "w:family");
11106
12399
  if (familyEl) {
@@ -11141,6 +12434,8 @@ const fontTableDesc = {
11141
12434
  if (rawKey) font.fontKey = rawKey.replace(/^\{\{|\}\}$/g, "").replace(/^\{|\}$/g, "");
11142
12435
  const rid = attr(embedEl, "r:id");
11143
12436
  if (rid) font.embedRid = rid;
12437
+ const subsetted = attrBool(embedEl, "w:subsetted");
12438
+ if (subsetted !== void 0) font.subsetted = subsetted;
11144
12439
  }
11145
12440
  fonts.push(font);
11146
12441
  }
@@ -11371,8 +12666,11 @@ function escapeAttr(s) {
11371
12666
  const COMMENTS_NS = "xmlns:aink=\"http://schemas.microsoft.com/office/drawing/2016/ink\" xmlns:am3d=\"http://schemas.microsoft.com/office/drawing/2017/model3d\" xmlns:cx=\"http://schemas.microsoft.com/office/drawing/2014/chartex\" xmlns:cx1=\"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex\" xmlns:cx2=\"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex\" xmlns:cx3=\"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex\" xmlns:cx4=\"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex\" xmlns:cx5=\"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex\" xmlns:cx6=\"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex\" xmlns:cx7=\"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex\" xmlns:cx8=\"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" xmlns:w16cex=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" xmlns:w16cid=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" xmlns:w16sdtdh=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" xmlns:wne=\"http://schemas.openxmlformats.org/office/word/2006/wordml\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\"";
11372
12667
  function stringifyComment(opts, ctx) {
11373
12668
  const dateStr = typeof opts.date === "string" ? opts.date : (opts.date ?? /* @__PURE__ */ new Date()).toISOString();
11374
- const attrs = [`w:id="${opts.id}"`, `w:date="${escapeAttr(dateStr)}"`];
11375
- if (opts.author !== void 0) attrs.push(`w:author="${escapeAttr(opts.author)}"`);
12669
+ const attrs = [
12670
+ `w:id="${opts.id}"`,
12671
+ `w:author="${escapeAttr(opts.author ?? "")}"`,
12672
+ `w:date="${escapeAttr(dateStr)}"`
12673
+ ];
11376
12674
  if (opts.initials !== void 0) attrs.push(`w:initials="${escapeAttr(opts.initials)}"`);
11377
12675
  const parts = [];
11378
12676
  for (const child of opts.children) parts.push(stringifyParagraphInline(child, ctx));
@@ -11396,9 +12694,9 @@ const commentsDesc = {
11396
12694
  const date = attr(child, "w:date");
11397
12695
  if (date) comment.date = date;
11398
12696
  const author = attr(child, "w:author");
11399
- if (author) comment.author = author;
12697
+ if (author !== void 0) comment.author = author;
11400
12698
  const initials = attr(child, "w:initials");
11401
- if (initials) comment.initials = initials;
12699
+ if (initials !== void 0) comment.initials = initials;
11402
12700
  const children = [];
11403
12701
  for (const sub of child.elements ?? []) if (sub.name === "w:p") children.push(parseParagraph(sub, ctx));
11404
12702
  comment.children = children;
@@ -11512,6 +12810,10 @@ const STANDARD_DEFAULTS = [
11512
12810
  {
11513
12811
  extension: "odttf",
11514
12812
  contentType: "application/vnd.openxmlformats-officedocument.obfuscatedFont"
12813
+ },
12814
+ {
12815
+ extension: "bin",
12816
+ contentType: "application/vnd.openxmlformats-officedocument.oleObject"
11515
12817
  }
11516
12818
  ];
11517
12819
  /**
@@ -11708,146 +13010,6 @@ const corePropertiesDesc = {
11708
13010
  }
11709
13011
  };
11710
13012
  //#endregion
11711
- //#region src/parts/custom-properties.ts
11712
- const customPropertiesDesc = {
11713
- kind: "custom",
11714
- stringify(opts, _ctx) {
11715
- const p = ["<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/custom-properties\" xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\">"];
11716
- let pid = 2;
11717
- for (const prop of opts.properties) {
11718
- p.push(`<property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="${pid}" name="${escapeXml(prop.name)}"><vt:lpwstr>${escapeXml(prop.value)}</vt:lpwstr></property>`);
11719
- pid++;
11720
- }
11721
- p.push("</Properties>");
11722
- return p.join("");
11723
- },
11724
- parse(el, _ctx) {
11725
- const properties = [];
11726
- for (const child of el.elements ?? []) {
11727
- if (child.name !== "property") continue;
11728
- const name = attr(child, "name");
11729
- if (!name) continue;
11730
- const valueEl = child.elements?.find((e) => e.name?.startsWith("vt:"));
11731
- const value = valueEl ? textOf(valueEl) ?? "" : "";
11732
- properties.push({
11733
- name,
11734
- value
11735
- });
11736
- }
11737
- return { properties };
11738
- }
11739
- };
11740
- //#endregion
11741
- //#region src/parts/app-properties.ts
11742
- /** xsd:boolean lexical form — spec canonical form is "true"/"false" (Word's convention). */
11743
- const xsdBoolean = (value) => value ? "true" : "false";
11744
- const appPropertiesDesc = {
11745
- kind: "custom",
11746
- stringify(opts, _ctx) {
11747
- const p = ["<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\" xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\">"];
11748
- if (opts.template !== void 0) p.push(`<Template>${escapeXml(opts.template)}</Template>`);
11749
- if (opts.manager !== void 0) p.push(`<Manager>${escapeXml(opts.manager)}</Manager>`);
11750
- if (opts.company !== void 0) p.push(`<Company>${escapeXml(opts.company)}</Company>`);
11751
- if (opts.pages !== void 0) p.push(`<Pages>${opts.pages}</Pages>`);
11752
- if (opts.words !== void 0) p.push(`<Words>${opts.words}</Words>`);
11753
- if (opts.characters !== void 0) p.push(`<Characters>${opts.characters}</Characters>`);
11754
- if (opts.lines !== void 0) p.push(`<Lines>${opts.lines}</Lines>`);
11755
- if (opts.paragraphs !== void 0) p.push(`<Paragraphs>${opts.paragraphs}</Paragraphs>`);
11756
- if (opts.slides !== void 0) p.push(`<Slides>${opts.slides}</Slides>`);
11757
- if (opts.notes !== void 0) p.push(`<Notes>${opts.notes}</Notes>`);
11758
- if (opts.totalTime !== void 0) p.push(`<TotalTime>${opts.totalTime}</TotalTime>`);
11759
- if (opts.hiddenSlides !== void 0) p.push(`<HiddenSlides>${opts.hiddenSlides}</HiddenSlides>`);
11760
- if (opts.mmClips !== void 0) p.push(`<MMClips>${opts.mmClips}</MMClips>`);
11761
- if (opts.scaleCrop !== void 0) p.push(`<ScaleCrop>${xsdBoolean(opts.scaleCrop)}</ScaleCrop>`);
11762
- if (opts.linksUpToDate !== void 0) p.push(`<LinksUpToDate>${xsdBoolean(opts.linksUpToDate)}</LinksUpToDate>`);
11763
- if (opts.charactersWithSpaces !== void 0) p.push(`<CharactersWithSpaces>${opts.charactersWithSpaces}</CharactersWithSpaces>`);
11764
- if (opts.sharedDoc !== void 0) p.push(`<SharedDoc>${xsdBoolean(opts.sharedDoc)}</SharedDoc>`);
11765
- if (opts.hyperlinkBase !== void 0) p.push(`<HyperlinkBase>${escapeXml(opts.hyperlinkBase)}</HyperlinkBase>`);
11766
- if (opts.hyperlinksChanged !== void 0) p.push(`<HyperlinksChanged>${xsdBoolean(opts.hyperlinksChanged)}</HyperlinksChanged>`);
11767
- if (opts.application !== void 0) p.push(`<Application>${escapeXml(opts.application)}</Application>`);
11768
- if (opts.appVersion !== void 0) p.push(`<AppVersion>${escapeXml(opts.appVersion)}</AppVersion>`);
11769
- if (opts.docSecurity !== void 0) p.push(`<DocSecurity>${opts.docSecurity}</DocSecurity>`);
11770
- p.push("</Properties>");
11771
- return p.join("");
11772
- },
11773
- parse(el, _ctx) {
11774
- const result = {};
11775
- for (const child of el.elements ?? []) {
11776
- if (typeof child.name !== "string") continue;
11777
- const text = child.elements?.[0]?.text;
11778
- switch (child.name) {
11779
- case "Template":
11780
- if (typeof text === "string") result.template = text;
11781
- break;
11782
- case "Manager":
11783
- if (typeof text === "string") result.manager = text;
11784
- break;
11785
- case "Company":
11786
- if (typeof text === "string") result.company = text;
11787
- break;
11788
- case "Pages":
11789
- if (typeof text === "string") result.pages = Number(text);
11790
- break;
11791
- case "Words":
11792
- if (typeof text === "string") result.words = Number(text);
11793
- break;
11794
- case "Characters":
11795
- if (typeof text === "string") result.characters = Number(text);
11796
- break;
11797
- case "Lines":
11798
- if (typeof text === "string") result.lines = Number(text);
11799
- break;
11800
- case "Paragraphs":
11801
- if (typeof text === "string") result.paragraphs = Number(text);
11802
- break;
11803
- case "Slides":
11804
- if (typeof text === "string") result.slides = Number(text);
11805
- break;
11806
- case "Notes":
11807
- if (typeof text === "string") result.notes = Number(text);
11808
- break;
11809
- case "TotalTime":
11810
- if (typeof text === "string") result.totalTime = Number(text);
11811
- break;
11812
- case "HiddenSlides":
11813
- if (typeof text === "string") result.hiddenSlides = Number(text);
11814
- break;
11815
- case "MMClips":
11816
- if (typeof text === "string") result.mmClips = Number(text);
11817
- break;
11818
- case "ScaleCrop":
11819
- if (typeof text === "string") result.scaleCrop = text === "1" || text === "true";
11820
- break;
11821
- case "LinksUpToDate":
11822
- if (typeof text === "string") result.linksUpToDate = text === "1" || text === "true";
11823
- break;
11824
- case "CharactersWithSpaces":
11825
- if (typeof text === "string") result.charactersWithSpaces = Number(text);
11826
- break;
11827
- case "SharedDoc":
11828
- if (typeof text === "string") result.sharedDoc = text === "1" || text === "true";
11829
- break;
11830
- case "HyperlinkBase":
11831
- if (typeof text === "string") result.hyperlinkBase = text;
11832
- break;
11833
- case "HyperlinksChanged":
11834
- if (typeof text === "string") result.hyperlinksChanged = text === "1" || text === "true";
11835
- break;
11836
- case "Application":
11837
- if (typeof text === "string") result.application = text;
11838
- break;
11839
- case "AppVersion":
11840
- if (typeof text === "string") result.appVersion = text;
11841
- break;
11842
- case "DocSecurity":
11843
- if (typeof text === "string") result.docSecurity = Number(text);
11844
- break;
11845
- }
11846
- }
11847
- return result;
11848
- }
11849
- };
11850
- //#endregion
11851
13013
  //#region src/parts/web-settings.ts
11852
13014
  /**
11853
13015
  * Screen size types for web settings target.
@@ -11974,22 +13136,22 @@ function parseDivEl(el) {
11974
13136
  const opts = { id: attrNum(el, "w:id") ?? 0 };
11975
13137
  const marLeft = findChild(el, "w:marLeft");
11976
13138
  if (marLeft) {
11977
- const val = attrNum(marLeft, "w:val");
13139
+ const val = attrMeasure(marLeft, "w:val");
11978
13140
  if (val !== void 0) opts.marginLeft = val;
11979
13141
  }
11980
13142
  const marRight = findChild(el, "w:marRight");
11981
13143
  if (marRight) {
11982
- const val = attrNum(marRight, "w:val");
13144
+ const val = attrMeasure(marRight, "w:val");
11983
13145
  if (val !== void 0) opts.marginRight = val;
11984
13146
  }
11985
13147
  const marTop = findChild(el, "w:marTop");
11986
13148
  if (marTop) {
11987
- const val = attrNum(marTop, "w:val");
13149
+ const val = attrMeasure(marTop, "w:val");
11988
13150
  if (val !== void 0) opts.marginTop = val;
11989
13151
  }
11990
13152
  const marBottom = findChild(el, "w:marBottom");
11991
13153
  if (marBottom) {
11992
- const val = attrNum(marBottom, "w:val");
13154
+ const val = attrMeasure(marBottom, "w:val");
11993
13155
  if (val !== void 0) opts.marginBottom = val;
11994
13156
  }
11995
13157
  const blockQuote = findChild(el, "w:blockQuote");
@@ -12106,7 +13268,15 @@ const webSettingsDesc = {
12106
13268
  p.push("</w:divs>");
12107
13269
  }
12108
13270
  if (opts.encoding !== void 0) p.push(wsStringVal("w:encoding", opts.encoding));
12109
- if (opts.optimizeForBrowser !== void 0) p.push(wsOnOff("w:optimizeForBrowser", opts.optimizeForBrowser));
13271
+ if (opts.optimizeForBrowser !== void 0) {
13272
+ const ob = opts.optimizeForBrowser;
13273
+ if (typeof ob === "boolean") p.push(wsOnOff("w:optimizeForBrowser", ob));
13274
+ else {
13275
+ const valAttr = ob.value === false ? " w:val=\"false\"" : "";
13276
+ const targetAttr = ob.target ? ` w:target="${wsEscapeAttr(ob.target)}"` : "";
13277
+ p.push(`<w:optimizeForBrowser${valAttr}${targetAttr}/>`);
13278
+ }
13279
+ }
12110
13280
  if (opts.relyOnVML !== void 0) p.push(wsOnOff("w:relyOnVML", opts.relyOnVML));
12111
13281
  if (opts.allowPNG !== void 0) p.push(wsOnOff("w:allowPNG", opts.allowPNG));
12112
13282
  if (opts.doNotRelyOnCSS !== void 0) p.push(wsOnOff("w:doNotRelyOnCSS", opts.doNotRelyOnCSS));
@@ -12134,7 +13304,6 @@ const webSettingsDesc = {
12134
13304
  if (val) opts.encoding = val;
12135
13305
  }
12136
13306
  for (const [name, optKey] of [
12137
- ["w:optimizeForBrowser", "optimizeForBrowser"],
12138
13307
  ["w:relyOnVML", "relyOnVML"],
12139
13308
  ["w:allowPNG", "allowPNG"],
12140
13309
  ["w:doNotRelyOnCSS", "doNotRelyOnCSS"],
@@ -12146,6 +13315,15 @@ const webSettingsDesc = {
12146
13315
  const child = findChild(el, name);
12147
13316
  if (child) opts[optKey] = attrBool(child, "w:val") ?? true;
12148
13317
  }
13318
+ const obEl = findChild(el, "w:optimizeForBrowser");
13319
+ if (obEl) {
13320
+ const target = attr(obEl, "w:target");
13321
+ if (target) opts.optimizeForBrowser = {
13322
+ value: attrBool(obEl, "w:val") ?? true,
13323
+ target
13324
+ };
13325
+ else opts.optimizeForBrowser = attrBool(obEl, "w:val") ?? true;
13326
+ }
12149
13327
  const ppi = findChild(el, "w:pixelsPerInch");
12150
13328
  if (ppi) {
12151
13329
  const val = attrNum(ppi, "w:val");
@@ -12160,6 +13338,6 @@ const webSettingsDesc = {
12160
13338
  }
12161
13339
  };
12162
13340
  //#endregion
12163
- export { tableDesc as $, RelativeVerticalPosition as $t, buildNumberingCache as A, LineRuleType as An, SpaceType as At, createLineNumberType as B, sdtBlockDesc as Bt, footnotesDesc as C, createTransformation as Cn, createPageNumberType as Ct, StyleLevel as D, TextAlignmentType as Dn, VerticalPositionRelativeFrom as Dt, SdtLock as E, PageNumber as En, HorizontalPositionRelativeFrom as Et, HeaderFooterType as F, TextWrappingType as Ft, DocumentGridType as G, subDocDesc as Gt, PageBorderDisplay as H, stringifyCustomXmlShell as Ht, createHeaderFooterReference as I, altChunkDesc as It, Numbering as J, TABLE_BORDERS_NONE as Jt, createDocumentGrid as K, stringifyElement as Kt, SectionType as L, checkboxSymbolRunInner as Lt, parseStyleDefinitions as M, createWrapThrough as Mt, DefaultStylesFactory as N, createWrapTight as Nt, settingsDesc as O, TextboxTightWrapType as On, HorizontalPositionAlign as Ot, HeaderFooterReferenceType as P, TextWrappingSide as Pt, setTableParseChild as Q, RelativeHorizontalPosition as Qt, createSectionType as R, customXmlBlockDesc as Rt, endnotesDesc as S, Media as Sn, PageNumberSeparator as St, SdtDateMappingType as T, TextEffect as Tn, createHorizontalPosition as Tt, PageBorderOffsetFrom as U, stringifySdtPr as Ut, createPageMargin as V, setBodyParseChild as Vt, PageBorderZOrder as W, stringifySdtShell as Wt, LevelFormat as X, TableLayoutType as Xt, parseNumberingDefinitions as Y, BorderStyle as Yt, LevelSuffix as Z, OverlapType as Zt, glossaryDesc as _, VerticalAnchor as _n, sectionMarginDefaults as _t, appPropertiesDesc as a, createFormFieldData as an, parseParagraph as at, CharacterSet as b, createImageData$1 as bn, PageOrientation as bt, relationshipsDesc as c, PositionalTabAlignment as cn, stringifyDocumentXml as ct, withAltChunkOverrides as d, EmphasisMarkType as dn, parseSdtBlock as dt, TableAnchorType as en, stringifyChildDispatch as et, withMediaDefaults as f, UnderlineType as fn, parseSdtProperties as ft, DocPartType as g, TextVerticalType as gn, stringifySectionPropertiesXml as gt, DocPartGallery as h, TextVertOverflowType as hn, sectionPropertiesDesc as ht, webSettingsDesc as i, FormFieldTextType as in, resetDrawingIdGen as it, buildStyleCache as j, AlignmentType as jn, VerticalPositionAlign as jt, Styles as k, HeadingLevel as kn, NumberFormat as kt, buildContentTypesFromRegistry as l, PositionalTabLeader as ln, replaceRelsWithPlaceholders as lt, DocPartBehavior as m, TextHorzOverflowType as mn, parseSectionPropertiesEl as mt, frameXml as n, VerticalMergeType as nn, stringifyRunInline as nt, customPropertiesDesc as o, parseFormFieldData as on, parseParagraphProperties as ot, commentsDesc as p, TextBodyWrappingType as pn, FontWrapper as pt, DocumentAttributeNamespaces as q, WidthType as qt, framesetXml as r, ProofErrorType as rn, drawingDesc as rt, corePropertiesDesc as s, RubyAlign as sn, stringifyBodyChild as st, TargetScreenSize as t, TextDirection as tn, stringifyParagraphInline as tt, contentTypesDesc as u, PositionalTabRelativeTo as un, stringifyTableOfContents as ut, bibliographyDesc as v, createBodyProperties as vn, sectionPageSizeDefaults as vt, parseToc as w, HighlightColor as wn, createVerticalPosition as wt, EditGroupType as x, WORKAROUND2 as xn, createPageSize as xt, fontTableDesc as y, parseBodyProperties as yn, PageTextDirectionType as yt, LineNumberRestartFormat as z, parseCustomXmlProperties as zt };
13341
+ export { PageBorderZOrder as $, stringifyCustomXmlShell as $t, settingsDesc as A, createBodyProperties as An, sectionPageSizeDefaults as At, stringifyConditionalTableStyle as B, TextAlignmentType as Bn, NumberFormat as Bt, footnotesDesc as C, EmphasisMarkType as Cn, parseSdtBlock as Ct, SdtDateMappingType as D, TextVertOverflowType as Dn, sectionPropertiesDesc as Dt, parseTocFieldInstruction as E, TextHorzOverflowType as En, parseSectionPropertiesEl as Et, parseStyleDefinitions as F, createTransformation as Fn, createVerticalPosition as Ft, createHeaderFooterReference as G, TextWrappingSide as Gt, stringifyTableStyle as H, HeadingLevel as Hn, VerticalPositionAlign as Ht, DefaultStylesFactory as I, HighlightColor as In, createHorizontalPosition as It, LineNumberRestartFormat as J, checkboxSymbolRunInner as Jt, SectionType as K, TextWrappingType as Kt, STYLE_ID_TO_DEFAULT_FIELD as L, TextEffect as Ln, HorizontalPositionRelativeFrom as Lt, buildNumberingCache as M, createImageData$1 as Mn, PageOrientation as Mt, buildStyleCache as N, WORKAROUND2 as Nn, PageNumberSeparator as Nt, SdtLock as O, TextVerticalType as On, stringifySectionPropertiesXml as Ot, extractStyleId as P, Media as Pn, createPageNumberType as Pt, PageBorderOffsetFrom as Q, setBodyParseChild as Qt, collectDefaultOverrideIds as R, PageNumber as Rn, VerticalPositionRelativeFrom as Rt, endnotesDesc as S, PositionalTabRelativeTo as Sn, stringifyTableOfContents as St, parseTocFieldFromElements as T, TextBodyWrappingType as Tn, FontWrapper as Tt, HeaderFooterReferenceType as U, LineRuleType as Un, createWrapThrough as Ut, stringifyParagraphStyle as V, TextboxTightWrapType as Vn, SpaceType as Vt, HeaderFooterType as W, AlignmentType as Wn, createWrapTight as Wt, createPageMargin as X, parseCustomXmlProperties as Xt, createLineNumberType as Y, customXmlBlockDesc as Yt, PageBorderDisplay as Z, sdtBlockDesc as Zt, glossaryDesc as _, createFormFieldData as _n, parseParagraph as _t, appPropertiesDesc as a, WidthType as an, LevelFormat as at, CharacterSet as b, PositionalTabAlignment as bn, stringifyDocumentXml as bt, relationshipsDesc as c, TableLayoutType as cn, parseTablePropertiesEl as ct, withAltChunkOverrides as d, RelativeVerticalPosition as dn, tableDesc as dt, stringifySdtPr as en, DocumentGridType as et, withMediaDefaults as f, TableAnchorType as fn, stringifyChildDispatch as ft, DocPartType as g, FormFieldTextType as gn, resetDrawingIdGen as gt, DocPartGallery as h, ProofErrorType as hn, drawingDesc as ht, webSettingsDesc as i, objectDesc as in, parseNumberingDefinitions as it, Styles as j, parseBodyProperties as jn, PageTextDirectionType as jt, StyleLevel as k, VerticalAnchor as kn, sectionMarginDefaults as kt, buildContentTypesFromRegistry as l, OverlapType as ln, parseTableRowPropertiesEl as lt, DocPartBehavior as m, VerticalMergeType as mn, stringifyRunInline as mt, frameXml as n, subDocDesc as nn, DocumentAttributeNamespaces as nt, customPropertiesDesc as o, TABLE_BORDERS_NONE as on, LevelSuffix as ot, commentsDesc as p, TextDirection as pn, stringifyParagraphInline as pt, createSectionType as q, altChunkDesc as qt, framesetXml as r, stringifyElement as rn, Numbering as rt, corePropertiesDesc as s, BorderStyle as sn, parseTableCellPropertiesEl as st, TargetScreenSize as t, stringifySdtShell as tn, createDocumentGrid as tt, contentTypesDesc as u, RelativeHorizontalPosition as un, setTableParseChild as ut, bibliographyDesc as v, parseFormFieldData as vn, parseParagraphProperties as vt, parseToc as w, UnderlineType as wn, parseSdtProperties as wt, EditGroupType as x, PositionalTabLeader as xn, replaceRelsWithPlaceholders as xt, fontTableDesc as y, RubyAlign as yn, stringifyBodyChild as yt, stringifyCharacterStyle as z, breakXml as zn, HorizontalPositionAlign as zt };
12164
13342
 
12165
- //# sourceMappingURL=parts-Cp_NxQFi.mjs.map
13343
+ //# sourceMappingURL=parts-DVpfsxSR.mjs.map