pptx-svelte-viewer 0.1.2 → 0.2.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.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,40 @@
1
1
  import { Component } from 'svelte';
2
2
 
3
+ export declare interface AutosaveRecord {
4
+ key: string;
5
+ data: Uint8Array;
6
+ timestamp: number;
7
+ size: number;
8
+ }
9
+
10
+ /**
11
+ * autosave.svelte.ts: debounced crash-recovery autosave for the Svelte viewer.
12
+ *
13
+ * A runes port that fuses the two shared semantics the other bindings use:
14
+ * - React's persistence target: each successful save writes the serialized
15
+ * `.pptx` bytes to the shared IndexedDB recovery store
16
+ * (`saveAutosaveSnapshot`, keyed by `filePath`), so a host can offer
17
+ * restore-on-load with `getAutosaveSnapshot` / `listAutosaveSnapshots`
18
+ * (both re-exported from this package). This binding does NOT auto-restore;
19
+ * matching React/Vue, recovery is a host concern.
20
+ * - Vue's debounce-on-edit trigger: an edit marks the document dirty and
21
+ * (re)arms a debounce timer instead of polling on a fixed interval.
22
+ *
23
+ * The controller registers its own edit-watching `$effect` in the constructor,
24
+ * so the SFC only has to construct it once during setup and read its reactive
25
+ * `status` / `isDirty` for the toolbar indicator.
26
+ */
27
+ /**
28
+ * Autosave status, surfaced for the toolbar status pill.
29
+ *
30
+ * - `idle` : nothing has been saved yet (or no edits since mount).
31
+ * - `disabled` : autosave is inactive (off, not editable, or no file path).
32
+ * - `saving` : a save is currently in flight.
33
+ * - `saved` : the most recent save succeeded.
34
+ * - `error` : the most recent save threw.
35
+ */
36
+ export declare type AutosaveStatus = 'idle' | 'disabled' | 'saving' | 'saved' | 'error';
37
+
3
38
  /**
4
39
  * Framework-agnostic public types shared by the viewer bindings.
5
40
  *
@@ -14,6 +49,69 @@ export declare interface CanvasSize {
14
49
  height: number;
15
50
  }
16
51
 
52
+ /**
53
+ * Real-time collaboration configuration.
54
+ *
55
+ * The same shape is accepted by the React, Vue, and Angular bindings.
56
+ */
57
+ export declare interface CollaborationConfig {
58
+ /** Unique identifier for the collaboration room (alphanumeric, hyphens, underscores). */
59
+ roomId: string;
60
+ /**
61
+ * WebSocket server URL for the Yjs provider (e.g. "wss://collab.example.com").
62
+ * Ignored (may be empty) when `transport` is `'webrtc'`.
63
+ */
64
+ serverUrl: string;
65
+ /** Transport to use. Defaults to `'websocket'`. */
66
+ transport?: CollaborationTransport;
67
+ /**
68
+ * WebRTC signaling server URLs (only used when `transport` is `'webrtc'`).
69
+ * Defaults to y-webrtc's built-in public signaling list. Same-browser tabs
70
+ * sync via BroadcastChannel regardless of signaling availability.
71
+ */
72
+ signaling?: string[];
73
+ /** Display name for the local user. */
74
+ userName: string;
75
+ /** Avatar URL for the local user (optional). */
76
+ userAvatar?: string;
77
+ /** Hex colour for the local user's cursor/presence indicator. */
78
+ userColor?: string;
79
+ /** Optional authentication token sent with the WebSocket handshake. */
80
+ authToken?: string;
81
+ /** Role in the session; defaults to `'collaborator'`. */
82
+ role?: CollaborationRole;
83
+ /**
84
+ * Elected-writer write-back callback (Area 3 of the C3 hardening plan).
85
+ *
86
+ * When the local user has `role: 'owner'`, the binding debounces changes and
87
+ * serializes the current Y.Doc state to a PPTX byte array, then calls this
88
+ * callback so the host can persist the snapshot. Only one writer (the owner)
89
+ * does this; other collaborators never trigger write-back, eliminating the
90
+ * last-save-wins problem.
91
+ */
92
+ onWriteBack?: (bytes: Uint8Array) => void;
93
+ /**
94
+ * Debounce delay (ms) between the last Y.Doc change and the write-back
95
+ * invocation. Defaults to 5000 ms. Set to 0 to write back on every change
96
+ * (not recommended for large documents).
97
+ */
98
+ writeBackDebounceMs?: number;
99
+ }
100
+
101
+ /** Collaboration role within a session. */
102
+ export declare type CollaborationRole = 'owner' | 'collaborator' | 'viewer';
103
+
104
+ /**
105
+ * Collaboration transport.
106
+ *
107
+ * - `'websocket'` (default): y-websocket against `serverUrl`.
108
+ * - `'webrtc'`: y-webrtc peer-to-peer; needs no document server. Peers meet
109
+ * through the `signaling` servers (WebRTC signaling only, no document data)
110
+ * and same-browser tabs additionally sync via BroadcastChannel even without
111
+ * any signaling server, which makes this mode usable from static hosting.
112
+ */
113
+ export declare type CollaborationTransport = 'websocket' | 'webrtc';
114
+
17
115
  /**
18
116
  * Build the complete set of CSS custom properties with all defaults.
19
117
  * Useful for generating a full fallback stylesheet.
@@ -32,8 +130,41 @@ export declare const defaultRadius = "0.5rem";
32
130
  */
