pptx-angular-viewer 2.0.1 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +1 -1
- package/fesm2022/{pptx-angular-viewer-chat-history-idb-D2zc6UxX.mjs → pptx-angular-viewer-chat-history-idb-wNAwjS8U.mjs} +2 -2
- package/fesm2022/{pptx-angular-viewer-chat-history-idb-D2zc6UxX.mjs.map → pptx-angular-viewer-chat-history-idb-wNAwjS8U.mjs.map} +1 -1
- package/fesm2022/{pptx-angular-viewer-pptx-angular-viewer-D9eqILzM.mjs → pptx-angular-viewer-pptx-angular-viewer-BwaiF7Nf.mjs} +1054 -560
- package/fesm2022/{pptx-angular-viewer-pptx-angular-viewer-D9eqILzM.mjs.map → pptx-angular-viewer-pptx-angular-viewer-BwaiF7Nf.mjs.map} +1 -1
- package/fesm2022/pptx-angular-viewer.mjs +1 -1
- package/package.json +3 -3
- package/types/pptx-angular-viewer.d.ts +221 -142
|
@@ -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, LucideShare2, LucideChevronRight, LucidePenTool, LucideHighlighter, LucideEraser, LucideMousePointer2, LucideChevronLeft, LucidePlay,
|
|
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
|
-
|
|
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
|
-
|
|
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-
|
|
51746
|
+
const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-wNAwjS8U.mjs');
|
|
51275
51747
|
const db = await openChatDb(dbName);
|
|
51276
51748
|
return createIdbBackend(db);
|
|
51277
51749
|
}
|
|
@@ -53502,6 +53974,129 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
53502
53974
|
`, styles: [":host{position:absolute;inset:0;pointer-events:none;overflow:visible;z-index:9999}.pptx-ng-collab-cursor{position:absolute;top:0;left:0;pointer-events:none;will-change:transform;transition:transform 90ms linear}.pptx-ng-collab-pointer{display:block;filter:drop-shadow(0 1px 1px rgba(0,0,0,.35))}.pptx-ng-collab-label{position:absolute;top:16px;left:12px;max-width:150px;padding:2px 6px;border-radius:4px;color:#fff;font-family:system-ui,sans-serif;font-size:10px;font-weight:500;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;box-shadow:0 1px 2px #0000004d}\n"] }]
|
|
53503
53975
|
}], propDecorators: { cursors: [{ type: i0.Input, args: [{ isSignal: true, alias: "cursors", required: false }] }], zoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoom", required: false }] }] } });
|
|
53504
53976
|
|
|
53977
|
+
/**
|
|
53978
|
+
* collaboration-providers.ts: transport factories for the Angular
|
|
53979
|
+
* collaboration service.
|
|
53980
|
+
*
|
|
53981
|
+
* Isolates the dynamic `yjs` / `y-websocket` / `y-webrtc` imports and provider
|
|
53982
|
+
* construction so the service focuses on lifecycle + reactive state. The Yjs
|
|
53983
|
+
* packages are dynamically imported (plain string-literal specifiers, matching
|
|
53984
|
+
* React/Vue) so they are fully tree-shaken when collaboration is unused, while
|
|
53985
|
+
* still resolving correctly under a consuming app's Vite dev server: an
|
|
53986
|
+
* `@vite-ignore`d or variable specifier skips Vite's dev-time bare-specifier
|
|
53987
|
+
* rewrite, which then fails to resolve natively in the browser.
|
|
53988
|
+
*/
|
|
53989
|
+
async function createDoc() {
|
|
53990
|
+
const Y = (await import('yjs'));
|
|
53991
|
+
const doc = new Y.Doc();
|
|
53992
|
+
const factories = {
|
|
53993
|
+
createMap: () => new Y.Map(),
|
|
53994
|
+
createArray: () => new Y.Array(),
|
|
53995
|
+
createText: () => new Y.Text(),
|
|
53996
|
+
};
|
|
53997
|
+
return { doc, factories, Y };
|
|
53998
|
+
}
|
|
53999
|
+
/** Create a y-websocket transport bundle for `config`. */
|
|
54000
|
+
async function createWebsocketBundle(config) {
|
|
54001
|
+
const [{ doc, factories }, yws] = await Promise.all([
|
|
54002
|
+
createDoc(),
|
|
54003
|
+
import('y-websocket'),
|
|
54004
|
+
]);
|
|
54005
|
+
const provider = new yws.WebsocketProvider(config.serverUrl, config.roomId, doc, config.authToken ? { params: { token: config.authToken } } : undefined);
|
|
54006
|
+
return {
|
|
54007
|
+
doc,
|
|
54008
|
+
provider,
|
|
54009
|
+
awareness: provider.awareness,
|
|
54010
|
+
factories,
|
|
54011
|
+
departure: createDepartureChannel(config.roomId, provider.awareness),
|
|
54012
|
+
};
|
|
54013
|
+
}
|
|
54014
|
+
/**
|
|
54015
|
+
* Create a y-webrtc (peer-to-peer, serverless) transport bundle for `config`.
|
|
54016
|
+
* Peers rendezvous through the configured `signaling` servers (or y-webrtc's
|
|
54017
|
+
* public default) and same-browser tabs additionally sync via BroadcastChannel.
|
|
54018
|
+
* `authToken` is passed as the room `password`.
|
|
54019
|
+
*/
|
|
54020
|
+
async function createWebrtcBundle(config) {
|
|
54021
|
+
const [{ doc, factories }, yrtc] = await Promise.all([
|
|
54022
|
+
createDoc(),
|
|
54023
|
+
import('y-webrtc'),
|
|
54024
|
+
]);
|
|
54025
|
+
const provider = new yrtc.WebrtcProvider(config.roomId, doc, {
|
|
54026
|
+
signaling: config.signaling?.length ? config.signaling : undefined,
|
|
54027
|
+
password: config.authToken || undefined,
|
|
54028
|
+
});
|
|
54029
|
+
return {
|
|
54030
|
+
doc,
|
|
54031
|
+
provider,
|
|
54032
|
+
awareness: provider.awareness,
|
|
54033
|
+
factories,
|
|
54034
|
+
departure: createDepartureChannel(config.roomId, provider.awareness),
|
|
54035
|
+
};
|
|
54036
|
+
}
|
|
54037
|
+
|
|
54038
|
+
/**
|
|
54039
|
+
* collaboration-connection.ts: provider connection-status wiring for the
|
|
54040
|
+
* Angular `CollaborationService`. Owns the websocket connect timeout and drives
|
|
54041
|
+
* the status transitions plus the sync-gate re-arm on drops; extracted from
|
|
54042
|
+
* `collaboration.service.ts` so the service stays within the file-size budget.
|
|
54043
|
+
*
|
|
54044
|
+
* Mirrors the vanilla binding's module of the same name, but over Angular's
|
|
54045
|
+
* `ProviderLike` event surface (`on('status', payload)` with
|
|
54046
|
+
* `payload.connected` for webrtc / `payload.status` for websocket).
|
|
54047
|
+
*/
|
|
54048
|
+
/**
|
|
54049
|
+
* Subscribe to the provider's status events, driving `setStatus` and the
|
|
54050
|
+
* sync-gate re-arm. For websocket transports this also arms a one-shot connect
|
|
54051
|
+
* timeout when the socket is not open yet.
|
|
54052
|
+
*/
|
|
54053
|
+
function wireConnectionStatus(deps) {
|
|
54054
|
+
const { provider, transport } = deps;
|
|
54055
|
+
let connectTimer = null;
|
|
54056
|
+
function cancelConnectTimer() {
|
|
54057
|
+
if (connectTimer !== null) {
|
|
54058
|
+
clearTimeout(connectTimer);
|
|
54059
|
+
connectTimer = null;
|
|
54060
|
+
}
|
|
54061
|
+
}
|
|
54062
|
+
if (transport === 'webrtc') {
|
|
54063
|
+
// P2P: no server round-trip to wait on. Treat "created" as connected, and
|
|
54064
|
+
// reflect explicit disconnect events (re-arming the gate on a drop).
|
|
54065
|
+
deps.setStatus('connected');
|
|
54066
|
+
provider.on('status', (payload) => {
|
|
54067
|
+
if (payload.connected === false && deps.isActive()) {
|
|
54068
|
+
deps.setStatus('disconnected');
|
|
54069
|
+
deps.reArmGate();
|
|
54070
|
+
}
|
|
54071
|
+
else if (payload.connected === true) {
|
|
54072
|
+
deps.setStatus('connected');
|
|
54073
|
+
}
|
|
54074
|
+
});
|
|
54075
|
+
return { cancelConnectTimer };
|
|
54076
|
+
}
|
|
54077
|
+
provider.on('status', (payload) => {
|
|
54078
|
+
if (payload.status === 'connected') {
|
|
54079
|
+
cancelConnectTimer();
|
|
54080
|
+
deps.setStatus('connected');
|
|
54081
|
+
}
|
|
54082
|
+
else if (payload.status === 'disconnected' && deps.isActive()) {
|
|
54083
|
+
deps.setStatus('disconnected');
|
|
54084
|
+
deps.reArmGate();
|
|
54085
|
+
}
|
|
54086
|
+
});
|
|
54087
|
+
if (provider.wsconnected) {
|
|
54088
|
+
deps.setStatus('connected');
|
|
54089
|
+
return { cancelConnectTimer };
|
|
54090
|
+
}
|
|
54091
|
+
connectTimer = setTimeout(() => {
|
|
54092
|
+
connectTimer = null;
|
|
54093
|
+
if (deps.getStatus() !== 'connected') {
|
|
54094
|
+
deps.onConnectTimeout();
|
|
54095
|
+
}
|
|
54096
|
+
}, CONNECTION_TIMEOUT_MS);
|
|
54097
|
+
return { cancelConnectTimer };
|
|
54098
|
+
}
|
|
54099
|
+
|
|
53505
54100
|
/**
|
|
53506
54101
|
* collaboration-local-presence.ts: publishes the local user's presence into a
|
|
53507
54102
|
* single awareness `presence` field.
|
|
@@ -53551,52 +54146,233 @@ class LocalPresencePublisher {
|
|
|
53551
54146
|
}
|
|
53552
54147
|
|
|
53553
54148
|
/**
|
|
53554
|
-
* collaboration-
|
|
53555
|
-
*
|
|
54149
|
+
* collaboration-session-setup.ts: build up and tear down a live collaboration
|
|
54150
|
+
* session for the Angular `CollaborationService`.
|
|
53556
54151
|
*
|
|
53557
|
-
*
|
|
53558
|
-
*
|
|
53559
|
-
*
|
|
53560
|
-
*
|
|
53561
|
-
* still resolving correctly under a consuming app's Vite dev server: an
|
|
53562
|
-
* `@vite-ignore`d or variable specifier skips Vite's dev-time bare-specifier
|
|
53563
|
-
* rewrite, which then fails to resolve natively in the browser.
|
|
54152
|
+
* Extracted from `collaboration.service.ts` so the service keeps only its
|
|
54153
|
+
* reactive state and public API. `activateSession` wires a freshly-created
|
|
54154
|
+
* provider bundle into a running session and returns the {@link ActiveSession}
|
|
54155
|
+
* the service holds as a single atomic handle; `teardownSession` disposes it.
|
|
53564
54156
|
*/
|
|
53565
|
-
|
|
53566
|
-
|
|
53567
|
-
|
|
53568
|
-
|
|
53569
|
-
|
|
53570
|
-
|
|
53571
|
-
|
|
54157
|
+
/**
|
|
54158
|
+
* Wire `bundle` into an active session: configure the live-patch channel, bind
|
|
54159
|
+
* the slide-sync engine, publish local presence, subscribe to awareness +
|
|
54160
|
+
* connection-status + remote-slide changes, then open the first-write gate.
|
|
54161
|
+
*/
|
|
54162
|
+
function activateSession(bundle, config, transport, deps) {
|
|
54163
|
+
deps.livePatcher.configure(bundle.doc, bundle.factories);
|
|
54164
|
+
deps.slideSync.bind({
|
|
54165
|
+
ydoc: bundle.doc,
|
|
54166
|
+
factories: bundle.factories,
|
|
54167
|
+
onRemoteSlides: deps.onRemoteSlides,
|
|
54168
|
+
scheduleWriteBack: deps.scheduleWriteBack,
|
|
54169
|
+
});
|
|
54170
|
+
const localPresence = new LocalPresencePublisher(bundle.awareness, {
|
|
54171
|
+
userName: config.userName,
|
|
54172
|
+
userColor: config.userColor ?? DEFAULT_CURSOR_COLOR,
|
|
54173
|
+
userAvatar: config.userAvatar,
|
|
54174
|
+
role: config.role,
|
|
54175
|
+
});
|
|
54176
|
+
localPresence.publish();
|
|
54177
|
+
bundle.awareness.on('change', deps.refreshPresence);
|
|
54178
|
+
bundle.awareness.on('update', deps.refreshPresence);
|
|
54179
|
+
deps.slideSync.gate.reset();
|
|
54180
|
+
const connection = wireConnectionStatus({
|
|
54181
|
+
provider: bundle.provider,
|
|
54182
|
+
transport,
|
|
54183
|
+
setStatus: deps.setStatus,
|
|
54184
|
+
getStatus: deps.getStatus,
|
|
54185
|
+
isActive: deps.isActive,
|
|
54186
|
+
reArmGate: () => {
|
|
54187
|
+
deps.slideSync.gate.reset();
|
|
54188
|
+
deps.slideSync.gate.arm();
|
|
54189
|
+
},
|
|
54190
|
+
onConnectTimeout: deps.failConnection,
|
|
54191
|
+
});
|
|
54192
|
+
deps.slideSync.wireSynced(bundle.provider);
|
|
54193
|
+
const unobserve = observeYDocSlides(bundle.doc, (_events, transaction) => deps.slideSync.onRemoteChange(transaction));
|
|
54194
|
+
return {
|
|
54195
|
+
ydoc: bundle.doc,
|
|
54196
|
+
provider: bundle.provider,
|
|
54197
|
+
awareness: bundle.awareness,
|
|
54198
|
+
departure: bundle.departure,
|
|
54199
|
+
factories: bundle.factories,
|
|
54200
|
+
selfId: bundle.awareness.clientID ?? -1,
|
|
54201
|
+
localPresence,
|
|
54202
|
+
connection,
|
|
54203
|
+
unobserve,
|
|
53572
54204
|
};
|
|
53573
|
-
return { doc, factories, Y };
|
|
53574
54205
|
}
|
|
53575
|
-
/**
|
|
53576
|
-
|
|
53577
|
-
|
|
53578
|
-
|
|
53579
|
-
|
|
53580
|
-
|
|
53581
|
-
|
|
53582
|
-
|
|
54206
|
+
/**
|
|
54207
|
+
* Dispose a live session. Announces the departure synchronously first: the
|
|
54208
|
+
* provider's own awareness removal is broadcast a microtask later and would be
|
|
54209
|
+
* dropped when this runs from a document being destroyed, leaving a ghost
|
|
54210
|
+
* collaborator until the 30s awareness timeout.
|
|
54211
|
+
*/
|
|
54212
|
+
function teardownSession(session, refreshPresence) {
|
|
54213
|
+
session.connection.cancelConnectTimer();
|
|
54214
|
+
session.unobserve();
|
|
54215
|
+
session.awareness.off?.('change', refreshPresence);
|
|
54216
|
+
session.awareness.off?.('update', refreshPresence);
|
|
54217
|
+
session.departure.announce();
|
|
54218
|
+
session.departure.dispose();
|
|
54219
|
+
clearLocalAwareness(session.awareness);
|
|
54220
|
+
session.provider.disconnect();
|
|
54221
|
+
session.provider.destroy();
|
|
54222
|
+
session.ydoc.destroy();
|
|
53583
54223
|
}
|
|
54224
|
+
|
|
53584
54225
|
/**
|
|
53585
|
-
*
|
|
53586
|
-
*
|
|
53587
|
-
*
|
|
53588
|
-
*
|
|
54226
|
+
* collaboration-slide-sync.ts: the granular local<->doc slide sync engine for
|
|
54227
|
+
* the Angular `CollaborationService`, extracted so the service stays within the
|
|
54228
|
+
* repo's 300 LOC ceiling.
|
|
54229
|
+
*
|
|
54230
|
+
* Owns the first-write gate plus the echo-dedupe bookkeeping (`lastSynced`,
|
|
54231
|
+
* `applyingRemote`, `pendingBroadcast`) and the broadcast / remote-apply /
|
|
54232
|
+
* post-load-adoption logic. The service keeps provider + awareness ownership
|
|
54233
|
+
* and binds this engine to the live doc for the duration of a session.
|
|
53589
54234
|
*/
|
|
53590
|
-
|
|
53591
|
-
|
|
53592
|
-
|
|
53593
|
-
|
|
53594
|
-
|
|
53595
|
-
|
|
53596
|
-
|
|
53597
|
-
|
|
53598
|
-
|
|
53599
|
-
|
|
54235
|
+
class SlideSyncEngine {
|
|
54236
|
+
/**
|
|
54237
|
+
* First-write gate: local broadcasts are suppressed (captured as pending)
|
|
54238
|
+
* until the provider confirms its initial sync or the grace period lifts the
|
|
54239
|
+
* gate, so a late joiner never seeds its placeholder deck into a room whose
|
|
54240
|
+
* real content has not arrived yet.
|
|
54241
|
+
*/
|
|
54242
|
+
gate = createSyncGate(() => this.#flushPending());
|
|
54243
|
+
#binding = null;
|
|
54244
|
+
#lastSynced = '';
|
|
54245
|
+
#applyingRemote = false;
|
|
54246
|
+
#pending = null;
|
|
54247
|
+
/** Attach the engine to a freshly connected session's doc. */
|
|
54248
|
+
bind(binding) {
|
|
54249
|
+
this.#binding = binding;
|
|
54250
|
+
}
|
|
54251
|
+
/** Clear all per-session state (call on disconnect). */
|
|
54252
|
+
reset() {
|
|
54253
|
+
this.gate.reset();
|
|
54254
|
+
this.#binding = null;
|
|
54255
|
+
this.#pending = null;
|
|
54256
|
+
this.#lastSynced = '';
|
|
54257
|
+
this.#applyingRemote = false;
|
|
54258
|
+
}
|
|
54259
|
+
/**
|
|
54260
|
+
* Record the current local deck as the sync baseline so the first (unchanged)
|
|
54261
|
+
* broadcast after connecting is suppressed. Call right after connect for a
|
|
54262
|
+
* joiner whose local deck is a placeholder awaiting remote sync, so it never
|
|
54263
|
+
* overwrites the shared document before receiving it.
|
|
54264
|
+
*/
|
|
54265
|
+
seedBaseline(slides) {
|
|
54266
|
+
this.#lastSynced = JSON.stringify(slides);
|
|
54267
|
+
}
|
|
54268
|
+
/**
|
|
54269
|
+
* Open the first-write gate on the provider's initial-sync confirmation.
|
|
54270
|
+
* y-websocket emits 'sync' with a boolean; y-webrtc emits 'synced' with an
|
|
54271
|
+
* object carrying a `synced` flag (and only once a peer syncs, hence the
|
|
54272
|
+
* grace timer). Listen to both; opening is idempotent.
|
|
54273
|
+
*/
|
|
54274
|
+
wireSynced(provider) {
|
|
54275
|
+
const handle = (payload) => {
|
|
54276
|
+
const flag = payload;
|
|
54277
|
+
const isSynced = typeof flag === 'boolean' ? flag : flag?.synced !== false;
|
|
54278
|
+
if (isSynced) {
|
|
54279
|
+
this.gate.open();
|
|
54280
|
+
}
|
|
54281
|
+
};
|
|
54282
|
+
provider.on('sync', handle);
|
|
54283
|
+
provider.on('synced', handle);
|
|
54284
|
+
if (provider.synced === true) {
|
|
54285
|
+
this.gate.open();
|
|
54286
|
+
}
|
|
54287
|
+
else {
|
|
54288
|
+
this.gate.arm();
|
|
54289
|
+
}
|
|
54290
|
+
}
|
|
54291
|
+
/**
|
|
54292
|
+
* Broadcast the local slide set to peers, reconciling only what changed into
|
|
54293
|
+
* the pptx:slides Y.Array. An empty deck is never written (so a late-joiner
|
|
54294
|
+
* that has not yet received the doc cannot clobber it), an unchanged deck is
|
|
54295
|
+
* skipped, and while the gate is shut the deck is held as pending.
|
|
54296
|
+
*/
|
|
54297
|
+
broadcast(slides) {
|
|
54298
|
+
const b = this.#binding;
|
|
54299
|
+
if (!b || this.#applyingRemote || slides.length === 0) {
|
|
54300
|
+
return;
|
|
54301
|
+
}
|
|
54302
|
+
if (!this.gate.isOpen()) {
|
|
54303
|
+
this.#pending = slides;
|
|
54304
|
+
return;
|
|
54305
|
+
}
|
|
54306
|
+
const s = JSON.stringify(slides);
|
|
54307
|
+
if (s === this.#lastSynced) {
|
|
54308
|
+
return;
|
|
54309
|
+
}
|
|
54310
|
+
this.#lastSynced = s;
|
|
54311
|
+
reconcileSlidesInYDoc([...slides], b.ydoc, b.factories, LOCAL_SYNC_ORIGIN);
|
|
54312
|
+
b.scheduleWriteBack();
|
|
54313
|
+
}
|
|
54314
|
+
/** Handle a remote Y.Doc change, skipping our own local-origin transactions. */
|
|
54315
|
+
onRemoteChange(transaction) {
|
|
54316
|
+
const b = this.#binding;
|
|
54317
|
+
if (transaction?.origin === LOCAL_SYNC_ORIGIN || this.#applyingRemote || !b) {
|
|
54318
|
+
return;
|
|
54319
|
+
}
|
|
54320
|
+
const remote = readSlidesFromYDoc(b.ydoc);
|
|
54321
|
+
if (remote.length === 0) {
|
|
54322
|
+
return;
|
|
54323
|
+
}
|
|
54324
|
+
// Suppress the echo: record what we just applied so the subsequent local
|
|
54325
|
+
// broadcast (driven by the editor signal) is a no-op.
|
|
54326
|
+
this.#lastSynced = JSON.stringify(remote);
|
|
54327
|
+
this.#applyingRemote = true;
|
|
54328
|
+
b.onRemoteSlides?.(remote);
|
|
54329
|
+
this.#applyingRemote = false;
|
|
54330
|
+
b.scheduleWriteBack();
|
|
54331
|
+
}
|
|
54332
|
+
/**
|
|
54333
|
+
* Re-adopt the shared document's slides after a local content load committed
|
|
54334
|
+
* a parsed deck to viewer state. The load pipeline applies its deck
|
|
54335
|
+
* unconditionally, so a load finishing AFTER the room's slides were applied
|
|
54336
|
+
* (a late joiner's bootstrap deck parsing slower than the doc sync) would
|
|
54337
|
+
* clobber the synced state, and with the doc itself unchanged the observer
|
|
54338
|
+
* never re-fires. When the room already has slides they win, re-applied
|
|
54339
|
+
* through `onRemoteSlides` and recorded as the baseline (bypassing the JSON
|
|
54340
|
+
* dedupe) so the follow-up local broadcast is a no-op. An empty room means
|
|
54341
|
+
* this client is the seeder. Returns true when the doc was adopted.
|
|
54342
|
+
*/
|
|
54343
|
+
adoptDocAfterLoad() {
|
|
54344
|
+
const b = this.#binding;
|
|
54345
|
+
if (!b) {
|
|
54346
|
+
return false;
|
|
54347
|
+
}
|
|
54348
|
+
const docSlides = readSlidesFromYDoc(b.ydoc);
|
|
54349
|
+
if (docSlides.length === 0) {
|
|
54350
|
+
return false;
|
|
54351
|
+
}
|
|
54352
|
+
this.#lastSynced = JSON.stringify(docSlides);
|
|
54353
|
+
this.#applyingRemote = true;
|
|
54354
|
+
b.onRemoteSlides?.(docSlides);
|
|
54355
|
+
this.#applyingRemote = false;
|
|
54356
|
+
return true;
|
|
54357
|
+
}
|
|
54358
|
+
/**
|
|
54359
|
+
* Perform the deferred first broadcast once the gate opens. When the doc is
|
|
54360
|
+
* still empty (fresh room, or nobody else present), clear the baseline so the
|
|
54361
|
+
* pending deck actually seeds it; when remote content already arrived, the
|
|
54362
|
+
* pending deck matches the applied baseline and the write is a no-op.
|
|
54363
|
+
*/
|
|
54364
|
+
#flushPending() {
|
|
54365
|
+
const b = this.#binding;
|
|
54366
|
+
const pending = this.#pending;
|
|
54367
|
+
this.#pending = null;
|
|
54368
|
+
if (!pending || !b) {
|
|
54369
|
+
return;
|
|
54370
|
+
}
|
|
54371
|
+
if (b.ydoc.getArray(YDOC_SLIDES_KEY).length === 0) {
|
|
54372
|
+
this.#lastSynced = '';
|
|
54373
|
+
}
|
|
54374
|
+
this.broadcast(pending);
|
|
54375
|
+
}
|
|
53600
54376
|
}
|
|
53601
54377
|
|
|
53602
54378
|
/**
|
|
@@ -53733,6 +54509,7 @@ class WriteBackScheduler {
|
|
|
53733
54509
|
*
|
|
53734
54510
|
* Provide at the component level: `@Component({ providers: [CollaborationService] })`.
|
|
53735
54511
|
*/
|
|
54512
|
+
/** Sentinel canvas bound used until the host reports real dimensions. */
|
|
53736
54513
|
const DEFAULT_CANVAS_BOUND = 100_000;
|
|
53737
54514
|
class CollaborationService {
|
|
53738
54515
|
// Reactive state
|
|
@@ -53766,25 +54543,19 @@ class CollaborationService {
|
|
|
53766
54543
|
/** Active-slide index of the first `owner` peer (the broadcaster), or null. */
|
|
53767
54544
|
broadcasterSlideIndex = computed(() => this.presence().find((p) => p.role === 'owner')?.activeSlideIndex ?? null, /* @ts-ignore */
|
|
53768
54545
|
...(ngDevMode ? [{ debugName: "broadcasterSlideIndex" }] : /* istanbul ignore next */ []));
|
|
53769
|
-
// Internal handles
|
|
53770
|
-
ydoc = null;
|
|
53771
|
-
provider = null;
|
|
53772
|
-
awareness = null;
|
|
53773
|
-
selfId = -1;
|
|
53774
|
-
applyingRemote = false;
|
|
53775
|
-
yFactories = null;
|
|
53776
|
-
lastSynced = '';
|
|
53777
|
-
connectTimer = null;
|
|
53778
|
-
unobserveSlides = null;
|
|
53779
|
-
writeBack = new WriteBackScheduler();
|
|
53780
54546
|
/**
|
|
53781
|
-
*
|
|
53782
|
-
*
|
|
53783
|
-
*
|
|
53784
|
-
* whose real content has not arrived yet.
|
|
54547
|
+
* Interim ("live preview") Y.Doc write channel: publishes in-flight inline
|
|
54548
|
+
* editor text that has not reached the slides state yet, so peers see typing
|
|
54549
|
+
* as it happens instead of on commit. Dormant outside a session.
|
|
53785
54550
|
*/
|
|
53786
|
-
|
|
53787
|
-
|
|
54551
|
+
livePatcher = createCollaborationLivePatcher();
|
|
54552
|
+
// The live session's transport objects + wiring handles, owned as one atomic
|
|
54553
|
+
// unit: null when disconnected, assigned by connect(), disposed by
|
|
54554
|
+
// disconnect(). See collaboration-session-setup.ts.
|
|
54555
|
+
session = null;
|
|
54556
|
+
writeBack = new WriteBackScheduler();
|
|
54557
|
+
/** Granular local<->doc slide sync (gate + echo dedupe + broadcast/adopt). */
|
|
54558
|
+
slideSync = new SlideSyncEngine();
|
|
53788
54559
|
onRemoteSlides = null;
|
|
53789
54560
|
canvasWidth = DEFAULT_CANVAS_BOUND;
|
|
53790
54561
|
canvasHeight = DEFAULT_CANVAS_BOUND;
|
|
@@ -53793,7 +54564,6 @@ class CollaborationService {
|
|
|
53793
54564
|
currentConfig = null;
|
|
53794
54565
|
lastConfig = null;
|
|
53795
54566
|
lastOptions = {};
|
|
53796
|
-
localPresence = null;
|
|
53797
54567
|
/**
|
|
53798
54568
|
* Reentrancy token for {@link connect}: bumped by every connect() and
|
|
53799
54569
|
* disconnect(). A connect() whose token no longer matches after an await was
|
|
@@ -53803,14 +54573,26 @@ class CollaborationService {
|
|
|
53803
54573
|
*/
|
|
53804
54574
|
connectToken = 0;
|
|
53805
54575
|
refreshPresence = () => {
|
|
53806
|
-
|
|
54576
|
+
const s = this.session;
|
|
54577
|
+
if (!s) {
|
|
53807
54578
|
this.presence.set([]);
|
|
53808
54579
|
return;
|
|
53809
54580
|
}
|
|
53810
|
-
this.presence.set(derivePresenceList(
|
|
54581
|
+
this.presence.set(derivePresenceList(s.awareness.getStates(), s.selfId, this.canvasWidth, this.canvasHeight));
|
|
53811
54582
|
};
|
|
53812
54583
|
constructor() {
|
|
53813
|
-
|
|
54584
|
+
// Service destruction is not the only way a session ends: a tab close, a
|
|
54585
|
+
// navigation, or an embedding page detaching the viewer's iframe destroys
|
|
54586
|
+
// the document without running Angular teardown, leaving a ghost peer in
|
|
54587
|
+
// everyone else's presence list. Leave the room from `pagehide` too.
|
|
54588
|
+
const disposeTeardown = registerCollaborationTeardown({
|
|
54589
|
+
leave: () => this.disconnect(),
|
|
54590
|
+
rejoin: () => void this.retry(),
|
|
54591
|
+
});
|
|
54592
|
+
inject(DestroyRef).onDestroy(() => {
|
|
54593
|
+
disposeTeardown();
|
|
54594
|
+
this.disconnect();
|
|
54595
|
+
});
|
|
53814
54596
|
}
|
|
53815
54597
|
async connect(config, options = {}) {
|
|
53816
54598
|
this.disconnect();
|
|
@@ -53851,29 +54633,26 @@ class CollaborationService {
|
|
|
53851
54633
|
// Superseded by a newer connect() or a disconnect() while awaiting
|
|
53852
54634
|
// the transport: destroy the just-created bundle and bail without
|
|
53853
54635
|
// touching the (newer call's) service state.
|
|
54636
|
+
bundle.departure.dispose();
|
|
53854
54637
|
bundle.provider.disconnect();
|
|
53855
54638
|
bundle.provider.destroy();
|
|
53856
54639
|
bundle.doc.destroy();
|
|
53857
54640
|
return;
|
|
53858
54641
|
}
|
|
53859
|
-
this.
|
|
53860
|
-
|
|
53861
|
-
|
|
53862
|
-
|
|
53863
|
-
|
|
53864
|
-
|
|
53865
|
-
|
|
53866
|
-
|
|
53867
|
-
|
|
53868
|
-
|
|
54642
|
+
this.session = activateSession(bundle, config, transport, {
|
|
54643
|
+
slideSync: this.slideSync,
|
|
54644
|
+
livePatcher: this.livePatcher,
|
|
54645
|
+
onRemoteSlides: this.onRemoteSlides,
|
|
54646
|
+
refreshPresence: this.refreshPresence,
|
|
54647
|
+
scheduleWriteBack: () => this.scheduleWriteBack(),
|
|
54648
|
+
setStatus: (status) => this.status.set(status),
|
|
54649
|
+
getStatus: () => this.status(),
|
|
54650
|
+
isActive: () => this.active(),
|
|
54651
|
+
failConnection: () => {
|
|
54652
|
+
this.disconnect();
|
|
54653
|
+
this.status.set('error');
|
|
54654
|
+
},
|
|
53869
54655
|
});
|
|
53870
|
-
this.localPresence.publish();
|
|
53871
|
-
this.awareness.on('change', this.refreshPresence);
|
|
53872
|
-
this.awareness.on('update', this.refreshPresence);
|
|
53873
|
-
this.wireStatus(transport);
|
|
53874
|
-
this.syncGate.reset();
|
|
53875
|
-
this.wireSynced();
|
|
53876
|
-
this.unobserveSlides = observeYDocSlides(this.ydoc, (_events, transaction) => this.onRemoteChange(transaction));
|
|
53877
54656
|
this.active.set(true);
|
|
53878
54657
|
this.refreshPresence();
|
|
53879
54658
|
}
|
|
@@ -53892,137 +54671,16 @@ class CollaborationService {
|
|
|
53892
54671
|
await this.connect(this.lastConfig, this.lastOptions);
|
|
53893
54672
|
}
|
|
53894
54673
|
}
|
|
53895
|
-
/** Wire the provider status events + (websocket-only) connection timeout. */
|
|
53896
|
-
wireStatus(transport) {
|
|
53897
|
-
const provider = this.provider;
|
|
53898
|
-
if (!provider) {
|
|
53899
|
-
return;
|
|
53900
|
-
}
|
|
53901
|
-
if (transport === 'webrtc') {
|
|
53902
|
-
// P2P: no server round-trip to wait on. Treat "created" as connected,
|
|
53903
|
-
// and reflect explicit disconnect events.
|
|
53904
|
-
this.status.set('connected');
|
|
53905
|
-
provider.on('status', (payload) => {
|
|
53906
|
-
if (payload.connected === false && this.active()) {
|
|
53907
|
-
this.status.set('disconnected');
|
|
53908
|
-
// Re-arm on (re)connect: without this, a peer that drops and
|
|
53909
|
-
// rejoins keeps the gate permanently open from the first
|
|
53910
|
-
// connection and can clobber the room with a stale local doc.
|
|
53911
|
-
this.syncGate.reset();
|
|
53912
|
-
this.syncGate.arm();
|
|
53913
|
-
}
|
|
53914
|
-
else if (payload.connected === true) {
|
|
53915
|
-
this.status.set('connected');
|
|
53916
|
-
}
|
|
53917
|
-
});
|
|
53918
|
-
return;
|
|
53919
|
-
}
|
|
53920
|
-
provider.on('status', (payload) => {
|
|
53921
|
-
if (payload.status === 'connected') {
|
|
53922
|
-
this.clearConnectTimer();
|
|
53923
|
-
this.status.set('connected');
|
|
53924
|
-
}
|
|
53925
|
-
else if (payload.status === 'disconnected' && this.active()) {
|
|
53926
|
-
this.status.set('disconnected');
|
|
53927
|
-
this.syncGate.reset();
|
|
53928
|
-
this.syncGate.arm();
|
|
53929
|
-
}
|
|
53930
|
-
});
|
|
53931
|
-
if (provider.wsconnected) {
|
|
53932
|
-
this.status.set('connected');
|
|
53933
|
-
return;
|
|
53934
|
-
}
|
|
53935
|
-
this.connectTimer = setTimeout(() => {
|
|
53936
|
-
this.connectTimer = null;
|
|
53937
|
-
if (this.status() !== 'connected') {
|
|
53938
|
-
this.disconnect();
|
|
53939
|
-
this.status.set('error');
|
|
53940
|
-
}
|
|
53941
|
-
}, CONNECTION_TIMEOUT_MS);
|
|
53942
|
-
}
|
|
53943
|
-
/**
|
|
53944
|
-
* Open the first-write gate on the provider's initial-sync confirmation.
|
|
53945
|
-
* y-websocket emits 'sync' with a boolean; y-webrtc emits 'synced' with an
|
|
53946
|
-
* object carrying a `synced` flag (and only once a peer syncs, hence the
|
|
53947
|
-
* grace timer). Listen to both; opening is idempotent.
|
|
53948
|
-
*/
|
|
53949
|
-
wireSynced() {
|
|
53950
|
-
const provider = this.provider;
|
|
53951
|
-
if (!provider) {
|
|
53952
|
-
return;
|
|
53953
|
-
}
|
|
53954
|
-
const handle = (payload) => {
|
|
53955
|
-
const flag = payload;
|
|
53956
|
-
const isSynced = typeof flag === 'boolean' ? flag : flag?.synced !== false;
|
|
53957
|
-
if (isSynced) {
|
|
53958
|
-
this.syncGate.open();
|
|
53959
|
-
}
|
|
53960
|
-
};
|
|
53961
|
-
provider.on('sync', handle);
|
|
53962
|
-
provider.on('synced', handle);
|
|
53963
|
-
if (provider.synced === true) {
|
|
53964
|
-
this.syncGate.open();
|
|
53965
|
-
}
|
|
53966
|
-
else {
|
|
53967
|
-
this.syncGate.arm();
|
|
53968
|
-
}
|
|
53969
|
-
}
|
|
53970
|
-
/**
|
|
53971
|
-
* Perform the deferred first broadcast once the gate opens. When the doc is
|
|
53972
|
-
* still empty (fresh room, or nobody else present), clear the baseline so
|
|
53973
|
-
* the pending deck actually seeds it; when remote content already arrived,
|
|
53974
|
-
* the pending deck matches the applied baseline and the write is a no-op.
|
|
53975
|
-
*/
|
|
53976
|
-
flushPendingBroadcast() {
|
|
53977
|
-
const pending = this.pendingBroadcast;
|
|
53978
|
-
this.pendingBroadcast = null;
|
|
53979
|
-
if (!pending || !this.ydoc || !this.yFactories) {
|
|
53980
|
-
return;
|
|
53981
|
-
}
|
|
53982
|
-
if (this.ydoc.getArray(YDOC_SLIDES_KEY).length === 0) {
|
|
53983
|
-
this.lastSynced = '';
|
|
53984
|
-
}
|
|
53985
|
-
this.broadcastSlides(pending);
|
|
53986
|
-
}
|
|
53987
|
-
/** Handle a remote Y.Doc change, skipping our own local-origin transactions. */
|
|
53988
|
-
onRemoteChange(transaction) {
|
|
53989
|
-
if (transaction?.origin === LOCAL_SYNC_ORIGIN || this.applyingRemote || !this.ydoc) {
|
|
53990
|
-
return;
|
|
53991
|
-
}
|
|
53992
|
-
const remote = readSlidesFromYDoc(this.ydoc);
|
|
53993
|
-
if (remote.length === 0) {
|
|
53994
|
-
return;
|
|
53995
|
-
}
|
|
53996
|
-
// Suppress the echo: record what we just applied so the subsequent local
|
|
53997
|
-
// broadcast (driven by the editor signal) is a no-op.
|
|
53998
|
-
this.lastSynced = JSON.stringify(remote);
|
|
53999
|
-
this.applyingRemote = true;
|
|
54000
|
-
this.onRemoteSlides?.(remote);
|
|
54001
|
-
this.applyingRemote = false;
|
|
54002
|
-
this.scheduleWriteBack();
|
|
54003
|
-
}
|
|
54004
54674
|
disconnect() {
|
|
54005
54675
|
// Invalidate any in-flight connect() so it discards its bundle on resume.
|
|
54006
54676
|
this.connectToken += 1;
|
|
54007
|
-
this.
|
|
54008
|
-
this.syncGate.reset();
|
|
54009
|
-
this.pendingBroadcast = null;
|
|
54677
|
+
this.slideSync.reset();
|
|
54010
54678
|
this.writeBack.cancel();
|
|
54011
|
-
this.
|
|
54012
|
-
|
|
54013
|
-
|
|
54014
|
-
|
|
54015
|
-
this.
|
|
54016
|
-
this.provider?.destroy();
|
|
54017
|
-
this.ydoc?.destroy();
|
|
54018
|
-
this.provider = null;
|
|
54019
|
-
this.ydoc = null;
|
|
54020
|
-
this.awareness = null;
|
|
54021
|
-
this.localPresence = null;
|
|
54022
|
-
this.selfId = -1;
|
|
54023
|
-
this.applyingRemote = false;
|
|
54024
|
-
this.yFactories = null;
|
|
54025
|
-
this.lastSynced = '';
|
|
54679
|
+
if (this.session) {
|
|
54680
|
+
teardownSession(this.session, this.refreshPresence);
|
|
54681
|
+
this.session = null;
|
|
54682
|
+
}
|
|
54683
|
+
this.livePatcher.configure(null, null);
|
|
54026
54684
|
this.onRemoteSlides = null;
|
|
54027
54685
|
this.currentConfig = null;
|
|
54028
54686
|
this.status.set('disconnected');
|
|
@@ -54031,88 +54689,46 @@ class CollaborationService {
|
|
|
54031
54689
|
this.presence.set([]);
|
|
54032
54690
|
this.followedClientId.set(null);
|
|
54033
54691
|
}
|
|
54034
|
-
/**
|
|
54035
|
-
* Broadcast the local slide set to peers, reconciling only what changed into
|
|
54036
|
-
* the pptx:slides Y.Array. An empty deck is never written (so a late-joiner
|
|
54037
|
-
* that has not yet received the doc cannot clobber it), and an unchanged deck
|
|
54038
|
-
* is skipped.
|
|
54039
|
-
*/
|
|
54040
54692
|
/**
|
|
54041
54693
|
* Record the current local deck as the sync baseline so the first (unchanged)
|
|
54042
54694
|
* broadcast after connecting is suppressed. Call right after {@link connect}
|
|
54043
|
-
* for a joiner whose local deck is a placeholder awaiting remote sync
|
|
54044
|
-
* never overwrites the shared document before receiving it.
|
|
54695
|
+
* for a joiner whose local deck is a placeholder awaiting remote sync.
|
|
54045
54696
|
*/
|
|
54046
54697
|
seedBaseline(slides) {
|
|
54047
|
-
this.
|
|
54698
|
+
this.slideSync.seedBaseline(slides);
|
|
54048
54699
|
}
|
|
54049
54700
|
/**
|
|
54050
|
-
* Re-adopt the shared document's slides after a local content load
|
|
54051
|
-
*
|
|
54052
|
-
*
|
|
54053
|
-
* already applied (a late joiner's bootstrap deck parsing slower than the
|
|
54054
|
-
* doc sync) silently clobbers the synced state and, with the doc itself
|
|
54055
|
-
* unchanged, the remote observer never re-fires. When the room already has
|
|
54056
|
-
* slides they win: the doc content is re-applied through `onRemoteSlides`
|
|
54057
|
-
* and recorded as the sync baseline (bypassing the usual JSON dedupe) so
|
|
54058
|
-
* the follow-up local broadcast of the adopted deck is a no-op. An empty
|
|
54059
|
-
* room means this client is the seeder and the loaded deck stands, written
|
|
54060
|
-
* by the normal gated broadcast path. Returns true when the doc was adopted.
|
|
54701
|
+
* Re-adopt the shared document's slides after a local content load committed
|
|
54702
|
+
* a parsed deck to viewer state (see {@link SlideSyncEngine.adoptDocAfterLoad}).
|
|
54703
|
+
* Returns true when the room's slides were adopted over the loaded deck.
|
|
54061
54704
|
*/
|
|
54062
54705
|
adoptDocSlidesAfterLoad() {
|
|
54063
|
-
|
|
54064
|
-
return false;
|
|
54065
|
-
}
|
|
54066
|
-
const docSlides = readSlidesFromYDoc(this.ydoc);
|
|
54067
|
-
if (docSlides.length === 0) {
|
|
54068
|
-
return false;
|
|
54069
|
-
}
|
|
54070
|
-
this.lastSynced = JSON.stringify(docSlides);
|
|
54071
|
-
this.applyingRemote = true;
|
|
54072
|
-
this.onRemoteSlides?.(docSlides);
|
|
54073
|
-
this.applyingRemote = false;
|
|
54074
|
-
return true;
|
|
54706
|
+
return this.connected() ? this.slideSync.adoptDocAfterLoad() : false;
|
|
54075
54707
|
}
|
|
54708
|
+
/**
|
|
54709
|
+
* Broadcast the local slide set to peers, reconciling only what changed into
|
|
54710
|
+
* the pptx:slides Y.Array. Empty/unchanged decks are skipped; while the gate
|
|
54711
|
+
* is shut the deck is held pending until the initial sync confirms.
|
|
54712
|
+
*/
|
|
54076
54713
|
broadcastSlides(slides) {
|
|
54077
|
-
|
|
54078
|
-
return;
|
|
54079
|
-
}
|
|
54080
|
-
if (!this.syncGate.isOpen()) {
|
|
54081
|
-
// Defer until the initial sync confirms; the gate flushes the latest
|
|
54082
|
-
// pending deck when it opens.
|
|
54083
|
-
this.pendingBroadcast = slides;
|
|
54084
|
-
return;
|
|
54085
|
-
}
|
|
54086
|
-
const s = JSON.stringify(slides);
|
|
54087
|
-
if (s === this.lastSynced) {
|
|
54088
|
-
return;
|
|
54089
|
-
}
|
|
54090
|
-
this.lastSynced = s;
|
|
54091
|
-
reconcileSlidesInYDoc([...slides], this.ydoc, this.yFactories, LOCAL_SYNC_ORIGIN);
|
|
54092
|
-
this.scheduleWriteBack();
|
|
54714
|
+
this.slideSync.broadcast(slides);
|
|
54093
54715
|
}
|
|
54094
54716
|
setCursor(x, y, activeSlideIndex) {
|
|
54095
|
-
this.localPresence
|
|
54717
|
+
this.session?.localPresence.setCursor(x, y, activeSlideIndex);
|
|
54096
54718
|
}
|
|
54097
54719
|
setSelection(selectedElementId, activeSlideIndex) {
|
|
54098
|
-
this.localPresence
|
|
54720
|
+
this.session?.localPresence.setSelection(selectedElementId, activeSlideIndex);
|
|
54099
54721
|
}
|
|
54100
54722
|
/** Publish the local active-slide index (drives follow-along). */
|
|
54101
54723
|
setActiveSlide(index) {
|
|
54102
|
-
this.localPresence
|
|
54724
|
+
this.session?.localPresence.setActiveSlide(index);
|
|
54103
54725
|
}
|
|
54104
54726
|
/** Follow the given peer's active slide, or `null` to stop following. */
|
|
54105
54727
|
followUser(clientId) {
|
|
54106
54728
|
this.followedClientId.set(clientId);
|
|
54107
54729
|
}
|
|
54108
|
-
clearConnectTimer() {
|
|
54109
|
-
if (this.connectTimer !== null) {
|
|
54110
|
-
clearTimeout(this.connectTimer);
|
|
54111
|
-
this.connectTimer = null;
|
|
54112
|
-
}
|
|
54113
|
-
}
|
|
54114
54730
|
scheduleWriteBack() {
|
|
54115
|
-
this.writeBack.schedule(this.currentConfig, this.ydoc, this.getSourceBytes, this.getTemplateElements);
|
|
54731
|
+
this.writeBack.schedule(this.currentConfig, this.session?.ydoc ?? null, this.getSourceBytes, this.getTemplateElements);
|
|
54116
54732
|
}
|
|
54117
54733
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: CollaborationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
54118
54734
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: CollaborationService });
|
|
@@ -68560,6 +69176,12 @@ class SlideCanvasComponent {
|
|
|
68560
69176
|
textEditStart = output();
|
|
68561
69177
|
/** Emitted with the new text when an inline edit commits. */
|
|
68562
69178
|
textCommit = output();
|
|
69179
|
+
/**
|
|
69180
|
+
* Emitted on EVERY keystroke while inline-editing. The commit path stays the
|
|
69181
|
+
* only thing that touches editor state/history; this feeds the collaboration
|
|
69182
|
+
* live preview so peers see typing before the edit commits.
|
|
69183
|
+
*/
|
|
69184
|
+
textInput = output();
|
|
68563
69185
|
/** Emitted when an inline edit is cancelled (Escape). */
|
|
68564
69186
|
textCancel = output();
|
|
68565
69187
|
/** Emitted on Ctrl/Cmd+B/I/U while inline-editing (parity with React/Vue). */
|
|
@@ -68947,6 +69569,10 @@ class SlideCanvasComponent {
|
|
|
68947
69569
|
: { underline: !ts?.underline };
|
|
68948
69570
|
this.textFormat.emit({ id, updates });
|
|
68949
69571
|
}
|
|
69572
|
+
/** Mirror each keystroke out for the collaboration live preview. */
|
|
69573
|
+
onTextInput(event, id) {
|
|
69574
|
+
this.textInput.emit({ id, text: event.target.value });
|
|
69575
|
+
}
|
|
68950
69576
|
commitText(event, id) {
|
|
68951
69577
|
if (this.editCancelled) {
|
|
68952
69578
|
this.editCancelled = false;
|
|
@@ -69276,7 +69902,7 @@ class SlideCanvasComponent {
|
|
|
69276
69902
|
}, /* @ts-ignore */
|
|
69277
69903
|
...(ngDevMode ? [{ debugName: "stageStyle" }] : /* istanbul ignore next */ []));
|
|
69278
69904
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SlideCanvasComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
69279
|
-
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: [
|
|
69905
|
+
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: [
|
|
69280
69906
|
CanvasFitService,
|
|
69281
69907
|
InkDrawingService,
|
|
69282
69908
|
RulerGuidesService,
|
|
@@ -69441,6 +70067,7 @@ class SlideCanvasComponent {
|
|
|
69441
70067
|
[style.width.px]="eb.width"
|
|
69442
70068
|
[style.height.px]="eb.height"
|
|
69443
70069
|
(pointerdown)="$event.stopPropagation()"
|
|
70070
|
+
(input)="onTextInput($event, eb.id)"
|
|
69444
70071
|
(blur)="commitText($event, eb.id)"
|
|
69445
70072
|
(keydown)="onEditorKeydown($event)"
|
|
69446
70073
|
></textarea>
|
|
@@ -69848,6 +70475,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
69848
70475
|
[style.width.px]="eb.width"
|
|
69849
70476
|
[style.height.px]="eb.height"
|
|
69850
70477
|
(pointerdown)="$event.stopPropagation()"
|
|
70478
|
+
(input)="onTextInput($event, eb.id)"
|
|
69851
70479
|
(blur)="commitText($event, eb.id)"
|
|
69852
70480
|
(keydown)="onEditorKeydown($event)"
|
|
69853
70481
|
></textarea>
|
|
@@ -70081,7 +70709,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
70081
70709
|
</div>
|
|
70082
70710
|
</div>
|
|
70083
70711
|
`, styles: [".pptx-ng-canvas-stage.is-editable{touch-action:none}\n"] }]
|
|
70084
|
-
}], 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: [{
|
|
70712
|
+
}], 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: [{
|
|
70085
70713
|
type: HostListener,
|
|
70086
70714
|
args: ['document:pointermove', ['$event']]
|
|
70087
70715
|
}], onPointerUp: [{
|
|
@@ -70221,7 +70849,7 @@ class MasterViewCanvasComponent {
|
|
|
70221
70849
|
<p class="empty">No master is available.</p>
|
|
70222
70850
|
}
|
|
70223
70851
|
</main>
|
|
70224
|
-
`, 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 });
|
|
70852
|
+
`, 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 });
|
|
70225
70853
|
}
|
|
70226
70854
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MasterViewCanvasComponent, decorators: [{
|
|
70227
70855
|
type: Component,
|
|
@@ -70417,17 +71045,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
70417
71045
|
* framework-neutral accessibility contract the e2e specs assert against
|
|
70418
71046
|
* (`getByRole('navigation', { name: 'Editor actions' })`).
|
|
70419
71047
|
*
|
|
70420
|
-
*
|
|
70421
|
-
*
|
|
70422
|
-
* commentCount : number of comments on the active slide (badge)
|
|
70423
|
-
* activeSheet : currently-active sheet, for highlighting the bar button
|
|
70424
|
-
*
|
|
70425
|
-
* Outputs
|
|
70426
|
-
* openSlides : user tapped the Slides button
|
|
70427
|
-
* insert : user tapped the Insert button
|
|
70428
|
-
* openFormat : user tapped the Format button
|
|
70429
|
-
* openComments : user tapped the Comments button
|
|
70430
|
-
* notes : user tapped the Notes button
|
|
71048
|
+
* Icons and colours come from the same Lucide glyphs and `--pptx-*` theme
|
|
71049
|
+
* tokens React uses. Each input/output is documented on its declaration below.
|
|
70431
71050
|
*/
|
|
70432
71051
|
class MobileBottomBarComponent {
|
|
70433
71052
|
// ── Inputs ────────────────────────────────────────────────────────────────
|
|
@@ -70460,8 +71079,6 @@ class MobileBottomBarComponent {
|
|
|
70460
71079
|
{
|
|
70461
71080
|
key: 'slides',
|
|
70462
71081
|
labelKey: 'pptx.sections.slides',
|
|
70463
|
-
// Layers icon
|
|
70464
|
-
svgPath: 'M12 2L2 7l10 5 10-5-10-5z M2 17l10 5 10-5 M2 12l10 5 10-5',
|
|
70465
71082
|
disabled: noSlides,
|
|
70466
71083
|
active: active === 'slides',
|
|
70467
71084
|
emit: () => this.openSlides.emit(),
|
|
@@ -70469,8 +71086,6 @@ class MobileBottomBarComponent {
|
|
|
70469
71086
|
{
|
|
70470
71087
|
key: 'insert',
|
|
70471
71088
|
labelKey: 'pptx.editorToolbar.insert',
|
|
70472
|
-
// Plus icon
|
|
70473
|
-
svgPath: 'M12 5v14 M5 12h14',
|
|
70474
71089
|
disabled: noSlides,
|
|
70475
71090
|
active: false,
|
|
70476
71091
|
emit: () => this.insert.emit(),
|
|
@@ -70478,8 +71093,6 @@ class MobileBottomBarComponent {
|
|
|
70478
71093
|
{
|
|
70479
71094
|
key: 'inspector',
|
|
70480
71095
|
labelKey: 'pptx.arrange.format',
|
|
70481
|
-
// Sliders icon
|
|
70482
|
-
svgPath: 'M4 21v-7 M4 10V3 M12 21v-9 M12 8V3 M20 21v-5 M20 12V3 M1 14h6 M9 8h6 M17 16h6',
|
|
70483
71096
|
disabled: noSlides,
|
|
70484
71097
|
active: active === 'inspector',
|
|
70485
71098
|
emit: () => this.openFormat.emit(),
|
|
@@ -70487,8 +71100,6 @@ class MobileBottomBarComponent {
|
|
|
70487
71100
|
{
|
|
70488
71101
|
key: 'comments',
|
|
70489
71102
|
labelKey: 'pptx.toolbar.comments',
|
|
70490
|
-
// Message-square icon
|
|
70491
|
-
svgPath: 'M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z',
|
|
70492
71103
|
disabled: noSlides,
|
|
70493
71104
|
active: active === 'comments',
|
|
70494
71105
|
badge: this.commentCount(),
|
|
@@ -70498,8 +71109,6 @@ class MobileBottomBarComponent {
|
|
|
70498
71109
|
key: 'notes',
|
|
70499
71110
|
labelKey: 'pptx.notes.title',
|
|
70500
71111
|
ariaLabelKey: 'pptx.statusBar.toggleNotes',
|
|
70501
|
-
// Note / document-text icon
|
|
70502
|
-
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',
|
|
70503
71112
|
disabled: noSlides,
|
|
70504
71113
|
active: active === 'notes',
|
|
70505
71114
|
emit: () => this.notes.emit(),
|
|
@@ -70520,19 +71129,23 @@ class MobileBottomBarComponent {
|
|
|
70520
71129
|
[disabled]="action.disabled"
|
|
70521
71130
|
(click)="action.emit()"
|
|
70522
71131
|
>
|
|
70523
|
-
|
|
70524
|
-
|
|
70525
|
-
|
|
70526
|
-
|
|
70527
|
-
|
|
70528
|
-
|
|
70529
|
-
|
|
70530
|
-
|
|
70531
|
-
|
|
70532
|
-
|
|
70533
|
-
|
|
70534
|
-
|
|
70535
|
-
|
|
71132
|
+
@switch (action.key) {
|
|
71133
|
+
@case ('slides') {
|
|
71134
|
+
<svg lucideLayers class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
|
|
71135
|
+
}
|
|
71136
|
+
@case ('insert') {
|
|
71137
|
+
<svg lucidePlus class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
|
|
71138
|
+
}
|
|
71139
|
+
@case ('inspector') {
|
|
71140
|
+
<svg lucideSettings2 class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
|
|
71141
|
+
}
|
|
71142
|
+
@case ('comments') {
|
|
71143
|
+
<svg lucideMessageSquare class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
|
|
71144
|
+
}
|
|
71145
|
+
@case ('notes') {
|
|
71146
|
+
<svg lucideStickyNote class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
|
|
71147
|
+
}
|
|
71148
|
+
}
|
|
70536
71149
|
<span class="pptx-ng-mbar-label">{{ action.labelKey | translate }}</span>
|
|
70537
71150
|
@if (action.badge && action.badge > 0) {
|
|
70538
71151
|
<span class="pptx-ng-mbar-badge" aria-hidden="true">
|
|
@@ -70545,11 +71158,18 @@ class MobileBottomBarComponent {
|
|
|
70545
71158
|
</button>
|
|
70546
71159
|
}
|
|
70547
71160
|
</nav>
|
|
70548
|
-
`, isInline: true, styles: [":host{display:block}.pptx-ng-mbar{display:flex;align-items:stretch;justify-content:space-around;background
|
|
71161
|
+
`, 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 });
|
|
70549
71162
|
}
|
|
70550
71163
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MobileBottomBarComponent, decorators: [{
|
|
70551
71164
|
type: Component,
|
|
70552
|
-
args: [{ selector: 'pptx-mobile-bottom-bar', standalone: true, imports: [
|
|
71165
|
+
args: [{ selector: 'pptx-mobile-bottom-bar', standalone: true, imports: [
|
|
71166
|
+
LucideLayers,
|
|
71167
|
+
LucideMessageSquare,
|
|
71168
|
+
LucidePlus,
|
|
71169
|
+
LucideSettings2,
|
|
71170
|
+
LucideStickyNote,
|
|
71171
|
+
TranslatePipe,
|
|
71172
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
70553
71173
|
<nav class="pptx-ng-mbar" [attr.aria-label]="'pptx.mobileBar.ariaLabel' | translate">
|
|
70554
71174
|
@for (action of actions(); track action.key) {
|
|
70555
71175
|
<button
|
|
@@ -70561,19 +71181,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
70561
71181
|
[disabled]="action.disabled"
|
|
70562
71182
|
(click)="action.emit()"
|
|
70563
71183
|
>
|
|
70564
|
-
|
|
70565
|
-
|
|
70566
|
-
|
|
70567
|
-
|
|
70568
|
-
|
|
70569
|
-
|
|
70570
|
-
|
|
70571
|
-
|
|
70572
|
-
|
|
70573
|
-
|
|
70574
|
-
|
|
70575
|
-
|
|
70576
|
-
|
|
71184
|
+
@switch (action.key) {
|
|
71185
|
+
@case ('slides') {
|
|
71186
|
+
<svg lucideLayers class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
|
|
71187
|
+
}
|
|
71188
|
+
@case ('insert') {
|
|
71189
|
+
<svg lucidePlus class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
|
|
71190
|
+
}
|
|
71191
|
+
@case ('inspector') {
|
|
71192
|
+
<svg lucideSettings2 class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
|
|
71193
|
+
}
|
|
71194
|
+
@case ('comments') {
|
|
71195
|
+
<svg lucideMessageSquare class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
|
|
71196
|
+
}
|
|
71197
|
+
@case ('notes') {
|
|
71198
|
+
<svg lucideStickyNote class="pptx-ng-mbar-icon" aria-hidden="true"></svg>
|
|
71199
|
+
}
|
|
71200
|
+
}
|
|
70577
71201
|
<span class="pptx-ng-mbar-label">{{ action.labelKey | translate }}</span>
|
|
70578
71202
|
@if (action.badge && action.badge > 0) {
|
|
70579
71203
|
<span class="pptx-ng-mbar-badge" aria-hidden="true">
|
|
@@ -70586,7 +71210,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
70586
71210
|
</button>
|
|
70587
71211
|
}
|
|
70588
71212
|
</nav>
|
|
70589
|
-
`, styles: [":host{display:block}.pptx-ng-mbar{display:flex;align-items:stretch;justify-content:space-around;background
|
|
71213
|
+
`, 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"] }]
|
|
70590
71214
|
}], 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"] }] } });
|
|
70591
71215
|
|
|
70592
71216
|
/**
|
|
@@ -71504,7 +72128,7 @@ class MobilePresenterViewComponent {
|
|
|
71504
72128
|
} @else {
|
|
71505
72129
|
<div class="pptx-ng-mpresenter-empty">{{ 'pptx.presenter.noSlides' | translate }}</div>
|
|
71506
72130
|
}
|
|
71507
|
-
`, 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 });
|
|
72131
|
+
`, 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 });
|
|
71508
72132
|
}
|
|
71509
72133
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MobilePresenterViewComponent, decorators: [{
|
|
71510
72134
|
type: Component,
|
|
@@ -71780,7 +72404,7 @@ class MobileSlidesSheetComponent {
|
|
|
71780
72404
|
}
|
|
71781
72405
|
</div>
|
|
71782
72406
|
</pptx-mobile-sheet>
|
|
71783
|
-
`, 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 });
|
|
72407
|
+
`, 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 });
|
|
71784
72408
|
}
|
|
71785
72409
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MobileSlidesSheetComponent, decorators: [{
|
|
71786
72410
|
type: Component,
|
|
@@ -71852,7 +72476,9 @@ function toolbarVisibility(hiddenActions) {
|
|
|
71852
72476
|
* A single compact row that replaces the desktop ribbon below the 768px
|
|
71853
72477
|
* breakpoint. Renders the essential always-available controls:
|
|
71854
72478
|
*
|
|
71855
|
-
* Menu · Undo · Redo · [spacer] · Present
|
|
72479
|
+
* Menu · Undo · Redo · [spacer] · AI · Save · Present · Share
|
|
72480
|
+
*
|
|
72481
|
+
* The slot order, icons and colours mirror React's MobileToolbar exactly.
|
|
71856
72482
|
*
|
|
71857
72483
|
* Section-specific functionality (Insert/Design/Export/etc.) lives in the
|
|
71858
72484
|
* `MobileMenuSheetComponent` that opens from the Menu button; per-selection
|
|
@@ -71862,19 +72488,7 @@ function toolbarVisibility(hiddenActions) {
|
|
|
71862
72488
|
* the framework-neutral accessibility contract the e2e specs assert against
|
|
71863
72489
|
* (`getByRole('toolbar', { name: 'Toolbar' })`).
|
|
71864
72490
|
*
|
|
71865
|
-
*
|
|
71866
|
-
* canUndo : whether the undo action is available
|
|
71867
|
-
* canRedo : whether the redo action is available
|
|
71868
|
-
* canPresent : whether the Present action should be enabled
|
|
71869
|
-
* canEdit : whether editor-only controls (menu/undo/redo) should render
|
|
71870
|
-
* menuOpen : whether the mobile menu sheet is currently open
|
|
71871
|
-
*
|
|
71872
|
-
* Outputs
|
|
71873
|
-
* toggleMenu : user tapped the Menu (hamburger) button
|
|
71874
|
-
* undo : user tapped Undo
|
|
71875
|
-
* redo : user tapped Redo
|
|
71876
|
-
* share : user tapped Share (opens the collaboration dialog)
|
|
71877
|
-
* present : user tapped Present
|
|
72491
|
+
* Each input/output is documented on its own declaration below.
|
|
71878
72492
|
*/
|
|
71879
72493
|
class MobileToolbarComponent {
|
|
71880
72494
|
/** Whether the undo action is available. */
|
|
@@ -71933,19 +72547,7 @@ class MobileToolbarComponent {
|
|
|
71933
72547
|
[title]="'pptx.mobileToolbar.menu' | translate"
|
|
71934
72548
|
(click)="toggleMenu.emit()"
|
|
71935
72549
|
>
|
|
71936
|
-
<svg
|
|
71937
|
-
class="pptx-ng-mtoolbar-icon"
|
|
71938
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
71939
|
-
viewBox="0 0 24 24"
|
|
71940
|
-
fill="none"
|
|
71941
|
-
stroke="currentColor"
|
|
71942
|
-
stroke-width="2"
|
|
71943
|
-
stroke-linecap="round"
|
|
71944
|
-
stroke-linejoin="round"
|
|
71945
|
-
aria-hidden="true"
|
|
71946
|
-
>
|
|
71947
|
-
<path d="M3 12h18 M3 6h18 M3 18h18" />
|
|
71948
|
-
</svg>
|
|
72550
|
+
<svg lucideMenu class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
|
|
71949
72551
|
</button>
|
|
71950
72552
|
|
|
71951
72553
|
@if (!toolbar.isHidden('undo')) {
|
|
@@ -71957,19 +72559,7 @@ class MobileToolbarComponent {
|
|
|
71957
72559
|
[disabled]="!canUndo()"
|
|
71958
72560
|
(click)="undo.emit()"
|
|
71959
72561
|
>
|
|
71960
|
-
<svg
|
|
71961
|
-
class="pptx-ng-mtoolbar-icon"
|
|
71962
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
71963
|
-
viewBox="0 0 24 24"
|
|
71964
|
-
fill="none"
|
|
71965
|
-
stroke="currentColor"
|
|
71966
|
-
stroke-width="2"
|
|
71967
|
-
stroke-linecap="round"
|
|
71968
|
-
stroke-linejoin="round"
|
|
71969
|
-
aria-hidden="true"
|
|
71970
|
-
>
|
|
71971
|
-
<path d="M3 7v6h6 M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13" />
|
|
71972
|
-
</svg>
|
|
72562
|
+
<svg lucideUndo class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
|
|
71973
72563
|
</button>
|
|
71974
72564
|
}
|
|
71975
72565
|
|
|
@@ -71982,19 +72572,7 @@ class MobileToolbarComponent {
|
|
|
71982
72572
|
[disabled]="!canRedo()"
|
|
71983
72573
|
(click)="redo.emit()"
|
|
71984
72574
|
>
|
|
71985
|
-
<svg
|
|
71986
|
-
class="pptx-ng-mtoolbar-icon"
|
|
71987
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
71988
|
-
viewBox="0 0 24 24"
|
|
71989
|
-
fill="none"
|
|
71990
|
-
stroke="currentColor"
|
|
71991
|
-
stroke-width="2"
|
|
71992
|
-
stroke-linecap="round"
|
|
71993
|
-
stroke-linejoin="round"
|
|
71994
|
-
aria-hidden="true"
|
|
71995
|
-
>
|
|
71996
|
-
<path d="M21 7v6h-6 M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13" />
|
|
71997
|
-
</svg>
|
|
72575
|
+
<svg lucideRedo class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
|
|
71998
72576
|
</button>
|
|
71999
72577
|
}
|
|
72000
72578
|
}
|
|
@@ -72018,39 +72596,7 @@ class MobileToolbarComponent {
|
|
|
72018
72596
|
[title]="'pptx.toolbar.toggleAiAssistant' | translate"
|
|
72019
72597
|
(click)="toggleAiPanel.emit()"
|
|
72020
72598
|
>
|
|
72021
|
-
<svg
|
|
72022
|
-
class="pptx-ng-mtoolbar-icon"
|
|
72023
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
72024
|
-
viewBox="0 0 24 24"
|
|
72025
|
-
fill="none"
|
|
72026
|
-
stroke="currentColor"
|
|
72027
|
-
stroke-width="2"
|
|
72028
|
-
stroke-linecap="round"
|
|
72029
|
-
stroke-linejoin="round"
|
|
72030
|
-
aria-hidden="true"
|
|
72031
|
-
>
|
|
72032
|
-
<path
|
|
72033
|
-
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"
|
|
72034
|
-
/>
|
|
72035
|
-
<path d="M20 3v4 M22 5h-4 M4 17v2 M5 18H3" />
|
|
72036
|
-
</svg>
|
|
72037
|
-
</button>
|
|
72038
|
-
}
|
|
72039
|
-
|
|
72040
|
-
<!--
|
|
72041
|
-
Share: start/join a real-time collaboration session. Gated on edit
|
|
72042
|
-
mode and toolbar visibility, mirroring React's MobileToolbar; the
|
|
72043
|
-
icon is the same Lucide Share2 the desktop ribbon uses.
|
|
72044
|
-
-->
|
|
72045
|
-
@if (canEdit() && !toolbar.isHidden('share')) {
|
|
72046
|
-
<button
|
|
72047
|
-
type="button"
|
|
72048
|
-
class="pptx-ng-mtoolbar-btn"
|
|
72049
|
-
[attr.aria-label]="'pptx.toolbar.share' | translate"
|
|
72050
|
-
[title]="'pptx.toolbar.share' | translate"
|
|
72051
|
-
(click)="share.emit()"
|
|
72052
|
-
>
|
|
72053
|
-
<svg lucideShare2 class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
|
|
72599
|
+
<svg lucideSparkles class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
|
|
72054
72600
|
</button>
|
|
72055
72601
|
}
|
|
72056
72602
|
|
|
@@ -72066,49 +72612,54 @@ class MobileToolbarComponent {
|
|
|
72066
72612
|
[title]="'pptx.toolbar.save' | translate"
|
|
72067
72613
|
(click)="save.emit()"
|
|
72068
72614
|
>
|
|
72069
|
-
<svg
|
|
72070
|
-
class="pptx-ng-mtoolbar-icon"
|
|
72071
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
72072
|
-
viewBox="0 0 24 24"
|
|
72073
|
-
fill="none"
|
|
72074
|
-
stroke="currentColor"
|
|
72075
|
-
stroke-width="2"
|
|
72076
|
-
stroke-linecap="round"
|
|
72077
|
-
stroke-linejoin="round"
|
|
72078
|
-
aria-hidden="true"
|
|
72079
|
-
>
|
|
72080
|
-
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 M7 10l5 5 5-5 M12 15V3" />
|
|
72081
|
-
</svg>
|
|
72615
|
+
<svg lucideDownload class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
|
|
72082
72616
|
</button>
|
|
72083
72617
|
|
|
72084
|
-
|
|
72085
|
-
|
|
72086
|
-
|
|
72087
|
-
|
|
72088
|
-
|
|
72089
|
-
|
|
72090
|
-
|
|
72091
|
-
|
|
72092
|
-
|
|
72093
|
-
class="pptx-ng-mtoolbar-icon"
|
|
72094
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
72095
|
-
viewBox="0 0 24 24"
|
|
72096
|
-
fill="none"
|
|
72097
|
-
stroke="currentColor"
|
|
72098
|
-
stroke-width="2"
|
|
72099
|
-
stroke-linecap="round"
|
|
72100
|
-
stroke-linejoin="round"
|
|
72101
|
-
aria-hidden="true"
|
|
72618
|
+
<!-- Present: same Lucide "presentation" glyph React's mobile bar uses. -->
|
|
72619
|
+
@if (!toolbar.isHidden('fullscreen')) {
|
|
72620
|
+
<button
|
|
72621
|
+
type="button"
|
|
72622
|
+
class="pptx-ng-mtoolbar-btn pptx-ng-mtoolbar-present"
|
|
72623
|
+
[attr.aria-label]="'pptx.toolbar.present' | translate"
|
|
72624
|
+
[title]="'pptx.toolbar.present' | translate"
|
|
72625
|
+
[disabled]="!canPresent()"
|
|
72626
|
+
(click)="present.emit()"
|
|
72102
72627
|
>
|
|
72103
|
-
<
|
|
72104
|
-
</
|
|
72105
|
-
|
|
72628
|
+
<svg lucidePresentation class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
|
|
72629
|
+
</button>
|
|
72630
|
+
}
|
|
72631
|
+
|
|
72632
|
+
<!--
|
|
72633
|
+
Share: start/join a real-time collaboration session. Sits last in
|
|
72634
|
+
the row (after Present) and renders as a filled primary pill, the
|
|
72635
|
+
same slot and treatment React's MobileToolbar gives it.
|
|
72636
|
+
-->
|
|
72637
|
+
@if (canEdit() && !toolbar.isHidden('share')) {
|
|
72638
|
+
<button
|
|
72639
|
+
type="button"
|
|
72640
|
+
class="pptx-ng-mtoolbar-btn pptx-ng-mtoolbar-share"
|
|
72641
|
+
[attr.aria-label]="'pptx.toolbar.share' | translate"
|
|
72642
|
+
[title]="'pptx.toolbar.share' | translate"
|
|
72643
|
+
(click)="share.emit()"
|
|
72644
|
+
>
|
|
72645
|
+
<svg lucideShare2 class="pptx-ng-mtoolbar-icon is-sm" aria-hidden="true"></svg>
|
|
72646
|
+
</button>
|
|
72647
|
+
}
|
|
72106
72648
|
</div>
|
|
72107
|
-
`, 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
|
|
72649
|
+
`, 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 });
|
|
72108
72650
|
}
|
|
72109
72651
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MobileToolbarComponent, decorators: [{
|
|
72110
72652
|
type: Component,
|
|
72111
|
-
args: [{ selector: 'pptx-mobile-toolbar', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
72653
|
+
args: [{ selector: 'pptx-mobile-toolbar', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
72654
|
+
LucideDownload,
|
|
72655
|
+
LucideMenu,
|
|
72656
|
+
LucidePresentation,
|
|
72657
|
+
LucideRedo,
|
|
72658
|
+
LucideShare2,
|
|
72659
|
+
LucideSparkles,
|
|
72660
|
+
LucideUndo,
|
|
72661
|
+
TranslatePipe,
|
|
72662
|
+
], template: `
|
|
72112
72663
|
<div
|
|
72113
72664
|
class="pptx-ng-mtoolbar"
|
|
72114
72665
|
role="toolbar"
|
|
@@ -72124,19 +72675,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
72124
72675
|
[title]="'pptx.mobileToolbar.menu' | translate"
|
|
72125
72676
|
(click)="toggleMenu.emit()"
|
|
72126
72677
|
>
|
|
72127
|
-
<svg
|
|
72128
|
-
class="pptx-ng-mtoolbar-icon"
|
|
72129
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
72130
|
-
viewBox="0 0 24 24"
|
|
72131
|
-
fill="none"
|
|
72132
|
-
stroke="currentColor"
|
|
72133
|
-
stroke-width="2"
|
|
72134
|
-
stroke-linecap="round"
|
|
72135
|
-
stroke-linejoin="round"
|
|
72136
|
-
aria-hidden="true"
|
|
72137
|
-
>
|
|
72138
|
-
<path d="M3 12h18 M3 6h18 M3 18h18" />
|
|
72139
|
-
</svg>
|
|
72678
|
+
<svg lucideMenu class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
|
|
72140
72679
|
</button>
|
|
72141
72680
|
|
|
72142
72681
|
@if (!toolbar.isHidden('undo')) {
|
|
@@ -72148,19 +72687,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
72148
72687
|
[disabled]="!canUndo()"
|
|
72149
72688
|
(click)="undo.emit()"
|
|
72150
72689
|
>
|
|
72151
|
-
<svg
|
|
72152
|
-
class="pptx-ng-mtoolbar-icon"
|
|
72153
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
72154
|
-
viewBox="0 0 24 24"
|
|
72155
|
-
fill="none"
|
|
72156
|
-
stroke="currentColor"
|
|
72157
|
-
stroke-width="2"
|
|
72158
|
-
stroke-linecap="round"
|
|
72159
|
-
stroke-linejoin="round"
|
|
72160
|
-
aria-hidden="true"
|
|
72161
|
-
>
|
|
72162
|
-
<path d="M3 7v6h6 M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13" />
|
|
72163
|
-
</svg>
|
|
72690
|
+
<svg lucideUndo class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
|
|
72164
72691
|
</button>
|
|
72165
72692
|
}
|
|
72166
72693
|
|
|
@@ -72173,19 +72700,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
72173
72700
|
[disabled]="!canRedo()"
|
|
72174
72701
|
(click)="redo.emit()"
|
|
72175
72702
|
>
|
|
72176
|
-
<svg
|
|
72177
|
-
class="pptx-ng-mtoolbar-icon"
|
|
72178
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
72179
|
-
viewBox="0 0 24 24"
|
|
72180
|
-
fill="none"
|
|
72181
|
-
stroke="currentColor"
|
|
72182
|
-
stroke-width="2"
|
|
72183
|
-
stroke-linecap="round"
|
|
72184
|
-
stroke-linejoin="round"
|
|
72185
|
-
aria-hidden="true"
|
|
72186
|
-
>
|
|
72187
|
-
<path d="M21 7v6h-6 M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13" />
|
|
72188
|
-
</svg>
|
|
72703
|
+
<svg lucideRedo class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
|
|
72189
72704
|
</button>
|
|
72190
72705
|
}
|
|
72191
72706
|
}
|
|
@@ -72209,39 +72724,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
72209
72724
|
[title]="'pptx.toolbar.toggleAiAssistant' | translate"
|
|
72210
72725
|
(click)="toggleAiPanel.emit()"
|
|
72211
72726
|
>
|
|
72212
|
-
<svg
|
|
72213
|
-
class="pptx-ng-mtoolbar-icon"
|
|
72214
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
72215
|
-
viewBox="0 0 24 24"
|
|
72216
|
-
fill="none"
|
|
72217
|
-
stroke="currentColor"
|
|
72218
|
-
stroke-width="2"
|
|
72219
|
-
stroke-linecap="round"
|
|
72220
|
-
stroke-linejoin="round"
|
|
72221
|
-
aria-hidden="true"
|
|
72222
|
-
>
|
|
72223
|
-
<path
|
|
72224
|
-
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"
|
|
72225
|
-
/>
|
|
72226
|
-
<path d="M20 3v4 M22 5h-4 M4 17v2 M5 18H3" />
|
|
72227
|
-
</svg>
|
|
72228
|
-
</button>
|
|
72229
|
-
}
|
|
72230
|
-
|
|
72231
|
-
<!--
|
|
72232
|
-
Share: start/join a real-time collaboration session. Gated on edit
|
|
72233
|
-
mode and toolbar visibility, mirroring React's MobileToolbar; the
|
|
72234
|
-
icon is the same Lucide Share2 the desktop ribbon uses.
|
|
72235
|
-
-->
|
|
72236
|
-
@if (canEdit() && !toolbar.isHidden('share')) {
|
|
72237
|
-
<button
|
|
72238
|
-
type="button"
|
|
72239
|
-
class="pptx-ng-mtoolbar-btn"
|
|
72240
|
-
[attr.aria-label]="'pptx.toolbar.share' | translate"
|
|
72241
|
-
[title]="'pptx.toolbar.share' | translate"
|
|
72242
|
-
(click)="share.emit()"
|
|
72243
|
-
>
|
|
72244
|
-
<svg lucideShare2 class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
|
|
72727
|
+
<svg lucideSparkles class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
|
|
72245
72728
|
</button>
|
|
72246
72729
|
}
|
|
72247
72730
|
|
|
@@ -72257,45 +72740,41 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
72257
72740
|
[title]="'pptx.toolbar.save' | translate"
|
|
72258
72741
|
(click)="save.emit()"
|
|
72259
72742
|
>
|
|
72260
|
-
<svg
|
|
72261
|
-
class="pptx-ng-mtoolbar-icon"
|
|
72262
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
72263
|
-
viewBox="0 0 24 24"
|
|
72264
|
-
fill="none"
|
|
72265
|
-
stroke="currentColor"
|
|
72266
|
-
stroke-width="2"
|
|
72267
|
-
stroke-linecap="round"
|
|
72268
|
-
stroke-linejoin="round"
|
|
72269
|
-
aria-hidden="true"
|
|
72270
|
-
>
|
|
72271
|
-
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 M7 10l5 5 5-5 M12 15V3" />
|
|
72272
|
-
</svg>
|
|
72743
|
+
<svg lucideDownload class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
|
|
72273
72744
|
</button>
|
|
72274
72745
|
|
|
72275
|
-
|
|
72276
|
-
|
|
72277
|
-
|
|
72278
|
-
|
|
72279
|
-
|
|
72280
|
-
|
|
72281
|
-
|
|
72282
|
-
|
|
72283
|
-
|
|
72284
|
-
class="pptx-ng-mtoolbar-icon"
|
|
72285
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
72286
|
-
viewBox="0 0 24 24"
|
|
72287
|
-
fill="none"
|
|
72288
|
-
stroke="currentColor"
|
|
72289
|
-
stroke-width="2"
|
|
72290
|
-
stroke-linecap="round"
|
|
72291
|
-
stroke-linejoin="round"
|
|
72292
|
-
aria-hidden="true"
|
|
72746
|
+
<!-- Present: same Lucide "presentation" glyph React's mobile bar uses. -->
|
|
72747
|
+
@if (!toolbar.isHidden('fullscreen')) {
|
|
72748
|
+
<button
|
|
72749
|
+
type="button"
|
|
72750
|
+
class="pptx-ng-mtoolbar-btn pptx-ng-mtoolbar-present"
|
|
72751
|
+
[attr.aria-label]="'pptx.toolbar.present' | translate"
|
|
72752
|
+
[title]="'pptx.toolbar.present' | translate"
|
|
72753
|
+
[disabled]="!canPresent()"
|
|
72754
|
+
(click)="present.emit()"
|
|
72293
72755
|
>
|
|
72294
|
-
<
|
|
72295
|
-
</
|
|
72296
|
-
|
|
72756
|
+
<svg lucidePresentation class="pptx-ng-mtoolbar-icon" aria-hidden="true"></svg>
|
|
72757
|
+
</button>
|
|
72758
|
+
}
|
|
72759
|
+
|
|
72760
|
+
<!--
|
|
72761
|
+
Share: start/join a real-time collaboration session. Sits last in
|
|
72762
|
+
the row (after Present) and renders as a filled primary pill, the
|
|
72763
|
+
same slot and treatment React's MobileToolbar gives it.
|
|
72764
|
+
-->
|
|
72765
|
+
@if (canEdit() && !toolbar.isHidden('share')) {
|
|
72766
|
+
<button
|
|
72767
|
+
type="button"
|
|
72768
|
+
class="pptx-ng-mtoolbar-btn pptx-ng-mtoolbar-share"
|
|
72769
|
+
[attr.aria-label]="'pptx.toolbar.share' | translate"
|
|
72770
|
+
[title]="'pptx.toolbar.share' | translate"
|
|
72771
|
+
(click)="share.emit()"
|
|
72772
|
+
>
|
|
72773
|
+
<svg lucideShare2 class="pptx-ng-mtoolbar-icon is-sm" aria-hidden="true"></svg>
|
|
72774
|
+
</button>
|
|
72775
|
+
}
|
|
72297
72776
|
</div>
|
|
72298
|
-
`, 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
|
|
72777
|
+
`, 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"] }]
|
|
72299
72778
|
}], 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"] }] } });
|
|
72300
72779
|
|
|
72301
72780
|
/**
|
|
@@ -73746,6 +74225,7 @@ class ViewerCanvasEditingService {
|
|
|
73746
74225
|
editor = inject(EditorStateService);
|
|
73747
74226
|
dialogs = inject(ViewerDialogsService);
|
|
73748
74227
|
formatPainter = inject(ViewerFormatPainterService);
|
|
74228
|
+
collab = inject(CollaborationService);
|
|
73749
74229
|
/** Id of the element being inline text-edited, or null. */
|
|
73750
74230
|
editingId = signal(null, /* @ts-ignore */
|
|
73751
74231
|
...(ngDevMode ? [{ debugName: "editingId" }] : /* istanbul ignore next */ []));
|
|
@@ -73790,9 +74270,21 @@ class ViewerCanvasEditingService {
|
|
|
73790
74270
|
}
|
|
73791
74271
|
this.editor.updateElement(host.activeSlideIndex(), event.id, textStylePatch(element, event.updates));
|
|
73792
74272
|
}
|
|
74273
|
+
/**
|
|
74274
|
+
* Mirror an in-progress inline edit to collaborators. The typed text only
|
|
74275
|
+
* reaches the editor state (and therefore the Y.Doc reconcile) on commit, so
|
|
74276
|
+
* without this peers saw nothing until the editor blurred. No-op when not
|
|
74277
|
+
* collaborating.
|
|
74278
|
+
*/
|
|
74279
|
+
onTextInput(event) {
|
|
74280
|
+
publishLiveInlineText(this.collab.livePatcher, this.requireHost().activeSlide(), event.id, event.text);
|
|
74281
|
+
}
|
|
73793
74282
|
/** Commit an inline text edit: replace the element's text (one history entry). */
|
|
73794
74283
|
onTextCommit(event) {
|
|
73795
74284
|
const host = this.requireHost();
|
|
74285
|
+
// Push any queued interim frame out first so it cannot land after the
|
|
74286
|
+
// committed text and revert it.
|
|
74287
|
+
this.collab.livePatcher.flush();
|
|
73796
74288
|
this.editor.updateElement(host.activeSlideIndex(), event.id, {
|
|
73797
74289
|
text: event.text,
|
|
73798
74290
|
textSegments: [],
|
|
@@ -77738,7 +78230,7 @@ class PresentationTransitionOverlayComponent {
|
|
|
77738
78230
|
/>
|
|
77739
78231
|
</div>
|
|
77740
78232
|
</div>
|
|
77741
|
-
`, 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 });
|
|
78233
|
+
`, 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 });
|
|
77742
78234
|
}
|
|
77743
78235
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PresentationTransitionOverlayComponent, decorators: [{
|
|
77744
78236
|
type: Component,
|
|
@@ -78539,7 +79031,7 @@ class PresentationOverlayComponent {
|
|
|
78539
79031
|
<svg lucideChevronRight class="h-6 w-6"></svg>
|
|
78540
79032
|
</button>
|
|
78541
79033
|
</div>
|
|
78542
|
-
`, 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 });
|
|
79034
|
+
`, 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 });
|
|
78543
79035
|
}
|
|
78544
79036
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PresentationOverlayComponent, decorators: [{
|
|
78545
79037
|
type: Component,
|
|
@@ -78774,7 +79266,7 @@ class PresenterControlsComponent {
|
|
|
78774
79266
|
@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>}
|
|
78775
79267
|
</main></div>
|
|
78776
79268
|
}
|
|
78777
|
-
`, 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 });
|
|
79269
|
+
`, 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 });
|
|
78778
79270
|
}
|
|
78779
79271
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PresenterControlsComponent, decorators: [{
|
|
78780
79272
|
type: Component,
|
|
@@ -79121,7 +79613,7 @@ class PresenterViewComponent {
|
|
|
79121
79613
|
} @else {
|
|
79122
79614
|
<div class="pptx-ng-presenter-empty">{{ 'pptx.presenter.noSlides' | translate }}</div>
|
|
79123
79615
|
}
|
|
79124
|
-
`, 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 });
|
|
79616
|
+
`, 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 });
|
|
79125
79617
|
}
|
|
79126
79618
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PresenterViewComponent, decorators: [{
|
|
79127
79619
|
type: Component,
|
|
@@ -83348,7 +83840,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
83348
83840
|
}], propDecorators: { canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }] } });
|
|
83349
83841
|
|
|
83350
83842
|
// Generated by scripts/inline-shared.mjs from package.json. Do not edit.
|
|
83351
|
-
const PPTX_ANGULAR_VIEWER_VERSION = "2.
|
|
83843
|
+
const PPTX_ANGULAR_VIEWER_VERSION = "2.1.0";
|
|
83352
83844
|
|
|
83353
83845
|
/**
|
|
83354
83846
|
* account-page.component.ts: File > Account content.
|
|
@@ -100763,7 +101255,7 @@ class SlideSorterOverlayComponent {
|
|
|
100763
101255
|
</div>
|
|
100764
101256
|
</div>
|
|
100765
101257
|
</div>
|
|
100766
|
-
`, 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 });
|
|
101258
|
+
`, 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 });
|
|
100767
101259
|
}
|
|
100768
101260
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SlideSorterOverlayComponent, decorators: [{
|
|
100769
101261
|
type: Component,
|
|
@@ -100980,7 +101472,7 @@ class SlidesPanelComponent {
|
|
|
100980
101472
|
return this.editor.sections().findIndex((section) => section.id === sectionId);
|
|
100981
101473
|
}
|
|
100982
101474
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SlidesPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
100983
|
-
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 });
|
|
101475
|
+
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 });
|
|
100984
101476
|
}
|
|
100985
101477
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SlidesPanelComponent, decorators: [{
|
|
100986
101478
|
type: Component,
|
|
@@ -102465,7 +102957,7 @@ class SlideDiffThumbnailsComponent {
|
|
|
102465
102957
|
</div>
|
|
102466
102958
|
}
|
|
102467
102959
|
</div>
|
|
102468
|
-
`, 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 });
|
|
102960
|
+
`, 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 });
|
|
102469
102961
|
}
|
|
102470
102962
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SlideDiffThumbnailsComponent, decorators: [{
|
|
102471
102963
|
type: Component,
|
|
@@ -109016,6 +109508,7 @@ class PowerPointViewerComponent {
|
|
|
109016
109508
|
(contextMenu)="canvasEditing.onContextMenu($event)"
|
|
109017
109509
|
[editingId]="canvasEditing.editingId()"
|
|
109018
109510
|
(textEditStart)="canvasEditing.onTextEditStart($event.id)"
|
|
109511
|
+
(textInput)="canvasEditing.onTextInput($event)"
|
|
109019
109512
|
(textCommit)="canvasEditing.onTextCommit($event)"
|
|
109020
109513
|
(textCancel)="canvasEditing.editingId.set(null)"
|
|
109021
109514
|
(textFormat)="canvasEditing.onTextFormat($event)"
|
|
@@ -109522,7 +110015,7 @@ class PowerPointViewerComponent {
|
|
|
109522
110015
|
/>
|
|
109523
110016
|
}
|
|
109524
110017
|
</div>
|
|
109525
|
-
`, 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", "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 */
|
|
110018
|
+
`, 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 */
|
|
109526
110019
|
Promise.resolve().then(function () { return aiChatPanel_component; }).then(m => m.AiChatPanelComponent)]] });
|
|
109527
110020
|
}
|
|
109528
110021
|
i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.0.8", ngImport: i0, type: PowerPointViewerComponent, resolveDeferredDeps: () => [/* @ts-ignore */
|
|
@@ -109800,6 +110293,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.0.8", ng
|
|
|
109800
110293
|
(contextMenu)="canvasEditing.onContextMenu($event)"
|
|
109801
110294
|
[editingId]="canvasEditing.editingId()"
|
|
109802
110295
|
(textEditStart)="canvasEditing.onTextEditStart($event.id)"
|
|
110296
|
+
(textInput)="canvasEditing.onTextInput($event)"
|
|
109803
110297
|
(textCommit)="canvasEditing.onTextCommit($event)"
|
|
109804
110298
|
(textCancel)="canvasEditing.editingId.set(null)"
|
|
109805
110299
|
(textFormat)="canvasEditing.onTextFormat($event)"
|
|
@@ -112160,4 +112654,4 @@ function cn(...values) {
|
|
|
112160
112654
|
*/
|
|
112161
112655
|
|
|
112162
112656
|
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 };
|
|
112163
|
-
//# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-
|
|
112657
|
+
//# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-BwaiF7Nf.mjs.map
|