@office-open/pptx 0.6.7 → 0.6.9

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,5 +1,5 @@
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, Formatter as Formatter$1, ImportedXmlComponent, NextAttributeComponent, OoxmlMimeType, PPTX_NS, Relationships, XmlComponent, ZIP_STORED_LEVEL, addSmartArtRelationships, appendContentType, buildCorePropertiesXml, buildCorePropertiesXmlString, collectPlaceholderKeys, compileMapping, convertEmuToInches, convertEmuToPixels, convertEmuToPixels as convertEmuToPixels$1, convertEmuToPoints, convertInchesToEmu, convertPixelsToEmu, convertPixelsToEmu as convertPixelsToEmu$1, convertPointsToEmu, createPacker, createReplacer, formatId, getReferencedMedia, hasPlaceholders, hashedId, parseArchive, parseCorePropsElement, replaceChartPlaceholders, replaceImagePlaceholders, replaceSmartArtPlaceholders, strFromU8, stringContainerObj, toJson, uniqueId, uniqueNumericIdCreator, uniqueUuid, unzipSync, xsdLineEndSize, xsdRectAlignment, xsdStrikeStyle, xsdTextAlign, xsdTextAnchor, xsdTextCaps, xsdUnderlineStyle, zipAndConvert } from "@office-open/core";
1
+ import { i as __toCommonJS, n as __exportAll, r as __reExport, t as __esmMin } from "./chunk-DHfcOUro.mjs";
2
+ import { AppProperties, BaseXmlComponent, BuilderElement, EmptyElement, Formatter, Formatter as Formatter$1, ImportedXmlComponent, OoxmlMimeType, PPTX_NS, Relationships, XmlComponent, ZIP_STORED_LEVEL, addSmartArtRelationships, appendContentType, buildAttrObject, buildCorePropertiesXmlString, collectPlaceholderKeys, compileMapping, convertEmuToInches, convertEmuToPixels, convertEmuToPixels as convertEmuToPixels$1, convertEmuToPoints, convertInchesToEmu, convertPixelsToEmu, convertPixelsToEmu as convertPixelsToEmu$1, convertPointsToEmu, createPacker, createReplacer, formatId, getReferencedMedia, hasPlaceholders, hashedId, parseArchive, parseCorePropsElement, replaceChartPlaceholders, replaceImagePlaceholders, replaceSmartArtPlaceholders, strFromU8, stringContainerObj, toJson, uniqueId, uniqueNumericIdCreator, uniqueUuid, unzipSync, xsdLineEndSize, xsdRectAlignment, xsdStrikeStyle, xsdTextAlign, xsdTextAnchor, xsdTextCaps, xsdUnderlineStyle, zipAndConvert } 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 { attr, attrBool, attrNum, children, colorAttr, escapeXml, findChild, findDeep, js2xml, textOf, xml, xml2js } from "@office-open/xml";
@@ -165,18 +165,14 @@ var init_background = __esmMin((() => {
165
165
  if (el) this.root.push(el);
166
166
  }
167
167
  }
168
- prepForXml(context) {
169
- const obj = super.prepForXml(context);
170
- if (!obj) return void 0;
171
- if (this.shadeToTitle && "p:bgPr" in obj) {
172
- const children = obj["p:bgPr"];
173
- for (const child of children) if ("_attr" in child) {
174
- child._attr.shadeToTitle = 1;
175
- return obj;
176
- }
177
- children.unshift({ _attr: { shadeToTitle: 1 } });
168
+ toXml(context) {
169
+ if (this.shadeToTitle) {
170
+ this.root.unshift({ _attr: { shadeToTitle: 1 } });
171
+ const result = super.toXml(context);
172
+ this.root.shift();
173
+ return result;
178
174
  }
179
- return obj;
175
+ return super.toXml(context);
180
176
  }
181
177
  };
182
178
  }));
