pptx-svelte-viewer 1.4.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/CHANGELOG.md +440 -0
  2. package/README.md +175 -17
  3. package/dist/AiChatPanel-CssmoLYL.js +1110 -0
  4. package/dist/__vite-browser-external-DOmiXdGM.js +7 -0
  5. package/dist/{dist-DZ-fjucV.js → dist-AHWCPEmj.js} +44226 -40236
  6. package/dist/export-DplwT6FC.js +96087 -0
  7. package/dist/i18n.js +1 -1
  8. package/dist/index.d.ts +2193 -99
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +22 -22
  11. package/dist/pptx-svelte-viewer.css +1 -1
  12. package/dist/rolldown-runtime--_vEcKDh.js +29 -0
  13. package/dist/{translator-D4a_pxY4.js → translator-Ddi-liGk.js} +251 -7
  14. package/dist/viewer/ai/ai-bridge.d.ts +61 -0
  15. package/dist/viewer/ai/ai-bridge.d.ts.map +1 -0
  16. package/dist/viewer/ai/ai-history-persist.d.ts +13 -0
  17. package/dist/viewer/ai/ai-history-persist.d.ts.map +1 -0
  18. package/dist/viewer/ai/ai-log-export.d.ts +71 -0
  19. package/dist/viewer/ai/ai-log-export.d.ts.map +1 -0
  20. package/dist/viewer/ai/ai-panel-controller.svelte.d.ts +77 -0
  21. package/dist/viewer/ai/ai-panel-controller.svelte.d.ts.map +1 -0
  22. package/dist/viewer/ai/chat.svelte.d.ts +43 -0
  23. package/dist/viewer/ai/chat.svelte.d.ts.map +1 -0
  24. package/dist/viewer/ai/focus-targets.d.ts +36 -0
  25. package/dist/viewer/ai/focus-targets.d.ts.map +1 -0
  26. package/dist/viewer/ai/index.d.ts +11 -0
  27. package/dist/viewer/ai/index.d.ts.map +1 -0
  28. package/dist/viewer/collab/collaboration-deps.d.ts +23 -0
  29. package/dist/viewer/collab/collaboration-deps.d.ts.map +1 -0
  30. package/dist/viewer/collab/collaboration-remote-sync.d.ts +13 -0
  31. package/dist/viewer/collab/collaboration-remote-sync.d.ts.map +1 -1
  32. package/dist/viewer/collab/collaboration.svelte.d.ts +9 -21
  33. package/dist/viewer/collab/collaboration.svelte.d.ts.map +1 -1
  34. package/dist/viewer/collab/components/props.d.ts +12 -0
  35. package/dist/viewer/collab/components/props.d.ts.map +1 -1
  36. package/dist/viewer/collab/components/remote-selection.d.ts +29 -0
  37. package/dist/viewer/collab/components/remote-selection.d.ts.map +1 -0
  38. package/dist/viewer/collab/components/share-helpers.d.ts +7 -28
  39. package/dist/viewer/collab/components/share-helpers.d.ts.map +1 -1
  40. package/dist/viewer/collab/index.d.ts +1 -1
  41. package/dist/viewer/collab/index.d.ts.map +1 -1
  42. package/dist/viewer/components/props.d.ts +66 -2
  43. package/dist/viewer/components/props.d.ts.map +1 -1
  44. package/dist/viewer/components/ribbon/ribbon-types.d.ts +7 -0
  45. package/dist/viewer/components/ribbon/ribbon-types.d.ts.map +1 -1
  46. package/dist/viewer/components/typed-exports.d.ts +19 -0
  47. package/dist/viewer/components/typed-exports.d.ts.map +1 -0
  48. package/dist/viewer/editor/editor-controller-deps.d.ts +5 -0
  49. package/dist/viewer/editor/editor-controller-deps.d.ts.map +1 -1
  50. package/dist/viewer/editor/editor-state.svelte.d.ts +6 -0
  51. package/dist/viewer/editor/editor-state.svelte.d.ts.map +1 -1
  52. package/dist/viewer/export/export-ui.svelte.d.ts +5 -0
  53. package/dist/viewer/export/export-ui.svelte.d.ts.map +1 -1
  54. package/dist/viewer/index.d.ts +2781 -31
  55. package/dist/viewer/index.d.ts.map +1 -1
  56. package/dist/viewer/index.js +392 -14
  57. package/dist/viewer/presentation/animation-playback-helpers.d.ts +43 -0
  58. package/dist/viewer/presentation/animation-playback-helpers.d.ts.map +1 -0
  59. package/dist/viewer/presentation/animation-playback.svelte.d.ts +50 -40
  60. package/dist/viewer/presentation/animation-playback.svelte.d.ts.map +1 -1
  61. package/dist/viewer/presentation/animation-sound.d.ts +20 -0
  62. package/dist/viewer/presentation/animation-sound.d.ts.map +1 -0
  63. package/dist/viewer/presentation/apply-animation-styles.d.ts +6 -5
  64. package/dist/viewer/presentation/apply-animation-styles.d.ts.map +1 -1
  65. package/dist/viewer/presentation/index.d.ts +2 -1
  66. package/dist/viewer/presentation/index.d.ts.map +1 -1
  67. package/dist/viewer/presentation/keyframes.d.ts +9 -0
  68. package/dist/viewer/presentation/keyframes.d.ts.map +1 -1
  69. package/dist/viewer/presentation/presentation-controller.svelte.d.ts +32 -10
  70. package/dist/viewer/presentation/presentation-controller.svelte.d.ts.map +1 -1
  71. package/dist/viewer/presentation/presentation-effects.svelte.d.ts +6 -2
  72. package/dist/viewer/presentation/presentation-effects.svelte.d.ts.map +1 -1
  73. package/dist/viewer/presentation/presentation-triggers.d.ts +18 -0
  74. package/dist/viewer/presentation/presentation-triggers.d.ts.map +1 -0
  75. package/dist/viewer/presentation/transition-overlay.d.ts +23 -0
  76. package/dist/viewer/presentation/transition-overlay.d.ts.map +1 -0
  77. package/dist/viewer/render/smartart-view.d.ts +7 -2
  78. package/dist/viewer/render/smartart-view.d.ts.map +1 -1
  79. package/dist/viewer/state/create-viewer-state-collab.svelte.d.ts +37 -0
  80. package/dist/viewer/state/create-viewer-state-collab.svelte.d.ts.map +1 -0
  81. package/dist/viewer/state/create-viewer-state-editor-ui.svelte.d.ts +42 -0
  82. package/dist/viewer/state/create-viewer-state-editor-ui.svelte.d.ts.map +1 -0
  83. package/dist/viewer/state/create-viewer-state-export-notes.svelte.d.ts +36 -0
  84. package/dist/viewer/state/create-viewer-state-export-notes.svelte.d.ts.map +1 -0
  85. package/dist/viewer/state/create-viewer-state-presentation.svelte.d.ts +30 -0
  86. package/dist/viewer/state/create-viewer-state-presentation.svelte.d.ts.map +1 -0
  87. package/dist/viewer/state/create-viewer-state-types.d.ts +134 -0
  88. package/dist/viewer/state/create-viewer-state-types.d.ts.map +1 -0
  89. package/dist/viewer/state/create-viewer-state.svelte.d.ts +30 -0
  90. package/dist/viewer/state/create-viewer-state.svelte.d.ts.map +1 -0
  91. package/dist/viewer/state/index.d.ts +2 -0
  92. package/dist/viewer/state/index.d.ts.map +1 -1
  93. package/dist/viewer/state/presentation-element-states-context.d.ts +37 -0
  94. package/dist/viewer/state/presentation-element-states-context.d.ts.map +1 -0
  95. package/dist/viewer/state/render-context.d.ts +3 -1
  96. package/dist/viewer/state/render-context.d.ts.map +1 -1
  97. package/dist/viewer/state/viewer-effects.svelte.d.ts +8 -0
  98. package/dist/viewer/state/viewer-effects.svelte.d.ts.map +1 -1
  99. package/dist/viewer/state/viewer-options-context.d.ts +10 -0
  100. package/dist/viewer/state/viewer-options-context.d.ts.map +1 -0
  101. package/dist/viewer/state/viewer-options-wiring.svelte.d.ts +31 -0
  102. package/dist/viewer/state/viewer-options-wiring.svelte.d.ts.map +1 -0
  103. package/dist/viewer/state/viewer-options.svelte.d.ts +55 -0
  104. package/dist/viewer/state/viewer-options.svelte.d.ts.map +1 -0
  105. package/dist/viewer/style/element-style.d.ts +3 -3
  106. package/dist/viewer/style/element-style.d.ts.map +1 -1
  107. package/dist/viewer/types.d.ts +16 -5
  108. package/dist/viewer/types.d.ts.map +1 -1
  109. package/dist/{y-webrtc-BdH40MC6.js → y-webrtc-BiViqyU2.js} +1079 -1101
  110. package/package.json +18 -5
  111. package/dist/export-N-hrLHrd.js +0 -38592
@@ -1,4 +1,6 @@
1
+ import * as svelte from 'svelte';
1
2
  import { Component } from 'svelte';
3
+ import { LanguageModel, ChatTransport, UIMessage, ToolSet } from 'ai';
2
4
 
3
5
  //#region src/core/types/actions.d.ts
4
6
  /**
@@ -204,6 +206,13 @@ interface PptxShapeLocks {
204
206
  noAdjustHandles?: boolean;
205
207
  noChangeArrowheads?: boolean;
206
208
  noChangeShapeType?: boolean;
209
+ /**
210
+ * Text-box flag from `p:cNvSpPr/@txBox`. Not a lock in the strict sense,
211
+ * but it lives on the same non-visual-properties node as `a:spLocks`, so
212
+ * it is captured here to round-trip through the model. When `true` the
213
+ * shape is a plain text box (no fill/line by default).
214
+ */
215
+ txBox?: boolean;
207
216
  }
208
217
  /**
209
218
  * A drawing guide parsed from OOXML extension lists.
@@ -793,6 +802,15 @@ interface ShapeStyle {
793
802
  r: number;
794
803
  b: number;
795
804
  };
805
+ /** Raw tileRect LTRB values (0..1 fractions, may be negative) from
806
+ * `a:gradFill/a:tileRect`. Defines the rectangle the gradient tile occupies
807
+ * before any flip/tiling is applied. */
808
+ fillGradientTileRect?: {
809
+ l: number;
810
+ t: number;
811
+ r: number;
812
+ b: number;
813
+ };
796
814
  /** Gradient tile flip mode (`a:gradFill/@flip`).
797
815
  * `none` = no tiling flip (default), `x|y|xy` = mirror in the named axis. */
798
816
  fillGradientFlip?: 'none' | 'x' | 'y' | 'xy';
