@office-open/pptx 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  import { n as __reExport, r as __require, t as __exportAll } from "./_chunks/chunk-C8fdooHg.mjs";
2
- import { AppProperties, BaseXmlComponent, BuilderElement, Formatter, ImportedXmlComponent, NextAttributeComponent, RawPassthrough, Relationships, StringContainer, XmlComponent, chartAttr, convertEmuToInches as emusToInches, convertEmuToPixels as emusToPixels, convertEmuToPoints as emusToPoints, convertInchesToEmu as inchesToEmus, convertPixelsToEmu as pixelsToEmus, convertPointsToEmu as pointsToEmus, getImageType, hashedId, isRaw, parseCoreProperties, parseRels, readAllXmlParts, readXmlFromZip, uint8ToBase64, uniqueId, uniqueNumericIdCreator, uniqueUuid, unzipToMap, wrapEl } from "@office-open/core";
2
+ import { AppProperties, BaseXmlComponent, BuilderElement, Formatter, ImportedXmlComponent, NextAttributeComponent, RawPassthrough, Relationships, StringContainer, XmlComponent, chartAttr, collectPlaceholderKeys, convertEmuToInches as emusToInches, convertEmuToPixels as emusToPixels, convertEmuToPoints as emusToPoints, convertInchesToEmu as inchesToEmus, convertPixelsToEmu as pixelsToEmus, convertPointsToEmu as pointsToEmus, getImageType, hasPlaceholders, hashedId, isRaw, parseCoreProperties, parseRels, readAllXmlParts, readXmlFromZip, uint8ToBase64, uniqueId, uniqueNumericIdCreator, uniqueUuid, unzipToMap, wrapEl } from "@office-open/core";
3
3
  import { ChartCollection, ChartTitle, createChartType } from "@office-open/core/chart";
4
+ import { attr, attrBool, attrNum, attrs, children, escapeXml, findChild, findDeep, textOf, xml } from "@office-open/xml";
4
5
  import { BevelPresetType, CompoundLine, LineCap, LineJoin, PathShadeType, PenAlignment, PresetDash, PresetMaterialType, TileFlipMode, buildFill, createBevel, createBottomBevel, createColorElement, createColorTransforms, createEffectList, createGradientFill, createGradientStop, createOutline, createOutline as createOutline$1, createScene3D, createShape3D, extractBlipFillMedia } from "@office-open/core/drawingml";
5
6
  import { COLOR_CATEGORIES, LAYOUT_CATEGORIES, STYLE_CATEGORIES, SmartArtCollection, createDataModel } from "@office-open/core/smartart";
6
7
  import { Readable } from "stream";
7
8
  import { Zip, ZipDeflate, ZipPassThrough, zipSync } from "fflate";
8
- import { attr, attrBool, attrNum, children, findChild, findDeep, textOf, xml } from "@office-open/xml";
9
9
  export * from "@office-open/core/values";
10
10
  //#region src/file/content-types/content-types.ts
