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
|
@@ -4426,12 +4426,25 @@ function svgToCustomGeometryPaths(pathData, width, height) {
|
|
|
4426
4426
|
function pointToXml(pt) {
|
|
4427
4427
|
return { "@_x": String(Math.round(pt.x)), "@_y": String(Math.round(pt.y)) };
|
|
4428
4428
|
}
|
|
4429
|
-
function customGeometryPathsToXml(paths) {
|
|
4429
|
+
function customGeometryPathsToXml(paths, rawData) {
|
|
4430
4430
|
const xmlPaths = paths.map((path2) => {
|
|
4431
4431
|
const pathXml = {
|
|
4432
4432
|
"@_w": String(Math.round(path2.width)),
|
|
4433
4433
|
"@_h": String(Math.round(path2.height))
|
|
4434
4434
|
};
|
|
4435
|
+
if (path2.fillMode) {
|
|
4436
|
+
pathXml["@_fill"] = path2.fillMode;
|
|
4437
|
+
}
|
|
4438
|
+
if (path2.stroke === false) {
|
|
4439
|
+
pathXml["@_stroke"] = "0";
|
|
4440
|
+
} else if (path2.stroke === true) {
|
|
4441
|
+
pathXml["@_stroke"] = "1";
|
|
4442
|
+
}
|
|
4443
|
+
if (path2.extrusionOk === true) {
|
|
4444
|
+
pathXml["@_extrusionOk"] = "1";
|
|
4445
|
+
} else if (path2.extrusionOk === false) {
|
|
4446
|
+
pathXml["@_extrusionOk"] = "0";
|
|
4447
|
+
}
|
|
4435
4448
|
const moveToList = [];
|
|
4436
4449
|
const lnToList = [];
|
|
4437
4450
|
const cubicBezToList = [];
|
|
@@ -4489,12 +4502,12 @@ function customGeometryPathsToXml(paths) {
|
|
|
4489
4502
|
}
|
|
4490
4503
|
return pathXml;
|
|
4491
4504
|
});
|
|
4492
|
-
|
|
4505
|
+
const result = {
|
|
4493
4506
|
"a:avLst": {},
|
|
4494
|
-
"a:gdLst": {},
|
|
4495
|
-
"a:ahLst": {},
|
|
4496
|
-
"a:cxnLst": {},
|
|
4497
|
-
"a:rect": {
|
|
4507
|
+
"a:gdLst": rawData?.gdLstXml ?? {},
|
|
4508
|
+
"a:ahLst": rawData?.ahLstXml ?? {},
|
|
4509
|
+
"a:cxnLst": rawData?.cxnLstXml ?? {},
|
|
4510
|
+
"a:rect": rawData?.rectXml ?? {
|
|
4498
4511
|
"@_l": "l",
|
|
4499
4512
|
"@_t": "t",
|
|
4500
4513
|
"@_r": "r",
|
|
@@ -4504,6 +4517,7 @@ function customGeometryPathsToXml(paths) {
|
|
|
4504
4517
|
"a:path": xmlPaths.length === 1 ? xmlPaths[0] : xmlPaths
|
|
4505
4518
|
}
|
|
4506
4519
|
};
|
|
4520
|
+
return result;
|
|
4507
4521
|
}
|
|
4508
4522
|
|
|
4509
4523
|
// src/core/builders/sdk/ElementFactory.ts
|
|
@@ -5188,7 +5202,11 @@ function isoNow() {
|
|
|
5188
5202
|
return (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d+Z$/, "Z");
|
|
5189
5203
|
}
|
|
5190
5204
|
var STANDARD_LAYOUTS = [
|
|
5191
|
-
|
|
5205
|
+
// `type` is ST_SlideLayoutType per ECMA-376 §19.7.15. The Title Slide
|
|
5206
|
+
// layout uses `title`; `ctrTitle` is a placeholder type (ST_PlaceholderType)
|
|
5207
|
+
// and is not valid here — PowerPoint's OPC loader rejects the package
|
|
5208
|
+
// with ERROR_FILE_CORRUPT (0x80070570) when it sees it.
|
|
5209
|
+
{ name: "Title Slide", type: "title" },
|
|
5192
5210
|
{ name: "Title and Content", type: "obj" },
|
|
5193
5211
|
{ name: "Section Header", type: "secHead" },
|
|
5194
5212
|
{ name: "Two Content", type: "twoObj" },
|
|
@@ -5222,7 +5240,7 @@ ${slideOverrides}
|
|
|
5222
5240
|
<Override PartName="/ppt/viewProps.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml"/>
|
|
5223
5241
|
<Override PartName="/ppt/tableStyles.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml"/>
|
|
5224
5242
|
<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
|
|
5225
|
-
<Override PartName="/docProps/app.xml" ContentType="application/vnd.
|
|
5243
|
+
<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>
|
|
5226
5244
|
</Types>`;
|
|
5227
5245
|
}
|
|
5228
5246
|
function rootRelsXml() {
|
|
@@ -5246,6 +5264,9 @@ ${Array.from(
|
|
|
5246
5264
|
<p:presentation xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
|
|
5247
5265
|
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
|
5248
5266
|
xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"
|
|
5267
|
+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
5268
|
+
xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main"
|
|
5269
|
+
xmlns:p15="http://schemas.microsoft.com/office/powerpoint/2012/main"
|
|
5249
5270
|
saveSubsetFonts="1">
|
|
5250
5271
|
<p:sldMasterIdLst>
|
|
5251
5272
|
<p:sldMasterId id="2147483648" r:id="rId1"/>
|
|
@@ -6548,10 +6569,41 @@ var PptxPresentationSlidesReconciler = class {
|
|
|
6548
6569
|
"@_r:id": slide.rId
|
|
6549
6570
|
};
|
|
6550
6571
|
});
|
|
6551
|
-
|
|
6552
|
-
|
|
6572
|
+
input.presentationData["p:presentation"] = this.insertSlideIdListInOrder(
|
|
6573
|
+
presentation,
|
|
6574
|
+
slideIdList
|
|
6575
|
+
);
|
|
6553
6576
|
}
|
|
6554
6577
|
}
|
|
6578
|
+
/**
|
|
6579
|
+
* Return a new presentation XML object whose `p:sldIdLst` child sits in the
|
|
6580
|
+
* schema-mandated position (after `sldMasterIdLst` / `notesMasterIdLst` /
|
|
6581
|
+
* `handoutMasterIdLst`, before `sldSz`). Non-sldIdLst keys keep their
|
|
6582
|
+
* relative order; attribute keys (`@_...`) stay at the front.
|
|
6583
|
+
*/
|
|
6584
|
+
insertSlideIdListInOrder(presentation, slideIdList) {
|
|
6585
|
+
const before = /* @__PURE__ */ new Set([
|
|
6586
|
+
"p:sldMasterIdLst",
|
|
6587
|
+
"p:notesMasterIdLst",
|
|
6588
|
+
"p:handoutMasterIdLst"
|
|
6589
|
+
]);
|
|
6590
|
+
const rebuilt = {};
|
|
6591
|
+
let inserted = false;
|
|
6592
|
+
for (const key of Object.keys(presentation)) {
|
|
6593
|
+
if (key === "p:sldIdLst") {
|
|
6594
|
+
continue;
|
|
6595
|
+
}
|
|
6596
|
+
if (!inserted && !key.startsWith("@_") && !before.has(key)) {
|
|
6597
|
+
rebuilt["p:sldIdLst"] = slideIdList;
|
|
6598
|
+
inserted = true;
|
|
6599
|
+
}
|
|
6600
|
+
rebuilt[key] = presentation[key];
|
|
6601
|
+
}
|
|
6602
|
+
if (!inserted) {
|
|
6603
|
+
rebuilt["p:sldIdLst"] = slideIdList;
|
|
6604
|
+
}
|
|
6605
|
+
return rebuilt;
|
|
6606
|
+
}
|
|
6555
6607
|
async attachNewSlide(init) {
|
|
6556
6608
|
const sourceSlidePath = init.input.findSourceSlidePath(init.slide.sourceSlideId);
|
|
6557
6609
|
const sourceSlideXml = sourceSlidePath ? init.input.deepCloneXml(init.input.slideMap.get(sourceSlidePath)) : void 0;
|
|
@@ -6636,6 +6688,22 @@ var PptxPresentationSlidesReconciler = class {
|
|
|
6636
6688
|
};
|
|
6637
6689
|
|
|
6638
6690
|
// src/core/core/builders/PptxSlideRelationshipRegistry.ts
|
|
6691
|
+
function isExternalTarget(target) {
|
|
6692
|
+
const normalized = target.trim();
|
|
6693
|
+
if (normalized.length === 0) {
|
|
6694
|
+
return false;
|
|
6695
|
+
}
|
|
6696
|
+
const colonIdx = normalized.indexOf(":");
|
|
6697
|
+
if (colonIdx <= 0) {
|
|
6698
|
+
return false;
|
|
6699
|
+
}
|
|
6700
|
+
const slashIdx = normalized.indexOf("/");
|
|
6701
|
+
if (slashIdx !== -1 && slashIdx < colonIdx) {
|
|
6702
|
+
return false;
|
|
6703
|
+
}
|
|
6704
|
+
const scheme = normalized.slice(0, colonIdx);
|
|
6705
|
+
return /^[A-Za-z][A-Za-z0-9+\-.]*$/.test(scheme);
|
|
6706
|
+
}
|
|
6639
6707
|
var PptxSlideRelationshipRegistry = class {
|
|
6640
6708
|
relationships;
|
|
6641
6709
|
usedRelationshipIds = /* @__PURE__ */ new Set();
|
|
@@ -6706,7 +6774,7 @@ var PptxSlideRelationshipRegistry = class {
|
|
|
6706
6774
|
return existingRelationshipId;
|
|
6707
6775
|
}
|
|
6708
6776
|
const relationshipId = this.nextRelationshipId();
|
|
6709
|
-
const targetMode =
|
|
6777
|
+
const targetMode = isExternalTarget(normalizedTarget) ? "External" : void 0;
|
|
6710
6778
|
this.upsertRelationship(
|
|
6711
6779
|
relationshipId,
|
|
6712
6780
|
this.hyperlinkRelationshipType,
|
|
@@ -6956,6 +7024,82 @@ var PptxSlideNotesPartUpdater = class {
|
|
|
6956
7024
|
}
|
|
6957
7025
|
};
|
|
6958
7026
|
|
|
7027
|
+
// src/core/utils/xml-reorder.ts
|
|
7028
|
+
function reorderObjectKeys(obj, schemaOrder) {
|
|
7029
|
+
const result = {};
|
|
7030
|
+
const consumed = /* @__PURE__ */ new Set();
|
|
7031
|
+
for (const key of schemaOrder) {
|
|
7032
|
+
if (Object.hasOwn(obj, key)) {
|
|
7033
|
+
const value = obj[key];
|
|
7034
|
+
if (value !== void 0) {
|
|
7035
|
+
result[key] = value;
|
|
7036
|
+
}
|
|
7037
|
+
consumed.add(key);
|
|
7038
|
+
}
|
|
7039
|
+
}
|
|
7040
|
+
for (const key of Object.keys(obj)) {
|
|
7041
|
+
if (consumed.has(key)) {
|
|
7042
|
+
continue;
|
|
7043
|
+
}
|
|
7044
|
+
const value = obj[key];
|
|
7045
|
+
if (value !== void 0) {
|
|
7046
|
+
result[key] = value;
|
|
7047
|
+
}
|
|
7048
|
+
}
|
|
7049
|
+
return result;
|
|
7050
|
+
}
|
|
7051
|
+
var EFFECT_LST_ORDER = [
|
|
7052
|
+
"a:blur",
|
|
7053
|
+
"a:fillOverlay",
|
|
7054
|
+
"a:glow",
|
|
7055
|
+
"a:innerShdw",
|
|
7056
|
+
"a:outerShdw",
|
|
7057
|
+
"a:prstShdw",
|
|
7058
|
+
"a:reflection",
|
|
7059
|
+
"a:softEdge"
|
|
7060
|
+
];
|
|
7061
|
+
var SP_PR_ORDER = [
|
|
7062
|
+
"a:xfrm",
|
|
7063
|
+
"a:custGeom",
|
|
7064
|
+
"a:prstGeom",
|
|
7065
|
+
"a:noFill",
|
|
7066
|
+
"a:solidFill",
|
|
7067
|
+
"a:gradFill",
|
|
7068
|
+
"a:blipFill",
|
|
7069
|
+
"a:pattFill",
|
|
7070
|
+
"a:grpFill",
|
|
7071
|
+
"a:ln",
|
|
7072
|
+
"a:effectLst",
|
|
7073
|
+
"a:effectDag",
|
|
7074
|
+
"a:scene3d",
|
|
7075
|
+
"a:sp3d",
|
|
7076
|
+
"a:extLst"
|
|
7077
|
+
];
|
|
7078
|
+
var TC_PR_BORDERS_ORDER = [
|
|
7079
|
+
"a:lnL",
|
|
7080
|
+
"a:lnR",
|
|
7081
|
+
"a:lnT",
|
|
7082
|
+
"a:lnB",
|
|
7083
|
+
"a:lnTlToBr",
|
|
7084
|
+
"a:lnBlToTr",
|
|
7085
|
+
"a:cell3D",
|
|
7086
|
+
"a:noFill",
|
|
7087
|
+
"a:solidFill",
|
|
7088
|
+
"a:gradFill",
|
|
7089
|
+
"a:blipFill",
|
|
7090
|
+
"a:pattFill",
|
|
7091
|
+
"a:grpFill",
|
|
7092
|
+
"a:headers",
|
|
7093
|
+
"a:extLst"
|
|
7094
|
+
];
|
|
7095
|
+
var BLIP_FILL_ORDER = ["a:blip", "a:srcRect", "a:tile", "a:stretch"];
|
|
7096
|
+
var SHAPE_STYLE_ORDER = [
|
|
7097
|
+
"a:lnRef",
|
|
7098
|
+
"a:fillRef",
|
|
7099
|
+
"a:effectRef",
|
|
7100
|
+
"a:fontRef"
|
|
7101
|
+
];
|
|
7102
|
+
|
|
6959
7103
|
// src/core/core/builders/PptxSlideBackgroundBuilder.ts
|
|
6960
7104
|
var PptxSlideBackgroundBuilder = class {
|
|
6961
7105
|
applyBackground(init) {
|
|
@@ -6991,10 +7135,13 @@ var PptxSlideBackgroundBuilder = class {
|
|
|
6991
7135
|
init.slideImageRelationshipType,
|
|
6992
7136
|
relativeBackgroundImagePath
|
|
6993
7137
|
);
|
|
6994
|
-
backgroundProperties["a:blipFill"] =
|
|
6995
|
-
|
|
6996
|
-
|
|
6997
|
-
|
|
7138
|
+
backgroundProperties["a:blipFill"] = reorderObjectKeys(
|
|
7139
|
+
{
|
|
7140
|
+
"a:blip": { "@_r:embed": backgroundRelationshipId },
|
|
7141
|
+
"a:stretch": { "a:fillRect": {} }
|
|
7142
|
+
},
|
|
7143
|
+
BLIP_FILL_ORDER
|
|
7144
|
+
);
|
|
6998
7145
|
}
|
|
6999
7146
|
} else if (hasBackgroundColor && init.slide.backgroundColor) {
|
|
7000
7147
|
backgroundProperties["a:solidFill"] = {
|
|
@@ -7738,6 +7885,45 @@ var PptxGradientStyleCodec = class {
|
|
|
7738
7885
|
b: Number.isFinite(b) ? this.context.clampUnitInterval(b / 1e5) : 0
|
|
7739
7886
|
};
|
|
7740
7887
|
}
|
|
7888
|
+
extractGradientFlip(gradFill) {
|
|
7889
|
+
const flipRaw = String(gradFill["@_flip"] || "").trim().toLowerCase();
|
|
7890
|
+
if (flipRaw === "x" || flipRaw === "y" || flipRaw === "xy" || flipRaw === "none") {
|
|
7891
|
+
return flipRaw;
|
|
7892
|
+
}
|
|
7893
|
+
return void 0;
|
|
7894
|
+
}
|
|
7895
|
+
extractGradientRotWithShape(gradFill) {
|
|
7896
|
+
const rot = gradFill["@_rotWithShape"];
|
|
7897
|
+
if (rot === void 0 || rot === null) {
|
|
7898
|
+
return void 0;
|
|
7899
|
+
}
|
|
7900
|
+
const token = String(rot).trim().toLowerCase();
|
|
7901
|
+
if (token === "1" || token === "true") {
|
|
7902
|
+
return true;
|
|
7903
|
+
}
|
|
7904
|
+
if (token === "0" || token === "false") {
|
|
7905
|
+
return false;
|
|
7906
|
+
}
|
|
7907
|
+
return void 0;
|
|
7908
|
+
}
|
|
7909
|
+
extractGradientScaled(gradFill) {
|
|
7910
|
+
const lin = gradFill["a:lin"];
|
|
7911
|
+
if (!lin) {
|
|
7912
|
+
return void 0;
|
|
7913
|
+
}
|
|
7914
|
+
const scaled = lin["@_scaled"];
|
|
7915
|
+
if (scaled === void 0 || scaled === null) {
|
|
7916
|
+
return void 0;
|
|
7917
|
+
}
|
|
7918
|
+
const token = String(scaled).trim().toLowerCase();
|
|
7919
|
+
if (token === "1" || token === "true") {
|
|
7920
|
+
return true;
|
|
7921
|
+
}
|
|
7922
|
+
if (token === "0" || token === "false") {
|
|
7923
|
+
return false;
|
|
7924
|
+
}
|
|
7925
|
+
return void 0;
|
|
7926
|
+
}
|
|
7741
7927
|
extractGradientAngle(gradFill) {
|
|
7742
7928
|
const angleRaw = Number.parseInt(
|
|
7743
7929
|
String(gradFill["a:lin"]?.["@_ang"] || ""),
|
|
@@ -7824,11 +8010,14 @@ var PptxGradientStyleCodec = class {
|
|
|
7824
8010
|
return void 0;
|
|
7825
8011
|
}
|
|
7826
8012
|
const gradientType = shapeStyle.fillGradientType || "linear";
|
|
7827
|
-
const gradientXml = {
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
|
|
7831
|
-
|
|
8013
|
+
const gradientXml = {};
|
|
8014
|
+
if (shapeStyle.fillGradientFlip && shapeStyle.fillGradientFlip !== "none") {
|
|
8015
|
+
gradientXml["@_flip"] = shapeStyle.fillGradientFlip;
|
|
8016
|
+
}
|
|
8017
|
+
if (shapeStyle.fillGradientRotWithShape !== void 0) {
|
|
8018
|
+
gradientXml["@_rotWithShape"] = shapeStyle.fillGradientRotWithShape ? "1" : "0";
|
|
8019
|
+
}
|
|
8020
|
+
gradientXml["a:gsLst"] = { "a:gs": stops };
|
|
7832
8021
|
if (gradientType === "radial") {
|
|
7833
8022
|
const pathType = shapeStyle.fillGradientPathType || "circle";
|
|
7834
8023
|
const pathXml = {
|
|
@@ -7858,10 +8047,15 @@ var PptxGradientStyleCodec = class {
|
|
|
7858
8047
|
gradientXml["a:path"] = pathXml;
|
|
7859
8048
|
} else {
|
|
7860
8049
|
const normalizedAngle = typeof shapeStyle.fillGradientAngle === "number" && Number.isFinite(shapeStyle.fillGradientAngle) ? shapeStyle.fillGradientAngle : 90;
|
|
7861
|
-
|
|
7862
|
-
"@_ang": String(Math.round(normalizedAngle * 6e4))
|
|
7863
|
-
"@_scaled": "1"
|
|
8050
|
+
const linNode = {
|
|
8051
|
+
"@_ang": String(Math.round(normalizedAngle * 6e4))
|
|
7864
8052
|
};
|
|
8053
|
+
if (shapeStyle.fillGradientScaled !== void 0) {
|
|
8054
|
+
linNode["@_scaled"] = shapeStyle.fillGradientScaled ? "1" : "0";
|
|
8055
|
+
} else {
|
|
8056
|
+
linNode["@_scaled"] = "1";
|
|
8057
|
+
}
|
|
8058
|
+
gradientXml["a:lin"] = linNode;
|
|
7865
8059
|
}
|
|
7866
8060
|
return gradientXml;
|
|
7867
8061
|
}
|
|
@@ -8258,6 +8452,30 @@ var PRESET_SHADOW_OPACITY_MAP = {
|
|
|
8258
8452
|
};
|
|
8259
8453
|
|
|
8260
8454
|
// src/core/core/builders/PptxShapeEffectStyleExtractor.ts
|
|
8455
|
+
var VALID_ALIGNMENTS = /* @__PURE__ */ new Set(["tl", "t", "tr", "l", "ctr", "r", "bl", "b", "br"]);
|
|
8456
|
+
function parseIntAttr(value) {
|
|
8457
|
+
if (value === void 0 || value === null || value === "") {
|
|
8458
|
+
return void 0;
|
|
8459
|
+
}
|
|
8460
|
+
const parsed = Number.parseInt(String(value), 10);
|
|
8461
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
8462
|
+
}
|
|
8463
|
+
function parseAlignmentAttr(value) {
|
|
8464
|
+
const v = String(value ?? "").trim();
|
|
8465
|
+
return VALID_ALIGNMENTS.has(v) ? v : void 0;
|
|
8466
|
+
}
|
|
8467
|
+
function parseBoolAttr(value) {
|
|
8468
|
+
if (typeof value === "boolean") {
|
|
8469
|
+
return value;
|
|
8470
|
+
}
|
|
8471
|
+
if (value === "1" || value === "true") {
|
|
8472
|
+
return true;
|
|
8473
|
+
}
|
|
8474
|
+
if (value === "0" || value === "false") {
|
|
8475
|
+
return false;
|
|
8476
|
+
}
|
|
8477
|
+
return void 0;
|
|
8478
|
+
}
|
|
8261
8479
|
var PptxShapeEffectStyleExtractor = class {
|
|
8262
8480
|
context;
|
|
8263
8481
|
constructor(context) {
|
|
@@ -8281,7 +8499,12 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8281
8499
|
const shadowOffsetX = distance !== void 0 ? Math.round(Math.cos(directionRadians) * distance * 100) / 100 : void 0;
|
|
8282
8500
|
const shadowOffsetY = distance !== void 0 ? Math.round(Math.sin(directionRadians) * distance * 100) / 100 : void 0;
|
|
8283
8501
|
const rotateWithShape = outerShadow["@_rotWithShape"];
|
|
8284
|
-
const shadowRotateWithShape = typeof rotateWithShape === "boolean" ? rotateWithShape : rotateWithShape === "1" || rotateWithShape === "true" ? true : void 0;
|
|
8502
|
+
const shadowRotateWithShape = typeof rotateWithShape === "boolean" ? rotateWithShape : rotateWithShape === "1" || rotateWithShape === "true" ? true : rotateWithShape === "0" || rotateWithShape === "false" ? false : void 0;
|
|
8503
|
+
const shadowScaleX = parseIntAttr(outerShadow["@_sx"]);
|
|
8504
|
+
const shadowScaleY = parseIntAttr(outerShadow["@_sy"]);
|
|
8505
|
+
const shadowSkewX = parseIntAttr(outerShadow["@_kx"]);
|
|
8506
|
+
const shadowSkewY = parseIntAttr(outerShadow["@_ky"]);
|
|
8507
|
+
const shadowAlignment = parseAlignmentAttr(outerShadow["@_algn"]);
|
|
8285
8508
|
return {
|
|
8286
8509
|
shadowColor,
|
|
8287
8510
|
shadowOpacity,
|
|
@@ -8290,7 +8513,12 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8290
8513
|
shadowOffsetY,
|
|
8291
8514
|
shadowAngle: directionDegrees,
|
|
8292
8515
|
shadowDistance: distance,
|
|
8293
|
-
shadowRotateWithShape
|
|
8516
|
+
shadowRotateWithShape,
|
|
8517
|
+
shadowScaleX,
|
|
8518
|
+
shadowScaleY,
|
|
8519
|
+
shadowSkewX,
|
|
8520
|
+
shadowSkewY,
|
|
8521
|
+
shadowAlignment
|
|
8294
8522
|
};
|
|
8295
8523
|
}
|
|
8296
8524
|
extractPresetShadowStyle(effectLstParent) {
|
|
@@ -8336,12 +8564,14 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8336
8564
|
const directionRadians = directionDegrees * Math.PI / 180;
|
|
8337
8565
|
const innerShadowOffsetX = distance !== void 0 ? Math.round(Math.cos(directionRadians) * distance * 100) / 100 : void 0;
|
|
8338
8566
|
const innerShadowOffsetY = distance !== void 0 ? Math.round(Math.sin(directionRadians) * distance * 100) / 100 : void 0;
|
|
8567
|
+
const innerShadowRotateWithShape = parseBoolAttr(innerShadow["@_rotWithShape"]);
|
|
8339
8568
|
return {
|
|
8340
8569
|
innerShadowColor,
|
|
8341
8570
|
innerShadowOpacity,
|
|
8342
8571
|
innerShadowBlur,
|
|
8343
8572
|
innerShadowOffsetX,
|
|
8344
|
-
innerShadowOffsetY
|
|
8573
|
+
innerShadowOffsetY,
|
|
8574
|
+
innerShadowRotateWithShape
|
|
8345
8575
|
};
|
|
8346
8576
|
}
|
|
8347
8577
|
extractGlowStyle(shapeProps) {
|
|
@@ -8390,6 +8620,16 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8390
8620
|
const reflectionRotation = Number.isFinite(rotationRaw) ? rotationRaw / 6e4 : void 0;
|
|
8391
8621
|
const distanceRaw = Number.parseInt(String(reflectionNode["@_dist"] || ""), 10);
|
|
8392
8622
|
const reflectionDistance = Number.isFinite(distanceRaw) && distanceRaw >= 0 ? distanceRaw / this.context.emuPerPx : void 0;
|
|
8623
|
+
const fadeDirRaw = parseIntAttr(reflectionNode["@_fadeDir"]);
|
|
8624
|
+
const reflectionFadeDirection = fadeDirRaw !== void 0 ? fadeDirRaw / 6e4 : void 0;
|
|
8625
|
+
const reflectionScaleX = parseIntAttr(reflectionNode["@_sx"]);
|
|
8626
|
+
const reflectionScaleY = parseIntAttr(reflectionNode["@_sy"]);
|
|
8627
|
+
const reflectionSkewX = parseIntAttr(reflectionNode["@_kx"]);
|
|
8628
|
+
const reflectionSkewY = parseIntAttr(reflectionNode["@_ky"]);
|
|
8629
|
+
const reflectionAlignment = parseAlignmentAttr(reflectionNode["@_algn"]);
|
|
8630
|
+
const reflectionRotateWithShape = parseBoolAttr(reflectionNode["@_rotWithShape"]);
|
|
8631
|
+
const stPosRaw = parseIntAttr(reflectionNode["@_stPos"]);
|
|
8632
|
+
const reflectionStartPosition = stPosRaw !== void 0 ? stPosRaw / 1e5 : void 0;
|
|
8393
8633
|
return {
|
|
8394
8634
|
reflectionBlurRadius,
|
|
8395
8635
|
reflectionStartOpacity,
|
|
@@ -8397,7 +8637,15 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8397
8637
|
reflectionEndPosition,
|
|
8398
8638
|
reflectionDirection,
|
|
8399
8639
|
reflectionRotation,
|
|
8400
|
-
reflectionDistance
|
|
8640
|
+
reflectionDistance,
|
|
8641
|
+
reflectionFadeDirection,
|
|
8642
|
+
reflectionScaleX,
|
|
8643
|
+
reflectionScaleY,
|
|
8644
|
+
reflectionSkewX,
|
|
8645
|
+
reflectionSkewY,
|
|
8646
|
+
reflectionAlignment,
|
|
8647
|
+
reflectionRotateWithShape,
|
|
8648
|
+
reflectionStartPosition
|
|
8401
8649
|
};
|
|
8402
8650
|
}
|
|
8403
8651
|
extractBlurStyle(shapeProps) {
|
|
@@ -8449,11 +8697,56 @@ var PptxShapeEffectXmlBuilder = class {
|
|
|
8449
8697
|
}
|
|
8450
8698
|
}
|
|
8451
8699
|
};
|
|
8700
|
+
if (typeof shapeStyle.shadowScaleX === "number") {
|
|
8701
|
+
xmlObj["@_sx"] = String(Math.round(shapeStyle.shadowScaleX));
|
|
8702
|
+
}
|
|
8703
|
+
if (typeof shapeStyle.shadowScaleY === "number") {
|
|
8704
|
+
xmlObj["@_sy"] = String(Math.round(shapeStyle.shadowScaleY));
|
|
8705
|
+
}
|
|
8706
|
+
if (typeof shapeStyle.shadowSkewX === "number") {
|
|
8707
|
+
xmlObj["@_kx"] = String(Math.round(shapeStyle.shadowSkewX));
|
|
8708
|
+
}
|
|
8709
|
+
if (typeof shapeStyle.shadowSkewY === "number") {
|
|
8710
|
+
xmlObj["@_ky"] = String(Math.round(shapeStyle.shadowSkewY));
|
|
8711
|
+
}
|
|
8712
|
+
if (shapeStyle.shadowAlignment) {
|
|
8713
|
+
xmlObj["@_algn"] = shapeStyle.shadowAlignment;
|
|
8714
|
+
}
|
|
8452
8715
|
if (typeof shapeStyle.shadowRotateWithShape === "boolean") {
|
|
8453
8716
|
xmlObj["@_rotWithShape"] = shapeStyle.shadowRotateWithShape ? "1" : "0";
|
|
8454
8717
|
}
|
|
8455
8718
|
return xmlObj;
|
|
8456
8719
|
}
|
|
8720
|
+
buildPresetShadowXml(shapeStyle) {
|
|
8721
|
+
const preset = shapeStyle.presetShadowName;
|
|
8722
|
+
if (!preset || preset.length === 0) {
|
|
8723
|
+
return void 0;
|
|
8724
|
+
}
|
|
8725
|
+
const shadowColor = String(shapeStyle.shadowColor || "#000000").trim();
|
|
8726
|
+
const shadowOpacity = typeof shapeStyle.shadowOpacity === "number" && Number.isFinite(shapeStyle.shadowOpacity) ? this.context.clampUnitInterval(shapeStyle.shadowOpacity) : 0.5;
|
|
8727
|
+
let distance;
|
|
8728
|
+
let directionDegrees;
|
|
8729
|
+
if (typeof shapeStyle.shadowAngle === "number" && typeof shapeStyle.shadowDistance === "number") {
|
|
8730
|
+
directionDegrees = shapeStyle.shadowAngle;
|
|
8731
|
+
distance = shapeStyle.shadowDistance;
|
|
8732
|
+
} else {
|
|
8733
|
+
const ox = typeof shapeStyle.shadowOffsetX === "number" ? shapeStyle.shadowOffsetX : 0;
|
|
8734
|
+
const oy = typeof shapeStyle.shadowOffsetY === "number" ? shapeStyle.shadowOffsetY : 0;
|
|
8735
|
+
distance = Math.sqrt(ox * ox + oy * oy);
|
|
8736
|
+
directionDegrees = (Math.atan2(oy, ox) * 180 / Math.PI + 360) % 360;
|
|
8737
|
+
}
|
|
8738
|
+
return {
|
|
8739
|
+
"@_prst": preset,
|
|
8740
|
+
"@_dist": String(Math.round(distance * this.context.emuPerPx)),
|
|
8741
|
+
"@_dir": String(Math.round(directionDegrees * 6e4)),
|
|
8742
|
+
"a:srgbClr": {
|
|
8743
|
+
"@_val": shadowColor.replace("#", ""),
|
|
8744
|
+
"a:alpha": {
|
|
8745
|
+
"@_val": String(Math.round(shadowOpacity * 1e5))
|
|
8746
|
+
}
|
|
8747
|
+
}
|
|
8748
|
+
};
|
|
8749
|
+
}
|
|
8457
8750
|
buildInnerShadowXml(shapeStyle) {
|
|
8458
8751
|
const innerColor = String(shapeStyle.innerShadowColor || "").trim();
|
|
8459
8752
|
if (innerColor.length === 0 || innerColor === "transparent") {
|
|
@@ -8465,7 +8758,7 @@ var PptxShapeEffectXmlBuilder = class {
|
|
|
8465
8758
|
const opacity = typeof shapeStyle.innerShadowOpacity === "number" && Number.isFinite(shapeStyle.innerShadowOpacity) ? this.context.clampUnitInterval(shapeStyle.innerShadowOpacity) : 0.5;
|
|
8466
8759
|
const distance = Math.sqrt(offsetX * offsetX + offsetY * offsetY);
|
|
8467
8760
|
const directionDegrees = (Math.atan2(offsetY, offsetX) * 180 / Math.PI + 360) % 360;
|
|
8468
|
-
|
|
8761
|
+
const xmlObj = {
|
|
8469
8762
|
"@_blurRad": String(Math.round(blurValue * this.context.emuPerPx)),
|
|
8470
8763
|
"@_dist": String(Math.round(distance * this.context.emuPerPx)),
|
|
8471
8764
|
"@_dir": String(Math.round(directionDegrees * 6e4)),
|
|
@@ -8476,6 +8769,10 @@ var PptxShapeEffectXmlBuilder = class {
|
|
|
8476
8769
|
}
|
|
8477
8770
|
}
|
|
8478
8771
|
};
|
|
8772
|
+
if (typeof shapeStyle.innerShadowRotateWithShape === "boolean") {
|
|
8773
|
+
xmlObj["@_rotWithShape"] = shapeStyle.innerShadowRotateWithShape ? "1" : "0";
|
|
8774
|
+
}
|
|
8775
|
+
return xmlObj;
|
|
8479
8776
|
}
|
|
8480
8777
|
buildGlowXml(shapeStyle) {
|
|
8481
8778
|
const glowColor = String(shapeStyle.glowColor || "").trim();
|
|
@@ -8537,6 +8834,30 @@ var PptxShapeEffectXmlBuilder = class {
|
|
|
8537
8834
|
Math.round(shapeStyle.reflectionDistance * this.context.emuPerPx)
|
|
8538
8835
|
);
|
|
8539
8836
|
}
|
|
8837
|
+
if (typeof shapeStyle.reflectionFadeDirection === "number") {
|
|
8838
|
+
reflectionXml["@_fadeDir"] = String(Math.round(shapeStyle.reflectionFadeDirection * 6e4));
|
|
8839
|
+
}
|
|
8840
|
+
if (typeof shapeStyle.reflectionScaleX === "number") {
|
|
8841
|
+
reflectionXml["@_sx"] = String(Math.round(shapeStyle.reflectionScaleX));
|
|
8842
|
+
}
|
|
8843
|
+
if (typeof shapeStyle.reflectionScaleY === "number") {
|
|
8844
|
+
reflectionXml["@_sy"] = String(Math.round(shapeStyle.reflectionScaleY));
|
|
8845
|
+
}
|
|
8846
|
+
if (typeof shapeStyle.reflectionSkewX === "number") {
|
|
8847
|
+
reflectionXml["@_kx"] = String(Math.round(shapeStyle.reflectionSkewX));
|
|
8848
|
+
}
|
|
8849
|
+
if (typeof shapeStyle.reflectionSkewY === "number") {
|
|
8850
|
+
reflectionXml["@_ky"] = String(Math.round(shapeStyle.reflectionSkewY));
|
|
8851
|
+
}
|
|
8852
|
+
if (shapeStyle.reflectionAlignment) {
|
|
8853
|
+
reflectionXml["@_algn"] = shapeStyle.reflectionAlignment;
|
|
8854
|
+
}
|
|
8855
|
+
if (typeof shapeStyle.reflectionRotateWithShape === "boolean") {
|
|
8856
|
+
reflectionXml["@_rotWithShape"] = shapeStyle.reflectionRotateWithShape ? "1" : "0";
|
|
8857
|
+
}
|
|
8858
|
+
if (typeof shapeStyle.reflectionStartPosition === "number") {
|
|
8859
|
+
reflectionXml["@_stPos"] = String(Math.round(shapeStyle.reflectionStartPosition * 1e5));
|
|
8860
|
+
}
|
|
8540
8861
|
return reflectionXml;
|
|
8541
8862
|
}
|
|
8542
8863
|
buildBlurXml(shapeStyle) {
|
|
@@ -8644,6 +8965,9 @@ var PptxShapeEffectXmlCodec = class {
|
|
|
8644
8965
|
buildOuterShadowXml(shapeStyle) {
|
|
8645
8966
|
return this.builder.buildOuterShadowXml(shapeStyle);
|
|
8646
8967
|
}
|
|
8968
|
+
buildPresetShadowXml(shapeStyle) {
|
|
8969
|
+
return this.builder.buildPresetShadowXml(shapeStyle);
|
|
8970
|
+
}
|
|
8647
8971
|
buildInnerShadowXml(shapeStyle) {
|
|
8648
8972
|
return this.builder.buildInnerShadowXml(shapeStyle);
|
|
8649
8973
|
}
|
|
@@ -8804,6 +9128,9 @@ var PptxColorStyleCodec = class {
|
|
|
8804
9128
|
buildOuterShadowXml(shapeStyle) {
|
|
8805
9129
|
return this.shapeEffectXmlCodec.buildOuterShadowXml(shapeStyle);
|
|
8806
9130
|
}
|
|
9131
|
+
buildPresetShadowXml(shapeStyle) {
|
|
9132
|
+
return this.shapeEffectXmlCodec.buildPresetShadowXml(shapeStyle);
|
|
9133
|
+
}
|
|
8807
9134
|
buildInnerShadowXml(shapeStyle) {
|
|
8808
9135
|
return this.shapeEffectXmlCodec.buildInnerShadowXml(shapeStyle);
|
|
8809
9136
|
}
|
|
@@ -8825,6 +9152,15 @@ var PptxColorStyleCodec = class {
|
|
|
8825
9152
|
extractGradientFillColor(gradFill) {
|
|
8826
9153
|
return this.gradientStyleCodec.extractGradientFillColor(gradFill);
|
|
8827
9154
|
}
|
|
9155
|
+
extractGradientFlip(gradFill) {
|
|
9156
|
+
return this.gradientStyleCodec.extractGradientFlip(gradFill);
|
|
9157
|
+
}
|
|
9158
|
+
extractGradientRotWithShape(gradFill) {
|
|
9159
|
+
return this.gradientStyleCodec.extractGradientRotWithShape(gradFill);
|
|
9160
|
+
}
|
|
9161
|
+
extractGradientScaled(gradFill) {
|
|
9162
|
+
return this.gradientStyleCodec.extractGradientScaled(gradFill);
|
|
9163
|
+
}
|
|
8828
9164
|
extractGradientPathType(gradFill) {
|
|
8829
9165
|
return this.gradientStyleCodec.extractGradientPathType(gradFill);
|
|
8830
9166
|
}
|
|
@@ -8836,6 +9172,61 @@ var PptxColorStyleCodec = class {
|
|
|
8836
9172
|
}
|
|
8837
9173
|
};
|
|
8838
9174
|
|
|
9175
|
+
// src/core/utils/color-xml-preservation.ts
|
|
9176
|
+
var COLOR_CHOICE_KEYS = [
|
|
9177
|
+
"a:srgbClr",
|
|
9178
|
+
"a:schemeClr",
|
|
9179
|
+
"a:sysClr",
|
|
9180
|
+
"a:prstClr",
|
|
9181
|
+
"a:scrgbClr",
|
|
9182
|
+
"a:hslClr"
|
|
9183
|
+
];
|
|
9184
|
+
function extractColorChoiceXml(parent) {
|
|
9185
|
+
if (!parent) {
|
|
9186
|
+
return void 0;
|
|
9187
|
+
}
|
|
9188
|
+
for (const key of COLOR_CHOICE_KEYS) {
|
|
9189
|
+
if (parent[key] !== void 0) {
|
|
9190
|
+
return { [key]: parent[key] };
|
|
9191
|
+
}
|
|
9192
|
+
}
|
|
9193
|
+
return void 0;
|
|
9194
|
+
}
|
|
9195
|
+
function normalizeHex(value) {
|
|
9196
|
+
const raw = String(value ?? "").trim();
|
|
9197
|
+
if (raw.length === 0) {
|
|
9198
|
+
return "";
|
|
9199
|
+
}
|
|
9200
|
+
const hex = raw.replace(/^#/, "");
|
|
9201
|
+
if (/^[0-9a-fA-F]{6}$/.test(hex)) {
|
|
9202
|
+
return hex.toUpperCase();
|
|
9203
|
+
}
|
|
9204
|
+
return raw.toLowerCase();
|
|
9205
|
+
}
|
|
9206
|
+
function colorsEqual(left, right) {
|
|
9207
|
+
if (left === void 0 || right === void 0) {
|
|
9208
|
+
return false;
|
|
9209
|
+
}
|
|
9210
|
+
return normalizeHex(left) === normalizeHex(right);
|
|
9211
|
+
}
|
|
9212
|
+
function buildSrgbColorChoice(hex, opacity) {
|
|
9213
|
+
const normalized = String(hex || "").replace(/^#/, "");
|
|
9214
|
+
const srgb = { "@_val": normalized };
|
|
9215
|
+
if (typeof opacity === "number" && Number.isFinite(opacity) && opacity >= 0 && opacity < 1) {
|
|
9216
|
+
const alphaPct = Math.round(Math.max(0, Math.min(1, opacity)) * 1e5);
|
|
9217
|
+
srgb["a:alpha"] = { "@_val": String(alphaPct) };
|
|
9218
|
+
}
|
|
9219
|
+
return { "a:srgbClr": srgb };
|
|
9220
|
+
}
|
|
9221
|
+
function serializeColorChoice(originalColorXml, currentResolvedHex, fallbackHex, opacity, options = {}) {
|
|
9222
|
+
if (originalColorXml && colorsEqual(currentResolvedHex, fallbackHex)) {
|
|
9223
|
+
if (options.preserveAlphaFromOriginal !== false) {
|
|
9224
|
+
return originalColorXml;
|
|
9225
|
+
}
|
|
9226
|
+
}
|
|
9227
|
+
return buildSrgbColorChoice(fallbackHex, opacity);
|
|
9228
|
+
}
|
|
9229
|
+
|
|
8839
9230
|
// src/core/core/builders/shape-style-3d-helpers.ts
|
|
8840
9231
|
function applyScene3dStyle(shapeProps, style) {
|
|
8841
9232
|
const scene3dNode = shapeProps["a:scene3d"];
|
|
@@ -8921,6 +9312,10 @@ function applyStrokeColor(lineNode, style, context) {
|
|
|
8921
9312
|
const lineFill = lineNode["a:solidFill"];
|
|
8922
9313
|
style.strokeColor = context.parseColor(lineFill);
|
|
8923
9314
|
style.strokeOpacity = context.extractColorOpacity(lineFill);
|
|
9315
|
+
const strokeColorXml = extractColorChoiceXml(lineFill);
|
|
9316
|
+
if (strokeColorXml) {
|
|
9317
|
+
style.strokeColorXml = strokeColorXml;
|
|
9318
|
+
}
|
|
8924
9319
|
} else if (lineNode["a:gradFill"]) {
|
|
8925
9320
|
style.strokeColor = context.extractGradientFillColor(lineNode["a:gradFill"]);
|
|
8926
9321
|
style.strokeOpacity = context.extractGradientOpacity(lineNode["a:gradFill"]);
|
|
@@ -8988,6 +9383,14 @@ function applyJoinCapCompound(lineNode, style) {
|
|
|
8988
9383
|
style.lineJoin = "bevel";
|
|
8989
9384
|
} else if ("a:miter" in lineNode) {
|
|
8990
9385
|
style.lineJoin = "miter";
|
|
9386
|
+
const miterNode = lineNode["a:miter"];
|
|
9387
|
+
const limRaw = miterNode?.["@_lim"];
|
|
9388
|
+
if (limRaw !== void 0 && limRaw !== "") {
|
|
9389
|
+
const parsed = parseInt(String(limRaw), 10);
|
|
9390
|
+
if (Number.isFinite(parsed)) {
|
|
9391
|
+
style.miterLimit = parsed;
|
|
9392
|
+
}
|
|
9393
|
+
}
|
|
8991
9394
|
}
|
|
8992
9395
|
const capValue = String(lineNode["@_cap"] || "").trim().toLowerCase();
|
|
8993
9396
|
if (capValue === "rnd" || capValue === "sq" || capValue === "flat") {
|
|
@@ -9044,6 +9447,10 @@ var PptxShapeStyleExtractor = class {
|
|
|
9044
9447
|
style.fillMode = "solid";
|
|
9045
9448
|
style.fillColor = this.context.parseColor(solidFill);
|
|
9046
9449
|
style.fillOpacity = this.context.extractColorOpacity(solidFill);
|
|
9450
|
+
const solidFillColorXml = extractColorChoiceXml(solidFill);
|
|
9451
|
+
if (solidFillColorXml) {
|
|
9452
|
+
style.fillColorXml = solidFillColorXml;
|
|
9453
|
+
}
|
|
9047
9454
|
} else if (gradFill) {
|
|
9048
9455
|
style.fillMode = "gradient";
|
|
9049
9456
|
style.fillColor = this.context.extractGradientFillColor(gradFill);
|
|
@@ -9055,6 +9462,18 @@ var PptxShapeStyleExtractor = class {
|
|
|
9055
9462
|
style.fillGradientPathType = this.context.extractGradientPathType(gradFill);
|
|
9056
9463
|
style.fillGradientFocalPoint = this.context.extractGradientFocalPoint(gradFill);
|
|
9057
9464
|
style.fillGradientFillToRect = this.context.extractGradientFillToRect(gradFill);
|
|
9465
|
+
const gradFlip = this.context.extractGradientFlip(gradFill);
|
|
9466
|
+
if (gradFlip) {
|
|
9467
|
+
style.fillGradientFlip = gradFlip;
|
|
9468
|
+
}
|
|
9469
|
+
const gradRot = this.context.extractGradientRotWithShape(gradFill);
|
|
9470
|
+
if (gradRot !== void 0) {
|
|
9471
|
+
style.fillGradientRotWithShape = gradRot;
|
|
9472
|
+
}
|
|
9473
|
+
const gradScaled = this.context.extractGradientScaled(gradFill);
|
|
9474
|
+
if (gradScaled !== void 0) {
|
|
9475
|
+
style.fillGradientScaled = gradScaled;
|
|
9476
|
+
}
|
|
9058
9477
|
} else if (pattFill) {
|
|
9059
9478
|
style.fillMode = "pattern";
|
|
9060
9479
|
style.fillColor = this.context.parseColor(pattFill["a:fgClr"]) || this.context.parseColor(pattFill["a:bgClr"]);
|
|
@@ -9136,10 +9555,45 @@ var PptxShapeStyleExtractor = class {
|
|
|
9136
9555
|
if (styleNode?.["a:effectRef"]) {
|
|
9137
9556
|
this.context.resolveThemeEffectRef(styleNode["a:effectRef"], style);
|
|
9138
9557
|
}
|
|
9558
|
+
const fontRef = styleNode?.["a:fontRef"];
|
|
9559
|
+
if (fontRef) {
|
|
9560
|
+
const idxAttr = String(fontRef["@_idx"] || "").trim();
|
|
9561
|
+
if (idxAttr.length > 0) {
|
|
9562
|
+
style.fontRefIdx = idxAttr;
|
|
9563
|
+
}
|
|
9564
|
+
const overrideColorXml = this.extractFontRefColorXml(fontRef);
|
|
9565
|
+
if (overrideColorXml) {
|
|
9566
|
+
style.fontRefColorXml = overrideColorXml;
|
|
9567
|
+
}
|
|
9568
|
+
}
|
|
9139
9569
|
applyScene3dStyle(shapeProps, style);
|
|
9140
9570
|
applyShape3dStyle(shapeProps, style, this.context);
|
|
9141
9571
|
return style;
|
|
9142
9572
|
}
|
|
9573
|
+
/**
|
|
9574
|
+
* Pull the verbatim colour-choice child out of an `a:fontRef` element,
|
|
9575
|
+
* preserving any contained colour transforms for round-trip.
|
|
9576
|
+
*/
|
|
9577
|
+
extractFontRefColorXml(refNode) {
|
|
9578
|
+
if (!refNode) {
|
|
9579
|
+
return void 0;
|
|
9580
|
+
}
|
|
9581
|
+
const keys = [
|
|
9582
|
+
"a:scrgbClr",
|
|
9583
|
+
"a:srgbClr",
|
|
9584
|
+
"a:hslClr",
|
|
9585
|
+
"a:sysClr",
|
|
9586
|
+
"a:schemeClr",
|
|
9587
|
+
"a:prstClr"
|
|
9588
|
+
];
|
|
9589
|
+
for (const key of keys) {
|
|
9590
|
+
const child = refNode[key];
|
|
9591
|
+
if (child !== void 0) {
|
|
9592
|
+
return { [key]: child };
|
|
9593
|
+
}
|
|
9594
|
+
}
|
|
9595
|
+
return void 0;
|
|
9596
|
+
}
|
|
9143
9597
|
/**
|
|
9144
9598
|
* Extract p14:hiddenFill from the shape properties extension list.
|
|
9145
9599
|
* URI: {AF507438-7753-43E0-B8FC-AC1667EBCBE1}
|
|
@@ -9190,10 +9644,15 @@ var PptxShapeStyleExtractor = class {
|
|
|
9190
9644
|
function applyCellFillStyle(cellProperties, style, context) {
|
|
9191
9645
|
let hasStyle = false;
|
|
9192
9646
|
if (cellProperties?.["a:solidFill"]) {
|
|
9193
|
-
const
|
|
9647
|
+
const solidFillNode = cellProperties["a:solidFill"];
|
|
9648
|
+
const fillColor = context.parseColor(solidFillNode);
|
|
9194
9649
|
if (fillColor) {
|
|
9195
9650
|
style.fillMode = "solid";
|
|
9196
9651
|
style.backgroundColor = fillColor;
|
|
9652
|
+
const bgColorXml = extractColorChoiceXml(solidFillNode);
|
|
9653
|
+
if (bgColorXml) {
|
|
9654
|
+
style.backgroundColorXml = bgColorXml;
|
|
9655
|
+
}
|
|
9197
9656
|
hasStyle = true;
|
|
9198
9657
|
}
|
|
9199
9658
|
}
|
|
@@ -9230,6 +9689,10 @@ function applyCellFillStyle(cellProperties, style, context) {
|
|
|
9230
9689
|
}
|
|
9231
9690
|
}
|
|
9232
9691
|
}
|
|
9692
|
+
if (cellProperties?.["a:noFill"] !== void 0) {
|
|
9693
|
+
style.fillMode = "none";
|
|
9694
|
+
hasStyle = true;
|
|
9695
|
+
}
|
|
9233
9696
|
if (cellProperties?.["a:pattFill"]) {
|
|
9234
9697
|
const pattFill = cellProperties["a:pattFill"];
|
|
9235
9698
|
const fgColor = context.parseColor(pattFill["a:fgClr"]);
|
|
@@ -9536,8 +9999,7 @@ var PptxTableDataParser = class {
|
|
|
9536
9999
|
return width / totalWidthEmu;
|
|
9537
10000
|
}) : gridColumns.map(() => 1 / Math.max(gridColumns.length, 1));
|
|
9538
10001
|
const tableProperties = tableNode["a:tblPr"] || {};
|
|
9539
|
-
const
|
|
9540
|
-
const tableStyleId = String(tableStyleNode?.["@_val"] || tableProperties["@_tblStyle"] || "").trim() || void 0;
|
|
10002
|
+
const tableStyleId = this.extractTableStyleId(tableProperties);
|
|
9541
10003
|
const xmlRows = this.context.ensureArray(tableNode["a:tr"]);
|
|
9542
10004
|
const rows = xmlRows.map((rowNode) => {
|
|
9543
10005
|
const rowHeightEmu = parseInt(String(rowNode?.["@_h"] || "0"), 10) || 0;
|
|
@@ -9572,6 +10034,28 @@ var PptxTableDataParser = class {
|
|
|
9572
10034
|
return void 0;
|
|
9573
10035
|
}
|
|
9574
10036
|
}
|
|
10037
|
+
/**
|
|
10038
|
+
* Read the table style ID from `a:tblPr`.
|
|
10039
|
+
*
|
|
10040
|
+
* ECMA-376 §21.1.3.13 defines `<a:tableStyleId>{GUID}</a:tableStyleId>` as
|
|
10041
|
+
* a child element of `a:tblPr` carrying the GUID as element text. Older
|
|
10042
|
+
* inputs (and earlier versions of this library) used the legacy
|
|
10043
|
+
* `<a:tblStyle val="{GUID}"/>` child element or a `@_tblStyle` attribute.
|
|
10044
|
+
* Accept all three; the spec form takes precedence.
|
|
10045
|
+
*/
|
|
10046
|
+
extractTableStyleId(tableProperties) {
|
|
10047
|
+
const tableStyleIdNode = tableProperties["a:tableStyleId"];
|
|
10048
|
+
if (tableStyleIdNode !== void 0 && tableStyleIdNode !== null) {
|
|
10049
|
+
const direct = typeof tableStyleIdNode === "string" || typeof tableStyleIdNode === "number" ? String(tableStyleIdNode) : String(tableStyleIdNode["#text"] ?? "");
|
|
10050
|
+
const trimmed = direct.trim();
|
|
10051
|
+
if (trimmed.length > 0) {
|
|
10052
|
+
return trimmed;
|
|
10053
|
+
}
|
|
10054
|
+
}
|
|
10055
|
+
const tableStyleNode = tableProperties["a:tblStyle"];
|
|
10056
|
+
const legacy = String(tableStyleNode?.["@_val"] || tableProperties["@_tblStyle"] || "").trim();
|
|
10057
|
+
return legacy.length > 0 ? legacy : void 0;
|
|
10058
|
+
}
|
|
9575
10059
|
extractTableCellText(tableCell) {
|
|
9576
10060
|
const paragraphs = this.context.ensureArray(tableCell?.["a:txBody"]?.["a:p"]);
|
|
9577
10061
|
const lines = [];
|
|
@@ -9850,6 +10334,19 @@ var PptxGraphicFrameParser = class {
|
|
|
9850
10334
|
if (graphicData["a:videoFile"] || graphicData["a:audioFile"] || uri.includes("/drawingml/2006/media")) {
|
|
9851
10335
|
return "media";
|
|
9852
10336
|
}
|
|
10337
|
+
if (graphicData["aink:ink"] || uri.includes("/2010/ink") || uri.includes("drawing/2010/ink")) {
|
|
10338
|
+
return "ink";
|
|
10339
|
+
}
|
|
10340
|
+
const alternateContent = graphicData["mc:AlternateContent"];
|
|
10341
|
+
if (alternateContent) {
|
|
10342
|
+
const choices = Array.isArray(alternateContent["mc:Choice"]) ? alternateContent["mc:Choice"] : alternateContent["mc:Choice"] ? [alternateContent["mc:Choice"]] : [];
|
|
10343
|
+
for (const choice of choices) {
|
|
10344
|
+
const requires = String(choice?.["@_Requires"] || "").toLowerCase();
|
|
10345
|
+
if (requires.includes("aink") || choice?.["aink:ink"]) {
|
|
10346
|
+
return "ink";
|
|
10347
|
+
}
|
|
10348
|
+
}
|
|
10349
|
+
}
|
|
9853
10350
|
return "unknown";
|
|
9854
10351
|
}
|
|
9855
10352
|
};
|
|
@@ -10751,6 +11248,7 @@ var PptxDocumentPropertiesUpdater = class {
|
|
|
10751
11248
|
}));
|
|
10752
11249
|
if (sanitized.length === 0) {
|
|
10753
11250
|
this.context.zip.remove("docProps/custom.xml");
|
|
11251
|
+
await this.removeCustomPropertiesPackagingArtifacts();
|
|
10754
11252
|
return;
|
|
10755
11253
|
}
|
|
10756
11254
|
const customXml = {
|
|
@@ -10770,6 +11268,116 @@ var PptxDocumentPropertiesUpdater = class {
|
|
|
10770
11268
|
}
|
|
10771
11269
|
};
|
|
10772
11270
|
this.context.zip.file("docProps/custom.xml", this.context.builder.build(customXml));
|
|
11271
|
+
await this.ensureCustomPropertiesPackagingArtifacts();
|
|
11272
|
+
}
|
|
11273
|
+
/**
|
|
11274
|
+
* Ensure `[Content_Types].xml` has an `Override` for `docProps/custom.xml`
|
|
11275
|
+
* and the root `_rels/.rels` references it (ECMA-376 §15.2.12.2 +
|
|
11276
|
+
* Part 2 §10.1.2.5). Without these, the package fails OPC validation
|
|
11277
|
+
* and Office strips the custom properties on next save.
|
|
11278
|
+
*/
|
|
11279
|
+
async ensureCustomPropertiesPackagingArtifacts() {
|
|
11280
|
+
const customContentType = "application/vnd.openxmlformats-officedocument.custom-properties+xml";
|
|
11281
|
+
const customRelType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties";
|
|
11282
|
+
const ctFile = this.context.zip.file("[Content_Types].xml");
|
|
11283
|
+
if (ctFile) {
|
|
11284
|
+
try {
|
|
11285
|
+
const ctXml = await ctFile.async("string");
|
|
11286
|
+
const ctData = this.context.parser.parse(ctXml);
|
|
11287
|
+
const types = ctData["Types"];
|
|
11288
|
+
if (types) {
|
|
11289
|
+
const overrides = Array.isArray(types["Override"]) ? types["Override"] : types["Override"] ? [types["Override"]] : [];
|
|
11290
|
+
const hasCustomOverride = overrides.some(
|
|
11291
|
+
(o) => String(o?.["@_PartName"] || "") === "/docProps/custom.xml"
|
|
11292
|
+
);
|
|
11293
|
+
if (!hasCustomOverride) {
|
|
11294
|
+
overrides.push({
|
|
11295
|
+
"@_PartName": "/docProps/custom.xml",
|
|
11296
|
+
"@_ContentType": customContentType
|
|
11297
|
+
});
|
|
11298
|
+
types["Override"] = overrides.length === 1 ? overrides[0] : overrides;
|
|
11299
|
+
this.context.zip.file("[Content_Types].xml", this.context.builder.build(ctData));
|
|
11300
|
+
}
|
|
11301
|
+
}
|
|
11302
|
+
} catch (error) {
|
|
11303
|
+
console.warn("Failed to update [Content_Types].xml for custom properties:", error);
|
|
11304
|
+
}
|
|
11305
|
+
}
|
|
11306
|
+
const relsFile = this.context.zip.file("_rels/.rels");
|
|
11307
|
+
if (relsFile) {
|
|
11308
|
+
try {
|
|
11309
|
+
const relsXml = await relsFile.async("string");
|
|
11310
|
+
const relsData = this.context.parser.parse(relsXml);
|
|
11311
|
+
const relationships = relsData["Relationships"];
|
|
11312
|
+
if (relationships) {
|
|
11313
|
+
const rels = Array.isArray(relationships["Relationship"]) ? relationships["Relationship"] : relationships["Relationship"] ? [relationships["Relationship"]] : [];
|
|
11314
|
+
const hasCustomRel = rels.some((r) => String(r?.["@_Type"] || "") === customRelType);
|
|
11315
|
+
if (!hasCustomRel) {
|
|
11316
|
+
let maxId = 0;
|
|
11317
|
+
for (const rel of rels) {
|
|
11318
|
+
const id = String(rel?.["@_Id"] || "");
|
|
11319
|
+
const num = Number.parseInt(id.replace(/^rId/, ""), 10);
|
|
11320
|
+
if (Number.isFinite(num) && num > maxId) {
|
|
11321
|
+
maxId = num;
|
|
11322
|
+
}
|
|
11323
|
+
}
|
|
11324
|
+
rels.push({
|
|
11325
|
+
"@_Id": `rId${maxId + 1}`,
|
|
11326
|
+
"@_Type": customRelType,
|
|
11327
|
+
"@_Target": "docProps/custom.xml"
|
|
11328
|
+
});
|
|
11329
|
+
relationships["Relationship"] = rels;
|
|
11330
|
+
this.context.zip.file("_rels/.rels", this.context.builder.build(relsData));
|
|
11331
|
+
}
|
|
11332
|
+
}
|
|
11333
|
+
} catch (error) {
|
|
11334
|
+
console.warn("Failed to update _rels/.rels for custom properties:", error);
|
|
11335
|
+
}
|
|
11336
|
+
}
|
|
11337
|
+
}
|
|
11338
|
+
/**
|
|
11339
|
+
* Remove the Override + root rel for `docProps/custom.xml` when the
|
|
11340
|
+
* caller has emptied custom properties so the package doesn't keep an
|
|
11341
|
+
* orphan content-type entry referencing a deleted part.
|
|
11342
|
+
*/
|
|
11343
|
+
async removeCustomPropertiesPackagingArtifacts() {
|
|
11344
|
+
const customRelType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties";
|
|
11345
|
+
const ctFile = this.context.zip.file("[Content_Types].xml");
|
|
11346
|
+
if (ctFile) {
|
|
11347
|
+
try {
|
|
11348
|
+
const ctXml = await ctFile.async("string");
|
|
11349
|
+
const ctData = this.context.parser.parse(ctXml);
|
|
11350
|
+
const types = ctData["Types"];
|
|
11351
|
+
if (types) {
|
|
11352
|
+
const overrides = Array.isArray(types["Override"]) ? types["Override"] : types["Override"] ? [types["Override"]] : [];
|
|
11353
|
+
const filtered = overrides.filter(
|
|
11354
|
+
(o) => String(o?.["@_PartName"] || "") !== "/docProps/custom.xml"
|
|
11355
|
+
);
|
|
11356
|
+
if (filtered.length !== overrides.length) {
|
|
11357
|
+
types["Override"] = filtered.length === 1 ? filtered[0] : filtered;
|
|
11358
|
+
this.context.zip.file("[Content_Types].xml", this.context.builder.build(ctData));
|
|
11359
|
+
}
|
|
11360
|
+
}
|
|
11361
|
+
} catch {
|
|
11362
|
+
}
|
|
11363
|
+
}
|
|
11364
|
+
const relsFile = this.context.zip.file("_rels/.rels");
|
|
11365
|
+
if (relsFile) {
|
|
11366
|
+
try {
|
|
11367
|
+
const relsXml = await relsFile.async("string");
|
|
11368
|
+
const relsData = this.context.parser.parse(relsXml);
|
|
11369
|
+
const relationships = relsData["Relationships"];
|
|
11370
|
+
if (relationships) {
|
|
11371
|
+
const rels = Array.isArray(relationships["Relationship"]) ? relationships["Relationship"] : relationships["Relationship"] ? [relationships["Relationship"]] : [];
|
|
11372
|
+
const filtered = rels.filter((r) => String(r?.["@_Type"] || "") !== customRelType);
|
|
11373
|
+
if (filtered.length !== rels.length) {
|
|
11374
|
+
relationships["Relationship"] = filtered;
|
|
11375
|
+
this.context.zip.file("_rels/.rels", this.context.builder.build(relsData));
|
|
11376
|
+
}
|
|
11377
|
+
}
|
|
11378
|
+
} catch {
|
|
11379
|
+
}
|
|
11380
|
+
}
|
|
10773
11381
|
}
|
|
10774
11382
|
normalizeCustomPropertyType(type) {
|
|
10775
11383
|
const supportedTypes = /* @__PURE__ */ new Set([
|
|
@@ -11113,6 +11721,7 @@ var PptxSlideLoaderService = class {
|
|
|
11113
11721
|
await params.loadSlideRelationships(path2, slideRelsPath);
|
|
11114
11722
|
const clrMapOverride = params.parseSlideClrMapOverride(slideXmlObj);
|
|
11115
11723
|
params.setCurrentSlideClrMapOverride(clrMapOverride);
|
|
11724
|
+
await params.setActiveMasterForSlide?.(path2);
|
|
11116
11725
|
let restoreThemeOverride;
|
|
11117
11726
|
try {
|
|
11118
11727
|
const layoutPathForOverride = params.findLayoutPathForSlide(path2);
|
|
@@ -15864,6 +16473,20 @@ var AXIS_TYPE_MAP = {
|
|
|
15864
16473
|
dateAx: "dateAx",
|
|
15865
16474
|
serAx: "serAx"
|
|
15866
16475
|
};
|
|
16476
|
+
function upsertChartAxisChild(parent, localName, value, getLocalName) {
|
|
16477
|
+
const existingKey = Object.keys(parent).find((k) => getLocalName(k) === localName);
|
|
16478
|
+
if (value === void 0) {
|
|
16479
|
+
if (existingKey) {
|
|
16480
|
+
delete parent[existingKey];
|
|
16481
|
+
}
|
|
16482
|
+
return;
|
|
16483
|
+
}
|
|
16484
|
+
if (existingKey) {
|
|
16485
|
+
parent[existingKey]["@_val"] = value;
|
|
16486
|
+
} else {
|
|
16487
|
+
parent[`c:${localName}`] = { "@_val": value };
|
|
16488
|
+
}
|
|
16489
|
+
}
|
|
15867
16490
|
function parseChartAxes(plotArea, xmlLookup, colorParser, getLocalName) {
|
|
15868
16491
|
const result = [];
|
|
15869
16492
|
for (const key of Object.keys(plotArea)) {
|
|
@@ -15984,6 +16607,27 @@ function parseSingleAxis(axisNode, axisType, xmlLookup, colorParser) {
|
|
|
15984
16607
|
if (dispUnitsNode) {
|
|
15985
16608
|
parseDisplayUnits(dispUnitsNode, xmlLookup, result);
|
|
15986
16609
|
}
|
|
16610
|
+
const majorUnitNode = xmlLookup.getChildByLocalName(axisNode, "majorUnit");
|
|
16611
|
+
if (majorUnitNode) {
|
|
16612
|
+
const majorVal = parseFloat(String(majorUnitNode["@_val"]));
|
|
16613
|
+
if (Number.isFinite(majorVal)) {
|
|
16614
|
+
result.majorUnit = majorVal;
|
|
16615
|
+
}
|
|
16616
|
+
}
|
|
16617
|
+
const minorUnitNode = xmlLookup.getChildByLocalName(axisNode, "minorUnit");
|
|
16618
|
+
if (minorUnitNode) {
|
|
16619
|
+
const minorVal = parseFloat(String(minorUnitNode["@_val"]));
|
|
16620
|
+
if (Number.isFinite(minorVal)) {
|
|
16621
|
+
result.minorUnit = minorVal;
|
|
16622
|
+
}
|
|
16623
|
+
}
|
|
16624
|
+
const tickLblPosNode = xmlLookup.getChildByLocalName(axisNode, "tickLblPos");
|
|
16625
|
+
if (tickLblPosNode) {
|
|
16626
|
+
const v = String(tickLblPosNode["@_val"] || "").trim();
|
|
16627
|
+
if (v === "high" || v === "low" || v === "nextTo" || v === "none") {
|
|
16628
|
+
result.tickLblPos = v;
|
|
16629
|
+
}
|
|
16630
|
+
}
|
|
15987
16631
|
return result;
|
|
15988
16632
|
}
|
|
15989
16633
|
var VALID_DISPLAY_UNITS = /* @__PURE__ */ new Set([
|
|
@@ -17295,23 +17939,55 @@ var SHAPE_TREE_ELEMENT_TAGS = /* @__PURE__ */ new Set([
|
|
|
17295
17939
|
"p16:model3D",
|
|
17296
17940
|
...VML_SHAPE_TAGS
|
|
17297
17941
|
]);
|
|
17942
|
+
function diagnoseSelection(ac) {
|
|
17943
|
+
const choices = ensureArray2(ac["mc:Choice"]);
|
|
17944
|
+
for (let i = 0; i < choices.length; i++) {
|
|
17945
|
+
const choice = choices[i];
|
|
17946
|
+
const requires = String(choice?.["@_Requires"] ?? "").trim();
|
|
17947
|
+
if (requires.length === 0 || areNamespacesSupported(requires)) {
|
|
17948
|
+
const resolved = resolveNestedAlternateContent(choice);
|
|
17949
|
+
return { branch: "choice", choiceIndex: i, resolved };
|
|
17950
|
+
}
|
|
17951
|
+
}
|
|
17952
|
+
const fallback = ac["mc:Fallback"];
|
|
17953
|
+
if (fallback) {
|
|
17954
|
+
return { branch: "fallback", resolved: resolveNestedAlternateContent(fallback) };
|
|
17955
|
+
}
|
|
17956
|
+
return void 0;
|
|
17957
|
+
}
|
|
17298
17958
|
function unwrapAlternateContent(container) {
|
|
17299
17959
|
const altContents = ensureArray2(container["mc:AlternateContent"]);
|
|
17300
17960
|
if (altContents.length === 0) {
|
|
17301
|
-
return;
|
|
17961
|
+
return [];
|
|
17302
17962
|
}
|
|
17963
|
+
const blocks = [];
|
|
17303
17964
|
for (const ac of altContents) {
|
|
17304
|
-
const
|
|
17305
|
-
if (!
|
|
17965
|
+
const diagnosis = diagnoseSelection(ac);
|
|
17966
|
+
if (!diagnosis) {
|
|
17306
17967
|
continue;
|
|
17307
17968
|
}
|
|
17969
|
+
const block = {
|
|
17970
|
+
rawAc: ac,
|
|
17971
|
+
selectedBranch: diagnosis.branch,
|
|
17972
|
+
choiceIndex: diagnosis.branch === "choice" ? diagnosis.choiceIndex : void 0,
|
|
17973
|
+
childRefs: []
|
|
17974
|
+
};
|
|
17975
|
+
const branch = diagnosis.resolved;
|
|
17308
17976
|
for (const tag of SHAPE_TREE_ELEMENT_TAGS) {
|
|
17309
17977
|
const children = ensureArray2(branch[tag]);
|
|
17310
17978
|
if (children.length > 0) {
|
|
17311
17979
|
container[tag] = [...ensureArray2(container[tag]), ...children];
|
|
17980
|
+
for (const child of children) {
|
|
17981
|
+
block.childRefs.push({ tag, node: child });
|
|
17982
|
+
}
|
|
17312
17983
|
}
|
|
17313
17984
|
}
|
|
17985
|
+
if (block.childRefs.length > 0) {
|
|
17986
|
+
blocks.push(block);
|
|
17987
|
+
}
|
|
17314
17988
|
}
|
|
17989
|
+
delete container["mc:AlternateContent"];
|
|
17990
|
+
return blocks;
|
|
17315
17991
|
}
|
|
17316
17992
|
function ensureArray2(val) {
|
|
17317
17993
|
if (!val) {
|
|
@@ -17323,7 +17999,7 @@ function ensureArray2(val) {
|
|
|
17323
17999
|
|
|
17324
18000
|
// src/core/utils/body-properties-parser.ts
|
|
17325
18001
|
function parseBodyPrBooleanAttrs(bodyPr, textStyle) {
|
|
17326
|
-
const
|
|
18002
|
+
const parseBoolAttr2 = (attr) => {
|
|
17327
18003
|
const raw = bodyPr[attr];
|
|
17328
18004
|
if (raw === void 0) {
|
|
17329
18005
|
return void 0;
|
|
@@ -17331,19 +18007,19 @@ function parseBodyPrBooleanAttrs(bodyPr, textStyle) {
|
|
|
17331
18007
|
const val = String(raw).trim().toLowerCase();
|
|
17332
18008
|
return val === "1" || val === "true";
|
|
17333
18009
|
};
|
|
17334
|
-
const compatLnSpc =
|
|
18010
|
+
const compatLnSpc = parseBoolAttr2("@_compatLnSpc");
|
|
17335
18011
|
if (compatLnSpc !== void 0) {
|
|
17336
18012
|
textStyle.compatibleLineSpacing = compatLnSpc;
|
|
17337
18013
|
}
|
|
17338
|
-
const forceAA =
|
|
18014
|
+
const forceAA = parseBoolAttr2("@_forceAA");
|
|
17339
18015
|
if (forceAA !== void 0) {
|
|
17340
18016
|
textStyle.forceAntiAlias = forceAA;
|
|
17341
18017
|
}
|
|
17342
|
-
const upright =
|
|
18018
|
+
const upright = parseBoolAttr2("@_upright");
|
|
17343
18019
|
if (upright !== void 0) {
|
|
17344
18020
|
textStyle.upright = upright;
|
|
17345
18021
|
}
|
|
17346
|
-
const fromWordArt =
|
|
18022
|
+
const fromWordArt = parseBoolAttr2("@_fromWordArt");
|
|
17347
18023
|
if (fromWordArt !== void 0) {
|
|
17348
18024
|
textStyle.fromWordArt = fromWordArt;
|
|
17349
18025
|
}
|
|
@@ -17366,46 +18042,6 @@ function writeBodyPrBooleanAttrs(bodyPr, textStyle) {
|
|
|
17366
18042
|
}
|
|
17367
18043
|
}
|
|
17368
18044
|
|
|
17369
|
-
// src/core/utils/theme-override-utils.ts
|
|
17370
|
-
var COLOR_MAP_ALIAS_KEYS = [
|
|
17371
|
-
"bg1",
|
|
17372
|
-
"tx1",
|
|
17373
|
-
"bg2",
|
|
17374
|
-
"tx2",
|
|
17375
|
-
"accent1",
|
|
17376
|
-
"accent2",
|
|
17377
|
-
"accent3",
|
|
17378
|
-
"accent4",
|
|
17379
|
-
"accent5",
|
|
17380
|
-
"accent6",
|
|
17381
|
-
"hlink",
|
|
17382
|
-
"folHlink"
|
|
17383
|
-
];
|
|
17384
|
-
var DEFAULT_COLOR_MAP = {
|
|
17385
|
-
bg1: "lt1",
|
|
17386
|
-
tx1: "dk1",
|
|
17387
|
-
bg2: "lt2",
|
|
17388
|
-
tx2: "dk2",
|
|
17389
|
-
accent1: "accent1",
|
|
17390
|
-
accent2: "accent2",
|
|
17391
|
-
accent3: "accent3",
|
|
17392
|
-
accent4: "accent4",
|
|
17393
|
-
accent5: "accent5",
|
|
17394
|
-
accent6: "accent6",
|
|
17395
|
-
hlink: "hlink",
|
|
17396
|
-
folHlink: "folHlink"
|
|
17397
|
-
};
|
|
17398
|
-
function buildClrMapOverrideXml(override) {
|
|
17399
|
-
if (!override || Object.keys(override).length === 0) {
|
|
17400
|
-
return { "a:masterClrMapping": {} };
|
|
17401
|
-
}
|
|
17402
|
-
const attrs2 = {};
|
|
17403
|
-
for (const key of COLOR_MAP_ALIAS_KEYS) {
|
|
17404
|
-
attrs2[`@_${key}`] = override[key] ?? DEFAULT_COLOR_MAP[key];
|
|
17405
|
-
}
|
|
17406
|
-
return { "a:overrideClrMapping": attrs2 };
|
|
17407
|
-
}
|
|
17408
|
-
|
|
17409
18045
|
// src/core/utils/data-url-utils.ts
|
|
17410
18046
|
function parseDataUrlToBytes(dataUrl) {
|
|
17411
18047
|
const match = dataUrl.match(/^data:([^;]+);base64,(.+)$/);
|
|
@@ -17503,6 +18139,46 @@ async function fetchUrlToBytes(url) {
|
|
|
17503
18139
|
}
|
|
17504
18140
|
}
|
|
17505
18141
|
|
|
18142
|
+
// src/core/utils/theme-override-utils.ts
|
|
18143
|
+
var COLOR_MAP_ALIAS_KEYS = [
|
|
18144
|
+
"bg1",
|
|
18145
|
+
"tx1",
|
|
18146
|
+
"bg2",
|
|
18147
|
+
"tx2",
|
|
18148
|
+
"accent1",
|
|
18149
|
+
"accent2",
|
|
18150
|
+
"accent3",
|
|
18151
|
+
"accent4",
|
|
18152
|
+
"accent5",
|
|
18153
|
+
"accent6",
|
|
18154
|
+
"hlink",
|
|
18155
|
+
"folHlink"
|
|
18156
|
+
];
|
|
18157
|
+
var DEFAULT_COLOR_MAP = {
|
|
18158
|
+
bg1: "lt1",
|
|
18159
|
+
tx1: "dk1",
|
|
18160
|
+
bg2: "lt2",
|
|
18161
|
+
tx2: "dk2",
|
|
18162
|
+
accent1: "accent1",
|
|
18163
|
+
accent2: "accent2",
|
|
18164
|
+
accent3: "accent3",
|
|
18165
|
+
accent4: "accent4",
|
|
18166
|
+
accent5: "accent5",
|
|
18167
|
+
accent6: "accent6",
|
|
18168
|
+
hlink: "hlink",
|
|
18169
|
+
folHlink: "folHlink"
|
|
18170
|
+
};
|
|
18171
|
+
function buildClrMapOverrideXml(override) {
|
|
18172
|
+
if (!override || Object.keys(override).length === 0) {
|
|
18173
|
+
return { "a:masterClrMapping": {} };
|
|
18174
|
+
}
|
|
18175
|
+
const attrs2 = {};
|
|
18176
|
+
for (const key of COLOR_MAP_ALIAS_KEYS) {
|
|
18177
|
+
attrs2[`@_${key}`] = override[key] ?? DEFAULT_COLOR_MAP[key];
|
|
18178
|
+
}
|
|
18179
|
+
return { "a:overrideClrMapping": attrs2 };
|
|
18180
|
+
}
|
|
18181
|
+
|
|
17506
18182
|
// src/core/utils/encryption-detection.ts
|
|
17507
18183
|
var OLE_MAGIC = new Uint8Array([208, 207, 17, 224, 161, 27, 26, 225]);
|
|
17508
18184
|
var ZIP_MAGIC = new Uint8Array([80, 75]);
|
|
@@ -23265,7 +23941,7 @@ function parseActiveXControlsFromSlide(slideXml2) {
|
|
|
23265
23941
|
}
|
|
23266
23942
|
|
|
23267
23943
|
// src/core/utils/theme-switching.ts
|
|
23268
|
-
function
|
|
23944
|
+
function normalizeHex2(hex) {
|
|
23269
23945
|
if (!hex) {
|
|
23270
23946
|
return "";
|
|
23271
23947
|
}
|
|
@@ -23275,8 +23951,8 @@ function buildColorRemapTable(oldColorMap, newColorMap) {
|
|
|
23275
23951
|
const remap = /* @__PURE__ */ new Map();
|
|
23276
23952
|
const allKeys = [...THEME_COLOR_SCHEME_KEYS, "tx1", "bg1", "tx2", "bg2"];
|
|
23277
23953
|
for (const key of allKeys) {
|
|
23278
|
-
const oldVal =
|
|
23279
|
-
const newVal =
|
|
23954
|
+
const oldVal = normalizeHex2(oldColorMap[key]);
|
|
23955
|
+
const newVal = normalizeHex2(newColorMap[key]);
|
|
23280
23956
|
if (oldVal && newVal && oldVal !== newVal) {
|
|
23281
23957
|
remap.set(oldVal, `#${newVal}`);
|
|
23282
23958
|
remap.set(`#${oldVal}`, `#${newVal}`);
|
|
@@ -23288,7 +23964,7 @@ function remapColor(color, remap) {
|
|
|
23288
23964
|
if (!color) {
|
|
23289
23965
|
return color;
|
|
23290
23966
|
}
|
|
23291
|
-
const normalized =
|
|
23967
|
+
const normalized = normalizeHex2(color);
|
|
23292
23968
|
const remapped = remap.get(normalized) ?? remap.get(`#${normalized}`);
|
|
23293
23969
|
return remapped ?? color;
|
|
23294
23970
|
}
|
|
@@ -23428,7 +24104,7 @@ function remapSlideColors(slide, remap) {
|
|
|
23428
24104
|
function buildThemeColorMap(colorScheme) {
|
|
23429
24105
|
const map = {};
|
|
23430
24106
|
for (const key of THEME_COLOR_SCHEME_KEYS) {
|
|
23431
|
-
map[key] =
|
|
24107
|
+
map[key] = normalizeHex2(colorScheme[key]);
|
|
23432
24108
|
}
|
|
23433
24109
|
map.tx1 = map.dk1;
|
|
23434
24110
|
map.bg1 = map.lt1;
|
|
@@ -23464,8 +24140,11 @@ function applyThemeToData(data, newColorScheme, newFontScheme, themeName) {
|
|
|
23464
24140
|
|
|
23465
24141
|
// src/core/core/runtime/PptxHandlerRuntimeSaveParagraphHelpers.ts
|
|
23466
24142
|
var EMU_PER_PX4 = 9525;
|
|
23467
|
-
function buildParagraphPropertiesXml(textStyle, paragraphAlign, bulletInfo, spacing) {
|
|
24143
|
+
function buildParagraphPropertiesXml(textStyle, paragraphAlign, bulletInfo, spacing, level) {
|
|
23468
24144
|
const paragraphProps = {};
|
|
24145
|
+
if (typeof level === "number" && Number.isFinite(level) && level > 0) {
|
|
24146
|
+
paragraphProps["@_lvl"] = String(Math.min(Math.max(Math.round(level), 0), 8));
|
|
24147
|
+
}
|
|
23469
24148
|
if (paragraphAlign) {
|
|
23470
24149
|
paragraphProps["@_algn"] = paragraphAlign;
|
|
23471
24150
|
}
|
|
@@ -23537,23 +24216,28 @@ function applyBulletProperties(paragraphProps, bulletInfo) {
|
|
|
23537
24216
|
paragraphProps["a:buNone"] = {};
|
|
23538
24217
|
return;
|
|
23539
24218
|
}
|
|
23540
|
-
if (bulletInfo.
|
|
24219
|
+
if (bulletInfo.colorInherit) {
|
|
24220
|
+
paragraphProps["a:buClrTx"] = {};
|
|
24221
|
+
} else if (bulletInfo.color) {
|
|
23541
24222
|
const colorHex = bulletInfo.color.replace("#", "");
|
|
23542
24223
|
paragraphProps["a:buClr"] = {
|
|
23543
24224
|
"a:srgbClr": { "@_val": colorHex }
|
|
23544
24225
|
};
|
|
23545
24226
|
}
|
|
23546
|
-
if (bulletInfo.
|
|
24227
|
+
if (bulletInfo.sizeInherit) {
|
|
24228
|
+
paragraphProps["a:buSzTx"] = {};
|
|
24229
|
+
} else if (bulletInfo.sizePercent !== void 0) {
|
|
23547
24230
|
paragraphProps["a:buSzPct"] = {
|
|
23548
24231
|
"@_val": String(Math.round(bulletInfo.sizePercent * 1e3))
|
|
23549
24232
|
};
|
|
23550
|
-
}
|
|
23551
|
-
if (bulletInfo.sizePts !== void 0) {
|
|
24233
|
+
} else if (bulletInfo.sizePts !== void 0) {
|
|
23552
24234
|
paragraphProps["a:buSzPts"] = {
|
|
23553
24235
|
"@_val": String(Math.round(bulletInfo.sizePts * 100))
|
|
23554
24236
|
};
|
|
23555
24237
|
}
|
|
23556
|
-
if (bulletInfo.
|
|
24238
|
+
if (bulletInfo.fontInherit) {
|
|
24239
|
+
paragraphProps["a:buFontTx"] = {};
|
|
24240
|
+
} else if (bulletInfo.fontFamily) {
|
|
23557
24241
|
paragraphProps["a:buFont"] = {
|
|
23558
24242
|
"@_typeface": bulletInfo.fontFamily
|
|
23559
24243
|
};
|
|
@@ -23576,7 +24260,7 @@ function applyBulletProperties(paragraphProps, bulletInfo) {
|
|
|
23576
24260
|
};
|
|
23577
24261
|
}
|
|
23578
24262
|
}
|
|
23579
|
-
function assembleParagraphXml(runs, paragraphProps) {
|
|
24263
|
+
function assembleParagraphXml(runs, paragraphProps, endParaRunProperties) {
|
|
23580
24264
|
const paragraph = {
|
|
23581
24265
|
"a:pPr": paragraphProps
|
|
23582
24266
|
};
|
|
@@ -23598,7 +24282,11 @@ function assembleParagraphXml(runs, paragraphProps) {
|
|
|
23598
24282
|
if (cleanRegularRuns.length === 0 && fieldRuns.length === 0) {
|
|
23599
24283
|
paragraph["a:r"] = runs.length > 1 ? runs : runs[0];
|
|
23600
24284
|
}
|
|
23601
|
-
|
|
24285
|
+
if (endParaRunProperties && typeof endParaRunProperties === "object") {
|
|
24286
|
+
paragraph["a:endParaRPr"] = endParaRunProperties;
|
|
24287
|
+
} else {
|
|
24288
|
+
paragraph["a:endParaRPr"] = { "@_lang": "en-US" };
|
|
24289
|
+
}
|
|
23602
24290
|
return paragraph;
|
|
23603
24291
|
}
|
|
23604
24292
|
function computeUniformSegmentOverrides(textStyle, textSegments) {
|
|
@@ -23902,6 +24590,140 @@ var PptxHandlerRuntime = class {
|
|
|
23902
24590
|
* `p:clrMapOvr / a:overrideClrMapping`.
|
|
23903
24591
|
*/
|
|
23904
24592
|
currentSlideClrMapOverride = null;
|
|
24593
|
+
/**
|
|
24594
|
+
* Per-master colour map alias dictionaries parsed from each master's
|
|
24595
|
+
* `<p:clrMap>` element (e.g. `bg1 → lt1`, `tx1 → dk1`, `accent1 → accent1`).
|
|
24596
|
+
*
|
|
24597
|
+
* `clrMap` is the *aliasing* layer between logical colour names used in
|
|
24598
|
+
* DrawingML and the raw theme scheme slots. Per ECMA-376 §19.3.1.7 it
|
|
24599
|
+
* lives on each `p:sldMaster`, and slide layouts/slides may further
|
|
24600
|
+
* override it via `p:clrMapOvr`. Resolution must happen at colour-lookup
|
|
24601
|
+
* time, *not* by baking it into {@link themeColorMap}.
|
|
24602
|
+
*
|
|
24603
|
+
* Phase 2 Stream B / C-H4.
|
|
24604
|
+
*/
|
|
24605
|
+
masterClrMaps = /* @__PURE__ */ new Map();
|
|
24606
|
+
/**
|
|
24607
|
+
* Per-master theme color maps. Each master may reference its own theme
|
|
24608
|
+
* file via `_rels/slideMasterN.xml.rels`. For multi-master decks, slides
|
|
24609
|
+
* must resolve scheme colours against their *own* master's theme.
|
|
24610
|
+
*
|
|
24611
|
+
* Falls back to {@link themeColorMap} when a master entry is missing.
|
|
24612
|
+
*
|
|
24613
|
+
* Phase 2 Stream B / C-H4.
|
|
24614
|
+
*/
|
|
24615
|
+
masterThemeColorMaps = /* @__PURE__ */ new Map();
|
|
24616
|
+
/**
|
|
24617
|
+
* Per-master theme font maps. Same rationale as
|
|
24618
|
+
* {@link masterThemeColorMaps}: multi-master decks may have one font
|
|
24619
|
+
* scheme per theme.
|
|
24620
|
+
*/
|
|
24621
|
+
masterThemeFontMaps = /* @__PURE__ */ new Map();
|
|
24622
|
+
/**
|
|
24623
|
+
* Per-master format schemes (fmtScheme). For multi-master decks each
|
|
24624
|
+
* master's slides should resolve fill/line/effect refs against the
|
|
24625
|
+
* matrix from that master's theme.
|
|
24626
|
+
*/
|
|
24627
|
+
masterThemeFormatSchemes = /* @__PURE__ */ new Map();
|
|
24628
|
+
/**
|
|
24629
|
+
* Per-master mapping from slide-master path to the theme path it
|
|
24630
|
+
* references via `_rels/slideMasterN.xml.rels`. Populated by
|
|
24631
|
+
* {@link loadPerMasterThemes} during load. Used by the save-side
|
|
24632
|
+
* theme writer to know which themeN.xml to (re)emit for each master.
|
|
24633
|
+
*
|
|
24634
|
+
* Phase 4 Stream A / C-H3.
|
|
24635
|
+
*/
|
|
24636
|
+
masterThemePaths = /* @__PURE__ */ new Map();
|
|
24637
|
+
/**
|
|
24638
|
+
* Per-script font tables for major and minor fonts. Captured per master
|
|
24639
|
+
* theme. Keys are master paths; values map `mj`/`mn` -> script tag (e.g.
|
|
24640
|
+
* `Hans`, `Hant`, `Arab`, `Hebr`, `Thai`, `Beng`, …) -> typeface name.
|
|
24641
|
+
*
|
|
24642
|
+
* Phase 4 Stream A / M4.
|
|
24643
|
+
*/
|
|
24644
|
+
masterThemeMajorFontScripts = /* @__PURE__ */ new Map();
|
|
24645
|
+
masterThemeMinorFontScripts = /* @__PURE__ */ new Map();
|
|
24646
|
+
/**
|
|
24647
|
+
* Theme name attribute (`<a:theme @name>`) per master theme path.
|
|
24648
|
+
* Captured for byte-stable round-trip.
|
|
24649
|
+
*/
|
|
24650
|
+
masterThemeNames = /* @__PURE__ */ new Map();
|
|
24651
|
+
/**
|
|
24652
|
+
* `<a:fontScheme @name>` per master theme path.
|
|
24653
|
+
*/
|
|
24654
|
+
masterThemeFontSchemeNames = /* @__PURE__ */ new Map();
|
|
24655
|
+
/**
|
|
24656
|
+
* `<a:clrScheme @name>` per master theme path.
|
|
24657
|
+
*/
|
|
24658
|
+
masterThemeColorSchemeNames = /* @__PURE__ */ new Map();
|
|
24659
|
+
/**
|
|
24660
|
+
* Raw original theme XML keyed by theme path. Captured at load-time.
|
|
24661
|
+
* Used by the save pipeline to passthrough the full theme XML when no
|
|
24662
|
+
* in-memory mutation has occurred — preserving fillStyleLst /
|
|
24663
|
+
* lnStyleLst / effectStyleLst / bgFillStyleLst /
|
|
24664
|
+
* extraClrSchemeLst / objectDefaults / extLst exactly as written.
|
|
24665
|
+
*
|
|
24666
|
+
* Phase 4 Stream A / C-H3.
|
|
24667
|
+
*/
|
|
24668
|
+
originalThemeXmlByPath = /* @__PURE__ */ new Map();
|
|
24669
|
+
/**
|
|
24670
|
+
* Set of theme paths whose in-memory state has been mutated since
|
|
24671
|
+
* load. Saving a theme path that's NOT dirty is a no-op (the original
|
|
24672
|
+
* file already exists in the ZIP). Saving a dirty theme path
|
|
24673
|
+
* regenerates the part from in-memory state.
|
|
24674
|
+
*
|
|
24675
|
+
* Phase 4 Stream A / C-H3.
|
|
24676
|
+
*/
|
|
24677
|
+
dirtyThemePaths = /* @__PURE__ */ new Set();
|
|
24678
|
+
/**
|
|
24679
|
+
* Per-master parsed `<p:txStyles>` (titleStyle/bodyStyle/otherStyle).
|
|
24680
|
+
* Populated by {@link enrichSlideMastersWithTxStyles} during load so the
|
|
24681
|
+
* inheritance chain can find the master text-style cascade without
|
|
24682
|
+
* re-parsing master XML on every lookup. Phase 4 Stream B / P-H1.
|
|
24683
|
+
*/
|
|
24684
|
+
masterTxStylesCache = /* @__PURE__ */ new Map();
|
|
24685
|
+
/**
|
|
24686
|
+
* Captured `<a:objectDefaults>` snapshot per master theme path. The
|
|
24687
|
+
* full ECMA-376 inheritance chain (master / layout / placeholder /
|
|
24688
|
+
* objectDefaults) is non-trivial; we store the raw spDef/lnDef/txDef
|
|
24689
|
+
* subtrees and re-emit them verbatim for round-trip.
|
|
24690
|
+
*
|
|
24691
|
+
* Phase 4 Stream A / M5.
|
|
24692
|
+
*/
|
|
24693
|
+
masterThemeObjectDefaults = /* @__PURE__ */ new Map();
|
|
24694
|
+
/**
|
|
24695
|
+
* Captured `<a:extraClrSchemeLst>` raw subtree per master theme path
|
|
24696
|
+
* for verbatim round-trip.
|
|
24697
|
+
*
|
|
24698
|
+
* Phase 4 Stream A.
|
|
24699
|
+
*/
|
|
24700
|
+
masterThemeExtraClrSchemeLst = /* @__PURE__ */ new Map();
|
|
24701
|
+
/**
|
|
24702
|
+
* Captured `<a:custClrLst>` raw subtree per master theme path
|
|
24703
|
+
* for verbatim round-trip.
|
|
24704
|
+
*
|
|
24705
|
+
* Phase 4 Stream A.
|
|
24706
|
+
*/
|
|
24707
|
+
masterThemeCustClrLst = /* @__PURE__ */ new Map();
|
|
24708
|
+
/**
|
|
24709
|
+
* Captured theme-level `<a:extLst>` raw subtree per master theme path.
|
|
24710
|
+
*/
|
|
24711
|
+
masterThemeExtLst = /* @__PURE__ */ new Map();
|
|
24712
|
+
/**
|
|
24713
|
+
* Active master's clrMap for the slide currently being parsed. Walked
|
|
24714
|
+
* after `currentSlideClrMapOverride` (slide and layout overrides take
|
|
24715
|
+
* precedence). `null` means "fall through to themeColorMap directly".
|
|
24716
|
+
*/
|
|
24717
|
+
currentMasterClrMap = null;
|
|
24718
|
+
/**
|
|
24719
|
+
* Snapshot of the global theme state taken right after
|
|
24720
|
+
* {@link loadThemeData} completes. Used as the fallback when a slide's
|
|
24721
|
+
* master has no per-master theme entry, so per-slide multi-master
|
|
24722
|
+
* switching does not leak the previous slide's master state.
|
|
24723
|
+
*/
|
|
24724
|
+
globalThemeColorMapSnapshot = {};
|
|
24725
|
+
globalThemeFontMapSnapshot = {};
|
|
24726
|
+
globalThemeFormatSchemeSnapshot;
|
|
23905
24727
|
/** Thumbnail image data from `docProps/thumbnail.jpeg` preserved for round-trip. */
|
|
23906
24728
|
thumbnailData = null;
|
|
23907
24729
|
/** Raw VBA project binary preserved for macro-enabled (.pptm) round-trip. */
|
|
@@ -23912,6 +24734,19 @@ var PptxHandlerRuntime = class {
|
|
|
23912
24734
|
signatureDetection = null;
|
|
23913
24735
|
/** Custom XML data parts parsed from `customXml/` in the OPC package. */
|
|
23914
24736
|
customXmlParts = [];
|
|
24737
|
+
/**
|
|
24738
|
+
* Maps an element's `rawXml` reference to the `mc:AlternateContent`
|
|
24739
|
+
* envelope that originally wrapped it (CC-4). Populated during slide
|
|
24740
|
+
* (and `p:grpSp`) parsing; consulted at save time to re-emit the
|
|
24741
|
+
* original `<mc:Choice>` / `<mc:Fallback>` shape so legacy renderers
|
|
24742
|
+
* keep their fallback content.
|
|
24743
|
+
*
|
|
24744
|
+
* Multiple sibling elements may share the same `AlternateContentBlock`
|
|
24745
|
+
* value (a single AC envelope often wraps several child shapes — e.g.
|
|
24746
|
+
* `p14:media` + its `p:pic` fallback nest one each). WeakMap so AC
|
|
24747
|
+
* envelopes are GC'd if the parsed XmlObject is dropped.
|
|
24748
|
+
*/
|
|
24749
|
+
alternateContentBlockByRawXml = /* @__PURE__ */ new WeakMap();
|
|
23915
24750
|
/** Embedded fonts extracted during load, preserved for automatic re-embedding on save. */
|
|
23916
24751
|
loadedEmbeddedFonts = [];
|
|
23917
24752
|
/** Map of comment author IDs to display names (from `ppt/commentAuthors.xml`). */
|
|
@@ -25725,7 +26560,12 @@ var PptxHandlerRuntime9 = class extends PptxHandlerRuntime8 {
|
|
|
25725
26560
|
const bgColor = this.parseBackgroundColor(bg);
|
|
25726
26561
|
const spTree = master["p:cSld"]?.["p:spTree"];
|
|
25727
26562
|
const placeholders = this.extractPlaceholderList(spTree);
|
|
25728
|
-
|
|
26563
|
+
const result = { path: path2, backgroundColor: bgColor, placeholders };
|
|
26564
|
+
const hf = parseHeaderFooterFlags(master["p:hf"]);
|
|
26565
|
+
if (hf) {
|
|
26566
|
+
result.headerFooter = hf;
|
|
26567
|
+
}
|
|
26568
|
+
return result;
|
|
25729
26569
|
} catch (e) {
|
|
25730
26570
|
console.warn("Failed to parse handout master:", e);
|
|
25731
26571
|
return void 0;
|
|
@@ -25751,7 +26591,12 @@ var PptxHandlerRuntime9 = class extends PptxHandlerRuntime8 {
|
|
|
25751
26591
|
const bgColor = this.parseBackgroundColor(bg);
|
|
25752
26592
|
const spTree = master["p:cSld"]?.["p:spTree"];
|
|
25753
26593
|
const placeholders = this.extractPlaceholderList(spTree);
|
|
25754
|
-
|
|
26594
|
+
const result = { path: path2, backgroundColor: bgColor, placeholders };
|
|
26595
|
+
const hf = parseHeaderFooterFlags(master["p:hf"]);
|
|
26596
|
+
if (hf) {
|
|
26597
|
+
result.headerFooter = hf;
|
|
26598
|
+
}
|
|
26599
|
+
return result;
|
|
25755
26600
|
} catch (e) {
|
|
25756
26601
|
console.warn("Failed to parse notes master:", e);
|
|
25757
26602
|
return void 0;
|
|
@@ -25796,6 +26641,10 @@ var PptxHandlerRuntime9 = class extends PptxHandlerRuntime8 {
|
|
|
25796
26641
|
const uVal = String(userDrawn).trim().toLowerCase();
|
|
25797
26642
|
layout.userDrawn = uVal === "1" || uVal === "true";
|
|
25798
26643
|
}
|
|
26644
|
+
const hf = parseHeaderFooterFlags(sldLayout["p:hf"]);
|
|
26645
|
+
if (hf) {
|
|
26646
|
+
layout.headerFooter = hf;
|
|
26647
|
+
}
|
|
25799
26648
|
const clrMapOvr = sldLayout["p:clrMapOvr"];
|
|
25800
26649
|
if (clrMapOvr && clrMapOvr["a:masterClrMapping"] === void 0) {
|
|
25801
26650
|
const overrideNode = clrMapOvr["a:overrideClrMapping"];
|
|
@@ -26401,6 +27250,18 @@ function buildClrChangeNode(style) {
|
|
|
26401
27250
|
}
|
|
26402
27251
|
|
|
26403
27252
|
// src/core/core/runtime/PptxHandlerRuntimeSaveRunProperties.ts
|
|
27253
|
+
function applyFontMetadata(fontNode, panose, pitchFamily, charset) {
|
|
27254
|
+
if (panose && panose.length > 0) {
|
|
27255
|
+
fontNode["@_panose"] = panose;
|
|
27256
|
+
}
|
|
27257
|
+
if (typeof pitchFamily === "number" && Number.isFinite(pitchFamily)) {
|
|
27258
|
+
fontNode["@_pitchFamily"] = String(pitchFamily);
|
|
27259
|
+
}
|
|
27260
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
27261
|
+
fontNode["@_charset"] = String(charset);
|
|
27262
|
+
}
|
|
27263
|
+
return fontNode;
|
|
27264
|
+
}
|
|
26404
27265
|
var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime11 {
|
|
26405
27266
|
createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId) {
|
|
26406
27267
|
const runProps = {
|
|
@@ -26458,6 +27319,12 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
26458
27319
|
if (style.bookmark) {
|
|
26459
27320
|
runProps["@_bmk"] = style.bookmark;
|
|
26460
27321
|
}
|
|
27322
|
+
if (style.altLanguage) {
|
|
27323
|
+
runProps["@_altLang"] = style.altLanguage;
|
|
27324
|
+
}
|
|
27325
|
+
if (typeof style.smartTagId === "number" && Number.isFinite(style.smartTagId)) {
|
|
27326
|
+
runProps["@_smtId"] = String(style.smartTagId);
|
|
27327
|
+
}
|
|
26461
27328
|
if (style.textOutlineWidth || style.textOutlineColor) {
|
|
26462
27329
|
const lnObj = {};
|
|
26463
27330
|
if (typeof style.textOutlineWidth === "number" && style.textOutlineWidth > 0) {
|
|
@@ -26473,11 +27340,12 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
26473
27340
|
runProps["a:ln"] = lnObj;
|
|
26474
27341
|
}
|
|
26475
27342
|
if (style.color) {
|
|
26476
|
-
|
|
26477
|
-
|
|
26478
|
-
|
|
26479
|
-
|
|
26480
|
-
|
|
27343
|
+
const resolvedOriginalColor = style.colorXml ? this.parseColor(style.colorXml) : void 0;
|
|
27344
|
+
runProps["a:solidFill"] = serializeColorChoice(
|
|
27345
|
+
style.colorXml,
|
|
27346
|
+
resolvedOriginalColor,
|
|
27347
|
+
style.color
|
|
27348
|
+
);
|
|
26481
27349
|
} else if (style.textFillGradientStops && style.textFillGradientStops.length > 0) {
|
|
26482
27350
|
const gradStops = style.textFillGradientStops.filter((stop) => Boolean(stop?.color)).map((stop) => {
|
|
26483
27351
|
const rawPos = (stop.position ?? 0) / 100;
|
|
@@ -26550,16 +27418,32 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
26550
27418
|
};
|
|
26551
27419
|
}
|
|
26552
27420
|
if (style.fontFamily) {
|
|
26553
|
-
runProps["a:latin"] =
|
|
26554
|
-
|
|
26555
|
-
|
|
26556
|
-
|
|
26557
|
-
|
|
26558
|
-
|
|
26559
|
-
|
|
27421
|
+
runProps["a:latin"] = applyFontMetadata(
|
|
27422
|
+
{ "@_typeface": style.fontFamily },
|
|
27423
|
+
style.latinFontPanose,
|
|
27424
|
+
style.latinFontPitchFamily,
|
|
27425
|
+
style.latinFontCharset
|
|
27426
|
+
);
|
|
27427
|
+
runProps["a:ea"] = applyFontMetadata(
|
|
27428
|
+
{ "@_typeface": style.eastAsiaFont || style.fontFamily },
|
|
27429
|
+
style.eastAsiaFontPanose,
|
|
27430
|
+
style.eastAsiaFontPitchFamily,
|
|
27431
|
+
style.eastAsiaFontCharset
|
|
27432
|
+
);
|
|
27433
|
+
runProps["a:cs"] = applyFontMetadata(
|
|
27434
|
+
{ "@_typeface": style.complexScriptFont || style.fontFamily },
|
|
27435
|
+
style.complexScriptFontPanose,
|
|
27436
|
+
style.complexScriptFontPitchFamily,
|
|
27437
|
+
style.complexScriptFontCharset
|
|
27438
|
+
);
|
|
26560
27439
|
}
|
|
26561
27440
|
if (style.symbolFont) {
|
|
26562
|
-
runProps["a:sym"] =
|
|
27441
|
+
runProps["a:sym"] = applyFontMetadata(
|
|
27442
|
+
{ "@_typeface": style.symbolFont },
|
|
27443
|
+
style.symbolFontPanose,
|
|
27444
|
+
style.symbolFontPitchFamily,
|
|
27445
|
+
style.symbolFontCharset
|
|
27446
|
+
);
|
|
26563
27447
|
}
|
|
26564
27448
|
if (style.hyperlink && resolveHyperlinkRelationshipId) {
|
|
26565
27449
|
const hyperlinkTarget = String(style.hyperlink).trim();
|
|
@@ -26634,14 +27518,15 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
|
|
|
26634
27518
|
lineSpacing: this.createLineSpacingXmlFromMultiplier(textStyle?.lineSpacing),
|
|
26635
27519
|
lineSpacingExactPt: textStyle?.lineSpacingExactPt
|
|
26636
27520
|
};
|
|
26637
|
-
const createParagraph = (runs, bulletInfo) => {
|
|
27521
|
+
const createParagraph = (runs, bulletInfo, level, endParaRunProperties) => {
|
|
26638
27522
|
const paragraphProps = buildParagraphPropertiesXml(
|
|
26639
27523
|
textStyle,
|
|
26640
27524
|
paragraphAlign,
|
|
26641
27525
|
bulletInfo,
|
|
26642
|
-
spacing
|
|
27526
|
+
spacing,
|
|
27527
|
+
level
|
|
26643
27528
|
);
|
|
26644
|
-
return assembleParagraphXml(runs, paragraphProps);
|
|
27529
|
+
return assembleParagraphXml(runs, paragraphProps, endParaRunProperties);
|
|
26645
27530
|
};
|
|
26646
27531
|
const createRun = (runText, style) => ({
|
|
26647
27532
|
"a:rPr": this.createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId),
|
|
@@ -26689,13 +27574,19 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
|
|
|
26689
27574
|
const paragraphs = [];
|
|
26690
27575
|
let currentRuns = [];
|
|
26691
27576
|
let currentBulletInfo;
|
|
27577
|
+
let currentLevel;
|
|
27578
|
+
let currentEndParaRunProperties;
|
|
26692
27579
|
const pushParagraph = () => {
|
|
26693
27580
|
if (currentRuns.length === 0) {
|
|
26694
27581
|
currentRuns.push(createRun("", textStyle));
|
|
26695
27582
|
}
|
|
26696
|
-
paragraphs.push(
|
|
27583
|
+
paragraphs.push(
|
|
27584
|
+
createParagraph(currentRuns, currentBulletInfo, currentLevel, currentEndParaRunProperties)
|
|
27585
|
+
);
|
|
26697
27586
|
currentRuns = [];
|
|
26698
27587
|
currentBulletInfo = void 0;
|
|
27588
|
+
currentLevel = void 0;
|
|
27589
|
+
currentEndParaRunProperties = void 0;
|
|
26699
27590
|
};
|
|
26700
27591
|
if (textSegments && textSegments.length > 0) {
|
|
26701
27592
|
const uniformSegmentOverrides = computeUniformSegmentOverrides(textStyle, textSegments);
|
|
@@ -26707,8 +27598,16 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
|
|
|
26707
27598
|
};
|
|
26708
27599
|
const segmentText = String(segment.text ?? "");
|
|
26709
27600
|
const lineParts = segmentText.split("\n");
|
|
26710
|
-
if (currentRuns.length === 0
|
|
26711
|
-
|
|
27601
|
+
if (currentRuns.length === 0) {
|
|
27602
|
+
if (segment.bulletInfo) {
|
|
27603
|
+
currentBulletInfo = segment.bulletInfo;
|
|
27604
|
+
}
|
|
27605
|
+
if (segment.paragraphLevel !== void 0) {
|
|
27606
|
+
currentLevel = segment.paragraphLevel;
|
|
27607
|
+
}
|
|
27608
|
+
if (segment.endParaRunProperties) {
|
|
27609
|
+
currentEndParaRunProperties = segment.endParaRunProperties;
|
|
27610
|
+
}
|
|
26712
27611
|
}
|
|
26713
27612
|
lineParts.forEach((linePart, lineIndex) => {
|
|
26714
27613
|
if (segment.rubyText !== void 0) {
|
|
@@ -26806,7 +27705,201 @@ var PptxHandlerRuntime14 = class extends PptxHandlerRuntime13 {
|
|
|
26806
27705
|
};
|
|
26807
27706
|
|
|
26808
27707
|
// src/core/core/runtime/PptxHandlerRuntimeSaveShapeXml.ts
|
|
27708
|
+
var OLE_OBJECT_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject";
|
|
27709
|
+
var IMAGE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
|
|
27710
|
+
var OLE_GRAPHIC_DATA_URI = "http://schemas.openxmlformats.org/presentationml/2006/ole";
|
|
26809
27711
|
var PptxHandlerRuntime15 = class _PptxHandlerRuntime extends PptxHandlerRuntime14 {
|
|
27712
|
+
/**
|
|
27713
|
+
* Build a `p:graphicFrame` XML skeleton for an SDK-created table.
|
|
27714
|
+
*
|
|
27715
|
+
* Tables round-trip as `<p:graphicFrame>/<a:graphic>/<a:graphicData
|
|
27716
|
+
* uri=".../drawingml/2006/table">/<a:tbl>` inside `p:spTree`. When the
|
|
27717
|
+
* element was loaded from an existing file, `el.rawXml` already contains
|
|
27718
|
+
* this envelope and the downstream `serializeTableDataToXml` path
|
|
27719
|
+
* populates cells in place. When the element was created via the SDK
|
|
27720
|
+
* (`SlideBuilder.addTable`), there is no `rawXml`, so this method
|
|
27721
|
+
* fabricates a minimal envelope with an empty `a:tbl`. The element
|
|
27722
|
+
* writer then calls `serializeTableDataToXml`, which triggers
|
|
27723
|
+
* `rebuildTableXmlFromData` and fills in `a:tblGrid` / `a:tr` children.
|
|
27724
|
+
*/
|
|
27725
|
+
createTableGraphicFrameXml(el) {
|
|
27726
|
+
const EMU = _PptxHandlerRuntime.EMU_PER_PX;
|
|
27727
|
+
const offX = String(Math.round(el.x * EMU));
|
|
27728
|
+
const offY = String(Math.round(el.y * EMU));
|
|
27729
|
+
const extCx = String(Math.round(Math.max(el.width, 1) * EMU));
|
|
27730
|
+
const extCy = String(Math.round(Math.max(el.height, 1) * EMU));
|
|
27731
|
+
const tblPr = {
|
|
27732
|
+
"@_firstRow": el.tableData?.firstRowHeader ? "1" : "0",
|
|
27733
|
+
"@_bandRow": el.tableData?.bandedRows ? "1" : "0"
|
|
27734
|
+
};
|
|
27735
|
+
if (el.tableData?.tableStyleId) {
|
|
27736
|
+
tblPr["a:tableStyleId"] = el.tableData.tableStyleId;
|
|
27737
|
+
}
|
|
27738
|
+
return {
|
|
27739
|
+
"p:nvGraphicFramePr": {
|
|
27740
|
+
"p:cNvPr": { "@_id": "0", "@_name": el.name || "Table" },
|
|
27741
|
+
"p:cNvGraphicFramePr": {
|
|
27742
|
+
"a:graphicFrameLocks": { "@_noGrp": "1" }
|
|
27743
|
+
},
|
|
27744
|
+
"p:nvPr": {}
|
|
27745
|
+
},
|
|
27746
|
+
"p:xfrm": {
|
|
27747
|
+
"a:off": { "@_x": offX, "@_y": offY },
|
|
27748
|
+
"a:ext": { "@_cx": extCx, "@_cy": extCy }
|
|
27749
|
+
},
|
|
27750
|
+
"a:graphic": {
|
|
27751
|
+
"a:graphicData": {
|
|
27752
|
+
"@_uri": "http://schemas.openxmlformats.org/drawingml/2006/table",
|
|
27753
|
+
"a:tbl": {
|
|
27754
|
+
"a:tblPr": tblPr,
|
|
27755
|
+
"a:tblGrid": {}
|
|
27756
|
+
}
|
|
27757
|
+
}
|
|
27758
|
+
}
|
|
27759
|
+
};
|
|
27760
|
+
}
|
|
27761
|
+
/**
|
|
27762
|
+
* Build a `p:graphicFrame` XML skeleton for an OLE object element.
|
|
27763
|
+
*
|
|
27764
|
+
* Used both for SDK-created OLE elements (no `rawXml`) and to refresh
|
|
27765
|
+
* a few key attributes on a loaded element when the typed fields have
|
|
27766
|
+
* been mutated. The output is the canonical
|
|
27767
|
+
* `p:graphicFrame > a:graphic > a:graphicData uri="…/ole" > p:oleObj`
|
|
27768
|
+
* shape per ECMA-376 §19.3.1.34 / §13.3.4.
|
|
27769
|
+
*
|
|
27770
|
+
* The caller (`processSlideElement`) is responsible for ensuring the
|
|
27771
|
+
* embed / preview-image relationships referenced from `r:id` / `r:embed`
|
|
27772
|
+
* exist in the slide's rels file. This method does not register them
|
|
27773
|
+
* itself because the typed model does not currently carry the binary
|
|
27774
|
+
* payload — the binary part must already be in the package (loaded from
|
|
27775
|
+
* the original file). A fully-fabricated SDK OLE element therefore
|
|
27776
|
+
* still requires the consumer to attach the binary out-of-band; this
|
|
27777
|
+
* method simply emits a schema-valid envelope referencing the
|
|
27778
|
+
* specified relationship ID.
|
|
27779
|
+
*/
|
|
27780
|
+
createOleGraphicFrameXml(el, embedRelationshipId) {
|
|
27781
|
+
const EMU = _PptxHandlerRuntime.EMU_PER_PX;
|
|
27782
|
+
const offX = String(Math.round(el.x * EMU));
|
|
27783
|
+
const offY = String(Math.round(el.y * EMU));
|
|
27784
|
+
const extCx = String(Math.round(Math.max(el.width, 1) * EMU));
|
|
27785
|
+
const extCy = String(Math.round(Math.max(el.height, 1) * EMU));
|
|
27786
|
+
const oleObj = {
|
|
27787
|
+
"@_showAsIcon": "0",
|
|
27788
|
+
"@_imgW": extCx,
|
|
27789
|
+
"@_imgH": extCy
|
|
27790
|
+
};
|
|
27791
|
+
if (el.oleProgId) {
|
|
27792
|
+
oleObj["@_progId"] = el.oleProgId;
|
|
27793
|
+
}
|
|
27794
|
+
if (el.oleName) {
|
|
27795
|
+
oleObj["@_name"] = el.oleName;
|
|
27796
|
+
}
|
|
27797
|
+
if (el.oleClsId) {
|
|
27798
|
+
oleObj["@_classid"] = el.oleClsId;
|
|
27799
|
+
}
|
|
27800
|
+
if (embedRelationshipId) {
|
|
27801
|
+
oleObj["@_r:id"] = embedRelationshipId;
|
|
27802
|
+
}
|
|
27803
|
+
if (el.isLinked) {
|
|
27804
|
+
oleObj["p:link"] = {
|
|
27805
|
+
"@_r:id": embedRelationshipId,
|
|
27806
|
+
"@_updateAutomatic": "1"
|
|
27807
|
+
};
|
|
27808
|
+
} else {
|
|
27809
|
+
oleObj["p:embed"] = {};
|
|
27810
|
+
}
|
|
27811
|
+
oleObj["p:pic"] = {
|
|
27812
|
+
"p:nvPicPr": {
|
|
27813
|
+
"p:cNvPr": { "@_id": "0", "@_name": el.oleName || "OleObject" },
|
|
27814
|
+
"p:cNvPicPr": {},
|
|
27815
|
+
"p:nvPr": {}
|
|
27816
|
+
},
|
|
27817
|
+
"p:blipFill": {
|
|
27818
|
+
"a:blip": {},
|
|
27819
|
+
"a:stretch": { "a:fillRect": {} }
|
|
27820
|
+
},
|
|
27821
|
+
"p:spPr": {
|
|
27822
|
+
"a:xfrm": {
|
|
27823
|
+
"a:off": { "@_x": offX, "@_y": offY },
|
|
27824
|
+
"a:ext": { "@_cx": extCx, "@_cy": extCy }
|
|
27825
|
+
},
|
|
27826
|
+
"a:prstGeom": { "@_prst": "rect", "a:avLst": {} }
|
|
27827
|
+
}
|
|
27828
|
+
};
|
|
27829
|
+
return {
|
|
27830
|
+
"p:nvGraphicFramePr": {
|
|
27831
|
+
"p:cNvPr": { "@_id": "0", "@_name": el.oleName || el.fileName || "OleObject" },
|
|
27832
|
+
"p:cNvGraphicFramePr": {
|
|
27833
|
+
"a:graphicFrameLocks": { "@_noChangeAspect": "1" }
|
|
27834
|
+
},
|
|
27835
|
+
"p:nvPr": {}
|
|
27836
|
+
},
|
|
27837
|
+
"p:xfrm": {
|
|
27838
|
+
"a:off": { "@_x": offX, "@_y": offY },
|
|
27839
|
+
"a:ext": { "@_cx": extCx, "@_cy": extCy }
|
|
27840
|
+
},
|
|
27841
|
+
"a:graphic": {
|
|
27842
|
+
"a:graphicData": {
|
|
27843
|
+
"@_uri": OLE_GRAPHIC_DATA_URI,
|
|
27844
|
+
"p:oleObj": oleObj
|
|
27845
|
+
}
|
|
27846
|
+
}
|
|
27847
|
+
};
|
|
27848
|
+
}
|
|
27849
|
+
/**
|
|
27850
|
+
* Refresh editable typed-field attributes on a loaded OLE graphicFrame's
|
|
27851
|
+
* raw XML. Only attributes that round-trip through the typed model
|
|
27852
|
+
* (`progId`, `name`, `classid`) are touched so unknown extension data
|
|
27853
|
+
* passes through verbatim.
|
|
27854
|
+
*/
|
|
27855
|
+
applyOleTypedFieldUpdates(shape, el) {
|
|
27856
|
+
const oleObj = shape["a:graphic"]?.["a:graphicData"]?.["p:oleObj"];
|
|
27857
|
+
if (!oleObj) {
|
|
27858
|
+
return;
|
|
27859
|
+
}
|
|
27860
|
+
if (el.oleProgId) {
|
|
27861
|
+
oleObj["@_progId"] = el.oleProgId;
|
|
27862
|
+
}
|
|
27863
|
+
if (el.oleName !== void 0) {
|
|
27864
|
+
if (el.oleName.length > 0) {
|
|
27865
|
+
oleObj["@_name"] = el.oleName;
|
|
27866
|
+
} else {
|
|
27867
|
+
delete oleObj["@_name"];
|
|
27868
|
+
}
|
|
27869
|
+
}
|
|
27870
|
+
if (el.oleClsId) {
|
|
27871
|
+
oleObj["@_classid"] = el.oleClsId;
|
|
27872
|
+
}
|
|
27873
|
+
}
|
|
27874
|
+
/** Look up the existing OLE binary relationship ID for this slide, if any. */
|
|
27875
|
+
resolveOleEmbedRelationshipId(slideRelationships, oleTarget) {
|
|
27876
|
+
if (!oleTarget) {
|
|
27877
|
+
return void 0;
|
|
27878
|
+
}
|
|
27879
|
+
const normalisedTarget = oleTarget.replace(/^ppt\//, "../").replace(/^\/+/, "");
|
|
27880
|
+
const lowerTarget = normalisedTarget.toLowerCase();
|
|
27881
|
+
for (const rel of slideRelationships) {
|
|
27882
|
+
const relType = String(rel?.["@_Type"] || "");
|
|
27883
|
+
if (relType !== OLE_OBJECT_RELATIONSHIP_TYPE) {
|
|
27884
|
+
continue;
|
|
27885
|
+
}
|
|
27886
|
+
const target = String(rel?.["@_Target"] || "").toLowerCase().trim();
|
|
27887
|
+
if (target === lowerTarget || target.endsWith(lowerTarget) || lowerTarget.endsWith(target)) {
|
|
27888
|
+
const relId = String(rel?.["@_Id"] || "").trim();
|
|
27889
|
+
if (relId.length > 0) {
|
|
27890
|
+
return relId;
|
|
27891
|
+
}
|
|
27892
|
+
}
|
|
27893
|
+
}
|
|
27894
|
+
const fallback = slideRelationships.find(
|
|
27895
|
+
(rel) => String(rel?.["@_Type"] || "") === OLE_OBJECT_RELATIONSHIP_TYPE
|
|
27896
|
+
);
|
|
27897
|
+
const fallbackId = String(fallback?.["@_Id"] || "").trim();
|
|
27898
|
+
return fallbackId.length > 0 ? fallbackId : void 0;
|
|
27899
|
+
}
|
|
27900
|
+
/** Constants are exposed so the element-writer mixin can reuse them. */
|
|
27901
|
+
static OLE_OBJECT_RELATIONSHIP_TYPE = OLE_OBJECT_RELATIONSHIP_TYPE;
|
|
27902
|
+
static OLE_IMAGE_RELATIONSHIP_TYPE = IMAGE_RELATIONSHIP_TYPE;
|
|
26810
27903
|
/**
|
|
26811
27904
|
* Build a p:sp XML object for an ink annotation element.
|
|
26812
27905
|
* Each ink path becomes a separate a:path within a:pathLst,
|
|
@@ -27123,6 +28216,9 @@ var PptxHandlerRuntime16 = class extends PptxHandlerRuntime15 {
|
|
|
27123
28216
|
buildOuterShadowXml(shapeStyle) {
|
|
27124
28217
|
return this.colorStyleCodec.buildOuterShadowXml(shapeStyle);
|
|
27125
28218
|
}
|
|
28219
|
+
buildPresetShadowXml(shapeStyle) {
|
|
28220
|
+
return this.colorStyleCodec.buildPresetShadowXml(shapeStyle);
|
|
28221
|
+
}
|
|
27126
28222
|
buildInnerShadowXml(shapeStyle) {
|
|
27127
28223
|
return this.colorStyleCodec.buildInnerShadowXml(shapeStyle);
|
|
27128
28224
|
}
|
|
@@ -27673,6 +28769,10 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
27673
28769
|
const solidFill = runProperties["a:solidFill"];
|
|
27674
28770
|
if (solidFill) {
|
|
27675
28771
|
style.color = this.parseColor(solidFill);
|
|
28772
|
+
const colorXml = extractColorChoiceXml(solidFill);
|
|
28773
|
+
if (colorXml) {
|
|
28774
|
+
style.colorXml = colorXml;
|
|
28775
|
+
}
|
|
27676
28776
|
}
|
|
27677
28777
|
this.applyHyperlinkStyle(style, runProperties, relationshipMap);
|
|
27678
28778
|
const capAttr = String(runProperties["@_cap"] || "").trim().toLowerCase();
|
|
@@ -27720,12 +28820,86 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
27720
28820
|
if (bmk) {
|
|
27721
28821
|
style.bookmark = bmk;
|
|
27722
28822
|
}
|
|
28823
|
+
const altLang = String(runProperties["@_altLang"] || "").trim();
|
|
28824
|
+
if (altLang) {
|
|
28825
|
+
style.altLanguage = altLang;
|
|
28826
|
+
}
|
|
28827
|
+
if (runProperties["@_smtId"] !== void 0) {
|
|
28828
|
+
const smtIdRaw = Number.parseInt(String(runProperties["@_smtId"]), 10);
|
|
28829
|
+
if (Number.isFinite(smtIdRaw)) {
|
|
28830
|
+
style.smartTagId = smtIdRaw;
|
|
28831
|
+
}
|
|
28832
|
+
}
|
|
28833
|
+
this.applyTextFontMetadata(style, latin, "latin");
|
|
28834
|
+
this.applyTextFontMetadata(style, eastAsian, "eastAsia");
|
|
28835
|
+
this.applyTextFontMetadata(style, complexScript, "complexScript");
|
|
28836
|
+
this.applyTextFontMetadata(style, runProperties["a:sym"], "symbol");
|
|
27723
28837
|
const runEffectList = runProperties["a:effectLst"];
|
|
27724
28838
|
if (runEffectList) {
|
|
27725
28839
|
this.applyTextRunEffects(style, runEffectList);
|
|
27726
28840
|
}
|
|
27727
28841
|
return style;
|
|
27728
28842
|
}
|
|
28843
|
+
/**
|
|
28844
|
+
* Copy `@panose` / `@pitchFamily` / `@charset` from a font child node
|
|
28845
|
+
* (`a:latin`, `a:ea`, `a:cs`, `a:sym`) onto the matching `*Font*`
|
|
28846
|
+
* fields of `style`.
|
|
28847
|
+
*/
|
|
28848
|
+
applyTextFontMetadata(style, fontNode, kind) {
|
|
28849
|
+
if (!fontNode) {
|
|
28850
|
+
return;
|
|
28851
|
+
}
|
|
28852
|
+
const panose = String(fontNode["@_panose"] || "").trim();
|
|
28853
|
+
const pitchRaw = fontNode["@_pitchFamily"];
|
|
28854
|
+
const charsetRaw = fontNode["@_charset"];
|
|
28855
|
+
const pitch = pitchRaw !== void 0 && pitchRaw !== null ? Number.parseInt(String(pitchRaw), 10) : void 0;
|
|
28856
|
+
const charset = charsetRaw !== void 0 && charsetRaw !== null ? Number.parseInt(String(charsetRaw), 10) : void 0;
|
|
28857
|
+
if (kind === "latin") {
|
|
28858
|
+
if (panose) {
|
|
28859
|
+
style.latinFontPanose = panose;
|
|
28860
|
+
}
|
|
28861
|
+
if (typeof pitch === "number" && Number.isFinite(pitch)) {
|
|
28862
|
+
style.latinFontPitchFamily = pitch;
|
|
28863
|
+
}
|
|
28864
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
28865
|
+
style.latinFontCharset = charset;
|
|
28866
|
+
}
|
|
28867
|
+
return;
|
|
28868
|
+
}
|
|
28869
|
+
if (kind === "eastAsia") {
|
|
28870
|
+
if (panose) {
|
|
28871
|
+
style.eastAsiaFontPanose = panose;
|
|
28872
|
+
}
|
|
28873
|
+
if (typeof pitch === "number" && Number.isFinite(pitch)) {
|
|
28874
|
+
style.eastAsiaFontPitchFamily = pitch;
|
|
28875
|
+
}
|
|
28876
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
28877
|
+
style.eastAsiaFontCharset = charset;
|
|
28878
|
+
}
|
|
28879
|
+
return;
|
|
28880
|
+
}
|
|
28881
|
+
if (kind === "complexScript") {
|
|
28882
|
+
if (panose) {
|
|
28883
|
+
style.complexScriptFontPanose = panose;
|
|
28884
|
+
}
|
|
28885
|
+
if (typeof pitch === "number" && Number.isFinite(pitch)) {
|
|
28886
|
+
style.complexScriptFontPitchFamily = pitch;
|
|
28887
|
+
}
|
|
28888
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
28889
|
+
style.complexScriptFontCharset = charset;
|
|
28890
|
+
}
|
|
28891
|
+
return;
|
|
28892
|
+
}
|
|
28893
|
+
if (panose) {
|
|
28894
|
+
style.symbolFontPanose = panose;
|
|
28895
|
+
}
|
|
28896
|
+
if (typeof pitch === "number" && Number.isFinite(pitch)) {
|
|
28897
|
+
style.symbolFontPitchFamily = pitch;
|
|
28898
|
+
}
|
|
28899
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
28900
|
+
style.symbolFontCharset = charset;
|
|
28901
|
+
}
|
|
28902
|
+
}
|
|
27729
28903
|
};
|
|
27730
28904
|
|
|
27731
28905
|
// src/core/core/runtime/PptxHandlerRuntimeTextEditing.ts
|
|
@@ -28161,7 +29335,7 @@ var PptxHandlerRuntime21 = class extends PptxHandlerRuntime20 {
|
|
|
28161
29335
|
};
|
|
28162
29336
|
|
|
28163
29337
|
// src/core/core/runtime/table-cell-save-helpers.ts
|
|
28164
|
-
function writeCellFill(tcPr, style) {
|
|
29338
|
+
function writeCellFill(tcPr, style, resolveColorXml) {
|
|
28165
29339
|
if (style.fillMode === "gradient" && style.gradientFillStops && style.gradientFillStops.length > 0) {
|
|
28166
29340
|
delete tcPr["a:solidFill"];
|
|
28167
29341
|
delete tcPr["a:pattFill"];
|
|
@@ -28240,11 +29414,12 @@ function writeCellFill(tcPr, style) {
|
|
|
28240
29414
|
} else if (style.backgroundColor) {
|
|
28241
29415
|
delete tcPr["a:gradFill"];
|
|
28242
29416
|
delete tcPr["a:pattFill"];
|
|
28243
|
-
|
|
28244
|
-
|
|
28245
|
-
|
|
28246
|
-
|
|
28247
|
-
|
|
29417
|
+
const resolvedOriginal = style.backgroundColorXml && resolveColorXml ? resolveColorXml(style.backgroundColorXml) : void 0;
|
|
29418
|
+
tcPr["a:solidFill"] = serializeColorChoice(
|
|
29419
|
+
style.backgroundColorXml,
|
|
29420
|
+
resolvedOriginal,
|
|
29421
|
+
style.backgroundColor
|
|
29422
|
+
);
|
|
28248
29423
|
}
|
|
28249
29424
|
}
|
|
28250
29425
|
function writeDiagonalBorders(tcPr, style, emuPerPx) {
|
|
@@ -28288,14 +29463,15 @@ function writeCellTextFormatting(xmlCell, style, ensureArray6) {
|
|
|
28288
29463
|
const paragraphs = ensureArray6(xmlCell["a:txBody"]?.["a:p"]);
|
|
28289
29464
|
for (const paragraph of paragraphs) {
|
|
28290
29465
|
const runs = ensureArray6(paragraph?.["a:r"]);
|
|
29466
|
+
const rebuiltRuns = [];
|
|
29467
|
+
let runsChanged = false;
|
|
28291
29468
|
for (const run of runs) {
|
|
28292
29469
|
if (!run) {
|
|
29470
|
+
rebuiltRuns.push(run);
|
|
28293
29471
|
continue;
|
|
28294
29472
|
}
|
|
28295
|
-
|
|
28296
|
-
|
|
28297
|
-
}
|
|
28298
|
-
const rPr = run["a:rPr"];
|
|
29473
|
+
const existingRPr = run["a:rPr"] ?? {};
|
|
29474
|
+
const rPr = { ...existingRPr };
|
|
28299
29475
|
if (style.bold !== void 0) {
|
|
28300
29476
|
rPr["@_b"] = style.bold ? "1" : "0";
|
|
28301
29477
|
}
|
|
@@ -28315,6 +29491,18 @@ function writeCellTextFormatting(xmlCell, style, ensureArray6) {
|
|
|
28315
29491
|
}
|
|
28316
29492
|
};
|
|
28317
29493
|
}
|
|
29494
|
+
const rebuilt = { "a:rPr": rPr };
|
|
29495
|
+
for (const key of Object.keys(run)) {
|
|
29496
|
+
if (key === "a:rPr") {
|
|
29497
|
+
continue;
|
|
29498
|
+
}
|
|
29499
|
+
rebuilt[key] = run[key];
|
|
29500
|
+
}
|
|
29501
|
+
rebuiltRuns.push(rebuilt);
|
|
29502
|
+
runsChanged = true;
|
|
29503
|
+
}
|
|
29504
|
+
if (runsChanged && rebuiltRuns.length > 0) {
|
|
29505
|
+
paragraph["a:r"] = rebuiltRuns.length === 1 ? rebuiltRuns[0] : rebuiltRuns;
|
|
28318
29506
|
}
|
|
28319
29507
|
}
|
|
28320
29508
|
}
|
|
@@ -28336,6 +29524,9 @@ var PptxHandlerRuntime22 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
28336
29524
|
const existingParagraphs = this.ensureArray(txBody["a:p"]);
|
|
28337
29525
|
const firstRPr = this.ensureArray(existingParagraphs[0]?.["a:r"])[0]?.["a:rPr"];
|
|
28338
29526
|
const firstPPr = existingParagraphs[0]?.["a:pPr"];
|
|
29527
|
+
const firstEndParaRPr = existingParagraphs[0]?.["a:endParaRPr"];
|
|
29528
|
+
const rPrForRun = firstRPr ? { ...firstRPr } : { "@_lang": "en-US", "@_dirty": "0" };
|
|
29529
|
+
const endParaRPr = firstEndParaRPr ? { ...firstEndParaRPr } : { "@_lang": "en-US", "@_dirty": "0" };
|
|
28339
29530
|
const lines = text.split("\n");
|
|
28340
29531
|
const paragraphs = lines.map((line) => {
|
|
28341
29532
|
const paragraph = {};
|
|
@@ -28343,9 +29534,10 @@ var PptxHandlerRuntime22 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
28343
29534
|
paragraph["a:pPr"] = firstPPr;
|
|
28344
29535
|
}
|
|
28345
29536
|
paragraph["a:r"] = {
|
|
28346
|
-
|
|
29537
|
+
"a:rPr": rPrForRun,
|
|
28347
29538
|
"a:t": line
|
|
28348
29539
|
};
|
|
29540
|
+
paragraph["a:endParaRPr"] = endParaRPr;
|
|
28349
29541
|
return paragraph;
|
|
28350
29542
|
});
|
|
28351
29543
|
txBody["a:p"] = paragraphs.length === 1 ? paragraphs[0] : paragraphs;
|
|
@@ -28358,7 +29550,7 @@ var PptxHandlerRuntime22 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
28358
29550
|
xmlCell["a:tcPr"] = {};
|
|
28359
29551
|
}
|
|
28360
29552
|
const tcPr = xmlCell["a:tcPr"];
|
|
28361
|
-
writeCellFill(tcPr, style);
|
|
29553
|
+
writeCellFill(tcPr, style, (colorXml) => this.parseColor(colorXml));
|
|
28362
29554
|
if (style.vAlign) {
|
|
28363
29555
|
const vAlignMap = {
|
|
28364
29556
|
top: "t",
|
|
@@ -28440,35 +29632,29 @@ var PptxHandlerRuntime22 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
28440
29632
|
}
|
|
28441
29633
|
}
|
|
28442
29634
|
}
|
|
28443
|
-
|
|
28444
|
-
|
|
28445
|
-
|
|
28446
|
-
|
|
28447
|
-
|
|
28448
|
-
|
|
28449
|
-
|
|
28450
|
-
|
|
28451
|
-
|
|
28452
|
-
|
|
28453
|
-
|
|
28454
|
-
|
|
28455
|
-
tcMar["a:marR"] = {
|
|
28456
|
-
"@_w": String(Math.round(style.marginRight * emuPerPx))
|
|
28457
|
-
};
|
|
28458
|
-
}
|
|
28459
|
-
if (style.marginTop !== void 0) {
|
|
28460
|
-
tcMar["a:marT"] = {
|
|
28461
|
-
"@_w": String(Math.round(style.marginTop * emuPerPx))
|
|
28462
|
-
};
|
|
28463
|
-
}
|
|
28464
|
-
if (style.marginBottom !== void 0) {
|
|
28465
|
-
tcMar["a:marB"] = {
|
|
28466
|
-
"@_w": String(Math.round(style.marginBottom * emuPerPx))
|
|
28467
|
-
};
|
|
28468
|
-
}
|
|
29635
|
+
const emuPerPx = _PptxHandlerRuntime.EMU_PER_PX;
|
|
29636
|
+
if (style.marginLeft !== void 0) {
|
|
29637
|
+
tcPr["@_marL"] = String(Math.round(style.marginLeft * emuPerPx));
|
|
29638
|
+
}
|
|
29639
|
+
if (style.marginRight !== void 0) {
|
|
29640
|
+
tcPr["@_marR"] = String(Math.round(style.marginRight * emuPerPx));
|
|
29641
|
+
}
|
|
29642
|
+
if (style.marginTop !== void 0) {
|
|
29643
|
+
tcPr["@_marT"] = String(Math.round(style.marginTop * emuPerPx));
|
|
29644
|
+
}
|
|
29645
|
+
if (style.marginBottom !== void 0) {
|
|
29646
|
+
tcPr["@_marB"] = String(Math.round(style.marginBottom * emuPerPx));
|
|
28469
29647
|
}
|
|
29648
|
+
delete tcPr["a:tcMar"];
|
|
28470
29649
|
writeDiagonalBorders(tcPr, style, _PptxHandlerRuntime.EMU_PER_PX);
|
|
28471
29650
|
writeCellTextFormatting(xmlCell, style, this.ensureArray.bind(this));
|
|
29651
|
+
const reordered = reorderObjectKeys(tcPr, TC_PR_BORDERS_ORDER);
|
|
29652
|
+
for (const key of Object.keys(tcPr)) {
|
|
29653
|
+
delete tcPr[key];
|
|
29654
|
+
}
|
|
29655
|
+
for (const key of Object.keys(reordered)) {
|
|
29656
|
+
tcPr[key] = reordered[key];
|
|
29657
|
+
}
|
|
28472
29658
|
}
|
|
28473
29659
|
};
|
|
28474
29660
|
|
|
@@ -28495,14 +29681,27 @@ function serializeCellMergeAttributes(xmlCell, cell) {
|
|
|
28495
29681
|
delete xmlCell["@_vMerge"];
|
|
28496
29682
|
}
|
|
28497
29683
|
}
|
|
29684
|
+
var DEFAULT_POWERPOINT_TABLE_STYLE_ID = "{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}";
|
|
28498
29685
|
function serializeTablePropertyFlags(tbl, tableData) {
|
|
28499
29686
|
const tblPr = tbl["a:tblPr"] ?? {};
|
|
28500
|
-
|
|
28501
|
-
|
|
28502
|
-
|
|
28503
|
-
|
|
28504
|
-
|
|
28505
|
-
|
|
29687
|
+
const setOrDelete = (key, truthy) => {
|
|
29688
|
+
if (truthy) {
|
|
29689
|
+
tblPr[key] = "1";
|
|
29690
|
+
} else {
|
|
29691
|
+
delete tblPr[key];
|
|
29692
|
+
}
|
|
29693
|
+
};
|
|
29694
|
+
setOrDelete("@_bandRow", tableData.bandedRows);
|
|
29695
|
+
setOrDelete("@_bandCol", tableData.bandedColumns);
|
|
29696
|
+
setOrDelete("@_firstRow", tableData.firstRowHeader);
|
|
29697
|
+
setOrDelete("@_lastRow", tableData.lastRow);
|
|
29698
|
+
setOrDelete("@_firstCol", tableData.firstCol);
|
|
29699
|
+
setOrDelete("@_lastCol", tableData.lastCol);
|
|
29700
|
+
if (tableData.tableStyleId) {
|
|
29701
|
+
tblPr["a:tableStyleId"] = tableData.tableStyleId;
|
|
29702
|
+
} else if (!tblPr["a:tableStyleId"]) {
|
|
29703
|
+
tblPr["a:tableStyleId"] = DEFAULT_POWERPOINT_TABLE_STYLE_ID;
|
|
29704
|
+
}
|
|
28506
29705
|
tbl["a:tblPr"] = tblPr;
|
|
28507
29706
|
}
|
|
28508
29707
|
function replaceFirstTextValueInTree(node, localName, newValue, getXmlLocalName) {
|
|
@@ -28547,7 +29746,9 @@ function createDefaultXmlCell() {
|
|
|
28547
29746
|
"a:bodyPr": {},
|
|
28548
29747
|
"a:lstStyle": {},
|
|
28549
29748
|
"a:p": {
|
|
28550
|
-
|
|
29749
|
+
// Match PowerPoint's "Insert Table" default: every paragraph-end
|
|
29750
|
+
// run carries `lang="en-US" dirty="0"`.
|
|
29751
|
+
"a:endParaRPr": { "@_lang": "en-US", "@_dirty": "0" }
|
|
28551
29752
|
}
|
|
28552
29753
|
},
|
|
28553
29754
|
"a:tcPr": {}
|
|
@@ -28555,6 +29756,54 @@ function createDefaultXmlCell() {
|
|
|
28555
29756
|
}
|
|
28556
29757
|
|
|
28557
29758
|
// src/core/core/runtime/table-xml-rebuild.ts
|
|
29759
|
+
var GRID_COL_ID_EXT_URI = "{9D8B030D-6E8A-4147-A177-3AD203B41FA5}";
|
|
29760
|
+
var A16_NAMESPACE = "http://schemas.microsoft.com/office/drawing/2014/main";
|
|
29761
|
+
function ensureA16NamespaceOnSlideRoot(slideRoot) {
|
|
29762
|
+
if (!slideRoot["@_xmlns:a16"]) {
|
|
29763
|
+
slideRoot["@_xmlns:a16"] = A16_NAMESPACE;
|
|
29764
|
+
}
|
|
29765
|
+
if (!slideRoot["@_xmlns:mc"]) {
|
|
29766
|
+
slideRoot["@_xmlns:mc"] = "http://schemas.openxmlformats.org/markup-compatibility/2006";
|
|
29767
|
+
}
|
|
29768
|
+
const existingIgnorable = String(slideRoot["@_mc:Ignorable"] || "").trim();
|
|
29769
|
+
if (existingIgnorable.length === 0) {
|
|
29770
|
+
slideRoot["@_mc:Ignorable"] = "a16";
|
|
29771
|
+
return;
|
|
29772
|
+
}
|
|
29773
|
+
const tokens = existingIgnorable.split(/\s+/).filter((token) => token.length > 0);
|
|
29774
|
+
if (!tokens.includes("a16")) {
|
|
29775
|
+
tokens.push("a16");
|
|
29776
|
+
slideRoot["@_mc:Ignorable"] = tokens.join(" ");
|
|
29777
|
+
}
|
|
29778
|
+
}
|
|
29779
|
+
function slideContainsA16Element(node) {
|
|
29780
|
+
if (node === null || node === void 0) {
|
|
29781
|
+
return false;
|
|
29782
|
+
}
|
|
29783
|
+
if (Array.isArray(node)) {
|
|
29784
|
+
for (const entry of node) {
|
|
29785
|
+
if (slideContainsA16Element(entry)) {
|
|
29786
|
+
return true;
|
|
29787
|
+
}
|
|
29788
|
+
}
|
|
29789
|
+
return false;
|
|
29790
|
+
}
|
|
29791
|
+
if (typeof node !== "object") {
|
|
29792
|
+
return false;
|
|
29793
|
+
}
|
|
29794
|
+
for (const [key, value] of Object.entries(node)) {
|
|
29795
|
+
if (key.startsWith("a16:")) {
|
|
29796
|
+
return true;
|
|
29797
|
+
}
|
|
29798
|
+
if (slideContainsA16Element(value)) {
|
|
29799
|
+
return true;
|
|
29800
|
+
}
|
|
29801
|
+
}
|
|
29802
|
+
return false;
|
|
29803
|
+
}
|
|
29804
|
+
function randomColumnId() {
|
|
29805
|
+
return String(Math.floor(Math.random() * 4294967295));
|
|
29806
|
+
}
|
|
28558
29807
|
function rebuildTableXmlFromData(tbl, tableData, emuPerPx, ensureArrayFn) {
|
|
28559
29808
|
const existingXmlRows = ensureArrayFn(tbl["a:tr"]);
|
|
28560
29809
|
const existingGridCols = ensureArrayFn(
|
|
@@ -28563,8 +29812,33 @@ function rebuildTableXmlFromData(tbl, tableData, emuPerPx, ensureArrayFn) {
|
|
|
28563
29812
|
const totalWidthEmu = existingGridCols.reduce((sum, col) => {
|
|
28564
29813
|
return sum + (parseInt(String(col?.["@_w"] || "0"), 10) || 0);
|
|
28565
29814
|
}, 0) || 9144e3;
|
|
28566
|
-
const
|
|
28567
|
-
|
|
29815
|
+
const existingColIds = existingGridCols.map((col) => {
|
|
29816
|
+
const extList = col?.["a:extLst"];
|
|
29817
|
+
const exts = Array.isArray(extList?.["a:ext"]) ? extList["a:ext"] : extList?.["a:ext"] ? [extList["a:ext"]] : [];
|
|
29818
|
+
for (const ext of exts) {
|
|
29819
|
+
if (ext?.["@_uri"] === GRID_COL_ID_EXT_URI) {
|
|
29820
|
+
const colId = ext["a16:colId"];
|
|
29821
|
+
const val = colId?.["@_val"];
|
|
29822
|
+
if (typeof val === "string" && val.length > 0) {
|
|
29823
|
+
return val;
|
|
29824
|
+
}
|
|
29825
|
+
}
|
|
29826
|
+
}
|
|
29827
|
+
return "";
|
|
29828
|
+
});
|
|
29829
|
+
const newGridCols = tableData.columnWidths.map((w, i) => ({
|
|
29830
|
+
"@_w": String(Math.round(w * totalWidthEmu)),
|
|
29831
|
+
"a:extLst": {
|
|
29832
|
+
"a:ext": {
|
|
29833
|
+
"@_uri": GRID_COL_ID_EXT_URI,
|
|
29834
|
+
// `xmlns:a16` is declared on the slide root by
|
|
29835
|
+
// `ensureA16NamespaceOnSlideRoot`; emitting it here too is
|
|
29836
|
+
// schema-redundant and PowerPoint flags it.
|
|
29837
|
+
"a16:colId": {
|
|
29838
|
+
"@_val": existingColIds[i] || randomColumnId()
|
|
29839
|
+
}
|
|
29840
|
+
}
|
|
29841
|
+
}
|
|
28568
29842
|
}));
|
|
28569
29843
|
if (!tbl["a:tblGrid"]) {
|
|
28570
29844
|
tbl["a:tblGrid"] = {};
|
|
@@ -28919,26 +30193,64 @@ var PptxHandlerRuntime23 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
28919
30193
|
continue;
|
|
28920
30194
|
}
|
|
28921
30195
|
const scalingNode = this.xmlLookupService.getChildByLocalName(axisNode, "scaling");
|
|
28922
|
-
if (
|
|
28923
|
-
|
|
30196
|
+
if (scalingNode) {
|
|
30197
|
+
if (matchingAxis.logBase !== void 0 && matchingAxis.logBase > 0) {
|
|
30198
|
+
const logBaseKey = Object.keys(scalingNode).find(
|
|
30199
|
+
(k) => this.compatibilityService.getXmlLocalName(k) === "logBase"
|
|
30200
|
+
);
|
|
30201
|
+
if (logBaseKey) {
|
|
30202
|
+
scalingNode[logBaseKey]["@_val"] = String(matchingAxis.logBase);
|
|
30203
|
+
} else {
|
|
30204
|
+
scalingNode["c:logBase"] = {
|
|
30205
|
+
"@_val": String(matchingAxis.logBase)
|
|
30206
|
+
};
|
|
30207
|
+
}
|
|
30208
|
+
} else if (matchingAxis.logScale === false) {
|
|
30209
|
+
const logBaseKey = Object.keys(scalingNode).find(
|
|
30210
|
+
(k) => this.compatibilityService.getXmlLocalName(k) === "logBase"
|
|
30211
|
+
);
|
|
30212
|
+
if (logBaseKey) {
|
|
30213
|
+
delete scalingNode[logBaseKey];
|
|
30214
|
+
}
|
|
30215
|
+
}
|
|
30216
|
+
this.upsertChartAxisChild(
|
|
30217
|
+
scalingNode,
|
|
30218
|
+
"min",
|
|
30219
|
+
matchingAxis.min !== void 0 ? String(matchingAxis.min) : void 0
|
|
30220
|
+
);
|
|
30221
|
+
this.upsertChartAxisChild(
|
|
30222
|
+
scalingNode,
|
|
30223
|
+
"max",
|
|
30224
|
+
matchingAxis.max !== void 0 ? String(matchingAxis.max) : void 0
|
|
30225
|
+
);
|
|
28924
30226
|
}
|
|
28925
|
-
if (matchingAxis.
|
|
28926
|
-
const
|
|
28927
|
-
(k) => this.compatibilityService.getXmlLocalName(k) === "
|
|
30227
|
+
if (matchingAxis.numFmt) {
|
|
30228
|
+
const numFmtKey = Object.keys(axisNode).find(
|
|
30229
|
+
(k) => this.compatibilityService.getXmlLocalName(k) === "numFmt"
|
|
28928
30230
|
);
|
|
28929
|
-
|
|
28930
|
-
|
|
30231
|
+
const numFmtAttrs = {
|
|
30232
|
+
"@_formatCode": matchingAxis.numFmt.formatCode,
|
|
30233
|
+
"@_sourceLinked": matchingAxis.numFmt.sourceLinked ? "1" : "0"
|
|
30234
|
+
};
|
|
30235
|
+
if (numFmtKey) {
|
|
30236
|
+
axisNode[numFmtKey] = numFmtAttrs;
|
|
28931
30237
|
} else {
|
|
28932
|
-
|
|
28933
|
-
"@_val": String(matchingAxis.logBase)
|
|
28934
|
-
};
|
|
30238
|
+
axisNode["c:numFmt"] = numFmtAttrs;
|
|
28935
30239
|
}
|
|
28936
|
-
}
|
|
28937
|
-
|
|
28938
|
-
|
|
30240
|
+
}
|
|
30241
|
+
this.upsertChartAxisChild(
|
|
30242
|
+
axisNode,
|
|
30243
|
+
"majorUnit",
|
|
30244
|
+
matchingAxis.majorUnit !== void 0 ? String(matchingAxis.majorUnit) : void 0
|
|
30245
|
+
);
|
|
30246
|
+
if (matchingAxis.tickLblPos !== void 0) {
|
|
30247
|
+
const tickLblKey = Object.keys(axisNode).find(
|
|
30248
|
+
(k) => this.compatibilityService.getXmlLocalName(k) === "tickLblPos"
|
|
28939
30249
|
);
|
|
28940
|
-
if (
|
|
28941
|
-
|
|
30250
|
+
if (tickLblKey) {
|
|
30251
|
+
axisNode[tickLblKey]["@_val"] = matchingAxis.tickLblPos;
|
|
30252
|
+
} else {
|
|
30253
|
+
axisNode["c:tickLblPos"] = { "@_val": matchingAxis.tickLblPos };
|
|
28942
30254
|
}
|
|
28943
30255
|
}
|
|
28944
30256
|
}
|
|
@@ -28951,6 +30263,18 @@ var PptxHandlerRuntime23 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
28951
30263
|
}
|
|
28952
30264
|
this.pendingChartUpdates = void 0;
|
|
28953
30265
|
}
|
|
30266
|
+
/**
|
|
30267
|
+
* Upsert a `c:<localName>` child with `@_val` on an axis or scaling node.
|
|
30268
|
+
* When `value` is undefined, removes any existing child of that local name.
|
|
30269
|
+
*/
|
|
30270
|
+
upsertChartAxisChild(parent, localName, value) {
|
|
30271
|
+
upsertChartAxisChild(
|
|
30272
|
+
parent,
|
|
30273
|
+
localName,
|
|
30274
|
+
value,
|
|
30275
|
+
(key) => this.compatibilityService.getXmlLocalName(key)
|
|
30276
|
+
);
|
|
30277
|
+
}
|
|
28954
30278
|
/**
|
|
28955
30279
|
* Update the cached point values in a chart reference node
|
|
28956
30280
|
* (numRef/strRef or numLit/strLit).
|
|
@@ -30230,17 +31554,13 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30230
31554
|
delete spPr["a:noFill"];
|
|
30231
31555
|
delete spPr["a:gradFill"];
|
|
30232
31556
|
delete spPr["a:blipFill"];
|
|
30233
|
-
const
|
|
30234
|
-
|
|
30235
|
-
|
|
30236
|
-
|
|
30237
|
-
|
|
30238
|
-
|
|
30239
|
-
|
|
30240
|
-
"@_val": String(Math.round(this.clampUnitInterval(shapeStyle.fillOpacity) * 1e5))
|
|
30241
|
-
};
|
|
30242
|
-
}
|
|
30243
|
-
spPr["a:solidFill"] = solidFill;
|
|
31557
|
+
const resolvedOriginal = shapeStyle.fillColorXml ? this.parseColor(shapeStyle.fillColorXml) : void 0;
|
|
31558
|
+
spPr["a:solidFill"] = serializeColorChoice(
|
|
31559
|
+
shapeStyle.fillColorXml,
|
|
31560
|
+
resolvedOriginal,
|
|
31561
|
+
fillColor,
|
|
31562
|
+
shapeStyle.fillOpacity
|
|
31563
|
+
);
|
|
30244
31564
|
}
|
|
30245
31565
|
}
|
|
30246
31566
|
if (shapeStyle.strokeColor !== void 0) {
|
|
@@ -30255,17 +31575,13 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30255
31575
|
delete lineNode["a:solidFill"];
|
|
30256
31576
|
} else {
|
|
30257
31577
|
delete lineNode["a:noFill"];
|
|
30258
|
-
const
|
|
30259
|
-
|
|
30260
|
-
|
|
30261
|
-
|
|
30262
|
-
|
|
30263
|
-
|
|
30264
|
-
|
|
30265
|
-
"@_val": String(Math.round(this.clampUnitInterval(shapeStyle.strokeOpacity) * 1e5))
|
|
30266
|
-
};
|
|
30267
|
-
}
|
|
30268
|
-
lineNode["a:solidFill"] = lineFill;
|
|
31578
|
+
const resolvedStrokeOriginal = shapeStyle.strokeColorXml ? this.parseColor(shapeStyle.strokeColorXml) : void 0;
|
|
31579
|
+
lineNode["a:solidFill"] = serializeColorChoice(
|
|
31580
|
+
shapeStyle.strokeColorXml,
|
|
31581
|
+
resolvedStrokeOriginal,
|
|
31582
|
+
shapeStyle.strokeColor,
|
|
31583
|
+
shapeStyle.strokeOpacity
|
|
31584
|
+
);
|
|
30269
31585
|
}
|
|
30270
31586
|
}
|
|
30271
31587
|
if (shapeStyle.strokeDash !== void 0) {
|
|
@@ -30346,7 +31662,11 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30346
31662
|
} else if (shapeStyle.lineJoin === "bevel") {
|
|
30347
31663
|
lineNode["a:bevel"] = {};
|
|
30348
31664
|
} else if (shapeStyle.lineJoin === "miter") {
|
|
30349
|
-
|
|
31665
|
+
const miterNode = {};
|
|
31666
|
+
if (typeof shapeStyle.miterLimit === "number" && Number.isFinite(shapeStyle.miterLimit) && shapeStyle.miterLimit !== 8e5) {
|
|
31667
|
+
miterNode["@_lim"] = String(Math.round(shapeStyle.miterLimit));
|
|
31668
|
+
}
|
|
31669
|
+
lineNode["a:miter"] = miterNode;
|
|
30350
31670
|
}
|
|
30351
31671
|
}
|
|
30352
31672
|
if (shapeStyle.lineCap !== void 0) {
|
|
@@ -30366,6 +31686,82 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30366
31686
|
spPr["a:ln"]["a:effectLst"] = lineEffectListXml;
|
|
30367
31687
|
}
|
|
30368
31688
|
}
|
|
31689
|
+
/**
|
|
31690
|
+
* Serialize the shape's `<p:style>` block (CT_ShapeStyle §20.1.2.2.36)
|
|
31691
|
+
* from the persisted ref indices/colour XML. Emits children in spec
|
|
31692
|
+
* order: `lnRef → fillRef → effectRef → fontRef`.
|
|
31693
|
+
*
|
|
31694
|
+
* When the original shape XML already contained a `<p:style>` we mutate
|
|
31695
|
+
* that node in place so any unmodelled attributes/children are preserved.
|
|
31696
|
+
* When it didn't, we create one. When the shape no longer has any ref
|
|
31697
|
+
* data we leave the existing `<p:style>` (if any) untouched — silently
|
|
31698
|
+
* dropping it would break round-tripping.
|
|
31699
|
+
*
|
|
31700
|
+
* Phase 2 Stream B / C-H2.
|
|
31701
|
+
*/
|
|
31702
|
+
applyShapeStyleRefs(shape, shapeStyle) {
|
|
31703
|
+
const hasAnyRef = shapeStyle.lnRefIdx !== void 0 || shapeStyle.fillRefIdx !== void 0 || shapeStyle.effectRefIdx !== void 0 || shapeStyle.fontRefIdx !== void 0;
|
|
31704
|
+
if (!hasAnyRef) {
|
|
31705
|
+
return;
|
|
31706
|
+
}
|
|
31707
|
+
const existing = shape["p:style"];
|
|
31708
|
+
const styleNode = existing ?? {};
|
|
31709
|
+
if (shapeStyle.lnRefIdx !== void 0) {
|
|
31710
|
+
const lnRef = styleNode["a:lnRef"] ?? {};
|
|
31711
|
+
lnRef["@_idx"] = String(shapeStyle.lnRefIdx);
|
|
31712
|
+
this.replaceRefColorChoice(lnRef, shapeStyle.lnRefColorXml);
|
|
31713
|
+
styleNode["a:lnRef"] = lnRef;
|
|
31714
|
+
}
|
|
31715
|
+
if (shapeStyle.fillRefIdx !== void 0) {
|
|
31716
|
+
const fillRef = styleNode["a:fillRef"] ?? {};
|
|
31717
|
+
fillRef["@_idx"] = String(shapeStyle.fillRefIdx);
|
|
31718
|
+
this.replaceRefColorChoice(fillRef, shapeStyle.fillRefColorXml);
|
|
31719
|
+
styleNode["a:fillRef"] = fillRef;
|
|
31720
|
+
}
|
|
31721
|
+
if (shapeStyle.effectRefIdx !== void 0) {
|
|
31722
|
+
const effectRef = styleNode["a:effectRef"] ?? {};
|
|
31723
|
+
effectRef["@_idx"] = String(shapeStyle.effectRefIdx);
|
|
31724
|
+
this.replaceRefColorChoice(effectRef, shapeStyle.effectRefColorXml);
|
|
31725
|
+
styleNode["a:effectRef"] = effectRef;
|
|
31726
|
+
}
|
|
31727
|
+
if (shapeStyle.fontRefIdx !== void 0) {
|
|
31728
|
+
const fontRef = styleNode["a:fontRef"] ?? {};
|
|
31729
|
+
fontRef["@_idx"] = shapeStyle.fontRefIdx;
|
|
31730
|
+
this.replaceRefColorChoice(fontRef, shapeStyle.fontRefColorXml);
|
|
31731
|
+
styleNode["a:fontRef"] = fontRef;
|
|
31732
|
+
}
|
|
31733
|
+
const reordered = reorderObjectKeys(styleNode, SHAPE_STYLE_ORDER);
|
|
31734
|
+
for (const key of Object.keys(styleNode)) {
|
|
31735
|
+
delete styleNode[key];
|
|
31736
|
+
}
|
|
31737
|
+
for (const key of Object.keys(reordered)) {
|
|
31738
|
+
styleNode[key] = reordered[key];
|
|
31739
|
+
}
|
|
31740
|
+
shape["p:style"] = styleNode;
|
|
31741
|
+
}
|
|
31742
|
+
/**
|
|
31743
|
+
* Replace any existing colour-choice child on a style-matrix-reference
|
|
31744
|
+
* element with the given preserved XML, or strip all colour children
|
|
31745
|
+
* when the override is undefined.
|
|
31746
|
+
*/
|
|
31747
|
+
replaceRefColorChoice(refNode, colorXml) {
|
|
31748
|
+
for (const key of [
|
|
31749
|
+
"a:scrgbClr",
|
|
31750
|
+
"a:srgbClr",
|
|
31751
|
+
"a:hslClr",
|
|
31752
|
+
"a:sysClr",
|
|
31753
|
+
"a:schemeClr",
|
|
31754
|
+
"a:prstClr"
|
|
31755
|
+
]) {
|
|
31756
|
+
delete refNode[key];
|
|
31757
|
+
}
|
|
31758
|
+
if (!colorXml) {
|
|
31759
|
+
return;
|
|
31760
|
+
}
|
|
31761
|
+
for (const [key, value] of Object.entries(colorXml)) {
|
|
31762
|
+
refNode[key] = value;
|
|
31763
|
+
}
|
|
31764
|
+
}
|
|
30369
31765
|
};
|
|
30370
31766
|
|
|
30371
31767
|
// src/core/core/runtime/PptxHandlerRuntimeSaveEffectsWriter.ts
|
|
@@ -30375,17 +31771,22 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
|
|
|
30375
31771
|
* effectDag, 3D scene, and 3D shape properties to the given spPr XML object.
|
|
30376
31772
|
*/
|
|
30377
31773
|
applyEffectsAndThreeD(spPr, shapeStyle) {
|
|
30378
|
-
const
|
|
31774
|
+
const presetShadowXml = shapeStyle.presetShadowName ? this.buildPresetShadowXml(shapeStyle) : void 0;
|
|
31775
|
+
const outerShadowXml = presetShadowXml ? void 0 : this.buildOuterShadowXml(shapeStyle);
|
|
30379
31776
|
const innerShadowXml = this.buildInnerShadowXml(shapeStyle);
|
|
30380
31777
|
const glowXml = this.buildGlowXml(shapeStyle);
|
|
30381
31778
|
const softEdgeXml = this.buildSoftEdgeXml(shapeStyle);
|
|
30382
31779
|
const reflectionXml = this.buildReflectionXml(shapeStyle);
|
|
30383
31780
|
const blurXml = this.buildBlurXml(shapeStyle);
|
|
30384
|
-
const hasAnyEffect = outerShadowXml || innerShadowXml || glowXml || softEdgeXml || reflectionXml || blurXml;
|
|
31781
|
+
const hasAnyEffect = outerShadowXml || presetShadowXml || innerShadowXml || glowXml || softEdgeXml || reflectionXml || blurXml;
|
|
30385
31782
|
if (hasAnyEffect) {
|
|
30386
31783
|
const effectList = spPr["a:effectLst"] || {};
|
|
30387
|
-
if (
|
|
31784
|
+
if (presetShadowXml) {
|
|
31785
|
+
effectList["a:prstShdw"] = presetShadowXml;
|
|
31786
|
+
delete effectList["a:outerShdw"];
|
|
31787
|
+
} else if (outerShadowXml) {
|
|
30388
31788
|
effectList["a:outerShdw"] = outerShadowXml;
|
|
31789
|
+
delete effectList["a:prstShdw"];
|
|
30389
31790
|
}
|
|
30390
31791
|
if (innerShadowXml) {
|
|
30391
31792
|
effectList["a:innerShdw"] = innerShadowXml;
|
|
@@ -30402,12 +31803,13 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
|
|
|
30402
31803
|
if (blurXml) {
|
|
30403
31804
|
effectList["a:blur"] = blurXml;
|
|
30404
31805
|
}
|
|
30405
|
-
spPr["a:effectLst"] = effectList;
|
|
31806
|
+
spPr["a:effectLst"] = reorderObjectKeys(effectList, EFFECT_LST_ORDER);
|
|
30406
31807
|
} else {
|
|
30407
31808
|
const effectList = spPr["a:effectLst"];
|
|
30408
31809
|
if (effectList) {
|
|
30409
|
-
if (shapeStyle.shadowColor !== void 0 && !outerShadowXml) {
|
|
31810
|
+
if (shapeStyle.shadowColor !== void 0 && !outerShadowXml && !presetShadowXml) {
|
|
30410
31811
|
delete effectList["a:outerShdw"];
|
|
31812
|
+
delete effectList["a:prstShdw"];
|
|
30411
31813
|
}
|
|
30412
31814
|
if (shapeStyle.innerShadowColor !== void 0 && !innerShadowXml) {
|
|
30413
31815
|
delete effectList["a:innerShdw"];
|
|
@@ -30426,6 +31828,8 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
|
|
|
30426
31828
|
}
|
|
30427
31829
|
if (Object.keys(effectList).length === 0) {
|
|
30428
31830
|
delete spPr["a:effectLst"];
|
|
31831
|
+
} else {
|
|
31832
|
+
spPr["a:effectLst"] = reorderObjectKeys(effectList, EFFECT_LST_ORDER);
|
|
30429
31833
|
}
|
|
30430
31834
|
}
|
|
30431
31835
|
}
|
|
@@ -30586,7 +31990,8 @@ var PptxHandlerRuntime30 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30586
31990
|
);
|
|
30587
31991
|
}
|
|
30588
31992
|
if (el.textStyle?.hOverflow) {
|
|
30589
|
-
bodyPr["@
|
|
31993
|
+
bodyPr["@_horzOverflow"] = el.textStyle.hOverflow;
|
|
31994
|
+
delete bodyPr["@_hOverflow"];
|
|
30590
31995
|
}
|
|
30591
31996
|
if (el.textStyle?.vertOverflow) {
|
|
30592
31997
|
bodyPr["@_vertOverflow"] = el.textStyle.vertOverflow;
|
|
@@ -30817,7 +32222,10 @@ var PptxHandlerRuntime31 = class extends PptxHandlerRuntime30 {
|
|
|
30817
32222
|
const elWithPaths = el;
|
|
30818
32223
|
if (elWithPaths.customGeometryPaths && elWithPaths.customGeometryPaths.length > 0) {
|
|
30819
32224
|
delete spPr["a:prstGeom"];
|
|
30820
|
-
spPr["a:custGeom"] = customGeometryPathsToXml(
|
|
32225
|
+
spPr["a:custGeom"] = customGeometryPathsToXml(
|
|
32226
|
+
elWithPaths.customGeometryPaths,
|
|
32227
|
+
elWithPaths.customGeometryRawData
|
|
32228
|
+
);
|
|
30821
32229
|
} else if (spPr["a:prstGeom"]) {
|
|
30822
32230
|
const presetGeometry = el.type === "connector" ? this.normalizePresetGeometry(el.shapeType || "straightConnector1") : this.normalizePresetGeometry(el.shapeType);
|
|
30823
32231
|
const prstGeom = spPr["a:prstGeom"];
|
|
@@ -30942,6 +32350,42 @@ var PptxHandlerRuntime32 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
30942
32350
|
isGraphicFrameShape(shape) {
|
|
30943
32351
|
return Boolean(shape["p:nvGraphicFramePr"] || shape["a:graphic"] && shape["p:xfrm"]);
|
|
30944
32352
|
}
|
|
32353
|
+
/**
|
|
32354
|
+
* Reorder children of `p:spPr` to match CT_ShapeProperties (§20.1.2.2.35).
|
|
32355
|
+
* Also reorders any nested `a:blipFill` per CT_BlipFillProperties.
|
|
32356
|
+
* fast-xml-parser preserves insertion order; PowerPoint validates against
|
|
32357
|
+
* the schema's required order, so save-side mutations must be re-sorted.
|
|
32358
|
+
*/
|
|
32359
|
+
finalizeSpPrSchemaOrder(shape) {
|
|
32360
|
+
const spPr = shape["p:spPr"];
|
|
32361
|
+
if (!spPr) {
|
|
32362
|
+
return;
|
|
32363
|
+
}
|
|
32364
|
+
const blipFill = spPr["a:blipFill"];
|
|
32365
|
+
if (blipFill) {
|
|
32366
|
+
this.reorderInPlace(blipFill, BLIP_FILL_ORDER);
|
|
32367
|
+
}
|
|
32368
|
+
this.reorderInPlace(spPr, SP_PR_ORDER);
|
|
32369
|
+
}
|
|
32370
|
+
/**
|
|
32371
|
+
* Reorder children of the picture-level `p:blipFill` (CT_BlipFillProperties).
|
|
32372
|
+
* Picture elements carry their blip data on the `p:pic` root, not under spPr.
|
|
32373
|
+
*/
|
|
32374
|
+
finalizePictureBlipFillOrder(shape) {
|
|
32375
|
+
const pBlipFill = shape["p:blipFill"];
|
|
32376
|
+
if (pBlipFill) {
|
|
32377
|
+
this.reorderInPlace(pBlipFill, BLIP_FILL_ORDER);
|
|
32378
|
+
}
|
|
32379
|
+
}
|
|
32380
|
+
reorderInPlace(target, schemaOrder) {
|
|
32381
|
+
const reordered = reorderObjectKeys(target, schemaOrder);
|
|
32382
|
+
for (const key of Object.keys(target)) {
|
|
32383
|
+
delete target[key];
|
|
32384
|
+
}
|
|
32385
|
+
for (const key of Object.keys(reordered)) {
|
|
32386
|
+
target[key] = reordered[key];
|
|
32387
|
+
}
|
|
32388
|
+
}
|
|
30945
32389
|
/** Whether an element ID indicates a template (layout/master) element. */
|
|
30946
32390
|
isTemplateElementId(elementId) {
|
|
30947
32391
|
return elementId.startsWith("layout-") || elementId.startsWith("master-");
|
|
@@ -30965,14 +32409,50 @@ var PptxHandlerRuntime32 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
30965
32409
|
}
|
|
30966
32410
|
return;
|
|
30967
32411
|
}
|
|
32412
|
+
if (el.type === "contentPart") {
|
|
32413
|
+
if (shape) {
|
|
32414
|
+
this.elementTransformUpdater.applyTransform(shape, el, _PptxHandlerRuntime.EMU_PER_PX);
|
|
32415
|
+
collectors.contentParts.push(shape);
|
|
32416
|
+
} else {
|
|
32417
|
+
this.compatibilityService.reportWarning({
|
|
32418
|
+
code: "SAVE_ELEMENT_SKIPPED",
|
|
32419
|
+
message: `Content part '${el.id}' has no rawXml and was skipped during save.`,
|
|
32420
|
+
scope: "save",
|
|
32421
|
+
slideId: ctx.slide.id,
|
|
32422
|
+
elementId: el.id
|
|
32423
|
+
});
|
|
32424
|
+
}
|
|
32425
|
+
return;
|
|
32426
|
+
}
|
|
30968
32427
|
if (!shape && (el.type === "text" || el.type === "shape")) {
|
|
30969
32428
|
shape = this.createElementXml(el);
|
|
30970
32429
|
}
|
|
30971
32430
|
if (!shape && el.type === "connector") {
|
|
30972
32431
|
shape = this.createConnectorXml(el);
|
|
30973
32432
|
}
|
|
30974
|
-
if (
|
|
30975
|
-
|
|
32433
|
+
if (el.type === "ink") {
|
|
32434
|
+
if (!shape) {
|
|
32435
|
+
shape = this.createInkShapeXml(el);
|
|
32436
|
+
this.compatibilityService.reportWarning({
|
|
32437
|
+
code: "SAVE_INK_ENCODED_AS_CUSTGEOM",
|
|
32438
|
+
message: "SDK-created ink element serialized as custGeom shape; pressure/tool metadata not represented in OOXML aink format.",
|
|
32439
|
+
scope: "save",
|
|
32440
|
+
slideId: ctx.slide.id,
|
|
32441
|
+
elementId: el.id
|
|
32442
|
+
});
|
|
32443
|
+
}
|
|
32444
|
+
}
|
|
32445
|
+
if (!shape && el.type === "table") {
|
|
32446
|
+
shape = this.createTableGraphicFrameXml(el);
|
|
32447
|
+
}
|
|
32448
|
+
if (el.type === "ole") {
|
|
32449
|
+
const oleEl = el;
|
|
32450
|
+
if (shape) {
|
|
32451
|
+
this.applyOleTypedFieldUpdates(shape, oleEl);
|
|
32452
|
+
} else {
|
|
32453
|
+
const embedRid = this.resolveOleEmbedRelationshipId(ctx.slideRelationships, oleEl.oleTarget) || ctx.slideRelationshipRegistry.nextRelationshipId();
|
|
32454
|
+
shape = this.createOleGraphicFrameXml(oleEl, embedRid);
|
|
32455
|
+
}
|
|
30976
32456
|
}
|
|
30977
32457
|
if (!shape) {
|
|
30978
32458
|
this.compatibilityService.reportWarning({
|
|
@@ -30986,11 +32466,14 @@ var PptxHandlerRuntime32 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
30986
32466
|
}
|
|
30987
32467
|
this.elementTransformUpdater.applyTransform(shape, el, _PptxHandlerRuntime.EMU_PER_PX);
|
|
30988
32468
|
this.applyImageProperties(shape, el);
|
|
32469
|
+
this.finalizePictureBlipFillOrder(shape);
|
|
30989
32470
|
this.applyGeometryUpdate(shape, el);
|
|
30990
32471
|
if (hasShapeProperties(el) && el.shapeStyle && shape["p:spPr"]) {
|
|
30991
32472
|
const spPr = shape["p:spPr"];
|
|
30992
32473
|
this.applyFillAndStroke(spPr, el.shapeStyle);
|
|
30993
32474
|
this.applyEffectsAndThreeD(spPr, el.shapeStyle);
|
|
32475
|
+
this.finalizeSpPrSchemaOrder(shape);
|
|
32476
|
+
this.applyShapeStyleRefs(shape, el.shapeStyle);
|
|
30994
32477
|
}
|
|
30995
32478
|
if (hasTextProperties(el)) {
|
|
30996
32479
|
this.applyTextBodyContent(
|
|
@@ -31148,7 +32631,8 @@ var PptxHandlerRuntime33 = class extends PptxHandlerRuntime32 {
|
|
|
31148
32631
|
connectors: [],
|
|
31149
32632
|
graphicFrames: [],
|
|
31150
32633
|
groups: [],
|
|
31151
|
-
model3ds: []
|
|
32634
|
+
model3ds: [],
|
|
32635
|
+
contentParts: []
|
|
31152
32636
|
};
|
|
31153
32637
|
const ctx = {
|
|
31154
32638
|
slide,
|
|
@@ -31180,6 +32664,12 @@ var PptxHandlerRuntime33 = class extends PptxHandlerRuntime32 {
|
|
|
31180
32664
|
} else {
|
|
31181
32665
|
delete spTree["p16:model3D"];
|
|
31182
32666
|
}
|
|
32667
|
+
if (collectors.contentParts.length > 0) {
|
|
32668
|
+
spTree["p:contentPart"] = collectors.contentParts;
|
|
32669
|
+
} else {
|
|
32670
|
+
delete spTree["p:contentPart"];
|
|
32671
|
+
}
|
|
32672
|
+
this.reapplyAlternateContentEnvelopes(spTree, collectors);
|
|
31183
32673
|
const reassigned = shapeIdValidator.validateAndDeduplicateIds(
|
|
31184
32674
|
spTree,
|
|
31185
32675
|
(v) => this.ensureArray(v)
|
|
@@ -31197,12 +32687,426 @@ var PptxHandlerRuntime33 = class extends PptxHandlerRuntime32 {
|
|
|
31197
32687
|
this.zip.file(slideRelsPath, this.builder.build(slideRelsData));
|
|
31198
32688
|
this.applySlideDrawingGuides(slideNode, slide);
|
|
31199
32689
|
this.deduplicateExtensionLists(xmlObj);
|
|
32690
|
+
if (slideContainsA16Element(slideNode)) {
|
|
32691
|
+
ensureA16NamespaceOnSlideRoot(slideNode);
|
|
32692
|
+
}
|
|
31200
32693
|
this.zip.file(slide.id, this.builder.build(xmlObj));
|
|
31201
32694
|
}
|
|
32695
|
+
/**
|
|
32696
|
+
* Re-wrap selected children with their original `<mc:AlternateContent>`
|
|
32697
|
+
* envelope (CC-4).
|
|
32698
|
+
*
|
|
32699
|
+
* Parsing merged the selected branch (Choice when supported, otherwise
|
|
32700
|
+
* Fallback) into the spTree's tag arrays. Without re-wrapping, dirty
|
|
32701
|
+
* save would emit flat `<p:sp>`/`<p:pic>` etc. and drop the
|
|
32702
|
+
* `<mc:Fallback>` branch — losing legacy rendering for files originally
|
|
32703
|
+
* authored with newer-namespace features.
|
|
32704
|
+
*
|
|
32705
|
+
* Strategy: for each XmlObject in `collectors.*` that traces back to a
|
|
32706
|
+
* known AC block, group by block and:
|
|
32707
|
+
* 1. Remove the node from its flat collector / spTree array.
|
|
32708
|
+
* 2. Clone the original AC envelope.
|
|
32709
|
+
* 3. Replace the selected branch's `<{tag}>` children with the
|
|
32710
|
+
* live (possibly edited) nodes from the collectors.
|
|
32711
|
+
* 4. Leave the unselected branch verbatim.
|
|
32712
|
+
*
|
|
32713
|
+
* Final envelopes are appended to `spTree['mc:AlternateContent']`.
|
|
32714
|
+
*/
|
|
32715
|
+
reapplyAlternateContentEnvelopes(spTree, collectors) {
|
|
32716
|
+
const TAG_TO_COLLECTOR = {
|
|
32717
|
+
"p:sp": collectors.shapes,
|
|
32718
|
+
"p:pic": collectors.pics,
|
|
32719
|
+
"p:cxnSp": collectors.connectors,
|
|
32720
|
+
"p:graphicFrame": collectors.graphicFrames,
|
|
32721
|
+
"p:grpSp": collectors.groups,
|
|
32722
|
+
"p:contentPart": collectors.contentParts,
|
|
32723
|
+
// `model3d` does not flow through SHAPE_TREE_ELEMENT_TAGS, but the
|
|
32724
|
+
// AC pathway in OpenXML decks frequently uses Choice = p16:model3D
|
|
32725
|
+
// + Fallback = p:pic, so map it for completeness.
|
|
32726
|
+
"p16:model3D": collectors.model3ds
|
|
32727
|
+
};
|
|
32728
|
+
const blockGroups = /* @__PURE__ */ new Map();
|
|
32729
|
+
for (const tag of Object.keys(TAG_TO_COLLECTOR)) {
|
|
32730
|
+
const collector = TAG_TO_COLLECTOR[tag];
|
|
32731
|
+
if (!collector) {
|
|
32732
|
+
continue;
|
|
32733
|
+
}
|
|
32734
|
+
for (const node of collector) {
|
|
32735
|
+
const block = this.alternateContentBlockByRawXml.get(node);
|
|
32736
|
+
if (!block) {
|
|
32737
|
+
continue;
|
|
32738
|
+
}
|
|
32739
|
+
let entries = blockGroups.get(block);
|
|
32740
|
+
if (!entries) {
|
|
32741
|
+
entries = [];
|
|
32742
|
+
blockGroups.set(block, entries);
|
|
32743
|
+
}
|
|
32744
|
+
entries.push({ tag, node, collector });
|
|
32745
|
+
}
|
|
32746
|
+
}
|
|
32747
|
+
if (blockGroups.size === 0) {
|
|
32748
|
+
return;
|
|
32749
|
+
}
|
|
32750
|
+
const envelopes = [];
|
|
32751
|
+
for (const [block, entries] of blockGroups) {
|
|
32752
|
+
for (const entry of entries) {
|
|
32753
|
+
const idx = entry.collector.indexOf(entry.node);
|
|
32754
|
+
if (idx !== -1) {
|
|
32755
|
+
entry.collector.splice(idx, 1);
|
|
32756
|
+
}
|
|
32757
|
+
}
|
|
32758
|
+
const clonedAc = { ...block.rawAc };
|
|
32759
|
+
const liveByTag = /* @__PURE__ */ new Map();
|
|
32760
|
+
for (const entry of entries) {
|
|
32761
|
+
let arr = liveByTag.get(entry.tag);
|
|
32762
|
+
if (!arr) {
|
|
32763
|
+
arr = [];
|
|
32764
|
+
liveByTag.set(entry.tag, arr);
|
|
32765
|
+
}
|
|
32766
|
+
arr.push(entry.node);
|
|
32767
|
+
}
|
|
32768
|
+
if (block.selectedBranch === "choice") {
|
|
32769
|
+
const choices = this.ensureArray(clonedAc["mc:Choice"]);
|
|
32770
|
+
const targetIdx = block.choiceIndex ?? 0;
|
|
32771
|
+
const original = choices[targetIdx];
|
|
32772
|
+
if (original) {
|
|
32773
|
+
const rebuilt = { ...original };
|
|
32774
|
+
for (const tag of SHAPE_TREE_ELEMENT_TAGS) {
|
|
32775
|
+
delete rebuilt[tag];
|
|
32776
|
+
}
|
|
32777
|
+
for (const [tag, nodes] of liveByTag) {
|
|
32778
|
+
rebuilt[tag] = nodes.length === 1 ? nodes[0] : nodes;
|
|
32779
|
+
}
|
|
32780
|
+
choices[targetIdx] = rebuilt;
|
|
32781
|
+
clonedAc["mc:Choice"] = choices.length === 1 ? choices[0] : choices;
|
|
32782
|
+
}
|
|
32783
|
+
} else {
|
|
32784
|
+
const fallback = clonedAc["mc:Fallback"];
|
|
32785
|
+
if (fallback) {
|
|
32786
|
+
const rebuilt = { ...fallback };
|
|
32787
|
+
for (const tag of SHAPE_TREE_ELEMENT_TAGS) {
|
|
32788
|
+
delete rebuilt[tag];
|
|
32789
|
+
}
|
|
32790
|
+
for (const [tag, nodes] of liveByTag) {
|
|
32791
|
+
rebuilt[tag] = nodes.length === 1 ? nodes[0] : nodes;
|
|
32792
|
+
}
|
|
32793
|
+
clonedAc["mc:Fallback"] = rebuilt;
|
|
32794
|
+
}
|
|
32795
|
+
}
|
|
32796
|
+
envelopes.push(clonedAc);
|
|
32797
|
+
}
|
|
32798
|
+
spTree["p:sp"] = collectors.shapes;
|
|
32799
|
+
spTree["p:pic"] = collectors.pics;
|
|
32800
|
+
spTree["p:cxnSp"] = collectors.connectors;
|
|
32801
|
+
spTree["p:graphicFrame"] = collectors.graphicFrames;
|
|
32802
|
+
if (collectors.groups.length > 0) {
|
|
32803
|
+
spTree["p:grpSp"] = collectors.groups;
|
|
32804
|
+
} else {
|
|
32805
|
+
delete spTree["p:grpSp"];
|
|
32806
|
+
}
|
|
32807
|
+
if (collectors.contentParts.length > 0) {
|
|
32808
|
+
spTree["p:contentPart"] = collectors.contentParts;
|
|
32809
|
+
} else {
|
|
32810
|
+
delete spTree["p:contentPart"];
|
|
32811
|
+
}
|
|
32812
|
+
if (collectors.model3ds.length > 0) {
|
|
32813
|
+
spTree["p16:model3D"] = collectors.model3ds;
|
|
32814
|
+
} else {
|
|
32815
|
+
delete spTree["p16:model3D"];
|
|
32816
|
+
}
|
|
32817
|
+
spTree["mc:AlternateContent"] = envelopes.length === 1 ? envelopes[0] : envelopes;
|
|
32818
|
+
}
|
|
32819
|
+
};
|
|
32820
|
+
|
|
32821
|
+
// src/core/core/runtime/PptxHandlerRuntimeSaveTheme.ts
|
|
32822
|
+
var PptxHandlerRuntime34 = class extends PptxHandlerRuntime33 {
|
|
32823
|
+
/**
|
|
32824
|
+
* Mark a theme path as dirty so the save pipeline will regenerate
|
|
32825
|
+
* the theme XML from in-memory state. Optional — without this the
|
|
32826
|
+
* original XML is preserved verbatim on save (C-H3).
|
|
32827
|
+
*/
|
|
32828
|
+
markThemeDirty(themePath) {
|
|
32829
|
+
this.dirtyThemePaths.add(themePath);
|
|
32830
|
+
}
|
|
32831
|
+
/**
|
|
32832
|
+
* Mark all known theme paths dirty in one call.
|
|
32833
|
+
*/
|
|
32834
|
+
markAllThemesDirty() {
|
|
32835
|
+
for (const themePath of this.originalThemeXmlByPath.keys()) {
|
|
32836
|
+
this.dirtyThemePaths.add(themePath);
|
|
32837
|
+
}
|
|
32838
|
+
for (const themePath of this.masterThemePaths.values()) {
|
|
32839
|
+
this.dirtyThemePaths.add(themePath);
|
|
32840
|
+
}
|
|
32841
|
+
}
|
|
32842
|
+
/**
|
|
32843
|
+
* Persist all theme parts during save. Called from the save pipeline
|
|
32844
|
+
* after master / layout XML have been flushed and before
|
|
32845
|
+
* presentation.xml is serialized.
|
|
32846
|
+
*
|
|
32847
|
+
* Order of operations per theme path:
|
|
32848
|
+
*
|
|
32849
|
+
* 1. If the path is *not* in {@link dirtyThemePaths}, the existing
|
|
32850
|
+
* ZIP entry is already correct — no-op. (Original XML was placed
|
|
32851
|
+
* into the ZIP at load time.)
|
|
32852
|
+
* 2. If the path is dirty, build a fresh `<a:theme>` document from
|
|
32853
|
+
* in-memory state and the captured raw subtrees, then overwrite
|
|
32854
|
+
* the ZIP entry.
|
|
32855
|
+
*/
|
|
32856
|
+
async persistThemeParts() {
|
|
32857
|
+
const seenThemePaths = /* @__PURE__ */ new Set();
|
|
32858
|
+
for (const [masterPath, themePath] of this.masterThemePaths.entries()) {
|
|
32859
|
+
if (!themePath) {
|
|
32860
|
+
continue;
|
|
32861
|
+
}
|
|
32862
|
+
seenThemePaths.add(themePath);
|
|
32863
|
+
if (!this.dirtyThemePaths.has(themePath)) {
|
|
32864
|
+
continue;
|
|
32865
|
+
}
|
|
32866
|
+
const themeXml2 = this.buildThemeXml(themePath, masterPath);
|
|
32867
|
+
if (themeXml2) {
|
|
32868
|
+
this.zip.file(themePath, themeXml2);
|
|
32869
|
+
}
|
|
32870
|
+
}
|
|
32871
|
+
for (const [themePath] of this.originalThemeXmlByPath.entries()) {
|
|
32872
|
+
if (seenThemePaths.has(themePath)) {
|
|
32873
|
+
continue;
|
|
32874
|
+
}
|
|
32875
|
+
if (!this.dirtyThemePaths.has(themePath)) {
|
|
32876
|
+
continue;
|
|
32877
|
+
}
|
|
32878
|
+
const themeXml2 = this.buildThemeXml(themePath, void 0);
|
|
32879
|
+
if (themeXml2) {
|
|
32880
|
+
this.zip.file(themePath, themeXml2);
|
|
32881
|
+
}
|
|
32882
|
+
}
|
|
32883
|
+
}
|
|
32884
|
+
/**
|
|
32885
|
+
* Build a complete `<a:theme>` XML document from in-memory state.
|
|
32886
|
+
* Returns the serialized XML string (with XML prolog), or `undefined`
|
|
32887
|
+
* if there is no source data to emit.
|
|
32888
|
+
*
|
|
32889
|
+
* - Color scheme: built from per-master color map (or global fallback).
|
|
32890
|
+
* - Font scheme: built from per-master font map + per-script entries.
|
|
32891
|
+
* - Format scheme: re-emit the original XML subtree if available; else
|
|
32892
|
+
* build a minimal scheme from {@link themeFormatScheme}.
|
|
32893
|
+
* - objectDefaults / extraClrSchemeLst / custClrLst / extLst: re-emit
|
|
32894
|
+
* captured raw subtrees.
|
|
32895
|
+
*/
|
|
32896
|
+
buildThemeXml(themePath, masterPath) {
|
|
32897
|
+
const colorMap = masterPath && this.masterThemeColorMaps.get(masterPath) || this.globalThemeColorMapSnapshot || this.themeColorMap;
|
|
32898
|
+
const fontMap = masterPath && this.masterThemeFontMaps.get(masterPath) || this.globalThemeFontMapSnapshot || this.themeFontMap;
|
|
32899
|
+
const themeName = this.masterThemeNames.get(themePath) || "Office Theme";
|
|
32900
|
+
const colorSchemeName = this.masterThemeColorSchemeNames.get(themePath) || themeName;
|
|
32901
|
+
const fontSchemeName = this.masterThemeFontSchemeNames.get(themePath) || themeName;
|
|
32902
|
+
const majorScripts = this.masterThemeMajorFontScripts.get(themePath) || {};
|
|
32903
|
+
const minorScripts = this.masterThemeMinorFontScripts.get(themePath) || {};
|
|
32904
|
+
const clrScheme = this.buildClrSchemeObject(colorSchemeName, colorMap);
|
|
32905
|
+
const fontScheme = this.buildFontSchemeObject(
|
|
32906
|
+
fontSchemeName,
|
|
32907
|
+
fontMap,
|
|
32908
|
+
majorScripts,
|
|
32909
|
+
minorScripts
|
|
32910
|
+
);
|
|
32911
|
+
const fmtScheme = this.extractRawSubtreeFromOriginal(themePath, [
|
|
32912
|
+
"a:theme",
|
|
32913
|
+
"a:themeElements",
|
|
32914
|
+
"a:fmtScheme"
|
|
32915
|
+
]);
|
|
32916
|
+
const themeElements = {
|
|
32917
|
+
"a:clrScheme": clrScheme,
|
|
32918
|
+
"a:fontScheme": fontScheme
|
|
32919
|
+
};
|
|
32920
|
+
if (fmtScheme !== void 0) {
|
|
32921
|
+
themeElements["a:fmtScheme"] = fmtScheme;
|
|
32922
|
+
} else {
|
|
32923
|
+
themeElements["a:fmtScheme"] = this.buildMinimalFmtScheme(themeName);
|
|
32924
|
+
}
|
|
32925
|
+
const themeRoot = {
|
|
32926
|
+
"@_xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
|
|
32927
|
+
"@_name": themeName,
|
|
32928
|
+
"a:themeElements": themeElements
|
|
32929
|
+
};
|
|
32930
|
+
const objectDefaults = this.masterThemeObjectDefaults.get(themePath);
|
|
32931
|
+
if (objectDefaults && (objectDefaults.spDef || objectDefaults.lnDef || objectDefaults.txDef)) {
|
|
32932
|
+
const od = {};
|
|
32933
|
+
if (objectDefaults.spDef !== void 0) {
|
|
32934
|
+
od["a:spDef"] = objectDefaults.spDef;
|
|
32935
|
+
}
|
|
32936
|
+
if (objectDefaults.lnDef !== void 0) {
|
|
32937
|
+
od["a:lnDef"] = objectDefaults.lnDef;
|
|
32938
|
+
}
|
|
32939
|
+
if (objectDefaults.txDef !== void 0) {
|
|
32940
|
+
od["a:txDef"] = objectDefaults.txDef;
|
|
32941
|
+
}
|
|
32942
|
+
themeRoot["a:objectDefaults"] = od;
|
|
32943
|
+
} else {
|
|
32944
|
+
themeRoot["a:objectDefaults"] = {};
|
|
32945
|
+
}
|
|
32946
|
+
const extraClr = this.masterThemeExtraClrSchemeLst.get(themePath);
|
|
32947
|
+
themeRoot["a:extraClrSchemeLst"] = extraClr !== void 0 ? extraClr : {};
|
|
32948
|
+
const custClr = this.masterThemeCustClrLst.get(themePath);
|
|
32949
|
+
if (custClr !== void 0) {
|
|
32950
|
+
themeRoot["a:custClrLst"] = custClr;
|
|
32951
|
+
}
|
|
32952
|
+
const themeExt = this.masterThemeExtLst.get(themePath);
|
|
32953
|
+
if (themeExt !== void 0) {
|
|
32954
|
+
themeRoot["a:extLst"] = themeExt;
|
|
32955
|
+
}
|
|
32956
|
+
const doc = {
|
|
32957
|
+
"?xml": { "@_version": "1.0", "@_encoding": "UTF-8", "@_standalone": "yes" },
|
|
32958
|
+
"a:theme": themeRoot
|
|
32959
|
+
};
|
|
32960
|
+
try {
|
|
32961
|
+
return this.builder.build(doc);
|
|
32962
|
+
} catch (error) {
|
|
32963
|
+
console.warn(`Failed to build theme XML for ${themePath}:`, error);
|
|
32964
|
+
return void 0;
|
|
32965
|
+
}
|
|
32966
|
+
}
|
|
32967
|
+
/**
|
|
32968
|
+
* Build the `a:clrScheme` XmlObject from a colour map. Each slot
|
|
32969
|
+
* value is interpreted as either a `#RRGGBB` srgb hex or a known
|
|
32970
|
+
* sysClr token (currently always emitted as srgbClr — the in-memory
|
|
32971
|
+
* map is hex-typed; sysClr round-trip belongs to the broader C-H3
|
|
32972
|
+
* fix to preserve original color XML and is out of scope here).
|
|
32973
|
+
*/
|
|
32974
|
+
buildClrSchemeObject(schemeName, colorMap) {
|
|
32975
|
+
const slot = (key) => {
|
|
32976
|
+
const hex = String(colorMap[key] || "").replace(/^#/, "");
|
|
32977
|
+
const srgb = hex.length === 6 ? hex.toUpperCase() : "000000";
|
|
32978
|
+
return { "a:srgbClr": { "@_val": srgb } };
|
|
32979
|
+
};
|
|
32980
|
+
return {
|
|
32981
|
+
"@_name": schemeName,
|
|
32982
|
+
"a:dk1": slot("dk1"),
|
|
32983
|
+
"a:lt1": slot("lt1"),
|
|
32984
|
+
"a:dk2": slot("dk2"),
|
|
32985
|
+
"a:lt2": slot("lt2"),
|
|
32986
|
+
"a:accent1": slot("accent1"),
|
|
32987
|
+
"a:accent2": slot("accent2"),
|
|
32988
|
+
"a:accent3": slot("accent3"),
|
|
32989
|
+
"a:accent4": slot("accent4"),
|
|
32990
|
+
"a:accent5": slot("accent5"),
|
|
32991
|
+
"a:accent6": slot("accent6"),
|
|
32992
|
+
"a:hlink": slot("hlink"),
|
|
32993
|
+
"a:folHlink": slot("folHlink")
|
|
32994
|
+
};
|
|
32995
|
+
}
|
|
32996
|
+
/**
|
|
32997
|
+
* Build the `a:fontScheme` XmlObject from a font map plus per-script
|
|
32998
|
+
* font tables.
|
|
32999
|
+
*
|
|
33000
|
+
* Phase 4 Stream A / M4.
|
|
33001
|
+
*/
|
|
33002
|
+
buildFontSchemeObject(schemeName, fontMap, majorScripts, minorScripts) {
|
|
33003
|
+
const buildFontGroup = (latinKey, eaKey, csKey, scripts) => {
|
|
33004
|
+
const group = {
|
|
33005
|
+
"a:latin": { "@_typeface": fontMap[latinKey] || "Calibri" },
|
|
33006
|
+
"a:ea": { "@_typeface": fontMap[eaKey] || "" },
|
|
33007
|
+
"a:cs": { "@_typeface": fontMap[csKey] || "" }
|
|
33008
|
+
};
|
|
33009
|
+
const scriptKeys = Object.keys(scripts);
|
|
33010
|
+
if (scriptKeys.length > 0) {
|
|
33011
|
+
const fontEntries = scriptKeys.map((script) => ({
|
|
33012
|
+
"@_script": script,
|
|
33013
|
+
"@_typeface": scripts[script]
|
|
33014
|
+
}));
|
|
33015
|
+
group["a:font"] = fontEntries.length === 1 ? fontEntries[0] : fontEntries;
|
|
33016
|
+
}
|
|
33017
|
+
return group;
|
|
33018
|
+
};
|
|
33019
|
+
return {
|
|
33020
|
+
"@_name": schemeName,
|
|
33021
|
+
"a:majorFont": buildFontGroup("mj-lt", "mj-ea", "mj-cs", majorScripts),
|
|
33022
|
+
"a:minorFont": buildFontGroup("mn-lt", "mn-ea", "mn-cs", minorScripts)
|
|
33023
|
+
};
|
|
33024
|
+
}
|
|
33025
|
+
/**
|
|
33026
|
+
* Re-parse the original theme XML and pluck out a subtree by path,
|
|
33027
|
+
* returning the raw parser object. Returns `undefined` when the
|
|
33028
|
+
* original is missing or the path doesn't exist.
|
|
33029
|
+
*
|
|
33030
|
+
* Used to preserve `a:fmtScheme` byte-for-byte through a regenerate
|
|
33031
|
+
* round-trip, since the in-memory PptxThemeFormatScheme is lossy.
|
|
33032
|
+
*/
|
|
33033
|
+
extractRawSubtreeFromOriginal(themePath, path2) {
|
|
33034
|
+
const original = this.originalThemeXmlByPath.get(themePath);
|
|
33035
|
+
if (!original) {
|
|
33036
|
+
return void 0;
|
|
33037
|
+
}
|
|
33038
|
+
try {
|
|
33039
|
+
const parsed = this.parser.parse(original);
|
|
33040
|
+
let cursor = parsed;
|
|
33041
|
+
for (const segment of path2) {
|
|
33042
|
+
if (cursor && typeof cursor === "object" && segment in cursor) {
|
|
33043
|
+
cursor = cursor[segment];
|
|
33044
|
+
} else {
|
|
33045
|
+
return void 0;
|
|
33046
|
+
}
|
|
33047
|
+
}
|
|
33048
|
+
return cursor;
|
|
33049
|
+
} catch {
|
|
33050
|
+
return void 0;
|
|
33051
|
+
}
|
|
33052
|
+
}
|
|
33053
|
+
/**
|
|
33054
|
+
* Last-resort minimal `<a:fmtScheme>` body. Mirrors the SDK new-deck
|
|
33055
|
+
* builder's output for new presentations, scaled down to the smallest
|
|
33056
|
+
* schema-valid form.
|
|
33057
|
+
*/
|
|
33058
|
+
buildMinimalFmtScheme(name) {
|
|
33059
|
+
const phClrSolid = { "a:solidFill": { "a:schemeClr": { "@_val": "phClr" } } };
|
|
33060
|
+
return {
|
|
33061
|
+
"@_name": name,
|
|
33062
|
+
"a:fillStyleLst": {
|
|
33063
|
+
"a:solidFill": [{ "a:schemeClr": { "@_val": "phClr" } }],
|
|
33064
|
+
"a:gradFill": []
|
|
33065
|
+
},
|
|
33066
|
+
"a:lnStyleLst": {
|
|
33067
|
+
"a:ln": [
|
|
33068
|
+
{
|
|
33069
|
+
"@_w": "6350",
|
|
33070
|
+
"@_cap": "flat",
|
|
33071
|
+
"@_cmpd": "sng",
|
|
33072
|
+
"@_algn": "ctr",
|
|
33073
|
+
...phClrSolid,
|
|
33074
|
+
"a:prstDash": { "@_val": "solid" },
|
|
33075
|
+
"a:miter": { "@_lim": "800000" }
|
|
33076
|
+
},
|
|
33077
|
+
{
|
|
33078
|
+
"@_w": "12700",
|
|
33079
|
+
"@_cap": "flat",
|
|
33080
|
+
"@_cmpd": "sng",
|
|
33081
|
+
"@_algn": "ctr",
|
|
33082
|
+
...phClrSolid,
|
|
33083
|
+
"a:prstDash": { "@_val": "solid" },
|
|
33084
|
+
"a:miter": { "@_lim": "800000" }
|
|
33085
|
+
},
|
|
33086
|
+
{
|
|
33087
|
+
"@_w": "19050",
|
|
33088
|
+
"@_cap": "flat",
|
|
33089
|
+
"@_cmpd": "sng",
|
|
33090
|
+
"@_algn": "ctr",
|
|
33091
|
+
...phClrSolid,
|
|
33092
|
+
"a:prstDash": { "@_val": "solid" },
|
|
33093
|
+
"a:miter": { "@_lim": "800000" }
|
|
33094
|
+
}
|
|
33095
|
+
]
|
|
33096
|
+
},
|
|
33097
|
+
"a:effectStyleLst": {
|
|
33098
|
+
"a:effectStyle": [{ "a:effectLst": {} }, { "a:effectLst": {} }, { "a:effectLst": {} }]
|
|
33099
|
+
},
|
|
33100
|
+
"a:bgFillStyleLst": {
|
|
33101
|
+
"a:solidFill": [{ "a:schemeClr": { "@_val": "phClr" } }],
|
|
33102
|
+
"a:gradFill": []
|
|
33103
|
+
}
|
|
33104
|
+
};
|
|
33105
|
+
}
|
|
31202
33106
|
};
|
|
31203
33107
|
|
|
31204
33108
|
// src/core/core/runtime/PptxHandlerRuntimeSavePipeline.ts
|
|
31205
|
-
var
|
|
33109
|
+
var PptxHandlerRuntime35 = class _PptxHandlerRuntime extends PptxHandlerRuntime34 {
|
|
31206
33110
|
/**
|
|
31207
33111
|
* Resolve the effective conformance class for this save operation.
|
|
31208
33112
|
*
|
|
@@ -31289,6 +33193,7 @@ var PptxHandlerRuntime34 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
31289
33193
|
for (const [masterPath, masterXmlObj] of this.masterXmlMap.entries()) {
|
|
31290
33194
|
this.zip.file(masterPath, this.builder.build(masterXmlObj));
|
|
31291
33195
|
}
|
|
33196
|
+
await this.persistThemeParts();
|
|
31292
33197
|
await this.applyEmbeddedFontPreservation(options?.embeddedFonts);
|
|
31293
33198
|
if (this.presentationData) {
|
|
31294
33199
|
this.presentationSaveBuilder.applySaveOptions({
|
|
@@ -31378,7 +33283,7 @@ var PptxHandlerRuntime34 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
31378
33283
|
};
|
|
31379
33284
|
|
|
31380
33285
|
// src/core/core/runtime/PptxHandlerRuntimeElementParsing.ts
|
|
31381
|
-
var
|
|
33286
|
+
var PptxHandlerRuntime36 = class _PptxHandlerRuntime extends PptxHandlerRuntime35 {
|
|
31382
33287
|
/**
|
|
31383
33288
|
* Parse media data (video/audio path and MIME type) from graphic frame data.
|
|
31384
33289
|
*/
|
|
@@ -31600,7 +33505,7 @@ var PptxHandlerRuntime35 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
31600
33505
|
};
|
|
31601
33506
|
|
|
31602
33507
|
// src/core/core/runtime/PptxHandlerRuntimePlaceholderLookup.ts
|
|
31603
|
-
var
|
|
33508
|
+
var PptxHandlerRuntime37 = class extends PptxHandlerRuntime36 {
|
|
31604
33509
|
findPlaceholderInShapeTree(spTree, expected) {
|
|
31605
33510
|
if (!spTree) {
|
|
31606
33511
|
return void 0;
|
|
@@ -31753,7 +33658,7 @@ var PptxHandlerRuntime36 = class extends PptxHandlerRuntime35 {
|
|
|
31753
33658
|
};
|
|
31754
33659
|
|
|
31755
33660
|
// src/core/core/runtime/PptxHandlerRuntimeGeometryParsing.ts
|
|
31756
|
-
var
|
|
33661
|
+
var PptxHandlerRuntime38 = class extends PptxHandlerRuntime37 {
|
|
31757
33662
|
parseGeometryAdjustments(prstGeom) {
|
|
31758
33663
|
if (!prstGeom) {
|
|
31759
33664
|
return void 0;
|
|
@@ -31862,6 +33767,103 @@ var PptxHandlerRuntime37 = class extends PptxHandlerRuntime36 {
|
|
|
31862
33767
|
}
|
|
31863
33768
|
return handles.length > 0 ? handles : void 0;
|
|
31864
33769
|
}
|
|
33770
|
+
/**
|
|
33771
|
+
* Extract `a:gdLst`/`a:ahLst`/`a:cxnLst`/`a:rect` raw XML from a `a:custGeom`
|
|
33772
|
+
* node so they can be re-emitted on save when the geometry is edited.
|
|
33773
|
+
* Returns `undefined` when none of these auxiliary children carry data.
|
|
33774
|
+
*/
|
|
33775
|
+
extractCustomGeometryRawData(custGeom) {
|
|
33776
|
+
if (!custGeom) {
|
|
33777
|
+
return void 0;
|
|
33778
|
+
}
|
|
33779
|
+
const isNonEmpty = (node) => {
|
|
33780
|
+
if (node === void 0 || node === null) {
|
|
33781
|
+
return false;
|
|
33782
|
+
}
|
|
33783
|
+
if (typeof node !== "object") {
|
|
33784
|
+
return true;
|
|
33785
|
+
}
|
|
33786
|
+
return Object.keys(node).length > 0;
|
|
33787
|
+
};
|
|
33788
|
+
const result = {};
|
|
33789
|
+
const gdLst = custGeom["a:gdLst"];
|
|
33790
|
+
if (isNonEmpty(gdLst)) {
|
|
33791
|
+
result.gdLstXml = gdLst;
|
|
33792
|
+
}
|
|
33793
|
+
const ahLst = custGeom["a:ahLst"];
|
|
33794
|
+
if (isNonEmpty(ahLst)) {
|
|
33795
|
+
result.ahLstXml = ahLst;
|
|
33796
|
+
}
|
|
33797
|
+
const cxnLst = custGeom["a:cxnLst"];
|
|
33798
|
+
if (isNonEmpty(cxnLst)) {
|
|
33799
|
+
result.cxnLstXml = cxnLst;
|
|
33800
|
+
}
|
|
33801
|
+
const rect = custGeom["a:rect"];
|
|
33802
|
+
if (isNonEmpty(rect)) {
|
|
33803
|
+
result.rectXml = rect;
|
|
33804
|
+
}
|
|
33805
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
33806
|
+
}
|
|
33807
|
+
/**
|
|
33808
|
+
* Build structured `CustomGeometryPath[]` from a parsed `a:custGeom` node,
|
|
33809
|
+
* including per-path `@fill`/`@stroke`/`@extrusionOk` attributes so they
|
|
33810
|
+
* survive a round-trip when the path list is later regenerated.
|
|
33811
|
+
*
|
|
33812
|
+
* Falls back to SVG → structured-path conversion when no structured path
|
|
33813
|
+
* info is otherwise available.
|
|
33814
|
+
*/
|
|
33815
|
+
buildStructuredCustomGeometryPaths(custGeom, pathData, pathWidth, pathHeight) {
|
|
33816
|
+
if (!custGeom) {
|
|
33817
|
+
return void 0;
|
|
33818
|
+
}
|
|
33819
|
+
const pathLst = custGeom["a:pathLst"];
|
|
33820
|
+
if (!pathLst) {
|
|
33821
|
+
return void 0;
|
|
33822
|
+
}
|
|
33823
|
+
const pathNodes = this.ensureArray(pathLst["a:path"]);
|
|
33824
|
+
if (pathNodes.length === 0) {
|
|
33825
|
+
return void 0;
|
|
33826
|
+
}
|
|
33827
|
+
const segments = svgToCustomGeometryPaths(pathData, pathWidth, pathHeight);
|
|
33828
|
+
if (segments.length === 0) {
|
|
33829
|
+
return void 0;
|
|
33830
|
+
}
|
|
33831
|
+
const validFillModes = /* @__PURE__ */ new Set([
|
|
33832
|
+
"norm",
|
|
33833
|
+
"lighten",
|
|
33834
|
+
"lightenLess",
|
|
33835
|
+
"darken",
|
|
33836
|
+
"darkenLess",
|
|
33837
|
+
"none"
|
|
33838
|
+
]);
|
|
33839
|
+
const parseBoolAttr2 = (value) => {
|
|
33840
|
+
if (value === void 0 || value === null || value === "") {
|
|
33841
|
+
return void 0;
|
|
33842
|
+
}
|
|
33843
|
+
if (value === "1" || value === "true" || value === true) {
|
|
33844
|
+
return true;
|
|
33845
|
+
}
|
|
33846
|
+
if (value === "0" || value === "false" || value === false) {
|
|
33847
|
+
return false;
|
|
33848
|
+
}
|
|
33849
|
+
return void 0;
|
|
33850
|
+
};
|
|
33851
|
+
const target = segments[0];
|
|
33852
|
+
const firstNode = pathNodes[0];
|
|
33853
|
+
const fillAttr = String(firstNode["@_fill"] ?? "").trim();
|
|
33854
|
+
if (validFillModes.has(fillAttr)) {
|
|
33855
|
+
target.fillMode = fillAttr;
|
|
33856
|
+
}
|
|
33857
|
+
const strokeAttr = parseBoolAttr2(firstNode["@_stroke"]);
|
|
33858
|
+
if (strokeAttr !== void 0) {
|
|
33859
|
+
target.stroke = strokeAttr;
|
|
33860
|
+
}
|
|
33861
|
+
const extrusionAttr = parseBoolAttr2(firstNode["@_extrusionOk"]);
|
|
33862
|
+
if (extrusionAttr !== void 0) {
|
|
33863
|
+
target.extrusionOk = extrusionAttr;
|
|
33864
|
+
}
|
|
33865
|
+
return segments;
|
|
33866
|
+
}
|
|
31865
33867
|
parseCustomGeometry(custGeom, shapeWidth, shapeHeight) {
|
|
31866
33868
|
if (!custGeom || !custGeom["a:pathLst"] || !custGeom["a:pathLst"]?.["a:path"]) {
|
|
31867
33869
|
return null;
|
|
@@ -31930,7 +33932,7 @@ var PptxHandlerRuntime37 = class extends PptxHandlerRuntime36 {
|
|
|
31930
33932
|
};
|
|
31931
33933
|
|
|
31932
33934
|
// src/core/core/runtime/PptxHandlerRuntimeShapeImageFill.ts
|
|
31933
|
-
var
|
|
33935
|
+
var PptxHandlerRuntime39 = class _PptxHandlerRuntime extends PptxHandlerRuntime38 {
|
|
31934
33936
|
/**
|
|
31935
33937
|
* Parse a shape that has an image fill (a:blipFill inside spPr)
|
|
31936
33938
|
* This handles shapes like rectangles filled with images (e.g., wood texture backgrounds)
|
|
@@ -32130,7 +34132,7 @@ var PptxHandlerRuntime38 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
32130
34132
|
};
|
|
32131
34133
|
|
|
32132
34134
|
// src/core/core/runtime/PptxHandlerRuntimeTextDefaults.ts
|
|
32133
|
-
var
|
|
34135
|
+
var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
32134
34136
|
/**
|
|
32135
34137
|
* Apply {@link PlaceholderDefaults} body-level properties to a
|
|
32136
34138
|
* {@link TextStyle} as fallback values (only sets fields that are
|
|
@@ -32254,7 +34256,7 @@ var PptxHandlerRuntime39 = class extends PptxHandlerRuntime38 {
|
|
|
32254
34256
|
};
|
|
32255
34257
|
|
|
32256
34258
|
// src/core/core/runtime/PptxHandlerRuntimeBulletParsing.ts
|
|
32257
|
-
var
|
|
34259
|
+
var PptxHandlerRuntime41 = class extends PptxHandlerRuntime40 {
|
|
32258
34260
|
resolveParagraphBulletInfo(paragraph, paragraphIndex, txBody, inheritedTxBody, isBodyPlaceholder = false, slidePath) {
|
|
32259
34261
|
if (!paragraph) {
|
|
32260
34262
|
return null;
|
|
@@ -32285,7 +34287,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32285
34287
|
if (candidate["a:buNone"]) {
|
|
32286
34288
|
return { none: true };
|
|
32287
34289
|
}
|
|
32288
|
-
if (candidate["a:buChar"] || candidate["a:buAutoNum"] || candidate["a:buBlip"]) {
|
|
34290
|
+
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) {
|
|
32289
34291
|
resolvedBulletProps = candidate;
|
|
32290
34292
|
break;
|
|
32291
34293
|
}
|
|
@@ -32299,6 +34301,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32299
34301
|
}
|
|
32300
34302
|
const buFont = resolvedBulletProps["a:buFont"];
|
|
32301
34303
|
const fontFamily = buFont?.["@_typeface"] ? String(buFont["@_typeface"]) : void 0;
|
|
34304
|
+
const fontInherit = resolvedBulletProps["a:buFontTx"] !== void 0;
|
|
32302
34305
|
const buSzPct = resolvedBulletProps["a:buSzPct"];
|
|
32303
34306
|
let sizePercent;
|
|
32304
34307
|
if (buSzPct?.["@_val"] !== void 0) {
|
|
@@ -32315,6 +34318,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32315
34318
|
sizePts = ptsRaw / 100;
|
|
32316
34319
|
}
|
|
32317
34320
|
}
|
|
34321
|
+
const sizeInherit = resolvedBulletProps["a:buSzTx"] !== void 0;
|
|
32318
34322
|
const buClr = resolvedBulletProps["a:buClr"];
|
|
32319
34323
|
let color;
|
|
32320
34324
|
if (buClr) {
|
|
@@ -32323,6 +34327,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32323
34327
|
color = String(srgb["@_val"]);
|
|
32324
34328
|
}
|
|
32325
34329
|
}
|
|
34330
|
+
const colorInherit = resolvedBulletProps["a:buClrTx"] !== void 0;
|
|
32326
34331
|
const bulletChar = String(
|
|
32327
34332
|
resolvedBulletProps["a:buChar"]?.["@_char"] || ""
|
|
32328
34333
|
);
|
|
@@ -32332,7 +34337,10 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32332
34337
|
fontFamily,
|
|
32333
34338
|
sizePercent,
|
|
32334
34339
|
sizePts,
|
|
32335
|
-
color
|
|
34340
|
+
color,
|
|
34341
|
+
...fontInherit ? { fontInherit: true } : {},
|
|
34342
|
+
...colorInherit ? { colorInherit: true } : {},
|
|
34343
|
+
...sizeInherit ? { sizeInherit: true } : {}
|
|
32336
34344
|
};
|
|
32337
34345
|
}
|
|
32338
34346
|
const autoNum = resolvedBulletProps["a:buAutoNum"];
|
|
@@ -32347,7 +34355,10 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32347
34355
|
fontFamily,
|
|
32348
34356
|
sizePercent,
|
|
32349
34357
|
sizePts,
|
|
32350
|
-
color
|
|
34358
|
+
color,
|
|
34359
|
+
...fontInherit ? { fontInherit: true } : {},
|
|
34360
|
+
...colorInherit ? { colorInherit: true } : {},
|
|
34361
|
+
...sizeInherit ? { sizeInherit: true } : {}
|
|
32351
34362
|
};
|
|
32352
34363
|
}
|
|
32353
34364
|
const buBlip = resolvedBulletProps["a:buBlip"];
|
|
@@ -32459,7 +34470,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32459
34470
|
};
|
|
32460
34471
|
|
|
32461
34472
|
// src/core/core/runtime/PptxHandlerRuntimeShapeBodyParsing.ts
|
|
32462
|
-
var
|
|
34473
|
+
var PptxHandlerRuntime42 = class _PptxHandlerRuntime extends PptxHandlerRuntime41 {
|
|
32463
34474
|
/**
|
|
32464
34475
|
* Parse `a:spLocks` attributes into a structured {@link PptxShapeLocks} object.
|
|
32465
34476
|
* Returns `undefined` when the node is absent or contains no lock attributes.
|
|
@@ -32554,7 +34565,8 @@ var PptxHandlerRuntime41 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
32554
34565
|
if (Number.isFinite(spcColRaw) && spcColRaw > 0) {
|
|
32555
34566
|
textStyle.columnSpacing = spcColRaw / _PptxHandlerRuntime.EMU_PER_PX;
|
|
32556
34567
|
}
|
|
32557
|
-
const
|
|
34568
|
+
const hOverflowRaw = bodyPr["@_horzOverflow"] ?? bodyPr["@_hOverflow"];
|
|
34569
|
+
const hOverflow = String(hOverflowRaw || "").trim();
|
|
32558
34570
|
if (hOverflow === "overflow" || hOverflow === "clip") {
|
|
32559
34571
|
textStyle.hOverflow = hOverflow;
|
|
32560
34572
|
}
|
|
@@ -32737,7 +34749,7 @@ var PptxHandlerRuntime41 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
32737
34749
|
};
|
|
32738
34750
|
|
|
32739
34751
|
// src/core/core/runtime/PptxHandlerRuntimeShapeTextParsing.ts
|
|
32740
|
-
var
|
|
34752
|
+
var PptxHandlerRuntime43 = class _PptxHandlerRuntime extends PptxHandlerRuntime42 {
|
|
32741
34753
|
/**
|
|
32742
34754
|
* Resolve paragraph-level styles (alignment, spacing, margins, tabs,
|
|
32743
34755
|
* level styles) for a single paragraph. Modifies `textStyle` in place
|
|
@@ -32919,7 +34931,7 @@ var PptxHandlerRuntime42 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
32919
34931
|
};
|
|
32920
34932
|
|
|
32921
34933
|
// src/core/core/runtime/PptxHandlerRuntimeShapeParagraphContentParsing.ts
|
|
32922
|
-
var
|
|
34934
|
+
var PptxHandlerRuntime44 = class extends PptxHandlerRuntime43 {
|
|
32923
34935
|
/**
|
|
32924
34936
|
* Collect text content (runs, fields, equations, bullets) for a single
|
|
32925
34937
|
* paragraph and return text parts + segments. The returned `seedStyle`
|
|
@@ -33102,6 +35114,23 @@ var PptxHandlerRuntime43 = class extends PptxHandlerRuntime42 {
|
|
|
33102
35114
|
parts.push("\n");
|
|
33103
35115
|
segments.push({ text: "\n", style: { ...mergedDefaultRunStyle } });
|
|
33104
35116
|
}
|
|
35117
|
+
const firstSegmentIndex = segments.length === 0 ? -1 : 0;
|
|
35118
|
+
if (firstSegmentIndex >= 0) {
|
|
35119
|
+
const pPrRaw = p["a:pPr"];
|
|
35120
|
+
const lvlRaw = pPrRaw?.["@_lvl"];
|
|
35121
|
+
if (lvlRaw !== void 0) {
|
|
35122
|
+
const lvlParsed = Number.parseInt(String(lvlRaw), 10);
|
|
35123
|
+
if (Number.isFinite(lvlParsed) && lvlParsed > 0) {
|
|
35124
|
+
segments[firstSegmentIndex].paragraphLevel = Math.min(Math.max(lvlParsed, 0), 8);
|
|
35125
|
+
}
|
|
35126
|
+
}
|
|
35127
|
+
const endParaRPrRaw = p["a:endParaRPr"];
|
|
35128
|
+
if (endParaRPrRaw && typeof endParaRPrRaw === "object") {
|
|
35129
|
+
segments[firstSegmentIndex].endParaRunProperties = {
|
|
35130
|
+
...endParaRPrRaw
|
|
35131
|
+
};
|
|
35132
|
+
}
|
|
35133
|
+
}
|
|
33105
35134
|
return { parts, segments, seedStyle };
|
|
33106
35135
|
}
|
|
33107
35136
|
/**
|
|
@@ -33211,7 +35240,7 @@ var PptxHandlerRuntime43 = class extends PptxHandlerRuntime42 {
|
|
|
33211
35240
|
};
|
|
33212
35241
|
|
|
33213
35242
|
// src/core/core/runtime/PptxHandlerRuntimeShapeParsing.ts
|
|
33214
|
-
var
|
|
35243
|
+
var PptxHandlerRuntime45 = class _PptxHandlerRuntime extends PptxHandlerRuntime44 {
|
|
33215
35244
|
parseShape(shape, id, slidePath) {
|
|
33216
35245
|
try {
|
|
33217
35246
|
const spPr = shape["p:spPr"];
|
|
@@ -33247,6 +35276,7 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33247
35276
|
let pathData;
|
|
33248
35277
|
let pathWidth;
|
|
33249
35278
|
let pathHeight;
|
|
35279
|
+
let customGeometryRawData;
|
|
33250
35280
|
const custGeom = effectiveSpPr?.["a:custGeom"];
|
|
33251
35281
|
if (custGeom) {
|
|
33252
35282
|
const customPath = this.parseCustomGeometry(
|
|
@@ -33259,6 +35289,7 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33259
35289
|
pathData = customPath.pathData;
|
|
33260
35290
|
pathWidth = customPath.pathWidth;
|
|
33261
35291
|
pathHeight = customPath.pathHeight;
|
|
35292
|
+
customGeometryRawData = this.extractCustomGeometryRawData(custGeom);
|
|
33262
35293
|
}
|
|
33263
35294
|
}
|
|
33264
35295
|
const geomNode = custGeom ?? effectiveSpPr?.["a:prstGeom"];
|
|
@@ -33416,7 +35447,8 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33416
35447
|
type: "shape",
|
|
33417
35448
|
pathData,
|
|
33418
35449
|
pathWidth,
|
|
33419
|
-
pathHeight
|
|
35450
|
+
pathHeight,
|
|
35451
|
+
customGeometryRawData
|
|
33420
35452
|
};
|
|
33421
35453
|
} catch (e) {
|
|
33422
35454
|
console.warn(`[pptx] Skipping shape element (${id}):`, e);
|
|
@@ -33426,7 +35458,7 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33426
35458
|
};
|
|
33427
35459
|
|
|
33428
35460
|
// src/core/core/runtime/PptxHandlerRuntimePictureParsing.ts
|
|
33429
|
-
var
|
|
35461
|
+
var PptxHandlerRuntime46 = class _PptxHandlerRuntime extends PptxHandlerRuntime45 {
|
|
33430
35462
|
async parsePicture(pic, id, slidePath) {
|
|
33431
35463
|
try {
|
|
33432
35464
|
const spPr = pic["p:spPr"];
|
|
@@ -33665,7 +35697,7 @@ var PptxHandlerRuntime45 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33665
35697
|
};
|
|
33666
35698
|
|
|
33667
35699
|
// src/core/core/runtime/PptxHandlerRuntimeSpTreeParsing.ts
|
|
33668
|
-
var
|
|
35700
|
+
var PptxHandlerRuntime47 = class _PptxHandlerRuntime extends PptxHandlerRuntime46 {
|
|
33669
35701
|
/**
|
|
33670
35702
|
* Known element tag names that appear as direct children of `p:spTree`
|
|
33671
35703
|
* (or `p:grpSp`) and represent renderable shapes/objects.
|
|
@@ -34010,9 +36042,18 @@ var PptxHandlerRuntime46 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
34010
36042
|
* Unwrap mc:AlternateContent elements within a shape tree (or group),
|
|
34011
36043
|
* merging selected branch children into the parent element arrays.
|
|
34012
36044
|
* Delegates to the standalone alternate-content utility.
|
|
36045
|
+
*
|
|
36046
|
+
* Records each consumed AC envelope in {@link alternateContentBlockByRawXml}
|
|
36047
|
+
* so the save layer can re-emit the original `<mc:Choice>` /
|
|
36048
|
+
* `<mc:Fallback>` shape on dirty save (CC-4).
|
|
34013
36049
|
*/
|
|
34014
36050
|
unwrapAlternateContent(container) {
|
|
34015
|
-
unwrapAlternateContent(container);
|
|
36051
|
+
const blocks = unwrapAlternateContent(container);
|
|
36052
|
+
for (const block of blocks) {
|
|
36053
|
+
for (const ref of block.childRefs) {
|
|
36054
|
+
this.alternateContentBlockByRawXml.set(ref.node, block);
|
|
36055
|
+
}
|
|
36056
|
+
}
|
|
34016
36057
|
}
|
|
34017
36058
|
/**
|
|
34018
36059
|
* Forward declaration – implemented in PptxHandlerRuntimeGroupParsing.
|
|
@@ -34023,7 +36064,7 @@ var PptxHandlerRuntime46 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
34023
36064
|
};
|
|
34024
36065
|
|
|
34025
36066
|
// src/core/core/runtime/PptxHandlerRuntimeGroupParsing.ts
|
|
34026
|
-
var
|
|
36067
|
+
var PptxHandlerRuntime48 = class _PptxHandlerRuntime extends PptxHandlerRuntime47 {
|
|
34027
36068
|
async parseGroupShape(group, baseId, slidePath, rawXmlStr) {
|
|
34028
36069
|
const grpSpPr = group["p:grpSpPr"];
|
|
34029
36070
|
const xfrm = grpSpPr?.["a:xfrm"];
|
|
@@ -34196,7 +36237,7 @@ var PptxHandlerRuntime47 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
34196
36237
|
};
|
|
34197
36238
|
|
|
34198
36239
|
// src/core/core/runtime/PptxHandlerRuntimeSlideParsing.ts
|
|
34199
|
-
var
|
|
36240
|
+
var PptxHandlerRuntime49 = class extends PptxHandlerRuntime48 {
|
|
34200
36241
|
/**
|
|
34201
36242
|
* Parse text body from a connector shape (p:cxnSp > p:txBody).
|
|
34202
36243
|
* Uses the same text run extraction logic as regular shapes but
|
|
@@ -34308,7 +36349,7 @@ var PptxHandlerRuntime48 = class extends PptxHandlerRuntime47 {
|
|
|
34308
36349
|
};
|
|
34309
36350
|
|
|
34310
36351
|
// src/core/core/runtime/PptxHandlerRuntimeColorAndEffects.ts
|
|
34311
|
-
var
|
|
36352
|
+
var PptxHandlerRuntime50 = class extends PptxHandlerRuntime49 {
|
|
34312
36353
|
/**
|
|
34313
36354
|
* Forward declaration – implemented in PptxHandlerRuntimeThemeProcessing.
|
|
34314
36355
|
* Re-resolves gradient stops by substituting `phClr` with the given colour.
|
|
@@ -34349,8 +36390,9 @@ var PptxHandlerRuntime49 = class extends PptxHandlerRuntime48 {
|
|
|
34349
36390
|
return void 0;
|
|
34350
36391
|
}
|
|
34351
36392
|
const resolvedKey = normalized === "phclr" ? "accent1" : normalized;
|
|
34352
|
-
|
|
34353
|
-
|
|
36393
|
+
const overrideMap = this.currentSlideClrMapOverride ?? this.currentMasterClrMap;
|
|
36394
|
+
if (overrideMap) {
|
|
36395
|
+
const remapped = overrideMap[resolvedKey];
|
|
34354
36396
|
if (remapped) {
|
|
34355
36397
|
return this.themeColorMap[remapped] || this.getDefaultSchemeColorMap()[remapped];
|
|
34356
36398
|
}
|
|
@@ -34433,7 +36475,7 @@ var PptxHandlerRuntime49 = class extends PptxHandlerRuntime48 {
|
|
|
34433
36475
|
};
|
|
34434
36476
|
|
|
34435
36477
|
// src/core/core/runtime/PptxHandlerRuntimeBackgroundParsing.ts
|
|
34436
|
-
var
|
|
36478
|
+
var PptxHandlerRuntime51 = class extends PptxHandlerRuntime50 {
|
|
34437
36479
|
async extractBackgroundImage(slideXml2, slidePath, rootElement = "p:sld") {
|
|
34438
36480
|
try {
|
|
34439
36481
|
const bg = slideXml2[rootElement]?.["p:cSld"]?.["p:bg"];
|
|
@@ -34644,7 +36686,7 @@ var PptxHandlerRuntime50 = class extends PptxHandlerRuntime49 {
|
|
|
34644
36686
|
};
|
|
34645
36687
|
|
|
34646
36688
|
// src/core/core/runtime/PptxHandlerRuntimeSlideUtils.ts
|
|
34647
|
-
var
|
|
36689
|
+
var PptxHandlerRuntime52 = class extends PptxHandlerRuntime51 {
|
|
34648
36690
|
/**
|
|
34649
36691
|
* Retrieve the background gradient from a layout, falling back to master.
|
|
34650
36692
|
*/
|
|
@@ -34715,6 +36757,64 @@ var PptxHandlerRuntime51 = class extends PptxHandlerRuntime50 {
|
|
|
34715
36757
|
}
|
|
34716
36758
|
return void 0;
|
|
34717
36759
|
}
|
|
36760
|
+
/**
|
|
36761
|
+
* Find the master file path referenced by a layout via its relationships.
|
|
36762
|
+
*/
|
|
36763
|
+
findMasterPathForLayoutBase(layoutPath) {
|
|
36764
|
+
const layoutRels = this.slideRelsMap.get(layoutPath);
|
|
36765
|
+
if (!layoutRels) {
|
|
36766
|
+
return void 0;
|
|
36767
|
+
}
|
|
36768
|
+
for (const [, target] of layoutRels.entries()) {
|
|
36769
|
+
if (target.includes("slideMaster")) {
|
|
36770
|
+
const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
|
|
36771
|
+
return target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${target.replace("../", "")}`;
|
|
36772
|
+
}
|
|
36773
|
+
}
|
|
36774
|
+
return void 0;
|
|
36775
|
+
}
|
|
36776
|
+
/**
|
|
36777
|
+
* Switch the active master state (clrMap + theme color/font/format
|
|
36778
|
+
* scheme) so that scheme-colour resolution for the slide currently
|
|
36779
|
+
* being parsed walks through the correct master.
|
|
36780
|
+
*
|
|
36781
|
+
* Multi-master decks must resolve scheme colours against each slide's
|
|
36782
|
+
* own master rather than always against `masterFiles[0]`.
|
|
36783
|
+
*
|
|
36784
|
+
* Phase 2 Stream B / C-H4.
|
|
36785
|
+
*/
|
|
36786
|
+
async setActiveMasterForSlide(slidePath) {
|
|
36787
|
+
const layoutPath = this.findLayoutPathForSlide(slidePath);
|
|
36788
|
+
if (!layoutPath) {
|
|
36789
|
+
this.currentMasterClrMap = null;
|
|
36790
|
+
this.themeColorMap = { ...this.globalThemeColorMapSnapshot };
|
|
36791
|
+
this.themeFontMap = { ...this.globalThemeFontMapSnapshot };
|
|
36792
|
+
this.themeFormatScheme = this.globalThemeFormatSchemeSnapshot;
|
|
36793
|
+
return;
|
|
36794
|
+
}
|
|
36795
|
+
if (!this.slideRelsMap.has(layoutPath)) {
|
|
36796
|
+
const layoutRelsPath = `${layoutPath.replace("slideLayouts/", "slideLayouts/_rels/")}.rels`;
|
|
36797
|
+
try {
|
|
36798
|
+
await this.loadSlideRelationships(layoutPath, layoutRelsPath);
|
|
36799
|
+
} catch {
|
|
36800
|
+
}
|
|
36801
|
+
}
|
|
36802
|
+
const masterPath = this.findMasterPathForLayoutBase(layoutPath);
|
|
36803
|
+
if (!masterPath) {
|
|
36804
|
+
this.currentMasterClrMap = null;
|
|
36805
|
+
this.themeColorMap = { ...this.globalThemeColorMapSnapshot };
|
|
36806
|
+
this.themeFontMap = { ...this.globalThemeFontMapSnapshot };
|
|
36807
|
+
this.themeFormatScheme = this.globalThemeFormatSchemeSnapshot;
|
|
36808
|
+
return;
|
|
36809
|
+
}
|
|
36810
|
+
this.currentMasterClrMap = this.masterClrMaps.get(masterPath) ?? null;
|
|
36811
|
+
const masterColorMap = this.masterThemeColorMaps.get(masterPath);
|
|
36812
|
+
this.themeColorMap = masterColorMap ? { ...masterColorMap } : { ...this.globalThemeColorMapSnapshot };
|
|
36813
|
+
const masterFontMap = this.masterThemeFontMaps.get(masterPath);
|
|
36814
|
+
this.themeFontMap = masterFontMap ? { ...masterFontMap } : { ...this.globalThemeFontMapSnapshot };
|
|
36815
|
+
const masterFormatScheme = this.masterThemeFormatSchemes.get(masterPath);
|
|
36816
|
+
this.themeFormatScheme = masterFormatScheme ?? this.globalThemeFormatSchemeSnapshot;
|
|
36817
|
+
}
|
|
34718
36818
|
/**
|
|
34719
36819
|
* Extract the `p:bg/@showAnimation` flag from a slide's XML.
|
|
34720
36820
|
* Returns `true` when the background should animate, `false` when
|
|
@@ -34855,7 +36955,7 @@ var PptxHandlerRuntime51 = class extends PptxHandlerRuntime50 {
|
|
|
34855
36955
|
};
|
|
34856
36956
|
|
|
34857
36957
|
// src/core/core/runtime/PptxHandlerRuntimePlaceholderStyles.ts
|
|
34858
|
-
var
|
|
36958
|
+
var PptxHandlerRuntime53 = class _PptxHandlerRuntime extends PptxHandlerRuntime52 {
|
|
34859
36959
|
/**
|
|
34860
36960
|
* Parse a single `a:lvlXpPr` node into a structured
|
|
34861
36961
|
* {@link PlaceholderTextLevelStyle}.
|
|
@@ -34976,7 +37076,7 @@ var PptxHandlerRuntime52 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
|
|
|
34976
37076
|
};
|
|
34977
37077
|
|
|
34978
37078
|
// src/core/core/runtime/PptxHandlerRuntimePlaceholderDefaults.ts
|
|
34979
|
-
var
|
|
37079
|
+
var PptxHandlerRuntime54 = class _PptxHandlerRuntime extends PptxHandlerRuntime53 {
|
|
34980
37080
|
/**
|
|
34981
37081
|
* Extract structured {@link PlaceholderDefaults} from a layout or master
|
|
34982
37082
|
* shape that carries a `p:ph` element.
|
|
@@ -35119,7 +37219,118 @@ var PptxHandlerRuntime53 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
|
|
|
35119
37219
|
};
|
|
35120
37220
|
|
|
35121
37221
|
// src/core/core/runtime/PptxHandlerRuntimeMasterElements.ts
|
|
35122
|
-
|
|
37222
|
+
function parseHeaderFooterFlags(hf) {
|
|
37223
|
+
if (!hf) {
|
|
37224
|
+
return void 0;
|
|
37225
|
+
}
|
|
37226
|
+
const result = {};
|
|
37227
|
+
if (hf["@_hdr"] !== void 0) {
|
|
37228
|
+
result.hasHeader = String(hf["@_hdr"]) !== "0";
|
|
37229
|
+
}
|
|
37230
|
+
if (hf["@_ftr"] !== void 0) {
|
|
37231
|
+
result.hasFooter = String(hf["@_ftr"]) !== "0";
|
|
37232
|
+
}
|
|
37233
|
+
if (hf["@_dt"] !== void 0) {
|
|
37234
|
+
result.hasDateTime = String(hf["@_dt"]) !== "0";
|
|
37235
|
+
}
|
|
37236
|
+
if (hf["@_sldNum"] !== void 0) {
|
|
37237
|
+
result.hasSlideNumber = String(hf["@_sldNum"]) !== "0";
|
|
37238
|
+
}
|
|
37239
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
37240
|
+
}
|
|
37241
|
+
var PptxHandlerRuntime55 = class extends PptxHandlerRuntime54 {
|
|
37242
|
+
/**
|
|
37243
|
+
* Parse a `CT_TextListStyle` node (`a:defPPr` + `a:lvl1pPr` … `a:lvl9pPr`)
|
|
37244
|
+
* into a level-keyed style map. Used for `<p:txStyles>` children
|
|
37245
|
+
* (`p:titleStyle`, `p:bodyStyle`, `p:otherStyle`) — see ECMA-376 §19.3.1.52.
|
|
37246
|
+
*/
|
|
37247
|
+
parseTextListStyle(node) {
|
|
37248
|
+
if (!node) {
|
|
37249
|
+
return void 0;
|
|
37250
|
+
}
|
|
37251
|
+
const levels = {};
|
|
37252
|
+
const defParsed = this.parsePlaceholderLevelStyle(node["a:defPPr"]);
|
|
37253
|
+
if (defParsed) {
|
|
37254
|
+
levels[-1] = defParsed;
|
|
37255
|
+
}
|
|
37256
|
+
for (let lvl = 1; lvl <= 9; lvl++) {
|
|
37257
|
+
const parsed = this.parsePlaceholderLevelStyle(
|
|
37258
|
+
node[`a:lvl${lvl}pPr`]
|
|
37259
|
+
);
|
|
37260
|
+
if (parsed) {
|
|
37261
|
+
levels[lvl - 1] = parsed;
|
|
37262
|
+
}
|
|
37263
|
+
}
|
|
37264
|
+
return Object.keys(levels).length > 0 ? levels : void 0;
|
|
37265
|
+
}
|
|
37266
|
+
/**
|
|
37267
|
+
* Parse `<p:txStyles>` from a slide-master XML object into a structured
|
|
37268
|
+
* {@link PptxMasterTextStyles}. Used to populate `PptxSlideMaster.txStyles`
|
|
37269
|
+
* so the title/body/other text-style cascade (P-H1) is visible on the
|
|
37270
|
+
* typed model.
|
|
37271
|
+
*/
|
|
37272
|
+
parseMasterTxStyles(masterXml) {
|
|
37273
|
+
const txStyles = masterXml?.["p:txStyles"];
|
|
37274
|
+
if (!txStyles) {
|
|
37275
|
+
return void 0;
|
|
37276
|
+
}
|
|
37277
|
+
const titleStyle = this.parseTextListStyle(txStyles["p:titleStyle"]);
|
|
37278
|
+
const bodyStyle = this.parseTextListStyle(txStyles["p:bodyStyle"]);
|
|
37279
|
+
const otherStyle = this.parseTextListStyle(txStyles["p:otherStyle"]);
|
|
37280
|
+
if (!titleStyle && !bodyStyle && !otherStyle) {
|
|
37281
|
+
return void 0;
|
|
37282
|
+
}
|
|
37283
|
+
const result = {};
|
|
37284
|
+
if (titleStyle) {
|
|
37285
|
+
result.titleStyle = titleStyle;
|
|
37286
|
+
}
|
|
37287
|
+
if (bodyStyle) {
|
|
37288
|
+
result.bodyStyle = bodyStyle;
|
|
37289
|
+
}
|
|
37290
|
+
if (otherStyle) {
|
|
37291
|
+
result.otherStyle = otherStyle;
|
|
37292
|
+
}
|
|
37293
|
+
return result;
|
|
37294
|
+
}
|
|
37295
|
+
/**
|
|
37296
|
+
* Enrich an array of {@link PptxSlideMaster} entries (already produced by
|
|
37297
|
+
* `parseSlideMasters`) with parsed `<p:txStyles>`. Loads each master's XML
|
|
37298
|
+
* once, parses, and caches it in `masterXmlMap` for downstream consumers.
|
|
37299
|
+
*
|
|
37300
|
+
* Also stores the parsed result on the per-master cache so that the
|
|
37301
|
+
* inheritance chain in `applyMasterTextStyleCascade` can find it without
|
|
37302
|
+
* re-parsing.
|
|
37303
|
+
*/
|
|
37304
|
+
async enrichSlideMastersWithTxStyles(slideMasters) {
|
|
37305
|
+
for (const master of slideMasters) {
|
|
37306
|
+
try {
|
|
37307
|
+
let masterXmlObj = this.masterXmlMap.get(master.path);
|
|
37308
|
+
if (!masterXmlObj) {
|
|
37309
|
+
const xmlStr = await this.zip.file(master.path)?.async("string");
|
|
37310
|
+
if (!xmlStr) {
|
|
37311
|
+
continue;
|
|
37312
|
+
}
|
|
37313
|
+
masterXmlObj = this.parser.parse(xmlStr);
|
|
37314
|
+
this.masterXmlMap.set(master.path, masterXmlObj);
|
|
37315
|
+
}
|
|
37316
|
+
const sldMaster = masterXmlObj["p:sldMaster"];
|
|
37317
|
+
if (!sldMaster) {
|
|
37318
|
+
continue;
|
|
37319
|
+
}
|
|
37320
|
+
const parsed = this.parseMasterTxStyles(sldMaster);
|
|
37321
|
+
if (parsed) {
|
|
37322
|
+
master.txStyles = parsed;
|
|
37323
|
+
this.masterTxStylesCache.set(master.path, parsed);
|
|
37324
|
+
}
|
|
37325
|
+
const hf = parseHeaderFooterFlags(sldMaster["p:hf"]);
|
|
37326
|
+
if (hf) {
|
|
37327
|
+
master.headerFooter = hf;
|
|
37328
|
+
}
|
|
37329
|
+
} catch (e) {
|
|
37330
|
+
console.warn("Failed to parse master txStyles:", e);
|
|
37331
|
+
}
|
|
37332
|
+
}
|
|
37333
|
+
}
|
|
35123
37334
|
parsePresentationDefaultTextStyle() {
|
|
35124
37335
|
const presentation = this.presentationData?.["p:presentation"];
|
|
35125
37336
|
const defaultTextStyle = presentation?.["p:defaultTextStyle"];
|
|
@@ -35275,7 +37486,7 @@ var PptxHandlerRuntime54 = class extends PptxHandlerRuntime53 {
|
|
|
35275
37486
|
};
|
|
35276
37487
|
|
|
35277
37488
|
// src/core/core/runtime/PptxHandlerRuntimeLayoutElements.ts
|
|
35278
|
-
var
|
|
37489
|
+
var PptxHandlerRuntime56 = class extends PptxHandlerRuntime55 {
|
|
35279
37490
|
async getLayoutElements(slidePath) {
|
|
35280
37491
|
const slideRels = this.slideRelsMap.get(slidePath);
|
|
35281
37492
|
if (!slideRels) {
|
|
@@ -35399,10 +37610,10 @@ var PptxHandlerRuntime55 = class extends PptxHandlerRuntime54 {
|
|
|
35399
37610
|
}
|
|
35400
37611
|
}
|
|
35401
37612
|
}
|
|
35402
|
-
this.currentSlideClrMapOverride = prevClrMapOverride;
|
|
35403
37613
|
const layoutShowMasterSp = layoutXmlObj["p:sldLayout"]?.["@_showMasterSp"];
|
|
35404
37614
|
const showMasterSp = layoutShowMasterSp === void 0 || String(layoutShowMasterSp).trim().toLowerCase() !== "0" && String(layoutShowMasterSp).trim().toLowerCase() !== "false";
|
|
35405
37615
|
const masterElements = showMasterSp ? await this.getMasterElements(layoutPath) : [];
|
|
37616
|
+
this.currentSlideClrMapOverride = prevClrMapOverride;
|
|
35406
37617
|
const allElements = [...masterElements, ...elements];
|
|
35407
37618
|
this.layoutCache.set(layoutPath, allElements);
|
|
35408
37619
|
return allElements;
|
|
@@ -35414,7 +37625,7 @@ var PptxHandlerRuntime55 = class extends PptxHandlerRuntime54 {
|
|
|
35414
37625
|
};
|
|
35415
37626
|
|
|
35416
37627
|
// src/core/core/runtime/PptxHandlerRuntimeThemeFormatScheme.ts
|
|
35417
|
-
var
|
|
37628
|
+
var PptxHandlerRuntime57 = class _PptxHandlerRuntime extends PptxHandlerRuntime56 {
|
|
35418
37629
|
/**
|
|
35419
37630
|
* Collect fill-style children from a style list node, preserving
|
|
35420
37631
|
* document order. Handles `a:solidFill`, `a:gradFill`, `a:pattFill`,
|
|
@@ -35656,7 +37867,7 @@ var PptxHandlerRuntime56 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
|
|
|
35656
37867
|
};
|
|
35657
37868
|
|
|
35658
37869
|
// src/core/core/runtime/PptxHandlerRuntimeThemeOverrides.ts
|
|
35659
|
-
var
|
|
37870
|
+
var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
|
|
35660
37871
|
/**
|
|
35661
37872
|
* Parse the `a:fmtScheme` element from the theme into a structured
|
|
35662
37873
|
* {@link PptxThemeFormatScheme}. Each sub-list (fillStyleLst, lnStyleLst,
|
|
@@ -35853,8 +38064,10 @@ var PptxHandlerRuntime57 = class extends PptxHandlerRuntime56 {
|
|
|
35853
38064
|
}
|
|
35854
38065
|
const fontScheme = root["a:fontScheme"];
|
|
35855
38066
|
if (fontScheme) {
|
|
35856
|
-
const
|
|
35857
|
-
const
|
|
38067
|
+
const majorFontNode = fontScheme["a:majorFont"];
|
|
38068
|
+
const minorFontNode = fontScheme["a:minorFont"];
|
|
38069
|
+
const majorLatin = majorFontNode?.["a:latin"];
|
|
38070
|
+
const minorLatin = minorFontNode?.["a:latin"];
|
|
35858
38071
|
const majorFont = this.normalizeTypefaceToken(String(majorLatin?.["@_typeface"] || ""));
|
|
35859
38072
|
const minorFont = this.normalizeTypefaceToken(String(minorLatin?.["@_typeface"] || ""));
|
|
35860
38073
|
if (!result.colorOverrides) {
|
|
@@ -35877,13 +38090,46 @@ var PptxHandlerRuntime57 = class extends PptxHandlerRuntime56 {
|
|
|
35877
38090
|
};
|
|
35878
38091
|
|
|
35879
38092
|
// src/core/core/runtime/PptxHandlerRuntimeThemeRefResolution.ts
|
|
35880
|
-
var
|
|
38093
|
+
var COLOR_CHOICE_KEYS2 = [
|
|
38094
|
+
"a:scrgbClr",
|
|
38095
|
+
"a:srgbClr",
|
|
38096
|
+
"a:hslClr",
|
|
38097
|
+
"a:sysClr",
|
|
38098
|
+
"a:schemeClr",
|
|
38099
|
+
"a:prstClr"
|
|
38100
|
+
];
|
|
38101
|
+
var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
|
|
38102
|
+
/**
|
|
38103
|
+
* Pull the verbatim colour-choice child out of a style-matrix-reference
|
|
38104
|
+
* element (`a:lnRef`/`a:fillRef`/`a:effectRef`/`a:fontRef`). Returns the
|
|
38105
|
+
* full child object so it can be round-tripped at save time, preserving
|
|
38106
|
+
* any contained colour transforms (`a:lumMod`, `a:tint`, etc.).
|
|
38107
|
+
*/
|
|
38108
|
+
extractRefColorXml(refNode) {
|
|
38109
|
+
if (!refNode) {
|
|
38110
|
+
return void 0;
|
|
38111
|
+
}
|
|
38112
|
+
for (const key of COLOR_CHOICE_KEYS2) {
|
|
38113
|
+
const child = refNode[key];
|
|
38114
|
+
if (child !== void 0) {
|
|
38115
|
+
return { [key]: child };
|
|
38116
|
+
}
|
|
38117
|
+
}
|
|
38118
|
+
return void 0;
|
|
38119
|
+
}
|
|
35881
38120
|
/**
|
|
35882
38121
|
* Resolve a `a:effectRef` element into concrete effect properties
|
|
35883
38122
|
* by looking up `@_idx` in the theme format scheme's effect style list.
|
|
35884
38123
|
*/
|
|
35885
38124
|
resolveThemeEffectRef(refNode, style) {
|
|
35886
38125
|
const idx = parseInt(String(refNode["@_idx"] || "0"), 10);
|
|
38126
|
+
if (Number.isFinite(idx) && idx > 0) {
|
|
38127
|
+
style.effectRefIdx = idx;
|
|
38128
|
+
}
|
|
38129
|
+
const overrideColorXml = this.extractRefColorXml(refNode);
|
|
38130
|
+
if (overrideColorXml) {
|
|
38131
|
+
style.effectRefColorXml = overrideColorXml;
|
|
38132
|
+
}
|
|
35887
38133
|
if (!Number.isFinite(idx) || idx <= 0 || !this.themeFormatScheme || idx > this.themeFormatScheme.effectStyles.length) {
|
|
35888
38134
|
return;
|
|
35889
38135
|
}
|
|
@@ -35936,6 +38182,13 @@ var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
|
|
|
35936
38182
|
resolveThemeLineRef(refNode, style) {
|
|
35937
38183
|
const idx = parseInt(String(refNode["@_idx"] || "0"), 10);
|
|
35938
38184
|
const overrideColor = this.parseColor(refNode);
|
|
38185
|
+
if (Number.isFinite(idx) && idx > 0) {
|
|
38186
|
+
style.lnRefIdx = idx;
|
|
38187
|
+
}
|
|
38188
|
+
const overrideColorXml = this.extractRefColorXml(refNode);
|
|
38189
|
+
if (overrideColorXml) {
|
|
38190
|
+
style.lnRefColorXml = overrideColorXml;
|
|
38191
|
+
}
|
|
35939
38192
|
if (!Number.isFinite(idx) || idx <= 0 || !this.themeFormatScheme || idx > this.themeFormatScheme.lineStyles.length) {
|
|
35940
38193
|
style.strokeColor = overrideColor;
|
|
35941
38194
|
if (overrideColor) {
|
|
@@ -36007,6 +38260,13 @@ var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
|
|
|
36007
38260
|
*/
|
|
36008
38261
|
resolveThemeFillRef(refNode, style) {
|
|
36009
38262
|
const idx = parseInt(String(refNode["@_idx"] || "0"), 10);
|
|
38263
|
+
if (Number.isFinite(idx) && idx > 0) {
|
|
38264
|
+
style.fillRefIdx = idx;
|
|
38265
|
+
}
|
|
38266
|
+
const overrideColorXml = this.extractRefColorXml(refNode);
|
|
38267
|
+
if (overrideColorXml) {
|
|
38268
|
+
style.fillRefColorXml = overrideColorXml;
|
|
38269
|
+
}
|
|
36010
38270
|
if (!Number.isFinite(idx) || idx <= 0 || !this.themeFormatScheme) {
|
|
36011
38271
|
style.fillMode = "theme";
|
|
36012
38272
|
style.fillColor = this.parseColor(refNode);
|
|
@@ -36072,7 +38332,7 @@ var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
|
|
|
36072
38332
|
};
|
|
36073
38333
|
|
|
36074
38334
|
// src/core/core/runtime/PptxHandlerRuntimeThemeLoading.ts
|
|
36075
|
-
var
|
|
38335
|
+
var PptxHandlerRuntime60 = class extends PptxHandlerRuntime59 {
|
|
36076
38336
|
async resolvePrimaryThemePath() {
|
|
36077
38337
|
const masterFiles = this.zip.file(/^ppt\/slideMasters\/slideMaster\d+\.xml$/);
|
|
36078
38338
|
if (!masterFiles || masterFiles.length === 0) {
|
|
@@ -36182,62 +38442,97 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
|
|
|
36182
38442
|
formatScheme: this.themeFormatScheme
|
|
36183
38443
|
};
|
|
36184
38444
|
}
|
|
36185
|
-
|
|
38445
|
+
/**
|
|
38446
|
+
* Parse every slide master's `<p:clrMap>` element and store the alias
|
|
38447
|
+
* dictionaries on {@link masterClrMaps}. Do *not* mutate
|
|
38448
|
+
* {@link themeColorMap} — alias resolution happens at colour-lookup
|
|
38449
|
+
* time so that:
|
|
38450
|
+
*
|
|
38451
|
+
* 1. The raw theme scheme stays the source of truth (clrMap is a
|
|
38452
|
+
* routing layer, not a colour table).
|
|
38453
|
+
* 2. Multi-master decks resolve each slide against its own master's
|
|
38454
|
+
* clrMap rather than always against `masterFiles[0]`.
|
|
38455
|
+
* 3. Layout `clrMapOvr` semantics work correctly when a slide's master
|
|
38456
|
+
* differs from the deck's first master.
|
|
38457
|
+
*
|
|
38458
|
+
* Phase 2 Stream B / C-H4.
|
|
38459
|
+
*/
|
|
38460
|
+
async applySlideMasterColorMap(_defaultMap) {
|
|
36186
38461
|
const masterFiles = this.zip.file(/^ppt\/slideMasters\/slideMaster\d+\.xml$/);
|
|
36187
38462
|
if (!masterFiles || masterFiles.length === 0) {
|
|
36188
38463
|
return;
|
|
36189
38464
|
}
|
|
36190
|
-
|
|
36191
|
-
|
|
36192
|
-
|
|
36193
|
-
|
|
36194
|
-
|
|
36195
|
-
|
|
36196
|
-
|
|
36197
|
-
|
|
36198
|
-
|
|
36199
|
-
|
|
36200
|
-
|
|
36201
|
-
|
|
36202
|
-
|
|
36203
|
-
|
|
36204
|
-
|
|
36205
|
-
|
|
36206
|
-
"
|
|
36207
|
-
|
|
36208
|
-
"
|
|
36209
|
-
|
|
36210
|
-
];
|
|
36211
|
-
for (const aliasKey of aliasKeys) {
|
|
36212
|
-
const mappedKey = String(clrMap[`@_${aliasKey}`] || "").trim().toLowerCase();
|
|
36213
|
-
if (!mappedKey) {
|
|
38465
|
+
const aliasKeys = [
|
|
38466
|
+
"bg1",
|
|
38467
|
+
"tx1",
|
|
38468
|
+
"bg2",
|
|
38469
|
+
"tx2",
|
|
38470
|
+
"accent1",
|
|
38471
|
+
"accent2",
|
|
38472
|
+
"accent3",
|
|
38473
|
+
"accent4",
|
|
38474
|
+
"accent5",
|
|
38475
|
+
"accent6",
|
|
38476
|
+
"hlink",
|
|
38477
|
+
"folHlink"
|
|
38478
|
+
];
|
|
38479
|
+
for (const file of masterFiles) {
|
|
38480
|
+
try {
|
|
38481
|
+
const masterXml = await file.async("string");
|
|
38482
|
+
const masterData = this.parser.parse(masterXml);
|
|
38483
|
+
const clrMap = masterData?.["p:sldMaster"]?.["p:clrMap"];
|
|
38484
|
+
if (!clrMap) {
|
|
36214
38485
|
continue;
|
|
36215
38486
|
}
|
|
36216
|
-
const
|
|
36217
|
-
|
|
36218
|
-
|
|
38487
|
+
const aliasMap = {};
|
|
38488
|
+
for (const aliasKey of aliasKeys) {
|
|
38489
|
+
const mappedKey = String(clrMap[`@_${aliasKey}`] || "").trim().toLowerCase();
|
|
38490
|
+
if (mappedKey) {
|
|
38491
|
+
aliasMap[aliasKey] = mappedKey;
|
|
38492
|
+
}
|
|
38493
|
+
}
|
|
38494
|
+
if (Object.keys(aliasMap).length > 0) {
|
|
38495
|
+
this.masterClrMaps.set(file.name, aliasMap);
|
|
36219
38496
|
}
|
|
38497
|
+
} catch (error) {
|
|
38498
|
+
console.warn(`Failed to parse slide master color map for ${file.name}:`, error);
|
|
36220
38499
|
}
|
|
36221
|
-
} catch (error) {
|
|
36222
|
-
console.warn("Failed to parse slide master color map:", error);
|
|
36223
38500
|
}
|
|
36224
38501
|
}
|
|
36225
|
-
|
|
36226
|
-
|
|
36227
|
-
|
|
36228
|
-
|
|
38502
|
+
/**
|
|
38503
|
+
* Parse a single theme part into structured colour, font, and format
|
|
38504
|
+
* scheme dictionaries. Used both for the global default theme and for
|
|
38505
|
+
* each master's per-master theme (multi-master support).
|
|
38506
|
+
*
|
|
38507
|
+
* Phase 2 Stream B / C-H4.
|
|
38508
|
+
*/
|
|
38509
|
+
async parseThemePart(themePath) {
|
|
38510
|
+
const themeFile = this.zip.file(themePath);
|
|
38511
|
+
if (!themeFile) {
|
|
38512
|
+
return null;
|
|
36229
38513
|
}
|
|
36230
|
-
const preferredThemePath = await this.resolvePrimaryThemePath();
|
|
36231
|
-
const preferredThemeFile = preferredThemePath ? themeFiles.find((file) => file.name === preferredThemePath) : void 0;
|
|
36232
|
-
const themeFile = preferredThemeFile ?? themeFiles[0];
|
|
36233
38514
|
const themeXml2 = await themeFile.async("string");
|
|
38515
|
+
this.originalThemeXmlByPath.set(themePath, themeXml2);
|
|
36234
38516
|
const themeData = this.parser.parse(themeXml2);
|
|
36235
38517
|
const themeRoot = themeData["a:theme"];
|
|
36236
38518
|
const themeElements = themeRoot?.["a:themeElements"];
|
|
36237
38519
|
const colorScheme = themeElements?.["a:clrScheme"];
|
|
36238
38520
|
const fontScheme = themeElements?.["a:fontScheme"];
|
|
38521
|
+
const fmtScheme = themeElements?.["a:fmtScheme"];
|
|
38522
|
+
const themeName = String(themeRoot?.["@_name"] || "").trim();
|
|
38523
|
+
if (themeName) {
|
|
38524
|
+
this.masterThemeNames.set(themePath, themeName);
|
|
38525
|
+
}
|
|
38526
|
+
const colorSchemeName = String(colorScheme?.["@_name"] || "").trim();
|
|
38527
|
+
if (colorSchemeName) {
|
|
38528
|
+
this.masterThemeColorSchemeNames.set(themePath, colorSchemeName);
|
|
38529
|
+
}
|
|
38530
|
+
const fontSchemeName = String(fontScheme?.["@_name"] || "").trim();
|
|
38531
|
+
if (fontSchemeName) {
|
|
38532
|
+
this.masterThemeFontSchemeNames.set(themePath, fontSchemeName);
|
|
38533
|
+
}
|
|
36239
38534
|
const defaultMap = this.getDefaultSchemeColorMap();
|
|
36240
|
-
|
|
38535
|
+
const colorMap = { ...defaultMap };
|
|
36241
38536
|
if (colorScheme) {
|
|
36242
38537
|
const schemeKeys = [
|
|
36243
38538
|
"dk1",
|
|
@@ -36257,39 +38552,196 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
|
|
|
36257
38552
|
const colorNode = colorScheme[`a:${key}`];
|
|
36258
38553
|
const parsed = this.parseColorChoice(colorNode);
|
|
36259
38554
|
if (parsed) {
|
|
36260
|
-
|
|
38555
|
+
colorMap[key] = parsed;
|
|
36261
38556
|
}
|
|
36262
38557
|
}
|
|
36263
38558
|
}
|
|
36264
|
-
|
|
36265
|
-
|
|
36266
|
-
|
|
36267
|
-
|
|
36268
|
-
|
|
36269
|
-
const
|
|
36270
|
-
const
|
|
38559
|
+
colorMap["tx1"] = colorMap["dk1"] || defaultMap["dk1"];
|
|
38560
|
+
colorMap["bg1"] = colorMap["lt1"] || defaultMap["lt1"];
|
|
38561
|
+
colorMap["tx2"] = colorMap["dk2"] || defaultMap["dk2"];
|
|
38562
|
+
colorMap["bg2"] = colorMap["lt2"] || defaultMap["lt2"];
|
|
38563
|
+
const majorFontNode = fontScheme?.["a:majorFont"];
|
|
38564
|
+
const minorFontNode = fontScheme?.["a:minorFont"];
|
|
38565
|
+
const majorLatin = majorFontNode?.["a:latin"];
|
|
38566
|
+
const minorLatin = minorFontNode?.["a:latin"];
|
|
36271
38567
|
const majorFont = this.normalizeTypefaceToken(String(majorLatin?.["@_typeface"] || ""));
|
|
36272
38568
|
const minorFont = this.normalizeTypefaceToken(String(minorLatin?.["@_typeface"] || ""));
|
|
36273
|
-
|
|
38569
|
+
const fontMap = {};
|
|
36274
38570
|
if (majorFont) {
|
|
36275
|
-
|
|
36276
|
-
|
|
36277
|
-
|
|
38571
|
+
fontMap["mj-lt"] = majorFont;
|
|
38572
|
+
fontMap["mj-ea"] = majorFont;
|
|
38573
|
+
fontMap["mj-cs"] = majorFont;
|
|
36278
38574
|
}
|
|
36279
38575
|
if (minorFont) {
|
|
36280
|
-
|
|
36281
|
-
|
|
36282
|
-
|
|
38576
|
+
fontMap["mn-lt"] = minorFont;
|
|
38577
|
+
fontMap["mn-ea"] = minorFont;
|
|
38578
|
+
fontMap["mn-cs"] = minorFont;
|
|
36283
38579
|
}
|
|
36284
|
-
const
|
|
36285
|
-
|
|
36286
|
-
|
|
38580
|
+
const majorEa = this.normalizeTypefaceToken(
|
|
38581
|
+
String(majorFontNode?.["a:ea"]?.["@_typeface"] || "")
|
|
38582
|
+
);
|
|
38583
|
+
if (majorEa) {
|
|
38584
|
+
fontMap["mj-ea"] = majorEa;
|
|
38585
|
+
}
|
|
38586
|
+
const majorCs = this.normalizeTypefaceToken(
|
|
38587
|
+
String(majorFontNode?.["a:cs"]?.["@_typeface"] || "")
|
|
38588
|
+
);
|
|
38589
|
+
if (majorCs) {
|
|
38590
|
+
fontMap["mj-cs"] = majorCs;
|
|
38591
|
+
}
|
|
38592
|
+
const minorEa = this.normalizeTypefaceToken(
|
|
38593
|
+
String(minorFontNode?.["a:ea"]?.["@_typeface"] || "")
|
|
38594
|
+
);
|
|
38595
|
+
if (minorEa) {
|
|
38596
|
+
fontMap["mn-ea"] = minorEa;
|
|
38597
|
+
}
|
|
38598
|
+
const minorCs = this.normalizeTypefaceToken(
|
|
38599
|
+
String(minorFontNode?.["a:cs"]?.["@_typeface"] || "")
|
|
38600
|
+
);
|
|
38601
|
+
if (minorCs) {
|
|
38602
|
+
fontMap["mn-cs"] = minorCs;
|
|
38603
|
+
}
|
|
38604
|
+
const majorScripts = this.collectFontScriptOverrides(majorFontNode);
|
|
38605
|
+
if (Object.keys(majorScripts).length > 0) {
|
|
38606
|
+
this.masterThemeMajorFontScripts.set(themePath, majorScripts);
|
|
38607
|
+
}
|
|
38608
|
+
const minorScripts = this.collectFontScriptOverrides(minorFontNode);
|
|
38609
|
+
if (Object.keys(minorScripts).length > 0) {
|
|
38610
|
+
this.masterThemeMinorFontScripts.set(themePath, minorScripts);
|
|
38611
|
+
}
|
|
38612
|
+
const objectDefaultsNode = themeRoot?.["a:objectDefaults"];
|
|
38613
|
+
if (objectDefaultsNode) {
|
|
38614
|
+
const od = {
|
|
38615
|
+
spDef: objectDefaultsNode["a:spDef"],
|
|
38616
|
+
lnDef: objectDefaultsNode["a:lnDef"],
|
|
38617
|
+
txDef: objectDefaultsNode["a:txDef"]
|
|
38618
|
+
};
|
|
38619
|
+
if (od.spDef !== void 0 || od.lnDef !== void 0 || od.txDef !== void 0) {
|
|
38620
|
+
this.masterThemeObjectDefaults.set(themePath, od);
|
|
38621
|
+
}
|
|
38622
|
+
}
|
|
38623
|
+
const extraClrSchemeLst = themeRoot?.["a:extraClrSchemeLst"];
|
|
38624
|
+
if (extraClrSchemeLst !== void 0) {
|
|
38625
|
+
this.masterThemeExtraClrSchemeLst.set(themePath, extraClrSchemeLst);
|
|
38626
|
+
}
|
|
38627
|
+
const custClrLst = themeRoot?.["a:custClrLst"];
|
|
38628
|
+
if (custClrLst !== void 0) {
|
|
38629
|
+
this.masterThemeCustClrLst.set(themePath, custClrLst);
|
|
38630
|
+
}
|
|
38631
|
+
const themeExtLst = themeRoot?.["a:extLst"];
|
|
38632
|
+
if (themeExtLst !== void 0) {
|
|
38633
|
+
this.masterThemeExtLst.set(themePath, themeExtLst);
|
|
38634
|
+
}
|
|
38635
|
+
const formatScheme = fmtScheme ? this.parseFormatScheme(fmtScheme) : void 0;
|
|
38636
|
+
return { colorMap, fontMap, formatScheme };
|
|
38637
|
+
}
|
|
38638
|
+
/**
|
|
38639
|
+
* Parse `<a:font script="…" typeface="…"/>` children of a major or
|
|
38640
|
+
* minor font node into a `script -> typeface` dictionary.
|
|
38641
|
+
*
|
|
38642
|
+
* fast-xml-parser collapses repeated tags into arrays, so iterate
|
|
38643
|
+
* over the array form regardless of how many siblings are present.
|
|
38644
|
+
*
|
|
38645
|
+
* Phase 4 Stream A / M4.
|
|
38646
|
+
*/
|
|
38647
|
+
collectFontScriptOverrides(fontNode) {
|
|
38648
|
+
const overrides = {};
|
|
38649
|
+
if (!fontNode) {
|
|
38650
|
+
return overrides;
|
|
38651
|
+
}
|
|
38652
|
+
const fontEntries = this.ensureArray(fontNode["a:font"]);
|
|
38653
|
+
for (const entry of fontEntries) {
|
|
38654
|
+
const script = String(entry?.["@_script"] || "").trim();
|
|
38655
|
+
const typeface = this.normalizeTypefaceToken(String(entry?.["@_typeface"] || ""));
|
|
38656
|
+
if (script && typeface) {
|
|
38657
|
+
overrides[script] = typeface;
|
|
38658
|
+
}
|
|
38659
|
+
}
|
|
38660
|
+
return overrides;
|
|
38661
|
+
}
|
|
38662
|
+
/**
|
|
38663
|
+
* Resolve the theme file path referenced by a given master's `.rels`.
|
|
38664
|
+
* Returns `undefined` when the master has no theme relationship.
|
|
38665
|
+
*/
|
|
38666
|
+
async resolveThemePathForMaster(masterPath) {
|
|
38667
|
+
const relsPath = masterPath.replace(
|
|
38668
|
+
/ppt\/slideMasters\/(slideMaster\d+)\.xml/,
|
|
38669
|
+
"ppt/slideMasters/_rels/$1.xml.rels"
|
|
38670
|
+
);
|
|
38671
|
+
const relsXml = this.zip.file(relsPath);
|
|
38672
|
+
if (!relsXml) {
|
|
38673
|
+
return void 0;
|
|
38674
|
+
}
|
|
38675
|
+
const relsData = this.parser.parse(await relsXml.async("string"));
|
|
38676
|
+
const relNodes = this.ensureArray(relsData?.Relationships?.Relationship);
|
|
38677
|
+
for (const rel of relNodes) {
|
|
38678
|
+
const target = String(rel["@_Target"] || "");
|
|
38679
|
+
if (!target.includes("theme")) {
|
|
38680
|
+
continue;
|
|
38681
|
+
}
|
|
38682
|
+
const themePath = target.startsWith("..") ? this.resolvePath(masterPath.substring(0, masterPath.lastIndexOf("/") + 1), target) : target.startsWith("/") ? target.slice(1) : `ppt/${target.replace(/^\.?\//, "")}`;
|
|
38683
|
+
if (themePath.startsWith("ppt/theme/")) {
|
|
38684
|
+
return themePath;
|
|
38685
|
+
}
|
|
38686
|
+
}
|
|
38687
|
+
return void 0;
|
|
38688
|
+
}
|
|
38689
|
+
/**
|
|
38690
|
+
* Populate {@link masterThemeColorMaps}, {@link masterThemeFontMaps},
|
|
38691
|
+
* and {@link masterThemeFormatSchemes} for every slide master in the
|
|
38692
|
+
* deck. Multi-master support — Phase 2 Stream B / C-H4.
|
|
38693
|
+
*/
|
|
38694
|
+
async loadPerMasterThemes() {
|
|
38695
|
+
const masterFiles = this.zip.file(/^ppt\/slideMasters\/slideMaster\d+\.xml$/);
|
|
38696
|
+
if (!masterFiles || masterFiles.length === 0) {
|
|
38697
|
+
return;
|
|
38698
|
+
}
|
|
38699
|
+
for (const file of masterFiles) {
|
|
38700
|
+
try {
|
|
38701
|
+
const themePath = await this.resolveThemePathForMaster(file.name);
|
|
38702
|
+
if (!themePath) {
|
|
38703
|
+
continue;
|
|
38704
|
+
}
|
|
38705
|
+
this.masterThemePaths.set(file.name, themePath);
|
|
38706
|
+
const parsed = await this.parseThemePart(themePath);
|
|
38707
|
+
if (!parsed) {
|
|
38708
|
+
continue;
|
|
38709
|
+
}
|
|
38710
|
+
this.masterThemeColorMaps.set(file.name, parsed.colorMap);
|
|
38711
|
+
this.masterThemeFontMaps.set(file.name, parsed.fontMap);
|
|
38712
|
+
if (parsed.formatScheme) {
|
|
38713
|
+
this.masterThemeFormatSchemes.set(file.name, parsed.formatScheme);
|
|
38714
|
+
}
|
|
38715
|
+
} catch (error) {
|
|
38716
|
+
console.warn(`Failed to load per-master theme for ${file.name}:`, error);
|
|
38717
|
+
}
|
|
38718
|
+
}
|
|
38719
|
+
}
|
|
38720
|
+
async loadThemeData() {
|
|
38721
|
+
const themeFiles = this.zip.file(/^ppt\/theme\/theme\d+\.xml$/);
|
|
38722
|
+
if (!themeFiles || themeFiles.length === 0) {
|
|
38723
|
+
return;
|
|
36287
38724
|
}
|
|
38725
|
+
const preferredThemePath = await this.resolvePrimaryThemePath();
|
|
38726
|
+
const themeFile = preferredThemePath ? themeFiles.find((file) => file.name === preferredThemePath) ?? themeFiles[0] : themeFiles[0];
|
|
38727
|
+
const parsed = await this.parseThemePart(themeFile.name);
|
|
38728
|
+
if (parsed) {
|
|
38729
|
+
this.themeColorMap = parsed.colorMap;
|
|
38730
|
+
this.themeFontMap = parsed.fontMap;
|
|
38731
|
+
if (parsed.formatScheme) {
|
|
38732
|
+
this.themeFormatScheme = parsed.formatScheme;
|
|
38733
|
+
}
|
|
38734
|
+
}
|
|
38735
|
+
await this.applySlideMasterColorMap(this.getDefaultSchemeColorMap());
|
|
38736
|
+
await this.loadPerMasterThemes();
|
|
38737
|
+
this.globalThemeColorMapSnapshot = { ...this.themeColorMap };
|
|
38738
|
+
this.globalThemeFontMapSnapshot = { ...this.themeFontMap };
|
|
38739
|
+
this.globalThemeFormatSchemeSnapshot = this.themeFormatScheme;
|
|
36288
38740
|
}
|
|
36289
38741
|
};
|
|
36290
38742
|
|
|
36291
38743
|
// src/core/core/runtime/PptxHandlerRuntimeThemeProcessing.ts
|
|
36292
|
-
var
|
|
38744
|
+
var PptxHandlerRuntime61 = class extends PptxHandlerRuntime60 {
|
|
36293
38745
|
// ---------------------------------------------------------------------------
|
|
36294
38746
|
// Theme editing — update colour scheme, font scheme, and name in the zip
|
|
36295
38747
|
// ---------------------------------------------------------------------------
|
|
@@ -36439,7 +38891,7 @@ var PptxHandlerRuntime60 = class extends PptxHandlerRuntime59 {
|
|
|
36439
38891
|
};
|
|
36440
38892
|
|
|
36441
38893
|
// src/core/core/runtime/PptxHandlerRuntimeComments.ts
|
|
36442
|
-
var
|
|
38894
|
+
var PptxHandlerRuntime62 = class _PptxHandlerRuntime extends PptxHandlerRuntime61 {
|
|
36443
38895
|
/**
|
|
36444
38896
|
* Parse modern threaded comments (PowerPoint 2019+ / Office 365).
|
|
36445
38897
|
* Modern comments use `p188:cmLst`/`p15:cmLst` roots within
|
|
@@ -36672,7 +39124,7 @@ var PptxHandlerRuntime61 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
|
|
|
36672
39124
|
};
|
|
36673
39125
|
|
|
36674
39126
|
// src/core/core/runtime/PptxHandlerRuntimeSmartArtXmlUtils.ts
|
|
36675
|
-
var
|
|
39127
|
+
var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
|
|
36676
39128
|
async readXmlPartByRelationshipId(slidePath, relationshipId) {
|
|
36677
39129
|
const normalizedRelationshipId = String(relationshipId || "").trim();
|
|
36678
39130
|
if (normalizedRelationshipId.length === 0) {
|
|
@@ -36827,7 +39279,7 @@ var PptxHandlerRuntime62 = class extends PptxHandlerRuntime61 {
|
|
|
36827
39279
|
};
|
|
36828
39280
|
|
|
36829
39281
|
// src/core/core/runtime/PptxHandlerRuntimeSmartArtParsing.ts
|
|
36830
|
-
var
|
|
39282
|
+
var PptxHandlerRuntime64 = class _PptxHandlerRuntime extends PptxHandlerRuntime63 {
|
|
36831
39283
|
/**
|
|
36832
39284
|
* Parse quick style from `ppt/diagrams/quickStyles*.xml`.
|
|
36833
39285
|
*/
|
|
@@ -36986,7 +39438,7 @@ var PptxHandlerRuntime63 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
|
|
|
36986
39438
|
};
|
|
36987
39439
|
|
|
36988
39440
|
// src/core/core/runtime/PptxHandlerRuntimeSmartArt.ts
|
|
36989
|
-
var
|
|
39441
|
+
var PptxHandlerRuntime65 = class _PptxHandlerRuntime extends PptxHandlerRuntime64 {
|
|
36990
39442
|
async getSmartArtDataForGraphicFrame(slidePath, graphicFrame) {
|
|
36991
39443
|
const graphicData = this.xmlLookupService.getChildByLocalName(
|
|
36992
39444
|
this.xmlLookupService.getChildByLocalName(graphicFrame, "graphic"),
|
|
@@ -37037,10 +39489,14 @@ var PptxHandlerRuntime64 = class extends PptxHandlerRuntime63 {
|
|
|
37037
39489
|
const layoutPart = layoutRelationshipId.length > 0 ? await this.readXmlPartByRelationshipId(slidePath, layoutRelationshipId) : void 0;
|
|
37038
39490
|
const layoutType = layoutPart?.partPath?.split("/").pop()?.replace(/\.[^.]+$/, "") || void 0;
|
|
37039
39491
|
const chrome = this.parseSmartArtChrome(dataModel);
|
|
37040
|
-
const drawingRelationshipId = String(relationshipIds["@_r:cs"] || "").trim();
|
|
37041
|
-
const drawingShapes = await this.parseSmartArtDrawingShapes(slidePath, drawingRelationshipId);
|
|
37042
39492
|
const colorsRelationshipId = String(relationshipIds["@_r:cs"] || "").trim();
|
|
37043
39493
|
const colorTransform = await this.parseSmartArtColorTransform(slidePath, colorsRelationshipId);
|
|
39494
|
+
const drawingResolution = await this.resolveSmartArtDrawingPart(
|
|
39495
|
+
slidePath,
|
|
39496
|
+
diagramDataRelationshipId
|
|
39497
|
+
);
|
|
39498
|
+
const drawingShapes = drawingResolution ? await this.parseSmartArtDrawingShapesFromPath(drawingResolution.path) : [];
|
|
39499
|
+
const drawingRelationshipId = drawingResolution?.relId;
|
|
37044
39500
|
const styleRelationshipId = String(relationshipIds["@_r:qs"] || "").trim();
|
|
37045
39501
|
const quickStyle = await this.parseSmartArtQuickStyle(slidePath, styleRelationshipId);
|
|
37046
39502
|
return {
|
|
@@ -37052,11 +39508,87 @@ var PptxHandlerRuntime64 = class extends PptxHandlerRuntime63 {
|
|
|
37052
39508
|
colorTransform,
|
|
37053
39509
|
quickStyle,
|
|
37054
39510
|
dataRelId: diagramDataRelationshipId,
|
|
37055
|
-
drawingRelId: drawingRelationshipId.length > 0 ? drawingRelationshipId : void 0,
|
|
39511
|
+
drawingRelId: drawingRelationshipId && drawingRelationshipId.length > 0 ? drawingRelationshipId : void 0,
|
|
37056
39512
|
colorsRelId: colorsRelationshipId.length > 0 ? colorsRelationshipId : void 0,
|
|
37057
39513
|
styleRelId: styleRelationshipId.length > 0 ? styleRelationshipId : void 0
|
|
37058
39514
|
};
|
|
37059
39515
|
}
|
|
39516
|
+
/**
|
|
39517
|
+
* Resolve the SmartArt drawing-shapes part path + relationship id.
|
|
39518
|
+
*
|
|
39519
|
+
* Strategy:
|
|
39520
|
+
* 1. Locate the data-model part's rels file
|
|
39521
|
+
* (`ppt/diagrams/_rels/data*.xml.rels`) via `slideRelsMap`.
|
|
39522
|
+
* 2. Find a relationship whose `Type` matches the `…/diagramDrawing`
|
|
39523
|
+
* URI. PowerPoint emits this for any deck that has had its
|
|
39524
|
+
* SmartArt rendered to drawing shapes.
|
|
39525
|
+
* 3. Return the matched part path (so the caller can load it
|
|
39526
|
+
* directly) and the relationship id (for round-trip preservation).
|
|
39527
|
+
*/
|
|
39528
|
+
async resolveSmartArtDrawingPart(slidePath, diagramDataRelationshipId) {
|
|
39529
|
+
if (diagramDataRelationshipId.length === 0) {
|
|
39530
|
+
return void 0;
|
|
39531
|
+
}
|
|
39532
|
+
const slideRels = this.slideRelsMap.get(slidePath);
|
|
39533
|
+
const dataTarget = slideRels?.get(diagramDataRelationshipId);
|
|
39534
|
+
if (!dataTarget) {
|
|
39535
|
+
return void 0;
|
|
39536
|
+
}
|
|
39537
|
+
const dataPath = this.resolveImagePath(slidePath, dataTarget);
|
|
39538
|
+
const dataDir = dataPath.replace(/\/[^/]+$/, "");
|
|
39539
|
+
const dataFile = dataPath.split("/").pop() ?? "";
|
|
39540
|
+
const dataRelsPath = `${dataDir}/_rels/${dataFile}.rels`;
|
|
39541
|
+
const relsXml = await this.zip.file(dataRelsPath)?.async("string");
|
|
39542
|
+
if (!relsXml) {
|
|
39543
|
+
return void 0;
|
|
39544
|
+
}
|
|
39545
|
+
try {
|
|
39546
|
+
const parsed = this.parser.parse(relsXml);
|
|
39547
|
+
const relsRoot = parsed["Relationships"];
|
|
39548
|
+
if (!relsRoot) {
|
|
39549
|
+
return void 0;
|
|
39550
|
+
}
|
|
39551
|
+
const rels = this.ensureArray(relsRoot["Relationship"]);
|
|
39552
|
+
const drawingRel = rels.find(
|
|
39553
|
+
(rel) => String(rel?.["@_Type"] || "").endsWith("/diagramDrawing")
|
|
39554
|
+
);
|
|
39555
|
+
const id = String(drawingRel?.["@_Id"] || "").trim();
|
|
39556
|
+
const target = String(drawingRel?.["@_Target"] || "").trim();
|
|
39557
|
+
if (id.length === 0 || target.length === 0) {
|
|
39558
|
+
return void 0;
|
|
39559
|
+
}
|
|
39560
|
+
const drawingPath = this.resolveImagePath(dataPath, target);
|
|
39561
|
+
return { relId: id, path: drawingPath };
|
|
39562
|
+
} catch {
|
|
39563
|
+
return void 0;
|
|
39564
|
+
}
|
|
39565
|
+
}
|
|
39566
|
+
/**
|
|
39567
|
+
* Parse SmartArt drawing shapes given an absolute part path.
|
|
39568
|
+
*
|
|
39569
|
+
* Wraps `parseSmartArtDrawingShapes` (which expects a slide-relative
|
|
39570
|
+
* relationship id) with a path-based lookup so the resolution layer
|
|
39571
|
+
* can pull the part from anywhere in the package.
|
|
39572
|
+
*/
|
|
39573
|
+
async parseSmartArtDrawingShapesFromPath(drawingPath) {
|
|
39574
|
+
const xmlString = await this.zip.file(drawingPath)?.async("string");
|
|
39575
|
+
if (!xmlString) {
|
|
39576
|
+
return [];
|
|
39577
|
+
}
|
|
39578
|
+
try {
|
|
39579
|
+
const xml = this.parser.parse(xmlString);
|
|
39580
|
+
const drawing = this.xmlLookupService.getChildByLocalName(xml, "drawing");
|
|
39581
|
+
const spTree = this.xmlLookupService.getChildByLocalName(drawing || xml, "spTree");
|
|
39582
|
+
if (!spTree) {
|
|
39583
|
+
return [];
|
|
39584
|
+
}
|
|
39585
|
+
const shapes = this.xmlLookupService.getChildrenArrayByLocalName(spTree, "sp");
|
|
39586
|
+
const emuPerPx = _PptxHandlerRuntime.EMU_PER_PX;
|
|
39587
|
+
return shapes.map((sp, index) => this.parseDrawingShape(sp, index, emuPerPx)).filter((entry) => entry !== null);
|
|
39588
|
+
} catch {
|
|
39589
|
+
return [];
|
|
39590
|
+
}
|
|
39591
|
+
}
|
|
37060
39592
|
parseSmartArtConnections(dataModel) {
|
|
37061
39593
|
const connectionList = this.xmlLookupService.getChildByLocalName(dataModel, "cxnLst");
|
|
37062
39594
|
const rawConnections = this.xmlLookupService.getChildrenArrayByLocalName(connectionList, "cxn");
|
|
@@ -37087,7 +39619,7 @@ var PptxHandlerRuntime64 = class extends PptxHandlerRuntime63 {
|
|
|
37087
39619
|
};
|
|
37088
39620
|
|
|
37089
39621
|
// src/core/core/runtime/PptxHandlerRuntimeChartDetection.ts
|
|
37090
|
-
var
|
|
39622
|
+
var PptxHandlerRuntime66 = class extends PptxHandlerRuntime65 {
|
|
37091
39623
|
detectChartType(plotArea) {
|
|
37092
39624
|
if (!plotArea) {
|
|
37093
39625
|
return "unknown";
|
|
@@ -37196,7 +39728,7 @@ var PptxHandlerRuntime65 = class extends PptxHandlerRuntime64 {
|
|
|
37196
39728
|
};
|
|
37197
39729
|
|
|
37198
39730
|
// src/core/core/runtime/PptxHandlerRuntimeChartParsingHelpers.ts
|
|
37199
|
-
var
|
|
39731
|
+
var PptxHandlerRuntime67 = class extends PptxHandlerRuntime66 {
|
|
37200
39732
|
/**
|
|
37201
39733
|
* Parse `c:plotVisOnly` from the chart root element.
|
|
37202
39734
|
*
|
|
@@ -37257,7 +39789,7 @@ var PptxHandlerRuntime66 = class extends PptxHandlerRuntime65 {
|
|
|
37257
39789
|
};
|
|
37258
39790
|
|
|
37259
39791
|
// src/core/core/runtime/PptxHandlerRuntimeChartExternalData.ts
|
|
37260
|
-
var
|
|
39792
|
+
var PptxHandlerRuntime68 = class extends PptxHandlerRuntime67 {
|
|
37261
39793
|
/**
|
|
37262
39794
|
* Parse `c:externalData` from the chart's `c:chartSpace` and resolve
|
|
37263
39795
|
* the external relationship target from the chart part's .rels file.
|
|
@@ -37373,7 +39905,7 @@ var PptxHandlerRuntime67 = class extends PptxHandlerRuntime66 {
|
|
|
37373
39905
|
};
|
|
37374
39906
|
|
|
37375
39907
|
// src/core/core/runtime/PptxHandlerRuntimeChartColorStyle.ts
|
|
37376
|
-
var
|
|
39908
|
+
var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
|
|
37377
39909
|
/**
|
|
37378
39910
|
* Parse the Office 2013+ chart color style part (`chartColorStyle*.xml`)
|
|
37379
39911
|
* referenced from the chart's relationships.
|
|
@@ -37480,7 +40012,7 @@ var PptxHandlerRuntime68 = class extends PptxHandlerRuntime67 {
|
|
|
37480
40012
|
};
|
|
37481
40013
|
|
|
37482
40014
|
// src/core/core/runtime/PptxHandlerRuntimeChartParsing.ts
|
|
37483
|
-
var
|
|
40015
|
+
var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
|
|
37484
40016
|
/**
|
|
37485
40017
|
* Parse chart data from a graphic frame element on a slide.
|
|
37486
40018
|
*
|
|
@@ -37727,7 +40259,7 @@ var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
|
|
|
37727
40259
|
};
|
|
37728
40260
|
|
|
37729
40261
|
// src/core/core/runtime/PptxHandlerRuntimePresentationStructure.ts
|
|
37730
|
-
var
|
|
40262
|
+
var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
|
|
37731
40263
|
parseEditorAnimations(slideXml2) {
|
|
37732
40264
|
return this.editorAnimationService.parseEditorAnimations(slideXml2);
|
|
37733
40265
|
}
|
|
@@ -37972,7 +40504,7 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
|
|
|
37972
40504
|
};
|
|
37973
40505
|
|
|
37974
40506
|
// src/core/core/runtime/PptxHandlerRuntimeEmbeddedFonts.ts
|
|
37975
|
-
var
|
|
40507
|
+
var PptxHandlerRuntime72 = class extends PptxHandlerRuntime71 {
|
|
37976
40508
|
async getEmbeddedFonts() {
|
|
37977
40509
|
const embeddedFontEntries = this.ensureArray(
|
|
37978
40510
|
this.presentationData?.["p:presentation"]?.["p:embeddedFontLst"]?.["p:embeddedFont"]
|
|
@@ -38144,7 +40676,7 @@ var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
|
|
|
38144
40676
|
};
|
|
38145
40677
|
|
|
38146
40678
|
// src/core/core/runtime/PptxHandlerRuntimeLoadSession.ts
|
|
38147
|
-
var
|
|
40679
|
+
var PptxHandlerRuntime73 = class _PptxHandlerRuntime extends PptxHandlerRuntime72 {
|
|
38148
40680
|
isZipContainer(data) {
|
|
38149
40681
|
const bytes = new Uint8Array(data);
|
|
38150
40682
|
if (bytes.byteLength < 4) {
|
|
@@ -38187,6 +40719,23 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38187
40719
|
this.imageDataCache.clear();
|
|
38188
40720
|
this.themeColorMap = {};
|
|
38189
40721
|
this.themeFontMap = {};
|
|
40722
|
+
this.masterClrMaps.clear();
|
|
40723
|
+
this.masterThemeColorMaps.clear();
|
|
40724
|
+
this.masterThemeFontMaps.clear();
|
|
40725
|
+
this.masterThemeFormatSchemes.clear();
|
|
40726
|
+
this.masterThemePaths.clear();
|
|
40727
|
+
this.masterThemeMajorFontScripts.clear();
|
|
40728
|
+
this.masterThemeMinorFontScripts.clear();
|
|
40729
|
+
this.masterThemeNames.clear();
|
|
40730
|
+
this.masterThemeFontSchemeNames.clear();
|
|
40731
|
+
this.masterThemeColorSchemeNames.clear();
|
|
40732
|
+
this.originalThemeXmlByPath.clear();
|
|
40733
|
+
this.dirtyThemePaths.clear();
|
|
40734
|
+
this.masterThemeObjectDefaults.clear();
|
|
40735
|
+
this.masterThemeExtraClrSchemeLst.clear();
|
|
40736
|
+
this.masterThemeCustClrLst.clear();
|
|
40737
|
+
this.masterThemeExtLst.clear();
|
|
40738
|
+
this.currentMasterClrMap = null;
|
|
38190
40739
|
this.presentationDefaultTextStyle = void 0;
|
|
38191
40740
|
this.commentAuthorMap.clear();
|
|
38192
40741
|
this.commentAuthorDetails.clear();
|
|
@@ -38341,6 +40890,7 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38341
40890
|
setCurrentSlideClrMapOverride: (override) => {
|
|
38342
40891
|
this.currentSlideClrMapOverride = override;
|
|
38343
40892
|
},
|
|
40893
|
+
setActiveMasterForSlide: (slidePath) => this.setActiveMasterForSlide(slidePath),
|
|
38344
40894
|
findLayoutPathForSlide: (slidePath) => this.findLayoutPathForSlide(slidePath),
|
|
38345
40895
|
loadThemeOverride: (partBasePath) => this.loadThemeOverride(partBasePath),
|
|
38346
40896
|
applyThemeOverrideState: (override) => this.applyThemeOverrideState(override),
|
|
@@ -38371,7 +40921,7 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38371
40921
|
};
|
|
38372
40922
|
|
|
38373
40923
|
// src/core/core/runtime/PptxHandlerRuntimeLoadPipeline.ts
|
|
38374
|
-
var
|
|
40924
|
+
var PptxHandlerRuntime74 = class extends PptxHandlerRuntime73 {
|
|
38375
40925
|
async buildLoadData(presentationState, slidesWithWarnings) {
|
|
38376
40926
|
const headerFooter = this.extractHeaderFooter();
|
|
38377
40927
|
const presentationProperties = await this.parsePresentationProperties();
|
|
@@ -38383,6 +40933,7 @@ var PptxHandlerRuntime73 = class extends PptxHandlerRuntime72 {
|
|
|
38383
40933
|
const notesMaster = await this.parseNotesMaster();
|
|
38384
40934
|
const handoutMaster = await this.parseHandoutMaster();
|
|
38385
40935
|
const slideMasters = await this.parseSlideMasters();
|
|
40936
|
+
await this.enrichSlideMastersWithTxStyles(slideMasters);
|
|
38386
40937
|
const tags = await this.parseTags();
|
|
38387
40938
|
const customProperties = await this.parseCustomProperties();
|
|
38388
40939
|
const coreProperties = await this.parseCoreProperties();
|
|
@@ -38717,7 +41268,7 @@ var PptxHandlerRuntime73 = class extends PptxHandlerRuntime72 {
|
|
|
38717
41268
|
};
|
|
38718
41269
|
|
|
38719
41270
|
// src/core/core/runtime/PptxHandlerRuntimeImplementation.ts
|
|
38720
|
-
var
|
|
41271
|
+
var PptxHandlerRuntime75 = class _PptxHandlerRuntime extends PptxHandlerRuntime74 {
|
|
38721
41272
|
constructor(dependencyFactory = new PptxRuntimeDependencyFactory()) {
|
|
38722
41273
|
super();
|
|
38723
41274
|
this.dependencyFactory = dependencyFactory;
|
|
@@ -38765,6 +41316,9 @@ var PptxHandlerRuntime74 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38765
41316
|
extractGradientPathType: (gradFill) => this.colorStyleCodec.extractGradientPathType(gradFill),
|
|
38766
41317
|
extractGradientFocalPoint: (gradFill) => this.colorStyleCodec.extractGradientFocalPoint(gradFill),
|
|
38767
41318
|
extractGradientFillToRect: (gradFill) => this.colorStyleCodec.extractGradientFillToRect(gradFill),
|
|
41319
|
+
extractGradientFlip: (gradFill) => this.colorStyleCodec.extractGradientFlip(gradFill),
|
|
41320
|
+
extractGradientRotWithShape: (gradFill) => this.colorStyleCodec.extractGradientRotWithShape(gradFill),
|
|
41321
|
+
extractGradientScaled: (gradFill) => this.colorStyleCodec.extractGradientScaled(gradFill),
|
|
38768
41322
|
normalizeStrokeDashType: (value) => this.normalizeStrokeDashType(value),
|
|
38769
41323
|
normalizeConnectorArrowType: (value) => this.normalizeConnectorArrowType(value),
|
|
38770
41324
|
ensureArray: (value) => this.ensureArray(value),
|
|
@@ -38838,11 +41392,11 @@ var PptxHandlerRuntime74 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38838
41392
|
};
|
|
38839
41393
|
|
|
38840
41394
|
// src/core/core/PptxHandlerRuntime.ts
|
|
38841
|
-
var
|
|
41395
|
+
var PptxHandlerRuntime76 = class extends PptxHandlerRuntime75 {
|
|
38842
41396
|
};
|
|
38843
41397
|
|
|
38844
41398
|
// src/core/core/PptxHandlerRuntimeFactory.ts
|
|
38845
|
-
var createDefaultPptxHandlerRuntime = () => new
|
|
41399
|
+
var createDefaultPptxHandlerRuntime = () => new PptxHandlerRuntime76();
|
|
38846
41400
|
|
|
38847
41401
|
// src/core/PptxHandlerCore.ts
|
|
38848
41402
|
var PptxHandlerCore = class {
|