33
131
  export declare const defaultThemeColors: ViewerThemeColors;
34
132
 
133
+ /**
134
+ * Delete an autosave snapshot by file path.
135
+ */
136
+ export declare function deleteAutosaveSnapshot(filePath: string): Promise<boolean>;
137
+
138
+ /**
139
+ * Animated-GIF export capture/encode pipeline. All the pure logic is shared:
140
+ * `planGifFrames` derives the per-slide frame delays (default duration +
141
+ * per-slide overrides), `clampGifDimensions` bounds the output size, and
142
+ * `encodeGif` (median-cut quantisation + LZW GIF89a) produces the bytes with
143
+ * each frame carrying its own plan delay. This module only owns the
144
+ * DOM-adjacent glue: rasterising each slide via the injected capture callback
145
+ * and normalising every frame onto a uniform-size canvas before pixel
146
+ * extraction. Blob download is left to the caller (`ExportController`).
147
+ */
148
+ /** Options for the animated-GIF export. */
149
+ export declare interface ExportGifOptions {
150
+ /** Duration each slide is shown, in milliseconds. Default 2000. */
151
+ slideDurationMs?: number;
152
+ /** Per-slide duration overrides in milliseconds (index maps to slide index). */
153
+ slideTimingsMs?: number[];
154
+ /**
155
+ * Longest allowed output side in pixels; frames are scaled down
156
+ * proportionally. Default 960 (GIF encoding cost grows with pixel count:
157
+ * every pixel is matched against a 256-colour palette per frame).
158
+ */
159
+ maxDimension?: number;
160
+ /** Capture-phase progress callback: `(currentSlide, totalSlides)`. */
161
+ onProgress?: ExportProgress;
162
+ /** Abort the export early; checked before each slide capture. */
163
+ signal?: AbortSignal;
164
+ }
165
+
35
166
  /** Options for the multi-slide PDF export (progress + cooperative cancel). */
