pptx-ts 0.0.1

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 (78) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +319 -0
  3. package/dist/autopage-DkjYZUFD.js +423 -0
  4. package/dist/autopage-DkjYZUFD.js.map +1 -0
  5. package/dist/browser.d.ts +31 -0
  6. package/dist/browser.d.ts.map +1 -0
  7. package/dist/browser.js +110 -0
  8. package/dist/browser.js.map +1 -0
  9. package/dist/diagnostics-Du_s75MT.d.ts +829 -0
  10. package/dist/diagnostics-Du_s75MT.d.ts.map +1 -0
  11. package/dist/enums-CvRYniUA.d.ts +463 -0
  12. package/dist/enums-CvRYniUA.d.ts.map +1 -0
  13. package/dist/errors-Bvln0H-7.js +112 -0
  14. package/dist/errors-Bvln0H-7.js.map +1 -0
  15. package/dist/errors-PflMPWBn.d.ts +182 -0
  16. package/dist/errors-PflMPWBn.d.ts.map +1 -0
  17. package/dist/fit-BKs0zxMI.js +1356 -0
  18. package/dist/fit-BKs0zxMI.js.map +1 -0
  19. package/dist/html-dom-B0I0QSbU.js +679 -0
  20. package/dist/html-dom-B0I0QSbU.js.map +1 -0
  21. package/dist/html.d.ts +26 -0
  22. package/dist/html.d.ts.map +1 -0
  23. package/dist/html.js +63 -0
  24. package/dist/html.js.map +1 -0
  25. package/dist/index.d.ts +24 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +57 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/inspect.d.ts +197 -0
  30. package/dist/inspect.d.ts.map +1 -0
  31. package/dist/inspect.js +317 -0
  32. package/dist/inspect.js.map +1 -0
  33. package/dist/math.d.ts +37 -0
  34. package/dist/math.d.ts.map +1 -0
  35. package/dist/math.js +203 -0
  36. package/dist/math.js.map +1 -0
  37. package/dist/measure.d.ts +313 -0
  38. package/dist/measure.d.ts.map +1 -0
  39. package/dist/measure.js +3 -0
  40. package/dist/namespaces-BVnNu7sg.js +666 -0
  41. package/dist/namespaces-BVnNu7sg.js.map +1 -0
  42. package/dist/node.d.ts +20 -0
  43. package/dist/node.d.ts.map +1 -0
  44. package/dist/node.js +55 -0
  45. package/dist/node.js.map +1 -0
  46. package/dist/notes-RLCwdlTE.js +1703 -0
  47. package/dist/notes-RLCwdlTE.js.map +1 -0
  48. package/dist/package-CaOLXSNi.d.ts +193 -0
  49. package/dist/package-CaOLXSNi.d.ts.map +1 -0
  50. package/dist/pres-C5__xkDh.d.ts +202 -0
  51. package/dist/pres-C5__xkDh.d.ts.map +1 -0
  52. package/dist/presentation-Cp7vzlAw.js +5427 -0
  53. package/dist/presentation-Cp7vzlAw.js.map +1 -0
  54. package/dist/presentation-types-DP_8jog7.d.ts +4872 -0
  55. package/dist/presentation-types-DP_8jog7.d.ts.map +1 -0
  56. package/dist/read.d.ts +55 -0
  57. package/dist/read.d.ts.map +1 -0
  58. package/dist/read.js +4 -0
  59. package/dist/script.d.ts +581 -0
  60. package/dist/script.d.ts.map +1 -0
  61. package/dist/script.js +3741 -0
  62. package/dist/script.js.map +1 -0
  63. package/dist/shapes-BemroU-z.js +6951 -0
  64. package/dist/shapes-BemroU-z.js.map +1 -0
  65. package/dist/slide-js0QpRV-.d.ts +3873 -0
  66. package/dist/slide-js0QpRV-.d.ts.map +1 -0
  67. package/dist/text-CyetbF6p.js +11278 -0
  68. package/dist/text-CyetbF6p.js.map +1 -0
  69. package/dist/units-1kRzYShk.js +231 -0
  70. package/dist/units-1kRzYShk.js.map +1 -0
  71. package/dist/units-internal-Dg95w_YD.js +753 -0
  72. package/dist/units-internal-Dg95w_YD.js.map +1 -0
  73. package/dist/zip.d.ts +68 -0
  74. package/dist/zip.d.ts.map +1 -0
  75. package/dist/zip.js +163 -0
  76. package/dist/zip.js.map +1 -0
  77. package/package.json +152 -0
  78. package/skills/ts-pptx-upstream/SKILL.md +340 -0
