@office-open/pptx 0.6.2 → 0.6.4

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.
package/dist/index.mjs CHANGED
@@ -1,9 +1,10 @@
1
1
  import { i as __toCommonJS, n as __exportAll, r as __reExport, t as __esmMin } from "./chunk-090QGkrx.mjs";
2
- import { AppProperties, BaseXmlComponent, BuilderElement, EmptyElement, Formatter, ImportedXmlComponent, NextAttributeComponent, OoxmlMimeType, PrettifyType, Relationships, XmlComponent, ZIP_STORED_LEVEL, addSmartArtRelationships, buildCorePropertiesXml, collectPlaceholderKeys, convertEmuToInches, convertEmuToPixels, convertEmuToPixels as convertEmuToPixels$1, convertEmuToPoints, convertInchesToEmu, convertPixelsToEmu, convertPixelsToEmu as convertPixelsToEmu$1, convertPointsToEmu, createPacker, escapeRegex, formatId, getReferencedMedia, hasPlaceholders, hashedId, parseArchive, parseCorePropsElement, replaceChartPlaceholders, replaceImagePlaceholders, replaceSmartArtPlaceholders, stringContainerObj, uniqueId, uniqueNumericIdCreator, uniqueUuid } from "@office-open/core";
2
+ import { AppProperties, BaseXmlComponent, BuilderElement, EmptyElement, Formatter, ImportedXmlComponent, NextAttributeComponent, OoxmlMimeType, PrettifyType, Relationships, XmlComponent, ZIP_STORED_LEVEL, addSmartArtRelationships, buildCorePropertiesXml, collectPlaceholderKeys, convertEmuToInches, convertEmuToPixels, convertEmuToPixels as convertEmuToPixels$1, convertEmuToPoints, convertInchesToEmu, convertPixelsToEmu, convertPixelsToEmu as convertPixelsToEmu$1, convertPointsToEmu, createPacker, escapeRegex, formatId, getReferencedMedia, hasPlaceholders, hashedId, parseArchive, parseCorePropsElement, replaceChartPlaceholders, replaceImagePlaceholders, replaceSmartArtPlaceholders, stringContainerObj, uniqueId, uniqueNumericIdCreator, uniqueUuid, xsdRectAlignment, xsdStrikeStyle, xsdTextAlign, xsdTextAnchor, xsdTextCaps, xsdUnderlineStyle } from "@office-open/core";
3
3
  import { BevelPresetType, CompoundLine, LineCap, LineJoin, PathShadeType, PenAlignment, PresetDash, PresetGeometry, PresetMaterialType, Stretch, TileFlipMode, buildFill, createBevel, createBlip, createBottomBevel, createColorElement, createColorTransforms, createEffectList, createEffectList as createEffectList$1, createGradientFill, createGradientStop, createGroupTransform2D, createOutline, createOutline as createOutline$1, createScene3D, createScene3D as createScene3D$1, createShape3D, createShape3D as createShape3D$1, createTransform2D, extractBlipFillMedia } from "@office-open/core/drawingml";
4
4
  import { ChartCollection, ChartSpace } from "@office-open/core/chart";
5
5
  import { DEFAULT_DRAWING_XML, SmartArtCollection, createDataModel, getColorXml, getLayoutXml, getStyleXml } from "@office-open/core/smartart";
6
- import { attr, attrBool, attrNum, children, findChild, findDeep, textOf, xml } from "@office-open/xml";
6
+ import { attr, attrBool, attrNum, children, colorAttr, findChild, findDeep, textOf, xml } from "@office-open/xml";
7
+ import { toUint8Array } from "undio";
7
8
  export * from "@office-open/core/values";
8
9
  //#region src/file/drawingml/effects.ts
9
10
  /** Convert PPTX simple color to core SolidFillOptions. */
@@ -58,7 +59,7 @@ function toReflection(opts) {
58
59
  if (opts.scaleY !== void 0) result.scaleY = opts.scaleY * 1e3;
59
60
  if (opts.skewX !== void 0) result.skewX = opts.skewX * 6e4;
60
61
  if (opts.skewY !== void 0) result.skewY = opts.skewY * 6e4;
61
- if (opts.alignment !== void 0) result.alignment = ReflectionAlignment[opts.alignment];
62
+ if (opts.alignment !== void 0) result.alignment = xsdRectAlignment.to(opts.alignment);
62
63
  if (opts.rotateWithShape === false) result.rotWithShape = 0;
63
64
  return result;
64
65
  }
@@ -117,15 +118,15 @@ function createPptxEffectList(options) {
117
118
  var ReflectionAlignment;
118
119
  var init_effects = __esmMin((() => {
119
120
  ReflectionAlignment = {
120
- TOP_LEFT: "tl",
121
- TOP: "t",
122
- TOP_RIGHT: "tr",
123
- LEFT: "l",
124
- CENTER: "ctr",
125
- RIGHT: "r",
126
- BOTTOM_LEFT: "bl",
127
- BOTTOM: "b",
128
- BOTTOM_RIGHT: "br"
121
+ TOP_LEFT: "topLeft",
122
+ TOP: "top",
123
+ TOP_RIGHT: "topRight",
124
+ LEFT: "left",
125
+ CENTER: "center",
126
+ RIGHT: "right",
127
+ BOTTOM_LEFT: "bottomLeft",
128
+ BOTTOM: "bottom",
129
+ BOTTOM_RIGHT: "bottomRight"
129
130
  };
130
131
  }));
131
132
  //#endregion
@@ -491,7 +492,7 @@ var HyperlinkCollection = class {
491
492
  tooltip
492
493
  });
493
494
  }
494
- get Array() {
495
+ get array() {
495
496
  return [...this.map.values()];
496
497
  }
497
498
  };
