@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/mathjax-BO1uUSCW.d.ts
1
+ //#region dist/.types-work/mathjax-Cp9KrvN5.d.ts
2
2
  //#region packages/core/src/math/mathjax.d.ts
3
3
  interface MathSvg {
4
4
  /** standalone `<svg>…</svg>` markup. */
@@ -29,7 +29,7 @@ interface MathRenderer {
29
29
  mathMLToSvg(mathml: string): Promise<MathSvg>;
30
30
  }
31
31
  //#endregion
32
- //#region dist/.types-work/hyperlink-CHHEOeCL.d.ts
32
+ //#region dist/.types-work/hyperlink-DTGUpBI3.d.ts
33
33
  //#region packages/core/src/types/math.d.ts
34
34
  type MathStyle = 'roman' | 'italic' | 'bold' | 'boldItalic';
35
35
  interface MathRun {
@@ -180,182 +180,654 @@ interface Duotone {
180
180
  clr2: string;
181
181
  }
182
182
  //#endregion
183
- //#region packages/core/src/types/chart.d.ts
184
- interface ChartSeries {
185
- name: string;
186
- /** Hex without '#'. null = fall back to palette. */
187
- color: string | null;
188
- /** Numeric values; null = missing data point. */
189
- values: (number | null)[];
183
+ //#region packages/core/src/types/common.d.ts
184
+ type PathCmd = {
185
+ cmd: 'moveTo';
186
+ x: number;
187
+ y: number;
188
+ } | {
189
+ cmd: 'lineTo';
190
+ x: number;
191
+ y: number;
192
+ } | {
193
+ cmd: 'cubicBezTo';
194
+ x1: number;
195
+ y1: number;
196
+ x2: number;
197
+ y2: number;
198
+ x: number;
199
+ y: number;
200
+ } | {
201
+ cmd: 'arcTo';
202
+ wr: number;
203
+ hr: number;
204
+ stAng: number;
205
+ swAng: number;
206
+ } | {
207
+ cmd: 'close';
208
+ };
209
+ type Fill = SolidFill | NoFill | GradientFill | PatternFill | ImageFill;
210
+ interface SolidFill {
211
+ fillType: 'solid';
212
+ color: string;
213
+ }
214
+ interface NoFill {
215
+ fillType: 'none';
216
+ }
217
+ interface GradientStop {
218
+ position: number;
219
+ color: string;
220
+ }
221
+ interface GradientFill {
222
+ fillType: 'gradient';
223
+ stops: GradientStop[];
224
+ /** degrees: 0 = left→right, 90 = top→bottom */
225
+ angle: number;
226
+ /** 'linear' | 'radial' */
227
+ gradType: string;
228
+ }
229
+ /**
230
+ * Preset pattern fill — ECMA-376 §20.1.8.40 (CT_PatternFillProperties)
231
+ * with `preset` drawn from §20.1.10.59 (ST_PresetPatternVal).
232
+ */
233
+ interface PatternFill {
234
+ fillType: 'pattern';
235
+ /** Foreground hex colour — used for the "1" pixels of the preset bitmap. */
236
+ fg: string;
237
+ /** Background hex colour — used for the "0" pixels. */
238
+ bg: string;
239
+ /** Preset name, e.g. "pct25", "horz", "diagCross", "lgGrid". */
240
+ preset: string;
241
+ }
242
+ /**
243
+ * ECMA-376 §20.1.8.30 (CT_RelativeRect) — the destination rectangle a stretched
244
+ * blip is mapped into, as edge insets relative to the fill region. Values are
245
+ * fractions (ST_Percentage / 100000); **negative values let the image bleed
246
+ * past the box (overscan)**. Absent edges default to 0.
247
+ */
248
+ interface FillRect {
249
+ l?: number;
250
+ t?: number;
251
+ r?: number;
252
+ b?: number;
253
+ }
254
+ /**
255
+ * ECMA-376 §20.1.8.58 (CT_TileInfoProperties) — tiled blip-fill placement.
256
+ * The blip repeats at its native size (scaled by sx/sy) across the fill box.
257
+ * Mutually exclusive with {@link ImageFill.fillRect} (the `stretch` mode).
258
+ */
259
+ interface TileInfo {
260
+ /** Horizontal offset of the first tile, in EMU (`tx`). Default 0. */
261
+ tx: number;
262
+ /** Vertical offset of the first tile, in EMU (`ty`). Default 0. */
263
+ ty: number;
264
+ /** Horizontal tile scale as a fraction (`sx` / 100000). Default 1.0. */
265
+ sx: number;
266
+ /** Vertical tile scale as a fraction (`sy` / 100000). Default 1.0. */
267
+ sy: number;
268
+ /** Mirror mode: `'none' | 'x' | 'y' | 'xy'` (`flip`). Default `'none'`. */
269
+ flip: string;
190
270
  /**
191
- * Per-data-point colors (pie / doughnut). Hex without '#'. null inside the
192
- * array = use palette for that slice. Omit entirely for non-pie series.
271
+ * Anchor corner the tile grid registers against:
272
+ * `tl|t|tr|l|ctr|r|bl|b|br` (`algn`). The schema has no default; a host may
273
+ * apply a compatibility fallback when omitted.
193
274
  */
194
- dataPointColors?: (string | null)[] | null;
275
+ algn?: string;
276
+ }
277
+ /**
278
+ * Image fill — ECMA-376 §20.1.8.14 (CT_BlipFillProperties). The embedded blip
279
+ * is carried as a zip path + MIME; the renderer fetches the bytes on demand via
280
+ * {@link RenderOptions.fetchImage} (no base64 inlined at parse time). Both
281
+ * fill-modes are modelled and mutually exclusive: `stretch` (§20.1.8.56) carries
282
+ * {@link ImageFill.fillRect}; `tile` (§20.1.8.58) carries {@link ImageFill.tile}.
283
+ */
284
+ interface ImageFill {
285
+ fillType: 'image';
195
286
  /**
196
- * Per-data-point data-label text colors. Used by chartEx (`<cx:dataLabel idx>`)
197
- * to override label colour per bar sample-2's waterfall paints negative
198
- * values in red while positive values stay black. Null inside the array =
199
- * fall back to the chart-level `dataLabelFontColor`.
287
+ * Embedded zip path of the blip (e.g. "word/media/image1.png"), for the lazy
288
+ * byte-on-demand pipeline. The renderer fetches the bytes via a path-keyed
289
+ * loader ({@link RenderOptions.fetchImage}) instead of inlining base64.
200
290
  */
201
- dataLabelColors?: (string | null)[] | null;
291
+ imagePath: string;
292
+ /** MIME type of the blip at {@link ImageFill.imagePath} (e.g. `image/png`). */
293
+ mimeType: string;
202
294
  /**
203
- * Series-level data-label text colour (`<c:ser><c:dLbls><c:txPr>…solidFill`,
204
- * ECMA-376 §21.2.2.216). Hex without '#'. Stacked-bar charts colour each
205
- * segment's label independently (e.g. white on the dark segment, black on
206
- * the light one), which a single chart-level `dataLabelFontColor` can't
207
- * express. Takes precedence over `dataLabelFontColor`; null = no override.
295
+ * `<a:stretch><a:fillRect>` insets. Absent fills the whole box (or the
296
+ * fill is tiled see {@link ImageFill.tile}).
208
297
  */
209
- labelColor?: string | null;
298
+ fillRect?: FillRect;
210
299
  /**
211
- * Mixed chart: per-series chart type override. Currently only "line" (XLSX
212
- * and PPTX combo charts) is honoured; other values are treated as the
213
- * chart's primary type.
300
+ * `<a:tile>` descriptor. Present only when the blipFill is tiled; mutually
301
+ * exclusive with {@link ImageFill.fillRect}.
214
302
  */
215
- seriesType?: string | null;
303
+ tile?: TileInfo;
304
+ /** `a:blip > a:alphaModFix@amt` as a fraction (0.0–1.0). Absent = opaque. */
305
+ alpha?: number;
216
306
  /**
217
- * Combo chart: this series is plotted against the SECONDARY value axis
218
- * (`ChartModel.secondaryValAxis`) the `<c:valAx>` with `axPos="r"` /
219
- * `<c:crosses val="max">`. When false/absent the series uses the primary
220
- * (left) value-axis scale. PowerPoint's "Revenue vs. gross margin" combo
221
- * (sample-14 slide-8) puts the margin line on a 0–100% secondary axis.
307
+ * ECMA-376 §20.1.8.23 `<a:duotone>` recolour, resolved to its two endpoint
308
+ * colours (through the slide theme). Absent no duotone. When present the
309
+ * renderer maps the blip's luminance ramp between the two colours (core
310
+ * `applyDuotone`) the same recolour a `<p:pic>` duotone applies, wired onto
311
+ * the picture-FILL path (§20.1.8.14) by issue #889.
222
312
  */
223
- useSecondaryAxis?: boolean | null;
313
+ duotone?: Duotone;
314
+ }
315
+ interface Shadow {
316
+ color: string;
317
+ alpha: number;
318
+ blur: number;
319
+ dist: number;
320
+ /** degrees clockwise from East */
321
+ dir: number;
322
+ }
323
+ /** ECMA-376 §20.1.8.17 (CT_GlowEffect) — coloured halo with blur radius. */
324
+ interface Glow {
325
+ color: string;
326
+ alpha: number;
327
+ /** Blur radius in EMU. */
328
+ radius: number;
329
+ }
330
+ /** ECMA-376 §20.1.8.31 (CT_SoftEdgesEffect) — feather radius in EMU. */
331
+ interface SoftEdge {
332
+ radius: number;
333
+ }
334
+ /** ECMA-376 §20.1.8.27 (CT_ReflectionEffect) — mirrored copy below the
335
+ * shape with a linear alpha gradient. Carries the spec attributes whose
336
+ * defaults the renderer needs to interpret correctly. */
337
+ interface Reflection {
338
+ blur: number;
339
+ dist: number;
340
+ /** Direction in degrees, clockwise from East. */
341
+ dir: number;
342
+ /** Start alpha (0–1). Default 1.0. */
343
+ stA: number;
344
+ /** Start position along the gradient (0–1). Default 0. */
345
+ stPos: number;
346
+ /** End alpha. Default 0. */
347
+ endA: number;
348
+ /** End position. Default 1.0. */
349
+ endPos: number;
350
+ /** Horizontal scale (1.0 = same width). */
351
+ sx: number;
352
+ /** Vertical scale (-1.0 = full mirror). */
353
+ sy: number;
354
+ }
355
+ interface ArrowEnd {
356
+ /** OOXML type: "none" | "triangle" | "stealth" | "diamond" | "oval" | "arrow" */
357
+ type: string;
358
+ /** Width multiplier: "sm" | "med" | "lg" */
359
+ w: string;
360
+ /** Length multiplier: "sm" | "med" | "lg" */
361
+ len: string;
362
+ }
363
+ interface Stroke {
364
+ color: string;
365
+ /** Width in EMU */
366
+ width: number;
367
+ /** Authored non-solid DrawingML line paint. Solid lines use `color`. */
368
+ fill?: Exclude<Fill, {
369
+ fillType: 'image';
370
+ } | {
371
+ fillType: 'none';
372
+ }>;
373
+ /** OOXML prstDash value: "dash", "dot", "dashDot", "lgDash", "lgDashDot", etc. */
374
+ dashStyle?: string;
375
+ /** Canvas line cap normalized from DrawingML/VML (`flat` → `butt`). */
376
+ lineCap?: CanvasLineCap;
377
+ /** Arrow head at the start of the line */
378
+ headEnd?: ArrowEnd;
379
+ /** Arrow head at the end of the line */
380
+ tailEnd?: ArrowEnd;
224
381
  /**
225
- * Scatter-only X values (as strings). When null the series uses
226
- * `ChartModel.categories` as X.
382
+ * ECMA-376 §20.1.8.42 ST_CompoundLine. "sng" (default) | "dbl" |
383
+ * "thinThick" | "thickThin" | "tri". Absent means single line.
227
384
  */
228
- categories?: string[] | null;
385
+ cmpd?: string;
386
+ }
387
+ interface TextBody$1 {
388
+ /** Vertical anchor: "t" | "ctr" | "b" */
389
+ verticalAnchor: string;
390
+ paragraphs: Paragraph$1[];
391
+ /** Default pt size from lstStyle (overrides renderer default when present) */
392
+ defaultFontSize: number | null;
393
+ /** Inherited bold from layout/master defRPr (null = not set, use false as final default) */
394
+ defaultBold: boolean | null;
395
+ /** Inherited italic from layout/master defRPr (null = not set, use false as final default) */
396
+ defaultItalic: boolean | null;
397
+ /** Text insets in EMU (defaults: lIns=rIns=91440, tIns=bIns=45720) */
398
+ lIns: number;
399
+ rIns: number;
400
+ tIns: number;
401
+ bIns: number;
402
+ /** "square" = wrap, "none" = no wrap */
403
+ wrap: string;
404
+ /** Text direction: "horz" | "vert" | "vert270" | "eaVert" etc. */
405
+ vert: string;
406
+ /** Auto-fit: "sp" = shape grows to fit text, "norm" = font shrinks, "none" = no fit */
407
+ autoFit: string;
229
408
  /**
230
- * Resolved marker visibility for line/scatter series. ECMA-376 §21.2.2.32
231
- * `<c:marker><c:symbol>` defaults to "none" for line charts unless the
232
- * chart-level `<c:marker val="1"/>` or a per-series symbol opts in. When
233
- * undefined/null the renderer uses its own default (visible) so callers
234
- * that don't parse markers (e.g. pptx today) keep their existing behavior.
409
+ * `<a:normAutofit fontScale>` (ECMA-376 §21.1.2.1.3) — PowerPoint's stored,
410
+ * pre-computed font-shrink ratio for `autoFit === "norm"`, as a fraction
411
+ * (e.g. 0.625 for `fontScale="62500"`). Null/absent when PowerPoint stored no
412
+ * scale; the renderer then re-derives one. Applying the stored value matches
413
+ * PowerPoint exactly instead of guessing from our own text metrics.
235
414
  */
236
- showMarker?: boolean | null;
237
- /**
238
- * Excel number-format code for this series' values (ECMA-376 §21.2.2.37,
239
- * `<c:val>/<c:numRef>/<c:formatCode>`). Used to format data labels when the
240
- * chart-level `<c:dLbls><c:numFmt>` is not set. null = no series-level code.
415
+ fontScale?: number | null;
416
+ /** `<a:normAutofit lnSpcReduction>` — stored line-spacing reduction fraction
417
+ * (e.g. 0.20 for `lnSpcReduction="20000"`). Null/absent when not stored. */
418
+ lnSpcReduction?: number | null;
419
+ /**
420
+ * `<a:bodyPr numCol>` (ECMA-376 §20.1.10.34) — number of text columns inside
421
+ * the shape. Defaults to 1; values > 1 cause the renderer to flow paragraphs
422
+ * across N columns left-to-right, top-to-bottom.
241
423
  */
242
- valFormatCode?: string | null;
424
+ numCol?: number;
425
+ /** `<a:bodyPr spcCol>` — gap between columns in EMU. Default 0. */
426
+ spcCol?: number;
427
+ }
428
+ type SpaceLine = {
429
+ type: 'pct';
430
+ val: number;
431
+ } | {
432
+ type: 'pts';
433
+ val: number;
434
+ };
435
+ /**
436
+ * A paragraph's bullet marker. For `char`, the marker size is EITHER `sizePct`
437
+ * (a percentage of the run size — ECMA-376 §21.1.2.4.9 `<a:buSzPct>`) OR `sizePts`
438
+ * (an absolute size in points — §21.1.2.4.10 `<a:buSzPts>`), never both: they are
439
+ * the one `EG_TextBulletSize` xsd:choice. `sizePts` is optional (absent when no
440
+ * `<a:buSzPts>` was declared); when present it takes precedence over `sizePct`.
441
+ */
442
+ type Bullet$1 = {
443
+ type: 'none';
444
+ } | {
445
+ type: 'inherit';
446
+ } | {
447
+ type: 'char';
448
+ char: string;
449
+ color: string | null;
450
+ sizePct: number | null;
451
+ sizePts?: number;
452
+ fontFamily: string | null;
453
+ } | {
454
+ type: 'autoNum';
455
+ numType: string;
456
+ startAt: number | null;
457
+ color: string | null;
458
+ };
459
+ interface TabStop {
460
+ /** Position in EMU from the LEADING text-inset edge of the text area —
461
+ * logical, not physical (ECMA-376 §21.1.2.1): the left edge (after lIns)
462
+ * in an LTR paragraph, the right edge (before rIns) in an RTL
463
+ * (`<a:pPr rtl="1">`) paragraph. */
464
+ pos: number;
465
+ /** Alignment: "l" | "r" | "ctr" | "dec" */
466
+ algn: string;
467
+ }
468
+ interface Paragraph$1 {
469
+ /** Alignment: "l" | "ctr" | "r" | "just" */
470
+ alignment: string;
471
+ /** Left margin in EMU */
472
+ marL: number;
473
+ /** Right margin in EMU */
474
+ marR: number;
475
+ /** First-line indent in EMU (negative = hanging indent) */
476
+ indent: number;
477
+ spaceBefore: number | null;
478
+ spaceAfter: number | null;
479
+ spaceLine: SpaceLine | null;
480
+ /** List nesting level (0–8) */
481
+ lvl: number;
482
+ bullet: Bullet$1;
483
+ defFontSize: number | null;
484
+ defColor: string | null;
485
+ defBold: boolean | null;
486
+ defItalic: boolean | null;
487
+ defFontFamily: string | null;
488
+ /** Tab stops from pPr > tabLst */
489
+ tabStops: TabStop[];
243
490
  /**
244
- * `<c:marker><c:symbol val>` (ECMA-376 §21.2.2.32) — point marker shape.
245
- * One of "circle"|"square"|"diamond"|"triangle"|"x"|"plus"|"star"|
246
- * "dot"|"dash"|"picture"|"none". null = renderer default (circle when
247
- * showMarker is true).
491
+ * `<a:pPr rtl="1">` — right-to-left paragraph (ECMA-376 §21.1.2.2.7).
492
+ * When true and no explicit `algn`, the parser-side default flips from
493
+ * "l" to "r"; renderers can also use this flag to flow runs RTL.
248
494
  */
249
- markerSymbol?: string | null;
495
+ rtl?: boolean;
496
+ runs: TextRun[];
497
+ }
498
+ type TextRun = TextRunData | LineBreak | EquationRun;
499
+ /**
500
+ * An OMML equation embedded in a paragraph (ECMA-376 §22.1). Parsed into the
501
+ * shared math AST and rendered by `@silurus/ooxml-core`'s math engine.
502
+ * PowerPoint stores these as `a14:m` inside `mc:AlternateContent`.
503
+ */
504
+ interface EquationRun {
505
+ type: 'math';
506
+ /** Parsed OMML node list. */
507
+ nodes: MathNode[];
508
+ /** True for block (`m:oMathPara`) math, false for inline (`m:oMath`). */
509
+ display: boolean;
510
+ /** Paragraph default run size in pt, if declared; absent → renderer inherits. */
511
+ fontSize?: number | null;
512
+ /** Equation colour (hex, no '#') from the math run's rPr; absent → inherit. */
513
+ color?: string | null;
514
+ }
515
+ interface TextRunData {
516
+ type: 'text';
517
+ text: string;
518
+ /** null = not set, inherit from paragraph/body defaults */
519
+ bold: boolean | null;
520
+ /** null = not set, inherit from paragraph/body defaults */
521
+ italic: boolean | null;
522
+ underline: boolean;
250
523
  /**
251
- * `<c:marker><c:size val>` (ECMA-376 §21.2.2.34) marker side length in
252
- * points. null = renderer default (~5 pt).
524
+ * Specific underline style when not the default single line. Values come
525
+ * from ECMA-376 §21.1.2.3.16 (ST_TextUnderlineType): "dbl", "heavy",
526
+ * "dotted", "dottedHeavy", "dash", "dashHeavy", "dashLong",
527
+ * "dashLongHeavy", "dotDash", "dotDashHeavy", "dotDotDash",
528
+ * "dotDotDashHeavy", "wavy", "wavyHeavy", "wavyDbl". Absent means either
529
+ * no underline (when `underline` is false) or the default single line.
253
530
  */
254
- markerSize?: number | null;
255
- /** `<c:marker><c:spPr><a:solidFill>` resolved hex (no `#`). */
256
- markerFill?: string | null;
257
- /** `<c:marker><c:spPr><a:ln><a:solidFill>` resolved hex (no `#`). */
258
- markerLine?: string | null;
531
+ underlineStyle?: string;
259
532
  /**
260
- * Per-data-point overrides (ECMA-376 §21.2.2.39 `<c:dPt>`). Keyed by point
261
- * index. Any unset field falls back to the series-level value.
533
+ * Underline-only colour from rPr > uFill (ECMA-376 §21.1.2.3.20). Absent
534
+ * means the underline follows the text colour (uFillTx default).
262
535
  */
263
- dataPointOverrides?: ChartDataPointOverride[] | null;
536
+ underlineColor?: string;
537
+ /** True when rPr strike is sngStrike or dblStrike. */
538
+ strikethrough: boolean;
264
539
  /**
265
- * Per-data-point custom labels (ECMA-376 §21.2.2.45 `<c:dLbl idx>`).
266
- * `text` is the resolved plain string — `<a:fld type="CELLRANGE">`
267
- * placeholders are already substituted at parse time. An empty string
268
- * means the point's label was deleted with `<c:delete val="1"/>` and
269
- * the renderer should skip it.
540
+ * True only when rPr strike = "dblStrike". Lets the renderer draw two parallel
541
+ * lines instead of one. ECMA-376 §21.1.2.3.10 (ST_TextStrikeType).
270
542
  */
271
- dataLabelOverrides?: ChartDataLabelOverride[] | null;
543
+ strikeDouble?: boolean;
544
+ /** Font size in points */
545
+ fontSize: number | null;
546
+ color: string | null;
547
+ fontFamily: string | null;
272
548
  /**
273
- * Series-level `<c:dLbls>` block (showVal / showSerName / position).
274
- * Applied to every point lacking its own `<c:dLbl>` override.
549
+ * East Asian font family from rPr > a:ea (ECMA-376 §21.1.2.3.7),
550
+ * resolved through the theme. Renderer uses this for CJK glyphs when
551
+ * present; absent means CJK falls back to fontFamily.
275
552
  */
276
- seriesDataLabels?: ChartSeriesDataLabels | null;
553
+ fontFamilyEa?: string;
277
554
  /**
278
- * `<c:errBars>` per-series error bars (ECMA-376 §21.2.2.20). Up to two
279
- * (one per direction). Plus / minus deltas are absolute per-point values
280
- * regardless of `errValType`.
555
+ * Symbol font family from rPr > a:sym (ECMA-376 §21.1.2.3.10), resolved
556
+ * through the theme. PowerPoint stores symbol-font glyphs as Private-Use
557
+ * codepoints U+F020–U+F0FF; the renderer uses this font to resolve them.
558
+ * Absent means no symbol font was declared.
281
559
  */
282
- errBars?: ChartErrBars[] | null;
560
+ fontFamilySym?: string;
561
+ /** Baseline shift in thousandths of a point. Positive = superscript, negative = subscript. */
562
+ baseline?: number;
283
563
  /**
284
- * `<c:bubbleSize>` per-point sizes for bubble charts (ECMA-376 §21.2.2.4).
285
- * Drives marker radius renderer treats the values as areas (radius
286
- * scales by sqrt) so visual area is proportional to value, matching
287
- * Excel. null / empty array = uniform marker size. Ignored for non-bubble
288
- * series.
564
+ * Capitalisation transform ECMA-376 §21.1.2.3.13 (ST_TextCapsType).
565
+ * 'all' renders text in upper case; 'small' uses small caps (rendered as
566
+ * upper case at ~80% size when no smcp font feature is available).
567
+ * 'none' or omitted leaves the text unchanged.
289
568
  */
290
- bubbleSizes?: (number | null)[] | null;
569
+ caps?: 'none' | 'small' | 'all';
291
570
  /**
292
- * `<c:ser><c:smooth val>` (ECMA-376 §21.2.2.194) — line/area series flag
293
- * requesting a smoothed (spline) curve through the points instead of straight
294
- * segments. Only consulted for the line and area families (scatter carries its
295
- * smoothing in `ChartModel.scatterStyle`). null/undefined/false = straight
296
- * polyline (the default; byte-stable for series that never set it).
571
+ * Inter-character spacing in 100ths of a point — ECMA-376 §21.1.2.3.5
572
+ * (rPr @spc). Positive values add space, negative values tighten.
297
573
  */
298
- smooth?: boolean | null;
574
+ letterSpacing?: number;
575
+ /** Set for OOXML field runs (e.g. "slidenum"). When set, renderer replaces text with field value. */
576
+ fieldType?: string;
299
577
  /**
300
- * `<c:ser><c:trendline>` per-series trendlines (ECMA-376 §21.2.2.211,
301
- * `CT_Trendline`). A series can carry several (e.g. a linear fit + a moving
302
- * average). null/undefined/empty = no trendline (the default; byte-stable for
303
- * series that never declare one).
578
+ * Hyperlink target resolved from rPr > a:hlinkClick @r:id via the slide's _rels.
579
+ * For an external link this is the URL; for an internal slide jump it is the
580
+ * resolved internal part name (e.g. "../slides/slide3.xml"). Undefined for runs
581
+ * without a hyperlink. ECMA-376 §21.1.2.3.5 (CT_Hyperlink).
304
582
  */
305
- trendLines?: ChartTrendline[] | null;
583
+ hyperlink?: string;
306
584
  /**
307
- * `<c:ser><c:spPr><a:ln><a:noFill/>` (ECMA-376 §21.2.2.198 CT_ShapeProperties
308
- * DrawingML §20.1.2.2.24 CT_LineProperties). true when the series connecting
309
- * line is explicitly turned OFF. For a scatter/line series this OVERRIDES the
310
- * chart-group `<c:scatterStyle>` (§21.2.2.42) / line default — Excel and
311
- * PowerPoint draw markers only (no connecting line) even when the group style
312
- * is `lineMarker`. null/undefined = no explicit line-off, so the group default
313
- * governs (byte-stable for series that carry a paintable line).
585
+ * Raw `<a:hlinkClick @action>` string (e.g. "ppaction://hlinksldjump") when
586
+ * present its presence marks {@link hyperlink} as an INTERNAL PowerPoint
587
+ * action (slide jump / first / last …) rather than an external URL. Undefined
588
+ * when the hlinkClick has no @action. ECMA-376 §21.1.2.3.5. (IX1)
314
589
  */
315
- lineHidden?: boolean | null;
316
- }
317
- /**
318
- * `<c:ser><c:trendline>` (ECMA-376 §21.2.2.211). A regression/smoothing curve
319
- * fitted to the series' data points.
320
- */
321
- interface ChartTrendline {
590
+ hyperlinkAction?: string;
322
591
  /**
323
- * `<c:trendlineType val>` (§21.2.2.213, `ST_TrendlineType` §21.2.3.50):
324
- * "linear" | "exp" | "log" | "power" | "poly" | "movingAvg". The renderer
325
- * currently draws "linear" (least squares) and "movingAvg"; other types parse
326
- * but are not yet plotted (tracked as a follow-up).
592
+ * Run-level drop shadow on glyphs (`<a:rPr><a:effectLst><a:outerShdw>`),
593
+ * ECMA-376 §20.1.8.45. Independent of the shape-level shadow on `spPr`.
594
+ * Absent means no run-level shadow.
327
595
  */
328
- trendlineType: string;
329
- /** `<c:order val>` — polynomial order (`poly`, default 2). */
330
- order?: number | null;
331
- /** `<c:period val>` — moving-average window (`movingAvg`, default 2). */
332
- period?: number | null;
333
- /** `<c:forward val>` — units to extend the line past the last point. */
334
- forward?: number | null;
335
- /** `<c:backward val>` — units to extend the line before the first point. */
336
- backward?: number | null;
337
- /** `<c:intercept val>` — forced y-intercept (linear/exp). null = free fit. */
338
- intercept?: number | null;
339
- /** `<c:dispRSqr val="1">` — show the R² value (label; not yet rendered). */
340
- dispRSqr?: boolean | null;
341
- /** `<c:dispEq val="1">` — show the fit equation (label; not yet rendered). */
342
- dispEq?: boolean | null;
343
- /** `<c:spPr><a:ln><a:solidFill>` trendline color (hex without '#'). null =
344
- * inherit the series color. */
345
- lineColor?: string | null;
346
- /** `<c:spPr><a:ln w>` trendline width in EMU. */
347
- lineWidthEmu?: number | null;
348
- }
349
- interface ChartDataPointOverride {
350
- idx: number;
351
- /** Resolved fill hex (no `#`). */
352
- color?: string;
353
- markerSymbol?: string;
354
- markerSize?: number;
355
- markerFill?: string;
356
- markerLine?: string;
596
+ shadow?: Shadow;
357
597
  /**
358
- * `<c:dPt><c:explosion val>` (ECMA-376 §21.2.2.61) — the amount this
598
+ * Run-level glyph outline (`<a:rPr><a:ln w="..">`), ECMA-376 §20.1.2.2.24
599
+ * (CT_TextOutlineEffect). Renderer strokes each glyph with the given
600
+ * width / colour in addition to the normal fill. Absent means glyphs are
601
+ * fill-only.
602
+ */
603
+ outline?: TextOutline;
604
+ /**
605
+ * Run-level text highlight / marker colour (`<a:rPr><a:highlight>`),
606
+ * ECMA-376 §21.1.2.3.4. In DrawingML this is a full CT_Color (any
607
+ * srgbClr / schemeClr / sysClr / prstClr + transforms), unlike
608
+ * WordprocessingML's fixed 16-name highlight enum — so the parser already
609
+ * resolves it through the theme/clrMap. The value is a hex string without
610
+ * `#` (6-char opaque, or 8-char RRGGBBAA when an alpha transform applies);
611
+ * the renderer paints a background rectangle behind the run's glyphs.
612
+ * Absent means no highlight.
613
+ */
614
+ highlight?: string;
615
+ }
616
+ /** Run-level glyph outline. Width is in OOXML EMU (12700 EMU = 1 pt). */
617
+ interface TextOutline {
618
+ width: number;
619
+ /** Hex without '#'. Absent = inherit from text fill colour. */
620
+ color?: string;
621
+ }
622
+ interface LineBreak {
623
+ type: 'break';
624
+ }
625
+ interface RenderOptions {
626
+ width?: number;
627
+ defaultTextColor?: string | null;
628
+ dpr?: number;
629
+ majorFont?: string | null;
630
+ minorFont?: string | null;
631
+ /** Theme hyperlink colour (hex 6 chars). Used to colour hyperlink runs without an explicit colour. */
632
+ hlinkColor?: string | null;
633
+ /**
634
+ * Lazily resolve an archive-internal asset (by zip path) to a Blob. The
635
+ * renderer uses this to fetch posters and other large embedded assets on
636
+ * demand, keeping the parse output free of inlined base64.
637
+ */
638
+ fetchMedia?: (path: string) => Promise<Blob>;
639
+ /**
640
+ * Lazily resolve an embedded image (by zip path + MIME) to a Blob. Twin of
641
+ * {@link RenderOptions.fetchMedia} for pictures and blip fills: the renderer
642
+ * fetches raster/SVG bytes on demand and decodes them (`createImageBitmap` /
643
+ * path-keyed `<img>`), so the parse output carries only paths, never base64.
644
+ */
645
+ fetchImage?: (path: string, mimeType: string) => Promise<Blob>;
646
+ /**
647
+ * When true, renderMedia draws only the poster frame — play/pause badges
648
+ * and progress bars are left to the caller. Set by the pptx presentSlide
649
+ * API so its interactive handle can own all control chrome without
650
+ * the static renderer drawing a duplicate play badge.
651
+ */
652
+ skipMediaControls?: boolean;
653
+ }
654
+ //#endregion
655
+ //#region packages/core/src/types/chart.d.ts
656
+ interface ChartSeries {
657
+ name: string;
658
+ /** Hex without '#'. null = fall back to palette. */
659
+ color: string | null;
660
+ /** Numeric values; null = missing data point. */
661
+ values: (number | null)[];
662
+ /**
663
+ * Per-data-point colors (pie / doughnut). Hex without '#'. null inside the
664
+ * array = use palette for that slice. Omit entirely for non-pie series.
665
+ */
666
+ dataPointColors?: (string | null)[] | null;
667
+ /**
668
+ * Per-data-point data-label text colors. Used by chartEx (`<cx:dataLabel idx>`)
669
+ * to override label colour per bar — sample-2's waterfall paints negative
670
+ * △ values in red while positive values stay black. Null inside the array =
671
+ * fall back to the chart-level `dataLabelFontColor`.
672
+ */
673
+ dataLabelColors?: (string | null)[] | null;
674
+ /**
675
+ * Series-level data-label text colour (`<c:ser><c:dLbls><c:txPr>…solidFill`,
676
+ * ECMA-376 §21.2.2.216). Hex without '#'. Stacked-bar charts colour each
677
+ * segment's label independently (e.g. white on the dark segment, black on
678
+ * the light one), which a single chart-level `dataLabelFontColor` can't
679
+ * express. Takes precedence over `dataLabelFontColor`; null = no override.
680
+ */
681
+ labelColor?: string | null;
682
+ /**
683
+ * Mixed chart: per-series chart type override. Currently only "line" (XLSX
684
+ * and PPTX combo charts) is honoured; other values are treated as the
685
+ * chart's primary type.
686
+ */
687
+ seriesType?: string | null;
688
+ /**
689
+ * Combo chart: this series is plotted against the SECONDARY value axis
690
+ * (`ChartModel.secondaryValAxis`) — the `<c:valAx>` with `axPos="r"` /
691
+ * `<c:crosses val="max">`. When false/absent the series uses the primary
692
+ * (left) value-axis scale. PowerPoint's "Revenue vs. gross margin" combo
693
+ * (sample-14 slide-8) puts the margin line on a 0–100% secondary axis.
694
+ */
695
+ useSecondaryAxis?: boolean | null;
696
+ /**
697
+ * Scatter-only X values (as strings). When null the series uses
698
+ * `ChartModel.categories` as X.
699
+ */
700
+ categories?: string[] | null;
701
+ /**
702
+ * Resolved marker visibility for line/scatter series. ECMA-376 §21.2.2.32
703
+ * `<c:marker><c:symbol>` defaults to "none" for line charts unless the
704
+ * chart-level `<c:marker val="1"/>` or a per-series symbol opts in. When
705
+ * undefined/null the renderer uses its own default (visible) so callers
706
+ * that don't parse markers (e.g. pptx today) keep their existing behavior.
707
+ */
708
+ showMarker?: boolean | null;
709
+ /**
710
+ * Excel number-format code for this series' values (ECMA-376 §21.2.2.37,
711
+ * `<c:val>/<c:numRef>/<c:formatCode>`). Used to format data labels when the
712
+ * chart-level `<c:dLbls><c:numFmt>` is not set. null = no series-level code.
713
+ */
714
+ valFormatCode?: string | null;
715
+ /**
716
+ * `<c:marker><c:symbol val>` (ECMA-376 §21.2.2.32) — point marker shape.
717
+ * One of "circle"|"square"|"diamond"|"triangle"|"x"|"plus"|"star"|
718
+ * "dot"|"dash"|"picture"|"none". null = renderer default (circle when
719
+ * showMarker is true).
720
+ */
721
+ markerSymbol?: string | null;
722
+ /**
723
+ * `<c:marker><c:size val>` (ECMA-376 §21.2.2.34) — marker side length in
724
+ * points. null = renderer default (~5 pt).
725
+ */
726
+ markerSize?: number | null;
727
+ /** `<c:marker><c:spPr><a:solidFill>` resolved hex (no `#`). */
728
+ markerFill?: string | null;
729
+ /** `<c:marker><c:spPr><a:ln><a:solidFill>` resolved hex (no `#`). */
730
+ markerLine?: string | null;
731
+ /**
732
+ * Per-data-point overrides (ECMA-376 §21.2.2.39 `<c:dPt>`). Keyed by point
733
+ * index. Any unset field falls back to the series-level value.
734
+ */
735
+ dataPointOverrides?: ChartDataPointOverride[] | null;
736
+ /**
737
+ * Per-data-point custom labels (ECMA-376 §21.2.2.45 `<c:dLbl idx>`).
738
+ * `text` is the resolved plain string — `<a:fld type="CELLRANGE">`
739
+ * placeholders are already substituted at parse time. An empty string
740
+ * means the point's label was deleted with `<c:delete val="1"/>` and
741
+ * the renderer should skip it.
742
+ */
743
+ dataLabelOverrides?: ChartDataLabelOverride[] | null;
744
+ /**
745
+ * Series-level `<c:dLbls>` block (showVal / showSerName / position).
746
+ * Applied to every point lacking its own `<c:dLbl>` override.
747
+ */
748
+ seriesDataLabels?: ChartSeriesDataLabels | null;
749
+ /**
750
+ * `<c:errBars>` per-series error bars (ECMA-376 §21.2.2.20). Up to two
751
+ * (one per direction). Plus / minus deltas are absolute per-point values
752
+ * regardless of `errValType`.
753
+ */
754
+ errBars?: ChartErrBars[] | null;
755
+ /**
756
+ * `<c:bubbleSize>` per-point sizes for bubble charts (ECMA-376 §21.2.2.4).
757
+ * Drives marker radius — renderer treats the values as areas (radius
758
+ * scales by sqrt) so visual area is proportional to value, matching
759
+ * Excel. null / empty array = uniform marker size. Ignored for non-bubble
760
+ * series.
761
+ */
762
+ bubbleSizes?: (number | null)[] | null;
763
+ /**
764
+ * `<c:ser><c:smooth val>` (ECMA-376 §21.2.2.194) — line/area series flag
765
+ * requesting a smoothed (spline) curve through the points instead of straight
766
+ * segments. Only consulted for the line and area families (scatter carries its
767
+ * smoothing in `ChartModel.scatterStyle`). null/undefined/false = straight
768
+ * polyline (the default; byte-stable for series that never set it).
769
+ */
770
+ smooth?: boolean | null;
771
+ /**
772
+ * `<c:ser><c:trendline>` per-series trendlines (ECMA-376 §21.2.2.211,
773
+ * `CT_Trendline`). A series can carry several (e.g. a linear fit + a moving
774
+ * average). null/undefined/empty = no trendline (the default; byte-stable for
775
+ * series that never declare one).
776
+ */
777
+ trendLines?: ChartTrendline[] | null;
778
+ /**
779
+ * `<c:ser><c:spPr><a:ln><a:noFill/>` (ECMA-376 §21.2.2.198 CT_ShapeProperties
780
+ * → DrawingML §20.1.2.2.24 CT_LineProperties). true when the series connecting
781
+ * line is explicitly turned OFF. For a scatter/line series this OVERRIDES the
782
+ * chart-group `<c:scatterStyle>` (§21.2.2.42) / line default — Excel and
783
+ * PowerPoint draw markers only (no connecting line) even when the group style
784
+ * is `lineMarker`. null/undefined = no explicit line-off, so the group default
785
+ * governs (byte-stable for series that carry a paintable line).
786
+ */
787
+ lineHidden?: boolean | null;
788
+ }
789
+ /**
790
+ * `<c:ser><c:trendline>` (ECMA-376 §21.2.2.211). A regression/smoothing curve
791
+ * fitted to the series' data points.
792
+ */
793
+ interface ChartTrendline {
794
+ /**
795
+ * `<c:trendlineType val>` (§21.2.2.213, `ST_TrendlineType` §21.2.3.50):
796
+ * "linear" | "exp" | "log" | "power" | "poly" | "movingAvg". The renderer
797
+ * currently draws "linear" (least squares) and "movingAvg"; other types parse
798
+ * but are not yet plotted (tracked as a follow-up).
799
+ */
800
+ trendlineType: string;
801
+ /** `<c:order val>` — polynomial order (`poly`, default 2). */
802
+ order?: number | null;
803
+ /** `<c:period val>` — moving-average window (`movingAvg`, default 2). */
804
+ period?: number | null;
805
+ /** `<c:forward val>` — units to extend the line past the last point. */
806
+ forward?: number | null;
807
+ /** `<c:backward val>` — units to extend the line before the first point. */
808
+ backward?: number | null;
809
+ /** `<c:intercept val>` — forced y-intercept (linear/exp). null = free fit. */
810
+ intercept?: number | null;
811
+ /** `<c:dispRSqr val="1">` — show the R² value (label; not yet rendered). */
812
+ dispRSqr?: boolean | null;
813
+ /** `<c:dispEq val="1">` — show the fit equation (label; not yet rendered). */
814
+ dispEq?: boolean | null;
815
+ /** `<c:spPr><a:ln><a:solidFill>` trendline color (hex without '#'). null =
816
+ * inherit the series color. */
817
+ lineColor?: string | null;
818
+ /** `<c:spPr><a:ln w>` trendline width in EMU. */
819
+ lineWidthEmu?: number | null;
820
+ }
821
+ interface ChartDataPointOverride {
822
+ idx: number;
823
+ /** Resolved fill hex (no `#`). */
824
+ color?: string;
825
+ markerSymbol?: string;
826
+ markerSize?: number;
827
+ markerFill?: string;
828
+ markerLine?: string;
829
+ /**
830
+ * `<c:dPt><c:explosion val>` (ECMA-376 §21.2.2.61) — the amount this
359
831
  * pie/doughnut slice is moved out from the center. The schema type is
360
832
  * `CT_UnsignedInt` (unbounded `xsd:unsignedInt`); the spec text only says
361
833
  * "the amount the data point shall be moved from the center of the pie"
@@ -1107,686 +1579,214 @@ type OoxmlResourceLimit = number | null;
1107
1579
  /** Admission limits for the inflated contents of one OOXML package session. */
1108
1580
  interface OoxmlResourceLimits {
1109
1581
  /**
1110
- * Maximum permitted inflated size for any one archive entry, including
1111
- * media. Enforced against both the ZIP declaration and actual output.
1112
- */
1113
- maxArchiveEntryBytes?: OoxmlResourceLimit;
1114
- /** Maximum actual inflated bytes across distinct entries in the session. */
1115
- maxTotalInflatedBytes?: OoxmlResourceLimit;
1116
- }
1117
- /**
1118
- * Common load-time options shared by the docx / pptx / xlsx
1119
- * `Document.load` / `Presentation.load` / `Workbook.load` factories and their
1120
- * viewer wrappers.
1121
- *
1122
- * This is the single source of truth — each package re-exports this exact type
1123
- * as its `LoadOptions` so application code can pass one options object to any
1124
- * of the three.
1125
- */
1126
- interface LoadOptions$1 {
1127
- /**
1128
- * Opt in to loading webfont substitutes from Google Fonts
1129
- * (`fonts.googleapis.com`). Default `false` — the canvas falls back to
1130
- * locally available fonts.
1131
- *
1132
- * When enabled, end-user IP / User-Agent is sent to Google, which may
1133
- * have privacy / GDPR implications for your application. To avoid the
1134
- * third-party request, host the substitutes yourself and reference them
1135
- * via `@font-face` in your application CSS.
1136
- */
1137
- useGoogleFonts?: boolean;
1138
- /**
1139
- * Password for an encrypted OOXML file ([MS-OFFCRYPTO] Agile Encryption).
1140
- *
1141
- * Password-protected Office documents are CFB (OLE2) containers, not ZIPs.
1142
- * When this is set and the input is Agile-encrypted, `load()` decrypts it on
1143
- * the main thread (via WebCrypto) and parses the recovered plaintext ZIP.
1144
- *
1145
- * Errors (thrown as {@link import('../errors/ooxml-error').OoxmlError}):
1146
- * - no `password` on an encrypted file → code `'encrypted'`
1147
- * - wrong `password` → code `'invalid-password'`
1148
- * - a non-Agile scheme (Standard / Extensible / legacy) → code
1149
- * `'unsupported-encryption'`
1150
- *
1151
- * Note: Agile Encryption uses a high password-hash spin count (commonly
1152
- * 100,000), so decryption of a protected file adds roughly a second of
1153
- * WebCrypto work before parsing begins.
1154
- *
1155
- * Security notes:
1156
- * - This value is held as an ordinary JS `string` in memory for the
1157
- * duration of key derivation. The library does not zero it, and does
1158
- * not wrap it in a `SecureString`-equivalent — it becomes eligible for
1159
- * garbage collection like any other string once nothing references it,
1160
- * but no explicit wipe is performed. It is never logged or included in
1161
- * thrown errors.
1162
- * - Decryption recovers the plaintext but does not verify the file's HMAC
1163
- * data-integrity tag ([MS-OFFCRYPTO] §2.3.4.14), so ciphertext tampering
1164
- * is not detected — see "Security & Privacy" in the README.
1165
- */
1166
- password?: string;
1167
- /**
1168
- * Override the URL the parser worker fetches the WebAssembly module from.
1169
- *
1170
- * By default each format resolves the `.wasm` asset that ships next to its
1171
- * bundle (relative to the module URL), so no configuration is needed. Set
1172
- * this to serve the parser WASM from a CDN or a self-hosted path instead — a
1173
- * relative value is resolved against the current document URL. The same
1174
- * dependency-injection contract across docx / pptx / xlsx.
1175
- *
1176
- * The referenced file must be the matching format's `*_parser_bg.wasm`
1177
- * artifact (the one wasm-bindgen emitted for that parser); pointing it at a
1178
- * mismatched or missing file makes `load()` reject when the worker
1179
- * instantiates it.
1180
- */
1181
- wasmUrl?: string | URL;
1182
- /**
1183
- * @deprecated Use `resourceLimits.maxArchiveEntryBytes`. Scheduled for
1184
- * removal in a future breaking release.
1185
- *
1186
- * Existing positive safe-integer values remain an all-entry inflated-byte
1187
- * limit. Zero, negative, and NaN values retain their historical fallback
1188
- * behavior; other invalid positive values reject during `load()`.
1189
- */
1190
- maxZipEntryBytes?: number;
1191
- /**
1192
- * Inflated archive admission limits for one document session. Omitted fields
1193
- * use the library defaults. A positive safe integer overrides a default;
1194
- * `null` disables that configurable limit only. Limits are admission policy,
1195
- * not guarantees of exact browser-process memory use.
1196
- */
1197
- resourceLimits?: OoxmlResourceLimits;
1198
- /**
1199
- * Emit one content-free resource-usage card after load succeeds or fails.
1200
- * Includes observed archive counters and configured limits, but never source
1201
- * URLs, part names, document text, passwords, or error messages.
1202
- */
1203
- debug?: boolean;
1204
- /**
1205
- * Receive the initial content-free, machine-readable report that powers the
1206
- * debug card, without enabling console output. After resource options validate,
1207
- * the callback runs once when the current load settles, including failed loads
1208
- * for which no renderer instance is returned. The callback is not awaited;
1209
- * synchronous exceptions and rejected promises are ignored and never change
1210
- * load results.
1211
- *
1212
- * A browser report covers the underlying document/workbook/presentation
1213
- * factory. It does not wait for a Viewer's first canvas paint; that paint and
1214
- * later lazy worksheet, slide, image, or media access may increase counters or
1215
- * surface a separate render error. Successfully opened packages include the
1216
- * declared package total and source byte size in the report. On a successful
1217
- * load, call `getResourceMetrics()` on the returned engine or Viewer for a fresh
1218
- * snapshot that includes subsequently observed lazy package work.
1219
- */
1220
- onResourceMetrics?: (metrics: OoxmlResourceMetrics) => void;
1221
- /**
1222
- * Reject the parse request if the parser worker does not answer within this
1223
- * many milliseconds. Opt-in safety net for a wedged or crashed worker that
1224
- * would otherwise leave `load()` pending forever. **Default: unlimited** —
1225
- * parsing a large document with heavy embedded media can legitimately take
1226
- * tens of seconds, so no timeout is imposed unless you set one. A worker that
1227
- * throws or fails to load already rejects immediately regardless of this
1228
- * value; this bound only covers the "silent, never-responds" case.
1229
- */
1230
- workerTimeoutMs?: number;
1231
- /**
1232
- * Opt-in OMML equation engine (MathJax + STIX Two Math, ~3 MB). Inject it
1233
- * **once** here and every render of this document / presentation / workbook
1234
- * uses it — the same dependency-injection contract across all three formats
1235
- * and their viewers. Import it from the separate `@silurus/ooxml/math` entry
1236
- * (`import { math } from '@silurus/ooxml/math'`). Omit it and equations are
1237
- * skipped and the engine tree-shakes away entirely (no network, no bundle
1238
- * cost).
1239
- */
1240
- math?: MathRenderer;
1241
- }
1242
- //#endregion
1243
- //#region packages/core/src/image/pixel-budget.d.ts
1244
- type OoxmlDecodedImageLimitMetric = 'image-pixels' | 'active-decoded-bytes';
1245
- /** Catchable hard-quota crossing for decoded image surfaces. */
1246
- declare class OoxmlDecodedImageLimitError extends RangeError {
1247
- readonly metric: OoxmlDecodedImageLimitMetric;
1248
- readonly limit: number;
1249
- readonly observed: number;
1250
- readonly code: "ooxml-decoded-image-limit";
1251
- constructor(metric: OoxmlDecodedImageLimitMetric, limit: number, observed: number);
1252
- }
1253
- declare function isOoxmlDecodedImageLimitError(error: unknown): error is OoxmlDecodedImageLimitError;
1254
- //#endregion
1255
- //#region packages/core/src/interaction/hyperlink.d.ts
1256
- /**
1257
- * Shared hyperlink model + URL sanitisation for docx / pptx / xlsx (IX1).
1258
- *
1259
- * All three formats carry the same two ECMA-376 concepts:
1260
- * - an **external** hyperlink — an absolute URL resolved from a relationship
1261
- * part target (`document.xml.rels` for docx §17.16.22, the slide rels for
1262
- * pptx §21.1.2.3.5, the worksheet rels for xlsx §18.3.1.47), with
1263
- * `TargetMode="External"`.
1264
- * - an **internal** hyperlink — a jump within the document itself:
1265
- * docx `w:anchor` -> a `<w:bookmarkStart w:name>` (§17.16.23), pptx
1266
- * `action="ppaction://hlinksldjump"` -> a slide, xlsx `location` -> a defined
1267
- * name or a `Sheet!A1` cell reference.
1268
- *
1269
- * The parsers (Rust, one per format) do the format-specific rels lookup and hand
1270
- * each run / shape / cell a {@link HyperlinkTarget}. Everything downstream — the
1271
- * text-layer overlay, the viewer default click behaviour, and any integrator
1272
- * callback — is format-agnostic and consumes this one shape. Keeping the type +
1273
- * the pure `sanitizeHyperlinkUrl` predicate here (not duplicated per package)
1274
- * follows the cross-package unification principle: a scheme-allowlist bug fixed
1275
- * once is fixed everywhere.
1276
- */
1277
- /**
1278
- * A resolved hyperlink attached to a run, shape, or cell.
1279
- *
1280
- * - `external` — `url` is the raw target as authored in the file. It is NOT
1281
- * guaranteed safe; run it through {@link sanitizeHyperlinkUrl} before
1282
- * navigating. It is kept verbatim here so an integrator can apply its own
1283
- * policy (e.g. allow `file:` on a trusted intranet viewer).
1284
- * - `internal` — `ref` is the in-document destination, verbatim from the file:
1285
- * docx: the bookmark name (`w:anchor`).
1286
- * pptx: the internal action (e.g. `ppaction://hlinksldjump`), with the
1287
- * resolved 0-based `slideIndex` when the rels target names a slide.
1288
- * xlsx: the `location` string (a defined name or `Sheet1!A1`).
1289
- */
1290
- type HyperlinkTarget = {
1291
- kind: 'external';
1292
- url: string;
1293
- } | {
1294
- kind: 'internal';
1295
- ref: string;
1296
- slideIndex?: number;
1297
- };
1298
- /**
1299
- * The default action a viewer takes for an **external** hyperlink click when
1300
- * the integrator supplies no `onHyperlinkClick` handler: sanitise the URL and,
1301
- * if allowed, open it in a new tab with `noopener,noreferrer` so the opened page
1302
- * gets no `window.opener` handle back into this document. A blocked scheme is a
1303
- * silent no-op (returns `false`) — the click does nothing rather than navigate
1304
- * somewhere dangerous.
1305
- *
1306
- * Internal targets are intentionally NOT handled here: the in-document jump
1307
- * (page / slide / cell) is format-specific and lives in each viewer.
1308
- *
1309
- * Split out (not inlined in three viewers) so the "open in new tab, drop opener,
1310
- * refuse unsafe schemes" policy is defined once. `win` is injected for tests;
1311
- * defaults to the ambient `window`.
1312
- *
1313
- * @returns `true` if navigation was initiated, `false` if the URL was blocked.
1314
- */
1315
- declare function openExternalHyperlink(url: string, allowed?: readonly string[], win?: Pick<Window, 'open'> | undefined): boolean;
1316
- //#endregion
1317
- //#region dist/.types-work/common-Bgczc_Eb.d.ts
1318
- //#region packages/core/src/types/common.d.ts
1319
- type PathCmd = {
1320
- cmd: 'moveTo';
1321
- x: number;
1322
- y: number;
1323
- } | {
1324
- cmd: 'lineTo';
1325
- x: number;
1326
- y: number;
1327
- } | {
1328
- cmd: 'cubicBezTo';
1329
- x1: number;
1330
- y1: number;
1331
- x2: number;
1332
- y2: number;
1333
- x: number;
1334
- y: number;
1335
- } | {
1336
- cmd: 'arcTo';
1337
- wr: number;
1338
- hr: number;
1339
- stAng: number;
1340
- swAng: number;
1341
- } | {
1342
- cmd: 'close';
1343
- };
1344
- type Fill = SolidFill | NoFill | GradientFill | PatternFill | ImageFill;
1345
- interface SolidFill {
1346
- fillType: 'solid';
1347
- color: string;
1348
- }
1349
- interface NoFill {
1350
- fillType: 'none';
1351
- }
1352
- interface GradientStop {
1353
- position: number;
1354
- color: string;
1355
- }
1356
- interface GradientFill {
1357
- fillType: 'gradient';
1358
- stops: GradientStop[];
1359
- /** degrees: 0 = left→right, 90 = top→bottom */
1360
- angle: number;
1361
- /** 'linear' | 'radial' */
1362
- gradType: string;
1363
- }
1364
- /**
1365
- * Preset pattern fill — ECMA-376 §20.1.8.40 (CT_PatternFillProperties)
1366
- * with `preset` drawn from §20.1.10.59 (ST_PresetPatternVal).
1367
- */
1368
- interface PatternFill {
1369
- fillType: 'pattern';
1370
- /** Foreground hex colour — used for the "1" pixels of the preset bitmap. */
1371
- fg: string;
1372
- /** Background hex colour — used for the "0" pixels. */
1373
- bg: string;
1374
- /** Preset name, e.g. "pct25", "horz", "diagCross", "lgGrid". */
1375
- preset: string;
1376
- }
1377
- /**
1378
- * ECMA-376 §20.1.8.30 (CT_RelativeRect) — the destination rectangle a stretched
1379
- * blip is mapped into, as edge insets relative to the fill region. Values are
1380
- * fractions (ST_Percentage / 100000); **negative values let the image bleed
1381
- * past the box (overscan)**. Absent edges default to 0.
1382
- */
1383
- interface FillRect {
1384
- l?: number;
1385
- t?: number;
1386
- r?: number;
1387
- b?: number;
1388
- }
1389
- /**
1390
- * ECMA-376 §20.1.8.58 (CT_TileInfoProperties) — tiled blip-fill placement.
1391
- * The blip repeats at its native size (scaled by sx/sy) across the fill box.
1392
- * Mutually exclusive with {@link ImageFill.fillRect} (the `stretch` mode).
1393
- */
1394
- interface TileInfo {
1395
- /** Horizontal offset of the first tile, in EMU (`tx`). Default 0. */
1396
- tx: number;
1397
- /** Vertical offset of the first tile, in EMU (`ty`). Default 0. */
1398
- ty: number;
1399
- /** Horizontal tile scale as a fraction (`sx` / 100000). Default 1.0. */
1400
- sx: number;
1401
- /** Vertical tile scale as a fraction (`sy` / 100000). Default 1.0. */
1402
- sy: number;
1403
- /** Mirror mode: `'none' | 'x' | 'y' | 'xy'` (`flip`). Default `'none'`. */
1404
- flip: string;
1405
- /**
1406
- * Anchor corner the tile grid registers against:
1407
- * `tl|t|tr|l|ctr|r|bl|b|br` (`algn`). Default `'tl'`.
1408
- */
1409
- algn: string;
1410
- }
1411
- /**
1412
- * Image fill — ECMA-376 §20.1.8.14 (CT_BlipFillProperties). The embedded blip
1413
- * is carried as a zip path + MIME; the renderer fetches the bytes on demand via
1414
- * {@link RenderOptions.fetchImage} (no base64 inlined at parse time). Both
1415
- * fill-modes are modelled and mutually exclusive: `stretch` (§20.1.8.56) carries
1416
- * {@link ImageFill.fillRect}; `tile` (§20.1.8.58) carries {@link ImageFill.tile}.
1417
- */
1418
- interface ImageFill {
1419
- fillType: 'image';
1420
- /**
1421
- * Embedded zip path of the blip (e.g. "word/media/image1.png"), for the lazy
1422
- * byte-on-demand pipeline. The renderer fetches the bytes via a path-keyed
1423
- * loader ({@link RenderOptions.fetchImage}) instead of inlining base64.
1424
- */
1425
- imagePath: string;
1426
- /** MIME type of the blip at {@link ImageFill.imagePath} (e.g. `image/png`). */
1427
- mimeType: string;
1428
- /**
1429
- * `<a:stretch><a:fillRect>` insets. Absent → fills the whole box (or the
1430
- * fill is tiled — see {@link ImageFill.tile}).
1431
- */
1432
- fillRect?: FillRect;
1433
- /**
1434
- * `<a:tile>` descriptor. Present only when the blipFill is tiled; mutually
1435
- * exclusive with {@link ImageFill.fillRect}.
1436
- */
1437
- tile?: TileInfo;
1438
- /** `a:blip > a:alphaModFix@amt` as a fraction (0.0–1.0). Absent = opaque. */
1439
- alpha?: number;
1440
- /**
1441
- * ECMA-376 §20.1.8.23 `<a:duotone>` recolour, resolved to its two endpoint
1442
- * colours (through the slide theme). Absent ⇒ no duotone. When present the
1443
- * renderer maps the blip's luminance ramp between the two colours (core
1444
- * `applyDuotone`) — the same recolour a `<p:pic>` duotone applies, wired onto
1445
- * the picture-FILL path (§20.1.8.14) by issue #889.
1446
- */
1447
- duotone?: Duotone;
1448
- }
1449
- interface Shadow {
1450
- color: string;
1451
- alpha: number;
1452
- blur: number;
1453
- dist: number;
1454
- /** degrees clockwise from East */
1455
- dir: number;
1456
- }
1457
- /** ECMA-376 §20.1.8.17 (CT_GlowEffect) — coloured halo with blur radius. */
1458
- interface Glow {
1459
- color: string;
1460
- alpha: number;
1461
- /** Blur radius in EMU. */
1462
- radius: number;
1463
- }
1464
- /** ECMA-376 §20.1.8.31 (CT_SoftEdgesEffect) — feather radius in EMU. */
1465
- interface SoftEdge {
1466
- radius: number;
1467
- }
1468
- /** ECMA-376 §20.1.8.27 (CT_ReflectionEffect) — mirrored copy below the
1469
- * shape with a linear alpha gradient. Carries the spec attributes whose
1470
- * defaults the renderer needs to interpret correctly. */
1471
- interface Reflection {
1472
- blur: number;
1473
- dist: number;
1474
- /** Direction in degrees, clockwise from East. */
1475
- dir: number;
1476
- /** Start alpha (0–1). Default 1.0. */
1477
- stA: number;
1478
- /** Start position along the gradient (0–1). Default 0. */
1479
- stPos: number;
1480
- /** End alpha. Default 0. */
1481
- endA: number;
1482
- /** End position. Default 1.0. */
1483
- endPos: number;
1484
- /** Horizontal scale (1.0 = same width). */
1485
- sx: number;
1486
- /** Vertical scale (-1.0 = full mirror). */
1487
- sy: number;
1488
- }
1489
- interface ArrowEnd {
1490
- /** OOXML type: "none" | "triangle" | "stealth" | "diamond" | "oval" | "arrow" */
1491
- type: string;
1492
- /** Width multiplier: "sm" | "med" | "lg" */
1493
- w: string;
1494
- /** Length multiplier: "sm" | "med" | "lg" */
1495
- len: string;
1496
- }
1497
- interface Stroke {
1498
- color: string;
1499
- /** Width in EMU */
1500
- width: number;
1501
- /** Authored non-solid DrawingML line paint. Solid lines use `color`. */
1502
- fill?: Exclude<Fill, {
1503
- fillType: 'image';
1504
- } | {
1505
- fillType: 'none';
1506
- }>;
1507
- /** OOXML prstDash value: "dash", "dot", "dashDot", "lgDash", "lgDashDot", etc. */
1508
- dashStyle?: string;
1509
- /** Canvas line cap normalized from DrawingML/VML (`flat` → `butt`). */
1510
- lineCap?: CanvasLineCap;
1511
- /** Arrow head at the start of the line */
1512
- headEnd?: ArrowEnd;
1513
- /** Arrow head at the end of the line */
1514
- tailEnd?: ArrowEnd;
1515
- /**
1516
- * ECMA-376 §20.1.8.42 ST_CompoundLine. "sng" (default) | "dbl" |
1517
- * "thinThick" | "thickThin" | "tri". Absent means single line.
1518
- */
1519
- cmpd?: string;
1520
- }
1521
- interface TextBody$1 {
1522
- /** Vertical anchor: "t" | "ctr" | "b" */
1523
- verticalAnchor: string;
1524
- paragraphs: Paragraph$1[];
1525
- /** Default pt size from lstStyle (overrides renderer default when present) */
1526
- defaultFontSize: number | null;
1527
- /** Inherited bold from layout/master defRPr (null = not set, use false as final default) */
1528
- defaultBold: boolean | null;
1529
- /** Inherited italic from layout/master defRPr (null = not set, use false as final default) */
1530
- defaultItalic: boolean | null;
1531
- /** Text insets in EMU (defaults: lIns=rIns=91440, tIns=bIns=45720) */
1532
- lIns: number;
1533
- rIns: number;
1534
- tIns: number;
1535
- bIns: number;
1536
- /** "square" = wrap, "none" = no wrap */
1537
- wrap: string;
1538
- /** Text direction: "horz" | "vert" | "vert270" | "eaVert" etc. */
1539
- vert: string;
1540
- /** Auto-fit: "sp" = shape grows to fit text, "norm" = font shrinks, "none" = no fit */
1541
- autoFit: string;
1542
- /**
1543
- * `<a:normAutofit fontScale>` (ECMA-376 §21.1.2.1.3) — PowerPoint's stored,
1544
- * pre-computed font-shrink ratio for `autoFit === "norm"`, as a fraction
1545
- * (e.g. 0.625 for `fontScale="62500"`). Null/absent when PowerPoint stored no
1546
- * scale; the renderer then re-derives one. Applying the stored value matches
1547
- * PowerPoint exactly instead of guessing from our own text metrics.
1548
- */
1549
- fontScale?: number | null;
1550
- /** `<a:normAutofit lnSpcReduction>` — stored line-spacing reduction fraction
1551
- * (e.g. 0.20 for `lnSpcReduction="20000"`). Null/absent when not stored. */
1552
- lnSpcReduction?: number | null;
1553
- /**
1554
- * `<a:bodyPr numCol>` (ECMA-376 §20.1.10.34) — number of text columns inside
1555
- * the shape. Defaults to 1; values > 1 cause the renderer to flow paragraphs
1556
- * across N columns left-to-right, top-to-bottom.
1557
- */
1558
- numCol?: number;
1559
- /** `<a:bodyPr spcCol>` — gap between columns in EMU. Default 0. */
1560
- spcCol?: number;
1561
- }
1562
- type SpaceLine = {
1563
- type: 'pct';
1564
- val: number;
1565
- } | {
1566
- type: 'pts';
1567
- val: number;
1568
- };
1569
- /**
1570
- * A paragraph's bullet marker. For `char`, the marker size is EITHER `sizePct`
1571
- * (a percentage of the run size — ECMA-376 §21.1.2.4.9 `<a:buSzPct>`) OR `sizePts`
1572
- * (an absolute size in points — §21.1.2.4.10 `<a:buSzPts>`), never both: they are
1573
- * the one `EG_TextBulletSize` xsd:choice. `sizePts` is optional (absent when no
1574
- * `<a:buSzPts>` was declared); when present it takes precedence over `sizePct`.
1575
- */
1576
- type Bullet$1 = {
1577
- type: 'none';
1578
- } | {
1579
- type: 'inherit';
1580
- } | {
1581
- type: 'char';
1582
- char: string;
1583
- color: string | null;
1584
- sizePct: number | null;
1585
- sizePts?: number;
1586
- fontFamily: string | null;
1587
- } | {
1588
- type: 'autoNum';
1589
- numType: string;
1590
- startAt: number | null;
1591
- color: string | null;
1592
- };
1593
- interface TabStop {
1594
- /** Position in EMU from the LEADING text-inset edge of the text area —
1595
- * logical, not physical (ECMA-376 §21.1.2.1): the left edge (after lIns)
1596
- * in an LTR paragraph, the right edge (before rIns) in an RTL
1597
- * (`<a:pPr rtl="1">`) paragraph. */
1598
- pos: number;
1599
- /** Alignment: "l" | "r" | "ctr" | "dec" */
1600
- algn: string;
1601
- }
1602
- interface Paragraph$1 {
1603
- /** Alignment: "l" | "ctr" | "r" | "just" */
1604
- alignment: string;
1605
- /** Left margin in EMU */
1606
- marL: number;
1607
- /** Right margin in EMU */
1608
- marR: number;
1609
- /** First-line indent in EMU (negative = hanging indent) */
1610
- indent: number;
1611
- spaceBefore: number | null;
1612
- spaceAfter: number | null;
1613
- spaceLine: SpaceLine | null;
1614
- /** List nesting level (0–8) */
1615
- lvl: number;
1616
- bullet: Bullet$1;
1617
- defFontSize: number | null;
1618
- defColor: string | null;
1619
- defBold: boolean | null;
1620
- defItalic: boolean | null;
1621
- defFontFamily: string | null;
1622
- /** Tab stops from pPr > tabLst */
1623
- tabStops: TabStop[];
1624
- /**
1625
- * `<a:pPr rtl="1">` — right-to-left paragraph (ECMA-376 §21.1.2.2.7).
1626
- * When true and no explicit `algn`, the parser-side default flips from
1627
- * "l" to "r"; renderers can also use this flag to flow runs RTL.
1628
- */
1629
- rtl?: boolean;
1630
- runs: TextRun[];
1631
- }
1632
- type TextRun = TextRunData | LineBreak | EquationRun;
1633
- /**
1634
- * An OMML equation embedded in a paragraph (ECMA-376 §22.1). Parsed into the
1635
- * shared math AST and rendered by `@silurus/ooxml-core`'s math engine.
1636
- * PowerPoint stores these as `a14:m` inside `mc:AlternateContent`.
1637
- */
1638
- interface EquationRun {
1639
- type: 'math';
1640
- /** Parsed OMML node list. */
1641
- nodes: MathNode[];
1642
- /** True for block (`m:oMathPara`) math, false for inline (`m:oMath`). */
1643
- display: boolean;
1644
- /** Paragraph default run size in pt, if declared; absent → renderer inherits. */
1645
- fontSize?: number | null;
1646
- /** Equation colour (hex, no '#') from the math run's rPr; absent → inherit. */
1647
- color?: string | null;
1648
- }
1649
- interface TextRunData {
1650
- type: 'text';
1651
- text: string;
1652
- /** null = not set, inherit from paragraph/body defaults */
1653
- bold: boolean | null;
1654
- /** null = not set, inherit from paragraph/body defaults */
1655
- italic: boolean | null;
1656
- underline: boolean;
1657
- /**
1658
- * Specific underline style when not the default single line. Values come
1659
- * from ECMA-376 §21.1.2.3.16 (ST_TextUnderlineType): "dbl", "heavy",
1660
- * "dotted", "dottedHeavy", "dash", "dashHeavy", "dashLong",
1661
- * "dashLongHeavy", "dotDash", "dotDashHeavy", "dotDotDash",
1662
- * "dotDotDashHeavy", "wavy", "wavyHeavy", "wavyDbl". Absent means either
1663
- * no underline (when `underline` is false) or the default single line.
1664
- */
1665
- underlineStyle?: string;
1666
- /**
1667
- * Underline-only colour from rPr > uFill (ECMA-376 §21.1.2.3.20). Absent
1668
- * means the underline follows the text colour (uFillTx default).
1669
- */
1670
- underlineColor?: string;
1671
- /** True when rPr strike is sngStrike or dblStrike. */
1672
- strikethrough: boolean;
1673
- /**
1674
- * True only when rPr strike = "dblStrike". Lets the renderer draw two parallel
1675
- * lines instead of one. ECMA-376 §21.1.2.3.10 (ST_TextStrikeType).
1676
- */
1677
- strikeDouble?: boolean;
1678
- /** Font size in points */
1679
- fontSize: number | null;
1680
- color: string | null;
1681
- fontFamily: string | null;
1682
- /**
1683
- * East Asian font family from rPr > a:ea (ECMA-376 §21.1.2.3.7),
1684
- * resolved through the theme. Renderer uses this for CJK glyphs when
1685
- * present; absent means CJK falls back to fontFamily.
1686
- */
1687
- fontFamilyEa?: string;
1688
- /**
1689
- * Symbol font family from rPr > a:sym (ECMA-376 §21.1.2.3.10), resolved
1690
- * through the theme. PowerPoint stores symbol-font glyphs as Private-Use
1691
- * codepoints U+F020–U+F0FF; the renderer uses this font to resolve them.
1692
- * Absent means no symbol font was declared.
1693
- */
1694
- fontFamilySym?: string;
1695
- /** Baseline shift in thousandths of a point. Positive = superscript, negative = subscript. */
1696
- baseline?: number;
1697
- /**
1698
- * Capitalisation transform — ECMA-376 §21.1.2.3.13 (ST_TextCapsType).
1699
- * 'all' renders text in upper case; 'small' uses small caps (rendered as
1700
- * upper case at ~80% size when no smcp font feature is available).
1701
- * 'none' or omitted leaves the text unchanged.
1582
+ * Maximum permitted inflated size for any one archive entry, including
1583
+ * media. Enforced against both the ZIP declaration and actual output.
1702
1584
  */
1703
- caps?: 'none' | 'small' | 'all';
1585
+ maxArchiveEntryBytes?: OoxmlResourceLimit;
1586
+ /** Maximum actual inflated bytes across distinct entries in the session. */
1587
+ maxTotalInflatedBytes?: OoxmlResourceLimit;
1588
+ }
1589
+ /**
1590
+ * Common load-time options shared by the docx / pptx / xlsx
1591
+ * `Document.load` / `Presentation.load` / `Workbook.load` factories and their
1592
+ * viewer wrappers.
1593
+ *
1594
+ * This is the single source of truth — each package re-exports this exact type
1595
+ * as its `LoadOptions` so application code can pass one options object to any
1596
+ * of the three.
1597
+ */
1598
+ interface LoadOptions$1 {
1704
1599
  /**
1705
- * Inter-character spacing in 100ths of a point ECMA-376 §21.1.2.3.5
1706
- * (rPr @spc). Positive values add space, negative values tighten.
1600
+ * Opt in to loading webfont substitutes from Google Fonts
1601
+ * (`fonts.googleapis.com`). Default `false` the canvas falls back to
1602
+ * locally available fonts.
1603
+ *
1604
+ * When enabled, end-user IP / User-Agent is sent to Google, which may
1605
+ * have privacy / GDPR implications for your application. To avoid the
1606
+ * third-party request, host the substitutes yourself and reference them
1607
+ * via `@font-face` in your application CSS.
1707
1608
  */
1708
- letterSpacing?: number;
1709
- /** Set for OOXML field runs (e.g. "slidenum"). When set, renderer replaces text with field value. */
1710
- fieldType?: string;
1609
+ useGoogleFonts?: boolean;
1711
1610
  /**
1712
- * Hyperlink target resolved from rPr > a:hlinkClick @r:id via the slide's _rels.
1713
- * For an external link this is the URL; for an internal slide jump it is the
1714
- * resolved internal part name (e.g. "../slides/slide3.xml"). Undefined for runs
1715
- * without a hyperlink. ECMA-376 §21.1.2.3.5 (CT_Hyperlink).
1611
+ * Password for an encrypted OOXML file ([MS-OFFCRYPTO] Agile Encryption).
1612
+ *
1613
+ * Password-protected Office documents are CFB (OLE2) containers, not ZIPs.
1614
+ * When this is set and the input is Agile-encrypted, `load()` decrypts it on
1615
+ * the main thread (via WebCrypto) and parses the recovered plaintext ZIP.
1616
+ *
1617
+ * Errors (thrown as {@link import('../errors/ooxml-error').OoxmlError}):
1618
+ * - no `password` on an encrypted file → code `'encrypted'`
1619
+ * - wrong `password` → code `'invalid-password'`
1620
+ * - a non-Agile scheme (Standard / Extensible / legacy) → code
1621
+ * `'unsupported-encryption'`
1622
+ *
1623
+ * Note: Agile Encryption uses a high password-hash spin count (commonly
1624
+ * 100,000), so decryption of a protected file adds roughly a second of
1625
+ * WebCrypto work before parsing begins.
1626
+ *
1627
+ * Security notes:
1628
+ * - This value is held as an ordinary JS `string` in memory for the
1629
+ * duration of key derivation. The library does not zero it, and does
1630
+ * not wrap it in a `SecureString`-equivalent — it becomes eligible for
1631
+ * garbage collection like any other string once nothing references it,
1632
+ * but no explicit wipe is performed. It is never logged or included in
1633
+ * thrown errors.
1634
+ * - Decryption recovers the plaintext but does not verify the file's HMAC
1635
+ * data-integrity tag ([MS-OFFCRYPTO] §2.3.4.14), so ciphertext tampering
1636
+ * is not detected — see "Security & Privacy" in the README.
1716
1637
  */
1717
- hyperlink?: string;
1638
+ password?: string;
1718
1639
  /**
1719
- * Raw `<a:hlinkClick @action>` string (e.g. "ppaction://hlinksldjump") when
1720
- * present — its presence marks {@link hyperlink} as an INTERNAL PowerPoint
1721
- * action (slide jump / first / last …) rather than an external URL. Undefined
1722
- * when the hlinkClick has no @action. ECMA-376 §21.1.2.3.5. (IX1)
1640
+ * Override the URL the parser worker fetches the WebAssembly module from.
1641
+ *
1642
+ * By default each format resolves the `.wasm` asset that ships next to its
1643
+ * bundle (relative to the module URL), so no configuration is needed. Set
1644
+ * this to serve the parser WASM from a CDN or a self-hosted path instead — a
1645
+ * relative value is resolved against the current document URL. The same
1646
+ * dependency-injection contract across docx / pptx / xlsx.
1647
+ *
1648
+ * The referenced file must be the matching format's `*_parser_bg.wasm`
1649
+ * artifact (the one wasm-bindgen emitted for that parser); pointing it at a
1650
+ * mismatched or missing file makes `load()` reject when the worker
1651
+ * instantiates it.
1723
1652
  */
1724
- hyperlinkAction?: string;
1653
+ wasmUrl?: string | URL;
1725
1654
  /**
1726
- * Run-level drop shadow on glyphs (`<a:rPr><a:effectLst><a:outerShdw>`),
1727
- * ECMA-376 §20.1.8.45. Independent of the shape-level shadow on `spPr`.
1728
- * Absent means no run-level shadow.
1655
+ * @deprecated Use `resourceLimits.maxArchiveEntryBytes`. Scheduled for
1656
+ * removal in a future breaking release.
1657
+ *
1658
+ * Existing positive safe-integer values remain an all-entry inflated-byte
1659
+ * limit. Zero, negative, and NaN values retain their historical fallback
1660
+ * behavior; other invalid positive values reject during `load()`.
1729
1661
  */
1730
- shadow?: Shadow;
1662
+ maxZipEntryBytes?: number;
1731
1663
  /**
1732
- * Run-level glyph outline (`<a:rPr><a:ln w="..">`), ECMA-376 §20.1.2.2.24
1733
- * (CT_TextOutlineEffect). Renderer strokes each glyph with the given
1734
- * width / colour in addition to the normal fill. Absent means glyphs are
1735
- * fill-only.
1664
+ * Inflated archive admission limits for one document session. Omitted fields
1665
+ * use the library defaults. A positive safe integer overrides a default;
1666
+ * `null` disables that configurable limit only. Limits are admission policy,
1667
+ * not guarantees of exact browser-process memory use.
1736
1668
  */
1737
- outline?: TextOutline;
1669
+ resourceLimits?: OoxmlResourceLimits;
1738
1670
  /**
1739
- * Run-level text highlight / marker colour (`<a:rPr><a:highlight>`),
1740
- * ECMA-376 §21.1.2.3.4. In DrawingML this is a full CT_Color (any
1741
- * srgbClr / schemeClr / sysClr / prstClr + transforms), unlike
1742
- * WordprocessingML's fixed 16-name highlight enum — so the parser already
1743
- * resolves it through the theme/clrMap. The value is a hex string without
1744
- * `#` (6-char opaque, or 8-char RRGGBBAA when an alpha transform applies);
1745
- * the renderer paints a background rectangle behind the run's glyphs.
1746
- * Absent means no highlight.
1671
+ * Emit one content-free resource-usage card after load succeeds or fails.
1672
+ * Includes observed archive counters and configured limits, but never source
1673
+ * URLs, part names, document text, passwords, or error messages.
1747
1674
  */
1748
- highlight?: string;
1749
- }
1750
- /** Run-level glyph outline. Width is in OOXML EMU (12700 EMU = 1 pt). */
1751
- interface TextOutline {
1752
- width: number;
1753
- /** Hex without '#'. Absent = inherit from text fill colour. */
1754
- color?: string;
1755
- }
1756
- interface LineBreak {
1757
- type: 'break';
1758
- }
1759
- interface RenderOptions {
1760
- width?: number;
1761
- defaultTextColor?: string | null;
1762
- dpr?: number;
1763
- majorFont?: string | null;
1764
- minorFont?: string | null;
1765
- /** Theme hyperlink colour (hex 6 chars). Used to colour hyperlink runs without an explicit colour. */
1766
- hlinkColor?: string | null;
1675
+ debug?: boolean;
1767
1676
  /**
1768
- * Lazily resolve an archive-internal asset (by zip path) to a Blob. The
1769
- * renderer uses this to fetch posters and other large embedded assets on
1770
- * demand, keeping the parse output free of inlined base64.
1677
+ * Receive the initial content-free, machine-readable report that powers the
1678
+ * debug card, without enabling console output. After resource options validate,
1679
+ * the callback runs once when the current load settles, including failed loads
1680
+ * for which no renderer instance is returned. The callback is not awaited;
1681
+ * synchronous exceptions and rejected promises are ignored and never change
1682
+ * load results.
1683
+ *
1684
+ * A browser report covers the underlying document/workbook/presentation
1685
+ * factory. It does not wait for a Viewer's first canvas paint; that paint and
1686
+ * later lazy worksheet, slide, image, or media access may increase counters or
1687
+ * surface a separate render error. Successfully opened packages include the
1688
+ * declared package total and source byte size in the report. On a successful
1689
+ * load, call `getResourceMetrics()` on the returned engine or Viewer for a fresh
1690
+ * snapshot that includes subsequently observed lazy package work.
1771
1691
  */
1772
- fetchMedia?: (path: string) => Promise<Blob>;
1692
+ onResourceMetrics?: (metrics: OoxmlResourceMetrics) => void;
1773
1693
  /**
1774
- * Lazily resolve an embedded image (by zip path + MIME) to a Blob. Twin of
1775
- * {@link RenderOptions.fetchMedia} for pictures and blip fills: the renderer
1776
- * fetches raster/SVG bytes on demand and decodes them (`createImageBitmap` /
1777
- * path-keyed `<img>`), so the parse output carries only paths, never base64.
1694
+ * Reject the parse request if the parser worker does not answer within this
1695
+ * many milliseconds. Opt-in safety net for a wedged or crashed worker that
1696
+ * would otherwise leave `load()` pending forever. **Default: unlimited**
1697
+ * parsing a large document with heavy embedded media can legitimately take
1698
+ * tens of seconds, so no timeout is imposed unless you set one. A worker that
1699
+ * throws or fails to load already rejects immediately regardless of this
1700
+ * value; this bound only covers the "silent, never-responds" case.
1778
1701
  */
1779
- fetchImage?: (path: string, mimeType: string) => Promise<Blob>;
1702
+ workerTimeoutMs?: number;
1780
1703
  /**
1781
- * When true, renderMedia draws only the poster frame play/pause badges
1782
- * and progress bars are left to the caller. Set by the pptx presentSlide
1783
- * API so its interactive handle can own all control chrome without
1784
- * the static renderer drawing a duplicate play badge.
1704
+ * Opt-in OMML equation engine (MathJax + STIX Two Math, ~3 MB). Inject it
1705
+ * **once** here and every render of this document / presentation / workbook
1706
+ * uses it the same dependency-injection contract across all three formats
1707
+ * and their viewers. Import it from the separate `@silurus/ooxml/math` entry
1708
+ * (`import { math } from '@silurus/ooxml/math'`). Omit it and equations are
1709
+ * skipped and the engine tree-shakes away entirely (no network, no bundle
1710
+ * cost).
1785
1711
  */
1786
- skipMediaControls?: boolean;
1712
+ math?: MathRenderer;
1713
+ }
1714
+ //#endregion
1715
+ //#region packages/core/src/image/pixel-budget.d.ts
1716
+ type OoxmlDecodedImageLimitMetric = 'image-pixels' | 'active-decoded-bytes';
1717
+ /** Catchable hard-quota crossing for decoded image surfaces. */
1718
+ declare class OoxmlDecodedImageLimitError extends RangeError {
1719
+ readonly metric: OoxmlDecodedImageLimitMetric;
1720
+ readonly limit: number;
1721
+ readonly observed: number;
1722
+ readonly code: "ooxml-decoded-image-limit";
1723
+ constructor(metric: OoxmlDecodedImageLimitMetric, limit: number, observed: number);
1787
1724
  }
1725
+ declare function isOoxmlDecodedImageLimitError(error: unknown): error is OoxmlDecodedImageLimitError;
1726
+ //#endregion
1727
+ //#region packages/core/src/interaction/hyperlink.d.ts
1728
+ /**
1729
+ * Shared hyperlink model + URL sanitisation for docx / pptx / xlsx (IX1).
1730
+ *
1731
+ * All three formats carry the same two ECMA-376 concepts:
1732
+ * - an **external** hyperlink — an absolute URL resolved from a relationship
1733
+ * part target (`document.xml.rels` for docx §17.16.22, the slide rels for
1734
+ * pptx §21.1.2.3.5, the worksheet rels for xlsx §18.3.1.47), with
1735
+ * `TargetMode="External"`.
1736
+ * - an **internal** hyperlink — a jump within the document itself:
1737
+ * docx `w:anchor` -> a `<w:bookmarkStart w:name>` (§17.16.23), pptx
1738
+ * `action="ppaction://hlinksldjump"` -> a slide, xlsx `location` -> a defined
1739
+ * name or a `Sheet!A1` cell reference.
1740
+ *
1741
+ * The parsers (Rust, one per format) do the format-specific rels lookup and hand
1742
+ * each run / shape / cell a {@link HyperlinkTarget}. Everything downstream — the
1743
+ * text-layer overlay, the viewer default click behaviour, and any integrator
1744
+ * callback — is format-agnostic and consumes this one shape. Keeping the type +
1745
+ * the pure `sanitizeHyperlinkUrl` predicate here (not duplicated per package)
1746
+ * follows the cross-package unification principle: a scheme-allowlist bug fixed
1747
+ * once is fixed everywhere.
1748
+ */
1749
+ /**
1750
+ * A resolved hyperlink attached to a run, shape, or cell.
1751
+ *
1752
+ * - `external` — `url` is the raw target as authored in the file. It is NOT
1753
+ * guaranteed safe; run it through {@link sanitizeHyperlinkUrl} before
1754
+ * navigating. It is kept verbatim here so an integrator can apply its own
1755
+ * policy (e.g. allow `file:` on a trusted intranet viewer).
1756
+ * - `internal` — `ref` is the in-document destination, verbatim from the file:
1757
+ * docx: the bookmark name (`w:anchor`).
1758
+ * pptx: the internal action (e.g. `ppaction://hlinksldjump`), with the
1759
+ * resolved 0-based `slideIndex` when the rels target names a slide.
1760
+ * xlsx: the `location` string (a defined name or `Sheet1!A1`).
1761
+ */
1762
+ type HyperlinkTarget = {
1763
+ kind: 'external';
1764
+ url: string;
1765
+ } | {
1766
+ kind: 'internal';
1767
+ ref: string;
1768
+ slideIndex?: number;
1769
+ };
1770
+ /**
1771
+ * The default action a viewer takes for an **external** hyperlink click when
1772
+ * the integrator supplies no `onHyperlinkClick` handler: sanitise the URL and,
1773
+ * if allowed, open it in a new tab with `noopener,noreferrer` so the opened page
1774
+ * gets no `window.opener` handle back into this document. A blocked scheme is a
1775
+ * silent no-op (returns `false`) — the click does nothing rather than navigate
1776
+ * somewhere dangerous.
1777
+ *
1778
+ * Internal targets are intentionally NOT handled here: the in-document jump
1779
+ * (page / slide / cell) is format-specific and lives in each viewer.
1780
+ *
1781
+ * Split out (not inlined in three viewers) so the "open in new tab, drop opener,
1782
+ * refuse unsafe schemes" policy is defined once. `win` is injected for tests;
1783
+ * defaults to the ambient `window`.
1784
+ *
1785
+ * @returns `true` if navigation was initiated, `false` if the URL was blocked.
1786
+ */
1787
+ declare function openExternalHyperlink(url: string, allowed?: readonly string[], win?: Pick<Window, 'open'> | undefined): boolean;
1788
1788
  //#endregion
1789
- //#region dist/.types-work/find-highlight-gMP3FAnW.d.ts
1789
+ //#region dist/.types-work/find-highlight-CnpZn3yb.d.ts
1790
1790
  //#region packages/core/src/autoResize.d.ts
1791
1791
  interface AutoResizeOptions {
1792
1792
  /**
@@ -1973,7 +1973,7 @@ interface FindHighlightColors {
1973
1973
  active?: string;
1974
1974
  }
1975
1975
  //#endregion
1976
- //#region dist/.types-work/pptx-B9ExAlcU.d.ts
1976
+ //#region dist/.types-work/pptx-BVpCWU0A.d.ts
1977
1977
  //#region packages/pptx/src/types.d.ts
1978
1978
  /**
1979
1979
  * Picture bullet — ECMA-376 §21.1.2.4.2 `<a:buBlip><a:blip r:embed>`. The