36
- declare interface ExportPdfOptions {
167
+ export declare interface ExportPdfOptions {
37
168
  /** Capture-phase progress callback: `(currentSlide, totalSlides)`. */
38
169
  onProgress?: ExportProgress;
39
170
  /** Abort the export early; the loop checks this between slides. */
@@ -43,6 +174,61 @@ declare interface ExportPdfOptions {
43
174
  /** Per-slide progress callback: `(currentSlideIndex, totalSlides)`. */
44
175
  declare type ExportProgress = (current: number, total: number) => void;
45
176
 
177
+ /**
178
+ * Video (WebM) export driven by the shared `video-plan` maths: segment timing
179
+ * comes from `planVideoSegments` (default duration + per-slide overrides +
180
+ * fps -> frame count), the frame pacing from `fpsToFrameIntervalMs`, and the
181
+ * recorder MIME type from `pickSupportedMimeType(WEBM_MIME_CANDIDATES)`. This
182
+ * module owns the browser glue only: rasterise every slide first (capture
183
+ * phase), then replay each canvas onto a recording canvas whose
184
+ * `captureStream()` feeds a `MediaRecorder` (recording phase). Mirrors
185
+ * React's `exportAllSlidesAsVideo`, minus the live-stage slide flipping (the
186
+ * injected rasteriser renders off-screen instead).
187
+ */
188
+ /** Options for the WebM video export. */
189
+ export declare interface ExportVideoOptions {
190
+ /** Duration each slide is shown, in milliseconds. Default 3000. */
191
+ slideDurationMs?: number;
192
+ /** Per-slide duration overrides in milliseconds (index maps to slide index). */
193
+ slideTimingsMs?: number[];
194
+ /** Recording frame rate. Default 30. */
195
+ fps?: number;
196
+ /** Recorder bitrate. Default 5,000,000 (5 Mbps). */
197
+ videoBitsPerSecond?: number;
198
+ /** Capture-phase progress callback: `(currentSlide, totalSlides)`. */
199
+ onProgress?: ExportProgress;
200
+ /** Recording-phase progress callback: `(currentSlide, totalSlides)`. */
201
+ onRecordProgress?: ExportProgress;
202
+ /** Abort the export early; checked between slides and between frames. */
203
+ signal?: AbortSignal;
204
+ }
205
+
206
+ /**
207
+ * Retrieve a single autosave snapshot by file path.
208
+ * Returns undefined when no snapshot exists.
209
+ */
210
+ export declare function getAutosaveSnapshot(filePath: string): Promise<AutosaveRecord | undefined>;
211
+
212
+ /**
213
+ * Pure handout layout calculations, shared by every binding's print path.
214
+ *
215
+ * Handles distributing slides across pages, computing grid dimensions, and
216
+ * positioning cells within A4 page space. No DOM/framework dependency: callers
217
+ * render the resulting rectangles however their view layer prefers.
218
+ */
219
+ /** Supported slides-per-page values. */
220
+ declare type HandoutSlidesPerPage = 1 | 2 | 3 | 4 | 6 | 9;
221
+
222
+ /**
223
+ * List all autosave snapshots (without the heavy `data` blob).
224
+ * Useful for showing a recovery picker on app start.
225
+ */
226
+ export declare function listAutosaveSnapshots(): Promise<Array<{
227
+ key: string;
228
+ timestamp: number;
229
+ size: number;
230
+ }>>;
231
+
46
232
  /**
47
233
  * Explicitly-typed public export of the viewer component.
48
234
  *
@@ -87,6 +273,30 @@ export declare interface PowerPointViewerApi {
87
273
  * `jspdf` is dynamically imported on first use.
88
274
  */
89
275
  exportPdf(options?: ExportPdfOptions): Promise<void>;
276
+ /**
277
+ * Export every slide as an animated GIF download. Per-slide frame delays
278
+ * come from the shared frame plan: a default `slideDurationMs` (2000) with
279
+ * optional per-slide `slideTimingsMs` overrides. Supports `onProgress` and
280
+ * an `AbortSignal`, like {@link exportPdf}.
281
+ */
282
+ exportGif(options?: ExportGifOptions): Promise<void>;
283
+ /**
284
+ * Export every slide as a WebM video download (canvas capture stream +
285
+ * `MediaRecorder`; codec picked from the shared WebM candidates). Timing
286
+ * follows the shared video plan (`slideDurationMs` default 3000, per-slide
287
+ * `slideTimingsMs`, `fps` default 30). Supports capture/recording progress
288
+ * callbacks and an `AbortSignal`.
289
+ */
290
+ exportVideo(options?: ExportVideoOptions): Promise<void>;
291
+ /**
292
+ * Assemble the shared print document (slides / handouts / notes / outline,
293
+ * slide range + colour mode) and open the browser print dialog. The default
294
+ * print surface is a hidden same-origin iframe, so no popup window is
295
+ * involved; a custom `window.open`-based opener (injectable at the
296
+ * controller level) is subject to popup blockers, in which case the promise
297
+ * resolves `false`. Resolves `true` once the print surface opened.
298
+ */
299
+ print(options?: PrintOptions): Promise<boolean>;
90
300
  }
91
301
 
92
302
  /** Props for `<PowerPointViewer>`. */
@@ -151,8 +361,101 @@ export declare interface PowerPointViewerProps {
151
361
  * to track the dirty state or mirror edits into host state.
152
362
  */
153
363
  onchange?: () => void;
364
+ /**
365
+ * Enable debounced crash-recovery autosave. On each edit (when `editable`)
366
+ * the current slides are serialized to `.pptx` bytes and written to the
367
+ * shared IndexedDB recovery store (keyed by {@link filePath}), and
368
+ * `onautosave` is fired with the bytes. Requires `filePath`; without one the
369
+ * autosave indicator reads "disabled". This binding does not auto-restore on
370
+ * load; recovery is a host concern (see the re-exported `getAutosaveSnapshot`
371
+ * / `listAutosaveSnapshots` helpers). Default false.
372
+ */
373
+ autosave?: boolean;
374
+ /**
375
+ * IndexedDB record key for autosave (typically the open file's name/path).
376
+ * Autosave is inert until this is set.
377
+ */
378
+ filePath?: string;
379
+ /** Autosave debounce window in milliseconds. Default 2000. */
380
+ autosaveIntervalMs?: number;
381
+ /** Fired with the serialized `.pptx` bytes after each successful autosave. */
382
+ onautosave?: (bytes: Uint8Array) => void;
383
+ /**
384
+ * Real-time collaboration configuration. When provided, the viewer connects
385
+ * to the room (y-websocket or serverless y-webrtc), publishes local edits
386
+ * granularly, and applies remote peers' edits into the editable slides.
387
+ * Clearing it (undefined) tears the session down. A `viewer` role makes the
388
+ * local user read-only. Remote presence/cursors are not rendered by this
389
+ * binding (descoped); see `collab/collaboration.svelte.ts`.
390
+ */
391
+ collaboration?: CollaborationConfig;
392
+ /** Fired when a collaboration session starts (with the resolved config). */
393
+ onstartcollaboration?: (config: CollaborationConfig) => void;
394
+ /** Fired when a collaboration session stops. */
395
+ onstopcollaboration?: () => void;
154
396
  }
155
397
 
398
+ /** Colour mode for the printed output. */
399
+ declare type PrintColorMode = 'color' | 'grayscale' | 'blackAndWhite';
400
+
401
+ /**
402
+ * Print flow: assemble the shared print document (slides / notes / handouts /
403
+ * outline) and hand it to a print surface. All the pure logic is shared and
404
+ * DOMPurify-hardened: `validatePrintSettings` normalises the caller's partial
405
+ * settings, `computeSlideIndices` / `computeColorFilter` resolve the range and
406
+ * colour mode, the `build*Html` helpers produce the escaped body markup, and
407
+ * `buildPrintHtmlDocument` sanitises + assembles the final document. This
408
+ * module (the Svelte counterpart of Vue's `usePrint`) only rasterises the
409
+ * selected slides and opens the print surface.
410
+ *
411
+ * **Print surface / popup-blocker caveats:** the default opener renders the
412
+ * document into a hidden same-origin `<iframe srcdoc>` and calls
413
+ * `contentWindow.print()`, so no popup window is involved and popup blockers
414
+ * cannot interfere (`document.write` is avoided too). A host that prefers a
415
+ * visible print window can inject its own {@link OpenPrintWindow} via the
416
+ * controller deps; note that a `window.open`-based opener only succeeds inside
417
+ * a user gesture (a click handler) and returns `null` under popup blockers,
418
+ * in which case it should report `false` so the flow resolves `false` and the
419
+ * host can surface "allow popups for this site" guidance.
420
+ */
421
+ /** Options for the print flow: any subset of the shared print settings. */
422
+ export declare type PrintOptions = Partial<PrintSettings>;
423
+
424
+ /** Page orientation for the printed output. */
425
+ declare type PrintOrientation = 'portrait' | 'landscape';
426
+
427
+ /** Resolved print settings emitted on confirm. */
428
+ declare interface PrintSettings {
429
+ printWhat: PrintWhat;
430
+ orientation: PrintOrientation;
431
+ colorMode: PrintColorMode;
432
+ frameSlides: boolean;
433
+ slidesPerPage: HandoutSlidesPerPage;
434
+ slideRange: PrintSlideRange;
435
+ customRangeFrom: number;
436
+ customRangeTo: number;
437
+ }
438
+
439
+ /** Slide range mode. */
440
+ declare type PrintSlideRange = 'all' | 'current' | 'custom';
441
+
442
+ /**
443
+ * Pure print helpers shared by every binding's print path: settings validation,
444
+ * slide-range / colour-filter resolution, page-count estimation, HTML markup
445
+ * builders, escaping, and the full print-document assembler.
446
+ *
447
+ * No DOM side effects and no `window.print()`: everything is deterministic and
448
+ * the binding writes the returned HTML string into a print window. The handout
449
+ * grid geometry lives in `handout-layout`; this module reuses it.
450
+ *
451
+ * ng-packagr constraint honoured here (the Angular binding inlines this source
452
+ * and compiles it through ng-packagr): NO `String.prototype.replaceAll`
453
+ * (`escapeHtml` uses `.split(x).join(y)` instead).
454
+ */
455
+
456
+ /** What to print. */
457
+ declare type PrintWhat = 'slides' | 'handouts' | 'notes' | 'outline';
458
+
156
459
  /**
157
460
  * Register (or extend) the dictionary for a locale. Later registrations are
158
461
  * merged over earlier ones, so hosts can override individual keys.
package/dist/index.js CHANGED
@@ -1,16 +1,19 @@
1
- import { _ as r, d as a, f as e, g as i, h as o, l as m, m as t, p as l, t as n, u as h } from "./component-DxQFSCeR.js";
1
+ import { _ as a, b as e, d as o, f as r, g as t, h as i, l, m, p as n, t as h, u, v, y as p } from "./component-Bvs5zPMN.js";
2
2
  import { r as f } from "./translator-C44zS1dl.js";
3
3
  import "./i18n.js";
4
4
  export {
5
- n as PowerPointViewer,
6
- m as defaultCssVars,
7
- h as defaultRadius,
8
- a as defaultThemeColors,
5
+ h as PowerPointViewer,
6
+ l as defaultCssVars,
7
+ u as defaultRadius,
8
+ o as defaultThemeColors,
9
+ r as deleteAutosaveSnapshot,
10
+ n as getAutosaveSnapshot,
11
+ m as listAutosaveSnapshots,
9
12
  f as registerTranslations,
10
- e as themeToCssVars,
11
- l as vermilionDarkColors,
12
- t as vermilionDarkTheme,
13
- o as vermilionLightColors,
14
- i as vermilionLightTheme,
15
- r as vermilionRadius
13
+ i as themeToCssVars,
14
+ t as vermilionDarkColors,
15
+ a as vermilionDarkTheme,
16
+ v as vermilionLightColors,
17
+ p as vermilionLightTheme,
18
+ e as vermilionRadius
16
19
  };
@@ -271,6 +271,69 @@ declare interface ChartSeriesInput {
271
271
  /** Clamp a slide index into `[0, count - 1]` (0 when there are no slides). */
272
272
  export declare function clampSlideIndex(index: number, count: number): number;
273
273
 
274
+ /**
275
+ * Real-time collaboration configuration.
276
+ *
277
+ * The same shape is accepted by the React, Vue, and Angular bindings.
278
+ */
279
+ declare interface CollaborationConfig {
280
+ /** Unique identifier for the collaboration room (alphanumeric, hyphens, underscores). */
281
+ roomId: string;
282
+ /**
283
+ * WebSocket server URL for the Yjs provider (e.g. "wss://collab.example.com").
284
+ * Ignored (may be empty) when `transport` is `'webrtc'`.
285
+ */
286
+ serverUrl: string;
287
+ /** Transport to use. Defaults to `'websocket'`. */
288
+ transport?: CollaborationTransport;
289
+ /**
290
+ * WebRTC signaling server URLs (only used when `transport` is `'webrtc'`).
291
+ * Defaults to y-webrtc's built-in public signaling list. Same-browser tabs
292
+ * sync via BroadcastChannel regardless of signaling availability.
293
+ */
294
+ signaling?: string[];
295
+ /** Display name for the local user. */
296
+ userName: string;
297
+ /** Avatar URL for the local user (optional). */
298
+ userAvatar?: string;
299
+ /** Hex colour for the local user's cursor/presence indicator. */
300
+ userColor?: string;
301
+ /** Optional authentication token sent with the WebSocket handshake. */
302
+ authToken?: string;
303
+ /** Role in the session; defaults to `'collaborator'`. */
304
+ role?: CollaborationRole;
305
+ /**
306
+ * Elected-writer write-back callback (Area 3 of the C3 hardening plan).
307
+ *
308
+ * When the local user has `role: 'owner'`, the binding debounces changes and
309
+ * serializes the current Y.Doc state to a PPTX byte array, then calls this
310
+ * callback so the host can persist the snapshot. Only one writer (the owner)
311
+ * does this; other collaborators never trigger write-back, eliminating the
312
+ * last-save-wins problem.
313
+ */
314
+ onWriteBack?: (bytes: Uint8Array) => void;
315
+ /**
316
+ * Debounce delay (ms) between the last Y.Doc change and the write-back
317
+ * invocation. Defaults to 5000 ms. Set to 0 to write back on every change
318
+ * (not recommended for large documents).
319
+ */
320
+ writeBackDebounceMs?: number;
321
+ }
322
+
323
+ /** Collaboration role within a session. */
324
+ declare type CollaborationRole = 'owner' | 'collaborator' | 'viewer';
325
+
326
+ /**
327
+ * Collaboration transport.
328
+ *
329
+ * - `'websocket'` (default): y-websocket against `serverUrl`.
330
+ * - `'webrtc'`: y-webrtc peer-to-peer; needs no document server. Peers meet
331
+ * through the `signaling` servers (WebRTC signaling only, no document data)
332
+ * and same-browser tabs additionally sync via BroadcastChannel even without
333
+ * any signaling server, which makes this mode usable from static hosting.
334
+ */
335
+ declare type CollaborationTransport = 'websocket' | 'webrtc';
336
+
274
337
  /**
275
338
  * Connection site (`a:cxn`) on a custom geometry.
276
339
  *
@@ -554,8 +617,36 @@ declare interface EncryptionOptions {
554
617
  spinCount?: number;
555
618
  }
556
619
 
620
+ /**
621
+ * Animated-GIF export capture/encode pipeline. All the pure logic is shared:
622
+ * `planGifFrames` derives the per-slide frame delays (default duration +
623
+ * per-slide overrides), `clampGifDimensions` bounds the output size, and
624
+ * `encodeGif` (median-cut quantisation + LZW GIF89a) produces the bytes with
625
+ * each frame carrying its own plan delay. This module only owns the
626
+ * DOM-adjacent glue: rasterising each slide via the injected capture callback
627
+ * and normalising every frame onto a uniform-size canvas before pixel
628
+ * extraction. Blob download is left to the caller (`ExportController`).
629
+ */
630
+ /** Options for the animated-GIF export. */
631
+ export declare interface ExportGifOptions {
632
+ /** Duration each slide is shown, in milliseconds. Default 2000. */
633
+ slideDurationMs?: number;
634
+ /** Per-slide duration overrides in milliseconds (index maps to slide index). */
635
+ slideTimingsMs?: number[];
636
+ /**
637
+ * Longest allowed output side in pixels; frames are scaled down
638
+ * proportionally. Default 960 (GIF encoding cost grows with pixel count:
639
+ * every pixel is matched against a 256-colour palette per frame).
640
+ */
641
+ maxDimension?: number;
642
+ /** Capture-phase progress callback: `(currentSlide, totalSlides)`. */
643
+ onProgress?: ExportProgress;
644
+ /** Abort the export early; checked before each slide capture. */
645
+ signal?: AbortSignal;
646
+ }
647
+
557
648
  /** Options for the multi-slide PDF export (progress + cooperative cancel). */
558
- declare interface ExportPdfOptions {
649
+ export declare interface ExportPdfOptions {
559
650
  /** Capture-phase progress callback: `(currentSlide, totalSlides)`. */
560
651
  onProgress?: ExportProgress;
561
652
  /** Abort the export early; the loop checks this between slides. */
@@ -565,6 +656,35 @@ declare interface ExportPdfOptions {
565
656
  /** Per-slide progress callback: `(currentSlideIndex, totalSlides)`. */
566
657
  declare type ExportProgress = (current: number, total: number) => void;
567
658
 
659
+ /**
660
+ * Video (WebM) export driven by the shared `video-plan` maths: segment timing
661
+ * comes from `planVideoSegments` (default duration + per-slide overrides +
662
+ * fps -> frame count), the frame pacing from `fpsToFrameIntervalMs`, and the
663
+ * recorder MIME type from `pickSupportedMimeType(WEBM_MIME_CANDIDATES)`. This
664
+ * module owns the browser glue only: rasterise every slide first (capture
665
+ * phase), then replay each canvas onto a recording canvas whose
666
+ * `captureStream()` feeds a `MediaRecorder` (recording phase). Mirrors
667
+ * React's `exportAllSlidesAsVideo`, minus the live-stage slide flipping (the
668
+ * injected rasteriser renders off-screen instead).
669
+ */
670
+ /** Options for the WebM video export. */
671
+ export declare interface ExportVideoOptions {
672
+ /** Duration each slide is shown, in milliseconds. Default 3000. */
673
+ slideDurationMs?: number;
674
+ /** Per-slide duration overrides in milliseconds (index maps to slide index). */
675
+ slideTimingsMs?: number[];
676
+ /** Recording frame rate. Default 30. */
677
+ fps?: number;
678
+ /** Recorder bitrate. Default 5,000,000 (5 Mbps). */
679
+ videoBitsPerSecond?: number;
680
+ /** Capture-phase progress callback: `(currentSlide, totalSlides)`. */
681
+ onProgress?: ExportProgress;
682
+ /** Recording-phase progress callback: `(currentSlide, totalSlides)`. */
683
+ onRecordProgress?: ExportProgress;
684
+ /** Abort the export early; checked between slides and between frames. */
685
+ signal?: AbortSignal;
686
+ }
687
+
568
688
  declare type FillInput = {
569
689
  type: 'solid';
570
690
  color: string;
@@ -660,6 +780,16 @@ declare interface GroupPptxElement extends PptxElementBase {
660
780
  groupFill?: ShapeStyle;
661
781
  }
662
782
 
783
+ /**
784
+ * Pure handout layout calculations, shared by every binding's print path.
785
+ *
786
+ * Handles distributing slides across pages, computing grid dimensions, and
787
+ * positioning cells within A4 page space. No DOM/framework dependency: callers
788
+ * render the resulting rectangles however their view layer prefers.
789
+ */
790
+ /** Supported slides-per-page values. */
791
+ declare type HandoutSlidesPerPage = 1 | 2 | 3 | 4 | 6 | 9;
792
+
663
793
  declare interface ImageOptions extends Partial<ElementPosition> {
664
794
  altText?: string;
665
795
  cropLeft?: number;
@@ -1303,6 +1433,30 @@ export declare interface PowerPointViewerApi {
1303
1433
  * `jspdf` is dynamically imported on first use.
1304
1434
  */
1305
1435
  exportPdf(options?: ExportPdfOptions): Promise<void>;
1436
+ /**
1437
+ * Export every slide as an animated GIF download. Per-slide frame delays
1438
+ * come from the shared frame plan: a default `slideDurationMs` (2000) with
1439
+ * optional per-slide `slideTimingsMs` overrides. Supports `onProgress` and
1440
+ * an `AbortSignal`, like {@link exportPdf}.
1441
+ */
1442
+ exportGif(options?: ExportGifOptions): Promise<void>;
1443
+ /**
1444
+ * Export every slide as a WebM video download (canvas capture stream +
1445
+ * `MediaRecorder`; codec picked from the shared WebM candidates). Timing
1446
+ * follows the shared video plan (`slideDurationMs` default 3000, per-slide
1447
+ * `slideTimingsMs`, `fps` default 30). Supports capture/recording progress
1448
+ * callbacks and an `AbortSignal`.
1449
+ */
1450
+ exportVideo(options?: ExportVideoOptions): Promise<void>;
1451
+ /**
1452
+ * Assemble the shared print document (slides / handouts / notes / outline,
1453
+ * slide range + colour mode) and open the browser print dialog. The default
1454
+ * print surface is a hidden same-origin iframe, so no popup window is
1455
+ * involved; a custom `window.open`-based opener (injectable at the
1456
+ * controller level) is subject to popup blockers, in which case the promise
1457
+ * resolves `false`. Resolves `true` once the print surface opened.
1458
+ */
1459
+ print(options?: PrintOptions): Promise<boolean>;
1306
1460
  }
1307
1461
 
1308
1462
  /** Props for `<PowerPointViewer>`. */
@@ -1367,6 +1521,38 @@ export declare interface PowerPointViewerProps {
1367
1521
  * to track the dirty state or mirror edits into host state.
1368
1522
  */
1369
1523
  onchange?: () => void;
1524
+ /**
1525
+ * Enable debounced crash-recovery autosave. On each edit (when `editable`)
1526
+ * the current slides are serialized to `.pptx` bytes and written to the
1527
+ * shared IndexedDB recovery store (keyed by {@link filePath}), and
1528
+ * `onautosave` is fired with the bytes. Requires `filePath`; without one the
1529
+ * autosave indicator reads "disabled". This binding does not auto-restore on
1530
+ * load; recovery is a host concern (see the re-exported `getAutosaveSnapshot`
1531
+ * / `listAutosaveSnapshots` helpers). Default false.
1532
+ */
1533
+ autosave?: boolean;
1534
+ /**
1535
+ * IndexedDB record key for autosave (typically the open file's name/path).
1536
+ * Autosave is inert until this is set.
1537
+ */
1538
+ filePath?: string;
1539
+ /** Autosave debounce window in milliseconds. Default 2000. */
1540
+ autosaveIntervalMs?: number;
1541
+ /** Fired with the serialized `.pptx` bytes after each successful autosave. */
1542
+ onautosave?: (bytes: Uint8Array) => void;
1543
+ /**
1544
+ * Real-time collaboration configuration. When provided, the viewer connects
1545
+ * to the room (y-websocket or serverless y-webrtc), publishes local edits
1546
+ * granularly, and applies remote peers' edits into the editable slides.
1547
+ * Clearing it (undefined) tears the session down. A `viewer` role makes the
1548
+ * local user read-only. Remote presence/cursors are not rendered by this
1549
+ * binding (descoped); see `collab/collaboration.svelte.ts`.
1550
+ */
1551
+ collaboration?: CollaborationConfig;
1552
+ /** Fired when a collaboration session starts (with the resolved config). */
1553
+ onstartcollaboration?: (config: CollaborationConfig) => void;
1554
+ /** Fired when a collaboration session stops. */
1555
+ onstopcollaboration?: () => void;
1370
1556
  }
1371
1557
 
1372
1558
  /**
@@ -5791,6 +5977,67 @@ declare interface PresentationThemeInput {
5791
5977
  };
5792
5978
  }
5793
5979
 
5980
+ /** Colour mode for the printed output. */
5981
+ declare type PrintColorMode = 'color' | 'grayscale' | 'blackAndWhite';
5982
+
5983
+ /**
5984
+ * Print flow: assemble the shared print document (slides / notes / handouts /
5985
+ * outline) and hand it to a print surface. All the pure logic is shared and
5986
+ * DOMPurify-hardened: `validatePrintSettings` normalises the caller's partial
5987
+ * settings, `computeSlideIndices` / `computeColorFilter` resolve the range and
5988
+ * colour mode, the `build*Html` helpers produce the escaped body markup, and
5989
+ * `buildPrintHtmlDocument` sanitises + assembles the final document. This
5990
+ * module (the Svelte counterpart of Vue's `usePrint`) only rasterises the
5991
+ * selected slides and opens the print surface.
5992
+ *
5993
+ * **Print surface / popup-blocker caveats:** the default opener renders the
5994
+ * document into a hidden same-origin `<iframe srcdoc>` and calls
5995
+ * `contentWindow.print()`, so no popup window is involved and popup blockers
5996
+ * cannot interfere (`document.write` is avoided too). A host that prefers a
5997
+ * visible print window can inject its own {@link OpenPrintWindow} via the
5998
+ * controller deps; note that a `window.open`-based opener only succeeds inside
5999
+ * a user gesture (a click handler) and returns `null` under popup blockers,
6000
+ * in which case it should report `false` so the flow resolves `false` and the
6001
+ * host can surface "allow popups for this site" guidance.
6002
+ */
6003
+ /** Options for the print flow: any subset of the shared print settings. */
6004
+ export declare type PrintOptions = Partial<PrintSettings>;
6005
+
6006
+ /** Page orientation for the printed output. */
6007
+ declare type PrintOrientation = 'portrait' | 'landscape';
6008
+
6009
+ /** Resolved print settings emitted on confirm. */
6010
+ declare interface PrintSettings {
6011
+ printWhat: PrintWhat;
6012
+ orientation: PrintOrientation;
6013
+ colorMode: PrintColorMode;
6014
+ frameSlides: boolean;
6015
+ slidesPerPage: HandoutSlidesPerPage;
6016
+ slideRange: PrintSlideRange;
6017
+ customRangeFrom: number;
6018
+ customRangeTo: number;
6019
+ }
6020
+
6021
+ /** Slide range mode. */
6022
+ declare type PrintSlideRange = 'all' | 'current' | 'custom';
6023
+
6024
+ /**
6025
+ * Pure print helpers shared by every binding's print path: settings validation,
6026
+ * slide-range / colour-filter resolution, page-count estimation, HTML markup
6027
+ * builders, escaping, and the full print-document assembler.
6028
+ *
6029
+ * No DOM side effects and no `window.print()`: everything is deterministic and
6030
+ * the binding writes the returned HTML string into a print window. The handout
6031
+ * grid geometry lives in `handout-layout`; this module reuses it.
6032
+ *
6033
+ * ng-packagr constraint honoured here (the Angular binding inlines this source
6034
+ * and compiles it through ng-packagr): NO `String.prototype.replaceAll`
6035
+ * (`escapeHtml` uses `.split(x).join(y)` instead).
6036
+ */
6037
+
6038
+ /** What to print. */
6039
+ declare type PrintWhat = 'slides' | 'handouts' | 'notes' | 'outline';
6040
+
5794
6041
  /**
5795
6042
  * Map a `KeyboardEvent.key` to a navigation action, mirroring the slideshow
5796
6043
  * conventions used by the other bindings (arrows, paging keys, space, Home/End).
@@ -1,4 +1,4 @@
1
- import { a, c as o, i as t, n as r, o as s, r as i, s as n, t as c } from "../component-DxQFSCeR.js";
1
+ import { a, c as o, i as t, n as r, o as s, r as i, s as n, t as c } from "../component-Bvs5zPMN.js";
2
2
  export {
3
3
  c as PowerPointViewer,
4
4
  o as PresentationLoader,