pptx-angular-viewer 1.1.22 → 1.1.23

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.
@@ -12554,6 +12554,98 @@ function replaceInSlides(slides, query, replacement, opts = {}) {
12554
12554
  return applyFindReplacements(slides, results, replacement);
12555
12555
  }
12556
12556
 
12557
+ /** Copy the paintable shape + text style off an element. */
12558
+ function copyFormatFromElement(element) {
12559
+ const result = {};
12560
+ if (hasShapeProperties(element) && element.shapeStyle) {
12561
+ const s = element.shapeStyle;
12562
+ result.shapeStyle = {
12563
+ fillColor: s.fillColor,
12564
+ fillMode: s.fillMode,
12565
+ fillGradient: s.fillGradient,
12566
+ fillGradientStops: s.fillGradientStops ? [...s.fillGradientStops] : undefined,
12567
+ fillGradientAngle: s.fillGradientAngle,
12568
+ fillGradientType: s.fillGradientType,
12569
+ fillOpacity: s.fillOpacity,
12570
+ fillPatternPreset: s.fillPatternPreset,
12571
+ fillPatternBackgroundColor: s.fillPatternBackgroundColor,
12572
+ strokeColor: s.strokeColor,
12573
+ strokeWidth: s.strokeWidth,
12574
+ strokeOpacity: s.strokeOpacity,
12575
+ strokeDash: s.strokeDash,
12576
+ lineJoin: s.lineJoin,
12577
+ lineCap: s.lineCap,
12578
+ shadowColor: s.shadowColor,
12579
+ shadowBlur: s.shadowBlur,
12580
+ shadowOffsetX: s.shadowOffsetX,
12581
+ shadowOffsetY: s.shadowOffsetY,
12582
+ shadowOpacity: s.shadowOpacity,
12583
+ glowColor: s.glowColor,
12584
+ glowRadius: s.glowRadius,
12585
+ glowOpacity: s.glowOpacity,
12586
+ softEdgeRadius: s.softEdgeRadius,
12587
+ };
12588
+ }
12589
+ if (hasTextProperties(element) && element.textStyle) {
12590
+ const t = element.textStyle;
12591
+ result.textStyle = {
12592
+ fontFamily: t.fontFamily,
12593
+ fontSize: t.fontSize,
12594
+ bold: t.bold,
12595
+ italic: t.italic,
12596
+ underline: t.underline,
12597
+ underlineStyle: t.underlineStyle,
12598
+ strikethrough: t.strikethrough,
12599
+ color: t.color,
12600
+ align: t.align,
12601
+ lineSpacing: t.lineSpacing,
12602
+ paragraphSpacingBefore: t.paragraphSpacingBefore,
12603
+ paragraphSpacingAfter: t.paragraphSpacingAfter,
12604
+ textCaps: t.textCaps,
12605
+ };
12606
+ }
12607
+ return result;
12608
+ }
12609
+ function definedEntries(obj) {
12610
+ const out = {};
12611
+ for (const key in obj) {
12612
+ if (obj[key] !== undefined) {
12613
+ out[key] = obj[key];
12614
+ }
12615
+ }
12616
+ return out;
12617
+ }
12618
+ /** Merge a copied format onto a target element (only defined fields win). */
12619
+ function applyFormatToElement(element, format) {
12620
+ let updated = { ...element };
12621
+ if (format.shapeStyle && hasShapeProperties(updated)) {
12622
+ updated = {
12623
+ ...updated,
12624
+ shapeStyle: {
12625
+ ...updated.shapeStyle,
12626
+ ...definedEntries(format.shapeStyle),
12627
+ },
12628
+ };
12629
+ }
12630
+ if (format.textStyle && hasTextProperties(updated)) {
12631
+ updated = {
12632
+ ...updated,
12633
+ textStyle: {
12634
+ ...updated.textStyle,
12635
+ ...definedEntries(format.textStyle),
12636
+ },
12637
+ };
12638
+ }
12639
+ return updated;
12640
+ }
12641
+ /** True when an element exposes formatting fields the painter can copy. */
12642
+ function hasCopyableFormat(element) {
12643
+ if (!element) {
12644
+ return false;
12645
+ }
12646
+ return hasShapeProperties(element) || hasTextProperties(element);
12647
+ }
12648
+
12557
12649
  /**
12558
12650
  * Hyperlink resolution + URL safety for the viewer.
12559
12651
  *
@@ -18643,6 +18735,9 @@ class MobileBottomBarComponent {
18643
18735
  /** Whether the slides thumbnail sheet is currently open. */
18644
18736
  slidesOpen = input(false, /* @ts-ignore */
18645
18737
  ...(ngDevMode ? [{ debugName: "slidesOpen" }] : /* istanbul ignore next */ []));
18738
+ /** Whether the speaker-notes sheet is currently open (highlights the button). */
18739
+ notesOpen = input(false, /* @ts-ignore */
18740
+ ...(ngDevMode ? [{ debugName: "notesOpen" }] : /* istanbul ignore next */ []));
18646
18741
  // ── Outputs ───────────────────────────────────────────────────────────────
18647
18742
  /** User tapped the previous-slide button. */
18648
18743
  prev = output();
