@shbernal/ts-pptx 3.2.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +19 -20
  2. package/dist/{autopage-QQyfRtoK.js → autopage-BYlTzX-l.js} +21 -17
  3. package/dist/autopage-BYlTzX-l.js.map +1 -0
  4. package/dist/browser.d.ts +6 -6
  5. package/dist/browser.js +11 -12
  6. package/dist/browser.js.map +1 -1
  7. package/dist/{diagnostics-Chjz_4_Q.d.ts → diagnostics-B0OmTOoz.d.ts} +65 -16
  8. package/dist/diagnostics-B0OmTOoz.d.ts.map +1 -0
  9. package/dist/{diagnostics-DYQC7xLV.js → diagnostics-CPVADSL1.js} +0 -0
  10. package/dist/{diagnostics-DYQC7xLV.js.map → diagnostics-CPVADSL1.js.map} +1 -1
  11. package/dist/{enums-CoXnxiCI.d.ts → enums-CvRYniUA.d.ts} +13 -3
  12. package/dist/{enums-CoXnxiCI.d.ts.map → enums-CvRYniUA.d.ts.map} +1 -1
  13. package/dist/{errors-BVLCFr-t.d.ts → errors-fB1KDJKQ.d.ts} +5 -5
  14. package/dist/{errors-BVLCFr-t.d.ts.map → errors-fB1KDJKQ.d.ts.map} +1 -1
  15. package/dist/{fit-DhMbQG5O.js → fit-TjpNbMru.js} +0 -0
  16. package/dist/fit-TjpNbMru.js.map +1 -0
  17. package/dist/{html-dom-DajBuobe.js → html-dom-yUSdCExA.js} +5 -6
  18. package/dist/html-dom-yUSdCExA.js.map +1 -0
  19. package/dist/html.d.ts +3 -3
  20. package/dist/html.js +1 -1
  21. package/dist/index.d.ts +6 -6
  22. package/dist/index.js +16 -34
  23. package/dist/index.js.map +1 -1
  24. package/dist/inspect.d.ts +1 -1
  25. package/dist/inspect.js +5 -4
  26. package/dist/inspect.js.map +1 -1
  27. package/dist/math.d.ts +1 -1
  28. package/dist/measure.d.ts +96 -6
  29. package/dist/measure.d.ts.map +1 -1
  30. package/dist/measure.js +2 -2
  31. package/dist/{st-enums-evQG2A7Z.js → namespaces-Sy_m7Nhd.js} +318 -209
  32. package/dist/namespaces-Sy_m7Nhd.js.map +1 -0
  33. package/dist/node.d.ts +6 -6
  34. package/dist/node.js +7 -20
  35. package/dist/node.js.map +1 -1
  36. package/dist/notes-bWApshah.js +1727 -0
  37. package/dist/notes-bWApshah.js.map +1 -0
  38. package/dist/{pres-C-EU3SkN.d.ts → pres-Dybf7ZUl.d.ts} +4 -4
  39. package/dist/{pres-C-EU3SkN.d.ts.map → pres-Dybf7ZUl.d.ts.map} +1 -1
  40. package/dist/{presentation-CxnUVhK9.js → presentation-3rAKKRfm.js} +1247 -743
  41. package/dist/presentation-3rAKKRfm.js.map +1 -0
  42. package/dist/{presentation-Osx1cDdJ.d.ts → presentation-types-D7cgT-eG.d.ts} +867 -24
  43. package/dist/presentation-types-D7cgT-eG.d.ts.map +1 -0
  44. package/dist/read.d.ts +4 -5
  45. package/dist/read.d.ts.map +1 -1
  46. package/dist/read.js +3 -3
  47. package/dist/script.d.ts +2 -2
  48. package/dist/script.d.ts.map +1 -1
  49. package/dist/script.js +0 -0
  50. package/dist/script.js.map +1 -1
  51. package/dist/{shapes-DoJBPrwN.js → shapes-Dyw5bxwO.js} +371 -52
  52. package/dist/shapes-Dyw5bxwO.js.map +1 -0
  53. package/dist/{slide-BTfn1Pyp.d.ts → slide-B_aInw3N.d.ts} +246 -182
  54. package/dist/slide-B_aInw3N.d.ts.map +1 -0
  55. package/dist/{text-C4P9MNdf.js → text-DSN3anEh.js} +3609 -4932
  56. package/dist/text-DSN3anEh.js.map +1 -0
  57. package/dist/{units-internal-CR8s8YQa.js → units-internal-DNvK2I6o.js} +207 -35
  58. package/dist/units-internal-DNvK2I6o.js.map +1 -0
  59. package/dist/zip.d.ts +2 -2
  60. package/package.json +36 -27
  61. package/dist/autopage-QQyfRtoK.js.map +0 -1
  62. package/dist/diagnostics-Chjz_4_Q.d.ts.map +0 -1
  63. package/dist/embedded-fonts-MaynAHa9.js +0 -94
  64. package/dist/embedded-fonts-MaynAHa9.js.map +0 -1
  65. package/dist/fit-DhMbQG5O.js.map +0 -1
  66. package/dist/html-dom-DajBuobe.js.map +0 -1
  67. package/dist/presentation-CxnUVhK9.js.map +0 -1
  68. package/dist/presentation-Osx1cDdJ.d.ts.map +0 -1
  69. package/dist/presentation-types-Dj4riuDs.d.ts +0 -538
  70. package/dist/presentation-types-Dj4riuDs.d.ts.map +0 -1
  71. package/dist/shapes-DoJBPrwN.js.map +0 -1
  72. package/dist/slide-BTfn1Pyp.d.ts.map +0 -1
  73. package/dist/st-enums-evQG2A7Z.js.map +0 -1
  74. package/dist/text-C4P9MNdf.js.map +0 -1
  75. package/dist/units-C7QM1KgH.js +0 -144
  76. package/dist/units-C7QM1KgH.js.map +0 -1
  77. package/dist/units-internal-CR8s8YQa.js.map +0 -1
