@office-kit/pptx 0.16.1 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/README.md +139 -58
- package/dist/{api-Dt6q_IAv.js → api-DTHZaBPq.js} +1803 -416
- package/dist/api-DTHZaBPq.js.map +1 -0
- package/dist/{index-mFv1-sf4.d.ts → index-Bfvx6-CU.d.ts} +348 -10
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/node.js +2 -2
- package/package.json +1 -1
- package/dist/api-Dt6q_IAv.js.map +0 -1
|
@@ -27,6 +27,9 @@ const STORE_BY_EXTENSION = new Set([
|
|
|
27
27
|
"wmv",
|
|
28
28
|
"mov",
|
|
29
29
|
"avi",
|
|
30
|
+
"webm",
|
|
31
|
+
"ogg",
|
|
32
|
+
"wma",
|
|
30
33
|
"pdf",
|
|
31
34
|
"zip",
|
|
32
35
|
"gz",
|
|
@@ -825,7 +828,7 @@ const emptyContentTypes = () => ({
|
|
|
825
828
|
const REL_NS = NS.relationships;
|
|
826
829
|
const NAME_RELATIONSHIPS = qname("", "Relationships", REL_NS);
|
|
827
830
|
const NAME_RELATIONSHIP = qname("", "Relationship", REL_NS);
|
|
828
|
-
const ATTR_ID$
|
|
831
|
+
const ATTR_ID$16 = qname("", "Id", "");
|
|
829
832
|
const ATTR_TYPE$7 = qname("", "Type", "");
|
|
830
833
|
const ATTR_TARGET = qname("", "Target", "");
|
|
831
834
|
const ATTR_TARGET_MODE = qname("", "TargetMode", "");
|
|
@@ -863,7 +866,7 @@ const serializeRels = (rels) => {
|
|
|
863
866
|
const children = rels.items.map((r) => {
|
|
864
867
|
const attrs = [
|
|
865
868
|
{
|
|
866
|
-
name: ATTR_ID$
|
|
869
|
+
name: ATTR_ID$16,
|
|
867
870
|
value: r.id
|
|
868
871
|
},
|
|
869
872
|
{
|
|
@@ -1060,6 +1063,79 @@ const contentTypeForFormat = (format) => {
|
|
|
1060
1063
|
}
|
|
1061
1064
|
};
|
|
1062
1065
|
//#endregion
|
|
1066
|
+
//#region src/internal/opc/media-format.ts
|
|
1067
|
+
const VIDEO_CONTENT_TYPES = {
|
|
1068
|
+
mp4: "video/mp4",
|
|
1069
|
+
m4v: "video/mp4",
|
|
1070
|
+
mov: "video/quicktime",
|
|
1071
|
+
webm: "video/webm",
|
|
1072
|
+
avi: "video/x-msvideo",
|
|
1073
|
+
wmv: "video/x-ms-wmv"
|
|
1074
|
+
};
|
|
1075
|
+
const AUDIO_CONTENT_TYPES = {
|
|
1076
|
+
mp3: "audio/mpeg",
|
|
1077
|
+
wav: "audio/x-wav",
|
|
1078
|
+
m4a: "audio/mp4",
|
|
1079
|
+
ogg: "audio/ogg",
|
|
1080
|
+
wma: "audio/x-ms-wma"
|
|
1081
|
+
};
|
|
1082
|
+
const contentTypeForVideoFormat = (format) => VIDEO_CONTENT_TYPES[format];
|
|
1083
|
+
const contentTypeForAudioFormat = (format) => AUDIO_CONTENT_TYPES[format];
|
|
1084
|
+
const hasBytesAt = (bytes, at, signature) => {
|
|
1085
|
+
if (bytes.length < at + signature.length) return false;
|
|
1086
|
+
for (let i = 0; i < signature.length; i++) if (bytes[at + i] !== signature[i]) return false;
|
|
1087
|
+
return true;
|
|
1088
|
+
};
|
|
1089
|
+
const hasAsciiAt = (bytes, at, text) => hasBytesAt(bytes, at, Array.from(text, (ch) => ch.charCodeAt(0)));
|
|
1090
|
+
const isoBrand = (bytes) => hasAsciiAt(bytes, 4, "ftyp") && bytes.length >= 12 ? String.fromCharCode(bytes[8], bytes[9], bytes[10], bytes[11]) : null;
|
|
1091
|
+
const isRiff = (bytes, form) => hasAsciiAt(bytes, 0, "RIFF") && hasAsciiAt(bytes, 8, form);
|
|
1092
|
+
const ASF_HEADER = [
|
|
1093
|
+
48,
|
|
1094
|
+
38,
|
|
1095
|
+
178,
|
|
1096
|
+
117,
|
|
1097
|
+
142,
|
|
1098
|
+
102,
|
|
1099
|
+
207,
|
|
1100
|
+
17
|
|
1101
|
+
];
|
|
1102
|
+
const EBML_HEADER = [
|
|
1103
|
+
26,
|
|
1104
|
+
69,
|
|
1105
|
+
223,
|
|
1106
|
+
163
|
|
1107
|
+
];
|
|
1108
|
+
const EBML_DOCTYPE_WINDOW = 64;
|
|
1109
|
+
const isWebm = (bytes) => {
|
|
1110
|
+
if (!hasBytesAt(bytes, 0, EBML_HEADER)) return false;
|
|
1111
|
+
const limit = Math.min(bytes.length, EBML_DOCTYPE_WINDOW) - 4;
|
|
1112
|
+
for (let i = 4; i <= limit; i++) if (hasAsciiAt(bytes, i, "webm")) return true;
|
|
1113
|
+
return false;
|
|
1114
|
+
};
|
|
1115
|
+
/** Detects a video container, or `null` when no known signature matches. */
|
|
1116
|
+
const detectVideoFormat = (bytes) => {
|
|
1117
|
+
const brand = isoBrand(bytes);
|
|
1118
|
+
if (brand !== null) {
|
|
1119
|
+
if (brand === "qt ") return "mov";
|
|
1120
|
+
if (brand === "M4V ") return "m4v";
|
|
1121
|
+
return "mp4";
|
|
1122
|
+
}
|
|
1123
|
+
if (isWebm(bytes)) return "webm";
|
|
1124
|
+
if (isRiff(bytes, "AVI ")) return "avi";
|
|
1125
|
+
if (hasBytesAt(bytes, 0, ASF_HEADER)) return "wmv";
|
|
1126
|
+
return null;
|
|
1127
|
+
};
|
|
1128
|
+
/** Detects an audio container, or `null` when no known signature matches. */
|
|
1129
|
+
const detectAudioFormat = (bytes) => {
|
|
1130
|
+
if (isoBrand(bytes) !== null) return "m4a";
|
|
1131
|
+
if (isRiff(bytes, "WAVE")) return "wav";
|
|
1132
|
+
if (hasAsciiAt(bytes, 0, "OggS")) return "ogg";
|
|
1133
|
+
if (hasBytesAt(bytes, 0, ASF_HEADER)) return "wma";
|
|
1134
|
+
if (hasAsciiAt(bytes, 0, "ID3")) return "mp3";
|
|
1135
|
+
if (bytes.length >= 2 && bytes[0] === 255 && (bytes[1] & 224) === 224) return "mp3";
|
|
1136
|
+
return null;
|
|
1137
|
+
};
|
|
1138
|
+
//#endregion
|
|
1063
1139
|
//#region src/internal/parts/package.ts
|
|
1064
1140
|
const TEXT_DECODER$1 = new TextDecoder();
|
|
1065
1141
|
const TEXT_ENCODER$3 = new TextEncoder();
|
|
@@ -1382,7 +1458,7 @@ const savePresentation = (pres) => {
|
|
|
1382
1458
|
//#region src/internal/presentationml/relationship-types.ts
|
|
1383
1459
|
const OFFICE_DOC = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
1384
1460
|
const PACKAGE = "http://schemas.openxmlformats.org/package/2006/relationships";
|
|
1385
|
-
const
|
|
1461
|
+
const MS_2007 = "http://schemas.microsoft.com/office/2007/relationships";
|
|
1386
1462
|
const MS_2015 = "http://schemas.microsoft.com/office/2015/relationships";
|
|
1387
1463
|
const REL_TYPES = {
|
|
1388
1464
|
officeDocument: `${OFFICE_DOC}/officeDocument`,
|
|
@@ -1411,10 +1487,10 @@ const REL_TYPES = {
|
|
|
1411
1487
|
diagramLayout: `${OFFICE_DOC}/diagramLayout`,
|
|
1412
1488
|
diagramQuickStyle: `${OFFICE_DOC}/diagramQuickStyle`,
|
|
1413
1489
|
diagramColors: `${OFFICE_DOC}/diagramColors`,
|
|
1414
|
-
media: `${
|
|
1415
|
-
video: `${
|
|
1416
|
-
audio: `${
|
|
1417
|
-
font: `${
|
|
1490
|
+
media: `${MS_2007}/media`,
|
|
1491
|
+
video: `${OFFICE_DOC}/video`,
|
|
1492
|
+
audio: `${OFFICE_DOC}/audio`,
|
|
1493
|
+
font: `${OFFICE_DOC}/font`,
|
|
1418
1494
|
authors: `${MS_2015}/authors`,
|
|
1419
1495
|
modernComment: `${MS_2015}/comments`,
|
|
1420
1496
|
comments: `${OFFICE_DOC}/comments`,
|
|
@@ -1431,13 +1507,13 @@ const NAME_NOTES_MASTER_ID_LST = qname("p", "notesMasterIdLst", NS.pml);
|
|
|
1431
1507
|
const NAME_NOTES_MASTER_ID = qname("p", "notesMasterId", NS.pml);
|
|
1432
1508
|
const NAME_SLD_SZ = qname("p", "sldSz", NS.pml);
|
|
1433
1509
|
const NAME_NOTES_SZ = qname("p", "notesSz", NS.pml);
|
|
1434
|
-
const ATTR_ID$
|
|
1435
|
-
const ATTR_R_ID$
|
|
1510
|
+
const ATTR_ID$15 = qname("", "id", "");
|
|
1511
|
+
const ATTR_R_ID$4 = qname("r", "id", NS.officeDocRels);
|
|
1436
1512
|
const ATTR_CX$9 = qname("", "cx", "");
|
|
1437
1513
|
const ATTR_CY$9 = qname("", "cy", "");
|
|
1438
1514
|
const ATTR_TYPE$6 = qname("", "type", "");
|
|
1439
1515
|
const requireRId = (element, context) => {
|
|
1440
|
-
const value = getAttrValue(element, ATTR_R_ID$
|
|
1516
|
+
const value = getAttrValue(element, ATTR_R_ID$4);
|
|
1441
1517
|
if (value === null) throw new Error(`${context}: missing r:id attribute`);
|
|
1442
1518
|
return value;
|
|
1443
1519
|
};
|
|
@@ -1463,7 +1539,7 @@ const readPresentationPart = (root) => {
|
|
|
1463
1539
|
const sldMasters = [];
|
|
1464
1540
|
const sldMasterLst = firstChildElement(root, NAME_SLD_MASTER_ID_LST$1);
|
|
1465
1541
|
if (sldMasterLst !== null) for (const item of allChildElements(sldMasterLst, NAME_SLD_MASTER_ID)) {
|
|
1466
|
-
const idRaw = getAttrValue(item, ATTR_ID$
|
|
1542
|
+
const idRaw = getAttrValue(item, ATTR_ID$15);
|
|
1467
1543
|
if (idRaw === null) throw new Error("<p:sldMasterId>: missing id attribute");
|
|
1468
1544
|
sldMasters.push({
|
|
1469
1545
|
id: Number.parseInt(idRaw, 10),
|
|
@@ -1473,7 +1549,7 @@ const readPresentationPart = (root) => {
|
|
|
1473
1549
|
const slides = [];
|
|
1474
1550
|
const sldLst = firstChildElement(root, NAME_SLD_ID_LST$2);
|
|
1475
1551
|
if (sldLst !== null) for (const item of allChildElements(sldLst, NAME_SLD_ID$2)) {
|
|
1476
|
-
const idRaw = getAttrValue(item, ATTR_ID$
|
|
1552
|
+
const idRaw = getAttrValue(item, ATTR_ID$15);
|
|
1477
1553
|
if (idRaw === null) throw new Error("<p:sldId>: missing id attribute");
|
|
1478
1554
|
slides.push({
|
|
1479
1555
|
id: Number.parseInt(idRaw, 10),
|
|
@@ -1551,7 +1627,15 @@ const RANGES = {
|
|
|
1551
1627
|
overlap: [-100, 100],
|
|
1552
1628
|
gapAmount: [0, 500],
|
|
1553
1629
|
holeSize: [1, 90],
|
|
1554
|
-
firstSliceAng: [0, 360]
|
|
1630
|
+
firstSliceAng: [0, 360],
|
|
1631
|
+
rotX: [-90, 90],
|
|
1632
|
+
rotY: [0, 360],
|
|
1633
|
+
perspective: [0, 240],
|
|
1634
|
+
depthPercent: [20, 2e3],
|
|
1635
|
+
heightPercent: [5, 500],
|
|
1636
|
+
secondPieSize: [5, 200],
|
|
1637
|
+
bubbleScale: [0, 300],
|
|
1638
|
+
percent100000: [0, 1e5]
|
|
1555
1639
|
};
|
|
1556
1640
|
const boundedInt = (value, key, field) => {
|
|
1557
1641
|
if (!Number.isFinite(value)) throw new RangeError(`${field}: expected a finite number, got ${value}`);
|
|
@@ -2518,7 +2602,7 @@ const ATTR_WR = qname("", "wR", "");
|
|
|
2518
2602
|
const ATTR_HR = qname("", "hR", "");
|
|
2519
2603
|
const ATTR_ST_ANG = qname("", "stAng", "");
|
|
2520
2604
|
const ATTR_SW_ANG = qname("", "swAng", "");
|
|
2521
|
-
const ATTR_FILL$
|
|
2605
|
+
const ATTR_FILL$2 = qname("", "fill", "");
|
|
2522
2606
|
const ATTR_STROKE = qname("", "stroke", "");
|
|
2523
2607
|
const NAME_AV_LST$5 = qname("a", "avLst", NS.dml);
|
|
2524
2608
|
const NAME_GD_LST = qname("a", "gdLst", NS.dml);
|
|
@@ -2667,7 +2751,7 @@ const isPathFillMode = (s) => FILL_MODES.has(s);
|
|
|
2667
2751
|
const parsePath = (pathEl, guides) => {
|
|
2668
2752
|
const w = parseIntOrNull(getAttrValue(pathEl, ATTR_W$2));
|
|
2669
2753
|
const h = parseIntOrNull(getAttrValue(pathEl, ATTR_H$1));
|
|
2670
|
-
const fillRaw = getAttrValue(pathEl, ATTR_FILL$
|
|
2754
|
+
const fillRaw = getAttrValue(pathEl, ATTR_FILL$2);
|
|
2671
2755
|
const fill = fillRaw !== null && isPathFillMode(fillRaw) ? fillRaw : "norm";
|
|
2672
2756
|
const strokeRaw = getAttrValue(pathEl, ATTR_STROKE);
|
|
2673
2757
|
const stroke = !(strokeRaw === "0" || strokeRaw === "false");
|
|
@@ -2760,8 +2844,8 @@ const parseCustomGeometry = (custGeom, shapeW, shapeH) => {
|
|
|
2760
2844
|
//#region src/internal/drawingml/hyperlink.ts
|
|
2761
2845
|
NS.dml;
|
|
2762
2846
|
const NAME_RPR$4 = qname("a", "rPr", NS.dml);
|
|
2763
|
-
const NAME_HLINK_CLICK = qname("a", "hlinkClick", NS.dml);
|
|
2764
|
-
const ATTR_R_ID$
|
|
2847
|
+
const NAME_HLINK_CLICK$1 = qname("a", "hlinkClick", NS.dml);
|
|
2848
|
+
const ATTR_R_ID$3 = qname("r", "id", NS.officeDocRels);
|
|
2765
2849
|
/**
|
|
2766
2850
|
* Sets `<a:hlinkClick r:id="rIdN" [tooltip="…"]/>` inside the `<a:rPr>`
|
|
2767
2851
|
* of every run in `txBody`. Pass `null` for `rId` to remove an existing
|
|
@@ -2781,9 +2865,9 @@ const applyHyperlinkToAllRuns = (txBody, rId, tooltip) => {
|
|
|
2781
2865
|
}
|
|
2782
2866
|
rPr.children = rPr.children.filter((c) => !(c.kind === "element" && c.name.namespaceURI === NS.dml && c.name.localName === "hlinkClick"));
|
|
2783
2867
|
if (rId !== null) {
|
|
2784
|
-
const attrs = [attr(ATTR_R_ID$
|
|
2868
|
+
const attrs = [attr(ATTR_R_ID$3, rId)];
|
|
2785
2869
|
if (tooltip !== void 0) attrs.push(attr(qname("", "tooltip", ""), tooltip));
|
|
2786
|
-
rPr.children.push(elem(NAME_HLINK_CLICK, { attrs }));
|
|
2870
|
+
rPr.children.push(elem(NAME_HLINK_CLICK$1, { attrs }));
|
|
2787
2871
|
}
|
|
2788
2872
|
}
|
|
2789
2873
|
}
|
|
@@ -2792,7 +2876,7 @@ const applyHyperlinkToAllRuns = (txBody, rId, tooltip) => {
|
|
|
2792
2876
|
//#region src/internal/drawingml/picture-mutation.ts
|
|
2793
2877
|
const NAME_BLIP_FILL$1 = qname("p", "blipFill", NS.pml);
|
|
2794
2878
|
const NAME_BLIP$1 = qname("a", "blip", NS.dml);
|
|
2795
|
-
const ATTR_R_EMBED$
|
|
2879
|
+
const ATTR_R_EMBED$2 = qname("r", "embed", NS.officeDocRels);
|
|
2796
2880
|
/**
|
|
2797
2881
|
* Returns the `r:embed` rId on this picture shape's `a:blip`. Returns null
|
|
2798
2882
|
* if the shape has no blip fill, no blip, or no embed attribute (which
|
|
@@ -2803,7 +2887,7 @@ const getPictureEmbedRId = (picElement) => {
|
|
|
2803
2887
|
if (blipFill === null) return null;
|
|
2804
2888
|
const blip = firstChildElement(blipFill, NAME_BLIP$1);
|
|
2805
2889
|
if (blip === null) return null;
|
|
2806
|
-
return getAttrValue(blip, ATTR_R_EMBED$
|
|
2890
|
+
return getAttrValue(blip, ATTR_R_EMBED$2);
|
|
2807
2891
|
};
|
|
2808
2892
|
//#endregion
|
|
2809
2893
|
//#region src/internal/drawingml/geometry.ts
|
|
@@ -2812,7 +2896,7 @@ const NAME_GRP_SP_PR$4 = qname("p", "grpSpPr", NS.pml);
|
|
|
2812
2896
|
const NAME_A_XFRM$6 = qname("a", "xfrm", NS.dml);
|
|
2813
2897
|
const NAME_P_XFRM$2 = qname("p", "xfrm", NS.pml);
|
|
2814
2898
|
const NAME_OFF$8 = qname("a", "off", NS.dml);
|
|
2815
|
-
const NAME_EXT$
|
|
2899
|
+
const NAME_EXT$9 = qname("a", "ext", NS.dml);
|
|
2816
2900
|
const ATTR_X$8 = qname("", "x", "");
|
|
2817
2901
|
const ATTR_Y$8 = qname("", "y", "");
|
|
2818
2902
|
const ATTR_CX$8 = qname("", "cx", "");
|
|
@@ -2853,7 +2937,7 @@ const readPosition = (shape, kind) => {
|
|
|
2853
2937
|
const readSize = (shape, kind) => {
|
|
2854
2938
|
const xfrm = findTransform(shape, kind);
|
|
2855
2939
|
if (xfrm === null) return null;
|
|
2856
|
-
const ext = firstChildElement(xfrm, NAME_EXT$
|
|
2940
|
+
const ext = firstChildElement(xfrm, NAME_EXT$9);
|
|
2857
2941
|
if (ext === null) return null;
|
|
2858
2942
|
const w = parseIntOr(getAttrValue(ext, ATTR_CX$8));
|
|
2859
2943
|
const h = parseIntOr(getAttrValue(ext, ATTR_CY$8));
|
|
@@ -2893,7 +2977,7 @@ const NAME_GRP_SP_PR$3 = qname("p", "grpSpPr", NS.pml);
|
|
|
2893
2977
|
const NAME_A_XFRM$5 = qname("a", "xfrm", NS.dml);
|
|
2894
2978
|
const NAME_P_XFRM$1 = qname("p", "xfrm", NS.pml);
|
|
2895
2979
|
const NAME_OFF$7 = qname("a", "off", NS.dml);
|
|
2896
|
-
const NAME_EXT$
|
|
2980
|
+
const NAME_EXT$8 = qname("a", "ext", NS.dml);
|
|
2897
2981
|
const ATTR_X$7 = qname("", "x", "");
|
|
2898
2982
|
const ATTR_Y$7 = qname("", "y", "");
|
|
2899
2983
|
const ATTR_CX$7 = qname("", "cx", "");
|
|
@@ -2939,9 +3023,9 @@ const setPosition = (shape, kind, x, y) => {
|
|
|
2939
3023
|
/** Sets the shape's `<a:ext>` to `(w, h)` in EMU. */
|
|
2940
3024
|
const setSize = (shape, kind, w, h) => {
|
|
2941
3025
|
const xfrm = ensureTransform(shape, kind);
|
|
2942
|
-
let ext = firstChildElement(xfrm, NAME_EXT$
|
|
3026
|
+
let ext = firstChildElement(xfrm, NAME_EXT$8);
|
|
2943
3027
|
if (ext === null) {
|
|
2944
|
-
ext = elem(NAME_EXT$
|
|
3028
|
+
ext = elem(NAME_EXT$8);
|
|
2945
3029
|
const offIdx = xfrm.children.findIndex((c) => c.kind === "element" && c.name.localName === "off" && c.name.namespaceURI === NS.dml);
|
|
2946
3030
|
if (offIdx >= 0) xfrm.children.splice(offIdx + 1, 0, ext);
|
|
2947
3031
|
else xfrm.children.push(ext);
|
|
@@ -3013,21 +3097,21 @@ const setAdjustValues = (shape, values) => {
|
|
|
3013
3097
|
const NAME_CSLD$4 = qname("p", "cSld", NS.pml);
|
|
3014
3098
|
const NAME_SP_TREE$3 = qname("p", "spTree", NS.pml);
|
|
3015
3099
|
const NAME_NV_SP_PR$4 = qname("p", "nvSpPr", NS.pml);
|
|
3016
|
-
const NAME_NV_PIC_PR$
|
|
3100
|
+
const NAME_NV_PIC_PR$2 = qname("p", "nvPicPr", NS.pml);
|
|
3017
3101
|
const NAME_NV_GRP_SP_PR$3 = qname("p", "nvGrpSpPr", NS.pml);
|
|
3018
3102
|
const NAME_NV_GRAPHIC_FRAME_PR$2 = qname("p", "nvGraphicFramePr", NS.pml);
|
|
3019
3103
|
const NAME_NV_CXN_SP_PR$1 = qname("p", "nvCxnSpPr", NS.pml);
|
|
3020
|
-
const NAME_C_NV_PR$
|
|
3021
|
-
const NAME_NV_PR$
|
|
3104
|
+
const NAME_C_NV_PR$9 = qname("p", "cNvPr", NS.pml);
|
|
3105
|
+
const NAME_NV_PR$10 = qname("p", "nvPr", NS.pml);
|
|
3022
3106
|
const NAME_PH$2 = qname("p", "ph", NS.pml);
|
|
3023
3107
|
const NAME_TX_BODY$9 = qname("p", "txBody", NS.pml);
|
|
3024
|
-
const ATTR_ID$
|
|
3108
|
+
const ATTR_ID$14 = qname("", "id", "");
|
|
3025
3109
|
const ATTR_NAME$11 = qname("", "name", "");
|
|
3026
3110
|
const ATTR_TYPE$4 = qname("", "type", "");
|
|
3027
3111
|
const ATTR_IDX$6 = qname("", "idx", "");
|
|
3028
3112
|
const NV_BY_KIND = {
|
|
3029
3113
|
shape: NAME_NV_SP_PR$4,
|
|
3030
|
-
picture: NAME_NV_PIC_PR$
|
|
3114
|
+
picture: NAME_NV_PIC_PR$2,
|
|
3031
3115
|
group: NAME_NV_GRP_SP_PR$3,
|
|
3032
3116
|
graphicFrame: NAME_NV_GRAPHIC_FRAME_PR$2,
|
|
3033
3117
|
connector: NAME_NV_CXN_SP_PR$1
|
|
@@ -3050,14 +3134,14 @@ const extractShape = (element, kind) => {
|
|
|
3050
3134
|
let placeholderType = null;
|
|
3051
3135
|
let placeholderIdx = null;
|
|
3052
3136
|
if (nvContainer !== null) {
|
|
3053
|
-
const cNvPr = firstChildElement(nvContainer, NAME_C_NV_PR$
|
|
3137
|
+
const cNvPr = firstChildElement(nvContainer, NAME_C_NV_PR$9);
|
|
3054
3138
|
if (cNvPr !== null) {
|
|
3055
|
-
const idRaw = getAttrValue(cNvPr, ATTR_ID$
|
|
3139
|
+
const idRaw = getAttrValue(cNvPr, ATTR_ID$14);
|
|
3056
3140
|
if (idRaw !== null) id = Number.parseInt(idRaw, 10);
|
|
3057
3141
|
const nameRaw = getAttrValue(cNvPr, ATTR_NAME$11);
|
|
3058
3142
|
if (nameRaw !== null) name = nameRaw;
|
|
3059
3143
|
}
|
|
3060
|
-
const nvPr = firstChildElement(nvContainer, NAME_NV_PR$
|
|
3144
|
+
const nvPr = firstChildElement(nvContainer, NAME_NV_PR$10);
|
|
3061
3145
|
if (nvPr !== null) {
|
|
3062
3146
|
const ph = firstChildElement(nvPr, NAME_PH$2);
|
|
3063
3147
|
if (ph !== null) {
|
|
@@ -3165,9 +3249,9 @@ const NAME_SLD = qname("p", "sld", NS.pml);
|
|
|
3165
3249
|
const NAME_CSLD$2 = qname("p", "cSld", NS.pml);
|
|
3166
3250
|
const NAME_SP_TREE$2 = qname("p", "spTree", NS.pml);
|
|
3167
3251
|
const NAME_NV_GRP_SP_PR$2 = qname("p", "nvGrpSpPr", NS.pml);
|
|
3168
|
-
const NAME_C_NV_PR$
|
|
3252
|
+
const NAME_C_NV_PR$8 = qname("p", "cNvPr", NS.pml);
|
|
3169
3253
|
const NAME_C_NV_GRP_SP_PR$2 = qname("p", "cNvGrpSpPr", NS.pml);
|
|
3170
|
-
const NAME_NV_PR$
|
|
3254
|
+
const NAME_NV_PR$9 = qname("p", "nvPr", NS.pml);
|
|
3171
3255
|
const NAME_GRP_SP_PR$2 = qname("p", "grpSpPr", NS.pml);
|
|
3172
3256
|
const NAME_SP$3 = qname("p", "sp", NS.pml);
|
|
3173
3257
|
const NAME_NV_SP_PR$3 = qname("p", "nvSpPr", NS.pml);
|
|
@@ -3179,7 +3263,7 @@ const NAME_BODY_PR$4 = qname("a", "bodyPr", NS.dml);
|
|
|
3179
3263
|
const NAME_LST_STYLE$4 = qname("a", "lstStyle", NS.dml);
|
|
3180
3264
|
const NAME_P$4 = qname("a", "p", NS.dml);
|
|
3181
3265
|
const NAME_SP_LOCKS$1 = qname("a", "spLocks", NS.dml);
|
|
3182
|
-
const ATTR_ID$
|
|
3266
|
+
const ATTR_ID$13 = qname("", "id", "");
|
|
3183
3267
|
const ATTR_NAME$9 = qname("", "name", "");
|
|
3184
3268
|
const ATTR_TYPE$2 = qname("", "type", "");
|
|
3185
3269
|
const ATTR_IDX$5 = qname("", "idx", "");
|
|
@@ -3200,7 +3284,7 @@ const buildSlideFromLayout = (layoutSpTree) => {
|
|
|
3200
3284
|
if (child.name.namespaceURI !== NS.pml || child.name.localName !== "sp") continue;
|
|
3201
3285
|
const nvSpPr = firstChildElement(child, NAME_NV_SP_PR$3);
|
|
3202
3286
|
if (nvSpPr === null) continue;
|
|
3203
|
-
const nvPr = firstChildElement(nvSpPr, NAME_NV_PR$
|
|
3287
|
+
const nvPr = firstChildElement(nvSpPr, NAME_NV_PR$9);
|
|
3204
3288
|
if (nvPr === null) continue;
|
|
3205
3289
|
const ph = firstChildElement(nvPr, NAME_PH$1);
|
|
3206
3290
|
if (ph === null) continue;
|
|
@@ -3240,21 +3324,21 @@ const buildSlideFromLayout = (layoutSpTree) => {
|
|
|
3240
3324
|
};
|
|
3241
3325
|
};
|
|
3242
3326
|
const buildNvGrpSpPr = (id) => elem(NAME_NV_GRP_SP_PR$2, { children: [
|
|
3243
|
-
elem(NAME_C_NV_PR$
|
|
3327
|
+
elem(NAME_C_NV_PR$8, { attrs: [attr(ATTR_ID$13, String(id)), attr(ATTR_NAME$9, "")] }),
|
|
3244
3328
|
elem(NAME_C_NV_GRP_SP_PR$2),
|
|
3245
|
-
elem(NAME_NV_PR$
|
|
3329
|
+
elem(NAME_NV_PR$9)
|
|
3246
3330
|
] });
|
|
3247
3331
|
const buildGrpSpPr = () => elem(NAME_GRP_SP_PR$2);
|
|
3248
3332
|
const buildPlaceholderStub = (id, phType, phIdx) => {
|
|
3249
3333
|
const phAttrs = [];
|
|
3250
3334
|
if (phType !== null) phAttrs.push(attr(ATTR_TYPE$2, phType));
|
|
3251
3335
|
if (phIdx !== null) phAttrs.push(attr(ATTR_IDX$5, phIdx));
|
|
3252
|
-
const nvPr = elem(NAME_NV_PR$
|
|
3336
|
+
const nvPr = elem(NAME_NV_PR$9, { children: [elem(NAME_PH$1, { attrs: phAttrs })] });
|
|
3253
3337
|
const cNvSpPr = elem(NAME_C_NV_SP_PR$3, { children: [elem(NAME_SP_LOCKS$1, { attrs: [attr(ATTR_NO_GRP$2, "1")] })] });
|
|
3254
3338
|
const name = inferPlaceholderName(id, phType);
|
|
3255
3339
|
return elem(NAME_SP$3, { children: [
|
|
3256
3340
|
elem(NAME_NV_SP_PR$3, { children: [
|
|
3257
|
-
elem(NAME_C_NV_PR$
|
|
3341
|
+
elem(NAME_C_NV_PR$8, { attrs: [attr(ATTR_ID$13, String(id)), attr(ATTR_NAME$9, name)] }),
|
|
3258
3342
|
cNvSpPr,
|
|
3259
3343
|
nvPr
|
|
3260
3344
|
] }),
|
|
@@ -3290,14 +3374,14 @@ const inferPlaceholderName = (id, phType) => {
|
|
|
3290
3374
|
//#region src/internal/presentationml/text-box-builder.ts
|
|
3291
3375
|
const NAME_SP$2 = qname("p", "sp", NS.pml);
|
|
3292
3376
|
const NAME_NV_SP_PR$2 = qname("p", "nvSpPr", NS.pml);
|
|
3293
|
-
const NAME_C_NV_PR$
|
|
3377
|
+
const NAME_C_NV_PR$7 = qname("p", "cNvPr", NS.pml);
|
|
3294
3378
|
const NAME_C_NV_SP_PR$2 = qname("p", "cNvSpPr", NS.pml);
|
|
3295
|
-
const NAME_NV_PR$
|
|
3379
|
+
const NAME_NV_PR$8 = qname("p", "nvPr", NS.pml);
|
|
3296
3380
|
const NAME_SP_PR$4 = qname("p", "spPr", NS.pml);
|
|
3297
3381
|
const NAME_TX_BODY$7 = qname("p", "txBody", NS.pml);
|
|
3298
3382
|
const NAME_A_XFRM$4 = qname("a", "xfrm", NS.dml);
|
|
3299
3383
|
const NAME_OFF$6 = qname("a", "off", NS.dml);
|
|
3300
|
-
const NAME_EXT$
|
|
3384
|
+
const NAME_EXT$7 = qname("a", "ext", NS.dml);
|
|
3301
3385
|
const NAME_PRST_GEOM$3 = qname("a", "prstGeom", NS.dml);
|
|
3302
3386
|
const NAME_AV_LST$3 = qname("a", "avLst", NS.dml);
|
|
3303
3387
|
const NAME_NO_FILL = qname("a", "noFill", NS.dml);
|
|
@@ -3307,7 +3391,7 @@ const NAME_P$3 = qname("a", "p", NS.dml);
|
|
|
3307
3391
|
const NAME_R$3 = qname("a", "r", NS.dml);
|
|
3308
3392
|
const NAME_RPR$3 = qname("a", "rPr", NS.dml);
|
|
3309
3393
|
const NAME_T$4 = qname("a", "t", NS.dml);
|
|
3310
|
-
const ATTR_ID$
|
|
3394
|
+
const ATTR_ID$12 = qname("", "id", "");
|
|
3311
3395
|
const ATTR_NAME$8 = qname("", "name", "");
|
|
3312
3396
|
const ATTR_TX_BOX$1 = qname("", "txBox", "");
|
|
3313
3397
|
const ATTR_X$6 = qname("", "x", "");
|
|
@@ -3328,12 +3412,12 @@ NS.xml;
|
|
|
3328
3412
|
const buildTextBox = (opts) => {
|
|
3329
3413
|
const name = opts.name ?? `TextBox ${opts.id}`;
|
|
3330
3414
|
const nvSpPr = elem(NAME_NV_SP_PR$2, { children: [
|
|
3331
|
-
elem(NAME_C_NV_PR$
|
|
3415
|
+
elem(NAME_C_NV_PR$7, { attrs: [attr(ATTR_ID$12, String(opts.id)), attr(ATTR_NAME$8, name)] }),
|
|
3332
3416
|
elem(NAME_C_NV_SP_PR$2, { attrs: [attr(ATTR_TX_BOX$1, "1")] }),
|
|
3333
|
-
elem(NAME_NV_PR$
|
|
3417
|
+
elem(NAME_NV_PR$8)
|
|
3334
3418
|
] });
|
|
3335
3419
|
const spPr = elem(NAME_SP_PR$4, { children: [
|
|
3336
|
-
elem(NAME_A_XFRM$4, { children: [elem(NAME_OFF$6, { attrs: [attr(ATTR_X$6, String(emuCoordinate(opts.x, "addSlideTextBox: x"))), attr(ATTR_Y$6, String(emuCoordinate(opts.y, "addSlideTextBox: y")))] }), elem(NAME_EXT$
|
|
3420
|
+
elem(NAME_A_XFRM$4, { children: [elem(NAME_OFF$6, { attrs: [attr(ATTR_X$6, String(emuCoordinate(opts.x, "addSlideTextBox: x"))), attr(ATTR_Y$6, String(emuCoordinate(opts.y, "addSlideTextBox: y")))] }), elem(NAME_EXT$7, { attrs: [attr(ATTR_CX$6, String(emuExtent(opts.w, "addSlideTextBox: w"))), attr(ATTR_CY$6, String(emuExtent(opts.h, "addSlideTextBox: h")))] })] }),
|
|
3337
3421
|
elem(NAME_PRST_GEOM$3, {
|
|
3338
3422
|
attrs: [attr(ATTR_PRST$3, "rect")],
|
|
3339
3423
|
children: [elem(NAME_AV_LST$3)]
|
|
@@ -3358,14 +3442,14 @@ const buildTextBox = (opts) => {
|
|
|
3358
3442
|
//#region src/internal/presentationml/shape-builder.ts
|
|
3359
3443
|
const NAME_SP$1 = qname("p", "sp", NS.pml);
|
|
3360
3444
|
const NAME_NV_SP_PR$1 = qname("p", "nvSpPr", NS.pml);
|
|
3361
|
-
const NAME_C_NV_PR$
|
|
3445
|
+
const NAME_C_NV_PR$6 = qname("p", "cNvPr", NS.pml);
|
|
3362
3446
|
const NAME_C_NV_SP_PR$1 = qname("p", "cNvSpPr", NS.pml);
|
|
3363
|
-
const NAME_NV_PR$
|
|
3447
|
+
const NAME_NV_PR$7 = qname("p", "nvPr", NS.pml);
|
|
3364
3448
|
const NAME_SP_PR$3 = qname("p", "spPr", NS.pml);
|
|
3365
3449
|
const NAME_TX_BODY$6 = qname("p", "txBody", NS.pml);
|
|
3366
3450
|
const NAME_A_XFRM$3 = qname("a", "xfrm", NS.dml);
|
|
3367
3451
|
const NAME_OFF$5 = qname("a", "off", NS.dml);
|
|
3368
|
-
const NAME_EXT$
|
|
3452
|
+
const NAME_EXT$6 = qname("a", "ext", NS.dml);
|
|
3369
3453
|
const NAME_PRST_GEOM$2 = qname("a", "prstGeom", NS.dml);
|
|
3370
3454
|
const NAME_AV_LST$2 = qname("a", "avLst", NS.dml);
|
|
3371
3455
|
const NAME_BODY_PR$2 = qname("a", "bodyPr", NS.dml);
|
|
@@ -3374,7 +3458,7 @@ const NAME_P$2 = qname("a", "p", NS.dml);
|
|
|
3374
3458
|
const NAME_R$2 = qname("a", "r", NS.dml);
|
|
3375
3459
|
const NAME_RPR$2 = qname("a", "rPr", NS.dml);
|
|
3376
3460
|
const NAME_T$3 = qname("a", "t", NS.dml);
|
|
3377
|
-
const ATTR_ID$
|
|
3461
|
+
const ATTR_ID$11 = qname("", "id", "");
|
|
3378
3462
|
const ATTR_NAME$7 = qname("", "name", "");
|
|
3379
3463
|
const ATTR_X$5 = qname("", "x", "");
|
|
3380
3464
|
const ATTR_Y$5 = qname("", "y", "");
|
|
@@ -3406,10 +3490,10 @@ const buildShape = (opts) => {
|
|
|
3406
3490
|
const name = opts.name ?? `${opts.preset} ${opts.id}`;
|
|
3407
3491
|
const anchor = opts.textAnchor ?? "ctr";
|
|
3408
3492
|
const children = [elem(NAME_NV_SP_PR$1, { children: [
|
|
3409
|
-
elem(NAME_C_NV_PR$
|
|
3493
|
+
elem(NAME_C_NV_PR$6, { attrs: [attr(ATTR_ID$11, String(opts.id)), attr(ATTR_NAME$7, name)] }),
|
|
3410
3494
|
elem(NAME_C_NV_SP_PR$1),
|
|
3411
|
-
elem(NAME_NV_PR$
|
|
3412
|
-
] }), elem(NAME_SP_PR$3, { children: [elem(NAME_A_XFRM$3, { children: [elem(NAME_OFF$5, { attrs: [attr(ATTR_X$5, String(emuCoordinate(opts.x, "addSlideShape: x"))), attr(ATTR_Y$5, String(emuCoordinate(opts.y, "addSlideShape: y")))] }), elem(NAME_EXT$
|
|
3495
|
+
elem(NAME_NV_PR$7)
|
|
3496
|
+
] }), elem(NAME_SP_PR$3, { children: [elem(NAME_A_XFRM$3, { children: [elem(NAME_OFF$5, { attrs: [attr(ATTR_X$5, String(emuCoordinate(opts.x, "addSlideShape: x"))), attr(ATTR_Y$5, String(emuCoordinate(opts.y, "addSlideShape: y")))] }), elem(NAME_EXT$6, { attrs: [attr(ATTR_CX$5, String(emuExtent(opts.w, "addSlideShape: w"))), attr(ATTR_CY$5, String(emuExtent(opts.h, "addSlideShape: h")))] })] }), elem(NAME_PRST_GEOM$2, {
|
|
3413
3497
|
attrs: [attr(ATTR_PRST$2, opts.preset)],
|
|
3414
3498
|
children: [elem(NAME_AV_LST$2)]
|
|
3415
3499
|
})] })];
|
|
@@ -3421,13 +3505,13 @@ const buildShape = (opts) => {
|
|
|
3421
3505
|
//#region src/internal/presentationml/connector-builder.ts
|
|
3422
3506
|
const NAME_CXN_SP = qname("p", "cxnSp", NS.pml);
|
|
3423
3507
|
const NAME_NV_CXN_SP_PR = qname("p", "nvCxnSpPr", NS.pml);
|
|
3424
|
-
const NAME_C_NV_PR$
|
|
3508
|
+
const NAME_C_NV_PR$5 = qname("p", "cNvPr", NS.pml);
|
|
3425
3509
|
const NAME_C_NV_CXN_SP_PR = qname("p", "cNvCxnSpPr", NS.pml);
|
|
3426
|
-
const NAME_NV_PR$
|
|
3510
|
+
const NAME_NV_PR$6 = qname("p", "nvPr", NS.pml);
|
|
3427
3511
|
const NAME_SP_PR$2 = qname("p", "spPr", NS.pml);
|
|
3428
3512
|
const NAME_A_XFRM$2 = qname("a", "xfrm", NS.dml);
|
|
3429
3513
|
const NAME_OFF$4 = qname("a", "off", NS.dml);
|
|
3430
|
-
const NAME_EXT$
|
|
3514
|
+
const NAME_EXT$5 = qname("a", "ext", NS.dml);
|
|
3431
3515
|
const NAME_PRST_GEOM$1 = qname("a", "prstGeom", NS.dml);
|
|
3432
3516
|
const NAME_AV_LST$1 = qname("a", "avLst", NS.dml);
|
|
3433
3517
|
const NAME_LN = qname("a", "ln", NS.dml);
|
|
@@ -3440,7 +3524,7 @@ const NAME_FONT_REF = qname("a", "fontRef", NS.dml);
|
|
|
3440
3524
|
const NAME_SCHEME_CLR = qname("a", "schemeClr", NS.dml);
|
|
3441
3525
|
const ATTR_IDX$4 = qname("", "idx", "");
|
|
3442
3526
|
const ATTR_VAL$5 = qname("", "val", "");
|
|
3443
|
-
const ATTR_ID$
|
|
3527
|
+
const ATTR_ID$10 = qname("", "id", "");
|
|
3444
3528
|
const ATTR_NAME$6 = qname("", "name", "");
|
|
3445
3529
|
const ATTR_X$4 = qname("", "x", "");
|
|
3446
3530
|
const ATTR_Y$4 = qname("", "y", "");
|
|
@@ -3454,9 +3538,9 @@ const ATTR_FLIP_V = qname("", "flipV", "");
|
|
|
3454
3538
|
const buildConnector = (opts) => {
|
|
3455
3539
|
const name = opts.name ?? `Straight Connector ${opts.id}`;
|
|
3456
3540
|
const nvCxnSpPr = elem(NAME_NV_CXN_SP_PR, { children: [
|
|
3457
|
-
elem(NAME_C_NV_PR$
|
|
3541
|
+
elem(NAME_C_NV_PR$5, { attrs: [attr(ATTR_ID$10, String(opts.id)), attr(ATTR_NAME$6, name)] }),
|
|
3458
3542
|
elem(NAME_C_NV_CXN_SP_PR),
|
|
3459
|
-
elem(NAME_NV_PR$
|
|
3543
|
+
elem(NAME_NV_PR$6)
|
|
3460
3544
|
] });
|
|
3461
3545
|
const x = Math.min(opts.from.x, opts.to.x);
|
|
3462
3546
|
const y = Math.min(opts.from.y, opts.to.y);
|
|
@@ -3469,7 +3553,7 @@ const buildConnector = (opts) => {
|
|
|
3469
3553
|
if (flipV) xfrmAttrs.push(attr(ATTR_FLIP_V, "1"));
|
|
3470
3554
|
const xfrm = elem(NAME_A_XFRM$2, {
|
|
3471
3555
|
attrs: xfrmAttrs,
|
|
3472
|
-
children: [elem(NAME_OFF$4, { attrs: [attr(ATTR_X$4, String(emuCoordinate(x, "addSlideLine: x"))), attr(ATTR_Y$4, String(emuCoordinate(y, "addSlideLine: y")))] }), elem(NAME_EXT$
|
|
3556
|
+
children: [elem(NAME_OFF$4, { attrs: [attr(ATTR_X$4, String(emuCoordinate(x, "addSlideLine: x"))), attr(ATTR_Y$4, String(emuCoordinate(y, "addSlideLine: y")))] }), elem(NAME_EXT$5, { attrs: [attr(ATTR_CX$4, String(emuExtent(cx, "addSlideLine: width"))), attr(ATTR_CY$4, String(emuExtent(cy, "addSlideLine: height")))] })]
|
|
3473
3557
|
});
|
|
3474
3558
|
const prstGeom = elem(NAME_PRST_GEOM$1, {
|
|
3475
3559
|
attrs: [attr(ATTR_PRST$1, "line")],
|
|
@@ -3503,16 +3587,16 @@ const buildConnector = (opts) => {
|
|
|
3503
3587
|
//#region src/internal/presentationml/group-builder.ts
|
|
3504
3588
|
const NAME_GRP_SP = qname("p", "grpSp", NS.pml);
|
|
3505
3589
|
const NAME_NV_GRP_SP_PR$1 = qname("p", "nvGrpSpPr", NS.pml);
|
|
3506
|
-
const NAME_C_NV_PR$
|
|
3590
|
+
const NAME_C_NV_PR$4 = qname("p", "cNvPr", NS.pml);
|
|
3507
3591
|
const NAME_C_NV_GRP_SP_PR$1 = qname("p", "cNvGrpSpPr", NS.pml);
|
|
3508
|
-
const NAME_NV_PR$
|
|
3592
|
+
const NAME_NV_PR$5 = qname("p", "nvPr", NS.pml);
|
|
3509
3593
|
const NAME_GRP_SP_PR$1 = qname("p", "grpSpPr", NS.pml);
|
|
3510
3594
|
const NAME_A_XFRM$1 = qname("a", "xfrm", NS.dml);
|
|
3511
3595
|
const NAME_OFF$3 = qname("a", "off", NS.dml);
|
|
3512
|
-
const NAME_EXT$
|
|
3596
|
+
const NAME_EXT$4 = qname("a", "ext", NS.dml);
|
|
3513
3597
|
const NAME_CH_OFF = qname("a", "chOff", NS.dml);
|
|
3514
3598
|
const NAME_CH_EXT = qname("a", "chExt", NS.dml);
|
|
3515
|
-
const ATTR_ID$
|
|
3599
|
+
const ATTR_ID$9 = qname("", "id", "");
|
|
3516
3600
|
const ATTR_NAME$5 = qname("", "name", "");
|
|
3517
3601
|
const ATTR_X$3 = qname("", "x", "");
|
|
3518
3602
|
const ATTR_Y$3 = qname("", "y", "");
|
|
@@ -3522,9 +3606,9 @@ const ATTR_CY$3 = qname("", "cy", "");
|
|
|
3522
3606
|
const buildGroup = (opts) => {
|
|
3523
3607
|
const name = opts.name ?? `Group ${opts.id}`;
|
|
3524
3608
|
const nvGrpSpPr = elem(NAME_NV_GRP_SP_PR$1, { children: [
|
|
3525
|
-
elem(NAME_C_NV_PR$
|
|
3609
|
+
elem(NAME_C_NV_PR$4, { attrs: [attr(ATTR_ID$9, String(opts.id)), attr(ATTR_NAME$5, name)] }),
|
|
3526
3610
|
elem(NAME_C_NV_GRP_SP_PR$1),
|
|
3527
|
-
elem(NAME_NV_PR$
|
|
3611
|
+
elem(NAME_NV_PR$5)
|
|
3528
3612
|
] });
|
|
3529
3613
|
const x = emuCoordinate(opts.x, "groupShapes: x");
|
|
3530
3614
|
const y = emuCoordinate(opts.y, "groupShapes: y");
|
|
@@ -3534,7 +3618,7 @@ const buildGroup = (opts) => {
|
|
|
3534
3618
|
nvGrpSpPr,
|
|
3535
3619
|
elem(NAME_GRP_SP_PR$1, { children: [elem(NAME_A_XFRM$1, { children: [
|
|
3536
3620
|
elem(NAME_OFF$3, { attrs: [attr(ATTR_X$3, String(x)), attr(ATTR_Y$3, String(y))] }),
|
|
3537
|
-
elem(NAME_EXT$
|
|
3621
|
+
elem(NAME_EXT$4, { attrs: [attr(ATTR_CX$3, String(cx)), attr(ATTR_CY$3, String(cy))] }),
|
|
3538
3622
|
elem(NAME_CH_OFF, { attrs: [attr(ATTR_X$3, String(x)), attr(ATTR_Y$3, String(y))] }),
|
|
3539
3623
|
elem(NAME_CH_EXT, { attrs: [attr(ATTR_CX$3, String(cx)), attr(ATTR_CY$3, String(cy))] })
|
|
3540
3624
|
] })] }),
|
|
@@ -3544,10 +3628,10 @@ const buildGroup = (opts) => {
|
|
|
3544
3628
|
//#endregion
|
|
3545
3629
|
//#region src/internal/presentationml/picture-builder.ts
|
|
3546
3630
|
const NAME_PIC = qname("p", "pic", NS.pml);
|
|
3547
|
-
const NAME_NV_PIC_PR = qname("p", "nvPicPr", NS.pml);
|
|
3548
|
-
const NAME_C_NV_PR$
|
|
3631
|
+
const NAME_NV_PIC_PR$1 = qname("p", "nvPicPr", NS.pml);
|
|
3632
|
+
const NAME_C_NV_PR$3 = qname("p", "cNvPr", NS.pml);
|
|
3549
3633
|
const NAME_C_NV_PIC_PR = qname("p", "cNvPicPr", NS.pml);
|
|
3550
|
-
const NAME_NV_PR$
|
|
3634
|
+
const NAME_NV_PR$4 = qname("p", "nvPr", NS.pml);
|
|
3551
3635
|
const NAME_BLIP_FILL = qname("p", "blipFill", NS.pml);
|
|
3552
3636
|
const NAME_BLIP = qname("a", "blip", NS.dml);
|
|
3553
3637
|
const NAME_STRETCH = qname("a", "stretch", NS.dml);
|
|
@@ -3555,37 +3639,175 @@ const NAME_FILL_RECT = qname("a", "fillRect", NS.dml);
|
|
|
3555
3639
|
const NAME_SP_PR$1 = qname("p", "spPr", NS.pml);
|
|
3556
3640
|
const NAME_A_XFRM = qname("a", "xfrm", NS.dml);
|
|
3557
3641
|
const NAME_OFF$2 = qname("a", "off", NS.dml);
|
|
3558
|
-
const NAME_EXT$
|
|
3642
|
+
const NAME_EXT$3 = qname("a", "ext", NS.dml);
|
|
3559
3643
|
const NAME_PRST_GEOM = qname("a", "prstGeom", NS.dml);
|
|
3560
3644
|
const NAME_AV_LST = qname("a", "avLst", NS.dml);
|
|
3561
3645
|
const NAME_PIC_LOCKS = qname("a", "picLocks", NS.dml);
|
|
3562
|
-
const ATTR_ID$
|
|
3646
|
+
const ATTR_ID$8 = qname("", "id", "");
|
|
3563
3647
|
const ATTR_NAME$4 = qname("", "name", "");
|
|
3564
3648
|
const ATTR_X$2 = qname("", "x", "");
|
|
3565
3649
|
const ATTR_Y$2 = qname("", "y", "");
|
|
3566
3650
|
const ATTR_CX$2 = qname("", "cx", "");
|
|
3567
3651
|
const ATTR_CY$2 = qname("", "cy", "");
|
|
3568
3652
|
const ATTR_PRST = qname("", "prst", "");
|
|
3569
|
-
const ATTR_R_EMBED = qname("r", "embed", NS.officeDocRels);
|
|
3653
|
+
const ATTR_R_EMBED$1 = qname("r", "embed", NS.officeDocRels);
|
|
3570
3654
|
const ATTR_NO_CHANGE_ASPECT$1 = qname("", "noChangeAspect", "");
|
|
3571
3655
|
/** Returns a `<p:pic>` element ready to be appended to a slide's `<p:spTree>`. */
|
|
3572
3656
|
const buildPicture = (opts) => {
|
|
3573
3657
|
const name = opts.name ?? `Picture ${opts.id}`;
|
|
3574
3658
|
const cNvPicPr = elem(NAME_C_NV_PIC_PR, { children: [elem(NAME_PIC_LOCKS, { attrs: opts.lockAspect ?? true ? [attr(ATTR_NO_CHANGE_ASPECT$1, "1")] : [] })] });
|
|
3575
3659
|
return elem(NAME_PIC, { children: [
|
|
3576
|
-
elem(NAME_NV_PIC_PR, { children: [
|
|
3577
|
-
elem(NAME_C_NV_PR$
|
|
3660
|
+
elem(NAME_NV_PIC_PR$1, { children: [
|
|
3661
|
+
elem(NAME_C_NV_PR$3, { attrs: [attr(ATTR_ID$8, String(opts.id)), attr(ATTR_NAME$4, name)] }),
|
|
3578
3662
|
cNvPicPr,
|
|
3579
|
-
elem(NAME_NV_PR$
|
|
3663
|
+
elem(NAME_NV_PR$4)
|
|
3580
3664
|
] }),
|
|
3581
|
-
elem(NAME_BLIP_FILL, { children: [elem(NAME_BLIP, { attrs: [attr(ATTR_R_EMBED, opts.rEmbed)] }), elem(NAME_STRETCH, { children: [elem(NAME_FILL_RECT)] })] }),
|
|
3582
|
-
elem(NAME_SP_PR$1, { children: [elem(NAME_A_XFRM, { children: [elem(NAME_OFF$2, { attrs: [attr(ATTR_X$2, String(emuCoordinate(opts.x, "addSlideImage: x"))), attr(ATTR_Y$2, String(emuCoordinate(opts.y, "addSlideImage: y")))] }), elem(NAME_EXT$
|
|
3665
|
+
elem(NAME_BLIP_FILL, { children: [elem(NAME_BLIP, { attrs: [attr(ATTR_R_EMBED$1, opts.rEmbed)] }), elem(NAME_STRETCH, { children: [elem(NAME_FILL_RECT)] })] }),
|
|
3666
|
+
elem(NAME_SP_PR$1, { children: [elem(NAME_A_XFRM, { children: [elem(NAME_OFF$2, { attrs: [attr(ATTR_X$2, String(emuCoordinate(opts.x, "addSlideImage: x"))), attr(ATTR_Y$2, String(emuCoordinate(opts.y, "addSlideImage: y")))] }), elem(NAME_EXT$3, { attrs: [attr(ATTR_CX$2, String(emuExtent(opts.w, "addSlideImage: w"))), attr(ATTR_CY$2, String(emuExtent(opts.h, "addSlideImage: h")))] })] }), elem(NAME_PRST_GEOM, {
|
|
3583
3667
|
attrs: [attr(ATTR_PRST, "rect")],
|
|
3584
3668
|
children: [elem(NAME_AV_LST)]
|
|
3585
3669
|
})] })
|
|
3586
3670
|
] });
|
|
3587
3671
|
};
|
|
3588
3672
|
//#endregion
|
|
3673
|
+
//#region src/internal/presentationml/media-builder.ts
|
|
3674
|
+
const NAME_NV_PIC_PR = qname("p", "nvPicPr", NS.pml);
|
|
3675
|
+
const NAME_C_NV_PR$2 = qname("p", "cNvPr", NS.pml);
|
|
3676
|
+
const NAME_NV_PR$3 = qname("p", "nvPr", NS.pml);
|
|
3677
|
+
const NAME_HLINK_CLICK = qname("a", "hlinkClick", NS.dml);
|
|
3678
|
+
const NAME_VIDEO_FILE = qname("a", "videoFile", NS.dml);
|
|
3679
|
+
const NAME_AUDIO_FILE = qname("a", "audioFile", NS.dml);
|
|
3680
|
+
const NAME_EXT_LST$2 = qname("p", "extLst", NS.pml);
|
|
3681
|
+
const NAME_EXT$2 = qname("p", "ext", NS.pml);
|
|
3682
|
+
const NAME_P14_MEDIA = qname("p14", "media", NS.p14);
|
|
3683
|
+
const NAME_TIMING$2 = qname("p", "timing", NS.pml);
|
|
3684
|
+
const NAME_TN_LST$2 = qname("p", "tnLst", NS.pml);
|
|
3685
|
+
const NAME_PAR$2 = qname("p", "par", NS.pml);
|
|
3686
|
+
const NAME_C_TN$2 = qname("p", "cTn", NS.pml);
|
|
3687
|
+
const NAME_CHILD_TN_LST$2 = qname("p", "childTnLst", NS.pml);
|
|
3688
|
+
const NAME_VIDEO = qname("p", "video", NS.pml);
|
|
3689
|
+
const NAME_AUDIO = qname("p", "audio", NS.pml);
|
|
3690
|
+
const NAME_C_MEDIA_NODE = qname("p", "cMediaNode", NS.pml);
|
|
3691
|
+
const NAME_ST_COND_LST$1 = qname("p", "stCondLst", NS.pml);
|
|
3692
|
+
const NAME_COND$1 = qname("p", "cond", NS.pml);
|
|
3693
|
+
const NAME_TGT_EL$1 = qname("p", "tgtEl", NS.pml);
|
|
3694
|
+
const NAME_SP_TGT$1 = qname("p", "spTgt", NS.pml);
|
|
3695
|
+
const ATTR_R_ID$2 = qname("r", "id", NS.officeDocRels);
|
|
3696
|
+
const ATTR_R_LINK = qname("r", "link", NS.officeDocRels);
|
|
3697
|
+
const ATTR_R_EMBED = qname("r", "embed", NS.officeDocRels);
|
|
3698
|
+
const ATTR_ACTION = qname("", "action", "");
|
|
3699
|
+
const ATTR_URI$2 = qname("", "uri", "");
|
|
3700
|
+
const ATTR_ID$7 = qname("", "id", "");
|
|
3701
|
+
const ATTR_DUR$1 = qname("", "dur", "");
|
|
3702
|
+
const ATTR_RESTART$1 = qname("", "restart", "");
|
|
3703
|
+
const ATTR_NODE_TYPE$1 = qname("", "nodeType", "");
|
|
3704
|
+
const ATTR_VOL = qname("", "vol", "");
|
|
3705
|
+
const ATTR_FILL$1 = qname("", "fill", "");
|
|
3706
|
+
const ATTR_DISPLAY = qname("", "display", "");
|
|
3707
|
+
const ATTR_DELAY$1 = qname("", "delay", "");
|
|
3708
|
+
const ATTR_SPID$1 = qname("", "spid", "");
|
|
3709
|
+
const MEDIA_ACTION = "ppaction://media";
|
|
3710
|
+
const P14_MEDIA_EXT_URI = "{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}";
|
|
3711
|
+
const DEFAULT_MEDIA_VOLUME = "80000";
|
|
3712
|
+
/** Returns a media `<p:pic>`; `opts.rEmbed` is the poster image relationship. */
|
|
3713
|
+
const buildMediaPicture = (opts) => {
|
|
3714
|
+
const pic = buildPicture(opts);
|
|
3715
|
+
const nvPicPr = firstChildElement(pic, NAME_NV_PIC_PR);
|
|
3716
|
+
const cNvPr = firstChildElement(nvPicPr, NAME_C_NV_PR$2);
|
|
3717
|
+
const nvPr = firstChildElement(nvPicPr, NAME_NV_PR$3);
|
|
3718
|
+
cNvPr.children.push(elem(NAME_HLINK_CLICK, { attrs: [attr(ATTR_R_ID$2, ""), attr(ATTR_ACTION, MEDIA_ACTION)] }));
|
|
3719
|
+
nvPr.children.push(elem(opts.kind === "video" ? NAME_VIDEO_FILE : NAME_AUDIO_FILE, { attrs: [attr(ATTR_R_LINK, opts.rLink)] }));
|
|
3720
|
+
if (opts.rMedia !== void 0) {
|
|
3721
|
+
const media = elem(NAME_P14_MEDIA, {
|
|
3722
|
+
attrs: [attr(ATTR_R_EMBED, opts.rMedia)],
|
|
3723
|
+
prefixDecls: new Map([["p14", NS.p14]])
|
|
3724
|
+
});
|
|
3725
|
+
const ext = elem(NAME_EXT$2, {
|
|
3726
|
+
attrs: [attr(ATTR_URI$2, P14_MEDIA_EXT_URI)],
|
|
3727
|
+
children: [media]
|
|
3728
|
+
});
|
|
3729
|
+
nvPr.children.push(elem(NAME_EXT_LST$2, { children: [ext] }));
|
|
3730
|
+
}
|
|
3731
|
+
return pic;
|
|
3732
|
+
};
|
|
3733
|
+
/** Returns the `<p:video>` / `<p:audio>` time node that targets shape `spid`. */
|
|
3734
|
+
const buildMediaTimingNode = (kind, spid, cTnId) => {
|
|
3735
|
+
const cTn = elem(NAME_C_TN$2, {
|
|
3736
|
+
attrs: [
|
|
3737
|
+
attr(ATTR_ID$7, String(cTnId)),
|
|
3738
|
+
attr(ATTR_FILL$1, "hold"),
|
|
3739
|
+
attr(ATTR_DISPLAY, "0")
|
|
3740
|
+
],
|
|
3741
|
+
children: [elem(NAME_ST_COND_LST$1, { children: [elem(NAME_COND$1, { attrs: [attr(ATTR_DELAY$1, "indefinite")] })] })]
|
|
3742
|
+
});
|
|
3743
|
+
const tgtEl = elem(NAME_TGT_EL$1, { children: [elem(NAME_SP_TGT$1, { attrs: [attr(ATTR_SPID$1, String(spid))] })] });
|
|
3744
|
+
const cMediaNode = elem(NAME_C_MEDIA_NODE, {
|
|
3745
|
+
attrs: [attr(ATTR_VOL, DEFAULT_MEDIA_VOLUME)],
|
|
3746
|
+
children: [cTn, tgtEl]
|
|
3747
|
+
});
|
|
3748
|
+
return elem(kind === "video" ? NAME_VIDEO : NAME_AUDIO, { children: [cMediaNode] });
|
|
3749
|
+
};
|
|
3750
|
+
/**
|
|
3751
|
+
* Returns a `<p:timing>` holding only the root time node, with `nodes` as its
|
|
3752
|
+
* children. `nodes` must be non-empty (`<p:childTnLst>` requires a child).
|
|
3753
|
+
*/
|
|
3754
|
+
const buildTimingRoot = (nodes) => {
|
|
3755
|
+
return elem(NAME_TIMING$2, { children: [elem(NAME_TN_LST$2, { children: [elem(NAME_PAR$2, { children: [elem(NAME_C_TN$2, {
|
|
3756
|
+
attrs: [
|
|
3757
|
+
attr(ATTR_ID$7, "1"),
|
|
3758
|
+
attr(ATTR_DUR$1, "indefinite"),
|
|
3759
|
+
attr(ATTR_RESTART$1, "never"),
|
|
3760
|
+
attr(ATTR_NODE_TYPE$1, "tmRoot")
|
|
3761
|
+
],
|
|
3762
|
+
children: [elem(NAME_CHILD_TN_LST$2, { children: [...nodes] })]
|
|
3763
|
+
})] })] })] });
|
|
3764
|
+
};
|
|
3765
|
+
/** `true` for a `<p:video>` / `<p:audio>` time node. */
|
|
3766
|
+
const isMediaTimingNode = (el) => el.name.namespaceURI === NS.pml && (el.name.localName === "video" || el.name.localName === "audio");
|
|
3767
|
+
/** Shape id a media time node targets, or `null` when it has no `<p:spTgt>`. */
|
|
3768
|
+
const mediaTimingNodeTarget = (node) => {
|
|
3769
|
+
const cMediaNode = firstChildElement(node, NAME_C_MEDIA_NODE);
|
|
3770
|
+
const tgtEl = cMediaNode ? firstChildElement(cMediaNode, NAME_TGT_EL$1) : null;
|
|
3771
|
+
const spTgt = tgtEl ? firstChildElement(tgtEl, NAME_SP_TGT$1) : null;
|
|
3772
|
+
const raw = spTgt ? getAttrValue(spTgt, ATTR_SPID$1) : null;
|
|
3773
|
+
if (raw === null) return null;
|
|
3774
|
+
const spid = Number.parseInt(raw, 10);
|
|
3775
|
+
return Number.isFinite(spid) ? spid : null;
|
|
3776
|
+
};
|
|
3777
|
+
const MEDIA_FILE_ELEMENTS = {
|
|
3778
|
+
videoFile: "video",
|
|
3779
|
+
quickTimeFile: "video",
|
|
3780
|
+
audioFile: "audio",
|
|
3781
|
+
wavAudioFile: "audio"
|
|
3782
|
+
};
|
|
3783
|
+
/** Reads the media reference off a `<p:pic>`, or `null` for a plain picture. */
|
|
3784
|
+
const readPictureMediaRef = (pic) => {
|
|
3785
|
+
const nvPicPr = firstChildElement(pic, NAME_NV_PIC_PR);
|
|
3786
|
+
const nvPr = nvPicPr ? firstChildElement(nvPicPr, NAME_NV_PR$3) : null;
|
|
3787
|
+
if (!nvPr) return null;
|
|
3788
|
+
for (const child of nvPr.children) {
|
|
3789
|
+
if (child.kind !== "element" || child.name.namespaceURI !== NS.dml) continue;
|
|
3790
|
+
const kind = MEDIA_FILE_ELEMENTS[child.name.localName];
|
|
3791
|
+
if (kind === void 0) continue;
|
|
3792
|
+
return {
|
|
3793
|
+
kind,
|
|
3794
|
+
fileRId: child.name.localName === "wavAudioFile" ? getAttrValue(child, ATTR_R_EMBED) : getAttrValue(child, ATTR_R_LINK),
|
|
3795
|
+
mediaRId: readP14MediaRId(nvPr)
|
|
3796
|
+
};
|
|
3797
|
+
}
|
|
3798
|
+
return null;
|
|
3799
|
+
};
|
|
3800
|
+
const readP14MediaRId = (nvPr) => {
|
|
3801
|
+
const extLst = firstChildElement(nvPr, NAME_EXT_LST$2);
|
|
3802
|
+
if (!extLst) return null;
|
|
3803
|
+
for (const ext of extLst.children) {
|
|
3804
|
+
if (ext.kind !== "element") continue;
|
|
3805
|
+
const media = firstChildElement(ext, NAME_P14_MEDIA);
|
|
3806
|
+
if (media) return getAttrValue(media, ATTR_R_EMBED);
|
|
3807
|
+
}
|
|
3808
|
+
return null;
|
|
3809
|
+
};
|
|
3810
|
+
//#endregion
|
|
3589
3811
|
//#region src/internal/presentationml/table-builder.ts
|
|
3590
3812
|
const TABLE_URI = "http://schemas.openxmlformats.org/drawingml/2006/table";
|
|
3591
3813
|
const DEFAULT_TABLE_STYLE_ID = "{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}";
|
|
@@ -3625,7 +3847,7 @@ const ATTR_MAR_R = qname("", "marR", "");
|
|
|
3625
3847
|
const ATTR_MAR_T = qname("", "marT", "");
|
|
3626
3848
|
const ATTR_MAR_B = qname("", "marB", "");
|
|
3627
3849
|
const ATTR_INDENT = qname("", "indent", "");
|
|
3628
|
-
const ATTR_ID$
|
|
3850
|
+
const ATTR_ID$6 = qname("", "id", "");
|
|
3629
3851
|
const ATTR_NAME$3 = qname("", "name", "");
|
|
3630
3852
|
const ATTR_NO_GRP$1 = qname("", "noGrp", "");
|
|
3631
3853
|
const ATTR_X$1 = qname("", "x", "");
|
|
@@ -3701,7 +3923,7 @@ const buildTable = (opts) => {
|
|
|
3701
3923
|
if (rowHeights.length !== rows.length) throw new Error(`addSlideTable: rowHeights has ${rowHeights.length} entries; expected ${rows.length}`);
|
|
3702
3924
|
const name = opts.name ?? `Table ${opts.id}`;
|
|
3703
3925
|
const nvGraphicFramePr = elem(NAME_NV_GRAPHIC_FRAME_PR$1, { children: [
|
|
3704
|
-
elem(NAME_C_NV_PR$1, { attrs: [attr(ATTR_ID$
|
|
3926
|
+
elem(NAME_C_NV_PR$1, { attrs: [attr(ATTR_ID$6, String(opts.id)), attr(ATTR_NAME$3, name)] }),
|
|
3705
3927
|
elem(NAME_C_NV_GRAPHIC_FRAME_PR$1, { children: [elem(NAME_GRAPHIC_FRAME_LOCKS, { attrs: [attr(ATTR_NO_GRP$1, "1")] })] }),
|
|
3706
3928
|
elem(NAME_NV_PR$2)
|
|
3707
3929
|
] });
|
|
@@ -3749,7 +3971,7 @@ const NAME_R = qname("a", "r", NS.dml);
|
|
|
3749
3971
|
const NAME_RPR = qname("a", "rPr", NS.dml);
|
|
3750
3972
|
const NAME_T$1 = qname("a", "t", NS.dml);
|
|
3751
3973
|
const NAME_SP_LOCKS = qname("a", "spLocks", NS.dml);
|
|
3752
|
-
const ATTR_ID$
|
|
3974
|
+
const ATTR_ID$5 = qname("", "id", "");
|
|
3753
3975
|
const ATTR_NAME$2 = qname("", "name", "");
|
|
3754
3976
|
const ATTR_NO_GRP = qname("", "noGrp", "");
|
|
3755
3977
|
const ATTR_NO_ROT = qname("", "noRot", "");
|
|
@@ -3759,14 +3981,14 @@ const ATTR_IDX$3 = qname("", "idx", "");
|
|
|
3759
3981
|
const ATTR_LANG = qname("", "lang", "");
|
|
3760
3982
|
const buildRootGroup = () => {
|
|
3761
3983
|
return elem(NAME_NV_GRP_SP_PR, { children: [
|
|
3762
|
-
elem(NAME_C_NV_PR, { attrs: [attr(ATTR_ID$
|
|
3984
|
+
elem(NAME_C_NV_PR, { attrs: [attr(ATTR_ID$5, "1"), attr(ATTR_NAME$2, "")] }),
|
|
3763
3985
|
elem(NAME_C_NV_GRP_SP_PR),
|
|
3764
3986
|
elem(NAME_NV_PR$1)
|
|
3765
3987
|
] });
|
|
3766
3988
|
};
|
|
3767
3989
|
const buildSldImgPlaceholder = (id) => {
|
|
3768
3990
|
return elem(NAME_SP, { children: [elem(NAME_NV_SP_PR, { children: [
|
|
3769
|
-
elem(NAME_C_NV_PR, { attrs: [attr(ATTR_ID$
|
|
3991
|
+
elem(NAME_C_NV_PR, { attrs: [attr(ATTR_ID$5, String(id)), attr(ATTR_NAME$2, `Slide Image Placeholder ${id - 1}`)] }),
|
|
3770
3992
|
elem(NAME_C_NV_SP_PR, { children: [elem(NAME_SP_LOCKS, { attrs: [
|
|
3771
3993
|
attr(ATTR_NO_GRP, "1"),
|
|
3772
3994
|
attr(ATTR_NO_ROT, "1"),
|
|
@@ -3783,7 +4005,7 @@ const buildNotesParagraphs = (notes) => {
|
|
|
3783
4005
|
};
|
|
3784
4006
|
const buildNotesBodyPlaceholder = (id, notes) => {
|
|
3785
4007
|
const nvSpPr = elem(NAME_NV_SP_PR, { children: [
|
|
3786
|
-
elem(NAME_C_NV_PR, { attrs: [attr(ATTR_ID$
|
|
4008
|
+
elem(NAME_C_NV_PR, { attrs: [attr(ATTR_ID$5, String(id)), attr(ATTR_NAME$2, `Notes Placeholder ${id - 1}`)] }),
|
|
3787
4009
|
elem(NAME_C_NV_SP_PR, { children: [elem(NAME_SP_LOCKS, { attrs: [attr(ATTR_NO_GRP, "1")] })] }),
|
|
3788
4010
|
elem(NAME_NV_PR$1, { children: [elem(NAME_PH, { attrs: [attr(ATTR_TYPE$1, "body"), attr(ATTR_IDX$3, "1")] })] })
|
|
3789
4011
|
] });
|
|
@@ -3924,11 +4146,11 @@ const buildTransition = (opts) => {
|
|
|
3924
4146
|
};
|
|
3925
4147
|
//#endregion
|
|
3926
4148
|
//#region src/internal/presentationml/animation-builder.ts
|
|
3927
|
-
const NAME_TIMING = qname("p", "timing", NS.pml);
|
|
3928
|
-
const NAME_TN_LST = qname("p", "tnLst", NS.pml);
|
|
3929
|
-
const NAME_PAR = qname("p", "par", NS.pml);
|
|
3930
|
-
const NAME_C_TN = qname("p", "cTn", NS.pml);
|
|
3931
|
-
const NAME_CHILD_TN_LST = qname("p", "childTnLst", NS.pml);
|
|
4149
|
+
const NAME_TIMING$1 = qname("p", "timing", NS.pml);
|
|
4150
|
+
const NAME_TN_LST$1 = qname("p", "tnLst", NS.pml);
|
|
4151
|
+
const NAME_PAR$1 = qname("p", "par", NS.pml);
|
|
4152
|
+
const NAME_C_TN$1 = qname("p", "cTn", NS.pml);
|
|
4153
|
+
const NAME_CHILD_TN_LST$1 = qname("p", "childTnLst", NS.pml);
|
|
3932
4154
|
const NAME_SEQ = qname("p", "seq", NS.pml);
|
|
3933
4155
|
const NAME_ST_COND_LST = qname("p", "stCondLst", NS.pml);
|
|
3934
4156
|
const NAME_PREV_COND_LST = qname("p", "prevCondLst", NS.pml);
|
|
@@ -3950,7 +4172,7 @@ const NAME_TAV_LST = qname("p", "tavLst", NS.pml);
|
|
|
3950
4172
|
const NAME_TAV = qname("p", "tav", NS.pml);
|
|
3951
4173
|
const NAME_BLD_LST = qname("p", "bldLst", NS.pml);
|
|
3952
4174
|
const NAME_BLD_P = qname("p", "bldP", NS.pml);
|
|
3953
|
-
const ATTR_ID$
|
|
4175
|
+
const ATTR_ID$4 = qname("", "id", "");
|
|
3954
4176
|
const ATTR_DUR = qname("", "dur", "");
|
|
3955
4177
|
const ATTR_RESTART = qname("", "restart", "");
|
|
3956
4178
|
const ATTR_NODE_TYPE = qname("", "nodeType", "");
|
|
@@ -3998,9 +4220,9 @@ const buildSetVisibility = (spid, visible) => {
|
|
|
3998
4220
|
data: "style.visibility"
|
|
3999
4221
|
}] })] });
|
|
4000
4222
|
return elem(NAME_SET, { children: [elem(NAME_C_BHVR, { children: [
|
|
4001
|
-
elem(NAME_C_TN, {
|
|
4223
|
+
elem(NAME_C_TN$1, {
|
|
4002
4224
|
attrs: [
|
|
4003
|
-
attr(ATTR_ID$
|
|
4225
|
+
attr(ATTR_ID$4, "6"),
|
|
4004
4226
|
attr(ATTR_DUR, "1"),
|
|
4005
4227
|
attr(ATTR_FILL, "hold")
|
|
4006
4228
|
],
|
|
@@ -4016,8 +4238,8 @@ const buildOpacityAnim = (spid, durationMs, fadeIn) => {
|
|
|
4016
4238
|
kind: "text",
|
|
4017
4239
|
data: "style.opacity"
|
|
4018
4240
|
}] })] });
|
|
4019
|
-
const cTn = elem(NAME_C_TN, { attrs: [
|
|
4020
|
-
attr(ATTR_ID$
|
|
4241
|
+
const cTn = elem(NAME_C_TN$1, { attrs: [
|
|
4242
|
+
attr(ATTR_ID$4, "7"),
|
|
4021
4243
|
attr(ATTR_DUR, String(durationMs)),
|
|
4022
4244
|
attr(ATTR_FILL, "hold")
|
|
4023
4245
|
] });
|
|
@@ -4055,9 +4277,9 @@ const buildSingleEffectTiming = (spid, opts) => {
|
|
|
4055
4277
|
const effectChildren = [];
|
|
4056
4278
|
effectChildren.push(buildSetVisibility(spid, isEntrance));
|
|
4057
4279
|
if (isFade) effectChildren.push(buildOpacityAnim(spid, duration, isEntrance));
|
|
4058
|
-
const effectPar = elem(NAME_PAR, { children: [elem(NAME_C_TN, {
|
|
4280
|
+
const effectPar = elem(NAME_PAR$1, { children: [elem(NAME_C_TN$1, {
|
|
4059
4281
|
attrs: [
|
|
4060
|
-
attr(ATTR_ID$
|
|
4282
|
+
attr(ATTR_ID$4, "5"),
|
|
4061
4283
|
attr(ATTR_PRESET_ID, String(preset.presetId)),
|
|
4062
4284
|
attr(ATTR_PRESET_CLASS, preset.presetClass),
|
|
4063
4285
|
attr(ATTR_PRESET_SUBTYPE, String(preset.presetSubtype)),
|
|
@@ -4065,23 +4287,23 @@ const buildSingleEffectTiming = (spid, opts) => {
|
|
|
4065
4287
|
attr(ATTR_GRP_ID, "0"),
|
|
4066
4288
|
attr(ATTR_NODE_TYPE, "clickEffect")
|
|
4067
4289
|
],
|
|
4068
|
-
children: [elem(NAME_ST_COND_LST, { children: [elem(NAME_COND, { attrs: [attr(ATTR_DELAY, "0")] })] }), elem(NAME_CHILD_TN_LST, { children: effectChildren })]
|
|
4290
|
+
children: [elem(NAME_ST_COND_LST, { children: [elem(NAME_COND, { attrs: [attr(ATTR_DELAY, "0")] })] }), elem(NAME_CHILD_TN_LST$1, { children: effectChildren })]
|
|
4069
4291
|
})] });
|
|
4070
|
-
const clickWrapperPar = elem(NAME_PAR, { children: [elem(NAME_C_TN, {
|
|
4071
|
-
attrs: [attr(ATTR_ID$
|
|
4072
|
-
children: [elem(NAME_ST_COND_LST, { children: [elem(NAME_COND, { attrs: [attr(ATTR_DELAY, "0")] })] }), elem(NAME_CHILD_TN_LST, { children: [effectPar] })]
|
|
4292
|
+
const clickWrapperPar = elem(NAME_PAR$1, { children: [elem(NAME_C_TN$1, {
|
|
4293
|
+
attrs: [attr(ATTR_ID$4, "4"), attr(ATTR_FILL, "hold")],
|
|
4294
|
+
children: [elem(NAME_ST_COND_LST, { children: [elem(NAME_COND, { attrs: [attr(ATTR_DELAY, "0")] })] }), elem(NAME_CHILD_TN_LST$1, { children: [effectPar] })]
|
|
4073
4295
|
})] });
|
|
4074
|
-
const indefinitePar = elem(NAME_PAR, { children: [elem(NAME_C_TN, {
|
|
4075
|
-
attrs: [attr(ATTR_ID$
|
|
4076
|
-
children: [elem(NAME_ST_COND_LST, { children: [elem(NAME_COND, { attrs: [attr(ATTR_DELAY, "indefinite")] })] }), elem(NAME_CHILD_TN_LST, { children: [clickWrapperPar] })]
|
|
4296
|
+
const indefinitePar = elem(NAME_PAR$1, { children: [elem(NAME_C_TN$1, {
|
|
4297
|
+
attrs: [attr(ATTR_ID$4, "3"), attr(ATTR_FILL, "hold")],
|
|
4298
|
+
children: [elem(NAME_ST_COND_LST, { children: [elem(NAME_COND, { attrs: [attr(ATTR_DELAY, "indefinite")] })] }), elem(NAME_CHILD_TN_LST$1, { children: [clickWrapperPar] })]
|
|
4077
4299
|
})] });
|
|
4078
|
-
const mainSeqCTn = elem(NAME_C_TN, {
|
|
4300
|
+
const mainSeqCTn = elem(NAME_C_TN$1, {
|
|
4079
4301
|
attrs: [
|
|
4080
|
-
attr(ATTR_ID$
|
|
4302
|
+
attr(ATTR_ID$4, "2"),
|
|
4081
4303
|
attr(ATTR_DUR, "indefinite"),
|
|
4082
4304
|
attr(ATTR_NODE_TYPE, "mainSeq")
|
|
4083
4305
|
],
|
|
4084
|
-
children: [elem(NAME_CHILD_TN_LST, { children: [indefinitePar] })]
|
|
4306
|
+
children: [elem(NAME_CHILD_TN_LST$1, { children: [indefinitePar] })]
|
|
4085
4307
|
});
|
|
4086
4308
|
const prevCond = elem(NAME_PREV_COND_LST, { children: [elem(NAME_COND, {
|
|
4087
4309
|
attrs: [attr(ATTR_EVT, "onPrev"), attr(ATTR_DELAY, "0")],
|
|
@@ -4099,14 +4321,14 @@ const buildSingleEffectTiming = (spid, opts) => {
|
|
|
4099
4321
|
nextCond
|
|
4100
4322
|
]
|
|
4101
4323
|
});
|
|
4102
|
-
return elem(NAME_TIMING, { children: [elem(NAME_TN_LST, { children: [elem(NAME_PAR, { children: [elem(NAME_C_TN, {
|
|
4324
|
+
return elem(NAME_TIMING$1, { children: [elem(NAME_TN_LST$1, { children: [elem(NAME_PAR$1, { children: [elem(NAME_C_TN$1, {
|
|
4103
4325
|
attrs: [
|
|
4104
|
-
attr(ATTR_ID$
|
|
4326
|
+
attr(ATTR_ID$4, "1"),
|
|
4105
4327
|
attr(ATTR_DUR, "indefinite"),
|
|
4106
4328
|
attr(ATTR_RESTART, "never"),
|
|
4107
4329
|
attr(ATTR_NODE_TYPE, "tmRoot")
|
|
4108
4330
|
],
|
|
4109
|
-
children: [elem(NAME_CHILD_TN_LST, { children: [seq] })]
|
|
4331
|
+
children: [elem(NAME_CHILD_TN_LST$1, { children: [seq] })]
|
|
4110
4332
|
})] })] }), elem(NAME_BLD_LST, { children: [elem(NAME_BLD_P, { attrs: [attr(ATTR_SPID, String(spid)), attr(ATTR_GRP_ID, "0")] })] })] });
|
|
4111
4333
|
};
|
|
4112
4334
|
//#endregion
|
|
@@ -4117,7 +4339,7 @@ const NAME_CM_LST = qname("p", "cmLst", NS.pml);
|
|
|
4117
4339
|
const NAME_CM = qname("p", "cm", NS.pml);
|
|
4118
4340
|
const NAME_POS = qname("p", "pos", NS.pml);
|
|
4119
4341
|
const NAME_TEXT = qname("p", "text", NS.pml);
|
|
4120
|
-
const ATTR_ID$
|
|
4342
|
+
const ATTR_ID$3 = qname("", "id", "");
|
|
4121
4343
|
const ATTR_NAME$1 = qname("", "name", "");
|
|
4122
4344
|
const ATTR_INITIALS = qname("", "initials", "");
|
|
4123
4345
|
const ATTR_LAST_IDX = qname("", "lastIdx", "");
|
|
@@ -4131,7 +4353,7 @@ const readCommentAuthorList = (root) => {
|
|
|
4131
4353
|
if (root.name.namespaceURI !== NS.pml || root.name.localName !== "cmAuthorLst") throw new Error(`expected <p:cmAuthorLst> root, got <${root.name.prefix}:${root.name.localName}>`);
|
|
4132
4354
|
const authors = [];
|
|
4133
4355
|
for (const el of allChildElements(root, NAME_CM_AUTHOR)) {
|
|
4134
|
-
const idRaw = getAttrValue(el, ATTR_ID$
|
|
4356
|
+
const idRaw = getAttrValue(el, ATTR_ID$3);
|
|
4135
4357
|
const nameVal = getAttrValue(el, ATTR_NAME$1);
|
|
4136
4358
|
const initialsVal = getAttrValue(el, ATTR_INITIALS);
|
|
4137
4359
|
const lastIdxRaw = getAttrValue(el, ATTR_LAST_IDX);
|
|
@@ -4191,7 +4413,7 @@ const readCommentList = (root) => {
|
|
|
4191
4413
|
};
|
|
4192
4414
|
const commentAuthorElement = (a) => {
|
|
4193
4415
|
return elem(NAME_CM_AUTHOR, { attrs: [
|
|
4194
|
-
attr(ATTR_ID$
|
|
4416
|
+
attr(ATTR_ID$3, String(a.id)),
|
|
4195
4417
|
attr(ATTR_NAME$1, a.name),
|
|
4196
4418
|
attr(ATTR_INITIALS, a.initials),
|
|
4197
4419
|
attr(ATTR_LAST_IDX, String(a.lastIdx)),
|
|
@@ -4255,7 +4477,7 @@ const NAME_SLD_ID_LST$1 = qname("p", "sldIdLst", NS.pml);
|
|
|
4255
4477
|
const NAME_SLD_ID$1 = qname("p", "sldId", NS.pml);
|
|
4256
4478
|
const NAME_CSLD = qname("p", "cSld", NS.pml);
|
|
4257
4479
|
const NAME_SP_TREE = qname("p", "spTree", NS.pml);
|
|
4258
|
-
const ATTR_ID$
|
|
4480
|
+
const ATTR_ID$2 = qname("", "id", "");
|
|
4259
4481
|
const ATTR_R_ID$1 = qname("r", "id", NS.officeDocRels);
|
|
4260
4482
|
const SLD_ID_MAX = 2147482623;
|
|
4261
4483
|
const commitSlideData = (slide) => {
|
|
@@ -5159,6 +5381,136 @@ const setShapeClickAction = (shape, action) => {
|
|
|
5159
5381
|
commitAndRefresh(shape);
|
|
5160
5382
|
};
|
|
5161
5383
|
//#endregion
|
|
5384
|
+
//#region src/internal/chartml/embedded-xlsx.ts
|
|
5385
|
+
const TEXT_ENCODER = new TextEncoder();
|
|
5386
|
+
const encode = (s) => TEXT_ENCODER.encode(s);
|
|
5387
|
+
const xmlEscape = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
5388
|
+
const colLetter = (col) => {
|
|
5389
|
+
let n = col;
|
|
5390
|
+
let out = "";
|
|
5391
|
+
while (true) {
|
|
5392
|
+
out = String.fromCharCode(65 + n % 26) + out;
|
|
5393
|
+
if (n < 26) return out;
|
|
5394
|
+
n = Math.floor(n / 26) - 1;
|
|
5395
|
+
}
|
|
5396
|
+
};
|
|
5397
|
+
const cellRef = (row, col) => `${colLetter(col)}${row + 1}`;
|
|
5398
|
+
/**
|
|
5399
|
+
* Builds the bytes of a fresh xlsx whose only sheet holds `grid`, row by
|
|
5400
|
+
* row from A1. Which cell means what is the caller's business — see
|
|
5401
|
+
* `layoutChartSheet`, which also produces the `<c:f>` formulas that point
|
|
5402
|
+
* back into this grid.
|
|
5403
|
+
*/
|
|
5404
|
+
const buildEmbeddedXlsx = (grid) => {
|
|
5405
|
+
const sheetXmlParts = [];
|
|
5406
|
+
sheetXmlParts.push("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n", "<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">", "<sheetData>");
|
|
5407
|
+
grid.forEach((row, r) => {
|
|
5408
|
+
sheetXmlParts.push(`<row r="${r + 1}">`);
|
|
5409
|
+
row.forEach((cell, col) => {
|
|
5410
|
+
if (cell === null) return;
|
|
5411
|
+
sheetXmlParts.push(typeof cell === "number" ? `<c r="${cellRef(r, col)}"><v>${cell}</v></c>` : `<c r="${cellRef(r, col)}" t="inlineStr"><is><t>${xmlEscape(cell)}</t></is></c>`);
|
|
5412
|
+
});
|
|
5413
|
+
sheetXmlParts.push("</row>");
|
|
5414
|
+
});
|
|
5415
|
+
sheetXmlParts.push("</sheetData></worksheet>");
|
|
5416
|
+
const sheetXml = sheetXmlParts.join("");
|
|
5417
|
+
return writeZip([
|
|
5418
|
+
{
|
|
5419
|
+
name: "[Content_Types].xml",
|
|
5420
|
+
data: encode("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"><Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/><Default Extension=\"xml\" ContentType=\"application/xml\"/><Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/><Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/></Types>")
|
|
5421
|
+
},
|
|
5422
|
+
{
|
|
5423
|
+
name: "_rels/.rels",
|
|
5424
|
+
data: encode("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"xl/workbook.xml\"/></Relationships>")
|
|
5425
|
+
},
|
|
5426
|
+
{
|
|
5427
|
+
name: "xl/workbook.xml",
|
|
5428
|
+
data: encode("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"><sheets><sheet name=\"Sheet1\" sheetId=\"1\" r:id=\"rId1\"/></sheets></workbook>")
|
|
5429
|
+
},
|
|
5430
|
+
{
|
|
5431
|
+
name: "xl/_rels/workbook.xml.rels",
|
|
5432
|
+
data: encode("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet1.xml\"/></Relationships>")
|
|
5433
|
+
},
|
|
5434
|
+
{
|
|
5435
|
+
name: "xl/worksheets/sheet1.xml",
|
|
5436
|
+
data: encode(sheetXml)
|
|
5437
|
+
}
|
|
5438
|
+
]);
|
|
5439
|
+
};
|
|
5440
|
+
/**
|
|
5441
|
+
* Returns the spreadsheet-cell reference span used by chart `<c:f>`
|
|
5442
|
+
* formulas. Example: `cellRange('Sheet1', 1, 0, 4)` →
|
|
5443
|
+
* `"Sheet1!$A$2:$A$5"` (column A, rows 2–5 inclusive, 0-indexed input).
|
|
5444
|
+
*/
|
|
5445
|
+
const cellRange = (sheet, startRow, col, count, endCol = col) => `${sheet}!$${colLetter(col)}$${startRow + 1}:$${colLetter(endCol)}$${startRow + count}`;
|
|
5446
|
+
/** Single-cell reference, e.g. `cellAddr('Sheet1', 0, 1)` → `"Sheet1!$B$1"`. */
|
|
5447
|
+
const cellAddr = (sheet, row, col) => `${sheet}!$${colLetter(col)}$${row + 1}`;
|
|
5448
|
+
//#endregion
|
|
5449
|
+
//#region src/internal/chartml/sheet-layout.ts
|
|
5450
|
+
const SHEET = "Sheet1";
|
|
5451
|
+
const isXyKind = (spec) => spec.kind === "scatter" || spec.kind === "bubble";
|
|
5452
|
+
/** Parses a date-axis category; the caller has validated it is numeric. */
|
|
5453
|
+
const dateSerial = (category) => Number(category);
|
|
5454
|
+
const layoutCategorySheet = (spec) => {
|
|
5455
|
+
const outerLevels = [...spec.categoryGroupLevels ?? []].reverse();
|
|
5456
|
+
const levelCount = outerLevels.length + 1;
|
|
5457
|
+
const rowCount = spec.categories.length;
|
|
5458
|
+
const isDateAxis = spec.categoryAxisDate !== void 0;
|
|
5459
|
+
const grid = [[...Array.from({ length: levelCount }, () => ""), ...spec.series.map((s) => s.name)]];
|
|
5460
|
+
for (let r = 0; r < rowCount; r++) {
|
|
5461
|
+
const category = spec.categories[r] ?? "";
|
|
5462
|
+
const row = outerLevels.map((level) => {
|
|
5463
|
+
const label = level[r] ?? "";
|
|
5464
|
+
return label === "" ? null : label;
|
|
5465
|
+
});
|
|
5466
|
+
row.push(isDateAxis ? dateSerial(category) : category);
|
|
5467
|
+
for (const s of spec.series) row.push(s.values[r] ?? null);
|
|
5468
|
+
grid.push(row);
|
|
5469
|
+
}
|
|
5470
|
+
return {
|
|
5471
|
+
grid,
|
|
5472
|
+
categories: cellRange(SHEET, 1, 0, rowCount, levelCount - 1),
|
|
5473
|
+
series: spec.series.map((_, i) => ({
|
|
5474
|
+
name: cellAddr(SHEET, 0, levelCount + i),
|
|
5475
|
+
values: cellRange(SHEET, 1, levelCount + i, rowCount)
|
|
5476
|
+
}))
|
|
5477
|
+
};
|
|
5478
|
+
};
|
|
5479
|
+
const layoutXySheet = (spec) => {
|
|
5480
|
+
const isBubble = spec.kind === "bubble";
|
|
5481
|
+
const stride = isBubble ? 3 : 2;
|
|
5482
|
+
const rowCount = Math.max(0, ...spec.series.map((s) => Math.max(s.values.length, s.xValues?.length ?? 0, s.bubbleSizes?.length ?? 0)));
|
|
5483
|
+
const header = [];
|
|
5484
|
+
for (const s of spec.series) {
|
|
5485
|
+
header.push("X", s.name);
|
|
5486
|
+
if (isBubble) header.push("Size");
|
|
5487
|
+
}
|
|
5488
|
+
const grid = [header];
|
|
5489
|
+
for (let r = 0; r < rowCount; r++) {
|
|
5490
|
+
const row = [];
|
|
5491
|
+
for (const s of spec.series) {
|
|
5492
|
+
row.push(s.xValues?.[r] ?? null, s.values[r] ?? null);
|
|
5493
|
+
if (isBubble) row.push(s.bubbleSizes?.[r] ?? null);
|
|
5494
|
+
}
|
|
5495
|
+
grid.push(row);
|
|
5496
|
+
}
|
|
5497
|
+
return {
|
|
5498
|
+
grid,
|
|
5499
|
+
series: spec.series.map((s, i) => {
|
|
5500
|
+
const base = i * stride;
|
|
5501
|
+
const pointCount = s.values.length;
|
|
5502
|
+
return {
|
|
5503
|
+
name: cellAddr(SHEET, 0, base + 1),
|
|
5504
|
+
xValues: cellRange(SHEET, 1, base, pointCount),
|
|
5505
|
+
values: cellRange(SHEET, 1, base + 1, pointCount),
|
|
5506
|
+
...isBubble ? { bubbleSizes: cellRange(SHEET, 1, base + 2, pointCount) } : {}
|
|
5507
|
+
};
|
|
5508
|
+
})
|
|
5509
|
+
};
|
|
5510
|
+
};
|
|
5511
|
+
/** Lays `spec` out as a sheet grid plus the formulas that address it. */
|
|
5512
|
+
const layoutChartSheet = (spec) => isXyKind(spec) ? layoutXySheet(spec) : layoutCategorySheet(spec);
|
|
5513
|
+
//#endregion
|
|
5162
5514
|
//#region src/internal/chartml/chart-builder.ts
|
|
5163
5515
|
const NS_C$1 = NS.chart;
|
|
5164
5516
|
const NS_A$1 = NS.dml;
|
|
@@ -5177,20 +5529,21 @@ const strRef = (formula, points) => {
|
|
|
5177
5529
|
const strCache = elem(c("strCache"), { children: [valNode(c("ptCount"), points.length), ...points.map((p, i) => ptNode(i, p))] });
|
|
5178
5530
|
return elem(c("strRef"), { children: [elem(c("f"), { children: [text(formula)] }), strCache] });
|
|
5179
5531
|
};
|
|
5180
|
-
const
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
const
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
};
|
|
5193
|
-
const lineSpPr = (color, widthEmu, field) => {
|
|
5532
|
+
const numDataChildren = (points, formatCode) => [
|
|
5533
|
+
elem(c("formatCode"), { children: [text(formatCode)] }),
|
|
5534
|
+
valNode(c("ptCount"), points.length),
|
|
5535
|
+
...points.map((v, i) => v === null ? null : ptNode(i, String(v))).filter((n) => n !== null)
|
|
5536
|
+
];
|
|
5537
|
+
const numRef = (formula, points, formatCode = "General") => elem(c("numRef"), { children: [elem(c("f"), { children: [text(formula)] }), elem(c("numCache"), { children: numDataChildren(points, formatCode) })] });
|
|
5538
|
+
const multiLvlStrRef = (formula, levels, pointCount) => elem(c("multiLvlStrRef"), { children: [elem(c("f"), { children: [text(formula)] }), elem(c("multiLvlStrCache"), { children: [valNode(c("ptCount"), pointCount), ...levels.map((level, depth) => elem(c("lvl"), { children: level.map((label, i) => depth > 0 && label === "" ? null : ptNode(i, label)).filter((n) => n !== null) }))] })] });
|
|
5539
|
+
const hexOf = (color) => color.replace(/^#/, "").toUpperCase();
|
|
5540
|
+
const solidFill = (color, opacity) => elem(a("solidFill"), { children: [elem(a("srgbClr"), {
|
|
5541
|
+
attrs: [attr(ATTR_VAL$1, hexOf(color))],
|
|
5542
|
+
children: opacity !== void 0 ? [valNode(a("alpha"), boundedInt(opacity * 1e5, "percent100000", "chart series: fillOpacity"))] : []
|
|
5543
|
+
})] });
|
|
5544
|
+
const solidFillSpPr = (color, opacity) => elem(c("spPr"), { children: [solidFill(color, opacity)] });
|
|
5545
|
+
const lineSpPr = (color, widthEmu, field, hidden = false) => {
|
|
5546
|
+
if (hidden) return elem(c("spPr"), { children: [elem(a("ln"), { children: [elem(a("noFill"))] })] });
|
|
5194
5547
|
if (color === void 0 && widthEmu === void 0) return null;
|
|
5195
5548
|
const ln = elem(a("ln"), {
|
|
5196
5549
|
attrs: widthEmu !== void 0 ? [attr(qname("", "w", ""), String(lineWidthEmu(widthEmu, field)))] : [],
|
|
@@ -5216,14 +5569,14 @@ const DEFAULT_ACCENT_COLORS = [
|
|
|
5216
5569
|
"5B9BD5",
|
|
5217
5570
|
"70AD47"
|
|
5218
5571
|
];
|
|
5219
|
-
const seriesSpPr = (color, lineColor, lineWidthEmu$1, lineDash) => {
|
|
5220
|
-
const lnChildren = [
|
|
5221
|
-
if (lineDash !== void 0) lnChildren.push(elem(a("prstDash"), { attrs: [attr(qname("", "val", ""), lineDash)] }));
|
|
5572
|
+
const seriesSpPr = (color, lineColor, lineWidthEmu$1, lineDash, fillOpacity) => {
|
|
5573
|
+
const lnChildren = [lineColor === null ? elem(a("noFill")) : solidFill(lineColor)];
|
|
5574
|
+
if (lineColor !== null && lineDash !== void 0) lnChildren.push(elem(a("prstDash"), { attrs: [attr(qname("", "val", ""), lineDash)] }));
|
|
5222
5575
|
const ln = lineWidthEmu$1 !== void 0 ? elem(a("ln"), {
|
|
5223
5576
|
attrs: [attr(qname("", "w", ""), String(lineWidthEmu(lineWidthEmu$1, "chart series: lineWidthEmu")))],
|
|
5224
5577
|
children: lnChildren
|
|
5225
5578
|
}) : elem(a("ln"), { children: lnChildren });
|
|
5226
|
-
return elem(c("spPr"), { children: [
|
|
5579
|
+
return elem(c("spPr"), { children: [solidFill(color, fillOpacity), ln] });
|
|
5227
5580
|
};
|
|
5228
5581
|
const markerElement = (symbol, sizePt, color, lineColor) => {
|
|
5229
5582
|
const children = [];
|
|
@@ -5235,7 +5588,7 @@ const markerElement = (symbol, sizePt, color, lineColor) => {
|
|
|
5235
5588
|
}
|
|
5236
5589
|
return elem(c("marker"), { children });
|
|
5237
5590
|
};
|
|
5238
|
-
const dPtElements = (colors, explosions) => {
|
|
5591
|
+
const dPtElements = (colors, explosions, fillOpacity, bubble3D) => {
|
|
5239
5592
|
const out = [];
|
|
5240
5593
|
const colorLen = colors?.length ?? 0;
|
|
5241
5594
|
const explLen = explosions?.length ?? 0;
|
|
@@ -5244,12 +5597,9 @@ const dPtElements = (colors, explosions) => {
|
|
|
5244
5597
|
const color = colors?.[i] ?? null;
|
|
5245
5598
|
const expl = explosions?.[i] ?? null;
|
|
5246
5599
|
if (color === null && (expl === null || !Number.isFinite(expl))) continue;
|
|
5247
|
-
const children = [valNode(c("idx"), i), valNode(c("bubble3D"), "0")];
|
|
5600
|
+
const children = [valNode(c("idx"), i), valNode(c("bubble3D"), bubble3D ? "1" : "0")];
|
|
5248
5601
|
if (expl !== null) children.push(valNode(c("explosion"), Math.round(expl)));
|
|
5249
|
-
if (color !== null)
|
|
5250
|
-
const hex = color.replace(/^#/, "").toUpperCase();
|
|
5251
|
-
children.push(solidFillSpPr(hex));
|
|
5252
|
-
}
|
|
5602
|
+
if (color !== null) children.push(solidFillSpPr(color, fillOpacity));
|
|
5253
5603
|
out.push(elem(c("dPt"), { children }));
|
|
5254
5604
|
}
|
|
5255
5605
|
return out;
|
|
@@ -5271,39 +5621,121 @@ const trendlineElement = (tl) => {
|
|
|
5271
5621
|
if (tl.displayEquation) children.push(valNode(c("dispEq"), "1"));
|
|
5272
5622
|
return elem(c("trendline"), { children });
|
|
5273
5623
|
};
|
|
5274
|
-
const
|
|
5624
|
+
const errBarsElement = (bars, direction) => {
|
|
5625
|
+
const children = [];
|
|
5626
|
+
if (direction !== null) children.push(valNode(c("errDir"), direction));
|
|
5627
|
+
children.push(valNode(c("errBarType"), bars.barType), valNode(c("errValType"), bars.amount.type));
|
|
5628
|
+
if (bars.noEndCap !== void 0) children.push(valNode(c("noEndCap"), bars.noEndCap ? "1" : "0"));
|
|
5629
|
+
if (bars.amount.type === "cust") {
|
|
5630
|
+
const literal = (name, points) => elem(c(name), { children: [elem(c("numLit"), { children: numDataChildren(points, "General") })] });
|
|
5631
|
+
if (bars.amount.plus !== void 0) children.push(literal("plus", bars.amount.plus));
|
|
5632
|
+
if (bars.amount.minus !== void 0) children.push(literal("minus", bars.amount.minus));
|
|
5633
|
+
} else if (bars.amount.type !== "stdErr") children.push(valNode(c("val"), bars.amount.value));
|
|
5634
|
+
const spPr = lineSpPr(bars.color, bars.lineWidthEmu, "chart series: errorBars.lineWidthEmu");
|
|
5635
|
+
if (spPr !== null) children.push(spPr);
|
|
5636
|
+
return elem(c("errBars"), { children });
|
|
5637
|
+
};
|
|
5638
|
+
const SERIES_SHAPE = {
|
|
5639
|
+
bar: "bar",
|
|
5640
|
+
column: "bar",
|
|
5641
|
+
line: "line",
|
|
5642
|
+
stock: "line",
|
|
5643
|
+
area: "area",
|
|
5644
|
+
pie: "pie",
|
|
5645
|
+
doughnut: "pie",
|
|
5646
|
+
scatter: "scatter",
|
|
5647
|
+
bubble: "bubble",
|
|
5648
|
+
radar: "radar",
|
|
5649
|
+
surface: "surface"
|
|
5650
|
+
};
|
|
5651
|
+
const SHAPES_WITH_MARKER = new Set([
|
|
5652
|
+
"line",
|
|
5653
|
+
"scatter",
|
|
5654
|
+
"radar"
|
|
5655
|
+
]);
|
|
5656
|
+
const SHAPES_WITH_TRENDLINE = new Set([
|
|
5657
|
+
"bar",
|
|
5658
|
+
"line",
|
|
5659
|
+
"area",
|
|
5660
|
+
"scatter",
|
|
5661
|
+
"bubble"
|
|
5662
|
+
]);
|
|
5663
|
+
const SHAPES_WITH_ERR_BARS = SHAPES_WITH_TRENDLINE;
|
|
5664
|
+
const SHAPES_WITH_INVERT = new Set(["bar", "bubble"]);
|
|
5665
|
+
const SCATTER_STYLES_WITH_LINE = new Set([
|
|
5666
|
+
"line",
|
|
5667
|
+
"lineMarker",
|
|
5668
|
+
"smooth",
|
|
5669
|
+
"smoothMarker"
|
|
5670
|
+
]);
|
|
5671
|
+
const SCATTER_STYLES_WITH_MARKER = new Set([
|
|
5672
|
+
"marker",
|
|
5673
|
+
"lineMarker",
|
|
5674
|
+
"smoothMarker"
|
|
5675
|
+
]);
|
|
5676
|
+
const categoryChannel = (spec, formula) => {
|
|
5677
|
+
if (spec.categoryAxisDate !== void 0) return elem(c("cat"), { children: [numRef(formula, spec.categories.map(dateSerial), spec.categoryAxisNumberFormat ?? "General")] });
|
|
5678
|
+
if (spec.categoryGroupLevels !== void 0 && spec.categoryGroupLevels.length > 0) return elem(c("cat"), { children: [multiLvlStrRef(formula, [spec.categories, ...spec.categoryGroupLevels], spec.categories.length)] });
|
|
5679
|
+
return elem(c("cat"), { children: [strRef(formula, spec.categories)] });
|
|
5680
|
+
};
|
|
5681
|
+
const padTo = (values, length) => Array.from({ length }, (_, i) => values?.[i] ?? null);
|
|
5682
|
+
const seriesElement = (spec, seriesIdx, layout) => {
|
|
5275
5683
|
const series = spec.series[seriesIdx];
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
const
|
|
5279
|
-
const valRange = `${sheet}!$${String.fromCharCode(66 + seriesIdx)}$2:$${String.fromCharCode(66 + seriesIdx)}$${spec.categories.length + 1}`;
|
|
5280
|
-
const color = series.color !== void 0 ? series.color.replace(/^#/, "").toUpperCase() : DEFAULT_ACCENT_COLORS[seriesIdx % DEFAULT_ACCENT_COLORS.length] ?? "4472C4";
|
|
5281
|
-
const paddedValues = [];
|
|
5282
|
-
for (let i = 0; i < spec.categories.length; i++) paddedValues.push(i < series.values.length ? series.values[i] ?? null : null);
|
|
5684
|
+
const refs = layout.series[seriesIdx];
|
|
5685
|
+
if (!series || !refs) throw new Error("seriesElement: out of range");
|
|
5686
|
+
const color = series.color !== void 0 ? hexOf(series.color) : DEFAULT_ACCENT_COLORS[seriesIdx % DEFAULT_ACCENT_COLORS.length] ?? "4472C4";
|
|
5283
5687
|
const kind = series.chartKind ?? spec.kind;
|
|
5688
|
+
const shape = SERIES_SHAPE[kind];
|
|
5284
5689
|
const children = [
|
|
5285
5690
|
valNode(c("idx"), seriesIdx),
|
|
5286
5691
|
valNode(c("order"), seriesIdx),
|
|
5287
|
-
elem(c("tx"), { children: [strRef(
|
|
5692
|
+
elem(c("tx"), { children: [strRef(refs.name, [series.name])] })
|
|
5288
5693
|
];
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5694
|
+
const isXy = shape === "scatter" || shape === "bubble";
|
|
5695
|
+
const pointCount = isXy ? series.values.length : spec.categories.length;
|
|
5696
|
+
const channels = [];
|
|
5697
|
+
if (isXy) {
|
|
5698
|
+
if (refs.xValues === void 0) throw new Error("seriesElement: xy series without an x range");
|
|
5699
|
+
channels.push(elem(c("xVal"), { children: [numRef(refs.xValues, padTo(series.xValues, pointCount))] }), elem(c("yVal"), { children: [numRef(refs.values, padTo(series.values, pointCount))] }));
|
|
5700
|
+
if (shape === "bubble") {
|
|
5701
|
+
if (refs.bubbleSizes === void 0) throw new Error("seriesElement: bubble series without a size range");
|
|
5702
|
+
channels.push(elem(c("bubbleSize"), { children: [numRef(refs.bubbleSizes, padTo(series.bubbleSizes, pointCount))] }), valNode(c("bubble3D"), spec.bubble3D === true ? "1" : "0"));
|
|
5703
|
+
}
|
|
5704
|
+
} else {
|
|
5705
|
+
if (layout.categories === void 0) throw new Error("seriesElement: category series without a category range");
|
|
5706
|
+
channels.push(categoryChannel(spec, layout.categories), elem(c("val"), { children: [numRef(refs.values, padTo(series.values, pointCount))] }));
|
|
5707
|
+
}
|
|
5708
|
+
if (shape === "surface") return elem(c("ser"), { children: [...children, ...channels] });
|
|
5709
|
+
const scatterStyle = spec.scatterStyle ?? "marker";
|
|
5710
|
+
const lineHidden = spec.kind === "stock" || shape === "scatter" && !SCATTER_STYLES_WITH_LINE.has(scatterStyle);
|
|
5711
|
+
if (lineHidden || shape === "line" || shape === "scatter" || shape === "radar" || series.lineWidthEmu !== void 0 || series.lineColor !== void 0 || series.lineDash !== void 0) {
|
|
5712
|
+
const lineColor = lineHidden ? null : series.lineColor !== void 0 ? hexOf(series.lineColor) : color;
|
|
5713
|
+
children.push(seriesSpPr(color, lineColor, series.lineWidthEmu, series.lineDash, series.fillOpacity));
|
|
5714
|
+
} else children.push(solidFillSpPr(color, series.fillOpacity));
|
|
5715
|
+
if (series.invertIfNegative === true && SHAPES_WITH_INVERT.has(shape)) children.push(valNode(c("invertIfNegative"), "1"));
|
|
5716
|
+
if (SHAPES_WITH_MARKER.has(shape)) {
|
|
5717
|
+
const markerColor = series.markerColor !== void 0 ? hexOf(series.markerColor) : color;
|
|
5718
|
+
const markerLineColor = series.markerLineColor !== void 0 ? hexOf(series.markerLineColor) : markerColor;
|
|
5719
|
+
const markersOff = spec.kind === "stock" || shape === "scatter" && !SCATTER_STYLES_WITH_MARKER.has(scatterStyle) || shape === "radar" && spec.radarStyle !== "marker";
|
|
5720
|
+
children.push(markerElement(series.markerSymbol ?? (markersOff ? "none" : void 0), series.markerSizePt, markerColor, markerLineColor));
|
|
5721
|
+
}
|
|
5722
|
+
for (const dPt of dPtElements(series.pointColors, series.pointExplosions, series.fillOpacity, spec.bubble3D === true)) children.push(dPt);
|
|
5300
5723
|
if (series.pointDataLabels !== void 0 && series.dataLabels === void 0) throw new Error(`chart: series '${series.name}' sets pointDataLabels without dataLabels; add the series-level dataLabels the overrides fall back to`);
|
|
5301
5724
|
const serDLbls = buildDLblsFromLabels(series.dataLabels, series.pointDataLabels);
|
|
5302
5725
|
if (serDLbls !== null) children.push(serDLbls);
|
|
5303
|
-
if (series.trendline &&
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5726
|
+
if (series.trendline && SHAPES_WITH_TRENDLINE.has(shape) && spec.kind !== "stock") children.push(trendlineElement(series.trendline));
|
|
5727
|
+
if (series.errorBars !== void 0 || series.xErrorBars !== void 0) {
|
|
5728
|
+
if (!SHAPES_WITH_ERR_BARS.has(shape)) throw new Error(`chart: series '${series.name}' sets error bars, which a ${kind} series cannot carry (bar / column / line / area / scatter / bubble only)`);
|
|
5729
|
+
if (series.xErrorBars !== void 0 && !isXy) throw new Error(`chart: series '${series.name}' sets xErrorBars, which only scatter / bubble series have an x channel for`);
|
|
5730
|
+
if (series.xErrorBars !== void 0) children.push(errBarsElement(series.xErrorBars, "x"));
|
|
5731
|
+
if (series.errorBars !== void 0) children.push(errBarsElement(series.errorBars, isXy ? "y" : null));
|
|
5732
|
+
}
|
|
5733
|
+
children.push(...channels);
|
|
5734
|
+
if (shape === "line") children.push(valNode(c("smooth"), series.smooth === true ? "1" : "0"));
|
|
5735
|
+
else if (shape === "scatter") {
|
|
5736
|
+
const smooth = series.smooth ?? (scatterStyle === "smooth" || scatterStyle === "smoothMarker");
|
|
5737
|
+
children.push(valNode(c("smooth"), smooth ? "1" : "0"));
|
|
5738
|
+
}
|
|
5307
5739
|
return elem(c("ser"), { children });
|
|
5308
5740
|
};
|
|
5309
5741
|
const CAT_AX_ID = 111111111;
|
|
@@ -5369,9 +5801,13 @@ const axisTxPrElement = (style, rotationDeg) => {
|
|
|
5369
5801
|
};
|
|
5370
5802
|
const catAxis = (spec) => {
|
|
5371
5803
|
const catOrientation = spec.categoryAxisOrientation ?? "minMax";
|
|
5804
|
+
const dateAxis = spec.categoryAxisDate;
|
|
5805
|
+
const scalingChildren = [valNode(c("orientation"), catOrientation)];
|
|
5806
|
+
if (spec.categoryAxisScaling?.max !== void 0) scalingChildren.push(valNode(c("max"), spec.categoryAxisScaling.max));
|
|
5807
|
+
if (spec.categoryAxisScaling?.min !== void 0) scalingChildren.push(valNode(c("min"), spec.categoryAxisScaling.min));
|
|
5372
5808
|
const children = [
|
|
5373
5809
|
valNode(c("axId"), CAT_AX_ID),
|
|
5374
|
-
elem(c("scaling"), { children:
|
|
5810
|
+
elem(c("scaling"), { children: scalingChildren }),
|
|
5375
5811
|
valNode(c("delete"), spec.categoryAxisHidden ? "1" : "0"),
|
|
5376
5812
|
valNode(c("axPos"), isHorizontalBar(spec) ? "l" : "b")
|
|
5377
5813
|
];
|
|
@@ -5382,11 +5818,21 @@ const catAxis = (spec) => {
|
|
|
5382
5818
|
if (spec.categoryAxisMajorTickMark !== void 0) children.push(valNode(c("majorTickMark"), spec.categoryAxisMajorTickMark));
|
|
5383
5819
|
if (spec.categoryAxisMinorTickMark !== void 0) children.push(valNode(c("minorTickMark"), spec.categoryAxisMinorTickMark));
|
|
5384
5820
|
if (spec.categoryAxisTickLabelPos !== void 0) children.push(valNode(c("tickLblPos"), spec.categoryAxisTickLabelPos));
|
|
5385
|
-
const catLine = lineSpPr(spec.categoryAxisLineColor, spec.categoryAxisLineWidthEmu, "chart: categoryAxisLineWidthEmu");
|
|
5821
|
+
const catLine = lineSpPr(spec.categoryAxisLineColor, spec.categoryAxisLineWidthEmu, "chart: categoryAxisLineWidthEmu", spec.categoryAxisLineHidden === true);
|
|
5386
5822
|
if (catLine !== null) children.push(catLine);
|
|
5387
5823
|
const catTxPr = axisTxPrElement(spec.categoryAxisLabelStyle, spec.categoryAxisLabelRotationDeg);
|
|
5388
5824
|
if (catTxPr) children.push(catTxPr);
|
|
5389
5825
|
children.push(valNode(c("crossAx"), VAL_AX_ID));
|
|
5826
|
+
if (dateAxis !== void 0) {
|
|
5827
|
+
children.push(valNode(c("auto"), "0"));
|
|
5828
|
+
if (spec.categoryAxisLabelOffset !== void 0) children.push(valNode(c("lblOffset"), spec.categoryAxisLabelOffset));
|
|
5829
|
+
if (dateAxis.baseTimeUnit !== void 0) children.push(valNode(c("baseTimeUnit"), dateAxis.baseTimeUnit));
|
|
5830
|
+
if (dateAxis.majorUnit !== void 0) children.push(valNode(c("majorUnit"), dateAxis.majorUnit));
|
|
5831
|
+
if (dateAxis.majorTimeUnit !== void 0) children.push(valNode(c("majorTimeUnit"), dateAxis.majorTimeUnit));
|
|
5832
|
+
if (dateAxis.minorUnit !== void 0) children.push(valNode(c("minorUnit"), dateAxis.minorUnit));
|
|
5833
|
+
if (dateAxis.minorTimeUnit !== void 0) children.push(valNode(c("minorTimeUnit"), dateAxis.minorTimeUnit));
|
|
5834
|
+
return elem(c("dateAx"), { children });
|
|
5835
|
+
}
|
|
5390
5836
|
if (spec.categoryAxisLabelAlign !== void 0) children.push(valNode(c("lblAlgn"), spec.categoryAxisLabelAlign));
|
|
5391
5837
|
if (spec.categoryAxisLabelOffset !== void 0) children.push(valNode(c("lblOffset"), spec.categoryAxisLabelOffset));
|
|
5392
5838
|
if (spec.categoryAxisTickLabelSkip !== void 0) children.push(valNode(c("tickLblSkip"), spec.categoryAxisTickLabelSkip));
|
|
@@ -5413,7 +5859,7 @@ const valueAxisElement = (f, ids) => {
|
|
|
5413
5859
|
if (f.majorTickMark !== void 0) children.push(valNode(c("majorTickMark"), f.majorTickMark));
|
|
5414
5860
|
if (f.minorTickMark !== void 0) children.push(valNode(c("minorTickMark"), f.minorTickMark));
|
|
5415
5861
|
if (f.tickLabelPos !== void 0) children.push(valNode(c("tickLblPos"), f.tickLabelPos));
|
|
5416
|
-
const axisLine = lineSpPr(f.lineColor, f.lineWidthEmu, `chart: ${f.widthFields.line}
|
|
5862
|
+
const axisLine = lineSpPr(f.lineColor, f.lineWidthEmu, `chart: ${f.widthFields.line}`, f.lineHidden === true);
|
|
5417
5863
|
if (axisLine !== null) children.push(axisLine);
|
|
5418
5864
|
const valTxPr = axisTxPrElement(f.labelStyle, f.labelRotationDeg);
|
|
5419
5865
|
if (valTxPr) children.push(valTxPr);
|
|
@@ -5424,7 +5870,7 @@ const valueAxisElement = (f, ids) => {
|
|
|
5424
5870
|
if (f.crossBetween !== void 0) children.push(valNode(c("crossBetween"), f.crossBetween));
|
|
5425
5871
|
if (f.scaling?.majorUnit !== void 0) children.push(valNode(c("majorUnit"), f.scaling.majorUnit));
|
|
5426
5872
|
if (f.scaling?.minorUnit !== void 0) children.push(valNode(c("minorUnit"), f.scaling.minorUnit));
|
|
5427
|
-
if (f.scaling?.displayUnits !== void 0) children.push(elem(c("dispUnits"), { children: [valNode(c("builtInUnit"), f.scaling.displayUnits)] }));
|
|
5873
|
+
if (f.scaling?.displayUnits !== void 0) children.push(elem(c("dispUnits"), { children: [valNode(c("builtInUnit"), f.scaling.displayUnits), ...f.scaling.displayUnitsLabel === true ? [elem(c("dispUnitsLbl"))] : []] }));
|
|
5428
5874
|
return elem(c("valAx"), { children });
|
|
5429
5875
|
};
|
|
5430
5876
|
const isHorizontalBar = (spec) => spec.kind === "bar";
|
|
@@ -5446,6 +5892,7 @@ const valAxis = (spec) => valueAxisElement({
|
|
|
5446
5892
|
tickLabelPos: spec.valueAxisTickLabelPos,
|
|
5447
5893
|
lineColor: spec.valueAxisLineColor,
|
|
5448
5894
|
lineWidthEmu: spec.valueAxisLineWidthEmu,
|
|
5895
|
+
lineHidden: spec.valueAxisLineHidden,
|
|
5449
5896
|
widthFields: {
|
|
5450
5897
|
majorGridline: "valueAxisMajorGridlineWidthEmu",
|
|
5451
5898
|
minorGridline: "valueAxisMinorGridlineWidthEmu",
|
|
@@ -5460,11 +5907,78 @@ const valAxis = (spec) => valueAxisElement({
|
|
|
5460
5907
|
crossAxId: CAT_AX_ID,
|
|
5461
5908
|
axPos: isHorizontalBar(spec) ? "b" : "l"
|
|
5462
5909
|
});
|
|
5910
|
+
/**
|
|
5911
|
+
* The horizontal axis of a scatter / bubble chart. Both of their axes are
|
|
5912
|
+
* `<c:valAx>`; this one takes the spec's `categoryAxis*` fields, so an
|
|
5913
|
+
* author formats "the axis along the bottom" the same way for every kind.
|
|
5914
|
+
* It keeps the category axis' id, which the y axis already crosses.
|
|
5915
|
+
*/
|
|
5916
|
+
const xValAxis = (spec) => valueAxisElement({
|
|
5917
|
+
scaling: {
|
|
5918
|
+
...spec.categoryAxisScaling,
|
|
5919
|
+
...spec.categoryAxisNumberFormat !== void 0 ? { numberFormat: spec.categoryAxisNumberFormat } : {}
|
|
5920
|
+
},
|
|
5921
|
+
orientation: spec.categoryAxisOrientation,
|
|
5922
|
+
hidden: spec.categoryAxisHidden,
|
|
5923
|
+
majorGridlines: spec.categoryAxisMajorGridlines,
|
|
5924
|
+
majorGridlineColor: spec.categoryAxisMajorGridlineColor,
|
|
5925
|
+
majorGridlineWidthEmu: spec.categoryAxisMajorGridlineWidthEmu,
|
|
5926
|
+
minorGridlines: spec.categoryAxisMinorGridlines,
|
|
5927
|
+
minorGridlineColor: spec.categoryAxisMinorGridlineColor,
|
|
5928
|
+
minorGridlineWidthEmu: spec.categoryAxisMinorGridlineWidthEmu,
|
|
5929
|
+
title: spec.categoryAxisTitle,
|
|
5930
|
+
titleStyle: spec.categoryAxisTitleStyle,
|
|
5931
|
+
titleRotationDeg: spec.categoryAxisTitleRotationDeg,
|
|
5932
|
+
majorTickMark: spec.categoryAxisMajorTickMark,
|
|
5933
|
+
minorTickMark: spec.categoryAxisMinorTickMark,
|
|
5934
|
+
tickLabelPos: spec.categoryAxisTickLabelPos,
|
|
5935
|
+
lineColor: spec.categoryAxisLineColor,
|
|
5936
|
+
lineWidthEmu: spec.categoryAxisLineWidthEmu,
|
|
5937
|
+
lineHidden: spec.categoryAxisLineHidden,
|
|
5938
|
+
widthFields: {
|
|
5939
|
+
majorGridline: "categoryAxisMajorGridlineWidthEmu",
|
|
5940
|
+
minorGridline: "categoryAxisMinorGridlineWidthEmu",
|
|
5941
|
+
line: "categoryAxisLineWidthEmu"
|
|
5942
|
+
},
|
|
5943
|
+
labelStyle: spec.categoryAxisLabelStyle,
|
|
5944
|
+
labelRotationDeg: spec.categoryAxisLabelRotationDeg,
|
|
5945
|
+
crosses: void 0,
|
|
5946
|
+
crossBetween: "midCat"
|
|
5947
|
+
}, {
|
|
5948
|
+
axId: CAT_AX_ID,
|
|
5949
|
+
crossAxId: VAL_AX_ID,
|
|
5950
|
+
axPos: "b"
|
|
5951
|
+
});
|
|
5952
|
+
const SER_AX_ID = 555555555;
|
|
5953
|
+
/** `<c:serAx>` — the depth axis of a 3-D or surface chart; it crosses the value axis. */
|
|
5954
|
+
const serAxis = (spec) => {
|
|
5955
|
+
const s = spec.seriesAxis ?? {};
|
|
5956
|
+
const children = [
|
|
5957
|
+
valNode(c("axId"), SER_AX_ID),
|
|
5958
|
+
elem(c("scaling"), { children: [valNode(c("orientation"), s.orientation ?? "minMax")] }),
|
|
5959
|
+
valNode(c("delete"), s.hidden ? "1" : "0"),
|
|
5960
|
+
valNode(c("axPos"), "b")
|
|
5961
|
+
];
|
|
5962
|
+
if (s.majorGridlines) children.push(elem(c("majorGridlines")));
|
|
5963
|
+
if (s.title !== void 0) children.push(titleElement(s.title, s.titleStyle));
|
|
5964
|
+
if (s.tickLabelPos !== void 0) children.push(valNode(c("tickLblPos"), s.tickLabelPos));
|
|
5965
|
+
const line = lineSpPr(s.lineColor, void 0, "chart: seriesAxis");
|
|
5966
|
+
if (line !== null) children.push(line);
|
|
5967
|
+
const txPr = axisTxPrElement(s.labelStyle, void 0);
|
|
5968
|
+
if (txPr !== null) children.push(txPr);
|
|
5969
|
+
children.push(valNode(c("crossAx"), VAL_AX_ID));
|
|
5970
|
+
if (s.tickLabelSkip !== void 0) children.push(valNode(c("tickLblSkip"), s.tickLabelSkip));
|
|
5971
|
+
return elem(c("serAx"), { children });
|
|
5972
|
+
};
|
|
5463
5973
|
const buildDLblsFromLabels = (dl, pointLabels = void 0) => {
|
|
5464
5974
|
const children = [];
|
|
5465
5975
|
pointLabels?.forEach((pl, i) => {
|
|
5466
5976
|
if (pl === null) return;
|
|
5467
|
-
children.push(elem(c("dLbl"), { children: [
|
|
5977
|
+
children.push(elem(c("dLbl"), { children: [
|
|
5978
|
+
valNode(c("idx"), i),
|
|
5979
|
+
...pl.text !== void 0 ? [elem(c("tx"), { children: [richText(pl.text)] })] : [],
|
|
5980
|
+
...dLblGroupChildren(pl)
|
|
5981
|
+
] }));
|
|
5468
5982
|
});
|
|
5469
5983
|
if (dl) {
|
|
5470
5984
|
children.push(...dLblGroupChildren(dl));
|
|
@@ -5475,93 +5989,220 @@ const buildDLblsFromLabels = (dl, pointLabels = void 0) => {
|
|
|
5475
5989
|
const dLblGroupChildren = (dl) => {
|
|
5476
5990
|
const children = [];
|
|
5477
5991
|
if (dl.numberFormat !== void 0) children.push(elem(c("numFmt"), { attrs: [attr(qname("", "formatCode", ""), dl.numberFormat), attr(qname("", "sourceLinked", ""), "0")] }));
|
|
5992
|
+
if (dl.fillColor !== void 0) children.push(solidFillSpPr(dl.fillColor));
|
|
5478
5993
|
if (dl.textStyle !== void 0) {
|
|
5479
5994
|
const txPr = axisTxPrElement(dl.textStyle, void 0);
|
|
5480
5995
|
if (txPr !== null) children.push(txPr);
|
|
5481
5996
|
}
|
|
5482
5997
|
if (dl.position !== void 0) children.push(valNode(c("dLblPos"), dl.position));
|
|
5483
|
-
children.push(valNode(c("showLegendKey"), "0"), valNode(c("showVal"), dl.showValue ? "1" : "0"), valNode(c("showCatName"), dl.showCategory ? "1" : "0"), valNode(c("showSerName"), dl.showSeriesName ? "1" : "0"), valNode(c("showPercent"), dl.showPercent ? "1" : "0"), valNode(c("showBubbleSize"), "0"));
|
|
5998
|
+
children.push(valNode(c("showLegendKey"), dl.showLegendKey ? "1" : "0"), valNode(c("showVal"), dl.showValue ? "1" : "0"), valNode(c("showCatName"), dl.showCategory ? "1" : "0"), valNode(c("showSerName"), dl.showSeriesName ? "1" : "0"), valNode(c("showPercent"), dl.showPercent ? "1" : "0"), valNode(c("showBubbleSize"), dl.showBubbleSize ? "1" : "0"));
|
|
5484
5999
|
if (dl.separator !== void 0) children.push(elem(c("separator"), { children: [text(dl.separator)] }));
|
|
5485
6000
|
return children;
|
|
5486
6001
|
};
|
|
5487
6002
|
const dLblsElement = (spec) => buildDLblsFromLabels(spec.dataLabels);
|
|
5488
|
-
const
|
|
5489
|
-
|
|
5490
|
-
const dl = dLblsElement(spec);
|
|
6003
|
+
const groupSeries = (g) => g.seriesIndices.map((i) => seriesElement(g.spec, i, g.layout));
|
|
6004
|
+
const groupDLbls = (g) => {
|
|
6005
|
+
const dl = dLblsElement(g.spec);
|
|
6006
|
+
return dl ? [dl] : [];
|
|
6007
|
+
};
|
|
6008
|
+
const isThreeD = (spec) => spec.view3D !== void 0;
|
|
6009
|
+
/**
|
|
6010
|
+
* Whether the chart carries a series (depth) axis. `<c:line3DChart>` and
|
|
6011
|
+
* the surface elements require three axes; 3-D bar / area charts only lay
|
|
6012
|
+
* their series out in depth — and so only have the axis — under the
|
|
6013
|
+
* `standard` grouping.
|
|
6014
|
+
*/
|
|
6015
|
+
const hasSeriesAxis = (spec) => {
|
|
6016
|
+
if (spec.kind === "surface") return true;
|
|
6017
|
+
if (!isThreeD(spec)) return false;
|
|
6018
|
+
if (spec.kind === "line") return true;
|
|
6019
|
+
return (spec.kind === "bar" || spec.kind === "column" || spec.kind === "area") && spec.grouping === "standard";
|
|
6020
|
+
};
|
|
6021
|
+
const axIdNodes = (g) => [
|
|
6022
|
+
valNode(c("axId"), g.axes.cat),
|
|
6023
|
+
valNode(c("axId"), g.axes.val),
|
|
6024
|
+
...hasSeriesAxis(g.spec) ? [valNode(c("axId"), SER_AX_ID)] : []
|
|
6025
|
+
];
|
|
6026
|
+
const gapDepthNodes = (spec) => spec.gapDepthPct !== void 0 ? [valNode(c("gapDepth"), gapAmountPercent(spec.gapDepthPct, "chart: gapDepthPct"))] : [];
|
|
6027
|
+
const buildBarChart = (g, direction) => {
|
|
6028
|
+
const { spec } = g;
|
|
5491
6029
|
const grouping = spec.grouping ?? "clustered";
|
|
5492
6030
|
const children = [
|
|
5493
6031
|
valNode(c("barDir"), direction),
|
|
5494
6032
|
valNode(c("grouping"), grouping),
|
|
5495
6033
|
valNode(c("varyColors"), spec.varyColors ? "1" : "0"),
|
|
5496
|
-
...
|
|
5497
|
-
...
|
|
6034
|
+
...groupSeries(g),
|
|
6035
|
+
...groupDLbls(g)
|
|
5498
6036
|
];
|
|
5499
6037
|
if (spec.gapWidthPct !== void 0) children.push(valNode(c("gapWidth"), gapAmountPercent(spec.gapWidthPct, "chart: gapWidthPct")));
|
|
6038
|
+
if (isThreeD(spec)) {
|
|
6039
|
+
children.push(...gapDepthNodes(spec));
|
|
6040
|
+
if (spec.bar3DShape !== void 0) children.push(valNode(c("shape"), spec.bar3DShape));
|
|
6041
|
+
children.push(...axIdNodes(g));
|
|
6042
|
+
return elem(c("bar3DChart"), { children });
|
|
6043
|
+
}
|
|
5500
6044
|
const overlapPct = spec.overlapPct ?? (grouping === "stacked" || grouping === "percentStacked" ? 100 : void 0);
|
|
5501
6045
|
if (overlapPct !== void 0) children.push(valNode(c("overlap"), overlapPercent(overlapPct, "chart: overlapPct")));
|
|
5502
|
-
children.push(
|
|
5503
|
-
return elem(c(
|
|
6046
|
+
children.push(...axIdNodes(g));
|
|
6047
|
+
return elem(c("barChart"), { children });
|
|
5504
6048
|
};
|
|
5505
6049
|
const lineAreaGrouping = (spec) => spec.grouping === "stacked" || spec.grouping === "percentStacked" ? spec.grouping : "standard";
|
|
5506
|
-
const
|
|
5507
|
-
const
|
|
5508
|
-
|
|
6050
|
+
const upDownBarsElement = (bars) => {
|
|
6051
|
+
const bar = (name, color) => elem(c(name), { children: color !== void 0 ? [solidFillSpPr(color)] : [] });
|
|
6052
|
+
return elem(c("upDownBars"), { children: [
|
|
6053
|
+
...bars.gapWidthPct !== void 0 ? [valNode(c("gapWidth"), gapAmountPercent(bars.gapWidthPct, "chart: upDownBars.gapWidthPct"))] : [],
|
|
6054
|
+
bar("upBars", bars.upColor),
|
|
6055
|
+
bar("downBars", bars.downColor)
|
|
6056
|
+
] });
|
|
6057
|
+
};
|
|
6058
|
+
const buildLineChart = (g) => {
|
|
6059
|
+
const { spec } = g;
|
|
5509
6060
|
const children = [
|
|
5510
6061
|
valNode(c("grouping"), lineAreaGrouping(spec)),
|
|
5511
6062
|
valNode(c("varyColors"), spec.varyColors ? "1" : "0"),
|
|
5512
|
-
...
|
|
5513
|
-
...
|
|
6063
|
+
...groupSeries(g),
|
|
6064
|
+
...groupDLbls(g)
|
|
5514
6065
|
];
|
|
5515
6066
|
if (spec.dropLines) children.push(elem(c("dropLines")));
|
|
6067
|
+
if (isThreeD(spec)) {
|
|
6068
|
+
if (spec.hiLowLines || spec.upDownBars !== void 0) throw new Error("chart: hiLowLines / upDownBars are not available on a 3-D line chart");
|
|
6069
|
+
children.push(...gapDepthNodes(spec), ...axIdNodes(g));
|
|
6070
|
+
return elem(c("line3DChart"), { children });
|
|
6071
|
+
}
|
|
5516
6072
|
if (spec.hiLowLines) children.push(elem(c("hiLowLines")));
|
|
5517
|
-
|
|
6073
|
+
if (spec.upDownBars !== void 0) children.push(upDownBarsElement(spec.upDownBars));
|
|
6074
|
+
children.push(valNode(c("marker"), spec.lineMarkers === false ? "0" : "1"), ...axIdNodes(g));
|
|
5518
6075
|
return elem(c("lineChart"), { children });
|
|
5519
6076
|
};
|
|
5520
|
-
const
|
|
5521
|
-
|
|
5522
|
-
const ser = seriesElement(spec, 0, sheet);
|
|
5523
|
-
const dl = dLblsElement(spec);
|
|
6077
|
+
const buildAreaChart = (g) => {
|
|
6078
|
+
const { spec } = g;
|
|
5524
6079
|
const children = [
|
|
5525
|
-
valNode(c("
|
|
5526
|
-
|
|
5527
|
-
...
|
|
6080
|
+
valNode(c("grouping"), lineAreaGrouping(spec)),
|
|
6081
|
+
valNode(c("varyColors"), spec.varyColors ? "1" : "0"),
|
|
6082
|
+
...groupSeries(g),
|
|
6083
|
+
...groupDLbls(g)
|
|
5528
6084
|
];
|
|
5529
|
-
if (spec.
|
|
5530
|
-
|
|
6085
|
+
if (spec.dropLines && spec.kind === "area") children.push(elem(c("dropLines")));
|
|
6086
|
+
if (isThreeD(spec)) {
|
|
6087
|
+
children.push(...gapDepthNodes(spec), ...axIdNodes(g));
|
|
6088
|
+
return elem(c("area3DChart"), { children });
|
|
6089
|
+
}
|
|
6090
|
+
children.push(...axIdNodes(g));
|
|
6091
|
+
return elem(c("areaChart"), { children });
|
|
5531
6092
|
};
|
|
5532
|
-
const
|
|
5533
|
-
if (spec.series.length !== 1) throw new Error(
|
|
5534
|
-
|
|
5535
|
-
|
|
6093
|
+
const requireSingleSeries = (spec) => {
|
|
6094
|
+
if (spec.series.length !== 1) throw new Error(`${spec.kind} chart requires exactly one series`);
|
|
6095
|
+
};
|
|
6096
|
+
const firstSliceAngNodes = (spec) => spec.firstSliceAngleDeg !== void 0 ? [valNode(c("firstSliceAng"), firstSliceAngle(spec.firstSliceAngleDeg, "chart: firstSliceAngleDeg"))] : [];
|
|
6097
|
+
const buildOfPieChart = (g, ofPie) => {
|
|
5536
6098
|
const children = [
|
|
6099
|
+
valNode(c("ofPieType"), ofPie.type),
|
|
5537
6100
|
valNode(c("varyColors"), "1"),
|
|
5538
|
-
|
|
5539
|
-
...
|
|
6101
|
+
...groupSeries(g),
|
|
6102
|
+
...groupDLbls(g)
|
|
5540
6103
|
];
|
|
5541
|
-
if (
|
|
5542
|
-
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
|
|
5548
|
-
return elem(c("
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
6104
|
+
if (ofPie.gapWidthPct !== void 0) children.push(valNode(c("gapWidth"), gapAmountPercent(ofPie.gapWidthPct, "chart: ofPie.gapWidthPct")));
|
|
6105
|
+
if (ofPie.customSplit !== void 0 && ofPie.splitType !== "cust") throw new Error("chart: ofPie.customSplit requires ofPie.splitType 'cust'");
|
|
6106
|
+
if (ofPie.splitType !== void 0) children.push(valNode(c("splitType"), ofPie.splitType));
|
|
6107
|
+
if (ofPie.splitPos !== void 0) children.push(valNode(c("splitPos"), ofPie.splitPos));
|
|
6108
|
+
if (ofPie.customSplit !== void 0) children.push(elem(c("custSplit"), { children: ofPie.customSplit.map((idx) => valNode(c("secondPiePt"), idx)) }));
|
|
6109
|
+
if (ofPie.secondPieSizePct !== void 0) children.push(valNode(c("secondPieSize"), boundedInt(ofPie.secondPieSizePct, "secondPieSize", "chart: ofPie.secondPieSizePct")));
|
|
6110
|
+
if (ofPie.seriesLines) children.push(elem(c("serLines")));
|
|
6111
|
+
return elem(c("ofPieChart"), { children });
|
|
6112
|
+
};
|
|
6113
|
+
const buildPieChart = (g) => {
|
|
6114
|
+
const { spec } = g;
|
|
6115
|
+
requireSingleSeries(spec);
|
|
6116
|
+
if (spec.ofPie !== void 0) {
|
|
6117
|
+
if (isThreeD(spec)) throw new Error("chart: ofPie and view3D cannot be combined");
|
|
6118
|
+
return buildOfPieChart(g, spec.ofPie);
|
|
6119
|
+
}
|
|
6120
|
+
const children = [
|
|
6121
|
+
valNode(c("varyColors"), "1"),
|
|
6122
|
+
...groupSeries(g),
|
|
6123
|
+
...groupDLbls(g)
|
|
6124
|
+
];
|
|
6125
|
+
if (isThreeD(spec)) {
|
|
6126
|
+
if (spec.firstSliceAngleDeg !== void 0) throw new Error("chart: a 3-D pie has no firstSliceAngleDeg; rotate it with view3D.rotY");
|
|
6127
|
+
return elem(c("pie3DChart"), { children });
|
|
6128
|
+
}
|
|
6129
|
+
children.push(...firstSliceAngNodes(spec));
|
|
6130
|
+
return elem(c("pieChart"), { children });
|
|
6131
|
+
};
|
|
6132
|
+
const buildDoughnutChart = (g) => {
|
|
6133
|
+
const { spec } = g;
|
|
6134
|
+
requireSingleSeries(spec);
|
|
6135
|
+
return elem(c("doughnutChart"), { children: [
|
|
6136
|
+
valNode(c("varyColors"), "1"),
|
|
6137
|
+
...groupSeries(g),
|
|
6138
|
+
...groupDLbls(g),
|
|
6139
|
+
...firstSliceAngNodes(spec),
|
|
6140
|
+
valNode(c("holeSize"), holeSizePercent(spec.holeSizePct ?? 50, "chart: holeSizePct"))
|
|
5555
6141
|
] });
|
|
5556
6142
|
};
|
|
5557
|
-
|
|
5558
|
-
|
|
6143
|
+
const buildScatterChart = (g) => elem(c("scatterChart"), { children: [
|
|
6144
|
+
valNode(c("scatterStyle"), g.spec.scatterStyle ?? "marker"),
|
|
6145
|
+
valNode(c("varyColors"), g.spec.varyColors ? "1" : "0"),
|
|
6146
|
+
...groupSeries(g),
|
|
6147
|
+
...groupDLbls(g),
|
|
6148
|
+
...axIdNodes(g)
|
|
6149
|
+
] });
|
|
6150
|
+
const buildBubbleChart = (g) => {
|
|
6151
|
+
const { spec } = g;
|
|
6152
|
+
const children = [
|
|
6153
|
+
valNode(c("varyColors"), spec.varyColors ? "1" : "0"),
|
|
6154
|
+
...groupSeries(g),
|
|
6155
|
+
...groupDLbls(g)
|
|
6156
|
+
];
|
|
6157
|
+
if (spec.bubbleScale !== void 0) children.push(valNode(c("bubbleScale"), boundedInt(spec.bubbleScale, "bubbleScale", "chart: bubbleScale")));
|
|
6158
|
+
if (spec.showNegativeBubbles !== void 0) children.push(valNode(c("showNegBubbles"), spec.showNegativeBubbles ? "1" : "0"));
|
|
6159
|
+
if (spec.bubbleSizeRepresents !== void 0) children.push(valNode(c("sizeRepresents"), spec.bubbleSizeRepresents === "width" ? "w" : "area"));
|
|
6160
|
+
children.push(...axIdNodes(g));
|
|
6161
|
+
return elem(c("bubbleChart"), { children });
|
|
6162
|
+
};
|
|
6163
|
+
const buildRadarChart = (g) => elem(c("radarChart"), { children: [
|
|
6164
|
+
valNode(c("radarStyle"), g.spec.radarStyle ?? "standard"),
|
|
6165
|
+
valNode(c("varyColors"), g.spec.varyColors ? "1" : "0"),
|
|
6166
|
+
...groupSeries(g),
|
|
6167
|
+
...groupDLbls(g),
|
|
6168
|
+
...axIdNodes(g)
|
|
6169
|
+
] });
|
|
6170
|
+
const STOCK_SERIES_WITH_OPEN = 4;
|
|
6171
|
+
const STOCK_SERIES_WITHOUT_OPEN = 3;
|
|
6172
|
+
const buildStockChart = (g) => {
|
|
6173
|
+
const { spec } = g;
|
|
6174
|
+
const count = spec.series.length;
|
|
6175
|
+
if (count !== STOCK_SERIES_WITHOUT_OPEN && count !== STOCK_SERIES_WITH_OPEN) throw new Error(`stock chart requires 3 series (high, low, close) or 4 (open, high, low, close); got ${count}`);
|
|
6176
|
+
const children = [...groupSeries(g), ...groupDLbls(g)];
|
|
6177
|
+
if (spec.dropLines) children.push(elem(c("dropLines")));
|
|
6178
|
+
if (spec.hiLowLines !== false) children.push(elem(c("hiLowLines")));
|
|
6179
|
+
if (spec.upDownBars !== void 0 && count !== STOCK_SERIES_WITH_OPEN) throw new Error("stock chart: upDownBars require the 4-series form (open, high, low, close)");
|
|
6180
|
+
if (count === STOCK_SERIES_WITH_OPEN) children.push(upDownBarsElement(spec.upDownBars ?? {}));
|
|
6181
|
+
children.push(...axIdNodes(g));
|
|
6182
|
+
return elem(c("stockChart"), { children });
|
|
6183
|
+
};
|
|
6184
|
+
const buildSurfaceChart = (g) => {
|
|
6185
|
+
const { spec } = g;
|
|
6186
|
+
const children = [];
|
|
6187
|
+
if (spec.surfaceWireframe !== void 0) children.push(valNode(c("wireframe"), spec.surfaceWireframe ? "1" : "0"));
|
|
6188
|
+
children.push(...groupSeries(g), ...axIdNodes(g));
|
|
6189
|
+
return elem(c(spec.surfaceContour === true ? "surfaceChart" : "surface3DChart"), { children });
|
|
6190
|
+
};
|
|
6191
|
+
/** One plot group, dispatched by its effective kind. */
|
|
6192
|
+
const buildPlotGroup = (g, kind) => {
|
|
5559
6193
|
switch (kind) {
|
|
5560
|
-
case "column": return buildBarChart(
|
|
5561
|
-
case "bar": return buildBarChart(
|
|
5562
|
-
case "line": return buildLineChart(
|
|
5563
|
-
case "area": return buildAreaChart(
|
|
5564
|
-
|
|
6194
|
+
case "column": return buildBarChart(g, "col");
|
|
6195
|
+
case "bar": return buildBarChart(g, "bar");
|
|
6196
|
+
case "line": return buildLineChart(g);
|
|
6197
|
+
case "area": return buildAreaChart(g);
|
|
6198
|
+
case "pie": return buildPieChart(g);
|
|
6199
|
+
case "doughnut": return buildDoughnutChart(g);
|
|
6200
|
+
case "scatter": return buildScatterChart(g);
|
|
6201
|
+
case "bubble": return buildBubbleChart(g);
|
|
6202
|
+
case "radar": return buildRadarChart(g);
|
|
6203
|
+
case "stock": return buildStockChart(g);
|
|
6204
|
+
case "surface": return buildSurfaceChart(g);
|
|
6205
|
+
default: throw new Error(`unsupported chart kind: ${String(kind)}`);
|
|
5565
6206
|
}
|
|
5566
6207
|
};
|
|
5567
6208
|
/**
|
|
@@ -5590,6 +6231,7 @@ const secondaryValAxis = (spec) => {
|
|
|
5590
6231
|
tickLabelPos: s.tickLabelPos,
|
|
5591
6232
|
lineColor: s.lineColor,
|
|
5592
6233
|
lineWidthEmu: s.lineWidthEmu,
|
|
6234
|
+
lineHidden: void 0,
|
|
5593
6235
|
widthFields: {
|
|
5594
6236
|
majorGridline: "secondaryValueAxis.majorGridlineWidthEmu",
|
|
5595
6237
|
minorGridline: "secondaryValueAxis.minorGridlineWidthEmu",
|
|
@@ -5640,7 +6282,20 @@ const rPrAttrsFromStyle = (style) => {
|
|
|
5640
6282
|
children
|
|
5641
6283
|
};
|
|
5642
6284
|
};
|
|
5643
|
-
const
|
|
6285
|
+
const manualLayoutElement = (position, size, target) => elem(c("layout"), { children: [elem(c("manualLayout"), { children: [
|
|
6286
|
+
...target !== void 0 ? [valNode(c("layoutTarget"), target)] : [],
|
|
6287
|
+
valNode(c("xMode"), "edge"),
|
|
6288
|
+
valNode(c("yMode"), "edge"),
|
|
6289
|
+
valNode(c("x"), position.x),
|
|
6290
|
+
valNode(c("y"), position.y),
|
|
6291
|
+
...size !== void 0 ? [valNode(c("w"), size.w), valNode(c("h"), size.h)] : []
|
|
6292
|
+
] })] });
|
|
6293
|
+
const richText = (value) => elem(c("rich"), { children: [
|
|
6294
|
+
elem(a("bodyPr")),
|
|
6295
|
+
elem(a("lstStyle")),
|
|
6296
|
+
elem(a("p"), { children: [elem(a("r"), { children: [elem(a("t"), { children: [text(value)] })] })] })
|
|
6297
|
+
] });
|
|
6298
|
+
const titleElement = (title, style, rotationDeg, placement) => {
|
|
5644
6299
|
const pPr = elem(a("pPr"), { children: [elem(a("defRPr"))] });
|
|
5645
6300
|
const { attrs: runAttrs, children: runChildren } = rPrAttrsFromStyle(style);
|
|
5646
6301
|
const runRPr = elem(a("rPr"), {
|
|
@@ -5662,7 +6317,95 @@ const titleElement = (title, style, rotationDeg) => {
|
|
|
5662
6317
|
elem(a("lstStyle")),
|
|
5663
6318
|
para
|
|
5664
6319
|
] });
|
|
5665
|
-
return elem(c("title"), { children: [
|
|
6320
|
+
return elem(c("title"), { children: [
|
|
6321
|
+
elem(c("tx"), { children: [rich] }),
|
|
6322
|
+
...placement?.layout !== void 0 ? [manualLayoutElement(placement.layout)] : [],
|
|
6323
|
+
valNode(c("overlay"), placement?.overlay === true ? "1" : "0")
|
|
6324
|
+
] });
|
|
6325
|
+
};
|
|
6326
|
+
const view3DDefaults = (spec) => {
|
|
6327
|
+
if (spec.kind === "surface" && spec.surfaceContour === true) return {
|
|
6328
|
+
rotX: 90,
|
|
6329
|
+
rotY: 0,
|
|
6330
|
+
rightAngleAxes: false,
|
|
6331
|
+
perspective: 0
|
|
6332
|
+
};
|
|
6333
|
+
if (spec.kind === "pie") return {
|
|
6334
|
+
rotX: 30,
|
|
6335
|
+
rotY: 0,
|
|
6336
|
+
rightAngleAxes: false
|
|
6337
|
+
};
|
|
6338
|
+
if (spec.kind === "surface") return {
|
|
6339
|
+
rotX: 15,
|
|
6340
|
+
rotY: 20,
|
|
6341
|
+
rightAngleAxes: false,
|
|
6342
|
+
perspective: 30
|
|
6343
|
+
};
|
|
6344
|
+
return {
|
|
6345
|
+
rotX: 15,
|
|
6346
|
+
rotY: 20,
|
|
6347
|
+
rightAngleAxes: true
|
|
6348
|
+
};
|
|
6349
|
+
};
|
|
6350
|
+
const view3DElement = (spec) => {
|
|
6351
|
+
const v = {
|
|
6352
|
+
...view3DDefaults(spec),
|
|
6353
|
+
...spec.view3D
|
|
6354
|
+
};
|
|
6355
|
+
const children = [];
|
|
6356
|
+
if (v.rotX !== void 0) children.push(valNode(c("rotX"), boundedInt(v.rotX, "rotX", "chart: view3D.rotX")));
|
|
6357
|
+
if (v.heightPercent !== void 0) children.push(valNode(c("hPercent"), boundedInt(v.heightPercent, "heightPercent", "chart: view3D.heightPercent")));
|
|
6358
|
+
if (v.rotY !== void 0) children.push(valNode(c("rotY"), boundedInt(v.rotY, "rotY", "chart: view3D.rotY")));
|
|
6359
|
+
if (v.depthPercent !== void 0) children.push(valNode(c("depthPercent"), boundedInt(v.depthPercent, "depthPercent", "chart: view3D.depthPercent")));
|
|
6360
|
+
if (v.rightAngleAxes !== void 0) children.push(valNode(c("rAngAx"), v.rightAngleAxes ? "1" : "0"));
|
|
6361
|
+
if (v.perspective !== void 0) children.push(valNode(c("perspective"), boundedInt(v.perspective, "perspective", "chart: view3D.perspective")));
|
|
6362
|
+
return elem(c("view3D"), { children });
|
|
6363
|
+
};
|
|
6364
|
+
const KINDS_WITH_VIEW_3D = new Set([
|
|
6365
|
+
"bar",
|
|
6366
|
+
"column",
|
|
6367
|
+
"line",
|
|
6368
|
+
"area",
|
|
6369
|
+
"pie",
|
|
6370
|
+
"surface"
|
|
6371
|
+
]);
|
|
6372
|
+
const AXISLESS_KINDS = new Set(["pie", "doughnut"]);
|
|
6373
|
+
const XY_KINDS = new Set(["scatter", "bubble"]);
|
|
6374
|
+
const validateSpec = (spec, usesComboFields) => {
|
|
6375
|
+
if (usesComboFields && !COMBO_KINDS.has(spec.kind)) throw new Error(`chart kind '${spec.kind}' does not support per-series chartKind / secondaryAxis (combo charts require a bar / column / line / area base kind)`);
|
|
6376
|
+
if (spec.view3D !== void 0) {
|
|
6377
|
+
if (!KINDS_WITH_VIEW_3D.has(spec.kind)) throw new Error(`chart kind '${spec.kind}' has no 3-D variant; view3D applies to bar / column / line / area / pie / surface`);
|
|
6378
|
+
if (usesComboFields) throw new Error("chart: view3D cannot be combined with a combo chart");
|
|
6379
|
+
}
|
|
6380
|
+
if ((spec.bar3DShape !== void 0 || spec.gapDepthPct !== void 0) && spec.view3D === void 0) throw new Error("chart: bar3DShape / gapDepthPct require view3D");
|
|
6381
|
+
if (spec.ofPie !== void 0 && spec.kind !== "pie") throw new Error(`chart: ofPie applies to kind 'pie', not '${spec.kind}'`);
|
|
6382
|
+
if (spec.dataTable !== void 0 && (AXISLESS_KINDS.has(spec.kind) || XY_KINDS.has(spec.kind))) throw new Error(`chart kind '${spec.kind}' cannot show a data table`);
|
|
6383
|
+
if (spec.categoryAxisDate !== void 0) {
|
|
6384
|
+
if (AXISLESS_KINDS.has(spec.kind) || XY_KINDS.has(spec.kind)) throw new Error(`chart kind '${spec.kind}' has no category axis to make a date axis of`);
|
|
6385
|
+
if (spec.categoryGroupLevels !== void 0) throw new Error("chart: a date axis cannot have categoryGroupLevels");
|
|
6386
|
+
spec.categories.forEach((category, i) => {
|
|
6387
|
+
if (category.trim() === "" || !Number.isFinite(Number(category))) throw new Error(`chart: categories[${i}] is ${JSON.stringify(category)}; a date axis needs date serial numbers (e.g. "45292" for 2024-01-01)`);
|
|
6388
|
+
});
|
|
6389
|
+
}
|
|
6390
|
+
if (spec.categoryAxisScaling !== void 0 && spec.categoryAxisDate === void 0 && !XY_KINDS.has(spec.kind)) throw new Error("chart: categoryAxisScaling needs a numeric horizontal axis — a scatter / bubble chart or a date axis");
|
|
6391
|
+
spec.categoryGroupLevels?.forEach((level, i) => {
|
|
6392
|
+
if (level.length !== spec.categories.length) throw new Error(`chart: categoryGroupLevels[${i}] has ${level.length} entries for ${spec.categories.length} categories`);
|
|
6393
|
+
});
|
|
6394
|
+
if (XY_KINDS.has(spec.kind)) spec.series.forEach((series) => {
|
|
6395
|
+
if (series.xValues === void 0) throw new Error(`chart: ${spec.kind} series '${series.name}' needs xValues`);
|
|
6396
|
+
if (spec.kind === "bubble" && series.bubbleSizes === void 0) throw new Error(`chart: bubble series '${series.name}' needs bubbleSizes`);
|
|
6397
|
+
});
|
|
6398
|
+
};
|
|
6399
|
+
const dataTableElement = (table) => {
|
|
6400
|
+
const children = [
|
|
6401
|
+
valNode(c("showHorzBorder"), table.showHorizontalBorder === false ? "0" : "1"),
|
|
6402
|
+
valNode(c("showVertBorder"), table.showVerticalBorder === false ? "0" : "1"),
|
|
6403
|
+
valNode(c("showOutline"), table.showOutline === false ? "0" : "1"),
|
|
6404
|
+
valNode(c("showKeys"), table.showKeys === false ? "0" : "1")
|
|
6405
|
+
];
|
|
6406
|
+
const txPr = axisTxPrElement(table.textStyle, void 0);
|
|
6407
|
+
if (txPr !== null) children.push(txPr);
|
|
6408
|
+
return elem(c("dTable"), { children });
|
|
5666
6409
|
};
|
|
5667
6410
|
/**
|
|
5668
6411
|
* Builds a complete `<c:chartSpace>` document for `spec`. The caller
|
|
@@ -5670,55 +6413,48 @@ const titleElement = (title, style, rotationDeg) => {
|
|
|
5670
6413
|
* `r:id="rId1"` for the embedded workbook.
|
|
5671
6414
|
*/
|
|
5672
6415
|
const buildChartSpaceDoc = (spec) => {
|
|
5673
|
-
const sheet = "Sheet1";
|
|
5674
6416
|
const usesComboFields = spec.series.some((series) => series.chartKind !== void 0 || series.secondaryAxis === true);
|
|
5675
|
-
|
|
5676
|
-
const
|
|
6417
|
+
validateSpec(spec, usesComboFields);
|
|
6418
|
+
const layout = layoutChartSheet(spec);
|
|
5677
6419
|
let plottedGroups;
|
|
5678
6420
|
let hasSecondary = false;
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
|
|
5688
|
-
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
default: {
|
|
5700
|
-
const exhaustive = spec.kind;
|
|
5701
|
-
throw new Error(`unsupported chart kind: ${String(exhaustive)}`);
|
|
5702
|
-
}
|
|
5703
|
-
}
|
|
5704
|
-
const axisless = spec.kind === "pie" || spec.kind === "doughnut";
|
|
5705
|
-
const plotAreaChildren = [elem(c("layout")), ...plottedGroups];
|
|
5706
|
-
if (!axisless) {
|
|
5707
|
-
plotAreaChildren.push(catAxis(spec), valAxis(spec));
|
|
6421
|
+
if (usesComboFields) {
|
|
6422
|
+
const groups = comboPlotGroups(spec);
|
|
6423
|
+
hasSecondary = groups.some((group) => group.secondary);
|
|
6424
|
+
plottedGroups = groups.map((group) => buildPlotGroup({
|
|
6425
|
+
spec,
|
|
6426
|
+
layout,
|
|
6427
|
+
seriesIndices: group.indices,
|
|
6428
|
+
axes: group.secondary ? SECONDARY_AXES : PRIMARY_AXES
|
|
6429
|
+
}, group.kind));
|
|
6430
|
+
} else plottedGroups = [buildPlotGroup({
|
|
6431
|
+
spec,
|
|
6432
|
+
layout,
|
|
6433
|
+
seriesIndices: spec.series.map((_, i) => i),
|
|
6434
|
+
axes: PRIMARY_AXES
|
|
6435
|
+
}, spec.kind)];
|
|
6436
|
+
const plotLayout = spec.plotAreaLayout;
|
|
6437
|
+
const plotAreaChildren = [plotLayout !== void 0 ? manualLayoutElement(plotLayout, plotLayout, plotLayout.target) : elem(c("layout")), ...plottedGroups];
|
|
6438
|
+
if (!AXISLESS_KINDS.has(spec.kind)) {
|
|
6439
|
+
plotAreaChildren.push(XY_KINDS.has(spec.kind) ? xValAxis(spec) : catAxis(spec), valAxis(spec));
|
|
6440
|
+
if (hasSeriesAxis(spec)) plotAreaChildren.push(serAxis(spec));
|
|
5708
6441
|
if (hasSecondary) plotAreaChildren.push(secondaryValAxis(spec), secondaryCatAxis(spec));
|
|
5709
6442
|
}
|
|
6443
|
+
if (spec.dataTable !== void 0) plotAreaChildren.push(dataTableElement(spec.dataTable));
|
|
5710
6444
|
if (spec.plotAreaFill !== void 0 || spec.plotAreaStrokeColor !== void 0) plotAreaChildren.push(spPrChildren(spec.plotAreaFill, spec.plotAreaStrokeColor));
|
|
5711
6445
|
const plotArea = elem(c("plotArea"), { children: plotAreaChildren });
|
|
5712
6446
|
const chartChildren = [];
|
|
5713
|
-
if (spec.title !== void 0) {
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
6447
|
+
if (spec.title !== void 0) chartChildren.push(titleElement(spec.title, spec.titleStyle, void 0, {
|
|
6448
|
+
...spec.titleOverlay !== void 0 ? { overlay: spec.titleOverlay } : {},
|
|
6449
|
+
...spec.titleLayout !== void 0 ? { layout: spec.titleLayout } : {}
|
|
6450
|
+
}));
|
|
6451
|
+
chartChildren.push(valNode(c("autoTitleDeleted"), spec.title !== void 0 ? "0" : "1"));
|
|
6452
|
+
if (spec.view3D !== void 0 || spec.kind === "surface") chartChildren.push(view3DElement(spec));
|
|
6453
|
+
chartChildren.push(plotArea);
|
|
5719
6454
|
if (spec.legend !== void 0 && spec.legend.position !== null) {
|
|
5720
6455
|
const legendChildren = [valNode(c("legendPos"), spec.legend.position)];
|
|
5721
6456
|
for (const idx of spec.legend.hiddenIndices ?? []) legendChildren.push(elem(c("legendEntry"), { children: [valNode(c("idx"), idx), valNode(c("delete"), "1")] }));
|
|
6457
|
+
if (spec.legend.layout !== void 0) legendChildren.push(manualLayoutElement(spec.legend.layout, spec.legend.layout));
|
|
5722
6458
|
legendChildren.push(valNode(c("overlay"), spec.legend.overlay ? "1" : "0"));
|
|
5723
6459
|
if (spec.legend.textStyle !== void 0) {
|
|
5724
6460
|
const txPr = axisTxPrElement(spec.legend.textStyle, void 0);
|
|
@@ -5852,15 +6588,15 @@ const KIND_MAP = [
|
|
|
5852
6588
|
},
|
|
5853
6589
|
{
|
|
5854
6590
|
localName: "stockChart",
|
|
5855
|
-
kind: "
|
|
6591
|
+
kind: "stock"
|
|
5856
6592
|
},
|
|
5857
6593
|
{
|
|
5858
6594
|
localName: "surfaceChart",
|
|
5859
|
-
kind: "
|
|
6595
|
+
kind: "surface"
|
|
5860
6596
|
},
|
|
5861
6597
|
{
|
|
5862
6598
|
localName: "surface3DChart",
|
|
5863
|
-
kind: "
|
|
6599
|
+
kind: "surface"
|
|
5864
6600
|
}
|
|
5865
6601
|
];
|
|
5866
6602
|
const findFirst = (parent, names) => {
|
|
@@ -6293,6 +7029,10 @@ const readDataLabelsGroup = (host, inherited) => {
|
|
|
6293
7029
|
const separator = readDataLabelSeparator(host);
|
|
6294
7030
|
const txPrEl = firstChildElement(host, qname("c", "txPr", NS_C));
|
|
6295
7031
|
const textStyle = txPrEl ? readLabelStyle(txPrEl) : void 0;
|
|
7032
|
+
const showBubbleSize = readToggle("showBubbleSize", inherited?.showBubbleSize ?? false);
|
|
7033
|
+
const showLegendKey = readToggle("showLegendKey", inherited?.showLegendKey ?? false);
|
|
7034
|
+
const spPr = firstChildElement(host, NAME_SP_PR_C);
|
|
7035
|
+
const fillColor = spPr !== null ? readSolidSrgb(spPr) : void 0;
|
|
6296
7036
|
return {
|
|
6297
7037
|
showValue: readToggle("showVal", inherited?.showValue ?? false),
|
|
6298
7038
|
showCategory: readToggle("showCatName", inherited?.showCategory ?? false),
|
|
@@ -6301,9 +7041,28 @@ const readDataLabelsGroup = (host, inherited) => {
|
|
|
6301
7041
|
...numberFormat !== void 0 ? { numberFormat } : {},
|
|
6302
7042
|
...position !== void 0 ? { position } : {},
|
|
6303
7043
|
...separator !== void 0 ? { separator } : {},
|
|
6304
|
-
...textStyle !== void 0 ? { textStyle } : {}
|
|
7044
|
+
...textStyle !== void 0 ? { textStyle } : {},
|
|
7045
|
+
...showBubbleSize ? { showBubbleSize } : {},
|
|
7046
|
+
...showLegendKey ? { showLegendKey } : {},
|
|
7047
|
+
...fillColor !== void 0 ? { fillColor } : {}
|
|
6305
7048
|
};
|
|
6306
7049
|
};
|
|
7050
|
+
const readRichText = (host) => {
|
|
7051
|
+
const tx = firstChildElement(host, NAME_TX);
|
|
7052
|
+
const rich = tx !== null ? firstChildElement(tx, NAME_RICH) : null;
|
|
7053
|
+
if (rich === null) return void 0;
|
|
7054
|
+
const paragraphs = [];
|
|
7055
|
+
for (const p of allChildElements(rich, NAME_P_DML)) {
|
|
7056
|
+
let line = "";
|
|
7057
|
+
for (const r of allChildElements(p, NAME_R_DML)) {
|
|
7058
|
+
const t = firstChildElement(r, NAME_T);
|
|
7059
|
+
if (t === null) continue;
|
|
7060
|
+
for (const child of t.children) if (child.kind === "text" || child.kind === "cdata") line += child.data;
|
|
7061
|
+
}
|
|
7062
|
+
paragraphs.push(line);
|
|
7063
|
+
}
|
|
7064
|
+
return paragraphs.join("\n");
|
|
7065
|
+
};
|
|
6307
7066
|
const readSeriesLevelDataLabels = (dLbls) => {
|
|
6308
7067
|
const group = readDataLabelsGroup(dLbls, void 0);
|
|
6309
7068
|
const leaderEl = firstChildElement(dLbls, qname("c", "showLeaderLines", NS_C));
|
|
@@ -6326,7 +7085,15 @@ const readPointDataLabels = (dLbls, pointCount, seriesLabels) => {
|
|
|
6326
7085
|
const idx = readPointIndex(dLbl, pointCount);
|
|
6327
7086
|
if (idx === null) continue;
|
|
6328
7087
|
const deleteEl = firstChildElement(dLbl, qname("c", "delete", NS_C));
|
|
6329
|
-
|
|
7088
|
+
if (deleteEl !== null && readXmlBool(deleteEl)) out[idx] = DELETED_POINT_LABEL;
|
|
7089
|
+
else {
|
|
7090
|
+
const group = readDataLabelsGroup(dLbl, seriesLabels);
|
|
7091
|
+
const literal = readRichText(dLbl);
|
|
7092
|
+
out[idx] = literal !== void 0 ? {
|
|
7093
|
+
...group,
|
|
7094
|
+
text: literal
|
|
7095
|
+
} : group;
|
|
7096
|
+
}
|
|
6330
7097
|
any = true;
|
|
6331
7098
|
}
|
|
6332
7099
|
if (!any) return void 0;
|
|
@@ -6340,6 +7107,7 @@ const readValueAxisScaling = (valAx) => {
|
|
|
6340
7107
|
let minorUnit;
|
|
6341
7108
|
let logBase;
|
|
6342
7109
|
let displayUnits;
|
|
7110
|
+
let displayUnitsLabel = false;
|
|
6343
7111
|
const scaling = firstChildElement(valAx, qname("c", "scaling", NS_C));
|
|
6344
7112
|
const readNumOn = (parent, local) => {
|
|
6345
7113
|
const el = firstChildElement(parent, qname("c", local, NS_C));
|
|
@@ -6376,6 +7144,7 @@ const readValueAxisScaling = (valAx) => {
|
|
|
6376
7144
|
break;
|
|
6377
7145
|
}
|
|
6378
7146
|
}
|
|
7147
|
+
displayUnitsLabel = firstChildElement(dispUnits, qname("c", "dispUnitsLbl", NS_C)) !== null;
|
|
6379
7148
|
}
|
|
6380
7149
|
let numberFormat;
|
|
6381
7150
|
const nfEl = firstChildElement(valAx, qname("c", "numFmt", NS_C));
|
|
@@ -6390,9 +7159,285 @@ const readValueAxisScaling = (valAx) => {
|
|
|
6390
7159
|
...minorUnit !== void 0 ? { minorUnit } : {},
|
|
6391
7160
|
...numberFormat !== void 0 ? { numberFormat } : {},
|
|
6392
7161
|
...logBase !== void 0 ? { logBase } : {},
|
|
6393
|
-
...displayUnits !== void 0 ? { displayUnits } : {}
|
|
7162
|
+
...displayUnits !== void 0 ? { displayUnits } : {},
|
|
7163
|
+
...displayUnits !== void 0 && displayUnitsLabel ? { displayUnitsLabel } : {}
|
|
7164
|
+
};
|
|
7165
|
+
};
|
|
7166
|
+
const childVal = (parent, local) => {
|
|
7167
|
+
const el = firstChildElement(parent, qname("c", local, NS_C));
|
|
7168
|
+
return el !== null ? getAttrValue(el, ATTR_VAL) : null;
|
|
7169
|
+
};
|
|
7170
|
+
const childNumber = (parent, local) => {
|
|
7171
|
+
const raw = childVal(parent, local);
|
|
7172
|
+
if (raw === null) return void 0;
|
|
7173
|
+
const n = Number.parseFloat(raw);
|
|
7174
|
+
return Number.isFinite(n) ? n : void 0;
|
|
7175
|
+
};
|
|
7176
|
+
const childBool = (parent, local) => {
|
|
7177
|
+
const el = firstChildElement(parent, qname("c", local, NS_C));
|
|
7178
|
+
return el !== null ? readXmlBool(el) : void 0;
|
|
7179
|
+
};
|
|
7180
|
+
const childToken = (parent, local, allowed) => {
|
|
7181
|
+
const raw = childVal(parent, local);
|
|
7182
|
+
return allowed.find((token) => token === raw);
|
|
7183
|
+
};
|
|
7184
|
+
const ALPHA_OPAQUE = 1e5;
|
|
7185
|
+
const readSeriesFillOpacity = (ser) => {
|
|
7186
|
+
const spPr = firstChildElement(ser, NAME_SP_PR_C);
|
|
7187
|
+
const fill = spPr !== null ? firstChildElement(spPr, NAME_SOLID_FILL$1) : null;
|
|
7188
|
+
const srgb = fill !== null ? firstChildElement(fill, NAME_SRGB_CLR) : null;
|
|
7189
|
+
const alpha = srgb !== null ? firstChildElement(srgb, qname("a", "alpha", NS_A)) : null;
|
|
7190
|
+
const raw = alpha !== null ? getAttrValue(alpha, ATTR_VAL) : null;
|
|
7191
|
+
if (raw === null || !/^\d+$/.test(raw)) return void 0;
|
|
7192
|
+
const n = Number.parseInt(raw, 10);
|
|
7193
|
+
return n <= ALPHA_OPAQUE ? n / ALPHA_OPAQUE : void 0;
|
|
7194
|
+
};
|
|
7195
|
+
const readErrorBarAmount = (errBars) => {
|
|
7196
|
+
const type = childToken(errBars, "errValType", [
|
|
7197
|
+
"cust",
|
|
7198
|
+
"fixedVal",
|
|
7199
|
+
"percentage",
|
|
7200
|
+
"stdDev",
|
|
7201
|
+
"stdErr"
|
|
7202
|
+
]);
|
|
7203
|
+
if (type === void 0) return void 0;
|
|
7204
|
+
if (type === "stdErr") return { type };
|
|
7205
|
+
if (type === "cust") {
|
|
7206
|
+
const side = (local) => {
|
|
7207
|
+
const el = firstChildElement(errBars, qname("c", local, NS_C));
|
|
7208
|
+
return el !== null ? readNumChannel(el) ?? void 0 : void 0;
|
|
7209
|
+
};
|
|
7210
|
+
const plus = side("plus");
|
|
7211
|
+
const minus = side("minus");
|
|
7212
|
+
return {
|
|
7213
|
+
type,
|
|
7214
|
+
...plus !== void 0 ? { plus } : {},
|
|
7215
|
+
...minus !== void 0 ? { minus } : {}
|
|
7216
|
+
};
|
|
7217
|
+
}
|
|
7218
|
+
const value = childNumber(errBars, "val");
|
|
7219
|
+
return value !== void 0 ? {
|
|
7220
|
+
type,
|
|
7221
|
+
value
|
|
7222
|
+
} : void 0;
|
|
7223
|
+
};
|
|
7224
|
+
const readErrorBars = (ser) => {
|
|
7225
|
+
const out = {};
|
|
7226
|
+
for (const el of allChildElements(ser, qname("c", "errBars", NS_C))) {
|
|
7227
|
+
const barType = childToken(el, "errBarType", [
|
|
7228
|
+
"both",
|
|
7229
|
+
"minus",
|
|
7230
|
+
"plus"
|
|
7231
|
+
]);
|
|
7232
|
+
const amount = readErrorBarAmount(el);
|
|
7233
|
+
if (barType === void 0 || amount === void 0) continue;
|
|
7234
|
+
const noEndCap = childBool(el, "noEndCap");
|
|
7235
|
+
const spPr = firstChildElement(el, NAME_SP_PR_C);
|
|
7236
|
+
const ln = spPr !== null ? firstChildElement(spPr, qname("a", "ln", NS_A)) : null;
|
|
7237
|
+
const color = readSolidSrgb(ln);
|
|
7238
|
+
const w = ln !== null ? getAttrValue(ln, qname("", "w", "")) : null;
|
|
7239
|
+
const bars = {
|
|
7240
|
+
barType,
|
|
7241
|
+
amount,
|
|
7242
|
+
...noEndCap !== void 0 ? { noEndCap } : {},
|
|
7243
|
+
...color !== void 0 ? { color } : {},
|
|
7244
|
+
...w !== null && /^\d+$/.test(w) ? { lineWidthEmu: Number.parseInt(w, 10) } : {}
|
|
7245
|
+
};
|
|
7246
|
+
if (childVal(el, "errDir") === "x") out.xErrorBars ??= bars;
|
|
7247
|
+
else out.errorBars ??= bars;
|
|
7248
|
+
}
|
|
7249
|
+
return out;
|
|
7250
|
+
};
|
|
7251
|
+
const readView3D = (chart) => {
|
|
7252
|
+
const el = firstChildElement(chart, qname("c", "view3D", NS_C));
|
|
7253
|
+
if (el === null) return void 0;
|
|
7254
|
+
const rotX = childNumber(el, "rotX");
|
|
7255
|
+
const rotY = childNumber(el, "rotY");
|
|
7256
|
+
const rightAngleAxes = childBool(el, "rAngAx");
|
|
7257
|
+
const perspective = childNumber(el, "perspective");
|
|
7258
|
+
const depthPercent = childNumber(el, "depthPercent");
|
|
7259
|
+
const heightPercent = childNumber(el, "hPercent");
|
|
7260
|
+
return {
|
|
7261
|
+
...rotX !== void 0 ? { rotX } : {},
|
|
7262
|
+
...rotY !== void 0 ? { rotY } : {},
|
|
7263
|
+
...rightAngleAxes !== void 0 ? { rightAngleAxes } : {},
|
|
7264
|
+
...perspective !== void 0 ? { perspective } : {},
|
|
7265
|
+
...depthPercent !== void 0 ? { depthPercent } : {},
|
|
7266
|
+
...heightPercent !== void 0 ? { heightPercent } : {}
|
|
7267
|
+
};
|
|
7268
|
+
};
|
|
7269
|
+
const readOfPie = (group) => {
|
|
7270
|
+
const type = childToken(group, "ofPieType", ["pie", "bar"]);
|
|
7271
|
+
if (type === void 0) return void 0;
|
|
7272
|
+
const splitType = childToken(group, "splitType", [
|
|
7273
|
+
"auto",
|
|
7274
|
+
"cust",
|
|
7275
|
+
"percent",
|
|
7276
|
+
"pos",
|
|
7277
|
+
"val"
|
|
7278
|
+
]);
|
|
7279
|
+
const splitPos = childNumber(group, "splitPos");
|
|
7280
|
+
const secondPieSizePct = childNumber(group, "secondPieSize");
|
|
7281
|
+
const gapWidthPct = childNumber(group, "gapWidth");
|
|
7282
|
+
const custSplit = firstChildElement(group, qname("c", "custSplit", NS_C));
|
|
7283
|
+
const customSplit = [];
|
|
7284
|
+
if (custSplit !== null) for (const pt of allChildElements(custSplit, qname("c", "secondPiePt", NS_C))) {
|
|
7285
|
+
const idx = parsePointIndex(getAttrValue(pt, ATTR_VAL), MAX_PT_COUNT);
|
|
7286
|
+
if (idx !== null) customSplit.push(idx);
|
|
7287
|
+
}
|
|
7288
|
+
const seriesLines = firstChildElement(group, qname("c", "serLines", NS_C)) !== null;
|
|
7289
|
+
return {
|
|
7290
|
+
type,
|
|
7291
|
+
...splitType !== void 0 ? { splitType } : {},
|
|
7292
|
+
...splitPos !== void 0 ? { splitPos } : {},
|
|
7293
|
+
...custSplit !== null ? { customSplit } : {},
|
|
7294
|
+
...secondPieSizePct !== void 0 ? { secondPieSizePct } : {},
|
|
7295
|
+
...gapWidthPct !== void 0 ? { gapWidthPct } : {},
|
|
7296
|
+
...seriesLines ? { seriesLines } : {}
|
|
7297
|
+
};
|
|
7298
|
+
};
|
|
7299
|
+
const readUpDownBars = (group) => {
|
|
7300
|
+
const el = firstChildElement(group, qname("c", "upDownBars", NS_C));
|
|
7301
|
+
if (el === null) return void 0;
|
|
7302
|
+
const barColor = (local) => {
|
|
7303
|
+
const bar = firstChildElement(el, qname("c", local, NS_C));
|
|
7304
|
+
return readSolidSrgb(bar !== null ? firstChildElement(bar, NAME_SP_PR_C) : null);
|
|
7305
|
+
};
|
|
7306
|
+
const gapWidthPct = childNumber(el, "gapWidth");
|
|
7307
|
+
const upColor = barColor("upBars");
|
|
7308
|
+
const downColor = barColor("downBars");
|
|
7309
|
+
return {
|
|
7310
|
+
...gapWidthPct !== void 0 ? { gapWidthPct } : {},
|
|
7311
|
+
...upColor !== void 0 ? { upColor } : {},
|
|
7312
|
+
...downColor !== void 0 ? { downColor } : {}
|
|
7313
|
+
};
|
|
7314
|
+
};
|
|
7315
|
+
const readDataTable = (plotArea) => {
|
|
7316
|
+
const el = firstChildElement(plotArea, qname("c", "dTable", NS_C));
|
|
7317
|
+
if (el === null) return void 0;
|
|
7318
|
+
const showHorizontalBorder = childBool(el, "showHorzBorder");
|
|
7319
|
+
const showVerticalBorder = childBool(el, "showVertBorder");
|
|
7320
|
+
const showOutline = childBool(el, "showOutline");
|
|
7321
|
+
const showKeys = childBool(el, "showKeys");
|
|
7322
|
+
const txPr = firstChildElement(el, qname("c", "txPr", NS_C));
|
|
7323
|
+
const textStyle = txPr !== null ? readLabelStyle(txPr) : void 0;
|
|
7324
|
+
return {
|
|
7325
|
+
...showHorizontalBorder !== void 0 ? { showHorizontalBorder } : {},
|
|
7326
|
+
...showVerticalBorder !== void 0 ? { showVerticalBorder } : {},
|
|
7327
|
+
...showOutline !== void 0 ? { showOutline } : {},
|
|
7328
|
+
...showKeys !== void 0 ? { showKeys } : {},
|
|
7329
|
+
...textStyle !== void 0 ? { textStyle } : {}
|
|
7330
|
+
};
|
|
7331
|
+
};
|
|
7332
|
+
const TIME_UNITS = [
|
|
7333
|
+
"days",
|
|
7334
|
+
"months",
|
|
7335
|
+
"years"
|
|
7336
|
+
];
|
|
7337
|
+
const readDateAxis = (dateAx) => {
|
|
7338
|
+
const baseTimeUnit = childToken(dateAx, "baseTimeUnit", TIME_UNITS);
|
|
7339
|
+
const majorUnit = childNumber(dateAx, "majorUnit");
|
|
7340
|
+
const majorTimeUnit = childToken(dateAx, "majorTimeUnit", TIME_UNITS);
|
|
7341
|
+
const minorUnit = childNumber(dateAx, "minorUnit");
|
|
7342
|
+
const minorTimeUnit = childToken(dateAx, "minorTimeUnit", TIME_UNITS);
|
|
7343
|
+
return {
|
|
7344
|
+
...baseTimeUnit !== void 0 ? { baseTimeUnit } : {},
|
|
7345
|
+
...majorUnit !== void 0 ? { majorUnit } : {},
|
|
7346
|
+
...majorTimeUnit !== void 0 ? { majorTimeUnit } : {},
|
|
7347
|
+
...minorUnit !== void 0 ? { minorUnit } : {},
|
|
7348
|
+
...minorTimeUnit !== void 0 ? { minorTimeUnit } : {}
|
|
7349
|
+
};
|
|
7350
|
+
};
|
|
7351
|
+
const withoutNumberFormat = (scaling) => {
|
|
7352
|
+
if (scaling === void 0) return void 0;
|
|
7353
|
+
const { numberFormat: _numberFormat, ...rest } = scaling;
|
|
7354
|
+
return Object.keys(rest).length > 0 ? rest : void 0;
|
|
7355
|
+
};
|
|
7356
|
+
const minMaxOnly = (scaling) => {
|
|
7357
|
+
if (scaling?.min === void 0 && scaling?.max === void 0) return void 0;
|
|
7358
|
+
return {
|
|
7359
|
+
...scaling.min !== void 0 ? { min: scaling.min } : {},
|
|
7360
|
+
...scaling.max !== void 0 ? { max: scaling.max } : {}
|
|
7361
|
+
};
|
|
7362
|
+
};
|
|
7363
|
+
const isAxisLineHidden = (axis) => {
|
|
7364
|
+
const spPr = firstChildElement(axis, NAME_SP_PR_C);
|
|
7365
|
+
const ln = spPr !== null ? firstChildElement(spPr, qname("a", "ln", NS_A)) : null;
|
|
7366
|
+
return ln !== null && firstChildElement(ln, qname("a", "noFill", NS_A)) !== null;
|
|
7367
|
+
};
|
|
7368
|
+
const readSeriesAxis = (plotArea) => {
|
|
7369
|
+
const el = firstChildElement(plotArea, qname("c", "serAx", NS_C));
|
|
7370
|
+
if (el === null) return void 0;
|
|
7371
|
+
const hidden = childBool(el, "delete");
|
|
7372
|
+
const title = readTitle(el);
|
|
7373
|
+
const titleEl = firstChildElement(el, NAME_TITLE);
|
|
7374
|
+
const titleStyle = titleEl !== null ? readTitleStyleOf(titleEl) : void 0;
|
|
7375
|
+
const txPr = firstChildElement(el, qname("c", "txPr", NS_C));
|
|
7376
|
+
const labelStyle = txPr !== null ? readLabelStyle(txPr) : void 0;
|
|
7377
|
+
const majorGridlines = firstChildElement(el, qname("c", "majorGridlines", NS_C)) !== null;
|
|
7378
|
+
const scaling = firstChildElement(el, qname("c", "scaling", NS_C));
|
|
7379
|
+
const orientation = scaling !== null ? childToken(scaling, "orientation", ["minMax", "maxMin"]) : void 0;
|
|
7380
|
+
const tickLabelPos = childToken(el, "tickLblPos", [
|
|
7381
|
+
"none",
|
|
7382
|
+
"low",
|
|
7383
|
+
"high",
|
|
7384
|
+
"nextTo"
|
|
7385
|
+
]);
|
|
7386
|
+
const tickLabelSkip = childNumber(el, "tickLblSkip");
|
|
7387
|
+
const spPr = firstChildElement(el, NAME_SP_PR_C);
|
|
7388
|
+
const lineColor = readSolidSrgb(spPr !== null ? firstChildElement(spPr, qname("a", "ln", NS_A)) : null);
|
|
7389
|
+
const fields = {
|
|
7390
|
+
...hidden === true ? { hidden } : {},
|
|
7391
|
+
...title !== void 0 ? { title } : {},
|
|
7392
|
+
...titleStyle !== void 0 ? { titleStyle } : {},
|
|
7393
|
+
...labelStyle !== void 0 ? { labelStyle } : {},
|
|
7394
|
+
...majorGridlines ? { majorGridlines } : {},
|
|
7395
|
+
...orientation === "maxMin" ? { orientation } : {},
|
|
7396
|
+
...tickLabelPos !== void 0 ? { tickLabelPos } : {},
|
|
7397
|
+
...tickLabelSkip !== void 0 ? { tickLabelSkip } : {},
|
|
7398
|
+
...lineColor !== void 0 ? { lineColor } : {}
|
|
7399
|
+
};
|
|
7400
|
+
return Object.keys(fields).length > 0 ? fields : void 0;
|
|
7401
|
+
};
|
|
7402
|
+
const readManualLayout = (host) => {
|
|
7403
|
+
const layout = firstChildElement(host, qname("c", "layout", NS_C));
|
|
7404
|
+
const manual = layout !== null ? firstChildElement(layout, qname("c", "manualLayout", NS_C)) : null;
|
|
7405
|
+
if (manual === null) return void 0;
|
|
7406
|
+
if (childVal(manual, "xMode") !== "edge" || childVal(manual, "yMode") !== "edge") return void 0;
|
|
7407
|
+
const sizeMode = (local) => (childVal(manual, local) ?? "factor") === "factor";
|
|
7408
|
+
if (!sizeMode("wMode") || !sizeMode("hMode")) return void 0;
|
|
7409
|
+
const x = childNumber(manual, "x");
|
|
7410
|
+
const y = childNumber(manual, "y");
|
|
7411
|
+
if (x === void 0 || y === void 0) return void 0;
|
|
7412
|
+
const w = childNumber(manual, "w");
|
|
7413
|
+
const h = childNumber(manual, "h");
|
|
7414
|
+
const target = childToken(manual, "layoutTarget", ["inner", "outer"]);
|
|
7415
|
+
return {
|
|
7416
|
+
x,
|
|
7417
|
+
y,
|
|
7418
|
+
...w !== void 0 ? { w } : {},
|
|
7419
|
+
...h !== void 0 ? { h } : {},
|
|
7420
|
+
...target !== void 0 ? { target } : {}
|
|
7421
|
+
};
|
|
7422
|
+
};
|
|
7423
|
+
const readBoxLayout = (host) => {
|
|
7424
|
+
const layout = readManualLayout(host);
|
|
7425
|
+
if (layout === void 0 || layout.w === void 0 || layout.h === void 0) return void 0;
|
|
7426
|
+
return {
|
|
7427
|
+
x: layout.x,
|
|
7428
|
+
y: layout.y,
|
|
7429
|
+
w: layout.w,
|
|
7430
|
+
h: layout.h,
|
|
7431
|
+
...layout.target !== void 0 ? { target: layout.target } : {}
|
|
6394
7432
|
};
|
|
6395
7433
|
};
|
|
7434
|
+
const readCategoryGroupLevels = (cat) => {
|
|
7435
|
+
const multi = firstChildElement(cat, NAME_MULTI_LVL_STR_REF);
|
|
7436
|
+
const cache = multi !== null ? firstChildElement(multi, NAME_MULTI_LVL_STR_CACHE) : null;
|
|
7437
|
+
if (cache === null) return void 0;
|
|
7438
|
+
const outer = allChildElements(cache, NAME_LVL).slice(1).map((lvl) => readPtArray(lvl, cache));
|
|
7439
|
+
return outer.length > 0 ? outer : void 0;
|
|
7440
|
+
};
|
|
6396
7441
|
/**
|
|
6397
7442
|
* Parses a `<c:chartSpace>` element into a typed `ChartSpec`. Throws if
|
|
6398
7443
|
* the root or any required child is missing. Returns `null` only when
|
|
@@ -6445,6 +7490,7 @@ const readChartSpec = (root) => {
|
|
|
6445
7490
|
const groupUsesSecondaryAxis = (group) => groupAxisIds(group).some((id) => secondaryValAxisIds.has(id));
|
|
6446
7491
|
const series = [];
|
|
6447
7492
|
let categoriesFromFirst = null;
|
|
7493
|
+
let categoryGroupLevels;
|
|
6448
7494
|
const serEntries = [];
|
|
6449
7495
|
for (const group of plotGroups) {
|
|
6450
7496
|
const secondary = groupUsesSecondaryAxis(group.element);
|
|
@@ -6459,6 +7505,7 @@ const readChartSpec = (root) => {
|
|
|
6459
7505
|
const cat = firstChildElement(ser, NAME_CAT);
|
|
6460
7506
|
if (cat !== null && categoriesFromFirst === null) {
|
|
6461
7507
|
categoriesFromFirst = readStringRef(cat) ?? null;
|
|
7508
|
+
categoryGroupLevels = readCategoryGroupLevels(cat);
|
|
6462
7509
|
if (categoriesFromFirst === null) {
|
|
6463
7510
|
const nums = readNumRef(cat);
|
|
6464
7511
|
if (nums !== null) categoriesFromFirst = nums.map((n) => n === null || !Number.isFinite(n) ? "" : String(n));
|
|
@@ -6481,6 +7528,8 @@ const readChartSpec = (root) => {
|
|
|
6481
7528
|
const smoothEl = firstChildElement(ser, qname("c", "smooth", NS_C));
|
|
6482
7529
|
const smooth = smoothEl !== null && readXmlBool(smoothEl);
|
|
6483
7530
|
const trendline = readTrendline(ser);
|
|
7531
|
+
const fillOpacity = readSeriesFillOpacity(ser);
|
|
7532
|
+
const { errorBars, xErrorBars } = readErrorBars(ser);
|
|
6484
7533
|
const serDLblsEl = firstChildElement(ser, NAME_D_LBLS);
|
|
6485
7534
|
const serDataLabels = serDLblsEl !== null && hasDataLabelGroupChild(serDLblsEl) ? readSeriesLevelDataLabels(serDLblsEl) : void 0;
|
|
6486
7535
|
const pointDataLabels = serDLblsEl !== null ? readPointDataLabels(serDLblsEl, pointCount, serDataLabels) : void 0;
|
|
@@ -6505,7 +7554,10 @@ const readChartSpec = (root) => {
|
|
|
6505
7554
|
...pointDataLabels !== void 0 ? { pointDataLabels } : {},
|
|
6506
7555
|
...smoothEl !== null ? { smooth } : {},
|
|
6507
7556
|
...trendline !== void 0 ? { trendline } : {},
|
|
6508
|
-
...serDataLabels !== void 0 ? { dataLabels: serDataLabels } : {}
|
|
7557
|
+
...serDataLabels !== void 0 ? { dataLabels: serDataLabels } : {},
|
|
7558
|
+
...fillOpacity !== void 0 ? { fillOpacity } : {},
|
|
7559
|
+
...errorBars !== void 0 ? { errorBars } : {},
|
|
7560
|
+
...xErrorBars !== void 0 ? { xErrorBars } : {}
|
|
6509
7561
|
});
|
|
6510
7562
|
}
|
|
6511
7563
|
const categories = categoriesFromFirst ?? [];
|
|
@@ -6525,6 +7577,22 @@ const readChartSpec = (root) => {
|
|
|
6525
7577
|
valAx = secValAx;
|
|
6526
7578
|
secValAx = null;
|
|
6527
7579
|
}
|
|
7580
|
+
const isXyKind = kind === "scatter" || kind === "bubble";
|
|
7581
|
+
let xValAx = null;
|
|
7582
|
+
if (isXyKind) {
|
|
7583
|
+
const [xId, yId] = groupAxisIds(plotted);
|
|
7584
|
+
const valAxById = /* @__PURE__ */ new Map();
|
|
7585
|
+
for (const el of allChildElements(plotArea, NAME_VAL_AX)) {
|
|
7586
|
+
const id = childVal(el, "axId");
|
|
7587
|
+
if (id !== null) valAxById.set(id, el);
|
|
7588
|
+
}
|
|
7589
|
+
const x = xId !== void 0 ? valAxById.get(xId) : void 0;
|
|
7590
|
+
const y = yId !== void 0 ? valAxById.get(yId) : void 0;
|
|
7591
|
+
if (x !== void 0 && y !== void 0) {
|
|
7592
|
+
xValAx = x;
|
|
7593
|
+
valAx = y;
|
|
7594
|
+
}
|
|
7595
|
+
}
|
|
6528
7596
|
const valueAxis = valAx !== null ? readValueAxisScaling(valAx) : void 0;
|
|
6529
7597
|
let grouping;
|
|
6530
7598
|
if (kind === "column" || kind === "bar" || kind === "area" || kind === "line") {
|
|
@@ -6641,11 +7709,7 @@ const readChartSpec = (root) => {
|
|
|
6641
7709
|
const v = getAttrValue(srgb, ATTR_VAL);
|
|
6642
7710
|
return v !== null ? `#${v.toUpperCase()}` : void 0;
|
|
6643
7711
|
};
|
|
6644
|
-
const catAx = findFirst(plotArea, [
|
|
6645
|
-
"catAx",
|
|
6646
|
-
"dateAx",
|
|
6647
|
-
"serAx"
|
|
6648
|
-
]);
|
|
7712
|
+
const catAx = xValAx ?? findFirst(plotArea, ["catAx", "dateAx"]);
|
|
6649
7713
|
const isHidden = (axis) => {
|
|
6650
7714
|
const d = firstChildElement(axis, qname("c", "delete", NS_C));
|
|
6651
7715
|
if (!d) return void 0;
|
|
@@ -6939,9 +8003,12 @@ const readChartSpec = (root) => {
|
|
|
6939
8003
|
const n = Number.parseInt(idxV, 10);
|
|
6940
8004
|
if (Number.isFinite(n) && n >= 0) hiddenIndices.push(n);
|
|
6941
8005
|
}
|
|
8006
|
+
const position = tok === "r" || tok === "t" || tok === "b" || tok === "l" || tok === "tr" ? tok : "r";
|
|
8007
|
+
const legendLayout = readBoxLayout(legendEl);
|
|
6942
8008
|
legend = {
|
|
6943
|
-
position
|
|
8009
|
+
position,
|
|
6944
8010
|
...overlay ? { overlay } : {},
|
|
8011
|
+
...legendLayout !== void 0 ? { layout: legendLayout } : {},
|
|
6945
8012
|
...textStyle !== void 0 ? { textStyle } : {},
|
|
6946
8013
|
...hiddenIndices.length > 0 ? { hiddenIndices } : {}
|
|
6947
8014
|
};
|
|
@@ -7012,6 +8079,38 @@ const readChartSpec = (root) => {
|
|
|
7012
8079
|
else if (v === "w") bubbleSizeRepresents = "width";
|
|
7013
8080
|
}
|
|
7014
8081
|
}
|
|
8082
|
+
const plottedName = plotted.name.localName;
|
|
8083
|
+
const view3DEl = readView3D(chart);
|
|
8084
|
+
const view3D = plottedName.endsWith("3DChart") || kind === "surface" ? view3DEl : void 0;
|
|
8085
|
+
const bar3DShape = plottedName === "bar3DChart" ? childToken(plotted, "shape", [
|
|
8086
|
+
"box",
|
|
8087
|
+
"cone",
|
|
8088
|
+
"coneToMax",
|
|
8089
|
+
"cylinder",
|
|
8090
|
+
"pyramid",
|
|
8091
|
+
"pyramidToMax"
|
|
8092
|
+
]) : void 0;
|
|
8093
|
+
const gapDepthPct = view3D !== void 0 ? childNumber(plotted, "gapDepth") : void 0;
|
|
8094
|
+
const bubble3D = kind === "bubble" && allChildElements(plotted, NAME_SER).some((ser) => childBool(ser, "bubble3D") === true);
|
|
8095
|
+
const showNegativeBubbles = kind === "bubble" ? childBool(plotted, "showNegBubbles") : void 0;
|
|
8096
|
+
const ofPie = plottedName === "ofPieChart" ? readOfPie(plotted) : void 0;
|
|
8097
|
+
const surfaceContour = plottedName === "surfaceChart";
|
|
8098
|
+
const surfaceWireframe = kind === "surface" ? childBool(plotted, "wireframe") : void 0;
|
|
8099
|
+
const upDownBars = readUpDownBars(plotted);
|
|
8100
|
+
const dataTable = readDataTable(plotArea);
|
|
8101
|
+
const seriesAxis = readSeriesAxis(plotArea);
|
|
8102
|
+
const plotAreaLayout = readBoxLayout(plotArea);
|
|
8103
|
+
const chartTitleEl = firstChildElement(chart, NAME_TITLE);
|
|
8104
|
+
const titlePosition = chartTitleEl !== null ? readManualLayout(chartTitleEl) : void 0;
|
|
8105
|
+
const titleLayout = titlePosition !== void 0 ? {
|
|
8106
|
+
x: titlePosition.x,
|
|
8107
|
+
y: titlePosition.y
|
|
8108
|
+
} : void 0;
|
|
8109
|
+
const categoryAxisDate = catAx !== null && catAx.name.localName === "dateAx" ? readDateAxis(catAx) : void 0;
|
|
8110
|
+
const horizontalScaling = catAx !== null ? readValueAxisScaling(catAx) : void 0;
|
|
8111
|
+
const categoryAxisScaling = isXyKind ? withoutNumberFormat(horizontalScaling) : categoryAxisDate !== void 0 ? minMaxOnly(horizontalScaling) : void 0;
|
|
8112
|
+
const valueAxisLineHidden = valAx !== null && isAxisLineHidden(valAx);
|
|
8113
|
+
const categoryAxisLineHidden = catAx !== null && isAxisLineHidden(catAx);
|
|
7015
8114
|
return {
|
|
7016
8115
|
kind,
|
|
7017
8116
|
categories,
|
|
@@ -7089,80 +8188,28 @@ const readChartSpec = (root) => {
|
|
|
7089
8188
|
...scatterStyle !== void 0 ? { scatterStyle } : {},
|
|
7090
8189
|
...radarStyle !== void 0 ? { radarStyle } : {},
|
|
7091
8190
|
...bubbleScale !== void 0 ? { bubbleScale } : {},
|
|
7092
|
-
...bubbleSizeRepresents !== void 0 ? { bubbleSizeRepresents } : {}
|
|
8191
|
+
...bubbleSizeRepresents !== void 0 ? { bubbleSizeRepresents } : {},
|
|
8192
|
+
...bubble3D === true ? { bubble3D } : {},
|
|
8193
|
+
...showNegativeBubbles !== void 0 ? { showNegativeBubbles } : {},
|
|
8194
|
+
...view3D !== void 0 ? { view3D } : {},
|
|
8195
|
+
...bar3DShape !== void 0 ? { bar3DShape } : {},
|
|
8196
|
+
...gapDepthPct !== void 0 ? { gapDepthPct } : {},
|
|
8197
|
+
...seriesAxis !== void 0 ? { seriesAxis } : {},
|
|
8198
|
+
...ofPie !== void 0 ? { ofPie } : {},
|
|
8199
|
+
...surfaceContour ? { surfaceContour } : {},
|
|
8200
|
+
...surfaceWireframe !== void 0 ? { surfaceWireframe } : {},
|
|
8201
|
+
...upDownBars !== void 0 ? { upDownBars } : {},
|
|
8202
|
+
...dataTable !== void 0 ? { dataTable } : {},
|
|
8203
|
+
...categoryAxisDate !== void 0 ? { categoryAxisDate } : {},
|
|
8204
|
+
...categoryAxisScaling !== void 0 ? { categoryAxisScaling } : {},
|
|
8205
|
+
...categoryGroupLevels !== void 0 ? { categoryGroupLevels } : {},
|
|
8206
|
+
...plotAreaLayout !== void 0 ? { plotAreaLayout } : {},
|
|
8207
|
+
...titleLayout !== void 0 ? { titleLayout } : {},
|
|
8208
|
+
...valueAxisLineHidden ? { valueAxisLineHidden } : {},
|
|
8209
|
+
...categoryAxisLineHidden ? { categoryAxisLineHidden } : {}
|
|
7093
8210
|
};
|
|
7094
8211
|
};
|
|
7095
8212
|
//#endregion
|
|
7096
|
-
//#region src/internal/chartml/embedded-xlsx.ts
|
|
7097
|
-
const TEXT_ENCODER = new TextEncoder();
|
|
7098
|
-
const encode = (s) => TEXT_ENCODER.encode(s);
|
|
7099
|
-
const xmlEscape = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
7100
|
-
const colLetter = (col) => {
|
|
7101
|
-
let n = col;
|
|
7102
|
-
let out = "";
|
|
7103
|
-
while (true) {
|
|
7104
|
-
out = String.fromCharCode(65 + n % 26) + out;
|
|
7105
|
-
if (n < 26) return out;
|
|
7106
|
-
n = Math.floor(n / 26) - 1;
|
|
7107
|
-
}
|
|
7108
|
-
};
|
|
7109
|
-
const cellRef = (row, col) => `${colLetter(col)}${row + 1}`;
|
|
7110
|
-
/**
|
|
7111
|
-
* Builds the bytes of a fresh xlsx whose only sheet is laid out as
|
|
7112
|
-
*
|
|
7113
|
-
* | | seriesNames[0] | seriesNames[1] | ...
|
|
7114
|
-
* |-------|----------------|----------------|----
|
|
7115
|
-
* | row0 | row0.values[0] | row0.values[1] | ...
|
|
7116
|
-
* | row1 | row1.values[0] | ... | ...
|
|
7117
|
-
*
|
|
7118
|
-
* Header row is row 1 in the sheet (1-indexed). The first column carries
|
|
7119
|
-
* category labels; subsequent columns carry series values.
|
|
7120
|
-
*/
|
|
7121
|
-
const buildEmbeddedXlsx = (seriesNames, rows) => {
|
|
7122
|
-
const sheetXmlParts = [];
|
|
7123
|
-
sheetXmlParts.push("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n", "<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">", "<sheetData>");
|
|
7124
|
-
sheetXmlParts.push("<row r=\"1\">");
|
|
7125
|
-
sheetXmlParts.push(`<c r="${cellRef(0, 0)}" t="inlineStr"><is><t></t></is></c>`);
|
|
7126
|
-
for (let i = 0; i < seriesNames.length; i++) sheetXmlParts.push(`<c r="${cellRef(0, i + 1)}" t="inlineStr"><is><t>${xmlEscape(seriesNames[i] ?? "")}</t></is></c>`);
|
|
7127
|
-
sheetXmlParts.push("</row>");
|
|
7128
|
-
for (let r = 0; r < rows.length; r++) {
|
|
7129
|
-
const row = rows[r];
|
|
7130
|
-
const rowIdx = r + 1;
|
|
7131
|
-
sheetXmlParts.push(`<row r="${rowIdx + 1}">`);
|
|
7132
|
-
sheetXmlParts.push(`<c r="${cellRef(rowIdx, 0)}" t="inlineStr"><is><t>${xmlEscape(row.label)}</t></is></c>`);
|
|
7133
|
-
for (let i = 0; i < row.values.length; i++) {
|
|
7134
|
-
const v = row.values[i];
|
|
7135
|
-
if (v === null || v === void 0) continue;
|
|
7136
|
-
sheetXmlParts.push(`<c r="${cellRef(rowIdx, i + 1)}"><v>${v}</v></c>`);
|
|
7137
|
-
}
|
|
7138
|
-
sheetXmlParts.push("</row>");
|
|
7139
|
-
}
|
|
7140
|
-
sheetXmlParts.push("</sheetData></worksheet>");
|
|
7141
|
-
const sheetXml = sheetXmlParts.join("");
|
|
7142
|
-
return writeZip([
|
|
7143
|
-
{
|
|
7144
|
-
name: "[Content_Types].xml",
|
|
7145
|
-
data: encode("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"><Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/><Default Extension=\"xml\" ContentType=\"application/xml\"/><Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/><Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/></Types>")
|
|
7146
|
-
},
|
|
7147
|
-
{
|
|
7148
|
-
name: "_rels/.rels",
|
|
7149
|
-
data: encode("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"xl/workbook.xml\"/></Relationships>")
|
|
7150
|
-
},
|
|
7151
|
-
{
|
|
7152
|
-
name: "xl/workbook.xml",
|
|
7153
|
-
data: encode("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"><sheets><sheet name=\"Sheet1\" sheetId=\"1\" r:id=\"rId1\"/></sheets></workbook>")
|
|
7154
|
-
},
|
|
7155
|
-
{
|
|
7156
|
-
name: "xl/_rels/workbook.xml.rels",
|
|
7157
|
-
data: encode("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet1.xml\"/></Relationships>")
|
|
7158
|
-
},
|
|
7159
|
-
{
|
|
7160
|
-
name: "xl/worksheets/sheet1.xml",
|
|
7161
|
-
data: encode(sheetXml)
|
|
7162
|
-
}
|
|
7163
|
-
]);
|
|
7164
|
-
};
|
|
7165
|
-
//#endregion
|
|
7166
8213
|
//#region src/api/fn/slide-background.ts
|
|
7167
8214
|
const setSlideBackgroundXml = (slide, configure) => {
|
|
7168
8215
|
const cSld = firstChildElement(slide[SLIDE_DOCUMENT].root, NAME_CSLD);
|
|
@@ -8138,12 +9185,22 @@ const validateChartSpecColors = (spec) => {
|
|
|
8138
9185
|
checkChartColor(spec.categoryAxisLineColor, "addSlideChart: categoryAxisLineColor");
|
|
8139
9186
|
checkChartColor(spec.secondaryValueAxis?.majorGridlineColor, "addSlideChart: secondaryValueAxis.majorGridlineColor");
|
|
8140
9187
|
checkChartColor(spec.secondaryValueAxis?.lineColor, "addSlideChart: secondaryValueAxis.lineColor");
|
|
9188
|
+
checkChartColor(spec.dataLabels?.fillColor, "addSlideChart: dataLabels.fillColor");
|
|
9189
|
+
checkChartColor(spec.upDownBars?.upColor, "addSlideChart: upDownBars.upColor");
|
|
9190
|
+
checkChartColor(spec.upDownBars?.downColor, "addSlideChart: upDownBars.downColor");
|
|
9191
|
+
checkChartColor(spec.seriesAxis?.lineColor, "addSlideChart: seriesAxis.lineColor");
|
|
8141
9192
|
spec.series.forEach((series, i) => {
|
|
8142
9193
|
checkChartColor(series.color, `addSlideChart: series[${i}].color`);
|
|
8143
9194
|
checkChartColor(series.lineColor, `addSlideChart: series[${i}].lineColor`);
|
|
8144
9195
|
checkChartColor(series.markerColor, `addSlideChart: series[${i}].markerColor`);
|
|
8145
9196
|
checkChartColor(series.markerLineColor, `addSlideChart: series[${i}].markerLineColor`);
|
|
8146
9197
|
checkChartColor(series.trendline?.color, `addSlideChart: series[${i}].trendline.color`);
|
|
9198
|
+
checkChartColor(series.errorBars?.color, `addSlideChart: series[${i}].errorBars.color`);
|
|
9199
|
+
checkChartColor(series.xErrorBars?.color, `addSlideChart: series[${i}].xErrorBars.color`);
|
|
9200
|
+
checkChartColor(series.dataLabels?.fillColor, `addSlideChart: series[${i}].dataLabels.fillColor`);
|
|
9201
|
+
series.pointDataLabels?.forEach((label, j) => {
|
|
9202
|
+
checkChartColor(label?.fillColor, `addSlideChart: series[${i}].pointDataLabels[${j}].fillColor`);
|
|
9203
|
+
});
|
|
8147
9204
|
series.pointColors?.forEach((c, j) => {
|
|
8148
9205
|
checkChartColor(c, `addSlideChart: series[${i}].pointColors[${j}]`);
|
|
8149
9206
|
});
|
|
@@ -8154,9 +9211,10 @@ const validateChartSpecAxes = (spec) => {
|
|
|
8154
9211
|
};
|
|
8155
9212
|
/**
|
|
8156
9213
|
* Adds a chart to the slide. Returns the new shape handle (kind
|
|
8157
|
-
* `graphicFrame`).
|
|
8158
|
-
* `
|
|
8159
|
-
*
|
|
9214
|
+
* `graphicFrame`). Every `ChartKind` is authorable, and the `view3D` /
|
|
9215
|
+
* `ofPie` / `surfaceContour` modifiers reach the remaining plot-group
|
|
9216
|
+
* elements (3-D bar / line / area / pie, pie-of-pie, contour) — see the
|
|
9217
|
+
* table on `ChartKind`.
|
|
8160
9218
|
*
|
|
8161
9219
|
* Side effects:
|
|
8162
9220
|
*
|
|
@@ -8170,9 +9228,15 @@ const validateChartSpecAxes = (spec) => {
|
|
|
8170
9228
|
*
|
|
8171
9229
|
* Constraints:
|
|
8172
9230
|
*
|
|
8173
|
-
* - `pie` charts require exactly one series
|
|
8174
|
-
*
|
|
8175
|
-
*
|
|
9231
|
+
* - `pie` / `doughnut` charts require exactly one series; `stock`
|
|
9232
|
+
* charts exactly three (high, low, close) or four (open first).
|
|
9233
|
+
* - `scatter` / `bubble` series carry their own `xValues` (and
|
|
9234
|
+
* `bubbleSizes`); `categories` is unused for them.
|
|
9235
|
+
* - All other series should have at most `categories.length` values;
|
|
9236
|
+
* missing values are treated as blanks (gaps in the visualization).
|
|
9237
|
+
* - A spec whose fields contradict each other (e.g. `view3D` on a
|
|
9238
|
+
* scatter chart, error bars on a pie) throws instead of writing a
|
|
9239
|
+
* chart PowerPoint would repair.
|
|
8176
9240
|
*/
|
|
8177
9241
|
const withChartDefaultTextColor = (spec, color) => {
|
|
8178
9242
|
if (color === null) return spec;
|
|
@@ -8210,11 +9274,7 @@ const addSlideChart = (slide, opts) => {
|
|
|
8210
9274
|
const chartN = allocateChartIndex(pkg);
|
|
8211
9275
|
const chartPartName = partName(`/ppt/charts/chart${chartN}.xml`);
|
|
8212
9276
|
const xlsxPartName = partName(`/ppt/embeddings/Microsoft_Excel_Worksheet${chartN}.xlsx`);
|
|
8213
|
-
const
|
|
8214
|
-
label,
|
|
8215
|
-
values: spec.series.map((s) => s.values[i] ?? null)
|
|
8216
|
-
}));
|
|
8217
|
-
const xlsxBytes = buildEmbeddedXlsx(spec.series.map((s) => s.name), xlsxRows);
|
|
9277
|
+
const xlsxBytes = buildEmbeddedXlsx(layoutChartSheet(spec).grid);
|
|
8218
9278
|
const chartBytes = encode$1(serializeXml(buildChartSpaceDoc(spec)));
|
|
8219
9279
|
pkg.addPart(chartPartName, CHART_CONTENT_TYPE, chartBytes);
|
|
8220
9280
|
pkg.addPart(xlsxPartName, EMBEDDED_XLSX_CONTENT_TYPE, xlsxBytes);
|
|
@@ -8304,12 +9364,7 @@ const setChartSpec = (chart, spec) => {
|
|
|
8304
9364
|
if (xlsxRel) {
|
|
8305
9365
|
const xlsxName = xlsxRel.target.startsWith("/") ? partName(xlsxRel.target) : resolveTarget(resolved.partName, xlsxRel.target);
|
|
8306
9366
|
const xlsxPart = pkg.getPart(xlsxName);
|
|
8307
|
-
|
|
8308
|
-
label,
|
|
8309
|
-
values: spec.series.map((s) => s.values[i] ?? null)
|
|
8310
|
-
}));
|
|
8311
|
-
const xlsxBytes = buildEmbeddedXlsx(spec.series.map((s) => s.name), rows);
|
|
8312
|
-
if (xlsxPart) xlsxPart.data = xlsxBytes;
|
|
9367
|
+
if (xlsxPart) xlsxPart.data = buildEmbeddedXlsx(layoutChartSheet(spec).grid);
|
|
8313
9368
|
}
|
|
8314
9369
|
}
|
|
8315
9370
|
};
|
|
@@ -8464,7 +9519,9 @@ const getPresentationChartKindCounts = (pres) => {
|
|
|
8464
9519
|
area: 0,
|
|
8465
9520
|
scatter: 0,
|
|
8466
9521
|
radar: 0,
|
|
8467
|
-
bubble: 0
|
|
9522
|
+
bubble: 0,
|
|
9523
|
+
stock: 0,
|
|
9524
|
+
surface: 0
|
|
8468
9525
|
};
|
|
8469
9526
|
for (const slide of getSlides(pres)) for (const chart of getSlideCharts(slide)) {
|
|
8470
9527
|
if (chart.spec === null) continue;
|
|
@@ -10397,7 +11454,7 @@ const PRES_PART = partName("/ppt/presentation.xml");
|
|
|
10397
11454
|
const PRES_RELS = partName("/ppt/_rels/presentation.xml.rels");
|
|
10398
11455
|
const NAME_SLD_ID_LST = qname("p", "sldIdLst", NS.pml);
|
|
10399
11456
|
const NAME_SLD_ID = qname("p", "sldId", NS.pml);
|
|
10400
|
-
const ATTR_ID = qname("", "id", "");
|
|
11457
|
+
const ATTR_ID$1 = qname("", "id", "");
|
|
10401
11458
|
const ATTR_R_ID = qname("r", "id", NS.officeDocRels);
|
|
10402
11459
|
const decoder = new TextDecoder();
|
|
10403
11460
|
const decode = (b) => decoder.decode(b);
|
|
@@ -10444,7 +11501,7 @@ const validatePresentationPackage = (pkg) => {
|
|
|
10444
11501
|
const seenRIds = /* @__PURE__ */ new Set();
|
|
10445
11502
|
const slidePartNames = [];
|
|
10446
11503
|
if (sldIdLst !== null) for (const sldId of allChildElements(sldIdLst, NAME_SLD_ID)) {
|
|
10447
|
-
const idRaw = getAttrValue(sldId, ATTR_ID);
|
|
11504
|
+
const idRaw = getAttrValue(sldId, ATTR_ID$1);
|
|
10448
11505
|
const rIdRaw = getAttrValue(sldId, ATTR_R_ID);
|
|
10449
11506
|
if (idRaw === null) {
|
|
10450
11507
|
issues.push({
|
|
@@ -10548,7 +11605,7 @@ const validatePresentationPackage = (pkg) => {
|
|
|
10548
11605
|
});
|
|
10549
11606
|
for (const rel of slideRels.items) {
|
|
10550
11607
|
if (rel.targetMode === "External") continue;
|
|
10551
|
-
if (rel.type !== REL_TYPES.image && rel.type !== REL_TYPES.chart && rel.type !== REL_TYPES.notesSlide && rel.type !== REL_TYPES.comments && rel.type !== REL_TYPES.oleObject && rel.type !== REL_TYPES.package) continue;
|
|
11608
|
+
if (rel.type !== REL_TYPES.image && rel.type !== REL_TYPES.media && rel.type !== REL_TYPES.video && rel.type !== REL_TYPES.audio && rel.type !== REL_TYPES.chart && rel.type !== REL_TYPES.notesSlide && rel.type !== REL_TYPES.comments && rel.type !== REL_TYPES.oleObject && rel.type !== REL_TYPES.package) continue;
|
|
10552
11609
|
const targetName = targetPartName(slideName, rel);
|
|
10553
11610
|
if (pkg.getPart(targetName) === null) issues.push({
|
|
10554
11611
|
severity: "error",
|
|
@@ -10582,7 +11639,7 @@ const validatePresentationPackage = (pkg) => {
|
|
|
10582
11639
|
if (!nvHost) continue;
|
|
10583
11640
|
const cNvPr = firstChildElement(nvHost, qname("p", "cNvPr", NS.pml));
|
|
10584
11641
|
if (!cNvPr) continue;
|
|
10585
|
-
const id = getAttrValue(cNvPr, ATTR_ID);
|
|
11642
|
+
const id = getAttrValue(cNvPr, ATTR_ID$1);
|
|
10586
11643
|
if (id === null) continue;
|
|
10587
11644
|
seenShapeIds.set(id, (seenShapeIds.get(id) ?? 0) + 1);
|
|
10588
11645
|
}
|
|
@@ -10593,6 +11650,23 @@ const validatePresentationPackage = (pkg) => {
|
|
|
10593
11650
|
message: `duplicate shape id="${id}" appears ${count}× in slide ${slideName}`,
|
|
10594
11651
|
partName: slideName
|
|
10595
11652
|
});
|
|
11653
|
+
const timing = firstChildElement(slideRoot, qname("p", "timing", NS.pml));
|
|
11654
|
+
const checkMediaNodes = (host) => {
|
|
11655
|
+
for (const child of host.children) {
|
|
11656
|
+
if (child.kind !== "element") continue;
|
|
11657
|
+
if (!isMediaTimingNode(child)) {
|
|
11658
|
+
checkMediaNodes(child);
|
|
11659
|
+
continue;
|
|
11660
|
+
}
|
|
11661
|
+
const target = mediaTimingNodeTarget(child);
|
|
11662
|
+
if (target !== null && !seenShapeIds.has(String(target))) issues.push({
|
|
11663
|
+
severity: "error",
|
|
11664
|
+
message: `media time node in slide ${slideName} targets missing shape id="${target}"`,
|
|
11665
|
+
partName: slideName
|
|
11666
|
+
});
|
|
11667
|
+
}
|
|
11668
|
+
};
|
|
11669
|
+
if (timing) checkMediaNodes(timing);
|
|
10596
11670
|
}
|
|
10597
11671
|
for (const part of pkg.parts) {
|
|
10598
11672
|
if (part.contentType !== "application/vnd.openxmlformats-officedocument.drawingml.chart+xml") continue;
|
|
@@ -12066,6 +13140,83 @@ const setShapeImageCrop = (shape, crop) => {
|
|
|
12066
13140
|
commitAndRefresh(shape);
|
|
12067
13141
|
};
|
|
12068
13142
|
//#endregion
|
|
13143
|
+
//#region src/api/fn/_media-timing.ts
|
|
13144
|
+
const NAME_TIMING = qname("p", "timing", NS.pml);
|
|
13145
|
+
const NAME_TN_LST = qname("p", "tnLst", NS.pml);
|
|
13146
|
+
const NAME_PAR = qname("p", "par", NS.pml);
|
|
13147
|
+
const NAME_C_TN = qname("p", "cTn", NS.pml);
|
|
13148
|
+
const NAME_CHILD_TN_LST = qname("p", "childTnLst", NS.pml);
|
|
13149
|
+
const NAME_EXT_LST$1 = qname("p", "extLst", NS.pml);
|
|
13150
|
+
const ATTR_ID = qname("", "id", "");
|
|
13151
|
+
const findSlideTiming = (slide) => firstChildElement(slide[SLIDE_DOCUMENT].root, NAME_TIMING);
|
|
13152
|
+
const insertSlideTiming = (slide, timing) => {
|
|
13153
|
+
const root = slide[SLIDE_DOCUMENT].root;
|
|
13154
|
+
const extLst = firstChildElement(root, NAME_EXT_LST$1);
|
|
13155
|
+
if (extLst === null) root.children.push(timing);
|
|
13156
|
+
else root.children.splice(root.children.indexOf(extLst), 0, timing);
|
|
13157
|
+
};
|
|
13158
|
+
/** The root time node's `<p:childTnLst>` — where media nodes and sequences live. */
|
|
13159
|
+
const rootChildTnLst = (timing) => {
|
|
13160
|
+
const tnLst = firstChildElement(timing, NAME_TN_LST);
|
|
13161
|
+
const par = tnLst ? firstChildElement(tnLst, NAME_PAR) : null;
|
|
13162
|
+
const cTn = par ? firstChildElement(par, NAME_C_TN) : null;
|
|
13163
|
+
return cTn ? firstChildElement(cTn, NAME_CHILD_TN_LST) : null;
|
|
13164
|
+
};
|
|
13165
|
+
const maxCTnId = (el) => {
|
|
13166
|
+
let max = 0;
|
|
13167
|
+
const walk = (e) => {
|
|
13168
|
+
if (e.name.namespaceURI === NS.pml && e.name.localName === "cTn") {
|
|
13169
|
+
const n = Number.parseInt(getAttrValue(e, ATTR_ID) ?? "", 10);
|
|
13170
|
+
if (Number.isFinite(n) && n > max) max = n;
|
|
13171
|
+
}
|
|
13172
|
+
for (const c of e.children) if (c.kind === "element") walk(c);
|
|
13173
|
+
};
|
|
13174
|
+
walk(el);
|
|
13175
|
+
return max;
|
|
13176
|
+
};
|
|
13177
|
+
/** Adds the media time node for shape `spid`. The caller commits the slide. */
|
|
13178
|
+
const addMediaTimingNode = (slide, kind, spid) => {
|
|
13179
|
+
const timing = findSlideTiming(slide);
|
|
13180
|
+
if (timing === null) {
|
|
13181
|
+
insertSlideTiming(slide, buildTimingRoot([buildMediaTimingNode(kind, spid, 2)]));
|
|
13182
|
+
return;
|
|
13183
|
+
}
|
|
13184
|
+
const node = buildMediaTimingNode(kind, spid, maxCTnId(timing) + 1);
|
|
13185
|
+
const childTnLst = rootChildTnLst(timing);
|
|
13186
|
+
if (childTnLst !== null) {
|
|
13187
|
+
childTnLst.children.push(node);
|
|
13188
|
+
return;
|
|
13189
|
+
}
|
|
13190
|
+
const fresh = buildTimingRoot([node]);
|
|
13191
|
+
const rest = timing.children.filter((c) => !(c.kind === "element" && c.name.namespaceURI === NS.pml && c.name.localName === "tnLst"));
|
|
13192
|
+
timing.children = [...fresh.children, ...rest];
|
|
13193
|
+
};
|
|
13194
|
+
/**
|
|
13195
|
+
* Removes the media nodes targeting any of `spids`, and the whole `<p:timing>`
|
|
13196
|
+
* when that leaves the root without children (an empty `<p:childTnLst>` is
|
|
13197
|
+
* schema-invalid and an empty root animates nothing). The caller commits.
|
|
13198
|
+
*/
|
|
13199
|
+
const removeMediaTimingNodes = (slide, spids) => {
|
|
13200
|
+
const timing = findSlideTiming(slide);
|
|
13201
|
+
const childTnLst = timing ? rootChildTnLst(timing) : null;
|
|
13202
|
+
if (timing === null || childTnLst === null) return;
|
|
13203
|
+
childTnLst.children = childTnLst.children.filter((c) => {
|
|
13204
|
+
if (c.kind !== "element" || !isMediaTimingNode(c)) return true;
|
|
13205
|
+
const target = mediaTimingNodeTarget(c);
|
|
13206
|
+
return target === null || !spids.has(target);
|
|
13207
|
+
});
|
|
13208
|
+
if (!childTnLst.children.some((c) => c.kind === "element")) {
|
|
13209
|
+
const root = slide[SLIDE_DOCUMENT].root;
|
|
13210
|
+
root.children = root.children.filter((c) => c !== timing);
|
|
13211
|
+
}
|
|
13212
|
+
};
|
|
13213
|
+
/** Media nodes at the timing root, in document order. */
|
|
13214
|
+
const mediaTimingNodes = (timing) => {
|
|
13215
|
+
const childTnLst = rootChildTnLst(timing);
|
|
13216
|
+
if (childTnLst === null) return [];
|
|
13217
|
+
return childTnLst.children.filter((c) => c.kind === "element" && isMediaTimingNode(c));
|
|
13218
|
+
};
|
|
13219
|
+
//#endregion
|
|
12069
13220
|
//#region src/api/fn/shape-animation.ts
|
|
12070
13221
|
NS.pml;
|
|
12071
13222
|
const ATTR_ID_FN = qname("", "id", "");
|
|
@@ -12085,18 +13236,6 @@ const findDescendant = (el, pred) => {
|
|
|
12085
13236
|
return null;
|
|
12086
13237
|
};
|
|
12087
13238
|
const isPml = (el, local) => el.name.namespaceURI === NS.pml && el.name.localName === local;
|
|
12088
|
-
const maxCTnId = (el) => {
|
|
12089
|
-
let max = 0;
|
|
12090
|
-
const walk = (e) => {
|
|
12091
|
-
if (isPml(e, "cTn")) {
|
|
12092
|
-
const n = Number.parseInt(getAttrValue(e, ATTR_ID_FN) ?? "", 10);
|
|
12093
|
-
if (Number.isFinite(n) && n > max) max = n;
|
|
12094
|
-
}
|
|
12095
|
-
for (const c of e.children) if (c.kind === "element") walk(c);
|
|
12096
|
-
};
|
|
12097
|
-
walk(el);
|
|
12098
|
-
return max;
|
|
12099
|
-
};
|
|
12100
13239
|
const shiftCTnIds = (el, offset) => {
|
|
12101
13240
|
const walk = (e) => {
|
|
12102
13241
|
if (isPml(e, "cTn")) {
|
|
@@ -12130,29 +13269,40 @@ const setGrpId = (el, grpId) => {
|
|
|
12130
13269
|
value: grpId
|
|
12131
13270
|
} : a);
|
|
12132
13271
|
};
|
|
13272
|
+
const isMainSeqCTn = (e) => isPml(e, "cTn") && getAttrValue(e, qname("", "nodeType", "")) === "mainSeq";
|
|
12133
13273
|
const mergeEffectInto = (existing, fresh) => {
|
|
12134
|
-
const
|
|
12135
|
-
const mainSeq = findDescendant(existing, (e) => isPml(e, "cTn") && getAttrValue(e, qname("", "nodeType", "")) === "mainSeq");
|
|
12136
|
-
return mainSeq ? firstChildElement(mainSeq, qname("p", "childTnLst", NS.pml)) : null;
|
|
12137
|
-
})();
|
|
12138
|
-
if (!existingMainSeqChildTnLst) return false;
|
|
12139
|
-
const freshMainSeq = findDescendant(fresh, (e) => isPml(e, "cTn") && getAttrValue(e, qname("", "nodeType", "")) === "mainSeq");
|
|
13274
|
+
const freshMainSeq = findDescendant(fresh, isMainSeqCTn);
|
|
12140
13275
|
const freshChildTnLst = freshMainSeq ? firstChildElement(freshMainSeq, qname("p", "childTnLst", NS.pml)) : null;
|
|
12141
13276
|
const newPar = freshChildTnLst ? freshChildTnLst.children.find((c) => c.kind === "element" && isPml(c, "par")) : null;
|
|
12142
13277
|
const freshBldP = findDescendant(fresh, (e) => isPml(e, "bldP"));
|
|
12143
13278
|
if (!newPar || !freshBldP) return false;
|
|
12144
|
-
const offset = maxCTnId(existing) - 2;
|
|
12145
|
-
if (offset > 0) shiftCTnIds(newPar, offset);
|
|
12146
13279
|
const newGrpId = String(maxGrpId(existing) + 1);
|
|
12147
13280
|
const effectCTn = findDescendant(newPar, (e) => getAttrValue(e, qname("", "presetID", "")) !== null);
|
|
13281
|
+
const existingMainSeq = findDescendant(existing, isMainSeqCTn);
|
|
13282
|
+
const existingMainSeqChildTnLst = existingMainSeq ? firstChildElement(existingMainSeq, qname("p", "childTnLst", NS.pml)) : null;
|
|
13283
|
+
if (existingMainSeqChildTnLst) {
|
|
13284
|
+
const offset = maxCTnId(existing) - 2;
|
|
13285
|
+
if (offset > 0) shiftCTnIds(newPar, offset);
|
|
13286
|
+
existingMainSeqChildTnLst.children.push(newPar);
|
|
13287
|
+
} else {
|
|
13288
|
+
const rootList = rootChildTnLst(existing);
|
|
13289
|
+
const freshSeq = rootChildTnLst(fresh)?.children.find((c) => c.kind === "element" && isPml(c, "seq"));
|
|
13290
|
+
if (!rootList || !freshSeq) return false;
|
|
13291
|
+
shiftCTnIds(freshSeq, maxCTnId(existing) - 1);
|
|
13292
|
+
rootList.children.unshift(freshSeq);
|
|
13293
|
+
}
|
|
12148
13294
|
if (effectCTn) setGrpId(effectCTn, newGrpId);
|
|
12149
13295
|
setGrpId(freshBldP, newGrpId);
|
|
12150
|
-
existingMainSeqChildTnLst.children.push(newPar);
|
|
12151
13296
|
const existingBldLst = findDescendant(existing, (e) => isPml(e, "bldLst"));
|
|
12152
13297
|
if (existingBldLst) existingBldLst.children.push(freshBldP);
|
|
12153
|
-
else existing
|
|
13298
|
+
else insertBldLst(existing, elem(qname("p", "bldLst", NS.pml), { children: [freshBldP] }));
|
|
12154
13299
|
return true;
|
|
12155
13300
|
};
|
|
13301
|
+
const insertBldLst = (timing, bldLst) => {
|
|
13302
|
+
const extLst = firstChildElement(timing, qname("p", "extLst", NS.pml));
|
|
13303
|
+
if (extLst === null) timing.children.push(bldLst);
|
|
13304
|
+
else timing.children.splice(timing.children.indexOf(extLst), 0, bldLst);
|
|
13305
|
+
};
|
|
12156
13306
|
/**
|
|
12157
13307
|
* Sets a single click-triggered animation effect on the given shape.
|
|
12158
13308
|
*
|
|
@@ -12240,7 +13390,12 @@ const findShapesWithAnimation = (slide) => {
|
|
|
12240
13390
|
return out;
|
|
12241
13391
|
};
|
|
12242
13392
|
const clearSlideAnimations = (slide) => {
|
|
12243
|
-
|
|
13393
|
+
const existing = findTiming(slide);
|
|
13394
|
+
const mediaNodes = existing ? mediaTimingNodes(existing) : [];
|
|
13395
|
+
if (existing !== null && mediaNodes.length > 0) {
|
|
13396
|
+
const root = slide[SLIDE_DOCUMENT].root;
|
|
13397
|
+
root.children[root.children.indexOf(existing)] = buildTimingRoot(mediaNodes);
|
|
13398
|
+
} else removeExistingTiming(slide);
|
|
12244
13399
|
commitSlideData(slide);
|
|
12245
13400
|
refreshSlideData(slide);
|
|
12246
13401
|
};
|
|
@@ -15791,7 +16946,8 @@ const copyShape = (targetSlide, sourceShape) => {
|
|
|
15791
16946
|
const pkg = targetSlide[INTERNAL_PACKAGE];
|
|
15792
16947
|
const sourceEl = sourceShape[SHAPE_ELEMENT];
|
|
15793
16948
|
const cloned = cloneXmlElement(sourceEl);
|
|
15794
|
-
|
|
16949
|
+
const newId = nextShapeId(targetSlide);
|
|
16950
|
+
rewriteCNvPrId(cloned, newId);
|
|
15795
16951
|
const sourceRels = pkg.getRels(sourceSlide[SLIDE_PART_NAME]);
|
|
15796
16952
|
if (sourceRels) {
|
|
15797
16953
|
const targetRels = pkg.getRels(targetSlide[SLIDE_PART_NAME]) ?? emptyRels();
|
|
@@ -15811,6 +16967,8 @@ const copyShape = (targetSlide, sourceShape) => {
|
|
|
15811
16967
|
});
|
|
15812
16968
|
pkg.setRels(targetSlide[SLIDE_PART_NAME], targetRels);
|
|
15813
16969
|
}
|
|
16970
|
+
const media = cloned.name.localName === "pic" ? readPictureMediaRef(cloned) : null;
|
|
16971
|
+
if (media !== null) addMediaTimingNode(targetSlide, media.kind, newId);
|
|
15814
16972
|
return appendAndReturnNewShape(targetSlide, cloned);
|
|
15815
16973
|
};
|
|
15816
16974
|
/** Recursively clone an XML element (no parent, deep). */
|
|
@@ -15995,7 +17153,13 @@ const sendShapeBackward = (shape) => {
|
|
|
15995
17153
|
*/
|
|
15996
17154
|
const clearSlideShapes = (slide) => {
|
|
15997
17155
|
const spTree = requireSpTree(slide);
|
|
15998
|
-
|
|
17156
|
+
const removedIds = /* @__PURE__ */ new Set();
|
|
17157
|
+
spTree.children = spTree.children.filter((c) => {
|
|
17158
|
+
const isShape = c.kind === "element" && c.name.namespaceURI === NS.pml && SHAPE_CHILD_LOCALS.has(c.name.localName);
|
|
17159
|
+
if (isShape) collectShapeIds(c, removedIds);
|
|
17160
|
+
return !isShape;
|
|
17161
|
+
});
|
|
17162
|
+
removeMediaTimingNodes(slide, removedIds);
|
|
15999
17163
|
commitSlideData(slide);
|
|
16000
17164
|
rebuildShapesFromDocument(slide);
|
|
16001
17165
|
};
|
|
@@ -16009,9 +17173,20 @@ const removeShape = (shape) => {
|
|
|
16009
17173
|
const idx = spTree.children.indexOf(shape[SHAPE_ELEMENT]);
|
|
16010
17174
|
if (idx < 0) return;
|
|
16011
17175
|
spTree.children.splice(idx, 1);
|
|
17176
|
+
const removedIds = /* @__PURE__ */ new Set();
|
|
17177
|
+
collectShapeIds(shape[SHAPE_ELEMENT], removedIds);
|
|
17178
|
+
removeMediaTimingNodes(slide, removedIds);
|
|
16012
17179
|
commitSlideData(slide);
|
|
16013
17180
|
rebuildShapesFromDocument(slide);
|
|
16014
17181
|
};
|
|
17182
|
+
const collectShapeIds = (el, into) => {
|
|
17183
|
+
if (el.name.namespaceURI === NS.pml && el.name.localName === "cNvPr") {
|
|
17184
|
+
const id = Number.parseInt(getAttrValue(el, qname("", "id", "")) ?? "", 10);
|
|
17185
|
+
if (Number.isFinite(id)) into.add(id);
|
|
17186
|
+
return;
|
|
17187
|
+
}
|
|
17188
|
+
for (const c of el.children) if (c.kind === "element") collectShapeIds(c, into);
|
|
17189
|
+
};
|
|
16015
17190
|
//#endregion
|
|
16016
17191
|
//#region src/api/fn/shape-authoring.ts
|
|
16017
17192
|
/**
|
|
@@ -16839,7 +18014,7 @@ const ensureSldIdLst = (presentationRoot) => {
|
|
|
16839
18014
|
const allocateSldId = (sldIdLst) => {
|
|
16840
18015
|
let max = 255;
|
|
16841
18016
|
for (const sldId of allChildElements(sldIdLst, NAME_SLD_ID$1)) {
|
|
16842
|
-
const raw = getAttrValue(sldId, ATTR_ID$
|
|
18017
|
+
const raw = getAttrValue(sldId, ATTR_ID$2);
|
|
16843
18018
|
if (raw === null) continue;
|
|
16844
18019
|
const n = Number.parseInt(raw, 10);
|
|
16845
18020
|
if (Number.isFinite(n) && n > max) max = n;
|
|
@@ -16970,7 +18145,7 @@ const addSlide = (pres, options) => {
|
|
|
16970
18145
|
targetMode: "Internal"
|
|
16971
18146
|
});
|
|
16972
18147
|
pkg.setRels(PRES_PART_NAME, presRels);
|
|
16973
|
-
sldIdLst.children.push(elem(NAME_SLD_ID$1, { attrs: [attr(ATTR_ID$
|
|
18148
|
+
sldIdLst.children.push(elem(NAME_SLD_ID$1, { attrs: [attr(ATTR_ID$2, String(newSldId)), attr(ATTR_R_ID$1, newRId)] }));
|
|
16974
18149
|
presPart.data = encode$1(serializeXml(presDoc));
|
|
16975
18150
|
pres._slidesCache = null;
|
|
16976
18151
|
const slides = getSlides(pres);
|
|
@@ -17149,7 +18324,7 @@ const duplicateSlide = (pres, slide) => {
|
|
|
17149
18324
|
targetMode: "Internal"
|
|
17150
18325
|
});
|
|
17151
18326
|
pkg.setRels(PRES_PART_NAME, presRels);
|
|
17152
|
-
sldIdLst.children.push(elem(NAME_SLD_ID$1, { attrs: [attr(ATTR_ID$
|
|
18327
|
+
sldIdLst.children.push(elem(NAME_SLD_ID$1, { attrs: [attr(ATTR_ID$2, String(newSldId)), attr(ATTR_R_ID$1, newRId)] }));
|
|
17153
18328
|
presPart.data = encode$1(serializeXml(presDoc));
|
|
17154
18329
|
pres._slidesCache = null;
|
|
17155
18330
|
const slides = getSlides(pres);
|
|
@@ -17179,6 +18354,12 @@ const collectRelRefs = (el, into) => {
|
|
|
17179
18354
|
for (const a of el.attrs) if (a.name.namespaceURI === NS.officeDocRels) into.add(a.value);
|
|
17180
18355
|
for (const c of el.children) if (c.kind === "element") collectRelRefs(c, into);
|
|
17181
18356
|
};
|
|
18357
|
+
const IMPORTED_MEDIA_REL_TYPES = new Set([
|
|
18358
|
+
REL_TYPES.image,
|
|
18359
|
+
REL_TYPES.media,
|
|
18360
|
+
REL_TYPES.video,
|
|
18361
|
+
REL_TYPES.audio
|
|
18362
|
+
]);
|
|
17182
18363
|
const pruneDanglingGraphicFrames = (el, keptRelIds) => {
|
|
17183
18364
|
el.children = el.children.filter((c) => {
|
|
17184
18365
|
if (c.kind !== "element") return true;
|
|
@@ -17200,8 +18381,8 @@ const pruneDanglingGraphicFrames = (el, keptRelIds) => {
|
|
|
17200
18381
|
*
|
|
17201
18382
|
* Limitations (v1):
|
|
17202
18383
|
*
|
|
17203
|
-
* - Only
|
|
17204
|
-
* workbooks, oleObjects, comments) are dropped from the imported
|
|
18384
|
+
* - Only image / video / audio rels are copied across. Other rels (charts,
|
|
18385
|
+
* embedded workbooks, oleObjects, comments) are dropped from the imported
|
|
17205
18386
|
* slide. A diagnostic message is appended for each dropped rel.
|
|
17206
18387
|
* - Hyperlinks (external URLs) are preserved.
|
|
17207
18388
|
* - Slide → notesSlide is dropped (notes don't follow imports).
|
|
@@ -17233,31 +18414,42 @@ const importSlide = (targetPres, sourceSlide, targetLayout) => {
|
|
|
17233
18414
|
target: `../slideLayouts/${basename(layoutPartName)}`,
|
|
17234
18415
|
targetMode: "Internal"
|
|
17235
18416
|
});
|
|
18417
|
+
const importedMedia = /* @__PURE__ */ new Map();
|
|
17236
18418
|
if (sourceRels !== null) for (const rel of sourceRels.items) {
|
|
17237
18419
|
if (rel.type === REL_TYPES.slideLayout) continue;
|
|
17238
18420
|
if (rel.type === REL_TYPES.notesSlide) continue;
|
|
17239
|
-
if (rel.type
|
|
18421
|
+
if (IMPORTED_MEDIA_REL_TYPES.has(rel.type)) {
|
|
18422
|
+
if (rel.targetMode === "External") {
|
|
18423
|
+
newRels.items.push({ ...rel });
|
|
18424
|
+
continue;
|
|
18425
|
+
}
|
|
17240
18426
|
const mediaName = rel.target.startsWith("/") ? partName(rel.target) : resolveTarget(sourcePartName, rel.target);
|
|
17241
|
-
|
|
17242
|
-
if (
|
|
17243
|
-
|
|
17244
|
-
|
|
17245
|
-
|
|
17246
|
-
|
|
17247
|
-
|
|
17248
|
-
|
|
17249
|
-
|
|
17250
|
-
|
|
17251
|
-
|
|
18427
|
+
let target = importedMedia.get(mediaName);
|
|
18428
|
+
if (target === void 0) {
|
|
18429
|
+
const mediaPart = sourcePkg.getPart(mediaName);
|
|
18430
|
+
if (!mediaPart) continue;
|
|
18431
|
+
const dotIdx = mediaName.lastIndexOf(".");
|
|
18432
|
+
const extension = dotIdx >= 0 ? mediaName.slice(dotIdx + 1) : "bin";
|
|
18433
|
+
const stem = rel.type === REL_TYPES.image ? "image" : "media";
|
|
18434
|
+
let nextN = 1;
|
|
18435
|
+
const re = new RegExp(`^/ppt/media/${stem}(\\d+)\\.`);
|
|
18436
|
+
for (const p of targetPkg.parts) {
|
|
18437
|
+
const m = p.name.match(re);
|
|
18438
|
+
if (m?.[1] !== void 0) {
|
|
18439
|
+
const n = Number.parseInt(m[1], 10);
|
|
18440
|
+
if (Number.isFinite(n) && n >= nextN) nextN = n + 1;
|
|
18441
|
+
}
|
|
17252
18442
|
}
|
|
18443
|
+
const newMediaName = partName(`/ppt/media/${stem}${nextN}.${extension}`);
|
|
18444
|
+
setOpcDefault(targetPkg, extension.toLowerCase(), mediaPart.contentType);
|
|
18445
|
+
targetPkg.addPart(newMediaName, mediaPart.contentType, new Uint8Array(mediaPart.data));
|
|
18446
|
+
target = `../media/${stem}${nextN}.${extension}`;
|
|
18447
|
+
importedMedia.set(mediaName, target);
|
|
17253
18448
|
}
|
|
17254
|
-
const newMediaName = partName(`/ppt/media/image${nextN}.${extension}`);
|
|
17255
|
-
setOpcDefault(targetPkg, extension.toLowerCase(), mediaPart.contentType);
|
|
17256
|
-
targetPkg.addPart(newMediaName, mediaPart.contentType, new Uint8Array(mediaPart.data));
|
|
17257
18449
|
newRels.items.push({
|
|
17258
18450
|
id: rel.id,
|
|
17259
|
-
type:
|
|
17260
|
-
target
|
|
18451
|
+
type: rel.type,
|
|
18452
|
+
target,
|
|
17261
18453
|
targetMode: "Internal"
|
|
17262
18454
|
});
|
|
17263
18455
|
continue;
|
|
@@ -17293,7 +18485,7 @@ const importSlide = (targetPres, sourceSlide, targetLayout) => {
|
|
|
17293
18485
|
targetMode: "Internal"
|
|
17294
18486
|
});
|
|
17295
18487
|
targetPkg.setRels(PRES_PART_NAME, presRels);
|
|
17296
|
-
sldIdLst.children.push(elem(NAME_SLD_ID$1, { attrs: [attr(ATTR_ID$
|
|
18488
|
+
sldIdLst.children.push(elem(NAME_SLD_ID$1, { attrs: [attr(ATTR_ID$2, String(newSldId)), attr(ATTR_R_ID$1, newRId)] }));
|
|
17297
18489
|
presPart.data = encode$1(serializeXml(presDoc));
|
|
17298
18490
|
targetPres._slidesCache = null;
|
|
17299
18491
|
const slides = getSlides(targetPres);
|
|
@@ -17436,9 +18628,204 @@ const ungroupShapes = (group) => {
|
|
|
17436
18628
|
});
|
|
17437
18629
|
};
|
|
17438
18630
|
//#endregion
|
|
18631
|
+
//#region src/api/fn/media.ts
|
|
18632
|
+
const DEFAULT_POSTER_BASE64 = "iVBORw0KGgoAAAANSUhEUgAAAUAAAAC0AQMAAADfKmdSAAAABlBMVEUmJib///+/9FOwAAAAvUlEQVR42u3XMQ7DIBAEQOfnfhpP4QmUFAgiJUqdKa6xtFtPA8J36+tKkiRJkiR5RF4Mm8KucCrcCg/DpnAoXAq3wnMr7AqnwqXwMGwKu8KpcCukK//ApnAoXAq3QjnNF3aFU+FSeBg2hUPhVLgV/r/yH2wKRzls1YfZ5Rc+yh9F+cOd5R/XXT0AVvmQatWDlEczD3teH7yQypcmr2Fe7FoVuHxwneGCxJWrvBZy0eTqymU4fxhJkiRJkjwqbzMmJGbQfp8bAAAAAElFTkSuQmCC";
|
|
18633
|
+
const defaultPoster = () => Uint8Array.from(atob(DEFAULT_POSTER_BASE64), (ch) => ch.charCodeAt(0));
|
|
18634
|
+
const YOUTUBE_HOSTS = new Set([
|
|
18635
|
+
"youtube.com",
|
|
18636
|
+
"www.youtube.com",
|
|
18637
|
+
"m.youtube.com"
|
|
18638
|
+
]);
|
|
18639
|
+
const YOUTUBE_SHORT_HOST = "youtu.be";
|
|
18640
|
+
const YOUTUBE_ID = /^[A-Za-z0-9_-]+$/;
|
|
18641
|
+
const youtubeVideoId = (url) => {
|
|
18642
|
+
const segments = url.pathname.split("/").filter((s) => s !== "");
|
|
18643
|
+
if (url.hostname === YOUTUBE_SHORT_HOST) return segments[0] ?? null;
|
|
18644
|
+
if (!YOUTUBE_HOSTS.has(url.hostname)) return null;
|
|
18645
|
+
if (segments[0] === "watch") return url.searchParams.get("v");
|
|
18646
|
+
if (segments[0] === "shorts" || segments[0] === "live") return segments[1] ?? null;
|
|
18647
|
+
return null;
|
|
18648
|
+
};
|
|
18649
|
+
const resolveOnlineVideoUrl = (input) => {
|
|
18650
|
+
let url;
|
|
18651
|
+
try {
|
|
18652
|
+
url = new URL(input);
|
|
18653
|
+
} catch {
|
|
18654
|
+
throw new Error(`addSlideMedia: url is not an absolute URL: ${JSON.stringify(input)}`);
|
|
18655
|
+
}
|
|
18656
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") throw new Error(`addSlideMedia: url must be http(s), got ${JSON.stringify(input)}`);
|
|
18657
|
+
const id = youtubeVideoId(url);
|
|
18658
|
+
if (id === null || !YOUTUBE_ID.test(id)) return url.href;
|
|
18659
|
+
return `https://www.youtube.com/embed/${id}?feature=oembed`;
|
|
18660
|
+
};
|
|
18661
|
+
const MEDIA_DIR = "/ppt/media/";
|
|
18662
|
+
const nextMediaPartName = (pkg, stem, extension) => {
|
|
18663
|
+
let nextN = 1;
|
|
18664
|
+
const pattern = new RegExp(`^/ppt/media/${stem}(\\d+)\\.`);
|
|
18665
|
+
for (const p of pkg.parts) {
|
|
18666
|
+
const m = p.name.match(pattern);
|
|
18667
|
+
if (m?.[1] !== void 0) {
|
|
18668
|
+
const n = Number.parseInt(m[1], 10);
|
|
18669
|
+
if (n >= nextN) nextN = n + 1;
|
|
18670
|
+
}
|
|
18671
|
+
}
|
|
18672
|
+
return partName(`${MEDIA_DIR}${stem}${nextN}.${extension}`);
|
|
18673
|
+
};
|
|
18674
|
+
const bytesEqual = (a, b) => {
|
|
18675
|
+
if (a.length !== b.length) return false;
|
|
18676
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
18677
|
+
return true;
|
|
18678
|
+
};
|
|
18679
|
+
const internClipPart = (pkg, extension, contentType, bytes) => {
|
|
18680
|
+
for (const p of pkg.parts) if (p.name.startsWith(MEDIA_DIR) && p.contentType === contentType && bytesEqual(p.data, bytes)) return p.name;
|
|
18681
|
+
const name = nextMediaPartName(pkg, "media", extension);
|
|
18682
|
+
setOpcDefault(pkg, extension, contentType);
|
|
18683
|
+
pkg.addPart(name, contentType, bytes);
|
|
18684
|
+
return name;
|
|
18685
|
+
};
|
|
18686
|
+
const resolveSource = (source) => {
|
|
18687
|
+
switch (source.kind) {
|
|
18688
|
+
case "online": return { url: resolveOnlineVideoUrl(source.url) };
|
|
18689
|
+
case "video": {
|
|
18690
|
+
const format = source.format ?? detectVideoFormat(source.data);
|
|
18691
|
+
if (format === null) throw new Error("addSlideMedia: could not detect the video format. Pass options.format explicitly.");
|
|
18692
|
+
const contentType = contentTypeForVideoFormat(format);
|
|
18693
|
+
return {
|
|
18694
|
+
data: source.data,
|
|
18695
|
+
extension: format,
|
|
18696
|
+
contentType
|
|
18697
|
+
};
|
|
18698
|
+
}
|
|
18699
|
+
case "audio": {
|
|
18700
|
+
const format = source.format ?? detectAudioFormat(source.data);
|
|
18701
|
+
if (format === null) throw new Error("addSlideMedia: could not detect the audio format. Pass options.format explicitly.");
|
|
18702
|
+
const contentType = contentTypeForAudioFormat(format);
|
|
18703
|
+
return {
|
|
18704
|
+
data: source.data,
|
|
18705
|
+
extension: format,
|
|
18706
|
+
contentType
|
|
18707
|
+
};
|
|
18708
|
+
}
|
|
18709
|
+
}
|
|
18710
|
+
};
|
|
18711
|
+
const DEFAULT_NAME_PREFIX = {
|
|
18712
|
+
video: "Video",
|
|
18713
|
+
audio: "Audio",
|
|
18714
|
+
online: "Online Media"
|
|
18715
|
+
};
|
|
18716
|
+
/**
|
|
18717
|
+
* Adds a video, an audio clip or an online (URL) video to the slide. Returns
|
|
18718
|
+
* the new picture shape — the clip's poster frame.
|
|
18719
|
+
*
|
|
18720
|
+
* Embedded clips are stored once per package: adding the same bytes again
|
|
18721
|
+
* reuses the existing `/ppt/media/mediaN.<ext>` part. The container format is
|
|
18722
|
+
* detected from the bytes (mp4 / m4v / mov / webm / avi / wmv, mp3 / wav / m4a /
|
|
18723
|
+
* ogg / wma); pass `format` for anything the signature check cannot tell.
|
|
18724
|
+
* Whether a clip plays depends on the codecs of the viewing application.
|
|
18725
|
+
*
|
|
18726
|
+
* The shape is an ordinary picture: `getShapeImageBytes` / `setShapeImage`
|
|
18727
|
+
* read and replace the poster, `getShapeMedia` reads the clip.
|
|
18728
|
+
*/
|
|
18729
|
+
const addSlideMedia = (slide, opts) => {
|
|
18730
|
+
const x = emuCoordinate(opts.x, "addSlideMedia: x");
|
|
18731
|
+
const y = emuCoordinate(opts.y, "addSlideMedia: y");
|
|
18732
|
+
const w = emuExtent(opts.w, "addSlideMedia: w");
|
|
18733
|
+
const h = emuExtent(opts.h, "addSlideMedia: h");
|
|
18734
|
+
const source = resolveSource(opts);
|
|
18735
|
+
const poster = opts.poster ?? defaultPoster();
|
|
18736
|
+
const posterFormat = opts.posterFormat ?? detectImageFormat(poster);
|
|
18737
|
+
if (posterFormat === null) throw new Error("addSlideMedia: could not detect the poster image format. Pass options.posterFormat explicitly.");
|
|
18738
|
+
const pkg = slide[INTERNAL_PACKAGE];
|
|
18739
|
+
const slidePartName = slide[SLIDE_PART_NAME];
|
|
18740
|
+
const rels = pkg.getRels(slidePartName) ?? emptyRels();
|
|
18741
|
+
const usedIds = rels.items.map((r) => r.id);
|
|
18742
|
+
const relate = (type, target, targetMode) => {
|
|
18743
|
+
const existing = rels.items.find((r) => r.type === type && r.target === target && r.targetMode === targetMode);
|
|
18744
|
+
if (existing) return existing.id;
|
|
18745
|
+
const id = nextRelId(usedIds);
|
|
18746
|
+
usedIds.push(id);
|
|
18747
|
+
rels.items.push({
|
|
18748
|
+
id,
|
|
18749
|
+
type,
|
|
18750
|
+
target,
|
|
18751
|
+
targetMode
|
|
18752
|
+
});
|
|
18753
|
+
return id;
|
|
18754
|
+
};
|
|
18755
|
+
const relativeTarget = (name) => `../media/${name.slice(11)}`;
|
|
18756
|
+
const kind = opts.kind === "audio" ? "audio" : "video";
|
|
18757
|
+
const fileRelType = kind === "audio" ? REL_TYPES.audio : REL_TYPES.video;
|
|
18758
|
+
let rLink;
|
|
18759
|
+
let rMedia;
|
|
18760
|
+
if ("url" in source) rLink = relate(fileRelType, source.url, "External");
|
|
18761
|
+
else {
|
|
18762
|
+
const clipPart = internClipPart(pkg, source.extension, source.contentType, source.data);
|
|
18763
|
+
rMedia = relate(REL_TYPES.media, relativeTarget(clipPart), "Internal");
|
|
18764
|
+
rLink = relate(fileRelType, relativeTarget(clipPart), "Internal");
|
|
18765
|
+
}
|
|
18766
|
+
const posterExtension = extensionForFormat(posterFormat);
|
|
18767
|
+
const posterContentType = contentTypeForFormat(posterFormat);
|
|
18768
|
+
const posterPart = nextMediaPartName(pkg, "image", posterExtension);
|
|
18769
|
+
setOpcDefault(pkg, posterExtension, posterContentType);
|
|
18770
|
+
pkg.addPart(posterPart, posterContentType, poster);
|
|
18771
|
+
const rPoster = relate(REL_TYPES.image, relativeTarget(posterPart), "Internal");
|
|
18772
|
+
pkg.setRels(slidePartName, rels);
|
|
18773
|
+
const id = nextShapeId(slide);
|
|
18774
|
+
const pic = buildMediaPicture({
|
|
18775
|
+
id,
|
|
18776
|
+
name: opts.name ?? `${DEFAULT_NAME_PREFIX[opts.kind]} ${id}`,
|
|
18777
|
+
kind,
|
|
18778
|
+
rLink,
|
|
18779
|
+
...rMedia !== void 0 ? { rMedia } : {},
|
|
18780
|
+
rEmbed: rPoster,
|
|
18781
|
+
x,
|
|
18782
|
+
y,
|
|
18783
|
+
w,
|
|
18784
|
+
h
|
|
18785
|
+
});
|
|
18786
|
+
addMediaTimingNode(slide, kind, id);
|
|
18787
|
+
return appendAndReturnNewShape(slide, pic);
|
|
18788
|
+
};
|
|
18789
|
+
/**
|
|
18790
|
+
* Returns the clip behind a media picture, or `null` when the shape is not
|
|
18791
|
+
* one. Reads PowerPoint-, PptxGenJS- and python-pptx-authored media alike: the
|
|
18792
|
+
* embedded part is taken from `<p14:media r:embed>` when present and from the
|
|
18793
|
+
* DrawingML `r:link` otherwise; a relationship with an external target is
|
|
18794
|
+
* reported as `'online'`.
|
|
18795
|
+
*/
|
|
18796
|
+
const getShapeMedia = (shape) => {
|
|
18797
|
+
if (shape[SHAPE_SNAPSHOT].kind !== "picture") return null;
|
|
18798
|
+
const ref = readPictureMediaRef(shape[SHAPE_ELEMENT]);
|
|
18799
|
+
if (ref === null) return null;
|
|
18800
|
+
const slide = shape[SHAPE_SLIDE];
|
|
18801
|
+
const pkg = slide[INTERNAL_PACKAGE];
|
|
18802
|
+
const rels = pkg.getRels(slide[SLIDE_PART_NAME]);
|
|
18803
|
+
if (rels === null) return null;
|
|
18804
|
+
const relsById = new Map(rels.items.map((r) => [r.id, r]));
|
|
18805
|
+
for (const rId of [ref.mediaRId, ref.fileRId]) {
|
|
18806
|
+
const rel = rId === null ? void 0 : relsById.get(rId);
|
|
18807
|
+
if (rel === void 0) continue;
|
|
18808
|
+
if (rel.targetMode === "External") return {
|
|
18809
|
+
kind: "online",
|
|
18810
|
+
url: rel.target
|
|
18811
|
+
};
|
|
18812
|
+
const name = rel.target.startsWith("/") ? partName(rel.target) : resolveTarget(slide[SLIDE_PART_NAME], rel.target);
|
|
18813
|
+
const part = pkg.getPart(name);
|
|
18814
|
+
if (part) return {
|
|
18815
|
+
kind: ref.kind,
|
|
18816
|
+
partName: part.name,
|
|
18817
|
+
contentType: part.contentType,
|
|
18818
|
+
bytes: part.data
|
|
18819
|
+
};
|
|
18820
|
+
}
|
|
18821
|
+
return null;
|
|
18822
|
+
};
|
|
18823
|
+
/** Every shape on the slide that `getShapeMedia` reports a clip for. */
|
|
18824
|
+
const findShapesWithMedia = (slide) => slide[SLIDE_SHAPES].filter((shape) => getShapeMedia(shape) !== null);
|
|
18825
|
+
//#endregion
|
|
17439
18826
|
//#region src/api/index.ts
|
|
17440
|
-
const VERSION = "0.
|
|
18827
|
+
const VERSION = "0.17.0";
|
|
17441
18828
|
//#endregion
|
|
17442
|
-
export { slideHasAnimations as $, getTableCellMargins as $a, clearSlideHyperlinks as $i, getShapeText as $n, getSlideLayouts as $o, getShapeRunCount as $r, getCommentAuthor as $s, getShapeStrokeColorResolved as $t, getPresentationTextLength as A, clearSlideTransition as Aa, getShapeImageContrast as Ai, findShapesAtPoint as An, setTableStyleFlags as Ao, setShapeSize as Ar, getSlideLayoutBackgroundImageBytes as As, setShapeTextBodyRotationDeg as At, getSlideText as B, listPackageParts as Ba, isShapeImageGrayscale as Bi, getShapeCenter as Bn, setCoreProperties as Bo, getParagraphAlignment as Br, setSlideBackgroundImage as Bs, getShapeEffectsEffective as Bt, findSlideByTitle as C, getSlidesWithOverlap as Ca, pt as Cc, findSlidesByLayoutName as Ci, getSlideLayout as Cn, setTableCellMargins as Co, setShapeGradientFill as Cr, getSlideBackground as Cs, getShapeTextWrap as Ct, getOutlineText as D, removeSlideNotes as Da, getShapeImageBiLevelThreshold as Di, setSlideLayout as Dn, setTableCellTextFormat as Do, setShapePatternFill as Dr, getSlideColorMapOverride as Ds, setShapeText as Dt, getAllShapes as E, hasSlideNotes as Ea, getPresentationImageCountsBySlide as Ei, replaceTokensInSlide as En, setTableCellTextDirection as Eo, setShapeNoStroke as Er, getSlideBackgroundPatternFill as Es, setShapeParagraphs as Et, getSlideIndex as F, getMediaParts as Fa, getShapeImageLinkUrl as Fi, getMaxShapeIdInPresentation as Fn, getCoreProperties as Fo, setShapeStrokeDash as Fr, getSlideMasterBackgroundGradientFill as Fs, setShapeTextWrap as Ft, isSlideHidden as G, clearTableCellFill as Ga, SLIDE_SIZE_16_10 as Gi, getShapeKind as Gn, findSlideLayoutByPartName as Go, getParagraphIndent as Gr, clearAllSlideComments as Gs, getShapeFill as Gt, getSlideXmlString as H, setMediaPartBytes as Ha, setShapeImageContrast as Hi, getShapeDescription as Hn, touchModified as Ho, getParagraphBulletImageBytes as Hr, setShapeClickAction as Hs, setShapeShadow as Ht, getSlideInfo as I, getOrphanMediaPartNames as Ia, getShapeImageOpacity as Ii, getShapeAdjustValues as In, getExtendedProperties as Io, setShapeStrokeJoin as Ir, getSlideMasterBackgroundImageBytes as Is, clearShapeEffects as It, replaceTextInSlide as J, getTableCell as Ja, getSlideSize as Ji, getShapePlaceholderType as Jn, getSlideLayoutPartName as Jo, getParagraphSpacing as Jr, findCommentsAfter as Js, getShapeFillEffective as Jt, replaceTextInNotes as K, getPresentationTableCountsBySlide as Ka, SLIDE_SIZE_16_9 as Ki, getShapeName as Kn, findSlideLayoutByType as Ko, getParagraphLevel as Kr, clearSlideComments as Ks, getShapeFillColor as Kt, getSlideLayoutCount as L, getPackageSize as La, getShapeImagePartName as Li, getShapeAltTitle as Ln, getPresentationCreated as Lo, getShapeRunFormat as Lr, getSlideMasterBackgroundPatternFill as Ls, findShapesByEffect as Lt, getShapeAt as M, setSlideTransition as Ma, getShapeImageDuotone as Mi, getGroupChildren as Mn, getThumbnail as Mo, setShapeStrokeArrow as Mr, getSlideLayoutBackgroundShapes as Ms, setShapeTextDirection as Mt, getSlideAt as N, _internalPackageOf as Na, getShapeImageFillBytes as Ni, getGroupTransform as Nn, removeThumbnail as No, setShapeStrokeCap as Nr, getSlideLayoutShapes as Ns, setShapeTextFormat as Nt, getPresentationShapeCountsBySlide as O, replaceHyperlink as Oa, getShapeImageBrightness as Oi, translateShapes as On, setTableColumnWidth as Oo, setShapePosition as Or, getSlideLayoutBackground as Os, setShapeTextAnchor as Ot, getSlideCount as P, compactPackage as Pa, getShapeImageFormat as Pi, getMaxShapeId as Pn, setThumbnail as Po, setShapeStrokeCompound as Pr, getSlideMasterBackground as Ps, setShapeTextMargins as Pt, setSlideHidden as Q, getTableCellFill as Qa, clearAllSlideNotes as Qi, getShapeSize as Qn, getSlideLayoutUsageCountsByType as Qo, getShapeRunClickAction as Qr, findSlidesWithCommentsByAuthor as Qs, getShapeStrokeColor as Qt, getSlideOutline as R, getPresentationSummary as Ra, hasShapeImage as Ri, getShapeBounds as Rn, getPresentationModified as Ro, resolveDrawingColor as Rr, getSlideMasterShapes as Rs, getShapeEffect as Rt, findSlideByText as S, getSlidesWithNotes as Sa, mm as Sc, findShapesOutsideCanvas as Si, getShapesBounds as Sn, setTableCellFill as So, setShapeFlip as Sr, clearSlideBackground as Ss, getShapeTextMargins as St, findSlidesByText as T, getVisibleSlides as Ta, findSlidesByLayoutType as Ti, getSlidesWithEmptyPlaceholders as Tn, setTableCellText as To, setShapeNoFill as Tr, getSlideBackgroundImageBytes as Ts, setShapeBullets as Tt, getSlides as U, slidesUsingMediaPart as Ua, setShapeImageCrop as Ui, getShapeFlip as Un, findLayoutsWithPlaceholderType as Uo, getParagraphBulletStyle as Ur, setShapeImage as Us, getShapeGradientFill as Ut, getSlideTextLength as V, readPackagePart as Va, setShapeImageBrightness as Vi, getShapeCustomGeometry as Vn, setExtendedProperties as Vo, getParagraphBullet as Vr, getShapeClickAction as Vs, setShapeGlow as Vt, getSlidesByLayout as W, validatePresentation as Wa, setShapeImageOpacity as Wi, getShapeId as Wn, findSlideLayout as Wo, getParagraphEndFormat as Wr, addSlideComment as Ws, getShapeGradientFillEffective as Wt, replaceTokensInPresentation as X, getTableCellAnchor as Xa, appendSlideNotes as Xi, getShapePreset as Xn, getSlideLayoutType as Xo, getShapeParagraphCount as Xr, findCommentsByAuthor as Xs, getShapeStroke as Xt, replaceTextInSlideNotes as Y, getTableCellAlignment as Ya, setSlideSize as Yi, getShapePosition as Yn, getSlideLayoutPlaceholders as Yo, getShapeHyperlinkTooltip as Yr, findCommentsBefore as Ys, getShapeFillOpacity as Yt, searchSlides as Z, getTableCellBorders as Za, clearAllHyperlinks as Zi, getShapeRotation as Zn, getSlideLayoutUsageCounts as Zo, getShapeParagraphElements as Zr, findCommentsByText as Zs, getShapeStrokeCap as Zt, sortSlides as _, getSlideNotesLength as _a, loadPresentation as _c, findShapesWithAnimation as _i, findSlidePlaceholderByIdx as _n, removeTableColumn as _o, getShapePatternFill as _r, getShapeChartSpec as _s, getShapeTextAutoFit as _t, addContentSlide as a, getAllHyperlinks as aa, getCommentsSortedByDate as ac, setParagraphBullet as ai, findEmptyPlaceholders as an, getTableCells as ao, isShapeHidden as ar, setShapeRunFormat as as, bringShapeForward as at, setSlideSections as b, getSlidesWithHyperlinks as ba, emu as bc, findFlippedShapes as bi, getShapeSlide as bn, setTableCellAnchor as bo, setShapeAdjustValues as br, getEffectiveColorMap as bs, getShapeTextColumns as bt, addSlideAt as c, getAllTables as ca, getPresentationCommenters as cc, setParagraphSpacing as ci, findShapeByText as cn, getTableRowHeights as co, pointInShape as cr, findChartsBySeriesName as cs, copyShape as ct, duplicateSlideAt as d, getHiddenSlides as da, removeSlideComment as dc, getSlideBody as di, findShapesByKind as dn, getTableStyleId as do, setShapeBounds as dr, getPresentationChartCountsBySlide as ds, sendShapeBackward as dt, findSlidesByHyperlink as ea, getCommentAuthors as ec, getShapeRunHyperlink as ei, getShapeStrokeCompound as en, getTableCellParagraphs as eo, getSlideMasterCount as er, getUnusedSlideLayouts as es, addSlideImage as et, importSlide as f, getPresentationHyperlinkCountsBySlide as fa, getPresentationFonts as fc, getSlideTitle as fi, findShapesByName as fn, insertTableColumn as fo, setShapeDescription as fr, getPresentationChartKindCounts as fs, sendShapeToBack as ft, reverseSlides as g, getSlideNotes as ga, createPresentation as gc, clearSlideAnimations as gi, findSlidePlaceholder as gn, mergeTableCells as go, clearShapeStroke as gr, getShapeChartSeriesValues as gs, getShapeTextAnchor as gt, removeSlide as h, getPresentationNotesText as ha, setPresentationTheme as hc, setSlideTitle as hi, findShapesWithHyperlinks as hn, isTableShape as ho, clearShapeFill as hr, getShapeChartSeriesNames as hs, getShapeBodyPrEffective as ht, addBlankSlide as i, getAllComments as ia, getCommentText as ic, setParagraphAlignment as ii, getShapeStrokeWidth as in, getTableCellTextDirection as io, getUnusedSlideMasters as ir, setShapeHyperlink as is, addSlideTextBox as it, getPresentationTextLengthsBySlide as j, getSlideTransition as ja, getShapeImageCrop as ji, findShapesInRect as jn, setTableStyleId as jo, setShapeStroke as jr, getSlideLayoutBackgroundPatternFill as js, setShapeTextColumns as jt, getPresentationText as k, setSlideNotes as ka, getShapeImageBytes as ki, centerShapeOnSlide as kn, setTableRowHeight as ko, setShapeRotation as kr, getSlideLayoutBackgroundGradientFill as ks, setShapeTextAutoFit as kt, addTitleSlide as l, getDistinctHyperlinkUrls as la, getSlideCommentAuthors as lc, setShapeRunHyperlink as li, findShapeInPresentation as ln, getTableSize as lo, renameShape as lr, findChartsWithDataLabels as ls, getShapeZIndex as lt, moveSlide as m, getPresentationNotesLengthsBySlide as ma, setPresentationFonts as mc, setSlidePlaceholders as mi, findShapesByText as mn, isChartShape as mo, shapesOverlap as mr, getShapeChartKind as ms, appendShapeText as mt, groupShapes as n, findSlidesWithChartTrendlines as na, getCommentPosition as nc, getShapeRunText as ni, getShapeStrokeJoin as nn, getTableCellSpan as no, getSlideMasterPartNames as nr, getShapeHyperlink as ns, addSlideShape as nt, addSectionHeaderSlide as o, getAllImages as oa, getPresentationCommentCountsByAuthor as oc, setParagraphLevel as oi, findShapeById as on, getTableColumnWidths as oo, isShapePlaceholder as or, addSlideChart as os, bringShapeToFront as ot, mergePresentations as p, getPresentationNotesLength as pa, getPresentationTheme as pc, setSlideBody as pi, findShapesByPreset as pn, insertTableRow as po, setShapeHidden as pr, getShapeChartCategories as ps, setShapeZIndex as pt, replaceTextInPresentation as q, getSlideTables as qa, SLIDE_SIZE_4_3 as qi, getShapePlaceholderIdx as qn, getSlideLayoutName as qo, getParagraphLineSpacing as qr, findCommentAuthorByName as qs, getShapeFillColorResolved as qt, ungroupShapes as r, getAllCharts as ra, getCommentSlide as rc, isParagraphBulletPicture as ri, getShapeStrokeOpacity as rn, getTableCellText as ro, getSlideMasterUsageCounts as rr, getShapeRunFormatEffective as rs, addSlideTable as rt, addSlide as s, getAllNotes as sa, getPresentationCommentCountsBySlide as sc, setParagraphLineSpacing as si, findShapeByName as sn, getTableDimensions as so, isShapeTextBox as sr, findChartByKind as ss, clearSlideShapes as st, VERSION as t, findSlidesWithChartKind as ta, getCommentDate as tc, getShapeRunHyperlinkTooltip as ti, getShapeStrokeEffective as tn, getTableCellPosition as to, getSlideMasterPartName as tr, getParagraphPropertiesEffective as ts, addSlideLine as tt, duplicateSlide as u, getEmptySlides as ua, getSlideComments as uc, setShapeRunText as ui, findShapesByHyperlink as un, getTableStyleFlags as uo, setShapeAltTitle as ur, findChartsWithTrendlines as us, removeShape as ut, swapSlides as v, getSlidesWithCharts as va, savePresentation as vc, getShapeAnimation as vi, findSlidePlaceholders as vn, removeTableRow as vo, getShapeStrokeArrow as vr, getSlideCharts as vs, getShapeTextAutoFitParams as vt, findSlidesByNotes as w, getSlidesWithTables as wa, findSlidesByLayoutPartName as wi, getSlideShapes as wn, setTableCellParagraphs as wo, setShapeImageFill as wr, getSlideBackgroundGradientFill as ws, setShapeAlignment as wt, findSlideByPartName as x, getSlidesWithImages as xa, inches as xc, findOverlappingShapePairs as xi, getShapeXmlString as xn, setTableCellBorders as xo, setShapeFill as xr, resolveDeckBodyTextColor as xs, getShapeTextDirection as xt, getSlideSections as y, getSlidesWithComments as ya, cm as yc, setShapeAnimation as yi, getShapeIndex as yn, setTableCellAlignment as yo, getShapeStrokeDash as yr, setChartSpec as ys, getShapeTextBodyRotationDeg as yt, getSlidePartName as z, getSlideMediaPartNames as za, hasShapeText as zi, getShapeBoundsResolved as zn, incrementRevision as zo, resolveDrawingColorOpacity as zr, setSlideBackground as zs, getShapeEffects as zt };
|
|
18829
|
+
export { replaceTokensInPresentation as $, getTableCellAnchor as $a, appendSlideNotes as $i, getShapePreset as $n, getSlideLayoutType as $o, getShapeParagraphCount as $r, findCommentsByAuthor as $s, getShapeStroke as $t, getOutlineText as A, removeSlideNotes as Aa, getShapeImageBiLevelThreshold as Ai, setSlideLayout as An, setTableCellTextFormat as Ao, setShapePatternFill as Ar, getSlideColorMapOverride as As, setShapeText as At, getSlideLayoutCount as B, getPackageSize as Ba, getShapeImagePartName as Bi, getShapeAltTitle as Bn, getPresentationCreated as Bo, getShapeRunFormat as Br, getSlideMasterBackgroundPatternFill as Bs, findShapesByEffect as Bt, setSlideSections as C, getSlidesWithHyperlinks as Ca, emu as Cc, findFlippedShapes as Ci, getShapeSlide as Cn, setTableCellAnchor as Co, setShapeAdjustValues as Cr, getEffectiveColorMap as Cs, getShapeTextColumns as Ct, findSlidesByNotes as D, getSlidesWithTables as Da, findSlidesByLayoutPartName as Di, getSlideShapes as Dn, setTableCellParagraphs as Do, setShapeImageFill as Dr, getSlideBackgroundGradientFill as Ds, setShapeAlignment as Dt, findSlideByTitle as E, getSlidesWithOverlap as Ea, pt as Ec, findSlidesByLayoutName as Ei, getSlideLayout as En, setTableCellMargins as Eo, setShapeGradientFill as Er, getSlideBackground as Es, getShapeTextWrap as Et, getShapeAt as F, setSlideTransition as Fa, getShapeImageDuotone as Fi, getGroupChildren as Fn, getThumbnail as Fo, setShapeStrokeArrow as Fr, getSlideLayoutBackgroundShapes as Fs, setShapeTextDirection as Ft, getSlideXmlString as G, setMediaPartBytes as Ga, setShapeImageContrast as Gi, getShapeDescription as Gn, touchModified as Go, getParagraphBulletImageBytes as Gr, setShapeClickAction as Gs, setShapeShadow as Gt, getSlidePartName as H, getSlideMediaPartNames as Ha, hasShapeText as Hi, getShapeBoundsResolved as Hn, incrementRevision as Ho, resolveDrawingColorOpacity as Hr, setSlideBackground as Hs, getShapeEffects as Ht, getSlideAt as I, _internalPackageOf as Ia, getShapeImageFillBytes as Ii, getGroupTransform as In, removeThumbnail as Io, setShapeStrokeCap as Ir, getSlideLayoutShapes as Is, setShapeTextFormat as It, isSlideHidden as J, clearTableCellFill as Ja, SLIDE_SIZE_16_10 as Ji, getShapeKind as Jn, findSlideLayoutByPartName as Jo, getParagraphIndent as Jr, clearAllSlideComments as Js, getShapeFill as Jt, getSlides as K, slidesUsingMediaPart as Ka, setShapeImageCrop as Ki, getShapeFlip as Kn, findLayoutsWithPlaceholderType as Ko, getParagraphBulletStyle as Kr, setShapeImage as Ks, getShapeGradientFill as Kt, getSlideCount as L, compactPackage as La, getShapeImageFormat as Li, getMaxShapeId as Ln, setThumbnail as Lo, setShapeStrokeCompound as Lr, getSlideMasterBackground as Ls, setShapeTextMargins as Lt, getPresentationText as M, setSlideNotes as Ma, getShapeImageBytes as Mi, centerShapeOnSlide as Mn, setTableRowHeight as Mo, setShapeRotation as Mr, getSlideLayoutBackgroundGradientFill as Ms, setShapeTextAutoFit as Mt, getPresentationTextLength as N, clearSlideTransition as Na, getShapeImageContrast as Ni, findShapesAtPoint as Nn, setTableStyleFlags as No, setShapeSize as Nr, getSlideLayoutBackgroundImageBytes as Ns, setShapeTextBodyRotationDeg as Nt, findSlidesByText as O, getVisibleSlides as Oa, findSlidesByLayoutType as Oi, getSlidesWithEmptyPlaceholders as On, setTableCellText as Oo, setShapeNoFill as Or, getSlideBackgroundImageBytes as Os, setShapeBullets as Ot, getPresentationTextLengthsBySlide as P, getSlideTransition as Pa, getShapeImageCrop as Pi, findShapesInRect as Pn, setTableStyleId as Po, setShapeStroke as Pr, getSlideLayoutBackgroundPatternFill as Ps, setShapeTextColumns as Pt, replaceTextInSlideNotes as Q, getTableCellAlignment as Qa, setSlideSize as Qi, getShapePosition as Qn, getSlideLayoutPlaceholders as Qo, getShapeHyperlinkTooltip as Qr, findCommentsBefore as Qs, getShapeFillOpacity as Qt, getSlideIndex as R, getMediaParts as Ra, getShapeImageLinkUrl as Ri, getMaxShapeIdInPresentation as Rn, getCoreProperties as Ro, setShapeStrokeDash as Rr, getSlideMasterBackgroundGradientFill as Rs, setShapeTextWrap as Rt, getSlideSections as S, getSlidesWithComments as Sa, cm as Sc, setShapeAnimation as Si, getShapeIndex as Sn, setTableCellAlignment as So, getShapeStrokeDash as Sr, setChartSpec as Ss, getShapeTextBodyRotationDeg as St, findSlideByText as T, getSlidesWithNotes as Ta, mm as Tc, findShapesOutsideCanvas as Ti, getShapesBounds as Tn, setTableCellFill as To, setShapeFlip as Tr, clearSlideBackground as Ts, getShapeTextMargins as Tt, getSlideText as U, listPackageParts as Ua, isShapeImageGrayscale as Ui, getShapeCenter as Un, setCoreProperties as Uo, getParagraphAlignment as Ur, setSlideBackgroundImage as Us, getShapeEffectsEffective as Ut, getSlideOutline as V, getPresentationSummary as Va, hasShapeImage as Vi, getShapeBounds as Vn, getPresentationModified as Vo, resolveDrawingColor as Vr, getSlideMasterShapes as Vs, getShapeEffect as Vt, getSlideTextLength as W, readPackagePart as Wa, setShapeImageBrightness as Wi, getShapeCustomGeometry as Wn, setExtendedProperties as Wo, getParagraphBullet as Wr, getShapeClickAction as Ws, setShapeGlow as Wt, replaceTextInPresentation as X, getSlideTables as Xa, SLIDE_SIZE_4_3 as Xi, getShapePlaceholderIdx as Xn, getSlideLayoutName as Xo, getParagraphLineSpacing as Xr, findCommentAuthorByName as Xs, getShapeFillColorResolved as Xt, replaceTextInNotes as Y, getPresentationTableCountsBySlide as Ya, SLIDE_SIZE_16_9 as Yi, getShapeName as Yn, findSlideLayoutByType as Yo, getParagraphLevel as Yr, clearSlideComments as Ys, getShapeFillColor as Yt, replaceTextInSlide as Z, getTableCell as Za, getSlideSize as Zi, getShapePlaceholderType as Zn, getSlideLayoutPartName as Zo, getParagraphSpacing as Zr, findCommentsAfter as Zs, getShapeFillEffective as Zt, moveSlide as _, getPresentationNotesLengthsBySlide as _a, setPresentationFonts as _c, setSlidePlaceholders as _i, findShapesByText as _n, isChartShape as _o, shapesOverlap as _r, getShapeChartKind as _s, appendShapeText as _t, groupShapes as a, findSlidesWithChartTrendlines as aa, getCommentPosition as ac, getShapeRunText as ai, getShapeStrokeJoin as an, getTableCellSpan as ao, getSlideMasterPartNames as ar, getShapeHyperlink as as, addSlideShape as at, sortSlides as b, getSlideNotesLength as ba, loadPresentation as bc, findShapesWithAnimation as bi, findSlidePlaceholderByIdx as bn, removeTableColumn as bo, getShapePatternFill as br, getShapeChartSpec as bs, getShapeTextAutoFit as bt, addContentSlide as c, getAllHyperlinks as ca, getCommentsSortedByDate as cc, setParagraphBullet as ci, findEmptyPlaceholders as cn, getTableCells as co, isShapeHidden as cr, setShapeRunFormat as cs, bringShapeForward as ct, addSlideAt as d, getAllTables as da, getPresentationCommenters as dc, setParagraphSpacing as di, findShapeByText as dn, getTableRowHeights as do, pointInShape as dr, findChartsBySeriesName as ds, copyShape as dt, clearAllHyperlinks as ea, findCommentsByText as ec, getShapeParagraphElements as ei, getShapeStrokeCap as en, getTableCellBorders as eo, getShapeRotation as er, getSlideLayoutUsageCounts as es, searchSlides as et, addTitleSlide as f, getDistinctHyperlinkUrls as fa, getSlideCommentAuthors as fc, setShapeRunHyperlink as fi, findShapeInPresentation as fn, getTableSize as fo, renameShape as fr, findChartsWithDataLabels as fs, getShapeZIndex as ft, mergePresentations as g, getPresentationNotesLength as ga, getPresentationTheme as gc, setSlideBody as gi, findShapesByPreset as gn, insertTableRow as go, setShapeHidden as gr, getShapeChartCategories as gs, setShapeZIndex as gt, importSlide as h, getPresentationHyperlinkCountsBySlide as ha, getPresentationFonts as hc, getSlideTitle as hi, findShapesByName as hn, insertTableColumn as ho, setShapeDescription as hr, getPresentationChartKindCounts as hs, sendShapeToBack as ht, getShapeMedia as i, findSlidesWithChartKind as ia, getCommentDate as ic, getShapeRunHyperlinkTooltip as ii, getShapeStrokeEffective as in, getTableCellPosition as io, getSlideMasterPartName as ir, getParagraphPropertiesEffective as is, addSlideLine as it, getPresentationShapeCountsBySlide as j, replaceHyperlink as ja, getShapeImageBrightness as ji, translateShapes as jn, setTableColumnWidth as jo, setShapePosition as jr, getSlideLayoutBackground as js, setShapeTextAnchor as jt, getAllShapes as k, hasSlideNotes as ka, getPresentationImageCountsBySlide as ki, replaceTokensInSlide as kn, setTableCellTextDirection as ko, setShapeNoStroke as kr, getSlideBackgroundPatternFill as ks, setShapeParagraphs as kt, addSectionHeaderSlide as l, getAllImages as la, getPresentationCommentCountsByAuthor as lc, setParagraphLevel as li, findShapeById as ln, getTableColumnWidths as lo, isShapePlaceholder as lr, addSlideChart as ls, bringShapeToFront as lt, duplicateSlideAt as m, getHiddenSlides as ma, removeSlideComment as mc, getSlideBody as mi, findShapesByKind as mn, getTableStyleId as mo, setShapeBounds as mr, getPresentationChartCountsBySlide as ms, sendShapeBackward as mt, addSlideMedia as n, clearSlideHyperlinks as na, getCommentAuthor as nc, getShapeRunCount as ni, getShapeStrokeColorResolved as nn, getTableCellMargins as no, getShapeText as nr, getSlideLayouts as ns, slideHasAnimations as nt, ungroupShapes as o, getAllCharts as oa, getCommentSlide as oc, isParagraphBulletPicture as oi, getShapeStrokeOpacity as on, getTableCellText as oo, getSlideMasterUsageCounts as or, getShapeRunFormatEffective as os, addSlideTable as ot, duplicateSlide as p, getEmptySlides as pa, getSlideComments as pc, setShapeRunText as pi, findShapesByHyperlink as pn, getTableStyleFlags as po, setShapeAltTitle as pr, findChartsWithTrendlines as ps, removeShape as pt, getSlidesByLayout as q, validatePresentation as qa, setShapeImageOpacity as qi, getShapeId as qn, findSlideLayout as qo, getParagraphEndFormat as qr, addSlideComment as qs, getShapeGradientFillEffective as qt, findShapesWithMedia as r, findSlidesByHyperlink as ra, getCommentAuthors as rc, getShapeRunHyperlink as ri, getShapeStrokeCompound as rn, getTableCellParagraphs as ro, getSlideMasterCount as rr, getUnusedSlideLayouts as rs, addSlideImage as rt, addBlankSlide as s, getAllComments as sa, getCommentText as sc, setParagraphAlignment as si, getShapeStrokeWidth as sn, getTableCellTextDirection as so, getUnusedSlideMasters as sr, setShapeHyperlink as ss, addSlideTextBox as st, VERSION as t, clearAllSlideNotes as ta, findSlidesWithCommentsByAuthor as tc, getShapeRunClickAction as ti, getShapeStrokeColor as tn, getTableCellFill as to, getShapeSize as tr, getSlideLayoutUsageCountsByType as ts, setSlideHidden as tt, addSlide as u, getAllNotes as ua, getPresentationCommentCountsBySlide as uc, setParagraphLineSpacing as ui, findShapeByName as un, getTableDimensions as uo, isShapeTextBox as ur, findChartByKind as us, clearSlideShapes as ut, removeSlide as v, getPresentationNotesText as va, setPresentationTheme as vc, setSlideTitle as vi, findShapesWithHyperlinks as vn, isTableShape as vo, clearShapeFill as vr, getShapeChartSeriesNames as vs, getShapeBodyPrEffective as vt, findSlideByPartName as w, getSlidesWithImages as wa, inches as wc, findOverlappingShapePairs as wi, getShapeXmlString as wn, setTableCellBorders as wo, setShapeFill as wr, resolveDeckBodyTextColor as ws, getShapeTextDirection as wt, swapSlides as x, getSlidesWithCharts as xa, savePresentation as xc, getShapeAnimation as xi, findSlidePlaceholders as xn, removeTableRow as xo, getShapeStrokeArrow as xr, getSlideCharts as xs, getShapeTextAutoFitParams as xt, reverseSlides as y, getSlideNotes as ya, createPresentation as yc, clearSlideAnimations as yi, findSlidePlaceholder as yn, mergeTableCells as yo, clearShapeStroke as yr, getShapeChartSeriesValues as ys, getShapeTextAnchor as yt, getSlideInfo as z, getOrphanMediaPartNames as za, getShapeImageOpacity as zi, getShapeAdjustValues as zn, getExtendedProperties as zo, setShapeStrokeJoin as zr, getSlideMasterBackgroundImageBytes as zs, clearShapeEffects as zt };
|
|
17443
18830
|
|
|
17444
|
-
//# sourceMappingURL=api-
|
|
18831
|
+
//# sourceMappingURL=api-DTHZaBPq.js.map
|