@@ -18654,6 +18749,8 @@ class MobileBottomBarComponent {
18654
18749
  openSorter = output();
18655
18750
  /** User tapped the Find button. */
18656
18751
  openFind = output();
18752
+ /** User tapped the Notes button. */
18753
+ notes = output();
18657
18754
  /** User tapped the Slides thumbnail strip button. */
18658
18755
  openSlides = output();
18659
18756
  /** User tapped the menu (⋯) button. */
@@ -18696,6 +18793,15 @@ class MobileBottomBarComponent {
18696
18793
  disabled: !this.canPresent() || count === 0,
18697
18794
  emit: () => this.present.emit(),
18698
18795
  },
18796
+ {
18797
+ key: 'notes',
18798
+ label: 'Notes',
18799
+ // Note / document-text icon
18800
+ svgPath: 'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z M14 2v6h6 M8 13h8 M8 17h5',
18801
+ disabled: count === 0,
18802
+ active: this.notesOpen(),
18803
+ emit: () => this.notes.emit(),
18804
+ },
18699
18805
  {
18700
18806
  key: 'menu',
18701
18807
  label: 'More',
@@ -18717,7 +18823,7 @@ class MobileBottomBarComponent {
18717
18823
  }, /* @ts-ignore */
18718
18824
  ...(ngDevMode ? [{ debugName: "actions" }] : /* istanbul ignore next */ []));
18719
18825
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: MobileBottomBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
18720
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: MobileBottomBarComponent, isStandalone: true, selector: "pptx-mobile-bottom-bar", inputs: { activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null }, slideCount: { classPropertyName: "slideCount", publicName: "slideCount", isSignal: true, isRequired: false, transformFunction: null }, canPresent: { classPropertyName: "canPresent", publicName: "canPresent", isSignal: true, isRequired: false, transformFunction: null }, menuOpen: { classPropertyName: "menuOpen", publicName: "menuOpen", isSignal: true, isRequired: false, transformFunction: null }, slidesOpen: { classPropertyName: "slidesOpen", publicName: "slidesOpen", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { prev: "prev", next: "next", present: "present", openSorter: "openSorter", openFind: "openFind", openSlides: "openSlides", toggleMenu: "toggleMenu" }, ngImport: i0, template: `
18826
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: MobileBottomBarComponent, isStandalone: true, selector: "pptx-mobile-bottom-bar", inputs: { activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null }, slideCount: { classPropertyName: "slideCount", publicName: "slideCount", isSignal: true, isRequired: false, transformFunction: null }, canPresent: { classPropertyName: "canPresent", publicName: "canPresent", isSignal: true, isRequired: false, transformFunction: null }, menuOpen: { classPropertyName: "menuOpen", publicName: "menuOpen", isSignal: true, isRequired: false, transformFunction: null }, slidesOpen: { classPropertyName: "slidesOpen", publicName: "slidesOpen", isSignal: true, isRequired: false, transformFunction: null }, notesOpen: { classPropertyName: "notesOpen", publicName: "notesOpen", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { prev: "prev", next: "next", present: "present", openSorter: "openSorter", openFind: "openFind", notes: "notes", openSlides: "openSlides", toggleMenu: "toggleMenu" }, ngImport: i0, template: `
18721
18827
  <nav class="pptx-ng-mbar" aria-label="Mobile navigation">
18722
18828
  @for (action of actions(); track action.key) {
18723
18829
  <button
@@ -18796,7 +18902,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
18796
18902
  }
18797
18903
  </nav>
18798
18904
  `, styles: [":host{display:block}.pptx-ng-mbar{display:flex;align-items:stretch;justify-content:space-around;background:#1a1a1aeb;border-top:1px solid rgba(255,255,255,.1);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);padding-bottom:max(env(safe-area-inset-bottom,0px),0px)}.pptx-ng-mbar-btn{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.125rem;flex:1;min-height:56px;padding:.375rem .25rem;border:none;background:transparent;color:#ffffff8c;font-size:.625rem;font-weight:500;cursor:pointer;touch-action:manipulation;transition:color .12s,transform .08s;-webkit-tap-highlight-color:transparent}.pptx-ng-mbar-btn:active:not([disabled]){transform:scale(.92)}.pptx-ng-mbar-btn.is-active{color:#3b82f6}.pptx-ng-mbar-btn:hover:not([disabled]):not(.is-active){color:#e5e5e5}.pptx-ng-mbar-btn[disabled]{opacity:.35;cursor:not-allowed}.pptx-ng-mbar-icon{width:1.25rem;height:1.25rem;flex-shrink:0}.pptx-ng-mbar-label{line-height:1;white-space:nowrap}.pptx-ng-mbar-badge{position:absolute;top:.25rem;right:calc(50% - 1.25rem);display:flex;align-items:center;justify-content:center;min-width:1rem;height:1rem;padding:0 .25rem;border-radius:9999px;background:#ef4444;color:#fff;font-size:.5625rem;font-weight:600;line-height:1}.pptx-ng-mbar-indicator{position:absolute;top:0;left:50%;transform:translate(-50%);width:2rem;height:.1875rem;border-radius:9999px;background:#3b82f6}\n"] }]
18799
- }], propDecorators: { activeIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIndex", required: false }] }], slideCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideCount", required: false }] }], canPresent: [{ type: i0.Input, args: [{ isSignal: true, alias: "canPresent", required: false }] }], menuOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuOpen", required: false }] }], slidesOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "slidesOpen", required: false }] }], prev: [{ type: i0.Output, args: ["prev"] }], next: [{ type: i0.Output, args: ["next"] }], present: [{ type: i0.Output, args: ["present"] }], openSorter: [{ type: i0.Output, args: ["openSorter"] }], openFind: [{ type: i0.Output, args: ["openFind"] }], openSlides: [{ type: i0.Output, args: ["openSlides"] }], toggleMenu: [{ type: i0.Output, args: ["toggleMenu"] }] } });
18905
+ }], propDecorators: { activeIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIndex", required: false }] }], slideCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideCount", required: false }] }], canPresent: [{ type: i0.Input, args: [{ isSignal: true, alias: "canPresent", required: false }] }], menuOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuOpen", required: false }] }], slidesOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "slidesOpen", required: false }] }], notesOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "notesOpen", required: false }] }], prev: [{ type: i0.Output, args: ["prev"] }], next: [{ type: i0.Output, args: ["next"] }], present: [{ type: i0.Output, args: ["present"] }], openSorter: [{ type: i0.Output, args: ["openSorter"] }], openFind: [{ type: i0.Output, args: ["openFind"] }], notes: [{ type: i0.Output, args: ["notes"] }], openSlides: [{ type: i0.Output, args: ["openSlides"] }], toggleMenu: [{ type: i0.Output, args: ["toggleMenu"] }] } });
18800
18906
 
18801
18907
  /**
18802
18908
  * mobile-sheet.component.ts — Reusable slide-up bottom sheet for mobile.
@@ -23631,6 +23737,7 @@ class ConnectorRendererComponent {
23631
23737
  class="pptx-ng-element pptx-ng-connector"
23632
23738
  [style]="geo().wrapperStyle"
23633
23739
  [attr.data-element-id]="element().id"
23740
+ data-pptx-element="true"
23634
23741
  >
23635
23742
  <svg
23636
23743
  [attr.width]="geo().svgW"
@@ -23725,6 +23832,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
23725
23832
  class="pptx-ng-element pptx-ng-connector"
23726
23833
  [style]="geo().wrapperStyle"
23727
23834
  [attr.data-element-id]="element().id"
23835
+ data-pptx-element="true"
23728
23836
  >
23729
23837
  <svg
23730
23838
  [attr.width]="geo().svgW"
@@ -29626,6 +29734,7 @@ class ElementRendererComponent {
29626
29734
  class="pptx-ng-element pptx-ng-smartart"
29627
29735
  [ngStyle]="containerStyle()"
29628
29736
  [attr.data-element-id]="element().id"
29737
+ data-pptx-element="true"
29629
29738
  >
29630
29739
  <pptx-smart-art-renderer [element]="element()" [zIndex]="zIndex()" />
29631
29740
  </div>
@@ -29635,6 +29744,7 @@ class ElementRendererComponent {
29635
29744
  class="pptx-ng-element pptx-ng-ole"
29636
29745
  [ngStyle]="containerStyle()"
29637
29746
  [attr.data-element-id]="element().id"
29747
+ data-pptx-element="true"
29638
29748
  >
29639
29749
  <pptx-ole-renderer [element]="element()" [zIndex]="zIndex()" />
29640
29750
  </div>
@@ -29644,6 +29754,7 @@ class ElementRendererComponent {
29644
29754
  class="pptx-ng-element pptx-ng-chart"
29645
29755
  [ngStyle]="containerStyle()"
29646
29756
  [attr.data-element-id]="element().id"
29757
+ data-pptx-element="true"
29647
29758
  >
29648
29759
  <pptx-chart-renderer [element]="element()" />
29649
29760
  </div>
@@ -29653,6 +29764,7 @@ class ElementRendererComponent {
29653
29764
  class="pptx-ng-element pptx-ng-table"
29654
29765
  [ngStyle]="containerStyle()"
29655
29766
  [attr.data-element-id]="element().id"
29767
+ data-pptx-element="true"
29656
29768
  >
29657
29769
  <pptx-table-renderer [element]="element()" />
29658
29770
  </div>
@@ -29662,6 +29774,7 @@ class ElementRendererComponent {
29662
29774
  class="pptx-ng-element pptx-ng-group"
29663
29775
  [ngStyle]="containerStyle()"
29664
29776
  [attr.data-element-id]="element().id"
29777
+ data-pptx-element="true"
29665
29778
  >
29666
29779
  @for (child of children(); track child.id) {
29667
29780
  <pptx-element-renderer
@@ -29677,6 +29790,7 @@ class ElementRendererComponent {
29677
29790
  class="pptx-ng-element pptx-ng-image"
29678
29791
  [ngStyle]="containerStyle()"
29679
29792
  [attr.data-element-id]="element().id"
29793
+ data-pptx-element="true"
29680
29794
  >
29681
29795
  @if (imageSrc()) {
29682
29796
  <img [src]="imageSrc()" alt="" class="pptx-ng-img" />
@@ -29688,6 +29802,7 @@ class ElementRendererComponent {
29688
29802
  class="pptx-ng-element pptx-ng-media"
29689
29803
  [ngStyle]="containerStyle()"
29690
29804
  [attr.data-element-id]="element().id"
29805
+ data-pptx-element="true"
29691
29806
  >
29692
29807
  @if (imageSrc()) {
29693
29808
  <img [src]="imageSrc()" alt="" class="pptx-ng-img" />
@@ -29701,6 +29816,7 @@ class ElementRendererComponent {
29701
29816
  class="pptx-ng-element pptx-ng-shape"
29702
29817
  [ngStyle]="shapeContainerStyle()"
29703
29818
  [attr.data-element-id]="element().id"
29819
+ data-pptx-element="true"
29704
29820
  >
29705
29821
  @if (pathWarp(); as warp) {
29706
29822
  <svg
@@ -29785,6 +29901,7 @@ class ElementRendererComponent {
29785
29901
  class="pptx-ng-element pptx-ng-unsupported"
29786
29902
  [ngStyle]="containerStyle()"
29787
29903
  [attr.data-element-id]="element().id"
29904
+ data-pptx-element="true"
29788
29905
  >
29789
29906
  <div class="pptx-ng-placeholder">{{ placeholderLabel() }}</div>
29790
29907
  </div>
@@ -29880,6 +29997,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
29880
29997
  class="pptx-ng-element pptx-ng-smartart"
29881
29998
  [ngStyle]="containerStyle()"
29882
29999
  [attr.data-element-id]="element().id"
30000
+ data-pptx-element="true"
29883
30001
  >
29884
30002
  <pptx-smart-art-renderer [element]="element()" [zIndex]="zIndex()" />
29885
30003
  </div>
@@ -29889,6 +30007,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
29889
30007
  class="pptx-ng-element pptx-ng-ole"
29890
30008
  [ngStyle]="containerStyle()"
29891
30009
  [attr.data-element-id]="element().id"
30010
+ data-pptx-element="true"
29892
30011
  >
29893
30012
  <pptx-ole-renderer [element]="element()" [zIndex]="zIndex()" />
29894
30013
  </div>
@@ -29898,6 +30017,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
29898
30017
  class="pptx-ng-element pptx-ng-chart"
29899
30018
  [ngStyle]="containerStyle()"
29900
30019
  [attr.data-element-id]="element().id"
30020
+ data-pptx-element="true"
29901
30021
  >
29902
30022
  <pptx-chart-renderer [element]="element()" />
29903
30023
  </div>
@@ -29907,6 +30027,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
29907
30027
  class="pptx-ng-element pptx-ng-table"
29908
30028
  [ngStyle]="containerStyle()"
29909
30029
  [attr.data-element-id]="element().id"
30030
+ data-pptx-element="true"
29910
30031
  >
29911
30032
  <pptx-table-renderer [element]="element()" />
29912
30033
  </div>
@@ -29916,6 +30037,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
29916
30037
  class="pptx-ng-element pptx-ng-group"
29917
30038
  [ngStyle]="containerStyle()"
29918
30039
  [attr.data-element-id]="element().id"
30040
+ data-pptx-element="true"
29919
30041
  >
29920
30042
  @for (child of children(); track child.id) {
29921
30043
  <pptx-element-renderer
@@ -29931,6 +30053,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
29931
30053
  class="pptx-ng-element pptx-ng-image"
29932
30054
  [ngStyle]="containerStyle()"
29933
30055
  [attr.data-element-id]="element().id"
30056
+ data-pptx-element="true"
29934
30057
  >
29935
30058
  @if (imageSrc()) {
29936
30059
  <img [src]="imageSrc()" alt="" class="pptx-ng-img" />
@@ -29942,6 +30065,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
29942
30065
  class="pptx-ng-element pptx-ng-media"
29943
30066
  [ngStyle]="containerStyle()"
29944
30067
  [attr.data-element-id]="element().id"
30068
+ data-pptx-element="true"
29945
30069
  >
29946
30070
  @if (imageSrc()) {
29947
30071
  <img [src]="imageSrc()" alt="" class="pptx-ng-img" />
@@ -29955,6 +30079,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
29955
30079
  class="pptx-ng-element pptx-ng-shape"
29956
30080
  [ngStyle]="shapeContainerStyle()"
29957
30081
  [attr.data-element-id]="element().id"
30082
+ data-pptx-element="true"
29958
30083
  >
29959
30084
  @if (pathWarp(); as warp) {
29960
30085
  <svg
@@ -30039,6 +30164,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
30039
30164
  class="pptx-ng-element pptx-ng-unsupported"
30040
30165
  [ngStyle]="containerStyle()"
30041
30166
  [attr.data-element-id]="element().id"
30167
+ data-pptx-element="true"
30042
30168
  >
30043
30169
  <div class="pptx-ng-placeholder">{{ placeholderLabel() }}</div>
30044
30170
  </div>
@@ -30292,6 +30418,15 @@ class SlideCanvasComponent {
30292
30418
  /** When true, elements are selectable and drag/resize handles are shown. */
30293
30419
  editable = input(false, /* @ts-ignore */
30294
30420
  ...(ngDevMode ? [{ debugName: "editable" }] : /* istanbul ignore next */ []));
30421
+ /**
30422
+ * When true (default), the stage auto-fits the slide to the scroll viewport so
30423
+ * the user's `zoom` is relative to "fit". Thumbnail consumers (slides panel,
30424
+ * slide sorter) pass an explicit fit-to-width `zoom` and set this `false`, so
30425
+ * their `zoom` is the sole scale — otherwise the two scales compound and the
30426
+ * thumbnail shrinks to near-invisible.
30427
+ */
30428
+ autoFit = input(true, /* @ts-ignore */
30429
+ ...(ngDevMode ? [{ debugName: "autoFit" }] : /* istanbul ignore next */ []));
30295
30430
  /** Ids of currently-selected elements (drawn with a selection outline). */
30296
30431
  selectedIds = input([], /* @ts-ignore */
30297
30432
  ...(ngDevMode ? [{ debugName: "selectedIds" }] : /* istanbul ignore next */ []));
@@ -30399,6 +30534,12 @@ class SlideCanvasComponent {
30399
30534
  * reserving the 1rem gutter + drop shadow. Sets fitScale to 1 when unmeasured.
30400
30535
  */
30401
30536
  recomputeFit() {
30537
+ // Thumbnail consumers manage their own scale via `zoom` — keep fit at 1 so
30538
+ // the two scales don't compound.
30539
+ if (!this.autoFit()) {
30540
+ this.fitScale.set(1);
30541
+ return;
30542
+ }
30402
30543
  const el = this.viewportRef()?.nativeElement;
30403
30544
  const size = this.canvasSize();
30404
30545
  if (!el || !size.width || !size.height) {
@@ -30778,8 +30919,8 @@ class SlideCanvasComponent {
30778
30919
  }, /* @ts-ignore */
30779
30920
  ...(ngDevMode ? [{ debugName: "stageStyle" }] : /* istanbul ignore next */ []));
30780
30921
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SlideCanvasComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
30781
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: SlideCanvasComponent, isStandalone: true, selector: "pptx-slide-canvas", inputs: { slide: { classPropertyName: "slide", publicName: "slide", isSignal: true, isRequired: false, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, zoom: { classPropertyName: "zoom", publicName: "zoom", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, selectedIds: { classPropertyName: "selectedIds", publicName: "selectedIds", isSignal: true, isRequired: false, transformFunction: null }, editingId: { classPropertyName: "editingId", publicName: "editingId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { elementSelect: "elementSelect", backgroundClick: "backgroundClick", transformStart: "transformStart", transformUpdate: "transformUpdate", contextMenu: "contextMenu", textEditStart: "textEditStart", textCommit: "textCommit", textCancel: "textCancel", rotateUpdate: "rotateUpdate", marqueeSelect: "marqueeSelect" }, host: { listeners: { "document:pointermove": "onPointerMove($event)", "document:pointerup": "onPointerUp()" } }, viewQueries: [{ propertyName: "textEditor", first: true, predicate: ["textEditor"], descendants: true, isSignal: true }, { propertyName: "stageRef", first: true, predicate: ["stage"], descendants: true, isSignal: true }, { propertyName: "viewportRef", first: true, predicate: ["viewport"], descendants: true, isSignal: true }], ngImport: i0, template: `
30782
- <div #viewport class="pptx-ng-canvas-viewport">
30922
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: SlideCanvasComponent, isStandalone: true, selector: "pptx-slide-canvas", inputs: { slide: { classPropertyName: "slide", publicName: "slide", isSignal: true, isRequired: false, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, zoom: { classPropertyName: "zoom", publicName: "zoom", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, autoFit: { classPropertyName: "autoFit", publicName: "autoFit", isSignal: true, isRequired: false, transformFunction: null }, selectedIds: { classPropertyName: "selectedIds", publicName: "selectedIds", isSignal: true, isRequired: false, transformFunction: null }, editingId: { classPropertyName: "editingId", publicName: "editingId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { elementSelect: "elementSelect", backgroundClick: "backgroundClick", transformStart: "transformStart", transformUpdate: "transformUpdate", contextMenu: "contextMenu", textEditStart: "textEditStart", textCommit: "textCommit", textCancel: "textCancel", rotateUpdate: "rotateUpdate", marqueeSelect: "marqueeSelect" }, host: { listeners: { "document:pointermove": "onPointerMove($event)", "document:pointerup": "onPointerUp()" } }, viewQueries: [{ propertyName: "textEditor", first: true, predicate: ["textEditor"], descendants: true, isSignal: true }, { propertyName: "stageRef", first: true, predicate: ["stage"], descendants: true, isSignal: true }, { propertyName: "viewportRef", first: true, predicate: ["viewport"], descendants: true, isSignal: true }], ngImport: i0, template: `
30923
+ <div #viewport class="pptx-ng-canvas-viewport" data-pptx-viewport>
30783
30924
  <div class="pptx-ng-canvas-wrapper" [ngStyle]="wrapperStyle()">
30784
30925
  <div
30785
30926
  #stage
@@ -30843,6 +30984,8 @@ class SlideCanvasComponent {
30843
30984
  @if (rotateHandle(); as rh) {
30844
30985
  <div
30845
30986
  class="pptx-ng-rotate-handle"
30987
+ role="button"
30988
+ aria-label="Adjust shape"
30846
30989
  [style.left.px]="rh.left"
30847
30990
  [style.top.px]="rh.top"
30848
30991
  [style.width.px]="rh.size"
@@ -30853,6 +30996,7 @@ class SlideCanvasComponent {
30853
30996
  @if (editingBox(); as eb) {
30854
30997
  <textarea
30855
30998
  #textEditor
30999
+ data-inline-editor
30856
31000
  class="pptx-ng-text-editor"
30857
31001
  [style.left.px]="eb.x"
30858
31002
  [style.top.px]="eb.y"
@@ -30871,7 +31015,7 @@ class SlideCanvasComponent {
30871
31015
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SlideCanvasComponent, decorators: [{
30872
31016
  type: Component,
30873
31017
  args: [{ selector: 'pptx-slide-canvas', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgStyle, ElementRendererComponent], template: `
30874
- <div #viewport class="pptx-ng-canvas-viewport">
31018
+ <div #viewport class="pptx-ng-canvas-viewport" data-pptx-viewport>
30875
31019
  <div class="pptx-ng-canvas-wrapper" [ngStyle]="wrapperStyle()">
30876
31020
  <div
30877
31021
  #stage
@@ -30935,6 +31079,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
30935
31079
  @if (rotateHandle(); as rh) {
30936
31080
  <div
30937
31081
  class="pptx-ng-rotate-handle"
31082
+ role="button"
31083
+ aria-label="Adjust shape"
30938
31084
  [style.left.px]="rh.left"
30939
31085
  [style.top.px]="rh.top"
30940
31086
  [style.width.px]="rh.size"
@@ -30945,6 +31091,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
30945
31091
  @if (editingBox(); as eb) {
30946
31092
  <textarea
30947
31093
  #textEditor
31094
+ data-inline-editor
30948
31095
  class="pptx-ng-text-editor"
30949
31096
  [style.left.px]="eb.x"
30950
31097
  [style.top.px]="eb.y"
@@ -30959,7 +31106,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
30959
31106
  </div>
30960
31107
  </div>
30961
31108
  `, styles: [".pptx-ng-canvas-stage.is-editable{touch-action:none}\n"] }]
30962
- }], ctorParameters: () => [], propDecorators: { slide: [{ type: i0.Input, args: [{ isSignal: true, alias: "slide", required: false }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], zoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoom", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], selectedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIds", required: false }] }], editingId: [{ type: i0.Input, args: [{ isSignal: true, alias: "editingId", required: false }] }], elementSelect: [{ type: i0.Output, args: ["elementSelect"] }], backgroundClick: [{ type: i0.Output, args: ["backgroundClick"] }], transformStart: [{ type: i0.Output, args: ["transformStart"] }], transformUpdate: [{ type: i0.Output, args: ["transformUpdate"] }], contextMenu: [{ type: i0.Output, args: ["contextMenu"] }], textEditStart: [{ type: i0.Output, args: ["textEditStart"] }], textCommit: [{ type: i0.Output, args: ["textCommit"] }], textCancel: [{ type: i0.Output, args: ["textCancel"] }], rotateUpdate: [{ type: i0.Output, args: ["rotateUpdate"] }], marqueeSelect: [{ type: i0.Output, args: ["marqueeSelect"] }], textEditor: [{ type: i0.ViewChild, args: ['textEditor', { isSignal: true }] }], stageRef: [{ type: i0.ViewChild, args: ['stage', { isSignal: true }] }], viewportRef: [{ type: i0.ViewChild, args: ['viewport', { isSignal: true }] }], onPointerMove: [{
31109
+ }], ctorParameters: () => [], propDecorators: { slide: [{ type: i0.Input, args: [{ isSignal: true, alias: "slide", required: false }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], zoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoom", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], autoFit: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFit", required: false }] }], selectedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIds", required: false }] }], editingId: [{ type: i0.Input, args: [{ isSignal: true, alias: "editingId", required: false }] }], elementSelect: [{ type: i0.Output, args: ["elementSelect"] }], backgroundClick: [{ type: i0.Output, args: ["backgroundClick"] }], transformStart: [{ type: i0.Output, args: ["transformStart"] }], transformUpdate: [{ type: i0.Output, args: ["transformUpdate"] }], contextMenu: [{ type: i0.Output, args: ["contextMenu"] }], textEditStart: [{ type: i0.Output, args: ["textEditStart"] }], textCommit: [{ type: i0.Output, args: ["textCommit"] }], textCancel: [{ type: i0.Output, args: ["textCancel"] }], rotateUpdate: [{ type: i0.Output, args: ["rotateUpdate"] }], marqueeSelect: [{ type: i0.Output, args: ["marqueeSelect"] }], textEditor: [{ type: i0.ViewChild, args: ['textEditor', { isSignal: true }] }], stageRef: [{ type: i0.ViewChild, args: ['stage', { isSignal: true }] }], viewportRef: [{ type: i0.ViewChild, args: ['viewport', { isSignal: true }] }], onPointerMove: [{
30963
31110
  type: HostListener,
30964
31111
  args: ['document:pointermove', ['$event']]
30965
31112
  }], onPointerUp: [{
@@ -31116,6 +31263,7 @@ class MobileSlidesSheetComponent {
31116
31263
  [mediaDataUrls]="mediaDataUrls()"
31117
31264
  [zoom]="thumbZoom()"
31118
31265
  [editable]="false"
31266
+ [autoFit]="false"
31119
31267
  />
31120
31268
  </div>
31121
31269
 
@@ -31125,7 +31273,7 @@ class MobileSlidesSheetComponent {
31125
31273
  }
31126
31274
  </div>
31127
31275
  </pptx-mobile-sheet>
31128
- `, isInline: true, styles: [":host{display:contents}.pptx-ng-mslides-count{margin:0;padding:.5rem 1rem .25rem;font-size:.75rem;color:#ffffff73}.pptx-ng-mslides-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:.75rem;padding:.75rem .875rem 1.5rem}.pptx-ng-mslides-cell{display:flex;flex-direction:column;align-items:center;gap:.375rem;padding:.375rem;border:2px solid transparent;border-radius:.5rem;background:transparent;color:inherit;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;transition:border-color .12s,background .12s}.pptx-ng-mslides-cell:hover{background:#ffffff0d;border-color:#ffffff26}.pptx-ng-mslides-cell:active{background:#ffffff1a}.pptx-ng-mslides-cell.is-active{border-color:#3b82f6;background:#3b82f61a}.pptx-ng-mslides-clip{overflow:hidden;border-radius:.25rem;width:100%}.pptx-ng-mslides-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-mslides-num{display:block;font-size:.625rem;color:#fff6;line-height:1.4;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: MobileSheetComponent, selector: "pptx-mobile-sheet", inputs: ["open", "title", "heightFraction", "fullScreen"], outputs: ["closed"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "selectedIds", "editingId"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "rotateUpdate", "marqueeSelect"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
31276
+ `, isInline: true, styles: [":host{display:contents}.pptx-ng-mslides-count{margin:0;padding:.5rem 1rem .25rem;font-size:.75rem;color:#ffffff73}.pptx-ng-mslides-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:.75rem;padding:.75rem .875rem 1.5rem}.pptx-ng-mslides-cell{display:flex;flex-direction:column;align-items:center;gap:.375rem;padding:.375rem;border:2px solid transparent;border-radius:.5rem;background:transparent;color:inherit;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;transition:border-color .12s,background .12s}.pptx-ng-mslides-cell:hover{background:#ffffff0d;border-color:#ffffff26}.pptx-ng-mslides-cell:active{background:#ffffff1a}.pptx-ng-mslides-cell.is-active{border-color:#3b82f6;background:#3b82f61a}.pptx-ng-mslides-clip{overflow:hidden;border-radius:.25rem;width:100%}.pptx-ng-mslides-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-mslides-num{display:block;font-size:.625rem;color:#fff6;line-height:1.4;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: MobileSheetComponent, selector: "pptx-mobile-sheet", inputs: ["open", "title", "heightFraction", "fullScreen"], outputs: ["closed"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "autoFit", "selectedIds", "editingId"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "rotateUpdate", "marqueeSelect"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
31129
31277
  }
31130
31278
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: MobileSlidesSheetComponent, decorators: [{
31131
31279
  type: Component,
@@ -31162,6 +31310,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
31162
31310
  [mediaDataUrls]="mediaDataUrls()"
31163
31311
  [zoom]="thumbZoom()"
31164
31312
  [editable]="false"
31313
+ [autoFit]="false"
31165
31314
  />
31166
31315
  </div>
31167
31316
 
@@ -31174,6 +31323,141 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
31174
31323
  `, styles: [":host{display:contents}.pptx-ng-mslides-count{margin:0;padding:.5rem 1rem .25rem;font-size:.75rem;color:#ffffff73}.pptx-ng-mslides-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:.75rem;padding:.75rem .875rem 1.5rem}.pptx-ng-mslides-cell{display:flex;flex-direction:column;align-items:center;gap:.375rem;padding:.375rem;border:2px solid transparent;border-radius:.5rem;background:transparent;color:inherit;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;transition:border-color .12s,background .12s}.pptx-ng-mslides-cell:hover{background:#ffffff0d;border-color:#ffffff26}.pptx-ng-mslides-cell:active{background:#ffffff1a}.pptx-ng-mslides-cell.is-active{border-color:#3b82f6;background:#3b82f61a}.pptx-ng-mslides-clip{overflow:hidden;border-radius:.25rem;width:100%}.pptx-ng-mslides-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-mslides-num{display:block;font-size:.625rem;color:#fff6;line-height:1.4;-webkit-user-select:none;user-select:none}\n"] }]
31175
31324
  }], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], slides: [{ type: i0.Input, args: [{ isSignal: true, alias: "slides", required: false }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], activeIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIndex", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], jumpToSlide: [{ type: i0.Output, args: ["jumpToSlide"] }] } });
31176
31325
 
31326
+ /**
31327
+ * notes-panel.component.ts — collapsible, editable speaker-notes panel.
31328
+ *
31329
+ * Ported from: packages/vue/src/viewer/components/NotesPanel.vue
31330
+ * (itself the Vue mirror of the React `SlideNotesPanel`).
31331
+ *
31332
+ * Renders the active slide's speaker notes in an editable `<textarea>`. Reads the
31333
+ * real core field `PptxSlide.notes` (populated during parse and preserved through
31334
+ * `LoadContentService` / `EditorStateService`). The host writes the edited text
31335
+ * back via a history-aware update when {@link update} is emitted.
31336
+ *
31337
+ * Framework-neutral e2e contract
31338
+ * ------------------------------
31339
+ * The body wrapper carries `id="slide-notes-content"` and the editor is a
31340
+ * `textarea[name="slide-notes"]`, matching the React/Vue viewers so the shared
31341
+ * Playwright specs (`e2e/mobile-notes.spec.ts`) run unchanged against Angular.
31342
+ *
31343
+ * Touch / focus correctness
31344
+ * -------------------------
31345
+ * The textarea is UNCONTROLLED: its value is seeded imperatively via a view-child
31346
+ * ref exactly once per slide and never re-bound while the user types. Re-binding
31347
+ * `value` to a signal the host mutated on every keystroke would dismiss the
31348
+ * on-screen keyboard and jump the caret — so the DOM owns the text during an edit
31349
+ * and we only commit on `change` / `blur` (one history entry per edit).
31350
+ */
31351
+ class NotesPanelComponent {
31352
+ /** The active slide whose notes are shown / edited. */
31353
+ slide = input(undefined, /* @ts-ignore */
31354
+ ...(ngDevMode ? [{ debugName: "slide" }] : /* istanbul ignore next */ []));
31355
+ /** Emits the new notes text on commit (change / blur). */
31356
+ update = output();
31357
+ /** Whether the panel body is collapsed (notes hidden). */
31358
+ collapsed = signal(false, /* @ts-ignore */
31359
+ ...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []));
31360
+ textarea = viewChild('textarea', /* @ts-ignore */
31361
+ ...(ngDevMode ? [{ debugName: "textarea" }] : /* istanbul ignore next */ []));
31362
+ /** The slide id we've already seeded the textarea for. */
31363
+ seededId = null;
31364
+ constructor() {
31365
+ // Seed (and re-seed) the uncontrolled textarea exactly once per slide.
31366
+ // Keying on the slide id means we never overwrite in-progress typed text on
31367
+ // an unrelated change-detection pass (which would steal focus on touch).
31368
+ effect(() => {
31369
+ const el = this.textarea()?.nativeElement;
31370
+ const slide = this.slide();
31371
+ if (!el) {
31372
+ return;
31373
+ }
31374
+ const id = slide?.id ?? null;
31375
+ if (this.seededId === id) {
31376
+ return;
31377
+ }
31378
+ this.seededId = id;
31379
+ el.value = slide?.notes ?? '';
31380
+ });
31381
+ afterNextRender(() => {
31382
+ const el = this.textarea()?.nativeElement;
31383
+ if (el && this.seededId === null) {
31384
+ this.seededId = this.slide()?.id ?? null;
31385
+ el.value = this.slide()?.notes ?? '';
31386
+ }
31387
+ });
31388
+ }
31389
+ /** Toggle the collapsed state. */
31390
+ toggle() {
31391
+ this.collapsed.update((v) => !v);
31392
+ }
31393
+ /** Commit the edited notes text to the host. */
31394
+ onCommit(event) {
31395
+ this.update.emit(event.target.value);
31396
+ }
31397
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: NotesPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
31398
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: NotesPanelComponent, isStandalone: true, selector: "pptx-notes-panel", inputs: { slide: { classPropertyName: "slide", publicName: "slide", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { update: "update" }, viewQueries: [{ propertyName: "textarea", first: true, predicate: ["textarea"], descendants: true, isSignal: true }], ngImport: i0, template: `
31399
+ <section class="pptx-ng-notes-panel" [attr.data-collapsed]="collapsed()">
31400
+ <button
31401
+ type="button"
31402
+ class="pptx-ng-notes-header"
31403
+ [attr.aria-expanded]="!collapsed()"
31404
+ (click)="toggle()"
31405
+ >
31406
+ <span class="pptx-ng-notes-label">Speaker notes</span>
31407
+ <span class="pptx-ng-notes-chevron" aria-hidden="true">{{ collapsed() ? '▸' : '▾' }}</span>
31408
+ </button>
31409
+
31410
+ @if (!collapsed()) {
31411
+ <div id="slide-notes-content" class="pptx-ng-notes-body">
31412
+ <textarea
31413
+ #textarea
31414
+ name="slide-notes"
31415
+ class="pptx-ng-notes-textarea"
31416
+ [disabled]="!slide()"
31417
+ [attr.placeholder]="slide() ? 'Add speaker notes…' : 'No slide selected'"
31418
+ aria-label="Speaker notes"
31419
+ spellcheck="true"
31420
+ (change)="onCommit($event)"
31421
+ (blur)="onCommit($event)"
31422
+ ></textarea>
31423
+ </div>
31424
+ }
31425
+ </section>
31426
+ `, isInline: true, styles: [":host{display:block}.pptx-ng-notes-panel{display:flex;flex-direction:column;border-top:1px solid rgba(0,0,0,.1);background:#fff;color:#111827}.pptx-ng-notes-header{display:flex;width:100%;align-items:center;justify-content:space-between;padding:.5rem .75rem;border:none;background:transparent;font-size:.8125rem;font-weight:600;color:#6b7280;cursor:pointer}.pptx-ng-notes-header:hover{color:#111827}.pptx-ng-notes-body{padding:0 .75rem .75rem}.pptx-ng-notes-textarea{box-sizing:border-box;width:100%;min-height:5rem;resize:vertical;padding:.5rem;border:1px solid rgba(0,0,0,.15);border-radius:.375rem;background:#00000008;font:inherit;font-size:.8125rem;line-height:1.5;color:#111827}.pptx-ng-notes-textarea:focus{outline:none;border-color:#6366f1;box-shadow:0 0 0 1px #6366f14d}.pptx-ng-notes-textarea:disabled{cursor:not-allowed;opacity:.6}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
31427
+ }
31428
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: NotesPanelComponent, decorators: [{
31429
+ type: Component,
31430
+ args: [{ selector: 'pptx-notes-panel', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
31431
+ <section class="pptx-ng-notes-panel" [attr.data-collapsed]="collapsed()">
31432
+ <button
31433
+ type="button"
31434
+ class="pptx-ng-notes-header"
31435
+ [attr.aria-expanded]="!collapsed()"
31436
+ (click)="toggle()"
31437
+ >
31438
+ <span class="pptx-ng-notes-label">Speaker notes</span>
31439
+ <span class="pptx-ng-notes-chevron" aria-hidden="true">{{ collapsed() ? '▸' : '▾' }}</span>
31440
+ </button>
31441
+
31442
+ @if (!collapsed()) {
31443
+ <div id="slide-notes-content" class="pptx-ng-notes-body">
31444
+ <textarea
31445
+ #textarea
31446
+ name="slide-notes"
31447
+ class="pptx-ng-notes-textarea"
31448
+ [disabled]="!slide()"
31449
+ [attr.placeholder]="slide() ? 'Add speaker notes…' : 'No slide selected'"
31450
+ aria-label="Speaker notes"
31451
+ spellcheck="true"
31452
+ (change)="onCommit($event)"
31453
+ (blur)="onCommit($event)"
31454
+ ></textarea>
31455
+ </div>
31456
+ }
31457
+ </section>
31458
+ `, styles: [":host{display:block}.pptx-ng-notes-panel{display:flex;flex-direction:column;border-top:1px solid rgba(0,0,0,.1);background:#fff;color:#111827}.pptx-ng-notes-header{display:flex;width:100%;align-items:center;justify-content:space-between;padding:.5rem .75rem;border:none;background:transparent;font-size:.8125rem;font-weight:600;color:#6b7280;cursor:pointer}.pptx-ng-notes-header:hover{color:#111827}.pptx-ng-notes-body{padding:0 .75rem .75rem}.pptx-ng-notes-textarea{box-sizing:border-box;width:100%;min-height:5rem;resize:vertical;padding:.5rem;border:1px solid rgba(0,0,0,.15);border-radius:.375rem;background:#00000008;font:inherit;font-size:.8125rem;line-height:1.5;color:#111827}.pptx-ng-notes-textarea:focus{outline:none;border-color:#6366f1;box-shadow:0 0 0 1px #6366f14d}.pptx-ng-notes-textarea:disabled{cursor:not-allowed;opacity:.6}\n"] }]
31459
+ }], ctorParameters: () => [], propDecorators: { slide: [{ type: i0.Input, args: [{ isSignal: true, alias: "slide", required: false }] }], update: [{ type: i0.Output, args: ["update"] }], textarea: [{ type: i0.ViewChild, args: ['textarea', { isSignal: true }] }] } });
31460
+
31177
31461
  /**
31178
31462
  * animation-playback-helpers.ts
31179
31463
  *
@@ -33378,7 +33662,7 @@ class PresentationTransitionOverlayComponent {
33378
33662
  />
33379
33663
  </div>
33380
33664
  </div>
33381
- `, isInline: true, styles: [":host{display:block;position:absolute;inset:0;overflow:hidden;pointer-events:none}.pptx-ng-transition-layer{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "selectedIds", "editingId"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "rotateUpdate", "marqueeSelect"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
33665
+ `, isInline: true, styles: [":host{display:block;position:absolute;inset:0;overflow:hidden;pointer-events:none}.pptx-ng-transition-layer{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "autoFit", "selectedIds", "editingId"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "rotateUpdate", "marqueeSelect"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
33382
33666
  }
33383
33667
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: PresentationTransitionOverlayComponent, decorators: [{
33384
33668
  type: Component,
@@ -33866,6 +34150,7 @@ class PresentationOverlayComponent {
33866
34150
  [canvasSize]="canvasSize()"
33867
34151
  [mediaDataUrls]="mediaDataUrls()"
33868
34152
  [zoom]="zoom()"
34153
+ [autoFit]="false"
33869
34154
  />
33870
34155
 
33871
34156
  @if (activeTransition(); as t) {
@@ -33971,7 +34256,7 @@ class PresentationOverlayComponent {
33971
34256
  {{ counterLabel() }}
33972
34257
  </span>
33973
34258
  </div>
33974
- `, isInline: true, styles: [":host{display:block;position:fixed;inset:0;z-index:10000;background:#000;cursor:pointer;-webkit-user-select:none;user-select:none}.pptx-ng-presentation-root{position:absolute;inset:0;touch-action:pan-y}.pptx-ng-presentation-close:hover,.pptx-ng-presentation-nav:hover{background:#000000bf}.pptx-ng-presentation-tools{position:absolute;bottom:max(1rem,env(safe-area-inset-bottom));left:50%;transform:translate(-50%);display:flex;gap:.25rem;padding:.25rem;border-radius:.5rem;background:#0000008c;z-index:80}.pptx-ng-presentation-tools button{width:2rem;height:2rem;border:none;border-radius:.35rem;background:transparent;color:#fff;font-size:1rem;cursor:pointer}.pptx-ng-presentation-tools button:hover{background:#ffffff26}.pptx-ng-presentation-tools button.is-active{background:#ffffff4d}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "selectedIds", "editingId"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "rotateUpdate", "marqueeSelect"] }, { kind: "component", type: PresentationTransitionOverlayComponent, selector: "pptx-presentation-transition-overlay", inputs: ["outgoingSlide", "canvasSize", "transition", "templateElements", "mediaDataUrls", "durationMs"], outputs: ["complete"] }, { kind: "component", type: PresentationAnnotationOverlayComponent, selector: "pptx-presentation-annotation-overlay", inputs: ["canvasSize", "zoom"] }, { kind: "component", type: PresentationSubtitleBarComponent, selector: "pptx-presentation-subtitle-bar", inputs: ["visible"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
34259
+ `, isInline: true, styles: [":host{display:block;position:fixed;inset:0;z-index:10000;background:#000;cursor:pointer;-webkit-user-select:none;user-select:none}.pptx-ng-presentation-root{position:absolute;inset:0;touch-action:pan-y}.pptx-ng-presentation-close:hover,.pptx-ng-presentation-nav:hover{background:#000000bf}.pptx-ng-presentation-tools{position:absolute;bottom:max(1rem,env(safe-area-inset-bottom));left:1rem;display:flex;gap:.25rem;padding:.25rem;border-radius:.5rem;background:#0000008c;z-index:80}.pptx-ng-presentation-tools button{width:2rem;height:2rem;border:none;border-radius:.35rem;background:transparent;color:#fff;font-size:1rem;cursor:pointer}.pptx-ng-presentation-tools button:hover{background:#ffffff26}.pptx-ng-presentation-tools button.is-active{background:#ffffff4d}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "autoFit", "selectedIds", "editingId"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "rotateUpdate", "marqueeSelect"] }, { kind: "component", type: PresentationTransitionOverlayComponent, selector: "pptx-presentation-transition-overlay", inputs: ["outgoingSlide", "canvasSize", "transition", "templateElements", "mediaDataUrls", "durationMs"], outputs: ["complete"] }, { kind: "component", type: PresentationAnnotationOverlayComponent, selector: "pptx-presentation-annotation-overlay", inputs: ["canvasSize", "zoom"] }, { kind: "component", type: PresentationSubtitleBarComponent, selector: "pptx-presentation-subtitle-bar", inputs: ["visible"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
33975
34260
  }
33976
34261
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: PresentationOverlayComponent, decorators: [{
33977
34262
  type: Component,
@@ -33999,6 +34284,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
33999
34284
  [canvasSize]="canvasSize()"
34000
34285
  [mediaDataUrls]="mediaDataUrls()"
34001
34286
  [zoom]="zoom()"
34287
+ [autoFit]="false"
34002
34288
  />
34003
34289
 
34004
34290
  @if (activeTransition(); as t) {
@@ -34104,7 +34390,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
34104
34390
  {{ counterLabel() }}
34105
34391
  </span>
34106
34392
  </div>
34107
- `, styles: [":host{display:block;position:fixed;inset:0;z-index:10000;background:#000;cursor:pointer;-webkit-user-select:none;user-select:none}.pptx-ng-presentation-root{position:absolute;inset:0;touch-action:pan-y}.pptx-ng-presentation-close:hover,.pptx-ng-presentation-nav:hover{background:#000000bf}.pptx-ng-presentation-tools{position:absolute;bottom:max(1rem,env(safe-area-inset-bottom));left:50%;transform:translate(-50%);display:flex;gap:.25rem;padding:.25rem;border-radius:.5rem;background:#0000008c;z-index:80}.pptx-ng-presentation-tools button{width:2rem;height:2rem;border:none;border-radius:.35rem;background:transparent;color:#fff;font-size:1rem;cursor:pointer}.pptx-ng-presentation-tools button:hover{background:#ffffff26}.pptx-ng-presentation-tools button.is-active{background:#ffffff4d}\n"] }]
34393
+ `, styles: [":host{display:block;position:fixed;inset:0;z-index:10000;background:#000;cursor:pointer;-webkit-user-select:none;user-select:none}.pptx-ng-presentation-root{position:absolute;inset:0;touch-action:pan-y}.pptx-ng-presentation-close:hover,.pptx-ng-presentation-nav:hover{background:#000000bf}.pptx-ng-presentation-tools{position:absolute;bottom:max(1rem,env(safe-area-inset-bottom));left:1rem;display:flex;gap:.25rem;padding:.25rem;border-radius:.5rem;background:#0000008c;z-index:80}.pptx-ng-presentation-tools button{width:2rem;height:2rem;border:none;border-radius:.35rem;background:transparent;color:#fff;font-size:1rem;cursor:pointer}.pptx-ng-presentation-tools button:hover{background:#ffffff26}.pptx-ng-presentation-tools button.is-active{background:#ffffff4d}\n"] }]
34108
34394
  }], ctorParameters: () => [], propDecorators: { slides: [{ type: i0.Input, args: [{ isSignal: true, alias: "slides", required: true }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], startIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "startIndex", required: false }] }], indexChange: [{ type: i0.Output, args: ["indexChange"] }], closed: [{ type: i0.Output, args: ["closed"] }], stageRef: [{ type: i0.ViewChild, args: ['stage', { isSignal: true }] }], onWindowResize: [{
34109
34395
  type: HostListener,
34110
34396
  args: ['window:resize']
@@ -34577,7 +34863,7 @@ class PresenterViewComponent {
34577
34863
  } @else {
34578
34864
  <div class="pptx-ng-presenter-empty">No slides to present.</div>
34579
34865
  }
34580
- `, isInline: true, styles: [":host{position:absolute;inset:0;z-index:50;display:flex;flex-direction:column;background:#0b0b0c;color:#f5f5f5;font-family:system-ui,sans-serif}.pptx-ng-presenter-body{display:flex;flex:1 1 auto;min-height:0}.pptx-ng-presenter-current{flex:7 1 0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#000;padding:1rem;min-width:0}.pptx-ng-presenter-preview-stage{width:100%;max-width:100%;min-height:0}.pptx-ng-presenter-slide-badge{margin-top:.5rem;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.75rem;color:#ffffff80;-webkit-user-select:none;user-select:none}.pptx-ng-presenter-side{flex:3 1 0;display:flex;flex-direction:column;background:#18181b;border-left:1px solid rgba(255,255,255,.12);min-width:260px;max-width:440px}.pptx-ng-presenter-header,.pptx-ng-presenter-nav,.pptx-ng-presenter-next{padding:.5rem 1rem;border-bottom:1px solid rgba(255,255,255,.08)}.pptx-ng-presenter-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem}.pptx-ng-presenter-label{font-size:.625rem;text-transform:uppercase;letter-spacing:.06em;color:#ffffff8c}.pptx-ng-presenter-clock{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:1.125rem}.pptx-ng-presenter-elapsed{color:#6ea8fe}.pptx-ng-presenter-iconbtn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:6px;background:transparent;color:#ffffffb3;cursor:pointer;font-size:1rem;line-height:1}.pptx-ng-presenter-iconbtn:hover{background:#ffffff1a;color:#fff}.pptx-ng-presenter-iconbtn:disabled{opacity:.3;cursor:not-allowed}.pptx-ng-presenter-nav{display:flex;align-items:center;justify-content:space-between}.pptx-ng-presenter-navbtn{display:inline-flex;align-items:center;gap:.375rem;padding:.375rem .75rem;border:none;border-radius:6px;background:#ffffff14;color:#f5f5f5;cursor:pointer;font-size:.75rem}.pptx-ng-presenter-navbtn:hover:not(:disabled){background:#ffffff29}.pptx-ng-presenter-navbtn:disabled{opacity:.4;cursor:not-allowed}.pptx-ng-presenter-counter{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.875rem}.pptx-ng-presenter-next-empty{display:flex;align-items:center;justify-content:center;height:4rem;border:1px solid rgba(255,255,255,.15);border-radius:6px;background:#ffffff0a;font-size:.75rem;font-style:italic;color:#ffffff80}.pptx-ng-presenter-notes{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;padding:.75rem 1rem}.pptx-ng-presenter-notes-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:.5rem}.pptx-ng-presenter-notes-size{display:flex;align-items:center;gap:.25rem}.pptx-ng-presenter-notes-size-value{min-width:28px;text-align:center;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.625rem;color:#ffffff8c;-webkit-user-select:none;user-select:none}.pptx-ng-presenter-notes-body{flex:1 1 auto;overflow-y:auto;border:1px solid rgba(255,255,255,.15);border-radius:6px;background:#ffffff0a;padding:.5rem .75rem;white-space:pre-wrap;line-height:1.5}.pptx-ng-presenter-notes-empty{font-style:italic;color:#ffffff80}.pptx-ng-presenter-progress{height:6px;width:100%;background:#ffffff1f;flex:0 0 auto}.pptx-ng-presenter-progress-fill{height:100%;background:#6ea8fe;transition:width 1s linear}.pptx-ng-presenter-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#fff9}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "selectedIds", "editingId"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "rotateUpdate", "marqueeSelect"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
34866
+ `, isInline: true, styles: [":host{position:absolute;inset:0;z-index:50;display:flex;flex-direction:column;background:#0b0b0c;color:#f5f5f5;font-family:system-ui,sans-serif}.pptx-ng-presenter-body{display:flex;flex:1 1 auto;min-height:0}.pptx-ng-presenter-current{flex:7 1 0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#000;padding:1rem;min-width:0}.pptx-ng-presenter-preview-stage{width:100%;max-width:100%;min-height:0}.pptx-ng-presenter-slide-badge{margin-top:.5rem;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.75rem;color:#ffffff80;-webkit-user-select:none;user-select:none}.pptx-ng-presenter-side{flex:3 1 0;display:flex;flex-direction:column;background:#18181b;border-left:1px solid rgba(255,255,255,.12);min-width:260px;max-width:440px}.pptx-ng-presenter-header,.pptx-ng-presenter-nav,.pptx-ng-presenter-next{padding:.5rem 1rem;border-bottom:1px solid rgba(255,255,255,.08)}.pptx-ng-presenter-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem}.pptx-ng-presenter-label{font-size:.625rem;text-transform:uppercase;letter-spacing:.06em;color:#ffffff8c}.pptx-ng-presenter-clock{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:1.125rem}.pptx-ng-presenter-elapsed{color:#6ea8fe}.pptx-ng-presenter-iconbtn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:6px;background:transparent;color:#ffffffb3;cursor:pointer;font-size:1rem;line-height:1}.pptx-ng-presenter-iconbtn:hover{background:#ffffff1a;color:#fff}.pptx-ng-presenter-iconbtn:disabled{opacity:.3;cursor:not-allowed}.pptx-ng-presenter-nav{display:flex;align-items:center;justify-content:space-between}.pptx-ng-presenter-navbtn{display:inline-flex;align-items:center;gap:.375rem;padding:.375rem .75rem;border:none;border-radius:6px;background:#ffffff14;color:#f5f5f5;cursor:pointer;font-size:.75rem}.pptx-ng-presenter-navbtn:hover:not(:disabled){background:#ffffff29}.pptx-ng-presenter-navbtn:disabled{opacity:.4;cursor:not-allowed}.pptx-ng-presenter-counter{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.875rem}.pptx-ng-presenter-next-empty{display:flex;align-items:center;justify-content:center;height:4rem;border:1px solid rgba(255,255,255,.15);border-radius:6px;background:#ffffff0a;font-size:.75rem;font-style:italic;color:#ffffff80}.pptx-ng-presenter-notes{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;padding:.75rem 1rem}.pptx-ng-presenter-notes-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:.5rem}.pptx-ng-presenter-notes-size{display:flex;align-items:center;gap:.25rem}.pptx-ng-presenter-notes-size-value{min-width:28px;text-align:center;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.625rem;color:#ffffff8c;-webkit-user-select:none;user-select:none}.pptx-ng-presenter-notes-body{flex:1 1 auto;overflow-y:auto;border:1px solid rgba(255,255,255,.15);border-radius:6px;background:#ffffff0a;padding:.5rem .75rem;white-space:pre-wrap;line-height:1.5}.pptx-ng-presenter-notes-empty{font-style:italic;color:#ffffff80}.pptx-ng-presenter-progress{height:6px;width:100%;background:#ffffff1f;flex:0 0 auto}.pptx-ng-presenter-progress-fill{height:100%;background:#6ea8fe;transition:width 1s linear}.pptx-ng-presenter-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#fff9}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "autoFit", "selectedIds", "editingId"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "rotateUpdate", "marqueeSelect"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
34581
34867
  }
34582
34868
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: PresenterViewComponent, decorators: [{
34583
34869
  type: Component,
@@ -36877,6 +37163,7 @@ class SlideSorterOverlayComponent {
36877
37163
  [canvasSize]="canvasSize()"
36878
37164
  [mediaDataUrls]="mediaDataUrls()"
36879
37165
  [zoom]="thumbZoom()"
37166
+ [autoFit]="false"
36880
37167
  />
36881
37168
  </div>
36882
37169
  <!-- Slide number badge -->
@@ -36887,7 +37174,7 @@ class SlideSorterOverlayComponent {
36887
37174
  </div>
36888
37175
  </div>
36889
37176
  </div>
36890
- `, isInline: true, styles: [":host{display:contents}.pptx-ng-sorter-backdrop{position:fixed;inset:0;z-index:50;display:flex;align-items:center;justify-content:center;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.pptx-ng-sorter-panel{display:flex;flex-direction:column;width:min(96vw,1200px);max-height:90vh;border-radius:.5rem;background:#1a1a1a;color:#e5e5e5;box-shadow:0 24px 64px #0009;overflow:hidden}.pptx-ng-sorter-header{display:flex;align-items:center;gap:.75rem;padding:.75rem 1.25rem;border-bottom:1px solid rgba(255,255,255,.1);flex-shrink:0}.pptx-ng-sorter-title{margin:0;font-size:.875rem;font-weight:500}.pptx-ng-sorter-count{font-size:.75rem;color:#ffffff80;flex:1}.pptx-ng-sorter-close{display:flex;align-items:center;justify-content:center;width:44px;height:44px;min-width:44px;min-height:44px;padding:0;border:none;border-radius:50%;background:#ffffff1a;color:#e5e5e5;cursor:pointer;transition:background .15s;flex-shrink:0;touch-action:manipulation}.pptx-ng-sorter-close:hover{background:#fff3}.pptx-ng-sorter-grid-scroll{flex:1;overflow-y:auto;padding:1.25rem}.pptx-ng-sorter-grid{display:grid;gap:1rem}.pptx-ng-sorter-cell{display:flex;flex-direction:column;align-items:center;gap:.5rem;padding:.5rem;border:2px solid transparent;border-radius:.375rem;background:transparent;cursor:pointer;transition:border-color .15s,background .15s;color:inherit}.pptx-ng-sorter-cell:hover{background:#ffffff0f;border-color:#fff3}.pptx-ng-sorter-cell.is-active{border-color:#3b82f6;background:#3b82f61a}.pptx-ng-sorter-cell.is-hidden{opacity:.4}.pptx-ng-sorter-thumb-clip{overflow:hidden;border-radius:2px}.pptx-ng-sorter-thumb-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-sorter-index{font-size:.6875rem;color:#ffffff8c;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "selectedIds", "editingId"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "rotateUpdate", "marqueeSelect"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
37177
+ `, isInline: true, styles: [":host{display:contents}.pptx-ng-sorter-backdrop{position:fixed;inset:0;z-index:50;display:flex;align-items:center;justify-content:center;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.pptx-ng-sorter-panel{display:flex;flex-direction:column;width:min(96vw,1200px);max-height:90vh;border-radius:.5rem;background:#1a1a1a;color:#e5e5e5;box-shadow:0 24px 64px #0009;overflow:hidden}.pptx-ng-sorter-header{display:flex;align-items:center;gap:.75rem;padding:.75rem 1.25rem;border-bottom:1px solid rgba(255,255,255,.1);flex-shrink:0}.pptx-ng-sorter-title{margin:0;font-size:.875rem;font-weight:500}.pptx-ng-sorter-count{font-size:.75rem;color:#ffffff80;flex:1}.pptx-ng-sorter-close{display:flex;align-items:center;justify-content:center;width:44px;height:44px;min-width:44px;min-height:44px;padding:0;border:none;border-radius:50%;background:#ffffff1a;color:#e5e5e5;cursor:pointer;transition:background .15s;flex-shrink:0;touch-action:manipulation}.pptx-ng-sorter-close:hover{background:#fff3}.pptx-ng-sorter-grid-scroll{flex:1;overflow-y:auto;padding:1.25rem}.pptx-ng-sorter-grid{display:grid;gap:1rem}.pptx-ng-sorter-cell{display:flex;flex-direction:column;align-items:center;gap:.5rem;padding:.5rem;border:2px solid transparent;border-radius:.375rem;background:transparent;cursor:pointer;transition:border-color .15s,background .15s;color:inherit}.pptx-ng-sorter-cell:hover{background:#ffffff0f;border-color:#fff3}.pptx-ng-sorter-cell.is-active{border-color:#3b82f6;background:#3b82f61a}.pptx-ng-sorter-cell.is-hidden{opacity:.4}.pptx-ng-sorter-thumb-clip{overflow:hidden;border-radius:2px}.pptx-ng-sorter-thumb-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-sorter-index{font-size:.6875rem;color:#ffffff8c;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "autoFit", "selectedIds", "editingId"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "rotateUpdate", "marqueeSelect"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
36891
37178
  }
36892
37179
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SlideSorterOverlayComponent, decorators: [{
36893
37180
  type: Component,
@@ -36944,6 +37231,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
36944
37231
  [canvasSize]="canvasSize()"
36945
37232
  [mediaDataUrls]="mediaDataUrls()"
36946
37233
  [zoom]="thumbZoom()"
37234
+ [autoFit]="false"
36947
37235
  />
36948
37236
  </div>
36949
37237
  <!-- Slide number badge -->
@@ -37052,6 +37340,7 @@ class SlidesPanelComponent {
37052
37340
  [mediaDataUrls]="mediaDataUrls()"
37053
37341
  [zoom]="thumbZoom()"
37054
37342
  [editable]="false"
37343
+ [autoFit]="false"
37055
37344
  />
37056
37345
  </div>
37057
37346
  </button>
@@ -37121,7 +37410,7 @@ class SlidesPanelComponent {
37121
37410
  </button>
37122
37411
  </footer>
37123
37412
  </div>
37124
- `, isInline: true, styles: [":host{display:flex;flex-direction:column;height:100%;overflow:hidden}.pptx-ng-spanel{display:flex;flex-direction:column;height:100%;background:#1e1e1e;color:#e5e5e5;border-right:1px solid rgba(255,255,255,.08);overflow:hidden}.pptx-ng-spanel-scroll{flex:1;overflow-y:auto;padding:.5rem .375rem;display:flex;flex-direction:column;gap:.375rem}.pptx-ng-spanel-card{position:relative;border-radius:.375rem;border:2px solid transparent;background:transparent;transition:border-color .15s,background .15s}.pptx-ng-spanel-card:hover,.pptx-ng-spanel-card:focus-within{background:#ffffff0d;border-color:#ffffff26}.pptx-ng-spanel-card.is-active{border-color:#3b82f6;background:#3b82f61a}.pptx-ng-spanel-thumb-btn{display:block;width:100%;padding:.375rem .375rem 0;border:none;background:transparent;cursor:pointer;color:inherit;line-height:0}.pptx-ng-spanel-thumb-btn:focus-visible{outline:2px solid #3b82f6;outline-offset:2px;border-radius:.25rem}.pptx-ng-spanel-clip{overflow:hidden;border-radius:2px}.pptx-ng-spanel-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-spanel-num{display:block;text-align:center;font-size:.625rem;line-height:1.6;color:#ffffff73;-webkit-user-select:none;user-select:none;padding-bottom:.25rem}.pptx-ng-spanel-actions{position:absolute;top:.25rem;right:.25rem;display:flex;flex-direction:column;gap:.125rem;opacity:0;pointer-events:none;transition:opacity .12s}.pptx-ng-spanel-card:hover .pptx-ng-spanel-actions,.pptx-ng-spanel-card:focus-within .pptx-ng-spanel-actions{opacity:1;pointer-events:auto}.pptx-ng-spanel-action{display:flex;align-items:center;justify-content:center;width:1.375rem;height:1.375rem;padding:0;border:none;border-radius:.25rem;background:#1e1e1ed9;color:#e5e5e5;font-size:.6875rem;cursor:pointer;transition:background .12s;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.pptx-ng-spanel-action:hover:not([disabled]){background:#3b82f6bf}.pptx-ng-spanel-action[disabled]{opacity:.3;cursor:not-allowed}.pptx-ng-spanel-footer{flex-shrink:0;padding:.5rem .375rem;border-top:1px solid rgba(255,255,255,.08)}.pptx-ng-spanel-add{display:block;width:100%;padding:.4375rem 0;border:1px dashed rgba(255,255,255,.2);border-radius:.375rem;background:transparent;color:#fff9;font-size:.75rem;cursor:pointer;transition:background .15s,border-color .15s,color .15s}.pptx-ng-spanel-add:hover{background:#3b82f626;border-color:#3b82f6;color:#e5e5e5}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "selectedIds", "editingId"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "rotateUpdate", "marqueeSelect"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
37413
+ `, isInline: true, styles: [":host{display:flex;flex-direction:column;height:100%;overflow:hidden}.pptx-ng-spanel{display:flex;flex-direction:column;height:100%;background:#1e1e1e;color:#e5e5e5;border-right:1px solid rgba(255,255,255,.08);overflow:hidden}.pptx-ng-spanel-scroll{flex:1;overflow-y:auto;padding:.5rem .375rem;display:flex;flex-direction:column;gap:.375rem}.pptx-ng-spanel-card{position:relative;border-radius:.375rem;border:2px solid transparent;background:transparent;transition:border-color .15s,background .15s}.pptx-ng-spanel-card:hover,.pptx-ng-spanel-card:focus-within{background:#ffffff0d;border-color:#ffffff26}.pptx-ng-spanel-card.is-active{border-color:#3b82f6;background:#3b82f61a}.pptx-ng-spanel-thumb-btn{display:block;width:100%;padding:.375rem .375rem 0;border:none;background:transparent;cursor:pointer;color:inherit;line-height:0}.pptx-ng-spanel-thumb-btn:focus-visible{outline:2px solid #3b82f6;outline-offset:2px;border-radius:.25rem}.pptx-ng-spanel-clip{overflow:hidden;border-radius:2px}.pptx-ng-spanel-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-spanel-num{display:block;text-align:center;font-size:.625rem;line-height:1.6;color:#ffffff73;-webkit-user-select:none;user-select:none;padding-bottom:.25rem}.pptx-ng-spanel-actions{position:absolute;top:.25rem;right:.25rem;display:flex;flex-direction:column;gap:.125rem;opacity:0;pointer-events:none;transition:opacity .12s}.pptx-ng-spanel-card:hover .pptx-ng-spanel-actions,.pptx-ng-spanel-card:focus-within .pptx-ng-spanel-actions{opacity:1;pointer-events:auto}.pptx-ng-spanel-action{display:flex;align-items:center;justify-content:center;width:1.375rem;height:1.375rem;padding:0;border:none;border-radius:.25rem;background:#1e1e1ed9;color:#e5e5e5;font-size:.6875rem;cursor:pointer;transition:background .12s;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.pptx-ng-spanel-action:hover:not([disabled]){background:#3b82f6bf}.pptx-ng-spanel-action[disabled]{opacity:.3;cursor:not-allowed}.pptx-ng-spanel-footer{flex-shrink:0;padding:.5rem .375rem;border-top:1px solid rgba(255,255,255,.08)}.pptx-ng-spanel-add{display:block;width:100%;padding:.4375rem 0;border:1px dashed rgba(255,255,255,.2);border-radius:.375rem;background:transparent;color:#fff9;font-size:.75rem;cursor:pointer;transition:background .15s,border-color .15s,color .15s}.pptx-ng-spanel-add:hover{background:#3b82f626;border-color:#3b82f6;color:#e5e5e5}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "autoFit", "selectedIds", "editingId"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "rotateUpdate", "marqueeSelect"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
37125
37414
  }
37126
37415
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SlidesPanelComponent, decorators: [{
37127
37416
  type: Component,
@@ -37152,6 +37441,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
37152
37441
  [mediaDataUrls]="mediaDataUrls()"
37153
37442
  [zoom]="thumbZoom()"
37154
37443
  [editable]="false"
37444
+ [autoFit]="false"
37155
37445
  />
37156
37446
  </div>
37157
37447
  </button>
@@ -37362,9 +37652,6 @@ class PowerPointViewerComponent {
37362
37652
  /** Id of the element being inline text-edited, or null. */
37363
37653
  editingId = signal(null, /* @ts-ignore */
37364
37654
  ...(ngDevMode ? [{ debugName: "editingId" }] : /* istanbul ignore next */ []));
37365
- /** Notes for the active slide, if any. */
37366
- activeNotes = computed(() => this.activeSlide()?.notes?.trim() || '', /* @ts-ignore */
37367
- ...(ngDevMode ? [{ debugName: "activeNotes" }] : /* istanbul ignore next */ []));
37368
37655
  /**
37369
37656
  * Stable, always-truthy key for the slide-properties form. Changes only when
37370
37657
  * the active slide changes, so the `@if` recreates (and reseeds) the
@@ -37382,6 +37669,17 @@ class PowerPointViewerComponent {
37382
37669
  return this.activeSlide()?.elements.find((e) => e.id === ids[0]) ?? null;
37383
37670
  }, /* @ts-ignore */
37384
37671
  ...(ngDevMode ? [{ debugName: "selectedElement" }] : /* istanbul ignore next */ []));
37672
+ // ── Format painter ─────────────────────────────────────────────────────
37673
+ // Arm by copying the selected element's format; the next element click applies
37674
+ // it. Escape or an empty-canvas click cancels (mirrors React/Vue).
37675
+ /** True while the painter is armed (next element click applies the copied format). */
37676
+ formatPainterActive = signal(false, /* @ts-ignore */
37677
+ ...(ngDevMode ? [{ debugName: "formatPainterActive" }] : /* istanbul ignore next */ []));
37678
+ /** Format copied from the source element when the painter was armed. */
37679
+ copiedFormat = null;
37680
+ /** Whether the painter can be armed: exactly one selected element with copyable format. */
37681
+ canActivateFormatPainter = computed(() => hasCopyableFormat(this.selectedElement()), /* @ts-ignore */
37682
+ ...(ngDevMode ? [{ debugName: "canActivateFormatPainter" }] : /* istanbul ignore next */ []));
37385
37683
  constructor() {
37386
37684
  // Load whenever the `content` input changes.
37387
37685
  effect(() => {
@@ -37685,6 +37983,13 @@ class PowerPointViewerComponent {
37685
37983
  * already was, so a subsequent drag works).
37686
37984
  */
37687
37985
  onElementSelect(event) {
37986
+ // The armed format painter intercepts the next element click: apply the
37987
+ // copied format to the target, then disarm (no selection change).
37988
+ if (this.formatPainterActive()) {
37989
+ this.applyFormatToTarget(event.id);
37990
+ this.cancelFormatPainter();
37991
+ return;
37992
+ }
37688
37993
  if (event.additive) {
37689
37994
  this.editor.toggleSelect(event.id, true);
37690
37995
  }
@@ -37692,6 +37997,51 @@ class PowerPointViewerComponent {
37692
37997
  this.editor.select([event.id]);
37693
37998
  }
37694
37999
  }
38000
+ /** Empty-stage press: disarm the painter if armed, else clear the selection. */
38001
+ onBackgroundClick() {
38002
+ if (this.formatPainterActive()) {
38003
+ this.cancelFormatPainter();
38004
+ return;
38005
+ }
38006
+ this.editor.clearSelection();
38007
+ }
38008
+ /** Toggle the format painter: arm from the current selection, or disarm. */
38009
+ toggleFormatPainter() {
38010
+ if (this.formatPainterActive()) {
38011
+ this.cancelFormatPainter();
38012
+ return;
38013
+ }
38014
+ const source = this.selectedElement();
38015
+ if (!source || !hasCopyableFormat(source)) {
38016
+ return;
38017
+ }
38018
+ this.copiedFormat = copyFormatFromElement(source);
38019
+ this.formatPainterActive.set(true);
38020
+ }
38021
+ /** Disarm the painter and drop the copied format. */
38022
+ cancelFormatPainter() {
38023
+ this.formatPainterActive.set(false);
38024
+ this.copiedFormat = null;
38025
+ }
38026
+ /** Apply the copied format to a target element (shape/text style only; one history entry). */
38027
+ applyFormatToTarget(id) {
38028
+ const format = this.copiedFormat;
38029
+ const target = this.activeSlide()?.elements.find((e) => e.id === id);
38030
+ if (!format || !target) {
38031
+ return;
38032
+ }
38033
+ const updated = applyFormatToElement(target, format);
38034
+ const patch = {};
38035
+ if (format.shapeStyle && updated['shapeStyle'] !== undefined) {
38036
+ patch['shapeStyle'] = updated['shapeStyle'];
38037
+ }
38038
+ if (format.textStyle && updated['textStyle'] !== undefined) {
38039
+ patch['textStyle'] = updated['textStyle'];
38040
+ }
38041
+ if (Object.keys(patch).length > 0) {
38042
+ this.editor.updateElement(this.activeSlideIndex(), id, patch);
38043
+ }
38044
+ }
37695
38045
  /** Right-click: select the element under the cursor and open the menu. */
37696
38046
  onContextMenu(event) {
37697
38047
  if (event.id && !this.editor.isSelected(event.id)) {
@@ -37711,6 +38061,10 @@ class PowerPointViewerComponent {
37711
38061
  notes: event.target.value,
37712
38062
  });
37713
38063
  }
38064
+ /** Update the active slide's speaker notes from the editable NotesPanel. */
38065
+ onNotesUpdate(notes) {
38066
+ this.editor.updateSlide(this.activeSlideIndex(), { notes });
38067
+ }
37714
38068
  /** Commit an inline text edit: replace the element's text (one history entry). */
37715
38069
  onTextCommit(event) {
37716
38070
  this.editor.updateElement(this.activeSlideIndex(), event.id, {
@@ -37733,6 +38087,12 @@ class PowerPointViewerComponent {
37733
38087
  if (tag === 'INPUT' || tag === 'TEXTAREA' || target?.isContentEditable) {
37734
38088
  return;
37735
38089
  }
38090
+ // Escape disarms the format painter first (mirrors React/Vue).
38091
+ if (event.key === 'Escape' && this.formatPainterActive()) {
38092
+ event.preventDefault();
38093
+ this.cancelFormatPainter();
38094
+ return;
38095
+ }
37736
38096
  const mod = event.ctrlKey || event.metaKey;
37737
38097
  const idx = this.activeSlideIndex();
37738
38098
  if (mod && (event.key === 'z' || event.key === 'Z')) {
@@ -38030,6 +38390,18 @@ class PowerPointViewerComponent {
38030
38390
  >
38031
38391
  Comments
38032
38392
  </button>
38393
+ <button
38394
+ type="button"
38395
+ data-testid="format-painter-toggle"
38396
+ [class.is-active]="formatPainterActive()"
38397
+ [attr.data-active]="formatPainterActive() ? 'true' : 'false'"
38398
+ [attr.aria-pressed]="formatPainterActive()"
38399
+ [disabled]="!canActivateFormatPainter() && !formatPainterActive()"
38400
+ (click)="toggleFormatPainter()"
38401
+ aria-label="Format painter"
38402
+ >
38403
+ Format Painter
38404
+ </button>
38033
38405
  @if (selectedElement(); as el) {
38034
38406
  <button type="button" (click)="showHyperlink.set(true)" aria-label="Edit hyperlink">
38035
38407
  Link
@@ -38050,7 +38422,7 @@ class PowerPointViewerComponent {
38050
38422
  <button
38051
38423
  type="button"
38052
38424
  [class.is-active]="showNotes()"
38053
- [disabled]="!activeNotes()"
38425
+ [disabled]="slideCount() === 0"
38054
38426
  (click)="toggleNotes()"
38055
38427
  aria-label="Speaker notes"
38056
38428
  >
@@ -38155,7 +38527,7 @@ class PowerPointViewerComponent {
38155
38527
  [editable]="canEdit()"
38156
38528
  [selectedIds]="editor.selectedIds()"
38157
38529
  (elementSelect)="onElementSelect($event)"
38158
- (backgroundClick)="editor.clearSelection()"
38530
+ (backgroundClick)="onBackgroundClick()"
38159
38531
  (marqueeSelect)="editor.select($event)"
38160
38532
  (transformStart)="editor.beginTransform($event.label)"
38161
38533
  (transformUpdate)="editor.applyTransform(activeSlideIndex(), $event.id, $event.box)"
@@ -38171,10 +38543,12 @@ class PowerPointViewerComponent {
38171
38543
  @if (collab.connected()) {
38172
38544
  <pptx-collaboration-cursors [cursors]="collab.cursors()" [zoom]="zoom()" />
38173
38545
  }
38174
- @if (showNotes() && activeNotes()) {
38546
+ @if (showNotes() && !mobile.isMobile()) {
38175
38547
  <aside class="pptx-ng-notes" aria-label="Speaker notes">
38176
- <h2 class="pptx-ng-notes-title">Notes</h2>
38177
- <p class="pptx-ng-notes-body">{{ activeNotes() }}</p>
38548
+ <pptx-notes-panel
38549
+ [slide]="activeSlide()"
38550
+ (update)="onNotesUpdate($event)"
38551
+ />
38178
38552
  </aside>
38179
38553
  }
38180
38554
  </main>
@@ -38380,19 +38754,31 @@ class PowerPointViewerComponent {
38380
38754
  [activeIndex]="activeSlideIndex()"
38381
38755
  [slideCount]="slideCount()"
38382
38756
  [canPresent]="slideCount() > 0"
38757
+ [notesOpen]="showNotes()"
38383
38758
  [slidesOpen]="mobileSheet() === 'slides'"
38384
38759
  [menuOpen]="mobileSheet() === 'menu'"
38385
38760
  (prev)="goPrev()"
38386
38761
  (next)="goNext()"
38387
38762
  (present)="present()"
38763
+ (notes)="toggleNotes()"
38388
38764
  (openSorter)="showSorter.set(true)"
38389
38765
  (openFind)="showFind.set(true)"
38390
38766
  (openSlides)="mobileSheet.set(mobileSheet() === 'slides' ? null : 'slides')"
38391
38767
  (toggleMenu)="mobileSheet.set(mobileSheet() === 'menu' ? null : 'menu')"
38392
38768
  />
38769
+
38770
+ <!-- Mobile speaker-notes sheet (toggled from the bottom bar). Rendered
38771
+ inside the isMobile() gate so it stays mounted when the on-screen
38772
+ keyboard shrinks the viewport (coarse pointer keeps isMobile true) —
38773
+ mirrors the Vue mobile notes sheet. -->
38774
+ @if (showNotes()) {
38775
+ <div class="pptx-ng-mobile-notes-sheet">
38776
+ <pptx-notes-panel [slide]="activeSlide()" (update)="onNotesUpdate($event)" />
38777
+ </div>
38778
+ }
38393
38779
  }
38394
38780
  </div>
38395
- `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "selectedIds", "editingId"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "rotateUpdate", "marqueeSelect"] }, { kind: "component", type: PresentationOverlayComponent, selector: "pptx-presentation-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "startIndex"], outputs: ["indexChange", "closed"] }, { kind: "component", type: PresenterViewComponent, selector: "pptx-presenter-view", inputs: ["slides", "currentSlideIndex", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime", "isAudienceWindowOpen"], outputs: ["movePresentationSlide", "exit", "openAudienceWindow", "closeAudienceWindow"] }, { kind: "component", type: SlideSorterOverlayComponent, selector: "pptx-slide-sorter-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select", "closed"] }, { kind: "component", type: FindBarComponent, selector: "pptx-find-bar", inputs: ["slides"], outputs: ["navigate", "closed"] }, { kind: "component", type: FindReplaceBarComponent, selector: "pptx-find-replace-bar", inputs: ["matchCount", "matchIndex"], outputs: ["find", "navigate", "replaceOne", "replaceAll", "close"] }, { kind: "component", type: InspectorPanelComponent, selector: "pptx-inspector-panel", inputs: ["element", "slideIndex"] }, { kind: "component", type: SlidesPanelComponent, selector: "pptx-slides-panel", inputs: ["canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select"] }, { kind: "component", type: EditorToolbarComponent, selector: "pptx-editor-toolbar", inputs: ["slideIndex"] }, { kind: "component", type: EditorContextMenuComponent, selector: "pptx-editor-context-menu", inputs: ["x", "y", "slideIndex"], outputs: ["closed"] }, { kind: "component", type: CommentsPanelComponent, selector: "pptx-comments-panel", inputs: ["comments", "authorName"], outputs: ["add", "remove", "resolve"] }, { kind: "component", type: SignaturesPanelComponent, selector: "pptx-signatures-panel", inputs: ["signatures"] }, { kind: "component", type: AccessibilityPanelComponent, selector: "pptx-accessibility-panel", inputs: ["issues"], outputs: ["selectSlide"] }, { kind: "component", type: CollaborationCursorsComponent, selector: "pptx-collaboration-cursors", inputs: ["cursors", "zoom"] }, { kind: "component", type: PropertiesDialogComponent, selector: "pptx-properties-dialog", inputs: ["open", "properties"], outputs: ["save", "close"] }, { kind: "component", type: HyperlinkDialogComponent, selector: "pptx-hyperlink-dialog", inputs: ["open", "element"], outputs: ["save", "close"] }, { kind: "component", type: PrintDialogComponent, selector: "pptx-print-dialog", inputs: ["slides", "activeSlideIndex", "defaultSlidesPerPage", "defaultFrameSlides"], outputs: ["print", "cancel"] }, { kind: "component", type: ShareDialogComponent, selector: "pptx-share-dialog", inputs: ["open", "defaults", "active"], outputs: ["start", "stop", "close"] }, { kind: "component", type: BroadcastDialogComponent, selector: "pptx-broadcast-dialog", inputs: ["open", "defaults", "active", "viewerUrl"], outputs: ["start", "stop", "close"] }, { kind: "component", type: MobileBottomBarComponent, selector: "pptx-mobile-bottom-bar", inputs: ["activeIndex", "slideCount", "canPresent", "menuOpen", "slidesOpen"], outputs: ["prev", "next", "present", "openSorter", "openFind", "openSlides", "toggleMenu"] }, { kind: "component", type: MobileMenuSheetComponent, selector: "pptx-mobile-menu-sheet", inputs: ["open", "slideCount", "exporting", "showNotes", "canEdit"], outputs: ["closed", "openFind", "openSorter", "toggleNotes", "present", "exportPng", "exportPdf", "exportGif", "exportVideo", "print"] }, { kind: "component", type: MobileSlidesSheetComponent, selector: "pptx-mobile-slides-sheet", inputs: ["open", "slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["closed", "jumpToSlide"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
38781
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "autoFit", "selectedIds", "editingId"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "rotateUpdate", "marqueeSelect"] }, { kind: "component", type: PresentationOverlayComponent, selector: "pptx-presentation-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "startIndex"], outputs: ["indexChange", "closed"] }, { kind: "component", type: PresenterViewComponent, selector: "pptx-presenter-view", inputs: ["slides", "currentSlideIndex", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime", "isAudienceWindowOpen"], outputs: ["movePresentationSlide", "exit", "openAudienceWindow", "closeAudienceWindow"] }, { kind: "component", type: SlideSorterOverlayComponent, selector: "pptx-slide-sorter-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select", "closed"] }, { kind: "component", type: FindBarComponent, selector: "pptx-find-bar", inputs: ["slides"], outputs: ["navigate", "closed"] }, { kind: "component", type: FindReplaceBarComponent, selector: "pptx-find-replace-bar", inputs: ["matchCount", "matchIndex"], outputs: ["find", "navigate", "replaceOne", "replaceAll", "close"] }, { kind: "component", type: InspectorPanelComponent, selector: "pptx-inspector-panel", inputs: ["element", "slideIndex"] }, { kind: "component", type: SlidesPanelComponent, selector: "pptx-slides-panel", inputs: ["canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select"] }, { kind: "component", type: EditorToolbarComponent, selector: "pptx-editor-toolbar", inputs: ["slideIndex"] }, { kind: "component", type: EditorContextMenuComponent, selector: "pptx-editor-context-menu", inputs: ["x", "y", "slideIndex"], outputs: ["closed"] }, { kind: "component", type: CommentsPanelComponent, selector: "pptx-comments-panel", inputs: ["comments", "authorName"], outputs: ["add", "remove", "resolve"] }, { kind: "component", type: SignaturesPanelComponent, selector: "pptx-signatures-panel", inputs: ["signatures"] }, { kind: "component", type: AccessibilityPanelComponent, selector: "pptx-accessibility-panel", inputs: ["issues"], outputs: ["selectSlide"] }, { kind: "component", type: CollaborationCursorsComponent, selector: "pptx-collaboration-cursors", inputs: ["cursors", "zoom"] }, { kind: "component", type: PropertiesDialogComponent, selector: "pptx-properties-dialog", inputs: ["open", "properties"], outputs: ["save", "close"] }, { kind: "component", type: HyperlinkDialogComponent, selector: "pptx-hyperlink-dialog", inputs: ["open", "element"], outputs: ["save", "close"] }, { kind: "component", type: PrintDialogComponent, selector: "pptx-print-dialog", inputs: ["slides", "activeSlideIndex", "defaultSlidesPerPage", "defaultFrameSlides"], outputs: ["print", "cancel"] }, { kind: "component", type: ShareDialogComponent, selector: "pptx-share-dialog", inputs: ["open", "defaults", "active"], outputs: ["start", "stop", "close"] }, { kind: "component", type: BroadcastDialogComponent, selector: "pptx-broadcast-dialog", inputs: ["open", "defaults", "active", "viewerUrl"], outputs: ["start", "stop", "close"] }, { kind: "component", type: MobileBottomBarComponent, selector: "pptx-mobile-bottom-bar", inputs: ["activeIndex", "slideCount", "canPresent", "menuOpen", "slidesOpen", "notesOpen"], outputs: ["prev", "next", "present", "openSorter", "openFind", "notes", "openSlides", "toggleMenu"] }, { kind: "component", type: MobileMenuSheetComponent, selector: "pptx-mobile-menu-sheet", inputs: ["open", "slideCount", "exporting", "showNotes", "canEdit"], outputs: ["closed", "openFind", "openSorter", "toggleNotes", "present", "exportPng", "exportPdf", "exportGif", "exportVideo", "print"] }, { kind: "component", type: MobileSlidesSheetComponent, selector: "pptx-mobile-slides-sheet", inputs: ["open", "slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["closed", "jumpToSlide"] }, { kind: "component", type: NotesPanelComponent, selector: "pptx-notes-panel", inputs: ["slide"], outputs: ["update"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
38396
38782
  }
38397
38783
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: PowerPointViewerComponent, decorators: [{
38398
38784
  type: Component,
@@ -38435,6 +38821,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
38435
38821
  MobileBottomBarComponent,
38436
38822
  MobileMenuSheetComponent,
38437
38823
  MobileSlidesSheetComponent,
38824
+ NotesPanelComponent,
38438
38825
  ],
38439
38826
  template: `
38440
38827
  <div class="pptx-ng-viewer" [ngClass]="class()" [ngStyle]="rootStyle()">
@@ -38540,6 +38927,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
38540
38927
  >
38541
38928
  Comments
38542
38929
  </button>
38930
+ <button
38931
+ type="button"
38932
+ data-testid="format-painter-toggle"
38933
+ [class.is-active]="formatPainterActive()"
38934
+ [attr.data-active]="formatPainterActive() ? 'true' : 'false'"
38935
+ [attr.aria-pressed]="formatPainterActive()"
38936
+ [disabled]="!canActivateFormatPainter() && !formatPainterActive()"
38937
+ (click)="toggleFormatPainter()"
38938
+ aria-label="Format painter"
38939
+ >
38940
+ Format Painter
38941
+ </button>
38543
38942
  @if (selectedElement(); as el) {
38544
38943
  <button type="button" (click)="showHyperlink.set(true)" aria-label="Edit hyperlink">
38545
38944
  Link
@@ -38560,7 +38959,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
38560
38959
  <button
38561
38960
  type="button"
38562
38961
  [class.is-active]="showNotes()"
38563
- [disabled]="!activeNotes()"
38962
+ [disabled]="slideCount() === 0"
38564
38963
  (click)="toggleNotes()"
38565
38964
  aria-label="Speaker notes"
38566
38965
  >
@@ -38665,7 +39064,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
38665
39064
  [editable]="canEdit()"
38666
39065
  [selectedIds]="editor.selectedIds()"
38667
39066
  (elementSelect)="onElementSelect($event)"
38668
- (backgroundClick)="editor.clearSelection()"
39067
+ (backgroundClick)="onBackgroundClick()"
38669
39068
  (marqueeSelect)="editor.select($event)"
38670
39069
  (transformStart)="editor.beginTransform($event.label)"
38671
39070
  (transformUpdate)="editor.applyTransform(activeSlideIndex(), $event.id, $event.box)"
@@ -38681,10 +39080,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
38681
39080
  @if (collab.connected()) {
38682
39081
  <pptx-collaboration-cursors [cursors]="collab.cursors()" [zoom]="zoom()" />
38683
39082
  }
38684
- @if (showNotes() && activeNotes()) {
39083
+ @if (showNotes() && !mobile.isMobile()) {
38685
39084
  <aside class="pptx-ng-notes" aria-label="Speaker notes">
38686
- <h2 class="pptx-ng-notes-title">Notes</h2>
38687
- <p class="pptx-ng-notes-body">{{ activeNotes() }}</p>
39085
+ <pptx-notes-panel
39086
+ [slide]="activeSlide()"
39087
+ (update)="onNotesUpdate($event)"
39088
+ />
38688
39089
  </aside>
38689
39090
  }
38690
39091
  </main>
@@ -38890,16 +39291,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
38890
39291
  [activeIndex]="activeSlideIndex()"
38891
39292
  [slideCount]="slideCount()"
38892
39293
  [canPresent]="slideCount() > 0"
39294
+ [notesOpen]="showNotes()"
38893
39295
  [slidesOpen]="mobileSheet() === 'slides'"
38894
39296
  [menuOpen]="mobileSheet() === 'menu'"
38895
39297
  (prev)="goPrev()"
38896
39298
  (next)="goNext()"
38897
39299
  (present)="present()"
39300
+ (notes)="toggleNotes()"
38898
39301
  (openSorter)="showSorter.set(true)"
38899
39302
  (openFind)="showFind.set(true)"
38900
39303
  (openSlides)="mobileSheet.set(mobileSheet() === 'slides' ? null : 'slides')"
38901
39304
  (toggleMenu)="mobileSheet.set(mobileSheet() === 'menu' ? null : 'menu')"
38902
39305
  />
39306
+
39307
+ <!-- Mobile speaker-notes sheet (toggled from the bottom bar). Rendered
39308
+ inside the isMobile() gate so it stays mounted when the on-screen
39309
+ keyboard shrinks the viewport (coarse pointer keeps isMobile true) —
39310
+ mirrors the Vue mobile notes sheet. -->
39311
+ @if (showNotes()) {
39312
+ <div class="pptx-ng-mobile-notes-sheet">
39313
+ <pptx-notes-panel [slide]="activeSlide()" (update)="onNotesUpdate($event)" />
39314
+ </div>
39315
+ }
38903
39316
  }
38904
39317
  </div>
38905
39318
  `,
@@ -39298,5 +39711,5 @@ function cn(...values) {
39298
39711
  * Generated bundle index. Do not edit.
39299
39712
  */
39300
39713
 
39301
- export { AccessibilityPanelComponent, AccessibilityService, AnimationAuthorPanelComponent, 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$1 as DEFAULT_TEXT_COLOR, EMBEDDED_FONTS_STYLE_ID, EditorContextMenuComponent, EditorHistory, EditorStateService, EditorToolbarComponent, EffectsPanelComponent, ElementRendererComponent, EmbeddedFontsService, EquationRendererComponent, ExportService, FindBarComponent, FindReplaceBarComponent, GradientPickerComponent, HANDOUT_OPTIONS, HyperlinkDialogComponent, InkRendererComponent, InspectorPanelComponent, IsMobileService, LoadContentService, MobileBottomBarComponent, MobileMenuSheetComponent, MobileSheetComponent, MobileSlidesSheetComponent, ModalDialogComponent, Model3DRendererComponent, OleRendererComponent, PowerPointViewerComponent, PresentationAnnotationOverlayComponent, PresentationAnnotationsService, PresentationOverlayComponent, PresentationSubtitleBarComponent, PresentationTransitionOverlayComponent, PresenterViewComponent, PrintDialogComponent, PrintService, PrintSettingsPanelComponent, PropertiesDialogComponent, RESIZE_HANDLES, SEVERITY_GROUPS, SEVERITY_LABELS, SLIDE_TRANSITION_KEYFRAMES, SVG_WARP_PRESETS, ShareDialogComponent, SignaturesPanelComponent, SignaturesService, SlideCanvasComponent, SlideSorterOverlayComponent, SlidesPanelComponent, SmartArtRendererComponent, TYPE_LABELS$1 as 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, computeIsMobile, computeIsTablet, 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, getTextWarp, getWarpCategory, getWarpPath, 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, shouldUseSvgWarp, signatureCountLabel, signatureKey, signatureTimestamp, signerName, statusKind, statusLabel, themeStyle, themeToCssVars, toggleCommentResolvedInList, updateElementById, validatePrintSettings, validateRoomId, waypointsToPathD, worstStatus };
39714
+ export { AccessibilityPanelComponent, AccessibilityService, AnimationAuthorPanelComponent, 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$1 as DEFAULT_TEXT_COLOR, EMBEDDED_FONTS_STYLE_ID, EditorContextMenuComponent, EditorHistory, EditorStateService, EditorToolbarComponent, EffectsPanelComponent, ElementRendererComponent, EmbeddedFontsService, EquationRendererComponent, ExportService, FindBarComponent, FindReplaceBarComponent, GradientPickerComponent, HANDOUT_OPTIONS, HyperlinkDialogComponent, InkRendererComponent, InspectorPanelComponent, IsMobileService, LoadContentService, MobileBottomBarComponent, MobileMenuSheetComponent, MobileSheetComponent, MobileSlidesSheetComponent, ModalDialogComponent, Model3DRendererComponent, NotesPanelComponent, OleRendererComponent, PowerPointViewerComponent, PresentationAnnotationOverlayComponent, PresentationAnnotationsService, PresentationOverlayComponent, PresentationSubtitleBarComponent, PresentationTransitionOverlayComponent, PresenterViewComponent, PrintDialogComponent, PrintService, PrintSettingsPanelComponent, PropertiesDialogComponent, RESIZE_HANDLES, SEVERITY_GROUPS, SEVERITY_LABELS, SLIDE_TRANSITION_KEYFRAMES, SVG_WARP_PRESETS, ShareDialogComponent, SignaturesPanelComponent, SignaturesService, SlideCanvasComponent, SlideSorterOverlayComponent, SlidesPanelComponent, SmartArtRendererComponent, TYPE_LABELS$1 as TYPE_LABELS, TableDataEditorComponent, TableRendererComponent, TextAdvancedPanelComponent, VIEWER_THEME, WEBM_MIME_CANDIDATES, ZoomRendererComponent, addCommentToList, advanceStep, applyFindReplacements, applyFormatToElement, 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, computeIsMobile, computeIsTablet, computePageCount, computeSlideIndices, computeTimerProgress, convertOmmlToMathMl, copyFormatFromElement, 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, getTextWarp, getWarpCategory, getWarpPath, groupIssuesBySeverity, hasCopyableFormat, 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, shouldUseSvgWarp, signatureCountLabel, signatureKey, signatureTimestamp, signerName, statusKind, statusLabel, themeStyle, themeToCssVars, toggleCommentResolvedInList, updateElementById, validatePrintSettings, validateRoomId, waypointsToPathD, worstStatus };
39302
39715
  //# sourceMappingURL=pptx-angular-viewer.mjs.map