pptx-angular-viewer 1.1.16 → 1.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,10 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { Signal, OnInit, OnDestroy, InjectionToken, Provider } from '@angular/core';
3
3
  import * as pptx_viewer_core from 'pptx-viewer-core';
4
- import { PptxSlide, AccessibilityCheckOptions, AccessibilityIssue, PptxElement, PptxTheme, PptxSlideMaster, PptxEmbeddedFont, PptxCoreProperties, PptxComment, TextSegment, TextStyle, PptxTableCell, Model3DPptxElement, ZoomPptxElement, XmlObject, ParsedSignature, SignatureStatus, AccessibilityIssueSeverity, AccessibilityIssueType, PptxElementAnimation, PptxTransitionType, PptxSlideTransition, ShapeStyle } from 'pptx-viewer-core';
4
+ import { PptxSlide, AccessibilityCheckOptions, AccessibilityIssue, PptxElement, PptxTheme, PptxSlideMaster, PptxEmbeddedFont, PptxCoreProperties, ParsedSignature, PptxComment, TextSegment, TextStyle, PptxTableCell, Model3DPptxElement, ZoomPptxElement, PptxSlideTransition, TablePptxElement, ChartPptxElement, XmlObject, SignatureStatus, AccessibilityIssueSeverity, AccessibilityIssueType, PptxElementAnimation, PptxTransitionType, ShapeStyle } from 'pptx-viewer-core';
5
+ import * as pptx_angular_viewer from 'pptx-angular-viewer';
5
6
  import { Options } from 'html2canvas-pro';
6
7
  import { SafeHtml } from '@angular/platform-browser';
7
- import * as pptx_angular_viewer from 'pptx-angular-viewer';
8
8
 
9
9
  /**
10
10
  * Theme configuration types for the PowerPoint viewer.
@@ -192,6 +192,55 @@ declare class AccessibilityService {
192
192
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<AccessibilityService>;
193
193
  }
194
194
 
195
+ /**
196
+ * broadcast-helpers.ts — Pure (no Angular) helpers for the Broadcast dialog.
197
+ *
198
+ * A broadcast is a one-way collaboration session: the presenter drives slide
199
+ * navigation and viewers follow along via a shareable link. These helpers
200
+ * cover the testable, framework-agnostic parts of the Vue `BroadcastDialog.vue`
201
+ * and React `BroadcastDialog.tsx`: room-id generation, form validation, and
202
+ * the viewer-link builder.
203
+ *
204
+ * No `any`; all regexes use the `/u` flag; no `String.prototype.replaceAll`,
205
+ * no regex named-capture-groups (ng-packagr lib-target constraints).
206
+ */
207
+ /** Default y-websocket server URL used when no default is supplied. */
208
+ declare const DEFAULT_BROADCAST_SERVER_URL = "ws://localhost:1234";
209
+ /** Optional seed values for the broadcast start form. */
210
+ interface BroadcastDefaults {
211
+ roomId?: string;
212
+ serverUrl?: string;
213
+ }
214
+ /** The configuration emitted when a broadcast starts. */
215
+ interface BroadcastConfig {
216
+ roomId: string;
217
+ serverUrl: string;
218
+ }
219
+ /** Generate a fresh, broadcast-scoped room id (`broadcast-<suffix>`). */
220
+ declare function generateBroadcastRoomId(): string;
221
+ /**
222
+ * Seed the start form from the (optional) defaults, generating a fresh room id
223
+ * when none is supplied and falling back to the default server URL.
224
+ */
225
+ declare function seedBroadcastFields(defaults?: BroadcastDefaults): BroadcastConfig;
226
+ /** Whether both required fields are non-blank (after trimming). */
227
+ declare function canStartBroadcast(fields: BroadcastConfig): boolean;
228
+ /**
229
+ * Assemble a {@link BroadcastConfig} from the (trimmed) form fields, or `null`
230
+ * when incomplete.
231
+ */
232
+ declare function buildBroadcastConfig(fields: BroadcastConfig): BroadcastConfig | null;
233
+ /**
234
+ * Build the shareable viewer follow-link for a broadcast. Returns just the
235
+ * room id when no `origin`/`pathname` are available (non-browser environments).
236
+ */
237
+ declare function buildBroadcastViewerUrl(roomId: string, serverUrl: string, location?: {
238
+ origin: string;
239
+ pathname: string;
240
+ }): string;
241
+ /** Whether the runtime exposes a usable async clipboard write API. */
242
+ declare function canUseClipboard(nav: Navigator | undefined): boolean;
243
+
195
244
  /**
196
245
  * collaboration-helpers.ts — Pure, framework-agnostic logic for the real-time
197
246
  * collaboration subsystem (Yjs-backed presence + remote cursors).
@@ -383,6 +432,12 @@ declare class EditorStateService {
383
432
  setSlides(slides: readonly PptxSlide[]): void;
384
433
  /** Current editable slides as a fresh (cloned) array. */
385
434
  snapshot(): readonly PptxSlide[];
435
+ /**
436
+ * Replace the whole deck with pre-computed slides (e.g. a find/replace
437
+ * result) as a single undoable history entry. Unlike {@link setSlides} this
438
+ * preserves history and selection.
439
+ */
440
+ applyReplacement(newSlides: readonly PptxSlide[], label?: string): void;
386
441
  select(ids: readonly string[]): void;
387
442
  toggleSelect(id: string, additive: boolean): void;
388
443
  clearSelection(): void;
@@ -457,6 +512,151 @@ declare class EditorStateService {
457
512
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<EditorStateService>;
458
513
  }
459
514
 
515
+ /** Emitted when the user changes the find query or the case-sensitive toggle. */
516
+ interface FindEvent {
517
+ query: string;
518
+ matchCase: boolean;
519
+ }
520
+ /** Emitted when the user confirms a replacement action. */
521
+ interface ReplaceEvent {
522
+ query: string;
523
+ replacement: string;
524
+ matchCase: boolean;
525
+ }
526
+ declare class FindReplaceBarComponent {
527
+ /**
528
+ * Total number of matches found across all slides for the current query.
529
+ * Kept at 0 when no search has been performed yet.
530
+ */
531
+ readonly matchCount: _angular_core.InputSignal<number>;
532
+ /**
533
+ * Zero-based index of the currently highlighted match.
534
+ * Used to derive the 1-based display counter.
535
+ */
536
+ readonly matchIndex: _angular_core.InputSignal<number>;
537
+ /**
538
+ * Emitted whenever the find query or the case-sensitive toggle changes.
539
+ * The parent should run `findInSlides` and update `matchCount`/`matchIndex`.
540
+ */
541
+ readonly find: _angular_core.OutputEmitterRef<FindEvent>;
542
+ /**
543
+ * Emitted when the user clicks ↑ / ↓ or presses Enter in the find input.
544
+ * Payload is `1` (next) or `-1` (previous).
545
+ * The parent advances `matchIndex` and navigates to the matching slide.
546
+ */
547
+ readonly navigate: _angular_core.OutputEmitterRef<1 | -1>;
548
+ /**
549
+ * Emitted when the user clicks "Replace" (single match).
550
+ * The parent calls `replaceMatch(...)` on `EditorStateService`.
551
+ */
552
+ readonly replaceOne: _angular_core.OutputEmitterRef<ReplaceEvent>;
553
+ /**
554
+ * Emitted when the user clicks "Replace All".
555
+ * The parent calls `replaceInSlides(...)` and commits the result to history.
556
+ */
557
+ readonly replaceAll: _angular_core.OutputEmitterRef<ReplaceEvent>;
558
+ /** Emitted when the user closes the bar (Escape or ✕ button). */
559
+ readonly close: _angular_core.OutputEmitterRef<void>;
560
+ private readonly findInputRef;
561
+ /** Current text in the find input. */
562
+ readonly query: _angular_core.WritableSignal<string>;
563
+ /** Current text in the replacement input. */
564
+ readonly replacement: _angular_core.WritableSignal<string>;
565
+ /** Whether the search should be case-sensitive. */
566
+ readonly matchCase: _angular_core.WritableSignal<boolean>;
567
+ /** 1-based display index for the counter (e.g. "2 / 5"). Clamps to bounds. */
568
+ readonly displayIndex: _angular_core.Signal<number>;
569
+ /** Escape anywhere on the document closes the bar. */
570
+ onDocumentKeydown(event: KeyboardEvent): void;
571
+ onQueryInput(event: Event): void;
572
+ onReplacementInput(event: Event): void;
573
+ toggleCase(): void;
574
+ emitReplaceOne(): void;
575
+ emitReplaceAll(): void;
576
+ /** Focus the find input (called by the parent after toggling the bar open). */
577
+ focusFindInput(): void;
578
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<FindReplaceBarComponent, never>;
579
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<FindReplaceBarComponent, "pptx-find-replace-bar", never, { "matchCount": { "alias": "matchCount"; "required": false; "isSignal": true; }; "matchIndex": { "alias": "matchIndex"; "required": false; "isSignal": true; }; }, { "find": "find"; "navigate": "navigate"; "replaceOne": "replaceOne"; "replaceAll": "replaceAll"; "close": "close"; }, never, never, true, never>;
580
+ }
581
+
582
+ /**
583
+ * find-replace-helpers.ts — Pure find & replace helpers for PPTX slides.
584
+ *
585
+ * Ported from:
586
+ * packages/react/src/viewer/hooks/useFindReplace.ts (findInSlides, applyFindReplacements)
587
+ *
588
+ * No Angular imports; safe to use in web workers or server-side code.
589
+ * All functions are immutable — they never mutate their input arrays.
590
+ *
591
+ * @module find-replace-helpers
592
+ */
593
+
594
+ /**
595
+ * Identifies a single match of the find query at segment-level precision.
596
+ * Mirrors the React `FindResult` shape.
597
+ */
598
+ interface FindResult {
599
+ /** Zero-based index of the slide in the slides array. */
600
+ slideIndex: number;
601
+ /** Id of the element that contains the match. */
602
+ elementId: string;
603
+ /** Zero-based index of the text segment within the element's `textSegments`. */
604
+ segmentIndex: number;
605
+ /** Character offset of the match start within the segment text. */
606
+ startOffset: number;
607
+ /** Number of characters matched (equals `query.length`). */
608
+ length: number;
609
+ }
610
+ /** Options passed to search and replace helpers. */
611
+ interface FindOptions {
612
+ /** When `true`, the search is case-sensitive. Defaults to `false`. */
613
+ matchCase?: boolean;
614
+ }
615
+ /** Result returned by {@link replaceInSlides} and {@link replaceMatch}. */
616
+ interface ReplaceResult {
617
+ /** Updated slides (immutable copy; unchanged slides share the original reference). */
618
+ slides: readonly PptxSlide[];
619
+ /** Number of text replacements actually applied. */
620
+ replacements: number;
621
+ }
622
+ /**
623
+ * Search all slides for occurrences of `query` at segment-level precision.
624
+ *
625
+ * - Only elements that pass `hasTextProperties` (text / shape / connector) are
626
+ * searched; tables, smartArt, and groups are skipped (they have no
627
+ * `textSegments`).
628
+ * - Overlapping matches are counted (search advances by 1 character after each
629
+ * hit, not by `query.length`).
630
+ * - Returns an empty array when `query` is empty.
631
+ */
632
+ declare function findInSlides(slides: readonly PptxSlide[], query: string, opts?: FindOptions): FindResult[];
633
+ /**
634
+ * Apply a set of find-replace substitutions to slides immutably.
635
+ *
636
+ * Replacements inside the same segment are applied in **descending offset**
637
+ * order so that earlier matches are not shifted by later substitutions.
638
+ *
639
+ * Returns the original `slides` reference (no allocation) when `toReplace` is
640
+ * empty.
641
+ */
642
+ declare function applyFindReplacements(slides: readonly PptxSlide[], toReplace: readonly FindResult[], replacement: string): ReplaceResult;
643
+ /**
644
+ * Replace a single match (identified by its position in `allResults`) and
645
+ * return the updated slides together with the count of replacements applied
646
+ * (always 0 or 1).
647
+ *
648
+ * This is a convenience wrapper around {@link applyFindReplacements} for the
649
+ * "Replace current" action.
650
+ */
651
+ declare function replaceMatch(slides: readonly PptxSlide[], allResults: readonly FindResult[], matchIndex: number, replacement: string): ReplaceResult;
652
+ /**
653
+ * Replace **all** current matches and return the updated slides.
654
+ *
655
+ * This is a convenience wrapper around {@link applyFindReplacements} for the
656
+ * "Replace All" action.
657
+ */
658
+ declare function replaceInSlides(slides: readonly PptxSlide[], query: string, replacement: string, opts?: FindOptions): ReplaceResult;
659
+
460
660
  /**
461
661
  * `LoadContentService` — Angular port of the React `useLoadContent` hook and
462
662
  * the Vue `useLoadContent` composable.
@@ -491,6 +691,8 @@ declare class LoadContentService {
491
691
  /** Core document properties from `docProps/core.xml`. */
