@office-open/core 0.11.0 → 0.12.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/chart/index.d.mts +2 -2
- package/dist/chart/index.mjs +1 -1
- package/dist/{chart-Kf_utasF.mjs → chart-DED4tXC9.mjs} +828 -283
- package/dist/chart-DED4tXC9.mjs.map +1 -0
- package/dist/data-type-CZMKVaaT.d.mts.map +1 -1
- package/dist/descriptor/index.d.mts +1 -1
- package/dist/descriptor/index.mjs +1 -1
- package/dist/{descriptor-BX8xW8na.mjs → descriptor-BqaNZrrZ.mjs} +38 -10
- package/dist/{descriptor-BX8xW8na.mjs.map → descriptor-BqaNZrrZ.mjs.map} +1 -1
- package/dist/drawing/index.d.mts +2 -2
- package/dist/drawing/index.mjs +2 -2
- package/dist/{drawing-FBzd2I0m.mjs → drawing-BCAyrCCw.mjs} +3056 -3130
- package/dist/drawing-BCAyrCCw.mjs.map +1 -0
- package/dist/{generators-CElPsAhd.mjs → ext-uri-BHBcIrW7.mjs} +599 -343
- package/dist/ext-uri-BHBcIrW7.mjs.map +1 -0
- package/dist/index-BAxlDUQ1.d.mts +590 -0
- package/dist/index-BAxlDUQ1.d.mts.map +1 -0
- package/dist/{index-DxwLMnBF.d.mts → index-BP541uS-.d.mts} +136 -31
- package/dist/index-BP541uS-.d.mts.map +1 -0
- package/dist/{index-CLX7gU9J.d.mts → index-BQLIofaF.d.mts} +3 -2
- package/dist/index-BQLIofaF.d.mts.map +1 -0
- package/dist/{index-k8WKLXnA.d.mts → index-CaNwM5_e.d.mts} +19 -20
- package/dist/index-CaNwM5_e.d.mts.map +1 -0
- package/dist/{index-CnjCK-lF.d.mts → index-DPkf_CtG.d.mts} +566 -597
- package/dist/index-DPkf_CtG.d.mts.map +1 -0
- package/dist/{index-BsTUn4K1.d.mts → index-DcukVskh.d.mts} +9 -6
- package/dist/index-DcukVskh.d.mts.map +1 -0
- package/dist/{index-Cgz88FU0.d.mts → index-Di6XPdGl.d.mts} +26 -12
- package/dist/index-Di6XPdGl.d.mts.map +1 -0
- package/dist/{index-C0ClOhmZ.d.mts → index-L6AXewfV.d.mts} +11 -8
- package/dist/index-L6AXewfV.d.mts.map +1 -0
- package/dist/index.d.mts +140 -29
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +849 -87
- package/dist/index.mjs.map +1 -1
- package/dist/{output-D_G_JR_8.d.mts → output-yyxdkG0C.d.mts} +2 -3
- package/dist/output-yyxdkG0C.d.mts.map +1 -0
- package/dist/patch/index.d.mts +2 -2
- package/dist/patch/index.mjs +2 -2
- package/dist/{patch-3KLx2yEP.mjs → patch-AkQY17CD.mjs} +71 -26
- package/dist/patch-AkQY17CD.mjs.map +1 -0
- package/dist/smartart/index.d.mts +2 -2
- package/dist/smartart/index.mjs +1 -1
- package/dist/{smartart-BxnkROOp.mjs → smartart-n1kYJ6Jg.mjs} +27 -26
- package/dist/smartart-n1kYJ6Jg.mjs.map +1 -0
- package/dist/{style-matrix-DAP6XrLv.mjs → style-matrix-B6jhPAT3.mjs} +4 -4
- package/dist/style-matrix-B6jhPAT3.mjs.map +1 -0
- package/dist/theme/index.d.mts +4 -4
- package/dist/theme/index.mjs +3 -2
- package/dist/{theme-OAuRcA9_.mjs → theme-BKnXRmvn.mjs} +37 -71
- package/dist/theme-BKnXRmvn.mjs.map +1 -0
- package/dist/{theme-options-BbWccl85.d.mts → theme-options-kO89NUEX.d.mts} +17 -17
- package/dist/theme-options-kO89NUEX.d.mts.map +1 -0
- package/dist/util/index.d.mts +3 -3
- package/dist/util/index.mjs +3 -3
- package/dist/{util-C94-JKtp.mjs → util-ptE16MEk.mjs} +69 -37
- package/dist/util-ptE16MEk.mjs.map +1 -0
- package/dist/{values-aVoirbWB.d.mts → values-BECDm4zr.d.mts} +15 -31
- package/dist/values-BECDm4zr.d.mts.map +1 -0
- package/dist/vector/index.d.mts +2 -2
- package/dist/vector/index.mjs +2 -2
- package/dist/{vector-TpjW6ZSc.mjs → vector-DhLGZjP5.mjs} +104 -147
- package/dist/vector-DhLGZjP5.mjs.map +1 -0
- package/package.json +3 -3
- package/dist/chart-Kf_utasF.mjs.map +0 -1
- package/dist/drawing-FBzd2I0m.mjs.map +0 -1
- package/dist/generators-CElPsAhd.mjs.map +0 -1
- package/dist/index-BsTUn4K1.d.mts.map +0 -1
- package/dist/index-C0ClOhmZ.d.mts.map +0 -1
- package/dist/index-CLX7gU9J.d.mts.map +0 -1
- package/dist/index-Cgz88FU0.d.mts.map +0 -1
- package/dist/index-CnjCK-lF.d.mts.map +0 -1
- package/dist/index-DpPeyf5f.d.mts +0 -316
- package/dist/index-DpPeyf5f.d.mts.map +0 -1
- package/dist/index-DxwLMnBF.d.mts.map +0 -1
- package/dist/index-k8WKLXnA.d.mts.map +0 -1
- package/dist/output-D_G_JR_8.d.mts.map +0 -1
- package/dist/patch-3KLx2yEP.mjs.map +0 -1
- package/dist/smartart-BxnkROOp.mjs.map +0 -1
- package/dist/style-matrix-DAP6XrLv.mjs.map +0 -1
- package/dist/theme-OAuRcA9_.mjs.map +0 -1
- package/dist/theme-options-BbWccl85.d.mts.map +0 -1
- package/dist/util-C94-JKtp.mjs.map +0 -1
- package/dist/values-aVoirbWB.d.mts.map +0 -1
- package/dist/vector-TpjW6ZSc.mjs.map +0 -1
|
@@ -170,7 +170,8 @@ const positiveUniversalMeasureValue = (val) => {
|
|
|
170
170
|
*/
|
|
171
171
|
const hexColorValue = (val) => {
|
|
172
172
|
if (val === "auto") return val;
|
|
173
|
-
|
|
173
|
+
const color = stripColorHashPrefix(val);
|
|
174
|
+
return hexBinary(color, 3);
|
|
174
175
|
};
|
|
175
176
|
/**
|
|
176
177
|
* Strips the leading "#" prefix from a color string if present.
|
|
@@ -212,8 +213,8 @@ const parseOnOff = (raw) => {
|
|
|
212
213
|
if (raw === void 0) return void 0;
|
|
213
214
|
if (typeof raw === "boolean") return raw;
|
|
214
215
|
const s = String(raw).toLowerCase();
|
|
215
|
-
if (s === "1" || s === "true" || s === "on") return true;
|
|
216
|
-
if (s === "0" || s === "false" || s === "off") return false;
|
|
216
|
+
if (s === "1" || s === "true" || s === "on" || s === "t") return true;
|
|
217
|
+
if (s === "0" || s === "false" || s === "off" || s === "f") return false;
|
|
217
218
|
};
|
|
218
219
|
/**
|
|
219
220
|
* Validates a signed TWIP measurement value.
|
|
@@ -369,49 +370,6 @@ const pointMeasureValue = unsignedDecimalNumber;
|
|
|
369
370
|
* ```
|
|
370
371
|
*/
|
|
371
372
|
const dateTimeValue = (val) => val.toISOString();
|
|
372
|
-
/**
|
|
373
|
-
* Theme color values used throughout OOXML for referencing document theme colors.
|
|
374
|
-
*
|
|
375
|
-
* Reference: ST_ThemeColor in OOXML specification
|
|
376
|
-
*
|
|
377
|
-
* @publicApi
|
|
378
|
-
*/
|
|
379
|
-
const ThemeColor = {
|
|
380
|
-
DARK1: "dark1",
|
|
381
|
-
LIGHT1: "light1",
|
|
382
|
-
DARK2: "dark2",
|
|
383
|
-
LIGHT2: "light2",
|
|
384
|
-
ACCENT1: "accent1",
|
|
385
|
-
ACCENT2: "accent2",
|
|
386
|
-
ACCENT3: "accent3",
|
|
387
|
-
ACCENT4: "accent4",
|
|
388
|
-
ACCENT5: "accent5",
|
|
389
|
-
ACCENT6: "accent6",
|
|
390
|
-
HYPERLINK: "hyperlink",
|
|
391
|
-
FOLLOWED_HYPERLINK: "followedHyperlink",
|
|
392
|
-
NONE: "none",
|
|
393
|
-
BACKGROUND1: "background1",
|
|
394
|
-
TEXT1: "text1",
|
|
395
|
-
BACKGROUND2: "background2",
|
|
396
|
-
TEXT2: "text2"
|
|
397
|
-
};
|
|
398
|
-
/**
|
|
399
|
-
* Theme font values used for referencing document theme fonts.
|
|
400
|
-
*
|
|
401
|
-
* Reference: ST_Theme in OOXML specification
|
|
402
|
-
*
|
|
403
|
-
* @publicApi
|
|
404
|
-
*/
|
|
405
|
-
const ThemeFont = {
|
|
406
|
-
MAJOR_EAST_ASIA: "majorEastAsia",
|
|
407
|
-
MAJOR_BIDI: "majorBidi",
|
|
408
|
-
MAJOR_ASCII: "majorAscii",
|
|
409
|
-
MAJOR_H_ANSI: "majorHAnsi",
|
|
410
|
-
MINOR_EAST_ASIA: "minorEastAsia",
|
|
411
|
-
MINOR_BIDI: "minorBidi",
|
|
412
|
-
MINOR_ASCII: "minorAscii",
|
|
413
|
-
MINOR_H_ANSI: "minorHAnsi"
|
|
414
|
-
};
|
|
415
373
|
//#endregion
|
|
416
374
|
//#region \0polyfill-node.global.js
|
|
417
375
|
var _polyfill_node_global_default = typeof _polyfill_node_global_default !== "undefined" ? _polyfill_node_global_default : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};
|
|
@@ -936,18 +894,23 @@ function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) {
|
|
|
936
894
|
byteOffset = +byteOffset;
|
|
937
895
|
if (isNaN(byteOffset)) byteOffset = dir ? 0 : buffer.length - 1;
|
|
938
896
|
if (byteOffset < 0) byteOffset = buffer.length + byteOffset;
|
|
939
|
-
if (byteOffset >= buffer.length)
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
else
|
|
897
|
+
if (byteOffset >= buffer.length) {
|
|
898
|
+
if (dir) return -1;
|
|
899
|
+
else byteOffset = buffer.length - 1;
|
|
900
|
+
} else if (byteOffset < 0) {
|
|
901
|
+
if (dir) byteOffset = 0;
|
|
902
|
+
else return -1;
|
|
903
|
+
}
|
|
943
904
|
if (typeof val === "string") val = Buffer.from(val, encoding);
|
|
944
905
|
if (internalIsBuffer(val)) {
|
|
945
906
|
if (val.length === 0) return -1;
|
|
946
907
|
return arrayIndexOf(buffer, val, byteOffset, encoding, dir);
|
|
947
908
|
} else if (typeof val === "number") {
|
|
948
909
|
val = val & 255;
|
|
949
|
-
if (Buffer.TYPED_ARRAY_SUPPORT && typeof Uint8Array.prototype.indexOf === "function")
|
|
950
|
-
|
|
910
|
+
if (Buffer.TYPED_ARRAY_SUPPORT && typeof Uint8Array.prototype.indexOf === "function") {
|
|
911
|
+
if (dir) return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset);
|
|
912
|
+
else return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset);
|
|
913
|
+
}
|
|
951
914
|
return arrayIndexOf(buffer, [val], byteOffset, encoding, dir);
|
|
952
915
|
}
|
|
953
916
|
throw new TypeError("val must be string, number or Buffer");
|
|
@@ -1707,275 +1670,67 @@ function encodeBase64(bytes) {
|
|
|
1707
1670
|
return btoa(binary);
|
|
1708
1671
|
}
|
|
1709
1672
|
//#endregion
|
|
1710
|
-
//#region src/util/
|
|
1673
|
+
//#region src/util/data-type.ts
|
|
1711
1674
|
/**
|
|
1712
|
-
*
|
|
1675
|
+
* Binary input normalization.
|
|
1713
1676
|
*
|
|
1714
|
-
*
|
|
1715
|
-
*
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
/**
|
|
1719
|
-
* Convert public percent (100 = 100%) to OOXML ST_Percentage scalar (1/1000).
|
|
1720
|
-
* Math.round ensures JSON-first float input produces exact integer output.
|
|
1721
|
-
*/
|
|
1722
|
-
const emitPercent = (percent) => Math.round(percent * 1e3);
|
|
1723
|
-
/**
|
|
1724
|
-
* Convert OOXML ST_Percentage scalar (1/1000) to public percent.
|
|
1725
|
-
*/
|
|
1726
|
-
const parsePercent = (value) => value / 1e3;
|
|
1727
|
-
/**
|
|
1728
|
-
* Convert public degrees to OOXML ST_Angle / ST_FixedAngle scalar (1/60000).
|
|
1729
|
-
* Math.round ensures JSON-first float input produces exact integer output.
|
|
1730
|
-
*/
|
|
1731
|
-
const emitAngle = (degrees) => Math.round(degrees * 6e4);
|
|
1732
|
-
/**
|
|
1733
|
-
* Convert OOXML ST_Angle / ST_FixedAngle scalar (1/60000) to public degrees.
|
|
1734
|
-
*/
|
|
1735
|
-
const parseAngle = (value) => value / 6e4;
|
|
1736
|
-
/**
|
|
1737
|
-
* Converts millimeters to TWIP (twentieths of a point).
|
|
1738
|
-
*/
|
|
1739
|
-
const convertMillimetersToTwip = (millimeters) => Math.floor(millimeters / 25.4 * 72 * 20);
|
|
1740
|
-
/**
|
|
1741
|
-
* Converts inches to TWIP (twentieths of a point).
|
|
1742
|
-
*/
|
|
1743
|
-
const convertInchesToTwip = (inches) => Math.floor(inches * 72 * 20);
|
|
1744
|
-
/**
|
|
1745
|
-
* Converts pixels to EMU (96 DPI).
|
|
1746
|
-
*/
|
|
1747
|
-
const convertPixelsToEmu = (pixels) => Math.round(pixels * 9525);
|
|
1748
|
-
/**
|
|
1749
|
-
* Converts EMU to pixels (96 DPI).
|
|
1677
|
+
* Accepts the full range of binary inputs (Buffer/Uint8Array/ArrayBuffer/
|
|
1678
|
+
* DataView/number[]/string/base64 data URL/…) and normalizes to `Uint8Array`.
|
|
1679
|
+
* Centralized here so every entry point (packer, patch, descriptor helpers)
|
|
1680
|
+
* shares one definition instead of re-declaring per module.
|
|
1750
1681
|
*
|
|
1751
|
-
*
|
|
1752
|
-
* lived here before permanently discarded sub-pixel precision, which made an
|
|
1753
|
-
* EMU → pixel → EMU round-trip lossy (e.g. 5521960 EMU → 580 px → 5524500 EMU).
|
|
1754
|
-
* Keeping the fraction lets convertPixelsToEmu restore the exact original EMU.
|
|
1755
|
-
* Callers needing an integer pixel for display should Math.round the result.
|
|
1756
|
-
*/
|
|
1757
|
-
const convertEmuToPixels = (emus) => emus / 9525;
|
|
1758
|
-
/**
|
|
1759
|
-
* Converts inches to EMU.
|
|
1760
|
-
*/
|
|
1761
|
-
const convertInchesToEmu = (inches) => Math.round(inches * 914400);
|
|
1762
|
-
/**
|
|
1763
|
-
* Converts EMU to inches.
|
|
1764
|
-
*/
|
|
1765
|
-
const convertEmuToInches = (emus) => emus / 914400;
|
|
1766
|
-
/**
|
|
1767
|
-
* Converts points to EMU.
|
|
1768
|
-
*/
|
|
1769
|
-
const convertPointsToEmu = (points) => Math.round(points * 12700);
|
|
1770
|
-
/**
|
|
1771
|
-
* Converts EMU to points.
|
|
1682
|
+
* @module
|
|
1772
1683
|
*/
|
|
1773
|
-
const
|
|
1774
|
-
/**
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
/**
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1684
|
+
const DATA_URL_RE = /^data:([\w.+-]+\/[\w.+-]+)?;base64,/;
|
|
1685
|
+
/** Test whether a string is a base64 data URL (`data:[mime];base64,...`). */
|
|
1686
|
+
function isBase64DataURL(input) {
|
|
1687
|
+
return DATA_URL_RE.test(input);
|
|
1688
|
+
}
|
|
1689
|
+
/** Normalize any supported binary input to a `Uint8Array`. */
|
|
1690
|
+
function toUint8Array(data, options) {
|
|
1691
|
+
if (data instanceof Uint8Array) return data;
|
|
1692
|
+
if (data instanceof ArrayBuffer) return new Uint8Array(data);
|
|
1693
|
+
if (data instanceof DataView) return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
1694
|
+
if (typeof data === "string") {
|
|
1695
|
+
const match = data.match(DATA_URL_RE);
|
|
1696
|
+
if (match) return decodeBase64(data.slice(match[0].length));
|
|
1697
|
+
if (options?.encoding === "base64") return decodeBase64(data);
|
|
1698
|
+
return new TextEncoder().encode(data);
|
|
1699
|
+
}
|
|
1700
|
+
if (Array.isArray(data)) return new Uint8Array(data);
|
|
1701
|
+
if (data instanceof Blob) throw new TypeError("Blob input requires async processing");
|
|
1702
|
+
if (data instanceof ReadableStream) throw new TypeError("ReadableStream input requires async processing");
|
|
1703
|
+
throw new TypeError(`Unsupported data type: ${typeof data}`);
|
|
1704
|
+
}
|
|
1705
|
+
//#endregion
|
|
1706
|
+
//#region src/util/mappings.ts
|
|
1782
1707
|
/**
|
|
1783
|
-
*
|
|
1708
|
+
* Bidirectional mappings between user-friendly values and XSD abbreviated values.
|
|
1784
1709
|
*
|
|
1785
|
-
*
|
|
1786
|
-
*
|
|
1787
|
-
* @throws Error if the format is invalid
|
|
1710
|
+
* When XSD uses full English words (e.g. "center", "start"), values are used directly — no mapping needed.
|
|
1711
|
+
* When XSD uses abbreviations (e.g. "ctr", "l", "rnd"), this module maps them to full words.
|
|
1788
1712
|
*
|
|
1789
|
-
*
|
|
1790
|
-
*
|
|
1791
|
-
* parseUniversalMeasure("2.54cm"); // { value: 2.54, unit: "cm" }
|
|
1792
|
-
* parseUniversalMeasure("-10mm"); // { value: -10, unit: "mm" }
|
|
1793
|
-
* ```
|
|
1713
|
+
* Usage in generation (Options → XML): xsdAlign.to("center") → "ctr"
|
|
1714
|
+
* Usage in parsing (XML → Options): xsdAlign.from("ctr") → "center"
|
|
1794
1715
|
*/
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
const
|
|
1799
|
-
|
|
1716
|
+
/** Invert a Record<K, V> into Record<V, K>. */
|
|
1717
|
+
function invertMap(map) {
|
|
1718
|
+
const result = {};
|
|
1719
|
+
for (const key of Object.keys(map)) result[map[key]] = key;
|
|
1720
|
+
return result;
|
|
1721
|
+
}
|
|
1722
|
+
/** Create a bidirectional mapping helper from a single forward map. */
|
|
1723
|
+
function bidi(forward) {
|
|
1724
|
+
const reverse = invertMap(forward);
|
|
1800
1725
|
return {
|
|
1801
|
-
value
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
/**
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
*
|
|
1810
|
-
* @param measure - A universal measure string like "2.54cm", "1in", "12pt"
|
|
1811
|
-
* @returns The value in TWIP
|
|
1812
|
-
*
|
|
1813
|
-
* @example
|
|
1814
|
-
* ```typescript
|
|
1815
|
-
* convertUniversalMeasureToTwip("1in"); // 1440
|
|
1816
|
-
* convertUniversalMeasureToTwip("2.54cm"); // ~1440 (1 inch)
|
|
1817
|
-
* convertUniversalMeasureToTwip("72pt"); // 1440 (1 inch = 72pt = 1440 twips)
|
|
1818
|
-
* ```
|
|
1819
|
-
*/
|
|
1820
|
-
const convertUniversalMeasureToTwip = (measure) => {
|
|
1821
|
-
const { value, unit } = parseUniversalMeasure(measure);
|
|
1822
|
-
switch (unit) {
|
|
1823
|
-
case "mm": return convertMillimetersToTwip(value);
|
|
1824
|
-
case "cm": return convertMillimetersToTwip(value * 10);
|
|
1825
|
-
case "in": return convertInchesToTwip(value);
|
|
1826
|
-
case "pt": return Math.floor(value * 20);
|
|
1827
|
-
case "pc":
|
|
1828
|
-
case "pi": return Math.floor(value * 12 * 20);
|
|
1829
|
-
case "px": return Math.round(value * 15);
|
|
1830
|
-
}
|
|
1831
|
-
};
|
|
1832
|
-
/**
|
|
1833
|
-
* Converts a measurement value (number or UniversalMeasure) to TWIP.
|
|
1834
|
-
*
|
|
1835
|
-
* If the value is already a number, it is returned as-is (assumed to be in twips).
|
|
1836
|
-
* If the value is a UniversalMeasure string, it is converted to twips.
|
|
1837
|
-
*
|
|
1838
|
-
* Useful for accepting both `number` and `UniversalMeasure` inputs where
|
|
1839
|
-
* the XSD type is a union (e.g., ST_TwipsMeasure, ST_SignedTwipsMeasure).
|
|
1840
|
-
*
|
|
1841
|
-
* @param val - A numeric twip value or a universal measure string
|
|
1842
|
-
* @returns The value in TWIP
|
|
1843
|
-
*
|
|
1844
|
-
* @example
|
|
1845
|
-
* ```typescript
|
|
1846
|
-
* convertToTwip(1440); // 1440 (already twips)
|
|
1847
|
-
* convertToTwip("1in"); // 1440
|
|
1848
|
-
* convertToTwip("2.54cm"); // ~1440
|
|
1849
|
-
* ```
|
|
1850
|
-
*/
|
|
1851
|
-
const convertToTwip = (val) => typeof val === "string" ? convertUniversalMeasureToTwip(val) : val;
|
|
1852
|
-
/**
|
|
1853
|
-
* Converts a UniversalMeasure string to EMU (English Metric Units).
|
|
1854
|
-
*
|
|
1855
|
-
* Supports units: mm, cm, in, pt, pc (picas, 1pc = 12pt), pi (alias for pc).
|
|
1856
|
-
*
|
|
1857
|
-
* @param measure - A universal measure string like "2.54cm", "1in", "12pt"
|
|
1858
|
-
* @returns The value in EMU
|
|
1859
|
-
*
|
|
1860
|
-
* @example
|
|
1861
|
-
* ```typescript
|
|
1862
|
-
* convertUniversalMeasureToEmu("1in"); // 914400
|
|
1863
|
-
* convertUniversalMeasureToEmu("2.54cm"); // 914400
|
|
1864
|
-
* convertUniversalMeasureToEmu("12pt"); // 152400
|
|
1865
|
-
* ```
|
|
1866
|
-
*/
|
|
1867
|
-
const convertUniversalMeasureToEmu = (measure) => {
|
|
1868
|
-
const { value, unit } = parseUniversalMeasure(measure);
|
|
1869
|
-
switch (unit) {
|
|
1870
|
-
case "mm": return Math.round(value * 36e3);
|
|
1871
|
-
case "cm": return Math.round(value * 36e4);
|
|
1872
|
-
case "in": return convertInchesToEmu(value);
|
|
1873
|
-
case "pt": return convertPointsToEmu(value);
|
|
1874
|
-
case "pc":
|
|
1875
|
-
case "pi": return convertPointsToEmu(value * 12);
|
|
1876
|
-
case "px": return convertPixelsToEmu(value);
|
|
1877
|
-
}
|
|
1878
|
-
};
|
|
1879
|
-
/**
|
|
1880
|
-
* Converts a measurement value (number or UniversalMeasure) to EMU.
|
|
1881
|
-
*
|
|
1882
|
-
* Numbers are returned as-is (assumed EMU). Strings are parsed as
|
|
1883
|
-
* UniversalMeasure via {@link convertUniversalMeasureToEmu} — including the
|
|
1884
|
-
* project-only `px` unit (96 DPI). The result is always an EMU number written to
|
|
1885
|
-
* XML, so px never appears verbatim in the document.
|
|
1886
|
-
*
|
|
1887
|
-
* Useful for DrawingML fields where the XSD type is a union (e.g., ST_Coordinate).
|
|
1888
|
-
*
|
|
1889
|
-
* @param val - A numeric EMU value, or a UniversalMeasure string (incl. `${n}px`)
|
|
1890
|
-
* @returns The value in EMU
|
|
1891
|
-
*
|
|
1892
|
-
* @example
|
|
1893
|
-
* ```typescript
|
|
1894
|
-
* convertToEmu(914400); // 914400 (already EMU)
|
|
1895
|
-
* convertToEmu("1in"); // 914400
|
|
1896
|
-
* convertToEmu("2.54cm"); // 914400
|
|
1897
|
-
* convertToEmu("200px"); // 1905000 (200 * 9525)
|
|
1898
|
-
* ```
|
|
1899
|
-
*/
|
|
1900
|
-
const convertToEmu = (val) => typeof val === "string" ? convertUniversalMeasureToEmu(val) : val;
|
|
1901
|
-
/**
|
|
1902
|
-
* Converts a UniversalMeasure string to points (1pt = 1/72 inch).
|
|
1903
|
-
*
|
|
1904
|
-
* Supports units: mm, cm, in, pt, pc (picas, 1pc = 12pt), pi (alias for pc),
|
|
1905
|
-
* px (96 DPI).
|
|
1906
|
-
*/
|
|
1907
|
-
const convertUniversalMeasureToPt = (measure) => {
|
|
1908
|
-
const { value, unit } = parseUniversalMeasure(measure);
|
|
1909
|
-
switch (unit) {
|
|
1910
|
-
case "mm": return value / 25.4 * 72;
|
|
1911
|
-
case "cm": return value * 10 / 25.4 * 72;
|
|
1912
|
-
case "in": return value * 72;
|
|
1913
|
-
case "pt": return value;
|
|
1914
|
-
case "pc":
|
|
1915
|
-
case "pi": return value * 12;
|
|
1916
|
-
case "px": return value / 96 * 72;
|
|
1917
|
-
}
|
|
1918
|
-
};
|
|
1919
|
-
/**
|
|
1920
|
-
* Converts a measurement value (number or UniversalMeasure) to points.
|
|
1921
|
-
*
|
|
1922
|
-
* Numbers are returned as-is (assumed to be in points). Strings are parsed as
|
|
1923
|
-
* UniversalMeasure. Useful for SpreadsheetML fields where a number is points.
|
|
1924
|
-
*/
|
|
1925
|
-
const convertToPt = (val) => typeof val === "string" ? convertUniversalMeasureToPt(val) : val;
|
|
1926
|
-
/**
|
|
1927
|
-
* Converts a UniversalMeasure string to inches.
|
|
1928
|
-
*
|
|
1929
|
-
* Supports units: mm, cm, in, pt, pc, pi, px (96 DPI).
|
|
1930
|
-
*/
|
|
1931
|
-
const convertUniversalMeasureToInch = (measure) => {
|
|
1932
|
-
const { value, unit } = parseUniversalMeasure(measure);
|
|
1933
|
-
switch (unit) {
|
|
1934
|
-
case "mm": return value / 25.4;
|
|
1935
|
-
case "cm": return value * 10 / 25.4;
|
|
1936
|
-
case "in": return value;
|
|
1937
|
-
case "pt": return value / 72;
|
|
1938
|
-
case "pc":
|
|
1939
|
-
case "pi": return value * 12 / 72;
|
|
1940
|
-
case "px": return value / 96;
|
|
1941
|
-
}
|
|
1942
|
-
};
|
|
1943
|
-
/**
|
|
1944
|
-
* Converts a measurement value (number or UniversalMeasure) to inches.
|
|
1945
|
-
*
|
|
1946
|
-
* Numbers are returned as-is (assumed to be in inches). Useful for SpreadsheetML
|
|
1947
|
-
* page-margin fields where a number is inches.
|
|
1948
|
-
*/
|
|
1949
|
-
const convertToInch = (val) => typeof val === "string" ? convertUniversalMeasureToInch(val) : val;
|
|
1950
|
-
//#endregion
|
|
1951
|
-
//#region src/util/mappings.ts
|
|
1952
|
-
/**
|
|
1953
|
-
* Bidirectional mappings between user-friendly values and XSD abbreviated values.
|
|
1954
|
-
*
|
|
1955
|
-
* When XSD uses full English words (e.g. "center", "start"), values are used directly — no mapping needed.
|
|
1956
|
-
* When XSD uses abbreviations (e.g. "ctr", "l", "rnd"), this module maps them to full words.
|
|
1957
|
-
*
|
|
1958
|
-
* Usage in generation (Options → XML): xsdAlign.to("center") → "ctr"
|
|
1959
|
-
* Usage in parsing (XML → Options): xsdAlign.from("ctr") → "center"
|
|
1960
|
-
*/
|
|
1961
|
-
/** Invert a Record<K, V> into Record<V, K>. */
|
|
1962
|
-
function invertMap(map) {
|
|
1963
|
-
const result = {};
|
|
1964
|
-
for (const key of Object.keys(map)) result[map[key]] = key;
|
|
1965
|
-
return result;
|
|
1966
|
-
}
|
|
1967
|
-
/** Create a bidirectional mapping helper from a single forward map. */
|
|
1968
|
-
function bidi(forward) {
|
|
1969
|
-
const reverse = invertMap(forward);
|
|
1970
|
-
return {
|
|
1971
|
-
/** User-friendly value → XSD value */
|
|
1972
|
-
to: (key) => forward[key] ?? key,
|
|
1973
|
-
/** XSD value → user-friendly value */
|
|
1974
|
-
from: (xsd) => reverse[xsd] ?? xsd,
|
|
1975
|
-
/** The forward map (user → XSD) */
|
|
1976
|
-
forward,
|
|
1977
|
-
/** The reverse map (XSD → user) */
|
|
1978
|
-
reverse
|
|
1726
|
+
/** User-friendly value → XSD value */
|
|
1727
|
+
to: (key) => forward[key] ?? key,
|
|
1728
|
+
/** XSD value → user-friendly value */
|
|
1729
|
+
from: (xsd) => reverse[xsd] ?? xsd,
|
|
1730
|
+
/** The forward map (user → XSD) */
|
|
1731
|
+
forward,
|
|
1732
|
+
/** The reverse map (XSD → user) */
|
|
1733
|
+
reverse
|
|
1979
1734
|
};
|
|
1980
1735
|
}
|
|
1981
1736
|
const xsdRectAlignment = bidi({
|
|
@@ -2064,6 +1819,16 @@ const xsdPresetShadow = bidi({
|
|
|
2064
1819
|
shadow19: "shdw19",
|
|
2065
1820
|
shadow20: "shdw20"
|
|
2066
1821
|
});
|
|
1822
|
+
const xsdLightRigDirection = bidi({
|
|
1823
|
+
topLeft: "tl",
|
|
1824
|
+
top: "t",
|
|
1825
|
+
topRight: "tr",
|
|
1826
|
+
left: "l",
|
|
1827
|
+
right: "r",
|
|
1828
|
+
bottomLeft: "bl",
|
|
1829
|
+
bottom: "b",
|
|
1830
|
+
bottomRight: "br"
|
|
1831
|
+
});
|
|
2067
1832
|
const xsdMaterialType = bidi({
|
|
2068
1833
|
legacyMatte: "legacyMatte",
|
|
2069
1834
|
legacyPlastic: "legacyPlastic",
|
|
@@ -2156,39 +1921,493 @@ const xsdTextCaps = bidi({
|
|
|
2156
1921
|
all: "all",
|
|
2157
1922
|
small: "small"
|
|
2158
1923
|
});
|
|
1924
|
+
const xsdAxisPosition = bidi({
|
|
1925
|
+
bottom: "b",
|
|
1926
|
+
left: "l",
|
|
1927
|
+
right: "r",
|
|
1928
|
+
top: "t"
|
|
1929
|
+
});
|
|
1930
|
+
const xsdLegendPosition = bidi({
|
|
1931
|
+
bottom: "b",
|
|
1932
|
+
topRight: "tr",
|
|
1933
|
+
left: "l",
|
|
1934
|
+
right: "r",
|
|
1935
|
+
top: "t"
|
|
1936
|
+
});
|
|
1937
|
+
const xsdDataLabelPosition = bidi({
|
|
1938
|
+
bottom: "b",
|
|
1939
|
+
center: "ctr",
|
|
1940
|
+
insideBase: "inBase",
|
|
1941
|
+
insideEnd: "inEnd",
|
|
1942
|
+
left: "l",
|
|
1943
|
+
outsideEnd: "outEnd",
|
|
1944
|
+
right: "r",
|
|
1945
|
+
top: "t"
|
|
1946
|
+
});
|
|
1947
|
+
const xsdAxisCrossBetween = bidi({ middleOfCategory: "midCat" });
|
|
1948
|
+
const xsdAxisCrosses = bidi({ zero: "autoZero" });
|
|
1949
|
+
const xsdComments = bidi({
|
|
1950
|
+
none: "commNone",
|
|
1951
|
+
indicator: "commIndicator",
|
|
1952
|
+
comment: "commIndAndComment"
|
|
1953
|
+
});
|
|
1954
|
+
const xsdErrorValueType = bidi({
|
|
1955
|
+
custom: "cust",
|
|
1956
|
+
fixedValue: "fixedVal",
|
|
1957
|
+
standardDeviation: "stdDev",
|
|
1958
|
+
standardError: "stdErr"
|
|
1959
|
+
});
|
|
1960
|
+
const xsdSizeRepresents = bidi({ width: "w" });
|
|
1961
|
+
const xsdSplitType = bidi({
|
|
1962
|
+
custom: "cust",
|
|
1963
|
+
position: "pos",
|
|
1964
|
+
value: "val"
|
|
1965
|
+
});
|
|
1966
|
+
const xsdAxisLabelAlignment = bidi({
|
|
1967
|
+
center: "ctr",
|
|
1968
|
+
left: "l",
|
|
1969
|
+
right: "r"
|
|
1970
|
+
});
|
|
1971
|
+
const xsdAxisOrientation = bidi({
|
|
1972
|
+
ascending: "minMax",
|
|
1973
|
+
descending: "maxMin"
|
|
1974
|
+
});
|
|
1975
|
+
const xsdTrendlineType = bidi({
|
|
1976
|
+
exponential: "exp",
|
|
1977
|
+
logarithmic: "log",
|
|
1978
|
+
movingAverage: "movingAvg",
|
|
1979
|
+
polynomial: "poly"
|
|
1980
|
+
});
|
|
1981
|
+
const xsdTextTabAlignment = bidi({
|
|
1982
|
+
left: "l",
|
|
1983
|
+
center: "ctr",
|
|
1984
|
+
right: "r",
|
|
1985
|
+
decimal: "dec"
|
|
1986
|
+
});
|
|
1987
|
+
const xsdFontAlignment = bidi({
|
|
1988
|
+
top: "t",
|
|
1989
|
+
center: "ctr",
|
|
1990
|
+
bottom: "b"
|
|
1991
|
+
});
|
|
1992
|
+
const xsdAnimLevel = bidi({
|
|
1993
|
+
level: "lvl",
|
|
1994
|
+
center: "ctr"
|
|
1995
|
+
});
|
|
1996
|
+
const xsdHierBranch = bidi({
|
|
1997
|
+
left: "l",
|
|
1998
|
+
right: "r",
|
|
1999
|
+
hanging: "hang",
|
|
2000
|
+
standard: "std",
|
|
2001
|
+
initial: "init"
|
|
2002
|
+
});
|
|
2003
|
+
const xsdHueDirection = bidi({
|
|
2004
|
+
clockwise: "cw",
|
|
2005
|
+
counterClockwise: "ccw"
|
|
2006
|
+
});
|
|
2007
|
+
const xsdDiagramDirection = bidi({
|
|
2008
|
+
normal: "norm",
|
|
2009
|
+
reversed: "rev"
|
|
2010
|
+
});
|
|
2011
|
+
const xsdResizeHandles = bidi({
|
|
2012
|
+
exact: "exact",
|
|
2013
|
+
relative: "rel"
|
|
2014
|
+
});
|
|
2015
|
+
const xsdOnOffStyle = bidi({ default: "def" });
|
|
2016
|
+
const xsdAnimClass = bidi({
|
|
2017
|
+
entrance: "entr",
|
|
2018
|
+
emphasis: "emph",
|
|
2019
|
+
mediaCall: "mediacall"
|
|
2020
|
+
});
|
|
2021
|
+
const xsdAnimCalcMode = bidi({
|
|
2022
|
+
linear: "lin",
|
|
2023
|
+
formula: "fmla"
|
|
2024
|
+
});
|
|
2025
|
+
const xsdAnimValueType = bidi({
|
|
2026
|
+
string: "str",
|
|
2027
|
+
number: "num",
|
|
2028
|
+
color: "clr"
|
|
2029
|
+
});
|
|
2030
|
+
const xsdTextBuild = bidi({
|
|
2031
|
+
paragraph: "p",
|
|
2032
|
+
custom: "cust"
|
|
2033
|
+
});
|
|
2034
|
+
const xsdDiagramBuild = bidi({
|
|
2035
|
+
clockwise: "cw",
|
|
2036
|
+
clockwiseIn: "cwIn",
|
|
2037
|
+
clockwiseOut: "cwOut",
|
|
2038
|
+
counterclockwise: "ccw",
|
|
2039
|
+
counterclockwiseIn: "ccwIn",
|
|
2040
|
+
counterclockwiseOut: "ccwOut",
|
|
2041
|
+
custom: "cust"
|
|
2042
|
+
});
|
|
2043
|
+
const xsdChartBuild = bidi({
|
|
2044
|
+
seriesElement: "seriesEl",
|
|
2045
|
+
categoryElement: "categoryEl"
|
|
2046
|
+
});
|
|
2047
|
+
const xsdAnimationDgmBuild = bidi({
|
|
2048
|
+
levelOne: "lvlOne",
|
|
2049
|
+
levelAtOnce: "lvlAtOnce"
|
|
2050
|
+
});
|
|
2051
|
+
const xsdIterateType = bidi({
|
|
2052
|
+
element: "el",
|
|
2053
|
+
word: "wd",
|
|
2054
|
+
letter: "lt"
|
|
2055
|
+
});
|
|
2056
|
+
const xsdSlideLayoutType = bidi({
|
|
2057
|
+
text: "tx",
|
|
2058
|
+
twoColumnText: "twoColTx",
|
|
2059
|
+
object: "obj",
|
|
2060
|
+
sectionHeader: "secHead",
|
|
2061
|
+
table: "tbl",
|
|
2062
|
+
clipArtAndText: "clipArtAndTx",
|
|
2063
|
+
pictureText: "picTx",
|
|
2064
|
+
twoObjects: "twoObj",
|
|
2065
|
+
twoTextAndTwoObjects: "twoTxTwoObj",
|
|
2066
|
+
objectAndText: "objTx",
|
|
2067
|
+
verticalText: "vertTx",
|
|
2068
|
+
verticalTitleAndText: "vertTitleAndTx"
|
|
2069
|
+
});
|
|
2070
|
+
const xsdTextVerticalType = bidi({
|
|
2071
|
+
horizontal: "horz",
|
|
2072
|
+
vertical: "vert",
|
|
2073
|
+
vertical270: "vert270",
|
|
2074
|
+
wordArtVertical: "wordArtVert",
|
|
2075
|
+
eastAsianVertical: "eaVert",
|
|
2076
|
+
mongolianVertical: "mongolianVert",
|
|
2077
|
+
wordArtVerticalRightToLeft: "wordArtVertRtl"
|
|
2078
|
+
});
|
|
2079
|
+
const xsdDashStyle = bidi({
|
|
2080
|
+
longDash: "lgDash",
|
|
2081
|
+
systemDot: "sysDot",
|
|
2082
|
+
systemDash: "sysDash"
|
|
2083
|
+
});
|
|
2084
|
+
const xsdOrient = bidi({
|
|
2085
|
+
horizontal: "horz",
|
|
2086
|
+
vertical: "vert"
|
|
2087
|
+
});
|
|
2088
|
+
const xsdPlaceholderType = bidi({
|
|
2089
|
+
centerTitle: "ctrTitle",
|
|
2090
|
+
date: "dt",
|
|
2091
|
+
slideNumber: "sldNum",
|
|
2092
|
+
footer: "ftr",
|
|
2093
|
+
header: "hdr",
|
|
2094
|
+
object: "obj",
|
|
2095
|
+
table: "tbl",
|
|
2096
|
+
diagram: "dgm",
|
|
2097
|
+
slideImage: "sldImg",
|
|
2098
|
+
picture: "pic"
|
|
2099
|
+
});
|
|
2100
|
+
const xsdMathStyle = bidi({
|
|
2101
|
+
plain: "p",
|
|
2102
|
+
bold: "b",
|
|
2103
|
+
italic: "i",
|
|
2104
|
+
boldItalic: "bi"
|
|
2105
|
+
});
|
|
2106
|
+
const xsdTableWidthType = bidi({
|
|
2107
|
+
twips: "dxa",
|
|
2108
|
+
percent: "pct"
|
|
2109
|
+
});
|
|
2110
|
+
const xsdJcAlignment = bidi({ numericTab: "numTab" });
|
|
2111
|
+
const xsdConsolidateFunction = bidi({
|
|
2112
|
+
countNumbers: "countNums",
|
|
2113
|
+
standardDeviation: "stdDev",
|
|
2114
|
+
standardDeviationPopulation: "stdDevp",
|
|
2115
|
+
variance: "var",
|
|
2116
|
+
variancePopulation: "varp"
|
|
2117
|
+
});
|
|
2118
|
+
const xsdShadingPattern = bidi({
|
|
2119
|
+
horizontalStripe: "horzStripe",
|
|
2120
|
+
verticalStripe: "vertStripe",
|
|
2121
|
+
reverseDiagonalStripe: "reverseDiagStripe",
|
|
2122
|
+
diagonalStripe: "diagStripe",
|
|
2123
|
+
horizontalCross: "horzCross",
|
|
2124
|
+
diagonalCross: "diagCross",
|
|
2125
|
+
thinHorizontalStripe: "thinHorzStripe",
|
|
2126
|
+
thinVerticalStripe: "thinVertStripe",
|
|
2127
|
+
thinReverseDiagonalStripe: "thinReverseDiagStripe",
|
|
2128
|
+
thinDiagonalStripe: "thinDiagStripe",
|
|
2129
|
+
thinHorizontalCross: "thinHorzCross",
|
|
2130
|
+
thinDiagonalCross: "thinDiagCross",
|
|
2131
|
+
percent5: "pct5",
|
|
2132
|
+
percent10: "pct10",
|
|
2133
|
+
percent12: "pct12",
|
|
2134
|
+
percent15: "pct15",
|
|
2135
|
+
percent20: "pct20",
|
|
2136
|
+
percent25: "pct25",
|
|
2137
|
+
percent30: "pct30",
|
|
2138
|
+
percent35: "pct35",
|
|
2139
|
+
percent37: "pct37",
|
|
2140
|
+
percent40: "pct40",
|
|
2141
|
+
percent45: "pct45",
|
|
2142
|
+
percent50: "pct50",
|
|
2143
|
+
percent55: "pct55",
|
|
2144
|
+
percent60: "pct60",
|
|
2145
|
+
percent62: "pct62",
|
|
2146
|
+
percent65: "pct65",
|
|
2147
|
+
percent70: "pct70",
|
|
2148
|
+
percent75: "pct75",
|
|
2149
|
+
percent80: "pct80",
|
|
2150
|
+
percent85: "pct85",
|
|
2151
|
+
percent87: "pct87",
|
|
2152
|
+
percent90: "pct90",
|
|
2153
|
+
percent95: "pct95"
|
|
2154
|
+
});
|
|
2155
|
+
const xsdTotalsRowFunction = bidi({
|
|
2156
|
+
countNumbers: "countNums",
|
|
2157
|
+
standardDeviation: "stdDev",
|
|
2158
|
+
variance: "var"
|
|
2159
|
+
});
|
|
2159
2160
|
//#endregion
|
|
2160
|
-
//#region src/util/
|
|
2161
|
+
//#region src/util/converters.ts
|
|
2161
2162
|
/**
|
|
2162
|
-
*
|
|
2163
|
+
* Apply `fn` to `value` unless it is `undefined`; `undefined` passes through.
|
|
2163
2164
|
*
|
|
2164
|
-
*
|
|
2165
|
-
*
|
|
2166
|
-
|
|
2167
|
-
|
|
2165
|
+
* Lets an optional field (e.g. `radius?: number | UniversalMeasure`) be threaded
|
|
2166
|
+
* through a conversion without a per-call ternary.
|
|
2167
|
+
*/
|
|
2168
|
+
const mapOptional = (value, fn) => value === void 0 ? void 0 : fn(value);
|
|
2169
|
+
/**
|
|
2170
|
+
* Convert public percent (100 = 100%) to OOXML ST_Percentage scalar (1/1000).
|
|
2171
|
+
* Math.round ensures JSON-first float input produces exact integer output.
|
|
2172
|
+
*/
|
|
2173
|
+
const emitPercent = (percent) => Math.round(percent * 1e3);
|
|
2174
|
+
/**
|
|
2175
|
+
* Convert OOXML ST_Percentage scalar (1/1000) to public percent.
|
|
2176
|
+
*/
|
|
2177
|
+
const parsePercent = (value) => value / 1e3;
|
|
2178
|
+
/**
|
|
2179
|
+
* Parse an ST_Percentage attribute that may arrive as either a 1/1000th
|
|
2180
|
+
* integer ("50000" = 50%) or a percent literal ("50%"); both are XSD-valid.
|
|
2181
|
+
* Returns the caller-facing integer percent.
|
|
2182
|
+
*/
|
|
2183
|
+
const parsePercentAttr = (raw) => {
|
|
2184
|
+
if (raw === void 0) return void 0;
|
|
2185
|
+
const s = typeof raw === "number" ? String(raw) : raw;
|
|
2186
|
+
return s.endsWith("%") ? Number(s.slice(0, -1)) : parsePercent(Number(s));
|
|
2187
|
+
};
|
|
2188
|
+
/**
|
|
2189
|
+
* Convert public degrees to OOXML ST_Angle / ST_FixedAngle scalar (1/60000).
|
|
2190
|
+
* Math.round ensures JSON-first float input produces exact integer output.
|
|
2191
|
+
*/
|
|
2192
|
+
const emitAngle = (degrees) => Math.round(degrees * 6e4);
|
|
2193
|
+
/**
|
|
2194
|
+
* Convert OOXML ST_Angle / ST_FixedAngle scalar (1/60000) to public degrees.
|
|
2195
|
+
*/
|
|
2196
|
+
const parseAngle = (value) => value / 6e4;
|
|
2197
|
+
/**
|
|
2198
|
+
* Converts millimeters to TWIP (twentieths of a point).
|
|
2199
|
+
*/
|
|
2200
|
+
const convertMillimetersToTwip = (millimeters) => Math.floor(millimeters / 25.4 * 72 * 20);
|
|
2201
|
+
/**
|
|
2202
|
+
* Converts inches to TWIP (twentieths of a point).
|
|
2203
|
+
*/
|
|
2204
|
+
const convertInchesToTwip = (inches) => Math.floor(inches * 72 * 20);
|
|
2205
|
+
/**
|
|
2206
|
+
* Converts pixels to EMU (96 DPI).
|
|
2207
|
+
*/
|
|
2208
|
+
const convertPixelsToEmu = (pixels) => Math.round(pixels * 9525);
|
|
2209
|
+
/**
|
|
2210
|
+
* Converts EMU to pixels (96 DPI).
|
|
2168
2211
|
*
|
|
2169
|
-
*
|
|
2212
|
+
* Returns a possibly fractional (sub-pixel) value. The integer rounding that
|
|
2213
|
+
* lived here before permanently discarded sub-pixel precision, which made an
|
|
2214
|
+
* EMU → pixel → EMU round-trip lossy (e.g. 5521960 EMU → 580 px → 5524500 EMU).
|
|
2215
|
+
* Keeping the fraction lets convertPixelsToEmu restore the exact original EMU.
|
|
2216
|
+
* Callers needing an integer pixel for display should Math.round the result.
|
|
2170
2217
|
*/
|
|
2171
|
-
const
|
|
2172
|
-
/**
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
/**
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2218
|
+
const convertEmuToPixels = (emus) => emus / 9525;
|
|
2219
|
+
/**
|
|
2220
|
+
* Converts inches to EMU.
|
|
2221
|
+
*/
|
|
2222
|
+
const convertInchesToEmu = (inches) => Math.round(inches * 914400);
|
|
2223
|
+
/**
|
|
2224
|
+
* Converts EMU to inches.
|
|
2225
|
+
*/
|
|
2226
|
+
const convertEmuToInches = (emus) => emus / 914400;
|
|
2227
|
+
/**
|
|
2228
|
+
* Converts points to EMU.
|
|
2229
|
+
*/
|
|
2230
|
+
const convertPointsToEmu = (points) => Math.round(points * 12700);
|
|
2231
|
+
/**
|
|
2232
|
+
* Converts EMU to points.
|
|
2233
|
+
*/
|
|
2234
|
+
const convertEmuToPoints = (emus) => emus / 12700;
|
|
2235
|
+
/** Converts EMU to TWIP (1 TWIP = 635 EMU). */
|
|
2236
|
+
const convertEmuToTwip = (emus) => Math.round(emus / 635);
|
|
2237
|
+
/** Converts TWIP to EMU (1 TWIP = 635 EMU). */
|
|
2238
|
+
const convertTwipToEmu = (twips) => twips * 635;
|
|
2239
|
+
/** Converts points to TWIP (1 point = 20 TWIP). */
|
|
2240
|
+
const convertPointsToTwip = (points) => Math.round(points * 20);
|
|
2241
|
+
/** Converts TWIP to points (1 point = 20 TWIP). */
|
|
2242
|
+
const convertTwipToPoints = (twips) => twips / 20;
|
|
2243
|
+
/**
|
|
2244
|
+
* Parse a UniversalMeasure string into its numeric value and unit.
|
|
2245
|
+
*
|
|
2246
|
+
* @param measure - A universal measure string like "2.54cm", "-10mm", "1in"
|
|
2247
|
+
* @returns The parsed value and unit
|
|
2248
|
+
* @throws Error if the format is invalid
|
|
2249
|
+
*
|
|
2250
|
+
* @example
|
|
2251
|
+
* ```typescript
|
|
2252
|
+
* parseUniversalMeasure("2.54cm"); // { value: 2.54, unit: "cm" }
|
|
2253
|
+
* parseUniversalMeasure("-10mm"); // { value: -10, unit: "mm" }
|
|
2254
|
+
* ```
|
|
2255
|
+
*/
|
|
2256
|
+
const parseUniversalMeasure = (measure) => {
|
|
2257
|
+
const match = measure.match(/^(-?[0-9]+(?:\.[0-9]+)?)(mm|cm|in|pt|pc|pi|px)$/);
|
|
2258
|
+
if (!match) throw new Error(`Invalid universal measure: '${measure}'`);
|
|
2259
|
+
const [, value, unit] = match;
|
|
2260
|
+
if (value === void 0 || unit === void 0) throw new Error(`Invalid universal measure: '${measure}'`);
|
|
2261
|
+
return {
|
|
2262
|
+
value: parseFloat(value),
|
|
2263
|
+
unit
|
|
2264
|
+
};
|
|
2265
|
+
};
|
|
2266
|
+
/**
|
|
2267
|
+
* Converts a UniversalMeasure string to TWIP (twentieths of a point).
|
|
2268
|
+
*
|
|
2269
|
+
* Supports units: mm, cm, in, pt, pc (picas, 1pc = 12pt), pi (alias for pc).
|
|
2270
|
+
*
|
|
2271
|
+
* @param measure - A universal measure string like "2.54cm", "1in", "12pt"
|
|
2272
|
+
* @returns The value in TWIP
|
|
2273
|
+
*
|
|
2274
|
+
* @example
|
|
2275
|
+
* ```typescript
|
|
2276
|
+
* convertUniversalMeasureToTwip("1in"); // 1440
|
|
2277
|
+
* convertUniversalMeasureToTwip("2.54cm"); // ~1440 (1 inch)
|
|
2278
|
+
* convertUniversalMeasureToTwip("72pt"); // 1440 (1 inch = 72pt = 1440 twips)
|
|
2279
|
+
* ```
|
|
2280
|
+
*/
|
|
2281
|
+
const convertUniversalMeasureToTwip = (measure) => {
|
|
2282
|
+
const { value, unit } = parseUniversalMeasure(measure);
|
|
2283
|
+
switch (unit) {
|
|
2284
|
+
case "mm": return convertMillimetersToTwip(value);
|
|
2285
|
+
case "cm": return convertMillimetersToTwip(value * 10);
|
|
2286
|
+
case "in": return convertInchesToTwip(value);
|
|
2287
|
+
case "pt": return Math.floor(value * 20);
|
|
2288
|
+
case "pc":
|
|
2289
|
+
case "pi": return Math.floor(value * 12 * 20);
|
|
2290
|
+
case "px": return Math.round(value * 15);
|
|
2186
2291
|
}
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2292
|
+
};
|
|
2293
|
+
/**
|
|
2294
|
+
* Converts a measurement value (number or UniversalMeasure) to TWIP.
|
|
2295
|
+
*
|
|
2296
|
+
* If the value is already a number, it is returned as-is (assumed to be in twips).
|
|
2297
|
+
* If the value is a UniversalMeasure string, it is converted to twips.
|
|
2298
|
+
*
|
|
2299
|
+
* Useful for accepting both `number` and `UniversalMeasure` inputs where
|
|
2300
|
+
* the XSD type is a union (e.g., ST_TwipsMeasure, ST_SignedTwipsMeasure).
|
|
2301
|
+
*
|
|
2302
|
+
* @param val - A numeric twip value or a universal measure string
|
|
2303
|
+
* @returns The value in TWIP
|
|
2304
|
+
*
|
|
2305
|
+
* @example
|
|
2306
|
+
* ```typescript
|
|
2307
|
+
* convertToTwip(1440); // 1440 (already twips)
|
|
2308
|
+
* convertToTwip("1in"); // 1440
|
|
2309
|
+
* convertToTwip("2.54cm"); // ~1440
|
|
2310
|
+
* ```
|
|
2311
|
+
*/
|
|
2312
|
+
const convertToTwip = (val) => typeof val === "string" ? convertUniversalMeasureToTwip(val) : val;
|
|
2313
|
+
/**
|
|
2314
|
+
* Converts a UniversalMeasure string to EMU (English Metric Units).
|
|
2315
|
+
*
|
|
2316
|
+
* Supports units: mm, cm, in, pt, pc (picas, 1pc = 12pt), pi (alias for pc).
|
|
2317
|
+
*
|
|
2318
|
+
* @param measure - A universal measure string like "2.54cm", "1in", "12pt"
|
|
2319
|
+
* @returns The value in EMU
|
|
2320
|
+
*
|
|
2321
|
+
* @example
|
|
2322
|
+
* ```typescript
|
|
2323
|
+
* convertUniversalMeasureToEmu("1in"); // 914400
|
|
2324
|
+
* convertUniversalMeasureToEmu("2.54cm"); // 914400
|
|
2325
|
+
* convertUniversalMeasureToEmu("12pt"); // 152400
|
|
2326
|
+
* ```
|
|
2327
|
+
*/
|
|
2328
|
+
const convertUniversalMeasureToEmu = (measure) => {
|
|
2329
|
+
const { value, unit } = parseUniversalMeasure(measure);
|
|
2330
|
+
switch (unit) {
|
|
2331
|
+
case "mm": return Math.round(value * 36e3);
|
|
2332
|
+
case "cm": return Math.round(value * 36e4);
|
|
2333
|
+
case "in": return convertInchesToEmu(value);
|
|
2334
|
+
case "pt": return convertPointsToEmu(value);
|
|
2335
|
+
case "pc":
|
|
2336
|
+
case "pi": return convertPointsToEmu(value * 12);
|
|
2337
|
+
case "px": return convertPixelsToEmu(value);
|
|
2338
|
+
}
|
|
2339
|
+
};
|
|
2340
|
+
/**
|
|
2341
|
+
* Converts a measurement value (number or UniversalMeasure) to EMU.
|
|
2342
|
+
*
|
|
2343
|
+
* Numbers are returned as-is (assumed EMU). Strings are parsed as
|
|
2344
|
+
* UniversalMeasure via {@link convertUniversalMeasureToEmu} — including the
|
|
2345
|
+
* project-only `px` unit (96 DPI). The result is always an EMU number written to
|
|
2346
|
+
* XML, so px never appears verbatim in the document.
|
|
2347
|
+
*
|
|
2348
|
+
* Useful for DrawingML fields where the XSD type is a union (e.g., ST_Coordinate).
|
|
2349
|
+
*
|
|
2350
|
+
* @param val - A numeric EMU value, or a UniversalMeasure string (incl. `${n}px`)
|
|
2351
|
+
* @returns The value in EMU
|
|
2352
|
+
*
|
|
2353
|
+
* @example
|
|
2354
|
+
* ```typescript
|
|
2355
|
+
* convertToEmu(914400); // 914400 (already EMU)
|
|
2356
|
+
* convertToEmu("1in"); // 914400
|
|
2357
|
+
* convertToEmu("2.54cm"); // 914400
|
|
2358
|
+
* convertToEmu("200px"); // 1905000 (200 * 9525)
|
|
2359
|
+
* ```
|
|
2360
|
+
*/
|
|
2361
|
+
const convertToEmu = (val) => typeof val === "string" ? convertUniversalMeasureToEmu(val) : val;
|
|
2362
|
+
/**
|
|
2363
|
+
* Converts a UniversalMeasure string to points (1pt = 1/72 inch).
|
|
2364
|
+
*
|
|
2365
|
+
* Supports units: mm, cm, in, pt, pc (picas, 1pc = 12pt), pi (alias for pc),
|
|
2366
|
+
* px (96 DPI).
|
|
2367
|
+
*/
|
|
2368
|
+
const convertUniversalMeasureToPt = (measure) => {
|
|
2369
|
+
const { value, unit } = parseUniversalMeasure(measure);
|
|
2370
|
+
switch (unit) {
|
|
2371
|
+
case "mm": return value / 25.4 * 72;
|
|
2372
|
+
case "cm": return value * 10 / 25.4 * 72;
|
|
2373
|
+
case "in": return value * 72;
|
|
2374
|
+
case "pt": return value;
|
|
2375
|
+
case "pc":
|
|
2376
|
+
case "pi": return value * 12;
|
|
2377
|
+
case "px": return value / 96 * 72;
|
|
2378
|
+
}
|
|
2379
|
+
};
|
|
2380
|
+
/**
|
|
2381
|
+
* Converts a measurement value (number or UniversalMeasure) to points.
|
|
2382
|
+
*
|
|
2383
|
+
* Numbers are returned as-is (assumed to be in points). Strings are parsed as
|
|
2384
|
+
* UniversalMeasure. Useful for SpreadsheetML fields where a number is points.
|
|
2385
|
+
*/
|
|
2386
|
+
const convertToPt = (val) => typeof val === "string" ? convertUniversalMeasureToPt(val) : val;
|
|
2387
|
+
/**
|
|
2388
|
+
* Converts a UniversalMeasure string to inches.
|
|
2389
|
+
*
|
|
2390
|
+
* Supports units: mm, cm, in, pt, pc, pi, px (96 DPI).
|
|
2391
|
+
*/
|
|
2392
|
+
const convertUniversalMeasureToInch = (measure) => {
|
|
2393
|
+
const { value, unit } = parseUniversalMeasure(measure);
|
|
2394
|
+
switch (unit) {
|
|
2395
|
+
case "mm": return value / 25.4;
|
|
2396
|
+
case "cm": return value * 10 / 25.4;
|
|
2397
|
+
case "in": return value;
|
|
2398
|
+
case "pt": return value / 72;
|
|
2399
|
+
case "pc":
|
|
2400
|
+
case "pi": return value * 12 / 72;
|
|
2401
|
+
case "px": return value / 96;
|
|
2402
|
+
}
|
|
2403
|
+
};
|
|
2404
|
+
/**
|
|
2405
|
+
* Converts a measurement value (number or UniversalMeasure) to inches.
|
|
2406
|
+
*
|
|
2407
|
+
* Numbers are returned as-is (assumed to be in inches). Useful for SpreadsheetML
|
|
2408
|
+
* page-margin fields where a number is inches.
|
|
2409
|
+
*/
|
|
2410
|
+
const convertToInch = (val) => typeof val === "string" ? convertUniversalMeasureToInch(val) : val;
|
|
2192
2411
|
//#endregion
|
|
2193
2412
|
//#region src/util/generators.ts
|
|
2194
2413
|
/**
|
|
@@ -2208,7 +2427,7 @@ const URL_ALPHABET = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvw
|
|
|
2208
2427
|
* Generates a unique lowercase alphanumeric ID using crypto.getRandomValues.
|
|
2209
2428
|
*/
|
|
2210
2429
|
const uniqueId = () => {
|
|
2211
|
-
const bytes = new Uint8Array(21);
|
|
2430
|
+
const bytes = /* @__PURE__ */ new Uint8Array(21);
|
|
2212
2431
|
crypto.getRandomValues(bytes);
|
|
2213
2432
|
let id = "";
|
|
2214
2433
|
for (const byte of bytes) id += URL_ALPHABET[byte & 63];
|
|
@@ -2218,13 +2437,50 @@ const uniqueId = () => {
|
|
|
2218
2437
|
* Generates a SHA-1 hash of the provided data.
|
|
2219
2438
|
*/
|
|
2220
2439
|
const hashedId = (data) => {
|
|
2221
|
-
|
|
2440
|
+
const bytes = data instanceof ArrayBuffer ? new Uint8Array(data) : typeof data === "string" ? new TextEncoder().encode(data) : data;
|
|
2441
|
+
return bytesToHex(sha1(bytes));
|
|
2222
2442
|
};
|
|
2223
2443
|
/**
|
|
2224
2444
|
* Generates a UUID v4-style unique identifier using crypto.randomUUID.
|
|
2225
2445
|
*/
|
|
2226
2446
|
const uniqueUuid = () => crypto.randomUUID();
|
|
2227
2447
|
//#endregion
|
|
2228
|
-
|
|
2448
|
+
//#region src/util/image-type.ts
|
|
2449
|
+
/** Map a media path's file extension to an image type token. */
|
|
2450
|
+
function imageTypeFromPath(path) {
|
|
2451
|
+
switch (path.split(".").pop()?.toLowerCase() ?? "") {
|
|
2452
|
+
case "jpg":
|
|
2453
|
+
case "jpeg": return "jpg";
|
|
2454
|
+
case "png": return "png";
|
|
2455
|
+
case "gif": return "gif";
|
|
2456
|
+
case "bmp": return "bmp";
|
|
2457
|
+
case "tif":
|
|
2458
|
+
case "tiff": return "tif";
|
|
2459
|
+
case "ico": return "ico";
|
|
2460
|
+
case "emf": return "emf";
|
|
2461
|
+
case "wmf": return "wmf";
|
|
2462
|
+
default: return "png";
|
|
2463
|
+
}
|
|
2464
|
+
}
|
|
2465
|
+
//#endregion
|
|
2466
|
+
//#region src/util/ext-uri.ts
|
|
2467
|
+
/**
|
|
2468
|
+
* Extension-uri matching for a:ext/p:ext style extension lists.
|
|
2469
|
+
*
|
|
2470
|
+
* @module
|
|
2471
|
+
*/
|
|
2472
|
+
/**
|
|
2473
|
+
* Match an `@uri` attribute against a known extension uri. Producers write
|
|
2474
|
+
* GUID-style uris with or without the enclosing braces and in mixed case —
|
|
2475
|
+
* both spellings denote the same extension, so compare brace-stripped and
|
|
2476
|
+
* case-insensitively.
|
|
2477
|
+
*/
|
|
2478
|
+
function extUriMatches(actual, expected) {
|
|
2479
|
+
if (actual === void 0) return false;
|
|
2480
|
+
const norm = (uri) => uri.replace(/^[{]+|[}]+$/g, "").toLowerCase();
|
|
2481
|
+
return norm(actual) === norm(expected);
|
|
2482
|
+
}
|
|
2483
|
+
//#endregion
|
|
2484
|
+
export { xsdDiagramDirection as $, pointMeasureValue as $t, parseAngle as A, xsdTextBuild as At, xsdAxisCrossBetween as B, decodeBase64 as Bt, convertUniversalMeasureToEmu as C, xsdSizeRepresents as Ct, emitAngle as D, xsdTableWidthType as Dt, convertUniversalMeasureToTwip as E, xsdStrikeStyle as Et, xsdAnimCalcMode as F, xsdTrendlineType as Ft, xsdBlendMode as G, eighthPointMeasureValue as Gt, xsdAxisLabelAlignment as H, Buffer as Ht, xsdAnimClass as I, xsdUnderlineStyle as It, xsdCompoundLine as J, hpsMeasureValue as Jt, xsdChartBuild as K, hexBinary as Kt, xsdAnimLevel as L, xsdVerticalMergeRev as Lt, parsePercentAttr as M, xsdTextTabAlignment as Mt, parseUniversalMeasure as N, xsdTextVerticalType as Nt, emitPercent as O, xsdTextAlign as Ot, invertMap as P, xsdTotalsRowFunction as Pt, xsdDiagramBuild as Q, percentageValue as Qt, xsdAnimValueType as R, isBase64DataURL as Rt, convertTwipToPoints as S, xsdShadingPattern as St, convertUniversalMeasureToPt as T, xsdSplitType as Tt, xsdAxisOrientation as U, dateTimeValue as Ut, xsdAxisCrosses as V, encodeBase64 as Vt, xsdAxisPosition as W, decimalNumber as Wt, xsdDashStyle as X, measurementOrPercentValue as Xt, xsdConsolidateFunction as Y, longHexNumber as Yt, xsdDataLabelPosition as Z, parseOnOff as Zt, convertToEmu as _, xsdPenAlignment as _t, uniqueNumericIdCreator as a, twipsMeasureValue as an, xsdIterateType as at, convertToTwip as b, xsdRectAlignment as bt, convertEmuToPixels as c, unsignedDecimalNumber as cn, xsdLightRigDirection as ct, convertInchesToEmu as d, xsdMaterialType as dt, positiveUniversalMeasureValue as en, xsdEffectContainer as et, convertInchesToTwip as f, xsdMathStyle as ft, convertPointsToTwip as g, xsdPattern as gt, convertPointsToEmu as h, xsdPathFillMode as ht, uniqueId as i, stripColorHashPrefix as in, xsdHueDirection as it, parsePercent as j, xsdTextCaps as jt, mapOptional as k, xsdTextAnchor as kt, convertEmuToPoints as l, xsdLineCap as lt, convertPixelsToEmu as m, xsdOrient as mt, imageTypeFromPath as n, signedHpsMeasureValue as nn, xsdFontAlignment as nt, uniqueUuid as o, uCharHexNumber as on, xsdJcAlignment as ot, convertMillimetersToTwip as p, xsdOnOffStyle as pt, xsdComments as q, hexColorValue as qt, hashedId as r, signedTwipsMeasureValue as rn, xsdHierBranch as rt, convertEmuToInches as s, universalMeasureValue as sn, xsdLegendPosition as st, extUriMatches as t, shortHexNumber as tn, xsdErrorValueType as tt, convertEmuToTwip as u, xsdLineEndSize as ut, convertToInch as v, xsdPlaceholderType as vt, convertUniversalMeasureToInch as w, xsdSlideLayoutType as wt, convertTwipToEmu as x, xsdResizeHandles as xt, convertToPt as y, xsdPresetShadow as yt, xsdAnimationDgmBuild as z, toUint8Array as zt };
|
|
2229
2485
|
|
|
2230
|
-
//# sourceMappingURL=
|
|
2486
|
+
//# sourceMappingURL=ext-uri-BHBcIrW7.mjs.map
|