docgen-utils 1.0.13 → 1.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle.js +994 -38
- package/dist/bundle.min.js +94 -89
- package/dist/cli.js +24908 -119
- package/dist/packages/cli/commands/common.d.ts +2 -0
- package/dist/packages/cli/commands/common.d.ts.map +1 -0
- package/dist/packages/cli/commands/common.js +22 -0
- package/dist/packages/cli/commands/common.js.map +1 -0
- package/dist/packages/cli/commands/export-docs.d.ts +10 -1
- package/dist/packages/cli/commands/export-docs.d.ts.map +1 -1
- package/dist/packages/cli/commands/export-docs.js +258 -44
- package/dist/packages/cli/commands/export-docs.js.map +1 -1
- package/dist/packages/cli/commands/export-slides.d.ts +1 -1
- package/dist/packages/cli/commands/export-slides.d.ts.map +1 -1
- package/dist/packages/cli/commands/export-slides.js +58 -25
- package/dist/packages/cli/commands/export-slides.js.map +1 -1
- package/dist/packages/cli/commands/import-docx.d.ts +1 -1
- package/dist/packages/cli/commands/import-docx.d.ts.map +1 -1
- package/dist/packages/cli/commands/import-docx.js +3 -3
- package/dist/packages/cli/commands/import-docx.js.map +1 -1
- package/dist/packages/cli/commands/import-pptx.d.ts +1 -1
- package/dist/packages/cli/commands/import-pptx.d.ts.map +1 -1
- package/dist/packages/cli/commands/import-pptx.js +2 -2
- package/dist/packages/cli/commands/import-pptx.js.map +1 -1
- package/dist/packages/cli/index.js +14 -8
- package/dist/packages/cli/index.js.map +1 -1
- package/dist/packages/docs/parse-helpers.d.ts.map +1 -1
- package/dist/packages/docs/parse-helpers.js +7 -1
- package/dist/packages/docs/parse-helpers.js.map +1 -1
- package/dist/packages/slides/createPresentation.d.ts.map +1 -1
- package/dist/packages/slides/createPresentation.js +20 -0
- package/dist/packages/slides/createPresentation.js.map +1 -1
- package/dist/packages/slides/import-pptx.d.ts.map +1 -1
- package/dist/packages/slides/import-pptx.js +1180 -47
- package/dist/packages/slides/import-pptx.js.map +1 -1
- package/dist/packages/slides/transform.d.ts.map +1 -1
- package/dist/packages/slides/transform.js +45 -0
- package/dist/packages/slides/transform.js.map +1 -1
- package/package.json +3 -2
package/dist/bundle.js
CHANGED
|
@@ -48969,7 +48969,9 @@ var docgen = (() => {
|
|
|
48969
48969
|
}
|
|
48970
48970
|
const cssBorder = styles.border || "";
|
|
48971
48971
|
const hasCssBorder = cssBorder.includes("solid") || cssBorder.includes("px");
|
|
48972
|
-
const
|
|
48972
|
+
const bgColor = styles.backgroundColor?.toLowerCase() || "";
|
|
48973
|
+
const isWhiteBackground = bgColor === "#ffffff" || bgColor === "#fff" || bgColor === "white" || bgColor === "rgb(255, 255, 255)" || bgColor === "rgba(255, 255, 255, 1)";
|
|
48974
|
+
const hasBackground = !!styles.backgroundColor && styles.backgroundColor !== "transparent" && styles.backgroundColor !== "inherit" && !isWhiteBackground;
|
|
48973
48975
|
if (hasBackground && (hasBorderLeft || hasCssBorder)) {
|
|
48974
48976
|
return true;
|
|
48975
48977
|
}
|
|
@@ -67530,6 +67532,23 @@ ${generateStylesCss(styleMap, themeFonts)}
|
|
|
67530
67532
|
// 3s timeout for slow CDN
|
|
67531
67533
|
]);
|
|
67532
67534
|
}
|
|
67535
|
+
const images = doc.querySelectorAll("img");
|
|
67536
|
+
if (images.length > 0) {
|
|
67537
|
+
const imagePromises = Array.from(images).map((img) => {
|
|
67538
|
+
if (img.complete && img.naturalWidth > 0) {
|
|
67539
|
+
return Promise.resolve();
|
|
67540
|
+
}
|
|
67541
|
+
return new Promise((resolve) => {
|
|
67542
|
+
img.onload = () => resolve();
|
|
67543
|
+
img.onerror = () => resolve();
|
|
67544
|
+
});
|
|
67545
|
+
});
|
|
67546
|
+
await Promise.race([
|
|
67547
|
+
Promise.all(imagePromises),
|
|
67548
|
+
new Promise((r) => setTimeout(r, 5e3))
|
|
67549
|
+
// 5s timeout for slow images
|
|
67550
|
+
]);
|
|
67551
|
+
}
|
|
67533
67552
|
return { iframe, doc };
|
|
67534
67553
|
}
|
|
67535
67554
|
async function addSlideFromHtml(source, pres, options = {}) {
|
|
@@ -67737,6 +67756,32 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
67737
67756
|
html = html.replace(/<\/style>/i, `body { width: ${targetWidth}pt; height: ${targetHeight}pt; overflow: hidden; margin: 0; }
|
|
67738
67757
|
</style>`);
|
|
67739
67758
|
}
|
|
67759
|
+
const maskImagePattern = /mask-image|--webkit-mask-image/i;
|
|
67760
|
+
const cssRules = html.match(/<style[^>]*>([\s\S]*?)<\/style>/gi) || [];
|
|
67761
|
+
const classesWithMask = /* @__PURE__ */ new Set();
|
|
67762
|
+
for (const styleBlock of cssRules) {
|
|
67763
|
+
const classMatches = styleBlock.matchAll(/\.([a-zA-Z_][\w-]*)\s*\{[^}]*mask-image[^}]*\}/gi);
|
|
67764
|
+
for (const m of classMatches) {
|
|
67765
|
+
classesWithMask.add(m[1]);
|
|
67766
|
+
}
|
|
67767
|
+
}
|
|
67768
|
+
html = html.replace(/<img\s+([^>]*?)src="(https?:\/\/[^"]+)"([^>]*)>/gi, (match, before2, url, after2) => {
|
|
67769
|
+
if (/crossorigin\s*=/i.test(before2 + after2)) {
|
|
67770
|
+
return match;
|
|
67771
|
+
}
|
|
67772
|
+
const fullAttrs = before2 + after2;
|
|
67773
|
+
const hasInlineMask = maskImagePattern.test(fullAttrs);
|
|
67774
|
+
let hasClassMask = false;
|
|
67775
|
+
const classMatch = fullAttrs.match(/class\s*=\s*["']([^"']+)["']/i);
|
|
67776
|
+
if (classMatch) {
|
|
67777
|
+
const classes = classMatch[1].split(/\s+/);
|
|
67778
|
+
hasClassMask = classes.some((c) => classesWithMask.has(c));
|
|
67779
|
+
}
|
|
67780
|
+
if (hasInlineMask || hasClassMask) {
|
|
67781
|
+
return `<img ${before2}src="${url}"${after2} crossorigin="anonymous">`;
|
|
67782
|
+
}
|
|
67783
|
+
return match;
|
|
67784
|
+
});
|
|
67740
67785
|
return html;
|
|
67741
67786
|
}
|
|
67742
67787
|
|
|
@@ -67802,28 +67847,62 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
67802
67847
|
const a = Math.round(alpha100k / 1e5 * 100) / 100;
|
|
67803
67848
|
return `rgba(${r},${g},${b},${a})`;
|
|
67804
67849
|
}
|
|
67850
|
+
function applyTint(hex, tintVal) {
|
|
67851
|
+
const factor = tintVal / 1e5;
|
|
67852
|
+
const r = parseInt(hex.slice(1, 3), 16);
|
|
67853
|
+
const g = parseInt(hex.slice(3, 5), 16);
|
|
67854
|
+
const b = parseInt(hex.slice(5, 7), 16);
|
|
67855
|
+
const nr = Math.round(r + (255 - r) * (1 - factor));
|
|
67856
|
+
const ng = Math.round(g + (255 - g) * (1 - factor));
|
|
67857
|
+
const nb = Math.round(b + (255 - b) * (1 - factor));
|
|
67858
|
+
return `#${nr.toString(16).padStart(2, "0")}${ng.toString(16).padStart(2, "0")}${nb.toString(16).padStart(2, "0")}`;
|
|
67859
|
+
}
|
|
67860
|
+
function applyShade(hex, shadeVal) {
|
|
67861
|
+
const factor = shadeVal / 1e5;
|
|
67862
|
+
const r = Math.round(parseInt(hex.slice(1, 3), 16) * factor);
|
|
67863
|
+
const g = Math.round(parseInt(hex.slice(3, 5), 16) * factor);
|
|
67864
|
+
const b = Math.round(parseInt(hex.slice(5, 7), 16) * factor);
|
|
67865
|
+
return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
|
67866
|
+
}
|
|
67867
|
+
function applyColorModifiers(colorEl, hex) {
|
|
67868
|
+
let color = hex;
|
|
67869
|
+
let alphaVal;
|
|
67870
|
+
const tintEl = findChild2(colorEl, "tint");
|
|
67871
|
+
if (tintEl) {
|
|
67872
|
+
const val = parseInt(tintEl.getAttribute("val") ?? "100000", 10);
|
|
67873
|
+
color = applyTint(color, val);
|
|
67874
|
+
}
|
|
67875
|
+
const shadeEl = findChild2(colorEl, "shade");
|
|
67876
|
+
if (shadeEl) {
|
|
67877
|
+
const val = parseInt(shadeEl.getAttribute("val") ?? "100000", 10);
|
|
67878
|
+
color = applyShade(color, val);
|
|
67879
|
+
}
|
|
67880
|
+
const alphaEl = findChild2(colorEl, "alpha");
|
|
67881
|
+
if (alphaEl) {
|
|
67882
|
+
alphaVal = parseInt(alphaEl.getAttribute("val") ?? "100000", 10);
|
|
67883
|
+
}
|
|
67884
|
+
return { color, alpha: alphaVal };
|
|
67885
|
+
}
|
|
67805
67886
|
function resolveColor2(parent, themeColors) {
|
|
67806
67887
|
const srgbClr = findChild2(parent, "srgbClr");
|
|
67807
67888
|
if (srgbClr) {
|
|
67808
67889
|
const hex = "#" + (srgbClr.getAttribute("val") ?? "000000");
|
|
67809
|
-
const
|
|
67810
|
-
if (
|
|
67811
|
-
|
|
67812
|
-
return hexToRgba(hex, alphaVal);
|
|
67890
|
+
const { color, alpha } = applyColorModifiers(srgbClr, hex);
|
|
67891
|
+
if (alpha !== void 0 && alpha < 1e5) {
|
|
67892
|
+
return hexToRgba(color, alpha);
|
|
67813
67893
|
}
|
|
67814
|
-
return
|
|
67894
|
+
return color;
|
|
67815
67895
|
}
|
|
67816
67896
|
const schemeClr = findChild2(parent, "schemeClr");
|
|
67817
67897
|
if (schemeClr) {
|
|
67818
67898
|
const val = schemeClr.getAttribute("val");
|
|
67819
67899
|
if (val && themeColors.has(val)) {
|
|
67820
67900
|
const hex = themeColors.get(val);
|
|
67821
|
-
const
|
|
67822
|
-
if (
|
|
67823
|
-
|
|
67824
|
-
return hexToRgba(hex, alphaVal);
|
|
67901
|
+
const { color, alpha } = applyColorModifiers(schemeClr, hex);
|
|
67902
|
+
if (alpha !== void 0 && alpha < 1e5) {
|
|
67903
|
+
return hexToRgba(color, alpha);
|
|
67825
67904
|
}
|
|
67826
|
-
return
|
|
67905
|
+
return color;
|
|
67827
67906
|
}
|
|
67828
67907
|
}
|
|
67829
67908
|
return void 0;
|
|
@@ -67874,6 +67953,158 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
67874
67953
|
return resolveColor2(solidFill, themeColors);
|
|
67875
67954
|
return extractGradientFill(spPr, themeColors);
|
|
67876
67955
|
}
|
|
67956
|
+
function resolveBgRef(bgRef, bgFillStyles, themeColors) {
|
|
67957
|
+
const idx = parseInt(bgRef.getAttribute("idx") ?? "0", 10);
|
|
67958
|
+
if (idx < 1001 || bgFillStyles.length === 0)
|
|
67959
|
+
return void 0;
|
|
67960
|
+
const styleIdx = idx - 1001;
|
|
67961
|
+
if (styleIdx >= bgFillStyles.length)
|
|
67962
|
+
return void 0;
|
|
67963
|
+
const fillStyle = bgFillStyles[styleIdx];
|
|
67964
|
+
const phColor = resolveColor2(bgRef, themeColors);
|
|
67965
|
+
if (fillStyle.localName === "solidFill") {
|
|
67966
|
+
const phClr = findChild2(fillStyle, "schemeClr");
|
|
67967
|
+
if (phClr?.getAttribute("val") === "phClr" && phColor) {
|
|
67968
|
+
return phColor;
|
|
67969
|
+
}
|
|
67970
|
+
return resolveColor2(fillStyle, themeColors) ?? phColor;
|
|
67971
|
+
}
|
|
67972
|
+
if (fillStyle.localName === "gradFill") {
|
|
67973
|
+
return extractGradientFill(
|
|
67974
|
+
// Wrap in a parent element for extractGradientFill
|
|
67975
|
+
{ children: [fillStyle] },
|
|
67976
|
+
themeColors
|
|
67977
|
+
);
|
|
67978
|
+
}
|
|
67979
|
+
return phColor;
|
|
67980
|
+
}
|
|
67981
|
+
function extractBgFill(bgEl, bgFillStyles, themeColors) {
|
|
67982
|
+
const bgPr = findChild2(bgEl, "bgPr");
|
|
67983
|
+
if (bgPr) {
|
|
67984
|
+
return extractFill(bgPr, themeColors);
|
|
67985
|
+
}
|
|
67986
|
+
const bgRef = findChild2(bgEl, "bgRef");
|
|
67987
|
+
if (bgRef) {
|
|
67988
|
+
return resolveBgRef(bgRef, bgFillStyles, themeColors);
|
|
67989
|
+
}
|
|
67990
|
+
return void 0;
|
|
67991
|
+
}
|
|
67992
|
+
function extractCustGeomClipPath(custGeom) {
|
|
67993
|
+
const pathLst = findChild2(custGeom, "pathLst");
|
|
67994
|
+
if (!pathLst)
|
|
67995
|
+
return void 0;
|
|
67996
|
+
const pathEl = findChild2(pathLst, "path");
|
|
67997
|
+
if (!pathEl)
|
|
67998
|
+
return void 0;
|
|
67999
|
+
const pathW = parseInt(pathEl.getAttribute("w") ?? "0", 10);
|
|
68000
|
+
const pathH = parseInt(pathEl.getAttribute("h") ?? "0", 10);
|
|
68001
|
+
if (pathW <= 0 || pathH <= 0)
|
|
68002
|
+
return void 0;
|
|
68003
|
+
const points = [];
|
|
68004
|
+
for (let i = 0; i < pathEl.children.length; i++) {
|
|
68005
|
+
const cmd = pathEl.children[i];
|
|
68006
|
+
const localName = cmd.localName;
|
|
68007
|
+
if (localName === "moveTo" || localName === "lnTo") {
|
|
68008
|
+
const pt = findChild2(cmd, "pt");
|
|
68009
|
+
if (pt) {
|
|
68010
|
+
const x = parseInt(pt.getAttribute("x") ?? "0", 10);
|
|
68011
|
+
const y = parseInt(pt.getAttribute("y") ?? "0", 10);
|
|
68012
|
+
points.push({ x, y });
|
|
68013
|
+
}
|
|
68014
|
+
} else if (localName === "close") {
|
|
68015
|
+
} else {
|
|
68016
|
+
return void 0;
|
|
68017
|
+
}
|
|
68018
|
+
}
|
|
68019
|
+
if (points.length < 3)
|
|
68020
|
+
return void 0;
|
|
68021
|
+
const polygonPoints = points.map((p) => {
|
|
68022
|
+
const xPct = Math.round(p.x / pathW * 1e4) / 100;
|
|
68023
|
+
const yPct = Math.round(p.y / pathH * 1e4) / 100;
|
|
68024
|
+
return `${xPct}% ${yPct}%`;
|
|
68025
|
+
}).join(", ");
|
|
68026
|
+
return `polygon(${polygonPoints})`;
|
|
68027
|
+
}
|
|
68028
|
+
function parseDecorativeShapes(spTree, scale, themeColors, imageMap, themeFonts) {
|
|
68029
|
+
const elements = [];
|
|
68030
|
+
for (let i = 0; i < spTree.children.length; i++) {
|
|
68031
|
+
const child = spTree.children[i];
|
|
68032
|
+
if (child.localName === "sp") {
|
|
68033
|
+
const nvSpPr = findChild2(child, "nvSpPr");
|
|
68034
|
+
if (nvSpPr) {
|
|
68035
|
+
const phEl = findChild2(findChild2(nvSpPr, "nvPr") ?? nvSpPr, "ph");
|
|
68036
|
+
if (phEl)
|
|
68037
|
+
continue;
|
|
68038
|
+
}
|
|
68039
|
+
const spPr = findChild2(child, "spPr");
|
|
68040
|
+
if (spPr) {
|
|
68041
|
+
const custGeom = findChild2(spPr, "custGeom");
|
|
68042
|
+
if (custGeom) {
|
|
68043
|
+
const clipPath = extractCustGeomClipPath(custGeom);
|
|
68044
|
+
if (!clipPath)
|
|
68045
|
+
continue;
|
|
68046
|
+
const shape2 = parseShape(child, scale, themeColors, themeFonts);
|
|
68047
|
+
if (shape2) {
|
|
68048
|
+
shape2.clipPath = clipPath;
|
|
68049
|
+
elements.push({ kind: "shape", data: shape2 });
|
|
68050
|
+
}
|
|
68051
|
+
continue;
|
|
68052
|
+
}
|
|
68053
|
+
}
|
|
68054
|
+
const shape = parseShape(child, scale, themeColors, themeFonts);
|
|
68055
|
+
if (shape)
|
|
68056
|
+
elements.push({ kind: "shape", data: shape });
|
|
68057
|
+
} else if (child.localName === "pic") {
|
|
68058
|
+
const img = parsePicture(child, scale, imageMap);
|
|
68059
|
+
if (img)
|
|
68060
|
+
elements.push({ kind: "image", data: img });
|
|
68061
|
+
} else if (child.localName === "grpSp") {
|
|
68062
|
+
const grpElements = parseGroupShape(child, scale, themeColors, imageMap, themeFonts);
|
|
68063
|
+
elements.push(...grpElements);
|
|
68064
|
+
}
|
|
68065
|
+
}
|
|
68066
|
+
return elements;
|
|
68067
|
+
}
|
|
68068
|
+
function parseGroupShape(grpSp, scale, themeColors, imageMap, themeFonts) {
|
|
68069
|
+
const elements = [];
|
|
68070
|
+
for (let i = 0; i < grpSp.children.length; i++) {
|
|
68071
|
+
const child = grpSp.children[i];
|
|
68072
|
+
if (child.localName === "sp") {
|
|
68073
|
+
const nvSpPr = findChild2(child, "nvSpPr");
|
|
68074
|
+
if (nvSpPr) {
|
|
68075
|
+
const phEl = findChild2(findChild2(nvSpPr, "nvPr") ?? nvSpPr, "ph");
|
|
68076
|
+
if (phEl)
|
|
68077
|
+
continue;
|
|
68078
|
+
}
|
|
68079
|
+
const spPr = findChild2(child, "spPr");
|
|
68080
|
+
if (spPr) {
|
|
68081
|
+
const custGeom = findChild2(spPr, "custGeom");
|
|
68082
|
+
if (custGeom) {
|
|
68083
|
+
const clipPath = extractCustGeomClipPath(custGeom);
|
|
68084
|
+
if (!clipPath)
|
|
68085
|
+
continue;
|
|
68086
|
+
const shape2 = parseShape(child, scale, themeColors, themeFonts);
|
|
68087
|
+
if (shape2) {
|
|
68088
|
+
shape2.clipPath = clipPath;
|
|
68089
|
+
elements.push({ kind: "shape", data: shape2 });
|
|
68090
|
+
}
|
|
68091
|
+
continue;
|
|
68092
|
+
}
|
|
68093
|
+
}
|
|
68094
|
+
const shape = parseShape(child, scale, themeColors, themeFonts);
|
|
68095
|
+
if (shape)
|
|
68096
|
+
elements.push({ kind: "shape", data: shape });
|
|
68097
|
+
} else if (child.localName === "pic") {
|
|
68098
|
+
const img = parsePicture(child, scale, imageMap);
|
|
68099
|
+
if (img)
|
|
68100
|
+
elements.push({ kind: "image", data: img });
|
|
68101
|
+
} else if (child.localName === "grpSp") {
|
|
68102
|
+
const nested = parseGroupShape(child, scale, themeColors, imageMap, themeFonts);
|
|
68103
|
+
elements.push(...nested);
|
|
68104
|
+
}
|
|
68105
|
+
}
|
|
68106
|
+
return elements;
|
|
68107
|
+
}
|
|
67877
68108
|
function extractRunProps(rPr, scale, themeColors, themeFonts) {
|
|
67878
68109
|
if (!rPr)
|
|
67879
68110
|
return {};
|
|
@@ -67887,6 +68118,9 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
67887
68118
|
const i = rPr.getAttribute("i");
|
|
67888
68119
|
if (i === "1" || i === "true")
|
|
67889
68120
|
result.italic = true;
|
|
68121
|
+
const u = rPr.getAttribute("u");
|
|
68122
|
+
if (u && u !== "none")
|
|
68123
|
+
result.underline = true;
|
|
67890
68124
|
const solidFill = findChild2(rPr, "solidFill");
|
|
67891
68125
|
if (solidFill) {
|
|
67892
68126
|
const color = resolveColor2(solidFill, themeColors);
|
|
@@ -67993,14 +68227,33 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
67993
68227
|
return null;
|
|
67994
68228
|
const wEmu = parseInt(ext.getAttribute("cx") ?? "0", 10);
|
|
67995
68229
|
const hEmu = parseInt(ext.getAttribute("cy") ?? "0", 10);
|
|
68230
|
+
let fill = extractFill(spPr, themeColors);
|
|
68231
|
+
if (!fill && !findChild2(spPr, "noFill")) {
|
|
68232
|
+
const styleEl = findChild2(sp, "style");
|
|
68233
|
+
if (styleEl) {
|
|
68234
|
+
const fillRef = findChild2(styleEl, "fillRef");
|
|
68235
|
+
if (fillRef) {
|
|
68236
|
+
const fillIdx = parseInt(fillRef.getAttribute("idx") ?? "0", 10);
|
|
68237
|
+
if (fillIdx > 0) {
|
|
68238
|
+
fill = resolveColor2(fillRef, themeColors) ?? void 0;
|
|
68239
|
+
}
|
|
68240
|
+
}
|
|
68241
|
+
}
|
|
68242
|
+
}
|
|
67996
68243
|
const shape = {
|
|
67997
68244
|
x: Math.round(emuToPx2(parseInt(off.getAttribute("x") ?? "0", 10)) * scale),
|
|
67998
68245
|
y: Math.round(emuToPx2(parseInt(off.getAttribute("y") ?? "0", 10)) * scale),
|
|
67999
68246
|
w: Math.round(emuToPx2(wEmu) * scale),
|
|
68000
68247
|
h: Math.round(emuToPx2(hEmu) * scale),
|
|
68001
|
-
fill
|
|
68248
|
+
fill,
|
|
68002
68249
|
paragraphs: []
|
|
68003
68250
|
};
|
|
68251
|
+
const rotAttr = xfrm.getAttribute("rot");
|
|
68252
|
+
if (rotAttr) {
|
|
68253
|
+
const rotDeg = parseInt(rotAttr, 10) / 6e4;
|
|
68254
|
+
if (rotDeg !== 0)
|
|
68255
|
+
shape.rotation = rotDeg;
|
|
68256
|
+
}
|
|
68004
68257
|
const prstGeom = findChild2(spPr, "prstGeom");
|
|
68005
68258
|
const prstType = prstGeom?.getAttribute("prst");
|
|
68006
68259
|
if (prstType === "roundRect" && prstGeom) {
|
|
@@ -68012,6 +68265,10 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
68012
68265
|
shape.borderRadius = Math.round(emuToPx2(radiusEmu) * scale);
|
|
68013
68266
|
} else if (prstType === "ellipse") {
|
|
68014
68267
|
shape.isEllipse = true;
|
|
68268
|
+
} else if (prstType === "rtTriangle") {
|
|
68269
|
+
shape.clipPath = "polygon(0 0, 0 100%, 100% 100%)";
|
|
68270
|
+
} else if (prstType === "triangle" || prstType === "isoTriangle") {
|
|
68271
|
+
shape.clipPath = "polygon(50% 0, 0 100%, 100% 100%)";
|
|
68015
68272
|
}
|
|
68016
68273
|
const ln = findChild2(spPr, "ln");
|
|
68017
68274
|
if (ln) {
|
|
@@ -68106,6 +68363,10 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
68106
68363
|
if (buChar) {
|
|
68107
68364
|
para.bulletChar = buChar.getAttribute("char") ?? void 0;
|
|
68108
68365
|
}
|
|
68366
|
+
const buFont = findChild2(pPr, "buFont");
|
|
68367
|
+
if (buFont) {
|
|
68368
|
+
para.bulletFont = buFont.getAttribute("typeface") ?? void 0;
|
|
68369
|
+
}
|
|
68109
68370
|
const buClr = findChild2(pPr, "buClr");
|
|
68110
68371
|
if (buClr) {
|
|
68111
68372
|
para.bulletColor = resolveColor2(buClr, themeColors);
|
|
@@ -68126,6 +68387,7 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
68126
68387
|
text,
|
|
68127
68388
|
bold: props.bold ?? defaults?.bold,
|
|
68128
68389
|
italic: props.italic ?? defaults?.italic,
|
|
68390
|
+
underline: props.underline ?? defaults?.underline,
|
|
68129
68391
|
fontSize: props.fontSize ?? defaults?.fontSize,
|
|
68130
68392
|
color: props.color ?? defaults?.color,
|
|
68131
68393
|
fontFamily: props.fontFamily ?? defaults?.fontFamily,
|
|
@@ -68196,12 +68458,16 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
68196
68458
|
const alt = cNvPr?.getAttribute("descr") ?? void 0;
|
|
68197
68459
|
const srcRect = findChild2(blipFill, "srcRect");
|
|
68198
68460
|
let hasCrop = false;
|
|
68461
|
+
let cropLeft = 0;
|
|
68462
|
+
let cropTop = 0;
|
|
68463
|
+
let cropRight = 0;
|
|
68464
|
+
let cropBottom = 0;
|
|
68199
68465
|
if (srcRect) {
|
|
68200
|
-
|
|
68201
|
-
|
|
68202
|
-
|
|
68203
|
-
|
|
68204
|
-
hasCrop =
|
|
68466
|
+
cropLeft = parseInt(srcRect.getAttribute("l") ?? "0", 10) / 1e3;
|
|
68467
|
+
cropRight = parseInt(srcRect.getAttribute("r") ?? "0", 10) / 1e3;
|
|
68468
|
+
cropTop = parseInt(srcRect.getAttribute("t") ?? "0", 10) / 1e3;
|
|
68469
|
+
cropBottom = parseInt(srcRect.getAttribute("b") ?? "0", 10) / 1e3;
|
|
68470
|
+
hasCrop = cropLeft > 0 || cropRight > 0 || cropTop > 0 || cropBottom > 0;
|
|
68205
68471
|
}
|
|
68206
68472
|
let borderRadius;
|
|
68207
68473
|
const prstGeom = findChild2(spPr, "prstGeom");
|
|
@@ -68215,6 +68481,13 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
68215
68481
|
const radiusEmu = minDim * Math.min(adjVal, 5e4) / 1e5;
|
|
68216
68482
|
borderRadius = Math.round(emuToPx2(radiusEmu) * scale);
|
|
68217
68483
|
}
|
|
68484
|
+
let rotation;
|
|
68485
|
+
const rotAttr = xfrm.getAttribute("rot");
|
|
68486
|
+
if (rotAttr) {
|
|
68487
|
+
const rotDeg = parseInt(rotAttr, 10) / 6e4;
|
|
68488
|
+
if (rotDeg !== 0)
|
|
68489
|
+
rotation = rotDeg;
|
|
68490
|
+
}
|
|
68218
68491
|
return {
|
|
68219
68492
|
x: Math.round(emuToPx2(parseInt(off.getAttribute("x") ?? "0", 10)) * scale),
|
|
68220
68493
|
y: Math.round(emuToPx2(parseInt(off.getAttribute("y") ?? "0", 10)) * scale),
|
|
@@ -68223,7 +68496,12 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
68223
68496
|
dataUri,
|
|
68224
68497
|
alt,
|
|
68225
68498
|
borderRadius,
|
|
68226
|
-
hasCrop
|
|
68499
|
+
hasCrop,
|
|
68500
|
+
cropLeft: hasCrop ? cropLeft : void 0,
|
|
68501
|
+
cropTop: hasCrop ? cropTop : void 0,
|
|
68502
|
+
cropRight: hasCrop ? cropRight : void 0,
|
|
68503
|
+
cropBottom: hasCrop ? cropBottom : void 0,
|
|
68504
|
+
rotation
|
|
68227
68505
|
};
|
|
68228
68506
|
}
|
|
68229
68507
|
async function parseTableStyles(zip, parser, themeColors) {
|
|
@@ -68351,6 +68629,10 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
68351
68629
|
if (buChar) {
|
|
68352
68630
|
para.bulletChar = buChar.getAttribute("char") ?? void 0;
|
|
68353
68631
|
}
|
|
68632
|
+
const buFont = findChild2(pPr, "buFont");
|
|
68633
|
+
if (buFont) {
|
|
68634
|
+
para.bulletFont = buFont.getAttribute("typeface") ?? void 0;
|
|
68635
|
+
}
|
|
68354
68636
|
const buClr = findChild2(pPr, "buClr");
|
|
68355
68637
|
if (buClr) {
|
|
68356
68638
|
para.bulletColor = resolveColor2(buClr, themeColors);
|
|
@@ -68371,6 +68653,7 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
68371
68653
|
text,
|
|
68372
68654
|
bold: props.bold ?? defaults?.bold,
|
|
68373
68655
|
italic: props.italic ?? defaults?.italic,
|
|
68656
|
+
underline: props.underline ?? defaults?.underline,
|
|
68374
68657
|
fontSize: props.fontSize ?? defaults?.fontSize,
|
|
68375
68658
|
color: props.color ?? defaults?.color,
|
|
68376
68659
|
fontFamily: props.fontFamily ?? defaults?.fontFamily,
|
|
@@ -68528,15 +68811,523 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
68528
68811
|
}
|
|
68529
68812
|
return table;
|
|
68530
68813
|
}
|
|
68531
|
-
function
|
|
68814
|
+
function resolveChartColor(parent, themeColors) {
|
|
68815
|
+
const solidFill = findChild2(parent, "solidFill");
|
|
68816
|
+
if (!solidFill)
|
|
68817
|
+
return void 0;
|
|
68818
|
+
return resolveColor2(solidFill, themeColors);
|
|
68819
|
+
}
|
|
68820
|
+
function parseChartRichText(richEl) {
|
|
68821
|
+
const paragraphs = findChildren2(richEl, "p");
|
|
68822
|
+
let text = "";
|
|
68823
|
+
let font;
|
|
68824
|
+
let color;
|
|
68825
|
+
let size;
|
|
68826
|
+
for (const p of paragraphs) {
|
|
68827
|
+
const runs = findChildren2(p, "r");
|
|
68828
|
+
for (const r of runs) {
|
|
68829
|
+
const tEl = findChild2(r, "t");
|
|
68830
|
+
if (tEl?.textContent)
|
|
68831
|
+
text += tEl.textContent;
|
|
68832
|
+
if (font === void 0) {
|
|
68833
|
+
const rPr = findChild2(r, "rPr");
|
|
68834
|
+
if (rPr) {
|
|
68835
|
+
const szAttr = rPr.getAttribute("sz");
|
|
68836
|
+
if (szAttr)
|
|
68837
|
+
size = hptToPx(parseInt(szAttr, 10));
|
|
68838
|
+
const latin = findChild2(rPr, "latin");
|
|
68839
|
+
if (latin)
|
|
68840
|
+
font = latin.getAttribute("typeface") ?? void 0;
|
|
68841
|
+
const fill = findChild2(rPr, "solidFill");
|
|
68842
|
+
if (fill) {
|
|
68843
|
+
const srgb = findChild2(fill, "srgbClr");
|
|
68844
|
+
if (srgb)
|
|
68845
|
+
color = "#" + (srgb.getAttribute("val") ?? "000000");
|
|
68846
|
+
}
|
|
68847
|
+
}
|
|
68848
|
+
}
|
|
68849
|
+
}
|
|
68850
|
+
}
|
|
68851
|
+
return { text, font, color, size };
|
|
68852
|
+
}
|
|
68853
|
+
function parseChartAxis(axEl, themeColors) {
|
|
68854
|
+
const axis = {
|
|
68855
|
+
position: "b"
|
|
68856
|
+
};
|
|
68857
|
+
const axPos = findChild2(axEl, "axPos");
|
|
68858
|
+
if (axPos) {
|
|
68859
|
+
const val = axPos.getAttribute("val");
|
|
68860
|
+
if (val === "b" || val === "l" || val === "r" || val === "t") {
|
|
68861
|
+
axis.position = val;
|
|
68862
|
+
}
|
|
68863
|
+
}
|
|
68864
|
+
const titleEl = findChild2(axEl, "title");
|
|
68865
|
+
if (titleEl) {
|
|
68866
|
+
const tx = findChild2(titleEl, "tx");
|
|
68867
|
+
if (tx) {
|
|
68868
|
+
const rich = findChild2(tx, "rich");
|
|
68869
|
+
if (rich) {
|
|
68870
|
+
const parsed = parseChartRichText(rich);
|
|
68871
|
+
axis.title = parsed.text;
|
|
68872
|
+
}
|
|
68873
|
+
}
|
|
68874
|
+
}
|
|
68875
|
+
const numFmt = findChild2(axEl, "numFmt");
|
|
68876
|
+
if (numFmt) {
|
|
68877
|
+
const fmt = numFmt.getAttribute("formatCode");
|
|
68878
|
+
if (fmt)
|
|
68879
|
+
axis.numFormat = fmt;
|
|
68880
|
+
}
|
|
68881
|
+
const txPr = findChild2(axEl, "txPr");
|
|
68882
|
+
if (txPr) {
|
|
68883
|
+
const pEls = findChildren2(txPr, "p");
|
|
68884
|
+
for (const p of pEls) {
|
|
68885
|
+
const pPr = findChild2(p, "pPr");
|
|
68886
|
+
if (pPr) {
|
|
68887
|
+
const defRPr = findChild2(pPr, "defRPr");
|
|
68888
|
+
if (defRPr) {
|
|
68889
|
+
const szAttr = defRPr.getAttribute("sz");
|
|
68890
|
+
if (szAttr)
|
|
68891
|
+
axis.labelSize = hptToPx(parseInt(szAttr, 10));
|
|
68892
|
+
const latin = findChild2(defRPr, "latin");
|
|
68893
|
+
if (latin)
|
|
68894
|
+
axis.labelFont = latin.getAttribute("typeface") ?? void 0;
|
|
68895
|
+
const fill = findChild2(defRPr, "solidFill");
|
|
68896
|
+
if (fill) {
|
|
68897
|
+
const srgb = findChild2(fill, "srgbClr");
|
|
68898
|
+
if (srgb)
|
|
68899
|
+
axis.labelColor = "#" + (srgb.getAttribute("val") ?? "000000");
|
|
68900
|
+
}
|
|
68901
|
+
}
|
|
68902
|
+
}
|
|
68903
|
+
}
|
|
68904
|
+
}
|
|
68905
|
+
const gridlines = findChild2(axEl, "majorGridlines");
|
|
68906
|
+
if (gridlines) {
|
|
68907
|
+
const spPr = findChild2(gridlines, "spPr");
|
|
68908
|
+
if (spPr) {
|
|
68909
|
+
const ln = findChild2(spPr, "ln");
|
|
68910
|
+
if (ln) {
|
|
68911
|
+
const fill = findChild2(ln, "solidFill");
|
|
68912
|
+
if (fill) {
|
|
68913
|
+
const srgb = findChild2(fill, "srgbClr");
|
|
68914
|
+
if (srgb) {
|
|
68915
|
+
axis.gridlineColor = "#" + (srgb.getAttribute("val") ?? "CCCCCC");
|
|
68916
|
+
const alphaEl = findChild2(srgb, "alpha");
|
|
68917
|
+
if (alphaEl) {
|
|
68918
|
+
axis.gridlineAlpha = parseInt(alphaEl.getAttribute("val") ?? "100000", 10) / 1e3;
|
|
68919
|
+
}
|
|
68920
|
+
}
|
|
68921
|
+
}
|
|
68922
|
+
}
|
|
68923
|
+
}
|
|
68924
|
+
}
|
|
68925
|
+
const scaling = findChild2(axEl, "scaling");
|
|
68926
|
+
if (scaling) {
|
|
68927
|
+
const minEl = findChild2(scaling, "min");
|
|
68928
|
+
if (minEl) {
|
|
68929
|
+
const val = minEl.getAttribute("val");
|
|
68930
|
+
if (val)
|
|
68931
|
+
axis.min = parseFloat(val);
|
|
68932
|
+
}
|
|
68933
|
+
}
|
|
68934
|
+
return axis;
|
|
68935
|
+
}
|
|
68936
|
+
async function parseChart(graphicFrame, scale, themeColors, zip, slideRelsDoc, parser) {
|
|
68937
|
+
const xfrm = findChild2(graphicFrame, "xfrm");
|
|
68938
|
+
if (!xfrm)
|
|
68939
|
+
return null;
|
|
68940
|
+
const off = findChild2(xfrm, "off");
|
|
68941
|
+
const ext = findChild2(xfrm, "ext");
|
|
68942
|
+
if (!off || !ext)
|
|
68943
|
+
return null;
|
|
68944
|
+
const graphic = findChild2(graphicFrame, "graphic");
|
|
68945
|
+
if (!graphic)
|
|
68946
|
+
return null;
|
|
68947
|
+
const graphicData = findChild2(graphic, "graphicData");
|
|
68948
|
+
if (!graphicData)
|
|
68949
|
+
return null;
|
|
68950
|
+
const uri2 = graphicData.getAttribute("uri") ?? "";
|
|
68951
|
+
if (!uri2.includes("chart"))
|
|
68952
|
+
return null;
|
|
68953
|
+
let chartRId;
|
|
68954
|
+
for (let i = 0; i < graphicData.children.length; i++) {
|
|
68955
|
+
const child = graphicData.children[i];
|
|
68956
|
+
if (child.localName === "chart") {
|
|
68957
|
+
chartRId = child.getAttribute("r:id") ?? child.getAttributeNS("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "id") ?? void 0;
|
|
68958
|
+
break;
|
|
68959
|
+
}
|
|
68960
|
+
}
|
|
68961
|
+
if (!chartRId)
|
|
68962
|
+
return null;
|
|
68963
|
+
let chartTarget;
|
|
68964
|
+
const rels = slideRelsDoc.getElementsByTagName("Relationship");
|
|
68965
|
+
for (let ri = 0; ri < rels.length; ri++) {
|
|
68966
|
+
const rel = rels[ri];
|
|
68967
|
+
if (rel.getAttribute("Id") === chartRId) {
|
|
68968
|
+
chartTarget = rel.getAttribute("Target") ?? void 0;
|
|
68969
|
+
break;
|
|
68970
|
+
}
|
|
68971
|
+
}
|
|
68972
|
+
if (!chartTarget)
|
|
68973
|
+
return null;
|
|
68974
|
+
const chartPath = chartTarget.startsWith("../") ? "ppt/" + chartTarget.slice(3) : chartTarget;
|
|
68975
|
+
const chartXml = await zip.file(chartPath)?.async("text");
|
|
68976
|
+
if (!chartXml)
|
|
68977
|
+
return null;
|
|
68978
|
+
const chartDoc = parser.parseFromString(chartXml, "application/xml");
|
|
68979
|
+
const chartSpace = chartDoc.documentElement;
|
|
68980
|
+
const x = Math.round(emuToPx2(parseInt(off.getAttribute("x") ?? "0", 10)) * scale);
|
|
68981
|
+
const y = Math.round(emuToPx2(parseInt(off.getAttribute("y") ?? "0", 10)) * scale);
|
|
68982
|
+
const w = Math.round(emuToPx2(parseInt(ext.getAttribute("cx") ?? "0", 10)) * scale);
|
|
68983
|
+
const h = Math.round(emuToPx2(parseInt(ext.getAttribute("cy") ?? "0", 10)) * scale);
|
|
68984
|
+
const chartEl = findChild2(chartSpace, "chart");
|
|
68985
|
+
if (!chartEl)
|
|
68986
|
+
return null;
|
|
68987
|
+
let title;
|
|
68988
|
+
let titleFont;
|
|
68989
|
+
let titleColor;
|
|
68990
|
+
let titleSize;
|
|
68991
|
+
const titleEl = findChild2(chartEl, "title");
|
|
68992
|
+
if (titleEl) {
|
|
68993
|
+
const tx = findChild2(titleEl, "tx");
|
|
68994
|
+
if (tx) {
|
|
68995
|
+
const rich = findChild2(tx, "rich");
|
|
68996
|
+
if (rich) {
|
|
68997
|
+
const parsed = parseChartRichText(rich);
|
|
68998
|
+
title = parsed.text;
|
|
68999
|
+
titleFont = parsed.font;
|
|
69000
|
+
titleColor = parsed.color;
|
|
69001
|
+
titleSize = parsed.size;
|
|
69002
|
+
}
|
|
69003
|
+
}
|
|
69004
|
+
}
|
|
69005
|
+
const plotArea = findChild2(chartEl, "plotArea");
|
|
69006
|
+
if (!plotArea)
|
|
69007
|
+
return null;
|
|
69008
|
+
const barChart = findChild2(plotArea, "barChart");
|
|
69009
|
+
if (!barChart)
|
|
69010
|
+
return null;
|
|
69011
|
+
const barDirEl = findChild2(barChart, "barDir");
|
|
69012
|
+
const barDir = barDirEl?.getAttribute("val") ?? "col";
|
|
69013
|
+
const chartType = barDir === "bar" ? "bar" : "column";
|
|
69014
|
+
const gapWidthEl = findChild2(barChart, "gapWidth");
|
|
69015
|
+
const gapWidth = gapWidthEl ? parseInt(gapWidthEl.getAttribute("val") ?? "150", 10) : 150;
|
|
69016
|
+
const roundedCornersEl = findChild2(chartSpace, "roundedCorners");
|
|
69017
|
+
const roundedCorners = roundedCornersEl?.getAttribute("val") === "1";
|
|
69018
|
+
const series = [];
|
|
69019
|
+
const serEls = findChildren2(barChart, "ser");
|
|
69020
|
+
for (const ser of serEls) {
|
|
69021
|
+
const seriesData = {
|
|
69022
|
+
categories: [],
|
|
69023
|
+
values: [],
|
|
69024
|
+
fillColors: []
|
|
69025
|
+
};
|
|
69026
|
+
const txEl = findChild2(ser, "tx");
|
|
69027
|
+
if (txEl) {
|
|
69028
|
+
const strRef = findChild2(txEl, "strRef");
|
|
69029
|
+
if (strRef) {
|
|
69030
|
+
const strCache = findChild2(strRef, "strCache");
|
|
69031
|
+
if (strCache) {
|
|
69032
|
+
const pt = findChild2(strCache, "pt");
|
|
69033
|
+
if (pt) {
|
|
69034
|
+
const v = findChild2(pt, "v");
|
|
69035
|
+
if (v?.textContent)
|
|
69036
|
+
seriesData.name = v.textContent;
|
|
69037
|
+
}
|
|
69038
|
+
}
|
|
69039
|
+
}
|
|
69040
|
+
}
|
|
69041
|
+
const serSpPr = findChild2(ser, "spPr");
|
|
69042
|
+
if (serSpPr) {
|
|
69043
|
+
const color = resolveChartColor(serSpPr, themeColors);
|
|
69044
|
+
if (color)
|
|
69045
|
+
seriesData.seriesColor = color;
|
|
69046
|
+
}
|
|
69047
|
+
const dPtMap = /* @__PURE__ */ new Map();
|
|
69048
|
+
const dPtEls = findChildren2(ser, "dPt");
|
|
69049
|
+
for (const dPt of dPtEls) {
|
|
69050
|
+
const idxEl = findChild2(dPt, "idx");
|
|
69051
|
+
const idx = idxEl ? parseInt(idxEl.getAttribute("val") ?? "0", 10) : 0;
|
|
69052
|
+
const spPr = findChild2(dPt, "spPr");
|
|
69053
|
+
if (spPr) {
|
|
69054
|
+
const color = resolveChartColor(spPr, themeColors);
|
|
69055
|
+
if (color)
|
|
69056
|
+
dPtMap.set(idx, color);
|
|
69057
|
+
}
|
|
69058
|
+
}
|
|
69059
|
+
const catEl = findChild2(ser, "cat");
|
|
69060
|
+
if (catEl) {
|
|
69061
|
+
const strRef = findChild2(catEl, "strRef");
|
|
69062
|
+
if (strRef) {
|
|
69063
|
+
const strCache = findChild2(strRef, "strCache");
|
|
69064
|
+
if (strCache) {
|
|
69065
|
+
const pts = findChildren2(strCache, "pt");
|
|
69066
|
+
for (const pt of pts) {
|
|
69067
|
+
const v = findChild2(pt, "v");
|
|
69068
|
+
seriesData.categories.push(v?.textContent ?? "");
|
|
69069
|
+
}
|
|
69070
|
+
}
|
|
69071
|
+
}
|
|
69072
|
+
}
|
|
69073
|
+
const valEl = findChild2(ser, "val");
|
|
69074
|
+
if (valEl) {
|
|
69075
|
+
const numRef = findChild2(valEl, "numRef");
|
|
69076
|
+
if (numRef) {
|
|
69077
|
+
const numCache = findChild2(numRef, "numCache");
|
|
69078
|
+
if (numCache) {
|
|
69079
|
+
const pts = findChildren2(numCache, "pt");
|
|
69080
|
+
for (const pt of pts) {
|
|
69081
|
+
const v = findChild2(pt, "v");
|
|
69082
|
+
seriesData.values.push(parseFloat(v?.textContent ?? "0"));
|
|
69083
|
+
}
|
|
69084
|
+
}
|
|
69085
|
+
}
|
|
69086
|
+
}
|
|
69087
|
+
for (let i = 0; i < seriesData.values.length; i++) {
|
|
69088
|
+
seriesData.fillColors.push(dPtMap.get(i) ?? void 0);
|
|
69089
|
+
}
|
|
69090
|
+
series.push(seriesData);
|
|
69091
|
+
}
|
|
69092
|
+
if (series.length === 0)
|
|
69093
|
+
return null;
|
|
69094
|
+
let categoryAxis;
|
|
69095
|
+
let valueAxis;
|
|
69096
|
+
const catAx = findChild2(plotArea, "catAx");
|
|
69097
|
+
if (catAx) {
|
|
69098
|
+
categoryAxis = parseChartAxis(catAx, themeColors);
|
|
69099
|
+
}
|
|
69100
|
+
const valAx = findChild2(plotArea, "valAx");
|
|
69101
|
+
if (valAx) {
|
|
69102
|
+
valueAxis = parseChartAxis(valAx, themeColors);
|
|
69103
|
+
}
|
|
69104
|
+
return {
|
|
69105
|
+
x,
|
|
69106
|
+
y,
|
|
69107
|
+
w,
|
|
69108
|
+
h,
|
|
69109
|
+
chartType,
|
|
69110
|
+
title,
|
|
69111
|
+
titleFont,
|
|
69112
|
+
titleColor,
|
|
69113
|
+
titleSize,
|
|
69114
|
+
series,
|
|
69115
|
+
categoryAxis,
|
|
69116
|
+
valueAxis,
|
|
69117
|
+
gapWidth,
|
|
69118
|
+
roundedCorners
|
|
69119
|
+
};
|
|
69120
|
+
}
|
|
69121
|
+
function formatChartValue(value, numFormat) {
|
|
69122
|
+
if (!numFormat || numFormat === "General") {
|
|
69123
|
+
return Number.isInteger(value) ? value.toString() : value.toFixed(1);
|
|
69124
|
+
}
|
|
69125
|
+
let prefix = "";
|
|
69126
|
+
let suffix = "";
|
|
69127
|
+
let fmt = numFormat;
|
|
69128
|
+
const prefixMatch = fmt.match(/^"([^"]*)"(.*)$/);
|
|
69129
|
+
if (prefixMatch) {
|
|
69130
|
+
prefix = prefixMatch[1];
|
|
69131
|
+
fmt = prefixMatch[2];
|
|
69132
|
+
}
|
|
69133
|
+
const suffixMatch = fmt.match(/^(.*)"([^"]*)"$/);
|
|
69134
|
+
if (suffixMatch) {
|
|
69135
|
+
fmt = suffixMatch[1];
|
|
69136
|
+
suffix = suffixMatch[2];
|
|
69137
|
+
}
|
|
69138
|
+
const decimalMatch = fmt.match(/\.(0+)/);
|
|
69139
|
+
const decimals = decimalMatch ? decimalMatch[1].length : 0;
|
|
69140
|
+
const absVal = Math.abs(value);
|
|
69141
|
+
let formatted;
|
|
69142
|
+
if (fmt.includes(",")) {
|
|
69143
|
+
const parts = absVal.toFixed(decimals).split(".");
|
|
69144
|
+
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
69145
|
+
formatted = parts.join(".");
|
|
69146
|
+
} else {
|
|
69147
|
+
formatted = absVal.toFixed(decimals);
|
|
69148
|
+
}
|
|
69149
|
+
const sign2 = value < 0 ? "-" : "";
|
|
69150
|
+
return sign2 + prefix + formatted + suffix;
|
|
69151
|
+
}
|
|
69152
|
+
function escSvg(text) {
|
|
69153
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
69154
|
+
}
|
|
69155
|
+
function renderChartSvg(chart, elId) {
|
|
69156
|
+
const { x, y, w, h } = chart;
|
|
69157
|
+
const titleHeight = chart.title ? Math.max(24, (chart.titleSize ?? 16) + 12) : 0;
|
|
69158
|
+
const axisLabelHeight = 16;
|
|
69159
|
+
const axisTitleHeight = chart.categoryAxis?.title ? 18 : 0;
|
|
69160
|
+
const valAxisTitleWidth = chart.valueAxis?.title ? 20 : 0;
|
|
69161
|
+
const allValues = chart.series.flatMap((s) => s.values);
|
|
69162
|
+
const maxValue = Math.max(...allValues, 0);
|
|
69163
|
+
const valNumFormat = chart.valueAxis?.numFormat;
|
|
69164
|
+
const maxFormattedLabel = formatChartValue(maxValue, valNumFormat);
|
|
69165
|
+
const valLabelCharWidth = (chart.valueAxis?.labelSize ?? 11) * 0.6;
|
|
69166
|
+
const valLabelWidth = Math.max(30, maxFormattedLabel.length * valLabelCharWidth + 8);
|
|
69167
|
+
const marginTop = 8 + titleHeight;
|
|
69168
|
+
const marginBottom = 8 + axisLabelHeight + axisTitleHeight + 4;
|
|
69169
|
+
const marginLeft = 4 + valAxisTitleWidth + valLabelWidth;
|
|
69170
|
+
const marginRight = 12;
|
|
69171
|
+
const plotX = marginLeft;
|
|
69172
|
+
const plotY = marginTop;
|
|
69173
|
+
const plotW = w - marginLeft - marginRight;
|
|
69174
|
+
const plotH = h - marginTop - marginBottom;
|
|
69175
|
+
if (plotW <= 0 || plotH <= 0)
|
|
69176
|
+
return "";
|
|
69177
|
+
const minValue = chart.valueAxis?.min ?? 0;
|
|
69178
|
+
const valueRange = maxValue - minValue;
|
|
69179
|
+
if (valueRange <= 0)
|
|
69180
|
+
return "";
|
|
69181
|
+
const rawInterval = valueRange / 5;
|
|
69182
|
+
const magnitude = Math.pow(10, Math.floor(Math.log10(rawInterval)));
|
|
69183
|
+
const normalized = rawInterval / magnitude;
|
|
69184
|
+
let niceInterval;
|
|
69185
|
+
if (normalized <= 1)
|
|
69186
|
+
niceInterval = 1 * magnitude;
|
|
69187
|
+
else if (normalized <= 2)
|
|
69188
|
+
niceInterval = 2 * magnitude;
|
|
69189
|
+
else if (normalized <= 5)
|
|
69190
|
+
niceInterval = 5 * magnitude;
|
|
69191
|
+
else
|
|
69192
|
+
niceInterval = 10 * magnitude;
|
|
69193
|
+
const ticks = [];
|
|
69194
|
+
let tickVal = Math.ceil(minValue / niceInterval) * niceInterval;
|
|
69195
|
+
while (tickVal <= maxValue) {
|
|
69196
|
+
ticks.push(tickVal);
|
|
69197
|
+
tickVal += niceInterval;
|
|
69198
|
+
}
|
|
69199
|
+
if (minValue <= 0 && !ticks.includes(0)) {
|
|
69200
|
+
ticks.unshift(0);
|
|
69201
|
+
ticks.sort((a, b) => a - b);
|
|
69202
|
+
}
|
|
69203
|
+
const labelFont = chart.categoryAxis?.labelFont ?? chart.titleFont ?? "sans-serif";
|
|
69204
|
+
const labelColor = chart.categoryAxis?.labelColor ?? "#333";
|
|
69205
|
+
const labelSize = chart.categoryAxis?.labelSize ?? 11;
|
|
69206
|
+
const valLabelColor = chart.valueAxis?.labelColor ?? labelColor;
|
|
69207
|
+
const valLabelSize = chart.valueAxis?.labelSize ?? 11;
|
|
69208
|
+
let svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${w}" height="${h}" viewBox="0 0 ${w} ${h}" style="overflow:visible">`;
|
|
69209
|
+
if (chart.title) {
|
|
69210
|
+
const tFont = chart.titleFont ? `font-family:${cssFontFamily(chart.titleFont)};` : `font-family:${cssFontFamily(labelFont)};`;
|
|
69211
|
+
const tColor = chart.titleColor ?? "#000";
|
|
69212
|
+
const tSize = chart.titleSize ?? 16;
|
|
69213
|
+
svg += `<text x="${w / 2}" y="${8 + tSize}" text-anchor="middle" style="${tFont}font-size:${tSize}px;font-weight:bold;fill:${tColor}">${escSvg(chart.title)}</text>`;
|
|
69214
|
+
}
|
|
69215
|
+
if (chart.valueAxis) {
|
|
69216
|
+
const gColor = chart.valueAxis.gridlineColor ?? "#e0e0e0";
|
|
69217
|
+
const gAlpha = chart.valueAxis.gridlineAlpha !== void 0 ? chart.valueAxis.gridlineAlpha / 100 : 0.3;
|
|
69218
|
+
for (const tick of ticks) {
|
|
69219
|
+
const tickY = plotY + plotH - (tick - minValue) / valueRange * plotH;
|
|
69220
|
+
svg += `<line x1="${plotX}" y1="${tickY}" x2="${plotX + plotW}" y2="${tickY}" stroke="${gColor}" stroke-opacity="${gAlpha}" stroke-width="1"/>`;
|
|
69221
|
+
}
|
|
69222
|
+
}
|
|
69223
|
+
const numCategories = chart.series[0]?.categories.length ?? 0;
|
|
69224
|
+
const numSeries = chart.series.length;
|
|
69225
|
+
if (numCategories > 0) {
|
|
69226
|
+
const gapFraction = (chart.gapWidth ?? 150) / 100;
|
|
69227
|
+
const categoryWidth = plotW / numCategories;
|
|
69228
|
+
const barGroupWidth = categoryWidth / (1 + gapFraction);
|
|
69229
|
+
const gapSpace = categoryWidth - barGroupWidth;
|
|
69230
|
+
const barWidth = barGroupWidth / numSeries;
|
|
69231
|
+
const cornerRadius = chart.roundedCorners ? Math.min(barWidth * 0.15, 4) : 0;
|
|
69232
|
+
for (let si = 0; si < numSeries; si++) {
|
|
69233
|
+
const s = chart.series[si];
|
|
69234
|
+
for (let ci = 0; ci < s.values.length; ci++) {
|
|
69235
|
+
const val = s.values[ci];
|
|
69236
|
+
const barH = (val - minValue) / valueRange * plotH;
|
|
69237
|
+
const barX = plotX + ci * categoryWidth + gapSpace / 2 + si * barWidth;
|
|
69238
|
+
const barY = plotY + plotH - barH;
|
|
69239
|
+
const fillColor = s.fillColors[ci] ?? s.seriesColor ?? "#4472C4";
|
|
69240
|
+
if (cornerRadius > 0) {
|
|
69241
|
+
const r = Math.min(cornerRadius, barH / 2, barWidth / 2);
|
|
69242
|
+
svg += `<path d="M${barX},${barY + barH} L${barX},${barY + r} Q${barX},${barY} ${barX + r},${barY} L${barX + barWidth - r},${barY} Q${barX + barWidth},${barY} ${barX + barWidth},${barY + r} L${barX + barWidth},${barY + barH} Z" fill="${fillColor}"/>`;
|
|
69243
|
+
} else {
|
|
69244
|
+
svg += `<rect x="${barX}" y="${barY}" width="${barWidth}" height="${barH}" fill="${fillColor}"/>`;
|
|
69245
|
+
}
|
|
69246
|
+
}
|
|
69247
|
+
}
|
|
69248
|
+
}
|
|
69249
|
+
svg += `<line x1="${plotX}" y1="${plotY + plotH}" x2="${plotX + plotW}" y2="${plotY + plotH}" stroke="${labelColor}" stroke-width="1"/>`;
|
|
69250
|
+
svg += `<line x1="${plotX}" y1="${plotY}" x2="${plotX}" y2="${plotY + plotH}" stroke="${valLabelColor}" stroke-width="1"/>`;
|
|
69251
|
+
if (numCategories > 0) {
|
|
69252
|
+
const categoryWidth = plotW / numCategories;
|
|
69253
|
+
const cats = chart.series[0]?.categories ?? [];
|
|
69254
|
+
for (let ci = 0; ci < cats.length; ci++) {
|
|
69255
|
+
const labelX = plotX + ci * categoryWidth + categoryWidth / 2;
|
|
69256
|
+
const labelY = plotY + plotH + 4;
|
|
69257
|
+
const catText = cats[ci];
|
|
69258
|
+
const lines = catText.split("\n");
|
|
69259
|
+
const lineH = labelSize + 2;
|
|
69260
|
+
for (let li = 0; li < lines.length; li++) {
|
|
69261
|
+
svg += `<text x="${labelX}" y="${labelY + labelSize + li * lineH}" text-anchor="middle" style="font-family:${cssFontFamily(labelFont)};font-size:${labelSize}px;fill:${labelColor}">${escSvg(lines[li])}</text>`;
|
|
69262
|
+
}
|
|
69263
|
+
}
|
|
69264
|
+
}
|
|
69265
|
+
for (const tick of ticks) {
|
|
69266
|
+
const tickY = plotY + plotH - (tick - minValue) / valueRange * plotH;
|
|
69267
|
+
const label = formatChartValue(tick, valNumFormat);
|
|
69268
|
+
svg += `<text x="${plotX - 6}" y="${tickY + valLabelSize * 0.35}" text-anchor="end" style="font-family:${cssFontFamily(labelFont)};font-size:${valLabelSize}px;fill:${valLabelColor}">${escSvg(label)}</text>`;
|
|
69269
|
+
}
|
|
69270
|
+
if (chart.categoryAxis?.title) {
|
|
69271
|
+
const axTitleY = plotY + plotH + axisLabelHeight + axisTitleHeight + 2;
|
|
69272
|
+
svg += `<text x="${plotX + plotW / 2}" y="${axTitleY}" text-anchor="middle" style="font-family:${cssFontFamily(labelFont)};font-size:${labelSize}px;fill:${labelColor}">${escSvg(chart.categoryAxis.title)}</text>`;
|
|
69273
|
+
}
|
|
69274
|
+
if (chart.valueAxis?.title) {
|
|
69275
|
+
const axTitleX = 4 + (chart.titleSize ?? 12) * 0.5;
|
|
69276
|
+
const axTitleY = plotY + plotH / 2;
|
|
69277
|
+
svg += `<text x="${axTitleX}" y="${axTitleY}" text-anchor="middle" transform="rotate(-90, ${axTitleX}, ${axTitleY})" style="font-family:${cssFontFamily(labelFont)};font-size:${labelSize}px;fill:${valLabelColor}">${escSvg(chart.valueAxis.title)}</text>`;
|
|
69278
|
+
}
|
|
69279
|
+
svg += `</svg>`;
|
|
69280
|
+
const wrapperStyles = [
|
|
69281
|
+
"position:absolute",
|
|
69282
|
+
`left:${x}px`,
|
|
69283
|
+
`top:${y}px`,
|
|
69284
|
+
`width:${w}px`,
|
|
69285
|
+
`height:${h}px`
|
|
69286
|
+
];
|
|
69287
|
+
return `<div id="${elId}" data-elementType="chart" style="${wrapperStyles.join(";")}">${svg}</div>
|
|
69288
|
+
`;
|
|
69289
|
+
}
|
|
69290
|
+
function renderSlideHtml(elements, bgColor, contentOffsetX = 0) {
|
|
68532
69291
|
let inner = "";
|
|
68533
69292
|
let elementIndex = 0;
|
|
68534
69293
|
for (const el of elements) {
|
|
68535
69294
|
const elId = `el-${elementIndex++}`;
|
|
68536
69295
|
if (el.kind === "image") {
|
|
68537
69296
|
const img = el.data;
|
|
69297
|
+
const altAttr = img.alt ? ` alt="${img.alt.replace(/"/g, """)}"` : "";
|
|
68538
69298
|
const isFullbleed = img.x <= 10 && img.y <= 10 && img.w >= TARGET_WIDTH - 20 && img.h >= TARGET_HEIGHT - 20;
|
|
68539
|
-
|
|
69299
|
+
if (img.hasCrop && img.cropLeft !== void 0 && img.cropTop !== void 0 && img.cropRight !== void 0 && img.cropBottom !== void 0) {
|
|
69300
|
+
const visW = (100 - img.cropLeft - img.cropRight) / 100;
|
|
69301
|
+
const visH = (100 - img.cropTop - img.cropBottom) / 100;
|
|
69302
|
+
if (visW > 0 && visH > 0) {
|
|
69303
|
+
const displayW = img.w / visW;
|
|
69304
|
+
const displayH = img.h / visH;
|
|
69305
|
+
const offsetX = -(img.cropLeft / 100) * displayW;
|
|
69306
|
+
const offsetY = -(img.cropTop / 100) * displayH;
|
|
69307
|
+
const wrapperStyles = [
|
|
69308
|
+
"position:absolute",
|
|
69309
|
+
`left:${img.x}px`,
|
|
69310
|
+
`top:${img.y}px`,
|
|
69311
|
+
`width:${img.w}px`,
|
|
69312
|
+
`height:${img.h}px`,
|
|
69313
|
+
"overflow:hidden"
|
|
69314
|
+
];
|
|
69315
|
+
if (img.rotation) {
|
|
69316
|
+
wrapperStyles.push(`transform:rotate(${img.rotation}deg)`);
|
|
69317
|
+
wrapperStyles.push("transform-origin:center center");
|
|
69318
|
+
}
|
|
69319
|
+
if (img.borderRadius && img.borderRadius > 0) {
|
|
69320
|
+
wrapperStyles.push(`border-radius:${img.borderRadius}px`);
|
|
69321
|
+
}
|
|
69322
|
+
const imgStyle = `position:absolute;width:${Math.round(displayW)}px;height:${Math.round(displayH)}px;left:${Math.round(offsetX)}px;top:${Math.round(offsetY)}px`;
|
|
69323
|
+
inner += `<div id="${elId}" data-elementType="image" style="${wrapperStyles.join(";")}">`;
|
|
69324
|
+
inner += `<img src="${img.dataUri}"${altAttr} style="${imgStyle}" />`;
|
|
69325
|
+
inner += `</div>
|
|
69326
|
+
`;
|
|
69327
|
+
continue;
|
|
69328
|
+
}
|
|
69329
|
+
}
|
|
69330
|
+
const objectFit = isFullbleed ? "cover" : "contain";
|
|
68540
69331
|
const stylesList = [
|
|
68541
69332
|
"position:absolute",
|
|
68542
69333
|
`left:${img.x}px`,
|
|
@@ -68545,11 +69336,14 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
68545
69336
|
`height:${img.h}px`,
|
|
68546
69337
|
`object-fit:${objectFit}`
|
|
68547
69338
|
];
|
|
69339
|
+
if (img.rotation) {
|
|
69340
|
+
stylesList.push(`transform:rotate(${img.rotation}deg)`);
|
|
69341
|
+
stylesList.push("transform-origin:center center");
|
|
69342
|
+
}
|
|
68548
69343
|
if (img.borderRadius && img.borderRadius > 0) {
|
|
68549
69344
|
stylesList.push(`border-radius:${img.borderRadius}px`);
|
|
68550
69345
|
}
|
|
68551
69346
|
const styles2 = stylesList.join(";");
|
|
68552
|
-
const altAttr = img.alt ? ` alt="${img.alt.replace(/"/g, """)}"` : "";
|
|
68553
69347
|
inner += `<img id="${elId}" data-elementType="image" src="${img.dataUri}"${altAttr} style="${styles2}" />
|
|
68554
69348
|
`;
|
|
68555
69349
|
continue;
|
|
@@ -68638,6 +69432,8 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
68638
69432
|
rStyles.push("font-weight:bold");
|
|
68639
69433
|
if (run.italic)
|
|
68640
69434
|
rStyles.push("font-style:italic");
|
|
69435
|
+
if (run.underline)
|
|
69436
|
+
rStyles.push("text-decoration:underline");
|
|
68641
69437
|
if (run.fontFamily)
|
|
68642
69438
|
rStyles.push(`font-family:${cssFontFamily(run.fontFamily)}`);
|
|
68643
69439
|
if (run.textShadow)
|
|
@@ -68660,6 +69456,11 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
68660
69456
|
`;
|
|
68661
69457
|
continue;
|
|
68662
69458
|
}
|
|
69459
|
+
if (el.kind === "chart") {
|
|
69460
|
+
const chart = el.data;
|
|
69461
|
+
inner += renderChartSvg(chart, elId);
|
|
69462
|
+
continue;
|
|
69463
|
+
}
|
|
68663
69464
|
const shape = el.data;
|
|
68664
69465
|
const styles = [
|
|
68665
69466
|
"position:absolute",
|
|
@@ -68672,6 +69473,12 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
68672
69473
|
if (shape.fill) {
|
|
68673
69474
|
styles.push(`background:${shape.fill}`);
|
|
68674
69475
|
}
|
|
69476
|
+
if (shape.clipPath) {
|
|
69477
|
+
styles.push(`clip-path:${shape.clipPath}`);
|
|
69478
|
+
}
|
|
69479
|
+
if (shape.rotation) {
|
|
69480
|
+
styles.push(`transform:rotate(${shape.rotation}deg)`);
|
|
69481
|
+
}
|
|
68675
69482
|
if (shape.borderRadius) {
|
|
68676
69483
|
styles.push(`border-radius:${shape.borderRadius}px`);
|
|
68677
69484
|
} else if (shape.isEllipse) {
|
|
@@ -68705,7 +69512,10 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
68705
69512
|
else if (shape.verticalAlign === "bottom")
|
|
68706
69513
|
styles.push("justify-content:flex-end");
|
|
68707
69514
|
}
|
|
68708
|
-
if (shape.
|
|
69515
|
+
if (shape.w <= 0 || shape.h <= 0) {
|
|
69516
|
+
continue;
|
|
69517
|
+
}
|
|
69518
|
+
if (shape.paragraphs.length === 0 && !shape.fill && !shape.borderWidth && !shape.isEllipse) {
|
|
68709
69519
|
continue;
|
|
68710
69520
|
}
|
|
68711
69521
|
const hasText = shape.paragraphs.length > 0;
|
|
@@ -68727,8 +69537,15 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
68727
69537
|
pStyles.push(`text-indent:${para.indentPx}px`);
|
|
68728
69538
|
let runHtml = "";
|
|
68729
69539
|
if (para.bulletChar) {
|
|
68730
|
-
const
|
|
68731
|
-
|
|
69540
|
+
const bulletStyleParts = ["margin-right:4px"];
|
|
69541
|
+
if (para.bulletColor)
|
|
69542
|
+
bulletStyleParts.push(`color:${para.bulletColor}`);
|
|
69543
|
+
if (para.bulletFont)
|
|
69544
|
+
bulletStyleParts.push(`font-family:${cssFontFamily(para.bulletFont)}`);
|
|
69545
|
+
const firstRunFontSize = para.runs[0]?.fontSize;
|
|
69546
|
+
if (firstRunFontSize)
|
|
69547
|
+
bulletStyleParts.push(`font-size:${firstRunFontSize}px`);
|
|
69548
|
+
runHtml += `<span style="${bulletStyleParts.join(";")}">${para.bulletChar}</span>`;
|
|
68732
69549
|
}
|
|
68733
69550
|
for (const run of para.runs) {
|
|
68734
69551
|
const rStyles = [];
|
|
@@ -68746,6 +69563,8 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
68746
69563
|
rStyles.push("font-weight:bold");
|
|
68747
69564
|
if (run.italic)
|
|
68748
69565
|
rStyles.push("font-style:italic");
|
|
69566
|
+
if (run.underline)
|
|
69567
|
+
rStyles.push("text-decoration:underline");
|
|
68749
69568
|
if (run.fontFamily)
|
|
68750
69569
|
rStyles.push(`font-family:${cssFontFamily(run.fontFamily)}`);
|
|
68751
69570
|
if (run.textShadow)
|
|
@@ -68763,8 +69582,12 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
|
|
|
68763
69582
|
`;
|
|
68764
69583
|
}
|
|
68765
69584
|
const bg = bgColor ?? "#fff";
|
|
69585
|
+
const offsetPx = Math.round(contentOffsetX);
|
|
69586
|
+
const innerWrapStyle = offsetPx > 0 ? ` style="position:absolute;left:${offsetPx}px;top:0"` : "";
|
|
68766
69587
|
return `<div style="position:relative;width:${TARGET_WIDTH}px;height:${TARGET_HEIGHT}px;overflow:hidden;font-family:'Segoe UI',Arial,sans-serif;background:${bg}">
|
|
68767
|
-
${
|
|
69588
|
+
<div${innerWrapStyle}>
|
|
69589
|
+
${inner}</div>
|
|
69590
|
+
</div>`;
|
|
68768
69591
|
}
|
|
68769
69592
|
async function importPptx(arrayBuffer) {
|
|
68770
69593
|
const zip = await import_jszip2.default.loadAsync(arrayBuffer);
|
|
@@ -68779,6 +69602,8 @@ ${inner}</div>`;
|
|
|
68779
69602
|
const slideWPx = emuToPx2(slideWEmu);
|
|
68780
69603
|
const slideHPx = emuToPx2(slideHEmu);
|
|
68781
69604
|
const scale = Math.min(TARGET_WIDTH / slideWPx, TARGET_HEIGHT / slideHPx);
|
|
69605
|
+
const scaledContentW = slideWPx * scale;
|
|
69606
|
+
const contentOffsetX = (TARGET_WIDTH - scaledContentW) / 2;
|
|
68782
69607
|
const sldIdLst = presDoc.getElementsByTagName("p:sldIdLst")[0];
|
|
68783
69608
|
const visibleSlideRIds = [];
|
|
68784
69609
|
if (sldIdLst) {
|
|
@@ -68827,6 +69652,7 @@ ${inner}</div>`;
|
|
|
68827
69652
|
}
|
|
68828
69653
|
const themeColors = /* @__PURE__ */ new Map();
|
|
68829
69654
|
const themeXml = await zip.file("ppt/theme/theme1.xml")?.async("text");
|
|
69655
|
+
const bgFillStyles = [];
|
|
68830
69656
|
if (themeXml) {
|
|
68831
69657
|
const themeDoc = parser.parseFromString(themeXml, "application/xml");
|
|
68832
69658
|
const clrScheme = themeDoc.getElementsByTagName("a:clrScheme")[0];
|
|
@@ -68872,6 +69698,12 @@ ${inner}</div>`;
|
|
|
68872
69698
|
const lt2Color = themeColors.get("lt2");
|
|
68873
69699
|
if (lt2Color)
|
|
68874
69700
|
themeColors.set("bg2", lt2Color);
|
|
69701
|
+
const bgFillStyleLst = themeDoc.getElementsByTagName("a:bgFillStyleLst")[0];
|
|
69702
|
+
if (bgFillStyleLst) {
|
|
69703
|
+
for (let i = 0; i < bgFillStyleLst.children.length; i++) {
|
|
69704
|
+
bgFillStyles.push(bgFillStyleLst.children[i]);
|
|
69705
|
+
}
|
|
69706
|
+
}
|
|
68875
69707
|
}
|
|
68876
69708
|
let themeFonts;
|
|
68877
69709
|
if (themeXml) {
|
|
@@ -68908,6 +69740,96 @@ ${inner}</div>`;
|
|
|
68908
69740
|
fontStyleBlock = `<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=${fontFamilies}&display=swap">`;
|
|
68909
69741
|
}
|
|
68910
69742
|
const slides = [];
|
|
69743
|
+
let masterBg;
|
|
69744
|
+
let masterDecorativeElements = [];
|
|
69745
|
+
const masterXml = await zip.file("ppt/slideMasters/slideMaster1.xml")?.async("text");
|
|
69746
|
+
if (masterXml) {
|
|
69747
|
+
const masterDoc = parser.parseFromString(masterXml, "application/xml");
|
|
69748
|
+
const masterBgEl = masterDoc.getElementsByTagName("p:bg")[0];
|
|
69749
|
+
if (masterBgEl) {
|
|
69750
|
+
masterBg = extractBgFill(masterBgEl, bgFillStyles, themeColors);
|
|
69751
|
+
}
|
|
69752
|
+
const masterImageMap = /* @__PURE__ */ new Map();
|
|
69753
|
+
const masterRelsXml = await zip.file("ppt/slideMasters/_rels/slideMaster1.xml.rels")?.async("text");
|
|
69754
|
+
if (masterRelsXml) {
|
|
69755
|
+
const relsDoc = parser.parseFromString(masterRelsXml, "application/xml");
|
|
69756
|
+
const rels = relsDoc.getElementsByTagName("Relationship");
|
|
69757
|
+
for (let ri = 0; ri < rels.length; ri++) {
|
|
69758
|
+
const rel = rels[ri];
|
|
69759
|
+
const type2 = rel.getAttribute("Type") ?? "";
|
|
69760
|
+
if (!type2.includes("/image"))
|
|
69761
|
+
continue;
|
|
69762
|
+
const rId = rel.getAttribute("Id");
|
|
69763
|
+
const target = rel.getAttribute("Target");
|
|
69764
|
+
if (!rId || !target)
|
|
69765
|
+
continue;
|
|
69766
|
+
const mediaPath = target.startsWith("../") ? "ppt/" + target.slice(3) : target;
|
|
69767
|
+
const imgFile = zip.file(mediaPath);
|
|
69768
|
+
if (!imgFile)
|
|
69769
|
+
continue;
|
|
69770
|
+
const imgData = await imgFile.async("base64");
|
|
69771
|
+
const ext = mediaPath.split(".").pop()?.toLowerCase() ?? "png";
|
|
69772
|
+
const mime = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : ext === "svg" ? "image/svg+xml" : `image/${ext}`;
|
|
69773
|
+
masterImageMap.set(rId, `data:${mime};base64,${imgData}`);
|
|
69774
|
+
}
|
|
69775
|
+
}
|
|
69776
|
+
const masterSpTree = masterDoc.getElementsByTagName("p:spTree")[0];
|
|
69777
|
+
if (masterSpTree) {
|
|
69778
|
+
masterDecorativeElements = parseDecorativeShapes(masterSpTree, scale, themeColors, masterImageMap, themeFonts);
|
|
69779
|
+
}
|
|
69780
|
+
}
|
|
69781
|
+
const layoutCache = /* @__PURE__ */ new Map();
|
|
69782
|
+
async function getLayoutInfo(layoutPath) {
|
|
69783
|
+
if (layoutCache.has(layoutPath))
|
|
69784
|
+
return layoutCache.get(layoutPath);
|
|
69785
|
+
const result = { bg: void 0, showMasterSp: true, decorativeElements: [] };
|
|
69786
|
+
const layoutXml = await zip.file(layoutPath)?.async("text");
|
|
69787
|
+
if (layoutXml) {
|
|
69788
|
+
const layoutDoc = parser.parseFromString(layoutXml, "application/xml");
|
|
69789
|
+
const cSld = layoutDoc.getElementsByTagName("p:cSld")[0];
|
|
69790
|
+
const rootEl = layoutDoc.documentElement;
|
|
69791
|
+
const showMasterSpAttr = rootEl.getAttribute("showMasterSp");
|
|
69792
|
+
if (showMasterSpAttr === "0") {
|
|
69793
|
+
result.showMasterSp = false;
|
|
69794
|
+
}
|
|
69795
|
+
const layoutBgEl = layoutDoc.getElementsByTagName("p:bg")[0];
|
|
69796
|
+
if (layoutBgEl) {
|
|
69797
|
+
result.bg = extractBgFill(layoutBgEl, bgFillStyles, themeColors);
|
|
69798
|
+
}
|
|
69799
|
+
const layoutImageMap = /* @__PURE__ */ new Map();
|
|
69800
|
+
const layoutBaseName = layoutPath.split("/").pop();
|
|
69801
|
+
const layoutRelsPath = layoutPath.replace(layoutBaseName, `_rels/${layoutBaseName}.rels`);
|
|
69802
|
+
const layoutRelsXml = await zip.file(layoutRelsPath)?.async("text");
|
|
69803
|
+
if (layoutRelsXml) {
|
|
69804
|
+
const relsDoc = parser.parseFromString(layoutRelsXml, "application/xml");
|
|
69805
|
+
const rels = relsDoc.getElementsByTagName("Relationship");
|
|
69806
|
+
for (let ri = 0; ri < rels.length; ri++) {
|
|
69807
|
+
const rel = rels[ri];
|
|
69808
|
+
const type2 = rel.getAttribute("Type") ?? "";
|
|
69809
|
+
if (!type2.includes("/image"))
|
|
69810
|
+
continue;
|
|
69811
|
+
const rId = rel.getAttribute("Id");
|
|
69812
|
+
const target = rel.getAttribute("Target");
|
|
69813
|
+
if (!rId || !target)
|
|
69814
|
+
continue;
|
|
69815
|
+
const mediaPath = target.startsWith("../") ? "ppt/" + target.slice(3) : target;
|
|
69816
|
+
const imgFile = zip.file(mediaPath);
|
|
69817
|
+
if (!imgFile)
|
|
69818
|
+
continue;
|
|
69819
|
+
const imgData = await imgFile.async("base64");
|
|
69820
|
+
const ext = mediaPath.split(".").pop()?.toLowerCase() ?? "png";
|
|
69821
|
+
const mime = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : ext === "svg" ? "image/svg+xml" : `image/${ext}`;
|
|
69822
|
+
layoutImageMap.set(rId, `data:${mime};base64,${imgData}`);
|
|
69823
|
+
}
|
|
69824
|
+
}
|
|
69825
|
+
const layoutSpTree = layoutDoc.getElementsByTagName("p:spTree")[0];
|
|
69826
|
+
if (layoutSpTree) {
|
|
69827
|
+
result.decorativeElements = parseDecorativeShapes(layoutSpTree, scale, themeColors, layoutImageMap, themeFonts);
|
|
69828
|
+
}
|
|
69829
|
+
}
|
|
69830
|
+
layoutCache.set(layoutPath, result);
|
|
69831
|
+
return result;
|
|
69832
|
+
}
|
|
68911
69833
|
for (const slideFile of slideFiles) {
|
|
68912
69834
|
const slideXml = await zip.file(slideFile)?.async("text");
|
|
68913
69835
|
if (!slideXml)
|
|
@@ -68917,24 +69839,47 @@ ${inner}</div>`;
|
|
|
68917
69839
|
let slideBg = void 0;
|
|
68918
69840
|
const bgEl = slideDoc.getElementsByTagName("p:bg")[0];
|
|
68919
69841
|
if (bgEl) {
|
|
68920
|
-
|
|
68921
|
-
if (bgPr) {
|
|
68922
|
-
slideBg = extractFill(bgPr, themeColors);
|
|
68923
|
-
}
|
|
68924
|
-
}
|
|
68925
|
-
if (!spTree) {
|
|
68926
|
-
slides.push(renderSlideHtml([], slideBg));
|
|
68927
|
-
continue;
|
|
69842
|
+
slideBg = extractBgFill(bgEl, bgFillStyles, themeColors);
|
|
68928
69843
|
}
|
|
68929
|
-
const imageMap = /* @__PURE__ */ new Map();
|
|
68930
69844
|
const slideBaseName = slideFile.split("/").pop();
|
|
68931
69845
|
const relsPath = slideFile.replace(slideBaseName, `_rels/${slideBaseName}.rels`);
|
|
68932
69846
|
const relsXml = await zip.file(relsPath)?.async("text");
|
|
69847
|
+
let layoutPath;
|
|
68933
69848
|
if (relsXml) {
|
|
68934
69849
|
const relsDoc = parser.parseFromString(relsXml, "application/xml");
|
|
68935
69850
|
const rels = relsDoc.getElementsByTagName("Relationship");
|
|
68936
|
-
for (let
|
|
68937
|
-
const rel = rels[
|
|
69851
|
+
for (let ri = 0; ri < rels.length; ri++) {
|
|
69852
|
+
const rel = rels[ri];
|
|
69853
|
+
const type2 = rel.getAttribute("Type") ?? "";
|
|
69854
|
+
if (type2.includes("/slideLayout")) {
|
|
69855
|
+
const target = rel.getAttribute("Target");
|
|
69856
|
+
if (target) {
|
|
69857
|
+
layoutPath = target.startsWith("../") ? "ppt/" + target.slice(3) : "ppt/slides/" + target;
|
|
69858
|
+
}
|
|
69859
|
+
break;
|
|
69860
|
+
}
|
|
69861
|
+
}
|
|
69862
|
+
}
|
|
69863
|
+
let layoutInfo;
|
|
69864
|
+
if (layoutPath) {
|
|
69865
|
+
layoutInfo = await getLayoutInfo(layoutPath);
|
|
69866
|
+
}
|
|
69867
|
+
if (!slideBg && layoutInfo?.bg) {
|
|
69868
|
+
slideBg = layoutInfo.bg;
|
|
69869
|
+
}
|
|
69870
|
+
if (!slideBg && masterBg) {
|
|
69871
|
+
slideBg = masterBg;
|
|
69872
|
+
}
|
|
69873
|
+
if (!spTree) {
|
|
69874
|
+
slides.push(renderSlideHtml([], slideBg, contentOffsetX));
|
|
69875
|
+
continue;
|
|
69876
|
+
}
|
|
69877
|
+
const imageMap = /* @__PURE__ */ new Map();
|
|
69878
|
+
const slideRelsDoc = relsXml ? parser.parseFromString(relsXml, "application/xml") : null;
|
|
69879
|
+
if (slideRelsDoc) {
|
|
69880
|
+
const rels = slideRelsDoc.getElementsByTagName("Relationship");
|
|
69881
|
+
for (let ri = 0; ri < rels.length; ri++) {
|
|
69882
|
+
const rel = rels[ri];
|
|
68938
69883
|
const type2 = rel.getAttribute("Type") ?? "";
|
|
68939
69884
|
if (!type2.includes("/image"))
|
|
68940
69885
|
continue;
|
|
@@ -68953,6 +69898,12 @@ ${inner}</div>`;
|
|
|
68953
69898
|
}
|
|
68954
69899
|
}
|
|
68955
69900
|
const elements = [];
|
|
69901
|
+
if (layoutInfo?.showMasterSp !== false) {
|
|
69902
|
+
elements.push(...masterDecorativeElements);
|
|
69903
|
+
}
|
|
69904
|
+
if (layoutInfo?.decorativeElements) {
|
|
69905
|
+
elements.push(...layoutInfo.decorativeElements);
|
|
69906
|
+
}
|
|
68956
69907
|
for (let i = 0; i < spTree.children.length; i++) {
|
|
68957
69908
|
const child = spTree.children[i];
|
|
68958
69909
|
if (child.localName === "sp") {
|
|
@@ -68965,11 +69916,16 @@ ${inner}</div>`;
|
|
|
68965
69916
|
elements.push({ kind: "image", data: img });
|
|
68966
69917
|
} else if (child.localName === "graphicFrame") {
|
|
68967
69918
|
const table = parseTable2(child, scale, themeColors, themeFonts, tableStyleMap);
|
|
68968
|
-
if (table)
|
|
69919
|
+
if (table) {
|
|
68969
69920
|
elements.push({ kind: "table", data: table });
|
|
69921
|
+
} else if (slideRelsDoc) {
|
|
69922
|
+
const chart = await parseChart(child, scale, themeColors, zip, slideRelsDoc, parser);
|
|
69923
|
+
if (chart)
|
|
69924
|
+
elements.push({ kind: "chart", data: chart });
|
|
69925
|
+
}
|
|
68970
69926
|
}
|
|
68971
69927
|
}
|
|
68972
|
-
slides.push(renderSlideHtml(elements, slideBg));
|
|
69928
|
+
slides.push(renderSlideHtml(elements, slideBg, contentOffsetX));
|
|
68973
69929
|
}
|
|
68974
69930
|
if (fontStyleBlock && slides.length > 0) {
|
|
68975
69931
|
slides[0] = fontStyleBlock + slides[0];
|