pptx-angular-viewer 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@ import DOMPurify from 'dompurify';
7
7
  import { z } from 'zod';
8
8
  import * as mcp from 'pptx-viewer-mcp';
9
9
  import * as mcpSchemas from 'pptx-viewer-mcp/schemas';
10
- import { LucideX, LucideSquare, LucideCircle, LucideSlash, LucideCopy, LucideTrash2, LucideChevronsUp, LucideChevronsDown, LucideArrowUp, LucideArrowDown, LucideGroup, LucideUngroup, LucideTextAlignStart, LucideTextAlignCenter, LucideTextAlignEnd, LucideChevronUp, LucideChevronDown, LucideAlignHorizontalSpaceAround, LucideAlignVerticalSpaceAround, LucideChevronRight, LucidePenTool, LucideHighlighter, LucideEraser, LucideMousePointer2, LucideChevronLeft, LucidePlay, LucideSparkles, LucidePanelRight, LucideMoveRight, LucidePencil, LucideType, LucideMinus, LucideSpline, LucideArrowLeft, LucideDownload, LucideFilePlus2, LucideFolderOpen, LucideHome, LucideInfo, LucidePrinter, LucideSave, LucideSettings, LucideShare2, LucideUpload, LucideUserRound, LucideAArrowUp, LucideAArrowDown, LucideRemoveFormatting, LucideList, LucideListOrdered, LucideListIndentDecrease, LucideListIndentIncrease, LucideTextAlignJustify, LucidePlus, LucideClipboardPaste, LucideFolderPlus, LucideLayoutGrid, LucidePaintbrush, LucideRotateCcw, LucideScissors, LucideImage, LucideVideo, LucideDatabase, LucideLayers, LucidePanelLeft, LucideMessageSquare, LucideEllipsis, LucideEye, LucideEyeOff, LucideSettings2, LucideStickyNote, LucideMonitor, LucideColumns2, LucidePresentation, LucideCheck, LucideUndo, LucideRedo, LucideSearch, LucideBug, LucideSend, LucideCrosshair, LucideGitMerge, LucidePin, LucidePinOff, LucideWrench, LucideLoaderCircle, LucideTriangleAlert, LucideShapes, LucidePalette, LucideTable, LucideLayoutTemplate, LucideChartColumn, LucideMove, LucideNavigation, LucideFilm, LucideBot, LucideUser } from '@lucide/angular';
10
+ import { LucideX, LucideSquare, LucideCircle, LucideSlash, LucideCopy, LucideTrash2, LucideChevronsUp, LucideChevronsDown, LucideArrowUp, LucideArrowDown, LucideGroup, LucideUngroup, LucideTextAlignStart, LucideTextAlignCenter, LucideTextAlignEnd, LucideChevronUp, LucideChevronDown, LucideAlignHorizontalSpaceAround, LucideAlignVerticalSpaceAround, LucideLayers, LucideMessageSquare, LucidePlus, LucideSettings2, LucideStickyNote, LucideDownload, LucideMenu, LucidePresentation, LucideRedo, LucideShare2, LucideSparkles, LucideUndo, LucideChevronRight, LucidePenTool, LucideHighlighter, LucideEraser, LucideMousePointer2, LucideChevronLeft, LucidePlay, LucidePanelRight, LucideMoveRight, LucidePencil, LucideType, LucideMinus, LucideSpline, LucideArrowLeft, LucideFilePlus2, LucideFolderOpen, LucideHome, LucideInfo, LucidePrinter, LucideSave, LucideSettings, LucideUpload, LucideUserRound, LucideAArrowUp, LucideAArrowDown, LucideRemoveFormatting, LucideList, LucideListOrdered, LucideListIndentDecrease, LucideListIndentIncrease, LucideTextAlignJustify, LucideClipboardPaste, LucideFolderPlus, LucideLayoutGrid, LucidePaintbrush, LucideRotateCcw, LucideScissors, LucideImage, LucideVideo, LucideDatabase, LucidePanelLeft, LucideEllipsis, LucideEye, LucideEyeOff, LucideMonitor, LucideColumns2, LucideCheck, LucideSearch, LucideBug, LucideSend, LucideCrosshair, LucideGitMerge, LucidePin, LucidePinOff, LucideWrench, LucideLoaderCircle, LucideTriangleAlert, LucideShapes, LucidePalette, LucideTable, LucideLayoutTemplate, LucideChartColumn, LucideMove, LucideNavigation, LucideFilm, LucideBot, LucideUser } from '@lucide/angular';
11
11
  import { DomSanitizer } from '@angular/platform-browser';
12
12
  import { jsPDF } from 'jspdf';
13
13
  import JSZip from 'jszip';
@@ -29174,7 +29174,16 @@ function reconcileComplexFields(ymap, rec, fields) {
29174
29174
  }
29175
29175
  }
29176
29176
  }
