@office-open/docx 0.9.7 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { Relationships, TargetModeType, ThemeColor, blipDesc, 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";
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
2
  import { attr, attrBool, 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";
@@ -317,10 +317,26 @@ const createTransformation = (options) => ({
317
317
  */
318
318
  var Media = class {
319
319
  map;
320
+ nextMediaCounter = 0;
320
321
  constructor() {
321
322
  this.map = /* @__PURE__ */ new Map();
322
323
  }
323
324
  /**
325
+ * Allocates the next sequential media file name (Office-style `image1.png`,
326
+ * `image2.png`, …). The counter is package-global because media is shared
327
+ * across the document, headers, and footers, matching MS Office's numbering.
328
+ *
329
+ * Deterministic across runs (unlike random ids) so round-trip output is stable
330
+ * and diffable. Callers pair this with {@link findByContent} to reuse an
331
+ * existing entry for byte-identical content before allocating a new name.
332
+ *
333
+ * @param type - File extension / image type token (e.g. "png", "jpg")
334
+ * @returns A sequential file name like `image3.png`
335
+ */
336
+ nextMediaName(type) {
337
+ return `image${++this.nextMediaCounter}.${type}`;
338
+ }
339
+ /**
324
340
  * Adds an image to the media collection.
325
341
  *
326
342
  * @param key - Unique identifier for this image
@@ -330,6 +346,28 @@ var Media = class {
330
346
  this.map.set(key, mediaData);
331
347
  }
332
348
  /**
349
+ * Finds an existing image with byte-identical content (content-based dedup).
350
+ *
351
+ * Returns the matching entry's key (fileName) so callers reuse it instead of
352
+ * registering a duplicate — e.g. a VML fallback image that mirrors the Choice
353
+ * blip should share one relationship/file, matching Office's output.
354
+ *
355
+ * @param data - Raw image bytes to search for
356
+ * @returns The matching entry's key, or `undefined` if no match
357
+ */
358
+ findByContent(data) {
359
+ for (const [key, md] of this.map) {
360
+ const existing = toUint8Array(md.data);
361
+ if (existing.length !== data.length) continue;
362
+ let match = true;
363
+ for (let i = 0; i < existing.length; i++) if (existing[i] !== data[i]) {
364
+ match = false;
365
+ break;
366
+ }
367
+ if (match) return key;
368
+ }
369
+ }
370
+ /**
333
371
  * Gets all images as an array.
334
372
  *
335
373
  * @returns Read-only array of all media data in the collection
@@ -346,11 +384,11 @@ var Media = class {
346
384
  const WORKAROUND2 = "";
347
385
  //#endregion
348
386
  //#region src/parts/paragraph/run/image-run.ts
349
- const createImageData$1 = (data, transformation, key, srcRect, cNvPr) => ({
387
+ const createImageData$1 = (data, transformation, key, sourceRectangle, nonVisualProperties) => ({
350
388
  data,
351
389
  fileName: key,
352
- srcRect,
353
- cNvPr,
390
+ sourceRectangle,
391
+ nonVisualProperties,
354
392
  transformation: createTransformation(transformation)
355
393
  });
356
394
  //#endregion
@@ -1337,8 +1375,12 @@ function parseRunProperties(el) {
1337
1375
  const eastAsia = attr(font, "w:eastAsia");
1338
1376
  const hAnsi = attr(font, "w:hAnsi");
1339
1377
  const cs = attr(font, "w:cs");
1378
+ const asciiTheme = attr(font, "w:asciiTheme");
1379
+ const eastAsiaTheme = attr(font, "w:eastAsiaTheme");
1380
+ const hAnsiTheme = attr(font, "w:hAnsiTheme");
1381
+ const cstheme = attr(font, "w:cstheme");
1340
1382
  const hint = attr(font, "w:hint");
1341
- if (ascii && !eastAsia && !hAnsi && !cs) opts.font = hint ? {
1383
+ if (ascii && !eastAsia && !hAnsi && !cs && !asciiTheme && !eastAsiaTheme && !hAnsiTheme && !cstheme) opts.font = hint ? {
1342
1384
  name: ascii,
1343
1385
  hint
1344
1386
  } : ascii;
@@ -1348,6 +1390,10 @@ function parseRunProperties(el) {
1348
1390
  if (eastAsia) fontObj.eastAsia = eastAsia;
1349
1391
  if (hAnsi) fontObj.hAnsi = hAnsi;
1350
1392
  if (cs) fontObj.cs = cs;
1393
+ if (asciiTheme) fontObj.asciiTheme = asciiTheme;
1394
+ if (eastAsiaTheme) fontObj.eastAsiaTheme = eastAsiaTheme;
1395
+ if (hAnsiTheme) fontObj.hAnsiTheme = hAnsiTheme;
1396
+ if (cstheme) fontObj.cstheme = cstheme;
1351
1397
  if (hint) fontObj.hint = hint;
1352
1398
  opts.font = fontObj;
1353
1399
  }
@@ -1562,7 +1608,7 @@ const PARSED_LINE_BREAK = Symbol("LineBreak");
1562
1608
  /** Matches w:tab */
1563
1609
  const PARSED_TAB = Symbol("Tab");
1564
1610
  /** Matches w:cr */
1565
- const PARSED_CR = Symbol("CarriageReturn");
1611
+ const PARSED_CARRIAGE_RETURN = Symbol("CarriageReturn");
1566
1612
  /** Matches w:noBreakHyphen */
1567
1613
  const PARSED_NO_BREAK_HYPHEN = Symbol("NoBreakHyphen");
1568
1614
  /** Matches w:softHyphen */
@@ -1590,7 +1636,7 @@ const PARSED_SEPARATOR = Symbol("Separator");
1590
1636
  /** Matches w:continuationSeparator */
1591
1637
  const PARSED_CONTINUATION_SEPARATOR = Symbol("ContinuationSeparator");
1592
1638
  /** Matches w:pgNum */
1593
- const PARSED_PG_NUM = Symbol("PgNum");
1639
+ const PARSED_PAGE_NUMBER = Symbol("PageNumber");
1594
1640
  /** Matches w:lastRenderedPageBreak */
1595
1641
  const PARSED_LAST_RENDERED_PAGE_BREAK = Symbol("LastRenderedPageBreak");
1596
1642
  /**
@@ -1627,7 +1673,7 @@ function parseRun(el, _ctx) {
1627
1673
  children.push(PARSED_TAB);
1628
1674
  break;
1629
1675
  case "w:cr":
1630
- children.push(PARSED_CR);
1676
+ children.push(PARSED_CARRIAGE_RETURN);
1631
1677
  break;
1632
1678
  case "w:noBreakHyphen":
1633
1679
  children.push(PARSED_NO_BREAK_HYPHEN);
@@ -1693,7 +1739,7 @@ function parseRun(el, _ctx) {
1693
1739
  children.push(PARSED_CONTINUATION_SEPARATOR);
1694
1740
  break;
1695
1741
  case "w:pgNum":
1696
- children.push(PARSED_PG_NUM);
1742
+ children.push(PARSED_PAGE_NUMBER);
1697
1743
  break;
1698
1744
  case "w:lastRenderedPageBreak":
1699
1745
  children.push(PARSED_LAST_RENDERED_PAGE_BREAK);
@@ -1718,7 +1764,7 @@ function parseRun(el, _ctx) {
1718
1764
  /** Mapping from parse symbols to RunOptions child objects for empty elements. */
1719
1765
  const SYMBOL_TO_CHILD = new Map([
1720
1766
  [PARSED_TAB, { tab: true }],
1721
- [PARSED_CR, { carriageReturn: true }],
1767
+ [PARSED_CARRIAGE_RETURN, { carriageReturn: true }],
1722
1768
  [PARSED_NO_BREAK_HYPHEN, { noBreakHyphen: true }],
1723
1769
  [PARSED_SOFT_HYPHEN, { softHyphen: true }],
1724
1770
  [PARSED_DAY_SHORT, { dayShort: true }],
@@ -1730,7 +1776,7 @@ const SYMBOL_TO_CHILD = new Map([
1730
1776
  [PARSED_ANNOTATION_REF, { annotationRef: true }],
1731
1777
  [PARSED_SEPARATOR, { separator: true }],
1732
1778
  [PARSED_CONTINUATION_SEPARATOR, { continuationSeparator: true }],
1733
- [PARSED_PG_NUM, { pgNum: true }],
1779
+ [PARSED_PAGE_NUMBER, { pgNum: true }],
1734
1780
  [PARSED_LAST_RENDERED_PAGE_BREAK, { lastRenderedPageBreak: true }]
1735
1781
  ]);
1736
1782
  function parsedRunToOptions(parsed) {
@@ -2190,14 +2236,14 @@ const altChunkDesc = {
2190
2236
  contentType: opts.contentType
2191
2237
  });
2192
2238
  const rId = `rId${relId}`;
2193
- if (opts.matchSrc) return `<w:altChunk r:id="${rId}"><w:altChunkPr><w:matchSrc/></w:altChunkPr></w:altChunk>`;
2239
+ if (opts.matchSource) return `<w:altChunk r:id="${rId}"><w:altChunkPr><w:matchSrc/></w:altChunkPr></w:altChunk>`;
2194
2240
  return `<w:altChunk r:id="${rId}"/>`;
2195
2241
  },
2196
2242
  parse(el, ctx) {
2197
2243
  const rId = attr(el, "r:id");
2198
2244
  const opts = {};
2199
2245
  const altChunkPr = findChild(el, "w:altChunkPr");
2200
- if (altChunkPr && findChild(altChunkPr, "w:matchSrc")) opts.matchSrc = true;
2246
+ if (altChunkPr && findChild(altChunkPr, "w:matchSrc")) opts.matchSource = true;
2201
2247
  const dctx = ctx;
2202
2248
  if (rId) {
2203
2249
  const path = dctx.resolveRelationship(rId);
@@ -2231,7 +2277,7 @@ const subDocDesc = {
2231
2277
  stringify(opts, ctx) {
2232
2278
  const relId = uniqueId();
2233
2279
  const partPath = `subdocs/subdoc${relId}.docx`;
2234
- const data = typeof opts.data === "string" ? new TextEncoder().encode(opts.data) : opts.data;
2280
+ const data = toUint8Array(opts.data);
2235
2281
  ctx.fileData.document.relationships.addRelationship(relId, SUBDOC_REL_TYPE, partPath);
2236
2282
  ctx.fileData.subDocs.addSubDoc(relId, {
2237
2283
  data,
@@ -2483,8 +2529,8 @@ function parseSdtPr(el) {
2483
2529
  }
2484
2530
  return opts;
2485
2531
  }
2486
- /** Parse w:customXmlPr element into CustomXmlPrOptions. */
2487
- function parseCustomXmlPr(el) {
2532
+ /** Parse w:customXmlPr element into CustomXmlPropertiesOptions. */
2533
+ function parseCustomXmlProperties(el) {
2488
2534
  const opts = {};
2489
2535
  const placeholder = findChild(el, "w:placeholder");
2490
2536
  if (placeholder) {
@@ -2558,7 +2604,7 @@ const sdtBlockDesc = {
2558
2604
  };
2559
2605
  }
2560
2606
  };
2561
- function buildCustomXmlPrXml(pr) {
2607
+ function buildCustomXmlPropertiesXml(pr) {
2562
2608
  const parts = ["<w:customXmlPr>"];
2563
2609
  if (pr.placeholder !== void 0) parts.push(`<w:placeholder w:val="${escapeAttr$2(pr.placeholder)}"/>`);
2564
2610
  if (pr.attributes) for (const attr of pr.attributes) {
@@ -2576,7 +2622,7 @@ function buildCustomXmlPrXml(pr) {
2576
2622
  function stringifyCustomXmlShell(opts, contentXml) {
2577
2623
  const attrs = [`w:element="${escapeAttr$2(opts.element)}"`];
2578
2624
  if (opts.uri !== void 0) attrs.push(`w:uri="${escapeAttr$2(opts.uri)}"`);
2579
- const prXml = opts.customXmlPr ? buildCustomXmlPrXml(opts.customXmlPr) : "";
2625
+ const prXml = opts.customXmlPr ? buildCustomXmlPropertiesXml(opts.customXmlPr) : "";
2580
2626
  return `<w:customXml ${attrs.join(" ")}>${prXml}${contentXml}</w:customXml>`;
2581
2627
  }
2582
2628
  const customXmlBlockDesc = {
@@ -2594,7 +2640,7 @@ const customXmlBlockDesc = {
2594
2640
  const uri = attr(el, "w:uri");
2595
2641
  if (uri) opts.uri = uri;
2596
2642
  const xmlPr = findChild(el, "w:customXmlPr");
2597
- if (xmlPr) opts.customXmlPr = parseCustomXmlPr(xmlPr);
2643
+ if (xmlPr) opts.customXmlPr = parseCustomXmlProperties(xmlPr);
2598
2644
  const childList = [];
2599
2645
  for (const child of el.elements ?? []) {
2600
2646
  if (child.name === "w:customXmlPr") continue;
@@ -3262,7 +3308,7 @@ const PageOrientation = {
3262
3308
  * </xsd:complexType>
3263
3309
  * ```
3264
3310
  */
3265
- const createPageSize = ({ width, height, orientation, code }) => {
3311
+ const createPageSize = ({ width = 11906, height = 16838, orientation, code }) => {
3266
3312
  const widthTwips = twipsMeasureValue(width);
3267
3313
  const heightTwips = twipsMeasureValue(height);
3268
3314
  return element("w:pgSz", {
@@ -3709,6 +3755,19 @@ function parseSectionPropertiesEl(el) {
3709
3755
  }
3710
3756
  if (Object.keys(headerGroup).length > 0) opts.headerWrapperGroup = headerGroup;
3711
3757
  if (Object.keys(footerGroup).length > 0) opts.footerWrapperGroup = footerGroup;
3758
+ const sectPrChange = findChild(el, "w:sectPrChange");
3759
+ if (sectPrChange) {
3760
+ const rev = {};
3761
+ const author = attr(sectPrChange, "w:author");
3762
+ if (author) rev.author = author;
3763
+ const revDate = attr(sectPrChange, "w:date");
3764
+ if (revDate) rev.date = revDate;
3765
+ const revId = attrNum(sectPrChange, "w:id");
3766
+ if (revId !== void 0) rev.id = revId;
3767
+ const innerSectPr = findChild(sectPrChange, "w:sectPr");
3768
+ if (innerSectPr) Object.assign(rev, parseSectionPropertiesEl(innerSectPr));
3769
+ if (Object.keys(rev).length > 0) opts.revision = rev;
3770
+ }
3712
3771
  return opts;
3713
3772
  }
3714
3773
  function parseNotePropertiesEl(el) {
@@ -3760,6 +3819,7 @@ var FontWrapper = class {
3760
3819
  this.options = options;
3761
3820
  this.fontOptionsWithKey = options.map((o) => ({
3762
3821
  ...o,
3822
+ data: o.data !== void 0 ? toUint8Array(o.data) : void 0,
3763
3823
  fontKey: o.data !== void 0 ? o.fontKey ?? uniqueUuid() : o.fontKey ?? ""
3764
3824
  }));
3765
3825
  this.relationships = new Relationships();
@@ -4525,7 +4585,7 @@ function stringifyDocumentBackground(opts, ctx) {
4525
4585
  if (opts.rawXml) {
4526
4586
  if (opts.rawMedia) for (const m of opts.rawMedia) ctx.file.media.addImage(m.fileName, {
4527
4587
  type: m.type,
4528
- data: m.data,
4588
+ data: toUint8Array(m.data),
4529
4589
  fileName: m.fileName,
4530
4590
  transformation: {
4531
4591
  emus: {
@@ -4547,7 +4607,7 @@ function stringifyDocumentBackground(opts, ctx) {
4547
4607
  if (opts.themeTint !== void 0) attrs.push(`w:themeTint="${uCharHexNumber(opts.themeTint)}"`);
4548
4608
  const attrStr = attrs.join(" ");
4549
4609
  if (opts.image) {
4550
- const fileName = `${uniqueId()}.${opts.image.type}`;
4610
+ const fileName = ctx.file.media.nextMediaName(opts.image.type);
4551
4611
  const rawData = toUint8Array(opts.image.data);
4552
4612
  ctx.file.media.addImage(fileName, {
4553
4613
  type: opts.image.type,
@@ -4722,11 +4782,25 @@ function parseParagraphProperties(el, ctx) {
4722
4782
  break;
4723
4783
  }
4724
4784
  }
4725
- if (abstractNumId !== void 0) opts.numbering = {
4726
- reference: `list_${numId}`,
4727
- level
4728
- };
4729
- else opts.bullet = { level };
4785
+ if (abstractNumId !== void 0) {
4786
+ const numberingOpts = {
4787
+ reference: `list_${numId}`,
4788
+ level,
4789
+ custom: true
4790
+ };
4791
+ const numberingChangeEl = findChild(numPr, "w:numberingChange");
4792
+ if (numberingChangeEl) {
4793
+ const nc = {
4794
+ original: attr(numberingChangeEl, "w:original") ?? "",
4795
+ id: attr(numberingChangeEl, "w:id") ?? "",
4796
+ author: attr(numberingChangeEl, "w:author") ?? ""
4797
+ };
4798
+ const ncDate = attr(numberingChangeEl, "w:date");
4799
+ if (ncDate) nc.date = ncDate;
4800
+ numberingOpts.numberingChange = nc;
4801
+ }
4802
+ opts.numbering = numberingOpts;
4803
+ } else opts.bullet = { level };
4730
4804
  } else opts.bullet = { level };
4731
4805
  } else opts.bullet = { level };
4732
4806
  }
@@ -4870,6 +4944,19 @@ function parseParagraphProperties(el, ctx) {
4870
4944
  if (h !== void 0) frame.height = h;
4871
4945
  if (Object.keys(frame).length > 0) opts.frame = frame;
4872
4946
  }
4947
+ const pPrChange = findChild(el, "w:pPrChange");
4948
+ if (pPrChange) {
4949
+ const rev = {};
4950
+ const author = attr(pPrChange, "w:author");
4951
+ if (author) rev.author = author;
4952
+ const revDate = attr(pPrChange, "w:date");
4953
+ if (revDate) rev.date = revDate;
4954
+ const revId = attrNum(pPrChange, "w:id");
4955
+ if (revId !== void 0) rev.id = revId;
4956
+ const innerPPr = findChild(pPrChange, "w:pPr");
4957
+ if (innerPPr) Object.assign(rev, parseParagraphProperties(innerPPr, ctx));
4958
+ if (Object.keys(rev).length > 0) opts.revision = rev;
4959
+ }
4873
4960
  return opts;
4874
4961
  }
4875
4962
  /**
@@ -4879,6 +4966,16 @@ function parseParagraphProperties(el, ctx) {
4879
4966
  * (the runs between the `separate` and `end` fldChars). Only `<w:t>` is read —
4880
4967
  * `<w:tab>`/`<w:br>` in results are ignored as rare for user-entered text.
4881
4968
  */
4969
+ /** Parse the w:r children of a track-change wrapper (w:ins/w:moveFrom/w:moveTo). */
4970
+ function parseTrackChangeRuns(el, ctx) {
4971
+ const runs = [];
4972
+ for (const sub of el.elements ?? []) {
4973
+ if (sub.name !== "w:r") continue;
4974
+ const runOpts = parsedRunToOptions(parseRun(sub, ctx));
4975
+ if (runOpts !== null && typeof runOpts === "object" && !("commentReference" in runOpts)) runs.push(runOpts);
4976
+ }
4977
+ return runs;
4978
+ }
4882
4979
  function collectRunText(el) {
4883
4980
  let text = "";
4884
4981
  for (const c of el.elements ?? []) if (c.name === "w:t") text += textOf(c);
@@ -4950,7 +5047,7 @@ function parseCustomXmlInline(el, ctx) {
4950
5047
  if (uri) cx.uri = uri;
4951
5048
  const pr = findChild(el, "w:customXmlPr");
4952
5049
  if (pr) {
4953
- const parsed = parseCustomXmlPr(pr);
5050
+ const parsed = parseCustomXmlProperties(pr);
4954
5051
  if (parsed.placeholder !== void 0 || parsed.attributes !== void 0) cx.customXmlPr = parsed;
4955
5052
  }
4956
5053
  const content = parseContainerChildren(el, ctx);
@@ -5161,73 +5258,56 @@ function parseRunLevelChildren(elements, ctx) {
5161
5258
  break;
5162
5259
  }
5163
5260
  case "w:ins": {
5164
- const insRun = findChild(child, "w:r");
5165
- if (insRun) {
5166
- const runOpts = parsedRunToOptions(parseRun(insRun, ctx));
5167
- if (runOpts !== null && typeof runOpts === "object" && !("commentReference" in runOpts)) childList.push({ insertion: {
5168
- id: attrNum(child, "w:id") ?? 0,
5169
- author: attr(child, "w:author") ?? "",
5170
- date: attr(child, "w:date") ?? "",
5171
- ...runOpts
5172
- } });
5173
- }
5261
+ const children = parseTrackChangeRuns(child, ctx);
5262
+ if (children.length > 0) childList.push({ insertion: {
5263
+ id: attrNum(child, "w:id") ?? 0,
5264
+ author: attr(child, "w:author") ?? "",
5265
+ date: attr(child, "w:date") ?? "",
5266
+ children
5267
+ } });
5174
5268
  break;
5175
5269
  }
5176
5270
  case "w:del": {
5177
- let delFieldPlaceholder;
5271
+ const children = [];
5178
5272
  for (const sub of child.elements ?? []) {
5179
5273
  if (sub.name !== "w:r") continue;
5180
5274
  const delInstrEl = findChild(sub, "w:delInstrText");
5181
5275
  if (delInstrEl) {
5182
- delFieldPlaceholder = DELETED_PAGE_FIELD[(textOf(delInstrEl) ?? "").trim()];
5183
- if (delFieldPlaceholder) break;
5276
+ const placeholder = DELETED_PAGE_FIELD[(textOf(delInstrEl) ?? "").trim()];
5277
+ if (placeholder) {
5278
+ children.push(placeholder);
5279
+ continue;
5280
+ }
5184
5281
  }
5282
+ const runOpts = parsedRunToOptions(parseRun(sub, ctx));
5283
+ if (runOpts !== null && typeof runOpts === "object" && !("commentReference" in runOpts)) children.push(runOpts);
5185
5284
  }
5186
- if (delFieldPlaceholder) {
5187
- childList.push({ deletion: {
5188
- id: attrNum(child, "w:id") ?? 0,
5189
- author: attr(child, "w:author") ?? "",
5190
- date: attr(child, "w:date") ?? "",
5191
- children: [delFieldPlaceholder]
5192
- } });
5193
- break;
5194
- }
5195
- const delRun = findChild(child, "w:r");
5196
- if (delRun) {
5197
- const runOpts = parsedRunToOptions(parseRun(delRun, ctx));
5198
- if (runOpts !== null && typeof runOpts === "object" && !("commentReference" in runOpts)) childList.push({ deletion: {
5199
- id: attrNum(child, "w:id") ?? 0,
5200
- author: attr(child, "w:author") ?? "",
5201
- date: attr(child, "w:date") ?? "",
5202
- ...runOpts
5203
- } });
5204
- }
5285
+ if (children.length > 0) childList.push({ deletion: {
5286
+ id: attrNum(child, "w:id") ?? 0,
5287
+ author: attr(child, "w:author") ?? "",
5288
+ date: attr(child, "w:date") ?? "",
5289
+ children
5290
+ } });
5205
5291
  break;
5206
5292
  }
5207
5293
  case "w:moveFrom": {
5208
- const runEl = findChild(child, "w:r");
5209
- if (runEl) {
5210
- const runOpts = parsedRunToOptions(parseRun(runEl, ctx));
5211
- if (runOpts !== null && typeof runOpts === "object" && !("commentReference" in runOpts)) childList.push({ movedFrom: {
5212
- id: attrNum(child, "w:id") ?? 0,
5213
- author: attr(child, "w:author") ?? "",
5214
- date: attr(child, "w:date") ?? "",
5215
- ...runOpts
5216
- } });
5217
- }
5294
+ const children = parseTrackChangeRuns(child, ctx);
5295
+ if (children.length > 0) childList.push({ movedFrom: {
5296
+ id: attrNum(child, "w:id") ?? 0,
5297
+ author: attr(child, "w:author") ?? "",
5298
+ date: attr(child, "w:date") ?? "",
5299
+ children
5300
+ } });
5218
5301
  break;
5219
5302
  }
5220
5303
  case "w:moveTo": {
5221
- const runEl = findChild(child, "w:r");
5222
- if (runEl) {
5223
- const runOpts = parsedRunToOptions(parseRun(runEl, ctx));
5224
- if (runOpts !== null && typeof runOpts === "object" && !("commentReference" in runOpts)) childList.push({ movedTo: {
5225
- id: attrNum(child, "w:id") ?? 0,
5226
- author: attr(child, "w:author") ?? "",
5227
- date: attr(child, "w:date") ?? "",
5228
- ...runOpts
5229
- } });
5230
- }
5304
+ const children = parseTrackChangeRuns(child, ctx);
5305
+ if (children.length > 0) childList.push({ movedTo: {
5306
+ id: attrNum(child, "w:id") ?? 0,
5307
+ author: attr(child, "w:author") ?? "",
5308
+ date: attr(child, "w:date") ?? "",
5309
+ children
5310
+ } });
5231
5311
  break;
5232
5312
  }
5233
5313
  case "w:fldSimple": {
@@ -5623,10 +5703,10 @@ function parseImageRun(el, ctx) {
5623
5703
  const blipFill = findDeep(el, "pic:blipFill")[0];
5624
5704
  if (blipFill) {
5625
5705
  const srcRect = readSourceRectangle(blipFill);
5626
- if (srcRect) imageOpts.srcRect = srcRect;
5706
+ if (srcRect) imageOpts.sourceRectangle = srcRect;
5627
5707
  }
5628
5708
  const cNvPr = readPicCnvPr(el);
5629
- if (cNvPr) imageOpts.cNvPr = cNvPr;
5709
+ if (cNvPr) imageOpts.nonVisualProperties = cNvPr;
5630
5710
  const picSpPr = findDeep(el, "pic:spPr")[0];
5631
5711
  if (picSpPr) {
5632
5712
  const fill = readShapeFill(picSpPr, ctx);
@@ -5688,7 +5768,7 @@ function readPicCnvPr(el) {
5688
5768
  const descr = attr(cNvPr, "descr");
5689
5769
  if (id !== void 0) result.id = id;
5690
5770
  if (name) result.name = name;
5691
- if (descr) result.descr = descr;
5771
+ if (descr) result.description = descr;
5692
5772
  }
5693
5773
  const cNvPicPr = findChild(nvPicPr, "pic:cNvPicPr");
5694
5774
  if (cNvPicPr) {
@@ -5765,7 +5845,7 @@ function parseWpsShapeCore(wspEl, ctx) {
5765
5845
  if (title) nvp.title = title;
5766
5846
  }
5767
5847
  if (cNvCnPr) nvp.connector = true;
5768
- else if (txBox !== void 0) nvp.txBox = txBox;
5848
+ else if (txBox !== void 0) nvp.textBox = txBox;
5769
5849
  result.nonVisualProperties = nvp;
5770
5850
  }
5771
5851
  const spPr = findChild(wspEl, "wps:spPr");
@@ -5880,10 +5960,10 @@ function parsePicChildMediaData(picEl, ctx) {
5880
5960
  const blipFill = findChild(picEl, "pic:blipFill");
5881
5961
  if (blipFill) {
5882
5962
  const srcRect = readSourceRectangle(blipFill);
5883
- if (srcRect) result.srcRect = srcRect;
5963
+ if (srcRect) result.sourceRectangle = srcRect;
5884
5964
  }
5885
5965
  const cNvPr = readPicCnvPr(picEl);
5886
- if (cNvPr) result.cNvPr = cNvPr;
5966
+ if (cNvPr) result.nonVisualProperties = cNvPr;
5887
5967
  if (spPr) {
5888
5968
  const fill = readShapeFill(spPr, ctx);
5889
5969
  if (fill) result.fill = fill;
@@ -5903,7 +5983,8 @@ function parseWpsShapeDrawing(el, ctx) {
5903
5983
  ...parseWpsShapeCore(wsp, ctx),
5904
5984
  transformation: {
5905
5985
  width: info.width ?? 0,
5906
- height: info.height ?? 0
5986
+ height: info.height ?? 0,
5987
+ ...info.effectExtent ? { effectExtent: info.effectExtent } : {}
5907
5988
  }
5908
5989
  };
5909
5990
  if (info.floating) shape.floating = info.floating;
@@ -5919,21 +6000,22 @@ function parseWpgGroupDrawing(el, ctx) {
5919
6000
  if (!wgp) return void 0;
5920
6001
  const info = parseAnchorOrInline(el) ?? {};
5921
6002
  const grpSpPr = findChild(wgp, "wpg:grpSpPr");
5922
- const { chOff, chExt } = readGroupCoords(grpSpPr);
6003
+ const { childOffset, childExtent } = readGroupCoords(grpSpPr);
5923
6004
  const group = {
5924
6005
  children: parseGroupChildren(wgp, ctx),
5925
6006
  transformation: {
5926
6007
  width: info.width ?? 0,
5927
- height: info.height ?? 0
6008
+ height: info.height ?? 0,
6009
+ ...info.effectExtent ? { effectExtent: info.effectExtent } : {}
5928
6010
  }
5929
6011
  };
5930
- if (chOff) group.chOff = chOff;
5931
- if (chExt) group.chExt = chExt;
6012
+ if (childOffset) group.childOffset = childOffset;
6013
+ if (childExtent) group.childExtent = childExtent;
5932
6014
  if (info.floating) group.floating = info.floating;
5933
6015
  if (info.altText) group.altText = info.altText;
5934
6016
  if (info.graphicFrameLocks !== void 0) group.graphicFrameLocks = info.graphicFrameLocks;
5935
6017
  const grpSpLocks = readGrpSpLocks(findChild(wgp, "wpg:cNvGrpSpPr"));
5936
- if (grpSpLocks) group.grpSpLocks = grpSpLocks;
6018
+ if (grpSpLocks) group.groupShapeLocks = grpSpLocks;
5937
6019
  if (grpSpPr) {
5938
6020
  const fill = readShapeFill(grpSpPr, ctx);
5939
6021
  if (fill) group.fill = fill;
@@ -5950,21 +6032,21 @@ function readGroupCoords(grpSpPr) {
5950
6032
  if (!grpSpPr) return {};
5951
6033
  const xfrm = findChild(grpSpPr, "a:xfrm");
5952
6034
  if (!xfrm) return {};
5953
- let chOff;
5954
- let chExt;
6035
+ let childOffset;
6036
+ let childExtent;
5955
6037
  const off = findChild(xfrm, "a:chOff");
5956
- if (off?.attributes) chOff = {
6038
+ if (off?.attributes) childOffset = {
5957
6039
  x: Number(off.attributes["x"] ?? 0),
5958
6040
  y: Number(off.attributes["y"] ?? 0)
5959
6041
  };
5960
6042
  const ext = findChild(xfrm, "a:chExt");
5961
- if (ext?.attributes) chExt = {
6043
+ if (ext?.attributes) childExtent = {
5962
6044
  cx: Number(ext.attributes["cx"] ?? 0),
5963
6045
  cy: Number(ext.attributes["cy"] ?? 0)
5964
6046
  };
5965
6047
  return {
5966
- chOff,
5967
- chExt
6048
+ childOffset,
6049
+ childExtent
5968
6050
  };
5969
6051
  }
5970
6052
  /**
@@ -5992,16 +6074,16 @@ function parseGroupChild(el, ctx) {
5992
6074
  */
5993
6075
  function parseNestedGroup(grpSpEl, ctx) {
5994
6076
  const grpSpPr = findChild(grpSpEl, "wpg:grpSpPr");
5995
- const { chOff, chExt } = readGroupCoords(grpSpPr);
6077
+ const { childOffset, childExtent } = readGroupCoords(grpSpPr);
5996
6078
  const result = {
5997
6079
  type: "wpg",
5998
6080
  transformation: readChildTransformation(grpSpPr),
5999
6081
  children: parseGroupChildren(grpSpEl, ctx)
6000
6082
  };
6001
- if (chOff) result.chOff = chOff;
6002
- if (chExt) result.chExt = chExt;
6083
+ if (childOffset) result.childOffset = childOffset;
6084
+ if (childExtent) result.childExtent = childExtent;
6003
6085
  const grpSpLocks = readGrpSpLocks(findChild(grpSpEl, "wpg:cNvGrpSpPr"));
6004
- if (grpSpLocks) result.grpSpLocks = grpSpLocks;
6086
+ if (grpSpLocks) result.groupShapeLocks = grpSpLocks;
6005
6087
  if (grpSpPr) {
6006
6088
  const fill = readShapeFill(grpSpPr, ctx);
6007
6089
  if (fill) result.fill = fill;
@@ -6364,7 +6446,7 @@ function stringifyBlipFill(mediaData, blipEffects, tile) {
6364
6446
  const blipContent = (extParts.length > 0 ? `<a:extLst>${extParts.join("")}</a:extLst>` : "") + (blipEffects ? buildBlipEffectsXml(blipEffects) : "");
6365
6447
  if (blipContent) parts.push(`<a:blip ${blipAttrs.join(" ")}>${blipContent}</a:blip>`);
6366
6448
  else parts.push(`<a:blip ${blipAttrs.join(" ")}/>`);
6367
- const srcRectXml = buildSrcRectXml(mediaData.srcRect);
6449
+ const srcRectXml = buildSrcRectXml(mediaData.sourceRectangle);
6368
6450
  if (srcRectXml) parts.push(srcRectXml);
6369
6451
  if (tile) {
6370
6452
  const tileAttrs = [];
@@ -6416,16 +6498,16 @@ function stringifyNvPicPr(hlIds, cNvPr) {
6416
6498
  const hlXml = buildHyperlinkChildren(hlIds);
6417
6499
  const id = cNvPr?.id ?? 0;
6418
6500
  const name = escapeXml(cNvPr?.name ?? "");
6419
- const descrAttr = cNvPr?.descr ? ` descr="${escapeXml(cNvPr.descr)}"` : "";
6501
+ const descrAttr = cNvPr?.description ? ` descr="${escapeXml(cNvPr.description)}"` : "";
6420
6502
  const cNvPicPrAttr = cNvPr?.preferRelativeResize === false ? " preferRelativeResize=\"0\"" : "";
6421
6503
  return `<pic:nvPicPr><pic:cNvPr id="${id}" name="${name}"${descrAttr}${hlXml ? `>${hlXml}</pic:cNvPr>` : "/>"}<pic:cNvPicPr${cNvPicPrAttr}><a:picLocks noChangeAspect="1"/></pic:cNvPicPr></pic:nvPicPr>`;
6422
6504
  }
6423
- function stringifyGroupTransform2D(transform, chOff, chExt) {
6505
+ function stringifyGroupTransform2D(transform, childOffset, childExtent) {
6424
6506
  const attrs = [];
6425
6507
  if (transform.flip?.horizontal !== void 0) attrs.push(`flipH="${transform.flip.horizontal}"`);
6426
6508
  if (transform.flip?.vertical !== void 0) attrs.push(`flipV="${transform.flip.vertical}"`);
6427
6509
  if (transform.rotation !== void 0) attrs.push(`rot="${transform.rotation}"`);
6428
- return `<a:xfrm${attrs.length ? " " + attrs.join(" ") : ""}>${`<a:off x="${transform.offset?.emus?.x ?? 0}" y="${transform.offset?.emus?.y ?? 0}"/>`}${`<a:ext cx="${transform.emus.x}" cy="${transform.emus.y}"/>`}${chOff ? `<a:chOff x="${chOff.x}" y="${chOff.y}"/>` : ""}${chExt ? `<a:chExt cx="${chExt.cx}" cy="${chExt.cy}"/>` : ""}</a:xfrm>`;
6510
+ return `<a:xfrm${attrs.length ? " " + attrs.join(" ") : ""}>${`<a:off x="${transform.offset?.emus?.x ?? 0}" y="${transform.offset?.emus?.y ?? 0}"/>`}${`<a:ext cx="${transform.emus.x}" cy="${transform.emus.y}"/>`}${childOffset ? `<a:chOff x="${childOffset.x}" y="${childOffset.y}"/>` : ""}${childExtent ? `<a:chExt cx="${childExtent.cx}" cy="${childExtent.cy}"/>` : ""}</a:xfrm>`;
6429
6511
  }
6430
6512
  function stringifyWpsShape(opts, ctx) {
6431
6513
  const transform = opts.transformation;
@@ -6464,7 +6546,7 @@ function stringifyNonVisualShapeProperties(opts) {
6464
6546
  xml += `<wps:cNvPr ${attrs.join(" ")}/>`;
6465
6547
  }
6466
6548
  if (opts.connector) xml += "<wps:cNvCnPr/>";
6467
- else if (opts.txBox !== void 0) xml += `<wps:cNvSpPr txBox="${opts.txBox}"/>`;
6549
+ else if (opts.textBox !== void 0) xml += `<wps:cNvSpPr txBox="${opts.textBox}"/>`;
6468
6550
  else xml += "<wps:cNvSpPr/>";
6469
6551
  return xml;
6470
6552
  }
@@ -6487,11 +6569,11 @@ function stringifyBodyPr(opts) {
6487
6569
  function stringifyWpgGroup(opts, ctx) {
6488
6570
  const transform = opts.transformation;
6489
6571
  const grpSpPrParts = [];
6490
- grpSpPrParts.push(stringifyGroupTransform2D(transform, opts.chOff, opts.chExt));
6572
+ grpSpPrParts.push(stringifyGroupTransform2D(transform, opts.childOffset, opts.childExtent));
6491
6573
  if (opts.fill) grpSpPrParts.push(fillDesc$1.stringify(opts.fill, NOOP_CTX) ?? "");
6492
6574
  if (opts.effects) grpSpPrParts.push(effectListDesc$1.stringify(opts.effects, NOOP_CTX) ?? "");
6493
6575
  const childXml = opts.children.map((child) => stringifyGroupChild(child, ctx)).join("");
6494
- return "<wpg:wgp>" + stringifyCnvGrpSpPr(opts.grpSpLocks) + `<wpg:grpSpPr>${grpSpPrParts.join("")}</wpg:grpSpPr>` + childXml + "</wpg:wgp>";
6576
+ return "<wpg:wgp>" + stringifyCnvGrpSpPr(opts.groupShapeLocks) + `<wpg:grpSpPr>${grpSpPrParts.join("")}</wpg:grpSpPr>` + childXml + "</wpg:wgp>";
6495
6577
  }
6496
6578
  /**
6497
6579
  * Stringify one group child: a wps shape, a nested wpg group, or a picture.
@@ -6510,11 +6592,11 @@ function stringifyGroupChild(child, ctx) {
6510
6592
  if (child.type === "wpg") return stringifyNestedGroup(child, ctx);
6511
6593
  const picData = child;
6512
6594
  const picParts = [];
6513
- picParts.push(stringifyNvPicPr({}, picData.cNvPr));
6595
+ picParts.push(stringifyNvPicPr({}, picData.nonVisualProperties));
6514
6596
  const groupBlipParts = [];
6515
6597
  const useLocalDpiExt = buildUseLocalDpiExt(picData.useLocalDpi);
6516
6598
  groupBlipParts.push(useLocalDpiExt ? `<a:blip r:embed="{${escapeXml(picData.fileName)}}"><a:extLst>${useLocalDpiExt}</a:extLst></a:blip>` : `<a:blip r:embed="{${escapeXml(picData.fileName)}}"/>`);
6517
- const groupSrcRectXml = buildSrcRectXml(picData.srcRect);
6599
+ const groupSrcRectXml = buildSrcRectXml(picData.sourceRectangle);
6518
6600
  if (groupSrcRectXml) groupBlipParts.push(groupSrcRectXml);
6519
6601
  groupBlipParts.push("<a:stretch><a:fillRect/></a:stretch>");
6520
6602
  picParts.push(`<pic:blipFill>${groupBlipParts.join("")}</pic:blipFill>`);
@@ -6527,10 +6609,10 @@ function stringifyGroupChild(child, ctx) {
6527
6609
  */
6528
6610
  function stringifyNestedGroup(grp, ctx) {
6529
6611
  const grpSpPrParts = [];
6530
- grpSpPrParts.push(stringifyGroupTransform2D(grp.transformation, grp.chOff, grp.chExt));
6612
+ grpSpPrParts.push(stringifyGroupTransform2D(grp.transformation, grp.childOffset, grp.childExtent));
6531
6613
  if (grp.fill) grpSpPrParts.push(fillDesc$1.stringify(grp.fill, NOOP_CTX) ?? "");
6532
6614
  if (grp.effects) grpSpPrParts.push(effectListDesc$1.stringify(grp.effects, NOOP_CTX) ?? "");
6533
- return "<wpg:grpSp><wpg:cNvPr id=\"0\" name=\"\"/>" + stringifyCnvGrpSpPr(grp.grpSpLocks) + `<wpg:grpSpPr>${grpSpPrParts.join("")}</wpg:grpSpPr>` + grp.children.map((c) => stringifyGroupChild(c, ctx)).join("") + "</wpg:grpSp>";
6615
+ return "<wpg:grpSp><wpg:cNvPr id=\"0\" name=\"\"/>" + stringifyCnvGrpSpPr(grp.groupShapeLocks) + `<wpg:grpSpPr>${grpSpPrParts.join("")}</wpg:grpSpPr>` + grp.children.map((c) => stringifyGroupChild(c, ctx)).join("") + "</wpg:grpSp>";
6534
6616
  }
6535
6617
  function stringifyGraphicDataContent(mediaData, opts, hlIds, ctx) {
6536
6618
  const { outline, fill, effects, blipEffects, tile } = opts;
@@ -6551,15 +6633,15 @@ function stringifyGraphicDataContent(mediaData, opts, hlIds, ctx) {
6551
6633
  return `<a:graphicData uri="${WPG_URI}">${stringifyWpgGroup({
6552
6634
  children: md.children,
6553
6635
  transformation: transform,
6554
- chOff: md.chOff,
6555
- chExt: md.chExt,
6636
+ childOffset: md.childOffset,
6637
+ childExtent: md.childExtent,
6556
6638
  fill: md.fill,
6557
6639
  effects: md.effects,
6558
- grpSpLocks: md.grpSpLocks
6640
+ groupShapeLocks: md.groupShapeLocks
6559
6641
  }, ctx)}</a:graphicData>`;
6560
6642
  }
6561
6643
  const md = mediaData;
6562
- return `<a:graphicData uri="${PIC_URI}"><pic:pic xmlns:pic="${PIC_URI}">` + stringifyNvPicPr(hlIds, md.cNvPr) + stringifyBlipFill(md, blipEffects, tile) + stringifyShapeProps(transform, outline, fill, effects) + `</pic:pic></a:graphicData>`;
6644
+ return `<a:graphicData uri="${PIC_URI}"><pic:pic xmlns:pic="${PIC_URI}">` + stringifyNvPicPr(hlIds, md.nonVisualProperties) + stringifyBlipFill(md, blipEffects, tile) + stringifyShapeProps(transform, outline, fill, effects) + `</pic:pic></a:graphicData>`;
6563
6645
  }
6564
6646
  function stringifyPositionH(opts) {
6565
6647
  return `<wp:positionH relativeFrom="${opts.relative ?? HorizontalPositionRelativeFrom.PAGE}">${opts.align ? `<wp:align>${opts.align}</wp:align>` : opts.offset !== void 0 ? `<wp:posOffset>${opts.offset}</wp:posOffset>` : "<wp:align>left</wp:align>"}</wp:positionH>`;
@@ -6695,7 +6777,7 @@ const drawingDesc = {
6695
6777
  kind: "custom",
6696
6778
  stringify(opts, ctx) {
6697
6779
  if (opts.fill) {
6698
- const media = extractBlipFillMedia(opts.fill);
6780
+ const media = extractBlipFillMedia(opts.fill, (type) => ctx.file.media.nextMediaName(type));
6699
6781
  if (media) ctx.file.media.addImage(media.fileName, {
6700
6782
  data: media.data,
6701
6783
  fileName: media.fileName,
@@ -6822,6 +6904,27 @@ const createEnd = (dirty) => createFieldChar(FieldCharacterType.END, dirty);
6822
6904
  *
6823
6905
  * @module
6824
6906
  */
6907
+ /** Serialize a deleted run: rPr + delText (or field delInstrText). */
6908
+ function stringifyDeletedRun(c) {
6909
+ const opts = typeof c === "string" ? { text: c } : c;
6910
+ const parts = [];
6911
+ const rPr = stringifyRunProperties(opts);
6912
+ if (rPr) parts.push(rPr);
6913
+ if (opts.break) for (let i = 0; i < opts.break; i++) parts.push("<w:br/>");
6914
+ const fieldMap = {
6915
+ CURRENT: "PAGE",
6916
+ TOTAL_PAGES: "NUMPAGES",
6917
+ TOTAL_PAGES_IN_SECTION: "SECTIONPAGES"
6918
+ };
6919
+ if (opts.children) {
6920
+ for (const cc of opts.children) if (typeof cc === "string") {
6921
+ const instrText = fieldMap[cc];
6922
+ 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"/>`);
6923
+ else parts.push(`<w:delText xml:space="preserve">${escapeXml(cc)}</w:delText>`);
6924
+ }
6925
+ } else if (opts.text) parts.push(`<w:delText xml:space="preserve">${escapeXml(String(opts.text))}</w:delText>`);
6926
+ return `<w:r>${parts.join("")}</w:r>`;
6927
+ }
6825
6928
  function stringifyRunInline(opts, ctx) {
6826
6929
  const parts = [];
6827
6930
  const rPr = stringifyRunProperties(opts);
@@ -6842,12 +6945,12 @@ function stringifyRunInline(opts, ctx) {
6842
6945
  const body = parts.join("");
6843
6946
  return body.length === 0 ? attr ? `<w:r${attr}/>` : "<w:r/>" : `<w:r${attr}>${body}</w:r>`;
6844
6947
  }
6845
- function createImageData(data, transformation, key, srcRect, cNvPr) {
6948
+ function createImageData(data, transformation, key, sourceRectangle, nonVisualProperties) {
6846
6949
  return {
6847
6950
  data,
6848
6951
  fileName: key,
6849
- srcRect,
6850
- cNvPr,
6952
+ sourceRectangle,
6953
+ nonVisualProperties,
6851
6954
  transformation: createTransformation(transformation)
6852
6955
  };
6853
6956
  }
@@ -6874,24 +6977,37 @@ function wrapDrawingRun(drawingXml, opts) {
6874
6977
  /**
6875
6978
  * Register media carried by a VML fallback (mc:AlternateContent Fallback) so the
6876
6979
  * compiler resolves the fallback's `{fileName}` placeholders into rIds.
6980
+ *
6981
+ * A VML fallback image mirrors its Choice blip (same source bytes). When the
6982
+ * blip is already registered, reuse it and remap the fallback's `{fileName}`
6983
+ * placeholder to the shared media — matching Office, which emits one
6984
+ * relationship/file per image rather than a duplicate for the VML branch.
6877
6985
  */
6878
6986
  function registerVmlFallbackMedia(opts, ctx) {
6879
6987
  if (!opts.vmlFallbackMedia) return;
6880
- for (const m of opts.vmlFallbackMedia) ctx.file.media.addImage(m.fileName, {
6881
- type: m.type,
6882
- data: m.data,
6883
- fileName: m.fileName,
6884
- transformation: {
6885
- emus: {
6886
- x: 0,
6887
- y: 0
6888
- },
6889
- pixels: {
6890
- x: 0,
6891
- y: 0
6892
- }
6988
+ for (const m of opts.vmlFallbackMedia) {
6989
+ const data = toUint8Array(m.data);
6990
+ const existing = ctx.file.media.findByContent(data);
6991
+ if (existing) {
6992
+ if (opts.vmlFallback) opts.vmlFallback = opts.vmlFallback.split(`{${m.fileName}}`).join(`{${existing}}`);
6993
+ continue;
6893
6994
  }
6894
- });
6995
+ ctx.file.media.addImage(m.fileName, {
6996
+ type: m.type,
6997
+ data,
6998
+ fileName: m.fileName,
6999
+ transformation: {
7000
+ emus: {
7001
+ x: 0,
7002
+ y: 0
7003
+ },
7004
+ pixels: {
7005
+ x: 0,
7006
+ y: 0
7007
+ }
7008
+ }
7009
+ });
7010
+ }
6895
7011
  }
6896
7012
  /**
6897
7013
  * Resolve a break/tab run's rPr: prefer the raw rPr carried from parse (verbatim,
@@ -6939,23 +7055,23 @@ function stringifyChildDispatch(child, ctx) {
6939
7055
  }
6940
7056
  if ("image" in child) {
6941
7057
  const opts = child.image;
6942
- const key = `${uniqueId()}.${opts.type}`;
7058
+ const key = ctx.file.media.nextMediaName(opts.type);
6943
7059
  const rawData = toUint8Array(opts.data);
6944
7060
  let mediaData;
6945
7061
  if (opts.type === "svg") {
6946
7062
  const fallbackData = toUint8Array(opts.fallback.data);
6947
7063
  mediaData = {
6948
7064
  type: "svg",
6949
- ...createImageData(rawData, opts.transformation, key, opts.srcRect, opts.cNvPr),
7065
+ ...createImageData(rawData, opts.transformation, key, opts.sourceRectangle, opts.nonVisualProperties),
6950
7066
  useLocalDpi: opts.useLocalDpi,
6951
7067
  fallback: {
6952
7068
  type: opts.fallback.type,
6953
- ...createImageData(fallbackData, opts.transformation, `${uniqueId()}.${opts.fallback.type}`)
7069
+ ...createImageData(fallbackData, opts.transformation, ctx.file.media.nextMediaName(opts.fallback.type))
6954
7070
  }
6955
7071
  };
6956
7072
  } else mediaData = {
6957
7073
  type: opts.type,
6958
- ...createImageData(rawData, opts.transformation, key, opts.srcRect, opts.cNvPr),
7074
+ ...createImageData(rawData, opts.transformation, key, opts.sourceRectangle, opts.nonVisualProperties),
6959
7075
  useLocalDpi: opts.useLocalDpi
6960
7076
  };
6961
7077
  ctx.file.media.addImage(mediaData.fileName, mediaData);
@@ -7047,11 +7163,11 @@ function stringifyChildDispatch(child, ctx) {
7047
7163
  const mediaData = {
7048
7164
  children: opts.children,
7049
7165
  transformation: createTransformation(opts.transformation),
7050
- chOff: opts.chOff,
7051
- chExt: opts.chExt,
7166
+ childOffset: opts.childOffset,
7167
+ childExtent: opts.childExtent,
7052
7168
  fill: opts.fill,
7053
7169
  effects: opts.effects,
7054
- grpSpLocks: opts.grpSpLocks,
7170
+ groupShapeLocks: opts.groupShapeLocks,
7055
7171
  type: "wpg"
7056
7172
  };
7057
7173
  const registerMedia = (children) => {
@@ -7095,29 +7211,14 @@ function stringifyChildDispatch(child, ctx) {
7095
7211
  }
7096
7212
  if ("math" in child && typeof child.math === "object" && child.math !== null) return stringifyMath(child.math.children ?? []);
7097
7213
  if ("insertion" in child) {
7098
- const { id, author, date, ...runOpts } = child.insertion;
7099
- const runXml = stringifyRunInline(runOpts, ctx);
7100
- return `<w:ins w:id="${id}" w:author="${escapeXml(String(author))}" w:date="${date}">${runXml}</w:ins>`;
7214
+ const { id, author, date, children } = child.insertion;
7215
+ const body = children.map((c) => stringifyRunInline(typeof c === "string" ? { text: c } : c, ctx)).join("");
7216
+ return `<w:ins w:id="${id}" w:author="${escapeXml(String(author))}" w:date="${date}">${body}</w:ins>`;
7101
7217
  }
7102
7218
  if ("deletion" in child) {
7103
- const { id, author, date, ...runOpts } = child.deletion;
7104
- const parts = [];
7105
- const rPr = stringifyRunProperties(runOpts);
7106
- if (rPr) parts.push(rPr);
7107
- if (runOpts.break) for (let i = 0; i < runOpts.break; i++) parts.push("<w:br/>");
7108
- if (runOpts.children) {
7109
- for (const c of runOpts.children) if (typeof c === "string") {
7110
- const instrText = {
7111
- CURRENT: "PAGE",
7112
- TOTAL_PAGES: "NUMPAGES",
7113
- TOTAL_PAGES_IN_SECTION: "SECTIONPAGES"
7114
- }[c];
7115
- 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"/>`);
7116
- else parts.push(`<w:delText xml:space="preserve">${escapeXml(c)}</w:delText>`);
7117
- }
7118
- } else if (runOpts.text) parts.push(`<w:delText xml:space="preserve">${escapeXml(String(runOpts.text))}</w:delText>`);
7119
- const runBody = parts.join("");
7120
- return `<w:del w:id="${id}" w:author="${escapeXml(String(author))}" w:date="${date}"><w:r>${runBody}</w:r></w:del>`;
7219
+ const { id, author, date, children } = child.deletion;
7220
+ const body = children.map((c) => stringifyDeletedRun(c)).join("");
7221
+ return `<w:del w:id="${id}" w:author="${escapeXml(String(author))}" w:date="${date}">${body}</w:del>`;
7121
7222
  }
7122
7223
  if ("hyperlink" in child) {
7123
7224
  const hl = child.hyperlink;
@@ -7173,14 +7274,14 @@ function stringifyChildDispatch(child, ctx) {
7173
7274
  }
7174
7275
  if ("moveToRangeEnd" in child) return `<w:moveToRangeEnd w:id="${child.moveToRangeEnd}"/>`;
7175
7276
  if ("movedFrom" in child) {
7176
- const { id, author, date, ...runOpts } = child.movedFrom;
7177
- const runXml = stringifyRunInline(runOpts, ctx);
7178
- return `<w:moveFrom w:id="${id}" w:author="${escapeXml(String(author))}" w:date="${date}">${runXml}</w:moveFrom>`;
7277
+ const { id, author, date, children } = child.movedFrom;
7278
+ const body = children.map((c) => stringifyRunInline(typeof c === "string" ? { text: c } : c, ctx)).join("");
7279
+ return `<w:moveFrom w:id="${id}" w:author="${escapeXml(String(author))}" w:date="${date}">${body}</w:moveFrom>`;
7179
7280
  }
7180
7281
  if ("movedTo" in child) {
7181
- const { id, author, date, ...runOpts } = child.movedTo;
7182
- const runXml = stringifyRunInline(runOpts, ctx);
7183
- return `<w:moveTo w:id="${id}" w:author="${escapeXml(String(author))}" w:date="${date}">${runXml}</w:moveTo>`;
7282
+ const { id, author, date, children } = child.movedTo;
7283
+ const body = children.map((c) => stringifyRunInline(typeof c === "string" ? { text: c } : c, ctx)).join("");
7284
+ return `<w:moveTo w:id="${id}" w:author="${escapeXml(String(author))}" w:date="${date}">${body}</w:moveTo>`;
7184
7285
  }
7185
7286
  if ("customXmlInsRangeStart" in child) {
7186
7287
  const o = child.customXmlInsRangeStart;
@@ -8418,7 +8519,7 @@ function parseTableRowEl(el, ctx) {
8418
8519
  if (cxUri) cx.uri = cxUri;
8419
8520
  const xmlPr = findChild(child, "w:customXmlPr");
8420
8521
  if (xmlPr) {
8421
- const parsed = parseCustomXmlPr(xmlPr);
8522
+ const parsed = parseCustomXmlProperties(xmlPr);
8422
8523
  if (parsed.placeholder !== void 0 || parsed.attributes !== void 0) cx.customXmlPr = parsed;
8423
8524
  }
8424
8525
  const cxCells = [];
@@ -8458,7 +8559,7 @@ function parseTableEl(el, ctx) {
8458
8559
  if (cxUri) cx.uri = cxUri;
8459
8560
  const xmlPr = findChild(child, "w:customXmlPr");
8460
8561
  if (xmlPr) {
8461
- const parsed = parseCustomXmlPr(xmlPr);
8562
+ const parsed = parseCustomXmlProperties(xmlPr);
8462
8563
  if (parsed.placeholder !== void 0 || parsed.attributes !== void 0) cx.customXmlPr = parsed;
8463
8564
  }
8464
8565
  const cxRows = [];
@@ -8818,9 +8919,10 @@ var Numbering = class {
8818
8919
  };
8819
8920
  function stringifyAbstractNumbering(id, levels, extraOptions) {
8820
8921
  const parts = [];
8821
- parts.push(`<w:abstractNum w:abstractNumId="${decimalNumber(id)}" w15:restartNumberingAfterBreak="0">`);
8922
+ const restartAttr = extraOptions?.restartNumberingAfterBreak !== void 0 ? ` w15:restartNumberingAfterBreak="${extraOptions.restartNumberingAfterBreak ? 1 : 0}"` : "";
8923
+ parts.push(`<w:abstractNum w:abstractNumId="${decimalNumber(id)}"${restartAttr}>`);
8822
8924
  if (extraOptions?.nsid !== void 0) parts.push(`<w:nsid w:val="${extraOptions.nsid}"/>`);
8823
- parts.push(`<w:multiLevelType w:val="hybridMultilevel"/>`);
8925
+ parts.push(`<w:multiLevelType w:val="${extraOptions?.multiLevelType ?? "hybridMultilevel"}"/>`);
8824
8926
  if (extraOptions?.tmpl !== void 0) parts.push(`<w:tmpl w:val="${extraOptions.tmpl}"/>`);
8825
8927
  if (extraOptions?.name !== void 0) parts.push(`<w:name w:val="${extraOptions.name}"/>`);
8826
8928
  if (extraOptions?.styleLink !== void 0) parts.push(`<w:styleLink w:val="${extraOptions.styleLink}"/>`);
@@ -8858,7 +8960,8 @@ function stringifyLevel(opts) {
8858
8960
  const rPrXml = stringifyRunProperties(opts.style && opts.style.run);
8859
8961
  if (pPrXml) children.push(pPrXml);
8860
8962
  if (rPrXml) children.push(rPrXml);
8861
- const lvlAttrs = [`w:ilvl="${decimalNumber(Math.min(opts.level, 9))}"`, `w15:tentative="1"`];
8963
+ const lvlAttrs = [`w:ilvl="${decimalNumber(Math.min(opts.level, 9))}"`];
8964
+ if (opts.w15Tentative !== void 0) lvlAttrs.push(`w15:tentative="${opts.w15Tentative ? 1 : 0}"`);
8862
8965
  if (opts.templateCode !== void 0) lvlAttrs.push(`w:tplc="${opts.templateCode}"`);
8863
8966
  if (opts.tentative !== void 0) lvlAttrs.push(`w:tentative="${opts.tentative ? 1 : 0}"`);
8864
8967
  return `<w:lvl ${lvlAttrs.join(" ")}>${children.join("")}</w:lvl>`;
@@ -8898,6 +9001,13 @@ function parseNumberingDefinitions(el, parseParagraphProperties, ctx) {
8898
9001
  const v = attr(nsidEl, "w:val");
8899
9002
  if (v) extraOptions.nsid = v;
8900
9003
  }
9004
+ const multiLevelTypeEl = findChild(abstractEl, "w:multiLevelType");
9005
+ if (multiLevelTypeEl) {
9006
+ const v = attr(multiLevelTypeEl, "w:val");
9007
+ if (v) extraOptions.multiLevelType = v;
9008
+ }
9009
+ const restartVal = attrBool(abstractEl, "w15:restartNumberingAfterBreak");
9010
+ if (restartVal !== void 0) extraOptions.restartNumberingAfterBreak = restartVal;
8901
9011
  const tmplEl = findChild(abstractEl, "w:tmpl");
8902
9012
  if (tmplEl) {
8903
9013
  const v = attr(tmplEl, "w:val");
@@ -8966,6 +9076,8 @@ function parseLevelEl(el, parseParagraphProperties, ctx) {
8966
9076
  if (tplc) opts.templateCode = tplc;
8967
9077
  const tentative = attrBool(el, "w:tentative");
8968
9078
  if (tentative !== void 0) opts.tentative = tentative;
9079
+ const w15Tentative = attrBool(el, "w15:tentative");
9080
+ if (w15Tentative !== void 0) opts.w15Tentative = w15Tentative;
8969
9081
  const style = {};
8970
9082
  const rPr = findChild(el, "w:rPr");
8971
9083
  if (rPr) {
@@ -9417,6 +9529,60 @@ function stringifyCharacterStyle(opts) {
9417
9529
  if (rPr) children.push(rPr);
9418
9530
  return `<w:style w:type="character" w:styleId="${esc(opts.id)}">${children.join("")}</w:style>`;
9419
9531
  }
9532
+ /** Resolve a user override for heading level N (1-9) from default styles options. */
9533
+ function headingOverride(options, level) {
9534
+ switch (level) {
9535
+ case 1: return options.heading1;
9536
+ case 2: return options.heading2;
9537
+ case 3: return options.heading3;
9538
+ case 4: return options.heading4;
9539
+ case 5: return options.heading5;
9540
+ case 6: return options.heading6;
9541
+ case 7: return options.heading7;
9542
+ case 8: return options.heading8;
9543
+ case 9: return options.heading9;
9544
+ default: return;
9545
+ }
9546
+ }
9547
+ /**
9548
+ * Maps DefaultStylesOptions override fields to every built-in styleId the
9549
+ * factory (re)emits when that field is provided — the main style plus its
9550
+ * linked character style (e.g. heading1 -> Heading1 + Heading1Char).
9551
+ */
9552
+ const DEFAULT_STYLE_FIELDS = [
9553
+ ["title", ["Title", "TitleChar"]],
9554
+ ["subtitle", ["Subtitle", "SubtitleChar"]],
9555
+ ["heading1", ["Heading1", "Heading1Char"]],
9556
+ ["heading2", ["Heading2", "Heading2Char"]],
9557
+ ["heading3", ["Heading3", "Heading3Char"]],
9558
+ ["heading4", ["Heading4", "Heading4Char"]],
9559
+ ["heading5", ["Heading5", "Heading5Char"]],
9560
+ ["heading6", ["Heading6", "Heading6Char"]],
9561
+ ["heading7", ["Heading7", "Heading7Char"]],
9562
+ ["heading8", ["Heading8", "Heading8Char"]],
9563
+ ["heading9", ["Heading9", "Heading9Char"]],
9564
+ ["listParagraph", ["ListParagraph"]],
9565
+ ["quote", ["Quote", "QuoteChar"]],
9566
+ ["strong", ["Strong"]],
9567
+ ["emphasis", ["Emphasis"]]
9568
+ ];
9569
+ /**
9570
+ * Reverse map: main built-in styleId -> the DefaultStylesOptions field that
9571
+ * overrides it. Linked char ids (Heading1Char, TitleChar, ...) are excluded —
9572
+ * they ride along with their main style.
9573
+ */
9574
+ const STYLE_ID_TO_DEFAULT_FIELD = Object.fromEntries(DEFAULT_STYLE_FIELDS.map(([field, [mainId]]) => [mainId, field]));
9575
+ /**
9576
+ * Collect every styleId the factory (re)emits for the default-styles fields the
9577
+ * user explicitly provided — including linked character styles, so the
9578
+ * round-trip path drops the matching verbatim entries (no duplicate styleId).
9579
+ */
9580
+ function collectDefaultOverrideIds(defaultOpts) {
9581
+ const ids = /* @__PURE__ */ new Set();
9582
+ if (!defaultOpts) return ids;
9583
+ for (const [field, styleIds] of DEFAULT_STYLE_FIELDS) if (defaultOpts[field] !== void 0) for (const id of styleIds) ids.add(id);
9584
+ return ids;
9585
+ }
9420
9586
  /** Build `<w:docDefaults>` XML matching Word's default settings. */
9421
9587
  function stringifyDocDefaults(opts) {
9422
9588
  const children = [];
@@ -9456,7 +9622,7 @@ var DefaultStylesFactory = class {
9456
9622
  importedStyles.push({ _raw: stringifyDocDefaults(options.document ?? {}) });
9457
9623
  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>" });
9458
9624
  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>" });
9459
- for (const h of [
9625
+ const headings = [
9460
9626
  {
9461
9627
  id: "Heading1",
9462
9628
  name: "heading 1",
@@ -9538,7 +9704,36 @@ var DefaultStylesFactory = class {
9538
9704
  after: "0",
9539
9705
  outlineLvl: "8"
9540
9706
  }
9541
- ]) {
9707
+ ];
9708
+ for (let headingIdx = 0; headingIdx < headings.length; headingIdx++) {
9709
+ const h = headings[headingIdx];
9710
+ const headingOverrideOpts = headingOverride(options, headingIdx + 1);
9711
+ if (headingOverrideOpts) {
9712
+ importedStyles.push({ _raw: stringifyParagraphStyle({
9713
+ id: h.id,
9714
+ name: headingOverrideOpts.name ?? h.name,
9715
+ basedOn: headingOverrideOpts.basedOn ?? "Normal",
9716
+ next: headingOverrideOpts.next ?? "Normal",
9717
+ link: headingOverrideOpts.link ?? h.link,
9718
+ uiPriority: headingOverrideOpts.uiPriority ?? 9,
9719
+ quickFormat: headingOverrideOpts.quickFormat ?? true,
9720
+ semiHidden: headingOverrideOpts.semiHidden,
9721
+ unhideWhenUsed: headingOverrideOpts.unhideWhenUsed,
9722
+ paragraph: {
9723
+ outlineLevel: headingIdx,
9724
+ ...headingOverrideOpts.paragraph
9725
+ },
9726
+ run: headingOverrideOpts.run
9727
+ }) });
9728
+ importedStyles.push({ _raw: stringifyCharacterStyle({
9729
+ id: h.link,
9730
+ name: `${h.name} Char`,
9731
+ basedOn: "DefaultParagraphFont",
9732
+ link: h.id,
9733
+ run: headingOverrideOpts.run
9734
+ }) });
9735
+ continue;
9736
+ }
9542
9737
  const pPrParts = [`<w:keepNext/>`, `<w:keepLines/>`];
9543
9738
  if (h.before || h.after) {
9544
9739
  const sp = [];
@@ -9563,13 +9758,103 @@ var DefaultStylesFactory = class {
9563
9758
  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>" });
9564
9759
  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>" });
9565
9760
  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>" });
9566
- 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>" });
9567
- 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>" });
9568
- 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>" });
9569
- 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>" });
9570
- 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>" });
9571
- 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>" });
9572
- 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>" });
9761
+ if (options.title) {
9762
+ importedStyles.push({ _raw: stringifyParagraphStyle({
9763
+ id: "Title",
9764
+ name: options.title.name ?? "Title",
9765
+ basedOn: options.title.basedOn ?? "Normal",
9766
+ next: options.title.next ?? "Normal",
9767
+ link: options.title.link ?? "TitleChar",
9768
+ uiPriority: options.title.uiPriority ?? 10,
9769
+ quickFormat: options.title.quickFormat ?? true,
9770
+ paragraph: options.title.paragraph,
9771
+ run: options.title.run
9772
+ }) });
9773
+ importedStyles.push({ _raw: stringifyCharacterStyle({
9774
+ id: "TitleChar",
9775
+ name: "Title Char",
9776
+ basedOn: "DefaultParagraphFont",
9777
+ link: "Title",
9778
+ run: options.title.run
9779
+ }) });
9780
+ } else {
9781
+ 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>" });
9782
+ 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>" });
9783
+ }
9784
+ if (options.subtitle) {
9785
+ importedStyles.push({ _raw: stringifyParagraphStyle({
9786
+ id: "Subtitle",
9787
+ name: options.subtitle.name ?? "Subtitle",
9788
+ basedOn: options.subtitle.basedOn ?? "Normal",
9789
+ next: options.subtitle.next ?? "Normal",
9790
+ link: options.subtitle.link ?? "SubtitleChar",
9791
+ uiPriority: options.subtitle.uiPriority ?? 11,
9792
+ quickFormat: options.subtitle.quickFormat ?? true,
9793
+ paragraph: options.subtitle.paragraph,
9794
+ run: options.subtitle.run
9795
+ }) });
9796
+ importedStyles.push({ _raw: stringifyCharacterStyle({
9797
+ id: "SubtitleChar",
9798
+ name: "Subtitle Char",
9799
+ basedOn: "DefaultParagraphFont",
9800
+ link: "Subtitle",
9801
+ run: options.subtitle.run
9802
+ }) });
9803
+ } else {
9804
+ 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>" });
9805
+ 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>" });
9806
+ }
9807
+ if (options.listParagraph) importedStyles.push({ _raw: stringifyParagraphStyle({
9808
+ id: "ListParagraph",
9809
+ name: options.listParagraph.name ?? "List Paragraph",
9810
+ basedOn: options.listParagraph.basedOn ?? "Normal",
9811
+ uiPriority: options.listParagraph.uiPriority ?? 34,
9812
+ quickFormat: options.listParagraph.quickFormat ?? true,
9813
+ paragraph: options.listParagraph.paragraph,
9814
+ run: options.listParagraph.run
9815
+ }) });
9816
+ 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>" });
9817
+ if (options.strong) importedStyles.push({ _raw: stringifyParagraphStyle({
9818
+ id: "Strong",
9819
+ name: options.strong.name ?? "Strong",
9820
+ basedOn: options.strong.basedOn ?? "Normal",
9821
+ next: options.strong.next ?? "Normal",
9822
+ quickFormat: options.strong.quickFormat ?? true,
9823
+ paragraph: options.strong.paragraph,
9824
+ run: options.strong.run
9825
+ }) });
9826
+ if (options.emphasis) importedStyles.push({ _raw: stringifyParagraphStyle({
9827
+ id: "Emphasis",
9828
+ name: options.emphasis.name ?? "Emphasis",
9829
+ basedOn: options.emphasis.basedOn ?? "Normal",
9830
+ next: options.emphasis.next ?? "Normal",
9831
+ quickFormat: options.emphasis.quickFormat ?? true,
9832
+ paragraph: options.emphasis.paragraph,
9833
+ run: options.emphasis.run
9834
+ }) });
9835
+ if (options.quote) {
9836
+ importedStyles.push({ _raw: stringifyParagraphStyle({
9837
+ id: "Quote",
9838
+ name: options.quote.name ?? "Quote",
9839
+ basedOn: options.quote.basedOn ?? "Normal",
9840
+ next: options.quote.next ?? "Normal",
9841
+ link: options.quote.link ?? "QuoteChar",
9842
+ uiPriority: options.quote.uiPriority ?? 29,
9843
+ quickFormat: options.quote.quickFormat ?? true,
9844
+ paragraph: options.quote.paragraph,
9845
+ run: options.quote.run
9846
+ }) });
9847
+ importedStyles.push({ _raw: stringifyCharacterStyle({
9848
+ id: "QuoteChar",
9849
+ name: "Quote Char",
9850
+ basedOn: "DefaultParagraphFont",
9851
+ link: "Quote",
9852
+ run: options.quote.run
9853
+ }) });
9854
+ } else {
9855
+ 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>" });
9856
+ 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>" });
9857
+ }
9573
9858
  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>" });
9574
9859
  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>" });
9575
9860
  importedStyles.push({ _raw: stringifyCharacterStyle({
@@ -9672,6 +9957,16 @@ var DefaultStylesFactory = class {
9672
9957
  * @module
9673
9958
  */
9674
9959
  /**
9960
+ * Extract the `w:styleId` from a raw `<w:style>` XML string, if present.
9961
+ *
9962
+ * Returns `undefined` for non-style elements (docDefaults / latentStyles),
9963
+ * whose raw XML carries no `w:styleId` attribute.
9964
+ */
9965
+ function extractStyleId(raw) {
9966
+ const m = raw.match(/w:styleId="([^"]+)"/);
9967
+ return m ? m[1] : void 0;
9968
+ }
9969
+ /**
9675
9970
  * Represents the styles definitions in a WordprocessingML document.
9676
9971
  *
9677
9972
  * Pure collector — no XmlComponent inheritance.
@@ -9682,8 +9977,16 @@ var Styles = class {
9682
9977
  parts = [];
9683
9978
  constructor(options) {
9684
9979
  if (options.initialAttributes) this.attributes = options.initialAttributes;
9685
- if (options.importedStyles) {
9686
- for (const style of options.importedStyles) if (style._raw) this.parts.push(style._raw);
9980
+ const customStyleIds = /* @__PURE__ */ new Set();
9981
+ for (const s of options.paragraphStyles ?? []) customStyleIds.add(s.id);
9982
+ for (const s of options.characterStyles ?? []) customStyleIds.add(s.id);
9983
+ if (options.importedStyles) for (const style of options.importedStyles) {
9984
+ if (!style._raw) continue;
9985
+ if (customStyleIds.size > 0) {
9986
+ const id = extractStyleId(style._raw);
9987
+ if (id && customStyleIds.has(id)) continue;
9988
+ }
9989
+ this.parts.push(style._raw);
9687
9990
  }
9688
9991
  if (options.paragraphStyles) for (const style of options.paragraphStyles) this.parts.push(stringifyParagraphStyle({
9689
9992
  id: style.id,
@@ -9794,6 +10097,13 @@ function parseStyleDefinitions(el, parseParagraphProperties, ctx) {
9794
10097
  const styleOpts = parseStyleElement(child, parseParagraphProperties, ctx);
9795
10098
  if (!styleOpts?._type || !styleOpts.id) continue;
9796
10099
  (opts.importedStyles ??= []).push({ _raw: stringifyElement(child) });
10100
+ const defaultField = STYLE_ID_TO_DEFAULT_FIELD[styleOpts.id];
10101
+ if (defaultField) {
10102
+ const { _type: _omitType, id: _omitId, ...rest } = styleOpts;
10103
+ opts.default ??= {};
10104
+ opts.default[defaultField] = rest;
10105
+ continue;
10106
+ }
9797
10107
  if (BUILTIN_STYLE_IDS.has(styleOpts.id)) continue;
9798
10108
  const type = styleOpts._type;
9799
10109
  delete styleOpts._type;
@@ -10401,17 +10711,9 @@ const settingsDesc = {
10401
10711
  if (val) opts.defaultTabStop = parseInt(val, 10);
10402
10712
  }
10403
10713
  const trackRevEl = findChild(el, "w:trackRevisions");
10404
- if (trackRevEl) {
10405
- const features = opts.features ?? {};
10406
- features.trackRevisions = attrBool(trackRevEl, "w:val") ?? true;
10407
- opts.features = features;
10408
- }
10714
+ if (trackRevEl) opts.trackRevisions = attrBool(trackRevEl, "w:val") ?? true;
10409
10715
  const updateFieldsEl = findChild(el, "w:updateFields");
10410
- if (updateFieldsEl) {
10411
- const features = opts.features ?? {};
10412
- features.updateFields = attrBool(updateFieldsEl, "w:val") ?? true;
10413
- opts.features = features;
10414
- }
10716
+ if (updateFieldsEl) opts.updateFields = attrBool(updateFieldsEl, "w:val") ?? true;
10415
10717
  const compatEl = findChild(el, "w:compat");
10416
10718
  if (compatEl) {
10417
10719
  for (const child of compatEl.elements ?? []) if (child.name === "w:compatSetting") {
@@ -10593,11 +10895,7 @@ const settingsDesc = {
10593
10895
  const formatting = attr(docProtEl, "w:formatting");
10594
10896
  if (formatting !== void 0) prot.formatting = formatting === "1" || formatting === "true";
10595
10897
  }
10596
- if (Object.keys(prot).length > 0) {
10597
- const features = opts.features ?? {};
10598
- features.documentProtection = prot;
10599
- opts.features = features;
10600
- }
10898
+ if (Object.keys(prot).length > 0) opts.documentProtection = prot;
10601
10899
  }
10602
10900
  const noMovesEl = findChild(el, "w:doNotTrackMoves");
10603
10901
  if (noMovesEl) opts.doNotTrackMoves = attrBool(noMovesEl, "w:val") ?? true;
@@ -10800,18 +11098,22 @@ function parseFieldSwitches(text) {
10800
11098
  const NS$2 = "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.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: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\"";
10801
11099
  /** XML for the footnoteRef run — auto-injected at start of first paragraph. */
10802
11100
  const FOOTNOTE_REF_RUN = "<w:r><w:rPr><w:rStyle w:val=\"FootnoteReference\"/></w:rPr><w:footnoteRef/></w:r>";
10803
- /** Separator footnote (id=-1). */
11101
+ /** Default separator footnote (id=-1) for freshly generated documents. */
10804
11102
  const SEPARATOR_FOOTNOTE = "<w:footnote w:type=\"separator\" w:id=\"-1\"><w:p><w:pPr><w:spacing w:after=\"0\" w:line=\"240\" w:lineRule=\"auto\"/></w:pPr><w:r><w:separator/></w:r></w:p></w:footnote>";
10805
- /** Continuation separator footnote (id=0). */
11103
+ /** Default continuation separator footnote (id=0) for freshly generated documents. */
10806
11104
  const CONTINUATION_SEPARATOR_FOOTNOTE = "<w:footnote w:type=\"continuationSeparator\" w:id=\"0\"><w:p><w:pPr><w:spacing w:after=\"0\" w:line=\"240\" w:lineRule=\"auto\"/></w:pPr><w:r><w:continuationSeparator/></w:r></w:p></w:footnote>";
11105
+ /** Render a system footnote from round-tripped id + content, or the spec default. */
11106
+ function footnoteSystemNote(type, sep, fallback, ctx) {
11107
+ if (!sep) return fallback;
11108
+ const inner = sep.paragraphs.map((p) => stringifyParagraphInline(p, ctx)).join("");
11109
+ return `<w:footnote w:type="${type}" w:id="${sep.id}">${inner}</w:footnote>`;
11110
+ }
10807
11111
  const footnotesDesc = {
10808
11112
  kind: "custom",
10809
11113
  stringify(data, ctx) {
10810
- const parts = [
10811
- `<w:footnotes ${NS$2} mc:Ignorable="w14 w15 wp14">`,
10812
- SEPARATOR_FOOTNOTE,
10813
- CONTINUATION_SEPARATOR_FOOTNOTE
10814
- ];
11114
+ const parts = [`<w:footnotes ${NS$2} mc:Ignorable="w14 w15 wp14">`];
11115
+ parts.push(footnoteSystemNote("separator", data.separator, SEPARATOR_FOOTNOTE, ctx));
11116
+ parts.push(footnoteSystemNote("continuationSeparator", data.continuationSeparator, CONTINUATION_SEPARATOR_FOOTNOTE, ctx));
10815
11117
  for (const [id, paragraphs] of data.notes) {
10816
11118
  parts.push(`<w:footnote w:id="${id}">`);
10817
11119
  for (let i = 0; i < paragraphs.length; i++) {
@@ -10829,16 +11131,30 @@ const footnotesDesc = {
10829
11131
  },
10830
11132
  parse(el, ctx) {
10831
11133
  const notes = /* @__PURE__ */ new Map();
11134
+ let separator;
11135
+ let continuationSeparator;
10832
11136
  for (const child of el.elements ?? []) {
10833
11137
  if (child.name !== "w:footnote") continue;
10834
11138
  const id = attrNum(child, "w:id");
10835
11139
  if (id === void 0) continue;
10836
- if (attr(child, "w:type") || id < 1) continue;
11140
+ const type = attr(child, "w:type");
10837
11141
  const paragraphs = [];
10838
11142
  for (const sub of child.elements ?? []) if (sub.name === "w:p") paragraphs.push(parseParagraph(sub, ctx));
10839
- notes.set(id, paragraphs);
11143
+ if (type === "separator") separator = {
11144
+ id,
11145
+ paragraphs
11146
+ };
11147
+ else if (type === "continuationSeparator") continuationSeparator = {
11148
+ id,
11149
+ paragraphs
11150
+ };
11151
+ else notes.set(id, paragraphs);
10840
11152
  }
10841
- return { notes };
11153
+ return {
11154
+ notes,
11155
+ separator,
11156
+ continuationSeparator
11157
+ };
10842
11158
  }
10843
11159
  };
10844
11160
  //#endregion
@@ -10846,18 +11162,22 @@ const footnotesDesc = {
10846
11162
  const NS$1 = "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.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: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\"";
10847
11163
  /** XML for the endnoteRef run — auto-injected at start of first paragraph. */
10848
11164
  const ENDNOTE_REF_RUN = "<w:r><w:rPr><w:rStyle w:val=\"EndnoteReference\"/></w:rPr><w:endnoteRef/></w:r>";
10849
- /** Separator endnote (id=-1). */
11165
+ /** Default separator endnote (id=-1) for freshly generated documents. */
10850
11166
  const SEPARATOR_ENDNOTE = "<w:endnote w:type=\"separator\" w:id=\"-1\"><w:p><w:pPr><w:spacing w:after=\"0\" w:line=\"240\" w:lineRule=\"auto\"/></w:pPr><w:r><w:separator/></w:r></w:p></w:endnote>";
10851
- /** Continuation separator endnote (id=0). */
11167
+ /** Default continuation separator endnote (id=0) for freshly generated documents. */
10852
11168
  const CONTINUATION_SEPARATOR_ENDNOTE = "<w:endnote w:type=\"continuationSeparator\" w:id=\"0\"><w:p><w:pPr><w:spacing w:after=\"0\" w:line=\"240\" w:lineRule=\"auto\"/></w:pPr><w:r><w:continuationSeparator/></w:r></w:p></w:endnote>";
11169
+ /** Render a system endnote from round-tripped id + content, or the spec default. */
11170
+ function endnoteSystemNote(type, sep, fallback, ctx) {
11171
+ if (!sep) return fallback;
11172
+ const inner = sep.paragraphs.map((p) => stringifyParagraphInline(p, ctx)).join("");
11173
+ return `<w:endnote w:type="${type}" w:id="${sep.id}">${inner}</w:endnote>`;
11174
+ }
10853
11175
  const endnotesDesc = {
10854
11176
  kind: "custom",
10855
11177
  stringify(data, ctx) {
10856
- const parts = [
10857
- `<w:endnotes ${NS$1} mc:Ignorable="w14 w15 wp14">`,
10858
- SEPARATOR_ENDNOTE,
10859
- CONTINUATION_SEPARATOR_ENDNOTE
10860
- ];
11178
+ const parts = [`<w:endnotes ${NS$1} mc:Ignorable="w14 w15 wp14">`];
11179
+ parts.push(endnoteSystemNote("separator", data.separator, SEPARATOR_ENDNOTE, ctx));
11180
+ parts.push(endnoteSystemNote("continuationSeparator", data.continuationSeparator, CONTINUATION_SEPARATOR_ENDNOTE, ctx));
10861
11181
  for (const [id, paragraphs] of data.notes) {
10862
11182
  parts.push(`<w:endnote w:id="${id}">`);
10863
11183
  for (let i = 0; i < paragraphs.length; i++) {
@@ -10875,16 +11195,30 @@ const endnotesDesc = {
10875
11195
  },
10876
11196
  parse(el, ctx) {
10877
11197
  const notes = /* @__PURE__ */ new Map();
11198
+ let separator;
11199
+ let continuationSeparator;
10878
11200
  for (const child of el.elements ?? []) {
10879
11201
  if (child.name !== "w:endnote") continue;
10880
11202
  const id = attrNum(child, "w:id");
10881
11203
  if (id === void 0) continue;
10882
- if (attr(child, "w:type") || id < 1) continue;
11204
+ const type = attr(child, "w:type");
10883
11205
  const paragraphs = [];
10884
11206
  for (const sub of child.elements ?? []) if (sub.name === "w:p") paragraphs.push(parseParagraph(sub, ctx));
10885
- notes.set(id, paragraphs);
11207
+ if (type === "separator") separator = {
11208
+ id,
11209
+ paragraphs
11210
+ };
11211
+ else if (type === "continuationSeparator") continuationSeparator = {
11212
+ id,
11213
+ paragraphs
11214
+ };
11215
+ else notes.set(id, paragraphs);
10886
11216
  }
10887
- return { notes };
11217
+ return {
11218
+ notes,
11219
+ separator,
11220
+ continuationSeparator
11221
+ };
10888
11222
  }
10889
11223
  };
10890
11224
  //#endregion
@@ -11269,8 +11603,11 @@ function escapeAttr(s) {
11269
11603
  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\"";
11270
11604
  function stringifyComment(opts, ctx) {
11271
11605
  const dateStr = typeof opts.date === "string" ? opts.date : (opts.date ?? /* @__PURE__ */ new Date()).toISOString();
11272
- const attrs = [`w:id="${opts.id}"`, `w:date="${escapeAttr(dateStr)}"`];
11273
- if (opts.author !== void 0) attrs.push(`w:author="${escapeAttr(opts.author)}"`);
11606
+ const attrs = [
11607
+ `w:id="${opts.id}"`,
11608
+ `w:author="${escapeAttr(opts.author ?? "")}"`,
11609
+ `w:date="${escapeAttr(dateStr)}"`
11610
+ ];
11274
11611
  if (opts.initials !== void 0) attrs.push(`w:initials="${escapeAttr(opts.initials)}"`);
11275
11612
  const parts = [];
11276
11613
  for (const child of opts.children) parts.push(stringifyParagraphInline(child, ctx));
@@ -11294,9 +11631,9 @@ const commentsDesc = {
11294
11631
  const date = attr(child, "w:date");
11295
11632
  if (date) comment.date = date;
11296
11633
  const author = attr(child, "w:author");
11297
- if (author) comment.author = author;
11634
+ if (author !== void 0) comment.author = author;
11298
11635
  const initials = attr(child, "w:initials");
11299
- if (initials) comment.initials = initials;
11636
+ if (initials !== void 0) comment.initials = initials;
11300
11637
  const children = [];
11301
11638
  for (const sub of child.elements ?? []) if (sub.name === "w:p") children.push(parseParagraph(sub, ctx));
11302
11639
  comment.children = children;
@@ -11307,6 +11644,13 @@ const commentsDesc = {
11307
11644
  };
11308
11645
  //#endregion
11309
11646
  //#region src/parts/contenttypes.ts
11647
+ /**
11648
+ * Content types descriptor — produces [Content_Types].xml.
11649
+ *
11650
+ * Reference: OPC, Content_Types.xsd
11651
+ *
11652
+ * @module
11653
+ */
11310
11654
  function defaultXml(ext, ct) {
11311
11655
  return `<Default Extension="${ext}" ContentType="${ct}"/>`;
11312
11656
  }
@@ -11436,111 +11780,69 @@ function withMediaDefaults(input, mediaFileNames) {
11436
11780
  overrides: input.overrides
11437
11781
  };
11438
11782
  }
11439
- /** Helper to build the standard DOCX content types with dynamic overrides. */
11440
- function buildContentTypes(extras = {}) {
11441
- const defaults = [...STANDARD_DEFAULTS];
11442
- const overrides = [
11443
- {
11444
- partName: "/word/document.xml",
11445
- contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"
11446
- },
11447
- {
11448
- partName: "/word/styles.xml",
11449
- contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"
11450
- },
11451
- {
11452
- partName: "/docProps/core.xml",
11453
- contentType: "application/vnd.openxmlformats-package.core-properties+xml"
11454
- },
11455
- {
11456
- partName: "/docProps/custom.xml",
11457
- contentType: "application/vnd.openxmlformats-officedocument.custom-properties+xml"
11458
- },
11459
- {
11460
- partName: "/docProps/app.xml",
11461
- contentType: "application/vnd.openxmlformats-officedocument.extended-properties+xml"
11462
- },
11463
- {
11464
- partName: "/word/numbering.xml",
11465
- contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"
11466
- },
11467
- {
11468
- partName: "/word/footnotes.xml",
11469
- contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"
11470
- },
11471
- {
11472
- partName: "/word/endnotes.xml",
11473
- contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml"
11474
- },
11475
- {
11476
- partName: "/word/settings.xml",
11477
- contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"
11478
- },
11479
- ...extras.hasComments ? [{
11480
- partName: "/word/comments.xml",
11481
- contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml"
11482
- }] : [],
11483
- {
11484
- partName: "/word/fontTable.xml",
11485
- contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"
11783
+ /** Default content types for altChunk part extensions. */
11784
+ const ALTCHUNK_DEFAULTS = {
11785
+ html: "text/html",
11786
+ rtf: "application/rtf",
11787
+ txt: "text/plain"
11788
+ };
11789
+ /**
11790
+ * Realign [Content_Types] Overrides for altChunk parts on a round-tripped
11791
+ * package. The pass-through content types carry Override PartNames from the
11792
+ * source, but the compiler regenerates altChunk part paths (uniqueId), so the
11793
+ * Override and the written part drift apart (O5/O6). This drops the stale
11794
+ * afchunk Overrides and appends ones matching the freshly generated paths,
11795
+ * backfilling the extension Default so the part is resolvable either way.
11796
+ */
11797
+ function withAltChunkOverrides(input, altChunks) {
11798
+ const defaults = [...input.defaults];
11799
+ const haveExt = new Set(defaults.map((d) => d.extension));
11800
+ for (const ac of altChunks) {
11801
+ const ext = (ac.path.split(".").pop() ?? "").toLowerCase();
11802
+ if (ext && !haveExt.has(ext) && ALTCHUNK_DEFAULTS[ext]) {
11803
+ defaults.push({
11804
+ extension: ext,
11805
+ contentType: ALTCHUNK_DEFAULTS[ext]
11806
+ });
11807
+ haveExt.add(ext);
11486
11808
  }
11487
- ];
11488
- for (let i = 1; i <= (extras.headerCount ?? 0); i++) overrides.push({
11489
- partName: `/word/header${i}.xml`,
11490
- contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml"
11491
- });
11492
- for (let i = 1; i <= (extras.footerCount ?? 0); i++) overrides.push({
11493
- partName: `/word/footer${i}.xml`,
11494
- contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml"
11495
- });
11496
- for (let i = 1; i <= (extras.chartCount ?? 0); i++) overrides.push({
11497
- partName: `/word/charts/chart${i}.xml`,
11498
- contentType: "application/vnd.openxmlformats-officedocument.drawingml.chart+xml"
11499
- });
11500
- for (let i = 1; i <= (extras.smartArtCount ?? 0); i++) {
11501
- overrides.push({
11502
- partName: `/word/diagrams/data${i}.xml`,
11503
- contentType: "application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml"
11504
- });
11505
- overrides.push({
11506
- partName: `/word/diagrams/layout${i}.xml`,
11507
- contentType: "application/vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml"
11508
- });
11509
- overrides.push({
11510
- partName: `/word/diagrams/quickStyle${i}.xml`,
11511
- contentType: "application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml"
11512
- });
11513
- overrides.push({
11514
- partName: `/word/diagrams/colors${i}.xml`,
11515
- contentType: "application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml"
11516
- });
11809
+ }
11810
+ const overrides = input.overrides.filter((o) => !o.partName.startsWith("/word/afchunks/"));
11811
+ for (const ac of altChunks) {
11812
+ const partName = ac.path.startsWith("/") ? ac.path : `/${ac.path}`;
11517
11813
  overrides.push({
11518
- partName: `/word/diagrams/drawing${i}.xml`,
11519
- contentType: "application/vnd.ms-office.drawingml.diagramDrawing+xml"
11814
+ partName,
11815
+ contentType: ac.contentType
11520
11816
  });
11521
11817
  }
11522
- if (extras.hasBibliography) overrides.push({
11523
- partName: "/word/bibliography.xml",
11524
- contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.bibliography+xml"
11525
- });
11526
- if (extras.hasGlossary) overrides.push({
11527
- partName: "/word/glossary/document.xml",
11528
- contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.glossary+xml"
11529
- });
11530
- if (extras.hasWebSettings) overrides.push({
11531
- partName: "/word/webSettings.xml",
11532
- contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml"
11533
- });
11534
- for (const ac of extras.altChunks ?? []) overrides.push({
11818
+ return {
11819
+ defaults,
11820
+ overrides
11821
+ };
11822
+ }
11823
+ /**
11824
+ * Build [Content_Types].xml for a fresh DOCX compile, driven by the part
11825
+ * registry. Static parts (document/styles/…/comments/headers/…) come from
11826
+ * {@link buildContentTypeOverrides} over {@link DOCX_PARTS}; dynamic parts whose
11827
+ * path or count is runtime-determined (altChunks, sub-documents) are appended
11828
+ * here — they are not enumerable in the registry.
11829
+ *
11830
+ * `facts` keys mirror the registry's `flag` / `countFrom` tokens. The Override
11831
+ * set (order-independent) matches the former hand-written builder, so the OPC
11832
+ * consistency validator stays green.
11833
+ */
11834
+ function buildContentTypesFromRegistry(facts, dynamic = {}) {
11835
+ const overrides = buildContentTypeOverrides(DOCX_PARTS, facts);
11836
+ for (const ac of dynamic.altChunks ?? []) overrides.push({
11535
11837
  partName: ac.path.startsWith("/") ? ac.path : `/${ac.path}`,
11536
11838
  contentType: ac.contentType
11537
11839
  });
11538
- for (const sd of extras.subDocs ?? []) overrides.push({
11840
+ for (const sd of dynamic.subDocs ?? []) overrides.push({
11539
11841
  partName: sd.path.startsWith("/") ? sd.path : `/${sd.path}`,
11540
11842
  contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"
11541
11843
  });
11542
11844
  return {
11543
- defaults,
11845
+ defaults: [...STANDARD_DEFAULTS],
11544
11846
  overrides
11545
11847
  };
11546
11848
  }
@@ -11585,16 +11887,16 @@ const corePropertiesDesc = {
11585
11887
  stringify(opts, _ctx) {
11586
11888
  const now = (/* @__PURE__ */ new Date()).toISOString();
11587
11889
  const p = ["<cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:dcmitype=\"http://purl.org/dc/dcmitype/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"];
11588
- if (opts.title) p.push(`<dc:title>${escapeXml(opts.title)}</dc:title>`);
11589
- if (opts.subject) p.push(`<dc:subject>${escapeXml(opts.subject)}</dc:subject>`);
11890
+ p.push(`<dcterms:created xsi:type="dcterms:W3CDTF">${opts.created ?? now}</dcterms:created>`);
11590
11891
  if (opts.creator) p.push(`<dc:creator>${escapeXml(opts.creator)}</dc:creator>`);
11591
- if (opts.keywords) p.push(`<cp:keywords>${escapeXml(opts.keywords)}</cp:keywords>`);
11592
11892
  if (opts.description) p.push(`<dc:description>${escapeXml(opts.description)}</dc:description>`);
11893
+ if (opts.keywords) p.push(`<cp:keywords>${escapeXml(opts.keywords)}</cp:keywords>`);
11593
11894
  if (opts.lastModifiedBy) p.push(`<cp:lastModifiedBy>${escapeXml(opts.lastModifiedBy)}</cp:lastModifiedBy>`);
11594
- if (opts.revision !== void 0) p.push(`<cp:revision>${opts.revision}</cp:revision>`);
11595
11895
  if (opts.lastPrinted) p.push(`<cp:lastPrinted>${escapeXml(opts.lastPrinted)}</cp:lastPrinted>`);
11596
- p.push(`<dcterms:created xsi:type="dcterms:W3CDTF">${now}</dcterms:created>`);
11597
- p.push(`<dcterms:modified xsi:type="dcterms:W3CDTF">${now}</dcterms:modified>`);
11896
+ p.push(`<dcterms:modified xsi:type="dcterms:W3CDTF">${opts.modified ?? now}</dcterms:modified>`);
11897
+ if (opts.revision !== void 0) p.push(`<cp:revision>${opts.revision}</cp:revision>`);
11898
+ if (opts.subject) p.push(`<dc:subject>${escapeXml(opts.subject)}</dc:subject>`);
11899
+ if (opts.title) p.push(`<dc:title>${escapeXml(opts.title)}</dc:title>`);
11598
11900
  p.push("</cp:coreProperties>");
11599
11901
  return p.join("");
11600
11902
  },
@@ -11629,143 +11931,11 @@ const corePropertiesDesc = {
11629
11931
  case "cp:lastPrinted":
11630
11932
  result.lastPrinted = text;
11631
11933
  break;
11632
- }
11633
- }
11634
- return result;
11635
- }
11636
- };
11637
- //#endregion
11638
- //#region src/parts/custom-properties.ts
11639
- const customPropertiesDesc = {
11640
- kind: "custom",
11641
- stringify(opts, _ctx) {
11642
- const p = ["<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/custom-properties\" xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\">"];
11643
- let pid = 2;
11644
- for (const prop of opts.properties) {
11645
- p.push(`<property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="${pid}" name="${escapeXml(prop.name)}"><vt:lpwstr>${escapeXml(prop.value)}</vt:lpwstr></property>`);
11646
- pid++;
11647
- }
11648
- p.push("</Properties>");
11649
- return p.join("");
11650
- },
11651
- parse(el, _ctx) {
11652
- const properties = [];
11653
- for (const child of el.elements ?? []) {
11654
- if (child.name !== "property") continue;
11655
- const name = attr(child, "name");
11656
- if (!name) continue;
11657
- const valueEl = child.elements?.find((e) => e.name?.startsWith("vt:"));
11658
- const value = valueEl ? textOf(valueEl) ?? "" : "";
11659
- properties.push({
11660
- name,
11661
- value
11662
- });
11663
- }
11664
- return { properties };
11665
- }
11666
- };
11667
- //#endregion
11668
- //#region src/parts/app-properties.ts
11669
- const appPropertiesDesc = {
11670
- kind: "custom",
11671
- stringify(opts, _ctx) {
11672
- const p = ["<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\" xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\">"];
11673
- if (opts.template !== void 0) p.push(`<Template>${escapeXml(opts.template)}</Template>`);
11674
- if (opts.manager !== void 0) p.push(`<Manager>${escapeXml(opts.manager)}</Manager>`);
11675
- if (opts.company !== void 0) p.push(`<Company>${escapeXml(opts.company)}</Company>`);
11676
- if (opts.pages !== void 0) p.push(`<Pages>${opts.pages}</Pages>`);
11677
- if (opts.words !== void 0) p.push(`<Words>${opts.words}</Words>`);
11678
- if (opts.characters !== void 0) p.push(`<Characters>${opts.characters}</Characters>`);
11679
- if (opts.lines !== void 0) p.push(`<Lines>${opts.lines}</Lines>`);
11680
- if (opts.paragraphs !== void 0) p.push(`<Paragraphs>${opts.paragraphs}</Paragraphs>`);
11681
- if (opts.slides !== void 0) p.push(`<Slides>${opts.slides}</Slides>`);
11682
- if (opts.notes !== void 0) p.push(`<Notes>${opts.notes}</Notes>`);
11683
- if (opts.totalTime !== void 0) p.push(`<TotalTime>${opts.totalTime}</TotalTime>`);
11684
- if (opts.hiddenSlides !== void 0) p.push(`<HiddenSlides>${opts.hiddenSlides}</HiddenSlides>`);
11685
- if (opts.mmClips !== void 0) p.push(`<MMClips>${opts.mmClips}</MMClips>`);
11686
- if (opts.scaleCrop !== void 0) p.push(`<ScaleCrop>${opts.scaleCrop ? 1 : 0}</ScaleCrop>`);
11687
- if (opts.linksUpToDate !== void 0) p.push(`<LinksUpToDate>${opts.linksUpToDate ? 1 : 0}</LinksUpToDate>`);
11688
- if (opts.charactersWithSpaces !== void 0) p.push(`<CharactersWithSpaces>${opts.charactersWithSpaces}</CharactersWithSpaces>`);
11689
- if (opts.sharedDoc !== void 0) p.push(`<SharedDoc>${opts.sharedDoc ? 1 : 0}</SharedDoc>`);
11690
- if (opts.hyperlinkBase !== void 0) p.push(`<HyperlinkBase>${escapeXml(opts.hyperlinkBase)}</HyperlinkBase>`);
11691
- if (opts.hyperlinksChanged !== void 0) p.push(`<HyperlinksChanged>${opts.hyperlinksChanged ? 1 : 0}</HyperlinksChanged>`);
11692
- if (opts.application !== void 0) p.push(`<Application>${escapeXml(opts.application)}</Application>`);
11693
- if (opts.appVersion !== void 0) p.push(`<AppVersion>${escapeXml(opts.appVersion)}</AppVersion>`);
11694
- if (opts.docSecurity !== void 0) p.push(`<DocSecurity>${opts.docSecurity}</DocSecurity>`);
11695
- p.push("</Properties>");
11696
- return p.join("");
11697
- },
11698
- parse(el, _ctx) {
11699
- const result = {};
11700
- for (const child of el.elements ?? []) {
11701
- if (typeof child.name !== "string") continue;
11702
- const text = child.elements?.[0]?.text;
11703
- switch (child.name) {
11704
- case "Template":
11705
- if (typeof text === "string") result.template = text;
11706
- break;
11707
- case "Manager":
11708
- if (typeof text === "string") result.manager = text;
11709
- break;
11710
- case "Company":
11711
- if (typeof text === "string") result.company = text;
11712
- break;
11713
- case "Pages":
11714
- if (typeof text === "string") result.pages = Number(text);
11715
- break;
11716
- case "Words":
11717
- if (typeof text === "string") result.words = Number(text);
11718
- break;
11719
- case "Characters":
11720
- if (typeof text === "string") result.characters = Number(text);
11721
- break;
11722
- case "Lines":
11723
- if (typeof text === "string") result.lines = Number(text);
11724
- break;
11725
- case "Paragraphs":
11726
- if (typeof text === "string") result.paragraphs = Number(text);
11727
- break;
11728
- case "Slides":
11729
- if (typeof text === "string") result.slides = Number(text);
11730
- break;
11731
- case "Notes":
11732
- if (typeof text === "string") result.notes = Number(text);
11733
- break;
11734
- case "TotalTime":
11735
- if (typeof text === "string") result.totalTime = Number(text);
11736
- break;
11737
- case "HiddenSlides":
11738
- if (typeof text === "string") result.hiddenSlides = Number(text);
11739
- break;
11740
- case "MMClips":
11741
- if (typeof text === "string") result.mmClips = Number(text);
11742
- break;
11743
- case "ScaleCrop":
11744
- if (typeof text === "string") result.scaleCrop = text === "1" || text === "true";
11745
- break;
11746
- case "LinksUpToDate":
11747
- if (typeof text === "string") result.linksUpToDate = text === "1" || text === "true";
11748
- break;
11749
- case "CharactersWithSpaces":
11750
- if (typeof text === "string") result.charactersWithSpaces = Number(text);
11751
- break;
11752
- case "SharedDoc":
11753
- if (typeof text === "string") result.sharedDoc = text === "1" || text === "true";
11754
- break;
11755
- case "HyperlinkBase":
11756
- if (typeof text === "string") result.hyperlinkBase = text;
11757
- break;
11758
- case "HyperlinksChanged":
11759
- if (typeof text === "string") result.hyperlinksChanged = text === "1" || text === "true";
11760
- break;
11761
- case "Application":
11762
- if (typeof text === "string") result.application = text;
11763
- break;
11764
- case "AppVersion":
11765
- if (typeof text === "string") result.appVersion = text;
11934
+ case "dcterms:created":
11935
+ result.created = text;
11766
11936
  break;
11767
- case "DocSecurity":
11768
- if (typeof text === "string") result.docSecurity = Number(text);
11937
+ case "dcterms:modified":
11938
+ result.modified = text;
11769
11939
  break;
11770
11940
  }
11771
11941
  }
@@ -12039,7 +12209,7 @@ const webSettingsDesc = {
12039
12209
  if (opts.doNotOrganizeInFolder !== void 0) p.push(wsOnOff("w:doNotOrganizeInFolder", opts.doNotOrganizeInFolder));
12040
12210
  if (opts.doNotUseLongFileNames !== void 0) p.push(wsOnOff("w:doNotUseLongFileNames", opts.doNotUseLongFileNames));
12041
12211
  if (opts.pixelsPerInch !== void 0) p.push(wsNumVal("w:pixelsPerInch", opts.pixelsPerInch));
12042
- if (opts.targetScreenSz !== void 0) p.push(wsStringVal("w:targetScreenSz", opts.targetScreenSz));
12212
+ if (opts.targetScreenSize !== void 0) p.push(wsStringVal("w:targetScreenSz", opts.targetScreenSize));
12043
12213
  if (opts.saveSmartTagsAsXml !== void 0) p.push(wsOnOff("w:saveSmartTagsAsXml", opts.saveSmartTagsAsXml));
12044
12214
  p.push("</w:webSettings>");
12045
12215
  return p.join("");
@@ -12076,15 +12246,15 @@ const webSettingsDesc = {
12076
12246
  const val = attrNum(ppi, "w:val");
12077
12247
  if (val !== void 0) opts.pixelsPerInch = val;
12078
12248
  }
12079
- const targetSz = findChild(el, "w:targetScreenSz");
12080
- if (targetSz) {
12081
- const val = attr(targetSz, "w:val");
12082
- if (val) opts.targetScreenSz = val;
12249
+ const targetScreenSize = findChild(el, "w:targetScreenSz");
12250
+ if (targetScreenSize) {
12251
+ const val = attr(targetScreenSize, "w:val");
12252
+ if (val) opts.targetScreenSize = val;
12083
12253
  }
12084
12254
  return opts;
12085
12255
  }
12086
12256
  };
12087
12257
  //#endregion
12088
- export { stringifyChildDispatch as $, TableAnchorType as $t, buildStyleCache as A, AlignmentType as An, VerticalPositionAlign as At, createPageMargin as B, setBodyParseChild as Bt, parseToc as C, HighlightColor as Cn, createVerticalPosition as Ct, settingsDesc as D, TextboxTightWrapType as Dn, HorizontalPositionAlign as Dt, StyleLevel as E, TextAlignmentType as En, VerticalPositionRelativeFrom as Et, createHeaderFooterReference as F, altChunkDesc as Ft, createDocumentGrid as G, stringifyElement as Gt, PageBorderOffsetFrom as H, stringifySdtPr as Ht, SectionType as I, checkboxSymbolRunInner as It, parseNumberingDefinitions as J, BorderStyle as Jt, DocumentAttributeNamespaces as K, WidthType as Kt, createSectionType as L, customXmlBlockDesc as Lt, DefaultStylesFactory as M, createWrapTight as Mt, HeaderFooterReferenceType as N, TextWrappingSide as Nt, Styles as O, HeadingLevel as On, NumberFormat as Ot, HeaderFooterType as P, TextWrappingType as Pt, tableDesc as Q, RelativeVerticalPosition as Qt, LineNumberRestartFormat as R, parseCustomXmlPr as Rt, footnotesDesc as S, createTransformation as Sn, createPageNumberType as St, SdtLock as T, PageNumber as Tn, HorizontalPositionRelativeFrom as Tt, PageBorderZOrder as U, stringifySdtShell as Ut, PageBorderDisplay as V, stringifyCustomXmlShell as Vt, DocumentGridType as W, subDocDesc as Wt, LevelSuffix as X, OverlapType as Xt, LevelFormat as Y, TableLayoutType as Yt, setTableParseChild as Z, RelativeHorizontalPosition as Zt, bibliographyDesc as _, createBodyProperties as _n, sectionPageSizeDefaults as _t, appPropertiesDesc as a, parseFormFieldData as an, parseParagraphProperties as at, EditGroupType as b, WORKAROUND2 as bn, createPageSize as bt, relationshipsDesc as c, PositionalTabLeader as cn, replaceRelsWithPlaceholders as ct, withMediaDefaults as d, UnderlineType as dn, parseSdtProperties as dt, TextDirection as en, stringifyParagraphInline as et, commentsDesc as f, TextBodyWrappingType as fn, FontWrapper as ft, glossaryDesc as g, VerticalAnchor as gn, sectionMarginDefaults as gt, DocPartType as h, TextVerticalType as hn, stringifySectionPropertiesXml as ht, webSettingsDesc as i, createFormFieldData as in, parseParagraph as it, parseStyleDefinitions as j, createWrapThrough as jt, buildNumberingCache as k, LineRuleType as kn, SpaceType as kt, buildContentTypes as l, PositionalTabRelativeTo as ln, stringifyTableOfContents as lt, DocPartGallery as m, TextVertOverflowType as mn, sectionPropertiesDesc as mt, frameXml as n, ProofErrorType as nn, drawingDesc as nt, customPropertiesDesc as o, RubyAlign as on, stringifyBodyChild as ot, DocPartBehavior as p, TextHorzOverflowType as pn, parseSectionPropertiesEl as pt, Numbering as q, TABLE_BORDERS_NONE as qt, framesetXml as r, FormFieldTextType as rn, resetDrawingIdGen as rt, corePropertiesDesc as s, PositionalTabAlignment as sn, stringifyDocumentXml as st, TargetScreenSize as t, VerticalMergeType as tn, stringifyRunInline as tt, contentTypesDesc as u, EmphasisMarkType as un, parseSdtBlock as ut, fontTableDesc as v, parseBodyProperties as vn, PageTextDirectionType as vt, SdtDateMappingType as w, TextEffect as wn, createHorizontalPosition as wt, endnotesDesc as x, Media as xn, PageNumberSeparator as xt, CharacterSet as y, createImageData$1 as yn, PageOrientation as yt, createLineNumberType as z, sdtBlockDesc as zt };
12258
+ export { LevelSuffix as $, OverlapType as $t, buildNumberingCache as A, TextboxTightWrapType as An, HorizontalPositionAlign as At, createSectionType as B, customXmlBlockDesc as Bt, footnotesDesc as C, WORKAROUND2 as Cn, createPageSize as Ct, StyleLevel as D, TextEffect as Dn, createHorizontalPosition as Dt, SdtLock as E, HighlightColor as En, createVerticalPosition as Et, collectDefaultOverrideIds as F, createWrapTight as Ft, PageBorderOffsetFrom as G, stringifySdtPr as Gt, createLineNumberType as H, sdtBlockDesc as Ht, HeaderFooterReferenceType as I, TextWrappingSide as It, createDocumentGrid as J, stringifyElement as Jt, PageBorderZOrder as K, stringifySdtShell as Kt, HeaderFooterType as L, TextWrappingType as Lt, extractStyleId as M, LineRuleType as Mn, SpaceType as Mt, parseStyleDefinitions as N, AlignmentType as Nn, VerticalPositionAlign as Nt, settingsDesc as O, PageNumber as On, HorizontalPositionRelativeFrom as Ot, DefaultStylesFactory as P, createWrapThrough as Pt, LevelFormat as Q, TableLayoutType as Qt, createHeaderFooterReference as R, altChunkDesc as Rt, endnotesDesc as S, createImageData$1 as Sn, PageOrientation as St, SdtDateMappingType as T, createTransformation as Tn, createPageNumberType as Tt, createPageMargin as U, setBodyParseChild as Ut, LineNumberRestartFormat as V, parseCustomXmlProperties as Vt, PageBorderDisplay as W, stringifyCustomXmlShell as Wt, Numbering as X, TABLE_BORDERS_NONE as Xt, DocumentAttributeNamespaces as Y, WidthType as Yt, parseNumberingDefinitions as Z, BorderStyle as Zt, glossaryDesc as _, TextVertOverflowType as _n, sectionPropertiesDesc as _t, appPropertiesDesc as a, ProofErrorType as an, drawingDesc as at, CharacterSet as b, createBodyProperties as bn, sectionPageSizeDefaults as bt, relationshipsDesc as c, parseFormFieldData as cn, parseParagraphProperties as ct, withAltChunkOverrides as d, PositionalTabLeader as dn, replaceRelsWithPlaceholders as dt, RelativeHorizontalPosition as en, setTableParseChild as et, withMediaDefaults as f, PositionalTabRelativeTo as fn, stringifyTableOfContents as ft, DocPartType as g, TextHorzOverflowType as gn, parseSectionPropertiesEl as gt, DocPartGallery as h, TextBodyWrappingType as hn, FontWrapper as ht, webSettingsDesc as i, VerticalMergeType as in, stringifyRunInline as it, buildStyleCache as j, HeadingLevel as jn, NumberFormat as jt, Styles as k, TextAlignmentType as kn, VerticalPositionRelativeFrom as kt, buildContentTypesFromRegistry as l, RubyAlign as ln, stringifyBodyChild as lt, DocPartBehavior as m, UnderlineType as mn, parseSdtProperties as mt, frameXml as n, TableAnchorType as nn, stringifyChildDispatch as nt, customPropertiesDesc as o, FormFieldTextType as on, resetDrawingIdGen as ot, commentsDesc as p, EmphasisMarkType as pn, parseSdtBlock as pt, DocumentGridType as q, subDocDesc as qt, framesetXml as r, TextDirection as rn, stringifyParagraphInline as rt, corePropertiesDesc as s, createFormFieldData as sn, parseParagraph as st, TargetScreenSize as t, RelativeVerticalPosition as tn, tableDesc as tt, contentTypesDesc as u, PositionalTabAlignment as un, stringifyDocumentXml as ut, bibliographyDesc as v, TextVerticalType as vn, stringifySectionPropertiesXml as vt, parseToc as w, Media as wn, PageNumberSeparator as wt, EditGroupType as x, parseBodyProperties as xn, PageTextDirectionType as xt, fontTableDesc as y, VerticalAnchor as yn, sectionMarginDefaults as yt, SectionType as z, checkboxSymbolRunInner as zt };
12089
12259
 
12090
- //# sourceMappingURL=parts-BQBGNSGm.mjs.map
12260
+ //# sourceMappingURL=parts-BWmkYaBr.mjs.map