pptx-angular-viewer 1.30.1 → 1.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19237,6 +19237,17 @@ class EditorHistory {
19237
19237
  constructor(options) {
19238
19238
  this._maxDepth = options?.maxDepth ?? 100;
19239
19239
  }
19240
+ /**
19241
+ * Change the maximum undo depth at runtime (File > Options > Advanced >
19242
+ * "Maximum number of undos"). Trims the past stack immediately if the new
19243
+ * limit is smaller.
19244
+ */
19245
+ setMaxDepth(maxDepth) {
19246
+ this._maxDepth = Math.max(1, Math.floor(maxDepth));
19247
+ while (this._past.length > this._maxDepth) {
19248
+ this._past.shift();
19249
+ }
19250
+ }
19240
19251
  // -- Getters --------------------------------------------------------------
19241
19252
  /** True when at least one undo step is available. */
19242
19253
  get canUndo() {
@@ -37247,6 +37258,1013 @@ function filterVisibleTabs(tabs, hiddenActions) {
37247
37258
  return tabs.filter((tab) => !isActionHidden(tab.id, hiddenActions));
37248
37259
  }
37249
37260
 
37261
+ /**
37262
+ * AutoCorrect-as-you-type engine behind Options > Proofing, mirroring
37263
+ * PowerPoint's replacements: initial-capitals fixes, sentence and day-name
37264
+ * capitalization, smart quotes, double-hyphen to dash, fraction glyphs, and
37265
+ * superscript-style ordinals. Bindings run `applyAutoCorrect` over committed
37266
+ * text (word boundaries, blur, or Enter), never on every keystroke.
37267
+ */
37268
+ const DAY_NAMES = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
37269
+ const FRACTIONS = [
37270
+ ['1/2', '½'],
37271
+ ['1/4', '¼'],
37272
+ ['3/4', '¾'],
37273
+ ];
37274
+ const ORDINAL_SUFFIXES = {
37275
+ st: 'ˢᵗ',
37276
+ nd: 'ⁿᵈ',
37277
+ rd: 'ʳᵈ',
37278
+ th: 'ᵗʰ',
37279
+ };
37280
+ function fixTwoInitialCapitals(word) {
37281
+ if (/^[A-Z]{2}[a-z]/.test(word) && !/^[A-Z]{3,}$/.test(word)) {
37282
+ const second = word.charAt(1).toLowerCase();
37283
+ return `${word.charAt(0)}${second}${word.slice(2)}`;
37284
+ }
37285
+ return word;
37286
+ }
37287
+ function capitalizeDayName(word) {
37288
+ const bare = word.toLowerCase();
37289
+ if (DAY_NAMES.includes(bare) && word === bare) {
37290
+ return `${bare.charAt(0).toUpperCase()}${bare.slice(1)}`;
37291
+ }
37292
+ return word;
37293
+ }
37294
+ function replaceFractions(word) {
37295
+ for (const [plain, glyph] of FRACTIONS) {
37296
+ if (word === plain) {
37297
+ return glyph;
37298
+ }
37299
+ }
37300
+ return word;
37301
+ }
37302
+ function replaceOrdinal(word) {
37303
+ const match = /^(\d+)(st|nd|rd|th)$/i.exec(word);
37304
+ if (!match || match[1] === undefined || match[2] === undefined) {
37305
+ return word;
37306
+ }
37307
+ const superscript = ORDINAL_SUFFIXES[match[2].toLowerCase()];
37308
+ return superscript ? `${match[1]}${superscript}` : word;
37309
+ }
37310
+ function transformWord(word, proofing) {
37311
+ let result = word;
37312
+ if (proofing.autoCorrectTwoInitialCapitals) {
37313
+ result = fixTwoInitialCapitals(result);
37314
+ }
37315
+ if (proofing.autoCorrectCapitalizeDayNames) {
37316
+ result = capitalizeDayName(result);
37317
+ }
37318
+ if (proofing.autoCorrectFractions) {
37319
+ result = replaceFractions(result);
37320
+ }
37321
+ if (proofing.autoCorrectOrdinals) {
37322
+ result = replaceOrdinal(result);
37323
+ }
37324
+ return result;
37325
+ }
37326
+ function applySmartQuotes(text) {
37327
+ let result = '';
37328
+ for (let i = 0; i < text.length; i += 1) {
37329
+ const char = text.charAt(i);
37330
+ if (char !== '"' && char !== "'") {
37331
+ result += char;
37332
+ continue;
37333
+ }
37334
+ const previous = i === 0 ? '' : text.charAt(i - 1);
37335
+ const opening = previous === '' || /[\s([{‘“-]/.test(previous);
37336
+ if (char === '"') {
37337
+ result += opening ? '“' : '”';
37338
+ }
37339
+ else {
37340
+ result += opening ? '‘' : '’';
37341
+ }
37342
+ }
37343
+ return result;
37344
+ }
37345
+ function applyHyphensToDash(text) {
37346
+ return text.replace(/(\S)--(?=\S)/g, '$1—').replace(/ -- /g, ' – ');
37347
+ }
37348
+ function capitalizeSentences(text) {
37349
+ return text.replace(/(^|[.!?]\s+)([a-z])/g, (_match, lead, letter) => `${lead}${letter.toUpperCase()}`);
37350
+ }
37351
+ /** Apply every enabled AutoCorrect rule to a committed run of text. */
37352
+ function applyAutoCorrect(text, proofing) {
37353
+ if (text.length === 0) {
37354
+ return text;
37355
+ }
37356
+ let result = text;
37357
+ if (proofing.autoCorrectSmartQuotes) {
37358
+ result = applySmartQuotes(result);
37359
+ }
37360
+ if (proofing.autoCorrectHyphensToDash) {
37361
+ result = applyHyphensToDash(result);
37362
+ }
37363
+ const needsWordPass = proofing.autoCorrectTwoInitialCapitals ||
37364
+ proofing.autoCorrectCapitalizeDayNames ||
37365
+ proofing.autoCorrectFractions ||
37366
+ proofing.autoCorrectOrdinals;
37367
+ if (needsWordPass) {
37368
+ result = result
37369
+ .split(/(\s+)/)
37370
+ .map((part) => (/^\s+$/.test(part) ? part : transformWord(part, proofing)))
37371
+ .join('');
37372
+ }
37373
+ if (proofing.autoCorrectCapitalizeFirstLetter) {
37374
+ result = capitalizeSentences(result);
37375
+ }
37376
+ return result;
37377
+ }
37378
+
37379
+ /**
37380
+ * Quick Access Toolbar command catalog and list-editing helpers, backing the
37381
+ * Options > Quick Access Toolbar pane and the title-bar QAT strip.
37382
+ *
37383
+ * Ids map onto actions every binding already exposes; each binding resolves
37384
+ * an id to its own icon + handler when rendering the strip.
37385
+ */
37386
+ const QUICK_ACCESS_COMMAND_CATALOG = [
37387
+ { id: 'save', labelKey: 'pptx.toolbar.save', icon: 'save' },
37388
+ { id: 'undo', labelKey: 'pptx.toolbar.undo', icon: 'undo' },
37389
+ { id: 'redo', labelKey: 'pptx.toolbar.redo', icon: 'redo' },
37390
+ {
37391
+ id: 'presentFromStart',
37392
+ labelKey: 'pptx.options.quickAccess.command.presentFromStart',
37393
+ icon: 'play',
37394
+ },
37395
+ { id: 'print', labelKey: 'pptx.options.quickAccess.command.print', icon: 'printer' },
37396
+ { id: 'exportPdf', labelKey: 'pptx.options.quickAccess.command.exportPdf', icon: 'fileDown' },
37397
+ { id: 'newSlide', labelKey: 'pptx.options.quickAccess.command.newSlide', icon: 'plus' },
37398
+ { id: 'spellCheck', labelKey: 'pptx.settings.spellCheck', icon: 'spellCheck' },
37399
+ { id: 'zoomIn', labelKey: 'pptx.options.quickAccess.command.zoomIn', icon: 'zoomIn' },
37400
+ { id: 'zoomOut', labelKey: 'pptx.options.quickAccess.command.zoomOut', icon: 'zoomOut' },
37401
+ ];
37402
+ const DEFAULT_QUICK_ACCESS_COMMAND_IDS = [
37403
+ 'save',
37404
+ 'undo',
37405
+ 'redo',
37406
+ 'presentFromStart',
37407
+ ];
37408
+ function getQuickAccessCommand(id) {
37409
+ return QUICK_ACCESS_COMMAND_CATALOG.find((entry) => entry.id === id);
37410
+ }
37411
+ /** Commands not yet on the toolbar, in catalog order. */
37412
+ function availableQuickAccessCommands(commandIds) {
37413
+ return QUICK_ACCESS_COMMAND_CATALOG.filter((entry) => !commandIds.includes(entry.id));
37414
+ }
37415
+ function addQuickAccessCommand(commandIds, id) {
37416
+ if (commandIds.includes(id) || !getQuickAccessCommand(id)) {
37417
+ return [...commandIds];
37418
+ }
37419
+ return [...commandIds, id];
37420
+ }
37421
+ function removeQuickAccessCommand(commandIds, id) {
37422
+ return commandIds.filter((entry) => entry !== id);
37423
+ }
37424
+ function moveQuickAccessCommand(commandIds, id, direction) {
37425
+ const index = commandIds.indexOf(id);
37426
+ const target = direction === 'up' ? index - 1 : index + 1;
37427
+ if (index < 0 || target < 0 || target >= commandIds.length) {
37428
+ return [...commandIds];
37429
+ }
37430
+ const next = [...commandIds];
37431
+ const swapped = next[target];
37432
+ if (swapped === undefined) {
37433
+ return next;
37434
+ }
37435
+ next[target] = id;
37436
+ next[index] = swapped;
37437
+ return next;
37438
+ }
37439
+
37440
+ /**
37441
+ * Options > Add-ins pane model: the viewer's optional capability modules,
37442
+ * presented the way PowerPoint lists COM add-ins (name / location / type,
37443
+ * grouped by active state). Bindings supply the runtime availability flags.
37444
+ */
37445
+ const VIEWER_ADDIN_CATALOG = [
37446
+ {
37447
+ id: 'smartArt3d',
37448
+ nameKey: 'pptx.options.addIns.smartArt3d',
37449
+ descriptionKey: 'pptx.options.addIns.smartArt3dDescription',
37450
+ type: 'renderer',
37451
+ location: 'pptx-viewer-shared/smartart-3d',
37452
+ },
37453
+ {
37454
+ id: 'model3d',
37455
+ nameKey: 'pptx.options.addIns.model3d',
37456
+ descriptionKey: 'pptx.options.addIns.model3dDescription',
37457
+ type: 'renderer',
37458
+ location: 'pptx-viewer-shared (three)',
37459
+ },
37460
+ {
37461
+ id: 'emfConverter',
37462
+ nameKey: 'pptx.options.addIns.emfConverter',
37463
+ descriptionKey: 'pptx.options.addIns.emfConverterDescription',
37464
+ type: 'converter',
37465
+ location: 'emf-converter',
37466
+ },
37467
+ {
37468
+ id: 'mtxDecompressor',
37469
+ nameKey: 'pptx.options.addIns.mtxDecompressor',
37470
+ descriptionKey: 'pptx.options.addIns.mtxDecompressorDescription',
37471
+ type: 'converter',
37472
+ location: 'mtx-decompressor',
37473
+ },
37474
+ {
37475
+ id: 'collaboration',
37476
+ nameKey: 'pptx.options.addIns.collaboration',
37477
+ descriptionKey: 'pptx.options.addIns.collaborationDescription',
37478
+ type: 'collaboration',
37479
+ location: 'pptx-viewer-shared (collaboration)',
37480
+ },
37481
+ {
37482
+ id: 'locales',
37483
+ nameKey: 'pptx.options.addIns.locales',
37484
+ descriptionKey: 'pptx.options.addIns.localesDescription',
37485
+ type: 'localization',
37486
+ location: 'pptx-viewer-locales',
37487
+ },
37488
+ ];
37489
+ /** Rows for the Add-ins table, split into active/inactive by the host's status flags. */
37490
+ function resolveViewerAddinRows(status) {
37491
+ return VIEWER_ADDIN_CATALOG.map((definition) => ({
37492
+ ...definition,
37493
+ active: status?.[definition.id] ?? true,
37494
+ }));
37495
+ }
37496
+
37497
+ const DEFAULT_VIEWER_OPTIONS = {
37498
+ general: {
37499
+ displayOptimization: 'appearance',
37500
+ showMiniToolbar: true,
37501
+ enableLivePreview: true,
37502
+ collapseRibbonAutomatically: false,
37503
+ collapseSearchByDefault: false,
37504
+ screenTipStyle: 'descriptions',
37505
+ userName: '',
37506
+ userInitials: '',
37507
+ showStartScreen: true,
37508
+ },
37509
+ proofing: {
37510
+ autoCorrectTwoInitialCapitals: true,
37511
+ autoCorrectCapitalizeFirstLetter: true,
37512
+ autoCorrectCapitalizeDayNames: true,
37513
+ autoCorrectSmartQuotes: true,
37514
+ autoCorrectHyphensToDash: true,
37515
+ autoCorrectFractions: true,
37516
+ autoCorrectOrdinals: true,
37517
+ ignoreUppercase: true,
37518
+ ignoreWordsWithNumbers: true,
37519
+ ignoreInternetAddresses: true,
37520
+ flagRepeatedWords: true,
37521
+ checkSpellingAsYouType: false,
37522
+ hideSpellingErrors: false,
37523
+ },
37524
+ save: {
37525
+ autoSave: true,
37526
+ autoRecoverIntervalMinutes: 2,
37527
+ keepLastAutoRecoveredVersion: true,
37528
+ defaultExportFormat: 'pptx',
37529
+ embedFonts: false,
37530
+ embedAllFontCharacters: false,
37531
+ cacheRetentionDays: 14,
37532
+ clearCacheOnClose: false,
37533
+ },
37534
+ accessibility: {
37535
+ showAccessibilityStatus: true,
37536
+ feedbackWithSound: false,
37537
+ soundScheme: 'modern',
37538
+ showShortcutKeysInScreenTips: true,
37539
+ reducedMotion: false,
37540
+ },
37541
+ advanced: {
37542
+ autoSelectEntireWord: true,
37543
+ allowTextDragAndDrop: true,
37544
+ maximumUndoSteps: 100,
37545
+ useSmartCutAndPaste: true,
37546
+ showPasteOptionsButton: true,
37547
+ imageDefaultResolution: 'highFidelity',
37548
+ doNotCompressImages: false,
37549
+ chartPropertiesFollowDataPoint: true,
37550
+ recentPresentationsCount: 50,
37551
+ showVerticalRuler: false,
37552
+ showGrid: false,
37553
+ snapToGrid: false,
37554
+ disableHardwareAcceleration: false,
37555
+ openDocumentsView: 'savedView',
37556
+ slideShowShowMenuOnRightClick: true,
37557
+ slideShowShowPopupToolbar: true,
37558
+ slideShowPromptKeepInkAnnotations: true,
37559
+ slideShowEndWithBlackSlide: true,
37560
+ printInBackground: true,
37561
+ printHighQuality: false,
37562
+ printUseMostRecentSettings: true,
37563
+ printWhat: 'slides',
37564
+ printColorMode: 'color',
37565
+ printHiddenSlides: false,
37566
+ printScaleToFit: false,
37567
+ printFrameSlides: false,
37568
+ },
37569
+ ribbon: { hiddenTabIds: [] },
37570
+ quickAccess: {
37571
+ visible: true,
37572
+ position: 'above',
37573
+ showCommandLabels: false,
37574
+ commandIds: ['save', 'undo', 'redo', 'presentFromStart'],
37575
+ },
37576
+ trust: {
37577
+ openInProtectedView: false,
37578
+ allowExternalContent: true,
37579
+ confirmExternalHyperlinks: true,
37580
+ },
37581
+ };
37582
+ function cloneOptions(options) {
37583
+ return {
37584
+ general: { ...options.general },
37585
+ proofing: { ...options.proofing },
37586
+ save: { ...options.save },
37587
+ accessibility: { ...options.accessibility },
37588
+ advanced: { ...options.advanced },
37589
+ ribbon: { hiddenTabIds: [...options.ribbon.hiddenTabIds] },
37590
+ quickAccess: { ...options.quickAccess, commandIds: [...options.quickAccess.commandIds] },
37591
+ trust: { ...options.trust },
37592
+ };
37593
+ }
37594
+ /** Merge a persisted partial over the defaults, dropping unknown keys. */
37595
+ function mergeViewerOptions(stored) {
37596
+ const merged = cloneOptions(DEFAULT_VIEWER_OPTIONS);
37597
+ if (!stored || typeof stored !== 'object') {
37598
+ return merged;
37599
+ }
37600
+ for (const groupId of Object.keys(merged)) {
37601
+ const patch = stored[groupId];
37602
+ if (!patch || typeof patch !== 'object') {
37603
+ continue;
37604
+ }
37605
+ const target = merged[groupId];
37606
+ const defaults = DEFAULT_VIEWER_OPTIONS[groupId];
37607
+ for (const [key, value] of Object.entries(patch)) {
37608
+ if (!(key in defaults) || value === undefined) {
37609
+ continue;
37610
+ }
37611
+ const defaultValue = defaults[key];
37612
+ if (Array.isArray(defaultValue)) {
37613
+ if (Array.isArray(value)) {
37614
+ target[key] = value.filter((entry) => typeof entry === 'string');
37615
+ }
37616
+ }
37617
+ else if (typeof value === typeof defaultValue) {
37618
+ target[key] = value;
37619
+ }
37620
+ }
37621
+ }
37622
+ return merged;
37623
+ }
37624
+ /** Sparse diff of `options` against the defaults, for lean persistence. */
37625
+ function diffViewerOptions(options) {
37626
+ const diff = {};
37627
+ for (const groupId of Object.keys(DEFAULT_VIEWER_OPTIONS)) {
37628
+ const defaults = DEFAULT_VIEWER_OPTIONS[groupId];
37629
+ const current = options[groupId];
37630
+ let groupDiff;
37631
+ for (const key of Object.keys(defaults)) {
37632
+ const defaultValue = defaults[key];
37633
+ const value = current[key];
37634
+ const changed = Array.isArray(defaultValue)
37635
+ ? JSON.stringify(defaultValue) !== JSON.stringify(value)
37636
+ : defaultValue !== value;
37637
+ if (changed) {
37638
+ groupDiff ??= {};
37639
+ groupDiff[key] = value;
37640
+ }
37641
+ }
37642
+ if (groupDiff) {
37643
+ diff[groupId] = groupDiff;
37644
+ }
37645
+ }
37646
+ return diff;
37647
+ }
37648
+ /** Project the full options model onto the legacy six-toggle preferences surface. */
37649
+ function viewerOptionsToPreferences(options) {
37650
+ return {
37651
+ autoSave: options.save.autoSave,
37652
+ spellCheck: options.proofing.checkSpellingAsYouType,
37653
+ showGrid: options.advanced.showGrid,
37654
+ showRulers: options.advanced.showVerticalRuler,
37655
+ snapToGrid: options.advanced.snapToGrid,
37656
+ reducedMotion: options.accessibility.reducedMotion,
37657
+ };
37658
+ }
37659
+ /** Apply a legacy preference toggle back onto the options model. */
37660
+ function applyPreferenceToOptions(options, key, value) {
37661
+ const next = cloneOptions(options);
37662
+ switch (key) {
37663
+ case 'autoSave':
37664
+ next.save.autoSave = value;
37665
+ break;
37666
+ case 'spellCheck':
37667
+ next.proofing.checkSpellingAsYouType = value;
37668
+ break;
37669
+ case 'showGrid':
37670
+ next.advanced.showGrid = value;
37671
+ break;
37672
+ case 'showRulers':
37673
+ next.advanced.showVerticalRuler = value;
37674
+ break;
37675
+ case 'snapToGrid':
37676
+ next.advanced.snapToGrid = value;
37677
+ break;
37678
+ case 'reducedMotion':
37679
+ next.accessibility.reducedMotion = value;
37680
+ break;
37681
+ }
37682
+ return next;
37683
+ }
37684
+
37685
+ /**
37686
+ * Pure helpers that translate File > Options values into the behaviors the
37687
+ * bindings actually wire: history depth, autosave cadence, tooltips, ribbon
37688
+ * visibility, print defaults, image export quality, and protected view.
37689
+ */
37690
+ /** Maximum undo steps for `EditorHistory({ maxDepth })`. */
37691
+ function resolveHistoryDepth(options) {
37692
+ const steps = Math.round(options.advanced.maximumUndoSteps);
37693
+ return Math.min(150, Math.max(3, Number.isFinite(steps) ? steps : 100));
37694
+ }
37695
+ /** AutoRecover cadence in seconds, honoring the shared minimum. */
37696
+ function resolveAutosaveIntervalSeconds(options) {
37697
+ const seconds = Math.round(options.save.autoRecoverIntervalMinutes * 60);
37698
+ return Math.max(AUTOSAVE_MIN_INTERVAL_SECONDS, Number.isFinite(seconds) ? seconds : 120);
37699
+ }
37700
+ /**
37701
+ * Tooltip text for a chrome control under the current ScreenTip style:
37702
+ * `off` suppresses tooltips entirely, `plain` drops the description, and
37703
+ * shortcut hints append only while Accessibility > shortcut keys is on.
37704
+ */
37705
+ function resolveScreenTip(options, label, description, shortcut) {
37706
+ const style = options.general.screenTipStyle;
37707
+ if (style === 'off') {
37708
+ return undefined;
37709
+ }
37710
+ let tip = label;
37711
+ if (style === 'descriptions' && description) {
37712
+ tip = `${tip}: ${description}`;
37713
+ }
37714
+ if (shortcut && options.accessibility.showShortcutKeysInScreenTips) {
37715
+ tip = `${tip} (${shortcut})`;
37716
+ }
37717
+ return tip;
37718
+ }
37719
+ /** Ribbon tabs after Customize Ribbon hiding; the File tab always survives. */
37720
+ function resolveVisibleRibbonTabs(options, tabs = TOOLBAR_TABS) {
37721
+ const hidden = new Set(options.ribbon.hiddenTabIds);
37722
+ hidden.delete('file');
37723
+ return tabs.filter((tab) => !hidden.has(tab.id));
37724
+ }
37725
+ /**
37726
+ * Seed for print dialogs when "use the following print settings" is chosen;
37727
+ * `undefined` keeps each dialog's own most-recent settings (PowerPoint's
37728
+ * "Use the most recently used print settings").
37729
+ */
37730
+ function resolveDefaultPrintSettings(options) {
37731
+ if (options.advanced.printUseMostRecentSettings) {
37732
+ return undefined;
37733
+ }
37734
+ return {
37735
+ printWhat: options.advanced.printWhat,
37736
+ colorMode: options.advanced.printColorMode,
37737
+ frameSlides: options.advanced.printFrameSlides,
37738
+ };
37739
+ }
37740
+ /** Target raster density in ppi for image export; `undefined` = lossless/high fidelity. */
37741
+ function resolveImageResolutionPpi(preset) {
37742
+ switch (preset) {
37743
+ case 'ppi330':
37744
+ return 330;
37745
+ case 'ppi220':
37746
+ return 220;
37747
+ case 'ppi150':
37748
+ return 150;
37749
+ case 'ppi96':
37750
+ return 96;
37751
+ default:
37752
+ return undefined;
37753
+ }
37754
+ }
37755
+ /** Raster scale multiplier relative to the standard 96 ppi CSS pixel grid. */
37756
+ function resolveImageResolutionScale(options) {
37757
+ if (options.advanced.doNotCompressImages) {
37758
+ return 1;
37759
+ }
37760
+ const ppi = resolveImageResolutionPpi(options.advanced.imageDefaultResolution);
37761
+ return ppi === undefined ? 1 : Math.max(0.25, Math.min(4, ppi / 96));
37762
+ }
37763
+ /** Whether the viewer should open documents read-only until editing is enabled. */
37764
+ function shouldOpenInProtectedView(options) {
37765
+ return options.trust.openInProtectedView;
37766
+ }
37767
+ /** Whether following an external hyperlink should ask for confirmation first. */
37768
+ function shouldConfirmExternalHyperlink(options, href) {
37769
+ if (!options.trust.confirmExternalHyperlinks) {
37770
+ return false;
37771
+ }
37772
+ return /^https?:/i.test(href);
37773
+ }
37774
+ /** CSS class list for the viewer root reflecting display-affecting options. */
37775
+ function resolveOptionRootClasses(options, prefix) {
37776
+ const classes = [];
37777
+ if (options.accessibility.reducedMotion) {
37778
+ classes.push(`${prefix}-reduced-motion`);
37779
+ }
37780
+ if (options.advanced.disableHardwareAcceleration) {
37781
+ classes.push(`${prefix}-no-hw-accel`);
37782
+ }
37783
+ if (options.general.displayOptimization === 'compatibility') {
37784
+ classes.push(`${prefix}-compat-display`);
37785
+ }
37786
+ return classes;
37787
+ }
37788
+ /** Play the Accessibility > "feedback with sound" cue for a completed action. */
37789
+ function playFeedbackSound(options) {
37790
+ if (!options.accessibility.feedbackWithSound || typeof window === 'undefined') {
37791
+ return;
37792
+ }
37793
+ const AudioContextCtor = window.AudioContext;
37794
+ if (!AudioContextCtor) {
37795
+ return;
37796
+ }
37797
+ try {
37798
+ const context = new AudioContextCtor();
37799
+ const oscillator = context.createOscillator();
37800
+ const gain = context.createGain();
37801
+ const modern = options.accessibility.soundScheme === 'modern';
37802
+ oscillator.frequency.value = modern ? 880 : 660;
37803
+ oscillator.type = modern ? 'sine' : 'square';
37804
+ gain.gain.setValueAtTime(0.04, context.currentTime);
37805
+ gain.gain.exponentialRampToValueAtTime(0.0001, context.currentTime + 0.15);
37806
+ oscillator.connect(gain).connect(context.destination);
37807
+ oscillator.start();
37808
+ oscillator.stop(context.currentTime + 0.16);
37809
+ oscillator.onended = () => {
37810
+ void context.close();
37811
+ };
37812
+ }
37813
+ catch {
37814
+ // Audio unavailable (autoplay policy, headless env): stay silent.
37815
+ }
37816
+ }
37817
+
37818
+ function toggle(group, key, labelKey, extra) {
37819
+ return { kind: 'toggle', group, key, labelKey, ...extra };
37820
+ }
37821
+ function select(group, key, labelKey, choiceList) {
37822
+ return { kind: 'select', group, key, labelKey, choices: choiceList };
37823
+ }
37824
+ function numberControl(group, key, labelKey, min, max, unitKey) {
37825
+ return { kind: 'number', group, key, labelKey, min, max, unitKey };
37826
+ }
37827
+ function textControl(group, key, labelKey) {
37828
+ return { kind: 'text', group, key, labelKey, maxLength: 64 };
37829
+ }
37830
+ function choices(prefix, values) {
37831
+ return values.map((value) => ({ value, labelKey: `${prefix}.${value}` }));
37832
+ }
37833
+ const SCREEN_TIP_CHOICES = choices('pptx.options.screenTipStyle', [
37834
+ 'descriptions',
37835
+ 'plain',
37836
+ 'off',
37837
+ ]);
37838
+
37839
+ /** Advanced, Customize Ribbon, Quick Access, Add-ins, and Trust Center tabs. */
37840
+ const ADVANCED_TAB = {
37841
+ id: 'advanced',
37842
+ labelKey: 'pptx.options.advanced.label',
37843
+ descriptionKey: 'pptx.options.advanced.description',
37844
+ sections: [
37845
+ {
37846
+ id: 'editing',
37847
+ titleKey: 'pptx.options.advanced.editing',
37848
+ controls: [
37849
+ toggle('advanced', 'autoSelectEntireWord', 'pptx.options.advanced.autoSelectWord'),
37850
+ toggle('advanced', 'allowTextDragAndDrop', 'pptx.options.advanced.textDragAndDrop'),
37851
+ numberControl('advanced', 'maximumUndoSteps', 'pptx.options.advanced.maximumUndoSteps', 3, 150),
37852
+ ],
37853
+ },
37854
+ {
37855
+ id: 'cutCopyPaste',
37856
+ titleKey: 'pptx.options.advanced.cutCopyPaste',
37857
+ controls: [
37858
+ toggle('advanced', 'useSmartCutAndPaste', 'pptx.options.advanced.smartCutAndPaste'),
37859
+ toggle('advanced', 'showPasteOptionsButton', 'pptx.options.advanced.showPasteOptions'),
37860
+ ],
37861
+ },
37862
+ {
37863
+ id: 'imageQuality',
37864
+ titleKey: 'pptx.options.advanced.imageQuality',
37865
+ controls: [
37866
+ toggle('advanced', 'doNotCompressImages', 'pptx.options.advanced.doNotCompressImages'),
37867
+ select('advanced', 'imageDefaultResolution', 'pptx.options.advanced.defaultResolution', choices('pptx.options.resolution', [
37868
+ 'highFidelity',
37869
+ 'ppi330',
37870
+ 'ppi220',
37871
+ 'ppi150',
37872
+ 'ppi96',
37873
+ ])),
37874
+ ],
37875
+ },
37876
+ {
37877
+ id: 'chart',
37878
+ titleKey: 'pptx.options.advanced.chart',
37879
+ controls: [
37880
+ toggle('advanced', 'chartPropertiesFollowDataPoint', 'pptx.options.advanced.chartFollowDataPoint'),
37881
+ ],
37882
+ },
37883
+ {
37884
+ id: 'display',
37885
+ titleKey: 'pptx.options.advanced.display',
37886
+ controls: [
37887
+ numberControl('advanced', 'recentPresentationsCount', 'pptx.options.advanced.recentCount', 0, 50),
37888
+ toggle('advanced', 'showVerticalRuler', 'pptx.settings.showRulers'),
37889
+ toggle('advanced', 'showGrid', 'pptx.settings.showGrid'),
37890
+ toggle('advanced', 'snapToGrid', 'pptx.settings.snapToGrid'),
37891
+ toggle('advanced', 'disableHardwareAcceleration', 'pptx.options.advanced.disableHardwareAcceleration'),
37892
+ select('advanced', 'openDocumentsView', 'pptx.options.advanced.openDocumentsView', choices('pptx.options.openView', [
37893
+ 'savedView',
37894
+ 'normal',
37895
+ 'outline',
37896
+ 'slideSorter',
37897
+ 'notes',
37898
+ ])),
37899
+ ],
37900
+ },
37901
+ {
37902
+ id: 'slideShow',
37903
+ titleKey: 'pptx.options.advanced.slideShow',
37904
+ controls: [
37905
+ toggle('advanced', 'slideShowShowMenuOnRightClick', 'pptx.options.advanced.showMenuOnRightClick'),
37906
+ toggle('advanced', 'slideShowShowPopupToolbar', 'pptx.options.advanced.showPopupToolbar'),
37907
+ toggle('advanced', 'slideShowPromptKeepInkAnnotations', 'pptx.options.advanced.promptKeepInk'),
37908
+ toggle('advanced', 'slideShowEndWithBlackSlide', 'pptx.options.advanced.endWithBlackSlide'),
37909
+ ],
37910
+ },
37911
+ {
37912
+ id: 'print',
37913
+ titleKey: 'pptx.options.advanced.print',
37914
+ controls: [
37915
+ toggle('advanced', 'printInBackground', 'pptx.options.advanced.printInBackground'),
37916
+ toggle('advanced', 'printHighQuality', 'pptx.options.advanced.printHighQuality'),
37917
+ toggle('advanced', 'printUseMostRecentSettings', 'pptx.options.advanced.printUseMostRecent'),
37918
+ select('advanced', 'printWhat', 'pptx.options.advanced.printWhat', choices('pptx.options.printWhat', ['slides', 'handouts', 'notes', 'outline'])),
37919
+ select('advanced', 'printColorMode', 'pptx.options.advanced.printColorMode', choices('pptx.options.printColorMode', ['color', 'grayscale', 'blackAndWhite'])),
37920
+ toggle('advanced', 'printHiddenSlides', 'pptx.options.advanced.printHiddenSlides', {
37921
+ indent: true,
37922
+ }),
37923
+ toggle('advanced', 'printScaleToFit', 'pptx.options.advanced.printScaleToFit', {
37924
+ indent: true,
37925
+ }),
37926
+ toggle('advanced', 'printFrameSlides', 'pptx.options.advanced.printFrameSlides', {
37927
+ indent: true,
37928
+ }),
37929
+ ],
37930
+ },
37931
+ ],
37932
+ };
37933
+ const RIBBON_TAB = {
37934
+ id: 'ribbon',
37935
+ labelKey: 'pptx.options.ribbon.label',
37936
+ descriptionKey: 'pptx.options.ribbon.description',
37937
+ custom: 'ribbon',
37938
+ sections: [
37939
+ {
37940
+ id: 'shortcutReference',
37941
+ titleKey: 'pptx.settings.keyboardShortcuts',
37942
+ special: 'shortcutReference',
37943
+ controls: [],
37944
+ },
37945
+ ],
37946
+ };
37947
+ const QUICK_ACCESS_TAB = {
37948
+ id: 'quickAccess',
37949
+ labelKey: 'pptx.options.quickAccess.label',
37950
+ descriptionKey: 'pptx.options.quickAccess.description',
37951
+ custom: 'quickAccess',
37952
+ sections: [
37953
+ {
37954
+ id: 'quickAccessOptions',
37955
+ titleKey: 'pptx.options.quickAccess.optionsTitle',
37956
+ controls: [
37957
+ toggle('quickAccess', 'visible', 'pptx.options.quickAccess.show'),
37958
+ select('quickAccess', 'position', 'pptx.options.quickAccess.position', choices('pptx.options.quickAccessPosition', ['above', 'below'])),
37959
+ toggle('quickAccess', 'showCommandLabels', 'pptx.options.quickAccess.showLabels'),
37960
+ ],
37961
+ },
37962
+ ],
37963
+ };
37964
+ const ADD_INS_TAB = {
37965
+ id: 'addIns',
37966
+ labelKey: 'pptx.options.addIns.label',
37967
+ descriptionKey: 'pptx.options.addIns.description',
37968
+ custom: 'addIns',
37969
+ sections: [],
37970
+ };
37971
+ const TRUST_TAB = {
37972
+ id: 'trust',
37973
+ labelKey: 'pptx.options.trust.label',
37974
+ descriptionKey: 'pptx.options.trust.description',
37975
+ sections: [
37976
+ {
37977
+ id: 'trustSettings',
37978
+ titleKey: 'pptx.options.trust.settingsTitle',
37979
+ descriptionKey: 'pptx.options.trust.settingsDescription',
37980
+ controls: [
37981
+ toggle('trust', 'openInProtectedView', 'pptx.options.trust.protectedView', {
37982
+ infoKey: 'pptx.options.trust.protectedViewInfo',
37983
+ }),
37984
+ toggle('trust', 'allowExternalContent', 'pptx.options.trust.allowExternalContent', {
37985
+ infoKey: 'pptx.options.trust.allowExternalContentInfo',
37986
+ }),
37987
+ toggle('trust', 'confirmExternalHyperlinks', 'pptx.options.trust.confirmHyperlinks'),
37988
+ ],
37989
+ },
37990
+ ],
37991
+ };
37992
+
37993
+ /** General, Proofing, Save, Language, and Accessibility tab definitions. */
37994
+ const GENERAL_TAB = {
37995
+ id: 'general',
37996
+ labelKey: 'pptx.settings.general',
37997
+ descriptionKey: 'pptx.options.general.description',
37998
+ sections: [
37999
+ {
38000
+ id: 'userInterface',
38001
+ titleKey: 'pptx.options.general.userInterface',
38002
+ controls: [
38003
+ select('general', 'displayOptimization', 'pptx.options.general.displayOptimization', choices('pptx.options.displayOptimization', ['appearance', 'compatibility'])),
38004
+ toggle('general', 'showMiniToolbar', 'pptx.options.general.showMiniToolbar', {
38005
+ infoKey: 'pptx.options.general.showMiniToolbarInfo',
38006
+ }),
38007
+ toggle('general', 'enableLivePreview', 'pptx.options.general.enableLivePreview', {
38008
+ infoKey: 'pptx.options.general.enableLivePreviewInfo',
38009
+ }),
38010
+ toggle('general', 'collapseRibbonAutomatically', 'pptx.options.general.collapseRibbon'),
38011
+ toggle('general', 'collapseSearchByDefault', 'pptx.options.general.collapseSearch'),
38012
+ select('general', 'screenTipStyle', 'pptx.options.general.screenTipStyle', SCREEN_TIP_CHOICES),
38013
+ ],
38014
+ },
38015
+ {
38016
+ id: 'personalize',
38017
+ titleKey: 'pptx.options.general.personalize',
38018
+ controls: [
38019
+ textControl('general', 'userName', 'pptx.options.general.userName'),
38020
+ textControl('general', 'userInitials', 'pptx.options.general.userInitials'),
38021
+ ],
38022
+ },
38023
+ {
38024
+ id: 'appearance',
38025
+ titleKey: 'pptx.options.general.appearance',
38026
+ special: 'themePicker',
38027
+ controls: [],
38028
+ },
38029
+ {
38030
+ id: 'startup',
38031
+ titleKey: 'pptx.options.general.startup',
38032
+ controls: [toggle('general', 'showStartScreen', 'pptx.options.general.showStartScreen')],
38033
+ },
38034
+ ],
38035
+ };
38036
+ const PROOFING_TAB = {
38037
+ id: 'proofing',
38038
+ labelKey: 'pptx.options.proofing.label',
38039
+ descriptionKey: 'pptx.options.proofing.description',
38040
+ sections: [
38041
+ {
38042
+ id: 'autoCorrect',
38043
+ titleKey: 'pptx.options.proofing.autoCorrect',
38044
+ descriptionKey: 'pptx.options.proofing.autoCorrectDescription',
38045
+ controls: [
38046
+ toggle('proofing', 'autoCorrectTwoInitialCapitals', 'pptx.options.proofing.twoInitialCapitals'),
38047
+ toggle('proofing', 'autoCorrectCapitalizeFirstLetter', 'pptx.options.proofing.capitalizeFirstLetter'),
38048
+ toggle('proofing', 'autoCorrectCapitalizeDayNames', 'pptx.options.proofing.capitalizeDayNames'),
38049
+ toggle('proofing', 'autoCorrectSmartQuotes', 'pptx.options.proofing.smartQuotes'),
38050
+ toggle('proofing', 'autoCorrectHyphensToDash', 'pptx.options.proofing.hyphensToDash'),
38051
+ toggle('proofing', 'autoCorrectFractions', 'pptx.options.proofing.fractions'),
38052
+ toggle('proofing', 'autoCorrectOrdinals', 'pptx.options.proofing.ordinals'),
38053
+ ],
38054
+ },
38055
+ {
38056
+ id: 'spellingOffice',
38057
+ titleKey: 'pptx.options.proofing.spellingOffice',
38058
+ controls: [
38059
+ toggle('proofing', 'ignoreUppercase', 'pptx.options.proofing.ignoreUppercase'),
38060
+ toggle('proofing', 'ignoreWordsWithNumbers', 'pptx.options.proofing.ignoreWordsWithNumbers'),
38061
+ toggle('proofing', 'ignoreInternetAddresses', 'pptx.options.proofing.ignoreInternetAddresses'),
38062
+ toggle('proofing', 'flagRepeatedWords', 'pptx.options.proofing.flagRepeatedWords'),
38063
+ ],
38064
+ },
38065
+ {
38066
+ id: 'spellingViewer',
38067
+ titleKey: 'pptx.options.proofing.spellingViewer',
38068
+ controls: [
38069
+ toggle('proofing', 'checkSpellingAsYouType', 'pptx.options.proofing.checkSpellingAsYouType'),
38070
+ toggle('proofing', 'hideSpellingErrors', 'pptx.options.proofing.hideSpellingErrors', {
38071
+ indent: true,
38072
+ }),
38073
+ ],
38074
+ },
38075
+ ],
38076
+ };
38077
+ const SAVE_TAB = {
38078
+ id: 'save',
38079
+ labelKey: 'pptx.options.save.label',
38080
+ descriptionKey: 'pptx.options.save.description',
38081
+ sections: [
38082
+ {
38083
+ id: 'savePresentations',
38084
+ titleKey: 'pptx.options.save.savePresentations',
38085
+ controls: [
38086
+ toggle('save', 'autoSave', 'pptx.options.save.autoSave', {
38087
+ infoKey: 'pptx.options.save.autoSaveInfo',
38088
+ }),
38089
+ select('save', 'defaultExportFormat', 'pptx.options.save.defaultFormat', choices('pptx.options.saveFormat', ['pptx', 'pdf', 'png'])),
38090
+ numberControl('save', 'autoRecoverIntervalMinutes', 'pptx.options.save.autoRecoverInterval', 1, 120, 'pptx.options.save.minutes'),
38091
+ toggle('save', 'keepLastAutoRecoveredVersion', 'pptx.options.save.keepLastAutoRecovered', {
38092
+ indent: true,
38093
+ }),
38094
+ ],
38095
+ },
38096
+ {
38097
+ id: 'fidelity',
38098
+ titleKey: 'pptx.options.save.fidelity',
38099
+ controls: [
38100
+ toggle('save', 'embedFonts', 'pptx.options.save.embedFonts', {
38101
+ infoKey: 'pptx.options.save.embedFontsInfo',
38102
+ }),
38103
+ toggle('save', 'embedAllFontCharacters', 'pptx.options.save.embedAllCharacters', {
38104
+ indent: true,
38105
+ }),
38106
+ ],
38107
+ },
38108
+ {
38109
+ id: 'cache',
38110
+ titleKey: 'pptx.options.save.cache',
38111
+ special: 'clearCache',
38112
+ controls: [
38113
+ numberControl('save', 'cacheRetentionDays', 'pptx.options.save.cacheRetentionDays', 1, 90, 'pptx.options.save.days'),
38114
+ toggle('save', 'clearCacheOnClose', 'pptx.options.save.clearCacheOnClose'),
38115
+ ],
38116
+ },
38117
+ ],
38118
+ };
38119
+ const LANGUAGE_TAB = {
38120
+ id: 'language',
38121
+ labelKey: 'pptx.settings.language',
38122
+ descriptionKey: 'pptx.options.language.description',
38123
+ custom: 'language',
38124
+ sections: [],
38125
+ };
38126
+ const ACCESSIBILITY_TAB = {
38127
+ id: 'accessibility',
38128
+ labelKey: 'pptx.options.accessibility.label',
38129
+ descriptionKey: 'pptx.options.accessibility.description',
38130
+ sections: [
38131
+ {
38132
+ id: 'assistant',
38133
+ titleKey: 'pptx.options.accessibility.assistant',
38134
+ controls: [
38135
+ toggle('accessibility', 'showAccessibilityStatus', 'pptx.options.accessibility.showStatus'),
38136
+ ],
38137
+ },
38138
+ {
38139
+ id: 'feedback',
38140
+ titleKey: 'pptx.options.accessibility.feedback',
38141
+ controls: [
38142
+ toggle('accessibility', 'feedbackWithSound', 'pptx.options.accessibility.feedbackWithSound'),
38143
+ select('accessibility', 'soundScheme', 'pptx.options.accessibility.soundScheme', choices('pptx.options.soundScheme', ['modern', 'classic'])),
38144
+ ],
38145
+ },
38146
+ {
38147
+ id: 'display',
38148
+ titleKey: 'pptx.options.accessibility.display',
38149
+ controls: [
38150
+ select('general', 'screenTipStyle', 'pptx.options.general.screenTipStyle', SCREEN_TIP_CHOICES),
38151
+ toggle('accessibility', 'showShortcutKeysInScreenTips', 'pptx.options.accessibility.showShortcutKeys'),
38152
+ toggle('accessibility', 'reducedMotion', 'pptx.settings.reducedMotion'),
38153
+ ],
38154
+ },
38155
+ ],
38156
+ };
38157
+
38158
+ /**
38159
+ * The ten File > Options categories, in PowerPoint's order. Bindings render
38160
+ * the dialog's category list and panes from this array.
38161
+ */
38162
+ const VIEWER_OPTIONS_TABS = [
38163
+ GENERAL_TAB,
38164
+ PROOFING_TAB,
38165
+ SAVE_TAB,
38166
+ LANGUAGE_TAB,
38167
+ ACCESSIBILITY_TAB,
38168
+ ADVANCED_TAB,
38169
+ RIBBON_TAB,
38170
+ QUICK_ACCESS_TAB,
38171
+ ADD_INS_TAB,
38172
+ TRUST_TAB,
38173
+ ];
38174
+ function getViewerOptionsTab(id) {
38175
+ const tab = VIEWER_OPTIONS_TABS.find((entry) => entry.id === id);
38176
+ if (!tab) {
38177
+ throw new Error(`Unknown viewer options tab: ${id}`);
38178
+ }
38179
+ return tab;
38180
+ }
38181
+
38182
+ function createViewerOptionsStore(init) {
38183
+ const persist = init?.persist !== false;
38184
+ const seeded = mergeViewerOptions(init?.initial);
38185
+ let options = persist ? overlayStored(seeded, readStoredViewerPrefs().options) : seeded;
38186
+ const listeners = new Set();
38187
+ function commit(next) {
38188
+ options = next;
38189
+ if (persist) {
38190
+ writeStoredViewerPrefs({ options: diffViewerOptions(next) });
38191
+ }
38192
+ for (const listener of listeners) {
38193
+ listener(options);
38194
+ }
38195
+ }
38196
+ return {
38197
+ getOptions: () => options,
38198
+ setOptions: (next) => commit(cloneOptions(next)),
38199
+ setValue: (group, key, value) => {
38200
+ const defaults = DEFAULT_VIEWER_OPTIONS[group];
38201
+ if (!(key in defaults) || typeof defaults[key] !== typeof value) {
38202
+ return;
38203
+ }
38204
+ const next = cloneOptions(options);
38205
+ next[group][key] = value;
38206
+ commit(next);
38207
+ },
38208
+ getValue: (group, key) => {
38209
+ const record = options[group];
38210
+ const value = record[key];
38211
+ return typeof value === 'boolean' || typeof value === 'number' || typeof value === 'string'
38212
+ ? value
38213
+ : undefined;
38214
+ },
38215
+ setRibbonTabHidden: (tabId, hidden) => {
38216
+ if (tabId === 'file') {
38217
+ return;
38218
+ }
38219
+ const current = options.ribbon.hiddenTabIds;
38220
+ const has = current.includes(tabId);
38221
+ if (hidden === has) {
38222
+ return;
38223
+ }
38224
+ const next = cloneOptions(options);
38225
+ next.ribbon.hiddenTabIds = hidden
38226
+ ? [...current, tabId]
38227
+ : current.filter((id) => id !== tabId);
38228
+ commit(next);
38229
+ },
38230
+ setQuickAccessCommands: (commandIds) => {
38231
+ const next = cloneOptions(options);
38232
+ next.quickAccess.commandIds = [...commandIds];
38233
+ commit(next);
38234
+ },
38235
+ reset: (group) => {
38236
+ if (!group) {
38237
+ commit(cloneOptions(DEFAULT_VIEWER_OPTIONS));
38238
+ return;
38239
+ }
38240
+ const next = cloneOptions(options);
38241
+ const defaults = cloneOptions(DEFAULT_VIEWER_OPTIONS);
38242
+ next[group] = defaults[group];
38243
+ commit(next);
38244
+ },
38245
+ subscribe: (listener) => {
38246
+ listeners.add(listener);
38247
+ return () => listeners.delete(listener);
38248
+ },
38249
+ };
38250
+ }
38251
+ function overlayStored(base, stored) {
38252
+ if (!stored) {
38253
+ return base;
38254
+ }
38255
+ const fromStored = mergeViewerOptions(stored);
38256
+ const merged = cloneOptions(base);
38257
+ const diff = diffViewerOptions(fromStored);
38258
+ for (const groupId of Object.keys(diff)) {
38259
+ const patch = diff[groupId];
38260
+ if (!patch) {
38261
+ continue;
38262
+ }
38263
+ Object.assign(merged[groupId], patch);
38264
+ }
38265
+ return merged;
38266
+ }
38267
+
37250
38268
  /**
37251
38269
  * Framework-agnostic rendering & editing helpers shared by the React, Vue, and
37252
38270
  * Angular `pptx-viewer` bindings. Pure TypeScript (no framework imports) — each
@@ -42585,6 +43603,192 @@ const translationsEn = {
42585
43603
  'pptx.connectorArrows.endLength': 'End Length',
42586
43604
  'pptx.slideThumbnail.transitionTooltip': 'Transition: {{name}}',
42587
43605
  'pptx.ribbon.groupShapeStyles': 'Shape Styles',
43606
+ 'pptx.options.title': 'Options',
43607
+ 'pptx.options.resetAll': 'Reset all options',
43608
+ 'pptx.options.resetTab': 'Reset this tab',
43609
+ 'pptx.options.general.description': 'General options for working with the viewer.',
43610
+ 'pptx.options.general.userInterface': 'User Interface options',
43611
+ 'pptx.options.general.displayOptimization': 'When using multiple displays',
43612
+ 'pptx.options.displayOptimization.appearance': 'Optimize for best appearance',
43613
+ 'pptx.options.displayOptimization.compatibility': 'Optimize for compatibility',
43614
+ 'pptx.options.general.showMiniToolbar': 'Show Mini Toolbar on selection',
43615
+ 'pptx.options.general.showMiniToolbarInfo': 'Shows the floating formatting toolbar when you select text.',
43616
+ 'pptx.options.general.enableLivePreview': 'Enable Live Preview',
43617
+ 'pptx.options.general.enableLivePreviewInfo': 'Previews formatting changes on the slide as you hover over gallery choices.',
43618
+ 'pptx.options.general.collapseRibbon': 'Collapse the ribbon automatically',
43619
+ 'pptx.options.general.collapseSearch': 'Collapse the search box by default',
43620
+ 'pptx.options.general.screenTipStyle': 'ScreenTip style',
43621
+ 'pptx.options.screenTipStyle.descriptions': 'Show feature descriptions in ScreenTips',
43622
+ 'pptx.options.screenTipStyle.plain': "Don't show feature descriptions in ScreenTips",
43623
+ 'pptx.options.screenTipStyle.off': "Don't show ScreenTips",
43624
+ 'pptx.options.general.personalize': 'Personalize your copy of the viewer',
43625
+ 'pptx.options.general.userName': 'User name',
43626
+ 'pptx.options.general.userInitials': 'Initials',
43627
+ 'pptx.options.general.appearance': 'Viewer theme',
43628
+ 'pptx.options.general.startup': 'Start up options',
43629
+ 'pptx.options.general.showStartScreen': 'Show the Start screen when this application starts',
43630
+ 'pptx.options.proofing.label': 'Proofing',
43631
+ 'pptx.options.proofing.description': 'Change how the viewer corrects and formats your text.',
43632
+ 'pptx.options.proofing.autoCorrect': 'AutoCorrect options',
43633
+ 'pptx.options.proofing.autoCorrectDescription': 'Change how text is corrected and formatted as you type.',
43634
+ 'pptx.options.proofing.twoInitialCapitals': 'Correct TWo INitial CApitals',
43635
+ 'pptx.options.proofing.capitalizeFirstLetter': 'Capitalize first letter of sentences',
43636
+ 'pptx.options.proofing.capitalizeDayNames': 'Capitalize names of days',
43637
+ 'pptx.options.proofing.smartQuotes': 'Replace straight quotes with smart quotes',
43638
+ 'pptx.options.proofing.hyphensToDash': 'Replace hyphens (--) with dash',
43639
+ 'pptx.options.proofing.fractions': 'Replace fractions (1/2) with fraction characters (½)',
43640
+ 'pptx.options.proofing.ordinals': 'Replace ordinals (1st) with superscript',
43641
+ 'pptx.options.proofing.spellingOffice': 'When correcting spelling',
43642
+ 'pptx.options.proofing.ignoreUppercase': 'Ignore words in UPPERCASE',
43643
+ 'pptx.options.proofing.ignoreWordsWithNumbers': 'Ignore words that contain numbers',
43644
+ 'pptx.options.proofing.ignoreInternetAddresses': 'Ignore Internet and file addresses',
43645
+ 'pptx.options.proofing.flagRepeatedWords': 'Flag repeated words',
43646
+ 'pptx.options.proofing.spellingViewer': 'When correcting spelling in the viewer',
43647
+ 'pptx.options.proofing.checkSpellingAsYouType': 'Check spelling as you type',
43648
+ 'pptx.options.proofing.hideSpellingErrors': 'Hide spelling errors',
43649
+ 'pptx.options.save.label': 'Save',
43650
+ 'pptx.options.save.description': 'Customize how documents are saved.',
43651
+ 'pptx.options.save.savePresentations': 'Save presentations',
43652
+ 'pptx.options.save.autoSave': 'Save changes automatically (AutoSave)',
43653
+ 'pptx.options.save.autoSaveInfo': 'Snapshots are stored locally and offered for recovery when you reopen.',
43654
+ 'pptx.options.save.defaultFormat': 'Save files in this format',
43655
+ 'pptx.options.saveFormat.pptx': 'PowerPoint Presentation (*.pptx)',
43656
+ 'pptx.options.saveFormat.pdf': 'PDF Document (*.pdf)',
43657
+ 'pptx.options.saveFormat.png': 'PNG Images (*.png)',
43658
+ 'pptx.options.save.autoRecoverInterval': 'Save AutoRecover information every',
43659
+ 'pptx.options.save.minutes': 'minutes',
43660
+ 'pptx.options.save.keepLastAutoRecovered': 'Keep the last AutoRecovered version if I close without saving',
43661
+ 'pptx.options.save.fidelity': 'Preserve fidelity when sharing this presentation',
43662
+ 'pptx.options.save.embedFonts': 'Embed fonts in the file',
43663
+ 'pptx.options.save.embedFontsInfo': 'Embedding fonts increases file size but keeps text identical on other devices.',
43664
+ 'pptx.options.save.embedAllCharacters': 'Embed all characters (best for editing by other people)',
43665
+ 'pptx.options.save.cache': 'Cache Settings',
43666
+ 'pptx.options.save.cacheRetentionDays': 'Days to keep files in the local document cache',
43667
+ 'pptx.options.save.days': 'days',
43668
+ 'pptx.options.save.clearCacheOnClose': 'Delete files from the local document cache when they are closed',
43669
+ 'pptx.options.save.clearCacheNow': 'Delete cached files',
43670
+ 'pptx.options.save.clearCacheDescription': 'Deletes locally stored recovery snapshots and recent files. This does not affect the open presentation.',
43671
+ 'pptx.options.language.description': 'Set the viewer language preferences.',
43672
+ 'pptx.options.language.displayLanguage': 'Display language',
43673
+ 'pptx.options.language.displayLanguageDescription': 'Buttons, menus, and other controls will show in the selected language.',
43674
+ 'pptx.options.accessibility.label': 'Accessibility',
43675
+ 'pptx.options.accessibility.description': 'Make the viewer more accessible.',
43676
+ 'pptx.options.accessibility.assistant': 'Make your document accessible to others',
43677
+ 'pptx.options.accessibility.showStatus': 'Show accessibility status in the status bar',
43678
+ 'pptx.options.accessibility.feedback': 'Feedback options',
43679
+ 'pptx.options.accessibility.feedbackWithSound': 'Provide feedback with sound',
43680
+ 'pptx.options.accessibility.soundScheme': 'Sound Scheme',
43681
+ 'pptx.options.soundScheme.modern': 'Modern',
43682
+ 'pptx.options.soundScheme.classic': 'Classic',
43683
+ 'pptx.options.accessibility.display': 'Application display options',
43684
+ 'pptx.options.accessibility.showShortcutKeys': 'Show shortcut keys in ScreenTips',
43685
+ 'pptx.options.advanced.label': 'Advanced',
43686
+ 'pptx.options.advanced.description': 'Advanced options for working with the viewer.',
43687
+ 'pptx.options.advanced.editing': 'Editing options',
43688
+ 'pptx.options.advanced.autoSelectWord': 'When selecting, automatically select entire word',
43689
+ 'pptx.options.advanced.textDragAndDrop': 'Allow text to be dragged and dropped',
43690
+ 'pptx.options.advanced.maximumUndoSteps': 'Maximum number of undos',
43691
+ 'pptx.options.advanced.cutCopyPaste': 'Cut, copy, and paste',
43692
+ 'pptx.options.advanced.smartCutAndPaste': 'Use smart cut and paste',
43693
+ 'pptx.options.advanced.showPasteOptions': 'Show Paste Options button when content is pasted',
43694
+ 'pptx.options.advanced.imageQuality': 'Image Size and Quality',
43695
+ 'pptx.options.advanced.doNotCompressImages': 'Do not compress images in file',
43696
+ 'pptx.options.advanced.defaultResolution': 'Default resolution',
43697
+ 'pptx.options.resolution.highFidelity': 'High fidelity',
43698
+ 'pptx.options.resolution.ppi330': '330 ppi',
43699
+ 'pptx.options.resolution.ppi220': '220 ppi',
43700
+ 'pptx.options.resolution.ppi150': '150 ppi',
43701
+ 'pptx.options.resolution.ppi96': '96 ppi',
43702
+ 'pptx.options.advanced.chart': 'Chart',
43703
+ 'pptx.options.advanced.chartFollowDataPoint': 'Properties follow chart data point',
43704
+ 'pptx.options.advanced.display': 'Display',
43705
+ 'pptx.options.advanced.recentCount': 'Show this number of Recent Presentations',
43706
+ 'pptx.options.advanced.disableHardwareAcceleration': 'Disable hardware graphics acceleration',
43707
+ 'pptx.options.advanced.openDocumentsView': 'Open all documents using this view',
43708
+ 'pptx.options.openView.savedView': 'The view saved in the file',
43709
+ 'pptx.options.openView.normal': 'Normal',
43710
+ 'pptx.options.openView.outline': 'Outline',
43711
+ 'pptx.options.openView.slideSorter': 'Slide Sorter',
43712
+ 'pptx.options.openView.notes': 'Notes',
43713
+ 'pptx.options.advanced.slideShow': 'Slide Show',
43714
+ 'pptx.options.advanced.showMenuOnRightClick': 'Show menu on right mouse click',
43715
+ 'pptx.options.advanced.showPopupToolbar': 'Show popup toolbar',
43716
+ 'pptx.options.advanced.promptKeepInk': 'Prompt to keep ink annotations when exiting',
43717
+ 'pptx.options.advanced.endWithBlackSlide': 'End with black slide',
43718
+ 'pptx.options.advanced.print': 'Print',
43719
+ 'pptx.options.advanced.printInBackground': 'Print in background',
43720
+ 'pptx.options.advanced.printHighQuality': 'High quality',
43721
+ 'pptx.options.advanced.printUseMostRecent': 'Use the most recently used print settings',
43722
+ 'pptx.options.advanced.printWhat': 'Print what',
43723
+ 'pptx.options.printWhat.slides': 'Full Page Slides',
43724
+ 'pptx.options.printWhat.handouts': 'Handouts',
43725
+ 'pptx.options.printWhat.notes': 'Notes Pages',
43726
+ 'pptx.options.printWhat.outline': 'Outline',
43727
+ 'pptx.options.advanced.printColorMode': 'Color/grayscale',
43728
+ 'pptx.options.printColorMode.color': 'Color',
43729
+ 'pptx.options.printColorMode.grayscale': 'Grayscale',
43730
+ 'pptx.options.printColorMode.blackAndWhite': 'Pure Black and White',
43731
+ 'pptx.options.advanced.printHiddenSlides': 'Print hidden slides',
43732
+ 'pptx.options.advanced.printScaleToFit': 'Scale to fit paper',
43733
+ 'pptx.options.advanced.printFrameSlides': 'Frame slides',
43734
+ 'pptx.options.ribbon.label': 'Customize Ribbon',
43735
+ 'pptx.options.ribbon.description': 'Customize the ribbon.',
43736
+ 'pptx.options.ribbon.tabsTitle': 'Main Tabs',
43737
+ 'pptx.options.ribbon.tabsDescription': 'Untick a tab to hide it from the ribbon. The File tab is always shown.',
43738
+ 'pptx.options.ribbon.reset': 'Reset ribbon customizations',
43739
+ 'pptx.options.quickAccess.label': 'Quick Access Toolbar',
43740
+ 'pptx.options.quickAccess.description': 'Customize the Quick Access Toolbar.',
43741
+ 'pptx.options.quickAccess.optionsTitle': 'Quick Access Toolbar options',
43742
+ 'pptx.options.quickAccess.show': 'Show Quick Access Toolbar',
43743
+ 'pptx.options.quickAccess.position': 'Toolbar Position',
43744
+ 'pptx.options.quickAccessPosition.above': 'Above Ribbon',
43745
+ 'pptx.options.quickAccessPosition.below': 'Below Ribbon',
43746
+ 'pptx.options.quickAccess.showLabels': 'Always show command labels',
43747
+ 'pptx.options.quickAccess.chooseCommands': 'Choose commands',
43748
+ 'pptx.options.quickAccess.currentCommands': 'Customize Quick Access Toolbar',
43749
+ 'pptx.options.quickAccess.add': 'Add',
43750
+ 'pptx.options.quickAccess.remove': 'Remove',
43751
+ 'pptx.options.quickAccess.moveUp': 'Move Up',
43752
+ 'pptx.options.quickAccess.moveDown': 'Move Down',
43753
+ 'pptx.options.quickAccess.reset': 'Reset',
43754
+ 'pptx.options.quickAccess.command.presentFromStart': 'From Beginning',
43755
+ 'pptx.options.quickAccess.command.print': 'Print',
43756
+ 'pptx.options.quickAccess.command.exportPdf': 'Export as PDF',
43757
+ 'pptx.options.quickAccess.command.newSlide': 'New Slide',
43758
+ 'pptx.options.quickAccess.command.zoomIn': 'Zoom In',
43759
+ 'pptx.options.quickAccess.command.zoomOut': 'Zoom Out',
43760
+ 'pptx.options.addIns.label': 'Add-ins',
43761
+ 'pptx.options.addIns.description': 'View and manage viewer capability modules.',
43762
+ 'pptx.options.addIns.name': 'Name',
43763
+ 'pptx.options.addIns.location': 'Location',
43764
+ 'pptx.options.addIns.type': 'Type',
43765
+ 'pptx.options.addIns.active': 'Active Capability Modules',
43766
+ 'pptx.options.addIns.inactive': 'Inactive Capability Modules',
43767
+ 'pptx.options.addInType.renderer': 'Renderer',
43768
+ 'pptx.options.addInType.converter': 'Converter',
43769
+ 'pptx.options.addInType.collaboration': 'Collaboration',
43770
+ 'pptx.options.addInType.localization': 'Localization',
43771
+ 'pptx.options.addIns.smartArt3d': 'SmartArt 3D Renderer',
43772
+ 'pptx.options.addIns.smartArt3dDescription': 'Opt-in three.js renderer for extruded and spatial SmartArt layouts.',
43773
+ 'pptx.options.addIns.model3d': '3D Model Renderer',
43774
+ 'pptx.options.addIns.model3dDescription': 'Interactive GLB/GLTF model rendering on slides.',
43775
+ 'pptx.options.addIns.emfConverter': 'EMF/WMF Converter',
43776
+ 'pptx.options.addIns.emfConverterDescription': 'Converts EMF and WMF metafile images to PNG for display.',
43777
+ 'pptx.options.addIns.mtxDecompressor': 'MicroType Express Font Decompressor',
43778
+ 'pptx.options.addIns.mtxDecompressorDescription': 'Decompresses embedded MicroType Express fonts.',
43779
+ 'pptx.options.addIns.collaboration': 'Real-time Collaboration',
43780
+ 'pptx.options.addIns.collaborationDescription': 'CRDT-based co-editing, presence, and sync relay support.',
43781
+ 'pptx.options.addIns.locales': 'Locale Packs',
43782
+ 'pptx.options.addIns.localesDescription': 'Additional display languages for the viewer chrome.',
43783
+ 'pptx.options.trust.label': 'Trust Center',
43784
+ 'pptx.options.trust.description': 'Help keep your documents safe and secure.',
43785
+ 'pptx.options.trust.settingsTitle': 'Security settings',
43786
+ 'pptx.options.trust.settingsDescription': 'These settings help keep the content you open safe. We recommend the defaults.',
43787
+ 'pptx.options.trust.protectedView': 'Open presentations in Protected View',
43788
+ 'pptx.options.trust.protectedViewInfo': 'Documents open read-only; use Enable Editing to make changes.',
43789
+ 'pptx.options.trust.allowExternalContent': 'Allow external content (remote images and media)',
43790
+ 'pptx.options.trust.allowExternalContentInfo': 'When off, only content embedded in the file is displayed.',
43791
+ 'pptx.options.trust.confirmHyperlinks': 'Confirm before opening external hyperlinks',
42588
43792
  };
42589
43793
  /**
42590
43794
  * Convert a dotted translation key to a human-readable label when no
@@ -64614,6 +65818,134 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
64614
65818
  type: Injectable
64615
65819
  }] });
64616
65820
 
65821
+ /**
65822
+ * viewer-options.service.ts: signal-based owner of the File > Options store for
65823
+ * one viewer instance (the Angular counterpart of React's `useViewerOptions`).
65824
+ *
65825
+ * Wraps the framework-neutral {@link createViewerOptionsStore} (which persists a
65826
+ * sparse diff into the shared `pptx-viewer-prefs` localStorage entry) behind an
65827
+ * Angular signal, and bundles the option-to-behavior helpers the rest of the
65828
+ * viewer consumes: history depth, autosave cadence, print defaults, screen
65829
+ * tips, root classes, AutoCorrect, feedback sounds, hyperlink confirmation,
65830
+ * protected view, and the Options > Save cache purge.
65831
+ *
65832
+ * Deliberately constructible with plain `new` (no required injection context)
65833
+ * so the colocated unit tests can exercise it without TestBed, matching
65834
+ * {@link EditorStateService}'s optional-inject pattern.
65835
+ */
65836
+ class ViewerOptionsService {
65837
+ /**
65838
+ * Optional: `inject()` needs an active injection context, which plain
65839
+ * `new ViewerOptionsService()` (used by the colocated unit tests) does not
65840
+ * provide. Outside DI the subscription simply lives as long as the instance.
65841
+ */
65842
+ destroyRef = (() => {
65843
+ try {
65844
+ return inject(DestroyRef);
65845
+ }
65846
+ catch {
65847
+ return null;
65848
+ }
65849
+ })();
65850
+ translate = (() => {
65851
+ try {
65852
+ return inject(TranslateService);
65853
+ }
65854
+ catch {
65855
+ return null;
65856
+ }
65857
+ })();
65858
+ /** Imperative store: hydrates from and persists to `pptx-viewer-prefs`. */
65859
+ store = createViewerOptionsStore();
65860
+ _options = signal(this.store.getOptions(), /* @ts-ignore */
65861
+ ...(ngDevMode ? [{ debugName: "_options" }] : /* istanbul ignore next */ []));
65862
+ /** Reactive File > Options snapshot; a new object per change. */
65863
+ options = this._options.asReadonly();
65864
+ constructor() {
65865
+ const unsubscribe = this.store.subscribe((next) => this._options.set(next));
65866
+ this.destroyRef?.onDestroy(unsubscribe);
65867
+ }
65868
+ // ── Store mutations ─────────────────────────────────────────────────────
65869
+ setValue(group, key, value) {
65870
+ this.store.setValue(group, key, value);
65871
+ }
65872
+ setRibbonTabHidden(tabId, hidden) {
65873
+ this.store.setRibbonTabHidden(tabId, hidden);
65874
+ }
65875
+ setQuickAccessCommands(commandIds) {
65876
+ this.store.setQuickAccessCommands(commandIds);
65877
+ }
65878
+ reset(group) {
65879
+ this.store.reset(group);
65880
+ }
65881
+ /** Restore a snapshot wholesale (the dialog's Cancel semantics). */
65882
+ restore(snapshot) {
65883
+ this.store.setOptions(snapshot);
65884
+ }
65885
+ // ── Behavior resolution helpers ─────────────────────────────────────────
65886
+ /** Undo-stack depth for `new EditorHistory({ maxDepth })`. */
65887
+ historyDepth() {
65888
+ return resolveHistoryDepth(this.options());
65889
+ }
65890
+ /** AutoRecover cadence in seconds for the autosave engine. */
65891
+ autosaveIntervalSeconds() {
65892
+ return resolveAutosaveIntervalSeconds(this.options());
65893
+ }
65894
+ /** Print-dialog seed; `undefined` keeps the dialog's own recents. */
65895
+ printDefaults() {
65896
+ return resolveDefaultPrintSettings(this.options());
65897
+ }
65898
+ /** Option-driven CSS classes for the viewer root (`pptx-ng-*` prefixed). */
65899
+ rootClasses() {
65900
+ return resolveOptionRootClasses(this.options(), 'pptx-ng');
65901
+ }
65902
+ /** Tooltip text under the current ScreenTip style (undefined = suppress). */
65903
+ screenTip(label, description, shortcut) {
65904
+ return resolveScreenTip(this.options(), label, description, shortcut);
65905
+ }
65906
+ /** Run the enabled AutoCorrect rules over a committed run of text. */
65907
+ autoCorrect(text) {
65908
+ return applyAutoCorrect(text, this.options().proofing);
65909
+ }
65910
+ /** Play the Accessibility "feedback with sound" cue for a completed action. */
65911
+ playFeedback() {
65912
+ playFeedbackSound(this.options());
65913
+ }
65914
+ /** Whether Trust Center forces the deck to open read-only. */
65915
+ protectedView() {
65916
+ return shouldOpenInProtectedView(this.options());
65917
+ }
65918
+ /**
65919
+ * Gate an external hyperlink activation. Returns `true` when navigation may
65920
+ * proceed (no confirmation required, or the user confirmed the prompt).
65921
+ */
65922
+ confirmExternalHyperlink(href) {
65923
+ if (!shouldConfirmExternalHyperlink(this.options(), href)) {
65924
+ return true;
65925
+ }
65926
+ if (typeof window === 'undefined' || typeof window.confirm !== 'function') {
65927
+ return true;
65928
+ }
65929
+ const label = this.translate?.instant('pptx.options.trust.confirmHyperlinks') ??
65930
+ 'Confirm before opening external hyperlinks';
65931
+ return window.confirm(`${label}\n\n${href}`);
65932
+ }
65933
+ /**
65934
+ * Options > Save > "Delete cached files": purge every autosave recovery
65935
+ * snapshot from the shared IndexedDB store. Resolves with the purge count.
65936
+ */
65937
+ async clearCache() {
65938
+ const snapshots = await listAutosaveSnapshots();
65939
+ await Promise.all(snapshots.map((entry) => deleteAutosaveSnapshot(entry.key)));
65940
+ return snapshots.length;
65941
+ }
65942
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ViewerOptionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
65943
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ViewerOptionsService });
65944
+ }
65945
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ViewerOptionsService, decorators: [{
65946
+ type: Injectable
65947
+ }], ctorParameters: () => [] });
65948
+
64617
65949
  /**
64618
65950
  * audience-content-store: IndexedDB-based storage for sharing PPTX content
64619
65951
  * between the presenter tab and audience tab.
@@ -65526,6 +66858,7 @@ const POWER_POINT_VIEWER_PROVIDERS = [
65526
66858
  ViewerInspectorPanelService,
65527
66859
  ViewerKeyboardService,
65528
66860
  ViewerMobileSheetService,
66861
+ ViewerOptionsService,
65529
66862
  ViewerPresentationModeService,
65530
66863
  ViewerThemeGalleryService,
65531
66864
  ViewerTouchGesturesService,
@@ -72537,7 +73870,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
72537
73870
  }], propDecorators: { canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }] } });
72538
73871
 
72539
73872
  // Generated by scripts/inline-shared.mjs from package.json. Do not edit.
72540
- const PPTX_ANGULAR_VIEWER_VERSION = "1.30.0";
73873
+ const PPTX_ANGULAR_VIEWER_VERSION = "1.30.1";
72541
73874
 
72542
73875
  /**
72543
73876
  * account-page.component.ts: File > Account content.
@@ -91050,10 +92383,15 @@ class TitleBarComponent {
91050
92383
  /** Toolbar buttons the host wants hidden (gates Undo/Redo independently). */
91051
92384
  hiddenActions = input([], /* @ts-ignore */
91052
92385
  ...(ngDevMode ? [{ debugName: "hiddenActions" }] : /* istanbul ignore next */ []));
92386
+ /** Live Quick Access Toolbar options (File > Options > Quick Access). */
92387
+ quickAccess = input(null, /* @ts-ignore */
92388
+ ...(ngDevMode ? [{ debugName: "quickAccess" }] : /* istanbul ignore next */ []));
91053
92389
  toggleAutosave = output();
91054
92390
  save = output();
91055
92391
  undo = output();
91056
92392
  redo = output();
92393
+ /** A configured Quick Access command was pressed (catalog id). */
92394
+ quickCommand = output();
91057
92395
  toggleFindReplace = output();
91058
92396
  commandSearch = output();
91059
92397
  translate = inject(TranslateService);
@@ -91064,6 +92402,41 @@ class TitleBarComponent {
91064
92402
  ...(ngDevMode ? [{ debugName: "searchQuery" }] : /* istanbul ignore next */ []));
91065
92403
  searchFocused = signal(false, /* @ts-ignore */
91066
92404
  ...(ngDevMode ? [{ debugName: "searchFocused" }] : /* istanbul ignore next */ []));
92405
+ /** Resolved Quick Access options (host-supplied, or the default trio+). */
92406
+ qat = computed(() => this.quickAccess() ?? DEFAULT_VIEWER_OPTIONS.quickAccess, /* @ts-ignore */
92407
+ ...(ngDevMode ? [{ debugName: "qat" }] : /* istanbul ignore next */ []));
92408
+ /**
92409
+ * Configured Quick Access commands beyond the dedicated save/undo/redo
92410
+ * buttons (which keep their own gating + labels). Rendered as text-label
92411
+ * buttons routed through {@link onQuickCommand}.
92412
+ */
92413
+ extraQuickCommands = computed(() => {
92414
+ const dedicated = new Set(['save', 'undo', 'redo']);
92415
+ return this.qat()
92416
+ .commandIds.filter((id) => !dedicated.has(id))
92417
+ .map((id) => QUICK_ACCESS_COMMAND_CATALOG.find((entry) => entry.id === id))
92418
+ .filter((entry) => entry !== undefined);
92419
+ }, /* @ts-ignore */
92420
+ ...(ngDevMode ? [{ debugName: "extraQuickCommands" }] : /* istanbul ignore next */ []));
92421
+ /**
92422
+ * Route a Quick Access press: keep the dedicated save/undo/redo outputs
92423
+ * (existing host wiring, `hiddenActions` gating) and forward everything
92424
+ * else through the generic {@link quickCommand} output.
92425
+ */
92426
+ onQuickCommand(id) {
92427
+ if (id === 'save') {
92428
+ this.save.emit();
92429
+ }
92430
+ else if (id === 'undo' && !this.toolbar.isHidden('undo')) {
92431
+ this.undo.emit();
92432
+ }
92433
+ else if (id === 'redo' && !this.toolbar.isHidden('redo')) {
92434
+ this.redo.emit();
92435
+ }
92436
+ else if (id !== 'undo' && id !== 'redo') {
92437
+ this.quickCommand.emit(id);
92438
+ }
92439
+ }
91067
92440
  commandResults = computed(() => filterCommands(this.searchQuery(), (key) => this.translate.instant(key)), /* @ts-ignore */
91068
92441
  ...(ngDevMode ? [{ debugName: "commandResults" }] : /* istanbul ignore next */ []));
91069
92442
  /** The i18n key for the save-location status text (next to the file name). */
@@ -91122,7 +92495,7 @@ class TitleBarComponent {
91122
92495
  }
91123
92496
  }