@@ -525,7 +526,7 @@ var Media = class {
525
526
  addMedia(key, mediaData) {
526
527
  this.map.set(key, mediaData);
527
528
  }
528
- get Array() {
529
+ get array() {
529
530
  return [...this.map.values()];
530
531
  }
531
532
  };
@@ -616,10 +617,10 @@ var EndParagraphRunProperties = class extends BuilderElement {
616
617
  //#region src/file/shape/paragraph/paragraph-properties.ts
617
618
  init_xml_components();
618
619
  const TextAlignment = {
619
- LEFT: "l",
620
- CENTER: "ctr",
621
- RIGHT: "r",
622
- JUSTIFY: "just"
620
+ LEFT: "left",
621
+ CENTER: "center",
622
+ RIGHT: "right",
623
+ JUSTIFY: "justify"
623
624
  };
624
625
  function buildBulletChildren(options) {
625
626
  const children = [];
@@ -650,7 +651,7 @@ function buildBulletChildren(options) {
650
651
  function buildParagraphProperties(options) {
651
652
  const children = [];
652
653
  const attrs = {};
653
- if (options.alignment) attrs.algn = TextAlignment[options.alignment];
654
+ if (options.alignment) attrs.algn = xsdTextAlign.to(options.alignment);
654
655
  if (options.indentLevel !== void 0) attrs.lvl = options.indentLevel;
655
656
  if (options.marginIndent !== void 0) attrs.marL = options.marginIndent;
656
657
  if (options.marginRight !== void 0) attrs.marR = options.marginRight;
@@ -685,8 +686,8 @@ init_fill();
685
686
  init_xml_components();
686
687
  let nextHyperlinkId = 1;
687
688
  const UnderlineStyle = {
688
- SINGLE: "sng",
689
- DOUBLE: "dbl",
689
+ SINGLE: "single",
690
+ DOUBLE: "double",
690
691
  NONE: "none"
691
692
  };
692
693
  const StrikeStyle = {
@@ -710,11 +711,11 @@ function buildRunProperties(options, hyperlinkKey, fillObject, effectListObject,
710
711
  if (options.fontSize) attrs.sz = options.fontSize * 100;
711
712
  if (options.bold !== void 0) attrs.b = options.bold;
712
713
  if (options.italic !== void 0) attrs.i = options.italic;
713
- if (options.underline) attrs.u = UnderlineStyle[options.underline];
714
+ if (options.underline) attrs.u = xsdUnderlineStyle.to(options.underline);
714
715
  if (options.lang) attrs.lang = options.lang;
715
- if (options.strike) attrs.strike = StrikeStyle[options.strike];
716
+ if (options.strike) attrs.strike = xsdStrikeStyle.to(options.strike);
716
717
  if (options.baseline !== void 0) attrs.baseline = options.baseline;
717
- if (options.capitalization) attrs.cap = TextCapitalization[options.capitalization] ?? options.capitalization;
718
+ if (options.capitalization) attrs.cap = xsdTextCaps.to(options.capitalization);
718
719
  if (options.spacing !== void 0) attrs.spc = options.spacing;
719
720
  if (options.noProof !== void 0) attrs.noProof = options.noProof;
720
721
  if (options.dirty !== void 0) attrs.dirty = options.dirty;
@@ -753,7 +754,7 @@ var RunProperties = class extends XmlComponent {
753
754
  let hyperlinkKey;
754
755
  if (opts.hyperlink) {
755
756
  hyperlinkKey = `hlink_${nextHyperlinkId++}`;
756
- context.fileData?.Hyperlinks?.addHyperlink(hyperlinkKey, opts.hyperlink.url, opts.hyperlink.tooltip);
757
+ context.fileData?.hyperlinks?.addHyperlink(hyperlinkKey, opts.hyperlink.url, opts.hyperlink.tooltip);
757
758
  }
758
759
  let fillObj;
759
760
  if (opts.fill !== void 0) fillObj = buildFill(opts.fill).prepForXml(context) ?? void 0;
@@ -871,9 +872,9 @@ var TableCellProperties = class extends BaseXmlComponent {
871
872
  //#region src/file/table/table-cell.ts
872
873
  init_xml_components();
873
874
  const VerticalAlignment = {
874
- TOP: "t",
875
- CENTER: "ctr",
876
- BOTTOM: "b"
875
+ TOP: "top",
876
+ CENTER: "center",
877
+ BOTTOM: "bottom"
877
878
  };
878
879
  /**
879
880
  * a:tc — Table cell with text body and properties.
@@ -915,7 +916,7 @@ var TableCell = class extends BaseXmlComponent {
915
916
  const tcPrObj = new TableCellProperties({
916
917
  fill: opts.fill,
917
918
  borders: opts.borders,
918
- verticalAlign: opts.verticalAlign ? VerticalAlignment[opts.verticalAlign] : void 0
919
+ verticalAlign: opts.verticalAlign ? xsdTextAnchor.to(opts.verticalAlign) : void 0
919
920
  }).prepForXml(context);
920
921
  if (tcPrObj) children.push(tcPrObj);
921
922
  return { "a:tc": children };
@@ -935,7 +936,7 @@ function buildBodyPr(options) {
935
936
  const bodyPrContent = [];
936
937
  const attrs = {};
937
938
  if (options.vertical) attrs.vert = options.vertical;
938
- if (options.anchor) attrs.anchor = VerticalAlignment[options.anchor];
939
+ if (options.anchor) attrs.anchor = xsdTextAnchor.to(options.anchor);
939
940
  if (options.wrap) attrs.wrap = options.wrap;
940
941
  if (options.margins?.top !== void 0) attrs.tIns = options.margins.top;
941
942
  if (options.margins?.bottom !== void 0) attrs.bIns = options.margins.bottom;
@@ -961,11 +962,14 @@ var TextBody = class extends XmlComponent {
961
962
  const children = [];
962
963
  children.push(buildBodyPr(this.options));
963
964
  children.push({ "a:lstStyle": {} });
964
- if (this.options.paragraphs) for (const p of this.options.paragraphs) {
965
+ if (this.options.children) for (const p of this.options.children) {
965
966
  const obj = (typeof p === "string" ? new Paragraph({ children: [new TextRun({ text: p })] }) : p instanceof Paragraph ? p : new Paragraph(p)).prepForXml(context);
966
967
  if (obj) children.push(obj);
967
968
  }
968
- else {
969
+ else if (this.options.text !== void 0) {
970
+ const obj = new Paragraph({ children: [new TextRun({ text: this.options.text })] }).prepForXml(context);
971
+ if (obj) children.push(obj);
972
+ } else {
969
973
  const obj = new Paragraph().prepForXml(context);
970
974
  if (obj) children.push(obj);
971
975
  }
@@ -1153,7 +1157,7 @@ var NotesBodyPlaceholder = class extends XmlComponent {
1153
1157
  })]
1154
1158
  })]
1155
1159
  }));
1156
- const textBodyOptions = text ? { paragraphs: [new Paragraph({ children: [new TextRun({ text })] })] } : void 0;
1160
+ const textBodyOptions = text ? { children: [new Paragraph({ children: [new TextRun({ text })] })] } : void 0;
1157
1161
  this.root.push(new TextBody(textBodyOptions));
1158
1162
  }
1159
1163
  };
@@ -1171,16 +1175,15 @@ function buildPresPropsXml(showOptions) {
1171
1175
  }
1172
1176
  var PresentationProperties = class PresentationProperties extends ImportedXmlComponent {
1173
1177
  static cache = /* @__PURE__ */ new Map();
1178
+ key;
1174
1179
  constructor(showOptions) {
1175
1180
  super("p:presentationPr");
1176
- const key = showOptions ? JSON.stringify(showOptions) : "";
1177
- if (!PresentationProperties.cache.has(key)) PresentationProperties.cache.set(key, ImportedXmlComponent.fromXmlString(buildPresPropsXml(showOptions)));
1181
+ this.key = showOptions ? JSON.stringify(showOptions) : "";
1182
+ if (!PresentationProperties.cache.has(this.key)) PresentationProperties.cache.set(this.key, ImportedXmlComponent.fromXmlString(buildPresPropsXml(showOptions)));
1178
1183
  }
1179
1184
  prepForXml() {
1180
- const key = this.showOptions ? JSON.stringify(this.showOptions) : "";
1181
- return PresentationProperties.cache.get(key).prepForXml({ stack: [] });
1185
+ return PresentationProperties.cache.get(this.key).prepForXml({ stack: [] });
1182
1186
  }
1183
- showOptions;
1184
1187
  };
1185
1188
  //#endregion
1186
1189
  //#region src/file/presentation/presentation.ts
@@ -1286,12 +1289,9 @@ var PresentationWrapper = class {
1286
1289
  this.presentation = new Presentation(options);
1287
1290
  this.relationships = new Relationships();
1288
1291
  }
1289
- get View() {
1292
+ get view() {
1290
1293
  return this.presentation;
1291
1294
  }
1292
- get Relationships() {
1293
- return this.relationships;
1294
- }
1295
1295
  };
1296
1296
  //#endregion
1297
1297
  //#region src/file/drawingml/transform-2d.ts
@@ -1367,15 +1367,12 @@ var ChartFrame = class extends XmlComponent {
1367
1367
  }
1368
1368
  prepForXml(context) {
1369
1369
  const file = context.fileData;
1370
- if (file?.Charts) file.Charts.addChart(this.chartKey, {
1370
+ if (file?.charts) file.charts.addChart(this.chartKey, {
1371
1371
  chartSpace: new ChartSpace(this.chartOptions),
1372
1372
  key: this.chartKey
1373
1373
  });
1374
1374
  return super.prepForXml(context);
1375
1375
  }
1376
- get ChartKey() {
1377
- return this.chartKey;
1378
- }
1379
1376
  };
1380
1377
  var GraphicFrameNonVisual$2 = class extends XmlComponent {
1381
1378
  constructor(id) {
@@ -1478,13 +1475,13 @@ function buildMediaData(type, fileName, width, height, data) {
1478
1475
  */
1479
1476
  var MediaFrameBase = class extends XmlComponent {
1480
1477
  shapeId;
1481
- animationOptions;
1478
+ animation;
1482
1479
  mediaData;
1483
1480
  posterData;
1484
1481
  constructor(options, id, mediaFileName, params) {
1485
1482
  super("p:pic");
1486
1483
  this.shapeId = id;
1487
- this.animationOptions = options.animation;
1484
+ this.animation = options.animation;
1488
1485
  const name = options.name ?? `Media ${id}`;
1489
1486
  const w = options.width ?? 0;
1490
1487
  const h = options.height ?? 0;
@@ -1575,16 +1572,10 @@ var MediaFrameBase = class extends XmlComponent {
1575
1572
  children: [new Transform2D({ ...emuPosition(options) }), new PresetGeometry({ preset: "rect" })]
1576
1573
  }));
1577
1574
  }
1578
- get ShapeId() {
1579
- return this.shapeId;
1580
- }
1581
- get Animation() {
1582
- return this.animationOptions;
1583
- }
1584
1575
  prepForXml(context) {
1585
1576
  const file = context.fileData;
1586
- if (this.posterData) file?.Media.addImage(this.posterData.fileName, this.posterData);
1587
- file?.Media.addMedia(this.mediaData.fileName, this.mediaData);
1577
+ if (this.posterData) file?.media.addImage(this.posterData.fileName, this.posterData);
1578
+ file?.media.addMedia(this.mediaData.fileName, this.mediaData);
1588
1579
  return super.prepForXml(context);
1589
1580
  }
1590
1581
  };
@@ -1812,7 +1803,7 @@ var Picture = class Picture extends XmlComponent {
1812
1803
  }));
1813
1804
  }
1814
1805
  prepForXml(context) {
1815
- context.fileData?.Media.addImage(this.imageData.fileName, this.imageData);
1806
+ context.fileData?.media.addImage(this.imageData.fileName, this.imageData);
1816
1807
  return super.prepForXml(context);
1817
1808
  }
1818
1809
  };
@@ -1889,28 +1880,28 @@ var NonVisualShapeProperties = class extends EmptyElement {
1889
1880
  //#endregion
1890
1881
  //#region src/file/drawingml/outline.ts
1891
1882
  const DASH_STYLE_MAP = {
1892
- solid: "SOLID",
1893
- dash: "DASH",
1894
- dashDot: "DASH_DOT",
1895
- lgDash: "LG_DASH",
1896
- sysDot: "SYS_DOT",
1897
- sysDash: "SYS_DASH"
1883
+ solid: "solid",
1884
+ dash: "dash",
1885
+ dashDot: "dashDot",
1886
+ lgDash: "lgDash",
1887
+ sysDot: "sysDot",
1888
+ sysDash: "sysDash"
1898
1889
  };
1899
1890
  const ARROWHEAD_MAP = {
1900
- triangle: "TRIANGLE",
1901
- stealth: "STEALTH",
1902
- diamond: "DIAMOND",
1903
- oval: "OVAL",
1904
- open: "ARROW"
1891
+ triangle: "triangle",
1892
+ stealth: "stealth",
1893
+ diamond: "diamond",
1894
+ oval: "oval",
1895
+ open: "arrow"
1905
1896
  };
1906
1897
  const ARROWHEAD_SIZE_MAP = {
1907
- sm: "SMALL",
1908
- med: "MEDIUM",
1909
- lg: "LARGE"
1898
+ sm: "small",
1899
+ med: "medium",
1900
+ lg: "large"
1910
1901
  };
1911
1902
  function toCoreLineEnd(type, width, length) {
1912
1903
  return {
1913
- type: ARROWHEAD_MAP[type] ?? "TRIANGLE",
1904
+ type: ARROWHEAD_MAP[type] ?? "triangle",
1914
1905
  ...width ? { width: ARROWHEAD_SIZE_MAP[width] } : {},
1915
1906
  ...length ? { length: ARROWHEAD_SIZE_MAP[length] } : {}
1916
1907
  };
@@ -1924,7 +1915,7 @@ const createOutlineCompat = (options = {}, arrowheads) => createOutline$1({
1924
1915
  type: "solidFill",
1925
1916
  color: { value: options.color.replace("#", "") }
1926
1917
  } : { type: "noFill" },
1927
- ...options.dashStyle && { dash: DASH_STYLE_MAP[options.dashStyle] ?? "SOLID" },
1918
+ ...options.dashStyle && { dash: DASH_STYLE_MAP[options.dashStyle] ?? "solid" },
1928
1919
  ...arrowheads?.endType ? { headEnd: toCoreLineEnd(arrowheads.endType, arrowheads.width, arrowheads.length) } : {},
1929
1920
  ...arrowheads?.beginType ? { tailEnd: toCoreLineEnd(arrowheads.beginType, arrowheads.width, arrowheads.length) } : {}
1930
1921
  });
@@ -2031,9 +2022,6 @@ var LineShape = class LineShape extends XmlComponent {
2031
2022
  ]
2032
2023
  }));
2033
2024
  }
2034
- get ShapeId() {
2035
- return this.shapeId;
2036
- }
2037
2025
  };
2038
2026
  /**
2039
2027
  * p:cxnSp — A connector shape on a slide (line with optional arrowheads).
@@ -2126,9 +2114,6 @@ var ConnectorShape = class ConnectorShape extends XmlComponent {
2126
2114
  children: spPrChildren
2127
2115
  }));
2128
2116
  }
2129
- get ShapeId() {
2130
- return this.shapeId;
2131
- }
2132
2117
  };
2133
2118
  //#endregion
2134
2119
  //#region src/file/drawingml/shape-properties.ts
@@ -2155,7 +2140,7 @@ var ShapeProperties = class extends BaseXmlComponent {
2155
2140
  const geomObj = new PresetGeometry({ preset: opts.geometry ?? "rect" }).prepForXml(context);
2156
2141
  if (geomObj) children.push(geomObj);
2157
2142
  const media = opts.fill ? extractBlipFillMedia(opts.fill) : void 0;
2158
- if (media) context.fileData?.Media.addImage(media.fileName, {
2143
+ if (media) context.fileData?.media.addImage(media.fileName, {
2159
2144
  data: media.data,
2160
2145
  fileName: media.fileName,
2161
2146
  type: media.type,
@@ -2225,24 +2210,18 @@ function buildPlaceholder(type, index) {
2225
2210
  var Shape = class Shape extends XmlComponent {
2226
2211
  static nextId = 2;
2227
2212
  shapeId;
2228
- animationOptions;
2213
+ animation;
2229
2214
  options;
2230
2215
  constructor(options = {}) {
2231
2216
  super("p:sp");
2232
2217
  const id = options.id ?? Shape.nextId++;
2233
2218
  this.shapeId = id;
2234
- this.animationOptions = options.animation;
2219
+ this.animation = options.animation;
2235
2220
  this.options = {
2236
2221
  ...options,
2237
2222
  id
2238
2223
  };
2239
2224
  }
2240
- get ShapeId() {
2241
- return this.shapeId;
2242
- }
2243
- get Animation() {
2244
- return this.animationOptions;
2245
- }
2246
2225
  prepForXml(context) {
2247
2226
  const opts = this.options;
2248
2227
  const id = this.shapeId;
@@ -2268,16 +2247,7 @@ var Shape = class Shape extends XmlComponent {
2268
2247
  rotation: opts.rotation
2269
2248
  }).prepForXml(context);
2270
2249
  if (spPrObj) children.push(spPrObj);
2271
- const txBodyObj = new TextBody({
2272
- paragraphs: opts.paragraphs ?? (opts.text ? [new Paragraph({ text: opts.text })] : void 0),
2273
- vertical: opts.textVertical,
2274
- anchor: opts.textAnchor,
2275
- autoFit: opts.textAutoFit,
2276
- wrap: opts.textWrap,
2277
- margins: opts.textMargins,
2278
- columns: opts.textColumns,
2279
- columnSpacing: opts.textColumnSpacing
2280
- }).prepForXml(context);
2250
+ const txBodyObj = new TextBody(opts.textBody ?? {}).prepForXml(context);
2281
2251
  if (txBodyObj) children.push(txBodyObj);
2282
2252
  return { "p:sp": children };
2283
2253
  }
@@ -2310,7 +2280,7 @@ var SmartArtFrame = class extends XmlComponent {
2310
2280
  }
2311
2281
  prepForXml(context) {
2312
2282
  const file = context.fileData;
2313
- if (file?.SmartArts) file.SmartArts.addSmartArt(this.smartArtKey, {
2283
+ if (file?.smartArts) file.smartArts.addSmartArt(this.smartArtKey, {
2314
2284
  key: this.smartArtKey,
2315
2285
  dataModel: this.dataModel,
2316
2286
  layout: this.layoutId,
@@ -2908,8 +2878,8 @@ function buildChildrenXml(children) {
2908
2878
  }
2909
2879
  return result;
2910
2880
  }
2911
- function buildSlideMasterXml(layoutCount, headerFooter, masterOptions, slideWidth = SW_REF, masterIndex = 0) {
2912
- const hfXml = headerFooter ? `<p:hf dt="0" hdr="0" ftr="0" sldNum="0"/>` : "";
2881
+ function buildSlideMasterXml(layoutCount, _headerFooter, masterOptions, slideWidth = SW_REF, masterIndex = 0) {
2882
+ const hfXml = `<p:hf dt="0" hdr="0" ftr="0" sldNum="0"/>`;
2913
2883
  const ph = masterOptions?.placeholders ?? {};
2914
2884
  const layoutIdBase = 2147483648 + masterIndex * 12 + 1;
2915
2885
  const layoutIdEntries = [];
@@ -2944,7 +2914,7 @@ var DefaultSlideMaster = class DefaultSlideMaster extends ImportedXmlComponent {
2944
2914
  cacheKey;
2945
2915
  constructor(layoutCount = 1, headerFooter, masterOptions, slideWidth = SW_REF, masterIndex = 0) {
2946
2916
  super("p:sldMaster");
2947
- this.cacheKey = `${layoutCount}:${headerFooter ? JSON.stringify(headerFooter) : ""}:${masterOptions ? JSON.stringify(masterOptions) : ""}:${slideWidth}:${masterIndex}`;
2917
+ this.cacheKey = `${layoutCount}:${masterOptions ? JSON.stringify(masterOptions) : ""}:${slideWidth}:${masterIndex}`;
2948
2918
  if (!DefaultSlideMaster.cache.has(this.cacheKey)) DefaultSlideMaster.cache.set(this.cacheKey, ImportedXmlComponent.fromXmlString(buildSlideMasterXml(layoutCount, headerFooter, masterOptions, slideWidth, masterIndex)));
2949
2919
  }
2950
2920
  prepForXml() {
@@ -4075,14 +4045,14 @@ var Transition = class extends BaseXmlComponent {
4075
4045
  //#region src/file/slide/slide.ts
4076
4046
  init_xml_components();
4077
4047
  function isAnimatable(child) {
4078
- return "ShapeId" in child && "Animation" in child;
4048
+ return "shapeId" in child && "animation" in child;
4079
4049
  }
4080
4050
  function collectAnimations(children) {
4081
4051
  const entries = [];
4082
4052
  for (const child of children) if (isAnimatable(child)) {
4083
- const anim = child.Animation;
4053
+ const anim = child.animation;
4084
4054
  if (anim) entries.push({
4085
- spid: child.ShapeId,
4055
+ spid: child.shapeId,
4086
4056
  options: anim
4087
4057
  });
4088
4058
  }
@@ -4335,27 +4305,27 @@ var File = class {
4335
4305
  slideWidthEmus;
4336
4306
  slideHeightEmus;
4337
4307
  masterDefs;
4338
- coreProperties;
4339
- appProperties;
4340
- contentTypes;
4341
- media;
4342
- charts;
4343
- smartArts;
4344
- hyperlinks;
4345
- presentationWrapper;
4346
- tableStyles;
4347
- presProps;
4348
- viewProps;
4349
- notesMasterRels;
4308
+ _coreProperties;
4309
+ _appProperties;
4310
+ _contentTypes;
4311
+ _media;
4312
+ _charts;
4313
+ _smartArts;
4314
+ _hyperlinks;
4315
+ _presentationWrapper;
4316
+ _tableStyles;
4317
+ _presProps;
4318
+ _viewProps;
4319
+ _notesMasterRels;
4350
4320
  masterMap;
4351
- allLayouts;
4352
- allLayoutRels;
4353
- slides;
4354
- slideWrappers;
4355
- notesSlides;
4356
- commentAuthorList;
4357
- slideCommentLists;
4358
- fileRels;
4321
+ _allLayouts;
4322
+ _allLayoutRels;
4323
+ _slides;
4324
+ _slideWrappers;
4325
+ _notesSlides;
4326
+ _commentAuthorList;
4327
+ _slideCommentLists;
4328
+ _fileRels;
4359
4329
  constructor(options) {
4360
4330
  this.slideOptions = options.slides ?? [];
4361
4331
  this.corePropsOptions = options;
@@ -4443,8 +4413,8 @@ var File = class {
4443
4413
  });
4444
4414
  }
4445
4415
  this.masterMap = masters;
4446
- this.allLayouts = masters.flatMap((m) => m.layouts);
4447
- this.allLayoutRels = masters.flatMap((m) => m.layoutRels);
4416
+ this._allLayouts = masters.flatMap((m) => m.layouts);
4417
+ this._allLayoutRels = masters.flatMap((m) => m.layoutRels);
4448
4418
  return this.masterMap;
4449
4419
  }
4450
4420
  findLayoutForSlide(slideIndex) {
@@ -4454,30 +4424,30 @@ var File = class {
4454
4424
  const layoutKey = opts.layout ?? "blank";
4455
4425
  return master.layouts.find((l) => l.key === layoutKey) ?? master.layouts[0];
4456
4426
  }
4457
- get CoreProperties() {
4458
- return this.coreProperties ??= new CoreProperties(this.corePropsOptions);
4427
+ get coreProperties() {
4428
+ return this._coreProperties ??= new CoreProperties(this.corePropsOptions);
4459
4429
  }
4460
- get AppProperties() {
4461
- return this.appProperties ??= new AppProperties();
4430
+ get appProperties() {
4431
+ return this._appProperties ??= new AppProperties();
4462
4432
  }
4463
- get ContentTypes() {
4464
- if (!this.contentTypes) {
4465
- this.contentTypes = new ContentTypes();
4433
+ get contentTypes() {
4434
+ if (!this._contentTypes) {
4435
+ this._contentTypes = new ContentTypes();
4466
4436
  let hasComments = false;
4467
4437
  for (let i = 0; i < this.slideOptions.length; i++) {
4468
- this.contentTypes.addSlide(i + 1);
4469
- if (this.slideOptions[i].notes) this.contentTypes.addNotesSlide(i + 1);
4438
+ this._contentTypes.addSlide(i + 1);
4439
+ if (this.slideOptions[i].notes) this._contentTypes.addNotesSlide(i + 1);
4470
4440
  if (this.slideOptions[i].comments && this.slideOptions[i].comments.length > 0) {
4471
- this.contentTypes.addComments(i + 1);
4441
+ this._contentTypes.addComments(i + 1);
4472
4442
  hasComments = true;
4473
4443
  }
4474
4444
  }
4475
- if (hasComments) this.contentTypes.addCommentAuthors();
4445
+ if (hasComments) this._contentTypes.addCommentAuthors();
4476
4446
  }
4477
- return this.contentTypes;
4447
+ return this._contentTypes;
4478
4448
  }
4479
- get FileRelationships() {
4480
- if (!this.fileRels) this.fileRels = buildRelationships([
4449
+ get fileRelationships() {
4450
+ if (!this._fileRels) this._fileRels = buildRelationships([
4481
4451
  {
4482
4452
  id: 1,
4483
4453
  type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
@@ -4494,30 +4464,30 @@ var File = class {
4494
4464
  target: "docProps/app.xml"
4495
4465
  }
4496
4466
  ]);
4497
- return this.fileRels;
4467
+ return this._fileRels;
4498
4468
  }
4499
- get Media() {
4500
- return this.media ??= new Media();
4469
+ get media() {
4470
+ return this._media ??= new Media();
4501
4471
  }
4502
- get Charts() {
4503
- return this.charts ??= new ChartCollection();
4472
+ get charts() {
4473
+ return this._charts ??= new ChartCollection();
4504
4474
  }
4505
- get SmartArts() {
4506
- return this.smartArts ??= new SmartArtCollection();
4475
+ get smartArts() {
4476
+ return this._smartArts ??= new SmartArtCollection();
4507
4477
  }
4508
- get Hyperlinks() {
4509
- return this.hyperlinks ??= new HyperlinkCollection();
4478
+ get hyperlinks() {
4479
+ return this._hyperlinks ??= new HyperlinkCollection();
4510
4480
  }
4511
- get PresentationWrapper() {
4512
- if (!this.presentationWrapper) {
4481
+ get presentationWrapper() {
4482
+ if (!this._presentationWrapper) {
4513
4483
  const masters = this.getMasterMap();
4514
- this.presentationWrapper = new PresentationWrapper({
4484
+ this._presentationWrapper = new PresentationWrapper({
4515
4485
  slideWidth: this.slideWidthEmus,
4516
4486
  slideHeight: this.slideHeightEmus,
4517
4487
  slideIds: this.slideOptions.map((_, i) => 256 + i),
4518
4488
  masterCount: masters.length
4519
4489
  });
4520
- const presRels = this.PresentationWrapper.Relationships;
4490
+ const presRels = this._presentationWrapper.relationships;
4521
4491
  let rid = 1;
4522
4492
  for (let mi = 0; mi < masters.length; mi++) presRels.addRelationship(rid++, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster", `slideMasters/slideMaster${mi + 1}.xml`);
4523
4493
  for (let i = 0; i < this.slideOptions.length; i++) presRels.addRelationship(rid++, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide", `slides/slide${i + 1}.xml`);
@@ -4526,49 +4496,49 @@ var File = class {
4526
4496
  for (let mi = 0; mi < masters.length; mi++) presRels.addRelationship(rid++, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme", `theme/theme${mi + 1}.xml`);
4527
4497
  presRels.addRelationship(rid, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableStyles", "tableStyles.xml");
4528
4498
  }
4529
- return this.presentationWrapper;
4499
+ return this._presentationWrapper;
4530
4500
  }
4531
- get Themes() {
4501
+ get themes() {
4532
4502
  return this.getMasterMap().map((m) => m.theme);
4533
4503
  }
4534
- get TableStyles() {
4535
- return this.tableStyles ??= new TableStyles();
4504
+ get tableStyles() {
4505
+ return this._tableStyles ??= new TableStyles();
4536
4506
  }
4537
- get PresProps() {
4538
- return this.presProps ??= new PresentationProperties(this.showOptions);
4507
+ get presProps() {
4508
+ return this._presProps ??= new PresentationProperties(this.showOptions);
4539
4509
  }
4540
- get ViewProps() {
4541
- return this.viewProps ??= new ViewProperties();
4510
+ get viewProps() {
4511
+ return this._viewProps ??= new ViewProperties();
4542
4512
  }
4543
- get SlideMasters() {
4513
+ get slideMasters() {
4544
4514
  return this.getMasterMap().map((m) => m.master);
4545
4515
  }
4546
- get SlideMasterRelsArray() {
4516
+ get slideMasterRelsArray() {
4547
4517
  return this.getMasterMap().map((m) => m.masterRels);
4548
4518
  }
4549
- get AllLayouts() {
4519
+ get allLayouts() {
4550
4520
  this.getMasterMap();
4551
- return this.allLayouts;
4521
+ return this._allLayouts;
4552
4522
  }
4553
- get AllLayoutRelsArray() {
4523
+ get allLayoutRelsArray() {
4554
4524
  this.getMasterMap();
4555
- return this.allLayoutRels;
4525
+ return this._allLayoutRels;
4556
4526
  }
4557
- get Slides() {
4558
- if (!this.slides) {
4559
- this.slides = [];
4560
- for (const s of this.slideOptions) this.slides.push(new Slide(s.children ?? [], s.background ? new Background(s.background) : void 0, s.transition, s.headerFooter));
4527
+ get slides() {
4528
+ if (!this._slides) {
4529
+ this._slides = [];
4530
+ for (const s of this.slideOptions) this._slides.push(new Slide(s.children ?? [], s.background ? new Background(s.background) : void 0, s.transition, s.headerFooter));
4561
4531
  }
4562
- return this.slides;
4532
+ return this._slides;
4563
4533
  }
4564
- get SlideWrappers() {
4565
- if (!this.slideWrappers) {
4566
- this.slideWrappers = [];
4534
+ get slideWrappers() {
4535
+ if (!this._slideWrappers) {
4536
+ this._slideWrappers = [];
4567
4537
  for (let i = 0; i < this.slideOptions.length; i++) {
4568
4538
  const layout = this.findLayoutForSlide(i);
4569
- this.slideWrappers.push({
4570
- View: this.Slides[i],
4571
- Relationships: buildRelationships([{
4539
+ this._slideWrappers.push({
4540
+ view: this.slides[i],
4541
+ relationships: buildRelationships([{
4572
4542
  id: 1,
4573
4543
  type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout",
4574
4544
  target: `../slideLayouts/slideLayout${layout.index + 1}.xml`
@@ -4576,37 +4546,37 @@ var File = class {
4576
4546
  });
4577
4547
  }
4578
4548
  }
4579
- return this.slideWrappers;
4549
+ return this._slideWrappers;
4580
4550
  }
4581
- get NotesSlides() {
4582
- if (!this.notesSlides) {
4583
- this.notesSlides = [];
4584
- for (let i = 0; i < this.slideOptions.length; i++) if (this.slideOptions[i].notes) this.notesSlides.push(new NotesSlide({ text: this.slideOptions[i].notes }));
4551
+ get notesSlides() {
4552
+ if (!this._notesSlides) {
4553
+ this._notesSlides = [];
4554
+ for (let i = 0; i < this.slideOptions.length; i++) if (this.slideOptions[i].notes) this._notesSlides.push(new NotesSlide({ text: this.slideOptions[i].notes }));
4585
4555
  }
4586
- return this.notesSlides;
4556
+ return this._notesSlides;
4587
4557
  }
4588
4558
  /** Map from slide index → notesSlide index (0-based) for slides that have notes. */
4589
- get NotesSlideIndexMap() {
4559
+ get notesSlideIndexMap() {
4590
4560
  const map = /* @__PURE__ */ new Map();
4591
4561
  let notesIdx = 0;
4592
4562
  for (let i = 0; i < this.slideOptions.length; i++) if (this.slideOptions[i].notes) map.set(i, notesIdx++);
4593
4563
  return map;
4594
4564
  }
4595
- get NotesMasterRelationships() {
4596
- return this.notesMasterRels ??= new Relationships();
4565
+ get notesMasterRelationships() {
4566
+ return this._notesMasterRels ??= new Relationships();
4597
4567
  }
4598
- get CommentAuthorList() {
4599
- if (!this.commentAuthorList && !this.slideCommentLists) this.buildComments();
4600
- return this.commentAuthorList;
4568
+ get commentAuthorList() {
4569
+ if (!this._commentAuthorList && !this._slideCommentLists) this.buildComments();
4570
+ return this._commentAuthorList;
4601
4571
  }
4602
- get SlideCommentLists() {
4603
- if (!this.slideCommentLists) this.buildComments();
4604
- return this.slideCommentLists;
4572
+ get slideCommentLists() {
4573
+ if (!this._slideCommentLists) this.buildComments();
4574
+ return this._slideCommentLists;
4605
4575
  }
4606
4576
  buildComments() {
4607
4577
  const authorMap = /* @__PURE__ */ new Map();
4608
4578
  let nextAuthorId = 0;
4609
- this.slideCommentLists = Array.from({ length: this.slideOptions.length });
4579
+ this._slideCommentLists = Array.from({ length: this.slideOptions.length });
4610
4580
  for (let i = 0; i < this.slideOptions.length; i++) {
4611
4581
  const slideComments = this.slideOptions[i].comments;
4612
4582
  if (!slideComments || slideComments.length === 0) continue;
@@ -4634,7 +4604,7 @@ var File = class {
4634
4604
  text: c.text
4635
4605
  });
4636
4606
  }
4637
- this.slideCommentLists[i] = new SlideCommentList(commentEntries);
4607
+ this._slideCommentLists[i] = new SlideCommentList(commentEntries);
4638
4608
  }
4639
4609
  if (authorMap.size > 0) {
4640
4610
  const authors = [...authorMap.values()].map((a) => ({
@@ -4644,7 +4614,7 @@ var File = class {
4644
4614
  clrIdx: a.clrIdx,
4645
4615
  lastIdx: a.commentCount
4646
4616
  }));
4647
- this.commentAuthorList = new CommentAuthorList(authors);
4617
+ this._commentAuthorList = new CommentAuthorList(authors);
4648
4618
  }
4649
4619
  }
4650
4620
  };
@@ -4897,40 +4867,40 @@ var Compiler = class {
4897
4867
  };
4898
4868
  const mapping = {
4899
4869
  AppProperties: {
4900
- data: xml(this.formatter.format(file.AppProperties, context), { declaration }),
4870
+ data: xml(this.formatter.format(file.appProperties, context), { declaration }),
4901
4871
  path: "docProps/app.xml"
4902
4872
  },
4903
4873
  Properties: {
4904
- data: xml(this.formatter.format(file.CoreProperties, context), {
4874
+ data: xml(this.formatter.format(file.coreProperties, context), {
4905
4875
  declaration,
4906
4876
  indent
4907
4877
  }),
4908
4878
  path: "docProps/core.xml"
4909
4879
  },
4910
4880
  FileRelationships: {
4911
- data: xml(this.formatter.format(file.FileRelationships, context), { declaration: false }),
4881
+ data: xml(this.formatter.format(file.fileRelationships, context), { declaration: false }),
4912
4882
  path: "_rels/.rels"
4913
4883
  }
4914
4884
  };
4915
- const themes = file.Themes;
4885
+ const themes = file.themes;
4916
4886
  for (let ti = 0; ti < themes.length; ti++) mapping[`Theme${ti}`] = {
4917
4887
  data: this.formatter.formatToXml(themes[ti], context, declaration),
4918
4888
  path: `ppt/theme/theme${ti + 1}.xml`
4919
4889
  };
4920
4890
  mapping["TableStyles"] = {
4921
- data: this.formatter.formatToXml(file.TableStyles, context, declaration),
4891
+ data: this.formatter.formatToXml(file.tableStyles, context, declaration),
4922
4892
  path: "ppt/tableStyles.xml"
4923
4893
  };
4924
4894
  mapping["PresProps"] = {
4925
- data: this.formatter.formatToXml(file.PresProps, context, declaration),
4895
+ data: this.formatter.formatToXml(file.presProps, context, declaration),
4926
4896
  path: "ppt/presProps.xml"
4927
4897
  };
4928
4898
  mapping["ViewProps"] = {
4929
- data: this.formatter.formatToXml(file.ViewProps, context, declaration),
4899
+ data: this.formatter.formatToXml(file.viewProps, context, declaration),
4930
4900
  path: "ppt/viewProps.xml"
4931
4901
  };
4932
- const masters = file.SlideMasters;
4933
- const masterRels = file.SlideMasterRelsArray;
4902
+ const masters = file.slideMasters;
4903
+ const masterRels = file.slideMasterRelsArray;
4934
4904
  for (let mi = 0; mi < masters.length; mi++) {
4935
4905
  mapping[`SlideMaster${mi}`] = {
4936
4906
  data: this.formatter.formatToXml(masters[mi], context, declaration),
@@ -4941,8 +4911,8 @@ var Compiler = class {
4941
4911
  path: `ppt/slideMasters/_rels/slideMaster${mi + 1}.xml.rels`
4942
4912
  };
4943
4913
  }
4944
- const layouts = file.AllLayouts;
4945
- const layoutRels = file.AllLayoutRelsArray;
4914
+ const layouts = file.allLayouts;
4915
+ const layoutRels = file.allLayoutRelsArray;
4946
4916
  for (let li = 0; li < layouts.length; li++) {
4947
4917
  mapping[`SlideLayout${li}`] = {
4948
4918
  data: this.formatter.formatToXml(layouts[li].layout, context, declaration),
@@ -4953,13 +4923,13 @@ var Compiler = class {
4953
4923
  path: `ppt/slideLayouts/_rels/slideLayout${li + 1}.xml.rels`
4954
4924
  };
4955
4925
  }
4956
- for (let i = 0; i < layouts.length; i++) file.ContentTypes.addSlideLayout(i + 1);
4926
+ for (let i = 0; i < layouts.length; i++) file.contentTypes.addSlideLayout(i + 1);
4957
4927
  for (let mi = 0; mi < masters.length; mi++) {
4958
- file.ContentTypes.addSlideMaster(mi + 1);
4959
- file.ContentTypes.addTheme(mi + 1);
4928
+ file.contentTypes.addSlideMaster(mi + 1);
4929
+ file.contentTypes.addTheme(mi + 1);
4960
4930
  }
4961
- if (file.NotesSlides.length > 0) {
4962
- file.PresentationWrapper.Relationships.addRelationship(file.PresentationWrapper.Relationships.RelationshipCount + 1, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster", "notesMasters/notesMaster1.xml");
4931
+ if (file.notesSlides.length > 0) {
4932
+ file.presentationWrapper.relationships.addRelationship(file.presentationWrapper.relationships.relationshipCount + 1, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster", "notesMasters/notesMaster1.xml");
4963
4933
  mapping["NotesMaster"] = {
4964
4934
  data: xml(this.formatter.format(new DefaultNotesMaster(), context), {
4965
4935
  declaration,
@@ -4968,17 +4938,17 @@ var Compiler = class {
4968
4938
  path: "ppt/notesMasters/notesMaster1.xml"
4969
4939
  };
4970
4940
  mapping["NotesMasterRelationships"] = {
4971
- data: xml(this.formatter.format(file.NotesMasterRelationships, context), { declaration: false }),
4941
+ data: xml(this.formatter.format(file.notesMasterRelationships, context), { declaration: false }),
4972
4942
  path: "ppt/notesMasters/_rels/notesMaster1.xml.rels"
4973
4943
  };
4974
4944
  }
4975
- if (file.CommentAuthorList) file.PresentationWrapper.Relationships.addRelationship(file.PresentationWrapper.Relationships.RelationshipCount + 1, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthors", "commentAuthors.xml");
4976
- const presentationXml = this.formatter.formatToXml(file.PresentationWrapper.View, context, declaration);
4945
+ if (file.commentAuthorList) file.presentationWrapper.relationships.addRelationship(file.presentationWrapper.relationships.relationshipCount + 1, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthors", "commentAuthors.xml");
4946
+ const presentationXml = this.formatter.formatToXml(file.presentationWrapper.view, context, declaration);
4977
4947
  let currentImageCount = 0;
4978
- const mediaData = getReferencedMedia(presentationXml, file.Media.Array);
4979
- const presImageOffset = file.PresentationWrapper.Relationships.RelationshipCount + 1;
4948
+ const mediaData = getReferencedMedia(presentationXml, file.media.array);
4949
+ const presImageOffset = file.presentationWrapper.relationships.relationshipCount + 1;
4980
4950
  mediaData.forEach((image, idx) => {
4981
- file.PresentationWrapper.Relationships.addRelationship(presImageOffset + idx, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `../media/${image.fileName}`);
4951
+ file.presentationWrapper.relationships.addRelationship(presImageOffset + idx, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `../media/${image.fileName}`);
4982
4952
  });
4983
4953
  const replacedPresentationXml = replaceImagePlaceholders(presentationXml, mediaData, presImageOffset);
4984
4954
  currentImageCount += mediaData.length;
@@ -4987,38 +4957,38 @@ var Compiler = class {
4987
4957
  path: "ppt/presentation.xml"
4988
4958
  };
4989
4959
  mapping["PresentationRelationships"] = {
4990
- data: xml(this.formatter.format(file.PresentationWrapper.Relationships, context), { declaration: false }),
4960
+ data: xml(this.formatter.format(file.presentationWrapper.relationships, context), { declaration: false }),
4991
4961
  path: "ppt/_rels/presentation.xml.rels"
4992
4962
  };
4993
- for (let i = 0; i < file.Slides.length; i++) {
4994
- const slideWrapper = file.SlideWrappers[i];
4995
- const slideXml = this.formatter.formatToXml(slideWrapper.View, context, declaration);
4996
- const slideMediaData = getReferencedMedia(slideXml, file.Media.Array);
4997
- const slideImageOffset = slideWrapper.Relationships.RelationshipCount + 1;
4963
+ for (let i = 0; i < file.slides.length; i++) {
4964
+ const slideWrapper = file.slideWrappers[i];
4965
+ const slideXml = this.formatter.formatToXml(slideWrapper.view, context, declaration);
4966
+ const slideMediaData = getReferencedMedia(slideXml, file.media.array);
4967
+ const slideImageOffset = slideWrapper.relationships.relationshipCount + 1;
4998
4968
  slideMediaData.forEach((image, idx) => {
4999
- slideWrapper.Relationships.addRelationship(slideImageOffset + idx, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `../media/${image.fileName}`);
4969
+ slideWrapper.relationships.addRelationship(slideImageOffset + idx, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `../media/${image.fileName}`);
5000
4970
  });
5001
4971
  let replacedSlideXml = replaceImagePlaceholders(slideXml, slideMediaData, slideImageOffset);
5002
4972
  currentImageCount += slideMediaData.length;
5003
4973
  if (hasPlaceholders(replacedSlideXml)) {
5004
4974
  const slideChartKeys = collectPlaceholderKeys(replacedSlideXml, "chart:");
5005
4975
  if (slideChartKeys.length > 0) {
5006
- const slideChartOffset = slideWrapper.Relationships.RelationshipCount + 1;
5007
- const slideCharts = file.Charts.Array.filter((c) => slideChartKeys.includes(c.key));
4976
+ const slideChartOffset = slideWrapper.relationships.relationshipCount + 1;
4977
+ const slideCharts = file.charts.array.filter((c) => slideChartKeys.includes(c.key));
5008
4978
  replacedSlideXml = replaceChartPlaceholders(replacedSlideXml, slideCharts.map((c) => c.key), slideChartOffset);
5009
4979
  slideCharts.forEach((chartData, ci) => {
5010
- const globalIndex = file.Charts.Array.indexOf(chartData);
5011
- slideWrapper.Relationships.addRelationship(slideChartOffset + ci, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart", `../charts/chart${globalIndex + 1}.xml`);
4980
+ const globalIndex = file.charts.array.indexOf(chartData);
4981
+ slideWrapper.relationships.addRelationship(slideChartOffset + ci, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart", `../charts/chart${globalIndex + 1}.xml`);
5012
4982
  });
5013
4983
  }
5014
4984
  const slideSmartArtKeys = collectPlaceholderKeys(replacedSlideXml, "smartart:");
5015
4985
  if (slideSmartArtKeys.length > 0) {
5016
- const slideSmartArts = file.SmartArts.Array.filter((s) => slideSmartArtKeys.includes(s.key));
5017
- const saOffset = slideWrapper.Relationships.RelationshipCount + 1;
4986
+ const slideSmartArts = file.smartArts.array.filter((s) => slideSmartArtKeys.includes(s.key));
4987
+ const saOffset = slideWrapper.relationships.relationshipCount + 1;
5018
4988
  replacedSlideXml = replaceSmartArtPlaceholders(replacedSlideXml, slideSmartArts.map((s) => s.key), saOffset);
5019
- const saGlobalStart = file.SmartArts.Array.indexOf(slideSmartArts[0]);
4989
+ const saGlobalStart = file.smartArts.array.indexOf(slideSmartArts[0]);
5020
4990
  addSmartArtRelationships(slideSmartArts.map((s) => s.key), (id, type, target) => {
5021
- slideWrapper.Relationships.addRelationship(id, type, target);
4991
+ slideWrapper.relationships.addRelationship(id, type, target);
5022
4992
  }, saOffset, saGlobalStart, {
5023
4993
  pathPrefix: "../",
5024
4994
  styleRelType: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramQuickStyle"
@@ -5026,25 +4996,25 @@ var Compiler = class {
5026
4996
  }
5027
4997
  const slideHlinkKeys = collectPlaceholderKeys(replacedSlideXml, "hlink:");
5028
4998
  if (slideHlinkKeys.length > 0) {
5029
- const slideHlinks = file.Hyperlinks.Array.filter((h) => slideHlinkKeys.includes(h.key));
5030
- const hlinkOffset = slideWrapper.Relationships.RelationshipCount + 1;
4999
+ const slideHlinks = file.hyperlinks.array.filter((h) => slideHlinkKeys.includes(h.key));
5000
+ const hlinkOffset = slideWrapper.relationships.relationshipCount + 1;
5031
5001
  replacedSlideXml = replaceHyperlinkPlaceholders(replacedSlideXml, slideHlinks, hlinkOffset);
5032
5002
  slideHlinks.forEach((hlink, hi) => {
5033
- slideWrapper.Relationships.addRelationship(hlinkOffset + hi, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", hlink.url, "External");
5003
+ slideWrapper.relationships.addRelationship(hlinkOffset + hi, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", hlink.url, "External");
5034
5004
  });
5035
5005
  }
5036
- const slideMediaRefs = getMediaRefs(replacedSlideXml, file.Media.Array);
5037
- const slideVideoRefs = getVideoRefs(replacedSlideXml, file.Media.Array);
5006
+ const slideMediaRefs = getMediaRefs(replacedSlideXml, file.media.array);
5007
+ const slideVideoRefs = getVideoRefs(replacedSlideXml, file.media.array);
5038
5008
  if (slideMediaRefs.length > 0 || slideVideoRefs.length > 0) {
5039
- const mediaOffset = slideWrapper.Relationships.RelationshipCount + 1;
5009
+ const mediaOffset = slideWrapper.relationships.relationshipCount + 1;
5040
5010
  const videoOffset = mediaOffset + slideMediaRefs.length;
5041
5011
  replacedSlideXml = replaceMediaPlaceholders(replacedSlideXml, slideMediaRefs, mediaOffset);
5042
5012
  replacedSlideXml = replaceVideoPlaceholders(replacedSlideXml, slideVideoRefs, videoOffset);
5043
5013
  slideMediaRefs.forEach((media, mi) => {
5044
- slideWrapper.Relationships.addRelationship(mediaOffset + mi, "http://schemas.microsoft.com/office/2007/relationships/media", `../media/${media.fileName}`);
5014
+ slideWrapper.relationships.addRelationship(mediaOffset + mi, "http://schemas.microsoft.com/office/2007/relationships/media", `../media/${media.fileName}`);
5045
5015
  });
5046
5016
  slideVideoRefs.forEach((video, vi) => {
5047
- slideWrapper.Relationships.addRelationship(videoOffset + vi, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/video", `../media/${video.fileName}`);
5017
+ slideWrapper.relationships.addRelationship(videoOffset + vi, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/video", `../media/${video.fileName}`);
5048
5018
  });
5049
5019
  }
5050
5020
  }
@@ -5052,26 +5022,26 @@ var Compiler = class {
5052
5022
  data: replacedSlideXml,
5053
5023
  path: `ppt/slides/slide${i + 1}.xml`
5054
5024
  };
5055
- if (file.SlideCommentLists[i]) slideWrapper.Relationships.addRelationship(slideWrapper.Relationships.RelationshipCount + 1, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments", `../comments/comment${i + 1}.xml`);
5056
- const notesSlideIndex = file.NotesSlideIndexMap.get(i);
5057
- if (notesSlideIndex !== void 0) slideWrapper.Relationships.addRelationship(slideWrapper.Relationships.RelationshipCount + 1, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide", `../notesSlides/notesSlide${notesSlideIndex + 1}.xml`);
5025
+ if (file.slideCommentLists[i]) slideWrapper.relationships.addRelationship(slideWrapper.relationships.relationshipCount + 1, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments", `../comments/comment${i + 1}.xml`);
5026
+ const notesSlideIndex = file.notesSlideIndexMap.get(i);
5027
+ if (notesSlideIndex !== void 0) slideWrapper.relationships.addRelationship(slideWrapper.relationships.relationshipCount + 1, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide", `../notesSlides/notesSlide${notesSlideIndex + 1}.xml`);
5058
5028
  mapping[`SlideRelationships${i}`] = {
5059
- data: xml(this.formatter.format(slideWrapper.Relationships, context), { declaration: false }),
5029
+ data: xml(this.formatter.format(slideWrapper.relationships, context), { declaration: false }),
5060
5030
  path: `ppt/slides/_rels/slide${i + 1}.xml.rels`
5061
5031
  };
5062
5032
  }
5063
- file.Charts.Array.forEach((_, i) => {
5064
- file.ContentTypes.addChart(i + 1);
5033
+ file.charts.array.forEach((_, i) => {
5034
+ file.contentTypes.addChart(i + 1);
5065
5035
  });
5066
- file.SmartArts.Array.forEach((_, i) => {
5067
- file.ContentTypes.addDiagramData(i + 1);
5068
- file.ContentTypes.addDiagramLayout(i + 1);
5069
- file.ContentTypes.addDiagramStyle(i + 1);
5070
- file.ContentTypes.addDiagramColors(i + 1);
5071
- file.ContentTypes.addDiagramDrawing(i + 1);
5036
+ file.smartArts.array.forEach((_, i) => {
5037
+ file.contentTypes.addDiagramData(i + 1);
5038
+ file.contentTypes.addDiagramLayout(i + 1);
5039
+ file.contentTypes.addDiagramStyle(i + 1);
5040
+ file.contentTypes.addDiagramColors(i + 1);
5041
+ file.contentTypes.addDiagramDrawing(i + 1);
5072
5042
  });
5073
5043
  mapping["ContentTypes"] = {
5074
- data: xml(this.formatter.format(file.ContentTypes, context), { declaration: false }),
5044
+ data: xml(this.formatter.format(file.contentTypes, context), { declaration: false }),
5075
5045
  path: "[Content_Types].xml"
5076
5046
  };
5077
5047
  const files = {};
@@ -5080,8 +5050,8 @@ var Compiler = class {
5080
5050
  files[entry.path] = textToUint8Array(entry.data);
5081
5051
  }
5082
5052
  for (const override of overrides) files[override.path] = override.data instanceof Uint8Array ? override.data : textToUint8Array(override.data);
5083
- for (let i = 0; i < file.Charts.Array.length; i++) {
5084
- const chartData = file.Charts.Array[i];
5053
+ for (let i = 0; i < file.charts.array.length; i++) {
5054
+ const chartData = file.charts.array[i];
5085
5055
  files[`ppt/charts/chart${i + 1}.xml`] = textToUint8Array(xml(this.formatter.format(chartData.chartSpace, context), {
5086
5056
  declaration,
5087
5057
  indent
@@ -5091,8 +5061,8 @@ var Compiler = class {
5091
5061
  standalone: "yes"
5092
5062
  } }));
5093
5063
  }
5094
- for (let i = 0; i < file.SmartArts.Array.length; i++) {
5095
- const smartArtData = file.SmartArts.Array[i];
5064
+ for (let i = 0; i < file.smartArts.array.length; i++) {
5065
+ const smartArtData = file.smartArts.array[i];
5096
5066
  files[`ppt/diagrams/data${i + 1}.xml`] = textToUint8Array(xml(this.formatter.format(smartArtData.dataModel, context), {
5097
5067
  declaration,
5098
5068
  indent
@@ -5102,8 +5072,8 @@ var Compiler = class {
5102
5072
  files[`ppt/diagrams/colors${i + 1}.xml`] = textToUint8Array(getColorXml(smartArtData.color));
5103
5073
  files[`ppt/diagrams/drawing${i + 1}.xml`] = textToUint8Array(DEFAULT_DRAWING_XML);
5104
5074
  }
5105
- for (let i = 0; i < file.NotesSlides.length; i++) {
5106
- const notesSlide = file.NotesSlides[i];
5075
+ for (let i = 0; i < file.notesSlides.length; i++) {
5076
+ const notesSlide = file.notesSlides[i];
5107
5077
  files[`ppt/notesSlides/notesSlide${i + 1}.xml`] = textToUint8Array(xml(this.formatter.format(notesSlide, context), {
5108
5078
  declaration,
5109
5079
  indent
@@ -5113,16 +5083,16 @@ var Compiler = class {
5113
5083
  standalone: "yes"
5114
5084
  } }));
5115
5085
  }
5116
- if (file.CommentAuthorList) files["ppt/commentAuthors.xml"] = textToUint8Array(xml(this.formatter.format(file.CommentAuthorList, context), {
5086
+ if (file.commentAuthorList) files["ppt/commentAuthors.xml"] = textToUint8Array(xml(this.formatter.format(file.commentAuthorList, context), {
5117
5087
  declaration,
5118
5088
  indent
5119
5089
  }));
5120
- const commentLists = file.SlideCommentLists;
5090
+ const commentLists = file.slideCommentLists;
5121
5091
  for (let i = 0; i < commentLists.length; i++) if (commentLists[i]) files[`ppt/comments/comment${i + 1}.xml`] = textToUint8Array(xml(this.formatter.format(commentLists[i], context), {
5122
5092
  declaration,
5123
5093
  indent
5124
5094
  }));
5125
- for (const image of file.Media.Array) {
5095
+ for (const image of file.media.array) {
5126
5096
  files[`ppt/media/${image.fileName}`] = [image.data, { level: ZIP_STORED_LEVEL }];
5127
5097
  if (image.type === "svg" && "fallback" in image) {
5128
5098
  const fallback = image.fallback;
@@ -5191,6 +5161,294 @@ var ParseContext = class {
5191
5161
  }
5192
5162
  };
5193
5163
  //#endregion
5164
+ //#region src/parse/animation.ts
5165
+ /**
5166
+ * Animation parser for PPTX documents.
5167
+ *
5168
+ * Parses p:timing elements and maps animations to their target shapes.
5169
+ *
5170
+ * @module
5171
+ */
5172
+ const ENTR_PRESET_TO_TYPE = /* @__PURE__ */ new Map();
5173
+ const EXIT_PRESET_TO_TYPE = /* @__PURE__ */ new Map();
5174
+ const EMPH_PRESET_TO_ID = /* @__PURE__ */ new Map();
5175
+ const PATH_PRESET_TO_TYPE = /* @__PURE__ */ new Map();
5176
+ const ENTR_IDS = {
5177
+ appear: 1,
5178
+ fade: 10,
5179
+ fly: 2,
5180
+ wipe: 22,
5181
+ dissolve: 34,
5182
+ split: 21,
5183
+ blinds: 25,
5184
+ checker: 26,
5185
+ randomBars: 24,
5186
+ wheel: 27,
5187
+ zoom: 10,
5188
+ cover: 28,
5189
+ push: 19,
5190
+ strips: 23
5191
+ };
5192
+ const EXIT_IDS = {
5193
+ appear: 53,
5194
+ fade: 59,
5195
+ fly: 51,
5196
+ wipe: 72,
5197
+ dissolve: 84,
5198
+ split: 71,
5199
+ blinds: 75,
5200
+ checker: 76,
5201
+ randomBars: 74,
5202
+ wheel: 77,
5203
+ zoom: 60,
5204
+ cover: 78,
5205
+ push: 69,
5206
+ strips: 73
5207
+ };
5208
+ const EMPH_IDS = {
5209
+ growShrink: 53,
5210
+ spin: 54,
5211
+ growWithTurn: 56,
5212
+ colorChange: 29,
5213
+ transparency: 57,
5214
+ boldFlash: 50,
5215
+ wave: 55,
5216
+ pulse: 58
5217
+ };
5218
+ const PATH_IDS = {
5219
+ customPath: 200,
5220
+ arc: 201,
5221
+ bounce: 202,
5222
+ circle: 203,
5223
+ curve: 204,
5224
+ figureEight: 205,
5225
+ line: 206,
5226
+ loop: 207
5227
+ };
5228
+ for (const [k, v] of Object.entries(ENTR_IDS)) ENTR_PRESET_TO_TYPE.set(v, k);
5229
+ for (const [k, v] of Object.entries(EXIT_IDS)) EXIT_PRESET_TO_TYPE.set(v, k);
5230
+ for (const [k, v] of Object.entries(EMPH_IDS)) EMPH_PRESET_TO_ID.set(v, k);
5231
+ for (const [k, v] of Object.entries(PATH_IDS)) PATH_PRESET_TO_TYPE.set(v, k);
5232
+ const SUBTYPE_TO_DIRECTION = /* @__PURE__ */ new Map();
5233
+ for (const [k, v] of Object.entries({
5234
+ left: 4,
5235
+ right: 8,
5236
+ up: 2,
5237
+ down: 1,
5238
+ horizontal: 16,
5239
+ vertical: 32
5240
+ })) SUBTYPE_TO_DIRECTION.set(v, k);
5241
+ /**
5242
+ * Parse p:timing element and return a map of shape ID → AnimationOptions.
5243
+ */
5244
+ function parseTiming(el) {
5245
+ const result = /* @__PURE__ */ new Map();
5246
+ const tnLst = findChild(el, "p:tnLst");
5247
+ if (!tnLst) return result;
5248
+ const mainPar = findChild(tnLst, "p:par");
5249
+ if (!mainPar) return result;
5250
+ const mainCTn = findChild(mainPar, "p:cTn");
5251
+ if (!mainCTn) return result;
5252
+ const childTnLst = findChild(mainCTn, "p:childTnLst");
5253
+ if (!childTnLst) return result;
5254
+ const seq = findChild(childTnLst, "p:seq");
5255
+ if (!seq) return result;
5256
+ const seqCTn = findChild(seq, "p:cTn");
5257
+ const seqChildTnLst = seqCTn ? findChild(seqCTn, "p:childTnLst") : void 0;
5258
+ if (!seqChildTnLst) return result;
5259
+ for (const parEl of seqChildTnLst.elements ?? []) {
5260
+ if (parEl.name !== "p:par") continue;
5261
+ const parCTn = findChild(parEl, "p:cTn");
5262
+ if (!parCTn) continue;
5263
+ const parChildTnLst = findChild(parCTn, "p:childTnLst");
5264
+ if (!parChildTnLst) continue;
5265
+ for (const effectEl of parChildTnLst.elements ?? []) {
5266
+ const anim = parseAnimationEffect(effectEl);
5267
+ if (!anim) continue;
5268
+ const shapeId = extractTargetShapeId(effectEl);
5269
+ if (shapeId !== void 0) result.set(shapeId, anim);
5270
+ }
5271
+ }
5272
+ return result;
5273
+ }
5274
+ function parseAnimationEffect(el) {
5275
+ const opts = {};
5276
+ const cTn = findChild(el, "p:cTn") ?? el;
5277
+ const nodeType = attr(cTn, "nodeType");
5278
+ if (nodeType === "clickEffect") opts.trigger = "onClick";
5279
+ else if (nodeType === "withEffect") opts.trigger = "withPrevious";
5280
+ else if (nodeType === "afterEffect") opts.trigger = "afterPrevious";
5281
+ const presetClass = attr(cTn, "presetClass");
5282
+ if (presetClass) opts.class = presetClass;
5283
+ const presetID = attrNum(cTn, "presetID");
5284
+ const dur = attr(cTn, "dur");
5285
+ if (dur) {
5286
+ const ms = parseDuration(dur);
5287
+ if (ms !== void 0) opts.duration = ms;
5288
+ }
5289
+ const stCondLst = findChild(cTn, "p:stCondLst");
5290
+ if (stCondLst) {
5291
+ const cond = findChild(stCondLst, "p:cond");
5292
+ if (cond) {
5293
+ const delay = attr(cond, "delay");
5294
+ if (delay) {
5295
+ const ms = parseDuration(delay);
5296
+ if (ms !== void 0) opts.delay = ms;
5297
+ }
5298
+ }
5299
+ }
5300
+ const presetSubtype = attrNum(cTn, "presetSubtype");
5301
+ if (presetSubtype !== void 0) {
5302
+ const dir = SUBTYPE_TO_DIRECTION.get(presetSubtype);
5303
+ if (dir) opts.direction = dir;
5304
+ }
5305
+ if (presetID !== void 0) {
5306
+ const cls = presetClass ?? "entr";
5307
+ if (cls === "entr") {
5308
+ const type = ENTR_PRESET_TO_TYPE.get(presetID);
5309
+ if (type) opts.type = type;
5310
+ } else if (cls === "exit") {
5311
+ const type = EXIT_PRESET_TO_TYPE.get(presetID);
5312
+ if (type) opts.type = type;
5313
+ } else if (cls === "emph") {
5314
+ const emphType = EMPH_PRESET_TO_ID.get(presetID);
5315
+ if (emphType) {
5316
+ opts.emphasisType = emphType;
5317
+ opts.type = "appear";
5318
+ }
5319
+ } else if (cls === "mediacall") {
5320
+ opts.mediaType = "play";
5321
+ opts.type = "appear";
5322
+ }
5323
+ }
5324
+ const childTnLst = findChild(cTn, "p:childTnLst");
5325
+ if (childTnLst) for (const sub of childTnLst.elements ?? []) switch (sub.name) {
5326
+ case "p:animEffect":
5327
+ if (opts.duration === void 0) {
5328
+ const cBhvr = findChild(sub, "p:cBhvr");
5329
+ const subCTn = cBhvr ? findChild(cBhvr, "p:cTn") : void 0;
5330
+ if (subCTn) {
5331
+ const subDur = attr(subCTn, "dur");
5332
+ if (subDur) {
5333
+ const ms = parseDuration(subDur);
5334
+ if (ms !== void 0) opts.duration = ms;
5335
+ }
5336
+ }
5337
+ }
5338
+ break;
5339
+ case "p:anim": {
5340
+ const subCTn = findChild(sub, "p:cTn");
5341
+ if (subCTn) {
5342
+ const attrName = findChild(subCTn, "p:attrNameLst");
5343
+ if (attrName) {
5344
+ const name = findChild(attrName, "p:attrName");
5345
+ if (name) {
5346
+ const text = name.elements?.[0]?.text;
5347
+ if (text) opts.attributeName = text;
5348
+ }
5349
+ }
5350
+ }
5351
+ const from = findChild(sub, "p:cb");
5352
+ if (from) {
5353
+ const val = findChild(from, "p:val");
5354
+ if (val) {
5355
+ const v = attr(val, "val");
5356
+ if (v) opts.from = v;
5357
+ }
5358
+ }
5359
+ const toEl = findChild(sub, "p:tavLst");
5360
+ if (toEl) {
5361
+ const tav = findChild(toEl, "p:tav");
5362
+ if (tav) {
5363
+ const toVal = findChild(tav, "p:val");
5364
+ if (toVal) {
5365
+ const v = attr(toVal, "val");
5366
+ if (v) opts.to = v;
5367
+ }
5368
+ }
5369
+ }
5370
+ break;
5371
+ }
5372
+ case "p:animMotion": {
5373
+ opts.pathType = "customPath";
5374
+ const path = attr(sub, "path");
5375
+ if (path) opts.path = path;
5376
+ break;
5377
+ }
5378
+ case "p:animScale":
5379
+ opts.emphasisType = "growShrink";
5380
+ readSubDuration(sub, opts);
5381
+ break;
5382
+ case "p:animRot":
5383
+ opts.emphasisType = "spin";
5384
+ readSubDuration(sub, opts);
5385
+ break;
5386
+ case "p:animClr":
5387
+ opts.emphasisType = "colorChange";
5388
+ readSubDuration(sub, opts);
5389
+ break;
5390
+ case "p:cmd":
5391
+ if (attr(sub, "type") === "call") opts.mediaType = "play";
5392
+ break;
5393
+ }
5394
+ return Object.keys(opts).length > 0 ? opts : void 0;
5395
+ }
5396
+ function extractTargetShapeId(el) {
5397
+ const cBhvr = findDeep$1(el, "p:cBhvr")[0];
5398
+ if (!cBhvr) return void 0;
5399
+ const tgtEl = findChild(cBhvr, "p:tgtEl");
5400
+ if (!tgtEl) return void 0;
5401
+ const spTgt = findChild(tgtEl, "p:spTgt");
5402
+ if (!spTgt) return void 0;
5403
+ return attrNum(spTgt, "spid");
5404
+ }
5405
+ function findDeep$1(parent, name) {
5406
+ const results = [];
5407
+ function walk(el) {
5408
+ if (el.name === name) {
5409
+ results.push(el);
5410
+ return;
5411
+ }
5412
+ for (const child of el.elements ?? []) walk(child);
5413
+ }
5414
+ for (const child of parent.elements ?? []) walk(child);
5415
+ return results;
5416
+ }
5417
+ /**
5418
+ * Read duration from p:cBhvr > p:cTn inside a sub-effect element.
5419
+ */
5420
+ function readSubDuration(sub, opts) {
5421
+ if (opts.duration !== void 0) return;
5422
+ const cBhvr = findChild(sub, "p:cBhvr");
5423
+ const subCTn = cBhvr ? findChild(cBhvr, "p:cTn") : void 0;
5424
+ if (subCTn) {
5425
+ const subDur = attr(subCTn, "dur");
5426
+ if (subDur) {
5427
+ const ms = parseDuration(subDur);
5428
+ if (ms !== void 0) opts.duration = ms;
5429
+ }
5430
+ }
5431
+ }
5432
+ /**
5433
+ * Parse OOXML duration string to milliseconds.
5434
+ * Format: "PT#H#M#S" or "###ms" or just a number string
5435
+ */
5436
+ function parseDuration(val) {
5437
+ if (val.startsWith("PT")) {
5438
+ let ms = 0;
5439
+ const sMatch = val.match(/(\d+\.?\d*)S/);
5440
+ if (sMatch) ms += Math.round(parseFloat(sMatch[1]) * 1e3);
5441
+ const mMatch = val.match(/(\d+\.?\d*)M/);
5442
+ if (mMatch) ms += Math.round(parseFloat(mMatch[1]) * 6e4);
5443
+ const hMatch = val.match(/(\d+\.?\d*)H/);
5444
+ if (hMatch) ms += Math.round(parseFloat(hMatch[1]) * 36e5);
5445
+ return ms;
5446
+ }
5447
+ if (val === "indefinite") return void 0;
5448
+ const num = parseInt(val, 10);
5449
+ return isNaN(num) ? void 0 : num;
5450
+ }
5451
+ //#endregion
5194
5452
  //#region src/parse/slide.ts
5195
5453
  /**
5196
5454
  * Slide parser for PPTX documents.
@@ -5217,9 +5475,31 @@ function parseSlide(el, ctx) {
5217
5475
  }
5218
5476
  if (slideChildren.length > 0) opts.children = slideChildren;
5219
5477
  }
5478
+ const hf = findChild(cSld, "p:hf");
5479
+ if (hf) {
5480
+ const hfOpts = {};
5481
+ if (findChild(hf, "p:sldNum")) hfOpts.slideNumber = true;
5482
+ if (findChild(hf, "p:dt")) hfOpts.dateTime = true;
5483
+ if (findChild(hf, "p:ftr")) hfOpts.footer = true;
5484
+ if (findChild(hf, "p:hdr")) hfOpts.header = true;
5485
+ if (Object.keys(hfOpts).length > 0) opts.headerFooter = hfOpts;
5486
+ }
5220
5487
  }
5221
5488
  const transition = findChild(el, "p:transition");
5222
5489
  if (transition) opts.transition = parseTransition(transition);
5490
+ const timing = findChild(el, "p:timing");
5491
+ if (timing) {
5492
+ const animMap = parseTiming(timing);
5493
+ if (animMap.size > 0 && opts.children) {
5494
+ const children = opts.children;
5495
+ for (let i = 0; i < children.length; i++) {
5496
+ const child = children[i];
5497
+ const inner = child[Object.keys(child)[0]] ?? {};
5498
+ const shapeId = inner.id;
5499
+ if (shapeId !== void 0 && animMap.has(shapeId)) inner.animation = animMap.get(shapeId);
5500
+ }
5501
+ }
5502
+ }
5223
5503
  for (const [, path] of ctx.slideRels) {
5224
5504
  if (!path.includes("notesSlides")) continue;
5225
5505
  const notesEl = ctx.pptx.doc.get(path);
@@ -5232,8 +5512,18 @@ function parseSlide(el, ctx) {
5232
5512
  }
5233
5513
  function parseSlideChild(el, ctx) {
5234
5514
  switch (el.name) {
5235
- case "p:sp": return { shape: parseShape(el, ctx) };
5236
- case "p:pic": return { picture: parsePicture(el, ctx) };
5515
+ case "p:sp": {
5516
+ const spPr = findChild(el, "p:spPr");
5517
+ const prstGeom = spPr ? findChild(spPr, "a:prstGeom") : void 0;
5518
+ if ((prstGeom ? attr(prstGeom, "prst") : void 0) === "line") return { line: parseLineShape(el) };
5519
+ return { shape: parseShape(el, ctx) };
5520
+ }
5521
+ case "p:pic": {
5522
+ const mediaType = detectMediaType(el);
5523
+ if (mediaType === "video") return { video: parseMediaFrame(el, ctx, "video") };
5524
+ if (mediaType === "audio") return { audio: parseMediaFrame(el, ctx, "audio") };
5525
+ return { picture: parsePicture(el, ctx) };
5526
+ }
5237
5527
  case "p:graphicFrame": return parseGraphicFrame(el, ctx);
5238
5528
  case "p:cxnSp": return { connector: parseConnector(el) };
5239
5529
  case "p:grpSp": return { group: parseGroup(el, ctx) };
@@ -5315,7 +5605,7 @@ function parseTransition(el) {
5315
5605
  }
5316
5606
  return opts;
5317
5607
  }
5318
- function parseShape(el, _ctx) {
5608
+ function parseShape(el, ctx) {
5319
5609
  const opts = {};
5320
5610
  const nvSpPr = findChild(el, "p:nvSpPr");
5321
5611
  if (nvSpPr) {
@@ -5349,7 +5639,49 @@ function parseShape(el, _ctx) {
5349
5639
  if (effects) opts.effects = effects;
5350
5640
  }
5351
5641
  const txBody = findChild(el, "p:txBody");
5352
- if (txBody) parseTextBody(txBody, opts);
5642
+ if (txBody) parseTextBody(txBody, opts, ctx.slideRels);
5643
+ return opts;
5644
+ }
5645
+ function parseLineShape(el) {
5646
+ const opts = {};
5647
+ const nvSpPr = findChild(el, "p:nvSpPr");
5648
+ if (nvSpPr) {
5649
+ const cNvPr = findChild(nvSpPr, "p:cNvPr");
5650
+ if (cNvPr) {
5651
+ const id = attrNum(cNvPr, "id");
5652
+ if (id !== void 0) opts.id = id;
5653
+ const name = attr(cNvPr, "name");
5654
+ if (name) opts.name = name;
5655
+ }
5656
+ }
5657
+ const spPr = findChild(el, "p:spPr");
5658
+ if (spPr) {
5659
+ const xfrm = findChild(spPr, "a:xfrm");
5660
+ if (xfrm) {
5661
+ const off = findChild(xfrm, "a:off");
5662
+ const ext = findChild(xfrm, "a:ext");
5663
+ const flipH = attrBool(xfrm, "flipH");
5664
+ const flipV = attrBool(xfrm, "flipV");
5665
+ if (off && ext) {
5666
+ const offX = attrNum(off, "x") ?? 0;
5667
+ const offY = attrNum(off, "y") ?? 0;
5668
+ const cx = attrNum(ext, "cx") ?? 0;
5669
+ const cy = attrNum(ext, "cy") ?? 0;
5670
+ const x1 = flipH ? offX + cx : offX;
5671
+ const y1 = flipV ? offY + cy : offY;
5672
+ const x2 = flipH ? offX : offX + cx;
5673
+ const y2 = flipV ? offY : offY + cy;
5674
+ opts.x1 = convertEmuToPixels$1(x1);
5675
+ opts.y1 = convertEmuToPixels$1(y1);
5676
+ opts.x2 = convertEmuToPixels$1(x2);
5677
+ opts.y2 = convertEmuToPixels$1(y2);
5678
+ }
5679
+ }
5680
+ const fill = parseFillFromElement(spPr);
5681
+ if (fill) opts.fill = fill;
5682
+ const outline = parseOutlineFromElement(spPr);
5683
+ if (outline) opts.outline = outline;
5684
+ }
5353
5685
  return opts;
5354
5686
  }
5355
5687
  function parsePicture(el, ctx) {
@@ -5372,7 +5704,7 @@ function parsePicture(el, ctx) {
5372
5704
  }
5373
5705
  const nvPicPr = findChild(el, "p:nvPicPr");
5374
5706
  if (nvPicPr) {
5375
- const cNvPr = findChild(nvPicPr, "p:cNvPr");
5707
+ const cNvPr = findChild(nvPicPr, "a:cNvPr") ?? findChild(nvPicPr, "p:cNvPr");
5376
5708
  if (cNvPr) {
5377
5709
  const name = attr(cNvPr, "name");
5378
5710
  if (name) opts.name = name;
@@ -5604,6 +5936,24 @@ function parseTableFrame(el, tbl) {
5604
5936
  if (attrBool(tblPr, "firstCol")) opts.firstCol = true;
5605
5937
  if (attrBool(tblPr, "lastCol")) opts.lastCol = true;
5606
5938
  if (attrBool(tblPr, "bandCol")) opts.bandCol = true;
5939
+ const borders = {};
5940
+ for (const [elName, key] of [
5941
+ ["a:lnL", "left"],
5942
+ ["a:lnR", "right"],
5943
+ ["a:lnT", "top"],
5944
+ ["a:lnB", "bottom"]
5945
+ ]) {
5946
+ const borderEl = findChild(tblPr, elName);
5947
+ if (borderEl) {
5948
+ const borderOpts = {};
5949
+ const w = attrNum(borderEl, "w");
5950
+ if (w !== void 0) borderOpts.width = w;
5951
+ const fill = parseFillFromElement(borderEl);
5952
+ if (typeof fill === "string") borderOpts.color = fill;
5953
+ if (Object.keys(borderOpts).length > 0) borders[key] = borderOpts;
5954
+ }
5955
+ }
5956
+ if (Object.keys(borders).length > 0) opts.borders = borders;
5607
5957
  }
5608
5958
  const tblGrid = findChild(tbl, "a:tblGrid");
5609
5959
  if (tblGrid) {
@@ -5637,6 +5987,20 @@ function parseTableCell(tc) {
5637
5987
  if (txBody) {
5638
5988
  const paragraphs = parseParagraphsFromTxBody(txBody);
5639
5989
  if (paragraphs.length > 0) opts.children = paragraphs;
5990
+ const bodyPr = findChild(txBody, "a:bodyPr");
5991
+ if (bodyPr) {
5992
+ const margins = {};
5993
+ for (const [attrName, key] of [
5994
+ ["tIns", "top"],
5995
+ ["bIns", "bottom"],
5996
+ ["lIns", "left"],
5997
+ ["rIns", "right"]
5998
+ ]) {
5999
+ const val = attrNum(bodyPr, attrName);
6000
+ if (val !== void 0) margins[key] = val;
6001
+ }
6002
+ if (Object.keys(margins).length > 0) opts.margins = margins;
6003
+ }
5640
6004
  }
5641
6005
  const tcPr = findChild(tc, "a:tcPr");
5642
6006
  if (tcPr) {
@@ -5645,9 +6009,9 @@ function parseTableCell(tc) {
5645
6009
  const anchor = attr(tcPr, "anchor");
5646
6010
  if (anchor) {
5647
6011
  const anchorMap = {
5648
- t: "TOP",
5649
- ctr: "CENTER",
5650
- b: "BOTTOM"
6012
+ t: "top",
6013
+ ctr: "center",
6014
+ b: "bottom"
5651
6015
  };
5652
6016
  if (anchor in anchorMap) opts.verticalAlign = anchorMap[anchor];
5653
6017
  }
@@ -5674,7 +6038,7 @@ function parseTableCell(tc) {
5674
6038
  const borderOpts = {};
5675
6039
  if (w !== void 0) borderOpts.width = w;
5676
6040
  const fill = parseFillFromElement(borderEl);
5677
- if (fill) borderOpts.fill = fill;
6041
+ if (typeof fill === "string") borderOpts.color = fill;
5678
6042
  if (Object.keys(borderOpts).length > 0) borders[key] = borderOpts;
5679
6043
  }
5680
6044
  }
@@ -5775,22 +6139,23 @@ function parseGroup(el, ctx) {
5775
6139
  opts.children = groupChildren;
5776
6140
  return opts;
5777
6141
  }
5778
- function parseTextBody(txBody, opts) {
6142
+ function parseTextBody(txBody, opts, rels) {
6143
+ const textBody = {};
5779
6144
  const bodyPr = findChild(txBody, "a:bodyPr");
5780
6145
  if (bodyPr) {
5781
6146
  const vert = attr(bodyPr, "vert");
5782
- if (vert) opts.textVertical = vert;
6147
+ if (vert) textBody.vertical = vert;
5783
6148
  const anchor = attr(bodyPr, "anchor");
5784
6149
  if (anchor) {
5785
6150
  const anchorMap = {
5786
- t: "TOP",
5787
- ctr: "CENTER",
5788
- b: "BOTTOM"
6151
+ t: "top",
6152
+ ctr: "center",
6153
+ b: "bottom"
5789
6154
  };
5790
- if (anchor in anchorMap) opts.textAnchor = anchorMap[anchor];
6155
+ if (anchor in anchorMap) textBody.anchor = anchorMap[anchor];
5791
6156
  }
5792
6157
  const wrap = attr(bodyPr, "wrap");
5793
- if (wrap) opts.textWrap = wrap;
6158
+ if (wrap) textBody.wrap = wrap;
5794
6159
  const tIns = attrNum(bodyPr, "tIns");
5795
6160
  const bIns = attrNum(bodyPr, "bIns");
5796
6161
  const lIns = attrNum(bodyPr, "lIns");
@@ -5800,34 +6165,36 @@ function parseTextBody(txBody, opts) {
5800
6165
  if (bIns !== void 0) margins.bottom = bIns;
5801
6166
  if (lIns !== void 0) margins.left = lIns;
5802
6167
  if (rIns !== void 0) margins.right = rIns;
5803
- if (Object.keys(margins).length > 0) opts.textMargins = margins;
6168
+ if (Object.keys(margins).length > 0) textBody.margins = margins;
5804
6169
  const numCol = attrNum(bodyPr, "numCol");
5805
- if (numCol !== void 0) opts.textColumns = numCol;
6170
+ if (numCol !== void 0) textBody.columns = numCol;
5806
6171
  const spcCol = attrNum(bodyPr, "spcCol");
5807
- if (spcCol !== void 0) opts.textColumnSpacing = spcCol / 100;
5808
- if (findChild(bodyPr, "a:normAutofit")) opts.textAutoFit = "normal";
5809
- else if (findChild(bodyPr, "a:spAutoFit")) opts.textAutoFit = "shape";
5810
- else if (findChild(bodyPr, "a:noAutofit")) opts.textAutoFit = "none";
6172
+ if (spcCol !== void 0) textBody.columnSpacing = spcCol / 100;
6173
+ if (findChild(bodyPr, "a:normAutofit")) textBody.autoFit = "normal";
6174
+ else if (findChild(bodyPr, "a:spAutoFit")) textBody.autoFit = "shape";
6175
+ else if (findChild(bodyPr, "a:noAutofit")) textBody.autoFit = "none";
5811
6176
  }
5812
- const paragraphs = parseParagraphsFromTxBody(txBody);
6177
+ const paragraphs = parseParagraphsFromTxBody(txBody, rels);
5813
6178
  if (paragraphs.length === 1) {
5814
6179
  const p = paragraphs[0];
5815
6180
  if (p.text && !p.children) {
5816
6181
  const props = p.properties;
5817
6182
  if (!(props && Object.keys(props).some((k) => k !== "bullet" || props[k]?.type !== "none"))) {
5818
- opts.text = p.text;
6183
+ textBody.text = p.text;
6184
+ opts.textBody = textBody;
5819
6185
  return;
5820
6186
  }
5821
6187
  }
5822
6188
  }
5823
- if (paragraphs.length > 0) opts.paragraphs = paragraphs;
6189
+ if (paragraphs.length > 0) textBody.children = paragraphs;
6190
+ if (Object.keys(textBody).length > 0) opts.textBody = textBody;
5824
6191
  }
5825
- function parseParagraphsFromTxBody(txBody) {
6192
+ function parseParagraphsFromTxBody(txBody, rels) {
5826
6193
  const paragraphs = [];
5827
- for (const pEl of children(txBody, "a:p")) paragraphs.push(parseParagraph(pEl));
6194
+ for (const pEl of children(txBody, "a:p")) paragraphs.push(parseParagraph(pEl, rels));
5828
6195
  return paragraphs;
5829
6196
  }
5830
- function parseParagraph(el) {
6197
+ function parseParagraph(el, rels) {
5831
6198
  const opts = {};
5832
6199
  const pPr = findChild(el, "a:pPr");
5833
6200
  if (pPr) {
@@ -5835,10 +6202,10 @@ function parseParagraph(el) {
5835
6202
  const algn = attr(pPr, "algn");
5836
6203
  if (algn) {
5837
6204
  const alignMap = {
5838
- l: "LEFT",
5839
- ctr: "CENTER",
5840
- r: "RIGHT",
5841
- just: "JUSTIFY"
6205
+ l: "left",
6206
+ ctr: "center",
6207
+ r: "right",
6208
+ just: "justify"
5842
6209
  };
5843
6210
  if (algn in alignMap) props.alignment = alignMap[algn];
5844
6211
  }
@@ -5858,7 +6225,7 @@ function parseParagraph(el) {
5858
6225
  if (buClr) {
5859
6226
  const srgbClr = findChild(buClr, "a:srgbClr");
5860
6227
  if (srgbClr) {
5861
- const val = attr(srgbClr, "val");
6228
+ const val = colorAttr(srgbClr, "val");
5862
6229
  if (val) bulletOpts.color = val;
5863
6230
  }
5864
6231
  }
@@ -5909,12 +6276,12 @@ function parseParagraph(el) {
5909
6276
  if (Object.keys(props).length > 0) opts.properties = props;
5910
6277
  }
5911
6278
  const runs = [];
5912
- for (const rEl of children(el, "a:r")) runs.push(parseRun(rEl));
6279
+ for (const rEl of children(el, "a:r")) runs.push(parseRun(rEl, rels));
5913
6280
  if (runs.length === 1 && Object.keys(runs[0]).length === 1 && runs[0].text) opts.text = runs[0].text;
5914
6281
  else if (runs.length > 0) opts.children = runs;
5915
6282
  return opts;
5916
6283
  }
5917
- function parseRun(el) {
6284
+ function parseRun(el, rels) {
5918
6285
  const opts = {};
5919
6286
  const rPr = findChild(el, "a:rPr");
5920
6287
  if (rPr) {
@@ -5927,9 +6294,9 @@ function parseRun(el) {
5927
6294
  const u = attr(rPr, "u");
5928
6295
  if (u) {
5929
6296
  const underlineMap = {
5930
- sng: "SINGLE",
5931
- dbl: "DOUBLE",
5932
- none: "NONE"
6297
+ sng: "single",
6298
+ dbl: "double",
6299
+ none: "none"
5933
6300
  };
5934
6301
  if (u in underlineMap) opts.underline = underlineMap[u];
5935
6302
  }
@@ -5938,9 +6305,9 @@ function parseRun(el) {
5938
6305
  const strike = attr(rPr, "strike");
5939
6306
  if (strike) {
5940
6307
  const strikeMap = {
5941
- sngStrike: "SINGLE",
5942
- dblStrike: "DOUBLE",
5943
- noStrike: "NONE"
6308
+ sngStrike: "sngStrike",
6309
+ dblStrike: "dblStrike",
6310
+ noStrike: "noStrike"
5944
6311
  };
5945
6312
  if (strike in strikeMap) opts.strike = strikeMap[strike];
5946
6313
  }
@@ -5949,9 +6316,9 @@ function parseRun(el) {
5949
6316
  const cap = attr(rPr, "cap");
5950
6317
  if (cap) {
5951
6318
  const capMap = {
5952
- none: "NONE",
5953
- all: "ALL",
5954
- small: "SMALL"
6319
+ none: "none",
6320
+ all: "all",
6321
+ small: "small"
5955
6322
  };
5956
6323
  if (cap in capMap) opts.capitalization = capMap[cap];
5957
6324
  }
@@ -5964,6 +6331,19 @@ function parseRun(el) {
5964
6331
  }
5965
6332
  const fill = parseFillFromElement(rPr);
5966
6333
  if (fill) opts.fill = fill;
6334
+ const hlinkClick = findChild(rPr, "a:hlinkClick");
6335
+ if (hlinkClick && rels) {
6336
+ const rId = attr(hlinkClick, "r:id");
6337
+ if (rId) {
6338
+ const url = rels.get(rId);
6339
+ if (url) {
6340
+ const hyperlink = { url };
6341
+ const tooltip = attr(hlinkClick, "tooltip");
6342
+ if (tooltip) hyperlink.tooltip = tooltip;
6343
+ opts.hyperlink = hyperlink;
6344
+ }
6345
+ }
6346
+ }
5967
6347
  }
5968
6348
  const t = findChild(el, "a:t");
5969
6349
  if (t) opts.text = textOf(t) ?? "";
@@ -6019,7 +6399,7 @@ function parseFillFromElement(parent) {
6019
6399
  const solidFill = findChild(parent, "a:solidFill");
6020
6400
  if (solidFill) {
6021
6401
  const srgbClr = findChild(solidFill, "a:srgbClr");
6022
- if (srgbClr) return attr(srgbClr, "val");
6402
+ if (srgbClr) return colorAttr(srgbClr, "val");
6023
6403
  const schemeClr = findChild(solidFill, "a:schemeClr");
6024
6404
  if (schemeClr) return {
6025
6405
  type: "scheme",
@@ -6027,6 +6407,34 @@ function parseFillFromElement(parent) {
6027
6407
  };
6028
6408
  }
6029
6409
  if (findChild(parent, "a:noFill")) return { type: "none" };
6410
+ const pattFill = findChild(parent, "a:pattFill");
6411
+ if (pattFill) {
6412
+ const result = {
6413
+ type: "pattern",
6414
+ pattern: attr(pattFill, "prst") ?? ""
6415
+ };
6416
+ const fgClr = findChild(pattFill, "a:fgClr");
6417
+ if (fgClr) {
6418
+ const srgbClr = findChild(fgClr, "a:srgbClr");
6419
+ if (srgbClr) {
6420
+ const val = colorAttr(srgbClr, "val");
6421
+ if (val) result.foregroundColor = val;
6422
+ }
6423
+ }
6424
+ const bgClr = findChild(pattFill, "a:bgClr");
6425
+ if (bgClr) {
6426
+ const srgbClr = findChild(bgClr, "a:srgbClr");
6427
+ if (srgbClr) {
6428
+ const val = colorAttr(srgbClr, "val");
6429
+ if (val) result.backgroundColor = val;
6430
+ }
6431
+ }
6432
+ return result;
6433
+ }
6434
+ const blipFill = findChild(parent, "a:blipFill");
6435
+ if (blipFill) {
6436
+ if (findChild(blipFill, "a:blip")) return { type: "blip" };
6437
+ }
6030
6438
  const gradFill = findChild(parent, "a:gradFill");
6031
6439
  if (gradFill) {
6032
6440
  const stops = [];
@@ -6036,8 +6444,8 @@ function parseFillFromElement(parent) {
6036
6444
  const pos = attrNum(gs, "pos");
6037
6445
  const srgbClr = findChild(gs, "a:srgbClr");
6038
6446
  if (pos !== void 0 && srgbClr) stops.push({
6039
- position: pos / 1e5,
6040
- color: attr(srgbClr, "val") ?? ""
6447
+ position: pos / 1e3,
6448
+ color: colorAttr(srgbClr, "val") ?? ""
6041
6449
  });
6042
6450
  }
6043
6451
  if (stops.length > 0) {
@@ -6050,6 +6458,11 @@ function parseFillFromElement(parent) {
6050
6458
  const ang = attrNum(lin, "ang");
6051
6459
  if (ang !== void 0) result.angle = Math.round(ang / 6e4);
6052
6460
  }
6461
+ const pathEl = findChild(gradFill, "a:path");
6462
+ if (pathEl) {
6463
+ const pathType = attr(pathEl, "path");
6464
+ if (pathType) result.path = pathType;
6465
+ }
6053
6466
  return result;
6054
6467
  }
6055
6468
  }
@@ -6064,17 +6477,22 @@ function parseOutlineFromElement(parent) {
6064
6477
  if (solidFill) {
6065
6478
  const srgbClr = findChild(solidFill, "a:srgbClr");
6066
6479
  if (srgbClr) {
6067
- const val = attr(srgbClr, "val");
6480
+ const val = colorAttr(srgbClr, "val");
6068
6481
  if (val) opts.color = val;
6069
6482
  }
6070
6483
  }
6484
+ const prstDash = findChild(ln, "a:prstDash");
6485
+ if (prstDash) {
6486
+ const val = attr(prstDash, "val");
6487
+ if (val) opts.dashStyle = val;
6488
+ }
6071
6489
  return Object.keys(opts).length > 0 ? opts : void 0;
6072
6490
  }
6073
6491
  function parseEffectsFromElement(parent) {
6074
- const effectLst = findChild(findChild(parent, "p:spPr") ?? parent, "a:effectLst");
6075
- if (!effectLst) return void 0;
6492
+ const spPr = findChild(parent, "p:spPr") ?? parent;
6076
6493
  const opts = {};
6077
- for (const child of effectLst.elements ?? []) {
6494
+ const effectLst = findChild(spPr, "a:effectLst");
6495
+ if (effectLst) for (const child of effectLst.elements ?? []) {
6078
6496
  if (!child.name) continue;
6079
6497
  switch (child.name) {
6080
6498
  case "a:outerShdw": {
@@ -6129,6 +6547,10 @@ function parseEffectsFromElement(parent) {
6129
6547
  if (dist !== void 0) reflection.distance = dist;
6130
6548
  const dir = attrNum(child, "dir");
6131
6549
  if (dir !== void 0) reflection.direction = dir;
6550
+ const stA = attrNum(child, "stA");
6551
+ if (stA !== void 0) reflection.startAlpha = stA / 1e3;
6552
+ const endA = attrNum(child, "endA");
6553
+ if (endA !== void 0) reflection.endAlpha = endA / 1e3;
6132
6554
  opts.reflection = reflection;
6133
6555
  break;
6134
6556
  }
@@ -6139,6 +6561,63 @@ function parseEffectsFromElement(parent) {
6139
6561
  }
6140
6562
  }
6141
6563
  }
6564
+ const scene3d = findChild(spPr, "a:scene3d");
6565
+ if (scene3d) {
6566
+ const camera = findChild(scene3d, "a:camera");
6567
+ if (camera) {
6568
+ const rot = findChild(camera, "a:rot");
6569
+ if (rot) {
6570
+ const rotation3d = {};
6571
+ const lat = attrNum(rot, "lat");
6572
+ const lon = attrNum(rot, "lon");
6573
+ const rev = attrNum(rot, "rev");
6574
+ if (lat !== void 0) rotation3d.x = Math.round(lat / 6e4);
6575
+ if (lon !== void 0) rotation3d.y = Math.round(lon / 6e4);
6576
+ if (rev !== void 0) rotation3d.z = Math.round(rev / 6e4);
6577
+ const fov = attrNum(camera, "fov");
6578
+ if (fov !== void 0) rotation3d.perspective = fov;
6579
+ if (Object.keys(rotation3d).length > 0) opts.rotation3D = rotation3d;
6580
+ }
6581
+ }
6582
+ const lightRig = findChild(scene3d, "a:lightRig");
6583
+ if (lightRig) {
6584
+ const rig = attr(lightRig, "rig");
6585
+ if (rig) opts.lighting = rig;
6586
+ }
6587
+ }
6588
+ const sp3d = findChild(spPr, "a:sp3d");
6589
+ if (sp3d) {
6590
+ const bevelT = findChild(sp3d, "a:bevelT");
6591
+ if (bevelT) {
6592
+ const bevel = {};
6593
+ const w = attrNum(bevelT, "w");
6594
+ const h = attrNum(bevelT, "h");
6595
+ if (w !== void 0) bevel.width = Math.round(w / 12700);
6596
+ if (h !== void 0) bevel.height = Math.round(h / 12700);
6597
+ const prst = attr(bevelT, "prst");
6598
+ if (prst) bevel.preset = prst;
6599
+ if (Object.keys(bevel).length > 0) opts.bevelTop = bevel;
6600
+ }
6601
+ const bevelB = findChild(sp3d, "a:bevelB");
6602
+ if (bevelB) {
6603
+ const bevel = {};
6604
+ const w = attrNum(bevelB, "w");
6605
+ const h = attrNum(bevelB, "h");
6606
+ if (w !== void 0) bevel.width = Math.round(w / 12700);
6607
+ if (h !== void 0) bevel.height = Math.round(h / 12700);
6608
+ const prst = attr(bevelB, "prst");
6609
+ if (prst) bevel.preset = prst;
6610
+ if (Object.keys(bevel).length > 0) opts.bevelBottom = bevel;
6611
+ }
6612
+ const z = attrNum(sp3d, "z");
6613
+ if (z !== void 0) opts.depth = z;
6614
+ const contourW = attrNum(sp3d, "contourW");
6615
+ if (contourW !== void 0) opts.contourWidth = contourW;
6616
+ const extrusionH = attrNum(sp3d, "extrusionH");
6617
+ if (extrusionH !== void 0) opts.extrusionH = extrusionH;
6618
+ const prstMaterial = attr(sp3d, "prstMaterial");
6619
+ if (prstMaterial) opts.material = prstMaterial;
6620
+ }
6142
6621
  return Object.keys(opts).length > 0 ? opts : void 0;
6143
6622
  }
6144
6623
  /**
@@ -6147,7 +6626,7 @@ function parseEffectsFromElement(parent) {
6147
6626
  */
6148
6627
  function extractColorFromElement(el) {
6149
6628
  for (const child of el.elements ?? []) if (child.name === "a:srgbClr") {
6150
- const color = attr(child, "val");
6629
+ const color = colorAttr(child, "val");
6151
6630
  let alpha;
6152
6631
  for (const transform of child.elements ?? []) if (transform.name === "a:alpha") {
6153
6632
  const val = attrNum(transform, "val");
@@ -6209,6 +6688,97 @@ function imageTypeFromPath(path) {
6209
6688
  default: return "png";
6210
6689
  }
6211
6690
  }
6691
+ const VIDEO_EXT_URI = "{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}";
6692
+ const AUDIO_EXT_URI = "{CF1602FD-DB20-4165-A070-5F299619DA56}";
6693
+ /**
6694
+ * Check if a p:pic element is actually a video or audio frame
6695
+ * by looking for media extension URIs in nvPr > extLst.
6696
+ */
6697
+ function detectMediaType(el) {
6698
+ const nvPicPr = findChild(el, "p:nvPicPr");
6699
+ if (!nvPicPr) return void 0;
6700
+ const nvPr = findChild(nvPicPr, "p:nvPr");
6701
+ if (!nvPr) return void 0;
6702
+ const extLst = findChild(nvPr, "p:extLst");
6703
+ if (!extLst) return void 0;
6704
+ for (const ext of extLst.elements ?? []) {
6705
+ if (ext.name !== "p:ext") continue;
6706
+ const uri = attr(ext, "uri");
6707
+ if (uri === VIDEO_EXT_URI) return "video";
6708
+ if (uri === AUDIO_EXT_URI) return "audio";
6709
+ }
6710
+ }
6711
+ function parseMediaFrame(el, ctx, mediaKind) {
6712
+ const opts = {};
6713
+ const spPr = findChild(el, "p:spPr");
6714
+ if (spPr) parseTransformFromSpPr(spPr, opts);
6715
+ const nvPicPr = findChild(el, "p:nvPicPr");
6716
+ if (nvPicPr) {
6717
+ const cNvPr = findChild(nvPicPr, "a:cNvPr") ?? findChild(nvPicPr, "p:cNvPr");
6718
+ if (cNvPr) {
6719
+ const name = attr(cNvPr, "name");
6720
+ if (name) opts.name = name;
6721
+ }
6722
+ }
6723
+ const mediaFileEl = findDeep(el, "a:videoFile")[0] ?? findDeep(el, "a:audioFile")[0];
6724
+ const rLink = mediaFileEl ? attr(mediaFileEl, "r:link") : void 0;
6725
+ const p14media = !mediaFileEl ? findDeep(el, "p14:media")[0] : void 0;
6726
+ const rEmbed = p14media ? attr(p14media, "r:embed") : void 0;
6727
+ const mediaRef = rLink ?? rEmbed;
6728
+ if (mediaRef) {
6729
+ const mediaPath = ctx.slideRels.get(mediaRef);
6730
+ if (mediaPath) {
6731
+ const data = ctx.pptx.doc.getRaw(mediaPath);
6732
+ if (data) {
6733
+ opts.data = data;
6734
+ opts.type = mediaTypeFromPath(mediaPath, mediaKind);
6735
+ }
6736
+ }
6737
+ }
6738
+ if (mediaKind === "video") {
6739
+ const blipFill = findChild(el, "p:blipFill");
6740
+ if (blipFill) {
6741
+ const posterBlip = findChild(blipFill, "a:blip");
6742
+ if (posterBlip) {
6743
+ const rEmbed = attr(posterBlip, "r:embed");
6744
+ if (rEmbed) {
6745
+ const posterPath = ctx.slideRels.get(rEmbed);
6746
+ if (posterPath) {
6747
+ const posterData = ctx.pptx.doc.getRaw(posterPath);
6748
+ if (posterData) {
6749
+ opts.poster = posterData;
6750
+ opts.posterType = imageTypeFromPath(posterPath);
6751
+ }
6752
+ }
6753
+ }
6754
+ }
6755
+ }
6756
+ }
6757
+ return opts;
6758
+ }
6759
+ function mediaTypeFromPath(path, kind) {
6760
+ const ext = path.split(".").pop()?.toLowerCase() ?? "";
6761
+ if (kind === "video") switch (ext) {
6762
+ case "mp4": return "mp4";
6763
+ case "mov":
6764
+ case "qt": return "mov";
6765
+ case "wmv": return "wmv";
6766
+ case "avi": return "avi";
6767
+ default: return "mp4";
6768
+ }
6769
+ else switch (ext) {
6770
+ case "mp3": return "mp3";
6771
+ case "wav": return "wav";
6772
+ case "wma": return "wma";
6773
+ case "aac": return "aac";
6774
+ default: return "mp3";
6775
+ }
6776
+ }
6777
+ /**
6778
+ * Parse a:blipFill from a shape's spPr.
6779
+ * Used when a shape has an image fill (not a picture element).
6780
+ * Returns { type: "blip", data } if found.
6781
+ */
6212
6782
  //#endregion
6213
6783
  //#region src/parse/slide-layout.ts
6214
6784
  const NAME_TO_TYPE = {
@@ -6255,7 +6825,7 @@ const COLOR_MAP = {
6255
6825
  };
6256
6826
  function extractColor(el) {
6257
6827
  const srgb = findChild(el, "a:srgbClr");
6258
- if (srgb) return attr(srgb, "val") ?? void 0;
6828
+ if (srgb) return colorAttr(srgb, "val") ?? void 0;
6259
6829
  const sysClr = findChild(el, "a:sysClr");
6260
6830
  if (sysClr) return attr(sysClr, "lastClr") ?? void 0;
6261
6831
  }
@@ -6361,7 +6931,7 @@ function parseSlideRels(doc, slidePaths, refs) {
6361
6931
  }
6362
6932
  }
6363
6933
  function parsePptx(data) {
6364
- const doc = parseArchive(data);
6934
+ const doc = parseArchive(toUint8Array(data));
6365
6935
  const presentation = doc.get("ppt/presentation.xml");
6366
6936
  const relsXml = doc.get("ppt/_rels/presentation.xml.rels");
6367
6937
  const slides = [];
@@ -6437,7 +7007,8 @@ function parseSlideRelMap(doc, slidePath) {
6437
7007
  const id = attr(child, "Id") ?? "";
6438
7008
  const target = attr(child, "Target") ?? "";
6439
7009
  if (!id || !target) continue;
6440
- rels.set(id, resolveRelsPath(target));
7010
+ if (attr(child, "TargetMode") === "External") rels.set(id, target);
7011
+ else rels.set(id, resolveRelsPath(target));
6441
7012
  }
6442
7013
  return rels;
6443
7014
  }
@@ -6520,6 +7091,24 @@ function parsePresentation(data) {
6520
7091
  const bg = cSld ? findChild(cSld, "p:bg") : void 0;
6521
7092
  const masterBackground = bg ? parseBackground(bg) : void 0;
6522
7093
  const hasBackground = masterBackground && Object.keys(masterBackground).length > 0;
7094
+ const spTree = cSld ? findChild(cSld, "p:spTree") : void 0;
7095
+ const masterChildren = [];
7096
+ if (spTree) {
7097
+ const emptyCtx = {
7098
+ pptx,
7099
+ slideRels: /* @__PURE__ */ new Map()
7100
+ };
7101
+ for (const child of spTree.elements ?? []) {
7102
+ if (child.name === "p:nvGrpSpPr" || child.name === "p:grpSpPr") continue;
7103
+ if (child.name === "p:sp") {
7104
+ const nvSpPr = findChild(child, "p:nvSpPr");
7105
+ const nvPr = nvSpPr ? findChild(nvSpPr, "p:nvPr") : void 0;
7106
+ if (nvPr && findChild(nvPr, "p:ph")) continue;
7107
+ }
7108
+ const parsed = parseSlideChild(child, emptyCtx);
7109
+ if (parsed !== void 0) masterChildren.push(parsed);
7110
+ }
7111
+ }
6523
7112
  const masterLayouts = [];
6524
7113
  for (const layoutPath of pptx.slideLayouts) {
6525
7114
  if (layoutMasterPaths.get(layoutPath) !== masterPath) continue;
@@ -6531,16 +7120,32 @@ function parsePresentation(data) {
6531
7120
  masterDef.name = masterName;
6532
7121
  if (themeOptions) masterDef.theme = themeOptions;
6533
7122
  if (hasBackground) masterDef.background = masterBackground;
7123
+ if (masterChildren.length > 0) masterDef.children = masterChildren;
6534
7124
  if (masterLayouts.length > 0) masterDef.layouts = masterLayouts;
6535
7125
  masterDefs.push(masterDef);
6536
7126
  }
6537
7127
  if (masterCount > 1) opts.masters = masterDefs;
7128
+ const commentAuthors = /* @__PURE__ */ new Map();
7129
+ if (pptx.partRefs.commentAuthors) {
7130
+ const authorsEl = pptx.doc.get(pptx.partRefs.commentAuthors);
7131
+ if (authorsEl) for (const child of authorsEl.elements ?? []) {
7132
+ if (child.name !== "p:cmAuthor") continue;
7133
+ const id = attrNum(child, "id");
7134
+ const name = attr(child, "name");
7135
+ const initials = attr(child, "initials");
7136
+ if (id !== void 0) commentAuthors.set(id, {
7137
+ name: name ?? "",
7138
+ initials: initials ?? ""
7139
+ });
7140
+ }
7141
+ }
6538
7142
  const result = [];
6539
7143
  for (let si = 0; si < pptx.slides.length; si++) {
6540
7144
  const slidePath = pptx.slides[si];
6541
7145
  const slideEl = pptx.doc.get(slidePath);
6542
7146
  if (!slideEl) continue;
6543
- const slideOpts = parseSlide(slideEl, new ParseContext(pptx, parseSlideRelMap(pptx.doc, slidePath)));
7147
+ const slideRels = parseSlideRelMap(pptx.doc, slidePath);
7148
+ const slideOpts = parseSlide(slideEl, new ParseContext(pptx, slideRels));
6544
7149
  const layoutPath = slideLayoutPaths.get(slidePath);
6545
7150
  if (layoutPath) {
6546
7151
  const layoutEl = pptx.doc.get(layoutPath);
@@ -6551,11 +7156,58 @@ function parsePresentation(data) {
6551
7156
  if (masterIdx >= 0 && masterDefs[masterIdx]) slideOpts.master = masterDefs[masterIdx].name;
6552
7157
  }
6553
7158
  }
7159
+ for (const [, relPath] of slideRels) {
7160
+ if (!relPath.includes("/comments/")) continue;
7161
+ const commentsEl = pptx.doc.get(relPath);
7162
+ if (!commentsEl) continue;
7163
+ const comments = [];
7164
+ for (const cm of commentsEl.elements ?? []) {
7165
+ if (cm.name !== "p:cm") continue;
7166
+ const authorId = attrNum(cm, "authorId");
7167
+ const dt = attr(cm, "dt");
7168
+ const idx = attrNum(cm, "idx");
7169
+ const author = authorId !== void 0 ? commentAuthors.get(authorId) : void 0;
7170
+ const pos = findChild(cm, "p:pos");
7171
+ const x = pos ? attrNum(pos, "x") : void 0;
7172
+ const y = pos ? attrNum(pos, "y") : void 0;
7173
+ const textEl = findChild(cm, "p:text");
7174
+ const txBody = findChild(cm, "p:txBody");
7175
+ const text = textEl ? textOf(textEl) ?? "" : txBody ? extractCommentText(txBody) : "";
7176
+ const commentEntry = {};
7177
+ if (authorId !== void 0) commentEntry.authorId = authorId;
7178
+ if (author) commentEntry.author = author.name;
7179
+ if (idx !== void 0) commentEntry.idx = idx;
7180
+ if (dt) commentEntry.date = dt;
7181
+ if (x !== void 0) commentEntry.x = x;
7182
+ if (y !== void 0) commentEntry.y = y;
7183
+ if (text) commentEntry.text = text;
7184
+ comments.push(commentEntry);
7185
+ }
7186
+ if (comments.length > 0) slideOpts.comments = comments;
7187
+ break;
7188
+ }
6554
7189
  result.push(slideOpts);
6555
7190
  }
6556
7191
  opts.slides = result;
6557
7192
  return opts;
6558
7193
  }
7194
+ /**
7195
+ * Extract plain text from a p:txBody in a comment element.
7196
+ */
7197
+ function extractCommentText(txBody) {
7198
+ const parts = [];
7199
+ for (const p of txBody.elements ?? []) {
7200
+ if (p.name !== "a:p") continue;
7201
+ for (const r of p.elements ?? []) {
7202
+ if (r.name !== "a:r") continue;
7203
+ for (const t of r.elements ?? []) if (t.name === "a:t") {
7204
+ const text = textOf(t);
7205
+ if (text) parts.push(text);
7206
+ }
7207
+ }
7208
+ }
7209
+ return parts.join("");
7210
+ }
6559
7211
  __reExport(/* @__PURE__ */ __exportAll({
6560
7212
  AppProperties: () => AppProperties,
6561
7213
  AudioFrame: () => AudioFrame,