json2pptx 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +606 -479
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +606 -479
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -41,7 +41,59 @@ __export(index_exports, {
|
|
|
41
41
|
module.exports = __toCommonJS(index_exports);
|
|
42
42
|
var import_pptxgenjs = __toESM(require("pptxgenjs"));
|
|
43
43
|
var import_jszip = __toESM(require("jszip"));
|
|
44
|
-
|
|
44
|
+
|
|
45
|
+
// src/element.ts
|
|
46
|
+
var getElementRange = (element) => {
|
|
47
|
+
var _a, _b, _c, _d, _e, _f;
|
|
48
|
+
let minX = 0;
|
|
49
|
+
let maxX = 0;
|
|
50
|
+
let minY = 0;
|
|
51
|
+
let maxY = 0;
|
|
52
|
+
if (element.type === "line" && element.start && element.end) {
|
|
53
|
+
minX = (_a = element.left) != null ? _a : 0;
|
|
54
|
+
maxX = ((_b = element.left) != null ? _b : 0) + Math.max(element.start[0], element.end[0]);
|
|
55
|
+
minY = (_c = element.top) != null ? _c : 0;
|
|
56
|
+
maxY = ((_d = element.top) != null ? _d : 0) + Math.max(element.start[1], element.end[1]);
|
|
57
|
+
} else if (element.left !== void 0 && element.top !== void 0) {
|
|
58
|
+
minX = element.left;
|
|
59
|
+
minY = element.top;
|
|
60
|
+
maxX = element.left + ((_e = element.width) != null ? _e : 0);
|
|
61
|
+
maxY = element.top + ((_f = element.height) != null ? _f : 0);
|
|
62
|
+
}
|
|
63
|
+
return { minX, maxX, minY, maxY };
|
|
64
|
+
};
|
|
65
|
+
var isLineElement = (element) => element.type === "line";
|
|
66
|
+
var getLineElementPath = (element) => {
|
|
67
|
+
if (!isLineElement(element) || !element.start || !element.end) return "";
|
|
68
|
+
const start = element.start.join(",");
|
|
69
|
+
const end = element.end.join(",");
|
|
70
|
+
const broken = element.broken;
|
|
71
|
+
const broken2 = element.broken2;
|
|
72
|
+
const curve = element.curve;
|
|
73
|
+
const cubic = element.cubic;
|
|
74
|
+
if (broken) {
|
|
75
|
+
const mid = broken.join(",");
|
|
76
|
+
return `M${start} L${mid} L${end}`;
|
|
77
|
+
}
|
|
78
|
+
if (broken2) {
|
|
79
|
+
const { minX, maxX, minY, maxY } = getElementRange(element);
|
|
80
|
+
if (maxX - minX >= maxY - minY) {
|
|
81
|
+
return `M${start} L${broken2[0]},${element.start[1]} L${broken2[0]},${element.end[1]} ${end}`;
|
|
82
|
+
}
|
|
83
|
+
return `M${start} L${element.start[0]},${broken2[1]} L${element.end[0]},${broken2[1]} ${end}`;
|
|
84
|
+
}
|
|
85
|
+
if (curve) {
|
|
86
|
+
const mid = curve.join(",");
|
|
87
|
+
return `M${start} Q${mid} ${end}`;
|
|
88
|
+
}
|
|
89
|
+
if (cubic) {
|
|
90
|
+
const [c1, c2] = cubic;
|
|
91
|
+
const p1 = c1.join(",");
|
|
92
|
+
const p2 = c2.join(",");
|
|
93
|
+
return `M${start} C${p1} ${p2} ${end}`;
|
|
94
|
+
}
|
|
95
|
+
return `M${start} L${end}`;
|
|
96
|
+
};
|
|
45
97
|
|
|
46
98
|
// src/resolveImageData.ts
|
|
47
99
|
var dataUrlRegex = /^data:image\/[^;]+;base64,/;
|
|
@@ -97,6 +149,15 @@ var resolveImageData = async (src) => {
|
|
|
97
149
|
return `data:${contentType};base64,${base64}`;
|
|
98
150
|
};
|
|
99
151
|
|
|
152
|
+
// src/renderers/constants.ts
|
|
153
|
+
var DEFAULT_WIDTH = 1e3;
|
|
154
|
+
var DEFAULT_HEIGHT = 562.5;
|
|
155
|
+
var DEFAULT_FONT_SIZE = 16;
|
|
156
|
+
var DEFAULT_FONT_FACE = "\u5FAE\u8F6F\u96C5\u9ED1";
|
|
157
|
+
|
|
158
|
+
// src/renderers/shared.ts
|
|
159
|
+
var import_tinycolor2 = __toESM(require("tinycolor2"));
|
|
160
|
+
|
|
100
161
|
// src/htmlParser/tags.ts
|
|
101
162
|
var childlessTags = ["style", "script", "template"];
|
|
102
163
|
var closingTags = [
|
|
@@ -534,160 +595,12 @@ var toAST = (str) => {
|
|
|
534
595
|
return format(nodes);
|
|
535
596
|
};
|
|
536
597
|
|
|
537
|
-
// src/
|
|
538
|
-
var
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
2: "M",
|
|
543
|
-
4: "H",
|
|
544
|
-
8: "V",
|
|
545
|
-
16: "L",
|
|
546
|
-
32: "C",
|
|
547
|
-
64: "S",
|
|
548
|
-
128: "Q",
|
|
549
|
-
256: "T",
|
|
550
|
-
512: "A"
|
|
551
|
-
};
|
|
552
|
-
var toPoints = (d) => {
|
|
553
|
-
const pathData = new import_svg_pathdata.SVGPathData(d);
|
|
554
|
-
const points = [];
|
|
555
|
-
for (const item of pathData.commands) {
|
|
556
|
-
const type = typeMap[item.type];
|
|
557
|
-
if (item.type === 2 || item.type === 16) {
|
|
558
|
-
points.push({
|
|
559
|
-
x: item.x,
|
|
560
|
-
y: item.y,
|
|
561
|
-
relative: item.relative,
|
|
562
|
-
type
|
|
563
|
-
});
|
|
564
|
-
}
|
|
565
|
-
if (item.type === 32) {
|
|
566
|
-
points.push({
|
|
567
|
-
x: item.x,
|
|
568
|
-
y: item.y,
|
|
569
|
-
curve: {
|
|
570
|
-
type: "cubic",
|
|
571
|
-
x1: item.x1,
|
|
572
|
-
y1: item.y1,
|
|
573
|
-
x2: item.x2,
|
|
574
|
-
y2: item.y2
|
|
575
|
-
},
|
|
576
|
-
relative: item.relative,
|
|
577
|
-
type
|
|
578
|
-
});
|
|
579
|
-
} else if (item.type === 128) {
|
|
580
|
-
points.push({
|
|
581
|
-
x: item.x,
|
|
582
|
-
y: item.y,
|
|
583
|
-
curve: {
|
|
584
|
-
type: "quadratic",
|
|
585
|
-
x1: item.x1,
|
|
586
|
-
y1: item.y1
|
|
587
|
-
},
|
|
588
|
-
relative: item.relative,
|
|
589
|
-
type
|
|
590
|
-
});
|
|
591
|
-
} else if (item.type === 512) {
|
|
592
|
-
const lastPoint = points[points.length - 1];
|
|
593
|
-
if (!lastPoint || !["M", "L", "Q", "C"].includes(lastPoint.type)) continue;
|
|
594
|
-
const cubicBezierPoints = (0, import_svg_arc_to_cubic_bezier.default)({
|
|
595
|
-
px: lastPoint.x,
|
|
596
|
-
py: lastPoint.y,
|
|
597
|
-
cx: item.x,
|
|
598
|
-
cy: item.y,
|
|
599
|
-
rx: item.rX,
|
|
600
|
-
ry: item.rY,
|
|
601
|
-
xAxisRotation: item.xRot,
|
|
602
|
-
largeArcFlag: item.lArcFlag,
|
|
603
|
-
sweepFlag: item.sweepFlag
|
|
604
|
-
});
|
|
605
|
-
for (const cbPoint of cubicBezierPoints) {
|
|
606
|
-
points.push({
|
|
607
|
-
x: cbPoint.x,
|
|
608
|
-
y: cbPoint.y,
|
|
609
|
-
curve: {
|
|
610
|
-
type: "cubic",
|
|
611
|
-
x1: cbPoint.x1,
|
|
612
|
-
y1: cbPoint.y1,
|
|
613
|
-
x2: cbPoint.x2,
|
|
614
|
-
y2: cbPoint.y2
|
|
615
|
-
},
|
|
616
|
-
relative: false,
|
|
617
|
-
type: "C"
|
|
618
|
-
});
|
|
619
|
-
}
|
|
620
|
-
} else if (item.type === 1) {
|
|
621
|
-
points.push({ close: true, type });
|
|
622
|
-
} else continue;
|
|
623
|
-
}
|
|
624
|
-
return points;
|
|
625
|
-
};
|
|
626
|
-
|
|
627
|
-
// src/element.ts
|
|
628
|
-
var getElementRange = (element) => {
|
|
629
|
-
var _a, _b, _c, _d, _e, _f;
|
|
630
|
-
let minX = 0;
|
|
631
|
-
let maxX = 0;
|
|
632
|
-
let minY = 0;
|
|
633
|
-
let maxY = 0;
|
|
634
|
-
if (element.type === "line" && element.start && element.end) {
|
|
635
|
-
minX = (_a = element.left) != null ? _a : 0;
|
|
636
|
-
maxX = ((_b = element.left) != null ? _b : 0) + Math.max(element.start[0], element.end[0]);
|
|
637
|
-
minY = (_c = element.top) != null ? _c : 0;
|
|
638
|
-
maxY = ((_d = element.top) != null ? _d : 0) + Math.max(element.start[1], element.end[1]);
|
|
639
|
-
} else if (element.left !== void 0 && element.top !== void 0) {
|
|
640
|
-
minX = element.left;
|
|
641
|
-
minY = element.top;
|
|
642
|
-
maxX = element.left + ((_e = element.width) != null ? _e : 0);
|
|
643
|
-
maxY = element.top + ((_f = element.height) != null ? _f : 0);
|
|
644
|
-
}
|
|
645
|
-
return { minX, maxX, minY, maxY };
|
|
646
|
-
};
|
|
647
|
-
var isLineElement = (element) => element.type === "line";
|
|
648
|
-
var getLineElementPath = (element) => {
|
|
649
|
-
if (!isLineElement(element) || !element.start || !element.end) return "";
|
|
650
|
-
const start = element.start.join(",");
|
|
651
|
-
const end = element.end.join(",");
|
|
652
|
-
const broken = element.broken;
|
|
653
|
-
const broken2 = element.broken2;
|
|
654
|
-
const curve = element.curve;
|
|
655
|
-
const cubic = element.cubic;
|
|
656
|
-
if (broken) {
|
|
657
|
-
const mid = broken.join(",");
|
|
658
|
-
return `M${start} L${mid} L${end}`;
|
|
659
|
-
}
|
|
660
|
-
if (broken2) {
|
|
661
|
-
const { minX, maxX, minY, maxY } = getElementRange(element);
|
|
662
|
-
if (maxX - minX >= maxY - minY) {
|
|
663
|
-
return `M${start} L${broken2[0]},${element.start[1]} L${broken2[0]},${element.end[1]} ${end}`;
|
|
664
|
-
}
|
|
665
|
-
return `M${start} L${element.start[0]},${broken2[1]} L${element.end[0]},${broken2[1]} ${end}`;
|
|
666
|
-
}
|
|
667
|
-
if (curve) {
|
|
668
|
-
const mid = curve.join(",");
|
|
669
|
-
return `M${start} Q${mid} ${end}`;
|
|
670
|
-
}
|
|
671
|
-
if (cubic) {
|
|
672
|
-
const [c1, c2] = cubic;
|
|
673
|
-
const p1 = c1.join(",");
|
|
674
|
-
const p2 = c2.join(",");
|
|
675
|
-
return `M${start} C${p1} ${p2} ${end}`;
|
|
676
|
-
}
|
|
677
|
-
return `M${start} L${end}`;
|
|
598
|
+
// src/renderers/shared.ts
|
|
599
|
+
var dashTypeMap = {
|
|
600
|
+
solid: "solid",
|
|
601
|
+
dashed: "dash",
|
|
602
|
+
dotted: "sysDot"
|
|
678
603
|
};
|
|
679
|
-
|
|
680
|
-
// src/index.ts
|
|
681
|
-
var DEFAULT_WIDTH = 1e3;
|
|
682
|
-
var DEFAULT_HEIGHT = 562.5;
|
|
683
|
-
var DEFAULT_FONT_SIZE = 16;
|
|
684
|
-
var DEFAULT_FONT_FACE = "\u5FAE\u8F6F\u96C5\u9ED1";
|
|
685
|
-
var ENABLE_DECK_JSON = true;
|
|
686
|
-
var PPTX_JSON_PAYLOAD_PATH = "json2ppt-editor.json";
|
|
687
|
-
var PPTX_JSON_PAYLOAD_VERSION = 1;
|
|
688
|
-
function sanitizeFileName(name) {
|
|
689
|
-
return name.replace(/[\\/:*?"<>|]/g, "").trim() || "presentation";
|
|
690
|
-
}
|
|
691
604
|
function formatColor(input) {
|
|
692
605
|
if (!input) {
|
|
693
606
|
return {
|
|
@@ -827,114 +740,32 @@ function formatHTML(html, ratioPx2Pt) {
|
|
|
827
740
|
parse2(ast);
|
|
828
741
|
return slices;
|
|
829
742
|
}
|
|
830
|
-
|
|
831
|
-
return
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
x: point.x / ratioPx2Inch * scale.x,
|
|
846
|
-
y: point.y / ratioPx2Inch * scale.y,
|
|
847
|
-
curve: {
|
|
848
|
-
type: "cubic",
|
|
849
|
-
x1: point.curve.x1 / ratioPx2Inch * scale.x,
|
|
850
|
-
y1: point.curve.y1 / ratioPx2Inch * scale.y,
|
|
851
|
-
x2: point.curve.x2 / ratioPx2Inch * scale.x,
|
|
852
|
-
y2: point.curve.y2 / ratioPx2Inch * scale.y
|
|
853
|
-
}
|
|
854
|
-
};
|
|
855
|
-
}
|
|
856
|
-
if (point.curve.type === "quadratic") {
|
|
857
|
-
return {
|
|
858
|
-
x: point.x / ratioPx2Inch * scale.x,
|
|
859
|
-
y: point.y / ratioPx2Inch * scale.y,
|
|
860
|
-
curve: {
|
|
861
|
-
type: "quadratic",
|
|
862
|
-
x1: point.curve.x1 / ratioPx2Inch * scale.x,
|
|
863
|
-
y1: point.curve.y1 / ratioPx2Inch * scale.y
|
|
864
|
-
}
|
|
865
|
-
};
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
return {
|
|
869
|
-
x: point.x / ratioPx2Inch * scale.x,
|
|
870
|
-
y: point.y / ratioPx2Inch * scale.y
|
|
871
|
-
};
|
|
872
|
-
});
|
|
873
|
-
};
|
|
874
|
-
var dashTypeMap = {
|
|
875
|
-
solid: "solid",
|
|
876
|
-
dashed: "dash",
|
|
877
|
-
dotted: "sysDot"
|
|
878
|
-
};
|
|
879
|
-
var stripFillTags = (value) => value.replace(/<a:solidFill>[\s\S]*?<\/a:solidFill>/g, "").replace(/<a:gradFill>[\s\S]*?<\/a:gradFill>/g, "").replace(/<a:blipFill>[\s\S]*?<\/a:blipFill>/g, "").replace(/<a:noFill\s*\/>/g, "").replace(/<a:noFill><\/a:noFill>/g, "");
|
|
880
|
-
var applyPatternFill = (slideXml, objectName, relId) => {
|
|
881
|
-
const nameToken = `name="${objectName}"`;
|
|
882
|
-
let cursor = 0;
|
|
883
|
-
let result = slideXml;
|
|
884
|
-
while (true) {
|
|
885
|
-
const nameIndex = result.indexOf(nameToken, cursor);
|
|
886
|
-
if (nameIndex === -1) break;
|
|
887
|
-
const spStart = result.lastIndexOf("<p:sp", nameIndex);
|
|
888
|
-
const spEnd = result.indexOf("</p:sp>", nameIndex);
|
|
889
|
-
if (spStart === -1 || spEnd === -1) break;
|
|
890
|
-
const spXml = result.slice(spStart, spEnd + "</p:sp>".length);
|
|
891
|
-
const spPrStart = spXml.indexOf("<p:spPr>");
|
|
892
|
-
const spPrEnd = spXml.indexOf("</p:spPr>");
|
|
893
|
-
if (spPrStart === -1 || spPrEnd === -1) {
|
|
894
|
-
cursor = spEnd + 1;
|
|
895
|
-
continue;
|
|
896
|
-
}
|
|
897
|
-
const spPrOpenEnd = spXml.indexOf(">", spPrStart);
|
|
898
|
-
const spPrInner = spXml.slice(spPrOpenEnd + 1, spPrEnd);
|
|
899
|
-
const cleanedInner = stripFillTags(spPrInner);
|
|
900
|
-
const blipFill = `<a:blipFill><a:blip r:embed="${relId}"/><a:srcRect/><a:stretch><a:fillRect/></a:stretch></a:blipFill>`;
|
|
901
|
-
let nextInner = cleanedInner;
|
|
902
|
-
if (cleanedInner.includes("</a:custGeom>")) {
|
|
903
|
-
nextInner = cleanedInner.replace("</a:custGeom>", `</a:custGeom>${blipFill}`);
|
|
904
|
-
} else {
|
|
905
|
-
const lnIndex = cleanedInner.indexOf("<a:ln");
|
|
906
|
-
nextInner = lnIndex === -1 ? `${cleanedInner}${blipFill}` : `${cleanedInner.slice(0, lnIndex)}${blipFill}${cleanedInner.slice(lnIndex)}`;
|
|
907
|
-
}
|
|
908
|
-
const updatedSpXml = spXml.slice(0, spPrOpenEnd + 1) + nextInner + spXml.slice(spPrEnd);
|
|
909
|
-
result = result.slice(0, spStart) + updatedSpXml + result.slice(spEnd + "</p:sp>".length);
|
|
910
|
-
cursor = spStart + updatedSpXml.length;
|
|
743
|
+
function normalizeFontName(value) {
|
|
744
|
+
return value ? value.replace(/^"+|"+$/g, "") : void 0;
|
|
745
|
+
}
|
|
746
|
+
function clampOpacity(value) {
|
|
747
|
+
if (value === void 0) return 1;
|
|
748
|
+
if (!Number.isFinite(value)) return 1;
|
|
749
|
+
return Math.min(1, Math.max(0, value));
|
|
750
|
+
}
|
|
751
|
+
function getOpacityRatio(value) {
|
|
752
|
+
if (!value) return void 0;
|
|
753
|
+
const normalized = value.trim();
|
|
754
|
+
if (!normalized) return void 0;
|
|
755
|
+
if (normalized.endsWith("%")) {
|
|
756
|
+
const percent = Number.parseFloat(normalized);
|
|
757
|
+
return Number.isFinite(percent) ? Math.min(1, Math.max(0, percent / 100)) : void 0;
|
|
911
758
|
}
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
if (!match) return null;
|
|
918
|
-
const mime = match[1];
|
|
919
|
-
const data = match[2];
|
|
920
|
-
const extMap = {
|
|
921
|
-
"image/jpeg": "jpeg",
|
|
922
|
-
"image/jpg": "jpg",
|
|
923
|
-
"image/png": "png",
|
|
924
|
-
"image/gif": "gif",
|
|
925
|
-
"image/svg+xml": "svg",
|
|
926
|
-
"image/webp": "webp",
|
|
927
|
-
"image/bmp": "bmp"
|
|
928
|
-
};
|
|
929
|
-
return { mime, data, ext: (_a = extMap[mime]) != null ? _a : "png" };
|
|
930
|
-
};
|
|
931
|
-
var normalizeFontName = (value) => value ? value.replace(/^"+|"+$/g, "") : void 0;
|
|
932
|
-
var parseFontSize = (value) => {
|
|
759
|
+
const numeric = Number.parseFloat(normalized);
|
|
760
|
+
if (!Number.isFinite(numeric)) return void 0;
|
|
761
|
+
return numeric > 1 ? Math.min(1, Math.max(0, numeric / 100)) : Math.min(1, Math.max(0, numeric));
|
|
762
|
+
}
|
|
763
|
+
function parseFontSize(value) {
|
|
933
764
|
if (!value) return void 0;
|
|
934
765
|
const size = Number.parseFloat(value);
|
|
935
766
|
return Number.isFinite(size) ? size : void 0;
|
|
936
|
-
}
|
|
937
|
-
|
|
767
|
+
}
|
|
768
|
+
function parseTableColor(value) {
|
|
938
769
|
if (!value) return void 0;
|
|
939
770
|
const normalized = value.trim();
|
|
940
771
|
if (!normalized) return void 0;
|
|
@@ -943,8 +774,8 @@ var parseTableColor = (value) => {
|
|
|
943
774
|
color: c.color.replace("#", ""),
|
|
944
775
|
transparency: (1 - c.alpha) * 100
|
|
945
776
|
};
|
|
946
|
-
}
|
|
947
|
-
|
|
777
|
+
}
|
|
778
|
+
function isPlaceholderCell(cell) {
|
|
948
779
|
var _a, _b, _c;
|
|
949
780
|
if (!cell) return false;
|
|
950
781
|
const colspan = (_a = cell.colspan) != null ? _a : 1;
|
|
@@ -954,15 +785,15 @@ var isPlaceholderCell = (cell) => {
|
|
|
954
785
|
const style = cell.style;
|
|
955
786
|
const hasStyle = Boolean(style == null ? void 0 : style.fontname) || Boolean(style == null ? void 0 : style.fontsize) || Boolean(style == null ? void 0 : style.color) || Boolean(style == null ? void 0 : style.backcolor);
|
|
956
787
|
return text.trim() === "" && !hasStyle;
|
|
957
|
-
}
|
|
958
|
-
|
|
788
|
+
}
|
|
789
|
+
function buildTableRows(element, ratioPx2Pt, ratioPx2Inch) {
|
|
959
790
|
var _a, _b;
|
|
960
791
|
const data = element.data;
|
|
961
792
|
if (!data || !data.length) return [];
|
|
962
793
|
const colCount = (_b = (_a = element.colWidths) == null ? void 0 : _a.length) != null ? _b : Math.max(...data.map((row) => row.length));
|
|
963
794
|
const rows = [];
|
|
964
795
|
const skip = new Array(colCount).fill(0);
|
|
965
|
-
data.forEach((row
|
|
796
|
+
data.forEach((row) => {
|
|
966
797
|
var _a2, _b2, _c, _d;
|
|
967
798
|
const cells = [];
|
|
968
799
|
let colIndex = 0;
|
|
@@ -997,6 +828,12 @@ var buildTableRows = (element, ratioPx2Pt) => {
|
|
|
997
828
|
const fontSize = parseFontSize(style.fontsize);
|
|
998
829
|
const fill = parseTableColor(style.backcolor);
|
|
999
830
|
const color = parseTableColor(style.color);
|
|
831
|
+
const cellMargin = [
|
|
832
|
+
6 / ratioPx2Inch,
|
|
833
|
+
8 / ratioPx2Inch,
|
|
834
|
+
6 / ratioPx2Inch,
|
|
835
|
+
8 / ratioPx2Inch
|
|
836
|
+
];
|
|
1000
837
|
const options = {
|
|
1001
838
|
colspan: colSpan > 1 ? colSpan : void 0,
|
|
1002
839
|
rowspan: rowSpan > 1 ? rowSpan : void 0,
|
|
@@ -1006,7 +843,7 @@ var buildTableRows = (element, ratioPx2Pt) => {
|
|
|
1006
843
|
fontSize: fontSize ? fontSize / ratioPx2Pt : void 0,
|
|
1007
844
|
color: color == null ? void 0 : color.color,
|
|
1008
845
|
fill: fill ? { color: fill.color, transparency: fill.transparency } : void 0,
|
|
1009
|
-
margin:
|
|
846
|
+
margin: cellMargin
|
|
1010
847
|
};
|
|
1011
848
|
cells.push({
|
|
1012
849
|
text: (_d = cell.text) != null ? _d : "",
|
|
@@ -1017,8 +854,8 @@ var buildTableRows = (element, ratioPx2Pt) => {
|
|
|
1017
854
|
rows.push(cells);
|
|
1018
855
|
});
|
|
1019
856
|
return rows;
|
|
1020
|
-
}
|
|
1021
|
-
|
|
857
|
+
}
|
|
858
|
+
function getShadowOption(shadow, ratioPx2Pt) {
|
|
1022
859
|
var _a, _b;
|
|
1023
860
|
const c = formatColor((_a = shadow.color) != null ? _a : "#000000");
|
|
1024
861
|
const { h = 0, v = 0 } = shadow;
|
|
@@ -1057,241 +894,531 @@ var getShadowOption = (shadow, ratioPx2Pt) => {
|
|
|
1057
894
|
angle = 225;
|
|
1058
895
|
}
|
|
1059
896
|
return {
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
opacity: c.alpha,
|
|
897
|
+
color: c.color,
|
|
898
|
+
transparency: (1 - c.alpha) * 100,
|
|
1063
899
|
blur: ((_b = shadow.blur) != null ? _b : 0) / ratioPx2Pt,
|
|
1064
900
|
offset,
|
|
1065
901
|
angle
|
|
1066
902
|
};
|
|
1067
|
-
}
|
|
1068
|
-
|
|
903
|
+
}
|
|
904
|
+
function getOutlineOption(outline, ratioPx2Pt, opacity = 1) {
|
|
1069
905
|
const c = formatColor(outline.color || "#000000");
|
|
906
|
+
const alpha = c.alpha * clampOpacity(opacity);
|
|
1070
907
|
return {
|
|
1071
908
|
color: c.color,
|
|
1072
|
-
transparency: (1 -
|
|
909
|
+
transparency: (1 - alpha) * 100,
|
|
1073
910
|
width: (outline.width || 1) / ratioPx2Pt,
|
|
1074
911
|
dashType: outline.style ? dashTypeMap[outline.style] : "solid"
|
|
1075
912
|
};
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
913
|
+
}
|
|
914
|
+
function getElementOpacity(value) {
|
|
915
|
+
return clampOpacity(value);
|
|
916
|
+
}
|
|
917
|
+
function getFilterOpacity(value) {
|
|
918
|
+
return getOpacityRatio(value);
|
|
919
|
+
}
|
|
920
|
+
function getDashTypeMap() {
|
|
921
|
+
return dashTypeMap;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
// src/renderers/background.ts
|
|
925
|
+
function applySlideBackground(slide, slideJson, theme) {
|
|
926
|
+
var _a, _b;
|
|
927
|
+
const backgroundColor = (_b = (_a = slideJson.background) == null ? void 0 : _a.color) != null ? _b : theme == null ? void 0 : theme.backgroundColor;
|
|
928
|
+
if (!backgroundColor) return;
|
|
929
|
+
const c = formatColor(backgroundColor);
|
|
930
|
+
slide.background = { color: c.color, transparency: (1 - c.alpha) * 100 };
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
// src/renderers/layout.ts
|
|
934
|
+
function applyPptxLayout(pptx, width, height) {
|
|
1087
935
|
const viewportRatio = height / width;
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
936
|
+
if (Math.abs(viewportRatio - 0.625) < 1e-3) {
|
|
937
|
+
pptx.layout = "LAYOUT_16x10";
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
if (Math.abs(viewportRatio - 0.75) < 1e-3) {
|
|
941
|
+
pptx.layout = "LAYOUT_4x3";
|
|
942
|
+
return;
|
|
943
|
+
}
|
|
944
|
+
if (Math.abs(viewportRatio - 0.70710678) < 1e-4) {
|
|
1093
945
|
pptx.defineLayout({ name: "A3", width: 10, height: 7.0710678 });
|
|
1094
946
|
pptx.layout = "A3";
|
|
1095
|
-
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
if (Math.abs(viewportRatio - 1.41421356) < 1e-4) {
|
|
1096
950
|
pptx.defineLayout({ name: "A3_V", width: 10, height: 14.1421356 });
|
|
1097
951
|
pptx.layout = "A3_V";
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
952
|
+
return;
|
|
953
|
+
}
|
|
954
|
+
pptx.layout = "LAYOUT_16x9";
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
// src/svgPathParser.ts
|
|
958
|
+
var import_svg_pathdata = require("svg-pathdata");
|
|
959
|
+
var import_svg_arc_to_cubic_bezier = __toESM(require("svg-arc-to-cubic-bezier"));
|
|
960
|
+
var typeMap = {
|
|
961
|
+
1: "Z",
|
|
962
|
+
2: "M",
|
|
963
|
+
4: "H",
|
|
964
|
+
8: "V",
|
|
965
|
+
16: "L",
|
|
966
|
+
32: "C",
|
|
967
|
+
64: "S",
|
|
968
|
+
128: "Q",
|
|
969
|
+
256: "T",
|
|
970
|
+
512: "A"
|
|
971
|
+
};
|
|
972
|
+
var toPoints = (d) => {
|
|
973
|
+
if (!d) return [];
|
|
974
|
+
if (d.includes("NaN") || d.includes("undefined") || d.includes("null")) return [];
|
|
975
|
+
let pathData;
|
|
976
|
+
try {
|
|
977
|
+
pathData = new import_svg_pathdata.SVGPathData(d);
|
|
978
|
+
} catch {
|
|
979
|
+
return [];
|
|
980
|
+
}
|
|
981
|
+
const points = [];
|
|
982
|
+
for (const item of pathData.commands) {
|
|
983
|
+
const type = typeMap[item.type];
|
|
984
|
+
if (item.type === 2 || item.type === 16) {
|
|
985
|
+
points.push({
|
|
986
|
+
x: item.x,
|
|
987
|
+
y: item.y,
|
|
988
|
+
relative: item.relative,
|
|
989
|
+
type
|
|
990
|
+
});
|
|
1105
991
|
}
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
992
|
+
if (item.type === 32) {
|
|
993
|
+
points.push({
|
|
994
|
+
x: item.x,
|
|
995
|
+
y: item.y,
|
|
996
|
+
curve: {
|
|
997
|
+
type: "cubic",
|
|
998
|
+
x1: item.x1,
|
|
999
|
+
y1: item.y1,
|
|
1000
|
+
x2: item.x2,
|
|
1001
|
+
y2: item.y2
|
|
1002
|
+
},
|
|
1003
|
+
relative: item.relative,
|
|
1004
|
+
type
|
|
1005
|
+
});
|
|
1006
|
+
} else if (item.type === 128) {
|
|
1007
|
+
points.push({
|
|
1008
|
+
x: item.x,
|
|
1009
|
+
y: item.y,
|
|
1010
|
+
curve: {
|
|
1011
|
+
type: "quadratic",
|
|
1012
|
+
x1: item.x1,
|
|
1013
|
+
y1: item.y1
|
|
1014
|
+
},
|
|
1015
|
+
relative: item.relative,
|
|
1016
|
+
type
|
|
1017
|
+
});
|
|
1018
|
+
} else if (item.type === 512) {
|
|
1019
|
+
const lastPoint = points[points.length - 1];
|
|
1020
|
+
if (!lastPoint || !["M", "L", "Q", "C"].includes(lastPoint.type)) continue;
|
|
1021
|
+
const cubicBezierPoints = (0, import_svg_arc_to_cubic_bezier.default)({
|
|
1022
|
+
px: lastPoint.x,
|
|
1023
|
+
py: lastPoint.y,
|
|
1024
|
+
cx: item.x,
|
|
1025
|
+
cy: item.y,
|
|
1026
|
+
rx: item.rX,
|
|
1027
|
+
ry: item.rY,
|
|
1028
|
+
xAxisRotation: item.xRot,
|
|
1029
|
+
largeArcFlag: item.lArcFlag,
|
|
1030
|
+
sweepFlag: item.sweepFlag
|
|
1031
|
+
});
|
|
1032
|
+
for (const cbPoint of cubicBezierPoints) {
|
|
1033
|
+
points.push({
|
|
1034
|
+
x: cbPoint.x,
|
|
1035
|
+
y: cbPoint.y,
|
|
1036
|
+
curve: {
|
|
1037
|
+
type: "cubic",
|
|
1038
|
+
x1: cbPoint.x1,
|
|
1039
|
+
y1: cbPoint.y1,
|
|
1040
|
+
x2: cbPoint.x2,
|
|
1041
|
+
y2: cbPoint.y2
|
|
1042
|
+
},
|
|
1043
|
+
relative: false,
|
|
1044
|
+
type: "C"
|
|
1045
|
+
});
|
|
1146
1046
|
}
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1047
|
+
} else if (item.type === 1) {
|
|
1048
|
+
points.push({ close: true, type });
|
|
1049
|
+
} else continue;
|
|
1050
|
+
}
|
|
1051
|
+
return points;
|
|
1052
|
+
};
|
|
1053
|
+
|
|
1054
|
+
// src/renderers/points.ts
|
|
1055
|
+
function formatPoints(points, ratioPx2Inch, scale = { x: 1, y: 1 }) {
|
|
1056
|
+
return points.map((point) => {
|
|
1057
|
+
if ("close" in point) {
|
|
1058
|
+
return { close: true };
|
|
1059
|
+
}
|
|
1060
|
+
if (point.type === "M") {
|
|
1061
|
+
return {
|
|
1062
|
+
x: point.x / ratioPx2Inch * scale.x,
|
|
1063
|
+
y: point.y / ratioPx2Inch * scale.y,
|
|
1064
|
+
moveTo: true
|
|
1065
|
+
};
|
|
1066
|
+
}
|
|
1067
|
+
if (point.curve) {
|
|
1068
|
+
if (point.curve.type === "cubic") {
|
|
1069
|
+
return {
|
|
1070
|
+
x: point.x / ratioPx2Inch * scale.x,
|
|
1071
|
+
y: point.y / ratioPx2Inch * scale.y,
|
|
1072
|
+
curve: {
|
|
1073
|
+
type: "cubic",
|
|
1074
|
+
x1: point.curve.x1 / ratioPx2Inch * scale.x,
|
|
1075
|
+
y1: point.curve.y1 / ratioPx2Inch * scale.y,
|
|
1076
|
+
x2: point.curve.x2 / ratioPx2Inch * scale.x,
|
|
1077
|
+
y2: point.curve.y2 / ratioPx2Inch * scale.y
|
|
1078
|
+
}
|
|
1153
1079
|
};
|
|
1154
|
-
if (isBase64Image(element.src)) options.data = element.src;
|
|
1155
|
-
else options.data = await resolveImageData(element.src);
|
|
1156
|
-
if (element.flipH) options.flipH = element.flipH;
|
|
1157
|
-
if (element.flipV) options.flipV = element.flipV;
|
|
1158
|
-
if (element.rotate) options.rotate = element.rotate;
|
|
1159
|
-
if ((_p = element.filters) == null ? void 0 : _p.opacity) {
|
|
1160
|
-
options.transparency = 100 - parseInt(element.filters.opacity, 10);
|
|
1161
|
-
}
|
|
1162
|
-
if ((_q = element.clip) == null ? void 0 : _q.range) {
|
|
1163
|
-
if (element.clip.shape === "ellipse") options.rounding = true;
|
|
1164
|
-
const [start, end] = element.clip.range;
|
|
1165
|
-
const [startX, startY] = start;
|
|
1166
|
-
const [endX, endY] = end;
|
|
1167
|
-
const originW = ((_r = element.width) != null ? _r : 0) / ((endX - startX) / ratioPx2Inch);
|
|
1168
|
-
const originH = ((_s = element.height) != null ? _s : 0) / ((endY - startY) / ratioPx2Inch);
|
|
1169
|
-
options.w = originW / ratioPx2Inch;
|
|
1170
|
-
options.h = originH / ratioPx2Inch;
|
|
1171
|
-
options.sizing = {
|
|
1172
|
-
type: "crop",
|
|
1173
|
-
x: startX / ratioPx2Inch * (originW / ratioPx2Inch),
|
|
1174
|
-
y: startY / ratioPx2Inch * (originH / ratioPx2Inch),
|
|
1175
|
-
w: (endX - startX) / ratioPx2Inch * (originW / ratioPx2Inch),
|
|
1176
|
-
h: (endY - startY) / ratioPx2Inch * (originH / ratioPx2Inch)
|
|
1177
|
-
};
|
|
1178
|
-
}
|
|
1179
|
-
slide.addImage(options);
|
|
1180
|
-
continue;
|
|
1181
1080
|
}
|
|
1182
|
-
if (
|
|
1183
|
-
|
|
1184
|
-
x:
|
|
1185
|
-
y:
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
const opacity = element.opacity === void 0 ? 1 : element.opacity;
|
|
1191
|
-
const options = {
|
|
1192
|
-
x: ((_v = element.left) != null ? _v : 0) / ratioPx2Inch,
|
|
1193
|
-
y: ((_w = element.top) != null ? _w : 0) / ratioPx2Inch,
|
|
1194
|
-
w: ((_x = element.width) != null ? _x : 0) / ratioPx2Inch,
|
|
1195
|
-
h: ((_y = element.height) != null ? _y : 0) / ratioPx2Inch,
|
|
1196
|
-
points
|
|
1197
|
-
};
|
|
1198
|
-
if (pattern) {
|
|
1199
|
-
const objectName = `pattern-${slideIndex}-${(_z = element.id) != null ? _z : elementIndex}`;
|
|
1200
|
-
options.objectName = objectName;
|
|
1201
|
-
options.fill = { color: "FFFFFF", transparency: 100 };
|
|
1202
|
-
patternShapes.push({ slideIndex, objectName, dataUrl: pattern });
|
|
1203
|
-
} else if (hasFill) {
|
|
1204
|
-
const fillColor = formatColor(element.fill || "#000000");
|
|
1205
|
-
options.fill = {
|
|
1206
|
-
color: fillColor.color,
|
|
1207
|
-
transparency: (1 - fillColor.alpha * opacity) * 100
|
|
1208
|
-
};
|
|
1209
|
-
} else {
|
|
1210
|
-
options.fill = { color: "FFFFFF", transparency: 100 };
|
|
1211
|
-
}
|
|
1212
|
-
if (element.flipH) options.flipH = element.flipH;
|
|
1213
|
-
if (element.flipV) options.flipV = element.flipV;
|
|
1214
|
-
if (element.shadow) options.shadow = getShadowOption(element.shadow, ratioPx2Pt);
|
|
1215
|
-
if ((_A = element.outline) == null ? void 0 : _A.width) options.line = getOutlineOption(element.outline, ratioPx2Pt);
|
|
1216
|
-
if (element.rotate) options.rotate = element.rotate;
|
|
1217
|
-
slide.addShape("custGeom", options);
|
|
1218
|
-
if ((_B = element.text) == null ? void 0 : _B.content) {
|
|
1219
|
-
const textProps = formatHTML(element.text.content, ratioPx2Pt);
|
|
1220
|
-
const textOptions = {
|
|
1221
|
-
x: ((_C = element.left) != null ? _C : 0) / ratioPx2Inch,
|
|
1222
|
-
y: ((_D = element.top) != null ? _D : 0) / ratioPx2Inch,
|
|
1223
|
-
w: ((_E = element.width) != null ? _E : 0) / ratioPx2Inch,
|
|
1224
|
-
h: ((_F = element.height) != null ? _F : 0) / ratioPx2Inch,
|
|
1225
|
-
fontSize: DEFAULT_FONT_SIZE / ratioPx2Pt,
|
|
1226
|
-
fontFace: element.text.defaultFontName || DEFAULT_FONT_FACE,
|
|
1227
|
-
color: "#000000",
|
|
1228
|
-
paraSpaceBefore: 5 / ratioPx2Pt,
|
|
1229
|
-
valign: element.text.align,
|
|
1230
|
-
fill: { color: "FFFFFF", transparency: 100 }
|
|
1231
|
-
};
|
|
1232
|
-
textOptions.margin = 0;
|
|
1233
|
-
if (element.rotate) textOptions.rotate = element.rotate;
|
|
1234
|
-
if (element.text.defaultColor) {
|
|
1235
|
-
textOptions.color = formatColor(element.text.defaultColor).color;
|
|
1081
|
+
if (point.curve.type === "quadratic") {
|
|
1082
|
+
return {
|
|
1083
|
+
x: point.x / ratioPx2Inch * scale.x,
|
|
1084
|
+
y: point.y / ratioPx2Inch * scale.y,
|
|
1085
|
+
curve: {
|
|
1086
|
+
type: "quadratic",
|
|
1087
|
+
x1: point.curve.x1 / ratioPx2Inch * scale.x,
|
|
1088
|
+
y1: point.curve.y1 / ratioPx2Inch * scale.y
|
|
1236
1089
|
}
|
|
1237
|
-
slide.addText(textProps, textOptions);
|
|
1238
|
-
}
|
|
1239
|
-
continue;
|
|
1240
|
-
}
|
|
1241
|
-
if (element.type === "line" && element.start && element.end) {
|
|
1242
|
-
const path = getLineElementPath(element);
|
|
1243
|
-
const points = formatPoints(toPoints(path), ratioPx2Inch);
|
|
1244
|
-
const { minX, maxX, minY, maxY } = getElementRange(element);
|
|
1245
|
-
const c = formatColor(element.color || "#000000");
|
|
1246
|
-
const options = {
|
|
1247
|
-
x: ((_G = element.left) != null ? _G : 0) / ratioPx2Inch,
|
|
1248
|
-
y: ((_H = element.top) != null ? _H : 0) / ratioPx2Inch,
|
|
1249
|
-
w: (maxX - minX) / ratioPx2Inch,
|
|
1250
|
-
h: (maxY - minY) / ratioPx2Inch,
|
|
1251
|
-
line: {
|
|
1252
|
-
color: c.color,
|
|
1253
|
-
transparency: (1 - c.alpha) * 100,
|
|
1254
|
-
width: ((_I = element.width) != null ? _I : 1) / ratioPx2Pt,
|
|
1255
|
-
dashType: element.style ? dashTypeMap[element.style] : "solid",
|
|
1256
|
-
beginArrowType: ((_J = element.points) == null ? void 0 : _J[0]) ? "arrow" : "none",
|
|
1257
|
-
endArrowType: ((_K = element.points) == null ? void 0 : _K[1]) ? "arrow" : "none"
|
|
1258
|
-
},
|
|
1259
|
-
points
|
|
1260
1090
|
};
|
|
1261
|
-
if (element.shadow) options.shadow = getShadowOption(element.shadow, ratioPx2Pt);
|
|
1262
|
-
slide.addShape("custGeom", options);
|
|
1263
|
-
}
|
|
1264
|
-
if (element.type === "table") {
|
|
1265
|
-
const rows = buildTableRows(element, ratioPx2Pt);
|
|
1266
|
-
if (!rows.length) continue;
|
|
1267
|
-
const colWidths = element.colWidths;
|
|
1268
|
-
const colW = colWidths ? colWidths.map((ratio) => {
|
|
1269
|
-
var _a2;
|
|
1270
|
-
return ((_a2 = element.width) != null ? _a2 : 0) * ratio / ratioPx2Inch;
|
|
1271
|
-
}) : void 0;
|
|
1272
|
-
const rowCount = rows.length || 1;
|
|
1273
|
-
const baseRowHeight = ((_L = element.height) != null ? _L : 0) / rowCount / ratioPx2Inch;
|
|
1274
|
-
const minRowHeight = element.cellMinHeight ? element.cellMinHeight / ratioPx2Inch : void 0;
|
|
1275
|
-
const rowH = minRowHeight ? new Array(rowCount).fill(Math.max(minRowHeight, baseRowHeight)) : void 0;
|
|
1276
|
-
const outline = element.outline;
|
|
1277
|
-
const border = (outline == null ? void 0 : outline.width) || (outline == null ? void 0 : outline.color) ? {
|
|
1278
|
-
pt: ((_M = outline.width) != null ? _M : 1) / ratioPx2Pt,
|
|
1279
|
-
color: formatColor(outline.color || "#000000").color.replace("#", "")
|
|
1280
|
-
} : void 0;
|
|
1281
|
-
slide.addTable(rows, {
|
|
1282
|
-
x: ((_N = element.left) != null ? _N : 0) / ratioPx2Inch,
|
|
1283
|
-
y: ((_O = element.top) != null ? _O : 0) / ratioPx2Inch,
|
|
1284
|
-
w: ((_P = element.width) != null ? _P : 0) / ratioPx2Inch,
|
|
1285
|
-
h: ((_Q = element.height) != null ? _Q : 0) / ratioPx2Inch,
|
|
1286
|
-
colW,
|
|
1287
|
-
rowH,
|
|
1288
|
-
border,
|
|
1289
|
-
margin: 0
|
|
1290
|
-
});
|
|
1291
1091
|
}
|
|
1292
1092
|
}
|
|
1093
|
+
return {
|
|
1094
|
+
x: point.x / ratioPx2Inch * scale.x,
|
|
1095
|
+
y: point.y / ratioPx2Inch * scale.y
|
|
1096
|
+
};
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
// src/renderers/utils.ts
|
|
1101
|
+
function isBase64Image(url) {
|
|
1102
|
+
const regex = /^data:image\/[^;]+;base64,/;
|
|
1103
|
+
return regex.test(url);
|
|
1104
|
+
}
|
|
1105
|
+
function getLineArrowType(value) {
|
|
1106
|
+
if (value === "arrow") return "arrow";
|
|
1107
|
+
if (value === "dot") return "oval";
|
|
1108
|
+
return "none";
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
// src/renderers/elements.ts
|
|
1112
|
+
function addTextElement(slide, element, template, ratioPx2Pt, ratioPx2Inch, textPadding) {
|
|
1113
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1114
|
+
if (element.type !== "text" || !element.content) return;
|
|
1115
|
+
const textProps = formatHTML(element.content, ratioPx2Pt);
|
|
1116
|
+
const opacity = getElementOpacity(element.opacity);
|
|
1117
|
+
const options = {
|
|
1118
|
+
x: ((_a = element.left) != null ? _a : 0) / ratioPx2Inch,
|
|
1119
|
+
y: ((_b = element.top) != null ? _b : 0) / ratioPx2Inch,
|
|
1120
|
+
w: ((_c = element.width) != null ? _c : 0) / ratioPx2Inch,
|
|
1121
|
+
h: ((_d = element.height) != null ? _d : 0) / ratioPx2Inch,
|
|
1122
|
+
fontSize: DEFAULT_FONT_SIZE / ratioPx2Pt,
|
|
1123
|
+
fontFace: element.defaultFontName || ((_e = template.theme) == null ? void 0 : _e.fontName) || DEFAULT_FONT_FACE,
|
|
1124
|
+
color: "#000000",
|
|
1125
|
+
valign: "top",
|
|
1126
|
+
margin: textPadding,
|
|
1127
|
+
paraSpaceBefore: 0,
|
|
1128
|
+
lineSpacingMultiple: 1.5,
|
|
1129
|
+
fit: "none"
|
|
1130
|
+
};
|
|
1131
|
+
if (element.rotate) options.rotate = element.rotate;
|
|
1132
|
+
if (element.wordSpace) options.charSpacing = element.wordSpace / ratioPx2Pt;
|
|
1133
|
+
if (element.lineHeight) options.lineSpacingMultiple = element.lineHeight;
|
|
1134
|
+
if (element.fill) {
|
|
1135
|
+
const c = formatColor(element.fill);
|
|
1136
|
+
options.fill = {
|
|
1137
|
+
color: c.color,
|
|
1138
|
+
transparency: (1 - c.alpha * opacity) * 100
|
|
1139
|
+
};
|
|
1140
|
+
} else {
|
|
1141
|
+
options.fill = { color: "FFFFFF", transparency: 100 };
|
|
1142
|
+
}
|
|
1143
|
+
if (element.defaultColor) options.color = formatColor(element.defaultColor).color;
|
|
1144
|
+
if (element.shadow) options.shadow = getShadowOption(element.shadow, ratioPx2Pt);
|
|
1145
|
+
if ((_f = element.outline) == null ? void 0 : _f.width) {
|
|
1146
|
+
options.line = getOutlineOption(element.outline, ratioPx2Pt, opacity);
|
|
1147
|
+
}
|
|
1148
|
+
if (element.opacity !== void 0) options.transparency = (1 - opacity) * 100;
|
|
1149
|
+
if (element.paragraphSpace !== void 0) {
|
|
1150
|
+
options.paraSpaceBefore = element.paragraphSpace / ratioPx2Pt;
|
|
1151
|
+
}
|
|
1152
|
+
if (element.vertical) options.vert = "eaVert";
|
|
1153
|
+
if (element.flipH) options.flipH = element.flipH;
|
|
1154
|
+
if (element.flipV) options.flipV = element.flipV;
|
|
1155
|
+
slide.addText(textProps, options);
|
|
1156
|
+
}
|
|
1157
|
+
async function addImageElement(slide, element, ratioPx2Inch) {
|
|
1158
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1159
|
+
if (element.type !== "image" || !element.src) return;
|
|
1160
|
+
const options = {
|
|
1161
|
+
x: ((_a = element.left) != null ? _a : 0) / ratioPx2Inch,
|
|
1162
|
+
y: ((_b = element.top) != null ? _b : 0) / ratioPx2Inch,
|
|
1163
|
+
w: ((_c = element.width) != null ? _c : 0) / ratioPx2Inch,
|
|
1164
|
+
h: ((_d = element.height) != null ? _d : 0) / ratioPx2Inch
|
|
1165
|
+
};
|
|
1166
|
+
if (isBase64Image(element.src)) options.data = element.src;
|
|
1167
|
+
else options.data = await resolveImageData(element.src);
|
|
1168
|
+
if (element.flipH) options.flipH = element.flipH;
|
|
1169
|
+
if (element.flipV) options.flipV = element.flipV;
|
|
1170
|
+
if (element.rotate) options.rotate = element.rotate;
|
|
1171
|
+
const filterOpacity = (_f = getFilterOpacity((_e = element.filters) == null ? void 0 : _e.opacity)) != null ? _f : 1;
|
|
1172
|
+
const elementOpacity = getElementOpacity(element.opacity);
|
|
1173
|
+
const imageOpacity = filterOpacity * elementOpacity;
|
|
1174
|
+
if (imageOpacity !== 1) {
|
|
1175
|
+
options.transparency = (1 - imageOpacity) * 100;
|
|
1176
|
+
}
|
|
1177
|
+
if ((_g = element.clip) == null ? void 0 : _g.range) {
|
|
1178
|
+
if (element.clip.shape === "ellipse") options.rounding = true;
|
|
1179
|
+
const [start, end] = element.clip.range;
|
|
1180
|
+
const [startX, startY] = start;
|
|
1181
|
+
const [endX, endY] = end;
|
|
1182
|
+
const originW = ((_h = element.width) != null ? _h : 0) / ((endX - startX) / ratioPx2Inch);
|
|
1183
|
+
const originH = ((_i = element.height) != null ? _i : 0) / ((endY - startY) / ratioPx2Inch);
|
|
1184
|
+
options.w = originW / ratioPx2Inch;
|
|
1185
|
+
options.h = originH / ratioPx2Inch;
|
|
1186
|
+
options.sizing = {
|
|
1187
|
+
type: "crop",
|
|
1188
|
+
x: startX / ratioPx2Inch * (originW / ratioPx2Inch),
|
|
1189
|
+
y: startY / ratioPx2Inch * (originH / ratioPx2Inch),
|
|
1190
|
+
w: (endX - startX) / ratioPx2Inch * (originW / ratioPx2Inch),
|
|
1191
|
+
h: (endY - startY) / ratioPx2Inch * (originH / ratioPx2Inch)
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
slide.addImage(options);
|
|
1195
|
+
}
|
|
1196
|
+
function addShapeElement(slide, element, ratioPx2Pt, ratioPx2Inch, slideIndex, elementIndex, patternShapes) {
|
|
1197
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
1198
|
+
if (element.type !== "shape" || !element.path || !element.viewBox) return;
|
|
1199
|
+
const scale = {
|
|
1200
|
+
x: ((_a = element.width) != null ? _a : 0) / element.viewBox[0],
|
|
1201
|
+
y: ((_b = element.height) != null ? _b : 0) / element.viewBox[1]
|
|
1202
|
+
};
|
|
1203
|
+
const rawPoints = toPoints(element.path);
|
|
1204
|
+
if (!rawPoints.length) return;
|
|
1205
|
+
const points = formatPoints(rawPoints, ratioPx2Inch, scale);
|
|
1206
|
+
const pattern = element.pattern;
|
|
1207
|
+
const hasFill = typeof element.fill === "string" ? element.fill.trim().length > 0 : false;
|
|
1208
|
+
const opacity = getElementOpacity(element.opacity);
|
|
1209
|
+
const options = {
|
|
1210
|
+
x: ((_c = element.left) != null ? _c : 0) / ratioPx2Inch,
|
|
1211
|
+
y: ((_d = element.top) != null ? _d : 0) / ratioPx2Inch,
|
|
1212
|
+
w: ((_e = element.width) != null ? _e : 0) / ratioPx2Inch,
|
|
1213
|
+
h: ((_f = element.height) != null ? _f : 0) / ratioPx2Inch,
|
|
1214
|
+
points
|
|
1215
|
+
};
|
|
1216
|
+
if (pattern) {
|
|
1217
|
+
const objectName = `pattern-${slideIndex}-${(_g = element.id) != null ? _g : elementIndex}`;
|
|
1218
|
+
options.objectName = objectName;
|
|
1219
|
+
options.fill = { color: "FFFFFF", transparency: 100 };
|
|
1220
|
+
patternShapes.push({ slideIndex, objectName, dataUrl: pattern });
|
|
1221
|
+
} else if (hasFill) {
|
|
1222
|
+
const fillColor = formatColor(element.fill || "#000000");
|
|
1223
|
+
options.fill = {
|
|
1224
|
+
color: fillColor.color,
|
|
1225
|
+
transparency: (1 - fillColor.alpha * opacity) * 100
|
|
1226
|
+
};
|
|
1227
|
+
} else {
|
|
1228
|
+
options.fill = { color: "FFFFFF", transparency: 100 };
|
|
1229
|
+
}
|
|
1230
|
+
if (element.flipH) options.flipH = element.flipH;
|
|
1231
|
+
if (element.flipV) options.flipV = element.flipV;
|
|
1232
|
+
if (element.shadow) options.shadow = getShadowOption(element.shadow, ratioPx2Pt);
|
|
1233
|
+
if ((_h = element.outline) == null ? void 0 : _h.width) {
|
|
1234
|
+
options.line = getOutlineOption(element.outline, ratioPx2Pt, opacity);
|
|
1235
|
+
}
|
|
1236
|
+
if (element.rotate) options.rotate = element.rotate;
|
|
1237
|
+
slide.addShape("custGeom", options);
|
|
1238
|
+
if (!((_i = element.text) == null ? void 0 : _i.content)) return;
|
|
1239
|
+
const textProps = formatHTML(element.text.content, ratioPx2Pt);
|
|
1240
|
+
const textOptions = {
|
|
1241
|
+
x: ((_j = element.left) != null ? _j : 0) / ratioPx2Inch,
|
|
1242
|
+
y: ((_k = element.top) != null ? _k : 0) / ratioPx2Inch,
|
|
1243
|
+
w: ((_l = element.width) != null ? _l : 0) / ratioPx2Inch,
|
|
1244
|
+
h: ((_m = element.height) != null ? _m : 0) / ratioPx2Inch,
|
|
1245
|
+
fontSize: DEFAULT_FONT_SIZE / ratioPx2Pt,
|
|
1246
|
+
fontFace: element.text.defaultFontName || DEFAULT_FONT_FACE,
|
|
1247
|
+
color: "#000000",
|
|
1248
|
+
paraSpaceBefore: 0,
|
|
1249
|
+
valign: element.text.align,
|
|
1250
|
+
fill: { color: "FFFFFF", transparency: 100 },
|
|
1251
|
+
fit: "none"
|
|
1252
|
+
};
|
|
1253
|
+
textOptions.margin = 0;
|
|
1254
|
+
if (element.rotate) textOptions.rotate = element.rotate;
|
|
1255
|
+
if (element.text.defaultColor) {
|
|
1256
|
+
textOptions.color = formatColor(element.text.defaultColor).color;
|
|
1257
|
+
}
|
|
1258
|
+
if (element.opacity !== void 0) {
|
|
1259
|
+
textOptions.transparency = (1 - opacity) * 100;
|
|
1260
|
+
}
|
|
1261
|
+
if (element.flipH) textOptions.flipH = element.flipH;
|
|
1262
|
+
if (element.flipV) textOptions.flipV = element.flipV;
|
|
1263
|
+
slide.addText(textProps, textOptions);
|
|
1264
|
+
}
|
|
1265
|
+
function addLineElement(slide, element, ratioPx2Pt, ratioPx2Inch) {
|
|
1266
|
+
var _a, _b, _c, _d;
|
|
1267
|
+
if (element.type !== "line" || !element.start || !element.end) return;
|
|
1268
|
+
const path = getLineElementPath(element);
|
|
1269
|
+
const rawPoints = toPoints(path);
|
|
1270
|
+
if (!rawPoints.length) return;
|
|
1271
|
+
const points = formatPoints(rawPoints, ratioPx2Inch);
|
|
1272
|
+
const { minX, maxX, minY, maxY } = getElementRange(element);
|
|
1273
|
+
const c = formatColor(element.color || "#000000");
|
|
1274
|
+
const opacity = getElementOpacity(element.opacity);
|
|
1275
|
+
const pointsMeta = (_a = element.points) != null ? _a : [];
|
|
1276
|
+
const dashTypeMap2 = getDashTypeMap();
|
|
1277
|
+
const options = {
|
|
1278
|
+
x: ((_b = element.left) != null ? _b : 0) / ratioPx2Inch,
|
|
1279
|
+
y: ((_c = element.top) != null ? _c : 0) / ratioPx2Inch,
|
|
1280
|
+
w: (maxX - minX) / ratioPx2Inch,
|
|
1281
|
+
h: (maxY - minY) / ratioPx2Inch,
|
|
1282
|
+
line: {
|
|
1283
|
+
color: c.color,
|
|
1284
|
+
transparency: (1 - c.alpha * opacity) * 100,
|
|
1285
|
+
width: ((_d = element.width) != null ? _d : 1) / ratioPx2Pt,
|
|
1286
|
+
dashType: element.style ? dashTypeMap2[element.style] : "solid",
|
|
1287
|
+
beginArrowType: getLineArrowType(pointsMeta[0]),
|
|
1288
|
+
endArrowType: getLineArrowType(pointsMeta[1])
|
|
1289
|
+
},
|
|
1290
|
+
points
|
|
1291
|
+
};
|
|
1292
|
+
if (element.flipH) options.flipH = element.flipH;
|
|
1293
|
+
if (element.flipV) options.flipV = element.flipV;
|
|
1294
|
+
if (element.shadow) options.shadow = getShadowOption(element.shadow, ratioPx2Pt);
|
|
1295
|
+
slide.addShape("custGeom", options);
|
|
1296
|
+
}
|
|
1297
|
+
function addTableElement(slide, element, ratioPx2Pt, ratioPx2Inch) {
|
|
1298
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1299
|
+
if (element.type !== "table") return;
|
|
1300
|
+
const rows = buildTableRows(element, ratioPx2Pt, ratioPx2Inch);
|
|
1301
|
+
if (!rows.length) return;
|
|
1302
|
+
const colWidths = element.colWidths;
|
|
1303
|
+
const colW = colWidths ? colWidths.map((ratio) => {
|
|
1304
|
+
var _a2;
|
|
1305
|
+
return ((_a2 = element.width) != null ? _a2 : 0) * ratio / ratioPx2Inch;
|
|
1306
|
+
}) : void 0;
|
|
1307
|
+
const rowCount = rows.length || 1;
|
|
1308
|
+
const baseRowHeight = ((_a = element.height) != null ? _a : 0) / rowCount / ratioPx2Inch;
|
|
1309
|
+
const minRowHeight = element.cellMinHeight ? element.cellMinHeight / ratioPx2Inch : void 0;
|
|
1310
|
+
const rowH = minRowHeight ? new Array(rowCount).fill(Math.max(minRowHeight, baseRowHeight)) : void 0;
|
|
1311
|
+
const outline = element.outline;
|
|
1312
|
+
const border = (outline == null ? void 0 : outline.width) || (outline == null ? void 0 : outline.color) ? {
|
|
1313
|
+
pt: ((_b = outline.width) != null ? _b : 1) / ratioPx2Pt,
|
|
1314
|
+
color: formatColor(outline.color || "#000000").color.replace("#", "")
|
|
1315
|
+
} : {
|
|
1316
|
+
pt: 1 / ratioPx2Pt,
|
|
1317
|
+
color: "DDDDDD"
|
|
1318
|
+
};
|
|
1319
|
+
slide.addTable(rows, {
|
|
1320
|
+
x: ((_c = element.left) != null ? _c : 0) / ratioPx2Inch,
|
|
1321
|
+
y: ((_d = element.top) != null ? _d : 0) / ratioPx2Inch,
|
|
1322
|
+
w: ((_e = element.width) != null ? _e : 0) / ratioPx2Inch,
|
|
1323
|
+
h: ((_f = element.height) != null ? _f : 0) / ratioPx2Inch,
|
|
1324
|
+
colW,
|
|
1325
|
+
rowH,
|
|
1326
|
+
border,
|
|
1327
|
+
margin: 0
|
|
1328
|
+
});
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
// src/index.ts
|
|
1332
|
+
var ENABLE_DECK_JSON = true;
|
|
1333
|
+
var PPTX_JSON_PAYLOAD_PATH = "json2ppt-editor.json";
|
|
1334
|
+
var PPTX_JSON_PAYLOAD_VERSION = 1;
|
|
1335
|
+
function sanitizeFileName(name) {
|
|
1336
|
+
return name.replace(/[\\/:*?"<>|]/g, "").trim() || "presentation";
|
|
1337
|
+
}
|
|
1338
|
+
function stripFillTags(value) {
|
|
1339
|
+
return value.replace(/<a:solidFill>[\s\S]*?<\/a:solidFill>/g, "").replace(/<a:gradFill>[\s\S]*?<\/a:gradFill>/g, "").replace(/<a:blipFill>[\s\S]*?<\/a:blipFill>/g, "").replace(/<a:noFill\s*\/>/g, "").replace(/<a:noFill><\/a:noFill>/g, "");
|
|
1340
|
+
}
|
|
1341
|
+
function applyPatternFill(slideXml, objectName, relId) {
|
|
1342
|
+
const nameToken = `name="${objectName}"`;
|
|
1343
|
+
let cursor = 0;
|
|
1344
|
+
let result = slideXml;
|
|
1345
|
+
while (true) {
|
|
1346
|
+
const nameIndex = result.indexOf(nameToken, cursor);
|
|
1347
|
+
if (nameIndex === -1) break;
|
|
1348
|
+
const spStart = result.lastIndexOf("<p:sp", nameIndex);
|
|
1349
|
+
const spEnd = result.indexOf("</p:sp>", nameIndex);
|
|
1350
|
+
if (spStart === -1 || spEnd === -1) break;
|
|
1351
|
+
const spXml = result.slice(spStart, spEnd + "</p:sp>".length);
|
|
1352
|
+
const spPrStart = spXml.indexOf("<p:spPr>");
|
|
1353
|
+
const spPrEnd = spXml.indexOf("</p:spPr>");
|
|
1354
|
+
if (spPrStart === -1 || spPrEnd === -1) {
|
|
1355
|
+
cursor = spEnd + 1;
|
|
1356
|
+
continue;
|
|
1357
|
+
}
|
|
1358
|
+
const spPrOpenEnd = spXml.indexOf(">", spPrStart);
|
|
1359
|
+
const spPrInner = spXml.slice(spPrOpenEnd + 1, spPrEnd);
|
|
1360
|
+
const cleanedInner = stripFillTags(spPrInner);
|
|
1361
|
+
const blipFill = `<a:blipFill><a:blip r:embed="${relId}"/><a:srcRect/><a:stretch><a:fillRect/></a:stretch></a:blipFill>`;
|
|
1362
|
+
let nextInner = cleanedInner;
|
|
1363
|
+
if (cleanedInner.includes("</a:custGeom>")) {
|
|
1364
|
+
nextInner = cleanedInner.replace("</a:custGeom>", `</a:custGeom>${blipFill}`);
|
|
1365
|
+
} else {
|
|
1366
|
+
const lnIndex = cleanedInner.indexOf("<a:ln");
|
|
1367
|
+
nextInner = lnIndex === -1 ? `${cleanedInner}${blipFill}` : `${cleanedInner.slice(0, lnIndex)}${blipFill}${cleanedInner.slice(lnIndex)}`;
|
|
1368
|
+
}
|
|
1369
|
+
const updatedSpXml = spXml.slice(0, spPrOpenEnd + 1) + nextInner + spXml.slice(spPrEnd);
|
|
1370
|
+
result = result.slice(0, spStart) + updatedSpXml + result.slice(spEnd + "</p:sp>".length);
|
|
1371
|
+
cursor = spStart + updatedSpXml.length;
|
|
1372
|
+
}
|
|
1373
|
+
return result;
|
|
1374
|
+
}
|
|
1375
|
+
function parseDataUrlImage(dataUrl) {
|
|
1376
|
+
var _a;
|
|
1377
|
+
const match = dataUrl.match(/^data:(image\/[^;]+);base64,(.+)$/);
|
|
1378
|
+
if (!match) return null;
|
|
1379
|
+
const mime = match[1];
|
|
1380
|
+
const data = match[2];
|
|
1381
|
+
const extMap = {
|
|
1382
|
+
"image/jpeg": "jpeg",
|
|
1383
|
+
"image/jpg": "jpg",
|
|
1384
|
+
"image/png": "png",
|
|
1385
|
+
"image/gif": "gif",
|
|
1386
|
+
"image/svg+xml": "svg",
|
|
1387
|
+
"image/webp": "webp",
|
|
1388
|
+
"image/bmp": "bmp"
|
|
1389
|
+
};
|
|
1390
|
+
return { mime, data, ext: (_a = extMap[mime]) != null ? _a : "png" };
|
|
1391
|
+
}
|
|
1392
|
+
async function buildPptxBlob(template) {
|
|
1393
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1394
|
+
const pptx = new import_pptxgenjs.default();
|
|
1395
|
+
const patternShapes = [];
|
|
1396
|
+
const width = (_a = template.width) != null ? _a : DEFAULT_WIDTH;
|
|
1397
|
+
const height = (_b = template.height) != null ? _b : DEFAULT_HEIGHT;
|
|
1398
|
+
const ratioPx2Inch = 96 * (width / 960);
|
|
1399
|
+
const ratioPx2Pt = 96 / 72 * (width / 960);
|
|
1400
|
+
const textPadding = 10 / ratioPx2Pt;
|
|
1401
|
+
applyPptxLayout(pptx, width, height);
|
|
1402
|
+
for (const [slideIndex, slideJson] of ((_c = template.slides) != null ? _c : []).entries()) {
|
|
1403
|
+
const slide = pptx.addSlide();
|
|
1404
|
+
applySlideBackground(slide, slideJson, template.theme);
|
|
1405
|
+
for (const [elementIndex, element] of ((_d = slideJson.elements) != null ? _d : []).entries()) {
|
|
1406
|
+
addTextElement(slide, element, template, ratioPx2Pt, ratioPx2Inch, textPadding);
|
|
1407
|
+
await addImageElement(slide, element, ratioPx2Inch);
|
|
1408
|
+
addShapeElement(
|
|
1409
|
+
slide,
|
|
1410
|
+
element,
|
|
1411
|
+
ratioPx2Pt,
|
|
1412
|
+
ratioPx2Inch,
|
|
1413
|
+
slideIndex,
|
|
1414
|
+
elementIndex,
|
|
1415
|
+
patternShapes
|
|
1416
|
+
);
|
|
1417
|
+
addLineElement(slide, element, ratioPx2Pt, ratioPx2Inch);
|
|
1418
|
+
addTableElement(slide, element, ratioPx2Pt, ratioPx2Inch);
|
|
1419
|
+
}
|
|
1293
1420
|
}
|
|
1294
|
-
const fileName = `${sanitizeFileName((
|
|
1421
|
+
const fileName = `${sanitizeFileName((_e = template.title) != null ? _e : "presentation")}.pptx`;
|
|
1295
1422
|
const pptxBuffer = await pptx.write({
|
|
1296
1423
|
outputType: "arraybuffer",
|
|
1297
1424
|
compression: true
|
|
@@ -1322,7 +1449,7 @@ async function buildPptxBlob(template) {
|
|
|
1322
1449
|
const slideNumber = pattern.slideIndex + 1;
|
|
1323
1450
|
const slidePath = `ppt/slides/slide${slideNumber}.xml`;
|
|
1324
1451
|
const relsPath = `ppt/slides/_rels/slide${slideNumber}.xml.rels`;
|
|
1325
|
-
const relsXml = (
|
|
1452
|
+
const relsXml = (_f = relsCache.get(slideNumber)) != null ? _f : zip.file(relsPath) ? await zip.file(relsPath).async("string") : `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"></Relationships>`;
|
|
1326
1453
|
let maxRelId = 0;
|
|
1327
1454
|
relsXml.replace(/Id="rId(\d+)"/g, (_, id) => {
|
|
1328
1455
|
const value = Number.parseInt(id, 10);
|
|
@@ -1336,7 +1463,7 @@ async function buildPptxBlob(template) {
|
|
|
1336
1463
|
`${relEntry}</Relationships>`
|
|
1337
1464
|
);
|
|
1338
1465
|
relsCache.set(slideNumber, nextRelsXml);
|
|
1339
|
-
const slideXml = (
|
|
1466
|
+
const slideXml = (_g = slideCache.get(slideNumber)) != null ? _g : zip.file(slidePath) ? await zip.file(slidePath).async("string") : "";
|
|
1340
1467
|
const nextSlideXml = slideXml ? applyPatternFill(slideXml, pattern.objectName, relId) : slideXml;
|
|
1341
1468
|
slideCache.set(slideNumber, nextSlideXml);
|
|
1342
1469
|
}
|