@shbernal/pptxgenjs 5.3.0 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{browser-CzGC6NnM.js → browser-DGH8T04O.js} +3 -3
- package/dist/{browser-CzGC6NnM.js.map → browser-DGH8T04O.js.map} +1 -1
- package/dist/browser.d.ts +3 -3
- package/dist/browser.js +3 -3
- package/dist/{core-interfaces-BFXQk67T.js → core-interfaces-C091uvh_.js} +13 -2
- package/dist/core-interfaces-C091uvh_.js.map +1 -0
- package/dist/core.d.ts +2 -2
- package/dist/core.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/node.d.ts +3 -3
- package/dist/node.js +3 -3
- package/dist/{pptxgen-B-mAxCRC.js → pptxgen-S8dEuBnC.js} +270 -36
- package/dist/pptxgen-S8dEuBnC.js.map +1 -0
- package/dist/{pptxgen-Clv3zz3l.d.ts → pptxgen-ZuXXUvB-.d.ts} +2 -2
- package/dist/{pptxgen-Clv3zz3l.d.ts.map → pptxgen-ZuXXUvB-.d.ts.map} +1 -1
- package/dist/standalone.d.ts +156 -5
- package/dist/standalone.d.ts.map +1 -1
- package/dist/standalone.js +280 -35
- package/dist/standalone.js.map +1 -1
- package/dist/{units-BPRPrYRg.d.ts → units-DlsWUw1U.d.ts} +157 -6
- package/dist/units-DlsWUw1U.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/core-interfaces-BFXQk67T.js.map +0 -1
- package/dist/pptxgen-B-mAxCRC.js.map +0 -1
- package/dist/units-BPRPrYRg.d.ts.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as coordToEmu, i as STANDARD_LAYOUTS, l as inchesToEmu, o as emuToInches } from "./units-BMrBTU0-.js";
|
|
2
|
-
import { A as
|
|
2
|
+
import { A as DEF_SLIDE_MARGIN_IN, E as DEF_PRES_LAYOUT_NAME, G as REGEX_HEX_COLOR, H as OutputType, J as SLDNUMFLDID, K as SCHEME_COLOR_NAMES, L as LAYOUT_IDX_SERIES_BASE, M as DEF_TEXT_SHADOW, N as EMU, O as DEF_SHAPE_SHADOW, P as IMG_BROKEN, R as LETTERS, S as DEF_FONT_COLOR, T as DEF_PRES_LAYOUT, U as PIECHART_COLORS, V as ONEPT, W as PLACEHOLDER_TYPES, X as SchemeColor, Z as ShapeType, _ as DEF_CELL_BORDER, a as AXIS_ID_SERIES_PRIMARY, b as DEF_CHART_BORDER, c as AlignH, f as CHART_TYPE, h as ChartType, i as AXIS_ID_CATEGORY_SECONDARY, j as DEF_TEXT_GLOW, l as AlignV, o as AXIS_ID_VALUE_PRIMARY, p as CONNECTOR_PRESETS, q as SHAPE_TYPE, r as AXIS_ID_CATEGORY_PRIMARY, s as AXIS_ID_VALUE_SECONDARY, tt as VALID_SHAPE_PRESETS, u as BARCHART_COLORS, v as DEF_CELL_MARGIN_IN, x as DEF_CHART_GRIDLINE, z as LINEH_MODIFIER } from "./core-interfaces-C091uvh_.js";
|
|
3
3
|
import JSZip from "jszip";
|
|
4
4
|
//#region src/gen-utils.ts
|
|
5
5
|
/**
|
|
@@ -429,15 +429,16 @@ function decodeBase64ToBytes(b64) {
|
|
|
429
429
|
}
|
|
430
430
|
}
|
|
431
431
|
/**
|
|
432
|
-
* Read the intrinsic
|
|
432
|
+
* Read the intrinsic dimensions of an image from its header bytes.
|
|
433
433
|
* - synchronous: parses only file-format headers, never decodes pixels
|
|
434
|
-
* -
|
|
435
|
-
* - vector
|
|
434
|
+
* - raster: PNG, JPEG, GIF, BMP, and WebP (VP8 / VP8L / VP8X) — natural pixels
|
|
435
|
+
* - vector: SVG — intrinsic size from the root `<svg>` width/height or viewBox
|
|
436
|
+
* - unrecognized formats return `null` (no measurable intrinsic size)
|
|
436
437
|
*
|
|
437
438
|
* Used by image `sizing: 'cover' | 'contain'` to compute an aspect-correct
|
|
438
439
|
* `<a:srcRect>` crop from the *natural* image ratio rather than the displayed box.
|
|
439
440
|
* @param {string} dataB64 - base64 image payload or `data:` URI
|
|
440
|
-
* @returns {{ w: number, h: number } | null} natural
|
|
441
|
+
* @returns {{ w: number, h: number } | null} natural size, or `null` when unmeasurable
|
|
441
442
|
*/
|
|
442
443
|
function getImageSizeFromBase64(dataB64) {
|
|
443
444
|
const b = decodeBase64ToBytes(dataB64);
|
|
@@ -523,8 +524,46 @@ function getImageSizeFromBase64(dataB64) {
|
|
|
523
524
|
}
|
|
524
525
|
return null;
|
|
525
526
|
}
|
|
527
|
+
const text = utf8Decode(b);
|
|
528
|
+
if (/<svg[\s>]/i.test(text)) return getSvgSizeFromMarkup(text);
|
|
526
529
|
return null;
|
|
527
530
|
}
|
|
531
|
+
/**
|
|
532
|
+
* Read the intrinsic size of an SVG document from its root `<svg>` element.
|
|
533
|
+
* Follows the SVG sizing model: an explicit absolute `width`/`height` pair wins;
|
|
534
|
+
* otherwise the `viewBox` width/height defines the size (and thus aspect ratio).
|
|
535
|
+
* Percentage or missing `width`/`height` fall through to `viewBox`.
|
|
536
|
+
* @param {string} svg - SVG markup
|
|
537
|
+
* @returns {{ w: number, h: number } | null} intrinsic size, or `null` when undeterminable
|
|
538
|
+
*/
|
|
539
|
+
function getSvgSizeFromMarkup(svg) {
|
|
540
|
+
const openTag = /<svg\b[^>]*>/i.exec(svg)?.[0];
|
|
541
|
+
if (!openTag) return null;
|
|
542
|
+
const attr = (name) => new RegExp(`\\b${name}\\s*=\\s*["']([^"']*)["']`, "i").exec(openTag)?.[1] ?? null;
|
|
543
|
+
const absLength = (val) => {
|
|
544
|
+
if (val == null || /%\s*$/.test(val)) return NaN;
|
|
545
|
+
const m = /^\s*\+?(\d*\.?\d+)/.exec(val);
|
|
546
|
+
return m ? parseFloat(m[1]) : NaN;
|
|
547
|
+
};
|
|
548
|
+
let w = absLength(attr("width"));
|
|
549
|
+
let h = absLength(attr("height"));
|
|
550
|
+
if (!(w > 0 && h > 0)) {
|
|
551
|
+
const vb = attr("viewBox");
|
|
552
|
+
const p = vb ? vb.trim().split(/[\s,]+/).map(Number) : [];
|
|
553
|
+
if (p.length === 4 && p[2] > 0 && p[3] > 0) {
|
|
554
|
+
w = p[2];
|
|
555
|
+
h = p[3];
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
return w > 0 && h > 0 ? {
|
|
559
|
+
w,
|
|
560
|
+
h
|
|
561
|
+
} : null;
|
|
562
|
+
}
|
|
563
|
+
/** Decode UTF-8 bytes to a string, isomorphic across Node and browsers. */
|
|
564
|
+
function utf8Decode(bytes) {
|
|
565
|
+
return new TextDecoder().decode(bytes);
|
|
566
|
+
}
|
|
528
567
|
//#endregion
|
|
529
568
|
//#region src/gen-tables.ts
|
|
530
569
|
/**
|
|
@@ -675,6 +714,7 @@ function getSlidesForTableRows(tableRows = [], tableProps = {}, presLayout, mast
|
|
|
675
714
|
let emuSlideTabH = EMU * 1;
|
|
676
715
|
let emuTabCurrH = 0;
|
|
677
716
|
let numCols = 0;
|
|
717
|
+
let warnedNoTabH = false;
|
|
678
718
|
const tableRowSlides = [];
|
|
679
719
|
const tablePropX = getSmartParseNumber(tableProps.x, "X", presLayout);
|
|
680
720
|
const tablePropY = getSmartParseNumber(tableProps.y, "Y", presLayout);
|
|
@@ -694,6 +734,15 @@ function getSlidesForTableRows(tableRows = [], tableProps = {}, presLayout, mast
|
|
|
694
734
|
if (emuSlideTabH < tablePropH) emuSlideTabH = tablePropH;
|
|
695
735
|
}
|
|
696
736
|
}
|
|
737
|
+
if (emuSlideTabH <= 0) {
|
|
738
|
+
const emuStartY = tableRowSlides.length === 0 ? tablePropY || inch2Emu(arrInchMargins[0]) : inch2Emu(tableProps.autoPageSlideStartY || tableProps.newSlideStartY || arrInchMargins[0]);
|
|
739
|
+
const fallbackH = presLayout.height - emuStartY - inch2Emu(arrInchMargins[2]);
|
|
740
|
+
if (!warnedNoTabH) {
|
|
741
|
+
console.warn("addTable/autoPage: the table height (`h`) leaves no room to paginate; ignoring it and using the slide height. Increase `h` or decrease `y`.");
|
|
742
|
+
warnedNoTabH = true;
|
|
743
|
+
}
|
|
744
|
+
emuSlideTabH = fallbackH > 0 ? fallbackH : presLayout.height;
|
|
745
|
+
}
|
|
697
746
|
}
|
|
698
747
|
if (tableProps.verbose) {
|
|
699
748
|
console.log("[[VERBOSE MODE]]");
|
|
@@ -866,7 +915,7 @@ function getSlidesForTableRows(tableRows = [], tableProps = {}, presLayout, mast
|
|
|
866
915
|
console.log("|-----------------------------------------------------------------------|\n\n");
|
|
867
916
|
}
|
|
868
917
|
if (currTableRow.length > 0 && currTableRow.map((cell) => Array.isArray(cell.text) ? cell.text.length : 0).reduce((p, n) => p + n) > 0) newTableRowSlide.rows.push(currTableRow);
|
|
869
|
-
tableRowSlides.push(newTableRowSlide);
|
|
918
|
+
if (newTableRowSlide.rows.length > 0) tableRowSlides.push(newTableRowSlide);
|
|
870
919
|
newTableRowSlide = { rows: [] };
|
|
871
920
|
currTableRow = [];
|
|
872
921
|
row.forEach((cell) => currTableRow.push({
|
|
@@ -915,7 +964,7 @@ function getSlidesForTableRows(tableRows = [], tableProps = {}, presLayout, mast
|
|
|
915
964
|
for (let c = 0; c < numCols; c++) if (colSpanDepths[c] > 0) colSpanDepths[c]--;
|
|
916
965
|
if (tableProps.verbose) console.log(`- SLIDE [${tableRowSlides.length}]: ROW [${iRow}]: ...COMPLETE ...... emuTabCurrH = ${(emuTabCurrH / EMU).toFixed(2)} ( emuSlideTabH = ${(emuSlideTabH / EMU).toFixed(2)} )`);
|
|
917
966
|
});
|
|
918
|
-
tableRowSlides.push(newTableRowSlide);
|
|
967
|
+
if (newTableRowSlide.rows.length > 0 || tableRowSlides.length === 0) tableRowSlides.push(newTableRowSlide);
|
|
919
968
|
if (tableProps.verbose) {
|
|
920
969
|
console.log("\n|================================================|");
|
|
921
970
|
console.log(`| FINAL: tableRowSlides.length = ${tableRowSlides.length}`);
|
|
@@ -947,6 +996,25 @@ function htmlBorderToProps(widthStr, colorStr) {
|
|
|
947
996
|
};
|
|
948
997
|
}
|
|
949
998
|
/**
|
|
999
|
+
* Resolve a single HTML-table column width for `tableToSlides`.
|
|
1000
|
+
*
|
|
1001
|
+
* Precedence: an explicit `data-pptx-width` wins outright; otherwise the proportional width
|
|
1002
|
+
* derived from the live table is used, raised to `data-pptx-min-width` when that floor is larger.
|
|
1003
|
+
*
|
|
1004
|
+
* Hidden tables report `offsetWidth` 0 for every cell, which makes `calcWidth` non-finite (a 0/0
|
|
1005
|
+
* proportional calc). Fall back to `0` there so an explicit `data-pptx-width` / `data-pptx-min-width`
|
|
1006
|
+
* override still drives the column instead of emitting a `NaN` width (upstream gitbrent/PptxGenJS#1157).
|
|
1007
|
+
* @param {number} calcWidth - proportional width derived from `offsetWidth` (may be `NaN` for hidden tables)
|
|
1008
|
+
* @param {number} setWidth - `data-pptx-width` override (`0`/`NaN` when absent or invalid)
|
|
1009
|
+
* @param {number} minWidth - `data-pptx-min-width` floor (`0`/`NaN` when absent or invalid)
|
|
1010
|
+
* @returns {number} resolved column width
|
|
1011
|
+
*/
|
|
1012
|
+
function resolveHtmlColWidth(calcWidth, setWidth, minWidth) {
|
|
1013
|
+
const safeCalc = isFinite(calcWidth) ? calcWidth : 0;
|
|
1014
|
+
if (isFinite(setWidth) && setWidth > 0) return setWidth;
|
|
1015
|
+
return isFinite(minWidth) && minWidth > safeCalc ? minWidth : safeCalc;
|
|
1016
|
+
}
|
|
1017
|
+
/**
|
|
950
1018
|
* Reproduces an HTML table as a PowerPoint table - including column widths, style, etc. - creates 1 or more slides as needed
|
|
951
1019
|
* @param {TableToSlidesHost} pptx - pptxgenjs instance
|
|
952
1020
|
* @param {string} tabEleId - HTMLElementID of the table
|
|
@@ -1010,12 +1078,10 @@ function genTableToSlides(pptx, tabEleId, options = {}, masterSlide) {
|
|
|
1010
1078
|
});
|
|
1011
1079
|
arrTabColW.forEach((colW, idxW) => {
|
|
1012
1080
|
const intCalcWidth = Number((Number(emuSlideTabW) * (colW / intTabW * 100) / 100 / EMU).toFixed(2));
|
|
1013
|
-
|
|
1014
|
-
const
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
if (colSelectorSet) intMinWidth = Number(colSelectorSet.getAttribute("data-pptx-width"));
|
|
1018
|
-
arrColW.push(intMinWidth > intCalcWidth ? intMinWidth : intCalcWidth);
|
|
1081
|
+
const headCell = document.querySelector(`#${tabEleId} thead tr:first-child th:nth-child(${idxW + 1})`);
|
|
1082
|
+
const intSetWidth = headCell ? Number(headCell.getAttribute("data-pptx-width")) : 0;
|
|
1083
|
+
const intMinWidth = headCell ? Number(headCell.getAttribute("data-pptx-min-width")) : 0;
|
|
1084
|
+
arrColW.push(resolveHtmlColWidth(intCalcWidth, intSetWidth, intMinWidth));
|
|
1019
1085
|
});
|
|
1020
1086
|
if (opts.verbose) console.log(`| arrColW ......................................... = [${arrColW.join(", ")}]`);
|
|
1021
1087
|
[
|
|
@@ -1189,7 +1255,7 @@ function createSlideMaster(props, target) {
|
|
|
1189
1255
|
else if ("line" in object) addShapeDefinition(tgt, "line", object.line);
|
|
1190
1256
|
else if ("rect" in object) addShapeDefinition(tgt, "rect", object.rect);
|
|
1191
1257
|
else if ("roundRect" in object) addShapeDefinition(tgt, "roundRect", object.roundRect);
|
|
1192
|
-
else if ("text" in object) addTextDefinition(tgt, [{ text: object.text.text }], object.text.options || {}, false);
|
|
1258
|
+
else if ("text" in object) addTextDefinition(tgt, Array.isArray(object.text.text) ? object.text.text : [{ text: object.text.text }], object.text.options || {}, false);
|
|
1193
1259
|
else if ("placeholder" in object) {
|
|
1194
1260
|
const placeholder = object.placeholder;
|
|
1195
1261
|
const { name, type, ...rawPlaceholderOptions } = placeholder.options;
|
|
@@ -1799,6 +1865,51 @@ function addShapeDefinition(target, shapeName, opts) {
|
|
|
1799
1865
|
target._slideObjects.push(newObject);
|
|
1800
1866
|
}
|
|
1801
1867
|
/**
|
|
1868
|
+
* Adds a connector object to a slide definition.
|
|
1869
|
+
* A connector is a line between two points emitted as a PowerPoint connector (`<p:cxnSp>`).
|
|
1870
|
+
* Endpoints are converted to a bounding box (`x/y/w/h`) plus `flipH`/`flipV` so the box can be
|
|
1871
|
+
* oriented from any corner; the connector preset geometry is derived from `type`.
|
|
1872
|
+
* @param {PresSlideInternal} target - slide the connector is added to
|
|
1873
|
+
* @param {ConnectorProps} opts - connector options (endpoints + line styling)
|
|
1874
|
+
*/
|
|
1875
|
+
function addConnectorDefinition(target, opts) {
|
|
1876
|
+
if (!opts || [
|
|
1877
|
+
opts.x1,
|
|
1878
|
+
opts.y1,
|
|
1879
|
+
opts.x2,
|
|
1880
|
+
opts.y2
|
|
1881
|
+
].some((v) => typeof v === "undefined")) throw new Error("addConnector requires { x1, y1, x2, y2 }. Example: `slide.addConnector({ x1:1, y1:1, x2:4, y2:3 })`");
|
|
1882
|
+
const preset = CONNECTOR_PRESETS[opts.type || "straight"];
|
|
1883
|
+
if (!preset) throw new Error(`Invalid connector type "${String(opts.type)}". Use 'straight', 'elbow', or 'curved'.`);
|
|
1884
|
+
const x1 = getSmartParseNumber(opts.x1, "X", target._presLayout) / EMU;
|
|
1885
|
+
const y1 = getSmartParseNumber(opts.y1, "Y", target._presLayout) / EMU;
|
|
1886
|
+
const x2 = getSmartParseNumber(opts.x2, "X", target._presLayout) / EMU;
|
|
1887
|
+
const y2 = getSmartParseNumber(opts.y2, "Y", target._presLayout) / EMU;
|
|
1888
|
+
const newObject = {
|
|
1889
|
+
_type: "connector",
|
|
1890
|
+
shape: preset,
|
|
1891
|
+
options: {
|
|
1892
|
+
x: Math.min(x1, x2),
|
|
1893
|
+
y: Math.min(y1, y2),
|
|
1894
|
+
w: Math.abs(x2 - x1),
|
|
1895
|
+
h: Math.abs(y2 - y1),
|
|
1896
|
+
flipH: x2 < x1,
|
|
1897
|
+
flipV: y2 < y1,
|
|
1898
|
+
line: {
|
|
1899
|
+
type: "solid",
|
|
1900
|
+
color: opts.color || "333333",
|
|
1901
|
+
width: typeof opts.width === "number" ? opts.width : 1,
|
|
1902
|
+
dashType: opts.dashType || "solid",
|
|
1903
|
+
beginArrowType: opts.beginArrowType,
|
|
1904
|
+
endArrowType: opts.endArrowType
|
|
1905
|
+
},
|
|
1906
|
+
altText: opts.altText,
|
|
1907
|
+
objectName: opts.objectName ? encodeXmlEntities(validateObjectName(opts.objectName, "connector")) : `Connector ${target._slideObjects.filter((obj) => obj._type === "connector").length}`
|
|
1908
|
+
}
|
|
1909
|
+
};
|
|
1910
|
+
target._slideObjects.push(newObject);
|
|
1911
|
+
}
|
|
1912
|
+
/**
|
|
1802
1913
|
* Adds a table object to a slide definition.
|
|
1803
1914
|
* @param {PresSlideInternal} target - slide object that the table should be added to
|
|
1804
1915
|
* @param {TableRow[]} tableRows - table data
|
|
@@ -1900,6 +2011,7 @@ function addTableDefinition(target, tableRows, options, slideLayout, presLayout,
|
|
|
1900
2011
|
});
|
|
1901
2012
|
}
|
|
1902
2013
|
opt.autoPage = typeof opt.autoPage === "boolean" ? opt.autoPage : false;
|
|
2014
|
+
opt.autoPagePlaceholder = typeof opt.autoPagePlaceholder === "boolean" ? opt.autoPagePlaceholder : false;
|
|
1903
2015
|
opt.autoPageRepeatHeader = typeof opt.autoPageRepeatHeader === "boolean" ? opt.autoPageRepeatHeader : false;
|
|
1904
2016
|
opt.autoPageHeaderRows = typeof opt.autoPageHeaderRows !== "undefined" && !isNaN(Number(opt.autoPageHeaderRows)) ? Number(opt.autoPageHeaderRows) : 1;
|
|
1905
2017
|
opt.autoPageLineWeight = typeof opt.autoPageLineWeight !== "undefined" && !isNaN(Number(opt.autoPageLineWeight)) ? Number(opt.autoPageLineWeight) : 0;
|
|
@@ -1963,12 +2075,14 @@ function addTableDefinition(target, tableRows, options, slideLayout, presLayout,
|
|
|
1963
2075
|
});
|
|
1964
2076
|
} else {
|
|
1965
2077
|
if (opt.autoPageRepeatHeader) opt._arrObjTabHeadRows = arrRows.filter((_row, idx) => idx < (opt.autoPageHeaderRows || 1));
|
|
2078
|
+
const sourcePlaceholders = opt.autoPagePlaceholder && Array.isArray(target._slideObjects) ? target._slideObjects.filter((obj) => obj._type !== "table" && obj.options?.placeholder) : [];
|
|
1966
2079
|
getSlidesForTableRows(arrRows, opt, presLayout, slideLayout).forEach((slide, idx) => {
|
|
1967
2080
|
if (!getSlide(target._slideNum + idx)) slides.push(addSlide({ masterName: slideLayout?._name || void 0 }));
|
|
1968
2081
|
if (idx > 0) opt.y = opt.autoPageSlideStartY || opt.newSlideStartY || arrTableMargin[0];
|
|
1969
2082
|
{
|
|
1970
2083
|
const newSlide = getSlide(target._slideNum + idx);
|
|
1971
2084
|
opt.autoPage = false;
|
|
2085
|
+
if (idx > 0 && sourcePlaceholders.length > 0) sourcePlaceholders.forEach((ph) => newSlide._slideObjects.push(structuredClone(ph)));
|
|
1972
2086
|
createHyperlinkRels(newSlide, slide.rows);
|
|
1973
2087
|
newSlide.addTable(slide.rows, { ...opt });
|
|
1974
2088
|
if (idx > 0) newAutoPagedSlides.push(newSlide);
|
|
@@ -2321,6 +2435,16 @@ var Slide = class {
|
|
|
2321
2435
|
return this;
|
|
2322
2436
|
}
|
|
2323
2437
|
/**
|
|
2438
|
+
* Add a connector (a line drawn between two points, emitted as a PowerPoint `<p:cxnSp>`).
|
|
2439
|
+
* @param {ConnectorProps} options - connector endpoints (`x1,y1,x2,y2`) and line styling
|
|
2440
|
+
* @return {Slide} this Slide
|
|
2441
|
+
* @example slide.addConnector({ type: 'elbow', x1: 1, y1: 1, x2: 5, y2: 3, endArrowType: 'triangle' })
|
|
2442
|
+
*/
|
|
2443
|
+
addConnector(options) {
|
|
2444
|
+
addConnectorDefinition(this, options);
|
|
2445
|
+
return this;
|
|
2446
|
+
}
|
|
2447
|
+
/**
|
|
2324
2448
|
* Add table to Slide
|
|
2325
2449
|
* @param {TableRow[]} tableRows - table rows
|
|
2326
2450
|
* @param {TableProps} options - table options
|
|
@@ -3334,6 +3458,7 @@ function makeChartType(chartType, data, opts, valAxisId, catAxisId) {
|
|
|
3334
3458
|
strXml += " <c:showPercent val=\"1\"/>";
|
|
3335
3459
|
strXml += " <c:showBubbleSize val=\"0\"/>";
|
|
3336
3460
|
strXml += ` <c:showLeaderLines val="${opts.showLeaderLines ? "1" : "0"}"/>`;
|
|
3461
|
+
strXml += createLeaderLinesElement(opts);
|
|
3337
3462
|
strXml += "</c:dLbls>";
|
|
3338
3463
|
strXml += "<c:cat>";
|
|
3339
3464
|
strXml += " <c:strRef>";
|
|
@@ -3766,6 +3891,24 @@ function createSerLinesElement(opt) {
|
|
|
3766
3891
|
strXml += "</a:ln></c:spPr></c:serLines>";
|
|
3767
3892
|
return strXml;
|
|
3768
3893
|
}
|
|
3894
|
+
/**
|
|
3895
|
+
* Build the `<c:leaderLines>` element for pie/doughnut data labels.
|
|
3896
|
+
*
|
|
3897
|
+
* Schema position: inside `<c:dLbls>`, immediately after `<c:showLeaderLines>`
|
|
3898
|
+
* (CT_DLbls / Group_DLbls order: showLeaderLines → leaderLines).
|
|
3899
|
+
*
|
|
3900
|
+
* Returns `''` unless the caller both enabled leader lines (`showLeaderLines`)
|
|
3901
|
+
* and configured their appearance (`leaderLineColor` / `leaderLineSize`). When
|
|
3902
|
+
* appearance is unset we leave the element off so PowerPoint applies its
|
|
3903
|
+
* automatic leader-line color, matching prior behavior.
|
|
3904
|
+
*
|
|
3905
|
+
* @param opts - chart options (reads `showLeaderLines`, `leaderLineColor`, `leaderLineSize`)
|
|
3906
|
+
*/
|
|
3907
|
+
function createLeaderLinesElement(opts) {
|
|
3908
|
+
if (!opts.showLeaderLines) return "";
|
|
3909
|
+
if (!opts.leaderLineColor && opts.leaderLineSize == null) return "";
|
|
3910
|
+
return `<c:leaderLines><c:spPr><a:ln w="${valToPts(opts.leaderLineSize ?? .75)}" cap="flat"><a:solidFill>${createColorElement(opts.leaderLineColor || "808080")}</a:solidFill><a:prstDash val="solid"/><a:round/></a:ln><a:effectLst/></c:spPr></c:leaderLines>`;
|
|
3911
|
+
}
|
|
3769
3912
|
function makeCustomDLblXml(idx, text, opts) {
|
|
3770
3913
|
const sz = Math.round((opts.dataLabelFontSize || 12) * 100);
|
|
3771
3914
|
const bold = opts.dataLabelFontBold ? "1" : "0";
|
|
@@ -3841,9 +3984,11 @@ function hasEncodingPath(rel) {
|
|
|
3841
3984
|
/**
|
|
3842
3985
|
* Encode Image/Audio/Video into base64
|
|
3843
3986
|
* @param {PresSlideInternal | SlideLayoutInternal} layout - slide layout
|
|
3987
|
+
* @param {RuntimeAdapter} runtime - runtime adapter (Node/browser media loader)
|
|
3988
|
+
* @param {'throw' | 'placeholder'} onMediaError - failure policy: reject the export (default) or substitute a placeholder and warn
|
|
3844
3989
|
* @return {Promise} promise
|
|
3845
3990
|
*/
|
|
3846
|
-
function encodeSlideMediaRels(layout, runtime) {
|
|
3991
|
+
function encodeSlideMediaRels(layout, runtime, onMediaError = "throw") {
|
|
3847
3992
|
const imageProms = [];
|
|
3848
3993
|
const candidateRels = layout._relsMedia.filter((rel) => rel.type !== "online" && !rel.data && hasEncodingPath(rel));
|
|
3849
3994
|
const unqPaths = [];
|
|
@@ -3861,9 +4006,13 @@ function encodeSlideMediaRels(layout, runtime) {
|
|
|
3861
4006
|
if (rel.isSvgPng) await runtime.createSvgPngPreview(rel);
|
|
3862
4007
|
return "done";
|
|
3863
4008
|
} catch (ex) {
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
4009
|
+
if (onMediaError === "placeholder") {
|
|
4010
|
+
console.warn(`[WARNING] Failed to load media "${rel.path}"; embedding a broken-image placeholder. (${String(ex)})`);
|
|
4011
|
+
rel.data = IMG_BROKEN;
|
|
4012
|
+
candidateRels.filter((dupe) => dupe.isDuplicate && dupe.path === rel.path).forEach((dupe) => dupe.data = rel.data);
|
|
4013
|
+
return "done";
|
|
4014
|
+
}
|
|
4015
|
+
throw new Error(`Failed to load media "${rel.path}" during export.`, { cause: ex });
|
|
3867
4016
|
}
|
|
3868
4017
|
})());
|
|
3869
4018
|
});
|
|
@@ -4398,6 +4547,24 @@ function slideObjectToXml(slide) {
|
|
|
4398
4547
|
strSlideXml += genXmlTextBody(slideItemObj);
|
|
4399
4548
|
strSlideXml += "</p:sp>";
|
|
4400
4549
|
break;
|
|
4550
|
+
case "connector":
|
|
4551
|
+
strSlideXml += "<p:cxnSp><p:nvCxnSpPr>";
|
|
4552
|
+
strSlideXml += `<p:cNvPr id="${idx + 2}" name="${slideItemObj.options.objectName}" descr="${encodeXmlEntities(slideItemObj.options.altText || "")}"/>`;
|
|
4553
|
+
strSlideXml += "<p:cNvCxnSpPr/><p:nvPr/></p:nvCxnSpPr><p:spPr>";
|
|
4554
|
+
strSlideXml += `<a:xfrm${locationAttr}><a:off x="${x}" y="${y}"/><a:ext cx="${cx}" cy="${cy}"/></a:xfrm>`;
|
|
4555
|
+
strSlideXml += `<a:prstGeom prst="${slideItemObj.shape}"><a:avLst/></a:prstGeom>`;
|
|
4556
|
+
{
|
|
4557
|
+
const ln = slideItemObj.options.line || {};
|
|
4558
|
+
const lnAttrs = (ln.width ? ` w="${lineWidthToEmu(ln.width)}"` : "") + (ln.cap ? ` cap="${createLineCap(ln.cap)}"` : "");
|
|
4559
|
+
strSlideXml += `<a:ln${lnAttrs}>`;
|
|
4560
|
+
if (ln.color) strSlideXml += genXmlColorSelection(ln);
|
|
4561
|
+
if (ln.dashType) strSlideXml += `<a:prstDash val="${ln.dashType}"/>`;
|
|
4562
|
+
if (ln.beginArrowType) strSlideXml += `<a:headEnd type="${ln.beginArrowType}"/>`;
|
|
4563
|
+
if (ln.endArrowType) strSlideXml += `<a:tailEnd type="${ln.endArrowType}"/>`;
|
|
4564
|
+
strSlideXml += "</a:ln>";
|
|
4565
|
+
}
|
|
4566
|
+
strSlideXml += "</p:spPr></p:cxnSp>";
|
|
4567
|
+
break;
|
|
4401
4568
|
case "image":
|
|
4402
4569
|
strSlideXml += "<p:pic>";
|
|
4403
4570
|
strSlideXml += " <p:nvPicPr>";
|
|
@@ -4441,7 +4608,7 @@ function slideObjectToXml(slide) {
|
|
|
4441
4608
|
const relData = (slide._relsMedia || []).find((rel) => rel.rId === slideItemObj.imageRid)?.data;
|
|
4442
4609
|
const natural = typeof relData === "string" ? getImageSizeFromBase64(relData) : null;
|
|
4443
4610
|
if (natural) cropSize = natural;
|
|
4444
|
-
else console.warn(`Warning: sizing '${sizing.type}' could not measure natural dimensions for image "${slideItemObj.options.objectName}"; falling back to displayed aspect ratio (crop may be inexact). Provide a raster image (PNG/JPEG/GIF/BMP/WebP) to enable an aspect-correct crop.`);
|
|
4611
|
+
else console.warn(`Warning: sizing '${sizing.type}' could not measure natural dimensions for image "${slideItemObj.options.objectName}"; falling back to displayed aspect ratio (crop may be inexact). Provide a raster image (PNG/JPEG/GIF/BMP/WebP) or an SVG with width/height or a viewBox to enable an aspect-correct crop.`);
|
|
4445
4612
|
}
|
|
4446
4613
|
strSlideXml += ImageSizingXml[sizing.type](cropSize, {
|
|
4447
4614
|
w: boxW,
|
|
@@ -4460,6 +4627,16 @@ function slideObjectToXml(slide) {
|
|
|
4460
4627
|
strSlideXml += " </a:xfrm>";
|
|
4461
4628
|
if (slideItemObj.options.points) strSlideXml += " " + genXmlCustGeom(slideItemObj.options.points, imgWidth, imgHeight, slide._presLayout);
|
|
4462
4629
|
else strSlideXml += " " + genXmlPresetGeom(slideItemObj.options.shape ?? (rounding ? "ellipse" : "rect"), slideItemObj.options, imgWidth, imgHeight);
|
|
4630
|
+
if (slideItemObj.options.line) {
|
|
4631
|
+
const imgLine = slideItemObj.options.line;
|
|
4632
|
+
const lnAttrs = (imgLine.width ? ` w="${lineWidthToEmu(imgLine.width)}"` : "") + (imgLine.cap ? ` cap="${createLineCap(imgLine.cap)}"` : "");
|
|
4633
|
+
strSlideXml += `<a:ln${lnAttrs}>`;
|
|
4634
|
+
if (imgLine.color) strSlideXml += genXmlColorSelection(imgLine);
|
|
4635
|
+
if (imgLine.dashType) strSlideXml += `<a:prstDash val="${imgLine.dashType}"/>`;
|
|
4636
|
+
if (imgLine.beginArrowType) strSlideXml += `<a:headEnd type="${imgLine.beginArrowType}"/>`;
|
|
4637
|
+
if (imgLine.endArrowType) strSlideXml += `<a:tailEnd type="${imgLine.endArrowType}"/>`;
|
|
4638
|
+
strSlideXml += "</a:ln>";
|
|
4639
|
+
}
|
|
4463
4640
|
if (slideItemObj.options.shadow && slideItemObj.options.shadow.type !== "none") {
|
|
4464
4641
|
const sh = slideItemObj.options.shadow;
|
|
4465
4642
|
const shadowType = sh.type || "outer";
|
|
@@ -4662,9 +4839,17 @@ function genXmlParagraphProperties(textObj, isDefault) {
|
|
|
4662
4839
|
if (typeof textObj.options.bullet === "object") {
|
|
4663
4840
|
if (textObj?.options?.bullet?.indent) bulletMarL = valToPts(textObj.options.bullet.indent);
|
|
4664
4841
|
if (textObj.options.bullet.color) strXmlBulletColor = `<a:buClr>${createColorElement(textObj.options.bullet.color)}</a:buClr>`;
|
|
4842
|
+
let bulletSizePct = 1e5;
|
|
4843
|
+
if (textObj.options.bullet.size !== void 0) {
|
|
4844
|
+
const bulletSize = Number(textObj.options.bullet.size);
|
|
4845
|
+
if (isNaN(bulletSize) || bulletSize < 25 || bulletSize > 400) console.warn("Warning: `bullet.size` must be a percentage between 25 and 400!");
|
|
4846
|
+
else bulletSizePct = Math.round(bulletSize * 1e3);
|
|
4847
|
+
}
|
|
4848
|
+
const strXmlBulletSize = `<a:buSzPct val="${bulletSizePct}"/>`;
|
|
4849
|
+
const strXmlBulletFont = textObj.options.bullet.fontFace ? `<a:buFont typeface="${encodeXmlEntities(textObj.options.bullet.fontFace)}"/>` : "";
|
|
4665
4850
|
if (textObj.options.bullet.type && textObj.options.bullet.type.toString().toLowerCase() === "number") {
|
|
4666
4851
|
paragraphPropXml += ` marL="${textObj.options.indentLevel && textObj.options.indentLevel > 0 ? bulletMarL + bulletMarL * textObj.options.indentLevel : bulletMarL}" indent="-${bulletMarL}"`;
|
|
4667
|
-
strXmlBullet =
|
|
4852
|
+
strXmlBullet = `${strXmlBulletSize}${strXmlBulletFont || "<a:buFont typeface=\"+mj-lt\"/>"}<a:buAutoNum type="${textObj.options.bullet.style || "arabicPeriod"}" startAt="${textObj.options.bullet.numberStartAt || textObj.options.bullet.startAt || "1"}"/>`;
|
|
4668
4853
|
} else if (textObj.options.bullet.characterCode) {
|
|
4669
4854
|
let bulletCode = `&#x${textObj.options.bullet.characterCode};`;
|
|
4670
4855
|
if (!/^[0-9A-Fa-f]{4}$/.test(textObj.options.bullet.characterCode)) {
|
|
@@ -4672,7 +4857,7 @@ function genXmlParagraphProperties(textObj, isDefault) {
|
|
|
4672
4857
|
bulletCode = "•";
|
|
4673
4858
|
}
|
|
4674
4859
|
paragraphPropXml += ` marL="${textObj.options.indentLevel && textObj.options.indentLevel > 0 ? bulletMarL + bulletMarL * textObj.options.indentLevel : bulletMarL}" indent="-${bulletMarL}"`;
|
|
4675
|
-
strXmlBullet = "<a:
|
|
4860
|
+
strXmlBullet = strXmlBulletSize + strXmlBulletFont + "<a:buChar char=\"" + bulletCode + "\"/>";
|
|
4676
4861
|
} else if (textObj.options.bullet.code) {
|
|
4677
4862
|
let bulletCode = `&#x${textObj.options.bullet.code};`;
|
|
4678
4863
|
if (!/^[0-9A-Fa-f]{4}$/.test(textObj.options.bullet.code)) {
|
|
@@ -4680,10 +4865,10 @@ function genXmlParagraphProperties(textObj, isDefault) {
|
|
|
4680
4865
|
bulletCode = "•";
|
|
4681
4866
|
}
|
|
4682
4867
|
paragraphPropXml += ` marL="${textObj.options.indentLevel && textObj.options.indentLevel > 0 ? bulletMarL + bulletMarL * textObj.options.indentLevel : bulletMarL}" indent="-${bulletMarL}"`;
|
|
4683
|
-
strXmlBullet = "<a:
|
|
4868
|
+
strXmlBullet = strXmlBulletSize + strXmlBulletFont + "<a:buChar char=\"" + bulletCode + "\"/>";
|
|
4684
4869
|
} else {
|
|
4685
4870
|
paragraphPropXml += ` marL="${textObj.options.indentLevel && textObj.options.indentLevel > 0 ? bulletMarL + bulletMarL * textObj.options.indentLevel : bulletMarL}" indent="-${bulletMarL}"`;
|
|
4686
|
-
strXmlBullet =
|
|
4871
|
+
strXmlBullet = `${strXmlBulletSize}${strXmlBulletFont}<a:buChar char="•"/>`;
|
|
4687
4872
|
}
|
|
4688
4873
|
} else if (textObj.options.bullet) {
|
|
4689
4874
|
paragraphPropXml += ` marL="${textObj.options.indentLevel && textObj.options.indentLevel > 0 ? bulletMarL + bulletMarL * textObj.options.indentLevel : bulletMarL}" indent="-${bulletMarL}"`;
|
|
@@ -5298,11 +5483,51 @@ function getLayoutIdxForSlide(slides, slideLayouts, slideNumber) {
|
|
|
5298
5483
|
return 1;
|
|
5299
5484
|
}
|
|
5300
5485
|
/**
|
|
5486
|
+
* Theme `<a:clrScheme>` slots in OOXML document order, with their default Office color child.
|
|
5487
|
+
* `dk1`/`lt1` default to `sysClr` (windowText/window); the rest are `srgbClr`. A user override
|
|
5488
|
+
* for any slot is emitted as `<a:srgbClr>` (see `buildThemeClrScheme`).
|
|
5489
|
+
*/
|
|
5490
|
+
const THEME_CLR_SCHEME_DEFAULTS = [
|
|
5491
|
+
["dk1", "<a:sysClr val=\"windowText\" lastClr=\"000000\"/>"],
|
|
5492
|
+
["lt1", "<a:sysClr val=\"window\" lastClr=\"FFFFFF\"/>"],
|
|
5493
|
+
["dk2", "<a:srgbClr val=\"44546A\"/>"],
|
|
5494
|
+
["lt2", "<a:srgbClr val=\"E7E6E6\"/>"],
|
|
5495
|
+
["accent1", "<a:srgbClr val=\"4472C4\"/>"],
|
|
5496
|
+
["accent2", "<a:srgbClr val=\"ED7D31\"/>"],
|
|
5497
|
+
["accent3", "<a:srgbClr val=\"A5A5A5\"/>"],
|
|
5498
|
+
["accent4", "<a:srgbClr val=\"FFC000\"/>"],
|
|
5499
|
+
["accent5", "<a:srgbClr val=\"5B9BD5\"/>"],
|
|
5500
|
+
["accent6", "<a:srgbClr val=\"70AD47\"/>"],
|
|
5501
|
+
["hlink", "<a:srgbClr val=\"0563C1\"/>"],
|
|
5502
|
+
["folHlink", "<a:srgbClr val=\"954F72\"/>"]
|
|
5503
|
+
];
|
|
5504
|
+
/**
|
|
5505
|
+
* Build the theme `<a:clrScheme>` block, applying any caller-supplied color overrides over the
|
|
5506
|
+
* default Office scheme. Invalid (non 6-digit-hex) overrides warn and keep the default rather
|
|
5507
|
+
* than emitting a degenerate color.
|
|
5508
|
+
* @param {ThemeColorScheme} [scheme] - per-slot hex overrides
|
|
5509
|
+
* @return {string} the `<a:clrScheme>...</a:clrScheme>` XML
|
|
5510
|
+
*/
|
|
5511
|
+
function buildThemeClrScheme(scheme) {
|
|
5512
|
+
return `<a:clrScheme name="Office">${THEME_CLR_SCHEME_DEFAULTS.map(([slot, defaultChild]) => {
|
|
5513
|
+
const override = scheme?.[slot];
|
|
5514
|
+
let child = defaultChild;
|
|
5515
|
+
if (typeof override === "string" && override.length > 0) {
|
|
5516
|
+
const hex = override.replace("#", "");
|
|
5517
|
+
if (REGEX_HEX_COLOR.test(hex)) child = `<a:srgbClr val="${hex.toUpperCase()}"/>`;
|
|
5518
|
+
else console.warn(`makeXmlTheme: colorScheme.${slot} "${override}" is not a 6-digit hex color; keeping the Office default.`);
|
|
5519
|
+
}
|
|
5520
|
+
return `<a:${slot}>${child}</a:${slot}>`;
|
|
5521
|
+
}).join("")}</a:clrScheme>`;
|
|
5522
|
+
}
|
|
5523
|
+
/**
|
|
5301
5524
|
* Creates `ppt/theme/theme1.xml`
|
|
5302
5525
|
* @return {string} XML
|
|
5303
5526
|
*/
|
|
5304
5527
|
function makeXmlTheme(pres) {
|
|
5305
|
-
|
|
5528
|
+
const majorFont = pres.theme?.headFontFace ? `<a:latin typeface="${pres.theme?.headFontFace}"/>` : "<a:latin typeface=\"Calibri Light\" panose=\"020F0302020204030204\"/>";
|
|
5529
|
+
const minorFont = pres.theme?.bodyFontFace ? `<a:latin typeface="${pres.theme?.bodyFontFace}"/>` : "<a:latin typeface=\"Calibri\" panose=\"020F0502020204030204\"/>";
|
|
5530
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme"><a:themeElements>${buildThemeClrScheme(pres.theme?.colorScheme)}<a:fontScheme name="Office"><a:majorFont>${majorFont}<a:ea typeface=""/><a:cs typeface=""/><a:font script="Jpan" typeface="游ゴシック Light"/><a:font script="Hang" typeface="맑은 고딕"/><a:font script="Hans" typeface="等线 Light"/><a:font script="Hant" typeface="新細明體"/><a:font script="Arab" typeface="Times New Roman"/><a:font script="Hebr" typeface="Times New Roman"/><a:font script="Thai" typeface="Angsana New"/><a:font script="Ethi" typeface="Nyala"/><a:font script="Beng" typeface="Vrinda"/><a:font script="Gujr" typeface="Shruti"/><a:font script="Khmr" typeface="MoolBoran"/><a:font script="Knda" typeface="Tunga"/><a:font script="Guru" typeface="Raavi"/><a:font script="Cans" typeface="Euphemia"/><a:font script="Cher" typeface="Plantagenet Cherokee"/><a:font script="Yiii" typeface="Microsoft Yi Baiti"/><a:font script="Tibt" typeface="Microsoft Himalaya"/><a:font script="Thaa" typeface="MV Boli"/><a:font script="Deva" typeface="Mangal"/><a:font script="Telu" typeface="Gautami"/><a:font script="Taml" typeface="Latha"/><a:font script="Syrc" typeface="Estrangelo Edessa"/><a:font script="Orya" typeface="Kalinga"/><a:font script="Mlym" typeface="Kartika"/><a:font script="Laoo" typeface="DokChampa"/><a:font script="Sinh" typeface="Iskoola Pota"/><a:font script="Mong" typeface="Mongolian Baiti"/><a:font script="Viet" typeface="Times New Roman"/><a:font script="Uigh" typeface="Microsoft Uighur"/><a:font script="Geor" typeface="Sylfaen"/><a:font script="Armn" typeface="Arial"/><a:font script="Bugi" typeface="Leelawadee UI"/><a:font script="Bopo" typeface="Microsoft JhengHei"/><a:font script="Java" typeface="Javanese Text"/><a:font script="Lisu" typeface="Segoe UI"/><a:font script="Mymr" typeface="Myanmar Text"/><a:font script="Nkoo" typeface="Ebrima"/><a:font script="Olck" typeface="Nirmala UI"/><a:font script="Osma" typeface="Ebrima"/><a:font script="Phag" typeface="Phagspa"/><a:font script="Syrn" typeface="Estrangelo Edessa"/><a:font script="Syrj" typeface="Estrangelo Edessa"/><a:font script="Syre" typeface="Estrangelo Edessa"/><a:font script="Sora" typeface="Nirmala UI"/><a:font script="Tale" typeface="Microsoft Tai Le"/><a:font script="Talu" typeface="Microsoft New Tai Lue"/><a:font script="Tfng" typeface="Ebrima"/></a:majorFont><a:minorFont>${minorFont}<a:ea typeface=""/><a:cs typeface=""/><a:font script="Jpan" typeface="游ゴシック"/><a:font script="Hang" typeface="맑은 고딕"/><a:font script="Hans" typeface="等线"/><a:font script="Hant" typeface="新細明體"/><a:font script="Arab" typeface="Arial"/><a:font script="Hebr" typeface="Arial"/><a:font script="Thai" typeface="Cordia New"/><a:font script="Ethi" typeface="Nyala"/><a:font script="Beng" typeface="Vrinda"/><a:font script="Gujr" typeface="Shruti"/><a:font script="Khmr" typeface="DaunPenh"/><a:font script="Knda" typeface="Tunga"/><a:font script="Guru" typeface="Raavi"/><a:font script="Cans" typeface="Euphemia"/><a:font script="Cher" typeface="Plantagenet Cherokee"/><a:font script="Yiii" typeface="Microsoft Yi Baiti"/><a:font script="Tibt" typeface="Microsoft Himalaya"/><a:font script="Thaa" typeface="MV Boli"/><a:font script="Deva" typeface="Mangal"/><a:font script="Telu" typeface="Gautami"/><a:font script="Taml" typeface="Latha"/><a:font script="Syrc" typeface="Estrangelo Edessa"/><a:font script="Orya" typeface="Kalinga"/><a:font script="Mlym" typeface="Kartika"/><a:font script="Laoo" typeface="DokChampa"/><a:font script="Sinh" typeface="Iskoola Pota"/><a:font script="Mong" typeface="Mongolian Baiti"/><a:font script="Viet" typeface="Arial"/><a:font script="Uigh" typeface="Microsoft Uighur"/><a:font script="Geor" typeface="Sylfaen"/><a:font script="Armn" typeface="Arial"/><a:font script="Bugi" typeface="Leelawadee UI"/><a:font script="Bopo" typeface="Microsoft JhengHei"/><a:font script="Java" typeface="Javanese Text"/><a:font script="Lisu" typeface="Segoe UI"/><a:font script="Mymr" typeface="Myanmar Text"/><a:font script="Nkoo" typeface="Ebrima"/><a:font script="Olck" typeface="Nirmala UI"/><a:font script="Osma" typeface="Ebrima"/><a:font script="Phag" typeface="Phagspa"/><a:font script="Syrn" typeface="Estrangelo Edessa"/><a:font script="Syrj" typeface="Estrangelo Edessa"/><a:font script="Syre" typeface="Estrangelo Edessa"/><a:font script="Sora" typeface="Nirmala UI"/><a:font script="Tale" typeface="Microsoft Tai Le"/><a:font script="Talu" typeface="Microsoft New Tai Lue"/><a:font script="Tfng" typeface="Ebrima"/></a:minorFont></a:fontScheme><a:fmtScheme name="Office"><a:fillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:lumMod val="110000"/><a:satMod val="105000"/><a:tint val="67000"/></a:schemeClr></a:gs><a:gs pos="50000"><a:schemeClr val="phClr"><a:lumMod val="105000"/><a:satMod val="103000"/><a:tint val="73000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:lumMod val="105000"/><a:satMod val="109000"/><a:tint val="81000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="5400000" scaled="0"/></a:gradFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:satMod val="103000"/><a:lumMod val="102000"/><a:tint val="94000"/></a:schemeClr></a:gs><a:gs pos="50000"><a:schemeClr val="phClr"><a:satMod val="110000"/><a:lumMod val="100000"/><a:shade val="100000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:lumMod val="99000"/><a:satMod val="120000"/><a:shade val="78000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="5400000" scaled="0"/></a:gradFill></a:fillStyleLst><a:lnStyleLst><a:ln w="6350" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/><a:miter lim="800000"/></a:ln><a:ln w="12700" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/><a:miter lim="800000"/></a:ln><a:ln w="19050" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/><a:miter lim="800000"/></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad="57150" dist="19050" dir="5400000" algn="ctr" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="63000"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"><a:tint val="95000"/><a:satMod val="170000"/></a:schemeClr></a:solidFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="93000"/><a:satMod val="150000"/><a:shade val="98000"/><a:lumMod val="102000"/></a:schemeClr></a:gs><a:gs pos="50000"><a:schemeClr val="phClr"><a:tint val="98000"/><a:satMod val="130000"/><a:shade val="90000"/><a:lumMod val="103000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="63000"/><a:satMod val="120000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="5400000" scaled="0"/></a:gradFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/><a:extraClrSchemeLst/><a:extLst><a:ext uri="{05A4C25C-085E-4340-85A3-A5531E510DB2}"><thm15:themeFamily xmlns:thm15="http://schemas.microsoft.com/office/thememl/2012/main" name="Office Theme" id="{62F939B6-93AF-4DB8-9C6B-D6C7DFDC589F}" vid="{4A3C46E8-61CC-4603-A589-7422A47A8E4A}"/></a:ext></a:extLst></a:theme>`;
|
|
5306
5531
|
}
|
|
5307
5532
|
/**
|
|
5308
5533
|
* Create presentation file (`ppt/presentation.xml`)
|
|
@@ -5511,7 +5736,7 @@ function makeXmlViewProps() {
|
|
|
5511
5736
|
* @see https://docs.microsoft.com/en-us/office/open-xml/structure-of-a-presentationml-document
|
|
5512
5737
|
* @see https://docs.microsoft.com/en-us/previous-versions/office/developer/office-2010/hh273476(v=office.14)
|
|
5513
5738
|
*/
|
|
5514
|
-
const VERSION = "5.
|
|
5739
|
+
const VERSION = "5.4.0";
|
|
5515
5740
|
function standardLayoutToPresLayout(layout) {
|
|
5516
5741
|
return {
|
|
5517
5742
|
name: layout.name,
|
|
@@ -5763,6 +5988,7 @@ var PptxGenJS = class {
|
|
|
5763
5988
|
this._tableStyles = [];
|
|
5764
5989
|
this._masterSlide = {
|
|
5765
5990
|
addChart: null,
|
|
5991
|
+
addConnector: null,
|
|
5766
5992
|
addImage: null,
|
|
5767
5993
|
addMedia: null,
|
|
5768
5994
|
addNotes: null,
|
|
@@ -5835,13 +6061,14 @@ var PptxGenJS = class {
|
|
|
5835
6061
|
const arrChartPromises = [];
|
|
5836
6062
|
let arrMediaPromises = [];
|
|
5837
6063
|
const zip = new JSZip();
|
|
6064
|
+
const onMediaError = props.onMediaError ?? "throw";
|
|
5838
6065
|
this._slides.forEach((slide) => {
|
|
5839
|
-
arrMediaPromises = arrMediaPromises.concat(encodeSlideMediaRels(slide, this._runtime));
|
|
6066
|
+
arrMediaPromises = arrMediaPromises.concat(encodeSlideMediaRels(slide, this._runtime, onMediaError));
|
|
5840
6067
|
});
|
|
5841
6068
|
this._slideLayouts.forEach((layout) => {
|
|
5842
|
-
arrMediaPromises = arrMediaPromises.concat(encodeSlideMediaRels(layout, this._runtime));
|
|
6069
|
+
arrMediaPromises = arrMediaPromises.concat(encodeSlideMediaRels(layout, this._runtime, onMediaError));
|
|
5843
6070
|
});
|
|
5844
|
-
arrMediaPromises = arrMediaPromises.concat(encodeSlideMediaRels(this._masterSlide, this._runtime));
|
|
6071
|
+
arrMediaPromises = arrMediaPromises.concat(encodeSlideMediaRels(this._masterSlide, this._runtime, onMediaError));
|
|
5845
6072
|
return await Promise.all(arrMediaPromises).then(async () => {
|
|
5846
6073
|
const canonicalMediaTargets = /* @__PURE__ */ new Map();
|
|
5847
6074
|
for (const target of [
|
|
@@ -5907,14 +6134,18 @@ var PptxGenJS = class {
|
|
|
5907
6134
|
});
|
|
5908
6135
|
this.createChartMediaRels(this._masterSlide, zip, arrChartPromises);
|
|
5909
6136
|
return await Promise.all(arrChartPromises).then(async () => {
|
|
6137
|
+
const compression = props.compression === false ? "STORE" : "DEFLATE";
|
|
5910
6138
|
if (props.outputType === "STREAM") return await zip.generateAsync({
|
|
5911
6139
|
type: "nodebuffer",
|
|
5912
|
-
compression
|
|
6140
|
+
compression
|
|
6141
|
+
});
|
|
6142
|
+
else if (props.outputType) return await zip.generateAsync({
|
|
6143
|
+
type: props.outputType,
|
|
6144
|
+
compression
|
|
5913
6145
|
});
|
|
5914
|
-
else if (props.outputType) return await zip.generateAsync({ type: props.outputType });
|
|
5915
6146
|
else return await zip.generateAsync({
|
|
5916
6147
|
type: "blob",
|
|
5917
|
-
compression
|
|
6148
|
+
compression
|
|
5918
6149
|
});
|
|
5919
6150
|
});
|
|
5920
6151
|
});
|
|
@@ -5937,10 +6168,12 @@ var PptxGenJS = class {
|
|
|
5937
6168
|
*/
|
|
5938
6169
|
async write(props) {
|
|
5939
6170
|
const propsOutpType = typeof props === "object" && props?.outputType ? props.outputType : props ? props : null;
|
|
5940
|
-
const propsCompress = typeof props === "object"
|
|
6171
|
+
const propsCompress = typeof props === "object" ? props?.compression : void 0;
|
|
6172
|
+
const propsMediaError = typeof props === "object" ? props?.onMediaError : void 0;
|
|
5941
6173
|
return await this.exportPresentation({
|
|
5942
6174
|
compression: propsCompress,
|
|
5943
|
-
outputType: propsOutpType
|
|
6175
|
+
outputType: propsOutpType,
|
|
6176
|
+
onMediaError: propsMediaError
|
|
5944
6177
|
});
|
|
5945
6178
|
}
|
|
5946
6179
|
/**
|
|
@@ -5954,11 +6187,12 @@ var PptxGenJS = class {
|
|
|
5954
6187
|
console.warn("[WARNING] writeFile(string) is deprecated - pass { fileName } instead.");
|
|
5955
6188
|
props = { fileName: props };
|
|
5956
6189
|
}
|
|
5957
|
-
const { fileName: rawName = "Presentation.pptx", compression
|
|
6190
|
+
const { fileName: rawName = "Presentation.pptx", compression, onMediaError } = props;
|
|
5958
6191
|
const fileName = rawName.toLowerCase().endsWith(".pptx") ? rawName : `${rawName}.pptx`;
|
|
5959
6192
|
const data = await this.exportPresentation({
|
|
5960
6193
|
compression,
|
|
5961
|
-
outputType: this._runtime.writeFileOutputType
|
|
6194
|
+
outputType: this._runtime.writeFileOutputType,
|
|
6195
|
+
onMediaError
|
|
5962
6196
|
});
|
|
5963
6197
|
return await this._runtime.writeFile(fileName, data);
|
|
5964
6198
|
}
|
|
@@ -6120,4 +6354,4 @@ var PptxGenJS = class {
|
|
|
6120
6354
|
//#endregion
|
|
6121
6355
|
export { PptxGenJS as t };
|
|
6122
6356
|
|
|
6123
|
-
//# sourceMappingURL=pptxgen-
|
|
6357
|
+
//# sourceMappingURL=pptxgen-S8dEuBnC.js.map
|