91124
92497
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: TitleBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
91125
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: TitleBarComponent, isStandalone: true, selector: "pptx-title-bar", inputs: { canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, isDirty: { classPropertyName: "isDirty", publicName: "isDirty", isSignal: true, isRequired: false, transformFunction: null }, autosaveStatus: { classPropertyName: "autosaveStatus", publicName: "autosaveStatus", isSignal: true, isRequired: false, transformFunction: null }, autosaveEnabled: { classPropertyName: "autosaveEnabled", publicName: "autosaveEnabled", isSignal: true, isRequired: false, transformFunction: null }, canUndo: { classPropertyName: "canUndo", publicName: "canUndo", isSignal: true, isRequired: false, transformFunction: null }, canRedo: { classPropertyName: "canRedo", publicName: "canRedo", isSignal: true, isRequired: false, transformFunction: null }, undoLabel: { classPropertyName: "undoLabel", publicName: "undoLabel", isSignal: true, isRequired: false, transformFunction: null }, redoLabel: { classPropertyName: "redoLabel", publicName: "redoLabel", isSignal: true, isRequired: false, transformFunction: null }, findReplaceOpen: { classPropertyName: "findReplaceOpen", publicName: "findReplaceOpen", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggleAutosave: "toggleAutosave", save: "save", undo: "undo", redo: "redo", toggleFindReplace: "toggleFindReplace", commandSearch: "commandSearch" }, ngImport: i0, template: `
92498
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: TitleBarComponent, isStandalone: true, selector: "pptx-title-bar", inputs: { canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, isDirty: { classPropertyName: "isDirty", publicName: "isDirty", isSignal: true, isRequired: false, transformFunction: null }, autosaveStatus: { classPropertyName: "autosaveStatus", publicName: "autosaveStatus", isSignal: true, isRequired: false, transformFunction: null }, autosaveEnabled: { classPropertyName: "autosaveEnabled", publicName: "autosaveEnabled", isSignal: true, isRequired: false, transformFunction: null }, canUndo: { classPropertyName: "canUndo", publicName: "canUndo", isSignal: true, isRequired: false, transformFunction: null }, canRedo: { classPropertyName: "canRedo", publicName: "canRedo", isSignal: true, isRequired: false, transformFunction: null }, undoLabel: { classPropertyName: "undoLabel", publicName: "undoLabel", isSignal: true, isRequired: false, transformFunction: null }, redoLabel: { classPropertyName: "redoLabel", publicName: "redoLabel", isSignal: true, isRequired: false, transformFunction: null }, findReplaceOpen: { classPropertyName: "findReplaceOpen", publicName: "findReplaceOpen", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, quickAccess: { classPropertyName: "quickAccess", publicName: "quickAccess", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggleAutosave: "toggleAutosave", save: "save", undo: "undo", redo: "redo", quickCommand: "quickCommand", toggleFindReplace: "toggleFindReplace", commandSearch: "commandSearch" }, ngImport: i0, template: `
91126
92499
  <div [class]="tb.container" data-pptx-title-bar>
91127
92500
  <span [class]="tb.logo" aria-hidden="true">P</span>
91128
92501
 
@@ -91152,46 +92525,65 @@ class TitleBarComponent {
91152
92525
 
91153
92526
  <div [class]="tb.separator"></div>
91154
92527
 
91155
- <button
91156
- type="button"
91157
- [class]="tb.quickButton"
91158
- [title]="'pptx.titleBar.save' | translate"
91159
- [attr.aria-label]="'pptx.titleBar.save' | translate"
91160
- (click)="save.emit()"
91161
- >
91162
- <svg lucideSave class="h-3.5 w-3.5"></svg>
91163
- </button>
91164
- @if (!toolbar.isHidden('undo')) {
91165
- <button
91166
- type="button"
91167
- [class]="tb.quickButton"
91168
- [disabled]="!canUndo()"
91169
- [title]="
91170
- undoLabel()
91171
- ? ('pptx.toolbar.undoAction' | translate: { action: undoLabel() })
91172
- : ('pptx.toolbar.undo' | translate)
91173
- "
91174
- [attr.aria-label]="'pptx.toolbar.undo' | translate"
91175
- (click)="undo.emit()"
91176
- >
91177
- <svg lucideUndo class="h-3.5 w-3.5"></svg>
91178
- </button>
91179
- }
91180
- @if (!toolbar.isHidden('redo')) {
92528
+ @if (qat().visible) {
91181
92529
  <button
91182
92530
  type="button"
91183
92531
  [class]="tb.quickButton"
91184
- [disabled]="!canRedo()"
91185
- [title]="
91186
- redoLabel()
91187
- ? ('pptx.toolbar.redoAction' | translate: { action: redoLabel() })
91188
- : ('pptx.toolbar.redo' | translate)
91189
- "
91190
- [attr.aria-label]="'pptx.toolbar.redo' | translate"
91191
- (click)="redo.emit()"
92532
+ [title]="'pptx.titleBar.save' | translate"
92533
+ [attr.aria-label]="'pptx.titleBar.save' | translate"
92534
+ (click)="save.emit()"
91192
92535
  >
91193
- <svg lucideRedo class="h-3.5 w-3.5"></svg>
92536
+ <svg lucideSave class="h-3.5 w-3.5"></svg>
91194
92537
  </button>
92538
+ @if (!toolbar.isHidden('undo')) {
92539
+ <button
92540
+ type="button"
92541
+ [class]="tb.quickButton"
92542
+ [disabled]="!canUndo()"
92543
+ [title]="
92544
+ undoLabel()
92545
+ ? ('pptx.toolbar.undoAction' | translate: { action: undoLabel() })
92546
+ : ('pptx.toolbar.undo' | translate)
92547
+ "
92548
+ [attr.aria-label]="'pptx.toolbar.undo' | translate"
92549
+ (click)="undo.emit()"
92550
+ >
92551
+ <svg lucideUndo class="h-3.5 w-3.5"></svg>
92552
+ </button>
92553
+ }
92554
+ @if (!toolbar.isHidden('redo')) {
92555
+ <button
92556
+ type="button"
92557
+ [class]="tb.quickButton"
92558
+ [disabled]="!canRedo()"
92559
+ [title]="
92560
+ redoLabel()
92561
+ ? ('pptx.toolbar.redoAction' | translate: { action: redoLabel() })
92562
+ : ('pptx.toolbar.redo' | translate)
92563
+ "
92564
+ [attr.aria-label]="'pptx.toolbar.redo' | translate"
92565
+ (click)="redo.emit()"
92566
+ >
92567
+ <svg lucideRedo class="h-3.5 w-3.5"></svg>
92568
+ </button>
92569
+ }
92570
+ @for (cmd of extraQuickCommands(); track cmd.id) {
92571
+ <button
92572
+ type="button"
92573
+ [class]="tb.quickButton"
92574
+ [title]="cmd.labelKey | translate"
92575
+ [attr.aria-label]="cmd.labelKey | translate"
92576
+ (click)="onQuickCommand(cmd.id)"
92577
+ >
92578
+ @if (qat().showCommandLabels) {
92579
+ <span class="text-[11px]">{{ cmd.labelKey | translate }}</span>
92580
+ } @else {
92581
+ <span class="text-[11px] font-semibold" aria-hidden="true">{{
92582
+ (cmd.labelKey | translate).charAt(0)
92583
+ }}</span>
92584
+ }
92585
+ </button>
92586
+ }
91195
92587
  }
91196
92588
 
91197
92589
  <div [class]="tb.separator"></div>
@@ -91319,46 +92711,65 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
91319
92711
 
91320
92712
  <div [class]="tb.separator"></div>
91321
92713
 
91322
- <button
91323
- type="button"
91324
- [class]="tb.quickButton"
91325
- [title]="'pptx.titleBar.save' | translate"
91326
- [attr.aria-label]="'pptx.titleBar.save' | translate"
91327
- (click)="save.emit()"
91328
- >
91329
- <svg lucideSave class="h-3.5 w-3.5"></svg>
91330
- </button>
91331
- @if (!toolbar.isHidden('undo')) {
91332
- <button
91333
- type="button"
91334
- [class]="tb.quickButton"
91335
- [disabled]="!canUndo()"
91336
- [title]="
91337
- undoLabel()
91338
- ? ('pptx.toolbar.undoAction' | translate: { action: undoLabel() })
91339
- : ('pptx.toolbar.undo' | translate)
91340
- "
91341
- [attr.aria-label]="'pptx.toolbar.undo' | translate"
91342
- (click)="undo.emit()"
91343
- >
91344
- <svg lucideUndo class="h-3.5 w-3.5"></svg>
91345
- </button>
91346
- }
91347
- @if (!toolbar.isHidden('redo')) {
92714
+ @if (qat().visible) {
91348
92715
  <button
91349
92716
  type="button"
91350
92717
  [class]="tb.quickButton"
91351
- [disabled]="!canRedo()"
91352
- [title]="
91353
- redoLabel()
91354
- ? ('pptx.toolbar.redoAction' | translate: { action: redoLabel() })
91355
- : ('pptx.toolbar.redo' | translate)
91356
- "
91357
- [attr.aria-label]="'pptx.toolbar.redo' | translate"
91358
- (click)="redo.emit()"
92718
+ [title]="'pptx.titleBar.save' | translate"
92719
+ [attr.aria-label]="'pptx.titleBar.save' | translate"
92720
+ (click)="save.emit()"
91359
92721
  >
91360
- <svg lucideRedo class="h-3.5 w-3.5"></svg>
92722
+ <svg lucideSave class="h-3.5 w-3.5"></svg>
91361
92723
  </button>
92724
+ @if (!toolbar.isHidden('undo')) {
92725
+ <button
92726
+ type="button"
92727
+ [class]="tb.quickButton"
92728
+ [disabled]="!canUndo()"
92729
+ [title]="
92730
+ undoLabel()
92731
+ ? ('pptx.toolbar.undoAction' | translate: { action: undoLabel() })
92732
+ : ('pptx.toolbar.undo' | translate)
92733
+ "
92734
+ [attr.aria-label]="'pptx.toolbar.undo' | translate"
92735
+ (click)="undo.emit()"
92736
+ >
92737
+ <svg lucideUndo class="h-3.5 w-3.5"></svg>
92738
+ </button>
92739
+ }
92740
+ @if (!toolbar.isHidden('redo')) {
92741
+ <button
92742
+ type="button"
92743
+ [class]="tb.quickButton"
92744
+ [disabled]="!canRedo()"
92745
+ [title]="
92746
+ redoLabel()
92747
+ ? ('pptx.toolbar.redoAction' | translate: { action: redoLabel() })
92748
+ : ('pptx.toolbar.redo' | translate)
92749
+ "
92750
+ [attr.aria-label]="'pptx.toolbar.redo' | translate"
92751
+ (click)="redo.emit()"
92752
+ >
92753
+ <svg lucideRedo class="h-3.5 w-3.5"></svg>
92754
+ </button>
92755
+ }
92756
+ @for (cmd of extraQuickCommands(); track cmd.id) {
92757
+ <button
92758
+ type="button"
92759
+ [class]="tb.quickButton"
92760
+ [title]="cmd.labelKey | translate"
92761
+ [attr.aria-label]="cmd.labelKey | translate"
92762
+ (click)="onQuickCommand(cmd.id)"
92763
+ >
92764
+ @if (qat().showCommandLabels) {
92765
+ <span class="text-[11px]">{{ cmd.labelKey | translate }}</span>
92766
+ } @else {
92767
+ <span class="text-[11px] font-semibold" aria-hidden="true">{{
92768
+ (cmd.labelKey | translate).charAt(0)
92769
+ }}</span>
92770
+ }
92771
+ </button>
92772
+ }
91362
92773
  }
91363
92774
 
91364
92775
  <div [class]="tb.separator"></div>
@@ -91449,7 +92860,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
91449
92860
  </div>
91450
92861
  `,
91451
92862
  }]
91452
- }], propDecorators: { canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], isDirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDirty", required: false }] }], autosaveStatus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autosaveStatus", required: false }] }], autosaveEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "autosaveEnabled", required: false }] }], canUndo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canUndo", required: false }] }], canRedo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canRedo", required: false }] }], undoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "undoLabel", required: false }] }], redoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "redoLabel", required: false }] }], findReplaceOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "findReplaceOpen", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], toggleAutosave: [{ type: i0.Output, args: ["toggleAutosave"] }], save: [{ type: i0.Output, args: ["save"] }], undo: [{ type: i0.Output, args: ["undo"] }], redo: [{ type: i0.Output, args: ["redo"] }], toggleFindReplace: [{ type: i0.Output, args: ["toggleFindReplace"] }], commandSearch: [{ type: i0.Output, args: ["commandSearch"] }] } });
92863
+ }], propDecorators: { canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], isDirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDirty", required: false }] }], autosaveStatus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autosaveStatus", required: false }] }], autosaveEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "autosaveEnabled", required: false }] }], canUndo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canUndo", required: false }] }], canRedo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canRedo", required: false }] }], undoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "undoLabel", required: false }] }], redoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "redoLabel", required: false }] }], findReplaceOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "findReplaceOpen", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], quickAccess: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickAccess", required: false }] }], toggleAutosave: [{ type: i0.Output, args: ["toggleAutosave"] }], save: [{ type: i0.Output, args: ["save"] }], undo: [{ type: i0.Output, args: ["undo"] }], redo: [{ type: i0.Output, args: ["redo"] }], quickCommand: [{ type: i0.Output, args: ["quickCommand"] }], toggleFindReplace: [{ type: i0.Output, args: ["toggleFindReplace"] }], commandSearch: [{ type: i0.Output, args: ["commandSearch"] }] } });
91453
92864
 
91454
92865
  /**
91455
92866
  * slide-diff-helpers.ts: Pure label / icon helpers for the slide-diff row and
@@ -94112,6 +95523,728 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
94112
95523
  `, styles: [".pptx-ng-sss-body{display:flex;flex-direction:column;gap:1.25rem;font-size:.75rem;color:var(--pptx-foreground, #f3f4f6)}.pptx-ng-sss-fieldset{display:flex;flex-direction:column;gap:.375rem;margin:0;padding:0;border:none}.pptx-ng-sss-legend{margin-bottom:.25rem;padding:0;font-size:.6875rem;font-weight:500;text-transform:uppercase;letter-spacing:.03em;color:var(--pptx-muted-foreground, #9ca3af)}.pptx-ng-sss-option{display:flex;align-items:center;gap:.5rem;font-size:.75rem;color:var(--pptx-foreground, #f3f4f6);cursor:pointer}.pptx-ng-sss-radio{accent-color:var(--pptx-primary, #6366f1)}.pptx-ng-sss-btn{padding:.375rem .75rem;border:1px solid var(--pptx-border, #374151);border-radius:.375rem;background:var(--pptx-card, #111827);color:var(--pptx-foreground, #f3f4f6);font-size:.75rem;cursor:pointer;white-space:nowrap;transition:background .15s ease}.pptx-ng-sss-btn:hover{background:var(--pptx-border, #374151)}.pptx-ng-sss-btn-primary{border-color:var(--pptx-primary, #6366f1);background:var(--pptx-primary, #6366f1);color:#fff}.pptx-ng-sss-btn-primary:hover{background:var(--pptx-primary, #6366f1);filter:brightness(1.1)}\n"] }]
94113
95524
  }], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], properties: [{ type: i0.Input, args: [{ isSignal: true, alias: "properties", required: false }] }], customShows: [{ type: i0.Input, args: [{ isSignal: true, alias: "customShows", required: false }] }], slideCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideCount", required: false }] }], save: [{ type: i0.Output, args: ["save"] }], close: [{ type: i0.Output, args: ["close"] }] } });