11
11
  /**
@@ -378,6 +378,9 @@ var GroupShapeNonVisualProperties = class extends BuilderElement {
378
378
  function buildEndParagraphRunProperties(lang = "en-US") {
379
379
  return { "a:endParaRPr": { _attr: { lang } } };
380
380
  }
381
+ function buildEndParagraphRunPropertiesXml(lang = "en-US") {
382
+ return `<a:endParaRPr${attrs({ lang })}/>`;
383
+ }
381
384
  /**
382
385
  * a:endParaRPr — End paragraph run properties.
383
386
  * Lazy: stores lang, builds XML object in prepForXml.
@@ -458,7 +461,48 @@ var ParagraphProperties = class extends XmlComponent {
458
461
  prepForXml(_context) {
459
462
  return buildParagraphProperties(this.options);
460
463
  }
464
+ toXml() {
465
+ return buildParagraphPropertiesXml(this.options);
466
+ }
461
467
  };
468
+ function buildBulletChildrenXml(options) {
469
+ if (options.type === "none") return "<a:buNone/>";
470
+ let s = "";
471
+ if (options.color) s += `<a:buClr><a:srgbClr${attrs({ val: options.color.replace("#", "") })}/></a:buClr>`;
472
+ if (options.size !== void 0) s += `<a:buSzPct${attrs({ val: `${options.size}%` })}/>`;
473
+ s += `<a:buFont${attrs({
474
+ typeface: "Arial",
475
+ panose: "020B0604020202020204",
476
+ pitchFamily: "34",
477
+ charset: "0"
478
+ })}/>`;
479
+ if (options.type === "char") s += `<a:buChar${attrs({ char: options.char ?? "•" })}/>`;
480
+ else if (options.type === "autoNum") {
481
+ const buAttrs = { type: options.format ?? "arabicPeriod" };
482
+ if (options.startAt !== void 0) buAttrs.startAt = options.startAt;
483
+ s += `<a:buAutoNum${attrs(buAttrs)}/>`;
484
+ }
485
+ return s;
486
+ }
487
+ function buildParagraphPropertiesXml(options) {
488
+ const attrStr = attrs({
489
+ algn: options.alignment ? TextAlignment[options.alignment] : void 0,
490
+ lvl: options.indentLevel,
491
+ marL: options.marginIndent,
492
+ marR: options.marginRight,
493
+ defTabSz: options.defTabSize
494
+ });
495
+ const body = [];
496
+ if (options.lineSpacing !== void 0) body.push(`<a:lnSpc><a:spcPct${attrs({ val: options.lineSpacing * 1e3 })}/></a:lnSpc>`);
497
+ if (options.lineSpacingPoints !== void 0) body.push(`<a:lnSpc><a:spcPts${attrs({ val: options.lineSpacingPoints * 100 })}/></a:lnSpc>`);
498
+ if (options.marginBottom !== void 0 || options.marginTop !== void 0) body.push(`<a:spcAft><a:spcPts${attrs({ val: options.marginBottom ?? 0 })}/></a:spcAft>`);
499
+ if (options.marginTop !== void 0) body.push(`<a:spcBef><a:spcPts${attrs({ val: options.marginTop })}/></a:spcBef>`);
500
+ if (options.bullet) body.push(buildBulletChildrenXml(options.bullet));
501
+ else if (options.bulletNone !== false) body.push("<a:buNone/>");
502
+ if (!attrStr && body.length === 0) return "";
503
+ if (body.length === 0) return `<a:pPr${attrStr}/>`;
504
+ return `<a:pPr${attrStr}>${body.join("")}</a:pPr>`;
505
+ }
462
506
  //#endregion
463
507
  //#region src/file/shape/paragraph/run-properties.ts
464
508
  let nextHyperlinkId = 1;
@@ -535,7 +579,48 @@ var RunProperties = class extends XmlComponent {
535
579
  if (opts.fill !== void 0) fillObj = buildFill(opts.fill).prepForXml(context) ?? void 0;
536
580
  return buildRunProperties(opts, hyperlinkKey, fillObj);
537
581
  }
582
+ toXml(context) {
583
+ const opts = this.options;
584
+ let hyperlinkKey;
585
+ if (opts.hyperlink) {
586
+ hyperlinkKey = `hlink_${nextHyperlinkId++}`;
587
+ context.fileData?.Hyperlinks?.addHyperlink(hyperlinkKey, opts.hyperlink.url, opts.hyperlink.tooltip);
588
+ }
589
+ let fillObj;
590
+ if (opts.fill !== void 0) fillObj = buildFill(opts.fill).prepForXml(context) ?? void 0;
591
+ return buildRunPropertiesXml(opts, hyperlinkKey, fillObj);
592
+ }
538
593
  };
594
+ /**
595
+ * String version of buildRunProperties for zero-allocation serialization.
596
+ */
597
+ function buildRunPropertiesXml(options, hyperlinkKey, fillObject) {
598
+ const a = {};
599
+ if (options.fontSize) a.sz = options.fontSize * 100;
600
+ if (options.bold !== void 0) a.b = options.bold;
601
+ if (options.italic !== void 0) a.i = options.italic;
602
+ if (options.underline) a.u = UnderlineStyle[options.underline];
603
+ if (options.lang) a.lang = options.lang;
604
+ if (options.strike) a.strike = StrikeStyle[options.strike];
605
+ if (options.baseline !== void 0) a.baseline = options.baseline;
606
+ if (options.capitalization) a.cap = TextCapitalization[options.capitalization] ?? options.capitalization;
607
+ if (options.spacing !== void 0) a.spc = options.spacing;
608
+ if (options.noProof !== void 0) a.noProof = options.noProof;
609
+ if (options.dirty !== void 0) a.dirty = options.dirty;
610
+ const attrStr = attrs(a);
611
+ const body = [];
612
+ if (options.font) body.push(`<a:latin${attrs({ typeface: options.font })}/><a:ea${attrs({ typeface: options.font })}/>`);
613
+ if (options.hyperlink && hyperlinkKey) {
614
+ const h = { "r:id": `{hlink:${hyperlinkKey}}` };
615
+ if (options.hyperlink.tooltip) h.tooltip = options.hyperlink.tooltip;
616
+ body.push(`<a:hlinkClick${attrs(h)}/>`);
617
+ }
618
+ if (options.rightToLeft !== void 0) body.push(`<a:rtl${attrs({ val: options.rightToLeft ? 1 : 0 })}/>`);
619
+ if (fillObject) body.push(xml(fillObject));
620
+ if (!attrStr && body.length === 0) return "";
621
+ if (body.length === 0) return `<a:rPr${attrStr}/>`;
622
+ return `<a:rPr${attrStr}>${body.join("")}</a:rPr>`;
623
+ }
539
624
  //#endregion
540
625
  //#region src/file/shape/paragraph/run.ts
