ooxml-core 1.19.2 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -1
- package/dist/{PptxHandler-2V4PQL6O.mjs → PptxHandler-FYD7IYXT.mjs} +2 -2
- package/dist/PptxHandler-SITN3K3F.mjs +4 -0
- package/dist/{PptxHandler-6TNIQ7S5.cjs → PptxHandler-TEKISCJO.cjs} +3 -3
- package/dist/{PresentationBuilder-HQ6C7L4V.mjs → PresentationBuilder-EYI6Z2JP.mjs} +2 -2
- package/dist/{PresentationBuilder-G7MPEGXJ.mjs → PresentationBuilder-IMB4DVRN.mjs} +2 -2
- package/dist/{PresentationBuilder-RM52LCVN.cjs → PresentationBuilder-NCKASKXU.cjs} +5 -5
- package/dist/automation/index.cjs +257 -30
- package/dist/automation/index.mjs +256 -31
- package/dist/automation/xlsx-read.d.ts +56 -0
- package/dist/automation/xlsx-read.d.ts.map +1 -0
- package/dist/automation/xlsx.d.ts +105 -4
- package/dist/automation/xlsx.d.ts.map +1 -1
- package/dist/{chunk-M6GDBVQ7.mjs → chunk-GQYQQ3GA.mjs} +1 -1
- package/dist/{chunk-SLNQNVQM.mjs → chunk-LEV2SVMK.mjs} +1 -1
- package/dist/{chunk-JUABSM7C.mjs → chunk-LVM3IZJ2.mjs} +1 -1
- package/dist/{chunk-TJPUAUWL.mjs → chunk-MN27HKHM.mjs} +8 -194
- package/dist/{chunk-4FTUAD2B.mjs → chunk-MNXKRXFB.mjs} +715 -200
- package/dist/{chunk-R5FIHHGB.cjs → chunk-NXKATFM5.cjs} +1598 -1204
- package/dist/{chunk-ZJ2OKIJN.mjs → chunk-WXY5EDGT.mjs} +592 -198
- package/dist/index.cjs +25 -0
- package/dist/index.mjs +25 -0
- package/dist/pptx/automation/index.cjs +887 -453
- package/dist/pptx/automation/index.d.ts +2 -2
- package/dist/pptx/automation/index.mjs +5 -5
- package/dist/pptx/chunks/{index-Bqm-jFG-.d.ts → index-CgFX0T7b.d.ts} +7573 -7508
- package/dist/pptx/chunks/index-CgFX0T7b.d.ts.map +1 -0
- package/dist/pptx/chunks/{index-B9x557hr.d.ts → index-qwVYoFn6.d.ts} +2 -2
- package/dist/pptx/chunks/{index-B9x557hr.d.ts.map → index-qwVYoFn6.d.ts.map} +1 -1
- package/dist/pptx/cli/index.cjs +654 -221
- package/dist/pptx/cli/index.mjs +4 -4
- package/dist/pptx/converter/index.d.ts +1 -1
- package/dist/pptx/converter/index.mjs +2 -2
- package/dist/pptx/editor/render/find-replace.cjs +14 -14
- package/dist/pptx/editor/render/find-replace.d.ts +1 -1
- package/dist/pptx/editor/render/find-replace.mjs +1 -1
- package/dist/pptx/editor/render/slide-operations.cjs +8 -8
- package/dist/pptx/editor/render/slide-operations.mjs +2 -2
- package/dist/pptx/index.cjs +991 -619
- package/dist/pptx/index.d.ts +3 -3
- package/dist/pptx/index.mjs +5 -5
- package/dist/visio/index.cjs +61 -7
- package/dist/visio/index.mjs +61 -7
- package/dist/visio/ui/contract.d.ts +2 -1
- package/dist/visio/ui/contract.d.ts.map +1 -1
- package/dist/visio/ui/index.cjs +62 -7
- package/dist/visio/ui/index.mjs +62 -7
- package/dist/xlsx/edit/dimensions.d.ts.map +1 -1
- package/dist/xlsx/edit/history-rows.d.ts +7 -0
- package/dist/xlsx/edit/history-rows.d.ts.map +1 -0
- package/dist/xlsx/edit/history.d.ts +11 -1
- package/dist/xlsx/edit/history.d.ts.map +1 -1
- package/dist/xlsx/edit/outline.d.ts.map +1 -1
- package/dist/xlsx/edit/row-autofit.d.ts.map +1 -1
- package/dist/xlsx/index.cjs +90 -16
- package/dist/xlsx/index.mjs +90 -16
- package/dist/xlsx/load/index.cjs +61 -7
- package/dist/xlsx/load/index.mjs +61 -7
- package/dist/xlsx/numfmt/format.d.ts +8 -0
- package/dist/xlsx/numfmt/format.d.ts.map +1 -1
- package/dist/xlsx/read/sheet-data-source.d.ts.map +1 -1
- package/dist/xlsx/ui/index.cjs +138 -16
- package/dist/xlsx/ui/index.d.ts +1 -0
- package/dist/xlsx/ui/index.d.ts.map +1 -1
- package/dist/xlsx/ui/index.mjs +138 -17
- package/dist/xlsx/ui/selection-format.d.ts +13 -0
- package/dist/xlsx/ui/selection-format.d.ts.map +1 -0
- package/dist/xml/index.cjs +25 -0
- package/dist/xml/index.mjs +25 -0
- package/dist/xml/lite.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/PptxHandler-HSPKEP5E.mjs +0 -4
- package/dist/pptx/chunks/index-Bqm-jFG-.d.ts.map +0 -1
- /package/dist/{chunk-NYTR4UZ5.cjs → chunk-3IENHIFD.cjs} +0 -0
- /package/dist/{chunk-XTSHZGSM.mjs → chunk-CC5UNZOO.mjs} +0 -0
package/dist/pptx/index.cjs
CHANGED
|
@@ -4696,13 +4696,14 @@ var init_SlideBuilder = __esm({
|
|
|
4696
4696
|
"pptx/core/builders/sdk/SlideBuilder.ts"() {
|
|
4697
4697
|
init_ElementFactory();
|
|
4698
4698
|
exports.SlideBuilder = class {
|
|
4699
|
-
slide;
|
|
4700
4699
|
/**
|
|
4701
4700
|
* @param slideNumber - 1-based slide number.
|
|
4702
4701
|
* @param layoutPath - Optional layout archive path.
|
|
4703
4702
|
* @param layoutName - Optional layout display name.
|
|
4703
|
+
* @param handler - Loaded deck context for placeholder geometry and text styles.
|
|
4704
4704
|
*/
|
|
4705
|
-
constructor(slideNumber, layoutPath, layoutName) {
|
|
4705
|
+
constructor(slideNumber, layoutPath, layoutName, handler) {
|
|
4706
|
+
this.handler = handler;
|
|
4706
4707
|
this.slide = {
|
|
4707
4708
|
id: `slide${slideNumber}`,
|
|
4708
4709
|
rId: `rId${slideNumber + 1}`,
|
|
@@ -4712,11 +4713,52 @@ var init_SlideBuilder = __esm({
|
|
|
4712
4713
|
layoutName: layoutName ?? "Title Slide"
|
|
4713
4714
|
};
|
|
4714
4715
|
}
|
|
4716
|
+
handler;
|
|
4717
|
+
slide;
|
|
4715
4718
|
/** Add a text box to the slide. */
|
|
4716
4719
|
addText(text2, options) {
|
|
4717
4720
|
this.slide.elements.push(createTextElement(text2, options));
|
|
4718
4721
|
return this;
|
|
4719
4722
|
}
|
|
4723
|
+
/**
|
|
4724
|
+
* Fill a layout placeholder, inheriting its frame and text styles.
|
|
4725
|
+
*
|
|
4726
|
+
* Unlike addText, this writes a real p:ph binding, not a free text box.
|
|
4727
|
+
* Use idx to select repeated slots (for example, Two Content's 1 and 2).
|
|
4728
|
+
* Explicit frame fields override the layout; all other fields inherit.
|
|
4729
|
+
* A standalone builder requires the fourth constructor argument (a loaded
|
|
4730
|
+
* handler), even with an explicit frame, so text styles resolve consistently.
|
|
4731
|
+
* Missing slots without a complete frame throw instead of creating a text box.
|
|
4732
|
+
* Master frames requiring compatible-role fallback are materialized locally
|
|
4733
|
+
* for new content only, keeping existing-deck loading unchanged.
|
|
4734
|
+
*
|
|
4735
|
+
* @example
|
|
4736
|
+
* ```ts
|
|
4737
|
+
* createSlide('Title Slide')
|
|
4738
|
+
* .addPlaceholder('ctrTitle', 'Quarterly review')
|
|
4739
|
+
* .addPlaceholder('subTitle', 'October 2026');
|
|
4740
|
+
* createSlide('Two Content').addPlaceholder('body', 'Right column', { idx: 2 });
|
|
4741
|
+
* ```
|
|
4742
|
+
*/
|
|
4743
|
+
addPlaceholder(type, text2, options = {}) {
|
|
4744
|
+
const input = createTextElement(text2);
|
|
4745
|
+
const context = `Slide ${this.slide.slideNumber} (${this.slide.id}), placeholder ${type} idx=${options.idx ?? "auto"}, layout ${this.slide.layoutName} (${this.slide.layoutPath})`;
|
|
4746
|
+
try {
|
|
4747
|
+
if (!this.handler) {
|
|
4748
|
+
throw new Error(
|
|
4749
|
+
"addPlaceholder requires a loaded handler as the fourth SlideBuilder constructor argument"
|
|
4750
|
+
);
|
|
4751
|
+
}
|
|
4752
|
+
this.slide.elements.push(
|
|
4753
|
+
this.handler.createPlaceholderElement(this.slide.layoutPath, input, type, options)
|
|
4754
|
+
);
|
|
4755
|
+
} catch (error) {
|
|
4756
|
+
throw new Error(`${context}: ${error instanceof Error ? error.message : String(error)}`, {
|
|
4757
|
+
cause: error
|
|
4758
|
+
});
|
|
4759
|
+
}
|
|
4760
|
+
return this;
|
|
4761
|
+
}
|
|
4720
4762
|
/** Add a shape to the slide. */
|
|
4721
4763
|
addShape(shapeType, options) {
|
|
4722
4764
|
this.slide.elements.push(createShapeElement(shapeType, options));
|
|
@@ -4956,6 +4998,466 @@ var init_SlideBuilder = __esm({
|
|
|
4956
4998
|
};
|
|
4957
4999
|
}
|
|
4958
5000
|
});
|
|
5001
|
+
function isSafePartName(name) {
|
|
5002
|
+
if (name.includes("\0") || name.includes("\\")) return false;
|
|
5003
|
+
if (/^[A-Za-z]:/u.test(name)) return false;
|
|
5004
|
+
const body = name.startsWith("/") ? name.slice(1) : name;
|
|
5005
|
+
if (body.startsWith("/")) return false;
|
|
5006
|
+
return !body.split("/").some((segment) => segment === "..");
|
|
5007
|
+
}
|
|
5008
|
+
function declaredEntrySize(entry2) {
|
|
5009
|
+
const data = entry2._data;
|
|
5010
|
+
const size = Number(data?.uncompressedSize ?? 0);
|
|
5011
|
+
return Number.isFinite(size) && size > 0 ? size : 0;
|
|
5012
|
+
}
|
|
5013
|
+
function resolveLimits(limits) {
|
|
5014
|
+
const create = limits.createError;
|
|
5015
|
+
return {
|
|
5016
|
+
maxEntries: limits.maxEntries ?? DEFAULT_ZIP_LIMITS.maxEntries,
|
|
5017
|
+
maxEntryBytes: limits.maxEntryBytes ?? DEFAULT_ZIP_LIMITS.maxEntryBytes,
|
|
5018
|
+
maxTotalBytes: limits.maxTotalBytes ?? DEFAULT_ZIP_LIMITS.maxTotalBytes,
|
|
5019
|
+
label: limits.label ?? "ZIP",
|
|
5020
|
+
fail: (message, limit) => create ? create(message, { limit }) : new ZipLimitError(message, { limit })
|
|
5021
|
+
};
|
|
5022
|
+
}
|
|
5023
|
+
function inflateEntryGuarded(entry2, alreadyRead, limits) {
|
|
5024
|
+
const r = resolveLimits(limits);
|
|
5025
|
+
const declared = declaredEntrySize(entry2);
|
|
5026
|
+
return new Promise((resolvePromise, reject) => {
|
|
5027
|
+
const chunks = [];
|
|
5028
|
+
let size = 0;
|
|
5029
|
+
let done = false;
|
|
5030
|
+
const stream = entry2.internalStream("uint8array");
|
|
5031
|
+
const abort = (error) => {
|
|
5032
|
+
if (done) return;
|
|
5033
|
+
done = true;
|
|
5034
|
+
stream.pause();
|
|
5035
|
+
chunks.length = 0;
|
|
5036
|
+
reject(error);
|
|
5037
|
+
};
|
|
5038
|
+
stream.on("data", (chunk2) => {
|
|
5039
|
+
if (done) return;
|
|
5040
|
+
size += chunk2.byteLength;
|
|
5041
|
+
if (size > declared || size > r.maxEntryBytes)
|
|
5042
|
+
return abort(
|
|
5043
|
+
r.fail(`${r.label} part ${entry2.name} inflates past its declared size`, r.maxEntryBytes)
|
|
5044
|
+
);
|
|
5045
|
+
if (alreadyRead + size > r.maxTotalBytes)
|
|
5046
|
+
return abort(
|
|
5047
|
+
r.fail(
|
|
5048
|
+
`${r.label} package exceeds the ${mib(r.maxTotalBytes)} MiB uncompressed content limit`,
|
|
5049
|
+
r.maxTotalBytes
|
|
5050
|
+
)
|
|
5051
|
+
);
|
|
5052
|
+
chunks.push(chunk2);
|
|
5053
|
+
});
|
|
5054
|
+
stream.on("error", (error) => abort(error));
|
|
5055
|
+
stream.on("end", () => {
|
|
5056
|
+
if (done) return;
|
|
5057
|
+
done = true;
|
|
5058
|
+
if (chunks.length === 1 && chunks[0]) return resolvePromise(chunks[0]);
|
|
5059
|
+
const out = new Uint8Array(size);
|
|
5060
|
+
let offset = 0;
|
|
5061
|
+
for (const chunk2 of chunks) {
|
|
5062
|
+
out.set(chunk2, offset);
|
|
5063
|
+
offset += chunk2.byteLength;
|
|
5064
|
+
}
|
|
5065
|
+
resolvePromise(out);
|
|
5066
|
+
});
|
|
5067
|
+
stream.resume();
|
|
5068
|
+
});
|
|
5069
|
+
}
|
|
5070
|
+
function toBase64(bytes) {
|
|
5071
|
+
let binary = "";
|
|
5072
|
+
for (let i2 = 0; i2 < bytes.length; i2 += 32768)
|
|
5073
|
+
binary += String.fromCharCode(...bytes.subarray(i2, i2 + 32768));
|
|
5074
|
+
return btoa(binary);
|
|
5075
|
+
}
|
|
5076
|
+
function guardZip(zip, limits = {}) {
|
|
5077
|
+
const r = resolveLimits(limits);
|
|
5078
|
+
const entries = Object.values(zip.files);
|
|
5079
|
+
if (entries.length > r.maxEntries)
|
|
5080
|
+
throw r.fail(
|
|
5081
|
+
`${r.label} package exceeds the ${r.maxEntries.toLocaleString("en-US")} part limit`,
|
|
5082
|
+
r.maxEntries
|
|
5083
|
+
);
|
|
5084
|
+
let declared = 0;
|
|
5085
|
+
for (const entry2 of entries) {
|
|
5086
|
+
const original = entry2.unsafeOriginalName;
|
|
5087
|
+
if (!isSafePartName(entry2.name) || original !== void 0 && !isSafePartName(original))
|
|
5088
|
+
throw r.fail(`${r.label} package has an unsafe part name`, r.maxEntries);
|
|
5089
|
+
if (entry2.dir) continue;
|
|
5090
|
+
const size = declaredEntrySize(entry2);
|
|
5091
|
+
if (size > r.maxEntryBytes)
|
|
5092
|
+
throw r.fail(
|
|
5093
|
+
`${r.label} part ${entry2.name} exceeds the uncompressed part size limit`,
|
|
5094
|
+
r.maxEntryBytes
|
|
5095
|
+
);
|
|
5096
|
+
declared += size;
|
|
5097
|
+
}
|
|
5098
|
+
if (declared > r.maxTotalBytes)
|
|
5099
|
+
throw r.fail(
|
|
5100
|
+
`${r.label} package exceeds the ${mib(r.maxTotalBytes)} MiB uncompressed content limit`,
|
|
5101
|
+
r.maxTotalBytes
|
|
5102
|
+
);
|
|
5103
|
+
const produced = /* @__PURE__ */ new Map();
|
|
5104
|
+
let total = 0;
|
|
5105
|
+
for (const entry2 of entries) {
|
|
5106
|
+
if (entry2.dir) continue;
|
|
5107
|
+
const inflateOriginal = entry2.async.bind(entry2);
|
|
5108
|
+
entry2.async = async (type, onUpdate) => {
|
|
5109
|
+
const previous = produced.get(entry2.name) ?? 0;
|
|
5110
|
+
const bytes = await inflateEntryGuarded(entry2, total - previous, limits);
|
|
5111
|
+
if (bytes.byteLength > previous) {
|
|
5112
|
+
total += bytes.byteLength - previous;
|
|
5113
|
+
produced.set(entry2.name, bytes.byteLength);
|
|
5114
|
+
}
|
|
5115
|
+
switch (type) {
|
|
5116
|
+
case "uint8array":
|
|
5117
|
+
return bytes;
|
|
5118
|
+
case "string":
|
|
5119
|
+
case "text":
|
|
5120
|
+
return new TextDecoder("utf-8", { ignoreBOM: true }).decode(bytes);
|
|
5121
|
+
case "arraybuffer":
|
|
5122
|
+
return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
5123
|
+
case "base64":
|
|
5124
|
+
return toBase64(bytes);
|
|
5125
|
+
default:
|
|
5126
|
+
return inflateOriginal(type, onUpdate);
|
|
5127
|
+
}
|
|
5128
|
+
};
|
|
5129
|
+
}
|
|
5130
|
+
return zip;
|
|
5131
|
+
}
|
|
5132
|
+
async function openZip(input, limits = {}) {
|
|
5133
|
+
const r = resolveLimits(limits);
|
|
5134
|
+
const maxInput = limits.maxInputBytes ?? DEFAULT_ZIP_LIMITS.maxInputBytes;
|
|
5135
|
+
const bytes = input instanceof Uint8Array ? input : new Uint8Array(input);
|
|
5136
|
+
if (bytes.byteLength > maxInput)
|
|
5137
|
+
throw r.fail(
|
|
5138
|
+
`${r.label} package exceeds the ${mib(maxInput)} MiB compressed input limit`,
|
|
5139
|
+
maxInput
|
|
5140
|
+
);
|
|
5141
|
+
return guardZip(await JSZip__default.default.loadAsync(bytes), limits);
|
|
5142
|
+
}
|
|
5143
|
+
var DEFAULT_ZIP_LIMITS, ZipLimitError, mib;
|
|
5144
|
+
var init_zip_limits = __esm({
|
|
5145
|
+
"opc/zip-limits.ts"() {
|
|
5146
|
+
DEFAULT_ZIP_LIMITS = {
|
|
5147
|
+
maxInputBytes: 100 * 1024 * 1024,
|
|
5148
|
+
maxEntries: 1e4,
|
|
5149
|
+
maxEntryBytes: 100 * 1024 * 1024,
|
|
5150
|
+
maxTotalBytes: 100 * 1024 * 1024
|
|
5151
|
+
};
|
|
5152
|
+
ZipLimitError = class extends Error {
|
|
5153
|
+
code = "ZIP_BOMB";
|
|
5154
|
+
limit;
|
|
5155
|
+
constructor(message, details) {
|
|
5156
|
+
super(message);
|
|
5157
|
+
this.name = "ZipLimitError";
|
|
5158
|
+
this.limit = details.limit;
|
|
5159
|
+
}
|
|
5160
|
+
};
|
|
5161
|
+
mib = (bytes) => Math.round(bytes / 1048576);
|
|
5162
|
+
}
|
|
5163
|
+
});
|
|
5164
|
+
|
|
5165
|
+
// pptx/core/core/types.ts
|
|
5166
|
+
exports.DEFAULT_MAX_UNCOMPRESSED_BYTES = void 0; exports.MAX_ZIP_ENTRY_COUNT = void 0; exports.ZipBombError = void 0;
|
|
5167
|
+
var init_types2 = __esm({
|
|
5168
|
+
"pptx/core/core/types.ts"() {
|
|
5169
|
+
exports.DEFAULT_MAX_UNCOMPRESSED_BYTES = 500 * 1024 * 1024;
|
|
5170
|
+
exports.MAX_ZIP_ENTRY_COUNT = 65536;
|
|
5171
|
+
exports.ZipBombError = class extends Error {
|
|
5172
|
+
code = "ZIP_BOMB";
|
|
5173
|
+
uncompressedBytes;
|
|
5174
|
+
limit;
|
|
5175
|
+
entryCount;
|
|
5176
|
+
constructor(message, details) {
|
|
5177
|
+
super(message);
|
|
5178
|
+
this.name = "ZipBombError";
|
|
5179
|
+
this.uncompressedBytes = details.uncompressedBytes;
|
|
5180
|
+
this.limit = details.limit;
|
|
5181
|
+
this.entryCount = details.entryCount;
|
|
5182
|
+
}
|
|
5183
|
+
};
|
|
5184
|
+
}
|
|
5185
|
+
});
|
|
5186
|
+
|
|
5187
|
+
// pptx/core/utils/zip-open.ts
|
|
5188
|
+
function openPptxZip(bytes) {
|
|
5189
|
+
return openZip(bytes, {
|
|
5190
|
+
label: "PPTX",
|
|
5191
|
+
maxInputBytes: exports.DEFAULT_MAX_UNCOMPRESSED_BYTES,
|
|
5192
|
+
maxEntries: exports.MAX_ZIP_ENTRY_COUNT,
|
|
5193
|
+
maxEntryBytes: exports.DEFAULT_MAX_UNCOMPRESSED_BYTES,
|
|
5194
|
+
maxTotalBytes: exports.DEFAULT_MAX_UNCOMPRESSED_BYTES,
|
|
5195
|
+
createError
|
|
5196
|
+
});
|
|
5197
|
+
}
|
|
5198
|
+
function openNestedZip(bytes) {
|
|
5199
|
+
return openZip(bytes, { label: "Embedded", createError });
|
|
5200
|
+
}
|
|
5201
|
+
var createError;
|
|
5202
|
+
var init_zip_open = __esm({
|
|
5203
|
+
"pptx/core/utils/zip-open.ts"() {
|
|
5204
|
+
init_zip_limits();
|
|
5205
|
+
init_types2();
|
|
5206
|
+
createError = (message, details) => new exports.ZipBombError(message, details);
|
|
5207
|
+
}
|
|
5208
|
+
});
|
|
5209
|
+
|
|
5210
|
+
// pptx/core/builders/sdk/layout-operations.ts
|
|
5211
|
+
function pxToEmu(px3) {
|
|
5212
|
+
return Math.round(px3 * EMU_PER_PIXEL2);
|
|
5213
|
+
}
|
|
5214
|
+
function placeholderSpXml(ph, shapeId) {
|
|
5215
|
+
const name = ph.name ?? `${ph.type.charAt(0).toUpperCase() + ph.type.slice(1)} Placeholder ${shapeId - 1}`;
|
|
5216
|
+
const x = pxToEmu(ph.x);
|
|
5217
|
+
const y = pxToEmu(ph.y);
|
|
5218
|
+
const cx = pxToEmu(ph.width);
|
|
5219
|
+
const cy = pxToEmu(ph.height);
|
|
5220
|
+
const idxAttr = ph.idx !== void 0 ? ` idx="${Math.max(0, Math.round(ph.idx))}"` : "";
|
|
5221
|
+
return ` <p:sp>
|
|
5222
|
+
<p:nvSpPr>
|
|
5223
|
+
<p:cNvPr id="${shapeId}" name="${escAttr(name)}"/>
|
|
5224
|
+
<p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr>
|
|
5225
|
+
<p:nvPr><p:ph type="${escAttr(ph.type)}"${idxAttr}/></p:nvPr>
|
|
5226
|
+
</p:nvSpPr>
|
|
5227
|
+
<p:spPr>
|
|
5228
|
+
<a:xfrm><a:off x="${x}" y="${y}"/><a:ext cx="${cx}" cy="${cy}"/></a:xfrm>
|
|
5229
|
+
</p:spPr>
|
|
5230
|
+
<p:txBody>
|
|
5231
|
+
<a:bodyPr/>
|
|
5232
|
+
<a:lstStyle/>
|
|
5233
|
+
<a:p><a:endParaRPr lang="en-US"/></a:p>
|
|
5234
|
+
</p:txBody>
|
|
5235
|
+
</p:sp>`;
|
|
5236
|
+
}
|
|
5237
|
+
function normalizeSrgbHex(color2) {
|
|
5238
|
+
if (!color2) {
|
|
5239
|
+
return void 0;
|
|
5240
|
+
}
|
|
5241
|
+
const raw = color2.trim().replace(/^#/, "").toUpperCase();
|
|
5242
|
+
if (/^[0-9A-F]{6}$/.test(raw)) {
|
|
5243
|
+
return raw;
|
|
5244
|
+
}
|
|
5245
|
+
if (/^[0-9A-F]{3}$/.test(raw)) {
|
|
5246
|
+
return raw.replace(/./g, (ch) => ch + ch);
|
|
5247
|
+
}
|
|
5248
|
+
return void 0;
|
|
5249
|
+
}
|
|
5250
|
+
function generateLayoutXml(definition) {
|
|
5251
|
+
const layoutType = definition.type ?? "obj";
|
|
5252
|
+
const placeholders = definition.placeholders ?? [];
|
|
5253
|
+
const phShapes = placeholders.map((ph, i2) => placeholderSpXml(ph, i2 + 2)).join("\n");
|
|
5254
|
+
let bgXml = "";
|
|
5255
|
+
const hex3 = normalizeSrgbHex(definition.backgroundColor);
|
|
5256
|
+
if (hex3) {
|
|
5257
|
+
bgXml = ` <p:bg><p:bgPr><a:solidFill><a:srgbClr val="${hex3}"/></a:solidFill><a:effectLst/></p:bgPr></p:bg>
|
|
5258
|
+
`;
|
|
5259
|
+
}
|
|
5260
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
5261
|
+
<p:sldLayout xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
|
|
5262
|
+
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
|
5263
|
+
xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"
|
|
5264
|
+
type="${escAttr(layoutType)}" preserve="1">
|
|
5265
|
+
<p:cSld name="${escAttr(definition.name)}">
|
|
5266
|
+
${bgXml} <p:spTree>
|
|
5267
|
+
<p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr>
|
|
5268
|
+
<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>
|
|
5269
|
+
${phShapes}
|
|
5270
|
+
</p:spTree>
|
|
5271
|
+
</p:cSld>
|
|
5272
|
+
<p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr>
|
|
5273
|
+
</p:sldLayout>`;
|
|
5274
|
+
}
|
|
5275
|
+
function layoutRelsXml(masterIndex = 1) {
|
|
5276
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
5277
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
5278
|
+
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" Target="../slideMasters/slideMaster${masterIndex}.xml"/>
|
|
5279
|
+
</Relationships>`;
|
|
5280
|
+
}
|
|
5281
|
+
function countExistingLayouts(zip) {
|
|
5282
|
+
let count = 0;
|
|
5283
|
+
zip.forEach((relativePath) => {
|
|
5284
|
+
if (/^ppt\/slideLayouts\/slideLayout\d+\.xml$/.test(relativePath)) {
|
|
5285
|
+
count++;
|
|
5286
|
+
}
|
|
5287
|
+
});
|
|
5288
|
+
return count;
|
|
5289
|
+
}
|
|
5290
|
+
async function addLayoutToSlideMaster(zip, layoutIndex2, masterIndex = 1) {
|
|
5291
|
+
const masterRelsPath = `ppt/slideMasters/_rels/slideMaster${masterIndex}.xml.rels`;
|
|
5292
|
+
const masterRelsContent = await zip.file(masterRelsPath)?.async("string");
|
|
5293
|
+
if (!masterRelsContent) {
|
|
5294
|
+
throw new Error(`Slide master rels not found at ${masterRelsPath}`);
|
|
5295
|
+
}
|
|
5296
|
+
const rIdMatches = [...masterRelsContent.matchAll(/rId(\d+)/g)];
|
|
5297
|
+
const maxRId = rIdMatches.reduce((max, m) => Math.max(max, parseInt(m[1], 10)), 0);
|
|
5298
|
+
const newRId = `rId${maxRId + 1}`;
|
|
5299
|
+
const newRel = ` <Relationship Id="${newRId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" Target="../slideLayouts/slideLayout${layoutIndex2}.xml"/>`;
|
|
5300
|
+
const updatedRels = masterRelsContent.replace("</Relationships>", `${newRel}
|
|
5301
|
+
</Relationships>`);
|
|
5302
|
+
zip.file(masterRelsPath, updatedRels);
|
|
5303
|
+
const masterPath = `ppt/slideMasters/slideMaster${masterIndex}.xml`;
|
|
5304
|
+
const masterContent = await zip.file(masterPath)?.async("string");
|
|
5305
|
+
if (!masterContent) {
|
|
5306
|
+
throw new Error(`Slide master not found at ${masterPath}`);
|
|
5307
|
+
}
|
|
5308
|
+
const idMatches = [...masterContent.matchAll(/sldLayoutId\s+id="(\d+)"/g)];
|
|
5309
|
+
const maxLayoutId = idMatches.reduce((max, m) => Math.max(max, parseInt(m[1], 10)), 2147483648);
|
|
5310
|
+
const newLayoutId = maxLayoutId + 1;
|
|
5311
|
+
const newLayoutIdEntry = ` <p:sldLayoutId id="${newLayoutId}" r:id="${newRId}"/>`;
|
|
5312
|
+
const updatedMaster = masterContent.replace(
|
|
5313
|
+
"</p:sldLayoutIdLst>",
|
|
5314
|
+
`${newLayoutIdEntry}
|
|
5315
|
+
</p:sldLayoutIdLst>`
|
|
5316
|
+
);
|
|
5317
|
+
zip.file(masterPath, updatedMaster);
|
|
5318
|
+
}
|
|
5319
|
+
async function addLayoutContentType(zip, layoutIndex2) {
|
|
5320
|
+
const ctPath = "[Content_Types].xml";
|
|
5321
|
+
const ctContent = await zip.file(ctPath)?.async("string");
|
|
5322
|
+
if (!ctContent) {
|
|
5323
|
+
throw new Error("Content types file not found");
|
|
5324
|
+
}
|
|
5325
|
+
const override = ` <Override PartName="/ppt/slideLayouts/slideLayout${layoutIndex2}.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/>`;
|
|
5326
|
+
const updatedCt = ctContent.replace("</Types>", `${override}
|
|
5327
|
+
</Types>`);
|
|
5328
|
+
zip.file(ctPath, updatedCt);
|
|
5329
|
+
}
|
|
5330
|
+
async function createLayout(handler, data, definition, masterIndex = 1) {
|
|
5331
|
+
const bytes = await handler.save(data.slides);
|
|
5332
|
+
const zip = await openPptxZip(bytes);
|
|
5333
|
+
const existingCount = countExistingLayouts(zip);
|
|
5334
|
+
const newIndex = existingCount + 1;
|
|
5335
|
+
const layoutPath = `ppt/slideLayouts/slideLayout${newIndex}.xml`;
|
|
5336
|
+
zip.file(layoutPath, generateLayoutXml(definition));
|
|
5337
|
+
zip.file(`ppt/slideLayouts/_rels/slideLayout${newIndex}.xml.rels`, layoutRelsXml(masterIndex));
|
|
5338
|
+
await addLayoutToSlideMaster(zip, newIndex, masterIndex);
|
|
5339
|
+
await addLayoutContentType(zip, newIndex);
|
|
5340
|
+
const updatedBuffer = await zip.generateAsync({ type: "arraybuffer" });
|
|
5341
|
+
const newHandler = new exports.PptxHandler();
|
|
5342
|
+
const newData = await newHandler.load(updatedBuffer);
|
|
5343
|
+
return {
|
|
5344
|
+
layoutPath,
|
|
5345
|
+
layoutName: definition.name,
|
|
5346
|
+
handler: newHandler,
|
|
5347
|
+
data: newData
|
|
5348
|
+
};
|
|
5349
|
+
}
|
|
5350
|
+
async function createLayouts(handler, data, definitions, masterIndex = 1) {
|
|
5351
|
+
if (definitions.length === 0) {
|
|
5352
|
+
return { layoutPaths: [], handler, data };
|
|
5353
|
+
}
|
|
5354
|
+
const bytes = await handler.save(data.slides);
|
|
5355
|
+
const zip = await openPptxZip(bytes);
|
|
5356
|
+
const existingCount = countExistingLayouts(zip);
|
|
5357
|
+
const layoutPaths = [];
|
|
5358
|
+
for (let i2 = 0; i2 < definitions.length; i2++) {
|
|
5359
|
+
const def = definitions[i2];
|
|
5360
|
+
const newIndex = existingCount + i2 + 1;
|
|
5361
|
+
const layoutPath = `ppt/slideLayouts/slideLayout${newIndex}.xml`;
|
|
5362
|
+
zip.file(layoutPath, generateLayoutXml(def));
|
|
5363
|
+
zip.file(`ppt/slideLayouts/_rels/slideLayout${newIndex}.xml.rels`, layoutRelsXml(masterIndex));
|
|
5364
|
+
await addLayoutToSlideMaster(zip, newIndex, masterIndex);
|
|
5365
|
+
await addLayoutContentType(zip, newIndex);
|
|
5366
|
+
layoutPaths.push(layoutPath);
|
|
5367
|
+
}
|
|
5368
|
+
const updatedBuffer = await zip.generateAsync({ type: "arraybuffer" });
|
|
5369
|
+
const newHandler = new exports.PptxHandler();
|
|
5370
|
+
const newData = await newHandler.load(updatedBuffer);
|
|
5371
|
+
return { layoutPaths, handler: newHandler, data: newData };
|
|
5372
|
+
}
|
|
5373
|
+
function findLayoutByName(data, name) {
|
|
5374
|
+
const lowerName = name.toLowerCase();
|
|
5375
|
+
const fromOptions = data.layoutOptions?.find((l) => l.name.toLowerCase() === lowerName);
|
|
5376
|
+
if (fromOptions) {
|
|
5377
|
+
return fromOptions;
|
|
5378
|
+
}
|
|
5379
|
+
if (data.slideMasters) {
|
|
5380
|
+
for (const master of data.slideMasters) {
|
|
5381
|
+
const layout = master.layouts?.find((l) => l.name?.toLowerCase() === lowerName);
|
|
5382
|
+
if (layout) {
|
|
5383
|
+
return { path: layout.path, name: layout.name ?? name };
|
|
5384
|
+
}
|
|
5385
|
+
}
|
|
5386
|
+
}
|
|
5387
|
+
return void 0;
|
|
5388
|
+
}
|
|
5389
|
+
function findLayoutByType(data, type) {
|
|
5390
|
+
const fromOptions = data.layoutOptions?.find((l) => l.type === type);
|
|
5391
|
+
if (fromOptions) {
|
|
5392
|
+
return fromOptions;
|
|
5393
|
+
}
|
|
5394
|
+
return void 0;
|
|
5395
|
+
}
|
|
5396
|
+
var EMU_PER_PIXEL2;
|
|
5397
|
+
var init_layout_operations = __esm({
|
|
5398
|
+
"pptx/core/builders/sdk/layout-operations.ts"() {
|
|
5399
|
+
init_zip_open();
|
|
5400
|
+
init_xml_utils();
|
|
5401
|
+
init_PptxHandler();
|
|
5402
|
+
EMU_PER_PIXEL2 = 9525;
|
|
5403
|
+
}
|
|
5404
|
+
});
|
|
5405
|
+
|
|
5406
|
+
// pptx/core/builders/sdk/standard-layout-placeholders.ts
|
|
5407
|
+
function standardLayoutPlaceholders(type, width, height) {
|
|
5408
|
+
if (type === "blank") return [];
|
|
5409
|
+
const box = (type2, idx, x, y, w, h2) => ({
|
|
5410
|
+
type: type2,
|
|
5411
|
+
idx,
|
|
5412
|
+
x: x * width,
|
|
5413
|
+
y: y * height,
|
|
5414
|
+
width: w * width,
|
|
5415
|
+
height: h2 * height
|
|
5416
|
+
});
|
|
5417
|
+
const title = box("title", 0, 0.05, 0.04, 0.9, 0.15);
|
|
5418
|
+
const content2 = box("obj", 1, 0.05, 0.23, 0.9, 0.64);
|
|
5419
|
+
let slots;
|
|
5420
|
+
switch (type) {
|
|
5421
|
+
case "title":
|
|
5422
|
+
slots = [
|
|
5423
|
+
box("ctrTitle", 0, 0.08, 0.24, 0.84, 0.22),
|
|
5424
|
+
box("subTitle", 1, 0.12, 0.49, 0.76, 0.2)
|
|
5425
|
+
];
|
|
5426
|
+
break;
|
|
5427
|
+
case "secHead":
|
|
5428
|
+
slots = [box("title", 0, 0.05, 0.37, 0.9, 0.2), box("body", 1, 0.05, 0.6, 0.9, 0.23)];
|
|
5429
|
+
break;
|
|
5430
|
+
case "twoObj":
|
|
5431
|
+
case "twoTxTwoObj":
|
|
5432
|
+
slots = [title, box("obj", 1, 0.05, 0.27, 0.43, 0.6), box("obj", 2, 0.52, 0.27, 0.43, 0.6)];
|
|
5433
|
+
if (type === "twoTxTwoObj")
|
|
5434
|
+
slots.push(box("body", 3, 0.05, 0.2, 0.43, 0.07), box("body", 4, 0.52, 0.2, 0.43, 0.07));
|
|
5435
|
+
break;
|
|
5436
|
+
case "titleOnly":
|
|
5437
|
+
slots = [title];
|
|
5438
|
+
break;
|
|
5439
|
+
case "objTx":
|
|
5440
|
+
case "picTx":
|
|
5441
|
+
slots = [
|
|
5442
|
+
title,
|
|
5443
|
+
box(type === "picTx" ? "pic" : "obj", 1, 0.36, 0.23, 0.59, 0.64),
|
|
5444
|
+
box("body", 2, 0.05, 0.23, 0.27, 0.64)
|
|
5445
|
+
];
|
|
5446
|
+
break;
|
|
5447
|
+
default:
|
|
5448
|
+
slots = [title, content2];
|
|
5449
|
+
}
|
|
5450
|
+
return [
|
|
5451
|
+
...slots,
|
|
5452
|
+
box("dt", 10, 0.05, 0.92, 0.25, 0.04),
|
|
5453
|
+
box("ftr", 11, 0.33, 0.92, 0.34, 0.04),
|
|
5454
|
+
box("sldNum", 12, 0.75, 0.92, 0.2, 0.04)
|
|
5455
|
+
];
|
|
5456
|
+
}
|
|
5457
|
+
var init_standard_layout_placeholders = __esm({
|
|
5458
|
+
"pptx/core/builders/sdk/standard-layout-placeholders.ts"() {
|
|
5459
|
+
}
|
|
5460
|
+
});
|
|
4959
5461
|
|
|
4960
5462
|
// pptx/core/builders/sdk/PresentationBuilder.ts
|
|
4961
5463
|
var PresentationBuilder_exports = {};
|
|
@@ -4964,7 +5466,7 @@ __export(PresentationBuilder_exports, {
|
|
|
4964
5466
|
STANDARD_LAYOUTS: () => STANDARD_LAYOUTS,
|
|
4965
5467
|
buildBlankPresentationArchive: () => buildBlankPresentationArchive
|
|
4966
5468
|
});
|
|
4967
|
-
function
|
|
5469
|
+
function normalizeSrgbHex2(color2) {
|
|
4968
5470
|
if (!color2) {
|
|
4969
5471
|
return void 0;
|
|
4970
5472
|
}
|
|
@@ -4980,7 +5482,7 @@ function normalizeSrgbHex(color2) {
|
|
|
4980
5482
|
function resolveThemeColors(overrides28) {
|
|
4981
5483
|
const resolved = {};
|
|
4982
5484
|
for (const [key2, fallback] of Object.entries(DEFAULT_COLORS)) {
|
|
4983
|
-
resolved[key2] =
|
|
5485
|
+
resolved[key2] = normalizeSrgbHex2(overrides28?.[key2]) ?? normalizeSrgbHex2(fallback) ?? "000000";
|
|
4984
5486
|
}
|
|
4985
5487
|
return resolved;
|
|
4986
5488
|
}
|
|
@@ -5120,21 +5622,6 @@ ${layoutRels}
|
|
|
5120
5622
|
<Relationship Id="rId${layoutCount + 1}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="../theme/theme1.xml"/>
|
|
5121
5623
|
</Relationships>`;
|
|
5122
5624
|
}
|
|
5123
|
-
function slideLayoutXml(name, layoutType) {
|
|
5124
|
-
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
5125
|
-
<p:sldLayout xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
|
|
5126
|
-
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
|
5127
|
-
xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"
|
|
5128
|
-
type="${escAttr(layoutType)}" preserve="1">
|
|
5129
|
-
<p:cSld name="${escAttr(name)}">
|
|
5130
|
-
<p:spTree>
|
|
5131
|
-
<p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr>
|
|
5132
|
-
<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>
|
|
5133
|
-
</p:spTree>
|
|
5134
|
-
</p:cSld>
|
|
5135
|
-
<p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr>
|
|
5136
|
-
</p:sldLayout>`;
|
|
5137
|
-
}
|
|
5138
5625
|
function slideLayoutRelsXml() {
|
|
5139
5626
|
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
5140
5627
|
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
@@ -5283,7 +5770,14 @@ async function buildBlankPresentationArchive(options) {
|
|
|
5283
5770
|
zip.file("ppt/slideMasters/_rels/slideMaster1.xml.rels", slideMasterRelsXml(layoutCount));
|
|
5284
5771
|
for (let i2 = 0; i2 < layoutCount; i2++) {
|
|
5285
5772
|
const layout = STANDARD_LAYOUTS[i2];
|
|
5286
|
-
zip.file(
|
|
5773
|
+
zip.file(
|
|
5774
|
+
`ppt/slideLayouts/slideLayout${i2 + 1}.xml`,
|
|
5775
|
+
generateLayoutXml({
|
|
5776
|
+
name: layout.name,
|
|
5777
|
+
type: layout.type,
|
|
5778
|
+
placeholders: standardLayoutPlaceholders(layout.type, width / 9525, height / 9525)
|
|
5779
|
+
})
|
|
5780
|
+
);
|
|
5287
5781
|
zip.file(`ppt/slideLayouts/_rels/slideLayout${i2 + 1}.xml.rels`, slideLayoutRelsXml());
|
|
5288
5782
|
}
|
|
5289
5783
|
for (let i2 = 0; i2 < initialSlideCount; i2++) {
|
|
@@ -5304,6 +5798,8 @@ var init_PresentationBuilder = __esm({
|
|
|
5304
5798
|
init_xml_utils();
|
|
5305
5799
|
init_PptxHandler();
|
|
5306
5800
|
init_SlideBuilder();
|
|
5801
|
+
init_layout_operations();
|
|
5802
|
+
init_standard_layout_placeholders();
|
|
5307
5803
|
DEFAULT_WIDTH = 12192e3;
|
|
5308
5804
|
DEFAULT_HEIGHT = 6858e3;
|
|
5309
5805
|
DEFAULT_COLORS = {
|
|
@@ -5361,7 +5857,7 @@ var init_PresentationBuilder = __esm({
|
|
|
5361
5857
|
const layoutIdx = STANDARD_LAYOUTS.findIndex((l) => l.name === layoutName) + 1 || 7;
|
|
5362
5858
|
const layoutPath = `ppt/slideLayouts/slideLayout${layoutIdx}.xml`;
|
|
5363
5859
|
const resolvedName = layoutName ?? STANDARD_LAYOUTS[layoutIdx - 1]?.name ?? "Blank";
|
|
5364
|
-
return new exports.SlideBuilder(slideNum, layoutPath, resolvedName);
|
|
5860
|
+
return new exports.SlideBuilder(slideNum, layoutPath, resolvedName, handler);
|
|
5365
5861
|
};
|
|
5366
5862
|
return { handler, data, createSlide };
|
|
5367
5863
|
}
|
|
@@ -22935,214 +23431,6 @@ var init_ole_embedded_replace = __esm({
|
|
|
22935
23431
|
CONTENTS_STREAM2 = "CONTENTS";
|
|
22936
23432
|
}
|
|
22937
23433
|
});
|
|
22938
|
-
function isSafePartName(name) {
|
|
22939
|
-
if (name.includes("\0") || name.includes("\\")) return false;
|
|
22940
|
-
if (/^[A-Za-z]:/u.test(name)) return false;
|
|
22941
|
-
const body = name.startsWith("/") ? name.slice(1) : name;
|
|
22942
|
-
if (body.startsWith("/")) return false;
|
|
22943
|
-
return !body.split("/").some((segment) => segment === "..");
|
|
22944
|
-
}
|
|
22945
|
-
function declaredEntrySize(entry2) {
|
|
22946
|
-
const data = entry2._data;
|
|
22947
|
-
const size = Number(data?.uncompressedSize ?? 0);
|
|
22948
|
-
return Number.isFinite(size) && size > 0 ? size : 0;
|
|
22949
|
-
}
|
|
22950
|
-
function resolveLimits(limits) {
|
|
22951
|
-
const create = limits.createError;
|
|
22952
|
-
return {
|
|
22953
|
-
maxEntries: limits.maxEntries ?? DEFAULT_ZIP_LIMITS.maxEntries,
|
|
22954
|
-
maxEntryBytes: limits.maxEntryBytes ?? DEFAULT_ZIP_LIMITS.maxEntryBytes,
|
|
22955
|
-
maxTotalBytes: limits.maxTotalBytes ?? DEFAULT_ZIP_LIMITS.maxTotalBytes,
|
|
22956
|
-
label: limits.label ?? "ZIP",
|
|
22957
|
-
fail: (message, limit) => create ? create(message, { limit }) : new ZipLimitError(message, { limit })
|
|
22958
|
-
};
|
|
22959
|
-
}
|
|
22960
|
-
function inflateEntryGuarded(entry2, alreadyRead, limits) {
|
|
22961
|
-
const r = resolveLimits(limits);
|
|
22962
|
-
const declared = declaredEntrySize(entry2);
|
|
22963
|
-
return new Promise((resolvePromise, reject) => {
|
|
22964
|
-
const chunks = [];
|
|
22965
|
-
let size = 0;
|
|
22966
|
-
let done = false;
|
|
22967
|
-
const stream = entry2.internalStream("uint8array");
|
|
22968
|
-
const abort = (error) => {
|
|
22969
|
-
if (done) return;
|
|
22970
|
-
done = true;
|
|
22971
|
-
stream.pause();
|
|
22972
|
-
chunks.length = 0;
|
|
22973
|
-
reject(error);
|
|
22974
|
-
};
|
|
22975
|
-
stream.on("data", (chunk2) => {
|
|
22976
|
-
if (done) return;
|
|
22977
|
-
size += chunk2.byteLength;
|
|
22978
|
-
if (size > declared || size > r.maxEntryBytes)
|
|
22979
|
-
return abort(
|
|
22980
|
-
r.fail(`${r.label} part ${entry2.name} inflates past its declared size`, r.maxEntryBytes)
|
|
22981
|
-
);
|
|
22982
|
-
if (alreadyRead + size > r.maxTotalBytes)
|
|
22983
|
-
return abort(
|
|
22984
|
-
r.fail(
|
|
22985
|
-
`${r.label} package exceeds the ${mib(r.maxTotalBytes)} MiB uncompressed content limit`,
|
|
22986
|
-
r.maxTotalBytes
|
|
22987
|
-
)
|
|
22988
|
-
);
|
|
22989
|
-
chunks.push(chunk2);
|
|
22990
|
-
});
|
|
22991
|
-
stream.on("error", (error) => abort(error));
|
|
22992
|
-
stream.on("end", () => {
|
|
22993
|
-
if (done) return;
|
|
22994
|
-
done = true;
|
|
22995
|
-
if (chunks.length === 1 && chunks[0]) return resolvePromise(chunks[0]);
|
|
22996
|
-
const out = new Uint8Array(size);
|
|
22997
|
-
let offset = 0;
|
|
22998
|
-
for (const chunk2 of chunks) {
|
|
22999
|
-
out.set(chunk2, offset);
|
|
23000
|
-
offset += chunk2.byteLength;
|
|
23001
|
-
}
|
|
23002
|
-
resolvePromise(out);
|
|
23003
|
-
});
|
|
23004
|
-
stream.resume();
|
|
23005
|
-
});
|
|
23006
|
-
}
|
|
23007
|
-
function toBase64(bytes) {
|
|
23008
|
-
let binary = "";
|
|
23009
|
-
for (let i2 = 0; i2 < bytes.length; i2 += 32768)
|
|
23010
|
-
binary += String.fromCharCode(...bytes.subarray(i2, i2 + 32768));
|
|
23011
|
-
return btoa(binary);
|
|
23012
|
-
}
|
|
23013
|
-
function guardZip(zip, limits = {}) {
|
|
23014
|
-
const r = resolveLimits(limits);
|
|
23015
|
-
const entries = Object.values(zip.files);
|
|
23016
|
-
if (entries.length > r.maxEntries)
|
|
23017
|
-
throw r.fail(
|
|
23018
|
-
`${r.label} package exceeds the ${r.maxEntries.toLocaleString("en-US")} part limit`,
|
|
23019
|
-
r.maxEntries
|
|
23020
|
-
);
|
|
23021
|
-
let declared = 0;
|
|
23022
|
-
for (const entry2 of entries) {
|
|
23023
|
-
const original = entry2.unsafeOriginalName;
|
|
23024
|
-
if (!isSafePartName(entry2.name) || original !== void 0 && !isSafePartName(original))
|
|
23025
|
-
throw r.fail(`${r.label} package has an unsafe part name`, r.maxEntries);
|
|
23026
|
-
if (entry2.dir) continue;
|
|
23027
|
-
const size = declaredEntrySize(entry2);
|
|
23028
|
-
if (size > r.maxEntryBytes)
|
|
23029
|
-
throw r.fail(
|
|
23030
|
-
`${r.label} part ${entry2.name} exceeds the uncompressed part size limit`,
|
|
23031
|
-
r.maxEntryBytes
|
|
23032
|
-
);
|
|
23033
|
-
declared += size;
|
|
23034
|
-
}
|
|
23035
|
-
if (declared > r.maxTotalBytes)
|
|
23036
|
-
throw r.fail(
|
|
23037
|
-
`${r.label} package exceeds the ${mib(r.maxTotalBytes)} MiB uncompressed content limit`,
|
|
23038
|
-
r.maxTotalBytes
|
|
23039
|
-
);
|
|
23040
|
-
const produced = /* @__PURE__ */ new Map();
|
|
23041
|
-
let total = 0;
|
|
23042
|
-
for (const entry2 of entries) {
|
|
23043
|
-
if (entry2.dir) continue;
|
|
23044
|
-
const inflateOriginal = entry2.async.bind(entry2);
|
|
23045
|
-
entry2.async = async (type, onUpdate) => {
|
|
23046
|
-
const previous = produced.get(entry2.name) ?? 0;
|
|
23047
|
-
const bytes = await inflateEntryGuarded(entry2, total - previous, limits);
|
|
23048
|
-
if (bytes.byteLength > previous) {
|
|
23049
|
-
total += bytes.byteLength - previous;
|
|
23050
|
-
produced.set(entry2.name, bytes.byteLength);
|
|
23051
|
-
}
|
|
23052
|
-
switch (type) {
|
|
23053
|
-
case "uint8array":
|
|
23054
|
-
return bytes;
|
|
23055
|
-
case "string":
|
|
23056
|
-
case "text":
|
|
23057
|
-
return new TextDecoder("utf-8", { ignoreBOM: true }).decode(bytes);
|
|
23058
|
-
case "arraybuffer":
|
|
23059
|
-
return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
23060
|
-
case "base64":
|
|
23061
|
-
return toBase64(bytes);
|
|
23062
|
-
default:
|
|
23063
|
-
return inflateOriginal(type, onUpdate);
|
|
23064
|
-
}
|
|
23065
|
-
};
|
|
23066
|
-
}
|
|
23067
|
-
return zip;
|
|
23068
|
-
}
|
|
23069
|
-
async function openZip(input, limits = {}) {
|
|
23070
|
-
const r = resolveLimits(limits);
|
|
23071
|
-
const maxInput = limits.maxInputBytes ?? DEFAULT_ZIP_LIMITS.maxInputBytes;
|
|
23072
|
-
const bytes = input instanceof Uint8Array ? input : new Uint8Array(input);
|
|
23073
|
-
if (bytes.byteLength > maxInput)
|
|
23074
|
-
throw r.fail(
|
|
23075
|
-
`${r.label} package exceeds the ${mib(maxInput)} MiB compressed input limit`,
|
|
23076
|
-
maxInput
|
|
23077
|
-
);
|
|
23078
|
-
return guardZip(await JSZip__default.default.loadAsync(bytes), limits);
|
|
23079
|
-
}
|
|
23080
|
-
var DEFAULT_ZIP_LIMITS, ZipLimitError, mib;
|
|
23081
|
-
var init_zip_limits = __esm({
|
|
23082
|
-
"opc/zip-limits.ts"() {
|
|
23083
|
-
DEFAULT_ZIP_LIMITS = {
|
|
23084
|
-
maxInputBytes: 100 * 1024 * 1024,
|
|
23085
|
-
maxEntries: 1e4,
|
|
23086
|
-
maxEntryBytes: 100 * 1024 * 1024,
|
|
23087
|
-
maxTotalBytes: 100 * 1024 * 1024
|
|
23088
|
-
};
|
|
23089
|
-
ZipLimitError = class extends Error {
|
|
23090
|
-
code = "ZIP_BOMB";
|
|
23091
|
-
limit;
|
|
23092
|
-
constructor(message, details) {
|
|
23093
|
-
super(message);
|
|
23094
|
-
this.name = "ZipLimitError";
|
|
23095
|
-
this.limit = details.limit;
|
|
23096
|
-
}
|
|
23097
|
-
};
|
|
23098
|
-
mib = (bytes) => Math.round(bytes / 1048576);
|
|
23099
|
-
}
|
|
23100
|
-
});
|
|
23101
|
-
|
|
23102
|
-
// pptx/core/core/types.ts
|
|
23103
|
-
exports.DEFAULT_MAX_UNCOMPRESSED_BYTES = void 0; exports.MAX_ZIP_ENTRY_COUNT = void 0; exports.ZipBombError = void 0;
|
|
23104
|
-
var init_types2 = __esm({
|
|
23105
|
-
"pptx/core/core/types.ts"() {
|
|
23106
|
-
exports.DEFAULT_MAX_UNCOMPRESSED_BYTES = 500 * 1024 * 1024;
|
|
23107
|
-
exports.MAX_ZIP_ENTRY_COUNT = 65536;
|
|
23108
|
-
exports.ZipBombError = class extends Error {
|
|
23109
|
-
code = "ZIP_BOMB";
|
|
23110
|
-
uncompressedBytes;
|
|
23111
|
-
limit;
|
|
23112
|
-
entryCount;
|
|
23113
|
-
constructor(message, details) {
|
|
23114
|
-
super(message);
|
|
23115
|
-
this.name = "ZipBombError";
|
|
23116
|
-
this.uncompressedBytes = details.uncompressedBytes;
|
|
23117
|
-
this.limit = details.limit;
|
|
23118
|
-
this.entryCount = details.entryCount;
|
|
23119
|
-
}
|
|
23120
|
-
};
|
|
23121
|
-
}
|
|
23122
|
-
});
|
|
23123
|
-
|
|
23124
|
-
// pptx/core/utils/zip-open.ts
|
|
23125
|
-
function openPptxZip(bytes) {
|
|
23126
|
-
return openZip(bytes, {
|
|
23127
|
-
label: "PPTX",
|
|
23128
|
-
maxInputBytes: exports.DEFAULT_MAX_UNCOMPRESSED_BYTES,
|
|
23129
|
-
maxEntries: exports.MAX_ZIP_ENTRY_COUNT,
|
|
23130
|
-
maxEntryBytes: exports.DEFAULT_MAX_UNCOMPRESSED_BYTES,
|
|
23131
|
-
maxTotalBytes: exports.DEFAULT_MAX_UNCOMPRESSED_BYTES,
|
|
23132
|
-
createError
|
|
23133
|
-
});
|
|
23134
|
-
}
|
|
23135
|
-
function openNestedZip(bytes) {
|
|
23136
|
-
return openZip(bytes, { label: "Embedded", createError });
|
|
23137
|
-
}
|
|
23138
|
-
var createError;
|
|
23139
|
-
var init_zip_open = __esm({
|
|
23140
|
-
"pptx/core/utils/zip-open.ts"() {
|
|
23141
|
-
init_zip_limits();
|
|
23142
|
-
init_types2();
|
|
23143
|
-
createError = (message, details) => new exports.ZipBombError(message, details);
|
|
23144
|
-
}
|
|
23145
|
-
});
|
|
23146
23434
|
|
|
23147
23435
|
// pptx/core/utils/ole-payload-kind.ts
|
|
23148
23436
|
function isZipMagic(bytes) {
|
|
@@ -74610,6 +74898,165 @@ var init_inherited_shape_transform = __esm({
|
|
|
74610
74898
|
}
|
|
74611
74899
|
});
|
|
74612
74900
|
|
|
74901
|
+
// pptx/core/utils/placeholder-xml.ts
|
|
74902
|
+
function findNonVisualProps(rawXml) {
|
|
74903
|
+
for (const container2 of ["p:nvSpPr", "p:nvPicPr", "p:nvGraphicFramePr"]) {
|
|
74904
|
+
const parent = rawXml[container2];
|
|
74905
|
+
const nvPr = parent?.["p:nvPr"];
|
|
74906
|
+
if (nvPr) {
|
|
74907
|
+
return nvPr;
|
|
74908
|
+
}
|
|
74909
|
+
}
|
|
74910
|
+
return void 0;
|
|
74911
|
+
}
|
|
74912
|
+
function retargetPlaceholder(rawXml, target) {
|
|
74913
|
+
const nvPr = findNonVisualProps(rawXml);
|
|
74914
|
+
if (!nvPr) {
|
|
74915
|
+
return;
|
|
74916
|
+
}
|
|
74917
|
+
const ph = nvPr["p:ph"] ?? {};
|
|
74918
|
+
nvPr["p:ph"] = ph;
|
|
74919
|
+
if (target.type) {
|
|
74920
|
+
ph["@_type"] = target.type;
|
|
74921
|
+
} else {
|
|
74922
|
+
delete ph["@_type"];
|
|
74923
|
+
}
|
|
74924
|
+
if (target.idx !== void 0) {
|
|
74925
|
+
ph["@_idx"] = target.idx;
|
|
74926
|
+
} else {
|
|
74927
|
+
delete ph["@_idx"];
|
|
74928
|
+
}
|
|
74929
|
+
}
|
|
74930
|
+
function setRawXmlTransform(rawXml, xEmu, yEmu, cxEmu, cyEmu) {
|
|
74931
|
+
const spPr = rawXml["p:spPr"];
|
|
74932
|
+
if (!spPr) {
|
|
74933
|
+
return;
|
|
74934
|
+
}
|
|
74935
|
+
const xfrm = spPr["a:xfrm"] ?? {};
|
|
74936
|
+
spPr["a:xfrm"] = xfrm;
|
|
74937
|
+
const off = xfrm["a:off"] ?? {};
|
|
74938
|
+
xfrm["a:off"] = off;
|
|
74939
|
+
off["@_x"] = String(xEmu);
|
|
74940
|
+
off["@_y"] = String(yEmu);
|
|
74941
|
+
const ext = xfrm["a:ext"] ?? {};
|
|
74942
|
+
xfrm["a:ext"] = ext;
|
|
74943
|
+
ext["@_cx"] = String(cxEmu);
|
|
74944
|
+
ext["@_cy"] = String(cyEmu);
|
|
74945
|
+
}
|
|
74946
|
+
function createEmptyPlaceholderElement(target, xEmu, yEmu, cxEmu, cyEmu, uniqueId) {
|
|
74947
|
+
if (cxEmu <= 0 || cyEmu <= 0) {
|
|
74948
|
+
return null;
|
|
74949
|
+
}
|
|
74950
|
+
const phNode = {};
|
|
74951
|
+
if (target.type) {
|
|
74952
|
+
phNode["@_type"] = target.type;
|
|
74953
|
+
}
|
|
74954
|
+
if (target.idx !== void 0) {
|
|
74955
|
+
phNode["@_idx"] = target.idx;
|
|
74956
|
+
}
|
|
74957
|
+
const rawXml = {
|
|
74958
|
+
"p:nvSpPr": {
|
|
74959
|
+
"p:cNvPr": {
|
|
74960
|
+
"@_id": uniqueId,
|
|
74961
|
+
"@_name": `Placeholder ${target.type || "content"}`
|
|
74962
|
+
},
|
|
74963
|
+
"p:cNvSpPr": {
|
|
74964
|
+
"a:spLocks": { "@_noGrp": "1" }
|
|
74965
|
+
},
|
|
74966
|
+
"p:nvPr": {
|
|
74967
|
+
"p:ph": phNode
|
|
74968
|
+
}
|
|
74969
|
+
},
|
|
74970
|
+
"p:spPr": {
|
|
74971
|
+
"a:xfrm": {
|
|
74972
|
+
"a:off": { "@_x": String(xEmu), "@_y": String(yEmu) },
|
|
74973
|
+
"a:ext": { "@_cx": String(cxEmu), "@_cy": String(cyEmu) }
|
|
74974
|
+
}
|
|
74975
|
+
},
|
|
74976
|
+
"p:txBody": {
|
|
74977
|
+
"a:bodyPr": {},
|
|
74978
|
+
"a:lstStyle": {},
|
|
74979
|
+
"a:p": { "a:endParaRPr": { "@_lang": "en-US" } }
|
|
74980
|
+
}
|
|
74981
|
+
};
|
|
74982
|
+
return {
|
|
74983
|
+
type: "text",
|
|
74984
|
+
id: `ph-${target.type || "content"}-${target.idx ?? "0"}-${uniqueId}`,
|
|
74985
|
+
x: Math.round(xEmu / exports.EMU_PER_PX),
|
|
74986
|
+
y: Math.round(yEmu / exports.EMU_PER_PX),
|
|
74987
|
+
width: Math.round(cxEmu / exports.EMU_PER_PX),
|
|
74988
|
+
height: Math.round(cyEmu / exports.EMU_PER_PX),
|
|
74989
|
+
text: "",
|
|
74990
|
+
rawXml
|
|
74991
|
+
};
|
|
74992
|
+
}
|
|
74993
|
+
var init_placeholder_xml = __esm({
|
|
74994
|
+
"pptx/core/utils/placeholder-xml.ts"() {
|
|
74995
|
+
init_constants2();
|
|
74996
|
+
}
|
|
74997
|
+
});
|
|
74998
|
+
|
|
74999
|
+
// pptx/core/core/runtime/save-geometry-validation.ts
|
|
75000
|
+
function omitsInheritedFrame(element) {
|
|
75001
|
+
if (!["text", "shape", "picture", "media"].includes(element.type) || !element.rawXml)
|
|
75002
|
+
return false;
|
|
75003
|
+
if (!xmlHasChild(findNonVisualProps(element.rawXml), "p:ph")) return false;
|
|
75004
|
+
if (xmlHasChild(xmlChild(element.rawXml, "p:spPr"), "a:xfrm") || xmlHasChild(element.rawXml, "p:xfrm"))
|
|
75005
|
+
return false;
|
|
75006
|
+
const baseline = element.inheritedTransform;
|
|
75007
|
+
if (!baseline) return FRAME_FIELDS.every((key2) => element[key2] === void 0);
|
|
75008
|
+
return FRAME_FIELDS.every(
|
|
75009
|
+
(key2) => Number.isFinite(baseline[key2]) && (element[key2] === void 0 || element[key2] === baseline[key2])
|
|
75010
|
+
) && ["rotation", "skewX", "skewY", "flipHorizontal", "flipVertical"].every(
|
|
75011
|
+
(key2) => (element[key2] ?? 0) === (baseline[key2] ?? 0)
|
|
75012
|
+
);
|
|
75013
|
+
}
|
|
75014
|
+
function validateElementGeometry(element, context, emuPerPx = 9525) {
|
|
75015
|
+
const inherited = omitsInheritedFrame(element);
|
|
75016
|
+
const record2 = element;
|
|
75017
|
+
const fields = [...inherited ? [] : FRAME_FIELDS, ...OPTIONAL_FIELDS];
|
|
75018
|
+
for (const field of fields) {
|
|
75019
|
+
const value = record2[field];
|
|
75020
|
+
if (OPTIONAL_FIELDS.includes(field) && value === void 0) continue;
|
|
75021
|
+
if (typeof value !== "number" || !Number.isFinite(value) || !Number.isFinite(value * emuPerPx)) {
|
|
75022
|
+
throw new Error(
|
|
75023
|
+
`${context}: element '${element.id}' (${element.name ?? "unnamed"}, type=${element.type}) has invalid ${field}=${String(value)}; expected a finite number`
|
|
75024
|
+
);
|
|
75025
|
+
}
|
|
75026
|
+
}
|
|
75027
|
+
if (element.type === "group") {
|
|
75028
|
+
for (const child32 of element.children) validateElementGeometry(child32, context, emuPerPx);
|
|
75029
|
+
}
|
|
75030
|
+
}
|
|
75031
|
+
function validateSlideGeometry(slides) {
|
|
75032
|
+
for (const slide of slides) {
|
|
75033
|
+
for (const element of slide.elements) {
|
|
75034
|
+
validateElementGeometry(element, `Slide ${slide.slideNumber} (${slide.id})`);
|
|
75035
|
+
}
|
|
75036
|
+
}
|
|
75037
|
+
}
|
|
75038
|
+
var FRAME_FIELDS, OPTIONAL_FIELDS;
|
|
75039
|
+
var init_save_geometry_validation = __esm({
|
|
75040
|
+
"pptx/core/core/runtime/save-geometry-validation.ts"() {
|
|
75041
|
+
init_placeholder_xml();
|
|
75042
|
+
init_xml_access();
|
|
75043
|
+
FRAME_FIELDS = ["x", "y", "width", "height"];
|
|
75044
|
+
OPTIONAL_FIELDS = [
|
|
75045
|
+
"xEmu",
|
|
75046
|
+
"yEmu",
|
|
75047
|
+
"widthEmu",
|
|
75048
|
+
"heightEmu",
|
|
75049
|
+
"rotation",
|
|
75050
|
+
"skewX",
|
|
75051
|
+
"skewY",
|
|
75052
|
+
"chOffXEmu",
|
|
75053
|
+
"chOffYEmu",
|
|
75054
|
+
"chExtWidthEmu",
|
|
75055
|
+
"chExtHeightEmu"
|
|
75056
|
+
];
|
|
75057
|
+
}
|
|
75058
|
+
});
|
|
75059
|
+
|
|
74613
75060
|
// pptx/core/core/builders/PptxElementTransformUpdater.ts
|
|
74614
75061
|
exports.PptxElementTransformUpdater = void 0;
|
|
74615
75062
|
var init_PptxElementTransformUpdater = __esm({
|
|
@@ -74619,6 +75066,7 @@ var init_PptxElementTransformUpdater = __esm({
|
|
|
74619
75066
|
init_xml_access();
|
|
74620
75067
|
init_group_tight_rewrap();
|
|
74621
75068
|
init_inherited_shape_transform();
|
|
75069
|
+
init_save_geometry_validation();
|
|
74622
75070
|
exports.PptxElementTransformUpdater = class {
|
|
74623
75071
|
applyTransform(shape, element, emuPerPx, enclosingGroupChildSpace) {
|
|
74624
75072
|
const transform7 = shape["p:spPr"]?.["a:xfrm"] || shape["p:xfrm"] || // A group's child geometry uses a different frame from the load-time baseline.
|
|
@@ -74626,6 +75074,7 @@ var init_PptxElementTransformUpdater = __esm({
|
|
|
74626
75074
|
if (!transform7) {
|
|
74627
75075
|
return;
|
|
74628
75076
|
}
|
|
75077
|
+
validateElementGeometry(element, "Transform writer", emuPerPx);
|
|
74629
75078
|
if (!transform7["a:off"]) {
|
|
74630
75079
|
transform7["a:off"] = {};
|
|
74631
75080
|
}
|
|
@@ -77660,7 +78109,7 @@ function parseBorderSide(side) {
|
|
|
77660
78109
|
}
|
|
77661
78110
|
const widthEmu = parseInt(String(ln["@_w"] || "0"), 10);
|
|
77662
78111
|
if (widthEmu > 0) {
|
|
77663
|
-
border.width = Math.max(1, Math.round(widthEmu /
|
|
78112
|
+
border.width = Math.max(1, Math.round(widthEmu / EMU_PER_PIXEL3));
|
|
77664
78113
|
has2 = true;
|
|
77665
78114
|
}
|
|
77666
78115
|
const prstDash = ln["a:prstDash"];
|
|
@@ -77717,12 +78166,12 @@ function parseTableStyleSectionCell3D(tcStyle) {
|
|
|
77717
78166
|
if (bevel2) {
|
|
77718
78167
|
const bevelWidth = parseInt(String(bevel2["@_w"] || "0"), 10);
|
|
77719
78168
|
if (bevelWidth > 0) {
|
|
77720
|
-
cell3D.bevelWidth = Math.round(bevelWidth /
|
|
78169
|
+
cell3D.bevelWidth = Math.round(bevelWidth / EMU_PER_PIXEL3);
|
|
77721
78170
|
hasStyle = true;
|
|
77722
78171
|
}
|
|
77723
78172
|
const bevelHeight = parseInt(String(bevel2["@_h"] || "0"), 10);
|
|
77724
78173
|
if (bevelHeight > 0) {
|
|
77725
|
-
cell3D.bevelHeight = Math.round(bevelHeight /
|
|
78174
|
+
cell3D.bevelHeight = Math.round(bevelHeight / EMU_PER_PIXEL3);
|
|
77726
78175
|
hasStyle = true;
|
|
77727
78176
|
}
|
|
77728
78177
|
const bevelPreset = String(bevel2["@_prst"] || "").trim();
|
|
@@ -77746,11 +78195,11 @@ function parseTableStyleSectionCell3D(tcStyle) {
|
|
|
77746
78195
|
}
|
|
77747
78196
|
return hasStyle ? cell3D : void 0;
|
|
77748
78197
|
}
|
|
77749
|
-
var
|
|
78198
|
+
var EMU_PER_PIXEL3, BORDER_SIDES;
|
|
77750
78199
|
var init_table_style_border_parse = __esm({
|
|
77751
78200
|
"pptx/core/core/runtime/table-style-border-parse.ts"() {
|
|
77752
78201
|
init_color_primitives();
|
|
77753
|
-
|
|
78202
|
+
EMU_PER_PIXEL3 = 9525;
|
|
77754
78203
|
BORDER_SIDES = [
|
|
77755
78204
|
"left",
|
|
77756
78205
|
"right",
|
|
@@ -107323,6 +107772,80 @@ var init_factories = __esm({
|
|
|
107323
107772
|
}
|
|
107324
107773
|
});
|
|
107325
107774
|
|
|
107775
|
+
// pptx/core/utils/placeholder-remap.ts
|
|
107776
|
+
function placeholderContentRole(type) {
|
|
107777
|
+
const declared = (type ?? "").trim().toLowerCase() || "body";
|
|
107778
|
+
if (TITLE_ROLE.has(declared)) {
|
|
107779
|
+
return "title";
|
|
107780
|
+
}
|
|
107781
|
+
if (CONTENT_ROLE.has(declared)) {
|
|
107782
|
+
return "content";
|
|
107783
|
+
}
|
|
107784
|
+
return declared;
|
|
107785
|
+
}
|
|
107786
|
+
function preferredPlaceholderTypes(element) {
|
|
107787
|
+
switch (element.type) {
|
|
107788
|
+
case "image":
|
|
107789
|
+
case "picture":
|
|
107790
|
+
return ["pic", "obj", "body"];
|
|
107791
|
+
case "chart":
|
|
107792
|
+
return ["chart", "obj", "body"];
|
|
107793
|
+
case "table":
|
|
107794
|
+
return ["tbl", "obj", "body"];
|
|
107795
|
+
case "media":
|
|
107796
|
+
case "model3d":
|
|
107797
|
+
return ["media", "pic", "obj", "body"];
|
|
107798
|
+
case "smartArt":
|
|
107799
|
+
return ["dgm", "obj", "body"];
|
|
107800
|
+
case "text":
|
|
107801
|
+
return ["body", "subtitle", "obj"];
|
|
107802
|
+
default:
|
|
107803
|
+
return ["obj", "body"];
|
|
107804
|
+
}
|
|
107805
|
+
}
|
|
107806
|
+
function scorePlaceholderMatch(element, source, target) {
|
|
107807
|
+
if (placeholderContentRole(source.type) !== placeholderContentRole(target.type)) {
|
|
107808
|
+
return -1;
|
|
107809
|
+
}
|
|
107810
|
+
const sourceType = normalizeType(source.type);
|
|
107811
|
+
const targetType = normalizeType(target.type);
|
|
107812
|
+
let score = 1;
|
|
107813
|
+
if (source.idx !== void 0 && source.idx === target.idx) {
|
|
107814
|
+
score += 100;
|
|
107815
|
+
}
|
|
107816
|
+
if (sourceType === targetType) {
|
|
107817
|
+
score += 50;
|
|
107818
|
+
}
|
|
107819
|
+
const preferred = preferredPlaceholderTypes(element).indexOf(targetType);
|
|
107820
|
+
if (preferred >= 0) {
|
|
107821
|
+
score += 30 - preferred * 5;
|
|
107822
|
+
}
|
|
107823
|
+
if (targetType === "obj") {
|
|
107824
|
+
score += 10;
|
|
107825
|
+
}
|
|
107826
|
+
return score;
|
|
107827
|
+
}
|
|
107828
|
+
function normalizeType(type) {
|
|
107829
|
+
return (type ?? "").trim().toLowerCase() || "body";
|
|
107830
|
+
}
|
|
107831
|
+
var TITLE_ROLE, CONTENT_ROLE;
|
|
107832
|
+
var init_placeholder_remap = __esm({
|
|
107833
|
+
"pptx/core/utils/placeholder-remap.ts"() {
|
|
107834
|
+
TITLE_ROLE = /* @__PURE__ */ new Set(["title", "ctrtitle"]);
|
|
107835
|
+
CONTENT_ROLE = /* @__PURE__ */ new Set([
|
|
107836
|
+
"body",
|
|
107837
|
+
"obj",
|
|
107838
|
+
"subtitle",
|
|
107839
|
+
"pic",
|
|
107840
|
+
"chart",
|
|
107841
|
+
"tbl",
|
|
107842
|
+
"media",
|
|
107843
|
+
"clipart",
|
|
107844
|
+
"dgm"
|
|
107845
|
+
]);
|
|
107846
|
+
}
|
|
107847
|
+
});
|
|
107848
|
+
|
|
107326
107849
|
// pptx/core/core/runtime/master-save-helpers.ts
|
|
107327
107850
|
function applyHeaderFooterFlagsToNode(root, flags) {
|
|
107328
107851
|
if (!flags || Object.keys(flags).length === 0) {
|
|
@@ -126916,178 +127439,6 @@ var init_chart_user_shapes_serializer = __esm({
|
|
|
126916
127439
|
}
|
|
126917
127440
|
});
|
|
126918
127441
|
|
|
126919
|
-
// pptx/core/utils/placeholder-remap.ts
|
|
126920
|
-
function placeholderContentRole(type) {
|
|
126921
|
-
const declared = (type ?? "").trim().toLowerCase() || "body";
|
|
126922
|
-
if (TITLE_ROLE.has(declared)) {
|
|
126923
|
-
return "title";
|
|
126924
|
-
}
|
|
126925
|
-
if (CONTENT_ROLE.has(declared)) {
|
|
126926
|
-
return "content";
|
|
126927
|
-
}
|
|
126928
|
-
return declared;
|
|
126929
|
-
}
|
|
126930
|
-
function preferredPlaceholderTypes(element) {
|
|
126931
|
-
switch (element.type) {
|
|
126932
|
-
case "image":
|
|
126933
|
-
case "picture":
|
|
126934
|
-
return ["pic", "obj", "body"];
|
|
126935
|
-
case "chart":
|
|
126936
|
-
return ["chart", "obj", "body"];
|
|
126937
|
-
case "table":
|
|
126938
|
-
return ["tbl", "obj", "body"];
|
|
126939
|
-
case "media":
|
|
126940
|
-
case "model3d":
|
|
126941
|
-
return ["media", "pic", "obj", "body"];
|
|
126942
|
-
case "smartArt":
|
|
126943
|
-
return ["dgm", "obj", "body"];
|
|
126944
|
-
case "text":
|
|
126945
|
-
return ["body", "subtitle", "obj"];
|
|
126946
|
-
default:
|
|
126947
|
-
return ["obj", "body"];
|
|
126948
|
-
}
|
|
126949
|
-
}
|
|
126950
|
-
function scorePlaceholderMatch(element, source, target) {
|
|
126951
|
-
if (placeholderContentRole(source.type) !== placeholderContentRole(target.type)) {
|
|
126952
|
-
return -1;
|
|
126953
|
-
}
|
|
126954
|
-
const sourceType = normalizeType(source.type);
|
|
126955
|
-
const targetType = normalizeType(target.type);
|
|
126956
|
-
let score = 1;
|
|
126957
|
-
if (source.idx !== void 0 && source.idx === target.idx) {
|
|
126958
|
-
score += 100;
|
|
126959
|
-
}
|
|
126960
|
-
if (sourceType === targetType) {
|
|
126961
|
-
score += 50;
|
|
126962
|
-
}
|
|
126963
|
-
const preferred = preferredPlaceholderTypes(element).indexOf(targetType);
|
|
126964
|
-
if (preferred >= 0) {
|
|
126965
|
-
score += 30 - preferred * 5;
|
|
126966
|
-
}
|
|
126967
|
-
if (targetType === "obj") {
|
|
126968
|
-
score += 10;
|
|
126969
|
-
}
|
|
126970
|
-
return score;
|
|
126971
|
-
}
|
|
126972
|
-
function normalizeType(type) {
|
|
126973
|
-
return (type ?? "").trim().toLowerCase() || "body";
|
|
126974
|
-
}
|
|
126975
|
-
var TITLE_ROLE, CONTENT_ROLE;
|
|
126976
|
-
var init_placeholder_remap = __esm({
|
|
126977
|
-
"pptx/core/utils/placeholder-remap.ts"() {
|
|
126978
|
-
TITLE_ROLE = /* @__PURE__ */ new Set(["title", "ctrtitle"]);
|
|
126979
|
-
CONTENT_ROLE = /* @__PURE__ */ new Set([
|
|
126980
|
-
"body",
|
|
126981
|
-
"obj",
|
|
126982
|
-
"subtitle",
|
|
126983
|
-
"pic",
|
|
126984
|
-
"chart",
|
|
126985
|
-
"tbl",
|
|
126986
|
-
"media",
|
|
126987
|
-
"clipart",
|
|
126988
|
-
"dgm"
|
|
126989
|
-
]);
|
|
126990
|
-
}
|
|
126991
|
-
});
|
|
126992
|
-
|
|
126993
|
-
// pptx/core/utils/placeholder-xml.ts
|
|
126994
|
-
function findNonVisualProps(rawXml) {
|
|
126995
|
-
for (const container2 of ["p:nvSpPr", "p:nvPicPr", "p:nvGraphicFramePr"]) {
|
|
126996
|
-
const parent = rawXml[container2];
|
|
126997
|
-
const nvPr = parent?.["p:nvPr"];
|
|
126998
|
-
if (nvPr) {
|
|
126999
|
-
return nvPr;
|
|
127000
|
-
}
|
|
127001
|
-
}
|
|
127002
|
-
return void 0;
|
|
127003
|
-
}
|
|
127004
|
-
function retargetPlaceholder(rawXml, target) {
|
|
127005
|
-
const nvPr = findNonVisualProps(rawXml);
|
|
127006
|
-
if (!nvPr) {
|
|
127007
|
-
return;
|
|
127008
|
-
}
|
|
127009
|
-
const ph = nvPr["p:ph"] ?? {};
|
|
127010
|
-
nvPr["p:ph"] = ph;
|
|
127011
|
-
if (target.type) {
|
|
127012
|
-
ph["@_type"] = target.type;
|
|
127013
|
-
} else {
|
|
127014
|
-
delete ph["@_type"];
|
|
127015
|
-
}
|
|
127016
|
-
if (target.idx !== void 0) {
|
|
127017
|
-
ph["@_idx"] = target.idx;
|
|
127018
|
-
} else {
|
|
127019
|
-
delete ph["@_idx"];
|
|
127020
|
-
}
|
|
127021
|
-
}
|
|
127022
|
-
function setRawXmlTransform(rawXml, xEmu, yEmu, cxEmu, cyEmu) {
|
|
127023
|
-
const spPr = rawXml["p:spPr"];
|
|
127024
|
-
if (!spPr) {
|
|
127025
|
-
return;
|
|
127026
|
-
}
|
|
127027
|
-
const xfrm = spPr["a:xfrm"] ?? {};
|
|
127028
|
-
spPr["a:xfrm"] = xfrm;
|
|
127029
|
-
const off = xfrm["a:off"] ?? {};
|
|
127030
|
-
xfrm["a:off"] = off;
|
|
127031
|
-
off["@_x"] = String(xEmu);
|
|
127032
|
-
off["@_y"] = String(yEmu);
|
|
127033
|
-
const ext = xfrm["a:ext"] ?? {};
|
|
127034
|
-
xfrm["a:ext"] = ext;
|
|
127035
|
-
ext["@_cx"] = String(cxEmu);
|
|
127036
|
-
ext["@_cy"] = String(cyEmu);
|
|
127037
|
-
}
|
|
127038
|
-
function createEmptyPlaceholderElement(target, xEmu, yEmu, cxEmu, cyEmu, uniqueId) {
|
|
127039
|
-
if (cxEmu <= 0 || cyEmu <= 0) {
|
|
127040
|
-
return null;
|
|
127041
|
-
}
|
|
127042
|
-
const phNode = {};
|
|
127043
|
-
if (target.type) {
|
|
127044
|
-
phNode["@_type"] = target.type;
|
|
127045
|
-
}
|
|
127046
|
-
if (target.idx !== void 0) {
|
|
127047
|
-
phNode["@_idx"] = target.idx;
|
|
127048
|
-
}
|
|
127049
|
-
const rawXml = {
|
|
127050
|
-
"p:nvSpPr": {
|
|
127051
|
-
"p:cNvPr": {
|
|
127052
|
-
"@_id": uniqueId,
|
|
127053
|
-
"@_name": `Placeholder ${target.type || "content"}`
|
|
127054
|
-
},
|
|
127055
|
-
"p:cNvSpPr": {
|
|
127056
|
-
"a:spLocks": { "@_noGrp": "1" }
|
|
127057
|
-
},
|
|
127058
|
-
"p:nvPr": {
|
|
127059
|
-
"p:ph": phNode
|
|
127060
|
-
}
|
|
127061
|
-
},
|
|
127062
|
-
"p:spPr": {
|
|
127063
|
-
"a:xfrm": {
|
|
127064
|
-
"a:off": { "@_x": String(xEmu), "@_y": String(yEmu) },
|
|
127065
|
-
"a:ext": { "@_cx": String(cxEmu), "@_cy": String(cyEmu) }
|
|
127066
|
-
}
|
|
127067
|
-
},
|
|
127068
|
-
"p:txBody": {
|
|
127069
|
-
"a:bodyPr": {},
|
|
127070
|
-
"a:lstStyle": {},
|
|
127071
|
-
"a:p": { "a:endParaRPr": { "@_lang": "en-US" } }
|
|
127072
|
-
}
|
|
127073
|
-
};
|
|
127074
|
-
return {
|
|
127075
|
-
type: "text",
|
|
127076
|
-
id: `ph-${target.type || "content"}-${target.idx ?? "0"}-${uniqueId}`,
|
|
127077
|
-
x: Math.round(xEmu / exports.EMU_PER_PX),
|
|
127078
|
-
y: Math.round(yEmu / exports.EMU_PER_PX),
|
|
127079
|
-
width: Math.round(cxEmu / exports.EMU_PER_PX),
|
|
127080
|
-
height: Math.round(cyEmu / exports.EMU_PER_PX),
|
|
127081
|
-
text: "",
|
|
127082
|
-
rawXml
|
|
127083
|
-
};
|
|
127084
|
-
}
|
|
127085
|
-
var init_placeholder_xml = __esm({
|
|
127086
|
-
"pptx/core/utils/placeholder-xml.ts"() {
|
|
127087
|
-
init_constants2();
|
|
127088
|
-
}
|
|
127089
|
-
});
|
|
127090
|
-
|
|
127091
127442
|
// pptx/core/utils/text-fill-blip.ts
|
|
127092
127443
|
function resolveTextFillBlip(blipFill, lookupTarget, resolveArchivePath, allowExternal) {
|
|
127093
127444
|
const blip = blipFill["a:blip"];
|
|
@@ -146991,8 +147342,8 @@ function mergeBorderSideXml(border, existingSide) {
|
|
|
146991
147342
|
const ln = ensureChild2(existing, "a:ln");
|
|
146992
147343
|
if (border.width !== void 0) {
|
|
146993
147344
|
const currentEmu = parseInt(String(ln["@_w"] || "0"), 10);
|
|
146994
|
-
if (currentEmu <= 0 || Math.max(1, Math.round(currentEmu /
|
|
146995
|
-
ln["@_w"] = String(Math.round(border.width *
|
|
147345
|
+
if (currentEmu <= 0 || Math.max(1, Math.round(currentEmu / EMU_PER_PIXEL4)) !== border.width) {
|
|
147346
|
+
ln["@_w"] = String(Math.round(border.width * EMU_PER_PIXEL4));
|
|
146996
147347
|
}
|
|
146997
147348
|
}
|
|
146998
147349
|
if (border.dash) {
|
|
@@ -147048,10 +147399,10 @@ function writeTableStyleSectionCell3D(section, cell3D) {
|
|
|
147048
147399
|
if (cell3D.bevelWidth !== void 0 || cell3D.bevelHeight !== void 0 || cell3D.bevelPreset !== void 0) {
|
|
147049
147400
|
const bevel2 = {};
|
|
147050
147401
|
if (cell3D.bevelWidth !== void 0) {
|
|
147051
|
-
bevel2["@_w"] = String(Math.round(cell3D.bevelWidth *
|
|
147402
|
+
bevel2["@_w"] = String(Math.round(cell3D.bevelWidth * EMU_PER_PIXEL4));
|
|
147052
147403
|
}
|
|
147053
147404
|
if (cell3D.bevelHeight !== void 0) {
|
|
147054
|
-
bevel2["@_h"] = String(Math.round(cell3D.bevelHeight *
|
|
147405
|
+
bevel2["@_h"] = String(Math.round(cell3D.bevelHeight * EMU_PER_PIXEL4));
|
|
147055
147406
|
}
|
|
147056
147407
|
if (cell3D.bevelPreset) {
|
|
147057
147408
|
bevel2["@_prst"] = cell3D.bevelPreset;
|
|
@@ -147070,12 +147421,12 @@ function writeTableStyleSectionCell3D(section, cell3D) {
|
|
|
147070
147421
|
}
|
|
147071
147422
|
tcStyle["a:cell3D"] = node;
|
|
147072
147423
|
}
|
|
147073
|
-
var
|
|
147424
|
+
var EMU_PER_PIXEL4, BORDER_SIDE_ORDER, LN_CHILD_ORDER, LN_FILL_KEYS;
|
|
147074
147425
|
var init_table_style_border_write = __esm({
|
|
147075
147426
|
"pptx/core/core/runtime/table-style-border-write.ts"() {
|
|
147076
147427
|
init_xml_reorder();
|
|
147077
147428
|
init_table_style_xml_helpers();
|
|
147078
|
-
|
|
147429
|
+
EMU_PER_PIXEL4 = 9525;
|
|
147079
147430
|
BORDER_SIDE_ORDER = [
|
|
147080
147431
|
"a:left",
|
|
147081
147432
|
"a:right",
|
|
@@ -148013,6 +148364,7 @@ var init_PptxHandlerRuntimeSavePipeline = __esm({
|
|
|
148013
148364
|
init_header_footer_parts();
|
|
148014
148365
|
init_pptx_print_properties();
|
|
148015
148366
|
init_PptxHandlerRuntimeSaveStructuralIds();
|
|
148367
|
+
init_save_geometry_validation();
|
|
148016
148368
|
PptxHandlerRuntime54 = class _PptxHandlerRuntime extends PptxHandlerRuntime53 {
|
|
148017
148369
|
/**
|
|
148018
148370
|
* Resolve the effective conformance class for this save operation.
|
|
@@ -148027,6 +148379,19 @@ var init_PptxHandlerRuntimeSavePipeline = __esm({
|
|
|
148027
148379
|
return this.isStrictOoxml ? "strict" : "transitional";
|
|
148028
148380
|
}
|
|
148029
148381
|
async save(slides, options) {
|
|
148382
|
+
validateSlideGeometry(slides);
|
|
148383
|
+
const templates = [
|
|
148384
|
+
...options?.slideMasters ?? [],
|
|
148385
|
+
...options?.slideLayouts ?? [],
|
|
148386
|
+
...options?.slideMasters?.flatMap((master) => master.layouts ?? []) ?? [],
|
|
148387
|
+
...options?.notesMaster ? [options.notesMaster] : [],
|
|
148388
|
+
...options?.handoutMaster ? [options.handoutMaster] : []
|
|
148389
|
+
];
|
|
148390
|
+
for (const template of templates) {
|
|
148391
|
+
for (const element of template.elements ?? []) {
|
|
148392
|
+
validateElementGeometry(element, `Template (${template.path})`);
|
|
148393
|
+
}
|
|
148394
|
+
}
|
|
148030
148395
|
if (options?.outputFormat === "ppt") {
|
|
148031
148396
|
return this.saveAsLegacyPpt(
|
|
148032
148397
|
slides,
|
|
@@ -148994,8 +149359,7 @@ var init_PptxHandlerRuntimePlaceholderLookup = __esm({
|
|
|
148994
149359
|
return this.scanPlaceholderBuckets(spTree, (info) => info?.type === type);
|
|
148995
149360
|
}
|
|
148996
149361
|
/** The layout and master counterparts of a placeholder, unmerged. */
|
|
148997
|
-
findPlaceholderContexts(slidePath, expected) {
|
|
148998
|
-
const layoutPath = this.resolveLayoutPathForSlide(slidePath);
|
|
149362
|
+
findPlaceholderContexts(slidePath, expected, layoutPath = this.resolveLayoutPathForSlide(slidePath)) {
|
|
148999
149363
|
if (!layoutPath) {
|
|
149000
149364
|
return {};
|
|
149001
149365
|
}
|
|
@@ -149007,10 +149371,11 @@ var init_PptxHandlerRuntimePlaceholderLookup = __esm({
|
|
|
149007
149371
|
const master = this.findPlaceholderInShapeTree(masterSpTree, expected) ?? this.findSingletonPlaceholderInShapeTree(masterSpTree, expected);
|
|
149008
149372
|
return { layout, master };
|
|
149009
149373
|
}
|
|
149010
|
-
findPlaceholderContext(slidePath, expected) {
|
|
149374
|
+
findPlaceholderContext(slidePath, expected, layoutPath) {
|
|
149011
149375
|
const { layout: layoutContext, master: masterContext } = this.findPlaceholderContexts(
|
|
149012
149376
|
slidePath,
|
|
149013
|
-
expected
|
|
149377
|
+
expected,
|
|
149378
|
+
layoutPath
|
|
149014
149379
|
);
|
|
149015
149380
|
if (!layoutContext) {
|
|
149016
149381
|
return masterContext;
|
|
@@ -149036,8 +149401,8 @@ var init_PptxHandlerRuntimePlaceholderLookup = __esm({
|
|
|
149036
149401
|
* a master `p:sp`), so the layout keeps winning exactly as it does when
|
|
149037
149402
|
* both are shapes.
|
|
149038
149403
|
*/
|
|
149039
|
-
findPlaceholderNode(slidePath, expected) {
|
|
149040
|
-
const { layout, master } = this.findPlaceholderContexts(slidePath, expected);
|
|
149404
|
+
findPlaceholderNode(slidePath, expected, layoutPath) {
|
|
149405
|
+
const { layout, master } = this.findPlaceholderContexts(slidePath, expected, layoutPath);
|
|
149041
149406
|
const firstNode2 = (context) => context?.shape ?? context?.picture ?? context?.graphicFrame;
|
|
149042
149407
|
const layoutNode = firstNode2(layout);
|
|
149043
149408
|
const masterNode = firstNode2(master);
|
|
@@ -149078,8 +149443,7 @@ var init_PptxHandlerRuntimePlaceholderLookup = __esm({
|
|
|
149078
149443
|
* reference. Checks the layout cache first, then the master cache, and
|
|
149079
149444
|
* merges them so that layout values take priority over master values.
|
|
149080
149445
|
*/
|
|
149081
|
-
lookupPlaceholderDefaults(slidePath, phInfo) {
|
|
149082
|
-
const layoutPath = this.resolveLayoutPathForSlide(slidePath);
|
|
149446
|
+
lookupPlaceholderDefaults(slidePath, phInfo, layoutPath = this.resolveLayoutPathForSlide(slidePath)) {
|
|
149083
149447
|
if (!layoutPath) {
|
|
149084
149448
|
return void 0;
|
|
149085
149449
|
}
|
|
@@ -151258,14 +151622,14 @@ var init_PptxHandlerRuntimeShapeParsing = __esm({
|
|
|
151258
151622
|
init_element_paragraph_geometry();
|
|
151259
151623
|
init_PptxHandlerRuntimeShapeParagraphContentParsing();
|
|
151260
151624
|
PptxHandlerRuntime67 = class _PptxHandlerRuntime extends PptxHandlerRuntime66 {
|
|
151261
|
-
parseShape(shape, id, slidePath) {
|
|
151625
|
+
parseShape(shape, id, slidePath, layoutPath) {
|
|
151262
151626
|
try {
|
|
151263
151627
|
const spPr = shape["p:spPr"];
|
|
151264
151628
|
const slideRelationshipMap = slidePath ? this.slideRelsMap.get(slidePath) : void 0;
|
|
151265
151629
|
const placeholderInfo = this.extractPlaceholderInfo(
|
|
151266
151630
|
shape?.["p:nvSpPr"]?.["p:nvPr"]
|
|
151267
151631
|
);
|
|
151268
|
-
const inheritedPlaceholder = slidePath && placeholderInfo ? this.findPlaceholderContext(slidePath, placeholderInfo) : void 0;
|
|
151632
|
+
const inheritedPlaceholder = (slidePath || layoutPath) && placeholderInfo ? this.findPlaceholderContext(slidePath ?? "", placeholderInfo, layoutPath) : void 0;
|
|
151269
151633
|
const inheritedSpPr = inheritedPlaceholder?.shape?.["p:spPr"] || inheritedPlaceholder?.picture?.["p:spPr"];
|
|
151270
151634
|
const effectiveSpPr = spPr ? {
|
|
151271
151635
|
...spPr,
|
|
@@ -151391,7 +151755,7 @@ var init_PptxHandlerRuntimeShapeParsing = __esm({
|
|
|
151391
151755
|
);
|
|
151392
151756
|
const linkedTxbxId = bodyPropResult.linkedTxbxId;
|
|
151393
151757
|
const linkedTxbxSeq = bodyPropResult.linkedTxbxSeq;
|
|
151394
|
-
const phDefaults = slidePath && placeholderInfo ? this.lookupPlaceholderDefaults(slidePath, placeholderInfo) : void 0;
|
|
151758
|
+
const phDefaults = (slidePath || layoutPath) && placeholderInfo ? this.lookupPlaceholderDefaults(slidePath ?? "", placeholderInfo, layoutPath) : void 0;
|
|
151395
151759
|
if (phDefaults) {
|
|
151396
151760
|
this.applyPlaceholderBodyDefaults(textStyle, phDefaults);
|
|
151397
151761
|
}
|
|
@@ -160754,14 +161118,199 @@ var init_PptxHandlerRuntimeBackgroundStyles = __esm({
|
|
|
160754
161118
|
};
|
|
160755
161119
|
}
|
|
160756
161120
|
});
|
|
161121
|
+
|
|
161122
|
+
// pptx/core/core/runtime/sdk-placeholder.ts
|
|
161123
|
+
function selectTextPlaceholder(input, type, options, slots) {
|
|
161124
|
+
if (!TEXT_PLACEHOLDER_TYPES.has(type.toLowerCase())) {
|
|
161125
|
+
throw new Error(`Unsupported text placeholder type: ${type}`);
|
|
161126
|
+
}
|
|
161127
|
+
if (options.idx !== void 0 && (!Number.isInteger(options.idx) || options.idx < 0 || options.idx > 4294967295)) {
|
|
161128
|
+
throw new Error("Placeholder idx must be an unsigned 32-bit integer");
|
|
161129
|
+
}
|
|
161130
|
+
const source = {
|
|
161131
|
+
type: type.toLowerCase(),
|
|
161132
|
+
...options.idx !== void 0 ? { idx: String(options.idx) } : {}
|
|
161133
|
+
};
|
|
161134
|
+
let best;
|
|
161135
|
+
let bestScore = 0;
|
|
161136
|
+
for (const slot of slots) {
|
|
161137
|
+
if (!TEXT_PLACEHOLDER_TYPES.has(slot.phInfo.type ?? "obj")) continue;
|
|
161138
|
+
if (source.idx !== void 0 && source.idx !== (slot.phInfo.idx ?? "0")) continue;
|
|
161139
|
+
const score = scorePlaceholderMatch(input, source, slot.phInfo);
|
|
161140
|
+
if (score > bestScore) {
|
|
161141
|
+
best = slot;
|
|
161142
|
+
bestScore = score;
|
|
161143
|
+
}
|
|
161144
|
+
}
|
|
161145
|
+
return best ? { type: canonicalPlaceholderType(best.phInfo.type ?? "obj"), idx: best.phInfo.idx } : { type: canonicalPlaceholderType(source.type), idx: source.idx };
|
|
161146
|
+
}
|
|
161147
|
+
function withoutFallbackLanguage(properties) {
|
|
161148
|
+
const { "@_lang": language, ...rest } = properties;
|
|
161149
|
+
if (language !== "en-US") return properties;
|
|
161150
|
+
const keys = Object.keys(rest);
|
|
161151
|
+
return keys.length === 0 || keys.length === 1 && rest["@_dirty"] === "0" ? void 0 : rest;
|
|
161152
|
+
}
|
|
161153
|
+
function stripFallbackLanguage(node, key2) {
|
|
161154
|
+
const properties = node[key2];
|
|
161155
|
+
if (!properties || typeof properties !== "object") return node;
|
|
161156
|
+
const next = withoutFallbackLanguage(properties);
|
|
161157
|
+
if (next === properties) return node;
|
|
161158
|
+
const result = {};
|
|
161159
|
+
for (const [name, value] of Object.entries(node)) {
|
|
161160
|
+
if (name !== key2) result[name] = value;
|
|
161161
|
+
else if (next) result[name] = next;
|
|
161162
|
+
}
|
|
161163
|
+
return result;
|
|
161164
|
+
}
|
|
161165
|
+
function withoutFallbackLanguages(paragraphs) {
|
|
161166
|
+
return paragraphs.map((paragraph) => {
|
|
161167
|
+
const next = { ...stripFallbackLanguage(paragraph, "a:endParaRPr") };
|
|
161168
|
+
for (const child32 of ["a:r", "a:br", "a:fld"]) {
|
|
161169
|
+
const nodes = next[child32];
|
|
161170
|
+
if (nodes === void 0) continue;
|
|
161171
|
+
next[child32] = Array.isArray(nodes) ? nodes.map((node) => stripFallbackLanguage(node, "a:rPr")) : stripFallbackLanguage(nodes, "a:rPr");
|
|
161172
|
+
}
|
|
161173
|
+
return next;
|
|
161174
|
+
});
|
|
161175
|
+
}
|
|
161176
|
+
function placeholderShape2(identity, paragraphs) {
|
|
161177
|
+
paragraphs = withoutFallbackLanguages(paragraphs);
|
|
161178
|
+
return {
|
|
161179
|
+
"p:nvSpPr": {
|
|
161180
|
+
"p:cNvPr": { "@_id": "2", "@_name": `Placeholder ${identity.type}` },
|
|
161181
|
+
"p:cNvSpPr": { "a:spLocks": { "@_noGrp": "1" } },
|
|
161182
|
+
"p:nvPr": {
|
|
161183
|
+
"p:ph": {
|
|
161184
|
+
"@_type": identity.type,
|
|
161185
|
+
...identity.idx !== void 0 ? { "@_idx": identity.idx } : {}
|
|
161186
|
+
}
|
|
161187
|
+
}
|
|
161188
|
+
},
|
|
161189
|
+
"p:spPr": {},
|
|
161190
|
+
"p:txBody": { "a:bodyPr": {}, "a:lstStyle": {}, "a:p": paragraphs }
|
|
161191
|
+
};
|
|
161192
|
+
}
|
|
161193
|
+
function applyPlaceholderFrame(shape, inherited, options, emuPerPx, materializeFrame = false) {
|
|
161194
|
+
for (const key2 of ["x", "y", "width", "height"]) {
|
|
161195
|
+
if (options[key2] !== void 0 && !Number.isFinite(options[key2])) {
|
|
161196
|
+
throw new Error(`Invalid placeholder frame for ${key2}: expected a finite number`);
|
|
161197
|
+
}
|
|
161198
|
+
}
|
|
161199
|
+
const off = xmlPath(inherited, "p:spPr", "a:xfrm", "a:off");
|
|
161200
|
+
const ext = xmlPath(inherited, "p:spPr", "a:xfrm", "a:ext");
|
|
161201
|
+
const frame2 = {
|
|
161202
|
+
x: options.x ?? (off?.["@_x"] !== void 0 ? Number(off["@_x"]) / emuPerPx : void 0),
|
|
161203
|
+
y: options.y ?? (off?.["@_y"] !== void 0 ? Number(off["@_y"]) / emuPerPx : void 0),
|
|
161204
|
+
width: options.width ?? (ext?.["@_cx"] !== void 0 ? Number(ext["@_cx"]) / emuPerPx : void 0),
|
|
161205
|
+
height: options.height ?? (ext?.["@_cy"] !== void 0 ? Number(ext["@_cy"]) / emuPerPx : void 0)
|
|
161206
|
+
};
|
|
161207
|
+
for (const [key2, value] of Object.entries(frame2)) {
|
|
161208
|
+
if (!Number.isFinite(value)) {
|
|
161209
|
+
throw new Error(
|
|
161210
|
+
`No matching placeholder frame for ${key2}; supply a complete explicit frame or choose a layout containing this slot`
|
|
161211
|
+
);
|
|
161212
|
+
}
|
|
161213
|
+
}
|
|
161214
|
+
if (materializeFrame || ["x", "y", "width", "height"].some((key2) => options[key2] !== void 0)) {
|
|
161215
|
+
setRawXmlTransform(
|
|
161216
|
+
shape,
|
|
161217
|
+
...["x", "y", "width", "height"].map(
|
|
161218
|
+
(key2) => Math.round(frame2[key2] * emuPerPx)
|
|
161219
|
+
)
|
|
161220
|
+
);
|
|
161221
|
+
}
|
|
161222
|
+
}
|
|
161223
|
+
var TEXT_PLACEHOLDER_TYPES;
|
|
161224
|
+
var init_sdk_placeholder = __esm({
|
|
161225
|
+
"pptx/core/core/runtime/sdk-placeholder.ts"() {
|
|
161226
|
+
init_placeholder_remap();
|
|
161227
|
+
init_placeholder_xml();
|
|
161228
|
+
init_placeholder_validation();
|
|
161229
|
+
init_xml_access();
|
|
161230
|
+
TEXT_PLACEHOLDER_TYPES = /* @__PURE__ */ new Set([
|
|
161231
|
+
"title",
|
|
161232
|
+
"ctrtitle",
|
|
161233
|
+
"subtitle",
|
|
161234
|
+
"body",
|
|
161235
|
+
"obj",
|
|
161236
|
+
"dt",
|
|
161237
|
+
"ftr",
|
|
161238
|
+
"hdr",
|
|
161239
|
+
"sldnum"
|
|
161240
|
+
]);
|
|
161241
|
+
}
|
|
161242
|
+
});
|
|
161243
|
+
|
|
161244
|
+
// pptx/core/core/runtime/PptxHandlerRuntimeSdkPlaceholders.ts
|
|
160757
161245
|
var PptxHandlerRuntime103;
|
|
161246
|
+
var init_PptxHandlerRuntimeSdkPlaceholders = __esm({
|
|
161247
|
+
"pptx/core/core/runtime/PptxHandlerRuntimeSdkPlaceholders.ts"() {
|
|
161248
|
+
init_placeholder_remap();
|
|
161249
|
+
init_xml_access();
|
|
161250
|
+
init_PptxHandlerRuntimeBackgroundStyles();
|
|
161251
|
+
init_sdk_placeholder();
|
|
161252
|
+
PptxHandlerRuntime103 = class _PptxHandlerRuntime extends PptxHandlerRuntime102 {
|
|
161253
|
+
createPlaceholderElement(layoutPath, input, type, options) {
|
|
161254
|
+
if (input.type !== "text") throw new Error("Placeholder input must be text");
|
|
161255
|
+
const layout = this.layoutXmlMap.get(layoutPath);
|
|
161256
|
+
if (!layout) throw new Error(`Unknown layout: ${layoutPath}`);
|
|
161257
|
+
const identity = selectTextPlaceholder(
|
|
161258
|
+
input,
|
|
161259
|
+
type,
|
|
161260
|
+
options,
|
|
161261
|
+
this.extractLayoutPlaceholders(layout, layoutPath)
|
|
161262
|
+
);
|
|
161263
|
+
const shape = placeholderShape2(
|
|
161264
|
+
identity,
|
|
161265
|
+
this.createParagraphsFromTextContent(input.text, void 0, input.textSegments)
|
|
161266
|
+
);
|
|
161267
|
+
const inherited = this.findPlaceholderNode(
|
|
161268
|
+
"",
|
|
161269
|
+
{ type: identity.type.toLowerCase(), idx: identity.idx },
|
|
161270
|
+
layoutPath
|
|
161271
|
+
);
|
|
161272
|
+
const fallback = this.sdkMasterFrame(layoutPath, identity.type, identity.idx, inherited);
|
|
161273
|
+
applyPlaceholderFrame(
|
|
161274
|
+
shape,
|
|
161275
|
+
fallback ?? inherited,
|
|
161276
|
+
options,
|
|
161277
|
+
_PptxHandlerRuntime.EMU_PER_PX,
|
|
161278
|
+
fallback !== void 0
|
|
161279
|
+
);
|
|
161280
|
+
const element = this.parseShape(shape, input.id, void 0, layoutPath);
|
|
161281
|
+
if (!element) throw new Error("Unable to resolve placeholder content");
|
|
161282
|
+
if ((element.type === "text" || element.type === "shape") && !element.textStyle && element.textSegments?.[0]?.style) {
|
|
161283
|
+
element.textStyle = { ...element.textSegments[0].style };
|
|
161284
|
+
}
|
|
161285
|
+
return element;
|
|
161286
|
+
}
|
|
161287
|
+
sdkMasterFrame(layoutPath, type, idx, inherited) {
|
|
161288
|
+
if (!inherited) return void 0;
|
|
161289
|
+
if (xmlPath(inherited, "p:spPr", "a:xfrm", "a:off") && xmlPath(inherited, "p:spPr", "a:xfrm", "a:ext"))
|
|
161290
|
+
return void 0;
|
|
161291
|
+
const masterPath = this.resolveMasterPathForLayout(layoutPath);
|
|
161292
|
+
const tree = masterPath ? xmlPath(this.masterXmlMap.get(masterPath), "p:sldMaster", "p:cSld", "p:spTree") : void 0;
|
|
161293
|
+
const role = placeholderContentRole(type.toLowerCase());
|
|
161294
|
+
const candidates = this.ensureArray(tree?.["p:sp"]).filter((shape) => {
|
|
161295
|
+
const info = this.extractPlaceholderInfo(xmlPath(shape, "p:nvSpPr", "p:nvPr"));
|
|
161296
|
+
return info && placeholderContentRole(info.type) === role;
|
|
161297
|
+
});
|
|
161298
|
+
const master = candidates.find(
|
|
161299
|
+
(shape) => this.extractPlaceholderInfo(xmlPath(shape, "p:nvSpPr", "p:nvPr"))?.idx === idx
|
|
161300
|
+
) ?? candidates[0];
|
|
161301
|
+
return master ? this.mergeXmlObjects(master, inherited) : void 0;
|
|
161302
|
+
}
|
|
161303
|
+
};
|
|
161304
|
+
}
|
|
161305
|
+
});
|
|
161306
|
+
var PptxHandlerRuntime104;
|
|
160758
161307
|
var init_PptxHandlerRuntimeImplementation = __esm({
|
|
160759
161308
|
"pptx/core/core/runtime/PptxHandlerRuntimeImplementation.ts"() {
|
|
160760
161309
|
init_PptxElementXmlBuilder();
|
|
160761
161310
|
init_builders();
|
|
160762
161311
|
init_factories();
|
|
160763
|
-
|
|
160764
|
-
|
|
161312
|
+
init_PptxHandlerRuntimeSdkPlaceholders();
|
|
161313
|
+
PptxHandlerRuntime104 = class _PptxHandlerRuntime extends PptxHandlerRuntime103 {
|
|
160765
161314
|
constructor(dependencyFactory = new exports.PptxRuntimeDependencyFactory()) {
|
|
160766
161315
|
super();
|
|
160767
161316
|
this.dependencyFactory = dependencyFactory;
|
|
@@ -160905,7 +161454,7 @@ exports.PptxHandlerRuntime = void 0;
|
|
|
160905
161454
|
var init_PptxHandlerRuntime = __esm({
|
|
160906
161455
|
"pptx/core/core/PptxHandlerRuntime.ts"() {
|
|
160907
161456
|
init_PptxHandlerRuntimeImplementation();
|
|
160908
|
-
exports.PptxHandlerRuntime = class extends
|
|
161457
|
+
exports.PptxHandlerRuntime = class extends PptxHandlerRuntime104 {
|
|
160909
161458
|
};
|
|
160910
161459
|
}
|
|
160911
161460
|
});
|
|
@@ -163669,7 +164218,7 @@ function slideMasterXml2(deck, ctx) {
|
|
|
163669
164218
|
</p:txStyles>
|
|
163670
164219
|
</p:sldMaster>`;
|
|
163671
164220
|
}
|
|
163672
|
-
function
|
|
164221
|
+
function slideLayoutXml() {
|
|
163673
164222
|
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
163674
164223
|
<p:sldLayout ${XMLNS2} type="blank" preserve="1">
|
|
163675
164224
|
<p:cSld name="Blank">
|
|
@@ -163989,7 +164538,7 @@ async function buildPptxPackage(deck) {
|
|
|
163989
164538
|
${masterRels.join("\n")}
|
|
163990
164539
|
</Relationships>`
|
|
163991
164540
|
);
|
|
163992
|
-
zip.file("ppt/slideLayouts/slideLayout1.xml",
|
|
164541
|
+
zip.file("ppt/slideLayouts/slideLayout1.xml", slideLayoutXml());
|
|
163993
164542
|
zip.file(
|
|
163994
164543
|
"ppt/slideLayouts/_rels/slideLayout1.xml.rels",
|
|
163995
164544
|
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
@@ -164207,6 +164756,13 @@ var init_PptxHandlerCore = __esm({
|
|
|
164207
164756
|
getLayoutOptions() {
|
|
164208
164757
|
return this.runtime.getLayoutOptions();
|
|
164209
164758
|
}
|
|
164759
|
+
/** Resolve a text placeholder in this loaded deck, preserving layout inheritance. */
|
|
164760
|
+
createPlaceholderElement(layoutPath, input, type, options = {}) {
|
|
164761
|
+
if (!this.runtime.createPlaceholderElement) {
|
|
164762
|
+
throw new Error("This runtime does not support creating layout placeholders");
|
|
164763
|
+
}
|
|
164764
|
+
return this.runtime.createPlaceholderElement(layoutPath, input, type, options);
|
|
164765
|
+
}
|
|
164210
164766
|
/**
|
|
164211
164767
|
* Build the artwork thumbnails backing the New Slide / Layout galleries.
|
|
164212
164768
|
*
|
|
@@ -166292,7 +166848,9 @@ var Presentation = class _Presentation {
|
|
|
166292
166848
|
data,
|
|
166293
166849
|
createSlide: (layoutName) => {
|
|
166294
166850
|
const slideNum = data.slides.length + 1;
|
|
166295
|
-
|
|
166851
|
+
const layouts = handler.getLayoutOptions();
|
|
166852
|
+
const layout = layouts.find((item) => item.name === layoutName) ?? layouts.find((item) => item.name === "Blank") ?? layouts[0];
|
|
166853
|
+
return new exports.SlideBuilder(slideNum, layout?.path, layout?.name ?? layoutName, handler);
|
|
166296
166854
|
}
|
|
166297
166855
|
});
|
|
166298
166856
|
}
|
|
@@ -167419,199 +167977,12 @@ function addChartUserShapeGroupChild(element, groupPath, child32) {
|
|
|
167419
167977
|
});
|
|
167420
167978
|
}
|
|
167421
167979
|
|
|
167422
|
-
// pptx/core/builders/sdk/
|
|
167423
|
-
|
|
167424
|
-
init_xml_utils();
|
|
167425
|
-
init_PptxHandler();
|
|
167426
|
-
var EMU_PER_PIXEL4 = 9525;
|
|
167427
|
-
function pxToEmu(px3) {
|
|
167428
|
-
return Math.round(px3 * EMU_PER_PIXEL4);
|
|
167429
|
-
}
|
|
167430
|
-
function placeholderSpXml(ph, shapeId) {
|
|
167431
|
-
const name = ph.name ?? `${ph.type.charAt(0).toUpperCase() + ph.type.slice(1)} Placeholder ${shapeId - 1}`;
|
|
167432
|
-
const x = pxToEmu(ph.x);
|
|
167433
|
-
const y = pxToEmu(ph.y);
|
|
167434
|
-
const cx = pxToEmu(ph.width);
|
|
167435
|
-
const cy = pxToEmu(ph.height);
|
|
167436
|
-
const idxAttr = ph.idx !== void 0 ? ` idx="${Math.max(0, Math.round(ph.idx))}"` : "";
|
|
167437
|
-
return ` <p:sp>
|
|
167438
|
-
<p:nvSpPr>
|
|
167439
|
-
<p:cNvPr id="${shapeId}" name="${escAttr(name)}"/>
|
|
167440
|
-
<p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr>
|
|
167441
|
-
<p:nvPr><p:ph type="${escAttr(ph.type)}"${idxAttr}/></p:nvPr>
|
|
167442
|
-
</p:nvSpPr>
|
|
167443
|
-
<p:spPr>
|
|
167444
|
-
<a:xfrm><a:off x="${x}" y="${y}"/><a:ext cx="${cx}" cy="${cy}"/></a:xfrm>
|
|
167445
|
-
</p:spPr>
|
|
167446
|
-
<p:txBody>
|
|
167447
|
-
<a:bodyPr/>
|
|
167448
|
-
<a:lstStyle/>
|
|
167449
|
-
<a:p><a:endParaRPr lang="en-US"/></a:p>
|
|
167450
|
-
</p:txBody>
|
|
167451
|
-
</p:sp>`;
|
|
167452
|
-
}
|
|
167453
|
-
function normalizeSrgbHex2(color2) {
|
|
167454
|
-
if (!color2) {
|
|
167455
|
-
return void 0;
|
|
167456
|
-
}
|
|
167457
|
-
const raw = color2.trim().replace(/^#/, "").toUpperCase();
|
|
167458
|
-
if (/^[0-9A-F]{6}$/.test(raw)) {
|
|
167459
|
-
return raw;
|
|
167460
|
-
}
|
|
167461
|
-
if (/^[0-9A-F]{3}$/.test(raw)) {
|
|
167462
|
-
return raw.replace(/./g, (ch) => ch + ch);
|
|
167463
|
-
}
|
|
167464
|
-
return void 0;
|
|
167465
|
-
}
|
|
167466
|
-
function generateLayoutXml(definition) {
|
|
167467
|
-
const layoutType = definition.type ?? "obj";
|
|
167468
|
-
const placeholders = definition.placeholders ?? [];
|
|
167469
|
-
const phShapes = placeholders.map((ph, i2) => placeholderSpXml(ph, i2 + 2)).join("\n");
|
|
167470
|
-
let bgXml = "";
|
|
167471
|
-
const hex3 = normalizeSrgbHex2(definition.backgroundColor);
|
|
167472
|
-
if (hex3) {
|
|
167473
|
-
bgXml = ` <p:bg><p:bgPr><a:solidFill><a:srgbClr val="${hex3}"/></a:solidFill><a:effectLst/></p:bgPr></p:bg>
|
|
167474
|
-
`;
|
|
167475
|
-
}
|
|
167476
|
-
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
167477
|
-
<p:sldLayout xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
|
|
167478
|
-
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
|
167479
|
-
xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"
|
|
167480
|
-
type="${escAttr(layoutType)}" preserve="1">
|
|
167481
|
-
<p:cSld name="${escAttr(definition.name)}">
|
|
167482
|
-
${bgXml} <p:spTree>
|
|
167483
|
-
<p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr>
|
|
167484
|
-
<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>
|
|
167485
|
-
${phShapes}
|
|
167486
|
-
</p:spTree>
|
|
167487
|
-
</p:cSld>
|
|
167488
|
-
<p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr>
|
|
167489
|
-
</p:sldLayout>`;
|
|
167490
|
-
}
|
|
167491
|
-
function layoutRelsXml(masterIndex = 1) {
|
|
167492
|
-
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
167493
|
-
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
167494
|
-
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" Target="../slideMasters/slideMaster${masterIndex}.xml"/>
|
|
167495
|
-
</Relationships>`;
|
|
167496
|
-
}
|
|
167497
|
-
function countExistingLayouts(zip) {
|
|
167498
|
-
let count = 0;
|
|
167499
|
-
zip.forEach((relativePath) => {
|
|
167500
|
-
if (/^ppt\/slideLayouts\/slideLayout\d+\.xml$/.test(relativePath)) {
|
|
167501
|
-
count++;
|
|
167502
|
-
}
|
|
167503
|
-
});
|
|
167504
|
-
return count;
|
|
167505
|
-
}
|
|
167506
|
-
async function addLayoutToSlideMaster(zip, layoutIndex2, masterIndex = 1) {
|
|
167507
|
-
const masterRelsPath = `ppt/slideMasters/_rels/slideMaster${masterIndex}.xml.rels`;
|
|
167508
|
-
const masterRelsContent = await zip.file(masterRelsPath)?.async("string");
|
|
167509
|
-
if (!masterRelsContent) {
|
|
167510
|
-
throw new Error(`Slide master rels not found at ${masterRelsPath}`);
|
|
167511
|
-
}
|
|
167512
|
-
const rIdMatches = [...masterRelsContent.matchAll(/rId(\d+)/g)];
|
|
167513
|
-
const maxRId = rIdMatches.reduce((max, m) => Math.max(max, parseInt(m[1], 10)), 0);
|
|
167514
|
-
const newRId = `rId${maxRId + 1}`;
|
|
167515
|
-
const newRel = ` <Relationship Id="${newRId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" Target="../slideLayouts/slideLayout${layoutIndex2}.xml"/>`;
|
|
167516
|
-
const updatedRels = masterRelsContent.replace("</Relationships>", `${newRel}
|
|
167517
|
-
</Relationships>`);
|
|
167518
|
-
zip.file(masterRelsPath, updatedRels);
|
|
167519
|
-
const masterPath = `ppt/slideMasters/slideMaster${masterIndex}.xml`;
|
|
167520
|
-
const masterContent = await zip.file(masterPath)?.async("string");
|
|
167521
|
-
if (!masterContent) {
|
|
167522
|
-
throw new Error(`Slide master not found at ${masterPath}`);
|
|
167523
|
-
}
|
|
167524
|
-
const idMatches = [...masterContent.matchAll(/sldLayoutId\s+id="(\d+)"/g)];
|
|
167525
|
-
const maxLayoutId = idMatches.reduce((max, m) => Math.max(max, parseInt(m[1], 10)), 2147483648);
|
|
167526
|
-
const newLayoutId = maxLayoutId + 1;
|
|
167527
|
-
const newLayoutIdEntry = ` <p:sldLayoutId id="${newLayoutId}" r:id="${newRId}"/>`;
|
|
167528
|
-
const updatedMaster = masterContent.replace(
|
|
167529
|
-
"</p:sldLayoutIdLst>",
|
|
167530
|
-
`${newLayoutIdEntry}
|
|
167531
|
-
</p:sldLayoutIdLst>`
|
|
167532
|
-
);
|
|
167533
|
-
zip.file(masterPath, updatedMaster);
|
|
167534
|
-
}
|
|
167535
|
-
async function addLayoutContentType(zip, layoutIndex2) {
|
|
167536
|
-
const ctPath = "[Content_Types].xml";
|
|
167537
|
-
const ctContent = await zip.file(ctPath)?.async("string");
|
|
167538
|
-
if (!ctContent) {
|
|
167539
|
-
throw new Error("Content types file not found");
|
|
167540
|
-
}
|
|
167541
|
-
const override = ` <Override PartName="/ppt/slideLayouts/slideLayout${layoutIndex2}.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/>`;
|
|
167542
|
-
const updatedCt = ctContent.replace("</Types>", `${override}
|
|
167543
|
-
</Types>`);
|
|
167544
|
-
zip.file(ctPath, updatedCt);
|
|
167545
|
-
}
|
|
167546
|
-
async function createLayout(handler, data, definition, masterIndex = 1) {
|
|
167547
|
-
const bytes = await handler.save(data.slides);
|
|
167548
|
-
const zip = await openPptxZip(bytes);
|
|
167549
|
-
const existingCount = countExistingLayouts(zip);
|
|
167550
|
-
const newIndex = existingCount + 1;
|
|
167551
|
-
const layoutPath = `ppt/slideLayouts/slideLayout${newIndex}.xml`;
|
|
167552
|
-
zip.file(layoutPath, generateLayoutXml(definition));
|
|
167553
|
-
zip.file(`ppt/slideLayouts/_rels/slideLayout${newIndex}.xml.rels`, layoutRelsXml(masterIndex));
|
|
167554
|
-
await addLayoutToSlideMaster(zip, newIndex, masterIndex);
|
|
167555
|
-
await addLayoutContentType(zip, newIndex);
|
|
167556
|
-
const updatedBuffer = await zip.generateAsync({ type: "arraybuffer" });
|
|
167557
|
-
const newHandler = new exports.PptxHandler();
|
|
167558
|
-
const newData = await newHandler.load(updatedBuffer);
|
|
167559
|
-
return {
|
|
167560
|
-
layoutPath,
|
|
167561
|
-
layoutName: definition.name,
|
|
167562
|
-
handler: newHandler,
|
|
167563
|
-
data: newData
|
|
167564
|
-
};
|
|
167565
|
-
}
|
|
167566
|
-
async function createLayouts(handler, data, definitions, masterIndex = 1) {
|
|
167567
|
-
if (definitions.length === 0) {
|
|
167568
|
-
return { layoutPaths: [], handler, data };
|
|
167569
|
-
}
|
|
167570
|
-
const bytes = await handler.save(data.slides);
|
|
167571
|
-
const zip = await openPptxZip(bytes);
|
|
167572
|
-
const existingCount = countExistingLayouts(zip);
|
|
167573
|
-
const layoutPaths = [];
|
|
167574
|
-
for (let i2 = 0; i2 < definitions.length; i2++) {
|
|
167575
|
-
const def = definitions[i2];
|
|
167576
|
-
const newIndex = existingCount + i2 + 1;
|
|
167577
|
-
const layoutPath = `ppt/slideLayouts/slideLayout${newIndex}.xml`;
|
|
167578
|
-
zip.file(layoutPath, generateLayoutXml(def));
|
|
167579
|
-
zip.file(`ppt/slideLayouts/_rels/slideLayout${newIndex}.xml.rels`, layoutRelsXml(masterIndex));
|
|
167580
|
-
await addLayoutToSlideMaster(zip, newIndex, masterIndex);
|
|
167581
|
-
await addLayoutContentType(zip, newIndex);
|
|
167582
|
-
layoutPaths.push(layoutPath);
|
|
167583
|
-
}
|
|
167584
|
-
const updatedBuffer = await zip.generateAsync({ type: "arraybuffer" });
|
|
167585
|
-
const newHandler = new exports.PptxHandler();
|
|
167586
|
-
const newData = await newHandler.load(updatedBuffer);
|
|
167587
|
-
return { layoutPaths, handler: newHandler, data: newData };
|
|
167588
|
-
}
|
|
167589
|
-
function findLayoutByName(data, name) {
|
|
167590
|
-
const lowerName = name.toLowerCase();
|
|
167591
|
-
const fromOptions = data.layoutOptions?.find((l) => l.name.toLowerCase() === lowerName);
|
|
167592
|
-
if (fromOptions) {
|
|
167593
|
-
return fromOptions;
|
|
167594
|
-
}
|
|
167595
|
-
if (data.slideMasters) {
|
|
167596
|
-
for (const master of data.slideMasters) {
|
|
167597
|
-
const layout = master.layouts?.find((l) => l.name?.toLowerCase() === lowerName);
|
|
167598
|
-
if (layout) {
|
|
167599
|
-
return { path: layout.path, name: layout.name ?? name };
|
|
167600
|
-
}
|
|
167601
|
-
}
|
|
167602
|
-
}
|
|
167603
|
-
return void 0;
|
|
167604
|
-
}
|
|
167605
|
-
function findLayoutByType(data, type) {
|
|
167606
|
-
const fromOptions = data.layoutOptions?.find((l) => l.type === type);
|
|
167607
|
-
if (fromOptions) {
|
|
167608
|
-
return fromOptions;
|
|
167609
|
-
}
|
|
167610
|
-
return void 0;
|
|
167611
|
-
}
|
|
167980
|
+
// pptx/core/builders/sdk/index.ts
|
|
167981
|
+
init_layout_operations();
|
|
167612
167982
|
|
|
167613
167983
|
// pptx/core/builders/sdk/master-layout-crud-layout.ts
|
|
167614
167984
|
init_PptxHandler();
|
|
167985
|
+
init_layout_operations();
|
|
167615
167986
|
|
|
167616
167987
|
// pptx/core/builders/sdk/master-layout-crud-lookup.ts
|
|
167617
167988
|
var NOT_FOUND = { ok: false, reason: "notFound" };
|
|
@@ -167915,6 +168286,7 @@ async function insertLayout(handler, data, masterId, definition) {
|
|
|
167915
168286
|
|
|
167916
168287
|
// pptx/core/builders/sdk/master-layout-crud-master.ts
|
|
167917
168288
|
init_PptxHandler();
|
|
168289
|
+
init_layout_operations();
|
|
167918
168290
|
init_PresentationBuilder();
|
|
167919
168291
|
async function duplicateSlideMaster(handler, data, masterId) {
|
|
167920
168292
|
const source = findMaster(data, masterId);
|