492
692
  readonly coreProperties: _angular_core.WritableSignal<PptxCoreProperties | undefined>;
493
693
  /** Whether the presentation contains digital signatures. */
694
+ /** Parsed digital signatures (empty when unsigned or parsing fails). */
695
+ readonly signatures: _angular_core.WritableSignal<ParsedSignature[]>;
494
696
  readonly hasDigitalSignatures: _angular_core.WritableSignal<boolean>;
495
697
  /** Number of digital signatures found. */
496
698
  readonly digitalSignatureCount: _angular_core.WritableSignal<number>;
@@ -736,18 +938,31 @@ declare class PowerPointViewerComponent {
736
938
  protected readonly zoomPercent: _angular_core.Signal<number>;
737
939
  /** Fullscreen presentation-mode overlay visibility. */
738
940
  protected readonly presenting: _angular_core.WritableSignal<boolean>;
941
+ /** Presenter-view (speaker) overlay visibility. */
942
+ protected readonly presentingPresenter: _angular_core.WritableSignal<boolean>;
943
+ /** Epoch ms when presenter view started (drives the elapsed timer). */
944
+ protected readonly presenterStartTime: _angular_core.WritableSignal<number | null>;
739
945
  /** Slide-sorter grid overlay visibility. */
740
946
  protected readonly showSorter: _angular_core.WritableSignal<boolean>;
741
947
  /** Speaker-notes strip visibility. */
742
948
  protected readonly showNotes: _angular_core.WritableSignal<boolean>;
743
949
  /** Find-in-slides bar visibility. */
744
950
  protected readonly showFind: _angular_core.WritableSignal<boolean>;
951
+ /** Find-and-replace bar state (edit mode only). */
952
+ protected readonly showFindReplace: _angular_core.WritableSignal<boolean>;
953
+ protected readonly findResults: _angular_core.WritableSignal<readonly FindResult[]>;
954
+ protected readonly findActiveIndex: _angular_core.WritableSignal<number>;
955
+ private findMatchCase;
745
956
  /** Active right-docked tool panel (comments / accessibility), or null. */
746
- protected readonly activePanel: _angular_core.WritableSignal<"comments" | "accessibility" | null>;
957
+ protected readonly activePanel: _angular_core.WritableSignal<"comments" | "accessibility" | "signatures" | null>;
747
958
  /** Document-properties (Info) dialog visibility. */
748
959
  protected readonly showProperties: _angular_core.WritableSignal<boolean>;
749
960
  /** Hyperlink-edit dialog visibility. */
750
961
  protected readonly showHyperlink: _angular_core.WritableSignal<boolean>;
962
+ /** Share (collaboration) dialog visibility. */
963
+ protected readonly showShare: _angular_core.WritableSignal<boolean>;
964
+ /** Broadcast dialog visibility. */
965
+ protected readonly showBroadcast: _angular_core.WritableSignal<boolean>;
751
966
  /** Local overrides applied to document properties via the Info dialog. */
752
967
  private readonly coreOverride;
753
968
  /** Comments on the active slide. */
@@ -781,6 +996,20 @@ declare class PowerPointViewerComponent {
781
996
  goTo(index: number): void;
782
997
  goPrev(): void;
783
998
  goNext(): void;
999
+ /** Open the find/replace bar (mutually exclusive with the find-only bar). */
1000
+ protected openFindReplace(): void;
1001
+ /** Re-run the search over the editable deck and refresh the match list. */
1002
+ private refreshFindResults;
1003
+ protected onFindReplaceFind(evt: FindEvent): void;
1004
+ protected onFindReplaceNavigate(dir: 1 | -1): void;
1005
+ protected onFindReplaceReplaceOne(evt: ReplaceEvent): void;
1006
+ protected onFindReplaceReplaceAll(evt: ReplaceEvent): void;
1007
+ /** Start a real-time collaboration session from the share dialog config. */
1008
+ protected onShareStart(config: CollaborationConfig): void;
1009
+ protected onShareStop(): void;
1010
+ /** Start broadcasting (presenter as session owner) from the broadcast config. */
1011
+ protected onBroadcastStart(config: BroadcastConfig): void;
1012
+ protected onBroadcastStop(): void;
784
1013
  /** Horizontal-swipe tracking start coordinates (touch begins on the canvas). */
785
1014
  private swipeStartX;
786
1015
  private swipeStartY;
@@ -804,10 +1033,14 @@ declare class PowerPointViewerComponent {
804
1033
  zoomReset(): void;
805
1034
  /** Open the fullscreen presentation overlay from the current slide. */
806
1035
  present(): void;
1036
+ /** Open the presenter (speaker) view — current+next slide, notes, timer. */
1037
+ presentPresenter(): void;
1038
+ /** Close the presenter view (and any audience overlay it opened). */
1039
+ exitPresenter(): void;
807
1040
  /** Toggle the speaker-notes strip. */
808
1041
  toggleNotes(): void;
809
1042
  /** Toggle a right-docked tool panel (clicking the active one closes it). */
810
- togglePanel(panel: 'comments' | 'accessibility'): void;
1043
+ togglePanel(panel: 'comments' | 'accessibility' | 'signatures'): void;
811
1044
  /** Append a comment to the active slide (one history entry). */
812
1045
  onCommentAdd(text: string): void;
813
1046
  /** Remove a comment from the active slide. */
@@ -866,6 +1099,12 @@ declare class PowerPointViewerComponent {
866
1099
  * slide is restored.
867
1100
  */
868
1101
  exportPdf(): Promise<void>;
1102
+ /** Render every slide to a canvas (each made the live stage in turn). */
1103
+ private renderAllSlideCanvases;
1104
+ /** Export every slide as an animated GIF (2s per slide). */
1105
+ exportGif(): Promise<void>;
1106
+ /** Export every slide as a WebM video (3s per slide) via MediaRecorder. */
1107
+ exportVideo(): Promise<void>;
869
1108
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<PowerPointViewerComponent, never>;
870
1109
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<PowerPointViewerComponent, "pptx-viewer", never, { "content": { "alias": "content"; "required": false; "isSignal": true; }; "canEdit": { "alias": "canEdit"; "required": false; "isSignal": true; }; "class": { "alias": "class"; "required": false; "isSignal": true; }; "theme": { "alias": "theme"; "required": false; "isSignal": true; }; "collaboration": { "alias": "collaboration"; "required": false; "isSignal": true; }; }, { "activeSlideChange": "activeSlideChange"; "dirtyChange": "dirtyChange"; "contentChange": "contentChange"; "propertiesChange": "propertiesChange"; }, never, never, true, never>;
871
1110
  }
@@ -896,6 +1135,184 @@ declare function applyMove(start: Box, dx: number, dy: number): Box;
896
1135
  */
897
1136
  declare function applyResize(start: Box, handle: ResizeHandle, dx: number, dy: number, min?: number): Box;
898
1137
 
1138
+ /**
1139
+ * Duotone SVG `<filter>` descriptor for Angular templates.
1140
+ *
1141
+ * Ported from:
1142
+ * packages/react/src/viewer/utils/effect-dag-filters.ts (getDuotoneSvgFilterMarkup, hexToRgbUnit)
1143
+ * packages/angular/src/viewer/visual-effects.ts (getDuotoneFilterId, getDuotoneSvgFilter)
1144
+ *
1145
+ * The React package serialises the SVG filter as a raw HTML string. The Angular
1146
+ * package instead returns a **structured descriptor** (`DuotoneFilterDef`) that
1147
+ * the template can render declaratively with `@for` / `@switch`, matching the
1148
+ * `SvgPrimitive` pattern used by `chart-renderer-helpers.ts`.
1149
+ *
1150
+ * @module viewer/duotone-filter
1151
+ */
1152
+
1153
+ /**
1154
+ * Descriptor for an SVG `<feColorMatrix type="matrix">` primitive.
1155
+ * The `values` string is a space-separated 4×5 colour-transformation matrix.
1156
+ */
1157
+ interface FeColorMatrixPrimitive {
1158
+ kind: 'feColorMatrix';
1159
+ /** Space-separated 4×5 matrix values (`type="matrix"`). */
1160
+ values: string;
1161
+ /** `color-interpolation-filters` attribute (always `"sRGB"`). */
1162
+ colorInterpolationFilters: 'sRGB';
1163
+ }
1164
+ /**
1165
+ * One channel entry for an `<feComponentTransfer>` child function element.
1166
+ * Maps to `<feFuncR>`, `<feFuncG>`, or `<feFuncB>` with `type="linear"`.
1167
+ */
1168
+ interface FeComponentTransferChannel {
1169
+ /** Which SVG component-transfer channel this entry corresponds to. */
1170
+ channel: 'R' | 'G' | 'B';
1171
+ /** The `slope` attribute value (highlight − shadow for that channel). */
1172
+ slope: number;
1173
+ /** The `intercept` attribute value (shadow colour for that channel, 0–1). */
1174
+ intercept: number;
1175
+ }
1176
+ /**
1177
+ * Descriptor for an SVG `<feComponentTransfer>` primitive, containing one
1178
+ * linear ramp per RGB channel.
1179
+ *
1180
+ * The template should render:
1181
+ * ```html
1182
+ * <feComponentTransfer>
1183
+ * <feFuncR type="linear" [attr.slope]="ch.slope" [attr.intercept]="ch.intercept" />
1184
+ * …
1185
+ * </feComponentTransfer>
1186
+ * ```
1187
+ */
1188
+ interface FeComponentTransferPrimitive {
1189
+ kind: 'feComponentTransfer';
1190
+ /** Exactly three entries — R, G, B in that order. */
1191
+ channels: [FeComponentTransferChannel, FeComponentTransferChannel, FeComponentTransferChannel];
1192
+ }
1193
+ /**
1194
+ * A fully structured descriptor for a duotone SVG `<filter>` definition.
1195
+ *
1196
+ * ### Integration guide (for the orchestrator)
1197
+ *
1198
+ * **Step 1 – Render the `<defs>` block.**
1199
+ * Inside the element's host component (or a shared slide-level `<svg>`), emit
1200
+ * a hidden `<svg>` containing one `<filter>` per element that has a duotone:
1201
+ *
1202
+ * ```html
1203
+ * @if (duotone) {
1204
+ * <svg width="0" height="0" style="position:absolute;overflow:hidden" aria-hidden="true">
1205
+ * <defs>
1206
+ * <filter [id]="duotone.id" color-interpolation-filters="sRGB">
1207
+ * @for (p of duotone.primitives; track p.kind) {
1208
+ * @switch (p.kind) {
1209
+ * @case ('feColorMatrix') {
1210
+ * <feColorMatrix type="matrix" [attr.values]="p.values" />
1211
+ * }
1212
+ * @case ('feComponentTransfer') {
1213
+ * <feComponentTransfer>
1214
+ * @for (ch of p.channels; track ch.channel) {
1215
+ * @switch (ch.channel) {
1216
+ * @case ('R') { <feFuncR type="linear" [attr.slope]="ch.slope" [attr.intercept]="ch.intercept" /> }
1217
+ * @case ('G') { <feFuncG type="linear" [attr.slope]="ch.slope" [attr.intercept]="ch.intercept" /> }
1218
+ * @case ('B') { <feFuncB type="linear" [attr.slope]="ch.slope" [attr.intercept]="ch.intercept" /> }
1219
+ * }
1220
+ * }
1221
+ * </feComponentTransfer>
1222
+ * }
1223
+ * }
1224
+ * }
1225
+ * </filter>
1226
+ * </defs>
1227
+ * </svg>
1228
+ * }
1229
+ * ```
1230
+ *
1231
+ * **Step 2 – Apply the CSS `filter` reference.**
1232
+ * In `element-style.ts` (or the image host component), when `duotone` is
1233
+ * defined, append `duotone.cssFilter` to the element's `filter` CSS property
1234
+ * *instead of* stripping the `url(#…)` reference as `getShapeFillStrokeStyle`
1235
+ * currently does. Example integration in `getShapeFillStrokeStyle`:
1236
+ *
1237
+ * ```ts
1238
+ * const duotone = buildDuotoneFilter(el);
1239
+ * const dagFilter = getEffectFilterCss(el.shapeStyle, el.id);
1240
+ * if (dagFilter) {
1241
+ * // duotone url(#…) is now meaningful — keep it
1242
+ * style['filter'] = dagFilter;
1243
+ * } else if (duotone) {
1244
+ * style['filter'] = duotone.cssFilter;
1245
+ * }
1246
+ * // Expose duotone so the template can render the <defs> block:
1247
+ * return { style, duotone };
1248
+ * ```
1249
+ */
1250
+ interface DuotoneFilterDef {
1251
+ /**
1252
+ * Stable SVG `filter` element `id`, derived deterministically from the
1253
+ * element id. Format: `dag-duotone-<elementId>`.
1254
+ */
1255
+ id: string;
1256
+ /**
1257
+ * Ordered list of SVG filter primitives that make up the `<filter>` body.
1258
+ * Always contains exactly two entries:
1259
+ * 0. `feColorMatrix` — BT.709 luminance-to-grayscale matrix
1260
+ * 1. `feComponentTransfer` — per-channel linear ramp (shadow → highlight)
1261
+ */
1262
+ primitives: [FeColorMatrixPrimitive, FeComponentTransferPrimitive];
1263
+ /**
1264
+ * Ready-to-use CSS `filter` function string.
1265
+ * Example: `"url(#dag-duotone-shape1)"`.
1266
+ * Append this to the element's existing `filter` CSS value.
1267
+ */
1268
+ cssFilter: string;
1269
+ /**
1270
+ * The raw shadow colour (`color1`) in 6-digit hex, preserved for tests and
1271
+ * debugging without re-parsing the matrix.
1272
+ */
1273
+ shadowHex: string;
1274
+ /**
1275
+ * The raw highlight colour (`color2`) in 6-digit hex, preserved for tests and
1276
+ * debugging without re-parsing the matrix.
1277
+ */
1278
+ highlightHex: string;
1279
+ }
1280
+ /**
1281
+ * Build a stable SVG filter `id` for a duotone effect on the given element.
1282
+ *
1283
+ * Matches the format used by `getDuotoneFilterId` in `visual-effects.ts` so
1284
+ * that the `url(#…)` reference emitted by `getEffectDagCssFilter` points to
1285
+ * the correct `<filter>` definition.
1286
+ *
1287
+ * @param elementId - The element's `id` from `PptxElement.id`.
1288
+ * @returns A CSS-identifier-safe string (no spaces, starts with a letter).
1289
+ */
1290
+ declare function buildDuotoneFilterId(elementId: string): string;
1291
+ /**
1292
+ * Derive a fully structured duotone `<filter>` descriptor from a
1293
+ * `PptxElement`.
1294
+ *
1295
+ * The function reads `element.shapeStyle.dagDuotone` — the parsed
1296
+ * `<a:duotone>` colour pair populated by the core parser. Returns
1297
+ * `undefined` when the element carries no duotone effect.
1298
+ *
1299
+ * ### Colour math
1300
+ * 1. Convert to grayscale using BT.709 luminance weights (feColorMatrix).
1301
+ * 2. Map grayscale 0 → `color1` (shadow) and 1 → `color2` (highlight) via
1302
+ * per-channel linear ramps (feComponentTransfer / feFuncR|G|B):
1303
+ * ```
1304
+ * slope = highlight_channel − shadow_channel
1305
+ * intercept = shadow_channel
1306
+ * ```
1307
+ * At luminance 0: `output = intercept = shadow`.
1308
+ * At luminance 1: `output = slope + intercept = highlight`.
1309
+ *
1310
+ * @param element - Any `PptxElement`; elements without `shapeStyle` or
1311
+ * `dagDuotone` return `undefined`.
1312
+ * @returns A {@link DuotoneFilterDef} or `undefined`.
1313
+ */
1314
+ declare function buildDuotoneFilter(element: PptxElement): DuotoneFilterDef | undefined;
1315
+
899
1316
  /**
900
1317
  * Basic, framework-agnostic style computation for slide elements, returning
901
1318
  * `[ngStyle]`-compatible maps.
@@ -911,6 +1328,13 @@ declare function applyResize(start: Box, handle: ResizeHandle, dx: number, dy: n
911
1328
  * return type (CSS map shape) differs per framework — so a future refactor
912
1329
  * could hoist a neutral core into `pptx-viewer-shared`.
913
1330
  */
1331
+ /**
1332
+ * Resolve the duotone SVG `<filter>` descriptor for an element, or `undefined`
1333
+ * when it carries no duotone image effect. The renderer pairs this with the
1334
+ * `filter: url(#…)` set in {@link getShapeFillStrokeStyle} by injecting the
1335
+ * matching `<filter>` def into a hidden `<defs>` block.
1336
+ */
1337
+ declare function getDuotoneFilterDef(el: PptxElement): DuotoneFilterDef | undefined;
914
1338
  /** `[ngStyle]`-compatible style map. */
915
1339
  type StyleMap = Record<string, string | number>;
916
1340
  /**
@@ -1241,6 +1665,8 @@ declare class ElementRendererComponent {
1241
1665
  readonly obstacles: _angular_core.InputSignal<readonly Rect[]>;
1242
1666
  readonly canvasWidth: _angular_core.InputSignal<number>;
1243
1667
  readonly canvasHeight: _angular_core.InputSignal<number>;
1668
+ /** Duotone SVG `<filter>` descriptor for this element, if any. */
1669
+ readonly duotoneFilter: _angular_core.Signal<pptx_angular_viewer.DuotoneFilterDef | undefined>;
1244
1670
  readonly containerStyle: _angular_core.Signal<StyleMap>;
1245
1671
  readonly shapeContainerStyle: _angular_core.Signal<StyleMap>;
1246
1672
  readonly textStyle: _angular_core.Signal<StyleMap>;
@@ -2061,6 +2487,14 @@ declare class PresentationOverlayComponent implements OnInit, OnDestroy {
2061
2487
  readonly closed: _angular_core.OutputEmitterRef<void>;
2062
2488
  /** Zero-based index into `slides()`. */
2063
2489
  protected readonly currentIndex: _angular_core.WritableSignal<number>;
2490
+ /**
2491
+ * Active slide-transition animation: the outgoing slide + the incoming
2492
+ * slide's transition, played over the new slide. Cleared on completion.
2493
+ */
2494
+ protected readonly activeTransition: _angular_core.WritableSignal<{
2495
+ outgoing: PptxSlide;
2496
+ transition: PptxSlideTransition;
2497
+ } | null>;
2064
2498
  /** Viewport dimensions — updated on resize. */
2065
2499
  private readonly viewportW;
2066
2500
  private readonly viewportH;
@@ -2299,6 +2733,14 @@ declare class InspectorPanelComponent {
2299
2733
  protected readonly currentBold: _angular_core.Signal<boolean>;
2300
2734
  protected readonly currentItalic: _angular_core.Signal<boolean>;
2301
2735
  protected readonly currentUnderline: _angular_core.Signal<boolean>;
2736
+ /** The selected element narrowed to a table, or undefined. */
2737
+ protected readonly tableEl: _angular_core.Signal<TablePptxElement | undefined>;
2738
+ /** The selected element narrowed to a chart, or undefined. */
2739
+ protected readonly chartEl: _angular_core.Signal<ChartPptxElement | undefined>;
2740
+ /** Commit a partial-element patch from an advanced sub-panel as one history entry. */
2741
+ protected onPatch(patch: Partial<PptxElement>): void;
2742
+ /** Commit a fully-replaced element (table/chart data editors) as one history entry. */
2743
+ protected onElementReplace(updated: PptxElement): void;
2302
2744
  protected onPositionChange(event: Event, axis: 'x' | 'y'): void;
2303
2745
  protected onSizeChange(event: Event, dim: 'width' | 'height'): void;
2304
2746
  protected onRotationChange(event: Event): void;
@@ -2314,6 +2756,281 @@ declare class InspectorPanelComponent {
2314
2756
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<InspectorPanelComponent, "pptx-inspector-panel", never, { "element": { "alias": "element"; "required": true; "isSignal": true; }; "slideIndex": { "alias": "slideIndex"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
2315
2757
  }
2316
2758
 
2759
+ /**
2760
+ * gradient-picker-helpers.ts — Pure (no Angular) helpers for GradientPickerComponent.
2761
+ *
2762
+ * Ported from / models the patterns in:
2763
+ * packages/react/src/viewer/components/inspector/FillAdvancedControls.tsx
2764
+ * packages/react/src/viewer/components/inspector/FillStrokeProperties.tsx
2765
+ * packages/angular/src/viewer/color-gradient.ts
2766
+ *
2767
+ * Readers extract current gradient values from a PptxElement (falling back to
2768
+ * sensible defaults), and patch-builders produce shallow-merge-ready
2769
+ * Partial<PptxElement> objects safe to pass to EditorStateService.updateElement.
2770
+ *
2771
+ * No `any` — every type is concrete or `unknown` + narrowed.
2772
+ */
2773
+
2774
+ /** A single gradient stop, mirroring the ShapeStyle array item shape. */
2775
+ interface GradientStop {
2776
+ color: string;
2777
+ position: number;
2778
+ opacity?: number;
2779
+ }
2780
+ /** The editable gradient state surfaced to the component. */
2781
+ interface GradientState {
2782
+ type: 'linear' | 'radial';
2783
+ /** Angle in degrees (only meaningful for linear). */
2784
+ angle: number;
2785
+ stops: GradientStop[];
2786
+ }
2787
+
2788
+ declare class GradientPickerComponent {
2789
+ /** The element whose gradient fill is being edited. */
2790
+ readonly element: _angular_core.InputSignal<PptxElement>;
2791
+ /**
2792
+ * Emits a Partial<PptxElement> patch each time the user commits a change.
2793
+ * The orchestrator (InspectorPanelComponent or a wrapper) should call
2794
+ * EditorStateService.updateElement(slideIndex, element().id, patch).
2795
+ */
2796
+ readonly patch: _angular_core.OutputEmitterRef<Partial<PptxElement>>;
2797
+ /** Derived gradient state from the current element. */
2798
+ protected readonly state: _angular_core.Signal<GradientState>;
2799
+ /** CSS gradient string for the preview strip. */
2800
+ protected readonly previewCss: _angular_core.Signal<string>;
2801
+ protected onTypeChange(event: Event): void;
2802
+ protected onAngleChange(event: Event): void;
2803
+ protected onStopColorChange(event: Event, index: number): void;
2804
+ protected onStopPositionChange(event: Event, index: number): void;
2805
+ protected onStopOpacityChange(event: Event, index: number): void;
2806
+ protected onRemoveStop(index: number): void;
2807
+ protected onAddStop(): void;
2808
+ private emit;
2809
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<GradientPickerComponent, never>;
2810
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<GradientPickerComponent, "pptx-gradient-picker", never, { "element": { "alias": "element"; "required": true; "isSignal": true; }; }, { "patch": "patch"; }, never, never, true, never>;
2811
+ }
2812
+
2813
+ /**
2814
+ * effects-helpers.ts — Pure (no Angular) helpers for EffectsPanelComponent.
2815
+ *
2816
+ * Ported from / models the patterns in:
2817
+ * packages/react/src/viewer/components/inspector/fill-stroke-effect-configs.ts
2818
+ * packages/react/src/viewer/components/inspector/fill-stroke-visual-configs.ts
2819
+ * packages/angular/src/viewer/visual-effects.ts
2820
+ * packages/angular/src/viewer/inspector-helpers.ts
2821
+ *
2822
+ * Readers extract effect values from a PptxElement (with sensible defaults),
2823
+ * and patch-builders produce shallow-merge-ready Partial<PptxElement> objects
2824
+ * for EditorStateService.updateElement.
2825
+ *
2826
+ * @module viewer/effects-helpers
2827
+ */
2828
+
2829
+ /** Editable outer shadow state. */
2830
+ interface OuterShadowState {
2831
+ enabled: boolean;
2832
+ color: string;
2833
+ opacity: number;
2834
+ blur: number;
2835
+ /** Direction angle in degrees. */
2836
+ angle: number;
2837
+ /** Distance in px. */
2838
+ distance: number;
2839
+ }
2840
+ /** Editable inner shadow state. */
2841
+ interface InnerShadowState {
2842
+ enabled: boolean;
2843
+ color: string;
2844
+ opacity: number;
2845
+ blur: number;
2846
+ offsetX: number;
2847
+ offsetY: number;
2848
+ }
2849
+ /** Editable glow state. */
2850
+ interface GlowState {
2851
+ enabled: boolean;
2852
+ color: string;
2853
+ radius: number;
2854
+ opacity: number;
2855
+ }
2856
+ /** Editable reflection state. */
2857
+ interface ReflectionState {
2858
+ enabled: boolean;
2859
+ blurRadius: number;
2860
+ startOpacity: number;
2861
+ endOpacity: number;
2862
+ distance: number;
2863
+ direction: number;
2864
+ }
2865
+ /** Editable soft-edge (blur) state. */
2866
+ interface SoftEdgeState {
2867
+ enabled: boolean;
2868
+ radius: number;
2869
+ }
2870
+ /** All effect values collected for the panel. */
2871
+ interface EffectsState {
2872
+ outerShadow: OuterShadowState;
2873
+ innerShadow: InnerShadowState;
2874
+ glow: GlowState;
2875
+ reflection: ReflectionState;
2876
+ softEdge: SoftEdgeState;
2877
+ }
2878
+
2879
+ declare class EffectsPanelComponent {
2880
+ /** The element whose effects are being edited. */
2881
+ readonly element: _angular_core.InputSignal<PptxElement>;
2882
+ /**
2883
+ * Emits a Partial<PptxElement> patch each time the user commits a change.
2884
+ * The orchestrator should call EditorStateService.updateElement(slideIndex, element().id, patch).
2885
+ */
2886
+ readonly patch: _angular_core.OutputEmitterRef<Partial<PptxElement>>;
2887
+ /** Derived EffectsState from the current element. */
2888
+ protected readonly state: _angular_core.Signal<EffectsState>;
2889
+ /** Stable key for keying inputs to the current element (prevents caret-reset). */
2890
+ protected readonly elementKey: _angular_core.Signal<string>;
2891
+ protected onOuterShadowToggle(event: Event): void;
2892
+ protected onOuterShadowField(field: 'color' | 'opacity' | 'blur' | 'angle' | 'distance', event: Event): void;
2893
+ protected onInnerShadowToggle(event: Event): void;
2894
+ protected onInnerShadowField(field: 'color' | 'opacity' | 'blur' | 'offsetX' | 'offsetY', event: Event): void;
2895
+ protected onGlowToggle(event: Event): void;
2896
+ protected onGlowField(field: 'color' | 'radius' | 'opacity', event: Event): void;
2897
+ protected onReflectionToggle(event: Event): void;
2898
+ protected onReflectionField(field: 'blurRadius' | 'startOpacity' | 'endOpacity' | 'distance' | 'direction', event: Event): void;
2899
+ protected onSoftEdgeToggle(event: Event): void;
2900
+ protected onSoftEdgeRadius(event: Event): void;
2901
+ private emit;
2902
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<EffectsPanelComponent, never>;
2903
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EffectsPanelComponent, "pptx-effects-panel", never, { "element": { "alias": "element"; "required": true; "isSignal": true; }; }, { "patch": "patch"; }, never, never, true, never>;
2904
+ }
2905
+
2906
+ /**
2907
+ * text-advanced-helpers.ts — Pure (no Angular) helpers for TextAdvancedPanelComponent.
2908
+ *
2909
+ * Ported from / models the patterns in:
2910
+ * packages/react/src/viewer/components/inspector/TextPropertiesHelpers.tsx
2911
+ * packages/react/src/viewer/components/inspector/TextProperties.tsx
2912
+ * packages/angular/src/viewer/inspector-helpers.ts
2913
+ *
2914
+ * Readers extract advanced text values from a PptxElement (with sensible
2915
+ * defaults), and patch-builders produce shallow-merge-ready Partial<PptxElement>
2916
+ * objects for EditorStateService.updateElement.
2917
+ *
2918
+ * @module viewer/text-advanced-helpers
2919
+ */
2920
+
2921
+ /**
2922
+ * The advanced text properties surfaced to the panel.
2923
+ *
2924
+ * Covers: character spacing, line spacing, paragraph alignment + spacing,
2925
+ * indent, text direction, and vertical anchor.
2926
+ */
2927
+ interface TextAdvancedState {
2928
+ /** Character spacing in hundredths of a point (0 = normal). */
2929
+ characterSpacing: number;
2930
+ /** Line spacing multiplier (1.0 = single). */
2931
+ lineSpacing: number;
2932
+ /** Exact line spacing in points, or null when using multiplier mode. */
2933
+ lineSpacingExactPt: number | null;
2934
+ /** Paragraph spacing before in px. */
2935
+ paragraphSpacingBefore: number;
2936
+ /** Paragraph spacing after in px. */
2937
+ paragraphSpacingAfter: number;
2938
+ /** Paragraph text alignment. */
2939
+ align: NonNullable<TextStyle['align']>;
2940
+ /** Vertical anchor within the text body. */
2941
+ vAlign: NonNullable<TextStyle['vAlign']>;
2942
+ /** Paragraph first-line indent in px. */
2943
+ paragraphIndent: number;
2944
+ /** Paragraph left margin in px. */
2945
+ paragraphMarginLeft: number;
2946
+ /** Body text direction. */
2947
+ textDirection: NonNullable<TextStyle['textDirection']>;
2948
+ /** Right-to-left paragraph/run direction. */
2949
+ rtl: boolean;
2950
+ }
2951
+
2952
+ declare class TextAdvancedPanelComponent {
2953
+ /** The element whose advanced text properties are being edited. */
2954
+ readonly element: _angular_core.InputSignal<PptxElement>;
2955
+ /**
2956
+ * Emits a Partial<PptxElement> patch each time the user commits a change.
2957
+ * The orchestrator should call EditorStateService.updateElement(slideIndex, element().id, patch).
2958
+ */
2959
+ readonly patch: _angular_core.OutputEmitterRef<Partial<PptxElement>>;
2960
+ /** Whether the element supports text properties. */
2961
+ protected readonly hasText: _angular_core.Signal<boolean>;
2962
+ /** Derived advanced text state from the current element. */
2963
+ protected readonly state: _angular_core.Signal<TextAdvancedState>;
2964
+ /** Stable key for keying inputs to the current element (prevents caret-reset mid-edit). */
2965
+ protected readonly elementKey: _angular_core.Signal<string>;
2966
+ /** Exposed option arrays for the template. */
2967
+ protected readonly alignOptions: [NonNullable<"center" | "left" | "right" | "justify" | "justLow" | "dist" | "thaiDist" | undefined>, string][];
2968
+ protected readonly vAlignOptions: [NonNullable<"top" | "middle" | "bottom" | undefined>, string][];
2969
+ protected readonly textDirectionOptions: [NonNullable<"eaVert" | "wordArtVert" | "wordArtVertRtl" | "mongolianVert" | "horizontal" | "vertical" | "vertical270" | undefined>, string][];
2970
+ protected alignLabel(align: NonNullable<TextStyle['align']>): string;
2971
+ protected onAlignChange(align: NonNullable<TextStyle['align']>): void;
2972
+ protected onVAlignChange(event: Event): void;
2973
+ protected onTextDirectionChange(event: Event): void;
2974
+ protected onRtlToggle(event: Event): void;
2975
+ protected onCharacterSpacingChange(event: Event): void;
2976
+ protected onLineSpacingChange(event: Event): void;
2977
+ protected onLineSpacingExactPtChange(event: Event): void;
2978
+ protected onSpacingBeforeChange(event: Event): void;
2979
+ protected onSpacingAfterChange(event: Event): void;
2980
+ protected onIndentChange(event: Event): void;
2981
+ protected onMarginLeftChange(event: Event): void;
2982
+ private emit;
2983
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TextAdvancedPanelComponent, never>;
2984
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TextAdvancedPanelComponent, "pptx-text-advanced-panel", never, { "element": { "alias": "element"; "required": true; "isSignal": true; }; }, { "patch": "patch"; }, never, never, true, never>;
2985
+ }
2986
+
2987
+ declare class TableDataEditorComponent {
2988
+ /** The table element being edited. */
2989
+ readonly element: _angular_core.InputSignal<TablePptxElement>;
2990
+ /** Whether editing is enabled (read-only mode when false). */
2991
+ readonly canEdit: _angular_core.InputSignal<boolean>;
2992
+ /** Emits the updated element after any edit operation. */
2993
+ readonly elementChange: _angular_core.OutputEmitterRef<TablePptxElement>;
2994
+ protected readonly rows: _angular_core.Signal<pptx_viewer_core.PptxTableRow[]>;
2995
+ protected readonly rowCount: _angular_core.Signal<number>;
2996
+ protected readonly colCount: _angular_core.Signal<number>;
2997
+ protected readonly colIndices: _angular_core.Signal<number[]>;
2998
+ protected onCellChange(event: Event, rowIndex: number, colIndex: number): void;
2999
+ protected onAddRow(): void;
3000
+ protected onRemoveLastRow(): void;
3001
+ protected onRemoveRow(rowIndex: number): void;
3002
+ protected onAddColumn(): void;
3003
+ protected onRemoveLastColumn(): void;
3004
+ protected onRemoveColumn(colIndex: number): void;
3005
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TableDataEditorComponent, never>;
3006
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TableDataEditorComponent, "pptx-table-data-editor", never, { "element": { "alias": "element"; "required": true; "isSignal": true; }; "canEdit": { "alias": "canEdit"; "required": false; "isSignal": true; }; }, { "elementChange": "elementChange"; }, never, never, true, never>;
3007
+ }
3008
+
3009
+ declare class ChartDataEditorComponent {
3010
+ /** The chart element being edited. */
3011
+ readonly element: _angular_core.InputSignal<ChartPptxElement>;
3012
+ /** Whether editing is enabled (read-only mode when false). */
3013
+ readonly canEdit: _angular_core.InputSignal<boolean>;
3014
+ /** Emits the updated element after any edit operation. */
3015
+ readonly elementChange: _angular_core.OutputEmitterRef<ChartPptxElement>;
3016
+ protected readonly hasData: _angular_core.Signal<boolean>;
3017
+ protected readonly series: _angular_core.Signal<pptx_viewer_core.PptxChartSeries[]>;
3018
+ protected readonly categories: _angular_core.Signal<string[]>;
3019
+ protected readonly seriesCount: _angular_core.Signal<number>;
3020
+ protected readonly catCount: _angular_core.Signal<number>;
3021
+ protected onSeriesNameChange(event: Event, seriesIndex: number): void;
3022
+ protected onCategoryLabelChange(event: Event, catIndex: number): void;
3023
+ protected onValueChange(event: Event, seriesIndex: number, catIndex: number): void;
3024
+ protected onAddSeries(): void;
3025
+ protected onRemoveLastSeries(): void;
3026
+ protected onRemoveSeries(seriesIndex: number): void;
3027
+ protected onAddCategory(): void;
3028
+ protected onRemoveLastCategory(): void;
3029
+ protected onRemoveCategory(catIndex: number): void;
3030
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ChartDataEditorComponent, never>;
3031
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ChartDataEditorComponent, "pptx-chart-data-editor", never, { "element": { "alias": "element"; "required": true; "isSignal": true; }; "canEdit": { "alias": "canEdit"; "required": false; "isSignal": true; }; }, { "elementChange": "elementChange"; }, never, never, true, never>;
3032
+ }
3033
+
2317
3034
  /**
2318
3035
  * SlidesPanelComponent — vertical slide-strip for the editor sidebar.
2319
3036
  *
@@ -2428,6 +3145,26 @@ declare class ExportService {
2428
3145
  * @param fileName - Suggested download file name (unsafe chars stripped).
2429
3146
  */
2430
3147
  exportCanvasesToPdf(canvases: HTMLCanvasElement[], canvasWidth: number, canvasHeight: number, fileName: string): void;
3148
+ /**
3149
+ * Assemble an animated GIF from pre-rendered slide canvases (one frame per
3150
+ * slide) and trigger a download. Frame delay is derived from
3151
+ * `slideDurationMs` via the pure {@link planGifFrames} planner.
3152
+ *
3153
+ * @param canvases - One canvas per slide, in order.
3154
+ * @param slideDurationMs - Display time per slide in milliseconds.
3155
+ * @param fileName - Suggested download file name.
3156
+ */
3157
+ exportCanvasesToGif(canvases: HTMLCanvasElement[], slideDurationMs: number, fileName: string): void;
3158
+ /**
3159
+ * Record a WebM video from pre-rendered slide canvases (each held for
3160
+ * `slideDurationMs`) via the browser `MediaRecorder` and trigger a download.
3161
+ *
3162
+ * @param canvases - One canvas per slide, in order.
3163
+ * @param slideDurationMs - Display time per slide in milliseconds.
3164
+ * @param fileName - Suggested download file name.
3165
+ * @param signal - Optional abort signal to cancel recording.
3166
+ */
3167
+ exportCanvasesToWebm(canvases: HTMLCanvasElement[], slideDurationMs: number, fileName: string, signal?: AbortSignal): Promise<void>;
2431
3168
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<ExportService, never>;
2432
3169
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<ExportService>;
2433
3170
  }
@@ -2450,6 +3187,309 @@ declare class ExportService {
2450
3187
  */
2451
3188
  declare function renderToCanvas(element: HTMLElement, options?: Partial<Options>): Promise<HTMLCanvasElement>;
2452
3189
 
3190
+ /**
3191
+ * GIF export helpers for the Angular viewer.
3192
+ *
3193
+ * Source: ported from packages/react/src/viewer/utils/export-gif-encoder.ts
3194
+ * and packages/react/src/viewer/utils/export-gif.ts.
3195
+ *
3196
+ * Split into two concerns:
3197
+ * 1. Pure, browser-free planning helpers (frame ordering, per-frame delay
3198
+ * computation, dimension clamping) — fully unit-testable.
3199
+ * 2. A thin browser-facing `encodeGif()` function that assembles an animated
3200
+ * GIF89a Uint8Array from per-slide ImageData objects and a pre-computed
3201
+ * frame delay. The caller (ExportService) is responsible for rasterising
3202
+ * slides to canvases and extracting ImageData via `ctx.getImageData()`.
3203
+ *
3204
+ * No external encoder dependency is required — the encoder is a self-contained
3205
+ * pure-JS GIF89a implementation (median-cut quantisation + LZW) that mirrors
3206
+ * the React package exactly.
3207
+ */
3208
+ /**
3209
+ * A single GIF frame descriptor produced by the planning helpers.
3210
+ * The `imageData` field is filled in by the caller (ExportService) after
3211
+ * rasterising the corresponding slide.
3212
+ */
3213
+ interface GifFramePlan {
3214
+ /** 0-based slide index this frame corresponds to. */
3215
+ slideIndex: number;
3216
+ /** Frame delay in **centiseconds** (1 cs = 10 ms), as required by GIF89a. */
3217
+ delayCs: number;
3218
+ }
3219
+ /**
3220
+ * Options controlling GIF frame planning.
3221
+ */
3222
+ interface GifPlanOptions {
3223
+ /** Total number of slides in the presentation. */
3224
+ totalSlides: number;
3225
+ /**
3226
+ * Duration each slide is shown, in **milliseconds** (default: 2000).
3227
+ * Per-slide overrides can be supplied via {@link slideTimingsMs}.
3228
+ */
3229
+ slideDurationMs?: number;
3230
+ /**
3231
+ * Per-slide duration overrides in milliseconds (index maps to slide index).
3232
+ * When a slide's index is present here its value takes precedence over
3233
+ * {@link slideDurationMs}.
3234
+ */
3235
+ slideTimingsMs?: number[];
3236
+ }
3237
+ /**
3238
+ * Compute the ordered list of {@link GifFramePlan} objects for a presentation.
3239
+ *
3240
+ * All timing is derived here; nothing browser-specific is touched.
3241
+ *
3242
+ * @param opts - Planning options.
3243
+ * @returns One {@link GifFramePlan} per slide, in slide order (0-based).
3244
+ *
3245
+ * @example
3246
+ * const plans = planGifFrames({ totalSlides: 5, slideDurationMs: 3000 });
3247
+ * // plans[0].slideIndex === 0, plans[0].delayCs === 300, …
3248
+ */
3249
+ declare function planGifFrames(opts: GifPlanOptions): GifFramePlan[];
3250
+ /**
3251
+ * Convert a slide duration in milliseconds to a GIF89a frame delay in
3252
+ * centiseconds (1 cs = 10 ms), clamped to a minimum of 1 cs.
3253
+ *
3254
+ * @param ms - Duration in milliseconds (must be > 0).
3255
+ * @returns Frame delay in centiseconds (integer ≥ 1).
3256
+ */
3257
+ declare function msToFrameDelayCs(ms: number): number;
3258
+ /**
3259
+ * Clamp canvas/image dimensions so neither side exceeds `maxSide` pixels
3260
+ * while preserving the aspect ratio. When both dimensions are already within
3261
+ * the limit the original values are returned unchanged.
3262
+ *
3263
+ * GIF is limited to 65535 × 65535 but practical encoders perform best at
3264
+ * much smaller sizes (the React package defaults to 0.5× scale). This
3265
+ * helper lets callers enforce a reasonable cap without coupling the logic to
3266
+ * a specific scale factor.
3267
+ *
3268
+ * @param width - Original width in pixels.
3269
+ * @param height - Original height in pixels.
3270
+ * @param maxSide - Maximum permitted dimension on either axis (default 1920).
3271
+ * @returns `{ width, height }` clamped to `maxSide`, floored to whole pixels.
3272
+ */
3273
+ declare function clampGifDimensions(width: number, height: number, maxSide?: number): {
3274
+ width: number;
3275
+ height: number;
3276
+ };
3277
+ /**
3278
+ * A single animated GIF frame: raw RGBA pixel data plus its dimensions.
3279
+ */
3280
+ interface GifFrame {
3281
+ imageData: ImageData;
3282
+ width: number;
3283
+ height: number;
3284
+ }
3285
+ /**
3286
+ * Options for {@link encodeGif}.
3287
+ */
3288
+ interface EncodeGifOptions {
3289
+ /**
3290
+ * Frame delay in **centiseconds** (1 cs = 10 ms). All frames share the
3291
+ * same delay; for per-frame delays compute them with {@link planGifFrames}
3292
+ * and encode each frame separately.
3293
+ *
3294
+ * Default: 200 cs (2 s).
3295
+ */
3296
+ delayCs?: number;
3297
+ /**
3298
+ * Number of times the animation loops (0 = loop forever, default).
3299
+ */
3300
+ loopCount?: number;
3301
+ }
3302
+ /**
3303
+ * Encode an ordered list of RGBA image frames into an animated GIF89a byte
3304
+ * sequence.
3305
+ *
3306
+ * Uses median-cut colour quantisation (256 colours per frame) and LZW
3307
+ * compression. All frames must have identical dimensions.
3308
+ *
3309
+ * This function is browser-safe but does NOT require any browser API — it
3310
+ * operates on pre-extracted `ImageData` objects. Callers must rasterise
3311
+ * slides to canvases themselves (see `ExportService.renderElement`).
3312
+ *
3313
+ * @param frames - Ordered array of frame descriptors.
3314
+ * @param opts - Encoding options.
3315
+ * @returns Raw GIF89a bytes.
3316
+ *
3317
+ * @example
3318
+ * // In ExportService:
3319
+ * const canvas = await this.renderElement(el, 0.5);
3320
+ * const ctx = canvas.getContext('2d')!;
3321
+ * const id = ctx.getImageData(0, 0, canvas.width, canvas.height);
3322
+ * const bytes = encodeGif([{ imageData: id, width: canvas.width, height: canvas.height }]);
3323
+ * const blob = new Blob([bytes.buffer], { type: 'image/gif' });
3324
+ */
3325
+ declare function encodeGif(frames: GifFrame[], opts?: EncodeGifOptions): Uint8Array;
3326
+
3327
+ /**
3328
+ * Video (WebM) export helpers for the Angular viewer.
3329
+ *
3330
+ * Source: ported from packages/react/src/viewer/utils/export-video.ts.
3331
+ *
3332
+ * Split into two concerns:
3333
+ * 1. Pure, browser-free planning helpers (frame-segment timing, MIME-type
3334
+ * selection) — fully unit-testable with no DOM/MediaRecorder dependency.
3335
+ * 2. A thin browser-facing `recordWebm()` function that drives a
3336
+ * `MediaRecorder` over a canvas `captureStream()` to produce a WebM Blob.
3337
+ * The caller (ExportService) supplies the pre-rendered slide canvases and
3338
+ * a `recordingCanvas` for compositing.
3339
+ *
3340
+ * No new npm dependency is needed — `MediaRecorder` is a browser built-in.
3341
+ */
3342
+ /**
3343
+ * Timing plan for one slide's contribution to the video.
3344
+ */
3345
+ interface VideoSegmentPlan {
3346
+ /** 0-based slide index. */
3347
+ slideIndex: number;
3348
+ /** Duration this segment should be held, in milliseconds. */
3349
+ durationMs: number;
3350
+ /** Target frame rate used to compute the segment frame count. */
3351
+ fps: number;
3352
+ /** Total number of draw-loop iterations for this segment at `fps`. */
3353
+ frameCount: number;
3354
+ }
3355
+ /**
3356
+ * Options for {@link planVideoSegments}.
3357
+ */
3358
+ interface VideoPlanOptions {
3359
+ /** Total number of slides. */
3360
+ totalSlides: number;
3361
+ /**
3362
+ * Default slide display duration in **milliseconds** (default: 3000).
3363
+ * Overridden per-slide by {@link slideTimingsMs}.
3364
+ */
3365
+ slideDurationMs?: number;
3366
+ /**
3367
+ * Per-slide duration overrides in milliseconds (index maps to slide index).
3368
+ * `undefined` entries fall back to {@link slideDurationMs}.
3369
+ */
3370
+ slideTimingsMs?: number[];
3371
+ /**
3372
+ * Desired recording frame rate in frames-per-second (default: 30).
3373
+ * Used to compute the number of draw iterations per segment.
3374
+ */
3375
+ fps?: number;
3376
+ }
3377
+ /**
3378
+ * Compute an ordered list of {@link VideoSegmentPlan} objects for a
3379
+ * presentation video. Nothing browser-specific is touched.
3380
+ *
3381
+ * @param opts - Planning options.
3382
+ * @returns One {@link VideoSegmentPlan} per slide, in slide order (0-based).
3383
+ *
3384
+ * @example
3385
+ * const segs = planVideoSegments({ totalSlides: 3, slideDurationMs: 2000, fps: 30 });
3386
+ * // segs[0].durationMs === 2000, segs[0].frameCount === 60
3387
+ */
3388
+ declare function planVideoSegments(opts: VideoPlanOptions): VideoSegmentPlan[];
3389
+ /**
3390
+ * Select the first MIME type from `candidates` that `MediaRecorder.isTypeSupported`
3391
+ * accepts, falling back to the last candidate in the list when none is supported.
3392
+ *
3393
+ * This is a pure browser-API wrapper (no DOM, no canvas) that can be
3394
+ * spied/mocked in unit tests.
3395
+ *
3396
+ * Priority order recommended for WebM:
3397
+ * ```
3398
+ * ['video/webm;codecs=vp9', 'video/webm;codecs=vp8', 'video/webm']
3399
+ * ```
3400
+ *
3401
+ * @param candidates - Ordered list of MIME type strings to test (most preferred first).
3402
+ * @returns The first supported MIME type, or the last candidate as the fallback.
3403
+ * @throws When `candidates` is empty.
3404
+ */
3405
+ declare function pickSupportedMimeType(candidates: string[]): string;
3406
+ /**
3407
+ * Compute the frame interval in milliseconds for a target frame rate.
3408
+ *
3409
+ * @param fps - Desired frames per second (must be > 0).
3410
+ * @returns Frame interval in milliseconds.
3411
+ */
3412
+ declare function fpsToFrameIntervalMs(fps: number): number;
3413
+ /**
3414
+ * Compute the number of draw-loop frames needed to fill a segment of `durationMs`
3415
+ * at `fps`. Always at least 1.
3416
+ *
3417
+ * @param durationMs - Segment duration in milliseconds.
3418
+ * @param fps - Frame rate in frames per second.
3419
+ * @returns Number of frames (integer ≥ 1).
3420
+ */
3421
+ declare function segmentFrameCount(durationMs: number, fps: number): number;
3422
+ /**
3423
+ * Default ordered MIME-type candidates for WebM recording, most preferred first.
3424
+ * Pass to {@link pickSupportedMimeType} or directly to `recordWebm`.
3425
+ */
3426
+ declare const WEBM_MIME_CANDIDATES: readonly string[];
3427
+ /**
3428
+ * Options for {@link recordWebm}.
3429
+ */
3430
+ interface RecordWebmOptions {
3431
+ /**
3432
+ * Desired recording frame rate fed to `captureStream()` (default: 30).
3433
+ */
3434
+ fps?: number;
3435
+ /**
3436
+ * Per-slide durations in milliseconds (index maps to slide order in `canvases`).
3437
+ * When absent, `slideDurationMs` is used for every slide.
3438
+ */
3439
+ slideTimingsMs?: number[];
3440
+ /**
3441
+ * Default slide duration in milliseconds (default: 3000).
3442
+ */
3443
+ slideDurationMs?: number;
3444
+ /**
3445
+ * MIME type for `MediaRecorder` (default: result of
3446
+ * `pickSupportedMimeType(WEBM_MIME_CANDIDATES)`).
3447
+ */
3448
+ mimeType?: string;
3449
+ /**
3450
+ * Video bit rate in bits/s (default: 5_000_000 = 5 Mbps, matching the
3451
+ * React package).
3452
+ */
3453
+ videoBitsPerSecond?: number;
3454
+ /**
3455
+ * Optional `AbortSignal` to cancel the recording mid-way.
3456
+ */
3457
+ signal?: AbortSignal;
3458
+ /**
3459
+ * Progress callback invoked at the start of each slide's recording segment.
3460
+ * Receives `(currentSlide, totalSlides)`.
3461
+ */
3462
+ onProgress?: (current: number, total: number) => void;
3463
+ }
3464
+ /**
3465
+ * Record an ordered list of pre-rendered slide canvases as a WebM video Blob.
3466
+ *
3467
+ * Strategy (mirrors the React `exportAllSlidesAsVideo`):
3468
+ * 1. Create an off-screen `recordingCanvas` sized to the first slide canvas.
3469
+ * 2. Start a `captureStream(fps)` + `MediaRecorder` on it.
3470
+ * 3. For each slide canvas, draw it repeatedly onto `recordingCanvas` for the
3471
+ * slide's duration at `fps`, feeding frames to the stream.
3472
+ * 4. Stop the recorder and return the accumulated WebM Blob.
3473
+ *
3474
+ * The caller is responsible for rasterising slides to canvases beforehand
3475
+ * (via `ExportService.renderElement`). This keeps the heavy html2canvas-pro
3476
+ * work outside this function and makes progress reporting easy.
3477
+ *
3478
+ * @param canvases - Pre-rendered slide canvases in slide order.
3479
+ * @param opts - Recording options.
3480
+ * @returns A `Promise<Blob>` resolving to a `video/webm` Blob.
3481
+ *
3482
+ * @throws `DOMException('Export cancelled', 'AbortError')` when `signal` fires.
3483
+ * @throws `Error` when no canvases are supplied or when 2D context creation fails.
3484
+ *
3485
+ * @example
3486
+ * // In ExportService:
3487
+ * const canvases = await Promise.all(slides.map(el => this.renderElement(el)));
3488
+ * const blob = await recordWebm(canvases, { slideDurationMs: 3000 });
3489
+ * downloadBlob(blob, 'presentation.webm');
3490
+ */
3491
+ declare function recordWebm(canvases: HTMLCanvasElement[], opts?: RecordWebmOptions): Promise<Blob>;
3492
+
2453
3493
  /**
2454
3494
  * editor-history.ts — Generic undo/redo history stack.
2455
3495
  *
@@ -3536,55 +4576,6 @@ declare class HyperlinkDialogComponent {
3536
4576
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<HyperlinkDialogComponent, "pptx-hyperlink-dialog", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "element": { "alias": "element"; "required": false; "isSignal": true; }; }, { "save": "save"; "close": "close"; }, never, never, true, never>;
3537
4577
  }
3538
4578
 
3539
- /**
3540
- * broadcast-helpers.ts — Pure (no Angular) helpers for the Broadcast dialog.
3541
- *
3542
- * A broadcast is a one-way collaboration session: the presenter drives slide
3543
- * navigation and viewers follow along via a shareable link. These helpers
3544
- * cover the testable, framework-agnostic parts of the Vue `BroadcastDialog.vue`
3545
- * and React `BroadcastDialog.tsx`: room-id generation, form validation, and
3546
- * the viewer-link builder.
3547
- *
3548
- * No `any`; all regexes use the `/u` flag; no `String.prototype.replaceAll`,
3549
- * no regex named-capture-groups (ng-packagr lib-target constraints).
3550
- */
3551
- /** Default y-websocket server URL used when no default is supplied. */
3552
- declare const DEFAULT_BROADCAST_SERVER_URL = "ws://localhost:1234";
3553
- /** Optional seed values for the broadcast start form. */
3554
- interface BroadcastDefaults {
3555
- roomId?: string;
3556
- serverUrl?: string;
3557
- }
3558
- /** The configuration emitted when a broadcast starts. */
3559
- interface BroadcastConfig {
3560
- roomId: string;
3561
- serverUrl: string;
3562
- }
3563
- /** Generate a fresh, broadcast-scoped room id (`broadcast-<suffix>`). */
3564
- declare function generateBroadcastRoomId(): string;
3565
- /**
3566
- * Seed the start form from the (optional) defaults, generating a fresh room id
3567
- * when none is supplied and falling back to the default server URL.
3568
- */
3569
- declare function seedBroadcastFields(defaults?: BroadcastDefaults): BroadcastConfig;
3570
- /** Whether both required fields are non-blank (after trimming). */
3571
- declare function canStartBroadcast(fields: BroadcastConfig): boolean;
3572
- /**
3573
- * Assemble a {@link BroadcastConfig} from the (trimmed) form fields, or `null`
3574
- * when incomplete.
3575
- */
3576
- declare function buildBroadcastConfig(fields: BroadcastConfig): BroadcastConfig | null;
3577
- /**
3578
- * Build the shareable viewer follow-link for a broadcast. Returns just the
3579
- * room id when no `origin`/`pathname` are available (non-browser environments).
3580
- */
3581
- declare function buildBroadcastViewerUrl(roomId: string, serverUrl: string, location?: {
3582
- origin: string;
3583
- pathname: string;
3584
- }): string;
3585
- /** Whether the runtime exposes a usable async clipboard write API. */
3586
- declare function canUseClipboard(nav: Navigator | undefined): boolean;
3587
-
3588
4579
  declare class BroadcastDialogComponent {
3589
4580
  /** Whether the dialog is visible. */
3590
4581
  readonly open: _angular_core.InputSignal<boolean>;
@@ -4187,5 +5178,5 @@ declare function themeStyle(theme: ViewerTheme | undefined): Record<string, stri
4187
5178
  type ClassValue = string | number | false | null | undefined;
4188
5179
  declare function cn(...values: ClassValue[]): string;
4189
5180
 
4190
- export { AccessibilityPanelComponent, AccessibilityService, AnimationPanelComponent, AnimationPlaybackService, BroadcastDialogComponent, CURSOR_PALETTE, ChartRendererComponent, CollaborationCursorsComponent, CollaborationService, CommentsPanelComponent, CommentsService, ConnectorRendererComponent, ConnectorTextOverlayComponent, DEFAULT_BROADCAST_SERVER_URL, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, DEFAULT_FILL_COLOR, DEFAULT_PRINT_SETTINGS, DEFAULT_SLIDE_BACKGROUND, DEFAULT_STROKE_COLOR, DEFAULT_TEXT_COLOR, EMBEDDED_FONTS_STYLE_ID, EditorContextMenuComponent, EditorHistory, EditorStateService, EditorToolbarComponent, ElementRendererComponent, EmbeddedFontsService, EquationRendererComponent, ExportService, FindBarComponent, HANDOUT_OPTIONS, HyperlinkDialogComponent, InkRendererComponent, InspectorPanelComponent, LoadContentService, ModalDialogComponent, Model3DRendererComponent, OleRendererComponent, PowerPointViewerComponent, PresentationOverlayComponent, PresentationTransitionOverlayComponent, PresenterViewComponent, PrintDialogComponent, PrintService, PrintSettingsPanelComponent, PropertiesDialogComponent, RESIZE_HANDLES, SEVERITY_GROUPS, SEVERITY_LABELS, SLIDE_TRANSITION_KEYFRAMES, ShareDialogComponent, SignaturesPanelComponent, SignaturesService, SlideCanvasComponent, SlideSorterOverlayComponent, SlidesPanelComponent, SmartArtRendererComponent, TYPE_LABELS, TableRendererComponent, VIEWER_THEME, ZoomRendererComponent, addCommentToList, advanceStep, applyMove, applyResize, assignUserColor, bringForward, bringToFront, buildBroadcastConfig, buildBroadcastViewerUrl, buildClearHyperlinkPatch, buildClickGroups, buildCollaborationConfig, buildCssGradientFromShapeStyle, buildEmbeddedFontStyles, buildFontFaceRule, buildHyperlinkPatch, buildPatternFillCss, buildPrintDocument, buildPropertiesPatch, buildShareUrl, bulletIndentPx, canStartBroadcast, canStartShare, canUseClipboard, clampCursorPosition, clampNotesFontSize, clampStep, cn, collectAccessibilityIssues, collectElementText, collectSlideText, computeHandoutLayout, computePageCount, computeSlideIndices, computeTimerProgress, convertOmmlToMathMl, countAccessibilityIssues, defaultCssVars, defaultRadius, defaultThemeColors, deleteElementsByIds, derivePresenceList, duplicateElementById, durationOf, estimatePageCount, fontMimeForFormat, formatAutoNumber, formatCursorLabel, formatElapsed, formatPropertyDate, formatTime, generateBroadcastRoomId, generateCommentId, getContainerStyle, getImageSrc, getPatternSvg, getResolvedShapeClipPath, getResolvedShapeClipPathFor, getShapeFillStrokeStyle, getSlideBackgroundStyle, getSlideTransitionAnimations, getTextBlockStyle, groupIssuesBySeverity, hasExistingLink, headerLabel, isInjectableUrl, isPpactionUrl, isSigned, isUrlSafe, isValidRoomId, issueTrackKey, issueTypeLabel, moveElementBy, normalizeFontFormat, normalizeSlidesPerPage, ommlToMathml, overallStatus, pendingElementStyles, presenceToCursors, provideViewerTheme, removeCommentFromList, renderToCanvas, resizeElement, resolveFontVariant, resolveHyperlinkHref, resolveParagraphBullet, resolvePresenterNotes, resolveTransitionDuration, revealedElementStyles, routeOrthogonalConnector, sanitizeColor, sanitizeSlideIndex, sanitizeUserName, searchSlides, seedBroadcastFields, seedHyperlinkDraft, seedPropertiesDraft, seedShareFields, sendBackward, sendToBack, setElementPosition, signatureCountLabel, signatureKey, signatureTimestamp, signerName, statusKind, statusLabel, themeStyle, themeToCssVars, toggleCommentResolvedInList, updateElementById, validatePrintSettings, validateRoomId, waypointsToPathD, worstStatus };
4191
- export type { AccessibilityIssueGroup, AnimationClickGroup, Box, BroadcastConfig, BroadcastDefaults, CSSProperties, CanvasSize, ClassValue, CollaborationConfig, CollaborationRole, Rect as ConnectorObstacle, Point as ConnectorPoint, ConnectorRouting, DocumentProperties, EmbeddedFontStyles, HandoutSlidesPerPage, HyperlinkDraft, NotesSegmentViewModel, ObjectUrlFactory, OverallSignatureStatus, PresenterNotes, PrintColorMode, PrintDocumentOptions, PrintOrientation, PrintSettings, PrintSlideRange, PrintWhat, PropertiesDraft, RemoteCursor, RemotePresence, ResizeHandle, ResolvedFontVariant, ShareDefaults, ShareFormFields, SignatureStatusKind, SlideTransitionAnimations, StyleMap, TimerProgress, ViewerTheme, ViewerThemeColors };
5181
+ export { AccessibilityPanelComponent, AccessibilityService, AnimationPanelComponent, AnimationPlaybackService, BroadcastDialogComponent, CURSOR_PALETTE, ChartDataEditorComponent, ChartRendererComponent, CollaborationCursorsComponent, CollaborationService, CommentsPanelComponent, CommentsService, ConnectorRendererComponent, ConnectorTextOverlayComponent, DEFAULT_BROADCAST_SERVER_URL, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, DEFAULT_FILL_COLOR, DEFAULT_PRINT_SETTINGS, DEFAULT_SLIDE_BACKGROUND, DEFAULT_STROKE_COLOR, DEFAULT_TEXT_COLOR, EMBEDDED_FONTS_STYLE_ID, EditorContextMenuComponent, EditorHistory, EditorStateService, EditorToolbarComponent, EffectsPanelComponent, ElementRendererComponent, EmbeddedFontsService, EquationRendererComponent, ExportService, FindBarComponent, FindReplaceBarComponent, GradientPickerComponent, HANDOUT_OPTIONS, HyperlinkDialogComponent, InkRendererComponent, InspectorPanelComponent, LoadContentService, ModalDialogComponent, Model3DRendererComponent, OleRendererComponent, PowerPointViewerComponent, PresentationOverlayComponent, PresentationTransitionOverlayComponent, PresenterViewComponent, PrintDialogComponent, PrintService, PrintSettingsPanelComponent, PropertiesDialogComponent, RESIZE_HANDLES, SEVERITY_GROUPS, SEVERITY_LABELS, SLIDE_TRANSITION_KEYFRAMES, ShareDialogComponent, SignaturesPanelComponent, SignaturesService, SlideCanvasComponent, SlideSorterOverlayComponent, SlidesPanelComponent, SmartArtRendererComponent, TYPE_LABELS, TableDataEditorComponent, TableRendererComponent, TextAdvancedPanelComponent, VIEWER_THEME, WEBM_MIME_CANDIDATES, ZoomRendererComponent, addCommentToList, advanceStep, applyFindReplacements, applyMove, applyResize, assignUserColor, bringForward, bringToFront, buildBroadcastConfig, buildBroadcastViewerUrl, buildClearHyperlinkPatch, buildClickGroups, buildCollaborationConfig, buildCssGradientFromShapeStyle, buildDuotoneFilter, buildDuotoneFilterId, buildEmbeddedFontStyles, buildFontFaceRule, buildHyperlinkPatch, buildPatternFillCss, buildPrintDocument, buildPropertiesPatch, buildShareUrl, bulletIndentPx, canStartBroadcast, canStartShare, canUseClipboard, clampCursorPosition, clampGifDimensions, clampNotesFontSize, clampStep, cn, collectAccessibilityIssues, collectElementText, collectSlideText, computeHandoutLayout, computePageCount, computeSlideIndices, computeTimerProgress, convertOmmlToMathMl, countAccessibilityIssues, defaultCssVars, defaultRadius, defaultThemeColors, deleteElementsByIds, derivePresenceList, duplicateElementById, durationOf, encodeGif, estimatePageCount, findInSlides, fontMimeForFormat, formatAutoNumber, formatCursorLabel, formatElapsed, formatPropertyDate, formatTime, fpsToFrameIntervalMs, generateBroadcastRoomId, generateCommentId, getContainerStyle, getDuotoneFilterDef, getImageSrc, getPatternSvg, getResolvedShapeClipPath, getResolvedShapeClipPathFor, getShapeFillStrokeStyle, getSlideBackgroundStyle, getSlideTransitionAnimations, getTextBlockStyle, groupIssuesBySeverity, hasExistingLink, headerLabel, isInjectableUrl, isPpactionUrl, isSigned, isUrlSafe, isValidRoomId, issueTrackKey, issueTypeLabel, moveElementBy, msToFrameDelayCs, normalizeFontFormat, normalizeSlidesPerPage, ommlToMathml, overallStatus, pendingElementStyles, pickSupportedMimeType, planGifFrames, planVideoSegments, presenceToCursors, provideViewerTheme, recordWebm, removeCommentFromList, renderToCanvas, replaceInSlides, replaceMatch, resizeElement, resolveFontVariant, resolveHyperlinkHref, resolveParagraphBullet, resolvePresenterNotes, resolveTransitionDuration, revealedElementStyles, routeOrthogonalConnector, sanitizeColor, sanitizeSlideIndex, sanitizeUserName, searchSlides, seedBroadcastFields, seedHyperlinkDraft, seedPropertiesDraft, seedShareFields, segmentFrameCount, sendBackward, sendToBack, setElementPosition, signatureCountLabel, signatureKey, signatureTimestamp, signerName, statusKind, statusLabel, themeStyle, themeToCssVars, toggleCommentResolvedInList, updateElementById, validatePrintSettings, validateRoomId, waypointsToPathD, worstStatus };
5182
+ export type { AccessibilityIssueGroup, AnimationClickGroup, Box, BroadcastConfig, BroadcastDefaults, CSSProperties, CanvasSize, ClassValue, CollaborationConfig, CollaborationRole, Rect as ConnectorObstacle, Point as ConnectorPoint, ConnectorRouting, DocumentProperties, DuotoneFilterDef, EmbeddedFontStyles, FindOptions, FindResult, GifFrame, GifFramePlan, GifPlanOptions, HandoutSlidesPerPage, HyperlinkDraft, NotesSegmentViewModel, ObjectUrlFactory, OverallSignatureStatus, PresenterNotes, PrintColorMode, PrintDocumentOptions, PrintOrientation, PrintSettings, PrintSlideRange, PrintWhat, PropertiesDraft, RecordWebmOptions, RemoteCursor, RemotePresence, ReplaceResult, ResizeHandle, ResolvedFontVariant, ShareDefaults, ShareFormFields, SignatureStatusKind, SlideTransitionAnimations, StyleMap, TimerProgress, VideoPlanOptions, VideoSegmentPlan, ViewerTheme, ViewerThemeColors };