@@ -192,10 +188,7 @@ init_xml_components();
192
188
  var CommentAuthorList = class extends XmlComponent {
193
189
  constructor(authors) {
194
190
  super("p:cmAuthorLst");
195
- this.root.push(new NextAttributeComponent({ "xmlns:p": {
196
- key: "xmlns:p",
197
- value: "http://schemas.openxmlformats.org/presentationml/2006/main"
198
- } }));
191
+ this.root.push(buildAttrObject({ "xmlns:p": "http://schemas.openxmlformats.org/presentationml/2006/main" }));
199
192
  for (const author of authors) this.root.push(new BuilderElement({
200
193
  name: "p:cmAuthor",
201
194
  attributes: {
@@ -232,10 +225,7 @@ init_xml_components();
232
225
  var SlideCommentList = class extends XmlComponent {
233
226
  constructor(comments) {
234
227
  super("p:cmLst");
235
- this.root.push(new NextAttributeComponent({ "xmlns:p": {
236
- key: "xmlns:p",
237
- value: "http://schemas.openxmlformats.org/presentationml/2006/main"
238
- } }));
228
+ this.root.push(buildAttrObject({ "xmlns:p": "http://schemas.openxmlformats.org/presentationml/2006/main" }));
239
229
  for (const comment of comments) this.root.push(new BuilderElement({
240
230
  name: "p:cm",
241
231
  attributes: {
@@ -283,7 +273,7 @@ const PPTX_NOTES = "application/vnd.openxmlformats-officedocument.presentationml
283
273
  const PPTX_COMMENTS = "application/vnd.openxmlformats-officedocument.presentationml.comments+xml";
284
274
  const PPTX_COMMENT_AUTHORS = "application/vnd.openxmlformats-officedocument.presentationml.commentAuthors+xml";
285
275
  const PPTX_CHART = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml";
286
- const STATIC_CHILDREN = [{ _attr: { xmlns: "http://schemas.openxmlformats.org/package/2006/content-types" } }, ...[
276
+ const STATIC_ENTRIES = [
287
277
  {
288
278
  type: "Default",
289
279
  contentType: "application/vnd.openxmlformats-package.relationships+xml",
@@ -349,16 +339,12 @@ const STATIC_CHILDREN = [{ _attr: { xmlns: "http://schemas.openxmlformats.org/pa
349
339
  contentType: "application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml",
350
340
  key: "/ppt/tableStyles.xml"
351
341
  }
352
- ].map((e) => {
353
- if (e.type === "Default") return { Default: { _attr: {
354
- ContentType: e.contentType,
355
- Extension: e.key
356
- } } };
357
- return { Override: { _attr: {
358
- ContentType: e.contentType,
359
- PartName: e.key
360
- } } };
361
- })];
342
+ ];
343
+ function formatEntry(e) {
344
+ if (e.type === "Default") return `<Default ContentType="${escapeXml(e.contentType)}" Extension="${escapeXml(e.key)}"/>`;
345
+ return `<Override ContentType="${escapeXml(e.contentType)}" PartName="${escapeXml(e.key)}"/>`;
346
+ }
347
+ const STATIC_XML = `<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">` + STATIC_ENTRIES.map(formatEntry).join("");
362
348
  var ContentTypes = class extends BaseXmlComponent {
363
349
  dynamicEntries = [];
364
350
  constructor() {
@@ -455,17 +441,11 @@ var ContentTypes = class extends BaseXmlComponent {
455
441
  key: `/ppt/theme/theme${index}.xml`
456
442
  });
457
443
  }
458
- prepForXml(_context) {
459
- const children = [...STATIC_CHILDREN];
460
- for (const e of this.dynamicEntries) if (e.type === "Default") children.push({ Default: { _attr: {
461
- ContentType: e.contentType,
462
- Extension: e.key
463
- } } });
464
- else children.push({ Override: { _attr: {
465
- ContentType: e.contentType,
466
- PartName: e.key
467
- } } });
468
- return { Types: children };
444
+ toXml(_context) {
445
+ const parts = [STATIC_XML];
446
+ for (const e of this.dynamicEntries) parts.push(formatEntry(e));
447
+ parts.push("</Types>");
448
+ return parts.join("");
469
449
  }
470
450
  };
471
451
  //#endregion
@@ -477,9 +457,6 @@ var CoreProperties = class extends BaseXmlComponent {
477
457
  super("cp:coreProperties");
478
458
  this.options = options;
479
459
  }
480
- prepForXml(_context) {
481
- return buildCorePropertiesXml(this.options);
482
- }
483
460
  toXml(_context) {
484
461
  return buildCorePropertiesXmlString(this.options);
485
462
  }
@@ -547,9 +524,6 @@ var GroupTransform2D = class extends XmlComponent {
547
524
  super(`${prefix}:xfrm`);
548
525
  this.core = createGroupTransform2D(options, `${prefix}:xfrm`);
549
526
  }
550
- prepForXml(context) {
551
- return this.core["prepForXml"]?.(context);
552
- }
553
527
  toXml(context) {
554
528
  return this.core.toXml(context);
555
529
  }
@@ -597,32 +571,6 @@ var GroupShapeNonVisualProperties = class extends BuilderElement {
597
571
  }
598
572
  };
599
573
  //#endregion
600
- //#region src/file/shape/paragraph/end-paragraph-run.ts
601
- init_xml_components();
602
- /**
603
- * Pure function: builds a:endParaRPr XML object.
604
- */
605
- function buildEndParagraphRunProperties(lang = "en-US") {
606
- return { "a:endParaRPr": { _attr: { lang } } };
607
- }
608
- /**
609
- * a:endParaRPr — End paragraph run properties.
610
- * Lazy: stores lang, builds XML object in prepForXml.
611
- */
612
- var EndParagraphRunProperties = class extends BuilderElement {
613
- lang;
614
- constructor(lang = "en-US") {
615
- super({ name: "a:endParaRPr" });
616
- this.lang = lang;
617
- }
618
- prepForXml(_context) {
619
- return buildEndParagraphRunProperties(this.lang);
620
- }
621
- toXml(_context) {
622
- return `<a:endParaRPr lang="${this.lang}"/>`;
623
- }
624
- };
625
- //#endregion
626
574
  //#region src/file/shape/paragraph/paragraph-properties.ts
627
575
  init_xml_components();
628
576
  const TextAlignment = {
@@ -676,7 +624,7 @@ function buildParagraphProperties(options) {
676
624
  }
677
625
  /**
678
626
  * a:pPr — Paragraph properties (alignment, indent, spacing).
679
- * Lazy: stores options, builds XML object in prepForXml.
627
+ * Lazy: stores options, builds XML in toXml().
680
628
  * Omitted from output when completely empty.
681
629
  */
682
630
  var ParagraphProperties = class extends XmlComponent {
@@ -685,15 +633,31 @@ var ParagraphProperties = class extends XmlComponent {
685
633
  super("a:pPr");
686
634
  this.options = options;
687
635
  }
688
- prepForXml(_context) {
689
- return buildParagraphProperties(this.options);
690
- }
691
636
  toXml(_context) {
692
637
  const obj = buildParagraphProperties(this.options);
693
638
  return obj ? xml(obj) : "";
694
639
  }
695
640
  };
696
641
  //#endregion
642
+ //#region src/file/constants.ts
643
+ /**
644
+ * OOXML magic-number constants for PPTX generation.
645
+ *
646
+ * Values are in EMU (English Metric Units) or hundredths of a point,
647
+ * as defined by the OOXML specification.
648
+ * @module
649
+ */
650
+ /** Default outline width: 1pt = 12700 EMU */
651
+ const DEFAULT_OUTLINE_WIDTH = 12700;
652
+ /** Default shadow blur radius: ~4pt = 50800 EMU */
653
+ const DEFAULT_SHADOW_BLUR_RADIUS = 50800;
654
+ /** Default shadow distance: ~3pt = 38100 EMU */
655
+ const DEFAULT_SHADOW_DISTANCE = 38100;
656
+ /** Default shadow direction: 270° = 2700000 (60,000ths of a degree) */
657
+ const DEFAULT_SHADOW_DIRECTION = 27e5;
658
+ /** Default shadow alpha: 40% = 40000 (100,000ths of a percent) */
659
+ const DEFAULT_SHADOW_ALPHA = 4e4;
660
+ //#endregion
697
661
  //#region src/file/shape/paragraph/run-properties.ts
698
662
  init_fill();
699
663
  init_xml_components();
@@ -714,81 +678,39 @@ const TextCapitalization = {
714
678
  SMALL: "small"
715
679
  };
716
680
  /**
717
- * Pure function: builds a:rPr XML object from options.
718
- * @param hyperlinkKey - pre-generated key for hyperlink placeholder
719
- * @param fillObject - pre-built fill IXmlableObject (from buildFill)
681
+ * Builds a:rPr attribute string.
720
682
  */
721
- function buildRunProperties(options, hyperlinkKey, fillObject, effectListObject, outlineObject) {
722
- const children = [];
723
- const attrs = {};
724
- if (options.fontSize) attrs.sz = options.fontSize * 100;
725
- if (options.bold !== void 0) attrs.b = options.bold;
726
- if (options.italic !== void 0) attrs.i = options.italic;
727
- if (options.underline) attrs.u = xsdUnderlineStyle.to(options.underline);
728
- if (options.lang) attrs.lang = options.lang;
729
- if (options.strike) attrs.strike = xsdStrikeStyle.to(options.strike);
730
- if (options.baseline !== void 0) attrs.baseline = options.baseline;
731
- if (options.capitalization) attrs.cap = xsdTextCaps.to(options.capitalization);
732
- if (options.spacing !== void 0) attrs.spc = options.spacing;
733
- if (options.noProof !== void 0) attrs.noProof = options.noProof;
734
- if (options.dirty !== void 0) attrs.dirty = options.dirty;
735
- if (Object.keys(attrs).length > 0) children.push({ _attr: attrs });
736
- if (outlineObject) children.push(outlineObject);
737
- if (fillObject) children.push(fillObject);
738
- if (effectListObject) children.push(effectListObject);
739
- if (options.font) {
740
- children.push({ "a:latin": { _attr: { typeface: options.font } } });
741
- children.push({ "a:ea": { _attr: { typeface: options.font } } });
742
- }
743
- if (options.hyperlink && hyperlinkKey) {
744
- const hlinkAttrs = { "r:id": `{hlink:${hyperlinkKey}}` };
745
- if (options.hyperlink.tooltip) hlinkAttrs.tooltip = options.hyperlink.tooltip;
746
- children.push({ "a:hlinkClick": { _attr: hlinkAttrs } });
747
- }
748
- if (options.rightToLeft !== void 0) children.push({ "a:rtl": { _attr: { val: options.rightToLeft ? 1 : 0 } } });
749
- if (children.length === 0) return void 0;
750
- return { "a:rPr": children.length === 1 && "_attr" in children[0] ? children[0] : children };
683
+ function buildAttrString(options) {
684
+ const attrs = [];
685
+ if (options.fontSize) attrs.push(`sz="${options.fontSize * 100}"`);
686
+ if (options.bold !== void 0) attrs.push(`b="${options.bold ? 1 : 0}"`);
687
+ if (options.italic !== void 0) attrs.push(`i="${options.italic ? 1 : 0}"`);
688
+ if (options.underline) attrs.push(`u="${xsdUnderlineStyle.to(options.underline)}"`);
689
+ if (options.lang) attrs.push(`lang="${options.lang}"`);
690
+ if (options.strike) attrs.push(`strike="${xsdStrikeStyle.to(options.strike)}"`);
691
+ if (options.baseline !== void 0) attrs.push(`baseline="${options.baseline}"`);
692
+ if (options.capitalization) attrs.push(`cap="${xsdTextCaps.to(options.capitalization)}"`);
693
+ if (options.spacing !== void 0) attrs.push(`spc="${options.spacing}"`);
694
+ if (options.noProof !== void 0) attrs.push(`noProof="${options.noProof ? 1 : 0}"`);
695
+ if (options.dirty !== void 0) attrs.push(`dirty="${options.dirty ? 1 : 0}"`);
696
+ return attrs.join(" ");
697
+ }
698
+ /**
699
+ * Checks if options have any settable properties.
700
+ */
701
+ function hasRunProperties(options) {
702
+ return !!(options.fontSize || options.bold !== void 0 || options.italic !== void 0 || options.underline || options.font || options.lang || options.fill || options.hyperlink || options.strike || options.baseline !== void 0 || options.spacing !== void 0 || options.capitalization || options.shadow !== void 0 || options.outline !== void 0 || options.rightToLeft !== void 0 || options.noProof !== void 0 || options.dirty !== void 0);
751
703
  }
752
704
  /**
753
705
  * a:rPr — Run properties (font, size, color, etc.).
754
- * Lazy: stores options, builds XML object in prepForXml.
755
706
  */
756
707
  var RunProperties = class extends XmlComponent {
757
708
  options;
758
- static hasProperties(options) {
759
- return !!(options.fontSize || options.bold !== void 0 || options.italic !== void 0 || options.underline || options.font || options.lang || options.fill || options.hyperlink || options.strike || options.baseline !== void 0 || options.spacing !== void 0 || options.capitalization || options.shadow !== void 0 || options.outline !== void 0 || options.rightToLeft !== void 0 || options.noProof !== void 0 || options.dirty !== void 0);
760
- }
709
+ static hasProperties = hasRunProperties;
761
710
  constructor(options = {}) {
762
711
  super("a:rPr");
763
712
  this.options = options;
764
713
  }
765
- prepForXml(context) {
766
- const opts = this.options;
767
- let hyperlinkKey;
768
- if (opts.hyperlink) {
769
- hyperlinkKey = `hlink_${nextHyperlinkId++}`;
770
- context.fileData?.hyperlinks?.addHyperlink(hyperlinkKey, opts.hyperlink.url, opts.hyperlink.tooltip);
771
- }
772
- let fillObj;
773
- if (opts.fill !== void 0) fillObj = buildFill(opts.fill).prepForXml(context) ?? void 0;
774
- let outlineObj;
775
- if (opts.outline) outlineObj = createOutline$1({
776
- width: 12700,
777
- type: "solidFill",
778
- color: { value: "000000" }
779
- }).prepForXml(context) ?? void 0;
780
- let effectListObj;
781
- if (opts.shadow) effectListObj = createEffectList$1({ outerShadow: {
782
- blurRadius: 50800,
783
- distance: 38100,
784
- direction: 27e5,
785
- color: {
786
- value: "000000",
787
- transforms: { alpha: 4e4 }
788
- }
789
- } }).prepForXml(context) ?? void 0;
790
- return buildRunProperties(opts, hyperlinkKey, fillObj, effectListObj, outlineObj);
791
- }
792
714
  toXml(context) {
793
715
  const opts = this.options;
794
716
  let hyperlinkKey;
@@ -796,26 +718,35 @@ var RunProperties = class extends XmlComponent {
796
718
  hyperlinkKey = `hlink_${nextHyperlinkId++}`;
797
719
  context.fileData?.hyperlinks?.addHyperlink(hyperlinkKey, opts.hyperlink.url, opts.hyperlink.tooltip);
798
720
  }
799
- let fillObj;
800
- if (opts.fill !== void 0) fillObj = buildFill(opts.fill).prepForXml(context) ?? void 0;
801
- let outlineObj;
802
- if (opts.outline) outlineObj = createOutline$1({
803
- width: 12700,
721
+ const parts = [];
722
+ const attrStr = buildAttrString(opts);
723
+ if (opts.outline) parts.push(createOutline$1({
724
+ width: DEFAULT_OUTLINE_WIDTH,
804
725
  type: "solidFill",
805
726
  color: { value: "000000" }
806
- }).prepForXml(context) ?? void 0;
807
- let effectListObj;
808
- if (opts.shadow) effectListObj = createEffectList$1({ outerShadow: {
809
- blurRadius: 50800,
810
- distance: 38100,
811
- direction: 27e5,
727
+ }).toXml(context));
728
+ if (opts.fill !== void 0) parts.push(buildFill(opts.fill).toXml(context));
729
+ if (opts.shadow) parts.push(createEffectList$1({ outerShadow: {
730
+ blurRadius: DEFAULT_SHADOW_BLUR_RADIUS,
731
+ distance: DEFAULT_SHADOW_DISTANCE,
732
+ direction: DEFAULT_SHADOW_DIRECTION,
812
733
  color: {
813
734
  value: "000000",
814
- transforms: { alpha: 4e4 }
735
+ transforms: { alpha: DEFAULT_SHADOW_ALPHA }
815
736
  }
816
- } }).prepForXml(context) ?? void 0;
817
- const obj = buildRunProperties(opts, hyperlinkKey, fillObj, effectListObj, outlineObj);
818
- return obj ? xml(obj) : "";
737
+ } }).toXml(context));
738
+ if (opts.font) {
739
+ parts.push(`<a:latin typeface="${opts.font}"/>`);
740
+ parts.push(`<a:ea typeface="${opts.font}"/>`);
741
+ }
742
+ if (opts.hyperlink && hyperlinkKey) {
743
+ const tooltip = opts.hyperlink.tooltip ? ` tooltip="${opts.hyperlink.tooltip}"` : "";
744
+ parts.push(`<a:hlinkClick r:id="{hlink:${hyperlinkKey}}"${tooltip}/>`);
745
+ }
746
+ if (opts.rightToLeft !== void 0) parts.push(`<a:rtl val="${opts.rightToLeft ? 1 : 0}"/>`);
747
+ if (attrStr.length === 0 && parts.length === 0) return "";
748
+ if (parts.length === 0) return `<a:rPr ${attrStr}/>`;
749
+ return `<a:rPr ${attrStr}>${parts.join("")}</a:rPr>`;
819
750
  }
820
751
  };
821
752
  //#endregion
@@ -823,7 +754,6 @@ var RunProperties = class extends XmlComponent {
823
754
  init_xml_components();
824
755
  /**
825
756
  * a:r — A run of text with properties.
826
- * Lazy: stores options, builds XML object in prepForXml.
827
757
  */
828
758
  var TextRun = class extends XmlComponent {
829
759
  options;
@@ -831,34 +761,9 @@ var TextRun = class extends XmlComponent {
831
761
  super("a:r");
832
762
  this.options = typeof options === "string" ? { text: options } : options;
833
763
  }
834
- prepForXml(context) {
835
- const children = [];
836
- if (RunProperties.hasProperties(this.options)) {
837
- const rPrObj = new RunProperties(this.options).prepForXml(context);
838
- if (rPrObj) children.push(rPrObj);
839
- }
840
- if (this.options.text) children.push({ "a:t": [this.options.text] });
841
- return { "a:r": children.length === 0 ? {} : children.length === 1 && "_attr" in children[0] ? children[0] : children };
842
- }
843
- /**
844
- * Fast path: simple properties (no hyperlink/fill/shadow/outline) skip
845
- * RunProperties side effects and serialize directly.
846
- * Complex path uses RunProperties.toXml() + direct text serialization.
847
- */
848
764
  toXml(context) {
849
- const opts = this.options;
850
- const hasRPr = RunProperties.hasProperties(opts);
851
- if (!hasRPr || !opts.hyperlink && !opts.fill && !opts.shadow && !opts.outline) {
852
- let body = "";
853
- if (hasRPr) {
854
- const rPrObj = buildRunProperties(opts);
855
- if (rPrObj) body += xml(rPrObj);
856
- }
857
- if (opts.text) body += `<a:t>${escapeXml(opts.text)}</a:t>`;
858
- return body.length === 0 ? "<a:r/>" : `<a:r>${body}</a:r>`;
859
- }
860
- let body = new RunProperties(opts).toXml(context);
861
- if (opts.text) body += `<a:t>${escapeXml(opts.text)}</a:t>`;
765
+ const body = new RunProperties(this.options).toXml(context);
766
+ if (this.options.text) return `<a:r>${body}<a:t>${escapeXml(this.options.text)}</a:t></a:r>`;
862
767
  return body ? `<a:r>${body}</a:r>` : "<a:r/>";
863
768
  }
864
769
  };
@@ -867,7 +772,7 @@ var TextRun = class extends XmlComponent {
867
772
  init_xml_components();
868
773
  /**
869
774
  * a:p — A paragraph in a text body.
870
- * Lazy: stores options, builds XML object in prepForXml.
775
+ * Lazy: stores options, builds XML in toXml().
871
776
  */
872
777
  var Paragraph = class extends XmlComponent {
873
778
  options;
@@ -875,21 +780,6 @@ var Paragraph = class extends XmlComponent {
875
780
  super("a:p");
876
781
  this.options = typeof options === "string" ? { text: options } : options;
877
782
  }
878
- prepForXml(context) {
879
- const children = [];
880
- const pPr = buildParagraphProperties(this.options.properties ?? {});
881
- if (pPr) children.push(pPr);
882
- if (this.options.text) {
883
- const obj = new TextRun(this.options.text).prepForXml(context);
884
- if (obj) children.push(obj);
885
- }
886
- if (this.options.children) for (const rawChild of this.options.children) {
887
- const obj = (rawChild instanceof TextRun || rawChild instanceof XmlComponent ? rawChild : new TextRun(rawChild)).prepForXml(context);
888
- if (obj) children.push(obj);
889
- }
890
- children.push(buildEndParagraphRunProperties());
891
- return { "a:p": children };
892
- }
893
783
  toXml(context) {
894
784
  const parts = [];
895
785
  const pPr = buildParagraphProperties(this.options.properties ?? {});
@@ -909,16 +799,17 @@ var Paragraph = class extends XmlComponent {
909
799
  init_xml_components();
910
800
  init_fill();
911
801
  function buildBorderLine(name, options) {
912
- const attrs = {};
802
+ const attrs = [];
803
+ if (options.width !== void 0) attrs.push(`w="${options.width}"`);
913
804
  const children = [];
914
- if (options.width !== void 0) attrs.w = options.width;
915
- if (options.color) children.push({ "a:solidFill": [{ "a:srgbClr": { _attr: { val: options.color.replace("#", "") } } }] });
916
- if (options.dashStyle) children.push({ "a:prstDash": { _attr: { val: options.dashStyle } } });
917
- return { [name]: Object.keys(attrs).length > 0 ? [{ _attr: attrs }, ...children] : children };
805
+ if (options.color) children.push(`<a:solidFill><a:srgbClr val="${options.color.replace("#", "")}"/></a:solidFill>`);
806
+ if (options.dashStyle) children.push(`<a:prstDash val="${options.dashStyle}"/>`);
807
+ const attrStr = attrs.length > 0 ? ` ${attrs.join(" ")}` : "";
808
+ if (children.length === 0) return `<${name}${attrStr}/>`;
809
+ return `<${name}${attrStr}>${children.join("")}</${name}>`;
918
810
  }
919
811
  /**
920
812
  * a:tcPr — Table cell properties (borders + fill).
921
- * Lazy: stores options, builds IXmlableObject in prepForXml.
922
813
  */
923
814
  var TableCellProperties = class extends BaseXmlComponent {
924
815
  options;
@@ -926,25 +817,28 @@ var TableCellProperties = class extends BaseXmlComponent {
926
817
  super("a:tcPr");
927
818
  this.options = options;
928
819
  }
929
- prepForXml(context) {
930
- const children = [];
820
+ toXml(context) {
821
+ const parts = [];
931
822
  const opts = this.options;
932
- if (opts?.verticalAlign) children.push({ _attr: { anchor: opts.verticalAlign } });
823
+ if (opts?.verticalAlign) parts.push(`anchor="${opts.verticalAlign}"`);
933
824
  if (opts?.borders) {
934
- if (opts.borders.left) children.push(buildBorderLine("a:lnL", opts.borders.left));
935
- if (opts.borders.right) children.push(buildBorderLine("a:lnR", opts.borders.right));
936
- if (opts.borders.top) children.push(buildBorderLine("a:lnT", opts.borders.top));
937
- if (opts.borders.bottom) children.push(buildBorderLine("a:lnB", opts.borders.bottom));
825
+ if (opts.borders.left) parts.push(buildBorderLine("a:lnL", opts.borders.left));
826
+ if (opts.borders.right) parts.push(buildBorderLine("a:lnR", opts.borders.right));
827
+ if (opts.borders.top) parts.push(buildBorderLine("a:lnT", opts.borders.top));
828
+ if (opts.borders.bottom) parts.push(buildBorderLine("a:lnB", opts.borders.bottom));
938
829
  }
939
830
  if (opts?.fill !== void 0) {
940
- const fillObj = buildFill(opts.fill).prepForXml(context);
941
- if (fillObj) children.push(fillObj);
831
+ const fillComp = buildFill(opts.fill);
832
+ parts.push(fillComp.toXml(context));
942
833
  }
943
- return { "a:tcPr": children.length === 0 ? {} : children.length === 1 && "_attr" in children[0] ? children[0] : children };
944
- }
945
- toXml(context) {
946
- const obj = this.prepForXml(context);
947
- return obj ? xml(obj) : "<a:tcPr/>";
834
+ if (parts.length === 0) return "<a:tcPr/>";
835
+ if (!parts[0].startsWith("<")) {
836
+ const attrStr = parts[0];
837
+ const children = parts.slice(1);
838
+ if (children.length === 0) return `<a:tcPr ${attrStr}/>`;
839
+ return `<a:tcPr ${attrStr}>${children.join("")}</a:tcPr>`;
840
+ }
841
+ return `<a:tcPr>${parts.join("")}</a:tcPr>`;
948
842
  }
949
843
  };
950
844
  //#endregion
@@ -957,7 +851,7 @@ const VerticalAlignment = {
957
851
  };
958
852
  /**
959
853
  * a:tc — Table cell with text body and properties.
960
- * Lazy: stores options, builds IXmlableObject in prepForXml.
854
+ * Lazy: stores options, builds XML string in toXml.
961
855
  */
962
856
  var TableCell = class extends BaseXmlComponent {
963
857
  options;
@@ -970,36 +864,6 @@ var TableCell = class extends BaseXmlComponent {
970
864
  children: [new TextRun({ text: options.text })]
971
865
  })] : void 0);
972
866
  }
973
- prepForXml(context) {
974
- const opts = this.options;
975
- const children = [];
976
- const tcAttrs = {};
977
- if (opts.columnSpan !== void 0 && opts.columnSpan > 1) tcAttrs.gridSpan = opts.columnSpan;
978
- if (opts.rowSpan !== void 0 && opts.rowSpan > 1) tcAttrs.rowSpan = opts.rowSpan;
979
- if (Object.keys(tcAttrs).length > 0) children.push({ _attr: tcAttrs });
980
- const txBodyChildren = [];
981
- const margins = opts.margins;
982
- const bodyPrAttrs = {};
983
- if (margins?.top !== void 0) bodyPrAttrs.tIns = margins.top;
984
- if (margins?.bottom !== void 0) bodyPrAttrs.bIns = margins.bottom;
985
- if (margins?.left !== void 0) bodyPrAttrs.lIns = margins.left;
986
- if (margins?.right !== void 0) bodyPrAttrs.rIns = margins.right;
987
- txBodyChildren.push({ "a:bodyPr": Object.keys(bodyPrAttrs).length > 0 ? { _attr: bodyPrAttrs } : {} });
988
- txBodyChildren.push({ "a:lstStyle": {} });
989
- if (this.paragraphs) for (const p of this.paragraphs) {
990
- const pObj = p.prepForXml(context);
991
- if (pObj) txBodyChildren.push(pObj);
992
- }
993
- else txBodyChildren.push({ "a:p": [] });
994
- children.push({ "a:txBody": txBodyChildren });
995
- const tcPrObj = new TableCellProperties({
996
- fill: opts.fill,
997
- borders: opts.borders,
998
- verticalAlign: opts.verticalAlign ? xsdTextAnchor.to(opts.verticalAlign) : void 0
999
- }).prepForXml(context);
1000
- if (tcPrObj) children.push(tcPrObj);
1001
- return { "a:tc": children };
1002
- }
1003
867
  toXml(context) {
1004
868
  const opts = this.options;
1005
869
  const parts = [];
@@ -1057,7 +921,7 @@ function buildBodyPr(options) {
1057
921
  }
1058
922
  /**
1059
923
  * p:txBody — Text body within a shape.
1060
- * Lazy: stores options, builds XML object in prepForXml.
924
+ * Lazy: stores options, builds XML in toXml().
1061
925
  */
1062
926
  var TextBody = class extends XmlComponent {
1063
927
  options;
@@ -1065,23 +929,6 @@ var TextBody = class extends XmlComponent {
1065
929
  super("p:txBody");
1066
930
  this.options = options;
1067
931
  }
1068
- prepForXml(context) {
1069
- const children = [];
1070
- children.push(buildBodyPr(this.options));
1071
- children.push({ "a:lstStyle": {} });
1072
- if (this.options.children) for (const p of this.options.children) {
1073
- const obj = (typeof p === "string" ? new Paragraph({ children: [new TextRun({ text: p })] }) : p instanceof Paragraph ? p : new Paragraph(p)).prepForXml(context);
1074
- if (obj) children.push(obj);
1075
- }
1076
- else if (this.options.text !== void 0) {
1077
- const obj = new Paragraph({ children: [new TextRun({ text: this.options.text })] }).prepForXml(context);
1078
- if (obj) children.push(obj);
1079
- } else {
1080
- const obj = new Paragraph().prepForXml(context);
1081
- if (obj) children.push(obj);
1082
- }
1083
- return { "p:txBody": children };
1084
- }
1085
932
  toXml(context) {
1086
933
  const parts = [];
1087
934
  parts.push(xml(buildBodyPr(this.options)));
@@ -1106,19 +953,10 @@ init_xml_components();
1106
953
  var NotesSlide = class extends XmlComponent {
1107
954
  constructor(options = {}) {
1108
955
  super("p:notes");
1109
- this.root.push(new NextAttributeComponent({
1110
- "xmlns:a": {
1111
- key: "xmlns:a",
1112
- value: "http://schemas.openxmlformats.org/drawingml/2006/main"
1113
- },
1114
- "xmlns:r": {
1115
- key: "xmlns:r",
1116
- value: "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
1117
- },
1118
- "xmlns:p": {
1119
- key: "xmlns:p",
1120
- value: "http://schemas.openxmlformats.org/presentationml/2006/main"
1121
- }
956
+ this.root.push(buildAttrObject({
957
+ "xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
958
+ "xmlns:r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
959
+ "xmlns:p": "http://schemas.openxmlformats.org/presentationml/2006/main"
1122
960
  }));
1123
961
  this.root.push(new NotesCommonSlideData(options.text));
1124
962
  this.root.push(new BuilderElement({
@@ -1300,9 +1138,6 @@ var PresentationProperties = class PresentationProperties extends ImportedXmlCom
1300
1138
  this.key = showOptions ? presPropsKey(showOptions) : "";
1301
1139
  if (!PresentationProperties.cache.has(this.key)) PresentationProperties.cache.set(this.key, ImportedXmlComponent.fromXmlString(buildPresPropsXml(showOptions)));
1302
1140
  }
1303
- prepForXml() {
1304
- return PresentationProperties.cache.get(this.key).prepForXml({ stack: [] });
1305
- }
1306
1141
  toXml(context) {
1307
1142
  return PresentationProperties.cache.get(this.key).toXml(context);
1308
1143
  }
@@ -1343,10 +1178,9 @@ const DEFAULT_TEXT_STYLE_XML = `<p:defaultTextStyle xmlns:a="http://schemas.open
1343
1178
  <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>
1344
1179
  </a:lvl9pPr>
1345
1180
  </p:defaultTextStyle>`;
1346
- const DEFAULT_TEXT_STYLE_OBJ = ImportedXmlComponent.fromXmlString(DEFAULT_TEXT_STYLE_XML).prepForXml({ stack: [] });
1347
1181
  /**
1348
1182
  * p:presentation — Root element of a PPTX file.
1349
- * Lazy: stores options, builds XML object directly in prepForXml.
1183
+ * Lazy: stores options, builds XML in toXml().
1350
1184
  */
1351
1185
  var Presentation = class extends XmlComponent {
1352
1186
  options;
@@ -1354,38 +1188,6 @@ var Presentation = class extends XmlComponent {
1354
1188
  super("p:presentation");
1355
1189
  this.options = options;
1356
1190
  }
1357
- prepForXml(_context) {
1358
- const opts = this.options;
1359
- const children = [];
1360
- children.push({ _attr: {
1361
- "xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
1362
- "xmlns:r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
1363
- "xmlns:p": "http://schemas.openxmlformats.org/presentationml/2006/main"
1364
- } });
1365
- const masterIds = Array.from({ length: opts.masterCount }, (_, i) => ({ "p:sldMasterId": { _attr: {
1366
- id: 2147483648 + i * 12,
1367
- "r:id": `rId${i + 1}`
1368
- } } }));
1369
- children.push({ "p:sldMasterIdLst": masterIds });
1370
- const slideRidOffset = opts.masterCount + 1;
1371
- const sldIds = opts.slideIds.map((id, i) => ({ "p:sldId": { _attr: {
1372
- id,
1373
- "r:id": `rId${slideRidOffset + i}`
1374
- } } }));
1375
- children.push({ "p:sldIdLst": sldIds });
1376
- const cx = opts.slideWidth ?? 12192e3;
1377
- const cy = opts.slideHeight ?? 6858e3;
1378
- children.push({ "p:sldSz": { _attr: {
1379
- cx,
1380
- cy
1381
- } } });
1382
- children.push({ "p:notesSz": { _attr: {
1383
- cx: 6858e3,
1384
- cy: 9144e3
1385
- } } });
1386
- children.push(DEFAULT_TEXT_STYLE_OBJ);
1387
- return { "p:presentation": children };
1388
- }
1389
1191
  toXml(_context) {
1390
1192
  const opts = this.options;
1391
1193
  const cx = opts.slideWidth ?? 12192e3;
@@ -1431,9 +1233,6 @@ var Transform2D = class extends XmlComponent {
1431
1233
  super(`${prefix}:xfrm`);
1432
1234
  this.core = createTransform2D(options, `${prefix}:xfrm`);
1433
1235
  }
1434
- prepForXml(context) {
1435
- return this.core["prepForXml"]?.(context);
1436
- }
1437
1236
  toXml(context) {
1438
1237
  return this.core.toXml(context);
1439
1238
  }
@@ -1501,10 +1300,6 @@ var Chart = class extends XmlComponent {
1501
1300
  key: this.chartKey
1502
1301
  });
1503
1302
  }
1504
- prepForXml(context) {
1505
- this.registerChart(context);
1506
- return super.prepForXml(context);
1507
- }
1508
1303
  toXml(context) {
1509
1304
  this.registerChart(context);
1510
1305
  return super.toXml(context);
@@ -1548,29 +1343,17 @@ var ChartGraphic = class extends XmlComponent {
1548
1343
  var ChartGraphicData = class extends XmlComponent {
1549
1344
  constructor(chartKey) {
1550
1345
  super("a:graphicData");
1551
- this.root.push(new NextAttributeComponent({ uri: {
1552
- key: "uri",
1553
- value: "http://schemas.openxmlformats.org/drawingml/2006/chart"
1554
- } }));
1346
+ this.root.push(buildAttrObject({ uri: "http://schemas.openxmlformats.org/drawingml/2006/chart" }));
1555
1347
  this.root.push(new ChartRef(chartKey));
1556
1348
  }
1557
1349
  };
1558
1350
  var ChartRef = class extends XmlComponent {
1559
1351
  constructor(chartKey) {
1560
1352
  super("c:chart");
1561
- this.root.push(new NextAttributeComponent({
1562
- xmlnsC: {
1563
- key: "xmlns:c",
1564
- value: "http://schemas.openxmlformats.org/drawingml/2006/chart"
1565
- },
1566
- xmlnsR: {
1567
- key: "xmlns:r",
1568
- value: "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
1569
- },
1570
- rId: {
1571
- key: "r:id",
1572
- value: `{chart:${chartKey}}`
1573
- }
1353
+ this.root.push(buildAttrObject({
1354
+ "xmlns:c": "http://schemas.openxmlformats.org/drawingml/2006/chart",
1355
+ "xmlns:r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
1356
+ "r:id": `{chart:${chartKey}}`
1574
1357
  }));
1575
1358
  }
1576
1359
  };
@@ -1607,7 +1390,7 @@ function buildMediaData(type, fileName, width, height, data) {
1607
1390
  *
1608
1391
  * Encapsulates the common structure: ID assignment, media data building,
1609
1392
  * p:spPr (Transform2D + PresetGeometry), p:blipFill, p:nvPicPr parts,
1610
- * and media registration in prepForXml.
1393
+ * and media registration in toXml().
1611
1394
  */
1612
1395
  var MediaFrameBase = class extends XmlComponent {
1613
1396
  shapeId;
@@ -1714,10 +1497,6 @@ var MediaFrameBase = class extends XmlComponent {
1714
1497
  if (this.posterData) file?.media.addImage(this.posterData.fileName, this.posterData);
1715
1498
  file?.media.addMedia(this.mediaData.fileName, this.mediaData);
1716
1499
  }
1717
- prepForXml(context) {
1718
- this.registerMedia(context);
1719
- return super.prepForXml(context);
1720
- }
1721
1500
  toXml(context) {
1722
1501
  this.registerMedia(context);
1723
1502
  return super.toXml(context);
@@ -1912,7 +1691,7 @@ init_xml_components();
1912
1691
  /**
1913
1692
  * p:pic — A picture on a slide.
1914
1693
  *
1915
- * Registers image with Media collection via prepForXml/toXml.
1694
+ * Registers image with Media collection via toXml().
1916
1695
  * The ImageReplacer replaces `{fileName}` placeholder with actual rId.
1917
1696
  */
1918
1697
  var Picture = class Picture extends XmlComponent {
@@ -1947,11 +1726,7 @@ var Picture = class Picture extends XmlComponent {
1947
1726
  }
1948
1727
  /** Register image with the File's Media collection. */
1949
1728
  registerMedia(context) {
1950
- context.fileData?.media.addImage(this.imageData.fileName, this.imageData);
1951
- }
1952
- prepForXml(context) {
1953
- this.registerMedia(context);
1954
- return super.prepForXml(context);
1729
+ context.fileData.media.addImage(this.imageData.fileName, this.imageData);
1955
1730
  }
1956
1731
  toXml(context) {
1957
1732
  this.registerMedia(context);
@@ -1963,7 +1738,7 @@ var Picture = class Picture extends XmlComponent {
1963
1738
  init_xml_components();
1964
1739
  /**
1965
1740
  * p:grpSp — Group shape containing child shapes.
1966
- * Lazy: stores options, builds XML object in prepForXml.
1741
+ * Lazy: stores options, builds XML in toXml().
1967
1742
  */
1968
1743
  var GroupShape = class GroupShape extends BaseXmlComponent {
1969
1744
  static nextId = 100;
@@ -1974,47 +1749,6 @@ var GroupShape = class GroupShape extends BaseXmlComponent {
1974
1749
  this.id = GroupShape.nextId++;
1975
1750
  this.options = options;
1976
1751
  }
1977
- prepForXml(context) {
1978
- const opts = this.options;
1979
- const id = this.id;
1980
- const name = `Group ${id}`;
1981
- const children = [];
1982
- children.push({ "p:nvGrpSpPr": [
1983
- { "p:cNvPr": { _attr: {
1984
- id,
1985
- name
1986
- } } },
1987
- { "p:cNvGrpSpPr": {} },
1988
- { "p:nvPr": {} }
1989
- ] });
1990
- const xfrmChildren = [];
1991
- const xfrmAttrs = {};
1992
- if (opts.flipHorizontal !== void 0) xfrmAttrs.flipH = opts.flipHorizontal ? 1 : 0;
1993
- if (opts.rotation !== void 0) xfrmAttrs.rot = opts.rotation;
1994
- if (Object.keys(xfrmAttrs).length > 0) xfrmChildren.push({ _attr: xfrmAttrs });
1995
- xfrmChildren.push({ "a:off": { _attr: {
1996
- x: opts.x !== void 0 ? convertPixelsToEmu$1(opts.x) : 0,
1997
- y: opts.y !== void 0 ? convertPixelsToEmu$1(opts.y) : 0
1998
- } } });
1999
- xfrmChildren.push({ "a:ext": { _attr: {
2000
- cx: opts.width !== void 0 ? convertPixelsToEmu$1(opts.width) : 0,
2001
- cy: opts.height !== void 0 ? convertPixelsToEmu$1(opts.height) : 0
2002
- } } });
2003
- xfrmChildren.push({ "a:chOff": { _attr: {
2004
- x: 0,
2005
- y: 0
2006
- } } });
2007
- xfrmChildren.push({ "a:chExt": { _attr: {
2008
- cx: 0,
2009
- cy: 0
2010
- } } });
2011
- children.push({ "p:grpSpPr": [{ "a:xfrm": xfrmChildren }] });
2012
- for (const rawChild of opts.children) {
2013
- const obj = coerceChild(rawChild).prepForXml(context);
2014
- if (obj) children.push(obj);
2015
- }
2016
- return { "p:grpSp": children };
2017
- }
2018
1752
  toXml(context) {
2019
1753
  const opts = this.options;
2020
1754
  const id = this.id;
@@ -2284,7 +2018,6 @@ init_effects();
2284
2018
  init_fill();
2285
2019
  /**
2286
2020
  * p:spPr — Shape properties (transform, geometry, fill, outline, effects).
2287
- * Lazy: stores options, builds XML object directly in prepForXml.
2288
2021
  */
2289
2022
  var ShapeProperties = class extends BaseXmlComponent {
2290
2023
  options;
@@ -2292,15 +2025,11 @@ var ShapeProperties = class extends BaseXmlComponent {
2292
2025
  super("p:spPr");
2293
2026
  this.options = options;
2294
2027
  }
2295
- prepForXml(context) {
2028
+ toXml(context) {
2296
2029
  const opts = this.options;
2297
- const children = [];
2298
- if (opts.x !== void 0 || opts.y !== void 0 || opts.width !== void 0 || opts.height !== void 0 || opts.flipHorizontal !== void 0 || opts.rotation !== void 0) {
2299
- const xfrmObj = new Transform2D(opts).prepForXml(context);
2300
- if (xfrmObj) children.push(xfrmObj);
2301
- }
2302
- const geomObj = new PresetGeometry({ preset: opts.geometry ?? "rect" }).prepForXml(context);
2303
- if (geomObj) children.push(geomObj);
2030
+ const parts = [];
2031
+ if (opts.x !== void 0 || opts.y !== void 0 || opts.width !== void 0 || opts.height !== void 0 || opts.flipHorizontal !== void 0 || opts.rotation !== void 0) parts.push(new Transform2D(opts).toXml(context));
2032
+ parts.push(new PresetGeometry({ preset: opts.geometry ?? "rect" }).toXml(context));
2304
2033
  const media = opts.fill ? extractBlipFillMedia(opts.fill) : void 0;
2305
2034
  if (media) context.fileData?.media.addImage(media.fileName, {
2306
2035
  data: media.data,
@@ -2317,59 +2046,34 @@ var ShapeProperties = class extends BaseXmlComponent {
2317
2046
  }
2318
2047
  }
2319
2048
  });
2320
- const fillObj = buildFill(opts.fill !== void 0 ? opts.fill : { type: "none" }).prepForXml(context);
2321
- if (fillObj) children.push(fillObj);
2322
- if (opts.outline) {
2323
- const outlineObj = createOutlineCompat(opts.outline).prepForXml(context);
2324
- if (outlineObj) children.push(outlineObj);
2325
- }
2049
+ const fillComponent = buildFill(opts.fill !== void 0 ? opts.fill : { type: "none" });
2050
+ parts.push(fillComponent.toXml(context));
2051
+ if (opts.outline) parts.push(createOutlineCompat(opts.outline).toXml(context));
2326
2052
  if (opts.effects) {
2327
2053
  const effectObj = createPptxEffectList(opts.effects);
2328
- if (effectObj) {
2329
- const effectXmlObj = effectObj.prepForXml(context);
2330
- if (effectXmlObj) children.push(effectXmlObj);
2331
- }
2054
+ if (effectObj) parts.push(effectObj.toXml(context));
2332
2055
  const scene3d = buildScene3D(opts.effects);
2333
- if (scene3d) {
2334
- const sceneObj = scene3d.prepForXml(context);
2335
- if (sceneObj) children.push(sceneObj);
2336
- }
2056
+ if (scene3d) parts.push(scene3d.toXml(context));
2337
2057
  const shape3d = buildShape3D(opts.effects);
2338
- if (shape3d) {
2339
- const shapeObj = shape3d.prepForXml(context);
2340
- if (shapeObj) children.push(shapeObj);
2341
- }
2058
+ if (shape3d) parts.push(shape3d.toXml(context));
2342
2059
  }
2343
2060
  if (opts.connectionSites && opts.connectionSites.length > 0) {
2344
- const cxnChildren = [];
2061
+ const cxnParts = [];
2345
2062
  for (const site of opts.connectionSites) {
2346
- const siteAttrs = { pos: `${site.x} ${site.y}` };
2347
- if (site.angle !== void 0) siteAttrs.ang = site.angle;
2348
- cxnChildren.push({ "a:cxn": { _attr: siteAttrs } });
2063
+ const ang = site.angle !== void 0 ? ` ang="${site.angle}"` : "";
2064
+ cxnParts.push(`<a:cxn pos="${site.x} ${site.y}"${ang}/>`);
2349
2065
  }
2350
- children.push({ "a:cxnLst": cxnChildren });
2066
+ parts.push(`<a:cxnLst>${cxnParts.join("")}</a:cxnLst>`);
2351
2067
  }
2352
- return { "p:spPr": children };
2353
- }
2354
- toXml(context) {
2355
- const obj = this.prepForXml(context);
2356
- return obj ? xml(obj) : "";
2068
+ return `<p:spPr>${parts.join("")}</p:spPr>`;
2357
2069
  }
2358
2070
  };
2359
2071
  //#endregion
2360
2072
  //#region src/file/shape/shape.ts
2361
2073
  init_xml_components();
2362
2074
  /**
2363
- * Pure function: builds p:ph element for placeholder.
2364
- */
2365
- function buildPlaceholder(type, index) {
2366
- const attrs = { type };
2367
- if (index !== void 0) attrs.idx = index;
2368
- return { "p:ph": { _attr: attrs } };
2369
- }
2370
- /**
2371
2075
  * p:sp — A shape on a slide.
2372
- * Lazy: stores options, builds XML object in prepForXml.
2076
+ * Lazy: stores options, builds XML in toXml().
2373
2077
  *
2374
2078
  * x/y/width/height accept pixel values and are internally converted to EMUs.
2375
2079
  */
@@ -2388,35 +2092,6 @@ var Shape = class Shape extends XmlComponent {
2388
2092
  id
2389
2093
  };
2390
2094
  }
2391
- prepForXml(context) {
2392
- const opts = this.options;
2393
- const id = this.shapeId;
2394
- const name = opts.name ?? `Shape ${id}`;
2395
- const children = [];
2396
- const nvPrChildren = [];
2397
- if (opts.placeholder) nvPrChildren.push(buildPlaceholder(opts.placeholder, opts.placeholderIndex));
2398
- children.push({ "p:nvSpPr": [
2399
- { "p:cNvPr": { _attr: {
2400
- id,
2401
- name
2402
- } } },
2403
- { "p:cNvSpPr": {} },
2404
- { "p:nvPr": nvPrChildren.length > 0 ? nvPrChildren : {} }
2405
- ] });
2406
- const spPrObj = new ShapeProperties({
2407
- ...emuPositionOptional(opts),
2408
- geometry: opts.geometry,
2409
- fill: opts.fill,
2410
- outline: opts.outline,
2411
- effects: opts.effects,
2412
- flipHorizontal: opts.flipHorizontal,
2413
- rotation: opts.rotation
2414
- }).prepForXml(context);
2415
- if (spPrObj) children.push(spPrObj);
2416
- const txBodyObj = new TextBody(opts.textBody ?? {}).prepForXml(context);
2417
- if (txBodyObj) children.push(txBodyObj);
2418
- return { "p:sp": children };
2419
- }
2420
2095
  toXml(context) {
2421
2096
  const opts = this.options;
2422
2097
  const id = this.shapeId;
@@ -2481,10 +2156,6 @@ var SmartArt = class extends XmlComponent {
2481
2156
  color: this.colorId
2482
2157
  });
2483
2158
  }
2484
- prepForXml(context) {
2485
- this.registerSmartArt(context);
2486
- return super.prepForXml(context);
2487
- }
2488
2159
  toXml(context) {
2489
2160
  this.registerSmartArt(context);
2490
2161
  return super.toXml(context);
@@ -2528,41 +2199,20 @@ var SmartArtGraphic = class extends XmlComponent {
2528
2199
  var SmartArtGraphicData = class extends XmlComponent {
2529
2200
  constructor(smartArtKey) {
2530
2201
  super("a:graphicData");
2531
- this.root.push(new NextAttributeComponent({ uri: {
2532
- key: "uri",
2533
- value: "http://schemas.openxmlformats.org/drawingml/2006/diagram"
2534
- } }));
2202
+ this.root.push(buildAttrObject({ uri: "http://schemas.openxmlformats.org/drawingml/2006/diagram" }));
2535
2203
  this.root.push(new DiagramRelIds(smartArtKey));
2536
2204
  }
2537
2205
  };
2538
2206
  var DiagramRelIds = class extends XmlComponent {
2539
2207
  constructor(smartArtKey) {
2540
2208
  super("dgm:relIds");
2541
- this.root.push(new NextAttributeComponent({
2542
- xmlnsDgm: {
2543
- key: "xmlns:dgm",
2544
- value: "http://schemas.openxmlformats.org/drawingml/2006/diagram"
2545
- },
2546
- xmlnsR: {
2547
- key: "xmlns:r",
2548
- value: "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
2549
- },
2550
- rDm: {
2551
- key: "r:dm",
2552
- value: `{smartart:${smartArtKey}}`
2553
- },
2554
- rLo: {
2555
- key: "r:lo",
2556
- value: `{smartart-lo:${smartArtKey}}`
2557
- },
2558
- rQs: {
2559
- key: "r:qs",
2560
- value: `{smartart-qs:${smartArtKey}}`
2561
- },
2562
- rCs: {
2563
- key: "r:cs",
2564
- value: `{smartart-cs:${smartArtKey}}`
2565
- }
2209
+ this.root.push(buildAttrObject({
2210
+ "xmlns:dgm": "http://schemas.openxmlformats.org/drawingml/2006/diagram",
2211
+ "xmlns:r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
2212
+ "r:dm": `{smartart:${smartArtKey}}`,
2213
+ "r:lo": `{smartart-lo:${smartArtKey}}`,
2214
+ "r:qs": `{smartart-qs:${smartArtKey}}`,
2215
+ "r:cs": `{smartart-cs:${smartArtKey}}`
2566
2216
  }));
2567
2217
  }
2568
2218
  };
@@ -2571,7 +2221,7 @@ var DiagramRelIds = class extends XmlComponent {
2571
2221
  init_xml_components();
2572
2222
  /**
2573
2223
  * a:graphic > a:graphicData — DrawingML graphic wrapper for table.
2574
- * Lazy: stores table reference, builds IXmlableObject in prepForXml.
2224
+ * Lazy: stores table reference, builds XML in toXml().
2575
2225
  */
2576
2226
  var Graphic = class extends BaseXmlComponent {
2577
2227
  table;
@@ -2579,12 +2229,6 @@ var Graphic = class extends BaseXmlComponent {
2579
2229
  super("a:graphic");
2580
2230
  this.table = table;
2581
2231
  }
2582
- prepForXml(context) {
2583
- const tableObj = this.table.prepForXml(context);
2584
- const graphicDataChildren = [{ _attr: { uri: "http://schemas.openxmlformats.org/drawingml/2006/table" } }];
2585
- if (tableObj) graphicDataChildren.push(tableObj);
2586
- return { "a:graphic": [{ "a:graphicData": graphicDataChildren }] };
2587
- }
2588
2232
  toXml(context) {
2589
2233
  return `<a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/table">${this.table.toXml(context)}</a:graphicData></a:graphic>`;
2590
2234
  }
@@ -2631,7 +2275,7 @@ var GraphicFrameNonVisual = class GraphicFrameNonVisual extends XmlComponent {
2631
2275
  init_xml_components();
2632
2276
  /**
2633
2277
  * a:tblGrid — Table grid with column width definitions.
2634
- * Lazy: stores widths, builds IXmlableObject in prepForXml.
2278
+ * Lazy: stores widths, builds XML in toXml().
2635
2279
  */
2636
2280
  var TableGrid = class extends BaseXmlComponent {
2637
2281
  columnWidths;
@@ -2639,9 +2283,6 @@ var TableGrid = class extends BaseXmlComponent {
2639
2283
  super("a:tblGrid");
2640
2284
  this.columnWidths = columnWidths;
2641
2285
  }
2642
- prepForXml(_context) {
2643
- return { "a:tblGrid": this.columnWidths.map((w) => ({ "a:gridCol": { _attr: { w } } })) };
2644
- }
2645
2286
  toXml(_context) {
2646
2287
  return `<a:tblGrid>${this.columnWidths.map((w) => `<a:gridCol w="${w}"/>`).join("")}</a:tblGrid>`;
2647
2288
  }
@@ -2651,7 +2292,7 @@ var TableGrid = class extends BaseXmlComponent {
2651
2292
  init_xml_components();
2652
2293
  /**
2653
2294
  * a:tblPr — Table properties (firstRow, bandRow, etc.).
2654
- * Lazy: stores options, builds IXmlableObject in prepForXml.
2295
+ * Lazy: stores options, builds XML in toXml().
2655
2296
  */
2656
2297
  var TableProperties = class extends BaseXmlComponent {
2657
2298
  options;
@@ -2659,18 +2300,6 @@ var TableProperties = class extends BaseXmlComponent {
2659
2300
  super("a:tblPr");
2660
2301
  this.options = options;
2661
2302
  }
2662
- prepForXml(_context) {
2663
- if (!this.options) return { "a:tblPr": {} };
2664
- const attrs = {};
2665
- const opts = this.options;
2666
- if (opts.firstRow !== void 0) attrs.firstRow = opts.firstRow ? 1 : 0;
2667
- if (opts.lastRow !== void 0) attrs.lastRow = opts.lastRow ? 1 : 0;
2668
- if (opts.bandRow !== void 0) attrs.bandRow = opts.bandRow ? 1 : 0;
2669
- if (opts.firstCol !== void 0) attrs.firstCol = opts.firstCol ? 1 : 0;
2670
- if (opts.lastCol !== void 0) attrs.lastCol = opts.lastCol ? 1 : 0;
2671
- if (opts.bandCol !== void 0) attrs.bandCol = opts.bandCol ? 1 : 0;
2672
- return { "a:tblPr": Object.keys(attrs).length > 0 ? { _attr: attrs } : {} };
2673
- }
2674
2303
  toXml(_context) {
2675
2304
  if (!this.options) return "<a:tblPr/>";
2676
2305
  const opts = this.options;
@@ -2689,7 +2318,7 @@ var TableProperties = class extends BaseXmlComponent {
2689
2318
  init_xml_components();
2690
2319
  /**
2691
2320
  * a:tr — Table row containing cells.
2692
- * Lazy: stores options, builds IXmlableObject in prepForXml.
2321
+ * Lazy: stores options, builds XML in toXml().
2693
2322
  */
2694
2323
  var TableRow = class extends BaseXmlComponent {
2695
2324
  options;
@@ -2697,15 +2326,6 @@ var TableRow = class extends BaseXmlComponent {
2697
2326
  super("a:tr");
2698
2327
  this.options = options;
2699
2328
  }
2700
- prepForXml(context) {
2701
- const children = [];
2702
- children.push({ _attr: { h: this.options.height ?? 0 } });
2703
- for (const cell of this.options.cells) {
2704
- const obj = new TableCell(cell).prepForXml(context);
2705
- if (obj) children.push(obj);
2706
- }
2707
- return { "a:tr": children };
2708
- }
2709
2329
  toXml(context) {
2710
2330
  const h = this.options.height ?? 0;
2711
2331
  const parts = [];
@@ -2718,7 +2338,7 @@ var TableRow = class extends BaseXmlComponent {
2718
2338
  init_xml_components();
2719
2339
  /**
2720
2340
  * a:tbl — DrawingML table element.
2721
- * Lazy: stores options, builds IXmlableObject in prepForXml.
2341
+ * Lazy: stores options, builds XML in toXml().
2722
2342
  */
2723
2343
  var DrawingTable = class extends BaseXmlComponent {
2724
2344
  options;
@@ -2726,32 +2346,6 @@ var DrawingTable = class extends BaseXmlComponent {
2726
2346
  super("a:tbl");
2727
2347
  this.options = options;
2728
2348
  }
2729
- prepForXml(context) {
2730
- const opts = this.options;
2731
- const children = [];
2732
- const tblPrObj = new TableProperties({
2733
- firstRow: opts.firstRow,
2734
- lastRow: opts.lastRow,
2735
- bandRow: opts.bandRow,
2736
- firstCol: opts.firstCol,
2737
- lastCol: opts.lastCol,
2738
- bandCol: opts.bandCol
2739
- }).prepForXml(context);
2740
- if (tblPrObj) children.push(tblPrObj);
2741
- const gridObj = new TableGrid(opts.columnWidths && opts.columnWidths.length > 0 ? opts.columnWidths : Array.from({ length: opts.rows[0]?.cells.length ?? 1 }, () => 0)).prepForXml(context);
2742
- if (gridObj) children.push(gridObj);
2743
- const rowCount = opts.rows.length;
2744
- for (let ri = 0; ri < rowCount; ri++) {
2745
- const row = opts.rows[ri];
2746
- const cells = this.distributeBorders(row, ri, rowCount, opts.borders);
2747
- const trObj = new TableRow({
2748
- ...row,
2749
- cells
2750
- }).prepForXml(context);
2751
- if (trObj) children.push(trObj);
2752
- }
2753
- return { "a:tbl": children };
2754
- }
2755
2349
  toXml(context) {
2756
2350
  const opts = this.options;
2757
2351
  const parts = [];
@@ -2995,8 +2589,8 @@ function buildChildrenXml$1(children) {
2995
2589
  const ctx = { stack: [] };
2996
2590
  let result = "";
2997
2591
  for (const child of children) {
2998
- const obj = coerceMasterChild(child).prepForXml(ctx);
2999
- if (obj) result += xml(obj);
2592
+ const xmlStr = coerceMasterChild(child).toXml(ctx);
2593
+ if (xmlStr) result += xmlStr;
3000
2594
  }
3001
2595
  return result;
3002
2596
  }
@@ -3057,9 +2651,6 @@ var SlideLayout = class SlideLayout extends ImportedXmlComponent {
3057
2651
  if (!SlideLayout.cache.has(this.cacheKey)) SlideLayout.cache.set(this.cacheKey, ImportedXmlComponent.fromXmlString(buildLayoutXml(layoutType, slideWidth)));
3058
2652
  }
3059
2653
  }
3060
- prepForXml() {
3061
- return SlideLayout.cache.get(this.cacheKey).prepForXml({ stack: [] });
3062
- }
3063
2654
  toXml(context) {
3064
2655
  return SlideLayout.cache.get(this.cacheKey).toXml(context);
3065
2656
  }
@@ -3127,17 +2718,15 @@ function footerBody(algn, fldType, fldId, fldText) {
3127
2718
  function buildBackgroundXml(bg) {
3128
2719
  if (!bg) return `<p:bgRef idx="1001"><a:schemeClr val="bg1"/></p:bgRef>`;
3129
2720
  const { Background } = (init_background(), __toCommonJS(background_exports));
3130
- const obj = new Background(bg).prepForXml({ stack: [] });
3131
- if (!obj) return `<p:bgRef idx="1001"><a:schemeClr val="bg1"/></p:bgRef>`;
3132
- return xml(obj).replace(/^<p:bg[^>]*>/, "").replace(/<\/p:bg>$/, "");
2721
+ return new Background(bg).toXml({ stack: [] }).replace(/^<p:bg[^>]*>/, "").replace(/<\/p:bg>$/, "");
3133
2722
  }
3134
2723
  function buildChildrenXml(children) {
3135
2724
  if (!children || children.length === 0) return "";
3136
2725
  const ctx = { stack: [] };
3137
2726
  let result = "";
3138
2727
  for (const child of children) {
3139
- const obj = coerceMasterChild(child).prepForXml(ctx);
3140
- if (obj) result += xml(obj);
2728
+ const xmlStr = coerceMasterChild(child).toXml(ctx);
2729
+ if (xmlStr) result += xmlStr;
3141
2730
  }
3142
2731
  return result;
3143
2732
  }
@@ -3180,9 +2769,6 @@ var DefaultSlideMaster = class DefaultSlideMaster extends ImportedXmlComponent {
3180
2769
  this.cacheKey = `${layoutCount}:${masterOptions ? JSON.stringify(masterOptions) : ""}:${slideWidth}:${masterIndex}`;
3181
2770
  if (!DefaultSlideMaster.cache.has(this.cacheKey)) DefaultSlideMaster.cache.set(this.cacheKey, ImportedXmlComponent.fromXmlString(buildSlideMasterXml(layoutCount, headerFooter, masterOptions, slideWidth, masterIndex)));
3182
2771
  }
3183
- prepForXml() {
3184
- return DefaultSlideMaster.cache.get(this.cacheKey).prepForXml({ stack: [] });
3185
- }
3186
2772
  toXml(context) {
3187
2773
  return DefaultSlideMaster.cache.get(this.cacheKey).toXml(context);
3188
2774
  }
@@ -4269,33 +3855,33 @@ const DIRECTION_MAP = {
4269
3855
  in: "in"
4270
3856
  };
4271
3857
  function buildTransitionElement(type, direction, orient, thruBlk, spokes) {
4272
- const attrs = {};
4273
3858
  const dir = direction ? DIRECTION_MAP[direction] : void 0;
4274
- if (ORIENT_TYPES.has(type) && dir) attrs.dir = dir;
4275
- else if (SIDE_DIR_TYPES.has(type) && dir) attrs.dir = dir;
4276
- else if (EIGHT_DIR_TYPES.has(type) && dir) attrs.dir = dir;
4277
- else if (type === "strips" && dir) attrs.dir = dir;
4278
- else if ((type === "fade" || type === "cut") && thruBlk !== void 0) attrs.thruBlk = thruBlk ? 1 : 0;
4279
- else if (type === "split") {
4280
- attrs.orient = orient ?? "horz";
4281
- attrs.dir = dir ?? "out";
4282
- } else if (type === "wheel") attrs.spokes = spokes ?? 4;
4283
- else if (type === "zoom" && dir) attrs.dir = dir;
4284
- return { [`p:${type}`]: Object.keys(attrs).length > 0 ? { _attr: attrs } : {} };
3859
+ const attrs = [];
3860
+ if (ORIENT_TYPES.has(type) && dir) attrs.push(`dir="${dir}"`);
3861
+ else if (SIDE_DIR_TYPES.has(type) && dir) attrs.push(`dir="${dir}"`);
3862
+ else if (EIGHT_DIR_TYPES.has(type) && dir) attrs.push(`dir="${dir}"`);
3863
+ else if (type === "strips" && dir) attrs.push(`dir="${dir}"`);
3864
+ else if ((type === "fade" || type === "cut") && thruBlk !== void 0) attrs.push(`thruBlk="${thruBlk ? 1 : 0}"`);
3865
+ else if (type === "split") attrs.push(`orient="${orient ?? "horz"}"`, `dir="${dir ?? "out"}"`);
3866
+ else if (type === "wheel") attrs.push(`spokes="${spokes ?? 4}"`);
3867
+ else if (type === "zoom" && dir) attrs.push(`dir="${dir}"`);
3868
+ return attrs.length > 0 ? `<p:${type} ${attrs.join(" ")}/>` : `<p:${type}/>`;
4285
3869
  }
4286
3870
  function buildTransition(options) {
3871
+ const attrParts = [];
3872
+ if (options.speed) attrParts.push(`spd="${options.speed}"`);
3873
+ if (options.advanceOnClick !== void 0) attrParts.push(`advClick="${options.advanceOnClick ? 1 : 0}"`);
3874
+ if (options.advanceAfterTime !== void 0) attrParts.push(`advTm="${options.advanceAfterTime}"`);
4287
3875
  const children = [];
4288
- const attrs = {};
4289
- if (options.speed) attrs.spd = options.speed;
4290
- if (options.advanceOnClick !== void 0) attrs.advClick = options.advanceOnClick ? 1 : 0;
4291
- if (options.advanceAfterTime !== void 0) attrs.advTm = options.advanceAfterTime;
4292
- if (Object.keys(attrs).length > 0) children.push({ _attr: attrs });
4293
3876
  if (options.type) children.push(buildTransitionElement(options.type, options.direction, options.orient, options.thruBlk, options.spokes));
4294
- return { "p:transition": children.length === 0 ? {} : children };
3877
+ if (attrParts.length === 0 && children.length === 0) return "<p:transition/>";
3878
+ const attrStr = attrParts.length > 0 ? ` ${attrParts.join(" ")}` : "";
3879
+ if (children.length === 0) return `<p:transition${attrStr}/>`;
3880
+ return `<p:transition${attrStr}>${children.join("")}</p:transition>`;
4295
3881
  }
4296
3882
  /**
4297
3883
  * p:transition — Slide transition effect.
4298
- * Lazy: stores options, builds XML object in prepForXml.
3884
+ * Lazy: stores options, builds XML in toXml.
4299
3885
  */
4300
3886
  var Transition = class extends BaseXmlComponent {
4301
3887
  options;
@@ -4303,7 +3889,7 @@ var Transition = class extends BaseXmlComponent {
4303
3889
  super("p:transition");
4304
3890
  this.options = options;
4305
3891
  }
4306
- prepForXml(_context) {
3892
+ toXml(_context) {
4307
3893
  return buildTransition(this.options);
4308
3894
  }
4309
3895
  };
@@ -4326,7 +3912,7 @@ function collectAnimations(children) {
4326
3912
  }
4327
3913
  /**
4328
3914
  * p:sld — A slide in a presentation.
4329
- * Lazy: stores options, builds XML object in prepForXml.
3915
+ * Lazy: stores options, builds XML in toXml().
4330
3916
  */
4331
3917
  var Slide = class extends XmlComponent {
4332
3918
  children;
@@ -4340,70 +3926,11 @@ var Slide = class extends XmlComponent {
4340
3926
  this.transition = transition;
4341
3927
  this.HeaderFooter = headerFooter;
4342
3928
  }
4343
- prepForXml(context) {
4344
- const children = [];
4345
- children.push({ _attr: {
4346
- "xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
4347
- "xmlns:r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
4348
- "xmlns:p": "http://schemas.openxmlformats.org/presentationml/2006/main"
4349
- } });
4350
- const cSldChildren = [];
4351
- if (this.background) {
4352
- const bgObj = this.background.prepForXml(context);
4353
- if (bgObj) cSldChildren.push(bgObj);
4354
- }
4355
- const spTreeChildren = [{ "p:nvGrpSpPr": [
4356
- { "p:cNvPr": { _attr: {
4357
- id: 1,
4358
- name: ""
4359
- } } },
4360
- { "p:cNvGrpSpPr": {} },
4361
- { "p:nvPr": {} }
4362
- ] }, { "p:grpSpPr": [{ "a:xfrm": [
4363
- { "a:off": { _attr: {
4364
- x: 0,
4365
- y: 0
4366
- } } },
4367
- { "a:ext": { _attr: {
4368
- cx: 0,
4369
- cy: 0
4370
- } } },
4371
- { "a:chOff": { _attr: {
4372
- x: 0,
4373
- y: 0
4374
- } } },
4375
- { "a:chExt": { _attr: {
4376
- cx: 0,
4377
- cy: 0
4378
- } } }
4379
- ] }] }];
4380
- const coercedChildren = this.children.map(coerceChild);
4381
- for (const child of coercedChildren) {
4382
- const obj = child.prepForXml(context);
4383
- if (obj) spTreeChildren.push(obj);
4384
- }
4385
- cSldChildren.push({ "p:spTree": spTreeChildren });
4386
- children.push({ "p:cSld": cSldChildren });
4387
- children.push({ "p:clrMapOvr": [{ "a:masterClrMapping": {} }] });
4388
- if (this.transition) {
4389
- const transObj = buildTransition(this.transition);
4390
- if (transObj) children.push(transObj);
4391
- }
4392
- const animations = collectAnimations(coercedChildren);
4393
- if (animations.length > 0) {
4394
- const timingObj = new SlideTiming(animations).prepForXml(context);
4395
- if (timingObj) children.push(timingObj);
4396
- }
4397
- return { "p:sld": children };
4398
- }
4399
3929
  toXml(context) {
4400
3930
  const parts = [];
4401
3931
  parts.push("<p:sld 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\">");
4402
3932
  parts.push("<p:cSld>");
4403
- if (this.background) {
4404
- const bgObj = this.background.prepForXml(context);
4405
- if (bgObj) parts.push(xml(bgObj));
4406
- }
3933
+ if (this.background) parts.push(this.background.toXml(context));
4407
3934
  parts.push("<p:spTree>");
4408
3935
  parts.push("<p:nvGrpSpPr><p:cNvPr id=\"1\" name=\"\"/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr>");
4409
3936
  parts.push("<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>");
@@ -4415,14 +3942,11 @@ var Slide = class extends XmlComponent {
4415
3942
  parts.push("</p:spTree>");
4416
3943
  parts.push("</p:cSld>");
4417
3944
  parts.push("<p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr>");
4418
- if (this.transition) {
4419
- const transObj = buildTransition(this.transition);
4420
- if (transObj) parts.push(xml(transObj));
4421
- }
3945
+ if (this.transition) parts.push(buildTransition(this.transition));
4422
3946
  const animations = collectAnimations(coercedChildren);
4423
3947
  if (animations.length > 0) {
4424
- const timingObj = new SlideTiming(animations).prepForXml(context);
4425
- if (timingObj) parts.push(xml(timingObj));
3948
+ const timing = new SlideTiming(animations);
3949
+ parts.push(timing.toXml(context));
4426
3950
  }
4427
3951
  parts.push("</p:sld>");
4428
3952
  return parts.join("");
@@ -4437,9 +3961,6 @@ var TableStyles = class TableStyles extends ImportedXmlComponent {
4437
3961
  constructor() {
4438
3962
  super("a:tblStyleLst");
4439
3963
  }
4440
- prepForXml() {
4441
- return TableStyles.instance.prepForXml({ stack: [] });
4442
- }
4443
3964
  toXml(context) {
4444
3965
  return TableStyles.instance.toXml(context);
4445
3966
  }
@@ -4535,9 +4056,6 @@ var DefaultTheme = class DefaultTheme extends ImportedXmlComponent {
4535
4056
  this.cacheKey = options ? themeKey(options) : "";
4536
4057
  if (!DefaultTheme.cache.has(this.cacheKey)) DefaultTheme.cache.set(this.cacheKey, ImportedXmlComponent.fromXmlString(buildThemeXml(options)));
4537
4058
  }
4538
- prepForXml() {
4539
- return DefaultTheme.cache.get(this.cacheKey).prepForXml({ stack: [] });
4540
- }
4541
4059
  toXml(context) {
4542
4060
  return DefaultTheme.cache.get(this.cacheKey).toXml(context);
4543
4061
  }
@@ -4577,9 +4095,6 @@ var ViewProperties = class ViewProperties extends ImportedXmlComponent {
4577
4095
  constructor() {
4578
4096
  super("p:viewPr");
4579
4097
  }
4580
- prepForXml() {
4581
- return ViewProperties.instance.prepForXml({ stack: [] });
4582
- }
4583
4098
  toXml(context) {
4584
4099
  return ViewProperties.instance.toXml(context);
4585
4100
  }
@@ -4918,7 +4433,7 @@ var File = class {
4918
4433
  this._slideCommentLists[i] = new SlideCommentList(commentEntries);
4919
4434
  }
4920
4435
  if (authorMap.size > 0) {
4921
- const authors = [...authorMap.values()].map((a) => ({
4436
+ const authors = Array.from(authorMap.values(), (a) => ({
4922
4437
  id: a.id,
4923
4438
  name: a.name,
4924
4439
  initials: a.initials,
@@ -4942,6 +4457,23 @@ var Text = class extends XmlComponent {
4942
4457
  }
4943
4458
  };
4944
4459
  //#endregion
4460
+ //#region src/file/shape/paragraph/end-paragraph-run.ts
4461
+ init_xml_components();
4462
+ /**
4463
+ * a:endParaRPr — End paragraph run properties.
4464
+ * Lazy: stores lang, builds XML in toXml().
4465
+ */
4466
+ var EndParagraphRunProperties = class extends BuilderElement {
4467
+ lang;
4468
+ constructor(lang = "en-US") {
4469
+ super({ name: "a:endParaRPr" });
4470
+ this.lang = lang;
4471
+ }
4472
+ toXml(_context) {
4473
+ return `<a:endParaRPr lang="${this.lang}"/>`;
4474
+ }
4475
+ };
4476
+ //#endregion
4945
4477
  //#region src/file/shape/paragraph/field.ts
4946
4478
  init_xml_components();
4947
4479
  /**
@@ -4952,15 +4484,9 @@ init_xml_components();
4952
4484
  var Field = class extends XmlComponent {
4953
4485
  constructor(fieldType, displayText) {
4954
4486
  super("a:fld");
4955
- this.root.push(new NextAttributeComponent({
4956
- id: {
4957
- key: "id",
4958
- value: `{${crypto.randomUUID()}}`
4959
- },
4960
- type: {
4961
- key: "type",
4962
- value: fieldType
4963
- }
4487
+ this.root.push(buildAttrObject({
4488
+ id: `{${crypto.randomUUID()}}`,
4489
+ type: fieldType
4964
4490
  }));
4965
4491
  this.root.push(new BuilderElement({
4966
4492
  name: "a:rPr",
@@ -5064,9 +4590,6 @@ var DefaultNotesMaster = class DefaultNotesMaster extends ImportedXmlComponent {
5064
4590
  constructor() {
5065
4591
  super("p:notesMaster");
5066
4592
  }
5067
- prepForXml() {
5068
- return DefaultNotesMaster.instance.prepForXml({ stack: [] });
5069
- }
5070
4593
  toXml(context) {
5071
4594
  return DefaultNotesMaster.instance.toXml(context);
5072
4595
  }
@@ -5084,23 +4607,11 @@ var HeaderFooter = class extends XmlComponent {
5084
4607
  constructor(options = {}) {
5085
4608
  super("p:hf");
5086
4609
  const attrs = {};
5087
- if (options.slideNumber !== false) attrs.sldNum = {
5088
- key: "sldNum",
5089
- value: 1
5090
- };
5091
- if (options.dateTime !== false) attrs.dt = {
5092
- key: "dt",
5093
- value: 1
5094
- };
5095
- if (options.header === true) attrs.hdr = {
5096
- key: "hdr",
5097
- value: 1
5098
- };
5099
- if (options.footer !== false && options.footer !== void 0) attrs.ftr = {
5100
- key: "ftr",
5101
- value: 1
5102
- };
5103
- if (Object.keys(attrs).length > 0) this.root.push(new NextAttributeComponent(attrs));
4610
+ if (options.slideNumber !== false) attrs.sldNum = 1;
4611
+ if (options.dateTime !== false) attrs.dt = 1;
4612
+ if (options.header === true) attrs.hdr = 1;
4613
+ if (options.footer !== false && options.footer !== void 0) attrs.ftr = 1;
4614
+ if (Object.keys(attrs).length > 0) this.root.push(buildAttrObject(attrs));
5104
4615
  if (typeof options.footer === "string") this.root.push(new BuilderElement({
5105
4616
  name: "p:ftr",
5106
4617
  children: [new BuilderElement({
@@ -5135,25 +4646,19 @@ init_background();
5135
4646
  //#region src/export/packer/hyperlink-placeholders.ts
5136
4647
  function replaceHyperlinkPlaceholders(xml, hyperlinks, offset) {
5137
4648
  let result = xml;
5138
- hyperlinks.forEach((h, i) => {
5139
- result = result.replaceAll(`{hlink:${h.key}}`, formatId(offset, i, "rId"));
5140
- });
4649
+ for (let i = 0; i < hyperlinks.length; i++) result = result.replaceAll(`{hlink:${hyperlinks[i].key}}`, formatId(offset, i, "rId"));
5141
4650
  return result;
5142
4651
  }
5143
4652
  //#endregion
5144
4653
  //#region src/export/packer/media-placeholders.ts
5145
4654
  function replaceMediaPlaceholders(xml, mediaData, offset) {
5146
4655
  let result = xml;
5147
- mediaData.forEach((m, i) => {
5148
- result = result.replaceAll(`{media:${m.fileName}}`, formatId(offset, i, "rId"));
5149
- });
4656
+ for (let i = 0; i < mediaData.length; i++) result = result.replaceAll(`{media:${mediaData[i].fileName}}`, formatId(offset, i, "rId"));
5150
4657
  return result;
5151
4658
  }
5152
4659
  function replaceVideoPlaceholders(xml, mediaData, offset) {
5153
4660
  let result = xml;
5154
- mediaData.forEach((m, i) => {
5155
- result = result.replaceAll(`{video:${m.fileName}}`, formatId(offset, i, "rId"));
5156
- });
4661
+ for (let i = 0; i < mediaData.length; i++) result = result.replaceAll(`{video:${mediaData[i].fileName}}`, formatId(offset, i, "rId"));
5157
4662
  return result;
5158
4663
  }
5159
4664
  function getMediaRefs(xml, mediaArray) {
@@ -5437,6 +4942,8 @@ var util_exports = /* @__PURE__ */ __exportAll({
5437
4942
  //#endregion
5438
4943
  //#region src/parse/context.ts
5439
4944
  var ParseContext = class {
4945
+ pptx;
4946
+ slideRels;
5440
4947
  constructor(pptx, slideRels) {
5441
4948
  this.pptx = pptx;
5442
4949
  this.slideRels = slideRels;
@@ -7188,6 +6695,10 @@ function parseRootRels(doc) {
7188
6695
  };
7189
6696
  }
7190
6697
  function parseSlideRels(doc, slidePaths, refs) {
6698
+ const commentsSet = new Set(refs.comments);
6699
+ const chartsSet = new Set(refs.charts);
6700
+ const diagramDataSet = new Set(refs.diagramData);
6701
+ const mediaSet = new Set(refs.media);
7191
6702
  for (const slidePath of slidePaths) {
7192
6703
  const parts = slidePath.split("/");
7193
6704
  const fileName = parts.pop();
@@ -7200,17 +6711,16 @@ function parseSlideRels(doc, slidePaths, refs) {
7200
6711
  const target = attr(child, "Target") ?? "";
7201
6712
  if (!target) continue;
7202
6713
  const path = resolveRelsPath(target);
7203
- if (type.includes("/comments") && !type.includes("commentAuthors")) {
7204
- if (!refs.comments.includes(path)) refs.comments.push(path);
7205
- } else if (type.includes("/chart")) {
7206
- if (!refs.charts.includes(path)) refs.charts.push(path);
7207
- } else if (type.includes("/diagramData")) {
7208
- if (!refs.diagramData.includes(path)) refs.diagramData.push(path);
7209
- } else if (type.includes("/image") || type.includes("/video") || type.includes("/media")) {
7210
- if (!refs.media.includes(path)) refs.media.push(path);
7211
- }
6714
+ if (type.includes("/comments") && !type.includes("commentAuthors")) commentsSet.add(path);
6715
+ else if (type.includes("/chart")) chartsSet.add(path);
6716
+ else if (type.includes("/diagramData")) diagramDataSet.add(path);
6717
+ else if (type.includes("/image") || type.includes("/video") || type.includes("/media")) mediaSet.add(path);
7212
6718
  }
7213
6719
  }
6720
+ refs.comments = [...commentsSet];
6721
+ refs.charts = [...chartsSet];
6722
+ refs.diagramData = [...diagramDataSet];
6723
+ refs.media = [...mediaSet];
7214
6724
  }
7215
6725
  function parsePptx(data) {
7216
6726
  const doc = parseArchive(toUint8Array(data));