pptx-react-viewer 1.1.3 → 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-BMjoxMDV.d.ts → SvgExporter-0TxiiorD.d.ts} +1 -1
- package/node_modules/pptx-viewer-core/dist/{SvgExporter-z6AbXRQg.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 +2711 -304
- package/node_modules/pptx-viewer-core/dist/cli/index.mjs +2711 -304
- 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 +692 -44
- package/node_modules/pptx-viewer-core/dist/index.d.ts +692 -44
- package/node_modules/pptx-viewer-core/dist/index.js +2794 -373
- package/node_modules/pptx-viewer-core/dist/index.mjs +2785 -373
- package/node_modules/pptx-viewer-core/dist/{presentation-CchuDGfU.d.mts → presentation-ArhfImJ5.d.mts} +225 -8
- package/node_modules/pptx-viewer-core/dist/{presentation-CchuDGfU.d.ts → presentation-ArhfImJ5.d.ts} +225 -8
- package/node_modules/pptx-viewer-core/dist/{text-operations-CeukUztU.d.mts → text-operations-CLj-sJyk.d.mts} +1 -1
- package/node_modules/pptx-viewer-core/dist/{text-operations-e7JxgI5l.d.ts → text-operations-rhJV-A_W.d.ts} +1 -1
- package/node_modules/pptx-viewer-core/package.json +5 -5
- package/package.json +20 -20
|
@@ -4400,12 +4400,25 @@ function svgToCustomGeometryPaths(pathData, width, height) {
|
|
|
4400
4400
|
function pointToXml(pt) {
|
|
4401
4401
|
return { "@_x": String(Math.round(pt.x)), "@_y": String(Math.round(pt.y)) };
|
|
4402
4402
|
}
|
|
4403
|
-
function customGeometryPathsToXml(paths) {
|
|
4403
|
+
function customGeometryPathsToXml(paths, rawData) {
|
|
4404
4404
|
const xmlPaths = paths.map((path2) => {
|
|
4405
4405
|
const pathXml = {
|
|
4406
4406
|
"@_w": String(Math.round(path2.width)),
|
|
4407
4407
|
"@_h": String(Math.round(path2.height))
|
|
4408
4408
|
};
|
|
4409
|
+
if (path2.fillMode) {
|
|
4410
|
+
pathXml["@_fill"] = path2.fillMode;
|
|
4411
|
+
}
|
|
4412
|
+
if (path2.stroke === false) {
|
|
4413
|
+
pathXml["@_stroke"] = "0";
|
|
4414
|
+
} else if (path2.stroke === true) {
|
|
4415
|
+
pathXml["@_stroke"] = "1";
|
|
4416
|
+
}
|
|
4417
|
+
if (path2.extrusionOk === true) {
|
|
4418
|
+
pathXml["@_extrusionOk"] = "1";
|
|
4419
|
+
} else if (path2.extrusionOk === false) {
|
|
4420
|
+
pathXml["@_extrusionOk"] = "0";
|
|
4421
|
+
}
|
|
4409
4422
|
const moveToList = [];
|
|
4410
4423
|
const lnToList = [];
|
|
4411
4424
|
const cubicBezToList = [];
|
|
@@ -4463,12 +4476,12 @@ function customGeometryPathsToXml(paths) {
|
|
|
4463
4476
|
}
|
|
4464
4477
|
return pathXml;
|
|
4465
4478
|
});
|
|
4466
|
-
|
|
4479
|
+
const result = {
|
|
4467
4480
|
"a:avLst": {},
|
|
4468
|
-
"a:gdLst": {},
|
|
4469
|
-
"a:ahLst": {},
|
|
4470
|
-
"a:cxnLst": {},
|
|
4471
|
-
"a:rect": {
|
|
4481
|
+
"a:gdLst": rawData?.gdLstXml ?? {},
|
|
4482
|
+
"a:ahLst": rawData?.ahLstXml ?? {},
|
|
4483
|
+
"a:cxnLst": rawData?.cxnLstXml ?? {},
|
|
4484
|
+
"a:rect": rawData?.rectXml ?? {
|
|
4472
4485
|
"@_l": "l",
|
|
4473
4486
|
"@_t": "t",
|
|
4474
4487
|
"@_r": "r",
|
|
@@ -4478,6 +4491,7 @@ function customGeometryPathsToXml(paths) {
|
|
|
4478
4491
|
"a:path": xmlPaths.length === 1 ? xmlPaths[0] : xmlPaths
|
|
4479
4492
|
}
|
|
4480
4493
|
};
|
|
4494
|
+
return result;
|
|
4481
4495
|
}
|
|
4482
4496
|
|
|
4483
4497
|
// src/core/builders/sdk/ElementFactory.ts
|
|
@@ -5224,6 +5238,9 @@ ${Array.from(
|
|
|
5224
5238
|
<p:presentation xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
|
|
5225
5239
|
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
|
5226
5240
|
xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"
|
|
5241
|
+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
5242
|
+
xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main"
|
|
5243
|
+
xmlns:p15="http://schemas.microsoft.com/office/powerpoint/2012/main"
|
|
5227
5244
|
saveSubsetFonts="1">
|
|
5228
5245
|
<p:sldMasterIdLst>
|
|
5229
5246
|
<p:sldMasterId id="2147483648" r:id="rId1"/>
|
|
@@ -6645,6 +6662,22 @@ var PptxPresentationSlidesReconciler = class {
|
|
|
6645
6662
|
};
|
|
6646
6663
|
|
|
6647
6664
|
// src/core/core/builders/PptxSlideRelationshipRegistry.ts
|
|
6665
|
+
function isExternalTarget(target) {
|
|
6666
|
+
const normalized = target.trim();
|
|
6667
|
+
if (normalized.length === 0) {
|
|
6668
|
+
return false;
|
|
6669
|
+
}
|
|
6670
|
+
const colonIdx = normalized.indexOf(":");
|
|
6671
|
+
if (colonIdx <= 0) {
|
|
6672
|
+
return false;
|
|
6673
|
+
}
|
|
6674
|
+
const slashIdx = normalized.indexOf("/");
|
|
6675
|
+
if (slashIdx !== -1 && slashIdx < colonIdx) {
|
|
6676
|
+
return false;
|
|
6677
|
+
}
|
|
6678
|
+
const scheme = normalized.slice(0, colonIdx);
|
|
6679
|
+
return /^[A-Za-z][A-Za-z0-9+\-.]*$/.test(scheme);
|
|
6680
|
+
}
|
|
6648
6681
|
var PptxSlideRelationshipRegistry = class {
|
|
6649
6682
|
relationships;
|
|
6650
6683
|
usedRelationshipIds = /* @__PURE__ */ new Set();
|
|
@@ -6715,7 +6748,7 @@ var PptxSlideRelationshipRegistry = class {
|
|
|
6715
6748
|
return existingRelationshipId;
|
|
6716
6749
|
}
|
|
6717
6750
|
const relationshipId = this.nextRelationshipId();
|
|
6718
|
-
const targetMode =
|
|
6751
|
+
const targetMode = isExternalTarget(normalizedTarget) ? "External" : void 0;
|
|
6719
6752
|
this.upsertRelationship(
|
|
6720
6753
|
relationshipId,
|
|
6721
6754
|
this.hyperlinkRelationshipType,
|
|
@@ -6965,6 +6998,82 @@ var PptxSlideNotesPartUpdater = class {
|
|
|
6965
6998
|
}
|
|
6966
6999
|
};
|
|
6967
7000
|
|
|
7001
|
+
// src/core/utils/xml-reorder.ts
|
|
7002
|
+
function reorderObjectKeys(obj, schemaOrder) {
|
|
7003
|
+
const result = {};
|
|
7004
|
+
const consumed = /* @__PURE__ */ new Set();
|
|
7005
|
+
for (const key of schemaOrder) {
|
|
7006
|
+
if (Object.hasOwn(obj, key)) {
|
|
7007
|
+
const value = obj[key];
|
|
7008
|
+
if (value !== void 0) {
|
|
7009
|
+
result[key] = value;
|
|
7010
|
+
}
|
|
7011
|
+
consumed.add(key);
|
|
7012
|
+
}
|
|
7013
|
+
}
|
|
7014
|
+
for (const key of Object.keys(obj)) {
|
|
7015
|
+
if (consumed.has(key)) {
|
|
7016
|
+
continue;
|
|
7017
|
+
}
|
|
7018
|
+
const value = obj[key];
|
|
7019
|
+
if (value !== void 0) {
|
|
7020
|
+
result[key] = value;
|
|
7021
|
+
}
|
|
7022
|
+
}
|
|
7023
|
+
return result;
|
|
7024
|
+
}
|
|
7025
|
+
var EFFECT_LST_ORDER = [
|
|
7026
|
+
"a:blur",
|
|
7027
|
+
"a:fillOverlay",
|
|
7028
|
+
"a:glow",
|
|
7029
|
+
"a:innerShdw",
|
|
7030
|
+
"a:outerShdw",
|
|
7031
|
+
"a:prstShdw",
|
|
7032
|
+
"a:reflection",
|
|
7033
|
+
"a:softEdge"
|
|
7034
|
+
];
|
|
7035
|
+
var SP_PR_ORDER = [
|
|
7036
|
+
"a:xfrm",
|
|
7037
|
+
"a:custGeom",
|
|
7038
|
+
"a:prstGeom",
|
|
7039
|
+
"a:noFill",
|
|
7040
|
+
"a:solidFill",
|
|
7041
|
+
"a:gradFill",
|
|
7042
|
+
"a:blipFill",
|
|
7043
|
+
"a:pattFill",
|
|
7044
|
+
"a:grpFill",
|
|
7045
|
+
"a:ln",
|
|
7046
|
+
"a:effectLst",
|
|
7047
|
+
"a:effectDag",
|
|
7048
|
+
"a:scene3d",
|
|
7049
|
+
"a:sp3d",
|
|
7050
|
+
"a:extLst"
|
|
7051
|
+
];
|
|
7052
|
+
var TC_PR_BORDERS_ORDER = [
|
|
7053
|
+
"a:lnL",
|
|
7054
|
+
"a:lnR",
|
|
7055
|
+
"a:lnT",
|
|
7056
|
+
"a:lnB",
|
|
7057
|
+
"a:lnTlToBr",
|
|
7058
|
+
"a:lnBlToTr",
|
|
7059
|
+
"a:cell3D",
|
|
7060
|
+
"a:noFill",
|
|
7061
|
+
"a:solidFill",
|
|
7062
|
+
"a:gradFill",
|
|
7063
|
+
"a:blipFill",
|
|
7064
|
+
"a:pattFill",
|
|
7065
|
+
"a:grpFill",
|
|
7066
|
+
"a:headers",
|
|
7067
|
+
"a:extLst"
|
|
7068
|
+
];
|
|
7069
|
+
var BLIP_FILL_ORDER = ["a:blip", "a:srcRect", "a:tile", "a:stretch"];
|
|
7070
|
+
var SHAPE_STYLE_ORDER = [
|
|
7071
|
+
"a:lnRef",
|
|
7072
|
+
"a:fillRef",
|
|
7073
|
+
"a:effectRef",
|
|
7074
|
+
"a:fontRef"
|
|
7075
|
+
];
|
|
7076
|
+
|
|
6968
7077
|
// src/core/core/builders/PptxSlideBackgroundBuilder.ts
|
|
6969
7078
|
var PptxSlideBackgroundBuilder = class {
|
|
6970
7079
|
applyBackground(init) {
|
|
@@ -7000,10 +7109,13 @@ var PptxSlideBackgroundBuilder = class {
|
|
|
7000
7109
|
init.slideImageRelationshipType,
|
|
7001
7110
|
relativeBackgroundImagePath
|
|
7002
7111
|
);
|
|
7003
|
-
backgroundProperties["a:blipFill"] =
|
|
7004
|
-
|
|
7005
|
-
|
|
7006
|
-
|
|
7112
|
+
backgroundProperties["a:blipFill"] = reorderObjectKeys(
|
|
7113
|
+
{
|
|
7114
|
+
"a:blip": { "@_r:embed": backgroundRelationshipId },
|
|
7115
|
+
"a:stretch": { "a:fillRect": {} }
|
|
7116
|
+
},
|
|
7117
|
+
BLIP_FILL_ORDER
|
|
7118
|
+
);
|
|
7007
7119
|
}
|
|
7008
7120
|
} else if (hasBackgroundColor && init.slide.backgroundColor) {
|
|
7009
7121
|
backgroundProperties["a:solidFill"] = {
|
|
@@ -7747,6 +7859,45 @@ var PptxGradientStyleCodec = class {
|
|
|
7747
7859
|
b: Number.isFinite(b) ? this.context.clampUnitInterval(b / 1e5) : 0
|
|
7748
7860
|
};
|
|
7749
7861
|
}
|
|
7862
|
+
extractGradientFlip(gradFill) {
|
|
7863
|
+
const flipRaw = String(gradFill["@_flip"] || "").trim().toLowerCase();
|
|
7864
|
+
if (flipRaw === "x" || flipRaw === "y" || flipRaw === "xy" || flipRaw === "none") {
|
|
7865
|
+
return flipRaw;
|
|
7866
|
+
}
|
|
7867
|
+
return void 0;
|
|
7868
|
+
}
|
|
7869
|
+
extractGradientRotWithShape(gradFill) {
|
|
7870
|
+
const rot = gradFill["@_rotWithShape"];
|
|
7871
|
+
if (rot === void 0 || rot === null) {
|
|
7872
|
+
return void 0;
|
|
7873
|
+
}
|
|
7874
|
+
const token = String(rot).trim().toLowerCase();
|
|
7875
|
+
if (token === "1" || token === "true") {
|
|
7876
|
+
return true;
|
|
7877
|
+
}
|
|
7878
|
+
if (token === "0" || token === "false") {
|
|
7879
|
+
return false;
|
|
7880
|
+
}
|
|
7881
|
+
return void 0;
|
|
7882
|
+
}
|
|
7883
|
+
extractGradientScaled(gradFill) {
|
|
7884
|
+
const lin = gradFill["a:lin"];
|
|
7885
|
+
if (!lin) {
|
|
7886
|
+
return void 0;
|
|
7887
|
+
}
|
|
7888
|
+
const scaled = lin["@_scaled"];
|
|
7889
|
+
if (scaled === void 0 || scaled === null) {
|
|
7890
|
+
return void 0;
|
|
7891
|
+
}
|
|
7892
|
+
const token = String(scaled).trim().toLowerCase();
|
|
7893
|
+
if (token === "1" || token === "true") {
|
|
7894
|
+
return true;
|
|
7895
|
+
}
|
|
7896
|
+
if (token === "0" || token === "false") {
|
|
7897
|
+
return false;
|
|
7898
|
+
}
|
|
7899
|
+
return void 0;
|
|
7900
|
+
}
|
|
7750
7901
|
extractGradientAngle(gradFill) {
|
|
7751
7902
|
const angleRaw = Number.parseInt(
|
|
7752
7903
|
String(gradFill["a:lin"]?.["@_ang"] || ""),
|
|
@@ -7833,11 +7984,14 @@ var PptxGradientStyleCodec = class {
|
|
|
7833
7984
|
return void 0;
|
|
7834
7985
|
}
|
|
7835
7986
|
const gradientType = shapeStyle.fillGradientType || "linear";
|
|
7836
|
-
const gradientXml = {
|
|
7837
|
-
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
|
|
7987
|
+
const gradientXml = {};
|
|
7988
|
+
if (shapeStyle.fillGradientFlip && shapeStyle.fillGradientFlip !== "none") {
|
|
7989
|
+
gradientXml["@_flip"] = shapeStyle.fillGradientFlip;
|
|
7990
|
+
}
|
|
7991
|
+
if (shapeStyle.fillGradientRotWithShape !== void 0) {
|
|
7992
|
+
gradientXml["@_rotWithShape"] = shapeStyle.fillGradientRotWithShape ? "1" : "0";
|
|
7993
|
+
}
|
|
7994
|
+
gradientXml["a:gsLst"] = { "a:gs": stops };
|
|
7841
7995
|
if (gradientType === "radial") {
|
|
7842
7996
|
const pathType = shapeStyle.fillGradientPathType || "circle";
|
|
7843
7997
|
const pathXml = {
|
|
@@ -7867,10 +8021,15 @@ var PptxGradientStyleCodec = class {
|
|
|
7867
8021
|
gradientXml["a:path"] = pathXml;
|
|
7868
8022
|
} else {
|
|
7869
8023
|
const normalizedAngle = typeof shapeStyle.fillGradientAngle === "number" && Number.isFinite(shapeStyle.fillGradientAngle) ? shapeStyle.fillGradientAngle : 90;
|
|
7870
|
-
|
|
7871
|
-
"@_ang": String(Math.round(normalizedAngle * 6e4))
|
|
7872
|
-
"@_scaled": "1"
|
|
8024
|
+
const linNode = {
|
|
8025
|
+
"@_ang": String(Math.round(normalizedAngle * 6e4))
|
|
7873
8026
|
};
|
|
8027
|
+
if (shapeStyle.fillGradientScaled !== void 0) {
|
|
8028
|
+
linNode["@_scaled"] = shapeStyle.fillGradientScaled ? "1" : "0";
|
|
8029
|
+
} else {
|
|
8030
|
+
linNode["@_scaled"] = "1";
|
|
8031
|
+
}
|
|
8032
|
+
gradientXml["a:lin"] = linNode;
|
|
7874
8033
|
}
|
|
7875
8034
|
return gradientXml;
|
|
7876
8035
|
}
|
|
@@ -8267,6 +8426,30 @@ var PRESET_SHADOW_OPACITY_MAP = {
|
|
|
8267
8426
|
};
|
|
8268
8427
|
|
|
8269
8428
|
// src/core/core/builders/PptxShapeEffectStyleExtractor.ts
|
|
8429
|
+
var VALID_ALIGNMENTS = /* @__PURE__ */ new Set(["tl", "t", "tr", "l", "ctr", "r", "bl", "b", "br"]);
|
|
8430
|
+
function parseIntAttr(value) {
|
|
8431
|
+
if (value === void 0 || value === null || value === "") {
|
|
8432
|
+
return void 0;
|
|
8433
|
+
}
|
|
8434
|
+
const parsed = Number.parseInt(String(value), 10);
|
|
8435
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
8436
|
+
}
|
|
8437
|
+
function parseAlignmentAttr(value) {
|
|
8438
|
+
const v = String(value ?? "").trim();
|
|
8439
|
+
return VALID_ALIGNMENTS.has(v) ? v : void 0;
|
|
8440
|
+
}
|
|
8441
|
+
function parseBoolAttr(value) {
|
|
8442
|
+
if (typeof value === "boolean") {
|
|
8443
|
+
return value;
|
|
8444
|
+
}
|
|
8445
|
+
if (value === "1" || value === "true") {
|
|
8446
|
+
return true;
|
|
8447
|
+
}
|
|
8448
|
+
if (value === "0" || value === "false") {
|
|
8449
|
+
return false;
|
|
8450
|
+
}
|
|
8451
|
+
return void 0;
|
|
8452
|
+
}
|
|
8270
8453
|
var PptxShapeEffectStyleExtractor = class {
|
|
8271
8454
|
context;
|
|
8272
8455
|
constructor(context) {
|
|
@@ -8290,7 +8473,12 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8290
8473
|
const shadowOffsetX = distance !== void 0 ? Math.round(Math.cos(directionRadians) * distance * 100) / 100 : void 0;
|
|
8291
8474
|
const shadowOffsetY = distance !== void 0 ? Math.round(Math.sin(directionRadians) * distance * 100) / 100 : void 0;
|
|
8292
8475
|
const rotateWithShape = outerShadow["@_rotWithShape"];
|
|
8293
|
-
const shadowRotateWithShape = typeof rotateWithShape === "boolean" ? rotateWithShape : rotateWithShape === "1" || rotateWithShape === "true" ? true : void 0;
|
|
8476
|
+
const shadowRotateWithShape = typeof rotateWithShape === "boolean" ? rotateWithShape : rotateWithShape === "1" || rotateWithShape === "true" ? true : rotateWithShape === "0" || rotateWithShape === "false" ? false : void 0;
|
|
8477
|
+
const shadowScaleX = parseIntAttr(outerShadow["@_sx"]);
|
|
8478
|
+
const shadowScaleY = parseIntAttr(outerShadow["@_sy"]);
|
|
8479
|
+
const shadowSkewX = parseIntAttr(outerShadow["@_kx"]);
|
|
8480
|
+
const shadowSkewY = parseIntAttr(outerShadow["@_ky"]);
|
|
8481
|
+
const shadowAlignment = parseAlignmentAttr(outerShadow["@_algn"]);
|
|
8294
8482
|
return {
|
|
8295
8483
|
shadowColor,
|
|
8296
8484
|
shadowOpacity,
|
|
@@ -8299,7 +8487,12 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8299
8487
|
shadowOffsetY,
|
|
8300
8488
|
shadowAngle: directionDegrees,
|
|
8301
8489
|
shadowDistance: distance,
|
|
8302
|
-
shadowRotateWithShape
|
|
8490
|
+
shadowRotateWithShape,
|
|
8491
|
+
shadowScaleX,
|
|
8492
|
+
shadowScaleY,
|
|
8493
|
+
shadowSkewX,
|
|
8494
|
+
shadowSkewY,
|
|
8495
|
+
shadowAlignment
|
|
8303
8496
|
};
|
|
8304
8497
|
}
|
|
8305
8498
|
extractPresetShadowStyle(effectLstParent) {
|
|
@@ -8345,12 +8538,14 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8345
8538
|
const directionRadians = directionDegrees * Math.PI / 180;
|
|
8346
8539
|
const innerShadowOffsetX = distance !== void 0 ? Math.round(Math.cos(directionRadians) * distance * 100) / 100 : void 0;
|
|
8347
8540
|
const innerShadowOffsetY = distance !== void 0 ? Math.round(Math.sin(directionRadians) * distance * 100) / 100 : void 0;
|
|
8541
|
+
const innerShadowRotateWithShape = parseBoolAttr(innerShadow["@_rotWithShape"]);
|
|
8348
8542
|
return {
|
|
8349
8543
|
innerShadowColor,
|
|
8350
8544
|
innerShadowOpacity,
|
|
8351
8545
|
innerShadowBlur,
|
|
8352
8546
|
innerShadowOffsetX,
|
|
8353
|
-
innerShadowOffsetY
|
|
8547
|
+
innerShadowOffsetY,
|
|
8548
|
+
innerShadowRotateWithShape
|
|
8354
8549
|
};
|
|
8355
8550
|
}
|
|
8356
8551
|
extractGlowStyle(shapeProps) {
|
|
@@ -8399,6 +8594,16 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8399
8594
|
const reflectionRotation = Number.isFinite(rotationRaw) ? rotationRaw / 6e4 : void 0;
|
|
8400
8595
|
const distanceRaw = Number.parseInt(String(reflectionNode["@_dist"] || ""), 10);
|
|
8401
8596
|
const reflectionDistance = Number.isFinite(distanceRaw) && distanceRaw >= 0 ? distanceRaw / this.context.emuPerPx : void 0;
|
|
8597
|
+
const fadeDirRaw = parseIntAttr(reflectionNode["@_fadeDir"]);
|
|
8598
|
+
const reflectionFadeDirection = fadeDirRaw !== void 0 ? fadeDirRaw / 6e4 : void 0;
|
|
8599
|
+
const reflectionScaleX = parseIntAttr(reflectionNode["@_sx"]);
|
|
8600
|
+
const reflectionScaleY = parseIntAttr(reflectionNode["@_sy"]);
|
|
8601
|
+
const reflectionSkewX = parseIntAttr(reflectionNode["@_kx"]);
|
|
8602
|
+
const reflectionSkewY = parseIntAttr(reflectionNode["@_ky"]);
|
|
8603
|
+
const reflectionAlignment = parseAlignmentAttr(reflectionNode["@_algn"]);
|
|
8604
|
+
const reflectionRotateWithShape = parseBoolAttr(reflectionNode["@_rotWithShape"]);
|
|
8605
|
+
const stPosRaw = parseIntAttr(reflectionNode["@_stPos"]);
|
|
8606
|
+
const reflectionStartPosition = stPosRaw !== void 0 ? stPosRaw / 1e5 : void 0;
|
|
8402
8607
|
return {
|
|
8403
8608
|
reflectionBlurRadius,
|
|
8404
8609
|
reflectionStartOpacity,
|
|
@@ -8406,7 +8611,15 @@ var PptxShapeEffectStyleExtractor = class {
|
|
|
8406
8611
|
reflectionEndPosition,
|
|
8407
8612
|
reflectionDirection,
|
|
8408
8613
|
reflectionRotation,
|
|
8409
|
-
reflectionDistance
|
|
8614
|
+
reflectionDistance,
|
|
8615
|
+
reflectionFadeDirection,
|
|
8616
|
+
reflectionScaleX,
|
|
8617
|
+
reflectionScaleY,
|
|
8618
|
+
reflectionSkewX,
|
|
8619
|
+
reflectionSkewY,
|
|
8620
|
+
reflectionAlignment,
|
|
8621
|
+
reflectionRotateWithShape,
|
|
8622
|
+
reflectionStartPosition
|
|
8410
8623
|
};
|
|
8411
8624
|
}
|
|
8412
8625
|
extractBlurStyle(shapeProps) {
|
|
@@ -8458,11 +8671,56 @@ var PptxShapeEffectXmlBuilder = class {
|
|
|
8458
8671
|
}
|
|
8459
8672
|
}
|
|
8460
8673
|
};
|
|
8674
|
+
if (typeof shapeStyle.shadowScaleX === "number") {
|
|
8675
|
+
xmlObj["@_sx"] = String(Math.round(shapeStyle.shadowScaleX));
|
|
8676
|
+
}
|
|
8677
|
+
if (typeof shapeStyle.shadowScaleY === "number") {
|
|
8678
|
+
xmlObj["@_sy"] = String(Math.round(shapeStyle.shadowScaleY));
|
|
8679
|
+
}
|
|
8680
|
+
if (typeof shapeStyle.shadowSkewX === "number") {
|
|
8681
|
+
xmlObj["@_kx"] = String(Math.round(shapeStyle.shadowSkewX));
|
|
8682
|
+
}
|
|
8683
|
+
if (typeof shapeStyle.shadowSkewY === "number") {
|
|
8684
|
+
xmlObj["@_ky"] = String(Math.round(shapeStyle.shadowSkewY));
|
|
8685
|
+
}
|
|
8686
|
+
if (shapeStyle.shadowAlignment) {
|
|
8687
|
+
xmlObj["@_algn"] = shapeStyle.shadowAlignment;
|
|
8688
|
+
}
|
|
8461
8689
|
if (typeof shapeStyle.shadowRotateWithShape === "boolean") {
|
|
8462
8690
|
xmlObj["@_rotWithShape"] = shapeStyle.shadowRotateWithShape ? "1" : "0";
|
|
8463
8691
|
}
|
|
8464
8692
|
return xmlObj;
|
|
8465
8693
|
}
|
|
8694
|
+
buildPresetShadowXml(shapeStyle) {
|
|
8695
|
+
const preset = shapeStyle.presetShadowName;
|
|
8696
|
+
if (!preset || preset.length === 0) {
|
|
8697
|
+
return void 0;
|
|
8698
|
+
}
|
|
8699
|
+
const shadowColor = String(shapeStyle.shadowColor || "#000000").trim();
|
|
8700
|
+
const shadowOpacity = typeof shapeStyle.shadowOpacity === "number" && Number.isFinite(shapeStyle.shadowOpacity) ? this.context.clampUnitInterval(shapeStyle.shadowOpacity) : 0.5;
|
|
8701
|
+
let distance;
|
|
8702
|
+
let directionDegrees;
|
|
8703
|
+
if (typeof shapeStyle.shadowAngle === "number" && typeof shapeStyle.shadowDistance === "number") {
|
|
8704
|
+
directionDegrees = shapeStyle.shadowAngle;
|
|
8705
|
+
distance = shapeStyle.shadowDistance;
|
|
8706
|
+
} else {
|
|
8707
|
+
const ox = typeof shapeStyle.shadowOffsetX === "number" ? shapeStyle.shadowOffsetX : 0;
|
|
8708
|
+
const oy = typeof shapeStyle.shadowOffsetY === "number" ? shapeStyle.shadowOffsetY : 0;
|
|
8709
|
+
distance = Math.sqrt(ox * ox + oy * oy);
|
|
8710
|
+
directionDegrees = (Math.atan2(oy, ox) * 180 / Math.PI + 360) % 360;
|
|
8711
|
+
}
|
|
8712
|
+
return {
|
|
8713
|
+
"@_prst": preset,
|
|
8714
|
+
"@_dist": String(Math.round(distance * this.context.emuPerPx)),
|
|
8715
|
+
"@_dir": String(Math.round(directionDegrees * 6e4)),
|
|
8716
|
+
"a:srgbClr": {
|
|
8717
|
+
"@_val": shadowColor.replace("#", ""),
|
|
8718
|
+
"a:alpha": {
|
|
8719
|
+
"@_val": String(Math.round(shadowOpacity * 1e5))
|
|
8720
|
+
}
|
|
8721
|
+
}
|
|
8722
|
+
};
|
|
8723
|
+
}
|
|
8466
8724
|
buildInnerShadowXml(shapeStyle) {
|
|
8467
8725
|
const innerColor = String(shapeStyle.innerShadowColor || "").trim();
|
|
8468
8726
|
if (innerColor.length === 0 || innerColor === "transparent") {
|
|
@@ -8474,7 +8732,7 @@ var PptxShapeEffectXmlBuilder = class {
|
|
|
8474
8732
|
const opacity = typeof shapeStyle.innerShadowOpacity === "number" && Number.isFinite(shapeStyle.innerShadowOpacity) ? this.context.clampUnitInterval(shapeStyle.innerShadowOpacity) : 0.5;
|
|
8475
8733
|
const distance = Math.sqrt(offsetX * offsetX + offsetY * offsetY);
|
|
8476
8734
|
const directionDegrees = (Math.atan2(offsetY, offsetX) * 180 / Math.PI + 360) % 360;
|
|
8477
|
-
|
|
8735
|
+
const xmlObj = {
|
|
8478
8736
|
"@_blurRad": String(Math.round(blurValue * this.context.emuPerPx)),
|
|
8479
8737
|
"@_dist": String(Math.round(distance * this.context.emuPerPx)),
|
|
8480
8738
|
"@_dir": String(Math.round(directionDegrees * 6e4)),
|
|
@@ -8485,6 +8743,10 @@ var PptxShapeEffectXmlBuilder = class {
|
|
|
8485
8743
|
}
|
|
8486
8744
|
}
|
|
8487
8745
|
};
|
|
8746
|
+
if (typeof shapeStyle.innerShadowRotateWithShape === "boolean") {
|
|
8747
|
+
xmlObj["@_rotWithShape"] = shapeStyle.innerShadowRotateWithShape ? "1" : "0";
|
|
8748
|
+
}
|
|
8749
|
+
return xmlObj;
|
|
8488
8750
|
}
|
|
8489
8751
|
buildGlowXml(shapeStyle) {
|
|
8490
8752
|
const glowColor = String(shapeStyle.glowColor || "").trim();
|
|
@@ -8546,6 +8808,30 @@ var PptxShapeEffectXmlBuilder = class {
|
|
|
8546
8808
|
Math.round(shapeStyle.reflectionDistance * this.context.emuPerPx)
|
|
8547
8809
|
);
|
|
8548
8810
|
}
|
|
8811
|
+
if (typeof shapeStyle.reflectionFadeDirection === "number") {
|
|
8812
|
+
reflectionXml["@_fadeDir"] = String(Math.round(shapeStyle.reflectionFadeDirection * 6e4));
|
|
8813
|
+
}
|
|
8814
|
+
if (typeof shapeStyle.reflectionScaleX === "number") {
|
|
8815
|
+
reflectionXml["@_sx"] = String(Math.round(shapeStyle.reflectionScaleX));
|
|
8816
|
+
}
|
|
8817
|
+
if (typeof shapeStyle.reflectionScaleY === "number") {
|
|
8818
|
+
reflectionXml["@_sy"] = String(Math.round(shapeStyle.reflectionScaleY));
|
|
8819
|
+
}
|
|
8820
|
+
if (typeof shapeStyle.reflectionSkewX === "number") {
|
|
8821
|
+
reflectionXml["@_kx"] = String(Math.round(shapeStyle.reflectionSkewX));
|
|
8822
|
+
}
|
|
8823
|
+
if (typeof shapeStyle.reflectionSkewY === "number") {
|
|
8824
|
+
reflectionXml["@_ky"] = String(Math.round(shapeStyle.reflectionSkewY));
|
|
8825
|
+
}
|
|
8826
|
+
if (shapeStyle.reflectionAlignment) {
|
|
8827
|
+
reflectionXml["@_algn"] = shapeStyle.reflectionAlignment;
|
|
8828
|
+
}
|
|
8829
|
+
if (typeof shapeStyle.reflectionRotateWithShape === "boolean") {
|
|
8830
|
+
reflectionXml["@_rotWithShape"] = shapeStyle.reflectionRotateWithShape ? "1" : "0";
|
|
8831
|
+
}
|
|
8832
|
+
if (typeof shapeStyle.reflectionStartPosition === "number") {
|
|
8833
|
+
reflectionXml["@_stPos"] = String(Math.round(shapeStyle.reflectionStartPosition * 1e5));
|
|
8834
|
+
}
|
|
8549
8835
|
return reflectionXml;
|
|
8550
8836
|
}
|
|
8551
8837
|
buildBlurXml(shapeStyle) {
|
|
@@ -8653,6 +8939,9 @@ var PptxShapeEffectXmlCodec = class {
|
|
|
8653
8939
|
buildOuterShadowXml(shapeStyle) {
|
|
8654
8940
|
return this.builder.buildOuterShadowXml(shapeStyle);
|
|
8655
8941
|
}
|
|
8942
|
+
buildPresetShadowXml(shapeStyle) {
|
|
8943
|
+
return this.builder.buildPresetShadowXml(shapeStyle);
|
|
8944
|
+
}
|
|
8656
8945
|
buildInnerShadowXml(shapeStyle) {
|
|
8657
8946
|
return this.builder.buildInnerShadowXml(shapeStyle);
|
|
8658
8947
|
}
|
|
@@ -8813,6 +9102,9 @@ var PptxColorStyleCodec = class {
|
|
|
8813
9102
|
buildOuterShadowXml(shapeStyle) {
|
|
8814
9103
|
return this.shapeEffectXmlCodec.buildOuterShadowXml(shapeStyle);
|
|
8815
9104
|
}
|
|
9105
|
+
buildPresetShadowXml(shapeStyle) {
|
|
9106
|
+
return this.shapeEffectXmlCodec.buildPresetShadowXml(shapeStyle);
|
|
9107
|
+
}
|
|
8816
9108
|
buildInnerShadowXml(shapeStyle) {
|
|
8817
9109
|
return this.shapeEffectXmlCodec.buildInnerShadowXml(shapeStyle);
|
|
8818
9110
|
}
|
|
@@ -8834,6 +9126,15 @@ var PptxColorStyleCodec = class {
|
|
|
8834
9126
|
extractGradientFillColor(gradFill) {
|
|
8835
9127
|
return this.gradientStyleCodec.extractGradientFillColor(gradFill);
|
|
8836
9128
|
}
|
|
9129
|
+
extractGradientFlip(gradFill) {
|
|
9130
|
+
return this.gradientStyleCodec.extractGradientFlip(gradFill);
|
|
9131
|
+
}
|
|
9132
|
+
extractGradientRotWithShape(gradFill) {
|
|
9133
|
+
return this.gradientStyleCodec.extractGradientRotWithShape(gradFill);
|
|
9134
|
+
}
|
|
9135
|
+
extractGradientScaled(gradFill) {
|
|
9136
|
+
return this.gradientStyleCodec.extractGradientScaled(gradFill);
|
|
9137
|
+
}
|
|
8837
9138
|
extractGradientPathType(gradFill) {
|
|
8838
9139
|
return this.gradientStyleCodec.extractGradientPathType(gradFill);
|
|
8839
9140
|
}
|
|
@@ -8845,6 +9146,61 @@ var PptxColorStyleCodec = class {
|
|
|
8845
9146
|
}
|
|
8846
9147
|
};
|
|
8847
9148
|
|
|
9149
|
+
// src/core/utils/color-xml-preservation.ts
|
|
9150
|
+
var COLOR_CHOICE_KEYS = [
|
|
9151
|
+
"a:srgbClr",
|
|
9152
|
+
"a:schemeClr",
|
|
9153
|
+
"a:sysClr",
|
|
9154
|
+
"a:prstClr",
|
|
9155
|
+
"a:scrgbClr",
|
|
9156
|
+
"a:hslClr"
|
|
9157
|
+
];
|
|
9158
|
+
function extractColorChoiceXml(parent) {
|
|
9159
|
+
if (!parent) {
|
|
9160
|
+
return void 0;
|
|
9161
|
+
}
|
|
9162
|
+
for (const key of COLOR_CHOICE_KEYS) {
|
|
9163
|
+
if (parent[key] !== void 0) {
|
|
9164
|
+
return { [key]: parent[key] };
|
|
9165
|
+
}
|
|
9166
|
+
}
|
|
9167
|
+
return void 0;
|
|
9168
|
+
}
|
|
9169
|
+
function normalizeHex(value) {
|
|
9170
|
+
const raw = String(value ?? "").trim();
|
|
9171
|
+
if (raw.length === 0) {
|
|
9172
|
+
return "";
|
|
9173
|
+
}
|
|
9174
|
+
const hex = raw.replace(/^#/, "");
|
|
9175
|
+
if (/^[0-9a-fA-F]{6}$/.test(hex)) {
|
|
9176
|
+
return hex.toUpperCase();
|
|
9177
|
+
}
|
|
9178
|
+
return raw.toLowerCase();
|
|
9179
|
+
}
|
|
9180
|
+
function colorsEqual(left, right) {
|
|
9181
|
+
if (left === void 0 || right === void 0) {
|
|
9182
|
+
return false;
|
|
9183
|
+
}
|
|
9184
|
+
return normalizeHex(left) === normalizeHex(right);
|
|
9185
|
+
}
|
|
9186
|
+
function buildSrgbColorChoice(hex, opacity) {
|
|
9187
|
+
const normalized = String(hex || "").replace(/^#/, "");
|
|
9188
|
+
const srgb = { "@_val": normalized };
|
|
9189
|
+
if (typeof opacity === "number" && Number.isFinite(opacity) && opacity >= 0 && opacity < 1) {
|
|
9190
|
+
const alphaPct = Math.round(Math.max(0, Math.min(1, opacity)) * 1e5);
|
|
9191
|
+
srgb["a:alpha"] = { "@_val": String(alphaPct) };
|
|
9192
|
+
}
|
|
9193
|
+
return { "a:srgbClr": srgb };
|
|
9194
|
+
}
|
|
9195
|
+
function serializeColorChoice(originalColorXml, currentResolvedHex, fallbackHex, opacity, options = {}) {
|
|
9196
|
+
if (originalColorXml && colorsEqual(currentResolvedHex, fallbackHex)) {
|
|
9197
|
+
if (options.preserveAlphaFromOriginal !== false) {
|
|
9198
|
+
return originalColorXml;
|
|
9199
|
+
}
|
|
9200
|
+
}
|
|
9201
|
+
return buildSrgbColorChoice(fallbackHex, opacity);
|
|
9202
|
+
}
|
|
9203
|
+
|
|
8848
9204
|
// src/core/core/builders/shape-style-3d-helpers.ts
|
|
8849
9205
|
function applyScene3dStyle(shapeProps, style) {
|
|
8850
9206
|
const scene3dNode = shapeProps["a:scene3d"];
|
|
@@ -8930,6 +9286,10 @@ function applyStrokeColor(lineNode, style, context) {
|
|
|
8930
9286
|
const lineFill = lineNode["a:solidFill"];
|
|
8931
9287
|
style.strokeColor = context.parseColor(lineFill);
|
|
8932
9288
|
style.strokeOpacity = context.extractColorOpacity(lineFill);
|
|
9289
|
+
const strokeColorXml = extractColorChoiceXml(lineFill);
|
|
9290
|
+
if (strokeColorXml) {
|
|
9291
|
+
style.strokeColorXml = strokeColorXml;
|
|
9292
|
+
}
|
|
8933
9293
|
} else if (lineNode["a:gradFill"]) {
|
|
8934
9294
|
style.strokeColor = context.extractGradientFillColor(lineNode["a:gradFill"]);
|
|
8935
9295
|
style.strokeOpacity = context.extractGradientOpacity(lineNode["a:gradFill"]);
|
|
@@ -8997,6 +9357,14 @@ function applyJoinCapCompound(lineNode, style) {
|
|
|
8997
9357
|
style.lineJoin = "bevel";
|
|
8998
9358
|
} else if ("a:miter" in lineNode) {
|
|
8999
9359
|
style.lineJoin = "miter";
|
|
9360
|
+
const miterNode = lineNode["a:miter"];
|
|
9361
|
+
const limRaw = miterNode?.["@_lim"];
|
|
9362
|
+
if (limRaw !== void 0 && limRaw !== "") {
|
|
9363
|
+
const parsed = parseInt(String(limRaw), 10);
|
|
9364
|
+
if (Number.isFinite(parsed)) {
|
|
9365
|
+
style.miterLimit = parsed;
|
|
9366
|
+
}
|
|
9367
|
+
}
|
|
9000
9368
|
}
|
|
9001
9369
|
const capValue = String(lineNode["@_cap"] || "").trim().toLowerCase();
|
|
9002
9370
|
if (capValue === "rnd" || capValue === "sq" || capValue === "flat") {
|
|
@@ -9053,6 +9421,10 @@ var PptxShapeStyleExtractor = class {
|
|
|
9053
9421
|
style.fillMode = "solid";
|
|
9054
9422
|
style.fillColor = this.context.parseColor(solidFill);
|
|
9055
9423
|
style.fillOpacity = this.context.extractColorOpacity(solidFill);
|
|
9424
|
+
const solidFillColorXml = extractColorChoiceXml(solidFill);
|
|
9425
|
+
if (solidFillColorXml) {
|
|
9426
|
+
style.fillColorXml = solidFillColorXml;
|
|
9427
|
+
}
|
|
9056
9428
|
} else if (gradFill) {
|
|
9057
9429
|
style.fillMode = "gradient";
|
|
9058
9430
|
style.fillColor = this.context.extractGradientFillColor(gradFill);
|
|
@@ -9064,6 +9436,18 @@ var PptxShapeStyleExtractor = class {
|
|
|
9064
9436
|
style.fillGradientPathType = this.context.extractGradientPathType(gradFill);
|
|
9065
9437
|
style.fillGradientFocalPoint = this.context.extractGradientFocalPoint(gradFill);
|
|
9066
9438
|
style.fillGradientFillToRect = this.context.extractGradientFillToRect(gradFill);
|
|
9439
|
+
const gradFlip = this.context.extractGradientFlip(gradFill);
|
|
9440
|
+
if (gradFlip) {
|
|
9441
|
+
style.fillGradientFlip = gradFlip;
|
|
9442
|
+
}
|
|
9443
|
+
const gradRot = this.context.extractGradientRotWithShape(gradFill);
|
|
9444
|
+
if (gradRot !== void 0) {
|
|
9445
|
+
style.fillGradientRotWithShape = gradRot;
|
|
9446
|
+
}
|
|
9447
|
+
const gradScaled = this.context.extractGradientScaled(gradFill);
|
|
9448
|
+
if (gradScaled !== void 0) {
|
|
9449
|
+
style.fillGradientScaled = gradScaled;
|
|
9450
|
+
}
|
|
9067
9451
|
} else if (pattFill) {
|
|
9068
9452
|
style.fillMode = "pattern";
|
|
9069
9453
|
style.fillColor = this.context.parseColor(pattFill["a:fgClr"]) || this.context.parseColor(pattFill["a:bgClr"]);
|
|
@@ -9145,10 +9529,45 @@ var PptxShapeStyleExtractor = class {
|
|
|
9145
9529
|
if (styleNode?.["a:effectRef"]) {
|
|
9146
9530
|
this.context.resolveThemeEffectRef(styleNode["a:effectRef"], style);
|
|
9147
9531
|
}
|
|
9532
|
+
const fontRef = styleNode?.["a:fontRef"];
|
|
9533
|
+
if (fontRef) {
|
|
9534
|
+
const idxAttr = String(fontRef["@_idx"] || "").trim();
|
|
9535
|
+
if (idxAttr.length > 0) {
|
|
9536
|
+
style.fontRefIdx = idxAttr;
|
|
9537
|
+
}
|
|
9538
|
+
const overrideColorXml = this.extractFontRefColorXml(fontRef);
|
|
9539
|
+
if (overrideColorXml) {
|
|
9540
|
+
style.fontRefColorXml = overrideColorXml;
|
|
9541
|
+
}
|
|
9542
|
+
}
|
|
9148
9543
|
applyScene3dStyle(shapeProps, style);
|
|
9149
9544
|
applyShape3dStyle(shapeProps, style, this.context);
|
|
9150
9545
|
return style;
|
|
9151
9546
|
}
|
|
9547
|
+
/**
|
|
9548
|
+
* Pull the verbatim colour-choice child out of an `a:fontRef` element,
|
|
9549
|
+
* preserving any contained colour transforms for round-trip.
|
|
9550
|
+
*/
|
|
9551
|
+
extractFontRefColorXml(refNode) {
|
|
9552
|
+
if (!refNode) {
|
|
9553
|
+
return void 0;
|
|
9554
|
+
}
|
|
9555
|
+
const keys = [
|
|
9556
|
+
"a:scrgbClr",
|
|
9557
|
+
"a:srgbClr",
|
|
9558
|
+
"a:hslClr",
|
|
9559
|
+
"a:sysClr",
|
|
9560
|
+
"a:schemeClr",
|
|
9561
|
+
"a:prstClr"
|
|
9562
|
+
];
|
|
9563
|
+
for (const key of keys) {
|
|
9564
|
+
const child = refNode[key];
|
|
9565
|
+
if (child !== void 0) {
|
|
9566
|
+
return { [key]: child };
|
|
9567
|
+
}
|
|
9568
|
+
}
|
|
9569
|
+
return void 0;
|
|
9570
|
+
}
|
|
9152
9571
|
/**
|
|
9153
9572
|
* Extract p14:hiddenFill from the shape properties extension list.
|
|
9154
9573
|
* URI: {AF507438-7753-43E0-B8FC-AC1667EBCBE1}
|
|
@@ -9199,10 +9618,15 @@ var PptxShapeStyleExtractor = class {
|
|
|
9199
9618
|
function applyCellFillStyle(cellProperties, style, context) {
|
|
9200
9619
|
let hasStyle = false;
|
|
9201
9620
|
if (cellProperties?.["a:solidFill"]) {
|
|
9202
|
-
const
|
|
9621
|
+
const solidFillNode = cellProperties["a:solidFill"];
|
|
9622
|
+
const fillColor = context.parseColor(solidFillNode);
|
|
9203
9623
|
if (fillColor) {
|
|
9204
9624
|
style.fillMode = "solid";
|
|
9205
9625
|
style.backgroundColor = fillColor;
|
|
9626
|
+
const bgColorXml = extractColorChoiceXml(solidFillNode);
|
|
9627
|
+
if (bgColorXml) {
|
|
9628
|
+
style.backgroundColorXml = bgColorXml;
|
|
9629
|
+
}
|
|
9206
9630
|
hasStyle = true;
|
|
9207
9631
|
}
|
|
9208
9632
|
}
|
|
@@ -9239,6 +9663,10 @@ function applyCellFillStyle(cellProperties, style, context) {
|
|
|
9239
9663
|
}
|
|
9240
9664
|
}
|
|
9241
9665
|
}
|
|
9666
|
+
if (cellProperties?.["a:noFill"] !== void 0) {
|
|
9667
|
+
style.fillMode = "none";
|
|
9668
|
+
hasStyle = true;
|
|
9669
|
+
}
|
|
9242
9670
|
if (cellProperties?.["a:pattFill"]) {
|
|
9243
9671
|
const pattFill = cellProperties["a:pattFill"];
|
|
9244
9672
|
const fgColor = context.parseColor(pattFill["a:fgClr"]);
|
|
@@ -9545,8 +9973,7 @@ var PptxTableDataParser = class {
|
|
|
9545
9973
|
return width / totalWidthEmu;
|
|
9546
9974
|
}) : gridColumns.map(() => 1 / Math.max(gridColumns.length, 1));
|
|
9547
9975
|
const tableProperties = tableNode["a:tblPr"] || {};
|
|
9548
|
-
const
|
|
9549
|
-
const tableStyleId = String(tableStyleNode?.["@_val"] || tableProperties["@_tblStyle"] || "").trim() || void 0;
|
|
9976
|
+
const tableStyleId = this.extractTableStyleId(tableProperties);
|
|
9550
9977
|
const xmlRows = this.context.ensureArray(tableNode["a:tr"]);
|
|
9551
9978
|
const rows = xmlRows.map((rowNode) => {
|
|
9552
9979
|
const rowHeightEmu = parseInt(String(rowNode?.["@_h"] || "0"), 10) || 0;
|
|
@@ -9581,6 +10008,28 @@ var PptxTableDataParser = class {
|
|
|
9581
10008
|
return void 0;
|
|
9582
10009
|
}
|
|
9583
10010
|
}
|
|
10011
|
+
/**
|
|
10012
|
+
* Read the table style ID from `a:tblPr`.
|
|
10013
|
+
*
|
|
10014
|
+
* ECMA-376 §21.1.3.13 defines `<a:tableStyleId>{GUID}</a:tableStyleId>` as
|
|
10015
|
+
* a child element of `a:tblPr` carrying the GUID as element text. Older
|
|
10016
|
+
* inputs (and earlier versions of this library) used the legacy
|
|
10017
|
+
* `<a:tblStyle val="{GUID}"/>` child element or a `@_tblStyle` attribute.
|
|
10018
|
+
* Accept all three; the spec form takes precedence.
|
|
10019
|
+
*/
|
|
10020
|
+
extractTableStyleId(tableProperties) {
|
|
10021
|
+
const tableStyleIdNode = tableProperties["a:tableStyleId"];
|
|
10022
|
+
if (tableStyleIdNode !== void 0 && tableStyleIdNode !== null) {
|
|
10023
|
+
const direct = typeof tableStyleIdNode === "string" || typeof tableStyleIdNode === "number" ? String(tableStyleIdNode) : String(tableStyleIdNode["#text"] ?? "");
|
|
10024
|
+
const trimmed = direct.trim();
|
|
10025
|
+
if (trimmed.length > 0) {
|
|
10026
|
+
return trimmed;
|
|
10027
|
+
}
|
|
10028
|
+
}
|
|
10029
|
+
const tableStyleNode = tableProperties["a:tblStyle"];
|
|
10030
|
+
const legacy = String(tableStyleNode?.["@_val"] || tableProperties["@_tblStyle"] || "").trim();
|
|
10031
|
+
return legacy.length > 0 ? legacy : void 0;
|
|
10032
|
+
}
|
|
9584
10033
|
extractTableCellText(tableCell) {
|
|
9585
10034
|
const paragraphs = this.context.ensureArray(tableCell?.["a:txBody"]?.["a:p"]);
|
|
9586
10035
|
const lines = [];
|
|
@@ -9859,6 +10308,19 @@ var PptxGraphicFrameParser = class {
|
|
|
9859
10308
|
if (graphicData["a:videoFile"] || graphicData["a:audioFile"] || uri.includes("/drawingml/2006/media")) {
|
|
9860
10309
|
return "media";
|
|
9861
10310
|
}
|
|
10311
|
+
if (graphicData["aink:ink"] || uri.includes("/2010/ink") || uri.includes("drawing/2010/ink")) {
|
|
10312
|
+
return "ink";
|
|
10313
|
+
}
|
|
10314
|
+
const alternateContent = graphicData["mc:AlternateContent"];
|
|
10315
|
+
if (alternateContent) {
|
|
10316
|
+
const choices = Array.isArray(alternateContent["mc:Choice"]) ? alternateContent["mc:Choice"] : alternateContent["mc:Choice"] ? [alternateContent["mc:Choice"]] : [];
|
|
10317
|
+
for (const choice of choices) {
|
|
10318
|
+
const requires = String(choice?.["@_Requires"] || "").toLowerCase();
|
|
10319
|
+
if (requires.includes("aink") || choice?.["aink:ink"]) {
|
|
10320
|
+
return "ink";
|
|
10321
|
+
}
|
|
10322
|
+
}
|
|
10323
|
+
}
|
|
9862
10324
|
return "unknown";
|
|
9863
10325
|
}
|
|
9864
10326
|
};
|
|
@@ -10760,6 +11222,7 @@ var PptxDocumentPropertiesUpdater = class {
|
|
|
10760
11222
|
}));
|
|
10761
11223
|
if (sanitized.length === 0) {
|
|
10762
11224
|
this.context.zip.remove("docProps/custom.xml");
|
|
11225
|
+
await this.removeCustomPropertiesPackagingArtifacts();
|
|
10763
11226
|
return;
|
|
10764
11227
|
}
|
|
10765
11228
|
const customXml = {
|
|
@@ -10779,6 +11242,116 @@ var PptxDocumentPropertiesUpdater = class {
|
|
|
10779
11242
|
}
|
|
10780
11243
|
};
|
|
10781
11244
|
this.context.zip.file("docProps/custom.xml", this.context.builder.build(customXml));
|
|
11245
|
+
await this.ensureCustomPropertiesPackagingArtifacts();
|
|
11246
|
+
}
|
|
11247
|
+
/**
|
|
11248
|
+
* Ensure `[Content_Types].xml` has an `Override` for `docProps/custom.xml`
|
|
11249
|
+
* and the root `_rels/.rels` references it (ECMA-376 §15.2.12.2 +
|
|
11250
|
+
* Part 2 §10.1.2.5). Without these, the package fails OPC validation
|
|
11251
|
+
* and Office strips the custom properties on next save.
|
|
11252
|
+
*/
|
|
11253
|
+
async ensureCustomPropertiesPackagingArtifacts() {
|
|
11254
|
+
const customContentType = "application/vnd.openxmlformats-officedocument.custom-properties+xml";
|
|
11255
|
+
const customRelType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties";
|
|
11256
|
+
const ctFile = this.context.zip.file("[Content_Types].xml");
|
|
11257
|
+
if (ctFile) {
|
|
11258
|
+
try {
|
|
11259
|
+
const ctXml = await ctFile.async("string");
|
|
11260
|
+
const ctData = this.context.parser.parse(ctXml);
|
|
11261
|
+
const types = ctData["Types"];
|
|
11262
|
+
if (types) {
|
|
11263
|
+
const overrides = Array.isArray(types["Override"]) ? types["Override"] : types["Override"] ? [types["Override"]] : [];
|
|
11264
|
+
const hasCustomOverride = overrides.some(
|
|
11265
|
+
(o) => String(o?.["@_PartName"] || "") === "/docProps/custom.xml"
|
|
11266
|
+
);
|
|
11267
|
+
if (!hasCustomOverride) {
|
|
11268
|
+
overrides.push({
|
|
11269
|
+
"@_PartName": "/docProps/custom.xml",
|
|
11270
|
+
"@_ContentType": customContentType
|
|
11271
|
+
});
|
|
11272
|
+
types["Override"] = overrides.length === 1 ? overrides[0] : overrides;
|
|
11273
|
+
this.context.zip.file("[Content_Types].xml", this.context.builder.build(ctData));
|
|
11274
|
+
}
|
|
11275
|
+
}
|
|
11276
|
+
} catch (error) {
|
|
11277
|
+
console.warn("Failed to update [Content_Types].xml for custom properties:", error);
|
|
11278
|
+
}
|
|
11279
|
+
}
|
|
11280
|
+
const relsFile = this.context.zip.file("_rels/.rels");
|
|
11281
|
+
if (relsFile) {
|
|
11282
|
+
try {
|
|
11283
|
+
const relsXml = await relsFile.async("string");
|
|
11284
|
+
const relsData = this.context.parser.parse(relsXml);
|
|
11285
|
+
const relationships = relsData["Relationships"];
|
|
11286
|
+
if (relationships) {
|
|
11287
|
+
const rels = Array.isArray(relationships["Relationship"]) ? relationships["Relationship"] : relationships["Relationship"] ? [relationships["Relationship"]] : [];
|
|
11288
|
+
const hasCustomRel = rels.some((r) => String(r?.["@_Type"] || "") === customRelType);
|
|
11289
|
+
if (!hasCustomRel) {
|
|
11290
|
+
let maxId = 0;
|
|
11291
|
+
for (const rel of rels) {
|
|
11292
|
+
const id = String(rel?.["@_Id"] || "");
|
|
11293
|
+
const num = Number.parseInt(id.replace(/^rId/, ""), 10);
|
|
11294
|
+
if (Number.isFinite(num) && num > maxId) {
|
|
11295
|
+
maxId = num;
|
|
11296
|
+
}
|
|
11297
|
+
}
|
|
11298
|
+
rels.push({
|
|
11299
|
+
"@_Id": `rId${maxId + 1}`,
|
|
11300
|
+
"@_Type": customRelType,
|
|
11301
|
+
"@_Target": "docProps/custom.xml"
|
|
11302
|
+
});
|
|
11303
|
+
relationships["Relationship"] = rels;
|
|
11304
|
+
this.context.zip.file("_rels/.rels", this.context.builder.build(relsData));
|
|
11305
|
+
}
|
|
11306
|
+
}
|
|
11307
|
+
} catch (error) {
|
|
11308
|
+
console.warn("Failed to update _rels/.rels for custom properties:", error);
|
|
11309
|
+
}
|
|
11310
|
+
}
|
|
11311
|
+
}
|
|
11312
|
+
/**
|
|
11313
|
+
* Remove the Override + root rel for `docProps/custom.xml` when the
|
|
11314
|
+
* caller has emptied custom properties so the package doesn't keep an
|
|
11315
|
+
* orphan content-type entry referencing a deleted part.
|
|
11316
|
+
*/
|
|
11317
|
+
async removeCustomPropertiesPackagingArtifacts() {
|
|
11318
|
+
const customRelType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties";
|
|
11319
|
+
const ctFile = this.context.zip.file("[Content_Types].xml");
|
|
11320
|
+
if (ctFile) {
|
|
11321
|
+
try {
|
|
11322
|
+
const ctXml = await ctFile.async("string");
|
|
11323
|
+
const ctData = this.context.parser.parse(ctXml);
|
|
11324
|
+
const types = ctData["Types"];
|
|
11325
|
+
if (types) {
|
|
11326
|
+
const overrides = Array.isArray(types["Override"]) ? types["Override"] : types["Override"] ? [types["Override"]] : [];
|
|
11327
|
+
const filtered = overrides.filter(
|
|
11328
|
+
(o) => String(o?.["@_PartName"] || "") !== "/docProps/custom.xml"
|
|
11329
|
+
);
|
|
11330
|
+
if (filtered.length !== overrides.length) {
|
|
11331
|
+
types["Override"] = filtered.length === 1 ? filtered[0] : filtered;
|
|
11332
|
+
this.context.zip.file("[Content_Types].xml", this.context.builder.build(ctData));
|
|
11333
|
+
}
|
|
11334
|
+
}
|
|
11335
|
+
} catch {
|
|
11336
|
+
}
|
|
11337
|
+
}
|
|
11338
|
+
const relsFile = this.context.zip.file("_rels/.rels");
|
|
11339
|
+
if (relsFile) {
|
|
11340
|
+
try {
|
|
11341
|
+
const relsXml = await relsFile.async("string");
|
|
11342
|
+
const relsData = this.context.parser.parse(relsXml);
|
|
11343
|
+
const relationships = relsData["Relationships"];
|
|
11344
|
+
if (relationships) {
|
|
11345
|
+
const rels = Array.isArray(relationships["Relationship"]) ? relationships["Relationship"] : relationships["Relationship"] ? [relationships["Relationship"]] : [];
|
|
11346
|
+
const filtered = rels.filter((r) => String(r?.["@_Type"] || "") !== customRelType);
|
|
11347
|
+
if (filtered.length !== rels.length) {
|
|
11348
|
+
relationships["Relationship"] = filtered;
|
|
11349
|
+
this.context.zip.file("_rels/.rels", this.context.builder.build(relsData));
|
|
11350
|
+
}
|
|
11351
|
+
}
|
|
11352
|
+
} catch {
|
|
11353
|
+
}
|
|
11354
|
+
}
|
|
10782
11355
|
}
|
|
10783
11356
|
normalizeCustomPropertyType(type) {
|
|
10784
11357
|
const supportedTypes = /* @__PURE__ */ new Set([
|
|
@@ -11122,6 +11695,7 @@ var PptxSlideLoaderService = class {
|
|
|
11122
11695
|
await params.loadSlideRelationships(path2, slideRelsPath);
|
|
11123
11696
|
const clrMapOverride = params.parseSlideClrMapOverride(slideXmlObj);
|
|
11124
11697
|
params.setCurrentSlideClrMapOverride(clrMapOverride);
|
|
11698
|
+
await params.setActiveMasterForSlide?.(path2);
|
|
11125
11699
|
let restoreThemeOverride;
|
|
11126
11700
|
try {
|
|
11127
11701
|
const layoutPathForOverride = params.findLayoutPathForSlide(path2);
|
|
@@ -15873,6 +16447,20 @@ var AXIS_TYPE_MAP = {
|
|
|
15873
16447
|
dateAx: "dateAx",
|
|
15874
16448
|
serAx: "serAx"
|
|
15875
16449
|
};
|
|
16450
|
+
function upsertChartAxisChild(parent, localName, value, getLocalName) {
|
|
16451
|
+
const existingKey = Object.keys(parent).find((k) => getLocalName(k) === localName);
|
|
16452
|
+
if (value === void 0) {
|
|
16453
|
+
if (existingKey) {
|
|
16454
|
+
delete parent[existingKey];
|
|
16455
|
+
}
|
|
16456
|
+
return;
|
|
16457
|
+
}
|
|
16458
|
+
if (existingKey) {
|
|
16459
|
+
parent[existingKey]["@_val"] = value;
|
|
16460
|
+
} else {
|
|
16461
|
+
parent[`c:${localName}`] = { "@_val": value };
|
|
16462
|
+
}
|
|
16463
|
+
}
|
|
15876
16464
|
function parseChartAxes(plotArea, xmlLookup, colorParser, getLocalName) {
|
|
15877
16465
|
const result = [];
|
|
15878
16466
|
for (const key of Object.keys(plotArea)) {
|
|
@@ -15993,6 +16581,27 @@ function parseSingleAxis(axisNode, axisType, xmlLookup, colorParser) {
|
|
|
15993
16581
|
if (dispUnitsNode) {
|
|
15994
16582
|
parseDisplayUnits(dispUnitsNode, xmlLookup, result);
|
|
15995
16583
|
}
|
|
16584
|
+
const majorUnitNode = xmlLookup.getChildByLocalName(axisNode, "majorUnit");
|
|
16585
|
+
if (majorUnitNode) {
|
|
16586
|
+
const majorVal = parseFloat(String(majorUnitNode["@_val"]));
|
|
16587
|
+
if (Number.isFinite(majorVal)) {
|
|
16588
|
+
result.majorUnit = majorVal;
|
|
16589
|
+
}
|
|
16590
|
+
}
|
|
16591
|
+
const minorUnitNode = xmlLookup.getChildByLocalName(axisNode, "minorUnit");
|
|
16592
|
+
if (minorUnitNode) {
|
|
16593
|
+
const minorVal = parseFloat(String(minorUnitNode["@_val"]));
|
|
16594
|
+
if (Number.isFinite(minorVal)) {
|
|
16595
|
+
result.minorUnit = minorVal;
|
|
16596
|
+
}
|
|
16597
|
+
}
|
|
16598
|
+
const tickLblPosNode = xmlLookup.getChildByLocalName(axisNode, "tickLblPos");
|
|
16599
|
+
if (tickLblPosNode) {
|
|
16600
|
+
const v = String(tickLblPosNode["@_val"] || "").trim();
|
|
16601
|
+
if (v === "high" || v === "low" || v === "nextTo" || v === "none") {
|
|
16602
|
+
result.tickLblPos = v;
|
|
16603
|
+
}
|
|
16604
|
+
}
|
|
15996
16605
|
return result;
|
|
15997
16606
|
}
|
|
15998
16607
|
var VALID_DISPLAY_UNITS = /* @__PURE__ */ new Set([
|
|
@@ -17304,23 +17913,55 @@ var SHAPE_TREE_ELEMENT_TAGS = /* @__PURE__ */ new Set([
|
|
|
17304
17913
|
"p16:model3D",
|
|
17305
17914
|
...VML_SHAPE_TAGS
|
|
17306
17915
|
]);
|
|
17916
|
+
function diagnoseSelection(ac) {
|
|
17917
|
+
const choices = ensureArray2(ac["mc:Choice"]);
|
|
17918
|
+
for (let i = 0; i < choices.length; i++) {
|
|
17919
|
+
const choice = choices[i];
|
|
17920
|
+
const requires = String(choice?.["@_Requires"] ?? "").trim();
|
|
17921
|
+
if (requires.length === 0 || areNamespacesSupported(requires)) {
|
|
17922
|
+
const resolved = resolveNestedAlternateContent(choice);
|
|
17923
|
+
return { branch: "choice", choiceIndex: i, resolved };
|
|
17924
|
+
}
|
|
17925
|
+
}
|
|
17926
|
+
const fallback = ac["mc:Fallback"];
|
|
17927
|
+
if (fallback) {
|
|
17928
|
+
return { branch: "fallback", resolved: resolveNestedAlternateContent(fallback) };
|
|
17929
|
+
}
|
|
17930
|
+
return void 0;
|
|
17931
|
+
}
|
|
17307
17932
|
function unwrapAlternateContent(container) {
|
|
17308
17933
|
const altContents = ensureArray2(container["mc:AlternateContent"]);
|
|
17309
17934
|
if (altContents.length === 0) {
|
|
17310
|
-
return;
|
|
17935
|
+
return [];
|
|
17311
17936
|
}
|
|
17937
|
+
const blocks = [];
|
|
17312
17938
|
for (const ac of altContents) {
|
|
17313
|
-
const
|
|
17314
|
-
if (!
|
|
17939
|
+
const diagnosis = diagnoseSelection(ac);
|
|
17940
|
+
if (!diagnosis) {
|
|
17315
17941
|
continue;
|
|
17316
17942
|
}
|
|
17943
|
+
const block = {
|
|
17944
|
+
rawAc: ac,
|
|
17945
|
+
selectedBranch: diagnosis.branch,
|
|
17946
|
+
choiceIndex: diagnosis.branch === "choice" ? diagnosis.choiceIndex : void 0,
|
|
17947
|
+
childRefs: []
|
|
17948
|
+
};
|
|
17949
|
+
const branch = diagnosis.resolved;
|
|
17317
17950
|
for (const tag of SHAPE_TREE_ELEMENT_TAGS) {
|
|
17318
17951
|
const children = ensureArray2(branch[tag]);
|
|
17319
17952
|
if (children.length > 0) {
|
|
17320
17953
|
container[tag] = [...ensureArray2(container[tag]), ...children];
|
|
17954
|
+
for (const child of children) {
|
|
17955
|
+
block.childRefs.push({ tag, node: child });
|
|
17956
|
+
}
|
|
17321
17957
|
}
|
|
17322
17958
|
}
|
|
17959
|
+
if (block.childRefs.length > 0) {
|
|
17960
|
+
blocks.push(block);
|
|
17961
|
+
}
|
|
17323
17962
|
}
|
|
17963
|
+
delete container["mc:AlternateContent"];
|
|
17964
|
+
return blocks;
|
|
17324
17965
|
}
|
|
17325
17966
|
function ensureArray2(val) {
|
|
17326
17967
|
if (!val) {
|
|
@@ -17332,7 +17973,7 @@ function ensureArray2(val) {
|
|
|
17332
17973
|
|
|
17333
17974
|
// src/core/utils/body-properties-parser.ts
|
|
17334
17975
|
function parseBodyPrBooleanAttrs(bodyPr, textStyle) {
|
|
17335
|
-
const
|
|
17976
|
+
const parseBoolAttr2 = (attr) => {
|
|
17336
17977
|
const raw = bodyPr[attr];
|
|
17337
17978
|
if (raw === void 0) {
|
|
17338
17979
|
return void 0;
|
|
@@ -17340,19 +17981,19 @@ function parseBodyPrBooleanAttrs(bodyPr, textStyle) {
|
|
|
17340
17981
|
const val = String(raw).trim().toLowerCase();
|
|
17341
17982
|
return val === "1" || val === "true";
|
|
17342
17983
|
};
|
|
17343
|
-
const compatLnSpc =
|
|
17984
|
+
const compatLnSpc = parseBoolAttr2("@_compatLnSpc");
|
|
17344
17985
|
if (compatLnSpc !== void 0) {
|
|
17345
17986
|
textStyle.compatibleLineSpacing = compatLnSpc;
|
|
17346
17987
|
}
|
|
17347
|
-
const forceAA =
|
|
17988
|
+
const forceAA = parseBoolAttr2("@_forceAA");
|
|
17348
17989
|
if (forceAA !== void 0) {
|
|
17349
17990
|
textStyle.forceAntiAlias = forceAA;
|
|
17350
17991
|
}
|
|
17351
|
-
const upright =
|
|
17992
|
+
const upright = parseBoolAttr2("@_upright");
|
|
17352
17993
|
if (upright !== void 0) {
|
|
17353
17994
|
textStyle.upright = upright;
|
|
17354
17995
|
}
|
|
17355
|
-
const fromWordArt =
|
|
17996
|
+
const fromWordArt = parseBoolAttr2("@_fromWordArt");
|
|
17356
17997
|
if (fromWordArt !== void 0) {
|
|
17357
17998
|
textStyle.fromWordArt = fromWordArt;
|
|
17358
17999
|
}
|
|
@@ -17375,46 +18016,6 @@ function writeBodyPrBooleanAttrs(bodyPr, textStyle) {
|
|
|
17375
18016
|
}
|
|
17376
18017
|
}
|
|
17377
18018
|
|
|
17378
|
-
// src/core/utils/theme-override-utils.ts
|
|
17379
|
-
var COLOR_MAP_ALIAS_KEYS = [
|
|
17380
|
-
"bg1",
|
|
17381
|
-
"tx1",
|
|
17382
|
-
"bg2",
|
|
17383
|
-
"tx2",
|
|
17384
|
-
"accent1",
|
|
17385
|
-
"accent2",
|
|
17386
|
-
"accent3",
|
|
17387
|
-
"accent4",
|
|
17388
|
-
"accent5",
|
|
17389
|
-
"accent6",
|
|
17390
|
-
"hlink",
|
|
17391
|
-
"folHlink"
|
|
17392
|
-
];
|
|
17393
|
-
var DEFAULT_COLOR_MAP = {
|
|
17394
|
-
bg1: "lt1",
|
|
17395
|
-
tx1: "dk1",
|
|
17396
|
-
bg2: "lt2",
|
|
17397
|
-
tx2: "dk2",
|
|
17398
|
-
accent1: "accent1",
|
|
17399
|
-
accent2: "accent2",
|
|
17400
|
-
accent3: "accent3",
|
|
17401
|
-
accent4: "accent4",
|
|
17402
|
-
accent5: "accent5",
|
|
17403
|
-
accent6: "accent6",
|
|
17404
|
-
hlink: "hlink",
|
|
17405
|
-
folHlink: "folHlink"
|
|
17406
|
-
};
|
|
17407
|
-
function buildClrMapOverrideXml(override) {
|
|
17408
|
-
if (!override || Object.keys(override).length === 0) {
|
|
17409
|
-
return { "a:masterClrMapping": {} };
|
|
17410
|
-
}
|
|
17411
|
-
const attrs2 = {};
|
|
17412
|
-
for (const key of COLOR_MAP_ALIAS_KEYS) {
|
|
17413
|
-
attrs2[`@_${key}`] = override[key] ?? DEFAULT_COLOR_MAP[key];
|
|
17414
|
-
}
|
|
17415
|
-
return { "a:overrideClrMapping": attrs2 };
|
|
17416
|
-
}
|
|
17417
|
-
|
|
17418
18019
|
// src/core/utils/data-url-utils.ts
|
|
17419
18020
|
function parseDataUrlToBytes(dataUrl) {
|
|
17420
18021
|
const match = dataUrl.match(/^data:([^;]+);base64,(.+)$/);
|
|
@@ -17512,6 +18113,46 @@ async function fetchUrlToBytes(url) {
|
|
|
17512
18113
|
}
|
|
17513
18114
|
}
|
|
17514
18115
|
|
|
18116
|
+
// src/core/utils/theme-override-utils.ts
|
|
18117
|
+
var COLOR_MAP_ALIAS_KEYS = [
|
|
18118
|
+
"bg1",
|
|
18119
|
+
"tx1",
|
|
18120
|
+
"bg2",
|
|
18121
|
+
"tx2",
|
|
18122
|
+
"accent1",
|
|
18123
|
+
"accent2",
|
|
18124
|
+
"accent3",
|
|
18125
|
+
"accent4",
|
|
18126
|
+
"accent5",
|
|
18127
|
+
"accent6",
|
|
18128
|
+
"hlink",
|
|
18129
|
+
"folHlink"
|
|
18130
|
+
];
|
|
18131
|
+
var DEFAULT_COLOR_MAP = {
|
|
18132
|
+
bg1: "lt1",
|
|
18133
|
+
tx1: "dk1",
|
|
18134
|
+
bg2: "lt2",
|
|
18135
|
+
tx2: "dk2",
|
|
18136
|
+
accent1: "accent1",
|
|
18137
|
+
accent2: "accent2",
|
|
18138
|
+
accent3: "accent3",
|
|
18139
|
+
accent4: "accent4",
|
|
18140
|
+
accent5: "accent5",
|
|
18141
|
+
accent6: "accent6",
|
|
18142
|
+
hlink: "hlink",
|
|
18143
|
+
folHlink: "folHlink"
|
|
18144
|
+
};
|
|
18145
|
+
function buildClrMapOverrideXml(override) {
|
|
18146
|
+
if (!override || Object.keys(override).length === 0) {
|
|
18147
|
+
return { "a:masterClrMapping": {} };
|
|
18148
|
+
}
|
|
18149
|
+
const attrs2 = {};
|
|
18150
|
+
for (const key of COLOR_MAP_ALIAS_KEYS) {
|
|
18151
|
+
attrs2[`@_${key}`] = override[key] ?? DEFAULT_COLOR_MAP[key];
|
|
18152
|
+
}
|
|
18153
|
+
return { "a:overrideClrMapping": attrs2 };
|
|
18154
|
+
}
|
|
18155
|
+
|
|
17515
18156
|
// src/core/utils/encryption-detection.ts
|
|
17516
18157
|
var OLE_MAGIC = new Uint8Array([208, 207, 17, 224, 161, 27, 26, 225]);
|
|
17517
18158
|
var ZIP_MAGIC = new Uint8Array([80, 75]);
|
|
@@ -23274,7 +23915,7 @@ function parseActiveXControlsFromSlide(slideXml2) {
|
|
|
23274
23915
|
}
|
|
23275
23916
|
|
|
23276
23917
|
// src/core/utils/theme-switching.ts
|
|
23277
|
-
function
|
|
23918
|
+
function normalizeHex2(hex) {
|
|
23278
23919
|
if (!hex) {
|
|
23279
23920
|
return "";
|
|
23280
23921
|
}
|
|
@@ -23284,8 +23925,8 @@ function buildColorRemapTable(oldColorMap, newColorMap) {
|
|
|
23284
23925
|
const remap = /* @__PURE__ */ new Map();
|
|
23285
23926
|
const allKeys = [...THEME_COLOR_SCHEME_KEYS, "tx1", "bg1", "tx2", "bg2"];
|
|
23286
23927
|
for (const key of allKeys) {
|
|
23287
|
-
const oldVal =
|
|
23288
|
-
const newVal =
|
|
23928
|
+
const oldVal = normalizeHex2(oldColorMap[key]);
|
|
23929
|
+
const newVal = normalizeHex2(newColorMap[key]);
|
|
23289
23930
|
if (oldVal && newVal && oldVal !== newVal) {
|
|
23290
23931
|
remap.set(oldVal, `#${newVal}`);
|
|
23291
23932
|
remap.set(`#${oldVal}`, `#${newVal}`);
|
|
@@ -23297,7 +23938,7 @@ function remapColor(color, remap) {
|
|
|
23297
23938
|
if (!color) {
|
|
23298
23939
|
return color;
|
|
23299
23940
|
}
|
|
23300
|
-
const normalized =
|
|
23941
|
+
const normalized = normalizeHex2(color);
|
|
23301
23942
|
const remapped = remap.get(normalized) ?? remap.get(`#${normalized}`);
|
|
23302
23943
|
return remapped ?? color;
|
|
23303
23944
|
}
|
|
@@ -23437,7 +24078,7 @@ function remapSlideColors(slide, remap) {
|
|
|
23437
24078
|
function buildThemeColorMap(colorScheme) {
|
|
23438
24079
|
const map = {};
|
|
23439
24080
|
for (const key of THEME_COLOR_SCHEME_KEYS) {
|
|
23440
|
-
map[key] =
|
|
24081
|
+
map[key] = normalizeHex2(colorScheme[key]);
|
|
23441
24082
|
}
|
|
23442
24083
|
map.tx1 = map.dk1;
|
|
23443
24084
|
map.bg1 = map.lt1;
|
|
@@ -23473,8 +24114,11 @@ function applyThemeToData(data, newColorScheme, newFontScheme, themeName) {
|
|
|
23473
24114
|
|
|
23474
24115
|
// src/core/core/runtime/PptxHandlerRuntimeSaveParagraphHelpers.ts
|
|
23475
24116
|
var EMU_PER_PX4 = 9525;
|
|
23476
|
-
function buildParagraphPropertiesXml(textStyle, paragraphAlign, bulletInfo, spacing) {
|
|
24117
|
+
function buildParagraphPropertiesXml(textStyle, paragraphAlign, bulletInfo, spacing, level) {
|
|
23477
24118
|
const paragraphProps = {};
|
|
24119
|
+
if (typeof level === "number" && Number.isFinite(level) && level > 0) {
|
|
24120
|
+
paragraphProps["@_lvl"] = String(Math.min(Math.max(Math.round(level), 0), 8));
|
|
24121
|
+
}
|
|
23478
24122
|
if (paragraphAlign) {
|
|
23479
24123
|
paragraphProps["@_algn"] = paragraphAlign;
|
|
23480
24124
|
}
|
|
@@ -23546,23 +24190,28 @@ function applyBulletProperties(paragraphProps, bulletInfo) {
|
|
|
23546
24190
|
paragraphProps["a:buNone"] = {};
|
|
23547
24191
|
return;
|
|
23548
24192
|
}
|
|
23549
|
-
if (bulletInfo.
|
|
24193
|
+
if (bulletInfo.colorInherit) {
|
|
24194
|
+
paragraphProps["a:buClrTx"] = {};
|
|
24195
|
+
} else if (bulletInfo.color) {
|
|
23550
24196
|
const colorHex = bulletInfo.color.replace("#", "");
|
|
23551
24197
|
paragraphProps["a:buClr"] = {
|
|
23552
24198
|
"a:srgbClr": { "@_val": colorHex }
|
|
23553
24199
|
};
|
|
23554
24200
|
}
|
|
23555
|
-
if (bulletInfo.
|
|
24201
|
+
if (bulletInfo.sizeInherit) {
|
|
24202
|
+
paragraphProps["a:buSzTx"] = {};
|
|
24203
|
+
} else if (bulletInfo.sizePercent !== void 0) {
|
|
23556
24204
|
paragraphProps["a:buSzPct"] = {
|
|
23557
24205
|
"@_val": String(Math.round(bulletInfo.sizePercent * 1e3))
|
|
23558
24206
|
};
|
|
23559
|
-
}
|
|
23560
|
-
if (bulletInfo.sizePts !== void 0) {
|
|
24207
|
+
} else if (bulletInfo.sizePts !== void 0) {
|
|
23561
24208
|
paragraphProps["a:buSzPts"] = {
|
|
23562
24209
|
"@_val": String(Math.round(bulletInfo.sizePts * 100))
|
|
23563
24210
|
};
|
|
23564
24211
|
}
|
|
23565
|
-
if (bulletInfo.
|
|
24212
|
+
if (bulletInfo.fontInherit) {
|
|
24213
|
+
paragraphProps["a:buFontTx"] = {};
|
|
24214
|
+
} else if (bulletInfo.fontFamily) {
|
|
23566
24215
|
paragraphProps["a:buFont"] = {
|
|
23567
24216
|
"@_typeface": bulletInfo.fontFamily
|
|
23568
24217
|
};
|
|
@@ -23585,7 +24234,7 @@ function applyBulletProperties(paragraphProps, bulletInfo) {
|
|
|
23585
24234
|
};
|
|
23586
24235
|
}
|
|
23587
24236
|
}
|
|
23588
|
-
function assembleParagraphXml(runs, paragraphProps) {
|
|
24237
|
+
function assembleParagraphXml(runs, paragraphProps, endParaRunProperties) {
|
|
23589
24238
|
const paragraph = {
|
|
23590
24239
|
"a:pPr": paragraphProps
|
|
23591
24240
|
};
|
|
@@ -23607,7 +24256,11 @@ function assembleParagraphXml(runs, paragraphProps) {
|
|
|
23607
24256
|
if (cleanRegularRuns.length === 0 && fieldRuns.length === 0) {
|
|
23608
24257
|
paragraph["a:r"] = runs.length > 1 ? runs : runs[0];
|
|
23609
24258
|
}
|
|
23610
|
-
|
|
24259
|
+
if (endParaRunProperties && typeof endParaRunProperties === "object") {
|
|
24260
|
+
paragraph["a:endParaRPr"] = endParaRunProperties;
|
|
24261
|
+
} else {
|
|
24262
|
+
paragraph["a:endParaRPr"] = { "@_lang": "en-US" };
|
|
24263
|
+
}
|
|
23611
24264
|
return paragraph;
|
|
23612
24265
|
}
|
|
23613
24266
|
function computeUniformSegmentOverrides(textStyle, textSegments) {
|
|
@@ -23911,6 +24564,140 @@ var PptxHandlerRuntime = class {
|
|
|
23911
24564
|
* `p:clrMapOvr / a:overrideClrMapping`.
|
|
23912
24565
|
*/
|
|
23913
24566
|
currentSlideClrMapOverride = null;
|
|
24567
|
+
/**
|
|
24568
|
+
* Per-master colour map alias dictionaries parsed from each master's
|
|
24569
|
+
* `<p:clrMap>` element (e.g. `bg1 → lt1`, `tx1 → dk1`, `accent1 → accent1`).
|
|
24570
|
+
*
|
|
24571
|
+
* `clrMap` is the *aliasing* layer between logical colour names used in
|
|
24572
|
+
* DrawingML and the raw theme scheme slots. Per ECMA-376 §19.3.1.7 it
|
|
24573
|
+
* lives on each `p:sldMaster`, and slide layouts/slides may further
|
|
24574
|
+
* override it via `p:clrMapOvr`. Resolution must happen at colour-lookup
|
|
24575
|
+
* time, *not* by baking it into {@link themeColorMap}.
|
|
24576
|
+
*
|
|
24577
|
+
* Phase 2 Stream B / C-H4.
|
|
24578
|
+
*/
|
|
24579
|
+
masterClrMaps = /* @__PURE__ */ new Map();
|
|
24580
|
+
/**
|
|
24581
|
+
* Per-master theme color maps. Each master may reference its own theme
|
|
24582
|
+
* file via `_rels/slideMasterN.xml.rels`. For multi-master decks, slides
|
|
24583
|
+
* must resolve scheme colours against their *own* master's theme.
|
|
24584
|
+
*
|
|
24585
|
+
* Falls back to {@link themeColorMap} when a master entry is missing.
|
|
24586
|
+
*
|
|
24587
|
+
* Phase 2 Stream B / C-H4.
|
|
24588
|
+
*/
|
|
24589
|
+
masterThemeColorMaps = /* @__PURE__ */ new Map();
|
|
24590
|
+
/**
|
|
24591
|
+
* Per-master theme font maps. Same rationale as
|
|
24592
|
+
* {@link masterThemeColorMaps}: multi-master decks may have one font
|
|
24593
|
+
* scheme per theme.
|
|
24594
|
+
*/
|
|
24595
|
+
masterThemeFontMaps = /* @__PURE__ */ new Map();
|
|
24596
|
+
/**
|
|
24597
|
+
* Per-master format schemes (fmtScheme). For multi-master decks each
|
|
24598
|
+
* master's slides should resolve fill/line/effect refs against the
|
|
24599
|
+
* matrix from that master's theme.
|
|
24600
|
+
*/
|
|
24601
|
+
masterThemeFormatSchemes = /* @__PURE__ */ new Map();
|
|
24602
|
+
/**
|
|
24603
|
+
* Per-master mapping from slide-master path to the theme path it
|
|
24604
|
+
* references via `_rels/slideMasterN.xml.rels`. Populated by
|
|
24605
|
+
* {@link loadPerMasterThemes} during load. Used by the save-side
|
|
24606
|
+
* theme writer to know which themeN.xml to (re)emit for each master.
|
|
24607
|
+
*
|
|
24608
|
+
* Phase 4 Stream A / C-H3.
|
|
24609
|
+
*/
|
|
24610
|
+
masterThemePaths = /* @__PURE__ */ new Map();
|
|
24611
|
+
/**
|
|
24612
|
+
* Per-script font tables for major and minor fonts. Captured per master
|
|
24613
|
+
* theme. Keys are master paths; values map `mj`/`mn` -> script tag (e.g.
|
|
24614
|
+
* `Hans`, `Hant`, `Arab`, `Hebr`, `Thai`, `Beng`, …) -> typeface name.
|
|
24615
|
+
*
|
|
24616
|
+
* Phase 4 Stream A / M4.
|
|
24617
|
+
*/
|
|
24618
|
+
masterThemeMajorFontScripts = /* @__PURE__ */ new Map();
|
|
24619
|
+
masterThemeMinorFontScripts = /* @__PURE__ */ new Map();
|
|
24620
|
+
/**
|
|
24621
|
+
* Theme name attribute (`<a:theme @name>`) per master theme path.
|
|
24622
|
+
* Captured for byte-stable round-trip.
|
|
24623
|
+
*/
|
|
24624
|
+
masterThemeNames = /* @__PURE__ */ new Map();
|
|
24625
|
+
/**
|
|
24626
|
+
* `<a:fontScheme @name>` per master theme path.
|
|
24627
|
+
*/
|
|
24628
|
+
masterThemeFontSchemeNames = /* @__PURE__ */ new Map();
|
|
24629
|
+
/**
|
|
24630
|
+
* `<a:clrScheme @name>` per master theme path.
|
|
24631
|
+
*/
|
|
24632
|
+
masterThemeColorSchemeNames = /* @__PURE__ */ new Map();
|
|
24633
|
+
/**
|
|
24634
|
+
* Raw original theme XML keyed by theme path. Captured at load-time.
|
|
24635
|
+
* Used by the save pipeline to passthrough the full theme XML when no
|
|
24636
|
+
* in-memory mutation has occurred — preserving fillStyleLst /
|
|
24637
|
+
* lnStyleLst / effectStyleLst / bgFillStyleLst /
|
|
24638
|
+
* extraClrSchemeLst / objectDefaults / extLst exactly as written.
|
|
24639
|
+
*
|
|
24640
|
+
* Phase 4 Stream A / C-H3.
|
|
24641
|
+
*/
|
|
24642
|
+
originalThemeXmlByPath = /* @__PURE__ */ new Map();
|
|
24643
|
+
/**
|
|
24644
|
+
* Set of theme paths whose in-memory state has been mutated since
|
|
24645
|
+
* load. Saving a theme path that's NOT dirty is a no-op (the original
|
|
24646
|
+
* file already exists in the ZIP). Saving a dirty theme path
|
|
24647
|
+
* regenerates the part from in-memory state.
|
|
24648
|
+
*
|
|
24649
|
+
* Phase 4 Stream A / C-H3.
|
|
24650
|
+
*/
|
|
24651
|
+
dirtyThemePaths = /* @__PURE__ */ new Set();
|
|
24652
|
+
/**
|
|
24653
|
+
* Per-master parsed `<p:txStyles>` (titleStyle/bodyStyle/otherStyle).
|
|
24654
|
+
* Populated by {@link enrichSlideMastersWithTxStyles} during load so the
|
|
24655
|
+
* inheritance chain can find the master text-style cascade without
|
|
24656
|
+
* re-parsing master XML on every lookup. Phase 4 Stream B / P-H1.
|
|
24657
|
+
*/
|
|
24658
|
+
masterTxStylesCache = /* @__PURE__ */ new Map();
|
|
24659
|
+
/**
|
|
24660
|
+
* Captured `<a:objectDefaults>` snapshot per master theme path. The
|
|
24661
|
+
* full ECMA-376 inheritance chain (master / layout / placeholder /
|
|
24662
|
+
* objectDefaults) is non-trivial; we store the raw spDef/lnDef/txDef
|
|
24663
|
+
* subtrees and re-emit them verbatim for round-trip.
|
|
24664
|
+
*
|
|
24665
|
+
* Phase 4 Stream A / M5.
|
|
24666
|
+
*/
|
|
24667
|
+
masterThemeObjectDefaults = /* @__PURE__ */ new Map();
|
|
24668
|
+
/**
|
|
24669
|
+
* Captured `<a:extraClrSchemeLst>` raw subtree per master theme path
|
|
24670
|
+
* for verbatim round-trip.
|
|
24671
|
+
*
|
|
24672
|
+
* Phase 4 Stream A.
|
|
24673
|
+
*/
|
|
24674
|
+
masterThemeExtraClrSchemeLst = /* @__PURE__ */ new Map();
|
|
24675
|
+
/**
|
|
24676
|
+
* Captured `<a:custClrLst>` raw subtree per master theme path
|
|
24677
|
+
* for verbatim round-trip.
|
|
24678
|
+
*
|
|
24679
|
+
* Phase 4 Stream A.
|
|
24680
|
+
*/
|
|
24681
|
+
masterThemeCustClrLst = /* @__PURE__ */ new Map();
|
|
24682
|
+
/**
|
|
24683
|
+
* Captured theme-level `<a:extLst>` raw subtree per master theme path.
|
|
24684
|
+
*/
|
|
24685
|
+
masterThemeExtLst = /* @__PURE__ */ new Map();
|
|
24686
|
+
/**
|
|
24687
|
+
* Active master's clrMap for the slide currently being parsed. Walked
|
|
24688
|
+
* after `currentSlideClrMapOverride` (slide and layout overrides take
|
|
24689
|
+
* precedence). `null` means "fall through to themeColorMap directly".
|
|
24690
|
+
*/
|
|
24691
|
+
currentMasterClrMap = null;
|
|
24692
|
+
/**
|
|
24693
|
+
* Snapshot of the global theme state taken right after
|
|
24694
|
+
* {@link loadThemeData} completes. Used as the fallback when a slide's
|
|
24695
|
+
* master has no per-master theme entry, so per-slide multi-master
|
|
24696
|
+
* switching does not leak the previous slide's master state.
|
|
24697
|
+
*/
|
|
24698
|
+
globalThemeColorMapSnapshot = {};
|
|
24699
|
+
globalThemeFontMapSnapshot = {};
|
|
24700
|
+
globalThemeFormatSchemeSnapshot;
|
|
23914
24701
|
/** Thumbnail image data from `docProps/thumbnail.jpeg` preserved for round-trip. */
|
|
23915
24702
|
thumbnailData = null;
|
|
23916
24703
|
/** Raw VBA project binary preserved for macro-enabled (.pptm) round-trip. */
|
|
@@ -23921,6 +24708,19 @@ var PptxHandlerRuntime = class {
|
|
|
23921
24708
|
signatureDetection = null;
|
|
23922
24709
|
/** Custom XML data parts parsed from `customXml/` in the OPC package. */
|
|
23923
24710
|
customXmlParts = [];
|
|
24711
|
+
/**
|
|
24712
|
+
* Maps an element's `rawXml` reference to the `mc:AlternateContent`
|
|
24713
|
+
* envelope that originally wrapped it (CC-4). Populated during slide
|
|
24714
|
+
* (and `p:grpSp`) parsing; consulted at save time to re-emit the
|
|
24715
|
+
* original `<mc:Choice>` / `<mc:Fallback>` shape so legacy renderers
|
|
24716
|
+
* keep their fallback content.
|
|
24717
|
+
*
|
|
24718
|
+
* Multiple sibling elements may share the same `AlternateContentBlock`
|
|
24719
|
+
* value (a single AC envelope often wraps several child shapes — e.g.
|
|
24720
|
+
* `p14:media` + its `p:pic` fallback nest one each). WeakMap so AC
|
|
24721
|
+
* envelopes are GC'd if the parsed XmlObject is dropped.
|
|
24722
|
+
*/
|
|
24723
|
+
alternateContentBlockByRawXml = /* @__PURE__ */ new WeakMap();
|
|
23924
24724
|
/** Embedded fonts extracted during load, preserved for automatic re-embedding on save. */
|
|
23925
24725
|
loadedEmbeddedFonts = [];
|
|
23926
24726
|
/** Map of comment author IDs to display names (from `ppt/commentAuthors.xml`). */
|
|
@@ -25734,7 +26534,12 @@ var PptxHandlerRuntime9 = class extends PptxHandlerRuntime8 {
|
|
|
25734
26534
|
const bgColor = this.parseBackgroundColor(bg);
|
|
25735
26535
|
const spTree = master["p:cSld"]?.["p:spTree"];
|
|
25736
26536
|
const placeholders = this.extractPlaceholderList(spTree);
|
|
25737
|
-
|
|
26537
|
+
const result = { path: path2, backgroundColor: bgColor, placeholders };
|
|
26538
|
+
const hf = parseHeaderFooterFlags(master["p:hf"]);
|
|
26539
|
+
if (hf) {
|
|
26540
|
+
result.headerFooter = hf;
|
|
26541
|
+
}
|
|
26542
|
+
return result;
|
|
25738
26543
|
} catch (e) {
|
|
25739
26544
|
console.warn("Failed to parse handout master:", e);
|
|
25740
26545
|
return void 0;
|
|
@@ -25760,7 +26565,12 @@ var PptxHandlerRuntime9 = class extends PptxHandlerRuntime8 {
|
|
|
25760
26565
|
const bgColor = this.parseBackgroundColor(bg);
|
|
25761
26566
|
const spTree = master["p:cSld"]?.["p:spTree"];
|
|
25762
26567
|
const placeholders = this.extractPlaceholderList(spTree);
|
|
25763
|
-
|
|
26568
|
+
const result = { path: path2, backgroundColor: bgColor, placeholders };
|
|
26569
|
+
const hf = parseHeaderFooterFlags(master["p:hf"]);
|
|
26570
|
+
if (hf) {
|
|
26571
|
+
result.headerFooter = hf;
|
|
26572
|
+
}
|
|
26573
|
+
return result;
|
|
25764
26574
|
} catch (e) {
|
|
25765
26575
|
console.warn("Failed to parse notes master:", e);
|
|
25766
26576
|
return void 0;
|
|
@@ -25805,6 +26615,10 @@ var PptxHandlerRuntime9 = class extends PptxHandlerRuntime8 {
|
|
|
25805
26615
|
const uVal = String(userDrawn).trim().toLowerCase();
|
|
25806
26616
|
layout.userDrawn = uVal === "1" || uVal === "true";
|
|
25807
26617
|
}
|
|
26618
|
+
const hf = parseHeaderFooterFlags(sldLayout["p:hf"]);
|
|
26619
|
+
if (hf) {
|
|
26620
|
+
layout.headerFooter = hf;
|
|
26621
|
+
}
|
|
25808
26622
|
const clrMapOvr = sldLayout["p:clrMapOvr"];
|
|
25809
26623
|
if (clrMapOvr && clrMapOvr["a:masterClrMapping"] === void 0) {
|
|
25810
26624
|
const overrideNode = clrMapOvr["a:overrideClrMapping"];
|
|
@@ -26410,6 +27224,18 @@ function buildClrChangeNode(style) {
|
|
|
26410
27224
|
}
|
|
26411
27225
|
|
|
26412
27226
|
// src/core/core/runtime/PptxHandlerRuntimeSaveRunProperties.ts
|
|
27227
|
+
function applyFontMetadata(fontNode, panose, pitchFamily, charset) {
|
|
27228
|
+
if (panose && panose.length > 0) {
|
|
27229
|
+
fontNode["@_panose"] = panose;
|
|
27230
|
+
}
|
|
27231
|
+
if (typeof pitchFamily === "number" && Number.isFinite(pitchFamily)) {
|
|
27232
|
+
fontNode["@_pitchFamily"] = String(pitchFamily);
|
|
27233
|
+
}
|
|
27234
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
27235
|
+
fontNode["@_charset"] = String(charset);
|
|
27236
|
+
}
|
|
27237
|
+
return fontNode;
|
|
27238
|
+
}
|
|
26413
27239
|
var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime11 {
|
|
26414
27240
|
createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId) {
|
|
26415
27241
|
const runProps = {
|
|
@@ -26467,6 +27293,12 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
26467
27293
|
if (style.bookmark) {
|
|
26468
27294
|
runProps["@_bmk"] = style.bookmark;
|
|
26469
27295
|
}
|
|
27296
|
+
if (style.altLanguage) {
|
|
27297
|
+
runProps["@_altLang"] = style.altLanguage;
|
|
27298
|
+
}
|
|
27299
|
+
if (typeof style.smartTagId === "number" && Number.isFinite(style.smartTagId)) {
|
|
27300
|
+
runProps["@_smtId"] = String(style.smartTagId);
|
|
27301
|
+
}
|
|
26470
27302
|
if (style.textOutlineWidth || style.textOutlineColor) {
|
|
26471
27303
|
const lnObj = {};
|
|
26472
27304
|
if (typeof style.textOutlineWidth === "number" && style.textOutlineWidth > 0) {
|
|
@@ -26482,11 +27314,12 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
26482
27314
|
runProps["a:ln"] = lnObj;
|
|
26483
27315
|
}
|
|
26484
27316
|
if (style.color) {
|
|
26485
|
-
|
|
26486
|
-
|
|
26487
|
-
|
|
26488
|
-
|
|
26489
|
-
|
|
27317
|
+
const resolvedOriginalColor = style.colorXml ? this.parseColor(style.colorXml) : void 0;
|
|
27318
|
+
runProps["a:solidFill"] = serializeColorChoice(
|
|
27319
|
+
style.colorXml,
|
|
27320
|
+
resolvedOriginalColor,
|
|
27321
|
+
style.color
|
|
27322
|
+
);
|
|
26490
27323
|
} else if (style.textFillGradientStops && style.textFillGradientStops.length > 0) {
|
|
26491
27324
|
const gradStops = style.textFillGradientStops.filter((stop) => Boolean(stop?.color)).map((stop) => {
|
|
26492
27325
|
const rawPos = (stop.position ?? 0) / 100;
|
|
@@ -26559,16 +27392,32 @@ var PptxHandlerRuntime12 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
26559
27392
|
};
|
|
26560
27393
|
}
|
|
26561
27394
|
if (style.fontFamily) {
|
|
26562
|
-
runProps["a:latin"] =
|
|
26563
|
-
|
|
26564
|
-
|
|
26565
|
-
|
|
26566
|
-
|
|
26567
|
-
|
|
26568
|
-
|
|
27395
|
+
runProps["a:latin"] = applyFontMetadata(
|
|
27396
|
+
{ "@_typeface": style.fontFamily },
|
|
27397
|
+
style.latinFontPanose,
|
|
27398
|
+
style.latinFontPitchFamily,
|
|
27399
|
+
style.latinFontCharset
|
|
27400
|
+
);
|
|
27401
|
+
runProps["a:ea"] = applyFontMetadata(
|
|
27402
|
+
{ "@_typeface": style.eastAsiaFont || style.fontFamily },
|
|
27403
|
+
style.eastAsiaFontPanose,
|
|
27404
|
+
style.eastAsiaFontPitchFamily,
|
|
27405
|
+
style.eastAsiaFontCharset
|
|
27406
|
+
);
|
|
27407
|
+
runProps["a:cs"] = applyFontMetadata(
|
|
27408
|
+
{ "@_typeface": style.complexScriptFont || style.fontFamily },
|
|
27409
|
+
style.complexScriptFontPanose,
|
|
27410
|
+
style.complexScriptFontPitchFamily,
|
|
27411
|
+
style.complexScriptFontCharset
|
|
27412
|
+
);
|
|
26569
27413
|
}
|
|
26570
27414
|
if (style.symbolFont) {
|
|
26571
|
-
runProps["a:sym"] =
|
|
27415
|
+
runProps["a:sym"] = applyFontMetadata(
|
|
27416
|
+
{ "@_typeface": style.symbolFont },
|
|
27417
|
+
style.symbolFontPanose,
|
|
27418
|
+
style.symbolFontPitchFamily,
|
|
27419
|
+
style.symbolFontCharset
|
|
27420
|
+
);
|
|
26572
27421
|
}
|
|
26573
27422
|
if (style.hyperlink && resolveHyperlinkRelationshipId) {
|
|
26574
27423
|
const hyperlinkTarget = String(style.hyperlink).trim();
|
|
@@ -26643,14 +27492,15 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
|
|
|
26643
27492
|
lineSpacing: this.createLineSpacingXmlFromMultiplier(textStyle?.lineSpacing),
|
|
26644
27493
|
lineSpacingExactPt: textStyle?.lineSpacingExactPt
|
|
26645
27494
|
};
|
|
26646
|
-
const createParagraph = (runs, bulletInfo) => {
|
|
27495
|
+
const createParagraph = (runs, bulletInfo, level, endParaRunProperties) => {
|
|
26647
27496
|
const paragraphProps = buildParagraphPropertiesXml(
|
|
26648
27497
|
textStyle,
|
|
26649
27498
|
paragraphAlign,
|
|
26650
27499
|
bulletInfo,
|
|
26651
|
-
spacing
|
|
27500
|
+
spacing,
|
|
27501
|
+
level
|
|
26652
27502
|
);
|
|
26653
|
-
return assembleParagraphXml(runs, paragraphProps);
|
|
27503
|
+
return assembleParagraphXml(runs, paragraphProps, endParaRunProperties);
|
|
26654
27504
|
};
|
|
26655
27505
|
const createRun = (runText, style) => ({
|
|
26656
27506
|
"a:rPr": this.createRunPropertiesFromTextStyle(style, resolveHyperlinkRelationshipId),
|
|
@@ -26698,13 +27548,19 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
|
|
|
26698
27548
|
const paragraphs = [];
|
|
26699
27549
|
let currentRuns = [];
|
|
26700
27550
|
let currentBulletInfo;
|
|
27551
|
+
let currentLevel;
|
|
27552
|
+
let currentEndParaRunProperties;
|
|
26701
27553
|
const pushParagraph = () => {
|
|
26702
27554
|
if (currentRuns.length === 0) {
|
|
26703
27555
|
currentRuns.push(createRun("", textStyle));
|
|
26704
27556
|
}
|
|
26705
|
-
paragraphs.push(
|
|
27557
|
+
paragraphs.push(
|
|
27558
|
+
createParagraph(currentRuns, currentBulletInfo, currentLevel, currentEndParaRunProperties)
|
|
27559
|
+
);
|
|
26706
27560
|
currentRuns = [];
|
|
26707
27561
|
currentBulletInfo = void 0;
|
|
27562
|
+
currentLevel = void 0;
|
|
27563
|
+
currentEndParaRunProperties = void 0;
|
|
26708
27564
|
};
|
|
26709
27565
|
if (textSegments && textSegments.length > 0) {
|
|
26710
27566
|
const uniformSegmentOverrides = computeUniformSegmentOverrides(textStyle, textSegments);
|
|
@@ -26716,8 +27572,16 @@ var PptxHandlerRuntime13 = class extends PptxHandlerRuntime12 {
|
|
|
26716
27572
|
};
|
|
26717
27573
|
const segmentText = String(segment.text ?? "");
|
|
26718
27574
|
const lineParts = segmentText.split("\n");
|
|
26719
|
-
if (currentRuns.length === 0
|
|
26720
|
-
|
|
27575
|
+
if (currentRuns.length === 0) {
|
|
27576
|
+
if (segment.bulletInfo) {
|
|
27577
|
+
currentBulletInfo = segment.bulletInfo;
|
|
27578
|
+
}
|
|
27579
|
+
if (segment.paragraphLevel !== void 0) {
|
|
27580
|
+
currentLevel = segment.paragraphLevel;
|
|
27581
|
+
}
|
|
27582
|
+
if (segment.endParaRunProperties) {
|
|
27583
|
+
currentEndParaRunProperties = segment.endParaRunProperties;
|
|
27584
|
+
}
|
|
26721
27585
|
}
|
|
26722
27586
|
lineParts.forEach((linePart, lineIndex) => {
|
|
26723
27587
|
if (segment.rubyText !== void 0) {
|
|
@@ -26815,6 +27679,9 @@ var PptxHandlerRuntime14 = class extends PptxHandlerRuntime13 {
|
|
|
26815
27679
|
};
|
|
26816
27680
|
|
|
26817
27681
|
// src/core/core/runtime/PptxHandlerRuntimeSaveShapeXml.ts
|
|
27682
|
+
var OLE_OBJECT_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject";
|
|
27683
|
+
var IMAGE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
|
|
27684
|
+
var OLE_GRAPHIC_DATA_URI = "http://schemas.openxmlformats.org/presentationml/2006/ole";
|
|
26818
27685
|
var PptxHandlerRuntime15 = class _PptxHandlerRuntime extends PptxHandlerRuntime14 {
|
|
26819
27686
|
/**
|
|
26820
27687
|
* Build a `p:graphicFrame` XML skeleton for an SDK-created table.
|
|
@@ -26865,6 +27732,148 @@ var PptxHandlerRuntime15 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
26865
27732
|
}
|
|
26866
27733
|
};
|
|
26867
27734
|
}
|
|
27735
|
+
/**
|
|
27736
|
+
* Build a `p:graphicFrame` XML skeleton for an OLE object element.
|
|
27737
|
+
*
|
|
27738
|
+
* Used both for SDK-created OLE elements (no `rawXml`) and to refresh
|
|
27739
|
+
* a few key attributes on a loaded element when the typed fields have
|
|
27740
|
+
* been mutated. The output is the canonical
|
|
27741
|
+
* `p:graphicFrame > a:graphic > a:graphicData uri="…/ole" > p:oleObj`
|
|
27742
|
+
* shape per ECMA-376 §19.3.1.34 / §13.3.4.
|
|
27743
|
+
*
|
|
27744
|
+
* The caller (`processSlideElement`) is responsible for ensuring the
|
|
27745
|
+
* embed / preview-image relationships referenced from `r:id` / `r:embed`
|
|
27746
|
+
* exist in the slide's rels file. This method does not register them
|
|
27747
|
+
* itself because the typed model does not currently carry the binary
|
|
27748
|
+
* payload — the binary part must already be in the package (loaded from
|
|
27749
|
+
* the original file). A fully-fabricated SDK OLE element therefore
|
|
27750
|
+
* still requires the consumer to attach the binary out-of-band; this
|
|
27751
|
+
* method simply emits a schema-valid envelope referencing the
|
|
27752
|
+
* specified relationship ID.
|
|
27753
|
+
*/
|
|
27754
|
+
createOleGraphicFrameXml(el, embedRelationshipId) {
|
|
27755
|
+
const EMU = _PptxHandlerRuntime.EMU_PER_PX;
|
|
27756
|
+
const offX = String(Math.round(el.x * EMU));
|
|
27757
|
+
const offY = String(Math.round(el.y * EMU));
|
|
27758
|
+
const extCx = String(Math.round(Math.max(el.width, 1) * EMU));
|
|
27759
|
+
const extCy = String(Math.round(Math.max(el.height, 1) * EMU));
|
|
27760
|
+
const oleObj = {
|
|
27761
|
+
"@_showAsIcon": "0",
|
|
27762
|
+
"@_imgW": extCx,
|
|
27763
|
+
"@_imgH": extCy
|
|
27764
|
+
};
|
|
27765
|
+
if (el.oleProgId) {
|
|
27766
|
+
oleObj["@_progId"] = el.oleProgId;
|
|
27767
|
+
}
|
|
27768
|
+
if (el.oleName) {
|
|
27769
|
+
oleObj["@_name"] = el.oleName;
|
|
27770
|
+
}
|
|
27771
|
+
if (el.oleClsId) {
|
|
27772
|
+
oleObj["@_classid"] = el.oleClsId;
|
|
27773
|
+
}
|
|
27774
|
+
if (embedRelationshipId) {
|
|
27775
|
+
oleObj["@_r:id"] = embedRelationshipId;
|
|
27776
|
+
}
|
|
27777
|
+
if (el.isLinked) {
|
|
27778
|
+
oleObj["p:link"] = {
|
|
27779
|
+
"@_r:id": embedRelationshipId,
|
|
27780
|
+
"@_updateAutomatic": "1"
|
|
27781
|
+
};
|
|
27782
|
+
} else {
|
|
27783
|
+
oleObj["p:embed"] = {};
|
|
27784
|
+
}
|
|
27785
|
+
oleObj["p:pic"] = {
|
|
27786
|
+
"p:nvPicPr": {
|
|
27787
|
+
"p:cNvPr": { "@_id": "0", "@_name": el.oleName || "OleObject" },
|
|
27788
|
+
"p:cNvPicPr": {},
|
|
27789
|
+
"p:nvPr": {}
|
|
27790
|
+
},
|
|
27791
|
+
"p:blipFill": {
|
|
27792
|
+
"a:blip": {},
|
|
27793
|
+
"a:stretch": { "a:fillRect": {} }
|
|
27794
|
+
},
|
|
27795
|
+
"p:spPr": {
|
|
27796
|
+
"a:xfrm": {
|
|
27797
|
+
"a:off": { "@_x": offX, "@_y": offY },
|
|
27798
|
+
"a:ext": { "@_cx": extCx, "@_cy": extCy }
|
|
27799
|
+
},
|
|
27800
|
+
"a:prstGeom": { "@_prst": "rect", "a:avLst": {} }
|
|
27801
|
+
}
|
|
27802
|
+
};
|
|
27803
|
+
return {
|
|
27804
|
+
"p:nvGraphicFramePr": {
|
|
27805
|
+
"p:cNvPr": { "@_id": "0", "@_name": el.oleName || el.fileName || "OleObject" },
|
|
27806
|
+
"p:cNvGraphicFramePr": {
|
|
27807
|
+
"a:graphicFrameLocks": { "@_noChangeAspect": "1" }
|
|
27808
|
+
},
|
|
27809
|
+
"p:nvPr": {}
|
|
27810
|
+
},
|
|
27811
|
+
"p:xfrm": {
|
|
27812
|
+
"a:off": { "@_x": offX, "@_y": offY },
|
|
27813
|
+
"a:ext": { "@_cx": extCx, "@_cy": extCy }
|
|
27814
|
+
},
|
|
27815
|
+
"a:graphic": {
|
|
27816
|
+
"a:graphicData": {
|
|
27817
|
+
"@_uri": OLE_GRAPHIC_DATA_URI,
|
|
27818
|
+
"p:oleObj": oleObj
|
|
27819
|
+
}
|
|
27820
|
+
}
|
|
27821
|
+
};
|
|
27822
|
+
}
|
|
27823
|
+
/**
|
|
27824
|
+
* Refresh editable typed-field attributes on a loaded OLE graphicFrame's
|
|
27825
|
+
* raw XML. Only attributes that round-trip through the typed model
|
|
27826
|
+
* (`progId`, `name`, `classid`) are touched so unknown extension data
|
|
27827
|
+
* passes through verbatim.
|
|
27828
|
+
*/
|
|
27829
|
+
applyOleTypedFieldUpdates(shape, el) {
|
|
27830
|
+
const oleObj = shape["a:graphic"]?.["a:graphicData"]?.["p:oleObj"];
|
|
27831
|
+
if (!oleObj) {
|
|
27832
|
+
return;
|
|
27833
|
+
}
|
|
27834
|
+
if (el.oleProgId) {
|
|
27835
|
+
oleObj["@_progId"] = el.oleProgId;
|
|
27836
|
+
}
|
|
27837
|
+
if (el.oleName !== void 0) {
|
|
27838
|
+
if (el.oleName.length > 0) {
|
|
27839
|
+
oleObj["@_name"] = el.oleName;
|
|
27840
|
+
} else {
|
|
27841
|
+
delete oleObj["@_name"];
|
|
27842
|
+
}
|
|
27843
|
+
}
|
|
27844
|
+
if (el.oleClsId) {
|
|
27845
|
+
oleObj["@_classid"] = el.oleClsId;
|
|
27846
|
+
}
|
|
27847
|
+
}
|
|
27848
|
+
/** Look up the existing OLE binary relationship ID for this slide, if any. */
|
|
27849
|
+
resolveOleEmbedRelationshipId(slideRelationships, oleTarget) {
|
|
27850
|
+
if (!oleTarget) {
|
|
27851
|
+
return void 0;
|
|
27852
|
+
}
|
|
27853
|
+
const normalisedTarget = oleTarget.replace(/^ppt\//, "../").replace(/^\/+/, "");
|
|
27854
|
+
const lowerTarget = normalisedTarget.toLowerCase();
|
|
27855
|
+
for (const rel of slideRelationships) {
|
|
27856
|
+
const relType = String(rel?.["@_Type"] || "");
|
|
27857
|
+
if (relType !== OLE_OBJECT_RELATIONSHIP_TYPE) {
|
|
27858
|
+
continue;
|
|
27859
|
+
}
|
|
27860
|
+
const target = String(rel?.["@_Target"] || "").toLowerCase().trim();
|
|
27861
|
+
if (target === lowerTarget || target.endsWith(lowerTarget) || lowerTarget.endsWith(target)) {
|
|
27862
|
+
const relId = String(rel?.["@_Id"] || "").trim();
|
|
27863
|
+
if (relId.length > 0) {
|
|
27864
|
+
return relId;
|
|
27865
|
+
}
|
|
27866
|
+
}
|
|
27867
|
+
}
|
|
27868
|
+
const fallback = slideRelationships.find(
|
|
27869
|
+
(rel) => String(rel?.["@_Type"] || "") === OLE_OBJECT_RELATIONSHIP_TYPE
|
|
27870
|
+
);
|
|
27871
|
+
const fallbackId = String(fallback?.["@_Id"] || "").trim();
|
|
27872
|
+
return fallbackId.length > 0 ? fallbackId : void 0;
|
|
27873
|
+
}
|
|
27874
|
+
/** Constants are exposed so the element-writer mixin can reuse them. */
|
|
27875
|
+
static OLE_OBJECT_RELATIONSHIP_TYPE = OLE_OBJECT_RELATIONSHIP_TYPE;
|
|
27876
|
+
static OLE_IMAGE_RELATIONSHIP_TYPE = IMAGE_RELATIONSHIP_TYPE;
|
|
26868
27877
|
/**
|
|
26869
27878
|
* Build a p:sp XML object for an ink annotation element.
|
|
26870
27879
|
* Each ink path becomes a separate a:path within a:pathLst,
|
|
@@ -27181,6 +28190,9 @@ var PptxHandlerRuntime16 = class extends PptxHandlerRuntime15 {
|
|
|
27181
28190
|
buildOuterShadowXml(shapeStyle) {
|
|
27182
28191
|
return this.colorStyleCodec.buildOuterShadowXml(shapeStyle);
|
|
27183
28192
|
}
|
|
28193
|
+
buildPresetShadowXml(shapeStyle) {
|
|
28194
|
+
return this.colorStyleCodec.buildPresetShadowXml(shapeStyle);
|
|
28195
|
+
}
|
|
27184
28196
|
buildInnerShadowXml(shapeStyle) {
|
|
27185
28197
|
return this.colorStyleCodec.buildInnerShadowXml(shapeStyle);
|
|
27186
28198
|
}
|
|
@@ -27731,6 +28743,10 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
27731
28743
|
const solidFill = runProperties["a:solidFill"];
|
|
27732
28744
|
if (solidFill) {
|
|
27733
28745
|
style.color = this.parseColor(solidFill);
|
|
28746
|
+
const colorXml = extractColorChoiceXml(solidFill);
|
|
28747
|
+
if (colorXml) {
|
|
28748
|
+
style.colorXml = colorXml;
|
|
28749
|
+
}
|
|
27734
28750
|
}
|
|
27735
28751
|
this.applyHyperlinkStyle(style, runProperties, relationshipMap);
|
|
27736
28752
|
const capAttr = String(runProperties["@_cap"] || "").trim().toLowerCase();
|
|
@@ -27778,12 +28794,86 @@ var PptxHandlerRuntime19 = class _PptxHandlerRuntime extends PptxHandlerRuntime1
|
|
|
27778
28794
|
if (bmk) {
|
|
27779
28795
|
style.bookmark = bmk;
|
|
27780
28796
|
}
|
|
28797
|
+
const altLang = String(runProperties["@_altLang"] || "").trim();
|
|
28798
|
+
if (altLang) {
|
|
28799
|
+
style.altLanguage = altLang;
|
|
28800
|
+
}
|
|
28801
|
+
if (runProperties["@_smtId"] !== void 0) {
|
|
28802
|
+
const smtIdRaw = Number.parseInt(String(runProperties["@_smtId"]), 10);
|
|
28803
|
+
if (Number.isFinite(smtIdRaw)) {
|
|
28804
|
+
style.smartTagId = smtIdRaw;
|
|
28805
|
+
}
|
|
28806
|
+
}
|
|
28807
|
+
this.applyTextFontMetadata(style, latin, "latin");
|
|
28808
|
+
this.applyTextFontMetadata(style, eastAsian, "eastAsia");
|
|
28809
|
+
this.applyTextFontMetadata(style, complexScript, "complexScript");
|
|
28810
|
+
this.applyTextFontMetadata(style, runProperties["a:sym"], "symbol");
|
|
27781
28811
|
const runEffectList = runProperties["a:effectLst"];
|
|
27782
28812
|
if (runEffectList) {
|
|
27783
28813
|
this.applyTextRunEffects(style, runEffectList);
|
|
27784
28814
|
}
|
|
27785
28815
|
return style;
|
|
27786
28816
|
}
|
|
28817
|
+
/**
|
|
28818
|
+
* Copy `@panose` / `@pitchFamily` / `@charset` from a font child node
|
|
28819
|
+
* (`a:latin`, `a:ea`, `a:cs`, `a:sym`) onto the matching `*Font*`
|
|
28820
|
+
* fields of `style`.
|
|
28821
|
+
*/
|
|
28822
|
+
applyTextFontMetadata(style, fontNode, kind) {
|
|
28823
|
+
if (!fontNode) {
|
|
28824
|
+
return;
|
|
28825
|
+
}
|
|
28826
|
+
const panose = String(fontNode["@_panose"] || "").trim();
|
|
28827
|
+
const pitchRaw = fontNode["@_pitchFamily"];
|
|
28828
|
+
const charsetRaw = fontNode["@_charset"];
|
|
28829
|
+
const pitch = pitchRaw !== void 0 && pitchRaw !== null ? Number.parseInt(String(pitchRaw), 10) : void 0;
|
|
28830
|
+
const charset = charsetRaw !== void 0 && charsetRaw !== null ? Number.parseInt(String(charsetRaw), 10) : void 0;
|
|
28831
|
+
if (kind === "latin") {
|
|
28832
|
+
if (panose) {
|
|
28833
|
+
style.latinFontPanose = panose;
|
|
28834
|
+
}
|
|
28835
|
+
if (typeof pitch === "number" && Number.isFinite(pitch)) {
|
|
28836
|
+
style.latinFontPitchFamily = pitch;
|
|
28837
|
+
}
|
|
28838
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
28839
|
+
style.latinFontCharset = charset;
|
|
28840
|
+
}
|
|
28841
|
+
return;
|
|
28842
|
+
}
|
|
28843
|
+
if (kind === "eastAsia") {
|
|
28844
|
+
if (panose) {
|
|
28845
|
+
style.eastAsiaFontPanose = panose;
|
|
28846
|
+
}
|
|
28847
|
+
if (typeof pitch === "number" && Number.isFinite(pitch)) {
|
|
28848
|
+
style.eastAsiaFontPitchFamily = pitch;
|
|
28849
|
+
}
|
|
28850
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
28851
|
+
style.eastAsiaFontCharset = charset;
|
|
28852
|
+
}
|
|
28853
|
+
return;
|
|
28854
|
+
}
|
|
28855
|
+
if (kind === "complexScript") {
|
|
28856
|
+
if (panose) {
|
|
28857
|
+
style.complexScriptFontPanose = panose;
|
|
28858
|
+
}
|
|
28859
|
+
if (typeof pitch === "number" && Number.isFinite(pitch)) {
|
|
28860
|
+
style.complexScriptFontPitchFamily = pitch;
|
|
28861
|
+
}
|
|
28862
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
28863
|
+
style.complexScriptFontCharset = charset;
|
|
28864
|
+
}
|
|
28865
|
+
return;
|
|
28866
|
+
}
|
|
28867
|
+
if (panose) {
|
|
28868
|
+
style.symbolFontPanose = panose;
|
|
28869
|
+
}
|
|
28870
|
+
if (typeof pitch === "number" && Number.isFinite(pitch)) {
|
|
28871
|
+
style.symbolFontPitchFamily = pitch;
|
|
28872
|
+
}
|
|
28873
|
+
if (typeof charset === "number" && Number.isFinite(charset)) {
|
|
28874
|
+
style.symbolFontCharset = charset;
|
|
28875
|
+
}
|
|
28876
|
+
}
|
|
27787
28877
|
};
|
|
27788
28878
|
|
|
27789
28879
|
// src/core/core/runtime/PptxHandlerRuntimeTextEditing.ts
|
|
@@ -28219,7 +29309,7 @@ var PptxHandlerRuntime21 = class extends PptxHandlerRuntime20 {
|
|
|
28219
29309
|
};
|
|
28220
29310
|
|
|
28221
29311
|
// src/core/core/runtime/table-cell-save-helpers.ts
|
|
28222
|
-
function writeCellFill(tcPr, style) {
|
|
29312
|
+
function writeCellFill(tcPr, style, resolveColorXml) {
|
|
28223
29313
|
if (style.fillMode === "gradient" && style.gradientFillStops && style.gradientFillStops.length > 0) {
|
|
28224
29314
|
delete tcPr["a:solidFill"];
|
|
28225
29315
|
delete tcPr["a:pattFill"];
|
|
@@ -28298,11 +29388,12 @@ function writeCellFill(tcPr, style) {
|
|
|
28298
29388
|
} else if (style.backgroundColor) {
|
|
28299
29389
|
delete tcPr["a:gradFill"];
|
|
28300
29390
|
delete tcPr["a:pattFill"];
|
|
28301
|
-
|
|
28302
|
-
|
|
28303
|
-
|
|
28304
|
-
|
|
28305
|
-
|
|
29391
|
+
const resolvedOriginal = style.backgroundColorXml && resolveColorXml ? resolveColorXml(style.backgroundColorXml) : void 0;
|
|
29392
|
+
tcPr["a:solidFill"] = serializeColorChoice(
|
|
29393
|
+
style.backgroundColorXml,
|
|
29394
|
+
resolvedOriginal,
|
|
29395
|
+
style.backgroundColor
|
|
29396
|
+
);
|
|
28306
29397
|
}
|
|
28307
29398
|
}
|
|
28308
29399
|
function writeDiagonalBorders(tcPr, style, emuPerPx) {
|
|
@@ -28433,7 +29524,7 @@ var PptxHandlerRuntime22 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
28433
29524
|
xmlCell["a:tcPr"] = {};
|
|
28434
29525
|
}
|
|
28435
29526
|
const tcPr = xmlCell["a:tcPr"];
|
|
28436
|
-
writeCellFill(tcPr, style);
|
|
29527
|
+
writeCellFill(tcPr, style, (colorXml) => this.parseColor(colorXml));
|
|
28437
29528
|
if (style.vAlign) {
|
|
28438
29529
|
const vAlignMap = {
|
|
28439
29530
|
top: "t",
|
|
@@ -28515,35 +29606,29 @@ var PptxHandlerRuntime22 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
28515
29606
|
}
|
|
28516
29607
|
}
|
|
28517
29608
|
}
|
|
28518
|
-
|
|
28519
|
-
|
|
28520
|
-
|
|
28521
|
-
tcPr["a:tcMar"] = {};
|
|
28522
|
-
}
|
|
28523
|
-
const tcMar = tcPr["a:tcMar"];
|
|
28524
|
-
if (style.marginLeft !== void 0) {
|
|
28525
|
-
tcMar["a:marL"] = {
|
|
28526
|
-
"@_w": String(Math.round(style.marginLeft * emuPerPx))
|
|
28527
|
-
};
|
|
28528
|
-
}
|
|
28529
|
-
if (style.marginRight !== void 0) {
|
|
28530
|
-
tcMar["a:marR"] = {
|
|
28531
|
-
"@_w": String(Math.round(style.marginRight * emuPerPx))
|
|
28532
|
-
};
|
|
28533
|
-
}
|
|
28534
|
-
if (style.marginTop !== void 0) {
|
|
28535
|
-
tcMar["a:marT"] = {
|
|
28536
|
-
"@_w": String(Math.round(style.marginTop * emuPerPx))
|
|
28537
|
-
};
|
|
28538
|
-
}
|
|
28539
|
-
if (style.marginBottom !== void 0) {
|
|
28540
|
-
tcMar["a:marB"] = {
|
|
28541
|
-
"@_w": String(Math.round(style.marginBottom * emuPerPx))
|
|
28542
|
-
};
|
|
28543
|
-
}
|
|
29609
|
+
const emuPerPx = _PptxHandlerRuntime.EMU_PER_PX;
|
|
29610
|
+
if (style.marginLeft !== void 0) {
|
|
29611
|
+
tcPr["@_marL"] = String(Math.round(style.marginLeft * emuPerPx));
|
|
28544
29612
|
}
|
|
29613
|
+
if (style.marginRight !== void 0) {
|
|
29614
|
+
tcPr["@_marR"] = String(Math.round(style.marginRight * emuPerPx));
|
|
29615
|
+
}
|
|
29616
|
+
if (style.marginTop !== void 0) {
|
|
29617
|
+
tcPr["@_marT"] = String(Math.round(style.marginTop * emuPerPx));
|
|
29618
|
+
}
|
|
29619
|
+
if (style.marginBottom !== void 0) {
|
|
29620
|
+
tcPr["@_marB"] = String(Math.round(style.marginBottom * emuPerPx));
|
|
29621
|
+
}
|
|
29622
|
+
delete tcPr["a:tcMar"];
|
|
28545
29623
|
writeDiagonalBorders(tcPr, style, _PptxHandlerRuntime.EMU_PER_PX);
|
|
28546
29624
|
writeCellTextFormatting(xmlCell, style, this.ensureArray.bind(this));
|
|
29625
|
+
const reordered = reorderObjectKeys(tcPr, TC_PR_BORDERS_ORDER);
|
|
29626
|
+
for (const key of Object.keys(tcPr)) {
|
|
29627
|
+
delete tcPr[key];
|
|
29628
|
+
}
|
|
29629
|
+
for (const key of Object.keys(reordered)) {
|
|
29630
|
+
tcPr[key] = reordered[key];
|
|
29631
|
+
}
|
|
28547
29632
|
}
|
|
28548
29633
|
};
|
|
28549
29634
|
|
|
@@ -28647,6 +29732,49 @@ function createDefaultXmlCell() {
|
|
|
28647
29732
|
// src/core/core/runtime/table-xml-rebuild.ts
|
|
28648
29733
|
var GRID_COL_ID_EXT_URI = "{9D8B030D-6E8A-4147-A177-3AD203B41FA5}";
|
|
28649
29734
|
var A16_NAMESPACE = "http://schemas.microsoft.com/office/drawing/2014/main";
|
|
29735
|
+
function ensureA16NamespaceOnSlideRoot(slideRoot) {
|
|
29736
|
+
if (!slideRoot["@_xmlns:a16"]) {
|
|
29737
|
+
slideRoot["@_xmlns:a16"] = A16_NAMESPACE;
|
|
29738
|
+
}
|
|
29739
|
+
if (!slideRoot["@_xmlns:mc"]) {
|
|
29740
|
+
slideRoot["@_xmlns:mc"] = "http://schemas.openxmlformats.org/markup-compatibility/2006";
|
|
29741
|
+
}
|
|
29742
|
+
const existingIgnorable = String(slideRoot["@_mc:Ignorable"] || "").trim();
|
|
29743
|
+
if (existingIgnorable.length === 0) {
|
|
29744
|
+
slideRoot["@_mc:Ignorable"] = "a16";
|
|
29745
|
+
return;
|
|
29746
|
+
}
|
|
29747
|
+
const tokens = existingIgnorable.split(/\s+/).filter((token) => token.length > 0);
|
|
29748
|
+
if (!tokens.includes("a16")) {
|
|
29749
|
+
tokens.push("a16");
|
|
29750
|
+
slideRoot["@_mc:Ignorable"] = tokens.join(" ");
|
|
29751
|
+
}
|
|
29752
|
+
}
|
|
29753
|
+
function slideContainsA16Element(node) {
|
|
29754
|
+
if (node === null || node === void 0) {
|
|
29755
|
+
return false;
|
|
29756
|
+
}
|
|
29757
|
+
if (Array.isArray(node)) {
|
|
29758
|
+
for (const entry of node) {
|
|
29759
|
+
if (slideContainsA16Element(entry)) {
|
|
29760
|
+
return true;
|
|
29761
|
+
}
|
|
29762
|
+
}
|
|
29763
|
+
return false;
|
|
29764
|
+
}
|
|
29765
|
+
if (typeof node !== "object") {
|
|
29766
|
+
return false;
|
|
29767
|
+
}
|
|
29768
|
+
for (const [key, value] of Object.entries(node)) {
|
|
29769
|
+
if (key.startsWith("a16:")) {
|
|
29770
|
+
return true;
|
|
29771
|
+
}
|
|
29772
|
+
if (slideContainsA16Element(value)) {
|
|
29773
|
+
return true;
|
|
29774
|
+
}
|
|
29775
|
+
}
|
|
29776
|
+
return false;
|
|
29777
|
+
}
|
|
28650
29778
|
function randomColumnId() {
|
|
28651
29779
|
return String(Math.floor(Math.random() * 4294967295));
|
|
28652
29780
|
}
|
|
@@ -28677,8 +29805,10 @@ function rebuildTableXmlFromData(tbl, tableData, emuPerPx, ensureArrayFn) {
|
|
|
28677
29805
|
"a:extLst": {
|
|
28678
29806
|
"a:ext": {
|
|
28679
29807
|
"@_uri": GRID_COL_ID_EXT_URI,
|
|
29808
|
+
// `xmlns:a16` is declared on the slide root by
|
|
29809
|
+
// `ensureA16NamespaceOnSlideRoot`; emitting it here too is
|
|
29810
|
+
// schema-redundant and PowerPoint flags it.
|
|
28680
29811
|
"a16:colId": {
|
|
28681
|
-
"@_xmlns:a16": A16_NAMESPACE,
|
|
28682
29812
|
"@_val": existingColIds[i] || randomColumnId()
|
|
28683
29813
|
}
|
|
28684
29814
|
}
|
|
@@ -29037,26 +30167,64 @@ var PptxHandlerRuntime23 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
29037
30167
|
continue;
|
|
29038
30168
|
}
|
|
29039
30169
|
const scalingNode = this.xmlLookupService.getChildByLocalName(axisNode, "scaling");
|
|
29040
|
-
if (
|
|
29041
|
-
|
|
30170
|
+
if (scalingNode) {
|
|
30171
|
+
if (matchingAxis.logBase !== void 0 && matchingAxis.logBase > 0) {
|
|
30172
|
+
const logBaseKey = Object.keys(scalingNode).find(
|
|
30173
|
+
(k) => this.compatibilityService.getXmlLocalName(k) === "logBase"
|
|
30174
|
+
);
|
|
30175
|
+
if (logBaseKey) {
|
|
30176
|
+
scalingNode[logBaseKey]["@_val"] = String(matchingAxis.logBase);
|
|
30177
|
+
} else {
|
|
30178
|
+
scalingNode["c:logBase"] = {
|
|
30179
|
+
"@_val": String(matchingAxis.logBase)
|
|
30180
|
+
};
|
|
30181
|
+
}
|
|
30182
|
+
} else if (matchingAxis.logScale === false) {
|
|
30183
|
+
const logBaseKey = Object.keys(scalingNode).find(
|
|
30184
|
+
(k) => this.compatibilityService.getXmlLocalName(k) === "logBase"
|
|
30185
|
+
);
|
|
30186
|
+
if (logBaseKey) {
|
|
30187
|
+
delete scalingNode[logBaseKey];
|
|
30188
|
+
}
|
|
30189
|
+
}
|
|
30190
|
+
this.upsertChartAxisChild(
|
|
30191
|
+
scalingNode,
|
|
30192
|
+
"min",
|
|
30193
|
+
matchingAxis.min !== void 0 ? String(matchingAxis.min) : void 0
|
|
30194
|
+
);
|
|
30195
|
+
this.upsertChartAxisChild(
|
|
30196
|
+
scalingNode,
|
|
30197
|
+
"max",
|
|
30198
|
+
matchingAxis.max !== void 0 ? String(matchingAxis.max) : void 0
|
|
30199
|
+
);
|
|
29042
30200
|
}
|
|
29043
|
-
if (matchingAxis.
|
|
29044
|
-
const
|
|
29045
|
-
(k) => this.compatibilityService.getXmlLocalName(k) === "
|
|
30201
|
+
if (matchingAxis.numFmt) {
|
|
30202
|
+
const numFmtKey = Object.keys(axisNode).find(
|
|
30203
|
+
(k) => this.compatibilityService.getXmlLocalName(k) === "numFmt"
|
|
29046
30204
|
);
|
|
29047
|
-
|
|
29048
|
-
|
|
30205
|
+
const numFmtAttrs = {
|
|
30206
|
+
"@_formatCode": matchingAxis.numFmt.formatCode,
|
|
30207
|
+
"@_sourceLinked": matchingAxis.numFmt.sourceLinked ? "1" : "0"
|
|
30208
|
+
};
|
|
30209
|
+
if (numFmtKey) {
|
|
30210
|
+
axisNode[numFmtKey] = numFmtAttrs;
|
|
29049
30211
|
} else {
|
|
29050
|
-
|
|
29051
|
-
"@_val": String(matchingAxis.logBase)
|
|
29052
|
-
};
|
|
30212
|
+
axisNode["c:numFmt"] = numFmtAttrs;
|
|
29053
30213
|
}
|
|
29054
|
-
}
|
|
29055
|
-
|
|
29056
|
-
|
|
30214
|
+
}
|
|
30215
|
+
this.upsertChartAxisChild(
|
|
30216
|
+
axisNode,
|
|
30217
|
+
"majorUnit",
|
|
30218
|
+
matchingAxis.majorUnit !== void 0 ? String(matchingAxis.majorUnit) : void 0
|
|
30219
|
+
);
|
|
30220
|
+
if (matchingAxis.tickLblPos !== void 0) {
|
|
30221
|
+
const tickLblKey = Object.keys(axisNode).find(
|
|
30222
|
+
(k) => this.compatibilityService.getXmlLocalName(k) === "tickLblPos"
|
|
29057
30223
|
);
|
|
29058
|
-
if (
|
|
29059
|
-
|
|
30224
|
+
if (tickLblKey) {
|
|
30225
|
+
axisNode[tickLblKey]["@_val"] = matchingAxis.tickLblPos;
|
|
30226
|
+
} else {
|
|
30227
|
+
axisNode["c:tickLblPos"] = { "@_val": matchingAxis.tickLblPos };
|
|
29060
30228
|
}
|
|
29061
30229
|
}
|
|
29062
30230
|
}
|
|
@@ -29069,6 +30237,18 @@ var PptxHandlerRuntime23 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
29069
30237
|
}
|
|
29070
30238
|
this.pendingChartUpdates = void 0;
|
|
29071
30239
|
}
|
|
30240
|
+
/**
|
|
30241
|
+
* Upsert a `c:<localName>` child with `@_val` on an axis or scaling node.
|
|
30242
|
+
* When `value` is undefined, removes any existing child of that local name.
|
|
30243
|
+
*/
|
|
30244
|
+
upsertChartAxisChild(parent, localName, value) {
|
|
30245
|
+
upsertChartAxisChild(
|
|
30246
|
+
parent,
|
|
30247
|
+
localName,
|
|
30248
|
+
value,
|
|
30249
|
+
(key) => this.compatibilityService.getXmlLocalName(key)
|
|
30250
|
+
);
|
|
30251
|
+
}
|
|
29072
30252
|
/**
|
|
29073
30253
|
* Update the cached point values in a chart reference node
|
|
29074
30254
|
* (numRef/strRef or numLit/strLit).
|
|
@@ -30348,17 +31528,13 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30348
31528
|
delete spPr["a:noFill"];
|
|
30349
31529
|
delete spPr["a:gradFill"];
|
|
30350
31530
|
delete spPr["a:blipFill"];
|
|
30351
|
-
const
|
|
30352
|
-
|
|
30353
|
-
|
|
30354
|
-
|
|
30355
|
-
|
|
30356
|
-
|
|
30357
|
-
|
|
30358
|
-
"@_val": String(Math.round(this.clampUnitInterval(shapeStyle.fillOpacity) * 1e5))
|
|
30359
|
-
};
|
|
30360
|
-
}
|
|
30361
|
-
spPr["a:solidFill"] = solidFill;
|
|
31531
|
+
const resolvedOriginal = shapeStyle.fillColorXml ? this.parseColor(shapeStyle.fillColorXml) : void 0;
|
|
31532
|
+
spPr["a:solidFill"] = serializeColorChoice(
|
|
31533
|
+
shapeStyle.fillColorXml,
|
|
31534
|
+
resolvedOriginal,
|
|
31535
|
+
fillColor,
|
|
31536
|
+
shapeStyle.fillOpacity
|
|
31537
|
+
);
|
|
30362
31538
|
}
|
|
30363
31539
|
}
|
|
30364
31540
|
if (shapeStyle.strokeColor !== void 0) {
|
|
@@ -30373,17 +31549,13 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30373
31549
|
delete lineNode["a:solidFill"];
|
|
30374
31550
|
} else {
|
|
30375
31551
|
delete lineNode["a:noFill"];
|
|
30376
|
-
const
|
|
30377
|
-
|
|
30378
|
-
|
|
30379
|
-
|
|
30380
|
-
|
|
30381
|
-
|
|
30382
|
-
|
|
30383
|
-
"@_val": String(Math.round(this.clampUnitInterval(shapeStyle.strokeOpacity) * 1e5))
|
|
30384
|
-
};
|
|
30385
|
-
}
|
|
30386
|
-
lineNode["a:solidFill"] = lineFill;
|
|
31552
|
+
const resolvedStrokeOriginal = shapeStyle.strokeColorXml ? this.parseColor(shapeStyle.strokeColorXml) : void 0;
|
|
31553
|
+
lineNode["a:solidFill"] = serializeColorChoice(
|
|
31554
|
+
shapeStyle.strokeColorXml,
|
|
31555
|
+
resolvedStrokeOriginal,
|
|
31556
|
+
shapeStyle.strokeColor,
|
|
31557
|
+
shapeStyle.strokeOpacity
|
|
31558
|
+
);
|
|
30387
31559
|
}
|
|
30388
31560
|
}
|
|
30389
31561
|
if (shapeStyle.strokeDash !== void 0) {
|
|
@@ -30464,7 +31636,11 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30464
31636
|
} else if (shapeStyle.lineJoin === "bevel") {
|
|
30465
31637
|
lineNode["a:bevel"] = {};
|
|
30466
31638
|
} else if (shapeStyle.lineJoin === "miter") {
|
|
30467
|
-
|
|
31639
|
+
const miterNode = {};
|
|
31640
|
+
if (typeof shapeStyle.miterLimit === "number" && Number.isFinite(shapeStyle.miterLimit) && shapeStyle.miterLimit !== 8e5) {
|
|
31641
|
+
miterNode["@_lim"] = String(Math.round(shapeStyle.miterLimit));
|
|
31642
|
+
}
|
|
31643
|
+
lineNode["a:miter"] = miterNode;
|
|
30468
31644
|
}
|
|
30469
31645
|
}
|
|
30470
31646
|
if (shapeStyle.lineCap !== void 0) {
|
|
@@ -30484,6 +31660,82 @@ var PptxHandlerRuntime28 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30484
31660
|
spPr["a:ln"]["a:effectLst"] = lineEffectListXml;
|
|
30485
31661
|
}
|
|
30486
31662
|
}
|
|
31663
|
+
/**
|
|
31664
|
+
* Serialize the shape's `<p:style>` block (CT_ShapeStyle §20.1.2.2.36)
|
|
31665
|
+
* from the persisted ref indices/colour XML. Emits children in spec
|
|
31666
|
+
* order: `lnRef → fillRef → effectRef → fontRef`.
|
|
31667
|
+
*
|
|
31668
|
+
* When the original shape XML already contained a `<p:style>` we mutate
|
|
31669
|
+
* that node in place so any unmodelled attributes/children are preserved.
|
|
31670
|
+
* When it didn't, we create one. When the shape no longer has any ref
|
|
31671
|
+
* data we leave the existing `<p:style>` (if any) untouched — silently
|
|
31672
|
+
* dropping it would break round-tripping.
|
|
31673
|
+
*
|
|
31674
|
+
* Phase 2 Stream B / C-H2.
|
|
31675
|
+
*/
|
|
31676
|
+
applyShapeStyleRefs(shape, shapeStyle) {
|
|
31677
|
+
const hasAnyRef = shapeStyle.lnRefIdx !== void 0 || shapeStyle.fillRefIdx !== void 0 || shapeStyle.effectRefIdx !== void 0 || shapeStyle.fontRefIdx !== void 0;
|
|
31678
|
+
if (!hasAnyRef) {
|
|
31679
|
+
return;
|
|
31680
|
+
}
|
|
31681
|
+
const existing = shape["p:style"];
|
|
31682
|
+
const styleNode = existing ?? {};
|
|
31683
|
+
if (shapeStyle.lnRefIdx !== void 0) {
|
|
31684
|
+
const lnRef = styleNode["a:lnRef"] ?? {};
|
|
31685
|
+
lnRef["@_idx"] = String(shapeStyle.lnRefIdx);
|
|
31686
|
+
this.replaceRefColorChoice(lnRef, shapeStyle.lnRefColorXml);
|
|
31687
|
+
styleNode["a:lnRef"] = lnRef;
|
|
31688
|
+
}
|
|
31689
|
+
if (shapeStyle.fillRefIdx !== void 0) {
|
|
31690
|
+
const fillRef = styleNode["a:fillRef"] ?? {};
|
|
31691
|
+
fillRef["@_idx"] = String(shapeStyle.fillRefIdx);
|
|
31692
|
+
this.replaceRefColorChoice(fillRef, shapeStyle.fillRefColorXml);
|
|
31693
|
+
styleNode["a:fillRef"] = fillRef;
|
|
31694
|
+
}
|
|
31695
|
+
if (shapeStyle.effectRefIdx !== void 0) {
|
|
31696
|
+
const effectRef = styleNode["a:effectRef"] ?? {};
|
|
31697
|
+
effectRef["@_idx"] = String(shapeStyle.effectRefIdx);
|
|
31698
|
+
this.replaceRefColorChoice(effectRef, shapeStyle.effectRefColorXml);
|
|
31699
|
+
styleNode["a:effectRef"] = effectRef;
|
|
31700
|
+
}
|
|
31701
|
+
if (shapeStyle.fontRefIdx !== void 0) {
|
|
31702
|
+
const fontRef = styleNode["a:fontRef"] ?? {};
|
|
31703
|
+
fontRef["@_idx"] = shapeStyle.fontRefIdx;
|
|
31704
|
+
this.replaceRefColorChoice(fontRef, shapeStyle.fontRefColorXml);
|
|
31705
|
+
styleNode["a:fontRef"] = fontRef;
|
|
31706
|
+
}
|
|
31707
|
+
const reordered = reorderObjectKeys(styleNode, SHAPE_STYLE_ORDER);
|
|
31708
|
+
for (const key of Object.keys(styleNode)) {
|
|
31709
|
+
delete styleNode[key];
|
|
31710
|
+
}
|
|
31711
|
+
for (const key of Object.keys(reordered)) {
|
|
31712
|
+
styleNode[key] = reordered[key];
|
|
31713
|
+
}
|
|
31714
|
+
shape["p:style"] = styleNode;
|
|
31715
|
+
}
|
|
31716
|
+
/**
|
|
31717
|
+
* Replace any existing colour-choice child on a style-matrix-reference
|
|
31718
|
+
* element with the given preserved XML, or strip all colour children
|
|
31719
|
+
* when the override is undefined.
|
|
31720
|
+
*/
|
|
31721
|
+
replaceRefColorChoice(refNode, colorXml) {
|
|
31722
|
+
for (const key of [
|
|
31723
|
+
"a:scrgbClr",
|
|
31724
|
+
"a:srgbClr",
|
|
31725
|
+
"a:hslClr",
|
|
31726
|
+
"a:sysClr",
|
|
31727
|
+
"a:schemeClr",
|
|
31728
|
+
"a:prstClr"
|
|
31729
|
+
]) {
|
|
31730
|
+
delete refNode[key];
|
|
31731
|
+
}
|
|
31732
|
+
if (!colorXml) {
|
|
31733
|
+
return;
|
|
31734
|
+
}
|
|
31735
|
+
for (const [key, value] of Object.entries(colorXml)) {
|
|
31736
|
+
refNode[key] = value;
|
|
31737
|
+
}
|
|
31738
|
+
}
|
|
30487
31739
|
};
|
|
30488
31740
|
|
|
30489
31741
|
// src/core/core/runtime/PptxHandlerRuntimeSaveEffectsWriter.ts
|
|
@@ -30493,17 +31745,22 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
|
|
|
30493
31745
|
* effectDag, 3D scene, and 3D shape properties to the given spPr XML object.
|
|
30494
31746
|
*/
|
|
30495
31747
|
applyEffectsAndThreeD(spPr, shapeStyle) {
|
|
30496
|
-
const
|
|
31748
|
+
const presetShadowXml = shapeStyle.presetShadowName ? this.buildPresetShadowXml(shapeStyle) : void 0;
|
|
31749
|
+
const outerShadowXml = presetShadowXml ? void 0 : this.buildOuterShadowXml(shapeStyle);
|
|
30497
31750
|
const innerShadowXml = this.buildInnerShadowXml(shapeStyle);
|
|
30498
31751
|
const glowXml = this.buildGlowXml(shapeStyle);
|
|
30499
31752
|
const softEdgeXml = this.buildSoftEdgeXml(shapeStyle);
|
|
30500
31753
|
const reflectionXml = this.buildReflectionXml(shapeStyle);
|
|
30501
31754
|
const blurXml = this.buildBlurXml(shapeStyle);
|
|
30502
|
-
const hasAnyEffect = outerShadowXml || innerShadowXml || glowXml || softEdgeXml || reflectionXml || blurXml;
|
|
31755
|
+
const hasAnyEffect = outerShadowXml || presetShadowXml || innerShadowXml || glowXml || softEdgeXml || reflectionXml || blurXml;
|
|
30503
31756
|
if (hasAnyEffect) {
|
|
30504
31757
|
const effectList = spPr["a:effectLst"] || {};
|
|
30505
|
-
if (
|
|
31758
|
+
if (presetShadowXml) {
|
|
31759
|
+
effectList["a:prstShdw"] = presetShadowXml;
|
|
31760
|
+
delete effectList["a:outerShdw"];
|
|
31761
|
+
} else if (outerShadowXml) {
|
|
30506
31762
|
effectList["a:outerShdw"] = outerShadowXml;
|
|
31763
|
+
delete effectList["a:prstShdw"];
|
|
30507
31764
|
}
|
|
30508
31765
|
if (innerShadowXml) {
|
|
30509
31766
|
effectList["a:innerShdw"] = innerShadowXml;
|
|
@@ -30520,12 +31777,13 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
|
|
|
30520
31777
|
if (blurXml) {
|
|
30521
31778
|
effectList["a:blur"] = blurXml;
|
|
30522
31779
|
}
|
|
30523
|
-
spPr["a:effectLst"] = effectList;
|
|
31780
|
+
spPr["a:effectLst"] = reorderObjectKeys(effectList, EFFECT_LST_ORDER);
|
|
30524
31781
|
} else {
|
|
30525
31782
|
const effectList = spPr["a:effectLst"];
|
|
30526
31783
|
if (effectList) {
|
|
30527
|
-
if (shapeStyle.shadowColor !== void 0 && !outerShadowXml) {
|
|
31784
|
+
if (shapeStyle.shadowColor !== void 0 && !outerShadowXml && !presetShadowXml) {
|
|
30528
31785
|
delete effectList["a:outerShdw"];
|
|
31786
|
+
delete effectList["a:prstShdw"];
|
|
30529
31787
|
}
|
|
30530
31788
|
if (shapeStyle.innerShadowColor !== void 0 && !innerShadowXml) {
|
|
30531
31789
|
delete effectList["a:innerShdw"];
|
|
@@ -30544,6 +31802,8 @@ var PptxHandlerRuntime29 = class extends PptxHandlerRuntime28 {
|
|
|
30544
31802
|
}
|
|
30545
31803
|
if (Object.keys(effectList).length === 0) {
|
|
30546
31804
|
delete spPr["a:effectLst"];
|
|
31805
|
+
} else {
|
|
31806
|
+
spPr["a:effectLst"] = reorderObjectKeys(effectList, EFFECT_LST_ORDER);
|
|
30547
31807
|
}
|
|
30548
31808
|
}
|
|
30549
31809
|
}
|
|
@@ -30704,7 +31964,8 @@ var PptxHandlerRuntime30 = class _PptxHandlerRuntime extends PptxHandlerRuntime2
|
|
|
30704
31964
|
);
|
|
30705
31965
|
}
|
|
30706
31966
|
if (el.textStyle?.hOverflow) {
|
|
30707
|
-
bodyPr["@
|
|
31967
|
+
bodyPr["@_horzOverflow"] = el.textStyle.hOverflow;
|
|
31968
|
+
delete bodyPr["@_hOverflow"];
|
|
30708
31969
|
}
|
|
30709
31970
|
if (el.textStyle?.vertOverflow) {
|
|
30710
31971
|
bodyPr["@_vertOverflow"] = el.textStyle.vertOverflow;
|
|
@@ -30935,7 +32196,10 @@ var PptxHandlerRuntime31 = class extends PptxHandlerRuntime30 {
|
|
|
30935
32196
|
const elWithPaths = el;
|
|
30936
32197
|
if (elWithPaths.customGeometryPaths && elWithPaths.customGeometryPaths.length > 0) {
|
|
30937
32198
|
delete spPr["a:prstGeom"];
|
|
30938
|
-
spPr["a:custGeom"] = customGeometryPathsToXml(
|
|
32199
|
+
spPr["a:custGeom"] = customGeometryPathsToXml(
|
|
32200
|
+
elWithPaths.customGeometryPaths,
|
|
32201
|
+
elWithPaths.customGeometryRawData
|
|
32202
|
+
);
|
|
30939
32203
|
} else if (spPr["a:prstGeom"]) {
|
|
30940
32204
|
const presetGeometry = el.type === "connector" ? this.normalizePresetGeometry(el.shapeType || "straightConnector1") : this.normalizePresetGeometry(el.shapeType);
|
|
30941
32205
|
const prstGeom = spPr["a:prstGeom"];
|
|
@@ -31060,6 +32324,42 @@ var PptxHandlerRuntime32 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
31060
32324
|
isGraphicFrameShape(shape) {
|
|
31061
32325
|
return Boolean(shape["p:nvGraphicFramePr"] || shape["a:graphic"] && shape["p:xfrm"]);
|
|
31062
32326
|
}
|
|
32327
|
+
/**
|
|
32328
|
+
* Reorder children of `p:spPr` to match CT_ShapeProperties (§20.1.2.2.35).
|
|
32329
|
+
* Also reorders any nested `a:blipFill` per CT_BlipFillProperties.
|
|
32330
|
+
* fast-xml-parser preserves insertion order; PowerPoint validates against
|
|
32331
|
+
* the schema's required order, so save-side mutations must be re-sorted.
|
|
32332
|
+
*/
|
|
32333
|
+
finalizeSpPrSchemaOrder(shape) {
|
|
32334
|
+
const spPr = shape["p:spPr"];
|
|
32335
|
+
if (!spPr) {
|
|
32336
|
+
return;
|
|
32337
|
+
}
|
|
32338
|
+
const blipFill = spPr["a:blipFill"];
|
|
32339
|
+
if (blipFill) {
|
|
32340
|
+
this.reorderInPlace(blipFill, BLIP_FILL_ORDER);
|
|
32341
|
+
}
|
|
32342
|
+
this.reorderInPlace(spPr, SP_PR_ORDER);
|
|
32343
|
+
}
|
|
32344
|
+
/**
|
|
32345
|
+
* Reorder children of the picture-level `p:blipFill` (CT_BlipFillProperties).
|
|
32346
|
+
* Picture elements carry their blip data on the `p:pic` root, not under spPr.
|
|
32347
|
+
*/
|
|
32348
|
+
finalizePictureBlipFillOrder(shape) {
|
|
32349
|
+
const pBlipFill = shape["p:blipFill"];
|
|
32350
|
+
if (pBlipFill) {
|
|
32351
|
+
this.reorderInPlace(pBlipFill, BLIP_FILL_ORDER);
|
|
32352
|
+
}
|
|
32353
|
+
}
|
|
32354
|
+
reorderInPlace(target, schemaOrder) {
|
|
32355
|
+
const reordered = reorderObjectKeys(target, schemaOrder);
|
|
32356
|
+
for (const key of Object.keys(target)) {
|
|
32357
|
+
delete target[key];
|
|
32358
|
+
}
|
|
32359
|
+
for (const key of Object.keys(reordered)) {
|
|
32360
|
+
target[key] = reordered[key];
|
|
32361
|
+
}
|
|
32362
|
+
}
|
|
31063
32363
|
/** Whether an element ID indicates a template (layout/master) element. */
|
|
31064
32364
|
isTemplateElementId(elementId) {
|
|
31065
32365
|
return elementId.startsWith("layout-") || elementId.startsWith("master-");
|
|
@@ -31083,18 +32383,51 @@ var PptxHandlerRuntime32 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
31083
32383
|
}
|
|
31084
32384
|
return;
|
|
31085
32385
|
}
|
|
32386
|
+
if (el.type === "contentPart") {
|
|
32387
|
+
if (shape) {
|
|
32388
|
+
this.elementTransformUpdater.applyTransform(shape, el, _PptxHandlerRuntime.EMU_PER_PX);
|
|
32389
|
+
collectors.contentParts.push(shape);
|
|
32390
|
+
} else {
|
|
32391
|
+
this.compatibilityService.reportWarning({
|
|
32392
|
+
code: "SAVE_ELEMENT_SKIPPED",
|
|
32393
|
+
message: `Content part '${el.id}' has no rawXml and was skipped during save.`,
|
|
32394
|
+
scope: "save",
|
|
32395
|
+
slideId: ctx.slide.id,
|
|
32396
|
+
elementId: el.id
|
|
32397
|
+
});
|
|
32398
|
+
}
|
|
32399
|
+
return;
|
|
32400
|
+
}
|
|
31086
32401
|
if (!shape && (el.type === "text" || el.type === "shape")) {
|
|
31087
32402
|
shape = this.createElementXml(el);
|
|
31088
32403
|
}
|
|
31089
32404
|
if (!shape && el.type === "connector") {
|
|
31090
32405
|
shape = this.createConnectorXml(el);
|
|
31091
32406
|
}
|
|
31092
|
-
if (
|
|
31093
|
-
|
|
32407
|
+
if (el.type === "ink") {
|
|
32408
|
+
if (!shape) {
|
|
32409
|
+
shape = this.createInkShapeXml(el);
|
|
32410
|
+
this.compatibilityService.reportWarning({
|
|
32411
|
+
code: "SAVE_INK_ENCODED_AS_CUSTGEOM",
|
|
32412
|
+
message: "SDK-created ink element serialized as custGeom shape; pressure/tool metadata not represented in OOXML aink format.",
|
|
32413
|
+
scope: "save",
|
|
32414
|
+
slideId: ctx.slide.id,
|
|
32415
|
+
elementId: el.id
|
|
32416
|
+
});
|
|
32417
|
+
}
|
|
31094
32418
|
}
|
|
31095
32419
|
if (!shape && el.type === "table") {
|
|
31096
32420
|
shape = this.createTableGraphicFrameXml(el);
|
|
31097
32421
|
}
|
|
32422
|
+
if (el.type === "ole") {
|
|
32423
|
+
const oleEl = el;
|
|
32424
|
+
if (shape) {
|
|
32425
|
+
this.applyOleTypedFieldUpdates(shape, oleEl);
|
|
32426
|
+
} else {
|
|
32427
|
+
const embedRid = this.resolveOleEmbedRelationshipId(ctx.slideRelationships, oleEl.oleTarget) || ctx.slideRelationshipRegistry.nextRelationshipId();
|
|
32428
|
+
shape = this.createOleGraphicFrameXml(oleEl, embedRid);
|
|
32429
|
+
}
|
|
32430
|
+
}
|
|
31098
32431
|
if (!shape) {
|
|
31099
32432
|
this.compatibilityService.reportWarning({
|
|
31100
32433
|
code: "SAVE_ELEMENT_SKIPPED",
|
|
@@ -31107,11 +32440,14 @@ var PptxHandlerRuntime32 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
31107
32440
|
}
|
|
31108
32441
|
this.elementTransformUpdater.applyTransform(shape, el, _PptxHandlerRuntime.EMU_PER_PX);
|
|
31109
32442
|
this.applyImageProperties(shape, el);
|
|
32443
|
+
this.finalizePictureBlipFillOrder(shape);
|
|
31110
32444
|
this.applyGeometryUpdate(shape, el);
|
|
31111
32445
|
if (hasShapeProperties(el) && el.shapeStyle && shape["p:spPr"]) {
|
|
31112
32446
|
const spPr = shape["p:spPr"];
|
|
31113
32447
|
this.applyFillAndStroke(spPr, el.shapeStyle);
|
|
31114
32448
|
this.applyEffectsAndThreeD(spPr, el.shapeStyle);
|
|
32449
|
+
this.finalizeSpPrSchemaOrder(shape);
|
|
32450
|
+
this.applyShapeStyleRefs(shape, el.shapeStyle);
|
|
31115
32451
|
}
|
|
31116
32452
|
if (hasTextProperties(el)) {
|
|
31117
32453
|
this.applyTextBodyContent(
|
|
@@ -31269,7 +32605,8 @@ var PptxHandlerRuntime33 = class extends PptxHandlerRuntime32 {
|
|
|
31269
32605
|
connectors: [],
|
|
31270
32606
|
graphicFrames: [],
|
|
31271
32607
|
groups: [],
|
|
31272
|
-
model3ds: []
|
|
32608
|
+
model3ds: [],
|
|
32609
|
+
contentParts: []
|
|
31273
32610
|
};
|
|
31274
32611
|
const ctx = {
|
|
31275
32612
|
slide,
|
|
@@ -31301,6 +32638,12 @@ var PptxHandlerRuntime33 = class extends PptxHandlerRuntime32 {
|
|
|
31301
32638
|
} else {
|
|
31302
32639
|
delete spTree["p16:model3D"];
|
|
31303
32640
|
}
|
|
32641
|
+
if (collectors.contentParts.length > 0) {
|
|
32642
|
+
spTree["p:contentPart"] = collectors.contentParts;
|
|
32643
|
+
} else {
|
|
32644
|
+
delete spTree["p:contentPart"];
|
|
32645
|
+
}
|
|
32646
|
+
this.reapplyAlternateContentEnvelopes(spTree, collectors);
|
|
31304
32647
|
const reassigned = shapeIdValidator.validateAndDeduplicateIds(
|
|
31305
32648
|
spTree,
|
|
31306
32649
|
(v) => this.ensureArray(v)
|
|
@@ -31318,12 +32661,426 @@ var PptxHandlerRuntime33 = class extends PptxHandlerRuntime32 {
|
|
|
31318
32661
|
this.zip.file(slideRelsPath, this.builder.build(slideRelsData));
|
|
31319
32662
|
this.applySlideDrawingGuides(slideNode, slide);
|
|
31320
32663
|
this.deduplicateExtensionLists(xmlObj);
|
|
32664
|
+
if (slideContainsA16Element(slideNode)) {
|
|
32665
|
+
ensureA16NamespaceOnSlideRoot(slideNode);
|
|
32666
|
+
}
|
|
31321
32667
|
this.zip.file(slide.id, this.builder.build(xmlObj));
|
|
31322
32668
|
}
|
|
32669
|
+
/**
|
|
32670
|
+
* Re-wrap selected children with their original `<mc:AlternateContent>`
|
|
32671
|
+
* envelope (CC-4).
|
|
32672
|
+
*
|
|
32673
|
+
* Parsing merged the selected branch (Choice when supported, otherwise
|
|
32674
|
+
* Fallback) into the spTree's tag arrays. Without re-wrapping, dirty
|
|
32675
|
+
* save would emit flat `<p:sp>`/`<p:pic>` etc. and drop the
|
|
32676
|
+
* `<mc:Fallback>` branch — losing legacy rendering for files originally
|
|
32677
|
+
* authored with newer-namespace features.
|
|
32678
|
+
*
|
|
32679
|
+
* Strategy: for each XmlObject in `collectors.*` that traces back to a
|
|
32680
|
+
* known AC block, group by block and:
|
|
32681
|
+
* 1. Remove the node from its flat collector / spTree array.
|
|
32682
|
+
* 2. Clone the original AC envelope.
|
|
32683
|
+
* 3. Replace the selected branch's `<{tag}>` children with the
|
|
32684
|
+
* live (possibly edited) nodes from the collectors.
|
|
32685
|
+
* 4. Leave the unselected branch verbatim.
|
|
32686
|
+
*
|
|
32687
|
+
* Final envelopes are appended to `spTree['mc:AlternateContent']`.
|
|
32688
|
+
*/
|
|
32689
|
+
reapplyAlternateContentEnvelopes(spTree, collectors) {
|
|
32690
|
+
const TAG_TO_COLLECTOR = {
|
|
32691
|
+
"p:sp": collectors.shapes,
|
|
32692
|
+
"p:pic": collectors.pics,
|
|
32693
|
+
"p:cxnSp": collectors.connectors,
|
|
32694
|
+
"p:graphicFrame": collectors.graphicFrames,
|
|
32695
|
+
"p:grpSp": collectors.groups,
|
|
32696
|
+
"p:contentPart": collectors.contentParts,
|
|
32697
|
+
// `model3d` does not flow through SHAPE_TREE_ELEMENT_TAGS, but the
|
|
32698
|
+
// AC pathway in OpenXML decks frequently uses Choice = p16:model3D
|
|
32699
|
+
// + Fallback = p:pic, so map it for completeness.
|
|
32700
|
+
"p16:model3D": collectors.model3ds
|
|
32701
|
+
};
|
|
32702
|
+
const blockGroups = /* @__PURE__ */ new Map();
|
|
32703
|
+
for (const tag of Object.keys(TAG_TO_COLLECTOR)) {
|
|
32704
|
+
const collector = TAG_TO_COLLECTOR[tag];
|
|
32705
|
+
if (!collector) {
|
|
32706
|
+
continue;
|
|
32707
|
+
}
|
|
32708
|
+
for (const node of collector) {
|
|
32709
|
+
const block = this.alternateContentBlockByRawXml.get(node);
|
|
32710
|
+
if (!block) {
|
|
32711
|
+
continue;
|
|
32712
|
+
}
|
|
32713
|
+
let entries = blockGroups.get(block);
|
|
32714
|
+
if (!entries) {
|
|
32715
|
+
entries = [];
|
|
32716
|
+
blockGroups.set(block, entries);
|
|
32717
|
+
}
|
|
32718
|
+
entries.push({ tag, node, collector });
|
|
32719
|
+
}
|
|
32720
|
+
}
|
|
32721
|
+
if (blockGroups.size === 0) {
|
|
32722
|
+
return;
|
|
32723
|
+
}
|
|
32724
|
+
const envelopes = [];
|
|
32725
|
+
for (const [block, entries] of blockGroups) {
|
|
32726
|
+
for (const entry of entries) {
|
|
32727
|
+
const idx = entry.collector.indexOf(entry.node);
|
|
32728
|
+
if (idx !== -1) {
|
|
32729
|
+
entry.collector.splice(idx, 1);
|
|
32730
|
+
}
|
|
32731
|
+
}
|
|
32732
|
+
const clonedAc = { ...block.rawAc };
|
|
32733
|
+
const liveByTag = /* @__PURE__ */ new Map();
|
|
32734
|
+
for (const entry of entries) {
|
|
32735
|
+
let arr = liveByTag.get(entry.tag);
|
|
32736
|
+
if (!arr) {
|
|
32737
|
+
arr = [];
|
|
32738
|
+
liveByTag.set(entry.tag, arr);
|
|
32739
|
+
}
|
|
32740
|
+
arr.push(entry.node);
|
|
32741
|
+
}
|
|
32742
|
+
if (block.selectedBranch === "choice") {
|
|
32743
|
+
const choices = this.ensureArray(clonedAc["mc:Choice"]);
|
|
32744
|
+
const targetIdx = block.choiceIndex ?? 0;
|
|
32745
|
+
const original = choices[targetIdx];
|
|
32746
|
+
if (original) {
|
|
32747
|
+
const rebuilt = { ...original };
|
|
32748
|
+
for (const tag of SHAPE_TREE_ELEMENT_TAGS) {
|
|
32749
|
+
delete rebuilt[tag];
|
|
32750
|
+
}
|
|
32751
|
+
for (const [tag, nodes] of liveByTag) {
|
|
32752
|
+
rebuilt[tag] = nodes.length === 1 ? nodes[0] : nodes;
|
|
32753
|
+
}
|
|
32754
|
+
choices[targetIdx] = rebuilt;
|
|
32755
|
+
clonedAc["mc:Choice"] = choices.length === 1 ? choices[0] : choices;
|
|
32756
|
+
}
|
|
32757
|
+
} else {
|
|
32758
|
+
const fallback = clonedAc["mc:Fallback"];
|
|
32759
|
+
if (fallback) {
|
|
32760
|
+
const rebuilt = { ...fallback };
|
|
32761
|
+
for (const tag of SHAPE_TREE_ELEMENT_TAGS) {
|
|
32762
|
+
delete rebuilt[tag];
|
|
32763
|
+
}
|
|
32764
|
+
for (const [tag, nodes] of liveByTag) {
|
|
32765
|
+
rebuilt[tag] = nodes.length === 1 ? nodes[0] : nodes;
|
|
32766
|
+
}
|
|
32767
|
+
clonedAc["mc:Fallback"] = rebuilt;
|
|
32768
|
+
}
|
|
32769
|
+
}
|
|
32770
|
+
envelopes.push(clonedAc);
|
|
32771
|
+
}
|
|
32772
|
+
spTree["p:sp"] = collectors.shapes;
|
|
32773
|
+
spTree["p:pic"] = collectors.pics;
|
|
32774
|
+
spTree["p:cxnSp"] = collectors.connectors;
|
|
32775
|
+
spTree["p:graphicFrame"] = collectors.graphicFrames;
|
|
32776
|
+
if (collectors.groups.length > 0) {
|
|
32777
|
+
spTree["p:grpSp"] = collectors.groups;
|
|
32778
|
+
} else {
|
|
32779
|
+
delete spTree["p:grpSp"];
|
|
32780
|
+
}
|
|
32781
|
+
if (collectors.contentParts.length > 0) {
|
|
32782
|
+
spTree["p:contentPart"] = collectors.contentParts;
|
|
32783
|
+
} else {
|
|
32784
|
+
delete spTree["p:contentPart"];
|
|
32785
|
+
}
|
|
32786
|
+
if (collectors.model3ds.length > 0) {
|
|
32787
|
+
spTree["p16:model3D"] = collectors.model3ds;
|
|
32788
|
+
} else {
|
|
32789
|
+
delete spTree["p16:model3D"];
|
|
32790
|
+
}
|
|
32791
|
+
spTree["mc:AlternateContent"] = envelopes.length === 1 ? envelopes[0] : envelopes;
|
|
32792
|
+
}
|
|
32793
|
+
};
|
|
32794
|
+
|
|
32795
|
+
// src/core/core/runtime/PptxHandlerRuntimeSaveTheme.ts
|
|
32796
|
+
var PptxHandlerRuntime34 = class extends PptxHandlerRuntime33 {
|
|
32797
|
+
/**
|
|
32798
|
+
* Mark a theme path as dirty so the save pipeline will regenerate
|
|
32799
|
+
* the theme XML from in-memory state. Optional — without this the
|
|
32800
|
+
* original XML is preserved verbatim on save (C-H3).
|
|
32801
|
+
*/
|
|
32802
|
+
markThemeDirty(themePath) {
|
|
32803
|
+
this.dirtyThemePaths.add(themePath);
|
|
32804
|
+
}
|
|
32805
|
+
/**
|
|
32806
|
+
* Mark all known theme paths dirty in one call.
|
|
32807
|
+
*/
|
|
32808
|
+
markAllThemesDirty() {
|
|
32809
|
+
for (const themePath of this.originalThemeXmlByPath.keys()) {
|
|
32810
|
+
this.dirtyThemePaths.add(themePath);
|
|
32811
|
+
}
|
|
32812
|
+
for (const themePath of this.masterThemePaths.values()) {
|
|
32813
|
+
this.dirtyThemePaths.add(themePath);
|
|
32814
|
+
}
|
|
32815
|
+
}
|
|
32816
|
+
/**
|
|
32817
|
+
* Persist all theme parts during save. Called from the save pipeline
|
|
32818
|
+
* after master / layout XML have been flushed and before
|
|
32819
|
+
* presentation.xml is serialized.
|
|
32820
|
+
*
|
|
32821
|
+
* Order of operations per theme path:
|
|
32822
|
+
*
|
|
32823
|
+
* 1. If the path is *not* in {@link dirtyThemePaths}, the existing
|
|
32824
|
+
* ZIP entry is already correct — no-op. (Original XML was placed
|
|
32825
|
+
* into the ZIP at load time.)
|
|
32826
|
+
* 2. If the path is dirty, build a fresh `<a:theme>` document from
|
|
32827
|
+
* in-memory state and the captured raw subtrees, then overwrite
|
|
32828
|
+
* the ZIP entry.
|
|
32829
|
+
*/
|
|
32830
|
+
async persistThemeParts() {
|
|
32831
|
+
const seenThemePaths = /* @__PURE__ */ new Set();
|
|
32832
|
+
for (const [masterPath, themePath] of this.masterThemePaths.entries()) {
|
|
32833
|
+
if (!themePath) {
|
|
32834
|
+
continue;
|
|
32835
|
+
}
|
|
32836
|
+
seenThemePaths.add(themePath);
|
|
32837
|
+
if (!this.dirtyThemePaths.has(themePath)) {
|
|
32838
|
+
continue;
|
|
32839
|
+
}
|
|
32840
|
+
const themeXml2 = this.buildThemeXml(themePath, masterPath);
|
|
32841
|
+
if (themeXml2) {
|
|
32842
|
+
this.zip.file(themePath, themeXml2);
|
|
32843
|
+
}
|
|
32844
|
+
}
|
|
32845
|
+
for (const [themePath] of this.originalThemeXmlByPath.entries()) {
|
|
32846
|
+
if (seenThemePaths.has(themePath)) {
|
|
32847
|
+
continue;
|
|
32848
|
+
}
|
|
32849
|
+
if (!this.dirtyThemePaths.has(themePath)) {
|
|
32850
|
+
continue;
|
|
32851
|
+
}
|
|
32852
|
+
const themeXml2 = this.buildThemeXml(themePath, void 0);
|
|
32853
|
+
if (themeXml2) {
|
|
32854
|
+
this.zip.file(themePath, themeXml2);
|
|
32855
|
+
}
|
|
32856
|
+
}
|
|
32857
|
+
}
|
|
32858
|
+
/**
|
|
32859
|
+
* Build a complete `<a:theme>` XML document from in-memory state.
|
|
32860
|
+
* Returns the serialized XML string (with XML prolog), or `undefined`
|
|
32861
|
+
* if there is no source data to emit.
|
|
32862
|
+
*
|
|
32863
|
+
* - Color scheme: built from per-master color map (or global fallback).
|
|
32864
|
+
* - Font scheme: built from per-master font map + per-script entries.
|
|
32865
|
+
* - Format scheme: re-emit the original XML subtree if available; else
|
|
32866
|
+
* build a minimal scheme from {@link themeFormatScheme}.
|
|
32867
|
+
* - objectDefaults / extraClrSchemeLst / custClrLst / extLst: re-emit
|
|
32868
|
+
* captured raw subtrees.
|
|
32869
|
+
*/
|
|
32870
|
+
buildThemeXml(themePath, masterPath) {
|
|
32871
|
+
const colorMap = masterPath && this.masterThemeColorMaps.get(masterPath) || this.globalThemeColorMapSnapshot || this.themeColorMap;
|
|
32872
|
+
const fontMap = masterPath && this.masterThemeFontMaps.get(masterPath) || this.globalThemeFontMapSnapshot || this.themeFontMap;
|
|
32873
|
+
const themeName = this.masterThemeNames.get(themePath) || "Office Theme";
|
|
32874
|
+
const colorSchemeName = this.masterThemeColorSchemeNames.get(themePath) || themeName;
|
|
32875
|
+
const fontSchemeName = this.masterThemeFontSchemeNames.get(themePath) || themeName;
|
|
32876
|
+
const majorScripts = this.masterThemeMajorFontScripts.get(themePath) || {};
|
|
32877
|
+
const minorScripts = this.masterThemeMinorFontScripts.get(themePath) || {};
|
|
32878
|
+
const clrScheme = this.buildClrSchemeObject(colorSchemeName, colorMap);
|
|
32879
|
+
const fontScheme = this.buildFontSchemeObject(
|
|
32880
|
+
fontSchemeName,
|
|
32881
|
+
fontMap,
|
|
32882
|
+
majorScripts,
|
|
32883
|
+
minorScripts
|
|
32884
|
+
);
|
|
32885
|
+
const fmtScheme = this.extractRawSubtreeFromOriginal(themePath, [
|
|
32886
|
+
"a:theme",
|
|
32887
|
+
"a:themeElements",
|
|
32888
|
+
"a:fmtScheme"
|
|
32889
|
+
]);
|
|
32890
|
+
const themeElements = {
|
|
32891
|
+
"a:clrScheme": clrScheme,
|
|
32892
|
+
"a:fontScheme": fontScheme
|
|
32893
|
+
};
|
|
32894
|
+
if (fmtScheme !== void 0) {
|
|
32895
|
+
themeElements["a:fmtScheme"] = fmtScheme;
|
|
32896
|
+
} else {
|
|
32897
|
+
themeElements["a:fmtScheme"] = this.buildMinimalFmtScheme(themeName);
|
|
32898
|
+
}
|
|
32899
|
+
const themeRoot = {
|
|
32900
|
+
"@_xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
|
|
32901
|
+
"@_name": themeName,
|
|
32902
|
+
"a:themeElements": themeElements
|
|
32903
|
+
};
|
|
32904
|
+
const objectDefaults = this.masterThemeObjectDefaults.get(themePath);
|
|
32905
|
+
if (objectDefaults && (objectDefaults.spDef || objectDefaults.lnDef || objectDefaults.txDef)) {
|
|
32906
|
+
const od = {};
|
|
32907
|
+
if (objectDefaults.spDef !== void 0) {
|
|
32908
|
+
od["a:spDef"] = objectDefaults.spDef;
|
|
32909
|
+
}
|
|
32910
|
+
if (objectDefaults.lnDef !== void 0) {
|
|
32911
|
+
od["a:lnDef"] = objectDefaults.lnDef;
|
|
32912
|
+
}
|
|
32913
|
+
if (objectDefaults.txDef !== void 0) {
|
|
32914
|
+
od["a:txDef"] = objectDefaults.txDef;
|
|
32915
|
+
}
|
|
32916
|
+
themeRoot["a:objectDefaults"] = od;
|
|
32917
|
+
} else {
|
|
32918
|
+
themeRoot["a:objectDefaults"] = {};
|
|
32919
|
+
}
|
|
32920
|
+
const extraClr = this.masterThemeExtraClrSchemeLst.get(themePath);
|
|
32921
|
+
themeRoot["a:extraClrSchemeLst"] = extraClr !== void 0 ? extraClr : {};
|
|
32922
|
+
const custClr = this.masterThemeCustClrLst.get(themePath);
|
|
32923
|
+
if (custClr !== void 0) {
|
|
32924
|
+
themeRoot["a:custClrLst"] = custClr;
|
|
32925
|
+
}
|
|
32926
|
+
const themeExt = this.masterThemeExtLst.get(themePath);
|
|
32927
|
+
if (themeExt !== void 0) {
|
|
32928
|
+
themeRoot["a:extLst"] = themeExt;
|
|
32929
|
+
}
|
|
32930
|
+
const doc = {
|
|
32931
|
+
"?xml": { "@_version": "1.0", "@_encoding": "UTF-8", "@_standalone": "yes" },
|
|
32932
|
+
"a:theme": themeRoot
|
|
32933
|
+
};
|
|
32934
|
+
try {
|
|
32935
|
+
return this.builder.build(doc);
|
|
32936
|
+
} catch (error) {
|
|
32937
|
+
console.warn(`Failed to build theme XML for ${themePath}:`, error);
|
|
32938
|
+
return void 0;
|
|
32939
|
+
}
|
|
32940
|
+
}
|
|
32941
|
+
/**
|
|
32942
|
+
* Build the `a:clrScheme` XmlObject from a colour map. Each slot
|
|
32943
|
+
* value is interpreted as either a `#RRGGBB` srgb hex or a known
|
|
32944
|
+
* sysClr token (currently always emitted as srgbClr — the in-memory
|
|
32945
|
+
* map is hex-typed; sysClr round-trip belongs to the broader C-H3
|
|
32946
|
+
* fix to preserve original color XML and is out of scope here).
|
|
32947
|
+
*/
|
|
32948
|
+
buildClrSchemeObject(schemeName, colorMap) {
|
|
32949
|
+
const slot = (key) => {
|
|
32950
|
+
const hex = String(colorMap[key] || "").replace(/^#/, "");
|
|
32951
|
+
const srgb = hex.length === 6 ? hex.toUpperCase() : "000000";
|
|
32952
|
+
return { "a:srgbClr": { "@_val": srgb } };
|
|
32953
|
+
};
|
|
32954
|
+
return {
|
|
32955
|
+
"@_name": schemeName,
|
|
32956
|
+
"a:dk1": slot("dk1"),
|
|
32957
|
+
"a:lt1": slot("lt1"),
|
|
32958
|
+
"a:dk2": slot("dk2"),
|
|
32959
|
+
"a:lt2": slot("lt2"),
|
|
32960
|
+
"a:accent1": slot("accent1"),
|
|
32961
|
+
"a:accent2": slot("accent2"),
|
|
32962
|
+
"a:accent3": slot("accent3"),
|
|
32963
|
+
"a:accent4": slot("accent4"),
|
|
32964
|
+
"a:accent5": slot("accent5"),
|
|
32965
|
+
"a:accent6": slot("accent6"),
|
|
32966
|
+
"a:hlink": slot("hlink"),
|
|
32967
|
+
"a:folHlink": slot("folHlink")
|
|
32968
|
+
};
|
|
32969
|
+
}
|
|
32970
|
+
/**
|
|
32971
|
+
* Build the `a:fontScheme` XmlObject from a font map plus per-script
|
|
32972
|
+
* font tables.
|
|
32973
|
+
*
|
|
32974
|
+
* Phase 4 Stream A / M4.
|
|
32975
|
+
*/
|
|
32976
|
+
buildFontSchemeObject(schemeName, fontMap, majorScripts, minorScripts) {
|
|
32977
|
+
const buildFontGroup = (latinKey, eaKey, csKey, scripts) => {
|
|
32978
|
+
const group = {
|
|
32979
|
+
"a:latin": { "@_typeface": fontMap[latinKey] || "Calibri" },
|
|
32980
|
+
"a:ea": { "@_typeface": fontMap[eaKey] || "" },
|
|
32981
|
+
"a:cs": { "@_typeface": fontMap[csKey] || "" }
|
|
32982
|
+
};
|
|
32983
|
+
const scriptKeys = Object.keys(scripts);
|
|
32984
|
+
if (scriptKeys.length > 0) {
|
|
32985
|
+
const fontEntries = scriptKeys.map((script) => ({
|
|
32986
|
+
"@_script": script,
|
|
32987
|
+
"@_typeface": scripts[script]
|
|
32988
|
+
}));
|
|
32989
|
+
group["a:font"] = fontEntries.length === 1 ? fontEntries[0] : fontEntries;
|
|
32990
|
+
}
|
|
32991
|
+
return group;
|
|
32992
|
+
};
|
|
32993
|
+
return {
|
|
32994
|
+
"@_name": schemeName,
|
|
32995
|
+
"a:majorFont": buildFontGroup("mj-lt", "mj-ea", "mj-cs", majorScripts),
|
|
32996
|
+
"a:minorFont": buildFontGroup("mn-lt", "mn-ea", "mn-cs", minorScripts)
|
|
32997
|
+
};
|
|
32998
|
+
}
|
|
32999
|
+
/**
|
|
33000
|
+
* Re-parse the original theme XML and pluck out a subtree by path,
|
|
33001
|
+
* returning the raw parser object. Returns `undefined` when the
|
|
33002
|
+
* original is missing or the path doesn't exist.
|
|
33003
|
+
*
|
|
33004
|
+
* Used to preserve `a:fmtScheme` byte-for-byte through a regenerate
|
|
33005
|
+
* round-trip, since the in-memory PptxThemeFormatScheme is lossy.
|
|
33006
|
+
*/
|
|
33007
|
+
extractRawSubtreeFromOriginal(themePath, path2) {
|
|
33008
|
+
const original = this.originalThemeXmlByPath.get(themePath);
|
|
33009
|
+
if (!original) {
|
|
33010
|
+
return void 0;
|
|
33011
|
+
}
|
|
33012
|
+
try {
|
|
33013
|
+
const parsed = this.parser.parse(original);
|
|
33014
|
+
let cursor = parsed;
|
|
33015
|
+
for (const segment of path2) {
|
|
33016
|
+
if (cursor && typeof cursor === "object" && segment in cursor) {
|
|
33017
|
+
cursor = cursor[segment];
|
|
33018
|
+
} else {
|
|
33019
|
+
return void 0;
|
|
33020
|
+
}
|
|
33021
|
+
}
|
|
33022
|
+
return cursor;
|
|
33023
|
+
} catch {
|
|
33024
|
+
return void 0;
|
|
33025
|
+
}
|
|
33026
|
+
}
|
|
33027
|
+
/**
|
|
33028
|
+
* Last-resort minimal `<a:fmtScheme>` body. Mirrors the SDK new-deck
|
|
33029
|
+
* builder's output for new presentations, scaled down to the smallest
|
|
33030
|
+
* schema-valid form.
|
|
33031
|
+
*/
|
|
33032
|
+
buildMinimalFmtScheme(name) {
|
|
33033
|
+
const phClrSolid = { "a:solidFill": { "a:schemeClr": { "@_val": "phClr" } } };
|
|
33034
|
+
return {
|
|
33035
|
+
"@_name": name,
|
|
33036
|
+
"a:fillStyleLst": {
|
|
33037
|
+
"a:solidFill": [{ "a:schemeClr": { "@_val": "phClr" } }],
|
|
33038
|
+
"a:gradFill": []
|
|
33039
|
+
},
|
|
33040
|
+
"a:lnStyleLst": {
|
|
33041
|
+
"a:ln": [
|
|
33042
|
+
{
|
|
33043
|
+
"@_w": "6350",
|
|
33044
|
+
"@_cap": "flat",
|
|
33045
|
+
"@_cmpd": "sng",
|
|
33046
|
+
"@_algn": "ctr",
|
|
33047
|
+
...phClrSolid,
|
|
33048
|
+
"a:prstDash": { "@_val": "solid" },
|
|
33049
|
+
"a:miter": { "@_lim": "800000" }
|
|
33050
|
+
},
|
|
33051
|
+
{
|
|
33052
|
+
"@_w": "12700",
|
|
33053
|
+
"@_cap": "flat",
|
|
33054
|
+
"@_cmpd": "sng",
|
|
33055
|
+
"@_algn": "ctr",
|
|
33056
|
+
...phClrSolid,
|
|
33057
|
+
"a:prstDash": { "@_val": "solid" },
|
|
33058
|
+
"a:miter": { "@_lim": "800000" }
|
|
33059
|
+
},
|
|
33060
|
+
{
|
|
33061
|
+
"@_w": "19050",
|
|
33062
|
+
"@_cap": "flat",
|
|
33063
|
+
"@_cmpd": "sng",
|
|
33064
|
+
"@_algn": "ctr",
|
|
33065
|
+
...phClrSolid,
|
|
33066
|
+
"a:prstDash": { "@_val": "solid" },
|
|
33067
|
+
"a:miter": { "@_lim": "800000" }
|
|
33068
|
+
}
|
|
33069
|
+
]
|
|
33070
|
+
},
|
|
33071
|
+
"a:effectStyleLst": {
|
|
33072
|
+
"a:effectStyle": [{ "a:effectLst": {} }, { "a:effectLst": {} }, { "a:effectLst": {} }]
|
|
33073
|
+
},
|
|
33074
|
+
"a:bgFillStyleLst": {
|
|
33075
|
+
"a:solidFill": [{ "a:schemeClr": { "@_val": "phClr" } }],
|
|
33076
|
+
"a:gradFill": []
|
|
33077
|
+
}
|
|
33078
|
+
};
|
|
33079
|
+
}
|
|
31323
33080
|
};
|
|
31324
33081
|
|
|
31325
33082
|
// src/core/core/runtime/PptxHandlerRuntimeSavePipeline.ts
|
|
31326
|
-
var
|
|
33083
|
+
var PptxHandlerRuntime35 = class _PptxHandlerRuntime extends PptxHandlerRuntime34 {
|
|
31327
33084
|
/**
|
|
31328
33085
|
* Resolve the effective conformance class for this save operation.
|
|
31329
33086
|
*
|
|
@@ -31410,6 +33167,7 @@ var PptxHandlerRuntime34 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
31410
33167
|
for (const [masterPath, masterXmlObj] of this.masterXmlMap.entries()) {
|
|
31411
33168
|
this.zip.file(masterPath, this.builder.build(masterXmlObj));
|
|
31412
33169
|
}
|
|
33170
|
+
await this.persistThemeParts();
|
|
31413
33171
|
await this.applyEmbeddedFontPreservation(options?.embeddedFonts);
|
|
31414
33172
|
if (this.presentationData) {
|
|
31415
33173
|
this.presentationSaveBuilder.applySaveOptions({
|
|
@@ -31499,7 +33257,7 @@ var PptxHandlerRuntime34 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
31499
33257
|
};
|
|
31500
33258
|
|
|
31501
33259
|
// src/core/core/runtime/PptxHandlerRuntimeElementParsing.ts
|
|
31502
|
-
var
|
|
33260
|
+
var PptxHandlerRuntime36 = class _PptxHandlerRuntime extends PptxHandlerRuntime35 {
|
|
31503
33261
|
/**
|
|
31504
33262
|
* Parse media data (video/audio path and MIME type) from graphic frame data.
|
|
31505
33263
|
*/
|
|
@@ -31721,7 +33479,7 @@ var PptxHandlerRuntime35 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
31721
33479
|
};
|
|
31722
33480
|
|
|
31723
33481
|
// src/core/core/runtime/PptxHandlerRuntimePlaceholderLookup.ts
|
|
31724
|
-
var
|
|
33482
|
+
var PptxHandlerRuntime37 = class extends PptxHandlerRuntime36 {
|
|
31725
33483
|
findPlaceholderInShapeTree(spTree, expected) {
|
|
31726
33484
|
if (!spTree) {
|
|
31727
33485
|
return void 0;
|
|
@@ -31874,7 +33632,7 @@ var PptxHandlerRuntime36 = class extends PptxHandlerRuntime35 {
|
|
|
31874
33632
|
};
|
|
31875
33633
|
|
|
31876
33634
|
// src/core/core/runtime/PptxHandlerRuntimeGeometryParsing.ts
|
|
31877
|
-
var
|
|
33635
|
+
var PptxHandlerRuntime38 = class extends PptxHandlerRuntime37 {
|
|
31878
33636
|
parseGeometryAdjustments(prstGeom) {
|
|
31879
33637
|
if (!prstGeom) {
|
|
31880
33638
|
return void 0;
|
|
@@ -31983,6 +33741,103 @@ var PptxHandlerRuntime37 = class extends PptxHandlerRuntime36 {
|
|
|
31983
33741
|
}
|
|
31984
33742
|
return handles.length > 0 ? handles : void 0;
|
|
31985
33743
|
}
|
|
33744
|
+
/**
|
|
33745
|
+
* Extract `a:gdLst`/`a:ahLst`/`a:cxnLst`/`a:rect` raw XML from a `a:custGeom`
|
|
33746
|
+
* node so they can be re-emitted on save when the geometry is edited.
|
|
33747
|
+
* Returns `undefined` when none of these auxiliary children carry data.
|
|
33748
|
+
*/
|
|
33749
|
+
extractCustomGeometryRawData(custGeom) {
|
|
33750
|
+
if (!custGeom) {
|
|
33751
|
+
return void 0;
|
|
33752
|
+
}
|
|
33753
|
+
const isNonEmpty = (node) => {
|
|
33754
|
+
if (node === void 0 || node === null) {
|
|
33755
|
+
return false;
|
|
33756
|
+
}
|
|
33757
|
+
if (typeof node !== "object") {
|
|
33758
|
+
return true;
|
|
33759
|
+
}
|
|
33760
|
+
return Object.keys(node).length > 0;
|
|
33761
|
+
};
|
|
33762
|
+
const result = {};
|
|
33763
|
+
const gdLst = custGeom["a:gdLst"];
|
|
33764
|
+
if (isNonEmpty(gdLst)) {
|
|
33765
|
+
result.gdLstXml = gdLst;
|
|
33766
|
+
}
|
|
33767
|
+
const ahLst = custGeom["a:ahLst"];
|
|
33768
|
+
if (isNonEmpty(ahLst)) {
|
|
33769
|
+
result.ahLstXml = ahLst;
|
|
33770
|
+
}
|
|
33771
|
+
const cxnLst = custGeom["a:cxnLst"];
|
|
33772
|
+
if (isNonEmpty(cxnLst)) {
|
|
33773
|
+
result.cxnLstXml = cxnLst;
|
|
33774
|
+
}
|
|
33775
|
+
const rect = custGeom["a:rect"];
|
|
33776
|
+
if (isNonEmpty(rect)) {
|
|
33777
|
+
result.rectXml = rect;
|
|
33778
|
+
}
|
|
33779
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
33780
|
+
}
|
|
33781
|
+
/**
|
|
33782
|
+
* Build structured `CustomGeometryPath[]` from a parsed `a:custGeom` node,
|
|
33783
|
+
* including per-path `@fill`/`@stroke`/`@extrusionOk` attributes so they
|
|
33784
|
+
* survive a round-trip when the path list is later regenerated.
|
|
33785
|
+
*
|
|
33786
|
+
* Falls back to SVG → structured-path conversion when no structured path
|
|
33787
|
+
* info is otherwise available.
|
|
33788
|
+
*/
|
|
33789
|
+
buildStructuredCustomGeometryPaths(custGeom, pathData, pathWidth, pathHeight) {
|
|
33790
|
+
if (!custGeom) {
|
|
33791
|
+
return void 0;
|
|
33792
|
+
}
|
|
33793
|
+
const pathLst = custGeom["a:pathLst"];
|
|
33794
|
+
if (!pathLst) {
|
|
33795
|
+
return void 0;
|
|
33796
|
+
}
|
|
33797
|
+
const pathNodes = this.ensureArray(pathLst["a:path"]);
|
|
33798
|
+
if (pathNodes.length === 0) {
|
|
33799
|
+
return void 0;
|
|
33800
|
+
}
|
|
33801
|
+
const segments = svgToCustomGeometryPaths(pathData, pathWidth, pathHeight);
|
|
33802
|
+
if (segments.length === 0) {
|
|
33803
|
+
return void 0;
|
|
33804
|
+
}
|
|
33805
|
+
const validFillModes = /* @__PURE__ */ new Set([
|
|
33806
|
+
"norm",
|
|
33807
|
+
"lighten",
|
|
33808
|
+
"lightenLess",
|
|
33809
|
+
"darken",
|
|
33810
|
+
"darkenLess",
|
|
33811
|
+
"none"
|
|
33812
|
+
]);
|
|
33813
|
+
const parseBoolAttr2 = (value) => {
|
|
33814
|
+
if (value === void 0 || value === null || value === "") {
|
|
33815
|
+
return void 0;
|
|
33816
|
+
}
|
|
33817
|
+
if (value === "1" || value === "true" || value === true) {
|
|
33818
|
+
return true;
|
|
33819
|
+
}
|
|
33820
|
+
if (value === "0" || value === "false" || value === false) {
|
|
33821
|
+
return false;
|
|
33822
|
+
}
|
|
33823
|
+
return void 0;
|
|
33824
|
+
};
|
|
33825
|
+
const target = segments[0];
|
|
33826
|
+
const firstNode = pathNodes[0];
|
|
33827
|
+
const fillAttr = String(firstNode["@_fill"] ?? "").trim();
|
|
33828
|
+
if (validFillModes.has(fillAttr)) {
|
|
33829
|
+
target.fillMode = fillAttr;
|
|
33830
|
+
}
|
|
33831
|
+
const strokeAttr = parseBoolAttr2(firstNode["@_stroke"]);
|
|
33832
|
+
if (strokeAttr !== void 0) {
|
|
33833
|
+
target.stroke = strokeAttr;
|
|
33834
|
+
}
|
|
33835
|
+
const extrusionAttr = parseBoolAttr2(firstNode["@_extrusionOk"]);
|
|
33836
|
+
if (extrusionAttr !== void 0) {
|
|
33837
|
+
target.extrusionOk = extrusionAttr;
|
|
33838
|
+
}
|
|
33839
|
+
return segments;
|
|
33840
|
+
}
|
|
31986
33841
|
parseCustomGeometry(custGeom, shapeWidth, shapeHeight) {
|
|
31987
33842
|
if (!custGeom || !custGeom["a:pathLst"] || !custGeom["a:pathLst"]?.["a:path"]) {
|
|
31988
33843
|
return null;
|
|
@@ -32051,7 +33906,7 @@ var PptxHandlerRuntime37 = class extends PptxHandlerRuntime36 {
|
|
|
32051
33906
|
};
|
|
32052
33907
|
|
|
32053
33908
|
// src/core/core/runtime/PptxHandlerRuntimeShapeImageFill.ts
|
|
32054
|
-
var
|
|
33909
|
+
var PptxHandlerRuntime39 = class _PptxHandlerRuntime extends PptxHandlerRuntime38 {
|
|
32055
33910
|
/**
|
|
32056
33911
|
* Parse a shape that has an image fill (a:blipFill inside spPr)
|
|
32057
33912
|
* This handles shapes like rectangles filled with images (e.g., wood texture backgrounds)
|
|
@@ -32251,7 +34106,7 @@ var PptxHandlerRuntime38 = class _PptxHandlerRuntime extends PptxHandlerRuntime3
|
|
|
32251
34106
|
};
|
|
32252
34107
|
|
|
32253
34108
|
// src/core/core/runtime/PptxHandlerRuntimeTextDefaults.ts
|
|
32254
|
-
var
|
|
34109
|
+
var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
32255
34110
|
/**
|
|
32256
34111
|
* Apply {@link PlaceholderDefaults} body-level properties to a
|
|
32257
34112
|
* {@link TextStyle} as fallback values (only sets fields that are
|
|
@@ -32375,7 +34230,7 @@ var PptxHandlerRuntime39 = class extends PptxHandlerRuntime38 {
|
|
|
32375
34230
|
};
|
|
32376
34231
|
|
|
32377
34232
|
// src/core/core/runtime/PptxHandlerRuntimeBulletParsing.ts
|
|
32378
|
-
var
|
|
34233
|
+
var PptxHandlerRuntime41 = class extends PptxHandlerRuntime40 {
|
|
32379
34234
|
resolveParagraphBulletInfo(paragraph, paragraphIndex, txBody, inheritedTxBody, isBodyPlaceholder = false, slidePath) {
|
|
32380
34235
|
if (!paragraph) {
|
|
32381
34236
|
return null;
|
|
@@ -32406,7 +34261,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32406
34261
|
if (candidate["a:buNone"]) {
|
|
32407
34262
|
return { none: true };
|
|
32408
34263
|
}
|
|
32409
|
-
if (candidate["a:buChar"] || candidate["a:buAutoNum"] || candidate["a:buBlip"]) {
|
|
34264
|
+
if (candidate["a:buChar"] || candidate["a:buAutoNum"] || candidate["a:buBlip"] || candidate["a:buFontTx"] !== void 0 || candidate["a:buClrTx"] !== void 0 || candidate["a:buSzTx"] !== void 0) {
|
|
32410
34265
|
resolvedBulletProps = candidate;
|
|
32411
34266
|
break;
|
|
32412
34267
|
}
|
|
@@ -32420,6 +34275,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32420
34275
|
}
|
|
32421
34276
|
const buFont = resolvedBulletProps["a:buFont"];
|
|
32422
34277
|
const fontFamily = buFont?.["@_typeface"] ? String(buFont["@_typeface"]) : void 0;
|
|
34278
|
+
const fontInherit = resolvedBulletProps["a:buFontTx"] !== void 0;
|
|
32423
34279
|
const buSzPct = resolvedBulletProps["a:buSzPct"];
|
|
32424
34280
|
let sizePercent;
|
|
32425
34281
|
if (buSzPct?.["@_val"] !== void 0) {
|
|
@@ -32436,6 +34292,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32436
34292
|
sizePts = ptsRaw / 100;
|
|
32437
34293
|
}
|
|
32438
34294
|
}
|
|
34295
|
+
const sizeInherit = resolvedBulletProps["a:buSzTx"] !== void 0;
|
|
32439
34296
|
const buClr = resolvedBulletProps["a:buClr"];
|
|
32440
34297
|
let color;
|
|
32441
34298
|
if (buClr) {
|
|
@@ -32444,6 +34301,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32444
34301
|
color = String(srgb["@_val"]);
|
|
32445
34302
|
}
|
|
32446
34303
|
}
|
|
34304
|
+
const colorInherit = resolvedBulletProps["a:buClrTx"] !== void 0;
|
|
32447
34305
|
const bulletChar = String(
|
|
32448
34306
|
resolvedBulletProps["a:buChar"]?.["@_char"] || ""
|
|
32449
34307
|
);
|
|
@@ -32453,7 +34311,10 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32453
34311
|
fontFamily,
|
|
32454
34312
|
sizePercent,
|
|
32455
34313
|
sizePts,
|
|
32456
|
-
color
|
|
34314
|
+
color,
|
|
34315
|
+
...fontInherit ? { fontInherit: true } : {},
|
|
34316
|
+
...colorInherit ? { colorInherit: true } : {},
|
|
34317
|
+
...sizeInherit ? { sizeInherit: true } : {}
|
|
32457
34318
|
};
|
|
32458
34319
|
}
|
|
32459
34320
|
const autoNum = resolvedBulletProps["a:buAutoNum"];
|
|
@@ -32468,7 +34329,10 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32468
34329
|
fontFamily,
|
|
32469
34330
|
sizePercent,
|
|
32470
34331
|
sizePts,
|
|
32471
|
-
color
|
|
34332
|
+
color,
|
|
34333
|
+
...fontInherit ? { fontInherit: true } : {},
|
|
34334
|
+
...colorInherit ? { colorInherit: true } : {},
|
|
34335
|
+
...sizeInherit ? { sizeInherit: true } : {}
|
|
32472
34336
|
};
|
|
32473
34337
|
}
|
|
32474
34338
|
const buBlip = resolvedBulletProps["a:buBlip"];
|
|
@@ -32580,7 +34444,7 @@ var PptxHandlerRuntime40 = class extends PptxHandlerRuntime39 {
|
|
|
32580
34444
|
};
|
|
32581
34445
|
|
|
32582
34446
|
// src/core/core/runtime/PptxHandlerRuntimeShapeBodyParsing.ts
|
|
32583
|
-
var
|
|
34447
|
+
var PptxHandlerRuntime42 = class _PptxHandlerRuntime extends PptxHandlerRuntime41 {
|
|
32584
34448
|
/**
|
|
32585
34449
|
* Parse `a:spLocks` attributes into a structured {@link PptxShapeLocks} object.
|
|
32586
34450
|
* Returns `undefined` when the node is absent or contains no lock attributes.
|
|
@@ -32675,7 +34539,8 @@ var PptxHandlerRuntime41 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
32675
34539
|
if (Number.isFinite(spcColRaw) && spcColRaw > 0) {
|
|
32676
34540
|
textStyle.columnSpacing = spcColRaw / _PptxHandlerRuntime.EMU_PER_PX;
|
|
32677
34541
|
}
|
|
32678
|
-
const
|
|
34542
|
+
const hOverflowRaw = bodyPr["@_horzOverflow"] ?? bodyPr["@_hOverflow"];
|
|
34543
|
+
const hOverflow = String(hOverflowRaw || "").trim();
|
|
32679
34544
|
if (hOverflow === "overflow" || hOverflow === "clip") {
|
|
32680
34545
|
textStyle.hOverflow = hOverflow;
|
|
32681
34546
|
}
|
|
@@ -32858,7 +34723,7 @@ var PptxHandlerRuntime41 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
32858
34723
|
};
|
|
32859
34724
|
|
|
32860
34725
|
// src/core/core/runtime/PptxHandlerRuntimeShapeTextParsing.ts
|
|
32861
|
-
var
|
|
34726
|
+
var PptxHandlerRuntime43 = class _PptxHandlerRuntime extends PptxHandlerRuntime42 {
|
|
32862
34727
|
/**
|
|
32863
34728
|
* Resolve paragraph-level styles (alignment, spacing, margins, tabs,
|
|
32864
34729
|
* level styles) for a single paragraph. Modifies `textStyle` in place
|
|
@@ -33040,7 +34905,7 @@ var PptxHandlerRuntime42 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33040
34905
|
};
|
|
33041
34906
|
|
|
33042
34907
|
// src/core/core/runtime/PptxHandlerRuntimeShapeParagraphContentParsing.ts
|
|
33043
|
-
var
|
|
34908
|
+
var PptxHandlerRuntime44 = class extends PptxHandlerRuntime43 {
|
|
33044
34909
|
/**
|
|
33045
34910
|
* Collect text content (runs, fields, equations, bullets) for a single
|
|
33046
34911
|
* paragraph and return text parts + segments. The returned `seedStyle`
|
|
@@ -33223,6 +35088,23 @@ var PptxHandlerRuntime43 = class extends PptxHandlerRuntime42 {
|
|
|
33223
35088
|
parts.push("\n");
|
|
33224
35089
|
segments.push({ text: "\n", style: { ...mergedDefaultRunStyle } });
|
|
33225
35090
|
}
|
|
35091
|
+
const firstSegmentIndex = segments.length === 0 ? -1 : 0;
|
|
35092
|
+
if (firstSegmentIndex >= 0) {
|
|
35093
|
+
const pPrRaw = p["a:pPr"];
|
|
35094
|
+
const lvlRaw = pPrRaw?.["@_lvl"];
|
|
35095
|
+
if (lvlRaw !== void 0) {
|
|
35096
|
+
const lvlParsed = Number.parseInt(String(lvlRaw), 10);
|
|
35097
|
+
if (Number.isFinite(lvlParsed) && lvlParsed > 0) {
|
|
35098
|
+
segments[firstSegmentIndex].paragraphLevel = Math.min(Math.max(lvlParsed, 0), 8);
|
|
35099
|
+
}
|
|
35100
|
+
}
|
|
35101
|
+
const endParaRPrRaw = p["a:endParaRPr"];
|
|
35102
|
+
if (endParaRPrRaw && typeof endParaRPrRaw === "object") {
|
|
35103
|
+
segments[firstSegmentIndex].endParaRunProperties = {
|
|
35104
|
+
...endParaRPrRaw
|
|
35105
|
+
};
|
|
35106
|
+
}
|
|
35107
|
+
}
|
|
33226
35108
|
return { parts, segments, seedStyle };
|
|
33227
35109
|
}
|
|
33228
35110
|
/**
|
|
@@ -33332,7 +35214,7 @@ var PptxHandlerRuntime43 = class extends PptxHandlerRuntime42 {
|
|
|
33332
35214
|
};
|
|
33333
35215
|
|
|
33334
35216
|
// src/core/core/runtime/PptxHandlerRuntimeShapeParsing.ts
|
|
33335
|
-
var
|
|
35217
|
+
var PptxHandlerRuntime45 = class _PptxHandlerRuntime extends PptxHandlerRuntime44 {
|
|
33336
35218
|
parseShape(shape, id, slidePath) {
|
|
33337
35219
|
try {
|
|
33338
35220
|
const spPr = shape["p:spPr"];
|
|
@@ -33368,6 +35250,7 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33368
35250
|
let pathData;
|
|
33369
35251
|
let pathWidth;
|
|
33370
35252
|
let pathHeight;
|
|
35253
|
+
let customGeometryRawData;
|
|
33371
35254
|
const custGeom = effectiveSpPr?.["a:custGeom"];
|
|
33372
35255
|
if (custGeom) {
|
|
33373
35256
|
const customPath = this.parseCustomGeometry(
|
|
@@ -33380,6 +35263,7 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33380
35263
|
pathData = customPath.pathData;
|
|
33381
35264
|
pathWidth = customPath.pathWidth;
|
|
33382
35265
|
pathHeight = customPath.pathHeight;
|
|
35266
|
+
customGeometryRawData = this.extractCustomGeometryRawData(custGeom);
|
|
33383
35267
|
}
|
|
33384
35268
|
}
|
|
33385
35269
|
const geomNode = custGeom ?? effectiveSpPr?.["a:prstGeom"];
|
|
@@ -33537,7 +35421,8 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33537
35421
|
type: "shape",
|
|
33538
35422
|
pathData,
|
|
33539
35423
|
pathWidth,
|
|
33540
|
-
pathHeight
|
|
35424
|
+
pathHeight,
|
|
35425
|
+
customGeometryRawData
|
|
33541
35426
|
};
|
|
33542
35427
|
} catch (e) {
|
|
33543
35428
|
console.warn(`[pptx] Skipping shape element (${id}):`, e);
|
|
@@ -33547,7 +35432,7 @@ var PptxHandlerRuntime44 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33547
35432
|
};
|
|
33548
35433
|
|
|
33549
35434
|
// src/core/core/runtime/PptxHandlerRuntimePictureParsing.ts
|
|
33550
|
-
var
|
|
35435
|
+
var PptxHandlerRuntime46 = class _PptxHandlerRuntime extends PptxHandlerRuntime45 {
|
|
33551
35436
|
async parsePicture(pic, id, slidePath) {
|
|
33552
35437
|
try {
|
|
33553
35438
|
const spPr = pic["p:spPr"];
|
|
@@ -33786,7 +35671,7 @@ var PptxHandlerRuntime45 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
33786
35671
|
};
|
|
33787
35672
|
|
|
33788
35673
|
// src/core/core/runtime/PptxHandlerRuntimeSpTreeParsing.ts
|
|
33789
|
-
var
|
|
35674
|
+
var PptxHandlerRuntime47 = class _PptxHandlerRuntime extends PptxHandlerRuntime46 {
|
|
33790
35675
|
/**
|
|
33791
35676
|
* Known element tag names that appear as direct children of `p:spTree`
|
|
33792
35677
|
* (or `p:grpSp`) and represent renderable shapes/objects.
|
|
@@ -34131,9 +36016,18 @@ var PptxHandlerRuntime46 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
34131
36016
|
* Unwrap mc:AlternateContent elements within a shape tree (or group),
|
|
34132
36017
|
* merging selected branch children into the parent element arrays.
|
|
34133
36018
|
* Delegates to the standalone alternate-content utility.
|
|
36019
|
+
*
|
|
36020
|
+
* Records each consumed AC envelope in {@link alternateContentBlockByRawXml}
|
|
36021
|
+
* so the save layer can re-emit the original `<mc:Choice>` /
|
|
36022
|
+
* `<mc:Fallback>` shape on dirty save (CC-4).
|
|
34134
36023
|
*/
|
|
34135
36024
|
unwrapAlternateContent(container) {
|
|
34136
|
-
unwrapAlternateContent(container);
|
|
36025
|
+
const blocks = unwrapAlternateContent(container);
|
|
36026
|
+
for (const block of blocks) {
|
|
36027
|
+
for (const ref of block.childRefs) {
|
|
36028
|
+
this.alternateContentBlockByRawXml.set(ref.node, block);
|
|
36029
|
+
}
|
|
36030
|
+
}
|
|
34137
36031
|
}
|
|
34138
36032
|
/**
|
|
34139
36033
|
* Forward declaration – implemented in PptxHandlerRuntimeGroupParsing.
|
|
@@ -34144,7 +36038,7 @@ var PptxHandlerRuntime46 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
34144
36038
|
};
|
|
34145
36039
|
|
|
34146
36040
|
// src/core/core/runtime/PptxHandlerRuntimeGroupParsing.ts
|
|
34147
|
-
var
|
|
36041
|
+
var PptxHandlerRuntime48 = class _PptxHandlerRuntime extends PptxHandlerRuntime47 {
|
|
34148
36042
|
async parseGroupShape(group, baseId, slidePath, rawXmlStr) {
|
|
34149
36043
|
const grpSpPr = group["p:grpSpPr"];
|
|
34150
36044
|
const xfrm = grpSpPr?.["a:xfrm"];
|
|
@@ -34317,7 +36211,7 @@ var PptxHandlerRuntime47 = class _PptxHandlerRuntime extends PptxHandlerRuntime4
|
|
|
34317
36211
|
};
|
|
34318
36212
|
|
|
34319
36213
|
// src/core/core/runtime/PptxHandlerRuntimeSlideParsing.ts
|
|
34320
|
-
var
|
|
36214
|
+
var PptxHandlerRuntime49 = class extends PptxHandlerRuntime48 {
|
|
34321
36215
|
/**
|
|
34322
36216
|
* Parse text body from a connector shape (p:cxnSp > p:txBody).
|
|
34323
36217
|
* Uses the same text run extraction logic as regular shapes but
|
|
@@ -34429,7 +36323,7 @@ var PptxHandlerRuntime48 = class extends PptxHandlerRuntime47 {
|
|
|
34429
36323
|
};
|
|
34430
36324
|
|
|
34431
36325
|
// src/core/core/runtime/PptxHandlerRuntimeColorAndEffects.ts
|
|
34432
|
-
var
|
|
36326
|
+
var PptxHandlerRuntime50 = class extends PptxHandlerRuntime49 {
|
|
34433
36327
|
/**
|
|
34434
36328
|
* Forward declaration – implemented in PptxHandlerRuntimeThemeProcessing.
|
|
34435
36329
|
* Re-resolves gradient stops by substituting `phClr` with the given colour.
|
|
@@ -34470,8 +36364,9 @@ var PptxHandlerRuntime49 = class extends PptxHandlerRuntime48 {
|
|
|
34470
36364
|
return void 0;
|
|
34471
36365
|
}
|
|
34472
36366
|
const resolvedKey = normalized === "phclr" ? "accent1" : normalized;
|
|
34473
|
-
|
|
34474
|
-
|
|
36367
|
+
const overrideMap = this.currentSlideClrMapOverride ?? this.currentMasterClrMap;
|
|
36368
|
+
if (overrideMap) {
|
|
36369
|
+
const remapped = overrideMap[resolvedKey];
|
|
34475
36370
|
if (remapped) {
|
|
34476
36371
|
return this.themeColorMap[remapped] || this.getDefaultSchemeColorMap()[remapped];
|
|
34477
36372
|
}
|
|
@@ -34554,7 +36449,7 @@ var PptxHandlerRuntime49 = class extends PptxHandlerRuntime48 {
|
|
|
34554
36449
|
};
|
|
34555
36450
|
|
|
34556
36451
|
// src/core/core/runtime/PptxHandlerRuntimeBackgroundParsing.ts
|
|
34557
|
-
var
|
|
36452
|
+
var PptxHandlerRuntime51 = class extends PptxHandlerRuntime50 {
|
|
34558
36453
|
async extractBackgroundImage(slideXml2, slidePath, rootElement = "p:sld") {
|
|
34559
36454
|
try {
|
|
34560
36455
|
const bg = slideXml2[rootElement]?.["p:cSld"]?.["p:bg"];
|
|
@@ -34765,7 +36660,7 @@ var PptxHandlerRuntime50 = class extends PptxHandlerRuntime49 {
|
|
|
34765
36660
|
};
|
|
34766
36661
|
|
|
34767
36662
|
// src/core/core/runtime/PptxHandlerRuntimeSlideUtils.ts
|
|
34768
|
-
var
|
|
36663
|
+
var PptxHandlerRuntime52 = class extends PptxHandlerRuntime51 {
|
|
34769
36664
|
/**
|
|
34770
36665
|
* Retrieve the background gradient from a layout, falling back to master.
|
|
34771
36666
|
*/
|
|
@@ -34836,6 +36731,64 @@ var PptxHandlerRuntime51 = class extends PptxHandlerRuntime50 {
|
|
|
34836
36731
|
}
|
|
34837
36732
|
return void 0;
|
|
34838
36733
|
}
|
|
36734
|
+
/**
|
|
36735
|
+
* Find the master file path referenced by a layout via its relationships.
|
|
36736
|
+
*/
|
|
36737
|
+
findMasterPathForLayoutBase(layoutPath) {
|
|
36738
|
+
const layoutRels = this.slideRelsMap.get(layoutPath);
|
|
36739
|
+
if (!layoutRels) {
|
|
36740
|
+
return void 0;
|
|
36741
|
+
}
|
|
36742
|
+
for (const [, target] of layoutRels.entries()) {
|
|
36743
|
+
if (target.includes("slideMaster")) {
|
|
36744
|
+
const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
|
|
36745
|
+
return target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${target.replace("../", "")}`;
|
|
36746
|
+
}
|
|
36747
|
+
}
|
|
36748
|
+
return void 0;
|
|
36749
|
+
}
|
|
36750
|
+
/**
|
|
36751
|
+
* Switch the active master state (clrMap + theme color/font/format
|
|
36752
|
+
* scheme) so that scheme-colour resolution for the slide currently
|
|
36753
|
+
* being parsed walks through the correct master.
|
|
36754
|
+
*
|
|
36755
|
+
* Multi-master decks must resolve scheme colours against each slide's
|
|
36756
|
+
* own master rather than always against `masterFiles[0]`.
|
|
36757
|
+
*
|
|
36758
|
+
* Phase 2 Stream B / C-H4.
|
|
36759
|
+
*/
|
|
36760
|
+
async setActiveMasterForSlide(slidePath) {
|
|
36761
|
+
const layoutPath = this.findLayoutPathForSlide(slidePath);
|
|
36762
|
+
if (!layoutPath) {
|
|
36763
|
+
this.currentMasterClrMap = null;
|
|
36764
|
+
this.themeColorMap = { ...this.globalThemeColorMapSnapshot };
|
|
36765
|
+
this.themeFontMap = { ...this.globalThemeFontMapSnapshot };
|
|
36766
|
+
this.themeFormatScheme = this.globalThemeFormatSchemeSnapshot;
|
|
36767
|
+
return;
|
|
36768
|
+
}
|
|
36769
|
+
if (!this.slideRelsMap.has(layoutPath)) {
|
|
36770
|
+
const layoutRelsPath = `${layoutPath.replace("slideLayouts/", "slideLayouts/_rels/")}.rels`;
|
|
36771
|
+
try {
|
|
36772
|
+
await this.loadSlideRelationships(layoutPath, layoutRelsPath);
|
|
36773
|
+
} catch {
|
|
36774
|
+
}
|
|
36775
|
+
}
|
|
36776
|
+
const masterPath = this.findMasterPathForLayoutBase(layoutPath);
|
|
36777
|
+
if (!masterPath) {
|
|
36778
|
+
this.currentMasterClrMap = null;
|
|
36779
|
+
this.themeColorMap = { ...this.globalThemeColorMapSnapshot };
|
|
36780
|
+
this.themeFontMap = { ...this.globalThemeFontMapSnapshot };
|
|
36781
|
+
this.themeFormatScheme = this.globalThemeFormatSchemeSnapshot;
|
|
36782
|
+
return;
|
|
36783
|
+
}
|
|
36784
|
+
this.currentMasterClrMap = this.masterClrMaps.get(masterPath) ?? null;
|
|
36785
|
+
const masterColorMap = this.masterThemeColorMaps.get(masterPath);
|
|
36786
|
+
this.themeColorMap = masterColorMap ? { ...masterColorMap } : { ...this.globalThemeColorMapSnapshot };
|
|
36787
|
+
const masterFontMap = this.masterThemeFontMaps.get(masterPath);
|
|
36788
|
+
this.themeFontMap = masterFontMap ? { ...masterFontMap } : { ...this.globalThemeFontMapSnapshot };
|
|
36789
|
+
const masterFormatScheme = this.masterThemeFormatSchemes.get(masterPath);
|
|
36790
|
+
this.themeFormatScheme = masterFormatScheme ?? this.globalThemeFormatSchemeSnapshot;
|
|
36791
|
+
}
|
|
34839
36792
|
/**
|
|
34840
36793
|
* Extract the `p:bg/@showAnimation` flag from a slide's XML.
|
|
34841
36794
|
* Returns `true` when the background should animate, `false` when
|
|
@@ -34976,7 +36929,7 @@ var PptxHandlerRuntime51 = class extends PptxHandlerRuntime50 {
|
|
|
34976
36929
|
};
|
|
34977
36930
|
|
|
34978
36931
|
// src/core/core/runtime/PptxHandlerRuntimePlaceholderStyles.ts
|
|
34979
|
-
var
|
|
36932
|
+
var PptxHandlerRuntime53 = class _PptxHandlerRuntime extends PptxHandlerRuntime52 {
|
|
34980
36933
|
/**
|
|
34981
36934
|
* Parse a single `a:lvlXpPr` node into a structured
|
|
34982
36935
|
* {@link PlaceholderTextLevelStyle}.
|
|
@@ -35097,7 +37050,7 @@ var PptxHandlerRuntime52 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
|
|
|
35097
37050
|
};
|
|
35098
37051
|
|
|
35099
37052
|
// src/core/core/runtime/PptxHandlerRuntimePlaceholderDefaults.ts
|
|
35100
|
-
var
|
|
37053
|
+
var PptxHandlerRuntime54 = class _PptxHandlerRuntime extends PptxHandlerRuntime53 {
|
|
35101
37054
|
/**
|
|
35102
37055
|
* Extract structured {@link PlaceholderDefaults} from a layout or master
|
|
35103
37056
|
* shape that carries a `p:ph` element.
|
|
@@ -35240,7 +37193,118 @@ var PptxHandlerRuntime53 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
|
|
|
35240
37193
|
};
|
|
35241
37194
|
|
|
35242
37195
|
// src/core/core/runtime/PptxHandlerRuntimeMasterElements.ts
|
|
35243
|
-
|
|
37196
|
+
function parseHeaderFooterFlags(hf) {
|
|
37197
|
+
if (!hf) {
|
|
37198
|
+
return void 0;
|
|
37199
|
+
}
|
|
37200
|
+
const result = {};
|
|
37201
|
+
if (hf["@_hdr"] !== void 0) {
|
|
37202
|
+
result.hasHeader = String(hf["@_hdr"]) !== "0";
|
|
37203
|
+
}
|
|
37204
|
+
if (hf["@_ftr"] !== void 0) {
|
|
37205
|
+
result.hasFooter = String(hf["@_ftr"]) !== "0";
|
|
37206
|
+
}
|
|
37207
|
+
if (hf["@_dt"] !== void 0) {
|
|
37208
|
+
result.hasDateTime = String(hf["@_dt"]) !== "0";
|
|
37209
|
+
}
|
|
37210
|
+
if (hf["@_sldNum"] !== void 0) {
|
|
37211
|
+
result.hasSlideNumber = String(hf["@_sldNum"]) !== "0";
|
|
37212
|
+
}
|
|
37213
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
37214
|
+
}
|
|
37215
|
+
var PptxHandlerRuntime55 = class extends PptxHandlerRuntime54 {
|
|
37216
|
+
/**
|
|
37217
|
+
* Parse a `CT_TextListStyle` node (`a:defPPr` + `a:lvl1pPr` … `a:lvl9pPr`)
|
|
37218
|
+
* into a level-keyed style map. Used for `<p:txStyles>` children
|
|
37219
|
+
* (`p:titleStyle`, `p:bodyStyle`, `p:otherStyle`) — see ECMA-376 §19.3.1.52.
|
|
37220
|
+
*/
|
|
37221
|
+
parseTextListStyle(node) {
|
|
37222
|
+
if (!node) {
|
|
37223
|
+
return void 0;
|
|
37224
|
+
}
|
|
37225
|
+
const levels = {};
|
|
37226
|
+
const defParsed = this.parsePlaceholderLevelStyle(node["a:defPPr"]);
|
|
37227
|
+
if (defParsed) {
|
|
37228
|
+
levels[-1] = defParsed;
|
|
37229
|
+
}
|
|
37230
|
+
for (let lvl = 1; lvl <= 9; lvl++) {
|
|
37231
|
+
const parsed = this.parsePlaceholderLevelStyle(
|
|
37232
|
+
node[`a:lvl${lvl}pPr`]
|
|
37233
|
+
);
|
|
37234
|
+
if (parsed) {
|
|
37235
|
+
levels[lvl - 1] = parsed;
|
|
37236
|
+
}
|
|
37237
|
+
}
|
|
37238
|
+
return Object.keys(levels).length > 0 ? levels : void 0;
|
|
37239
|
+
}
|
|
37240
|
+
/**
|
|
37241
|
+
* Parse `<p:txStyles>` from a slide-master XML object into a structured
|
|
37242
|
+
* {@link PptxMasterTextStyles}. Used to populate `PptxSlideMaster.txStyles`
|
|
37243
|
+
* so the title/body/other text-style cascade (P-H1) is visible on the
|
|
37244
|
+
* typed model.
|
|
37245
|
+
*/
|
|
37246
|
+
parseMasterTxStyles(masterXml) {
|
|
37247
|
+
const txStyles = masterXml?.["p:txStyles"];
|
|
37248
|
+
if (!txStyles) {
|
|
37249
|
+
return void 0;
|
|
37250
|
+
}
|
|
37251
|
+
const titleStyle = this.parseTextListStyle(txStyles["p:titleStyle"]);
|
|
37252
|
+
const bodyStyle = this.parseTextListStyle(txStyles["p:bodyStyle"]);
|
|
37253
|
+
const otherStyle = this.parseTextListStyle(txStyles["p:otherStyle"]);
|
|
37254
|
+
if (!titleStyle && !bodyStyle && !otherStyle) {
|
|
37255
|
+
return void 0;
|
|
37256
|
+
}
|
|
37257
|
+
const result = {};
|
|
37258
|
+
if (titleStyle) {
|
|
37259
|
+
result.titleStyle = titleStyle;
|
|
37260
|
+
}
|
|
37261
|
+
if (bodyStyle) {
|
|
37262
|
+
result.bodyStyle = bodyStyle;
|
|
37263
|
+
}
|
|
37264
|
+
if (otherStyle) {
|
|
37265
|
+
result.otherStyle = otherStyle;
|
|
37266
|
+
}
|
|
37267
|
+
return result;
|
|
37268
|
+
}
|
|
37269
|
+
/**
|
|
37270
|
+
* Enrich an array of {@link PptxSlideMaster} entries (already produced by
|
|
37271
|
+
* `parseSlideMasters`) with parsed `<p:txStyles>`. Loads each master's XML
|
|
37272
|
+
* once, parses, and caches it in `masterXmlMap` for downstream consumers.
|
|
37273
|
+
*
|
|
37274
|
+
* Also stores the parsed result on the per-master cache so that the
|
|
37275
|
+
* inheritance chain in `applyMasterTextStyleCascade` can find it without
|
|
37276
|
+
* re-parsing.
|
|
37277
|
+
*/
|
|
37278
|
+
async enrichSlideMastersWithTxStyles(slideMasters) {
|
|
37279
|
+
for (const master of slideMasters) {
|
|
37280
|
+
try {
|
|
37281
|
+
let masterXmlObj = this.masterXmlMap.get(master.path);
|
|
37282
|
+
if (!masterXmlObj) {
|
|
37283
|
+
const xmlStr = await this.zip.file(master.path)?.async("string");
|
|
37284
|
+
if (!xmlStr) {
|
|
37285
|
+
continue;
|
|
37286
|
+
}
|
|
37287
|
+
masterXmlObj = this.parser.parse(xmlStr);
|
|
37288
|
+
this.masterXmlMap.set(master.path, masterXmlObj);
|
|
37289
|
+
}
|
|
37290
|
+
const sldMaster = masterXmlObj["p:sldMaster"];
|
|
37291
|
+
if (!sldMaster) {
|
|
37292
|
+
continue;
|
|
37293
|
+
}
|
|
37294
|
+
const parsed = this.parseMasterTxStyles(sldMaster);
|
|
37295
|
+
if (parsed) {
|
|
37296
|
+
master.txStyles = parsed;
|
|
37297
|
+
this.masterTxStylesCache.set(master.path, parsed);
|
|
37298
|
+
}
|
|
37299
|
+
const hf = parseHeaderFooterFlags(sldMaster["p:hf"]);
|
|
37300
|
+
if (hf) {
|
|
37301
|
+
master.headerFooter = hf;
|
|
37302
|
+
}
|
|
37303
|
+
} catch (e) {
|
|
37304
|
+
console.warn("Failed to parse master txStyles:", e);
|
|
37305
|
+
}
|
|
37306
|
+
}
|
|
37307
|
+
}
|
|
35244
37308
|
parsePresentationDefaultTextStyle() {
|
|
35245
37309
|
const presentation = this.presentationData?.["p:presentation"];
|
|
35246
37310
|
const defaultTextStyle = presentation?.["p:defaultTextStyle"];
|
|
@@ -35396,7 +37460,7 @@ var PptxHandlerRuntime54 = class extends PptxHandlerRuntime53 {
|
|
|
35396
37460
|
};
|
|
35397
37461
|
|
|
35398
37462
|
// src/core/core/runtime/PptxHandlerRuntimeLayoutElements.ts
|
|
35399
|
-
var
|
|
37463
|
+
var PptxHandlerRuntime56 = class extends PptxHandlerRuntime55 {
|
|
35400
37464
|
async getLayoutElements(slidePath) {
|
|
35401
37465
|
const slideRels = this.slideRelsMap.get(slidePath);
|
|
35402
37466
|
if (!slideRels) {
|
|
@@ -35520,10 +37584,10 @@ var PptxHandlerRuntime55 = class extends PptxHandlerRuntime54 {
|
|
|
35520
37584
|
}
|
|
35521
37585
|
}
|
|
35522
37586
|
}
|
|
35523
|
-
this.currentSlideClrMapOverride = prevClrMapOverride;
|
|
35524
37587
|
const layoutShowMasterSp = layoutXmlObj["p:sldLayout"]?.["@_showMasterSp"];
|
|
35525
37588
|
const showMasterSp = layoutShowMasterSp === void 0 || String(layoutShowMasterSp).trim().toLowerCase() !== "0" && String(layoutShowMasterSp).trim().toLowerCase() !== "false";
|
|
35526
37589
|
const masterElements = showMasterSp ? await this.getMasterElements(layoutPath) : [];
|
|
37590
|
+
this.currentSlideClrMapOverride = prevClrMapOverride;
|
|
35527
37591
|
const allElements = [...masterElements, ...elements];
|
|
35528
37592
|
this.layoutCache.set(layoutPath, allElements);
|
|
35529
37593
|
return allElements;
|
|
@@ -35535,7 +37599,7 @@ var PptxHandlerRuntime55 = class extends PptxHandlerRuntime54 {
|
|
|
35535
37599
|
};
|
|
35536
37600
|
|
|
35537
37601
|
// src/core/core/runtime/PptxHandlerRuntimeThemeFormatScheme.ts
|
|
35538
|
-
var
|
|
37602
|
+
var PptxHandlerRuntime57 = class _PptxHandlerRuntime extends PptxHandlerRuntime56 {
|
|
35539
37603
|
/**
|
|
35540
37604
|
* Collect fill-style children from a style list node, preserving
|
|
35541
37605
|
* document order. Handles `a:solidFill`, `a:gradFill`, `a:pattFill`,
|
|
@@ -35777,7 +37841,7 @@ var PptxHandlerRuntime56 = class _PptxHandlerRuntime extends PptxHandlerRuntime5
|
|
|
35777
37841
|
};
|
|
35778
37842
|
|
|
35779
37843
|
// src/core/core/runtime/PptxHandlerRuntimeThemeOverrides.ts
|
|
35780
|
-
var
|
|
37844
|
+
var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
|
|
35781
37845
|
/**
|
|
35782
37846
|
* Parse the `a:fmtScheme` element from the theme into a structured
|
|
35783
37847
|
* {@link PptxThemeFormatScheme}. Each sub-list (fillStyleLst, lnStyleLst,
|
|
@@ -35974,8 +38038,10 @@ var PptxHandlerRuntime57 = class extends PptxHandlerRuntime56 {
|
|
|
35974
38038
|
}
|
|
35975
38039
|
const fontScheme = root["a:fontScheme"];
|
|
35976
38040
|
if (fontScheme) {
|
|
35977
|
-
const
|
|
35978
|
-
const
|
|
38041
|
+
const majorFontNode = fontScheme["a:majorFont"];
|
|
38042
|
+
const minorFontNode = fontScheme["a:minorFont"];
|
|
38043
|
+
const majorLatin = majorFontNode?.["a:latin"];
|
|
38044
|
+
const minorLatin = minorFontNode?.["a:latin"];
|
|
35979
38045
|
const majorFont = this.normalizeTypefaceToken(String(majorLatin?.["@_typeface"] || ""));
|
|
35980
38046
|
const minorFont = this.normalizeTypefaceToken(String(minorLatin?.["@_typeface"] || ""));
|
|
35981
38047
|
if (!result.colorOverrides) {
|
|
@@ -35998,13 +38064,46 @@ var PptxHandlerRuntime57 = class extends PptxHandlerRuntime56 {
|
|
|
35998
38064
|
};
|
|
35999
38065
|
|
|
36000
38066
|
// src/core/core/runtime/PptxHandlerRuntimeThemeRefResolution.ts
|
|
36001
|
-
var
|
|
38067
|
+
var COLOR_CHOICE_KEYS2 = [
|
|
38068
|
+
"a:scrgbClr",
|
|
38069
|
+
"a:srgbClr",
|
|
38070
|
+
"a:hslClr",
|
|
38071
|
+
"a:sysClr",
|
|
38072
|
+
"a:schemeClr",
|
|
38073
|
+
"a:prstClr"
|
|
38074
|
+
];
|
|
38075
|
+
var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
|
|
38076
|
+
/**
|
|
38077
|
+
* Pull the verbatim colour-choice child out of a style-matrix-reference
|
|
38078
|
+
* element (`a:lnRef`/`a:fillRef`/`a:effectRef`/`a:fontRef`). Returns the
|
|
38079
|
+
* full child object so it can be round-tripped at save time, preserving
|
|
38080
|
+
* any contained colour transforms (`a:lumMod`, `a:tint`, etc.).
|
|
38081
|
+
*/
|
|
38082
|
+
extractRefColorXml(refNode) {
|
|
38083
|
+
if (!refNode) {
|
|
38084
|
+
return void 0;
|
|
38085
|
+
}
|
|
38086
|
+
for (const key of COLOR_CHOICE_KEYS2) {
|
|
38087
|
+
const child = refNode[key];
|
|
38088
|
+
if (child !== void 0) {
|
|
38089
|
+
return { [key]: child };
|
|
38090
|
+
}
|
|
38091
|
+
}
|
|
38092
|
+
return void 0;
|
|
38093
|
+
}
|
|
36002
38094
|
/**
|
|
36003
38095
|
* Resolve a `a:effectRef` element into concrete effect properties
|
|
36004
38096
|
* by looking up `@_idx` in the theme format scheme's effect style list.
|
|
36005
38097
|
*/
|
|
36006
38098
|
resolveThemeEffectRef(refNode, style) {
|
|
36007
38099
|
const idx = parseInt(String(refNode["@_idx"] || "0"), 10);
|
|
38100
|
+
if (Number.isFinite(idx) && idx > 0) {
|
|
38101
|
+
style.effectRefIdx = idx;
|
|
38102
|
+
}
|
|
38103
|
+
const overrideColorXml = this.extractRefColorXml(refNode);
|
|
38104
|
+
if (overrideColorXml) {
|
|
38105
|
+
style.effectRefColorXml = overrideColorXml;
|
|
38106
|
+
}
|
|
36008
38107
|
if (!Number.isFinite(idx) || idx <= 0 || !this.themeFormatScheme || idx > this.themeFormatScheme.effectStyles.length) {
|
|
36009
38108
|
return;
|
|
36010
38109
|
}
|
|
@@ -36057,6 +38156,13 @@ var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
|
|
|
36057
38156
|
resolveThemeLineRef(refNode, style) {
|
|
36058
38157
|
const idx = parseInt(String(refNode["@_idx"] || "0"), 10);
|
|
36059
38158
|
const overrideColor = this.parseColor(refNode);
|
|
38159
|
+
if (Number.isFinite(idx) && idx > 0) {
|
|
38160
|
+
style.lnRefIdx = idx;
|
|
38161
|
+
}
|
|
38162
|
+
const overrideColorXml = this.extractRefColorXml(refNode);
|
|
38163
|
+
if (overrideColorXml) {
|
|
38164
|
+
style.lnRefColorXml = overrideColorXml;
|
|
38165
|
+
}
|
|
36060
38166
|
if (!Number.isFinite(idx) || idx <= 0 || !this.themeFormatScheme || idx > this.themeFormatScheme.lineStyles.length) {
|
|
36061
38167
|
style.strokeColor = overrideColor;
|
|
36062
38168
|
if (overrideColor) {
|
|
@@ -36128,6 +38234,13 @@ var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
|
|
|
36128
38234
|
*/
|
|
36129
38235
|
resolveThemeFillRef(refNode, style) {
|
|
36130
38236
|
const idx = parseInt(String(refNode["@_idx"] || "0"), 10);
|
|
38237
|
+
if (Number.isFinite(idx) && idx > 0) {
|
|
38238
|
+
style.fillRefIdx = idx;
|
|
38239
|
+
}
|
|
38240
|
+
const overrideColorXml = this.extractRefColorXml(refNode);
|
|
38241
|
+
if (overrideColorXml) {
|
|
38242
|
+
style.fillRefColorXml = overrideColorXml;
|
|
38243
|
+
}
|
|
36131
38244
|
if (!Number.isFinite(idx) || idx <= 0 || !this.themeFormatScheme) {
|
|
36132
38245
|
style.fillMode = "theme";
|
|
36133
38246
|
style.fillColor = this.parseColor(refNode);
|
|
@@ -36193,7 +38306,7 @@ var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
|
|
|
36193
38306
|
};
|
|
36194
38307
|
|
|
36195
38308
|
// src/core/core/runtime/PptxHandlerRuntimeThemeLoading.ts
|
|
36196
|
-
var
|
|
38309
|
+
var PptxHandlerRuntime60 = class extends PptxHandlerRuntime59 {
|
|
36197
38310
|
async resolvePrimaryThemePath() {
|
|
36198
38311
|
const masterFiles = this.zip.file(/^ppt\/slideMasters\/slideMaster\d+\.xml$/);
|
|
36199
38312
|
if (!masterFiles || masterFiles.length === 0) {
|
|
@@ -36303,62 +38416,97 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
|
|
|
36303
38416
|
formatScheme: this.themeFormatScheme
|
|
36304
38417
|
};
|
|
36305
38418
|
}
|
|
36306
|
-
|
|
38419
|
+
/**
|
|
38420
|
+
* Parse every slide master's `<p:clrMap>` element and store the alias
|
|
38421
|
+
* dictionaries on {@link masterClrMaps}. Do *not* mutate
|
|
38422
|
+
* {@link themeColorMap} — alias resolution happens at colour-lookup
|
|
38423
|
+
* time so that:
|
|
38424
|
+
*
|
|
38425
|
+
* 1. The raw theme scheme stays the source of truth (clrMap is a
|
|
38426
|
+
* routing layer, not a colour table).
|
|
38427
|
+
* 2. Multi-master decks resolve each slide against its own master's
|
|
38428
|
+
* clrMap rather than always against `masterFiles[0]`.
|
|
38429
|
+
* 3. Layout `clrMapOvr` semantics work correctly when a slide's master
|
|
38430
|
+
* differs from the deck's first master.
|
|
38431
|
+
*
|
|
38432
|
+
* Phase 2 Stream B / C-H4.
|
|
38433
|
+
*/
|
|
38434
|
+
async applySlideMasterColorMap(_defaultMap) {
|
|
36307
38435
|
const masterFiles = this.zip.file(/^ppt\/slideMasters\/slideMaster\d+\.xml$/);
|
|
36308
38436
|
if (!masterFiles || masterFiles.length === 0) {
|
|
36309
38437
|
return;
|
|
36310
38438
|
}
|
|
36311
|
-
|
|
36312
|
-
|
|
36313
|
-
|
|
36314
|
-
|
|
36315
|
-
|
|
36316
|
-
|
|
36317
|
-
|
|
36318
|
-
|
|
36319
|
-
|
|
36320
|
-
|
|
36321
|
-
|
|
36322
|
-
|
|
36323
|
-
|
|
36324
|
-
|
|
36325
|
-
|
|
36326
|
-
|
|
36327
|
-
"
|
|
36328
|
-
|
|
36329
|
-
"
|
|
36330
|
-
|
|
36331
|
-
];
|
|
36332
|
-
for (const aliasKey of aliasKeys) {
|
|
36333
|
-
const mappedKey = String(clrMap[`@_${aliasKey}`] || "").trim().toLowerCase();
|
|
36334
|
-
if (!mappedKey) {
|
|
38439
|
+
const aliasKeys = [
|
|
38440
|
+
"bg1",
|
|
38441
|
+
"tx1",
|
|
38442
|
+
"bg2",
|
|
38443
|
+
"tx2",
|
|
38444
|
+
"accent1",
|
|
38445
|
+
"accent2",
|
|
38446
|
+
"accent3",
|
|
38447
|
+
"accent4",
|
|
38448
|
+
"accent5",
|
|
38449
|
+
"accent6",
|
|
38450
|
+
"hlink",
|
|
38451
|
+
"folHlink"
|
|
38452
|
+
];
|
|
38453
|
+
for (const file of masterFiles) {
|
|
38454
|
+
try {
|
|
38455
|
+
const masterXml = await file.async("string");
|
|
38456
|
+
const masterData = this.parser.parse(masterXml);
|
|
38457
|
+
const clrMap = masterData?.["p:sldMaster"]?.["p:clrMap"];
|
|
38458
|
+
if (!clrMap) {
|
|
36335
38459
|
continue;
|
|
36336
38460
|
}
|
|
36337
|
-
const
|
|
36338
|
-
|
|
36339
|
-
|
|
38461
|
+
const aliasMap = {};
|
|
38462
|
+
for (const aliasKey of aliasKeys) {
|
|
38463
|
+
const mappedKey = String(clrMap[`@_${aliasKey}`] || "").trim().toLowerCase();
|
|
38464
|
+
if (mappedKey) {
|
|
38465
|
+
aliasMap[aliasKey] = mappedKey;
|
|
38466
|
+
}
|
|
38467
|
+
}
|
|
38468
|
+
if (Object.keys(aliasMap).length > 0) {
|
|
38469
|
+
this.masterClrMaps.set(file.name, aliasMap);
|
|
36340
38470
|
}
|
|
38471
|
+
} catch (error) {
|
|
38472
|
+
console.warn(`Failed to parse slide master color map for ${file.name}:`, error);
|
|
36341
38473
|
}
|
|
36342
|
-
} catch (error) {
|
|
36343
|
-
console.warn("Failed to parse slide master color map:", error);
|
|
36344
38474
|
}
|
|
36345
38475
|
}
|
|
36346
|
-
|
|
36347
|
-
|
|
36348
|
-
|
|
36349
|
-
|
|
38476
|
+
/**
|
|
38477
|
+
* Parse a single theme part into structured colour, font, and format
|
|
38478
|
+
* scheme dictionaries. Used both for the global default theme and for
|
|
38479
|
+
* each master's per-master theme (multi-master support).
|
|
38480
|
+
*
|
|
38481
|
+
* Phase 2 Stream B / C-H4.
|
|
38482
|
+
*/
|
|
38483
|
+
async parseThemePart(themePath) {
|
|
38484
|
+
const themeFile = this.zip.file(themePath);
|
|
38485
|
+
if (!themeFile) {
|
|
38486
|
+
return null;
|
|
36350
38487
|
}
|
|
36351
|
-
const preferredThemePath = await this.resolvePrimaryThemePath();
|
|
36352
|
-
const preferredThemeFile = preferredThemePath ? themeFiles.find((file) => file.name === preferredThemePath) : void 0;
|
|
36353
|
-
const themeFile = preferredThemeFile ?? themeFiles[0];
|
|
36354
38488
|
const themeXml2 = await themeFile.async("string");
|
|
38489
|
+
this.originalThemeXmlByPath.set(themePath, themeXml2);
|
|
36355
38490
|
const themeData = this.parser.parse(themeXml2);
|
|
36356
38491
|
const themeRoot = themeData["a:theme"];
|
|
36357
38492
|
const themeElements = themeRoot?.["a:themeElements"];
|
|
36358
38493
|
const colorScheme = themeElements?.["a:clrScheme"];
|
|
36359
38494
|
const fontScheme = themeElements?.["a:fontScheme"];
|
|
38495
|
+
const fmtScheme = themeElements?.["a:fmtScheme"];
|
|
38496
|
+
const themeName = String(themeRoot?.["@_name"] || "").trim();
|
|
38497
|
+
if (themeName) {
|
|
38498
|
+
this.masterThemeNames.set(themePath, themeName);
|
|
38499
|
+
}
|
|
38500
|
+
const colorSchemeName = String(colorScheme?.["@_name"] || "").trim();
|
|
38501
|
+
if (colorSchemeName) {
|
|
38502
|
+
this.masterThemeColorSchemeNames.set(themePath, colorSchemeName);
|
|
38503
|
+
}
|
|
38504
|
+
const fontSchemeName = String(fontScheme?.["@_name"] || "").trim();
|
|
38505
|
+
if (fontSchemeName) {
|
|
38506
|
+
this.masterThemeFontSchemeNames.set(themePath, fontSchemeName);
|
|
38507
|
+
}
|
|
36360
38508
|
const defaultMap = this.getDefaultSchemeColorMap();
|
|
36361
|
-
|
|
38509
|
+
const colorMap = { ...defaultMap };
|
|
36362
38510
|
if (colorScheme) {
|
|
36363
38511
|
const schemeKeys = [
|
|
36364
38512
|
"dk1",
|
|
@@ -36378,39 +38526,196 @@ var PptxHandlerRuntime59 = class extends PptxHandlerRuntime58 {
|
|
|
36378
38526
|
const colorNode = colorScheme[`a:${key}`];
|
|
36379
38527
|
const parsed = this.parseColorChoice(colorNode);
|
|
36380
38528
|
if (parsed) {
|
|
36381
|
-
|
|
38529
|
+
colorMap[key] = parsed;
|
|
36382
38530
|
}
|
|
36383
38531
|
}
|
|
36384
38532
|
}
|
|
36385
|
-
|
|
36386
|
-
|
|
36387
|
-
|
|
36388
|
-
|
|
36389
|
-
|
|
36390
|
-
const
|
|
36391
|
-
const
|
|
38533
|
+
colorMap["tx1"] = colorMap["dk1"] || defaultMap["dk1"];
|
|
38534
|
+
colorMap["bg1"] = colorMap["lt1"] || defaultMap["lt1"];
|
|
38535
|
+
colorMap["tx2"] = colorMap["dk2"] || defaultMap["dk2"];
|
|
38536
|
+
colorMap["bg2"] = colorMap["lt2"] || defaultMap["lt2"];
|
|
38537
|
+
const majorFontNode = fontScheme?.["a:majorFont"];
|
|
38538
|
+
const minorFontNode = fontScheme?.["a:minorFont"];
|
|
38539
|
+
const majorLatin = majorFontNode?.["a:latin"];
|
|
38540
|
+
const minorLatin = minorFontNode?.["a:latin"];
|
|
36392
38541
|
const majorFont = this.normalizeTypefaceToken(String(majorLatin?.["@_typeface"] || ""));
|
|
36393
38542
|
const minorFont = this.normalizeTypefaceToken(String(minorLatin?.["@_typeface"] || ""));
|
|
36394
|
-
|
|
38543
|
+
const fontMap = {};
|
|
36395
38544
|
if (majorFont) {
|
|
36396
|
-
|
|
36397
|
-
|
|
36398
|
-
|
|
38545
|
+
fontMap["mj-lt"] = majorFont;
|
|
38546
|
+
fontMap["mj-ea"] = majorFont;
|
|
38547
|
+
fontMap["mj-cs"] = majorFont;
|
|
36399
38548
|
}
|
|
36400
38549
|
if (minorFont) {
|
|
36401
|
-
|
|
36402
|
-
|
|
36403
|
-
|
|
38550
|
+
fontMap["mn-lt"] = minorFont;
|
|
38551
|
+
fontMap["mn-ea"] = minorFont;
|
|
38552
|
+
fontMap["mn-cs"] = minorFont;
|
|
36404
38553
|
}
|
|
36405
|
-
const
|
|
36406
|
-
|
|
36407
|
-
|
|
38554
|
+
const majorEa = this.normalizeTypefaceToken(
|
|
38555
|
+
String(majorFontNode?.["a:ea"]?.["@_typeface"] || "")
|
|
38556
|
+
);
|
|
38557
|
+
if (majorEa) {
|
|
38558
|
+
fontMap["mj-ea"] = majorEa;
|
|
36408
38559
|
}
|
|
38560
|
+
const majorCs = this.normalizeTypefaceToken(
|
|
38561
|
+
String(majorFontNode?.["a:cs"]?.["@_typeface"] || "")
|
|
38562
|
+
);
|
|
38563
|
+
if (majorCs) {
|
|
38564
|
+
fontMap["mj-cs"] = majorCs;
|
|
38565
|
+
}
|
|
38566
|
+
const minorEa = this.normalizeTypefaceToken(
|
|
38567
|
+
String(minorFontNode?.["a:ea"]?.["@_typeface"] || "")
|
|
38568
|
+
);
|
|
38569
|
+
if (minorEa) {
|
|
38570
|
+
fontMap["mn-ea"] = minorEa;
|
|
38571
|
+
}
|
|
38572
|
+
const minorCs = this.normalizeTypefaceToken(
|
|
38573
|
+
String(minorFontNode?.["a:cs"]?.["@_typeface"] || "")
|
|
38574
|
+
);
|
|
38575
|
+
if (minorCs) {
|
|
38576
|
+
fontMap["mn-cs"] = minorCs;
|
|
38577
|
+
}
|
|
38578
|
+
const majorScripts = this.collectFontScriptOverrides(majorFontNode);
|
|
38579
|
+
if (Object.keys(majorScripts).length > 0) {
|
|
38580
|
+
this.masterThemeMajorFontScripts.set(themePath, majorScripts);
|
|
38581
|
+
}
|
|
38582
|
+
const minorScripts = this.collectFontScriptOverrides(minorFontNode);
|
|
38583
|
+
if (Object.keys(minorScripts).length > 0) {
|
|
38584
|
+
this.masterThemeMinorFontScripts.set(themePath, minorScripts);
|
|
38585
|
+
}
|
|
38586
|
+
const objectDefaultsNode = themeRoot?.["a:objectDefaults"];
|
|
38587
|
+
if (objectDefaultsNode) {
|
|
38588
|
+
const od = {
|
|
38589
|
+
spDef: objectDefaultsNode["a:spDef"],
|
|
38590
|
+
lnDef: objectDefaultsNode["a:lnDef"],
|
|
38591
|
+
txDef: objectDefaultsNode["a:txDef"]
|
|
38592
|
+
};
|
|
38593
|
+
if (od.spDef !== void 0 || od.lnDef !== void 0 || od.txDef !== void 0) {
|
|
38594
|
+
this.masterThemeObjectDefaults.set(themePath, od);
|
|
38595
|
+
}
|
|
38596
|
+
}
|
|
38597
|
+
const extraClrSchemeLst = themeRoot?.["a:extraClrSchemeLst"];
|
|
38598
|
+
if (extraClrSchemeLst !== void 0) {
|
|
38599
|
+
this.masterThemeExtraClrSchemeLst.set(themePath, extraClrSchemeLst);
|
|
38600
|
+
}
|
|
38601
|
+
const custClrLst = themeRoot?.["a:custClrLst"];
|
|
38602
|
+
if (custClrLst !== void 0) {
|
|
38603
|
+
this.masterThemeCustClrLst.set(themePath, custClrLst);
|
|
38604
|
+
}
|
|
38605
|
+
const themeExtLst = themeRoot?.["a:extLst"];
|
|
38606
|
+
if (themeExtLst !== void 0) {
|
|
38607
|
+
this.masterThemeExtLst.set(themePath, themeExtLst);
|
|
38608
|
+
}
|
|
38609
|
+
const formatScheme = fmtScheme ? this.parseFormatScheme(fmtScheme) : void 0;
|
|
38610
|
+
return { colorMap, fontMap, formatScheme };
|
|
38611
|
+
}
|
|
38612
|
+
/**
|
|
38613
|
+
* Parse `<a:font script="…" typeface="…"/>` children of a major or
|
|
38614
|
+
* minor font node into a `script -> typeface` dictionary.
|
|
38615
|
+
*
|
|
38616
|
+
* fast-xml-parser collapses repeated tags into arrays, so iterate
|
|
38617
|
+
* over the array form regardless of how many siblings are present.
|
|
38618
|
+
*
|
|
38619
|
+
* Phase 4 Stream A / M4.
|
|
38620
|
+
*/
|
|
38621
|
+
collectFontScriptOverrides(fontNode) {
|
|
38622
|
+
const overrides = {};
|
|
38623
|
+
if (!fontNode) {
|
|
38624
|
+
return overrides;
|
|
38625
|
+
}
|
|
38626
|
+
const fontEntries = this.ensureArray(fontNode["a:font"]);
|
|
38627
|
+
for (const entry of fontEntries) {
|
|
38628
|
+
const script = String(entry?.["@_script"] || "").trim();
|
|
38629
|
+
const typeface = this.normalizeTypefaceToken(String(entry?.["@_typeface"] || ""));
|
|
38630
|
+
if (script && typeface) {
|
|
38631
|
+
overrides[script] = typeface;
|
|
38632
|
+
}
|
|
38633
|
+
}
|
|
38634
|
+
return overrides;
|
|
38635
|
+
}
|
|
38636
|
+
/**
|
|
38637
|
+
* Resolve the theme file path referenced by a given master's `.rels`.
|
|
38638
|
+
* Returns `undefined` when the master has no theme relationship.
|
|
38639
|
+
*/
|
|
38640
|
+
async resolveThemePathForMaster(masterPath) {
|
|
38641
|
+
const relsPath = masterPath.replace(
|
|
38642
|
+
/ppt\/slideMasters\/(slideMaster\d+)\.xml/,
|
|
38643
|
+
"ppt/slideMasters/_rels/$1.xml.rels"
|
|
38644
|
+
);
|
|
38645
|
+
const relsXml = this.zip.file(relsPath);
|
|
38646
|
+
if (!relsXml) {
|
|
38647
|
+
return void 0;
|
|
38648
|
+
}
|
|
38649
|
+
const relsData = this.parser.parse(await relsXml.async("string"));
|
|
38650
|
+
const relNodes = this.ensureArray(relsData?.Relationships?.Relationship);
|
|
38651
|
+
for (const rel of relNodes) {
|
|
38652
|
+
const target = String(rel["@_Target"] || "");
|
|
38653
|
+
if (!target.includes("theme")) {
|
|
38654
|
+
continue;
|
|
38655
|
+
}
|
|
38656
|
+
const themePath = target.startsWith("..") ? this.resolvePath(masterPath.substring(0, masterPath.lastIndexOf("/") + 1), target) : target.startsWith("/") ? target.slice(1) : `ppt/${target.replace(/^\.?\//, "")}`;
|
|
38657
|
+
if (themePath.startsWith("ppt/theme/")) {
|
|
38658
|
+
return themePath;
|
|
38659
|
+
}
|
|
38660
|
+
}
|
|
38661
|
+
return void 0;
|
|
38662
|
+
}
|
|
38663
|
+
/**
|
|
38664
|
+
* Populate {@link masterThemeColorMaps}, {@link masterThemeFontMaps},
|
|
38665
|
+
* and {@link masterThemeFormatSchemes} for every slide master in the
|
|
38666
|
+
* deck. Multi-master support — Phase 2 Stream B / C-H4.
|
|
38667
|
+
*/
|
|
38668
|
+
async loadPerMasterThemes() {
|
|
38669
|
+
const masterFiles = this.zip.file(/^ppt\/slideMasters\/slideMaster\d+\.xml$/);
|
|
38670
|
+
if (!masterFiles || masterFiles.length === 0) {
|
|
38671
|
+
return;
|
|
38672
|
+
}
|
|
38673
|
+
for (const file of masterFiles) {
|
|
38674
|
+
try {
|
|
38675
|
+
const themePath = await this.resolveThemePathForMaster(file.name);
|
|
38676
|
+
if (!themePath) {
|
|
38677
|
+
continue;
|
|
38678
|
+
}
|
|
38679
|
+
this.masterThemePaths.set(file.name, themePath);
|
|
38680
|
+
const parsed = await this.parseThemePart(themePath);
|
|
38681
|
+
if (!parsed) {
|
|
38682
|
+
continue;
|
|
38683
|
+
}
|
|
38684
|
+
this.masterThemeColorMaps.set(file.name, parsed.colorMap);
|
|
38685
|
+
this.masterThemeFontMaps.set(file.name, parsed.fontMap);
|
|
38686
|
+
if (parsed.formatScheme) {
|
|
38687
|
+
this.masterThemeFormatSchemes.set(file.name, parsed.formatScheme);
|
|
38688
|
+
}
|
|
38689
|
+
} catch (error) {
|
|
38690
|
+
console.warn(`Failed to load per-master theme for ${file.name}:`, error);
|
|
38691
|
+
}
|
|
38692
|
+
}
|
|
38693
|
+
}
|
|
38694
|
+
async loadThemeData() {
|
|
38695
|
+
const themeFiles = this.zip.file(/^ppt\/theme\/theme\d+\.xml$/);
|
|
38696
|
+
if (!themeFiles || themeFiles.length === 0) {
|
|
38697
|
+
return;
|
|
38698
|
+
}
|
|
38699
|
+
const preferredThemePath = await this.resolvePrimaryThemePath();
|
|
38700
|
+
const themeFile = preferredThemePath ? themeFiles.find((file) => file.name === preferredThemePath) ?? themeFiles[0] : themeFiles[0];
|
|
38701
|
+
const parsed = await this.parseThemePart(themeFile.name);
|
|
38702
|
+
if (parsed) {
|
|
38703
|
+
this.themeColorMap = parsed.colorMap;
|
|
38704
|
+
this.themeFontMap = parsed.fontMap;
|
|
38705
|
+
if (parsed.formatScheme) {
|
|
38706
|
+
this.themeFormatScheme = parsed.formatScheme;
|
|
38707
|
+
}
|
|
38708
|
+
}
|
|
38709
|
+
await this.applySlideMasterColorMap(this.getDefaultSchemeColorMap());
|
|
38710
|
+
await this.loadPerMasterThemes();
|
|
38711
|
+
this.globalThemeColorMapSnapshot = { ...this.themeColorMap };
|
|
38712
|
+
this.globalThemeFontMapSnapshot = { ...this.themeFontMap };
|
|
38713
|
+
this.globalThemeFormatSchemeSnapshot = this.themeFormatScheme;
|
|
36409
38714
|
}
|
|
36410
38715
|
};
|
|
36411
38716
|
|
|
36412
38717
|
// src/core/core/runtime/PptxHandlerRuntimeThemeProcessing.ts
|
|
36413
|
-
var
|
|
38718
|
+
var PptxHandlerRuntime61 = class extends PptxHandlerRuntime60 {
|
|
36414
38719
|
// ---------------------------------------------------------------------------
|
|
36415
38720
|
// Theme editing — update colour scheme, font scheme, and name in the zip
|
|
36416
38721
|
// ---------------------------------------------------------------------------
|
|
@@ -36560,7 +38865,7 @@ var PptxHandlerRuntime60 = class extends PptxHandlerRuntime59 {
|
|
|
36560
38865
|
};
|
|
36561
38866
|
|
|
36562
38867
|
// src/core/core/runtime/PptxHandlerRuntimeComments.ts
|
|
36563
|
-
var
|
|
38868
|
+
var PptxHandlerRuntime62 = class _PptxHandlerRuntime extends PptxHandlerRuntime61 {
|
|
36564
38869
|
/**
|
|
36565
38870
|
* Parse modern threaded comments (PowerPoint 2019+ / Office 365).
|
|
36566
38871
|
* Modern comments use `p188:cmLst`/`p15:cmLst` roots within
|
|
@@ -36793,7 +39098,7 @@ var PptxHandlerRuntime61 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
|
|
|
36793
39098
|
};
|
|
36794
39099
|
|
|
36795
39100
|
// src/core/core/runtime/PptxHandlerRuntimeSmartArtXmlUtils.ts
|
|
36796
|
-
var
|
|
39101
|
+
var PptxHandlerRuntime63 = class extends PptxHandlerRuntime62 {
|
|
36797
39102
|
async readXmlPartByRelationshipId(slidePath, relationshipId) {
|
|
36798
39103
|
const normalizedRelationshipId = String(relationshipId || "").trim();
|
|
36799
39104
|
if (normalizedRelationshipId.length === 0) {
|
|
@@ -36948,7 +39253,7 @@ var PptxHandlerRuntime62 = class extends PptxHandlerRuntime61 {
|
|
|
36948
39253
|
};
|
|
36949
39254
|
|
|
36950
39255
|
// src/core/core/runtime/PptxHandlerRuntimeSmartArtParsing.ts
|
|
36951
|
-
var
|
|
39256
|
+
var PptxHandlerRuntime64 = class _PptxHandlerRuntime extends PptxHandlerRuntime63 {
|
|
36952
39257
|
/**
|
|
36953
39258
|
* Parse quick style from `ppt/diagrams/quickStyles*.xml`.
|
|
36954
39259
|
*/
|
|
@@ -37107,7 +39412,7 @@ var PptxHandlerRuntime63 = class _PptxHandlerRuntime extends PptxHandlerRuntime6
|
|
|
37107
39412
|
};
|
|
37108
39413
|
|
|
37109
39414
|
// src/core/core/runtime/PptxHandlerRuntimeSmartArt.ts
|
|
37110
|
-
var
|
|
39415
|
+
var PptxHandlerRuntime65 = class _PptxHandlerRuntime extends PptxHandlerRuntime64 {
|
|
37111
39416
|
async getSmartArtDataForGraphicFrame(slidePath, graphicFrame) {
|
|
37112
39417
|
const graphicData = this.xmlLookupService.getChildByLocalName(
|
|
37113
39418
|
this.xmlLookupService.getChildByLocalName(graphicFrame, "graphic"),
|
|
@@ -37158,10 +39463,14 @@ var PptxHandlerRuntime64 = class extends PptxHandlerRuntime63 {
|
|
|
37158
39463
|
const layoutPart = layoutRelationshipId.length > 0 ? await this.readXmlPartByRelationshipId(slidePath, layoutRelationshipId) : void 0;
|
|
37159
39464
|
const layoutType = layoutPart?.partPath?.split("/").pop()?.replace(/\.[^.]+$/, "") || void 0;
|
|
37160
39465
|
const chrome = this.parseSmartArtChrome(dataModel);
|
|
37161
|
-
const drawingRelationshipId = String(relationshipIds["@_r:cs"] || "").trim();
|
|
37162
|
-
const drawingShapes = await this.parseSmartArtDrawingShapes(slidePath, drawingRelationshipId);
|
|
37163
39466
|
const colorsRelationshipId = String(relationshipIds["@_r:cs"] || "").trim();
|
|
37164
39467
|
const colorTransform = await this.parseSmartArtColorTransform(slidePath, colorsRelationshipId);
|
|
39468
|
+
const drawingResolution = await this.resolveSmartArtDrawingPart(
|
|
39469
|
+
slidePath,
|
|
39470
|
+
diagramDataRelationshipId
|
|
39471
|
+
);
|
|
39472
|
+
const drawingShapes = drawingResolution ? await this.parseSmartArtDrawingShapesFromPath(drawingResolution.path) : [];
|
|
39473
|
+
const drawingRelationshipId = drawingResolution?.relId;
|
|
37165
39474
|
const styleRelationshipId = String(relationshipIds["@_r:qs"] || "").trim();
|
|
37166
39475
|
const quickStyle = await this.parseSmartArtQuickStyle(slidePath, styleRelationshipId);
|
|
37167
39476
|
return {
|
|
@@ -37173,11 +39482,87 @@ var PptxHandlerRuntime64 = class extends PptxHandlerRuntime63 {
|
|
|
37173
39482
|
colorTransform,
|
|
37174
39483
|
quickStyle,
|
|
37175
39484
|
dataRelId: diagramDataRelationshipId,
|
|
37176
|
-
drawingRelId: drawingRelationshipId.length > 0 ? drawingRelationshipId : void 0,
|
|
39485
|
+
drawingRelId: drawingRelationshipId && drawingRelationshipId.length > 0 ? drawingRelationshipId : void 0,
|
|
37177
39486
|
colorsRelId: colorsRelationshipId.length > 0 ? colorsRelationshipId : void 0,
|
|
37178
39487
|
styleRelId: styleRelationshipId.length > 0 ? styleRelationshipId : void 0
|
|
37179
39488
|
};
|
|
37180
39489
|
}
|
|
39490
|
+
/**
|
|
39491
|
+
* Resolve the SmartArt drawing-shapes part path + relationship id.
|
|
39492
|
+
*
|
|
39493
|
+
* Strategy:
|
|
39494
|
+
* 1. Locate the data-model part's rels file
|
|
39495
|
+
* (`ppt/diagrams/_rels/data*.xml.rels`) via `slideRelsMap`.
|
|
39496
|
+
* 2. Find a relationship whose `Type` matches the `…/diagramDrawing`
|
|
39497
|
+
* URI. PowerPoint emits this for any deck that has had its
|
|
39498
|
+
* SmartArt rendered to drawing shapes.
|
|
39499
|
+
* 3. Return the matched part path (so the caller can load it
|
|
39500
|
+
* directly) and the relationship id (for round-trip preservation).
|
|
39501
|
+
*/
|
|
39502
|
+
async resolveSmartArtDrawingPart(slidePath, diagramDataRelationshipId) {
|
|
39503
|
+
if (diagramDataRelationshipId.length === 0) {
|
|
39504
|
+
return void 0;
|
|
39505
|
+
}
|
|
39506
|
+
const slideRels = this.slideRelsMap.get(slidePath);
|
|
39507
|
+
const dataTarget = slideRels?.get(diagramDataRelationshipId);
|
|
39508
|
+
if (!dataTarget) {
|
|
39509
|
+
return void 0;
|
|
39510
|
+
}
|
|
39511
|
+
const dataPath = this.resolveImagePath(slidePath, dataTarget);
|
|
39512
|
+
const dataDir = dataPath.replace(/\/[^/]+$/, "");
|
|
39513
|
+
const dataFile = dataPath.split("/").pop() ?? "";
|
|
39514
|
+
const dataRelsPath = `${dataDir}/_rels/${dataFile}.rels`;
|
|
39515
|
+
const relsXml = await this.zip.file(dataRelsPath)?.async("string");
|
|
39516
|
+
if (!relsXml) {
|
|
39517
|
+
return void 0;
|
|
39518
|
+
}
|
|
39519
|
+
try {
|
|
39520
|
+
const parsed = this.parser.parse(relsXml);
|
|
39521
|
+
const relsRoot = parsed["Relationships"];
|
|
39522
|
+
if (!relsRoot) {
|
|
39523
|
+
return void 0;
|
|
39524
|
+
}
|
|
39525
|
+
const rels = this.ensureArray(relsRoot["Relationship"]);
|
|
39526
|
+
const drawingRel = rels.find(
|
|
39527
|
+
(rel) => String(rel?.["@_Type"] || "").endsWith("/diagramDrawing")
|
|
39528
|
+
);
|
|
39529
|
+
const id = String(drawingRel?.["@_Id"] || "").trim();
|
|
39530
|
+
const target = String(drawingRel?.["@_Target"] || "").trim();
|
|
39531
|
+
if (id.length === 0 || target.length === 0) {
|
|
39532
|
+
return void 0;
|
|
39533
|
+
}
|
|
39534
|
+
const drawingPath = this.resolveImagePath(dataPath, target);
|
|
39535
|
+
return { relId: id, path: drawingPath };
|
|
39536
|
+
} catch {
|
|
39537
|
+
return void 0;
|
|
39538
|
+
}
|
|
39539
|
+
}
|
|
39540
|
+
/**
|
|
39541
|
+
* Parse SmartArt drawing shapes given an absolute part path.
|
|
39542
|
+
*
|
|
39543
|
+
* Wraps `parseSmartArtDrawingShapes` (which expects a slide-relative
|
|
39544
|
+
* relationship id) with a path-based lookup so the resolution layer
|
|
39545
|
+
* can pull the part from anywhere in the package.
|
|
39546
|
+
*/
|
|
39547
|
+
async parseSmartArtDrawingShapesFromPath(drawingPath) {
|
|
39548
|
+
const xmlString = await this.zip.file(drawingPath)?.async("string");
|
|
39549
|
+
if (!xmlString) {
|
|
39550
|
+
return [];
|
|
39551
|
+
}
|
|
39552
|
+
try {
|
|
39553
|
+
const xml = this.parser.parse(xmlString);
|
|
39554
|
+
const drawing = this.xmlLookupService.getChildByLocalName(xml, "drawing");
|
|
39555
|
+
const spTree = this.xmlLookupService.getChildByLocalName(drawing || xml, "spTree");
|
|
39556
|
+
if (!spTree) {
|
|
39557
|
+
return [];
|
|
39558
|
+
}
|
|
39559
|
+
const shapes = this.xmlLookupService.getChildrenArrayByLocalName(spTree, "sp");
|
|
39560
|
+
const emuPerPx = _PptxHandlerRuntime.EMU_PER_PX;
|
|
39561
|
+
return shapes.map((sp, index) => this.parseDrawingShape(sp, index, emuPerPx)).filter((entry) => entry !== null);
|
|
39562
|
+
} catch {
|
|
39563
|
+
return [];
|
|
39564
|
+
}
|
|
39565
|
+
}
|
|
37181
39566
|
parseSmartArtConnections(dataModel) {
|
|
37182
39567
|
const connectionList = this.xmlLookupService.getChildByLocalName(dataModel, "cxnLst");
|
|
37183
39568
|
const rawConnections = this.xmlLookupService.getChildrenArrayByLocalName(connectionList, "cxn");
|
|
@@ -37208,7 +39593,7 @@ var PptxHandlerRuntime64 = class extends PptxHandlerRuntime63 {
|
|
|
37208
39593
|
};
|
|
37209
39594
|
|
|
37210
39595
|
// src/core/core/runtime/PptxHandlerRuntimeChartDetection.ts
|
|
37211
|
-
var
|
|
39596
|
+
var PptxHandlerRuntime66 = class extends PptxHandlerRuntime65 {
|
|
37212
39597
|
detectChartType(plotArea) {
|
|
37213
39598
|
if (!plotArea) {
|
|
37214
39599
|
return "unknown";
|
|
@@ -37317,7 +39702,7 @@ var PptxHandlerRuntime65 = class extends PptxHandlerRuntime64 {
|
|
|
37317
39702
|
};
|
|
37318
39703
|
|
|
37319
39704
|
// src/core/core/runtime/PptxHandlerRuntimeChartParsingHelpers.ts
|
|
37320
|
-
var
|
|
39705
|
+
var PptxHandlerRuntime67 = class extends PptxHandlerRuntime66 {
|
|
37321
39706
|
/**
|
|
37322
39707
|
* Parse `c:plotVisOnly` from the chart root element.
|
|
37323
39708
|
*
|
|
@@ -37378,7 +39763,7 @@ var PptxHandlerRuntime66 = class extends PptxHandlerRuntime65 {
|
|
|
37378
39763
|
};
|
|
37379
39764
|
|
|
37380
39765
|
// src/core/core/runtime/PptxHandlerRuntimeChartExternalData.ts
|
|
37381
|
-
var
|
|
39766
|
+
var PptxHandlerRuntime68 = class extends PptxHandlerRuntime67 {
|
|
37382
39767
|
/**
|
|
37383
39768
|
* Parse `c:externalData` from the chart's `c:chartSpace` and resolve
|
|
37384
39769
|
* the external relationship target from the chart part's .rels file.
|
|
@@ -37494,7 +39879,7 @@ var PptxHandlerRuntime67 = class extends PptxHandlerRuntime66 {
|
|
|
37494
39879
|
};
|
|
37495
39880
|
|
|
37496
39881
|
// src/core/core/runtime/PptxHandlerRuntimeChartColorStyle.ts
|
|
37497
|
-
var
|
|
39882
|
+
var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
|
|
37498
39883
|
/**
|
|
37499
39884
|
* Parse the Office 2013+ chart color style part (`chartColorStyle*.xml`)
|
|
37500
39885
|
* referenced from the chart's relationships.
|
|
@@ -37601,7 +39986,7 @@ var PptxHandlerRuntime68 = class extends PptxHandlerRuntime67 {
|
|
|
37601
39986
|
};
|
|
37602
39987
|
|
|
37603
39988
|
// src/core/core/runtime/PptxHandlerRuntimeChartParsing.ts
|
|
37604
|
-
var
|
|
39989
|
+
var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
|
|
37605
39990
|
/**
|
|
37606
39991
|
* Parse chart data from a graphic frame element on a slide.
|
|
37607
39992
|
*
|
|
@@ -37848,7 +40233,7 @@ var PptxHandlerRuntime69 = class extends PptxHandlerRuntime68 {
|
|
|
37848
40233
|
};
|
|
37849
40234
|
|
|
37850
40235
|
// src/core/core/runtime/PptxHandlerRuntimePresentationStructure.ts
|
|
37851
|
-
var
|
|
40236
|
+
var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
|
|
37852
40237
|
parseEditorAnimations(slideXml2) {
|
|
37853
40238
|
return this.editorAnimationService.parseEditorAnimations(slideXml2);
|
|
37854
40239
|
}
|
|
@@ -38093,7 +40478,7 @@ var PptxHandlerRuntime70 = class extends PptxHandlerRuntime69 {
|
|
|
38093
40478
|
};
|
|
38094
40479
|
|
|
38095
40480
|
// src/core/core/runtime/PptxHandlerRuntimeEmbeddedFonts.ts
|
|
38096
|
-
var
|
|
40481
|
+
var PptxHandlerRuntime72 = class extends PptxHandlerRuntime71 {
|
|
38097
40482
|
async getEmbeddedFonts() {
|
|
38098
40483
|
const embeddedFontEntries = this.ensureArray(
|
|
38099
40484
|
this.presentationData?.["p:presentation"]?.["p:embeddedFontLst"]?.["p:embeddedFont"]
|
|
@@ -38265,7 +40650,7 @@ var PptxHandlerRuntime71 = class extends PptxHandlerRuntime70 {
|
|
|
38265
40650
|
};
|
|
38266
40651
|
|
|
38267
40652
|
// src/core/core/runtime/PptxHandlerRuntimeLoadSession.ts
|
|
38268
|
-
var
|
|
40653
|
+
var PptxHandlerRuntime73 = class _PptxHandlerRuntime extends PptxHandlerRuntime72 {
|
|
38269
40654
|
isZipContainer(data) {
|
|
38270
40655
|
const bytes = new Uint8Array(data);
|
|
38271
40656
|
if (bytes.byteLength < 4) {
|
|
@@ -38308,6 +40693,23 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38308
40693
|
this.imageDataCache.clear();
|
|
38309
40694
|
this.themeColorMap = {};
|
|
38310
40695
|
this.themeFontMap = {};
|
|
40696
|
+
this.masterClrMaps.clear();
|
|
40697
|
+
this.masterThemeColorMaps.clear();
|
|
40698
|
+
this.masterThemeFontMaps.clear();
|
|
40699
|
+
this.masterThemeFormatSchemes.clear();
|
|
40700
|
+
this.masterThemePaths.clear();
|
|
40701
|
+
this.masterThemeMajorFontScripts.clear();
|
|
40702
|
+
this.masterThemeMinorFontScripts.clear();
|
|
40703
|
+
this.masterThemeNames.clear();
|
|
40704
|
+
this.masterThemeFontSchemeNames.clear();
|
|
40705
|
+
this.masterThemeColorSchemeNames.clear();
|
|
40706
|
+
this.originalThemeXmlByPath.clear();
|
|
40707
|
+
this.dirtyThemePaths.clear();
|
|
40708
|
+
this.masterThemeObjectDefaults.clear();
|
|
40709
|
+
this.masterThemeExtraClrSchemeLst.clear();
|
|
40710
|
+
this.masterThemeCustClrLst.clear();
|
|
40711
|
+
this.masterThemeExtLst.clear();
|
|
40712
|
+
this.currentMasterClrMap = null;
|
|
38311
40713
|
this.presentationDefaultTextStyle = void 0;
|
|
38312
40714
|
this.commentAuthorMap.clear();
|
|
38313
40715
|
this.commentAuthorDetails.clear();
|
|
@@ -38462,6 +40864,7 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38462
40864
|
setCurrentSlideClrMapOverride: (override) => {
|
|
38463
40865
|
this.currentSlideClrMapOverride = override;
|
|
38464
40866
|
},
|
|
40867
|
+
setActiveMasterForSlide: (slidePath) => this.setActiveMasterForSlide(slidePath),
|
|
38465
40868
|
findLayoutPathForSlide: (slidePath) => this.findLayoutPathForSlide(slidePath),
|
|
38466
40869
|
loadThemeOverride: (partBasePath) => this.loadThemeOverride(partBasePath),
|
|
38467
40870
|
applyThemeOverrideState: (override) => this.applyThemeOverrideState(override),
|
|
@@ -38492,7 +40895,7 @@ var PptxHandlerRuntime72 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38492
40895
|
};
|
|
38493
40896
|
|
|
38494
40897
|
// src/core/core/runtime/PptxHandlerRuntimeLoadPipeline.ts
|
|
38495
|
-
var
|
|
40898
|
+
var PptxHandlerRuntime74 = class extends PptxHandlerRuntime73 {
|
|
38496
40899
|
async buildLoadData(presentationState, slidesWithWarnings) {
|
|
38497
40900
|
const headerFooter = this.extractHeaderFooter();
|
|
38498
40901
|
const presentationProperties = await this.parsePresentationProperties();
|
|
@@ -38504,6 +40907,7 @@ var PptxHandlerRuntime73 = class extends PptxHandlerRuntime72 {
|
|
|
38504
40907
|
const notesMaster = await this.parseNotesMaster();
|
|
38505
40908
|
const handoutMaster = await this.parseHandoutMaster();
|
|
38506
40909
|
const slideMasters = await this.parseSlideMasters();
|
|
40910
|
+
await this.enrichSlideMastersWithTxStyles(slideMasters);
|
|
38507
40911
|
const tags = await this.parseTags();
|
|
38508
40912
|
const customProperties = await this.parseCustomProperties();
|
|
38509
40913
|
const coreProperties = await this.parseCoreProperties();
|
|
@@ -38838,7 +41242,7 @@ var PptxHandlerRuntime73 = class extends PptxHandlerRuntime72 {
|
|
|
38838
41242
|
};
|
|
38839
41243
|
|
|
38840
41244
|
// src/core/core/runtime/PptxHandlerRuntimeImplementation.ts
|
|
38841
|
-
var
|
|
41245
|
+
var PptxHandlerRuntime75 = class _PptxHandlerRuntime extends PptxHandlerRuntime74 {
|
|
38842
41246
|
constructor(dependencyFactory = new PptxRuntimeDependencyFactory()) {
|
|
38843
41247
|
super();
|
|
38844
41248
|
this.dependencyFactory = dependencyFactory;
|
|
@@ -38886,6 +41290,9 @@ var PptxHandlerRuntime74 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38886
41290
|
extractGradientPathType: (gradFill) => this.colorStyleCodec.extractGradientPathType(gradFill),
|
|
38887
41291
|
extractGradientFocalPoint: (gradFill) => this.colorStyleCodec.extractGradientFocalPoint(gradFill),
|
|
38888
41292
|
extractGradientFillToRect: (gradFill) => this.colorStyleCodec.extractGradientFillToRect(gradFill),
|
|
41293
|
+
extractGradientFlip: (gradFill) => this.colorStyleCodec.extractGradientFlip(gradFill),
|
|
41294
|
+
extractGradientRotWithShape: (gradFill) => this.colorStyleCodec.extractGradientRotWithShape(gradFill),
|
|
41295
|
+
extractGradientScaled: (gradFill) => this.colorStyleCodec.extractGradientScaled(gradFill),
|
|
38889
41296
|
normalizeStrokeDashType: (value) => this.normalizeStrokeDashType(value),
|
|
38890
41297
|
normalizeConnectorArrowType: (value) => this.normalizeConnectorArrowType(value),
|
|
38891
41298
|
ensureArray: (value) => this.ensureArray(value),
|
|
@@ -38959,11 +41366,11 @@ var PptxHandlerRuntime74 = class _PptxHandlerRuntime extends PptxHandlerRuntime7
|
|
|
38959
41366
|
};
|
|
38960
41367
|
|
|
38961
41368
|
// src/core/core/PptxHandlerRuntime.ts
|
|
38962
|
-
var
|
|
41369
|
+
var PptxHandlerRuntime76 = class extends PptxHandlerRuntime75 {
|
|
38963
41370
|
};
|
|
38964
41371
|
|
|
38965
41372
|
// src/core/core/PptxHandlerRuntimeFactory.ts
|
|
38966
|
-
var createDefaultPptxHandlerRuntime = () => new
|
|
41373
|
+
var createDefaultPptxHandlerRuntime = () => new PptxHandlerRuntime76();
|
|
38967
41374
|
|
|
38968
41375
|
// src/core/PptxHandlerCore.ts
|
|
38969
41376
|
var PptxHandlerCore = class {
|