@@ -0,0 +1,3873 @@
1
+ import { _ as TextAnchor, f as SHAPE_NAME, g as TableStyle, h as SlideObjectType, i as CHART_NAME, l as PLACEHOLDER_TYPE, t as AlignH } from "./enums-CvRYniUA.js";
2
+ //#region src/types/shape.d.ts
3
+ /**
4
+ * A single preset-geometry adjustment guide (`<a:gd>` inside `<a:avLst>`).
5
+ * - `name` is the guide name the preset defines, e.g. `'adj'`, `'adj1'`, `'adj2'`.
6
+ * PowerPoint shows these handles as the yellow drag dots on a selected shape.
7
+ * - `value` is a fraction `0.0–1.0` of the handle's range, emitted as a percentage
8
+ * guide formula (`val`, in 1/100000 units, so `0.25` → `fmla="val 25000"`).
9
+ * Most adjustment handles (corner radius, chevron point, callout depth, bevel
10
+ * width, …) are percentage-based and map directly; some shapes accept values
11
+ * beyond `1.0`. For angle-based handles, prefer the `angleRange` shortcut.
12
+ */
13
+ interface ShapeAdjustValue {
14
+ name: string;
15
+ value: number;
16
+ }
17
+ /**
18
+ * A geometry guide (`<a:gd>` inside a `custGeom`'s `<a:gdLst>`): a named construction formula
19
+ * that connection sites, adjust handles, and the text rect can reference by name.
20
+ * - `name` is a `ST_GeomGuideName` token, e.g. `'w2'`.
21
+ * - `formula` is a `ST_GeomGuideFormula` — a space-delimited op + args string emitted verbatim,
22
+ * e.g. the multiply-divide op `"* / w 1 2"` written without the inner space (w × 1 ÷ 2), or
23
+ * `'val 10800'`. This is an advanced escape hatch: the arguments are not interpreted, only
24
+ * escaped. The leading operation *is* checked against the 17 ECMA-376 §20.1.9.11 operations
25
+ * (multiply-divide, add-subtract, add-divide, if-else, `abs`, `at2`, `cat2`, `cos`, `max`,
26
+ * `min`, `mod`, `pin`, `sat2`, `sin`, `sqrt`, `tan`, `val` — see `GEOM_GUIDE_OPS` in
27
+ * `src/gen/drawingml/geometry.ts` for the literal tokens), because an unknown one emits
28
+ * schema-shaped but semantically dead geometry that PowerPoint answers with a repair prompt;
29
+ * such a guide is warned about and skipped.
30
+ * @see http://www.datypic.com/sc/ooxml/e-a_gd-1.html
31
+ */
32
+ interface ShapeGuide {
33
+ name: string;
34
+ formula: string;
35
+ }
36
+ /**
37
+ * A connection site (`<a:cxn>` inside a `custGeom`'s `<a:cxnLst>`): a point a connector can attach
38
+ * to. A connector's `startShapeIdx`/`endShapeIdx` index into the target shape's connection sites.
39
+ */
40
+ interface ShapeConnectionSite {
41
+ /** Incoming-connector angle in degrees (emitted to `ang`, `ST_AdjAngle` 60000ths). */
42
+ ang: number;
43
+ /** X in the object's own space (like `points`), or a guide-name string emitted verbatim. */
44
+ x: Coord | string;
45
+ /** Y in the object's own space (like `points`), or a guide-name string emitted verbatim. */
46
+ y: Coord | string;
47
+ }
48
+ /** An XY adjust handle (`<a:ahXY>`) — a draggable handle, optionally bound to guides. */
49
+ interface ShapeAdjustHandleXY {
50
+ x: Coord | string;
51
+ y: Coord | string;
52
+ gdRefX?: string;
53
+ minX?: Coord | string;
54
+ maxX?: Coord | string;
55
+ gdRefY?: string;
56
+ minY?: Coord | string;
57
+ maxY?: Coord | string;
58
+ }
59
+ /** A polar adjust handle (`<a:ahPolar>`) — radius/angle rather than XY. */
60
+ interface ShapeAdjustHandlePolar {
61
+ x: Coord | string;
62
+ y: Coord | string;
63
+ gdRefR?: string;
64
+ minR?: Coord | string;
65
+ maxR?: Coord | string;
66
+ gdRefAng?: string;
67
+ minAng?: number;
68
+ maxAng?: number;
69
+ }
70
+ type ShapeAdjustHandle = ShapeAdjustHandleXY | ShapeAdjustHandlePolar;
71
+ interface ShapeProps extends PositionProps, ObjectNameProps {
72
+ /**
73
+ * Horizontal alignment
74
+ * @default 'left'
75
+ */
76
+ align?: HAlign;
77
+ /**
78
+ * Radius (only for ShapeType.pie, ShapeType.arc, ShapeType.blockArc)
79
+ * - In the case of ShapeType.blockArc you have to setup the arcThicknessRatio
80
+ * - values: [0-359, 0-359]
81
+ * @default [270, 0]
82
+ */
83
+ angleRange?: [number, number];
84
+ /**
85
+ * Preset-geometry adjustment handles (`<a:avLst>` guides) for any preset shape.
86
+ * - Use this to tune adjustment handles that lack a dedicated shortcut option,
87
+ * e.g. chevron/arrow point depth, callout pointer, bevel/frame thickness.
88
+ * - Accepts a single guide or an array; each `value` is a `0.0–1.0` fraction of
89
+ * the handle's range (see {@link ShapeAdjustValue}).
90
+ * - `rectRadius` / `angleRange` remain friendly shortcuts; any `shapeAdjust`
91
+ * guide that does not collide with a shortcut name is emitted in addition.
92
+ * @example { name: 'adj', value: 0.25 } // set the single adjust handle to 25%
93
+ * @example [{ name: 'adj1', value: 0.5 }, { name: 'adj2', value: 0.25 }] // two handles
94
+ */
95
+ shapeAdjust?: ShapeAdjustValue | ShapeAdjustValue[];
96
+ /**
97
+ * Radius (only for ShapeType.blockArc)
98
+ * - You have to setup the angleRange values too
99
+ * - values: 0.0-1.0
100
+ * @default 0.5
101
+ */
102
+ arcThicknessRatio?: number;
103
+ /**
104
+ * Shape fill color properties
105
+ * @example { color:'FF0000' } // hex color (red)
106
+ * @example { color:'0088CC', transparency:50 } // hex color, 50% transparent
107
+ * @example { color:SchemeColor.accent1 } // Theme color Accent1
108
+ */
109
+ fill?: ShapeFillProps;
110
+ /**
111
+ * Flip shape horizontally?
112
+ * @default false
113
+ */
114
+ flipH?: boolean;
115
+ /**
116
+ * Flip shape vertical?
117
+ * @default false
118
+ */
119
+ flipV?: boolean;
120
+ /**
121
+ * Add hyperlink to shape
122
+ * @example hyperlink: { url: "https://example.com", tooltip: "Visit Homepage" },
123
+ */
124
+ hyperlink?: HyperlinkProps;
125
+ /**
126
+ * Line options
127
+ */
128
+ line?: ShapeLineProps;
129
+ /**
130
+ * Points (only for ShapeType.custGeom)
131
+ * - type: 'arc' (no end point — it is computed from the pen position, radii and sweep)
132
+ * - `hR` Shape Arc Height Radius
133
+ * - `wR` Shape Arc Width Radius
134
+ * - `stAng` Shape Arc Start Angle (degrees, not wrapped into 0..360)
135
+ * - `swAng` Shape Arc Swing Angle (degrees, not wrapped into 0..360)
136
+ * @see http://www.datypic.com/sc/ooxml/e-a_arcTo-1.html
137
+ * @example [{ x: 0, y: 0 }, { x: 10, y: 10 }] // draw a line between those two points
138
+ */
139
+ points?: GeometryPoint[];
140
+ /**
141
+ * Geometry guides (`<a:gdLst>`) for a `custGeom` shape — named construction formulas that
142
+ * connection sites / adjust handles can reference. Advanced: each `formula` is emitted verbatim.
143
+ * @example [{ name: 'w2', formula: 'val 10800' }]
144
+ */
145
+ guides?: ShapeGuide[];
146
+ /**
147
+ * Connection sites (`<a:cxnLst>`) for a `custGeom` shape — the points a connector can attach to.
148
+ * Positions are absolute in the object's own space (like `points`); a `startShapeIdx`/`endShapeIdx`
149
+ * on an `addConnector` indexes into this list.
150
+ * @example [{ ang: 0, x: 1, y: 0 }, { ang: 180, x: 0, y: 1 }]
151
+ */
152
+ connectionSites?: ShapeConnectionSite[];
153
+ /**
154
+ * Adjust handles (`<a:ahLst>`) for a `custGeom` shape — draggable handles (XY or polar),
155
+ * optionally bound to guides via `gdRef*`.
156
+ */
157
+ adjustHandles?: ShapeAdjustHandle[];
158
+ /**
159
+ * Rounded rectangle radius (only for ShapeType.roundRect)
160
+ * - values: 0.0 to 1.0
161
+ * @default 0
162
+ */
163
+ rectRadius?: number;
164
+ /**
165
+ * Rotation (degrees)
166
+ * - range: -360 to 360
167
+ * @default 0
168
+ * @example 180 // rotate 180 degrees
169
+ */
170
+ rotate?: number;
171
+ /**
172
+ * Shadow options
173
+ */
174
+ shadow?: ShadowProps;
175
+ }
176
+ //#endregion
177
+ //#region src/types/media.d.ts
178
+ type MediaType = 'audio' | 'online' | 'video';
179
+ interface ImageBaseProps extends PositionProps, ObjectNameProps {
180
+ /**
181
+ * Sizing note (`w`/`h` inherited from {@link PositionProps}):
182
+ * - When a `data` (base64) image is supplied and `w`/`h` are omitted, the natural pixel
183
+ * size is read from the image header (PNG/JPEG/GIF/BMP/WebP) and used at 96 DPI
184
+ * (natural pixels / 96 = inches).
185
+ * - When only one of `w`/`h` is given, the other is derived from the natural aspect ratio —
186
+ * for an SVG too, from its `width`/`height` or `viewBox`.
187
+ * - A `path` image is measured at export time (its bytes are not available synchronously);
188
+ * an omitted dimension falls back to 1 inch if it stays unmeasurable.
189
+ * - An SVG with *neither* dimension given also falls back to 1 inch: its user units carry a
190
+ * dependable aspect ratio but only a conventional magnitude, so a 24-unit icon is not
191
+ * treated as a quarter-inch object.
192
+ * - A vector source placed in a box whose ratio differs from its own is letterboxed, not
193
+ * stretched; see {@link sizing} to override.
194
+ */
195
+ /**
196
+ * Alt Text value ("How would you describe this object and its contents to someone who is blind?")
197
+ * - PowerPoint: [right-click on an image] > "Edit Alt Text..."
198
+ */
199
+ altText?: string;
200
+ /**
201
+ * Flip horizontally?
202
+ * @default false
203
+ */
204
+ flipH?: boolean;
205
+ /**
206
+ * Flip vertical?
207
+ * @default false
208
+ */
209
+ flipV?: boolean;
210
+ hyperlink?: HyperlinkProps;
211
+ /**
212
+ * Border line (`<a:ln>` outline) drawn around the image
213
+ * - same options as a shape outline; a picture supports a single outline, not per-side borders
214
+ * - MS-PPT: Format Picture > Line
215
+ * @example { color: '0088CC', width: 2 } // 2pt blue border
216
+ * @example { color: '666666', width: 1, dashType: 'dash' } // dashed gray border
217
+ */
218
+ line?: ShapeLineProps;
219
+ /**
220
+ * Name of a picture placeholder defined on the slide layout/master to populate
221
+ * - when it matches a layout/master placeholder, the image inherits that placeholder's
222
+ * position and size for any of `x`/`y`/`w`/`h` not supplied explicitly;
223
+ * explicit values always win
224
+ * @example 'picph'
225
+ * @see https://docs.microsoft.com/en-us/office/vba/api/powerpoint.ppplaceholdertype
226
+ */
227
+ placeholder?: string;
228
+ /**
229
+ * Image rotation (degrees)
230
+ * - range: -360 to 360
231
+ * @default 0
232
+ * @example 180 // rotate image 180 degrees
233
+ */
234
+ rotate?: number;
235
+ /**
236
+ * Enable image rounding (clips the image to a circle/ellipse)
237
+ * - shorthand for `shape: 'ellipse'`; `shape` takes precedence when both are set
238
+ * @default false
239
+ */
240
+ rounding?: boolean;
241
+ /**
242
+ * Clip the image to a preset shape geometry ("fit image into shape")
243
+ * - accepts any PowerPoint preset geometry name, e.g. `'roundRect'`, `'hexagon'`, `'ellipse'`
244
+ * - combine with `sizing: { type: 'cover', ... }` for an aspect-correct fill of the shape box
245
+ * - use `rectRadius` to set the corner radius for `'roundRect'`
246
+ * @example 'roundRect' // rounded-rectangle avatar
247
+ * @example 'hexagon' // hexagonal photo
248
+ */
249
+ shape?: SHAPE_NAME;
250
+ /**
251
+ * Clip the image to an arbitrary freeform path (`custGeom`)
252
+ * - takes precedence over `shape` / `rounding` when present
253
+ * - coordinates are authored in the image's own inch/EMU space (0..w, 0..h), not slide-relative and not normalized
254
+ * - supports the same path DSL as freeform shapes: `moveTo` / `lnTo` / `cubicBezTo` / `quadBezTo` / `arcTo` / `close`
255
+ * @example [{ x: 1, y: 0 }, { x: 2, y: 2 }, { x: 0, y: 2 }, { close: true }] // triangular photo clip
256
+ */
257
+ points?: GeometryPoint[];
258
+ /**
259
+ * Rounded rectangle corner radius (inches) when `shape: 'roundRect'`
260
+ * - values: 0.0 to 1.0
261
+ * @default 0
262
+ */
263
+ rectRadius?: number;
264
+ /**
265
+ * Preset-geometry adjustment handles (`<a:avLst>` guides) for the clip `shape`.
266
+ * - tune adjustment handles that lack a dedicated option, e.g. chevron point depth
267
+ * - accepts a single guide or an array; each `value` is a `0.0–1.0` fraction (see {@link ShapeAdjustValue})
268
+ * @example { name: 'adj', value: 0.25 }
269
+ */
270
+ shapeAdjust?: ShapeAdjustValue | ShapeAdjustValue[];
271
+ /**
272
+ * Shadow Props
273
+ * - MS-PPT > Format Picture > Shadow
274
+ * @example
275
+ * { type: 'outer', color: '000000', transparency: 50, blur: 20, offset: 20, angle: 270 }
276
+ */
277
+ shadow?: ShadowProps;
278
+ /**
279
+ * Crop the source image to a sub-region by percentage edge insets, emitted verbatim
280
+ * as OOXML `<a:srcRect>`.
281
+ * - each value is the percent (0–100) trimmed off that edge of the *source* image, the
282
+ * same model PowerPoint's Picture Format > Crop uses; `l`+`r` and `t`+`b` must each be < 100
283
+ * - the remaining sub-region is stretched to fill the picture's displayed `w`×`h` box, so this
284
+ * is the faithful way to reproduce a deck that maps several icons out of one composite raster
285
+ * - operates on the source image directly (independent of natural-pixel measurement), so unlike
286
+ * `sizing: 'crop'` (which crops in *displayed inches*) it works for SVG and unmeasurable formats
287
+ * - mutually exclusive with {@link sizing}; if both are set `crop` wins and `sizing` is ignored
288
+ * @example { l: 0, t: 0, r: 50, b: 50 } // keep the top-left quadrant of the source image
289
+ */
290
+ crop?: {
291
+ /** Percent (0–100) trimmed from the left edge of the source image. @default 0 */
292
+ l?: number;
293
+ /** Percent (0–100) trimmed from the top edge of the source image. @default 0 */
294
+ t?: number;
295
+ /** Percent (0–100) trimmed from the right edge of the source image. @default 0 */
296
+ r?: number;
297
+ /** Percent (0–100) trimmed from the bottom edge of the source image. @default 0 */
298
+ b?: number;
299
+ };
300
+ /**
301
+ * Image sizing options
302
+ * - omit entirely for the default: a raster fills the `w`×`h` box, a vector (SVG) source is
303
+ * letterboxed to its own aspect ratio inside that box
304
+ */
305
+ sizing?: {
306
+ /**
307
+ * Sizing type
308
+ * - `cover` / `contain` fit the image into the `w`×`h` box using the image's *natural*
309
+ * aspect ratio — read from the embedded PNG/JPEG/GIF/BMP/WebP header, or from an SVG's
310
+ * `width`/`height` or `viewBox`. If the natural size cannot be determined (an
311
+ * unrecognized format, or an SVG carrying neither) the displayed `w`/`h` ratio is used
312
+ * as a fallback and a warning is logged.
313
+ * - `crop` cuts a window out of the displayed image using the `x`/`y`/`w`/`h` offsets.
314
+ * - `stretch` fills the box regardless of aspect ratio. This is what a raster does
315
+ * anyway; name it explicitly to opt a vector source out of its aspect-correct default.
316
+ */
317
+ type: 'contain' | 'cover' | 'crop' | 'stretch';
318
+ /**
319
+ * Image width
320
+ * - inches or percentage
321
+ * - defaults to the picture's own `w`, which is what `cover`/`contain` almost always want
322
+ * @example 10.25 // position in inches
323
+ * @example '75%' // position as percentage of slide size
324
+ */
325
+ w?: Coord;
326
+ /**
327
+ * Image height
328
+ * - inches or percentage
329
+ * - defaults to the picture's own `h`
330
+ * @example 10.25 // position in inches
331
+ * @example '75%' // position as percentage of slide size
332
+ */
333
+ h?: Coord;
334
+ /**
335
+ * Offset from left to crop image
336
+ * - `crop` only
337
+ * - inches or percentage
338
+ * @example 10.25 // position in inches
339
+ * @example '75%' // position as percentage of slide size
340
+ */
341
+ x?: Coord;
342
+ /**
343
+ * Offset from top to crop image
344
+ * - `crop` only
345
+ * - inches or percentage
346
+ * @example 10.25 // position in inches
347
+ * @example '75%' // position as percentage of slide size
348
+ */
349
+ y?: Coord;
350
+ };
351
+ /**
352
+ * Transparency (percent)
353
+ * - MS-PPT > Format Picture > Picture > Picture Transparency > Transparency
354
+ * - range: 0-100
355
+ * @default 0
356
+ * @example 25 // 25% transparent
357
+ */
358
+ transparency?: number;
359
+ /**
360
+ * Recolor the image as a two-tone (duotone) effect
361
+ * - maps the image's shadows to `shadow` and its highlights to `highlight`
362
+ * - serializes `<a:duotone>` inside the picture's `<a:blip>` (MS-PPT > Format Picture > Picture Color > Recolor)
363
+ * - colors accept `HexColor` or `ThemeColor`, same as fills
364
+ * - the classic brand treatment: tint stock photography into a single brand hue
365
+ * @example { shadow: '250F6B', highlight: 'FFFFFF' } // deep-blue duotone
366
+ */
367
+ duotone?: {
368
+ /** Color mapped to the image's dark/shadow tones. */
369
+ shadow: Color;
370
+ /** Color mapped to the image's light/highlight tones. */
371
+ highlight: Color;
372
+ };
373
+ /**
374
+ * Recolor the image to grayscale (`<a:grayscl/>`)
375
+ * - maps every pixel to its luminance grey (MS-PPT > Format Picture > Picture Color > Recolor > Grayscale)
376
+ * - the cheapest recolour: no payload
377
+ * - mutually exclusive with the other recolour modes (`duotone`/`biLevel`/`clrChange`); if several are set,
378
+ * the first present in document order wins on read-back
379
+ * @default false
380
+ * @example true // desaturate the image
381
+ */
382
+ grayscale?: boolean;
383
+ /**
384
+ * Recolor the image to two-level black & white (`<a:biLevel thresh="…"/>`)
385
+ * - every pixel at/above the luminance threshold becomes white, everything below it black
386
+ * (MS-PPT > Format Picture > Picture Color > Recolor > Black and White …%)
387
+ * @example { threshold: 0.5 } // split at 50% luminance
388
+ */
389
+ biLevel?: {
390
+ /** Luminance split point as a `0.0–1.0` fraction (serialized to `thresh`, the 0–1 fraction ×100000). */
391
+ threshold: number;
392
+ };
393
+ /**
394
+ * Recolor the image by mapping one source color to another (`<a:clrChange>`)
395
+ * - every pixel matching `from` is repainted `to` — the classic "swap the flat background out" recolour
396
+ * (MS-PPT > Format Picture > Picture Color > Set Transparent Color is the single-colour sibling)
397
+ * - colors accept `HexColor` or `ThemeColor`, same as fills / `duotone`
398
+ * @example { from: '000000', to: 'FF0000' } // turn black pixels red
399
+ */
400
+ clrChange?: {
401
+ /** Source color to replace (`<a:clrFrom>`). */
402
+ from: Color;
403
+ /** Replacement color (`<a:clrTo>`). */
404
+ to: Color;
405
+ };
406
+ /**
407
+ * Raw SVG markup to embed as the image source
408
+ * - convenience for `data: 'data:image/svg+xml;base64,...'`; ts-pptx encodes it for you
409
+ * - ignored when `data` or `path` is also provided
410
+ * @example '<svg viewBox="0 0 24 24">...</svg>'
411
+ */
412
+ svg?: string;
413
+ }
414
+ type ImageProps = ImageBaseProps & (DataOrPathRequiredProps | (DataOrPathProps & {
415
+ svg: string;
416
+ }));
417
+ /**
418
+ * Add media (audio/video) to slide
419
+ * Requires either `data` or `path`; online media requires `link`.
420
+ */
421
+ interface MediaBaseProps extends PositionProps, ObjectNameProps {
422
+ /**
423
+ * Cover image
424
+ * @default "play button" image, gray background
425
+ */
426
+ cover?: string;
427
+ /**
428
+ * media file extension
429
+ * - use when the media file path does not already have an extension, ex: "/folder/SomeSong"
430
+ * @default extension from file provided
431
+ */
432
+ extn?: string;
433
+ /**
434
+ * Loop playback indefinitely (PowerPoint "Playback > Loop until Stopped")
435
+ * - emits a slide timing tree so the embedded audio/video repeats when played
436
+ * - not supported for `type: 'online'` (e.g. YouTube) embeds
437
+ * @default false
438
+ */
439
+ loop?: boolean;
440
+ /**
441
+ * Total number of times to play the media (a finite loop), ex: `3` plays it three times
442
+ * - ignored when `loop` is `true` (which repeats forever)
443
+ * - not supported for `type: 'online'` (e.g. YouTube) embeds
444
+ */
445
+ loopCount?: number;
446
+ }
447
+ /**
448
+ * Add an embedded OLE object (PowerPoint's Insert ▸ Object ▸ Create from File) to a slide.
449
+ *
450
+ * The payload's bytes travel inside the `.pptx` (in `ppt/embeddings/`), so double-clicking the
451
+ * object in PowerPoint opens the source document in place. Requires either `data` or `path`.
452
+ * Linked objects (`<p:link>` to a file outside the package) are not supported.
453
+ */
454
+ interface OleObjectBaseProps extends PositionProps, ObjectNameProps {
455
+ /**
456
+ * Picture of the embedded document shown on the slide — a raster image `path` (Node/local)
457
+ * or base64 `data:` URI.
458
+ * - the library is Node-first and cannot render an Office document, so when this is omitted a
459
+ * neutral gray placeholder is embedded; PowerPoint draws the live object over it, but every
460
+ * other consumer (and PowerPoint's own `mc:Fallback` path) shows exactly what is supplied here
461
+ * - supply a real screenshot whenever the deck is meant to read correctly outside PowerPoint
462
+ * @example { path: 'assets/budget-preview.png' }
463
+ */
464
+ cover?: {
465
+ path?: string;
466
+ data?: string;
467
+ };
468
+ /**
469
+ * Payload file extension, used to name the embedded part and to pick the content type,
470
+ * relationship type, and default `progId`.
471
+ * - inferred from `data`'s MIME, else `path`'s extension, else `progId`
472
+ * - anything that is not a known Office package extension (`xlsx`/`xlsm`/`docx`/`docm`/`pptx`/`pptm`)
473
+ * is embedded as a generic OLE blob part named `.bin`
474
+ * @example 'xlsx'
475
+ */
476
+ extn?: string;
477
+ /**
478
+ * OLE server ProgID — what PowerPoint launches on double-click.
479
+ * - defaults from the resolved extension (`xlsx` → `Excel.Sheet.12`, `docx` → `Word.Document.12`,
480
+ * `pptx` → `PowerPoint.Show.12`, anything else → `Package`)
481
+ * @example 'Excel.Sheet.12'
482
+ */
483
+ progId?: string;
484
+ /**
485
+ * Display the object as its application icon instead of a document preview (`showAsIcon`).
486
+ * - the `cover` image is still what gets drawn, so supply an icon-looking preview to match
487
+ * @default false
488
+ */
489
+ showAsIcon?: boolean;
490
+ /**
491
+ * Native size of the preview image in EMU (`imgW`/`imgH`), which PowerPoint uses to keep the
492
+ * object's aspect ratio when it re-renders the embedded document.
493
+ * - defaults to the object's own `w`/`h` converted to EMU
494
+ */
495
+ imgW?: number;
496
+ /** @see {@link imgW} */
497
+ imgH?: number;
498
+ }
499
+ /**
500
+ * Options for `slide.addOleObject()`. Requires either `data` (base64, with or without a
501
+ * `data:...;base64,` header) or `path` (a local/remote file read at export time).
502
+ *
503
+ * Sizing note: `w`/`h` default to 4 × 3 inches rather than being measured, since the library
504
+ * does not open the embedded document.
505
+ */
506
+ type OleObjectProps = OleObjectBaseProps & DataOrPathRequiredProps;
507
+ type MediaProps = MediaBaseProps & ((DataOrPathRequiredProps & {
508
+ /**
509
+ * Media type
510
+ */
511
+ type: Exclude<MediaType, 'online'>;
512
+ /**
513
+ * Optional video embed link metadata.
514
+ */
515
+ link?: string;
516
+ }) | (DataOrPathProps & {
517
+ /**
518
+ * Use 'online' to embed a YouTube video (only supported in recent versions of PowerPoint)
519
+ */
520
+ type: 'online';
521
+ /**
522
+ * video embed link
523
+ * - works with YouTube
524
+ * - other sites may not show correctly in PowerPoint
525
+ * @example 'https://www.youtube.com/embed/Dph6ynRVyUc' // embed a youtube video
526
+ */
527
+ link: string;
528
+ }));
529
+ //#endregion
530
+ //#region src/types/text.d.ts
531
+ interface TextBaseProps {
532
+ /**
533
+ * Horizontal alignment
534
+ *
535
+ * When a shape's text is an array of runs, set this on **every run** of a paragraph.
536
+ * {@link breakLine} is not the only paragraph boundary: two adjacent runs whose `align`
537
+ * differs start a new one, so stating it on the opening run alone splits the paragraph in
538
+ * two. That is the mirror of {@link bullet}, {@link paraMarginLeft} and {@link paraIndent},
539
+ * which are read from the opening run only. Neither mistake changes the run count — the
540
+ * only symptom is a differently shaped paragraph, with no error.
541
+ * @default 'left'
542
+ */
543
+ align?: HAlign;
544
+ /**
545
+ * Bold style
546
+ * @default false
547
+ */
548
+ bold?: boolean;
549
+ /**
550
+ * Add a line-break
551
+ * @default false
552
+ */
553
+ breakLine?: boolean;
554
+ /**
555
+ * Preset text warp / WordArt shape (`<a:bodyPr><a:prstTxWarp prst="..">`), which
556
+ * bends the text along a preset path (arch, circle, wave, …). The value is an
557
+ * OOXML `ST_TextShapeType` preset name.
558
+ * @example 'textArchUp' // bend text along an upward arch (e.g. a label following a ring/arc)
559
+ * @example 'textCircle'
560
+ */
561
+ textWarp?: string;
562
+ /**
563
+ * Add standard or custom bullet
564
+ * - use `true` for standard bullet
565
+ * - pass object options for custom bullet
566
+ * - `false` (and omitting the option) is the *explicit off*: it writes `<a:buNone/>`
567
+ * plus `marL="0" indent="0"`, which overrides whatever bullet the layout's or
568
+ * master's list style sets for this level
569
+ * - `'inherit'` states nothing at all — no bullet child and no margin attributes — so
570
+ * the list style keeps reaching the paragraph. This is the one state omission
571
+ * cannot spell, because omitting the option means `false` here for compatibility
572
+ *
573
+ * The margins are only a *default* of the bullet state: {@link paraMarginLeft} and
574
+ * {@link paraIndent} state `@marL`/`@indent` independently in any of the three, including
575
+ * an inherited margin under a drawn bullet.
576
+ *
577
+ * When a shape's text is an array of runs, state this on the **opening run only**. A run
578
+ * that draws a bullet starts a new paragraph by itself, so repeating it — the placement
579
+ * that {@link align} requires — turns one three-run paragraph into three one-run
580
+ * paragraphs. A paragraph takes its properties from its first run.
581
+ * @default false
582
+ */
583
+ bullet?: boolean | 'inherit' | {
584
+ /**
585
+ * Bullet type
586
+ * @default bullet
587
+ */
588
+ type?: 'bullet' | 'number';
589
+ /**
590
+ * Bullet character code (unicode)
591
+ * @example '25BA' // 'BLACK RIGHT-POINTING POINTER' (U+25BA)
592
+ */
593
+ characterCode?: string;
594
+ /**
595
+ * Bullet glyph font typeface (`<a:buFont/>`), e.g. for symbol-font bullets
596
+ * @example 'Wingdings' // render `characterCode` using the Wingdings font
597
+ */
598
+ fontFace?: string;
599
+ /**
600
+ * Bullet glyph size as a percentage of the run's text size (25–400)
601
+ * @default 100
602
+ * @example 80 // bullet glyph is 80% of the text size
603
+ */
604
+ size?: number;
605
+ /**
606
+ * Indentation (space between bullet and text) (points)
607
+ * @default 27 // DEF_BULLET_MARGIN
608
+ * @example 10 // Indents text 10 points from bullet
609
+ */
610
+ indent?: number;
611
+ /**
612
+ * Number type
613
+ * @example 'romanLcParenR' // roman numerals lower-case with paranthesis right
614
+ */
615
+ numberType?: 'alphaLcParenBoth' | 'alphaLcParenR' | 'alphaLcPeriod' | 'alphaUcParenBoth' | 'alphaUcParenR' | 'alphaUcPeriod' | 'arabicParenBoth' | 'arabicParenR' | 'arabicPeriod' | 'arabicPlain' | 'romanLcParenBoth' | 'romanLcParenR' | 'romanLcPeriod' | 'romanUcParenBoth' | 'romanUcParenR' | 'romanUcPeriod';
616
+ /**
617
+ * Number bullets start at
618
+ * @default 1
619
+ * @example 10 // numbered bullets start with 10
620
+ */
621
+ numberStartAt?: number;
622
+ /**
623
+ * Image to use as the bullet glyph ("picture bullet", `<a:buBlip>`)
624
+ * - supply an image `path` (filesystem/URL) or base64 `data` (same forms as `addImage()`)
625
+ * - raster formats (PNG/JPG/GIF) and SVG are supported; use `size` to scale relative to the text height
626
+ * - SVG bullets embed a PNG preview plus the SVG (the same dual-rel handling as `addImage()`)
627
+ * - takes precedence over `type`/`characterCode` when set
628
+ * @example image: { path: 'images/star.png' }
629
+ * @example image: { data: 'image/png;base64,iVBOR...' }
630
+ * @example image: { path: 'images/star.svg' }
631
+ */
632
+ image?: {
633
+ path?: string;
634
+ data?: string;
635
+ };
636
+ /**
637
+ * Relationship id assigned to a picture-bullet image (`<a:blip r:embed>`)
638
+ * - for SVG bullets this is the PNG-preview rel; the SVG rel is `_rIdSvg`
639
+ * @internal populated by `addText()`; do not set directly
640
+ */
641
+ _rId?: number;
642
+ /**
643
+ * Relationship id of the SVG image for an SVG picture bullet (`<asvg:svgBlip r:embed>`)
644
+ * @internal populated by `addText()`; do not set directly
645
+ */
646
+ _rIdSvg?: number;
647
+ /**
648
+ * Bullet glyph color (separate from the text run color)
649
+ * @example 'FF0000' // red bullet
650
+ */
651
+ color?: HexColor;
652
+ };
653
+ /**
654
+ * Text capitalization (`a:rPr/@cap`, `ST_TextCapsType`)
655
+ * - `'all'` = ALL CAPS
656
+ * - `'small'` = Small Caps
657
+ * - `'none'` = the *explicit off*: it writes `cap="none"`, which overrides a capitalization
658
+ * the run would otherwise inherit. Omitting the option states nothing and lets that
659
+ * inheritance stand
660
+ * - PowerPoint: Font > Effects > All Caps / Small Caps
661
+ * @default (unset) inherit
662
+ */
663
+ caps?: 'none' | 'small' | 'all';
664
+ /**
665
+ * Text color
666
+ * - `HexColor` or `ThemeColor`
667
+ * - MS-PPT > Format Shape > Text Options > Text Fill & Outline > Text Fill > Color
668
+ * @example 'FF0000' // hex color (red)
669
+ * @example SchemeColor.text1 // Theme color (Text1)
670
+ */
671
+ color?: Color;
672
+ /**
673
+ * Font face name
674
+ *
675
+ * Applied to the Latin (`<a:latin>`) and complex-script (`<a:cs>`) font slots, matching
676
+ * how PowerPoint writes a font picked from the UI. The East Asian slot (`<a:ea>`) is left
677
+ * to inherit from the theme unless `fontFaceEA` is set — forcing a Latin-only face into the
678
+ * East Asian slot duplicates/ghosts text in Office 365.
679
+ * @example 'Arial' // Arial font
680
+ */
681
+ fontFace?: string;
682
+ /**
683
+ * East Asian font face name (`<a:ea>` slot), used to render CJK (Chinese/Japanese/Korean) glyphs
684
+ *
685
+ * Set this when the East Asian font differs from `fontFace`. When omitted, `<a:ea>` inherits the
686
+ * theme East Asian font, which is what PowerPoint does for Latin fonts.
687
+ * @example '微軟正黑體' // render East Asian glyphs with Microsoft JhengHei
688
+ */
689
+ fontFaceEA?: string;
690
+ /**
691
+ * Font size
692
+ * @example 12 // Font size 12
693
+ */
694
+ fontSize?: number;
695
+ /**
696
+ * Text highlight color (hex format)
697
+ * @example 'FFFF00' // yellow
698
+ */
699
+ highlight?: HexColor;
700
+ /**
701
+ * italic style
702
+ * @default false
703
+ */
704
+ italic?: boolean;
705
+ /**
706
+ * language
707
+ * - ISO 639-1 standard language code
708
+ * @default 'en-US' // english US
709
+ * @example 'fr-CA' // french Canadian
710
+ */
711
+ lang?: string;
712
+ /**
713
+ * First-line indent (points) — `a:pPr/@indent`, the offset of the paragraph's FIRST line
714
+ * from {@link paraMarginLeft}. Negative hangs the first line to the left of the body, which
715
+ * is what a bulleted paragraph does; positive indents it to the right, the "first line
716
+ * indented" prose form. PowerPoint: Paragraph > Indentation > Special.
717
+ * - `'inherit'` writes no `@indent` at all, so the paragraph takes whatever its list style
718
+ * (`a:lstStyle` → placeholder → layout → master) sets — the same third state
719
+ * {@link bullet} spells, on the attribute beside it
720
+ * - omitting the option keeps the bullet-derived default: a drawn bullet hangs the first
721
+ * line by its margin, `bullet: false` writes `indent="0"`, `bullet: 'inherit'` writes
722
+ * nothing
723
+ * - a value here overrides all of those, in every bullet state
724
+ * @example -18 // hang the first line 18pt left of the body text
725
+ * @example 18 // indent the first line 18pt, prose style
726
+ * @example 'inherit' // keep the list style's indent, even on a bulleted paragraph
727
+ * @remarks Read from the **opening run** of a paragraph, like {@link bullet} and unlike
728
+ * {@link align}; a value on a continuation run is ignored.
729
+ */
730
+ paraIndent?: number | 'inherit';
731
+ /**
732
+ * Left margin of the paragraph (points) — `a:pPr/@marL`, where the paragraph's body text
733
+ * starts. This is the paragraph's own margin, not the text frame's internal padding
734
+ * (`margin`) and not the discrete outline level (`indentLevel`, which writes `a:p/@lvl`).
735
+ * PowerPoint: Paragraph > Indentation > Before text.
736
+ * - `'inherit'` writes no `@marL` at all, so the paragraph takes whatever its list style
737
+ * (`a:lstStyle` → placeholder → layout → master) sets — the third state that omission
738
+ * cannot spell, since omitting it writes the bullet-derived default
739
+ * - omitting the option keeps that default: a drawn bullet writes its own margin (see
740
+ * `bullet.indent`), `bullet: false` writes `marL="0"`, `bullet: 'inherit'` writes nothing
741
+ * - a value here overrides all of those, in every bullet state
742
+ * @example 36 // body text starts 36pt (0.5in) from the frame's text edge
743
+ * @example 'inherit' // keep the list style's margin, even on a bulleted paragraph
744
+ * @remarks Read from the **opening run** of a paragraph, like {@link bullet} and unlike
745
+ * {@link align}; a value on a continuation run is ignored.
746
+ */
747
+ paraMarginLeft?: number | 'inherit';
748
+ /**
749
+ * Add a soft line-break (shift+enter) before line text content
750
+ * @default false
751
+ */
752
+ softBreakBefore?: boolean;
753
+ /**
754
+ * tab stops
755
+ * - PowerPoint: Paragraph > Tabs > Tab stop position
756
+ * @example [{ position:1 }, { position:3 }] // Set first tab stop to 1 inch, set second tab stop to 3 inches
757
+ */
758
+ tabStops?: Array<{
759
+ position: number;
760
+ alignment?: 'l' | 'r' | 'ctr' | 'dec';
761
+ }>;
762
+ /**
763
+ * text direction
764
+ * `horz` = horizontal
765
+ * `vert` = rotate 90^
766
+ * `vert270` = rotate 270^
767
+ * `wordArtVert` = stacked
768
+ * @default 'horz'
769
+ */
770
+ textDirection?: 'horz' | 'vert' | 'vert270' | 'wordArtVert';
771
+ /**
772
+ * Transparency (percent)
773
+ * - MS-PPT > Format Shape > Text Options > Text Fill & Outline > Text Fill > Transparency
774
+ * - range: 0-100
775
+ * @default 0
776
+ */
777
+ transparency?: number;
778
+ /**
779
+ * underline properties
780
+ * - PowerPoint: Font > Color & Underline > Underline Style/Underline Color
781
+ * - `style` is the full `ST_TextUnderlineType` enumeration (ECMA-376 §20.1.10.81)
782
+ * - `'none'` is the *explicit off*: it writes `a:rPr/@u="none"`, which overrides an
783
+ * underline the run would otherwise inherit from its list style, placeholder, layout or
784
+ * master. Omitting the option instead states nothing and lets that inheritance stand —
785
+ * the two are different facts, not two spellings of one.
786
+ * @default (unset) inherit
787
+ */
788
+ underline?: {
789
+ style?: 'dash' | 'dashHeavy' | 'dashLong' | 'dashLongHeavy' | 'dbl' | 'dotDash' | 'dotDashHeavy' | 'dotDotDash' | 'dotDotDashHeavy' | 'dotted' | 'dottedHeavy' | 'heavy' | 'none' | 'sng' | 'wavy' | 'wavyDbl' | 'wavyHeavy' | 'words';
790
+ color?: Color;
791
+ };
792
+ /**
793
+ * vertical alignment
794
+ * @default 'top'
795
+ */
796
+ valign?: VAlign;
797
+ }
798
+ interface TextGlowProps {
799
+ /**
800
+ * Border color (hex format)
801
+ * @example 'FF3399'
802
+ */
803
+ color?: HexColor;
804
+ /**
805
+ * opacity (0.0 - 1.0)
806
+ * @example 0.5
807
+ * 50% opaque
808
+ */
809
+ opacity?: number;
810
+ /**
811
+ * size (points)
812
+ */
813
+ size: number;
814
+ }
815
+ interface TextFitShrinkProps {
816
+ /**
817
+ * Shrink text on overflow (`<a:normAutofit>`)
818
+ */
819
+ type: 'shrink';
820
+ /**
821
+ * Font scale as a percent (0-100), mapped to `<a:normAutofit fontScale="..">`.
822
+ *
823
+ * PowerPoint normally calculates this dynamically when text overflows; set it
824
+ * explicitly to bake the scale into the generated file.
825
+ * @example 85 // render text at 85% of its nominal size
826
+ * @default undefined // attribute omitted (PowerPoint defaults to 100%)
827
+ */
828
+ fontScale?: number;
829
+ /**
830
+ * Line-space reduction as a percent (0-100), mapped to `<a:normAutofit lnSpcReduction="..">`.
831
+ * @example 20 // reduce line spacing by 20%
832
+ * @default undefined // attribute omitted (PowerPoint defaults to 0%)
833
+ */
834
+ lnSpcReduction?: number;
835
+ }
836
+ interface TextPropsOptions extends PositionProps, DataOrPathProps, TextBaseProps, ObjectNameProps {
837
+ /**
838
+ * Preset-geometry start/end angles for text frames (`shape` + these build `<a:prstGeom>`
839
+ * adjustment guides through the shared emitter — `genXmlPresetGeom` reads them whether
840
+ * the object is a shape or a styled text frame).
841
+ */
842
+ angleRange?: [number, number];
843
+ /** Preset-geometry block-arc thickness for text frames. */
844
+ arcThicknessRatio?: number;
845
+ /** Custom geometry points when a text frame uses a custom geometry shape. */
846
+ points?: GeometryPoint[];
847
+ /** Preset-geometry adjustment guides for text frames. */
848
+ shapeAdjust?: ShapeAdjustValue | ShapeAdjustValue[];
849
+ _bodyProp?: {
850
+ align?: AlignH;
851
+ anchor?: TextAnchor;
852
+ lIns?: number;
853
+ rIns?: number;
854
+ tIns?: number;
855
+ bIns?: number;
856
+ numCol?: number;
857
+ spcCol?: number;
858
+ vert?: TextVertType;
859
+ wrap?: boolean;
860
+ prstTxWarp?: string;
861
+ };
862
+ _lineIdx?: number;
863
+ baseline?: number;
864
+ /**
865
+ * Character spacing
866
+ */
867
+ charSpacing?: number;
868
+ /**
869
+ * Number of text columns in the text body
870
+ * - PowerPoint: Format Shape > Shape Options > Size & Properties > Text Box > Columns > "Number"
871
+ * - range: 1-16
872
+ * @default 1
873
+ * @example 2 // flow text into two columns
874
+ */
875
+ columns?: number;
876
+ /**
877
+ * Spacing between text columns (points)
878
+ * - PowerPoint: Format Shape > Shape Options > Size & Properties > Text Box > Columns > "Spacing"
879
+ * - only applies when `columns` > 1
880
+ * @default 0
881
+ * @example 10 // 10pt gap between columns
882
+ */
883
+ columnSpacing?: number;
884
+ /**
885
+ * Text fit options
886
+ *
887
+ * MS-PPT > Format Shape > Shape Options > Text Box > "[unlabeled group]": [3 options below]
888
+ * - 'none' = Do not Autofit
889
+ * - 'shrink' = Shrink text on overflow
890
+ * - 'resize' = Resize shape to fit text
891
+ *
892
+ * **Measured fit:** if you register the box's font with
893
+ * {@link TsPptx.registerFontMetrics}, both `'shrink'` and `'resize'` are
894
+ * **measured at export time**, so the text renders correctly in headless renderers
895
+ * and on plain file-open (no edit/resize needed):
896
+ * - `'shrink'` computes the largest `fontScale` at which the wrapped text fits and
897
+ * bakes `<a:normAutofit fontScale=…/>`.
898
+ * - `'resize'` computes the height the text needs and bakes it into the shape's
899
+ * `a:ext/@cy` (adjusting `a:off/@y` per vertical anchor), the marker being
900
+ * `<a:spAutoFit/>`.
901
+ * Without registered metrics they fall back to the bare flag (`<a:normAutofit/>` /
902
+ * `<a:spAutoFit/>`, which only PowerPoint recomputes on edit) and warn once.
903
+ *
904
+ * **Note** Bare `'shrink'`/`'resize'` (no metrics) only take effect after editing
905
+ * text / resizing the shape; PowerPoint calculates the result then. The object form
906
+ * of `'shrink'` always bakes the explicit values you pass.
907
+ * @example 'shrink' // measured when metrics are registered; else bare <a:normAutofit/>
908
+ * @example 'resize' // measured when metrics are registered; else bare <a:spAutoFit/>
909
+ * @example { type: 'shrink', fontScale: 85, lnSpcReduction: 20 } // pre-shrink with explicit values
910
+ * @default "none"
911
+ */
912
+ fit?: 'none' | 'shrink' | 'resize' | TextFitShrinkProps;
913
+ /**
914
+ * Shape fill
915
+ * @example { color:'FF0000' } // hex color (red)
916
+ * @example { color:'0088CC', transparency:50 } // hex color, 50% transparent
917
+ * @example { color:SchemeColor.accent1 } // theme color Accent1
918
+ */
919
+ fill?: ShapeFillProps;
920
+ /**
921
+ * Flip shape horizontally?
922
+ * @default false
923
+ */
924
+ flipH?: boolean;
925
+ /**
926
+ * Flip shape vertical?
927
+ * @default false
928
+ */
929
+ flipV?: boolean;
930
+ glow?: TextGlowProps;
931
+ hyperlink?: HyperlinkProps;
932
+ indentLevel?: number;
933
+ isTextBox?: boolean;
934
+ line?: ShapeLineProps;
935
+ /**
936
+ * Line spacing (pt)
937
+ * - PowerPoint: Paragraph > Indents and Spacing > Line Spacing: > "Exactly"
938
+ * @example 28 // 28pt
939
+ */
940
+ lineSpacing?: number;
941
+ /**
942
+ * line spacing multiple (percent)
943
+ * - range: 0.0-9.99
944
+ * - PowerPoint: Paragraph > Indents and Spacing > Line Spacing: > "Multiple"
945
+ * @example 1.5 // 1.5X line spacing
946
+ */
947
+ lineSpacingMultiple?: number;
948
+ /**
949
+ * Margin (inches) — the text-frame internal margin/padding
950
+ * - PowerPoint: Format Shape > Shape Options > Size & Properties > Text Box > Left/Right/Top/Bottom margin (shown in inches)
951
+ * - array order is `[top, right, bottom, left]`
952
+ * - a value `>= 1` is honored as inches but warns once (it is likely a legacy points value; divide by 72)
953
+ * @default (unset) PowerPoint's "Normal" internal margin [0.05", 0.1", 0.05", 0.1"]
954
+ * @example 0 // Top/Right/Bottom/Left margin 0
955
+ * @example 0.1 // Top/Right/Bottom/Left margin 0.1 inch
956
+ * @example [0.05, 0.1, 0.05, 0.1] // top 0.05", right 0.1", bottom 0.05", left 0.1"
957
+ */
958
+ margin?: Margin;
959
+ outline?: {
960
+ color: Color;
961
+ size: number;
962
+ };
963
+ paraSpaceAfter?: number;
964
+ paraSpaceBefore?: number;
965
+ /**
966
+ * Placeholder type
967
+ * - when the value matches a placeholder defined on the slide layout/master, this text
968
+ * inherits that placeholder's position and formatting
969
+ * - otherwise the text shape is promoted to a standalone placeholder of this type, emitting
970
+ * a real `<p:ph type="...">`. Use `placeholder: 'title'` to give a slide an accessible
971
+ * title (PowerPoint's accessibility checker otherwise reports "Missing Slide Title")
972
+ * - values: 'title' | 'body' | et. al.
973
+ * @example 'title'
974
+ * @see https://learn.microsoft.com/en-us/office/vba/api/powerpoint.ppplaceholdertype
975
+ */
976
+ placeholder?: string;
977
+ /**
978
+ * Rounded rectangle radius (only for ShapeType.roundRect)
979
+ * - values: 0.0 to 1.0
980
+ * @default 0
981
+ */
982
+ rectRadius?: number;
983
+ /**
984
+ * Rotation (degrees)
985
+ * - range: -360 to 360
986
+ * @default 0
987
+ * @example 180 // rotate 180 degrees
988
+ */
989
+ rotate?: number;
990
+ /**
991
+ * Whether to enable right-to-left mode
992
+ * @default false
993
+ */
994
+ rtlMode?: boolean;
995
+ shadow?: ShadowProps;
996
+ shape?: SHAPE_NAME;
997
+ /**
998
+ * Strikethrough (`a:rPr/@strike`, `ST_TextStrikeType` — ECMA-376 §20.1.10.78)
999
+ * - `true` is `'sngStrike'`; `'dblStrike'` is the double rule
1000
+ * - `'noStrike'` is the *explicit off*: it writes `strike="noStrike"`, which overrides a
1001
+ * strikethrough the run would otherwise inherit from its list style, placeholder, layout
1002
+ * or master
1003
+ * - `false`, like leaving the option out, writes no attribute at all and so states
1004
+ * *nothing* — the run keeps whatever it inherits. This matches `bold`/`italic`, whose
1005
+ * falsy arm is likewise an omission; reach for `'noStrike'` when the intent is "not
1006
+ * struck" rather than "unspecified"
1007
+ * @default (unset) inherit
1008
+ */
1009
+ strike?: boolean | 'noStrike' | 'sngStrike' | 'dblStrike';
1010
+ subscript?: boolean;
1011
+ superscript?: boolean;
1012
+ /**
1013
+ * Vertical alignment
1014
+ * @default middle
1015
+ */
1016
+ valign?: VAlign;
1017
+ /**
1018
+ * Advanced/legacy escape hatch for the full `ST_TextVerticalType` range (e.g. `eaVert`,
1019
+ * `mongolianVert`, `wordArtVert`). Prefer {@link TextBaseProps.textDirection} for the common
1020
+ * cases; both map to `a:bodyPr@vert`.
1021
+ */
1022
+ vert?: TextVertType;
1023
+ /**
1024
+ * Text wrap
1025
+ * @default true
1026
+ */
1027
+ wrap?: boolean;
1028
+ }
1029
+ interface TextProps {
1030
+ text?: string | number;
1031
+ options?: TextPropsOptions;
1032
+ /**
1033
+ * Raw OMML (Office MathML) for a native, editable PowerPoint equation. By default it is emitted
1034
+ * as its own centered display-math paragraph (`<a14:m><m:oMathPara><m:oMath>…`) and `text` is
1035
+ * ignored; set `inline` to instead flow it as an equation run mid-paragraph. Accepts either the
1036
+ * inner OMML (children of `<m:oMath>`), a full `<m:oMath>…</m:oMath>`, or a full
1037
+ * `<m:oMathPara>…</m:oMathPara>`; the `m:` prefix is resolved by the wrapper, so the markup does
1038
+ * not need its own namespace declarations.
1039
+ * This is the raw-OMML entry point. To author from LaTeX or MathML, convert with
1040
+ * `latexToOmml()` / `mathmlToOmml()` from the `@shbernal/ts-pptx/math` subpath.
1041
+ * @example { math: '<m:r><m:t>x^2+1=y</m:t></m:r>' } // raw OMML
1042
+ * @example import { latexToOmml } from '@shbernal/ts-pptx/math'; ({ math: latexToOmml('x^2+1=y') })
1043
+ */
1044
+ math?: string;
1045
+ /**
1046
+ * Emit this item's `math` equation *inline* — an `<a14:m><m:oMath>` run flowing mid-paragraph
1047
+ * between the surrounding plain text runs — instead of as its own centered display-math
1048
+ * paragraph. Has no effect unless `math` is set. Pair with the bare-`<m:oMath>` inline form of
1049
+ * the equation: `latexToOmml(tex, { display: false })` or `mathmlToOmml(mathml)`.
1050
+ * @example addText([{ text: 'where ' }, { math: latexToOmml('x^2+1=y', { display: false }), inline: true }, { text: ' holds' }])
1051
+ */
1052
+ inline?: boolean;
1053
+ }
1054
+ /**
1055
+ * Options for layout-time text measurement ({@link TsPptx.measureText}).
1056
+ * Inches for width, points for type/spacing — the consumer-facing units. The
1057
+ * measured face must have metrics registered via {@link TsPptx.registerFontMetrics}
1058
+ * (a named face without exact metrics uses a conservative heuristic; an unnamed
1059
+ * theme-default face is unmeasurable).
1060
+ */
1061
+ interface MeasureTextOptions {
1062
+ /** Available text width in inches (the box width minus L/R inset, unless `insetIn` is given). */
1063
+ wIn: number;
1064
+ /** Font size in points. */
1065
+ fontSize: number;
1066
+ /** Font family name, as used in `fontFace`. Required for an exact measure; an unnamed face is unmeasurable. */
1067
+ fontFace?: string;
1068
+ bold?: boolean;
1069
+ italic?: boolean;
1070
+ /** Character spacing in points. */
1071
+ charSpacing?: number;
1072
+ /** Exact line spacing in points (overrides `lineSpacingMultiple`). */
1073
+ lineSpacing?: number;
1074
+ /** Line spacing as a multiple of single (e.g. `1.5`). */
1075
+ lineSpacingMultiple?: number;
1076
+ /** Space before each paragraph, in points. */
1077
+ paraSpaceBefore?: number;
1078
+ /** Space after each paragraph, in points. */
1079
+ paraSpaceAfter?: number;
1080
+ /** L/R text inset in inches; when set, subtracted from `wIn` on both sides (pass a raw box width). */
1081
+ insetIn?: number;
1082
+ }
1083
+ /**
1084
+ * Result of {@link TsPptx.measureText}. Heights err **tall** (conservative) —
1085
+ * they match the value the export-time autofit bake uses, so the laid-out height is
1086
+ * ≥ what PowerPoint/LibreOffice render. Use it to grow a container; for an overflow
1087
+ * check it may slightly over-report (good for a warning, not a hard gate).
1088
+ */
1089
+ interface TextMeasurement {
1090
+ /** Laid-out height in inches at the given `fontSize` (conservative/tall). */
1091
+ heightIn: number;
1092
+ /** Number of wrapped lines (conservative — the model wraps marginally early). */
1093
+ lineCount: number;
1094
+ /**
1095
+ * Width in inches of the widest laid-out line (conservative — the model wraps
1096
+ * marginally early, so this errs slightly wide). With an unconstrained `wIn` it
1097
+ * is the natural single-line width; constrained, it is the widest wrapped line.
1098
+ * A box set to this width will not re-wrap the text.
1099
+ */
1100
+ widestLineIn: number;
1101
+ /** `false` only for an unnamed theme-default face that could not be measured. */
1102
+ measurable: boolean;
1103
+ /**
1104
+ * The **named** faces laid out with the conservative average-advance heuristic
1105
+ * instead of their real metrics — i.e. faces with no registered metrics. Empty
1106
+ * when every run was measured exactly (and for an unmeasurable result, which
1107
+ * guessed nothing). The numbers stay conservative (they err tall/wide), but a
1108
+ * non-empty list means they are an approximation, not a measurement; register
1109
+ * the face via {@link TsPptx.registerFontMetrics} for an exact result.
1110
+ */
1111
+ approximatedFaces: string[];
1112
+ /**
1113
+ * Code points in the measured text — sorted, deduplicated — whose run resolved to a
1114
+ * **registered** face that has no glyph for them. Empty for fully covered text.
1115
+ *
1116
+ * Unlike everything else here, a non-empty list means the numbers are **not reliably
1117
+ * conservative**. PowerPoint renders such a code point from a substituted face and
1118
+ * measures it in that face's advances; this model has no fallback and charges the
1119
+ * registered font's `.notdef` advance, which is unrelated to the glyph that paints. A
1120
+ * `.notdef` wider than the real glyph over-reports (harmless); a narrower one
1121
+ * under-reports the width and can drop a line, so `heightIn` may come back **short**
1122
+ * and the text overflow. Register a face that covers them (or set an explicit
1123
+ * `fontFace` on those runs) before trusting the height.
1124
+ *
1125
+ * Faces with no registered metrics are not audited — they measure through the
1126
+ * cmap-less heuristic and are reported in {@link approximatedFaces} instead.
1127
+ * `String.fromCodePoint(...uncoveredCodepoints)` renders the list.
1128
+ */
1129
+ uncoveredCodepoints: number[];
1130
+ /** True if the text fits a box of inner height `hIn` (inches) at full size. */
1131
+ fitsBox: (hIn: number) => boolean;
1132
+ /** The `fontScale` (percent) that fits inner height `hIn`; `100` if it already fits, never below the shrink floor. */
1133
+ shrinkScaleFor: (hIn: number) => number;
1134
+ }
1135
+ /** Options for {@link TsPptx.overflowsBox}: a measure plus the box inner height to test against. */
1136
+ interface OverflowBoxOptions extends MeasureTextOptions {
1137
+ /** Box inner height in inches to test for overflow. */
1138
+ hIn: number;
1139
+ }
1140
+ /**
1141
+ * One cell's computed rectangle from {@link TsPptx.tableLayout}. All values are
1142
+ * inches; `x`/`y` are absolute (offset from the table's `x`/`y`). For a merged cell,
1143
+ * `row`/`col` are the top-left origin and `wIn`/`hIn` cover the whole span; the
1144
+ * cells it covers are not emitted separately.
1145
+ */
1146
+ interface TableCellLayout {
1147
+ /** Zero-based grid row of the cell's top-left origin. */
1148
+ row: number;
1149
+ /** Zero-based grid column of the cell's top-left origin. */
1150
+ col: number;
1151
+ /** Number of rows the cell spans (1 if not merged). */
1152
+ rowSpan: number;
1153
+ /** Number of columns the cell spans (1 if not merged). */
1154
+ colSpan: number;
1155
+ /** Left edge in inches (absolute). */
1156
+ xIn: number;
1157
+ /** Top edge in inches (absolute). */
1158
+ yIn: number;
1159
+ /** Outer cell width in inches (sum of spanned column widths). */
1160
+ wIn: number;
1161
+ /** Outer cell height in inches (sum of spanned row heights). */
1162
+ hIn: number;
1163
+ /**
1164
+ * `true` when `hIn`/`yIn` are pinned by an explicit `rowH` (array or scalar) or
1165
+ * table `h`; `false` when the row is auto-height and the value is a conservative
1166
+ * (tall) estimate from the same text model as {@link TsPptx.measureText}.
1167
+ */
1168
+ heightExact: boolean;
1169
+ }
1170
+ /**
1171
+ * Result of {@link TsPptx.tableLayout}: per-cell geometry plus overall table
1172
+ * bounds, for placing images/shapes over a table without rendering it. Geometry is
1173
+ * for a single, un-paginated table laid out at `opts.x`/`y`/`w`; `autoPage` paging
1174
+ * is not modeled. Widths are exact; auto-height row heights are conservative
1175
+ * estimates (see {@link TableCellLayout.heightExact}).
1176
+ */
1177
+ interface TableLayoutResult {
1178
+ /** One entry per non-merged origin cell, in row-major order. */
1179
+ cells: TableCellLayout[];
1180
+ /** Overall table width in inches (sum of column widths). */
1181
+ widthIn: number;
1182
+ /** Overall table height in inches (sum of row heights; may include estimates). */
1183
+ heightIn: number;
1184
+ /** `false` if any row height was estimated (the total errs tall, like `measureText`). */
1185
+ heightExact: boolean;
1186
+ }
1187
+ /**
1188
+ * Per-run options for a speaker-notes text run.
1189
+ * A focused subset of `TextPropsOptions`: inline formatting plus an (external URL) hyperlink.
1190
+ * Notes hyperlinks support `url` only; `slide` targets are not yet supported.
1191
+ */
1192
+ type NotesTextOptions = Pick<TextPropsOptions, 'hyperlink' | 'bold' | 'italic' | 'underline' | 'color' | 'fontSize' | 'fontFace'>;
1193
+ /** A single speaker-notes text run: text plus optional inline formatting / hyperlink. */
1194
+ interface NotesProps {
1195
+ text: string;
1196
+ options?: NotesTextOptions;
1197
+ }
1198
+ /**
1199
+ * A review comment attached to a slide (legacy ISO/IEC 29500 §13 comment).
1200
+ */
1201
+ interface CommentProps {
1202
+ /** Author display name (required). Comments sharing the same `author`+`initials` are grouped under one author entry. */
1203
+ author: string;
1204
+ /** Author initials shown in the comment marker. Defaults to letters derived from `author`. */
1205
+ initials?: string;
1206
+ /** Comment body text (required). */
1207
+ text: string;
1208
+ /** Comment marker X position in inches. @default 0.5 */
1209
+ x?: number;
1210
+ /** Comment marker Y position in inches. @default 0.5 */
1211
+ y?: number;
1212
+ /** Authored date/time as a `Date` or ISO-8601 string. Omitted from the XML when not provided. */
1213
+ date?: Date | string;
1214
+ }
1215
+ /** Internal normalized comment stored on a slide (`_comments`). x/y are inches; `date` is ISO-8601 when present. */
1216
+ interface SlideComment {
1217
+ author: string;
1218
+ initials: string;
1219
+ text: string;
1220
+ x: number;
1221
+ y: number;
1222
+ date?: string;
1223
+ }
1224
+ /** Resolved presentation-level comment author, emitted to `commentAuthors.xml`. */
1225
+ interface ResolvedCommentAuthor {
1226
+ id: number;
1227
+ name: string;
1228
+ initials: string;
1229
+ lastIdx: number;
1230
+ clrIdx: number;
1231
+ }
1232
+ /** Factory for a single inline text run. Prevents `as never` casts when building mixed-style run arrays. */
1233
+ declare function textRun(text: string | number, options?: TextPropsOptions): TextProps;
1234
+ /** Wraps a run array so TypeScript accepts it as `TextProps[]` without a cast. */
1235
+ declare function textRuns(runs: TextProps[]): TextProps[];
1236
+ //#endregion
1237
+ //#region src/types/object.d.ts
1238
+ interface PlaceholderProps extends PositionProps, TextBaseProps, ObjectNameProps {
1239
+ name: string;
1240
+ type: PLACEHOLDER_TYPE;
1241
+ /**
1242
+ * margin (inches) — text-frame internal margin; a value `>= 1` warns as a likely legacy points value
1243
+ */
1244
+ margin?: Margin;
1245
+ /**
1246
+ * Preset shape geometry for this placeholder (e.g. `'roundRect'`)
1247
+ * @default 'rect'
1248
+ */
1249
+ shape?: SHAPE_NAME;
1250
+ /**
1251
+ * Rounded rectangle corner radius (inches) when `shape: 'roundRect'`
1252
+ * - range: 0.0 to slide height/2
1253
+ */
1254
+ rectRadius?: number;
1255
+ }
1256
+ interface ObjectNameProps {
1257
+ /**
1258
+ * Object name
1259
+ * - used instead of default "Object N" name
1260
+ * - PowerPoint: Home > Arrange > Selection Pane...
1261
+ * @default 'Object 1'
1262
+ * @example 'Antenna Design 9'
1263
+ */
1264
+ objectName?: string;
1265
+ /**
1266
+ * Alt Text value ("How would you describe this object and its contents to someone who is blind?")
1267
+ * - serialized to the generated object's `p:cNvPr` `descr` attribute
1268
+ * - PowerPoint: [right-click on the object] > "Edit Alt Text..."
1269
+ * @example 'Quarterly revenue bar chart'
1270
+ */
1271
+ altText?: string;
1272
+ /**
1273
+ * Object lock flags (DrawingML `a:spLocks` / `a:picLocks` / `a:graphicFrameLocks`)
1274
+ * - restrict how the object can be manipulated in PowerPoint (e.g. prevent moving, resizing, or grouping)
1275
+ * - each flag maps 1:1 to the OOXML attribute of the same name; only flags set to `true` are emitted
1276
+ * - PowerPoint UI: Selection Pane / right-click protections (most locks are honored at edit time, not as a password)
1277
+ * - flags only apply to the object types that support them (see each flag); flags set on an unsupported
1278
+ * object type are ignored with a console warning
1279
+ * @example { noMove: true, noResize: true } // pin an object in place
1280
+ * @example { noGrp: true } // exclude from grouping
1281
+ */
1282
+ objectLock?: ObjectLockProps;
1283
+ }
1284
+ /**
1285
+ * Object lock flags. Maps to DrawingML locking elements:
1286
+ * - shapes / text boxes / placeholders → `a:spLocks`
1287
+ * - images / media → `a:picLocks`
1288
+ * - tables → `a:graphicFrameLocks`
1289
+ *
1290
+ * Each property mirrors the OOXML attribute name. A flag is only serialized for object types whose
1291
+ * locking element defines it (noted per-flag); setting an unsupported flag logs a warning and is ignored.
1292
+ */
1293
+ interface ObjectLockProps {
1294
+ /** Disallow grouping/ungrouping with other objects. (shapes, images, tables) */
1295
+ noGrp?: boolean;
1296
+ /** Disallow selecting the object. (shapes, images, tables) */
1297
+ noSelect?: boolean;
1298
+ /** Disallow moving the object. (shapes, images, tables) */
1299
+ noMove?: boolean;
1300
+ /** Disallow resizing the object. (shapes, images, tables) */
1301
+ noResize?: boolean;
1302
+ /** Disallow changing the aspect ratio. (shapes, images, tables) */
1303
+ noChangeAspect?: boolean;
1304
+ /** Disallow rotating the object. (shapes, images) */
1305
+ noRot?: boolean;
1306
+ /** Disallow editing the freeform/custom-geometry points. (shapes, images) */
1307
+ noEditPoints?: boolean;
1308
+ /** Disallow moving the shape's adjustment handles. (shapes, images) */
1309
+ noAdjustHandles?: boolean;
1310
+ /** Disallow changing arrowheads. (shapes, images) */
1311
+ noChangeArrowheads?: boolean;
1312
+ /** Disallow changing the shape type (preset geometry). (shapes, images) */
1313
+ noChangeShapeType?: boolean;
1314
+ /** Disallow editing the text body. (shapes / text boxes) */
1315
+ noTextEdit?: boolean;
1316
+ /** Disallow cropping the picture. (images) */
1317
+ noCrop?: boolean;
1318
+ /** Disallow drilling down into the graphical object (e.g. chart data). (tables) */
1319
+ noDrilldown?: boolean;
1320
+ }
1321
+ /**
1322
+ * The object descriptors a slide master and a group child both accept.
1323
+ *
1324
+ * Both surfaces take a key-tagged descriptor — one key naming the object kind, its value the
1325
+ * options for that kind — and both accepted the same six. They were written out twice, and the
1326
+ * doc on `GroupChildProps` said as much in as many words: "Uses the same key-tagged descriptor
1327
+ * shape as `SlideMasterObject`". That coupling was real and maintained by hand, which meant a
1328
+ * seventh descriptor added to one was silently missing from the other.
1329
+ *
1330
+ * Each union is now this plus what is genuinely its own — a master adds `chart` and
1331
+ * `placeholder`, a group child adds `group` — so the difference between them is the part you
1332
+ * read, and the shared vocabulary is stated once.
1333
+ */
1334
+ type CommonObjectDescriptor = {
1335
+ image: ImageProps;
1336
+ } | {
1337
+ line: ShapeProps;
1338
+ } | {
1339
+ rect: ShapeProps;
1340
+ } | {
1341
+ roundRect: ShapeProps;
1342
+ } |
1343
+ /**
1344
+ * Any preset shape, addressed by `SHAPE_NAME` (e.g. `ShapeType.ellipse`).
1345
+ * Generalizes the `line`/`rect`/`roundRect` shortcuts to every preset the
1346
+ * `addShape()` serializer supports (ellipse, triangle, chevron, …).
1347
+ *
1348
+ * A union member's comment cannot carry block tags, so this stands in for `@example`:
1349
+ * `{ shape: { type: 'ellipse', options: { x: 1, y: 1, w: 2, h: 2, fill: { color: 'FF0000' } } } }`
1350
+ */
1351
+ {
1352
+ shape: {
1353
+ type: SHAPE_NAME;
1354
+ options?: ShapeProps;
1355
+ };
1356
+ } | {
1357
+ text: {
1358
+ text: string | number | TextProps[];
1359
+ options?: TextPropsOptions;
1360
+ };
1361
+ };
1362
+ //#endregion
1363
+ //#region src/types/chart.d.ts
1364
+ type ChartAxisTickMark = 'none' | 'inside' | 'outside' | 'cross';
1365
+ /**
1366
+ * Line end cap style. Maps to the OOXML `cap` attribute on `<a:ln>` (`flat`/`sq`/`rnd`).
1367
+ */
1368
+ type LineCap = 'flat' | 'round' | 'square';
1369
+ type ChartLineDash = 'dash' | 'dashDot' | 'lgDash' | 'lgDashDot' | 'lgDashDotDot' | 'solid' | 'sysDash' | 'sysDot';
1370
+ interface OptsChartData {
1371
+ /**
1372
+ * category labels
1373
+ * @example ['Year 2000', 'Year 2010', 'Year 2020'] // single-level category axes labels
1374
+ * @example [['Year 2000', 'Year 2010', 'Year 2020'], ['Decades', '', '']] // multi-level category axes labels
1375
+ */
1376
+ labels?: string[] | string[][];
1377
+ /**
1378
+ * series name
1379
+ * @example 'Locations'
1380
+ */
1381
+ name?: string;
1382
+ /**
1383
+ * bubble sizes
1384
+ * @example [5, 1, 5, 1]
1385
+ */
1386
+ sizes?: number[];
1387
+ /**
1388
+ * category values
1389
+ * @example [2000, 2010, 2020]
1390
+ */
1391
+ values?: number[];
1392
+ /**
1393
+ * Custom text label per data point, replacing the auto-generated value label.
1394
+ * Index aligns with `values[]`. Empty string or missing entries fall back to the chart-level label settings.
1395
+ * Supported for BAR, LINE, AREA, RADAR, PIE, and DOUGHNUT chart types.
1396
+ * @example ['Low', '', 'High'] // only points 0 and 2 get custom labels
1397
+ */
1398
+ customLabels?: string[];
1399
+ /**
1400
+ * Per-data-point visual overrides (border / fill), index-aligned with `values[]`.
1401
+ * Empty (`{}`) or missing entries fall back to series/chart styling.
1402
+ * Supported for BAR, LINE, AREA, SCATTER, PIE, and DOUGHNUT chart types.
1403
+ * @example
1404
+ * pointStyles: [
1405
+ * { border: { width: 2, color: 'FF0000' } }, // point 0: red 2pt border
1406
+ * {}, // point 1: default
1407
+ * { fill: '00B050', border: { type: 'dash', color: '404040' } }, // point 2
1408
+ * ]
1409
+ */
1410
+ pointStyles?: ChartDataPointStyle[];
1411
+ /**
1412
+ * Error bars for this series (`<c:errBars>`).
1413
+ * - Supported for BAR, BAR3D, LINE, AREA, and SCATTER chart types (RADAR has no error bars in the schema).
1414
+ * - Pass a single config, or an array to draw both X and Y error bars (SCATTER/AREA only; BAR/LINE use the first entry).
1415
+ * @example { valueType: 'percentage', value: 5 } // ±5% error bars
1416
+ * @example { valueType: 'fixedVal', value: 2, barType: 'plus', noEndCap: true }
1417
+ * @example { valueType: 'cust', plusValues: [1, 2, 1], minusValues: [0.5, 1, 0.5] }
1418
+ */
1419
+ errorBars?: ChartErrorBarOptions | ChartErrorBarOptions[];
1420
+ }
1421
+ /**
1422
+ * Per-data-point style override for a chart series.
1423
+ * Each entry applies to the data point at the same index in `values[]`.
1424
+ * Unset fields fall back to the series/chart-level styling.
1425
+ */
1426
+ interface ChartDataPointStyle {
1427
+ /**
1428
+ * Data-point border (line). Reuses {@link BorderProps}.
1429
+ * - `type: 'none'` hides the border; `'dash'` draws a dashed border.
1430
+ * @example { width: 2, color: 'FF0000' }
1431
+ */
1432
+ border?: BorderProps;
1433
+ /**
1434
+ * Data-point fill color (hex), overriding `chartColors[idx]`.
1435
+ * Most meaningful on fill-based charts (BAR, AREA, PIE, DOUGHNUT).
1436
+ * @example '00B050'
1437
+ */
1438
+ fill?: HexColor;
1439
+ /**
1440
+ * Data-point pattern fill (`<a:pattFill>`), e.g. diagonal hatching, for the
1441
+ * BAR/BAR3D and SCATTER charts that emit per-point `c:dPt`. Takes precedence
1442
+ * over `fill` (OOXML allows only one fill per data point).
1443
+ *
1444
+ * When `pattern.fgColor` is omitted it defaults to this point's resolved fill
1445
+ * color (`fill` or the varied `chartColors[idx]`), giving a hatched version of
1446
+ * the bar color; if no point color is resolvable it falls back to black.
1447
+ * `pattern.bgColor` defaults to white.
1448
+ * @example { preset: 'ltUpDiag' }
1449
+ * @example { preset: 'diagCross', fgColor: 'C00000', bgColor: 'FFFFFF' }
1450
+ */
1451
+ pattern?: PatternFillProps;
1452
+ }
1453
+ /**
1454
+ * Error-bar configuration for a chart series (`<c:errBars>`).
1455
+ * Maps onto OOXML `CT_ErrBars` (errDir / errBarType / errValType / noEndCap / plus / minus / val).
1456
+ */
1457
+ interface ChartErrorBarOptions {
1458
+ /**
1459
+ * Axis the error bars measure along.
1460
+ * - `'y'` (the value axis) for BAR/BAR3D/LINE/AREA; SCATTER may also use `'x'`.
1461
+ * @default 'y'
1462
+ */
1463
+ direction?: 'x' | 'y';
1464
+ /**
1465
+ * Which sides of each marker draw a bar.
1466
+ * @default 'both'
1467
+ */
1468
+ barType?: 'both' | 'minus' | 'plus';
1469
+ /**
1470
+ * How `value` (or `plusValues`/`minusValues`) is interpreted.
1471
+ * - `'fixedVal'` — fixed amount in axis units
1472
+ * - `'percentage'` — percent of each value (e.g. `value: 5` → ±5%)
1473
+ * - `'stdDev'` — `value` standard deviations
1474
+ * - `'stdErr'` — standard error (ignores `value`)
1475
+ * - `'cust'` — explicit per-point amounts via `plusValues`/`minusValues`
1476
+ * @default 'fixedVal'
1477
+ */
1478
+ valueType?: 'cust' | 'fixedVal' | 'percentage' | 'stdDev' | 'stdErr';
1479
+ /**
1480
+ * Magnitude for `'fixedVal'`, `'percentage'`, or `'stdDev'`. Ignored for `'stdErr'` and `'cust'`.
1481
+ * @default 1
1482
+ */
1483
+ value?: number;
1484
+ /** Per-point positive magnitudes; required when `valueType === 'cust'` (unless `barType: 'minus'`). Index-aligned with `values[]`. */
1485
+ plusValues?: number[];
1486
+ /** Per-point negative magnitudes; required when `valueType === 'cust'` (unless `barType: 'plus'`). Index-aligned with `values[]`. */
1487
+ minusValues?: number[];
1488
+ /**
1489
+ * Hide the perpendicular end caps.
1490
+ * @default false
1491
+ */
1492
+ noEndCap?: boolean;
1493
+ /** Error-bar line color (hex, e.g. `'FF0000'`). */
1494
+ color?: HexColor;
1495
+ /** Error-bar line width (points). */
1496
+ size?: number;
1497
+ }
1498
+ interface OptsChartGridLine {
1499
+ /**
1500
+ * MS-PPT > Chart format > Format Major Gridlines > Line > Cap type
1501
+ * - line cap type
1502
+ * @default flat
1503
+ */
1504
+ cap?: LineCap;
1505
+ /**
1506
+ * Gridline color
1507
+ * - `HexColor` or `ThemeColor`
1508
+ * @example 'FF3399'
1509
+ * @example SchemeColor.accent1 // theme color Accent1
1510
+ */
1511
+ color?: Color;
1512
+ /**
1513
+ * Gridline size (points)
1514
+ */
1515
+ size?: number;
1516
+ /**
1517
+ * Gridline style
1518
+ */
1519
+ style?: 'solid' | 'dash' | 'dot' | 'none';
1520
+ }
1521
+ interface ChartMulti {
1522
+ type: CHART_NAME;
1523
+ data: OptsChartData[];
1524
+ options: ChartOpts;
1525
+ }
1526
+ interface ChartPropsFillLine {
1527
+ /**
1528
+ * PowerPoint: Format Chart Area/Plot > Border ["Line"]
1529
+ * @example border: {color: 'FF0000', width: 1} // hex RGB color, 1 pt line
1530
+ */
1531
+ border?: BorderProps;
1532
+ /**
1533
+ * PowerPoint: Format Chart Area/Plot Area > Fill
1534
+ *
1535
+ * Omitting `fill` leaves the area transparent (`<a:noFill/>`), as does a `fill` that
1536
+ * states neither a `color` nor a `type` — `transparency` alone is not a fill, since
1537
+ * there is no colour for the alpha to apply to.
1538
+ *
1539
+ * `type: 'image'` is not supported here and falls back to no fill with a warning: a
1540
+ * blip fill needs a media relationship on the chart part, which nothing registers.
1541
+ * @example fill: {color: '696969'} // hex RGB color value
1542
+ * @example fill: {color: SchemeColor.background2} // Theme color value
1543
+ * @example fill: {color: '696969', transparency: 50} // 50% transparent grey
1544
+ * @example fill: {type: 'gradient', gradient: {kind: 'linear', angle: 90, stops: [{position: 0, color: '0088CC'}, {position: 100, color: 'FFFFFF'}]}}
1545
+ * @example fill: {type: 'inherit'} // no fill child at all -- take the chart style's fill
1546
+ */
1547
+ fill?: ShapeFillProps;
1548
+ }
1549
+ interface ChartAreaProps extends ChartPropsFillLine {
1550
+ /**
1551
+ * Whether the chart area has rounded corners
1552
+ * - only applies when either `fill` or `border` is used
1553
+ * @default true
1554
+ */
1555
+ roundedCorners?: boolean;
1556
+ }
1557
+ interface ChartPropsBase {
1558
+ /**
1559
+ * Axis position
1560
+ */
1561
+ axisPos?: 'b' | 'l' | 'r' | 't';
1562
+ /**
1563
+ * Series colours, cycled: series (or, on a pie/doughnut, data point) `n` takes
1564
+ * `chartColors[n % chartColors.length]`, so a shorter list repeats rather than running out.
1565
+ *
1566
+ * Omitting it, or passing an empty array, both mean the same thing — the built-in default
1567
+ * palette for the chart type. Two spellings of "I named no colours"; there is no third state
1568
+ * that suppresses the fills.
1569
+ */
1570
+ chartColors?: HexColor[];
1571
+ /**
1572
+ * opacity (0 - 100)
1573
+ * @example 50 // 50% opaque
1574
+ */
1575
+ chartColorsOpacity?: number;
1576
+ dataBorder?: BorderProps;
1577
+ displayBlanksAs?: 'gap' | 'span' | 'zero';
1578
+ invertedColors?: HexColor[];
1579
+ lang?: string;
1580
+ layout?: PositionProps;
1581
+ shadow?: ShadowProps;
1582
+ /**
1583
+ * Show each bubble's size value as a data label (bubble / bubble3D charts only).
1584
+ * Has no effect on other chart types.
1585
+ * @default false
1586
+ */
1587
+ showBubbleSize?: boolean;
1588
+ /**
1589
+ * Enable data labels, with a meaning that is **overloaded per plot type** — it is not a
1590
+ * plain duplicate of {@link ChartPropsBase.showValue}:
1591
+ * - pie / doughnut: shows the **category name** (`c:showCatName`);
1592
+ * - scatter: shows **both** the value and the category name;
1593
+ * - chartEx (waterfall/funnel/…): OR-combined with `showValue` to show the **value** label.
1594
+ *
1595
+ * For the common "show the numeric value" case on standard plots, prefer `showValue`.
1596
+ * @default false
1597
+ */
1598
+ showLabel?: boolean;
1599
+ showLeaderLines?: boolean;
1600
+ /**
1601
+ * Leader line color (pie/doughnut data labels). Requires `showLeaderLines: true`.
1602
+ * When omitted, PowerPoint applies its automatic leader-line color.
1603
+ * @example 'FF0000' // red leader lines
1604
+ */
1605
+ leaderLineColor?: HexColor;
1606
+ /**
1607
+ * Leader line width, in points (pie/doughnut data labels). Requires `showLeaderLines: true`.
1608
+ * @default 0.75
1609
+ * @example 1.5
1610
+ */
1611
+ leaderLineSize?: number;
1612
+ /**
1613
+ * @default false
1614
+ */
1615
+ showLegend?: boolean;
1616
+ /**
1617
+ * @default false
1618
+ */
1619
+ showPercent?: boolean;
1620
+ /**
1621
+ * @default false
1622
+ */
1623
+ showSerName?: boolean;
1624
+ /**
1625
+ * @default false
1626
+ */
1627
+ showTitle?: boolean;
1628
+ /**
1629
+ * @default false
1630
+ */
1631
+ showValue?: boolean;
1632
+ /**
1633
+ * 3D Perspecitve
1634
+ * - range: 0-120
1635
+ * @default 30
1636
+ */
1637
+ v3DPerspective?: number;
1638
+ /**
1639
+ * Right Angle Axes
1640
+ * - Shows chart from first-person perspective
1641
+ * - Overrides `v3DPerspective` when true
1642
+ * - PowerPoint: Chart Options > 3-D Rotation
1643
+ * @default false
1644
+ */
1645
+ v3DRAngAx?: boolean;
1646
+ /**
1647
+ * X Rotation
1648
+ * - PowerPoint: Chart Options > 3-D Rotation
1649
+ * - range: 0-359.9
1650
+ * @default 30
1651
+ */
1652
+ v3DRotX?: number;
1653
+ /**
1654
+ * Y Rotation
1655
+ * - range: 0-359.9
1656
+ * @default 30
1657
+ */
1658
+ v3DRotY?: number;
1659
+ /**
1660
+ * PowerPoint: Format Chart Area (Fill & Border/Line)
1661
+ */
1662
+ chartArea?: ChartAreaProps;
1663
+ /**
1664
+ * PowerPoint: Format Plot Area (Fill & Border/Line)
1665
+ */
1666
+ plotArea?: ChartPropsFillLine;
1667
+ /**
1668
+ * Per-series style overrides.
1669
+ * Element at index N applies to the series at data[N].
1670
+ * Missing indices or unset fields fall back to the chart-level option.
1671
+ */
1672
+ seriesOptions?: ChartSeriesOpts[];
1673
+ }
1674
+ interface ChartPropsAxisCat {
1675
+ /**
1676
+ * Multi-Chart prop: array of cat axes
1677
+ */
1678
+ catAxes?: ChartPropsAxisCat[];
1679
+ catAxisBaseTimeUnit?: string;
1680
+ catAxisCrossesAt?: number | 'autoZero';
1681
+ catAxisHidden?: boolean;
1682
+ catAxisLabelColor?: string;
1683
+ catAxisLabelFontBold?: boolean;
1684
+ catAxisLabelFontFace?: string;
1685
+ catAxisLabelFontItalic?: boolean;
1686
+ catAxisLabelFontSize?: number;
1687
+ /**
1688
+ * Number format code for the category (X) axis labels on scatter and bubble charts.
1689
+ * Falls back to `valAxisLabelFormatCode` when not set.
1690
+ * - Example: `'0.00'`, `'#,##0'`, `'mmm yyyy'`
1691
+ * - PowerPoint: Format Axis > Number > Format Code
1692
+ */
1693
+ catAxisLabelFormatCode?: string;
1694
+ catAxisLabelFrequency?: string;
1695
+ catAxisLabelPos?: 'none' | 'low' | 'high' | 'nextTo';
1696
+ catAxisLabelRotate?: number;
1697
+ catAxisLineColor?: string;
1698
+ catAxisLineShow?: boolean;
1699
+ catAxisLineSize?: number;
1700
+ catAxisLineStyle?: 'solid' | 'dash' | 'dot';
1701
+ catAxisMajorTickMark?: ChartAxisTickMark;
1702
+ catAxisMajorTimeUnit?: string;
1703
+ catAxisMajorUnit?: number;
1704
+ catAxisMaxVal?: number;
1705
+ catAxisMinorTickMark?: ChartAxisTickMark;
1706
+ catAxisMinorTimeUnit?: string;
1707
+ catAxisMinorUnit?: number;
1708
+ catAxisMinVal?: number;
1709
+ catAxisMultiLevelLabels?: boolean;
1710
+ catAxisOrientation?: 'minMax' | 'maxMin';
1711
+ catAxisTitle?: string;
1712
+ catAxisTitleColor?: string;
1713
+ catAxisTitleFontFace?: string;
1714
+ catAxisTitleFontSize?: number;
1715
+ catAxisTitleRotate?: number;
1716
+ catGridLine?: OptsChartGridLine;
1717
+ catLabelFormatCode?: string;
1718
+ /**
1719
+ * Whether data should use secondary category axis (instead of primary)
1720
+ * @default false
1721
+ */
1722
+ secondaryCatAxis?: boolean;
1723
+ showCatAxisTitle?: boolean;
1724
+ }
1725
+ interface ChartPropsAxisSer {
1726
+ serAxisBaseTimeUnit?: string;
1727
+ serAxisHidden?: boolean;
1728
+ serAxisLabelColor?: string;
1729
+ serAxisLabelFontBold?: boolean;
1730
+ serAxisLabelFontFace?: string;
1731
+ serAxisLabelFontItalic?: boolean;
1732
+ serAxisLabelFontSize?: number;
1733
+ serAxisLabelFrequency?: string;
1734
+ serAxisLabelPos?: 'none' | 'low' | 'high' | 'nextTo';
1735
+ serAxisLineColor?: string;
1736
+ serAxisLineShow?: boolean;
1737
+ serAxisMajorTimeUnit?: string;
1738
+ serAxisMajorUnit?: number;
1739
+ serAxisMinorTimeUnit?: string;
1740
+ serAxisMinorUnit?: number;
1741
+ serAxisOrientation?: string;
1742
+ serAxisTitle?: string;
1743
+ serAxisTitleColor?: string;
1744
+ serAxisTitleFontFace?: string;
1745
+ serAxisTitleFontSize?: number;
1746
+ serAxisTitleRotate?: number;
1747
+ serGridLine?: OptsChartGridLine;
1748
+ serLabelFormatCode?: string;
1749
+ showSerAxisTitle?: boolean;
1750
+ }
1751
+ interface ChartPropsAxisVal {
1752
+ /**
1753
+ * Whether data should use secondary value axis (instead of primary)
1754
+ * @default false
1755
+ */
1756
+ secondaryValAxis?: boolean;
1757
+ showValAxisTitle?: boolean;
1758
+ /**
1759
+ * Multi-Chart prop: array of val axes
1760
+ */
1761
+ valAxes?: ChartPropsAxisVal[];
1762
+ valAxisCrossesAt?: number | 'autoZero';
1763
+ /**
1764
+ * Controls where axis values are plotted relative to tick marks
1765
+ * - `'between'` = values plotted between tick marks (default for bar/column/line)
1766
+ * - `'midCat'` = values plotted on tick marks (default for scatter/area)
1767
+ * - PowerPoint: Format Axis > Axis Options > Axis crosses > On tick marks / Between tick marks
1768
+ */
1769
+ valAxisCrossBetween?: 'between' | 'midCat';
1770
+ valAxisDisplayUnit?: 'billions' | 'hundredMillions' | 'hundreds' | 'hundredThousands' | 'millions' | 'tenMillions' | 'tenThousands' | 'thousands' | 'trillions';
1771
+ valAxisDisplayUnitLabel?: boolean;
1772
+ valAxisHidden?: boolean;
1773
+ valAxisLabelColor?: string;
1774
+ valAxisLabelFontBold?: boolean;
1775
+ valAxisLabelFontFace?: string;
1776
+ valAxisLabelFontItalic?: boolean;
1777
+ valAxisLabelFontSize?: number;
1778
+ valAxisLabelFormatCode?: string;
1779
+ valAxisLabelPos?: 'none' | 'low' | 'high' | 'nextTo';
1780
+ valAxisLabelRotate?: number;
1781
+ valAxisLineColor?: string;
1782
+ valAxisLineShow?: boolean;
1783
+ valAxisLineSize?: number;
1784
+ valAxisLineStyle?: 'solid' | 'dash' | 'dot';
1785
+ /**
1786
+ * PowerPoint: Format Axis > Axis Options > Logarithmic scale - Base
1787
+ * - range: 2-99
1788
+ */
1789
+ valAxisLogScaleBase?: number;
1790
+ valAxisMajorTickMark?: ChartAxisTickMark;
1791
+ valAxisMajorUnit?: number;
1792
+ valAxisMaxVal?: number;
1793
+ valAxisMinorTickMark?: ChartAxisTickMark;
1794
+ valAxisMinVal?: number;
1795
+ valAxisOrientation?: 'minMax' | 'maxMin';
1796
+ valAxisTitle?: string;
1797
+ valAxisTitleColor?: string;
1798
+ valAxisTitleFontFace?: string;
1799
+ valAxisTitleFontSize?: number;
1800
+ valAxisTitleRotate?: number;
1801
+ valGridLine?: OptsChartGridLine;
1802
+ /**
1803
+ * Value label format code
1804
+ * - this also directs Data Table formatting
1805
+ * @example '#%' // round percent
1806
+ * @example '0.00%' // shows values as '0.00%'
1807
+ * @example '$0.00' // shows values as '$0.00'
1808
+ */
1809
+ valLabelFormatCode?: string;
1810
+ }
1811
+ interface ChartPropsChartBar {
1812
+ bar3DShape?: string;
1813
+ barDir?: string;
1814
+ barGapDepthPct?: number;
1815
+ /**
1816
+ * MS-PPT > Format chart > Format Data Point > Series Options > "Gap Width"
1817
+ * - width (percent)
1818
+ * - range: `0`-`500`
1819
+ * @default 150
1820
+ */
1821
+ barGapWidthPct?: number;
1822
+ barGrouping?: string;
1823
+ /**
1824
+ * MS-PPT > Format chart > Format Data Point > Series Options > "Series Overlap"
1825
+ * - overlap (percent)
1826
+ * - range: `-100`-`100`
1827
+ * @default 0
1828
+ */
1829
+ barOverlapPct?: number;
1830
+ /**
1831
+ * Draw connector lines between data points across stacked bar/column series
1832
+ * ("Series Lines" in PowerPoint). Emits `<c:serLines>` in the bar chart.
1833
+ *
1834
+ * - `true` uses PowerPoint's automatic line styling.
1835
+ * - An {@link OptsChartGridLine} object customizes color/size/style/cap.
1836
+ * - Omit (or pass an object with `style: 'none'`) to disable.
1837
+ *
1838
+ * Bar (`bar`) charts only; ignored for 3D bar charts.
1839
+ * @default undefined
1840
+ * @example true
1841
+ * @example { color: '777777', size: 1, style: 'dash' }
1842
+ */
1843
+ barSeriesLine?: boolean | OptsChartGridLine;
1844
+ }
1845
+ interface ChartPropsChartDoughnut {
1846
+ dataNoEffects?: boolean;
1847
+ holeSize?: number;
1848
+ }
1849
+ interface ChartPropsChartLine {
1850
+ /**
1851
+ * MS-PPT > Chart format > Format Data Series > Line > Cap type
1852
+ * - line cap type
1853
+ * @default flat
1854
+ */
1855
+ lineCap?: LineCap;
1856
+ /**
1857
+ * MS-PPT > Chart format > Format Data Series > Line > Dash type (chart-level default)
1858
+ * - applies to every series that has no entry in `lineDashValues`
1859
+ * @default solid
1860
+ */
1861
+ lineDash?: ChartLineDash;
1862
+ /**
1863
+ * Per-series dash type overrides; index matches the series order in the `data` array.
1864
+ * - entries shorter than the series count fall back to `lineDash`
1865
+ * - example: `['solid', 'dash', 'lgDash']` gives each series its own dash pattern
1866
+ */
1867
+ lineDashValues?: ChartLineDash[];
1868
+ /**
1869
+ * MS-PPT > Chart format > Format Data Series > Marker Options > Built-in > Type
1870
+ * - marker type
1871
+ * @default circle
1872
+ */
1873
+ lineDataSymbol?: 'circle' | 'dash' | 'diamond' | 'dot' | 'none' | 'square' | 'triangle';
1874
+ /**
1875
+ * MS-PPT > Chart format > Format Data Series > [Marker Options] > Border > Color
1876
+ * - border color
1877
+ * @default circle
1878
+ */
1879
+ lineDataSymbolLineColor?: string;
1880
+ /**
1881
+ * MS-PPT > Chart format > Format Data Series > [Marker Options] > Border > Width
1882
+ * - border width (points)
1883
+ * @default 0.75
1884
+ */
1885
+ lineDataSymbolLineSize?: number;
1886
+ /**
1887
+ * MS-PPT > Chart format > Format Data Series > Marker Options > Built-in > Size
1888
+ * - marker size
1889
+ * - range: 2-72
1890
+ * @default 6
1891
+ */
1892
+ lineDataSymbolSize?: number;
1893
+ /**
1894
+ * MS-PPT > Chart format > Format Data Series > Line > Width
1895
+ * - line width (points)
1896
+ * - range: 0-1584
1897
+ * @default 2
1898
+ */
1899
+ lineSize?: number;
1900
+ /**
1901
+ * MS-PPT > Chart format > Format Data Series > Line > Smoothed line
1902
+ * - "Smoothed line"
1903
+ * @default false
1904
+ */
1905
+ lineSmooth?: boolean;
1906
+ }
1907
+ interface ChartPropsChartPie {
1908
+ dataNoEffects?: boolean;
1909
+ /**
1910
+ * MS-PPT > Format chart > Format Data Series > Series Options > "Angle of first slice"
1911
+ * - angle (degrees)
1912
+ * - range: 0-359
1913
+ * @default 0
1914
+ */
1915
+ firstSliceAng?: number;
1916
+ }
1917
+ interface ChartPropsChartRadar {
1918
+ /**
1919
+ * Radar chart sub-type, named to match the PowerPoint UI ("Radar", "Radar with
1920
+ * Markers", "Filled Radar").
1921
+ * @default radar
1922
+ */
1923
+ radarStyle?: 'radar' | 'markers' | 'filled';
1924
+ }
1925
+ /**
1926
+ * Options for the modern (Office 2016) chartEx chart types.
1927
+ *
1928
+ * NOTE: chartEx charts (currently `waterfall`) render only in PowerPoint 2016+/Microsoft 365.
1929
+ * In older Office, Google Slides, Keynote and LibreOffice a fallback placeholder shows instead.
1930
+ */
1931
+ interface ChartPropsChartWaterfall {
1932
+ /**
1933
+ * Zero-based category indices to render as **subtotal/total** columns in a `waterfall` chart
1934
+ * (columns anchored to the axis baseline rather than floating from the running cumulative
1935
+ * value). Out-of-range or non-integer entries are dropped with a console warning.
1936
+ * @example [0, 4] // first and fifth categories are totals
1937
+ */
1938
+ subtotals?: number[];
1939
+ }
1940
+ /**
1941
+ * Bin configuration for a `histogram` chart. A histogram is fed **raw observations** (one series of
1942
+ * `values`, no `labels`); PowerPoint groups them into bins automatically. The only control wired
1943
+ * today is which side of each bin interval is closed.
1944
+ *
1945
+ * NOTE: explicit bin geometry (fixed bin width / bin count / overflow / underflow) is not yet
1946
+ * supported — PowerPoint desktop rejects the decks those settings produce, so they are deferred.
1947
+ */
1948
+ interface ChartExBinning {
1949
+ /** Which side of each bin interval is closed: `'r'` (right, the default) or `'l'` (left). */
1950
+ intervalClosed?: 'l' | 'r';
1951
+ }
1952
+ interface ChartPropsChartHistogram {
1953
+ /**
1954
+ * Bin configuration for a `histogram` chart. Omit for PowerPoint's automatic binning.
1955
+ * @example { intervalClosed: 'l' }
1956
+ */
1957
+ binning?: ChartExBinning;
1958
+ }
1959
+ /**
1960
+ * Statistics configuration for a `boxWhisker` (box-and-whisker) chart. Each value series is
1961
+ * summarized into a box (quartiles + median) with whiskers; these flags mirror the toggles
1962
+ * PowerPoint exposes in the *Format Data Series* pane. All fields are optional and default to
1963
+ * PowerPoint's own defaults (inclusive of the outlier points and the mean marker).
1964
+ */
1965
+ interface ChartExStatistics {
1966
+ /**
1967
+ * How the first/third quartiles are computed: `'exclusive'` (PowerPoint's default — the median
1968
+ * is excluded when splitting the halves) or `'inclusive'`.
1969
+ */
1970
+ quartileMethod?: 'inclusive' | 'exclusive';
1971
+ /** Draw a line connecting the mean of each box across categories. Default `false`. */
1972
+ meanLine?: boolean;
1973
+ /** Mark the mean of each box with a marker. Default `true`. */
1974
+ meanMarker?: boolean;
1975
+ /** Plot outlier points (values beyond the whiskers) individually. Default `true`. */
1976
+ outliers?: boolean;
1977
+ /** Plot every non-outlier point alongside the box, not just the box itself. Default `false`. */
1978
+ nonoutliers?: boolean;
1979
+ }
1980
+ interface ChartPropsChartBoxWhisker {
1981
+ /**
1982
+ * Statistics configuration for a `boxWhisker` chart. Omit for PowerPoint's defaults
1983
+ * (exclusive quartiles, mean marker shown, outliers shown).
1984
+ * @example { quartileMethod: 'inclusive', meanLine: true }
1985
+ */
1986
+ statistics?: ChartExStatistics;
1987
+ }
1988
+ /**
1989
+ * Geography configuration for a `regionMap` (filled-map) chart. A region map colors each geographic
1990
+ * area by its value; the category labels are region names (countries, states, provinces, …) that
1991
+ * PowerPoint resolves against its Bing-backed geography database when the deck is opened.
1992
+ *
1993
+ * These fields tell PowerPoint how to interpret ambiguous region names (e.g. "Georgia" the country
1994
+ * vs. the US state). They do NOT change what ts-pptx writes beyond the `<cx:geography>` hint —
1995
+ * the actual map is resolved and rendered by PowerPoint 2016+/Microsoft 365 at open time, so the
1996
+ * region names must match PowerPoint's geography database or the map renders blank.
1997
+ */
1998
+ interface ChartExGeography {
1999
+ /** BCP-47 language used to interpret the region names, e.g. `'en-US'` (the default). */
2000
+ cultureLanguage?: string;
2001
+ /** ISO region the names are scoped to, e.g. `'US'` (the default) or `'FR'`. */
2002
+ cultureRegion?: string;
2003
+ }
2004
+ interface ChartPropsChartRegionMap {
2005
+ /**
2006
+ * Geography configuration for a `regionMap` chart. Omit for PowerPoint's defaults
2007
+ * (`cultureLanguage: 'en-US'`, `cultureRegion: 'US'`).
2008
+ * @example { cultureLanguage: 'en-US', cultureRegion: 'FR' }
2009
+ */
2010
+ geography?: ChartExGeography;
2011
+ }
2012
+ interface ChartPropsChartStock {
2013
+ /**
2014
+ * Stock (high-low-close) chart style — selects how many value series the chart expects and how
2015
+ * they are drawn. The data series must be supplied in the exact order implied by the style:
2016
+ * - `'hlc'` — High, Low, Close (3 series). The close is marked with a dot.
2017
+ * - `'ohlc'` — Open, High, Low, Close (4 series). Open→close is drawn as up/down bars.
2018
+ * - `'vhlc'` — Volume, High, Low, Close (4 series). Volume is a column on its own axis.
2019
+ * - `'vohlc'` — Volume, Open, High, Low, Close (5 series). Volume column + up/down bars.
2020
+ *
2021
+ * `<c:hiLowLines>` connect the high/low of each category in every style.
2022
+ * @default 'hlc'
2023
+ */
2024
+ stockStyle?: 'hlc' | 'ohlc' | 'vhlc' | 'vohlc';
2025
+ }
2026
+ interface ChartPropsChartSurface {
2027
+ /**
2028
+ * Draw a 3-D surface (`<c:surface3DChart>`) rather than a 2-D contour / top view
2029
+ * (`<c:surfaceChart>`). The 3-D surface tilts the scene; the contour looks straight down.
2030
+ * @default true
2031
+ */
2032
+ surface3D?: boolean;
2033
+ /**
2034
+ * Draw the surface as a wireframe mesh (`<c:wireframe val="1"/>`) instead of a filled sheet.
2035
+ * Applies to both the 3-D surface and the 2-D contour.
2036
+ * @default false
2037
+ */
2038
+ surfaceWireframe?: boolean;
2039
+ }
2040
+ /**
2041
+ * Per-series style overrides for a chart.
2042
+ * Each entry applies to the series at the same index in the data array.
2043
+ * Unset fields fall back to the chart-level option.
2044
+ */
2045
+ interface ChartSeriesOpts {
2046
+ /** Series fill / line color (hex, e.g. `'FF0000'`) */
2047
+ color?: HexColor;
2048
+ /** Data-label font color */
2049
+ dataLabelColor?: string;
2050
+ /** Data-label font bold */
2051
+ dataLabelFontBold?: boolean;
2052
+ /** Data-label typeface */
2053
+ dataLabelFontFace?: string;
2054
+ /** Data-label font italic */
2055
+ dataLabelFontItalic?: boolean;
2056
+ /** Data-label font size (points) */
2057
+ dataLabelFontSize?: number;
2058
+ /**
2059
+ * Data-label number format code for this series.
2060
+ * Overrides the chart-level `dataLabelFormatCode` for this series only.
2061
+ * @example '#,##0' // thousands separator
2062
+ * @example '0.00%' // shows values as '0.00%'
2063
+ * @example '$0.00' // shows values as '$0.00'
2064
+ */
2065
+ dataLabelFormatCode?: string;
2066
+ /**
2067
+ * Line/radar series line width (points).
2068
+ * Pass `0` to hide the line.
2069
+ */
2070
+ lineSize?: number;
2071
+ }
2072
+ interface ChartPropsDataLabel {
2073
+ dataLabelBkgrdColors?: boolean;
2074
+ dataLabelColor?: string;
2075
+ dataLabelFontBold?: boolean;
2076
+ dataLabelFontFace?: string;
2077
+ dataLabelFontItalic?: boolean;
2078
+ dataLabelFontSize?: number;
2079
+ /**
2080
+ * Data label format code
2081
+ * @example '#%' // round percent
2082
+ * @example '0.00%' // shows values as '0.00%'
2083
+ * @example '$0.00' // shows values as '$0.00'
2084
+ */
2085
+ dataLabelFormatCode?: string;
2086
+ dataLabelFormatScatter?: 'custom' | 'customXY' | 'XY';
2087
+ dataLabelPosition?: 'b' | 'bestFit' | 'ctr' | 'l' | 'r' | 't' | 'inEnd' | 'outEnd';
2088
+ }
2089
+ interface ChartPropsDataTable {
2090
+ dataTableFontSize?: number;
2091
+ /**
2092
+ * Data table format code
2093
+ * @example '#%' // round percent
2094
+ * @example '0.00%' // shows values as '0.00%'
2095
+ * @example '$0.00' // shows values as '$0.00'
2096
+ */
2097
+ dataTableFormatCode?: string;
2098
+ /**
2099
+ * Whether to show a data table adjacent to the chart
2100
+ * @default false
2101
+ */
2102
+ showDataTable?: boolean;
2103
+ showDataTableHorzBorder?: boolean;
2104
+ showDataTableKeys?: boolean;
2105
+ showDataTableOutline?: boolean;
2106
+ showDataTableVertBorder?: boolean;
2107
+ }
2108
+ interface ChartPropsLegend {
2109
+ legendColor?: string;
2110
+ legendFontFace?: string;
2111
+ legendFontSize?: number;
2112
+ /**
2113
+ * Manual legend placement within the chart area.
2114
+ *
2115
+ * Each of `x`/`y`/`w`/`h` is a fraction (0-1) of the chart's width/height.
2116
+ * `x`/`y` position the legend's top-left corner relative to the chart edge;
2117
+ * `w`/`h` set its size. Each axis is independent: provide only `x` to move the
2118
+ * legend horizontally while leaving vertical placement and size automatic.
2119
+ * Setting this overrides the automatic placement implied by `legendPos`.
2120
+ *
2121
+ * Has no effect unless `showLegend` is `true`.
2122
+ *
2123
+ * @example { x: 0.7, y: 0.3, w: 0.25, h: 0.4 }
2124
+ */
2125
+ legendLayout?: PositionProps;
2126
+ legendPos?: 'b' | 'l' | 'r' | 't' | 'tr';
2127
+ }
2128
+ interface ChartPropsTitle extends TextBaseProps {
2129
+ title?: string;
2130
+ titleAlign?: string;
2131
+ titleBold?: boolean;
2132
+ titleColor?: string;
2133
+ titleFontFace?: string;
2134
+ titleFontSize?: number;
2135
+ titleItalic?: boolean;
2136
+ titleUnderline?: boolean;
2137
+ /**
2138
+ * Manual title position (inches), relative to the chart.
2139
+ * Each axis is independent: omit `x` to keep automatic horizontal centering,
2140
+ * or omit `y` to keep automatic vertical placement. Provide at least one.
2141
+ */
2142
+ titlePos?: {
2143
+ x?: number;
2144
+ y?: number;
2145
+ };
2146
+ titleRotate?: number;
2147
+ }
2148
+ interface ChartOpts extends ChartPropsAxisCat, ChartPropsAxisSer, ChartPropsAxisVal, ChartPropsBase, ChartPropsChartBar, ChartPropsChartDoughnut, ChartPropsChartLine, ChartPropsChartPie, ChartPropsChartRadar, ChartPropsChartWaterfall, ChartPropsChartHistogram, ChartPropsChartBoxWhisker, ChartPropsChartRegionMap, ChartPropsChartStock, ChartPropsChartSurface, ChartPropsDataLabel, ChartPropsDataTable, ChartPropsLegend, ChartPropsTitle, ObjectNameProps, OptsChartGridLine, PositionProps {
2149
+ /**
2150
+ * Chart type — required when using the canonical `addChart(data, options)` signature.
2151
+ * - Omit only for multi-type (combo) charts, where each `ChartMulti` entry carries its own `type`.
2152
+ */
2153
+ type?: CHART_NAME;
2154
+ /**
2155
+ * Alt Text value ("How would you describe this object and its contents to someone who is blind?")
2156
+ * - PowerPoint: [right-click on a chart] > "Edit Alt Text..."
2157
+ */
2158
+ altText?: string;
2159
+ /**
2160
+ * Custom chart-level metadata, emitted as a schema-valid extension on the chart space
2161
+ * (`c:chartSpace/c:extLst`) under a stable ts-pptx vendor GUID.
2162
+ * - Use for round-trippable, machine-readable annotations a consumer wants to travel with the
2163
+ * chart (e.g. a source-data id, a generator tag, a semantic role). PowerPoint preserves the
2164
+ * extension untouched and ignores it for rendering.
2165
+ * - Keys must be non-empty strings; values must be strings. Invalid entries are dropped with a
2166
+ * console warning rather than emitting degenerate XML.
2167
+ * @example { sourceId: 'q3-revenue', generator: 'my-deck-tool' }
2168
+ */
2169
+ metadata?: Record<string, string>;
2170
+ }
2171
+ //#endregion
2172
+ //#region src/ooxml/st-enums.d.ts
2173
+ /**
2174
+ * `ST_` simple-type enumerations from ECMA-376, declared once as the single source of both the
2175
+ * TypeScript union a caller is checked against and the runtime list a value is validated against.
2176
+ *
2177
+ * **The problem this solves.** Each of these used to exist twice: a hand-written string union in
2178
+ * `src/types/` (what the compiler enforces) and a hand-written array in `src/gen/` or `src/read/`
2179
+ * (what the validator checks at run time). Nothing tied the two together, so adding a member to
2180
+ * one and not the other produced either a value TypeScript accepts and the validator drops, or a
2181
+ * value the validator passes and the type rejects. Two of them had already diverged in *order*,
2182
+ * which is harmless, but nothing would have caught a divergence in *content*.
2183
+ *
2184
+ * **The shape.** Every entry is a `readonly` tuple declared `as const`, with its union derived via
2185
+ * `(typeof X)[number]`. Widening the tuple widens the union in the same edit — they cannot drift.
2186
+ * This is the idiom already used for `EMBEDDED_FONT_SLOTS` and `EXTRA_SHAPE_PRESETS`; this module
2187
+ * brings the stragglers onto it.
2188
+ *
2189
+ * **Why this module is neither `gen/` nor `read/`.** `src/types/` needs the unions for the public
2190
+ * write API, `src/gen/` needs the tuples to vet a value before emitting it, and `src/read/` needs
2191
+ * them to vet a value before writing it into a loaded part. It is a fact about the schema, so it
2192
+ * belongs to none of the three.
2193
+ *
2194
+ * Values are listed in **schema declaration order**, which is the order the diagnostics print
2195
+ * when they tell a caller what is legal.
2196
+ */
2197
+ /**
2198
+ * `ST_BevelPresetType` — the bevel profile applied to a 3-D edge.
2199
+ * @see ECMA-376 Part 1 §20.1.10.9
2200
+ */
2201
+ declare const BEVEL_PRESETS: readonly ['relaxedInset', 'circle', 'slope', 'cross', 'angle', 'softRound', 'convex', 'coolSlant', 'divot', 'riblet', 'hardEdge', 'artDeco'];
2202
+ type BevelPresetType = (typeof BEVEL_PRESETS)[number];
2203
+ /**
2204
+ * `ST_PresetMaterialType` — how a 3-D surface responds to light.
2205
+ * @see ECMA-376 Part 1 §20.1.10.50
2206
+ */
2207
+ declare const PRESET_MATERIALS: readonly ['legacyMatte', 'legacyPlastic', 'legacyMetal', 'legacyWireframe', 'matte', 'plastic', 'metal', 'warmMatte', 'translucentPowder', 'powder', 'dkEdge', 'softEdge', 'clear', 'flat', 'softmetal'];
2208
+ type PresetMaterialType = (typeof PRESET_MATERIALS)[number];
2209
+ /**
2210
+ * `ST_LightRigType` — the preset lighting scene.
2211
+ * @see ECMA-376 Part 1 §20.1.10.35
2212
+ */
2213
+ declare const LIGHT_RIGS: readonly ['legacyFlat1', 'legacyFlat2', 'legacyFlat3', 'legacyFlat4', 'legacyNormal1', 'legacyNormal2', 'legacyNormal3', 'legacyNormal4', 'legacyHarsh1', 'legacyHarsh2', 'legacyHarsh3', 'legacyHarsh4', 'threePt', 'balanced', 'soft', 'harsh', 'flood', 'contrasting', 'morning', 'sunrise', 'sunset', 'chilly', 'freezing', 'flat', 'twoPt', 'glow', 'brightRoom'];
2214
+ type LightRigType = (typeof LIGHT_RIGS)[number];
2215
+ /**
2216
+ * `ST_LightRigDirection` — where the light rig sits relative to the scene.
2217
+ * @see ECMA-376 Part 1 §20.1.10.33
2218
+ */
2219
+ declare const LIGHT_RIG_DIRECTIONS: readonly ['tl', 't', 'tr', 'l', 'r', 'bl', 'b', 'br'];
2220
+ type LightRigDirection = (typeof LIGHT_RIG_DIRECTIONS)[number];
2221
+ /**
2222
+ * `ST_TextVerticalType` — `a:bodyPr/@vert` and `a:tcPr/@vert`.
2223
+ * @see ECMA-376 Part 1 §20.1.10.83
2224
+ */
2225
+ declare const TEXT_VERTICAL: readonly ['horz', 'vert', 'vert270', 'wordArtVert', 'eaVert', 'mongolianVert', 'wordArtVertRtl'];
2226
+ type TextVerticalType = (typeof TEXT_VERTICAL)[number];
2227
+ /**
2228
+ * `ST_PresetLineDashVal` — the dash pattern of a line or border (`a:prstDash/@val`).
2229
+ *
2230
+ * The `sys*` members are the "system" dashes whose exact dot/gap ratio the renderer picks; the
2231
+ * rest are defined by the spec. Both `BorderProps.dashType` and `ShapeLineProps.dashType` accept
2232
+ * this whole set, so a caller who knows one knows the other.
2233
+ * @see ECMA-376 Part 1 §20.1.10.49
2234
+ */
2235
+ declare const PRESET_LINE_DASHES: readonly ['solid', 'dot', 'dash', 'lgDash', 'dashDot', 'lgDashDot', 'lgDashDotDot', 'sysDash', 'sysDot', 'sysDashDot', 'sysDashDotDot'];
2236
+ type PresetLineDashVal = (typeof PRESET_LINE_DASHES)[number];
2237
+ /**
2238
+ * The twelve theme colour slots (`a:clrScheme` children) a `p:clrMap` token can point at.
2239
+ *
2240
+ * Not an `ST_` type — these are element names inside `a:CT_ColorScheme`, which the schema
2241
+ * declares as a fixed sequence rather than an enumeration. The effect is the same: a closed,
2242
+ * ordered set of twelve names, in the order the scheme declares them.
2243
+ * @see ECMA-376 Part 1 §20.1.6.2
2244
+ */
2245
+ declare const THEME_COLOR_SLOTS: readonly ['dk1', 'lt1', 'dk2', 'lt2', 'accent1', 'accent2', 'accent3', 'accent4', 'accent5', 'accent6', 'hlink', 'folHlink'];
2246
+ type ThemeColorSlot = (typeof THEME_COLOR_SLOTS)[number];
2247
+ /**
2248
+ * The twelve colour-map tokens (`p:clrMap` attributes), in schema attribute order.
2249
+ *
2250
+ * A slide's `schemeClr val="tx1"` names a *token*, not a slot: the master's `p:clrMap` is the
2251
+ * indirection that sends it to a {@link ThemeColorSlot}. Which is why the two lists look alike
2252
+ * and are not the same list — `bg1`/`tx1` are tokens, `lt1`/`dk1` are slots.
2253
+ * @see ECMA-376 Part 1 §19.3.1.6
2254
+ */
2255
+ declare const COLOR_MAP_TOKENS: readonly ['bg1', 'tx1', 'bg2', 'tx2', 'accent1', 'accent2', 'accent3', 'accent4', 'accent5', 'accent6', 'hlink', 'folHlink'];
2256
+ type ColorMapToken = (typeof COLOR_MAP_TOKENS)[number];
2257
+ //#endregion
2258
+ //#region src/types/style.d.ts
2259
+ interface BorderProps {
2260
+ /**
2261
+ * Border type
2262
+ * @default solid
2263
+ */
2264
+ type?: 'none' | 'dash' | 'solid';
2265
+ /**
2266
+ * Dash pattern, using the same vocabulary as {@link ShapeLineProps.dashType}.
2267
+ *
2268
+ * `type` is only a coarse three-way switch, so every dashed border it can express
2269
+ * collapses onto `sysDash`. Set this to pick the exact `a:prstDash` preset instead:
2270
+ * `dashType: 'lgDashDot'` emits `<a:prstDash val="lgDashDot"/>`.
2271
+ *
2272
+ * **Precedence.** When both are set, `dashType` wins over `type` for the dash pattern —
2273
+ * `{ type: 'solid', dashType: 'sysDot' }` draws a dotted rule. The one exception is
2274
+ * `type: 'none'`, which suppresses the border entirely and is decided before any dash
2275
+ * pattern is chosen. An unrecognized value warns and falls back to what `type` implies.
2276
+ * @default (derived from `type`: `sysDash` for `'dash'`, else `solid`)
2277
+ * @example { type: 'solid', color: '999999', dashType: 'lgDash' }
2278
+ */
2279
+ dashType?: ShapeLineProps['dashType'];
2280
+ /**
2281
+ * Border color (hex)
2282
+ * @example 'FF3399'
2283
+ * @default '666666'
2284
+ */
2285
+ color?: HexColor;
2286
+ /**
2287
+ * Border width (points)
2288
+ * - MS-PPT > Format Shape > Fill & Line > Line > Width
2289
+ * @default 1
2290
+ */
2291
+ width?: number;
2292
+ /**
2293
+ * Border transparency (percent)
2294
+ * - MS-PPT > Format Shape > Fill & Line > Line > Transparency
2295
+ * - range: 0-100
2296
+ * @default 0
2297
+ */
2298
+ transparency?: number;
2299
+ /**
2300
+ * Line end cap style
2301
+ * @default 'flat'
2302
+ */
2303
+ cap?: LineCap;
2304
+ }
2305
+ /**
2306
+ * Slide-show navigation action for action-button shapes. Each value maps 1:1 onto
2307
+ * `ppaction://hlinkshowjump?jump=<value>`. A specific numbered slide is reached via
2308
+ * `HyperlinkProps.slide` instead (which emits `ppaction://hlinksldjump`).
2309
+ */
2310
+ type HyperlinkActionJump = 'firstslide' | 'previousslide' | 'nextslide' | 'lastslide' | 'lastslideviewed' | 'endshow';
2311
+ interface HyperlinkProps {
2312
+ _rId?: number;
2313
+ /**
2314
+ * Slide number to link to
2315
+ */
2316
+ slide?: number;
2317
+ /**
2318
+ * Url to link to
2319
+ */
2320
+ url?: string;
2321
+ /**
2322
+ * Hyperlink Tooltip
2323
+ */
2324
+ tooltip?: string;
2325
+ /**
2326
+ * Slide-show navigation action for action-button shapes. Emits a relationship-less
2327
+ * `<a:hlinkClick action="ppaction://hlinkshowjump?jump=…"/>` on the shape.
2328
+ * @example hyperlink: { action: 'nextslide' }
2329
+ */
2330
+ action?: HyperlinkActionJump;
2331
+ }
2332
+ interface ShadowProps {
2333
+ /**
2334
+ * shadow type
2335
+ * @default 'none'
2336
+ */
2337
+ type: 'outer' | 'inner' | 'none';
2338
+ /**
2339
+ * shadow transparency (percent)
2340
+ * - MS-PPT > Format Shape > Effects > Shadow > Transparency
2341
+ * - range: 0-100 (0 = fully opaque, 100 = fully transparent)
2342
+ * @example 25 // 25% transparent
2343
+ */
2344
+ transparency?: number;
2345
+ /**
2346
+ * blur (points)
2347
+ * - range: 0-100
2348
+ * @default 0
2349
+ */
2350
+ blur?: number;
2351
+ /**
2352
+ * angle (degrees)
2353
+ * - range: 0-359
2354
+ * @default 0
2355
+ */
2356
+ angle?: number;
2357
+ /**
2358
+ * shadow offset (points)
2359
+ * - range: 0-200
2360
+ * @default 0
2361
+ */
2362
+ offset?: number;
2363
+ /**
2364
+ * shadow color (hex format)
2365
+ * @example 'FF3399'
2366
+ */
2367
+ color?: HexColor;
2368
+ /**
2369
+ * whether to rotate shadow with shape
2370
+ * @default false
2371
+ */
2372
+ rotateWithShape?: boolean;
2373
+ }
2374
+ interface ShapeFillProps {
2375
+ /**
2376
+ * Fill color
2377
+ * - `HexColor` or `ThemeColor`
2378
+ * @example 'FF0000' // hex color (red)
2379
+ * @example SchemeColor.text1 // Theme color (Text1)
2380
+ */
2381
+ color?: Color;
2382
+ /**
2383
+ * Transparency (percent)
2384
+ * - MS-PPT > Format Shape > Fill & Line > Fill > Transparency
2385
+ * - range: 0-100
2386
+ * @default 0
2387
+ */
2388
+ transparency?: number;
2389
+ /**
2390
+ * Fill type
2391
+ *
2392
+ * `'none'` and `'inherit'` are different states, and both have to be spelled out
2393
+ * because omitting `fill` is not one of them: the shape/text-box emitter defaults a
2394
+ * missing `fill` to `<a:noFill/>`.
2395
+ * - `'none'` emits `<a:noFill/>` — an explicit transparent interior.
2396
+ * - `'inherit'` emits no fill child at all, leaving the interior to
2397
+ * `p:style/a:fillRef` or the placeholder. This is the only way to author that
2398
+ * state from `addShape`/`addText`.
2399
+ *
2400
+ * On a table cell (`TableCellProps.fill`) and a slide background the two spellings
2401
+ * differ the same way, except that *omitting* the option there already means
2402
+ * inherit, so `'inherit'` is merely the explicit form of the default.
2403
+ * @default 'solid'
2404
+ */
2405
+ type?: 'none' | 'inherit' | 'solid' | 'gradient' | 'pattern' | 'image';
2406
+ /**
2407
+ * Native PPTX gradient fill options.
2408
+ */
2409
+ gradient?: GradientFillProps;
2410
+ /**
2411
+ * Native PPTX pattern fill options.
2412
+ */
2413
+ pattern?: PatternFillProps;
2414
+ /**
2415
+ * Native PPTX picture fill options. Setting this (or `type: 'image'`) fills the
2416
+ * shape interior with a stretched bitmap instead of a color.
2417
+ */
2418
+ image?: ImageFillProps;
2419
+ /**
2420
+ * Resolved media relationship id for an image fill, assigned at add-time.
2421
+ * @internal
2422
+ */
2423
+ _imgRid?: number;
2424
+ }
2425
+ /**
2426
+ * Line (stroke) options.
2427
+ *
2428
+ * A stroke is painted like a fill: in addition to a solid `color`, it accepts the
2429
+ * inherited `gradient`/`pattern`/`image` fill options (DrawingML allows the same
2430
+ * fill group inside `<a:ln>`). Setting `gradient` (or `type: 'gradient'`) paints a
2431
+ * gradient stroke, e.g. `line: { width: 1, gradient: { kind: 'linear', angle: 0,
2432
+ * stops: [{ position: 0, color: 'accent3' }, { position: 100, color: 'accent4' }] } }`.
2433
+ */
2434
+ interface ShapeLineProps extends ShapeFillProps {
2435
+ /**
2436
+ * Line width (pt)
2437
+ * @default 1
2438
+ */
2439
+ width?: number;
2440
+ /**
2441
+ * Dash type — the full `ST_PresetLineDashVal` set, so any dash a source deck can
2442
+ * carry can also be authored and replicated.
2443
+ * @default 'solid'
2444
+ */
2445
+ dashType?: PresetLineDashVal;
2446
+ /**
2447
+ * Line end cap style
2448
+ * @default 'flat'
2449
+ */
2450
+ cap?: LineCap;
2451
+ /**
2452
+ * Begin arrow type
2453
+ */
2454
+ beginArrowType?: 'none' | 'arrow' | 'diamond' | 'oval' | 'stealth' | 'triangle';
2455
+ /**
2456
+ * End arrow type
2457
+ */
2458
+ endArrowType?: 'none' | 'arrow' | 'diamond' | 'oval' | 'stealth' | 'triangle';
2459
+ }
2460
+ /**
2461
+ * Connector routing style. Maps to a connector preset geometry. The exact preset
2462
+ * also depends on `bends` (number of jogs):
2463
+ * `straight`→`straightConnector1`; `elbow`→`bentConnector{3,4,5}`;
2464
+ * `curved`→`curvedConnector{3,4,5}`.
2465
+ */
2466
+ type ConnectorType = 'straight' | 'elbow' | 'curved';
2467
+ /**
2468
+ * A connector is a line drawn between two points, emitted as a PowerPoint connector
2469
+ * (`<p:cxnSp>`) so the app treats it as a connector (selectable/reroutable) rather than a
2470
+ * plain line shape. Endpoints are given directly; the bounding box and flip flags are derived.
2471
+ */
2472
+ interface ConnectorProps {
2473
+ /**
2474
+ * Routing style
2475
+ * @default 'straight'
2476
+ */
2477
+ type?: ConnectorType;
2478
+ /**
2479
+ * Number of adjustable bends (jogs) for an `elbow` / `curved` connector. Selects the
2480
+ * preset variant and how many `adj` values it accepts:
2481
+ * - `1` → `bentConnector3` / `curvedConnector3` (one jog) — the default
2482
+ * - `2` → `bentConnector4` / `curvedConnector4` (two jogs)
2483
+ * - `3` → `bentConnector5` / `curvedConnector5` (three jogs)
2484
+ *
2485
+ * Ignored for `type: 'straight'` (a straight connector has no bends).
2486
+ * @default 1
2487
+ */
2488
+ bends?: 1 | 2 | 3;
2489
+ /**
2490
+ * Bend position(s) as a percent of the connector box (`0`–`100`), one value per bend.
2491
+ * A single number sets the sole jog of a one-bend `elbow` / `curved`; an array sets each
2492
+ * jog of a multi-bend connector and its length must equal `bends`. Values outside `0`–`100`
2493
+ * are allowed (they place the bend beyond the endpoint box, as PowerPoint itself does when
2494
+ * endpoints flip). When omitted, PowerPoint uses the preset default (50%).
2495
+ *
2496
+ * Emitted as `<a:gd name="adj1…" fmla="val …"/>` adjust guides (OOXML 1000ths-of-a-percent).
2497
+ */
2498
+ adj?: number | number[];
2499
+ /**
2500
+ * Bind the connector's start point to a shape on the **same slide**, referenced by that
2501
+ * shape's `objectName`. Emits `<a:stCxn id=… idx=…>`, so PowerPoint treats the endpoint as
2502
+ * attached: it reroutes when the shape moves and its elbow auto-router can engage.
2503
+ * The shape's `objectName` must be set and unique on the slide. `x1`/`y1` remain the static
2504
+ * fallback geometry (and are used if the name can't be resolved).
2505
+ *
2506
+ * A shape inside a group is a valid target — group children are named on the same slide — though
2507
+ * the connector itself cannot be a group child (see {@link Slide.addGroup}).
2508
+ */
2509
+ startShape?: string;
2510
+ /**
2511
+ * Connection-site index on `startShape` (0-based; the valid range is preset-dependent — a
2512
+ * shape's `<a:cxnLst>` enumerates its sites). Ignored without `startShape`.
2513
+ * @default 0
2514
+ */
2515
+ startShapeIdx?: number;
2516
+ /** Bind the connector's end point to a shape on the same slide (by `objectName`). Emits `<a:endCxn>`. See {@link startShape}. */
2517
+ endShape?: string;
2518
+ /**
2519
+ * Connection-site index on `endShape`. Ignored without `endShape`.
2520
+ * @default 0
2521
+ */
2522
+ endShapeIdx?: number;
2523
+ /** Start point X — inches, or a `Coord` such as `'50%'` / `'2in'` */
2524
+ x1: Coord;
2525
+ /** Start point Y */
2526
+ y1: Coord;
2527
+ /** End point X */
2528
+ x2: Coord;
2529
+ /** End point Y */
2530
+ y2: Coord;
2531
+ /**
2532
+ * Line color (6-digit hex, no `#`)
2533
+ * @default '000000'
2534
+ */
2535
+ color?: HexColor;
2536
+ /**
2537
+ * Line width (pt)
2538
+ * @default 1
2539
+ */
2540
+ width?: number;
2541
+ /** Dash style */
2542
+ dashType?: ShapeLineProps['dashType'];
2543
+ /** Arrowhead at the start point */
2544
+ beginArrowType?: ShapeLineProps['beginArrowType'];
2545
+ /** Arrowhead at the end point */
2546
+ endArrowType?: ShapeLineProps['endArrowType'];
2547
+ /** Selection Pane object name */
2548
+ objectName?: string;
2549
+ /** Accessibility alt text */
2550
+ altText?: string;
2551
+ }
2552
+ //#endregion
2553
+ //#region src/types/core.d.ts
2554
+ /**
2555
+ * Coordinate value. A bare `number` is **always inches** — there is no magnitude-based unit
2556
+ * guessing. For other units use an explicit string suffix:
2557
+ * - `number` → inches (e.g. `10.25`)
2558
+ * - `"<n>%"` → percentage of the slide axis (e.g. `"75%"`)
2559
+ * - `"<n>in"` → inches (e.g. `"10.25in"`)
2560
+ * - `"<n>pt"` → points (e.g. `"72pt"` = 1 inch)
2561
+ * - `"<n>px"` → CSS reference pixels at 96 px/inch (e.g. `"96px"` = 1 inch), for authoring against
2562
+ * a known web/source canvas size
2563
+ * - `"<n>emu"` → raw EMU, the escape hatch for exact OOXML units (e.g. `"914400emu"` = 1 inch)
2564
+ *
2565
+ * @example 10.25 // inches
2566
+ * @example '75%' // percentage of slide size
2567
+ * @example '72pt' // points
2568
+ * @example '960px' // pixels at 96 DPI = 10 inches
2569
+ * @example '914400emu' // raw EMU
2570
+ */
2571
+ type Coord = number | `${number}%` | `${number}in` | `${number}pt` | `${number}px` | `${number}emu`;
2572
+ interface PositionProps {
2573
+ /**
2574
+ * Horizontal position
2575
+ * - inches or percentage
2576
+ * @example 10.25 // position in inches
2577
+ * @example '75%' // position as percentage of slide size
2578
+ */
2579
+ x?: Coord;
2580
+ /**
2581
+ * Vertical position
2582
+ * - inches or percentage
2583
+ * @example 10.25 // position in inches
2584
+ * @example '75%' // position as percentage of slide size
2585
+ */
2586
+ y?: Coord;
2587
+ /**
2588
+ * Height
2589
+ * - inches or percentage
2590
+ * @example 10.25 // height in inches
2591
+ * @example '75%' // height as percentage of slide size
2592
+ */
2593
+ h?: Coord;
2594
+ /**
2595
+ * Width
2596
+ * - inches or percentage
2597
+ * @example 10.25 // width in inches
2598
+ * @example '75%' // width as percentage of slide size
2599
+ */
2600
+ w?: Coord;
2601
+ }
2602
+ /**
2603
+ * Reusable optional data/path fields.
2604
+ * Use `DataOrPathRequiredProps` for APIs that require at least one source.
2605
+ */
2606
+ interface DataOrPathProps {
2607
+ /**
2608
+ * URL or relative path
2609
+ *
2610
+ * @example 'https://onedrives.com/myimg.png` // retrieve image via URL
2611
+ * @example '/home/user/images/myimg.png` // retrieve image via local path
2612
+ */
2613
+ path?: string;
2614
+ /**
2615
+ * base64-encoded string
2616
+ * - Useful for avoiding potential path/server issues
2617
+ *
2618
+ * @example 'image/png;base64,iVtDafDrBF[...]=' // pre-encoded image in base-64
2619
+ */
2620
+ data?: string;
2621
+ }
2622
+ type DataOrPathRequiredProps = (DataOrPathProps & {
2623
+ data: string;
2624
+ }) | (DataOrPathProps & {
2625
+ path: string;
2626
+ });
2627
+ interface BackgroundProps extends DataOrPathProps, ShapeFillProps {}
2628
+ /**
2629
+ * Color in Hex format
2630
+ * @example 'FF3399'
2631
+ */
2632
+ type HexColor = string;
2633
+ type ThemeColor = 'tx1' | 'tx2' | 'bg1' | 'bg2' | 'accent1' | 'accent2' | 'accent3' | 'accent4' | 'accent5' | 'accent6';
2634
+ type Color = HexColor | ThemeColor;
2635
+ interface GradientStopProps {
2636
+ /**
2637
+ * Stop position as a percentage.
2638
+ * - range: 0-100
2639
+ */
2640
+ position: number;
2641
+ /**
2642
+ * Stop color.
2643
+ * - `HexColor` or `ThemeColor`
2644
+ */
2645
+ color: Color;
2646
+ /**
2647
+ * Transparency (percent)
2648
+ * - range: 0-100
2649
+ * @default 0
2650
+ */
2651
+ transparency?: number;
2652
+ }
2653
+ interface LinearGradientFillProps {
2654
+ /**
2655
+ * Gradient type.
2656
+ */
2657
+ kind: 'linear';
2658
+ /**
2659
+ * Gradient angle in degrees. Values are normalized into 0-359.999...
2660
+ * @default 0
2661
+ */
2662
+ angle?: number;
2663
+ /**
2664
+ * Whether the gradient angle scales with the fill region.
2665
+ */
2666
+ scaled?: boolean;
2667
+ /**
2668
+ * Whether the fill rotates with the shape.
2669
+ * @default true
2670
+ */
2671
+ rotateWithShape?: boolean;
2672
+ /**
2673
+ * Gradient stops. Stops are serialized in ascending `position` order.
2674
+ */
2675
+ stops: GradientStopProps[];
2676
+ }
2677
+ interface RadialGradientFillProps {
2678
+ /**
2679
+ * Gradient type. A circular gradient radiating from a focus point: the stop at
2680
+ * `position: 0` sits at the center and later stops fan outward to the edges.
2681
+ */
2682
+ kind: 'radial';
2683
+ /**
2684
+ * Focus point of the radial gradient as percentages of the fill box, where
2685
+ * `{ x: 50, y: 50 }` (the default) centers it. Lower/higher values push the
2686
+ * bright center toward an edge.
2687
+ * @default { x: 50, y: 50 }
2688
+ */
2689
+ center?: {
2690
+ x: number;
2691
+ y: number;
2692
+ };
2693
+ /**
2694
+ * Whether the fill rotates with the shape.
2695
+ * @default true
2696
+ */
2697
+ rotateWithShape?: boolean;
2698
+ /**
2699
+ * Gradient stops. Stops are serialized in ascending `position` order; the
2700
+ * first (`position: 0`) is the center color.
2701
+ */
2702
+ stops: GradientStopProps[];
2703
+ }
2704
+ type GradientFillProps = LinearGradientFillProps | RadialGradientFillProps;
2705
+ /** OOXML ST_PresetPatternVal — preset pattern names for `<a:pattFill prst="...">` */
2706
+ type PatternPreset = 'pct5' | 'pct10' | 'pct20' | 'pct25' | 'pct30' | 'pct40' | 'pct50' | 'pct60' | 'pct70' | 'pct75' | 'pct80' | 'pct90' | 'horz' | 'vert' | 'ltHorz' | 'ltVert' | 'dkHorz' | 'dkVert' | 'narHorz' | 'narVert' | 'dashHorz' | 'dashVert' | 'cross' | 'dnDiag' | 'upDiag' | 'ltDnDiag' | 'ltUpDiag' | 'dkDnDiag' | 'dkUpDiag' | 'wdDnDiag' | 'wdUpDiag' | 'dashDnDiag' | 'dashUpDiag' | 'diagCross' | 'smCheck' | 'lgCheck' | 'smGrid' | 'lgGrid' | 'dotGrid' | 'smConfetti' | 'lgConfetti' | 'horzBrick' | 'diagBrick' | 'solidDmnd' | 'openDmnd' | 'dotDmnd' | 'plaid' | 'sphere' | 'weave' | 'divot' | 'shingle' | 'wave' | 'trellis' | 'zigZag';
2707
+ interface PatternFillProps {
2708
+ /** OOXML preset pattern (`prst` attribute on `<a:pattFill>`). */
2709
+ preset: PatternPreset;
2710
+ /** Foreground color. Defaults to black (`000000`) if omitted. */
2711
+ fgColor?: Color;
2712
+ /** Background color. Defaults to white (`FFFFFF`) if omitted. */
2713
+ bgColor?: Color;
2714
+ }
2715
+ /**
2716
+ * Native PPTX picture (image) fill — fills a shape's interior with a bitmap
2717
+ * (`<a:blipFill>`). Provide exactly one of `path` or `data`; raster formats only
2718
+ * (PNG/JPEG/GIF/BMP/WebP). SVG is not yet supported as a fill source.
2719
+ */
2720
+ interface ImageFillProps {
2721
+ /** Image file path (Node filesystem path or URL). */
2722
+ path?: string;
2723
+ /** Pre-encoded base64 data URI, e.g. `'image/png;base64,iVBOR...'`. */
2724
+ data?: string;
2725
+ }
2726
+ type Margin = number | [number, number, number, number];
2727
+ type HAlign = 'left' | 'center' | 'right' | 'justify';
2728
+ type VAlign = 'top' | 'middle' | 'bottom';
2729
+ /**
2730
+ * Text body `vert` attribute — flow/rotation direction of the text within its box.
2731
+ * Maps to `<a:bodyPr vert="…">` (ECMA-376 `ST_TextVerticalType`).
2732
+ */
2733
+ type TextVertType = TextVerticalType;
2734
+ /**
2735
+ * A single node of a freeform (`custGeom`) path.
2736
+ * - coordinates are authored in the object's own inch/EMU space (0..width, 0..height), not slide-relative and not normalized
2737
+ * - used by shapes (`ShapeType.custGeom`) and by images (clips the picture to the path)
2738
+ *
2739
+ * The `arc` node carries no `x`/`y`: an `<a:arcTo>` has no explicit end point. The renderer
2740
+ * derives it from the current pen position, the radii and the swept angle, so an end point
2741
+ * authored here would be discarded (a warning is emitted if one is supplied).
2742
+ */
2743
+ type GeometryPoint = {
2744
+ x: Coord;
2745
+ y: Coord;
2746
+ moveTo?: boolean;
2747
+ } | {
2748
+ curve: {
2749
+ type: 'arc';
2750
+ hR: Coord;
2751
+ wR: Coord;
2752
+ stAng: number;
2753
+ swAng: number;
2754
+ };
2755
+ } | {
2756
+ x: Coord;
2757
+ y: Coord;
2758
+ curve: {
2759
+ type: 'cubic';
2760
+ x1: Coord;
2761
+ y1: Coord;
2762
+ x2: Coord;
2763
+ y2: Coord;
2764
+ };
2765
+ } | {
2766
+ x: Coord;
2767
+ y: Coord;
2768
+ curve: {
2769
+ type: 'quadratic';
2770
+ x1: Coord;
2771
+ y1: Coord;
2772
+ };
2773
+ } | {
2774
+ close: true;
2775
+ };
2776
+ //#endregion
2777
+ //#region src/types/table.d.ts
2778
+ /**
2779
+ * A `<table>` element, from whatever DOM implementation the caller has.
2780
+ *
2781
+ * Deliberately *not* `lib.dom`'s `Element`. `lib.dom`'s types are built for a browser, and a
2782
+ * non-browser DOM's element type — happy-dom's, jsdom's — declares its own members and does
2783
+ * not satisfy them, so demanding `Element` would reject from TypeScript exactly the
2784
+ * implementations `ts-pptx/html` exists to accept. Requiring the three members the conversion
2785
+ * actually calls keeps a mistyped argument an error while letting every real DOM through.
2786
+ */
2787
+ interface TableToSlidesElement {
2788
+ getAttribute: (name: string) => string | null;
2789
+ querySelector: (selectors: string) => unknown;
2790
+ querySelectorAll: (selectors: string) => unknown;
2791
+ }
2792
+ /**
2793
+ * The one thing `tableToSlides` asks a document for. Structural for the same reason
2794
+ * {@link TableToSlidesElement} is.
2795
+ */
2796
+ interface TableToSlidesDocument {
2797
+ getElementById: (elementId: string) => TableToSlidesElement | null;
2798
+ }
2799
+ interface TableToSlidesProps extends TableProps {
2800
+ _arrObjTabHeadRows?: TableRow[];
2801
+ /**
2802
+ * Add an image to slide(s) created during autopaging
2803
+ * - `image` prop requires either `path` or `data`
2804
+ * - see `DataOrPathProps` for details on `image` props
2805
+ * - see `PositionProps` for details on `options` props
2806
+ */
2807
+ addImage?: {
2808
+ image: DataOrPathProps;
2809
+ options: PositionProps;
2810
+ };
2811
+ /**
2812
+ * Add a shape to slide(s) created during autopaging
2813
+ */
2814
+ addShape?: {
2815
+ shapeName: SHAPE_NAME;
2816
+ options: ShapeProps;
2817
+ };
2818
+ /**
2819
+ * Add a table to slide(s) created during autopaging
2820
+ */
2821
+ addTable?: {
2822
+ rows: TableRow[];
2823
+ options: TableProps;
2824
+ };
2825
+ /**
2826
+ * Add a text object to slide(s) created during autopaging
2827
+ */
2828
+ addText?: {
2829
+ text: TextProps[];
2830
+ options: TextPropsOptions;
2831
+ };
2832
+ /**
2833
+ * Whether to enable auto-paging
2834
+ * - auto-paging creates new slides as content overflows a slide
2835
+ * @default true
2836
+ */
2837
+ autoPage?: boolean;
2838
+ /**
2839
+ * Auto-paging character weight
2840
+ * - adjusts how many characters are used before lines wrap
2841
+ * - range: -1.0 to 1.0
2842
+ * @default 0.0
2843
+ * @example 0.5 // lines are longer (increases the number of characters that can fit on a given line)
2844
+ */
2845
+ autoPageCharWeight?: number;
2846
+ /**
2847
+ * Auto-paging line weight
2848
+ * - adjusts how many lines are used before slides wrap
2849
+ * - range: -1.0 to 1.0
2850
+ * @default 0.0
2851
+ * @example 0.5 // tables are taller (increases the number of lines that can fit on a given slide)
2852
+ */
2853
+ autoPageLineWeight?: number;
2854
+ /**
2855
+ * Whether to repeat head row(s) on new tables created by autopaging
2856
+ * @default false
2857
+ */
2858
+ autoPageRepeatHeader?: boolean;
2859
+ /**
2860
+ * The `y` location to use on subsequent slides created by autopaging
2861
+ * @default (top margin of Slide)
2862
+ */
2863
+ autoPageSlideStartY?: number;
2864
+ /**
2865
+ * Column widths (inches)
2866
+ */
2867
+ colW?: number | number[];
2868
+ /**
2869
+ * Document to resolve a table *id* against.
2870
+ * - only consulted when the table is identified by string id; passing the element itself
2871
+ * needs no document, since one is reached through the element's `ownerDocument`
2872
+ * - defaults to the global `document`, which is what a browser caller gets
2873
+ * - supply this to convert a table outside a browser (any DOM implementation will do)
2874
+ */
2875
+ document?: TableToSlidesDocument;
2876
+ /**
2877
+ * Title of the slide master to use for the auto-paged slides (the `title` passed to
2878
+ * `defineSlideMaster`). Matches the `masterTitle` option of `addSlide`.
2879
+ * - define a master slide to have your auto-paged slides carry a corporate design, etc.
2880
+ */
2881
+ masterTitle?: string;
2882
+ /**
2883
+ * Slide margin
2884
+ * - this margin will be across all slides created by auto-paging
2885
+ */
2886
+ slideMargin?: Margin;
2887
+ }
2888
+ /**
2889
+ * A table cell's corner-to-corner rules (`a:tcPr/a:lnTlToBr` / `a:lnBlToTr`) — the
2890
+ * "Diagonal Down Border" / "Diagonal Up Border" of PowerPoint's border gallery.
2891
+ *
2892
+ * Deliberately its own object rather than two more entries on {@link TableCellProps.border}'s
2893
+ * tuple: widening that tuple to six would break every existing caller for a construct almost
2894
+ * no deck uses, and the two diagonals are not edges — they do not participate in the
2895
+ * perimeter, and they are not inherited by a merged region's covered cells.
2896
+ *
2897
+ * @example diagonal: { tlToBr: { type:'solid', color:'C00000', width:1 } } // strike a cell out
2898
+ * @example diagonal: { tlToBr: { type:'solid' }, blToTr: { type:'solid' } } // an X across the cell
2899
+ */
2900
+ interface TableCellDiagonals {
2901
+ /** Top-left to bottom-right (`╲`, `a:lnTlToBr`). */
2902
+ tlToBr?: BorderProps;
2903
+ /** Bottom-left to top-right (`╱`, `a:lnBlToTr`). */
2904
+ blToTr?: BorderProps;
2905
+ }
2906
+ /**
2907
+ * A cell's 3-D bevel (`a:tcPr/a:cell3D`).
2908
+ *
2909
+ * A minimal surface over `CT_Cell3D`, which is a required `a:bevel` plus an optional
2910
+ * `a:lightRig`. PowerPoint's table UI exposes no control for it — it reaches a deck through a
2911
+ * theme's table style or through another producer — so this exists to author and reproduce
2912
+ * one, not as a general 3-D model.
2913
+ */
2914
+ interface TableCell3DProps {
2915
+ /**
2916
+ * The bevel's preset shape (`a:bevel/@prst`).
2917
+ * @default 'circle'
2918
+ */
2919
+ preset?: BevelPresetType;
2920
+ /**
2921
+ * Bevel width in points (`a:bevel/@w`; the attribute is EMU).
2922
+ * @default 6 // 76200 EMU
2923
+ */
2924
+ width?: number;
2925
+ /**
2926
+ * Bevel height in points (`a:bevel/@h`; the attribute is EMU).
2927
+ * @default 6 // 76200 EMU
2928
+ */
2929
+ height?: number;
2930
+ /**
2931
+ * Surface material (`a:cell3D/@prstMaterial`), which decides how the bevel takes light.
2932
+ * @default 'plastic'
2933
+ */
2934
+ material?: PresetMaterialType;
2935
+ /**
2936
+ * Scene lighting (`a:cell3D/a:lightRig`). Both fields are required by the schema, so
2937
+ * either give both or omit the whole object and let the renderer light the bevel.
2938
+ * @example lightRig: { rig: 'threePt', dir: 't' }
2939
+ */
2940
+ lightRig?: {
2941
+ rig: LightRigType;
2942
+ dir: LightRigDirection;
2943
+ };
2944
+ }
2945
+ interface TableCellProps extends TextBaseProps {
2946
+ /**
2947
+ * Auto-paging character weight
2948
+ * - adjusts how many characters are used before lines wrap
2949
+ * - range: -1.0 to 1.0
2950
+ * @default 0.0
2951
+ * @example 0.5 // lines are longer (increases the number of characters that can fit on a given line)
2952
+ */
2953
+ autoPageCharWeight?: number;
2954
+ /**
2955
+ * Auto-paging line weight
2956
+ * - adjusts how many lines are used before slides wrap
2957
+ * - range: -1.0 to 1.0
2958
+ * @default 0.0
2959
+ * @example 0.5 // tables are taller (increases the number of lines that can fit on a given slide)
2960
+ */
2961
+ autoPageLineWeight?: number;
2962
+ /**
2963
+ * The cell's four edge borders (`a:tcPr/a:lnT|lnR|lnB|lnL`).
2964
+ * - a single `BorderProps` is broadcast to all four sides
2965
+ * - an array is read in **TRBL** order (`[top, right, bottom, left]`)
2966
+ *
2967
+ * Overrides the table-level {@link TableProps.border} default entirely — the two do not
2968
+ * merge per side. A `null` entry is a hole: that edge is left out of `a:tcPr` and keeps
2969
+ * inheriting from the table style, while `{ type: 'none' }` writes an explicit no-line
2970
+ * that overrides it. For the two corner-to-corner rules see {@link diagonal}; for the
2971
+ * table's outside edge see {@link TableProps.outerBorder}.
2972
+ */
2973
+ border?: BorderProps | [BorderProps | null, BorderProps | null, BorderProps | null, BorderProps | null];
2974
+ /**
2975
+ * The cell's corner-to-corner rules — PowerPoint's "Diagonal Down/Up Border".
2976
+ *
2977
+ * Kept off {@link border}'s tuple on purpose: see {@link TableCellDiagonals}. A diagonal
2978
+ * on a merged cell is one stroke across the whole region, so only the span origin carries
2979
+ * it — the covered cells inherit the origin's *edges* but never its diagonals.
2980
+ * @example diagonal: { tlToBr: { type:'solid', color:'C00000' } } // strike the cell out
2981
+ */
2982
+ diagonal?: TableCellDiagonals;
2983
+ /**
2984
+ * Centre the cell's whole text **block** horizontally within the cell
2985
+ * (`a:tcPr/@anchorCtr`), independent of each paragraph's own `align`.
2986
+ *
2987
+ * The two do different things and compose: `align` decides where each line sits inside
2988
+ * the text block, `anchorCtr` decides where that block sits inside the cell. With
2989
+ * left-aligned text in a wide cell, `anchorCtr: true` centres the ragged-right column of
2990
+ * lines as a unit while keeping their left edges flush with each other.
2991
+ *
2992
+ * `false` is the schema default, so it emits nothing — the same reasoning as
2993
+ * `horzOverflow: 'clip'`.
2994
+ * @default false
2995
+ */
2996
+ anchorCtr?: boolean;
2997
+ /**
2998
+ * A 3-D bevel on the cell (`a:tcPr/a:cell3D`). Niche: PowerPoint's table UI has no
2999
+ * control for it, so it reaches a deck from a theme or another producer, and this exists
3000
+ * to author and reproduce one. See {@link TableCell3DProps}.
3001
+ */
3002
+ cell3D?: TableCell3DProps;
3003
+ /**
3004
+ * Cell colspan
3005
+ */
3006
+ colspan?: number;
3007
+ /**
3008
+ * Cell fill — a solid color, or a picture that fills the cell (`a:blipFill` in
3009
+ * the cell's `a:tcPr`, stretched to the cell box). A picture fill embeds the
3010
+ * image as slide media; identical sources are embedded once. Raster only —
3011
+ * an SVG source warns and is ignored, matching shape fills.
3012
+ * @example { color:'FF0000' } // hex color (red)
3013
+ * @example { color:'0088CC', transparency:50 } // hex color, 50% transparent
3014
+ * @example { color:SchemeColor.accent1 } // theme color Accent1
3015
+ * @example { type:'image', image:{ path:'logo.png' } } // picture fill
3016
+ * @example { image:{ data:'image/png;base64,…' } } // picture fill, `type` inferred
3017
+ */
3018
+ fill?: ShapeFillProps;
3019
+ /**
3020
+ * What happens to a **single glyph** wider than the cell's text width (`a:tcPr/@horzOverflow`).
3021
+ * - `'clip'` (PowerPoint's default) cuts the glyph off at the cell edge
3022
+ * - `'overflow'` lets it draw past the edge, over whatever is beside it
3023
+ *
3024
+ * This is **not** a text-wrap switch, despite the name. Lines always wrap to the column
3025
+ * width; only an individual character too wide to fit on a line by itself is affected, so
3026
+ * it matters for oversized display type, wide CJK/emoji glyphs, and icon fonts in a narrow
3027
+ * column. PowerPoint has no per-cell no-wrap at all — `wrap="none"` on a cell's `a:bodyPr`
3028
+ * is discarded on the next save (probe:
3029
+ * `test/read/fixtures/authoring/probe-table-cell-wrap.ps1`).
3030
+ * `'clip'` is written as asked but is the schema default, so PowerPoint drops the
3031
+ * attribute again the first time it saves the deck — the visible result is the same
3032
+ * either way, and leaving this unset emits nothing at all.
3033
+ * @default (unset — PowerPoint clips)
3034
+ * @example 'overflow' // a 60pt glyph in a 0.5in column draws whole instead of being cut
3035
+ */
3036
+ horzOverflow?: 'clip' | 'overflow';
3037
+ hyperlink?: HyperlinkProps;
3038
+ /**
3039
+ * Cell margin (inches)
3040
+ * @default 0
3041
+ */
3042
+ margin?: Margin;
3043
+ /**
3044
+ * Cell rowspan
3045
+ */
3046
+ rowspan?: number;
3047
+ /**
3048
+ * Shrink cell text to fit when it would overflow the cell's fixed height.
3049
+ * - `'shrink'` measures the wrapped text and bakes a **reduced literal font size**
3050
+ * onto the cell's runs so the text fits — PowerPoint does not support text
3051
+ * autofit (`normAutofit`) inside table cells, so there is no font-scale flag to
3052
+ * set; the size itself is lowered, which both PowerPoint and LibreOffice render
3053
+ * identically with no edit/resize.
3054
+ * - Requires the cell font registered via {@link TsPptx.registerFontMetrics};
3055
+ * without metrics it is a no-op (the cell keeps its authored size) and warns once.
3056
+ * - Only triggers when the cell's row has a **fixed** height that the text exceeds.
3057
+ * With auto-height rows (no `rowH`/`h`), the row simply grows, so nothing shrinks.
3058
+ * - Only `'shrink'` is acted on for cells. `'resize'` and the object form are ignored
3059
+ * here: a table row already auto-grows to fit its tallest cell (the cell equivalent
3060
+ * of `spAutoFit`), so there is nothing to bake. (The wider union is shared with
3061
+ * {@link TextPropsOptions.fit} so table-level `fit` can cascade to cells.)
3062
+ * @example 'shrink' // measured when the cell font is registered; else no-op
3063
+ */
3064
+ fit?: 'none' | 'shrink' | 'resize' | TextFitShrinkProps;
3065
+ }
3066
+ interface TableProps extends PositionProps, TextBaseProps, ObjectNameProps {
3067
+ _arrObjTabHeadRows?: TableRow[];
3068
+ /**
3069
+ * Name of a table/content placeholder defined on the slide layout/master to bind this table to.
3070
+ * - when it matches a layout/master placeholder, the table's `<p:graphicFrame>` emits that
3071
+ * placeholder's `<p:ph>` (idx/type) so PowerPoint treats the table as filling the placeholder
3072
+ * (e.g. a "Title and Content" content placeholder)
3073
+ * - the table also inherits the placeholder's position/size for any of x/y/w/h left unset
3074
+ * @example 'body' // bind to the layout placeholder named 'body'
3075
+ */
3076
+ placeholder?: string;
3077
+ /**
3078
+ * Whether to enable auto-paging
3079
+ * - auto-paging creates new slides as content overflows a slide
3080
+ * @default false
3081
+ */
3082
+ autoPage?: boolean;
3083
+ /**
3084
+ * Auto-paging character weight
3085
+ * - adjusts how many characters are used before lines wrap
3086
+ * - range: -1.0 to 1.0
3087
+ * @default 0.0
3088
+ * @example 0.5 // lines are longer (increases the number of characters that can fit on a given line)
3089
+ */
3090
+ autoPageCharWeight?: number;
3091
+ /**
3092
+ * Auto-paging line weight
3093
+ * - adjusts how many lines are used before slides wrap
3094
+ * - range: -1.0 to 1.0
3095
+ * @default 0.0
3096
+ * @example 0.5 // tables are taller (increases the number of lines that can fit on a given slide)
3097
+ */
3098
+ autoPageLineWeight?: number;
3099
+ /**
3100
+ * Whether table header row(s) should be repeated on each new slide creating by autoPage.
3101
+ * Use `autoPageHeaderRows` to designate how many rows comprise the table header (1+).
3102
+ * @default false
3103
+ */
3104
+ autoPageRepeatHeader?: boolean;
3105
+ /**
3106
+ * Number of rows that comprise table headers
3107
+ * - required when `autoPageRepeatHeader` is set to true.
3108
+ * @example 2 - repeats the first two table rows on each new slide created
3109
+ * @default 1
3110
+ */
3111
+ autoPageHeaderRows?: number;
3112
+ /**
3113
+ * The `y` location to use on subsequent slides created by autopaging
3114
+ * @default (top margin of Slide)
3115
+ */
3116
+ autoPageSlideStartY?: number;
3117
+ /**
3118
+ * Whether populated placeholders on the source slide (e.g. a title set via
3119
+ * `addText(text, { placeholder })`) are copied onto each overflow slide created by autoPage.
3120
+ * - new slides otherwise inherit only the layout's empty placeholders, so a title set on the
3121
+ * first slide would not appear on continuation slides.
3122
+ * @default false
3123
+ */
3124
+ autoPagePlaceholder?: boolean;
3125
+ /**
3126
+ * Default border for **every cell** in the table — not the table's outer perimeter.
3127
+ *
3128
+ * A single `BorderProps` is broadcast to all four sides of each cell; an array is read
3129
+ * in TRBL order and applied to each cell's own four sides. So
3130
+ * `border: [{type:'solid'}, {type:'none'}, {type:'solid'}, {type:'none'}]` gives *every*
3131
+ * cell a top and bottom rule — a full set of horizontal grid lines, not a rule at the
3132
+ * top and bottom of the table. A cell's own `options.border` overrides this entirely.
3133
+ *
3134
+ * A `null` entry is a hole — that edge inherits from the table style — where
3135
+ * `{ type: 'none' }` writes an explicit no-line that overrides it. Authoring nothing at
3136
+ * all depends on {@link tableStyle}: a styled table leaves every edge absent so the style
3137
+ * paints its grid, and a table with no style takes four no-fill sides, which is what keeps
3138
+ * it clear of PowerPoint's no-style black hairline grid.
3139
+ *
3140
+ * For the perimeter, use {@link outerBorder}, which applies only to the cells on the
3141
+ * table's outside edge. The two compose: `border` draws the interior grid and
3142
+ * `outerBorder` overrides the edges it reaches.
3143
+ * @example border: { type:'solid', color:'D9D9D9', width:0.5 } // full grid
3144
+ * @example border: [{type:'solid'}, {type:'none'}, {type:'solid'}, {type:'none'}] // horizontal rules only
3145
+ */
3146
+ border?: BorderProps | [BorderProps | null, BorderProps | null, BorderProps | null, BorderProps | null];
3147
+ /**
3148
+ * Border for the table's outer perimeter only — the top edge of the first row, the
3149
+ * bottom edge of the last row, the left edge of the first column and the right edge of
3150
+ * the last column.
3151
+ *
3152
+ * A single `BorderProps` is used for all four perimeter sides; an array is read in TRBL
3153
+ * order, so `outerBorder: [box, box, box, box]` boxes the table and
3154
+ * `outerBorder: [rule, undefined, rule, undefined]` rules only above and below it.
3155
+ * An `undefined`/omitted entry leaves that side to whatever {@link border} (or the cell's
3156
+ * own `options.border`) already put there.
3157
+ *
3158
+ * Applied **after** every other border source, so it wins on the sides it touches and
3159
+ * leaves the interior alone — the "outline the table, no interior grid" case is
3160
+ * `outerBorder` with no `border` at all. Merged cells are handled: a span's covered cells
3161
+ * inherit the origin's borders, so a colspan straddling the last column still gets the
3162
+ * right-hand rule.
3163
+ * @example outerBorder: { type:'solid', color:'1A2B3C', width:1 } // box the table
3164
+ * @example outerBorder: [{type:'solid'}, undefined, {type:'solid'}, undefined] // rules above and below
3165
+ */
3166
+ outerBorder?: BorderProps | [BorderProps?, BorderProps?, BorderProps?, BorderProps?];
3167
+ /**
3168
+ * Width of table columns (inches)
3169
+ * - single value is applied to every column equally based upon `w`
3170
+ * - array of values in applied to each column in order
3171
+ * @default columns of equal width based upon `w`
3172
+ */
3173
+ colW?: number | number[];
3174
+ /**
3175
+ * Shrink columns proportionally so a too-wide table fits the slide.
3176
+ * - `'shrink'`: if the total column width exceeds the space available between
3177
+ * the table's `x` and the right slide margin, scale every column down by the
3178
+ * same factor so the whole table fits. Columns that already fit are untouched.
3179
+ * - applies to an explicit `colW` array (the common "too many columns" case) and
3180
+ * to a `w` wider than the slide; never grows columns and never enforces a
3181
+ * minimum width, so a very high column count can still become thin.
3182
+ * - opt-in: explicit widths are otherwise emitted as-is and may run off the slide.
3183
+ * @default undefined (no scaling)
3184
+ */
3185
+ fitColumns?: 'shrink';
3186
+ /**
3187
+ * Table-level text-fit policy, cascaded to every cell that does not set its own
3188
+ * {@link TableCellProps.fit}.
3189
+ * - `'shrink'`: each cell whose row has a **fixed** height that its wrapped text
3190
+ * would exceed gets a reduced literal font size baked onto its runs so the text
3191
+ * fits (see {@link TableCellProps.fit} for the full semantics and the font-metrics
3192
+ * requirement). Cells that set their own `fit` win over this table default.
3193
+ * - `'none'` / `'resize'` / the object form are accepted for parity with
3194
+ * {@link TextPropsOptions.fit} but only `'shrink'` is acted on for table cells.
3195
+ * @default undefined (cells keep their authored size)
3196
+ * @example 'shrink'
3197
+ */
3198
+ fit?: 'none' | 'shrink' | 'resize' | TextFitShrinkProps;
3199
+ /**
3200
+ * Mark the first row as a header row.
3201
+ * Emits `firstRow="1"` on `<a:tblPr>`, activating the first-row style region of
3202
+ * the table style and satisfying the PowerPoint accessibility checker's "table header" rule.
3203
+ * @default false
3204
+ */
3205
+ hasHeader?: boolean;
3206
+ /**
3207
+ * Mark the last row as a footer row.
3208
+ * Emits `lastRow="1"` on `<a:tblPr>`, activating the last-row style region.
3209
+ * Requires `tableStyle` to have a visible effect.
3210
+ * @default false
3211
+ */
3212
+ hasFooter?: boolean;
3213
+ /**
3214
+ * Enable alternating row (band) shading.
3215
+ * Emits `bandRow="1"` on `<a:tblPr>`, activating band1H/band2H style regions.
3216
+ * Requires `tableStyle` to have a visible effect.
3217
+ * @default false
3218
+ */
3219
+ hasBandedRows?: boolean;
3220
+ /**
3221
+ * Enable alternating column (band) shading.
3222
+ * Emits `bandCol="1"` on `<a:tblPr>`, activating band1V/band2V style regions.
3223
+ * Requires `tableStyle` to have a visible effect.
3224
+ * @default false
3225
+ */
3226
+ hasBandedColumns?: boolean;
3227
+ /**
3228
+ * Apply special styling to the first column.
3229
+ * Emits `firstCol="1"` on `<a:tblPr>`, activating the firstCol style region.
3230
+ * Requires `tableStyle` to have a visible effect.
3231
+ * @default false
3232
+ */
3233
+ hasFirstColumn?: boolean;
3234
+ /**
3235
+ * Apply special styling to the last column.
3236
+ * Emits `lastCol="1"` on `<a:tblPr>`, activating the lastCol style region.
3237
+ * Requires `tableStyle` to have a visible effect.
3238
+ * @default false
3239
+ */
3240
+ hasLastColumn?: boolean;
3241
+ /**
3242
+ * Lay the table out right-to-left.
3243
+ * Emits `rtl="1"` on `<a:tblPr>`, which mirrors the column order so the first
3244
+ * column renders on the right — the correct layout for RTL scripts (Arabic, Hebrew).
3245
+ * This controls only the table/column direction; per-cell text direction is set
3246
+ * with each cell's `rtlMode` option.
3247
+ * @default false
3248
+ */
3249
+ rtl?: boolean;
3250
+ /**
3251
+ * Built-in table style to apply, as a `TableStyle` member.
3252
+ * Emits `<a:tableStyleId>` inside `<a:tblPr>` with the corresponding GUID.
3253
+ * Style flags (`hasHeader`, `hasFooter`, `hasBandedRows`, etc.) select which
3254
+ * regions of the chosen style are activated; they have no visible effect without
3255
+ * a `tableStyle` set.
3256
+ *
3257
+ * **Only a built-in GUID renders.** PowerPoint resolves `<a:tableStyleId>` against
3258
+ * its own table-style gallery and never reads a style definition out of the package,
3259
+ * so a GUID it does not recognise leaves the table with PowerPoint's no-style look —
3260
+ * a black hairline grid. For brand colours use direct formatting instead:
3261
+ * `headerRow`, `columns[i]`, the table-level {@link border} / {@link fill}, or per-cell
3262
+ * options. See `docs/tables.md` → "Table styles".
3263
+ *
3264
+ * @example tableStyle: pptx.TableStyle.MEDIUM_STYLE_2_ACCENT_1
3265
+ */
3266
+ tableStyle?: TableStyle;
3267
+ /**
3268
+ * Inline styling for the header (first) row, applied as direct per-cell formatting.
3269
+ *
3270
+ * This is how a header is styled distinctly from the body: each property is merged
3271
+ * onto every cell of row 0 (`fill`, `color`, `bold`, `align`, `border`, etc.).
3272
+ *
3273
+ * Precedence (highest wins), matching how PowerPoint resolves styling — direct cell
3274
+ * formatting overrides a table-style region:
3275
+ * 1. explicit per-cell `options` on a row-0 cell
3276
+ * 2. this `headerRow`
3277
+ * 3. the `firstRow` region of a built-in `tableStyle`
3278
+ * 4. the library's per-cell defaults
3279
+ *
3280
+ * Setting `headerRow` also implies `hasHeader: true` (emits `firstRow="1"` for the
3281
+ * accessibility "table header" marker) unless `hasHeader` is explicitly set to `false`.
3282
+ * @example headerRow: { fill: { color:'1A2B3C' }, color:'FFFFFF', bold:true, align:'center' }
3283
+ */
3284
+ headerRow?: TableCellProps;
3285
+ /**
3286
+ * Per-column default cell styling, applied as direct per-cell formatting.
3287
+ *
3288
+ * `columns[i]` is merged onto every cell that starts in column `i` (`fill`, `color`,
3289
+ * `bold`, `align`, `valign`, `border`, `margin`, …), so a wide **colored** matrix —
3290
+ * per-column fills, maturity-gradient headers — does not require hand-writing a fill
3291
+ * onto every cell. Entries may be sparse (`columns[2]` alone styles only column 2);
3292
+ * an `undefined`/omitted entry leaves that column untouched. The whole option is
3293
+ * optional and degrades cleanly to today's text-on-white when not given.
3294
+ *
3295
+ * Precedence (highest wins), matching how PowerPoint resolves styling — direct cell
3296
+ * formatting overrides a table-style region:
3297
+ * 1. explicit per-cell `options`
3298
+ * 2. `headerRow` (row 0 only)
3299
+ * 3. this `columns[colIdx]`
3300
+ * 4. a built-in `tableStyle` / the library's per-cell defaults
3301
+ *
3302
+ * The merge is property-level, so a header cell keeps `headerRow`'s typography **and**
3303
+ * takes its column's `fill` when they set different properties. For a graduated header
3304
+ * band, put shared header typography (bold/white/centered, **no fill**) in `headerRow`
3305
+ * and let each `columns[i].fill` supply that column's fill.
3306
+ *
3307
+ * Column index counts each cell's `colspan` (default 1) within a row, so merged cells
3308
+ * map to the correct column; it does not track `rowspan`s inherited from earlier rows.
3309
+ *
3310
+ * There is deliberately no built-in "group bracket" annotation. Label a span of columns
3311
+ * by composing existing primitives: `addShape('rightBrace', …)` (or `'bracePair'`) plus
3312
+ * `addText`, positioned from the table's `x` and `colW` (a span's `x`/`w` is the running
3313
+ * sum of the preceding/covered column widths).
3314
+ *
3315
+ * @example columns: [{}, { fill: { color:'E8F0FE' } }, { fill: { color:'C6DAFC' } }] // per-column solid fills
3316
+ * @example // gradient header: shared typography on headerRow, graduated fills per column
3317
+ * headerRow: { color:'FFFFFF', bold:true, align:'center' },
3318
+ * columns: [{}, { fill:{color:'BBD3FB'} }, { fill:{color:'89AEF6'} }, { fill:{color:'4B7BE5'} }]
3319
+ */
3320
+ columns?: TableCellProps[];
3321
+ /**
3322
+ * Default cell background — **stamped onto every cell**, not painted behind the table.
3323
+ *
3324
+ * Each cell that does not set its own `options.fill` (or take one from `headerRow` /
3325
+ * `columns[i]`) gets this as its own `a:tcPr` fill. A picture fill is embedded once and
3326
+ * shared by every cell that inherits it.
3327
+ *
3328
+ * Visually this is usually what you want, but it is not what a source deck contains, and
3329
+ * it has one real consequence: because every cell ends up explicitly filled, a cell that
3330
+ * later gets its own fill has nothing to fall back to. For a genuine table background —
3331
+ * one `a:tblPr` fill that cells sit on top of — use {@link tableFill}.
3332
+ * @example { color:'FF0000' } // hex color (red)
3333
+ * @example { color:'0088CC', transparency:50 } // hex color, 50% transparent
3334
+ * @example { color:SchemeColor.accent1 } // theme color Accent1
3335
+ * @example { type:'image', image:{ path:'watermark.png' } } // picture fill
3336
+ */
3337
+ fill?: ShapeFillProps;
3338
+ /**
3339
+ * The table's own background (`a:tblPr` fill) — one fill behind the whole table that
3340
+ * every cell sits on top of.
3341
+ *
3342
+ * The counterpart to {@link fill}, and the difference is where the paint lands rather
3343
+ * than how it looks: `fill` copies a colour onto every cell, while this writes a single
3344
+ * fill on the table itself. That matters when a cell is meant to be transparent — with
3345
+ * `tableFill`, an unfilled cell shows the table background through; with `fill` there is
3346
+ * no such thing as an unfilled cell. It is also what a deck read back from PowerPoint
3347
+ * actually carries, so a replica reproduces the source's structure rather than an
3348
+ * equivalent-looking flattening of it.
3349
+ *
3350
+ * Takes the same `ShapeFillProps` a cell does — solid, gradient, pattern or picture.
3351
+ * @example { color:'F2F2F2' } // a light background behind the whole table
3352
+ * @example { type:'image', image:{ path:'watermark.png' } } // one watermark, not one per cell
3353
+ */
3354
+ tableFill?: ShapeFillProps;
3355
+ /**
3356
+ * Cell margin (inches)
3357
+ * - affects all table cells, is superceded by cell options
3358
+ */
3359
+ margin?: Margin;
3360
+ /**
3361
+ * Height of table rows (inches)
3362
+ * - single value is applied to every row equally based upon `h`
3363
+ * - array of values in applied to each row in order
3364
+ * @default rows of equal height based upon `h`
3365
+ */
3366
+ rowH?: number | number[];
3367
+ /**
3368
+ * DEV-ONLY diagnostic flag: when `true`, logs a verbose trace of the auto-paging
3369
+ * calculations to the console. Intended for debugging table layout only; leave unset
3370
+ * in production. Inherited by {@link TableToSlidesProps}.
3371
+ * @default false
3372
+ */
3373
+ verbose?: boolean;
3374
+ }
3375
+ interface TableCell {
3376
+ _type?: SlideObjectType.tablecell;
3377
+ /** lines in this cell (autoPage) */
3378
+ _lines?: TableCell[][];
3379
+ /** `text` prop but guaranteed to hold "TableCell[]" */
3380
+ _tableCells?: TableCell[];
3381
+ /** height in EMU */
3382
+ _lineHeight?: number;
3383
+ _hmerge?: boolean;
3384
+ _vmerge?: boolean;
3385
+ _rowContinue?: number;
3386
+ /** origin cell of a colspan/rowspan span, set on the dummy `_hmerge`/`_vmerge` cells so they can
3387
+ * inherit the origin's border/fill and render the merged region's outer edges */
3388
+ _spanOrigin?: TableCell;
3389
+ /**
3390
+ * Cell content: a plain string, or an array of `TableCell` runs for mixed formatting.
3391
+ * (A `number` is still coerced to a string at runtime for plain-JS callers, but is no
3392
+ * longer part of the type — pass `String(n)` from TypeScript.)
3393
+ */
3394
+ text?: string | TableCell[];
3395
+ options?: TableCellProps;
3396
+ }
3397
+ interface TableRowSlide {
3398
+ rows: TableRow[];
3399
+ /**
3400
+ * Per-row height (inches) aligned 1:1 with `rows`, derived from the original `rowH` array.
3401
+ * Auto-paging splits/reorders rows across slides and inserts repeated headers, so the caller's
3402
+ * `rowH[i]` (keyed by *original* row index) can no longer be applied by physical row index on
3403
+ * each generated slide. This carries each output row's resolved height so a configured height
3404
+ * follows its source row instead of being re-applied to whatever lands at that index.
3405
+ * Entries are `undefined` where no explicit height was configured (auto-distributed height).
3406
+ */
3407
+ rowH?: Array<number | undefined>;
3408
+ }
3409
+ type TableRow = TableCell[];
3410
+ //#endregion
3411
+ //#region src/types/animation.d.ts
3412
+ /**
3413
+ * Slide transition and animation types.
3414
+ *
3415
+ * Re-exported by `./index.js`, which is the import site for the rest of `src/`.
3416
+ */
3417
+ /**
3418
+ * Base ECMA-376 slide-transition type (`p:transition`'s single type child). Each
3419
+ * maps to a `<p:TYPE/>` element; type-specific variants (e.g. direction) go in
3420
+ * {@link TransitionProps.variant}. Modern PowerPoint-only transitions (Morph,
3421
+ * Vortex, …) live in the `p14`/`p15`/`p159` namespaces and are out of authoring
3422
+ * scope for now. See `docs/animations-and-transitions.md`.
3423
+ */
3424
+ type TransitionType = 'blinds' | 'checker' | 'circle' | 'comb' | 'cover' | 'cut' | 'diamond' | 'dissolve' | 'fade' | 'newsflash' | 'plus' | 'pull' | 'push' | 'random' | 'randomBar' | 'split' | 'strips' | 'wedge' | 'wheel' | 'wipe' | 'zoom';
3425
+ /**
3426
+ * Slide-show transition applied between slides (`p:transition`). Assign to
3427
+ * {@link Slide.transition}. Setting `durationMs` emits PowerPoint's
3428
+ * `mc:AlternateContent` form (a `p14` Choice carrying `p14:dur` plus a base
3429
+ * `mc:Fallback`); otherwise only the coarse `speed` bucket is written.
3430
+ * @example slide.transition = { type: 'push', durationMs: 1250, variant: { dir: 'd' } }
3431
+ */
3432
+ interface TransitionProps {
3433
+ /** Transition type (the `<p:TYPE/>` element), e.g. `fade`, `push`, `wipe`, `cut`, `dissolve`. */
3434
+ type: TransitionType;
3435
+ /** Exact duration in milliseconds (`p14:dur`); emits the `mc:AlternateContent` form. */
3436
+ durationMs?: number;
3437
+ /** Coarse speed bucket (`spd`); derived from `durationMs` when omitted, else defaults to `fast`. */
3438
+ speed?: 'slow' | 'med' | 'fast';
3439
+ /** Advance on mouse click (`advClick`). @default true */
3440
+ advanceOnClick?: boolean;
3441
+ /** Auto-advance after this many milliseconds (`advTm`). */
3442
+ advanceAfterMs?: number;
3443
+ /** Type-specific variant attributes, e.g. `{ dir: 'd' }` for push, `{ spokes: '2' }` for wheel. */
3444
+ variant?: Record<string, string>;
3445
+ /** Sound played with the transition (`p:sndAc`): a start sound (embedded WAV) or the stop-previous form. */
3446
+ sound?: TransitionSoundProps;
3447
+ /**
3448
+ * Internal: the slide relationship id assigned to the embedded sound part, stamped
3449
+ * by the export-time registration pass. Not part of the authoring surface.
3450
+ */
3451
+ _sndRId?: number;
3452
+ }
3453
+ /**
3454
+ * A transition sound (`p:sndAc`). Either a **start sound** — an embedded WAV played
3455
+ * when the transition runs (`p:stSnd` → `p:snd`), optionally looped — or the
3456
+ * **stop-previous** form (`p:endSnd`) that silences a still-playing transition
3457
+ * sound. Built-in PowerPoint sounds embed identically to a custom file, so there is
3458
+ * no separate built-in path: supply the WAV bytes via `data` or `path`.
3459
+ * See `docs/animations-and-transitions.md`.
3460
+ */
3461
+ interface TransitionSoundProps {
3462
+ /** Embedded sound bytes as a base64 data URI (e.g. `data:audio/wav;base64,…`) or raw base64. */
3463
+ data?: string;
3464
+ /** Path to a sound file, read at export time (alternative to `data`). */
3465
+ path?: string;
3466
+ /** Display name emitted on `<p:snd @name>` (e.g. `ding.wav`); defaults to the file name. */
3467
+ name?: string;
3468
+ /** Loop the sound until the next sound starts (`<p:stSnd loop="1">`). @default false */
3469
+ loop?: boolean;
3470
+ /** Emit the stop-previous form (`<p:endSnd/>`) instead of a start sound. Mutually exclusive with `data`/`path`. */
3471
+ stopPrevious?: boolean;
3472
+ }
3473
+ /**
3474
+ * A preset build-animation effect. The supported set is fixed (each is a verbatim
3475
+ * template captured from PowerPoint); adding one means adding a fixture + template,
3476
+ * not a new code path. See `docs/animations-and-transitions.md`.
3477
+ */
3478
+ type PresetEffect = 'fadeIn' | 'flyIn' | 'appear' | 'wipe' | 'grow' | 'spin' | 'fadeOut' | 'flyOut';
3479
+ /** When a build-animation effect starts relative to the preceding one. */
3480
+ type AnimationTrigger = 'onClick' | 'withPrevious' | 'afterPrevious';
3481
+ /**
3482
+ * A preset build animation on a shape (entrance/emphasis/exit), added via
3483
+ * {@link Slide.addAnimation}. Target the shape by its 0-based add order
3484
+ * (`shapeIndex`, mapping to the generated `spid = shapeIndex + 2`) or by
3485
+ * `objectName`. Effects play in the order added, grouped into click steps by
3486
+ * `trigger`.
3487
+ */
3488
+ interface AnimationProps {
3489
+ /** The preset effect to play. */
3490
+ preset: PresetEffect;
3491
+ /**
3492
+ * 0-based add order of the target shape on the slide (`spid = shapeIndex + 2`).
3493
+ * Counts top-level objects only; use `objectName` to target a shape inside a group.
3494
+ */
3495
+ shapeIndex?: number;
3496
+ /**
3497
+ * Target shape by its `objectName` (alternative to `shapeIndex`). Any shape on the slide,
3498
+ * including one inside a group; an unresolved name warns and drops the effect.
3499
+ */
3500
+ objectName?: string;
3501
+ /** Trigger relative to the previous effect. @default 'onClick' */
3502
+ trigger?: AnimationTrigger;
3503
+ /** Effect duration in milliseconds; preset-specific default when omitted. */
3504
+ durationMs?: number;
3505
+ }
3506
+ //#endregion
3507
+ //#region src/types/master.d.ts
3508
+ interface SlideNumberProps extends PositionProps, TextBaseProps {
3509
+ /**
3510
+ * margin (inches) — text-frame internal margin; a value `>= 1` warns as a likely legacy points value
3511
+ */
3512
+ margin?: Margin;
3513
+ }
3514
+ interface SlideMasterChartProps {
3515
+ type: CHART_NAME | ChartMulti[];
3516
+ data: OptsChartData[];
3517
+ options?: ChartOpts;
3518
+ opts?: ChartOpts;
3519
+ }
3520
+ /**
3521
+ * One object on a slide master, as a key-tagged descriptor.
3522
+ *
3523
+ * The six descriptors it shares with a group child are {@link CommonObjectDescriptor}; the two
3524
+ * below are the master's own — a chart, which a group cannot hold, and a placeholder, which is
3525
+ * the whole point of a master.
3526
+ */
3527
+ type SlideMasterObject = CommonObjectDescriptor | {
3528
+ chart: SlideMasterChartProps;
3529
+ } | {
3530
+ placeholder: {
3531
+ options: PlaceholderProps;
3532
+ /**
3533
+ * Text to be shown in placeholder (shown until user focuses textbox or adds text)
3534
+ * - Leave blank to have powerpoint show default phrase (ex: "Click to add title")
3535
+ */
3536
+ text?: string;
3537
+ };
3538
+ };
3539
+ /**
3540
+ * Bullet configuration for one slide-master text-style level (`a:buChar`/`a:buAutoNum`/`a:buNone`).
3541
+ * A focused subset of the run-level bullet model — picture bullets and per-glyph sizing are not
3542
+ * supported in master defaults (those require slide rels). Set `bullet: false` to suppress the
3543
+ * level's bullet entirely.
3544
+ */
3545
+ interface MasterBulletProps {
3546
+ /** `'bullet'` emits a character bullet (`a:buChar`); `'number'` emits an auto-number (`a:buAutoNum`). @default 'bullet' */
3547
+ type?: 'bullet' | 'number';
3548
+ /** Bullet character (unicode code point hex), e.g. `'2022'` for •. Used when `type` is `'bullet'`. */
3549
+ characterCode?: string;
3550
+ /** Glyph font typeface for the bullet character (`a:buFont`), e.g. `'Arial'` or `'Wingdings'`. */
3551
+ fontFace?: string;
3552
+ /** Auto-number scheme (`a:buAutoNum@type`) when `type` is `'number'`, e.g. `'arabicPeriod'`. @default 'arabicPeriod' */
3553
+ numberType?: string;
3554
+ /** Starting value for auto-numbered bullets (`a:buAutoNum@startAt`). @default 1 */
3555
+ numberStartAt?: number;
3556
+ }
3557
+ /**
3558
+ * Styling for one paragraph level (`a:lvlNpPr`) of a slide-master text style. Every field is
3559
+ * optional; an unset field keeps PowerPoint's built-in default for that level. Configure via
3560
+ * {@link SlideMasterProps.textStyles}.
3561
+ */
3562
+ interface MasterTextStyleLevel {
3563
+ /** Font size in points (`a:defRPr@sz`), e.g. `24`. */
3564
+ fontSize?: number;
3565
+ /** Font face (`a:defRPr/a:latin@typeface`). Unset keeps the theme font (`+mn-lt`/`+mj-lt`). */
3566
+ fontFace?: string;
3567
+ /** Text color — hex (`'C00000'`) or theme slot (`'tx1'`) — emitted as `a:defRPr/a:solidFill`. */
3568
+ color?: Color;
3569
+ /** Bold text (`a:defRPr@b`). */
3570
+ bold?: boolean;
3571
+ /** Italic text (`a:defRPr@i`). */
3572
+ italic?: boolean;
3573
+ /** Horizontal alignment (`a:lvlNpPr@algn`). */
3574
+ align?: HAlign;
3575
+ /** Left margin in inches (`a:lvlNpPr@marL`); for a hanging bullet this is the text indent. */
3576
+ marginLeft?: number;
3577
+ /** First-line indent in inches (`a:lvlNpPr@indent`); negative produces a hanging bullet. */
3578
+ indent?: number;
3579
+ /** Bullet config: `false` emits `a:buNone`; an object configures a char/number bullet. Unset keeps the level default. */
3580
+ bullet?: boolean | MasterBulletProps;
3581
+ }
3582
+ /**
3583
+ * Per-level slide-master text styles, written to `slideMaster1.xml`'s `<p:txStyles>`.
3584
+ * Because a deck has a single shared slide master, these styles are **deck-wide**: when set on more
3585
+ * than one `defineSlideMaster()` call the last value for each group (`title`/`body`/`other`) wins.
3586
+ */
3587
+ interface MasterTextStyleProps {
3588
+ /** Title placeholder style (`p:titleStyle`, single level). */
3589
+ title?: MasterTextStyleLevel;
3590
+ /** Body placeholder per-level styles (`p:bodyStyle`, levels 1–9; index 0 is `lvl1`). */
3591
+ body?: MasterTextStyleLevel[];
3592
+ /** Other/default placeholder per-level styles (`p:otherStyle`, levels 1–9). */
3593
+ other?: MasterTextStyleLevel[];
3594
+ }
3595
+ interface SlideMasterProps {
3596
+ /**
3597
+ * Unique name for this master
3598
+ */
3599
+ title: string;
3600
+ background?: BackgroundProps;
3601
+ margin?: Margin;
3602
+ slideNumber?: SlideNumberProps;
3603
+ objects?: SlideMasterObject[];
3604
+ /**
3605
+ * Per-level master text styles (title / body / other) written to the shared slide master's
3606
+ * `<p:txStyles>`. Configure nested bullet character, font size, color, alignment, and indent
3607
+ * for each of the nine list levels. Deck-wide (see {@link MasterTextStyleProps}).
3608
+ * @example textStyles: { body: [{ fontSize: 24, color: 'C00000', bullet: { characterCode: '25AA' } }] }
3609
+ */
3610
+ textStyles?: MasterTextStyleProps;
3611
+ }
3612
+ //#endregion
3613
+ //#region src/types/model3d.d.ts
3614
+ /** A point or direction in the model's 3D scene, in metres. */
3615
+ interface Model3dPoint {
3616
+ x: number;
3617
+ y: number;
3618
+ z: number;
3619
+ }
3620
+ /**
3621
+ * Camera override for `addModel3d()`, mapping onto `am3d:camera`.
3622
+ *
3623
+ * The defaults are what PowerPoint itself wrote for a 2×2×2 cube, and they are correct for any
3624
+ * model whose bounding box is roughly cubic **once `meterPerModelUnit` is right** — the camera is
3625
+ * expressed in metres, so the scale is what actually decides framing.
3626
+ *
3627
+ * PowerPoint's own rule, measured against three models: it normalizes the model's largest
3628
+ * bounding-box extent to 1 metre and then places the camera at
3629
+ *
3630
+ * ```
3631
+ * pos.z = |halfExtents / maxExtent| / sin(fov / 2)
3632
+ * ```
3633
+ *
3634
+ * looking at the origin. A caller who knows their model's bounding box can reproduce that
3635
+ * exactly; a caller who does not should at least set `meterPerModelUnit` to `1 / maxExtent`.
3636
+ */
3637
+ interface Model3dCameraProps {
3638
+ /**
3639
+ * Camera position in metres (`am3d:camera/am3d:pos`).
3640
+ * @default { x: 0, y: 0, z: 2.2630334 }
3641
+ */
3642
+ pos?: Model3dPoint;
3643
+ /**
3644
+ * Point the camera aims at, in metres (`am3d:camera/am3d:lookAt`).
3645
+ * @default { x: 0, y: 0, z: 0 }
3646
+ */
3647
+ lookAt?: Model3dPoint;
3648
+ /**
3649
+ * Camera "up" direction (`am3d:camera/am3d:up`). Need not be normalized.
3650
+ * @default { x: 0, y: 1, z: 0 }
3651
+ */
3652
+ up?: Model3dPoint;
3653
+ /**
3654
+ * Vertical field of view in **degrees** (`am3d:perspective@fov`).
3655
+ * - range: greater than 0 and less than 180
3656
+ * @default 45
3657
+ */
3658
+ fov?: number;
3659
+ }
3660
+ /**
3661
+ * Add an embedded 3D model (PowerPoint's Insert ▸ 3D Models) to a slide.
3662
+ *
3663
+ * The `.glb` bytes travel inside the `.pptx` (in `ppt/media/`), so PowerPoint 2019+ renders and
3664
+ * lets the viewer orbit the model. Requires either `data` or `path`. Linked (non-embedded)
3665
+ * models are not supported.
3666
+ */
3667
+ interface Model3dBaseProps extends PositionProps, ObjectNameProps {
3668
+ /**
3669
+ * Picture of the model shown wherever the live 3D view is unavailable — a raster image `path`
3670
+ * (Node/local) or base64 `data:` URI.
3671
+ * - the library cannot render a 3D scene, so when this is omitted a neutral gray placeholder is
3672
+ * embedded; PowerPoint 2019+ draws the live model over it, but every other consumer — and
3673
+ * PowerPoint's own `mc:Fallback` path, thumbnails, and PDF export — shows exactly what is here
3674
+ * - supply a real render whenever the deck is meant to read correctly outside PowerPoint
3675
+ * @example { path: 'assets/engine-render.png' }
3676
+ */
3677
+ preview?: {
3678
+ path?: string;
3679
+ data?: string;
3680
+ };
3681
+ /**
3682
+ * Camera override. Omitted, ts-pptx emits the camera PowerPoint wrote for a 2×2×2 cube.
3683
+ * @see {@link Model3dCameraProps} for the framing formula and when this matters.
3684
+ */
3685
+ camera?: Model3dCameraProps;
3686
+ /**
3687
+ * Metres per model unit (`am3d:trans/am3d:meterPerModelUnit`) — the scale that decides how
3688
+ * large the model is in the scene the {@link camera} looks at.
3689
+ *
3690
+ * This is the single override most models need. PowerPoint sets it to `1 / maxExtent`, where
3691
+ * `maxExtent` is the model's largest bounding-box dimension in model units, which normalizes
3692
+ * every model to 1 metre across. ts-pptx does not parse the `.glb`, so it cannot measure that
3693
+ * — it defaults to `0.5`, correct for a model 2 units across. A model 100 units across left at
3694
+ * the default is a 50-metre object with the camera 2.26 metres from its centre, i.e. the
3695
+ * viewer is inside it.
3696
+ * - range: greater than 0
3697
+ * @default 0.5
3698
+ * @example 1 / 100 // a model whose largest bounding-box dimension is 100 units
3699
+ */
3700
+ meterPerModelUnit?: number;
3701
+ /**
3702
+ * Alt text (`p:cNvPr@descr`) — what a screen reader announces for the model.
3703
+ */
3704
+ altText?: string;
3705
+ }
3706
+ /**
3707
+ * Options for `slide.addModel3d()`. Requires either `data` (base64, with or without a
3708
+ * `data:...;base64,` header) or `path` (a local/remote `.glb` read at export time).
3709
+ *
3710
+ * Sizing note: `w`/`h` default to 4 × 3 inches rather than being measured. A 3D model has no
3711
+ * intrinsic aspect ratio, and the library never opens the payload.
3712
+ */
3713
+ type Model3dProps = Model3dBaseProps & DataOrPathRequiredProps;
3714
+ //#endregion
3715
+ //#region src/types/slide.d.ts
3716
+ /**
3717
+ * A child object that can be placed inside a group via `slide.addGroup()`.
3718
+ *
3719
+ * The six descriptors it shares with `SlideMasterObject` are {@link CommonObjectDescriptor};
3720
+ * `group` is the group's own, and the master's `chart` and `placeholder` are deliberately not
3721
+ * here. A `group` child nests another group (an identity child
3722
+ * coordinate space is kept at every depth, so descendants keep their slide-absolute
3723
+ * coordinates). Charts, media, tables, and placeholders are intentionally excluded (see
3724
+ * `addGroup`); passing one logs a warning and skips it.
3725
+ */
3726
+ type GroupChildProps = CommonObjectDescriptor | {
3727
+ group: {
3728
+ children: GroupChildProps[];
3729
+ options?: GroupProps;
3730
+ };
3731
+ };
3732
+ /**
3733
+ * Options for `slide.addGroup()`.
3734
+ *
3735
+ * The group keeps an identity child coordinate space (`chOff/chExt == off/ext`) at every depth:
3736
+ * children — including nested groups — keep their slide-absolute `x/y/w/h`. A consequence worth
3737
+ * knowing: a group's own frame never moves or scales its children, it only places the selection
3738
+ * handle and the rotate pivot.
3739
+ *
3740
+ * The frame is all-or-nothing. Pass all four of `x/y/w/h` to set it explicitly, or none to have it
3741
+ * auto-computed as the bounding box of the children. A partial frame is ambiguous, so it warns and
3742
+ * falls back to auto-bounds on every axis.
3743
+ */
3744
+ interface GroupProps extends PositionProps, ObjectNameProps {
3745
+ /** Rotation in degrees (applied to the whole group) */
3746
+ rotate?: number;
3747
+ /** Flip the group horizontally */
3748
+ flipH?: boolean;
3749
+ /** Flip the group vertically */
3750
+ flipV?: boolean;
3751
+ }
3752
+ interface ObjectOptions extends ImageBaseProps, PositionProps, ShapeProps, TableCellProps, TextPropsOptions {
3753
+ _placeholderIdx?: number;
3754
+ _placeholderType?: PLACEHOLDER_TYPE;
3755
+ /** Connector adjust-guide values (OOXML 1000ths-of-a-percent), one per bend; emitted as `<a:gd name="adjN">` */
3756
+ _connectorAdj?: number[];
3757
+ /** Connector start-point binding: target shape `objectName` (raw, as the caller spelled it) + connection-site index; resolved to `<a:stCxn>` at serialize time */
3758
+ _startCxn?: {
3759
+ name: string;
3760
+ idx: number;
3761
+ };
3762
+ /** Connector end-point binding: target shape `objectName` (raw, as the caller spelled it) + connection-site index; resolved to `<a:endCxn>` at serialize time */
3763
+ _endCxn?: {
3764
+ name: string;
3765
+ idx: number;
3766
+ };
3767
+ /**
3768
+ * Image: which dimensions were omitted by the user and should be derived from the image's
3769
+ * natural pixel size at serialize time. Path-based images can't be measured synchronously in
3770
+ * `addImage()` (bytes are loaded async during export), so the missing extent is backfilled
3771
+ * once `_relsMedia[].data` is populated. `{ w, h }` true means "derive this side from the
3772
+ * natural ratio". Base64 `data` images are measured eagerly in `addImage()` and never set this.
3773
+ */
3774
+ _szAuto?: {
3775
+ w: boolean;
3776
+ h: boolean;
3777
+ };
3778
+ cx?: Coord;
3779
+ cy?: Coord;
3780
+ margin?: Margin;
3781
+ colW?: number | number[];
3782
+ rowH?: number | number[];
3783
+ hasHeader?: boolean;
3784
+ hasFooter?: boolean;
3785
+ hasBandedRows?: boolean;
3786
+ hasBandedColumns?: boolean;
3787
+ hasFirstColumn?: boolean;
3788
+ hasLastColumn?: boolean;
3789
+ rtl?: boolean;
3790
+ tableStyle?: TableStyle;
3791
+ /**
3792
+ * Table perimeter border. `addTableDefinition` normalizes it to a 4-tuple (TRBL, sides
3793
+ * left unset as `undefined`) before it reaches the emitter, so the serializer never has
3794
+ * to re-handle the single-`BorderProps` form.
3795
+ */
3796
+ outerBorder?: TableProps['outerBorder'];
3797
+ /** Table background (`a:tblPr` fill), as distinct from `fill`, which is stamped onto each cell. */
3798
+ tableFill?: TableProps['tableFill'];
3799
+ }
3800
+ interface SlideLayout {
3801
+ background?: BackgroundProps;
3802
+ }
3803
+ interface Slide {
3804
+ addChart(data: OptsChartData[], options: ChartOpts & {
3805
+ type: CHART_NAME;
3806
+ }): Slide;
3807
+ addChart(charts: ChartMulti[], options?: ChartOpts): Slide;
3808
+ addConnector: (options: ConnectorProps) => Slide;
3809
+ addImage: (options: ImageProps) => Slide;
3810
+ addMedia: (options: MediaProps) => Slide;
3811
+ /** Embed a 3D model (Insert ▸ 3D Models) — a `.glb` PowerPoint 2019+ renders live. */
3812
+ addModel3d: (options: Model3dProps) => Slide;
3813
+ /** Embed an OLE object (Insert ▸ Object) whose bytes travel inside the `.pptx`. */
3814
+ addOleObject: (options: OleObjectProps) => Slide;
3815
+ addComment: (options: CommentProps) => Slide;
3816
+ addNotes: (notes: string | NotesProps | NotesProps[]) => Slide;
3817
+ addShape: (shapeName: SHAPE_NAME, options?: ShapeProps) => Slide;
3818
+ addTable: (tableRows: TableRow[], options?: TableProps) => Slide;
3819
+ addText: (text: string | number | TextProps[], options?: TextPropsOptions) => Slide;
3820
+ addAnimation: (options: AnimationProps) => Slide;
3821
+ /** Group child object descriptors into a single PowerPoint group (`<p:grpSp>`). */
3822
+ addGroup: (children: GroupChildProps[], options?: GroupProps) => Slide;
3823
+ /** Group objects already on this slide, addressed by their `objectName`, into a single group. */
3824
+ groupObjects: (objectNames: string[], options?: GroupProps) => Slide;
3825
+ readonly newAutoPagedSlides?: Slide[];
3826
+ /**
3827
+ * Slide-show transition played when advancing to this slide (`p:transition`).
3828
+ * @example slide.transition = { type: 'fade', durationMs: 1500 }
3829
+ */
3830
+ transition?: TransitionProps;
3831
+ /**
3832
+ * Slide width in inches, resolved from the active presentation layout.
3833
+ * Use for coordinate math instead of hard-coding layout dimensions.
3834
+ * @example slide.addText('Centered', { x: 0, w: slide.width, align: 'center' })
3835
+ */
3836
+ readonly width?: number;
3837
+ /**
3838
+ * Slide height in inches, resolved from the active presentation layout.
3839
+ */
3840
+ readonly height?: number;
3841
+ /**
3842
+ * Background color or image (`color` | `path` | `data`)
3843
+ * @example { color: 'FF3399' } - hex color
3844
+ * @example { color: 'FF3399', transparency:50 } - hex color with 50% transparency
3845
+ * @example { path: 'https://onedrives.com/myimg.png` } - retrieve image via URL
3846
+ * @example { path: '/home/user/images/myimg.png` } - retrieve image via local path
3847
+ * @example { data: 'image/png;base64,iVtDaDrF[...]=' } - base64 string
3848
+ */
3849
+ background?: BackgroundProps;
3850
+ /**
3851
+ * Default text color (hex format)
3852
+ * @example 'FF3399'
3853
+ * @default '000000' (DEF_FONT_COLOR)
3854
+ */
3855
+ color?: HexColor;
3856
+ /**
3857
+ * Whether slide is hidden
3858
+ * @default false
3859
+ */
3860
+ hidden?: boolean;
3861
+ /**
3862
+ * Slide number options
3863
+ */
3864
+ slideNumber?: SlideNumberProps;
3865
+ }
3866
+ interface AddSlideProps {
3867
+ /** Title of the slide master to use for the new slide (the `title` passed to {@link SlideMasterProps} via `defineSlideMaster`). */
3868
+ masterTitle?: string;
3869
+ sectionTitle?: string;
3870
+ }
3871
+ //#endregion
3872
+ export { BorderProps as $, NotesProps as $t, TableToSlidesDocument as A, ChartPropsChartHistogram as At, GradientStopProps as B, ChartPropsFillLine as Bt, TableCell as C, ShapeConnectionSite as Cn, ChartPropsAxisCat as Ct, TableProps as D, ChartPropsChartBar as Dt, TableCellProps as E, ChartPropsBase as Et, Coord as F, ChartPropsChartStock as Ft, Margin as G, OptsChartData as Gt, HexColor as H, ChartPropsTitle as Ht, DataOrPathProps as I, ChartPropsChartSurface as It, PositionProps as J, ObjectLockProps as Jt, PatternFillProps as K, OptsChartGridLine as Kt, DataOrPathRequiredProps as L, ChartPropsChartWaterfall as Lt, TableToSlidesProps as M, ChartPropsChartPie as Mt, BackgroundProps as N, ChartPropsChartRadar as Nt, TableRow as O, ChartPropsChartBoxWhisker as Ot, Color as P, ChartPropsChartRegionMap as Pt, VAlign as Q, MeasureTextOptions as Qt, GeometryPoint as R, ChartPropsDataLabel as Rt, TransitionType as S, ShapeAdjustValue as Sn, ChartOpts as St, TableCellDiagonals as T, ShapeProps as Tn, ChartPropsAxisVal as Tt, ImageFillProps as U, ChartSeriesOpts as Ut, HAlign as V, ChartPropsLegend as Vt, LinearGradientFillProps as W, LineCap as Wt, TextVertType as X, PlaceholderProps as Xt, RadialGradientFillProps as Y, ObjectNameProps as Yt, ThemeColor as Z, CommentProps as Zt, AnimationProps as _, MediaType as _n, ChartExBinning as _t, Slide as a, TableLayoutResult as an, ShapeFillProps as at, TransitionProps as b, ShapeAdjustHandlePolar as bn, ChartLineDash as bt, Model3dPoint as c, TextGlowProps as cn, ColorMapToken as ct, MasterTextStyleLevel as d, TextPropsOptions as dn, PresetMaterialType as dt, NotesTextOptions as en, ConnectorProps as et, MasterTextStyleProps as f, textRun as fn, ThemeColorSlot as ft, SlideNumberProps as g, MediaProps as gn, ChartErrorBarOptions as gt, SlideMasterProps as h, ImageProps as hn, ChartDataPointStyle as ht, ObjectOptions as i, TableCellLayout as in, ShadowProps as it, TableToSlidesElement as j, ChartPropsChartLine as jt, TableRowSlide as k, ChartPropsChartDoughnut as kt, Model3dProps as l, TextMeasurement as ln, LightRigDirection as lt, SlideMasterObject as m, ImageBaseProps as mn, ChartAxisTickMark as mt, GroupChildProps as n, ResolvedCommentAuthor as nn, HyperlinkActionJump as nt, SlideLayout as o, TextBaseProps as on, ShapeLineProps as ot, SlideMasterChartProps as p, textRuns as pn, ChartAreaProps as pt, PatternPreset as q, CommonObjectDescriptor as qt, GroupProps as r, SlideComment as rn, HyperlinkProps as rt, Model3dCameraProps as s, TextFitShrinkProps as sn, BevelPresetType as st, AddSlideProps as t, OverflowBoxOptions as tn, ConnectorType as tt, MasterBulletProps as u, TextProps as un, LightRigType as ut, AnimationTrigger as v, OleObjectProps as vn, ChartExGeography as vt, TableCell3DProps as w, ShapeGuide as wn, ChartPropsAxisSer as wt, TransitionSoundProps as x, ShapeAdjustHandleXY as xn, ChartMulti as xt, PresetEffect as y, ShapeAdjustHandle as yn, ChartExStatistics as yt, GradientFillProps as z, ChartPropsDataTable as zt };
3873
+ //# sourceMappingURL=slide-js0QpRV-.d.ts.map