pptx-react-viewer 1.1.2 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +587 -288
- package/dist/index.mjs +587 -288
- package/dist/pptx-viewer.css +1 -1
- package/dist/viewer/index.js +587 -288
- package/dist/viewer/index.mjs +587 -288
- package/node_modules/emf-converter/package.json +2 -2
- package/node_modules/mtx-decompressor/package.json +2 -2
- package/node_modules/pptx-viewer-core/dist/{SvgExporter--H1PDfAY.d.ts → SvgExporter-0TxiiorD.d.ts} +1 -1
- package/node_modules/pptx-viewer-core/dist/{SvgExporter-Dq_2eV_r.d.mts → SvgExporter-BQ4KbRO9.d.mts} +1 -1
- package/node_modules/pptx-viewer-core/dist/cli/index.d.mts +2 -2
- package/node_modules/pptx-viewer-core/dist/cli/index.d.ts +2 -2
- package/node_modules/pptx-viewer-core/dist/cli/index.js +2875 -321
- package/node_modules/pptx-viewer-core/dist/cli/index.mjs +2875 -321
- package/node_modules/pptx-viewer-core/dist/converter/index.d.mts +3 -3
- package/node_modules/pptx-viewer-core/dist/converter/index.d.ts +3 -3
- package/node_modules/pptx-viewer-core/dist/index.d.mts +713 -44
- package/node_modules/pptx-viewer-core/dist/index.d.ts +713 -44
- package/node_modules/pptx-viewer-core/dist/index.js +2958 -390
- package/node_modules/pptx-viewer-core/dist/index.mjs +2949 -390
- package/node_modules/pptx-viewer-core/dist/{presentation-BozkirFp.d.mts → presentation-ArhfImJ5.d.mts} +225 -8
- package/node_modules/pptx-viewer-core/dist/{presentation-BozkirFp.d.ts → presentation-ArhfImJ5.d.ts} +225 -8
- package/node_modules/pptx-viewer-core/dist/{text-operations-B2JbPA5H.d.mts → text-operations-CLj-sJyk.d.mts} +1 -1
- package/node_modules/pptx-viewer-core/dist/{text-operations-zwF6i4eH.d.ts → text-operations-rhJV-A_W.d.ts} +1 -1
- package/node_modules/pptx-viewer-core/package.json +5 -5
- package/package.json +20 -20
|
@@ -4400,12 +4400,25 @@ function svgToCustomGeometryPaths(pathData, width, height) {
|
|
|
4400
4400
|
function pointToXml(pt) {
|
|
4401
4401
|
return { "@_x": String(Math.round(pt.x)), "@_y": String(Math.round(pt.y)) };
|
|
4402
4402
|
}
|
|
4403
|
-
function customGeometryPathsToXml(paths) {
|
|
4403
|
+
function customGeometryPathsToXml(paths, rawData) {
|
|
4404
4404
|
const xmlPaths = paths.map((path2) => {
|
|
4405
4405
|
const pathXml = {
|
|
4406
4406
|
"@_w": String(Math.round(path2.width)),
|
|
4407
4407
|
"@_h": String(Math.round(path2.height))
|
|
4408
4408
|
};
|
|
4409
|
+
if (path2.fillMode) {
|
|
4410
|
+
pathXml["@_fill"] = path2.fillMode;
|
|
4411
|
+
}
|
|
4412
|
+
if (path2.stroke === false) {
|
|
4413
|
+
pathXml["@_stroke"] = "0";
|
|
4414
|
+
} else if (path2.stroke === true) {
|
|
4415
|
+
pathXml["@_stroke"] = "1";
|
|
4416
|
+
}
|
|
4417
|
+
if (path2.extrusionOk === true) {
|
|
4418
|
+
pathXml["@_extrusionOk"] = "1";
|
|
4419
|
+
} else if (path2.extrusionOk === false) {
|
|
4420
|
+
pathXml["@_extrusionOk"] = "0";
|
|
4421
|
+
}
|
|
4409
4422
|
const moveToList = [];
|
|
4410
4423
|
const lnToList = [];
|
|
4411
4424
|
const cubicBezToList = [];
|
|
@@ -4463,12 +4476,12 @@ function customGeometryPathsToXml(paths) {
|
|
|
4463
4476
|
}
|
|
4464
4477
|
return pathXml;
|
|
4465
4478
|
});
|
|
4466
|
-
|
|
4479
|
+
const result = {
|
|
4467
4480
|
"a:avLst": {},
|
|
4468
|
-
"a:gdLst": {},
|
|
4469
|
-
"a:ahLst": {},
|
|
4470
|
-
"a:cxnLst": {},
|
|
4471
|
-
"a:rect": {
|
|
4481
|
+
"a:gdLst": rawData?.gdLstXml ?? {},
|
|
4482
|
+
"a:ahLst": rawData?.ahLstXml ?? {},
|
|
4483
|
+
"a:cxnLst": rawData?.cxnLstXml ?? {},
|
|
4484
|
+
"a:rect": rawData?.rectXml ?? {
|
|
4472
4485
|
"@_l": "l",
|
|
4473
4486
|
"@_t": "t",
|
|
4474
4487
|
"@_r": "r",
|
|
@@ -4478,6 +4491,7 @@ function customGeometryPathsToXml(paths) {
|
|
|
4478
4491
|
"a:path": xmlPaths.length === 1 ? xmlPaths[0] : xmlPaths
|
|
4479
4492
|
}
|
|
4480
4493
|
};
|
|
4494
|
+
return result;
|
|
4481
4495
|
}
|
|
4482
4496
|
|
|
4483
4497
|
// src/core/builders/sdk/ElementFactory.ts
|
|
@@ -5162,7 +5176,11 @@ function isoNow() {
|
|
|
5162
5176
|
return (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d+Z$/, "Z");
|
|
5163
5177
|
}
|
|
5164
5178
|
var STANDARD_LAYOUTS = [
|
|
5165
|
-
|
|
5179
|
+
// `type` is ST_SlideLayoutType per ECMA-376 §19.7.15. The Title Slide
|
|
5180
|
+
// layout uses `title`; `ctrTitle` is a placeholder type (ST_PlaceholderType)
|
|
5181
|
+
// and is not valid here — PowerPoint's OPC loader rejects the package
|
|
5182
|
+
// with ERROR_FILE_CORRUPT (0x80070570) when it sees it.
|
|
5183
|
+
{ name: "Title Slide", type: "title" },
|
|
5166
5184
|
{ name: "Title and Content", type: "obj" },
|
|
5167
5185
|
{ name: "Section Header", type: "secHead" },
|
|
5168
5186
|
{ name: "Two Content", type: "twoObj" },
|
|
@@ -5196,7 +5214,7 @@ ${slideOverrides}
|
|
|
5196
5214
|
<Override PartName="/ppt/viewProps.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml"/>
|
|
5197
5215
|
<Override PartName="/ppt/tableStyles.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml"/>
|
|
5198
5216
|
<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
|
|
5199
|
-
<Override PartName="/docProps/app.xml" ContentType="application/vnd.
|
|
5217
|
+
<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>
|
|
5200
5218
|
</Types>`;
|
|
5201
5219
|
}
|
|
5202
5220
|
function rootRelsXml() {
|
|
@@ -5220,6 +5238,9 @@ ${Array.from(
|
|
|
5220
5238
|
<p:presentation xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
|
|
5221
5239
|
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
|
5222
5240
|
xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"
|
|
5241
|
+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
5242
|
+
xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main"
|
|
5243
|
+
xmlns:p15="http://schemas.microsoft.com/office/powerpoint/2012/main"
|
|
5223
5244
|
saveSubsetFonts="1">
|
|
5224
5245
|
<p:sldMasterIdLst>
|
|
5225
5246
|
<p:sldMasterId id="2147483648" r:id="rId1"/>
|
|
@@ -6522,10 +6543,41 @@ var PptxPresentationSlidesReconciler = class {
|
|
|
6522
6543
|
"@_r:id": slide.rId
|
|
6523
6544
|
};
|
|
6524
6545
|
});
|
|
6525
|
-
|
|
6526
|
-
|
|
6546
|
+
input.presentationData["p:presentation"] = this.insertSlideIdListInOrder(
|
|
6547
|
+
presentation,
|
|
6548
|
+
slideIdList
|
|
6549
|
+
);
|
|
6527
6550
|
}
|
|
6528
6551
|
}
|
|
6552
|
+
/**
|
|
6553
|
+
* Return a new presentation XML object whose `p:sldIdLst` child sits in the
|
|
6554
|
+
* schema-mandated position (after `sldMasterIdLst` / `notesMasterIdLst` /
|
|
6555
|
+
* `handoutMasterIdLst`, before `sldSz`). Non-sldIdLst keys keep their
|
|
6556
|
+
* relative order; attribute keys (`@_...`) stay at the front.
|
|
6557
|
+
*/
|
|
6558
|
+
insertSlideIdListInOrder(presentation, slideIdList) {
|
|
6559
|
+
const before = /* @__PURE__ */ new Set([
|
|
6560
|
+
"p:sldMasterIdLst",
|
|
6561
|
+
"p:notesMasterIdLst",
|
|
6562
|
+
"p:handoutMasterIdLst"
|
|
6563
|
+
]);
|
|
6564
|
+
const rebuilt = {};
|
|
6565
|
+
let inserted = false;
|
|
6566
|
+
for (const key of Object.keys(presentation)) {
|
|
6567
|
+
if (key === "p:sldIdLst") {
|
|
6568
|
+
continue;
|
|
6569
|
+
}
|
|
6570
|
+
if (!inserted && !key.startsWith("@_") && !before.has(key)) {
|
|
6571
|
+
rebuilt["p:sldIdLst"] = slideIdList;
|
|
6572
|
+
inserted = true;
|
|
6573
|
+
}
|
|
6574
|
+
rebuilt[key] = presentation[key];
|
|
6575
|
+
}
|
|
6576
|
+
if (!inserted) {
|
|
6577
|
+
rebuilt["p:sldIdLst"] = slideIdList;
|
|
6578
|
+
}
|
|
6579
|
+
return rebuilt;
|
|
6580
|
+
}
|
|
6529
6581
|
async attachNewSlide(init) {
|
|
6530
6582
|
const sourceSlidePath = init.input.findSourceSlidePath(init.slide.sourceSlideId);
|
|
6531
6583
|
const sourceSlideXml = sourceSlidePath ? init.input.deepCloneXml(init.input.slideMap.get(sourceSlidePath)) : void 0;
|
|
@@ -6610,6 +6662,22 @@ var PptxPresentationSlidesReconciler = class {
|
|
|
6610
6662
|
};
|
|
6611
6663
|
|
|
6612
6664
|
// src/core/core/builders/PptxSlideRelationshipRegistry.ts
|
|
6665
|
+
function isExternalTarget(target) {
|
|
6666
|
+
const normalized = target.trim();
|
|
6667
|
+
if (normalized.length === 0) {
|
|
6668
|
+
return false;
|
|
6669
|
+
}
|
|
6670
|
+
const colonIdx = normalized.indexOf(":");
|
|
6671
|
+
if (colonIdx <= 0) {
|
|
6672
|
+
return false;
|
|
6673
|
+
}
|
|
6674
|
+
const slashIdx = normalized.indexOf("/");
|
|
6675
|
+
if (slashIdx !== -1 && slashIdx < colonIdx) {
|
|
6676
|
+
return false;
|
|
6677
|
+
}
|
|
6678
|
+
const scheme = normalized.slice(0, colonIdx);
|
|
6679
|
+
return /^[A-Za-z][A-Za-z0-9+\-.]*$/.test(scheme);
|
|
6680
|
+
}
|
|
6613
6681
|
var PptxSlideRelationshipRegistry = class {
|
|
6614
6682
|
relationships;
|
|
6615
6683
|
usedRelationshipIds = /* @__PURE__ */ new Set();
|
|
@@ -6680,7 +6748,7 @@ var PptxSlideRelationshipRegistry = class {
|
|
|
6680
6748
|
return existingRelationshipId;
|
|
6681
6749
|
}
|
|
6682
6750
|
const relationshipId = this.nextRelationshipId();
|
|
6683
|
-
const targetMode =
|
|
6751
|
+
const targetMode = isExternalTarget(normalizedTarget) ? "External" : void 0;
|
|
6684
6752
|
this.upsertRelationship(
|
|
6685
6753
|
relationshipId,
|
|
6686
6754
|
this.hyperlinkRelationshipType,
|
|
@@ -6930,6 +6998,82 @@ var PptxSlideNotesPartUpdater = class {
|
|
|
6930
6998
|
}
|
|
6931
6999
|
};
|
|
6932
7000
|
|
|
7001
|
+
// src/core/utils/xml-reorder.ts
|
|
7002
|
+
function reorderObjectKeys(obj, schemaOrder) {
|
|
7003
|
+
const result = {};
|
|
7004
|
+
const consumed = /* @__PURE__ */ new Set();
|
|
7005
|
+
for (const key of schemaOrder) {
|
|
7006
|
+
if (Object.hasOwn(obj, key)) {
|
|
7007
|
+
const value = obj[key];
|
|
7008
|
+
if (value !== void 0) {
|
|
7009
|
+
result[key] = value;
|
|
7010
|
+
}
|
|
7011
|
+
consumed.add(key);
|
|
7012
|
+
}
|
|
7013
|
+
}
|
|
7014
|
+
for (const key of Object.keys(obj)) {
|
|
7015
|
+
if (consumed.has(key)) {
|
|
7016
|
+
continue;
|
|
7017
|
+
}
|
|
7018
|
+
const value = obj[key];
|
|
7019
|
+
if (value !== void 0) {
|
|
7020
|
+
result[key] = value;
|
|
7021
|
+
}
|
|
7022
|
+
}
|
|
7023
|
+
return result;
|
|
7024
|
+
}
|
|
7025
|
+
var EFFECT_LST_ORDER = [
|
|
7026
|
+
"a:blur",
|
|
7027
|
+
"a:fillOverlay",
|
|
7028
|
+
"a:glow",
|
|
7029
|
+
"a:innerShdw",
|
|
7030
|
+
"a:outerShdw",
|
|
7031
|
+
"a:prstShdw",
|
|
7032
|
+
"a:reflection",
|
|
7033
|
+
"a:softEdge"
|
|
7034
|
+
];
|
|
7035
|
+
var SP_PR_ORDER = [
|
|
7036
|
+
"a:xfrm",
|
|
7037
|
+
"a:custGeom",
|
|
7038
|
+
"a:prstGeom",
|
|
7039
|
+
"a:noFill",
|
|
7040
|
+
"a:solidFill",
|
|
7041
|
+
"a:gradFill",
|
|
7042
|
+
"a:blipFill",
|
|
7043
|
+
"a:pattFill",
|
|
7044
|
+
"a:grpFill",
|
|
7045
|
+
"a:ln",
|
|
7046
|
+
"a:effectLst",
|
|
7047
|
+
"a:effectDag",
|
|
7048
|
+
"a:scene3d",
|
|
7049
|
+
"a:sp3d",
|
|
7050
|
+
"a:extLst"
|
|
7051
|
+
];
|
|
7052
|
+
var TC_PR_BORDERS_ORDER = [
|
|
7053
|
+
"a:lnL",
|
|
7054
|
+
"a:lnR",
|
|
7055
|
+
"a:lnT",
|
|
7056
|
+
"a:lnB",
|
|
7057
|
+
"a:lnTlToBr",
|
|
7058
|
+
"a:lnBlToTr",
|
|
7059
|
+
"a:cell3D",
|
|
7060
|
+
"a:noFill",
|
|
7061
|
+
"a:solidFill",
|
|
7062
|
+
"a:gradFill",
|
|
7063
|
+
"a:blipFill",
|
|
7064
|
+
"a:pattFill",
|
|
7065
|
+
"a:grpFill",
|
|
7066
|
+
"a:headers",
|
|
7067
|
+
"a:extLst"
|
|
7068
|
+
];
|
|
7069
|
+
var BLIP_FILL_ORDER = ["a:blip", "a:srcRect", "a:tile", "a:stretch"];
|
|
7070
|
+
var SHAPE_STYLE_ORDER = [
|
|
7071
|
+
"a:lnRef",
|
|
7072
|
+
"a:fillRef",
|
|
7073
|
+
"a:effectRef",
|
|
7074
|
+
"a:fontRef"
|
|
7075
|
+
];
|
|
7076
|
+
|
|
6933
7077
|
// src/core/core/builders/PptxSlideBackgroundBuilder.ts
|
|
6934
7078
|
var PptxSlideBackgroundBuilder = class {
|
|
6935
7079
|
applyBackground(init) {
|
|
@@ -6965,10 +7109,13 @@ var PptxSlideBackgroundBuilder = class {
|
|
|
6965
7109
|
init.slideImageRelationshipType,
|
|
6966
7110
|
relativeBackgroundImagePath
|
|
6967
7111
|
);
|
|
6968
|
-
backgroundProperties["a:blipFill"] =
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
|
|
7112
|
+
backgroundProperties["a:blipFill"] = reorderObjectKeys(
|
|
7113
|
+
{
|
|
7114
|
+
"a:blip": { "@_r:embed": backgroundRelationshipId },
|
|
7115
|
+
"a:stretch": { "a:fillRect": {} }
|
|
7116
|
+
},
|
|
7117
|
+
BLIP_FILL_ORDER
|
|
7118
|
+
);
|
|
6972
7119
|
}
|
|
6973
7120
|
} else if (hasBackgroundColor && init.slide.backgroundColor) {
|
|
6974
7121
|
backgroundProperties["a:solidFill"] = {
|
|
@@ -7712,6 +7859,45 @@ var PptxGradientStyleCodec = class {
|
|
|
7712
7859
|
b: Number.isFinite(b) ? this.context.clampUnitInterval(b / 1e5) : 0
|
|
7713
7860
|
};
|
|
7714
7861
|
}
|
|
7862
|
+
extractGradientFlip(gradFill) {
|
|
7863
|
+
const flipRaw = String(gradFill["@_flip"] || "").trim().toLowerCase();
|
|
7864
|
+
if (flipRaw === "x" || flipRaw === "y" || flipRaw === "xy" || flipRaw === "none") {
|
|
7865
|
+
return flipRaw;
|
|
7866
|
+
}
|
|
7867
|
+
return void 0;
|
|
7868
|
+
}
|
|
7869
|
+
extractGradientRotWithShape(gradFill) {
|
|
7870
|
+
const rot = gradFill["@_rotWithShape"];
|
|
7871
|
+
if (rot === void 0 || rot === null) {
|
|
7872
|
+
return void 0;
|
|
7873
|
+
}
|
|
7874
|
+
const token = String(rot).trim().toLowerCase();
|
|
7875
|
+
if (token === "1" || token === "true") {
|
|
7876
|
+
return true;
|
|
7877
|
+
}
|
|
7878
|
+
if (token === "0" || token === "false") {
|
|
7879
|
+
return false;
|
|
7880
|
+
}
|
|
7881
|
+
return void 0;
|
|
7882
|
+
}
|
|
7883
|
+
extractGradientScaled(gradFill) {
|
|
7884
|
+
const lin = gradFill["a:lin"];
|
|
7885
|
+
if (!lin) {
|
|
7886
|
+
return void 0;
|
|
7887
|
+
}
|
|
7888
|
+
const scaled = lin["@_scaled"];
|
|
7889
|
+
if (scaled === void 0 || scaled === null) {
|
|
7890
|
+
return void 0;
|
|
7891
|
+
}
|
|
7892
|
+
const token = String(scaled).trim().toLowerCase();
|
|
7893
|
+
if (token === "1" || token === "true") {
|
|
7894
|
+
return true;
|
|
7895
|
+
}
|
|
7896
|
+
if (token === "0" || token === "false") {
|
|
7897
|
+
return false;
|
|
7898
|
+
}
|
|
7899
|
+
return void 0;
|
|
7900
|
+
}
|
|
7715
7901
|
extractGradientAngle(gradFill) {
|
|
7716
7902
|
const angleRaw = Number.parseInt(
|
|
7717
7903
|
String(gradFill["a:lin"]?.["@_ang"] || ""),
|
|
@@ -7798,11 +7984,14 @@ var PptxGradientStyleCodec = class {
|
|
|
7798
7984
|
return void 0;
|
|
7799
7985
|
}
|
|
7800
7986
|
const gradientType = shapeStyle.fillGradientType || "linear";
|
|
7801
|
-
const gradientXml = {
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
|
|
7987
|
+
const gradientXml = {};
|
|
7988
|
+
if (shapeStyle.fillGradientFlip && shapeStyle.fillGradientFlip !== "none") {
|
|
7989
|
+
gradientXml["@_flip"] = shapeStyle.fillGradientFlip;
|
|
7990
|
+
}
|
|
7991
|
+
if (shapeStyle.fillGradientRotWithShape !== void 0) {
|
|
7992
|
+
gradientXml["@_rotWithShape"] = shapeStyle.fillGradientRotWithShape ? "1" : "0";
|
|
7993
|
+
}
|
|
7994
|
+
gradientXml["a:gsLst"] = { "a:gs": stops };
|
|
7806
7995
|
if (gradientType === "radial") {
|
|
7807
7996
|
const pathType = shapeStyle.fillGradientPathType || "circle";
|
|
7808
7997
|
const pathXml = {
|
|
@@ -7832,10 +8021,15 @@ var PptxGradientStyleCodec = class {
|
|
|
7832
8021
|
gradientXml["a:path"] = pathXml;
|
|
7833
8022
|
} else {
|
|
7834
8023
|
const normalizedAngle = typeof shapeStyle.fillGradientAngle === "number" && Number.isFinite(shapeStyle.fillGradientAngle) ? shapeStyle.fillGradientAngle : 90;
|
|
7835
|
-
|
|
7836
|
-
"@_ang": String(Math.round(normalizedAngle * 6e4))
|
|
7837
|
-
"@_scaled": "1"
|
|
8024
|
+
const linNode = {
|
|
8025
|
+
"@_ang": String(Math.round(normalizedAngle * 6e4))
|
|
7838
8026
|
};
|
|
8027
|
+
if (shapeStyle.fillGradientScaled !== void 0) {
|
|
8028
|
+
linNode["@_scaled"] = shapeStyle.fillGradientScaled ? "1" : "0";
|
|
8029
|
+
} else {
|
|
8030
|
+
linNode["@_scaled"] = "1";
|
|
8031
|
+
}
|
|
8032
|
+
gradientXml["a:lin"] = linNode;
|
|
7839
8033
|
}
|
|
7840
8034
|
return gradientXml;
|
|
7841
8035
|
}
|
|
@@ -8232,6 +8426,30 @@ var PRESET_SHADOW_OPACITY_MAP = {
|
|
|
8232
8426
|
};
|
|
8233
8427
|
|
|
8234
8428
|
// src/core/core/builders/PptxShapeEffectStyleExtractor.ts
|
|
8429
|
+
var VALID_ALIGNMENTS = /* @__PURE__ */ new Set(["tl", "t", "tr", "l", "ctr", "r", "bl", "b", "br"]);
|
|
8430
|
+
function parseIntAttr(value) {
|
|
8431
|
+
if (value === void 0 || value === null || value === "") {
|
|
8432
|
+
return void 0;
|
|
8433
|
+
}
|
|
8434
|
+
const parsed = Number.parseInt(String(value), 10);
|
|
8435
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
8436
|
+
}
|
|
8437
|
+
function parseAlignmentAttr(value) {
|
|
8438
|
+
const v = String(value ?? "").trim();
|
|
8439
|
+
return VALID_ALIGNMENTS.has(v) ? v : void 0;
|
|
8440
|
+
}
|
|
8441
|
+
function parseBoolAttr(value) {
|
|
8442
|
+
if (typeof value === "boolean") {
|
|
8443
|
+
return value;
|
|
8444
|
+
}
|
|
8445
|
+
if (value === "1" || value === "true") {
|
|
8446
|
+
return true;
|
|
8447
|
+
}
|
|
8448
|
+
if (value === "0" || value === "false") {
|
|
8449
|
+
return false;
|
|
8450
|
+
}
|
|
8451
|
+
return void 0;
|
|
8452
|
+
}
|
|
8235
8453
|
var PptxShapeEffectStyleExtractor = class {
|
|
8236
8454
|
context;
|
|
8237
8455
|
constructor(context) {
|
|
@@ -8255,7 +8473,12 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8255
8473
|
const shadowOffsetX = distance !== void 0 ? Math.round(Math.cos(directionRadians) * distance * 100) / 100 : void 0;
|
|
8256
8474
|
const shadowOffsetY = distance !== void 0 ? Math.round(Math.sin(directionRadians) * distance * 100) / 100 : void 0;
|
|
8257
8475
|
const rotateWithShape = outerShadow["@_rotWithShape"];
|
|
8258
|
-
const shadowRotateWithShape = typeof rotateWithShape === "boolean" ? rotateWithShape : rotateWithShape === "1" || rotateWithShape === "true" ? true : void 0;
|
|
8476
|
+
const shadowRotateWithShape = typeof rotateWithShape === "boolean" ? rotateWithShape : rotateWithShape === "1" || rotateWithShape === "true" ? true : rotateWithShape === "0" || rotateWithShape === "false" ? false : void 0;
|
|
8477
|
+
const shadowScaleX = parseIntAttr(outerShadow["@_sx"]);
|
|
8478
|
+
const shadowScaleY = parseIntAttr(outerShadow["@_sy"]);
|
|
8479
|
+
const shadowSkewX = parseIntAttr(outerShadow["@_kx"]);
|
|
8480
|
+
const shadowSkewY = parseIntAttr(outerShadow["@_ky"]);
|
|
8481
|
+
const shadowAlignment = parseAlignmentAttr(outerShadow["@_algn"]);
|
|
8259
8482
|
return {
|
|
8260
8483
|
shadowColor,
|
|
8261
8484
|
shadowOpacity,
|
|
@@ -8264,7 +8487,12 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8264
8487
|
shadowOffsetY,
|
|
8265
8488
|
shadowAngle: directionDegrees,
|
|
8266
8489
|
shadowDistance: distance,
|
|
8267
|
-
shadowRotateWithShape
|
|
8490
|
+
shadowRotateWithShape,
|
|
8491
|
+
shadowScaleX,
|
|
8492
|
+
shadowScaleY,
|
|
8493
|
+
shadowSkewX,
|
|
8494
|
+
shadowSkewY,
|
|
8495
|
+
shadowAlignment
|
|
8268
8496
|
};
|
|
8269
8497
|
}
|
|
8270
8498
|
extractPresetShadowStyle(effectLstParent) {
|
|
@@ -8310,12 +8538,14 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8310
8538
|
const directionRadians = directionDegrees * Math.PI / 180;
|
|
8311
8539
|
const innerShadowOffsetX = distance !== void 0 ? Math.round(Math.cos(directionRadians) * distance * 100) / 100 : void 0;
|
|
8312
8540
|
const innerShadowOffsetY = distance !== void 0 ? Math.round(Math.sin(directionRadians) * distance * 100) / 100 : void 0;
|
|
8541
|
+
const innerShadowRotateWithShape = parseBoolAttr(innerShadow["@_rotWithShape"]);
|
|
8313
8542
|
return {
|
|
8314
8543
|
innerShadowColor,
|
|
8315
8544
|
innerShadowOpacity,
|
|
8316
8545
|
innerShadowBlur,
|
|
8317
8546
|
innerShadowOffsetX,
|
|
8318
|
-
innerShadowOffsetY
|
|
8547
|
+
innerShadowOffsetY,
|
|
8548
|
+
innerShadowRotateWithShape
|
|
8319
8549
|
};
|
|
8320
8550
|
}
|
|
8321
8551
|
extractGlowStyle(shapeProps) {
|
|
@@ -8364,6 +8594,16 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8364
8594
|
const reflectionRotation = Number.isFinite(rotationRaw) ? rotationRaw / 6e4 : void 0;
|
|
8365
8595
|
const distanceRaw = Number.parseInt(String(reflectionNode["@_dist"] || ""), 10);
|
|
8366
8596
|
const reflectionDistance = Number.isFinite(distanceRaw) && distanceRaw >= 0 ? distanceRaw / this.context.emuPerPx : void 0;
|
|
8597
|
+
const fadeDirRaw = parseIntAttr(reflectionNode["@_fadeDir"]);
|
|
8598
|
+
const reflectionFadeDirection = fadeDirRaw !== void 0 ? fadeDirRaw / 6e4 : void 0;
|
|
8599
|
+
const reflectionScaleX = parseIntAttr(reflectionNode["@_sx"]);
|
|
8600
|
+
const reflectionScaleY = parseIntAttr(reflectionNode["@_sy"]);
|
|
8601
|
+
const reflectionSkewX = parseIntAttr(reflectionNode["@_kx"]);
|
|
8602
|
+
const reflectionSkewY = parseIntAttr(reflectionNode["@_ky"]);
|
|
8603
|
+
const reflectionAlignment = parseAlignmentAttr(reflectionNode["@_algn"]);
|
|
8604
|
+
const reflectionRotateWithShape = parseBoolAttr(reflectionNode["@_rotWithShape"]);
|
|
8605
|
+
const stPosRaw = parseIntAttr(reflectionNode["@_stPos"]);
|
|
8606
|
+
const reflectionStartPosition = stPosRaw !== void 0 ? stPosRaw / 1e5 : void 0;
|
|
8367
8607
|
return {
|
|
8368
8608
|
reflectionBlurRadius,
|
|
8369
8609
|
reflectionStartOpacity,
|
|
@@ -8371,7 +8611,15 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8371
8611
|
reflectionEndPosition,
|
|
8372
8612
|
reflectionDirection,
|
|
8373
8613
|
reflectionRotation,
|
|
8374
|
-
reflectionDistance
|
|
8614
|
+
reflectionDistance,
|
|
8615
|
+
reflectionFadeDirection,
|
|
8616
|
+
reflectionScaleX,
|
|
8617
|
+
reflectionScaleY,
|
|
8618
|
+
reflectionSkewX,
|
|
8619
|
+
reflectionSkewY,
|
|
8620
|
+
reflectionAlignment,
|
|
8621
|
+
reflectionRotateWithShape,
|
|
8622
|
+
reflectionStartPosition
|
|
8375
8623
|
};
|
|
8376
8624
|
}
|
|
8377
8625
|
extractBlurStyle(shapeProps) {
|
|
@@ -8423,11 +8671,56 @@ var PptxShapeEffectXmlBuilder = class {
|
|
|
8423
8671
|
}
|
|
8424
8672
|
}
|
|
8425
8673
|
};
|
|
8674
|
+
if (typeof shapeStyle.shadowScaleX === "number") {
|
|
8675
|
+
xmlObj["@_sx"] = String(Math.round(shapeStyle.shadowScaleX));
|
|
8676
|
+
}
|
|
8677
|
+
if (typeof shapeStyle.shadowScaleY === "number") {
|
|
8678
|
+
xmlObj["@_sy"] = String(Math.round(shapeStyle.shadowScaleY));
|
|
8679
|
+
}
|
|
8680
|
+
if (typeof shapeStyle.shadowSkewX === "number") {
|
|
8681
|
+
xmlObj["@_kx"] = String(Math.round(shapeStyle.shadowSkewX));
|
|
8682
|
+
}
|
|
8683
|
+
if (typeof shapeStyle.shadowSkewY === "number") {
|
|
8684
|
+
xmlObj["@_ky"] = String(Math.round(shapeStyle.shadowSkewY));
|
|
8685
|
+
}
|
|
8686
|
+
if (shapeStyle.shadowAlignment) {
|
|
8687
|
+
xmlObj["@_algn"] = shapeStyle.shadowAlignment;
|
|
8688
|
+
}
|
|
8426
8689
|
if (typeof shapeStyle.shadowRotateWithShape === "boolean") {
|
|
8427
8690
|
xmlObj["@_rotWithShape"] = shapeStyle.shadowRotateWithShape ? "1" : "0";
|
|
8428
8691
|
}
|
|
8429
8692
|
return xmlObj;
|
|
8430
8693
|
}
|
|
8694
|
+
buildPresetShadowXml(shapeStyle) {
|
|
8695
|
+
const preset = shapeStyle.presetShadowName;
|
|
8696
|
+
if (!preset || preset.length === 0) {
|
|
8697
|
+
return void 0;
|
|
8698
|
+
}
|
|
8699
|
+
const shadowColor = String(shapeStyle.shadowColor || "#000000").trim();
|
|
8700
|
+
const shadowOpacity = typeof shapeStyle.shadowOpacity === "number" && Number.isFinite(shapeStyle.shadowOpacity) ? this.context.clampUnitInterval(shapeStyle.shadowOpacity) : 0.5;
|
|
8701
|
+
let distance;
|
|
8702
|
+
let directionDegrees;
|
|
8703
|
+
if (typeof shapeStyle.shadowAngle === "number" && typeof shapeStyle.shadowDistance === "number") {
|
|
8704
|
+
directionDegrees = shapeStyle.shadowAngle;
|
|
8705
|
+
distance = shapeStyle.shadowDistance;
|
|
8706
|
+
} else {
|
|
8707
|
+
const ox = typeof shapeStyle.shadowOffsetX === "number" ? shapeStyle.shadowOffsetX : 0;
|
|
8708
|
+
const oy = typeof shapeStyle.shadowOffsetY === "number" ? shapeStyle.shadowOffsetY : 0;
|
|
8709
|
+
distance = Math.sqrt(ox * ox + oy * oy);
|
|
8710
|
+
directionDegrees = (Math.atan2(oy, ox) * 180 / Math.PI + 360) % 360;
|
|
8711
|
+
}
|
|
8712
|
+
return {
|
|
8713
|
+
"@_prst": preset,
|
|
8714
|
+
"@_dist": String(Math.round(distance * this.context.emuPerPx)),
|
|
8715
|
+
"@_dir": String(Math.round(directionDegrees * 6e4)),
|
|
8716
|
+
"a:srgbClr": {
|
|
8717
|
+
"@_val": shadowColor.replace("#", ""),
|
|
8718
|
+
"a:alpha": {
|
|
8719
|
+
"@_val": String(Math.round(shadowOpacity * 1e5))
|
|
8720
|
+
}
|
|
8721
|
+
}
|
|
8722
|
+
};
|
|
8723
|
+
}
|
|
8431
8724
|
buildInnerShadowXml(shapeStyle) {
|
|
8432
8725
|
const innerColor = String(shapeStyle.innerShadowColor || "").trim();
|
|
8433
8726
|
if (innerColor.length === 0 || innerColor === "transparent") {
|
|
@@ -8439,7 +8732,7 @@ var PptxShapeEffectXmlBuilder = class {
|
|
|
8439
8732
|
const opacity = typeof shapeStyle.innerShadowOpacity === "number" && Number.isFinite(shapeStyle.innerShadowOpacity) ? this.context.clampUnitInterval(shapeStyle.innerShadowOpacity) : 0.5;
|
|
8440
8733
|
const distance = Math.sqrt(offsetX * offsetX + offsetY * offsetY);
|
|
8441
8734
|
const directionDegrees = (Math.atan2(offsetY, offsetX) * 180 / Math.PI + 360) % 360;
|
|
8442
|
-
|
|
8735
|
+
const xmlObj = {
|
|
8443
8736
|
"@_blurRad": String(Math.round(blurValue * this.context.emuPerPx)),
|
|
8444
8737
|
"@_dist": String(Math.round(distance * this.context.emuPerPx)),
|
|
8445
8738
|
"@_dir": String(Math.round(directionDegrees * 6e4)),
|
|
@@ -8450,6 +8743,10 @@ var PptxShapeEffectXmlBuilder = class {
|
|
|
8450
8743
|
}
|
|
8451
8744
|
}
|
|
8452
8745
|
};
|
|
8746
|
+
if (typeof shapeStyle.innerShadowRotateWithShape === "boolean") {
|
|
8747
|
+
xmlObj["@_rotWithShape"] = shapeStyle.innerShadowRotateWithShape ? "1" : "0";
|
|
8748
|
+
}
|
|
8749
|
+
return xmlObj;
|
|
8453
8750
|
}
|
|
8454
8751
|
buildGlowXml(shapeStyle) {
|
|
8455
8752
|
const glowColor = String(shapeStyle.glowColor || "").trim();
|
|
@@ -8511,6 +8808,30 @@ var PptxShapeEffectXmlBuilder = class {
|
|
|
8511
8808
|
Math.round(shapeStyle.reflectionDistance * this.context.emuPerPx)
|
|
8512
8809
|
);
|
|
8513
8810
|
}
|
|
8811
|
+
if (typeof shapeStyle.reflectionFadeDirection === "number") {
|
|
8812
|
+
reflectionXml["@_fadeDir"] = String(Math.round(shapeStyle.reflectionFadeDirection * 6e4));
|
|
8813
|
+
}
|
|
8814
|
+
if (typeof shapeStyle.reflectionScaleX === "number") {
|
|
8815
|
+
reflectionXml["@_sx"] = String(Math.round(shapeStyle.reflectionScaleX));
|
|
8816
|
+
}
|
|
8817
|
+
if (typeof shapeStyle.reflectionScaleY === "number") {
|
|
8818
|
+
reflectionXml["@_sy"] = String(Math.round(shapeStyle.reflectionScaleY));
|
|
8819
|
+
}
|
|
8820
|
+
if (typeof shapeStyle.reflectionSkewX === "number") {
|
|
8821
|
+
reflectionXml["@_kx"] = String(Math.round(shapeStyle.reflectionSkewX));
|
|
8822
|
+
}
|
|
8823
|
+
if (typeof shapeStyle.reflectionSkewY === "number") {
|
|
8824
|
+
reflectionXml["@_ky"] = String(Math.round(shapeStyle.reflectionSkewY));
|
|
8825
|
+
}
|
|
8826
|
+
if (shapeStyle.reflectionAlignment) {
|
|
8827
|
+
reflectionXml["@_algn"] = shapeStyle.reflectionAlignment;
|
|
8828
|
+
}
|
|
8829
|
+
if (typeof shapeStyle.reflectionRotateWithShape === "boolean") {
|
|
8830
|
+
reflectionXml["@_rotWithShape"] = shapeStyle.reflectionRotateWithShape ? "1" : "0";
|
|
8831
|
+
}
|
|
8832
|
+
if (typeof shapeStyle.reflectionStartPosition === "number") {
|
|
8833
|
+
reflectionXml["@_stPos"] = String(Math.round(shapeStyle.reflectionStartPosition * 1e5));
|
|
8834
|
+
}
|
|
8514
8835
|
return reflectionXml;
|
|
8515
8836
|
}
|
|
8516
8837
|
buildBlurXml(shapeStyle) {
|
|
@@ -8618,6 +8939,9 @@ var PptxShapeEffectXmlCodec = class {
|
|
|
8618
8939
|
buildOuterShadowXml(shapeStyle) {
|
|
8619
8940
|
return this.builder.buildOuterShadowXml(shapeStyle);
|
|
8620
8941
|
}
|
|
8942
|
+
buildPresetShadowXml(shapeStyle) {
|
|
8943
|
+
return this.builder.buildPresetShadowXml(shapeStyle);
|
|
8944
|
+
}
|
|
8621
8945
|
buildInnerShadowXml(shapeStyle) {
|
|
8622
8946
|
return this.builder.buildInnerShadowXml(shapeStyle);
|
|
8623
8947
|
}
|
|
@@ -8778,6 +9102,9 @@ var PptxColorStyleCodec = class {
|
|
|
8778
9102
|
buildOuterShadowXml(shapeStyle) {
|
|
8779
9103
|
return this.shapeEffectXmlCodec.buildOuterShadowXml(shapeStyle);
|
|
8780
9104
|
}
|
|
9105
|
+
buildPresetShadowXml(shapeStyle) {
|
|
9106
|
+
return this.shapeEffectXmlCodec.buildPresetShadowXml(shapeStyle);
|
|
9107
|
+
}
|
|
8781
9108
|
buildInnerShadowXml(shapeStyle) {
|
|
8782
9109
|
return this.shapeEffectXmlCodec.buildInnerShadowXml(shapeStyle);
|
|
8783
9110
|
}
|
|
@@ -8799,6 +9126,15 @@ var PptxColorStyleCodec = class {
|
|
|
8799
9126
|
extractGradientFillColor(gradFill) {
|
|
8800
9127
|
return this.gradientStyleCodec.extractGradientFillColor(gradFill);
|
|
8801
9128
|
}
|
|
9129
|
+
extractGradientFlip(gradFill) {
|
|
9130
|
+
return this.gradientStyleCodec.extractGradientFlip(gradFill);
|
|
9131
|
+
}
|
|
9132
|
+
extractGradientRotWithShape(gradFill) {
|
|
9133
|
+
return this.gradientStyleCodec.extractGradientRotWithShape(gradFill);
|
|
9134
|
+
}
|
|
9135
|
+
extractGradientScaled(gradFill) {
|
|
9136
|
+
return this.gradientStyleCodec.extractGradientScaled(gradFill);
|
|
9137
|
+
}
|
|
8802
9138
|
extractGradientPathType(gradFill) {
|
|
8803
9139
|
return this.gradientStyleCodec.extractGradientPathType(gradFill);
|
|
8804
9140
|
}
|
|
@@ -8810,6 +9146,61 @@ var PptxColorStyleCodec = class {
|
|
|
8810
9146
|
}
|
|
8811
9147
|
};
|
|
8812
9148
|
|
|
9149
|
+
// src/core/utils/color-xml-preservation.ts
|
|
9150
|
+
var COLOR_CHOICE_KEYS = [
|
|
9151
|
+
"a:srgbClr",
|
|
9152
|
+
"a:schemeClr",
|
|
9153
|
+
"a:sysClr",
|
|
9154
|
+
"a:prstClr",
|
|
9155
|
+
"a:scrgbClr",
|
|
9156
|
+
"a:hslClr"
|
|
9157
|
+
];
|
|
9158
|
+
function extractColorChoiceXml(parent) {
|
|
9159
|
+
if (!parent) {
|
|
9160
|
+
return void 0;
|
|
9161
|
+
}
|
|
9162
|
+
for (const key of COLOR_CHOICE_KEYS) {
|
|
9163
|
+
if (parent[key] !== void 0) {
|
|
9164
|
+
return { [key]: parent[key] };
|
|
9165
|
+
}
|
|
9166
|
+
}
|
|
9167
|
+
return void 0;
|
|
9168
|
+
}
|
|
9169
|
+
function normalizeHex(value) {
|
|
9170
|
+
const raw = String(value ?? "").trim();
|
|
9171
|
+
if (raw.length === 0) {
|
|
9172
|
+
return "";
|
|
9173
|
+
}
|
|
9174
|
+
const hex = raw.replace(/^#/, "");
|
|
9175
|
+
if (/^[0-9a-fA-F]{6}$/.test(hex)) {
|
|
9176
|
+
return hex.toUpperCase();
|
|
9177
|
+
}
|
|
9178
|
+
return raw.toLowerCase();
|
|
9179
|
+
}
|
|
9180
|
+
function colorsEqual(left, right) {
|
|
9181
|
+
if (left === void 0 || right === void 0) {
|
|
9182
|
+
return false;
|
|
9183
|
+
}
|
|
9184
|
+
return normalizeHex(left) === normalizeHex(right);
|
|
9185
|
+
}
|
|
9186
|
+
function buildSrgbColorChoice(hex, opacity) {
|
|
9187
|
+
const normalized = String(hex || "").replace(/^#/, "");
|
|
9188
|
+
const srgb = { "@_val": normalized };
|
|
9189
|
+
if (typeof opacity === "number" && Number.isFinite(opacity) && opacity >= 0 && opacity < 1) {
|
|
9190
|
+
const alphaPct = Math.round(Math.max(0, Math.min(1, opacity)) * 1e5);
|
|
9191
|
+
srgb["a:alpha"] = { "@_val": String(alphaPct) };
|
|
9192
|
+
}
|
|
9193
|
+
return { "a:srgbClr": srgb };
|
|
9194
|
+
}
|
|
9195
|
+
function serializeColorChoice(originalColorXml, currentResolvedHex, fallbackHex, opacity, options = {}) {
|
|
9196
|
+
if (originalColorXml && colorsEqual(currentResolvedHex, fallbackHex)) {
|
|
9197
|
+
if (options.preserveAlphaFromOriginal !== false) {
|
|
9198
|
+
return originalColorXml;
|
|
9199
|
+
}
|
|
9200
|
+
}
|
|
9201
|
+
return buildSrgbColorChoice(fallbackHex, opacity);
|
|
9202
|
+
}
|
|
9203
|
+
|
|
8813
9204
|
// src/core/core/builders/shape-style-3d-helpers.ts
|
|
8814
9205
|
function applyScene3dStyle(shapeProps, style) {
|
|
8815
9206
|
const scene3dNode = shapeProps["a:scene3d"];
|
|
@@ -8895,6 +9286,10 @@ function applyStrokeColor(lineNode, style, context) {
|
|
|
8895
9286
|
const lineFill = lineNode["a:solidFill"];
|
|
8896
9287
|
style.strokeColor = context.parseColor(lineFill);
|
|
8897
9288
|
style.strokeOpacity = context.extractColorOpacity(lineFill);
|
|
9289
|
+
const strokeColorXml = extractColorChoiceXml(lineFill);
|
|
9290
|
+
if (strokeColorXml) {
|
|
9291
|
+
style.strokeColorXml = strokeColorXml;
|
|
9292
|
+
}
|
|
8898
9293
|
} else if (lineNode["a:gradFill"]) {
|
|
8899
9294
|
style.strokeColor = context.extractGradientFillColor(lineNode["a:gradFill"]);
|
|
8900
9295
|
style.strokeOpacity = context.extractGradientOpacity(lineNode["a:gradFill"]);
|
|
@@ -8962,6 +9357,14 @@ function applyJoinCapCompound(lineNode, style) {
|
|
|
8962
9357
|
style.lineJoin = "bevel";
|
|
8963
9358
|
} else if ("a:miter" in lineNode) {
|
|
8964
9359
|
style.lineJoin = "miter";
|
|
9360
|
+
const miterNode = lineNode["a:miter"];
|
|
9361
|
+
const limRaw = miterNode?.["@_lim"];
|
|
9362
|
+
if (limRaw !== void 0 && limRaw !== "") {
|
|
9363
|
+
const parsed = parseInt(String(limRaw), 10);
|
|
9364
|
+
if (Number.isFinite(parsed)) {
|
|
9365
|
+
style.miterLimit = parsed;
|
|
9366
|
+
}
|
|
9367
|
+
}
|
|
8965
9368
|
}
|
|
8966
9369
|
const capValue = String(lineNode["@_cap"] || "").trim().toLowerCase();
|
|
8967
9370
|
if (capValue === "rnd" || capValue === "sq" || capValue === "flat") {
|
|
@@ -9018,6 +9421,10 @@ var PptxShapeStyleExtractor = class {
|
|
|
9018
9421
|
style.fillMode = "solid";
|
|
9019
9422
|
style.fillColor = this.context.parseColor(solidFill);
|
|
9020
9423
|
style.fillOpacity = this.context.extractColorOpacity(solidFill);
|
|
9424
|
+
const solidFillColorXml = extractColorChoiceXml(solidFill);
|
|
9425
|
+
if (solidFillColorXml) {
|
|
9426
|
+
style.fillColorXml = solidFillColorXml;
|
|
9427
|
+
}
|
|
9021
9428
|
} else if (gradFill) {
|
|
9022
9429
|
style.fillMode = "gradient";
|
|
9023
9430
|
style.fillColor = this.context.extractGradientFillColor(gradFill);
|
|
@@ -9029,6 +9436,18 @@ var PptxShapeStyleExtractor = class {
|
|
|
9029
9436
|
style.fillGradientPathType = this.context.extractGradientPathType(gradFill);
|
|
9030
9437
|
style.fillGradientFocalPoint = this.context.extractGradientFocalPoint(gradFill);
|
|
9031
9438
|
style.fillGradientFillToRect = this.context.extractGradientFillToRect(gradFill);
|
|
9439
|
+
const gradFlip = this.context.extractGradientFlip(gradFill);
|
|
9440
|
+
if (gradFlip) {
|
|
9441
|
+
style.fillGradientFlip = gradFlip;
|
|
9442
|
+
}
|
|
9443
|
+
const gradRot = this.context.extractGradientRotWithShape(gradFill);
|
|
9444
|
+
if (gradRot !== void 0) {
|
|
9445
|
+
style.fillGradientRotWithShape = gradRot;
|
|
9446
|
+
}
|
|
9447
|
+
const gradScaled = this.context.extractGradientScaled(gradFill);
|
|
9448
|
+
if (gradScaled !== void 0) {
|
|
9449
|
+
style.fillGradientScaled = gradScaled;
|
|
9450
|
+
}
|
|
9032
9451
|
} else if (pattFill) {
|
|
9033
9452
|
style.fillMode = "pattern";
|
|
9034
9453
|
style.fillColor = this.context.parseColor(pattFill["a:fgClr"]) || this.context.parseColor(pattFill["a:bgClr"]);
|
|
@@ -9110,10 +9529,45 @@ var PptxShapeStyleExtractor = class {
|
|
|
9110
9529
|
if (styleNode?.["a:effectRef"]) {
|
|
9111
9530
|
this.context.resolveThemeEffectRef(styleNode["a:effectRef"], style);
|
|
9112
9531
|
}
|
|
9532
|
+
const fontRef = styleNode?.["a:fontRef"];
|
|
9533
|
+
if (fontRef) {
|
|
9534
|
+
const idxAttr = String(fontRef["@_idx"] || "").trim();
|
|
9535
|
+
if (idxAttr.length > 0) {
|
|
9536
|
+
style.fontRefIdx = idxAttr;
|
|
9537
|
+
}
|
|
9538
|
+
const overrideColorXml = this.extractFontRefColorXml(fontRef);
|
|
9539
|
+
if (overrideColorXml) {
|
|
9540
|
+
style.fontRefColorXml = overrideColorXml;
|
|
9541
|
+
}
|
|
9542
|
+
}
|
|
9113
9543
|
applyScene3dStyle(shapeProps, style);
|
|
9114
9544
|
applyShape3dStyle(shapeProps, style, this.context);
|
|
9115
9545
|
return style;
|
|
9116
9546
|
}
|
|
9547
|
+
/**
|
|
9548
|
+
* Pull the verbatim colour-choice child out of an `a:fontRef` element,
|
|
9549
|
+
* preserving any contained colour transforms for round-trip.
|
|
9550
|
+
*/
|
|
9551
|
+
extractFontRefColorXml(refNode) {
|
|
9552
|
+
if (!refNode) {
|
|
9553
|
+
return void 0;
|
|
9554
|
+
}
|
|
9555
|
+
const keys = [
|
|
9556
|
+
"a:scrgbClr",
|
|
9557
|
+
"a:srgbClr",
|
|
9558
|
+
"a:hslClr",
|
|
9559
|
+
"a:sysClr",
|
|
9560
|
+
"a:schemeClr",
|
|
9561
|
+
"a:prstClr"
|
|
9562
|
+
];
|
|
9563
|
+
for (const key of keys) {
|
|
9564
|
+
const child = refNode[key];
|
|
9565
|
+
if (child !== void 0) {
|
|
9566
|
+
return { [key]: child };
|
|
9567
|
+
}
|
|
9568
|
+
}
|
|
9569
|
+
return void 0;
|
|
9570
|
+
}
|
|
9117
9571
|
/**
|
|
9118
9572
|
* Extract p14:hiddenFill from the shape properties extension list.
|
|
9119
9573
|
* URI: {AF507438-7753-43E0-B8FC-AC1667EBCBE1}
|
|
@@ -9164,10 +9618,15 @@ var PptxShapeStyleExtractor = class {
|
|
|
9164
9618
|
function applyCellFillStyle(cellProperties, style, context) {
|
|
9165
9619
|
let hasStyle = false;
|
|
9166
9620
|
if (cellProperties?.["a:solidFill"]) {
|
|
9167
|
-
const
|
|
9621
|
+
const solidFillNode = cellProperties["a:solidFill"];
|
|
9622
|
+
const fillColor = context.parseColor(solidFillNode);
|
|
9168
9623
|
if (fillColor) {
|
|
9169
9624
|
style.fillMode = "solid";
|
|
9170
9625
|
style.backgroundColor = fillColor;
|
|
9626
|
+
const bgColorXml = extractColorChoiceXml(solidFillNode);
|
|
9627
|
+
if (bgColorXml) {
|
|
9628
|
+
style.backgroundColorXml = bgColorXml;
|
|
9629
|
+
}
|
|
9171
9630
|
hasStyle = true;
|
|
9172
9631
|
}
|
|
9173
9632
|
}
|
|
@@ -9204,6 +9663,10 @@ function applyCellFillStyle(cellProperties, style, context) {
|
|
|
9204
9663
|
}
|
|
9205
9664
|
}
|
|
9206
9665
|
}
|
|
9666
|
+
if (cellProperties?.["a:noFill"] !== void 0) {
|
|
9667
|
+
style.fillMode = "none";
|
|
9668
|
+
hasStyle = true;
|
|
9669
|
+
}
|
|
9207
9670
|
if (cellProperties?.["a:pattFill"]) {
|
|
9208
9671
|
const pattFill = cellProperties["a:pattFill"];
|
|
9209
9672
|
const fgColor = context.parseColor(pattFill["a:fgClr"]);
|
|
@@ -9510,8 +9973,7 @@ var PptxTableDataParser = class {
|
|
|
9510
9973
|
return width / totalWidthEmu;
|
|
9511
9974
|
}) : gridColumns.map(() => 1 / Math.max(gridColumns.length, 1));
|
|
9512
9975
|
const tableProperties = tableNode["a:tblPr"] || {};
|
|
9513
|
-
const
|
|
9514
|
-
const tableStyleId = String(tableStyleNode?.["@_val"] || tableProperties["@_tblStyle"] || "").trim() || void 0;
|
|
9976
|
+
const tableStyleId = this.extractTableStyleId(tableProperties);
|
|
9515
9977
|
const xmlRows = this.context.ensureArray(tableNode["a:tr"]);
|
|
9516
9978
|
const rows = xmlRows.map((rowNode) => {
|
|
9517
9979
|
const rowHeightEmu = parseInt(String(rowNode?.["@_h"] || "0"), 10) || 0;
|
|
@@ -9546,6 +10008,28 @@ var PptxTableDataParser = class {
|
|
|
9546
10008
|
return void 0;
|
|
9547
10009
|
}
|
|
9548
10010
|
}
|
|
10011
|
+
/**
|
|
10012
|
+
* Read the table style ID from `a:tblPr`.
|
|
10013
|
+
*
|
|
10014
|
+
* ECMA-376 §21.1.3.13 defines `<a:tableStyleId>{GUID}</a:tableStyleId>` as
|
|
10015
|
+
* a child element of `a:tblPr` carrying the GUID as element text. Older
|
|
10016
|
+
* inputs (and earlier versions of this library) used the legacy
|
|
10017
|
+
* `<a:tblStyle val="{GUID}"/>` child element or a `@_tblStyle` attribute.
|
|
10018
|
+
* Accept all three; the spec form takes precedence.
|
|
10019
|
+
*/
|
|
10020
|
+
extractTableStyleId(tableProperties) {
|
|
10021
|
+
const tableStyleIdNode = tableProperties["a:tableStyleId"];
|
|
10022
|
+
if (tableStyleIdNode !== void 0 && tableStyleIdNode !== null) {
|
|
10023
|
+
const direct = typeof tableStyleIdNode === "string" || typeof tableStyleIdNode === "number" ? String(tableStyleIdNode) : String(tableStyleIdNode["#text"] ?? "");
|
|
10024
|
+
const trimmed = direct.trim();
|
|
10025
|
+
if (trimmed.length > 0) {
|
|
10026
|
+
return trimmed;
|
|
10027
|
+
}
|
|
10028
|
+
}
|
|
10029
|
+
const tableStyleNode = tableProperties["a:tblStyle"];
|
|
10030
|
+
const legacy = String(tableStyleNode?.["@_val"] || tableProperties["@_tblStyle"] || "").trim();
|
|
10031
|
+
return legacy.length > 0 ? legacy : void 0;
|
|
10032
|
+
}
|
|
9549
10033
|
extractTableCellText(tableCell) {
|
|
9550
10034
|
const paragraphs = this.context.ensureArray(tableCell?.["a:txBody"]?.["a:p"]);
|
|
9551
10035
|
const lines = [];
|
|
@@ -9824,6 +10308,19 @@ var PptxGraphicFrameParser = class {
|
|
|
9824
10308
|
if (graphicData["a:videoFile"] || graphicData["a:audioFile"] || uri.includes("/drawingml/2006/media")) {
|
|
9825
10309
|
return "media";
|
|
9826
10310
|
}
|
|
10311
|
+
if (graphicData["aink:ink"] || uri.includes("/2010/ink") || uri.includes("drawing/2010/ink")) {
|
|
10312
|
+
return "ink";
|
|
10313
|
+
}
|
|
10314
|
+
const alternateContent = graphicData["mc:AlternateContent"];
|
|
10315
|
+
if (alternateContent) {
|
|
10316
|
+
const choices = Array.isArray(alternateContent["mc:Choice"]) ? alternateContent["mc:Choice"] : alternateContent["mc:Choice"] ? [alternateContent["mc:Choice"]] : [];
|
|
10317
|
+
for (const choice of choices) {
|
|
10318
|
+
const requires = String(choice?.["@_Requires"] || "").toLowerCase();
|
|
10319
|
+
if (requires.includes("aink") || choice?.["aink:ink"]) {
|
|
10320
|
+
return "ink";
|
|
10321
|
+
}
|
|
10322
|
+
}
|
|
10323
|
+
}
|
|
9827
10324
|
return "unknown";
|
|
9828
10325
|
}
|
|
9829
10326
|
};
|
|
@@ -10725,6 +11222,7 @@ var PptxDocumentPropertiesUpdater = class {
|
|
|
10725
11222
|
}));
|
|
10726
11223
|
if (sanitized.length === 0) {
|
|
10727
11224
|
this.context.zip.remove("docProps/custom.xml");
|
|
11225
|
+
await this.removeCustomPropertiesPackagingArtifacts();
|
|
10728
11226
|
return;
|
|
10729
11227
|
}
|
|
10730
11228
|
const customXml = {
|
|
@@ -10744,6 +11242,116 @@ var PptxDocumentPropertiesUpdater = class {
|
|
|
10744
11242
|
}
|
|
10745
11243
|
};
|
|
10746
11244
|
this.context.zip.file("docProps/custom.xml", this.context.builder.build(customXml));
|
|
11245
|
+
await this.ensureCustomPropertiesPackagingArtifacts();
|
|
11246
|
+
}
|
|
11247
|
+
/**
|
|
11248
|
+
* Ensure `[Content_Types].xml` has an `Override` for `docProps/custom.xml`
|
|
11249
|
+
* and the root `_rels/.rels` references it (ECMA-376 §15.2.12.2 +
|
|
11250
|
+
* Part 2 §10.1.2.5). Without these, the package fails OPC validation
|
|
11251
|
+
* and Office strips the custom properties on next save.
|
|
11252
|
+
*/
|
|
11253
|
+
async ensureCustomPropertiesPackagingArtifacts() {
|
|
11254
|
+
const customContentType = "application/vnd.openxmlformats-officedocument.custom-properties+xml";
|
|
11255
|
+
const customRelType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties";
|
|
11256
|
+
const ctFile = this.context.zip.file("[Content_Types].xml");
|
|
11257
|
+
if (ctFile) {
|
|
11258
|
+
try {
|
|
11259
|
+
const ctXml = await ctFile.async("string");
|
|
11260
|
+
const ctData = this.context.parser.parse(ctXml);
|
|
11261
|
+
const types = ctData["Types"];
|
|
11262
|
+
if (types) {
|
|
11263
|
+
const overrides = Array.isArray(types["Override"]) ? types["Override"] : types["Override"] ? [types["Override"]] : [];
|
|
11264
|
+
const hasCustomOverride = overrides.some(
|
|
11265
|
+
(o) => String(o?.["@_PartName"] || "") === "/docProps/custom.xml"
|
|
11266
|
+
);
|
|
11267
|
+
if (!hasCustomOverride) {
|
|
11268
|
+
overrides.push({
|
|
11269
|
+
"@_PartName": "/docProps/custom.xml",
|
|
11270
|
+
"@_ContentType": customContentType
|
|
11271
|
+
});
|
|
11272
|
+
types["Override"] = overrides.length === 1 ? overrides[0] : overrides;
|
|
11273
|
+
this.context.zip.file("[Content_Types].xml", this.context.builder.build(ctData));
|
|
11274
|
+
}
|
|
11275
|
+
}
|
|
11276
|
+
} catch (error) {
|
|
11277
|
+
console.warn("Failed to update [Content_Types].xml for custom properties:", error);
|
|
11278
|
+
}
|
|
11279
|
+
}
|
|
11280
|
+
const relsFile = this.context.zip.file("_rels/.rels");
|
|
11281
|
+
if (relsFile) {
|
|
11282
|
+
try {
|
|
11283
|
+
const relsXml = await relsFile.async("string");
|
|
11284
|
+
const relsData = this.context.parser.parse(relsXml);
|
|
11285
|
+
const relationships = relsData["Relationships"];
|
|
11286
|
+
if (relationships) {
|
|
11287
|
+
const rels = Array.isArray(relationships["Relationship"]) ? relationships["Relationship"] : relationships["Relationship"] ? [relationships["Relationship"]] : [];
|
|
11288
|
+
const hasCustomRel = rels.some((r) => String(r?.["@_Type"] || "") === customRelType);
|
|
11289
|
+
if (!hasCustomRel) {
|
|
11290
|
+
let maxId = 0;
|
|
11291
|
+
for (const rel of rels) {
|
|
11292
|
+
const id = String(rel?.["@_Id"] || "");
|
|
11293
|
+
const num = Number.parseInt(id.replace(/^rId/, ""), 10);
|
|
11294
|
+
if (Number.isFinite(num) && num > maxId) {
|
|
11295
|
+
maxId = num;
|
|
11296
|
+
}
|
|
11297
|
+
}
|
|
11298
|
+
rels.push({
|
|
11299
|
+
"@_Id": `rId${maxId + 1}`,
|
|
11300
|
+
"@_Type": customRelType,
|
|
11301
|
+
"@_Target": "docProps/custom.xml"
|
|
11302
|
+
});
|
|
11303
|
+
relationships["Relationship"] = rels;
|
|
11304
|
+
this.context.zip.file("_rels/.rels", this.context.builder.build(relsData));
|
|
11305
|
+
}
|
|
11306
|
+
}
|
|
11307
|
+
} catch (error) {
|
|
11308
|
+
console.warn("Failed to update _rels/.rels for custom properties:", error);
|
|
11309
|
+
}
|
|
11310
|
+
}
|
|
11311
|
+
}
|
|
11312
|
+
/**
|
|
11313
|
+
* Remove the Override + root rel for `docProps/custom.xml` when the
|
|
11314
|
+
* caller has emptied custom properties so the package doesn't keep an
|
|
11315
|
+
* orphan content-type entry referencing a deleted part.
|
|
11316
|
+
*/
|
|
11317
|
+
async removeCustomPropertiesPackagingArtifacts() {
|
|
11318
|
+
const customRelType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties";
|
|
11319
|
+
const ctFile = this.context.zip.file("[Content_Types].xml");
|
|
11320
|
+
if (ctFile) {
|
|
11321
|
+
try {
|
|
11322
|
+
const ctXml = await ctFile.async("string");
|
|
11323
|
+
const ctData = this.context.parser.parse(ctXml);
|
|
11324
|
+
const types = ctData["Types"];
|
|
11325
|
+
if (types) {
|
|
11326
|
+
const overrides = Array.isArray(types["Override"]) ? types["Override"] : types["Override"] ? [types["Override"]] : [];
|
|
11327
|
+
const filtered = overrides.filter(
|
|
11328
|
+
(o) => String(o?.["@_PartName"] || "") !== "/docProps/custom.xml"
|
|
11329
|
+
);
|
|
11330
|
+
if (filtered.length !== overrides.length) {
|
|
11331
|
+
types["Override"] = filtered.length === 1 ? filtered[0] : filtered;
|
|
11332
|
+
this.context.zip.file("[Content_Types].xml", this.context.builder.build(ctData));
|
|
11333
|
+
}
|
|
11334
|
+
}
|
|
11335
|
+
} catch {
|
|
11336
|
+
}
|
|
11337
|
+
}
|
|
11338
|
+
const relsFile = this.context.zip.file("_rels/.rels");
|
|
11339
|
+
if (relsFile) {
|
|
11340
|
+
try {
|
|
11341
|
+
const relsXml = await relsFile.async("string");
|
|
11342
|
+
const relsData = this.context.parser.parse(relsXml);
|
|
11343
|
+
const relationships = relsData["Relationships"];
|
|
11344
|
+
if (relationships) {
|
|
11345
|
+
const rels = Array.isArray(relationships["Relationship"]) ? relationships["Relationship"] : relationships["Relationship"] ? [relationships["Relationship"]] : [];
|
|
11346
|
+
const filtered = rels.filter((r) => String(r?.["@_Type"] || "") !== customRelType);
|
|
11347
|
+
if (filtered.length !== rels.length) {
|
|
11348
|
+
relationships["Relationship"] = filtered;
|
|
11349
|
+
this.context.zip.file("_rels/.rels", this.context.builder.build(relsData));
|
|
11350
|
+
}
|
|
11351
|
+
}
|
|
11352
|
+
} catch {
|
|
11353
|
+
}
|
|
11354
|
+
}
|
|
10747
11355
|
}
|
|
10748
11356
|
normalizeCustomPropertyType(type) {
|
|
10749
11357
|
const supportedTypes = /* @__PURE__ */ new Set([
|
|
@@ -11087,6 +11695,7 @@ var PptxSlideLoaderService = class {
|
|
|
11087
11695
|
await params.loadSlideRelationships(path2, slideRelsPath);
|
|
11088
11696
|
const clrMapOverride = params.parseSlideClrMapOverride(slideXmlObj);
|
|
11089
11697
|
params.setCurrentSlideClrMapOverride(clrMapOverride);
|
|
11698
|
+
await params.setActiveMasterForSlide?.(path2);
|
|
11090
11699
|
let restoreThemeOverride;
|
|
11091
11700
|
try {
|
|
11092
11701
|
const layoutPathForOverride = params.findLayoutPathForSlide(path2);
|
|
@@ -15838,6 +16447,20 @@ var AXIS_TYPE_MAP = {
|
|
|
15838
16447
|
dateAx: "dateAx",
|
|
15839
16448
|
serAx: "serAx"
|
|
15840
16449
|
};
|
|
16450
|
+
function upsertChartAxisChild(parent, localName, value, getLocalName) {
|
|
16451
|
+
const existingKey = Object.keys(parent).find((k) => getLocalName(k) === localName);
|
|
16452
|
+
if (value === void 0) {
|
|
16453
|
+
if (existingKey) {
|
|
16454
|
+
delete parent[existingKey];
|
|
16455
|
+
}
|
|
16456
|
+
return;
|
|
16457
|
+
}
|
|
16458
|
+
if (existingKey) {
|
|
16459
|
+
parent[existingKey]["@_val"] = value;
|
|
16460
|
+
} else {
|
|
16461
|
+
parent[`c:${localName}`] = { "@_val": value };
|
|
16462
|
+
}
|
|
16463
|
+
}
|
|
15841
16464
|
function parseChartAxes(plotArea, xmlLookup, colorParser, getLocalName) {
|
|
15842
16465
|
const result = [];
|
|
15843
16466
|
for (const key of Object.keys(plotArea)) {
|
|
@@ -15958,6 +16581,27 @@ function parseSingleAxis(axisNode, axisType, xmlLookup, colorParser) {
|
|
|
15958
16581
|
if (dispUnitsNode) {
|
|
15959
16582
|
parseDisplayUnits(dispUnitsNode, xmlLookup, result);
|
|
15960
16583
|
}
|
|
16584
|
+
const majorUnitNode = xmlLookup.getChildByLocalName(axisNode, "majorUnit");
|
|
16585
|
+
if (majorUnitNode) {
|
|
16586
|
+
const majorVal = parseFloat(String(majorUnitNode["@_val"]));
|
|
16587
|
+
if (Number.isFinite(majorVal)) {
|
|
16588
|
+
result.majorUnit = majorVal;
|
|
16589
|
+
}
|
|
16590
|
+
}
|
|
16591
|
+
const minorUnitNode = xmlLookup.getChildByLocalName(axisNode, "minorUnit");
|
|
16592
|
+
if (minorUnitNode) {
|
|
16593
|
+
const minorVal = parseFloat(String(minorUnitNode["@_val"]));
|
|
16594
|
+
if (Number.isFinite(minorVal)) {
|
|
16595
|
+
result.minorUnit = minorVal;
|
|
16596
|
+
}
|
|
16597
|
+
}
|
|
16598
|
+
const tickLblPosNode = xmlLookup.getChildByLocalName(axisNode, "tickLblPos");
|
|
16599
|
+
if (tickLblPosNode) {
|
|
16600
|
+
const v = String(tickLblPosNode["@_val"] || "").trim();
|
|
16601
|
+
if (v === "high" || v === "low" || v === "nextTo" || v === "none") {
|
|
16602
|
+
result.tickLblPos = v;
|
|
16603
|
+
}
|
|
16604
|
+
}
|
|
15961
16605
|
return result;
|
|
15962
16606
|
}
|
|
15963
16607
|
var VALID_DISPLAY_UNITS = /* @__PURE__ */ new Set([
|
|
@@ -17269,23 +17913,55 @@ var SHAPE_TREE_ELEMENT_TAGS = /* @__PURE__ */ new Set([
|
|
|
17269
17913
|
"p16:model3D",
|
|
17270
17914
|
...VML_SHAPE_TAGS
|
|
17271
17915
|
]);
|
|
17916
|
+
function diagnoseSelection(ac) {
|
|
17917
|
+
const choices = ensureArray2(ac["mc:Choice"]);
|
|
17918
|
+
for (let i = 0; i < choices.length; i++) {
|
|
17919
|
+
const choice = choices[i];
|
|
17920
|
+
const requires = String(choice?.["@_Requires"] ?? "").trim();
|
|
17921
|
+
if (requires.length === 0 || areNamespacesSupported(requires)) {
|
|
17922
|
+
const resolved = resolveNestedAlternateContent(choice);
|
|
17923
|
+
return { branch: "choice", choiceIndex: i, resolved };
|
|
17924
|
+
}
|
|
17925
|
+
}
|
|
17926
|
+
const fallback = ac["mc:Fallback"];
|
|
17927
|
+
if (fallback) {
|
|
17928
|
+
return { branch: "fallback", resolved: resolveNestedAlternateContent(fallback) };
|
|
17929
|
+
}
|
|
17930
|
+
return void 0;
|
|
17931
|
+
}
|
|
17272
17932
|
function unwrapAlternateContent(container) {
|
|
17273
17933
|
const altContents = ensureArray2(container["mc:AlternateContent"]);
|
|
17274
17934
|
if (altContents.length === 0) {
|
|
17275
|
-
return;
|
|
17935
|
+
return [];
|
|
17276
17936
|
}
|
|
17937
|
+
const blocks = [];
|
|
17277
17938
|
for (const ac of altContents) {
|
|
17278
|
-
const
|
|
17279
|
-
if (!
|
|
17939
|
+
const diagnosis = diagnoseSelection(ac);
|
|
17940
|
+
if (!diagnosis) {
|
|
17280
17941
|
continue;
|
|
17281
17942
|
}
|
|
17943
|
+
const block = {
|
|
17944
|
+
rawAc: ac,
|
|
17945
|
+
selectedBranch: diagnosis.branch,
|
|
17946
|
+
choiceIndex: diagnosis.branch === "choice" ? diagnosis.choiceIndex : void 0,
|
|
17947
|
+
childRefs: []
|
|
17948
|
+
};
|
|
17949
|
+
const branch = diagnosis.resolved;
|
|
17282
17950
|
for (const tag of SHAPE_TREE_ELEMENT_TAGS) {
|
|
17283
17951
|
const children = ensureArray2(branch[tag]);
|
|
17284
17952
|
if (children.length > 0) {
|
|
17285
17953
|
container[tag] = [...ensureArray2(container[tag]), ...children];
|
|
17954
|
+
for (const child of children) {
|
|
17955
|
+
block.childRefs.push({ tag, node: child });
|
|
17956
|
+
}
|
|
17286
17957
|
}
|
|
17287
17958
|
}
|
|
17959
|
+
if (block.childRefs.length > 0) {
|
|
17960
|
+
blocks.push(block);
|
|
17961
|
+
}
|
|
17288
17962
|
}
|
|
17963
|
+
delete container["mc:AlternateContent"];
|
|
17964
|
+
return blocks;
|
|
17289
17965
|
}
|
|
17290
17966
|
function ensureArray2(val) {
|
|
17291
17967
|
if (!val) {
|
|
@@ -17297,7 +17973,7 @@ function ensureArray2(val) {
|
|
|
17297
17973
|
|
|
17298
17974
|
// src/core/utils/body-properties-parser.ts
|
|
17299
17975
|
function parseBodyPrBooleanAttrs(bodyPr, textStyle) {
|
|
17300
|
-
const
|
|
17976
|
+
const parseBoolAttr2 = (attr) => {
|
|
17301
17977
|
const raw = bodyPr[attr];
|
|
17302
17978
|
if (raw === void 0) {
|
|
17303
17979
|
return void 0;
|
|
@@ -17305,19 +17981,19 @@ function parseBodyPrBooleanAttrs(bodyPr, textStyle) {
|
|
|
17305
17981
|
const val = String(raw).trim().toLowerCase();
|
|
17306
17982
|
return val === "1" || val === "true";
|
|
17307
17983
|
};
|
|
17308
|
-
const compatLnSpc =
|
|
17984
|
+
const compatLnSpc = parseBoolAttr2("@_compatLnSpc");
|
|
17309
17985
|
if (compatLnSpc !== void 0) {
|
|
17310
17986
|
textStyle.compatibleLineSpacing = compatLnSpc;
|
|
17311
17987
|
}
|
|
17312
|
-
const forceAA =
|
|
17988
|
+
const forceAA = parseBoolAttr2("@_forceAA");
|
|
17313
17989
|
if (forceAA !== void 0) {
|
|
17314
17990
|
textStyle.forceAntiAlias = forceAA;
|
|
17315
17991
|
}
|
|
17316
|
-
const upright =
|
|
17992
|
+
const upright = parseBoolAttr2("@_upright");
|
|
17317
17993
|
if (upright !== void 0) {
|
|
17318
17994
|
textStyle.upright = upright;
|
|
17319
17995
|
}
|
|
17320
|
-
const fromWordArt =
|
|
17996
|
+
const fromWordArt = parseBoolAttr2("@_fromWordArt");
|
|
17321
17997
|
if (fromWordArt !== void 0) {
|
|
17322
17998
|
textStyle.fromWordArt = fromWordArt;
|
|
17323
17999
|
}
|
|
@@ -17340,46 +18016,6 @@ function writeBodyPrBooleanAttrs(bodyPr, textStyle) {
|
|
|
17340
18016
|
}
|
|
17341
18017
|
}
|
|
17342
18018
|
|
|
17343
|
-
// src/core/utils/theme-override-utils.ts
|
|
17344
|
-
var COLOR_MAP_ALIAS_KEYS = [
|
|
17345
|
-
"bg1",
|
|
17346
|
-
"tx1",
|
|
17347
|
-
"bg2",
|
|
17348
|
-
"tx2",
|
|
17349
|
-
"accent1",
|
|
17350
|
-
"accent2",
|
|
17351
|
-
"accent3",
|
|
17352
|
-
"accent4",
|
|
17353
|
-
"accent5",
|
|
17354
|
-
"accent6",
|
|
17355
|
-
"hlink",
|
|
17356
|
-
"folHlink"
|
|
17357
|
-
];
|
|
17358
|
-
var DEFAULT_COLOR_MAP = {
|
|
17359
|
-
bg1: "lt1",
|
|
17360
|
-
tx1: "dk1",
|
|
17361
|
-
bg2: "lt2",
|
|
17362
|
-
tx2: "dk2",
|
|
17363
|
-
accent1: "accent1",
|
|
17364
|
-
accent2: "accent2",
|
|
17365
|
-
accent3: "accent3",
|
|
17366
|
-
accent4: "accent4",
|
|
17367
|
-
accent5: "accent5",
|
|
17368
|
-
accent6: "accent6",
|
|
17369
|
-
hlink: "hlink",
|
|
17370
|
-
folHlink: "folHlink"
|
|
17371
|
-
};
|
|
17372
|
-
function buildClrMapOverrideXml(override) {
|
|
17373
|
-
if (!override || Object.keys(override).length === 0) {
|
|
17374
|
-
return { "a:masterClrMapping": {} };
|
|
17375
|
-
}
|
|
17376
|
-
const attrs2 = {};
|
|
17377
|
-
for (const key of COLOR_MAP_ALIAS_KEYS) {
|
|
17378
|
-
attrs2[`@_${key}`] = override[key] ?? DEFAULT_COLOR_MAP[key];
|
|
17379
|
-
}
|
|
17380
|
-
return { "a:overrideClrMapping": attrs2 };
|
|
17381
|
-
}
|
|
17382
|
-
|
|
17383
18019
|
// src/core/utils/data-url-utils.ts
|
|
17384
18020
|
function parseDataUrlToBytes(dataUrl) {
|
|
17385
18021
|
const match = dataUrl.match(/^data:([^;]+);base64,(.+)$/);
|
|
@@ -17477,6 +18113,46 @@ async function fetchUrlToBytes(url) {
|
|
|
17477
18113
|
}
|
|
17478
18114
|
}
|
|
17479
18115
|
|
|
18116
|
+
// src/core/utils/theme-override-utils.ts
|
|
18117
|
+
var COLOR_MAP_ALIAS_KEYS = [
|
|
18118
|
+
"bg1",
|
|
18119
|
+
"tx1",
|
|
18120
|
+
"bg2",
|
|
18121
|
+
"tx2",
|
|
18122
|
+
"accent1",
|
|
18123
|
+
"accent2",
|
|
18124
|
+
"accent3",
|
|
18125
|
+
"accent4",
|
|
18126
|
+
"accent5",
|
|
18127
|
+
"accent6",
|
|
18128
|
+
"hlink",
|
|
18129
|
+
"folHlink"
|
|
18130
|
+
];
|
|
18131
|
+
var DEFAULT_COLOR_MAP = {
|
|
18132
|
+
bg1: "lt1",
|
|
18133
|
+
tx1: "dk1",
|
|
18134
|
+
bg2: "lt2",
|
|
18135
|
+
tx2: "dk2",
|
|
18136
|
+
accent1: "accent1",
|
|
18137
|
+
accent2: "accent2",
|
|
18138
|
+
accent3: "accent3",
|
|
18139
|
+
accent4: "accent4",
|
|
18140
|
+
accent5: "accent5",
|
|
18141
|
+
accent6: "accent6",
|
|
18142
|
+
hlink: "hlink",
|
|
18143
|
+
folHlink: "folHlink"
|
|
18144
|
+
};
|
|
18145
|
+
function buildClrMapOverrideXml(override) {
|
|
18146
|
+
if (!override || Object.keys(override).length === 0) {
|
|
18147
|
+
return { "a:masterClrMapping": {} };
|
|
18148
|
+
}
|
|
18149
|
+
const attrs2 = {};
|
|
18150
|
+
for (const key of COLOR_MAP_ALIAS_KEYS) {
|
|
18151
|
+
attrs2[`@_${key}`] = override[key] ?? DEFAULT_COLOR_MAP[key];
|
|
18152
|
+
}
|
|
18153
|
+
return { "a:overrideClrMapping": attrs2 };
|
|
18154
|
+
}
|
|
18155
|
+
|
|
17480
18156
|
// src/core/utils/encryption-detection.ts
|
|
17481
18157
|
var OLE_MAGIC = new Uint8Array([208, 207, 17, 224, 161, 27, 26, 225]);
|
|
17482
18158
|
var ZIP_MAGIC = new Uint8Array([80, 75]);
|
|
@@ -23239,7 +23915,7 @@ function parseActiveXControlsFromSlide(slideXml2) {
|
|
|
23239
23915
|
}
|
|
23240
23916
|
|
|
23241
23917
|
// src/core/utils/theme-switching.ts
|
|
23242
|
-
function
|
|
23918
|
+
function normalizeHex2(hex) {
|
|
23243
23919
|
if (!hex) {
|
|
23244
23920
|
return "";
|
|
23245
23921
|
}
|
|
@@ -23249,8 +23925,8 @@ function buildColorRemapTable(oldColorMap, newColorMap) {
|
|
|
23249
23925
|
const remap = /* @__PURE__ */ new Map();
|
|
23250
23926
|
const allKeys = [...THEME_COLOR_SCHEME_KEYS, "tx1", "bg1", "tx2", "bg2"];
|
|
23251
23927
|
for (const key of allKeys) {
|
|
23252
|
-
const oldVal =
|
|
23253
|
-
const newVal =
|
|
23928
|
+
const oldVal = normalizeHex2(oldColorMap[key]);
|
|
23929
|
+
const newVal = normalizeHex2(newColorMap[key]);
|
|
23254
23930
|
if (oldVal && newVal && oldVal !== newVal) {
|
|
23255
23931
|
remap.set(oldVal, `#${newVal}`);
|
|
23256
23932
|
remap.set(`#${oldVal}`, `#${newVal}`);
|
|
@@ -23262,7 +23938,7 @@ function remapColor(color, remap) {
|
|
|
23262
23938
|
if (!color) {
|
|
23263
23939
|
return color;
|
|
23264
23940
|
}
|
|
23265
|
-
const normalized =
|
|
23941
|
+
const normalized = normalizeHex2(color);
|
|
23266
23942
|
const remapped = remap.get(normalized) ?? remap.get(`#${normalized}`);
|
|
23267
23943
|
return remapped ?? color;
|
|
23268
23944
|
}
|
|
@@ -23402,7 +24078,7 @@ function remapSlideColors(slide, remap) {
|
|
|
23402
24078
|
function buildThemeColorMap(colorScheme) {
|
|
23403
24079
|
const map = {};
|
|
23404
24080
|
for (const key of THEME_COLOR_SCHEME_KEYS) {
|
|
23405
|
-
map[key] =
|
|
24081
|
+
map[key] = normalizeHex2(colorScheme[key]);
|
|
23406
24082
|
}
|
|
23407
24083
|
map.tx1 = map.dk1;
|
|
23408
24084
|
map.bg1 = map.lt1;
|
|
@@ -23438,8 +24114,11 @@ function applyThemeToData(data, newColorScheme, newFontScheme, themeName) {
|
|
|
23438
24114
|
|
|
23439
24115
|
// src/core/core/runtime/PptxHandlerRuntimeSaveParagraphHelpers.ts
|
|
23440
24116
|
var EMU_PER_PX4 = 9525;
|
|
23441
|
-
function buildParagraphPropertiesXml(textStyle, paragraphAlign, bulletInfo, spacing) {
|
|
24117
|
+
function buildParagraphPropertiesXml(textStyle, paragraphAlign, bulletInfo, spacing, level) {
|
|
23442
24118
|
const paragraphProps = {};
|
|
24119
|
+
if (typeof level === "number" && Number.isFinite(level) && level > 0) {
|
|
24120
|
+
paragraphProps["@_lvl"] = String(Math.min(Math.max(Math.round(level), 0), 8));
|
|
24121
|
+
}
|
|
23443
24122
|
if (paragraphAlign) {
|
|
23444
24123
|
paragraphProps["@_algn"] = paragraphAlign;
|
|
23445
24124
|
}
|
|
@@ -23511,23 +24190,28 @@ function applyBulletProperties(paragraphProps, bulletInfo) {
|
|
|
23511
24190
|
paragraphProps["a:buNone"] = {};
|
|
23512
24191
|
return;
|
|
23513
24192
|
}
|
|
23514
|
-
if (bulletInfo.
|
|
24193
|
+
if (bulletInfo.colorInherit) {
|
|
24194
|
+
paragraphProps["a:buClrTx"] = {};
|
|
24195
|
+
} else if (bulletInfo.color) {
|
|
23515
24196
|
const colorHex = bulletInfo.color.replace("#", "");
|
|
23516
24197
|
paragraphProps["a:buClr"] = {
|
|
23517
24198
|
"a:srgbClr": { "@_val": colorHex }
|
|
23518
24199
|
};
|
|
23519
24200
|
}
|
|
23520
|
-
if (bulletInfo.
|
|
24201
|
+
if (bulletInfo.sizeInherit) {
|
|
24202
|
+
paragraphProps["a:buSzTx"] = {};
|
|
24203
|
+
} else if (bulletInfo.sizePercent !== void 0) {
|
|
23521
24204
|
paragraphProps["a:buSzPct"] = {
|
|
23522
24205
|
"@_val": String(Math.round(bulletInfo.sizePercent * 1e3))
|
|
23523
24206
|
};
|
|
23524
|
-
}
|
|
23525
|
-
if (bulletInfo.sizePts !== void 0) {
|
|
24207
|
+
} else if (bulletInfo.sizePts !== void 0) {
|
|
23526
24208
|
paragraphProps["a:buSzPts"] = {
|
|
23527
24209
|
"@_val": String(Math.round(bulletInfo.sizePts * 100))
|
|
23528
24210
|
};
|
|
23529
24211
|
}
|
|
23530
|
-
if (bulletInfo.
|
|
24212
|
+
if (bulletInfo.fontInherit) {
|
|
24213
|
+
paragraphProps["a:buFontTx"] = {};
|
|
24214
|
+
} else if (bulletInfo.fontFamily) {
|
|
23531
24215
|
paragraphProps["a:buFont"] = {
|
|
23532
24216
|
"@_typeface": bulletInfo.fontFamily
|
|
23533
24217
|
};
|
|
@@ -23550,7 +24234,7 @@ function applyBulletProperties(paragraphProps, bulletInfo) {
|
|
|
23550
24234
|
};
|
|
23551
24235
|
}
|
|
23552
24236
|
}
|
|
23553
|
-
function assembleParagraphXml(runs, paragraphProps) {
|
|
24237
|
+
function assembleParagraphXml(runs, paragraphProps, endParaRunProperties) {
|
|
23554
24238
|
const paragraph = {
|
|
23555
24239
|
"a:pPr": paragraphProps
|
|
23556
24240
|
};
|
|
@@ -23572,7 +24256,11 @@ function assembleParagraphXml(runs, paragraphProps) {
|
|
|
23572
24256
|
if (cleanRegularRuns.length === 0 && fieldRuns.length === 0) {
|
|
23573
24257
|
paragraph["a:r"] = runs.length > 1 ? runs : runs[0];
|
|
23574
24258
|
}
|
|
23575
|
-
|
|
24259
|
+
if (endParaRunProperties && typeof endParaRunProperties === "object") {
|
|
24260
|
+
paragraph["a:endParaRPr"] = endParaRunProperties;
|
|
24261
|
+
} else {
|
|
24262
|
+
paragraph["a:endParaRPr"] = { "@_lang": "en-US" };
|
|
24263
|
+
}
|
|
23576
24264
|
return paragraph;
|
|
23577
24265
|
}
|
|
23578
24266
|
function computeUniformSegmentOverrides(textStyle, textSegments) {
|
|
@@ -23876,6 +24564,140 @@ var PptxHandlerRuntime = class {
|
|
|
23876
24564
|
* `p:clrMapOvr / a:overrideClrMapping`.
|
|
23877
24565
|
*/
|
|
23878
24566
|
currentSlideClrMapOverride = null;
|
|
24567
|
+
/**
|
|
24568
|
+
* Per-master colour map alias dictionaries parsed from each master's
|
|
24569
|
+
* `<p:clrMap>` element (e.g. `bg1 → lt1`, `tx1 → dk1`, `accent1 → accent1`).
|
|
24570
|
+
*
|
|
24571
|
+
* `clrMap` is the *aliasing* layer between logical colour names used in
|
|
24572
|
+
* DrawingML and the raw theme scheme slots. Per ECMA-376 §19.3.1.7 it
|
|
24573
|
+
* lives on each `p:sldMaster`, and slide layouts/slides may further
|
|
24574
|
+
* override it via `p:clrMapOvr`. Resolution must happen at colour-lookup
|
|
24575
|
+
* time, *not* by baking it into {@link themeColorMap}.
|
|
24576
|
+
*
|
|
24577
|
+
* Phase 2 Stream B / C-H4.
|
|
24578
|
+
*/
|
|
24579
|
+
masterClrMaps = /* @__PURE__ */ new Map();
|
|
24580
|
+
/**
|
|
24581
|
+
* Per-master theme color maps. Each master may reference its own theme
|
|
24582
|
+
* file via `_rels/slideMasterN.xml.rels`. For multi-master decks, slides
|
|
24583
|
+
* must resolve scheme colours against their *own* master's theme.
|
|
24584
|
+
*
|
|
24585
|
+
* Falls back to {@link themeColorMap} when a master entry is missing.
|
|
24586
|
+
*
|
|
24587
|
+
* Phase 2 Stream B / C-H4.
|
|
24588
|
+
*/
|
|
24589
|
+
masterThemeColorMaps = /* @__PURE__ */ new Map();
|
|
24590
|
+
/**
|
|
24591
|
+
* Per-master theme font maps. Same rationale as
|
|
24592
|
+
* {@link masterThemeColorMaps}: multi-master decks may have one font
|
|
24593
|
+
* scheme per theme.
|
|
24594
|
+
*/
|
|
24595
|
+
masterThemeFontMaps = /* @__PURE__ */ new Map();
|
|
24596
|
+
/**
|
|
24597
|
+
* Per-master format schemes (fmtScheme). For multi-master decks each
|
|
24598
|
+
* master's slides should resolve fill/line/effect refs against the
|
|
24599
|
+
* matrix from that master's theme.
|
|
24600
|
+
*/
|
|
24601
|
+
masterThemeFormatSchemes = /* @__PURE__ */ new Map();
|
|
24602
|
+
/**
|
|
24603
|
+
* Per-master mapping from slide-master path to the theme path it
|
|
24604
|
+
* references via `_rels/slideMasterN.xml.rels`. Populated by
|
|
24605
|
+
* {@link loadPerMasterThemes} during load. Used by the save-side
|
|
24606
|
+
* theme writer to know which themeN.xml to (re)emit for each master.
|
|
24607
|
+
*
|
|
24608
|
+
* Phase 4 Stream A / C-H3.
|
|
24609
|
+
*/
|
|
24610
|
+
masterThemePaths = /* @__PURE__ */ new Map();
|
|
24611
|
+
/**
|
|
24612
|
+
* Per-script font tables for major and minor fonts. Captured per master
|
|
24613
|
+
* theme. Keys are master paths; values map `mj`/`mn` -> script tag (e.g.
|
|
24614
|
+
* `Hans`, `Hant`, `Arab`, `Hebr`, `Thai`, `Beng`, …) -> typeface name.
|
|
24615
|
+
*
|
|
24616
|
+
* Phase 4 Stream A / M4.
|
|
24617
|
+
*/
|
|
24618
|
+
masterThemeMajorFontScripts = /* @__PURE__ */ new Map();
|
|
24619
|
+
masterThemeMinorFontScripts = /* @__PURE__ */ new Map();
|
|
24620
|
+
/**
|
|
24621
|
+
* Theme name attribute (`<a:theme @name>`) per master theme path.
|
|
24622
|
+
* Captured for byte-stable round-trip.
|
|
24623
|
+
*/
|
|
24624
|
+
masterThemeNames = /* @__PURE__ */ new Map();
|
|
24625
|
+
/**
|
|
24626
|
+
* `<a:fontScheme @name>` per master theme path.
|
|
24627
|
+
*/
|
|
24628
|
+
masterThemeFontSchemeNames = /* @__PURE__ */ new Map();
|
|
24629
|
+
/**
|
|
24630
|
+
* `<a:clrScheme @name>` per master theme path.
|
|
24631
|
+
*/
|
|
24632
|
+
masterThemeColorSchemeNames = /* @__PURE__ */ new Map();
|
|
24633
|
+
/**
|
|
24634
|
+
* Raw original theme XML keyed by theme path. Captured at load-time.
|
|
24635
|
+
* Used by the save pipeline to passthrough the full theme XML when no
|
|
24636
|
+
* in-memory mutation has occurred — preserving fillStyleLst /
|
|
24637
|
+
* lnStyleLst / effectStyleLst / bgFillStyleLst /
|
|
24638
|
+
* extraClrSchemeLst / objectDefaults / extLst exactly as written.
|
|
24639
|
+
*
|
|
24640
|
+
* Phase 4 Stream A / C-H3.
|
|
24641
|
+
*/
|
|
24642
|
+
originalThemeXmlByPath = /* @__PURE__ */ new Map();
|
|
24643
|
+
/**
|
|
24644
|
+
* Set of theme paths whose in-memory state has been mutated since
|
|
24645
|
+
* load. Saving a theme path that's NOT dirty is a no-op (the original
|
|
24646
|
+
* file already exists in the ZIP). Saving a dirty theme path
|
|
24647
|
+
* regenerates the part from in-memory state.
|
|
24648
|
+
*
|
|
24649
|
+
* Phase 4 Stream A / C-H3.
|
|
24650
|
+
*/
|
|
24651
|
+
dirtyThemePaths = /* @__PURE__ */ new Set();
|
|
24652
|
+
/**
|
|
24653
|
+
* Per-master parsed `<p:txStyles>` (titleStyle/bodyStyle/otherStyle).
|
|
24654
|
+
* Populated by {@link enrichSlideMastersWithTxStyles} during load so the
|
|
24655
|
+
* inheritance chain can find the master text-style cascade without
|
|
24656
|
+
* re-parsing master XML on every lookup. Phase 4 Stream B / P-H1.
|
|
24657
|
+
*/
|
|
24658
|
+
masterTxStylesCache = /* @__PURE__ */ new Map();
|
|
24659
|
+
/**
|
|
24660
|
+
* Captured `<a:objectDefaults>` snapshot per master theme path. The
|
|
24661
|
+
* full ECMA-376 inheritance chain (master / layout / placeholder /
|
|
24662
|
+
* objectDefaults) is non-trivial; we store the raw spDef/lnDef/txDef
|
|
24663
|
+
* subtrees and re-emit them verbatim for round-trip.
|
|
24664
|
+
*
|
|
24665
|
+
* Phase 4 Stream A / M5.
|
|
24666
|
+
*/
|
|
24667
|
+
masterThemeObjectDefaults = /* @__PURE__ */ new Map();
|
|
24668
|
+
/**
|
|
24669
|
+
* Captured `<a:extraClrSchemeLst>` raw subtree per master theme path
|
|
24670
|
+
* for verbatim round-trip.
|
|
24671
|
+
*
|
|
24672
|
+
* Phase 4 Stream A.
|
|
24673
|
+
*/
|
|
24674
|
+
masterThemeExtraClrSchemeLst = /* @__PURE__ */ new Map();
|
|
24675
|
+
/**
|
|
24676
|
+
* Captured `<a:custClrLst>` raw subtree per master theme path
|
|
24677
|
+
* for verbatim round-trip.
|
|
24678
|
+
*
|
|
24679
|
+
* Phase 4 Stream A.
|
|
24680
|
+
*/
|
|
24681
|
+
masterThemeCustClrLst = /* @__PURE__ */ new Map();
|
|
24682
|
+
/**
|
|
24683
|
+
* Captured theme-level `<a:extLst>` raw subtree per master theme path.
|
|
24684
|
+
*/
|
|
24685
|
+
masterThemeExtLst = /* @__PURE__ */ new Map();
|
|
24686
|
+
/**
|
|
24687
|
+
* Active master's clrMap for the slide currently being parsed. Walked
|
|
24688
|
+
* after `currentSlideClrMapOverride` (slide and layout overrides take
|
|
24689
|
+
* precedence). `null` means "fall through to themeColorMap directly".
|
|
24690
|
+
*/
|
|
24691
|
+
currentMasterClrMap = null;
|
|
24692
|
+
/**
|
|
24693
|
+
* Snapshot of the global theme state taken right after
|
|
24694
|
+
* {@link loadThemeData} completes. Used as the fallback when a slide's
|
|
24695
|
+
* master has no per-master theme entry, so per-slide multi-master
|
|
24696
|
+
* switching does not leak the previous slide's master state.
|
|
24697
|
+
*/
|
|
24698
|
+
globalThemeColorMapSnapshot = {};
|
|
24699
|
+
globalThemeFontMapSnapshot = {};
|
|
24700
|
+
globalThemeFormatSchemeSnapshot;
|
|
23879
24701
|
/** Thumbnail image data from `docProps/thumbnail.jpeg` preserved for round-trip. */
|
|
23880
24702
|
thumbnailData = null;
|
|
23881
24703
|
/** Raw VBA project binary preserved for macro-enabled (.pptm) round-trip. */
|
|
@@ -23886,6 +24708,19 @@ var PptxHandlerRuntime = class {
|
|
|
23886
24708
|
signatureDetection = null;
|
|
23887
24709
|
/** Custom XML data parts parsed from `customXml/` in the OPC package. */
|
|
23888
24710
|
customXmlParts = [];
|
|
24711
|
+
/**
|
|
24712
|
+
* Maps an element's `rawXml` reference to the `mc:AlternateContent`
|
|
24713
|
+
* envelope that originally wrapped it (CC-4). Populated during slide
|
|
24714
|
+
* (and `p:grpSp`) parsing; consulted at save time to re-emit the
|
|
24715
|
+
* original `<mc:Choice>` / `<mc:Fallback>` shape so legacy renderers
|
|
24716
|
+
* keep their fallback content.
|
|
24717
|
+
*
|
|
24718
|
+
* Multiple sibling elements may share the same `AlternateContentBlock`
|
|
24719
|
+
* value (a single AC envelope often wraps several child shapes — e.g.
|
|
24720
|
+
* `p14:media` + its `p:pic` fallback nest one each). WeakMap so AC
|
|
24721
|
+
* envelopes are GC'd if the parsed XmlObject is dropped.
|
|
24722
|
+
*/
|
|
24723
|
+
alternateContentBlockByRawXml = /* @__PURE__ */ new WeakMap();
|
|
23889
24724
|
/** Embedded fonts extracted during load, preserved for automatic re-embedding on save. */
|
|
23890
24725
|
loadedEmbeddedFonts = [];
|
|
23891
24726
|
/** Map of comment author IDs to display names (from `ppt/commentAuthors.xml`). */
|
|
@@ -25699,7 +26534,12 @@ var PptxHandlerRuntime9 = class extends PptxHandlerRuntime8 {
|
|
|
25699
26534
|
const bgColor = this.parseBackgroundColor(bg);
|
|
25700
26535
|
const spTree = master["p:cSld"]?.["p:spTree"];
|
|
25701
26536
|
const placeholders = this.extractPlaceholderList(spTree);
|
|
25702
|
-
|
|
26537
|
+
const result = { path: path2, backgroundColor: bgColor, placeholders };
|
|
26538
|
+
const hf = parseHeaderFooterFlags(master["p:hf"]);
|
|
26539
|
+
if (hf) {
|
|
26540
|
+
result.headerFooter = hf;
|
|
26541
|
+
}
|
|
26542
|
+
return result;
|
|
25703
26543
|
} catch (e) {
|
|
25704
26544
|
console.warn("Failed to parse handout master:", e);
|
|
25705
26545
|
return void 0;
|
|
@@ -25725,7 +26565,12 @@ var PptxHandlerRuntime9 = class extends PptxHandlerRuntime8 {
|
|
|
25725
26565
|
const bgColor = this.parseBackgroundColor(bg);
|
|
25726
26566
|
const spTree = master["p:cSld"]?.["p:spTree"];
|
|
25727
26567
|
const placeholders = this.extractPlaceholderList(spTree);
|
|
25728
|
-
|
|
26568
|
+
const result = { path: path2, backgroundColor: bgColor, placeholders };
|
|
26569
|
+
const hf = parseHeaderFooterFlags(master["p:hf"]);
|
|
26570
|
+
if (hf) {
|
|
26571
|
+
result.headerFooter = hf;
|
|
26572
|
+
}
|
|
26573
|
+
return result;
|
|
25729
26574
|
} catch (e) {
|
|
25730
26575
|
console.warn("Failed to parse notes master:", e);
|
|
25731
26576
|
return void 0;
|
|
@@ -25770,6 +26615,10 @@ var PptxHandlerRuntime9 = class extends PptxHandlerRuntime8 {
|
|
|
25770
26615
|
const uVal = String(userDrawn).trim().toLowerCase();
|
|
25771
26616
|
layout.userDrawn = uVal === "1" || uVal === "true";
|
|
25772
26617
|
}
|
|
26618
|
+
const hf = parseHeaderFooterFlags(sldLayout["p:hf"]);
|
|
26619
|
+
if (hf) {
|
|
26620
|
+
layout.headerFooter = hf;
|
|
26621
|
+
}
|
|
25773
26622
|
const clrMapOvr = sldLayout["p:clrMapOvr"];
|
|
25774
26623
|
if (clrMapOvr && clrMapOvr["a:masterClrMapping"] === void 0) {
|
|
25775
26624
|
const overrideNode = clrMapOvr["a:overrideClrMapping"];
|
|
@@ -26375,6 +27224,18 @@ function buildClrChangeNode(style) {
|
|
|
26375
27224
|
}
|
|
26376
27225
|
|
|
26377
27226
|
// src/core/core/runtime/PptxHandlerRuntimeSaveRunProperties.ts
|
|
27227
|
+
function applyFontMetadata(fontNode, panose, pitchFamily, charset) {
|
|
27228
|
+
if (panose && panose.length > 0) {
|
|
27229
|
+
fontNode["@_panose"] = panose;
|
|
27230
|
+
}
|
|
27231
|
+
if (typeof pitchFamily === "number" && Number.isFinite(pitchFamily)) {
|
|
27232
|
+
fontNode["@_pitchFamily"] = String(pitchFamily);
|
|
27233
|
+
}
|
|
27234
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
27235
|
+
fontNode["@_charset"] = String(charset);
|
|
27236
|
+
}
|
|
27237
|
+
return fontNode;
|
|
27238
|
+
}
|
|
26378
27239
|
var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime11 {
|
|
26379
27240
|
createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId) {
|
|
26380
27241
|
const runProps = {
|
|
@@ -26432,6 +27293,12 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
26432
27293
|
if (style.bookmark) {
|
|
26433
27294
|
runProps["@_bmk"] = style.bookmark;
|
|
26434
27295
|
}
|
|
27296
|
+
if (style.altLanguage) {
|
|
27297
|
+
runProps["@_altLang"] = style.altLanguage;
|
|
27298
|
+
}
|
|
27299
|
+
if (typeof style.smartTagId === "number" && Number.isFinite(style.smartTagId)) {
|
|
27300
|
+
runProps["@_smtId"] = String(style.smartTagId);
|
|
27301
|
+
}
|
|
26435
27302
|
if (style.textOutlineWidth || style.textOutlineColor) {
|
|
26436
27303
|
const lnObj = {};
|
|
26437
27304
|
if (typeof style.textOutlineWidth === "number" && style.textOutlineWidth > 0) {
|
|
@@ -26447,11 +27314,12 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
26447
27314
|
runProps["a:ln"] = lnObj;
|
|
26448
27315
|
}
|
|
26449
27316
|
if (style.color) {
|
|
26450
|
-
|
|
26451
|
-
|
|
26452
|
-
|
|
26453
|
-
|
|
26454
|
-
|
|
27317
|
+
const resolvedOriginalColor = style.colorXml ? this.parseColor(style.colorXml) : void 0;
|
|
27318
|
+
runProps["a:solidFill"] = serializeColorChoice(
|
|
27319
|
+
style.colorXml,
|
|
27320
|
+
resolvedOriginalColor,
|
|
27321
|
+
style.color
|
|
27322
|
+
);
|
|
26455
27323
|
} else if (style.textFillGradientStops && style.textFillGradientStops.length > 0) {
|
|
26456
27324
|
const gradStops = style.textFillGradientStops.filter((stop) => Boolean(stop?.color)).map((stop) => {
|
|
26457
27325
|
const rawPos = (stop.position ?? 0) / 100;
|
|
@@ -26524,16 +27392,32 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
26524
27392
|
};
|
|
26525
27393
|
}
|
|
26526
27394
|
if (style.fontFamily) {
|
|
26527
|
-
runProps["a:latin"] =
|
|
26528
|
-
|
|
26529
|
-
|
|
26530
|
-
|
|
26531
|
-
|
|
26532
|
-
|
|
26533
|
-
|
|
27395
|
+
runProps["a:latin"] = applyFontMetadata(
|
|
27396
|
+
{ "@_typeface": style.fontFamily },
|
|
27397
|
+
style.latinFontPanose,
|
|
27398
|
+
style.latinFontPitchFamily,
|
|
27399
|
+
style.latinFontCharset
|
|
27400
|
+
);
|
|
27401
|
+
runProps["a:ea"] = applyFontMetadata(
|
|
27402
|
+
{ "@_typeface": style.eastAsiaFont || style.fontFamily },
|
|
27403
|
+
style.eastAsiaFontPanose,
|
|
27404
|
+
style.eastAsiaFontPitchFamily,
|
|
27405
|
+
style.eastAsiaFontCharset
|
|
27406
|
+
);
|
|
27407
|
+
runProps["a:cs"] = applyFontMetadata(
|
|
27408
|
+
{ "@_typeface": style.complexScriptFont || style.fontFamily },
|
|
27409
|
+
style.complexScriptFontPanose,
|
|
27410
|
+
style.complexScriptFontPitchFamily,
|
|
27411
|
+
style.complexScriptFontCharset
|
|
27412
|
+
);
|
|
26534
27413
|
}
|
|
26535
27414
|
if (style.symbolFont) {
|
|
26536
|
-
runProps["a:sym"] =
|
|
27415
|
+
runProps["a:sym"] = applyFontMetadata(
|
|
27416
|
+
{ "@_typeface": style.symbolFont },
|
|
27417
|
+
style.symbolFontPanose,
|
|
27418
|
+
style.symbolFontPitchFamily,
|
|
27419
|
+
style.symbolFontCharset
|
|
27420
|
+
);
|
|
26537
27421
|
}
|
|
26538
27422
|
if (style.hyperlink && resolveHyperlinkRelationshipId) {
|
|
26539
27423
|
const hyperlinkTarget = String(style.hyperlink).trim();
|
|
@@ -26608,14 +27492,15 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
|
|
|
26608
27492
|
lineSpacing: this.createLineSpacingXmlFromMultiplier(textStyle?.lineSpacing),
|
|
26609
27493
|
lineSpacingExactPt: textStyle?.lineSpacingExactPt
|
|
26610
27494
|
};
|
|
26611
|
-
const createParagraph = (runs, bulletInfo) => {
|
|
27495
|
+
const createParagraph = (runs, bulletInfo, level, endParaRunProperties) => {
|
|
26612
27496
|
const paragraphProps = buildParagraphPropertiesXml(
|
|
26613
27497
|
textStyle,
|
|
26614
27498
|
paragraphAlign,
|
|
26615
27499
|
bulletInfo,
|
|
26616
|
-
spacing
|
|
27500
|
+
spacing,
|
|
27501
|
+
level
|
|
26617
27502
|
);
|
|
26618
|
-
return assembleParagraphXml(runs, paragraphProps);
|
|
27503
|
+
return assembleParagraphXml(runs, paragraphProps, endParaRunProperties);
|
|
26619
27504
|
};
|
|
26620
27505
|
const createRun = (runText, style) => ({
|
|
26621
27506
|
"a:rPr": this.createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId),
|
|
@@ -26663,13 +27548,19 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
|
|
|
26663
27548
|
const paragraphs = [];
|
|
26664
27549
|
let currentRuns = [];
|
|
26665
27550
|
let currentBulletInfo;
|
|
27551
|
+
let currentLevel;
|
|
27552
|
+
let currentEndParaRunProperties;
|
|
26666
27553
|
const pushParagraph = () => {
|
|
26667
27554
|
if (currentRuns.length === 0) {
|
|
26668
27555
|
currentRuns.push(createRun("", textStyle));
|
|
26669
27556
|
}
|
|
26670
|
-
paragraphs.push(
|
|
27557
|
+
paragraphs.push(
|
|
27558
|
+
createParagraph(currentRuns, currentBulletInfo, currentLevel, currentEndParaRunProperties)
|
|
27559
|
+
);
|
|
26671
27560
|
currentRuns = [];
|
|
26672
27561
|
currentBulletInfo = void 0;
|
|
27562
|
+
currentLevel = void 0;
|
|
27563
|
+
currentEndParaRunProperties = void 0;
|
|
26673
27564
|
};
|
|
26674
27565
|
if (textSegments && textSegments.length > 0) {
|
|
26675
27566
|
const uniformSegmentOverrides = computeUniformSegmentOverrides(textStyle, textSegments);
|
|
@@ -26681,8 +27572,16 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
|
|
|
26681
27572
|
};
|
|
26682
27573
|
const segmentText = String(segment.text ?? "");
|
|
26683
27574
|
const lineParts = segmentText.split("\n");
|
|
26684
|
-
if (currentRuns.length === 0
|
|
26685
|
-
|
|
27575
|
+
if (currentRuns.length === 0) {
|
|
27576
|
+
if (segment.bulletInfo) {
|
|
27577
|
+
currentBulletInfo = segment.bulletInfo;
|
|
27578
|
+
}
|
|
27579
|
+
if (segment.paragraphLevel !== void 0) {
|
|
27580
|
+
currentLevel = segment.paragraphLevel;
|
|
27581
|
+
}
|
|
27582
|
+
if (segment.endParaRunProperties) {
|
|
27583
|
+
currentEndParaRunProperties = segment.endParaRunProperties;
|
|
27584
|
+
}
|
|
26686
27585
|
}
|
|
26687
27586
|
lineParts.forEach((linePart, lineIndex) => {
|
|
26688
27587
|
if (segment.rubyText !== void 0) {
|
|
@@ -26780,7 +27679,201 @@ var PptxHandlerRuntime14 = class extends PptxHandlerRuntime13 {
|
|
|
26780
27679
|
};
|
|
26781
27680
|
|
|
26782
27681
|
// src/core/core/runtime/PptxHandlerRuntimeSaveShapeXml.ts
|
|
27682
|
+
var OLE_OBJECT_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject";
|
|
27683
|
+
var IMAGE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
|
|
27684
|
+
var OLE_GRAPHIC_DATA_URI = "http://schemas.openxmlformats.org/presentationml/2006/ole";
|
|
26783
27685
|
var PptxHandlerRuntime15 = class _PptxHandlerRuntime extends PptxHandlerRuntime14 {
|
|
27686
|
+
/**
|
|
27687
|
+
* Build a `p:graphicFrame` XML skeleton for an SDK-created table.
|
|
27688
|
+
*
|
|
27689
|
+
* Tables round-trip as `<p:graphicFrame>/<a:graphic>/<a:graphicData
|
|
27690
|
+
* uri=".../drawingml/2006/table">/<a:tbl>` inside `p:spTree`. When the
|
|
27691
|
+
* element was loaded from an existing file, `el.rawXml` already contains
|
|
27692
|
+
* this envelope and the downstream `serializeTableDataToXml` path
|
|
27693
|
+
* populates cells in place. When the element was created via the SDK
|
|
27694
|
+
* (`SlideBuilder.addTable`), there is no `rawXml`, so this method
|
|
27695
|
+
* fabricates a minimal envelope with an empty `a:tbl`. The element
|
|
27696
|
+
* writer then calls `serializeTableDataToXml`, which triggers
|
|
27697
|
+
* `rebuildTableXmlFromData` and fills in `a:tblGrid` / `a:tr` children.
|
|
27698
|
+
*/
|
|
27699
|
+
createTableGraphicFrameXml(el) {
|
|
27700
|
+
const EMU = _PptxHandlerRuntime.EMU_PER_PX;
|
|
27701
|
+
const offX = String(Math.round(el.x * EMU));
|
|
27702
|
+
const offY = String(Math.round(el.y * EMU));
|
|
27703
|
+
const extCx = String(Math.round(Math.max(el.width, 1) * EMU));
|
|
27704
|
+
const extCy = String(Math.round(Math.max(el.height, 1) * EMU));
|
|
27705
|
+
const tblPr = {
|
|
27706
|
+
"@_firstRow": el.tableData?.firstRowHeader ? "1" : "0",
|
|
27707
|
+
"@_bandRow": el.tableData?.bandedRows ? "1" : "0"
|
|
27708
|
+
};
|
|
27709
|
+
if (el.tableData?.tableStyleId) {
|
|
27710
|
+
tblPr["a:tableStyleId"] = el.tableData.tableStyleId;
|
|
27711
|
+
}
|
|
27712
|
+
return {
|
|
27713
|
+
"p:nvGraphicFramePr": {
|
|
27714
|
+
"p:cNvPr": { "@_id": "0", "@_name": el.name || "Table" },
|
|
27715
|
+
"p:cNvGraphicFramePr": {
|
|
27716
|
+
"a:graphicFrameLocks": { "@_noGrp": "1" }
|
|
27717
|
+
},
|
|
27718
|
+
"p:nvPr": {}
|
|
27719
|
+
},
|
|
27720
|
+
"p:xfrm": {
|
|
27721
|
+
"a:off": { "@_x": offX, "@_y": offY },
|
|
27722
|
+
"a:ext": { "@_cx": extCx, "@_cy": extCy }
|
|
27723
|
+
},
|
|
27724
|
+
"a:graphic": {
|
|
27725
|
+
"a:graphicData": {
|
|
27726
|
+
"@_uri": "http://schemas.openxmlformats.org/drawingml/2006/table",
|
|
27727
|
+
"a:tbl": {
|
|
27728
|
+
"a:tblPr": tblPr,
|
|
27729
|
+
"a:tblGrid": {}
|
|
27730
|
+
}
|
|
27731
|
+
}
|
|
27732
|
+
}
|
|
27733
|
+
};
|
|
27734
|
+
}
|
|
27735
|
+
/**
|
|
27736
|
+
* Build a `p:graphicFrame` XML skeleton for an OLE object element.
|
|
27737
|
+
*
|
|
27738
|
+
* Used both for SDK-created OLE elements (no `rawXml`) and to refresh
|
|
27739
|
+
* a few key attributes on a loaded element when the typed fields have
|
|
27740
|
+
* been mutated. The output is the canonical
|
|
27741
|
+
* `p:graphicFrame > a:graphic > a:graphicData uri="…/ole" > p:oleObj`
|
|
27742
|
+
* shape per ECMA-376 §19.3.1.34 / §13.3.4.
|
|
27743
|
+
*
|
|
27744
|
+
* The caller (`processSlideElement`) is responsible for ensuring the
|
|
27745
|
+
* embed / preview-image relationships referenced from `r:id` / `r:embed`
|
|
27746
|
+
* exist in the slide's rels file. This method does not register them
|
|
27747
|
+
* itself because the typed model does not currently carry the binary
|
|
27748
|
+
* payload — the binary part must already be in the package (loaded from
|
|
27749
|
+
* the original file). A fully-fabricated SDK OLE element therefore
|
|
27750
|
+
* still requires the consumer to attach the binary out-of-band; this
|
|
27751
|
+
* method simply emits a schema-valid envelope referencing the
|
|
27752
|
+
* specified relationship ID.
|
|
27753
|
+
*/
|
|
27754
|
+
createOleGraphicFrameXml(el, embedRelationshipId) {
|
|
27755
|
+
const EMU = _PptxHandlerRuntime.EMU_PER_PX;
|
|
27756
|
+
const offX = String(Math.round(el.x * EMU));
|
|
27757
|
+
const offY = String(Math.round(el.y * EMU));
|
|
27758
|
+
const extCx = String(Math.round(Math.max(el.width, 1) * EMU));
|
|
27759
|
+
const extCy = String(Math.round(Math.max(el.height, 1) * EMU));
|
|
27760
|
+
const oleObj = {
|
|
27761
|
+
"@_showAsIcon": "0",
|
|
27762
|
+
"@_imgW": extCx,
|
|
27763
|
+
"@_imgH": extCy
|
|
27764
|
+
};
|
|
27765
|
+
if (el.oleProgId) {
|
|
27766
|
+
oleObj["@_progId"] = el.oleProgId;
|
|
27767
|
+
}
|
|
27768
|
+
if (el.oleName) {
|
|
27769
|
+
oleObj["@_name"] = el.oleName;
|
|
27770
|
+
}
|
|
27771
|
+
if (el.oleClsId) {
|
|
27772
|
+
oleObj["@_classid"] = el.oleClsId;
|
|
27773
|
+
}
|
|
27774
|
+
if (embedRelationshipId) {
|
|
27775
|
+
oleObj["@_r:id"] = embedRelationshipId;
|
|
27776
|
+
}
|
|
27777
|
+
if (el.isLinked) {
|
|
27778
|
+
oleObj["p:link"] = {
|
|
27779
|
+
"@_r:id": embedRelationshipId,
|
|
27780
|
+
"@_updateAutomatic": "1"
|
|
27781
|
+
};
|
|
27782
|
+
} else {
|
|
27783
|
+
oleObj["p:embed"] = {};
|
|
27784
|
+
}
|
|
27785
|
+
oleObj["p:pic"] = {
|
|
27786
|
+
"p:nvPicPr": {
|
|
27787
|
+
"p:cNvPr": { "@_id": "0", "@_name": el.oleName || "OleObject" },
|
|
27788
|
+
"p:cNvPicPr": {},
|
|
27789
|
+
"p:nvPr": {}
|
|
27790
|
+
},
|
|
27791
|
+
"p:blipFill": {
|
|
27792
|
+
"a:blip": {},
|
|
27793
|
+
"a:stretch": { "a:fillRect": {} }
|
|
27794
|
+
},
|
|
27795
|
+
"p:spPr": {
|
|
27796
|
+
"a:xfrm": {
|
|
27797
|
+
"a:off": { "@_x": offX, "@_y": offY },
|
|
27798
|
+
"a:ext": { "@_cx": extCx, "@_cy": extCy }
|
|
27799
|
+
},
|
|
27800
|
+
"a:prstGeom": { "@_prst": "rect", "a:avLst": {} }
|
|
27801
|
+
}
|
|
27802
|
+
};
|
|
27803
|
+
return {
|
|
27804
|
+
"p:nvGraphicFramePr": {
|
|
27805
|
+
"p:cNvPr": { "@_id": "0", "@_name": el.oleName || el.fileName || "OleObject" },
|
|
27806
|
+
"p:cNvGraphicFramePr": {
|
|
27807
|
+
"a:graphicFrameLocks": { "@_noChangeAspect": "1" }
|
|
27808
|
+
},
|
|
27809
|
+
"p:nvPr": {}
|
|
27810
|
+
},
|
|
27811
|
+
"p:xfrm": {
|
|
27812
|
+
"a:off": { "@_x": offX, "@_y": offY },
|
|
27813
|
+
"a:ext": { "@_cx": extCx, "@_cy": extCy }
|
|
27814
|
+
},
|
|
27815
|
+
"a:graphic": {
|
|
27816
|
+
"a:graphicData": {
|
|
27817
|
+
"@_uri": OLE_GRAPHIC_DATA_URI,
|
|
27818
|
+
"p:oleObj": oleObj
|
|
27819
|
+
}
|
|
27820
|
+
}
|
|
27821
|
+
};
|
|
27822
|
+
}
|
|
27823
|
+
/**
|
|
27824
|
+
* Refresh editable typed-field attributes on a loaded OLE graphicFrame's
|
|
27825
|
+
* raw XML. Only attributes that round-trip through the typed model
|
|
27826
|
+
* (`progId`, `name`, `classid`) are touched so unknown extension data
|
|
27827
|
+
* passes through verbatim.
|
|
27828
|
+
*/
|
|
27829
|
+
applyOleTypedFieldUpdates(shape, el) {
|
|
27830
|
+
const oleObj = shape["a:graphic"]?.["a:graphicData"]?.["p:oleObj"];
|
|
27831
|
+
if (!oleObj) {
|
|
27832
|
+
return;
|
|
27833
|
+
}
|
|
27834
|
+
if (el.oleProgId) {
|
|
27835
|
+
oleObj["@_progId"] = el.oleProgId;
|
|
27836
|
+
}
|
|
27837
|
+
if (el.oleName !== void 0) {
|
|
27838
|
+
if (el.oleName.length > 0) {
|
|
27839
|
+
oleObj["@_name"] = el.oleName;
|
|
27840
|
+
} else {
|
|
27841
|
+
delete oleObj["@_name"];
|
|
27842
|
+
}
|
|
27843
|
+
}
|
|
27844
|
+
if (el.oleClsId) {
|
|
27845
|
+
oleObj["@_classid"] = el.oleClsId;
|
|
27846
|
+
}
|
|
27847
|
+
}
|
|
27848
|
+
/** Look up the existing OLE binary relationship ID for this slide, if any. */
|
|
27849
|
+
resolveOleEmbedRelationshipId(slideRelationships, oleTarget) {
|
|
27850
|
+
if (!oleTarget) {
|
|
27851
|
+
return void 0;
|
|
27852
|
+
}
|
|
27853
|
+
const normalisedTarget = oleTarget.replace(/^ppt\//, "../").replace(/^\/+/, "");
|
|
27854
|
+
const lowerTarget = normalisedTarget.toLowerCase();
|
|
27855
|
+
for (const rel of slideRelationships) {
|
|
27856
|
+
const relType = String(rel?.["@_Type"] || "");
|
|
27857
|
+
if (relType !== OLE_OBJECT_RELATIONSHIP_TYPE) {
|
|
27858
|
+
continue;
|
|
27859
|
+
}
|
|
27860
|
+
const target = String(rel?.["@_Target"] || "").toLowerCase().trim();
|
|
27861
|
+
if (target === lowerTarget || target.endsWith(lowerTarget) || lowerTarget.endsWith(target)) {
|
|
27862
|
+
const relId = String(rel?.["@_Id"] || "").trim();
|
|
27863
|
+
if (relId.length > 0) {
|
|
27864
|
+
return relId;
|
|
27865
|
+
}
|
|
27866
|
+
}
|
|
27867
|
+
}
|
|
27868
|
+
const fallback = slideRelationships.find(
|
|
27869
|
+
(rel) => String(rel?.["@_Type"] || "") === OLE_OBJECT_RELATIONSHIP_TYPE
|
|
27870
|
+
);
|
|
27871
|
+
const fallbackId = String(fallback?.["@_Id"] || "").trim();
|
|
27872
|
+
return fallbackId.length > 0 ? fallbackId : void 0;
|
|
27873
|
+
}
|
|
27874
|
+
/** Constants are exposed so the element-writer mixin can reuse them. */
|
|
27875
|
+
static OLE_OBJECT_RELATIONSHIP_TYPE = OLE_OBJECT_RELATIONSHIP_TYPE;
|
|
27876
|
+
static OLE_IMAGE_RELATIONSHIP_TYPE = IMAGE_RELATIONSHIP_TYPE;
|
|
26784
27877
|
/**
|
|
26785
27878
|
* Build a p:sp XML object for an ink annotation element.
|
|
26786
27879
|
* Each ink path becomes a separate a:path within a:pathLst,
|
|
@@ -27097,6 +28190,9 @@ var PptxHandlerRuntime16 = class extends PptxHandlerRuntime15 {
|
|
|
27097
28190
|
buildOuterShadowXml(shapeStyle) {
|
|
27098
28191
|
return this.colorStyleCodec.buildOuterShadowXml(shapeStyle);
|
|
27099
28192
|
}
|
|
28193
|
+
buildPresetShadowXml(shapeStyle) {
|
|
28194
|
+
return this.colorStyleCodec.buildPresetShadowXml(shapeStyle);
|
|
28195
|
+
}
|
|
27100
28196
|
buildInnerShadowXml(shapeStyle) {
|
|
27101
28197
|
return this.colorStyleCodec.buildInnerShadowXml(shapeStyle);
|
|
27102
28198
|
}
|
|
@@ -27647,6 +28743,10 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
27647
28743
|
const solidFill = runProperties["a:solidFill"];
|
|
27648
28744
|
if (solidFill) {
|
|
27649
28745
|
style.color = this.parseColor(solidFill);
|
|
28746
|
+
const colorXml = extractColorChoiceXml(solidFill);
|
|
28747
|
+
if (colorXml) {
|
|
28748
|
+
style.colorXml = colorXml;
|
|
28749
|
+
}
|
|
27650
28750
|
}
|
|
27651
28751
|
this.applyHyperlinkStyle(style, runProperties, relationshipMap);
|
|
27652
28752
|
const capAttr = String(runProperties["@_cap"] || "").trim().toLowerCase();
|
|
@@ -27694,12 +28794,86 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
27694
28794
|
if (bmk) {
|
|
27695
28795
|
style.bookmark = bmk;
|
|
27696
28796
|
}
|
|
28797
|
+
const altLang = String(runProperties["@_altLang"] || "").trim();
|
|
28798
|
+
if (altLang) {
|
|
28799
|
+
style.altLanguage = altLang;
|
|
28800
|
+
}
|
|
28801
|
+
if (runProperties["@_smtId"] !== void 0) {
|
|
28802
|
+
const smtIdRaw = Number.parseInt(String(runProperties["@_smtId"]), 10);
|
|
28803
|
+
if (Number.isFinite(smtIdRaw)) {
|
|
28804
|
+
style.smartTagId = smtIdRaw;
|
|
28805
|
+
}
|
|
28806
|
+
}
|
|
28807
|
+
this.applyTextFontMetadata(style, latin, "latin");
|
|
28808
|
+
this.applyTextFontMetadata(style, eastAsian, "eastAsia");
|
|
28809
|
+
this.applyTextFontMetadata(style, complexScript, "complexScript");
|
|
28810
|
+
this.applyTextFontMetadata(style, runProperties["a:sym"], "symbol");
|
|
27697
28811
|
const runEffectList = runProperties["a:effectLst"];
|
|
27698
28812
|
if (runEffectList) {
|
|
27699
28813
|
this.applyTextRunEffects(style, runEffectList);
|
|
27700
28814
|
}
|
|
27701
28815
|
return style;
|
|
27702
28816
|
}
|
|
28817
|
+
/**
|
|
28818
|
+
* Copy `@panose` / `@pitchFamily` / `@charset` from a font child node
|
|
28819
|
+
* (`a:latin`, `a:ea`, `a:cs`, `a:sym`) onto the matching `*Font*`
|
|
28820
|
+
* fields of `style`.
|
|
28821
|
+
*/
|
|
28822
|
+
applyTextFontMetadata(style, fontNode, kind) {
|
|
28823
|
+
if (!fontNode) {
|
|
28824
|
+
return;
|
|
28825
|
+
}
|
|
28826
|
+
const panose = String(fontNode["@_panose"] || "").trim();
|
|
28827
|
+
const pitchRaw = fontNode["@_pitchFamily"];
|
|
28828
|
+
const charsetRaw = fontNode["@_charset"];
|
|
28829
|
+
const pitch = pitchRaw !== void 0 && pitchRaw !== null ? Number.parseInt(String(pitchRaw), 10) : void 0;
|
|
28830
|
+
const charset = charsetRaw !== void 0 && charsetRaw !== null ? Number.parseInt(String(charsetRaw), 10) : void 0;
|
|
28831
|
+
if (kind === "latin") {
|
|
28832
|
+
if (panose) {
|
|
28833
|
+
style.latinFontPanose = panose;
|
|
28834
|
+
}
|
|
28835
|
+
if (typeof pitch === "number" && Number.isFinite(pitch)) {
|
|
28836
|
+
style.latinFontPitchFamily = pitch;
|
|
28837
|
+
}
|
|
28838
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
28839
|
+
style.latinFontCharset = charset;
|
|
28840
|
+
}
|
|
28841
|
+
return;
|
|
28842
|
+
}
|
|
28843
|
+
if (kind === "eastAsia") {
|
|
28844
|
+
if (panose) {
|
|
28845
|
+
style.eastAsiaFontPanose = panose;
|
|
28846
|
+
}
|
|
28847
|
+
if (typeof pitch === "number" && Number.isFinite(pitch)) {
|
|
28848
|
+
style.eastAsiaFontPitchFamily = pitch;
|
|
28849
|
+
}
|
|
28850
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
28851
|
+
style.eastAsiaFontCharset = charset;
|
|
28852
|
+
}
|
|
28853
|
+
return;
|
|
28854
|
+
}
|
|
28855
|
+
if (kind === "complexScript") {
|
|
28856
|
+
if (panose) {
|
|
28857
|
+
style.complexScriptFontPanose = panose;
|
|
28858
|
+
}
|
|
28859
|
+
if (typeof pitch === "number" && Number.isFinite(pitch)) {
|
|
28860
|
+
style.complexScriptFontPitchFamily = pitch;
|
|
28861
|
+
}
|
|
28862
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
28863
|
+
style.complexScriptFontCharset = charset;
|
|
28864
|
+
}
|
|
28865
|
+
return;
|
|
28866
|
+
}
|
|
28867
|
+
if (panose) {
|
|
28868
|
+
style.symbolFontPanose = panose;
|
|
28869
|
+
}
|
|
28870
|
+
if (typeof pitch === "number" && Number.isFinite(pitch)) {
|
|
28871
|
+
style.symbolFontPitchFamily = pitch;
|
|
28872
|
+
}
|
|
28873
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
28874
|
+
style.symbolFontCharset = charset;
|
|
28875
|
+
}
|
|
28876
|
+
}
|
|
27703
28877
|
};
|
|
27704
28878
|
|
|
27705
28879
|
// src/core/core/runtime/PptxHandlerRuntimeTextEditing.ts
|
|
@@ -28135,7 +29309,7 @@ var PptxHandlerRuntime21 = class extends PptxHandlerRuntime20 {
|
|
|
28135
29309
|
};
|
|
28136
29310
|
|
|
28137
29311
|
// src/core/core/runtime/table-cell-save-helpers.ts
|
|
28138
|
-
function writeCellFill(tcPr, style) {
|
|
29312
|
+
function writeCellFill(tcPr, style, resolveColorXml) {
|
|
28139
29313
|
if (style.fillMode === "gradient" && style.gradientFillStops && style.gradientFillStops.length > 0) {
|
|
28140
29314
|
delete tcPr["a:solidFill"];
|
|
28141
29315
|
delete tcPr["a:pattFill"];
|
|
@@ -28214,11 +29388,12 @@ function writeCellFill(tcPr, style) {
|
|
|
28214
29388
|
} else if (style.backgroundColor) {
|
|
28215
29389
|
delete tcPr["a:gradFill"];
|
|
28216
29390
|
delete tcPr["a:pattFill"];
|
|
28217
|
-
|
|
28218
|
-
|
|
28219
|
-
|
|
28220
|
-
|
|
28221
|
-
|
|
29391
|
+
const resolvedOriginal = style.backgroundColorXml && resolveColorXml ? resolveColorXml(style.backgroundColorXml) : void 0;
|
|
29392
|
+
tcPr["a:solidFill"] = serializeColorChoice(
|
|
29393
|
+
style.backgroundColorXml,
|
|
29394
|
+
resolvedOriginal,
|
|
29395
|
+
style.backgroundColor
|
|
29396
|
+
);
|
|
28222
29397
|
}
|
|
28223
29398
|
}
|
|
28224
29399
|
function writeDiagonalBorders(tcPr, style, emuPerPx) {
|
|
@@ -28262,14 +29437,15 @@ function writeCellTextFormatting(xmlCell, style, ensureArray6) {
|
|
|
28262
29437
|
const paragraphs = ensureArray6(xmlCell["a:txBody"]?.["a:p"]);
|
|
28263
29438
|
for (const paragraph of paragraphs) {
|
|
28264
29439
|
const runs = ensureArray6(paragraph?.["a:r"]);
|
|
29440
|
+
const rebuiltRuns = [];
|
|
29441
|
+
let runsChanged = false;
|
|
28265
29442
|
for (const run of runs) {
|
|
28266
29443
|
if (!run) {
|
|
29444
|
+
rebuiltRuns.push(run);
|
|
28267
29445
|
continue;
|
|
28268
29446
|
}
|
|
28269
|
-
|
|
28270
|
-
|
|
28271
|
-
}
|
|
28272
|
-
const rPr = run["a:rPr"];
|
|
29447
|
+
const existingRPr = run["a:rPr"] ?? {};
|
|
29448
|
+
const rPr = { ...existingRPr };
|
|
28273
29449
|
if (style.bold !== void 0) {
|
|
28274
29450
|
rPr["@_b"] = style.bold ? "1" : "0";
|
|
28275
29451
|
}
|
|
@@ -28289,6 +29465,18 @@ function writeCellTextFormatting(xmlCell, style, ensureArray6) {
|
|
|
28289
29465
|
}
|
|
28290
29466
|
};
|
|
28291
29467
|
}
|
|
29468
|
+
const rebuilt = { "a:rPr": rPr };
|
|
29469
|
+
for (const key of Object.keys(run)) {
|
|
29470
|
+
if (key === "a:rPr") {
|
|
29471
|
+
continue;
|
|
29472
|
+
}
|
|
29473
|
+
rebuilt[key] = run[key];
|
|
29474
|
+
}
|
|
29475
|
+
rebuiltRuns.push(rebuilt);
|
|
29476
|
+
runsChanged = true;
|
|
29477
|
+
}
|
|
29478
|
+
if (runsChanged && rebuiltRuns.length > 0) {
|
|
29479
|
+
paragraph["a:r"] = rebuiltRuns.length === 1 ? rebuiltRuns[0] : rebuiltRuns;
|
|
28292
29480
|
}
|
|
28293
29481
|
}
|
|
28294
29482
|
}
|
|
@@ -28310,6 +29498,9 @@ var PptxHandlerRuntime22 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
28310
29498
|
const existingParagraphs = this.ensureArray(txBody["a:p"]);
|
|
28311
29499
|
const firstRPr = this.ensureArray(existingParagraphs[0]?.["a:r"])[0]?.["a:rPr"];
|
|
28312
29500
|
const firstPPr = existingParagraphs[0]?.["a:pPr"];
|
|
29501
|
+
const firstEndParaRPr = existingParagraphs[0]?.["a:endParaRPr"];
|
|
29502
|
+
const rPrForRun = firstRPr ? { ...firstRPr } : { "@_lang": "en-US", "@_dirty": "0" };
|
|
29503
|
+
const endParaRPr = firstEndParaRPr ? { ...firstEndParaRPr } : { "@_lang": "en-US", "@_dirty": "0" };
|
|
28313
29504
|
const lines = text.split("\n");
|
|
28314
29505
|
const paragraphs = lines.map((line) => {
|
|
28315
29506
|
const paragraph = {};
|
|
@@ -28317,9 +29508,10 @@ var PptxHandlerRuntime22 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
28317
29508
|
paragraph["a:pPr"] = firstPPr;
|
|
28318
29509
|
}
|
|
28319
29510
|
paragraph["a:r"] = {
|
|
28320
|
-
|
|
29511
|
+
"a:rPr": rPrForRun,
|
|
28321
29512
|
"a:t": line
|
|
28322
29513
|
};
|
|
29514
|
+
paragraph["a:endParaRPr"] = endParaRPr;
|
|
28323
29515
|
return paragraph;
|
|
28324
29516
|
});
|
|
28325
29517
|
txBody["a:p"] = paragraphs.length === 1 ? paragraphs[0] : paragraphs;
|
|
@@ -28332,7 +29524,7 @@ var PptxHandlerRuntime22 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
28332
29524
|
xmlCell["a:tcPr"] = {};
|
|
28333
29525
|
}
|
|
28334
29526
|
const tcPr = xmlCell["a:tcPr"];
|
|
28335
|
-
writeCellFill(tcPr, style);
|
|
29527
|
+
writeCellFill(tcPr, style, (colorXml) => this.parseColor(colorXml));
|
|
28336
29528
|
if (style.vAlign) {
|
|
28337
29529
|
const vAlignMap = {
|
|
28338
29530
|
top: "t",
|
|
@@ -28414,35 +29606,29 @@ var PptxHandlerRuntime22 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
28414
29606
|
}
|
|
28415
29607
|
}
|
|
28416
29608
|
}
|
|
28417
|
-
|
|
28418
|
-
|
|
28419
|
-
|
|
28420
|
-
|
|
28421
|
-
|
|
28422
|
-
|
|
28423
|
-
|
|
28424
|
-
|
|
28425
|
-
|
|
28426
|
-
|
|
28427
|
-
|
|
28428
|
-
|
|
28429
|
-
tcMar["a:marR"] = {
|
|
28430
|
-
"@_w": String(Math.round(style.marginRight * emuPerPx))
|
|
28431
|
-
};
|
|
28432
|
-
}
|
|
28433
|
-
if (style.marginTop !== void 0) {
|
|
28434
|
-
tcMar["a:marT"] = {
|
|
28435
|
-
"@_w": String(Math.round(style.marginTop * emuPerPx))
|
|
28436
|
-
};
|
|
28437
|
-
}
|
|
28438
|
-
if (style.marginBottom !== void 0) {
|
|
28439
|
-
tcMar["a:marB"] = {
|
|
28440
|
-
"@_w": String(Math.round(style.marginBottom * emuPerPx))
|
|
28441
|
-
};
|
|
28442
|
-
}
|
|
29609
|
+
const emuPerPx = _PptxHandlerRuntime.EMU_PER_PX;
|
|
29610
|
+
if (style.marginLeft !== void 0) {
|
|
29611
|
+
tcPr["@_marL"] = String(Math.round(style.marginLeft * emuPerPx));
|
|
29612
|
+
}
|
|
29613
|
+
if (style.marginRight !== void 0) {
|
|
29614
|
+
tcPr["@_marR"] = String(Math.round(style.marginRight * emuPerPx));
|
|
29615
|
+
}
|
|
29616
|
+
if (style.marginTop !== void 0) {
|
|
29617
|
+
tcPr["@_marT"] = String(Math.round(style.marginTop * emuPerPx));
|
|
29618
|
+
}
|
|
29619
|
+
if (style.marginBottom !== void 0) {
|
|
29620
|
+
tcPr["@_marB"] = String(Math.round(style.marginBottom * emuPerPx));
|
|
28443
29621
|
}
|
|
29622
|
+
delete tcPr["a:tcMar"];
|
|
28444
29623
|
writeDiagonalBorders(tcPr, style, _PptxHandlerRuntime.EMU_PER_PX);
|
|
28445
29624
|
writeCellTextFormatting(xmlCell, style, this.ensureArray.bind(this));
|
|
29625
|
+
const reordered = reorderObjectKeys(tcPr, TC_PR_BORDERS_ORDER);
|
|
29626
|
+
for (const key of Object.keys(tcPr)) {
|
|
29627
|
+
delete tcPr[key];
|
|
29628
|
+
}
|
|
29629
|
+
for (const key of Object.keys(reordered)) {
|
|
29630
|
+
tcPr[key] = reordered[key];
|
|
29631
|
+
}
|
|
28446
29632
|
}
|
|
28447
29633
|
};
|
|
28448
29634
|
|
|
@@ -28469,14 +29655,27 @@ function serializeCellMergeAttributes(xmlCell, cell) {
|
|
|
28469
29655
|
delete xmlCell["@_vMerge"];
|
|
28470
29656
|
}
|
|
28471
29657
|
}
|
|
29658
|
+
var DEFAULT_POWERPOINT_TABLE_STYLE_ID = "{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}";
|
|
28472
29659
|
function serializeTablePropertyFlags(tbl, tableData) {
|
|
28473
29660
|
const tblPr = tbl["a:tblPr"] ?? {};
|
|
28474
|
-
|
|
28475
|
-
|
|
28476
|
-
|
|
28477
|
-
|
|
28478
|
-
|
|
28479
|
-
|
|
29661
|
+
const setOrDelete = (key, truthy) => {
|
|
29662
|
+
if (truthy) {
|
|
29663
|
+
tblPr[key] = "1";
|
|
29664
|
+
} else {
|
|
29665
|
+
delete tblPr[key];
|
|
29666
|
+
}
|
|
29667
|
+
};
|
|
29668
|
+
setOrDelete("@_bandRow", tableData.bandedRows);
|
|
29669
|
+
setOrDelete("@_bandCol", tableData.bandedColumns);
|
|
29670
|
+
setOrDelete("@_firstRow", tableData.firstRowHeader);
|
|
29671
|
+
setOrDelete("@_lastRow", tableData.lastRow);
|
|
29672
|
+
setOrDelete("@_firstCol", tableData.firstCol);
|
|
29673
|
+
setOrDelete("@_lastCol", tableData.lastCol);
|
|
29674
|
+
if (tableData.tableStyleId) {
|
|
29675
|
+
tblPr["a:tableStyleId"] = tableData.tableStyleId;
|
|
29676
|
+
} else if (!tblPr["a:tableStyleId"]) {
|
|
29677
|
+
tblPr["a:tableStyleId"] = DEFAULT_POWERPOINT_TABLE_STYLE_ID;
|
|
29678
|
+
}
|
|
28480
29679
|
tbl["a:tblPr"] = tblPr;
|
|
28481
29680
|
}
|
|
28482
29681
|
function replaceFirstTextValueInTree(node, localName, newValue, getXmlLocalName) {
|
|
@@ -28521,7 +29720,9 @@ function createDefaultXmlCell() {
|
|
|
28521
29720
|
"a:bodyPr": {},
|
|
28522
29721
|
"a:lstStyle": {},
|
|
28523
29722
|
"a:p": {
|
|
28524
|
-
|
|
29723
|
+
// Match PowerPoint's "Insert Table" default: every paragraph-end
|
|
29724
|
+
// run carries `lang="en-US" dirty="0"`.
|
|
29725
|
+
"a:endParaRPr": { "@_lang": "en-US", "@_dirty": "0" }
|
|
28525
29726
|
}
|
|
28526
29727
|
},
|
|
28527
29728
|
"a:tcPr": {}
|
|
@@ -28529,6 +29730,54 @@ function createDefaultXmlCell() {
|
|
|
28529
29730
|
}
|
|
28530
29731
|
|
|
28531
29732
|
// src/core/core/runtime/table-xml-rebuild.ts
|
|
29733
|
+
var GRID_COL_ID_EXT_URI = "{9D8B030D-6E8A-4147-A177-3AD203B41FA5}";
|
|
29734
|
+
var A16_NAMESPACE = "http://schemas.microsoft.com/office/drawing/2014/main";
|
|
29735
|
+
function ensureA16NamespaceOnSlideRoot(slideRoot) {
|
|
29736
|
+
if (!slideRoot["@_xmlns:a16"]) {
|
|
29737
|
+
slideRoot["@_xmlns:a16"] = A16_NAMESPACE;
|
|
29738
|
+
}
|
|
29739
|
+
if (!slideRoot["@_xmlns:mc"]) {
|
|
29740
|
+
slideRoot["@_xmlns:mc"] = "http://schemas.openxmlformats.org/markup-compatibility/2006";
|
|
29741
|
+
}
|
|
29742
|
+
const existingIgnorable = String(slideRoot["@_mc:Ignorable"] || "").trim();
|
|
29743
|
+
if (existingIgnorable.length === 0) {
|
|
29744
|
+
slideRoot["@_mc:Ignorable"] = "a16";
|
|
29745
|
+
return;
|
|
29746
|
+
}
|
|
29747
|
+
const tokens = existingIgnorable.split(/\s+/).filter((token) => token.length > 0);
|
|
29748
|
+
if (!tokens.includes("a16")) {
|
|
29749
|
+
tokens.push("a16");
|
|
29750
|
+
slideRoot["@_mc:Ignorable"] = tokens.join(" ");
|
|
29751
|
+
}
|
|
29752
|
+
}
|
|
29753
|
+
function slideContainsA16Element(node) {
|
|
29754
|
+
if (node === null || node === void 0) {
|
|
29755
|
+
return false;
|
|
29756
|
+
}
|
|
29757
|
+
if (Array.isArray(node)) {
|
|
29758
|
+
for (const entry of node) {
|
|
29759
|
+
if (slideContainsA16Element(entry)) {
|
|
29760
|
+
return true;
|
|
29761
|
+
}
|
|
29762
|
+
}
|
|
29763
|
+
return false;
|
|
29764
|
+
}
|
|
29765
|
+
if (typeof node !== "object") {
|
|
29766
|
+
return false;
|
|
29767
|
+
}
|
|
29768
|
+
for (const [key, value] of Object.entries(node)) {
|
|
29769
|
+
if (key.startsWith("a16:")) {
|
|
29770
|
+
return true;
|
|
29771
|
+
}
|
|
29772
|
+
if (slideContainsA16Element(value)) {
|
|
29773
|
+
return true;
|
|
29774
|
+
}
|
|
29775
|
+
}
|
|
29776
|
+
return false;
|
|
29777
|
+
}
|
|
29778
|
+
function randomColumnId() {
|
|
29779
|
+
return String(Math.floor(Math.random() * 4294967295));
|
|
29780
|
+
}
|
|
28532
29781
|
function rebuildTableXmlFromData(tbl, tableData, emuPerPx, ensureArrayFn) {
|
|
28533
29782
|
const existingXmlRows = ensureArrayFn(tbl["a:tr"]);
|
|
28534
29783
|
const existingGridCols = ensureArrayFn(
|
|
@@ -28537,8 +29786,33 @@ function rebuildTableXmlFromData(tbl, tableData, emuPerPx, ensureArrayFn) {
|
|
|
28537
29786
|
const totalWidthEmu = existingGridCols.reduce((sum, col) => {
|
|
28538
29787
|
return sum + (parseInt(String(col?.["@_w"] || "0"), 10) || 0);
|
|
28539
29788
|
}, 0) || 9144e3;
|
|
28540
|
-
const
|
|
28541
|
-
|
|
29789
|
+
const existingColIds = existingGridCols.map((col) => {
|
|
29790
|
+
const extList = col?.["a:extLst"];
|
|
29791
|
+
const exts = Array.isArray(extList?.["a:ext"]) ? extList["a:ext"] : extList?.["a:ext"] ? [extList["a:ext"]] : [];
|
|
29792
|
+
for (const ext of exts) {
|
|
29793
|
+
if (ext?.["@_uri"] === GRID_COL_ID_EXT_URI) {
|
|
29794
|
+
const colId = ext["a16:colId"];
|
|
29795
|
+
const val = colId?.["@_val"];
|
|
29796
|
+
if (typeof val === "string" && val.length > 0) {
|
|
29797
|
+
return val;
|
|
29798
|
+
}
|
|
29799
|
+
}
|
|
29800
|
+
}
|
|
29801
|
+
return "";
|
|
29802
|
+
});
|
|
29803
|
+
const newGridCols = tableData.columnWidths.map((w, i) => ({
|
|
29804
|
+
"@_w": String(Math.round(w * totalWidthEmu)),
|
|
29805
|
+
"a:extLst": {
|
|
29806
|
+
"a:ext": {
|
|
29807
|
+
"@_uri": GRID_COL_ID_EXT_URI,
|
|
29808
|
+
// `xmlns:a16` is declared on the slide root by
|
|
29809
|
+
// `ensureA16NamespaceOnSlideRoot`; emitting it here too is
|
|
29810
|
+
// schema-redundant and PowerPoint flags it.
|
|
29811
|
+
"a16:colId": {
|
|
29812
|
+
"@_val": existingColIds[i] || randomColumnId()
|
|
29813
|
+
}
|
|
29814
|
+
}
|
|
29815
|
+
}
|
|
28542
29816
|
}));
|
|
28543
29817
|
if (!tbl["a:tblGrid"]) {
|
|
28544
29818
|
tbl["a:tblGrid"] = {};
|
|
@@ -28893,26 +30167,64 @@ var PptxHandlerRuntime23 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
28893
30167
|
continue;
|
|
28894
30168
|
}
|
|
28895
30169
|
const scalingNode = this.xmlLookupService.getChildByLocalName(axisNode, "scaling");
|
|
28896
|
-
if (
|
|
28897
|
-
|
|
30170
|
+
if (scalingNode) {
|
|
30171
|
+
if (matchingAxis.logBase !== void 0 && matchingAxis.logBase > 0) {
|
|
30172
|
+
const logBaseKey = Object.keys(scalingNode).find(
|
|
30173
|
+
(k) => this.compatibilityService.getXmlLocalName(k) === "logBase"
|
|
30174
|
+
);
|
|
30175
|
+
if (logBaseKey) {
|
|
30176
|
+
scalingNode[logBaseKey]["@_val"] = String(matchingAxis.logBase);
|
|
30177
|
+
} else {
|
|
30178
|
+
scalingNode["c:logBase"] = {
|
|
30179
|
+
"@_val": String(matchingAxis.logBase)
|
|
30180
|
+
};
|
|
30181
|
+
}
|
|
30182
|
+
} else if (matchingAxis.logScale === false) {
|
|
30183
|
+
const logBaseKey = Object.keys(scalingNode).find(
|
|
30184
|
+
(k) => this.compatibilityService.getXmlLocalName(k) === "logBase"
|
|
30185
|
+
);
|
|
30186
|
+
if (logBaseKey) {
|
|
30187
|
+
delete scalingNode[logBaseKey];
|
|
30188
|
+
}
|
|
30189
|
+
}
|
|
30190
|
+
this.upsertChartAxisChild(
|
|
30191
|
+
scalingNode,
|
|
30192
|
+
"min",
|
|
30193
|
+
matchingAxis.min !== void 0 ? String(matchingAxis.min) : void 0
|
|
30194
|
+
);
|
|
30195
|
+
this.upsertChartAxisChild(
|
|
30196
|
+
scalingNode,
|
|
30197
|
+
"max",
|
|
30198
|
+
matchingAxis.max !== void 0 ? String(matchingAxis.max) : void 0
|
|
30199
|
+
);
|
|
28898
30200
|
}
|
|
28899
|
-
if (matchingAxis.
|
|
28900
|
-
const
|
|
28901
|
-
(k) => this.compatibilityService.getXmlLocalName(k) === "
|
|
30201
|
+
if (matchingAxis.numFmt) {
|
|
30202
|
+
const numFmtKey = Object.keys(axisNode).find(
|
|
30203
|
+
(k) => this.compatibilityService.getXmlLocalName(k) === "numFmt"
|
|
28902
30204
|
);
|
|
28903
|
-
|
|
28904
|
-
|
|
30205
|
+
const numFmtAttrs = {
|
|
30206
|
+
"@_formatCode": matchingAxis.numFmt.formatCode,
|
|
30207
|
+
"@_sourceLinked": matchingAxis.numFmt.sourceLinked ? "1" : "0"
|
|
30208
|
+
};
|
|
30209
|
+
if (numFmtKey) {
|
|
30210
|
+
axisNode[numFmtKey] = numFmtAttrs;
|
|
28905
30211
|
} else {
|
|
28906
|
-
|
|
28907
|
-
"@_val": String(matchingAxis.logBase)
|
|
28908
|
-
};
|
|
30212
|
+
axisNode["c:numFmt"] = numFmtAttrs;
|
|
28909
30213
|
}
|
|
28910
|
-
}
|
|
28911
|
-
|
|
28912
|
-
|
|
30214
|
+
}
|
|
30215
|
+
this.upsertChartAxisChild(
|
|
30216
|
+
axisNode,
|
|
30217
|
+
"majorUnit",
|
|
30218
|
+
matchingAxis.majorUnit !== void 0 ? String(matchingAxis.majorUnit) : void 0
|
|
30219
|
+
);
|
|
30220
|
+
if (matchingAxis.tickLblPos !== void 0) {
|
|
30221
|
+
const tickLblKey = Object.keys(axisNode).find(
|
|
30222
|
+
(k) => this.compatibilityService.getXmlLocalName(k) === "tickLblPos"
|
|
28913
30223
|
);
|
|
28914
|
-
if (
|
|
28915
|
-
|
|
30224
|
+
if (tickLblKey) {
|
|
30225
|
+
axisNode[tickLblKey]["@_val"] = matchingAxis.tickLblPos;
|
|
30226
|
+
} else {
|
|
30227
|
+
axisNode["c:tickLblPos"] = { "@_val": matchingAxis.tickLblPos };
|
|
28916
30228
|
}
|
|
28917
30229
|
}
|
|
28918
30230
|
}
|
|
@@ -28925,6 +30237,18 @@ var PptxHandlerRuntime23 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
28925
30237
|
}
|
|
28926
30238
|
this.pendingChartUpdates = void 0;
|
|
28927
30239
|
}
|
|
30240
|
+
/**
|
|
30241
|
+
* Upsert a `c:<localName>` child with `@_val` on an axis or scaling node.
|
|
30242
|
+
* When `value` is undefined, removes any existing child of that local name.
|
|
30243
|
+
*/
|
|
30244
|
+
upsertChartAxisChild(parent, localName, value) {
|
|
30245
|
+
upsertChartAxisChild(
|
|
30246
|
+
parent,
|
|
30247
|
+
localName,
|
|
30248
|
+
value,
|
|
30249
|
+
(key) => this.compatibilityService.getXmlLocalName(key)
|
|
30250
|
+
);
|
|
30251
|
+
}
|
|
28928
30252
|
/**
|
|
28929
30253
|
* Update the cached point values in a chart reference node
|
|
28930
30254
|
* (numRef/strRef or numLit/strLit).
|
|
@@ -30204,17 +31528,13 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30204
31528
|
delete spPr["a:noFill"];
|
|
30205
31529
|
delete spPr["a:gradFill"];
|
|
30206
31530
|
delete spPr["a:blipFill"];
|
|
30207
|
-
const
|
|
30208
|
-
|
|
30209
|
-
|
|
30210
|
-
|
|
30211
|
-
|
|
30212
|
-
|
|
30213
|
-
|
|
30214
|
-
"@_val": String(Math.round(this.clampUnitInterval(shapeStyle.fillOpacity) * 1e5))
|
|
30215
|
-
};
|
|
30216
|
-
}
|
|
30217
|
-
spPr["a:solidFill"] = solidFill;
|
|
31531
|
+
const resolvedOriginal = shapeStyle.fillColorXml ? this.parseColor(shapeStyle.fillColorXml) : void 0;
|
|
31532
|
+
spPr["a:solidFill"] = serializeColorChoice(
|
|
31533
|
+
shapeStyle.fillColorXml,
|
|
31534
|
+
resolvedOriginal,
|
|
31535
|
+
fillColor,
|
|
31536
|
+
shapeStyle.fillOpacity
|
|
31537
|
+
);
|
|
30218
31538
|
}
|
|
30219
31539
|
}
|
|
30220
31540
|
if (shapeStyle.strokeColor !== void 0) {
|
|
@@ -30229,17 +31549,13 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30229
31549
|
delete lineNode["a:solidFill"];
|
|
30230
31550
|
} else {
|
|
30231
31551
|
delete lineNode["a:noFill"];
|
|
30232
|
-
const
|
|
30233
|
-
|
|
30234
|
-
|
|
30235
|
-
|
|
30236
|
-
|
|
30237
|
-
|
|
30238
|
-
|
|
30239
|
-
"@_val": String(Math.round(this.clampUnitInterval(shapeStyle.strokeOpacity) * 1e5))
|
|
30240
|
-
};
|
|
30241
|
-
}
|
|
30242
|
-
lineNode["a:solidFill"] = lineFill;
|
|
31552
|
+
const resolvedStrokeOriginal = shapeStyle.strokeColorXml ? this.parseColor(shapeStyle.strokeColorXml) : void 0;
|
|
31553
|
+
lineNode["a:solidFill"] = serializeColorChoice(
|
|
31554
|
+
shapeStyle.strokeColorXml,
|
|
31555
|
+
resolvedStrokeOriginal,
|
|
31556
|
+
shapeStyle.strokeColor,
|
|
31557
|
+
shapeStyle.strokeOpacity
|
|
31558
|
+
);
|
|
30243
31559
|
}
|
|
30244
31560
|
}
|
|
30245
31561
|
if (shapeStyle.strokeDash !== void 0) {
|
|
@@ -30320,7 +31636,11 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30320
31636
|
} else if (shapeStyle.lineJoin === "bevel") {
|
|
30321
31637
|
lineNode["a:bevel"] = {};
|
|
30322
31638
|
} else if (shapeStyle.lineJoin === "miter") {
|
|
30323
|
-
|
|
31639
|
+
const miterNode = {};
|
|
31640
|
+
if (typeof shapeStyle.miterLimit === "number" && Number.isFinite(shapeStyle.miterLimit) && shapeStyle.miterLimit !== 8e5) {
|
|
31641
|
+
miterNode["@_lim"] = String(Math.round(shapeStyle.miterLimit));
|
|
31642
|
+
}
|
|
31643
|
+
lineNode["a:miter"] = miterNode;
|
|
30324
31644
|
}
|
|
30325
31645
|
}
|
|
30326
31646
|
if (shapeStyle.lineCap !== void 0) {
|
|
@@ -30340,6 +31660,82 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30340
31660
|
spPr["a:ln"]["a:effectLst"] = lineEffectListXml;
|
|
30341
31661
|
}
|
|
30342
31662
|
}
|
|
31663
|
+
/**
|
|
31664
|
+
* Serialize the shape's `<p:style>` block (CT_ShapeStyle §20.1.2.2.36)
|
|
31665
|
+
* from the persisted ref indices/colour XML. Emits children in spec
|
|
31666
|
+
* order: `lnRef → fillRef → effectRef → fontRef`.
|
|
31667
|
+
*
|
|
31668
|
+
* When the original shape XML already contained a `<p:style>` we mutate
|
|
31669
|
+
* that node in place so any unmodelled attributes/children are preserved.
|
|
31670
|
+
* When it didn't, we create one. When the shape no longer has any ref
|
|
31671
|
+
* data we leave the existing `<p:style>` (if any) untouched — silently
|
|
31672
|
+
* dropping it would break round-tripping.
|
|
31673
|
+
*
|
|
31674
|
+
* Phase 2 Stream B / C-H2.
|
|
31675
|
+
*/
|
|
31676
|
+
applyShapeStyleRefs(shape, shapeStyle) {
|
|
31677
|
+
const hasAnyRef = shapeStyle.lnRefIdx !== void 0 || shapeStyle.fillRefIdx !== void 0 || shapeStyle.effectRefIdx !== void 0 || shapeStyle.fontRefIdx !== void 0;
|
|
31678
|
+
if (!hasAnyRef) {
|
|
31679
|
+
return;
|
|
31680
|
+
}
|
|
31681
|
+
const existing = shape["p:style"];
|
|
31682
|
+
const styleNode = existing ?? {};
|
|
31683
|
+
if (shapeStyle.lnRefIdx !== void 0) {
|
|
31684
|
+
const lnRef = styleNode["a:lnRef"] ?? {};
|
|
31685
|
+
lnRef["@_idx"] = String(shapeStyle.lnRefIdx);
|
|
31686
|
+
this.replaceRefColorChoice(lnRef, shapeStyle.lnRefColorXml);
|
|
31687
|
+
styleNode["a:lnRef"] = lnRef;
|
|
31688
|
+
}
|
|
31689
|
+
if (shapeStyle.fillRefIdx !== void 0) {
|
|
31690
|
+
const fillRef = styleNode["a:fillRef"] ?? {};
|
|
31691
|
+
fillRef["@_idx"] = String(shapeStyle.fillRefIdx);
|
|
31692
|
+
this.replaceRefColorChoice(fillRef, shapeStyle.fillRefColorXml);
|
|
31693
|
+
styleNode["a:fillRef"] = fillRef;
|
|
31694
|
+
}
|
|
31695
|
+
if (shapeStyle.effectRefIdx !== void 0) {
|
|
31696
|
+
const effectRef = styleNode["a:effectRef"] ?? {};
|
|
31697
|
+
effectRef["@_idx"] = String(shapeStyle.effectRefIdx);
|
|
31698
|
+
this.replaceRefColorChoice(effectRef, shapeStyle.effectRefColorXml);
|
|
31699
|
+
styleNode["a:effectRef"] = effectRef;
|
|
31700
|
+
}
|
|
31701
|
+
if (shapeStyle.fontRefIdx !== void 0) {
|
|
31702
|
+
const fontRef = styleNode["a:fontRef"] ?? {};
|
|
31703
|
+
fontRef["@_idx"] = shapeStyle.fontRefIdx;
|
|
31704
|
+
this.replaceRefColorChoice(fontRef, shapeStyle.fontRefColorXml);
|
|
31705
|
+
styleNode["a:fontRef"] = fontRef;
|
|
31706
|
+
}
|
|
31707
|
+
const reordered = reorderObjectKeys(styleNode, SHAPE_STYLE_ORDER);
|
|
31708
|
+
for (const key of Object.keys(styleNode)) {
|
|
31709
|
+
delete styleNode[key];
|
|
31710
|
+
}
|
|
31711
|
+
for (const key of Object.keys(reordered)) {
|
|
31712
|
+
styleNode[key] = reordered[key];
|
|
31713
|
+
}
|
|
31714
|
+
shape["p:style"] = styleNode;
|
|
31715
|
+
}
|
|
31716
|
+
/**
|
|
31717
|
+
* Replace any existing colour-choice child on a style-matrix-reference
|
|
31718
|
+
* element with the given preserved XML, or strip all colour children
|
|
31719
|
+
* when the override is undefined.
|
|
31720
|
+
*/
|
|
31721
|
+
replaceRefColorChoice(refNode, colorXml) {
|
|
31722
|
+
for (const key of [
|
|
31723
|
+
"a:scrgbClr",
|
|
31724
|
+
"a:srgbClr",
|
|
31725
|
+
"a:hslClr",
|
|
31726
|
+
"a:sysClr",
|
|
31727
|
+
"a:schemeClr",
|
|
31728
|
+
"a:prstClr"
|
|
31729
|
+
]) {
|
|
31730
|
+
delete refNode[key];
|
|
31731
|
+
}
|
|
31732
|
+
if (!colorXml) {
|
|
31733
|
+
return;
|
|
31734
|
+
}
|
|
31735
|
+
for (const [key, value] of Object.entries(colorXml)) {
|
|
31736
|
+
refNode[key] = value;
|
|
31737
|
+
}
|
|
31738
|
+
}
|
|
30343
31739
|
};
|
|
30344
31740
|
|
|
30345
31741
|
// src/core/core/runtime/PptxHandlerRuntimeSaveEffectsWriter.ts
|
|
@@ -30349,17 +31745,22 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
|
|
|
30349
31745
|
* effectDag, 3D scene, and 3D shape properties to the given spPr XML object.
|
|
30350
31746
|
*/
|
|
30351
31747
|
applyEffectsAndThreeD(spPr, shapeStyle) {
|
|
30352
|
-
const
|
|
31748
|
+
const presetShadowXml = shapeStyle.presetShadowName ? this.buildPresetShadowXml(shapeStyle) : void 0;
|
|
31749
|
+
const outerShadowXml = presetShadowXml ? void 0 : this.buildOuterShadowXml(shapeStyle);
|
|
30353
31750
|
const innerShadowXml = this.buildInnerShadowXml(shapeStyle);
|
|
30354
31751
|
const glowXml = this.buildGlowXml(shapeStyle);
|
|
30355
31752
|
const softEdgeXml = this.buildSoftEdgeXml(shapeStyle);
|
|
30356
31753
|
const reflectionXml = this.buildReflectionXml(shapeStyle);
|
|
30357
31754
|
const blurXml = this.buildBlurXml(shapeStyle);
|
|
30358
|
-
const hasAnyEffect = outerShadowXml || innerShadowXml || glowXml || softEdgeXml || reflectionXml || blurXml;
|
|
31755
|
+
const hasAnyEffect = outerShadowXml || presetShadowXml || innerShadowXml || glowXml || softEdgeXml || reflectionXml || blurXml;
|
|
30359
31756
|
if (hasAnyEffect) {
|
|
30360
31757
|
const effectList = spPr["a:effectLst"] || {};
|
|
30361
|
-
if (
|
|
31758
|
+
if (presetShadowXml) {
|
|
31759
|
+
effectList["a:prstShdw"] = presetShadowXml;
|
|
31760
|
+
delete effectList["a:outerShdw"];
|
|
31761
|
+
} else if (outerShadowXml) {
|
|
30362
31762
|
effectList["a:outerShdw"] = outerShadowXml;
|
|
31763
|
+
delete effectList["a:prstShdw"];
|
|
30363
31764
|
}
|
|
30364
31765
|
if (innerShadowXml) {
|
|
30365
31766
|
effectList["a:innerShdw"] = innerShadowXml;
|
|
@@ -30376,12 +31777,13 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
|
|
|
30376
31777
|
if (blurXml) {
|
|
30377
31778
|
effectList["a:blur"] = blurXml;
|
|
30378
31779
|
}
|
|
30379
|
-
spPr["a:effectLst"] = effectList;
|
|
31780
|
+
spPr["a:effectLst"] = reorderObjectKeys(effectList, EFFECT_LST_ORDER);
|
|
30380
31781
|
} else {
|
|
30381
31782
|
const effectList = spPr["a:effectLst"];
|
|
30382
31783
|
if (effectList) {
|
|
30383
|
-
if (shapeStyle.shadowColor !== void 0 && !outerShadowXml) {
|
|
31784
|
+
if (shapeStyle.shadowColor !== void 0 && !outerShadowXml && !presetShadowXml) {
|
|
30384
31785
|
delete effectList["a:outerShdw"];
|
|
31786
|
+
delete effectList["a:prstShdw"];
|
|
30385
31787
|
}
|
|
30386
31788
|
if (shapeStyle.innerShadowColor !== void 0 && !innerShadowXml) {
|
|
30387
31789
|
delete effectList["a:innerShdw"];
|
|
@@ -30400,6 +31802,8 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
|
|
|
30400
31802
|
}
|
|
30401
31803
|
if (Object.keys(effectList).length === 0) {
|
|
30402
31804
|
delete spPr["a:effectLst"];
|
|
31805
|
+
} else {
|
|
31806
|
+
spPr["a:effectLst"] = reorderObjectKeys(effectList, EFFECT_LST_ORDER);
|
|
30403
31807
|
}
|
|
30404
31808
|
}
|
|
30405
31809
|
}
|
|
@@ -30560,7 +31964,8 @@ var PptxHandlerRuntime30 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30560
31964
|
);
|
|
30561
31965
|
}
|
|
30562
31966
|
if (el.textStyle?.hOverflow) {
|
|
30563
|
-
bodyPr["@
|
|
31967
|
+
bodyPr["@_horzOverflow"] = el.textStyle.hOverflow;
|
|
31968
|
+
delete bodyPr["@_hOverflow"];
|
|
30564
31969
|
}
|
|
30565
31970
|
if (el.textStyle?.vertOverflow) {
|
|
30566
31971
|
bodyPr["@_vertOverflow"] = el.textStyle.vertOverflow;
|
|
@@ -30791,7 +32196,10 @@ var PptxHandlerRuntime31 = class extends PptxHandlerRuntime30 {
|
|
|
30791
32196
|
const elWithPaths = el;
|
|
30792
32197
|
if (elWithPaths.customGeometryPaths && elWithPaths.customGeometryPaths.length > 0) {
|
|
30793
32198
|
delete spPr["a:prstGeom"];
|
|
30794
|
-
spPr["a:custGeom"] = customGeometryPathsToXml(
|
|
32199
|
+
spPr["a:custGeom"] = customGeometryPathsToXml(
|
|
32200
|
+
elWithPaths.customGeometryPaths,
|
|
32201
|
+
elWithPaths.customGeometryRawData
|
|
32202
|
+
);
|
|
30795
32203
|
} else if (spPr["a:prstGeom"]) {
|
|
30796
32204
|
const presetGeometry = el.type === "connector" ? this.normalizePresetGeometry(el.shapeType || "straightConnector1") : this.normalizePresetGeometry(el.shapeType);
|
|
30797
32205
|
const prstGeom = spPr["a:prstGeom"];
|
|
@@ -30916,6 +32324,42 @@ var PptxHandlerRuntime32 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
30916
32324
|
isGraphicFrameShape(shape) {
|
|
30917
32325
|
return Boolean(shape["p:nvGraphicFramePr"] || shape["a:graphic"] && shape["p:xfrm"]);
|
|
30918
32326
|
}
|
|
32327
|
+
/**
|
|
32328
|
+
* Reorder children of `p:spPr` to match CT_ShapeProperties (§20.1.2.2.35).
|
|
32329
|
+
* Also reorders any nested `a:blipFill` per CT_BlipFillProperties.
|
|
32330
|
+
* fast-xml-parser preserves insertion order; PowerPoint validates against
|
|
32331
|
+
* the schema's required order, so save-side mutations must be re-sorted.
|
|
32332
|
+
*/
|
|
32333
|
+
finalizeSpPrSchemaOrder(shape) {
|
|
32334
|
+
const spPr = shape["p:spPr"];
|
|
32335
|
+
if (!spPr) {
|
|
32336
|
+
return;
|
|
32337
|
+
}
|
|
32338
|
+
const blipFill = spPr["a:blipFill"];
|
|
32339
|
+
if (blipFill) {
|
|
32340
|
+
this.reorderInPlace(blipFill, BLIP_FILL_ORDER);
|
|
32341
|
+
}
|
|
32342
|
+
this.reorderInPlace(spPr, SP_PR_ORDER);
|
|
32343
|
+
}
|
|
32344
|
+
/**
|
|
32345
|
+
* Reorder children of the picture-level `p:blipFill` (CT_BlipFillProperties).
|
|
32346
|
+
* Picture elements carry their blip data on the `p:pic` root, not under spPr.
|
|
32347
|
+
*/
|
|
32348
|
+
finalizePictureBlipFillOrder(shape) {
|
|
32349
|
+
const pBlipFill = shape["p:blipFill"];
|
|
32350
|
+
if (pBlipFill) {
|
|
32351
|
+
this.reorderInPlace(pBlipFill, BLIP_FILL_ORDER);
|
|
32352
|
+
}
|
|
32353
|
+
}
|
|
32354
|
+
reorderInPlace(target, schemaOrder) {
|
|
32355
|
+
const reordered = reorderObjectKeys(target, schemaOrder);
|
|
32356
|
+
for (const key of Object.keys(target)) {
|
|
32357
|
+
delete target[key];
|
|
32358
|
+
}
|
|
32359
|
+
for (const key of Object.keys(reordered)) {
|
|
32360
|
+
target[key] = reordered[key];
|
|
32361
|
+
}
|
|
32362
|
+
}
|
|
30919
32363
|
/** Whether an element ID indicates a template (layout/master) element. */
|
|
30920
32364
|
isTemplateElementId(elementId) {
|
|
30921
32365
|
return elementId.startsWith("layout-") || elementId.startsWith("master-");
|
|
@@ -30939,14 +32383,50 @@ var PptxHandlerRuntime32 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
30939
32383
|
}
|
|
30940
32384
|
return;
|
|
30941
32385
|
}
|
|
32386
|
+
if (el.type === "contentPart") {
|
|
32387
|
+
if (shape) {
|
|
32388
|
+
this.elementTransformUpdater.applyTransform(shape, el, _PptxHandlerRuntime.EMU_PER_PX);
|
|
32389
|
+
collectors.contentParts.push(shape);
|
|
32390
|
+
} else {
|
|
32391
|
+
this.compatibilityService.reportWarning({
|
|
32392
|
+
code: "SAVE_ELEMENT_SKIPPED",
|
|
32393
|
+
message: `Content part '${el.id}' has no rawXml and was skipped during save.`,
|
|
32394
|
+
scope: "save",
|
|
32395
|
+
slideId: ctx.slide.id,
|
|
32396
|
+
elementId: el.id
|
|
32397
|
+
});
|
|
32398
|
+
}
|
|
32399
|
+
return;
|
|
32400
|
+
}
|
|
30942
32401
|
if (!shape && (el.type === "text" || el.type === "shape")) {
|
|
30943
32402
|
shape = this.createElementXml(el);
|
|
30944
32403
|
}
|
|
30945
32404
|
if (!shape && el.type === "connector") {
|
|
30946
32405
|
shape = this.createConnectorXml(el);
|
|
30947
32406
|
}
|
|
30948
|
-
if (
|
|
30949
|
-
|
|
32407
|
+
if (el.type === "ink") {
|
|
32408
|
+
if (!shape) {
|
|
32409
|
+
shape = this.createInkShapeXml(el);
|
|
32410
|
+
this.compatibilityService.reportWarning({
|
|
32411
|
+
code: "SAVE_INK_ENCODED_AS_CUSTGEOM",
|
|
32412
|
+
message: "SDK-created ink element serialized as custGeom shape; pressure/tool metadata not represented in OOXML aink format.",
|
|
32413
|
+
scope: "save",
|
|
32414
|
+
slideId: ctx.slide.id,
|
|
32415
|
+
elementId: el.id
|
|
32416
|
+
});
|
|
32417
|
+
}
|
|
32418
|
+
}
|
|
32419
|
+
if (!shape && el.type === "table") {
|
|
32420
|
+
shape = this.createTableGraphicFrameXml(el);
|
|
32421
|
+
}
|
|
32422
|
+
if (el.type === "ole") {
|
|
32423
|
+
const oleEl = el;
|
|
32424
|
+
if (shape) {
|
|
32425
|
+
this.applyOleTypedFieldUpdates(shape, oleEl);
|
|
32426
|
+
} else {
|
|
32427
|
+
const embedRid = this.resolveOleEmbedRelationshipId(ctx.slideRelationships, oleEl.oleTarget) || ctx.slideRelationshipRegistry.nextRelationshipId();
|
|
32428
|
+
shape = this.createOleGraphicFrameXml(oleEl, embedRid);
|
|
32429
|
+
}
|
|
30950
32430
|
}
|
|
30951
32431
|
if (!shape) {
|
|
30952
32432
|
this.compatibilityService.reportWarning({
|
|
@@ -30960,11 +32440,14 @@ var PptxHandlerRuntime32 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
30960
32440
|
}
|
|
30961
32441
|
this.elementTransformUpdater.applyTransform(shape, el, _PptxHandlerRuntime.EMU_PER_PX);
|
|
30962
32442
|
this.applyImageProperties(shape, el);
|
|
32443
|
+
this.finalizePictureBlipFillOrder(shape);
|
|
30963
32444
|
this.applyGeometryUpdate(shape, el);
|
|
30964
32445
|
if (hasShapeProperties(el) && el.shapeStyle && shape["p:spPr"]) {
|
|
30965
32446
|
const spPr = shape["p:spPr"];
|
|
30966
32447
|
this.applyFillAndStroke(spPr, el.shapeStyle);
|
|
30967
32448
|
this.applyEffectsAndThreeD(spPr, el.shapeStyle);
|
|
32449
|
+
this.finalizeSpPrSchemaOrder(shape);
|
|
32450
|
+
this.applyShapeStyleRefs(shape, el.shapeStyle);
|
|
30968
32451
|
}
|
|
30969
32452
|
if (hasTextProperties(el)) {
|
|
30970
32453
|
this.applyTextBodyContent(
|
|
@@ -31122,7 +32605,8 @@ var PptxHandlerRuntime33 = class extends PptxHandlerRuntime32 {
|
|
|
31122
32605
|
connectors: [],
|
|
31123
32606
|
graphicFrames: [],
|
|
31124
32607
|
groups: [],
|
|
31125
|
-
model3ds: []
|
|
32608
|
+
model3ds: [],
|
|
32609
|
+
contentParts: []
|
|
31126
32610
|
};
|
|
31127
32611
|
const ctx = {
|
|
31128
32612
|
slide,
|
|
@@ -31154,6 +32638,12 @@ var PptxHandlerRuntime33 = class extends PptxHandlerRuntime32 {
|
|
|
31154
32638
|
} else {
|
|
31155
32639
|
delete spTree["p16:model3D"];
|
|
31156
32640
|
}
|
|
32641
|
+
if (collectors.contentParts.length > 0) {
|
|
32642
|
+
spTree["p:contentPart"] = collectors.contentParts;
|
|
32643
|
+
} else {
|
|
32644
|
+
delete spTree["p:contentPart"];
|
|
32645
|
+
}
|
|
32646
|
+
this.reapplyAlternateContentEnvelopes(spTree, collectors);
|
|
31157
32647
|
const reassigned = shapeIdValidator.validateAndDeduplicateIds(
|
|
31158
32648
|
spTree,
|
|
31159
32649
|
(v) => this.ensureArray(v)
|
|
@@ -31171,12 +32661,426 @@ var PptxHandlerRuntime33 = class extends PptxHandlerRuntime32 {
|
|
|
31171
32661
|
this.zip.file(slideRelsPath, this.builder.build(slideRelsData));
|
|
31172
32662
|
this.applySlideDrawingGuides(slideNode, slide);
|
|
31173
32663
|
this.deduplicateExtensionLists(xmlObj);
|
|
32664
|
+
if (slideContainsA16Element(slideNode)) {
|
|
32665
|
+
ensureA16NamespaceOnSlideRoot(slideNode);
|
|
32666
|
+
}
|
|
31174
32667
|
this.zip.file(slide.id, this.builder.build(xmlObj));
|
|
31175
32668
|
}
|
|
32669
|
+
/**
|
|
32670
|
+
* Re-wrap selected children with their original `<mc:AlternateContent>`
|
|
32671
|
+
* envelope (CC-4).
|
|
32672
|
+
*
|
|
32673
|
+
* Parsing merged the selected branch (Choice when supported, otherwise
|
|
32674
|
+
* Fallback) into the spTree's tag arrays. Without re-wrapping, dirty
|
|
32675
|
+
* save would emit flat `<p:sp>`/`<p:pic>` etc. and drop the
|
|
32676
|
+
* `<mc:Fallback>` branch — losing legacy rendering for files originally
|
|
32677
|
+
* authored with newer-namespace features.
|
|
32678
|
+
*
|
|
32679
|
+
* Strategy: for each XmlObject in `collectors.*` that traces back to a
|
|
32680
|
+
* known AC block, group by block and:
|
|
32681
|
+
* 1. Remove the node from its flat collector / spTree array.
|
|
32682
|
+
* 2. Clone the original AC envelope.
|
|
32683
|
+
* 3. Replace the selected branch's `<{tag}>` children with the
|
|
32684
|
+
* live (possibly edited) nodes from the collectors.
|
|
32685
|
+
* 4. Leave the unselected branch verbatim.
|
|
32686
|
+
*
|
|
32687
|
+
* Final envelopes are appended to `spTree['mc:AlternateContent']`.
|
|
32688
|
+
*/
|
|
32689
|
+
reapplyAlternateContentEnvelopes(spTree, collectors) {
|
|
32690
|
+
const TAG_TO_COLLECTOR = {
|
|
32691
|
+
"p:sp": collectors.shapes,
|
|
32692
|
+
"p:pic": collectors.pics,
|
|
32693
|
+
"p:cxnSp": collectors.connectors,
|
|
32694
|
+
"p:graphicFrame": collectors.graphicFrames,
|
|
32695
|
+
"p:grpSp": collectors.groups,
|
|
32696
|
+
"p:contentPart": collectors.contentParts,
|
|
32697
|
+
// `model3d` does not flow through SHAPE_TREE_ELEMENT_TAGS, but the
|
|
32698
|
+
// AC pathway in OpenXML decks frequently uses Choice = p16:model3D
|
|
32699
|
+
// + Fallback = p:pic, so map it for completeness.
|
|
32700
|
+
"p16:model3D": collectors.model3ds
|
|
32701
|
+
};
|
|
32702
|
+
const blockGroups = /* @__PURE__ */ new Map();
|
|
32703
|
+
for (const tag of Object.keys(TAG_TO_COLLECTOR)) {
|
|
32704
|
+
const collector = TAG_TO_COLLECTOR[tag];
|
|
32705
|
+
if (!collector) {
|
|
32706
|
+
continue;
|
|
32707
|
+
}
|
|
32708
|
+
for (const node of collector) {
|
|
32709
|
+
const block = this.alternateContentBlockByRawXml.get(node);
|
|
32710
|
+
if (!block) {
|
|
32711
|
+
continue;
|
|
32712
|
+
}
|
|
32713
|
+
let entries = blockGroups.get(block);
|
|
32714
|
+
if (!entries) {
|
|
32715
|
+
entries = [];
|
|
32716
|
+
blockGroups.set(block, entries);
|
|
32717
|
+
}
|
|
32718
|
+
entries.push({ tag, node, collector });
|
|
32719
|
+
}
|
|
32720
|
+
}
|
|
32721
|
+
if (blockGroups.size === 0) {
|
|
32722
|
+
return;
|
|
32723
|
+
}
|
|
32724
|
+
const envelopes = [];
|
|
32725
|
+
for (const [block, entries] of blockGroups) {
|
|
32726
|
+
for (const entry of entries) {
|
|
32727
|
+
const idx = entry.collector.indexOf(entry.node);
|
|
32728
|
+
if (idx !== -1) {
|
|
32729
|
+
entry.collector.splice(idx, 1);
|
|
32730
|
+
}
|
|
32731
|
+
}
|
|
32732
|
+
const clonedAc = { ...block.rawAc };
|
|
32733
|
+
const liveByTag = /* @__PURE__ */ new Map();
|
|
32734
|
+
for (const entry of entries) {
|
|
32735
|
+
let arr = liveByTag.get(entry.tag);
|
|
32736
|
+
if (!arr) {
|
|
32737
|
+
arr = [];
|
|
32738
|
+
liveByTag.set(entry.tag, arr);
|
|
32739
|
+
}
|
|
32740
|
+
arr.push(entry.node);
|
|
32741
|
+
}
|
|
32742
|
+
if (block.selectedBranch === "choice") {
|
|
32743
|
+
const choices = this.ensureArray(clonedAc["mc:Choice"]);
|
|
32744
|
+
const targetIdx = block.choiceIndex ?? 0;
|
|
32745
|
+
const original = choices[targetIdx];
|
|
32746
|
+
if (original) {
|
|
32747
|
+
const rebuilt = { ...original };
|
|
32748
|
+
for (const tag of SHAPE_TREE_ELEMENT_TAGS) {
|
|
32749
|
+
delete rebuilt[tag];
|
|
32750
|
+
}
|
|
32751
|
+
for (const [tag, nodes] of liveByTag) {
|
|
32752
|
+
rebuilt[tag] = nodes.length === 1 ? nodes[0] : nodes;
|
|
32753
|
+
}
|
|
32754
|
+
choices[targetIdx] = rebuilt;
|
|
32755
|
+
clonedAc["mc:Choice"] = choices.length === 1 ? choices[0] : choices;
|
|
32756
|
+
}
|
|
32757
|
+
} else {
|
|
32758
|
+
const fallback = clonedAc["mc:Fallback"];
|
|
32759
|
+
if (fallback) {
|
|
32760
|
+
const rebuilt = { ...fallback };
|
|
32761
|
+
for (const tag of SHAPE_TREE_ELEMENT_TAGS) {
|
|
32762
|
+
delete rebuilt[tag];
|
|
32763
|
+
}
|
|
32764
|
+
for (const [tag, nodes] of liveByTag) {
|
|
32765
|
+
rebuilt[tag] = nodes.length === 1 ? nodes[0] : nodes;
|
|
32766
|
+
}
|
|
32767
|
+
clonedAc["mc:Fallback"] = rebuilt;
|
|
32768
|
+
}
|
|
32769
|
+
}
|
|
32770
|
+
envelopes.push(clonedAc);
|
|
32771
|
+
}
|
|
32772
|
+
spTree["p:sp"] = collectors.shapes;
|
|
32773
|
+
spTree["p:pic"] = collectors.pics;
|
|
32774
|
+
spTree["p:cxnSp"] = collectors.connectors;
|
|
32775
|
+
spTree["p:graphicFrame"] = collectors.graphicFrames;
|
|
32776
|
+
if (collectors.groups.length > 0) {
|
|
32777
|
+
spTree["p:grpSp"] = collectors.groups;
|
|
32778
|
+
} else {
|
|
32779
|
+
delete spTree["p:grpSp"];
|
|
32780
|
+
}
|
|
32781
|
+
if (collectors.contentParts.length > 0) {
|
|
32782
|
+
spTree["p:contentPart"] = collectors.contentParts;
|
|
32783
|
+
} else {
|
|
32784
|
+
delete spTree["p:contentPart"];
|
|
32785
|
+
}
|
|
32786
|
+
if (collectors.model3ds.length > 0) {
|
|
32787
|
+
spTree["p16:model3D"] = collectors.model3ds;
|
|
32788
|
+
} else {
|
|
32789
|
+
delete spTree["p16:model3D"];
|
|
32790
|
+
}
|
|
32791
|
+
spTree["mc:AlternateContent"] = envelopes.length === 1 ? envelopes[0] : envelopes;
|
|
32792
|
+
}
|
|
32793
|
+
};
|
|
32794
|
+
|
|
32795
|
+
// src/core/core/runtime/PptxHandlerRuntimeSaveTheme.ts
|
|
32796
|
+
var PptxHandlerRuntime34 = class extends PptxHandlerRuntime33 {
|
|
32797
|
+
/**
|
|
32798
|
+
* Mark a theme path as dirty so the save pipeline will regenerate
|
|
32799
|
+
* the theme XML from in-memory state. Optional — without this the
|
|
32800
|
+
* original XML is preserved verbatim on save (C-H3).
|
|
32801
|
+
*/
|
|
32802
|
+
markThemeDirty(themePath) {
|
|
32803
|
+
this.dirtyThemePaths.add(themePath);
|
|
32804
|
+
}
|
|
32805
|
+
/**
|
|
32806
|
+
* Mark all known theme paths dirty in one call.
|
|
32807
|
+
*/
|
|
32808
|
+
markAllThemesDirty() {
|
|
32809
|
+
for (const themePath of this.originalThemeXmlByPath.keys()) {
|
|
32810
|
+
this.dirtyThemePaths.add(themePath);
|
|
32811
|
+
}
|
|
32812
|
+
for (const themePath of this.masterThemePaths.values()) {
|
|
32813
|
+
this.dirtyThemePaths.add(themePath);
|
|
32814
|
+
}
|
|
32815
|
+
}
|
|
32816
|
+
/**
|
|
32817
|
+
* Persist all theme parts during save. Called from the save pipeline
|
|
32818
|
+
* after master / layout XML have been flushed and before
|
|
32819
|
+
* presentation.xml is serialized.
|
|
32820
|
+
*
|
|
32821
|
+
* Order of operations per theme path:
|
|
32822
|
+
*
|
|
32823
|
+
* 1. If the path is *not* in {@link dirtyThemePaths}, the existing
|
|
32824
|
+
* ZIP entry is already correct — no-op. (Original XML was placed
|
|
32825
|
+
* into the ZIP at load time.)
|
|
32826
|
+
* 2. If the path is dirty, build a fresh `<a:theme>` document from
|
|
32827
|
+
* in-memory state and the captured raw subtrees, then overwrite
|
|
32828
|
+
* the ZIP entry.
|
|
32829
|
+
*/
|
|
32830
|
+
async persistThemeParts() {
|
|
32831
|
+
const seenThemePaths = /* @__PURE__ */ new Set();
|
|
32832
|
+
for (const [masterPath, themePath] of this.masterThemePaths.entries()) {
|
|
32833
|
+
if (!themePath) {
|
|
32834
|
+
continue;
|
|
32835
|
+
}
|
|
32836
|
+
seenThemePaths.add(themePath);
|
|
32837
|
+
if (!this.dirtyThemePaths.has(themePath)) {
|
|
32838
|
+
continue;
|
|
32839
|
+
}
|
|
32840
|
+
const themeXml2 = this.buildThemeXml(themePath, masterPath);
|
|
32841
|
+
if (themeXml2) {
|
|
32842
|
+
this.zip.file(themePath, themeXml2);
|
|
32843
|
+
}
|
|
32844
|
+
}
|
|
32845
|
+
for (const [themePath] of this.originalThemeXmlByPath.entries()) {
|
|
32846
|
+
if (seenThemePaths.has(themePath)) {
|
|
32847
|
+
continue;
|
|
32848
|
+
}
|
|
32849
|
+
if (!this.dirtyThemePaths.has(themePath)) {
|
|
32850
|
+
continue;
|
|
32851
|
+
}
|
|
32852
|
+
const themeXml2 = this.buildThemeXml(themePath, void 0);
|
|
32853
|
+
if (themeXml2) {
|
|
32854
|
+
this.zip.file(themePath, themeXml2);
|
|
32855
|
+
}
|
|
32856
|
+
}
|
|
32857
|
+
}
|
|
32858
|
+
/**
|
|
32859
|
+
* Build a complete `<a:theme>` XML document from in-memory state.
|
|
32860
|
+
* Returns the serialized XML string (with XML prolog), or `undefined`
|
|
32861
|
+
* if there is no source data to emit.
|
|
32862
|
+
*
|
|
32863
|
+
* - Color scheme: built from per-master color map (or global fallback).
|
|
32864
|
+
* - Font scheme: built from per-master font map + per-script entries.
|
|
32865
|
+
* - Format scheme: re-emit the original XML subtree if available; else
|
|
32866
|
+
* build a minimal scheme from {@link themeFormatScheme}.
|
|
32867
|
+
* - objectDefaults / extraClrSchemeLst / custClrLst / extLst: re-emit
|
|
32868
|
+
* captured raw subtrees.
|
|
32869
|
+
*/
|
|
32870
|
+
buildThemeXml(themePath, masterPath) {
|
|
32871
|
+
const colorMap = masterPath && this.masterThemeColorMaps.get(masterPath) || this.globalThemeColorMapSnapshot || this.themeColorMap;
|
|
32872
|
+
const fontMap = masterPath && this.masterThemeFontMaps.get(masterPath) || this.globalThemeFontMapSnapshot || this.themeFontMap;
|
|
32873
|
+
const themeName = this.masterThemeNames.get(themePath) || "Office Theme";
|
|
32874
|
+
const colorSchemeName = this.masterThemeColorSchemeNames.get(themePath) || themeName;
|
|
32875
|
+
const fontSchemeName = this.masterThemeFontSchemeNames.get(themePath) || themeName;
|
|
32876
|
+
const majorScripts = this.masterThemeMajorFontScripts.get(themePath) || {};
|
|
32877
|
+
const minorScripts = this.masterThemeMinorFontScripts.get(themePath) || {};
|
|
32878
|
+
const clrScheme = this.buildClrSchemeObject(colorSchemeName, colorMap);
|
|
32879
|
+
const fontScheme = this.buildFontSchemeObject(
|
|
32880
|
+
fontSchemeName,
|
|
32881
|
+
fontMap,
|
|
32882
|
+
majorScripts,
|
|
32883
|
+
minorScripts
|
|
32884
|
+
);
|
|
32885
|
+
const fmtScheme = this.extractRawSubtreeFromOriginal(themePath, [
|
|
32886
|
+
"a:theme",
|
|
32887
|
+
"a:themeElements",
|
|
32888
|
+
"a:fmtScheme"
|
|
32889
|
+
]);
|
|
32890
|
+
const themeElements = {
|
|
32891
|
+
"a:clrScheme": clrScheme,
|
|
32892
|
+
"a:fontScheme": fontScheme
|
|
32893
|
+
};
|
|
32894
|
+
if (fmtScheme !== void 0) {
|
|
32895
|
+
themeElements["a:fmtScheme"] = fmtScheme;
|
|
32896
|
+
} else {
|
|
32897
|
+
themeElements["a:fmtScheme"] = this.buildMinimalFmtScheme(themeName);
|
|
32898
|
+
}
|
|
32899
|
+
const themeRoot = {
|
|
32900
|
+
"@_xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
|
|
32901
|
+
"@_name": themeName,
|
|
32902
|
+
"a:themeElements": themeElements
|
|
32903
|
+
};
|
|
32904
|
+
const objectDefaults = this.masterThemeObjectDefaults.get(themePath);
|
|
32905
|
+
if (objectDefaults && (objectDefaults.spDef || objectDefaults.lnDef || objectDefaults.txDef)) {
|
|
32906
|
+
const od = {};
|
|
32907
|
+
if (objectDefaults.spDef !== void 0) {
|
|
32908
|
+
od["a:spDef"] = objectDefaults.spDef;
|
|
32909
|
+
}
|
|
32910
|
+
if (objectDefaults.lnDef !== void 0) {
|
|
32911
|
+
od["a:lnDef"] = objectDefaults.lnDef;
|
|
32912
|
+
}
|
|
32913
|
+
if (objectDefaults.txDef !== void 0) {
|
|
32914
|
+
od["a:txDef"] = objectDefaults.txDef;
|
|
32915
|
+
}
|
|
32916
|
+
themeRoot["a:objectDefaults"] = od;
|
|
32917
|
+
} else {
|
|
32918
|
+
themeRoot["a:objectDefaults"] = {};
|
|
32919
|
+
}
|
|
32920
|
+
const extraClr = this.masterThemeExtraClrSchemeLst.get(themePath);
|
|
32921
|
+
themeRoot["a:extraClrSchemeLst"] = extraClr !== void 0 ? extraClr : {};
|
|
32922
|
+
const custClr = this.masterThemeCustClrLst.get(themePath);
|
|
32923
|
+
if (custClr !== void 0) {
|
|
32924
|
+
themeRoot["a:custClrLst"] = custClr;
|
|
32925
|
+
}
|
|
32926
|
+
const themeExt = this.masterThemeExtLst.get(themePath);
|
|
32927
|
+
if (themeExt !== void 0) {
|
|
32928
|
+
themeRoot["a:extLst"] = themeExt;
|
|
32929
|
+
}
|
|
32930
|
+
const doc = {
|
|
32931
|
+
"?xml": { "@_version": "1.0", "@_encoding": "UTF-8", "@_standalone": "yes" },
|
|
32932
|
+
"a:theme": themeRoot
|
|
32933
|
+
};
|
|
32934
|
+
try {
|
|
32935
|
+
return this.builder.build(doc);
|
|
32936
|
+
} catch (error) {
|
|
32937
|
+
console.warn(`Failed to build theme XML for ${themePath}:`, error);
|
|
32938
|
+
return void 0;
|
|
32939
|
+
}
|
|
32940
|
+
}
|
|
32941
|
+
/**
|
|
32942
|
+
* Build the `a:clrScheme` XmlObject from a colour map. Each slot
|
|
32943
|
+
* value is interpreted as either a `#RRGGBB` srgb hex or a known
|
|
32944
|
+
* sysClr token (currently always emitted as srgbClr — the in-memory
|
|
32945
|
+
* map is hex-typed; sysClr round-trip belongs to the broader C-H3
|
|
32946
|
+
* fix to preserve original color XML and is out of scope here).
|
|
32947
|
+
*/
|
|
32948
|
+
buildClrSchemeObject(schemeName, colorMap) {
|
|
32949
|
+
const slot = (key) => {
|
|
32950
|
+
const hex = String(colorMap[key] || "").replace(/^#/, "");
|
|
32951
|
+
const srgb = hex.length === 6 ? hex.toUpperCase() : "000000";
|
|
32952
|
+
return { "a:srgbClr": { "@_val": srgb } };
|
|
32953
|
+
};
|
|
32954
|
+
return {
|
|
32955
|
+
"@_name": schemeName,
|
|
32956
|
+
"a:dk1": slot("dk1"),
|
|
32957
|
+
"a:lt1": slot("lt1"),
|
|
32958
|
+
"a:dk2": slot("dk2"),
|
|
32959
|
+
"a:lt2": slot("lt2"),
|
|
32960
|
+
"a:accent1": slot("accent1"),
|
|
32961
|
+
"a:accent2": slot("accent2"),
|
|
32962
|
+
"a:accent3": slot("accent3"),
|
|
32963
|
+
"a:accent4": slot("accent4"),
|
|
32964
|
+
"a:accent5": slot("accent5"),
|
|
32965
|
+
"a:accent6": slot("accent6"),
|
|
32966
|
+
"a:hlink": slot("hlink"),
|
|
32967
|
+
"a:folHlink": slot("folHlink")
|
|
32968
|
+
};
|
|
32969
|
+
}
|
|
32970
|
+
/**
|
|
32971
|
+
* Build the `a:fontScheme` XmlObject from a font map plus per-script
|
|
32972
|
+
* font tables.
|
|
32973
|
+
*
|
|
32974
|
+
* Phase 4 Stream A / M4.
|
|
32975
|
+
*/
|
|
32976
|
+
buildFontSchemeObject(schemeName, fontMap, majorScripts, minorScripts) {
|
|
32977
|
+
const buildFontGroup = (latinKey, eaKey, csKey, scripts) => {
|
|
32978
|
+
const group = {
|
|
32979
|
+
"a:latin": { "@_typeface": fontMap[latinKey] || "Calibri" },
|
|
32980
|
+
"a:ea": { "@_typeface": fontMap[eaKey] || "" },
|
|
32981
|
+
"a:cs": { "@_typeface": fontMap[csKey] || "" }
|
|
32982
|
+
};
|
|
32983
|
+
const scriptKeys = Object.keys(scripts);
|
|
32984
|
+
if (scriptKeys.length > 0) {
|
|
32985
|
+
const fontEntries = scriptKeys.map((script) => ({
|
|
32986
|
+
"@_script": script,
|
|
32987
|
+
"@_typeface": scripts[script]
|
|
32988
|
+
}));
|
|
32989
|
+
group["a:font"] = fontEntries.length === 1 ? fontEntries[0] : fontEntries;
|
|
32990
|
+
}
|
|
32991
|
+
return group;
|
|
32992
|
+
};
|
|
32993
|
+
return {
|
|
32994
|
+
"@_name": schemeName,
|
|
32995
|
+
"a:majorFont": buildFontGroup("mj-lt", "mj-ea", "mj-cs", majorScripts),
|
|
32996
|
+
"a:minorFont": buildFontGroup("mn-lt", "mn-ea", "mn-cs", minorScripts)
|
|
32997
|
+
};
|
|
32998
|
+
}
|
|
32999
|
+
/**
|
|
33000
|
+
* Re-parse the original theme XML and pluck out a subtree by path,
|
|
33001
|
+
* returning the raw parser object. Returns `undefined` when the
|
|
33002
|
+
* original is missing or the path doesn't exist.
|
|
33003
|
+
*
|
|
33004
|
+
* Used to preserve `a:fmtScheme` byte-for-byte through a regenerate
|
|
33005
|
+
* round-trip, since the in-memory PptxThemeFormatScheme is lossy.
|
|
33006
|
+
*/
|
|
33007
|
+
extractRawSubtreeFromOriginal(themePath, path2) {
|
|
33008
|
+
const original = this.originalThemeXmlByPath.get(themePath);
|
|
33009
|
+
if (!original) {
|
|
33010
|
+
return void 0;
|
|
33011
|
+
}
|
|
33012
|
+
try {
|
|
33013
|
+
const parsed = this.parser.parse(original);
|
|
33014
|
+
let cursor = parsed;
|
|
33015
|
+
for (const segment of path2) {
|
|
33016
|
+
if (cursor && typeof cursor === "object" && segment in cursor) {
|
|
33017
|
+
cursor = cursor[segment];
|
|
33018
|
+
} else {
|
|
33019
|
+
return void 0;
|
|
33020
|
+
}
|
|
33021
|
+
}
|
|
33022
|
+
return cursor;
|
|
33023
|
+
} catch {
|
|
33024
|
+
return void 0;
|
|
33025
|
+
}
|
|
33026
|
+
}
|
|
33027
|
+
/**
|
|
33028
|
+
* Last-resort minimal `<a:fmtScheme>` body. Mirrors the SDK new-deck
|
|
33029
|
+
* builder's output for new presentations, scaled down to the smallest
|
|
33030
|
+
* schema-valid form.
|
|
33031
|
+
*/
|
|
33032
|
+
buildMinimalFmtScheme(name) {
|
|
33033
|
+
const phClrSolid = { "a:solidFill": { "a:schemeClr": { "@_val": "phClr" } } };
|
|
33034
|
+
return {
|
|
33035
|
+
"@_name": name,
|
|
33036
|
+
"a:fillStyleLst": {
|
|
33037
|
+
"a:solidFill": [{ "a:schemeClr": { "@_val": "phClr" } }],
|
|
33038
|
+
"a:gradFill": []
|
|
33039
|
+
},
|
|
33040
|
+
"a:lnStyleLst": {
|
|
33041
|
+
"a:ln": [
|
|
33042
|
+
{
|
|
33043
|
+
"@_w": "6350",
|
|
33044
|
+
"@_cap": "flat",
|
|
33045
|
+
"@_cmpd": "sng",
|
|
33046
|
+
"@_algn": "ctr",
|
|
33047
|
+
...phClrSolid,
|
|
33048
|
+
"a:prstDash": { "@_val": "solid" },
|
|
33049
|
+
"a:miter": { "@_lim": "800000" }
|
|
33050
|
+
},
|
|
33051
|
+
{
|
|
33052
|
+
"@_w": "12700",
|
|
33053
|
+
"@_cap": "flat",
|
|
33054
|
+
"@_cmpd": "sng",
|
|
33055
|
+
"@_algn": "ctr",
|
|
33056
|
+
...phClrSolid,
|
|
33057
|
+
"a:prstDash": { "@_val": "solid" },
|
|
33058
|
+
"a:miter": { "@_lim": "800000" }
|
|
33059
|
+
},
|
|
33060
|
+
{
|
|
33061
|
+
"@_w": "19050",
|
|
33062
|
+
"@_cap": "flat",
|
|
33063
|
+
"@_cmpd": "sng",
|
|
33064
|
+
"@_algn": "ctr",
|
|
33065
|
+
...phClrSolid,
|
|
33066
|
+
"a:prstDash": { "@_val": "solid" },
|
|
33067
|
+
"a:miter": { "@_lim": "800000" }
|
|
33068
|
+
}
|
|
33069
|
+
]
|
|
33070
|
+
},
|
|
33071
|
+
"a:effectStyleLst": {
|
|
33072
|
+
"a:effectStyle": [{ "a:effectLst": {} }, { "a:effectLst": {} }, { "a:effectLst": {} }]
|
|
33073
|
+
},
|
|
33074
|
+
"a:bgFillStyleLst": {
|
|
33075
|
+
"a:solidFill": [{ "a:schemeClr": { "@_val": "phClr" } }],
|
|
33076
|
+
"a:gradFill": []
|
|
33077
|
+
}
|
|
33078
|
+
};
|
|
33079
|
+
}
|
|
31176
33080
|
};
|
|
31177
33081
|
|
|
31178
33082
|
// src/core/core/runtime/PptxHandlerRuntimeSavePipeline.ts
|
|
31179
|
-
var
|
|
33083
|
+
var PptxHandlerRuntime35 = class _PptxHandlerRuntime extends PptxHandlerRuntime34 {
|
|
31180
33084
|
/**
|
|
31181
33085
|
* Resolve the effective conformance class for this save operation.
|
|
31182
33086
|
*
|
|
@@ -31263,6 +33167,7 @@ var PptxHandlerRuntime34 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
31263
33167
|
for (const [masterPath, masterXmlObj] of this.masterXmlMap.entries()) {
|
|
31264
33168
|
this.zip.file(masterPath, this.builder.build(masterXmlObj));
|
|
31265
33169
|
}
|
|
33170
|
+
await this.persistThemeParts();
|
|
31266
33171
|
await this.applyEmbeddedFontPreservation(options?.embeddedFonts);
|
|
31267
33172
|
if (this.presentationData) {
|
|
31268
33173
|
this.presentationSaveBuilder.applySaveOptions({
|
|
@@ -31352,7 +33257,7 @@ var PptxHandlerRuntime34 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
31352
33257
|
};
|
|
31353
33258
|
|
|
31354
33259
|
// src/core/core/runtime/PptxHandlerRuntimeElementParsing.ts
|
|
31355
|
-
var
|
|
33260
|
+
var PptxHandlerRuntime36 = class _PptxHandlerRuntime extends PptxHandlerRuntime35 {
|
|
31356
33261
|
/**
|
|
31357
33262
|
* Parse media data (video/audio path and MIME type) from graphic frame data.
|
|
31358
33263
|
*/
|
|
@@ -31574,7 +33479,7 @@ var PptxHandlerRuntime35 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
31574
33479
|
};
|
|
31575
33480
|
|
|
31576
33481
|
// src/core/core/runtime/PptxHandlerRuntimePlaceholderLookup.ts
|
|
31577
|
-
var
|
|
33482
|
+
var PptxHandlerRuntime37 = class extends PptxHandlerRuntime36 {
|
|
31578
33483
|
findPlaceholderInShapeTree(spTree, expected) {
|
|
31579
33484
|
if (!spTree) {
|
|
31580
33485
|
return void 0;
|
|
@@ -31727,7 +33632,7 @@ var PptxHandlerRuntime36 = class extends PptxHandlerRuntime35 {
|
|
|
31727
33632
|
};
|
|
31728
33633
|
|
|
31729
33634
|
// src/core/core/runtime/PptxHandlerRuntimeGeometryParsing.ts
|
|
31730
|
-
var
|
|
33635
|
+
var PptxHandlerRuntime38 = class extends PptxHandlerRuntime37 {
|
|
31731
33636
|
parseGeometryAdjustments(prstGeom) {
|
|
31732
33637
|
if (!prstGeom) {
|
|
31733
33638
|
return void 0;
|
|
@@ -31836,6 +33741,103 @@ var PptxHandlerRuntime37 = class extends PptxHandlerRuntime36 {
|
|
|
31836
33741
|
}
|
|
31837
33742
|
return handles.length > 0 ? handles : void 0;
|
|
31838
33743
|
}
|
|
33744
|
+
/**
|
|
33745
|
+
* Extract `a:gdLst`/`a:ahLst`/`a:cxnLst`/`a:rect` raw XML from a `a:custGeom`
|
|
33746
|
+
* node so they can be re-emitted on save when the geometry is edited.
|
|
33747
|
+
* Returns `undefined` when none of these auxiliary children carry data.
|
|
33748
|
+
*/
|
|
33749
|
+
extractCustomGeometryRawData(custGeom) {
|
|
33750
|
+
if (!custGeom) {
|
|
33751
|
+
return void 0;
|
|
33752
|
+
}
|
|
33753
|
+
const isNonEmpty = (node) => {
|
|
33754
|
+
if (node === void 0 || node === null) {
|
|
33755
|
+
return false;
|
|
33756
|
+
}
|
|
33757
|
+
if (typeof node !== "object") {
|
|
33758
|
+
return true;
|
|
33759
|
+
}
|
|
33760
|
+
return Object.keys(node).length > 0;
|
|
33761
|
+
};
|
|
33762
|
+
const result = {};
|
|
33763
|
+
const gdLst = custGeom["a:gdLst"];
|
|
33764
|
+
if (isNonEmpty(gdLst)) {
|
|
33765
|
+
result.gdLstXml = gdLst;
|
|
33766
|
+
}
|
|
33767
|
+
const ahLst = custGeom["a:ahLst"];
|
|
33768
|
+
if (isNonEmpty(ahLst)) {
|
|
33769
|
+
result.ahLstXml = ahLst;
|
|
33770
|
+
}
|
|
33771
|
+
const cxnLst = custGeom["a:cxnLst"];
|
|
33772
|
+
if (isNonEmpty(cxnLst)) {
|
|
33773
|
+
result.cxnLstXml = cxnLst;
|
|
33774
|
+
}
|
|
33775
|
+
const rect = custGeom["a:rect"];
|
|
33776
|
+
if (isNonEmpty(rect)) {
|
|
33777
|
+
result.rectXml = rect;
|
|
33778
|
+
}
|
|
33779
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
33780
|
+
}
|
|
33781
|
+
/**
|
|
33782
|
+
* Build structured `CustomGeometryPath[]` from a parsed `a:custGeom` node,
|
|
33783
|
+
* including per-path `@fill`/`@stroke`/`@extrusionOk` attributes so they
|
|
33784
|
+
* survive a round-trip when the path list is later regenerated.
|
|
33785
|
+
*
|
|
33786
|
+
* Falls back to SVG → structured-path conversion when no structured path
|
|
33787
|
+
* info is otherwise available.
|
|
33788
|
+
*/
|
|
33789
|
+
buildStructuredCustomGeometryPaths(custGeom, pathData, pathWidth, pathHeight) {
|
|
33790
|
+
if (!custGeom) {
|
|
33791
|
+
return void 0;
|
|
33792
|
+
}
|
|
33793
|
+
const pathLst = custGeom["a:pathLst"];
|
|
33794
|
+
if (!pathLst) {
|
|
33795
|
+
return void 0;
|
|
33796
|
+
}
|
|
33797
|
+
const pathNodes = this.ensureArray(pathLst["a:path"]);
|
|
33798
|
+
if (pathNodes.length === 0) {
|
|
33799
|
+
return void 0;
|
|
33800
|
+
}
|
|
33801
|
+
const segments = svgToCustomGeometryPaths(pathData, pathWidth, pathHeight);
|
|
33802
|
+
if (segments.length === 0) {
|
|
33803
|
+
return void 0;
|
|
33804
|
+
}
|
|
33805
|
+
const validFillModes = /* @__PURE__ */ new Set([
|
|
33806
|
+
"norm",
|
|
33807
|
+
"lighten",
|
|
33808
|
+
"lightenLess",
|
|
33809
|
+
"darken",
|
|
33810
|
+
"darkenLess",
|
|
33811
|
+
"none"
|
|
33812
|
+
]);
|
|
33813
|
+
const parseBoolAttr2 = (value) => {
|
|
33814
|
+
if (value === void 0 || value === null || value === "") {
|
|
33815
|
+
return void 0;
|
|
33816
|
+
}
|
|
33817
|
+
if (value === "1" || value === "true" || value === true) {
|
|
33818
|
+
return true;
|
|
33819
|
+
}
|
|
33820
|
+
if (value === "0" || value === "false" || value === false) {
|
|
33821
|
+
return false;
|
|
33822
|
+
}
|
|
33823
|
+
return void 0;
|
|
33824
|
+
};
|
|
33825
|
+
const target = segments[0];
|
|
33826
|
+
const firstNode = pathNodes[0];
|
|
33827
|
+
const fillAttr = String(firstNode["@_fill"] ?? "").trim();
|
|
33828
|
+
if (validFillModes.has(fillAttr)) {
|
|
33829
|
+
target.fillMode = fillAttr;
|
|
33830
|
+
}
|
|
33831
|
+
const strokeAttr = parseBoolAttr2(firstNode["@_stroke"]);
|
|
33832
|
+
if (strokeAttr !== void 0) {
|
|
33833
|
+
target.stroke = strokeAttr;
|
|
33834
|
+
}
|
|
33835
|
+
const extrusionAttr = parseBoolAttr2(firstNode["@_extrusionOk"]);
|
|
33836
|
+
if (extrusionAttr !== void 0) {
|
|
33837
|
+
target.extrusionOk = extrusionAttr;
|
|
33838
|
+
}
|
|
33839
|
+
return segments;
|
|
33840
|
+
}
|
|
31839
33841
|
parseCustomGeometry(custGeom, shapeWidth, shapeHeight) {
|
|
31840
33842
|
if (!custGeom || !custGeom["a:pathLst"] || !custGeom["a:pathLst"]?.["a:path"]) {
|
|
31841
33843
|
return null;
|
|
@@ -31904,7 +33906,7 @@ var PptxHandlerRuntime37 = class extends PptxHandlerRuntime36 {
|
|
|
31904
33906
|
};
|
|
31905
33907
|
|
|
31906
33908
|
// src/core/core/runtime/PptxHandlerRuntimeShapeImageFill.ts
|
|
31907
|
-
var
|
|
33909
|
+
var PptxHandlerRuntime39 = class _PptxHandlerRuntime extends PptxHandlerRuntime38 {
|
|
31908
33910
|
/**
|
|
31909
33911
|
* Parse a shape that has an image fill (a:blipFill inside spPr)
|
|
31910
33912
|
* This handles shapes like rectangles filled with images (e.g., wood texture backgrounds)
|
|
@@ -32104,7 +34106,7 @@ var PptxHandlerRuntime38 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
32104
34106
|
};
|
|
32105
34107
|
|
|
32106
34108
|
// src/core/core/runtime/PptxHandlerRuntimeTextDefaults.ts
|
|
32107
|
-
var
|
|
34109
|
+
var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
32108
34110
|
/**
|
|
32109
34111
|
* Apply {@link PlaceholderDefaults} body-level properties to a
|
|
32110
34112
|
* {@link TextStyle} as fallback values (only sets fields that are
|
|
@@ -32228,7 +34230,7 @@ var PptxHandlerRuntime39 = class extends PptxHandlerRuntime38 {
|
|
|
32228
34230
|
};
|
|
32229
34231
|
|
|
32230
34232
|
// src/core/core/runtime/PptxHandlerRuntimeBulletParsing.ts
|
|
32231
|
-
var
|
|
34233
|
+
var PptxHandlerRuntime41 = class extends PptxHandlerRuntime40 {
|
|
32232
34234
|
resolveParagraphBulletInfo(paragraph, paragraphIndex, txBody, inheritedTxBody, isBodyPlaceholder = false, slidePath) {
|
|
32233
34235
|
if (!paragraph) {
|
|
32234
34236
|
return null;
|
|
@@ -32259,7 +34261,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32259
34261
|
if (candidate["a:buNone"]) {
|
|
32260
34262
|
return { none: true };
|
|
32261
34263
|
}
|
|
32262
|
-
if (candidate["a:buChar"] || candidate["a:buAutoNum"] || candidate["a:buBlip"]) {
|
|
34264
|
+
if (candidate["a:buChar"] || candidate["a:buAutoNum"] || candidate["a:buBlip"] || candidate["a:buFontTx"] !== void 0 || candidate["a:buClrTx"] !== void 0 || candidate["a:buSzTx"] !== void 0) {
|
|
32263
34265
|
resolvedBulletProps = candidate;
|
|
32264
34266
|
break;
|
|
32265
34267
|
}
|
|
@@ -32273,6 +34275,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32273
34275
|
}
|
|
32274
34276
|
const buFont = resolvedBulletProps["a:buFont"];
|
|
32275
34277
|
const fontFamily = buFont?.["@_typeface"] ? String(buFont["@_typeface"]) : void 0;
|
|
34278
|
+
const fontInherit = resolvedBulletProps["a:buFontTx"] !== void 0;
|
|
32276
34279
|
const buSzPct = resolvedBulletProps["a:buSzPct"];
|
|
32277
34280
|
let sizePercent;
|
|
32278
34281
|
if (buSzPct?.["@_val"] !== void 0) {
|
|
@@ -32289,6 +34292,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32289
34292
|
sizePts = ptsRaw / 100;
|
|
32290
34293
|
}
|
|
32291
34294
|
}
|
|
34295
|
+
const sizeInherit = resolvedBulletProps["a:buSzTx"] !== void 0;
|
|
32292
34296
|
const buClr = resolvedBulletProps["a:buClr"];
|
|
32293
34297
|
let color;
|
|
32294
34298
|
if (buClr) {
|
|
@@ -32297,6 +34301,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32297
34301
|
color = String(srgb["@_val"]);
|
|
32298
34302
|
}
|
|
32299
34303
|
}
|
|
34304
|
+
const colorInherit = resolvedBulletProps["a:buClrTx"] !== void 0;
|
|
32300
34305
|
const bulletChar = String(
|
|
32301
34306
|
resolvedBulletProps["a:buChar"]?.["@_char"] || ""
|
|
32302
34307
|
);
|
|
@@ -32306,7 +34311,10 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32306
34311
|
fontFamily,
|
|
32307
34312
|
sizePercent,
|
|
32308
34313
|
sizePts,
|
|
32309
|
-
color
|
|
34314
|
+
color,
|
|
34315
|
+
...fontInherit ? { fontInherit: true } : {},
|
|
34316
|
+
...colorInherit ? { colorInherit: true } : {},
|
|
34317
|
+
...sizeInherit ? { sizeInherit: true } : {}
|
|
32310
34318
|
};
|
|
32311
34319
|
}
|
|
32312
34320
|
const autoNum = resolvedBulletProps["a:buAutoNum"];
|
|
@@ -32321,7 +34329,10 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32321
34329
|
fontFamily,
|
|
32322
34330
|
sizePercent,
|
|
32323
34331
|
sizePts,
|
|
32324
|
-
color
|
|
34332
|
+
color,
|
|
34333
|
+
...fontInherit ? { fontInherit: true } : {},
|
|
34334
|
+
...colorInherit ? { colorInherit: true } : {},
|
|
34335
|
+
...sizeInherit ? { sizeInherit: true } : {}
|
|
32325
34336
|
};
|
|
32326
34337
|
}
|
|
32327
34338
|
const buBlip = resolvedBulletProps["a:buBlip"];
|
|
@@ -32433,7 +34444,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32433
34444
|
};
|
|
32434
34445
|
|
|
32435
34446
|
// src/core/core/runtime/PptxHandlerRuntimeShapeBodyParsing.ts
|
|
32436
|
-
var
|
|
34447
|
+
var PptxHandlerRuntime42 = class _PptxHandlerRuntime extends PptxHandlerRuntime41 {
|
|
32437
34448
|
/**
|
|
32438
34449
|
* Parse `a:spLocks` attributes into a structured {@link PptxShapeLocks} object.
|
|
32439
34450
|
* Returns `undefined` when the node is absent or contains no lock attributes.
|
|
@@ -32528,7 +34539,8 @@ var PptxHandlerRuntime41 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
32528
34539
|
if (Number.isFinite(spcColRaw) && spcColRaw > 0) {
|
|
32529
34540
|
textStyle.columnSpacing = spcColRaw / _PptxHandlerRuntime.EMU_PER_PX;
|
|
32530
34541
|
}
|
|
32531
|
-
const
|
|
34542
|
+
const hOverflowRaw = bodyPr["@_horzOverflow"] ?? bodyPr["@_hOverflow"];
|
|
34543
|
+
const hOverflow = String(hOverflowRaw || "").trim();
|
|
32532
34544
|
if (hOverflow === "overflow" || hOverflow === "clip") {
|
|
32533
34545
|
textStyle.hOverflow = hOverflow;
|
|
32534
34546
|
}
|
|
@@ -32711,7 +34723,7 @@ var PptxHandlerRuntime41 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
32711
34723
|
};
|
|
32712
34724
|
|
|
32713
34725
|
// src/core/core/runtime/PptxHandlerRuntimeShapeTextParsing.ts
|
|
32714
|
-
var
|
|
34726
|
+
var PptxHandlerRuntime43 = class _PptxHandlerRuntime extends PptxHandlerRuntime42 {
|
|
32715
34727
|
/**
|
|
32716
34728
|
* Resolve paragraph-level styles (alignment, spacing, margins, tabs,
|
|
32717
34729
|
* level styles) for a single paragraph. Modifies `textStyle` in place
|
|
@@ -32893,7 +34905,7 @@ var PptxHandlerRuntime42 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
32893
34905
|
};
|
|
32894
34906
|
|
|
32895
34907
|
// src/core/core/runtime/PptxHandlerRuntimeShapeParagraphContentParsing.ts
|
|
32896
|
-
var
|
|
34908
|
+
var PptxHandlerRuntime44 = class extends PptxHandlerRuntime43 {
|
|
32897
34909
|
/**
|
|
32898
34910
|
* Collect text content (runs, fields, equations, bullets) for a single
|
|
32899
34911
|
* paragraph and return text parts + segments. The returned `seedStyle`
|
|
@@ -33076,6 +35088,23 @@ var PptxHandlerRuntime43 = class extends PptxHandlerRuntime42 {
|
|
|
33076
35088
|
parts.push("\n");
|
|
33077
35089
|
segments.push({ text: "\n", style: { ...mergedDefaultRunStyle } });
|
|
33078
35090
|
}
|
|
35091
|
+
const firstSegmentIndex = segments.length === 0 ? -1 : 0;
|
|
35092
|
+
if (firstSegmentIndex >= 0) {
|
|
35093
|
+
const pPrRaw = p["a:pPr"];
|
|
35094
|
+
const lvlRaw = pPrRaw?.["@_lvl"];
|
|
35095
|
+
if (lvlRaw !== void 0) {
|
|
35096
|
+
const lvlParsed = Number.parseInt(String(lvlRaw), 10);
|
|
35097
|
+
if (Number.isFinite(lvlParsed) && lvlParsed > 0) {
|
|
35098
|
+
segments[firstSegmentIndex].paragraphLevel = Math.min(Math.max(lvlParsed, 0), 8);
|
|
35099
|
+
}
|
|
35100
|
+
}
|
|
35101
|
+
const endParaRPrRaw = p["a:endParaRPr"];
|
|
35102
|
+
if (endParaRPrRaw && typeof endParaRPrRaw === "object") {
|
|
35103
|
+
segments[firstSegmentIndex].endParaRunProperties = {
|
|
35104
|
+
...endParaRPrRaw
|
|
35105
|
+
};
|
|
35106
|
+
}
|
|
35107
|
+
}
|
|
33079
35108
|
return { parts, segments, seedStyle };
|
|
33080
35109
|
}
|
|
33081
35110
|
/**
|
|
@@ -33185,7 +35214,7 @@ var PptxHandlerRuntime43 = class extends PptxHandlerRuntime42 {
|
|
|
33185
35214
|
};
|
|
33186
35215
|
|
|
33187
35216
|
// src/core/core/runtime/PptxHandlerRuntimeShapeParsing.ts
|
|
33188
|
-
var
|
|
35217
|
+
var PptxHandlerRuntime45 = class _PptxHandlerRuntime extends PptxHandlerRuntime44 {
|
|
33189
35218
|
parseShape(shape, id, slidePath) {
|
|
33190
35219
|
try {
|
|
33191
35220
|
const spPr = shape["p:spPr"];
|
|
@@ -33221,6 +35250,7 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33221
35250
|
let pathData;
|
|
33222
35251
|
let pathWidth;
|
|
33223
35252
|
let pathHeight;
|
|
35253
|
+
let customGeometryRawData;
|
|
33224
35254
|
const custGeom = effectiveSpPr?.["a:custGeom"];
|
|
33225
35255
|
if (custGeom) {
|
|
33226
35256
|
const customPath = this.parseCustomGeometry(
|
|
@@ -33233,6 +35263,7 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33233
35263
|
pathData = customPath.pathData;
|
|
33234
35264
|
pathWidth = customPath.pathWidth;
|
|
33235
35265
|
pathHeight = customPath.pathHeight;
|
|
35266
|
+
customGeometryRawData = this.extractCustomGeometryRawData(custGeom);
|
|
33236
35267
|
}
|
|
33237
35268
|
}
|
|
33238
35269
|
const geomNode = custGeom ?? effectiveSpPr?.["a:prstGeom"];
|
|
@@ -33390,7 +35421,8 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33390
35421
|
type: "shape",
|
|
33391
35422
|
pathData,
|
|
33392
35423
|
pathWidth,
|
|
33393
|
-
pathHeight
|
|
35424
|
+
pathHeight,
|
|
35425
|
+
customGeometryRawData
|
|
33394
35426
|
};
|
|
33395
35427
|
} catch (e) {
|
|
33396
35428
|
console.warn(`[pptx] Skipping shape element (${id}):`, e);
|
|
@@ -33400,7 +35432,7 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33400
35432
|
};
|
|
33401
35433
|
|
|
33402
35434
|
// src/core/core/runtime/PptxHandlerRuntimePictureParsing.ts
|
|
33403
|
-
var
|
|
35435
|
+
var PptxHandlerRuntime46 = class _PptxHandlerRuntime extends PptxHandlerRuntime45 {
|
|
33404
35436
|
async parsePicture(pic, id, slidePath) {
|
|
33405
35437
|
try {
|
|
33406
35438
|
const spPr = pic["p:spPr"];
|
|
@@ -33639,7 +35671,7 @@ var PptxHandlerRuntime45 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33639
35671
|
};
|
|
33640
35672
|
|
|
33641
35673
|
// src/core/core/runtime/PptxHandlerRuntimeSpTreeParsing.ts
|
|
33642
|
-
var
|
|
35674
|
+
var PptxHandlerRuntime47 = class _PptxHandlerRuntime extends PptxHandlerRuntime46 {
|
|
33643
35675
|
/**
|
|
33644
35676
|
* Known element tag names that appear as direct children of `p:spTree`
|
|
33645
35677
|
* (or `p:grpSp`) and represent renderable shapes/objects.
|
|
@@ -33984,9 +36016,18 @@ var PptxHandlerRuntime46 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33984
36016
|
* Unwrap mc:AlternateContent elements within a shape tree (or group),
|
|
33985
36017
|
* merging selected branch children into the parent element arrays.
|
|
33986
36018
|
* Delegates to the standalone alternate-content utility.
|
|
36019
|
+
*
|
|
36020
|
+
* Records each consumed AC envelope in {@link alternateContentBlockByRawXml}
|
|
36021
|
+
* so the save layer can re-emit the original `<mc:Choice>` /
|
|
36022
|
+
* `<mc:Fallback>` shape on dirty save (CC-4).
|
|
33987
36023
|
*/
|
|
33988
36024
|
unwrapAlternateContent(container) {
|
|
33989
|
-
unwrapAlternateContent(container);
|
|
36025
|
+
const blocks = unwrapAlternateContent(container);
|
|
36026
|
+
for (const block of blocks) {
|
|
36027
|
+
for (const ref of block.childRefs) {
|
|
36028
|
+
this.alternateContentBlockByRawXml.set(ref.node, block);
|
|
36029
|
+
}
|
|
36030
|
+
}
|
|
33990
36031
|
}
|
|
33991
36032
|
/**
|
|
33992
36033
|
* Forward declaration – implemented in PptxHandlerRuntimeGroupParsing.
|
|
@@ -33997,7 +36038,7 @@ var PptxHandlerRuntime46 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33997
36038
|
};
|
|
33998
36039
|
|
|
33999
36040
|
// src/core/core/runtime/PptxHandlerRuntimeGroupParsing.ts
|
|
34000
|
-
var
|
|
36041
|
+
var PptxHandlerRuntime48 = class _PptxHandlerRuntime extends PptxHandlerRuntime47 {
|
|
34001
36042
|
async parseGroupShape(group, baseId, slidePath, rawXmlStr) {
|
|
34002
36043
|
const grpSpPr = group["p:grpSpPr"];
|
|
34003
36044
|
const xfrm = grpSpPr?.["a:xfrm"];
|
|
@@ -34170,7 +36211,7 @@ var PptxHandlerRuntime47 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
34170
36211
|
};
|
|
34171
36212
|
|
|
34172
36213
|
// src/core/core/runtime/PptxHandlerRuntimeSlideParsing.ts
|
|
34173
|
-
var
|
|
36214
|
+
var PptxHandlerRuntime49 = class extends PptxHandlerRuntime48 {
|
|
34174
36215
|
/**
|
|
34175
36216
|
* Parse text body from a connector shape (p:cxnSp > p:txBody).
|
|
34176
36217
|
* Uses the same text run extraction logic as regular shapes but
|
|
@@ -34282,7 +36323,7 @@ var PptxHandlerRuntime48 = class extends PptxHandlerRuntime47 {
|
|
|
34282
36323
|
};
|
|
34283
36324
|
|
|
34284
36325
|
// src/core/core/runtime/PptxHandlerRuntimeColorAndEffects.ts
|
|
34285
|
-
var
|
|
36326
|
+
var PptxHandlerRuntime50 = class extends PptxHandlerRuntime49 {
|
|
34286
36327
|
/**
|
|
34287
36328
|
* Forward declaration – implemented in PptxHandlerRuntimeThemeProcessing.
|
|
34288
36329
|
* Re-resolves gradient stops by substituting `phClr` with the given colour.
|
|
@@ -34323,8 +36364,9 @@ var PptxHandlerRuntime49 = class extends PptxHandlerRuntime48 {
|
|
|
34323
36364
|
return void 0;
|
|
34324
36365
|
}
|
|
34325
36366
|
const resolvedKey = normalized === "phclr" ? "accent1" : normalized;
|
|
34326
|
-
|
|
34327
|
-
|
|
36367
|
+
const overrideMap = this.currentSlideClrMapOverride ?? this.currentMasterClrMap;
|
|
36368
|
+
if (overrideMap) {
|
|
36369
|
+
const remapped = overrideMap[resolvedKey];
|
|
34328
36370
|
if (remapped) {
|
|
34329
36371
|
return this.themeColorMap[remapped] || this.getDefaultSchemeColorMap()[remapped];
|
|
34330
36372
|
}
|
|
@@ -34407,7 +36449,7 @@ var PptxHandlerRuntime49 = class extends PptxHandlerRuntime48 {
|
|
|
34407
36449
|
};
|
|
34408
36450
|
|
|
34409
36451
|
// src/core/core/runtime/PptxHandlerRuntimeBackgroundParsing.ts
|
|
34410
|
-
var
|
|
36452
|
+
var PptxHandlerRuntime51 = class extends PptxHandlerRuntime50 {
|
|
34411
36453
|
async extractBackgroundImage(slideXml2, slidePath, rootElement = "p:sld") {
|
|
34412
36454
|
try {
|
|
34413
36455
|
const bg = slideXml2[rootElement]?.["p:cSld"]?.["p:bg"];
|
|
@@ -34618,7 +36660,7 @@ var PptxHandlerRuntime50 = class extends PptxHandlerRuntime49 {
|
|
|
34618
36660
|
};
|
|
34619
36661
|
|
|
34620
36662
|
// src/core/core/runtime/PptxHandlerRuntimeSlideUtils.ts
|
|
34621
|
-
var
|
|
36663
|
+
var PptxHandlerRuntime52 = class extends PptxHandlerRuntime51 {
|
|
34622
36664
|
/**
|
|
34623
36665
|
* Retrieve the background gradient from a layout, falling back to master.
|
|
34624
36666
|
*/
|
|
@@ -34689,6 +36731,64 @@ var PptxHandlerRuntime51 = class extends PptxHandlerRuntime50 {
|
|
|
34689
36731
|
}
|
|
34690
36732
|
return void 0;
|
|
34691
36733
|
}
|
|
36734
|
+
/**
|
|
36735
|
+
* Find the master file path referenced by a layout via its relationships.
|
|
36736
|
+
*/
|
|
36737
|
+
findMasterPathForLayoutBase(layoutPath) {
|
|
36738
|
+
const layoutRels = this.slideRelsMap.get(layoutPath);
|
|
36739
|
+
if (!layoutRels) {
|
|
36740
|
+
return void 0;
|
|
36741
|
+
}
|
|
36742
|
+
for (const [, target] of layoutRels.entries()) {
|
|
36743
|
+
if (target.includes("slideMaster")) {
|
|
36744
|
+
const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
|
|
36745
|
+
return target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${target.replace("../", "")}`;
|
|
36746
|
+
}
|
|
36747
|
+
}
|
|
36748
|
+
return void 0;
|
|
36749
|
+
}
|
|
36750
|
+
/**
|
|
36751
|
+
* Switch the active master state (clrMap + theme color/font/format
|
|
36752
|
+
* scheme) so that scheme-colour resolution for the slide currently
|
|
36753
|
+
* being parsed walks through the correct master.
|
|
36754
|
+
*
|
|
36755
|
+
* Multi-master decks must resolve scheme colours against each slide's
|
|
36756
|
+
* own master rather than always against `masterFiles[0]`.
|
|
36757
|
+
*
|
|
36758
|
+
* Phase 2 Stream B / C-H4.
|
|
36759
|
+
*/
|
|
36760
|
+
async setActiveMasterForSlide(slidePath) {
|
|
36761
|
+
const layoutPath = this.findLayoutPathForSlide(slidePath);
|
|
36762
|
+
if (!layoutPath) {
|
|
36763
|
+
this.currentMasterClrMap = null;
|
|
36764
|
+
this.themeColorMap = { ...this.globalThemeColorMapSnapshot };
|
|
36765
|
+
this.themeFontMap = { ...this.globalThemeFontMapSnapshot };
|
|
36766
|
+
this.themeFormatScheme = this.globalThemeFormatSchemeSnapshot;
|
|
36767
|
+
return;
|
|
36768
|
+
}
|
|
36769
|
+
if (!this.slideRelsMap.has(layoutPath)) {
|
|
36770
|
+
const layoutRelsPath = `${layoutPath.replace("slideLayouts/", "slideLayouts/_rels/")}.rels`;
|
|
36771
|
+
try {
|
|
36772
|
+
await this.loadSlideRelationships(layoutPath, layoutRelsPath);
|
|
36773
|
+
} catch {
|
|
36774
|
+
}
|
|
36775
|
+
}
|
|
36776
|
+
const masterPath = this.findMasterPathForLayoutBase(layoutPath);
|
|
36777
|
+
if (!masterPath) {
|
|
36778
|
+
this.currentMasterClrMap = null;
|
|
36779
|
+
this.themeColorMap = { ...this.globalThemeColorMapSnapshot };
|
|
36780
|
+
this.themeFontMap = { ...this.globalThemeFontMapSnapshot };
|
|
36781
|
+
this.themeFormatScheme = this.globalThemeFormatSchemeSnapshot;
|
|
36782
|
+
return;
|
|
36783
|
+
}
|
|
36784
|
+
this.currentMasterClrMap = this.masterClrMaps.get(masterPath) ?? null;
|
|
36785
|
+
const masterColorMap = this.masterThemeColorMaps.get(masterPath);
|
|
36786
|
+
this.themeColorMap = masterColorMap ? { ...masterColorMap } : { ...this.globalThemeColorMapSnapshot };
|
|
36787
|
+
const masterFontMap = this.masterThemeFontMaps.get(masterPath);
|
|
36788
|
+
this.themeFontMap = masterFontMap ? { ...masterFontMap } : { ...this.globalThemeFontMapSnapshot };
|
|
36789
|
+
const masterFormatScheme = this.masterThemeFormatSchemes.get(masterPath);
|
|
36790
|
+
this.themeFormatScheme = masterFormatScheme ?? this.globalThemeFormatSchemeSnapshot;
|
|
36791
|
+
}
|
|
34692
36792
|
/**
|
|
34693
36793
|
* Extract the `p:bg/@showAnimation` flag from a slide's XML.
|
|
34694
36794
|
* Returns `true` when the background should animate, `false` when
|
|
@@ -34829,7 +36929,7 @@ var PptxHandlerRuntime51 = class extends PptxHandlerRuntime50 {
|
|
|
34829
36929
|
};
|
|
34830
36930
|
|
|
34831
36931
|
// src/core/core/runtime/PptxHandlerRuntimePlaceholderStyles.ts
|
|
34832
|
-
var
|
|
36932
|
+
var PptxHandlerRuntime53 = class _PptxHandlerRuntime extends PptxHandlerRuntime52 {
|
|
34833
36933
|
/**
|
|
34834
36934
|
* Parse a single `a:lvlXpPr` node into a structured
|
|
34835
36935
|
* {@link PlaceholderTextLevelStyle}.
|
|
@@ -34950,7 +37050,7 @@ var PptxHandlerRuntime52 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
|
|
|
34950
37050
|
};
|
|
34951
37051
|
|
|
34952
37052
|
// src/core/core/runtime/PptxHandlerRuntimePlaceholderDefaults.ts
|
|
34953
|
-
var
|
|
37053
|
+
var PptxHandlerRuntime54 = class _PptxHandlerRuntime extends PptxHandlerRuntime53 {
|
|
34954
37054
|
/**
|
|
34955
37055
|
* Extract structured {@link PlaceholderDefaults} from a layout or master
|
|
34956
37056
|
* shape that carries a `p:ph` element.
|
|
@@ -35093,7 +37193,118 @@ var PptxHandlerRuntime53 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
|
|
|
35093
37193
|
};
|
|
35094
37194
|
|
|
35095
37195
|
// src/core/core/runtime/PptxHandlerRuntimeMasterElements.ts
|
|
35096
|
-
|
|
37196
|
+
function parseHeaderFooterFlags(hf) {
|
|
37197
|
+
if (!hf) {
|
|
37198
|
+
return void 0;
|
|
37199
|
+
}
|
|
37200
|
+
const result = {};
|
|
37201
|
+
if (hf["@_hdr"] !== void 0) {
|
|
37202
|
+
result.hasHeader = String(hf["@_hdr"]) !== "0";
|
|
37203
|
+
}
|
|
37204
|
+
if (hf["@_ftr"] !== void 0) {
|
|
37205
|
+
result.hasFooter = String(hf["@_ftr"]) !== "0";
|
|
37206
|
+
}
|
|
37207
|
+
if (hf["@_dt"] !== void 0) {
|
|
37208
|
+
result.hasDateTime = String(hf["@_dt"]) !== "0";
|
|
37209
|
+
}
|
|
37210
|
+
if (hf["@_sldNum"] !== void 0) {
|
|
37211
|
+
result.hasSlideNumber = String(hf["@_sldNum"]) !== "0";
|
|
37212
|
+
}
|
|
37213
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
37214
|
+
}
|
|
37215
|
+
var PptxHandlerRuntime55 = class extends PptxHandlerRuntime54 {
|
|
37216
|
+
/**
|
|
37217
|
+
* Parse a `CT_TextListStyle` node (`a:defPPr` + `a:lvl1pPr` … `a:lvl9pPr`)
|
|
37218
|
+
* into a level-keyed style map. Used for `<p:txStyles>` children
|
|
37219
|
+
* (`p:titleStyle`, `p:bodyStyle`, `p:otherStyle`) — see ECMA-376 §19.3.1.52.
|
|
37220
|
+
*/
|
|
37221
|
+
parseTextListStyle(node) {
|
|
37222
|
+
if (!node) {
|
|
37223
|
+
return void 0;
|
|
37224
|
+
}
|
|
37225
|
+
const levels = {};
|
|
37226
|
+
const defParsed = this.parsePlaceholderLevelStyle(node["a:defPPr"]);
|
|
37227
|
+
if (defParsed) {
|
|
37228
|
+
levels[-1] = defParsed;
|
|
37229
|
+
}
|
|
37230
|
+
for (let lvl = 1; lvl <= 9; lvl++) {
|
|
37231
|
+
const parsed = this.parsePlaceholderLevelStyle(
|
|
37232
|
+
node[`a:lvl${lvl}pPr`]
|
|
37233
|
+
);
|
|
37234
|
+
if (parsed) {
|
|
37235
|
+
levels[lvl - 1] = parsed;
|
|
37236
|
+
}
|
|
37237
|
+
}
|
|
37238
|
+
return Object.keys(levels).length > 0 ? levels : void 0;
|
|
37239
|
+
}
|
|
37240
|
+
/**
|
|
37241
|
+
* Parse `<p:txStyles>` from a slide-master XML object into a structured
|
|
37242
|
+
* {@link PptxMasterTextStyles}. Used to populate `PptxSlideMaster.txStyles`
|
|
37243
|
+
* so the title/body/other text-style cascade (P-H1) is visible on the
|
|
37244
|
+
* typed model.
|
|
37245
|
+
*/
|
|
37246
|
+
parseMasterTxStyles(masterXml) {
|
|
37247
|
+
const txStyles = masterXml?.["p:txStyles"];
|
|
37248
|
+
if (!txStyles) {
|
|
37249
|
+
return void 0;
|
|
37250
|
+
}
|
|
37251
|
+
const titleStyle = this.parseTextListStyle(txStyles["p:titleStyle"]);
|
|
37252
|
+
const bodyStyle = this.parseTextListStyle(txStyles["p:bodyStyle"]);
|
|
37253
|
+
const otherStyle = this.parseTextListStyle(txStyles["p:otherStyle"]);
|
|
37254
|
+
if (!titleStyle && !bodyStyle && !otherStyle) {
|
|
37255
|
+
return void 0;
|
|
37256
|
+
}
|
|
37257
|
+
const result = {};
|
|
37258
|
+
if (titleStyle) {
|
|
37259
|
+
result.titleStyle = titleStyle;
|
|
37260
|
+
}
|
|
37261
|
+
if (bodyStyle) {
|
|
37262
|
+
result.bodyStyle = bodyStyle;
|
|
37263
|
+
}
|
|
37264
|
+
if (otherStyle) {
|
|
37265
|
+
result.otherStyle = otherStyle;
|
|
37266
|
+
}
|
|
37267
|
+
return result;
|
|
37268
|
+
}
|
|
37269
|
+
/**
|
|
37270
|
+
* Enrich an array of {@link PptxSlideMaster} entries (already produced by
|
|
37271
|
+
* `parseSlideMasters`) with parsed `<p:txStyles>`. Loads each master's XML
|
|
37272
|
+
* once, parses, and caches it in `masterXmlMap` for downstream consumers.
|
|
37273
|
+
*
|
|
37274
|
+
* Also stores the parsed result on the per-master cache so that the
|
|
37275
|
+
* inheritance chain in `applyMasterTextStyleCascade` can find it without
|
|
37276
|
+
* re-parsing.
|
|
37277
|
+
*/
|
|
37278
|
+
async enrichSlideMastersWithTxStyles(slideMasters) {
|
|
37279
|
+
for (const master of slideMasters) {
|
|
37280
|
+
try {
|
|
37281
|
+
let masterXmlObj = this.masterXmlMap.get(master.path);
|
|
37282
|
+
if (!masterXmlObj) {
|
|
37283
|
+
const xmlStr = await this.zip.file(master.path)?.async("string");
|
|
37284
|
+
if (!xmlStr) {
|
|
37285
|
+
continue;
|
|
37286
|
+
}
|
|
37287
|
+
masterXmlObj = this.parser.parse(xmlStr);
|
|
37288
|
+
this.masterXmlMap.set(master.path, masterXmlObj);
|
|
37289
|
+
}
|
|
37290
|
+
const sldMaster = masterXmlObj["p:sldMaster"];
|
|
37291
|
+
if (!sldMaster) {
|
|
37292
|
+
continue;
|
|
37293
|
+
}
|
|
37294
|
+
const parsed = this.parseMasterTxStyles(sldMaster);
|
|
37295
|
+
if (parsed) {
|
|
37296
|
+
master.txStyles = parsed;
|
|
37297
|
+
this.masterTxStylesCache.set(master.path, parsed);
|
|
37298
|
+
}
|
|
37299
|
+
const hf = parseHeaderFooterFlags(sldMaster["p:hf"]);
|
|
37300
|
+
if (hf) {
|
|
37301
|
+
master.headerFooter = hf;
|
|
37302
|
+
}
|
|
37303
|
+
} catch (e) {
|
|
37304
|
+
console.warn("Failed to parse master txStyles:", e);
|
|
37305
|
+
}
|
|
37306
|
+
}
|
|
37307
|
+
}
|
|
35097
37308
|
parsePresentationDefaultTextStyle() {
|
|
35098
37309
|
const presentation = this.presentationData?.["p:presentation"];
|
|
35099
37310
|
const defaultTextStyle = presentation?.["p:defaultTextStyle"];
|
|
@@ -35249,7 +37460,7 @@ var PptxHandlerRuntime54 = class extends PptxHandlerRuntime53 {
|
|
|
35249
37460
|
};
|
|
35250
37461
|
|
|
35251
37462
|
// src/core/core/runtime/PptxHandlerRuntimeLayoutElements.ts
|
|
35252
|
-
var
|
|
37463
|
+
var PptxHandlerRuntime56 = class extends PptxHandlerRuntime55 {
|
|
35253
37464
|
async getLayoutElements(slidePath) {
|
|
35254
37465
|
const slideRels = this.slideRelsMap.get(slidePath);
|
|
35255
37466
|
if (!slideRels) {
|
|
@@ -35373,10 +37584,10 @@ var PptxHandlerRuntime55 = class extends PptxHandlerRuntime54 {
|
|
|
35373
37584
|
}
|
|
35374
37585
|
}
|
|
35375
37586
|
}
|
|
35376
|
-
this.currentSlideClrMapOverride = prevClrMapOverride;
|
|
35377
37587
|
const layoutShowMasterSp = layoutXmlObj["p:sldLayout"]?.["@_showMasterSp"];
|
|
35378
37588
|
const showMasterSp = layoutShowMasterSp === void 0 || String(layoutShowMasterSp).trim().toLowerCase() !== "0" && String(layoutShowMasterSp).trim().toLowerCase() !== "false";
|
|
35379
37589
|
const masterElements = showMasterSp ? await this.getMasterElements(layoutPath) : [];
|
|
37590
|
+
this.currentSlideClrMapOverride = prevClrMapOverride;
|
|
35380
37591
|
const allElements = [...masterElements, ...elements];
|
|
35381
37592
|
this.layoutCache.set(layoutPath, allElements);
|
|
35382
37593
|
return allElements;
|
|
@@ -35388,7 +37599,7 @@ var PptxHandlerRuntime55 = class extends PptxHandlerRuntime54 {
|
|
|
35388
37599
|
};
|
|
35389
37600
|
|
|
35390
37601
|
// src/core/core/runtime/PptxHandlerRuntimeThemeFormatScheme.ts
|
|
35391
|
-
var
|
|
37602
|
+
var PptxHandlerRuntime57 = class _PptxHandlerRuntime extends PptxHandlerRuntime56 {
|
|
35392
37603
|
/**
|
|
35393
37604
|
* Collect fill-style children from a style list node, preserving
|
|
35394
37605
|
* document order. Handles `a:solidFill`, `a:gradFill`, `a:pattFill`,
|
|
@@ -35630,7 +37841,7 @@ var PptxHandlerRuntime56 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
|
|
|
35630
37841
|
};
|
|
35631
37842
|
|
|
35632
37843
|
// src/core/core/runtime/PptxHandlerRuntimeThemeOverrides.ts
|
|
35633
|
-
var
|
|
37844
|
+
var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
|
|
35634
37845
|
/**
|
|
35635
37846
|
* Parse the `a:fmtScheme` element from the theme into a structured
|
|
35636
37847
|
* {@link PptxThemeFormatScheme}. Each sub-list (fillStyleLst, lnStyleLst,
|
|
@@ -35827,8 +38038,10 @@ var PptxHandlerRuntime57 = class extends PptxHandlerRuntime56 {
|
|
|
35827
38038
|
}
|
|
35828
38039
|
const fontScheme = root["a:fontScheme"];
|
|
35829
38040
|
if (fontScheme) {
|
|
35830
|
-
const
|
|
35831
|
-
const
|
|
38041
|
+
const majorFontNode = fontScheme["a:majorFont"];
|
|
38042
|
+
const minorFontNode = fontScheme["a:minorFont"];
|
|
38043
|
+
const majorLatin = majorFontNode?.["a:latin"];
|
|
38044
|
+
const minorLatin = minorFontNode?.["a:latin"];
|
|
35832
38045
|
const majorFont = this.normalizeTypefaceToken(String(majorLatin?.["@_typeface"] || ""));
|
|
35833
38046
|
const minorFont = this.normalizeTypefaceToken(String(minorLatin?.["@_typeface"] || ""));
|
|
35834
38047
|
if (!result.colorOverrides) {
|
|
@@ -35851,13 +38064,46 @@ var PptxHandlerRuntime57 = class extends PptxHandlerRuntime56 {
|
|
|
35851
38064
|
};
|
|
35852
38065
|
|
|
35853
38066
|
// src/core/core/runtime/PptxHandlerRuntimeThemeRefResolution.ts
|
|
35854
|
-
var
|
|
38067
|
+
var COLOR_CHOICE_KEYS2 = [
|
|
38068
|
+
"a:scrgbClr",
|
|
38069
|
+
"a:srgbClr",
|
|
38070
|
+
"a:hslClr",
|
|
38071
|
+
"a:sysClr",
|
|
38072
|
+
"a:schemeClr",
|
|
38073
|
+
"a:prstClr"
|
|
38074
|
+
];
|
|
38075
|
+
var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
|
|
38076
|
+
/**
|
|
38077
|
+
* Pull the verbatim colour-choice child out of a style-matrix-reference
|
|
38078
|
+
* element (`a:lnRef`/`a:fillRef`/`a:effectRef`/`a:fontRef`). Returns the
|
|
38079
|
+
* full child object so it can be round-tripped at save time, preserving
|
|
38080
|
+
* any contained colour transforms (`a:lumMod`, `a:tint`, etc.).
|
|
38081
|
+
*/
|
|
38082
|
+
extractRefColorXml(refNode) {
|
|
38083
|
+
if (!refNode) {
|
|
38084
|
+
return void 0;
|
|
38085
|
+
}
|
|
38086
|
+
for (const key of COLOR_CHOICE_KEYS2) {
|
|
38087
|
+
const child = refNode[key];
|
|
38088
|
+
if (child !== void 0) {
|
|
38089
|
+
return { [key]: child };
|
|
38090
|
+
}
|
|
38091
|
+
}
|
|
38092
|
+
return void 0;
|
|
38093
|
+
}
|
|
35855
38094
|
/**
|
|
35856
38095
|
* Resolve a `a:effectRef` element into concrete effect properties
|
|
35857
38096
|
* by looking up `@_idx` in the theme format scheme's effect style list.
|
|
35858
38097
|
*/
|
|
35859
38098
|
resolveThemeEffectRef(refNode, style) {
|
|
35860
38099
|
const idx = parseInt(String(refNode["@_idx"] || "0"), 10);
|
|
38100
|
+
if (Number.isFinite(idx) && idx > 0) {
|
|
38101
|
+
style.effectRefIdx = idx;
|
|
38102
|
+
}
|
|
38103
|
+
const overrideColorXml = this.extractRefColorXml(refNode);
|
|
38104
|
+
if (overrideColorXml) {
|
|
38105
|
+
style.effectRefColorXml = overrideColorXml;
|
|
38106
|
+
}
|
|
35861
38107
|
if (!Number.isFinite(idx) || idx <= 0 || !this.themeFormatScheme || idx > this.themeFormatScheme.effectStyles.length) {
|
|
35862
38108
|
return;
|
|
35863
38109
|
}
|
|
@@ -35910,6 +38156,13 @@ var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
|
|
|
35910
38156
|
resolveThemeLineRef(refNode, style) {
|
|
35911
38157
|
const idx = parseInt(String(refNode["@_idx"] || "0"), 10);
|
|
35912
38158
|
const overrideColor = this.parseColor(refNode);
|
|
38159
|
+
if (Number.isFinite(idx) && idx > 0) {
|
|
38160
|
+
style.lnRefIdx = idx;
|
|
38161
|
+
}
|
|
38162
|
+
const overrideColorXml = this.extractRefColorXml(refNode);
|
|
38163
|
+
if (overrideColorXml) {
|
|
38164
|
+
style.lnRefColorXml = overrideColorXml;
|
|
38165
|
+
}
|
|
35913
38166
|
if (!Number.isFinite(idx) || idx <= 0 || !this.themeFormatScheme || idx > this.themeFormatScheme.lineStyles.length) {
|
|
35914
38167
|
style.strokeColor = overrideColor;
|
|
35915
38168
|
if (overrideColor) {
|
|
@@ -35981,6 +38234,13 @@ var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
|
|
|
35981
38234
|
*/
|
|
35982
38235
|
resolveThemeFillRef(refNode, style) {
|
|
35983
38236
|
const idx = parseInt(String(refNode["@_idx"] || "0"), 10);
|
|
38237
|
+
if (Number.isFinite(idx) && idx > 0) {
|
|
38238
|
+
style.fillRefIdx = idx;
|
|
38239
|
+
}
|
|
38240
|
+
const overrideColorXml = this.extractRefColorXml(refNode);
|
|
38241
|
+
if (overrideColorXml) {
|
|
38242
|
+
style.fillRefColorXml = overrideColorXml;
|
|
38243
|
+
}
|
|
35984
38244
|
if (!Number.isFinite(idx) || idx <= 0 || !this.themeFormatScheme) {
|
|
35985
38245
|
style.fillMode = "theme";
|
|
35986
38246
|
style.fillColor = this.parseColor(refNode);
|
|
@@ -36046,7 +38306,7 @@ var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
|
|
|
36046
38306
|
};
|
|
36047
38307
|
|
|
36048
38308
|
// src/core/core/runtime/PptxHandlerRuntimeThemeLoading.ts
|
|
36049
|
-
var
|
|
38309
|
+
var PptxHandlerRuntime60 = class extends PptxHandlerRuntime59 {
|
|
36050
38310
|
async resolvePrimaryThemePath() {
|
|
36051
38311
|
const masterFiles = this.zip.file(/^ppt\/slideMasters\/slideMaster\d+\.xml$/);
|
|
36052
38312
|
if (!masterFiles || masterFiles.length === 0) {
|
|
@@ -36156,62 +38416,97 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
|
|
|
36156
38416
|
formatScheme: this.themeFormatScheme
|
|
36157
38417
|
};
|
|
36158
38418
|
}
|
|
36159
|
-
|
|
38419
|
+
/**
|
|
38420
|
+
* Parse every slide master's `<p:clrMap>` element and store the alias
|
|
38421
|
+
* dictionaries on {@link masterClrMaps}. Do *not* mutate
|
|
38422
|
+
* {@link themeColorMap} — alias resolution happens at colour-lookup
|
|
38423
|
+
* time so that:
|
|
38424
|
+
*
|
|
38425
|
+
* 1. The raw theme scheme stays the source of truth (clrMap is a
|
|
38426
|
+
* routing layer, not a colour table).
|
|
38427
|
+
* 2. Multi-master decks resolve each slide against its own master's
|
|
38428
|
+
* clrMap rather than always against `masterFiles[0]`.
|
|
38429
|
+
* 3. Layout `clrMapOvr` semantics work correctly when a slide's master
|
|
38430
|
+
* differs from the deck's first master.
|
|
38431
|
+
*
|
|
38432
|
+
* Phase 2 Stream B / C-H4.
|
|
38433
|
+
*/
|
|
38434
|
+
async applySlideMasterColorMap(_defaultMap) {
|
|
36160
38435
|
const masterFiles = this.zip.file(/^ppt\/slideMasters\/slideMaster\d+\.xml$/);
|
|
36161
38436
|
if (!masterFiles || masterFiles.length === 0) {
|
|
36162
38437
|
return;
|
|
36163
38438
|
}
|
|
36164
|
-
|
|
36165
|
-
|
|
36166
|
-
|
|
36167
|
-
|
|
36168
|
-
|
|
36169
|
-
|
|
36170
|
-
|
|
36171
|
-
|
|
36172
|
-
|
|
36173
|
-
|
|
36174
|
-
|
|
36175
|
-
|
|
36176
|
-
|
|
36177
|
-
|
|
36178
|
-
|
|
36179
|
-
|
|
36180
|
-
"
|
|
36181
|
-
|
|
36182
|
-
"
|
|
36183
|
-
|
|
36184
|
-
];
|
|
36185
|
-
for (const aliasKey of aliasKeys) {
|
|
36186
|
-
const mappedKey = String(clrMap[`@_${aliasKey}`] || "").trim().toLowerCase();
|
|
36187
|
-
if (!mappedKey) {
|
|
38439
|
+
const aliasKeys = [
|
|
38440
|
+
"bg1",
|
|
38441
|
+
"tx1",
|
|
38442
|
+
"bg2",
|
|
38443
|
+
"tx2",
|
|
38444
|
+
"accent1",
|
|
38445
|
+
"accent2",
|
|
38446
|
+
"accent3",
|
|
38447
|
+
"accent4",
|
|
38448
|
+
"accent5",
|
|
38449
|
+
"accent6",
|
|
38450
|
+
"hlink",
|
|
38451
|
+
"folHlink"
|
|
38452
|
+
];
|
|
38453
|
+
for (const file of masterFiles) {
|
|
38454
|
+
try {
|
|
38455
|
+
const masterXml = await file.async("string");
|
|
38456
|
+
const masterData = this.parser.parse(masterXml);
|
|
38457
|
+
const clrMap = masterData?.["p:sldMaster"]?.["p:clrMap"];
|
|
38458
|
+
if (!clrMap) {
|
|
36188
38459
|
continue;
|
|
36189
38460
|
}
|
|
36190
|
-
const
|
|
36191
|
-
|
|
36192
|
-
|
|
38461
|
+
const aliasMap = {};
|
|
38462
|
+
for (const aliasKey of aliasKeys) {
|
|
38463
|
+
const mappedKey = String(clrMap[`@_${aliasKey}`] || "").trim().toLowerCase();
|
|
38464
|
+
if (mappedKey) {
|
|
38465
|
+
aliasMap[aliasKey] = mappedKey;
|
|
38466
|
+
}
|
|
38467
|
+
}
|
|
38468
|
+
if (Object.keys(aliasMap).length > 0) {
|
|
38469
|
+
this.masterClrMaps.set(file.name, aliasMap);
|
|
36193
38470
|
}
|
|
38471
|
+
} catch (error) {
|
|
38472
|
+
console.warn(`Failed to parse slide master color map for ${file.name}:`, error);
|
|
36194
38473
|
}
|
|
36195
|
-
} catch (error) {
|
|
36196
|
-
console.warn("Failed to parse slide master color map:", error);
|
|
36197
38474
|
}
|
|
36198
38475
|
}
|
|
36199
|
-
|
|
36200
|
-
|
|
36201
|
-
|
|
36202
|
-
|
|
38476
|
+
/**
|
|
38477
|
+
* Parse a single theme part into structured colour, font, and format
|
|
38478
|
+
* scheme dictionaries. Used both for the global default theme and for
|
|
38479
|
+
* each master's per-master theme (multi-master support).
|
|
38480
|
+
*
|
|
38481
|
+
* Phase 2 Stream B / C-H4.
|
|
38482
|
+
*/
|
|
38483
|
+
async parseThemePart(themePath) {
|
|
38484
|
+
const themeFile = this.zip.file(themePath);
|
|
38485
|
+
if (!themeFile) {
|
|
38486
|
+
return null;
|
|
36203
38487
|
}
|
|
36204
|
-
const preferredThemePath = await this.resolvePrimaryThemePath();
|
|
36205
|
-
const preferredThemeFile = preferredThemePath ? themeFiles.find((file) => file.name === preferredThemePath) : void 0;
|
|
36206
|
-
const themeFile = preferredThemeFile ?? themeFiles[0];
|
|
36207
38488
|
const themeXml2 = await themeFile.async("string");
|
|
38489
|
+
this.originalThemeXmlByPath.set(themePath, themeXml2);
|
|
36208
38490
|
const themeData = this.parser.parse(themeXml2);
|
|
36209
38491
|
const themeRoot = themeData["a:theme"];
|
|
36210
38492
|
const themeElements = themeRoot?.["a:themeElements"];
|
|
36211
38493
|
const colorScheme = themeElements?.["a:clrScheme"];
|
|
36212
38494
|
const fontScheme = themeElements?.["a:fontScheme"];
|
|
38495
|
+
const fmtScheme = themeElements?.["a:fmtScheme"];
|
|
38496
|
+
const themeName = String(themeRoot?.["@_name"] || "").trim();
|
|
38497
|
+
if (themeName) {
|
|
38498
|
+
this.masterThemeNames.set(themePath, themeName);
|
|
38499
|
+
}
|
|
38500
|
+
const colorSchemeName = String(colorScheme?.["@_name"] || "").trim();
|
|
38501
|
+
if (colorSchemeName) {
|
|
38502
|
+
this.masterThemeColorSchemeNames.set(themePath, colorSchemeName);
|
|
38503
|
+
}
|
|
38504
|
+
const fontSchemeName = String(fontScheme?.["@_name"] || "").trim();
|
|
38505
|
+
if (fontSchemeName) {
|
|
38506
|
+
this.masterThemeFontSchemeNames.set(themePath, fontSchemeName);
|
|
38507
|
+
}
|
|
36213
38508
|
const defaultMap = this.getDefaultSchemeColorMap();
|
|
36214
|
-
|
|
38509
|
+
const colorMap = { ...defaultMap };
|
|
36215
38510
|
if (colorScheme) {
|
|
36216
38511
|
const schemeKeys = [
|
|
36217
38512
|
"dk1",
|
|
@@ -36231,39 +38526,196 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
|
|
|
36231
38526
|
const colorNode = colorScheme[`a:${key}`];
|
|
36232
38527
|
const parsed = this.parseColorChoice(colorNode);
|
|
36233
38528
|
if (parsed) {
|
|
36234
|
-
|
|
38529
|
+
colorMap[key] = parsed;
|
|
36235
38530
|
}
|
|
36236
38531
|
}
|
|
36237
38532
|
}
|
|
36238
|
-
|
|
36239
|
-
|
|
36240
|
-
|
|
36241
|
-
|
|
36242
|
-
|
|
36243
|
-
const
|
|
36244
|
-
const
|
|
38533
|
+
colorMap["tx1"] = colorMap["dk1"] || defaultMap["dk1"];
|
|
38534
|
+
colorMap["bg1"] = colorMap["lt1"] || defaultMap["lt1"];
|
|
38535
|
+
colorMap["tx2"] = colorMap["dk2"] || defaultMap["dk2"];
|
|
38536
|
+
colorMap["bg2"] = colorMap["lt2"] || defaultMap["lt2"];
|
|
38537
|
+
const majorFontNode = fontScheme?.["a:majorFont"];
|
|
38538
|
+
const minorFontNode = fontScheme?.["a:minorFont"];
|
|
38539
|
+
const majorLatin = majorFontNode?.["a:latin"];
|
|
38540
|
+
const minorLatin = minorFontNode?.["a:latin"];
|
|
36245
38541
|
const majorFont = this.normalizeTypefaceToken(String(majorLatin?.["@_typeface"] || ""));
|
|
36246
38542
|
const minorFont = this.normalizeTypefaceToken(String(minorLatin?.["@_typeface"] || ""));
|
|
36247
|
-
|
|
38543
|
+
const fontMap = {};
|
|
36248
38544
|
if (majorFont) {
|
|
36249
|
-
|
|
36250
|
-
|
|
36251
|
-
|
|
38545
|
+
fontMap["mj-lt"] = majorFont;
|
|
38546
|
+
fontMap["mj-ea"] = majorFont;
|
|
38547
|
+
fontMap["mj-cs"] = majorFont;
|
|
36252
38548
|
}
|
|
36253
38549
|
if (minorFont) {
|
|
36254
|
-
|
|
36255
|
-
|
|
36256
|
-
|
|
38550
|
+
fontMap["mn-lt"] = minorFont;
|
|
38551
|
+
fontMap["mn-ea"] = minorFont;
|
|
38552
|
+
fontMap["mn-cs"] = minorFont;
|
|
36257
38553
|
}
|
|
36258
|
-
const
|
|
36259
|
-
|
|
36260
|
-
|
|
38554
|
+
const majorEa = this.normalizeTypefaceToken(
|
|
38555
|
+
String(majorFontNode?.["a:ea"]?.["@_typeface"] || "")
|
|
38556
|
+
);
|
|
38557
|
+
if (majorEa) {
|
|
38558
|
+
fontMap["mj-ea"] = majorEa;
|
|
38559
|
+
}
|
|
38560
|
+
const majorCs = this.normalizeTypefaceToken(
|
|
38561
|
+
String(majorFontNode?.["a:cs"]?.["@_typeface"] || "")
|
|
38562
|
+
);
|
|
38563
|
+
if (majorCs) {
|
|
38564
|
+
fontMap["mj-cs"] = majorCs;
|
|
38565
|
+
}
|
|
38566
|
+
const minorEa = this.normalizeTypefaceToken(
|
|
38567
|
+
String(minorFontNode?.["a:ea"]?.["@_typeface"] || "")
|
|
38568
|
+
);
|
|
38569
|
+
if (minorEa) {
|
|
38570
|
+
fontMap["mn-ea"] = minorEa;
|
|
38571
|
+
}
|
|
38572
|
+
const minorCs = this.normalizeTypefaceToken(
|
|
38573
|
+
String(minorFontNode?.["a:cs"]?.["@_typeface"] || "")
|
|
38574
|
+
);
|
|
38575
|
+
if (minorCs) {
|
|
38576
|
+
fontMap["mn-cs"] = minorCs;
|
|
38577
|
+
}
|
|
38578
|
+
const majorScripts = this.collectFontScriptOverrides(majorFontNode);
|
|
38579
|
+
if (Object.keys(majorScripts).length > 0) {
|
|
38580
|
+
this.masterThemeMajorFontScripts.set(themePath, majorScripts);
|
|
38581
|
+
}
|
|
38582
|
+
const minorScripts = this.collectFontScriptOverrides(minorFontNode);
|
|
38583
|
+
if (Object.keys(minorScripts).length > 0) {
|
|
38584
|
+
this.masterThemeMinorFontScripts.set(themePath, minorScripts);
|
|
38585
|
+
}
|
|
38586
|
+
const objectDefaultsNode = themeRoot?.["a:objectDefaults"];
|
|
38587
|
+
if (objectDefaultsNode) {
|
|
38588
|
+
const od = {
|
|
38589
|
+
spDef: objectDefaultsNode["a:spDef"],
|
|
38590
|
+
lnDef: objectDefaultsNode["a:lnDef"],
|
|
38591
|
+
txDef: objectDefaultsNode["a:txDef"]
|
|
38592
|
+
};
|
|
38593
|
+
if (od.spDef !== void 0 || od.lnDef !== void 0 || od.txDef !== void 0) {
|
|
38594
|
+
this.masterThemeObjectDefaults.set(themePath, od);
|
|
38595
|
+
}
|
|
38596
|
+
}
|
|
38597
|
+
const extraClrSchemeLst = themeRoot?.["a:extraClrSchemeLst"];
|
|
38598
|
+
if (extraClrSchemeLst !== void 0) {
|
|
38599
|
+
this.masterThemeExtraClrSchemeLst.set(themePath, extraClrSchemeLst);
|
|
38600
|
+
}
|
|
38601
|
+
const custClrLst = themeRoot?.["a:custClrLst"];
|
|
38602
|
+
if (custClrLst !== void 0) {
|
|
38603
|
+
this.masterThemeCustClrLst.set(themePath, custClrLst);
|
|
38604
|
+
}
|
|
38605
|
+
const themeExtLst = themeRoot?.["a:extLst"];
|
|
38606
|
+
if (themeExtLst !== void 0) {
|
|
38607
|
+
this.masterThemeExtLst.set(themePath, themeExtLst);
|
|
38608
|
+
}
|
|
38609
|
+
const formatScheme = fmtScheme ? this.parseFormatScheme(fmtScheme) : void 0;
|
|
38610
|
+
return { colorMap, fontMap, formatScheme };
|
|
38611
|
+
}
|
|
38612
|
+
/**
|
|
38613
|
+
* Parse `<a:font script="…" typeface="…"/>` children of a major or
|
|
38614
|
+
* minor font node into a `script -> typeface` dictionary.
|
|
38615
|
+
*
|
|
38616
|
+
* fast-xml-parser collapses repeated tags into arrays, so iterate
|
|
38617
|
+
* over the array form regardless of how many siblings are present.
|
|
38618
|
+
*
|
|
38619
|
+
* Phase 4 Stream A / M4.
|
|
38620
|
+
*/
|
|
38621
|
+
collectFontScriptOverrides(fontNode) {
|
|
38622
|
+
const overrides = {};
|
|
38623
|
+
if (!fontNode) {
|
|
38624
|
+
return overrides;
|
|
38625
|
+
}
|
|
38626
|
+
const fontEntries = this.ensureArray(fontNode["a:font"]);
|
|
38627
|
+
for (const entry of fontEntries) {
|
|
38628
|
+
const script = String(entry?.["@_script"] || "").trim();
|
|
38629
|
+
const typeface = this.normalizeTypefaceToken(String(entry?.["@_typeface"] || ""));
|
|
38630
|
+
if (script && typeface) {
|
|
38631
|
+
overrides[script] = typeface;
|
|
38632
|
+
}
|
|
38633
|
+
}
|
|
38634
|
+
return overrides;
|
|
38635
|
+
}
|
|
38636
|
+
/**
|
|
38637
|
+
* Resolve the theme file path referenced by a given master's `.rels`.
|
|
38638
|
+
* Returns `undefined` when the master has no theme relationship.
|
|
38639
|
+
*/
|
|
38640
|
+
async resolveThemePathForMaster(masterPath) {
|
|
38641
|
+
const relsPath = masterPath.replace(
|
|
38642
|
+
/ppt\/slideMasters\/(slideMaster\d+)\.xml/,
|
|
38643
|
+
"ppt/slideMasters/_rels/$1.xml.rels"
|
|
38644
|
+
);
|
|
38645
|
+
const relsXml = this.zip.file(relsPath);
|
|
38646
|
+
if (!relsXml) {
|
|
38647
|
+
return void 0;
|
|
38648
|
+
}
|
|
38649
|
+
const relsData = this.parser.parse(await relsXml.async("string"));
|
|
38650
|
+
const relNodes = this.ensureArray(relsData?.Relationships?.Relationship);
|
|
38651
|
+
for (const rel of relNodes) {
|
|
38652
|
+
const target = String(rel["@_Target"] || "");
|
|
38653
|
+
if (!target.includes("theme")) {
|
|
38654
|
+
continue;
|
|
38655
|
+
}
|
|
38656
|
+
const themePath = target.startsWith("..") ? this.resolvePath(masterPath.substring(0, masterPath.lastIndexOf("/") + 1), target) : target.startsWith("/") ? target.slice(1) : `ppt/${target.replace(/^\.?\//, "")}`;
|
|
38657
|
+
if (themePath.startsWith("ppt/theme/")) {
|
|
38658
|
+
return themePath;
|
|
38659
|
+
}
|
|
38660
|
+
}
|
|
38661
|
+
return void 0;
|
|
38662
|
+
}
|
|
38663
|
+
/**
|
|
38664
|
+
* Populate {@link masterThemeColorMaps}, {@link masterThemeFontMaps},
|
|
38665
|
+
* and {@link masterThemeFormatSchemes} for every slide master in the
|
|
38666
|
+
* deck. Multi-master support — Phase 2 Stream B / C-H4.
|
|
38667
|
+
*/
|
|
38668
|
+
async loadPerMasterThemes() {
|
|
38669
|
+
const masterFiles = this.zip.file(/^ppt\/slideMasters\/slideMaster\d+\.xml$/);
|
|
38670
|
+
if (!masterFiles || masterFiles.length === 0) {
|
|
38671
|
+
return;
|
|
38672
|
+
}
|
|
38673
|
+
for (const file of masterFiles) {
|
|
38674
|
+
try {
|
|
38675
|
+
const themePath = await this.resolveThemePathForMaster(file.name);
|
|
38676
|
+
if (!themePath) {
|
|
38677
|
+
continue;
|
|
38678
|
+
}
|
|
38679
|
+
this.masterThemePaths.set(file.name, themePath);
|
|
38680
|
+
const parsed = await this.parseThemePart(themePath);
|
|
38681
|
+
if (!parsed) {
|
|
38682
|
+
continue;
|
|
38683
|
+
}
|
|
38684
|
+
this.masterThemeColorMaps.set(file.name, parsed.colorMap);
|
|
38685
|
+
this.masterThemeFontMaps.set(file.name, parsed.fontMap);
|
|
38686
|
+
if (parsed.formatScheme) {
|
|
38687
|
+
this.masterThemeFormatSchemes.set(file.name, parsed.formatScheme);
|
|
38688
|
+
}
|
|
38689
|
+
} catch (error) {
|
|
38690
|
+
console.warn(`Failed to load per-master theme for ${file.name}:`, error);
|
|
38691
|
+
}
|
|
38692
|
+
}
|
|
38693
|
+
}
|
|
38694
|
+
async loadThemeData() {
|
|
38695
|
+
const themeFiles = this.zip.file(/^ppt\/theme\/theme\d+\.xml$/);
|
|
38696
|
+
if (!themeFiles || themeFiles.length === 0) {
|
|
38697
|
+
return;
|
|
36261
38698
|
}
|
|
38699
|
+
const preferredThemePath = await this.resolvePrimaryThemePath();
|
|
38700
|
+
const themeFile = preferredThemePath ? themeFiles.find((file) => file.name === preferredThemePath) ?? themeFiles[0] : themeFiles[0];
|
|
38701
|
+
const parsed = await this.parseThemePart(themeFile.name);
|
|
38702
|
+
if (parsed) {
|
|
38703
|
+
this.themeColorMap = parsed.colorMap;
|
|
38704
|
+
this.themeFontMap = parsed.fontMap;
|
|
38705
|
+
if (parsed.formatScheme) {
|
|
38706
|
+
this.themeFormatScheme = parsed.formatScheme;
|
|
38707
|
+
}
|
|
38708
|
+
}
|
|
38709
|
+
await this.applySlideMasterColorMap(this.getDefaultSchemeColorMap());
|
|
38710
|
+
await this.loadPerMasterThemes();
|
|
38711
|
+
this.globalThemeColorMapSnapshot = { ...this.themeColorMap };
|
|
38712
|
+
this.globalThemeFontMapSnapshot = { ...this.themeFontMap };
|
|
38713
|
+
this.globalThemeFormatSchemeSnapshot = this.themeFormatScheme;
|
|
36262
38714
|
}
|
|
36263
38715
|
};
|
|
36264
38716
|
|
|
36265
38717
|
// src/core/core/runtime/PptxHandlerRuntimeThemeProcessing.ts
|
|
36266
|
-
var
|
|
38718
|
+
var PptxHandlerRuntime61 = class extends PptxHandlerRuntime60 {
|
|
36267
38719
|
// ---------------------------------------------------------------------------
|
|
36268
38720
|
// Theme editing — update colour scheme, font scheme, and name in the zip
|
|
36269
38721
|
// ---------------------------------------------------------------------------
|
|
@@ -36413,7 +38865,7 @@ var PptxHandlerRuntime60 = class extends PptxHandlerRuntime59 {
|
|
|
36413
38865
|
};
|
|
36414
38866
|
|
|
36415
38867
|
// src/core/core/runtime/PptxHandlerRuntimeComments.ts
|
|
36416
|
-
var
|
|
38868
|
+
var PptxHandlerRuntime62 = class _PptxHandlerRuntime extends PptxHandlerRuntime61 {
|
|
36417
38869
|
/**
|
|
36418
38870
|
* Parse modern threaded comments (PowerPoint 2019+ / Office 365).
|
|
36419
38871
|
* Modern comments use `p188:cmLst`/`p15:cmLst` roots within
|
|
@@ -36646,7 +39098,7 @@ var PptxHandlerRuntime61 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
|
|
|
36646
39098
|
};
|
|
36647
39099
|
|
|
36648
39100
|
// src/core/core/runtime/PptxHandlerRuntimeSmartArtXmlUtils.ts
|
|
36649
|
-
var
|
|
39101
|
+
var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
|
|
36650
39102
|
async readXmlPartByRelationshipId(slidePath, relationshipId) {
|
|
36651
39103
|
const normalizedRelationshipId = String(relationshipId || "").trim();
|
|
36652
39104
|
if (normalizedRelationshipId.length === 0) {
|
|
@@ -36801,7 +39253,7 @@ var PptxHandlerRuntime62 = class extends PptxHandlerRuntime61 {
|
|
|
36801
39253
|
};
|
|
36802
39254
|
|
|
36803
39255
|
// src/core/core/runtime/PptxHandlerRuntimeSmartArtParsing.ts
|
|
36804
|
-
var
|
|
39256
|
+
var PptxHandlerRuntime64 = class _PptxHandlerRuntime extends PptxHandlerRuntime63 {
|
|
36805
39257
|
/**
|
|
36806
39258
|
* Parse quick style from `ppt/diagrams/quickStyles*.xml`.
|
|
36807
39259
|
*/
|
|
@@ -36960,7 +39412,7 @@ var PptxHandlerRuntime63 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
|
|
|
36960
39412
|
};
|
|
36961
39413
|
|
|
36962
39414
|
// src/core/core/runtime/PptxHandlerRuntimeSmartArt.ts
|
|
36963
|
-
var
|
|
39415
|
+
var PptxHandlerRuntime65 = class _PptxHandlerRuntime extends PptxHandlerRuntime64 {
|
|
36964
39416
|
async getSmartArtDataForGraphicFrame(slidePath, graphicFrame) {
|
|
36965
39417
|
const graphicData = this.xmlLookupService.getChildByLocalName(
|
|
36966
39418
|
this.xmlLookupService.getChildByLocalName(graphicFrame, "graphic"),
|
|
@@ -37011,10 +39463,14 @@ var PptxHandlerRuntime64 = class extends PptxHandlerRuntime63 {
|
|
|
37011
39463
|
const layoutPart = layoutRelationshipId.length > 0 ? await this.readXmlPartByRelationshipId(slidePath, layoutRelationshipId) : void 0;
|
|
37012
39464
|
const layoutType = layoutPart?.partPath?.split("/").pop()?.replace(/\.[^.]+$/, "") || void 0;
|
|
37013
39465
|
const chrome = this.parseSmartArtChrome(dataModel);
|
|
37014
|
-
const drawingRelationshipId = String(relationshipIds["@_r:cs"] || "").trim();
|
|
37015
|
-
const drawingShapes = await this.parseSmartArtDrawingShapes(slidePath, drawingRelationshipId);
|
|
37016
39466
|
const colorsRelationshipId = String(relationshipIds["@_r:cs"] || "").trim();
|
|
37017
39467
|
const colorTransform = await this.parseSmartArtColorTransform(slidePath, colorsRelationshipId);
|
|
39468
|
+
const drawingResolution = await this.resolveSmartArtDrawingPart(
|
|
39469
|
+
slidePath,
|
|
39470
|
+
diagramDataRelationshipId
|
|
39471
|
+
);
|
|
39472
|
+
const drawingShapes = drawingResolution ? await this.parseSmartArtDrawingShapesFromPath(drawingResolution.path) : [];
|
|
39473
|
+
const drawingRelationshipId = drawingResolution?.relId;
|
|
37018
39474
|
const styleRelationshipId = String(relationshipIds["@_r:qs"] || "").trim();
|
|
37019
39475
|
const quickStyle = await this.parseSmartArtQuickStyle(slidePath, styleRelationshipId);
|
|
37020
39476
|
return {
|
|
@@ -37026,11 +39482,87 @@ var PptxHandlerRuntime64 = class extends PptxHandlerRuntime63 {
|
|
|
37026
39482
|
colorTransform,
|
|
37027
39483
|
quickStyle,
|
|
37028
39484
|
dataRelId: diagramDataRelationshipId,
|
|
37029
|
-
drawingRelId: drawingRelationshipId.length > 0 ? drawingRelationshipId : void 0,
|
|
39485
|
+
drawingRelId: drawingRelationshipId && drawingRelationshipId.length > 0 ? drawingRelationshipId : void 0,
|
|
37030
39486
|
colorsRelId: colorsRelationshipId.length > 0 ? colorsRelationshipId : void 0,
|
|
37031
39487
|
styleRelId: styleRelationshipId.length > 0 ? styleRelationshipId : void 0
|
|
37032
39488
|
};
|
|
37033
39489
|
}
|
|
39490
|
+
/**
|
|
39491
|
+
* Resolve the SmartArt drawing-shapes part path + relationship id.
|
|
39492
|
+
*
|
|
39493
|
+
* Strategy:
|
|
39494
|
+
* 1. Locate the data-model part's rels file
|
|
39495
|
+
* (`ppt/diagrams/_rels/data*.xml.rels`) via `slideRelsMap`.
|
|
39496
|
+
* 2. Find a relationship whose `Type` matches the `…/diagramDrawing`
|
|
39497
|
+
* URI. PowerPoint emits this for any deck that has had its
|
|
39498
|
+
* SmartArt rendered to drawing shapes.
|
|
39499
|
+
* 3. Return the matched part path (so the caller can load it
|
|
39500
|
+
* directly) and the relationship id (for round-trip preservation).
|
|
39501
|
+
*/
|
|
39502
|
+
async resolveSmartArtDrawingPart(slidePath, diagramDataRelationshipId) {
|
|
39503
|
+
if (diagramDataRelationshipId.length === 0) {
|
|
39504
|
+
return void 0;
|
|
39505
|
+
}
|
|
39506
|
+
const slideRels = this.slideRelsMap.get(slidePath);
|
|
39507
|
+
const dataTarget = slideRels?.get(diagramDataRelationshipId);
|
|
39508
|
+
if (!dataTarget) {
|
|
39509
|
+
return void 0;
|
|
39510
|
+
}
|
|
39511
|
+
const dataPath = this.resolveImagePath(slidePath, dataTarget);
|
|
39512
|
+
const dataDir = dataPath.replace(/\/[^/]+$/, "");
|
|
39513
|
+
const dataFile = dataPath.split("/").pop() ?? "";
|
|
39514
|
+
const dataRelsPath = `${dataDir}/_rels/${dataFile}.rels`;
|
|
39515
|
+
const relsXml = await this.zip.file(dataRelsPath)?.async("string");
|
|
39516
|
+
if (!relsXml) {
|
|
39517
|
+
return void 0;
|
|
39518
|
+
}
|
|
39519
|
+
try {
|
|
39520
|
+
const parsed = this.parser.parse(relsXml);
|
|
39521
|
+
const relsRoot = parsed["Relationships"];
|
|
39522
|
+
if (!relsRoot) {
|
|
39523
|
+
return void 0;
|
|
39524
|
+
}
|
|
39525
|
+
const rels = this.ensureArray(relsRoot["Relationship"]);
|
|
39526
|
+
const drawingRel = rels.find(
|
|
39527
|
+
(rel) => String(rel?.["@_Type"] || "").endsWith("/diagramDrawing")
|
|
39528
|
+
);
|
|
39529
|
+
const id = String(drawingRel?.["@_Id"] || "").trim();
|
|
39530
|
+
const target = String(drawingRel?.["@_Target"] || "").trim();
|
|
39531
|
+
if (id.length === 0 || target.length === 0) {
|
|
39532
|
+
return void 0;
|
|
39533
|
+
}
|
|
39534
|
+
const drawingPath = this.resolveImagePath(dataPath, target);
|
|
39535
|
+
return { relId: id, path: drawingPath };
|
|
39536
|
+
} catch {
|
|
39537
|
+
return void 0;
|
|
39538
|
+
}
|
|
39539
|
+
}
|
|
39540
|
+
/**
|
|
39541
|
+
* Parse SmartArt drawing shapes given an absolute part path.
|
|
39542
|
+
*
|
|
39543
|
+
* Wraps `parseSmartArtDrawingShapes` (which expects a slide-relative
|
|
39544
|
+
* relationship id) with a path-based lookup so the resolution layer
|
|
39545
|
+
* can pull the part from anywhere in the package.
|
|
39546
|
+
*/
|
|
39547
|
+
async parseSmartArtDrawingShapesFromPath(drawingPath) {
|
|
39548
|
+
const xmlString = await this.zip.file(drawingPath)?.async("string");
|
|
39549
|
+
if (!xmlString) {
|
|
39550
|
+
return [];
|
|
39551
|
+
}
|
|
39552
|
+
try {
|
|
39553
|
+
const xml = this.parser.parse(xmlString);
|
|
39554
|
+
const drawing = this.xmlLookupService.getChildByLocalName(xml, "drawing");
|
|
39555
|
+
const spTree = this.xmlLookupService.getChildByLocalName(drawing || xml, "spTree");
|
|
39556
|
+
if (!spTree) {
|
|
39557
|
+
return [];
|
|
39558
|
+
}
|
|
39559
|
+
const shapes = this.xmlLookupService.getChildrenArrayByLocalName(spTree, "sp");
|
|
39560
|
+
const emuPerPx = _PptxHandlerRuntime.EMU_PER_PX;
|
|
39561
|
+
return shapes.map((sp, index) => this.parseDrawingShape(sp, index, emuPerPx)).filter((entry) => entry !== null);
|
|
39562
|
+
} catch {
|
|
39563
|
+
return [];
|
|
39564
|
+
}
|
|
39565
|
+
}
|
|
37034
39566
|
parseSmartArtConnections(dataModel) {
|
|
37035
39567
|
const connectionList = this.xmlLookupService.getChildByLocalName(dataModel, "cxnLst");
|
|
37036
39568
|
const rawConnections = this.xmlLookupService.getChildrenArrayByLocalName(connectionList, "cxn");
|
|
@@ -37061,7 +39593,7 @@ var PptxHandlerRuntime64 = class extends PptxHandlerRuntime63 {
|
|
|
37061
39593
|
};
|
|
37062
39594
|
|
|
37063
39595
|
// src/core/core/runtime/PptxHandlerRuntimeChartDetection.ts
|
|
37064
|
-
var
|
|
39596
|
+
var PptxHandlerRuntime66 = class extends PptxHandlerRuntime65 {
|
|
37065
39597
|
detectChartType(plotArea) {
|
|
37066
39598
|
if (!plotArea) {
|
|
37067
39599
|
return "unknown";
|
|
@@ -37170,7 +39702,7 @@ var PptxHandlerRuntime65 = class extends PptxHandlerRuntime64 {
|
|
|
37170
39702
|
};
|
|
37171
39703
|
|
|
37172
39704
|
// src/core/core/runtime/PptxHandlerRuntimeChartParsingHelpers.ts
|
|
37173
|
-
var
|
|
39705
|
+
var PptxHandlerRuntime67 = class extends PptxHandlerRuntime66 {
|
|
37174
39706
|
/**
|
|
37175
39707
|
* Parse `c:plotVisOnly` from the chart root element.
|
|
37176
39708
|
*
|
|
@@ -37231,7 +39763,7 @@ var PptxHandlerRuntime66 = class extends PptxHandlerRuntime65 {
|
|
|
37231
39763
|
};
|
|
37232
39764
|
|
|
37233
39765
|
// src/core/core/runtime/PptxHandlerRuntimeChartExternalData.ts
|
|
37234
|
-
var
|
|
39766
|
+
var PptxHandlerRuntime68 = class extends PptxHandlerRuntime67 {
|
|
37235
39767
|
/**
|
|
37236
39768
|
* Parse `c:externalData` from the chart's `c:chartSpace` and resolve
|
|
37237
39769
|
* the external relationship target from the chart part's .rels file.
|
|
@@ -37347,7 +39879,7 @@ var PptxHandlerRuntime67 = class extends PptxHandlerRuntime66 {
|
|
|
37347
39879
|
};
|
|
37348
39880
|
|
|
37349
39881
|
// src/core/core/runtime/PptxHandlerRuntimeChartColorStyle.ts
|
|
37350
|
-
var
|
|
39882
|
+
var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
|
|
37351
39883
|
/**
|
|
37352
39884
|
* Parse the Office 2013+ chart color style part (`chartColorStyle*.xml`)
|
|
37353
39885
|
* referenced from the chart's relationships.
|
|
@@ -37454,7 +39986,7 @@ var PptxHandlerRuntime68 = class extends PptxHandlerRuntime67 {
|
|
|
37454
39986
|
};
|
|
37455
39987
|
|
|
37456
39988
|
// src/core/core/runtime/PptxHandlerRuntimeChartParsing.ts
|
|
37457
|
-
var
|
|
39989
|
+
var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
|
|
37458
39990
|
/**
|
|
37459
39991
|
* Parse chart data from a graphic frame element on a slide.
|
|
37460
39992
|
*
|
|
@@ -37701,7 +40233,7 @@ var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
|
|
|
37701
40233
|
};
|
|
37702
40234
|
|
|
37703
40235
|
// src/core/core/runtime/PptxHandlerRuntimePresentationStructure.ts
|
|
37704
|
-
var
|
|
40236
|
+
var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
|
|
37705
40237
|
parseEditorAnimations(slideXml2) {
|
|
37706
40238
|
return this.editorAnimationService.parseEditorAnimations(slideXml2);
|
|
37707
40239
|
}
|
|
@@ -37946,7 +40478,7 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
|
|
|
37946
40478
|
};
|
|
37947
40479
|
|
|
37948
40480
|
// src/core/core/runtime/PptxHandlerRuntimeEmbeddedFonts.ts
|
|
37949
|
-
var
|
|
40481
|
+
var PptxHandlerRuntime72 = class extends PptxHandlerRuntime71 {
|
|
37950
40482
|
async getEmbeddedFonts() {
|
|
37951
40483
|
const embeddedFontEntries = this.ensureArray(
|
|
37952
40484
|
this.presentationData?.["p:presentation"]?.["p:embeddedFontLst"]?.["p:embeddedFont"]
|
|
@@ -38118,7 +40650,7 @@ var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
|
|
|
38118
40650
|
};
|
|
38119
40651
|
|
|
38120
40652
|
// src/core/core/runtime/PptxHandlerRuntimeLoadSession.ts
|
|
38121
|
-
var
|
|
40653
|
+
var PptxHandlerRuntime73 = class _PptxHandlerRuntime extends PptxHandlerRuntime72 {
|
|
38122
40654
|
isZipContainer(data) {
|
|
38123
40655
|
const bytes = new Uint8Array(data);
|
|
38124
40656
|
if (bytes.byteLength < 4) {
|
|
@@ -38161,6 +40693,23 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38161
40693
|
this.imageDataCache.clear();
|
|
38162
40694
|
this.themeColorMap = {};
|
|
38163
40695
|
this.themeFontMap = {};
|
|
40696
|
+
this.masterClrMaps.clear();
|
|
40697
|
+
this.masterThemeColorMaps.clear();
|
|
40698
|
+
this.masterThemeFontMaps.clear();
|
|
40699
|
+
this.masterThemeFormatSchemes.clear();
|
|
40700
|
+
this.masterThemePaths.clear();
|
|
40701
|
+
this.masterThemeMajorFontScripts.clear();
|
|
40702
|
+
this.masterThemeMinorFontScripts.clear();
|
|
40703
|
+
this.masterThemeNames.clear();
|
|
40704
|
+
this.masterThemeFontSchemeNames.clear();
|
|
40705
|
+
this.masterThemeColorSchemeNames.clear();
|
|
40706
|
+
this.originalThemeXmlByPath.clear();
|
|
40707
|
+
this.dirtyThemePaths.clear();
|
|
40708
|
+
this.masterThemeObjectDefaults.clear();
|
|
40709
|
+
this.masterThemeExtraClrSchemeLst.clear();
|
|
40710
|
+
this.masterThemeCustClrLst.clear();
|
|
40711
|
+
this.masterThemeExtLst.clear();
|
|
40712
|
+
this.currentMasterClrMap = null;
|
|
38164
40713
|
this.presentationDefaultTextStyle = void 0;
|
|
38165
40714
|
this.commentAuthorMap.clear();
|
|
38166
40715
|
this.commentAuthorDetails.clear();
|
|
@@ -38315,6 +40864,7 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38315
40864
|
setCurrentSlideClrMapOverride: (override) => {
|
|
38316
40865
|
this.currentSlideClrMapOverride = override;
|
|
38317
40866
|
},
|
|
40867
|
+
setActiveMasterForSlide: (slidePath) => this.setActiveMasterForSlide(slidePath),
|
|
38318
40868
|
findLayoutPathForSlide: (slidePath) => this.findLayoutPathForSlide(slidePath),
|
|
38319
40869
|
loadThemeOverride: (partBasePath) => this.loadThemeOverride(partBasePath),
|
|
38320
40870
|
applyThemeOverrideState: (override) => this.applyThemeOverrideState(override),
|
|
@@ -38345,7 +40895,7 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38345
40895
|
};
|
|
38346
40896
|
|
|
38347
40897
|
// src/core/core/runtime/PptxHandlerRuntimeLoadPipeline.ts
|
|
38348
|
-
var
|
|
40898
|
+
var PptxHandlerRuntime74 = class extends PptxHandlerRuntime73 {
|
|
38349
40899
|
async buildLoadData(presentationState, slidesWithWarnings) {
|
|
38350
40900
|
const headerFooter = this.extractHeaderFooter();
|
|
38351
40901
|
const presentationProperties = await this.parsePresentationProperties();
|
|
@@ -38357,6 +40907,7 @@ var PptxHandlerRuntime73 = class extends PptxHandlerRuntime72 {
|
|
|
38357
40907
|
const notesMaster = await this.parseNotesMaster();
|
|
38358
40908
|
const handoutMaster = await this.parseHandoutMaster();
|
|
38359
40909
|
const slideMasters = await this.parseSlideMasters();
|
|
40910
|
+
await this.enrichSlideMastersWithTxStyles(slideMasters);
|
|
38360
40911
|
const tags = await this.parseTags();
|
|
38361
40912
|
const customProperties = await this.parseCustomProperties();
|
|
38362
40913
|
const coreProperties = await this.parseCoreProperties();
|
|
@@ -38691,7 +41242,7 @@ var PptxHandlerRuntime73 = class extends PptxHandlerRuntime72 {
|
|
|
38691
41242
|
};
|
|
38692
41243
|
|
|
38693
41244
|
// src/core/core/runtime/PptxHandlerRuntimeImplementation.ts
|
|
38694
|
-
var
|
|
41245
|
+
var PptxHandlerRuntime75 = class _PptxHandlerRuntime extends PptxHandlerRuntime74 {
|
|
38695
41246
|
constructor(dependencyFactory = new PptxRuntimeDependencyFactory()) {
|
|
38696
41247
|
super();
|
|
38697
41248
|
this.dependencyFactory = dependencyFactory;
|
|
@@ -38739,6 +41290,9 @@ var PptxHandlerRuntime74 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38739
41290
|
extractGradientPathType: (gradFill) => this.colorStyleCodec.extractGradientPathType(gradFill),
|
|
38740
41291
|
extractGradientFocalPoint: (gradFill) => this.colorStyleCodec.extractGradientFocalPoint(gradFill),
|
|
38741
41292
|
extractGradientFillToRect: (gradFill) => this.colorStyleCodec.extractGradientFillToRect(gradFill),
|
|
41293
|
+
extractGradientFlip: (gradFill) => this.colorStyleCodec.extractGradientFlip(gradFill),
|
|
41294
|
+
extractGradientRotWithShape: (gradFill) => this.colorStyleCodec.extractGradientRotWithShape(gradFill),
|
|
41295
|
+
extractGradientScaled: (gradFill) => this.colorStyleCodec.extractGradientScaled(gradFill),
|
|
38742
41296
|
normalizeStrokeDashType: (value) => this.normalizeStrokeDashType(value),
|
|
38743
41297
|
normalizeConnectorArrowType: (value) => this.normalizeConnectorArrowType(value),
|
|
38744
41298
|
ensureArray: (value) => this.ensureArray(value),
|
|
@@ -38812,11 +41366,11 @@ var PptxHandlerRuntime74 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38812
41366
|
};
|
|
38813
41367
|
|
|
38814
41368
|
// src/core/core/PptxHandlerRuntime.ts
|
|
38815
|
-
var
|
|
41369
|
+
var PptxHandlerRuntime76 = class extends PptxHandlerRuntime75 {
|
|
38816
41370
|
};
|
|
38817
41371
|
|
|
38818
41372
|
// src/core/core/PptxHandlerRuntimeFactory.ts
|
|
38819
|
-
var createDefaultPptxHandlerRuntime = () => new
|
|
41373
|
+
var createDefaultPptxHandlerRuntime = () => new PptxHandlerRuntime76();
|
|
38820
41374
|
|
|
38821
41375
|
// src/core/PptxHandlerCore.ts
|
|
38822
41376
|
var PptxHandlerCore = class {
|