94114
95525
 
95526
+ /**
95527
+ * options-add-ins-pane.component.ts: Options > Add-ins pane (Angular port of
95528
+ * React's `settings/OptionsAddInsPane.tsx`).
95529
+ *
95530
+ * Presents the viewer's optional capability modules the way PowerPoint lists
95531
+ * COM add-ins: a name/location/type table grouped by active state (from
95532
+ * host-supplied {@link ViewerAddinStatus} flags; unset ids default to active),
95533
+ * with a detail card for the selected row.
95534
+ */
95535
+ class OptionsAddInsPaneComponent {
95536
+ /** Host-supplied availability flags; unset ids default to active. */
95537
+ addinStatus = input(undefined, /* @ts-ignore */
95538
+ ...(ngDevMode ? [{ debugName: "addinStatus" }] : /* istanbul ignore next */ []));
95539
+ selectedId = signal(null, /* @ts-ignore */
95540
+ ...(ngDevMode ? [{ debugName: "selectedId" }] : /* istanbul ignore next */ []));
95541
+ rows = computed(() => resolveViewerAddinRows(this.addinStatus()), /* @ts-ignore */
95542
+ ...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
95543
+ active = computed(() => this.rows().filter((row) => row.active), /* @ts-ignore */
95544
+ ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
95545
+ inactive = computed(() => this.rows().filter((row) => !row.active), /* @ts-ignore */
95546
+ ...(ngDevMode ? [{ debugName: "inactive" }] : /* istanbul ignore next */ []));
95547
+ selected = computed(() => this.rows().find((row) => row.id === this.selectedId()) ?? null, /* @ts-ignore */
95548
+ ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
95549
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OptionsAddInsPaneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
95550
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: OptionsAddInsPaneComponent, isStandalone: true, selector: "pptx-options-add-ins-pane", inputs: { addinStatus: { classPropertyName: "addinStatus", publicName: "addinStatus", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
95551
+ <div class="pptx-ng-options-addins">
95552
+ <div class="pptx-ng-options-addins-head">
95553
+ <span>{{ 'pptx.options.addIns.name' | translate }}</span>
95554
+ <span>{{ 'pptx.options.addIns.location' | translate }}</span>
95555
+ <span>{{ 'pptx.options.addIns.type' | translate }}</span>
95556
+ </div>
95557
+
95558
+ <section>
95559
+ <h4>{{ 'pptx.options.addIns.active' | translate }}</h4>
95560
+ @for (row of active(); track row.id) {
95561
+ <button
95562
+ type="button"
95563
+ class="pptx-ng-options-addins-row"
95564
+ [class.is-selected]="selectedId() === row.id"
95565
+ (click)="selectedId.set(row.id)"
95566
+ >
95567
+ <span>{{ row.nameKey | translate }}</span>
95568
+ <span class="pptx-ng-options-addins-loc">{{ row.location }}</span>
95569
+ <span>{{ 'pptx.options.addInType.' + row.type | translate }}</span>
95570
+ </button>
95571
+ } @empty {
95572
+ <p class="pptx-ng-options-addins-empty">
95573
+ {{ 'pptx.options.addIns.description' | translate }}
95574
+ </p>
95575
+ }
95576
+ </section>
95577
+
95578
+ <section>
95579
+ <h4>{{ 'pptx.options.addIns.inactive' | translate }}</h4>
95580
+ @for (row of inactive(); track row.id) {
95581
+ <button
95582
+ type="button"
95583
+ class="pptx-ng-options-addins-row"
95584
+ [class.is-selected]="selectedId() === row.id"
95585
+ (click)="selectedId.set(row.id)"
95586
+ >
95587
+ <span>{{ row.nameKey | translate }}</span>
95588
+ <span class="pptx-ng-options-addins-loc">{{ row.location }}</span>
95589
+ <span>{{ 'pptx.options.addInType.' + row.type | translate }}</span>
95590
+ </button>
95591
+ } @empty {
95592
+ <p class="pptx-ng-options-addins-empty">
95593
+ {{ 'pptx.options.addIns.description' | translate }}
95594
+ </p>
95595
+ }
95596
+ </section>
95597
+
95598
+ @if (selected(); as row) {
95599
+ <div class="pptx-ng-options-addins-detail">
95600
+ <p class="pptx-ng-options-addins-detail-name">{{ row.nameKey | translate }}</p>
95601
+ <p>{{ row.descriptionKey | translate }}</p>
95602
+ <p class="pptx-ng-options-addins-loc">{{ row.location }}</p>
95603
+ </div>
95604
+ }
95605
+ </div>
95606
+ `, isInline: true, styles: [".pptx-ng-options-addins{display:flex;flex-direction:column;gap:14px}.pptx-ng-options-addins-head,.pptx-ng-options-addins-row{display:grid;grid-template-columns:1.4fr 1fr .7fr;gap:8px;align-items:center}.pptx-ng-options-addins-head{padding:0 8px 4px;border-bottom:1px solid var(--pptx-border);color:var(--pptx-muted-foreground);font-size:10px;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.pptx-ng-options-addins h4{margin:0 0 2px;font-size:12px;font-weight:600}.pptx-ng-options-addins-row{width:100%;padding:6px 8px;border:0;border-bottom:1px solid color-mix(in srgb,var(--pptx-border) 45%,transparent);background:transparent;color:var(--pptx-foreground);font-size:12px;text-align:left;cursor:pointer}.pptx-ng-options-addins-row:hover{background:var(--pptx-accent)}.pptx-ng-options-addins-row.is-selected{background:color-mix(in srgb,var(--pptx-primary) 10%,transparent)}.pptx-ng-options-addins-loc{color:var(--pptx-muted-foreground);font:11px ui-monospace,monospace;overflow-wrap:anywhere}.pptx-ng-options-addins-empty{margin:0;padding:4px 8px;color:var(--pptx-muted-foreground);font-size:11px;font-style:italic}.pptx-ng-options-addins-detail{padding:10px 12px;border:1px solid var(--pptx-border);border-radius:6px;background:var(--pptx-muted);font-size:12px}.pptx-ng-options-addins-detail p{margin:0 0 4px}.pptx-ng-options-addins-detail-name{font-weight:600}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
95607
+ }
95608
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OptionsAddInsPaneComponent, decorators: [{
95609
+ type: Component,
95610
+ args: [{ selector: 'pptx-options-add-ins-pane', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslatePipe], template: `
95611
+ <div class="pptx-ng-options-addins">
95612
+ <div class="pptx-ng-options-addins-head">
95613
+ <span>{{ 'pptx.options.addIns.name' | translate }}</span>
95614
+ <span>{{ 'pptx.options.addIns.location' | translate }}</span>
95615
+ <span>{{ 'pptx.options.addIns.type' | translate }}</span>
95616
+ </div>
95617
+
95618
+ <section>
95619
+ <h4>{{ 'pptx.options.addIns.active' | translate }}</h4>
95620
+ @for (row of active(); track row.id) {
95621
+ <button
95622
+ type="button"
95623
+ class="pptx-ng-options-addins-row"
95624
+ [class.is-selected]="selectedId() === row.id"
95625
+ (click)="selectedId.set(row.id)"
95626
+ >
95627
+ <span>{{ row.nameKey | translate }}</span>
95628
+ <span class="pptx-ng-options-addins-loc">{{ row.location }}</span>
95629
+ <span>{{ 'pptx.options.addInType.' + row.type | translate }}</span>
95630
+ </button>
95631
+ } @empty {
95632
+ <p class="pptx-ng-options-addins-empty">
95633
+ {{ 'pptx.options.addIns.description' | translate }}
95634
+ </p>
95635
+ }
95636
+ </section>
95637
+
95638
+ <section>
95639
+ <h4>{{ 'pptx.options.addIns.inactive' | translate }}</h4>
95640
+ @for (row of inactive(); track row.id) {
95641
+ <button
95642
+ type="button"
95643
+ class="pptx-ng-options-addins-row"
95644
+ [class.is-selected]="selectedId() === row.id"
95645
+ (click)="selectedId.set(row.id)"
95646
+ >
95647
+ <span>{{ row.nameKey | translate }}</span>
95648
+ <span class="pptx-ng-options-addins-loc">{{ row.location }}</span>
95649
+ <span>{{ 'pptx.options.addInType.' + row.type | translate }}</span>
95650
+ </button>
95651
+ } @empty {
95652
+ <p class="pptx-ng-options-addins-empty">
95653
+ {{ 'pptx.options.addIns.description' | translate }}
95654
+ </p>
95655
+ }
95656
+ </section>
95657
+
95658
+ @if (selected(); as row) {
95659
+ <div class="pptx-ng-options-addins-detail">
95660
+ <p class="pptx-ng-options-addins-detail-name">{{ row.nameKey | translate }}</p>
95661
+ <p>{{ row.descriptionKey | translate }}</p>
95662
+ <p class="pptx-ng-options-addins-loc">{{ row.location }}</p>
95663
+ </div>
95664
+ }
95665
+ </div>
95666
+ `, styles: [".pptx-ng-options-addins{display:flex;flex-direction:column;gap:14px}.pptx-ng-options-addins-head,.pptx-ng-options-addins-row{display:grid;grid-template-columns:1.4fr 1fr .7fr;gap:8px;align-items:center}.pptx-ng-options-addins-head{padding:0 8px 4px;border-bottom:1px solid var(--pptx-border);color:var(--pptx-muted-foreground);font-size:10px;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.pptx-ng-options-addins h4{margin:0 0 2px;font-size:12px;font-weight:600}.pptx-ng-options-addins-row{width:100%;padding:6px 8px;border:0;border-bottom:1px solid color-mix(in srgb,var(--pptx-border) 45%,transparent);background:transparent;color:var(--pptx-foreground);font-size:12px;text-align:left;cursor:pointer}.pptx-ng-options-addins-row:hover{background:var(--pptx-accent)}.pptx-ng-options-addins-row.is-selected{background:color-mix(in srgb,var(--pptx-primary) 10%,transparent)}.pptx-ng-options-addins-loc{color:var(--pptx-muted-foreground);font:11px ui-monospace,monospace;overflow-wrap:anywhere}.pptx-ng-options-addins-empty{margin:0;padding:4px 8px;color:var(--pptx-muted-foreground);font-size:11px;font-style:italic}.pptx-ng-options-addins-detail{padding:10px 12px;border:1px solid var(--pptx-border);border-radius:6px;background:var(--pptx-muted);font-size:12px}.pptx-ng-options-addins-detail p{margin:0 0 4px}.pptx-ng-options-addins-detail-name{font-weight:600}\n"] }]
95667
+ }], propDecorators: { addinStatus: [{ type: i0.Input, args: [{ isSignal: true, alias: "addinStatus", required: false }] }] } });
95668
+
95669
+ /**
95670
+ * options-pane.component.ts: generic, schema-driven File > Options pane
95671
+ * (Angular port of React's `settings/OptionsPane.tsx`).
95672
+ *
95673
+ * Renders one {@link ViewerOptionsTabDefinition}: the headline, then each
95674
+ * section's toggle/select/number/text controls with optional "(i)" info
95675
+ * tooltips and PowerPoint-style indenting. Bespoke blocks are handled via
95676
+ * `special`: `clearCache` renders inline (emitting {@link clearCache}), and
95677
+ * `themePicker` projects host content marked `themePicker` (the appearance
95678
+ * swatch gallery). Extra custom content (the Quick Access chooser) projects
95679
+ * after the sections.
95680
+ */
95681
+ /** Read a control's current primitive value off the options snapshot. */
95682
+ function readOptionValue(options, control) {
95683
+ const group = options[control.group];
95684
+ const value = group[control.key];
95685
+ return typeof value === 'boolean' || typeof value === 'number' || typeof value === 'string'
95686
+ ? value
95687
+ : undefined;
95688
+ }
95689
+ /** Clamp a number-control edit into its schema range (NaN falls to min). */
95690
+ function clampOptionNumber(raw, min, max) {
95691
+ const parsed = Number(raw);
95692
+ if (!Number.isFinite(parsed)) {
95693
+ return min;
95694
+ }
95695
+ return Math.min(max, Math.max(min, parsed));
95696
+ }
95697
+ class OptionsPaneComponent {
95698
+ tab = input.required(/* @ts-ignore */
95699
+ ...(ngDevMode ? [{ debugName: "tab" }] : /* istanbul ignore next */ []));
95700
+ options = input.required(/* @ts-ignore */
95701
+ ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
95702
+ /** One control edited (applied live by the host). */
95703
+ valueChange = output();
95704
+ /** Options > Save > "Delete cached files" pressed. */
95705
+ clearCache = output();
95706
+ value(control) {
95707
+ return readOptionValue(this.options(), control);
95708
+ }
95709
+ selectChoices(control) {
95710
+ return control.kind === 'select' ? control.choices : [];
95711
+ }
95712
+ numberMin(control) {
95713
+ return control.kind === 'number' ? control.min : 0;
95714
+ }
95715
+ numberMax(control) {
95716
+ return control.kind === 'number' ? control.max : 0;
95717
+ }
95718
+ numberUnitKey(control) {
95719
+ return control.kind === 'number' ? control.unitKey : undefined;
95720
+ }
95721
+ emitToggle(control, event) {
95722
+ this.emit(control, event.target.checked);
95723
+ }
95724
+ emitSelect(control, event) {
95725
+ this.emit(control, event.target.value);
95726
+ }
95727
+ emitNumber(control, event) {
95728
+ if (control.kind !== 'number') {
95729
+ return;
95730
+ }
95731
+ const raw = event.target.value;
95732
+ this.emit(control, clampOptionNumber(raw, control.min, control.max));
95733
+ }
95734
+ emitText(control, event) {
95735
+ this.emit(control, event.target.value);
95736
+ }
95737
+ emit(control, value) {
95738
+ this.valueChange.emit({ group: control.group, key: control.key, value });
95739
+ }
95740
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OptionsPaneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
95741
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: OptionsPaneComponent, isStandalone: true, selector: "pptx-options-pane", inputs: { tab: { classPropertyName: "tab", publicName: "tab", isSignal: true, isRequired: true, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { valueChange: "valueChange", clearCache: "clearCache" }, ngImport: i0, template: `
95742
+ <div class="pptx-ng-options-pane">
95743
+ <p class="pptx-ng-options-headline">{{ tab().descriptionKey | translate }}</p>
95744
+ @for (section of tab().sections; track section.id) {
95745
+ <section class="pptx-ng-options-section">
95746
+ <h3>{{ section.titleKey | translate }}</h3>
95747
+ @if (section.descriptionKey; as descriptionKey) {
95748
+ <p class="pptx-ng-options-note">{{ descriptionKey | translate }}</p>
95749
+ }
95750
+ @for (control of section.controls; track control.group + '.' + control.key) {
95751
+ <div class="pptx-ng-options-row" [class.is-indented]="control.indent">
95752
+ <span class="pptx-ng-options-label">
95753
+ {{ control.labelKey | translate }}
95754
+ @if (control.infoKey; as infoKey) {
95755
+ <span
95756
+ class="pptx-ng-options-info"
95757
+ [title]="infoKey | translate"
95758
+ aria-hidden="true"
95759
+ >&#9432;</span
95760
+ >
95761
+ }
95762
+ </span>
95763
+ @switch (control.kind) {
95764
+ @case ('toggle') {
95765
+ <input
95766
+ type="checkbox"
95767
+ class="pptx-ng-options-check"
95768
+ [checked]="value(control) === true"
95769
+ [attr.aria-label]="control.labelKey | translate"
95770
+ (change)="emitToggle(control, $event)"
95771
+ />
95772
+ }
95773
+ @case ('select') {
95774
+ <select
95775
+ class="pptx-ng-options-select"
95776
+ [value]="value(control)"
95777
+ [attr.aria-label]="control.labelKey | translate"
95778
+ (change)="emitSelect(control, $event)"
95779
+ >
95780
+ @for (choice of selectChoices(control); track choice.value) {
95781
+ <option [value]="choice.value" [selected]="choice.value === value(control)">
95782
+ {{ choice.labelKey | translate }}
95783
+ </option>
95784
+ }
95785
+ </select>
95786
+ }
95787
+ @case ('number') {
95788
+ <span class="pptx-ng-options-number">
95789
+ <input
95790
+ type="number"
95791
+ [min]="numberMin(control)"
95792
+ [max]="numberMax(control)"
95793
+ [value]="value(control)"
95794
+ [attr.aria-label]="control.labelKey | translate"
95795
+ (change)="emitNumber(control, $event)"
95796
+ />
95797
+ @if (numberUnitKey(control); as unitKey) {
95798
+ <span class="pptx-ng-options-note">{{ unitKey | translate }}</span>
95799
+ }
95800
+ </span>
95801
+ }
95802
+ @default {
95803
+ <input
95804
+ type="text"
95805
+ class="pptx-ng-options-text"
95806
+ maxlength="64"
95807
+ [value]="value(control) ?? ''"
95808
+ [attr.aria-label]="control.labelKey | translate"
95809
+ (change)="emitText(control, $event)"
95810
+ />
95811
+ }
95812
+ }
95813
+ </div>
95814
+ }
95815
+ @if (section.special === 'themePicker') {
95816
+ <ng-content select="[themePicker]" />
95817
+ } @else if (section.special === 'clearCache') {
95818
+ <p class="pptx-ng-options-note">
95819
+ {{ 'pptx.options.save.clearCacheDescription' | translate }}
95820
+ </p>
95821
+ <button type="button" class="pptx-ng-options-btn" (click)="clearCache.emit()">
95822
+ {{ 'pptx.options.save.clearCacheNow' | translate }}
95823
+ </button>
95824
+ }
95825
+ </section>
95826
+ }
95827
+ <ng-content />
95828
+ </div>
95829
+ `, isInline: true, styles: [".pptx-ng-options-pane{display:flex;flex-direction:column;gap:16px}.pptx-ng-options-headline{margin:0;font-size:13px;font-weight:600}.pptx-ng-options-section h3{margin:0 0 4px;padding-bottom:4px;border-bottom:1px solid var(--pptx-border);color:var(--pptx-muted-foreground);font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.pptx-ng-options-note{margin:2px 0 6px;color:var(--pptx-muted-foreground);font-size:11px}.pptx-ng-options-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:5px 0;font-size:13px}.pptx-ng-options-row.is-indented{padding-left:22px}.pptx-ng-options-info{margin-left:4px;color:var(--pptx-primary);cursor:help}.pptx-ng-options-check{width:15px;height:15px;flex-shrink:0;accent-color:var(--pptx-primary)}.pptx-ng-options-select,.pptx-ng-options-text,.pptx-ng-options-number input{max-width:55%;padding:3px 6px;border:1px solid var(--pptx-border);border-radius:4px;background:var(--pptx-background);color:var(--pptx-foreground);font-size:12px}.pptx-ng-options-number{display:inline-flex;align-items:center;gap:6px}.pptx-ng-options-number input{width:72px;text-align:right}.pptx-ng-options-text{width:180px}.pptx-ng-options-btn{padding:5px 12px;border:1px solid var(--pptx-border);border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:12px;cursor:pointer}.pptx-ng-options-btn:hover{background:var(--pptx-accent)}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
95830
+ }
95831
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OptionsPaneComponent, decorators: [{
95832
+ type: Component,
95833
+ args: [{ selector: 'pptx-options-pane', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslatePipe], template: `
95834
+ <div class="pptx-ng-options-pane">
95835
+ <p class="pptx-ng-options-headline">{{ tab().descriptionKey | translate }}</p>
95836
+ @for (section of tab().sections; track section.id) {
95837
+ <section class="pptx-ng-options-section">
95838
+ <h3>{{ section.titleKey | translate }}</h3>
95839
+ @if (section.descriptionKey; as descriptionKey) {
95840
+ <p class="pptx-ng-options-note">{{ descriptionKey | translate }}</p>
95841
+ }
95842
+ @for (control of section.controls; track control.group + '.' + control.key) {
95843
+ <div class="pptx-ng-options-row" [class.is-indented]="control.indent">
95844
+ <span class="pptx-ng-options-label">
95845
+ {{ control.labelKey | translate }}
95846
+ @if (control.infoKey; as infoKey) {
95847
+ <span
95848
+ class="pptx-ng-options-info"
95849
+ [title]="infoKey | translate"
95850
+ aria-hidden="true"
95851
+ >&#9432;</span
95852
+ >
95853
+ }
95854
+ </span>
95855
+ @switch (control.kind) {
95856
+ @case ('toggle') {
95857
+ <input
95858
+ type="checkbox"
95859
+ class="pptx-ng-options-check"
95860
+ [checked]="value(control) === true"
95861
+ [attr.aria-label]="control.labelKey | translate"
95862
+ (change)="emitToggle(control, $event)"
95863
+ />
95864
+ }
95865
+ @case ('select') {
95866
+ <select
95867
+ class="pptx-ng-options-select"
95868
+ [value]="value(control)"
95869
+ [attr.aria-label]="control.labelKey | translate"
95870
+ (change)="emitSelect(control, $event)"
95871
+ >
95872
+ @for (choice of selectChoices(control); track choice.value) {
95873
+ <option [value]="choice.value" [selected]="choice.value === value(control)">
95874
+ {{ choice.labelKey | translate }}
95875
+ </option>
95876
+ }
95877
+ </select>
95878
+ }
95879
+ @case ('number') {
95880
+ <span class="pptx-ng-options-number">
95881
+ <input
95882
+ type="number"
95883
+ [min]="numberMin(control)"
95884
+ [max]="numberMax(control)"
95885
+ [value]="value(control)"
95886
+ [attr.aria-label]="control.labelKey | translate"
95887
+ (change)="emitNumber(control, $event)"
95888
+ />
95889
+ @if (numberUnitKey(control); as unitKey) {
95890
+ <span class="pptx-ng-options-note">{{ unitKey | translate }}</span>
95891
+ }
95892
+ </span>
95893
+ }
95894
+ @default {
95895
+ <input
95896
+ type="text"
95897
+ class="pptx-ng-options-text"
95898
+ maxlength="64"
95899
+ [value]="value(control) ?? ''"
95900
+ [attr.aria-label]="control.labelKey | translate"
95901
+ (change)="emitText(control, $event)"
95902
+ />
95903
+ }
95904
+ }
95905
+ </div>
95906
+ }
95907
+ @if (section.special === 'themePicker') {
95908
+ <ng-content select="[themePicker]" />
95909
+ } @else if (section.special === 'clearCache') {
95910
+ <p class="pptx-ng-options-note">
95911
+ {{ 'pptx.options.save.clearCacheDescription' | translate }}
95912
+ </p>
95913
+ <button type="button" class="pptx-ng-options-btn" (click)="clearCache.emit()">
95914
+ {{ 'pptx.options.save.clearCacheNow' | translate }}
95915
+ </button>
95916
+ }
95917
+ </section>
95918
+ }
95919
+ <ng-content />
95920
+ </div>
95921
+ `, styles: [".pptx-ng-options-pane{display:flex;flex-direction:column;gap:16px}.pptx-ng-options-headline{margin:0;font-size:13px;font-weight:600}.pptx-ng-options-section h3{margin:0 0 4px;padding-bottom:4px;border-bottom:1px solid var(--pptx-border);color:var(--pptx-muted-foreground);font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.pptx-ng-options-note{margin:2px 0 6px;color:var(--pptx-muted-foreground);font-size:11px}.pptx-ng-options-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:5px 0;font-size:13px}.pptx-ng-options-row.is-indented{padding-left:22px}.pptx-ng-options-info{margin-left:4px;color:var(--pptx-primary);cursor:help}.pptx-ng-options-check{width:15px;height:15px;flex-shrink:0;accent-color:var(--pptx-primary)}.pptx-ng-options-select,.pptx-ng-options-text,.pptx-ng-options-number input{max-width:55%;padding:3px 6px;border:1px solid var(--pptx-border);border-radius:4px;background:var(--pptx-background);color:var(--pptx-foreground);font-size:12px}.pptx-ng-options-number{display:inline-flex;align-items:center;gap:6px}.pptx-ng-options-number input{width:72px;text-align:right}.pptx-ng-options-text{width:180px}.pptx-ng-options-btn{padding:5px 12px;border:1px solid var(--pptx-border);border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:12px;cursor:pointer}.pptx-ng-options-btn:hover{background:var(--pptx-accent)}\n"] }]
95922
+ }], propDecorators: { tab: [{ type: i0.Input, args: [{ isSignal: true, alias: "tab", required: true }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], clearCache: [{ type: i0.Output, args: ["clearCache"] }] } });
95923
+
95924
+ /**
95925
+ * options-quick-access-pane.component.ts: Options > Quick Access Toolbar pane
95926
+ * (Angular port of React's `settings/OptionsQuickAccessPane.tsx`).
95927
+ *
95928
+ * PowerPoint's dual-list command chooser over the shared
95929
+ * {@link QUICK_ACCESS_COMMAND_CATALOG}: available commands on the left, the
95930
+ * current toolbar on the right, Add/Remove between them, reorder arrows, and a
95931
+ * Reset back to {@link DEFAULT_QUICK_ACCESS_COMMAND_IDS}.
95932
+ */
95933
+ class OptionsQuickAccessPaneComponent {
95934
+ options = input.required(/* @ts-ignore */
95935
+ ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
95936
+ /** The full replacement command-id list (applied live by the host). */
95937
+ commandsChange = output();
95938
+ selectedAvailable = signal(null, /* @ts-ignore */
95939
+ ...(ngDevMode ? [{ debugName: "selectedAvailable" }] : /* istanbul ignore next */ []));
95940
+ selectedCurrent = signal(null, /* @ts-ignore */
95941
+ ...(ngDevMode ? [{ debugName: "selectedCurrent" }] : /* istanbul ignore next */ []));
95942
+ current = computed(() => this.options().quickAccess.commandIds, /* @ts-ignore */
95943
+ ...(ngDevMode ? [{ debugName: "current" }] : /* istanbul ignore next */ []));
95944
+ available = computed(() => availableQuickAccessCommands(this.current()).map((entry) => entry.id), /* @ts-ignore */
95945
+ ...(ngDevMode ? [{ debugName: "available" }] : /* istanbul ignore next */ []));
95946
+ labelKey(id) {
95947
+ return getQuickAccessCommand(id)?.labelKey ?? id;
95948
+ }
95949
+ add() {
95950
+ const id = this.selectedAvailable();
95951
+ if (id) {
95952
+ this.commandsChange.emit(addQuickAccessCommand(this.current(), id));
95953
+ this.selectedAvailable.set(null);
95954
+ }
95955
+ }
95956
+ remove() {
95957
+ const id = this.selectedCurrent();
95958
+ if (id) {
95959
+ this.commandsChange.emit(removeQuickAccessCommand(this.current(), id));
95960
+ this.selectedCurrent.set(null);
95961
+ }
95962
+ }
95963
+ move(direction) {
95964
+ const id = this.selectedCurrent();
95965
+ if (id) {
95966
+ this.commandsChange.emit(moveQuickAccessCommand(this.current(), id, direction));
95967
+ }
95968
+ }
95969
+ reset() {
95970
+ this.commandsChange.emit([...DEFAULT_QUICK_ACCESS_COMMAND_IDS]);
95971
+ }
95972
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OptionsQuickAccessPaneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
95973
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: OptionsQuickAccessPaneComponent, isStandalone: true, selector: "pptx-options-quick-access-pane", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { commandsChange: "commandsChange" }, ngImport: i0, template: `
95974
+ <div class="pptx-ng-options-qat">
95975
+ <div class="pptx-ng-options-qat-lists">
95976
+ <div class="pptx-ng-options-qat-col">
95977
+ <p>{{ 'pptx.options.quickAccess.chooseCommands' | translate }}</p>
95978
+ <div
95979
+ role="listbox"
95980
+ [attr.aria-label]="'pptx.options.quickAccess.chooseCommands' | translate"
95981
+ >
95982
+ @for (id of available(); track id) {
95983
+ <button
95984
+ type="button"
95985
+ role="option"
95986
+ [attr.aria-selected]="selectedAvailable() === id"
95987
+ [class.is-selected]="selectedAvailable() === id"
95988
+ (click)="selectedAvailable.set(id)"
95989
+ >
95990
+ {{ labelKey(id) | translate }}
95991
+ </button>
95992
+ }
95993
+ </div>
95994
+ </div>
95995
+ <div class="pptx-ng-options-qat-actions">
95996
+ <button
95997
+ type="button"
95998
+ class="pptx-ng-options-btn"
95999
+ [disabled]="!selectedAvailable()"
96000
+ (click)="add()"
96001
+ >
96002
+ {{ 'pptx.options.quickAccess.add' | translate }} &raquo;
96003
+ </button>
96004
+ <button
96005
+ type="button"
96006
+ class="pptx-ng-options-btn"
96007
+ [disabled]="!selectedCurrent()"
96008
+ (click)="remove()"
96009
+ >
96010
+ &laquo; {{ 'pptx.options.quickAccess.remove' | translate }}
96011
+ </button>
96012
+ </div>
96013
+ <div class="pptx-ng-options-qat-col">
96014
+ <p>{{ 'pptx.options.quickAccess.currentCommands' | translate }}</p>
96015
+ <div
96016
+ role="listbox"
96017
+ [attr.aria-label]="'pptx.options.quickAccess.currentCommands' | translate"
96018
+ >
96019
+ @for (id of current(); track id) {
96020
+ <button
96021
+ type="button"
96022
+ role="option"
96023
+ [attr.aria-selected]="selectedCurrent() === id"
96024
+ [class.is-selected]="selectedCurrent() === id"
96025
+ (click)="selectedCurrent.set(id)"
96026
+ >
96027
+ {{ labelKey(id) | translate }}
96028
+ </button>
96029
+ }
96030
+ </div>
96031
+ </div>
96032
+ <div class="pptx-ng-options-qat-actions">
96033
+ <button
96034
+ type="button"
96035
+ class="pptx-ng-options-btn"
96036
+ [disabled]="!selectedCurrent()"
96037
+ [attr.aria-label]="'pptx.options.quickAccess.moveUp' | translate"
96038
+ (click)="move('up')"
96039
+ >
96040
+ &#9650;
96041
+ </button>
96042
+ <button
96043
+ type="button"
96044
+ class="pptx-ng-options-btn"
96045
+ [disabled]="!selectedCurrent()"
96046
+ [attr.aria-label]="'pptx.options.quickAccess.moveDown' | translate"
96047
+ (click)="move('down')"
96048
+ >
96049
+ &#9660;
96050
+ </button>
96051
+ </div>
96052
+ </div>
96053
+ <button type="button" class="pptx-ng-options-btn" (click)="reset()">
96054
+ {{ 'pptx.options.quickAccess.reset' | translate }}
96055
+ </button>
96056
+ </div>
96057
+ `, isInline: true, styles: [".pptx-ng-options-qat{display:flex;flex-direction:column;gap:10px}.pptx-ng-options-qat-lists{display:flex;align-items:stretch;gap:10px}.pptx-ng-options-qat-col{flex:1;min-width:0}.pptx-ng-options-qat-col p{margin:0 0 4px;color:var(--pptx-muted-foreground);font-size:11px;font-weight:600}.pptx-ng-options-qat-col [role=listbox]{height:190px;overflow-y:auto;padding:4px;border:1px solid var(--pptx-border);border-radius:6px}.pptx-ng-options-qat-col [role=option]{display:block;width:100%;padding:5px 8px;border:0;border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:13px;text-align:left;cursor:pointer}.pptx-ng-options-qat-col [role=option]:hover{background:var(--pptx-accent)}.pptx-ng-options-qat-col [role=option].is-selected{background:color-mix(in srgb,var(--pptx-primary) 15%,transparent);color:var(--pptx-primary)}.pptx-ng-options-qat-actions{display:flex;flex-direction:column;justify-content:center;gap:8px}.pptx-ng-options-btn{padding:5px 10px;border:1px solid var(--pptx-border);border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:12px;white-space:nowrap;cursor:pointer}.pptx-ng-options-btn:hover:not(:disabled){background:var(--pptx-accent)}.pptx-ng-options-btn:disabled{opacity:.5;cursor:not-allowed}.pptx-ng-options-qat>.pptx-ng-options-btn{align-self:flex-start}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
96058
+ }
96059
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OptionsQuickAccessPaneComponent, decorators: [{
96060
+ type: Component,
96061
+ args: [{ selector: 'pptx-options-quick-access-pane', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslatePipe], template: `
96062
+ <div class="pptx-ng-options-qat">
96063
+ <div class="pptx-ng-options-qat-lists">
96064
+ <div class="pptx-ng-options-qat-col">
96065
+ <p>{{ 'pptx.options.quickAccess.chooseCommands' | translate }}</p>
96066
+ <div
96067
+ role="listbox"
96068
+ [attr.aria-label]="'pptx.options.quickAccess.chooseCommands' | translate"
96069
+ >
96070
+ @for (id of available(); track id) {
96071
+ <button
96072
+ type="button"
96073
+ role="option"
96074
+ [attr.aria-selected]="selectedAvailable() === id"
96075
+ [class.is-selected]="selectedAvailable() === id"
96076
+ (click)="selectedAvailable.set(id)"
96077
+ >
96078
+ {{ labelKey(id) | translate }}
96079
+ </button>
96080
+ }
96081
+ </div>
96082
+ </div>
96083
+ <div class="pptx-ng-options-qat-actions">
96084
+ <button
96085
+ type="button"
96086
+ class="pptx-ng-options-btn"
96087
+ [disabled]="!selectedAvailable()"
96088
+ (click)="add()"
96089
+ >
96090
+ {{ 'pptx.options.quickAccess.add' | translate }} &raquo;
96091
+ </button>
96092
+ <button
96093
+ type="button"
96094
+ class="pptx-ng-options-btn"
96095
+ [disabled]="!selectedCurrent()"
96096
+ (click)="remove()"
96097
+ >
96098
+ &laquo; {{ 'pptx.options.quickAccess.remove' | translate }}
96099
+ </button>
96100
+ </div>
96101
+ <div class="pptx-ng-options-qat-col">
96102
+ <p>{{ 'pptx.options.quickAccess.currentCommands' | translate }}</p>
96103
+ <div
96104
+ role="listbox"
96105
+ [attr.aria-label]="'pptx.options.quickAccess.currentCommands' | translate"
96106
+ >
96107
+ @for (id of current(); track id) {
96108
+ <button
96109
+ type="button"
96110
+ role="option"
96111
+ [attr.aria-selected]="selectedCurrent() === id"
96112
+ [class.is-selected]="selectedCurrent() === id"
96113
+ (click)="selectedCurrent.set(id)"
96114
+ >
96115
+ {{ labelKey(id) | translate }}
96116
+ </button>
96117
+ }
96118
+ </div>
96119
+ </div>
96120
+ <div class="pptx-ng-options-qat-actions">
96121
+ <button
96122
+ type="button"
96123
+ class="pptx-ng-options-btn"
96124
+ [disabled]="!selectedCurrent()"
96125
+ [attr.aria-label]="'pptx.options.quickAccess.moveUp' | translate"
96126
+ (click)="move('up')"
96127
+ >
96128
+ &#9650;
96129
+ </button>
96130
+ <button
96131
+ type="button"
96132
+ class="pptx-ng-options-btn"
96133
+ [disabled]="!selectedCurrent()"
96134
+ [attr.aria-label]="'pptx.options.quickAccess.moveDown' | translate"
96135
+ (click)="move('down')"
96136
+ >
96137
+ &#9660;
96138
+ </button>
96139
+ </div>
96140
+ </div>
96141
+ <button type="button" class="pptx-ng-options-btn" (click)="reset()">
96142
+ {{ 'pptx.options.quickAccess.reset' | translate }}
96143
+ </button>
96144
+ </div>
96145
+ `, styles: [".pptx-ng-options-qat{display:flex;flex-direction:column;gap:10px}.pptx-ng-options-qat-lists{display:flex;align-items:stretch;gap:10px}.pptx-ng-options-qat-col{flex:1;min-width:0}.pptx-ng-options-qat-col p{margin:0 0 4px;color:var(--pptx-muted-foreground);font-size:11px;font-weight:600}.pptx-ng-options-qat-col [role=listbox]{height:190px;overflow-y:auto;padding:4px;border:1px solid var(--pptx-border);border-radius:6px}.pptx-ng-options-qat-col [role=option]{display:block;width:100%;padding:5px 8px;border:0;border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:13px;text-align:left;cursor:pointer}.pptx-ng-options-qat-col [role=option]:hover{background:var(--pptx-accent)}.pptx-ng-options-qat-col [role=option].is-selected{background:color-mix(in srgb,var(--pptx-primary) 15%,transparent);color:var(--pptx-primary)}.pptx-ng-options-qat-actions{display:flex;flex-direction:column;justify-content:center;gap:8px}.pptx-ng-options-btn{padding:5px 10px;border:1px solid var(--pptx-border);border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:12px;white-space:nowrap;cursor:pointer}.pptx-ng-options-btn:hover:not(:disabled){background:var(--pptx-accent)}.pptx-ng-options-btn:disabled{opacity:.5;cursor:not-allowed}.pptx-ng-options-qat>.pptx-ng-options-btn{align-self:flex-start}\n"] }]
96146
+ }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], commandsChange: [{ type: i0.Output, args: ["commandsChange"] }] } });
96147
+
96148
+ /**
96149
+ * options-ribbon-pane.component.ts: Options > Customize Ribbon pane (Angular
96150
+ * port of React's `settings/OptionsRibbonPane.tsx`).
96151
+ *
96152
+ * Renders PowerPoint's "Main Tabs" checkbox tree over the shared
96153
+ * {@link TOOLBAR_TABS} registry (the File tab can never be hidden), a Reset
96154
+ * button that restores the ribbon group, and the keyboard-shortcut reference
96155
+ * list that backs the tab's `shortcutReference` special section.
96156
+ */
96157
+ /** Whether a ribbon tab is ticked in Customize Ribbon (File always is). */
96158
+ function isRibbonTabTicked(options, tabId) {
96159
+ return tabId === 'file' || !options.ribbon.hiddenTabIds.includes(tabId);
96160
+ }
96161
+ class OptionsRibbonPaneComponent {
96162
+ options = input.required(/* @ts-ignore */
96163
+ ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
96164
+ tabHiddenChange = output();
96165
+ resetRibbon = output();
96166
+ tabs = TOOLBAR_TABS;
96167
+ shortcuts = SHORTCUT_REFERENCE_ITEMS;
96168
+ ticked(tabId) {
96169
+ return isRibbonTabTicked(this.options(), tabId);
96170
+ }
96171
+ onTicked(tabId, event) {
96172
+ this.tabHiddenChange.emit({ tabId, hidden: !event.target.checked });
96173
+ }
96174
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OptionsRibbonPaneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
96175
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: OptionsRibbonPaneComponent, isStandalone: true, selector: "pptx-options-ribbon-pane", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { tabHiddenChange: "tabHiddenChange", resetRibbon: "resetRibbon" }, ngImport: i0, template: `
96176
+ <div class="pptx-ng-options-ribbon">
96177
+ <section>
96178
+ <h3>{{ 'pptx.options.ribbon.tabsTitle' | translate }}</h3>
96179
+ <p class="pptx-ng-options-note">{{ 'pptx.options.ribbon.tabsDescription' | translate }}</p>
96180
+ <div class="pptx-ng-options-ribbon-tabs">
96181
+ @for (tab of tabs; track tab.id) {
96182
+ <label class="pptx-ng-options-ribbon-tab" [class.is-locked]="tab.id === 'file'">
96183
+ <input
96184
+ type="checkbox"
96185
+ [checked]="ticked(tab.id)"
96186
+ [disabled]="tab.id === 'file'"
96187
+ (change)="onTicked(tab.id, $event)"
96188
+ />
96189
+ <span>{{ tab.labelKey | translate }}</span>
96190
+ </label>
96191
+ }
96192
+ </div>
96193
+ <button type="button" class="pptx-ng-options-btn" (click)="resetRibbon.emit()">
96194
+ {{ 'pptx.options.ribbon.reset' | translate }}
96195
+ </button>
96196
+ </section>
96197
+
96198
+ <section>
96199
+ <h3>{{ 'pptx.settings.keyboardShortcuts' | translate }}</h3>
96200
+ @for (item of shortcuts; track item.actionKey; let even = $even) {
96201
+ <div class="pptx-ng-options-shortcut" [class.is-alt]="even">
96202
+ <span>{{ item.actionKey | translate }}</span>
96203
+ <kbd>{{ item.shortcut }}</kbd>
96204
+ </div>
96205
+ }
96206
+ </section>
96207
+ </div>
96208
+ `, isInline: true, styles: [".pptx-ng-options-ribbon{display:flex;flex-direction:column;gap:16px}.pptx-ng-options-ribbon h3{margin:0 0 4px;padding-bottom:4px;border-bottom:1px solid var(--pptx-border);color:var(--pptx-muted-foreground);font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.pptx-ng-options-note{margin:2px 0 6px;color:var(--pptx-muted-foreground);font-size:11px}.pptx-ng-options-ribbon-tabs{margin-bottom:8px;padding:6px;border:1px solid var(--pptx-border);border-radius:6px}.pptx-ng-options-ribbon-tab{display:flex;align-items:center;gap:8px;padding:5px 6px;border-radius:4px;font-size:13px;cursor:pointer}.pptx-ng-options-ribbon-tab:hover{background:var(--pptx-accent)}.pptx-ng-options-ribbon-tab.is-locked{opacity:.6;cursor:not-allowed}.pptx-ng-options-ribbon-tab input{width:15px;height:15px;accent-color:var(--pptx-primary)}.pptx-ng-options-btn{padding:5px 12px;border:1px solid var(--pptx-border);border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:12px;cursor:pointer}.pptx-ng-options-btn:hover{background:var(--pptx-accent)}.pptx-ng-options-shortcut{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:6px 10px;border-radius:4px;font-size:12px}.pptx-ng-options-shortcut.is-alt{background:var(--pptx-muted)}.pptx-ng-options-shortcut kbd{color:var(--pptx-muted-foreground);font:11px ui-monospace,monospace;white-space:nowrap}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
96209
+ }
96210
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OptionsRibbonPaneComponent, decorators: [{
96211
+ type: Component,
96212
+ args: [{ selector: 'pptx-options-ribbon-pane', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslatePipe], template: `
96213
+ <div class="pptx-ng-options-ribbon">
96214
+ <section>
96215
+ <h3>{{ 'pptx.options.ribbon.tabsTitle' | translate }}</h3>
96216
+ <p class="pptx-ng-options-note">{{ 'pptx.options.ribbon.tabsDescription' | translate }}</p>
96217
+ <div class="pptx-ng-options-ribbon-tabs">
96218
+ @for (tab of tabs; track tab.id) {
96219
+ <label class="pptx-ng-options-ribbon-tab" [class.is-locked]="tab.id === 'file'">
96220
+ <input
96221
+ type="checkbox"
96222
+ [checked]="ticked(tab.id)"
96223
+ [disabled]="tab.id === 'file'"
96224
+ (change)="onTicked(tab.id, $event)"
96225
+ />
96226
+ <span>{{ tab.labelKey | translate }}</span>
96227
+ </label>
96228
+ }
96229
+ </div>
96230
+ <button type="button" class="pptx-ng-options-btn" (click)="resetRibbon.emit()">
96231
+ {{ 'pptx.options.ribbon.reset' | translate }}
96232
+ </button>
96233
+ </section>
96234
+
96235
+ <section>
96236
+ <h3>{{ 'pptx.settings.keyboardShortcuts' | translate }}</h3>
96237
+ @for (item of shortcuts; track item.actionKey; let even = $even) {
96238
+ <div class="pptx-ng-options-shortcut" [class.is-alt]="even">
96239
+ <span>{{ item.actionKey | translate }}</span>
96240
+ <kbd>{{ item.shortcut }}</kbd>
96241
+ </div>
96242
+ }
96243
+ </section>
96244
+ </div>
96245
+ `, styles: [".pptx-ng-options-ribbon{display:flex;flex-direction:column;gap:16px}.pptx-ng-options-ribbon h3{margin:0 0 4px;padding-bottom:4px;border-bottom:1px solid var(--pptx-border);color:var(--pptx-muted-foreground);font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.pptx-ng-options-note{margin:2px 0 6px;color:var(--pptx-muted-foreground);font-size:11px}.pptx-ng-options-ribbon-tabs{margin-bottom:8px;padding:6px;border:1px solid var(--pptx-border);border-radius:6px}.pptx-ng-options-ribbon-tab{display:flex;align-items:center;gap:8px;padding:5px 6px;border-radius:4px;font-size:13px;cursor:pointer}.pptx-ng-options-ribbon-tab:hover{background:var(--pptx-accent)}.pptx-ng-options-ribbon-tab.is-locked{opacity:.6;cursor:not-allowed}.pptx-ng-options-ribbon-tab input{width:15px;height:15px;accent-color:var(--pptx-primary)}.pptx-ng-options-btn{padding:5px 12px;border:1px solid var(--pptx-border);border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:12px;cursor:pointer}.pptx-ng-options-btn:hover{background:var(--pptx-accent)}.pptx-ng-options-shortcut{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:6px 10px;border-radius:4px;font-size:12px}.pptx-ng-options-shortcut.is-alt{background:var(--pptx-muted)}.pptx-ng-options-shortcut kbd{color:var(--pptx-muted-foreground);font:11px ui-monospace,monospace;white-space:nowrap}\n"] }]
96246
+ }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], tabHiddenChange: [{ type: i0.Output, args: ["tabHiddenChange"] }], resetRibbon: [{ type: i0.Output, args: ["resetRibbon"] }] } });
96247
+
94115
96248
  /**
94116
96249
  * settings-appearance-tab.component.ts: File > Options > Appearance tab.
94117
96250
  *
@@ -94225,233 +96358,332 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
94225
96358
  `, styles: [".pptx-ng-lang-row{width:100%;border:0;background:transparent;color:inherit;cursor:pointer}.pptx-ng-lang-row.is-active{color:var(--pptx-primary);font-weight:600}.pptx-ng-lang-en{color:var(--pptx-muted-foreground)}\n"] }]
94226
96359
  }], propDecorators: { locales: [{ type: i0.Input, args: [{ isSignal: true, alias: "locales", required: true }] }], activeCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeCode", required: false }] }], select: [{ type: i0.Output, args: ["select"] }] } });
94227
96360
 
94228
- function toggleViewerSetting(settings, key) {
94229
- return updateViewerPreference(settings, key, !settings[key]);
96361
+ /**
96362
+ * settings-dialog.component.ts: the File > Options dialog (Angular port of
96363
+ * React's `SettingsDialog.tsx`).
96364
+ *
96365
+ * A PowerPoint Options-style dialog: the ten shared categories from
96366
+ * {@link VIEWER_OPTIONS_TABS} in a left rail, schema-driven panes on the right
96367
+ * ({@link OptionsPaneComponent}), and bespoke panes for Language (locale list),
96368
+ * Customize Ribbon, Quick Access Toolbar, and Add-ins. Changes apply live
96369
+ * through the host's options store; Cancel restores the snapshot taken when
96370
+ * the dialog opened, while OK / Escape / backdrop keep the edits.
96371
+ *
96372
+ * Built as its own overlay + panel (not `pptx-modal-dialog`) because the
96373
+ * two-column rail layout needs the wide footprint the shared modal shell does
96374
+ * not provide, mirroring how `insert-smart-art-dialog` sizes itself.
96375
+ */
96376
+ /** The ten File > Options categories the dialog's rail renders, in order. */
96377
+ const OPTIONS_DIALOG_TABS = VIEWER_OPTIONS_TABS;
96378
+ /** Resolve the active tab definition, falling back to the first category. */
96379
+ function resolveOptionsTab(id) {
96380
+ const fallback = OPTIONS_DIALOG_TABS[0];
96381
+ return OPTIONS_DIALOG_TABS.find((tab) => tab.id === id) ?? fallback;
94230
96382
  }
94231
96383
  class SettingsDialogComponent {
94232
96384
  open = input(false, /* @ts-ignore */
94233
96385
  ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
94234
- settings = input.required(/* @ts-ignore */
94235
- ...(ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []));
94236
- /** Selected `THEME_CATALOG` (or `availableThemes`) key, for the Appearance tab. */
96386
+ /** Full File > Options snapshot rendered by every pane. */
96387
+ options = input.required(/* @ts-ignore */
96388
+ ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
96389
+ /** Selected theme catalog key, for General > Appearance. */
94237
96390
  themeKey = input('default', /* @ts-ignore */
94238
96391
  ...(ngDevMode ? [{ debugName: "themeKey" }] : /* istanbul ignore next */ []));
94239
- /** Theme choices offered by the Appearance tab. Defaults to the built-in `THEME_CATALOG`. */
94240
96392
  availableThemes = input(THEME_CATALOG, /* @ts-ignore */
94241
96393
  ...(ngDevMode ? [{ debugName: "availableThemes" }] : /* istanbul ignore next */ []));
94242
- /** Active locale code, for the Language tab. */
96394
+ /** Active locale code, for the Language category. */
94243
96395
  localeCode = input('en', /* @ts-ignore */
94244
96396
  ...(ngDevMode ? [{ debugName: "localeCode" }] : /* istanbul ignore next */ []));
94245
- /** Locale choices offered by the Language tab. Defaults to the built-in `LOCALE_CATALOG`. */
94246
96397
  availableLocales = input(LOCALE_CATALOG, /* @ts-ignore */
94247
96398
  ...(ngDevMode ? [{ debugName: "availableLocales" }] : /* istanbul ignore next */ []));
94248
- settingsChange = output();
94249
- /** Fired when the user picks an Appearance tab swatch. */
96399
+ /** Availability flags for the Add-ins pane (unset ids default to active). */
96400
+ addinStatus = input(undefined, /* @ts-ignore */
96401
+ ...(ngDevMode ? [{ debugName: "addinStatus" }] : /* istanbul ignore next */ []));
96402
+ optionChange = output();
96403
+ /** Restore a snapshot wholesale (Cancel semantics). */
96404
+ restoreOptions = output();
96405
+ ribbonTabHiddenChange = output();
96406
+ quickAccessCommandsChange = output();
96407
+ /** Reset one tab-group (or everything when `undefined`). */
96408
+ resetOptions = output();
96409
+ clearCache = output();
94250
96410
  themeKeySelect = output();
94251
- /** Fired when the user picks a Language tab entry. */
94252
96411
  localeSelect = output();
94253
96412
  close = output();
94254
- activeTab = signal('general', /* @ts-ignore */
96413
+ tabs = OPTIONS_DIALOG_TABS;
96414
+ activeTabId = signal('general', /* @ts-ignore */
96415
+ ...(ngDevMode ? [{ debugName: "activeTabId" }] : /* istanbul ignore next */ []));
96416
+ activeTab = computed(() => resolveOptionsTab(this.activeTabId()), /* @ts-ignore */
94255
96417
  ...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
94256
- specs = SETTING_TOGGLES;
94257
- shortcuts = SHORTCUT_REFERENCE_ITEMS;
94258
- toggle(key) {
94259
- this.settingsChange.emit(toggleViewerSetting(this.settings(), key));
96418
+ /** Snapshot taken when the dialog opens, restored by Cancel. */
96419
+ snapshot = null;
96420
+ wasOpen = false;
96421
+ constructor() {
96422
+ effect(() => {
96423
+ const isOpen = this.open();
96424
+ if (isOpen && !this.wasOpen) {
96425
+ this.snapshot = untracked(() => this.options());
96426
+ }
96427
+ this.wasOpen = isOpen;
96428
+ });
96429
+ }
96430
+ /** Cancel: restore the on-open snapshot, then close. */
96431
+ cancel() {
96432
+ if (this.snapshot) {
96433
+ this.restoreOptions.emit(this.snapshot);
96434
+ }
96435
+ this.close.emit();
96436
+ }
96437
+ /** Escape confirms (keeps edits), mirroring React's dialog. */
96438
+ onEscape() {
96439
+ if (this.open()) {
96440
+ this.close.emit();
96441
+ }
94260
96442
  }
94261
96443
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SettingsDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
94262
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: SettingsDialogComponent, isStandalone: true, selector: "pptx-settings-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null }, themeKey: { classPropertyName: "themeKey", publicName: "themeKey", isSignal: true, isRequired: false, transformFunction: null }, availableThemes: { classPropertyName: "availableThemes", publicName: "availableThemes", isSignal: true, isRequired: false, transformFunction: null }, localeCode: { classPropertyName: "localeCode", publicName: "localeCode", isSignal: true, isRequired: false, transformFunction: null }, availableLocales: { classPropertyName: "availableLocales", publicName: "availableLocales", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { settingsChange: "settingsChange", themeKeySelect: "themeKeySelect", localeSelect: "localeSelect", close: "close" }, ngImport: i0, template: `
94263
- <pptx-modal-dialog
94264
- [open]="open()"
94265
- [title]="'pptx.settings.title' | translate"
94266
- (close)="close.emit()"
94267
- >
94268
- <div class="pptx-ng-settings">
94269
- <div class="pptx-ng-settings-tabs" role="tablist">
94270
- <button
94271
- type="button"
94272
- role="tab"
94273
- [attr.aria-selected]="activeTab() === 'general'"
94274
- [class.is-active]="activeTab() === 'general'"
94275
- (click)="activeTab.set('general')"
94276
- >
94277
- {{ 'pptx.settings.general' | translate }}
94278
- </button>
94279
- <button
94280
- type="button"
94281
- role="tab"
94282
- [attr.aria-selected]="activeTab() === 'appearance'"
94283
- [class.is-active]="activeTab() === 'appearance'"
94284
- (click)="activeTab.set('appearance')"
94285
- >
94286
- {{ 'pptx.settings.appearance' | translate }}
94287
- </button>
94288
- <button
94289
- type="button"
94290
- role="tab"
94291
- [attr.aria-selected]="activeTab() === 'language'"
94292
- [class.is-active]="activeTab() === 'language'"
94293
- (click)="activeTab.set('language')"
94294
- >
94295
- {{ 'pptx.settings.language' | translate }}
94296
- </button>
96444
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: SettingsDialogComponent, isStandalone: true, selector: "pptx-settings-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, themeKey: { classPropertyName: "themeKey", publicName: "themeKey", isSignal: true, isRequired: false, transformFunction: null }, availableThemes: { classPropertyName: "availableThemes", publicName: "availableThemes", isSignal: true, isRequired: false, transformFunction: null }, localeCode: { classPropertyName: "localeCode", publicName: "localeCode", isSignal: true, isRequired: false, transformFunction: null }, availableLocales: { classPropertyName: "availableLocales", publicName: "availableLocales", isSignal: true, isRequired: false, transformFunction: null }, addinStatus: { classPropertyName: "addinStatus", publicName: "addinStatus", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { optionChange: "optionChange", restoreOptions: "restoreOptions", ribbonTabHiddenChange: "ribbonTabHiddenChange", quickAccessCommandsChange: "quickAccessCommandsChange", resetOptions: "resetOptions", clearCache: "clearCache", themeKeySelect: "themeKeySelect", localeSelect: "localeSelect", close: "close" }, host: { listeners: { "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: `
96445
+ @if (open()) {
96446
+ <button
96447
+ type="button"
96448
+ class="pptx-ng-options-backdrop"
96449
+ [attr.aria-label]="'pptx.settings.closeSettings' | translate"
96450
+ (click)="close.emit()"
96451
+ ></button>
96452
+ <div
96453
+ class="pptx-ng-options-modal"
96454
+ role="dialog"
96455
+ aria-modal="true"
96456
+ [attr.aria-label]="'pptx.options.title' | translate"
96457
+ >
96458
+ <div class="pptx-ng-options-header">
96459
+ <h2>{{ 'pptx.options.title' | translate }}</h2>
94297
96460
  <button
94298
96461
  type="button"
94299
- role="tab"
94300
- [attr.aria-selected]="activeTab() === 'shortcuts'"
94301
- [class.is-active]="activeTab() === 'shortcuts'"
94302
- (click)="activeTab.set('shortcuts')"
96462
+ class="pptx-ng-options-x"
96463
+ [attr.aria-label]="'pptx.settings.close' | translate"
96464
+ (click)="close.emit()"
94303
96465
  >
94304
- {{ 'pptx.settings.keyboardShortcuts' | translate }}
96466
+ &#10005;
94305
96467
  </button>
94306
96468
  </div>
94307
96469
 
94308
- @if (activeTab() === 'general') {
94309
- <div class="pptx-ng-settings-list">
94310
- @for (spec of specs; track spec.key) {
94311
- <div class="pptx-ng-settings-row">
94312
- <span>{{ spec.labelKey | translate }}</span>
94313
- <button
94314
- type="button"
94315
- role="switch"
94316
- [attr.aria-checked]="settings()[spec.key]"
94317
- [attr.aria-label]="spec.labelKey | translate"
94318
- [class.is-on]="settings()[spec.key]"
94319
- (click)="toggle(spec.key)"
94320
- >
94321
- <span></span>
94322
- </button>
94323
- </div>
96470
+ <div class="pptx-ng-options-layout">
96471
+ <nav [attr.aria-label]="'pptx.options.title' | translate">
96472
+ @for (tab of tabs; track tab.id) {
96473
+ <button
96474
+ type="button"
96475
+ [attr.aria-current]="activeTabId() === tab.id"
96476
+ [class.is-active]="activeTabId() === tab.id"
96477
+ (click)="activeTabId.set(tab.id)"
96478
+ >
96479
+ {{ tab.labelKey | translate }}
96480
+ </button>
94324
96481
  }
94325
- </div>
94326
- } @else if (activeTab() === 'appearance') {
94327
- <pptx-settings-appearance-tab
94328
- [themes]="availableThemes()"
94329
- [activeKey]="themeKey()"
94330
- (select)="themeKeySelect.emit($event)"
94331
- />
94332
- } @else if (activeTab() === 'language') {
94333
- <pptx-settings-language-tab
94334
- [locales]="availableLocales()"
94335
- [activeCode]="localeCode()"
94336
- (select)="localeSelect.emit($event)"
94337
- />
94338
- } @else {
94339
- <div class="pptx-ng-settings-list">
94340
- @for (item of shortcuts; track item.actionKey; let even = $even) {
94341
- <div class="pptx-ng-shortcut-row" [class.is-alt]="even">
94342
- <span>{{ item.actionKey | translate }}</span>
94343
- <kbd>{{ item.shortcut }}</kbd>
94344
- </div>
96482
+ </nav>
96483
+
96484
+ <div class="pptx-ng-options-content">
96485
+ @switch (activeTab().custom) {
96486
+ @case ('language') {
96487
+ <p class="pptx-ng-options-headline">{{ activeTab().descriptionKey | translate }}</p>
96488
+ <h3 class="pptx-ng-options-subhead">
96489
+ {{ 'pptx.options.language.displayLanguage' | translate }}
96490
+ </h3>
96491
+ <p class="pptx-ng-options-note">
96492
+ {{ 'pptx.options.language.displayLanguageDescription' | translate }}
96493
+ </p>
96494
+ <pptx-settings-language-tab
96495
+ [locales]="availableLocales()"
96496
+ [activeCode]="localeCode()"
96497
+ (select)="localeSelect.emit($event)"
96498
+ />
96499
+ }
96500
+ @case ('ribbon') {
96501
+ <p class="pptx-ng-options-headline">{{ activeTab().descriptionKey | translate }}</p>
96502
+ <pptx-options-ribbon-pane
96503
+ [options]="options()"
96504
+ (tabHiddenChange)="ribbonTabHiddenChange.emit($event)"
96505
+ (resetRibbon)="resetOptions.emit('ribbon')"
96506
+ />
96507
+ }
96508
+ @case ('addIns') {
96509
+ <p class="pptx-ng-options-headline">{{ activeTab().descriptionKey | translate }}</p>
96510
+ <pptx-options-add-ins-pane [addinStatus]="addinStatus()" />
96511
+ }
96512
+ @default {
96513
+ <pptx-options-pane
96514
+ [tab]="activeTab()"
96515
+ [options]="options()"
96516
+ (valueChange)="optionChange.emit($event)"
96517
+ (clearCache)="clearCache.emit()"
96518
+ >
96519
+ <div themePicker>
96520
+ <pptx-settings-appearance-tab
96521
+ [themes]="availableThemes()"
96522
+ [activeKey]="themeKey()"
96523
+ (select)="themeKeySelect.emit($event)"
96524
+ />
96525
+ </div>
96526
+ @if (activeTab().custom === 'quickAccess') {
96527
+ <pptx-options-quick-access-pane
96528
+ [options]="options()"
96529
+ (commandsChange)="quickAccessCommandsChange.emit($event)"
96530
+ />
96531
+ }
96532
+ </pptx-options-pane>
96533
+ }
94345
96534
  }
94346
96535
  </div>
94347
- }
96536
+ </div>
96537
+
96538
+ <div class="pptx-ng-options-footer">
96539
+ <button
96540
+ type="button"
96541
+ class="pptx-ng-options-ghost"
96542
+ (click)="resetOptions.emit(undefined)"
96543
+ >
96544
+ {{ 'pptx.options.resetAll' | translate }}
96545
+ </button>
96546
+ <span class="pptx-ng-options-footer-end">
96547
+ <button type="button" class="pptx-ng-options-ghost" (click)="cancel()">
96548
+ {{ 'pptx.common.cancel' | translate }}
96549
+ </button>
96550
+ <button type="button" class="pptx-ng-options-ok" (click)="close.emit()">
96551
+ {{ 'pptx.common.ok' | translate }}
96552
+ </button>
96553
+ </span>
96554
+ </div>
94348
96555
  </div>
94349
- <button footer type="button" class="pptx-ng-settings-done" (click)="close.emit()">
94350
- {{ 'pptx.settings.done' | translate }}
94351
- </button>
94352
- </pptx-modal-dialog>
94353
- `, isInline: true, styles: [".pptx-ng-settings{min-width:320px}.pptx-ng-settings-tabs{display:flex;flex-wrap:wrap;gap:4px;border-bottom:1px solid var(--pptx-border)}.pptx-ng-settings-tabs button{padding:7px 10px;border:0;border-bottom:2px solid transparent;background:transparent;color:var(--pptx-muted-foreground);font-size:12px;cursor:pointer}.pptx-ng-settings-tabs button.is-active{border-bottom-color:var(--pptx-primary);color:var(--pptx-primary)}.pptx-ng-settings-list{max-height:56vh;overflow-y:auto;padding-top:8px}.pptx-ng-settings-row,.pptx-ng-shortcut-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:9px 10px;font-size:13px}.pptx-ng-settings-row button{position:relative;width:36px;height:20px;padding:0;border:0;border-radius:999px;background:color-mix(in srgb,var(--pptx-muted-foreground) 30%,transparent);cursor:pointer}.pptx-ng-settings-row button span{position:absolute;top:3px;left:3px;width:14px;height:14px;border-radius:50%;background:#fff;transition:transform .12s ease}.pptx-ng-settings-row button.is-on{background:var(--pptx-primary)}.pptx-ng-settings-row button.is-on span{transform:translate(16px)}.pptx-ng-shortcut-row.is-alt{background:var(--pptx-muted)}.pptx-ng-shortcut-row kbd{color:var(--pptx-muted-foreground);font:11px ui-monospace,monospace;white-space:nowrap}.pptx-ng-settings-done{border:0;border-radius:4px;padding:7px 14px;background:var(--pptx-primary);color:#fff;cursor:pointer}\n"], dependencies: [{ kind: "component", type: ModalDialogComponent, selector: "pptx-modal-dialog", inputs: ["open", "title"], outputs: ["close"] }, { kind: "component", type: SettingsAppearanceTabComponent, selector: "pptx-settings-appearance-tab", inputs: ["themes", "activeKey"], outputs: ["select"] }, { kind: "component", type: SettingsLanguageTabComponent, selector: "pptx-settings-language-tab", inputs: ["locales", "activeCode"], outputs: ["select"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
96556
+ }
96557
+ `, isInline: true, styles: [".pptx-ng-options-backdrop{position:fixed;inset:0;z-index:1200;border:0;background:#0009;cursor:default}.pptx-ng-options-modal{position:fixed;top:50%;left:50%;z-index:1201;display:flex;flex-direction:column;width:min(56rem,calc(100vw - 2rem));max-height:85vh;transform:translate(-50%,-50%);border:1px solid var(--pptx-border);border-radius:12px;background:var(--pptx-popover, var(--pptx-background));color:var(--pptx-foreground);box-shadow:0 24px 64px #00000059}.pptx-ng-options-header{display:flex;align-items:center;justify-content:space-between;padding:14px 20px;border-bottom:1px solid var(--pptx-border)}.pptx-ng-options-header h2{margin:0;font-size:14px;font-weight:600}.pptx-ng-options-x{border:0;border-radius:4px;padding:4px 8px;background:transparent;color:var(--pptx-muted-foreground);cursor:pointer}.pptx-ng-options-x:hover{background:var(--pptx-accent)}.pptx-ng-options-layout{display:flex;flex:1;min-height:0}.pptx-ng-options-layout nav{display:flex;flex-direction:column;gap:2px;width:176px;flex-shrink:0;overflow-y:auto;padding:8px;border-right:1px solid var(--pptx-border)}.pptx-ng-options-layout nav button{padding:8px 12px;border:0;border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:13px;text-align:left;white-space:nowrap;cursor:pointer}.pptx-ng-options-layout nav button:hover{background:var(--pptx-accent)}.pptx-ng-options-layout nav button.is-active{background:color-mix(in srgb,var(--pptx-primary) 10%,transparent);color:var(--pptx-primary);font-weight:500}.pptx-ng-options-content{flex:1;min-height:0;min-width:0;overflow-y:auto;padding:16px 20px}.pptx-ng-options-headline{margin:0 0 12px;font-size:13px;font-weight:600}.pptx-ng-options-subhead{margin:0 0 4px;padding-bottom:4px;border-bottom:1px solid var(--pptx-border);color:var(--pptx-muted-foreground);font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.pptx-ng-options-note{margin:2px 0 6px;color:var(--pptx-muted-foreground);font-size:11px}.pptx-ng-options-footer{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 20px;border-top:1px solid var(--pptx-border)}.pptx-ng-options-footer-end{display:inline-flex;gap:8px}.pptx-ng-options-ghost,.pptx-ng-options-ok{padding:6px 16px;border-radius:4px;font-size:12px;cursor:pointer}.pptx-ng-options-ghost{border:1px solid var(--pptx-border);background:transparent;color:var(--pptx-foreground)}.pptx-ng-options-ghost:hover{background:var(--pptx-accent)}.pptx-ng-options-ok{border:0;background:var(--pptx-primary);color:#fff;font-weight:500}\n"], dependencies: [{ kind: "component", type: OptionsPaneComponent, selector: "pptx-options-pane", inputs: ["tab", "options"], outputs: ["valueChange", "clearCache"] }, { kind: "component", type: OptionsRibbonPaneComponent, selector: "pptx-options-ribbon-pane", inputs: ["options"], outputs: ["tabHiddenChange", "resetRibbon"] }, { kind: "component", type: OptionsQuickAccessPaneComponent, selector: "pptx-options-quick-access-pane", inputs: ["options"], outputs: ["commandsChange"] }, { kind: "component", type: OptionsAddInsPaneComponent, selector: "pptx-options-add-ins-pane", inputs: ["addinStatus"] }, { kind: "component", type: SettingsAppearanceTabComponent, selector: "pptx-settings-appearance-tab", inputs: ["themes", "activeKey"], outputs: ["select"] }, { kind: "component", type: SettingsLanguageTabComponent, selector: "pptx-settings-language-tab", inputs: ["locales", "activeCode"], outputs: ["select"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
94354
96558
  }
94355
96559
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SettingsDialogComponent, decorators: [{
94356
96560
  type: Component,
94357
96561
  args: [{ selector: 'pptx-settings-dialog', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
94358
- ModalDialogComponent,
94359
96562
  TranslatePipe,
96563
+ OptionsPaneComponent,
96564
+ OptionsRibbonPaneComponent,
96565
+ OptionsQuickAccessPaneComponent,
96566
+ OptionsAddInsPaneComponent,
94360
96567
  SettingsAppearanceTabComponent,
94361
96568
  SettingsLanguageTabComponent,
94362
96569
  ], template: `
94363
- <pptx-modal-dialog
94364
- [open]="open()"
94365
- [title]="'pptx.settings.title' | translate"
94366
- (close)="close.emit()"
94367
- >
94368
- <div class="pptx-ng-settings">
94369
- <div class="pptx-ng-settings-tabs" role="tablist">
94370
- <button
94371
- type="button"
94372
- role="tab"
94373
- [attr.aria-selected]="activeTab() === 'general'"
94374
- [class.is-active]="activeTab() === 'general'"
94375
- (click)="activeTab.set('general')"
94376
- >
94377
- {{ 'pptx.settings.general' | translate }}
94378
- </button>
94379
- <button
94380
- type="button"
94381
- role="tab"
94382
- [attr.aria-selected]="activeTab() === 'appearance'"
94383
- [class.is-active]="activeTab() === 'appearance'"
94384
- (click)="activeTab.set('appearance')"
94385
- >
94386
- {{ 'pptx.settings.appearance' | translate }}
94387
- </button>
94388
- <button
94389
- type="button"
94390
- role="tab"
94391
- [attr.aria-selected]="activeTab() === 'language'"
94392
- [class.is-active]="activeTab() === 'language'"
94393
- (click)="activeTab.set('language')"
94394
- >
94395
- {{ 'pptx.settings.language' | translate }}
94396
- </button>
96570
+ @if (open()) {
96571
+ <button
96572
+ type="button"
96573
+ class="pptx-ng-options-backdrop"
96574
+ [attr.aria-label]="'pptx.settings.closeSettings' | translate"
96575
+ (click)="close.emit()"
96576
+ ></button>
96577
+ <div
96578
+ class="pptx-ng-options-modal"
96579
+ role="dialog"
96580
+ aria-modal="true"
96581
+ [attr.aria-label]="'pptx.options.title' | translate"
96582
+ >
96583
+ <div class="pptx-ng-options-header">
96584
+ <h2>{{ 'pptx.options.title' | translate }}</h2>
94397
96585
  <button
94398
96586
  type="button"
94399
- role="tab"
94400
- [attr.aria-selected]="activeTab() === 'shortcuts'"
94401
- [class.is-active]="activeTab() === 'shortcuts'"
94402
- (click)="activeTab.set('shortcuts')"
96587
+ class="pptx-ng-options-x"
96588
+ [attr.aria-label]="'pptx.settings.close' | translate"
96589
+ (click)="close.emit()"
94403
96590
  >
94404
- {{ 'pptx.settings.keyboardShortcuts' | translate }}
96591
+ &#10005;
94405
96592
  </button>
94406
96593
  </div>
94407
96594
 
94408
- @if (activeTab() === 'general') {
94409
- <div class="pptx-ng-settings-list">
94410
- @for (spec of specs; track spec.key) {
94411
- <div class="pptx-ng-settings-row">
94412
- <span>{{ spec.labelKey | translate }}</span>
94413
- <button
94414
- type="button"
94415
- role="switch"
94416
- [attr.aria-checked]="settings()[spec.key]"
94417
- [attr.aria-label]="spec.labelKey | translate"
94418
- [class.is-on]="settings()[spec.key]"
94419
- (click)="toggle(spec.key)"
94420
- >
94421
- <span></span>
94422
- </button>
94423
- </div>
96595
+ <div class="pptx-ng-options-layout">
96596
+ <nav [attr.aria-label]="'pptx.options.title' | translate">
96597
+ @for (tab of tabs; track tab.id) {
96598
+ <button
96599
+ type="button"
96600
+ [attr.aria-current]="activeTabId() === tab.id"
96601
+ [class.is-active]="activeTabId() === tab.id"
96602
+ (click)="activeTabId.set(tab.id)"
96603
+ >
96604
+ {{ tab.labelKey | translate }}
96605
+ </button>
94424
96606
  }
94425
- </div>
94426
- } @else if (activeTab() === 'appearance') {
94427
- <pptx-settings-appearance-tab
94428
- [themes]="availableThemes()"
94429
- [activeKey]="themeKey()"
94430
- (select)="themeKeySelect.emit($event)"
94431
- />
94432
- } @else if (activeTab() === 'language') {
94433
- <pptx-settings-language-tab
94434
- [locales]="availableLocales()"
94435
- [activeCode]="localeCode()"
94436
- (select)="localeSelect.emit($event)"
94437
- />
94438
- } @else {
94439
- <div class="pptx-ng-settings-list">
94440
- @for (item of shortcuts; track item.actionKey; let even = $even) {
94441
- <div class="pptx-ng-shortcut-row" [class.is-alt]="even">
94442
- <span>{{ item.actionKey | translate }}</span>
94443
- <kbd>{{ item.shortcut }}</kbd>
94444
- </div>
96607
+ </nav>
96608
+
96609
+ <div class="pptx-ng-options-content">
96610
+ @switch (activeTab().custom) {
96611
+ @case ('language') {
96612
+ <p class="pptx-ng-options-headline">{{ activeTab().descriptionKey | translate }}</p>
96613
+ <h3 class="pptx-ng-options-subhead">
96614
+ {{ 'pptx.options.language.displayLanguage' | translate }}
96615
+ </h3>
96616
+ <p class="pptx-ng-options-note">
96617
+ {{ 'pptx.options.language.displayLanguageDescription' | translate }}
96618
+ </p>
96619
+ <pptx-settings-language-tab
96620
+ [locales]="availableLocales()"
96621
+ [activeCode]="localeCode()"
96622
+ (select)="localeSelect.emit($event)"
96623
+ />
96624
+ }
96625
+ @case ('ribbon') {
96626
+ <p class="pptx-ng-options-headline">{{ activeTab().descriptionKey | translate }}</p>
96627
+ <pptx-options-ribbon-pane
96628
+ [options]="options()"
96629
+ (tabHiddenChange)="ribbonTabHiddenChange.emit($event)"
96630
+ (resetRibbon)="resetOptions.emit('ribbon')"
96631
+ />
96632
+ }
96633
+ @case ('addIns') {
96634
+ <p class="pptx-ng-options-headline">{{ activeTab().descriptionKey | translate }}</p>
96635
+ <pptx-options-add-ins-pane [addinStatus]="addinStatus()" />
96636
+ }
96637
+ @default {
96638
+ <pptx-options-pane
96639
+ [tab]="activeTab()"
96640
+ [options]="options()"
96641
+ (valueChange)="optionChange.emit($event)"
96642
+ (clearCache)="clearCache.emit()"
96643
+ >
96644
+ <div themePicker>
96645
+ <pptx-settings-appearance-tab
96646
+ [themes]="availableThemes()"
96647
+ [activeKey]="themeKey()"
96648
+ (select)="themeKeySelect.emit($event)"
96649
+ />
96650
+ </div>
96651
+ @if (activeTab().custom === 'quickAccess') {
96652
+ <pptx-options-quick-access-pane
96653
+ [options]="options()"
96654
+ (commandsChange)="quickAccessCommandsChange.emit($event)"
96655
+ />
96656
+ }
96657
+ </pptx-options-pane>
96658
+ }
94445
96659
  }
94446
96660
  </div>
94447
- }
96661
+ </div>
96662
+
96663
+ <div class="pptx-ng-options-footer">
96664
+ <button
96665
+ type="button"
96666
+ class="pptx-ng-options-ghost"
96667
+ (click)="resetOptions.emit(undefined)"
96668
+ >
96669
+ {{ 'pptx.options.resetAll' | translate }}
96670
+ </button>
96671
+ <span class="pptx-ng-options-footer-end">
96672
+ <button type="button" class="pptx-ng-options-ghost" (click)="cancel()">
96673
+ {{ 'pptx.common.cancel' | translate }}
96674
+ </button>
96675
+ <button type="button" class="pptx-ng-options-ok" (click)="close.emit()">
96676
+ {{ 'pptx.common.ok' | translate }}
96677
+ </button>
96678
+ </span>
96679
+ </div>
94448
96680
  </div>
94449
- <button footer type="button" class="pptx-ng-settings-done" (click)="close.emit()">
94450
- {{ 'pptx.settings.done' | translate }}
94451
- </button>
94452
- </pptx-modal-dialog>
94453
- `, styles: [".pptx-ng-settings{min-width:320px}.pptx-ng-settings-tabs{display:flex;flex-wrap:wrap;gap:4px;border-bottom:1px solid var(--pptx-border)}.pptx-ng-settings-tabs button{padding:7px 10px;border:0;border-bottom:2px solid transparent;background:transparent;color:var(--pptx-muted-foreground);font-size:12px;cursor:pointer}.pptx-ng-settings-tabs button.is-active{border-bottom-color:var(--pptx-primary);color:var(--pptx-primary)}.pptx-ng-settings-list{max-height:56vh;overflow-y:auto;padding-top:8px}.pptx-ng-settings-row,.pptx-ng-shortcut-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:9px 10px;font-size:13px}.pptx-ng-settings-row button{position:relative;width:36px;height:20px;padding:0;border:0;border-radius:999px;background:color-mix(in srgb,var(--pptx-muted-foreground) 30%,transparent);cursor:pointer}.pptx-ng-settings-row button span{position:absolute;top:3px;left:3px;width:14px;height:14px;border-radius:50%;background:#fff;transition:transform .12s ease}.pptx-ng-settings-row button.is-on{background:var(--pptx-primary)}.pptx-ng-settings-row button.is-on span{transform:translate(16px)}.pptx-ng-shortcut-row.is-alt{background:var(--pptx-muted)}.pptx-ng-shortcut-row kbd{color:var(--pptx-muted-foreground);font:11px ui-monospace,monospace;white-space:nowrap}.pptx-ng-settings-done{border:0;border-radius:4px;padding:7px 14px;background:var(--pptx-primary);color:#fff;cursor:pointer}\n"] }]
94454
- }], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], settings: [{ type: i0.Input, args: [{ isSignal: true, alias: "settings", required: true }] }], themeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "themeKey", required: false }] }], availableThemes: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableThemes", required: false }] }], localeCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "localeCode", required: false }] }], availableLocales: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableLocales", required: false }] }], settingsChange: [{ type: i0.Output, args: ["settingsChange"] }], themeKeySelect: [{ type: i0.Output, args: ["themeKeySelect"] }], localeSelect: [{ type: i0.Output, args: ["localeSelect"] }], close: [{ type: i0.Output, args: ["close"] }] } });
96681
+ }
96682
+ `, styles: [".pptx-ng-options-backdrop{position:fixed;inset:0;z-index:1200;border:0;background:#0009;cursor:default}.pptx-ng-options-modal{position:fixed;top:50%;left:50%;z-index:1201;display:flex;flex-direction:column;width:min(56rem,calc(100vw - 2rem));max-height:85vh;transform:translate(-50%,-50%);border:1px solid var(--pptx-border);border-radius:12px;background:var(--pptx-popover, var(--pptx-background));color:var(--pptx-foreground);box-shadow:0 24px 64px #00000059}.pptx-ng-options-header{display:flex;align-items:center;justify-content:space-between;padding:14px 20px;border-bottom:1px solid var(--pptx-border)}.pptx-ng-options-header h2{margin:0;font-size:14px;font-weight:600}.pptx-ng-options-x{border:0;border-radius:4px;padding:4px 8px;background:transparent;color:var(--pptx-muted-foreground);cursor:pointer}.pptx-ng-options-x:hover{background:var(--pptx-accent)}.pptx-ng-options-layout{display:flex;flex:1;min-height:0}.pptx-ng-options-layout nav{display:flex;flex-direction:column;gap:2px;width:176px;flex-shrink:0;overflow-y:auto;padding:8px;border-right:1px solid var(--pptx-border)}.pptx-ng-options-layout nav button{padding:8px 12px;border:0;border-radius:4px;background:transparent;color:var(--pptx-foreground);font-size:13px;text-align:left;white-space:nowrap;cursor:pointer}.pptx-ng-options-layout nav button:hover{background:var(--pptx-accent)}.pptx-ng-options-layout nav button.is-active{background:color-mix(in srgb,var(--pptx-primary) 10%,transparent);color:var(--pptx-primary);font-weight:500}.pptx-ng-options-content{flex:1;min-height:0;min-width:0;overflow-y:auto;padding:16px 20px}.pptx-ng-options-headline{margin:0 0 12px;font-size:13px;font-weight:600}.pptx-ng-options-subhead{margin:0 0 4px;padding-bottom:4px;border-bottom:1px solid var(--pptx-border);color:var(--pptx-muted-foreground);font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.pptx-ng-options-note{margin:2px 0 6px;color:var(--pptx-muted-foreground);font-size:11px}.pptx-ng-options-footer{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 20px;border-top:1px solid var(--pptx-border)}.pptx-ng-options-footer-end{display:inline-flex;gap:8px}.pptx-ng-options-ghost,.pptx-ng-options-ok{padding:6px 16px;border-radius:4px;font-size:12px;cursor:pointer}.pptx-ng-options-ghost{border:1px solid var(--pptx-border);background:transparent;color:var(--pptx-foreground)}.pptx-ng-options-ghost:hover{background:var(--pptx-accent)}.pptx-ng-options-ok{border:0;background:var(--pptx-primary);color:#fff;font-weight:500}\n"] }]
96683
+ }], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], themeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "themeKey", required: false }] }], availableThemes: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableThemes", required: false }] }], localeCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "localeCode", required: false }] }], availableLocales: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableLocales", required: false }] }], addinStatus: [{ type: i0.Input, args: [{ isSignal: true, alias: "addinStatus", required: false }] }], optionChange: [{ type: i0.Output, args: ["optionChange"] }], restoreOptions: [{ type: i0.Output, args: ["restoreOptions"] }], ribbonTabHiddenChange: [{ type: i0.Output, args: ["ribbonTabHiddenChange"] }], quickAccessCommandsChange: [{ type: i0.Output, args: ["quickAccessCommandsChange"] }], resetOptions: [{ type: i0.Output, args: ["resetOptions"] }], clearCache: [{ type: i0.Output, args: ["clearCache"] }], themeKeySelect: [{ type: i0.Output, args: ["themeKeySelect"] }], localeSelect: [{ type: i0.Output, args: ["localeSelect"] }], close: [{ type: i0.Output, args: ["close"] }], onEscape: [{
96684
+ type: HostListener,
96685
+ args: ['document:keydown.escape']
96686
+ }] } });
94455
96687
 