541
626
  /**
@@ -557,6 +642,16 @@ var Run = class extends XmlComponent {
557
642
  if (this.options.text) children.push({ "a:t": [this.options.text] });
558
643
  return { "a:r": children.length === 0 ? {} : children.length === 1 && "_attr" in children[0] ? children[0] : children };
559
644
  }
645
+ toXml(context) {
646
+ let s = "<a:r>";
647
+ if (RunProperties.hasProperties(this.options)) {
648
+ const rp = new RunProperties(this.options);
649
+ s += rp.toXml(context);
650
+ }
651
+ if (this.options.text) s += `<a:t>${escapeXml(this.options.text)}</a:t>`;
652
+ s += "</a:r>";
653
+ return s;
654
+ }
560
655
  };
561
656
  //#endregion
562
657
  //#region src/file/shape/paragraph/paragraph.ts
@@ -581,6 +676,15 @@ var Paragraph = class extends XmlComponent {
581
676
  children.push(buildEndParagraphRunProperties());
582
677
  return { "a:p": children };
583
678
  }
679
+ toXml(context) {
680
+ let s = "<a:p>";
681
+ const pPr = buildParagraphPropertiesXml(this.options.properties ?? {});
682
+ if (pPr) s += pPr;
683
+ if (this.options.children) for (const child of this.options.children) s += child.toXml(context);
684
+ s += buildEndParagraphRunPropertiesXml();
685
+ s += "</a:p>";
686
+ return s;
687
+ }
584
688
  };
585
689
  //#endregion
586
690
  //#region src/file/table/table-cell-properties.ts
@@ -697,6 +801,25 @@ function buildBodyPr(options) {
697
801
  bodyPrContent.push(...bodyPrChildren);
698
802
  return { "a:bodyPr": bodyPrContent.length === 1 && "_attr" in bodyPrContent[0] ? bodyPrContent[0] : bodyPrContent.length > 0 ? bodyPrContent : {} };
699
803
  }
804
+ function buildBodyPrXml(options) {
805
+ let s = "<a:bodyPr";
806
+ const a = {};
807
+ if (options.vertical) a.vert = options.vertical;
808
+ if (options.anchor) a.anchor = VerticalAlignment[options.anchor];
809
+ if (options.wrap) a.wrap = options.wrap;
810
+ if (options.margins?.top !== void 0) a.tIns = options.margins.top;
811
+ if (options.margins?.bottom !== void 0) a.bIns = options.margins.bottom;
812
+ if (options.margins?.left !== void 0) a.lIns = options.margins.left;
813
+ if (options.margins?.right !== void 0) a.rIns = options.margins.right;
814
+ if (options.columns !== void 0) a.numCol = options.columns;
815
+ if (options.columnSpacing !== void 0) a.spcCol = options.columnSpacing * 100;
816
+ s += attrs(a);
817
+ let inner = "";
818
+ if (options.autoFit === "normal") inner += "<a:normAutofit/>";
819
+ else if (options.autoFit === "shape") inner += "<a:spAutoFit/>";
820
+ else if (options.autoFit === "none") inner += "<a:noAutofit/>";
821
+ return inner ? `${s}>${inner}</a:bodyPr>` : `${s}/>`;
822
+ }
700
823
  /**
701
824
  * p:txBody — Text body within a shape.
702
825
  * Lazy: stores options, builds XML object in prepForXml.
@@ -721,6 +844,18 @@ var TextBody = class extends XmlComponent {
721
844
  }
722
845
  return { "p:txBody": children };
723
846
  }
847
+ toXml(context) {
848
+ let s = "<p:txBody>";
849
+ s += buildBodyPrXml(this.options);
850
+ s += "<a:lstStyle/>";
851
+ if (this.options.paragraphs) for (const p of this.options.paragraphs) {
852
+ const para = typeof p === "string" ? new Paragraph({ children: [new Run({ text: p })] }) : p;
853
+ s += para.toXml(context);
854
+ }
855
+ else s += new Paragraph().toXml(context);
856
+ s += "</p:txBody>";
857
+ return s;
858
+ }
724
859
  };
725
860
  //#endregion
726
861
  //#region src/file/notes/notes-slide.ts
@@ -931,7 +1066,7 @@ var PresentationProperties = class PresentationProperties extends ImportedXmlCom
931
1066
  };
932
1067
  //#endregion
933
1068
  //#region src/file/presentation/presentation.ts
934
- const DEFAULT_TEXT_STYLE_OBJ = ImportedXmlComponent.fromXmlString(`<p:defaultTextStyle xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
1069
+ const DEFAULT_TEXT_STYLE_XML = `<p:defaultTextStyle xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
935
1070
  <a:defPPr><a:defRPr/></a:defPPr>
936
1071
  <a:lvl1pPr marL="0" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
937
1072
  <a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr>
@@ -960,7 +1095,8 @@ const DEFAULT_TEXT_STYLE_OBJ = ImportedXmlComponent.fromXmlString(`<p:defaultTex
960
1095
  <a:lvl9pPr marL="3657600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
961
1096
  <a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr>
962
1097
  </a:lvl9pPr>
963
- </p:defaultTextStyle>`).prepForXml({ stack: [] });
1098
+ </p:defaultTextStyle>`;
1099
+ const DEFAULT_TEXT_STYLE_OBJ = ImportedXmlComponent.fromXmlString(DEFAULT_TEXT_STYLE_XML).prepForXml({ stack: [] });
964
1100
  /**
965
1101
  * p:presentation — Root element of a PPTX file.
966
1102
  * Lazy: stores options, builds XML object directly in prepForXml.
@@ -1002,6 +1138,22 @@ var Presentation = class extends BaseXmlComponent {
1002
1138
  children.push(DEFAULT_TEXT_STYLE_OBJ);
1003
1139
  return { "p:presentation": children };
1004
1140
  }
1141
+ toXml(_context) {
1142
+ const opts = this.options;
1143
+ const cx = opts.slideWidth ?? 9144e3;
1144
+ const cy = opts.slideHeight ?? 6858e3;
1145
+ const typeAttr = cx === 914400 && cy === 6858e3 ? " type=\"screen4x3\"" : "";
1146
+ let s = `<p:presentation xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main">`;
1147
+ s += "<p:sldMasterIdLst><p:sldMasterId id=\"2147483648\" r:id=\"rId1\"/></p:sldMasterIdLst>";
1148
+ s += "<p:sldIdLst>";
1149
+ for (let i = 0; i < opts.slideIds.length; i++) s += `<p:sldId id="${opts.slideIds[i]}" r:id="rId${i + 2}"/>`;
1150
+ s += "</p:sldIdLst>";
1151
+ s += `<p:sldSz cx="${cx}" cy="${cy}"${typeAttr}/>`;
1152
+ s += "<p:notesSz cx=\"6858000\" cy=\"9144000\"/>";
1153
+ s += DEFAULT_TEXT_STYLE_XML;
1154
+ s += "</p:presentation>";
1155
+ return s;
1156
+ }
1005
1157
  };
1006
1158
  //#endregion
1007
1159
  //#region src/file/presentation/presentation-wrapper.ts
@@ -2238,6 +2390,49 @@ var Shape = class Shape extends XmlComponent {
2238
2390
  if (txBodyObj) children.push(txBodyObj);
2239
2391
  return { "p:sp": children };
2240
2392
  }
2393
+ toXml(context) {
2394
+ const opts = this.options;
2395
+ const id = this.shapeId;
2396
+ const name = escapeXml(opts.name ?? `Shape ${id}`);
2397
+ let s = "<p:sp><p:nvSpPr>";
2398
+ s += `<p:cNvPr${attrs({
2399
+ id,
2400
+ name
2401
+ })}/>`;
2402
+ s += "<p:cNvSpPr/>";
2403
+ if (opts.placeholder) {
2404
+ const phAttrs = { type: opts.placeholder };
2405
+ if (opts.placeholderIndex !== void 0) phAttrs.idx = opts.placeholderIndex;
2406
+ s += `<p:nvPr><p:ph${attrs(phAttrs)}/></p:nvPr>`;
2407
+ } else s += "<p:nvPr/>";
2408
+ s += "</p:nvSpPr>";
2409
+ const spPrObj = new ShapeProperties({
2410
+ x: opts.x !== void 0 ? pixelsToEmus(opts.x) : void 0,
2411
+ y: opts.y !== void 0 ? pixelsToEmus(opts.y) : void 0,
2412
+ width: opts.width !== void 0 ? pixelsToEmus(opts.width) : void 0,
2413
+ height: opts.height !== void 0 ? pixelsToEmus(opts.height) : void 0,
2414
+ geometry: opts.geometry,
2415
+ fill: opts.fill,
2416
+ outline: opts.outline,
2417
+ effects: opts.effects,
2418
+ flipH: opts.flipH,
2419
+ rotation: opts.rotation
2420
+ }).prepForXml(context);
2421
+ if (spPrObj) s += xml(spPrObj);
2422
+ const txBodyOpts = {
2423
+ paragraphs: opts.paragraphs ?? (opts.text ? [new Paragraph({ children: [new Run({ text: opts.text })] })] : void 0),
2424
+ vertical: opts.textVertical,
2425
+ anchor: opts.textAnchor,
2426
+ autoFit: opts.textAutoFit,
2427
+ wrap: opts.textWrap,
2428
+ margins: opts.textMargins,
2429
+ columns: opts.textColumns,
2430
+ columnSpacing: opts.textColumnSpacing
2431
+ };
2432
+ s += new TextBody(txBodyOpts).toXml(context);
2433
+ s += "</p:sp>";
2434
+ return s;
2435
+ }
2241
2436
  };
2242
2437
  //#endregion
2243
2438
  //#region src/file/transition/transition.ts
@@ -2289,47 +2484,10 @@ var Transition = class extends BaseXmlComponent {
2289
2484
  };
2290
2485
  //#endregion
2291
2486
  //#region src/file/slide/slide.ts
2292
- /**
2293
- * p:nvGrpSpPr singleton non-visual properties for shape tree.
2294
- */
2295
- const NV_GRP_SP_PR = { "p:nvGrpSpPr": [
2296
- { "p:cNvPr": { _attr: {
2297
- id: 1,
2298
- name: ""
2299
- } } },
2300
- { "p:cNvGrpSpPr": {} },
2301
- { "p:nvPr": {} }
2302
- ] };
2303
- /**
2304
- * p:grpSpPr singleton — group shape properties with default transform.
2305
- */
2306
- const GRP_SP_PR = { "p:grpSpPr": { "a:xfrm": [
2307
- { "a:off": { _attr: {
2308
- x: 0,
2309
- y: 0
2310
- } } },
2311
- { "a:ext": { _attr: {
2312
- cx: 0,
2313
- cy: 0
2314
- } } },
2315
- { "a:chOff": { _attr: {
2316
- x: 0,
2317
- y: 0
2318
- } } },
2319
- { "a:chExt": { _attr: {
2320
- cx: 0,
2321
- cy: 0
2322
- } } }
2323
- ] } };
2324
- /**
2325
- * p:clrMapOvr singleton — color map override.
2326
- */
2327
- const CLR_MAP_OVR = { "p:clrMapOvr": [{ "a:masterClrMapping": {} }] };
2328
- const XMLNS_ATTRS = { _attr: {
2329
- "xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
2330
- "xmlns:r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
2331
- "xmlns:p": "http://schemas.openxmlformats.org/presentationml/2006/main"
2332
- } };
2487
+ const NV_GRP_SP_PR = "<p:nvGrpSpPr><p:cNvPr id=\"1\" name=\"\"/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr>";
2488
+ const GRP_SP_PR = "<p:grpSpPr><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\"0\" cy=\"0\"/><a:chOff x=\"0\" y=\"0\"/><a:chExt cx=\"0\" cy=\"0\"/></a:xfrm></p:grpSpPr>";
2489
+ const CLR_MAP_OVR = "<p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr>";
2490
+ const XMLNS = " xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\"";
2333
2491
  function collectAnimations(children) {
2334
2492
  const entries = [];
2335
2493
  for (const child of children) if (child instanceof Shape) {
@@ -2359,20 +2517,48 @@ var Slide = class extends BaseXmlComponent {
2359
2517
  }
2360
2518
  prepForXml(context) {
2361
2519
  const children = [];
2362
- children.push(XMLNS_ATTRS);
2520
+ children.push({ _attr: {
2521
+ "xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
2522
+ "xmlns:r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
2523
+ "xmlns:p": "http://schemas.openxmlformats.org/presentationml/2006/main"
2524
+ } });
2363
2525
  const cSldChildren = [];
2364
2526
  if (this.background) {
2365
2527
  const bgObj = this.background.prepForXml(context);
2366
2528
  if (bgObj) cSldChildren.push(bgObj);
2367
2529
  }
2368
- const spTreeChildren = [NV_GRP_SP_PR, GRP_SP_PR];
2530
+ const spTreeChildren = [{ "p:nvGrpSpPr": [
2531
+ { "p:cNvPr": { _attr: {
2532
+ id: 1,
2533
+ name: ""
2534
+ } } },
2535
+ { "p:cNvGrpSpPr": {} },
2536
+ { "p:nvPr": {} }
2537
+ ] }, { "p:grpSpPr": { "a:xfrm": [
2538
+ { "a:off": { _attr: {
2539
+ x: 0,
2540
+ y: 0
2541
+ } } },
2542
+ { "a:ext": { _attr: {
2543
+ cx: 0,
2544
+ cy: 0
2545
+ } } },
2546
+ { "a:chOff": { _attr: {
2547
+ x: 0,
2548
+ y: 0
2549
+ } } },
2550
+ { "a:chExt": { _attr: {
2551
+ cx: 0,
2552
+ cy: 0
2553
+ } } }
2554
+ ] } }];
2369
2555
  for (const child of this.children) {
2370
2556
  const obj = child.prepForXml(context);
2371
2557
  if (obj) spTreeChildren.push(obj);
2372
2558
  }
2373
2559
  cSldChildren.push({ "p:spTree": spTreeChildren });
2374
2560
  children.push({ "p:cSld": cSldChildren });
2375
- children.push(CLR_MAP_OVR);
2561
+ children.push({ "p:clrMapOvr": [{ "a:masterClrMapping": {} }] });
2376
2562
  if (this.transition) {
2377
2563
  const transObj = buildTransition(this.transition);
2378
2564
  if (transObj) children.push(transObj);
@@ -2384,6 +2570,35 @@ var Slide = class extends BaseXmlComponent {
2384
2570
  }
2385
2571
  return { "p:sld": children };
2386
2572
  }
2573
+ toXml(context) {
2574
+ let s = `<p:sld${XMLNS}>`;
2575
+ s += "<p:cSld>";
2576
+ if (this.background) {
2577
+ const bgObj = this.background.prepForXml(context);
2578
+ if (bgObj) s += xml(bgObj);
2579
+ }
2580
+ s += "<p:spTree>";
2581
+ s += NV_GRP_SP_PR;
2582
+ s += GRP_SP_PR;
2583
+ for (const child of this.children) if (typeof child.toXml === "function") s += child.toXml(context);
2584
+ else {
2585
+ const obj = child.prepForXml(context);
2586
+ if (obj) s += xml(obj);
2587
+ }
2588
+ s += "</p:spTree></p:cSld>";
2589
+ s += CLR_MAP_OVR;
2590
+ if (this.transition) {
2591
+ const transObj = buildTransition(this.transition);
2592
+ if (transObj) s += xml(transObj);
2593
+ }
2594
+ const animations = collectAnimations(this.children);
2595
+ if (animations.length > 0) {
2596
+ const timingObj = new SlideTiming(animations).prepForXml(context);
2597
+ if (timingObj) s += xml(timingObj);
2598
+ }
2599
+ s += "</p:sld>";
2600
+ return s;
2601
+ }
2387
2602
  };
2388
2603
  //#endregion
2389
2604
  //#region src/file/table-styles.ts
@@ -4412,38 +4627,23 @@ var Compiler = class {
4412
4627
  }
4413
4628
  };
4414
4629
  mapping["Theme"] = {
4415
- data: xml(this.formatter.format(file.Theme, context), {
4416
- declaration,
4417
- indent
4418
- }),
4630
+ data: this.formatter.formatToXml(file.Theme, context, declaration),
4419
4631
  path: "ppt/theme/theme1.xml"
4420
4632
  };
4421
4633
  mapping["TableStyles"] = {
4422
- data: xml(this.formatter.format(file.TableStyles, context), {
4423
- declaration,
4424
- indent
4425
- }),
4634
+ data: this.formatter.formatToXml(file.TableStyles, context, declaration),
4426
4635
  path: "ppt/tableStyles.xml"
4427
4636
  };
4428
4637
  mapping["PresProps"] = {
4429
- data: xml(this.formatter.format(file.PresProps, context), {
4430
- declaration,
4431
- indent
4432
- }),
4638
+ data: this.formatter.formatToXml(file.PresProps, context, declaration),
4433
4639
  path: "ppt/presProps.xml"
4434
4640
  };
4435
4641
  mapping["ViewProps"] = {
4436
- data: xml(this.formatter.format(file.ViewProps, context), {
4437
- declaration,
4438
- indent
4439
- }),
4642
+ data: this.formatter.formatToXml(file.ViewProps, context, declaration),
4440
4643
  path: "ppt/viewProps.xml"
4441
4644
  };
4442
4645
  mapping["SlideMaster"] = {
4443
- data: xml(this.formatter.format(file.SlideMaster, context), {
4444
- declaration,
4445
- indent
4446
- }),
4646
+ data: this.formatter.formatToXml(file.SlideMaster, context, declaration),
4447
4647
  path: "ppt/slideMasters/slideMaster1.xml"
4448
4648
  };
4449
4649
  mapping["SlideMasterRelationships"] = {
@@ -4451,10 +4651,7 @@ var Compiler = class {
4451
4651
  path: "ppt/slideMasters/_rels/slideMaster1.xml.rels"
4452
4652
  };
4453
4653
  mapping["SlideLayout"] = {
4454
- data: xml(this.formatter.format(file.SlideLayout, context), {
4455
- declaration,
4456
- indent
4457
- }),
4654
+ data: this.formatter.formatToXml(file.SlideLayout, context, declaration),
4458
4655
  path: "ppt/slideLayouts/slideLayout1.xml"
4459
4656
  };
4460
4657
  mapping["SlideLayoutRelationships"] = {
@@ -4475,10 +4672,7 @@ var Compiler = class {
4475
4672
  path: "ppt/notesMasters/_rels/notesMaster1.xml.rels"
4476
4673
  };
4477
4674
  }
4478
- const presentationXml = xml(this.formatter.format(file.PresentationWrapper.View, context), {
4479
- declaration,
4480
- indent
4481
- });
4675
+ const presentationXml = this.formatter.formatToXml(file.PresentationWrapper.View, context, declaration);
4482
4676
  let currentImageCount = 0;
4483
4677
  const mediaData = this.imageReplacer.getMediaData(presentationXml, file.Media);
4484
4678
  const presImageOffset = file.PresentationWrapper.Relationships.RelationshipCount + 1;
@@ -4497,10 +4691,7 @@ var Compiler = class {
4497
4691
  };
4498
4692
  for (let i = 0; i < file.Slides.length; i++) {
4499
4693
  const slideWrapper = file.SlideWrappers[i];
4500
- const slideXml = xml(this.formatter.format(slideWrapper.View, context), {
4501
- declaration,
4502
- indent
4503
- });
4694
+ const slideXml = this.formatter.formatToXml(slideWrapper.View, context, declaration);
4504
4695
  const slideMediaData = this.imageReplacer.getMediaData(slideXml, file.Media);
4505
4696
  const slideImageOffset = slideWrapper.Relationships.RelationshipCount + 1;
4506
4697
  slideMediaData.forEach((image, idx) => {
@@ -4508,58 +4699,50 @@ var Compiler = class {
4508
4699
  });
4509
4700
  let replacedSlideXml = this.imageReplacer.replace(slideXml, slideMediaData, slideImageOffset);
4510
4701
  currentImageCount += slideMediaData.length;
4511
- const chartPlaceholderRegex = /\{chart:([^}]+)\}/g;
4512
- const slideChartKeys = [];
4513
- let match;
4514
- const slideXmlForCharts = replacedSlideXml;
4515
- while ((match = chartPlaceholderRegex.exec(slideXmlForCharts)) !== null) if (!slideChartKeys.includes(match[1])) slideChartKeys.push(match[1]);
4516
- if (slideChartKeys.length > 0) {
4517
- const slideChartOffset = slideWrapper.Relationships.RelationshipCount + 1;
4518
- const slideCharts = file.Charts.Array.filter((c) => slideChartKeys.includes(c.key));
4519
- replacedSlideXml = this.chartReplacer.replace(replacedSlideXml, { Array: slideCharts }, slideChartOffset);
4520
- slideCharts.forEach((chartData, ci) => {
4521
- const globalIndex = file.Charts.Array.indexOf(chartData);
4522
- slideWrapper.Relationships.addRelationship(slideChartOffset + ci, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart", `../charts/chart${globalIndex + 1}.xml`);
4523
- });
4524
- }
4525
- const slideSmartArtKeys = [];
4526
- const smartArtRegex = /\{smartart:([^}]+)\}/g;
4527
- let saMatch;
4528
- while ((saMatch = smartArtRegex.exec(replacedSlideXml)) !== null) if (!slideSmartArtKeys.includes(saMatch[1])) slideSmartArtKeys.push(saMatch[1]);
4529
- if (slideSmartArtKeys.length > 0) {
4530
- const slideSmartArts = file.SmartArts.Array.filter((s) => slideSmartArtKeys.includes(s.key));
4531
- const saOffset = slideWrapper.Relationships.RelationshipCount + 1;
4532
- replacedSlideXml = this.smartArtReplacer.replace(replacedSlideXml, { Array: slideSmartArts }, saOffset);
4533
- const saGlobalStart = file.SmartArts.Array.indexOf(slideSmartArts[0]);
4534
- this.smartArtReplacer.addRelationships({ Array: slideSmartArts }, (id, type, target) => {
4535
- slideWrapper.Relationships.addRelationship(id, type, target);
4536
- }, saOffset, saGlobalStart);
4537
- }
4538
- const hlinkPlaceholderRegex = /\{hlink:([^}]+)\}/g;
4539
- const slideHlinkKeys = [];
4540
- let hlinkMatch;
4541
- while ((hlinkMatch = hlinkPlaceholderRegex.exec(replacedSlideXml)) !== null) if (!slideHlinkKeys.includes(hlinkMatch[1])) slideHlinkKeys.push(hlinkMatch[1]);
4542
- if (slideHlinkKeys.length > 0) {
4543
- const slideHlinks = file.Hyperlinks.Array.filter((h) => slideHlinkKeys.includes(h.key));
4544
- const hlinkOffset = slideWrapper.Relationships.RelationshipCount + 1;
4545
- replacedSlideXml = this.hyperlinkReplacer.replace(replacedSlideXml, slideHlinks, hlinkOffset);
4546
- slideHlinks.forEach((hlink, hi) => {
4547
- slideWrapper.Relationships.addRelationship(hlinkOffset + hi, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", hlink.url, "External");
4548
- });
4549
- }
4550
- const slideMediaRefs = this.mediaReplacer.getMediaRefs(replacedSlideXml, file.Media);
4551
- const slideVideoRefs = this.mediaReplacer.getVideoRefs(replacedSlideXml, file.Media);
4552
- if ([...slideMediaRefs, ...slideVideoRefs].length > 0) {
4553
- const mediaOffset = slideWrapper.Relationships.RelationshipCount + 1;
4554
- const videoOffset = mediaOffset + slideMediaRefs.length;
4555
- replacedSlideXml = this.mediaReplacer.replaceMedia(replacedSlideXml, slideMediaRefs, mediaOffset);
4556
- replacedSlideXml = this.mediaReplacer.replaceVideo(replacedSlideXml, slideVideoRefs, videoOffset);
4557
- slideMediaRefs.forEach((media, mi) => {
4558
- slideWrapper.Relationships.addRelationship(mediaOffset + mi, "http://schemas.microsoft.com/office/2007/relationships/media", `../media/${media.fileName}`);
4559
- });
4560
- slideVideoRefs.forEach((video, vi) => {
4561
- slideWrapper.Relationships.addRelationship(videoOffset + vi, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/video", `../media/${video.fileName}`);
4562
- });
4702
+ if (hasPlaceholders(replacedSlideXml)) {
4703
+ const slideChartKeys = collectPlaceholderKeys(replacedSlideXml, "chart:");
4704
+ if (slideChartKeys.length > 0) {
4705
+ const slideChartOffset = slideWrapper.Relationships.RelationshipCount + 1;
4706
+ const slideCharts = file.Charts.Array.filter((c) => slideChartKeys.includes(c.key));
4707
+ replacedSlideXml = this.chartReplacer.replace(replacedSlideXml, { Array: slideCharts }, slideChartOffset);
4708
+ slideCharts.forEach((chartData, ci) => {
4709
+ const globalIndex = file.Charts.Array.indexOf(chartData);
4710
+ slideWrapper.Relationships.addRelationship(slideChartOffset + ci, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart", `../charts/chart${globalIndex + 1}.xml`);
4711
+ });
4712
+ }
4713
+ const slideSmartArtKeys = collectPlaceholderKeys(replacedSlideXml, "smartart:");
4714
+ if (slideSmartArtKeys.length > 0) {
4715
+ const slideSmartArts = file.SmartArts.Array.filter((s) => slideSmartArtKeys.includes(s.key));
4716
+ const saOffset = slideWrapper.Relationships.RelationshipCount + 1;
4717
+ replacedSlideXml = this.smartArtReplacer.replace(replacedSlideXml, { Array: slideSmartArts }, saOffset);
4718
+ const saGlobalStart = file.SmartArts.Array.indexOf(slideSmartArts[0]);
4719
+ this.smartArtReplacer.addRelationships({ Array: slideSmartArts }, (id, type, target) => {
4720
+ slideWrapper.Relationships.addRelationship(id, type, target);
4721
+ }, saOffset, saGlobalStart);
4722
+ }
4723
+ const slideHlinkKeys = collectPlaceholderKeys(replacedSlideXml, "hlink:");
4724
+ if (slideHlinkKeys.length > 0) {
4725
+ const slideHlinks = file.Hyperlinks.Array.filter((h) => slideHlinkKeys.includes(h.key));
4726
+ const hlinkOffset = slideWrapper.Relationships.RelationshipCount + 1;
4727
+ replacedSlideXml = this.hyperlinkReplacer.replace(replacedSlideXml, slideHlinks, hlinkOffset);
4728
+ slideHlinks.forEach((hlink, hi) => {
4729
+ slideWrapper.Relationships.addRelationship(hlinkOffset + hi, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", hlink.url, "External");
4730
+ });
4731
+ }
4732
+ const slideMediaRefs = this.mediaReplacer.getMediaRefs(replacedSlideXml, file.Media);
4733
+ const slideVideoRefs = this.mediaReplacer.getVideoRefs(replacedSlideXml, file.Media);
4734
+ if (slideMediaRefs.length > 0 || slideVideoRefs.length > 0) {
4735
+ const mediaOffset = slideWrapper.Relationships.RelationshipCount + 1;
4736
+ const videoOffset = mediaOffset + slideMediaRefs.length;
4737
+ replacedSlideXml = this.mediaReplacer.replaceMedia(replacedSlideXml, slideMediaRefs, mediaOffset);
4738
+ replacedSlideXml = this.mediaReplacer.replaceVideo(replacedSlideXml, slideVideoRefs, videoOffset);
4739
+ slideMediaRefs.forEach((media, mi) => {
4740
+ slideWrapper.Relationships.addRelationship(mediaOffset + mi, "http://schemas.microsoft.com/office/2007/relationships/media", `../media/${media.fileName}`);
4741
+ });
4742
+ slideVideoRefs.forEach((video, vi) => {
4743
+ slideWrapper.Relationships.addRelationship(videoOffset + vi, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/video", `../media/${video.fileName}`);
4744
+ });
4745
+ }
4563
4746
  }
4564
4747
  mapping[`Slide${i}`] = {
4565
4748
  data: replacedSlideXml,
@@ -4587,41 +4770,41 @@ var Compiler = class {
4587
4770
  const files = {};
4588
4771
  for (const key of Object.keys(mapping)) {
4589
4772
  const entry = mapping[key];
4590
- files[entry.path] = textToUint8Array(entry.data);
4773
+ files[entry.path] = [textToUint8Array(entry.data), { level: 0 }];
4591
4774
  }
4592
4775
  for (const override of overrides) files[override.path] = override.data instanceof Uint8Array ? override.data : textToUint8Array(override.data);
4593
4776
  for (let i = 0; i < file.Charts.Array.length; i++) {
4594
4777
  const chartData = file.Charts.Array[i];
4595
- files[`ppt/charts/chart${i + 1}.xml`] = textToUint8Array(xml(this.formatter.format(chartData.chartSpace, context), {
4778
+ files[`ppt/charts/chart${i + 1}.xml`] = [textToUint8Array(xml(this.formatter.format(chartData.chartSpace, context), {
4596
4779
  declaration,
4597
4780
  indent
4598
- }));
4599
- files[`ppt/charts/_rels/chart${i + 1}.xml.rels`] = textToUint8Array(xml({ Relationships: { _attr: { xmlns: "http://schemas.openxmlformats.org/package/2006/relationships" } } }, { declaration: {
4781
+ })), { level: 0 }];
4782
+ files[`ppt/charts/_rels/chart${i + 1}.xml.rels`] = [textToUint8Array(xml({ Relationships: { _attr: { xmlns: "http://schemas.openxmlformats.org/package/2006/relationships" } } }, { declaration: {
4600
4783
  encoding: "UTF-8",
4601
4784
  standalone: "yes"
4602
- } }));
4785
+ } })), { level: 0 }];
4603
4786
  }
4604
4787
  for (let i = 0; i < file.SmartArts.Array.length; i++) {
4605
4788
  const smartArtData = file.SmartArts.Array[i];
4606
- files[`ppt/diagrams/data${i + 1}.xml`] = textToUint8Array(xml(this.formatter.format(smartArtData.dataModel, context), {
4789
+ files[`ppt/diagrams/data${i + 1}.xml`] = [textToUint8Array(xml(this.formatter.format(smartArtData.dataModel, context), {
4607
4790
  declaration,
4608
4791
  indent
4609
- }));
4610
- files[`ppt/diagrams/layout${i + 1}.xml`] = textToUint8Array(getLayoutXml(smartArtData.layout));
4611
- files[`ppt/diagrams/quickStyle${i + 1}.xml`] = textToUint8Array(getStyleXml(smartArtData.style));
4612
- files[`ppt/diagrams/colors${i + 1}.xml`] = textToUint8Array(getColorXml(smartArtData.color));
4613
- files[`ppt/diagrams/drawing${i + 1}.xml`] = textToUint8Array(DEFAULT_DRAWING_XML);
4792
+ })), { level: 0 }];
4793
+ files[`ppt/diagrams/layout${i + 1}.xml`] = [textToUint8Array(getLayoutXml(smartArtData.layout)), { level: 0 }];
4794
+ files[`ppt/diagrams/quickStyle${i + 1}.xml`] = [textToUint8Array(getStyleXml(smartArtData.style)), { level: 0 }];
4795
+ files[`ppt/diagrams/colors${i + 1}.xml`] = [textToUint8Array(getColorXml(smartArtData.color)), { level: 0 }];
4796
+ files[`ppt/diagrams/drawing${i + 1}.xml`] = [textToUint8Array(DEFAULT_DRAWING_XML), { level: 0 }];
4614
4797
  }
4615
4798
  for (let i = 0; i < file.NotesSlides.length; i++) {
4616
4799
  const notesSlide = file.NotesSlides[i];
4617
- files[`ppt/notesSlides/notesSlide${i + 1}.xml`] = textToUint8Array(xml(this.formatter.format(notesSlide, context), {
4800
+ files[`ppt/notesSlides/notesSlide${i + 1}.xml`] = [textToUint8Array(xml(this.formatter.format(notesSlide, context), {
4618
4801
  declaration,
4619
4802
  indent
4620
- }));
4621
- files[`ppt/notesSlides/_rels/notesSlide${i + 1}.xml.rels`] = textToUint8Array(xml({ Relationships: { _attr: { xmlns: "http://schemas.openxmlformats.org/package/2006/relationships" } } }, { declaration: {
4803
+ })), { level: 0 }];
4804
+ files[`ppt/notesSlides/_rels/notesSlide${i + 1}.xml.rels`] = [textToUint8Array(xml({ Relationships: { _attr: { xmlns: "http://schemas.openxmlformats.org/package/2006/relationships" } } }, { declaration: {
4622
4805
  encoding: "UTF-8",
4623
4806
  standalone: "yes"
4624
- } }));
4807
+ } })), { level: 0 }];
4625
4808
  }
4626
4809
  for (const image of file.Media.Array) {
4627
4810
  files[`ppt/media/${image.fileName}`] = [image.data, { level: 0 }];
@@ -5515,16 +5698,14 @@ function parseGroupShape(grpSp, ctx, slideRels) {
5515
5698
  if (flipV === "1") result.flipV = true;
5516
5699
  }
5517
5700
  }
5518
- const spTree = findChild(grpSp, "p:spTree");
5519
- if (spTree) {
5520
- const children = [];
5521
- for (const child of spTree.elements ?? []) {
5522
- if (child.name === "p:nvGrpSpPr" || child.name === "p:grpSpPr") continue;
5523
- const parsed = parseShapeTreeElement(child, ctx, slideRels);
5524
- if (parsed) children.push(parsed);
5525
- }
5526
- if (children.length > 0) result.children = children;
5701
+ const childSource = findChild(grpSp, "p:spTree") ?? grpSp;
5702
+ const children = [];
5703
+ for (const child of childSource.elements ?? []) {
5704
+ if (child.name === "p:nvGrpSpPr" || child.name === "p:grpSpPr") continue;
5705
+ const parsed = parseShapeTreeElement(child, ctx, slideRels);
5706
+ if (parsed) children.push(parsed);
5527
5707
  }
5708
+ if (children.length > 0) result.children = children;
5528
5709
  return result;
5529
5710
  }
5530
5711
  /** Parse slide notes content */