@silurus/ooxml 0.75.3 → 0.75.5

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.
@@ -1,4 +1,4 @@
1
- //#region dist/.types-work/hyperlink-CHHEOeCL.d.ts
1
+ //#region dist/.types-work/hyperlink-DTGUpBI3.d.ts
2
2
  //#region packages/core/src/types/math.d.ts
3
3
  type MathStyle = 'roman' | 'italic' | 'bold' | 'boldItalic';
4
4
  interface MathRun {
@@ -149,182 +149,625 @@ interface Duotone$1 {
149
149
  clr2: string;
150
150
  }
151
151
  //#endregion
152
- //#region packages/core/src/types/chart.d.ts
153
- interface ChartSeries {
154
- name: string;
155
- /** Hex without '#'. null = fall back to palette. */
156
- color: string | null;
157
- /** Numeric values; null = missing data point. */
158
- values: (number | null)[];
152
+ //#region packages/core/src/types/common.d.ts
153
+ type PathCmd$2 = {
154
+ cmd: 'moveTo';
155
+ x: number;
156
+ y: number;
157
+ } | {
158
+ cmd: 'lineTo';
159
+ x: number;
160
+ y: number;
161
+ } | {
162
+ cmd: 'cubicBezTo';
163
+ x1: number;
164
+ y1: number;
165
+ x2: number;
166
+ y2: number;
167
+ x: number;
168
+ y: number;
169
+ } | {
170
+ cmd: 'arcTo';
171
+ wr: number;
172
+ hr: number;
173
+ stAng: number;
174
+ swAng: number;
175
+ } | {
176
+ cmd: 'close';
177
+ };
178
+ type Fill = SolidFill | NoFill | GradientFill | PatternFill | ImageFill;
179
+ interface SolidFill {
180
+ fillType: 'solid';
181
+ color: string;
182
+ }
183
+ interface NoFill {
184
+ fillType: 'none';
185
+ }
186
+ interface GradientStop$1 {
187
+ position: number;
188
+ color: string;
189
+ }
190
+ interface GradientFill {
191
+ fillType: 'gradient';
192
+ stops: GradientStop$1[];
193
+ /** degrees: 0 = left→right, 90 = top→bottom */
194
+ angle: number;
195
+ /** 'linear' | 'radial' */
196
+ gradType: string;
197
+ }
198
+ /**
199
+ * Preset pattern fill — ECMA-376 §20.1.8.40 (CT_PatternFillProperties)
200
+ * with `preset` drawn from §20.1.10.59 (ST_PresetPatternVal).
201
+ */
202
+ interface PatternFill {
203
+ fillType: 'pattern';
204
+ /** Foreground hex colour — used for the "1" pixels of the preset bitmap. */
205
+ fg: string;
206
+ /** Background hex colour — used for the "0" pixels. */
207
+ bg: string;
208
+ /** Preset name, e.g. "pct25", "horz", "diagCross", "lgGrid". */
209
+ preset: string;
210
+ }
211
+ /**
212
+ * ECMA-376 §20.1.8.30 (CT_RelativeRect) — the destination rectangle a stretched
213
+ * blip is mapped into, as edge insets relative to the fill region. Values are
214
+ * fractions (ST_Percentage / 100000); **negative values let the image bleed
215
+ * past the box (overscan)**. Absent edges default to 0.
216
+ */
217
+ interface FillRect {
218
+ l?: number;
219
+ t?: number;
220
+ r?: number;
221
+ b?: number;
222
+ }
223
+ /**
224
+ * ECMA-376 §20.1.8.58 (CT_TileInfoProperties) — tiled blip-fill placement.
225
+ * The blip repeats at its native size (scaled by sx/sy) across the fill box.
226
+ * Mutually exclusive with {@link ImageFill.fillRect} (the `stretch` mode).
227
+ */
228
+ interface TileInfo {
229
+ /** Horizontal offset of the first tile, in EMU (`tx`). Default 0. */
230
+ tx: number;
231
+ /** Vertical offset of the first tile, in EMU (`ty`). Default 0. */
232
+ ty: number;
233
+ /** Horizontal tile scale as a fraction (`sx` / 100000). Default 1.0. */
234
+ sx: number;
235
+ /** Vertical tile scale as a fraction (`sy` / 100000). Default 1.0. */
236
+ sy: number;
237
+ /** Mirror mode: `'none' | 'x' | 'y' | 'xy'` (`flip`). Default `'none'`. */
238
+ flip: string;
159
239
  /**
160
- * Per-data-point colors (pie / doughnut). Hex without '#'. null inside the
161
- * array = use palette for that slice. Omit entirely for non-pie series.
240
+ * Anchor corner the tile grid registers against:
241
+ * `tl|t|tr|l|ctr|r|bl|b|br` (`algn`). The schema has no default; a host may
242
+ * apply a compatibility fallback when omitted.
162
243
  */
163
- dataPointColors?: (string | null)[] | null;
244
+ algn?: string;
245
+ }
246
+ /**
247
+ * Image fill — ECMA-376 §20.1.8.14 (CT_BlipFillProperties). The embedded blip
248
+ * is carried as a zip path + MIME; the renderer fetches the bytes on demand via
249
+ * {@link RenderOptions.fetchImage} (no base64 inlined at parse time). Both
250
+ * fill-modes are modelled and mutually exclusive: `stretch` (§20.1.8.56) carries
251
+ * {@link ImageFill.fillRect}; `tile` (§20.1.8.58) carries {@link ImageFill.tile}.
252
+ */
253
+ interface ImageFill {
254
+ fillType: 'image';
164
255
  /**
165
- * Per-data-point data-label text colors. Used by chartEx (`<cx:dataLabel idx>`)
166
- * to override label colour per bar sample-2's waterfall paints negative
167
- * values in red while positive values stay black. Null inside the array =
168
- * fall back to the chart-level `dataLabelFontColor`.
256
+ * Embedded zip path of the blip (e.g. "word/media/image1.png"), for the lazy
257
+ * byte-on-demand pipeline. The renderer fetches the bytes via a path-keyed
258
+ * loader ({@link RenderOptions.fetchImage}) instead of inlining base64.
169
259
  */
170
- dataLabelColors?: (string | null)[] | null;
260
+ imagePath: string;
261
+ /** MIME type of the blip at {@link ImageFill.imagePath} (e.g. `image/png`). */
262
+ mimeType: string;
171
263
  /**
172
- * Series-level data-label text colour (`<c:ser><c:dLbls><c:txPr>…solidFill`,
173
- * ECMA-376 §21.2.2.216). Hex without '#'. Stacked-bar charts colour each
174
- * segment's label independently (e.g. white on the dark segment, black on
175
- * the light one), which a single chart-level `dataLabelFontColor` can't
176
- * express. Takes precedence over `dataLabelFontColor`; null = no override.
264
+ * `<a:stretch><a:fillRect>` insets. Absent fills the whole box (or the
265
+ * fill is tiled see {@link ImageFill.tile}).
177
266
  */
178
- labelColor?: string | null;
267
+ fillRect?: FillRect;
179
268
  /**
180
- * Mixed chart: per-series chart type override. Currently only "line" (XLSX
181
- * and PPTX combo charts) is honoured; other values are treated as the
182
- * chart's primary type.
269
+ * `<a:tile>` descriptor. Present only when the blipFill is tiled; mutually
270
+ * exclusive with {@link ImageFill.fillRect}.
183
271
  */
184
- seriesType?: string | null;
272
+ tile?: TileInfo;
273
+ /** `a:blip > a:alphaModFix@amt` as a fraction (0.0–1.0). Absent = opaque. */
274
+ alpha?: number;
185
275
  /**
186
- * Combo chart: this series is plotted against the SECONDARY value axis
187
- * (`ChartModel.secondaryValAxis`) the `<c:valAx>` with `axPos="r"` /
188
- * `<c:crosses val="max">`. When false/absent the series uses the primary
189
- * (left) value-axis scale. PowerPoint's "Revenue vs. gross margin" combo
190
- * (sample-14 slide-8) puts the margin line on a 0–100% secondary axis.
276
+ * ECMA-376 §20.1.8.23 `<a:duotone>` recolour, resolved to its two endpoint
277
+ * colours (through the slide theme). Absent no duotone. When present the
278
+ * renderer maps the blip's luminance ramp between the two colours (core
279
+ * `applyDuotone`) the same recolour a `<p:pic>` duotone applies, wired onto
280
+ * the picture-FILL path (§20.1.8.14) by issue #889.
191
281
  */
192
- useSecondaryAxis?: boolean | null;
282
+ duotone?: Duotone$1;
283
+ }
284
+ interface Shadow {
285
+ color: string;
286
+ alpha: number;
287
+ blur: number;
288
+ dist: number;
289
+ /** degrees clockwise from East */
290
+ dir: number;
291
+ }
292
+ /** ECMA-376 §20.1.8.17 (CT_GlowEffect) — coloured halo with blur radius. */
293
+ interface Glow {
294
+ color: string;
295
+ alpha: number;
296
+ /** Blur radius in EMU. */
297
+ radius: number;
298
+ }
299
+ /** ECMA-376 §20.1.8.31 (CT_SoftEdgesEffect) — feather radius in EMU. */
300
+ interface SoftEdge {
301
+ radius: number;
302
+ }
303
+ /** ECMA-376 §20.1.8.27 (CT_ReflectionEffect) — mirrored copy below the
304
+ * shape with a linear alpha gradient. Carries the spec attributes whose
305
+ * defaults the renderer needs to interpret correctly. */
306
+ interface Reflection {
307
+ blur: number;
308
+ dist: number;
309
+ /** Direction in degrees, clockwise from East. */
310
+ dir: number;
311
+ /** Start alpha (0–1). Default 1.0. */
312
+ stA: number;
313
+ /** Start position along the gradient (0–1). Default 0. */
314
+ stPos: number;
315
+ /** End alpha. Default 0. */
316
+ endA: number;
317
+ /** End position. Default 1.0. */
318
+ endPos: number;
319
+ /** Horizontal scale (1.0 = same width). */
320
+ sx: number;
321
+ /** Vertical scale (-1.0 = full mirror). */
322
+ sy: number;
323
+ }
324
+ interface ArrowEnd {
325
+ /** OOXML type: "none" | "triangle" | "stealth" | "diamond" | "oval" | "arrow" */
326
+ type: string;
327
+ /** Width multiplier: "sm" | "med" | "lg" */
328
+ w: string;
329
+ /** Length multiplier: "sm" | "med" | "lg" */
330
+ len: string;
331
+ }
332
+ interface Stroke {
333
+ color: string;
334
+ /** Width in EMU */
335
+ width: number;
336
+ /** Authored non-solid DrawingML line paint. Solid lines use `color`. */
337
+ fill?: Exclude<Fill, {
338
+ fillType: 'image';
339
+ } | {
340
+ fillType: 'none';
341
+ }>;
342
+ /** OOXML prstDash value: "dash", "dot", "dashDot", "lgDash", "lgDashDot", etc. */
343
+ dashStyle?: string;
344
+ /** Canvas line cap normalized from DrawingML/VML (`flat` → `butt`). */
345
+ lineCap?: CanvasLineCap;
346
+ /** Arrow head at the start of the line */
347
+ headEnd?: ArrowEnd;
348
+ /** Arrow head at the end of the line */
349
+ tailEnd?: ArrowEnd;
193
350
  /**
194
- * Scatter-only X values (as strings). When null the series uses
195
- * `ChartModel.categories` as X.
351
+ * ECMA-376 §20.1.8.42 ST_CompoundLine. "sng" (default) | "dbl" |
352
+ * "thinThick" | "thickThin" | "tri". Absent means single line.
196
353
  */
197
- categories?: string[] | null;
354
+ cmpd?: string;
355
+ }
356
+ interface TextBody$1 {
357
+ /** Vertical anchor: "t" | "ctr" | "b" */
358
+ verticalAnchor: string;
359
+ paragraphs: Paragraph$1[];
360
+ /** Default pt size from lstStyle (overrides renderer default when present) */
361
+ defaultFontSize: number | null;
362
+ /** Inherited bold from layout/master defRPr (null = not set, use false as final default) */
363
+ defaultBold: boolean | null;
364
+ /** Inherited italic from layout/master defRPr (null = not set, use false as final default) */
365
+ defaultItalic: boolean | null;
366
+ /** Text insets in EMU (defaults: lIns=rIns=91440, tIns=bIns=45720) */
367
+ lIns: number;
368
+ rIns: number;
369
+ tIns: number;
370
+ bIns: number;
371
+ /** "square" = wrap, "none" = no wrap */
372
+ wrap: string;
373
+ /** Text direction: "horz" | "vert" | "vert270" | "eaVert" etc. */
374
+ vert: string;
375
+ /** Auto-fit: "sp" = shape grows to fit text, "norm" = font shrinks, "none" = no fit */
376
+ autoFit: string;
198
377
  /**
199
- * Resolved marker visibility for line/scatter series. ECMA-376 §21.2.2.32
200
- * `<c:marker><c:symbol>` defaults to "none" for line charts unless the
201
- * chart-level `<c:marker val="1"/>` or a per-series symbol opts in. When
202
- * undefined/null the renderer uses its own default (visible) so callers
203
- * that don't parse markers (e.g. pptx today) keep their existing behavior.
378
+ * `<a:normAutofit fontScale>` (ECMA-376 §21.1.2.1.3) — PowerPoint's stored,
379
+ * pre-computed font-shrink ratio for `autoFit === "norm"`, as a fraction
380
+ * (e.g. 0.625 for `fontScale="62500"`). Null/absent when PowerPoint stored no
381
+ * scale; the renderer then re-derives one. Applying the stored value matches
382
+ * PowerPoint exactly instead of guessing from our own text metrics.
204
383
  */
205
- showMarker?: boolean | null;
206
- /**
207
- * Excel number-format code for this series' values (ECMA-376 §21.2.2.37,
208
- * `<c:val>/<c:numRef>/<c:formatCode>`). Used to format data labels when the
209
- * chart-level `<c:dLbls><c:numFmt>` is not set. null = no series-level code.
384
+ fontScale?: number | null;
385
+ /** `<a:normAutofit lnSpcReduction>` — stored line-spacing reduction fraction
386
+ * (e.g. 0.20 for `lnSpcReduction="20000"`). Null/absent when not stored. */
387
+ lnSpcReduction?: number | null;
388
+ /**
389
+ * `<a:bodyPr numCol>` (ECMA-376 §20.1.10.34) — number of text columns inside
390
+ * the shape. Defaults to 1; values > 1 cause the renderer to flow paragraphs
391
+ * across N columns left-to-right, top-to-bottom.
210
392
  */
211
- valFormatCode?: string | null;
393
+ numCol?: number;
394
+ /** `<a:bodyPr spcCol>` — gap between columns in EMU. Default 0. */
395
+ spcCol?: number;
396
+ }
397
+ type SpaceLine = {
398
+ type: 'pct';
399
+ val: number;
400
+ } | {
401
+ type: 'pts';
402
+ val: number;
403
+ };
404
+ /**
405
+ * A paragraph's bullet marker. For `char`, the marker size is EITHER `sizePct`
406
+ * (a percentage of the run size — ECMA-376 §21.1.2.4.9 `<a:buSzPct>`) OR `sizePts`
407
+ * (an absolute size in points — §21.1.2.4.10 `<a:buSzPts>`), never both: they are
408
+ * the one `EG_TextBulletSize` xsd:choice. `sizePts` is optional (absent when no
409
+ * `<a:buSzPts>` was declared); when present it takes precedence over `sizePct`.
410
+ */
411
+ type Bullet = {
412
+ type: 'none';
413
+ } | {
414
+ type: 'inherit';
415
+ } | {
416
+ type: 'char';
417
+ char: string;
418
+ color: string | null;
419
+ sizePct: number | null;
420
+ sizePts?: number;
421
+ fontFamily: string | null;
422
+ } | {
423
+ type: 'autoNum';
424
+ numType: string;
425
+ startAt: number | null;
426
+ color: string | null;
427
+ };
428
+ interface TabStop$1 {
429
+ /** Position in EMU from the LEADING text-inset edge of the text area —
430
+ * logical, not physical (ECMA-376 §21.1.2.1): the left edge (after lIns)
431
+ * in an LTR paragraph, the right edge (before rIns) in an RTL
432
+ * (`<a:pPr rtl="1">`) paragraph. */
433
+ pos: number;
434
+ /** Alignment: "l" | "r" | "ctr" | "dec" */
435
+ algn: string;
436
+ }
437
+ interface Paragraph$1 {
438
+ /** Alignment: "l" | "ctr" | "r" | "just" */
439
+ alignment: string;
440
+ /** Left margin in EMU */
441
+ marL: number;
442
+ /** Right margin in EMU */
443
+ marR: number;
444
+ /** First-line indent in EMU (negative = hanging indent) */
445
+ indent: number;
446
+ spaceBefore: number | null;
447
+ spaceAfter: number | null;
448
+ spaceLine: SpaceLine | null;
449
+ /** List nesting level (0–8) */
450
+ lvl: number;
451
+ bullet: Bullet;
452
+ defFontSize: number | null;
453
+ defColor: string | null;
454
+ defBold: boolean | null;
455
+ defItalic: boolean | null;
456
+ defFontFamily: string | null;
457
+ /** Tab stops from pPr > tabLst */
458
+ tabStops: TabStop$1[];
212
459
  /**
213
- * `<c:marker><c:symbol val>` (ECMA-376 §21.2.2.32) — point marker shape.
214
- * One of "circle"|"square"|"diamond"|"triangle"|"x"|"plus"|"star"|
215
- * "dot"|"dash"|"picture"|"none". null = renderer default (circle when
216
- * showMarker is true).
460
+ * `<a:pPr rtl="1">` — right-to-left paragraph (ECMA-376 §21.1.2.2.7).
461
+ * When true and no explicit `algn`, the parser-side default flips from
462
+ * "l" to "r"; renderers can also use this flag to flow runs RTL.
217
463
  */
218
- markerSymbol?: string | null;
464
+ rtl?: boolean;
465
+ runs: TextRun[];
466
+ }
467
+ type TextRun = TextRunData | LineBreak | EquationRun;
468
+ /**
469
+ * An OMML equation embedded in a paragraph (ECMA-376 §22.1). Parsed into the
470
+ * shared math AST and rendered by `@silurus/ooxml-core`'s math engine.
471
+ * PowerPoint stores these as `a14:m` inside `mc:AlternateContent`.
472
+ */
473
+ interface EquationRun {
474
+ type: 'math';
475
+ /** Parsed OMML node list. */
476
+ nodes: MathNode[];
477
+ /** True for block (`m:oMathPara`) math, false for inline (`m:oMath`). */
478
+ display: boolean;
479
+ /** Paragraph default run size in pt, if declared; absent → renderer inherits. */
480
+ fontSize?: number | null;
481
+ /** Equation colour (hex, no '#') from the math run's rPr; absent → inherit. */
482
+ color?: string | null;
483
+ }
484
+ interface TextRunData {
485
+ type: 'text';
486
+ text: string;
487
+ /** null = not set, inherit from paragraph/body defaults */
488
+ bold: boolean | null;
489
+ /** null = not set, inherit from paragraph/body defaults */
490
+ italic: boolean | null;
491
+ underline: boolean;
219
492
  /**
220
- * `<c:marker><c:size val>` (ECMA-376 §21.2.2.34) marker side length in
221
- * points. null = renderer default (~5 pt).
493
+ * Specific underline style when not the default single line. Values come
494
+ * from ECMA-376 §21.1.2.3.16 (ST_TextUnderlineType): "dbl", "heavy",
495
+ * "dotted", "dottedHeavy", "dash", "dashHeavy", "dashLong",
496
+ * "dashLongHeavy", "dotDash", "dotDashHeavy", "dotDotDash",
497
+ * "dotDotDashHeavy", "wavy", "wavyHeavy", "wavyDbl". Absent means either
498
+ * no underline (when `underline` is false) or the default single line.
222
499
  */
223
- markerSize?: number | null;
224
- /** `<c:marker><c:spPr><a:solidFill>` resolved hex (no `#`). */
225
- markerFill?: string | null;
226
- /** `<c:marker><c:spPr><a:ln><a:solidFill>` resolved hex (no `#`). */
227
- markerLine?: string | null;
500
+ underlineStyle?: string;
228
501
  /**
229
- * Per-data-point overrides (ECMA-376 §21.2.2.39 `<c:dPt>`). Keyed by point
230
- * index. Any unset field falls back to the series-level value.
502
+ * Underline-only colour from rPr > uFill (ECMA-376 §21.1.2.3.20). Absent
503
+ * means the underline follows the text colour (uFillTx default).
231
504
  */
232
- dataPointOverrides?: ChartDataPointOverride[] | null;
505
+ underlineColor?: string;
506
+ /** True when rPr strike is sngStrike or dblStrike. */
507
+ strikethrough: boolean;
233
508
  /**
234
- * Per-data-point custom labels (ECMA-376 §21.2.2.45 `<c:dLbl idx>`).
235
- * `text` is the resolved plain string — `<a:fld type="CELLRANGE">`
236
- * placeholders are already substituted at parse time. An empty string
237
- * means the point's label was deleted with `<c:delete val="1"/>` and
238
- * the renderer should skip it.
509
+ * True only when rPr strike = "dblStrike". Lets the renderer draw two parallel
510
+ * lines instead of one. ECMA-376 §21.1.2.3.10 (ST_TextStrikeType).
239
511
  */
240
- dataLabelOverrides?: ChartDataLabelOverride[] | null;
512
+ strikeDouble?: boolean;
513
+ /** Font size in points */
514
+ fontSize: number | null;
515
+ color: string | null;
516
+ fontFamily: string | null;
241
517
  /**
242
- * Series-level `<c:dLbls>` block (showVal / showSerName / position).
243
- * Applied to every point lacking its own `<c:dLbl>` override.
518
+ * East Asian font family from rPr > a:ea (ECMA-376 §21.1.2.3.7),
519
+ * resolved through the theme. Renderer uses this for CJK glyphs when
520
+ * present; absent means CJK falls back to fontFamily.
244
521
  */
245
- seriesDataLabels?: ChartSeriesDataLabels | null;
522
+ fontFamilyEa?: string;
246
523
  /**
247
- * `<c:errBars>` per-series error bars (ECMA-376 §21.2.2.20). Up to two
248
- * (one per direction). Plus / minus deltas are absolute per-point values
249
- * regardless of `errValType`.
524
+ * Symbol font family from rPr > a:sym (ECMA-376 §21.1.2.3.10), resolved
525
+ * through the theme. PowerPoint stores symbol-font glyphs as Private-Use
526
+ * codepoints U+F020–U+F0FF; the renderer uses this font to resolve them.
527
+ * Absent means no symbol font was declared.
250
528
  */
251
- errBars?: ChartErrBars[] | null;
529
+ fontFamilySym?: string;
530
+ /** Baseline shift in thousandths of a point. Positive = superscript, negative = subscript. */
531
+ baseline?: number;
252
532
  /**
253
- * `<c:bubbleSize>` per-point sizes for bubble charts (ECMA-376 §21.2.2.4).
254
- * Drives marker radius renderer treats the values as areas (radius
255
- * scales by sqrt) so visual area is proportional to value, matching
256
- * Excel. null / empty array = uniform marker size. Ignored for non-bubble
257
- * series.
533
+ * Capitalisation transform ECMA-376 §21.1.2.3.13 (ST_TextCapsType).
534
+ * 'all' renders text in upper case; 'small' uses small caps (rendered as
535
+ * upper case at ~80% size when no smcp font feature is available).
536
+ * 'none' or omitted leaves the text unchanged.
258
537
  */
259
- bubbleSizes?: (number | null)[] | null;
538
+ caps?: 'none' | 'small' | 'all';
260
539
  /**
261
- * `<c:ser><c:smooth val>` (ECMA-376 §21.2.2.194) — line/area series flag
262
- * requesting a smoothed (spline) curve through the points instead of straight
263
- * segments. Only consulted for the line and area families (scatter carries its
264
- * smoothing in `ChartModel.scatterStyle`). null/undefined/false = straight
265
- * polyline (the default; byte-stable for series that never set it).
540
+ * Inter-character spacing in 100ths of a point — ECMA-376 §21.1.2.3.5
541
+ * (rPr @spc). Positive values add space, negative values tighten.
266
542
  */
267
- smooth?: boolean | null;
543
+ letterSpacing?: number;
544
+ /** Set for OOXML field runs (e.g. "slidenum"). When set, renderer replaces text with field value. */
545
+ fieldType?: string;
268
546
  /**
269
- * `<c:ser><c:trendline>` per-series trendlines (ECMA-376 §21.2.2.211,
270
- * `CT_Trendline`). A series can carry several (e.g. a linear fit + a moving
271
- * average). null/undefined/empty = no trendline (the default; byte-stable for
272
- * series that never declare one).
547
+ * Hyperlink target resolved from rPr > a:hlinkClick @r:id via the slide's _rels.
548
+ * For an external link this is the URL; for an internal slide jump it is the
549
+ * resolved internal part name (e.g. "../slides/slide3.xml"). Undefined for runs
550
+ * without a hyperlink. ECMA-376 §21.1.2.3.5 (CT_Hyperlink).
273
551
  */
274
- trendLines?: ChartTrendline[] | null;
552
+ hyperlink?: string;
275
553
  /**
276
- * `<c:ser><c:spPr><a:ln><a:noFill/>` (ECMA-376 §21.2.2.198 CT_ShapeProperties
277
- * DrawingML §20.1.2.2.24 CT_LineProperties). true when the series connecting
278
- * line is explicitly turned OFF. For a scatter/line series this OVERRIDES the
279
- * chart-group `<c:scatterStyle>` (§21.2.2.42) / line default — Excel and
280
- * PowerPoint draw markers only (no connecting line) even when the group style
281
- * is `lineMarker`. null/undefined = no explicit line-off, so the group default
282
- * governs (byte-stable for series that carry a paintable line).
554
+ * Raw `<a:hlinkClick @action>` string (e.g. "ppaction://hlinksldjump") when
555
+ * present its presence marks {@link hyperlink} as an INTERNAL PowerPoint
556
+ * action (slide jump / first / last …) rather than an external URL. Undefined
557
+ * when the hlinkClick has no @action. ECMA-376 §21.1.2.3.5. (IX1)
283
558
  */
284
- lineHidden?: boolean | null;
285
- }
286
- /**
287
- * `<c:ser><c:trendline>` (ECMA-376 §21.2.2.211). A regression/smoothing curve
288
- * fitted to the series' data points.
289
- */
290
- interface ChartTrendline {
559
+ hyperlinkAction?: string;
291
560
  /**
292
- * `<c:trendlineType val>` (§21.2.2.213, `ST_TrendlineType` §21.2.3.50):
293
- * "linear" | "exp" | "log" | "power" | "poly" | "movingAvg". The renderer
294
- * currently draws "linear" (least squares) and "movingAvg"; other types parse
295
- * but are not yet plotted (tracked as a follow-up).
561
+ * Run-level drop shadow on glyphs (`<a:rPr><a:effectLst><a:outerShdw>`),
562
+ * ECMA-376 §20.1.8.45. Independent of the shape-level shadow on `spPr`.
563
+ * Absent means no run-level shadow.
296
564
  */
297
- trendlineType: string;
298
- /** `<c:order val>` — polynomial order (`poly`, default 2). */
299
- order?: number | null;
300
- /** `<c:period val>` — moving-average window (`movingAvg`, default 2). */
301
- period?: number | null;
302
- /** `<c:forward val>` — units to extend the line past the last point. */
303
- forward?: number | null;
304
- /** `<c:backward val>` — units to extend the line before the first point. */
305
- backward?: number | null;
306
- /** `<c:intercept val>` — forced y-intercept (linear/exp). null = free fit. */
307
- intercept?: number | null;
308
- /** `<c:dispRSqr val="1">` — show the R² value (label; not yet rendered). */
309
- dispRSqr?: boolean | null;
310
- /** `<c:dispEq val="1">` — show the fit equation (label; not yet rendered). */
311
- dispEq?: boolean | null;
312
- /** `<c:spPr><a:ln><a:solidFill>` trendline color (hex without '#'). null =
313
- * inherit the series color. */
314
- lineColor?: string | null;
315
- /** `<c:spPr><a:ln w>` trendline width in EMU. */
316
- lineWidthEmu?: number | null;
317
- }
318
- interface ChartDataPointOverride {
319
- idx: number;
320
- /** Resolved fill hex (no `#`). */
321
- color?: string;
322
- markerSymbol?: string;
323
- markerSize?: number;
324
- markerFill?: string;
325
- markerLine?: string;
565
+ shadow?: Shadow;
326
566
  /**
327
- * `<c:dPt><c:explosion val>` (ECMA-376 §21.2.2.61) — the amount this
567
+ * Run-level glyph outline (`<a:rPr><a:ln w="..">`), ECMA-376 §20.1.2.2.24
568
+ * (CT_TextOutlineEffect). Renderer strokes each glyph with the given
569
+ * width / colour in addition to the normal fill. Absent means glyphs are
570
+ * fill-only.
571
+ */
572
+ outline?: TextOutline;
573
+ /**
574
+ * Run-level text highlight / marker colour (`<a:rPr><a:highlight>`),
575
+ * ECMA-376 §21.1.2.3.4. In DrawingML this is a full CT_Color (any
576
+ * srgbClr / schemeClr / sysClr / prstClr + transforms), unlike
577
+ * WordprocessingML's fixed 16-name highlight enum — so the parser already
578
+ * resolves it through the theme/clrMap. The value is a hex string without
579
+ * `#` (6-char opaque, or 8-char RRGGBBAA when an alpha transform applies);
580
+ * the renderer paints a background rectangle behind the run's glyphs.
581
+ * Absent means no highlight.
582
+ */
583
+ highlight?: string;
584
+ }
585
+ /** Run-level glyph outline. Width is in OOXML EMU (12700 EMU = 1 pt). */
586
+ interface TextOutline {
587
+ width: number;
588
+ /** Hex without '#'. Absent = inherit from text fill colour. */
589
+ color?: string;
590
+ }
591
+ interface LineBreak {
592
+ type: 'break';
593
+ }
594
+ //#endregion
595
+ //#region packages/core/src/types/chart.d.ts
596
+ interface ChartSeries {
597
+ name: string;
598
+ /** Hex without '#'. null = fall back to palette. */
599
+ color: string | null;
600
+ /** Numeric values; null = missing data point. */
601
+ values: (number | null)[];
602
+ /**
603
+ * Per-data-point colors (pie / doughnut). Hex without '#'. null inside the
604
+ * array = use palette for that slice. Omit entirely for non-pie series.
605
+ */
606
+ dataPointColors?: (string | null)[] | null;
607
+ /**
608
+ * Per-data-point data-label text colors. Used by chartEx (`<cx:dataLabel idx>`)
609
+ * to override label colour per bar — sample-2's waterfall paints negative
610
+ * △ values in red while positive values stay black. Null inside the array =
611
+ * fall back to the chart-level `dataLabelFontColor`.
612
+ */
613
+ dataLabelColors?: (string | null)[] | null;
614
+ /**
615
+ * Series-level data-label text colour (`<c:ser><c:dLbls><c:txPr>…solidFill`,
616
+ * ECMA-376 §21.2.2.216). Hex without '#'. Stacked-bar charts colour each
617
+ * segment's label independently (e.g. white on the dark segment, black on
618
+ * the light one), which a single chart-level `dataLabelFontColor` can't
619
+ * express. Takes precedence over `dataLabelFontColor`; null = no override.
620
+ */
621
+ labelColor?: string | null;
622
+ /**
623
+ * Mixed chart: per-series chart type override. Currently only "line" (XLSX
624
+ * and PPTX combo charts) is honoured; other values are treated as the
625
+ * chart's primary type.
626
+ */
627
+ seriesType?: string | null;
628
+ /**
629
+ * Combo chart: this series is plotted against the SECONDARY value axis
630
+ * (`ChartModel.secondaryValAxis`) — the `<c:valAx>` with `axPos="r"` /
631
+ * `<c:crosses val="max">`. When false/absent the series uses the primary
632
+ * (left) value-axis scale. PowerPoint's "Revenue vs. gross margin" combo
633
+ * (sample-14 slide-8) puts the margin line on a 0–100% secondary axis.
634
+ */
635
+ useSecondaryAxis?: boolean | null;
636
+ /**
637
+ * Scatter-only X values (as strings). When null the series uses
638
+ * `ChartModel.categories` as X.
639
+ */
640
+ categories?: string[] | null;
641
+ /**
642
+ * Resolved marker visibility for line/scatter series. ECMA-376 §21.2.2.32
643
+ * `<c:marker><c:symbol>` defaults to "none" for line charts unless the
644
+ * chart-level `<c:marker val="1"/>` or a per-series symbol opts in. When
645
+ * undefined/null the renderer uses its own default (visible) so callers
646
+ * that don't parse markers (e.g. pptx today) keep their existing behavior.
647
+ */
648
+ showMarker?: boolean | null;
649
+ /**
650
+ * Excel number-format code for this series' values (ECMA-376 §21.2.2.37,
651
+ * `<c:val>/<c:numRef>/<c:formatCode>`). Used to format data labels when the
652
+ * chart-level `<c:dLbls><c:numFmt>` is not set. null = no series-level code.
653
+ */
654
+ valFormatCode?: string | null;
655
+ /**
656
+ * `<c:marker><c:symbol val>` (ECMA-376 §21.2.2.32) — point marker shape.
657
+ * One of "circle"|"square"|"diamond"|"triangle"|"x"|"plus"|"star"|
658
+ * "dot"|"dash"|"picture"|"none". null = renderer default (circle when
659
+ * showMarker is true).
660
+ */
661
+ markerSymbol?: string | null;
662
+ /**
663
+ * `<c:marker><c:size val>` (ECMA-376 §21.2.2.34) — marker side length in
664
+ * points. null = renderer default (~5 pt).
665
+ */
666
+ markerSize?: number | null;
667
+ /** `<c:marker><c:spPr><a:solidFill>` resolved hex (no `#`). */
668
+ markerFill?: string | null;
669
+ /** `<c:marker><c:spPr><a:ln><a:solidFill>` resolved hex (no `#`). */
670
+ markerLine?: string | null;
671
+ /**
672
+ * Per-data-point overrides (ECMA-376 §21.2.2.39 `<c:dPt>`). Keyed by point
673
+ * index. Any unset field falls back to the series-level value.
674
+ */
675
+ dataPointOverrides?: ChartDataPointOverride[] | null;
676
+ /**
677
+ * Per-data-point custom labels (ECMA-376 §21.2.2.45 `<c:dLbl idx>`).
678
+ * `text` is the resolved plain string — `<a:fld type="CELLRANGE">`
679
+ * placeholders are already substituted at parse time. An empty string
680
+ * means the point's label was deleted with `<c:delete val="1"/>` and
681
+ * the renderer should skip it.
682
+ */
683
+ dataLabelOverrides?: ChartDataLabelOverride[] | null;
684
+ /**
685
+ * Series-level `<c:dLbls>` block (showVal / showSerName / position).
686
+ * Applied to every point lacking its own `<c:dLbl>` override.
687
+ */
688
+ seriesDataLabels?: ChartSeriesDataLabels | null;
689
+ /**
690
+ * `<c:errBars>` per-series error bars (ECMA-376 §21.2.2.20). Up to two
691
+ * (one per direction). Plus / minus deltas are absolute per-point values
692
+ * regardless of `errValType`.
693
+ */
694
+ errBars?: ChartErrBars[] | null;
695
+ /**
696
+ * `<c:bubbleSize>` per-point sizes for bubble charts (ECMA-376 §21.2.2.4).
697
+ * Drives marker radius — renderer treats the values as areas (radius
698
+ * scales by sqrt) so visual area is proportional to value, matching
699
+ * Excel. null / empty array = uniform marker size. Ignored for non-bubble
700
+ * series.
701
+ */
702
+ bubbleSizes?: (number | null)[] | null;
703
+ /**
704
+ * `<c:ser><c:smooth val>` (ECMA-376 §21.2.2.194) — line/area series flag
705
+ * requesting a smoothed (spline) curve through the points instead of straight
706
+ * segments. Only consulted for the line and area families (scatter carries its
707
+ * smoothing in `ChartModel.scatterStyle`). null/undefined/false = straight
708
+ * polyline (the default; byte-stable for series that never set it).
709
+ */
710
+ smooth?: boolean | null;
711
+ /**
712
+ * `<c:ser><c:trendline>` per-series trendlines (ECMA-376 §21.2.2.211,
713
+ * `CT_Trendline`). A series can carry several (e.g. a linear fit + a moving
714
+ * average). null/undefined/empty = no trendline (the default; byte-stable for
715
+ * series that never declare one).
716
+ */
717
+ trendLines?: ChartTrendline[] | null;
718
+ /**
719
+ * `<c:ser><c:spPr><a:ln><a:noFill/>` (ECMA-376 §21.2.2.198 CT_ShapeProperties
720
+ * → DrawingML §20.1.2.2.24 CT_LineProperties). true when the series connecting
721
+ * line is explicitly turned OFF. For a scatter/line series this OVERRIDES the
722
+ * chart-group `<c:scatterStyle>` (§21.2.2.42) / line default — Excel and
723
+ * PowerPoint draw markers only (no connecting line) even when the group style
724
+ * is `lineMarker`. null/undefined = no explicit line-off, so the group default
725
+ * governs (byte-stable for series that carry a paintable line).
726
+ */
727
+ lineHidden?: boolean | null;
728
+ }
729
+ /**
730
+ * `<c:ser><c:trendline>` (ECMA-376 §21.2.2.211). A regression/smoothing curve
731
+ * fitted to the series' data points.
732
+ */
733
+ interface ChartTrendline {
734
+ /**
735
+ * `<c:trendlineType val>` (§21.2.2.213, `ST_TrendlineType` §21.2.3.50):
736
+ * "linear" | "exp" | "log" | "power" | "poly" | "movingAvg". The renderer
737
+ * currently draws "linear" (least squares) and "movingAvg"; other types parse
738
+ * but are not yet plotted (tracked as a follow-up).
739
+ */
740
+ trendlineType: string;
741
+ /** `<c:order val>` — polynomial order (`poly`, default 2). */
742
+ order?: number | null;
743
+ /** `<c:period val>` — moving-average window (`movingAvg`, default 2). */
744
+ period?: number | null;
745
+ /** `<c:forward val>` — units to extend the line past the last point. */
746
+ forward?: number | null;
747
+ /** `<c:backward val>` — units to extend the line before the first point. */
748
+ backward?: number | null;
749
+ /** `<c:intercept val>` — forced y-intercept (linear/exp). null = free fit. */
750
+ intercept?: number | null;
751
+ /** `<c:dispRSqr val="1">` — show the R² value (label; not yet rendered). */
752
+ dispRSqr?: boolean | null;
753
+ /** `<c:dispEq val="1">` — show the fit equation (label; not yet rendered). */
754
+ dispEq?: boolean | null;
755
+ /** `<c:spPr><a:ln><a:solidFill>` trendline color (hex without '#'). null =
756
+ * inherit the series color. */
757
+ lineColor?: string | null;
758
+ /** `<c:spPr><a:ln w>` trendline width in EMU. */
759
+ lineWidthEmu?: number | null;
760
+ }
761
+ interface ChartDataPointOverride {
762
+ idx: number;
763
+ /** Resolved fill hex (no `#`). */
764
+ color?: string;
765
+ markerSymbol?: string;
766
+ markerSize?: number;
767
+ markerFill?: string;
768
+ markerLine?: string;
769
+ /**
770
+ * `<c:dPt><c:explosion val>` (ECMA-376 §21.2.2.61) — the amount this
328
771
  * pie/doughnut slice is moved out from the center. The schema type is
329
772
  * `CT_UnsignedInt` (unbounded `xsd:unsignedInt`); the spec text only says
330
773
  * "the amount the data point shall be moved from the center of the pie"
@@ -966,580 +1409,137 @@ interface OoxmlResourceViolation {
966
1409
  readonly configurable: boolean;
967
1410
  readonly usage: OoxmlResourceUsageSnapshot;
968
1411
  }
969
- interface OoxmlResourceLimitErrorDetails {
970
- readonly stage: OoxmlErrorStage;
971
- readonly violation: OoxmlResourceViolation;
972
- }
973
- /** Deterministic rejection caused by a measured OOXML resource-policy breach. */
974
- declare class OoxmlResourceLimitError extends Error {
975
- readonly code: "ooxml-resource-limit";
976
- readonly details: OoxmlResourceLimitErrorDetails;
977
- constructor(message: string, details: OoxmlResourceLimitErrorDetails);
978
- }
979
- //#endregion
980
- //#region packages/core/src/types/resource-metrics.d.ts
981
- /** Configured public admission policy used for one measured operation. */
982
- interface OoxmlResourcePolicySnapshot {
983
- readonly maxArchiveEntryBytes: number | null;
984
- readonly maxTotalInflatedBytes: number | null;
985
- }
986
- interface OoxmlResourceMetricsCheckpoint {
987
- readonly name: string;
988
- readonly elapsedMs: number;
989
- readonly usage?: OoxmlResourceUsageSnapshot;
990
- }
991
- /**
992
- * Content-free, machine-readable resource report for an OOXML load or bounded
993
- * Node session. Byte counters describe measured package work, not the JavaScript
994
- * heap, WASM allocator overhead, decoded images, canvas, or GPU. Browser engines
995
- * and Viewers can return a newer snapshot after lazy package access.
996
- *
997
- * No source URL, filename, OOXML part name, document text, password, or raw
998
- * error message is included. Sizes, counts, and timings are still
999
- * document-derived metadata; applications apply their own consent, retention,
1000
- * and telemetry policy.
1001
- */
1002
- interface OoxmlResourceMetrics {
1003
- /** Version of this metrics payload, independent of the package version. */
1004
- readonly schemaVersion: 1;
1005
- /**
1006
- * Browser factories report `load`; bounded Node sessions report `session`.
1007
- */
1008
- readonly scope: 'load' | 'session';
1009
- readonly format: OoxmlFormat;
1010
- readonly mode: 'main' | 'worker' | 'node';
1011
- /** Outcome of this measured load/session, not of later render operations. */
1012
- readonly status: 'ok' | 'error';
1013
- /** Compressed or decrypted OOXML container bytes supplied to the parser. */
1014
- readonly sourceBytes?: number;
1015
- readonly elapsedMs: number;
1016
- readonly policy: Readonly<OoxmlResourcePolicySnapshot>;
1017
- /** Last complete observed package-usage checkpoint. */
1018
- readonly usage?: OoxmlResourceUsageSnapshot;
1019
- readonly checkpoints: readonly OoxmlResourceMetricsCheckpoint[];
1020
- readonly outcome?: Readonly<Record<string, number>>;
1021
- readonly error?: Readonly<{
1022
- readonly code?: string;
1023
- readonly stage?: string;
1024
- readonly resource?: string;
1025
- readonly metric?: string;
1026
- }>;
1027
- }
1028
- //#endregion
1029
- //#region packages/core/src/types/load-options.d.ts
1030
- /** A positive safe-integer byte count, or `null` to disable one public limit. */
1031
- type OoxmlResourceLimit = number | null;
1032
- /** Admission limits for the inflated contents of one OOXML package session. */
1033
- interface OoxmlResourceLimits {
1034
- /**
1035
- * Maximum permitted inflated size for any one archive entry, including
1036
- * media. Enforced against both the ZIP declaration and actual output.
1037
- */
1038
- maxArchiveEntryBytes?: OoxmlResourceLimit;
1039
- /** Maximum actual inflated bytes across distinct entries in the session. */
1040
- maxTotalInflatedBytes?: OoxmlResourceLimit;
1041
- }
1042
- //#endregion
1043
- //#region packages/core/src/image/pixel-budget.d.ts
1044
- type OoxmlDecodedImageLimitMetric = 'image-pixels' | 'active-decoded-bytes';
1045
- /** Catchable hard-quota crossing for decoded image surfaces. */
1046
- declare class OoxmlDecodedImageLimitError extends RangeError {
1047
- readonly metric: OoxmlDecodedImageLimitMetric;
1048
- readonly limit: number;
1049
- readonly observed: number;
1050
- readonly code: "ooxml-decoded-image-limit";
1051
- constructor(metric: OoxmlDecodedImageLimitMetric, limit: number, observed: number);
1052
- }
1053
- declare function isOoxmlDecodedImageLimitError(error: unknown): error is OoxmlDecodedImageLimitError;
1054
- //#endregion
1055
- //#region packages/core/src/interaction/hyperlink.d.ts
1056
- /**
1057
- * Shared hyperlink model + URL sanitisation for docx / pptx / xlsx (IX1).
1058
- *
1059
- * All three formats carry the same two ECMA-376 concepts:
1060
- * - an **external** hyperlink — an absolute URL resolved from a relationship
1061
- * part target (`document.xml.rels` for docx §17.16.22, the slide rels for
1062
- * pptx §21.1.2.3.5, the worksheet rels for xlsx §18.3.1.47), with
1063
- * `TargetMode="External"`.
1064
- * - an **internal** hyperlink — a jump within the document itself:
1065
- * docx `w:anchor` -> a `<w:bookmarkStart w:name>` (§17.16.23), pptx
1066
- * `action="ppaction://hlinksldjump"` -> a slide, xlsx `location` -> a defined
1067
- * name or a `Sheet!A1` cell reference.
1068
- *
1069
- * The parsers (Rust, one per format) do the format-specific rels lookup and hand
1070
- * each run / shape / cell a {@link HyperlinkTarget}. Everything downstream — the
1071
- * text-layer overlay, the viewer default click behaviour, and any integrator
1072
- * callback — is format-agnostic and consumes this one shape. Keeping the type +
1073
- * the pure `sanitizeHyperlinkUrl` predicate here (not duplicated per package)
1074
- * follows the cross-package unification principle: a scheme-allowlist bug fixed
1075
- * once is fixed everywhere.
1076
- */
1077
- /**
1078
- * A resolved hyperlink attached to a run, shape, or cell.
1079
- *
1080
- * - `external` — `url` is the raw target as authored in the file. It is NOT
1081
- * guaranteed safe; run it through {@link sanitizeHyperlinkUrl} before
1082
- * navigating. It is kept verbatim here so an integrator can apply its own
1083
- * policy (e.g. allow `file:` on a trusted intranet viewer).
1084
- * - `internal` — `ref` is the in-document destination, verbatim from the file:
1085
- * docx: the bookmark name (`w:anchor`).
1086
- * pptx: the internal action (e.g. `ppaction://hlinksldjump`), with the
1087
- * resolved 0-based `slideIndex` when the rels target names a slide.
1088
- * xlsx: the `location` string (a defined name or `Sheet1!A1`).
1089
- */
1090
- type HyperlinkTarget = {
1091
- kind: 'external';
1092
- url: string;
1093
- } | {
1094
- kind: 'internal';
1095
- ref: string;
1096
- slideIndex?: number;
1097
- };
1098
- //#endregion
1099
- //#region dist/.types-work/common-Bgczc_Eb.d.ts
1100
- //#region packages/core/src/types/common.d.ts
1101
- type PathCmd$2 = {
1102
- cmd: 'moveTo';
1103
- x: number;
1104
- y: number;
1105
- } | {
1106
- cmd: 'lineTo';
1107
- x: number;
1108
- y: number;
1109
- } | {
1110
- cmd: 'cubicBezTo';
1111
- x1: number;
1112
- y1: number;
1113
- x2: number;
1114
- y2: number;
1115
- x: number;
1116
- y: number;
1117
- } | {
1118
- cmd: 'arcTo';
1119
- wr: number;
1120
- hr: number;
1121
- stAng: number;
1122
- swAng: number;
1123
- } | {
1124
- cmd: 'close';
1125
- };
1126
- type Fill = SolidFill | NoFill | GradientFill | PatternFill | ImageFill;
1127
- interface SolidFill {
1128
- fillType: 'solid';
1129
- color: string;
1130
- }
1131
- interface NoFill {
1132
- fillType: 'none';
1133
- }
1134
- interface GradientStop$1 {
1135
- position: number;
1136
- color: string;
1137
- }
1138
- interface GradientFill {
1139
- fillType: 'gradient';
1140
- stops: GradientStop$1[];
1141
- /** degrees: 0 = left→right, 90 = top→bottom */
1142
- angle: number;
1143
- /** 'linear' | 'radial' */
1144
- gradType: string;
1145
- }
1146
- /**
1147
- * Preset pattern fill — ECMA-376 §20.1.8.40 (CT_PatternFillProperties)
1148
- * with `preset` drawn from §20.1.10.59 (ST_PresetPatternVal).
1149
- */
1150
- interface PatternFill {
1151
- fillType: 'pattern';
1152
- /** Foreground hex colour — used for the "1" pixels of the preset bitmap. */
1153
- fg: string;
1154
- /** Background hex colour — used for the "0" pixels. */
1155
- bg: string;
1156
- /** Preset name, e.g. "pct25", "horz", "diagCross", "lgGrid". */
1157
- preset: string;
1158
- }
1159
- /**
1160
- * ECMA-376 §20.1.8.30 (CT_RelativeRect) — the destination rectangle a stretched
1161
- * blip is mapped into, as edge insets relative to the fill region. Values are
1162
- * fractions (ST_Percentage / 100000); **negative values let the image bleed
1163
- * past the box (overscan)**. Absent edges default to 0.
1164
- */
1165
- interface FillRect {
1166
- l?: number;
1167
- t?: number;
1168
- r?: number;
1169
- b?: number;
1170
- }
1171
- /**
1172
- * ECMA-376 §20.1.8.58 (CT_TileInfoProperties) — tiled blip-fill placement.
1173
- * The blip repeats at its native size (scaled by sx/sy) across the fill box.
1174
- * Mutually exclusive with {@link ImageFill.fillRect} (the `stretch` mode).
1175
- */
1176
- interface TileInfo {
1177
- /** Horizontal offset of the first tile, in EMU (`tx`). Default 0. */
1178
- tx: number;
1179
- /** Vertical offset of the first tile, in EMU (`ty`). Default 0. */
1180
- ty: number;
1181
- /** Horizontal tile scale as a fraction (`sx` / 100000). Default 1.0. */
1182
- sx: number;
1183
- /** Vertical tile scale as a fraction (`sy` / 100000). Default 1.0. */
1184
- sy: number;
1185
- /** Mirror mode: `'none' | 'x' | 'y' | 'xy'` (`flip`). Default `'none'`. */
1186
- flip: string;
1187
- /**
1188
- * Anchor corner the tile grid registers against:
1189
- * `tl|t|tr|l|ctr|r|bl|b|br` (`algn`). Default `'tl'`.
1190
- */
1191
- algn: string;
1192
- }
1193
- /**
1194
- * Image fill — ECMA-376 §20.1.8.14 (CT_BlipFillProperties). The embedded blip
1195
- * is carried as a zip path + MIME; the renderer fetches the bytes on demand via
1196
- * {@link RenderOptions.fetchImage} (no base64 inlined at parse time). Both
1197
- * fill-modes are modelled and mutually exclusive: `stretch` (§20.1.8.56) carries
1198
- * {@link ImageFill.fillRect}; `tile` (§20.1.8.58) carries {@link ImageFill.tile}.
1199
- */
1200
- interface ImageFill {
1201
- fillType: 'image';
1202
- /**
1203
- * Embedded zip path of the blip (e.g. "word/media/image1.png"), for the lazy
1204
- * byte-on-demand pipeline. The renderer fetches the bytes via a path-keyed
1205
- * loader ({@link RenderOptions.fetchImage}) instead of inlining base64.
1206
- */
1207
- imagePath: string;
1208
- /** MIME type of the blip at {@link ImageFill.imagePath} (e.g. `image/png`). */
1209
- mimeType: string;
1210
- /**
1211
- * `<a:stretch><a:fillRect>` insets. Absent → fills the whole box (or the
1212
- * fill is tiled — see {@link ImageFill.tile}).
1213
- */
1214
- fillRect?: FillRect;
1215
- /**
1216
- * `<a:tile>` descriptor. Present only when the blipFill is tiled; mutually
1217
- * exclusive with {@link ImageFill.fillRect}.
1218
- */
1219
- tile?: TileInfo;
1220
- /** `a:blip > a:alphaModFix@amt` as a fraction (0.0–1.0). Absent = opaque. */
1221
- alpha?: number;
1222
- /**
1223
- * ECMA-376 §20.1.8.23 `<a:duotone>` recolour, resolved to its two endpoint
1224
- * colours (through the slide theme). Absent ⇒ no duotone. When present the
1225
- * renderer maps the blip's luminance ramp between the two colours (core
1226
- * `applyDuotone`) — the same recolour a `<p:pic>` duotone applies, wired onto
1227
- * the picture-FILL path (§20.1.8.14) by issue #889.
1228
- */
1229
- duotone?: Duotone$1;
1230
- }
1231
- interface Shadow {
1232
- color: string;
1233
- alpha: number;
1234
- blur: number;
1235
- dist: number;
1236
- /** degrees clockwise from East */
1237
- dir: number;
1238
- }
1239
- /** ECMA-376 §20.1.8.17 (CT_GlowEffect) — coloured halo with blur radius. */
1240
- interface Glow {
1241
- color: string;
1242
- alpha: number;
1243
- /** Blur radius in EMU. */
1244
- radius: number;
1245
- }
1246
- /** ECMA-376 §20.1.8.31 (CT_SoftEdgesEffect) — feather radius in EMU. */
1247
- interface SoftEdge {
1248
- radius: number;
1249
- }
1250
- /** ECMA-376 §20.1.8.27 (CT_ReflectionEffect) — mirrored copy below the
1251
- * shape with a linear alpha gradient. Carries the spec attributes whose
1252
- * defaults the renderer needs to interpret correctly. */
1253
- interface Reflection {
1254
- blur: number;
1255
- dist: number;
1256
- /** Direction in degrees, clockwise from East. */
1257
- dir: number;
1258
- /** Start alpha (0–1). Default 1.0. */
1259
- stA: number;
1260
- /** Start position along the gradient (0–1). Default 0. */
1261
- stPos: number;
1262
- /** End alpha. Default 0. */
1263
- endA: number;
1264
- /** End position. Default 1.0. */
1265
- endPos: number;
1266
- /** Horizontal scale (1.0 = same width). */
1267
- sx: number;
1268
- /** Vertical scale (-1.0 = full mirror). */
1269
- sy: number;
1270
- }
1271
- interface ArrowEnd {
1272
- /** OOXML type: "none" | "triangle" | "stealth" | "diamond" | "oval" | "arrow" */
1273
- type: string;
1274
- /** Width multiplier: "sm" | "med" | "lg" */
1275
- w: string;
1276
- /** Length multiplier: "sm" | "med" | "lg" */
1277
- len: string;
1278
- }
1279
- interface Stroke {
1280
- color: string;
1281
- /** Width in EMU */
1282
- width: number;
1283
- /** Authored non-solid DrawingML line paint. Solid lines use `color`. */
1284
- fill?: Exclude<Fill, {
1285
- fillType: 'image';
1286
- } | {
1287
- fillType: 'none';
1288
- }>;
1289
- /** OOXML prstDash value: "dash", "dot", "dashDot", "lgDash", "lgDashDot", etc. */
1290
- dashStyle?: string;
1291
- /** Canvas line cap normalized from DrawingML/VML (`flat` → `butt`). */
1292
- lineCap?: CanvasLineCap;
1293
- /** Arrow head at the start of the line */
1294
- headEnd?: ArrowEnd;
1295
- /** Arrow head at the end of the line */
1296
- tailEnd?: ArrowEnd;
1297
- /**
1298
- * ECMA-376 §20.1.8.42 ST_CompoundLine. "sng" (default) | "dbl" |
1299
- * "thinThick" | "thickThin" | "tri". Absent means single line.
1300
- */
1301
- cmpd?: string;
1302
- }
1303
- interface TextBody$1 {
1304
- /** Vertical anchor: "t" | "ctr" | "b" */
1305
- verticalAnchor: string;
1306
- paragraphs: Paragraph$1[];
1307
- /** Default pt size from lstStyle (overrides renderer default when present) */
1308
- defaultFontSize: number | null;
1309
- /** Inherited bold from layout/master defRPr (null = not set, use false as final default) */
1310
- defaultBold: boolean | null;
1311
- /** Inherited italic from layout/master defRPr (null = not set, use false as final default) */
1312
- defaultItalic: boolean | null;
1313
- /** Text insets in EMU (defaults: lIns=rIns=91440, tIns=bIns=45720) */
1314
- lIns: number;
1315
- rIns: number;
1316
- tIns: number;
1317
- bIns: number;
1318
- /** "square" = wrap, "none" = no wrap */
1319
- wrap: string;
1320
- /** Text direction: "horz" | "vert" | "vert270" | "eaVert" etc. */
1321
- vert: string;
1322
- /** Auto-fit: "sp" = shape grows to fit text, "norm" = font shrinks, "none" = no fit */
1323
- autoFit: string;
1324
- /**
1325
- * `<a:normAutofit fontScale>` (ECMA-376 §21.1.2.1.3) — PowerPoint's stored,
1326
- * pre-computed font-shrink ratio for `autoFit === "norm"`, as a fraction
1327
- * (e.g. 0.625 for `fontScale="62500"`). Null/absent when PowerPoint stored no
1328
- * scale; the renderer then re-derives one. Applying the stored value matches
1329
- * PowerPoint exactly instead of guessing from our own text metrics.
1330
- */
1331
- fontScale?: number | null;
1332
- /** `<a:normAutofit lnSpcReduction>` — stored line-spacing reduction fraction
1333
- * (e.g. 0.20 for `lnSpcReduction="20000"`). Null/absent when not stored. */
1334
- lnSpcReduction?: number | null;
1335
- /**
1336
- * `<a:bodyPr numCol>` (ECMA-376 §20.1.10.34) — number of text columns inside
1337
- * the shape. Defaults to 1; values > 1 cause the renderer to flow paragraphs
1338
- * across N columns left-to-right, top-to-bottom.
1339
- */
1340
- numCol?: number;
1341
- /** `<a:bodyPr spcCol>` — gap between columns in EMU. Default 0. */
1342
- spcCol?: number;
1343
- }
1344
- type SpaceLine = {
1345
- type: 'pct';
1346
- val: number;
1347
- } | {
1348
- type: 'pts';
1349
- val: number;
1350
- };
1351
- /**
1352
- * A paragraph's bullet marker. For `char`, the marker size is EITHER `sizePct`
1353
- * (a percentage of the run size — ECMA-376 §21.1.2.4.9 `<a:buSzPct>`) OR `sizePts`
1354
- * (an absolute size in points — §21.1.2.4.10 `<a:buSzPts>`), never both: they are
1355
- * the one `EG_TextBulletSize` xsd:choice. `sizePts` is optional (absent when no
1356
- * `<a:buSzPts>` was declared); when present it takes precedence over `sizePct`.
1357
- */
1358
- type Bullet = {
1359
- type: 'none';
1360
- } | {
1361
- type: 'inherit';
1362
- } | {
1363
- type: 'char';
1364
- char: string;
1365
- color: string | null;
1366
- sizePct: number | null;
1367
- sizePts?: number;
1368
- fontFamily: string | null;
1369
- } | {
1370
- type: 'autoNum';
1371
- numType: string;
1372
- startAt: number | null;
1373
- color: string | null;
1374
- };
1375
- interface TabStop$1 {
1376
- /** Position in EMU from the LEADING text-inset edge of the text area —
1377
- * logical, not physical (ECMA-376 §21.1.2.1): the left edge (after lIns)
1378
- * in an LTR paragraph, the right edge (before rIns) in an RTL
1379
- * (`<a:pPr rtl="1">`) paragraph. */
1380
- pos: number;
1381
- /** Alignment: "l" | "r" | "ctr" | "dec" */
1382
- algn: string;
1383
- }
1384
- interface Paragraph$1 {
1385
- /** Alignment: "l" | "ctr" | "r" | "just" */
1386
- alignment: string;
1387
- /** Left margin in EMU */
1388
- marL: number;
1389
- /** Right margin in EMU */
1390
- marR: number;
1391
- /** First-line indent in EMU (negative = hanging indent) */
1392
- indent: number;
1393
- spaceBefore: number | null;
1394
- spaceAfter: number | null;
1395
- spaceLine: SpaceLine | null;
1396
- /** List nesting level (0–8) */
1397
- lvl: number;
1398
- bullet: Bullet;
1399
- defFontSize: number | null;
1400
- defColor: string | null;
1401
- defBold: boolean | null;
1402
- defItalic: boolean | null;
1403
- defFontFamily: string | null;
1404
- /** Tab stops from pPr > tabLst */
1405
- tabStops: TabStop$1[];
1406
- /**
1407
- * `<a:pPr rtl="1">` — right-to-left paragraph (ECMA-376 §21.1.2.2.7).
1408
- * When true and no explicit `algn`, the parser-side default flips from
1409
- * "l" to "r"; renderers can also use this flag to flow runs RTL.
1410
- */
1411
- rtl?: boolean;
1412
- runs: TextRun[];
1413
- }
1414
- type TextRun = TextRunData | LineBreak | EquationRun;
1412
+ interface OoxmlResourceLimitErrorDetails {
1413
+ readonly stage: OoxmlErrorStage;
1414
+ readonly violation: OoxmlResourceViolation;
1415
+ }
1416
+ /** Deterministic rejection caused by a measured OOXML resource-policy breach. */
1417
+ declare class OoxmlResourceLimitError extends Error {
1418
+ readonly code: "ooxml-resource-limit";
1419
+ readonly details: OoxmlResourceLimitErrorDetails;
1420
+ constructor(message: string, details: OoxmlResourceLimitErrorDetails);
1421
+ }
1422
+ //#endregion
1423
+ //#region packages/core/src/types/resource-metrics.d.ts
1424
+ /** Configured public admission policy used for one measured operation. */
1425
+ interface OoxmlResourcePolicySnapshot {
1426
+ readonly maxArchiveEntryBytes: number | null;
1427
+ readonly maxTotalInflatedBytes: number | null;
1428
+ }
1429
+ interface OoxmlResourceMetricsCheckpoint {
1430
+ readonly name: string;
1431
+ readonly elapsedMs: number;
1432
+ readonly usage?: OoxmlResourceUsageSnapshot;
1433
+ }
1415
1434
  /**
1416
- * An OMML equation embedded in a paragraph (ECMA-376 §22.1). Parsed into the
1417
- * shared math AST and rendered by `@silurus/ooxml-core`'s math engine.
1418
- * PowerPoint stores these as `a14:m` inside `mc:AlternateContent`.
1435
+ * Content-free, machine-readable resource report for an OOXML load or bounded
1436
+ * Node session. Byte counters describe measured package work, not the JavaScript
1437
+ * heap, WASM allocator overhead, decoded images, canvas, or GPU. Browser engines
1438
+ * and Viewers can return a newer snapshot after lazy package access.
1439
+ *
1440
+ * No source URL, filename, OOXML part name, document text, password, or raw
1441
+ * error message is included. Sizes, counts, and timings are still
1442
+ * document-derived metadata; applications apply their own consent, retention,
1443
+ * and telemetry policy.
1419
1444
  */
1420
- interface EquationRun {
1421
- type: 'math';
1422
- /** Parsed OMML node list. */
1423
- nodes: MathNode[];
1424
- /** True for block (`m:oMathPara`) math, false for inline (`m:oMath`). */
1425
- display: boolean;
1426
- /** Paragraph default run size in pt, if declared; absent → renderer inherits. */
1427
- fontSize?: number | null;
1428
- /** Equation colour (hex, no '#') from the math run's rPr; absent → inherit. */
1429
- color?: string | null;
1430
- }
1431
- interface TextRunData {
1432
- type: 'text';
1433
- text: string;
1434
- /** null = not set, inherit from paragraph/body defaults */
1435
- bold: boolean | null;
1436
- /** null = not set, inherit from paragraph/body defaults */
1437
- italic: boolean | null;
1438
- underline: boolean;
1439
- /**
1440
- * Specific underline style when not the default single line. Values come
1441
- * from ECMA-376 §21.1.2.3.16 (ST_TextUnderlineType): "dbl", "heavy",
1442
- * "dotted", "dottedHeavy", "dash", "dashHeavy", "dashLong",
1443
- * "dashLongHeavy", "dotDash", "dotDashHeavy", "dotDotDash",
1444
- * "dotDotDashHeavy", "wavy", "wavyHeavy", "wavyDbl". Absent means either
1445
- * no underline (when `underline` is false) or the default single line.
1446
- */
1447
- underlineStyle?: string;
1448
- /**
1449
- * Underline-only colour from rPr > uFill (ECMA-376 §21.1.2.3.20). Absent
1450
- * means the underline follows the text colour (uFillTx default).
1451
- */
1452
- underlineColor?: string;
1453
- /** True when rPr strike is sngStrike or dblStrike. */
1454
- strikethrough: boolean;
1455
- /**
1456
- * True only when rPr strike = "dblStrike". Lets the renderer draw two parallel
1457
- * lines instead of one. ECMA-376 §21.1.2.3.10 (ST_TextStrikeType).
1458
- */
1459
- strikeDouble?: boolean;
1460
- /** Font size in points */
1461
- fontSize: number | null;
1462
- color: string | null;
1463
- fontFamily: string | null;
1464
- /**
1465
- * East Asian font family from rPr > a:ea (ECMA-376 §21.1.2.3.7),
1466
- * resolved through the theme. Renderer uses this for CJK glyphs when
1467
- * present; absent means CJK falls back to fontFamily.
1468
- */
1469
- fontFamilyEa?: string;
1470
- /**
1471
- * Symbol font family from rPr > a:sym (ECMA-376 §21.1.2.3.10), resolved
1472
- * through the theme. PowerPoint stores symbol-font glyphs as Private-Use
1473
- * codepoints U+F020–U+F0FF; the renderer uses this font to resolve them.
1474
- * Absent means no symbol font was declared.
1475
- */
1476
- fontFamilySym?: string;
1477
- /** Baseline shift in thousandths of a point. Positive = superscript, negative = subscript. */
1478
- baseline?: number;
1479
- /**
1480
- * Capitalisation transform — ECMA-376 §21.1.2.3.13 (ST_TextCapsType).
1481
- * 'all' renders text in upper case; 'small' uses small caps (rendered as
1482
- * upper case at ~80% size when no smcp font feature is available).
1483
- * 'none' or omitted leaves the text unchanged.
1484
- */
1485
- caps?: 'none' | 'small' | 'all';
1486
- /**
1487
- * Inter-character spacing in 100ths of a point — ECMA-376 §21.1.2.3.5
1488
- * (rPr @spc). Positive values add space, negative values tighten.
1489
- */
1490
- letterSpacing?: number;
1491
- /** Set for OOXML field runs (e.g. "slidenum"). When set, renderer replaces text with field value. */
1492
- fieldType?: string;
1493
- /**
1494
- * Hyperlink target resolved from rPr > a:hlinkClick @r:id via the slide's _rels.
1495
- * For an external link this is the URL; for an internal slide jump it is the
1496
- * resolved internal part name (e.g. "../slides/slide3.xml"). Undefined for runs
1497
- * without a hyperlink. ECMA-376 §21.1.2.3.5 (CT_Hyperlink).
1498
- */
1499
- hyperlink?: string;
1500
- /**
1501
- * Raw `<a:hlinkClick @action>` string (e.g. "ppaction://hlinksldjump") when
1502
- * present — its presence marks {@link hyperlink} as an INTERNAL PowerPoint
1503
- * action (slide jump / first / last …) rather than an external URL. Undefined
1504
- * when the hlinkClick has no @action. ECMA-376 §21.1.2.3.5. (IX1)
1505
- */
1506
- hyperlinkAction?: string;
1507
- /**
1508
- * Run-level drop shadow on glyphs (`<a:rPr><a:effectLst><a:outerShdw>`),
1509
- * ECMA-376 §20.1.8.45. Independent of the shape-level shadow on `spPr`.
1510
- * Absent means no run-level shadow.
1511
- */
1512
- shadow?: Shadow;
1445
+ interface OoxmlResourceMetrics {
1446
+ /** Version of this metrics payload, independent of the package version. */
1447
+ readonly schemaVersion: 1;
1513
1448
  /**
1514
- * Run-level glyph outline (`<a:rPr><a:ln w="..">`), ECMA-376 §20.1.2.2.24
1515
- * (CT_TextOutlineEffect). Renderer strokes each glyph with the given
1516
- * width / colour in addition to the normal fill. Absent means glyphs are
1517
- * fill-only.
1449
+ * Browser factories report `load`; bounded Node sessions report `session`.
1518
1450
  */
1519
- outline?: TextOutline;
1451
+ readonly scope: 'load' | 'session';
1452
+ readonly format: OoxmlFormat;
1453
+ readonly mode: 'main' | 'worker' | 'node';
1454
+ /** Outcome of this measured load/session, not of later render operations. */
1455
+ readonly status: 'ok' | 'error';
1456
+ /** Compressed or decrypted OOXML container bytes supplied to the parser. */
1457
+ readonly sourceBytes?: number;
1458
+ readonly elapsedMs: number;
1459
+ readonly policy: Readonly<OoxmlResourcePolicySnapshot>;
1460
+ /** Last complete observed package-usage checkpoint. */
1461
+ readonly usage?: OoxmlResourceUsageSnapshot;
1462
+ readonly checkpoints: readonly OoxmlResourceMetricsCheckpoint[];
1463
+ readonly outcome?: Readonly<Record<string, number>>;
1464
+ readonly error?: Readonly<{
1465
+ readonly code?: string;
1466
+ readonly stage?: string;
1467
+ readonly resource?: string;
1468
+ readonly metric?: string;
1469
+ }>;
1470
+ }
1471
+ //#endregion
1472
+ //#region packages/core/src/types/load-options.d.ts
1473
+ /** A positive safe-integer byte count, or `null` to disable one public limit. */
1474
+ type OoxmlResourceLimit = number | null;
1475
+ /** Admission limits for the inflated contents of one OOXML package session. */
1476
+ interface OoxmlResourceLimits {
1520
1477
  /**
1521
- * Run-level text highlight / marker colour (`<a:rPr><a:highlight>`),
1522
- * ECMA-376 §21.1.2.3.4. In DrawingML this is a full CT_Color (any
1523
- * srgbClr / schemeClr / sysClr / prstClr + transforms), unlike
1524
- * WordprocessingML's fixed 16-name highlight enum — so the parser already
1525
- * resolves it through the theme/clrMap. The value is a hex string without
1526
- * `#` (6-char opaque, or 8-char RRGGBBAA when an alpha transform applies);
1527
- * the renderer paints a background rectangle behind the run's glyphs.
1528
- * Absent means no highlight.
1478
+ * Maximum permitted inflated size for any one archive entry, including
1479
+ * media. Enforced against both the ZIP declaration and actual output.
1529
1480
  */
1530
- highlight?: string;
1531
- }
1532
- /** Run-level glyph outline. Width is in OOXML EMU (12700 EMU = 1 pt). */
1533
- interface TextOutline {
1534
- width: number;
1535
- /** Hex without '#'. Absent = inherit from text fill colour. */
1536
- color?: string;
1481
+ maxArchiveEntryBytes?: OoxmlResourceLimit;
1482
+ /** Maximum actual inflated bytes across distinct entries in the session. */
1483
+ maxTotalInflatedBytes?: OoxmlResourceLimit;
1537
1484
  }
1538
- interface LineBreak {
1539
- type: 'break';
1485
+ //#endregion
1486
+ //#region packages/core/src/image/pixel-budget.d.ts
1487
+ type OoxmlDecodedImageLimitMetric = 'image-pixels' | 'active-decoded-bytes';
1488
+ /** Catchable hard-quota crossing for decoded image surfaces. */
1489
+ declare class OoxmlDecodedImageLimitError extends RangeError {
1490
+ readonly metric: OoxmlDecodedImageLimitMetric;
1491
+ readonly limit: number;
1492
+ readonly observed: number;
1493
+ readonly code: "ooxml-decoded-image-limit";
1494
+ constructor(metric: OoxmlDecodedImageLimitMetric, limit: number, observed: number);
1540
1495
  }
1496
+ declare function isOoxmlDecodedImageLimitError(error: unknown): error is OoxmlDecodedImageLimitError;
1497
+ //#endregion
1498
+ //#region packages/core/src/interaction/hyperlink.d.ts
1499
+ /**
1500
+ * Shared hyperlink model + URL sanitisation for docx / pptx / xlsx (IX1).
1501
+ *
1502
+ * All three formats carry the same two ECMA-376 concepts:
1503
+ * - an **external** hyperlink — an absolute URL resolved from a relationship
1504
+ * part target (`document.xml.rels` for docx §17.16.22, the slide rels for
1505
+ * pptx §21.1.2.3.5, the worksheet rels for xlsx §18.3.1.47), with
1506
+ * `TargetMode="External"`.
1507
+ * - an **internal** hyperlink — a jump within the document itself:
1508
+ * docx `w:anchor` -> a `<w:bookmarkStart w:name>` (§17.16.23), pptx
1509
+ * `action="ppaction://hlinksldjump"` -> a slide, xlsx `location` -> a defined
1510
+ * name or a `Sheet!A1` cell reference.
1511
+ *
1512
+ * The parsers (Rust, one per format) do the format-specific rels lookup and hand
1513
+ * each run / shape / cell a {@link HyperlinkTarget}. Everything downstream — the
1514
+ * text-layer overlay, the viewer default click behaviour, and any integrator
1515
+ * callback — is format-agnostic and consumes this one shape. Keeping the type +
1516
+ * the pure `sanitizeHyperlinkUrl` predicate here (not duplicated per package)
1517
+ * follows the cross-package unification principle: a scheme-allowlist bug fixed
1518
+ * once is fixed everywhere.
1519
+ */
1520
+ /**
1521
+ * A resolved hyperlink attached to a run, shape, or cell.
1522
+ *
1523
+ * - `external` — `url` is the raw target as authored in the file. It is NOT
1524
+ * guaranteed safe; run it through {@link sanitizeHyperlinkUrl} before
1525
+ * navigating. It is kept verbatim here so an integrator can apply its own
1526
+ * policy (e.g. allow `file:` on a trusted intranet viewer).
1527
+ * - `internal` — `ref` is the in-document destination, verbatim from the file:
1528
+ * docx: the bookmark name (`w:anchor`).
1529
+ * pptx: the internal action (e.g. `ppaction://hlinksldjump`), with the
1530
+ * resolved 0-based `slideIndex` when the rels target names a slide.
1531
+ * xlsx: the `location` string (a defined name or `Sheet1!A1`).
1532
+ */
1533
+ type HyperlinkTarget = {
1534
+ kind: 'external';
1535
+ url: string;
1536
+ } | {
1537
+ kind: 'internal';
1538
+ ref: string;
1539
+ slideIndex?: number;
1540
+ };
1541
1541
  //#endregion
1542
- //#region dist/.types-work/renderer-CU7Ays06.d.ts
1542
+ //#region dist/.types-work/renderer-BwmBZ5GX.d.ts
1543
1543
  //#endregion
1544
1544
  //#region packages/docx/src/renderer.d.ts
1545
1545
  /** Information about a rendered text segment for building a transparent selection overlay. */
@@ -2706,10 +2706,9 @@ interface DocParagraph {
2706
2706
  defaultFontFamilyEastAsia?: string | null;
2707
2707
  /** ECMA-376 §17.3.1.29 — the paragraph mark run's resolved `w:color` (direct
2708
2708
  * pPr/rPr → pStyle chain → docDefaults; hex 6 without `#`, lowercased; an
2709
- * explicit `auto` surfaces as absent, §17.3.2.6). The numbering level rPr
2710
- * (§17.9.24) layers over the mark's run properties, so the renderer uses
2711
- * this as the marker-color fallback when {@link NumberingInfo.color} is
2712
- * absent. */
2709
+ * explicit `auto` surfaces as absent, §17.3.2.6). Compatibility rule
2710
+ * `word-numbering-marker-paragraph-mark-fallback` uses this when §17.9.24
2711
+ * leaves {@link NumberingInfo.color} absent. */
2713
2712
  paragraphMarkColor?: string | null;
2714
2713
  /**
2715
2714
  * ECMA-376 §17.3.1.6 `<w:bidi>` — right-to-left paragraph. `true` = RTL,
@@ -2835,7 +2834,8 @@ interface NumberingInfo {
2835
2834
  * it (the renderer treats absent as "left"). */
2836
2835
  jc?: string;
2837
2836
  /** ECMA-376 §17.3.2.26 ascii axis for the marker glyph, resolved through the
2838
- * level's `rPr` (§17.9.6) merged over the paragraph's run formatting. The
2837
+ * level's `rPr` (§17.9.24) plus compatibility rule
2838
+ * `word-numbering-marker-paragraph-mark-fallback`. The
2839
2839
  * renderer draws Latin marker chars (e.g. a decimal "1") with this family, so
2840
2840
  * a heading whose ascii=Times renders its auto-number in Times (serif) even
2841
2841
  * when eastAsia=Gothic. Absent ⇒ the renderer falls back to its default. */
@@ -2848,9 +2848,11 @@ interface NumberingInfo {
2848
2848
  /** ECMA-376 §17.9.24 — the numbering level rPr's `w:color` (hex 6 without
2849
2849
  * `#`, lowercased). Colors the marker glyph only, never the paragraph's
2850
2850
  * runs. Absent ⇒ the renderer falls back to
2851
- * {@link DocParagraph.paragraphMarkColor} (§17.3.1.29 the level rPr layers
2852
- * over the paragraph mark's run properties) and finally to its
2853
- * default ink. An explicit `w:val="auto"` is absent here + {@link colorAuto}. */
2851
+ * {@link DocParagraph.paragraphMarkColor} under compatibility rule
2852
+ * `word-numbering-marker-paragraph-mark-fallback`, then to its default ink.
2853
+ * §17.3.1.29 defines the
2854
+ * mark properties but not that fallback. An explicit `w:val="auto"` is
2855
+ * absent here + {@link colorAuto}. */
2854
2856
  color?: string | null;
2855
2857
  /** ECMA-376 §17.3.2.6 / ST_HexColorAuto (§17.18.39) — true when the level
2856
2858
  * rPr carries an EXPLICIT `w:color w:val="auto"`. Auto names no concrete
@@ -3001,6 +3003,9 @@ interface AnchorHostMetrics {
3001
3003
  italic?: boolean;
3002
3004
  }
3003
3005
  interface ShapeRun {
3006
+ /** ECMA-376 §20.4.2.8 — true when the shape is hosted by `<wp:inline>` and
3007
+ * therefore advances the paragraph pen like an inline drawing object. */
3008
+ inline?: boolean;
3004
3009
  widthPt: number;
3005
3010
  heightPt: number;
3006
3011
  /** X offset in pt */
@@ -3171,6 +3176,13 @@ interface ShapeText$1 {
3171
3176
  text: string;
3172
3177
  fontSizePt: number;
3173
3178
  color?: string | null;
3179
+ /** Resolved paragraph-mark run color used by compatibility rule
3180
+ * `word-numbering-marker-paragraph-mark-fallback` when the numbering level
3181
+ * has no explicit color; kept separate from the first content run's
3182
+ * compatibility-level {@link ShapeText.color}. `null` means the parser
3183
+ * resolved automatic/default ink; `undefined` preserves the legacy contract
3184
+ * for hand-built values that did not provide paragraph-mark facts. */
3185
+ paragraphMarkColor?: string | null;
3174
3186
  fontFamily?: string | null;
3175
3187
  bold?: boolean;
3176
3188
  italic?: boolean;
@@ -3253,6 +3265,24 @@ type ShapeFill = {
3253
3265
  stops: GradientStop[];
3254
3266
  angle: number;
3255
3267
  gradType: string;
3268
+ } | {
3269
+ /** ECMA-376 §20.1.8.14 picture fill on a DrawingML shape. */
3270
+ fillType: 'image';
3271
+ imagePath: string;
3272
+ mimeType: string;
3273
+ /** Microsoft 2016 SVG original retained beside the raster fallback. */
3274
+ svgImagePath?: string;
3275
+ /** ECMA-376 §20.1.8.55 source-image crop. */
3276
+ srcRect?: {
3277
+ l: number;
3278
+ t: number;
3279
+ r: number;
3280
+ b: number;
3281
+ };
3282
+ fillRect?: FillRect;
3283
+ tile?: TileInfo;
3284
+ alpha?: number;
3285
+ duotone?: Duotone$1;
3256
3286
  };
3257
3287
  interface GradientStop {
3258
3288
  /** 0.0–1.0 */
@@ -3393,7 +3423,8 @@ interface DocxTextRun {
3393
3423
  * width, not the gap between glyphs. Absent ⇒ 100%. */
3394
3424
  charScale?: number;
3395
3425
  /** ECMA-376 §17.3.2.24 `<w:position w:val>` — baseline raise (positive) /
3396
- * lower (negative) in POINTS, without changing the font size or line box.
3426
+ * lower (negative) in POINTS, without changing the font size. The shifted
3427
+ * ink still participates in the surrounding line's visible extent.
3397
3428
  * Absent ⇒ no shift. */
3398
3429
  position?: number;
3399
3430
  /** ECMA-376 §17.3.2.19 `<w:kern w:val>` — font-kerning threshold in POINTS