94456
96688
  /** Compatibility barrel for the shared keyboard shortcut reference. */
94457
96689
 
@@ -94937,9 +97169,6 @@ class ViewerExtraDialogsComponent {
94937
97169
  /** Custom shows offered in the set-up-slide-show "show slides" fieldset. */
94938
97170
  customShows = input([], /* @ts-ignore */
94939
97171
  ...(ngDevMode ? [{ debugName: "customShows" }] : /* istanbul ignore next */ []));
94940
- /** Live viewer preferences surfaced by the settings dialog. */
94941
- settings = input.required(/* @ts-ignore */
94942
- ...(ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []));
94943
97172
  // Settings dialog Appearance/Language tab state; see PowerPointViewerComponent.
94944
97173
  themeKey = input('default', /* @ts-ignore */
94945
97174
  ...(ngDevMode ? [{ debugName: "themeKey" }] : /* istanbul ignore next */ []));
@@ -94951,12 +97180,11 @@ class ViewerExtraDialogsComponent {
94951
97180
  ...(ngDevMode ? [{ debugName: "availableLocales" }] : /* istanbul ignore next */ []));
94952
97181
  /** Fired with a restored `.pptx` version's bytes; the host swaps the deck. */
94953
97182
  restoreContent = output();
94954
- /** Fired whenever a settings toggle changes. */
94955
- settingsChange = output();
94956
97183
  // Fired when the user picks a Settings dialog Appearance/Language selection.
94957
97184
  themeKeySelect = output();
94958
97185
  localeSelect = output();
94959
97186
  svc = inject(ViewerDialogsService);
97187
+ viewerOpts = inject(ViewerOptionsService);
94960
97188
  compare = inject(ViewerCompareService);
94961
97189
  editor = inject(EditorStateService);
94962
97190
  loader = inject(LoadContentService);
@@ -95001,6 +97229,11 @@ class ViewerExtraDialogsComponent {
95001
97229
  if (strokeCount === 0) {
95002
97230
  return;
95003
97231
  }
97232
+ // Options > Advanced > "Prompt to keep ink annotations": when off, the
97233
+ // ink is discarded without asking (PowerPoint parity).
97234
+ if (!this.viewerOpts.options().advanced.slideShowPromptKeepInkAnnotations) {
97235
+ return;
97236
+ }
95004
97237
  this.pendingAnnotations.set(map);
95005
97238
  this.svc.keepAnnotationCount.set(strokeCount);
95006
97239
  this.svc.keepSlideCount.set(map.size);
@@ -95017,6 +97250,10 @@ class ViewerExtraDialogsComponent {
95017
97250
  this.pendingAnnotations.set(null);
95018
97251
  this.svc.showKeepAnnotations.set(false);
95019
97252
  }
97253
+ /** Options > Save > "Delete cached files": purge autosave recovery snapshots. */
97254
+ onClearOptionsCache() {
97255
+ void this.viewerOpts.clearCache();
97256
+ }
95020
97257
  /** Drop the pending presentation ink. */
95021
97258
  onDiscardAnnotations() {
95022
97259
  this.pendingAnnotations.set(null);
@@ -95053,7 +97290,7 @@ class ViewerExtraDialogsComponent {
95053
97290
  this.svc.showPassword.set(false);
95054
97291
  }
95055
97292
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ViewerExtraDialogsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
95056
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.7", type: ViewerExtraDialogsComponent, isStandalone: true, selector: "pptx-viewer-extra-dialogs", inputs: { activeSlideIndex: { classPropertyName: "activeSlideIndex", publicName: "activeSlideIndex", isSignal: true, isRequired: false, transformFunction: null }, selectedElementId: { classPropertyName: "selectedElementId", publicName: "selectedElementId", isSignal: true, isRequired: false, transformFunction: null }, filePath: { classPropertyName: "filePath", publicName: "filePath", isSignal: true, isRequired: false, transformFunction: null }, customShows: { classPropertyName: "customShows", publicName: "customShows", isSignal: true, isRequired: false, transformFunction: null }, settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null }, themeKey: { classPropertyName: "themeKey", publicName: "themeKey", isSignal: true, isRequired: false, transformFunction: null }, availableThemes: { classPropertyName: "availableThemes", publicName: "availableThemes", isSignal: true, isRequired: false, transformFunction: null }, localeCode: { classPropertyName: "localeCode", publicName: "localeCode", isSignal: true, isRequired: false, transformFunction: null }, availableLocales: { classPropertyName: "availableLocales", publicName: "availableLocales", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { restoreContent: "restoreContent", settingsChange: "settingsChange", themeKeySelect: "themeKeySelect", localeSelect: "localeSelect" }, host: { classAttribute: "contents" }, ngImport: i0, template: `
97293
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.7", type: ViewerExtraDialogsComponent, isStandalone: true, selector: "pptx-viewer-extra-dialogs", inputs: { activeSlideIndex: { classPropertyName: "activeSlideIndex", publicName: "activeSlideIndex", isSignal: true, isRequired: false, transformFunction: null }, selectedElementId: { classPropertyName: "selectedElementId", publicName: "selectedElementId", isSignal: true, isRequired: false, transformFunction: null }, filePath: { classPropertyName: "filePath", publicName: "filePath", isSignal: true, isRequired: false, transformFunction: null }, customShows: { classPropertyName: "customShows", publicName: "customShows", isSignal: true, isRequired: false, transformFunction: null }, themeKey: { classPropertyName: "themeKey", publicName: "themeKey", isSignal: true, isRequired: false, transformFunction: null }, availableThemes: { classPropertyName: "availableThemes", publicName: "availableThemes", isSignal: true, isRequired: false, transformFunction: null }, localeCode: { classPropertyName: "localeCode", publicName: "localeCode", isSignal: true, isRequired: false, transformFunction: null }, availableLocales: { classPropertyName: "availableLocales", publicName: "availableLocales", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { restoreContent: "restoreContent", themeKeySelect: "themeKeySelect", localeSelect: "localeSelect" }, host: { classAttribute: "contents" }, ngImport: i0, template: `
95057
97294
  <pptx-equation-editor-dialog
95058
97295
  [open]="svc.showEquation()"
95059
97296
  [existingOmml]="svc.editingEquationOmml()"
@@ -95114,12 +97351,17 @@ class ViewerExtraDialogsComponent {
95114
97351
 
95115
97352
  <pptx-settings-dialog
95116
97353
  [open]="svc.showSettings()"
95117
- [settings]="settings()"
97354
+ [options]="viewerOpts.options()"
95118
97355
  [themeKey]="themeKey()"
95119
97356
  [availableThemes]="availableThemes()"
95120
97357
  [localeCode]="localeCode()"
95121
97358
  [availableLocales]="availableLocales()"
95122
- (settingsChange)="settingsChange.emit($event)"
97359
+ (optionChange)="viewerOpts.setValue($event.group, $event.key, $event.value)"
97360
+ (restoreOptions)="viewerOpts.restore($event)"
97361
+ (ribbonTabHiddenChange)="viewerOpts.setRibbonTabHidden($event.tabId, $event.hidden)"
97362
+ (quickAccessCommandsChange)="viewerOpts.setQuickAccessCommands($event)"
97363
+ (resetOptions)="viewerOpts.reset($event)"
97364
+ (clearCache)="onClearOptionsCache()"
95123
97365
  (themeKeySelect)="themeKeySelect.emit($event)"
95124
97366
  (localeSelect)="localeSelect.emit($event)"
95125
97367
  (close)="svc.showSettings.set(false)"
@@ -95146,7 +97388,7 @@ class ViewerExtraDialogsComponent {
95146
97388
  (confirm)="svc.showSignatureStripped.set(false)"
95147
97389
  (cancel)="svc.showSignatureStripped.set(false)"
95148
97390
  />
95149
- `, isInline: true, dependencies: [{ kind: "component", type: EquationEditorDialogComponent, selector: "pptx-equation-editor-dialog", inputs: ["open", "existingOmml"], outputs: ["insert", "close"] }, { kind: "component", type: SetUpSlideShowDialogComponent, selector: "pptx-set-up-slide-show-dialog", inputs: ["open", "properties", "customShows", "slideCount"], outputs: ["save", "close"] }, { kind: "component", type: PasswordProtectionDialogComponent, selector: "pptx-password-protection-dialog", inputs: ["open", "isCurrentlyProtected"], outputs: ["setPassword", "removePassword", "close"] }, { kind: "component", type: EncryptedFileDialogComponent, selector: "pptx-encrypted-file-dialog", inputs: ["open"], outputs: ["close"] }, { kind: "component", type: ComparePanelComponent, selector: "pptx-compare-panel", inputs: ["open", "compareResult", "canvasSize", "mediaDataUrls"], outputs: ["close", "acceptSlide", "rejectSlide", "acceptAll"] }, { kind: "component", type: FontEmbeddingPanelComponent, selector: "pptx-font-embedding-panel", inputs: ["open", "embedFontsEnabled", "usedFontFamilies", "embeddedFonts"], outputs: ["close", "toggleEmbedFonts"] }, { kind: "component", type: VersionHistoryPanelComponent, selector: "pptx-version-history-panel", inputs: ["open", "filePath"], outputs: ["close", "restore"] }, { kind: "component", type: ShortcutPanelComponent, selector: "pptx-shortcut-panel", inputs: ["open"], outputs: ["close"] }, { kind: "component", type: SettingsDialogComponent, selector: "pptx-settings-dialog", inputs: ["open", "settings", "themeKey", "availableThemes", "localeCode", "availableLocales"], outputs: ["settingsChange", "themeKeySelect", "localeSelect", "close"] }, { kind: "component", type: KeepAnnotationsDialogComponent, selector: "pptx-keep-annotations-dialog", inputs: ["open", "annotationCount", "slideCount"], outputs: ["keep", "discard"] }, { kind: "component", type: SignatureStrippedDialogComponent, selector: "pptx-signature-stripped-dialog", inputs: ["open", "signatureCount"], outputs: ["confirm", "cancel"] }, { kind: "component", type: HeaderFooterDialogComponent, selector: "pptx-header-footer-dialog", inputs: ["open", "value"], outputs: ["save", "close"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
97391
+ `, isInline: true, dependencies: [{ kind: "component", type: EquationEditorDialogComponent, selector: "pptx-equation-editor-dialog", inputs: ["open", "existingOmml"], outputs: ["insert", "close"] }, { kind: "component", type: SetUpSlideShowDialogComponent, selector: "pptx-set-up-slide-show-dialog", inputs: ["open", "properties", "customShows", "slideCount"], outputs: ["save", "close"] }, { kind: "component", type: PasswordProtectionDialogComponent, selector: "pptx-password-protection-dialog", inputs: ["open", "isCurrentlyProtected"], outputs: ["setPassword", "removePassword", "close"] }, { kind: "component", type: EncryptedFileDialogComponent, selector: "pptx-encrypted-file-dialog", inputs: ["open"], outputs: ["close"] }, { kind: "component", type: ComparePanelComponent, selector: "pptx-compare-panel", inputs: ["open", "compareResult", "canvasSize", "mediaDataUrls"], outputs: ["close", "acceptSlide", "rejectSlide", "acceptAll"] }, { kind: "component", type: FontEmbeddingPanelComponent, selector: "pptx-font-embedding-panel", inputs: ["open", "embedFontsEnabled", "usedFontFamilies", "embeddedFonts"], outputs: ["close", "toggleEmbedFonts"] }, { kind: "component", type: VersionHistoryPanelComponent, selector: "pptx-version-history-panel", inputs: ["open", "filePath"], outputs: ["close", "restore"] }, { kind: "component", type: ShortcutPanelComponent, selector: "pptx-shortcut-panel", inputs: ["open"], outputs: ["close"] }, { kind: "component", type: SettingsDialogComponent, selector: "pptx-settings-dialog", inputs: ["open", "options", "themeKey", "availableThemes", "localeCode", "availableLocales", "addinStatus"], outputs: ["optionChange", "restoreOptions", "ribbonTabHiddenChange", "quickAccessCommandsChange", "resetOptions", "clearCache", "themeKeySelect", "localeSelect", "close"] }, { kind: "component", type: KeepAnnotationsDialogComponent, selector: "pptx-keep-annotations-dialog", inputs: ["open", "annotationCount", "slideCount"], outputs: ["keep", "discard"] }, { kind: "component", type: SignatureStrippedDialogComponent, selector: "pptx-signature-stripped-dialog", inputs: ["open", "signatureCount"], outputs: ["confirm", "cancel"] }, { kind: "component", type: HeaderFooterDialogComponent, selector: "pptx-header-footer-dialog", inputs: ["open", "value"], outputs: ["save", "close"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
95150
97392
  }
95151
97393
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ViewerExtraDialogsComponent, decorators: [{
95152
97394
  type: Component,
@@ -95230,12 +97472,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
95230
97472
 
95231
97473
  <pptx-settings-dialog
95232
97474
  [open]="svc.showSettings()"
95233
- [settings]="settings()"
97475
+ [options]="viewerOpts.options()"
95234
97476
  [themeKey]="themeKey()"
95235
97477
  [availableThemes]="availableThemes()"
95236
97478
  [localeCode]="localeCode()"
95237
97479
  [availableLocales]="availableLocales()"
95238
- (settingsChange)="settingsChange.emit($event)"
97480
+ (optionChange)="viewerOpts.setValue($event.group, $event.key, $event.value)"
97481
+ (restoreOptions)="viewerOpts.restore($event)"
97482
+ (ribbonTabHiddenChange)="viewerOpts.setRibbonTabHidden($event.tabId, $event.hidden)"
97483
+ (quickAccessCommandsChange)="viewerOpts.setQuickAccessCommands($event)"
97484
+ (resetOptions)="viewerOpts.reset($event)"
97485
+ (clearCache)="onClearOptionsCache()"
95239
97486
  (themeKeySelect)="themeKeySelect.emit($event)"
95240
97487
  (localeSelect)="localeSelect.emit($event)"
95241
97488
  (close)="svc.showSettings.set(false)"
@@ -95264,7 +97511,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
95264
97511
  />
95265
97512
  `,
95266
97513
  }]
95267
- }], ctorParameters: () => [], propDecorators: { activeSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeSlideIndex", required: false }] }], selectedElementId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElementId", required: false }] }], filePath: [{ type: i0.Input, args: [{ isSignal: true, alias: "filePath", required: false }] }], customShows: [{ type: i0.Input, args: [{ isSignal: true, alias: "customShows", required: false }] }], settings: [{ type: i0.Input, args: [{ isSignal: true, alias: "settings", required: true }] }], themeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "themeKey", required: false }] }], availableThemes: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableThemes", required: false }] }], localeCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "localeCode", required: false }] }], availableLocales: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableLocales", required: false }] }], restoreContent: [{ type: i0.Output, args: ["restoreContent"] }], settingsChange: [{ type: i0.Output, args: ["settingsChange"] }], themeKeySelect: [{ type: i0.Output, args: ["themeKeySelect"] }], localeSelect: [{ type: i0.Output, args: ["localeSelect"] }] } });
97514
+ }], ctorParameters: () => [], propDecorators: { activeSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeSlideIndex", required: false }] }], selectedElementId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElementId", required: false }] }], filePath: [{ type: i0.Input, args: [{ isSignal: true, alias: "filePath", required: false }] }], customShows: [{ type: i0.Input, args: [{ isSignal: true, alias: "customShows", required: false }] }], themeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "themeKey", required: false }] }], availableThemes: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableThemes", required: false }] }], localeCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "localeCode", required: false }] }], availableLocales: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableLocales", required: false }] }], restoreContent: [{ type: i0.Output, args: ["restoreContent"] }], themeKeySelect: [{ type: i0.Output, args: ["themeKeySelect"] }], localeSelect: [{ type: i0.Output, args: ["localeSelect"] }] } });
95268
97515
 
95269
97516
  /**
95270
97517
  * PowerPointViewerComponent: Angular port of the React `PowerPointViewer.tsx`
@@ -95288,9 +97535,8 @@ class PowerPointViewerComponent {
95288
97535
  ...(ngDevMode ? [{ debugName: "content" }] : /* istanbul ignore next */ []));
95289
97536
  /** Licensed fonts supplied by the host application. No fonts are bundled. */
95290
97537
  fontsInput = input([], { ...(ngDevMode ? { debugName: "fontsInput" } : /* istanbul ignore next */ {}), alias: 'fonts' });
95291
- /** Whether editing actions are enabled. (Editor chrome not yet ported.) */
95292
- canEdit = input(false, /* @ts-ignore */
95293
- ...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
97538
+ /** Whether editing actions are enabled (host input; see {@link canEdit}). */
97539
+ canEditInput = input(false, { ...(ngDevMode ? { debugName: "canEditInput" } : /* istanbul ignore next */ {}), alias: 'canEdit' });
95294
97540
  /** Optional class applied to the root element. */
95295
97541
  class = input('', /* @ts-ignore */
95296
97542
  ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
@@ -95428,6 +97674,7 @@ class PowerPointViewerComponent {
95428
97674
  presenterWindow = inject(PresenterWindowService);
95429
97675
  destroyRef = inject(DestroyRef);
95430
97676
  dialogs = inject(ViewerDialogsService);
97677
+ viewerOpts = inject(ViewerOptionsService);
95431
97678
  compareSvc = inject(ViewerCompareService);
95432
97679
  xport = inject(ViewerExportService);
95433
97680
  findReplace = inject(ViewerFindReplaceService);
@@ -95459,6 +97706,13 @@ class PowerPointViewerComponent {
95459
97706
  /** The `<main>` host; used to locate the live `.pptx-ng-canvas-stage`. */
95460
97707
  mainEl = viewChild('mainEl', /* @ts-ignore */
95461
97708
  ...(ngDevMode ? [{ debugName: "mainEl" }] : /* istanbul ignore next */ []));
97709
+ /**
97710
+ * Effective edit permission: the host's `canEdit` input gated by Trust
97711
+ * Center > "Open presentations in Protected View", which forces the deck
97712
+ * read-only while enabled (File > Options wiring, mirrors PowerPoint).
97713
+ */
97714
+ canEdit = computed(() => this.canEditInput() && !this.viewerOpts.options().trust.openInProtectedView, /* @ts-ignore */
97715
+ ...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
95462
97716
  activeSlideIndex = signal(0, /* @ts-ignore */
95463
97717
  ...(ngDevMode ? [{ debugName: "activeSlideIndex" }] : /* istanbul ignore next */ []));
95464
97718
  /** Slides to display: the editable deck when `canEdit`, else the loaded deck. */
@@ -95609,7 +97863,10 @@ class PowerPointViewerComponent {
95609
97863
  /** User override that suppresses viewer animations and transitions. */
95610
97864
  reducedMotion = signal(false, /* @ts-ignore */
95611
97865
  ...(ngDevMode ? [{ debugName: "reducedMotion" }] : /* istanbul ignore next */ []));
95612
- /** Snapshot consumed by the settings dialog. */
97866
+ /**
97867
+ * The six legacy preference toggles as a snapshot, kept in a guarded
97868
+ * two-way sync with the File > Options store (see the constructor).
97869
+ */
95613
97870
  viewerSettings = computed(() => ({
95614
97871
  autoSave: this.autosaveEnabled(),
95615
97872
  spellCheck: this.spellCheck(),
@@ -95619,6 +97876,17 @@ class PowerPointViewerComponent {
95619
97876
  reducedMotion: this.reducedMotion(),
95620
97877
  }), /* @ts-ignore */
95621
97878
  ...(ngDevMode ? [{ debugName: "viewerSettings" }] : /* istanbul ignore next */ []));
97879
+ /**
97880
+ * Root class list: the host `class` input, the reduced-motion override, and
97881
+ * the option-driven display classes (`resolveOptionRootClasses`, so e.g.
97882
+ * hardware-acceleration and compatibility-display choices are styleable).
97883
+ */
97884
+ rootClasses = computed(() => [
97885
+ this.class(),
97886
+ this.reducedMotion() ? 'pptx-ng-reduced-motion' : '',
97887
+ ...this.viewerOpts.rootClasses(),
97888
+ ], /* @ts-ignore */
97889
+ ...(ngDevMode ? [{ debugName: "rootClasses" }] : /* istanbul ignore next */ []));
95622
97890
  /** Whether the Insert SmartArt gallery dialog is open. */
95623
97891
  showSmartArtInsert = signal(false, /* @ts-ignore */
95624
97892
  ...(ngDevMode ? [{ debugName: "showSmartArtInsert" }] : /* istanbul ignore next */ []));
@@ -95653,6 +97921,42 @@ class PowerPointViewerComponent {
95653
97921
  void this.translateService.use(initialLocale);
95654
97922
  }
95655
97923
  });
97924
+ // ── File > Options store ──────────────────────────────────────────
97925
+ // The full PowerPoint Options model lives in ViewerOptionsService
97926
+ // (persisted to localStorage by the shared store). The six legacy
97927
+ // ViewerSettings toggles stay the source of behavior; the two effects
97928
+ // below keep them and the store in sync BOTH ways without echoing:
97929
+ // each side only writes when the mapped values actually differ, and
97930
+ // signal writes are synchronous, so a store change lands on the legacy
97931
+ // signals before the reverse effect re-compares (and vice versa).
97932
+ effect(() => {
97933
+ // Options -> scattered legacy state (dialog edits, persisted values).
97934
+ const mapped = viewerOptionsToPreferences(this.viewerOpts.options());
97935
+ untracked(() => {
97936
+ const current = this.viewerSettings();
97937
+ for (const key of Object.keys(mapped)) {
97938
+ if (mapped[key] !== current[key]) {
97939
+ this.applyPreferenceSnapshot({ ...current, ...mapped });
97940
+ break;
97941
+ }
97942
+ }
97943
+ });
97944
+ });
97945
+ effect(() => {
97946
+ // Legacy state -> options (ribbon View toggles, title-bar autosave).
97947
+ const settings = this.viewerSettings();
97948
+ const current = this.viewerOpts.store.getOptions();
97949
+ const mapped = viewerOptionsToPreferences(current);
97950
+ let next = current;
97951
+ for (const key of Object.keys(mapped)) {
97952
+ if (mapped[key] !== settings[key]) {
97953
+ next = applyPreferenceToOptions(next, key, settings[key]);
97954
+ }
97955
+ }
97956
+ if (next !== current) {
97957
+ this.viewerOpts.store.setOptions(next);
97958
+ }
97959
+ });
95656
97960
  // Surface the `smartArt3D` opt-in to the element dispatcher via the
95657
97961
  // viewer-scoped SmartArt3DService.
95658
97962
  effect(() => {
@@ -95954,6 +98258,8 @@ class PowerPointViewerComponent {
95954
98258
  filePath: () => this.filePath(),
95955
98259
  isDirty: () => this.editor.dirty(),
95956
98260
  serialize: () => this.serializeForAutosave(),
98261
+ // Options > Save > "Save AutoRecover information every N minutes".
98262
+ intervalSeconds: () => this.viewerOpts.autosaveIntervalSeconds(),
95957
98263
  });
95958
98264
  }
95959
98265
  /**
@@ -96403,8 +98709,8 @@ class PowerPointViewerComponent {
96403
98709
  onRestoreVersion(bytes) {
96404
98710
  this.fileIO.contentOverride.set(bytes);
96405
98711
  }
96406
- /** Apply Settings dialog changes to the live editor state. */
96407
- onSettingsChange(settings) {
98712
+ /** Apply one legacy preference snapshot onto the scattered live signals. */
98713
+ applyPreferenceSnapshot(settings) {
96408
98714
  this.autosaveEnabled.set(settings.autoSave);
96409
98715
  this.spellCheck.set(settings.spellCheck);
96410
98716
  this.showGrid.set(settings.showGrid);
@@ -96412,6 +98718,41 @@ class PowerPointViewerComponent {
96412
98718
  this.snapToGrid.set(settings.snapToGrid);
96413
98719
  this.reducedMotion.set(settings.reducedMotion);
96414
98720
  }
98721
+ /** Dispatch a Quick Access Toolbar command id to its existing handler. */
98722
+ onQuickAccessCommand(id) {
98723
+ switch (id) {
98724
+ case 'save':
98725
+ void this.fileIO.saveAsPptx();
98726
+ break;
98727
+ case 'undo':
98728
+ this.editor.undo();
98729
+ break;
98730
+ case 'redo':
98731
+ this.editor.redo();
98732
+ break;
98733
+ case 'presentFromStart':
98734
+ this.presentationMode.presentFromBeginning();
98735
+ break;
98736
+ case 'print':
98737
+ this.print.openDialog();
98738
+ break;
98739
+ case 'exportPdf':
98740
+ void this.xport.exportPdf();
98741
+ break;
98742
+ case 'newSlide':
98743
+ this.editor.addSlide(this.activeSlideIndex());
98744
+ break;
98745
+ case 'spellCheck':
98746
+ this.spellCheck.update((enabled) => !enabled);
98747
+ break;
98748
+ case 'zoomIn':
98749
+ this.zoomSvc.zoomIn();
98750
+ break;
98751
+ case 'zoomOut':
98752
+ this.zoomSvc.zoomOut();
98753
+ break;
98754
+ }
98755
+ }
96415
98756
  /**
96416
98757
  * Mobile "Format" slot: surface the inspector for the current selection.
96417
98758
  * On mobile the format pane starts closed (React parity: the canvas owns
@@ -96475,10 +98816,10 @@ class PowerPointViewerComponent {
96475
98816
  return (this.mainEl()?.nativeElement.querySelector('.pptx-ng-canvas-stage') ?? undefined);
96476
98817
  }
96477
98818
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: PowerPointViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
96478
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: PowerPointViewerComponent, isStandalone: true, selector: "pptx-viewer", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, fontsInput: { classPropertyName: "fontsInput", publicName: "fonts", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, defaultThemeKey: { classPropertyName: "defaultThemeKey", publicName: "defaultThemeKey", isSignal: true, isRequired: false, transformFunction: null }, availableThemes: { classPropertyName: "availableThemes", publicName: "availableThemes", isSignal: true, isRequired: false, transformFunction: null }, onThemeChange: { classPropertyName: "onThemeChange", publicName: "onThemeChange", isSignal: true, isRequired: false, transformFunction: null }, defaultLocale: { classPropertyName: "defaultLocale", publicName: "defaultLocale", isSignal: true, isRequired: false, transformFunction: null }, availableLocales: { classPropertyName: "availableLocales", publicName: "availableLocales", isSignal: true, isRequired: false, transformFunction: null }, onLocaleChange: { classPropertyName: "onLocaleChange", publicName: "onLocaleChange", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null }, filePath: { classPropertyName: "filePath", publicName: "filePath", isSignal: true, isRequired: false, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, collaboration: { classPropertyName: "collaboration", publicName: "collaboration", isSignal: true, isRequired: false, transformFunction: null }, authorName: { classPropertyName: "authorName", publicName: "authorName", isSignal: true, isRequired: false, transformFunction: null }, shareDefaults: { classPropertyName: "shareDefaults", publicName: "shareDefaults", isSignal: true, isRequired: false, transformFunction: null }, onOpenFile: { classPropertyName: "onOpenFile", publicName: "onOpenFile", isSignal: true, isRequired: false, transformFunction: null }, smartArt3D: { classPropertyName: "smartArt3D", publicName: "smartArt3D", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeSlideChange: "activeSlideChange", dirtyChange: "dirtyChange", contentChange: "contentChange", propertiesChange: "propertiesChange", modeChange: "modeChange", zoomChange: "zoomChange", selectionChange: "selectionChange", slideCountChange: "slideCountChange", startCollaboration: "startCollaboration", stopCollaboration: "stopCollaboration" }, host: { listeners: { "document:keydown": "onKeyDown($event)" } }, providers: [...POWER_POINT_VIEWER_PROVIDERS], viewQueries: [{ propertyName: "extraDialogs", first: true, predicate: ViewerExtraDialogsComponent, descendants: true, isSignal: true }, { propertyName: "mainEl", first: true, predicate: ["mainEl"], descendants: true, isSignal: true }], ngImport: i0, template: `
98819
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: PowerPointViewerComponent, isStandalone: true, selector: "pptx-viewer", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, fontsInput: { classPropertyName: "fontsInput", publicName: "fonts", isSignal: true, isRequired: false, transformFunction: null }, canEditInput: { classPropertyName: "canEditInput", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, defaultThemeKey: { classPropertyName: "defaultThemeKey", publicName: "defaultThemeKey", isSignal: true, isRequired: false, transformFunction: null }, availableThemes: { classPropertyName: "availableThemes", publicName: "availableThemes", isSignal: true, isRequired: false, transformFunction: null }, onThemeChange: { classPropertyName: "onThemeChange", publicName: "onThemeChange", isSignal: true, isRequired: false, transformFunction: null }, defaultLocale: { classPropertyName: "defaultLocale", publicName: "defaultLocale", isSignal: true, isRequired: false, transformFunction: null }, availableLocales: { classPropertyName: "availableLocales", publicName: "availableLocales", isSignal: true, isRequired: false, transformFunction: null }, onLocaleChange: { classPropertyName: "onLocaleChange", publicName: "onLocaleChange", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null }, filePath: { classPropertyName: "filePath", publicName: "filePath", isSignal: true, isRequired: false, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, collaboration: { classPropertyName: "collaboration", publicName: "collaboration", isSignal: true, isRequired: false, transformFunction: null }, authorName: { classPropertyName: "authorName", publicName: "authorName", isSignal: true, isRequired: false, transformFunction: null }, shareDefaults: { classPropertyName: "shareDefaults", publicName: "shareDefaults", isSignal: true, isRequired: false, transformFunction: null }, onOpenFile: { classPropertyName: "onOpenFile", publicName: "onOpenFile", isSignal: true, isRequired: false, transformFunction: null }, smartArt3D: { classPropertyName: "smartArt3D", publicName: "smartArt3D", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeSlideChange: "activeSlideChange", dirtyChange: "dirtyChange", contentChange: "contentChange", propertiesChange: "propertiesChange", modeChange: "modeChange", zoomChange: "zoomChange", selectionChange: "selectionChange", slideCountChange: "slideCountChange", startCollaboration: "startCollaboration", stopCollaboration: "stopCollaboration" }, host: { listeners: { "document:keydown": "onKeyDown($event)" } }, providers: [...POWER_POINT_VIEWER_PROVIDERS], viewQueries: [{ propertyName: "extraDialogs", first: true, predicate: ViewerExtraDialogsComponent, descendants: true, isSignal: true }, { propertyName: "mainEl", first: true, predicate: ["mainEl"], descendants: true, isSignal: true }], ngImport: i0, template: `
96479
98820
  <div
96480
98821
  class="pptx-ng-viewer"
96481
- [ngClass]="[class(), reducedMotion() ? 'pptx-ng-reduced-motion' : '']"
98822
+ [ngClass]="rootClasses()"
96482
98823
  [ngStyle]="rootStyle()"
96483
98824
  [attr.aria-busy]="loader.loading()"
96484
98825
  >
@@ -96510,10 +98851,12 @@ class PowerPointViewerComponent {
96510
98851
  [redoLabel]="editor.redoLabel()"
96511
98852
  [findReplaceOpen]="findReplace.showFind() || findReplace.showFindReplace()"
96512
98853
  [hiddenActions]="hiddenActions()"
98854
+ [quickAccess]="viewerOpts.options().quickAccess"
96513
98855
  (toggleAutosave)="autosaveEnabled.update(v => !v)"
96514
98856
  (save)="fileIO.saveAsPptx()"
96515
98857
  (undo)="editor.undo()"
96516
98858
  (redo)="editor.redo()"
98859
+ (quickCommand)="onQuickAccessCommand($event)"
96517
98860
  (toggleFindReplace)="toggleFindReplace()"
96518
98861
  (commandSearch)="handleCommandSearch($event)"
96519
98862
  />
@@ -96983,13 +99326,11 @@ class PowerPointViewerComponent {
96983
99326
  [selectedElementId]="selectedElement()?.id ?? null"
96984
99327
  [filePath]="filePath()"
96985
99328
  [customShows]="customShowsCtl.pptxCustomShows()"
96986
- [settings]="viewerSettings()"
96987
99329
  [themeKey]="themeKey()"
96988
99330
  [availableThemes]="resolvedThemes()"
96989
99331
  [localeCode]="localeCode()"
96990
99332
  [availableLocales]="resolvedLocales()"
96991
99333
  (restoreContent)="onRestoreVersion($event)"
96992
- (settingsChange)="onSettingsChange($event)"
96993
99334
  (themeKeySelect)="selectThemeKey($event)"
96994
99335
  (localeSelect)="selectLocale($event)"
96995
99336
  />
@@ -97153,7 +99494,7 @@ class PowerPointViewerComponent {
97153
99494
  />
97154
99495
  }
97155
99496
  </div>
97156
- `, 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", "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"], outputs: ["closed"] }, { 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", "hiddenActions"], outputs: ["toggleMenu", "undo", "redo", "save", "present"] }, { kind: "component", type: MasterViewCanvasComponent, selector: "pptx-master-view-canvas", inputs: ["tab", "slideMasters", "activeMasterIndex", "activeLayoutIndex", "notesMaster", "handoutMaster", "canvasSize", "notesCanvasSize", "mediaDataUrls", "editable"], outputs: ["notesMasterChange", "handoutMasterChange"] }, { kind: "component", type: MasterViewSidebarComponent, selector: "pptx-master-view-sidebar", inputs: ["tab", "slideMasters", "notesMaster", "handoutMaster", "activeMasterIndex", "activeLayoutIndex", "handoutSlidesPerPage"], outputs: ["tabChange", "selectMaster", "selectLayout", "slidesPerPageChange", "backgroundChange", "close"] }, { kind: "component", type: NotesPanelComponent, selector: "pptx-notes-panel", inputs: ["slide", "expanded"], outputs: ["update", "notesToggle"] }, { kind: "component", type: RibbonComponent, selector: "pptx-ribbon", inputs: ["slideIndex", "slideCount", "canEdit", "selectedElement", "zoomPercent", "formatPainterActive", "canActivateFormatPainter", "exporting", "hasMacros", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "eyedropperActive", "themeGalleryOpen", "sidebarCollapsed", "inspectorOpen", "commentsOpen", "commentCount", "findOpen", "collabConnected", "connectedCount", "spellCheckEnabled", "showSubtitles", "hiddenActions", "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", "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"], outputs: ["toggleAutosave", "save", "undo", "redo", "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", "settings", "themeKey", "availableThemes", "localeCode", "availableLocales"], outputs: ["restoreContent", "settingsChange", "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 });
99497
+ `, 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", "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"], outputs: ["closed"] }, { 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", "hiddenActions"], outputs: ["toggleMenu", "undo", "redo", "save", "present"] }, { kind: "component", type: MasterViewCanvasComponent, selector: "pptx-master-view-canvas", inputs: ["tab", "slideMasters", "activeMasterIndex", "activeLayoutIndex", "notesMaster", "handoutMaster", "canvasSize", "notesCanvasSize", "mediaDataUrls", "editable"], outputs: ["notesMasterChange", "handoutMasterChange"] }, { kind: "component", type: MasterViewSidebarComponent, selector: "pptx-master-view-sidebar", inputs: ["tab", "slideMasters", "notesMaster", "handoutMaster", "activeMasterIndex", "activeLayoutIndex", "handoutSlidesPerPage"], outputs: ["tabChange", "selectMaster", "selectLayout", "slidesPerPageChange", "backgroundChange", "close"] }, { kind: "component", type: NotesPanelComponent, selector: "pptx-notes-panel", inputs: ["slide", "expanded"], outputs: ["update", "notesToggle"] }, { kind: "component", type: RibbonComponent, selector: "pptx-ribbon", inputs: ["slideIndex", "slideCount", "canEdit", "selectedElement", "zoomPercent", "formatPainterActive", "canActivateFormatPainter", "exporting", "hasMacros", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "eyedropperActive", "themeGalleryOpen", "sidebarCollapsed", "inspectorOpen", "commentsOpen", "commentCount", "findOpen", "collabConnected", "connectedCount", "spellCheckEnabled", "showSubtitles", "hiddenActions", "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", "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"], 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 });
97157
99498
  }
97158
99499
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: PowerPointViewerComponent, decorators: [{
97159
99500
  type: Component,
@@ -97209,7 +99550,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
97209
99550
  template: `
97210
99551
  <div
97211
99552
  class="pptx-ng-viewer"
97212
- [ngClass]="[class(), reducedMotion() ? 'pptx-ng-reduced-motion' : '']"
99553
+ [ngClass]="rootClasses()"
97213
99554
  [ngStyle]="rootStyle()"
97214
99555
  [attr.aria-busy]="loader.loading()"
97215
99556
  >
@@ -97241,10 +99582,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
97241
99582
  [redoLabel]="editor.redoLabel()"
97242
99583
  [findReplaceOpen]="findReplace.showFind() || findReplace.showFindReplace()"
97243
99584
  [hiddenActions]="hiddenActions()"
99585
+ [quickAccess]="viewerOpts.options().quickAccess"
97244
99586
  (toggleAutosave)="autosaveEnabled.update(v => !v)"
97245
99587
  (save)="fileIO.saveAsPptx()"
97246
99588
  (undo)="editor.undo()"
97247
99589
  (redo)="editor.redo()"
99590
+ (quickCommand)="onQuickAccessCommand($event)"
97248
99591
  (toggleFindReplace)="toggleFindReplace()"
97249
99592
  (commandSearch)="handleCommandSearch($event)"
97250
99593
  />
@@ -97714,13 +100057,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
97714
100057
  [selectedElementId]="selectedElement()?.id ?? null"
97715
100058
  [filePath]="filePath()"
97716
100059
  [customShows]="customShowsCtl.pptxCustomShows()"
97717
- [settings]="viewerSettings()"
97718
100060
  [themeKey]="themeKey()"
97719
100061
  [availableThemes]="resolvedThemes()"
97720
100062
  [localeCode]="localeCode()"
97721
100063
  [availableLocales]="resolvedLocales()"
97722
100064
  (restoreContent)="onRestoreVersion($event)"
97723
- (settingsChange)="onSettingsChange($event)"
97724
100065
  (themeKeySelect)="selectThemeKey($event)"
97725
100066
  (localeSelect)="selectLocale($event)"
97726
100067
  />
@@ -97886,7 +100227,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
97886
100227
  </div>
97887
100228
  `,
97888
100229
  }]
97889
- }], ctorParameters: () => [], propDecorators: { content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }], fontsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "fonts", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], defaultThemeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultThemeKey", required: false }] }], availableThemes: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableThemes", required: false }] }], onThemeChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "onThemeChange", required: false }] }], defaultLocale: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultLocale", required: false }] }], availableLocales: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableLocales", required: false }] }], onLocaleChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "onLocaleChange", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], filePath: [{ type: i0.Input, args: [{ isSignal: true, alias: "filePath", required: false }] }], fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], collaboration: [{ type: i0.Input, args: [{ isSignal: true, alias: "collaboration", required: false }] }], authorName: [{ type: i0.Input, args: [{ isSignal: true, alias: "authorName", required: false }] }], shareDefaults: [{ type: i0.Input, args: [{ isSignal: true, alias: "shareDefaults", required: false }] }], onOpenFile: [{ type: i0.Input, args: [{ isSignal: true, alias: "onOpenFile", required: false }] }], smartArt3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "smartArt3D", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], activeSlideChange: [{ type: i0.Output, args: ["activeSlideChange"] }], dirtyChange: [{ type: i0.Output, args: ["dirtyChange"] }], contentChange: [{ type: i0.Output, args: ["contentChange"] }], propertiesChange: [{ type: i0.Output, args: ["propertiesChange"] }], modeChange: [{ type: i0.Output, args: ["modeChange"] }], zoomChange: [{ type: i0.Output, args: ["zoomChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], slideCountChange: [{ type: i0.Output, args: ["slideCountChange"] }], startCollaboration: [{ type: i0.Output, args: ["startCollaboration"] }], stopCollaboration: [{ type: i0.Output, args: ["stopCollaboration"] }], extraDialogs: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ViewerExtraDialogsComponent), { isSignal: true }] }], mainEl: [{ type: i0.ViewChild, args: ['mainEl', { isSignal: true }] }], onKeyDown: [{
100230
+ }], ctorParameters: () => [], propDecorators: { content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }], fontsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "fonts", required: false }] }], canEditInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], defaultThemeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultThemeKey", required: false }] }], availableThemes: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableThemes", required: false }] }], onThemeChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "onThemeChange", required: false }] }], defaultLocale: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultLocale", required: false }] }], availableLocales: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableLocales", required: false }] }], onLocaleChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "onLocaleChange", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], filePath: [{ type: i0.Input, args: [{ isSignal: true, alias: "filePath", required: false }] }], fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], collaboration: [{ type: i0.Input, args: [{ isSignal: true, alias: "collaboration", required: false }] }], authorName: [{ type: i0.Input, args: [{ isSignal: true, alias: "authorName", required: false }] }], shareDefaults: [{ type: i0.Input, args: [{ isSignal: true, alias: "shareDefaults", required: false }] }], onOpenFile: [{ type: i0.Input, args: [{ isSignal: true, alias: "onOpenFile", required: false }] }], smartArt3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "smartArt3D", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], activeSlideChange: [{ type: i0.Output, args: ["activeSlideChange"] }], dirtyChange: [{ type: i0.Output, args: ["dirtyChange"] }], contentChange: [{ type: i0.Output, args: ["contentChange"] }], propertiesChange: [{ type: i0.Output, args: ["propertiesChange"] }], modeChange: [{ type: i0.Output, args: ["modeChange"] }], zoomChange: [{ type: i0.Output, args: ["zoomChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], slideCountChange: [{ type: i0.Output, args: ["slideCountChange"] }], startCollaboration: [{ type: i0.Output, args: ["startCollaboration"] }], stopCollaboration: [{ type: i0.Output, args: ["stopCollaboration"] }], extraDialogs: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ViewerExtraDialogsComponent), { isSignal: true }] }], mainEl: [{ type: i0.ViewChild, args: ['mainEl', { isSignal: true }] }], onKeyDown: [{
97890
100231
  type: HostListener,
97891
100232
  args: ['document:keydown', ['$event']]
97892
100233
  }] } });