@@ -1,6 +1,145 @@
1
- import { n as warn, r as warnOnce } from "./diagnostics-DYQC7xLV.js";
1
+ import { i as warnOnce, r as warn } from "./diagnostics-CPVADSL1.js";
2
2
  import { n as InvalidOptionError } from "./errors-Bvln0H-7.js";
3
- import { a as FIXED_PCT_PER_PERCENT, i as EMU_PER_POINT, m as inchesToEmu, r as EMU_PER_INCH, s as PERCENT_SCALE, t as ANGLE_UNITS_PER_DEGREE, u as coordToEmu } from "./units-C7QM1KgH.js";
3
+ //#region src/units.ts
4
+ /**
5
+ * Public unit conversion helpers and standard PowerPoint slide-layout constants.
6
+ */
7
+ const EMU_PER_INCH = 914400;
8
+ const EMU_PER_POINT = 12700;
9
+ const POINTS_PER_INCH = 72;
10
+ /**
11
+ * DrawingML angle unit. `ST_Angle` (`rot`, shadow `dir`, gradient `ang`, …) is measured in
12
+ * sixtieths-of-a-thousandth of a degree, i.e. 60000 units per degree. Multiply a value in
13
+ * degrees by this to get the OOXML integer.
14
+ */
15
+ const ANGLE_UNITS_PER_DEGREE = 6e4;
16
+ /**
17
+ * DrawingML fixed-point percentage scale. `ST_Percentage` / `ST_PositiveFixedPercentage` and
18
+ * related types (`<a:alpha>`, `<a:spcPct>`, shape adjustment guides, `<p:tav tm>`, …) encode
19
+ * 100% as the integer 100000. Multiply a 0-1 fraction by this to get the OOXML value.
20
+ */
21
+ const PERCENT_SCALE = 1e5;
22
+ /**
23
+ * Scale for a percentage supplied as 0-100 (rather than a 0-1 fraction) into the same
24
+ * fixed-point percentage integer as {@link PERCENT_SCALE} (1% = 1000 units, i.e. thousandths
25
+ * of a percent). Use for inputs documented as percents: transparency/alpha, image crop insets,
26
+ * gradient stops, bullet size, connector adjust, etc.
27
+ */
28
+ const FIXED_PCT_PER_PERCENT = PERCENT_SCALE / 100;
29
+ /**
30
+ * DrawingML text measures font size (`sz`), character spacing (`spc`) and point line/paragraph
31
+ * spacing (`<a:spcPts val>`) in hundredths of a point. Multiply a value in points by this to get
32
+ * the OOXML integer.
33
+ */
34
+ const HUNDREDTHS_PER_POINT = 100;
35
+ /**
36
+ * Convert a value in points to hundredths of a point (rounded), the integer unit DrawingML uses
37
+ * for `sz`, `spc`, and `<a:spcPts val>`. See {@link HUNDREDTHS_PER_POINT}.
38
+ */
39
+ function ptToHundredths(pt) {
40
+ assertFiniteNumber(pt, "points");
41
+ return Math.round(pt * 100);
42
+ }
43
+ /** A bare number larger than this (in inches) is almost certainly a mistake — likely a raw EMU
44
+ * value passed where inches are expected. We interpret it as inches (the documented contract) but
45
+ * warn, pointing at the explicit `"<n>emu"` form. ~1000in is far beyond any real slide. */
46
+ const IMPLAUSIBLE_INCHES = 1e3;
47
+ /** Default pixel density for the `"<n>px"` coordinate unit: CSS reference pixels, also the
48
+ * density ts-pptx assumes when reading an image header's pixel dimensions. */
49
+ const DEFAULT_PX_PER_INCH = 96;
50
+ function inchesToEmu(inches) {
51
+ assertFiniteNumber(inches, "inches");
52
+ return Math.round(inches * EMU_PER_INCH);
53
+ }
54
+ function pointsToEmu(points) {
55
+ assertFiniteNumber(points, "points");
56
+ return Math.round(points * EMU_PER_POINT);
57
+ }
58
+ function pixelsToEmu(pixels, dpi) {
59
+ assertFiniteNumber(pixels, "pixels");
60
+ assertPositiveFiniteNumber(dpi, "dpi");
61
+ return inchesToEmu(pixels / dpi);
62
+ }
63
+ /**
64
+ * Resolve a percentage of an axis length to EMU.
65
+ * @param percent - percentage value (e.g. `50` for 50%)
66
+ * @param axisEmu - the axis length in EMU (slide width for x/w, height for y/h)
67
+ */
68
+ function percentToEmu(percent, axisEmu) {
69
+ assertFiniteNumber(percent, "percent");
70
+ assertFiniteNumber(axisEmu, "axisEmu");
71
+ return Math.round(percent / 100 * axisEmu);
72
+ }
73
+ /**
74
+ * The single user-coordinate → EMU boundary. Convert each user-supplied coordinate exactly once.
75
+ *
76
+ * Accepts (see {@link Coord}):
77
+ * - a bare `number` → **always inches** (the documented unit); no magnitude guessing
78
+ * - `"<n>%"` → percentage of `axisEmu`
79
+ * - `"<n>in"` / `"<n>pt"` / `"<n>px"` / `"<n>emu"` → explicit units (the escape hatch for non-inch
80
+ * values). `px` is resolved at {@link DEFAULT_PX_PER_INCH} (96), for authoring against a known
81
+ * web/source canvas size.
82
+ *
83
+ * Throws on non-finite or unparseable input rather than silently emitting a degenerate 0-size.
84
+ * @param value - user coordinate
85
+ * @param axisEmu - axis length in EMU, used only to resolve percentages
86
+ */
87
+ function coordToEmu(value, axisEmu) {
88
+ if (typeof value === "number") {
89
+ assertFiniteNumber(value, "coordinate");
90
+ if (Math.abs(value) > IMPLAUSIBLE_INCHES) warn("coord/bare-number-is-inches", `coordinate ${value} interpreted as ${value} inches. A bare number is always inches; if you meant EMU, pass it as a string like "${Math.round(value)}emu".`);
91
+ return inchesToEmu(value);
92
+ }
93
+ const match = /^\s*(-?\d*\.?\d+)\s*(%|in|pt|px|emu)\s*$/.exec(value);
94
+ if (!match) throw new InvalidOptionError("coord/invalid-format", `Invalid coordinate "${value}". Expected a number (inches) or a string like "50%", "5in", "72pt", "96px", or "914400emu".`);
95
+ const n = Number(match[1]);
96
+ switch (match[2]) {
97
+ case "%": return percentToEmu(n, axisEmu);
98
+ case "in": return inchesToEmu(n);
99
+ case "pt": return pointsToEmu(n);
100
+ case "px": return pixelsToEmu(n, 96);
101
+ default:
102
+ assertFiniteNumber(n, "coordinate");
103
+ return Math.round(n);
104
+ }
105
+ }
106
+ function emuToInches(emu) {
107
+ assertFiniteNumber(emu, "emu");
108
+ return emu / EMU_PER_INCH;
109
+ }
110
+ function emuToPoints(emu) {
111
+ assertFiniteNumber(emu, "emu");
112
+ return emu / EMU_PER_POINT;
113
+ }
114
+ function emuToPixels(emu, dpi) {
115
+ assertFiniteNumber(emu, "emu");
116
+ assertPositiveFiniteNumber(dpi, "dpi");
117
+ return Math.round(emuToInches(emu) * dpi);
118
+ }
119
+ function standardLayout(layout, name, widthIn, heightIn) {
120
+ return Object.freeze({
121
+ layout,
122
+ name,
123
+ widthIn,
124
+ heightIn,
125
+ widthEmu: inchesToEmu(widthIn),
126
+ heightEmu: inchesToEmu(heightIn)
127
+ });
128
+ }
129
+ const STANDARD_LAYOUTS = Object.freeze({
130
+ LAYOUT_4x3: standardLayout("LAYOUT_4x3", "screen4x3", 10, 7.5),
131
+ LAYOUT_16x9: standardLayout("LAYOUT_16x9", "screen16x9", 10, 5.625),
132
+ LAYOUT_16x10: standardLayout("LAYOUT_16x10", "screen16x10", 10, 6.25),
133
+ LAYOUT_WIDE: standardLayout("LAYOUT_WIDE", "custom", 40 / 3, 7.5)
134
+ });
135
+ function assertFiniteNumber(value, name) {
136
+ if (!Number.isFinite(value)) throw new InvalidOptionError("coord/non-finite", `${name} must be a finite number`);
137
+ }
138
+ function assertPositiveFiniteNumber(value, name) {
139
+ assertFiniteNumber(value, name);
140
+ if (value <= 0) throw new InvalidOptionError("coord/not-positive", `${name} must be greater than 0`);
141
+ }
142
+ //#endregion
4
143
  //#region src/enums.ts