29177
- function reconcileTextBody(ymap, rec, factories) {
29177
+ /**
29178
+ * Bring `ymap.textBody` in line with `rec.textSegments`, preferring a
29179
+ * character-level in-place merge (so concurrent typing on one element
29180
+ * converges) and falling back to a wholesale Y.Text replacement.
29181
+ *
29182
+ * Exported for the live-patch channel (collaboration-live-patch.ts), which
29183
+ * writes interim editor text into the doc mid-edit and must use the exact same
29184
+ * merge path as this reconcile pass.
29185
+ */
29186
+ function reconcileElementTextBody(ymap, rec, factories) {
29178
29187
  const segments = rec.textSegments;
29179
29188
  const current = ymap.get('textBody');
29180
29189
  if (!Array.isArray(segments)) {
@@ -29202,7 +29211,7 @@ function reconcileElementYMap(ymap, element, factories, assets) {
29202
29211
  const rec = element;
29203
29212
  reconcileScalars(ymap, rec, SCALAR_ELEMENT_KEYS);
29204
29213
  reconcileComplexFields(ymap, rec, COMPLEX_ELEMENT_FIELDS);
29205
- reconcileTextBody(ymap, rec, factories);
29214
+ reconcileElementTextBody(ymap, rec, factories);
29206
29215
  reconcileAssetFields(rec.id, rec, ymap, assets);
29207
29216
  }
29208
29217
  function mapIdAt(arr, index) {
@@ -29320,6 +29329,244 @@ function reconcileSlidesInYDoc(slides, ydoc, factories, origin = LOCAL_SYNC_ORIG
29320
29329
  }, origin);
29321
29330
  }
29322
29331
 
29332
+ /**
29333
+ * collaboration-live-patch-target.ts: locating an element inside the shared
29334
+ * Y.Doc and writing one interim patch into it.
29335
+ *
29336
+ * Split out of `collaboration-live-patch.ts` (which owns the throttled patcher
29337
+ * and the binding-facing helpers) to keep both files inside the repo's 300 LOC
29338
+ * ceiling. This half is pure: given a doc it finds the element's Y.Map through
29339
+ * the existing schema and applies geometry / text, with no timers or state.
29340
+ */
29341
+ const GEOMETRY_KEYS = ['x', 'y', 'width', 'height', 'rotation'];
29342
+ /** Interim text longer than this is left to the commit path (safety valve). */
29343
+ const MAX_LIVE_TEXT_LENGTH = 100_000;
29344
+ const asMap = (value) => typeof value === 'object' && value !== null && typeof value.get === 'function'
29345
+ ? value
29346
+ : undefined;
29347
+ const asArray = (value) => typeof value === 'object' && value !== null && typeof value.get === 'function'
29348
+ ? value
29349
+ : undefined;
29350
+ /**
29351
+ * Locate an element's Y.Map through the existing schema
29352
+ * (pptx:slides -> slide Y.Map -> `elements` Y.Array -> element Y.Map).
29353
+ * When `slideId` is undefined every slide is searched.
29354
+ *
29355
+ * Only top-level `elements` are walked, so a group's children are not
29356
+ * reachable. No binding drags a group child directly today; if one starts to,
29357
+ * this walk needs to recurse into `groupElements`.
29358
+ */
29359
+ function findElementYMap(doc, slideId, elementId) {
29360
+ const slidesArr = doc.getArray(YDOC_SLIDES_KEY);
29361
+ for (let i = 0; i < slidesArr.length; i++) {
29362
+ const slideMap = asMap(slidesArr.get(i));
29363
+ if (!slideMap || (slideId !== undefined && slideMap.get('id') !== slideId)) {
29364
+ continue;
29365
+ }
29366
+ const elements = asArray(slideMap.get('elements'));
29367
+ if (!elements) {
29368
+ continue;
29369
+ }
29370
+ for (let j = 0; j < elements.length; j++) {
29371
+ const elementMap = asMap(elements.get(j));
29372
+ if (elementMap && elementMap.get('id') === elementId) {
29373
+ return elementMap;
29374
+ }
29375
+ }
29376
+ }
29377
+ return undefined;
29378
+ }
29379
+ /** Write one queued patch into the doc. Caller owns the transaction + origin. */
29380
+ function applyLivePatch(doc, factories, patch, textPatchLimit) {
29381
+ const ymap = findElementYMap(doc, patch.slideId, patch.elementId);
29382
+ if (!ymap) {
29383
+ return;
29384
+ }
29385
+ if (patch.geometry) {
29386
+ for (const key of GEOMETRY_KEYS) {
29387
+ const next = patch.geometry[key];
29388
+ if (typeof next === 'number' && ymap.get(key) !== next) {
29389
+ ymap.set(key, next);
29390
+ }
29391
+ }
29392
+ }
29393
+ if (patch.text) {
29394
+ const { value, source } = patch.text;
29395
+ if (value.length > textPatchLimit) {
29396
+ return;
29397
+ }
29398
+ if (ymap.get('text') !== value) {
29399
+ ymap.set('text', value);
29400
+ }
29401
+ const segments = remapTextToSegments(value, source.textSegments, source.textStyle);
29402
+ reconcileElementTextBody(ymap, { textSegments: segments }, factories);
29403
+ }
29404
+ }
29405
+
29406
+ /**
29407
+ * collaboration-live-patch.ts: interim ("live preview") writes straight into
29408
+ * the shared Y.Doc, bypassing each binding's slides state.
29409
+ *
29410
+ * Why: the editors deliberately keep gestures out of framework state. React's
29411
+ * drag/resize writes `style.left/top/width/height` on the DOM node and only
29412
+ * calls `updateElementById` on pointer-up; every binding's inline text editor
29413
+ * buffers the typed string and only commits it on blur. Because the Y.Doc sync
29414
+ * is driven off the slides state, remote peers saw nothing until the gesture
29415
+ * (or the edit) ended.
29416
+ *
29417
+ * This module patches the element's Y.Map directly, so the host keeps its
29418
+ * per-frame performance design while peers see the move/typing live:
29419
+ *
29420
+ * - geometry scalars (x / y / width / height / rotation) are set in place
29421
+ * - text goes through the SAME character-level Y.Text merge the reconcile
29422
+ * pass uses (`reconcileElementTextBody`), so concurrent typing on one
29423
+ * element still merges instead of last-write-wins
29424
+ * - writes are throttled (~1 per 50ms) with a trailing write, plus an
29425
+ * explicit `flush()` for gesture end
29426
+ * - every transaction is tagged with LOCAL_SYNC_ORIGIN, exactly like
29427
+ * `reconcileSlidesInYDoc`, so the local observer skips the echo
29428
+ *
29429
+ * It is a no-op until `configure()` is handed a live doc + factories, so
29430
+ * bindings can call it unconditionally.
29431
+ */
29432
+ /** Default gap between interim doc writes. */
29433
+ const LIVE_PATCH_THROTTLE_MS = 50;
29434
+ // ---------------------------------------------------------------------------
29435
+ // Patcher
29436
+ // ---------------------------------------------------------------------------
29437
+ function createCollaborationLivePatcher(options = {}) {
29438
+ const throttleMs = options.throttleMs ?? LIVE_PATCH_THROTTLE_MS;
29439
+ const pending = new Map();
29440
+ let doc = null;
29441
+ let factories = null;
29442
+ let timer = null;
29443
+ let lastWriteAt = Number.NEGATIVE_INFINITY;
29444
+ const cancelTimer = () => {
29445
+ if (timer !== null) {
29446
+ clearTimeout(timer);
29447
+ timer = null;
29448
+ }
29449
+ };
29450
+ const writePending = () => {
29451
+ const activeDoc = doc;
29452
+ const activeFactories = factories;
29453
+ if (!activeDoc || !activeFactories || pending.size === 0) {
29454
+ pending.clear();
29455
+ return;
29456
+ }
29457
+ const patches = [...pending.values()];
29458
+ pending.clear();
29459
+ lastWriteAt = Date.now();
29460
+ try {
29461
+ activeDoc.transact(() => {
29462
+ for (const patch of patches) {
29463
+ applyLivePatch(activeDoc, activeFactories, patch, MAX_LIVE_TEXT_LENGTH);
29464
+ }
29465
+ }, LOCAL_SYNC_ORIGIN);
29466
+ }
29467
+ catch {
29468
+ /* a live preview must never break the gesture it mirrors */
29469
+ }
29470
+ };
29471
+ const schedule = () => {
29472
+ if (timer !== null) {
29473
+ return;
29474
+ }
29475
+ const elapsed = Date.now() - lastWriteAt;
29476
+ if (elapsed >= throttleMs) {
29477
+ writePending();
29478
+ return;
29479
+ }
29480
+ timer = setTimeout(() => {
29481
+ timer = null;
29482
+ writePending();
29483
+ }, throttleMs - elapsed);
29484
+ };
29485
+ const enqueue = (slideId, elementId) => {
29486
+ if (!doc || !factories || !elementId) {
29487
+ return null;
29488
+ }
29489
+ const key = `${slideId ?? ''}\u0000${elementId}`;
29490
+ let entry = pending.get(key);
29491
+ if (!entry) {
29492
+ entry = { slideId, elementId };
29493
+ pending.set(key, entry);
29494
+ }
29495
+ return entry;
29496
+ };
29497
+ return {
29498
+ configure(nextDoc, nextFactories) {
29499
+ if (nextDoc === doc && nextFactories === factories) {
29500
+ return;
29501
+ }
29502
+ cancelTimer();
29503
+ pending.clear();
29504
+ doc = nextDoc;
29505
+ factories = nextFactories;
29506
+ lastWriteAt = Number.NEGATIVE_INFINITY;
29507
+ },
29508
+ isActive() {
29509
+ return doc !== null && factories !== null;
29510
+ },
29511
+ patchGeometry(slideId, elementId, geometry) {
29512
+ const entry = enqueue(slideId, elementId);
29513
+ if (!entry) {
29514
+ return;
29515
+ }
29516
+ entry.geometry = { ...entry.geometry, ...geometry };
29517
+ schedule();
29518
+ },
29519
+ patchText(slideId, elementId, text, source) {
29520
+ const entry = enqueue(slideId, elementId);
29521
+ if (!entry) {
29522
+ return;
29523
+ }
29524
+ entry.text = { value: text, source: source ?? entry.text?.source ?? {} };
29525
+ schedule();
29526
+ },
29527
+ flush() {
29528
+ cancelTimer();
29529
+ writePending();
29530
+ },
29531
+ dispose() {
29532
+ cancelTimer();
29533
+ pending.clear();
29534
+ doc = null;
29535
+ factories = null;
29536
+ },
29537
+ };
29538
+ }
29539
+ // ---------------------------------------------------------------------------
29540
+ // Binding helpers
29541
+ // ---------------------------------------------------------------------------
29542
+ /**
29543
+ * Publish the interim inline-editor text for `elementId` on `slide`. Reads the
29544
+ * element's pre-edit segments/style so the remap keeps per-run formatting (and
29545
+ * equation/field metadata). Safe to call on every keystroke: it no-ops when
29546
+ * collaboration is off, the slide/element is unknown, or the element carries no
29547
+ * text.
29548
+ */
29549
+ function publishLiveInlineText(patcher, slide, elementId, text) {
29550
+ if (!patcher || !slide || !elementId || !patcher.isActive()) {
29551
+ return;
29552
+ }
29553
+ const element = slide.elements.find((el) => el.id === elementId);
29554
+ if (!element || !hasTextProperties(element)) {
29555
+ return;
29556
+ }
29557
+ patcher.patchText(slide.id, elementId, text, {
29558
+ textSegments: element.textSegments,
29559
+ textStyle: element.textStyle,
29560
+ });
29561
+ }
29562
+ /** Publish interim geometry for `elementId` on the slide with id `slideId`. */
29563
+ function publishLiveGeometry(patcher, slideId, elementId, geometry) {
29564
+ if (!patcher || !elementId || !patcher.isActive()) {
29565
+ return;
29566
+ }
29567
+ patcher.patchGeometry(slideId, elementId, geometry);
29568
+ }
29569
+
29323
29570
  /**
29324
29571
  * collaboration-sync-gate.ts: first-write gate for collaborative sessions.
29325
29572
  *
@@ -29372,6 +29619,231 @@ function createSyncGate(onOpen, graceMs = INITIAL_SYNC_GRACE_MS) {
29372
29619
  };
29373
29620
  }
29374
29621
 
29622
+ /**
29623
+ * collaboration-teardown.ts: make a departing peer actually leave the room.
29624
+ *
29625
+ * Every binding tears its collaboration session down on component unmount, but
29626
+ * that path never runs when the *document* goes away: closing the tab,
29627
+ * navigating away, or (the case that motivated this module) an embedding page
29628
+ * removing the viewer's `<iframe>` outright. y-webrtc installs its own
29629
+ * `beforeunload` handler, but `beforeunload` is only fired by the
29630
+ * "prompt to unload" algorithm during a navigation; destroying a document by
29631
+ * detaching its frame fires `pagehide`/`unload` and never `beforeunload`. The
29632
+ * peer therefore keeps its awareness entry until the 30s awareness timeout,
29633
+ * which reads as a ghost collaborator in everyone else's presence list.
29634
+ *
29635
+ * This helper registers the missing listeners once per session:
29636
+ * - `pagehide` (the reliable signal, and the only one mobile Safari honours),
29637
+ * - `beforeunload` (belt and braces for the plain navigation case),
29638
+ * - a `postMessage` from an embedding page (see {@link COLLAB_LEAVE_MESSAGE}),
29639
+ * so a host that is about to destroy the frame can ask it to leave first
29640
+ * instead of relying on the unload path alone.
29641
+ *
29642
+ * A `pagehide` with `persisted === true` means the document went into the
29643
+ * back/forward cache and may come back. We only leave in that case when the
29644
+ * caller supplied a `rejoin`, and then rejoin from `pageshow`.
29645
+ *
29646
+ * The window is injected (structurally typed) so bindings can unit-test the
29647
+ * behaviour without a DOM.
29648
+ */
29649
+ /**
29650
+ * `postMessage` payload an embedding page can send into a viewer frame to make
29651
+ * it leave its collaboration room before the frame is destroyed:
29652
+ * `frame.contentWindow?.postMessage({ type: COLLAB_LEAVE_MESSAGE }, '*')`.
29653
+ */
29654
+ const COLLAB_LEAVE_MESSAGE = 'pptx-viewer:collab-leave';
29655
+ /** Resolve the listener target without depending on DOM lib types. */
29656
+ function resolveTarget(target) {
29657
+ if (target) {
29658
+ return target;
29659
+ }
29660
+ const scope = globalThis;
29661
+ return scope.window ?? null;
29662
+ }
29663
+ /** Whether a `message` event carries the leave request. */
29664
+ function isLeaveMessage(data) {
29665
+ if (typeof data === 'string') {
29666
+ return data === COLLAB_LEAVE_MESSAGE;
29667
+ }
29668
+ if (typeof data !== 'object' || data === null) {
29669
+ return false;
29670
+ }
29671
+ return data.type === COLLAB_LEAVE_MESSAGE;
29672
+ }
29673
+ /**
29674
+ * Register document-teardown listeners that make the local peer leave its
29675
+ * collaboration room. Returns a disposer that removes them again; call it from
29676
+ * the binding's normal unmount cleanup (which performs its own teardown).
29677
+ *
29678
+ * Safe to call in a non-browser environment: it becomes a no-op disposer.
29679
+ */
29680
+ function registerCollaborationTeardown(options) {
29681
+ const target = resolveTarget(options.target);
29682
+ if (!target) {
29683
+ return () => { };
29684
+ }
29685
+ const { leave, rejoin } = options;
29686
+ let left = false;
29687
+ const doLeave = () => {
29688
+ if (left) {
29689
+ return;
29690
+ }
29691
+ left = true;
29692
+ leave();
29693
+ };
29694
+ const onPageHide = (event) => {
29695
+ if (event.persisted === true && !rejoin) {
29696
+ // Bfcache'd with no way back into the room: keep the session so the
29697
+ // restored page keeps working rather than silently going offline.
29698
+ return;
29699
+ }
29700
+ doLeave();
29701
+ };
29702
+ const onBeforeUnload = () => {
29703
+ doLeave();
29704
+ };
29705
+ const onPageShow = (event) => {
29706
+ if (event.persisted !== true || !left || !rejoin) {
29707
+ return;
29708
+ }
29709
+ left = false;
29710
+ rejoin();
29711
+ };
29712
+ const onMessage = (event) => {
29713
+ if (isLeaveMessage(event.data)) {
29714
+ doLeave();
29715
+ }
29716
+ };
29717
+ target.addEventListener('pagehide', onPageHide);
29718
+ target.addEventListener('beforeunload', onBeforeUnload);
29719
+ target.addEventListener('pageshow', onPageShow);
29720
+ target.addEventListener('message', onMessage);
29721
+ return () => {
29722
+ target.removeEventListener('pagehide', onPageHide);
29723
+ target.removeEventListener('beforeunload', onBeforeUnload);
29724
+ target.removeEventListener('pageshow', onPageShow);
29725
+ target.removeEventListener('message', onMessage);
29726
+ };
29727
+ }
29728
+ /**
29729
+ * Withdraw the local awareness state so peers drop us immediately instead of
29730
+ * waiting out the 30s awareness timeout. Yjs broadcasts the resulting `removed`
29731
+ * update through the still-open transport, so call this BEFORE destroying the
29732
+ * provider.
29733
+ */
29734
+ function clearLocalAwareness(awareness) {
29735
+ awareness?.setLocalState?.(null);
29736
+ }
29737
+
29738
+ /**
29739
+ * collaboration-departure.ts: a synchronous "I am leaving" announcement.
29740
+ *
29741
+ * Destroying a Yjs provider is NOT enough to make a peer disappear when the
29742
+ * document itself is going away (tab close, navigation, or an embedding page
29743
+ * detaching the viewer's iframe):
29744
+ *
29745
+ * - y-webrtc broadcasts the awareness removal through
29746
+ * `cryptoutils.encrypt(...).then(...)`, i.e. always one microtask later. By
29747
+ * then the detached frame's BroadcastChannel / RTCDataChannel are dead and
29748
+ * the browser silently drops the message.
29749
+ * - y-webrtc's `peer.on('close')` handler does not remove the peer's awareness
29750
+ * state either, so surviving peers keep the entry until the 30s awareness
29751
+ * timeout: a ghost collaborator in every presence list.
29752
+ *
29753
+ * This module closes that window for the same-browser case (which is exactly
29754
+ * the embedded-iframe case) with a plain BroadcastChannel `postMessage` issued
29755
+ * SYNCHRONOUSLY from the teardown path, which the browser does deliver even
29756
+ * from a document that is being destroyed. Every live session listens on the
29757
+ * same channel and drops the announced client from its own awareness at once.
29758
+ *
29759
+ * Cross-device peers are unaffected by this channel and still rely on the
29760
+ * transport (socket close / peer close plus the awareness timeout).
29761
+ */
29762
+ /** BroadcastChannel name shared by every viewer session in the browser. */
29763
+ const DEPARTURE_CHANNEL = 'pptx-viewer:collab-departures';
29764
+ /**
29765
+ * Drop `clients` from `awareness` locally and notify its observers, mirroring
29766
+ * `y-protocols`' `removeAwarenessStates` for remote clients (the local-client
29767
+ * clock bump is not needed here: we never announce ourselves to ourselves).
29768
+ */
29769
+ function removeAwarenessStatesLocally(awareness, clients) {
29770
+ const states = awareness?.states;
29771
+ if (!awareness || !states) {
29772
+ return [];
29773
+ }
29774
+ const removed = [];
29775
+ for (const clientId of clients) {
29776
+ if (states.delete(clientId)) {
29777
+ removed.push(clientId);
29778
+ }
29779
+ }
29780
+ if (removed.length > 0) {
29781
+ const change = { added: [], updated: [], removed };
29782
+ awareness.emit?.('change', [change, 'peer-departed']);
29783
+ awareness.emit?.('update', [change, 'peer-departed']);
29784
+ }
29785
+ return removed;
29786
+ }
29787
+ /** Whether `data` is a departure notice for a different client in `roomId`. */
29788
+ function readNotice(data, roomId, selfId) {
29789
+ if (typeof data !== 'object' || data === null) {
29790
+ return null;
29791
+ }
29792
+ const notice = data;
29793
+ if (notice.channel !== DEPARTURE_CHANNEL || notice.roomId !== roomId) {
29794
+ return null;
29795
+ }
29796
+ if (typeof notice.clientId !== 'number' || notice.clientId === selfId) {
29797
+ return null;
29798
+ }
29799
+ return notice.clientId;
29800
+ }
29801
+ function defaultFactory(name) {
29802
+ const scope = globalThis;
29803
+ if (!scope.BroadcastChannel) {
29804
+ return null;
29805
+ }
29806
+ return new scope.BroadcastChannel(name);
29807
+ }
29808
+ /**
29809
+ * Open the departure channel for one collaboration session: listens for peers
29810
+ * announcing their exit (dropping them from `awareness` immediately) and
29811
+ * exposes {@link DepartureChannel.announce} for our own exit.
29812
+ *
29813
+ * Returns a no-op channel where `BroadcastChannel` is unavailable (SSR, older
29814
+ * runtimes), so callers never need to guard.
29815
+ */
29816
+ function createDepartureChannel(roomId, awareness, factory) {
29817
+ const channel = factory ? factory(DEPARTURE_CHANNEL) : defaultFactory(DEPARTURE_CHANNEL);
29818
+ if (!channel) {
29819
+ return { announce: () => { }, dispose: () => { } };
29820
+ }
29821
+ const selfId = awareness.clientID;
29822
+ channel.onmessage = (event) => {
29823
+ const departed = readNotice(event.data, roomId, selfId);
29824
+ if (departed !== null) {
29825
+ removeAwarenessStatesLocally(awareness, [departed]);
29826
+ }
29827
+ };
29828
+ let closed = false;
29829
+ return {
29830
+ announce: () => {
29831
+ if (closed || typeof selfId !== 'number') {
29832
+ return;
29833
+ }
29834
+ channel.postMessage({ channel: DEPARTURE_CHANNEL, roomId, clientId: selfId });
29835
+ },
29836
+ dispose: () => {
29837
+ if (closed) {
29838
+ return;
29839
+ }
29840
+ closed = true;
29841
+ channel.onmessage = null;
29842
+ channel.close();
29843
+ },
29844
+ };
29845
+ }
29846
+
29375
29847
  const DEFAULT_DEBOUNCE_MS = 5_000;
29376
29848
  function createWriteBackScheduler(deps) {
29377
29849
  let timer = null;
@@ -51271,7 +51743,7 @@ function createLocalStorageBackend(namespace) {
51271
51743
  /** Try IndexedDB first; fall back to localStorage on any failure. */
51272
51744
  async function resolveBackend(dbName, namespace) {
51273
51745
  try {
51274
- const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-OWtthCqn.mjs');
51746
+ const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-DuJ08L_k.mjs');
51275
51747
  const db = await openChatDb(dbName);
51276
51748
  return createIdbBackend(db);
51277
51749
  }
@@ -53579,7 +54051,13 @@ async function createWebsocketBundle(config) {
53579
54051
  import('y-websocket'),
53580
54052
  ]);
53581
54053
  const provider = new yws.WebsocketProvider(config.serverUrl, config.roomId, doc, config.authToken ? { params: { token: config.authToken } } : undefined);
53582
- return { doc, provider, awareness: provider.awareness, factories };
54054
+ return {
54055
+ doc,
54056
+ provider,
54057
+ awareness: provider.awareness,
54058
+ factories,
54059
+ departure: createDepartureChannel(config.roomId, provider.awareness),
54060
+ };
53583
54061
  }
53584
54062
  /**
53585
54063
  * Create a y-webrtc (peer-to-peer, serverless) transport bundle for `config`.
@@ -53596,7 +54074,13 @@ async function createWebrtcBundle(config) {
53596
54074
  signaling: config.signaling?.length ? config.signaling : undefined,
53597
54075
  password: config.authToken || undefined,
53598
54076
  });
53599
- return { doc, provider, awareness: provider.awareness, factories };
54077
+ return {
54078
+ doc,
54079
+ provider,
54080
+ awareness: provider.awareness,
54081
+ factories,
54082
+ departure: createDepartureChannel(config.roomId, provider.awareness),
54083
+ };
53600
54084
  }
53601
54085
 
53602
54086
  /**
@@ -53766,10 +54250,17 @@ class CollaborationService {
53766
54250
  /** Active-slide index of the first `owner` peer (the broadcaster), or null. */
53767
54251
  broadcasterSlideIndex = computed(() => this.presence().find((p) => p.role === 'owner')?.activeSlideIndex ?? null, /* @ts-ignore */
53768
54252
  ...(ngDevMode ? [{ debugName: "broadcasterSlideIndex" }] : /* istanbul ignore next */ []));
54253
+ /**
54254
+ * Interim ("live preview") Y.Doc write channel: publishes in-flight inline
54255
+ * editor text that has not reached the slides state yet, so peers see typing
54256
+ * as it happens instead of on commit. Dormant outside a session.
54257
+ */
54258
+ livePatcher = createCollaborationLivePatcher();
53769
54259
  // Internal handles
53770
54260
  ydoc = null;
53771
54261
  provider = null;
53772
54262
  awareness = null;
54263
+ departure = null;
53773
54264
  selfId = -1;
53774
54265
  applyingRemote = false;
53775
54266
  yFactories = null;
@@ -53794,6 +54285,14 @@ class CollaborationService {
53794
54285
  lastConfig = null;
53795
54286
  lastOptions = {};
53796
54287
  localPresence = null;
54288
+ /**
54289
+ * Reentrancy token for {@link connect}: bumped by every connect() and
54290
+ * disconnect(). A connect() whose token no longer matches after an await was
54291
+ * superseded, so it tears down whatever it just created and leaves the
54292
+ * service state to the newer call (a second provider join on the same room
54293
+ * would otherwise throw inside Yjs and kill the surviving session).
54294
+ */
54295
+ connectToken = 0;
53797
54296
  refreshPresence = () => {
53798
54297
  if (!this.awareness) {
53799
54298
  this.presence.set([]);
@@ -53802,10 +54301,22 @@ class CollaborationService {
53802
54301
  this.presence.set(derivePresenceList(this.awareness.getStates(), this.selfId, this.canvasWidth, this.canvasHeight));
53803
54302
  };
53804
54303
  constructor() {
53805
- inject(DestroyRef).onDestroy(() => this.disconnect());
54304
+ // Service destruction is not the only way a session ends: a tab close, a
54305
+ // navigation, or an embedding page detaching the viewer's iframe destroys
54306
+ // the document without running Angular teardown, leaving a ghost peer in
54307
+ // everyone else's presence list. Leave the room from `pagehide` too.
54308
+ const disposeTeardown = registerCollaborationTeardown({
54309
+ leave: () => this.disconnect(),
54310
+ rejoin: () => void this.retry(),
54311
+ });
54312
+ inject(DestroyRef).onDestroy(() => {
54313
+ disposeTeardown();
54314
+ this.disconnect();
54315
+ });
53806
54316
  }
53807
54317
  async connect(config, options = {}) {
53808
54318
  this.disconnect();
54319
+ const token = ++this.connectToken;
53809
54320
  this.lastConfig = config;
53810
54321
  this.lastOptions = options;
53811
54322
  try {
@@ -53838,8 +54349,20 @@ class CollaborationService {
53838
54349
  const bundle = transport === 'webrtc'
53839
54350
  ? await createWebrtcBundle(config)
53840
54351
  : await createWebsocketBundle(config);
54352
+ if (token !== this.connectToken) {
54353
+ // Superseded by a newer connect() or a disconnect() while awaiting
54354
+ // the transport: destroy the just-created bundle and bail without
54355
+ // touching the (newer call's) service state.
54356
+ bundle.departure.dispose();
54357
+ bundle.provider.disconnect();
54358
+ bundle.provider.destroy();
54359
+ bundle.doc.destroy();
54360
+ return;
54361
+ }
54362
+ this.departure = bundle.departure;
53841
54363
  this.ydoc = bundle.doc;
53842
54364
  this.yFactories = bundle.factories;
54365
+ this.livePatcher.configure(bundle.doc, bundle.factories);
53843
54366
  this.provider = bundle.provider;
53844
54367
  this.awareness = bundle.awareness;
53845
54368
  this.selfId = this.awareness.clientID ?? -1;
@@ -53860,6 +54383,10 @@ class CollaborationService {
53860
54383
  this.refreshPresence();
53861
54384
  }
53862
54385
  catch {
54386
+ if (token !== this.connectToken) {
54387
+ // A newer connect() owns the service state; do not tear it down.
54388
+ return;
54389
+ }
53863
54390
  this.disconnect();
53864
54391
  this.status.set('error');
53865
54392
  }
@@ -53980,6 +54507,8 @@ class CollaborationService {
53980
54507
  this.scheduleWriteBack();
53981
54508
  }
53982
54509
  disconnect() {
54510
+ // Invalidate any in-flight connect() so it discards its bundle on resume.
54511
+ this.connectToken += 1;
53983
54512
  this.clearConnectTimer();
53984
54513
  this.syncGate.reset();
53985
54514
  this.pendingBroadcast = null;
@@ -53988,6 +54517,15 @@ class CollaborationService {
53988
54517
  this.unobserveSlides = null;
53989
54518
  this.awareness?.off?.('change', this.refreshPresence);
53990
54519
  this.awareness?.off?.('update', this.refreshPresence);
54520
+ // Announce first: it is synchronous, so it still reaches same-browser
54521
+ // peers when this runs from a document that is being destroyed. The
54522
+ // provider's own awareness removal is broadcast a microtask later and
54523
+ // would be dropped, leaving us a ghost collaborator until the 30s
54524
+ // awareness timeout.
54525
+ this.departure?.announce();
54526
+ this.departure?.dispose();
54527
+ this.departure = null;
54528
+ clearLocalAwareness(this.awareness);
53991
54529
  this.provider?.disconnect();
53992
54530
  this.provider?.destroy();
53993
54531
  this.ydoc?.destroy();
@@ -53998,6 +54536,7 @@ class CollaborationService {
53998
54536
  this.selfId = -1;
53999
54537
  this.applyingRemote = false;
54000
54538
  this.yFactories = null;
54539
+ this.livePatcher.configure(null, null);
54001
54540
  this.lastSynced = '';
54002
54541
  this.onRemoteSlides = null;
54003
54542
  this.currentConfig = null;
@@ -68536,6 +69075,12 @@ class SlideCanvasComponent {
68536
69075
  textEditStart = output();
68537
69076
  /** Emitted with the new text when an inline edit commits. */
68538
69077
  textCommit = output();
69078
+ /**
69079
+ * Emitted on EVERY keystroke while inline-editing. The commit path stays the
69080
+ * only thing that touches editor state/history; this feeds the collaboration
69081
+ * live preview so peers see typing before the edit commits.
69082
+ */
69083
+ textInput = output();
68539
69084
  /** Emitted when an inline edit is cancelled (Escape). */
68540
69085
  textCancel = output();
68541
69086
  /** Emitted on Ctrl/Cmd+B/I/U while inline-editing (parity with React/Vue). */
@@ -68923,6 +69468,10 @@ class SlideCanvasComponent {
68923
69468
  : { underline: !ts?.underline };
68924
69469
  this.textFormat.emit({ id, updates });
68925
69470
  }
69471
+ /** Mirror each keystroke out for the collaboration live preview. */
69472
+ onTextInput(event, id) {
69473
+ this.textInput.emit({ id, text: event.target.value });
69474
+ }
68926
69475
  commitText(event, id) {
68927
69476
  if (this.editCancelled) {
68928
69477
  this.editCancelled = false;
@@ -69252,7 +69801,7 @@ class SlideCanvasComponent {
69252
69801
  }, /* @ts-ignore */
69253
69802
  ...(ngDevMode ? [{ debugName: "stageStyle" }] : /* istanbul ignore next */ []));
69254
69803
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SlideCanvasComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
69255
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", 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 }, showGrid: { classPropertyName: "showGrid", publicName: "showGrid", isSignal: true, isRequired: false, transformFunction: null }, showRulers: { classPropertyName: "showRulers", publicName: "showRulers", isSignal: true, isRequired: false, transformFunction: null }, showGuides: { classPropertyName: "showGuides", publicName: "showGuides", isSignal: true, isRequired: false, transformFunction: null }, snapToGrid: { classPropertyName: "snapToGrid", publicName: "snapToGrid", isSignal: true, isRequired: false, transformFunction: null }, snapToShape: { classPropertyName: "snapToShape", publicName: "snapToShape", isSignal: true, isRequired: false, transformFunction: null }, guideCommand: { classPropertyName: "guideCommand", publicName: "guideCommand", isSignal: true, isRequired: false, transformFunction: null }, spellCheck: { classPropertyName: "spellCheck", publicName: "spellCheck", isSignal: true, isRequired: false, transformFunction: null }, snapToGuides: { classPropertyName: "snapToGuides", publicName: "snapToGuides", isSignal: true, isRequired: false, transformFunction: null }, autoFit: { classPropertyName: "autoFit", publicName: "autoFit", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, presenting: { classPropertyName: "presenting", publicName: "presenting", 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 }, editTemplateMode: { classPropertyName: "editTemplateMode", publicName: "editTemplateMode", isSignal: true, isRequired: false, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, aiHighlights: { classPropertyName: "aiHighlights", publicName: "aiHighlights", isSignal: true, isRequired: false, transformFunction: null }, aiActive: { classPropertyName: "aiActive", publicName: "aiActive", isSignal: true, isRequired: false, transformFunction: null }, aiActiveSlideIndex: { classPropertyName: "aiActiveSlideIndex", publicName: "aiActiveSlideIndex", isSignal: true, isRequired: false, transformFunction: null }, aiChangeBatch: { classPropertyName: "aiChangeBatch", publicName: "aiChangeBatch", isSignal: true, isRequired: false, transformFunction: null }, aiPickMode: { classPropertyName: "aiPickMode", publicName: "aiPickMode", isSignal: true, isRequired: false, transformFunction: null }, drawTool: { classPropertyName: "drawTool", publicName: "drawTool", isSignal: true, isRequired: false, transformFunction: null }, drawColor: { classPropertyName: "drawColor", publicName: "drawColor", isSignal: true, isRequired: false, transformFunction: null }, drawWidth: { classPropertyName: "drawWidth", publicName: "drawWidth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { elementSelect: "elementSelect", backgroundClick: "backgroundClick", transformStart: "transformStart", transformUpdate: "transformUpdate", contextMenu: "contextMenu", textEditStart: "textEditStart", textCommit: "textCommit", textCancel: "textCancel", textFormat: "textFormat", rotateUpdate: "rotateUpdate", marqueeSelect: "marqueeSelect", inkStrokeComplete: "inkStrokeComplete", eraserHit: "eraserHit", cellCommit: "cellCommit", tableChange: "tableChange" }, host: { listeners: { "document:pointermove": "onPointerMove($event)", "document:pointerup": "onPointerUp()" } }, providers: [
69804
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", 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 }, showGrid: { classPropertyName: "showGrid", publicName: "showGrid", isSignal: true, isRequired: false, transformFunction: null }, showRulers: { classPropertyName: "showRulers", publicName: "showRulers", isSignal: true, isRequired: false, transformFunction: null }, showGuides: { classPropertyName: "showGuides", publicName: "showGuides", isSignal: true, isRequired: false, transformFunction: null }, snapToGrid: { classPropertyName: "snapToGrid", publicName: "snapToGrid", isSignal: true, isRequired: false, transformFunction: null }, snapToShape: { classPropertyName: "snapToShape", publicName: "snapToShape", isSignal: true, isRequired: false, transformFunction: null }, guideCommand: { classPropertyName: "guideCommand", publicName: "guideCommand", isSignal: true, isRequired: false, transformFunction: null }, spellCheck: { classPropertyName: "spellCheck", publicName: "spellCheck", isSignal: true, isRequired: false, transformFunction: null }, snapToGuides: { classPropertyName: "snapToGuides", publicName: "snapToGuides", isSignal: true, isRequired: false, transformFunction: null }, autoFit: { classPropertyName: "autoFit", publicName: "autoFit", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, presenting: { classPropertyName: "presenting", publicName: "presenting", 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 }, editTemplateMode: { classPropertyName: "editTemplateMode", publicName: "editTemplateMode", isSignal: true, isRequired: false, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, aiHighlights: { classPropertyName: "aiHighlights", publicName: "aiHighlights", isSignal: true, isRequired: false, transformFunction: null }, aiActive: { classPropertyName: "aiActive", publicName: "aiActive", isSignal: true, isRequired: false, transformFunction: null }, aiActiveSlideIndex: { classPropertyName: "aiActiveSlideIndex", publicName: "aiActiveSlideIndex", isSignal: true, isRequired: false, transformFunction: null }, aiChangeBatch: { classPropertyName: "aiChangeBatch", publicName: "aiChangeBatch", isSignal: true, isRequired: false, transformFunction: null }, aiPickMode: { classPropertyName: "aiPickMode", publicName: "aiPickMode", isSignal: true, isRequired: false, transformFunction: null }, drawTool: { classPropertyName: "drawTool", publicName: "drawTool", isSignal: true, isRequired: false, transformFunction: null }, drawColor: { classPropertyName: "drawColor", publicName: "drawColor", isSignal: true, isRequired: false, transformFunction: null }, drawWidth: { classPropertyName: "drawWidth", publicName: "drawWidth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { elementSelect: "elementSelect", backgroundClick: "backgroundClick", transformStart: "transformStart", transformUpdate: "transformUpdate", contextMenu: "contextMenu", textEditStart: "textEditStart", textCommit: "textCommit", textInput: "textInput", textCancel: "textCancel", textFormat: "textFormat", rotateUpdate: "rotateUpdate", marqueeSelect: "marqueeSelect", inkStrokeComplete: "inkStrokeComplete", eraserHit: "eraserHit", cellCommit: "cellCommit", tableChange: "tableChange" }, host: { listeners: { "document:pointermove": "onPointerMove($event)", "document:pointerup": "onPointerUp()" } }, providers: [
69256
69805
  CanvasFitService,
69257
69806
  InkDrawingService,
69258
69807
  RulerGuidesService,
@@ -69417,6 +69966,7 @@ class SlideCanvasComponent {
69417
69966
  [style.width.px]="eb.width"
69418
69967
  [style.height.px]="eb.height"
69419
69968
  (pointerdown)="$event.stopPropagation()"
69969
+ (input)="onTextInput($event, eb.id)"
69420
69970
  (blur)="commitText($event, eb.id)"
69421
69971
  (keydown)="onEditorKeydown($event)"
69422
69972
  ></textarea>
@@ -69824,6 +70374,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
69824
70374
  [style.width.px]="eb.width"
69825
70375
  [style.height.px]="eb.height"
69826
70376
  (pointerdown)="$event.stopPropagation()"
70377
+ (input)="onTextInput($event, eb.id)"
69827
70378
  (blur)="commitText($event, eb.id)"
69828
70379
  (keydown)="onEditorKeydown($event)"
69829
70380
  ></textarea>
@@ -70057,7 +70608,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
70057
70608
  </div>
70058
70609
  </div>
70059
70610
  `, styles: [".pptx-ng-canvas-stage.is-editable{touch-action:none}\n"] }]
70060
- }], 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 }] }], showGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGrid", required: false }] }], showRulers: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRulers", required: false }] }], showGuides: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGuides", required: false }] }], snapToGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToGrid", required: false }] }], snapToShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToShape", required: false }] }], guideCommand: [{ type: i0.Input, args: [{ isSignal: true, alias: "guideCommand", required: false }] }], spellCheck: [{ type: i0.Input, args: [{ isSignal: true, alias: "spellCheck", required: false }] }], snapToGuides: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToGuides", required: false }] }], autoFit: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFit", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], presenting: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenting", required: false }] }], selectedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIds", required: false }] }], editingId: [{ type: i0.Input, args: [{ isSignal: true, alias: "editingId", required: false }] }], editTemplateMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "editTemplateMode", required: false }] }], templateElements: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateElements", required: false }] }], aiHighlights: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiHighlights", required: false }] }], aiActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiActive", required: false }] }], aiActiveSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiActiveSlideIndex", required: false }] }], aiChangeBatch: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiChangeBatch", required: false }] }], aiPickMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiPickMode", required: false }] }], drawTool: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawTool", required: false }] }], drawColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawColor", required: false }] }], drawWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawWidth", 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"] }], textFormat: [{ type: i0.Output, args: ["textFormat"] }], rotateUpdate: [{ type: i0.Output, args: ["rotateUpdate"] }], marqueeSelect: [{ type: i0.Output, args: ["marqueeSelect"] }], inkStrokeComplete: [{ type: i0.Output, args: ["inkStrokeComplete"] }], eraserHit: [{ type: i0.Output, args: ["eraserHit"] }], cellCommit: [{ type: i0.Output, args: ["cellCommit"] }], tableChange: [{ type: i0.Output, args: ["tableChange"] }], 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: [{
70611
+ }], 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 }] }], showGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGrid", required: false }] }], showRulers: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRulers", required: false }] }], showGuides: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGuides", required: false }] }], snapToGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToGrid", required: false }] }], snapToShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToShape", required: false }] }], guideCommand: [{ type: i0.Input, args: [{ isSignal: true, alias: "guideCommand", required: false }] }], spellCheck: [{ type: i0.Input, args: [{ isSignal: true, alias: "spellCheck", required: false }] }], snapToGuides: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToGuides", required: false }] }], autoFit: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFit", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], presenting: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenting", required: false }] }], selectedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIds", required: false }] }], editingId: [{ type: i0.Input, args: [{ isSignal: true, alias: "editingId", required: false }] }], editTemplateMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "editTemplateMode", required: false }] }], templateElements: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateElements", required: false }] }], aiHighlights: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiHighlights", required: false }] }], aiActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiActive", required: false }] }], aiActiveSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiActiveSlideIndex", required: false }] }], aiChangeBatch: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiChangeBatch", required: false }] }], aiPickMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiPickMode", required: false }] }], drawTool: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawTool", required: false }] }], drawColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawColor", required: false }] }], drawWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawWidth", 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"] }], textInput: [{ type: i0.Output, args: ["textInput"] }], textCancel: [{ type: i0.Output, args: ["textCancel"] }], textFormat: [{ type: i0.Output, args: ["textFormat"] }], rotateUpdate: [{ type: i0.Output, args: ["rotateUpdate"] }], marqueeSelect: [{ type: i0.Output, args: ["marqueeSelect"] }], inkStrokeComplete: [{ type: i0.Output, args: ["inkStrokeComplete"] }], eraserHit: [{ type: i0.Output, args: ["eraserHit"] }], cellCommit: [{ type: i0.Output, args: ["cellCommit"] }], tableChange: [{ type: i0.Output, args: ["tableChange"] }], 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: [{
70061
70612
  type: HostListener,
70062
70613
  args: ['document:pointermove', ['$event']]
70063
70614
  }], onPointerUp: [{
@@ -70197,7 +70748,7 @@ class MasterViewCanvasComponent {
70197
70748
  <p class="empty">No master is available.</p>
70198
70749
  }
70199
70750
  </main>
70200
- `, isInline: true, styles: [".master-canvas{display:flex;min-width:0;flex:1;overflow:hidden;background:var(--pptx-background, #11111b)}pptx-slide-canvas{display:flex;min-width:0;flex:1}.empty{margin:auto;color:var(--pptx-muted-foreground, #a5a5b5)}\n"], dependencies: [{ kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
70751
+ `, isInline: true, styles: [".master-canvas{display:flex;min-width:0;flex:1;overflow:hidden;background:var(--pptx-background, #11111b)}pptx-slide-canvas{display:flex;min-width:0;flex:1}.empty{margin:auto;color:var(--pptx-muted-foreground, #a5a5b5)}\n"], dependencies: [{ kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
70201
70752
  }
70202
70753
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MasterViewCanvasComponent, decorators: [{
70203
70754
  type: Component,
@@ -70393,17 +70944,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
70393
70944
  * framework-neutral accessibility contract the e2e specs assert against
70394
70945
  * (`getByRole('navigation', { name: 'Editor actions' })`).
70395
70946
  *
70396
- * Inputs
70397
- * slideCount : total number of slides (gates Slides/Format/Insert)
70398
- * commentCount : number of comments on the active slide (badge)
70399
- * activeSheet : currently-active sheet, for highlighting the bar button
70400
- *
70401
- * Outputs
70402
- * openSlides : user tapped the Slides button
70403
- * insert : user tapped the Insert button
70404
- * openFormat : user tapped the Format button
70405
- * openComments : user tapped the Comments button
70406
- * notes : user tapped the Notes button
70947
+ * Icons and colours come from the same Lucide glyphs and `--pptx-*` theme
70948
+ * tokens React uses. Each input/output is documented on its declaration below.
70407
70949
  */
70408
70950
  class MobileBottomBarComponent {
70409
70951
  // ── Inputs ────────────────────────────────────────────────────────────────
@@ -70436,8 +70978,6 @@ class MobileBottomBarComponent {
70436
70978
  {
70437
70979
  key: 'slides',
70438
70980
  labelKey: 'pptx.sections.slides',
70439
- // Layers icon
70440
- svgPath: 'M12 2L2 7l10 5 10-5-10-5z M2 17l10 5 10-5 M2 12l10 5 10-5',
70441
70981
  disabled: noSlides,
70442
70982
  active: active === 'slides',
70443
70983
  emit: () => this.openSlides.emit(),
@@ -70445,8 +70985,6 @@ class MobileBottomBarComponent {
70445
70985
  {
70446
70986
  key: 'insert',
70447
70987
  labelKey: 'pptx.editorToolbar.insert',
70448
- // Plus icon
70449
- svgPath: 'M12 5v14 M5 12h14',
70450
70988
  disabled: noSlides,
70451
70989
  active: false,
70452
70990
  emit: () => this.insert.emit(),
@@ -70454,8 +70992,6 @@ class MobileBottomBarComponent {
70454
70992
  {
70455
70993
  key: 'inspector',
70456
70994
  labelKey: 'pptx.arrange.format',
70457
- // Sliders icon
70458
- svgPath: 'M4 21v-7 M4 10V3 M12 21v-9 M12 8V3 M20 21v-5 M20 12V3 M1 14h6 M9 8h6 M17 16h6',
70459
70995
  disabled: noSlides,
70460
70996
  active: active === 'inspector',
70461
70997
  emit: () => this.openFormat.emit(),
@@ -70463,8 +70999,6 @@ class MobileBottomBarComponent {
70463
70999
  {
70464
71000
  key: 'comments',
70465
71001
  labelKey: 'pptx.toolbar.comments',
70466
- // Message-square icon
70467
- svgPath: 'M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z',
70468
71002
  disabled: noSlides,
70469
71003
  active: active === 'comments',
70470
71004
  badge: this.commentCount(),
@@ -70474,8 +71008,6 @@ class MobileBottomBarComponent {
70474
71008
  key: 'notes',
70475
71009
  labelKey: 'pptx.notes.title',
70476
71010
  ariaLabelKey: 'pptx.statusBar.toggleNotes',
70477
- // Note / document-text icon
70478
- 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',
70479
71011
  disabled: noSlides,
70480
71012
  active: active === 'notes',
70481
71013
  emit: () => this.notes.emit(),
@@ -70496,19 +71028,23 @@ class MobileBottomBarComponent {
70496
71028
  [disabled]="action.disabled"
70497
71029
  (click)="action.emit()"
70498
71030
  >
70499
- <svg
70500
- class="pptx-ng-mbar-icon"
70501
- xmlns="http://www.w3.org/2000/svg"
70502
- viewBox="0 0 24 24"
70503
- fill="none"
70504
- stroke="currentColor"
70505
- stroke-width="2"
70506
- stroke-linecap="round"
70507
- stroke-linejoin="round"
70508
- aria-hidden="true"
70509
- >
70510
- <path [attr.d]="action.svgPath" />
70511
- </svg>
71031
+ @switch (action.key) {
71032
+ @case ('slides') {
71033
+ <svg lucideLayers class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
71034
+ }
71035
+ @case ('insert') {
71036
+ <svg lucidePlus class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
71037
+ }
71038
+ @case ('inspector') {
71039
+ <svg lucideSettings2 class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
71040
+ }
71041
+ @case ('comments') {
71042
+ <svg lucideMessageSquare class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
71043
+ }
71044
+ @case ('notes') {
71045
+ <svg lucideStickyNote class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
71046
+ }
71047
+ }
70512
71048
  <span class="pptx-ng-mbar-label">{{ action.labelKey | translate }}</span>
70513
71049
  @if (action.badge && action.badge > 0) {
70514
71050
  <span class="pptx-ng-mbar-badge" aria-hidden="true">
@@ -70521,11 +71057,18 @@ class MobileBottomBarComponent {
70521
71057
  </button>
70522
71058
  }
70523
71059
  </nav>
70524
- `, isInline: true, 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"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
71060
+ `, isInline: true, styles: [":host{display:block}.pptx-ng-mbar{display:flex;align-items:stretch;justify-content:space-around;background:color-mix(in srgb,var(--pptx-secondary, #1f2937) 80%,transparent);border-top:1px solid var(--pptx-border, #374151);padding-bottom:max(env(safe-area-inset-bottom,0px),0px)}@supports ((backdrop-filter: blur(12px)) or (-webkit-backdrop-filter: blur(12px))){.pptx-ng-mbar{background:color-mix(in srgb,var(--pptx-secondary, #1f2937) 60%,transparent);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}}.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:var(--pptx-muted-foreground, #9ca3af);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:var(--pptx-primary, #6366f1)}.pptx-ng-mbar-btn:hover:not([disabled]):not(.is-active){color:var(--pptx-foreground, #f3f4f6)}.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:var(--pptx-primary, #6366f1);color:var(--pptx-primary-foreground, #ffffff);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:var(--pptx-primary, #6366f1)}\n"], dependencies: [{ kind: "component", type: LucideLayers, selector: "svg[lucideLayers], svg[lucideLayers3]" }, { kind: "component", type: LucideMessageSquare, selector: "svg[lucideMessageSquare]" }, { kind: "component", type: LucidePlus, selector: "svg[lucidePlus]" }, { kind: "component", type: LucideSettings2, selector: "svg[lucideSettings2]" }, { kind: "component", type: LucideStickyNote, selector: "svg[lucideStickyNote]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
70525
71061
  }
70526
71062
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MobileBottomBarComponent, decorators: [{
70527
71063
  type: Component,
70528
- args: [{ selector: 'pptx-mobile-bottom-bar', standalone: true, imports: [TranslatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: `
71064
+ args: [{ selector: 'pptx-mobile-bottom-bar', standalone: true, imports: [
71065
+ LucideLayers,
71066
+ LucideMessageSquare,
71067
+ LucidePlus,
71068
+ LucideSettings2,
71069
+ LucideStickyNote,
71070
+ TranslatePipe,
71071
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: `
70529
71072
  <nav class="pptx-ng-mbar" [attr.aria-label]="'pptx.mobileBar.ariaLabel' | translate">
70530
71073
  @for (action of actions(); track action.key) {
70531
71074
  <button
@@ -70537,19 +71080,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
70537
71080
  [disabled]="action.disabled"
70538
71081
  (click)="action.emit()"
70539
71082
  >
70540
- <svg
70541
- class="pptx-ng-mbar-icon"
70542
- xmlns="http://www.w3.org/2000/svg"
70543
- viewBox="0 0 24 24"
70544
- fill="none"
70545
- stroke="currentColor"
70546
- stroke-width="2"
70547
- stroke-linecap="round"
70548
- stroke-linejoin="round"
70549
- aria-hidden="true"
70550
- >
70551
- <path [attr.d]="action.svgPath" />
70552
- </svg>
71083
+ @switch (action.key) {
71084
+ @case ('slides') {
71085
+ <svg lucideLayers class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
71086
+ }
71087
+ @case ('insert') {
71088
+ <svg lucidePlus class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
71089
+ }
71090
+ @case ('inspector') {
71091
+ <svg lucideSettings2 class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
71092
+ }
71093
+ @case ('comments') {
71094
+ <svg lucideMessageSquare class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
71095
+ }
71096
+ @case ('notes') {
71097
+ <svg lucideStickyNote class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
71098
+ }
71099
+ }
70553
71100
  <span class="pptx-ng-mbar-label">{{ action.labelKey | translate }}</span>
70554
71101
  @if (action.badge && action.badge > 0) {
70555
71102
  <span class="pptx-ng-mbar-badge" aria-hidden="true">
@@ -70562,7 +71109,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
70562
71109
  </button>
70563
71110
  }
70564
71111
  </nav>
70565
- `, 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"] }]
71112
+ `, styles: [":host{display:block}.pptx-ng-mbar{display:flex;align-items:stretch;justify-content:space-around;background:color-mix(in srgb,var(--pptx-secondary, #1f2937) 80%,transparent);border-top:1px solid var(--pptx-border, #374151);padding-bottom:max(env(safe-area-inset-bottom,0px),0px)}@supports ((backdrop-filter: blur(12px)) or (-webkit-backdrop-filter: blur(12px))){.pptx-ng-mbar{background:color-mix(in srgb,var(--pptx-secondary, #1f2937) 60%,transparent);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}}.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:var(--pptx-muted-foreground, #9ca3af);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:var(--pptx-primary, #6366f1)}.pptx-ng-mbar-btn:hover:not([disabled]):not(.is-active){color:var(--pptx-foreground, #f3f4f6)}.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:var(--pptx-primary, #6366f1);color:var(--pptx-primary-foreground, #ffffff);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:var(--pptx-primary, #6366f1)}\n"] }]
70566
71113
  }], propDecorators: { slideCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideCount", required: false }] }], commentCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "commentCount", required: false }] }], activeSheet: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeSheet", required: false }] }], openSlides: [{ type: i0.Output, args: ["openSlides"] }], insert: [{ type: i0.Output, args: ["insert"] }], openFormat: [{ type: i0.Output, args: ["openFormat"] }], openComments: [{ type: i0.Output, args: ["openComments"] }], notes: [{ type: i0.Output, args: ["notes"] }] } });
70567
71114
 
70568
71115
  /**
@@ -71480,7 +72027,7 @@ class MobilePresenterViewComponent {
71480
72027
  } @else {
71481
72028
  <div class="pptx-ng-mpresenter-empty">{{ 'pptx.presenter.noSlides' | translate }}</div>
71482
72029
  }
71483
- `, 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;padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px);padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}.pptx-ng-mpresenter-header,.pptx-ng-mpresenter-next,.pptx-ng-mpresenter-ctl{display:flex;align-items:center;gap:.75rem;padding:.5rem 1rem}.pptx-ng-mpresenter-header{justify-content:space-between;border-bottom:1px solid rgba(255,255,255,.08)}.pptx-ng-mpresenter-label{font-size:.625rem;text-transform:uppercase;letter-spacing:.06em;color:#ffffff8c}.pptx-ng-mpresenter-elapsed{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:1.125rem;color:#6ea8fe}.pptx-ng-mpresenter-counter{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.875rem}.pptx-ng-mpresenter-exit{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;min-width:44px;min-height:44px;border:none;border-radius:6px;background:transparent;color:#ffffffbf;cursor:pointer;font-size:1.25rem;line-height:1}.pptx-ng-mpresenter-exit:hover{background:#ffffff1f;color:#fff}.pptx-ng-mpresenter-main{display:flex;align-items:center;justify-content:center;background:#000;padding:.75rem}.pptx-ng-mpresenter-main-stage{width:100%;max-width:640px}.pptx-ng-mpresenter-next{border-bottom:1px solid rgba(255,255,255,.08)}.pptx-ng-mpresenter-thumb{flex:0 0 auto;overflow:hidden;border:1px solid rgba(255,255,255,.15);border-radius:4px}.pptx-ng-mpresenter-next-empty{display:flex;flex:1 1 auto;align-items:center;justify-content:center;height:3rem;border:1px solid rgba(255,255,255,.15);border-radius:4px;background:#ffffff0a;font-size:.625rem;font-style:italic;color:#ffffff80}.pptx-ng-mpresenter-notes{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;padding:.5rem 1rem}.pptx-ng-mpresenter-notes-body{flex:1 1 auto;overflow-y:auto;margin-top:.25rem;border:1px solid rgba(255,255,255,.15);border-radius:6px;background:#ffffff0a;padding:.5rem .75rem;white-space:pre-wrap;line-height:1.5;font-size:15px}.pptx-ng-mpresenter-notes-empty{font-style:italic;color:#ffffff80}.pptx-ng-mpresenter-ctl{justify-content:space-between;border-top:1px solid rgba(255,255,255,.08)}.pptx-ng-mpresenter-navbtn{flex:1 1 0;display:inline-flex;align-items:center;justify-content:center;gap:.375rem;height:44px;border:none;border-radius:6px;background:#ffffff14;color:#f5f5f5;cursor:pointer;font-size:.9rem}.pptx-ng-mpresenter-navbtn:hover:not(:disabled){background:#ffffff29}.pptx-ng-mpresenter-navbtn:disabled{opacity:.4;cursor:not-allowed}.pptx-ng-mpresenter-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", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
72030
+ `, 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;padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px);padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}.pptx-ng-mpresenter-header,.pptx-ng-mpresenter-next,.pptx-ng-mpresenter-ctl{display:flex;align-items:center;gap:.75rem;padding:.5rem 1rem}.pptx-ng-mpresenter-header{justify-content:space-between;border-bottom:1px solid rgba(255,255,255,.08)}.pptx-ng-mpresenter-label{font-size:.625rem;text-transform:uppercase;letter-spacing:.06em;color:#ffffff8c}.pptx-ng-mpresenter-elapsed{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:1.125rem;color:#6ea8fe}.pptx-ng-mpresenter-counter{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.875rem}.pptx-ng-mpresenter-exit{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;min-width:44px;min-height:44px;border:none;border-radius:6px;background:transparent;color:#ffffffbf;cursor:pointer;font-size:1.25rem;line-height:1}.pptx-ng-mpresenter-exit:hover{background:#ffffff1f;color:#fff}.pptx-ng-mpresenter-main{display:flex;align-items:center;justify-content:center;background:#000;padding:.75rem}.pptx-ng-mpresenter-main-stage{width:100%;max-width:640px}.pptx-ng-mpresenter-next{border-bottom:1px solid rgba(255,255,255,.08)}.pptx-ng-mpresenter-thumb{flex:0 0 auto;overflow:hidden;border:1px solid rgba(255,255,255,.15);border-radius:4px}.pptx-ng-mpresenter-next-empty{display:flex;flex:1 1 auto;align-items:center;justify-content:center;height:3rem;border:1px solid rgba(255,255,255,.15);border-radius:4px;background:#ffffff0a;font-size:.625rem;font-style:italic;color:#ffffff80}.pptx-ng-mpresenter-notes{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;padding:.5rem 1rem}.pptx-ng-mpresenter-notes-body{flex:1 1 auto;overflow-y:auto;margin-top:.25rem;border:1px solid rgba(255,255,255,.15);border-radius:6px;background:#ffffff0a;padding:.5rem .75rem;white-space:pre-wrap;line-height:1.5;font-size:15px}.pptx-ng-mpresenter-notes-empty{font-style:italic;color:#ffffff80}.pptx-ng-mpresenter-ctl{justify-content:space-between;border-top:1px solid rgba(255,255,255,.08)}.pptx-ng-mpresenter-navbtn{flex:1 1 0;display:inline-flex;align-items:center;justify-content:center;gap:.375rem;height:44px;border:none;border-radius:6px;background:#ffffff14;color:#f5f5f5;cursor:pointer;font-size:.9rem}.pptx-ng-mpresenter-navbtn:hover:not(:disabled){background:#ffffff29}.pptx-ng-mpresenter-navbtn:disabled{opacity:.4;cursor:not-allowed}.pptx-ng-mpresenter-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", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
71484
72031
  }
71485
72032
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MobilePresenterViewComponent, decorators: [{
71486
72033
  type: Component,
@@ -71756,7 +72303,7 @@ class MobileSlidesSheetComponent {
71756
72303
  }
71757
72304
  </div>
71758
72305
  </pptx-mobile-sheet>
71759
- `, 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", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
72306
+ `, 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", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
71760
72307
  }
71761
72308
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MobileSlidesSheetComponent, decorators: [{
71762
72309
  type: Component,
@@ -71828,7 +72375,9 @@ function toolbarVisibility(hiddenActions) {
71828
72375
  * A single compact row that replaces the desktop ribbon below the 768px
71829
72376
  * breakpoint. Renders the essential always-available controls:
71830
72377
  *
71831
- * Menu · Undo · Redo · [spacer] · Present
72378
+ * Menu · Undo · Redo · [spacer] · AI · Save · Present · Share
72379
+ *
72380
+ * The slot order, icons and colours mirror React's MobileToolbar exactly.
71832
72381
  *
71833
72382
  * Section-specific functionality (Insert/Design/Export/etc.) lives in the
71834
72383
  * `MobileMenuSheetComponent` that opens from the Menu button; per-selection
@@ -71838,18 +72387,7 @@ function toolbarVisibility(hiddenActions) {
71838
72387
  * the framework-neutral accessibility contract the e2e specs assert against
71839
72388
  * (`getByRole('toolbar', { name: 'Toolbar' })`).
71840
72389
  *
71841
- * Inputs
71842
- * canUndo : whether the undo action is available
71843
- * canRedo : whether the redo action is available
71844
- * canPresent : whether the Present action should be enabled
71845
- * canEdit : whether editor-only controls (menu/undo/redo) should render
71846
- * menuOpen : whether the mobile menu sheet is currently open
71847
- *
71848
- * Outputs
71849
- * toggleMenu : user tapped the Menu (hamburger) button
71850
- * undo : user tapped Undo
71851
- * redo : user tapped Redo
71852
- * present : user tapped Present
72390
+ * Each input/output is documented on its own declaration below.
71853
72391
  */
71854
72392
  class MobileToolbarComponent {
71855
72393
  /** Whether the undo action is available. */
@@ -71884,13 +72422,15 @@ class MobileToolbarComponent {
71884
72422
  undo = output();
71885
72423
  /** User tapped Redo. */
71886
72424
  redo = output();
72425
+ /** User tapped Share (opens the collaboration share dialog). */
72426
+ share = output();
71887
72427
  /** User tapped Save (download as .pptx). */
71888
72428
  save = output();
71889
72429
  /** User tapped Present. */
71890
72430
  present = output();
71891
72431
  toolbar = toolbarVisibility(this.hiddenActions);
71892
72432
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MobileToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
71893
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: MobileToolbarComponent, isStandalone: true, selector: "pptx-mobile-toolbar", inputs: { canUndo: { classPropertyName: "canUndo", publicName: "canUndo", isSignal: true, isRequired: false, transformFunction: null }, canRedo: { classPropertyName: "canRedo", publicName: "canRedo", isSignal: true, isRequired: false, transformFunction: null }, canPresent: { classPropertyName: "canPresent", publicName: "canPresent", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, menuOpen: { classPropertyName: "menuOpen", publicName: "menuOpen", isSignal: true, isRequired: false, transformFunction: null }, aiEnabled: { classPropertyName: "aiEnabled", publicName: "aiEnabled", isSignal: true, isRequired: false, transformFunction: null }, aiPanelOpen: { classPropertyName: "aiPanelOpen", publicName: "aiPanelOpen", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggleMenu: "toggleMenu", toggleAiPanel: "toggleAiPanel", undo: "undo", redo: "redo", save: "save", present: "present" }, ngImport: i0, template: `
72433
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: MobileToolbarComponent, isStandalone: true, selector: "pptx-mobile-toolbar", inputs: { canUndo: { classPropertyName: "canUndo", publicName: "canUndo", isSignal: true, isRequired: false, transformFunction: null }, canRedo: { classPropertyName: "canRedo", publicName: "canRedo", isSignal: true, isRequired: false, transformFunction: null }, canPresent: { classPropertyName: "canPresent", publicName: "canPresent", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, menuOpen: { classPropertyName: "menuOpen", publicName: "menuOpen", isSignal: true, isRequired: false, transformFunction: null }, aiEnabled: { classPropertyName: "aiEnabled", publicName: "aiEnabled", isSignal: true, isRequired: false, transformFunction: null }, aiPanelOpen: { classPropertyName: "aiPanelOpen", publicName: "aiPanelOpen", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggleMenu: "toggleMenu", toggleAiPanel: "toggleAiPanel", undo: "undo", redo: "redo", share: "share", save: "save", present: "present" }, ngImport: i0, template: `
71894
72434
  <div
71895
72435
  class="pptx-ng-mtoolbar"
71896
72436
  role="toolbar"
@@ -71906,19 +72446,7 @@ class MobileToolbarComponent {
71906
72446
  [title]="'pptx.mobileToolbar.menu' | translate"
71907
72447
  (click)="toggleMenu.emit()"
71908
72448
  >
71909
- <svg
71910
- class="pptx-ng-mtoolbar-icon"
71911
- xmlns="http://www.w3.org/2000/svg"
71912
- viewBox="0 0 24 24"
71913
- fill="none"
71914
- stroke="currentColor"
71915
- stroke-width="2"
71916
- stroke-linecap="round"
71917
- stroke-linejoin="round"
71918
- aria-hidden="true"
71919
- >
71920
- <path d="M3 12h18 M3 6h18 M3 18h18" />
71921
- </svg>
72449
+ <svg lucideMenu class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
71922
72450
  </button>
71923
72451
 
71924
72452
  @if (!toolbar.isHidden('undo')) {
@@ -71930,19 +72458,7 @@ class MobileToolbarComponent {
71930
72458
  [disabled]="!canUndo()"
71931
72459
  (click)="undo.emit()"
71932
72460
  >
71933
- <svg
71934
- class="pptx-ng-mtoolbar-icon"
71935
- xmlns="http://www.w3.org/2000/svg"
71936
- viewBox="0 0 24 24"
71937
- fill="none"
71938
- stroke="currentColor"
71939
- stroke-width="2"
71940
- stroke-linecap="round"
71941
- stroke-linejoin="round"
71942
- aria-hidden="true"
71943
- >
71944
- <path d="M3 7v6h6 M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13" />
71945
- </svg>
72461
+ <svg lucideUndo class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
71946
72462
  </button>
71947
72463
  }
71948
72464
 
@@ -71955,19 +72471,7 @@ class MobileToolbarComponent {
71955
72471
  [disabled]="!canRedo()"
71956
72472
  (click)="redo.emit()"
71957
72473
  >
71958
- <svg
71959
- class="pptx-ng-mtoolbar-icon"
71960
- xmlns="http://www.w3.org/2000/svg"
71961
- viewBox="0 0 24 24"
71962
- fill="none"
71963
- stroke="currentColor"
71964
- stroke-width="2"
71965
- stroke-linecap="round"
71966
- stroke-linejoin="round"
71967
- aria-hidden="true"
71968
- >
71969
- <path d="M21 7v6h-6 M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13" />
71970
- </svg>
72474
+ <svg lucideRedo class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
71971
72475
  </button>
71972
72476
  }
71973
72477
  }
@@ -71991,22 +72495,7 @@ class MobileToolbarComponent {
71991
72495
  [title]="'pptx.toolbar.toggleAiAssistant' | translate"
71992
72496
  (click)="toggleAiPanel.emit()"
71993
72497
  >
71994
- <svg
71995
- class="pptx-ng-mtoolbar-icon"
71996
- xmlns="http://www.w3.org/2000/svg"
71997
- viewBox="0 0 24 24"
71998
- fill="none"
71999
- stroke="currentColor"
72000
- stroke-width="2"
72001
- stroke-linecap="round"
72002
- stroke-linejoin="round"
72003
- aria-hidden="true"
72004
- >
72005
- <path
72006
- d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"
72007
- />
72008
- <path d="M20 3v4 M22 5h-4 M4 17v2 M5 18H3" />
72009
- </svg>
72498
+ <svg lucideSparkles class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
72010
72499
  </button>
72011
72500
  }
72012
72501
 
@@ -72022,49 +72511,54 @@ class MobileToolbarComponent {
72022
72511
  [title]="'pptx.toolbar.save' | translate"
72023
72512
  (click)="save.emit()"
72024
72513
  >
72025
- <svg
72026
- class="pptx-ng-mtoolbar-icon"
72027
- xmlns="http://www.w3.org/2000/svg"
72028
- viewBox="0 0 24 24"
72029
- fill="none"
72030
- stroke="currentColor"
72031
- stroke-width="2"
72032
- stroke-linecap="round"
72033
- stroke-linejoin="round"
72034
- aria-hidden="true"
72035
- >
72036
- <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 M7 10l5 5 5-5 M12 15V3" />
72037
- </svg>
72514
+ <svg lucideDownload class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
72038
72515
  </button>
72039
72516
 
72040
- <button
72041
- type="button"
72042
- class="pptx-ng-mtoolbar-btn pptx-ng-mtoolbar-present"
72043
- [attr.aria-label]="'pptx.toolbar.present' | translate"
72044
- [title]="'pptx.toolbar.present' | translate"
72045
- [disabled]="!canPresent()"
72046
- (click)="present.emit()"
72047
- >
72048
- <svg
72049
- class="pptx-ng-mtoolbar-icon"
72050
- xmlns="http://www.w3.org/2000/svg"
72051
- viewBox="0 0 24 24"
72052
- fill="none"
72053
- stroke="currentColor"
72054
- stroke-width="2"
72055
- stroke-linecap="round"
72056
- stroke-linejoin="round"
72057
- aria-hidden="true"
72517
+ <!-- Present: same Lucide "presentation" glyph React's mobile bar uses. -->
72518
+ @if (!toolbar.isHidden('fullscreen')) {
72519
+ <button
72520
+ type="button"
72521
+ class="pptx-ng-mtoolbar-btn pptx-ng-mtoolbar-present"
72522
+ [attr.aria-label]="'pptx.toolbar.present' | translate"
72523
+ [title]="'pptx.toolbar.present' | translate"
72524
+ [disabled]="!canPresent()"
72525
+ (click)="present.emit()"
72058
72526
  >
72059
- <path d="M5 3l14 9-14 9V3z" />
72060
- </svg>
72061
- </button>
72527
+ <svg lucidePresentation class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
72528
+ </button>
72529
+ }
72530
+
72531
+ <!--
72532
+ Share: start/join a real-time collaboration session. Sits last in
72533
+ the row (after Present) and renders as a filled primary pill, the
72534
+ same slot and treatment React's MobileToolbar gives it.
72535
+ -->
72536
+ @if (canEdit() && !toolbar.isHidden('share')) {
72537
+ <button
72538
+ type="button"
72539
+ class="pptx-ng-mtoolbar-btn pptx-ng-mtoolbar-share"
72540
+ [attr.aria-label]="'pptx.toolbar.share' | translate"
72541
+ [title]="'pptx.toolbar.share' | translate"
72542
+ (click)="share.emit()"
72543
+ >
72544
+ <svg lucideShare2 class="pptx-ng-mtoolbar-icon is-sm" aria-hidden="true"></svg>
72545
+ </button>
72546
+ }
72062
72547
  </div>
72063
- `, isInline: true, styles: [":host{display:block}.pptx-ng-mtoolbar{position:relative;z-index:20;display:flex;align-items:center;gap:.25rem;padding:.25rem .5rem;min-height:52px;background:#1a1a1aeb;border-bottom:1px solid rgba(255,255,255,.1);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);padding-top:max(env(safe-area-inset-top,0px),.25rem)}.pptx-ng-mtoolbar-spacer{flex:1 1 auto}.pptx-ng-mtoolbar-btn{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;border:none;border-radius:.375rem;background:transparent;color:#ffffffd9;cursor:pointer;touch-action:manipulation;transition:background .12s,transform .08s;-webkit-tap-highlight-color:transparent}.pptx-ng-mtoolbar-btn:active:not([disabled]){transform:scale(.92)}.pptx-ng-mtoolbar-btn:hover:not([disabled]){background:#ffffff14}.pptx-ng-mtoolbar-btn.is-active{color:#3b82f6}.pptx-ng-mtoolbar-btn[disabled]{opacity:.35;cursor:not-allowed}.pptx-ng-mtoolbar-present{color:#3b82f6}.pptx-ng-mtoolbar-icon{width:1.25rem;height:1.25rem;flex-shrink:0}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
72548
+ `, isInline: true, styles: [":host{display:block}.pptx-ng-mtoolbar{position:relative;z-index:20;display:flex;align-items:center;gap:.25rem;padding:.25rem .5rem;min-height:52px;background:color-mix(in srgb,var(--pptx-secondary, #1f2937) 50%,transparent);border-bottom:1px solid var(--pptx-border, #374151);padding-top:max(env(safe-area-inset-top,0px),.25rem)}.pptx-ng-mtoolbar-spacer{flex:1 1 auto}.pptx-ng-mtoolbar-btn{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;border:none;border-radius:.375rem;background:transparent;color:color-mix(in srgb,var(--pptx-foreground, #f3f4f6) 80%,transparent);cursor:pointer;touch-action:manipulation;transition:background .12s,transform .08s;-webkit-tap-highlight-color:transparent}.pptx-ng-mtoolbar-btn:active:not([disabled]){transform:scale(.92)}.pptx-ng-mtoolbar-btn:hover:not([disabled]){background:color-mix(in srgb,var(--pptx-accent, #1f2937) 60%,transparent)}.pptx-ng-mtoolbar-btn.is-active{color:var(--pptx-primary, #6366f1)}.pptx-ng-mtoolbar-btn[disabled]{opacity:.35;cursor:not-allowed}.pptx-ng-mtoolbar-present{color:var(--pptx-primary, #6366f1)}.pptx-ng-mtoolbar-share{padding:0 .75rem;background:var(--pptx-primary, #6366f1);color:var(--pptx-primary-foreground, #ffffff)}.pptx-ng-mtoolbar-share:hover:not([disabled]){background:color-mix(in srgb,var(--pptx-primary, #6366f1) 90%,transparent)}.pptx-ng-mtoolbar-icon{width:1.25rem;height:1.25rem;flex-shrink:0}.pptx-ng-mtoolbar-icon.is-sm{width:1rem;height:1rem}\n"], dependencies: [{ kind: "component", type: LucideDownload, selector: "svg[lucideDownload]" }, { kind: "component", type: LucideMenu, selector: "svg[lucideMenu]" }, { kind: "component", type: LucidePresentation, selector: "svg[lucidePresentation]" }, { kind: "component", type: LucideRedo, selector: "svg[lucideRedo]" }, { kind: "component", type: LucideShare2, selector: "svg[lucideShare2]" }, { kind: "component", type: LucideSparkles, selector: "svg[lucideSparkles], svg[lucideStars]" }, { kind: "component", type: LucideUndo, selector: "svg[lucideUndo]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
72064
72549
  }
72065
72550
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MobileToolbarComponent, decorators: [{
72066
72551
  type: Component,
72067
- args: [{ selector: 'pptx-mobile-toolbar', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslatePipe], template: `
72552
+ args: [{ selector: 'pptx-mobile-toolbar', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
72553
+ LucideDownload,
72554
+ LucideMenu,
72555
+ LucidePresentation,
72556
+ LucideRedo,
72557
+ LucideShare2,
72558
+ LucideSparkles,
72559
+ LucideUndo,
72560
+ TranslatePipe,
72561
+ ], template: `
72068
72562
  <div
72069
72563
  class="pptx-ng-mtoolbar"
72070
72564
  role="toolbar"
@@ -72080,19 +72574,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
72080
72574
  [title]="'pptx.mobileToolbar.menu' | translate"
72081
72575
  (click)="toggleMenu.emit()"
72082
72576
  >
72083
- <svg
72084
- class="pptx-ng-mtoolbar-icon"
72085
- xmlns="http://www.w3.org/2000/svg"
72086
- viewBox="0 0 24 24"
72087
- fill="none"
72088
- stroke="currentColor"
72089
- stroke-width="2"
72090
- stroke-linecap="round"
72091
- stroke-linejoin="round"
72092
- aria-hidden="true"
72093
- >
72094
- <path d="M3 12h18 M3 6h18 M3 18h18" />
72095
- </svg>
72577
+ <svg lucideMenu class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
72096
72578
  </button>
72097
72579
 
72098
72580
  @if (!toolbar.isHidden('undo')) {
@@ -72104,19 +72586,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
72104
72586
  [disabled]="!canUndo()"
72105
72587
  (click)="undo.emit()"
72106
72588
  >
72107
- <svg
72108
- class="pptx-ng-mtoolbar-icon"
72109
- xmlns="http://www.w3.org/2000/svg"
72110
- viewBox="0 0 24 24"
72111
- fill="none"
72112
- stroke="currentColor"
72113
- stroke-width="2"
72114
- stroke-linecap="round"
72115
- stroke-linejoin="round"
72116
- aria-hidden="true"
72117
- >
72118
- <path d="M3 7v6h6 M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13" />
72119
- </svg>
72589
+ <svg lucideUndo class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
72120
72590
  </button>
72121
72591
  }
72122
72592
 
@@ -72129,19 +72599,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
72129
72599
  [disabled]="!canRedo()"
72130
72600
  (click)="redo.emit()"
72131
72601
  >
72132
- <svg
72133
- class="pptx-ng-mtoolbar-icon"
72134
- xmlns="http://www.w3.org/2000/svg"
72135
- viewBox="0 0 24 24"
72136
- fill="none"
72137
- stroke="currentColor"
72138
- stroke-width="2"
72139
- stroke-linecap="round"
72140
- stroke-linejoin="round"
72141
- aria-hidden="true"
72142
- >
72143
- <path d="M21 7v6h-6 M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13" />
72144
- </svg>
72602
+ <svg lucideRedo class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
72145
72603
  </button>
72146
72604
  }
72147
72605
  }
@@ -72165,22 +72623,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
72165
72623
  [title]="'pptx.toolbar.toggleAiAssistant' | translate"
72166
72624
  (click)="toggleAiPanel.emit()"
72167
72625
  >
72168
- <svg
72169
- class="pptx-ng-mtoolbar-icon"
72170
- xmlns="http://www.w3.org/2000/svg"
72171
- viewBox="0 0 24 24"
72172
- fill="none"
72173
- stroke="currentColor"
72174
- stroke-width="2"
72175
- stroke-linecap="round"
72176
- stroke-linejoin="round"
72177
- aria-hidden="true"
72178
- >
72179
- <path
72180
- d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"
72181
- />
72182
- <path d="M20 3v4 M22 5h-4 M4 17v2 M5 18H3" />
72183
- </svg>
72626
+ <svg lucideSparkles class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
72184
72627
  </button>
72185
72628
  }
72186
72629
 
@@ -72196,46 +72639,42 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
72196
72639
  [title]="'pptx.toolbar.save' | translate"
72197
72640
  (click)="save.emit()"
72198
72641
  >
72199
- <svg
72200
- class="pptx-ng-mtoolbar-icon"
72201
- xmlns="http://www.w3.org/2000/svg"
72202
- viewBox="0 0 24 24"
72203
- fill="none"
72204
- stroke="currentColor"
72205
- stroke-width="2"
72206
- stroke-linecap="round"
72207
- stroke-linejoin="round"
72208
- aria-hidden="true"
72209
- >
72210
- <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 M7 10l5 5 5-5 M12 15V3" />
72211
- </svg>
72642
+ <svg lucideDownload class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
72212
72643
  </button>
72213
72644
 
72214
- <button
72215
- type="button"
72216
- class="pptx-ng-mtoolbar-btn pptx-ng-mtoolbar-present"
72217
- [attr.aria-label]="'pptx.toolbar.present' | translate"
72218
- [title]="'pptx.toolbar.present' | translate"
72219
- [disabled]="!canPresent()"
72220
- (click)="present.emit()"
72221
- >
72222
- <svg
72223
- class="pptx-ng-mtoolbar-icon"
72224
- xmlns="http://www.w3.org/2000/svg"
72225
- viewBox="0 0 24 24"
72226
- fill="none"
72227
- stroke="currentColor"
72228
- stroke-width="2"
72229
- stroke-linecap="round"
72230
- stroke-linejoin="round"
72231
- aria-hidden="true"
72645
+ <!-- Present: same Lucide "presentation" glyph React's mobile bar uses. -->
72646
+ @if (!toolbar.isHidden('fullscreen')) {
72647
+ <button
72648
+ type="button"
72649
+ class="pptx-ng-mtoolbar-btn pptx-ng-mtoolbar-present"
72650
+ [attr.aria-label]="'pptx.toolbar.present' | translate"
72651
+ [title]="'pptx.toolbar.present' | translate"
72652
+ [disabled]="!canPresent()"
72653
+ (click)="present.emit()"
72232
72654
  >
72233
- <path d="M5 3l14 9-14 9V3z" />
72234
- </svg>
72235
- </button>
72655
+ <svg lucidePresentation class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
72656
+ </button>
72657
+ }
72658
+
72659
+ <!--
72660
+ Share: start/join a real-time collaboration session. Sits last in
72661
+ the row (after Present) and renders as a filled primary pill, the
72662
+ same slot and treatment React's MobileToolbar gives it.
72663
+ -->
72664
+ @if (canEdit() && !toolbar.isHidden('share')) {
72665
+ <button
72666
+ type="button"
72667
+ class="pptx-ng-mtoolbar-btn pptx-ng-mtoolbar-share"
72668
+ [attr.aria-label]="'pptx.toolbar.share' | translate"
72669
+ [title]="'pptx.toolbar.share' | translate"
72670
+ (click)="share.emit()"
72671
+ >
72672
+ <svg lucideShare2 class="pptx-ng-mtoolbar-icon is-sm" aria-hidden="true"></svg>
72673
+ </button>
72674
+ }
72236
72675
  </div>
72237
- `, styles: [":host{display:block}.pptx-ng-mtoolbar{position:relative;z-index:20;display:flex;align-items:center;gap:.25rem;padding:.25rem .5rem;min-height:52px;background:#1a1a1aeb;border-bottom:1px solid rgba(255,255,255,.1);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);padding-top:max(env(safe-area-inset-top,0px),.25rem)}.pptx-ng-mtoolbar-spacer{flex:1 1 auto}.pptx-ng-mtoolbar-btn{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;border:none;border-radius:.375rem;background:transparent;color:#ffffffd9;cursor:pointer;touch-action:manipulation;transition:background .12s,transform .08s;-webkit-tap-highlight-color:transparent}.pptx-ng-mtoolbar-btn:active:not([disabled]){transform:scale(.92)}.pptx-ng-mtoolbar-btn:hover:not([disabled]){background:#ffffff14}.pptx-ng-mtoolbar-btn.is-active{color:#3b82f6}.pptx-ng-mtoolbar-btn[disabled]{opacity:.35;cursor:not-allowed}.pptx-ng-mtoolbar-present{color:#3b82f6}.pptx-ng-mtoolbar-icon{width:1.25rem;height:1.25rem;flex-shrink:0}\n"] }]
72238
- }], propDecorators: { canUndo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canUndo", required: false }] }], canRedo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canRedo", required: false }] }], canPresent: [{ type: i0.Input, args: [{ isSignal: true, alias: "canPresent", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], menuOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuOpen", required: false }] }], aiEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiEnabled", required: false }] }], aiPanelOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiPanelOpen", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], toggleMenu: [{ type: i0.Output, args: ["toggleMenu"] }], toggleAiPanel: [{ type: i0.Output, args: ["toggleAiPanel"] }], undo: [{ type: i0.Output, args: ["undo"] }], redo: [{ type: i0.Output, args: ["redo"] }], save: [{ type: i0.Output, args: ["save"] }], present: [{ type: i0.Output, args: ["present"] }] } });
72676
+ `, styles: [":host{display:block}.pptx-ng-mtoolbar{position:relative;z-index:20;display:flex;align-items:center;gap:.25rem;padding:.25rem .5rem;min-height:52px;background:color-mix(in srgb,var(--pptx-secondary, #1f2937) 50%,transparent);border-bottom:1px solid var(--pptx-border, #374151);padding-top:max(env(safe-area-inset-top,0px),.25rem)}.pptx-ng-mtoolbar-spacer{flex:1 1 auto}.pptx-ng-mtoolbar-btn{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;border:none;border-radius:.375rem;background:transparent;color:color-mix(in srgb,var(--pptx-foreground, #f3f4f6) 80%,transparent);cursor:pointer;touch-action:manipulation;transition:background .12s,transform .08s;-webkit-tap-highlight-color:transparent}.pptx-ng-mtoolbar-btn:active:not([disabled]){transform:scale(.92)}.pptx-ng-mtoolbar-btn:hover:not([disabled]){background:color-mix(in srgb,var(--pptx-accent, #1f2937) 60%,transparent)}.pptx-ng-mtoolbar-btn.is-active{color:var(--pptx-primary, #6366f1)}.pptx-ng-mtoolbar-btn[disabled]{opacity:.35;cursor:not-allowed}.pptx-ng-mtoolbar-present{color:var(--pptx-primary, #6366f1)}.pptx-ng-mtoolbar-share{padding:0 .75rem;background:var(--pptx-primary, #6366f1);color:var(--pptx-primary-foreground, #ffffff)}.pptx-ng-mtoolbar-share:hover:not([disabled]){background:color-mix(in srgb,var(--pptx-primary, #6366f1) 90%,transparent)}.pptx-ng-mtoolbar-icon{width:1.25rem;height:1.25rem;flex-shrink:0}.pptx-ng-mtoolbar-icon.is-sm{width:1rem;height:1rem}\n"] }]
72677
+ }], propDecorators: { canUndo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canUndo", required: false }] }], canRedo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canRedo", required: false }] }], canPresent: [{ type: i0.Input, args: [{ isSignal: true, alias: "canPresent", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], menuOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuOpen", required: false }] }], aiEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiEnabled", required: false }] }], aiPanelOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiPanelOpen", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], toggleMenu: [{ type: i0.Output, args: ["toggleMenu"] }], toggleAiPanel: [{ type: i0.Output, args: ["toggleAiPanel"] }], undo: [{ type: i0.Output, args: ["undo"] }], redo: [{ type: i0.Output, args: ["redo"] }], share: [{ type: i0.Output, args: ["share"] }], save: [{ type: i0.Output, args: ["save"] }], present: [{ type: i0.Output, args: ["present"] }] } });
72239
72678
 
72240
72679
  /**
72241
72680
  * notes-toolbar.component.ts: formatting toolbar for the rich speaker-notes
@@ -73685,6 +74124,7 @@ class ViewerCanvasEditingService {
73685
74124
  editor = inject(EditorStateService);
73686
74125
  dialogs = inject(ViewerDialogsService);
73687
74126
  formatPainter = inject(ViewerFormatPainterService);
74127
+ collab = inject(CollaborationService);
73688
74128
  /** Id of the element being inline text-edited, or null. */
73689
74129
  editingId = signal(null, /* @ts-ignore */
73690
74130
  ...(ngDevMode ? [{ debugName: "editingId" }] : /* istanbul ignore next */ []));
@@ -73729,9 +74169,21 @@ class ViewerCanvasEditingService {
73729
74169
  }
73730
74170
  this.editor.updateElement(host.activeSlideIndex(), event.id, textStylePatch(element, event.updates));
73731
74171
  }
74172
+ /**
74173
+ * Mirror an in-progress inline edit to collaborators. The typed text only
74174
+ * reaches the editor state (and therefore the Y.Doc reconcile) on commit, so
74175
+ * without this peers saw nothing until the editor blurred. No-op when not
74176
+ * collaborating.
74177
+ */
74178
+ onTextInput(event) {
74179
+ publishLiveInlineText(this.collab.livePatcher, this.requireHost().activeSlide(), event.id, event.text);
74180
+ }
73732
74181
  /** Commit an inline text edit: replace the element's text (one history entry). */
73733
74182
  onTextCommit(event) {
73734
74183
  const host = this.requireHost();
74184
+ // Push any queued interim frame out first so it cannot land after the
74185
+ // committed text and revert it.
74186
+ this.collab.livePatcher.flush();
73735
74187
  this.editor.updateElement(host.activeSlideIndex(), event.id, {
73736
74188
  text: event.text,
73737
74189
  textSegments: [],
@@ -74007,6 +74459,14 @@ class ViewerCollaborationSessionService {
74007
74459
  activeSession = signal(null, /* @ts-ignore */
74008
74460
  ...(ngDevMode ? [{ debugName: "activeSession" }] : /* istanbul ignore next */ []));
74009
74461
  host = null;
74462
+ /**
74463
+ * Last host `collaboration` config handled by {@link syncHostConfig}
74464
+ * (reference-equal dedup). A re-invocation with the same object (e.g. a
74465
+ * spurious effect re-run) must not reconnect: a second provider join on the
74466
+ * same room throws inside Yjs and tears down the live session. Cleared on
74467
+ * the explicit stop paths so stop + restart with the same object works.
74468
+ */
74469
+ lastSyncedConfig;
74010
74470
  /** Wire the host inputs/outputs (called once from the component constructor). */
74011
74471
  bind(host) {
74012
74472
  this.host = host;
@@ -74084,6 +74544,10 @@ class ViewerCollaborationSessionService {
74084
74544
  * input changes (called from the component's effect).
74085
74545
  */
74086
74546
  syncHostConfig(config) {
74547
+ if (config === this.lastSyncedConfig) {
74548
+ return;
74549
+ }
74550
+ this.lastSyncedConfig = config;
74087
74551
  if (config) {
74088
74552
  this.activeSession.set({ roomId: config.roomId, serverUrl: config.serverUrl });
74089
74553
  this.connectWithBaseline(config);
@@ -74110,6 +74574,7 @@ class ViewerCollaborationSessionService {
74110
74574
  host.emitStart(collaboratorConfig);
74111
74575
  }
74112
74576
  onShareStop() {
74577
+ this.lastSyncedConfig = undefined;
74113
74578
  this.collab.disconnect();
74114
74579
  this.activeSession.set(null);
74115
74580
  this.requireHost().emitStop();
@@ -74129,6 +74594,7 @@ class ViewerCollaborationSessionService {
74129
74594
  host.emitStart(collabConfig);
74130
74595
  }
74131
74596
  onBroadcastStop() {
74597
+ this.lastSyncedConfig = undefined;
74132
74598
  this.collab.disconnect();
74133
74599
  this.activeSession.set(null);
74134
74600
  this.requireHost().emitStop();
@@ -75066,10 +75532,7 @@ class ViewerInspectorPanelService {
75066
75532
  * sheet), so the gesture is wired here rather than via a fixed-overlay
75067
75533
  * dismiss. Clearing the past-threshold drag also closes any open tool panel.
75068
75534
  */
75069
- inspectorDrag = createSwipeDismissDrag(() => {
75070
- this.mobileInspectorHidden.set(true);
75071
- this.activePanel.set(null);
75072
- });
75535
+ inspectorDrag = createSwipeDismissDrag(() => this.dismissMobileInspector());
75073
75536
  host = null;
75074
75537
  /** Wire the host accessors (called once from the component constructor). */
75075
75538
  bind(host) {
@@ -75159,6 +75622,14 @@ class ViewerInspectorPanelService {
75159
75622
  }
75160
75623
  }, /* @ts-ignore */
75161
75624
  ...(ngDevMode ? [{ debugName: "inspectorLabel" }] : /* istanbul ignore next */ []));
75625
+ /**
75626
+ * Dismiss the mobile bottom-sheet inspector (backdrop tap or a past-threshold
75627
+ * swipe-down): hide the host until reopened and clear any explicit tool panel.
75628
+ */
75629
+ dismissMobileInspector() {
75630
+ this.mobileInspectorHidden.set(true);
75631
+ this.activePanel.set(null);
75632
+ }
75162
75633
  /** Toggle a right-docked tool panel (clicking the active one closes it). */
75163
75634
  togglePanel(panel) {
75164
75635
  this.activePanel.update((current) => (current === panel ? null : panel));
@@ -77658,7 +78129,7 @@ class PresentationTransitionOverlayComponent {
77658
78129
  />
77659
78130
  </div>
77660
78131
  </div>
77661
- `, 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", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
78132
+ `, 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", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
77662
78133
  }
77663
78134
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PresentationTransitionOverlayComponent, decorators: [{
77664
78135
  type: Component,
@@ -78459,7 +78930,7 @@ class PresentationOverlayComponent {
78459
78930
  <svg lucideChevronRight class="h-6 w-6"></svg>
78460
78931
  </button>
78461
78932
  </div>
78462
- `, 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}.presenter-blank{position:absolute;inset:0;z-index:75}.presenter-laser{position:absolute;z-index:76;width:20px;height:20px;transform:translate(-50%,-50%);border-radius:50%;background:#ef4444;box-shadow:0 0 20px 8px #ef444488;pointer-events:none}.presenter-caption{position:absolute;z-index:77;left:10%;right:10%;bottom:2rem;padding:.75rem 1.5rem;border-radius:.5rem;background:#000c;color:#fff;text-align:center;font-size:1.25rem;pointer-events: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", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { 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"] }, { kind: "component", type: LucidePenTool, selector: "svg[lucidePenTool]" }, { kind: "component", type: LucideHighlighter, selector: "svg[lucideHighlighter]" }, { kind: "component", type: LucideEraser, selector: "svg[lucideEraser]" }, { kind: "component", type: LucideMousePointer2, selector: "svg[lucideMousePointer2]" }, { kind: "component", type: LucideTrash2, selector: "svg[lucideTrash2]" }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
78933
+ `, 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}.presenter-blank{position:absolute;inset:0;z-index:75}.presenter-laser{position:absolute;z-index:76;width:20px;height:20px;transform:translate(-50%,-50%);border-radius:50%;background:#ef4444;box-shadow:0 0 20px 8px #ef444488;pointer-events:none}.presenter-caption{position:absolute;z-index:77;left:10%;right:10%;bottom:2rem;padding:.75rem 1.5rem;border-radius:.5rem;background:#000c;color:#fff;text-align:center;font-size:1.25rem;pointer-events: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", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { 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"] }, { kind: "component", type: LucidePenTool, selector: "svg[lucidePenTool]" }, { kind: "component", type: LucideHighlighter, selector: "svg[lucideHighlighter]" }, { kind: "component", type: LucideEraser, selector: "svg[lucideEraser]" }, { kind: "component", type: LucideMousePointer2, selector: "svg[lucideMousePointer2]" }, { kind: "component", type: LucideTrash2, selector: "svg[lucideTrash2]" }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
78463
78934
  }
78464
78935
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PresentationOverlayComponent, decorators: [{
78465
78936
  type: Component,
@@ -78694,7 +79165,7 @@ class PresenterControlsComponent {
78694
79165
  @for(slide of slides();track slide.id;let index=$index){<button class="tile" [class.current]="index===current()" [class.hidden]="slide.hidden" (click)="select(index)"><div class="preview" [style.height.px]="canvasSize().height*(200/canvasSize().width)"><pptx-slide-canvas [slide]="slide" [canvasSize]="canvasSize()" [mediaDataUrls]="mediaDataUrls()" [zoom]="200/canvasSize().width" [interactive]="false" /></div><span>{{index+1}}{{slide.hidden?' - hidden':''}}</span></button>}
78695
79166
  </main></div>
78696
79167
  }
78697
- `, isInline: true, styles: [":host{display:block}.strip{display:flex;flex-wrap:wrap;align-items:center;gap:4px;padding:8px 12px;background:#020617;border-bottom:1px solid #ffffff1a}.strip button,.grid button{border:0;border-radius:5px;padding:7px 10px;background:#ffffff12;color:#e2e8f0;cursor:pointer}.strip button:hover,.strip .active{background:#38bdf8;color:#082f49}.strip span{flex:1}.grid{position:fixed;inset:0;z-index:120;display:flex;flex-direction:column;background:#020617fa;color:#f8fafc}.grid header{display:flex;align-items:center;justify-content:space-between;padding:18px 24px;border-bottom:1px solid #ffffff1a}.grid main{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:20px;padding:24px;overflow:auto}.tile{text-align:left}.tile.current{outline:2px solid #38bdf8}.tile.hidden{opacity:.45}.preview{width:200px;overflow:hidden}.tile span{display:block;margin-top:8px;color:#94a3b8}\n"], dependencies: [{ kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
79168
+ `, isInline: true, styles: [":host{display:block}.strip{display:flex;flex-wrap:wrap;align-items:center;gap:4px;padding:8px 12px;background:#020617;border-bottom:1px solid #ffffff1a}.strip button,.grid button{border:0;border-radius:5px;padding:7px 10px;background:#ffffff12;color:#e2e8f0;cursor:pointer}.strip button:hover,.strip .active{background:#38bdf8;color:#082f49}.strip span{flex:1}.grid{position:fixed;inset:0;z-index:120;display:flex;flex-direction:column;background:#020617fa;color:#f8fafc}.grid header{display:flex;align-items:center;justify-content:space-between;padding:18px 24px;border-bottom:1px solid #ffffff1a}.grid main{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:20px;padding:24px;overflow:auto}.tile{text-align:left}.tile.current{outline:2px solid #38bdf8}.tile.hidden{opacity:.45}.preview{width:200px;overflow:hidden}.tile span{display:block;margin-top:8px;color:#94a3b8}\n"], dependencies: [{ kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
78698
79169
  }
78699
79170
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PresenterControlsComponent, decorators: [{
78700
79171
  type: Component,
@@ -79041,7 +79512,7 @@ class PresenterViewComponent {
79041
79512
  } @else {
79042
79513
  <div class="pptx-ng-presenter-empty">{{ 'pptx.presenter.noSlides' | translate }}</div>
79043
79514
  }
79044
- `, 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", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresenterControlsComponent, selector: "pptx-presenter-controls", inputs: ["snapshot", "audienceOpen", "slides", "current", "canvasSize", "mediaDataUrls"], outputs: ["patch", "navigate", "audience", "end"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
79515
+ `, 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", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresenterControlsComponent, selector: "pptx-presenter-controls", inputs: ["snapshot", "audienceOpen", "slides", "current", "canvasSize", "mediaDataUrls"], outputs: ["patch", "navigate", "audience", "end"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
79045
79516
  }
79046
79517
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PresenterViewComponent, decorators: [{
79047
79518
  type: Component,
@@ -83268,7 +83739,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
83268
83739
  }], propDecorators: { canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }] } });
83269
83740
 
83270
83741
  // Generated by scripts/inline-shared.mjs from package.json. Do not edit.
83271
- const PPTX_ANGULAR_VIEWER_VERSION = "1.31.5";
83742
+ const PPTX_ANGULAR_VIEWER_VERSION = "2.0.1";
83272
83743
 
83273
83744
  /**
83274
83745
  * account-page.component.ts: File > Account content.
@@ -100683,7 +101154,7 @@ class SlideSorterOverlayComponent {
100683
101154
  </div>
100684
101155
  </div>
100685
101156
  </div>
100686
- `, 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", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
101157
+ `, 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", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
100687
101158
  }
100688
101159
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SlideSorterOverlayComponent, decorators: [{
100689
101160
  type: Component,
@@ -100900,7 +101371,7 @@ class SlidesPanelComponent {
100900
101371
  return this.editor.sections().findIndex((section) => section.id === sectionId);
100901
101372
  }
100902
101373
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SlidesPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
100903
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: SlidesPanelComponent, isStandalone: true, selector: "pptx-slides-panel", inputs: { canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select" }, viewQueries: [{ propertyName: "scrollViewport", first: true, predicate: ["scrollViewport"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"pptx-ng-spanel\">\n\t<!-- Scrollable slide list -->\n\t<div\n\t\t#scrollViewport\n\t\tclass=\"pptx-ng-spanel-scroll\"\n\t\trole=\"listbox\"\n\t\t[attr.aria-label]=\"'pptx.sections.slides' | translate\"\n\t\t(scroll)=\"onScroll()\"\n\t>\n\t\t<div\n\t\t\tclass=\"pptx-ng-spanel-space\"\n\t\t\t[attr.data-virtualized]=\"shouldVirtualize() ? 'true' : null\"\n\t\t\t[style.height.px]=\"shouldVirtualize() ? virtualRange().totalHeight : null\"\n\t\t>\n\t\t\t<div\n\t\t\t\tclass=\"pptx-ng-spanel-window\"\n\t\t\t\t[class.is-virtualized]=\"shouldVirtualize()\"\n\t\t\t\t[style.top.px]=\"shouldVirtualize() ? virtualRange().offsetY : null\"\n\t\t\t>\n\t\t\t\t@for (item of renderedSlides(); track item.slide.id) {\n\t\t\t\t\t@let slide = item.slide;\n\t\t\t\t\t@let i = item.index;\n\t\t\t\t\t@if (item.sectionStart) {\n\t\t\t\t\t\t<header class=\"pptx-ng-section-header\" [attr.data-section-id]=\"item.section?.id\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-section-toggle\"\n\t\t\t\t\t\t\t\t[attr.aria-expanded]=\"!item.section?.collapsed\"\n\t\t\t\t\t\t\t\t(click)=\"item.section && editor.sectionOps.toggle(item.section.id)\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span>{{ item.section?.collapsed ? '\u25B8' : '\u25BE' }}</span>\n\t\t\t\t\t\t\t\t<strong>{{\n\t\t\t\t\t\t\t\t\titem.section?.name ?? ('pptx.slides.ungroupedSlides' | translate)\n\t\t\t\t\t\t\t\t}}</strong>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t@if (item.section) {\n\t\t\t\t\t\t\t\t<div class=\"pptx-ng-section-actions\">\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t(click)=\"onRenameSection(item.section.id, item.section.name)\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u270E\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t[disabled]=\"sectionIndex(item.section.id) === 0\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"editor.sectionOps.move(item.section.id, 'up')\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u2191\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t[disabled]=\"sectionIndex(item.section.id) === editor.sections().length - 1\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"editor.sectionOps.move(item.section.id, 'down')\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u2193\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t(click)=\"editor.sectionOps.delete(item.section.id)\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u00D7\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</header>\n\t\t\t\t\t}\n\t\t\t\t\t@if (!item.section?.collapsed) {\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-card\"\n\t\t\t\t\t\t\t[class.is-active]=\"i === activeIndex()\"\n\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t[attr.aria-selected]=\"i === activeIndex()\"\n\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.notes.slideN' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<!-- Thumbnail (clickable to select). Slide number sits to the LEFT\n\t\t\t\t\t\t\t of the preview (React SlideItem parity), not below it. -->\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-thumb-btn\"\n\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.slidesPanel.goToSlide' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t\t\t(click)=\"select.emit(i)\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<!-- Slide number badge (left column) -->\n\t\t\t\t\t\t\t\t<span class=\"pptx-ng-spanel-num\" aria-hidden=\"true\">{{ i + 1 }}</span>\n\n\t\t\t\t\t\t\t\t<!-- Clipping wrapper: neutralises the 1rem auto margin from SlideCanvas -->\n\t\t\t\t\t\t\t\t<div class=\"pptx-ng-spanel-clip\" [ngStyle]=\"clipStyle()\">\n\t\t\t\t\t\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t\t\t\t\t\t[slide]=\"slide\"\n\t\t\t\t\t\t\t\t\t\t[templateElements]=\"editor.templateElementsBySlideId()[slide.id] ?? []\"\n\t\t\t\t\t\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t\t\t\t\t\t[zoom]=\"thumbZoom()\"\n\t\t\t\t\t\t\t\t\t\t[editable]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[autoFit]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t\t<!-- Per-card action toolbar (visible on hover / focus-within) -->\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-actions\"\n\t\t\t\t\t\t\t\trole=\"toolbar\"\n\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.slideMenu.slideActions' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.ribbon.duplicateSlide' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.arrange.duplicate' | translate\"\n\t\t\t\t\t\t\t\t\t(click)=\"onDuplicate(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideCopy class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.slidesPanel.deleteSlide' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.arrange.delete' | translate\"\n\t\t\t\t\t\t\t\t\t[disabled]=\"editor.slides().length <= 1\"\n\t\t\t\t\t\t\t\t\t(click)=\"onDelete(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideTrash2 class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.sections.moveUp' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.sections.moveUp' | translate\"\n\t\t\t\t\t\t\t\t\t[disabled]=\"i === 0\"\n\t\t\t\t\t\t\t\t\t(click)=\"onMoveUp(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideArrowUp class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.sections.moveDown' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.sections.moveDown' | translate\"\n\t\t\t\t\t\t\t\t\t[disabled]=\"i === editor.slides().length - 1\"\n\t\t\t\t\t\t\t\t\t(click)=\"onMoveDown(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideArrowDown class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\n\t<!-- Footer: add new slide -->\n\t<footer class=\"pptx-ng-spanel-footer\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-spanel-add\"\n\t\t\t[attr.aria-label]=\"'pptx.sections.addSlide' | translate\"\n\t\t\t(click)=\"onAddSlide()\"\n\t\t>\n\t\t\t<svg lucidePlus class=\"h-3.5 w-3.5\"></svg> {{ 'pptx.sections.addSlide' | translate }}\n\t\t</button>\n\t</footer>\n</div>\n", styles: [":host{display:flex;flex-direction:column;height:100%;overflow:hidden}.pptx-ng-spanel{display:flex;flex-direction:column;height:100%;background:var(--pptx-secondary, #1e1e1e);color:var(--pptx-foreground, #e5e5e5);border-right:1px solid var(--pptx-border, rgba(255, 255, 255, .08));overflow:hidden}.pptx-ng-spanel-scroll{flex:1;overflow-y:auto;padding:.5rem .375rem}.pptx-ng-spanel-space{position:relative}.pptx-ng-spanel-window{display:flex;flex-direction:column;gap:.375rem}.pptx-ng-spanel-window.is-virtualized{position:absolute;inset-inline:0}.pptx-ng-section-header{display:flex;align-items:center;gap:.2rem;min-height:1.75rem;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .58))}.pptx-ng-section-toggle{display:flex;align-items:center;gap:.35rem;min-width:0;flex:1;border:0;background:transparent;color:inherit;cursor:pointer;text-align:left}.pptx-ng-section-toggle strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.7rem}.pptx-ng-section-actions{display:flex}.pptx-ng-section-actions button{width:1.25rem;height:1.25rem;padding:0;border:0;border-radius:.2rem;background:transparent;color:inherit;cursor:pointer}.pptx-ng-section-actions button:hover:not(:disabled){background:color-mix(in srgb,var(--pptx-primary, #3b82f6) 35%,transparent);color:var(--pptx-foreground, #fff)}.pptx-ng-section-actions button:disabled{opacity:.3}.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:color-mix(in srgb,var(--pptx-foreground, #fff) 5%,transparent);border-color:color-mix(in srgb,var(--pptx-foreground, #fff) 15%,transparent)}.pptx-ng-spanel-card.is-active{border-color:var(--pptx-primary, #3b82f6);background:color-mix(in srgb,var(--pptx-primary, #3b82f6) 10%,transparent)}.pptx-ng-spanel-thumb-btn{display:flex;align-items:center;gap:.25rem;width:100%;padding:.375rem;border:none;background:transparent;cursor:pointer;color:inherit;line-height:0}.pptx-ng-spanel-thumb-btn:focus-visible{outline:2px solid var(--pptx-ring, #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{flex:0 0 auto;width:1.1rem;text-align:right;font-size:.625rem;line-height:1;font-variant-numeric:tabular-nums;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .45));-webkit-user-select:none;user-select:none}.pptx-ng-spanel-card.is-active .pptx-ng-spanel-num{color:var(--pptx-primary, #3b82f6);font-weight:500}.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:color-mix(in srgb,var(--pptx-popover, #1e1e1e) 85%,transparent);color:var(--pptx-popover-foreground, #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:color-mix(in srgb,var(--pptx-primary, #3b82f6) 75%,transparent);color:var(--pptx-primary-foreground, #fff)}.pptx-ng-spanel-action[disabled]{opacity:.3;cursor:not-allowed}.pptx-ng-spanel-footer{flex-shrink:0;padding:.5rem .375rem;border-top:1px solid var(--pptx-border, rgba(255, 255, 255, .08))}.pptx-ng-spanel-add{display:flex;align-items:center;justify-content:center;gap:.25rem;width:100%;padding:.25rem .5rem;border:none;border-radius:.25rem;background:transparent;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .6));font-size:.6875rem;cursor:pointer;transition:background .15s,color .15s}.pptx-ng-spanel-add:hover{background:color-mix(in srgb,var(--pptx-foreground, #fff) 8%,transparent);color:var(--pptx-foreground, #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", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: LucideCopy, selector: "svg[lucideCopy]" }, { kind: "component", type: LucideTrash2, selector: "svg[lucideTrash2]" }, { kind: "component", type: LucideArrowUp, selector: "svg[lucideArrowUp]" }, { kind: "component", type: LucideArrowDown, selector: "svg[lucideArrowDown]" }, { kind: "component", type: LucidePlus, selector: "svg[lucidePlus]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
101374
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: SlidesPanelComponent, isStandalone: true, selector: "pptx-slides-panel", inputs: { canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select" }, viewQueries: [{ propertyName: "scrollViewport", first: true, predicate: ["scrollViewport"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"pptx-ng-spanel\">\n\t<!-- Scrollable slide list -->\n\t<div\n\t\t#scrollViewport\n\t\tclass=\"pptx-ng-spanel-scroll\"\n\t\trole=\"listbox\"\n\t\t[attr.aria-label]=\"'pptx.sections.slides' | translate\"\n\t\t(scroll)=\"onScroll()\"\n\t>\n\t\t<div\n\t\t\tclass=\"pptx-ng-spanel-space\"\n\t\t\t[attr.data-virtualized]=\"shouldVirtualize() ? 'true' : null\"\n\t\t\t[style.height.px]=\"shouldVirtualize() ? virtualRange().totalHeight : null\"\n\t\t>\n\t\t\t<div\n\t\t\t\tclass=\"pptx-ng-spanel-window\"\n\t\t\t\t[class.is-virtualized]=\"shouldVirtualize()\"\n\t\t\t\t[style.top.px]=\"shouldVirtualize() ? virtualRange().offsetY : null\"\n\t\t\t>\n\t\t\t\t@for (item of renderedSlides(); track item.slide.id) {\n\t\t\t\t\t@let slide = item.slide;\n\t\t\t\t\t@let i = item.index;\n\t\t\t\t\t@if (item.sectionStart) {\n\t\t\t\t\t\t<header class=\"pptx-ng-section-header\" [attr.data-section-id]=\"item.section?.id\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-section-toggle\"\n\t\t\t\t\t\t\t\t[attr.aria-expanded]=\"!item.section?.collapsed\"\n\t\t\t\t\t\t\t\t(click)=\"item.section && editor.sectionOps.toggle(item.section.id)\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span>{{ item.section?.collapsed ? '\u25B8' : '\u25BE' }}</span>\n\t\t\t\t\t\t\t\t<strong>{{\n\t\t\t\t\t\t\t\t\titem.section?.name ?? ('pptx.slides.ungroupedSlides' | translate)\n\t\t\t\t\t\t\t\t}}</strong>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t@if (item.section) {\n\t\t\t\t\t\t\t\t<div class=\"pptx-ng-section-actions\">\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t(click)=\"onRenameSection(item.section.id, item.section.name)\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u270E\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t[disabled]=\"sectionIndex(item.section.id) === 0\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"editor.sectionOps.move(item.section.id, 'up')\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u2191\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t[disabled]=\"sectionIndex(item.section.id) === editor.sections().length - 1\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"editor.sectionOps.move(item.section.id, 'down')\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u2193\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t(click)=\"editor.sectionOps.delete(item.section.id)\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u00D7\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</header>\n\t\t\t\t\t}\n\t\t\t\t\t@if (!item.section?.collapsed) {\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-card\"\n\t\t\t\t\t\t\t[class.is-active]=\"i === activeIndex()\"\n\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t[attr.aria-selected]=\"i === activeIndex()\"\n\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.notes.slideN' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<!-- Thumbnail (clickable to select). Slide number sits to the LEFT\n\t\t\t\t\t\t\t of the preview (React SlideItem parity), not below it. -->\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-thumb-btn\"\n\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.slidesPanel.goToSlide' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t\t\t(click)=\"select.emit(i)\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<!-- Slide number badge (left column) -->\n\t\t\t\t\t\t\t\t<span class=\"pptx-ng-spanel-num\" aria-hidden=\"true\">{{ i + 1 }}</span>\n\n\t\t\t\t\t\t\t\t<!-- Clipping wrapper: neutralises the 1rem auto margin from SlideCanvas -->\n\t\t\t\t\t\t\t\t<div class=\"pptx-ng-spanel-clip\" [ngStyle]=\"clipStyle()\">\n\t\t\t\t\t\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t\t\t\t\t\t[slide]=\"slide\"\n\t\t\t\t\t\t\t\t\t\t[templateElements]=\"editor.templateElementsBySlideId()[slide.id] ?? []\"\n\t\t\t\t\t\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t\t\t\t\t\t[zoom]=\"thumbZoom()\"\n\t\t\t\t\t\t\t\t\t\t[editable]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[autoFit]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t\t<!-- Per-card action toolbar (visible on hover / focus-within) -->\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-actions\"\n\t\t\t\t\t\t\t\trole=\"toolbar\"\n\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.slideMenu.slideActions' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.ribbon.duplicateSlide' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.arrange.duplicate' | translate\"\n\t\t\t\t\t\t\t\t\t(click)=\"onDuplicate(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideCopy class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.slidesPanel.deleteSlide' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.arrange.delete' | translate\"\n\t\t\t\t\t\t\t\t\t[disabled]=\"editor.slides().length <= 1\"\n\t\t\t\t\t\t\t\t\t(click)=\"onDelete(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideTrash2 class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.sections.moveUp' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.sections.moveUp' | translate\"\n\t\t\t\t\t\t\t\t\t[disabled]=\"i === 0\"\n\t\t\t\t\t\t\t\t\t(click)=\"onMoveUp(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideArrowUp class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.sections.moveDown' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.sections.moveDown' | translate\"\n\t\t\t\t\t\t\t\t\t[disabled]=\"i === editor.slides().length - 1\"\n\t\t\t\t\t\t\t\t\t(click)=\"onMoveDown(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideArrowDown class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\n\t<!-- Footer: add new slide -->\n\t<footer class=\"pptx-ng-spanel-footer\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-spanel-add\"\n\t\t\t[attr.aria-label]=\"'pptx.sections.addSlide' | translate\"\n\t\t\t(click)=\"onAddSlide()\"\n\t\t>\n\t\t\t<svg lucidePlus class=\"h-3.5 w-3.5\"></svg> {{ 'pptx.sections.addSlide' | translate }}\n\t\t</button>\n\t</footer>\n</div>\n", styles: [":host{display:flex;flex-direction:column;height:100%;overflow:hidden}.pptx-ng-spanel{display:flex;flex-direction:column;height:100%;background:var(--pptx-secondary, #1e1e1e);color:var(--pptx-foreground, #e5e5e5);border-right:1px solid var(--pptx-border, rgba(255, 255, 255, .08));overflow:hidden}.pptx-ng-spanel-scroll{flex:1;overflow-y:auto;padding:.5rem .375rem}.pptx-ng-spanel-space{position:relative}.pptx-ng-spanel-window{display:flex;flex-direction:column;gap:.375rem}.pptx-ng-spanel-window.is-virtualized{position:absolute;inset-inline:0}.pptx-ng-section-header{display:flex;align-items:center;gap:.2rem;min-height:1.75rem;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .58))}.pptx-ng-section-toggle{display:flex;align-items:center;gap:.35rem;min-width:0;flex:1;border:0;background:transparent;color:inherit;cursor:pointer;text-align:left}.pptx-ng-section-toggle strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.7rem}.pptx-ng-section-actions{display:flex}.pptx-ng-section-actions button{width:1.25rem;height:1.25rem;padding:0;border:0;border-radius:.2rem;background:transparent;color:inherit;cursor:pointer}.pptx-ng-section-actions button:hover:not(:disabled){background:color-mix(in srgb,var(--pptx-primary, #3b82f6) 35%,transparent);color:var(--pptx-foreground, #fff)}.pptx-ng-section-actions button:disabled{opacity:.3}.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:color-mix(in srgb,var(--pptx-foreground, #fff) 5%,transparent);border-color:color-mix(in srgb,var(--pptx-foreground, #fff) 15%,transparent)}.pptx-ng-spanel-card.is-active{border-color:var(--pptx-primary, #3b82f6);background:color-mix(in srgb,var(--pptx-primary, #3b82f6) 10%,transparent)}.pptx-ng-spanel-thumb-btn{display:flex;align-items:center;gap:.25rem;width:100%;padding:.375rem;border:none;background:transparent;cursor:pointer;color:inherit;line-height:0}.pptx-ng-spanel-thumb-btn:focus-visible{outline:2px solid var(--pptx-ring, #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{flex:0 0 auto;width:1.1rem;text-align:right;font-size:.625rem;line-height:1;font-variant-numeric:tabular-nums;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .45));-webkit-user-select:none;user-select:none}.pptx-ng-spanel-card.is-active .pptx-ng-spanel-num{color:var(--pptx-primary, #3b82f6);font-weight:500}.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:color-mix(in srgb,var(--pptx-popover, #1e1e1e) 85%,transparent);color:var(--pptx-popover-foreground, #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:color-mix(in srgb,var(--pptx-primary, #3b82f6) 75%,transparent);color:var(--pptx-primary-foreground, #fff)}.pptx-ng-spanel-action[disabled]{opacity:.3;cursor:not-allowed}.pptx-ng-spanel-footer{flex-shrink:0;padding:.5rem .375rem;border-top:1px solid var(--pptx-border, rgba(255, 255, 255, .08))}.pptx-ng-spanel-add{display:flex;align-items:center;justify-content:center;gap:.25rem;width:100%;padding:.25rem .5rem;border:none;border-radius:.25rem;background:transparent;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .6));font-size:.6875rem;cursor:pointer;transition:background .15s,color .15s}.pptx-ng-spanel-add:hover{background:color-mix(in srgb,var(--pptx-foreground, #fff) 8%,transparent);color:var(--pptx-foreground, #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", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: LucideCopy, selector: "svg[lucideCopy]" }, { kind: "component", type: LucideTrash2, selector: "svg[lucideTrash2]" }, { kind: "component", type: LucideArrowUp, selector: "svg[lucideArrowUp]" }, { kind: "component", type: LucideArrowDown, selector: "svg[lucideArrowDown]" }, { kind: "component", type: LucidePlus, selector: "svg[lucidePlus]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
100904
101375
  }
100905
101376
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SlidesPanelComponent, decorators: [{
100906
101377
  type: Component,
@@ -102385,7 +102856,7 @@ class SlideDiffThumbnailsComponent {
102385
102856
  </div>
102386
102857
  }
102387
102858
  </div>
102388
- `, isInline: true, styles: [".pptx-ng-diff-thumbs{display:flex;gap:.5rem}.pptx-ng-diff-thumb-col{flex:1}.pptx-ng-diff-thumb-label{margin-bottom:.25rem;font-size:.625rem;color:var(--pptx-muted-foreground, #9ca3af)}.pptx-ng-diff-thumb-clip{overflow:hidden;border:1px solid var(--pptx-border, #374151);border-radius:.25rem}.pptx-ng-diff-thumb-clip[data-status=added]{border-color:#15803d99}.pptx-ng-diff-thumb-clip[data-status=changed]{border-color:#b4530999}.pptx-ng-diff-thumb-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}\n"], dependencies: [{ kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
102859
+ `, isInline: true, styles: [".pptx-ng-diff-thumbs{display:flex;gap:.5rem}.pptx-ng-diff-thumb-col{flex:1}.pptx-ng-diff-thumb-label{margin-bottom:.25rem;font-size:.625rem;color:var(--pptx-muted-foreground, #9ca3af)}.pptx-ng-diff-thumb-clip{overflow:hidden;border:1px solid var(--pptx-border, #374151);border-radius:.25rem}.pptx-ng-diff-thumb-clip[data-status=added]{border-color:#15803d99}.pptx-ng-diff-thumb-clip[data-status=changed]{border-color:#b4530999}.pptx-ng-diff-thumb-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}\n"], dependencies: [{ kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
102389
102860
  }
102390
102861
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SlideDiffThumbnailsComponent, decorators: [{
102391
102862
  type: Component,
@@ -107915,8 +108386,13 @@ class PowerPointViewerComponent {
107915
108386
  this.zoomTarget.setSlides(this.mergedSlides());
107916
108387
  });
107917
108388
  // Connect / disconnect real-time collaboration when the host config changes.
108389
+ // Track ONLY the `collaboration` input: `syncHostConfig` synchronously
108390
+ // reads other signals (canvas size, current slides for the baseline), and
108391
+ // tracking those would re-run this effect mid-connect (e.g. when a guest's
108392
+ // placeholder deck loads) and double-join the Yjs room.
107918
108393
  effect(() => {
107919
- this.session.syncHostConfig(this.collaboration());
108394
+ const config = this.collaboration();
108395
+ untracked(() => this.session.syncHostConfig(config));
107920
108396
  });
107921
108397
  // Push local slide edits into the shared Y.Doc (reconcile-based; the
107922
108398
  // service guards against echoing remote-applied changes and against
@@ -108865,6 +109341,7 @@ class PowerPointViewerComponent {
108865
109341
  (toggleAiPanel)="aiPanelOpen.update(v => !v)"
108866
109342
  (undo)="editor.undo()"
108867
109343
  (redo)="editor.redo()"
109344
+ (share)="session.showShare.set(true)"
108868
109345
  (save)="fileIO.saveAsPptx()"
108869
109346
  (present)="presentationMode.present()"
108870
109347
  />
@@ -108930,6 +109407,7 @@ class PowerPointViewerComponent {
108930
109407
  (contextMenu)="canvasEditing.onContextMenu($event)"
108931
109408
  [editingId]="canvasEditing.editingId()"
108932
109409
  (textEditStart)="canvasEditing.onTextEditStart($event.id)"
109410
+ (textInput)="canvasEditing.onTextInput($event)"
108933
109411
  (textCommit)="canvasEditing.onTextCommit($event)"
108934
109412
  (textCancel)="canvasEditing.editingId.set(null)"
108935
109413
  (textFormat)="canvasEditing.onTextFormat($event)"
@@ -108966,6 +109444,16 @@ class PowerPointViewerComponent {
108966
109444
  reclaims the canvas.
108967
109445
  -->
108968
109446
  @if (inspectorPanel.visibleInspectorKind(); as kind) {
109447
+ <!--
109448
+ Mobile-only tap-to-dismiss backdrop behind the inspector sheet
109449
+ (hidden on desktop via CSS, mirroring React's MobileDismissSheet).
109450
+ -->
109451
+ <button
109452
+ type="button"
109453
+ class="pptx-ng-inspector-backdrop"
109454
+ [attr.aria-label]="'pptx.mobileSheet.close' | translate"
109455
+ (click)="inspectorPanel.dismissMobileInspector()"
109456
+ ></button>
108969
109457
  <aside
108970
109458
  data-pptx-inspector
108971
109459
  class="pptx-ng-inspector-host"
@@ -109426,7 +109914,7 @@ class PowerPointViewerComponent {
109426
109914
  />
109427
109915
  }
109428
109916
  </div>
109429
- `, 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", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationOverlayComponent, selector: "pptx-presentation-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "startIndex", "showWithAnimation", "subtitlesVisible"], outputs: ["indexChange", "closed", "subtitlesChange", "annotationsExit"] }, { kind: "component", type: PresenterViewComponent, selector: "pptx-presenter-view", inputs: ["slides", "currentSlideIndex", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime", "isAudienceWindowOpen"], outputs: ["movePresentationSlide", "exit", "openAudienceWindow", "closeAudienceWindow", "navigateToSlide"] }, { kind: "component", type: MobilePresenterViewComponent, selector: "pptx-mobile-presenter-view", inputs: ["slides", "currentSlideIndex", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime"], outputs: ["movePresentationSlide", "exit"] }, { kind: "component", type: SlideSorterOverlayComponent, selector: "pptx-slide-sorter-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select", "closed"] }, { kind: "component", type: SlideDefaultInspectorComponent, selector: "pptx-slide-default-inspector", inputs: ["slideIndex", "canEdit", "selectedElement", "comments"], outputs: ["commentAdd", "commentRemove", "commentResolve"] }, { 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: SlidesPanelComponent, selector: "pptx-slides-panel", inputs: ["canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select"] }, { kind: "component", type: StatusBarComponent, selector: "pptx-status-bar", inputs: ["slideIndex", "slideCount", "canEdit", "dirty", "autosaveStatus", "notesOpen", "zoomPercent", "sorterActive", "presenting", "hiddenActions"], outputs: ["toggleNotes", "normalView", "openSorter", "slideShow", "zoomIn", "zoomOut", "zoomReset"] }, { kind: "component", type: EditorContextMenuComponent, selector: "pptx-editor-context-menu", inputs: ["x", "y", "slideIndex", "showAiActions"], outputs: ["closed", "askAi", "fixAi"] }, { kind: "component", type: ExportProgressModalComponent, selector: "pptx-export-progress-modal", inputs: ["open", "title", "progress", "statusMessage"], outputs: ["cancel"] }, { 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: RemoteSelectionOverlayComponent, selector: "pptx-remote-selection-overlay", inputs: ["presences", "elements", "activeSlideIndex", "zoom"] }, { kind: "component", type: FollowModeBarComponent, selector: "pptx-follow-mode-bar", inputs: ["presences", "followedClientId"], outputs: ["follow"] }, { 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", "connected", "userCount", "shareUrl", "p2p"], outputs: ["start", "stop", "close"] }, { kind: "component", type: BroadcastDialogComponent, selector: "pptx-broadcast-dialog", inputs: ["open", "defaults", "active", "connected", "viewerCount", "viewerUrl", "p2p"], outputs: ["start", "stop", "close"] }, { kind: "component", type: MobileBottomBarComponent, selector: "pptx-mobile-bottom-bar", inputs: ["slideCount", "commentCount", "activeSheet"], outputs: ["openSlides", "insert", "openFormat", "openComments", "notes"] }, { kind: "component", type: MobileMenuSheetComponent, selector: "pptx-mobile-menu-sheet", inputs: ["open", "slideCount", "exporting", "showNotes", "canEdit", "hiddenActions"], outputs: ["closed", "openFind", "openSorter", "toggleNotes", "insertText", "present", "openFile", "savePptx", "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: MobileToolbarComponent, selector: "pptx-mobile-toolbar", inputs: ["canUndo", "canRedo", "canPresent", "canEdit", "menuOpen", "aiEnabled", "aiPanelOpen", "hiddenActions"], outputs: ["toggleMenu", "toggleAiPanel", "undo", "redo", "save", "present"] }, { kind: "component", type: MasterViewCanvasComponent, selector: "pptx-master-view-canvas", inputs: ["tab", "slideMasters", "activeMasterIndex", "activeLayoutIndex", "notesMaster", "handoutMaster", "canvasSize", "notesCanvasSize", "mediaDataUrls", "editable"], outputs: ["notesMasterChange", "handoutMasterChange"] }, { kind: "component", type: MasterViewSidebarComponent, selector: "pptx-master-view-sidebar", inputs: ["tab", "slideMasters", "notesMaster", "handoutMaster", "activeMasterIndex", "activeLayoutIndex", "handoutSlidesPerPage"], outputs: ["tabChange", "selectMaster", "selectLayout", "slidesPerPageChange", "backgroundChange", "close"] }, { kind: "component", type: NotesPanelComponent, selector: "pptx-notes-panel", inputs: ["slide", "expanded"], outputs: ["update", "notesToggle"] }, { kind: "component", type: RibbonComponent, selector: "pptx-ribbon", inputs: ["slideIndex", "slideCount", "canEdit", "selectedElement", "zoomPercent", "formatPainterActive", "canActivateFormatPainter", "exporting", "hasMacros", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "eyedropperActive", "themeGalleryOpen", "sidebarCollapsed", "inspectorOpen", "commentsOpen", "commentCount", "findOpen", "collabConnected", "connectedCount", "spellCheckEnabled", "showSubtitles", "hiddenActions", "aiEnabled", "aiPanelOpen", "accountAuth"], outputs: ["prev", "next", "zoomIn", "zoomOut", "zoomReset", "find", "present", "presenter", "record", "presentFromBeginning", "rehearseTimings", "toggleSubtitles", "openSubtitleSettings", "recordFromBeginning", "recordFromCurrent", "spellCheckChange", "share", "broadcast", "openFile", "openRecentFile", "createPresentation", "save", "savePpsx", "savePptm", "packageForSharing", "toggleSidebar", "toggleAiPanel", "signatures", "info", "print", "comments", "a11y", "link", "openSorter", "openMasterView", "toggleNotes", "toggleFormatPainter", "exportPng", "exportPdf", "exportGif", "exportVideo", "copySlideAsImage", "replace", "toggleInspector", "drawToolChange", "toggleThemeGallery", "toggleGrid", "toggleRulers", "toggleGuides", "toggleSelectionPane", "openCustomShows", "toggleSnapToGrid", "toggleSnapToShape", "addGuide", "zoomToFit", "toggleEyedropper", "openSmartArtDialog", "openEquationDialog", "openSetUpSlideShow", "openCompare", "openPassword", "openFontEmbedding", "openVersionHistory", "openShortcuts", "openSettings"] }, { kind: "component", type: TitleBarComponent, selector: "pptx-title-bar", inputs: ["canEdit", "fileName", "isDirty", "autosaveStatus", "autosaveEnabled", "canUndo", "canRedo", "undoLabel", "redoLabel", "findReplaceOpen", "hiddenActions", "quickAccess"], outputs: ["toggleAutosave", "save", "undo", "redo", "quickCommand", "toggleFindReplace", "commandSearch"] }, { kind: "component", type: ThemeGalleryComponent, selector: "pptx-theme-gallery", inputs: ["open", "activeName", "theme"], outputs: ["applyTheme", "applyCustomTheme", "close"] }, { kind: "component", type: SelectionPaneComponent, selector: "pptx-selection-pane", inputs: ["elements", "selectedIds"], outputs: ["selectElement", "bringForward", "sendBackward", "toggleHidden"] }, { kind: "component", type: CustomShowsComponent, selector: "pptx-custom-shows", inputs: ["open", "slides", "customShows", "activeCustomShowId"], outputs: ["create", "remove", "update", "setActive", "close"] }, { kind: "component", type: InsertSmartArtDialogComponent, selector: "pptx-insert-smart-art-dialog", inputs: ["open"], outputs: ["close", "insert"] }, { kind: "component", type: ViewerExtraDialogsComponent, selector: "pptx-viewer-extra-dialogs", inputs: ["activeSlideIndex", "selectedElementId", "filePath", "customShows", "themeKey", "availableThemes", "localeCode", "availableLocales", "aiExportVisible"], outputs: ["restoreContent", "themeKeySelect", "localeSelect"] }, { kind: "component", type: RehearseTimingsComponent, selector: "pptx-rehearse-timings", inputs: ["summary", "paused", "slideStartedAt", "presentationStartedAt", "timings"], outputs: ["togglePause", "save", "discard"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [/* @ts-ignore */
109917
+ `, 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", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationOverlayComponent, selector: "pptx-presentation-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "startIndex", "showWithAnimation", "subtitlesVisible"], outputs: ["indexChange", "closed", "subtitlesChange", "annotationsExit"] }, { kind: "component", type: PresenterViewComponent, selector: "pptx-presenter-view", inputs: ["slides", "currentSlideIndex", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime", "isAudienceWindowOpen"], outputs: ["movePresentationSlide", "exit", "openAudienceWindow", "closeAudienceWindow", "navigateToSlide"] }, { kind: "component", type: MobilePresenterViewComponent, selector: "pptx-mobile-presenter-view", inputs: ["slides", "currentSlideIndex", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime"], outputs: ["movePresentationSlide", "exit"] }, { kind: "component", type: SlideSorterOverlayComponent, selector: "pptx-slide-sorter-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select", "closed"] }, { kind: "component", type: SlideDefaultInspectorComponent, selector: "pptx-slide-default-inspector", inputs: ["slideIndex", "canEdit", "selectedElement", "comments"], outputs: ["commentAdd", "commentRemove", "commentResolve"] }, { 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: SlidesPanelComponent, selector: "pptx-slides-panel", inputs: ["canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select"] }, { kind: "component", type: StatusBarComponent, selector: "pptx-status-bar", inputs: ["slideIndex", "slideCount", "canEdit", "dirty", "autosaveStatus", "notesOpen", "zoomPercent", "sorterActive", "presenting", "hiddenActions"], outputs: ["toggleNotes", "normalView", "openSorter", "slideShow", "zoomIn", "zoomOut", "zoomReset"] }, { kind: "component", type: EditorContextMenuComponent, selector: "pptx-editor-context-menu", inputs: ["x", "y", "slideIndex", "showAiActions"], outputs: ["closed", "askAi", "fixAi"] }, { kind: "component", type: ExportProgressModalComponent, selector: "pptx-export-progress-modal", inputs: ["open", "title", "progress", "statusMessage"], outputs: ["cancel"] }, { 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: RemoteSelectionOverlayComponent, selector: "pptx-remote-selection-overlay", inputs: ["presences", "elements", "activeSlideIndex", "zoom"] }, { kind: "component", type: FollowModeBarComponent, selector: "pptx-follow-mode-bar", inputs: ["presences", "followedClientId"], outputs: ["follow"] }, { 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", "connected", "userCount", "shareUrl", "p2p"], outputs: ["start", "stop", "close"] }, { kind: "component", type: BroadcastDialogComponent, selector: "pptx-broadcast-dialog", inputs: ["open", "defaults", "active", "connected", "viewerCount", "viewerUrl", "p2p"], outputs: ["start", "stop", "close"] }, { kind: "component", type: MobileBottomBarComponent, selector: "pptx-mobile-bottom-bar", inputs: ["slideCount", "commentCount", "activeSheet"], outputs: ["openSlides", "insert", "openFormat", "openComments", "notes"] }, { kind: "component", type: MobileMenuSheetComponent, selector: "pptx-mobile-menu-sheet", inputs: ["open", "slideCount", "exporting", "showNotes", "canEdit", "hiddenActions"], outputs: ["closed", "openFind", "openSorter", "toggleNotes", "insertText", "present", "openFile", "savePptx", "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: MobileToolbarComponent, selector: "pptx-mobile-toolbar", inputs: ["canUndo", "canRedo", "canPresent", "canEdit", "menuOpen", "aiEnabled", "aiPanelOpen", "hiddenActions"], outputs: ["toggleMenu", "toggleAiPanel", "undo", "redo", "share", "save", "present"] }, { kind: "component", type: MasterViewCanvasComponent, selector: "pptx-master-view-canvas", inputs: ["tab", "slideMasters", "activeMasterIndex", "activeLayoutIndex", "notesMaster", "handoutMaster", "canvasSize", "notesCanvasSize", "mediaDataUrls", "editable"], outputs: ["notesMasterChange", "handoutMasterChange"] }, { kind: "component", type: MasterViewSidebarComponent, selector: "pptx-master-view-sidebar", inputs: ["tab", "slideMasters", "notesMaster", "handoutMaster", "activeMasterIndex", "activeLayoutIndex", "handoutSlidesPerPage"], outputs: ["tabChange", "selectMaster", "selectLayout", "slidesPerPageChange", "backgroundChange", "close"] }, { kind: "component", type: NotesPanelComponent, selector: "pptx-notes-panel", inputs: ["slide", "expanded"], outputs: ["update", "notesToggle"] }, { kind: "component", type: RibbonComponent, selector: "pptx-ribbon", inputs: ["slideIndex", "slideCount", "canEdit", "selectedElement", "zoomPercent", "formatPainterActive", "canActivateFormatPainter", "exporting", "hasMacros", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "eyedropperActive", "themeGalleryOpen", "sidebarCollapsed", "inspectorOpen", "commentsOpen", "commentCount", "findOpen", "collabConnected", "connectedCount", "spellCheckEnabled", "showSubtitles", "hiddenActions", "aiEnabled", "aiPanelOpen", "accountAuth"], outputs: ["prev", "next", "zoomIn", "zoomOut", "zoomReset", "find", "present", "presenter", "record", "presentFromBeginning", "rehearseTimings", "toggleSubtitles", "openSubtitleSettings", "recordFromBeginning", "recordFromCurrent", "spellCheckChange", "share", "broadcast", "openFile", "openRecentFile", "createPresentation", "save", "savePpsx", "savePptm", "packageForSharing", "toggleSidebar", "toggleAiPanel", "signatures", "info", "print", "comments", "a11y", "link", "openSorter", "openMasterView", "toggleNotes", "toggleFormatPainter", "exportPng", "exportPdf", "exportGif", "exportVideo", "copySlideAsImage", "replace", "toggleInspector", "drawToolChange", "toggleThemeGallery", "toggleGrid", "toggleRulers", "toggleGuides", "toggleSelectionPane", "openCustomShows", "toggleSnapToGrid", "toggleSnapToShape", "addGuide", "zoomToFit", "toggleEyedropper", "openSmartArtDialog", "openEquationDialog", "openSetUpSlideShow", "openCompare", "openPassword", "openFontEmbedding", "openVersionHistory", "openShortcuts", "openSettings"] }, { kind: "component", type: TitleBarComponent, selector: "pptx-title-bar", inputs: ["canEdit", "fileName", "isDirty", "autosaveStatus", "autosaveEnabled", "canUndo", "canRedo", "undoLabel", "redoLabel", "findReplaceOpen", "hiddenActions", "quickAccess"], outputs: ["toggleAutosave", "save", "undo", "redo", "quickCommand", "toggleFindReplace", "commandSearch"] }, { kind: "component", type: ThemeGalleryComponent, selector: "pptx-theme-gallery", inputs: ["open", "activeName", "theme"], outputs: ["applyTheme", "applyCustomTheme", "close"] }, { kind: "component", type: SelectionPaneComponent, selector: "pptx-selection-pane", inputs: ["elements", "selectedIds"], outputs: ["selectElement", "bringForward", "sendBackward", "toggleHidden"] }, { kind: "component", type: CustomShowsComponent, selector: "pptx-custom-shows", inputs: ["open", "slides", "customShows", "activeCustomShowId"], outputs: ["create", "remove", "update", "setActive", "close"] }, { kind: "component", type: InsertSmartArtDialogComponent, selector: "pptx-insert-smart-art-dialog", inputs: ["open"], outputs: ["close", "insert"] }, { kind: "component", type: ViewerExtraDialogsComponent, selector: "pptx-viewer-extra-dialogs", inputs: ["activeSlideIndex", "selectedElementId", "filePath", "customShows", "themeKey", "availableThemes", "localeCode", "availableLocales", "aiExportVisible"], outputs: ["restoreContent", "themeKeySelect", "localeSelect"] }, { kind: "component", type: RehearseTimingsComponent, selector: "pptx-rehearse-timings", inputs: ["summary", "paused", "slideStartedAt", "presentationStartedAt", "timings"], outputs: ["togglePause", "save", "discard"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [/* @ts-ignore */
109430
109918
  Promise.resolve().then(function () { return aiChatPanel_component; }).then(m => m.AiChatPanelComponent)]] });
109431
109919
  }
109432
109920
  i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.0.8", ngImport: i0, type: PowerPointViewerComponent, resolveDeferredDeps: () => [/* @ts-ignore */
@@ -109638,6 +110126,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.0.8", ng
109638
110126
  (toggleAiPanel)="aiPanelOpen.update(v => !v)"
109639
110127
  (undo)="editor.undo()"
109640
110128
  (redo)="editor.redo()"
110129
+ (share)="session.showShare.set(true)"
109641
110130
  (save)="fileIO.saveAsPptx()"
109642
110131
  (present)="presentationMode.present()"
109643
110132
  />
@@ -109703,6 +110192,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.0.8", ng
109703
110192
  (contextMenu)="canvasEditing.onContextMenu($event)"
109704
110193
  [editingId]="canvasEditing.editingId()"
109705
110194
  (textEditStart)="canvasEditing.onTextEditStart($event.id)"
110195
+ (textInput)="canvasEditing.onTextInput($event)"
109706
110196
  (textCommit)="canvasEditing.onTextCommit($event)"
109707
110197
  (textCancel)="canvasEditing.editingId.set(null)"
109708
110198
  (textFormat)="canvasEditing.onTextFormat($event)"
@@ -109739,6 +110229,16 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.0.8", ng
109739
110229
  reclaims the canvas.
109740
110230
  -->
109741
110231
  @if (inspectorPanel.visibleInspectorKind(); as kind) {
110232
+ <!--
110233
+ Mobile-only tap-to-dismiss backdrop behind the inspector sheet
110234
+ (hidden on desktop via CSS, mirroring React's MobileDismissSheet).
110235
+ -->
110236
+ <button
110237
+ type="button"
110238
+ class="pptx-ng-inspector-backdrop"
110239
+ [attr.aria-label]="'pptx.mobileSheet.close' | translate"
110240
+ (click)="inspectorPanel.dismissMobileInspector()"
110241
+ ></button>
109742
110242
  <aside
109743
110243
  data-pptx-inspector
109744
110244
  class="pptx-ng-inspector-host"
@@ -112053,4 +112553,4 @@ function cn(...values) {
112053
112553
  */
112054
112554
 
112055
112555
  export { DATA_TABLE_KEY_W as $, ALIGN_OPTIONS as A, BroadcastDialogComponent as B, CHART_EDITOR_STYLES as C, ChartAxisOptionsComponent as D, ChartAxisStyleOptionsComponent as E, ChartComboTypeOptionsComponent as F, ChartDataEditorComponent as G, ChartDataLabelOptionsComponent as H, ChartDatapointOptionsComponent as I, ChartDisplayOptionsComponent as J, ChartElementViewComponent as K, ChartErrorBarOptionsComponent as L, ChartMarkerOptionsComponent as M, ChartPartSelectionService as N, ChartPrimitivesComponent as O, ChartRendererComponent as P, ChartTrendlineOptionsComponent as Q, CollaborationCursorsComponent as R, CollaborationService as S, ColorChangedImageComponent as T, CommentsPanelComponent as U, CommentsService as V, ComparePanelComponent as W, ConnectorRendererComponent as X, ConnectorTextOverlayComponent as Y, CustomShowsComponent as Z, DATA_TABLE_HEADER_H as _, AUDIENCE_HASH as a, MIN_ZOOM_SCALE as a$, DATA_TABLE_PADDING as a0, DATA_TABLE_ROW_H as a1, DEFAULT_BOUNDS as a2, DEFAULT_BROADCAST_SERVER_URL as a3, DEFAULT_CANVAS_HEIGHT as a4, DEFAULT_CANVAS_WIDTH as a5, DEFAULT_COLOR_SCHEME as a6, DEFAULT_FILL_COLOR as a7, DEFAULT_LAYOUT as a8, DEFAULT_PALETTE$1 as a9, ExportProgressModalComponent as aA, ExportService as aB, FieldContextService as aC, FindBarComponent as aD, FindReplaceBarComponent as aE, FollowModeBarComponent as aF, FontEmbeddingListComponent as aG, FontEmbeddingPanelComponent as aH, GALLERY_THEME_PRESETS as aI, GradientPickerComponent as aJ, HANDOUT_OPTIONS as aK, HeaderFooterDialogComponent as aL, HyperlinkDialogComponent as aM, ImagePropertiesPanelComponent as aN, InkDrawingService as aO, InkRendererComponent as aP, InsertSmartArtDialogComponent as aQ, InspectorPaneHeaderComponent as aR, InspectorPanelComponent as aS, IsMobileService as aT, KeepAnnotationsDialogComponent as aU, LOCALE_CATALOG as aV, LONG_PRESS_DURATION_MS as aW, LONG_PRESS_MOVE_TOLERANCE_PX as aX, LoadContentService as aY, LocalPresencePublisher as aZ, MAX_ZOOM_SCALE as a_, DEFAULT_PRINT_SETTINGS as aa, DEFAULT_SLIDE_BACKGROUND as ab, DEFAULT_STROKE_COLOR as ac, DEFAULT_STYLE as ad, DEFAULT_TABLE_ROW_HEIGHT as ae, DEFAULT_TEXT_COLOR$1 as af, DEFAULT_VIEWER_PROFILE as ag, DIRECTIONAL_PRESETS as ah, DIRECTION_OPTIONS as ai, DocumentPropertiesCardComponent as aj, EMBEDDED_FONTS_STYLE_ID as ak, EMPHASIS_PRESETS as al, ENTRANCE_PRESETS as am, TEMPLATES as an, EXIT_PRESETS as ao, EditorContextMenuComponent as ap, EditorHistory as aq, EditorStateService as ar, EditorToolbarComponent as as, EffectsPanelComponent as at, ElementRendererComponent as au, EmbeddedFontsService as av, EncryptedFileDialogComponent as aw, EquationEditorDialogComponent as ax, EquationRendererComponent as ay, EquationTemplateGalleryComponent as az, AUDIENCE_NONCE_KEY as b, SLIDE_PX_PER_INCH as b$, MediaPreviewComponent as b0, MediaPropertiesPanelComponent as b1, MediaRendererComponent as b2, MediaTrimTimelineComponent as b3, MobileBottomBarComponent as b4, MobileMenuSheetComponent as b5, MobilePresenterViewComponent as b6, MobileSheetComponent as b7, MobileSlidesSheetComponent as b8, MobileToolbarComponent as b9, RESIZE_HANDLES as bA, RULER_THICKNESS as bB, RemoteSelectionOverlayComponent as bC, RibbonAnimationsSectionComponent as bD, RibbonArrangeSectionComponent as bE, RibbonColorPopoverComponent as bF, RibbonComponent as bG, RibbonDesignSectionComponent as bH, RibbonDrawSectionComponent as bI, RibbonDrawingGroupComponent as bJ, RibbonEditingSectionComponent as bK, RibbonFileSectionComponent as bL, RibbonFontControlsComponent as bM, RibbonHomeSectionComponent as bN, RibbonInsertFieldsComponent as bO, RibbonInsertSectionComponent as bP, RibbonParagraphControlsComponent as bQ, RibbonPrimaryRowComponent as bR, RibbonReviewSectionComponent as bS, RibbonSlideshowSectionComponent as bT, RibbonTransitionsSectionComponent as bU, RibbonViewSectionComponent as bV, RulerGuidesService as bW, SEQUENCE_OPTIONS as bX, SEVERITY_GROUPS as bY, SEVERITY_LABELS as bZ, SHORTCUT_REFERENCE_ITEMS as b_, ModalDialogComponent as ba, Model3DRendererComponent as bb, NotesHandoutCardComponent as bc, NotesPanelComponent as bd, NotesToolbarComponent as be, OleRendererComponent as bf, POWER_POINT_VIEWER_PROVIDERS as bg, PRESENTER_CHANNEL_NAME as bh, PRESENTER_MSG_ORIGIN as bi, PasswordProtectionDialogComponent as bj, PasswordStrengthMeterComponent as bk, PowerPointViewerComponent as bl, PresentationAnnotationOverlayComponent as bm, PresentationAnnotationsService as bn, PresentationOverlayComponent as bo, PresentationPropertiesPanelComponent as bp, PresentationSettingsCardComponent as bq, PresentationSubtitleBarComponent as br, PresentationTransitionOverlayComponent as bs, PresenterViewComponent as bt, PresenterWindowService as bu, PrintDialogComponent as bv, PrintService as bw, PrintSettingsPanelComponent as bx, PropertiesDialogComponent as by, REPEAT_MODE_OPTIONS as bz, AVATAR_COLOR_SWATCHES as c, ViewerDocumentPropertiesService as c$, SLIDE_TRANSITION_KEYFRAMES as c0, DEFAULT_PALETTE as c1, PALETTES$1 as c2, SMART_ART_COLOR_SCHEMES as c3, SMART_ART_STYLE_OPTIONS as c4, SUB_ITEM_LABEL as c5, SVG_WARP_PRESETS as c6, SWIPE_MAX_VERTICAL_PX as c7, SWIPE_THRESHOLD_PX as c8, SelectionPaneComponent as c9, TABLE_STRUCTURE_TOGGLES as cA, TEXT_DIRECTION_OPTIONS$1 as cB, THEME_CATALOG as cC, TIMING_CURVE_OPTIONS as cD, TRIGGER_OPTIONS as cE, TYPE_LABELS as cF, TableCellAdvancedFillComponent as cG, TableCellFormattingComponent as cH, TableDataEditorComponent as cI, TablePropertiesComponent as cJ, TableRendererComponent as cK, TableResizeOverlayComponent as cL, TableSelectionService as cM, TextAdvancedPanelComponent as cN, ThemeEditorFieldsComponent as cO, ThemeGalleryComponent as cP, ThemeSelectorCardComponent as cQ, TitleBarComponent as cR, VALIGN_OPTIONS as cS, VIEWER_THEME as cT, VersionHistoryPanelComponent as cU, ViewerCanvasEditingService as cV, ViewerCollabCursorService as cW, ViewerCollaborationSessionService as cX, ViewerCompareService as cY, ViewerCustomShowsService as cZ, ViewerDialogsService as c_, SetUpSlideShowDialogComponent as ca, SettingsAppearanceTabComponent as cb, SettingsDialogComponent as cc, SettingsLanguageTabComponent as cd, ShareDialogComponent as ce, ShortcutPanelComponent as cf, ShowOptionsFieldsetComponent as cg, ShowSlidesFieldsetComponent as ch, SignatureStrippedDialogComponent as ci, SignaturesPanelComponent as cj, SignaturesService as ck, SlideCanvasComponent as cl, SlideDefaultInspectorComponent as cm, SlideDiffChangesComponent as cn, SlideDiffRowComponent as co, SlideDiffThumbnailsComponent as cp, SlideSizeCardComponent as cq, SlideSorterOverlayComponent as cr, SlideThemeOverridePanelComponent as cs, SlidesPanelComponent as ct, SmartArt3DRendererComponent as cu, SmartArt3DService as cv, SmartArtPreviewComponent as cw, SmartArtPropertiesComponent as cx, SmartArtRendererComponent as cy, StatusBarComponent as cz, AccessibilityPanelComponent as d, buildFallbackViewModel as d$, ViewerExportService as d0, ViewerExtraDialogsComponent as d1, ViewerFileIOService as d2, ViewerFindReplaceService as d3, ViewerFormatPainterService as d4, ViewerInspectorPanelService as d5, ViewerKeyboardService as d6, ViewerMobileSheetService as d7, ViewerPresentationModeService as d8, ViewerThemeGalleryService as d9, asMediaElement as dA, assignUserColor as dB, attachTouchGestures as dC, beginNodeEdit as dD, boolFromEvent as dE, bringForward as dF, bringToFront as dG, buildBarActions as dH, buildBroadcastConfig as dI, buildBroadcastViewerUrl as dJ, buildCategoryLabels as dK, buildCellParagraphs as dL, buildChartViewModel as dM, buildChatLogExport as dN, buildChatLogMarkdown as dO, buildChromeStyle as dP, buildClearHyperlinkPatch as dQ, buildClickGroups as dR, buildColStyles as dS, buildCollaborationConfig as dT, buildComboViewModel as dU, buildCssGradientFromShapeStyle as dV, buildDuotoneFilter as dW, buildDuotoneFilterId as dX, buildEmbeddedFontStyles as dY, buildEquationElement as dZ, buildEquationSegment as d_, ViewerTouchGesturesService as da, ViewerZoomService as db, WEBM_MIME_CANDIDATES as dc, WriteBackScheduler as dd, ZoomNavigationService as de, ZoomRendererComponent as df, ZoomTargetService as dg, addCategory as dh, addCommentToList as di, addGradientStopPatch as dj, addItem as dk, addSeries as dl, addSubItem as dm, advanceStep as dn, aiToggleVisible as dp, alignPatch as dq, animationFor as dr, annotationMapToInkInserts as ds, applyAcceptedDiff as dt, applyAnimationPreset as du, applyFindReplacements as dv, applyFormatToElement as dw, applyMove as dx, applyResize as dy, applyTableStylePreset as dz, AccessibilityService as e, computeDataTablePrimitives as e$, buildFontFaceRule as e0, buildGradientFillCss as e1, buildGridlinesAndLabels as e2, buildHyperlinkPatch as e3, buildInkContainerStyle as e4, buildInkStrokes as e5, buildLegend as e6, buildModel3DContainerStyle as e7, buildModel3DViewModel as e8, buildOleActionModel as e9, cellStyleToStyleMap as eA, cellTdStyle as eB, changeCountLabel as eC, changeIcon as eD, characterSpacingPatch as eE, checkFontAvailable as eF, clampCursorPosition as eG, clampGifDimensions as eH, clampIndex as eI, clampNotesFontSize as eJ, clampScale as eK, clampStep as eL, clearAllLocalViewerData as eM, clearAudienceContent as eN, cn as eO, collectAccessibilityIssues as eP, collectElementText as eQ, collectSlideText as eR, collectStoredChats as eS, collectUsedFontFamilies as eT, columnWidthStyle as eU, commitNodeText as eV, computeAlign as eW, computeAxisTitlePrimitives as eX, computeBarRects as eY, computeBubbleRadius as eZ, computeCornerHandle as e_, buildOleInfoRows as ea, buildPatternFillCss as eb, buildPrintHtmlDocument as ec, buildPropertiesPatch as ed, buildRegionMapViewModel as ee, buildSaveSlides as ef, buildShareUrl as eg, buildSmartArtInsertElement as eh, buildSmartArtNodes as ei, buildStockViewModel as ej, buildSurfaceViewModel as ek, buildTableViewModel as el, buildTreemapViewModel as em, buildTrimFragment as en, buildWaterfallViewModel as eo, buildZeroLine as ep, buildZoomContainerStyle as eq, buildZoomViewModel as er, bulletIndentPx as es, canAddTopLevelNode as et, canRemoveTopLevelNode as eu, canStartBroadcast as ev, canStartShare as ew, canUseClipboard as ex, captionDisplayText as ey, cellRunStyle as ez, AccountPageComponent as f, encodeGif as f$, computeDistribute as f0, computeDrawingViewBox as f1, computeErrorBarPrimitives as f2, computeFocusTargets as f3, computeHandleBoxes as f4, computeHandoutLayout as f5, computeIsMobile as f6, computeIsTablet as f7, computeLinePoints as f8, computeLinearRegression as f9, createWebsocketBundle as fA, cssObjectToStyleMap as fB, currentColorScheme as fC, currentLayout as fD, currentStyle as fE, defaultCssVars as fF, defaultRadius as fG, defaultThemeColors as fH, deleteElementsByIds as fI, deleteVersion as fJ, demoteNode as fK, deriveModel3DBlobUrl as fL, derivePresenceList as fM, describeSmartArtBounds as fN, disableGlowPatch as fO, disableInnerShadowPatch as fP, disableOuterShadowPatch as fQ, disableReflectionPatch as fR, disableSoftEdgePatch as fS, duplicateElementById as fT, durationOf as fU, effectsStateOf as fV, enableGlowPatch as fW, enableInnerShadowPatch as fX, enableOuterShadowPatch as fY, enableReflectionPatch as fZ, enableSoftEdgePatch as f_, computePageCount as fa, computePieLayout as fb, computePieSlicePath as fc, computePieSlices as fd, computePlotLayout as fe, computeRSquared as ff, computeRadarPoints as fg, computeScatterDots as fh, computeSelectionBoxes as fi, computeSingleSelected as fj, computeSlideIndices as fk, computeSnap as fl, computeStackedBarRects as fm, computeStackedValueRange as fn, computeTextLines as fo, computeTimerProgress as fp, computeTrendlinePrimitives as fq, computeValueRange as fr, convertOmmlToMathMl as fs, copyFormatFromElement as ft, countAccessibilityIssues as fu, countAnnotationStrokes as fv, createAngularAiBridge as fw, createCustomShow as fx, createSwipeDismissDrag as fy, createWebrtcBundle as fz, ActionSettingsPanelComponent as g, hasAnimation as g$, estimatePageCount as g0, evenColumnWidths as g1, evenRowHeights as g2, exitPresentationFullscreen as g3, exportAiChatLogs as g4, extractPathPoints as g5, eyedropperAvailable as g6, fillColorOf as g7, findInSlides as g8, findOwningSlideIndex as g9, getOleBadgeLabel as gA, getOleDisplayName as gB, getOleDownloadFileName as gC, getOleTypeColor as gD, getOleTypeLabel as gE, getPasswordStrength as gF, getPatternSvg as gG, getPlaceholderStyle as gH, getVersions as gI, getResolvedShapeClipPath as gJ, getResolvedShapeClipPathFor as gK, getShapeFillStrokeStyle as gL, getSlideBackgroundStyle as gM, getSlideTransitionAnimations as gN, getSmartArtNodeBounds as gO, getSpeechRecognitionCtor as gP, getTextBlockStyle as gQ, getTextWarp as gR, getTouchDistance as gS, getWarpCategory as gT, getWarpPath as gU, gradientStateFromStyle as gV, gradientStateOf as gW, gradientStatePatch as gX, gridColumns as gY, groupElements as gZ, groupIssuesBySeverity as g_, findSlideIndexByElementId as ga, fitPolynomial as gb, fitZoom as gc, focusTargetChips as gd, fontMimeForFormat as ge, fontSizeOf as gf, formatAutoNumber as gg, formatAxisValue as gh, formatBytes as gi, formatCursorLabel as gj, formatElapsed as gk, formatFileSize as gl, formatPropertyDate as gm, formatTime as gn, fpsToFrameIntervalMs as go, generateBroadcastRoomId as gp, generateCommentId as gq, generateCustomShowId as gr, generatePressureCircles as gs, generateRulerTicks as gt, getClrChangeParams as gu, getContainerStyle as gv, getDuotoneFilterDef as gw, getImageSrc as gx, getLocalStorageUsageSummary as gy, getOleAriaLabel as gz, AdvancedChartEditorComponent as h, numFromEvent as h$, hasCopyableFormat as h0, hasExistingLink as h1, hasExitedFullscreen as h2, hasGradientFill as h3, hasPressureVariation as h4, headerLabel as h5, inkViewBox as h6, insertColumn as h7, insertRow as h8, interpolateWidth as h9, mergeRight as hA, mergeSelection as hB, moveElementBy as hC, moveNodeDown as hD, moveNodeUp as hE, msToFrameDelayCs as hF, narrowToCircle as hG, narrowToPolygon as hH, narrowToRect as hI, newChartElement as hJ, newEquationElement as hK, newPresetShapeElement as hL, newShapeElement as hM, newSmartArtElement as hN, newTableElement as hO, newTextElement as hP, nextVisibleIndex as hQ, nodeBold as hR, nodeEditBox as hS, nodeFillColor as hT, nodeFontColor as hU, nodeIdFromKey as hV, nodeItalic as hW, nodeStyle as hX, normalizeFontFormat as hY, normalizeSlidesPerPage as hZ, normalizeValue as h_, isAudienceTab as ha, isBold as hb, isBrowserOpenableMime as hc, isChildNode as hd, isElementInteractive as he, isInjectableUrl as hf, isItalic as hg, isPpactionUrl as hh, isPresenterMessage as hi, isSigned as hj, isTextElement as hk, isTwoTableFocus as hl, isUnderline as hm, isUrlSafe as hn, isValidRoomId as ho, isViewportBackgroundPressTarget as hp, isZoomActivationKey as hq, issueTrackKey as hr, issueTypeLabel as hs, keyToLabel as ht, latexToMathml as hu, linePointsToSvgString as hv, lineSpacingPatch as hw, loadAudienceContent as hx, mergeCaptionResults as hy, mergeDown as hz, AiChangeOverlayComponent as i, routeOrthogonalConnector as i$, ommlToMathml as i0, ooxmlDashToCssBorderStyle as i1, openNativeEyeDropper as i2, overallStatus as i3, paletteColor as i4, parseAudienceNonce as i5, parseNodeTextarea as i6, partitionSlides as i7, patchChartData as i8, patchChartStyle as i9, removeElementAnimation as iA, removeGradientStopPatch as iB, removeNode as iC, removeRow as iD, removeSeries as iE, renderToCanvas as iF, reorderAnimationDown as iG, reorderAnimationUp as iH, replaceInSlides as iI, replaceMatch as iJ, requestPresentationFullscreen as iK, resizeElement as iL, resolveCaptionTracks as iM, resolveChartKind as iN, resolveFontVariant as iO, resolveHyperlinkHref as iP, resolveInteractiveElementId as iQ, resolveMediaSrc as iR, resolveOleType as iS, resolveParagraphBullet as iT, resolvePresenterNotes as iU, resolveProfileInitial as iV, resolveRegionCode as iW, resolvePalette as iX, resolveThemeCatalogEntry as iY, resolveTransitionDuration as iZ, revealedElementStyles as i_, patchTableData as ia, patchTextStyle as ib, pendingElementStyles as ic, pickColorByClickFallback as id, pickSupportedMimeType as ie, planGifFrames as ig, planVideoSegments as ih, pointsToSvgPathD as ii, presenceToCursors as ij, presetByLayout as ik, presetsForCategory as il, pressuresToWidths as im, prevVisibleIndex as io, projectDrawingShapes as ip, promoteNode as iq, provideViewerTheme as ir, radarAngle as is, radarRingPoints as it, recordWebm as iu, redistributeColumnWidth as iv, removeAnimation as iw, removeCategory as ix, removeColumn as iy, removeCommentFromList as iz, AiChatPanelComponent as j, signatureKey as j$, rowStyle as j0, sampleColorFromSlide as j1, sanitizeColor as j2, sanitizeSlideIndex as j3, sanitizeUserName as j4, saveViewerProfile as j5, scanAvailableFonts as j6, searchSlides as j7, seedBroadcastFields as j8, seedHyperlinkDraft as j9, setGridlineStyle as jA, setLayout as jB, setLegend as jC, setNodeStyle as jD, setNodeText as jE, setRepeatCount as jF, setRepeatMode as jG, setSequence as jH, setSeriesChartType as jI, setSeriesColor as jJ, setSeriesErrorBars as jK, setSeriesMarker as jL, setSeriesName as jM, setSeriesTrendline as jN, setSeriesValue as jO, setStyle as jP, setTimingCurve as jQ, setTitle as jR, setTrigger as jS, setTriggerShapeId as jT, shapeStylePatch as jU, sheetAfterNavigate as jV, shouldBlockClickAdvance as jW, shouldUseSvgWarp as jX, showDirectionPicker as jY, showsTemplateAffordance as jZ, signatureCountLabel as j_, seedPropertiesDraft as ja, seedShareFields as jb, segmentFrameCount as jc, selectValue$2 as jd, sendBackward as je, sendToBack as jf, sequentialColorScale as jg, serializeWriteBack as jh, seriesColor as ji, setAnimationEmphasis as jj, setAnimationEntrance as jk, setAnimationExit as jl, setAxis as jm, setAxisLogScale as jn, setAxisTitleStyle as jo, setCategoryLabel as jp, setCellText as jq, setColorScheme as jr, setDataLabels as js, setDataPointExplosion as jt, setDataPointFill as ju, setDataPointLabel as jv, setDelay as jw, setDirection as jx, setDuration as jy, setElementPosition as jz, AiChatService as k, signatureTimestamp as k0, signerName as k1, statusLabel as k2, slideNumberOf as k3, smartArtNodes as k4, paletteColour as k5, snapToGridStep as k6, splitCursorCell as k7, splitMergedCell as k8, statusKind as k9, updateGlowPatch as kA, updateGradientStopPatch as kB, updateInnerShadowPatch as kC, updateOuterShadowPatch as kD, updateReflectionPatch as kE, vAlignPatch as kF, validatePassword as kG, validatePrintSettings as kH, validateRoomId as kI, valueToY as kJ, vermilionDarkColors as kK, vermilionDarkTheme as kL, vermilionLightColors as kM, vermilionLightTheme as kN, vermilionRadius as kO, waypointsToPathD as kP, worstStatus as kQ, zoomTargetSlideIndex as kR, statusLabel$1 as ka, storeAudienceContent as kb, stringFromEvent$5 as kc, strokeColorOf as kd, strokeToInkElement as ke, styleShadowFilter as kf, textAdvancedPatch as kg, textAdvancedStateFromStyle as kh, textAdvancedStateOf as ki, textColorOf as kj, textDirectionPatch as kk, textStyleOf as kl, textStylePatch as km, themeStyle as kn, themeToCssVars as ko, thumbnailHeight as kp, thumbnailZoom as kq, toggleCommentResolvedInList as kr, toggleNodeBold as ks, toggleNodeItalic as kt, toggleSheet as ku, topLevelNodeCount as kv, transformSelectedTextCase as kw, translationsEn as kx, ungroupElements as ky, updateElementById as kz, AiComposerComponent as l, AiFocusBarComponent as m, AiFocusHighlightOverlayComponent as n, AiMessageListComponent as o, AiPanelStore as p, AiProposalCardComponent as q, AiSettingsSectionComponent as r, AiToolCallCardComponent as s, toChatSummary as t, AnimationAuthorPanelComponent as u, AnimationPanelComponent as v, AnimationPlaybackService as w, AutosaveService as x, CURSOR_PALETTE as y, CanvasFitService as z };
112056
- //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-YtlYBdwp.mjs.map
112556
+ //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-X944WpER.mjs.map