@@ -810,6 +828,20 @@ interface ShapeStyle {
810
828
  * round-trip serialisation. See {@link fillColorXml} for the rationale.
811
829
  */
812
830
  strokeColorXml?: XmlObject;
831
+ /**
832
+ * Kind of fill painted on the outline (`a:ln` child). Distinguishes a solid
833
+ * outline from a gradient/pattern/none outline so save can emit the correct
834
+ * single line fill instead of collapsing every outline to `a:solidFill`
835
+ * (which, alongside a preserved `a:gradFill`/`a:pattFill`, produces an
836
+ * invalid dual-fill `<a:ln>`).
837
+ */
838
+ strokeFillMode?: 'solid' | 'gradient' | 'pattern' | 'none';
839
+ /** Raw `a:ln/a:gradFill` XML preserved for round-trip when the outline is
840
+ * gradient-filled. Re-emitted verbatim as the line's single fill on save. */
841
+ strokeGradientXml?: XmlObject;
842
+ /** Raw `a:ln/a:pattFill` XML preserved for round-trip when the outline is
843
+ * pattern-filled. Re-emitted verbatim as the line's single fill on save. */
844
+ strokePatternXml?: XmlObject;
813
845
  strokeWidth?: number;
814
846
  strokeOpacity?: number;
815
847
  strokeDash?: StrokeDashType;
@@ -991,6 +1023,14 @@ interface ShapeStyle {
991
1023
  };
992
1024
  /** Fill overlay blend mode from effectDag `a:fillOverlay/@blend`. */
993
1025
  dagFillOverlayBlend?: 'over' | 'mult' | 'screen' | 'darken' | 'lighten';
1026
+ /**
1027
+ * Fill overlay tint colour (hex `#RRGGBB`) from effectDag `a:fillOverlay`'s
1028
+ * `a:solidFill`/`a:gradFill`. Painted as a blended overlay layer over the
1029
+ * element; the blend mode comes from {@link dagFillOverlayBlend}.
1030
+ */
1031
+ dagFillOverlayColor?: string;
1032
+ /** Fill overlay tint opacity (0-1), from the overlay fill colour's alpha. */
1033
+ dagFillOverlayOpacity?: number;
994
1034
  /** `<a:lnRef @idx>` — 1-based index into the theme's lnStyleLst. */
995
1035
  lnRefIdx?: number;
996
1036
  /** Raw XML colour child of `<a:lnRef>` (e.g. `<a:schemeClr>` with transforms). */
@@ -1118,6 +1158,13 @@ interface TextStyle {
1118
1158
  kerning?: number;
1119
1159
  /** Text highlight colour as hex string (`a:highlight`). */
1120
1160
  highlightColor?: string;
1161
+ /**
1162
+ * Raw colour-choice XML preserved from `a:highlight` so a themed highlight
1163
+ * (`a:schemeClr` / `a:sysClr` / `a:prstClr`) re-emits with its original
1164
+ * identity rather than being flattened to `<a:srgbClr/>` on save. On save we
1165
+ * re-emit verbatim when the resolved {@link highlightColor} still matches.
1166
+ */
1167
+ highlightColorXml?: XmlObject;
1121
1168
  /** Text-level gradient fill CSS string (from `a:rPr > a:gradFill`). */
1122
1169
  textFillGradient?: string;
1123
1170
  /** Structured gradient stops for text fill round-trip serialization. */
@@ -1229,10 +1276,36 @@ interface TextStyle {
1229
1276
  eastAsiaFont?: string;
1230
1277
  /** Complex Script font family from `a:cs`. */
1231
1278
  complexScriptFont?: string;
1279
+ /**
1280
+ * Theme-font token (`+mj-lt` / `+mn-lt` / ...) authored on `a:latin`, when
1281
+ * present. {@link fontFamily} holds the resolved concrete face for
1282
+ * rendering; this preserves the token linkage so the writer re-emits the
1283
+ * token rather than the flattened face (see #84).
1284
+ */
1285
+ latinFontThemeToken?: string;
1286
+ /** Theme-font token authored on `a:ea` (e.g. `+mn-ea`), when present. */
1287
+ eastAsiaFontThemeToken?: string;
1288
+ /** Theme-font token authored on `a:cs` (e.g. `+mn-cs`), when present. */
1289
+ complexScriptFontThemeToken?: string;
1290
+ /**
1291
+ * Automatic per-script fallback face resolved from the theme's
1292
+ * `<a:font script="...">` overrides for a run whose text is dominantly
1293
+ * CJK / Arabic / Hebrew / Thai (see #83). A rendering hint only: it is not
1294
+ * serialised back on save, so it never disturbs the round-trip typefaces.
1295
+ */
1296
+ scriptFallbackFont?: string;
1232
1297
  /** Text language from `a:rPr/@lang`. */
1233
1298
  language?: string;
1234
1299
  /** Hyperlink mouse-over target from `a:hlinkMouseOver`. */
1235
1300
  hyperlinkMouseOver?: string;
1301
+ /**
1302
+ * Raw `a:snd` (embedded WAV audio) child of `a:hlinkClick`, preserved
1303
+ * verbatim (carries `@r:embed` + `@name`). Round-tripped on save so the
1304
+ * click sound survives instead of being dropped.
1305
+ */
1306
+ hyperlinkSoundXml?: XmlObject;
1307
+ /** Raw `a:snd` child of `a:hlinkMouseOver`, preserved verbatim for round-trip. */
1308
+ hyperlinkMouseOverSoundXml?: XmlObject;
1236
1309
  /** Hyperlink invalidUrl attribute (`a:hlinkClick/@invalidUrl`). */
1237
1310
  hyperlinkInvalidUrl?: string;
1238
1311
  /** Hyperlink target frame (`a:hlinkClick/@tgtFrame`). */
@@ -1576,6 +1649,15 @@ interface TextSegment {
1576
1649
  * on the first segment of a paragraph.
1577
1650
  */
1578
1651
  endParaRunProperties?: Record<string, unknown>;
1652
+ /**
1653
+ * Per-paragraph properties (alignment, spacing, margins, indent, tab stops,
1654
+ * rtl) authored on this paragraph's own `a:pPr` (#69). Only meaningful on
1655
+ * the first segment of a paragraph. When present, the writer emits these
1656
+ * per paragraph instead of collapsing one shape-level pPr onto every
1657
+ * paragraph. Only the paragraph-geometry keys of {@link TextStyle} are
1658
+ * populated; unrelated fields fall back to the shape-level style.
1659
+ */
1660
+ paragraphProperties?: TextStyle;
1579
1661
  /**
1580
1662
  * Phonetic annotation text from `a:ruby > a:rt` (e.g. furigana, pinyin).
1581
1663
  * When present, the renderer should wrap the base text with an HTML `<ruby>` tag.
@@ -1881,6 +1963,75 @@ interface PptxChartProtection {
1881
1963
  rawXml?: XmlObject;
1882
1964
  }
1883
1965
  //#endregion
1966
+ //#region src/core/types/chart-user-shapes.d.ts
1967
+ /**
1968
+ * Types for chart drawing-overlay shapes (`c:userShapes`).
1969
+ *
1970
+ * A chart's `c:userShapes` element carries an `r:id` that references a
1971
+ * separate drawing part (`ppt/drawings/drawingN.xml`) whose root is a
1972
+ * `c:userShapes` element populated with `cdr:relSizeAnchor` /
1973
+ * `cdr:absSizeAnchor` wrappers around `sp` / `pic` / `cxnSp` shapes drawn on
1974
+ * top of the chart plot. These interfaces describe the parsed, renderable
1975
+ * overlay model. The raw reference is preserved separately on
1976
+ * {@link PptxChartData.userShapesXml} for verbatim round-trip save; this model
1977
+ * is render-only.
1978
+ *
1979
+ * @module pptx-types/chart-user-shapes
1980
+ */
1981
+ /** A single paragraph of overlay-shape text with light formatting. */
1982
+ interface PptxChartUserShapeParagraph {
1983
+ /** Joined run text of the paragraph. */
1984
+ text: string;
1985
+ /** Font size in points (`a:rPr/@sz` divided by 100), when present. */
1986
+ fontSize?: number;
1987
+ /** Whether the first run is bold (`a:rPr/@b`). */
1988
+ bold?: boolean;
1989
+ /** Whether the first run is italic (`a:rPr/@i`). */
1990
+ italic?: boolean;
1991
+ /** Resolved run colour hex (e.g. `"#FF0000"`), when present. */
1992
+ color?: string;
1993
+ /** Paragraph alignment (`a:pPr/@algn`): left / centre / right. */
1994
+ align?: 'l' | 'ctr' | 'r';
1995
+ }
1996
+ /**
1997
+ * A parsed chart-overlay shape positioned by a drawing anchor.
1998
+ *
1999
+ * Position is expressed as chart-relative fractions in {@link from}. For a
2000
+ * `relSizeAnchor` the opposite corner is {@link to} (also fractional); for an
2001
+ * `absSizeAnchor` the extent is {@link ext} in EMU.
2002
+ */
2003
+ interface PptxChartUserShape {
2004
+ /** Shape kind: text/preset shape, connector, or picture. */
2005
+ kind: 'sp' | 'cxnSp' | 'pic';
2006
+ /** Anchor kind that positioned the shape. */
2007
+ anchor: 'rel' | 'abs';
2008
+ /** Top-left corner as chart-relative fractions (0-1). */
2009
+ from: {
2010
+ x: number;
2011
+ y: number;
2012
+ };
2013
+ /** Bottom-right corner as chart-relative fractions (0-1); relSizeAnchor only. */
2014
+ to?: {
2015
+ x: number;
2016
+ y: number;
2017
+ };
2018
+ /** Extent in EMU (cx, cy); absSizeAnchor only. */
2019
+ ext?: {
2020
+ cx: number;
2021
+ cy: number;
2022
+ };
2023
+ /** Preset geometry name (`a:prstGeom/@prst`), defaulting to `"rect"`. */
2024
+ prst?: string;
2025
+ /** Resolved solid-fill hex colour, when present. */
2026
+ fill?: string;
2027
+ /** Resolved line/stroke hex colour, when present. */
2028
+ stroke?: string;
2029
+ /** Line width in points (`a:ln/@w` divided by 12700), when present. */
2030
+ strokeWidth?: number;
2031
+ /** Text paragraphs of the shape's `txBody`, when present. */
2032
+ paragraphs?: PptxChartUserShapeParagraph[];
2033
+ }
2034
+ //#endregion
1884
2035
  //#region src/core/types/chart.d.ts
1885
2036
  /**
1886
2037
  * Supported chart type discriminators.
@@ -2214,6 +2365,15 @@ interface PptxChartTreemapOptions {
2214
2365
  interface PptxChartSeries {
2215
2366
  name: string;
2216
2367
  values: number[];
2368
+ /**
2369
+ * Blank-value mask aligned index-for-index with {@link values}: `true` marks
2370
+ * a category whose numeric cache point (`c:numCache/c:pt`) was absent or
2371
+ * empty, i.e. a genuine blank rather than a real `0`. Present only when the
2372
+ * source series actually contains blanks; when set, blank slots in
2373
+ * {@link values} carry `0` as a placeholder. Renderers honour
2374
+ * `c:dispBlanksAs` (gap / zero / span) using this mask.
2375
+ */
2376
+ blanks?: boolean[];
2217
2377
  color?: string;
2218
2378
  trendlines?: PptxChartTrendline[];
2219
2379
  errBars?: PptxChartErrBars[];
@@ -2221,6 +2381,18 @@ interface PptxChartSeries {
2221
2381
  marker?: PptxChartMarker;
2222
2382
  dataLabels?: PptxChartDataLabel[];
2223
2383
  explosion?: number;
2384
+ /**
2385
+ * Series-level `c:invertIfNegative`: when true, bar/column data points with a
2386
+ * negative value are drawn with an inverted (lightened) fill. A per-point
2387
+ * `c:dPt/c:invertIfNegative` overrides this for that point. Absent when the
2388
+ * source XML omits the flag.
2389
+ */
2390
+ invertIfNegative?: boolean;
2391
+ /**
2392
+ * Whether this line/scatter series is drawn with bezier smoothing
2393
+ * (`c:ser/c:smooth/@val`). Absent when the source XML omits `c:smooth`.
2394
+ */
2395
+ smooth?: boolean;
2224
2396
  /** Axis ID this series is plotted against (links to PptxChartAxisFormatting.axisId). */
2225
2397
  axisId?: number;
2226
2398
  /**
@@ -2423,6 +2595,14 @@ interface PptxChartManualLayout {
2423
2595
  y?: number;
2424
2596
  width?: number;
2425
2597
  height?: number;
2598
+ /**
2599
+ * Raw `c:extLst` (CT_ExtensionList) of the `c:manualLayout`, captured
2600
+ * verbatim so it round-trips through the typed model. Without this, a dirty
2601
+ * write of an edited layout would drop the extension list (the manual node
2602
+ * is rebuilt from the typed fields). Emitted as the trailing child, matching
2603
+ * the CT_ManualLayout schema order.
2604
+ */
2605
+ ext?: XmlObject;
2426
2606
  }
2427
2607
  /**
2428
2608
  * Typed manual layouts for chart regions that accept `c:layout`.
@@ -2487,6 +2667,33 @@ interface PptxChartData {
2487
2667
  style?: PptxChartStyle;
2488
2668
  /** Grouping mode for bar/area/line charts: 'clustered' | 'stacked' | 'percentStacked' */
2489
2669
  grouping?: 'clustered' | 'stacked' | 'percentStacked';
2670
+ /**
2671
+ * Whether the first (or only) series varies its point colours
2672
+ * (`c:varyColors/@val`). Pie/doughnut default this on; single-series
2673
+ * bar/column honour it by giving each point a distinct palette colour.
2674
+ * Absent when the source XML omits `c:varyColors`.
2675
+ */
2676
+ varyColors?: boolean;
2677
+ /**
2678
+ * Pie/doughnut start angle in degrees clockwise from 12 o'clock
2679
+ * (`c:firstSliceAng/@val`, 0 through 360). Absent uses the default 0.
2680
+ */
2681
+ firstSliceAngle?: number;
2682
+ /**
2683
+ * Doughnut hole diameter as a percentage of the outer diameter
2684
+ * (`c:holeSize/@val`, 10 through 90). Absent uses the renderer default.
2685
+ */
2686
+ doughnutHoleSize?: number;
2687
+ /**
2688
+ * Bar/column gap between category clusters as a percentage of bar width
2689
+ * (`c:gapWidth/@val`, 0 through 500). Absent uses the renderer default.
2690
+ */
2691
+ barGapWidth?: number;
2692
+ /**
2693
+ * Clustered bar/column overlap between series within a category as a
2694
+ * percentage (`c:overlap/@val`, -100 through 100). Absent uses 0.
2695
+ */
2696
+ barOverlap?: number;
2490
2697
  /** Internal: path to the chart XML part in the PPTX archive (for round-trip save). */
2491
2698
  chartPartPath?: string;
2492
2699
  /** Internal: relationship ID linking the graphic frame to the chart part. */
@@ -2587,6 +2794,15 @@ interface PptxChartData {
2587
2794
  * attempting to parse the nested drawing tree.
2588
2795
  */
2589
2796
  userShapesXml?: unknown;
2797
+ /**
2798
+ * Parsed, renderable drawing-overlay shapes resolved from the separate
2799
+ * drawing part referenced by `c:userShapes/@r:id`
2800
+ * (`ppt/drawings/drawingN.xml`). Each entry carries chart-relative anchor
2801
+ * geometry plus light shape/text formatting so the viewer can render an
2802
+ * overlay on top of the chart plot. Render-only: {@link userShapesXml}
2803
+ * remains the source of truth for round-trip save.
2804
+ */
2805
+ userShapes?: PptxChartUserShape[];
2590
2806
  /**
2591
2807
  * Raw `c:pivotFmts` XML subtree preserved verbatim.
2592
2808
  *
@@ -3294,6 +3510,18 @@ interface PptxSmartArtColorTransform extends PptxSmartArtDefinitionMetadata {
3294
3510
  fillColors: string[];
3295
3511
  /** Ordered resolved line colors for rendering. */
3296
3512
  lineColors: string[];
3513
+ /** Ordered resolved text-fill colors (primary styleLbl `txFillClrLst`). */
3514
+ textFillColors?: string[];
3515
+ /** Ordered resolved text-line colors (primary styleLbl `txLinClrLst`). */
3516
+ textLineColors?: string[];
3517
+ /** Ordered resolved effect colors (primary styleLbl `effectClrLst`). */
3518
+ effectColors?: string[];
3519
+ /** Ordered resolved text-effect colors (primary styleLbl `txEffectClrLst`). */
3520
+ textEffectColors?: string[];
3521
+ /** Fill-list span/cycle + hue-direction interpolation of the primary styleLbl. */
3522
+ fillInterpolation?: PptxSmartArtColorListMetadata;
3523
+ /** Line-list span/cycle + hue-direction interpolation of the primary styleLbl. */
3524
+ lineInterpolation?: PptxSmartArtColorListMetadata;
3297
3525
  /** Ordered CT_CTStyleLabel metadata. */
3298
3526
  labels?: PptxSmartArtColorStyleLabel[];
3299
3527
  }
@@ -3414,6 +3642,40 @@ interface PptxSmartArtDrawingShape extends PptxCustomPathProperties {
3414
3642
  skewY?: number;
3415
3643
  /** Solid fill colour (hex). */
3416
3644
  fillColor?: string;
3645
+ /**
3646
+ * Gradient fill stops when the cached shape uses `a:gradFill`. Positions are
3647
+ * 0..100 (percent). Renderers emit an SVG/CSS gradient instead of a flat box.
3648
+ */
3649
+ fillGradientStops?: Array<{
3650
+ color: string;
3651
+ position: number;
3652
+ opacity?: number;
3653
+ }>;
3654
+ /** Gradient geometry type (`linear` for `a:lin`, `radial` for `a:path`). */
3655
+ fillGradientType?: 'linear' | 'radial';
3656
+ /** Linear gradient angle in degrees (0..360). */
3657
+ fillGradientAngle?: number;
3658
+ /** Pattern fill preset name from `a:pattFill/@prst` (e.g. "pct50", "cross"). */
3659
+ fillPatternPreset?: string;
3660
+ /** Pattern fill foreground colour (hex) from `a:pattFill/a:fgClr`. */
3661
+ fillPatternForegroundColor?: string;
3662
+ /** Pattern fill background colour (hex) from `a:pattFill/a:bgClr`. */
3663
+ fillPatternBackgroundColor?: string;
3664
+ /**
3665
+ * Relationship id of a picture (blip) fill's embedded image, from
3666
+ * `a:blipFill/a:blip/@r:embed`. The image bytes are resolved separately; see
3667
+ * {@link fillImageUrl}.
3668
+ */
3669
+ fillBlipEmbedId?: string;
3670
+ /**
3671
+ * Resolved data-URI/URL for a picture (blip) fill, when the embedded image
3672
+ * part could be resolved. Absent when only {@link fillBlipEmbedId} is known.
3673
+ */
3674
+ fillImageUrl?: string;
3675
+ /** Whether the cached shape carries an outer-shadow effect (`a:effectLst`). */
3676
+ hasShadow?: boolean;
3677
+ /** Resolved outer-shadow colour (hex), when present. */
3678
+ shadowColor?: string;
3417
3679
  /** Stroke colour (hex). */
3418
3680
  strokeColor?: string;
3419
3681
  /** Stroke width in points. */
@@ -3448,6 +3710,40 @@ interface PptxSmartArtChrome {
3448
3710
  /** Outline stroke width in points. */
3449
3711
  outlineWidth?: number;
3450
3712
  }
3713
+ /**
3714
+ * Presentation layout variables from `dgm:prSet/dgm:presLayoutVars` (data model)
3715
+ * or `dgm:varLst` (layout definition defaults).
3716
+ *
3717
+ * These drive how the DiagramML layout interpreter arranges points: flow
3718
+ * direction, hierarchy branch style, org-chart mode, and child count limits.
3719
+ * The fallback layout engine can consult them for direction/org-chart hints.
3720
+ *
3721
+ * @example
3722
+ * ```ts
3723
+ * const vars: PptxSmartArtPresLayoutVars = { direction: "rev", orgChart: true };
3724
+ * // => satisfies PptxSmartArtPresLayoutVars
3725
+ * ```
3726
+ */
3727
+ interface PptxSmartArtPresLayoutVars {
3728
+ /** Flow direction (`dgm:dir`): "norm" (default) or "rev" (reversed/RTL). */
3729
+ direction?: 'norm' | 'rev';
3730
+ /** Hierarchy branch style (`dgm:hierBranch`): std/init/l/r/hang. */
3731
+ hierarchyBranch?: 'std' | 'init' | 'l' | 'r' | 'hang';
3732
+ /** Org-chart mode enabled (`dgm:orgChart`). */
3733
+ orgChart?: boolean;
3734
+ /** Maximum children per node (`dgm:chMax`, -1 = unbounded). */
3735
+ childMax?: number;
3736
+ /** Preferred children per node (`dgm:chPref`, -1 = unbounded). */
3737
+ childPreferred?: number;
3738
+ /** Whether bullets are enabled (`dgm:bulletEnabled`). */
3739
+ bulletEnabled?: boolean;
3740
+ /** Animation-by-level setting (`dgm:animLvl`). */
3741
+ animationLevel?: string;
3742
+ /** Animate-one setting (`dgm:animOne`). */
3743
+ animateOne?: string;
3744
+ /** Allowed resize handles (`dgm:resizeHandles`). */
3745
+ resizeHandles?: string;
3746
+ }
3451
3747
  /**
3452
3748
  * Complete parsed SmartArt data for a {@link SmartArtPptxElement}.
3453
3749
  *
@@ -3489,6 +3785,12 @@ interface PptxSmartArtData {
3489
3785
  quickStyle?: PptxSmartArtQuickStyle;
3490
3786
  /** Editable metadata from the related DiagramML layout definition. */
3491
3787
  layoutDefinition?: PptxSmartArtLayoutDefinition;
3788
+ /**
3789
+ * Presentation layout variables (direction, hierarchy branch, org-chart,
3790
+ * child limits, bullets) from `dgm:presLayoutVars` / layout `dgm:varLst`.
3791
+ * Consulted by the fallback layout engine for direction/org-chart hints.
3792
+ */
3793
+ presLayoutVars?: PptxSmartArtPresLayoutVars;
3492
3794
  /** Relationship ID for the diagram data part (for round-trip save). */
3493
3795
  dataRelId?: string;
3494
3796
  /** Relationship ID for the diagram layout part. */
@@ -3521,7 +3823,7 @@ interface PptxSmartArtData {
3521
3823
  /**
3522
3824
  * Per-cell visual style for a table cell.
3523
3825
  *
3524
- * All fields are optional unset values inherit from the table style.
3826
+ * All fields are optional - unset values inherit from the table style.
3525
3827
  *
3526
3828
  * @example
3527
3829
  * ```ts
@@ -3649,6 +3951,52 @@ interface PptxTableCellStyle {
3649
3951
  patternFillForeground?: string;
3650
3952
  /** Pattern fill background colour. */
3651
3953
  patternFillBackground?: string;
3954
+ /**
3955
+ * Cell 3D bevel + lighting from `a:tcPr/a:cell3D` (CT_Cell3D,
3956
+ * ECMA-376 §21.1.3.1). Rendered as a CSS bevel treatment.
3957
+ */
3958
+ cell3D?: PptxTableCell3D;
3959
+ /**
3960
+ * `a:tcPr/@anchorCtr` - centre the text block in the direction
3961
+ * perpendicular to the text flow (horizontal centring for horizontal text).
3962
+ */
3963
+ anchorCtr?: boolean;
3964
+ /**
3965
+ * `a:tcPr/@horzOverflow` (ST_TextHorzOverflowType): `clip` clips text at
3966
+ * the cell edge, `overflow` (the default) lets it spill.
3967
+ */
3968
+ horzOverflow?: 'clip' | 'overflow';
3969
+ }
3970
+ /**
3971
+ * Cell 3D bevel + lighting parsed from `a:tcPr/a:cell3D` (CT_Cell3D).
3972
+ *
3973
+ * Only the fields needed to render a plausible bevel treatment are captured;
3974
+ * verbatim round-trip of the full node is handled separately by the save path.
3975
+ *
3976
+ * @example
3977
+ * ```ts
3978
+ * const c3d: PptxTableCell3D = {
3979
+ * bevelWidth: 8,
3980
+ * bevelHeight: 8,
3981
+ * bevelPreset: 'circle',
3982
+ * material: 'plastic',
3983
+ * };
3984
+ * // => satisfies PptxTableCell3D
3985
+ * ```
3986
+ */
3987
+ interface PptxTableCell3D {
3988
+ /** Bevel width in px (from `a:bevel@w`, EMU converted). */
3989
+ bevelWidth?: number;
3990
+ /** Bevel height in px (from `a:bevel@h`, EMU converted). */
3991
+ bevelHeight?: number;
3992
+ /** Bevel preset name (`a:bevel@prst`, e.g. `circle`, `relaxedInset`). */
3993
+ bevelPreset?: string;
3994
+ /** Preset material (`a:cell3D@prstMaterial`, e.g. `plastic`, `metal`). */
3995
+ material?: string;
3996
+ /** Light rig type (`a:lightRig@rig`, e.g. `threePt`, `soft`). */
3997
+ lightRig?: string;
3998
+ /** Light rig direction (`a:lightRig@dir`, e.g. `tl`, `t`, `tr`). */
3999
+ lightRigDirection?: string;
3652
4000
  }
3653
4001
  /**
3654
4002
  * A single table cell with text content, optional style, and merge info.
@@ -3761,12 +4109,50 @@ interface PptxTableData {
3761
4109
  * ```
3762
4110
  */
3763
4111
  interface ParsedTableStyleFill {
3764
- /** Theme colour key (e.g. `accent1`, `dk1`). */
4112
+ /**
4113
+ * Theme colour key (e.g. `accent1`, `dk1`). Empty string when the fill is a
4114
+ * non-scheme fill (explicit sRGB, gradient, pattern, or none) that carries
4115
+ * no theme colour reference; the renderer then resolves {@link color},
4116
+ * {@link gradient}, {@link pattern}, or {@link noFill} instead.
4117
+ */
3765
4118
  schemeColor: string;
3766
4119
  /** Tint value (0-100 000). */
3767
4120
  tint?: number;
3768
4121
  /** Shade value (0-100 000). */
3769
4122
  shade?: number;
4123
+ /** Explicit sRGB hex colour (e.g. `#FF8800`) from `a:srgbClr`. */
4124
+ color?: string;
4125
+ /** The fill was `a:noFill`: renders transparent and clears lower layers. */
4126
+ noFill?: boolean;
4127
+ /** Gradient fill parsed from `a:gradFill`. */
4128
+ gradient?: ParsedTableStyleGradient;
4129
+ /** Preset pattern fill parsed from `a:pattFill`. */
4130
+ pattern?: ParsedTableStylePattern;
4131
+ }
4132
+ /** A single colour stop within a {@link ParsedTableStyleGradient}. */
4133
+ interface ParsedTableStyleGradientStop {
4134
+ /** Stop position as a percentage (0-100). */
4135
+ position: number;
4136
+ /** Stop colour (scheme or explicit sRGB). */
4137
+ fill: ParsedTableStyleFill;
4138
+ }
4139
+ /** A gradient fill parsed from a table style section's `a:gradFill`. */
4140
+ interface ParsedTableStyleGradient {
4141
+ /** Ordered colour stops. */
4142
+ stops: ParsedTableStyleGradientStop[];
4143
+ /** Linear gradient angle in degrees (from `a:lin@ang`, 60000ths -> deg). */
4144
+ angle?: number;
4145
+ /** Gradient family: linear (`a:lin`) or radial (`a:path`). */
4146
+ type: 'linear' | 'radial';
4147
+ }
4148
+ /** A preset pattern fill parsed from a table style section's `a:pattFill`. */
4149
+ interface ParsedTableStylePattern {
4150
+ /** OOXML preset name (e.g. `ltDnDiag`) from `a:pattFill@prst`. */
4151
+ preset: string;
4152
+ /** Foreground colour (`a:fgClr`). */
4153
+ foreground?: ParsedTableStyleFill;
4154
+ /** Background colour (`a:bgClr`). */
4155
+ background?: ParsedTableStyleFill;
3770
4156
  }
3771
4157
  /**
3772
4158
  * A single entry in the parsed table style map.
@@ -3793,12 +4179,67 @@ interface ParsedTableStyleText {
3793
4179
  bold?: boolean;
3794
4180
  /** Font italic. */
3795
4181
  italic?: boolean;
4182
+ /** Font underline (from `a:tcTxStyle@u`, any value other than `none`). */
4183
+ underline?: boolean;
3796
4184
  /** Font colour as theme scheme key. */
3797
4185
  fontSchemeColor?: string;
3798
4186
  /** Font colour tint (0-100 000). */
3799
4187
  fontTint?: number;
3800
4188
  /** Font colour shade (0-100 000). */
3801
4189
  fontShade?: number;
4190
+ /** Explicit sRGB hex font colour (e.g. `#FF0000`) from `a:srgbClr`. */
4191
+ fontColor?: string;
4192
+ /** Typeface from `a:font@typeface` (latin font). */
4193
+ fontFace?: string;
4194
+ /** Font-collection index from `a:fontRef@idx` (`minor`, `major`, `none`). */
4195
+ fontRefIdx?: string;
4196
+ }
4197
+ /**
4198
+ * A single border side within a table style's `a:tcStyle/a:tcBdr`.
4199
+ *
4200
+ * Corresponds to one of `a:left`, `a:right`, `a:top`, `a:bottom`,
4201
+ * `a:insideH`, `a:insideV`, `a:tl2br`, `a:bl2tr` (each a
4202
+ * `CT_ThemeableLineStyle` wrapping an `a:ln`).
4203
+ *
4204
+ * @example
4205
+ * ```ts
4206
+ * const side: ParsedTableStyleBorder = {
4207
+ * width: 1,
4208
+ * dash: 'solid',
4209
+ * fill: { schemeColor: 'lt1' },
4210
+ * };
4211
+ * // => satisfies ParsedTableStyleBorder
4212
+ * ```
4213
+ */
4214
+ interface ParsedTableStyleBorder {
4215
+ /** Line width in px (converted from the `a:ln@w` EMU value). */
4216
+ width?: number;
4217
+ /** OOXML `a:prstDash@val` (e.g. `solid`, `dash`, `sysDot`). */
4218
+ dash?: string;
4219
+ /** Border colour as a theme scheme fill (from `a:ln/a:solidFill/a:schemeClr`). */
4220
+ fill?: ParsedTableStyleFill;
4221
+ /** Explicit hex colour when the line used `a:srgbClr` (e.g. `#808080`). */
4222
+ color?: string;
4223
+ /** The line was `a:noFill` - an explicit "no border" that clears lower layers. */
4224
+ noFill?: boolean;
4225
+ }
4226
+ /**
4227
+ * The set of border sides parsed from a table style section's
4228
+ * `a:tcStyle/a:tcBdr` element.
4229
+ */
4230
+ interface ParsedTableStyleBorders {
4231
+ left?: ParsedTableStyleBorder;
4232
+ right?: ParsedTableStyleBorder;
4233
+ top?: ParsedTableStyleBorder;
4234
+ bottom?: ParsedTableStyleBorder;
4235
+ /** Interior horizontal borders between rows in the region. */
4236
+ insideH?: ParsedTableStyleBorder;
4237
+ /** Interior vertical borders between columns in the region. */
4238
+ insideV?: ParsedTableStyleBorder;
4239
+ /** Top-left to bottom-right diagonal. */
4240
+ tl2br?: ParsedTableStyleBorder;
4241
+ /** Bottom-left to top-right diagonal. */
4242
+ bl2tr?: ParsedTableStyleBorder;
3802
4243
  }
3803
4244
  /**
3804
4245
  * Table background style (CT_TableBackgroundStyle, ECMA-376 §21.1.3.7).
@@ -3834,6 +4275,24 @@ interface ParsedTableStyleEntry {
3834
4275
  swCellFill?: ParsedTableStyleFill;
3835
4276
  neCellFill?: ParsedTableStyleFill;
3836
4277
  nwCellFill?: ParsedTableStyleFill;
4278
+ /**
4279
+ * Per-role border styling from `a:tcStyle/a:tcBdr`. These supply the
4280
+ * gridlines/edges a styled table inherits from its table style when the
4281
+ * cells carry no explicit per-cell `a:lnX` overrides.
4282
+ */
4283
+ wholeTblBorders?: ParsedTableStyleBorders;
4284
+ firstRowBorders?: ParsedTableStyleBorders;
4285
+ lastRowBorders?: ParsedTableStyleBorders;
4286
+ firstColBorders?: ParsedTableStyleBorders;
4287
+ lastColBorders?: ParsedTableStyleBorders;
4288
+ band1HBorders?: ParsedTableStyleBorders;
4289
+ band2HBorders?: ParsedTableStyleBorders;
4290
+ band1VBorders?: ParsedTableStyleBorders;
4291
+ band2VBorders?: ParsedTableStyleBorders;
4292
+ seCellBorders?: ParsedTableStyleBorders;
4293
+ swCellBorders?: ParsedTableStyleBorders;
4294
+ neCellBorders?: ParsedTableStyleBorders;
4295
+ nwCellBorders?: ParsedTableStyleBorders;
3837
4296
  /** Per-role text styling from a:tcTxStyle. */
3838
4297
  wholeTblText?: ParsedTableStyleText;
3839
4298
  firstRowText?: ParsedTableStyleText;
@@ -4399,6 +4858,16 @@ interface PptxHandoutMaster {
4399
4858
  /** Colour map from `<p:clrMap>` (12 alias attributes). Applied at save time. */
4400
4859
  clrMap?: Record<string, string>;
4401
4860
  }
4861
+ /**
4862
+ * Active tab within the master view sidebar.
4863
+ *
4864
+ * @example
4865
+ * ```ts
4866
+ * const tab: MasterViewTab = "slides";
4867
+ * // => "slides" — one of: "slides" | "notes" | "handout"
4868
+ * ```
4869
+ */
4870
+ type MasterViewTab = 'slides' | 'notes' | 'handout';
4402
4871
  /**
4403
4872
  * Structured slide master data.
4404
4873
  *
@@ -4631,10 +5100,30 @@ interface PptxNativeAnimation {
4631
5100
  presetClass?: 'entr' | 'exit' | 'emph' | 'path';
4632
5101
  /** Effect preset sub-type identifier. */
4633
5102
  presetId?: number;
5103
+ /**
5104
+ * Effect preset direction/variant code from `p:cTn/@presetSubtype`
5105
+ * (ECMA-376 CT_TLCommonTimeNodeData). For Fly In/Out this encodes the
5106
+ * edge/corner the object travels from as a bitmask (1=top, 2=right,
5107
+ * 4=bottom, 8=left; corners combine bits). Absent means the preset default.
5108
+ */
5109
+ presetSubtype?: number;
4634
5110
  /** Duration in milliseconds. */
4635
5111
  durationMs?: number;
4636
5112
  /** Delay in milliseconds. */
4637
5113
  delayMs?: number;
5114
+ /**
5115
+ * Acceleration fraction in the range 0..1, parsed from `p:cTn/@accel`
5116
+ * (ST_PositiveFixedPercentage, stored as 1000ths of a percent). A non-zero
5117
+ * value means the effect eases in (starts slow). Absent means no easing-in.
5118
+ */
5119
+ accel?: number;
5120
+ /**
5121
+ * Deceleration fraction in the range 0..1, parsed from `p:cTn/@decel`.
5122
+ * A non-zero value means the effect eases out (ends slow). Absent means no
5123
+ * easing-out. When both {@link accel} and {@link decel} are set, the effect
5124
+ * eases in and out.
5125
+ */
5126
+ decel?: number;
4638
5127
  /** Trigger delay in milliseconds (for afterDelay). */
4639
5128
  triggerDelayMs?: number;
4640
5129
  /** SVG path string for motion path animations (`p:animMotion/@path`). */
@@ -4727,6 +5216,14 @@ interface PptxNativeAnimation {
4727
5216
  * that aren't OLE charts).
4728
5217
  */
4729
5218
  graphicBuild?: string;
5219
+ /**
5220
+ * OLE-embedded chart build attribute (`p:bldOleChart/@bld`) when this
5221
+ * animation stages an OLE chart graphic frame. Values follow
5222
+ * ST_TLOleChartBuildType: `allAtOnce`, `series`, `category`, `seriesEl`,
5223
+ * `categoryEl`. Lets a staged-reveal renderer build the chart by series /
5224
+ * category / element to match PowerPoint, rather than as one whole element.
5225
+ */
5226
+ oleChartBuild?: string;
4730
5227
  /** Schema-accurate `p:bldGraphic/p:bldAsOne|p:bldSub` representation. */
4731
5228
  graphicBuildProperties?: PptxGraphicBuild;
4732
5229
  /**
@@ -5216,6 +5713,18 @@ interface PptxAppProperties {
5216
5713
  template?: string;
5217
5714
  /** Hyperlink base URL. */
5218
5715
  hyperlinkBase?: string;
5716
+ /** Document security bitmask (`<DocSecurity>`). */
5717
+ docSecurity?: number;
5718
+ /** Number of multimedia clips (`<MMClips>`). */
5719
+ mmClips?: number;
5720
+ /** Whether thumbnail images were scaled to fit (`<ScaleCrop>`). */
5721
+ scaleCrop?: boolean;
5722
+ /** Whether hyperlinks are current (`<LinksUpToDate>`). */
5723
+ linksUpToDate?: boolean;
5724
+ /** Whether the document is shared (`<SharedDoc>`). */
5725
+ sharedDoc?: boolean;
5726
+ /** Whether hyperlinks changed since last save (`<HyperlinksChanged>`). */
5727
+ hyperlinksChanged?: boolean;
5219
5728
  }
5220
5729
  //#endregion
5221
5730
  //#region src/core/types/presentation-print-properties.d.ts
@@ -5506,7 +6015,7 @@ interface PptxTheme {
5506
6015
  * // => "morph" — one of 40+ transition effects
5507
6016
  * ```
5508
6017
  */
5509
- type PptxTransitionType = 'none' | 'cut' | 'fade' | 'push' | 'wipe' | 'split' | 'randomBar' | 'blinds' | 'checker' | 'circle' | 'comb' | 'cover' | 'diamond' | 'dissolve' | 'plus' | 'pull' | 'random' | 'strips' | 'uncover' | 'wedge' | 'wheel' | 'zoom' | 'newsflash' | 'morph' | 'conveyor' | 'doors' | 'ferris' | 'flash' | 'flythrough' | 'gallery' | 'glitter' | 'honeycomb' | 'pan' | 'prism' | 'reveal' | 'ripple' | 'shred' | 'switch' | 'vortex' | 'warp' | 'wheelReverse' | 'window' | 'cube' | 'flip' | 'rotate' | 'orbit';
6018
+ type PptxTransitionType = 'none' | 'cut' | 'fade' | 'push' | 'wipe' | 'split' | 'randomBar' | 'blinds' | 'checker' | 'circle' | 'comb' | 'cover' | 'diamond' | 'dissolve' | 'plus' | 'pull' | 'random' | 'strips' | 'uncover' | 'wedge' | 'wheel' | 'zoom' | 'newsflash' | 'morph' | 'conveyor' | 'doors' | 'ferris' | 'flash' | 'flythrough' | 'gallery' | 'glitter' | 'honeycomb' | 'pan' | 'prism' | 'reveal' | 'ripple' | 'shred' | 'switch' | 'vortex' | 'warp' | 'wheelReverse' | 'window' | 'cube' | 'flip' | 'rotate' | 'orbit' | 'fallOver' | 'drape' | 'curtains' | 'wind' | 'prestige' | 'fracture' | 'crush' | 'peelOff' | 'pageCurlDouble' | 'pageCurlSingle' | 'airplane' | 'origami';
5510
6019
  /** Split orientation from OOXML `@_orient`. */
5511
6020
  type PptxSplitOrientation = 'horz' | 'vert';
5512
6021
  /** Schema-defined `ST_TransitionSpeed` values. */
@@ -5720,6 +6229,21 @@ interface PptxActiveXControl {
5720
6229
  name?: string;
5721
6230
  /** Shape ID this control is linked to (from @spid). */
5722
6231
  shapeId?: string;
6232
+ /** X position (px) of the control's fallback picture, if present. */
6233
+ x?: number;
6234
+ /** Y position (px) of the control's fallback picture, if present. */
6235
+ y?: number;
6236
+ /** Width (px) of the control's fallback picture, if present. */
6237
+ width?: number;
6238
+ /** Height (px) of the control's fallback picture, if present. */
6239
+ height?: number;
6240
+ /**
6241
+ * Relationship ID of the control's static fallback picture
6242
+ * (`mc:AlternateContent > mc:Fallback > p:pic > p:blipFill > a:blip@r:embed`).
6243
+ * Renderers resolve this to an image so a control shows its last static
6244
+ * frame instead of a blank area (the live ActiveX cannot run in a viewer).
6245
+ */
6246
+ fallbackImageRelId?: string;
5723
6247
  /** Raw XML for round-trip preservation. */
5724
6248
  rawXml?: XmlObject;
5725
6249
  }
@@ -5846,6 +6370,13 @@ interface PptxSlide {
5846
6370
  customerData?: PptxCustomerData[];
5847
6371
  /** ActiveX control references from `p:controls` on this slide. */
5848
6372
  activeXControls?: PptxActiveXControl[];
6373
+ /**
6374
+ * Shapes parsed from a referenced legacy VML drawing part
6375
+ * (`ppt/drawings/vmlDrawing*.vml`, linked via a `legacyDrawing`
6376
+ * relationship). These are read-only render hints: the VML part itself is
6377
+ * preserved verbatim on save, so this field is not re-serialized.
6378
+ */
6379
+ legacyVmlElements?: PptxElement[];
5849
6380
  /** Per-slide header/footer flags from `<p:hf>` (P-H3). */
5850
6381
  headerFooterFlags?: PptxHeaderFooterFlags;
5851
6382
  /** Server-backed slide synchronization metadata stored in a related OPC part. */
@@ -5954,12 +6485,6 @@ interface PptxPresentationProperties {
5954
6485
  showSubtitles?: boolean;
5955
6486
  /** Typed `p:prnPr` settings. Set to null during save to remove the element. */
5956
6487
  printProperties?: PptxPresentationPrintProperties | null;
5957
- /** @deprecated Use `printProperties.printWhat`; retained as a handout compatibility alias. */
5958
- printSlidesPerPage?: number;
5959
- /** @deprecated Use `printProperties.frameSlides`. */
5960
- printFrameSlides?: boolean;
5961
- /** @deprecated Use `printProperties.colorMode`. */
5962
- printColorMode?: 'clr' | 'gray' | 'bw';
5963
6488
  /** Most-recently-used colours from the presentation palette. */
5964
6489
  mruColors?: string[];
5965
6490
  /** Grid spacing in EMUs (cx, cy). Default is 914400 / 8 = 114300. */
@@ -7911,6 +8436,262 @@ interface CollaborationConfig {
7911
8436
  */
7912
8437
  writeBackDebounceMs?: number;
7913
8438
  }
8439
+ //#endregion
8440
+ //#region src/render/animation-authoring.d.ts
8441
+ /** One of the three animation buckets a preset can occupy on an element. */
8442
+ type AnimationGroup = 'entrance' | 'emphasis' | 'exit';
8443
+ /**
8444
+ * Normalized staged-reveal mode for a chart graphic frame, derived from the
8445
+ * OOXML `a:bldChart/@bld` (or `p:bldOleChart/@bld`) token:
8446
+ * - `asOne` the whole chart appears at once (`allAtOnce`).
8447
+ * - `bySeries` one data series is revealed per stage (`series`).
8448
+ * - `byCategory` one category is revealed per stage (`category`).
8449
+ * - `byElement` one series/category ELEMENT is revealed per stage
8450
+ * (`seriesElement` / `categoryElement`).
8451
+ */
8452
+ type ChartBuildMode = 'asOne' | 'bySeries' | 'byCategory' | 'byElement';
8453
+ /**
8454
+ * Normalized staged-reveal mode for a SmartArt diagram, derived from the OOXML
8455
+ * `a:bldDgm/@bld` or `p:bldDgm/@bld` token:
8456
+ * - `asOne` the whole diagram appears at once (`whole` / `allAtOnce`).
8457
+ * - `byOne` one node is revealed per stage (`one`, and the assorted
8458
+ * `depthBy*` / `breadthBy*` / directional traversals).
8459
+ * - `byLvl` levels are revealed one element at a time (`lvlOne`).
8460
+ * - `byLvlAtOnce` a whole level is revealed per stage (`lvlAtOnce`).
8461
+ */
8462
+ type DiagramBuildMode = 'asOne' | 'byOne' | 'byLvl' | 'byLvlAtOnce';
8463
+ /**
8464
+ * Playback-time staged-build state surfaced on {@link ElementAnimationState}.
8465
+ * `progress` is the 0..1 fraction of the build revealed at the current playback
8466
+ * time; a consumer maps it to its own item COUNT (see `revealedStageCount`).
8467
+ */
8468
+ type ElementBuildState = {
8469
+ kind: 'chart';
8470
+ mode: ChartBuildMode;
8471
+ progress: number;
8472
+ } | {
8473
+ kind: 'diagram';
8474
+ mode: DiagramBuildMode;
8475
+ progress: number;
8476
+ };
8477
+ /** Snapshot of a single element's animation state at a point in the timeline. */
8478
+ interface ElementAnimationState {
8479
+ /** Whether the element should be visible. */
8480
+ visible: boolean;
8481
+ /** CSS animation shorthand to apply (undefined = no active animation). */
8482
+ cssAnimation: string | undefined;
8483
+ /**
8484
+ * Staged-build reveal state, present only when the active animation builds a
8485
+ * chart or SmartArt diagram in stages (`p:bldChart` / `p:bldDgm`) rather than
8486
+ * revealing the whole element at once. A staged renderer multiplies
8487
+ * `build.progress` (0..1) by its own series / category / level COUNT to
8488
+ * decide how many stages are revealed at the current playback time; see
8489
+ * {@link import('./animation-build').revealedStageCount}. Absent for ordinary
8490
+ * whole-element entrances, so existing renderers are unaffected.
8491
+ */
8492
+ build?: ElementBuildState;
8493
+ /**
8494
+ * True when an active `p:animClr` color animation targets this shape's fill.
8495
+ * A vector renderer should then paint the fill with `fill: inherit` so the
8496
+ * wrapper-level colour keyframes cascade to the SVG path. Absent/false means
8497
+ * no active fill-colour animation.
8498
+ */
8499
+ animatesFill?: boolean;
8500
+ /**
8501
+ * True when an active `p:animClr` color animation targets this shape's
8502
+ * stroke. A vector renderer should then paint the stroke with
8503
+ * `stroke: inherit`. Absent/false means no active stroke-colour animation.
8504
+ */
8505
+ animatesStroke?: boolean;
8506
+ }
8507
+ //#endregion
8508
+ //#region src/render/element-align.d.ts
8509
+ /**
8510
+ * Pure geometry helpers for the align / distribute editor operations.
8511
+ *
8512
+ * These functions operate over a list of slide elements (anything carrying the
8513
+ * `{ id, x, y, width, height }` bounding-box fields of {@link PptxElement}) and
8514
+ * return a `Map` keyed by element `id` describing the *new* position(s) for the
8515
+ * elements that need to move. Elements that already sit on the target edge (or
8516
+ * the two outer-most elements during distribution) are still included with
8517
+ * their unchanged coordinate so callers can apply the whole map uniformly — the
8518
+ * map only ever contains the axis that the operation touches.
8519
+ *
8520
+ * The helpers are deliberately framework-agnostic: no DOM, no Vue reactivity,
8521
+ * no side effects. The host wires them into the editor by feeding the current
8522
+ * selection in and applying the returned `Map` via its element-transform
8523
+ * operation (one batched history entry per call).
8524
+ */
8525
+ /** Edge / centre that {@link alignElements} can snap a selection to. */
8526
+ type AlignEdge = 'left' | 'centerH' | 'right' | 'top' | 'middle' | 'bottom';
8527
+ /** Axis along which {@link distributeElements} evenly spaces a selection. */
8528
+ type DistributeAxis = 'horizontal' | 'vertical';
8529
+ /** The eight resize handles, named by compass direction. */
8530
+ type ResizeHandleId = 'nw' | 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w';
8531
+ /** A marquee drag described by its start and current corner (any order). */
8532
+ interface MarqueeRect {
8533
+ startX: number;
8534
+ startY: number;
8535
+ currentX: number;
8536
+ currentY: number;
8537
+ }
8538
+ /** Minimum section metadata needed to build sidebar groups. */
8539
+ interface SectionGroupDescriptor {
8540
+ id: string;
8541
+ name: string;
8542
+ collapsed?: boolean;
8543
+ color?: string;
8544
+ }
8545
+ /** A declared section paired with its slides, or the trailing ungrouped slides. */
8546
+ interface SectionSlideGroup<TSection extends SectionGroupDescriptor = PptxSection> {
8547
+ section: TSection | undefined;
8548
+ slides: PptxSlide[];
8549
+ slideIndexes: number[];
8550
+ }
8551
+ /** A snap alignment line: `axis: 'v'` is a vertical line at x=`position`. */
8552
+ interface SnapLine {
8553
+ axis: 'h' | 'v';
8554
+ position: number;
8555
+ }
8556
+ //#endregion
8557
+ //#region src/render/collaboration-presence.d.ts
8558
+ /** Connection lifecycle states for the Yjs WebSocket provider. */
8559
+ type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'error';
8560
+ /** A single remote collaborator's cursor, in unscaled slide coordinates. */
8561
+ interface RemoteCursor {
8562
+ /** Stable id for the remote client (awareness clientId or peer id). */
8563
+ clientId: number | string;
8564
+ /** Display name shown in the label chip. */
8565
+ userName: string;
8566
+ /** Cursor + chip colour (any CSS colour string). */
8567
+ color: string;
8568
+ /** Unscaled slide-space X coordinate (px). */
8569
+ x: number;
8570
+ /** Unscaled slide-space Y coordinate (px). */
8571
+ y: number;
8572
+ /** Optional ids of elements this user has selected. */
8573
+ selectionIds?: string[];
8574
+ }
8575
+ /**
8576
+ * Presence data for a remote collaborator, sanitised from the awareness
8577
+ * protocol. Returned by {@link sanitizePresence}; coordinates are in unscaled
8578
+ * slide pixels, clamped to the supplied canvas bounds.
8579
+ */
8580
+ interface SanitizedPresence {
8581
+ clientId: number;
8582
+ userName: string;
8583
+ userAvatar?: string;
8584
+ userColor: string;
8585
+ activeSlideIndex: number;
8586
+ cursorX: number;
8587
+ cursorY: number;
8588
+ lastUpdated: string;
8589
+ selectedElementId?: string;
8590
+ role?: CollaborationRole;
8591
+ }
8592
+ //#endregion
8593
+ //#region src/render/collaboration-presence-publisher.d.ts
8594
+ /**
8595
+ * Structural interface for the lazily-imported Yjs awareness surface. Every
8596
+ * binding's live `y-protocols/awareness` `Awareness` instance satisfies this.
8597
+ */
8598
+ interface AwarenessLike {
8599
+ clientID?: number;
8600
+ setLocalStateField: (field: string, value: unknown) => void;
8601
+ getStates: () => Map<number, Record<string, unknown>>;
8602
+ on: (event: string, cb: () => void) => void;
8603
+ off?: (event: string, cb: () => void) => void;
8604
+ }
8605
+ //#endregion
8606
+ //#region src/render/collaboration-text-codec.d.ts
8607
+ /**
8608
+ * collaboration-text-codec.ts: TextSegment[] <-> Y.Text delta codec used by the
8609
+ * collaboration sync layer. Split out of collaboration-sync.ts to keep both
8610
+ * modules focused.
8611
+ *
8612
+ * Exports:
8613
+ * - DeltaOp / YTextLike: structural Yjs text interfaces (no yjs import)
8614
+ * - encodeTextBody: write TextSegment[] into a live YTextLike
8615
+ * - encodeSegmentsToDelta: pure simulation of the delta Y.Text would produce
8616
+ * - decodeDelta / decodeTextBody: delta -> TextSegment[]
8617
+ * - isYTextLike: runtime guard
8618
+ */
8619
+ interface DeltaOp {
8620
+ insert?: unknown;
8621
+ attributes?: Record<string, unknown>;
8622
+ }
8623
+ interface YTextLike {
8624
+ insert: (index: number, text: string, attrs?: Record<string, string>) => void;
8625
+ toDelta: () => DeltaOp[];
8626
+ toString: () => string;
8627
+ }
8628
+ //#endregion
8629
+ //#region src/render/collaboration-sync.d.ts
8630
+ interface YMapLike {
8631
+ get: (key: string) => unknown;
8632
+ set: (key: string, value: unknown) => void;
8633
+ delete: (key: string) => void;
8634
+ forEach: (cb: (value: unknown, key: string) => void) => void;
8635
+ }
8636
+ /** Shape of the Yjs transaction passed to (deep) observers. */
8637
+ interface YTransactionLike {
8638
+ origin?: unknown;
8639
+ }
8640
+ type YDeepObserver = (events?: unknown, transaction?: YTransactionLike) => void;
8641
+ interface YArrayLike {
8642
+ readonly length: number;
8643
+ get: (index: number) => unknown;
8644
+ push: (items: unknown[]) => void;
8645
+ delete: (index: number, length?: number) => void;
8646
+ insert: (index: number, items: unknown[]) => void;
8647
+ toArray: () => unknown[];
8648
+ observe: (handler: () => void) => void;
8649
+ unobserve: (handler: () => void) => void;
8650
+ observeDeep: (handler: YDeepObserver) => void;
8651
+ unobserveDeep: (handler: YDeepObserver) => void;
8652
+ }
8653
+ interface YDocLike {
8654
+ getMap: (name: string) => YMapLike;
8655
+ getArray: (name: string) => YArrayLike;
8656
+ transact: (fn: () => void, origin?: unknown) => void;
8657
+ }
8658
+ interface YjsFactories {
8659
+ createMap: () => YMapLike;
8660
+ createArray: () => YArrayLike;
8661
+ createText: () => YTextLike;
8662
+ }
8663
+ //#endregion
8664
+ //#region src/render/slide-compare.d.ts
8665
+ type SlideDiffStatus = 'added' | 'removed' | 'changed' | 'unchanged';
8666
+ type ElementChangeKind = 'added' | 'removed' | 'moved' | 'resized' | 'textChanged';
8667
+ interface ElementChange {
8668
+ elementId: string;
8669
+ label: string;
8670
+ kind: ElementChangeKind;
8671
+ description: string;
8672
+ }
8673
+ interface SlideDiff {
8674
+ status: SlideDiffStatus;
8675
+ /** Index in the base (current) presentation, or -1 for added slides. */
8676
+ baseIndex: number;
8677
+ /** Index in the compare (other) presentation, or -1 for removed slides. */
8678
+ compareIndex: number;
8679
+ /** The base slide data (undefined for added slides). */
8680
+ baseSlide?: PptxSlide;
8681
+ /** The compare slide data (undefined for removed slides). */
8682
+ compareSlide?: PptxSlide;
8683
+ /** Per-element changes when status is `changed`. */
8684
+ changes: ElementChange[];
8685
+ }
8686
+ interface CompareResult {
8687
+ diffs: SlideDiff[];
8688
+ baseSlideCount: number;
8689
+ compareSlideCount: number;
8690
+ addedCount: number;
8691
+ removedCount: number;
8692
+ changedCount: number;
8693
+ unchangedCount: number;
8694
+ }
7914
8695
  /**
7915
8696
  * A font supplied by the host application. The package never ships fonts:
7916
8697
  * applications provide a licensed URL, data URL, or blob URL for their users.
@@ -7922,6 +8703,105 @@ interface ViewerFontSource {
7922
8703
  weight?: string | number;
7923
8704
  style?: 'normal' | 'italic';
7924
8705
  }
8706
+ /** The configuration emitted when a broadcast starts. */
8707
+ interface BroadcastConfig {
8708
+ roomId: string;
8709
+ serverUrl: string;
8710
+ /** Derived from serverUrl: empty server means peer-to-peer (webrtc). */
8711
+ transport?: CollaborationTransport;
8712
+ }
8713
+ //#endregion
8714
+ //#region src/render/presentation-session-types.d.ts
8715
+ interface PresentationSnapshot {
8716
+ slideIndex: number;
8717
+ buildStep: number;
8718
+ sequence: number;
8719
+ blackout: 'none' | 'black' | 'white';
8720
+ paused: boolean;
8721
+ elapsedMs: number;
8722
+ zoom?: PresentationZoomState;
8723
+ pointer?: PresentationPointerState;
8724
+ inkStrokes?: PresentationInkStroke[];
8725
+ caption?: string;
8726
+ subtitlesVisible?: boolean;
8727
+ }
8728
+ interface PresentationZoomState {
8729
+ scale: number;
8730
+ originX: number;
8731
+ originY: number;
8732
+ }
8733
+ type PresentationPointerTool = 'none' | 'laser' | 'pen' | 'highlighter' | 'eraser';
8734
+ interface PresentationPointerState {
8735
+ tool: PresentationPointerTool;
8736
+ x: number;
8737
+ y: number;
8738
+ color: string;
8739
+ }
8740
+ interface PresentationInkPoint {
8741
+ x: number;
8742
+ y: number;
8743
+ }
8744
+ interface PresentationInkStroke {
8745
+ id: string;
8746
+ slideIndex: number;
8747
+ tool: 'pen' | 'highlighter';
8748
+ color: string;
8749
+ width: number;
8750
+ points: PresentationInkPoint[];
8751
+ }
8752
+ //#endregion
8753
+ //#region src/render/find-replace.d.ts
8754
+ /** Identifies a single match of the find query at segment-level precision. */
8755
+ interface FindResult {
8756
+ /** Zero-based index of the slide in the slides array. */
8757
+ slideIndex: number;
8758
+ /** Id of the element that contains the match. */
8759
+ elementId: string;
8760
+ /** Zero-based index of the text segment within the element's `textSegments`. */
8761
+ segmentIndex: number;
8762
+ /** Character offset of the match start within the segment text. */
8763
+ startOffset: number;
8764
+ /** Number of characters matched (equals `query.length`). */
8765
+ length: number;
8766
+ }
8767
+ //#endregion
8768
+ //#region src/render/ink-drawing.d.ts
8769
+ /** A 2D point in stage-local coordinates. */
8770
+ interface InkPoint {
8771
+ x: number;
8772
+ y: number;
8773
+ }
8774
+ //#endregion
8775
+ //#region src/render/mobile-chrome.d.ts
8776
+ /**
8777
+ * Pure helper logic for mobile chrome state, shared by every binding.
8778
+ *
8779
+ * These helpers capture the sheet open/close state machine that governs which
8780
+ * sheet is visible at any given time and which bottom-bar button appears active.
8781
+ * Keeping this logic as pure functions makes it straightforward to test and
8782
+ * trivial to adapt when each binding wires the components together.
8783
+ */
8784
+ /** All mobile sheets that can be open at one time. */
8785
+ type MobileSheetKey = 'slides' | 'menu' | 'insert' | 'inspector' | 'comments' | 'notes' | null;
8786
+ /** In-memory clipboard payload stored when an element is copied or cut. */
8787
+ interface ElementClipboardPayload {
8788
+ element: PptxElement;
8789
+ isTemplate: boolean;
8790
+ }
8791
+ //#endregion
8792
+ //#region src/render/template-editing.d.ts
8793
+ type TemplateElementMap = Record<string, PptxElement[]>;
8794
+ //#endregion
8795
+ //#region src/render/viewer-preferences.d.ts
8796
+ /** Framework-neutral viewer preferences surfaced by Settings dialogs. */
8797
+ interface ViewerPreferences {
8798
+ autoSave: boolean;
8799
+ spellCheck: boolean;
8800
+ showGrid: boolean;
8801
+ showRulers: boolean;
8802
+ snapToGrid: boolean;
8803
+ reducedMotion: boolean;
8804
+ }
7925
8805
  /**
7926
8806
  * Optional hook point for hosts that want to wire a real sign-in flow into
7927
8807
  * File > Account. Disabled by default: the Account page renders nothing
@@ -7997,22 +8877,243 @@ interface PrintSettings {
7997
8877
  }
7998
8878
 
7999
8879
  //#endregion
8000
- //#region src/i18n/locale-catalog.d.ts
8001
- /** One selectable entry in the viewer chrome's built-in language picker (File > Options > Language). */
8002
- interface LocaleCatalogEntry {
8003
- /** BCP-47-ish locale code, e.g. `'en'`, `'fr'`. Matches `pptx-viewer-locales`' exports. */
8004
- code: string;
8005
- /** English display name, used before a translation dictionary for the target locale is loaded. */
8006
- label: string;
8007
- /** The locale's own name for itself, e.g. `'Français'` for `fr`. */
8008
- nativeLabel: string;
8880
+ //#region src/ai/change-animator.d.ts
8881
+ /** Host-tunable options for how AI edits are animated on the canvas. */
8882
+ interface AiChangeAnimationConfig {
8883
+ /** Master switch. Default true. */
8884
+ enabled?: boolean;
8885
+ /** How long the motion + glow plays, in ms. Default 900. */
8886
+ durationMs?: number;
8887
+ /** Draw the pulsing glow highlight on changed elements. Default true. */
8888
+ glow?: boolean;
8889
+ /** Glide old->new bounds and cross-fade colours. Default true. */
8890
+ tween?: boolean;
8891
+ /** Accent colour (any CSS colour) for the glow/ghosts. Default a blue. */
8892
+ color?: string;
8009
8893
  }
8010
-
8011
- /**
8012
- * Animated-GIF export capture/encode pipeline. All the pure logic is shared:
8013
- * `planGifFrames` derives the per-slide frame delays (default duration +
8014
- * per-slide overrides), `clampGifDimensions` bounds the output size, and
8015
- * `encodeGif` (median-cut quantisation + LZW GIF89a) produces the bytes with
8894
+ //#endregion
8895
+ //#region src/ai/config.d.ts
8896
+ /** The UI message shape exchanged with the assistant. Alias of the SDK type. */
8897
+ type PptxAiUIMessage = UIMessage;
8898
+ /**
8899
+ * Canonical name of every tool the assistant can call. Document tools mirror the
8900
+ * `pptx-viewer-mcp` server exactly (they ARE the same functions, run against the
8901
+ * live deck); the viewer-only tools (navigation, deck outline, element/notes
8902
+ * readers, table merge) have no MCP counterpart.
8903
+ */
8904
+ type PptxAiToolName = 'get_deck_overview' | 'get_slide' | 'get_element' | 'get_speaker_notes' | 'find_text' | 'get_theme' | 'go_to_slide' | 'select_elements' | 'merge_tables' | 'get_metadata' | 'get_layouts' | 'find_placeholders' | 'get_presentation_properties' | 'run_accessibility_check' | 'convert_to_markdown' | 'add_element' | 'update_element' | 'delete_elements' | 'arrange_elements' | 'clone_element' | 'set_element_animation' | 'group_elements' | 'ungroup_elements' | 'batch_update_elements' | 'update_element_style' | 'replace_geometry' | 'set_element_lock' | 'manage_hyperlinks' | 'replace_text' | 'manage_comments' | 'update_table_cells' | 'manage_table_structure' | 'create_chart' | 'update_chart' | 'add_chart_series' | 'remove_chart_series' | 'update_chart_series_data' | 'manage_smart_art' | 'apply_template' | 'add_slide' | 'duplicate_slide' | 'delete_slides' | 'reorder_slides' | 'update_slide_properties' | 'set_slide_transition' | 'apply_theme_preset' | 'update_theme_colors' | 'update_theme_fonts' | 'set_canvas_size' | 'update_metadata' | 'manage_sections' | 'update_presentation_properties' | 'apply_layout';
8905
+ type Resolvable<T> = T | (() => T | Promise<T>);
8906
+ /** How the assistant reaches a language model. */
8907
+ type PptxAiConnection =
8908
+ /**
8909
+ * Post messages to a host backend route (recommended for production so the
8910
+ * provider API key stays server-side). Maps to `DefaultChatTransport`.
8911
+ */
8912
+ {
8913
+ kind: 'endpoint';
8914
+ api: string;
8915
+ headers?: Resolvable<Record<string, string>>;
8916
+ body?: Resolvable<Record<string, unknown>>;
8917
+ credentials?: RequestCredentials;
8918
+ fetch?: typeof globalThis.fetch;
8919
+ } |
8920
+ /**
8921
+ * Run a language model in-process in the browser (bring-your-own key /
8922
+ * local model). Maps to a `ToolLoopAgent` behind a `DirectChatTransport`.
8923
+ */
8924
+ {
8925
+ kind: 'model';
8926
+ model: LanguageModel;
8927
+ system?: string;
8928
+ maxSteps?: number;
8929
+ } |
8930
+ /** Provide a fully-constructed transport (advanced / testing escape hatch). */
8931
+ {
8932
+ kind: 'transport';
8933
+ transport: ChatTransport<PptxAiUIMessage>;
8934
+ };
8935
+ /** How writes proposed by the assistant reach the document. */
8936
+ type PptxAiWritePolicy = 'stage' | 'approve' | 'auto';
8937
+ /** Which deck context is fed to the model with each turn. */
8938
+ type PptxAiContextStrategy = 'outline' | 'current-slide' | 'none';
8939
+ /** Optional per-session history persistence hooks. */
8940
+ interface PptxAiHistoryHooks {
8941
+ load?(id: string): Promise<PptxAiUIMessage[]>;
8942
+ save?(id: string, messages: PptxAiUIMessage[]): Promise<void>;
8943
+ }
8944
+ /** Complete host configuration for an AI chat session. */
8945
+ interface PptxAiConfig {
8946
+ connection: PptxAiConnection;
8947
+ /** Extra host instructions appended to the base system prompt. */
8948
+ systemPromptExtras?: string;
8949
+ tools?: {
8950
+ /** Allowlist. When set, only these tools are exposed. */
8951
+ enabled?: PptxAiToolName[];
8952
+ /** Denylist, applied after `enabled`. */
8953
+ disabled?: PptxAiToolName[];
8954
+ /** Additional host-defined tools merged into the tool set. */
8955
+ extra?: ToolSet;
8956
+ };
8957
+ /** Default `'stage'`. */
8958
+ writePolicy?: PptxAiWritePolicy;
8959
+ /** Default `'outline'`. */
8960
+ contextStrategy?: PptxAiContextStrategy;
8961
+ history?: PptxAiHistoryHooks;
8962
+ /**
8963
+ * How AI edits are animated on the canvas so the user can watch them land
8964
+ * (glide old->new, fade/scale in-out, glow-pulse). Omit for the defaults;
8965
+ * set `{ enabled: false }` to turn it off.
8966
+ */
8967
+ changeAnimation?: AiChangeAnimationConfig;
8968
+ onError?(error: Error): void;
8969
+ }
8970
+ //#endregion
8971
+ //#region src/ai/bridge.d.ts
8972
+ /** Lightweight, model-friendly summary of the whole deck. */
8973
+ interface PptxAiDeckMeta {
8974
+ /** Total number of slides. */
8975
+ slideCount: number;
8976
+ /** Zero-based index of the currently active slide. */
8977
+ activeSlideIndex: number;
8978
+ /** Deck title, when known (first slide title / core properties). */
8979
+ title?: string;
8980
+ /** Slide canvas width in CSS pixels. */
8981
+ width: number;
8982
+ /** Slide canvas height in CSS pixels. */
8983
+ height: number;
8984
+ }
8985
+ /** Severity hint for {@link PptxAiBridge.notify}. */
8986
+ type PptxAiNotifyLevel = 'info' | 'success' | 'warning' | 'error';
8987
+ /**
8988
+ * A target the user has scoped the assistant to: either a whole slide or a
8989
+ * single element on a slide. Returned by {@link PptxAiBridge.getFocusedTargets}
8990
+ * so the context builder can tell the model exactly what to focus on.
8991
+ */
8992
+ type PptxAiFocusedTarget = {
8993
+ kind: 'slide';
8994
+ slideIndex: number;
8995
+ } | {
8996
+ kind: 'element';
8997
+ slideIndex: number;
8998
+ elementId: string;
8999
+ };
9000
+ /**
9001
+ * A pure updater over the deck's slides. It receives a deep clone of the
9002
+ * current slides (mutation-safe) and returns the next slides array. The bridge
9003
+ * commits the returned array as ONE history entry.
9004
+ */
9005
+ type PptxAiSlidesUpdater = (slides: PptxSlide[]) => PptxSlide[];
9006
+ /**
9007
+ * A pure updater over the whole parsed deck ({@link PptxData}). Mirrors the
9008
+ * `pptx-viewer-mcp` tool model (data in, mutated data out) so presentation-level
9009
+ * MCP tools (metadata, sections, canvas size, presentation properties, layouts)
9010
+ * can be committed as ONE undoable history entry through {@link
9011
+ * PptxAiBridge.applyDeckData}. Optional: bindings that only track slide/theme
9012
+ * state can omit it, in which case those presentation-level tools report that
9013
+ * they are unavailable in this viewer while every slide/theme tool still works.
9014
+ */
9015
+ type PptxAiDataUpdater = (data: PptxData) => PptxData;
9016
+ /** Field-level updates for a single element, mirroring the MCP update vocab. */
9017
+ interface PptxAiElementUpdate {
9018
+ x?: number;
9019
+ y?: number;
9020
+ width?: number;
9021
+ height?: number;
9022
+ rotation?: number;
9023
+ opacity?: number;
9024
+ hidden?: boolean;
9025
+ flipHorizontal?: boolean;
9026
+ flipVertical?: boolean;
9027
+ text?: string;
9028
+ fontSize?: number;
9029
+ fontFamily?: string;
9030
+ fontColor?: string;
9031
+ bold?: boolean;
9032
+ italic?: boolean;
9033
+ underline?: boolean;
9034
+ align?: 'left' | 'center' | 'right' | 'justify';
9035
+ fillColor?: string;
9036
+ strokeColor?: string;
9037
+ strokeWidth?: number;
9038
+ }
9039
+ /**
9040
+ * Implemented by each binding to expose its live editor to the AI core.
9041
+ *
9042
+ * Read methods must be cheap and synchronous. Write methods must route through
9043
+ * the binding's editor-history layer so AI edits are undoable like manual ones.
9044
+ */
9045
+ interface PptxAiBridge {
9046
+ /** Return a summary of the whole deck. */
9047
+ getDeckMeta(): PptxAiDeckMeta;
9048
+ /** Return the deck's slides. Callers must not mutate the returned array. */
9049
+ getSlides(): PptxSlide[];
9050
+ /** Return the zero-based index of the active slide. */
9051
+ getActiveSlideIndex(): number;
9052
+ /** Return the resolved presentation theme, when available. */
9053
+ getTheme(): PptxTheme | undefined;
9054
+ /** Return the underlying core handler, when the binding exposes one. */
9055
+ getHandler(): PptxHandler | undefined;
9056
+ /** Navigate the viewer to a slide by zero-based index. */
9057
+ goToSlide(index: number): void;
9058
+ /** Select the given elements on a slide (empty array clears selection). */
9059
+ selectElements(slideIndex: number, elementIds: string[]): void;
9060
+ /**
9061
+ * Apply a slides updater as a single, atomic, undoable history entry. The
9062
+ * binding is responsible for cloning current slides before calling
9063
+ * `updater` and for installing the result.
9064
+ */
9065
+ applySlidesUpdate(updater: PptxAiSlidesUpdater, label: string): void;
9066
+ /** Apply field updates to one element as a single history entry. */
9067
+ updateElement(slideIndex: number, elementId: string, updates: PptxAiElementUpdate): void;
9068
+ /** Apply partial theme updates as a single history entry. */
9069
+ applyTheme(updates: Partial<PptxTheme>): void;
9070
+ /**
9071
+ * Return the full parsed {@link PptxData} for the open deck, with the live
9072
+ * (edited) slides and theme overlaid. Enables `pptx-viewer-mcp` tools that
9073
+ * read presentation-level state (metadata, sections, layouts, presentation
9074
+ * properties). Optional: when absent, the AI core synthesises a minimal
9075
+ * PptxData from slides + dimensions, which is enough for every slide/theme
9076
+ * tool but not for presentation-level reads.
9077
+ */
9078
+ getDeckData?(): PptxData | undefined;
9079
+ /**
9080
+ * Commit a whole-deck {@link PptxData} mutation as one undoable history entry.
9081
+ * Used to apply presentation-level MCP tool results (metadata, sections,
9082
+ * canvas size, presentation properties, layouts). Optional: when absent,
9083
+ * those tools report they are not supported in this viewer; slide/theme tools
9084
+ * are unaffected (they route through {@link PptxAiBridge.applySlidesUpdate}
9085
+ * and {@link PptxAiBridge.applyTheme}).
9086
+ */
9087
+ applyDeckData?(updater: PptxAiDataUpdater, label: string): void;
9088
+ /**
9089
+ * Return the slides / elements the user has scoped the assistant to, if any.
9090
+ * When present and non-empty, the context builder tells the model to focus on
9091
+ * exactly these targets. Optional so existing bridges satisfy the contract
9092
+ * without change; a bridge that does not implement it behaves as before (no
9093
+ * focus scoping).
9094
+ */
9095
+ getFocusedTargets?(): PptxAiFocusedTarget[];
9096
+ /** Surface a transient message in the host UI (toast / status line). */
9097
+ notify?(message: string, level?: PptxAiNotifyLevel): void;
9098
+ }
9099
+
9100
+ //#endregion
9101
+ //#region src/i18n/locale-catalog.d.ts
9102
+ /** One selectable entry in the viewer chrome's built-in language picker (File > Options > Language). */
9103
+ interface LocaleCatalogEntry {
9104
+ /** BCP-47-ish locale code, e.g. `'en'`, `'fr'`. Matches `pptx-viewer-locales`' exports. */
9105
+ code: string;
9106
+ /** English display name, used before a translation dictionary for the target locale is loaded. */
9107
+ label: string;
9108
+ /** The locale's own name for itself, e.g. `'Français'` for `fr`. */
9109
+ nativeLabel: string;
9110
+ }
9111
+
9112
+ /**
9113
+ * Animated-GIF export capture/encode pipeline. All the pure logic is shared:
9114
+ * `planGifFrames` derives the per-slide frame delays (default duration +
9115
+ * per-slide overrides), `clampGifDimensions` bounds the output size, and
9116
+ * `encodeGif` (median-cut quantisation + LZW GIF89a) produces the bytes with
8016
9117
  * each frame carrying its own plan delay. This module only owns the
8017
9118
  * DOM-adjacent glue: rasterising each slide via the injected capture callback
8018
9119
  * and normalising every frame onto a uniform-size canvas before pixel
@@ -8059,6 +9160,12 @@ interface ExportGifOptions {
8059
9160
  */
8060
9161
  /** Options for the print flow: any subset of the shared print settings. */
8061
9162
  type PrintOptions = Partial<PrintSettings>;
9163
+ /**
9164
+ * Render a complete HTML document into a print surface and trigger printing.
9165
+ * Returns `false` when the surface could not be opened (e.g. a custom
9166
+ * `window.open`-based opener hit a popup blocker).
9167
+ */
9168
+ type OpenPrintWindow = (htmlDocument: string) => boolean;
8062
9169
 
8063
9170
  /**
8064
9171
  * Video (WebM) export driven by the shared `video-plan` maths: segment timing
@@ -8089,6 +9196,9 @@ interface ExportVideoOptions {
8089
9196
  signal?: AbortSignal;
8090
9197
  }
8091
9198
 
9199
+ /** Rasterise the slide at `index` to an `HTMLCanvasElement`. Injected so the
9200
+ * controller stays DOM-capture-free and unit-testable. */
9201
+ type RasterizeSlide = (index: number) => Promise<HTMLCanvasElement>;
8092
9202
  /** Per-slide progress callback: `(currentSlideIndex, totalSlides)`. */
8093
9203
  type ExportProgress = (current: number, total: number) => void;
8094
9204
  /** Options for the multi-slide PDF export (progress + cooperative cancel). */
@@ -8098,6 +9208,77 @@ interface ExportPdfOptions {
8098
9208
  /** Abort the export early; the loop checks this between slides. */
8099
9209
  signal?: AbortSignal;
8100
9210
  }
9211
+ interface ExportControllerDeps {
9212
+ /** Live slide count; read fresh on every call. */
9213
+ getSlideCount(): number;
9214
+ /** Active slide index (0-based); the PNG export's default target. */
9215
+ getCurrent(): number;
9216
+ /** Live slide canvas size (px), for the PDF page size. */
9217
+ getCanvasSize(): CanvasSize;
9218
+ /** Live slide list (print needs slide notes/titles, not just the count). */
9219
+ getSlides(): PptxSlide[];
9220
+ rasterizeSlide: RasterizeSlide;
9221
+ /** Print-surface opener override; see `export-print.ts` for the default. */
9222
+ openPrintWindow?: OpenPrintWindow;
9223
+ /** Base file name (without extension) for downloads. Defaults to `presentation`. */
9224
+ fileName?: string;
9225
+ }
9226
+ /**
9227
+ * Export controller (runes class): render slides to PNG / PDF / animated GIF /
9228
+ * WebM video, plus the print flow. Started as a Svelte port of Vue's
9229
+ * `useExport` composable (`packages/vue/src/viewer/composables/useExport.ts`)
9230
+ * and now also covers React's `useExportHandlers` GIF/video surface (via
9231
+ * `export-gif.ts` / `export-video.ts`) and Vue's `usePrint`
9232
+ * (`export-print.ts`), reshaped as a `$state`-backed class to match this
9233
+ * package's runes-class convention (see `EditorState` in
9234
+ * `../editor/editor-state.svelte.ts`) rather than Vue `Ref`s.
9235
+ *
9236
+ * Rasterisation is delegated to the injected `rasterizeSlide` (the host owns
9237
+ * the off-screen `SlideStage` mount + `html2canvas-pro`, see
9238
+ * `rasterize-slide.ts`). `jspdf` is loaded lazily so it stays out of the main
9239
+ * bundle.
9240
+ */
9241
+ declare class ExportController {
9242
+ #private;
9243
+ /** True while an export is running (disable UI / show a spinner). */
9244
+ exporting: boolean;
9245
+ constructor(deps: ExportControllerDeps);
9246
+ /** Export a single slide as a PNG download. Defaults to the current slide. */
9247
+ exportSlidePng(index?: number): Promise<void>;
9248
+ /** Copy a slide to the system clipboard as a PNG image. */
9249
+ copySlideAsImage(index?: number): Promise<void>;
9250
+ /** Export every slide as a multi-page PDF download (one slide per page). */
9251
+ exportPdf(options?: ExportPdfOptions): Promise<void>;
9252
+ /**
9253
+ * Export every slide as an animated GIF download. Frame delays come from
9254
+ * the shared `planGifFrames` plan (default duration + per-slide overrides);
9255
+ * see `export-gif.ts`. Supports progress + AbortSignal like `exportPdf`.
9256
+ */
9257
+ exportGif(options?: ExportGifOptions): Promise<void>;
9258
+ /**
9259
+ * Export every slide as a WebM video download (MediaRecorder over a canvas
9260
+ * capture stream, timing from the shared `planVideoSegments` plan); see
9261
+ * `export-video.ts`. Supports progress + AbortSignal like `exportPdf`.
9262
+ */
9263
+ exportVideo(options?: ExportVideoOptions): Promise<void>;
9264
+ /**
9265
+ * Assemble the shared print document for the given (partial) settings and
9266
+ * open it in the print surface (hidden iframe by default; see
9267
+ * `export-print.ts` for the popup-blocker caveats of custom openers).
9268
+ * Resolves `true` when the print surface opened.
9269
+ */
9270
+ print(options?: PrintOptions): Promise<boolean>;
9271
+ }
9272
+
9273
+ /** Translate `key`, interpolating `{{name}}` placeholders from `params`. */
9274
+ type Translator = (key: string, params?: Record<string, string | number>) => string;
9275
+
9276
+ interface ExportWiring {
9277
+ /** The reactive PNG/PDF export controller (`exporting` drives a spinner). */
9278
+ controller: ExportController;
9279
+ /** Tear down the off-screen capture stage (component destroy). */
9280
+ destroy(): void;
9281
+ }
8101
9282
 
8102
9283
  type SvgExportSingleSlideOptions = SvgExportOptions;
8103
9284
  type SvgExportAllOptions = SvgExportOptions;
@@ -8112,6 +9293,16 @@ declare function exportAllSlidesToSvg(data: PptxData, options?: SvgExportAllOpti
8112
9293
  /** Export the selected presentation slides as SVG Blobs. */
8113
9294
  declare function exportAllSlidesToSvgBlobs(data: PptxData, options?: SvgExportAllOptions): Blob[];
8114
9295
 
9296
+ /** The imperative export API exposed on the `PowerPointViewer` instance. */
9297
+ interface ExportingApi {
9298
+ exportSlidePng(index?: number): Promise<void>;
9299
+ copySlideAsImage(index?: number): Promise<void>;
9300
+ exportPdf(options?: ExportPdfOptions): Promise<void>;
9301
+ exportGif(options?: ExportGifOptions): Promise<void>;
9302
+ exportVideo(options?: ExportVideoOptions): Promise<void>;
9303
+ print(options?: PrintOptions): Promise<boolean>;
9304
+ }
9305
+
8115
9306
  /** Payload for the `onload` callback. */
8116
9307
  interface ViewerLoadDetail {
8117
9308
  /** Number of slides in the loaded presentation. */
@@ -8198,11 +9389,11 @@ interface PowerPointViewerProps {
8198
9389
  */
8199
9390
  showNotes?: boolean;
8200
9391
  /**
8201
- * Opt in to the experimental Three.js (WebGL) SmartArt renderer for
8202
- * `smartArt` elements, in place of the default SVG renderer. Requires the
8203
- * optional `three` peer dependency; when it is unavailable, or a diagram
8204
- * has no renderable nodes, or the WebGL mount fails, the SVG renderer is
8205
- * used automatically. Default false.
9392
+ * Opt in to the Three.js (WebGL) SmartArt renderer for `smartArt` elements,
9393
+ * in place of the default SVG renderer. Requires the optional `three` peer
9394
+ * dependency; when it is unavailable, or a diagram has no renderable nodes,
9395
+ * or the WebGL mount fails, the SVG renderer is used automatically. Default
9396
+ * false.
8206
9397
  */
8207
9398
  smartArt3D?: boolean;
8208
9399
  /**
@@ -8291,6 +9482,15 @@ interface PowerPointViewerProps {
8291
9482
  userName?: string;
8292
9483
  serverUrl?: string;
8293
9484
  };
9485
+ /**
9486
+ * Optional AI assistant configuration. When provided, a Sparkles toggle
9487
+ * appears in the ribbon's command row and opens a right-side chat panel that
9488
+ * can read the open deck and propose edits through the viewer's undo history.
9489
+ * The panel (and the optional `@ai-sdk/svelte` + `ai` peers it needs) is
9490
+ * lazily loaded only when first opened; leaving this undefined ships no AI UI
9491
+ * and never pulls the SDK. See `pptx-viewer-shared/ai`'s `PptxAiConfig`.
9492
+ */
9493
+ ai?: PptxAiConfig;
8294
9494
  }
8295
9495
  /**
8296
9496
  * Imperative editing API exposed on the `<PowerPointViewer>` component
@@ -8366,6 +9566,999 @@ interface PowerPointViewerApi extends PowerPointViewerAPI {
8366
9566
  */
8367
9567
  declare const PowerPointViewer: Component<PowerPointViewerProps, PowerPointViewerApi>;
8368
9568
 
9569
+ /**
9570
+ * Shared value types for the Svelte editing layer.
9571
+ */
9572
+ /** Box geometry in element (unscaled slide) px. */
9573
+ interface OverlayBox {
9574
+ x: number;
9575
+ y: number;
9576
+ width: number;
9577
+ height: number;
9578
+ rotation: number;
9579
+ }
9580
+
9581
+ interface EditorControllerDeps {
9582
+ getScale(): number;
9583
+ getCurrent(): number;
9584
+ getPresenting(): boolean;
9585
+ getStageRoot(): Element | null;
9586
+ getHolderEl(): HTMLElement | null;
9587
+ onCursorMove?(x: number, y: number): void;
9588
+ onContextMenu?(x: number, y: number): void;
9589
+ getSnapToGrid?(): boolean;
9590
+ getSnapToShape?(): boolean;
9591
+ getGuides?(): readonly {
9592
+ axis: 'h' | 'v';
9593
+ position: number;
9594
+ }[];
9595
+ /**
9596
+ * Transform inline-editor text at commit time (File > Options > Proofing
9597
+ * AutoCorrect); identity when unset.
9598
+ */
9599
+ transformCommittedText?(text: string): string;
9600
+ }
9601
+
9602
+ /**
9603
+ * Pure, immutable slide-array mutations for the Svelte editor.
9604
+ *
9605
+ * Mirrors the vanilla binding's `editor-mutations` (in turn the Vue binding's
9606
+ * `useEditorOperations` commit helpers), minus the reactivity: every function
9607
+ * takes the current `PptxSlide[]` and returns a brand-new array (untouched
9608
+ * slides are reused by reference so the render layer can cheaply detect
9609
+ * changes). All cloning defers to the core helpers (`cloneSlide`,
9610
+ * `cloneElement`, `duplicateElement`); nothing is mutated in place.
9611
+ */
9612
+ /** Geometry patch applied by drag / resize / rotate / nudge. */
9613
+ interface ElementBoxPatch {
9614
+ x: number;
9615
+ y: number;
9616
+ width: number;
9617
+ height: number;
9618
+ rotation: number;
9619
+ }
9620
+
9621
+ interface EditorMarqueeRect extends MarqueeRect {
9622
+ additive: boolean;
9623
+ }
9624
+
9625
+ /**
9626
+ * Element-animation actions for the ribbon's Animations tab, split out of
9627
+ * `EditorState` to keep it under the repo's 300-LOC budget.
9628
+ *
9629
+ * Animation data lives on the SLIDE (`PptxSlide.animations`, keyed by
9630
+ * `elementId`), not on the element itself, matching how the presentation
9631
+ * playback state machine reads it (`buildClickGroups` in
9632
+ * `presentation/animation-playback.svelte.ts`). Both actions target the
9633
+ * currently selected element and route through the shared
9634
+ * `animation-authoring.ts` "coarse group preset" model (`applyAnimationPreset`
9635
+ * / `removeElementAnimation`), the same one the Vue/vanilla ribbons use:
9636
+ * applying a preset sets one of entrance/emphasis/exit without touching the
9637
+ * others; remove drops the whole entry. Both mutations go through
9638
+ * `EditorState.commitSlides`, so they are history-integrated (undoable).
9639
+ */
9640
+ declare class EditorAnimationController {
9641
+ #private;
9642
+ constructor(editor: EditorState);
9643
+ addAnimation(group: AnimationGroup, preset: PptxAnimationPreset): void;
9644
+ removeAnimation(): void;
9645
+ }
9646
+
9647
+ /**
9648
+ * The Home tab's multi-select-aware Arrange group (align / distribute /
9649
+ * flip / group / ungroup), split out of `EditorState` to keep it under the
9650
+ * repo's 300-LOC budget. Reads `editor.selection.ids` (the ordered
9651
+ * multi-selection) rather than just the primary id, matching React's
9652
+ * `selectedElementIds` semantics.
9653
+ */
9654
+ declare class EditorArrangeController {
9655
+ #private;
9656
+ constructor(editor: EditorState);
9657
+ /** Align every selected element to `edge` (needs >= 2 selected). */
9658
+ alignSelected(edge: AlignEdge): void;
9659
+ /** Distribute the selected elements evenly along `axis` (needs >= 3 selected). */
9660
+ distributeSelected(axis: DistributeAxis): void;
9661
+ /** Flip every selected element across `axis`. */
9662
+ flipSelected(axis: 'horizontal' | 'vertical'): void;
9663
+ /** Group the selected elements (needs >= 2 selected). Selects the new group. */
9664
+ groupSelected(): void;
9665
+ /** Ungroup the primary selected group element. Selects the ungrouped children. */
9666
+ ungroupSelected(): void;
9667
+ }
9668
+
9669
+ /**
9670
+ * Slide-background actions for the ribbon's Design tab "Format Background"
9671
+ * panel, split out of `EditorState` to keep it under the repo's 300-LOC
9672
+ * budget (mirrors `EditorSlidesController` / `EditorArrangeController`).
9673
+ *
9674
+ * Solid-colour fill only (matches the docked panel's scope: a single colour
9675
+ * input); clearing removes every background field so the slide falls back to
9676
+ * its layout/master background. Both mutations route through
9677
+ * `EditorState.commitSlides`, so they are history-integrated (undoable) like
9678
+ * every other ribbon mutation.
9679
+ */
9680
+ declare class EditorBackgroundController {
9681
+ #private;
9682
+ constructor(editor: EditorState);
9683
+ /** Set the current slide's background to a solid colour. */
9684
+ setSlideBackgroundColor(color: string): void;
9685
+ /** Clear every background field on the current slide (fall back to layout/master). */
9686
+ clearSlideBackground(): void;
9687
+ }
9688
+
9689
+ /**
9690
+ * Ctrl+C/X/V and the Home tab's Clipboard group, split out of `EditorState`
9691
+ * to keep it under the repo's 300-LOC budget. Operates entirely through
9692
+ * `EditorState`'s public surface (`slides`, `selection`, `currentSlideIndex`,
9693
+ * `commitSlides`), the same contract a component would use.
9694
+ */
9695
+ declare class EditorClipboardController {
9696
+ #private;
9697
+ constructor(editor: EditorState);
9698
+ /** Copy the primary selected element to the clipboard (works read-only, like React). */
9699
+ copySelected(): void;
9700
+ /** Copy the primary selected element then delete it (with history). */
9701
+ cutSelected(): void;
9702
+ /** Paste the clipboard payload onto the current slide (fresh id, offset, selects it). */
9703
+ pasteClipboard(): string | null;
9704
+ }
9705
+
9706
+ /**
9707
+ * Z-order (paint-order) reordering for the Svelte editor.
9708
+ *
9709
+ * The array-level primitives (`bringToFront`, `sendToBack`, `bringForward`,
9710
+ * `sendBackward`) are the shared, framework-agnostic operations from
9711
+ * `pptx-viewer-shared` (`render/element-operations`), where array index 0 is
9712
+ * the back and the last index is the front. This module only lifts them to the
9713
+ * slide-array shape the editor state stores, reusing the same immutable
9714
+ * `mapSlideElements` helper as the other mutations.
9715
+ */
9716
+ /** Which way to move the selected element through the paint-order stack. */
9717
+ type ZOrderDirection = 'front' | 'back' | 'forward' | 'backward';
9718
+
9719
+ /** History-integrated element and notes mutations for {@link EditorState}. */
9720
+ declare class EditorElementController {
9721
+ #private;
9722
+ constructor(editor: EditorState);
9723
+ resetNudge(): void;
9724
+ patchGeometry(id: string, box: ElementBoxPatch): void;
9725
+ deleteSelected(): void;
9726
+ duplicateSelected(): string | null;
9727
+ applyElementPatch(id: string, patch: Partial<PptxElement>): void;
9728
+ patchSelected(patch: Partial<PptxElement>): void;
9729
+ insertElement(element: PptxElement): string | null;
9730
+ reorderSelected(direction: ZOrderDirection): void;
9731
+ nudgeSelected(dx: number, dy: number): void;
9732
+ commitInlineText(id: string, text: string): void;
9733
+ commitNotes(notes: string, notesSegments?: TextSegment[]): void;
9734
+ }
9735
+
9736
+ /** Existing-equation edit state with history-integrated OMML replacement. */
9737
+ declare class EditorEquationController {
9738
+ private readonly editor;
9739
+ editingId: string | null;
9740
+ constructor(editor: EditorState);
9741
+ open(id: string): boolean;
9742
+ get omml(): Record<string, unknown> | null;
9743
+ apply(omml: Record<string, unknown>): void;
9744
+ close(): void;
9745
+ }
9746
+
9747
+ /** One-shot Format Painter state and history-integrated application. */
9748
+ declare class EditorFormatPainterController {
9749
+ #private;
9750
+ private readonly editor;
9751
+ constructor(editor: EditorState);
9752
+ get active(): boolean;
9753
+ get enabled(): boolean;
9754
+ toggle(): void;
9755
+ applyTo(id: string): boolean;
9756
+ cancel(): void;
9757
+ }
9758
+
9759
+ /**
9760
+ * The ribbon Draw tab's active tool. `'select'` means "not drawing": the
9761
+ * stage's normal selection/drag/resize gestures own the pointer, matching
9762
+ * React's `DrawingTool` / Angular's `DrawTool` conventions (minus `freeform`,
9763
+ * out of scope for this wave; see the Draw tab's JSDoc).
9764
+ */
9765
+ type InkDrawTool = 'select' | 'pen' | 'highlighter' | 'eraser';
9766
+ /**
9767
+ * EditorInkController: the ribbon Draw tab's tool/colour/width state plus the
9768
+ * pure element-factory / erase mutations, split out of `EditorState` to keep
9769
+ * it under the repo's 300-LOC budget (mirrors `EditorArrangeController` /
9770
+ * `EditorBackgroundController`). Instantiated as `EditorState.inkOps`.
9771
+ *
9772
+ * The actual pointer-event lifecycle (accumulating a stroke's points, driving
9773
+ * the live preview) lives in `editor-ink-gesture.ts`, owned by
9774
+ * `EditorController`; this class only holds the tool/colour/width state the
9775
+ * gesture controller reads and the two mutations it calls into
9776
+ * ({@link commitStroke}, {@link eraseElementAt}), both of which route through
9777
+ * `EditorState` so they participate in undo/redo like every other edit.
9778
+ */
9779
+ declare class EditorInkController {
9780
+ #private;
9781
+ /** The active draw tool. `'select'` hands the stage back to normal editing gestures. */
9782
+ tool: InkDrawTool;
9783
+ /** Stroke colour for new pen/highlighter strokes. */
9784
+ color: string;
9785
+ /** Stroke width (px, element space) for new pen/highlighter strokes. */
9786
+ width: number;
9787
+ /** SVG path `d` for the in-progress stroke's live preview, or `''` when idle. */
9788
+ livePathD: string;
9789
+ constructor(editor: EditorState);
9790
+ /** True whenever a tool other than `select` is active: the stage hands pointer gestures to ink drawing. */
9791
+ get isDrawing(): boolean;
9792
+ /**
9793
+ * Switch the active tool. Clears the current selection when entering a draw
9794
+ * tool so the selection overlay's resize/rotate handles (which own their
9795
+ * own `pointerdown` and would otherwise race a drawing gesture over the
9796
+ * same screen area) are not rendered while drawing.
9797
+ */
9798
+ setTool(tool: InkDrawTool): void;
9799
+ setColor(color: string): void;
9800
+ setWidth(width: number): void;
9801
+ /** Update the live preview path while a pen/highlighter stroke is in progress. */
9802
+ previewStroke(points: readonly InkPoint[]): void;
9803
+ /**
9804
+ * Finalise the in-progress stroke into a new `ink` element (undoable via
9805
+ * `EditorState.insertElement`), or discard it silently when too short (a
9806
+ * plain tap) or the tool changed mid-gesture.
9807
+ */
9808
+ commitStroke(points: readonly InkPoint[]): void;
9809
+ /**
9810
+ * Hit-test `ink` elements on the current slide at `point` (topmost first)
9811
+ * and delete the first match, with history. No-op when nothing is hit.
9812
+ */
9813
+ eraseElementAt(point: InkPoint): void;
9814
+ }
9815
+
9816
+ interface MasterViewTarget {
9817
+ tab: MasterViewTab;
9818
+ masterIndex: number;
9819
+ layoutIndex: number | null;
9820
+ }
9821
+ /** Routes the active editing layer into a parsed slide master or layout. */
9822
+ declare class EditorMasterController {
9823
+ private readonly editor;
9824
+ constructor(editor: EditorState);
9825
+ enter(masterIndex?: number, layoutIndex?: number | null): void;
9826
+ enterTab(tab: MasterViewTab): void;
9827
+ exit(): void;
9828
+ activeElements(): PptxElement[] | null;
9829
+ replace(elements: PptxElement[]): boolean;
9830
+ cloneMasters(): PptxSlideMaster[];
9831
+ cloneNotesMaster(): PptxNotesMaster | undefined;
9832
+ cloneHandoutMaster(): PptxHandoutMaster | undefined;
9833
+ setHandoutSlidesPerPage(slidesPerPage: number): void;
9834
+ setBackgroundColor(backgroundColor: string): void;
9835
+ }
9836
+
9837
+ interface PresentationMetadataHost {
9838
+ readonly editable: boolean;
9839
+ pushHistory(): void;
9840
+ commitChange(): void;
9841
+ }
9842
+ /** Owns presentation-level metadata and its undoable editor mutations. */
9843
+ declare class EditorPresentationMetadata {
9844
+ private readonly host;
9845
+ headerFooter: PptxHeaderFooter;
9846
+ presentationProperties: PptxPresentationProperties;
9847
+ customShows: PptxCustomShow[];
9848
+ constructor(host: PresentationMetadataHost);
9849
+ set(headerFooter?: PptxHeaderFooter, presentationProperties?: PptxPresentationProperties, customShows?: PptxCustomShow[]): void;
9850
+ updatePresentationProperties(next: PptxPresentationProperties): void;
9851
+ updateHeaderFooter(next: PptxHeaderFooter): void;
9852
+ updateCustomShows(next: PptxCustomShow[]): void;
9853
+ private commit;
9854
+ }
9855
+
9856
+ /** History-aware section CRUD and grouping for the Svelte editor. */
9857
+ declare class EditorSectionController {
9858
+ private readonly editor;
9859
+ constructor(editor: EditorState);
9860
+ get groups(): SectionSlideGroup<PptxSection>[];
9861
+ add(name: string, afterSlideIndex?: number): string | null;
9862
+ rename(sectionId: string, name: string): void;
9863
+ delete(sectionId: string): void;
9864
+ moveUp(sectionId: string): void;
9865
+ moveDown(sectionId: string): void;
9866
+ moveSlides(slideIndexes: number[], targetSectionId: string): void;
9867
+ toggle(sectionId: string): void;
9868
+ private commit;
9869
+ }
9870
+
9871
+ /**
9872
+ * EditorSelection: the reactive multi-element selection for the Svelte editor.
9873
+ *
9874
+ * Holds an ordered list of selected element ids; the LAST id is the primary
9875
+ * selection (the one the overlay handles, gestures, and inline editing act
9876
+ * on), matching the React binding's `selectedElementIds` + primary convention.
9877
+ * Plain clicks call {@link set} (single selection), shift/ctrl clicks call
9878
+ * {@link toggle} (additive), and mutations that invalidate ids call
9879
+ * {@link prune}.
9880
+ */
9881
+ declare class EditorSelection {
9882
+ #private;
9883
+ /** All selected ids in selection order (primary last). */
9884
+ get ids(): readonly string[];
9885
+ /** The primary selected id (last selected), or null when empty. */
9886
+ get primary(): string | null;
9887
+ /** Number of selected elements. */
9888
+ get size(): number;
9889
+ /** True when `id` is part of the selection. */
9890
+ has(id: string): boolean;
9891
+ /** Replace the selection with a single id (or clear it with `null`). */
9892
+ set(id: string | null): void;
9893
+ /** Replace the selection with an explicit id list (primary = last). */
9894
+ setAll(ids: readonly string[]): void;
9895
+ /** Additive (shift/ctrl-click) toggle: add `id`, or remove it when present. */
9896
+ toggle(id: string): void;
9897
+ /** Clear the selection. */
9898
+ clear(): void;
9899
+ /** Drop ids that no longer resolve to an element (after remote/undo edits). */
9900
+ prune(exists: (id: string) => boolean): void;
9901
+ }
9902
+
9903
+ /**
9904
+ * The Home tab's Slides group (new / duplicate / delete slide), split out of
9905
+ * `EditorState` to keep it under the repo's 300-LOC budget. Every method
9906
+ * returns the new active slide index (or `null` on a no-op) so the caller
9907
+ * (the Slides group, via the host's slide-navigation callback) can move the
9908
+ * viewer to it; `EditorState` itself has no concept of "the active slide"
9909
+ * beyond the `getCurrent` dependency it already reads for element ops.
9910
+ */
9911
+ declare class EditorSlidesController {
9912
+ #private;
9913
+ constructor(editor: EditorState);
9914
+ /** Insert a blank slide after the current one. Returns its new index, or null when not editable. */
9915
+ insertSlideAfterCurrent(): number | null;
9916
+ /** Duplicate the current slide. Returns its new index, or null when not editable. */
9917
+ duplicateCurrentSlide(): number | null;
9918
+ /** Delete the current slide. Returns the new active index, or null (not editable / only slide). */
9919
+ deleteCurrentSlide(): number | null;
9920
+ /**
9921
+ * The layouts available for the current slide (its master's layouts),
9922
+ * resolved via the core `getAvailableLayoutsForSlide` API. Empty when no
9923
+ * deck is loaded. Backs the Home tab's Layout dropdown (React parity).
9924
+ */
9925
+ availableLayouts(): Promise<PptxLayoutOption[]>;
9926
+ /** Re-map the current slide onto `layoutPath`. Returns its index, or null when not editable. */
9927
+ applyLayout(layoutPath: string): Promise<number | null>;
9928
+ /**
9929
+ * Reset the current slide by re-applying its own layout, restoring inherited
9930
+ * placeholder geometry/formatting (React's Home > Reset). Returns the slide
9931
+ * index, or null when the slide has no known layout path.
9932
+ */
9933
+ resetSlide(): Promise<number | null>;
9934
+ /** Move an arbitrary thumbnail slide. Returns the selected target index on success. */
9935
+ moveSlide(fromIndex: number, toIndex: number): number | null;
9936
+ }
9937
+
9938
+ /** Active-layer routing for normal slide content versus inherited template elements. */
9939
+ declare class EditorTemplateController {
9940
+ #private;
9941
+ constructor(editor: EditorState);
9942
+ activeElements(): PptxElement[];
9943
+ renderedSlides(): PptxSlide[];
9944
+ replace(elements: PptxElement[]): void;
9945
+ commit(elements: PptxElement[]): void;
9946
+ }
9947
+
9948
+ /**
9949
+ * Slide-transition actions for the ribbon's Transitions tab, split out of
9950
+ * `EditorState` to keep it under the repo's 300-LOC budget. Playback already
9951
+ * reads `PptxSlide.transition` (see `presentation/presentation-controller.svelte.ts`),
9952
+ * so this only needs to write that same field, routed through
9953
+ * `EditorState.commitSlides` so it is history-integrated (undoable).
9954
+ *
9955
+ * `applyTransition` covers both the preset gallery buttons and the duration
9956
+ * input (the tab re-applies the currently-selected preset whenever the
9957
+ * duration changes), plus the "Apply to All Slides" checkbox: when
9958
+ * `applyToAll` is true every slide gets the same fresh `{ type, durationMs }`
9959
+ * transition; otherwise only the current slide is patched, preserving any
9960
+ * advanced fields (direction, sound, ...) it already carried.
9961
+ */
9962
+ declare class EditorTransitionController {
9963
+ #private;
9964
+ constructor(editor: EditorState);
9965
+ applyTransition(type: PptxTransitionType, durationMs: number, applyToAll: boolean): void;
9966
+ }
9967
+
9968
+ interface EditorStateDeps {
9969
+ getCurrent(): number;
9970
+ getHandler(): PptxHandler | null;
9971
+ onChange?: () => void;
9972
+ }
9973
+ declare class EditorState {
9974
+ #private;
9975
+ slides: PptxSlide[];
9976
+ templateElementsBySlideId: TemplateElementMap;
9977
+ slideMasters: PptxSlideMaster[];
9978
+ notesMaster: PptxNotesMaster | undefined;
9979
+ handoutMaster: PptxHandoutMaster | undefined;
9980
+ sections: PptxSection[];
9981
+ readonly presentationMetadata: EditorPresentationMetadata;
9982
+ coreProperties: PptxCoreProperties | undefined;
9983
+ appProperties: PptxAppProperties | undefined;
9984
+ customProperties: PptxCustomProperty[];
9985
+ masterViewTarget: MasterViewTarget | null;
9986
+ readonly selection: EditorSelection;
9987
+ editable: boolean;
9988
+ dirty: boolean;
9989
+ editTemplateMode: boolean;
9990
+ interactionActive: boolean;
9991
+ clipboard: ElementClipboardPayload | null;
9992
+ readonly clipboardOps: EditorClipboardController;
9993
+ readonly elementOps: EditorElementController;
9994
+ readonly templateOps: EditorTemplateController;
9995
+ readonly slidesOps: EditorSlidesController;
9996
+ readonly sectionOps: EditorSectionController;
9997
+ readonly arrangeOps: EditorArrangeController;
9998
+ readonly backgroundOps: EditorBackgroundController;
9999
+ readonly transitionOps: EditorTransitionController;
10000
+ readonly animationOps: EditorAnimationController;
10001
+ readonly inkOps: EditorInkController;
10002
+ readonly masterOps: EditorMasterController;
10003
+ readonly formatPainter: EditorFormatPainterController;
10004
+ readonly equationOps: EditorEquationController;
10005
+ constructor(deps: EditorStateDeps);
10006
+ get canUndo(): boolean;
10007
+ get headerFooter(): PptxHeaderFooter;
10008
+ get presentationProperties(): PptxPresentationProperties;
10009
+ get customShows(): PptxCustomShow[];
10010
+ get canRedo(): boolean;
10011
+ get selectedElementId(): string | null;
10012
+ get selectedElement(): PptxElement | undefined;
10013
+ get selectedElements(): PptxElement[];
10014
+ get activeElements(): PptxElement[];
10015
+ get renderedSlides(): PptxSlide[];
10016
+ get hasClipboard(): boolean;
10017
+ get currentSlideIndex(): number;
10018
+ /** The loaded core handler, or null before a deck is open. Used by the
10019
+ * Slides group for layout switching (`applyLayoutToSlide`). */
10020
+ getHandler(): PptxHandler | null;
10021
+ setSlides(slides: PptxSlide[], slideMasters?: PptxSlideMaster[], notesMaster?: PptxNotesMaster, handoutMaster?: PptxHandoutMaster, sections?: PptxSection[], coreProperties?: PptxCoreProperties, appProperties?: PptxAppProperties, customProperties?: PptxCustomProperty[], headerFooter?: PptxHeaderFooter, presentationProperties?: PptxPresentationProperties, customShows?: PptxCustomShow[]): void;
10022
+ /**
10023
+ * Replace the working slides with a remote (collaboration) snapshot without
10024
+ * recording an undo step or touching the dirty flag: the granular reconcile
10025
+ * already merged the peer's change, and treating an incoming remote edit as
10026
+ * a local mutation would both pollute the undo stack and re-broadcast it.
10027
+ *
10028
+ * Selection is preserved when the selected element still exists so a remote
10029
+ * edit does not yank the local user's selection out from under them. Local
10030
+ * undo history is intentionally kept (see the collaboration module JSDoc):
10031
+ * shared defines no collaborative-undo semantics, so, matching React/Vue,
10032
+ * local undo may fight a concurrent remote edit.
10033
+ */
10034
+ applyRemoteSlides(slides: PptxSlide[]): void;
10035
+ reset(): void;
10036
+ select(id: string | null): void;
10037
+ isElementInteractive(id: string): boolean;
10038
+ setTemplateEditing(enabled: boolean): void;
10039
+ /**
10040
+ * Apply the File > Options "maximum number of undos" value. Recreates the
10041
+ * history stack when the depth changes (PowerPoint likewise applies the new
10042
+ * maximum going forward; existing entries are dropped).
10043
+ */
10044
+ setHistoryDepth(depth: number): void;
10045
+ pushHistory(): void;
10046
+ commitChange(): void;
10047
+ /** Patch geometry without history for live gesture preview frames. */
10048
+ patchGeometry: (id: string, box: ElementBoxPatch) => void;
10049
+ replaceActiveElements(elements: PptxElement[]): void;
10050
+ /** Commit a replacement active element collection as one undo step. */
10051
+ commitActiveElements(elements: PptxElement[]): void;
10052
+ /**
10053
+ * Replace the whole slide array with history (the generic multi-slide
10054
+ * mutation entry point: slide add/duplicate/delete, arrange group ops,
10055
+ * and find/replace all route through this so every change is a single
10056
+ * undoable step). No-op when not editable.
10057
+ */
10058
+ commitSlides(next: PptxSlide[]): void;
10059
+ deleteSelected: () => void;
10060
+ duplicateSelected: () => string | null;
10061
+ applyElementPatch: (id: string, patch: Partial<PptxElement>) => void;
10062
+ patchSelected: (patch: Partial<PptxElement>) => void;
10063
+ insertElement: (element: PptxElement) => string | null;
10064
+ reorderSelected: (direction: ZOrderDirection) => void;
10065
+ nudgeSelected: (dx: number, dy: number) => void;
10066
+ commitInlineText: (id: string, text: string) => void;
10067
+ commitNotes: (notes: string, notesSegments?: TextSegment[]) => void;
10068
+ updateDocumentProperties(core: PptxCoreProperties, app: PptxAppProperties, custom: PptxCustomProperty[]): void;
10069
+ undo(): void;
10070
+ redo(): void;
10071
+ save(format?: PptxSaveFormat): Promise<Uint8Array>;
10072
+ }
10073
+
10074
+ declare class EditorController {
10075
+ #private;
10076
+ snapLines: readonly SnapLine[];
10077
+ editingId: string | null;
10078
+ marquee: EditorMarqueeRect | null;
10079
+ constructor(editor: EditorState, deps: EditorControllerDeps);
10080
+ get overlayBox(): OverlayBox | null;
10081
+ get editing(): boolean;
10082
+ get selectionCount(): number;
10083
+ get editingElement(): PptxElement | undefined;
10084
+ /** True when editing owns the keyboard (a selection or inline edit is live). */
10085
+ capturesKeyboard(): boolean;
10086
+ onStagePointerDown: (event: PointerEvent) => void;
10087
+ onStagePointerMove: (event: PointerEvent) => void;
10088
+ onStageDblClick: (event: MouseEvent) => void;
10089
+ /** Select the right-clicked element and expose the edit context menu. */
10090
+ onStageContextMenu: (event: MouseEvent) => void;
10091
+ onHandlePointerDown: (handle: ResizeHandleId, event: PointerEvent) => void;
10092
+ onRotatePointerDown: (event: PointerEvent) => void;
10093
+ onKeyDown: (event: KeyboardEvent) => void;
10094
+ /** Open the inline text editor over `id` when the element carries text. */
10095
+ enterInlineEdit(id: string): void;
10096
+ /** Commit the inline editor's text onto the element and close it. */
10097
+ commitInline(id: string, text: string): void;
10098
+ /** Close the inline editor without further mutation. */
10099
+ closeInline(): void;
10100
+ /** Tear down window listeners (component destroy). */
10101
+ destroy(): void;
10102
+ }
10103
+
10104
+ /**
10105
+ * ExportUiState: reactive state behind the toolbar `ExportMenu` and the
10106
+ * `ExportProgressModal`. Svelte port of Vue's `useExportProgress` composable:
10107
+ * it owns the modal state (open / title / progress / status), the
10108
+ * `AbortController` the export loops check between slides, and wraps each
10109
+ * multi-slide export (PDF / GIF / WebM) in a `begin -> run -> end` envelope.
10110
+ * All percentage maths + status labels come from `pptx-viewer-shared`
10111
+ * (`export-progress.ts`) so every binding shows identical progress.
10112
+ *
10113
+ * PNG (single slide, fast) and print (opens its own surface) run without the
10114
+ * modal; the menu trigger still disables via {@link exporting} while they run.
10115
+ */
10116
+ interface ExportUiDeps {
10117
+ controller: ExportController;
10118
+ getTranslator(): Translator;
10119
+ /**
10120
+ * Fired after an export completes successfully (Options > Accessibility
10121
+ * "feedback with sound" hook); not called on abort or failure.
10122
+ */
10123
+ onComplete?(): void;
10124
+ }
10125
+ declare class ExportUiState {
10126
+ #private;
10127
+ /** Whether the progress modal is visible. */
10128
+ open: boolean;
10129
+ /** Modal heading (e.g. "Export as PDF"). */
10130
+ title: string;
10131
+ /** Current progress, 0-100. */
10132
+ progress: number;
10133
+ /** Status line under the bar (e.g. "Rendering slide 3 of 10..."). */
10134
+ status: string;
10135
+ constructor(deps: ExportUiDeps);
10136
+ /** True while any export runs (disables the menu trigger). */
10137
+ get exporting(): boolean;
10138
+ /** Export the current slide as PNG (no modal; quick single capture). */
10139
+ runPng(): void;
10140
+ /** Copy the current slide to the system image clipboard. */
10141
+ runCopyImage(): void;
10142
+ /** Run the PDF export with the progress modal wired. */
10143
+ runPdf(): Promise<void>;
10144
+ /** Run the animated-GIF export with the progress modal wired. */
10145
+ runGif(): Promise<void>;
10146
+ /** Run the WebM video export with the progress modal wired. */
10147
+ runVideo(): Promise<void>;
10148
+ /** Run the print flow (no modal; the print surface takes over). */
10149
+ runPrint(options?: PrintOptions): void;
10150
+ /** Cancel the in-flight export (aborts the loop, closes the modal). */
10151
+ cancel(): void;
10152
+ }
10153
+
10154
+ /**
10155
+ * autosave.svelte.ts: debounced crash-recovery autosave for the Svelte viewer.
10156
+ *
10157
+ * A runes port that fuses the two shared semantics the other bindings use:
10158
+ * - React's persistence target: each successful save writes the serialized
10159
+ * `.pptx` bytes to the shared IndexedDB recovery store
10160
+ * (`saveAutosaveSnapshot`, keyed by `filePath`), so a host can offer
10161
+ * restore-on-load with `getAutosaveSnapshot` / `listAutosaveSnapshots`
10162
+ * (both re-exported from this package). This binding does NOT auto-restore;
10163
+ * matching React/Vue, recovery is a host concern.
10164
+ * - Vue's debounce-on-edit trigger: an edit marks the document dirty and
10165
+ * (re)arms a debounce timer instead of polling on a fixed interval.
10166
+ *
10167
+ * The controller registers its own edit-watching `$effect` in the constructor,
10168
+ * so the SFC only has to construct it once during setup and read its reactive
10169
+ * `status` / `isDirty` for the toolbar indicator.
10170
+ */
10171
+ /**
10172
+ * Autosave status, surfaced for the toolbar status pill.
10173
+ *
10174
+ * - `idle` : nothing has been saved yet (or no edits since mount).
10175
+ * - `disabled` : autosave is inactive (off, not editable, or no file path).
10176
+ * - `saving` : a save is currently in flight.
10177
+ * - `saved` : the most recent save succeeded.
10178
+ * - `error` : the most recent save threw.
10179
+ */
10180
+ type AutosaveStatus = 'idle' | 'disabled' | 'saving' | 'saved' | 'error';
10181
+ interface AutosaveDeps {
10182
+ /** Master on/off: host `autosave` prop AND editing allowed. */
10183
+ getEnabled: () => boolean;
10184
+ /** Debounce window in milliseconds. */
10185
+ getIntervalMs: () => number;
10186
+ /** IndexedDB record key (host `filePath`); autosave is disabled without one. */
10187
+ getFilePath: () => string | undefined;
10188
+ /** The current editable slides (watched for edits). */
10189
+ getSlides: () => PptxSlide[];
10190
+ getSlideMasters?: () => PptxSlideMaster[];
10191
+ getNotesMaster?: () => PptxNotesMaster | undefined;
10192
+ getHandoutMaster?: () => PptxHandoutMaster | undefined;
10193
+ getSections?: () => PptxSection[];
10194
+ /** The live core handler used to serialize slides to `.pptx` bytes. */
10195
+ getHandler: () => PptxHandler | null;
10196
+ /**
10197
+ * Monotonic load counter: a change means a fresh presentation was seeded (not
10198
+ * a user edit), so the watcher clears dirty instead of arming a save.
10199
+ */
10200
+ getLoadCount: () => number;
10201
+ /** Host callback with the freshly-serialized bytes on each successful save. */
10202
+ onSaved?: (bytes: Uint8Array) => void;
10203
+ }
10204
+ declare class AutosaveController {
10205
+ #private;
10206
+ /** Current autosave lifecycle status (reactive). */
10207
+ status: AutosaveStatus;
10208
+ /** Whether there are unsaved edits pending (reactive). */
10209
+ isDirty: boolean;
10210
+ /** Epoch ms of the last successful save, or null (reactive). */
10211
+ lastSavedAt: number | null;
10212
+ constructor(deps: AutosaveDeps);
10213
+ /** Force an immediate save, bypassing the debounce window. */
10214
+ save(): Promise<void>;
10215
+ }
10216
+
10217
+ interface SlideCanvasProps {
10218
+ slide: PptxSlide | undefined;
10219
+ canvasSize: CanvasSize;
10220
+ mediaDataUrls: Map<string, string>;
10221
+ /** Effective scale (fit-to-viewport x user zoom), pre-computed by the host. */
10222
+ scale: number;
10223
+ /** True only on the live presentation stage; see `SlideStageProps.presenting`. */
10224
+ presenting?: boolean;
10225
+ /** True while in-place editing is available; gates the pointer handlers and the editing cursor/class. */
10226
+ editingActive?: boolean;
10227
+ editTemplateMode?: boolean;
10228
+ ontablecellcommit?: (elementId: string, rowIndex: number, cellIndex: number, text: string) => void;
10229
+ onsmartartnodecommit?: (elementId: string, nodeId: string, text: string) => void;
10230
+ onsmartartnodefill?: (elementId: string, nodeId: string, fill: string) => void;
10231
+ /** Reports the stage-holder node to the host on mount/teardown (editing hit-surface, export capture anchor). */
10232
+ onstageholder?: (el: HTMLDivElement | null) => void;
10233
+ onstagepointerdown?: (event: PointerEvent) => void;
10234
+ onstagepointermove?: (event: PointerEvent) => void;
10235
+ onstagedblclick?: (event: MouseEvent) => void;
10236
+ onstagecontextmenu?: (event: MouseEvent) => void;
10237
+ /** Fired on any stage click; the host wires this to advance presentation playback. */
10238
+ onstageclick?: (event: MouseEvent) => void;
10239
+ /**
10240
+ * True while the AI panel is picking an element: the next element click(s)
10241
+ * become the assistant's focus (highlighted) instead of selecting / editing.
10242
+ */
10243
+ aiPickMode?: boolean;
10244
+ /**
10245
+ * True while a running AI tool is active: the stage marks itself
10246
+ * `data-pptx-ai-active` so element colour changes tween while the assistant
10247
+ * works (see AiFocusHighlightOverlay's tween rule).
10248
+ */
10249
+ aiActive?: boolean;
10250
+ /** Route a picked canvas element to the AI focus (pick mode only). */
10251
+ onaipickelement?: (elementId: string) => void;
10252
+ /**
10253
+ * Overlay content layered above the slide (selection/editor layer, ink
10254
+ * drawing, alignment guides, presentation annotations, collaboration
10255
+ * cursors, transition overlay, ...). Rendered inside the same
10256
+ * fixed-size, scaled stage-holder as the slide itself. Kept out of this
10257
+ * component's own props (rather than a fixed list of overlay slots) so it
10258
+ * stays free of the live editor/controller instances those overlays need.
10259
+ */
10260
+ children?: svelte.Snippet;
10261
+ }
10262
+ interface ViewerToolbarProps {
10263
+ /** Active slide (0-based). */
10264
+ current: number;
10265
+ total: number;
10266
+ /** Currently-effective zoom percent (rounded). */
10267
+ zoomPercent: number;
10268
+ isFullscreen: boolean;
10269
+ onprev: () => void;
10270
+ onnext: () => void;
10271
+ onzoomin: () => void;
10272
+ onzoomout: () => void;
10273
+ onzoomfit: () => void;
10274
+ onfullscreen: () => void;
10275
+ /** Whether the Notes toggle button is shown (host has a notes panel). */
10276
+ showNotes?: boolean;
10277
+ /** Whether the notes panel is currently expanded (drives the pressed state). */
10278
+ notesExpanded?: boolean;
10279
+ onnotestoggle?: () => void;
10280
+ /** Show the editing action group (Undo / Redo / Save). Default false. */
10281
+ editable?: boolean;
10282
+ /** Whether an undo step is available (drives the Undo button's disabled state). */
10283
+ canUndo?: boolean;
10284
+ /** Whether a redo step is available (drives the Redo button's disabled state). */
10285
+ canRedo?: boolean;
10286
+ /** Whether there are unsaved edits (drives the Save button's emphasis). */
10287
+ dirty?: boolean;
10288
+ onundo?: () => void;
10289
+ onredo?: () => void;
10290
+ onsave?: () => void;
10291
+ ondownload?: () => void;
10292
+ /**
10293
+ * Autosave lifecycle status; when set (host opted into `autosave`) a small
10294
+ * status pill renders in the editing group. Omit to hide the pill entirely.
10295
+ */
10296
+ autosaveStatus?: AutosaveStatus;
10297
+ /** Whether there are unsaved autosave edits (drives the pill's "dirty" tone). */
10298
+ autosaveDirty?: boolean;
10299
+ /**
10300
+ * Export menu state (PNG / PDF / GIF / video / print). When set, the
10301
+ * toolbar renders the `ExportMenu` dropdown in its right-hand group,
10302
+ * matching the export affordance the React/Vue/Angular chrome exposes.
10303
+ * Omit to hide the menu (e.g. while no presentation is loaded).
10304
+ */
10305
+ exportUi?: ExportUiState;
10306
+ /** Opens the Share (collaboration) dialog. Omit to hide the button. */
10307
+ onshare?: () => void;
10308
+ /** Opens the Broadcast dialog. Omit to hide the button. */
10309
+ onbroadcast?: () => void;
10310
+ /** Whether a collaboration session is currently active (highlights the Share button). */
10311
+ collabActive?: boolean;
10312
+ /** Toolbar buttons to hide; see `PowerPointViewerProps.hiddenActions`. Default undefined: nothing hidden. */
10313
+ hiddenActions?: ToolbarActionId[];
10314
+ }
10315
+
10316
+ /**
10317
+ * Reactive Find & Replace panel state for the Home tab's Editing group.
10318
+ * Wraps the shared, framework-agnostic `render/find-replace` functions
10319
+ * (pure slide-array search/replace); this class owns only the panel's UI
10320
+ * state (query, current match, open/closed) and routes every replace through
10321
+ * the host's history-tracked commit so undo/redo cover it.
10322
+ */
10323
+ interface FindReplaceDeps {
10324
+ getSlides(): readonly PptxSlide[];
10325
+ /** Commit a fully-replaced slide array (pushes history, marks dirty). */
10326
+ commitSlides(next: PptxSlide[]): void;
10327
+ /** Called with the match's slide/element so the host can navigate to it. */
10328
+ onNavigate?(slideIndex: number, elementId: string): void;
10329
+ }
10330
+ declare class FindReplaceState {
10331
+ #private;
10332
+ open: boolean;
10333
+ query: string;
10334
+ replacement: string;
10335
+ matchCase: boolean;
10336
+ results: FindResult[];
10337
+ index: number;
10338
+ constructor(deps: FindReplaceDeps);
10339
+ get hasResults(): boolean;
10340
+ get matchCount(): number;
10341
+ toggle(): void;
10342
+ close(): void;
10343
+ /** Re-run the search from the current query/matchCase and jump to the first match. */
10344
+ search(): void;
10345
+ next(): void;
10346
+ prev(): void;
10347
+ /** Replace the current match, then refresh the result set. */
10348
+ replaceCurrent(): void;
10349
+ /** Replace every match of the current query, then refresh the result set. */
10350
+ replaceAll(): void;
10351
+ }
10352
+
10353
+ /**
10354
+ * ChromeUiState: reactive open/collapsed state for the editing chrome's side
10355
+ * panels, mirroring React's `useViewerState` flags (`isSidebarCollapsed`,
10356
+ * `isInspectorPaneOpen`, `inspectorTab`). Owned by `PowerPointViewer` and
10357
+ * threaded to both the ribbon's primary row (the toggle buttons) and
10358
+ * `ViewerBody` (which gates the thumbnail rail and inspector pane on it).
10359
+ */
10360
+ /** The inspector pane's tab strip, matching React's `InspectorTab`. */
10361
+ type InspectorTabId = 'elements' | 'properties' | 'comments';
10362
+ declare class ChromeUiState {
10363
+ /** Left thumbnail rail visibility (React: `isSidebarCollapsed`). */
10364
+ sidebarCollapsed: boolean;
10365
+ /** Right inspector pane visibility (React: `isInspectorPaneOpen`). */
10366
+ inspectorOpen: boolean;
10367
+ /** Active inspector tab (React defaults to Properties). */
10368
+ inspectorTab: InspectorTabId;
10369
+ toggleSidebar(): void;
10370
+ toggleInspector(): void;
10371
+ setInspectorTab(tab: InspectorTabId): void;
10372
+ /** Comments toolbar button: toggle the inspector's Comments tab. */
10373
+ toggleComments(): void;
10374
+ /** True when the inspector is showing the Comments tab. */
10375
+ get commentsOpen(): boolean;
10376
+ }
10377
+
10378
+ /**
10379
+ * Prop contracts for the ribbon shell and its tabs. Kept in a plain `.ts`
10380
+ * module per repo convention: SFCs stay thin presentation, types live in
10381
+ * lintable TypeScript files.
10382
+ */
10383
+ interface RibbonProps {
10384
+ fileName?: string;
10385
+ /** History-tracked editor state; Home/Insert tab groups read/write it directly. */
10386
+ editor: EditorState;
10387
+ /** Reactive Find & Replace panel state, owned by the host so it can navigate the viewer. */
10388
+ findReplace: FindReplaceState;
10389
+ /** Slide canvas size (px); the Insert tab centres new charts/media/SmartArt/etc. on it. */
10390
+ canvasSize: CanvasSize;
10391
+ /** Read-only deck: the full ribbon still renders (React parity) but a
10392
+ read-only badge shows in the primary row and edits are inert. */
10393
+ readOnly?: boolean;
10394
+ /** Compact nav row (always visible): active slide (0-based) / total. */
10395
+ current: number;
10396
+ total: number;
10397
+ onprev: () => void;
10398
+ onnext: () => void;
10399
+ /** Move the viewer to a specific slide index (the Home tab's Slides group). */
10400
+ onnavigateslide: (index: number) => void;
10401
+ /** Primary row: undo/redo/save/download + autosave pill. */
10402
+ canUndo: boolean;
10403
+ canRedo: boolean;
10404
+ dirty: boolean;
10405
+ onundo: () => void;
10406
+ onredo: () => void;
10407
+ onsave: () => void;
10408
+ ondownload: () => void;
10409
+ ondownloadppsx: () => void;
10410
+ ondownloadpptm: () => void;
10411
+ onpackage: () => void;
10412
+ onversionhistory: () => void;
10413
+ hasMacros: boolean;
10414
+ embeddedFontNames: string[];
10415
+ hasDigitalSignatures: boolean;
10416
+ digitalSignatureCount: number;
10417
+ isPasswordProtected: boolean;
10418
+ autosaveStatus?: AutosaveStatus;
10419
+ autosaveDirty?: boolean;
10420
+ /** Collaboration entry points: Share on the tab row, broadcast in the Present dropdown (React parity). */
10421
+ onshare?: () => void;
10422
+ onbroadcast?: () => void;
10423
+ collabActive?: boolean;
10424
+ /** Side-panel (slides rail / inspector) open state + toggles for the primary row. */
10425
+ chromeUi?: ChromeUiState;
10426
+ /** Whether live subtitles are currently enabled (Present dropdown checkmark). */
10427
+ subtitlesEnabled?: boolean;
10428
+ /** Toggle the AI assistant panel. Only wired when the viewer's `ai` prop is set. */
10429
+ onai?: () => void;
10430
+ /** Whether the AI assistant panel is currently open (primary-row toggle state). */
10431
+ aiActive?: boolean;
10432
+ /** Toolbar buttons/ribbon tabs to hide; see `PowerPointViewerProps.hiddenActions`. */
10433
+ hiddenActions?: ToolbarActionId[];
10434
+ /** Slide Show tab actions: enter presentation from slide 0 or the current slide. */
10435
+ onfrombeginning: () => void;
10436
+ onfromcurrent: () => void;
10437
+ onpresenter: () => void;
10438
+ onsetupslideshow: () => void;
10439
+ onheaderfooter: () => void;
10440
+ oncompare: () => void;
10441
+ onshortcuts: () => void;
10442
+ onsettings: () => void;
10443
+ onprintsettings: () => void;
10444
+ onrehearse: () => void;
10445
+ onrecordfrombeginning: () => void;
10446
+ onrecordfromcurrent: () => void;
10447
+ onsubtitles: () => void;
10448
+ oncustomshows: () => void;
10449
+ onselectionpane: () => void;
10450
+ onslidesorter: () => void;
10451
+ preferences: ViewerPreferences;
10452
+ onpreferenceschange: (preferences: ViewerPreferences) => void;
10453
+ showGuides: boolean;
10454
+ onshowguideschange: (show: boolean) => void;
10455
+ snapToShape: boolean;
10456
+ onsnapToShapechange: (enabled: boolean) => void;
10457
+ onaddguide: (axis: 'h' | 'v') => void;
10458
+ /** Review tab: presentation-wide accessibility audit and issue navigation. */
10459
+ slides: readonly PptxSlide[];
10460
+ onnavigatetoissue: (slideIndex: number, elementId?: string) => void;
10461
+ /** View tab: zoom / fullscreen / notes toggle. */
10462
+ zoomPercent: number;
10463
+ onzoomin: () => void;
10464
+ onzoomout: () => void;
10465
+ onzoomfit: () => void;
10466
+ isFullscreen: boolean;
10467
+ onfullscreen: () => void;
10468
+ showNotes?: boolean;
10469
+ notesExpanded?: boolean;
10470
+ onnotestoggle?: () => void;
10471
+ /** Opens the dedicated slide-master and layout navigation workspace. */
10472
+ onentermasterview?: () => void;
10473
+ /** File tab: export menu (PNG / PDF / GIF / video / print). */
10474
+ exportUi?: ExportUiState;
10475
+ onopenfile?: () => void;
10476
+ onopenrecent?: (key: string) => void;
10477
+ /**
10478
+ * Design tab: the current effective viewer-chrome theme (for highlighting
10479
+ * the active swatch) and the setter its gallery calls to switch presets.
10480
+ */
10481
+ theme: ViewerTheme | undefined;
10482
+ onsettheme: (theme: ViewerTheme | undefined) => void;
10483
+ /** File tab > Account: disabled-by-default sign-in hook point. */
10484
+ accountAuth?: AccountAuthConfig;
10485
+ }
10486
+
10487
+ /**
10488
+ * Explicitly-typed public exports of the standalone view components.
10489
+ *
10490
+ * Same rationale as `PowerPointViewer` in `../component.ts`: `svelte-check`
10491
+ * types `.svelte` imports precisely, but the plain TypeScript pass that emits
10492
+ * the published declaration files resolves `.svelte` modules through a loose
10493
+ * ambient shim (`src/shims-svelte.d.ts`), and the post-build Rollup
10494
+ * declaration bundling cannot resolve a raw `.svelte` specifier at all (no
10495
+ * `.svelte.d.ts` is emitted, which broke the library build on CI). Re-export
10496
+ * through annotated constants so the published `.d.ts` is fully typed and
10497
+ * free of `.svelte` specifiers.
10498
+ */
10499
+ declare const Ribbon: Component<RibbonProps>;
10500
+ declare const ViewerToolbar: Component<ViewerToolbarProps>;
10501
+ declare const SlideCanvas: Component<SlideCanvasProps>;
10502
+
10503
+ /** Live editor accessors the bridge closes over (all read from viewer runes). */
10504
+ interface SvelteAiBridgeDeps {
10505
+ /** The editable slides array (the single source of truth the AI mutates). */
10506
+ getSlides(): PptxSlide[];
10507
+ /** Zero-based index of the active slide. */
10508
+ getActiveSlideIndex(): number;
10509
+ /** Slide canvas size in CSS pixels. */
10510
+ getCanvasSize(): {
10511
+ width: number;
10512
+ height: number;
10513
+ };
10514
+ /** The resolved presentation theme, when available. */
10515
+ getTheme(): PptxTheme | undefined;
10516
+ /** The loaded core handler, or null before a deck is open. */
10517
+ getHandler(): PptxHandler | null;
10518
+ /** Optional display file name, used as a friendly deck title. */
10519
+ getFileName(): string | undefined;
10520
+ /** Navigate the viewer to a slide by zero-based index. */
10521
+ goToSlide(index: number): void;
10522
+ /** Select elements on a slide (navigates first when off-slide). */
10523
+ selectElements(slideIndex: number, elementIds: string[]): void;
10524
+ /**
10525
+ * Install a new slides array as ONE undoable history entry. The
10526
+ * implementation is responsible for ensuring the editor is editable (so the
10527
+ * commit is not silently dropped) before recording the step.
10528
+ */
10529
+ commitSlides(next: PptxSlide[], label: string): void;
10530
+ /** Apply partial theme updates (colour/font scheme) and re-render. */
10531
+ applyTheme(updates: Partial<PptxTheme>): void;
10532
+ /** Optional host notification sink (status line / toast / console). */
10533
+ notify?(message: string, level?: PptxAiNotifyLevel): void;
10534
+ /** Deck sections (editor-tracked, undoable). */
10535
+ getSections(): PptxSection[];
10536
+ /** Deck-wide slide-show / print settings (editor-tracked, undoable). */
10537
+ getPresentationProperties(): PptxPresentationProperties;
10538
+ /** Document core properties (Title / Author / ...), when present. */
10539
+ getCoreProperties(): PptxCoreProperties | undefined;
10540
+ /** Application properties (Company / Application), when present. */
10541
+ getAppProperties(): PptxAppProperties | undefined;
10542
+ /** Custom document-property list (editor-tracked, undoable). */
10543
+ getCustomProperties(): PptxCustomProperty[];
10544
+ /** Resize the slide canvas (loader value + editor history entry). */
10545
+ setCanvasSize(size: {
10546
+ width: number;
10547
+ height: number;
10548
+ }): void;
10549
+ /** Replace the section list. */
10550
+ setSections(sections: PptxSection[]): void;
10551
+ /** Replace the deck-wide presentation properties. */
10552
+ setPresentationProperties(props: PptxPresentationProperties): void;
10553
+ /**
10554
+ * Replace the document properties as one unit. Svelte's editor commits
10555
+ * core / app / custom together, so the bridge fans all three through here.
10556
+ */
10557
+ setDocumentProperties(core: PptxCoreProperties, app: PptxAppProperties, custom: PptxCustomProperty[]): void;
10558
+ }
10559
+ /** Build the AI bridge that exposes the live Svelte viewer to the AI core. */
10560
+ declare function createSvelteAiBridge(deps: SvelteAiBridgeDeps): PptxAiBridge;
10561
+
8369
10562
  /**
8370
10563
  * Pure slide-navigation and zoom-step helpers for the Svelte viewer.
8371
10564
  * Kept framework-free so they are trivially unit-testable.
@@ -8483,5 +10676,562 @@ declare class ViewerState {
8483
10676
  handleNavigationKey(key: string): boolean;
8484
10677
  }
8485
10678
 
8486
- export { PowerPointViewer, PresentationLoader, ViewerState, clampSlideIndex, exportAllSlidesToSvg, exportAllSlidesToSvgBlobs, exportSlideAsSvg, exportSlideToSvg, exportSlideToSvgBlob, fitScale, resolveNavigationKey, zoomInPercent, zoomOutPercent };
8487
- export type { CanvasSize, ExportGifOptions, ExportPdfOptions, ExportVideoOptions, NavigationAction, PowerPointViewerApi, PowerPointViewerProps, PrintOptions, SvgExportAllOptions, SvgExportSingleSlideOptions, ViewerLoadDetail, ViewerTheme };
10679
+ /** A transport-agnostic view of a live Yjs provider. */
10680
+ interface CollabProviderHandle {
10681
+ /** The provider's awareness instance (local/remote presence). */
10682
+ awareness: AwarenessLike;
10683
+ /**
10684
+ * Subscribe to connection-status changes. The callback receives whether the
10685
+ * transport currently reports a connection. Only meaningful for websocket;
10686
+ * webrtc callers rely on {@link connectedNow} instead.
10687
+ */
10688
+ onStatus: (cb: (connected: boolean) => void) => void;
10689
+ /** Whether the transport reports a connection immediately after creation. */
10690
+ connectedNow: boolean;
10691
+ /**
10692
+ * Subscribe to the provider's initial-document-sync confirmation. Websocket
10693
+ * fires reliably once the server sync completes; webrtc only fires when a
10694
+ * peer syncs with us (a lone fresh-room peer never receives one, so callers
10695
+ * pair this with a grace timer, see the shared createSyncGate).
10696
+ */
10697
+ onSynced: (cb: () => void) => void;
10698
+ /** Whether the provider already reports its initial sync as complete. */
10699
+ syncedNow: boolean;
10700
+ /** Tear the provider down (disconnect + destroy). */
10701
+ destroy: () => void;
10702
+ }
10703
+
10704
+ /** A fully-wired collaboration session: the doc, its factories, and transport. */
10705
+ interface CollabSession {
10706
+ /** The live Y.Doc (structural view used by the shared reconcile helpers). */
10707
+ ydoc: YDocLike;
10708
+ /** Factories the shared reconcile helpers use to build Y.Map/Array/Text. */
10709
+ factories: YjsFactories;
10710
+ /** The normalised transport provider handle. */
10711
+ provider: CollabProviderHandle;
10712
+ /** Tear down the provider and destroy the doc. */
10713
+ destroy: () => void;
10714
+ }
10715
+ /**
10716
+ * Build a live session for the given transport + config. Injectable so tests
10717
+ * can substitute an in-memory fake (see `collaboration.svelte.ts`).
10718
+ */
10719
+ type CollabSessionFactory = (transport: CollaborationTransport, config: CollaborationConfig) => Promise<CollabSession>;
10720
+
10721
+ interface CollaborationDeps {
10722
+ /** Read the current local slides (broadcast granularly on change). */
10723
+ getSlides: () => PptxSlide[];
10724
+ /** Apply a remote peer's slide snapshot into the editable slides. */
10725
+ applyRemoteSlides: (slides: PptxSlide[]) => void;
10726
+ /** Live host `collaboration` config; watched to auto start/stop a session. */
10727
+ getConfig: () => CollaborationConfig | undefined;
10728
+ /** Return the loaded source bytes for elected-writer (role 'owner') write-back. */
10729
+ getSourceBytes?: () => Uint8Array | null;
10730
+ /** Slide canvas width/height (unscaled px), used to clamp incoming cursor coordinates. */
10731
+ getCanvasWidth?: () => number | undefined;
10732
+ getCanvasHeight?: () => number | undefined;
10733
+ /** Fired when a session starts (host observability). */
10734
+ onStart?: (config: CollaborationConfig) => void;
10735
+ /** Fired when a session stops (host observability). */
10736
+ onStop?: () => void;
10737
+ /** Session factory seam (defaults to the real yjs + transport wiring). */
10738
+ createSession?: CollabSessionFactory;
10739
+ }
10740
+
10741
+ /**
10742
+ * The collaboration controller. Construct it once during component setup: it
10743
+ * registers the two effects (auto start/stop from the config, granular publish
10744
+ * of local edits) itself, so no further wiring is needed in the SFC.
10745
+ */
10746
+ declare class CollaborationController {
10747
+ #private;
10748
+ /** Live connection status (reactive). */
10749
+ status: ConnectionStatus;
10750
+ constructor(deps: CollaborationDeps);
10751
+ /** Whether a session is live (reactive). */
10752
+ get active(): boolean;
10753
+ /** Read-only participant (session live with the `viewer` role) - cannot select/drag/mutate. */
10754
+ get readOnly(): boolean;
10755
+ /** Remote cursors on the current slide (reactive). */
10756
+ get cursors(): RemoteCursor[];
10757
+ /** Remote collaborators in the session (reactive). */
10758
+ get remotePresences(): SanitizedPresence[];
10759
+ /** Followed peer's client id, or null when free (reactive). */
10760
+ get followedClientId(): number | null;
10761
+ /** Publish a cursor move (slide-space px); no-op when no session is active. */
10762
+ setCursor(x: number, y: number, activeSlideIndex?: number): void;
10763
+ /** Publish the local selection; no-op when no session is active. */
10764
+ setSelection(selectedElementId: string | undefined, activeSlideIndex?: number): void;
10765
+ /** Publish the local active-slide index (drives peer follow-along). */
10766
+ setActiveSlide(index: number): void;
10767
+ /** Follow the given peer's active slide, or `null` to stop following. */
10768
+ followUser(clientId: number | null): void;
10769
+ /**
10770
+ * Re-adopt the shared doc's slides after a local content load committed a
10771
+ * parsed deck to viewer state (see `adoptDocSlidesAfterLoad`). The load
10772
+ * pipeline calls this synchronously right after it applies, i.e. before the
10773
+ * publish effect can flush the freshly loaded slides into the doc, so a
10774
+ * late joiner's bootstrap deck never clobbers the room's synced content.
10775
+ */
10776
+ adoptDocAfterLoad(): void;
10777
+ /** Start (or restart) a session with the given config (dialog-driven). */
10778
+ start(config: CollaborationConfig): Promise<void>;
10779
+ stop(): void;
10780
+ }
10781
+
10782
+ /** Prefilled values for the Share dialog's form (Broadcast reuses `serverUrl`). */
10783
+ interface ShareDefaultsInput {
10784
+ roomId?: string;
10785
+ userName?: string;
10786
+ serverUrl?: string;
10787
+ }
10788
+ declare class CollaborationDialogsState {
10789
+ #private;
10790
+ shareOpen: boolean;
10791
+ broadcastOpen: boolean;
10792
+ constructor(collab: CollaborationController, getShareDefaults: () => ShareDefaultsInput | undefined);
10793
+ /** Number of connected participants (including the local user), when active. */
10794
+ get connectedCount(): number;
10795
+ /** The shareable follow link for the current (or last) broadcast, once known. */
10796
+ get broadcastViewerUrl(): string | undefined;
10797
+ openShare(): void;
10798
+ openBroadcast(): void;
10799
+ readonly onShareStart: (config: CollaborationConfig) => void;
10800
+ readonly onShareStop: () => void;
10801
+ readonly onBroadcastStart: (config: BroadcastConfig) => void;
10802
+ readonly onBroadcastStop: () => void;
10803
+ /**
10804
+ * Retry the active session after a connection error: prefers the host's
10805
+ * live `collaboration` prop, falling back to whatever config either dialog
10806
+ * last started (since a dialog-started session has no corresponding prop).
10807
+ */
10808
+ retry(propConfig: CollaborationConfig | undefined): void;
10809
+ }
10810
+
10811
+ /** The imperative editing API exposed on the `PowerPointViewer` instance. */
10812
+ interface EditingApi {
10813
+ undo(): void;
10814
+ redo(): void;
10815
+ canUndo(): boolean;
10816
+ canRedo(): boolean;
10817
+ deleteSelected(): void;
10818
+ getSelectedElementId(): string | null;
10819
+ save(format?: PptxSaveFormat): Promise<Uint8Array>;
10820
+ downloadAs(format: PptxSaveFormat, fileName?: string): Promise<void>;
10821
+ downloadPptx(fileName?: string): Promise<void>;
10822
+ packageForSharing(fileName?: string): Promise<void>;
10823
+ }
10824
+
10825
+ /**
10826
+ * `AnimationPlayback`: native-timing (`p:timing`) animation playback for the
10827
+ * Svelte binding's presentation mode, driven by the shared, framework-agnostic
10828
+ * {@link PresentationAnimationController}. The runes analogue of the Vue
10829
+ * `useAnimationPlayback` composable, kept out of the SFC so it is unit-testable.
10830
+ *
10831
+ * This replaces the older preset (`PptxElementAnimation`) click-group model for
10832
+ * the slide show: the controller builds a timeline engine from the slide's
10833
+ * `nativeAnimations` (expanding staged text builds), which can represent native
10834
+ * staged chart / SmartArt builds (`p:bldChart` / `p:bldDgm`) and colour
10835
+ * animations (`p:animClr`) that the preset model could not. It mirrors the Vue /
10836
+ * React bindings.
10837
+ *
10838
+ * The class owns the reactive per-element state map, the keyframes CSS, and the
10839
+ * interactive / hover trigger-shape id sets; the controller stays pure. The
10840
+ * clock (timers, requestAnimationFrame) + DOM effects live in
10841
+ * {@link module:presentation/animation-playback-helpers}.
10842
+ *
10843
+ * NOTE: the editor / inspector animation PREVIEW still uses the older shared
10844
+ * `buildClickGroups` model (see `AnimationsTab` / `editor-animation-controller`);
10845
+ * this class is only the running slide show.
10846
+ */
10847
+ interface AnimationPlaybackDeps {
10848
+ /** The current slide to build the native-animation timeline for. */
10849
+ getSlide(): PptxSlide | undefined;
10850
+ /** Presentation-level switch parsed from `p:showPr`. */
10851
+ getShowWithAnimation?(): boolean | undefined;
10852
+ /** Host-provided action-sound player (resolves + plays embedded sounds). */
10853
+ onPlayActionSound?: (soundPath: string) => void;
10854
+ /** Root element to scope media-command (`p:cmd`) target lookups to. */
10855
+ frameRoot?: () => HTMLElement | null;
10856
+ }
10857
+ declare class AnimationPlayback {
10858
+ #private;
10859
+ constructor(deps: AnimationPlaybackDeps);
10860
+ /** Reactive per-element native-animation state (visibility, build, colour). */
10861
+ get elementStates(): Map<string, ElementAnimationState>;
10862
+ /** The per-slide `@keyframes` CSS to inject once per slide. */
10863
+ get keyframesCss(): string;
10864
+ /** Shape ids that trigger an interactive (`onShapeClick`) sequence. */
10865
+ get interactiveTriggerShapeIds(): ReadonlySet<string>;
10866
+ /** Shape ids that trigger a hover (`onHover`) sequence. */
10867
+ get hoverTriggerShapeIds(): ReadonlySet<string>;
10868
+ /** True once every main-timeline click-group has been revealed. */
10869
+ get isComplete(): boolean;
10870
+ /** Clear all pending timers + the in-flight staged-build RAF. */
10871
+ clearTimers(): void;
10872
+ /**
10873
+ * Rebuild the controller for the current slide and replay from the start. The
10874
+ * controller builds the timeline engine (expanding text-build animations) and
10875
+ * derives keyframes CSS, trigger-shape ids, and the tracked element id list.
10876
+ */
10877
+ reset(): void;
10878
+ /**
10879
+ * Reveal the next click-group. Returns `true` if a group was revealed, `false`
10880
+ * when playback is complete or animations are disabled (so the caller can fall
10881
+ * through to slide navigation).
10882
+ */
10883
+ advance(): boolean;
10884
+ /** Play an interactive shape's sequence; `true` when it triggered one. */
10885
+ handleInteractiveShapeClick(shapeId: string): boolean;
10886
+ /** Play a hover shape's sequence; `true` when it triggered one. */
10887
+ handleHoverStart(shapeId: string): boolean;
10888
+ /** Reset a hover shape's sequence so the next hover replays it. */
10889
+ handleHoverEnd(shapeId: string): void;
10890
+ }
10891
+
10892
+ /**
10893
+ * `PresentationController`: the runes state machine wiring the Svelte viewer's
10894
+ * fullscreen (presentation) mode to the framework-agnostic animation and
10895
+ * slide-transition helpers in `pptx-viewer-shared`.
10896
+ *
10897
+ * It owns:
10898
+ * - an {@link AnimationPlayback} for the current slide's click-stepped element
10899
+ * builds, and
10900
+ * - the transient slide-transition state (outgoing + incoming slide + the
10901
+ * resolved transition) rendered by `PresentationTransitionOverlay`.
10902
+ *
10903
+ * `advance()` implements the on-click contract: reveal the next animation build
10904
+ * first, and only advance the slide once the slide's builds are exhausted.
10905
+ * `onSlideChange` / `start` / `stop` are driven from a `$effect` in the viewer
10906
+ * (see `usePresentationEffects`) as the fullscreen flag and current slide move.
10907
+ *
10908
+ * Matches the Vue binding's presentation-mode behaviour (its parity bar):
10909
+ * click-stepped element animations, CSS-driven slide transitions on every slide
10910
+ * change, entrance elements hidden until revealed. Since the native-timing
10911
+ * migration it also drives staged chart / SmartArt builds (`p:bldChart` /
10912
+ * `p:bldDgm`), `p:animClr` colour animations, withPrevious / afterPrevious
10913
+ * auto-advance, and interactive / hover trigger sequences. Still no presenter
10914
+ * view (React-only).
10915
+ */
10916
+ interface TransitionState {
10917
+ /** The outgoing (previous) slide, rendered in the exit layer. */
10918
+ outgoing: PptxSlide | undefined;
10919
+ /** The incoming (new) slide, rendered in the entrance layer. */
10920
+ incoming: PptxSlide | undefined;
10921
+ /** The incoming slide's transition (drives the CSS animation shorthands). */
10922
+ transition: PptxSlideTransition;
10923
+ }
10924
+ interface PresentationControllerDeps {
10925
+ /** The live, editable slide array (single source of truth). */
10926
+ getSlides(): PptxSlide[];
10927
+ /** The active slide index (0-based). */
10928
+ getCurrentIndex(): number;
10929
+ /** Navigate to a slide index (clamped by the caller's viewer state). */
10930
+ navigate(index: number): void;
10931
+ /** Presentation-level switch parsed from `p:showPr`. */
10932
+ getShowWithAnimation?(): boolean | undefined;
10933
+ /** Host-provided action-sound player (resolves + plays embedded sounds). */
10934
+ onPlayActionSound?: (soundPath: string) => void;
10935
+ /** The live presentation stage root, to scope media-command lookups to. */
10936
+ getFrameRoot?(): HTMLElement | null;
10937
+ }
10938
+ declare class PresentationController {
10939
+ #private;
10940
+ readonly playback: AnimationPlayback;
10941
+ constructor(deps: PresentationControllerDeps);
10942
+ /** The active slide-transition overlay state, or `null` when none is playing. */
10943
+ get transition(): TransitionState | null;
10944
+ /** Reactive per-element native-animation state (visibility, build, colour). */
10945
+ get elementStates(): Map<string, ElementAnimationState>;
10946
+ /** The per-slide native-animation `@keyframes` CSS to inject. */
10947
+ get keyframesCss(): string;
10948
+ /** Shape ids that trigger an interactive (`onShapeClick`) sequence. */
10949
+ get interactiveTriggerShapeIds(): ReadonlySet<string>;
10950
+ /** Shape ids that trigger a hover (`onHover`) sequence. */
10951
+ get hoverTriggerShapeIds(): ReadonlySet<string>;
10952
+ /** Play an interactive shape's sequence; `true` when it triggered one. */
10953
+ handleInteractiveShapeClick(shapeId: string): boolean;
10954
+ /** Play a hover shape's sequence; `true` when it triggered one. */
10955
+ handleHoverStart(shapeId: string): boolean;
10956
+ /** Reset a hover shape's sequence so the next hover replays it. */
10957
+ handleHoverEnd(shapeId: string): void;
10958
+ /**
10959
+ * The on-click advance contract: reveal the next element-animation build if
10960
+ * one remains, otherwise advance to the next slide.
10961
+ *
10962
+ * `fromClick` marks a click/tap/swipe on the slide, which is PowerPoint's
10963
+ * "on mouse click" advance: it still steps the remaining animation builds,
10964
+ * but once they are exhausted it advances the slide only when the current
10965
+ * slide's transition allows it (advanceOnClick !== false). Keyboard and the
10966
+ * on-screen next button pass `fromClick = false` and are never gated.
10967
+ */
10968
+ advance(fromClick?: boolean): void;
10969
+ /** Entering presentation: seed builds for the current slide, drop any overlay. */
10970
+ start(): void;
10971
+ /** Leaving presentation: clear timers, reset builds, drop any overlay. */
10972
+ stop(): void;
10973
+ /**
10974
+ * The presented slide changed: reset the new slide's builds and, when the
10975
+ * incoming slide carries a real transition, play it over the frame.
10976
+ */
10977
+ onSlideChange(previousIndex: number, nextIndex: number): void;
10978
+ /** The transition overlay finished its animation: drop it. */
10979
+ endTransition(): void;
10980
+ }
10981
+
10982
+ interface PresenterSessionOptions {
10983
+ getSource: () => Uint8Array | ArrayBuffer | null | undefined;
10984
+ getSlideIndex: () => number;
10985
+ onAudienceSlide: (index: number) => void;
10986
+ onAudienceExit: () => void;
10987
+ }
10988
+ declare class PresenterSession {
10989
+ private readonly options;
10990
+ audienceOpen: boolean;
10991
+ snapshot: PresentationSnapshot;
10992
+ readonly audienceSessionId: string | null;
10993
+ readonly isAudience: boolean;
10994
+ private channel;
10995
+ private audienceWindow;
10996
+ private presenterSessionId;
10997
+ private sequence;
10998
+ constructor(options: PresenterSessionOptions);
10999
+ connect(): void;
11000
+ openAudience(): boolean;
11001
+ sync(slideIndex?: number): void;
11002
+ updateSnapshot(patch: Partial<PresentationSnapshot>): void;
11003
+ closeAudience(): void;
11004
+ dispose(): void;
11005
+ private getChannel;
11006
+ }
11007
+
11008
+ declare class CompareController {
11009
+ #private;
11010
+ result: CompareResult | null;
11011
+ open: boolean;
11012
+ accepted: Set<number>;
11013
+ rejected: Set<number>;
11014
+ constructor(editor: EditorState);
11015
+ chooseFile(): Promise<void>;
11016
+ accept(index: number): void;
11017
+ reject(index: number): void;
11018
+ acceptAll(): void;
11019
+ }
11020
+
11021
+ type PresentationInkTool = 'none' | 'pen' | 'highlighter' | 'eraser' | 'laser';
11022
+ interface PresentationStroke {
11023
+ id: string;
11024
+ points: InkPoint[];
11025
+ color: string;
11026
+ width: number;
11027
+ tool: 'pen' | 'highlighter';
11028
+ }
11029
+ declare class PresentationAnnotations {
11030
+ #private;
11031
+ tool: PresentationInkTool;
11032
+ color: string;
11033
+ current: PresentationStroke | null;
11034
+ bySlide: Map<number, PresentationStroke[]>;
11035
+ laser: InkPoint | null;
11036
+ get count(): number;
11037
+ get slideCount(): number;
11038
+ strokes(index: number): PresentationStroke[];
11039
+ pointerDown(index: number, point: InkPoint): void;
11040
+ pointerMove(index: number, point: InkPoint): void;
11041
+ pointerUp(index: number): void;
11042
+ erase(index: number, point: InkPoint): void;
11043
+ clear(): void;
11044
+ keep(editor: EditorState): void;
11045
+ }
11046
+
11047
+ declare class RehearseState {
11048
+ #private;
11049
+ active: boolean;
11050
+ paused: boolean;
11051
+ summaryOpen: boolean;
11052
+ times: Map<number, number>;
11053
+ current: number;
11054
+ elapsedMs: number;
11055
+ start(index: number): void;
11056
+ tick(): void;
11057
+ move(index: number): void;
11058
+ togglePause(): void;
11059
+ finish(): void;
11060
+ record(): void;
11061
+ save(editor: EditorState): void;
11062
+ discard(): void;
11063
+ get totalMs(): number;
11064
+ }
11065
+
11066
+ /** Reactive state for the optional parity dialogs and presentation tools. */
11067
+ declare class ViewerParityUiState {
11068
+ readonly compare: CompareController;
11069
+ readonly annotations: PresentationAnnotations;
11070
+ readonly rehearse: RehearseState;
11071
+ setupSlideShowOpen: boolean;
11072
+ headerFooterOpen: boolean;
11073
+ settingsOpen: boolean;
11074
+ shortcutsOpen: boolean;
11075
+ keepAnnotationsOpen: boolean;
11076
+ printSettingsOpen: boolean;
11077
+ subtitlesEnabled: boolean;
11078
+ customShowsOpen: boolean;
11079
+ selectionPaneOpen: boolean;
11080
+ slideSorterOpen: boolean;
11081
+ showGuides: boolean;
11082
+ snapToShape: boolean;
11083
+ guides: {
11084
+ axis: "h" | "v";
11085
+ position: number;
11086
+ }[];
11087
+ preferences: ViewerPreferences;
11088
+ constructor(editor: EditorState);
11089
+ syncAutosave(enabled: boolean): void;
11090
+ updatePreferences(next: ViewerPreferences, onAutosaveChange: (enabled: boolean) => void): void;
11091
+ }
11092
+
11093
+ /**
11094
+ * Options accepted by {@link createViewerState}. Mirrors the subset of
11095
+ * `PowerPointViewerProps` the extracted construction block (formerly
11096
+ * inlined at the top of `PowerPointViewer.svelte`'s `<script>`) closes
11097
+ * over, plus getter callbacks for the handful of DOM-bound values
11098
+ * (`bind:this` / `bind:clientWidth` targets) that must stay owned by
11099
+ * whichever component renders the actual markup.
11100
+ */
11101
+ interface CreateViewerStateOptions {
11102
+ getSource: () => Uint8Array | ArrayBuffer | null | undefined;
11103
+ collaboration?: CollaborationConfig;
11104
+ shareDefaults?: ShareDefaultsInput;
11105
+ /** Host `autosave` prop (post-effect value the caller keeps in sync). */
11106
+ getAutosave: () => boolean;
11107
+ autosaveIntervalMs?: number;
11108
+ getFilePath: () => string | undefined;
11109
+ getInitialSlide: () => number;
11110
+ /** Already locale-bound translator; propagated to descendants via context. */
11111
+ t: Translator;
11112
+ getSmartArt3D: () => boolean;
11113
+ /** Whether in-place editing is enabled (host `editable` prop, post-effect value). */
11114
+ getEditable: () => boolean;
11115
+ onload?: (detail: ViewerLoadDetail) => void;
11116
+ onerror?: (message: string) => void;
11117
+ onslidechange?: (index: number) => void;
11118
+ onnotesupdate?: (notes: string) => void;
11119
+ onchange?: () => void;
11120
+ ondirtychange?: (dirty: boolean) => void;
11121
+ oncontentchange?: (content: Uint8Array) => void;
11122
+ onmodechange?: (mode: ViewerMode) => void;
11123
+ onzoomchange?: (zoom: number) => void;
11124
+ onselectionchange?: (elementIds: string[]) => void;
11125
+ onslidecountchange?: (count: number) => void;
11126
+ onautosave?: (bytes: Uint8Array) => void;
11127
+ /** Fired when the host toggles AutoSave (title bar / Settings dialog). */
11128
+ onautosavetoggle?: (enabled: boolean) => void;
11129
+ onstartcollaboration?: (config: CollaborationConfig) => void;
11130
+ onstopcollaboration?: () => void;
11131
+ /** DOM-bound getters, supplied by the component that owns the markup. */
11132
+ getStageHolderEl: () => HTMLDivElement | undefined;
11133
+ getRootEl: () => HTMLDivElement | undefined;
11134
+ getViewportWidth: () => number;
11135
+ getViewportHeight: () => number;
11136
+ /** Master/layout workspace zoom, assigned by `MasterViewBody`. */
11137
+ getMasterScale: () => number;
11138
+ }
11139
+ /**
11140
+ * Everything the ribbon, toolbar, and canvas need, returned from
11141
+ * {@link createViewerState}. Reactive/derived fields are exposed as
11142
+ * getters (some paired with setters for the plain local UI flags) so reads
11143
+ * anywhere, not just inside an `$effect`, stay live.
11144
+ */
11145
+ interface ViewerStateBag {
11146
+ readonly loader: PresentationLoader;
11147
+ readonly viewer: ViewerState;
11148
+ readonly editor: EditorState;
11149
+ readonly controller: EditorController;
11150
+ readonly parityUi: ViewerParityUiState;
11151
+ readonly chromeUi: ChromeUiState;
11152
+ readonly findReplace: FindReplaceState;
11153
+ readonly collab: CollaborationController;
11154
+ readonly dialogs: CollaborationDialogsState;
11155
+ readonly autosaveCtl: AutosaveController;
11156
+ readonly presentation: PresentationController;
11157
+ readonly presenterSession: PresenterSession;
11158
+ readonly exportWiring: ExportWiring;
11159
+ readonly exportUi: ExportUiState;
11160
+ readonly t: Translator;
11161
+ /** Imperative undo/redo/save/download API, matching `PowerPointViewerApi`'s editing subset. */
11162
+ readonly editingApi: EditingApi;
11163
+ /** Imperative PNG/PDF/GIF/video/print API, matching `PowerPointViewerApi`'s export subset. */
11164
+ readonly exportingApi: ExportingApi;
11165
+ /** Effective scale (fit-to-viewport x user zoom), matching the main canvas. */
11166
+ readonly scale: number;
11167
+ /** User-facing zoom percent (rounded, never below 1). */
11168
+ readonly effectivePercent: number;
11169
+ readonly displaySlides: EditorState['renderedSlides'];
11170
+ readonly activeSlide: EditorState['renderedSlides'][number] | undefined;
11171
+ readonly chromeVisible: boolean;
11172
+ /** True when in-place editing is actually available (editable, not presenting, not read-only). */
11173
+ readonly editingActive: boolean;
11174
+ /** True once the ribbon (vs. the compact `ViewerToolbar`) should be shown. */
11175
+ readonly showRibbon: boolean;
11176
+ readonly viewerMode: ViewerMode;
11177
+ /** True while the autosave debounce/write cycle is armed. */
11178
+ readonly autosaveActive: boolean;
11179
+ /** Read-only: mutate via {@link setAutosaveEnabled}, which also fires `onautosavetoggle`. */
11180
+ readonly autosaveEnabled: boolean;
11181
+ setAutosaveEnabled(enabled: boolean): void;
11182
+ presenterMode: boolean;
11183
+ /** `Date.now()` timestamp of the last `enterPresenterView()` call; the presenter view's elapsed-time display. */
11184
+ readonly presenterStartedAt: number;
11185
+ stageContextMenu: {
11186
+ x: number;
11187
+ y: number;
11188
+ } | null;
11189
+ readonly activeMobileSheet: MobileSheetKey;
11190
+ setActiveMobileSheet(next: MobileSheetKey): void;
11191
+ readonly notesExpanded: boolean;
11192
+ versionHistoryOpen: boolean;
11193
+ readonly signatureWarningOpen: boolean;
11194
+ enterPresenterView(): void;
11195
+ closeSignatureWarning(): void;
11196
+ onNotesToggle(): void;
11197
+ onNotesCommit(notes: string, segments?: TextSegment[]): void;
11198
+ onFullscreenToggle(): void;
11199
+ onFullscreenChange(): void;
11200
+ onKeydown(event: KeyboardEvent): void;
11201
+ downloadPptx(fileName?: string): Promise<void>;
11202
+ downloadAs(format: PptxSaveFormat, fileName?: string): Promise<void>;
11203
+ /** Tear down every constructed controller (call from the host's `onDestroy`). */
11204
+ destroy(): void;
11205
+ }
11206
+
11207
+ /**
11208
+ * Builds every reactive controller the ribbon, toolbar, and slide canvas
11209
+ * need: the runes port of `PowerPointViewer.svelte`'s own construction block
11210
+ * (originally inlined at the top of its `<script>`), extracted so a host can
11211
+ * compose its own viewer shell out of `Ribbon` / `ViewerToolbar` / the state
11212
+ * classes without pulling in the whole `PowerPointViewer` component.
11213
+ *
11214
+ * MUST be called synchronously from a `.svelte` component's own script body
11215
+ * (top level, not inside a callback or after an `await`): it registers
11216
+ * `onMount` / `onDestroy` hooks and Svelte context (`setContext`) via
11217
+ * `provideTranslator` / `provideSmartArt3D` / `provideRenderContext` /
11218
+ * `provideZoomNavigation` (inside the editor-ui cluster) / `provideInspectorDeck`,
11219
+ * all of which require an active component-initialisation context. Svelte's
11220
+ * lifecycle context stays active for the whole synchronous execution of a
11221
+ * component's script, not just its top-level statements, so calling this
11222
+ * from a component's script works exactly like inlining the same code would.
11223
+ *
11224
+ * Construction is split across a few `create-viewer-state-*.svelte.ts`
11225
+ * helpers purely to stay under the repo's file-size budget; the ORDER those
11226
+ * helpers are invoked in below mirrors the original inline code (later
11227
+ * clusters close over earlier ones), with one deliberate reordering: the
11228
+ * collaboration cluster is now built right after `editor` (it doesn't need
11229
+ * the editing-chrome cluster), which lets `controller` close over the real
11230
+ * `collab.setCursor` instead of a forward reference.
11231
+ *
11232
+ * Call the returned `destroy()` from the host component's own `onDestroy`.
11233
+ */
11234
+ declare function createViewerState(options: CreateViewerStateOptions): ViewerStateBag;
11235
+
11236
+ export { PowerPointViewer, PresentationLoader, Ribbon, SlideCanvas, ViewerState, ViewerToolbar, clampSlideIndex, createSvelteAiBridge, createViewerState, exportAllSlidesToSvg, exportAllSlidesToSvgBlobs, exportSlideAsSvg, exportSlideToSvg, exportSlideToSvgBlob, fitScale, resolveNavigationKey, zoomInPercent, zoomOutPercent };
11237
+ export type { CanvasSize, CreateViewerStateOptions, ExportGifOptions, ExportPdfOptions, ExportVideoOptions, NavigationAction, PowerPointViewerApi, PowerPointViewerProps, PptxAiBridge, PptxAiConfig, PptxAiConnection, PptxAiContextStrategy, PptxAiToolName, PptxAiUIMessage, PptxAiWritePolicy, PrintOptions, RibbonProps, SlideCanvasProps, SvelteAiBridgeDeps, SvgExportAllOptions, SvgExportSingleSlideOptions, ViewerLoadDetail, ViewerStateBag, ViewerTheme, ViewerToolbarProps };