5
144
  let TextAnchor = /* @__PURE__ */ function(TextAnchor) {
6
145
  TextAnchor["b"] = "b";
@@ -283,6 +422,20 @@ const VALID_SHAPE_PRESETS = /* @__PURE__ */ new Set([...Object.values(ShapeType)
283
422
  function asChartType(name) {
284
423
  return name;
285
424
  }
425
+ /** Every {@link ChartType} value, for validating a caller-supplied `type` at the API boundary. */
426
+ const CHART_TYPES = new Set(Object.values(ChartType));
427
+ /**
428
+ * Is `name` a chart type this library emits?
429
+ *
430
+ * `CHART_NAME` constrains TypeScript callers, but `addChart` is reachable from plain JavaScript
431
+ * where nothing enforces the union — and the two emitters partition the catalog between them by
432
+ * `switch`, so an off-catalog string has no arm in either and cannot produce a plot. Checked once
433
+ * at define time (`gen/define/chart.ts`) so the caller hears about it at the call that was wrong,
434
+ * rather than getting a chart-shaped hole in the deck.
435
+ */
436
+ function isChartType(name) {
437
+ return typeof name === "string" && CHART_TYPES.has(name);
438
+ }
286
439
  /**
287
440
  * The chartEx (`cx:` / Office 2016 chart-extension) chart types. Unlike the classic 2007 catalog
288
441
  * these do NOT emit a `<c:chartSpace>` chart part: they emit a separate `chartEx{N}.xml` part in
@@ -526,14 +679,6 @@ const AXIS_ID_CATEGORY_SECONDARY = "2094734555";
526
679
  const AXIS_ID_SERIES_PRIMARY = "2094734556";
527
680
  const LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
528
681
  const BARCHART_COLORS = [
529
- "C0504D",
530
- "4F81BD",
531
- "9BBB59",
532
- "8064A2",
533
- "4BACC6",
534
- "F79646",
535
- "628FC6",
536
- "C86360",
537
682
  "C0504D",
538
683
  "4F81BD",
539
684
  "9BBB59",
@@ -544,15 +689,6 @@ const BARCHART_COLORS = [
544
689
  "C86360"
545
690
  ];
546
691
  const PIECHART_COLORS = [
547
- "5DA5DA",
548
- "FAA43A",
549
- "60BD68",
550
- "F17CB0",
551
- "B2912F",
552
- "B276B2",
553
- "DECF3F",
554
- "F15854",
555
- "A7A7A7",
556
692
  "5DA5DA",
557
693
  "FAA43A",
558
694
  "60BD68",
@@ -564,6 +700,7 @@ const PIECHART_COLORS = [
564
700
  "A7A7A7"
565
701
  ];
566
702
  const SLDNUMFLDID = "{F7021451-1387-4CA6-816F-3879F97B5CBC}";
703
+ const SLDNUM_PLACEHOLDER_TEXT = "‹#›";
567
704
  const XML_DECL = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
568
705
  const IMG_BROKEN = "data:image/png;base64,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";
569
706
  const IMG_SVG_PLACEHOLDER = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==";
@@ -662,13 +799,20 @@ function resolveTableColWidthsEmu(colW, totalWidthEmu, colCount) {
662
799
  return new Array(colCount).fill(even);
663
800
  }
664
801
  /**
665
- * Convert `pt` into points (using `ONEPT`)
666
- * @param {number|string} pt
667
- * @returns {number} value in points (`ONEPT`)
802
+ * Convert points to EMU, leniently: anything that does not read as a finite number — a `NaN`,
803
+ * an `Infinity`, a non-numeric string, `null` — becomes `0` rather than throwing.
804
+ *
805
+ * That is the whole difference from {@link pointsToEmu} in `units.ts`, which throws on the same
806
+ * input. Emitters use this one for the many optional size/width/offset options where a missing
807
+ * or malformed value should collapse the feature (a zero-width line, no shadow offset) rather
808
+ * than take the whole deck down.
809
+ *
810
+ * @param pt - points, as a number or a numeric string
811
+ * @returns the value in EMU, or `0` if it does not read as a finite number
668
812
  */
669
- function valToPts(pt) {
670
- const points = Number(pt) || 0;
671
- return isNaN(points) ? 0 : Math.round(points * EMU_PER_POINT);
813
+ function ptsToEmuLenient(pt) {
814
+ const points = Number(pt);
815
+ return Number.isFinite(points) ? Math.round(points * EMU_PER_POINT) : 0;
672
816
  }
673
817
  /**
674
818
  * Convert a transparency percentage (0-100) into a schema-valid `<a:alpha>` value
@@ -692,19 +836,48 @@ function opacityToAlpha(opacity) {
692
836
  * repair, so clamp into range and warn.
693
837
  */
694
838
  function lineWidthToEmu(widthPts) {
695
- const raw = valToPts(widthPts);
839
+ const raw = ptsToEmuLenient(widthPts);
696
840
  const clamped = Math.min(20116800, Math.max(0, raw));
697
841
  if (clamped !== raw) warn("line/width-out-of-range", `line width ${widthPts} is outside the valid range 0-1584pt; using ${clamped / EMU_PER_POINT}.`);
698
842
  return clamped;
699
843
  }
700
844
  /**
701
- * Convert degrees (0..360) to PowerPoint `rot` value
702
- * @param {number} d degrees
703
- * @returns {number} calculated `rot` value
845
+ * Convert degrees to a DrawingML angle (60000ths of a degree), **without** wrapping.
846
+ *
847
+ * Most angles in the format are not modular: a connection site at 400 degrees, a polar adjust
848
+ * handle whose range runs to 540, an arc that sweeps 400 degrees — each means something a
849
+ * reduction into 0..360 would destroy. Use this for those, and {@link convertRotationDegrees}
850
+ * for the ones that genuinely are a rotation.
851
+ *
852
+ * Non-finite input throws rather than reaching the attribute: `Math.round(Infinity * 60000)` is
853
+ * `Infinity`, which serializes as `ang="Infinity"` and makes PowerPoint offer to repair the file.
854
+ *
855
+ * @param d - degrees
856
+ * @param what - what is being converted, for the error message
857
+ * @param code - diagnostic code to throw under, where a caller has a more specific one
858
+ */
859
+ function convertAngleUnits(d, what, code = "coord/non-finite") {
860
+ assertFiniteDegrees(d, what, code);
861
+ return Math.round(d * ANGLE_UNITS_PER_DEGREE);
862
+ }
863
+ function assertFiniteDegrees(d, what, code) {
864
+ if (typeof d !== "number" || !Number.isFinite(d)) throw new InvalidOptionError(code, `${what} must be a finite number of degrees; received ${String(d)}.`);
865
+ }
866
+ /**
867
+ * Convert a shape or gradient rotation (degrees) to a DrawingML angle (60000ths of a degree).
868
+ *
869
+ * A rotation *is* modular — 800 degrees and 80 degrees point the same way — so the value is
870
+ * reduced with `% 360`. The reduction keeps the sign: `-45` stays `-45` rather than becoming
871
+ * `315`, because both are valid `ST_Angle`, PowerPoint writes negative rotations itself, and
872
+ * the read side reports back what was authored. Only an input outside -360..360 moves.
873
+ *
874
+ * @param d - degrees
875
+ * @returns the `rot` value in 60000ths of a degree
704
876
  */
705
877
  function convertRotationDegrees(d) {
706
- d = d || 0;
707
- return Math.round((d > 360 ? d - 360 : d) * ANGLE_UNITS_PER_DEGREE);
878
+ const degrees = d || 0;
879
+ assertFiniteDegrees(degrees, "rotation", "coord/non-finite");
880
+ return Math.round(degrees % 360 * ANGLE_UNITS_PER_DEGREE);
708
881
  }
709
882
  /**
710
883
  * Convert a freeform arc angle (degrees) to an `<a:arcTo>` ST_AdjAngle value (60000ths).
@@ -715,10 +888,9 @@ function convertRotationDegrees(d) {
715
888
  * @returns {number} ST_AdjAngle value (60000ths of a degree)
716
889
  */
717
890
  function convertArcAngle(d, attr) {
718
- if (typeof d !== "number" || !Number.isFinite(d)) throw new InvalidOptionError("geometry/arc-angle-non-finite", `Arc ${attr} must be a finite number of degrees; received ${String(d)}.`);
719
- return Math.round(d * ANGLE_UNITS_PER_DEGREE);
891
+ return convertAngleUnits(d, `Arc ${attr}`, "geometry/arc-angle-non-finite");
720
892
  }
721
893
  //#endregion
722
- export { connectorPresetFor as $, IMG_PLAYBTN as A, AlignV as B, DEF_PRES_LAYOUT_NAME as C, DEF_TEXT_GLOW as D, DEF_SLIDE_MARGIN_IN as E, PIECHART_COLORS as F, PlaceholderType as G, CONNECTOR_PRESETS as H, REGEX_HEX_COLOR as I, SlideObjectType as J, SchemeColor as K, SLDNUMFLDID as L, LAYOUT_IDX_SERIES_BASE as M, LETTERS as N, DEF_TEXT_SHADOW as O, LINEH_MODIFIER as P, asChartType as Q, XML_DECL as R, DEF_PRES_LAYOUT as S, DEF_SHAPE_SHADOW as T, ChartType as U, BulletType as V, OutputType as W, TextAnchor as X, TableStyle as Y, VALID_SHAPE_PRESETS as Z, DEF_CELL_BORDER as _, lineWidthToEmu as a, DEF_CHART_GRIDLINE as b, resolveTableColWidthsEmu as c, AXIS_ID_CATEGORY_PRIMARY as d, isChartExType as et, AXIS_ID_CATEGORY_SECONDARY as f, BARCHART_COLORS as g, AXIS_ID_VALUE_SECONDARY as h, inch2Emu as i, IMG_SVG_PLACEHOLDER as j, IMG_BROKEN as k, transparencyToAlpha as l, AXIS_ID_VALUE_PRIMARY as m, convertRotationDegrees as n, marginToEmu as o, AXIS_ID_SERIES_PRIMARY as p, ShapeType as q, getSmartParseNumber as r, opacityToAlpha as s, convertArcAngle as t, valToPts as u, DEF_CELL_MARGIN_IN as v, DEF_SHAPE_LINE_COLOR as w, DEF_FONT_COLOR as x, DEF_CHART_BORDER as y, AlignH as z };
894
+ export { VALID_SHAPE_PRESETS as $, IMG_BROKEN as A, XML_DECL as B, DEF_PRES_LAYOUT as C, DEF_SLIDE_MARGIN_IN as D, DEF_SHAPE_SHADOW as E, LINEH_MODIFIER as F, ChartType as G, AlignV as H, PIECHART_COLORS as I, SchemeColor as J, OutputType as K, REGEX_HEX_COLOR as L, IMG_SVG_PLACEHOLDER as M, LAYOUT_IDX_SERIES_BASE as N, DEF_TEXT_GLOW as O, LETTERS as P, TextAnchor as Q, SLDNUMFLDID as R, DEF_FONT_COLOR as S, DEF_SHAPE_LINE_COLOR as T, BulletType as U, AlignH as V, CONNECTOR_PRESETS as W, SlideObjectType as X, ShapeType as Y, TableStyle as Z, BARCHART_COLORS as _, inchesToEmu as _t, inch2Emu as a, DEFAULT_PX_PER_INCH as at, DEF_CHART_BORDER as b, pointsToEmu as bt, opacityToAlpha as c, FIXED_PCT_PER_PERCENT as ct, transparencyToAlpha as d, POINTS_PER_INCH as dt, asChartType as et, AXIS_ID_CATEGORY_PRIMARY as f, STANDARD_LAYOUTS as ft, AXIS_ID_VALUE_SECONDARY as g, emuToPoints as gt, AXIS_ID_VALUE_PRIMARY as h, emuToPixels as ht, getSmartParseNumber as i, ANGLE_UNITS_PER_DEGREE as it, IMG_PLAYBTN as j, DEF_TEXT_SHADOW as k, ptsToEmuLenient as l, HUNDREDTHS_PER_POINT as lt, AXIS_ID_SERIES_PRIMARY as m, emuToInches as mt, convertArcAngle as n, isChartExType as nt, lineWidthToEmu as o, EMU_PER_INCH as ot, AXIS_ID_CATEGORY_SECONDARY as p, coordToEmu as pt, PlaceholderType as q, convertRotationDegrees as r, isChartType as rt, marginToEmu as s, EMU_PER_POINT as st, convertAngleUnits as t, connectorPresetFor as tt, resolveTableColWidthsEmu as u, PERCENT_SCALE as ut, DEF_CELL_BORDER as v, percentToEmu as vt, DEF_PRES_LAYOUT_NAME as w, DEF_CHART_GRIDLINE as x, ptToHundredths as xt, DEF_CELL_MARGIN_IN as y, pixelsToEmu as yt, SLDNUM_PLACEHOLDER_TEXT as z };
723
895
 
724
- //# sourceMappingURL=units-internal-CR8s8YQa.js.map
896
+ //# sourceMappingURL=units-internal-DNvK2I6o.js.map