@office-kit/pptx 0.13.0 → 0.14.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.
@@ -520,7 +520,7 @@ const parseElement = (cur, parentScope) => {
520
520
  };
521
521
  const parseXml = (src) => {
522
522
  const cur = {
523
- src: src.charCodeAt(0) === 65279 ? src.slice(1) : src,
523
+ src: (src.charCodeAt(0) === 65279 ? src.slice(1) : src).replace(/\r\n?/g, "\n"),
524
524
  pos: 0
525
525
  };
526
526
  const decl = parseDeclaration(cur);
@@ -1534,285 +1534,6 @@ const textBodyText = (txBody) => {
1534
1534
  return parts.join("\n");
1535
1535
  };
1536
1536
  //#endregion
1537
- //#region src/internal/drawingml/text-body-mutation.ts
1538
- const NAME_BU_CHAR = qname("a", "buChar", NS.dml);
1539
- const NAME_BU_AUTO_NUM = qname("a", "buAutoNum", NS.dml);
1540
- const NAME_BU_NONE$1 = qname("a", "buNone", NS.dml);
1541
- const NAME_BU_FONT = qname("a", "buFont", NS.dml);
1542
- const ATTR_CHAR = qname("", "char", "");
1543
- const ATTR_BU_TYPE = qname("", "type", "");
1544
- const ATTR_START_AT = qname("", "startAt", "");
1545
- const ATTR_TYPEFACE$3 = qname("", "typeface", "");
1546
- const NAME_P$5 = qname("a", "p", NS.dml);
1547
- const NAME_R$4 = qname("a", "r", NS.dml);
1548
- const NAME_T$5 = qname("a", "t", NS.dml);
1549
- const NAME_RPR$6 = qname("a", "rPr", NS.dml);
1550
- const NAME_PPR$1 = qname("a", "pPr", NS.dml);
1551
- NS.xml;
1552
- const cloneAttrs = (attrs) => attrs.map((a) => attr(a.name, a.value));
1553
- const cloneElement = (e) => elem(e.name, {
1554
- attrs: cloneAttrs(e.attrs),
1555
- prefixDecls: new Map(e.prefixDecls),
1556
- children: e.children.map(cloneNode)
1557
- });
1558
- const cloneNode = (n) => {
1559
- switch (n.kind) {
1560
- case "element": return cloneElement(n);
1561
- case "text": return {
1562
- kind: "text",
1563
- data: n.data
1564
- };
1565
- case "cdata": return {
1566
- kind: "cdata",
1567
- data: n.data
1568
- };
1569
- case "comment": return {
1570
- kind: "comment",
1571
- data: n.data
1572
- };
1573
- case "pi": return {
1574
- kind: "pi",
1575
- target: n.target,
1576
- data: n.data
1577
- };
1578
- }
1579
- };
1580
- /**
1581
- * Returns the first `a:rPr` reachable on the first run of the first paragraph
1582
- * inside `txBody`. Used to preserve formatting on text replacement: we clone
1583
- * the original rPr into the new run so font, color, size, etc. survive.
1584
- */
1585
- const findFirstRunProperties = (txBody) => {
1586
- const firstP = firstChildElement(txBody, NAME_P$5);
1587
- if (firstP === null) return null;
1588
- const firstR = firstChildElement(firstP, NAME_R$4);
1589
- if (firstR === null) return null;
1590
- return firstChildElement(firstR, NAME_RPR$6);
1591
- };
1592
- /**
1593
- * Returns the first `a:pPr` from the first paragraph. Used to preserve
1594
- * paragraph-level formatting (alignment, bullet, indent) when replacing.
1595
- */
1596
- const findFirstParagraphProperties = (txBody) => {
1597
- const firstP = firstChildElement(txBody, NAME_P$5);
1598
- if (firstP === null) return null;
1599
- return firstChildElement(firstP, NAME_PPR$1);
1600
- };
1601
- const removeAllParagraphs = (txBody) => {
1602
- txBody.children = txBody.children.filter((c) => !(c.kind === "element" && c.name.namespaceURI === NS.dml && c.name.localName === "p"));
1603
- };
1604
- const TOKEN_PATTERN = /\{\{([^{}]+)\}\}/g;
1605
- /**
1606
- * Replaces `{{key}}` tokens in every `a:t` element under `root` with values
1607
- * from `tokens`. Tokens whose key is not in `tokens` are left untouched.
1608
- *
1609
- * Returns the number of substitutions performed. Useful for callers that
1610
- * want to know whether anything matched.
1611
- *
1612
- * Limitation: a token must fit entirely within one `<a:t>` element to
1613
- * match. PowerPoint normally serializes contiguous user text as a single
1614
- * `<a:t>`, so the limitation only bites when a placeholder was edited
1615
- * character-by-character (causing PowerPoint to split runs). For those
1616
- * cases, fall back to `setText()`.
1617
- */
1618
- const replaceTokensInTree = (root, tokens) => {
1619
- let count = 0;
1620
- walkElements(root, (el) => {
1621
- if (el.name.namespaceURI !== NAME_T$5.namespaceURI) return;
1622
- if (el.name.localName !== "t") return;
1623
- const child = el.children[0];
1624
- if (!child || child.kind !== "text") return;
1625
- const before = child.data;
1626
- let didMatch = false;
1627
- const after = before.replace(TOKEN_PATTERN, (match, key) => {
1628
- if (Object.hasOwn(tokens, key)) {
1629
- didMatch = true;
1630
- return tokens[key] ?? "";
1631
- }
1632
- return match;
1633
- });
1634
- if (didMatch) {
1635
- child.data = after;
1636
- count++;
1637
- }
1638
- });
1639
- return count;
1640
- };
1641
- /**
1642
- * Replaces every occurrence of `from` in every `<a:t>` element under
1643
- * `root` with `to`. `from` may be a string (literal) or a `RegExp`
1644
- * (matched per-run). Returns the count of `<a:t>` elements that were
1645
- * mutated — not the count of substitutions inside them, since callers
1646
- * usually want "did anything change" rather than "how many letters
1647
- * moved."
1648
- *
1649
- * Same single-run constraint as `replaceTokensInTree`: matches must
1650
- * fit inside one `<a:t>`. Use this for the broader "find/replace
1651
- * across the deck" use case where {{token}} syntax isn't a fit.
1652
- */
1653
- const replaceTextInTree = (root, from, to) => {
1654
- const pattern = typeof from === "string" ? new RegExp(from.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g") : from.global ? from : new RegExp(from.source, `${from.flags}g`);
1655
- let count = 0;
1656
- walkElements(root, (el) => {
1657
- if (el.name.namespaceURI !== NAME_T$5.namespaceURI) return;
1658
- if (el.name.localName !== "t") return;
1659
- const child = el.children[0];
1660
- if (!child || child.kind !== "text") return;
1661
- const before = child.data;
1662
- const after = before.replace(pattern, to);
1663
- if (after !== before) {
1664
- child.data = after;
1665
- count++;
1666
- }
1667
- });
1668
- return count;
1669
- };
1670
- const normalizeBulletStyle = (s) => {
1671
- if (s === "bullet") return {
1672
- kind: "char",
1673
- char: "•"
1674
- };
1675
- if (s === "number") return {
1676
- kind: "autoNum",
1677
- type: "arabicPeriod"
1678
- };
1679
- if (s === "none") return { kind: "none" };
1680
- if ("char" in s) return {
1681
- kind: "char",
1682
- char: s.char
1683
- };
1684
- return {
1685
- kind: "autoNum",
1686
- type: s.autoNum
1687
- };
1688
- };
1689
- const buildBulletElement = (style) => {
1690
- const n = normalizeBulletStyle(style);
1691
- switch (n.kind) {
1692
- case "char": return elem(NAME_BU_CHAR, { attrs: [attr(ATTR_CHAR, n.char)] });
1693
- case "autoNum": return elem(NAME_BU_AUTO_NUM, { attrs: [attr(ATTR_START_AT, "1"), attr(ATTR_BU_TYPE, n.type)] });
1694
- case "none": return elem(NAME_BU_NONE$1);
1695
- }
1696
- };
1697
- const NAME_PPR_FOR_BULLET = qname("a", "pPr", NS.dml);
1698
- const NAME_P_FOR_BULLET = qname("a", "p", NS.dml);
1699
- const alignToken = (a) => {
1700
- switch (a) {
1701
- case "left":
1702
- case "l": return "l";
1703
- case "center":
1704
- case "ctr": return "ctr";
1705
- case "right":
1706
- case "r": return "r";
1707
- case "justify":
1708
- case "just": return "just";
1709
- case "distribute":
1710
- case "dist": return "dist";
1711
- default: return a;
1712
- }
1713
- };
1714
- const ATTR_ALGN$1 = qname("", "algn", "");
1715
- /**
1716
- * Sets `<a:pPr algn="...">` on every paragraph in `txBody`. Existing
1717
- * pPr attributes other than `algn` are preserved.
1718
- */
1719
- const applyAlignmentToAllParagraphs = (txBody, align) => {
1720
- const token = alignToken(align);
1721
- for (const p of txBody.children) {
1722
- if (p.kind !== "element" || p.name.namespaceURI !== NAME_P_FOR_BULLET.namespaceURI || p.name.localName !== "p") continue;
1723
- let pPr = firstChildElement(p, NAME_PPR_FOR_BULLET);
1724
- if (pPr === null) {
1725
- pPr = elem(NAME_PPR_FOR_BULLET);
1726
- p.children.unshift(pPr);
1727
- }
1728
- pPr.attrs = pPr.attrs.filter((a) => a.name.localName !== "algn");
1729
- pPr.attrs.push(attr(ATTR_ALGN$1, token));
1730
- }
1731
- };
1732
- /**
1733
- * Sets the bullet style on a single `<a:p>` paragraph. Drops any
1734
- * existing bullet child element (`a:buChar`, `a:buAutoNum`, `a:buNone`)
1735
- * before inserting the new one. Creates `<a:pPr>` if absent.
1736
- */
1737
- const BULLET_INDENT_BY_LEVEL = [
1738
- {
1739
- marL: 342900,
1740
- indent: -342900
1741
- },
1742
- {
1743
- marL: 742950,
1744
- indent: -285750
1745
- },
1746
- {
1747
- marL: 1143e3,
1748
- indent: -228600
1749
- },
1750
- {
1751
- marL: 1600200,
1752
- indent: -228600
1753
- },
1754
- {
1755
- marL: 2057400,
1756
- indent: -228600
1757
- }
1758
- ];
1759
- const bulletIndentForLevel = (lvl) => BULLET_INDENT_BY_LEVEL[Math.min(lvl, BULLET_INDENT_BY_LEVEL.length - 1)];
1760
- const ATTR_MAR_L$1 = qname("", "marL", "");
1761
- const ATTR_INDENT$1 = qname("", "indent", "");
1762
- const hasAttr = (el, local) => el.attrs.some((a) => a.name.namespaceURI === "" && a.name.localName === local);
1763
- const applyBulletToParagraph = (paragraph, style) => {
1764
- let pPr = firstChildElement(paragraph, NAME_PPR_FOR_BULLET);
1765
- if (pPr === null) {
1766
- pPr = elem(NAME_PPR_FOR_BULLET);
1767
- paragraph.children.unshift(pPr);
1768
- }
1769
- pPr.children = pPr.children.filter((c) => !(c.kind === "element" && c.name.namespaceURI === NS.dml && (c.name.localName === "buChar" || c.name.localName === "buAutoNum" || c.name.localName === "buNone" || c.name.localName === "buFont")));
1770
- if (style !== "none") {
1771
- const lvl = Number.parseInt(pPr.attrs.find((a) => a.name.localName === "lvl")?.value ?? "0", 10);
1772
- const { marL, indent } = bulletIndentForLevel(Number.isFinite(lvl) ? lvl : 0);
1773
- if (!hasAttr(pPr, "marL")) pPr.attrs.push(attr(ATTR_MAR_L$1, String(marL)));
1774
- if (!hasAttr(pPr, "indent")) pPr.attrs.push(attr(ATTR_INDENT$1, String(indent)));
1775
- }
1776
- if (normalizeBulletStyle(style).kind === "autoNum") pPr.children.push(elem(NAME_BU_FONT, { attrs: [attr(ATTR_TYPEFACE$3, "+mj-lt")] }));
1777
- pPr.children.push(buildBulletElement(style));
1778
- };
1779
- /**
1780
- * Sets the bullet style on every paragraph in `txBody`. Drops any
1781
- * existing bullet child element (`a:buChar`, `a:buAutoNum`, `a:buNone`)
1782
- * before inserting the new one. Creates `<a:pPr>` if absent.
1783
- */
1784
- const applyBulletToAllParagraphs = (txBody, style) => {
1785
- for (const p of txBody.children) {
1786
- if (p.kind !== "element" || p.name.namespaceURI !== NAME_P_FOR_BULLET.namespaceURI || p.name.localName !== "p") continue;
1787
- applyBulletToParagraph(p, style);
1788
- }
1789
- };
1790
- /**
1791
- * Replaces the entire visible text of a `txBody` element with `value`.
1792
- * Newlines in `value` start a new paragraph.
1793
- *
1794
- * The first existing `a:rPr` (run properties) and `a:pPr` (paragraph
1795
- * properties) are cloned into every new paragraph so that font, color, size,
1796
- * alignment, and bullet style survive the replacement. If the source had
1797
- * mixed formatting per run, that gets collapsed into the first-run formatting
1798
- * across the entire new text — matching what PowerPoint does when you select
1799
- * all and type.
1800
- *
1801
- * The `bodyPr` and `lstStyle` children (if any) are preserved untouched.
1802
- */
1803
- const setTextBody = (txBody, value) => {
1804
- const rPrTemplate = findFirstRunProperties(txBody);
1805
- const pPrTemplate = findFirstParagraphProperties(txBody);
1806
- removeAllParagraphs(txBody);
1807
- const lines = value.split("\n");
1808
- for (const line of lines) {
1809
- const t = elem(NAME_T$5, { children: line.length > 0 ? [text(line)] : [] });
1810
- const r = elem(NAME_R$4, { children: rPrTemplate !== null ? [cloneElement(rPrTemplate), t] : [t] });
1811
- const p = elem(NAME_P$5, { children: pPrTemplate !== null ? [cloneElement(pPrTemplate), r] : [r] });
1812
- txBody.children.push(p);
1813
- }
1814
- };
1815
- //#endregion
1816
1537
  //#region src/internal/bounds.ts
1817
1538
  const RANGES = {
1818
1539
  coordinate: [-27273042329600, 27273042316900],
@@ -1954,7 +1675,7 @@ const buildColorElement = (value) => {
1954
1675
  //#endregion
1955
1676
  //#region src/internal/drawingml/text-format.ts
1956
1677
  NS.dml;
1957
- const NAME_RPR$5 = qname("a", "rPr", NS.dml);
1678
+ const NAME_RPR$6 = qname("a", "rPr", NS.dml);
1958
1679
  const NAME_LATIN = qname("a", "latin", NS.dml);
1959
1680
  const NAME_EA = qname("a", "ea", NS.dml);
1960
1681
  NS.dml;
@@ -1970,7 +1691,7 @@ const ATTR_SPC = qname("", "spc", "");
1970
1691
  const ATTR_KERN = qname("", "kern", "");
1971
1692
  const ATTR_BASELINE = qname("", "baseline", "");
1972
1693
  const ATTR_CAP = qname("", "cap", "");
1973
- const ATTR_TYPEFACE$2 = qname("", "typeface", "");
1694
+ const ATTR_TYPEFACE$3 = qname("", "typeface", "");
1974
1695
  const ATTR_VAL$8 = qname("", "val", "");
1975
1696
  const NAME_HIGHLIGHT = qname("a", "highlight", NS.dml);
1976
1697
  const RPR_CHILD_RANK = {
@@ -2013,70 +1734,369 @@ const setSolidFill$1 = (rPr, value) => {
2013
1734
  const setLatin = (rPr, font) => {
2014
1735
  rPr.children = rPr.children.filter((c) => !(c.kind === "element" && c.name.namespaceURI === NS.dml && c.name.localName === "latin"));
2015
1736
  if (font === null) return;
2016
- insertChildByRank(rPr, elem(NAME_LATIN, { attrs: [attr(ATTR_TYPEFACE$2, font)] }), rprChildRank);
1737
+ insertChildByRank(rPr, elem(NAME_LATIN, { attrs: [attr(ATTR_TYPEFACE$3, font)] }), rprChildRank);
2017
1738
  };
2018
1739
  const setEastAsian = (rPr, font) => {
2019
1740
  rPr.children = rPr.children.filter((c) => !(c.kind === "element" && c.name.namespaceURI === NS.dml && c.name.localName === "ea"));
2020
1741
  if (font === null) return;
2021
- insertChildByRank(rPr, elem(NAME_EA, { attrs: [attr(ATTR_TYPEFACE$2, font)] }), rprChildRank);
1742
+ insertChildByRank(rPr, elem(NAME_EA, { attrs: [attr(ATTR_TYPEFACE$3, font)] }), rprChildRank);
1743
+ };
1744
+ const setHighlight = (rPr, value) => {
1745
+ rPr.children = rPr.children.filter((c) => !(c.kind === "element" && c.name.namespaceURI === NS.dml && c.name.localName === "highlight"));
1746
+ if (value === null) return;
1747
+ const parsed = parseColor(value);
1748
+ if (parsed === null) throw new Error(`unrecognized highlight color: ${value}`);
1749
+ insertChildByRank(rPr, elem(NAME_HIGHLIGHT, { children: [parsed.kind === "srgb" ? elem(NAME_SRGB_CLR$3, { attrs: [attr(ATTR_VAL$8, parsed.hex)] }) : elem(NAME_SCHEME_CLR$1, { attrs: [attr(ATTR_VAL$8, parsed.token)] })] }), rprChildRank);
1750
+ };
1751
+ /** Mutates `rPr` in place per `format`. */
1752
+ const applyRunFormat = (rPr, format) => {
1753
+ let attrs = rPr.attrs;
1754
+ if (format.size !== void 0) {
1755
+ const sz = fontSizeHundredthPt(format.size * 100, "setShapeRunFormat: size");
1756
+ attrs = setOrRemoveAttr(attrs, ATTR_SZ, String(sz));
1757
+ }
1758
+ if (format.bold !== void 0) attrs = setOrRemoveAttr(attrs, ATTR_B, format.bold ? "1" : "0");
1759
+ if (format.italic !== void 0) attrs = setOrRemoveAttr(attrs, ATTR_I, format.italic ? "1" : "0");
1760
+ if (format.underline !== void 0) {
1761
+ const value = format.underline === false ? "none" : format.underline === true ? "sng" : format.underline;
1762
+ attrs = setOrRemoveAttr(attrs, ATTR_U, value);
1763
+ }
1764
+ if (format.strike !== void 0) {
1765
+ const value = format.strike === false ? "noStrike" : format.strike === true ? "sngStrike" : format.strike;
1766
+ attrs = setOrRemoveAttr(attrs, ATTR_STRIKE, value);
1767
+ }
1768
+ if (format.spc !== void 0) {
1769
+ const spc = textPointSpacing(format.spc, "setShapeRunFormat: spc");
1770
+ attrs = setOrRemoveAttr(attrs, ATTR_SPC, String(spc));
1771
+ }
1772
+ if (format.kern !== void 0) attrs = setOrRemoveAttr(attrs, ATTR_KERN, String(Math.round(format.kern)));
1773
+ if (format.baseline !== void 0) {
1774
+ const pct = Math.round(format.baseline * 1e5);
1775
+ attrs = setOrRemoveAttr(attrs, ATTR_BASELINE, String(pct));
1776
+ }
1777
+ if (format.cap !== void 0) attrs = setOrRemoveAttr(attrs, ATTR_CAP, format.cap);
1778
+ rPr.attrs = attrs;
1779
+ if (format.font !== void 0) setLatin(rPr, format.font);
1780
+ if (format.fontEastAsian !== void 0) setEastAsian(rPr, format.fontEastAsian);
1781
+ if (format.color !== void 0) setSolidFill$1(rPr, format.color);
1782
+ if (format.highlight !== void 0) setHighlight(rPr, format.highlight);
1783
+ };
1784
+ /**
1785
+ * Walks `txBody`, ensuring every `<a:r>` has an `<a:rPr>` carrying the
1786
+ * supplied format. Existing run-property attributes not addressed by
1787
+ * `format` are preserved.
1788
+ */
1789
+ const applyFormatToAllRuns = (txBody, format) => {
1790
+ for (const p of txBody.children) {
1791
+ if (p.kind !== "element" || p.name.namespaceURI !== NS.dml || p.name.localName !== "p") continue;
1792
+ for (const r of p.children) {
1793
+ if (r.kind !== "element" || r.name.namespaceURI !== NS.dml || r.name.localName !== "r") continue;
1794
+ let rPr = firstChildElement(r, NAME_RPR$6);
1795
+ if (rPr === null) {
1796
+ rPr = elem(NAME_RPR$6);
1797
+ r.children.unshift(rPr);
1798
+ }
1799
+ applyRunFormat(rPr, format);
1800
+ }
1801
+ }
1802
+ };
1803
+ //#endregion
1804
+ //#region src/internal/drawingml/text-body-mutation.ts
1805
+ const NAME_BU_CHAR = qname("a", "buChar", NS.dml);
1806
+ const NAME_BU_AUTO_NUM = qname("a", "buAutoNum", NS.dml);
1807
+ const NAME_BU_NONE$1 = qname("a", "buNone", NS.dml);
1808
+ const NAME_BU_FONT = qname("a", "buFont", NS.dml);
1809
+ const ATTR_CHAR = qname("", "char", "");
1810
+ const ATTR_BU_TYPE = qname("", "type", "");
1811
+ const ATTR_START_AT = qname("", "startAt", "");
1812
+ const ATTR_TYPEFACE$2 = qname("", "typeface", "");
1813
+ const NAME_P$5 = qname("a", "p", NS.dml);
1814
+ const NAME_R$4 = qname("a", "r", NS.dml);
1815
+ const NAME_T$5 = qname("a", "t", NS.dml);
1816
+ const NAME_RPR$5 = qname("a", "rPr", NS.dml);
1817
+ const NAME_PPR$1 = qname("a", "pPr", NS.dml);
1818
+ NS.xml;
1819
+ const cloneAttrs = (attrs) => attrs.map((a) => attr(a.name, a.value));
1820
+ const cloneElement = (e) => elem(e.name, {
1821
+ attrs: cloneAttrs(e.attrs),
1822
+ prefixDecls: new Map(e.prefixDecls),
1823
+ children: e.children.map(cloneNode)
1824
+ });
1825
+ const cloneNode = (n) => {
1826
+ switch (n.kind) {
1827
+ case "element": return cloneElement(n);
1828
+ case "text": return {
1829
+ kind: "text",
1830
+ data: n.data
1831
+ };
1832
+ case "cdata": return {
1833
+ kind: "cdata",
1834
+ data: n.data
1835
+ };
1836
+ case "comment": return {
1837
+ kind: "comment",
1838
+ data: n.data
1839
+ };
1840
+ case "pi": return {
1841
+ kind: "pi",
1842
+ target: n.target,
1843
+ data: n.data
1844
+ };
1845
+ }
1846
+ };
1847
+ /**
1848
+ * Returns the first `a:rPr` reachable on the first run of the first paragraph
1849
+ * inside `txBody`. Used to preserve formatting on text replacement: we clone
1850
+ * the original rPr into the new run so font, color, size, etc. survive.
1851
+ */
1852
+ const findFirstRunProperties = (txBody) => {
1853
+ const firstP = firstChildElement(txBody, NAME_P$5);
1854
+ if (firstP === null) return null;
1855
+ const firstR = firstChildElement(firstP, NAME_R$4);
1856
+ if (firstR === null) return null;
1857
+ return firstChildElement(firstR, NAME_RPR$5);
1858
+ };
1859
+ /**
1860
+ * Returns the first `a:pPr` from the first paragraph. Used to preserve
1861
+ * paragraph-level formatting (alignment, bullet, indent) when replacing.
1862
+ */
1863
+ const findFirstParagraphProperties = (txBody) => {
1864
+ const firstP = firstChildElement(txBody, NAME_P$5);
1865
+ if (firstP === null) return null;
1866
+ return firstChildElement(firstP, NAME_PPR$1);
1867
+ };
1868
+ const removeAllParagraphs = (txBody) => {
1869
+ txBody.children = txBody.children.filter((c) => !(c.kind === "element" && c.name.namespaceURI === NS.dml && c.name.localName === "p"));
1870
+ };
1871
+ const TOKEN_PATTERN = /\{\{([^{}]+)\}\}/g;
1872
+ /**
1873
+ * Replaces `{{key}}` tokens in every `a:t` element under `root` with values
1874
+ * from `tokens`. Tokens whose key is not in `tokens` are left untouched.
1875
+ *
1876
+ * Returns the number of substitutions performed. Useful for callers that
1877
+ * want to know whether anything matched.
1878
+ *
1879
+ * Limitation: a token must fit entirely within one `<a:t>` element to
1880
+ * match. PowerPoint normally serializes contiguous user text as a single
1881
+ * `<a:t>`, so the limitation only bites when a placeholder was edited
1882
+ * character-by-character (causing PowerPoint to split runs). For those
1883
+ * cases, fall back to `setText()`.
1884
+ */
1885
+ const replaceTokensInTree = (root, tokens) => {
1886
+ let count = 0;
1887
+ walkElements(root, (el) => {
1888
+ if (el.name.namespaceURI !== NAME_T$5.namespaceURI) return;
1889
+ if (el.name.localName !== "t") return;
1890
+ const child = el.children[0];
1891
+ if (!child || child.kind !== "text") return;
1892
+ const before = child.data;
1893
+ let didMatch = false;
1894
+ const after = before.replace(TOKEN_PATTERN, (match, key) => {
1895
+ if (Object.hasOwn(tokens, key)) {
1896
+ didMatch = true;
1897
+ return tokens[key] ?? "";
1898
+ }
1899
+ return match;
1900
+ });
1901
+ if (didMatch) {
1902
+ child.data = after;
1903
+ count++;
1904
+ }
1905
+ });
1906
+ return count;
1907
+ };
1908
+ /**
1909
+ * Replaces every occurrence of `from` in every `<a:t>` element under
1910
+ * `root` with `to`. `from` may be a string (literal) or a `RegExp`
1911
+ * (matched per-run). Returns the count of `<a:t>` elements that were
1912
+ * mutated — not the count of substitutions inside them, since callers
1913
+ * usually want "did anything change" rather than "how many letters
1914
+ * moved."
1915
+ *
1916
+ * Same single-run constraint as `replaceTokensInTree`: matches must
1917
+ * fit inside one `<a:t>`. Use this for the broader "find/replace
1918
+ * across the deck" use case where {{token}} syntax isn't a fit.
1919
+ */
1920
+ const replaceTextInTree = (root, from, to) => {
1921
+ const pattern = typeof from === "string" ? new RegExp(from.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g") : from.global ? from : new RegExp(from.source, `${from.flags}g`);
1922
+ let count = 0;
1923
+ walkElements(root, (el) => {
1924
+ if (el.name.namespaceURI !== NAME_T$5.namespaceURI) return;
1925
+ if (el.name.localName !== "t") return;
1926
+ const child = el.children[0];
1927
+ if (!child || child.kind !== "text") return;
1928
+ const before = child.data;
1929
+ const after = before.replace(pattern, to);
1930
+ if (after !== before) {
1931
+ child.data = after;
1932
+ count++;
1933
+ }
1934
+ });
1935
+ return count;
1936
+ };
1937
+ const normalizeBulletStyle = (s) => {
1938
+ if (s === "bullet") return {
1939
+ kind: "char",
1940
+ char: "•"
1941
+ };
1942
+ if (s === "number") return {
1943
+ kind: "autoNum",
1944
+ type: "arabicPeriod"
1945
+ };
1946
+ if (s === "none") return { kind: "none" };
1947
+ if ("char" in s) return {
1948
+ kind: "char",
1949
+ char: s.char
1950
+ };
1951
+ return {
1952
+ kind: "autoNum",
1953
+ type: s.autoNum
1954
+ };
2022
1955
  };
2023
- const setHighlight = (rPr, value) => {
2024
- rPr.children = rPr.children.filter((c) => !(c.kind === "element" && c.name.namespaceURI === NS.dml && c.name.localName === "highlight"));
2025
- if (value === null) return;
2026
- const parsed = parseColor(value);
2027
- if (parsed === null) throw new Error(`unrecognized highlight color: ${value}`);
2028
- insertChildByRank(rPr, elem(NAME_HIGHLIGHT, { children: [parsed.kind === "srgb" ? elem(NAME_SRGB_CLR$3, { attrs: [attr(ATTR_VAL$8, parsed.hex)] }) : elem(NAME_SCHEME_CLR$1, { attrs: [attr(ATTR_VAL$8, parsed.token)] })] }), rprChildRank);
1956
+ const buildBulletElement = (style) => {
1957
+ const n = normalizeBulletStyle(style);
1958
+ switch (n.kind) {
1959
+ case "char": return elem(NAME_BU_CHAR, { attrs: [attr(ATTR_CHAR, n.char)] });
1960
+ case "autoNum": return elem(NAME_BU_AUTO_NUM, { attrs: [attr(ATTR_START_AT, "1"), attr(ATTR_BU_TYPE, n.type)] });
1961
+ case "none": return elem(NAME_BU_NONE$1);
1962
+ }
2029
1963
  };
2030
- /** Mutates `rPr` in place per `format`. */
2031
- const applyRunFormat = (rPr, format) => {
2032
- let attrs = rPr.attrs;
2033
- if (format.size !== void 0) {
2034
- const sz = fontSizeHundredthPt(format.size * 100, "setShapeRunFormat: size");
2035
- attrs = setOrRemoveAttr(attrs, ATTR_SZ, String(sz));
1964
+ const NAME_PPR_FOR_BULLET = qname("a", "pPr", NS.dml);
1965
+ const NAME_P_FOR_BULLET = qname("a", "p", NS.dml);
1966
+ const alignToken = (a) => {
1967
+ switch (a) {
1968
+ case "left":
1969
+ case "l": return "l";
1970
+ case "center":
1971
+ case "ctr": return "ctr";
1972
+ case "right":
1973
+ case "r": return "r";
1974
+ case "justify":
1975
+ case "just": return "just";
1976
+ case "distribute":
1977
+ case "dist": return "dist";
1978
+ default: return a;
2036
1979
  }
2037
- if (format.bold !== void 0) attrs = setOrRemoveAttr(attrs, ATTR_B, format.bold ? "1" : "0");
2038
- if (format.italic !== void 0) attrs = setOrRemoveAttr(attrs, ATTR_I, format.italic ? "1" : "0");
2039
- if (format.underline !== void 0) {
2040
- const value = format.underline === false ? "none" : format.underline === true ? "sng" : format.underline;
2041
- attrs = setOrRemoveAttr(attrs, ATTR_U, value);
1980
+ };
1981
+ const ATTR_ALGN$1 = qname("", "algn", "");
1982
+ /**
1983
+ * Sets `<a:pPr algn="...">` on every paragraph in `txBody`. Existing
1984
+ * pPr attributes other than `algn` are preserved.
1985
+ */
1986
+ const applyAlignmentToAllParagraphs = (txBody, align) => {
1987
+ const token = alignToken(align);
1988
+ for (const p of txBody.children) {
1989
+ if (p.kind !== "element" || p.name.namespaceURI !== NAME_P_FOR_BULLET.namespaceURI || p.name.localName !== "p") continue;
1990
+ let pPr = firstChildElement(p, NAME_PPR_FOR_BULLET);
1991
+ if (pPr === null) {
1992
+ pPr = elem(NAME_PPR_FOR_BULLET);
1993
+ p.children.unshift(pPr);
1994
+ }
1995
+ pPr.attrs = pPr.attrs.filter((a) => a.name.localName !== "algn");
1996
+ pPr.attrs.push(attr(ATTR_ALGN$1, token));
2042
1997
  }
2043
- if (format.strike !== void 0) {
2044
- const value = format.strike === false ? "noStrike" : format.strike === true ? "sngStrike" : format.strike;
2045
- attrs = setOrRemoveAttr(attrs, ATTR_STRIKE, value);
1998
+ };
1999
+ /**
2000
+ * Sets the bullet style on a single `<a:p>` paragraph. Drops any
2001
+ * existing bullet child element (`a:buChar`, `a:buAutoNum`, `a:buNone`)
2002
+ * before inserting the new one. Creates `<a:pPr>` if absent.
2003
+ */
2004
+ const BULLET_INDENT_BY_LEVEL = [
2005
+ {
2006
+ marL: 342900,
2007
+ indent: -342900
2008
+ },
2009
+ {
2010
+ marL: 742950,
2011
+ indent: -285750
2012
+ },
2013
+ {
2014
+ marL: 1143e3,
2015
+ indent: -228600
2016
+ },
2017
+ {
2018
+ marL: 1600200,
2019
+ indent: -228600
2020
+ },
2021
+ {
2022
+ marL: 2057400,
2023
+ indent: -228600
2046
2024
  }
2047
- if (format.spc !== void 0) {
2048
- const spc = textPointSpacing(format.spc, "setShapeRunFormat: spc");
2049
- attrs = setOrRemoveAttr(attrs, ATTR_SPC, String(spc));
2025
+ ];
2026
+ const bulletIndentForLevel = (lvl) => BULLET_INDENT_BY_LEVEL[Math.min(lvl, BULLET_INDENT_BY_LEVEL.length - 1)];
2027
+ const ATTR_MAR_L$1 = qname("", "marL", "");
2028
+ const ATTR_INDENT$1 = qname("", "indent", "");
2029
+ const hasAttr = (el, local) => el.attrs.some((a) => a.name.namespaceURI === "" && a.name.localName === local);
2030
+ const applyBulletToParagraph = (paragraph, style) => {
2031
+ let pPr = firstChildElement(paragraph, NAME_PPR_FOR_BULLET);
2032
+ if (pPr === null) {
2033
+ pPr = elem(NAME_PPR_FOR_BULLET);
2034
+ paragraph.children.unshift(pPr);
2050
2035
  }
2051
- if (format.kern !== void 0) attrs = setOrRemoveAttr(attrs, ATTR_KERN, String(Math.round(format.kern)));
2052
- if (format.baseline !== void 0) {
2053
- const pct = Math.round(format.baseline * 1e5);
2054
- attrs = setOrRemoveAttr(attrs, ATTR_BASELINE, String(pct));
2036
+ pPr.children = pPr.children.filter((c) => !(c.kind === "element" && c.name.namespaceURI === NS.dml && (c.name.localName === "buChar" || c.name.localName === "buAutoNum" || c.name.localName === "buNone" || c.name.localName === "buFont")));
2037
+ if (style !== "none") {
2038
+ const lvl = Number.parseInt(pPr.attrs.find((a) => a.name.localName === "lvl")?.value ?? "0", 10);
2039
+ const { marL, indent } = bulletIndentForLevel(Number.isFinite(lvl) ? lvl : 0);
2040
+ if (!hasAttr(pPr, "marL")) pPr.attrs.push(attr(ATTR_MAR_L$1, String(marL)));
2041
+ if (!hasAttr(pPr, "indent")) pPr.attrs.push(attr(ATTR_INDENT$1, String(indent)));
2055
2042
  }
2056
- if (format.cap !== void 0) attrs = setOrRemoveAttr(attrs, ATTR_CAP, format.cap);
2057
- rPr.attrs = attrs;
2058
- if (format.font !== void 0) setLatin(rPr, format.font);
2059
- if (format.fontEastAsian !== void 0) setEastAsian(rPr, format.fontEastAsian);
2060
- if (format.color !== void 0) setSolidFill$1(rPr, format.color);
2061
- if (format.highlight !== void 0) setHighlight(rPr, format.highlight);
2043
+ if (normalizeBulletStyle(style).kind === "autoNum") pPr.children.push(elem(NAME_BU_FONT, { attrs: [attr(ATTR_TYPEFACE$2, "+mj-lt")] }));
2044
+ pPr.children.push(buildBulletElement(style));
2062
2045
  };
2063
2046
  /**
2064
- * Walks `txBody`, ensuring every `<a:r>` has an `<a:rPr>` carrying the
2065
- * supplied format. Existing run-property attributes not addressed by
2066
- * `format` are preserved.
2047
+ * Sets the bullet style on every paragraph in `txBody`. Drops any
2048
+ * existing bullet child element (`a:buChar`, `a:buAutoNum`, `a:buNone`)
2049
+ * before inserting the new one. Creates `<a:pPr>` if absent.
2067
2050
  */
2068
- const applyFormatToAllRuns = (txBody, format) => {
2051
+ const applyBulletToAllParagraphs = (txBody, style) => {
2069
2052
  for (const p of txBody.children) {
2070
- if (p.kind !== "element" || p.name.namespaceURI !== NS.dml || p.name.localName !== "p") continue;
2071
- for (const r of p.children) {
2072
- if (r.kind !== "element" || r.name.namespaceURI !== NS.dml || r.name.localName !== "r") continue;
2073
- let rPr = firstChildElement(r, NAME_RPR$5);
2074
- if (rPr === null) {
2075
- rPr = elem(NAME_RPR$5);
2076
- r.children.unshift(rPr);
2077
- }
2078
- applyRunFormat(rPr, format);
2053
+ if (p.kind !== "element" || p.name.namespaceURI !== NAME_P_FOR_BULLET.namespaceURI || p.name.localName !== "p") continue;
2054
+ applyBulletToParagraph(p, style);
2055
+ }
2056
+ };
2057
+ /**
2058
+ * Replaces the entire visible text of a `txBody` element with `value`.
2059
+ * Newlines in `value` start a new paragraph.
2060
+ *
2061
+ * The first existing `a:rPr` (run properties) and `a:pPr` (paragraph
2062
+ * properties) are cloned into every new paragraph so that font, color, size,
2063
+ * alignment, and bullet style survive the replacement. If the source had
2064
+ * mixed formatting per run, that gets collapsed into the first-run formatting
2065
+ * across the entire new text — matching what PowerPoint does when you select
2066
+ * all and type.
2067
+ *
2068
+ * The `bodyPr` and `lstStyle` children (if any) are preserved untouched.
2069
+ */
2070
+ const setTextBody = (txBody, value) => {
2071
+ const rPrTemplate = findFirstRunProperties(txBody);
2072
+ const pPrTemplate = findFirstParagraphProperties(txBody);
2073
+ removeAllParagraphs(txBody);
2074
+ const lines = value.split("\n");
2075
+ for (const line of lines) {
2076
+ const t = elem(NAME_T$5, { children: line.length > 0 ? [text(line)] : [] });
2077
+ const r = elem(NAME_R$4, { children: rPrTemplate !== null ? [cloneElement(rPrTemplate), t] : [t] });
2078
+ const p = elem(NAME_P$5, { children: pPrTemplate !== null ? [cloneElement(pPrTemplate), r] : [r] });
2079
+ txBody.children.push(p);
2080
+ }
2081
+ };
2082
+ /**
2083
+ * Replaces every paragraph of `txBody` with explicitly structured ones.
2084
+ * Unlike `setTextBody`, nothing is inherited from the existing runs: each
2085
+ * run gets a fresh `<a:rPr>` carrying only its own `format`.
2086
+ */
2087
+ const setTextBodyParagraphs = (txBody, paragraphs) => {
2088
+ if (paragraphs.length === 0) throw new Error("setTextBodyParagraphs: at least one paragraph is required");
2089
+ removeAllParagraphs(txBody);
2090
+ for (const para of paragraphs) {
2091
+ const children = [];
2092
+ if (para.align !== void 0) children.push(elem(NAME_PPR$1, { attrs: [attr(ATTR_ALGN$1, alignToken(para.align))] }));
2093
+ for (const run of para.runs) {
2094
+ const rPr = elem(NAME_RPR$5);
2095
+ if (run.format !== void 0) applyRunFormat(rPr, run.format);
2096
+ const t = elem(NAME_T$5, { children: run.text.length > 0 ? [text(run.text)] : [] });
2097
+ children.push(elem(NAME_R$4, { children: [rPr, t] }));
2079
2098
  }
2099
+ txBody.children.push(elem(NAME_P$5, { children }));
2080
2100
  }
2081
2101
  };
2082
2102
  //#endregion
@@ -5143,11 +5163,17 @@ const solidFillSpPr = (color) => {
5143
5163
  const solidFill = elem(a("solidFill"), { children: [srgbClr] });
5144
5164
  return elem(c("spPr"), { children: [solidFill] });
5145
5165
  };
5146
- const gridlinesElement = (local, color) => {
5147
- if (color === void 0) return elem(c(local));
5148
- const hex = color.replace(/^#/, "").toUpperCase();
5149
- const ln = elem(a("ln"), { children: [elem(a("solidFill"), { children: [elem(a("srgbClr"), { attrs: [attr(qname("", "val", ""), hex)] })] })] });
5150
- return elem(c(local), { children: [elem(c("spPr"), { children: [ln] })] });
5166
+ const lineSpPr = (color, widthEmu, field) => {
5167
+ if (color === void 0 && widthEmu === void 0) return null;
5168
+ const ln = elem(a("ln"), {
5169
+ attrs: widthEmu !== void 0 ? [attr(qname("", "w", ""), String(lineWidthEmu(widthEmu, field)))] : [],
5170
+ children: color !== void 0 ? [elem(a("solidFill"), { children: [elem(a("srgbClr"), { attrs: [attr(qname("", "val", ""), color.replace(/^#/, "").toUpperCase())] })] })] : []
5171
+ });
5172
+ return elem(c("spPr"), { children: [ln] });
5173
+ };
5174
+ const gridlinesElement = (local, color, widthEmu, field) => {
5175
+ const spPr = lineSpPr(color, widthEmu, field);
5176
+ return spPr === null ? elem(c(local)) : elem(c(local), { children: [spPr] });
5151
5177
  };
5152
5178
  const spPrChildren = (fill, stroke) => {
5153
5179
  const out = [];
@@ -5163,8 +5189,8 @@ const DEFAULT_ACCENT_COLORS = [
5163
5189
  "5B9BD5",
5164
5190
  "70AD47"
5165
5191
  ];
5166
- const seriesSpPr = (color, lineWidthEmu$1, lineDash) => {
5167
- const lnChildren = [elem(a("solidFill"), { children: [elem(a("srgbClr"), { attrs: [attr(qname("", "val", ""), color)] })] })];
5192
+ const seriesSpPr = (color, lineColor, lineWidthEmu$1, lineDash) => {
5193
+ const lnChildren = [elem(a("solidFill"), { children: [elem(a("srgbClr"), { attrs: [attr(qname("", "val", ""), lineColor)] })] })];
5168
5194
  if (lineDash !== void 0) lnChildren.push(elem(a("prstDash"), { attrs: [attr(qname("", "val", ""), lineDash)] }));
5169
5195
  const ln = lineWidthEmu$1 !== void 0 ? elem(a("ln"), {
5170
5196
  attrs: [attr(qname("", "w", ""), String(lineWidthEmu(lineWidthEmu$1, "chart series: lineWidthEmu")))],
@@ -5172,11 +5198,14 @@ const seriesSpPr = (color, lineWidthEmu$1, lineDash) => {
5172
5198
  }) : elem(a("ln"), { children: lnChildren });
5173
5199
  return elem(c("spPr"), { children: [elem(a("solidFill"), { children: [elem(a("srgbClr"), { attrs: [attr(qname("", "val", ""), color)] })] }), ln] });
5174
5200
  };
5175
- const markerElement = (symbol, sizePt) => {
5176
- if (symbol === void 0 && sizePt === void 0) return null;
5201
+ const markerElement = (symbol, sizePt, color, lineColor) => {
5177
5202
  const children = [];
5178
5203
  if (symbol !== void 0) children.push(valNode(c("symbol"), symbol));
5179
5204
  if (sizePt !== void 0) children.push(valNode(c("size"), Math.round(sizePt)));
5205
+ if (symbol !== "none") {
5206
+ const fill = (hex) => elem(a("solidFill"), { children: [elem(a("srgbClr"), { attrs: [attr(qname("", "val", ""), hex)] })] });
5207
+ children.push(elem(c("spPr"), { children: [fill(color), elem(a("ln"), { children: [fill(lineColor)] })] }));
5208
+ }
5180
5209
  return elem(c("marker"), { children });
5181
5210
  };
5182
5211
  const dPtElements = (colors, explosions) => {
@@ -5224,25 +5253,30 @@ const seriesElement = (spec, seriesIdx, sheet) => {
5224
5253
  const color = series.color !== void 0 ? series.color.replace(/^#/, "").toUpperCase() : DEFAULT_ACCENT_COLORS[seriesIdx % DEFAULT_ACCENT_COLORS.length] ?? "4472C4";
5225
5254
  const paddedValues = [];
5226
5255
  for (let i = 0; i < spec.categories.length; i++) paddedValues.push(i < series.values.length ? series.values[i] ?? null : null);
5256
+ const kind = series.chartKind ?? spec.kind;
5227
5257
  const children = [
5228
5258
  valNode(c("idx"), seriesIdx),
5229
5259
  valNode(c("order"), seriesIdx),
5230
5260
  elem(c("tx"), { children: [strRef(headerCellFormula, [series.name])] })
5231
5261
  ];
5232
- if (spec.kind === "line" || series.lineWidthEmu !== void 0 || series.lineDash !== void 0) children.push(seriesSpPr(color, series.lineWidthEmu, series.lineDash));
5233
- else children.push(solidFillSpPr(color));
5234
- if (series.invertIfNegative === true && (spec.kind === "bar" || spec.kind === "column")) children.push(valNode(c("invertIfNegative"), "1"));
5235
- if (spec.kind === "line" || spec.kind === "scatter" || spec.kind === "radar") {
5236
- const mk = markerElement(series.markerSymbol, series.markerSizePt);
5237
- if (mk !== null) children.push(mk);
5262
+ if (kind === "line" || series.lineWidthEmu !== void 0 || series.lineColor !== void 0 || series.lineDash !== void 0) {
5263
+ const lineColor = series.lineColor !== void 0 ? series.lineColor.replace(/^#/, "").toUpperCase() : color;
5264
+ children.push(seriesSpPr(color, lineColor, series.lineWidthEmu, series.lineDash));
5265
+ } else children.push(solidFillSpPr(color));
5266
+ if (series.invertIfNegative === true && (kind === "bar" || kind === "column")) children.push(valNode(c("invertIfNegative"), "1"));
5267
+ if (kind === "line" || kind === "scatter" || kind === "radar") {
5268
+ const markerColor = series.markerColor !== void 0 ? series.markerColor.replace(/^#/, "").toUpperCase() : color;
5269
+ const markerLineColor = series.markerLineColor !== void 0 ? series.markerLineColor.replace(/^#/, "").toUpperCase() : markerColor;
5270
+ children.push(markerElement(series.markerSymbol, series.markerSizePt, markerColor, markerLineColor));
5238
5271
  }
5239
5272
  for (const dPt of dPtElements(series.pointColors, series.pointExplosions)) children.push(dPt);
5240
- const serDLbls = buildDLblsFromLabels(series.dataLabels);
5273
+ if (series.pointDataLabels !== void 0 && series.dataLabels === void 0) throw new Error(`chart: series '${series.name}' sets pointDataLabels without dataLabels; add the series-level dataLabels the overrides fall back to`);
5274
+ const serDLbls = buildDLblsFromLabels(series.dataLabels, series.pointDataLabels);
5241
5275
  if (serDLbls !== null) children.push(serDLbls);
5242
- if (series.trendline && spec.kind !== "pie" && spec.kind !== "doughnut" && spec.kind !== "radar") children.push(trendlineElement(series.trendline));
5276
+ if (series.trendline && kind !== "pie" && kind !== "doughnut" && kind !== "radar") children.push(trendlineElement(series.trendline));
5243
5277
  children.push(elem(c("cat"), { children: [strRef(catRange, spec.categories)] }));
5244
5278
  children.push(elem(c("val"), { children: [numRef(valRange, paddedValues)] }));
5245
- if (spec.kind === "line") children.push(valNode(c("smooth"), series.smooth === true ? "1" : "0"));
5279
+ if (kind === "line") children.push(valNode(c("smooth"), series.smooth === true ? "1" : "0"));
5246
5280
  return elem(c("ser"), { children });
5247
5281
  };
5248
5282
  const CAT_AX_ID = 111111111;
@@ -5312,16 +5346,17 @@ const catAxis = (spec) => {
5312
5346
  valNode(c("axId"), CAT_AX_ID),
5313
5347
  elem(c("scaling"), { children: [valNode(c("orientation"), catOrientation)] }),
5314
5348
  valNode(c("delete"), spec.categoryAxisHidden ? "1" : "0"),
5315
- valNode(c("axPos"), "b")
5349
+ valNode(c("axPos"), isHorizontalBar(spec) ? "l" : "b")
5316
5350
  ];
5317
- if (spec.categoryAxisMajorGridlines) children.push(gridlinesElement("majorGridlines", spec.categoryAxisMajorGridlineColor));
5318
- if (spec.categoryAxisMinorGridlines) children.push(gridlinesElement("minorGridlines", spec.categoryAxisMinorGridlineColor));
5351
+ if (spec.categoryAxisMajorGridlines) children.push(gridlinesElement("majorGridlines", spec.categoryAxisMajorGridlineColor, spec.categoryAxisMajorGridlineWidthEmu, "chart: categoryAxisMajorGridlineWidthEmu"));
5352
+ if (spec.categoryAxisMinorGridlines) children.push(gridlinesElement("minorGridlines", spec.categoryAxisMinorGridlineColor, spec.categoryAxisMinorGridlineWidthEmu, "chart: categoryAxisMinorGridlineWidthEmu"));
5319
5353
  if (spec.categoryAxisTitle !== void 0) children.push(titleElement(spec.categoryAxisTitle, spec.categoryAxisTitleStyle, spec.categoryAxisTitleRotationDeg));
5320
5354
  if (spec.categoryAxisNumberFormat !== void 0) children.push(elem(c("numFmt"), { attrs: [attr(qname("", "formatCode", ""), spec.categoryAxisNumberFormat), attr(qname("", "sourceLinked", ""), "0")] }));
5321
5355
  if (spec.categoryAxisMajorTickMark !== void 0) children.push(valNode(c("majorTickMark"), spec.categoryAxisMajorTickMark));
5322
5356
  if (spec.categoryAxisMinorTickMark !== void 0) children.push(valNode(c("minorTickMark"), spec.categoryAxisMinorTickMark));
5323
5357
  if (spec.categoryAxisTickLabelPos !== void 0) children.push(valNode(c("tickLblPos"), spec.categoryAxisTickLabelPos));
5324
- if (spec.categoryAxisLineColor !== void 0) children.push(spPrChildren(void 0, spec.categoryAxisLineColor));
5358
+ const catLine = lineSpPr(spec.categoryAxisLineColor, spec.categoryAxisLineWidthEmu, "chart: categoryAxisLineWidthEmu");
5359
+ if (catLine !== null) children.push(catLine);
5325
5360
  const catTxPr = axisTxPrElement(spec.categoryAxisLabelStyle, spec.categoryAxisLabelRotationDeg);
5326
5361
  if (catTxPr) children.push(catTxPr);
5327
5362
  children.push(valNode(c("crossAx"), VAL_AX_ID));
@@ -5332,39 +5367,85 @@ const catAxis = (spec) => {
5332
5367
  if (spec.categoryAxisNoMultiLevelLabel) children.push(valNode(c("noMultiLvlLbl"), "1"));
5333
5368
  return elem(c("catAx"), { children });
5334
5369
  };
5335
- const valAxis = (spec) => {
5370
+ const valueAxisElement = (f, ids) => {
5336
5371
  const scalingChildren = [];
5337
- if (spec.valueAxis?.logBase !== void 0) scalingChildren.push(valNode(c("logBase"), spec.valueAxis.logBase));
5338
- scalingChildren.push(valNode(c("orientation"), spec.valueAxisOrientation ?? "minMax"));
5339
- if (spec.valueAxis?.max !== void 0) scalingChildren.push(valNode(c("max"), spec.valueAxis.max));
5340
- if (spec.valueAxis?.min !== void 0) scalingChildren.push(valNode(c("min"), spec.valueAxis.min));
5372
+ if (f.scaling?.logBase !== void 0) scalingChildren.push(valNode(c("logBase"), f.scaling.logBase));
5373
+ scalingChildren.push(valNode(c("orientation"), f.orientation ?? "minMax"));
5374
+ if (f.scaling?.max !== void 0) scalingChildren.push(valNode(c("max"), f.scaling.max));
5375
+ if (f.scaling?.min !== void 0) scalingChildren.push(valNode(c("min"), f.scaling.min));
5341
5376
  const children = [
5342
- valNode(c("axId"), VAL_AX_ID),
5377
+ valNode(c("axId"), ids.axId),
5343
5378
  elem(c("scaling"), { children: scalingChildren }),
5344
- valNode(c("delete"), spec.valueAxisHidden ? "1" : "0"),
5345
- valNode(c("axPos"), "l")
5379
+ valNode(c("delete"), f.hidden ? "1" : "0"),
5380
+ valNode(c("axPos"), ids.axPos)
5346
5381
  ];
5347
- if (spec.valueAxisMajorGridlines) children.push(gridlinesElement("majorGridlines", spec.valueAxisMajorGridlineColor));
5348
- if (spec.valueAxisMinorGridlines) children.push(gridlinesElement("minorGridlines", spec.valueAxisMinorGridlineColor));
5349
- if (spec.valueAxisTitle !== void 0) children.push(titleElement(spec.valueAxisTitle, spec.valueAxisTitleStyle, spec.valueAxisTitleRotationDeg));
5350
- if (spec.valueAxis?.numberFormat !== void 0) children.push(elem(c("numFmt"), { attrs: [attr(qname("", "formatCode", ""), spec.valueAxis.numberFormat), attr(qname("", "sourceLinked", ""), "0")] }));
5351
- if (spec.valueAxisMajorTickMark !== void 0) children.push(valNode(c("majorTickMark"), spec.valueAxisMajorTickMark));
5352
- if (spec.valueAxisMinorTickMark !== void 0) children.push(valNode(c("minorTickMark"), spec.valueAxisMinorTickMark));
5353
- if (spec.valueAxisLineColor !== void 0) children.push(spPrChildren(void 0, spec.valueAxisLineColor));
5354
- const valTxPr = axisTxPrElement(spec.valueAxisLabelStyle, spec.valueAxisLabelRotationDeg);
5382
+ if (f.majorGridlines) children.push(gridlinesElement("majorGridlines", f.majorGridlineColor, f.majorGridlineWidthEmu, `chart: ${f.widthFields.majorGridline}`));
5383
+ if (f.minorGridlines) children.push(gridlinesElement("minorGridlines", f.minorGridlineColor, f.minorGridlineWidthEmu, `chart: ${f.widthFields.minorGridline}`));
5384
+ if (f.title !== void 0) children.push(titleElement(f.title, f.titleStyle, f.titleRotationDeg));
5385
+ if (f.scaling?.numberFormat !== void 0) children.push(elem(c("numFmt"), { attrs: [attr(qname("", "formatCode", ""), f.scaling.numberFormat), attr(qname("", "sourceLinked", ""), "0")] }));
5386
+ if (f.majorTickMark !== void 0) children.push(valNode(c("majorTickMark"), f.majorTickMark));
5387
+ if (f.minorTickMark !== void 0) children.push(valNode(c("minorTickMark"), f.minorTickMark));
5388
+ if (f.tickLabelPos !== void 0) children.push(valNode(c("tickLblPos"), f.tickLabelPos));
5389
+ const axisLine = lineSpPr(f.lineColor, f.lineWidthEmu, `chart: ${f.widthFields.line}`);
5390
+ if (axisLine !== null) children.push(axisLine);
5391
+ const valTxPr = axisTxPrElement(f.labelStyle, f.labelRotationDeg);
5355
5392
  if (valTxPr) children.push(valTxPr);
5356
- children.push(valNode(c("crossAx"), CAT_AX_ID));
5357
- const xross = spec.valueAxisCrosses;
5393
+ children.push(valNode(c("crossAx"), ids.crossAxId));
5394
+ const xross = f.crosses;
5358
5395
  if (xross !== void 0) if (typeof xross === "string") children.push(valNode(c("crosses"), xross));
5359
5396
  else children.push(valNode(c("crossesAt"), String(xross.at)));
5360
- if (spec.valueAxisCrossBetween !== void 0) children.push(valNode(c("crossBetween"), spec.valueAxisCrossBetween));
5361
- if (spec.valueAxis?.majorUnit !== void 0) children.push(valNode(c("majorUnit"), spec.valueAxis.majorUnit));
5362
- if (spec.valueAxis?.minorUnit !== void 0) children.push(valNode(c("minorUnit"), spec.valueAxis.minorUnit));
5363
- if (spec.valueAxis?.displayUnits !== void 0) children.push(elem(c("dispUnits"), { children: [valNode(c("builtInUnit"), spec.valueAxis.displayUnits)] }));
5397
+ if (f.crossBetween !== void 0) children.push(valNode(c("crossBetween"), f.crossBetween));
5398
+ if (f.scaling?.majorUnit !== void 0) children.push(valNode(c("majorUnit"), f.scaling.majorUnit));
5399
+ if (f.scaling?.minorUnit !== void 0) children.push(valNode(c("minorUnit"), f.scaling.minorUnit));
5400
+ if (f.scaling?.displayUnits !== void 0) children.push(elem(c("dispUnits"), { children: [valNode(c("builtInUnit"), f.scaling.displayUnits)] }));
5364
5401
  return elem(c("valAx"), { children });
5365
5402
  };
5366
- const buildDLblsFromLabels = (dl) => {
5367
- if (!dl) return null;
5403
+ const isHorizontalBar = (spec) => spec.kind === "bar";
5404
+ const valAxis = (spec) => valueAxisElement({
5405
+ scaling: spec.valueAxis,
5406
+ orientation: spec.valueAxisOrientation,
5407
+ hidden: spec.valueAxisHidden,
5408
+ majorGridlines: spec.valueAxisMajorGridlines,
5409
+ majorGridlineColor: spec.valueAxisMajorGridlineColor,
5410
+ majorGridlineWidthEmu: spec.valueAxisMajorGridlineWidthEmu,
5411
+ minorGridlines: spec.valueAxisMinorGridlines,
5412
+ minorGridlineColor: spec.valueAxisMinorGridlineColor,
5413
+ minorGridlineWidthEmu: spec.valueAxisMinorGridlineWidthEmu,
5414
+ title: spec.valueAxisTitle,
5415
+ titleStyle: spec.valueAxisTitleStyle,
5416
+ titleRotationDeg: spec.valueAxisTitleRotationDeg,
5417
+ majorTickMark: spec.valueAxisMajorTickMark,
5418
+ minorTickMark: spec.valueAxisMinorTickMark,
5419
+ tickLabelPos: spec.valueAxisTickLabelPos,
5420
+ lineColor: spec.valueAxisLineColor,
5421
+ lineWidthEmu: spec.valueAxisLineWidthEmu,
5422
+ widthFields: {
5423
+ majorGridline: "valueAxisMajorGridlineWidthEmu",
5424
+ minorGridline: "valueAxisMinorGridlineWidthEmu",
5425
+ line: "valueAxisLineWidthEmu"
5426
+ },
5427
+ labelStyle: spec.valueAxisLabelStyle,
5428
+ labelRotationDeg: spec.valueAxisLabelRotationDeg,
5429
+ crosses: spec.valueAxisCrosses,
5430
+ crossBetween: spec.valueAxisCrossBetween
5431
+ }, {
5432
+ axId: VAL_AX_ID,
5433
+ crossAxId: CAT_AX_ID,
5434
+ axPos: isHorizontalBar(spec) ? "b" : "l"
5435
+ });
5436
+ const buildDLblsFromLabels = (dl, pointLabels = void 0) => {
5437
+ const children = [];
5438
+ pointLabels?.forEach((pl, i) => {
5439
+ if (pl === null) return;
5440
+ children.push(elem(c("dLbl"), { children: [valNode(c("idx"), i), ...dLblGroupChildren(pl)] }));
5441
+ });
5442
+ if (dl) {
5443
+ children.push(...dLblGroupChildren(dl));
5444
+ if (dl.showLeaderLines !== void 0) children.push(valNode(c("showLeaderLines"), dl.showLeaderLines ? "1" : "0"));
5445
+ }
5446
+ return children.length === 0 ? null : elem(c("dLbls"), { children });
5447
+ };
5448
+ const dLblGroupChildren = (dl) => {
5368
5449
  const children = [];
5369
5450
  if (dl.numberFormat !== void 0) children.push(elem(c("numFmt"), { attrs: [attr(qname("", "formatCode", ""), dl.numberFormat), attr(qname("", "sourceLinked", ""), "0")] }));
5370
5451
  if (dl.textStyle !== void 0) {
@@ -5374,7 +5455,7 @@ const buildDLblsFromLabels = (dl) => {
5374
5455
  if (dl.position !== void 0) children.push(valNode(c("dLblPos"), dl.position));
5375
5456
  children.push(valNode(c("showLegendKey"), "0"), valNode(c("showVal"), dl.showValue ? "1" : "0"), valNode(c("showCatName"), dl.showCategory ? "1" : "0"), valNode(c("showSerName"), dl.showSeriesName ? "1" : "0"), valNode(c("showPercent"), dl.showPercent ? "1" : "0"), valNode(c("showBubbleSize"), "0"));
5376
5457
  if (dl.separator !== void 0) children.push(elem(c("separator"), { children: [text(dl.separator)] }));
5377
- return elem(c("dLbls"), { children });
5458
+ return children;
5378
5459
  };
5379
5460
  const dLblsElement = (spec) => buildDLblsFromLabels(spec.dataLabels);
5380
5461
  const buildBarChart = (spec, sheet, direction, seriesIndices, axes) => {
@@ -5394,11 +5475,12 @@ const buildBarChart = (spec, sheet, direction, seriesIndices, axes) => {
5394
5475
  children.push(valNode(c("axId"), axes.cat), valNode(c("axId"), axes.val));
5395
5476
  return elem(c(direction === "col" ? "barChart" : "barChart"), { children });
5396
5477
  };
5478
+ const lineAreaGrouping = (spec) => spec.grouping === "stacked" || spec.grouping === "percentStacked" ? spec.grouping : "standard";
5397
5479
  const buildLineChart = (spec, sheet, seriesIndices, axes) => {
5398
5480
  const ser = seriesIndices.map((i) => seriesElement(spec, i, sheet));
5399
5481
  const dl = dLblsElement(spec);
5400
5482
  const children = [
5401
- valNode(c("grouping"), spec.grouping ?? "standard"),
5483
+ valNode(c("grouping"), lineAreaGrouping(spec)),
5402
5484
  valNode(c("varyColors"), spec.varyColors ? "1" : "0"),
5403
5485
  ...ser,
5404
5486
  ...dl ? [dl] : []
@@ -5437,7 +5519,7 @@ const buildAreaChart = (spec, sheet, seriesIndices, axes) => {
5437
5519
  const ser = seriesIndices.map((i) => seriesElement(spec, i, sheet));
5438
5520
  const dl = dLblsElement(spec);
5439
5521
  return elem(c("areaChart"), { children: [
5440
- valNode(c("grouping"), spec.grouping ?? "standard"),
5522
+ valNode(c("grouping"), lineAreaGrouping(spec)),
5441
5523
  valNode(c("varyColors"), spec.varyColors ? "1" : "0"),
5442
5524
  ...ser,
5443
5525
  ...dl ? [dl] : [],
@@ -5458,25 +5540,54 @@ const buildComboGroupChart = (spec, sheet, kind, seriesIndices, axes) => {
5458
5540
  /**
5459
5541
  * Secondary value axis (`axPos="r"`, crossing at the category maximum) —
5460
5542
  * the right-hand axis PowerPoint pairs with `secondaryAxis` series.
5461
- */
5462
- const secondaryValAxis = () => elem(c("valAx"), { children: [
5463
- valNode(c("axId"), SEC_VAL_AX_ID),
5464
- elem(c("scaling"), { children: [valNode(c("orientation"), "minMax")] }),
5465
- valNode(c("delete"), "0"),
5466
- valNode(c("axPos"), "r"),
5467
- valNode(c("crossAx"), SEC_CAT_AX_ID),
5468
- valNode(c("crosses"), "max")
5469
- ] });
5543
+ * Formatting comes from `spec.secondaryValueAxis`; PowerPoint's defaults
5544
+ * apply for everything left out.
5545
+ */
5546
+ const secondaryValAxis = (spec) => {
5547
+ const s = spec.secondaryValueAxis ?? {};
5548
+ return valueAxisElement({
5549
+ scaling: s.scaling,
5550
+ orientation: void 0,
5551
+ hidden: void 0,
5552
+ majorGridlines: s.majorGridlines,
5553
+ majorGridlineColor: s.majorGridlineColor,
5554
+ majorGridlineWidthEmu: s.majorGridlineWidthEmu,
5555
+ minorGridlines: void 0,
5556
+ minorGridlineColor: void 0,
5557
+ minorGridlineWidthEmu: void 0,
5558
+ title: s.title,
5559
+ titleStyle: s.titleStyle,
5560
+ titleRotationDeg: void 0,
5561
+ majorTickMark: s.majorTickMark,
5562
+ minorTickMark: s.minorTickMark,
5563
+ tickLabelPos: s.tickLabelPos,
5564
+ lineColor: s.lineColor,
5565
+ lineWidthEmu: s.lineWidthEmu,
5566
+ widthFields: {
5567
+ majorGridline: "secondaryValueAxis.majorGridlineWidthEmu",
5568
+ minorGridline: "secondaryValueAxis.minorGridlineWidthEmu",
5569
+ line: "secondaryValueAxis.lineWidthEmu"
5570
+ },
5571
+ labelStyle: s.labelStyle,
5572
+ labelRotationDeg: void 0,
5573
+ crosses: "max",
5574
+ crossBetween: s.crossBetween
5575
+ }, {
5576
+ axId: SEC_VAL_AX_ID,
5577
+ crossAxId: SEC_CAT_AX_ID,
5578
+ axPos: "r"
5579
+ });
5580
+ };
5470
5581
  /**
5471
5582
  * Deleted companion category axis for the secondary pair. PowerPoint
5472
5583
  * requires every plot group's axId pair to resolve to a cat+val pair,
5473
5584
  * so the secondary group gets its own (hidden) category axis.
5474
5585
  */
5475
- const secondaryCatAxis = () => elem(c("catAx"), { children: [
5586
+ const secondaryCatAxis = (spec) => elem(c("catAx"), { children: [
5476
5587
  valNode(c("axId"), SEC_CAT_AX_ID),
5477
5588
  elem(c("scaling"), { children: [valNode(c("orientation"), "minMax")] }),
5478
5589
  valNode(c("delete"), "1"),
5479
- valNode(c("axPos"), "b"),
5590
+ valNode(c("axPos"), isHorizontalBar(spec) ? "l" : "b"),
5480
5591
  valNode(c("crossAx"), SEC_VAL_AX_ID)
5481
5592
  ] });
5482
5593
  const rPrAttrsFromStyle = (style) => {
@@ -5502,8 +5613,7 @@ const rPrAttrsFromStyle = (style) => {
5502
5613
  };
5503
5614
  };
5504
5615
  const titleElement = (title, style, rotationDeg) => {
5505
- const rPr = elem(a("defRPr"), { attrs: [attr(qname("", "sz", ""), "1400")] });
5506
- const pPr = elem(a("pPr"), { children: [rPr] });
5616
+ const pPr = elem(a("pPr"), { children: [elem(a("defRPr"))] });
5507
5617
  const { attrs: runAttrs, children: runChildren } = rPrAttrsFromStyle(style);
5508
5618
  const runRPr = elem(a("rPr"), {
5509
5619
  attrs: [attr(qname("", "lang", ""), "en-US"), ...runAttrs],
@@ -5511,13 +5621,12 @@ const titleElement = (title, style, rotationDeg) => {
5511
5621
  });
5512
5622
  const tRun = elem(a("r"), { children: [runRPr, elem(a("t"), { children: [text(title)] })] });
5513
5623
  const para = elem(a("p"), { children: [pPr, tRun] });
5514
- const rotStr = rotationDeg !== void 0 && rotationDeg !== 0 ? String(Math.round(rotationDeg * 6e4)) : "0";
5515
5624
  const rich = elem(c("rich"), { children: [
5516
5625
  elem(a("bodyPr"), { attrs: [
5517
- attr(qname("", "rot", ""), rotStr),
5626
+ ...rotationDeg !== void 0 ? [attr(qname("", "rot", ""), String(Math.round(rotationDeg * 6e4)))] : [],
5518
5627
  attr(qname("", "spcFirstLastPara", ""), "1"),
5519
5628
  attr(qname("", "vertOverflow", ""), "ellipsis"),
5520
- attr(qname("", "vert", ""), "horz"),
5629
+ ...rotationDeg !== void 0 ? [attr(qname("", "vert", ""), "horz")] : [],
5521
5630
  attr(qname("", "wrap", ""), "square"),
5522
5631
  attr(qname("", "anchor", ""), "ctr"),
5523
5632
  attr(qname("", "anchorCtr", ""), "1")
@@ -5568,7 +5677,7 @@ const buildChartSpaceDoc = (spec) => {
5568
5677
  const plotAreaChildren = [elem(c("layout")), ...plottedGroups];
5569
5678
  if (!axisless) {
5570
5679
  plotAreaChildren.push(catAxis(spec), valAxis(spec));
5571
- if (hasSecondary) plotAreaChildren.push(secondaryValAxis(), secondaryCatAxis());
5680
+ if (hasSecondary) plotAreaChildren.push(secondaryValAxis(spec), secondaryCatAxis(spec));
5572
5681
  }
5573
5682
  if (spec.plotAreaFill !== void 0 || spec.plotAreaStrokeColor !== void 0) plotAreaChildren.push(spPrChildren(spec.plotAreaFill, spec.plotAreaStrokeColor));
5574
5683
  const plotArea = elem(c("plotArea"), { children: plotAreaChildren });
@@ -5642,7 +5751,12 @@ const NAME_MULTI_LVL_STR_REF = qname("c", "multiLvlStrRef", NS_C);
5642
5751
  const NAME_MULTI_LVL_STR_CACHE = qname("c", "multiLvlStrCache", NS_C);
5643
5752
  const NAME_LVL = qname("c", "lvl", NS_C);
5644
5753
  const NAME_PT = qname("c", "pt", NS_C);
5754
+ const NAME_PT_COUNT = qname("c", "ptCount", NS_C);
5755
+ const MAX_PT_COUNT = 1048576;
5645
5756
  const NAME_V = qname("c", "v", NS_C);
5757
+ const NAME_D_LBLS = qname("c", "dLbls", NS_C);
5758
+ const NAME_D_LBL = qname("c", "dLbl", NS_C);
5759
+ const NAME_VAL_AX = qname("c", "valAx", NS_C);
5646
5760
  const NAME_TITLE = qname("c", "title", NS_C);
5647
5761
  const NAME_RICH = qname("c", "rich", NS_C);
5648
5762
  const NAME_T = qname("a", "t", NS_A);
@@ -5728,19 +5842,40 @@ const findFirst = (parent, names) => {
5728
5842
  }
5729
5843
  return null;
5730
5844
  };
5731
- const readPtArray = (cache) => {
5845
+ const readPtCount = (host) => {
5846
+ const ptCountEl = firstChildElement(host, NAME_PT_COUNT);
5847
+ const raw = ptCountEl !== null ? getAttrValue(ptCountEl, ATTR_VAL) : null;
5848
+ return raw !== null ? Number.parseInt(raw, 10) : NaN;
5849
+ };
5850
+ const readXmlBool = (el) => {
5851
+ const v = getAttrValue(el, ATTR_VAL);
5852
+ return v === null || v === "1" || v === "true";
5853
+ };
5854
+ const parsePointIndex = (raw, limit) => {
5855
+ if (raw === null || !/^\d+$/.test(raw)) return null;
5856
+ const idx = Number.parseInt(raw, 10);
5857
+ return idx < limit ? idx : null;
5858
+ };
5859
+ const readPointIndex = (host, pointCount) => {
5860
+ const idxEl = firstChildElement(host, qname("c", "idx", NS_C));
5861
+ return parsePointIndex(idxEl !== null ? getAttrValue(idxEl, ATTR_VAL) : null, pointCount);
5862
+ };
5863
+ const readPtArray = (cache, countHost = cache) => {
5732
5864
  const out = [];
5865
+ const ptCount = readPtCount(countHost);
5866
+ const idxLimit = Number.isFinite(ptCount) ? Math.min(ptCount, MAX_PT_COUNT) : MAX_PT_COUNT;
5733
5867
  for (const pt of allChildElements(cache, NAME_PT)) {
5734
- const idxRaw = getAttrValue(pt, ATTR_IDX);
5735
- if (idxRaw === null) continue;
5736
- const idx = Number.parseInt(idxRaw, 10);
5737
- if (!Number.isFinite(idx) || idx < 0) continue;
5868
+ const idx = parsePointIndex(getAttrValue(pt, ATTR_IDX), idxLimit);
5869
+ if (idx === null) continue;
5738
5870
  const v = firstChildElement(pt, NAME_V);
5739
5871
  if (v === null) continue;
5740
5872
  let text = "";
5741
5873
  for (const child of v.children) if (child.kind === "text" || child.kind === "cdata") text += child.data;
5742
5874
  out[idx] = text;
5743
5875
  }
5876
+ if (Number.isFinite(ptCount) && ptCount <= MAX_PT_COUNT) {
5877
+ for (let i = 0; i < ptCount; i++) if (out[i] === void 0) out[i] = "";
5878
+ }
5744
5879
  return out;
5745
5880
  };
5746
5881
  const readStringChannel = (parent) => {
@@ -5755,7 +5890,7 @@ const readStringChannel = (parent) => {
5755
5890
  if (multi) {
5756
5891
  const cache = firstChildElement(multi, NAME_MULTI_LVL_STR_CACHE);
5757
5892
  const lvl = cache ? firstChildElement(cache, NAME_LVL) : null;
5758
- if (lvl) return readPtArray(lvl);
5893
+ if (lvl && cache) return readPtArray(lvl, cache);
5759
5894
  }
5760
5895
  return null;
5761
5896
  };
@@ -5784,19 +5919,15 @@ const readSeriesName = (ser) => {
5784
5919
  if (!tx) return "";
5785
5920
  return readStringRef(tx)?.[0] ?? "";
5786
5921
  };
5787
- const readDataPointOverrides = (ser) => {
5922
+ const readDataPointOverrides = (ser, pointCount) => {
5788
5923
  const colors = [];
5789
5924
  const explosions = [];
5790
5925
  let anyColor = false;
5791
5926
  let anyExplosion = false;
5792
5927
  for (const c of ser.children) {
5793
5928
  if (c.kind !== "element" || c.name.namespaceURI !== NS_C || c.name.localName !== "dPt") continue;
5794
- const idxEl = firstChildElement(c, qname("c", "idx", NS_C));
5795
- if (!idxEl) continue;
5796
- const idxRaw = getAttrValue(idxEl, ATTR_VAL);
5797
- if (idxRaw === null) continue;
5798
- const idx = Number.parseInt(idxRaw, 10);
5799
- if (!Number.isFinite(idx) || idx < 0) continue;
5929
+ const idx = readPointIndex(c, pointCount);
5930
+ if (idx === null) continue;
5800
5931
  const spPr = firstChildElement(c, NAME_SP_PR_C);
5801
5932
  if (spPr) {
5802
5933
  const solidFill = firstChildElement(spPr, NAME_SOLID_FILL$1);
@@ -5929,10 +6060,21 @@ const readSeriesColor = (ser) => {
5929
6060
  const v = getAttrValue(srgb, ATTR_VAL);
5930
6061
  return v !== null ? `#${v.toUpperCase()}` : void 0;
5931
6062
  };
6063
+ const readSolidSrgb = (host) => {
6064
+ const fill = host !== null ? firstChildElement(host, NAME_SOLID_FILL$1) : null;
6065
+ const srgb = fill !== null ? firstChildElement(fill, NAME_SRGB_CLR) : null;
6066
+ const color = srgb !== null ? getAttrValue(srgb, ATTR_VAL) : null;
6067
+ return color !== null ? `#${color.toUpperCase()}` : void 0;
6068
+ };
5932
6069
  const readSeriesMarker = (ser) => {
5933
6070
  const m = firstChildElement(ser, qname("c", "marker", NS_C));
5934
6071
  if (!m) return {};
5935
6072
  const out = {};
6073
+ const spPr = firstChildElement(m, NAME_SP_PR_C);
6074
+ const color = readSolidSrgb(spPr);
6075
+ if (color !== void 0) out.markerColor = color;
6076
+ const lineColor = readSolidSrgb(spPr !== null ? firstChildElement(spPr, qname("a", "ln", NS_A)) : null);
6077
+ if (lineColor !== void 0) out.markerLineColor = lineColor;
5936
6078
  const symEl = firstChildElement(m, qname("c", "symbol", NS_C));
5937
6079
  if (symEl) {
5938
6080
  const v = getAttrValue(symEl, ATTR_VAL);
@@ -5954,10 +6096,14 @@ const readSeriesLineProps = (ser) => {
5954
6096
  const ln = firstChildElement(spPr, qname("a", "ln", NS_A));
5955
6097
  if (!ln) return {};
5956
6098
  const out = {};
6099
+ const lnFill = firstChildElement(ln, NAME_SOLID_FILL$1);
6100
+ const lnSrgb = lnFill !== null ? firstChildElement(lnFill, NAME_SRGB_CLR) : null;
6101
+ const lnColor = lnSrgb !== null ? getAttrValue(lnSrgb, ATTR_VAL) : null;
6102
+ if (lnColor !== null) out.lineColor = `#${lnColor.toUpperCase()}`;
5957
6103
  const w = getAttrValue(ln, qname("", "w", ""));
5958
6104
  if (w !== null) {
5959
6105
  const n = Number.parseInt(w, 10);
5960
- if (Number.isFinite(n) && n > 0) out.lineWidthEmu = n;
6106
+ if (Number.isFinite(n) && n >= 0) out.lineWidthEmu = n;
5961
6107
  }
5962
6108
  const prstDash = firstChildElement(ln, qname("a", "prstDash", NS_A));
5963
6109
  if (prstDash) {
@@ -6032,21 +6178,20 @@ const readRunStyle = (rPr) => {
6032
6178
  };
6033
6179
  const readLabelStyle = (richHost) => {
6034
6180
  for (const p of allChildElements(richHost, NAME_P_DML)) {
6181
+ let runStyle;
6035
6182
  for (const r of allChildElements(p, NAME_R_DML)) {
6036
6183
  const rPr = firstChildElement(r, NAME_A_RPR$1);
6037
- if (rPr) {
6038
- const s = readRunStyle(rPr);
6039
- if (s) return s;
6040
- }
6184
+ runStyle = rPr !== null ? readRunStyle(rPr) : void 0;
6185
+ if (runStyle !== void 0) break;
6041
6186
  }
6042
6187
  const pPr = firstChildElement(p, NAME_A_PPR$1);
6043
- if (pPr) {
6044
- const defRPr = firstChildElement(pPr, NAME_A_DEF_RPR$1);
6045
- if (defRPr) {
6046
- const s = readRunStyle(defRPr);
6047
- if (s) return s;
6048
- }
6049
- }
6188
+ const defRPr = pPr !== null ? firstChildElement(pPr, NAME_A_DEF_RPR$1) : null;
6189
+ const defStyle = defRPr !== null ? readRunStyle(defRPr) : void 0;
6190
+ if (runStyle === void 0 && defStyle === void 0) continue;
6191
+ return {
6192
+ ...defStyle,
6193
+ ...runStyle
6194
+ };
6050
6195
  }
6051
6196
  };
6052
6197
  const readTitleStyleOf = (titleEl) => {
@@ -6097,6 +6242,121 @@ const readDataLabelSeparator = (dLbls) => {
6097
6242
  for (const c of el.children) if (c.kind === "text" || c.kind === "cdata") acc += c.data;
6098
6243
  return acc.length > 0 ? acc : void 0;
6099
6244
  };
6245
+ const readDataLabelsGroup = (host, inherited) => {
6246
+ const readToggle = (local, fallback) => {
6247
+ const el = firstChildElement(host, qname("c", local, NS_C));
6248
+ return el !== null ? readXmlBool(el) : fallback;
6249
+ };
6250
+ const nfEl = firstChildElement(host, qname("c", "numFmt", NS_C));
6251
+ let numberFormat;
6252
+ if (nfEl) {
6253
+ const fc = getAttrValue(nfEl, qname("", "formatCode", ""));
6254
+ if (fc !== null && fc.length > 0 && fc !== "General") numberFormat = fc;
6255
+ }
6256
+ const position = readDataLabelPosition(host);
6257
+ const separator = readDataLabelSeparator(host);
6258
+ const txPrEl = firstChildElement(host, qname("c", "txPr", NS_C));
6259
+ const textStyle = txPrEl ? readLabelStyle(txPrEl) : void 0;
6260
+ return {
6261
+ showValue: readToggle("showVal", inherited?.showValue ?? false),
6262
+ showCategory: readToggle("showCatName", inherited?.showCategory ?? false),
6263
+ showSeriesName: readToggle("showSerName", inherited?.showSeriesName ?? false),
6264
+ showPercent: readToggle("showPercent", inherited?.showPercent ?? false),
6265
+ ...numberFormat !== void 0 ? { numberFormat } : {},
6266
+ ...position !== void 0 ? { position } : {},
6267
+ ...separator !== void 0 ? { separator } : {},
6268
+ ...textStyle !== void 0 ? { textStyle } : {}
6269
+ };
6270
+ };
6271
+ const readSeriesLevelDataLabels = (dLbls) => {
6272
+ const group = readDataLabelsGroup(dLbls, void 0);
6273
+ const leaderEl = firstChildElement(dLbls, qname("c", "showLeaderLines", NS_C));
6274
+ return leaderEl !== null ? {
6275
+ ...group,
6276
+ showLeaderLines: readXmlBool(leaderEl)
6277
+ } : group;
6278
+ };
6279
+ const hasDataLabelGroupChild = (dLbls) => dLbls.children.some((ch) => ch.kind === "element" && ch.name.namespaceURI === NS_C && ch.name.localName !== "dLbl" && ch.name.localName !== "extLst");
6280
+ const DELETED_POINT_LABEL = {
6281
+ showValue: false,
6282
+ showCategory: false,
6283
+ showSeriesName: false,
6284
+ showPercent: false
6285
+ };
6286
+ const readPointDataLabels = (dLbls, pointCount, seriesLabels) => {
6287
+ const out = [];
6288
+ let any = false;
6289
+ for (const dLbl of allChildElements(dLbls, NAME_D_LBL)) {
6290
+ const idx = readPointIndex(dLbl, pointCount);
6291
+ if (idx === null) continue;
6292
+ const deleteEl = firstChildElement(dLbl, qname("c", "delete", NS_C));
6293
+ out[idx] = deleteEl !== null && readXmlBool(deleteEl) ? DELETED_POINT_LABEL : readDataLabelsGroup(dLbl, seriesLabels);
6294
+ any = true;
6295
+ }
6296
+ if (!any) return void 0;
6297
+ for (let i = 0; i < out.length; i++) out[i] ??= null;
6298
+ return out;
6299
+ };
6300
+ const readValueAxisScaling = (valAx) => {
6301
+ let min;
6302
+ let max;
6303
+ let majorUnit;
6304
+ let minorUnit;
6305
+ let logBase;
6306
+ let displayUnits;
6307
+ const scaling = firstChildElement(valAx, qname("c", "scaling", NS_C));
6308
+ const readNumOn = (parent, local) => {
6309
+ const el = firstChildElement(parent, qname("c", local, NS_C));
6310
+ if (!el) return void 0;
6311
+ const v = getAttrValue(el, ATTR_VAL);
6312
+ if (v === null) return void 0;
6313
+ const n = Number.parseFloat(v);
6314
+ return Number.isFinite(n) ? n : void 0;
6315
+ };
6316
+ if (scaling) {
6317
+ min = readNumOn(scaling, "min");
6318
+ max = readNumOn(scaling, "max");
6319
+ const lb = readNumOn(scaling, "logBase");
6320
+ if (lb !== void 0 && lb >= 2 && lb <= 1e3) logBase = lb;
6321
+ }
6322
+ majorUnit = readNumOn(valAx, "majorUnit");
6323
+ minorUnit = readNumOn(valAx, "minorUnit");
6324
+ const dispUnits = firstChildElement(valAx, qname("c", "dispUnits", NS_C));
6325
+ if (dispUnits) {
6326
+ const builtIn = firstChildElement(dispUnits, qname("c", "builtInUnit", NS_C));
6327
+ if (builtIn) {
6328
+ const v = getAttrValue(builtIn, ATTR_VAL);
6329
+ switch (v) {
6330
+ case "hundreds":
6331
+ case "thousands":
6332
+ case "tenThousands":
6333
+ case "hundredThousands":
6334
+ case "millions":
6335
+ case "tenMillions":
6336
+ case "hundredMillions":
6337
+ case "billions":
6338
+ case "trillions":
6339
+ displayUnits = v;
6340
+ break;
6341
+ }
6342
+ }
6343
+ }
6344
+ let numberFormat;
6345
+ const nfEl = firstChildElement(valAx, qname("c", "numFmt", NS_C));
6346
+ if (nfEl) {
6347
+ const fc = getAttrValue(nfEl, qname("", "formatCode", ""));
6348
+ if (fc !== null && fc.length > 0 && fc !== "General") numberFormat = fc;
6349
+ }
6350
+ if (min !== void 0 || max !== void 0 || majorUnit !== void 0 || minorUnit !== void 0 || numberFormat !== void 0 || logBase !== void 0 || displayUnits !== void 0) return {
6351
+ ...min !== void 0 ? { min } : {},
6352
+ ...max !== void 0 ? { max } : {},
6353
+ ...majorUnit !== void 0 ? { majorUnit } : {},
6354
+ ...minorUnit !== void 0 ? { minorUnit } : {},
6355
+ ...numberFormat !== void 0 ? { numberFormat } : {},
6356
+ ...logBase !== void 0 ? { logBase } : {},
6357
+ ...displayUnits !== void 0 ? { displayUnits } : {}
6358
+ };
6359
+ };
6100
6360
  /**
6101
6361
  * Parses a `<c:chartSpace>` element into a typed `ChartSpec`. Throws if
6102
6362
  * the root or any required child is missing. Returns `null` only when
@@ -6129,22 +6389,24 @@ const readChartSpec = (root) => {
6129
6389
  if (!firstGroup) return null;
6130
6390
  const plotted = firstGroup.element;
6131
6391
  const kind = firstGroup.kind;
6132
- const secondaryValAxisIds = /* @__PURE__ */ new Set();
6133
- for (const child of plotArea.children) {
6134
- if (child.kind !== "element" || child.name.namespaceURI !== NS_C || child.name.localName !== "valAx") continue;
6135
- const axIdEl = firstChildElement(child, qname("c", "axId", NS_C));
6136
- const axPosEl = firstChildElement(child, qname("c", "axPos", NS_C));
6137
- const axId = axIdEl !== null ? getAttrValue(axIdEl, ATTR_VAL) : null;
6138
- const axPos = axPosEl !== null ? getAttrValue(axPosEl, ATTR_VAL) : null;
6139
- if (axId !== null && (axPos === "r" || axPos === "t")) secondaryValAxisIds.add(axId);
6140
- }
6141
- const groupUsesSecondaryAxis = (group) => {
6142
- for (const child of group.children) if (child.kind === "element" && child.name.namespaceURI === NS_C && child.name.localName === "axId") {
6143
- const id = getAttrValue(child, ATTR_VAL);
6144
- if (id !== null && secondaryValAxisIds.has(id)) return true;
6392
+ const groupAxisIds = (group) => {
6393
+ const ids = [];
6394
+ for (const axIdEl of allChildElements(group, qname("c", "axId", NS_C))) {
6395
+ const id = getAttrValue(axIdEl, ATTR_VAL);
6396
+ if (id !== null) ids.push(id);
6145
6397
  }
6146
- return false;
6398
+ return ids;
6147
6399
  };
6400
+ const valAxisIds = /* @__PURE__ */ new Set();
6401
+ for (const el of allChildElements(plotArea, NAME_VAL_AX)) {
6402
+ const axIdEl = firstChildElement(el, qname("c", "axId", NS_C));
6403
+ const id = axIdEl !== null ? getAttrValue(axIdEl, ATTR_VAL) : null;
6404
+ if (id !== null) valAxisIds.add(id);
6405
+ }
6406
+ const primaryAxisIds = new Set(groupAxisIds(plotted));
6407
+ const secondaryValAxisIds = /* @__PURE__ */ new Set();
6408
+ for (const group of plotGroups.slice(1)) for (const id of groupAxisIds(group.element)) if (valAxisIds.has(id) && !primaryAxisIds.has(id)) secondaryValAxisIds.add(id);
6409
+ const groupUsesSecondaryAxis = (group) => groupAxisIds(group).some((id) => secondaryValAxisIds.has(id));
6148
6410
  const series = [];
6149
6411
  let categoriesFromFirst = null;
6150
6412
  const serEntries = [];
@@ -6174,44 +6436,18 @@ const readChartSpec = (root) => {
6174
6436
  const bubbleSizeEl = firstChildElement(ser, qname("c", "bubbleSize", NS_C));
6175
6437
  const bubbleSizes = bubbleSizeEl !== null ? readNumRef(bubbleSizeEl) : null;
6176
6438
  const color = readSeriesColor(ser);
6177
- const { lineWidthEmu, lineDash } = readSeriesLineProps(ser);
6178
- const { markerSymbol, markerSizePt } = readSeriesMarker(ser);
6439
+ const { lineWidthEmu, lineColor, lineDash } = readSeriesLineProps(ser);
6440
+ const { markerSymbol, markerSizePt, markerColor, markerLineColor } = readSeriesMarker(ser);
6179
6441
  const invertEl = firstChildElement(ser, qname("c", "invertIfNegative", NS_C));
6180
- const invertIfNegative = invertEl !== null && getAttrValue(invertEl, ATTR_VAL) !== "0" ? true : void 0;
6181
- const { colors: pointColors, explosions: pointExplosions } = readDataPointOverrides(ser);
6442
+ const invertIfNegative = invertEl !== null && readXmlBool(invertEl) ? true : void 0;
6443
+ const pointCount = values !== null ? values.length : 0;
6444
+ const { colors: pointColors, explosions: pointExplosions } = readDataPointOverrides(ser, pointCount);
6182
6445
  const smoothEl = firstChildElement(ser, qname("c", "smooth", NS_C));
6183
- const smooth = smoothEl !== null && getAttrValue(smoothEl, ATTR_VAL) !== "0";
6446
+ const smooth = smoothEl !== null && readXmlBool(smoothEl);
6184
6447
  const trendline = readTrendline(ser);
6185
- const serDLblsEl = firstChildElement(ser, qname("c", "dLbls", NS_C));
6186
- let serDataLabels;
6187
- if (serDLblsEl) {
6188
- const readToggle = (local) => {
6189
- const el = firstChildElement(serDLblsEl, qname("c", local, NS_C));
6190
- if (!el) return false;
6191
- const v = getAttrValue(el, ATTR_VAL);
6192
- return v === null || v === "1" || v === "true";
6193
- };
6194
- const nfEl = firstChildElement(serDLblsEl, qname("c", "numFmt", NS_C));
6195
- let numberFormat;
6196
- if (nfEl) {
6197
- const fc = getAttrValue(nfEl, qname("", "formatCode", ""));
6198
- if (fc !== null && fc.length > 0 && fc !== "General") numberFormat = fc;
6199
- }
6200
- const position = readDataLabelPosition(serDLblsEl);
6201
- const separator = readDataLabelSeparator(serDLblsEl);
6202
- const txPrEl = firstChildElement(serDLblsEl, qname("c", "txPr", NS_C));
6203
- const textStyle = txPrEl ? readLabelStyle(txPrEl) : void 0;
6204
- serDataLabels = {
6205
- showValue: readToggle("showVal"),
6206
- showCategory: readToggle("showCatName"),
6207
- showSeriesName: readToggle("showSerName"),
6208
- showPercent: readToggle("showPercent"),
6209
- ...numberFormat !== void 0 ? { numberFormat } : {},
6210
- ...position !== void 0 ? { position } : {},
6211
- ...separator !== void 0 ? { separator } : {},
6212
- ...textStyle !== void 0 ? { textStyle } : {}
6213
- };
6214
- }
6448
+ const serDLblsEl = firstChildElement(ser, NAME_D_LBLS);
6449
+ const serDataLabels = serDLblsEl !== null && hasDataLabelGroupChild(serDLblsEl) ? readSeriesLevelDataLabels(serDLblsEl) : void 0;
6450
+ const pointDataLabels = serDLblsEl !== null ? readPointDataLabels(serDLblsEl, pointCount, serDataLabels) : void 0;
6215
6451
  series.push({
6216
6452
  name,
6217
6453
  values: values ?? [],
@@ -6221,12 +6457,16 @@ const readChartSpec = (root) => {
6221
6457
  ...bubbleSizes !== null ? { bubbleSizes } : {},
6222
6458
  ...color !== void 0 ? { color } : {},
6223
6459
  ...lineWidthEmu !== void 0 ? { lineWidthEmu } : {},
6460
+ ...lineColor !== void 0 ? { lineColor } : {},
6224
6461
  ...lineDash !== void 0 ? { lineDash } : {},
6225
6462
  ...markerSymbol !== void 0 ? { markerSymbol } : {},
6226
6463
  ...markerSizePt !== void 0 ? { markerSizePt } : {},
6464
+ ...markerColor !== void 0 ? { markerColor } : {},
6465
+ ...markerLineColor !== void 0 ? { markerLineColor } : {},
6227
6466
  ...invertIfNegative !== void 0 ? { invertIfNegative } : {},
6228
6467
  ...pointColors !== void 0 ? { pointColors } : {},
6229
6468
  ...pointExplosions !== void 0 ? { pointExplosions } : {},
6469
+ ...pointDataLabels !== void 0 ? { pointDataLabels } : {},
6230
6470
  ...smoothEl !== null ? { smooth } : {},
6231
6471
  ...trendline !== void 0 ? { trendline } : {},
6232
6472
  ...serDataLabels !== void 0 ? { dataLabels: serDataLabels } : {}
@@ -6235,98 +6475,21 @@ const readChartSpec = (root) => {
6235
6475
  const categories = categoriesFromFirst ?? [];
6236
6476
  const title = readTitle(chart);
6237
6477
  const titleStyle = readTitleStyle(chart);
6238
- const dLbls = firstChildElement(plotted, qname("c", "dLbls", NS_C));
6239
- let dataLabels;
6240
- if (dLbls) {
6241
- const readToggle = (local) => {
6242
- const el = firstChildElement(dLbls, qname("c", local, NS_C));
6243
- if (!el) return false;
6244
- const v = getAttrValue(el, ATTR_VAL);
6245
- return v === null || v === "1" || v === "true";
6246
- };
6247
- const nfEl = firstChildElement(dLbls, qname("c", "numFmt", NS_C));
6248
- let numberFormat;
6249
- if (nfEl) {
6250
- const fc = getAttrValue(nfEl, qname("", "formatCode", ""));
6251
- if (fc !== null && fc.length > 0 && fc !== "General") numberFormat = fc;
6252
- }
6253
- const position = readDataLabelPosition(dLbls);
6254
- const separator = readDataLabelSeparator(dLbls);
6255
- const txPrEl = firstChildElement(dLbls, qname("c", "txPr", NS_C));
6256
- const textStyle = txPrEl ? readLabelStyle(txPrEl) : void 0;
6257
- dataLabels = {
6258
- showValue: readToggle("showVal"),
6259
- showCategory: readToggle("showCatName"),
6260
- showSeriesName: readToggle("showSerName"),
6261
- showPercent: readToggle("showPercent"),
6262
- ...numberFormat !== void 0 ? { numberFormat } : {},
6263
- ...position !== void 0 ? { position } : {},
6264
- ...separator !== void 0 ? { separator } : {},
6265
- ...textStyle !== void 0 ? { textStyle } : {}
6266
- };
6267
- }
6268
- let valueAxis;
6269
- const valAx = findFirst(plotArea, ["valAx"]);
6270
- if (valAx) {
6271
- let min;
6272
- let max;
6273
- let majorUnit;
6274
- let minorUnit;
6275
- let logBase;
6276
- let displayUnits;
6277
- const scaling = firstChildElement(valAx, qname("c", "scaling", NS_C));
6278
- const readNumOn = (parent, local) => {
6279
- const el = firstChildElement(parent, qname("c", local, NS_C));
6280
- if (!el) return void 0;
6281
- const v = getAttrValue(el, ATTR_VAL);
6282
- if (v === null) return void 0;
6283
- const n = Number.parseFloat(v);
6284
- return Number.isFinite(n) ? n : void 0;
6285
- };
6286
- if (scaling) {
6287
- min = readNumOn(scaling, "min");
6288
- max = readNumOn(scaling, "max");
6289
- const lb = readNumOn(scaling, "logBase");
6290
- if (lb !== void 0 && lb >= 2 && lb <= 1e3) logBase = lb;
6291
- }
6292
- majorUnit = readNumOn(valAx, "majorUnit");
6293
- minorUnit = readNumOn(valAx, "minorUnit");
6294
- const dispUnits = firstChildElement(valAx, qname("c", "dispUnits", NS_C));
6295
- if (dispUnits) {
6296
- const builtIn = firstChildElement(dispUnits, qname("c", "builtInUnit", NS_C));
6297
- if (builtIn) {
6298
- const v = getAttrValue(builtIn, ATTR_VAL);
6299
- switch (v) {
6300
- case "hundreds":
6301
- case "thousands":
6302
- case "tenThousands":
6303
- case "hundredThousands":
6304
- case "millions":
6305
- case "tenMillions":
6306
- case "hundredMillions":
6307
- case "billions":
6308
- case "trillions":
6309
- displayUnits = v;
6310
- break;
6311
- }
6312
- }
6313
- }
6314
- let numberFormat;
6315
- const nfEl = firstChildElement(valAx, qname("c", "numFmt", NS_C));
6316
- if (nfEl) {
6317
- const fc = getAttrValue(nfEl, qname("", "formatCode", ""));
6318
- if (fc !== null && fc.length > 0 && fc !== "General") numberFormat = fc;
6319
- }
6320
- if (min !== void 0 || max !== void 0 || majorUnit !== void 0 || minorUnit !== void 0 || numberFormat !== void 0 || logBase !== void 0 || displayUnits !== void 0) valueAxis = {
6321
- ...min !== void 0 ? { min } : {},
6322
- ...max !== void 0 ? { max } : {},
6323
- ...majorUnit !== void 0 ? { majorUnit } : {},
6324
- ...minorUnit !== void 0 ? { minorUnit } : {},
6325
- ...numberFormat !== void 0 ? { numberFormat } : {},
6326
- ...logBase !== void 0 ? { logBase } : {},
6327
- ...displayUnits !== void 0 ? { displayUnits } : {}
6328
- };
6329
- }
6478
+ const dLbls = firstChildElement(plotted, NAME_D_LBLS);
6479
+ const dataLabels = dLbls !== null ? readSeriesLevelDataLabels(dLbls) : void 0;
6480
+ let valAx = null;
6481
+ let secValAx = null;
6482
+ for (const el of allChildElements(plotArea, NAME_VAL_AX)) {
6483
+ const axIdEl = firstChildElement(el, qname("c", "axId", NS_C));
6484
+ const id = axIdEl !== null ? getAttrValue(axIdEl, ATTR_VAL) : null;
6485
+ if (id !== null && secondaryValAxisIds.has(id)) secValAx ??= el;
6486
+ else valAx ??= el;
6487
+ }
6488
+ if (valAx === null) {
6489
+ valAx = secValAx;
6490
+ secValAx = null;
6491
+ }
6492
+ const valueAxis = valAx !== null ? readValueAxisScaling(valAx) : void 0;
6330
6493
  let grouping;
6331
6494
  if (kind === "column" || kind === "bar" || kind === "area" || kind === "line") {
6332
6495
  const groupingEl = firstChildElement(plotted, qname("c", "grouping", NS_C));
@@ -6405,6 +6568,12 @@ const readChartSpec = (root) => {
6405
6568
  let categoryAxisMajorGridlineColor;
6406
6569
  let categoryAxisMinorGridlineColor;
6407
6570
  let valueAxisMinorGridlineColor;
6571
+ let categoryAxisLineWidthEmu;
6572
+ let valueAxisLineWidthEmu;
6573
+ let categoryAxisMajorGridlineWidthEmu;
6574
+ let categoryAxisMinorGridlineWidthEmu;
6575
+ let valueAxisMajorGridlineWidthEmu;
6576
+ let valueAxisMinorGridlineWidthEmu;
6408
6577
  const readGridlineColor = (gl) => {
6409
6578
  const spPr = firstChildElement(gl, NAME_SP_PR_C);
6410
6579
  if (!spPr) return void 0;
@@ -6417,6 +6586,13 @@ const readChartSpec = (root) => {
6417
6586
  const v = getAttrValue(srgb, ATTR_VAL);
6418
6587
  return v !== null ? `#${v.toUpperCase()}` : void 0;
6419
6588
  };
6589
+ const readLineWidthEmu = (host) => {
6590
+ const spPr = firstChildElement(host, NAME_SP_PR_C);
6591
+ const ln = spPr !== null ? firstChildElement(spPr, qname("a", "ln", NS_A)) : null;
6592
+ const w = ln !== null ? getAttrValue(ln, qname("", "w", "")) : null;
6593
+ if (w === null || !/^\d+$/.test(w)) return void 0;
6594
+ return Number.parseInt(w, 10);
6595
+ };
6420
6596
  const readAxisLineColor = (axis) => {
6421
6597
  const spPr = firstChildElement(axis, NAME_SP_PR_C);
6422
6598
  if (!spPr) return void 0;
@@ -6444,6 +6620,7 @@ const readChartSpec = (root) => {
6444
6620
  let valueAxisOrientation;
6445
6621
  let valueAxisCrosses;
6446
6622
  let valueAxisCrossBetween;
6623
+ let valueAxisTickLabelPos;
6447
6624
  const readAxisOrientation = (axis) => {
6448
6625
  const scaling = firstChildElement(axis, qname("c", "scaling", NS_C));
6449
6626
  if (!scaling) return void 0;
@@ -6474,12 +6651,19 @@ const readChartSpec = (root) => {
6474
6651
  }
6475
6652
  categoryAxisHidden = isHidden(catAx);
6476
6653
  categoryAxisLineColor = readAxisLineColor(catAx);
6654
+ categoryAxisLineWidthEmu = readLineWidthEmu(catAx);
6477
6655
  const catMajorGl = firstChildElement(catAx, qname("c", "majorGridlines", NS_C));
6478
6656
  categoryAxisMajorGridlines = catMajorGl !== null;
6479
- if (catMajorGl) categoryAxisMajorGridlineColor = readGridlineColor(catMajorGl);
6657
+ if (catMajorGl) {
6658
+ categoryAxisMajorGridlineColor = readGridlineColor(catMajorGl);
6659
+ categoryAxisMajorGridlineWidthEmu = readLineWidthEmu(catMajorGl);
6660
+ }
6480
6661
  const catMinorGl = firstChildElement(catAx, qname("c", "minorGridlines", NS_C));
6481
6662
  categoryAxisMinorGridlines = catMinorGl !== null;
6482
- if (catMinorGl) categoryAxisMinorGridlineColor = readGridlineColor(catMinorGl);
6663
+ if (catMinorGl) {
6664
+ categoryAxisMinorGridlineColor = readGridlineColor(catMinorGl);
6665
+ categoryAxisMinorGridlineWidthEmu = readLineWidthEmu(catMinorGl);
6666
+ }
6483
6667
  categoryAxisOrientation = readAxisOrientation(catAx);
6484
6668
  categoryAxisMajorTickMark = readTickMark(catAx);
6485
6669
  categoryAxisMinorTickMark = readTickMarkLocal(catAx, "minorTickMark");
@@ -6553,9 +6737,15 @@ const readChartSpec = (root) => {
6553
6737
  }
6554
6738
  valueAxisHidden = isHidden(valAx);
6555
6739
  valueAxisLineColor = readAxisLineColor(valAx);
6740
+ valueAxisLineWidthEmu = readLineWidthEmu(valAx);
6556
6741
  valueAxisOrientation = readAxisOrientation(valAx);
6557
6742
  valueAxisMajorTickMark = readTickMark(valAx);
6558
6743
  valueAxisMinorTickMark = readTickMarkLocal(valAx, "minorTickMark");
6744
+ const valPosEl = firstChildElement(valAx, qname("c", "tickLblPos", NS_C));
6745
+ if (valPosEl) {
6746
+ const v = getAttrValue(valPosEl, ATTR_VAL);
6747
+ if (v === "none" || v === "low" || v === "high" || v === "nextTo") valueAxisTickLabelPos = v;
6748
+ }
6559
6749
  const crossesAtEl = firstChildElement(valAx, qname("c", "crossesAt", NS_C));
6560
6750
  if (crossesAtEl) {
6561
6751
  const v = getAttrValue(crossesAtEl, ATTR_VAL);
@@ -6577,10 +6767,54 @@ const readChartSpec = (root) => {
6577
6767
  }
6578
6768
  const majorGl = firstChildElement(valAx, qname("c", "majorGridlines", NS_C));
6579
6769
  valueAxisMajorGridlines = majorGl !== null;
6580
- if (majorGl) valueAxisMajorGridlineColor = readGridlineColor(majorGl);
6770
+ if (majorGl) {
6771
+ valueAxisMajorGridlineColor = readGridlineColor(majorGl);
6772
+ valueAxisMajorGridlineWidthEmu = readLineWidthEmu(majorGl);
6773
+ }
6581
6774
  const minorGl = firstChildElement(valAx, qname("c", "minorGridlines", NS_C));
6582
6775
  valueAxisMinorGridlines = minorGl !== null;
6583
- if (minorGl) valueAxisMinorGridlineColor = readGridlineColor(minorGl);
6776
+ if (minorGl) {
6777
+ valueAxisMinorGridlineColor = readGridlineColor(minorGl);
6778
+ valueAxisMinorGridlineWidthEmu = readLineWidthEmu(minorGl);
6779
+ }
6780
+ }
6781
+ let secondaryValueAxis;
6782
+ if (secValAx !== null) {
6783
+ const scaling = readValueAxisScaling(secValAx);
6784
+ const title = readTitle(secValAx);
6785
+ const titleEl = firstChildElement(secValAx, NAME_TITLE);
6786
+ const titleStyle = titleEl !== null ? readTitleStyleOf(titleEl) : void 0;
6787
+ const txPr = firstChildElement(secValAx, qname("c", "txPr", NS_C));
6788
+ const labelStyle = txPr !== null ? readLabelStyle(txPr) : void 0;
6789
+ const majorGl = firstChildElement(secValAx, qname("c", "majorGridlines", NS_C));
6790
+ const majorGridlineColor = majorGl !== null ? readGridlineColor(majorGl) : void 0;
6791
+ const majorGridlineWidthEmu = majorGl !== null ? readLineWidthEmu(majorGl) : void 0;
6792
+ const lineColor = readAxisLineColor(secValAx);
6793
+ const lineWidthEmu = readLineWidthEmu(secValAx);
6794
+ const majorTickMark = readTickMark(secValAx);
6795
+ const minorTickMark = readTickMarkLocal(secValAx, "minorTickMark");
6796
+ const secPosEl = firstChildElement(secValAx, qname("c", "tickLblPos", NS_C));
6797
+ const secPos = secPosEl !== null ? getAttrValue(secPosEl, ATTR_VAL) : null;
6798
+ const tickLabelPos = secPos === "none" || secPos === "low" || secPos === "high" || secPos === "nextTo" ? secPos : void 0;
6799
+ const crossBetweenEl = firstChildElement(secValAx, qname("c", "crossBetween", NS_C));
6800
+ const cb = crossBetweenEl !== null ? getAttrValue(crossBetweenEl, ATTR_VAL) : null;
6801
+ const crossBetween = cb === "between" || cb === "midCat" ? cb : void 0;
6802
+ const fields = {
6803
+ ...scaling !== void 0 ? { scaling } : {},
6804
+ ...title !== void 0 ? { title } : {},
6805
+ ...titleStyle !== void 0 ? { titleStyle } : {},
6806
+ ...labelStyle !== void 0 ? { labelStyle } : {},
6807
+ ...majorGl !== null ? { majorGridlines: true } : {},
6808
+ ...majorGridlineColor !== void 0 ? { majorGridlineColor } : {},
6809
+ ...majorGridlineWidthEmu !== void 0 ? { majorGridlineWidthEmu } : {},
6810
+ ...lineColor !== void 0 ? { lineColor } : {},
6811
+ ...lineWidthEmu !== void 0 ? { lineWidthEmu } : {},
6812
+ ...majorTickMark !== void 0 ? { majorTickMark } : {},
6813
+ ...minorTickMark !== void 0 ? { minorTickMark } : {},
6814
+ ...tickLabelPos !== void 0 ? { tickLabelPos } : {},
6815
+ ...crossBetween !== void 0 ? { crossBetween } : {}
6816
+ };
6817
+ if (Object.keys(fields).length > 0) secondaryValueAxis = fields;
6584
6818
  }
6585
6819
  const readSpPrFill = (parent) => {
6586
6820
  const spPr = firstChildElement(parent, NAME_SP_PR_C);
@@ -6750,6 +6984,7 @@ const readChartSpec = (root) => {
6750
6984
  ...titleStyle !== void 0 ? { titleStyle } : {},
6751
6985
  ...dataLabels !== void 0 ? { dataLabels } : {},
6752
6986
  ...valueAxis !== void 0 ? { valueAxis } : {},
6987
+ ...secondaryValueAxis !== void 0 ? { secondaryValueAxis } : {},
6753
6988
  ...grouping !== void 0 ? { grouping } : {},
6754
6989
  ...dropLines !== void 0 ? { dropLines } : {},
6755
6990
  ...hiLowLines !== void 0 ? { hiLowLines } : {},
@@ -6782,8 +7017,10 @@ const readChartSpec = (root) => {
6782
7017
  ...valueAxisHidden !== void 0 ? { valueAxisHidden } : {},
6783
7018
  ...valueAxisMajorGridlines !== void 0 ? { valueAxisMajorGridlines } : {},
6784
7019
  ...valueAxisMajorGridlineColor !== void 0 ? { valueAxisMajorGridlineColor } : {},
7020
+ ...valueAxisMajorGridlineWidthEmu !== void 0 ? { valueAxisMajorGridlineWidthEmu } : {},
6785
7021
  ...valueAxisMajorTickMark !== void 0 ? { valueAxisMajorTickMark } : {},
6786
7022
  ...valueAxisMinorTickMark !== void 0 ? { valueAxisMinorTickMark } : {},
7023
+ ...valueAxisTickLabelPos !== void 0 ? { valueAxisTickLabelPos } : {},
6787
7024
  ...valueAxisLabelRotationDeg !== void 0 ? { valueAxisLabelRotationDeg } : {},
6788
7025
  ...categoryAxisMajorTickMark !== void 0 ? { categoryAxisMajorTickMark } : {},
6789
7026
  ...categoryAxisMinorTickMark !== void 0 ? { categoryAxisMinorTickMark } : {},
@@ -6802,6 +7039,11 @@ const readChartSpec = (root) => {
6802
7039
  ...categoryAxisMajorGridlineColor !== void 0 ? { categoryAxisMajorGridlineColor } : {},
6803
7040
  ...categoryAxisMinorGridlineColor !== void 0 ? { categoryAxisMinorGridlineColor } : {},
6804
7041
  ...valueAxisMinorGridlineColor !== void 0 ? { valueAxisMinorGridlineColor } : {},
7042
+ ...categoryAxisLineWidthEmu !== void 0 ? { categoryAxisLineWidthEmu } : {},
7043
+ ...valueAxisLineWidthEmu !== void 0 ? { valueAxisLineWidthEmu } : {},
7044
+ ...categoryAxisMajorGridlineWidthEmu !== void 0 ? { categoryAxisMajorGridlineWidthEmu } : {},
7045
+ ...categoryAxisMinorGridlineWidthEmu !== void 0 ? { categoryAxisMinorGridlineWidthEmu } : {},
7046
+ ...valueAxisMinorGridlineWidthEmu !== void 0 ? { valueAxisMinorGridlineWidthEmu } : {},
6805
7047
  ...categoryAxisOrientation !== void 0 ? { categoryAxisOrientation } : {},
6806
7048
  ...valueAxisOrientation !== void 0 ? { valueAxisOrientation } : {},
6807
7049
  ...valueAxisCrosses !== void 0 ? { valueAxisCrosses } : {},
@@ -7858,14 +8100,22 @@ const validateChartSpecColors = (spec) => {
7858
8100
  checkChartColor(spec.categoryAxisMinorGridlineColor, "addSlideChart: categoryAxisMinorGridlineColor");
7859
8101
  checkChartColor(spec.valueAxisLineColor, "addSlideChart: valueAxisLineColor");
7860
8102
  checkChartColor(spec.categoryAxisLineColor, "addSlideChart: categoryAxisLineColor");
8103
+ checkChartColor(spec.secondaryValueAxis?.majorGridlineColor, "addSlideChart: secondaryValueAxis.majorGridlineColor");
8104
+ checkChartColor(spec.secondaryValueAxis?.lineColor, "addSlideChart: secondaryValueAxis.lineColor");
7861
8105
  spec.series.forEach((series, i) => {
7862
8106
  checkChartColor(series.color, `addSlideChart: series[${i}].color`);
8107
+ checkChartColor(series.lineColor, `addSlideChart: series[${i}].lineColor`);
8108
+ checkChartColor(series.markerColor, `addSlideChart: series[${i}].markerColor`);
8109
+ checkChartColor(series.markerLineColor, `addSlideChart: series[${i}].markerLineColor`);
7863
8110
  checkChartColor(series.trendline?.color, `addSlideChart: series[${i}].trendline.color`);
7864
8111
  series.pointColors?.forEach((c, j) => {
7865
8112
  checkChartColor(c, `addSlideChart: series[${i}].pointColors[${j}]`);
7866
8113
  });
7867
8114
  });
7868
8115
  };
8116
+ const validateChartSpecAxes = (spec) => {
8117
+ if (spec.series.length > 0 && spec.series.every((series) => series.secondaryAxis === true)) throw new Error("chart: at least one series must plot on the primary axis");
8118
+ };
7869
8119
  /**
7870
8120
  * Adds a chart to the slide. Returns the new shape handle (kind
7871
8121
  * `graphicFrame`). Supported chart kinds today: `bar`, `column`,
@@ -7893,10 +8143,17 @@ const withChartDefaultTextColor = (spec, color) => {
7893
8143
  ...style,
7894
8144
  color
7895
8145
  } : style;
8146
+ const hasSecondary = spec.series.some((series) => series.secondaryAxis === true);
8147
+ const secondary = spec.secondaryValueAxis ?? {};
7896
8148
  return {
7897
8149
  ...spec,
7898
8150
  categoryAxisLabelStyle: withColor(spec.categoryAxisLabelStyle),
7899
8151
  valueAxisLabelStyle: withColor(spec.valueAxisLabelStyle),
8152
+ ...hasSecondary ? { secondaryValueAxis: {
8153
+ ...secondary,
8154
+ labelStyle: withColor(secondary.labelStyle),
8155
+ ...secondary.title !== void 0 ? { titleStyle: withColor(secondary.titleStyle) } : {}
8156
+ } } : {},
7900
8157
  ...spec.title !== void 0 ? { titleStyle: withColor(spec.titleStyle) } : {},
7901
8158
  ...spec.legend !== void 0 ? { legend: {
7902
8159
  ...spec.legend,
@@ -7910,6 +8167,7 @@ const withChartDefaultTextColor = (spec, color) => {
7910
8167
  };
7911
8168
  const addSlideChart = (slide, opts) => {
7912
8169
  validateChartSpecColors(opts.spec);
8170
+ validateChartSpecAxes(opts.spec);
7913
8171
  const spec = withChartDefaultTextColor(opts.spec, resolveDeckBodyTextColor(slide));
7914
8172
  const pkg = slide[INTERNAL_PACKAGE];
7915
8173
  const chartN = allocateChartIndex(pkg);
@@ -7994,11 +8252,12 @@ const resolveChartPartName = (slide, shape) => {
7994
8252
  */
7995
8253
  const setChartSpec = (chart, spec) => {
7996
8254
  validateChartSpecColors(spec);
8255
+ validateChartSpecAxes(spec);
7997
8256
  const slide = chart.shape[SHAPE_SLIDE];
7998
8257
  const pkg = slide[INTERNAL_PACKAGE];
7999
8258
  const resolved = resolveChartPartName(slide, chart.shape);
8000
8259
  if (!resolved) throw new Error("setChartSpec: shape is not a chart graphic frame");
8001
- const chartBytes = encode$1(serializeXml(buildChartSpaceDoc(spec)));
8260
+ const chartBytes = encode$1(serializeXml(buildChartSpaceDoc(withChartDefaultTextColor(spec, resolveDeckBodyTextColor(slide)))));
8002
8261
  const chartPart = pkg.getPart(resolved.partName);
8003
8262
  if (!chartPart) throw new Error(`setChartSpec: chart part ${resolved.partName} not found`);
8004
8263
  chartPart.data = chartBytes;
@@ -9514,6 +9773,15 @@ const setTableCellText = (cell, text) => {
9514
9773
  commitTableCell(cell);
9515
9774
  };
9516
9775
  /**
9776
+ * Replaces the cell's text with explicitly structured paragraphs and runs —
9777
+ * the table counterpart of `setShapeParagraphs`. Read back with
9778
+ * `getTableCellParagraphs`.
9779
+ */
9780
+ const setTableCellParagraphs = (cell, paragraphs) => {
9781
+ setTextBodyParagraphs(ensureCellTxBody(cell), paragraphs);
9782
+ commitTableCell(cell);
9783
+ };
9784
+ /**
9517
9785
  * Reads the cell's merge / span attributes:
9518
9786
  *
9519
9787
  * - `gridSpan` — number of columns this cell spans (≥1, default 1).
@@ -15415,6 +15683,17 @@ const setShapeTextFormat = (shape, format) => {
15415
15683
  applyFormatToAllRuns(requireTxBody(shape), format);
15416
15684
  commitAndRefresh(shape);
15417
15685
  };
15686
+ /**
15687
+ * Replaces the shape's text with explicitly structured paragraphs, each
15688
+ * carrying its own runs and per-run formats. `setShapeText` yields one run
15689
+ * per paragraph; use this when a paragraph mixes formats (a bold lead-in
15690
+ * followed by plain text, for example). Read back with
15691
+ * `getShapeParagraphElements`.
15692
+ */
15693
+ const setShapeParagraphs = (shape, paragraphs) => {
15694
+ setTextBodyParagraphs(requireTxBody(shape), paragraphs);
15695
+ commitAndRefresh(shape);
15696
+ };
15418
15697
  //#endregion
15419
15698
  //#region src/api/fn/shape-removal-zorder.ts
15420
15699
  /**
@@ -17000,8 +17279,8 @@ const ungroupShapes = (group) => {
17000
17279
  };
17001
17280
  //#endregion
17002
17281
  //#region src/api/index.ts
17003
- const VERSION = "0.13.0";
17282
+ const VERSION = "0.14.0";
17004
17283
  //#endregion
17005
- export { slideHasAnimations as $, getTableCellPosition as $a, findSlidesWithChartKind as $i, getSlideMasterCount as $n, getShapeHyperlink as $o, getShapeRunHyperlinkTooltip as $r, getCommentPosition as $s, getShapeStrokeCompound as $t, getPresentationTextLength as A, setSlideTransition as Aa, getShapeImageDuotone as Ai, findShapesInRect as An, removeThumbnail as Ao, setShapeStroke as Ar, getSlideLayoutShapes as As, setShapeTextColumns as At, getSlideText as B, setMediaPartBytes as Ba, setShapeImageContrast as Bi, getShapeCustomGeometry as Bn, findLayoutsWithPlaceholderType as Bo, getParagraphBullet as Br, setShapeImage as Bs, setShapeGlow as Bt, findSlideByTitle as C, getVisibleSlides as Ca, findSlidesByLayoutType as Ci, getSlideShapes as Cn, setTableCellTextDirection as Co, setShapeImageFill as Cr, getSlideBackgroundPatternFill as Cs, getShapeTextWrap as Ct, getOutlineText as D, setSlideNotes as Da, getShapeImageBytes as Di, translateShapes as Dn, setTableStyleFlags as Do, setShapePosition as Dr, getSlideLayoutBackgroundImageBytes as Ds, setShapeTextAnchor as Dt, getAllShapes as E, replaceHyperlink as Ea, getShapeImageBrightness as Ei, setSlideLayout as En, setTableRowHeight as Eo, setShapePatternFill as Er, getSlideLayoutBackgroundGradientFill as Es, setShapeText as Et, getSlideIndex as F, getPackageSize as Fa, getShapeImagePartName as Fi, getShapeAdjustValues as Fn, getPresentationModified as Fo, setShapeStrokeJoin as Fr, getSlideMasterShapes as Fs, clearShapeEffects as Ft, isSlideHidden as G, getSlideTables as Ga, SLIDE_SIZE_4_3 as Gi, getShapeName as Gn, getSlideLayoutPartName as Go, getParagraphLineSpacing as Gr, findCommentsAfter as Gs, getShapeFillColor as Gt, getSlideXmlString as H, validatePresentation as Ha, setShapeImageOpacity as Hi, getShapeFlip as Hn, findSlideLayoutByPartName as Ho, getParagraphBulletStyle as Hr, clearAllSlideComments as Hs, getShapeGradientFill as Ht, getSlideInfo as I, getPresentationSummary as Ia, hasShapeImage as Ii, getShapeAltTitle as In, incrementRevision as Io, getShapeRunFormat as Ir, setSlideBackground as Is, findShapesByEffect as It, replaceTextInSlide as J, getTableCellAnchor as Ja, appendSlideNotes as Ji, getShapePosition as Jn, getSlideLayoutUsageCounts as Jo, getShapeParagraphCount as Jr, findCommentsByText as Js, getShapeFillOpacity as Jt, replaceTextInNotes as K, getTableCell as Ka, getSlideSize as Ki, getShapePlaceholderIdx as Kn, getSlideLayoutPlaceholders as Ko, getParagraphSpacing as Kr, findCommentsBefore as Ks, getShapeFillColorResolved as Kt, getSlideLayoutCount as L, getSlideMediaPartNames as La, hasShapeText as Li, getShapeBounds as Ln, setCoreProperties as Lo, resolveDrawingColor as Lr, setSlideBackgroundImage as Ls, getShapeEffect as Lt, getShapeAt as M, compactPackage as Ma, getShapeImageFormat as Mi, getGroupTransform as Mn, getCoreProperties as Mo, setShapeStrokeCap as Mr, getSlideMasterBackgroundGradientFill as Ms, setShapeTextFormat as Mt, getSlideAt as N, getMediaParts as Na, getShapeImageLinkUrl as Ni, getMaxShapeId as Nn, getExtendedProperties as No, setShapeStrokeCompound as Nr, getSlideMasterBackgroundImageBytes as Ns, setShapeTextMargins as Nt, getPresentationShapeCountsBySlide as O, clearSlideTransition as Oa, getShapeImageContrast as Oi, centerShapeOnSlide as On, setTableStyleId as Oo, setShapeRotation as Or, getSlideLayoutBackgroundPatternFill as Os, setShapeTextAutoFit as Ot, getSlideCount as P, getOrphanMediaPartNames as Pa, getShapeImageOpacity as Pi, getMaxShapeIdInPresentation as Pn, getPresentationCreated as Po, setShapeStrokeDash as Pr, getSlideMasterBackgroundPatternFill as Ps, setShapeTextWrap as Pt, setSlideHidden as Q, getTableCellParagraphs as Qa, findSlidesByHyperlink as Qi, getShapeText as Qn, getParagraphPropertiesEffective as Qo, getShapeRunHyperlink as Qr, getCommentDate as Qs, getShapeStrokeColorResolved as Qt, getSlideOutline as R, listPackageParts as Ra, isShapeImageGrayscale as Ri, getShapeBoundsResolved as Rn, setExtendedProperties as Ro, resolveDrawingColorOpacity as Rr, getShapeClickAction as Rs, getShapeEffects as Rt, findSlideByText as S, getSlidesWithTables as Sa, findSlidesByLayoutPartName as Si, getSlideLayout as Sn, setTableCellText as So, setShapeGradientFill as Sr, getSlideBackgroundImageBytes as Ss, getShapeTextMargins as St, findSlidesByText as T, removeSlideNotes as Ta, getShapeImageBiLevelThreshold as Ti, replaceTokensInSlide as Tn, setTableColumnWidth as To, setShapeNoStroke as Tr, getSlideLayoutBackground as Ts, setShapeBullets as Tt, getSlides as U, clearTableCellFill as Ua, SLIDE_SIZE_16_10 as Ui, getShapeId as Un, findSlideLayoutByType as Uo, getParagraphIndent as Ur, clearSlideComments as Us, getShapeGradientFillEffective as Ut, getSlideTextLength as V, slidesUsingMediaPart as Va, setShapeImageCrop as Vi, getShapeDescription as Vn, findSlideLayout as Vo, getParagraphBulletImageBytes as Vr, addSlideComment as Vs, setShapeShadow as Vt, getSlidesByLayout as W, getPresentationTableCountsBySlide as Wa, SLIDE_SIZE_16_9 as Wi, getShapeKind as Wn, getSlideLayoutName as Wo, getParagraphLevel as Wr, findCommentAuthorByName as Ws, getShapeFill as Wt, replaceTokensInPresentation as X, getTableCellFill as Xa, clearAllSlideNotes as Xi, getShapeRotation as Xn, getSlideLayouts as Xo, getShapeRunClickAction as Xr, getCommentAuthor as Xs, getShapeStrokeCap as Xt, replaceTextInSlideNotes as Y, getTableCellBorders as Ya, clearAllHyperlinks as Yi, getShapePreset as Yn, getSlideLayoutUsageCountsByType as Yo, getShapeParagraphElements as Yr, findSlidesWithCommentsByAuthor as Ys, getShapeStroke as Yt, searchSlides as Z, getTableCellMargins as Za, clearSlideHyperlinks as Zi, getShapeSize as Zn, getUnusedSlideLayouts as Zo, getShapeRunCount as Zr, getCommentAuthors as Zs, getShapeStrokeColor as Zt, sortSlides as _, getSlidesWithComments as _a, emu as _c, setShapeAnimation as _i, findSlidePlaceholders as _n, setTableCellAlignment as _o, getShapeStrokeArrow as _r, getEffectiveColorMap as _s, getShapeTextAutoFit as _t, addContentSlide as a, getAllNotes as aa, getPresentationCommenters as ac, setParagraphLineSpacing as ai, findShapeById as an, getTableDimensions as ao, isShapePlaceholder as ar, findChartsBySeriesName as as, bringShapeForward as at, setSlideSections as b, getSlidesWithNotes as ba, pt as bc, findShapesOutsideCanvas as bi, getShapeXmlString as bn, setTableCellFill as bo, setShapeFill as br, getSlideBackground as bs, getShapeTextColumns as bt, addSlideAt as c, getEmptySlides as ca, removeSlideComment as cc, setShapeRunText as ci, findShapeInPresentation as cn, getTableStyleFlags as co, renameShape as cr, getPresentationChartCountsBySlide as cs, copyShape as ct, duplicateSlideAt as d, getPresentationNotesLength as da, setPresentationFonts as dc, setSlideBody as di, findShapesByName as dn, insertTableRow as do, setShapeDescription as dr, getShapeChartKind as ds, sendShapeBackward as dt, findSlidesWithChartTrendlines as ea, getCommentSlide as ec, getShapeRunText as ei, getShapeStrokeEffective as en, getTableCellSpan as eo, getSlideMasterPartName as er, getShapeRunFormatEffective as es, addSlideImage as et, importSlide as f, getPresentationNotesLengthsBySlide as fa, setPresentationTheme as fc, setSlidePlaceholders as fi, findShapesByPreset as fn, isChartShape as fo, setShapeHidden as fr, getShapeChartSeriesNames as fs, sendShapeToBack as ft, reverseSlides as g, getSlidesWithCharts as ga, cm as gc, getShapeAnimation as gi, findSlidePlaceholderByIdx as gn, removeTableRow as go, getShapePatternFill as gr, setChartSpec as gs, getShapeTextAnchor as gt, removeSlide as h, getSlideNotesLength as ha, savePresentation as hc, findShapesWithAnimation as hi, findSlidePlaceholder as hn, removeTableColumn as ho, clearShapeStroke as hr, getSlideCharts as hs, getShapeBodyPrEffective as ht, addBlankSlide as i, getAllImages as ia, getPresentationCommentCountsBySlide as ic, setParagraphLevel as ii, findEmptyPlaceholders as in, getTableColumnWidths as io, isShapeHidden as ir, findChartByKind as is, addSlideTextBox as it, getPresentationTextLengthsBySlide as j, _internalPackageOf as ja, getShapeImageFillBytes as ji, getGroupChildren as jn, setThumbnail as jo, setShapeStrokeArrow as jr, getSlideMasterBackground as js, setShapeTextDirection as jt, getPresentationText as k, getSlideTransition as ka, getShapeImageCrop as ki, findShapesAtPoint as kn, getThumbnail as ko, setShapeSize as kr, getSlideLayoutBackgroundShapes as ks, setShapeTextBodyRotationDeg as kt, addTitleSlide as l, getHiddenSlides as la, getPresentationFonts as lc, getSlideBody as li, findShapesByHyperlink as ln, getTableStyleId as lo, setShapeAltTitle as lr, getPresentationChartKindCounts as ls, getShapeZIndex as lt, moveSlide as m, getSlideNotes as ma, loadPresentation as mc, clearSlideAnimations as mi, findShapesWithHyperlinks as mn, mergeTableCells as mo, clearShapeFill as mr, getShapeChartSpec as ms, appendShapeText as mt, groupShapes as n, getAllComments as na, getCommentsSortedByDate as nc, setParagraphAlignment as ni, getShapeStrokeOpacity as nn, getTableCellTextDirection as no, getSlideMasterUsageCounts as nr, setShapeRunFormat as ns, addSlideShape as nt, addSectionHeaderSlide as o, getAllTables as oa, getSlideCommentAuthors as oc, setParagraphSpacing as oi, findShapeByName as on, getTableRowHeights as oo, isShapeTextBox as or, findChartsWithDataLabels as os, bringShapeToFront as ot, mergePresentations as p, getPresentationNotesText as pa, createPresentation as pc, setSlideTitle as pi, findShapesByText as pn, isTableShape as po, shapesOverlap as pr, getShapeChartSeriesValues as ps, setShapeZIndex as pt, replaceTextInPresentation as q, getTableCellAlignment as qa, setSlideSize as qi, getShapePlaceholderType as qn, getSlideLayoutType as qo, getShapeHyperlinkTooltip as qr, findCommentsByAuthor as qs, getShapeFillEffective as qt, ungroupShapes as r, getAllHyperlinks as ra, getPresentationCommentCountsByAuthor as rc, setParagraphBullet as ri, getShapeStrokeWidth as rn, getTableCells as ro, getUnusedSlideMasters as rr, addSlideChart as rs, addSlideTable as rt, addSlide as s, getDistinctHyperlinkUrls as sa, getSlideComments as sc, setShapeRunHyperlink as si, findShapeByText as sn, getTableSize as so, pointInShape as sr, findChartsWithTrendlines as ss, clearSlideShapes as st, VERSION as t, getAllCharts as ta, getCommentText as tc, isParagraphBulletPicture as ti, getShapeStrokeJoin as tn, getTableCellText as to, getSlideMasterPartNames as tr, setShapeHyperlink as ts, addSlideLine as tt, duplicateSlide as u, getPresentationHyperlinkCountsBySlide as ua, getPresentationTheme as uc, getSlideTitle as ui, findShapesByKind as un, insertTableColumn as uo, setShapeBounds as ur, getShapeChartCategories as us, removeShape as ut, swapSlides as v, getSlidesWithHyperlinks as va, inches as vc, findFlippedShapes as vi, getShapeIndex as vn, setTableCellAnchor as vo, getShapeStrokeDash as vr, resolveDeckBodyTextColor as vs, getShapeTextAutoFitParams as vt, findSlidesByNotes as w, hasSlideNotes as wa, getPresentationImageCountsBySlide as wi, getSlidesWithEmptyPlaceholders as wn, setTableCellTextFormat as wo, setShapeNoFill as wr, getSlideColorMapOverride as ws, setShapeAlignment as wt, findSlideByPartName as x, getSlidesWithOverlap as xa, findSlidesByLayoutName as xi, getShapesBounds as xn, setTableCellMargins as xo, setShapeFlip as xr, getSlideBackgroundGradientFill as xs, getShapeTextDirection as xt, getSlideSections as y, getSlidesWithImages as ya, mm as yc, findOverlappingShapePairs as yi, getShapeSlide as yn, setTableCellBorders as yo, setShapeAdjustValues as yr, clearSlideBackground as ys, getShapeTextBodyRotationDeg as yt, getSlidePartName as z, readPackagePart as za, setShapeImageBrightness as zi, getShapeCenter as zn, touchModified as zo, getParagraphAlignment as zr, setShapeClickAction as zs, getShapeEffectsEffective as zt };
17284
+ export { slideHasAnimations as $, getTableCellParagraphs as $a, findSlidesByHyperlink as $i, getShapeText as $n, getUnusedSlideLayouts as $o, getShapeRunHyperlink as $r, getCommentAuthors as $s, getShapeStrokeColorResolved as $t, getPresentationTextLength as A, getSlideTransition as Aa, getShapeImageCrop as Ai, findShapesAtPoint as An, setTableStyleId as Ao, setShapeSize as Ar, getSlideLayoutBackgroundPatternFill as As, setShapeTextBodyRotationDeg as At, getSlideText as B, readPackagePart as Ba, setShapeImageBrightness as Bi, getShapeCenter as Bn, setExtendedProperties as Bo, getParagraphAlignment as Br, getShapeClickAction as Bs, getShapeEffectsEffective as Bt, findSlideByTitle as C, getSlidesWithTables as Ca, findSlidesByLayoutPartName as Ci, getSlideLayout as Cn, setTableCellParagraphs as Co, setShapeGradientFill as Cr, getSlideBackgroundGradientFill as Cs, getShapeTextWrap as Ct, getOutlineText as D, replaceHyperlink as Da, getShapeImageBrightness as Di, setSlideLayout as Dn, setTableColumnWidth as Do, setShapePatternFill as Dr, getSlideLayoutBackground as Ds, setShapeText as Dt, getAllShapes as E, removeSlideNotes as Ea, getShapeImageBiLevelThreshold as Ei, replaceTokensInSlide as En, setTableCellTextFormat as Eo, setShapeNoStroke as Er, getSlideColorMapOverride as Es, setShapeParagraphs as Et, getSlideIndex as F, getOrphanMediaPartNames as Fa, getShapeImageOpacity as Fi, getMaxShapeIdInPresentation as Fn, getExtendedProperties as Fo, setShapeStrokeDash as Fr, getSlideMasterBackgroundImageBytes as Fs, setShapeTextWrap as Ft, isSlideHidden as G, getPresentationTableCountsBySlide as Ga, SLIDE_SIZE_16_9 as Gi, getShapeKind as Gn, findSlideLayoutByType as Go, getParagraphLevel as Gr, clearSlideComments as Gs, getShapeFill as Gt, getSlideXmlString as H, slidesUsingMediaPart as Ha, setShapeImageCrop as Hi, getShapeDescription as Hn, findLayoutsWithPlaceholderType as Ho, getParagraphBulletImageBytes as Hr, setShapeImage as Hs, setShapeShadow as Ht, getSlideInfo as I, getPackageSize as Ia, getShapeImagePartName as Ii, getShapeAdjustValues as In, getPresentationCreated as Io, setShapeStrokeJoin as Ir, getSlideMasterBackgroundPatternFill as Is, clearShapeEffects as It, replaceTextInSlide as J, getTableCellAlignment as Ja, setSlideSize as Ji, getShapePlaceholderType as Jn, getSlideLayoutPlaceholders as Jo, getShapeHyperlinkTooltip as Jr, findCommentsBefore as Js, getShapeFillEffective as Jt, replaceTextInNotes as K, getSlideTables as Ka, SLIDE_SIZE_4_3 as Ki, getShapeName as Kn, getSlideLayoutName as Ko, getParagraphLineSpacing as Kr, findCommentAuthorByName as Ks, getShapeFillColor as Kt, getSlideLayoutCount as L, getPresentationSummary as La, hasShapeImage as Li, getShapeAltTitle as Ln, getPresentationModified as Lo, getShapeRunFormat as Lr, getSlideMasterShapes as Ls, findShapesByEffect as Lt, getShapeAt as M, _internalPackageOf as Ma, getShapeImageFillBytes as Mi, getGroupChildren as Mn, removeThumbnail as Mo, setShapeStrokeArrow as Mr, getSlideLayoutShapes as Ms, setShapeTextDirection as Mt, getSlideAt as N, compactPackage as Na, getShapeImageFormat as Ni, getGroupTransform as Nn, setThumbnail as No, setShapeStrokeCap as Nr, getSlideMasterBackground as Ns, setShapeTextFormat as Nt, getPresentationShapeCountsBySlide as O, setSlideNotes as Oa, getShapeImageBytes as Oi, translateShapes as On, setTableRowHeight as Oo, setShapePosition as Or, getSlideLayoutBackgroundGradientFill as Os, setShapeTextAnchor as Ot, getSlideCount as P, getMediaParts as Pa, getShapeImageLinkUrl as Pi, getMaxShapeId as Pn, getCoreProperties as Po, setShapeStrokeCompound as Pr, getSlideMasterBackgroundGradientFill as Ps, setShapeTextMargins as Pt, setSlideHidden as Q, getTableCellMargins as Qa, clearSlideHyperlinks as Qi, getShapeSize as Qn, getSlideLayouts as Qo, getShapeRunCount as Qr, getCommentAuthor as Qs, getShapeStrokeColor as Qt, getSlideOutline as R, getSlideMediaPartNames as Ra, hasShapeText as Ri, getShapeBounds as Rn, incrementRevision as Ro, resolveDrawingColor as Rr, setSlideBackground as Rs, getShapeEffect as Rt, findSlideByText as S, getSlidesWithOverlap as Sa, pt as Sc, findSlidesByLayoutName as Si, getShapesBounds as Sn, setTableCellMargins as So, setShapeFlip as Sr, getSlideBackground as Ss, getShapeTextMargins as St, findSlidesByText as T, hasSlideNotes as Ta, getPresentationImageCountsBySlide as Ti, getSlidesWithEmptyPlaceholders as Tn, setTableCellTextDirection as To, setShapeNoFill as Tr, getSlideBackgroundPatternFill as Ts, setShapeBullets as Tt, getSlides as U, validatePresentation as Ua, setShapeImageOpacity as Ui, getShapeFlip as Un, findSlideLayout as Uo, getParagraphBulletStyle as Ur, addSlideComment as Us, getShapeGradientFill as Ut, getSlideTextLength as V, setMediaPartBytes as Va, setShapeImageContrast as Vi, getShapeCustomGeometry as Vn, touchModified as Vo, getParagraphBullet as Vr, setShapeClickAction as Vs, setShapeGlow as Vt, getSlidesByLayout as W, clearTableCellFill as Wa, SLIDE_SIZE_16_10 as Wi, getShapeId as Wn, findSlideLayoutByPartName as Wo, getParagraphIndent as Wr, clearAllSlideComments as Ws, getShapeGradientFillEffective as Wt, replaceTokensInPresentation as X, getTableCellBorders as Xa, clearAllHyperlinks as Xi, getShapePreset as Xn, getSlideLayoutUsageCounts as Xo, getShapeParagraphElements as Xr, findCommentsByText as Xs, getShapeStroke as Xt, replaceTextInSlideNotes as Y, getTableCellAnchor as Ya, appendSlideNotes as Yi, getShapePosition as Yn, getSlideLayoutType as Yo, getShapeParagraphCount as Yr, findCommentsByAuthor as Ys, getShapeFillOpacity as Yt, searchSlides as Z, getTableCellFill as Za, clearAllSlideNotes as Zi, getShapeRotation as Zn, getSlideLayoutUsageCountsByType as Zo, getShapeRunClickAction as Zr, findSlidesWithCommentsByAuthor as Zs, getShapeStrokeCap as Zt, sortSlides as _, getSlidesWithCharts as _a, savePresentation as _c, getShapeAnimation as _i, findSlidePlaceholderByIdx as _n, removeTableRow as _o, getShapePatternFill as _r, getSlideCharts as _s, getShapeTextAutoFit as _t, addContentSlide as a, getAllImages as aa, getPresentationCommentCountsByAuthor as ac, setParagraphLevel as ai, findEmptyPlaceholders as an, getTableColumnWidths as ao, isShapeHidden as ar, addSlideChart as as, bringShapeForward as at, setSlideSections as b, getSlidesWithImages as ba, inches as bc, findOverlappingShapePairs as bi, getShapeSlide as bn, setTableCellBorders as bo, setShapeAdjustValues as br, resolveDeckBodyTextColor as bs, getShapeTextColumns as bt, addSlideAt as c, getDistinctHyperlinkUrls as ca, getSlideCommentAuthors as cc, setShapeRunHyperlink as ci, findShapeByText as cn, getTableSize as co, pointInShape as cr, findChartsWithDataLabels as cs, copyShape as ct, duplicateSlideAt as d, getPresentationHyperlinkCountsBySlide as da, getPresentationFonts as dc, getSlideTitle as di, findShapesByKind as dn, insertTableColumn as do, setShapeBounds as dr, getPresentationChartKindCounts as ds, sendShapeBackward as dt, findSlidesWithChartKind as ea, getCommentDate as ec, getShapeRunHyperlinkTooltip as ei, getShapeStrokeCompound as en, getTableCellPosition as eo, getSlideMasterCount as er, getParagraphPropertiesEffective as es, addSlideImage as et, importSlide as f, getPresentationNotesLength as fa, getPresentationTheme as fc, setSlideBody as fi, findShapesByName as fn, insertTableRow as fo, setShapeDescription as fr, getShapeChartCategories as fs, sendShapeToBack as ft, reverseSlides as g, getSlideNotesLength as ga, loadPresentation as gc, findShapesWithAnimation as gi, findSlidePlaceholder as gn, removeTableColumn as go, clearShapeStroke as gr, getShapeChartSpec as gs, getShapeTextAnchor as gt, removeSlide as h, getSlideNotes as ha, createPresentation as hc, clearSlideAnimations as hi, findShapesWithHyperlinks as hn, mergeTableCells as ho, clearShapeFill as hr, getShapeChartSeriesValues as hs, getShapeBodyPrEffective as ht, addBlankSlide as i, getAllHyperlinks as ia, getCommentsSortedByDate as ic, setParagraphBullet as ii, getShapeStrokeWidth as in, getTableCells as io, getUnusedSlideMasters as ir, setShapeRunFormat as is, addSlideTextBox as it, getPresentationTextLengthsBySlide as j, setSlideTransition as ja, getShapeImageDuotone as ji, findShapesInRect as jn, getThumbnail as jo, setShapeStroke as jr, getSlideLayoutBackgroundShapes as js, setShapeTextColumns as jt, getPresentationText as k, clearSlideTransition as ka, getShapeImageContrast as ki, centerShapeOnSlide as kn, setTableStyleFlags as ko, setShapeRotation as kr, getSlideLayoutBackgroundImageBytes as ks, setShapeTextAutoFit as kt, addTitleSlide as l, getEmptySlides as la, getSlideComments as lc, setShapeRunText as li, findShapeInPresentation as ln, getTableStyleFlags as lo, renameShape as lr, findChartsWithTrendlines as ls, getShapeZIndex as lt, moveSlide as m, getPresentationNotesText as ma, setPresentationTheme as mc, setSlideTitle as mi, findShapesByText as mn, isTableShape as mo, shapesOverlap as mr, getShapeChartSeriesNames as ms, appendShapeText as mt, groupShapes as n, getAllCharts as na, getCommentSlide as nc, isParagraphBulletPicture as ni, getShapeStrokeJoin as nn, getTableCellText as no, getSlideMasterPartNames as nr, getShapeRunFormatEffective as ns, addSlideShape as nt, addSectionHeaderSlide as o, getAllNotes as oa, getPresentationCommentCountsBySlide as oc, setParagraphLineSpacing as oi, findShapeById as on, getTableDimensions as oo, isShapePlaceholder as or, findChartByKind as os, bringShapeToFront as ot, mergePresentations as p, getPresentationNotesLengthsBySlide as pa, setPresentationFonts as pc, setSlidePlaceholders as pi, findShapesByPreset as pn, isChartShape as po, setShapeHidden as pr, getShapeChartKind as ps, setShapeZIndex as pt, replaceTextInPresentation as q, getTableCell as qa, getSlideSize as qi, getShapePlaceholderIdx as qn, getSlideLayoutPartName as qo, getParagraphSpacing as qr, findCommentsAfter as qs, getShapeFillColorResolved as qt, ungroupShapes as r, getAllComments as ra, getCommentText as rc, setParagraphAlignment as ri, getShapeStrokeOpacity as rn, getTableCellTextDirection as ro, getSlideMasterUsageCounts as rr, setShapeHyperlink as rs, addSlideTable as rt, addSlide as s, getAllTables as sa, getPresentationCommenters as sc, setParagraphSpacing as si, findShapeByName as sn, getTableRowHeights as so, isShapeTextBox as sr, findChartsBySeriesName as ss, clearSlideShapes as st, VERSION as t, findSlidesWithChartTrendlines as ta, getCommentPosition as tc, getShapeRunText as ti, getShapeStrokeEffective as tn, getTableCellSpan as to, getSlideMasterPartName as tr, getShapeHyperlink as ts, addSlideLine as tt, duplicateSlide as u, getHiddenSlides as ua, removeSlideComment as uc, getSlideBody as ui, findShapesByHyperlink as un, getTableStyleId as uo, setShapeAltTitle as ur, getPresentationChartCountsBySlide as us, removeShape as ut, swapSlides as v, getSlidesWithComments as va, cm as vc, setShapeAnimation as vi, findSlidePlaceholders as vn, setTableCellAlignment as vo, getShapeStrokeArrow as vr, setChartSpec as vs, getShapeTextAutoFitParams as vt, findSlidesByNotes as w, getVisibleSlides as wa, findSlidesByLayoutType as wi, getSlideShapes as wn, setTableCellText as wo, setShapeImageFill as wr, getSlideBackgroundImageBytes as ws, setShapeAlignment as wt, findSlideByPartName as x, getSlidesWithNotes as xa, mm as xc, findShapesOutsideCanvas as xi, getShapeXmlString as xn, setTableCellFill as xo, setShapeFill as xr, clearSlideBackground as xs, getShapeTextDirection as xt, getSlideSections as y, getSlidesWithHyperlinks as ya, emu as yc, findFlippedShapes as yi, getShapeIndex as yn, setTableCellAnchor as yo, getShapeStrokeDash as yr, getEffectiveColorMap as ys, getShapeTextBodyRotationDeg as yt, getSlidePartName as z, listPackageParts as za, isShapeImageGrayscale as zi, getShapeBoundsResolved as zn, setCoreProperties as zo, resolveDrawingColorOpacity as zr, setSlideBackgroundImage as zs, getShapeEffects as zt };
17006
17285
 
17007
- //# sourceMappingURL=api-BfZ3bkVf.js.map
17286
+ //# sourceMappingURL=api-BmXESxg5.js.map