pptx-angular-viewer 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@ import DOMPurify from 'dompurify';
7
7
  import { z } from 'zod';
8
8
  import * as mcp from 'pptx-viewer-mcp';
9
9
  import * as mcpSchemas from 'pptx-viewer-mcp/schemas';
10
- import { LucideX, LucideSquare, LucideCircle, LucideSlash, LucideCopy, LucideTrash2, LucideChevronsUp, LucideChevronsDown, LucideArrowUp, LucideArrowDown, LucideGroup, LucideUngroup, LucideTextAlignStart, LucideTextAlignCenter, LucideTextAlignEnd, LucideChevronUp, LucideChevronDown, LucideAlignHorizontalSpaceAround, LucideAlignVerticalSpaceAround, LucideLayers, LucideMessageSquare, LucidePlus, LucideSettings2, LucideStickyNote, LucideDownload, LucideMenu, LucidePresentation, LucideRedo, LucideShare2, LucideSparkles, LucideUndo, LucideChevronRight, LucideChevronLeft, LucideEraser, LucideHighlighter, LucideMousePointer2, LucidePanelRight, LucidePenTool, LucideTimer, LucideArrowLeftRight, LucideCaptions, LucideCirclePause, LucideCirclePlay, LucideGrid2x2, LucideMonitor, LucideMonitorOff, LucideRotateCcw, LucideScan, LucideZoomIn, LucideZoomOut, LucideStar, LucideMoveRight, LucidePlay, LucideMousePointerClick, LucidePaintbrush, LucideClock3, LucidePencil, LucideType, LucideMinus, LucideSpline, LucideArrowLeft, LucideFilePlus2, LucideFolderOpen, LucideHome, LucideInfo, LucidePrinter, LucideSave, LucideSettings, LucideUpload, LucideUserRound, LucideAArrowUp, LucideAArrowDown, LucideRemoveFormatting, LucideList, LucideListOrdered, LucideListIndentDecrease, LucideListIndentIncrease, LucideTextAlignJustify, LucideClipboardPaste, LucideFolderPlus, LucideLayoutGrid, LucideLayoutTemplate, LucideScissors, LucideLink, LucideImage, LucideVideo, LucideDatabase, LucidePanelLeft, LucideEllipsis, LucideEye, LucideEyeOff, LucideColumns2, LucideCheck, LucideFileDown, LucideSearch, LucideBug, LucideSend, LucideCrosshair, LucideGitMerge, LucidePin, LucidePinOff, LucideHistory, LucideMessageSquarePlus, LucideWrench, LucideLoaderCircle, LucideTriangleAlert, LucideShapes, LucidePalette, LucideTable, LucideChartColumn, LucideMove, LucideNavigation, LucideFilm, LucideBot, LucideUser } from '@lucide/angular';
10
+ import { LucideX, LucideSquare, LucideCircle, LucideSlash, LucideCopy, LucideTrash2, LucideChevronsUp, LucideChevronsDown, LucideArrowUp, LucideArrowDown, LucideGroup, LucideUngroup, LucideTextAlignStart, LucideTextAlignCenter, LucideTextAlignEnd, LucideChevronUp, LucideChevronDown, LucideAlignHorizontalSpaceAround, LucideAlignVerticalSpaceAround, LucideLayers, LucideMessageSquare, LucidePlus, LucideSettings2, LucideStickyNote, LucideDownload, LucideMenu, LucidePresentation, LucideRedo, LucideShare2, LucideSparkles, LucideUndo, LucideChevronRight, LucideChevronLeft, LucideEraser, LucideHighlighter, LucideMousePointer2, LucidePanelRight, LucidePenTool, LucideTimer, LucideArrowLeftRight, LucideCaptions, LucideCirclePause, LucideCirclePlay, LucideGrid2x2, LucideMonitor, LucideMonitorOff, LucideRotateCcw, LucideScan, LucideZoomIn, LucideZoomOut, LucideSave, LucidePlay, LucidePrinter, LucideFileDown, LucideSearch, LucideStar, LucideMoveRight, LucideMousePointerClick, LucidePaintbrush, LucideClock3, LucidePencil, LucideType, LucideMinus, LucideSpline, LucideArrowLeft, LucideFilePlus2, LucideFolderOpen, LucideHome, LucideInfo, LucideSettings, LucideUpload, LucideUserRound, LucideAArrowUp, LucideAArrowDown, LucideRemoveFormatting, LucideList, LucideListOrdered, LucideListIndentDecrease, LucideListIndentIncrease, LucideTextAlignJustify, LucideClipboardPaste, LucideFolderPlus, LucideLayoutGrid, LucideLayoutTemplate, LucideScissors, LucideLink, LucideImage, LucideVideo, LucideDatabase, LucidePanelLeft, LucideEllipsis, LucideEye, LucideEyeOff, LucideColumns2, LucideCheck, LucideBug, LucideSend, LucideCrosshair, LucideGitMerge, LucidePin, LucidePinOff, LucideHistory, LucideMessageSquarePlus, LucideWrench, LucideLoaderCircle, LucideTriangleAlert, LucideShapes, LucidePalette, LucideTable, LucideChartColumn, LucideMove, LucideNavigation, LucideFilm, LucideBot, LucideUser } from '@lucide/angular';
11
11
  import { XMLParser } from 'fast-xml-parser';
12
12
  import JSZip from 'jszip';
13
13
  import { DomSanitizer } from '@angular/platform-browser';
@@ -17067,10 +17067,15 @@ function buildParetoAxis(layout) {
17067
17067
 
17068
17068
  const CHART_TYPE_OPTIONS = [
17069
17069
  { value: 'bar', label: 'Bar', labelKey: 'pptx.chart.typeBar' },
17070
+ { value: 'bar3D', label: 'Bar (3-D)', labelKey: 'pptx.chart.typeBar3D' },
17070
17071
  { value: 'line', label: 'Line', labelKey: 'pptx.chart.typeLine' },
17072
+ { value: 'line3D', label: 'Line (3-D)', labelKey: 'pptx.chart.typeLine3D' },
17071
17073
  { value: 'pie', label: 'Pie', labelKey: 'pptx.chart.typePie' },
17074
+ { value: 'pie3D', label: 'Pie (3-D)', labelKey: 'pptx.chart.typePie3D' },
17072
17075
  { value: 'doughnut', label: 'Doughnut', labelKey: 'pptx.chart.typeDoughnut' },
17073
17076
  { value: 'area', label: 'Area', labelKey: 'pptx.chart.typeArea' },
17077
+ { value: 'area3D', label: 'Area (3-D)', labelKey: 'pptx.chart.typeArea3D' },
17078
+ { value: 'surface', label: 'Surface', labelKey: 'pptx.chart.typeSurface' },
17074
17079
  { value: 'scatter', label: 'Scatter', labelKey: 'pptx.chart.typeScatter' },
17075
17080
  { value: 'bubble', label: 'Bubble', labelKey: 'pptx.chart.typeBubble' },
17076
17081
  { value: 'radar', label: 'Radar', labelKey: 'pptx.chart.typeRadar' },
@@ -17826,12 +17831,21 @@ function removeChartSeries(data, seriesIndex) {
17826
17831
  function addChartCategory(data) {
17827
17832
  return chartDataAddCategory(data, `Cat ${data.categories.length + 1}`);
17828
17833
  }
17829
- /** Remove one category, or `null` when it is the last one. */
17830
- function removeChartCategory(data, categoryIndex) {
17834
+ /**
17835
+ * Remove one category, or `null` when it is the last one.
17836
+ *
17837
+ * `followDataPoint` mirrors File > Options > Advanced > "Properties follow
17838
+ * chart data point for current workbook" (`chartPropertiesFollowDataPoint`):
17839
+ * when `true` (the default, and PowerPoint's own default), each series'
17840
+ * per-point manual formatting re-indexes along with the removed column
17841
+ * instead of staying pinned to its old numeric position. See
17842
+ * `chartDataRemoveCategory`.
17843
+ */
17844
+ function removeChartCategory(data, categoryIndex, followDataPoint = true) {
17831
17845
  if (data.categories.length <= 1 || categoryIndex < 0 || categoryIndex >= data.categories.length) {
17832
17846
  return null;
17833
17847
  }
17834
- return chartDataRemoveCategory(data, categoryIndex);
17848
+ return chartDataRemoveCategory(data, categoryIndex, followDataPoint);
17835
17849
  }
17836
17850
  /** Rename one category label. */
17837
17851
  function setChartCategoryLabel(data, categoryIndex, label) {
@@ -32531,6 +32545,7 @@ const translationsEn = {
32531
32545
  // Print
32532
32546
  'pptx.print.title': 'Print',
32533
32547
  'pptx.print.printButton': 'Print',
32548
+ 'pptx.print.preparingToPrint': 'Preparing to print…',
32534
32549
  // Export
32535
32550
  'pptx.export.processing': 'Processing…',
32536
32551
  'pptx.export.cancel': 'Cancel',
@@ -33840,6 +33855,8 @@ const translationsEn = {
33840
33855
  'pptx.security.hidePassword': 'Hide password',
33841
33856
  'pptx.security.show': 'Show',
33842
33857
  'pptx.security.hide': 'Hide',
33858
+ 'pptx.security.protectedViewTitle': 'PROTECTED VIEW',
33859
+ 'pptx.security.enableEditing': 'Enable Editing',
33843
33860
  'pptx.ribbon.slideShowOptions': 'Slide show options',
33844
33861
  'pptx.ribbon.fromBeginning': 'From Beginning',
33845
33862
  'pptx.ribbon.presenterView': 'Presenter View',
@@ -34270,8 +34287,6 @@ const translationsEn = {
34270
34287
  'pptx.file.copyImageTooltip': 'Copy Slide as Image',
34271
34288
  'pptx.file.fonts': 'Fonts',
34272
34289
  'pptx.file.gif': 'GIF',
34273
- 'pptx.file.package': 'Package',
34274
- 'pptx.file.packageTooltip': 'Package for Sharing',
34275
34290
  'pptx.file.pdf': 'PDF',
34276
34291
  'pptx.file.png': 'PNG',
34277
34292
  'pptx.file.saveAsPpsx': 'Save .ppsx',
@@ -35065,6 +35080,8 @@ const translationsEn = {
35065
35080
  'pptx.options.advanced.display': 'Display',
35066
35081
  'pptx.options.advanced.recentCount': 'Show this number of Recent Presentations',
35067
35082
  'pptx.options.advanced.disableHardwareAcceleration': 'Disable hardware graphics acceleration',
35083
+ 'pptx.options.advanced.disable3DRendering': 'Disable 3D rendering (for performance)',
35084
+ 'pptx.options.advanced.disable3DRenderingInfo': 'Forces every 3D chart and SmartArt scene to fall back to flat 2D rendering, even in a presentation that enables 3D. Turn this on if 3D scenes run slowly on this device.',
35068
35085
  'pptx.options.advanced.openDocumentsView': 'Open all documents using this view',
35069
35086
  'pptx.options.openView.savedView': 'The view saved in the file',
35070
35087
  'pptx.options.openView.normal': 'Normal',
@@ -35374,8 +35391,6 @@ const translationsEn = {
35374
35391
  'pptx.backstage.card.saveAsPpsx.body': 'Save a .ppsx file that opens directly in slide show.',
35375
35392
  'pptx.backstage.card.saveAsPptm.title': 'Macro-Enabled Presentation',
35376
35393
  'pptx.backstage.card.saveAsPptm.body': 'Preserve VBA content in a .pptm file.',
35377
- 'pptx.backstage.card.package.title': 'Package for Sharing',
35378
- 'pptx.backstage.card.package.body': 'Bundle the presentation and linked assets.',
35379
35394
  'pptx.backstage.card.pdf.title': 'Create PDF',
35380
35395
  'pptx.backstage.card.pdf.body': 'Publish a portable document with one page per slide.',
35381
35396
  'pptx.backstage.card.png.title': 'Export current slide',
@@ -35392,8 +35407,6 @@ const translationsEn = {
35392
35407
  'pptx.backstage.card.print.body': 'Choose a printer, layout, copies, and output settings in your browser print dialog.',
35393
35408
  'pptx.backstage.card.share.title': 'Share with People',
35394
35409
  'pptx.backstage.card.share.body': 'Invite collaborators and work on the presentation together.',
35395
- 'pptx.backstage.card.sharePackage.title': 'Package for Sharing',
35396
- 'pptx.backstage.card.sharePackage.body': 'Download a self-contained package for offline sharing.',
35397
35410
  // OOXML wire tokens that controls used to render verbatim. Wording follows
35398
35411
  // PowerPoint's own dialogs; see `render/schema-label-keys.ts` for the
35399
35412
  // token -> key lookups these back.
@@ -48246,7 +48259,9 @@ function buildActiveSessionUsers(params) {
48246
48259
  const local = {
48247
48260
  id: 'local',
48248
48261
  name: params.localUserName,
48249
- initials: getUserInitials(params.localUserName),
48262
+ initials: params.localUserInitials?.trim()
48263
+ ? params.localUserInitials.trim().slice(0, 2).toUpperCase()
48264
+ : getUserInitials(params.localUserName),
48250
48265
  color: params.localUserColor ?? DEFAULT_LOCAL_COLOR,
48251
48266
  isLocal: true,
48252
48267
  }, remote = params.remoteUsers.map((user) => ({
@@ -61200,6 +61215,74 @@ function toggleBlackboard(blackout, tool) {
61200
61215
  : { blackout: 'black', tool: 'pen' };
61201
61216
  }
61202
61217
 
61218
+ /**
61219
+ * Slide-show right-click menu: shared item structure for every binding.
61220
+ *
61221
+ * PowerPoint shows a minimal Next/Previous/See All Slides/Presenter View menu
61222
+ * (plus pointer tools, blank-screen and End Presentation) when you right-click
61223
+ * during a slide show and Options > Advanced > "Show menu on right mouse
61224
+ * click" is on. React built the full menu first (`PresentationContextMenu`);
61225
+ * this module gives Vue/Angular/Svelte/Vanilla the same item order, grouping
61226
+ * and i18n keys instead of each hand-porting React's JSX structure and
61227
+ * drifting. A binding maps `getPresentationContextMenuSections` onto its own
61228
+ * menu component and wires each action id to whatever handler it already
61229
+ * uses for its toolbar's equivalent button; a capability the binding lacks
61230
+ * (e.g. no "See All Slides" grid) is simply left out of `capabilities`, and
61231
+ * the section/item is omitted rather than rendered disabled.
61232
+ */
61233
+ /**
61234
+ * Build the menu's sections for the given capabilities. Next/Previous/End
61235
+ * Presentation are always present (every binding can do those); everything
61236
+ * else is opt-in via `capabilities` so a binding missing the underlying
61237
+ * feature (e.g. Vue and Vanilla have no all-slides grid, Vue's toolbar only
61238
+ * supports a black screen) omits that item cleanly instead of rendering a
61239
+ * dead control.
61240
+ */
61241
+ function getPresentationContextMenuSections(capabilities) {
61242
+ const navItems = [
61243
+ { id: 'next', labelKey: 'pptx.presenter.nextSlide' },
61244
+ { id: 'previous', labelKey: 'pptx.presenter.previousSlide' },
61245
+ ];
61246
+ if (capabilities.seeAllSlides) {
61247
+ navItems.push({ id: 'seeAllSlides', labelKey: 'pptx.presenter.seeAllSlides' });
61248
+ }
61249
+ if (capabilities.presenterView) {
61250
+ navItems.push({ id: 'presenterView', labelKey: 'pptx.presenter.presenterView' });
61251
+ }
61252
+ const sections = [{ id: 'nav', items: navItems }];
61253
+ if (capabilities.pointerTools) {
61254
+ const pointerItems = [
61255
+ { id: 'pointerArrow', labelKey: 'pptx.presenter.pointerArrow' },
61256
+ { id: 'pointerPen', labelKey: 'pptx.presenter.pointerPen' },
61257
+ { id: 'pointerHighlighter', labelKey: 'pptx.presenter.pointerHighlighter' },
61258
+ { id: 'pointerLaser', labelKey: 'pptx.presentation.laserPointer' },
61259
+ ];
61260
+ if (capabilities.eraseInk) {
61261
+ pointerItems.push({ id: 'eraseInk', labelKey: 'pptx.presenter.eraseAllInk' });
61262
+ }
61263
+ sections.push({
61264
+ id: 'pointer',
61265
+ headingKey: 'pptx.presentation.pointerTools',
61266
+ items: pointerItems,
61267
+ });
61268
+ }
61269
+ if (capabilities.blankBlack || capabilities.blankWhite) {
61270
+ const blankItems = [];
61271
+ if (capabilities.blankBlack) {
61272
+ blankItems.push({ id: 'blankBlack', labelKey: 'pptx.presenter.blackScreen' });
61273
+ }
61274
+ if (capabilities.blankWhite) {
61275
+ blankItems.push({ id: 'blankWhite', labelKey: 'pptx.presenter.whiteScreen' });
61276
+ }
61277
+ sections.push({ id: 'screen', headingKey: 'pptx.presenter.screen', items: blankItems });
61278
+ }
61279
+ sections.push({
61280
+ id: 'end',
61281
+ items: [{ id: 'endShow', labelKey: 'pptx.presenter.endPresentation' }],
61282
+ });
61283
+ return sections;
61284
+ }
61285
+
61203
61286
  /**
61204
61287
  * The presenter view (PowerPoint's "presenter console"), described once for all
61205
61288
  * five bindings.
@@ -64850,6 +64933,11 @@ function runPresentationAction(action, options, runner) {
64850
64933
  runner.endShow();
64851
64934
  return true;
64852
64935
  case 'openUrl':
64936
+ // A declined confirmation still counts as "the click was spent on an
64937
+ // action", the same as an opened link: the show must not also advance.
64938
+ if (runner.confirmUrl && !runner.confirmUrl(intent.url)) {
64939
+ return true;
64940
+ }
64853
64941
  return safeOpenUrl(intent.url);
64854
64942
  default:
64855
64943
  return false;
@@ -70311,16 +70399,23 @@ function splitFilePath(path, translate) {
70311
70399
  * Recent autosave snapshots, newest first. `translate` only covers the two
70312
70400
  * fallback labels for a snapshot with no usable path; pass the binding's `t`
70313
70401
  * so those read in the user's language rather than English.
70402
+ *
70403
+ * @param limit File > Options > Advanced > "Quickly access this number of
70404
+ * Recent Documents" (`options.advanced.recentPresentationsCount`, 0-50).
70405
+ * Truncates the list to this many entries; `0` returns an empty list
70406
+ * (PowerPoint's own semantics for the setting). Omit to keep every stored
70407
+ * snapshot (existing callers that predate the option).
70314
70408
  */
70315
- async function listBackstageRecentFiles(translate) {
70409
+ async function listBackstageRecentFiles(translate, limit) {
70316
70410
  if (typeof indexedDB === 'undefined') {
70317
70411
  return [];
70318
70412
  }
70319
70413
  try {
70320
70414
  const snapshots = await listAutosaveSnapshots();
70321
- return snapshots
70415
+ const sorted = snapshots
70322
70416
  .map((snapshot) => ({ ...snapshot, ...splitFilePath(snapshot.key, translate) }))
70323
70417
  .sort((a, b) => b.timestamp - a.timestamp);
70418
+ return limit === undefined ? sorted : sorted.slice(0, Math.max(0, limit));
70324
70419
  }
70325
70420
  catch {
70326
70421
  return [];
@@ -70386,7 +70481,6 @@ const BACKSTAGE_CARDS = {
70386
70481
  saveAsPptx: card('saveAsPptx', 'PowerPoint Presentation', 'Save an editable .pptx copy.'),
70387
70482
  saveAsPpsx: card('saveAsPpsx', 'PowerPoint Show', 'Save a .ppsx file that opens directly in slide show.'),
70388
70483
  saveAsPptm: card('saveAsPptm', 'Macro-Enabled Presentation', 'Preserve VBA content in a .pptm file.'),
70389
- package: card('package', 'Package for Sharing', 'Bundle the presentation and linked assets.'),
70390
70484
  pdf: card('pdf', 'Create PDF', 'Publish a portable document with one page per slide.'),
70391
70485
  png: card('png', 'Export current slide', 'Create a high-quality PNG image.'),
70392
70486
  video: card('video', 'Create a Video', 'Export slide timings and animations as WebM.'),
@@ -70395,7 +70489,6 @@ const BACKSTAGE_CARDS = {
70395
70489
  copyImage: card('copyImage', 'Copy as Image', 'Copy the current slide to the clipboard.'),
70396
70490
  print: card('print', 'Print Presentation', 'Choose a printer, layout, copies, and output settings in your browser print dialog.'),
70397
70491
  share: card('share', 'Share with People', 'Invite collaborators and work on the presentation together.'),
70398
- sharePackage: card('sharePackage', 'Package for Sharing', 'Download a self-contained package for offline sharing.'),
70399
70492
  };
70400
70493
  /**
70401
70494
  * Which cards a backstage page shows, in order.
@@ -70407,10 +70500,10 @@ const BACKSTAGE_CARDS = {
70407
70500
  */
70408
70501
  const BACKSTAGE_PAGE_CARDS = {
70409
70502
  info: ['protect', 'inspect', 'embedFonts', 'signatures', 'versionHistory'],
70410
- saveAs: ['saveAsPptx', 'saveAsPpsx', 'saveAsPptm', 'package'],
70503
+ saveAs: ['saveAsPptx', 'saveAsPpsx', 'saveAsPptm'],
70411
70504
  export: ['pdf', 'png', 'video', 'gif', 'json', 'copyImage'],
70412
70505
  print: ['print'],
70413
- share: ['share', 'sharePackage'],
70506
+ share: ['share'],
70414
70507
  };
70415
70508
  /** The cards for a page, already resolved to their descriptors. */
70416
70509
  function backstageCardsFor(page) {
@@ -71846,6 +71939,21 @@ function resolveViewerAddinRows(status) {
71846
71939
  active: status?.[definition.id] ?? true,
71847
71940
  }));
71848
71941
  }
71942
+ /**
71943
+ * Build an Add-ins status map from the runtime signals every binding can
71944
+ * cheaply read: Options > Advanced > "Disable 3D rendering" (gates the two
71945
+ * three.js-backed renderers) and whether a collaboration session is live.
71946
+ * The remaining catalog entries (EMF/MTX converters, locales) have no
71947
+ * runtime on/off switch, so they are left out and fall back to `active: true`
71948
+ * in {@link resolveViewerAddinRows}.
71949
+ */
71950
+ function resolveViewerAddinStatus(disable3DRendering, collaborationActive) {
71951
+ return {
71952
+ smartArt3d: !disable3DRendering,
71953
+ model3d: !disable3DRendering,
71954
+ collaboration: collaborationActive,
71955
+ };
71956
+ }
71849
71957
 
71850
71958
  const DEFAULT_VIEWER_OPTIONS = {
71851
71959
  general: {
@@ -71904,6 +72012,7 @@ const DEFAULT_VIEWER_OPTIONS = {
71904
72012
  showGrid: false,
71905
72013
  snapToGrid: false,
71906
72014
  disableHardwareAcceleration: false,
72015
+ disable3DRendering: false,
71907
72016
  openDocumentsView: 'savedView',
71908
72017
  slideShowShowMenuOnRightClick: true,
71909
72018
  slideShowShowPopupToolbar: true,
@@ -72087,6 +72196,7 @@ function resolveDefaultPrintSettings(options) {
72087
72196
  printWhat: options.advanced.printWhat,
72088
72197
  colorMode: options.advanced.printColorMode,
72089
72198
  frameSlides: options.advanced.printFrameSlides,
72199
+ scaleToFit: options.advanced.printScaleToFit,
72090
72200
  };
72091
72201
  }
72092
72202
  /** Target raster density in ppi for image export; `undefined` = lossless/high fidelity. */
@@ -72123,6 +72233,31 @@ function shouldConfirmExternalHyperlink(options, href) {
72123
72233
  }
72124
72234
  return /^https?:/i.test(href);
72125
72235
  }
72236
+ /**
72237
+ * AND every host-supplied 3D opt-in flag with the viewer user's own
72238
+ * Options > Advanced > "Disable 3D rendering" override.
72239
+ *
72240
+ * The host prop says "this deck may render its 3D scenes"; a viewer user on
72241
+ * underpowered hardware needs a way to fall back to the flat 2D rendering
72242
+ * regardless of what the host wired up. Each binding should pass its raw
72243
+ * host props through this before feeding them to the SmartArt3D/*Chart3D
72244
+ * context/provider/service that actually gates the WebGL scenes, so the
72245
+ * override reaches every one of them uniformly instead of being wired (or
72246
+ * missed) six separate times.
72247
+ */
72248
+ function resolve3DRenderingFlags(hostFlags, options) {
72249
+ if (!options.advanced.disable3DRendering) {
72250
+ return hostFlags;
72251
+ }
72252
+ return {
72253
+ smartArt3D: false,
72254
+ surfaceChart3D: false,
72255
+ barChart3D: false,
72256
+ lineChart3D: false,
72257
+ areaChart3D: false,
72258
+ pieChart3D: false,
72259
+ };
72260
+ }
72126
72261
  /** CSS class list for the viewer root reflecting display-affecting options. */
72127
72262
  function resolveOptionRootClasses(options, prefix) {
72128
72263
  const classes = [];
@@ -72137,6 +72272,37 @@ function resolveOptionRootClasses(options, prefix) {
72137
72272
  }
72138
72273
  return classes;
72139
72274
  }
72275
+ /**
72276
+ * Whether a successful, explicit save should discard the AutoRecover
72277
+ * snapshot for the deck just saved.
72278
+ *
72279
+ * PowerPoint's default behavior: once the user has saved, the snapshot that
72280
+ * existed to recover unsaved work is stale (the file on disk already has it),
72281
+ * so it is dropped. Options > Save > "Keep the last autosaved version if I
72282
+ * close without saving" flips that off: the snapshot survives a successful
72283
+ * save too, in case the user wants to roll back to it later.
72284
+ */
72285
+ function shouldDiscardAutosaveOnSuccessfulSave(options) {
72286
+ return !options.save.keepLastAutoRecoveredVersion;
72287
+ }
72288
+ /** Whether Options > Save > "clear cache on close" should wipe recovery snapshots for this deck. */
72289
+ function shouldClearAutosaveCacheOnClose(options) {
72290
+ return options.save.clearCacheOnClose;
72291
+ }
72292
+ /**
72293
+ * Snapshot keys older than Options > Save > "cache retention" (days), for
72294
+ * periodic pruning. A non-positive or non-finite retention value prunes
72295
+ * nothing rather than everything, since it means the option could not be
72296
+ * read rather than "retain 0 days".
72297
+ */
72298
+ function resolveExpiredAutosaveSnapshots(snapshots, options, now = Date.now()) {
72299
+ const days = options.save.cacheRetentionDays;
72300
+ if (!Number.isFinite(days) || days <= 0) {
72301
+ return [];
72302
+ }
72303
+ const maxAgeMs = days * 24 * 60 * 60 * 1000;
72304
+ return snapshots.filter((snapshot) => now - snapshot.timestamp > maxAgeMs).map((s) => s.key);
72305
+ }
72140
72306
  /** Play the Accessibility > "feedback with sound" cue for a completed action. */
72141
72307
  function playFeedbackSound(options) {
72142
72308
  if (!options.accessibility.feedbackWithSound || typeof window === 'undefined') {
@@ -72255,6 +72421,9 @@ const ADVANCED_TAB = {
72255
72421
  toggle('advanced', 'showGrid', 'pptx.settings.showGrid'),
72256
72422
  toggle('advanced', 'snapToGrid', 'pptx.settings.snapToGrid'),
72257
72423
  toggle('advanced', 'disableHardwareAcceleration', 'pptx.options.advanced.disableHardwareAcceleration'),
72424
+ toggle('advanced', 'disable3DRendering', 'pptx.options.advanced.disable3DRendering', {
72425
+ infoKey: 'pptx.options.advanced.disable3DRenderingInfo',
72426
+ }),
72258
72427
  select('advanced', 'openDocumentsView', 'pptx.options.advanced.openDocumentsView', choices('pptx.options.openView', [
72259
72428
  'savedView',
72260
72429
  'normal',
@@ -72917,24 +73086,6 @@ function canvasToJpegData(canvas, quality = 0.92) {
72917
73086
  return { bytes, w: canvas.width, h: canvas.height };
72918
73087
  }
72919
73088
 
72920
- /** Build the README bundled with a presentation package-for-sharing archive. */
72921
- function generatePackageReadme(presentationFilename) {
72922
- return [
72923
- 'Presentation Package',
72924
- '====================',
72925
- '',
72926
- `This folder contains the presentation "${presentationFilename}" along with`,
72927
- 'all linked media files (images, audio, video) in the /media subfolder.',
72928
- '',
72929
- 'To view this presentation:',
72930
- '1. Open the presentation file with any compatible presentation software',
72931
- '2. Ensure the /media folder remains alongside the presentation file',
72932
- '',
72933
- `Packaged on ${new Date().toLocaleDateString()}`,
72934
- '',
72935
- ].join('\n');
72936
- }
72937
-
72938
73089
  /**
72939
73090
  * Minimal GIF89a encoder (pure JS, no external dependency) plus pure
72940
73091
  * frame-planning helpers — shared by the React, Vue, and Angular bindings.
@@ -73752,9 +73903,15 @@ function buildPrintStyleSheet(width, height, customCss) {
73752
73903
  * @param height Slide height in pixels.
73753
73904
  */
73754
73905
  function buildPrintDocument(svgs, width, height, options = {}) {
73755
- const { title = 'Print', orientation = 'landscape', colorFilter = '' } = options;
73906
+ const { title = 'Print', orientation = 'landscape', colorFilter = '', scaleToFit = true, } = options;
73756
73907
  const safeOrientation = sanitizeOrientation$1(orientation);
73757
73908
  const safeColorFilter = sanitizeCssDeclaration(colorFilter);
73909
+ // Options > Advanced > "Print scale to fit" off: render each slide SVG at
73910
+ // its native `width`/`height` instead of shrinking/growing it to fill the
73911
+ // page, matching PowerPoint's "Scale to Fit Paper" off.
73912
+ const svgSizeStyle = scaleToFit
73913
+ ? '.print-slide-page svg { max-width: 100%; max-height: 100%; width: auto; height: auto; }'
73914
+ : `.print-slide-page svg { max-width: none; max-height: none; width: ${width}px; height: ${height}px; }`;
73758
73915
  const slidePages = svgs
73759
73916
  .map((svg, i) => {
73760
73917
  // Belt-and-suspenders: the structural allow/deny-list guard runs
@@ -73792,12 +73949,7 @@ function buildPrintDocument(svgs, width, height, options = {}) {
73792
73949
  .print-slide-page:last-child {
73793
73950
  page-break-after: auto;
73794
73951
  }
73795
- .print-slide-page svg {
73796
- max-width: 100%;
73797
- max-height: 100%;
73798
- width: auto;
73799
- height: auto;
73800
- }
73952
+ ${svgSizeStyle}
73801
73953
  @page {
73802
73954
  size: ${safeOrientation};
73803
73955
  margin: 5mm;
@@ -74973,6 +75125,7 @@ const DEFAULT_PRINT_SETTINGS = {
74973
75125
  slideRange: 'all',
74974
75126
  customRangeFrom: 1,
74975
75127
  customRangeTo: 1,
75128
+ scaleToFit: true,
74976
75129
  };
74977
75130
  /** Number of ruled note lines drawn next to each slide in 3-per-page handouts. */
74978
75131
  const NOTE_LINE_COUNT = 8;
@@ -75022,6 +75175,7 @@ function validatePrintSettings(partial, slideCount) {
75022
75175
  slideRange: merged.slideRange,
75023
75176
  customRangeFrom: from,
75024
75177
  customRangeTo: to,
75178
+ scaleToFit: merged.scaleToFit ?? true,
75025
75179
  };
75026
75180
  }
75027
75181
  /**
@@ -75052,6 +75206,24 @@ function computeSlideIndices(slideRange, activeSlideIndex, slideCount, customRan
75052
75206
  }
75053
75207
  return Array.from({ length: slideCount }, (_, i) => i);
75054
75208
  }
75209
+ /**
75210
+ * Filter hidden slides out of a resolved index list, unless `includeHidden` is
75211
+ * set. Mirrors PowerPoint: slides marked "hidden" (skipped during normal
75212
+ * presentation) are excluded from print output by default too (Options >
75213
+ * Advanced > "Print hidden slides" turns that off).
75214
+ *
75215
+ * A post-filter over {@link computeSlideIndices}'s output rather than a new
75216
+ * parameter on that function: `computeSlideIndices` is called from every
75217
+ * binding's print path already and only ever received a `slideCount`, so
75218
+ * threading the slides array (or a hidden-flags array) through its signature
75219
+ * would be a breaking change to a widely-called function for one option.
75220
+ */
75221
+ function filterHiddenSlideIndices(indices, slides, includeHidden) {
75222
+ if (includeHidden) {
75223
+ return indices;
75224
+ }
75225
+ return indices.filter((index) => !slides[index]?.hidden);
75226
+ }
75055
75227
  /**
75056
75228
  * Number of slides selected by the given range. Custom ranges use 1-based,
75057
75229
  * inclusive `from`/`to` clamped to `[1, slideCount]`; an inverted range
@@ -75286,6 +75458,14 @@ function buildPrintHtmlDocument(options) {
75286
75458
  const frameStyle = frameSlides
75287
75459
  ? 'img.slide-img, .notes-slide, .handout-cell img { border: 2px solid #000 !important; }'
75288
75460
  : '';
75461
+ // Options > Advanced > "Print scale to fit" (also the Print dialog's own
75462
+ // setting when it exposes one). `false` drops the shrink/grow-to-fill
75463
+ // rules so each slide image prints at its native size instead: it may
75464
+ // overflow its page/cell (clipped by `.handout-cell`'s `overflow: hidden`)
75465
+ // or under-fill it, exactly like PowerPoint with "Scale to Fit Paper" off.
75466
+ const scaleToFitStyle = options.scaleToFit === false
75467
+ ? '.slide-page img.slide-img { max-width: none; max-height: none; width: auto; height: auto; } .handout-cell img { width: auto; height: auto; max-width: none; max-height: none; object-fit: none; }'
75468
+ : '';
75289
75469
  return `<!doctype html>
75290
75470
  <html>
75291
75471
  <head>
@@ -75328,12 +75508,83 @@ function buildPrintHtmlDocument(options) {
75328
75508
  img { break-inside: avoid; }
75329
75509
  }
75330
75510
  ${frameStyle}
75511
+ ${scaleToFitStyle}
75331
75512
  </style>
75332
75513
  </head>
75333
75514
  <body>${safeBodyHtml}</body>
75334
75515
  </html>`;
75335
75516
  }
75336
75517
 
75518
+ /**
75519
+ * DOM-touching print-window lifecycle, shared by every binding's raster
75520
+ * print path (`window.open`-based; the Svelte binding avoids all of this by
75521
+ * printing through a hidden iframe instead and has no need for it).
75522
+ *
75523
+ * `window.open` is only exempt from popup blocking while it runs as part of
75524
+ * the original user-gesture call stack; the instant a caller `await`s
75525
+ * anything first (rasterising slides one by one for notes/handouts), the
75526
+ * browser no longer considers the call gesture-initiated and silently blocks
75527
+ * it -- `window.open` just returns `null`, no error, no console warning. Each
75528
+ * binding's raster print path used to build its whole document before ever
75529
+ * calling `window.open`, so print silently did nothing the moment that build
75530
+ * crossed an `await`.
75531
+ *
75532
+ * The fix: open the window FIRST, synchronously, with a placeholder page,
75533
+ * then write the real document into that same window once it's ready. These
75534
+ * two functions are the whole fix; every binding's print handler just calls
75535
+ * them at the right points instead of re-implementing this dance itself.
75536
+ */
75537
+ /**
75538
+ * Open a blank print window right now, synchronously, still inside the
75539
+ * click's call stack, with a placeholder page. Returns `null` if the popup
75540
+ * was blocked (fully disabled popups, say) -- callers should surface that to
75541
+ * the user (e.g. "allow popups for this site to print") rather than silently
75542
+ * doing nothing.
75543
+ *
75544
+ * @param preparingLabel - Host-translated "Preparing to print…" text shown
75545
+ * in the placeholder while the real document is assembled.
75546
+ */
75547
+ function openPendingPrintWindow(preparingLabel) {
75548
+ const printWindow = window.open('', '_blank', 'noopener,noreferrer');
75549
+ if (!printWindow) {
75550
+ return null;
75551
+ }
75552
+ const safeLabel = escapeHtml(preparingLabel);
75553
+ printWindow.document.open();
75554
+ printWindow.document.write(`<!doctype html><title>${safeLabel}</title><body style="font:14px system-ui;color:#666;padding:2rem">${safeLabel}</body>`);
75555
+ printWindow.document.close();
75556
+ return printWindow;
75557
+ }
75558
+ /**
75559
+ * Write the final print document into an already-open print window (from
75560
+ * {@link openPendingPrintWindow}, or opened directly for a path that never
75561
+ * awaits anything first), focus it, and trigger the print dialog.
75562
+ */
75563
+ function finishPrintWindow(printWindow, htmlDocument) {
75564
+ printWindow.document.open();
75565
+ printWindow.document.write(htmlDocument);
75566
+ printWindow.document.close();
75567
+ printWindow.focus();
75568
+ setTimeout(() => {
75569
+ printWindow.print();
75570
+ }, 300);
75571
+ }
75572
+ /**
75573
+ * Open a print window and write a complete document into it in one
75574
+ * synchronous call. Only safe for a path that never `await`s before this
75575
+ * point (outline; direct SVG slides) -- one that does needs the
75576
+ * `openPendingPrintWindow`/`finishPrintWindow` split instead, called before
75577
+ * and after its `await`s respectively.
75578
+ */
75579
+ function openPrintWindow(htmlDocument) {
75580
+ const printWindow = window.open('', '_blank', 'noopener,noreferrer');
75581
+ if (!printWindow) {
75582
+ return false;
75583
+ }
75584
+ finishPrintWindow(printWindow, htmlDocument);
75585
+ return true;
75586
+ }
75587
+
75337
75588
  /**
75338
75589
  * Pure video (WebM) export planning helpers shared by every binding's video
75339
75590
  * export. Frame-segment timing, fps -> frame-interval maths, and MediaRecorder
@@ -77403,7 +77654,7 @@ function createLocalStorageBackend(namespace) {
77403
77654
  /** Try IndexedDB first; fall back to localStorage on any failure. */
77404
77655
  async function resolveBackend(dbName, namespace) {
77405
77656
  try {
77406
- const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-Bq0WpWA9.mjs');
77657
+ const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-B--KpLRw.mjs');
77407
77658
  const db = await openChatDb(dbName);
77408
77659
  return createIdbBackend(db);
77409
77660
  }
@@ -81610,6 +81861,164 @@ function createEditorSectionOperations(host) {
81610
81861
  * unchanged.
81611
81862
  */
81612
81863
 
81864
+ /**
81865
+ * viewer-options.service.ts: signal-based owner of the File > Options store for
81866
+ * one viewer instance (the Angular counterpart of React's `useViewerOptions`).
81867
+ *
81868
+ * Wraps the framework-neutral {@link createViewerOptionsStore} (which persists a
81869
+ * sparse diff into the shared `pptx-viewer-prefs` localStorage entry) behind an
81870
+ * Angular signal, and bundles the option-to-behavior helpers the rest of the
81871
+ * viewer consumes: history depth, autosave cadence, print defaults, screen
81872
+ * tips, root classes, AutoCorrect, feedback sounds, hyperlink confirmation,
81873
+ * protected view, and the Options > Save cache purge.
81874
+ *
81875
+ * Deliberately constructible with plain `new` (no required injection context)
81876
+ * so the colocated unit tests can exercise it without TestBed, matching
81877
+ * {@link EditorStateService}'s optional-inject pattern.
81878
+ */
81879
+ class ViewerOptionsService {
81880
+ constructor() {
81881
+ /**
81882
+ * Optional: `inject()` needs an active injection context, which plain
81883
+ * `new ViewerOptionsService()` (used by the colocated unit tests) does not
81884
+ * provide. Outside DI the subscription simply lives as long as the instance.
81885
+ */
81886
+ this.destroyRef = (() => {
81887
+ try {
81888
+ return inject(DestroyRef);
81889
+ }
81890
+ catch {
81891
+ return null;
81892
+ }
81893
+ })();
81894
+ this.translate = (() => {
81895
+ try {
81896
+ return inject(TranslateService);
81897
+ }
81898
+ catch {
81899
+ return null;
81900
+ }
81901
+ })();
81902
+ /** Imperative store: hydrates from and persists to `pptx-viewer-prefs`. */
81903
+ this.store = createViewerOptionsStore();
81904
+ this._options = signal(this.store.getOptions(), /* @ts-ignore */
81905
+ ...(ngDevMode ? [{ debugName: "_options" }] : /* istanbul ignore next */ []));
81906
+ /** Reactive File > Options snapshot; a new object per change. */
81907
+ this.options = this._options.asReadonly();
81908
+ const unsubscribe = this.store.subscribe((next) => this._options.set(next));
81909
+ this.destroyRef?.onDestroy(unsubscribe);
81910
+ }
81911
+ // ── Store mutations ─────────────────────────────────────────────────────
81912
+ setValue(group, key, value) {
81913
+ this.store.setValue(group, key, value);
81914
+ }
81915
+ setRibbonTabHidden(tabId, hidden) {
81916
+ this.store.setRibbonTabHidden(tabId, hidden);
81917
+ }
81918
+ setQuickAccessCommands(commandIds) {
81919
+ this.store.setQuickAccessCommands(commandIds);
81920
+ }
81921
+ reset(group) {
81922
+ this.store.reset(group);
81923
+ }
81924
+ /** Restore a snapshot wholesale (the dialog's Cancel semantics). */
81925
+ restore(snapshot) {
81926
+ this.store.setOptions(snapshot);
81927
+ }
81928
+ // ── Behavior resolution helpers ─────────────────────────────────────────
81929
+ /** Undo-stack depth for `new EditorHistory({ maxDepth })`. */
81930
+ historyDepth() {
81931
+ return resolveHistoryDepth(this.options());
81932
+ }
81933
+ /** AutoRecover cadence in seconds for the autosave engine. */
81934
+ autosaveIntervalSeconds() {
81935
+ return resolveAutosaveIntervalSeconds(this.options());
81936
+ }
81937
+ /**
81938
+ * Raster-scale multiplier for PNG/PDF export and copy-slide-as-image.
81939
+ * Multiplied against the pre-existing 2x baseline (not used outright) so
81940
+ * the default "High fidelity" preset (raw multiplier 1) keeps today's
81941
+ * export quality instead of silently downgrading it; the explicit ppi
81942
+ * presets still scale proportionally from that baseline. Mirrors the
81943
+ * vanilla/vue/svelte bindings.
81944
+ */
81945
+ imageExportScale() {
81946
+ return 2 * resolveImageResolutionScale(this.options());
81947
+ }
81948
+ /** Print-dialog seed; `undefined` keeps the dialog's own recents. */
81949
+ printDefaults() {
81950
+ return resolveDefaultPrintSettings(this.options());
81951
+ }
81952
+ /** Option-driven CSS classes for the viewer root (`pptx-ng-*` prefixed). */
81953
+ rootClasses() {
81954
+ return resolveOptionRootClasses(this.options(), 'pptx-ng');
81955
+ }
81956
+ /** Tooltip text under the current ScreenTip style (undefined = suppress). */
81957
+ screenTip(label, description, shortcut) {
81958
+ return resolveScreenTip(this.options(), label, description, shortcut);
81959
+ }
81960
+ /** Run the enabled AutoCorrect rules over a committed run of text. */
81961
+ autoCorrect(text) {
81962
+ return applyAutoCorrect(text, this.options().proofing);
81963
+ }
81964
+ /** Play the Accessibility "feedback with sound" cue for a completed action. */
81965
+ playFeedback() {
81966
+ playFeedbackSound(this.options());
81967
+ }
81968
+ /** Whether Trust Center forces the deck to open read-only. */
81969
+ protectedView() {
81970
+ return shouldOpenInProtectedView(this.options());
81971
+ }
81972
+ /**
81973
+ * Gate an external hyperlink activation. Returns `true` when navigation may
81974
+ * proceed (no confirmation required, or the user confirmed the prompt).
81975
+ */
81976
+ confirmExternalHyperlink(href) {
81977
+ if (!shouldConfirmExternalHyperlink(this.options(), href)) {
81978
+ return true;
81979
+ }
81980
+ if (typeof window === 'undefined' || typeof window.confirm !== 'function') {
81981
+ return true;
81982
+ }
81983
+ const label = this.translate?.instant('pptx.options.trust.confirmHyperlinks') ??
81984
+ 'Confirm before opening external hyperlinks';
81985
+ return window.confirm(`${label}\n\n${href}`);
81986
+ }
81987
+ /**
81988
+ * Options > Save > "Delete cached files": purge every autosave recovery
81989
+ * snapshot from the shared IndexedDB store. Resolves with the purge count.
81990
+ */
81991
+ async clearCache() {
81992
+ const snapshots = await listAutosaveSnapshots();
81993
+ await Promise.all(snapshots.map((entry) => deleteAutosaveSnapshot(entry.key)));
81994
+ return snapshots.length;
81995
+ }
81996
+ /**
81997
+ * Options > Save > "keep the last AutoRecover version": whether a
81998
+ * successful `.pptx` save should discard the AutoRecover snapshot for the
81999
+ * deck just saved (PowerPoint's default: the real file already has the
82000
+ * work, so the snapshot is stale unless the user asked to keep it).
82001
+ */
82002
+ shouldDiscardAutosaveOnSave() {
82003
+ return shouldDiscardAutosaveOnSuccessfulSave(this.options());
82004
+ }
82005
+ /** Options > Save > "clear cache on close": whether to wipe snapshots now. */
82006
+ shouldClearCacheOnClose() {
82007
+ return shouldClearAutosaveCacheOnClose(this.options());
82008
+ }
82009
+ /** Options > Save > "cache retention": prune snapshots older than N days. */
82010
+ async pruneExpiredCache() {
82011
+ const snapshots = await listAutosaveSnapshots();
82012
+ const expired = resolveExpiredAutosaveSnapshots(snapshots, this.options());
82013
+ await Promise.all(expired.map((key) => deleteAutosaveSnapshot(key)));
82014
+ }
82015
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ViewerOptionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
82016
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ViewerOptionsService }); }
82017
+ }
82018
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ViewerOptionsService, decorators: [{
82019
+ type: Injectable
82020
+ }], ctorParameters: () => [] });
82021
+
81613
82022
  /**
81614
82023
  * `LoadContentService`: Angular port of the React `useLoadContent` hook and
81615
82024
  * the Vue `useLoadContent` composable.
@@ -81784,6 +82193,19 @@ class LoadContentService {
81784
82193
  this.handler = null;
81785
82194
  this.renderToken = 0;
81786
82195
  this.activeBlobUrls = [];
82196
+ /**
82197
+ * Optional: `inject()` needs an active injection context, which the
82198
+ * colocated unit tests construct this service without. Trust Center >
82199
+ * "Allow external content" reads through this when present.
82200
+ */
82201
+ this.optionsService = (() => {
82202
+ try {
82203
+ return inject(ViewerOptionsService);
82204
+ }
82205
+ catch {
82206
+ return null;
82207
+ }
82208
+ })();
81787
82209
  inject(DestroyRef).onDestroy(() => {
81788
82210
  this.renderToken++;
81789
82211
  this.revokeBlobUrls(this.activeBlobUrls);
@@ -81874,7 +82296,11 @@ class LoadContentService {
81874
82296
  const sigBuffer = buffer.slice(0);
81875
82297
  const previousHandler = this.handler;
81876
82298
  const newHandler = new PptxHandler();
81877
- const parsed = await newHandler.load(buffer);
82299
+ // Trust Center > "Allow external content": gates linked (non-embedded)
82300
+ // http(s) image URLs. Defaults to blocked when the options service is
82301
+ // unreachable (e.g. constructed outside DI in a unit test).
82302
+ const allowExternalImages = this.optionsService?.options().trust.allowExternalContent ?? false;
82303
+ const parsed = await newHandler.load(buffer, { allowExternalImages });
81878
82304
  if (token !== this.renderToken) {
81879
82305
  newHandler.dispose();
81880
82306
  return;
@@ -82308,6 +82734,13 @@ class EditorStateService {
82308
82734
  ...(ngDevMode ? [{ debugName: "hasClipboard" }] : /* istanbul ignore next */ []));
82309
82735
  this.idCounter = 0;
82310
82736
  }
82737
+ /**
82738
+ * Apply File > Options > Advanced > "Maximum number of undos" at runtime.
82739
+ * Trims the past stack immediately if the new limit is smaller.
82740
+ */
82741
+ setHistoryDepth(depth) {
82742
+ this.history.setMaxDepth(depth);
82743
+ }
82311
82744
  /**
82312
82745
  * Resolve a translation. Outside an injection context (see {@link translate})
82313
82746
  * falls back to the canonical English dictionary text, then the raw key.
@@ -93650,6 +94083,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
93650
94083
  `, styles: [".pptx-ng-zoom-interactive{cursor:pointer}.pptx-ng-zoom-interactive:focus-visible{outline:2px solid #2563eb;outline-offset:2px}\n"] }]
93651
94084
  }], propDecorators: { element: [{ type: i0.Input, args: [{ isSignal: true, alias: "element", required: true }] }], zIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "zIndex", required: false }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], markElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "markElement", required: false }] }] } });
93652
94085
 
94086
+ /**
94087
+ * Trust Center > "Confirm before opening external hyperlinks" gate for a
94088
+ * text-run hyperlink click. `confirm` is `viewerOpts?.confirmExternalHyperlink`
94089
+ * (absent outside a `PowerPointViewerComponent` host, where a click is never
94090
+ * vetoed); returns `true` when the browser's default navigation must be
94091
+ * prevented. Exported (and pure) because this package has no TestBed.
94092
+ */
94093
+ function shouldPreventHyperlinkNavigation(confirm, href) {
94094
+ return confirm !== undefined && !confirm(href);
94095
+ }
93653
94096
  /**
93654
94097
  * ElementRendererComponent: Angular port of the React `ElementRenderer.tsx`
93655
94098
  * and the Vue `ElementRenderer.vue`.
@@ -93693,6 +94136,12 @@ class ElementRendererComponent {
93693
94136
  */
93694
94137
  this.playback = inject(AnimationPlaybackService, { optional: true });
93695
94138
  this.translate = inject(TranslateService);
94139
+ /**
94140
+ * Optional so this renderer still works outside a `PowerPointViewerComponent`
94141
+ * host (thumbnails, export): a text-run hyperlink click is then never
94142
+ * confirmed, matching the option's own default meaning ("not configured").
94143
+ */
94144
+ this.viewerOpts = inject(ViewerOptionsService, { optional: true });
93696
94145
  this.smartArt3D = computed(() => this.smartArt3DService?.enabled() ?? false, /* @ts-ignore */
93697
94146
  ...(ngDevMode ? [{ debugName: "smartArt3D" }] : /* istanbul ignore next */ []));
93698
94147
  /**
@@ -94046,6 +94495,18 @@ class ElementRendererComponent {
94046
94495
  }, /* @ts-ignore */
94047
94496
  ...(ngDevMode ? [{ debugName: "placeholderLabel" }] : /* istanbul ignore next */ []));
94048
94497
  }
94498
+ /**
94499
+ * Trust Center > "Confirm before opening external hyperlinks" gate for a
94500
+ * text-run hyperlink (`<a class="pptx-ng-link">`). The anchor's own `href` /
94501
+ * `target="_blank"` still does the actual navigation; this only vetoes it
94502
+ * via `preventDefault()` when the user declines the prompt.
94503
+ */
94504
+ onHyperlinkClick(event, href) {
94505
+ const confirm = this.viewerOpts?.confirmExternalHyperlink.bind(this.viewerOpts);
94506
+ if (shouldPreventHyperlinkNavigation(confirm, href)) {
94507
+ event.preventDefault();
94508
+ }
94509
+ }
94049
94510
  /** Whole-paragraph text, for the paragraph-level build wrapper. */
94050
94511
  paragraphText(para) {
94051
94512
  return para.runs.map((run) => run.text).join('');
@@ -94055,7 +94516,7 @@ class ElementRendererComponent {
94055
94516
  return { ...(span.style ?? {}), ...textBuildSpanStyle(span) };
94056
94517
  }
94057
94518
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ElementRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
94058
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: ElementRendererComponent, isStandalone: true, selector: "pptx-element-renderer", inputs: { element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, obstacles: { classPropertyName: "obstacles", publicName: "obstacles", isSignal: true, isRequired: false, transformFunction: null }, canvasWidth: { classPropertyName: "canvasWidth", publicName: "canvasWidth", isSignal: true, isRequired: false, transformFunction: null }, canvasHeight: { classPropertyName: "canvasHeight", publicName: "canvasHeight", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, marked: { classPropertyName: "marked", publicName: "marked", isSignal: true, isRequired: false, transformFunction: null }, exposeElementId: { classPropertyName: "exposeElementId", publicName: "exposeElementId", isSignal: true, isRequired: false, transformFunction: null }, presenting: { classPropertyName: "presenting", publicName: "presenting", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, fieldContext: { classPropertyName: "fieldContext", publicName: "fieldContext", isSignal: true, isRequired: false, transformFunction: null }, slideElements: { classPropertyName: "slideElements", publicName: "slideElements", isSignal: true, isRequired: false, transformFunction: null }, editTemplateMode: { classPropertyName: "editTemplateMode", publicName: "editTemplateMode", isSignal: true, isRequired: false, transformFunction: null }, parentGroupFill: { classPropertyName: "parentGroupFill", publicName: "parentGroupFill", isSignal: true, isRequired: false, transformFunction: null }, editingElementId: { classPropertyName: "editingElementId", publicName: "editingElementId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellCommit: "cellCommit", tableChange: "tableChange" }, host: { classAttribute: "contents" }, ngImport: i0, template: "@switch (true) {\n\t@case (isHidden()) {\n\t\t<!--\n\t\t\tHidden via the Selection Pane: draw nothing, exactly as PowerPoint\n\t\t\tdoes. This is the FIRST case on purpose - @switch takes the first\n\t\t\tmatch, so one empty branch suppresses every element type at once\n\t\t\twithout wrapping (and re-indenting) the whole template. The host\n\t\t\tcarries \\`display: contents\\`, so an empty component collapses.\n\t\t\tRendering nothing (rather than an invisible box) is what keeps the\n\t\t\telement out of hit-testing, the tab order and the export raster; it\n\t\t\tstays listed in and selectable from the Selection Pane, which reads\n\t\t\tthe slide model rather than the DOM.\n\t\t-->\n\t}\n\t@case (element().type === 'connector') {\n\t\t<pptx-connector-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[obstacles]=\"obstacles()\"\n\t\t\t[canvasWidth]=\"canvasWidth()\"\n\t\t\t[canvasHeight]=\"canvasHeight()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[animationState]=\"animationState()\"\n\t\t/>\n\t}\n\t@case (element().type === 'ink') {\n\t\t<!--\n\t\t\tThis renderer (and zoom / model3d / 3D SmartArt below) positions its\n\t\t\town root box, so it takes the neutral element marker\n\t\t\t(data-pptx-element) as an input instead of being wrapped in a marked\n\t\t\tbox the way chart / table / OLE are: an outer positioned box would\n\t\t\toffset it twice.\n\t\t-->\n\t\t<pptx-ink-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'contentPart') {\n\t\t<!--\n\t\t\tReal PowerPoint ink. Same positioning contract as pptx-ink-renderer\n\t\t\tabove: the renderer's own root is absolutely positioned, so it takes\n\t\t\tthe neutral element marker as an input rather than being wrapped.\n\t\t-->\n\t\t<pptx-content-part-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'zoom') {\n\t\t<pptx-zoom-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'model3d') {\n\t\t<pptx-model3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt' && smartArt3D()) {\n\t\t<pptx-smart-art-3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[canEdit]=\"interactive() && editable()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-smartart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-smart-art-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'ole') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-ole\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-ole-renderer [element]=\"element()\" />\n\t\t</div>\n\t}\n\t@case (element().type === 'chart') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-chart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-chart-element-view\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'table') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-table\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-table-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t(cellCommit)=\"cellCommit.emit({ id: element().id, commit: $event })\"\n\t\t\t\t(tableChange)=\"tableChange.emit($event)\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'group') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-group\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t@for (child of children(); track child.id) {\n\t\t\t\t<pptx-element-renderer\n\t\t\t\t\t[element]=\"child\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zIndex]=\"$index\"\n\t\t\t\t\t[interactive]=\"interactive()\"\n\t\t\t\t\t[marked]=\"marked()\"\n\t\t\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t\t\t[presenting]=\"presenting()\"\n\t\t\t\t\t[fieldContext]=\"fieldContext()\"\n\t\t\t\t\t[slideElements]=\"slideElements()\"\n\t\t\t\t\t[parentGroupFill]=\"childParentGroupFill()\"\n\t\t\t\t\t[editingElementId]=\"editingElementId()\"\n\t\t\t\t/>\n\t\t\t}\n\t\t</div>\n\t}\n\t@case (isImageLike()) {\n\t\t<pptx-image-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'media') {\n\t\t<pptx-media-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[presenting]=\"presenting()\"\n\t\t\t[placeholderLabel]=\"placeholderLabel()\"\n\t\t/>\n\t}\n\t@case (isShapeLike()) {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-shape\"\n\t\t\t[ngStyle]=\"shapeContainerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n\t\t\t open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n\t\t\t geometry whose sub-paths cannot share one CSS background-color. -->\n\t\t\t@if (subpathFill(); as sf) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-subpath-fill\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"subpathFillViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n\t\t\t\t>\n\t\t\t\t\t@for (paint of sf.paints; track $index) {\n\t\t\t\t\t\t<path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t@if (fillOverlay(); as ov) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-fill-overlay\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; pointer-events: none\"\n\t\t\t\t\t[style.background]=\"ov.color\"\n\t\t\t\t\t[style.mix-blend-mode]=\"ov.blendMode\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t<!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n\t\t\t the `-webkit-box-reflect` this replaced (Firefox never implemented\n\t\t\t that property, so reflections were invisible there entirely). -->\n\t\t\t@if (reflection(); as refl) {\n\t\t\t\t<div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n\t\t\t\t\t@if (refl.imgSrc) {\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t[src]=\"refl.imgSrc\"\n\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\tdraggable=\"false\"\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[ngStyle]=\"refl.imgFitStyle\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t} @else if (refl.fill) {\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[style.background-color]=\"refl.fill.backgroundColor\"\n\t\t\t\t\t\t\t[style.background-image]=\"refl.fill.backgroundImage\"\n\t\t\t\t\t\t\t[style.background-size]=\"refl.fill.backgroundSize\"\n\t\t\t\t\t\t\t[style.background-position]=\"refl.fill.backgroundPosition\"\n\t\t\t\t\t\t\t[style.background-repeat]=\"refl.fill.backgroundRepeat\"\n\t\t\t\t\t\t></div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n\t\t\t on its outline only, so its interior lets clicks through. -->\n\t\t\t@if (hollowHit(); as hit) {\n\t\t\t\t<svg\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\t[attr.d]=\"hit.d\"\n\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\tstroke=\"transparent\"\n\t\t\t\t\t\t[attr.stroke-width]=\"hit.strokeWidth\"\n\t\t\t\t\t\tstyle=\"pointer-events: stroke\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- Stroked outline: a CSS border takes one flat colour, and cannot\n\t\t\t outline an open preset (`line`, `arc`) at all. -->\n\t\t\t@if (gradientOutline(); as go) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-gradient-outline\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t@if (go.paint; as paint) {\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@if (paint.kind === 'pattern') {\n\t\t\t\t\t\t\t\t<pattern\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\tpatternUnits=\"userSpaceOnUse\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<image\n\t\t\t\t\t\t\t\t\t\t[attr.href]=\"paint.href\"\n\t\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</pattern>\n\t\t\t\t\t\t\t} @else if (paint.kind === 'radial') {\n\t\t\t\t\t\t\t\t<radialGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.cx]=\"paint.cx\"\n\t\t\t\t\t\t\t\t\t[attr.cy]=\"paint.cy\"\n\t\t\t\t\t\t\t\t\t[attr.r]=\"paint.r\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</radialGradient>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<linearGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.x1]=\"paint.x1\"\n\t\t\t\t\t\t\t\t\t[attr.y1]=\"paint.y1\"\n\t\t\t\t\t\t\t\t\t[attr.x2]=\"paint.x2\"\n\t\t\t\t\t\t\t\t\t[attr.y2]=\"paint.y2\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</linearGradient>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t}\n\t\t\t\t\t@for (strand of go.strands; track $index) {\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t[attr.d]=\"go.d\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t[attr.stroke]=\"go.stroke\"\n\t\t\t\t\t\t\t[attr.stroke-width]=\"strand.strokeWidth\"\n\t\t\t\t\t\t\t[attr.stroke-dasharray]=\"go.dashArray\"\n\t\t\t\t\t\t\t[attr.stroke-linecap]=\"go.lineCap\"\n\t\t\t\t\t\t\t[attr.stroke-linejoin]=\"go.lineJoin\"\n\t\t\t\t\t\t\t[style.transform]=\"\n\t\t\t\t\t\t\t\tstrand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\n\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- While this element is open in the inline text editor, its live text\n\t\t\t is drawn by that overlay instead (see `isBeingInlineEdited`);\n\t\t\t rendering it here too produced a duplicate, offset \"text shadow\"\n\t\t\t (issue #182). -->\n\t\t\t@if (!isBeingInlineEdited()) {\n\t\t\t\t@if (pathWarp(); as warp) {\n\t\t\t\t\t<svg\n\t\t\t\t\t\t[attr.width]=\"warp.width\"\n\t\t\t\t\t\t[attr.height]=\"warp.height\"\n\t\t\t\t\t\t[attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n\t\t\t\t\t\tstyle=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t\t<path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t[attr.font-size]=\"warp.baseFontSize\"\n\t\t\t\t\t\t\t\t[attr.font-family]=\"warp.baseFontFamily\"\n\t\t\t\t\t\t\t\t[attr.fill]=\"warp.baseColor\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<textPath\n\t\t\t\t\t\t\t\t\t[attr.href]=\"'#' + line.pathId\"\n\t\t\t\t\t\t\t\t\t[attr.startOffset]=\"warp.startOffset\"\n\t\t\t\t\t\t\t\t\t[attr.text-anchor]=\"warp.textAnchor\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (seg of line.segments; track $index) {\n\t\t\t\t\t\t\t\t\t\t<tspan\n\t\t\t\t\t\t\t\t\t\t\t[attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{{ seg.text }}\n\t\t\t\t\t\t\t\t\t\t</tspan>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</textPath>\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t}\n\t\t\t\t\t</svg>\n\t\t\t\t} @else if (hasText()) {\n\t\t\t\t\t<div class=\"pptx-ng-text\" [ngStyle]=\"warpedTextStyle()\">\n\t\t\t\t\t\t@for (para of paragraphs(); track $index) {\n\t\t\t\t\t\t\t<p\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-para\"\n\t\t\t\t\t\t\t\t[ngStyle]=\"para.paragraphStyle ?? null\"\n\t\t\t\t\t\t\t\t[style.padding-left.px]=\"para.indentPx\"\n\t\t\t\t\t\t\t\t[style.text-indent.px]=\"para.textIndentPx ?? null\"\n\t\t\t\t\t\t\t\t[style.line-height]=\"para.lineHeight ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-top.px]=\"para.spaceBeforePx ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-bottom.px]=\"para.spaceAfterPx ?? null\"\n\t\t\t\t\t\t\t\t[style.font-size.px]=\"para.strutFontSizePx ?? null\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t@if (para.bulletPicture?.src) {\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet-image\"\n\t\t\t\t\t\t\t\t\t\t[src]=\"para.bulletPicture.src\"\n\t\t\t\t\t\t\t\t\t\t[alt]=\"para.bulletPicture.accessibleLabel\"\n\t\t\t\t\t\t\t\t\t\t[style.width.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\t[style.height.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\tstyle=\"\n\t\t\t\t\t\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t\t\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\t\t\t\t\t\t\tmargin-inline-end: 4px;\n\t\t\t\t\t\t\t\t\t\t\tobject-fit: contain;\n\t\t\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t} @else if (para.bulletMarker) {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet\"\n\t\t\t\t\t\t\t\t\t\t[ngStyle]=\"para.bulletStyle\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"para.bulletPicture?.accessibleLabel ?? null\"\n\t\t\t\t\t\t\t\t\t\t>{{ para.bulletMarker }}</span\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (textBuildSpecs()[$index]; as spec) {\n\t\t\t\t\t\t\t\t\t<!-- Staged text build: render the split pieces so each one\n\t\t\t\t\t\t\t\t carries its own sub-animation. -->\n\t\t\t\t\t\t\t\t\t@if (spec.granularity === 'paragraph') {\n\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"spec.animId\" [ngStyle]=\"buildSpanStyle(spec)\">{{\n\t\t\t\t\t\t\t\t\t\t\tparagraphText(para)\n\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t@for (span of spec.spans ?? []; track $index) {\n\t\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"span.animId\" [ngStyle]=\"buildSpanStyle(span)\">{{\n\t\t\t\t\t\t\t\t\t\t\t\tspan.text\n\t\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t@for (run of para.runs; track $index) {\n\t\t\t\t\t\t\t\t\t\t@if (run.equationXml) {\n\t\t\t\t\t\t\t\t\t\t\t<pptx-equation-renderer\n\t\t\t\t\t\t\t\t\t\t\t\t[equationXml]=\"run.equationXml\"\n\t\t\t\t\t\t\t\t\t\t\t\t[equationNumber]=\"run.equationNumber\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t} @else if (\n\t\t\t\t\t\t\t\t\t\t\trun.text ===\n\t\t\t\t\t\t\t\t\t\t\t'\n'\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t\t\t} @else if (run.reflection; as refl) {\n\t\t\t\t\t\t\t\t\t\t\t<!-- `a:reflection`: wrapped HERE, around the whole base\n\t\t\t\t\t\t\t\t\t\t run (`runBase`), rather than inside its href/ruby/plain\n\t\t\t\t\t\t\t\t\t\t branches - a `<ruby>` run's own `display: ruby` (which\n\t\t\t\t\t\t\t\t\t\t positions the annotation above its base text) would\n\t\t\t\t\t\t\t\t\t\t break if forced to `display: inline-block` to host the\n\t\t\t\t\t\t\t\t\t\t mirror. Cross-browser, unlike the `-webkit-box-reflect`\n\t\t\t\t\t\t\t\t\t\t this replaced (Firefox never implemented it). -->\n\t\t\t\t\t\t\t\t\t\t\t<span style=\"position: relative; display: inline-block\">\n\t\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-text-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t><span [ngStyle]=\"run.style\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t><ng-container\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t*ngTemplateOutlet=\"runContent; context: { run: run }\" /></span\n\t\t\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (para.isEmpty) {\n\t\t\t\t\t\t\t\t\t<!-- An authored blank line has no runs, so without this the\n\t\t\t\t\t\t\t\t <p> collapses to zero height and the gap a deck puts\n\t\t\t\t\t\t\t\t between a heading and its bullet list disappears. -->\n\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t}\n\t@default {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-unsupported\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<div class=\"pptx-ng-placeholder\">{{ placeholderLabel() }}</div>\n\t\t</div>\n\t}\n}\n\n<!-- Soft-edge feather <filter> def, referenced via filter: url(#soft-edge-<id>). -->\n@if (softEdgeFilter(); as sef) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter\n\t\t\t\t[attr.id]=\"sef.id\"\n\t\t\t\tx=\"-20%\"\n\t\t\t\ty=\"-20%\"\n\t\t\t\twidth=\"140%\"\n\t\t\t\theight=\"140%\"\n\t\t\t\tcolor-interpolation-filters=\"sRGB\"\n\t\t\t>\n\t\t\t\t<feGaussianBlur in=\"SourceAlpha\" [attr.stdDeviation]=\"sef.radius\" result=\"softEdgeAlpha\" />\n\t\t\t\t<feComposite in=\"SourceGraphic\" in2=\"softEdgeAlpha\" operator=\"in\" />\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!-- Duotone image-effect <filter> def, referenced via filter: url(#id). -->\n@if (duotoneFilter(); as df) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter [attr.id]=\"df.id\" color-interpolation-filters=\"sRGB\">\n\t\t\t\t<feColorMatrix type=\"matrix\" [attr.values]=\"df.primitives[0].values\" />\n\t\t\t\t<feComponentTransfer>\n\t\t\t\t\t<feFuncR\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[0].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[0].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncG\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[1].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[1].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncB\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[2].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[2].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t</feComponentTransfer>\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!--\n\tOne run's base element (hyperlink / ruby / plain span), reused via\n\t`ngTemplateOutlet` both directly and inside the `a:reflection` wrapper above,\n\tso the reflection case does not duplicate this three-way branch.\n-->\n<ng-template #runBase let-run=\"run\">\n\t@if (run.href) {\n\t\t<a\n\t\t\tclass=\"pptx-ng-link\"\n\t\t\t[href]=\"run.href\"\n\t\t\ttarget=\"_blank\"\n\t\t\trel=\"noopener noreferrer\"\n\t\t\t[attr.title]=\"run.tooltip ?? null\"\n\t\t\t[ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></a>\n\t} @else if (run.rubyText) {\n\t\t<!-- `a:ruby`: the phonetic guide sits above its base\n\t\t text; the <rp> parentheses are the fallback for a\n\t\t browser without ruby support. -->\n\t\t<ruby [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\" /><rp>(</rp\n\t\t\t><rt [ngStyle]=\"run.rubyStyle\">{{ run.rubyText }}</rt\n\t\t\t><rp>)</rp></ruby\n\t\t>\n\t} @else {\n\t\t<span [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></span>\n\t}\n</ng-template>\n\n<!--\n\tA run's text content, honouring shared's per-script font split\n\t(`run.scriptRuns`) and measured tab-stop layout (`run.tabLines`) when\n\teither is present. Both descriptors come from `pptx-viewer-shared`'s\n\t`buildParagraphs` (the per-script split was React-only before this\n\ttemplate existed: CJK, Arabic, Hebrew and Thai text rendered in the wrong\n\ttypeface here; the tab layout was likewise React-only, so a TOC-style row\n\tlost its leader dots and right-aligned page number). Reused via\n\t`ngTemplateOutlet` for the run's span / anchor / ruby base text, so all\n\tthree carry the same content logic.\n-->\n<ng-template #runContent let-run=\"run\">\n\t@if (run.tabLines) {\n\t\t@for (line of run.tabLines; track $index) {\n\t\t\t<span style=\"display: inline-block; white-space: nowrap\">\n\t\t\t\t@for (piece of line.pieces; track $index) {\n\t\t\t\t\t@if (piece.leaderStyle) {\n\t\t\t\t\t\t<span aria-hidden=\"true\" [ngStyle]=\"piece.leaderStyle\">{{ piece.leaderText }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t\t}\n\t\t\t</span>\n\t\t\t@if (!$last) {\n\t\t\t\t<br />\n\t\t\t}\n\t\t}\n\t} @else if (run.scriptRuns) {\n\t\t<!--\n\t\t\tA bare interpolation as the sole content of an `@if`/`@else` block\n\t\t\tleaks a real leading + trailing whitespace text node: Angular does\n\t\t\tnot collapse that whitespace the way it collapses whitespace between\n\t\t\telement TAGS. Worse, oxfmt's Angular-template printer always breaks a\n\t\t\tblock's content onto its own indented line, even when the block was\n\t\t\twritten as a single line with the braces touching, so writing the\n\t\t\t`{{ x }}` compact ourselves does not survive the next `bun run fmt` /\n\t\t\tpre-commit `lint-staged` pass: it silently re-introduces the leak\n\t\t\t(this happened twice, see `20d4d177`, `18eebb6f`). `<ng-container>`\n\t\t\tdoes not render any DOM node of its own, so wrapping the\n\t\t\tinterpolation in one keeps the no-wrapper-element behaviour of\n\t\t\tReact's `<>{piece.text}</>` fragment while making the interpolation\n\t\t\ttag-adjacent, which both Angular AND oxfmt already treat as safely\n\t\t\tcollapsible (see the many `<span>{{ x }}</span>` one-liners in this\n\t\t\tfile). That was invisible while a paragraph was one run per script\n\t\t\t(two stray spaces at the run's own edges, trimmed visually by the\n\t\t\tbrowser but still present in `textContent`), but shared's per-word /\n\t\t\tper-gap metric split (`text-run-spacing.ts`, issue #149) re-emits\n\t\t\tevery WORD and inter-word GAP as its own sibling run, so the same\n\t\t\tone-space leak lands between every word: \"will choose\" rendered as\n\t\t\t\"will choose\" (five spaces: the word's own trailing leak, the\n\t\t\tgap run's real space plus its OWN two leaks, the next word's leading\n\t\t\tleak). The same leak also showed up one paragraph at a time:\n\t\t\t\"Project\" / \"Atlas\" as two separate paragraphs read back as\n\t\t\t\"ProjectAtlas\" instead of React's \"Project Atlas\", because the\n\t\t\tplain-run `@else` below had the same bug.\n\t\t-->\n\t\t@for (piece of run.scriptRuns; track $index) {\n\t\t\t@if (piece.style) {\n\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t} @else {\n\t\t\t\t<ng-container>{{ piece.text }}</ng-container>\n\t\t\t}\n\t\t}\n\t} @else {\n\t\t<ng-container>{{ run.text }}</ng-container>\n\t}\n</ng-template>\n", dependencies: [{ kind: "component", type: ElementRendererComponent, selector: "pptx-element-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "obstacles", "canvasWidth", "canvasHeight", "interactive", "marked", "exposeElementId", "presenting", "editable", "fieldContext", "slideElements", "editTemplateMode", "parentGroupFill", "editingElementId"], outputs: ["cellCommit", "tableChange"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ConnectorRendererComponent, selector: "pptx-connector-renderer", inputs: ["element", "zIndex", "obstacles", "canvasWidth", "canvasHeight", "interactive", "marked", "exposeElementId", "animationState"] }, { kind: "component", type: TableRendererComponent, selector: "pptx-table-renderer", inputs: ["element", "editable"], outputs: ["cellCommit", "tableChange"] }, { kind: "component", type: ChartElementViewComponent, selector: "pptx-chart-element-view", inputs: ["element", "editable", "animationState"] }, { kind: "component", type: SmartArtRendererComponent, selector: "pptx-smart-art-renderer", inputs: ["element", "editable", "animationState"] }, { kind: "component", type: SmartArt3DRendererComponent, selector: "pptx-smart-art-3d-renderer", inputs: ["element", "zIndex", "canEdit", "markElement"] }, { kind: "component", type: InkRendererComponent, selector: "pptx-ink-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "replay", "markElement", "exposeElementId"] }, { kind: "component", type: ContentPartRendererComponent, selector: "pptx-content-part-renderer", inputs: ["element", "zIndex", "replay", "markElement", "exposeElementId"] }, { kind: "component", type: MediaRendererComponent, selector: "pptx-media-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "interactive", "marked", "exposeElementId", "presenting", "placeholderLabel"] }, { kind: "component", type: OleRendererComponent, selector: "pptx-ole-renderer", inputs: ["element"] }, { kind: "component", type: Model3DRendererComponent, selector: "pptx-model3d-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "interactive", "markElement", "exposeElementId"] }, { kind: "component", type: ZoomRendererComponent, selector: "pptx-zoom-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "markElement"] }, { kind: "component", type: EquationRendererComponent, selector: "pptx-equation-renderer", inputs: ["equationXml", "equationNumber"] }, { kind: "component", type: ImageRendererComponent, selector: "pptx-image-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "interactive", "marked", "exposeElementId"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
94519
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: ElementRendererComponent, isStandalone: true, selector: "pptx-element-renderer", inputs: { element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, obstacles: { classPropertyName: "obstacles", publicName: "obstacles", isSignal: true, isRequired: false, transformFunction: null }, canvasWidth: { classPropertyName: "canvasWidth", publicName: "canvasWidth", isSignal: true, isRequired: false, transformFunction: null }, canvasHeight: { classPropertyName: "canvasHeight", publicName: "canvasHeight", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, marked: { classPropertyName: "marked", publicName: "marked", isSignal: true, isRequired: false, transformFunction: null }, exposeElementId: { classPropertyName: "exposeElementId", publicName: "exposeElementId", isSignal: true, isRequired: false, transformFunction: null }, presenting: { classPropertyName: "presenting", publicName: "presenting", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, fieldContext: { classPropertyName: "fieldContext", publicName: "fieldContext", isSignal: true, isRequired: false, transformFunction: null }, slideElements: { classPropertyName: "slideElements", publicName: "slideElements", isSignal: true, isRequired: false, transformFunction: null }, editTemplateMode: { classPropertyName: "editTemplateMode", publicName: "editTemplateMode", isSignal: true, isRequired: false, transformFunction: null }, parentGroupFill: { classPropertyName: "parentGroupFill", publicName: "parentGroupFill", isSignal: true, isRequired: false, transformFunction: null }, editingElementId: { classPropertyName: "editingElementId", publicName: "editingElementId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellCommit: "cellCommit", tableChange: "tableChange" }, host: { classAttribute: "contents" }, ngImport: i0, template: "@switch (true) {\n\t@case (isHidden()) {\n\t\t<!--\n\t\t\tHidden via the Selection Pane: draw nothing, exactly as PowerPoint\n\t\t\tdoes. This is the FIRST case on purpose - @switch takes the first\n\t\t\tmatch, so one empty branch suppresses every element type at once\n\t\t\twithout wrapping (and re-indenting) the whole template. The host\n\t\t\tcarries \\`display: contents\\`, so an empty component collapses.\n\t\t\tRendering nothing (rather than an invisible box) is what keeps the\n\t\t\telement out of hit-testing, the tab order and the export raster; it\n\t\t\tstays listed in and selectable from the Selection Pane, which reads\n\t\t\tthe slide model rather than the DOM.\n\t\t-->\n\t}\n\t@case (element().type === 'connector') {\n\t\t<pptx-connector-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[obstacles]=\"obstacles()\"\n\t\t\t[canvasWidth]=\"canvasWidth()\"\n\t\t\t[canvasHeight]=\"canvasHeight()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[animationState]=\"animationState()\"\n\t\t/>\n\t}\n\t@case (element().type === 'ink') {\n\t\t<!--\n\t\t\tThis renderer (and zoom / model3d / 3D SmartArt below) positions its\n\t\t\town root box, so it takes the neutral element marker\n\t\t\t(data-pptx-element) as an input instead of being wrapped in a marked\n\t\t\tbox the way chart / table / OLE are: an outer positioned box would\n\t\t\toffset it twice.\n\t\t-->\n\t\t<pptx-ink-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'contentPart') {\n\t\t<!--\n\t\t\tReal PowerPoint ink. Same positioning contract as pptx-ink-renderer\n\t\t\tabove: the renderer's own root is absolutely positioned, so it takes\n\t\t\tthe neutral element marker as an input rather than being wrapped.\n\t\t-->\n\t\t<pptx-content-part-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'zoom') {\n\t\t<pptx-zoom-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'model3d') {\n\t\t<pptx-model3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt' && smartArt3D()) {\n\t\t<pptx-smart-art-3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[canEdit]=\"interactive() && editable()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-smartart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-smart-art-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'ole') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-ole\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-ole-renderer [element]=\"element()\" />\n\t\t</div>\n\t}\n\t@case (element().type === 'chart') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-chart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-chart-element-view\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'table') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-table\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-table-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t(cellCommit)=\"cellCommit.emit({ id: element().id, commit: $event })\"\n\t\t\t\t(tableChange)=\"tableChange.emit($event)\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'group') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-group\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t@for (child of children(); track child.id) {\n\t\t\t\t<pptx-element-renderer\n\t\t\t\t\t[element]=\"child\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zIndex]=\"$index\"\n\t\t\t\t\t[interactive]=\"interactive()\"\n\t\t\t\t\t[marked]=\"marked()\"\n\t\t\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t\t\t[presenting]=\"presenting()\"\n\t\t\t\t\t[fieldContext]=\"fieldContext()\"\n\t\t\t\t\t[slideElements]=\"slideElements()\"\n\t\t\t\t\t[parentGroupFill]=\"childParentGroupFill()\"\n\t\t\t\t\t[editingElementId]=\"editingElementId()\"\n\t\t\t\t/>\n\t\t\t}\n\t\t</div>\n\t}\n\t@case (isImageLike()) {\n\t\t<pptx-image-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'media') {\n\t\t<pptx-media-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[presenting]=\"presenting()\"\n\t\t\t[placeholderLabel]=\"placeholderLabel()\"\n\t\t/>\n\t}\n\t@case (isShapeLike()) {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-shape\"\n\t\t\t[ngStyle]=\"shapeContainerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n\t\t\t open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n\t\t\t geometry whose sub-paths cannot share one CSS background-color. -->\n\t\t\t@if (subpathFill(); as sf) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-subpath-fill\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"subpathFillViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n\t\t\t\t>\n\t\t\t\t\t@for (paint of sf.paints; track $index) {\n\t\t\t\t\t\t<path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t@if (fillOverlay(); as ov) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-fill-overlay\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; pointer-events: none\"\n\t\t\t\t\t[style.background]=\"ov.color\"\n\t\t\t\t\t[style.mix-blend-mode]=\"ov.blendMode\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t<!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n\t\t\t the `-webkit-box-reflect` this replaced (Firefox never implemented\n\t\t\t that property, so reflections were invisible there entirely). -->\n\t\t\t@if (reflection(); as refl) {\n\t\t\t\t<div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n\t\t\t\t\t@if (refl.imgSrc) {\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t[src]=\"refl.imgSrc\"\n\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\tdraggable=\"false\"\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[ngStyle]=\"refl.imgFitStyle\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t} @else if (refl.fill) {\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[style.background-color]=\"refl.fill.backgroundColor\"\n\t\t\t\t\t\t\t[style.background-image]=\"refl.fill.backgroundImage\"\n\t\t\t\t\t\t\t[style.background-size]=\"refl.fill.backgroundSize\"\n\t\t\t\t\t\t\t[style.background-position]=\"refl.fill.backgroundPosition\"\n\t\t\t\t\t\t\t[style.background-repeat]=\"refl.fill.backgroundRepeat\"\n\t\t\t\t\t\t></div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n\t\t\t on its outline only, so its interior lets clicks through. -->\n\t\t\t@if (hollowHit(); as hit) {\n\t\t\t\t<svg\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\t[attr.d]=\"hit.d\"\n\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\tstroke=\"transparent\"\n\t\t\t\t\t\t[attr.stroke-width]=\"hit.strokeWidth\"\n\t\t\t\t\t\tstyle=\"pointer-events: stroke\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- Stroked outline: a CSS border takes one flat colour, and cannot\n\t\t\t outline an open preset (`line`, `arc`) at all. -->\n\t\t\t@if (gradientOutline(); as go) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-gradient-outline\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t@if (go.paint; as paint) {\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@if (paint.kind === 'pattern') {\n\t\t\t\t\t\t\t\t<pattern\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\tpatternUnits=\"userSpaceOnUse\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<image\n\t\t\t\t\t\t\t\t\t\t[attr.href]=\"paint.href\"\n\t\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</pattern>\n\t\t\t\t\t\t\t} @else if (paint.kind === 'radial') {\n\t\t\t\t\t\t\t\t<radialGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.cx]=\"paint.cx\"\n\t\t\t\t\t\t\t\t\t[attr.cy]=\"paint.cy\"\n\t\t\t\t\t\t\t\t\t[attr.r]=\"paint.r\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</radialGradient>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<linearGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.x1]=\"paint.x1\"\n\t\t\t\t\t\t\t\t\t[attr.y1]=\"paint.y1\"\n\t\t\t\t\t\t\t\t\t[attr.x2]=\"paint.x2\"\n\t\t\t\t\t\t\t\t\t[attr.y2]=\"paint.y2\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</linearGradient>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t}\n\t\t\t\t\t@for (strand of go.strands; track $index) {\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t[attr.d]=\"go.d\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t[attr.stroke]=\"go.stroke\"\n\t\t\t\t\t\t\t[attr.stroke-width]=\"strand.strokeWidth\"\n\t\t\t\t\t\t\t[attr.stroke-dasharray]=\"go.dashArray\"\n\t\t\t\t\t\t\t[attr.stroke-linecap]=\"go.lineCap\"\n\t\t\t\t\t\t\t[attr.stroke-linejoin]=\"go.lineJoin\"\n\t\t\t\t\t\t\t[style.transform]=\"\n\t\t\t\t\t\t\t\tstrand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\n\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- While this element is open in the inline text editor, its live text\n\t\t\t is drawn by that overlay instead (see `isBeingInlineEdited`);\n\t\t\t rendering it here too produced a duplicate, offset \"text shadow\"\n\t\t\t (issue #182). -->\n\t\t\t@if (!isBeingInlineEdited()) {\n\t\t\t\t@if (pathWarp(); as warp) {\n\t\t\t\t\t<svg\n\t\t\t\t\t\t[attr.width]=\"warp.width\"\n\t\t\t\t\t\t[attr.height]=\"warp.height\"\n\t\t\t\t\t\t[attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n\t\t\t\t\t\tstyle=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t\t<path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t[attr.font-size]=\"warp.baseFontSize\"\n\t\t\t\t\t\t\t\t[attr.font-family]=\"warp.baseFontFamily\"\n\t\t\t\t\t\t\t\t[attr.fill]=\"warp.baseColor\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<textPath\n\t\t\t\t\t\t\t\t\t[attr.href]=\"'#' + line.pathId\"\n\t\t\t\t\t\t\t\t\t[attr.startOffset]=\"warp.startOffset\"\n\t\t\t\t\t\t\t\t\t[attr.text-anchor]=\"warp.textAnchor\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (seg of line.segments; track $index) {\n\t\t\t\t\t\t\t\t\t\t<tspan\n\t\t\t\t\t\t\t\t\t\t\t[attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{{ seg.text }}\n\t\t\t\t\t\t\t\t\t\t</tspan>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</textPath>\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t}\n\t\t\t\t\t</svg>\n\t\t\t\t} @else if (hasText()) {\n\t\t\t\t\t<div class=\"pptx-ng-text\" [ngStyle]=\"warpedTextStyle()\">\n\t\t\t\t\t\t@for (para of paragraphs(); track $index) {\n\t\t\t\t\t\t\t<p\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-para\"\n\t\t\t\t\t\t\t\t[ngStyle]=\"para.paragraphStyle ?? null\"\n\t\t\t\t\t\t\t\t[style.padding-left.px]=\"para.indentPx\"\n\t\t\t\t\t\t\t\t[style.text-indent.px]=\"para.textIndentPx ?? null\"\n\t\t\t\t\t\t\t\t[style.line-height]=\"para.lineHeight ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-top.px]=\"para.spaceBeforePx ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-bottom.px]=\"para.spaceAfterPx ?? null\"\n\t\t\t\t\t\t\t\t[style.font-size.px]=\"para.strutFontSizePx ?? null\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t@if (para.bulletPicture?.src) {\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet-image\"\n\t\t\t\t\t\t\t\t\t\t[src]=\"para.bulletPicture.src\"\n\t\t\t\t\t\t\t\t\t\t[alt]=\"para.bulletPicture.accessibleLabel\"\n\t\t\t\t\t\t\t\t\t\t[style.width.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\t[style.height.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\tstyle=\"\n\t\t\t\t\t\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t\t\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\t\t\t\t\t\t\tmargin-inline-end: 4px;\n\t\t\t\t\t\t\t\t\t\t\tobject-fit: contain;\n\t\t\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t} @else if (para.bulletMarker) {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet\"\n\t\t\t\t\t\t\t\t\t\t[ngStyle]=\"para.bulletStyle\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"para.bulletPicture?.accessibleLabel ?? null\"\n\t\t\t\t\t\t\t\t\t\t>{{ para.bulletMarker }}</span\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (textBuildSpecs()[$index]; as spec) {\n\t\t\t\t\t\t\t\t\t<!-- Staged text build: render the split pieces so each one\n\t\t\t\t\t\t\t\t carries its own sub-animation. -->\n\t\t\t\t\t\t\t\t\t@if (spec.granularity === 'paragraph') {\n\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"spec.animId\" [ngStyle]=\"buildSpanStyle(spec)\">{{\n\t\t\t\t\t\t\t\t\t\t\tparagraphText(para)\n\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t@for (span of spec.spans ?? []; track $index) {\n\t\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"span.animId\" [ngStyle]=\"buildSpanStyle(span)\">{{\n\t\t\t\t\t\t\t\t\t\t\t\tspan.text\n\t\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t@for (run of para.runs; track $index) {\n\t\t\t\t\t\t\t\t\t\t@if (run.equationXml) {\n\t\t\t\t\t\t\t\t\t\t\t<pptx-equation-renderer\n\t\t\t\t\t\t\t\t\t\t\t\t[equationXml]=\"run.equationXml\"\n\t\t\t\t\t\t\t\t\t\t\t\t[equationNumber]=\"run.equationNumber\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t} @else if (\n\t\t\t\t\t\t\t\t\t\t\trun.text ===\n\t\t\t\t\t\t\t\t\t\t\t'\n'\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t\t\t} @else if (run.reflection; as refl) {\n\t\t\t\t\t\t\t\t\t\t\t<!-- `a:reflection`: wrapped HERE, around the whole base\n\t\t\t\t\t\t\t\t\t\t run (`runBase`), rather than inside its href/ruby/plain\n\t\t\t\t\t\t\t\t\t\t branches - a `<ruby>` run's own `display: ruby` (which\n\t\t\t\t\t\t\t\t\t\t positions the annotation above its base text) would\n\t\t\t\t\t\t\t\t\t\t break if forced to `display: inline-block` to host the\n\t\t\t\t\t\t\t\t\t\t mirror. Cross-browser, unlike the `-webkit-box-reflect`\n\t\t\t\t\t\t\t\t\t\t this replaced (Firefox never implemented it). -->\n\t\t\t\t\t\t\t\t\t\t\t<span style=\"position: relative; display: inline-block\">\n\t\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-text-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t><span [ngStyle]=\"run.style\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t><ng-container\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t*ngTemplateOutlet=\"runContent; context: { run: run }\" /></span\n\t\t\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (para.isEmpty) {\n\t\t\t\t\t\t\t\t\t<!-- An authored blank line has no runs, so without this the\n\t\t\t\t\t\t\t\t <p> collapses to zero height and the gap a deck puts\n\t\t\t\t\t\t\t\t between a heading and its bullet list disappears. -->\n\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t}\n\t@default {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-unsupported\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<div class=\"pptx-ng-placeholder\">{{ placeholderLabel() }}</div>\n\t\t</div>\n\t}\n}\n\n<!-- Soft-edge feather <filter> def, referenced via filter: url(#soft-edge-<id>). -->\n@if (softEdgeFilter(); as sef) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter\n\t\t\t\t[attr.id]=\"sef.id\"\n\t\t\t\tx=\"-20%\"\n\t\t\t\ty=\"-20%\"\n\t\t\t\twidth=\"140%\"\n\t\t\t\theight=\"140%\"\n\t\t\t\tcolor-interpolation-filters=\"sRGB\"\n\t\t\t>\n\t\t\t\t<feGaussianBlur in=\"SourceAlpha\" [attr.stdDeviation]=\"sef.radius\" result=\"softEdgeAlpha\" />\n\t\t\t\t<feComposite in=\"SourceGraphic\" in2=\"softEdgeAlpha\" operator=\"in\" />\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!-- Duotone image-effect <filter> def, referenced via filter: url(#id). -->\n@if (duotoneFilter(); as df) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter [attr.id]=\"df.id\" color-interpolation-filters=\"sRGB\">\n\t\t\t\t<feColorMatrix type=\"matrix\" [attr.values]=\"df.primitives[0].values\" />\n\t\t\t\t<feComponentTransfer>\n\t\t\t\t\t<feFuncR\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[0].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[0].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncG\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[1].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[1].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncB\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[2].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[2].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t</feComponentTransfer>\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!--\n\tOne run's base element (hyperlink / ruby / plain span), reused via\n\t`ngTemplateOutlet` both directly and inside the `a:reflection` wrapper above,\n\tso the reflection case does not duplicate this three-way branch.\n-->\n<ng-template #runBase let-run=\"run\">\n\t@if (run.href) {\n\t\t<a\n\t\t\tclass=\"pptx-ng-link\"\n\t\t\t[href]=\"run.href\"\n\t\t\ttarget=\"_blank\"\n\t\t\trel=\"noopener noreferrer\"\n\t\t\t[attr.title]=\"run.tooltip ?? null\"\n\t\t\t[ngStyle]=\"run.style\"\n\t\t\t(click)=\"onHyperlinkClick($event, run.href)\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></a>\n\t} @else if (run.rubyText) {\n\t\t<!-- `a:ruby`: the phonetic guide sits above its base\n\t\t text; the <rp> parentheses are the fallback for a\n\t\t browser without ruby support. -->\n\t\t<ruby [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\" /><rp>(</rp\n\t\t\t><rt [ngStyle]=\"run.rubyStyle\">{{ run.rubyText }}</rt\n\t\t\t><rp>)</rp></ruby\n\t\t>\n\t} @else {\n\t\t<span [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></span>\n\t}\n</ng-template>\n\n<!--\n\tA run's text content, honouring shared's per-script font split\n\t(`run.scriptRuns`) and measured tab-stop layout (`run.tabLines`) when\n\teither is present. Both descriptors come from `pptx-viewer-shared`'s\n\t`buildParagraphs` (the per-script split was React-only before this\n\ttemplate existed: CJK, Arabic, Hebrew and Thai text rendered in the wrong\n\ttypeface here; the tab layout was likewise React-only, so a TOC-style row\n\tlost its leader dots and right-aligned page number). Reused via\n\t`ngTemplateOutlet` for the run's span / anchor / ruby base text, so all\n\tthree carry the same content logic.\n-->\n<ng-template #runContent let-run=\"run\">\n\t@if (run.tabLines) {\n\t\t@for (line of run.tabLines; track $index) {\n\t\t\t<span style=\"display: inline-block; white-space: nowrap\">\n\t\t\t\t@for (piece of line.pieces; track $index) {\n\t\t\t\t\t@if (piece.leaderStyle) {\n\t\t\t\t\t\t<span aria-hidden=\"true\" [ngStyle]=\"piece.leaderStyle\">{{ piece.leaderText }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t\t}\n\t\t\t</span>\n\t\t\t@if (!$last) {\n\t\t\t\t<br />\n\t\t\t}\n\t\t}\n\t} @else if (run.scriptRuns) {\n\t\t<!--\n\t\t\tA bare interpolation as the sole content of an `@if`/`@else` block\n\t\t\tleaks a real leading + trailing whitespace text node: Angular does\n\t\t\tnot collapse that whitespace the way it collapses whitespace between\n\t\t\telement TAGS. Worse, oxfmt's Angular-template printer always breaks a\n\t\t\tblock's content onto its own indented line, even when the block was\n\t\t\twritten as a single line with the braces touching, so writing the\n\t\t\t`{{ x }}` compact ourselves does not survive the next `bun run fmt` /\n\t\t\tpre-commit `lint-staged` pass: it silently re-introduces the leak\n\t\t\t(this happened twice, see `20d4d177`, `18eebb6f`). `<ng-container>`\n\t\t\tdoes not render any DOM node of its own, so wrapping the\n\t\t\tinterpolation in one keeps the no-wrapper-element behaviour of\n\t\t\tReact's `<>{piece.text}</>` fragment while making the interpolation\n\t\t\ttag-adjacent, which both Angular AND oxfmt already treat as safely\n\t\t\tcollapsible (see the many `<span>{{ x }}</span>` one-liners in this\n\t\t\tfile). That was invisible while a paragraph was one run per script\n\t\t\t(two stray spaces at the run's own edges, trimmed visually by the\n\t\t\tbrowser but still present in `textContent`), but shared's per-word /\n\t\t\tper-gap metric split (`text-run-spacing.ts`, issue #149) re-emits\n\t\t\tevery WORD and inter-word GAP as its own sibling run, so the same\n\t\t\tone-space leak lands between every word: \"will choose\" rendered as\n\t\t\t\"will choose\" (five spaces: the word's own trailing leak, the\n\t\t\tgap run's real space plus its OWN two leaks, the next word's leading\n\t\t\tleak). The same leak also showed up one paragraph at a time:\n\t\t\t\"Project\" / \"Atlas\" as two separate paragraphs read back as\n\t\t\t\"ProjectAtlas\" instead of React's \"Project Atlas\", because the\n\t\t\tplain-run `@else` below had the same bug.\n\t\t-->\n\t\t@for (piece of run.scriptRuns; track $index) {\n\t\t\t@if (piece.style) {\n\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t} @else {\n\t\t\t\t<ng-container>{{ piece.text }}</ng-container>\n\t\t\t}\n\t\t}\n\t} @else {\n\t\t<ng-container>{{ run.text }}</ng-container>\n\t}\n</ng-template>\n", dependencies: [{ kind: "component", type: ElementRendererComponent, selector: "pptx-element-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "obstacles", "canvasWidth", "canvasHeight", "interactive", "marked", "exposeElementId", "presenting", "editable", "fieldContext", "slideElements", "editTemplateMode", "parentGroupFill", "editingElementId"], outputs: ["cellCommit", "tableChange"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ConnectorRendererComponent, selector: "pptx-connector-renderer", inputs: ["element", "zIndex", "obstacles", "canvasWidth", "canvasHeight", "interactive", "marked", "exposeElementId", "animationState"] }, { kind: "component", type: TableRendererComponent, selector: "pptx-table-renderer", inputs: ["element", "editable"], outputs: ["cellCommit", "tableChange"] }, { kind: "component", type: ChartElementViewComponent, selector: "pptx-chart-element-view", inputs: ["element", "editable", "animationState"] }, { kind: "component", type: SmartArtRendererComponent, selector: "pptx-smart-art-renderer", inputs: ["element", "editable", "animationState"] }, { kind: "component", type: SmartArt3DRendererComponent, selector: "pptx-smart-art-3d-renderer", inputs: ["element", "zIndex", "canEdit", "markElement"] }, { kind: "component", type: InkRendererComponent, selector: "pptx-ink-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "replay", "markElement", "exposeElementId"] }, { kind: "component", type: ContentPartRendererComponent, selector: "pptx-content-part-renderer", inputs: ["element", "zIndex", "replay", "markElement", "exposeElementId"] }, { kind: "component", type: MediaRendererComponent, selector: "pptx-media-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "interactive", "marked", "exposeElementId", "presenting", "placeholderLabel"] }, { kind: "component", type: OleRendererComponent, selector: "pptx-ole-renderer", inputs: ["element"] }, { kind: "component", type: Model3DRendererComponent, selector: "pptx-model3d-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "interactive", "markElement", "exposeElementId"] }, { kind: "component", type: ZoomRendererComponent, selector: "pptx-zoom-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "markElement"] }, { kind: "component", type: EquationRendererComponent, selector: "pptx-equation-renderer", inputs: ["equationXml", "equationNumber"] }, { kind: "component", type: ImageRendererComponent, selector: "pptx-image-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "interactive", "marked", "exposeElementId"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
94059
94520
  }
94060
94521
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ElementRendererComponent, decorators: [{
94061
94522
  type: Component,
@@ -94075,7 +94536,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
94075
94536
  ZoomRendererComponent,
94076
94537
  EquationRendererComponent,
94077
94538
  ImageRendererComponent,
94078
- ], template: "@switch (true) {\n\t@case (isHidden()) {\n\t\t<!--\n\t\t\tHidden via the Selection Pane: draw nothing, exactly as PowerPoint\n\t\t\tdoes. This is the FIRST case on purpose - @switch takes the first\n\t\t\tmatch, so one empty branch suppresses every element type at once\n\t\t\twithout wrapping (and re-indenting) the whole template. The host\n\t\t\tcarries \\`display: contents\\`, so an empty component collapses.\n\t\t\tRendering nothing (rather than an invisible box) is what keeps the\n\t\t\telement out of hit-testing, the tab order and the export raster; it\n\t\t\tstays listed in and selectable from the Selection Pane, which reads\n\t\t\tthe slide model rather than the DOM.\n\t\t-->\n\t}\n\t@case (element().type === 'connector') {\n\t\t<pptx-connector-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[obstacles]=\"obstacles()\"\n\t\t\t[canvasWidth]=\"canvasWidth()\"\n\t\t\t[canvasHeight]=\"canvasHeight()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[animationState]=\"animationState()\"\n\t\t/>\n\t}\n\t@case (element().type === 'ink') {\n\t\t<!--\n\t\t\tThis renderer (and zoom / model3d / 3D SmartArt below) positions its\n\t\t\town root box, so it takes the neutral element marker\n\t\t\t(data-pptx-element) as an input instead of being wrapped in a marked\n\t\t\tbox the way chart / table / OLE are: an outer positioned box would\n\t\t\toffset it twice.\n\t\t-->\n\t\t<pptx-ink-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'contentPart') {\n\t\t<!--\n\t\t\tReal PowerPoint ink. Same positioning contract as pptx-ink-renderer\n\t\t\tabove: the renderer's own root is absolutely positioned, so it takes\n\t\t\tthe neutral element marker as an input rather than being wrapped.\n\t\t-->\n\t\t<pptx-content-part-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'zoom') {\n\t\t<pptx-zoom-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'model3d') {\n\t\t<pptx-model3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt' && smartArt3D()) {\n\t\t<pptx-smart-art-3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[canEdit]=\"interactive() && editable()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-smartart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-smart-art-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'ole') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-ole\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-ole-renderer [element]=\"element()\" />\n\t\t</div>\n\t}\n\t@case (element().type === 'chart') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-chart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-chart-element-view\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'table') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-table\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-table-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t(cellCommit)=\"cellCommit.emit({ id: element().id, commit: $event })\"\n\t\t\t\t(tableChange)=\"tableChange.emit($event)\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'group') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-group\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t@for (child of children(); track child.id) {\n\t\t\t\t<pptx-element-renderer\n\t\t\t\t\t[element]=\"child\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zIndex]=\"$index\"\n\t\t\t\t\t[interactive]=\"interactive()\"\n\t\t\t\t\t[marked]=\"marked()\"\n\t\t\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t\t\t[presenting]=\"presenting()\"\n\t\t\t\t\t[fieldContext]=\"fieldContext()\"\n\t\t\t\t\t[slideElements]=\"slideElements()\"\n\t\t\t\t\t[parentGroupFill]=\"childParentGroupFill()\"\n\t\t\t\t\t[editingElementId]=\"editingElementId()\"\n\t\t\t\t/>\n\t\t\t}\n\t\t</div>\n\t}\n\t@case (isImageLike()) {\n\t\t<pptx-image-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'media') {\n\t\t<pptx-media-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[presenting]=\"presenting()\"\n\t\t\t[placeholderLabel]=\"placeholderLabel()\"\n\t\t/>\n\t}\n\t@case (isShapeLike()) {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-shape\"\n\t\t\t[ngStyle]=\"shapeContainerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n\t\t\t open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n\t\t\t geometry whose sub-paths cannot share one CSS background-color. -->\n\t\t\t@if (subpathFill(); as sf) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-subpath-fill\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"subpathFillViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n\t\t\t\t>\n\t\t\t\t\t@for (paint of sf.paints; track $index) {\n\t\t\t\t\t\t<path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t@if (fillOverlay(); as ov) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-fill-overlay\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; pointer-events: none\"\n\t\t\t\t\t[style.background]=\"ov.color\"\n\t\t\t\t\t[style.mix-blend-mode]=\"ov.blendMode\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t<!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n\t\t\t the `-webkit-box-reflect` this replaced (Firefox never implemented\n\t\t\t that property, so reflections were invisible there entirely). -->\n\t\t\t@if (reflection(); as refl) {\n\t\t\t\t<div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n\t\t\t\t\t@if (refl.imgSrc) {\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t[src]=\"refl.imgSrc\"\n\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\tdraggable=\"false\"\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[ngStyle]=\"refl.imgFitStyle\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t} @else if (refl.fill) {\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[style.background-color]=\"refl.fill.backgroundColor\"\n\t\t\t\t\t\t\t[style.background-image]=\"refl.fill.backgroundImage\"\n\t\t\t\t\t\t\t[style.background-size]=\"refl.fill.backgroundSize\"\n\t\t\t\t\t\t\t[style.background-position]=\"refl.fill.backgroundPosition\"\n\t\t\t\t\t\t\t[style.background-repeat]=\"refl.fill.backgroundRepeat\"\n\t\t\t\t\t\t></div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n\t\t\t on its outline only, so its interior lets clicks through. -->\n\t\t\t@if (hollowHit(); as hit) {\n\t\t\t\t<svg\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\t[attr.d]=\"hit.d\"\n\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\tstroke=\"transparent\"\n\t\t\t\t\t\t[attr.stroke-width]=\"hit.strokeWidth\"\n\t\t\t\t\t\tstyle=\"pointer-events: stroke\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- Stroked outline: a CSS border takes one flat colour, and cannot\n\t\t\t outline an open preset (`line`, `arc`) at all. -->\n\t\t\t@if (gradientOutline(); as go) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-gradient-outline\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t@if (go.paint; as paint) {\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@if (paint.kind === 'pattern') {\n\t\t\t\t\t\t\t\t<pattern\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\tpatternUnits=\"userSpaceOnUse\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<image\n\t\t\t\t\t\t\t\t\t\t[attr.href]=\"paint.href\"\n\t\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</pattern>\n\t\t\t\t\t\t\t} @else if (paint.kind === 'radial') {\n\t\t\t\t\t\t\t\t<radialGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.cx]=\"paint.cx\"\n\t\t\t\t\t\t\t\t\t[attr.cy]=\"paint.cy\"\n\t\t\t\t\t\t\t\t\t[attr.r]=\"paint.r\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</radialGradient>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<linearGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.x1]=\"paint.x1\"\n\t\t\t\t\t\t\t\t\t[attr.y1]=\"paint.y1\"\n\t\t\t\t\t\t\t\t\t[attr.x2]=\"paint.x2\"\n\t\t\t\t\t\t\t\t\t[attr.y2]=\"paint.y2\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</linearGradient>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t}\n\t\t\t\t\t@for (strand of go.strands; track $index) {\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t[attr.d]=\"go.d\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t[attr.stroke]=\"go.stroke\"\n\t\t\t\t\t\t\t[attr.stroke-width]=\"strand.strokeWidth\"\n\t\t\t\t\t\t\t[attr.stroke-dasharray]=\"go.dashArray\"\n\t\t\t\t\t\t\t[attr.stroke-linecap]=\"go.lineCap\"\n\t\t\t\t\t\t\t[attr.stroke-linejoin]=\"go.lineJoin\"\n\t\t\t\t\t\t\t[style.transform]=\"\n\t\t\t\t\t\t\t\tstrand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\n\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- While this element is open in the inline text editor, its live text\n\t\t\t is drawn by that overlay instead (see `isBeingInlineEdited`);\n\t\t\t rendering it here too produced a duplicate, offset \"text shadow\"\n\t\t\t (issue #182). -->\n\t\t\t@if (!isBeingInlineEdited()) {\n\t\t\t\t@if (pathWarp(); as warp) {\n\t\t\t\t\t<svg\n\t\t\t\t\t\t[attr.width]=\"warp.width\"\n\t\t\t\t\t\t[attr.height]=\"warp.height\"\n\t\t\t\t\t\t[attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n\t\t\t\t\t\tstyle=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t\t<path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t[attr.font-size]=\"warp.baseFontSize\"\n\t\t\t\t\t\t\t\t[attr.font-family]=\"warp.baseFontFamily\"\n\t\t\t\t\t\t\t\t[attr.fill]=\"warp.baseColor\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<textPath\n\t\t\t\t\t\t\t\t\t[attr.href]=\"'#' + line.pathId\"\n\t\t\t\t\t\t\t\t\t[attr.startOffset]=\"warp.startOffset\"\n\t\t\t\t\t\t\t\t\t[attr.text-anchor]=\"warp.textAnchor\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (seg of line.segments; track $index) {\n\t\t\t\t\t\t\t\t\t\t<tspan\n\t\t\t\t\t\t\t\t\t\t\t[attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{{ seg.text }}\n\t\t\t\t\t\t\t\t\t\t</tspan>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</textPath>\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t}\n\t\t\t\t\t</svg>\n\t\t\t\t} @else if (hasText()) {\n\t\t\t\t\t<div class=\"pptx-ng-text\" [ngStyle]=\"warpedTextStyle()\">\n\t\t\t\t\t\t@for (para of paragraphs(); track $index) {\n\t\t\t\t\t\t\t<p\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-para\"\n\t\t\t\t\t\t\t\t[ngStyle]=\"para.paragraphStyle ?? null\"\n\t\t\t\t\t\t\t\t[style.padding-left.px]=\"para.indentPx\"\n\t\t\t\t\t\t\t\t[style.text-indent.px]=\"para.textIndentPx ?? null\"\n\t\t\t\t\t\t\t\t[style.line-height]=\"para.lineHeight ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-top.px]=\"para.spaceBeforePx ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-bottom.px]=\"para.spaceAfterPx ?? null\"\n\t\t\t\t\t\t\t\t[style.font-size.px]=\"para.strutFontSizePx ?? null\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t@if (para.bulletPicture?.src) {\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet-image\"\n\t\t\t\t\t\t\t\t\t\t[src]=\"para.bulletPicture.src\"\n\t\t\t\t\t\t\t\t\t\t[alt]=\"para.bulletPicture.accessibleLabel\"\n\t\t\t\t\t\t\t\t\t\t[style.width.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\t[style.height.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\tstyle=\"\n\t\t\t\t\t\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t\t\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\t\t\t\t\t\t\tmargin-inline-end: 4px;\n\t\t\t\t\t\t\t\t\t\t\tobject-fit: contain;\n\t\t\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t} @else if (para.bulletMarker) {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet\"\n\t\t\t\t\t\t\t\t\t\t[ngStyle]=\"para.bulletStyle\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"para.bulletPicture?.accessibleLabel ?? null\"\n\t\t\t\t\t\t\t\t\t\t>{{ para.bulletMarker }}</span\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (textBuildSpecs()[$index]; as spec) {\n\t\t\t\t\t\t\t\t\t<!-- Staged text build: render the split pieces so each one\n\t\t\t\t\t\t\t\t carries its own sub-animation. -->\n\t\t\t\t\t\t\t\t\t@if (spec.granularity === 'paragraph') {\n\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"spec.animId\" [ngStyle]=\"buildSpanStyle(spec)\">{{\n\t\t\t\t\t\t\t\t\t\t\tparagraphText(para)\n\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t@for (span of spec.spans ?? []; track $index) {\n\t\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"span.animId\" [ngStyle]=\"buildSpanStyle(span)\">{{\n\t\t\t\t\t\t\t\t\t\t\t\tspan.text\n\t\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t@for (run of para.runs; track $index) {\n\t\t\t\t\t\t\t\t\t\t@if (run.equationXml) {\n\t\t\t\t\t\t\t\t\t\t\t<pptx-equation-renderer\n\t\t\t\t\t\t\t\t\t\t\t\t[equationXml]=\"run.equationXml\"\n\t\t\t\t\t\t\t\t\t\t\t\t[equationNumber]=\"run.equationNumber\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t} @else if (\n\t\t\t\t\t\t\t\t\t\t\trun.text ===\n\t\t\t\t\t\t\t\t\t\t\t'\n'\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t\t\t} @else if (run.reflection; as refl) {\n\t\t\t\t\t\t\t\t\t\t\t<!-- `a:reflection`: wrapped HERE, around the whole base\n\t\t\t\t\t\t\t\t\t\t run (`runBase`), rather than inside its href/ruby/plain\n\t\t\t\t\t\t\t\t\t\t branches - a `<ruby>` run's own `display: ruby` (which\n\t\t\t\t\t\t\t\t\t\t positions the annotation above its base text) would\n\t\t\t\t\t\t\t\t\t\t break if forced to `display: inline-block` to host the\n\t\t\t\t\t\t\t\t\t\t mirror. Cross-browser, unlike the `-webkit-box-reflect`\n\t\t\t\t\t\t\t\t\t\t this replaced (Firefox never implemented it). -->\n\t\t\t\t\t\t\t\t\t\t\t<span style=\"position: relative; display: inline-block\">\n\t\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-text-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t><span [ngStyle]=\"run.style\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t><ng-container\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t*ngTemplateOutlet=\"runContent; context: { run: run }\" /></span\n\t\t\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (para.isEmpty) {\n\t\t\t\t\t\t\t\t\t<!-- An authored blank line has no runs, so without this the\n\t\t\t\t\t\t\t\t <p> collapses to zero height and the gap a deck puts\n\t\t\t\t\t\t\t\t between a heading and its bullet list disappears. -->\n\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t}\n\t@default {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-unsupported\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<div class=\"pptx-ng-placeholder\">{{ placeholderLabel() }}</div>\n\t\t</div>\n\t}\n}\n\n<!-- Soft-edge feather <filter> def, referenced via filter: url(#soft-edge-<id>). -->\n@if (softEdgeFilter(); as sef) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter\n\t\t\t\t[attr.id]=\"sef.id\"\n\t\t\t\tx=\"-20%\"\n\t\t\t\ty=\"-20%\"\n\t\t\t\twidth=\"140%\"\n\t\t\t\theight=\"140%\"\n\t\t\t\tcolor-interpolation-filters=\"sRGB\"\n\t\t\t>\n\t\t\t\t<feGaussianBlur in=\"SourceAlpha\" [attr.stdDeviation]=\"sef.radius\" result=\"softEdgeAlpha\" />\n\t\t\t\t<feComposite in=\"SourceGraphic\" in2=\"softEdgeAlpha\" operator=\"in\" />\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!-- Duotone image-effect <filter> def, referenced via filter: url(#id). -->\n@if (duotoneFilter(); as df) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter [attr.id]=\"df.id\" color-interpolation-filters=\"sRGB\">\n\t\t\t\t<feColorMatrix type=\"matrix\" [attr.values]=\"df.primitives[0].values\" />\n\t\t\t\t<feComponentTransfer>\n\t\t\t\t\t<feFuncR\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[0].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[0].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncG\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[1].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[1].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncB\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[2].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[2].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t</feComponentTransfer>\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!--\n\tOne run's base element (hyperlink / ruby / plain span), reused via\n\t`ngTemplateOutlet` both directly and inside the `a:reflection` wrapper above,\n\tso the reflection case does not duplicate this three-way branch.\n-->\n<ng-template #runBase let-run=\"run\">\n\t@if (run.href) {\n\t\t<a\n\t\t\tclass=\"pptx-ng-link\"\n\t\t\t[href]=\"run.href\"\n\t\t\ttarget=\"_blank\"\n\t\t\trel=\"noopener noreferrer\"\n\t\t\t[attr.title]=\"run.tooltip ?? null\"\n\t\t\t[ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></a>\n\t} @else if (run.rubyText) {\n\t\t<!-- `a:ruby`: the phonetic guide sits above its base\n\t\t text; the <rp> parentheses are the fallback for a\n\t\t browser without ruby support. -->\n\t\t<ruby [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\" /><rp>(</rp\n\t\t\t><rt [ngStyle]=\"run.rubyStyle\">{{ run.rubyText }}</rt\n\t\t\t><rp>)</rp></ruby\n\t\t>\n\t} @else {\n\t\t<span [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></span>\n\t}\n</ng-template>\n\n<!--\n\tA run's text content, honouring shared's per-script font split\n\t(`run.scriptRuns`) and measured tab-stop layout (`run.tabLines`) when\n\teither is present. Both descriptors come from `pptx-viewer-shared`'s\n\t`buildParagraphs` (the per-script split was React-only before this\n\ttemplate existed: CJK, Arabic, Hebrew and Thai text rendered in the wrong\n\ttypeface here; the tab layout was likewise React-only, so a TOC-style row\n\tlost its leader dots and right-aligned page number). Reused via\n\t`ngTemplateOutlet` for the run's span / anchor / ruby base text, so all\n\tthree carry the same content logic.\n-->\n<ng-template #runContent let-run=\"run\">\n\t@if (run.tabLines) {\n\t\t@for (line of run.tabLines; track $index) {\n\t\t\t<span style=\"display: inline-block; white-space: nowrap\">\n\t\t\t\t@for (piece of line.pieces; track $index) {\n\t\t\t\t\t@if (piece.leaderStyle) {\n\t\t\t\t\t\t<span aria-hidden=\"true\" [ngStyle]=\"piece.leaderStyle\">{{ piece.leaderText }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t\t}\n\t\t\t</span>\n\t\t\t@if (!$last) {\n\t\t\t\t<br />\n\t\t\t}\n\t\t}\n\t} @else if (run.scriptRuns) {\n\t\t<!--\n\t\t\tA bare interpolation as the sole content of an `@if`/`@else` block\n\t\t\tleaks a real leading + trailing whitespace text node: Angular does\n\t\t\tnot collapse that whitespace the way it collapses whitespace between\n\t\t\telement TAGS. Worse, oxfmt's Angular-template printer always breaks a\n\t\t\tblock's content onto its own indented line, even when the block was\n\t\t\twritten as a single line with the braces touching, so writing the\n\t\t\t`{{ x }}` compact ourselves does not survive the next `bun run fmt` /\n\t\t\tpre-commit `lint-staged` pass: it silently re-introduces the leak\n\t\t\t(this happened twice, see `20d4d177`, `18eebb6f`). `<ng-container>`\n\t\t\tdoes not render any DOM node of its own, so wrapping the\n\t\t\tinterpolation in one keeps the no-wrapper-element behaviour of\n\t\t\tReact's `<>{piece.text}</>` fragment while making the interpolation\n\t\t\ttag-adjacent, which both Angular AND oxfmt already treat as safely\n\t\t\tcollapsible (see the many `<span>{{ x }}</span>` one-liners in this\n\t\t\tfile). That was invisible while a paragraph was one run per script\n\t\t\t(two stray spaces at the run's own edges, trimmed visually by the\n\t\t\tbrowser but still present in `textContent`), but shared's per-word /\n\t\t\tper-gap metric split (`text-run-spacing.ts`, issue #149) re-emits\n\t\t\tevery WORD and inter-word GAP as its own sibling run, so the same\n\t\t\tone-space leak lands between every word: \"will choose\" rendered as\n\t\t\t\"will choose\" (five spaces: the word's own trailing leak, the\n\t\t\tgap run's real space plus its OWN two leaks, the next word's leading\n\t\t\tleak). The same leak also showed up one paragraph at a time:\n\t\t\t\"Project\" / \"Atlas\" as two separate paragraphs read back as\n\t\t\t\"ProjectAtlas\" instead of React's \"Project Atlas\", because the\n\t\t\tplain-run `@else` below had the same bug.\n\t\t-->\n\t\t@for (piece of run.scriptRuns; track $index) {\n\t\t\t@if (piece.style) {\n\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t} @else {\n\t\t\t\t<ng-container>{{ piece.text }}</ng-container>\n\t\t\t}\n\t\t}\n\t} @else {\n\t\t<ng-container>{{ run.text }}</ng-container>\n\t}\n</ng-template>\n" }]
94539
+ ], template: "@switch (true) {\n\t@case (isHidden()) {\n\t\t<!--\n\t\t\tHidden via the Selection Pane: draw nothing, exactly as PowerPoint\n\t\t\tdoes. This is the FIRST case on purpose - @switch takes the first\n\t\t\tmatch, so one empty branch suppresses every element type at once\n\t\t\twithout wrapping (and re-indenting) the whole template. The host\n\t\t\tcarries \\`display: contents\\`, so an empty component collapses.\n\t\t\tRendering nothing (rather than an invisible box) is what keeps the\n\t\t\telement out of hit-testing, the tab order and the export raster; it\n\t\t\tstays listed in and selectable from the Selection Pane, which reads\n\t\t\tthe slide model rather than the DOM.\n\t\t-->\n\t}\n\t@case (element().type === 'connector') {\n\t\t<pptx-connector-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[obstacles]=\"obstacles()\"\n\t\t\t[canvasWidth]=\"canvasWidth()\"\n\t\t\t[canvasHeight]=\"canvasHeight()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[animationState]=\"animationState()\"\n\t\t/>\n\t}\n\t@case (element().type === 'ink') {\n\t\t<!--\n\t\t\tThis renderer (and zoom / model3d / 3D SmartArt below) positions its\n\t\t\town root box, so it takes the neutral element marker\n\t\t\t(data-pptx-element) as an input instead of being wrapped in a marked\n\t\t\tbox the way chart / table / OLE are: an outer positioned box would\n\t\t\toffset it twice.\n\t\t-->\n\t\t<pptx-ink-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'contentPart') {\n\t\t<!--\n\t\t\tReal PowerPoint ink. Same positioning contract as pptx-ink-renderer\n\t\t\tabove: the renderer's own root is absolutely positioned, so it takes\n\t\t\tthe neutral element marker as an input rather than being wrapped.\n\t\t-->\n\t\t<pptx-content-part-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[replay]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'zoom') {\n\t\t<pptx-zoom-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'model3d') {\n\t\t<pptx-model3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt' && smartArt3D()) {\n\t\t<pptx-smart-art-3d-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[canEdit]=\"interactive() && editable()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t/>\n\t}\n\t@case (element().type === 'smartArt') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-smartart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-smart-art-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'ole') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-ole\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-ole-renderer [element]=\"element()\" />\n\t\t</div>\n\t}\n\t@case (element().type === 'chart') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-chart\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-chart-element-view\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t[animationState]=\"animationState()\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'table') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-table\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<pptx-table-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[editable]=\"interactive() && editable()\"\n\t\t\t\t(cellCommit)=\"cellCommit.emit({ id: element().id, commit: $event })\"\n\t\t\t\t(tableChange)=\"tableChange.emit($event)\"\n\t\t\t/>\n\t\t</div>\n\t}\n\t@case (element().type === 'group') {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-group\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t@for (child of children(); track child.id) {\n\t\t\t\t<pptx-element-renderer\n\t\t\t\t\t[element]=\"child\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zIndex]=\"$index\"\n\t\t\t\t\t[interactive]=\"interactive()\"\n\t\t\t\t\t[marked]=\"marked()\"\n\t\t\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t\t\t[presenting]=\"presenting()\"\n\t\t\t\t\t[fieldContext]=\"fieldContext()\"\n\t\t\t\t\t[slideElements]=\"slideElements()\"\n\t\t\t\t\t[parentGroupFill]=\"childParentGroupFill()\"\n\t\t\t\t\t[editingElementId]=\"editingElementId()\"\n\t\t\t\t/>\n\t\t\t}\n\t\t</div>\n\t}\n\t@case (isImageLike()) {\n\t\t<pptx-image-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t/>\n\t}\n\t@case (element().type === 'media') {\n\t\t<pptx-media-renderer\n\t\t\t[element]=\"element()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zIndex]=\"zIndex()\"\n\t\t\t[interactive]=\"interactive()\"\n\t\t\t[marked]=\"elementMarked()\"\n\t\t\t[exposeElementId]=\"exposeElementId()\"\n\t\t\t[presenting]=\"presenting()\"\n\t\t\t[placeholderLabel]=\"placeholderLabel()\"\n\t\t/>\n\t}\n\t@case (isShapeLike()) {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-shape\"\n\t\t\t[ngStyle]=\"shapeContainerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n\t\t\t open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n\t\t\t geometry whose sub-paths cannot share one CSS background-color. -->\n\t\t\t@if (subpathFill(); as sf) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-subpath-fill\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"subpathFillViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n\t\t\t\t>\n\t\t\t\t\t@for (paint of sf.paints; track $index) {\n\t\t\t\t\t\t<path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t@if (fillOverlay(); as ov) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-fill-overlay\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; pointer-events: none\"\n\t\t\t\t\t[style.background]=\"ov.color\"\n\t\t\t\t\t[style.mix-blend-mode]=\"ov.blendMode\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t<!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n\t\t\t the `-webkit-box-reflect` this replaced (Firefox never implemented\n\t\t\t that property, so reflections were invisible there entirely). -->\n\t\t\t@if (reflection(); as refl) {\n\t\t\t\t<div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n\t\t\t\t\t@if (refl.imgSrc) {\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t[src]=\"refl.imgSrc\"\n\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\tdraggable=\"false\"\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[ngStyle]=\"refl.imgFitStyle\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t} @else if (refl.fill) {\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle=\"width: 100%; height: 100%\"\n\t\t\t\t\t\t\t[style.background-color]=\"refl.fill.backgroundColor\"\n\t\t\t\t\t\t\t[style.background-image]=\"refl.fill.backgroundImage\"\n\t\t\t\t\t\t\t[style.background-size]=\"refl.fill.backgroundSize\"\n\t\t\t\t\t\t\t[style.background-position]=\"refl.fill.backgroundPosition\"\n\t\t\t\t\t\t\t[style.background-repeat]=\"refl.fill.backgroundRepeat\"\n\t\t\t\t\t\t></div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n\t\t\t on its outline only, so its interior lets clicks through. -->\n\t\t\t@if (hollowHit(); as hit) {\n\t\t\t\t<svg\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\t[attr.d]=\"hit.d\"\n\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\tstroke=\"transparent\"\n\t\t\t\t\t\t[attr.stroke-width]=\"hit.strokeWidth\"\n\t\t\t\t\t\tstyle=\"pointer-events: stroke\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- Stroked outline: a CSS border takes one flat colour, and cannot\n\t\t\t outline an open preset (`line`, `arc`) at all. -->\n\t\t\t@if (gradientOutline(); as go) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-gradient-outline\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.viewBox]=\"outlineViewBox()\"\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\tstyle=\"\n\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\tinset: 0;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 100%;\n\t\t\t\t\t\toverflow: visible;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\"\n\t\t\t\t>\n\t\t\t\t\t@if (go.paint; as paint) {\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@if (paint.kind === 'pattern') {\n\t\t\t\t\t\t\t\t<pattern\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\tpatternUnits=\"userSpaceOnUse\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<image\n\t\t\t\t\t\t\t\t\t\t[attr.href]=\"paint.href\"\n\t\t\t\t\t\t\t\t\t\t[attr.width]=\"paint.width\"\n\t\t\t\t\t\t\t\t\t\t[attr.height]=\"paint.height\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</pattern>\n\t\t\t\t\t\t\t} @else if (paint.kind === 'radial') {\n\t\t\t\t\t\t\t\t<radialGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.cx]=\"paint.cx\"\n\t\t\t\t\t\t\t\t\t[attr.cy]=\"paint.cy\"\n\t\t\t\t\t\t\t\t\t[attr.r]=\"paint.r\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</radialGradient>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<linearGradient\n\t\t\t\t\t\t\t\t\t[attr.id]=\"paint.id\"\n\t\t\t\t\t\t\t\t\t[attr.x1]=\"paint.x1\"\n\t\t\t\t\t\t\t\t\t[attr.y1]=\"paint.y1\"\n\t\t\t\t\t\t\t\t\t[attr.x2]=\"paint.x2\"\n\t\t\t\t\t\t\t\t\t[attr.y2]=\"paint.y2\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (stop of paint.stops; track $index) {\n\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t[attr.offset]=\"stop.offset\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-color]=\"stop.color\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.stop-opacity]=\"stop.opacity\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</linearGradient>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t}\n\t\t\t\t\t@for (strand of go.strands; track $index) {\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t[attr.d]=\"go.d\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t[attr.stroke]=\"go.stroke\"\n\t\t\t\t\t\t\t[attr.stroke-width]=\"strand.strokeWidth\"\n\t\t\t\t\t\t\t[attr.stroke-dasharray]=\"go.dashArray\"\n\t\t\t\t\t\t\t[attr.stroke-linecap]=\"go.lineCap\"\n\t\t\t\t\t\t\t[attr.stroke-linejoin]=\"go.lineJoin\"\n\t\t\t\t\t\t\t[style.transform]=\"\n\t\t\t\t\t\t\t\tstrand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\n\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\t\t\t<!-- While this element is open in the inline text editor, its live text\n\t\t\t is drawn by that overlay instead (see `isBeingInlineEdited`);\n\t\t\t rendering it here too produced a duplicate, offset \"text shadow\"\n\t\t\t (issue #182). -->\n\t\t\t@if (!isBeingInlineEdited()) {\n\t\t\t\t@if (pathWarp(); as warp) {\n\t\t\t\t\t<svg\n\t\t\t\t\t\t[attr.width]=\"warp.width\"\n\t\t\t\t\t\t[attr.height]=\"warp.height\"\n\t\t\t\t\t\t[attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n\t\t\t\t\t\tstyle=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t\t<path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t\t@for (line of warp.pathLines; track line.pathId) {\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t[attr.font-size]=\"warp.baseFontSize\"\n\t\t\t\t\t\t\t\t[attr.font-family]=\"warp.baseFontFamily\"\n\t\t\t\t\t\t\t\t[attr.fill]=\"warp.baseColor\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<textPath\n\t\t\t\t\t\t\t\t\t[attr.href]=\"'#' + line.pathId\"\n\t\t\t\t\t\t\t\t\t[attr.startOffset]=\"warp.startOffset\"\n\t\t\t\t\t\t\t\t\t[attr.text-anchor]=\"warp.textAnchor\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t@for (seg of line.segments; track $index) {\n\t\t\t\t\t\t\t\t\t\t<tspan\n\t\t\t\t\t\t\t\t\t\t\t[attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{{ seg.text }}\n\t\t\t\t\t\t\t\t\t\t</tspan>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</textPath>\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t}\n\t\t\t\t\t</svg>\n\t\t\t\t} @else if (hasText()) {\n\t\t\t\t\t<div class=\"pptx-ng-text\" [ngStyle]=\"warpedTextStyle()\">\n\t\t\t\t\t\t@for (para of paragraphs(); track $index) {\n\t\t\t\t\t\t\t<p\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-para\"\n\t\t\t\t\t\t\t\t[ngStyle]=\"para.paragraphStyle ?? null\"\n\t\t\t\t\t\t\t\t[style.padding-left.px]=\"para.indentPx\"\n\t\t\t\t\t\t\t\t[style.text-indent.px]=\"para.textIndentPx ?? null\"\n\t\t\t\t\t\t\t\t[style.line-height]=\"para.lineHeight ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-top.px]=\"para.spaceBeforePx ?? null\"\n\t\t\t\t\t\t\t\t[style.margin-bottom.px]=\"para.spaceAfterPx ?? null\"\n\t\t\t\t\t\t\t\t[style.font-size.px]=\"para.strutFontSizePx ?? null\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t@if (para.bulletPicture?.src) {\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet-image\"\n\t\t\t\t\t\t\t\t\t\t[src]=\"para.bulletPicture.src\"\n\t\t\t\t\t\t\t\t\t\t[alt]=\"para.bulletPicture.accessibleLabel\"\n\t\t\t\t\t\t\t\t\t\t[style.width.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\t[style.height.px]=\"para.bulletPicture.sizePx\"\n\t\t\t\t\t\t\t\t\t\tstyle=\"\n\t\t\t\t\t\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t\t\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\t\t\t\t\t\t\tmargin-inline-end: 4px;\n\t\t\t\t\t\t\t\t\t\t\tobject-fit: contain;\n\t\t\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t} @else if (para.bulletMarker) {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-bullet\"\n\t\t\t\t\t\t\t\t\t\t[ngStyle]=\"para.bulletStyle\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"para.bulletPicture?.accessibleLabel ?? null\"\n\t\t\t\t\t\t\t\t\t\t>{{ para.bulletMarker }}</span\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (textBuildSpecs()[$index]; as spec) {\n\t\t\t\t\t\t\t\t\t<!-- Staged text build: render the split pieces so each one\n\t\t\t\t\t\t\t\t carries its own sub-animation. -->\n\t\t\t\t\t\t\t\t\t@if (spec.granularity === 'paragraph') {\n\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"spec.animId\" [ngStyle]=\"buildSpanStyle(spec)\">{{\n\t\t\t\t\t\t\t\t\t\t\tparagraphText(para)\n\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t@for (span of spec.spans ?? []; track $index) {\n\t\t\t\t\t\t\t\t\t\t\t<span [attr.data-anim-id]=\"span.animId\" [ngStyle]=\"buildSpanStyle(span)\">{{\n\t\t\t\t\t\t\t\t\t\t\t\tspan.text\n\t\t\t\t\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t@for (run of para.runs; track $index) {\n\t\t\t\t\t\t\t\t\t\t@if (run.equationXml) {\n\t\t\t\t\t\t\t\t\t\t\t<pptx-equation-renderer\n\t\t\t\t\t\t\t\t\t\t\t\t[equationXml]=\"run.equationXml\"\n\t\t\t\t\t\t\t\t\t\t\t\t[equationNumber]=\"run.equationNumber\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t} @else if (\n\t\t\t\t\t\t\t\t\t\t\trun.text ===\n\t\t\t\t\t\t\t\t\t\t\t'\n'\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t\t\t} @else if (run.reflection; as refl) {\n\t\t\t\t\t\t\t\t\t\t\t<!-- `a:reflection`: wrapped HERE, around the whole base\n\t\t\t\t\t\t\t\t\t\t run (`runBase`), rather than inside its href/ruby/plain\n\t\t\t\t\t\t\t\t\t\t branches - a `<ruby>` run's own `display: ruby` (which\n\t\t\t\t\t\t\t\t\t\t positions the annotation above its base text) would\n\t\t\t\t\t\t\t\t\t\t break if forced to `display: inline-block` to host the\n\t\t\t\t\t\t\t\t\t\t mirror. Cross-browser, unlike the `-webkit-box-reflect`\n\t\t\t\t\t\t\t\t\t\t this replaced (Firefox never implemented it). -->\n\t\t\t\t\t\t\t\t\t\t\t<span style=\"position: relative; display: inline-block\">\n\t\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-text-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t><span [ngStyle]=\"run.style\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t><ng-container\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t*ngTemplateOutlet=\"runContent; context: { run: run }\" /></span\n\t\t\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"runBase; context: { run: run }\" />\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@if (para.isEmpty) {\n\t\t\t\t\t\t\t\t\t<!-- An authored blank line has no runs, so without this the\n\t\t\t\t\t\t\t\t <p> collapses to zero height and the gap a deck puts\n\t\t\t\t\t\t\t\t between a heading and its bullet list disappears. -->\n\t\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t}\n\t@default {\n\t\t<div\n\t\t\tclass=\"pptx-ng-element pptx-ng-unsupported\"\n\t\t\t[ngStyle]=\"containerStyle()\"\n\t\t\t[style.pointer-events]=\"rootPointerEvents()\"\n\t\t\t[attr.data-element-id]=\"elementIdAttr()\"\n\t\t\t[attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n\t\t>\n\t\t\t<div class=\"pptx-ng-placeholder\">{{ placeholderLabel() }}</div>\n\t\t</div>\n\t}\n}\n\n<!-- Soft-edge feather <filter> def, referenced via filter: url(#soft-edge-<id>). -->\n@if (softEdgeFilter(); as sef) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter\n\t\t\t\t[attr.id]=\"sef.id\"\n\t\t\t\tx=\"-20%\"\n\t\t\t\ty=\"-20%\"\n\t\t\t\twidth=\"140%\"\n\t\t\t\theight=\"140%\"\n\t\t\t\tcolor-interpolation-filters=\"sRGB\"\n\t\t\t>\n\t\t\t\t<feGaussianBlur in=\"SourceAlpha\" [attr.stdDeviation]=\"sef.radius\" result=\"softEdgeAlpha\" />\n\t\t\t\t<feComposite in=\"SourceGraphic\" in2=\"softEdgeAlpha\" operator=\"in\" />\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!-- Duotone image-effect <filter> def, referenced via filter: url(#id). -->\n@if (duotoneFilter(); as df) {\n\t<svg\n\t\twidth=\"0\"\n\t\theight=\"0\"\n\t\taria-hidden=\"true\"\n\t\tstyle=\"position: absolute; width: 0; height: 0; overflow: hidden\"\n\t>\n\t\t<defs>\n\t\t\t<filter [attr.id]=\"df.id\" color-interpolation-filters=\"sRGB\">\n\t\t\t\t<feColorMatrix type=\"matrix\" [attr.values]=\"df.primitives[0].values\" />\n\t\t\t\t<feComponentTransfer>\n\t\t\t\t\t<feFuncR\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[0].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[0].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncG\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[1].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[1].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t\t<feFuncB\n\t\t\t\t\t\ttype=\"linear\"\n\t\t\t\t\t\t[attr.slope]=\"df.primitives[1].channels[2].slope\"\n\t\t\t\t\t\t[attr.intercept]=\"df.primitives[1].channels[2].intercept\"\n\t\t\t\t\t/>\n\t\t\t\t</feComponentTransfer>\n\t\t\t</filter>\n\t\t</defs>\n\t</svg>\n}\n\n<!--\n\tOne run's base element (hyperlink / ruby / plain span), reused via\n\t`ngTemplateOutlet` both directly and inside the `a:reflection` wrapper above,\n\tso the reflection case does not duplicate this three-way branch.\n-->\n<ng-template #runBase let-run=\"run\">\n\t@if (run.href) {\n\t\t<a\n\t\t\tclass=\"pptx-ng-link\"\n\t\t\t[href]=\"run.href\"\n\t\t\ttarget=\"_blank\"\n\t\t\trel=\"noopener noreferrer\"\n\t\t\t[attr.title]=\"run.tooltip ?? null\"\n\t\t\t[ngStyle]=\"run.style\"\n\t\t\t(click)=\"onHyperlinkClick($event, run.href)\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></a>\n\t} @else if (run.rubyText) {\n\t\t<!-- `a:ruby`: the phonetic guide sits above its base\n\t\t text; the <rp> parentheses are the fallback for a\n\t\t browser without ruby support. -->\n\t\t<ruby [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\" /><rp>(</rp\n\t\t\t><rt [ngStyle]=\"run.rubyStyle\">{{ run.rubyText }}</rt\n\t\t\t><rp>)</rp></ruby\n\t\t>\n\t} @else {\n\t\t<span [ngStyle]=\"run.style\"\n\t\t\t><ng-container *ngTemplateOutlet=\"runContent; context: { run: run }\"\n\t\t/></span>\n\t}\n</ng-template>\n\n<!--\n\tA run's text content, honouring shared's per-script font split\n\t(`run.scriptRuns`) and measured tab-stop layout (`run.tabLines`) when\n\teither is present. Both descriptors come from `pptx-viewer-shared`'s\n\t`buildParagraphs` (the per-script split was React-only before this\n\ttemplate existed: CJK, Arabic, Hebrew and Thai text rendered in the wrong\n\ttypeface here; the tab layout was likewise React-only, so a TOC-style row\n\tlost its leader dots and right-aligned page number). Reused via\n\t`ngTemplateOutlet` for the run's span / anchor / ruby base text, so all\n\tthree carry the same content logic.\n-->\n<ng-template #runContent let-run=\"run\">\n\t@if (run.tabLines) {\n\t\t@for (line of run.tabLines; track $index) {\n\t\t\t<span style=\"display: inline-block; white-space: nowrap\">\n\t\t\t\t@for (piece of line.pieces; track $index) {\n\t\t\t\t\t@if (piece.leaderStyle) {\n\t\t\t\t\t\t<span aria-hidden=\"true\" [ngStyle]=\"piece.leaderStyle\">{{ piece.leaderText }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t\t}\n\t\t\t</span>\n\t\t\t@if (!$last) {\n\t\t\t\t<br />\n\t\t\t}\n\t\t}\n\t} @else if (run.scriptRuns) {\n\t\t<!--\n\t\t\tA bare interpolation as the sole content of an `@if`/`@else` block\n\t\t\tleaks a real leading + trailing whitespace text node: Angular does\n\t\t\tnot collapse that whitespace the way it collapses whitespace between\n\t\t\telement TAGS. Worse, oxfmt's Angular-template printer always breaks a\n\t\t\tblock's content onto its own indented line, even when the block was\n\t\t\twritten as a single line with the braces touching, so writing the\n\t\t\t`{{ x }}` compact ourselves does not survive the next `bun run fmt` /\n\t\t\tpre-commit `lint-staged` pass: it silently re-introduces the leak\n\t\t\t(this happened twice, see `20d4d177`, `18eebb6f`). `<ng-container>`\n\t\t\tdoes not render any DOM node of its own, so wrapping the\n\t\t\tinterpolation in one keeps the no-wrapper-element behaviour of\n\t\t\tReact's `<>{piece.text}</>` fragment while making the interpolation\n\t\t\ttag-adjacent, which both Angular AND oxfmt already treat as safely\n\t\t\tcollapsible (see the many `<span>{{ x }}</span>` one-liners in this\n\t\t\tfile). That was invisible while a paragraph was one run per script\n\t\t\t(two stray spaces at the run's own edges, trimmed visually by the\n\t\t\tbrowser but still present in `textContent`), but shared's per-word /\n\t\t\tper-gap metric split (`text-run-spacing.ts`, issue #149) re-emits\n\t\t\tevery WORD and inter-word GAP as its own sibling run, so the same\n\t\t\tone-space leak lands between every word: \"will choose\" rendered as\n\t\t\t\"will choose\" (five spaces: the word's own trailing leak, the\n\t\t\tgap run's real space plus its OWN two leaks, the next word's leading\n\t\t\tleak). The same leak also showed up one paragraph at a time:\n\t\t\t\"Project\" / \"Atlas\" as two separate paragraphs read back as\n\t\t\t\"ProjectAtlas\" instead of React's \"Project Atlas\", because the\n\t\t\tplain-run `@else` below had the same bug.\n\t\t-->\n\t\t@for (piece of run.scriptRuns; track $index) {\n\t\t\t@if (piece.style) {\n\t\t\t\t<span [ngStyle]=\"piece.style\">{{ piece.text }}</span>\n\t\t\t} @else {\n\t\t\t\t<ng-container>{{ piece.text }}</ng-container>\n\t\t\t}\n\t\t}\n\t} @else {\n\t\t<ng-container>{{ run.text }}</ng-container>\n\t}\n</ng-template>\n" }]
94079
94540
  }], propDecorators: { element: [{ type: i0.Input, args: [{ isSignal: true, alias: "element", required: true }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], zIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "zIndex", required: false }] }], obstacles: [{ type: i0.Input, args: [{ isSignal: true, alias: "obstacles", required: false }] }], canvasWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasWidth", required: false }] }], canvasHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasHeight", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], marked: [{ type: i0.Input, args: [{ isSignal: true, alias: "marked", required: false }] }], exposeElementId: [{ type: i0.Input, args: [{ isSignal: true, alias: "exposeElementId", required: false }] }], presenting: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenting", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], fieldContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldContext", required: false }] }], slideElements: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideElements", required: false }] }], editTemplateMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "editTemplateMode", required: false }] }], parentGroupFill: [{ type: i0.Input, args: [{ isSignal: true, alias: "parentGroupFill", required: false }] }], editingElementId: [{ type: i0.Input, args: [{ isSignal: true, alias: "editingElementId", required: false }] }], cellCommit: [{ type: i0.Output, args: ["cellCommit"] }], tableChange: [{ type: i0.Output, args: ["tableChange"] }] } });
94080
94541
 
94081
94542
  /**
@@ -95018,6 +95479,8 @@ class SlideCanvasComponent {
95018
95479
  this.fieldContextSvc = inject(FieldContextService, { optional: true });
95019
95480
  this.fieldContext = computed(() => this.fieldContextSvc?.forSlide(this.slide()), /* @ts-ignore */
95020
95481
  ...(ngDevMode ? [{ debugName: "fieldContext" }] : /* istanbul ignore next */ []));
95482
+ /** Options > Proofing > AutoCorrect, applied to committed inline-edit text. */
95483
+ this.viewerOpts = inject(ViewerOptionsService, { optional: true });
95021
95484
  /**
95022
95485
  * Obstacle rects (absolute slide coords) for connector A* routing: every
95023
95486
  * non-connector element with a positive footprint. Bent connectors detour
@@ -95571,7 +96034,8 @@ class SlideCanvasComponent {
95571
96034
  // is the live, still-mounted textarea (this handler runs off its own
95572
96035
  // `blur`), so no separate DOM lookup is needed here.
95573
96036
  const height = resolveCommitTextAutoFitHeight(this.allElements(), id, editor);
95574
- this.textCommit.emit(height !== undefined ? { id, text: editor.value, height } : { id, text: editor.value });
96037
+ const text = this.viewerOpts ? this.viewerOpts.autoCorrect(editor.value) : editor.value;
96038
+ this.textCommit.emit(height !== undefined ? { id, text, height } : { id, text });
95575
96039
  }
95576
96040
  onContextMenu(event) {
95577
96041
  if (!this.editable()) {
@@ -97531,6 +97995,20 @@ function toolbarVisibility(hiddenActions) {
97531
97995
  isHidden: (id) => isActionHidden(id, hiddenActions()),
97532
97996
  };
97533
97997
  }
97998
+ /**
97999
+ * Union the host's own `hiddenActions` input with File > Options > Customize
98000
+ * Ribbon's `ribbon.hiddenTabIds`, so both reach the same filter every chrome
98001
+ * component already gates on. `ToolbarTabId` is a subtype of `ToolbarActionId`,
98002
+ * so a hidden tab id fits directly into the result.
98003
+ *
98004
+ * Without this, Customize Ribbon changed only what its own pane displayed:
98005
+ * nothing downstream (the ribbon's tab strip, the title bar, the mobile
98006
+ * toolbar/menu, the status bar) ever read `ribbon.hiddenTabIds`, so ticking a
98007
+ * tab off there left every one of them unchanged.
98008
+ */
98009
+ function mergeHiddenActions(hostHiddenActions, ribbonHiddenTabIds) {
98010
+ return [...hostHiddenActions, ...ribbonHiddenTabIds];
98011
+ }
97534
98012
 
97535
98013
  /**
97536
98014
  * mobile-toolbar.component.ts: Compact mobile top toolbar.
@@ -99230,11 +99708,13 @@ class PrintService {
99230
99708
  async print(rawSettings, slides, activeSlideIndex, captureSlide, slideSize = {
99231
99709
  width: DEFAULT_CANVAS_WIDTH,
99232
99710
  height: DEFAULT_CANVAS_HEIGHT,
99233
- }) {
99711
+ },
99712
+ /** Options > Advanced > "Print hidden slides". Defaults to PowerPoint's own default (excluded). */
99713
+ includeHiddenSlides = false) {
99234
99714
  this.closeDialog();
99235
99715
  const settings = validatePrintSettings(rawSettings, slides.length);
99236
99716
  const colorFilter = computeColorFilter(settings.colorMode);
99237
- const slideIndices = computeSlideIndices(settings.slideRange, activeSlideIndex, slides.length, settings.customRangeFrom, settings.customRangeTo);
99717
+ const slideIndices = filterHiddenSlideIndices(computeSlideIndices(settings.slideRange, activeSlideIndex, slides.length, settings.customRangeFrom, settings.customRangeTo), slides, includeHiddenSlides);
99238
99718
  if (slideIndices.length === 0) {
99239
99719
  return false;
99240
99720
  }
@@ -99247,6 +99727,7 @@ class PrintService {
99247
99727
  orientation: settings.orientation,
99248
99728
  colorFilter,
99249
99729
  frameSlides: settings.frameSlides,
99730
+ scaleToFit: settings.scaleToFit,
99250
99731
  }));
99251
99732
  }
99252
99733
  if (settings.printWhat === 'slides') {
@@ -99267,9 +99748,18 @@ class PrintService {
99267
99748
  title: this.translate.instant('pptx.sections.slides'),
99268
99749
  orientation: settings.orientation,
99269
99750
  colorFilter,
99751
+ scaleToFit: settings.scaleToFit,
99270
99752
  }));
99271
99753
  }
99272
99754
  // ── Capture the requested slides to PNG data URLs ─────────────────
99755
+ // `captureSlide` awaits per slide, so the print window has to be opened
99756
+ // NOW, before that first await, or the browser silently blocks it as a
99757
+ // popup the instant the call stack leaves the click's user gesture (see
99758
+ // `openPendingPrintWindow`, shared by every window.open-based binding).
99759
+ const pendingWindow = openPendingPrintWindow(this.translate.instant('pptx.print.preparingToPrint'));
99760
+ if (!pendingWindow) {
99761
+ return false;
99762
+ }
99273
99763
  const slideImages = [];
99274
99764
  const capturedIndices = [];
99275
99765
  for (const idx of slideIndices) {
@@ -99280,19 +99770,22 @@ class PrintService {
99280
99770
  }
99281
99771
  }
99282
99772
  if (slideImages.length === 0) {
99773
+ pendingWindow.close();
99283
99774
  return false;
99284
99775
  }
99285
99776
  if (settings.printWhat === 'notes') {
99286
- return this._open(buildPrintHtmlDocument({
99777
+ finishPrintWindow(pendingWindow, buildPrintHtmlDocument({
99287
99778
  title: this.translate.instant('pptx.print.notesPages'),
99288
99779
  bodyHtml: buildNotesHtml(slideImages, capturedIndices, slides),
99289
99780
  orientation: 'portrait',
99290
99781
  colorFilter,
99291
99782
  frameSlides: settings.frameSlides,
99783
+ scaleToFit: settings.scaleToFit,
99292
99784
  }));
99785
+ return true;
99293
99786
  }
99294
99787
  // printWhat === 'handouts'
99295
- return this._open(buildPrintHtmlDocument({
99788
+ finishPrintWindow(pendingWindow, buildPrintHtmlDocument({
99296
99789
  title: this.translate.instant('pptx.print.handoutPerPageTitle', {
99297
99790
  count: settings.slidesPerPage,
99298
99791
  }),
@@ -99300,28 +99793,22 @@ class PrintService {
99300
99793
  orientation: 'portrait',
99301
99794
  colorFilter,
99302
99795
  frameSlides: settings.frameSlides,
99796
+ scaleToFit: settings.scaleToFit,
99303
99797
  }));
99798
+ return true;
99304
99799
  }
99305
99800
  /* ---------------------------------------------------------------- */
99306
99801
  /* Internal: print-window side effects (DOM only) */
99307
99802
  /* ---------------------------------------------------------------- */
99308
99803
  /**
99309
- * Open a print window, write the document, focus, and trigger printing.
99310
- * Returns `false` if the popup was blocked.
99804
+ * Open a print window, write the document, focus, and trigger printing, all
99805
+ * in one synchronous call. Used by the outline/slides paths, which never
99806
+ * `await` before this point so the window is never at risk of being popup
99807
+ * blocked -- no need for the placeholder-then-real-document split `print`'s
99808
+ * notes/handouts branch needs (see `openPendingPrintWindow`/`finishPrintWindow`).
99311
99809
  */
99312
99810
  _open(htmlDocument) {
99313
- const printWindow = window.open('', '_blank', 'noopener,noreferrer');
99314
- if (!printWindow) {
99315
- return false;
99316
- }
99317
- printWindow.document.open();
99318
- printWindow.document.write(htmlDocument);
99319
- printWindow.document.close();
99320
- printWindow.focus();
99321
- setTimeout(() => {
99322
- printWindow.print();
99323
- }, 300);
99324
- return true;
99811
+ return openPrintWindow(htmlDocument);
99325
99812
  }
99326
99813
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PrintService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
99327
99814
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PrintService }); }
@@ -99622,6 +100109,8 @@ class ViewerCanvasEditingService {
99622
100109
  this.dialogs = inject(ViewerDialogsService);
99623
100110
  this.formatPainter = inject(ViewerFormatPainterService);
99624
100111
  this.collab = inject(CollaborationService);
100112
+ /** Options > Proofing > AutoCorrect, applied to committed inline-edit text. */
100113
+ this.viewerOpts = inject(ViewerOptionsService, { optional: true });
99625
100114
  /** Id of the element being inline text-edited, or null. */
99626
100115
  this.editingId = signal(null, /* @ts-ignore */
99627
100116
  ...(ngDevMode ? [{ debugName: "editingId" }] : /* istanbul ignore next */ []));
@@ -99807,7 +100296,10 @@ class ViewerCanvasEditingService {
99807
100296
  if (!el || el.type !== 'table') {
99808
100297
  return;
99809
100298
  }
99810
- const updated = setCellText(el, event.commit.rowIndex, event.commit.colIndex, event.commit.text);
100299
+ const text = this.viewerOpts
100300
+ ? this.viewerOpts.autoCorrect(event.commit.text)
100301
+ : event.commit.text;
100302
+ const updated = setCellText(el, event.commit.rowIndex, event.commit.colIndex, text);
99811
100303
  this.editor.updateElement(host.activeSlideIndex(), event.id, {
99812
100304
  tableData: updated.tableData,
99813
100305
  });
@@ -100030,6 +100522,7 @@ function buildShareUrl(roomId, serverUrl, location) {
100030
100522
  class ViewerCollaborationSessionService {
100031
100523
  constructor() {
100032
100524
  this.collab = inject(CollaborationService);
100525
+ this.viewerOpts = inject(ViewerOptionsService, { optional: true });
100033
100526
  /** Share (collaboration) dialog visibility. */
100034
100527
  this.showShare = signal(false, /* @ts-ignore */
100035
100528
  ...(ngDevMode ? [{ debugName: "showShare" }] : /* istanbul ignore next */ []));
@@ -100069,6 +100562,7 @@ class ViewerCollaborationSessionService {
100069
100562
  }
100070
100563
  return buildActiveSessionUsers({
100071
100564
  localUserName: config.userName,
100565
+ localUserInitials: this.viewerOpts?.options().general.userInitials,
100072
100566
  localUserColor: config.userColor,
100073
100567
  remoteUsers: this.collab.presence(),
100074
100568
  });
@@ -100290,6 +100784,21 @@ function annotationMapToInkInserts(map) {
100290
100784
  }
100291
100785
  return inserts;
100292
100786
  }
100787
+ /**
100788
+ * Real runtime availability for the Options > Add-ins pane, for the catalog
100789
+ * ids this host can answer cheaply. Every other id (emfConverter,
100790
+ * mtxDecompressor, locales) has no meaningful "off" state: they are
100791
+ * compile-time bundled dependencies, always present, so they fall back to
100792
+ * `resolveViewerAddinRows`'s own `active: true` default instead of a
100793
+ * fabricated signal.
100794
+ */
100795
+ function resolveViewerExtraAddinStatus(flags) {
100796
+ return {
100797
+ smartArt3d: flags.smartArt3dEnabled,
100798
+ model3d: !flags.disable3DRendering,
100799
+ collaboration: flags.collaborationConnected,
100800
+ };
100801
+ }
100293
100802
  /**
100294
100803
  * Return a new slide array with the accepted diff applied: an `added` slide is
100295
100804
  * appended, a `changed`/`removed` slide adopts the incoming (`compareSlide`)
@@ -100324,6 +100833,7 @@ class ViewerCompareService {
100324
100833
  this.svc = inject(ViewerDialogsService);
100325
100834
  this.editor = inject(EditorStateService);
100326
100835
  this.translate = inject(TranslateService);
100836
+ this.optionsService = inject(ViewerOptionsService);
100327
100837
  }
100328
100838
  /**
100329
100839
  * Open a `.pptx` picker and diff it against the current deck, opening the
@@ -100350,7 +100860,8 @@ class ViewerCompareService {
100350
100860
  try {
100351
100861
  const buffer = await file.arrayBuffer();
100352
100862
  const handler = new PptxHandler();
100353
- const parsed = await handler.load(buffer);
100863
+ const allowExternalImages = this.optionsService.options().trust.allowExternalContent;
100864
+ const parsed = await handler.load(buffer, { allowExternalImages });
100354
100865
  const result = compareSlides([...this.editor.slides()], [...parsed.slides]);
100355
100866
  this.svc.compareResult.set(result);
100356
100867
  this.svc.showCompare.set(true);
@@ -100734,7 +101245,7 @@ class ViewerExportService {
100734
101245
  }
100735
101246
  this.exporting.set(true);
100736
101247
  try {
100737
- await this.exportSvc.exportElementToPng(el, slideFileName('slide', host.activeSlideIndex() + 1, 'png'));
101248
+ await this.exportSvc.exportElementToPng(el, slideFileName('slide', host.activeSlideIndex() + 1, 'png'), host.imageExportScale?.() ?? 2);
100738
101249
  }
100739
101250
  finally {
100740
101251
  this.exporting.set(false);
@@ -100742,13 +101253,14 @@ class ViewerExportService {
100742
101253
  }
100743
101254
  /** Copy the current slide to the system clipboard as a PNG image. */
100744
101255
  async copySlideAsImage() {
100745
- const el = this.requireHost().resolveStage();
101256
+ const host = this.requireHost();
101257
+ const el = host.resolveStage();
100746
101258
  if (!el || this.exporting()) {
100747
101259
  return;
100748
101260
  }
100749
101261
  this.exporting.set(true);
100750
101262
  try {
100751
- await this.exportSvc.copyElementAsPng(el);
101263
+ await this.exportSvc.copyElementAsPng(el, host.imageExportScale?.() ?? 2);
100752
101264
  }
100753
101265
  catch (err) {
100754
101266
  console.error('[PowerPointViewer] Copy slide as image failed:', err);
@@ -100770,7 +101282,7 @@ class ViewerExportService {
100770
101282
  const controller = this.beginExport(this.translate.instant('pptx.mobileMenu.exportPdf'));
100771
101283
  const { width, height } = this.loader.canvasSize();
100772
101284
  try {
100773
- const canvases = await this.captureSlideCanvases(controller.signal, this.translate.instant('pptx.export.rendering'), 90);
101285
+ const canvases = await this.captureSlideCanvases(controller.signal, this.translate.instant('pptx.export.rendering'), 90, this.requireHost().imageExportScale?.() ?? 2);
100774
101286
  this.progress.set(EXPORT_ASSEMBLING_PERCENT);
100775
101287
  this.statusMessage.set(this.translate.instant('pptx.export.buildingPdf'));
100776
101288
  this.exportSvc.exportCanvasesToPdf(canvases, width, height, 'presentation.pdf');
@@ -100834,11 +101346,18 @@ class ViewerExportService {
100834
101346
  this.endExport();
100835
101347
  }
100836
101348
  }
100837
- async onPrint(settings) {
101349
+ /**
101350
+ * `includeHiddenSlides`: Options > Advanced > "Print hidden slides".
101351
+ * `highQuality`: Options > Advanced > "High quality" raster scale for the
101352
+ * notes/handouts fallback path, composed on top of the host's own Image
101353
+ * Size/Quality scale.
101354
+ */
101355
+ async onPrint(settings, includeHiddenSlides = false, highQuality = false) {
100838
101356
  const host = this.requireHost();
100839
101357
  const original = host.activeSlideIndex();
101358
+ const printScale = (host.imageExportScale?.() ?? 2) * (highQuality ? 2 : 1);
100840
101359
  try {
100841
- await this.print.print(settings, [...host.mergedSlides()], original, (index) => this.captureSlideDataUrl(index), this.loader.canvasSize());
101360
+ await this.print.print(settings, [...host.mergedSlides()], original, (index) => this.captureSlideDataUrl(index, printScale), this.loader.canvasSize(), includeHiddenSlides);
100842
101361
  }
100843
101362
  finally {
100844
101363
  host.activeSlideIndex.set(original);
@@ -100873,7 +101392,7 @@ class ViewerExportService {
100873
101392
  * Render every slide to a canvas (each made the live stage in turn), reporting
100874
101393
  * per-slide progress and bailing out cooperatively when `abortSignal.aborted`.
100875
101394
  */
100876
- async captureSlideCanvases(abortSignal, verb, span) {
101395
+ async captureSlideCanvases(abortSignal, verb, span, scale = 2) {
100877
101396
  const host = this.requireHost();
100878
101397
  const total = host.slideCount();
100879
101398
  const original = host.activeSlideIndex();
@@ -100891,7 +101410,7 @@ class ViewerExportService {
100891
101410
  });
100892
101411
  const el = host.resolveStage();
100893
101412
  if (el) {
100894
- canvases.push(await this.exportSvc.renderElement(el));
101413
+ canvases.push(await this.exportSvc.renderElement(el, scale));
100895
101414
  }
100896
101415
  }
100897
101416
  }
@@ -100900,8 +101419,13 @@ class ViewerExportService {
100900
101419
  }
100901
101420
  return canvases;
100902
101421
  }
100903
- /** Flip the live stage to `index`, let it settle, and capture it to a PNG data URL. */
100904
- async captureSlideDataUrl(index) {
101422
+ /**
101423
+ * Flip the live stage to `index`, let it settle, and capture it to a PNG
101424
+ * data URL. `scale` defaults to the host's own Image Size/Quality scale
101425
+ * (matching PNG/PDF export); the print notes/handouts path passes a higher
101426
+ * value when Options > Advanced > "High quality" is on.
101427
+ */
101428
+ async captureSlideDataUrl(index, scale) {
100905
101429
  const host = this.requireHost();
100906
101430
  host.activeSlideIndex.set(index);
100907
101431
  await new Promise((resolve) => {
@@ -100911,7 +101435,7 @@ class ViewerExportService {
100911
101435
  if (!el) {
100912
101436
  return null;
100913
101437
  }
100914
- const canvas = await this.exportSvc.renderElement(el);
101438
+ const canvas = await this.exportSvc.renderElement(el, scale ?? host.imageExportScale?.() ?? 2);
100915
101439
  return canvas.toDataURL('image/png');
100916
101440
  }
100917
101441
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ViewerExportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
@@ -100921,18 +101445,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
100921
101445
  type: Injectable
100922
101446
  }] });
100923
101447
 
100924
- /** Build the ZIP downloaded by the File tab's Package for Sharing action. */
100925
- async function buildSharingPackage(presentation, presentationFilename) {
100926
- const zip = new JSZip();
100927
- const folder = zip.folder('presentation-package');
100928
- if (!folder) {
100929
- throw new Error('Unable to create presentation package');
100930
- }
100931
- folder.file(presentationFilename, presentation);
100932
- folder.file('README.txt', generatePackageReadme(presentationFilename));
100933
- return zip.generateAsync({ type: 'blob' });
100934
- }
100935
-
100936
101448
  /**
100937
101449
  * viewer-file-io.service.ts: Viewer-scoped state + logic for getting `.pptx`
100938
101450
  * bytes in and out of the viewer: the built-in File ▸ Open override signal (a
@@ -101014,6 +101526,7 @@ class ViewerFileIOService {
101014
101526
  : await this.loader.saveSlides(this.loader.slides(), format, undefined, intent);
101015
101527
  host.emitContentChange(bytes);
101016
101528
  this.exportSvc.savePresentation(bytes, `presentation.${format}`, format);
101529
+ host.afterSuccessfulSave(format);
101017
101530
  }
101018
101531
  async saveAsPptx() {
101019
101532
  await this.saveAs('pptx');
@@ -101049,12 +101562,6 @@ class ViewerFileIOService {
101049
101562
  presentationProperties: this.loader.presentationProperties(),
101050
101563
  }, sourceName);
101051
101564
  }
101052
- /** Bundle the presentation and its usage notes in a shareable ZIP archive. */
101053
- async packageForSharing() {
101054
- const presentationFilename = 'presentation.pptx';
101055
- const blob = await buildSharingPackage(await this.getContent(), presentationFilename);
101056
- downloadBlob(blob, 'presentation-package.zip');
101057
- }
101058
101565
  /**
101059
101566
  * File ▸ Open: host override (`onOpenFile` input) takes precedence; otherwise
101060
101567
  * a built-in native picker loads the chosen presentation in place.
@@ -101611,134 +102118,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
101611
102118
  type: Injectable
101612
102119
  }] });
101613
102120
 
101614
- /**
101615
- * viewer-options.service.ts: signal-based owner of the File > Options store for
101616
- * one viewer instance (the Angular counterpart of React's `useViewerOptions`).
101617
- *
101618
- * Wraps the framework-neutral {@link createViewerOptionsStore} (which persists a
101619
- * sparse diff into the shared `pptx-viewer-prefs` localStorage entry) behind an
101620
- * Angular signal, and bundles the option-to-behavior helpers the rest of the
101621
- * viewer consumes: history depth, autosave cadence, print defaults, screen
101622
- * tips, root classes, AutoCorrect, feedback sounds, hyperlink confirmation,
101623
- * protected view, and the Options > Save cache purge.
101624
- *
101625
- * Deliberately constructible with plain `new` (no required injection context)
101626
- * so the colocated unit tests can exercise it without TestBed, matching
101627
- * {@link EditorStateService}'s optional-inject pattern.
101628
- */
101629
- class ViewerOptionsService {
101630
- constructor() {
101631
- /**
101632
- * Optional: `inject()` needs an active injection context, which plain
101633
- * `new ViewerOptionsService()` (used by the colocated unit tests) does not
101634
- * provide. Outside DI the subscription simply lives as long as the instance.
101635
- */
101636
- this.destroyRef = (() => {
101637
- try {
101638
- return inject(DestroyRef);
101639
- }
101640
- catch {
101641
- return null;
101642
- }
101643
- })();
101644
- this.translate = (() => {
101645
- try {
101646
- return inject(TranslateService);
101647
- }
101648
- catch {
101649
- return null;
101650
- }
101651
- })();
101652
- /** Imperative store: hydrates from and persists to `pptx-viewer-prefs`. */
101653
- this.store = createViewerOptionsStore();
101654
- this._options = signal(this.store.getOptions(), /* @ts-ignore */
101655
- ...(ngDevMode ? [{ debugName: "_options" }] : /* istanbul ignore next */ []));
101656
- /** Reactive File > Options snapshot; a new object per change. */
101657
- this.options = this._options.asReadonly();
101658
- const unsubscribe = this.store.subscribe((next) => this._options.set(next));
101659
- this.destroyRef?.onDestroy(unsubscribe);
101660
- }
101661
- // ── Store mutations ─────────────────────────────────────────────────────
101662
- setValue(group, key, value) {
101663
- this.store.setValue(group, key, value);
101664
- }
101665
- setRibbonTabHidden(tabId, hidden) {
101666
- this.store.setRibbonTabHidden(tabId, hidden);
101667
- }
101668
- setQuickAccessCommands(commandIds) {
101669
- this.store.setQuickAccessCommands(commandIds);
101670
- }
101671
- reset(group) {
101672
- this.store.reset(group);
101673
- }
101674
- /** Restore a snapshot wholesale (the dialog's Cancel semantics). */
101675
- restore(snapshot) {
101676
- this.store.setOptions(snapshot);
101677
- }
101678
- // ── Behavior resolution helpers ─────────────────────────────────────────
101679
- /** Undo-stack depth for `new EditorHistory({ maxDepth })`. */
101680
- historyDepth() {
101681
- return resolveHistoryDepth(this.options());
101682
- }
101683
- /** AutoRecover cadence in seconds for the autosave engine. */
101684
- autosaveIntervalSeconds() {
101685
- return resolveAutosaveIntervalSeconds(this.options());
101686
- }
101687
- /** Print-dialog seed; `undefined` keeps the dialog's own recents. */
101688
- printDefaults() {
101689
- return resolveDefaultPrintSettings(this.options());
101690
- }
101691
- /** Option-driven CSS classes for the viewer root (`pptx-ng-*` prefixed). */
101692
- rootClasses() {
101693
- return resolveOptionRootClasses(this.options(), 'pptx-ng');
101694
- }
101695
- /** Tooltip text under the current ScreenTip style (undefined = suppress). */
101696
- screenTip(label, description, shortcut) {
101697
- return resolveScreenTip(this.options(), label, description, shortcut);
101698
- }
101699
- /** Run the enabled AutoCorrect rules over a committed run of text. */
101700
- autoCorrect(text) {
101701
- return applyAutoCorrect(text, this.options().proofing);
101702
- }
101703
- /** Play the Accessibility "feedback with sound" cue for a completed action. */
101704
- playFeedback() {
101705
- playFeedbackSound(this.options());
101706
- }
101707
- /** Whether Trust Center forces the deck to open read-only. */
101708
- protectedView() {
101709
- return shouldOpenInProtectedView(this.options());
101710
- }
101711
- /**
101712
- * Gate an external hyperlink activation. Returns `true` when navigation may
101713
- * proceed (no confirmation required, or the user confirmed the prompt).
101714
- */
101715
- confirmExternalHyperlink(href) {
101716
- if (!shouldConfirmExternalHyperlink(this.options(), href)) {
101717
- return true;
101718
- }
101719
- if (typeof window === 'undefined' || typeof window.confirm !== 'function') {
101720
- return true;
101721
- }
101722
- const label = this.translate?.instant('pptx.options.trust.confirmHyperlinks') ??
101723
- 'Confirm before opening external hyperlinks';
101724
- return window.confirm(`${label}\n\n${href}`);
101725
- }
101726
- /**
101727
- * Options > Save > "Delete cached files": purge every autosave recovery
101728
- * snapshot from the shared IndexedDB store. Resolves with the purge count.
101729
- */
101730
- async clearCache() {
101731
- const snapshots = await listAutosaveSnapshots();
101732
- await Promise.all(snapshots.map((entry) => deleteAutosaveSnapshot(entry.key)));
101733
- return snapshots.length;
101734
- }
101735
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ViewerOptionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
101736
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ViewerOptionsService }); }
101737
- }
101738
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ViewerOptionsService, decorators: [{
101739
- type: Injectable
101740
- }], ctorParameters: () => [] });
101741
-
101742
102121
  /**
101743
102122
  * Whether a click/tap/swipe advance must be swallowed instead of moving to the
101744
102123
  * next slide. A click still steps the current slide's remaining animation
@@ -103476,6 +103855,120 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
103476
103855
  args: [{ selector: 'pptx-presentation-annotation-overlay', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgStyle], template: "@if (isArmed()) {\n\t<div\n\t\tclass=\"pptx-ng-anno-wrapper\"\n\t\t[ngStyle]=\"wrapperStyle()\"\n\t\t(pointerdown)=\"onPointerDown($event)\"\n\t\t(pointermove)=\"onPointerMove($event)\"\n\t\t(pointerup)=\"onPointerUp($event)\"\n\t\t(pointerleave)=\"onPointerLeave($event)\"\n\t>\n\t\t<svg\n\t\t\t#svg\n\t\t\tclass=\"pptx-ng-anno-svg\"\n\t\t\t[attr.width]=\"canvasSize().width\"\n\t\t\t[attr.height]=\"canvasSize().height\"\n\t\t\t[attr.viewBox]=\"viewBox()\"\n\t\t\t[ngStyle]=\"svgStyle()\"\n\t\t>\n\t\t\t@for (s of allStrokes(); track s.id) {\n\t\t\t\t<path\n\t\t\t\t\t[attr.d]=\"strokePath(s.points)\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t[attr.stroke]=\"s.color\"\n\t\t\t\t\t[attr.stroke-width]=\"s.width\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\t[attr.opacity]=\"s.opacity\"\n\t\t\t\t/>\n\t\t\t}\n\t\t</svg>\n\n\t\t@if (service.tool() === 'laser' && service.laserPosition(); as lp) {\n\t\t\t<div class=\"pptx-ng-laser-dot\" [ngStyle]=\"laserDotStyle(lp.x, lp.y)\"></div>\n\t\t}\n\t</div>\n}\n", styles: [":host{display:block;position:absolute;inset:0;pointer-events:none}.pptx-ng-anno-wrapper{position:absolute;inset:0}.pptx-ng-anno-svg{position:absolute;top:0;left:0;transform-origin:top left;overflow:visible}.pptx-ng-laser-dot{position:absolute;border-radius:50%;pointer-events:none;background:#ff0000d9;box-shadow:0 0 12px 6px #ff000080,0 0 24px 12px #ff000040;filter:drop-shadow(0 0 8px rgba(255,0,0,.7))}\n"] }]
103477
103856
  }], propDecorators: { canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], zoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoom", required: false }] }], svgRef: [{ type: i0.ViewChild, args: ['svg', { isSignal: true }] }] } });
103478
103857
 
103858
+ /**
103859
+ * presentation-context-menu.component.ts: right-click menu shown while
103860
+ * presenting.
103861
+ *
103862
+ * Selector: `pptx-presentation-context-menu`
103863
+ *
103864
+ * Item order/grouping/i18n keys come from the shared
103865
+ * `getPresentationContextMenuSections` (`pptx-viewer-shared`), the same
103866
+ * source React's `PresentationContextMenu` and Vue's `PresentationMode`
103867
+ * render from, so this menu cannot drift from theirs. This component only
103868
+ * describes what capabilities are available (always all of them here: the
103869
+ * overlay already has next/prev, See All Slides, presenter view, pointer
103870
+ * tools, and the black/white blank screen) and routes a chosen action id
103871
+ * back to the overlay via a single output.
103872
+ *
103873
+ * Closes on Escape and on an outside pointerdown, matching
103874
+ * `EditorContextMenuComponent`.
103875
+ */
103876
+ class PresentationContextMenuComponent {
103877
+ constructor() {
103878
+ /** Horizontal viewport coordinate (px) of the top-left corner of the menu. */
103879
+ this.x = input.required(/* @ts-ignore */
103880
+ ...(ngDevMode ? [{ debugName: "x" }] : /* istanbul ignore next */ []));
103881
+ /** Vertical viewport coordinate (px) of the top-left corner of the menu. */
103882
+ this.y = input.required(/* @ts-ignore */
103883
+ ...(ngDevMode ? [{ debugName: "y" }] : /* istanbul ignore next */ []));
103884
+ /** Emitted when the menu should close (Escape, outside click, or after an action). */
103885
+ this.closed = output();
103886
+ /** The chosen action id; the overlay maps it onto its own navigator/annotations/etc. */
103887
+ this.action = output();
103888
+ this.host = inject(ElementRef);
103889
+ this.sections = computed(() => getPresentationContextMenuSections({
103890
+ seeAllSlides: true,
103891
+ presenterView: true,
103892
+ pointerTools: true,
103893
+ eraseInk: true,
103894
+ blankBlack: true,
103895
+ blankWhite: true,
103896
+ }), /* @ts-ignore */
103897
+ ...(ngDevMode ? [{ debugName: "sections" }] : /* istanbul ignore next */ []));
103898
+ }
103899
+ onEscape() {
103900
+ this.closed.emit();
103901
+ }
103902
+ onDocumentPointerDown(event) {
103903
+ const target = event.target;
103904
+ if (!(target instanceof Node)) {
103905
+ return;
103906
+ }
103907
+ if (!this.host.nativeElement.contains(target)) {
103908
+ this.closed.emit();
103909
+ }
103910
+ }
103911
+ run(id) {
103912
+ this.action.emit(id);
103913
+ this.closed.emit();
103914
+ }
103915
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PresentationContextMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
103916
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: PresentationContextMenuComponent, isStandalone: true, selector: "pptx-presentation-context-menu", inputs: { x: { classPropertyName: "x", publicName: "x", isSignal: true, isRequired: true, transformFunction: null }, y: { classPropertyName: "y", publicName: "y", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { closed: "closed", action: "action" }, host: { listeners: { "document:keydown.escape": "onEscape()", "document:pointerdown": "onDocumentPointerDown($event)" }, properties: { "style.--pptx-ctx-x": "x() + \"px\"", "style.--pptx-ctx-y": "y() + \"px\"" } }, ngImport: i0, template: `
103917
+ <ul
103918
+ class="pptx-ctx__menu"
103919
+ data-pptx-presentation-menu="true"
103920
+ role="menu"
103921
+ (contextmenu)="$event.preventDefault()"
103922
+ >
103923
+ @for (section of sections(); track section.id; let sectionIndex = $index) {
103924
+ @if (sectionIndex > 0) {
103925
+ <li role="separator" class="pptx-ctx__divider"></li>
103926
+ }
103927
+ @for (item of section.items; track item.id) {
103928
+ <li role="none">
103929
+ <button type="button" class="pptx-ctx__item" role="menuitem" (click)="run(item.id)">
103930
+ {{ item.labelKey | translate }}
103931
+ </button>
103932
+ </li>
103933
+ }
103934
+ }
103935
+ </ul>
103936
+ `, isInline: true, styles: [":host{position:fixed;left:var(--pptx-ctx-x, 0px);top:var(--pptx-ctx-y, 0px);z-index:9000;display:block}.pptx-ctx__menu{list-style:none;margin:0;padding:4px 0;min-width:160px;background:var(--pptx-ctx-bg, #252526);color:var(--pptx-ctx-fg, #e0e0e0);border:1px solid var(--pptx-ctx-border, #454545);border-radius:4px;box-shadow:0 4px 12px #0006,0 1px 3px #0000004d;font-size:13px;-webkit-user-select:none;user-select:none}.pptx-ctx__item{display:block;width:100%;padding:5px 14px;background:transparent;border:none;color:inherit;text-align:left;cursor:pointer;font-size:inherit;white-space:nowrap}.pptx-ctx__item:hover:not(:disabled){background:var(--pptx-ctx-hover, #094771);color:var(--pptx-ctx-hover-fg, #ffffff)}.pptx-ctx__item:disabled{opacity:.4;pointer-events:none;cursor:default}.pptx-ctx__item--danger{color:var(--pptx-ctx-danger, #f47c7c)}.pptx-ctx__item--danger:hover:not(:disabled){background:var(--pptx-ctx-danger-hover, #4a1a1a);color:var(--pptx-ctx-danger-fg, #ffaaaa)}.pptx-ctx__divider{height:1px;background:var(--pptx-ctx-divider, #454545);margin:3px 0}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
103937
+ }
103938
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PresentationContextMenuComponent, decorators: [{
103939
+ type: Component,
103940
+ args: [{ selector: 'pptx-presentation-context-menu', standalone: true, imports: [TranslatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: `
103941
+ <ul
103942
+ class="pptx-ctx__menu"
103943
+ data-pptx-presentation-menu="true"
103944
+ role="menu"
103945
+ (contextmenu)="$event.preventDefault()"
103946
+ >
103947
+ @for (section of sections(); track section.id; let sectionIndex = $index) {
103948
+ @if (sectionIndex > 0) {
103949
+ <li role="separator" class="pptx-ctx__divider"></li>
103950
+ }
103951
+ @for (item of section.items; track item.id) {
103952
+ <li role="none">
103953
+ <button type="button" class="pptx-ctx__item" role="menuitem" (click)="run(item.id)">
103954
+ {{ item.labelKey | translate }}
103955
+ </button>
103956
+ </li>
103957
+ }
103958
+ }
103959
+ </ul>
103960
+ `, host: {
103961
+ '[style.--pptx-ctx-x]': 'x() + "px"',
103962
+ '[style.--pptx-ctx-y]': 'y() + "px"',
103963
+ }, styles: [":host{position:fixed;left:var(--pptx-ctx-x, 0px);top:var(--pptx-ctx-y, 0px);z-index:9000;display:block}.pptx-ctx__menu{list-style:none;margin:0;padding:4px 0;min-width:160px;background:var(--pptx-ctx-bg, #252526);color:var(--pptx-ctx-fg, #e0e0e0);border:1px solid var(--pptx-ctx-border, #454545);border-radius:4px;box-shadow:0 4px 12px #0006,0 1px 3px #0000004d;font-size:13px;-webkit-user-select:none;user-select:none}.pptx-ctx__item{display:block;width:100%;padding:5px 14px;background:transparent;border:none;color:inherit;text-align:left;cursor:pointer;font-size:inherit;white-space:nowrap}.pptx-ctx__item:hover:not(:disabled){background:var(--pptx-ctx-hover, #094771);color:var(--pptx-ctx-hover-fg, #ffffff)}.pptx-ctx__item:disabled{opacity:.4;pointer-events:none;cursor:default}.pptx-ctx__item--danger{color:var(--pptx-ctx-danger, #f47c7c)}.pptx-ctx__item--danger:hover:not(:disabled){background:var(--pptx-ctx-danger-hover, #4a1a1a);color:var(--pptx-ctx-danger-fg, #ffaaaa)}.pptx-ctx__divider{height:1px;background:var(--pptx-ctx-divider, #454545);margin:3px 0}\n"] }]
103964
+ }], propDecorators: { x: [{ type: i0.Input, args: [{ isSignal: true, alias: "x", required: true }] }], y: [{ type: i0.Input, args: [{ isSignal: true, alias: "y", required: true }] }], closed: [{ type: i0.Output, args: ["closed"] }], action: [{ type: i0.Output, args: ["action"] }], onEscape: [{
103965
+ type: HostListener,
103966
+ args: ['document:keydown.escape']
103967
+ }], onDocumentPointerDown: [{
103968
+ type: HostListener,
103969
+ args: ['document:pointerdown', ['$event']]
103970
+ }] } });
103971
+
103479
103972
  /**
103480
103973
  * presentation-fullscreen.ts
103481
103974
  *
@@ -103773,13 +104266,31 @@ class PresentationInputController {
103773
104266
  /**
103774
104267
  * Run any on-slide action under the pointer, and report what the click left
103775
104268
  * for the show: only `'advance'` reaches {@link advanceFromClick}.
104269
+ *
104270
+ * Reimplements `handlePresentationStageClick`'s classify-then-run in two
104271
+ * steps (rather than calling it directly) so an `openUrl` intent can be
104272
+ * gated by Trust Center > "Confirm before opening external hyperlinks"
104273
+ * before the navigation actually runs. A declined confirmation still
104274
+ * consumes the click (PowerPoint does not also advance the slide).
103776
104275
  */
103777
104276
  handleActionClick(target) {
103778
- return handlePresentationStageClick(target, this.deps.currentSlide(), { slideCount: this.deps.slides().length }, {
104277
+ const outcome = resolvePresentationClick(target, this.deps.currentSlide());
104278
+ if (outcome.kind !== 'action') {
104279
+ return outcome.kind;
104280
+ }
104281
+ const options = { slideCount: this.deps.slides().length };
104282
+ const { intent } = resolvePresentationAction(outcome.action, options);
104283
+ if (intent.kind === 'openUrl' &&
104284
+ this.deps.confirmExternalHyperlink &&
104285
+ !this.deps.confirmExternalHyperlink(intent.url)) {
104286
+ return 'action';
104287
+ }
104288
+ runPresentationAction(outcome.action, options, {
103779
104289
  goToSlide: (index) => this.deps.navigator.goToSlide(index),
103780
104290
  move: (direction) => this.deps.navigator.navigate(direction > 0 ? 'next' : 'prev'),
103781
104291
  endShow: () => this.deps.requestClose(),
103782
104292
  });
104293
+ return 'action';
103783
104294
  }
103784
104295
  /**
103785
104296
  * Click/tap/swipe advance. Like every forward step it first reveals the
@@ -104577,6 +105088,13 @@ class PresentationToolbarComponent {
104577
105088
  /** Whether presenter view is currently up (tints the toggle). */
104578
105089
  this.presenterMode = input(false, /* @ts-ignore */
104579
105090
  ...(ngDevMode ? [{ debugName: "presenterMode" }] : /* istanbul ignore next */ []));
105091
+ /**
105092
+ * File > Options > Advanced > "Show popup toolbar" (default true). When
105093
+ * `false`, `mousemove` never auto-reveals the bar; `toggleVisible`
105094
+ * (PowerPoint's Ctrl+H) still works.
105095
+ */
105096
+ this.popupToolbarEnabled = input(true, /* @ts-ignore */
105097
+ ...(ngDevMode ? [{ debugName: "popupToolbarEnabled" }] : /* istanbul ignore next */ []));
104580
105098
  /** Step the show by one slide (`-1` back, `1` forward). */
104581
105099
  this.move = output();
104582
105100
  /** Leave the show. */
@@ -104647,6 +105165,9 @@ class PresentationToolbarComponent {
104647
105165
  * back on the next twitch.
104648
105166
  */
104649
105167
  onDocumentMouseMove(event) {
105168
+ if (!this.popupToolbarEnabled()) {
105169
+ return;
105170
+ }
104650
105171
  const surface = this.host.nativeElement.parentElement;
104651
105172
  if (surface) {
104652
105173
  const rect = surface.getBoundingClientRect();
@@ -104748,7 +105269,7 @@ class PresentationToolbarComponent {
104748
105269
  this.openPalette.update((open) => (open === kind ? 'none' : kind));
104749
105270
  }
104750
105271
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PresentationToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
104751
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: PresentationToolbarComponent, isStandalone: true, selector: "pptx-presentation-toolbar", inputs: { currentSlideIndex: { classPropertyName: "currentSlideIndex", publicName: "currentSlideIndex", isSignal: true, isRequired: true, transformFunction: null }, totalSlides: { classPropertyName: "totalSlides", publicName: "totalSlides", isSignal: true, isRequired: true, transformFunction: null }, presentationStartTime: { classPropertyName: "presentationStartTime", publicName: "presentationStartTime", isSignal: true, isRequired: false, transformFunction: null }, presenterMode: { classPropertyName: "presenterMode", publicName: "presenterMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { move: "move", endPresentation: "endPresentation", presenterViewToggle: "presenterViewToggle" }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()", "document:mousemove": "onDocumentMouseMove($event)", "document:mousedown": "onDocumentMouseDown($event)" }, properties: { "class": "ui.wrapper", "style.opacity": "visible() ? 1 : 0", "style.pointer-events": "visible() ? \"auto\" : \"none\"" } }, ngImport: i0, template: "<!--\n\tThe 17 slots of `PRESENT_TOOLBAR_CONTROLS` (pptx-viewer-shared), in order.\n\tEach carries its shared id as `data-pptx-present-control` so a parity spec\n\tcan read the inventory off any binding without knowing its markup.\n-->\n<div\n\tdata-pptx-present-toolbar\n\trole=\"toolbar\"\n\t[attr.aria-label]=\"'pptx.toolbar.presentationToolbarAria' | translate\"\n\t[class]=\"ui.container\"\n\t(click)=\"$event.stopPropagation()\"\n>\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"previous\"\n\t\t[class]=\"ui.button\"\n\t\t[disabled]=\"atFirstSlide()\"\n\t\t[attr.title]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t(click)=\"onControlClick($event, 'previous')\"\n\t\t(touchend)=\"onControlTouch($event, 'previous')\"\n\t>\n\t\t<svg lucideChevronLeft [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<span data-pptx-present-control=\"counter\" [class]=\"ui.counter\">{{ counterLabel() }}</span>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"next\"\n\t\t[class]=\"ui.button\"\n\t\t[disabled]=\"atLastSlide()\"\n\t\t[attr.title]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t(click)=\"onControlClick($event, 'next')\"\n\t\t(touchend)=\"onControlTouch($event, 'next')\"\n\t>\n\t\t<svg lucideChevronRight [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<div data-pptx-present-control=\"divider-navigation\" [class]=\"ui.divider\"></div>\n\n\t<div\n\t\tdata-pptx-present-control=\"timer\"\n\t\t[class]=\"ui.timer\"\n\t\t[attr.title]=\"'pptx.presenter.elapsed' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.elapsed' | translate\"\n\t>\n\t\t<svg lucideTimer [class]=\"ui.timerIcon\"></svg>\n\t\t<span>{{ elapsedLabel() }}</span>\n\t</div>\n\n\t<div data-pptx-present-control=\"divider-timer\" [class]=\"ui.divider\"></div>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"laser\"\n\t\t[class]=\"ui.toggleClass(annotations.tool() === 'laser')\"\n\t\t[attr.title]=\"'pptx.presentation.laserPointer' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.laserPointer' | translate\"\n\t\t(click)=\"onControlClick($event, 'laser')\"\n\t\t(touchend)=\"onControlTouch($event, 'laser')\"\n\t>\n\t\t<svg lucideMousePointer2 [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<div [class]=\"ui.group\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"pen\"\n\t\t\t[class]=\"ui.toggleClass(annotations.tool() === 'pen')\"\n\t\t\t[attr.title]=\"'pptx.presentation.pen' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentation.pen' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'pen')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'pen')\"\n\t\t>\n\t\t\t<svg lucidePenTool [class]=\"ui.icon\"></svg>\n\t\t\t<span [class]=\"ui.swatchBar\" [style.background-color]=\"annotations.penColor()\"></span>\n\t\t</button>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"pen-color\"\n\t\t\t[class]=\"ui.caret\"\n\t\t\t[attr.title]=\"'pptx.presentationToolbar.penColor' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentationToolbar.penColor' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'pen-color')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'pen-color')\"\n\t\t>\n\t\t\t<svg lucideChevronDown [class]=\"ui.caretIcon\"></svg>\n\t\t</button>\n\t\t@if (openPalette() === 'pen') {\n\t\t\t<div [class]=\"ui.palette\">\n\t\t\t\t@for (color of ui.penColors; track color) {\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t[class]=\"ui.swatchClass(annotations.penColor() === color)\"\n\t\t\t\t\t\t[style.background-color]=\"color\"\n\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t'pptx.presentationToolbar.penColorValue' | translate: { color: color }\n\t\t\t\t\t\t\"\n\t\t\t\t\t\t(click)=\"pickColor($event, 'pen', color)\"\n\t\t\t\t\t\t(touchend)=\"pickColor($event, 'pen', color)\"\n\t\t\t\t\t></button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t</div>\n\n\t<div [class]=\"ui.group\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"highlighter\"\n\t\t\t[class]=\"ui.toggleClass(annotations.tool() === 'highlighter')\"\n\t\t\t[attr.title]=\"'pptx.presentation.highlighter' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentation.highlighter' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'highlighter')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'highlighter')\"\n\t\t>\n\t\t\t<svg lucideHighlighter [class]=\"ui.icon\"></svg>\n\t\t\t<span [class]=\"ui.swatchBar\" [style.background-color]=\"annotations.highlighterColor()\"></span>\n\t\t</button>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"highlighter-color\"\n\t\t\t[class]=\"ui.caret\"\n\t\t\t[attr.title]=\"'pptx.presentationToolbar.highlighterColor' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentationToolbar.highlighterColor' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'highlighter-color')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'highlighter-color')\"\n\t\t>\n\t\t\t<svg lucideChevronDown [class]=\"ui.caretIcon\"></svg>\n\t\t</button>\n\t\t@if (openPalette() === 'highlighter') {\n\t\t\t<div [class]=\"ui.palette\">\n\t\t\t\t@for (color of ui.highlighterColors; track color) {\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t[class]=\"ui.swatchClass(annotations.highlighterColor() === color)\"\n\t\t\t\t\t\t[style.background-color]=\"color\"\n\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t'pptx.presentationToolbar.highlighterColorValue' | translate: { color: color }\n\t\t\t\t\t\t\"\n\t\t\t\t\t\t(click)=\"pickColor($event, 'highlighter', color)\"\n\t\t\t\t\t\t(touchend)=\"pickColor($event, 'highlighter', color)\"\n\t\t\t\t\t></button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t</div>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"eraser\"\n\t\t[class]=\"ui.toggleClass(annotations.tool() === 'eraser')\"\n\t\t[attr.title]=\"'pptx.presentation.eraser' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.eraser' | translate\"\n\t\t(click)=\"onControlClick($event, 'eraser')\"\n\t\t(touchend)=\"onControlTouch($event, 'eraser')\"\n\t>\n\t\t<svg lucideEraser [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<!-- One-click blackboard: arms the black screen AND the pen together. -->\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"blackboard\"\n\t\t[class]=\"ui.toggleClass(blackboardActive())\"\n\t\t[attr.title]=\"'pptx.presentation.blackboard' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.blackboard' | translate\"\n\t\t(click)=\"onControlClick($event, 'blackboard')\"\n\t\t(touchend)=\"onControlTouch($event, 'blackboard')\"\n\t>\n\t\t<svg lucidePresentation [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"clear\"\n\t\t[class]=\"ui.clearClass(hasAnnotations())\"\n\t\t[disabled]=\"!hasAnnotations()\"\n\t\t[attr.title]=\"'pptx.presentation.clearAnnotations' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.clearAnnotations' | translate\"\n\t\t(click)=\"onControlClick($event, 'clear')\"\n\t\t(touchend)=\"onControlTouch($event, 'clear')\"\n\t>\n\t\t<svg lucideTrash2 [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<div data-pptx-present-control=\"divider-tools\" [class]=\"ui.divider\"></div>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"presenter-view\"\n\t\t[class]=\"ui.toggleClass(presenterMode())\"\n\t\t[attr.title]=\"'pptx.presenter.presenterView' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.presenterView' | translate\"\n\t\t(click)=\"onControlClick($event, 'presenter-view')\"\n\t\t(touchend)=\"onControlTouch($event, 'presenter-view')\"\n\t>\n\t\t<svg lucidePanelRight [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"end\"\n\t\t[class]=\"ui.end\"\n\t\t[attr.title]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t(click)=\"onControlClick($event, 'end')\"\n\t\t(touchend)=\"onControlTouch($event, 'end')\"\n\t>\n\t\t<svg lucideX [class]=\"ui.icon\"></svg>\n\t</button>\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: LucideChevronDown, selector: "svg[lucideChevronDown]" }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "component", type: LucideEraser, selector: "svg[lucideEraser]" }, { kind: "component", type: LucideHighlighter, selector: "svg[lucideHighlighter]" }, { kind: "component", type: LucideMousePointer2, selector: "svg[lucideMousePointer2]" }, { kind: "component", type: LucidePanelRight, selector: "svg[lucidePanelRight]" }, { kind: "component", type: LucidePenTool, selector: "svg[lucidePenTool]" }, { kind: "component", type: LucidePresentation, selector: "svg[lucidePresentation]" }, { kind: "component", type: LucideTimer, selector: "svg[lucideTimer]" }, { kind: "component", type: LucideTrash2, selector: "svg[lucideTrash2]" }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
105272
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: PresentationToolbarComponent, isStandalone: true, selector: "pptx-presentation-toolbar", inputs: { currentSlideIndex: { classPropertyName: "currentSlideIndex", publicName: "currentSlideIndex", isSignal: true, isRequired: true, transformFunction: null }, totalSlides: { classPropertyName: "totalSlides", publicName: "totalSlides", isSignal: true, isRequired: true, transformFunction: null }, presentationStartTime: { classPropertyName: "presentationStartTime", publicName: "presentationStartTime", isSignal: true, isRequired: false, transformFunction: null }, presenterMode: { classPropertyName: "presenterMode", publicName: "presenterMode", isSignal: true, isRequired: false, transformFunction: null }, popupToolbarEnabled: { classPropertyName: "popupToolbarEnabled", publicName: "popupToolbarEnabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { move: "move", endPresentation: "endPresentation", presenterViewToggle: "presenterViewToggle" }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()", "document:mousemove": "onDocumentMouseMove($event)", "document:mousedown": "onDocumentMouseDown($event)" }, properties: { "class": "ui.wrapper", "style.opacity": "visible() ? 1 : 0", "style.pointer-events": "visible() ? \"auto\" : \"none\"" } }, ngImport: i0, template: "<!--\n\tThe 17 slots of `PRESENT_TOOLBAR_CONTROLS` (pptx-viewer-shared), in order.\n\tEach carries its shared id as `data-pptx-present-control` so a parity spec\n\tcan read the inventory off any binding without knowing its markup.\n-->\n<div\n\tdata-pptx-present-toolbar\n\trole=\"toolbar\"\n\t[attr.aria-label]=\"'pptx.toolbar.presentationToolbarAria' | translate\"\n\t[class]=\"ui.container\"\n\t(click)=\"$event.stopPropagation()\"\n>\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"previous\"\n\t\t[class]=\"ui.button\"\n\t\t[disabled]=\"atFirstSlide()\"\n\t\t[attr.title]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t(click)=\"onControlClick($event, 'previous')\"\n\t\t(touchend)=\"onControlTouch($event, 'previous')\"\n\t>\n\t\t<svg lucideChevronLeft [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<span data-pptx-present-control=\"counter\" [class]=\"ui.counter\">{{ counterLabel() }}</span>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"next\"\n\t\t[class]=\"ui.button\"\n\t\t[disabled]=\"atLastSlide()\"\n\t\t[attr.title]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t(click)=\"onControlClick($event, 'next')\"\n\t\t(touchend)=\"onControlTouch($event, 'next')\"\n\t>\n\t\t<svg lucideChevronRight [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<div data-pptx-present-control=\"divider-navigation\" [class]=\"ui.divider\"></div>\n\n\t<div\n\t\tdata-pptx-present-control=\"timer\"\n\t\t[class]=\"ui.timer\"\n\t\t[attr.title]=\"'pptx.presenter.elapsed' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.elapsed' | translate\"\n\t>\n\t\t<svg lucideTimer [class]=\"ui.timerIcon\"></svg>\n\t\t<span>{{ elapsedLabel() }}</span>\n\t</div>\n\n\t<div data-pptx-present-control=\"divider-timer\" [class]=\"ui.divider\"></div>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"laser\"\n\t\t[class]=\"ui.toggleClass(annotations.tool() === 'laser')\"\n\t\t[attr.title]=\"'pptx.presentation.laserPointer' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.laserPointer' | translate\"\n\t\t(click)=\"onControlClick($event, 'laser')\"\n\t\t(touchend)=\"onControlTouch($event, 'laser')\"\n\t>\n\t\t<svg lucideMousePointer2 [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<div [class]=\"ui.group\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"pen\"\n\t\t\t[class]=\"ui.toggleClass(annotations.tool() === 'pen')\"\n\t\t\t[attr.title]=\"'pptx.presentation.pen' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentation.pen' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'pen')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'pen')\"\n\t\t>\n\t\t\t<svg lucidePenTool [class]=\"ui.icon\"></svg>\n\t\t\t<span [class]=\"ui.swatchBar\" [style.background-color]=\"annotations.penColor()\"></span>\n\t\t</button>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"pen-color\"\n\t\t\t[class]=\"ui.caret\"\n\t\t\t[attr.title]=\"'pptx.presentationToolbar.penColor' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentationToolbar.penColor' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'pen-color')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'pen-color')\"\n\t\t>\n\t\t\t<svg lucideChevronDown [class]=\"ui.caretIcon\"></svg>\n\t\t</button>\n\t\t@if (openPalette() === 'pen') {\n\t\t\t<div [class]=\"ui.palette\">\n\t\t\t\t@for (color of ui.penColors; track color) {\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t[class]=\"ui.swatchClass(annotations.penColor() === color)\"\n\t\t\t\t\t\t[style.background-color]=\"color\"\n\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t'pptx.presentationToolbar.penColorValue' | translate: { color: color }\n\t\t\t\t\t\t\"\n\t\t\t\t\t\t(click)=\"pickColor($event, 'pen', color)\"\n\t\t\t\t\t\t(touchend)=\"pickColor($event, 'pen', color)\"\n\t\t\t\t\t></button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t</div>\n\n\t<div [class]=\"ui.group\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"highlighter\"\n\t\t\t[class]=\"ui.toggleClass(annotations.tool() === 'highlighter')\"\n\t\t\t[attr.title]=\"'pptx.presentation.highlighter' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentation.highlighter' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'highlighter')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'highlighter')\"\n\t\t>\n\t\t\t<svg lucideHighlighter [class]=\"ui.icon\"></svg>\n\t\t\t<span [class]=\"ui.swatchBar\" [style.background-color]=\"annotations.highlighterColor()\"></span>\n\t\t</button>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"highlighter-color\"\n\t\t\t[class]=\"ui.caret\"\n\t\t\t[attr.title]=\"'pptx.presentationToolbar.highlighterColor' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentationToolbar.highlighterColor' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'highlighter-color')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'highlighter-color')\"\n\t\t>\n\t\t\t<svg lucideChevronDown [class]=\"ui.caretIcon\"></svg>\n\t\t</button>\n\t\t@if (openPalette() === 'highlighter') {\n\t\t\t<div [class]=\"ui.palette\">\n\t\t\t\t@for (color of ui.highlighterColors; track color) {\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t[class]=\"ui.swatchClass(annotations.highlighterColor() === color)\"\n\t\t\t\t\t\t[style.background-color]=\"color\"\n\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t'pptx.presentationToolbar.highlighterColorValue' | translate: { color: color }\n\t\t\t\t\t\t\"\n\t\t\t\t\t\t(click)=\"pickColor($event, 'highlighter', color)\"\n\t\t\t\t\t\t(touchend)=\"pickColor($event, 'highlighter', color)\"\n\t\t\t\t\t></button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t</div>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"eraser\"\n\t\t[class]=\"ui.toggleClass(annotations.tool() === 'eraser')\"\n\t\t[attr.title]=\"'pptx.presentation.eraser' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.eraser' | translate\"\n\t\t(click)=\"onControlClick($event, 'eraser')\"\n\t\t(touchend)=\"onControlTouch($event, 'eraser')\"\n\t>\n\t\t<svg lucideEraser [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<!-- One-click blackboard: arms the black screen AND the pen together. -->\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"blackboard\"\n\t\t[class]=\"ui.toggleClass(blackboardActive())\"\n\t\t[attr.title]=\"'pptx.presentation.blackboard' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.blackboard' | translate\"\n\t\t(click)=\"onControlClick($event, 'blackboard')\"\n\t\t(touchend)=\"onControlTouch($event, 'blackboard')\"\n\t>\n\t\t<svg lucidePresentation [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"clear\"\n\t\t[class]=\"ui.clearClass(hasAnnotations())\"\n\t\t[disabled]=\"!hasAnnotations()\"\n\t\t[attr.title]=\"'pptx.presentation.clearAnnotations' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.clearAnnotations' | translate\"\n\t\t(click)=\"onControlClick($event, 'clear')\"\n\t\t(touchend)=\"onControlTouch($event, 'clear')\"\n\t>\n\t\t<svg lucideTrash2 [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<div data-pptx-present-control=\"divider-tools\" [class]=\"ui.divider\"></div>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"presenter-view\"\n\t\t[class]=\"ui.toggleClass(presenterMode())\"\n\t\t[attr.title]=\"'pptx.presenter.presenterView' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.presenterView' | translate\"\n\t\t(click)=\"onControlClick($event, 'presenter-view')\"\n\t\t(touchend)=\"onControlTouch($event, 'presenter-view')\"\n\t>\n\t\t<svg lucidePanelRight [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"end\"\n\t\t[class]=\"ui.end\"\n\t\t[attr.title]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t(click)=\"onControlClick($event, 'end')\"\n\t\t(touchend)=\"onControlTouch($event, 'end')\"\n\t>\n\t\t<svg lucideX [class]=\"ui.icon\"></svg>\n\t</button>\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: LucideChevronDown, selector: "svg[lucideChevronDown]" }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "component", type: LucideEraser, selector: "svg[lucideEraser]" }, { kind: "component", type: LucideHighlighter, selector: "svg[lucideHighlighter]" }, { kind: "component", type: LucideMousePointer2, selector: "svg[lucideMousePointer2]" }, { kind: "component", type: LucidePanelRight, selector: "svg[lucidePanelRight]" }, { kind: "component", type: LucidePenTool, selector: "svg[lucidePenTool]" }, { kind: "component", type: LucidePresentation, selector: "svg[lucidePresentation]" }, { kind: "component", type: LucideTimer, selector: "svg[lucideTimer]" }, { kind: "component", type: LucideTrash2, selector: "svg[lucideTrash2]" }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
104752
105273
  }
104753
105274
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PresentationToolbarComponent, decorators: [{
104754
105275
  type: Component,
@@ -104773,7 +105294,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
104773
105294
  '(mouseenter)': 'onMouseEnter()',
104774
105295
  '(mouseleave)': 'onMouseLeave()',
104775
105296
  }, template: "<!--\n\tThe 17 slots of `PRESENT_TOOLBAR_CONTROLS` (pptx-viewer-shared), in order.\n\tEach carries its shared id as `data-pptx-present-control` so a parity spec\n\tcan read the inventory off any binding without knowing its markup.\n-->\n<div\n\tdata-pptx-present-toolbar\n\trole=\"toolbar\"\n\t[attr.aria-label]=\"'pptx.toolbar.presentationToolbarAria' | translate\"\n\t[class]=\"ui.container\"\n\t(click)=\"$event.stopPropagation()\"\n>\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"previous\"\n\t\t[class]=\"ui.button\"\n\t\t[disabled]=\"atFirstSlide()\"\n\t\t[attr.title]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t(click)=\"onControlClick($event, 'previous')\"\n\t\t(touchend)=\"onControlTouch($event, 'previous')\"\n\t>\n\t\t<svg lucideChevronLeft [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<span data-pptx-present-control=\"counter\" [class]=\"ui.counter\">{{ counterLabel() }}</span>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"next\"\n\t\t[class]=\"ui.button\"\n\t\t[disabled]=\"atLastSlide()\"\n\t\t[attr.title]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t(click)=\"onControlClick($event, 'next')\"\n\t\t(touchend)=\"onControlTouch($event, 'next')\"\n\t>\n\t\t<svg lucideChevronRight [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<div data-pptx-present-control=\"divider-navigation\" [class]=\"ui.divider\"></div>\n\n\t<div\n\t\tdata-pptx-present-control=\"timer\"\n\t\t[class]=\"ui.timer\"\n\t\t[attr.title]=\"'pptx.presenter.elapsed' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.elapsed' | translate\"\n\t>\n\t\t<svg lucideTimer [class]=\"ui.timerIcon\"></svg>\n\t\t<span>{{ elapsedLabel() }}</span>\n\t</div>\n\n\t<div data-pptx-present-control=\"divider-timer\" [class]=\"ui.divider\"></div>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"laser\"\n\t\t[class]=\"ui.toggleClass(annotations.tool() === 'laser')\"\n\t\t[attr.title]=\"'pptx.presentation.laserPointer' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.laserPointer' | translate\"\n\t\t(click)=\"onControlClick($event, 'laser')\"\n\t\t(touchend)=\"onControlTouch($event, 'laser')\"\n\t>\n\t\t<svg lucideMousePointer2 [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<div [class]=\"ui.group\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"pen\"\n\t\t\t[class]=\"ui.toggleClass(annotations.tool() === 'pen')\"\n\t\t\t[attr.title]=\"'pptx.presentation.pen' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentation.pen' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'pen')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'pen')\"\n\t\t>\n\t\t\t<svg lucidePenTool [class]=\"ui.icon\"></svg>\n\t\t\t<span [class]=\"ui.swatchBar\" [style.background-color]=\"annotations.penColor()\"></span>\n\t\t</button>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"pen-color\"\n\t\t\t[class]=\"ui.caret\"\n\t\t\t[attr.title]=\"'pptx.presentationToolbar.penColor' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentationToolbar.penColor' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'pen-color')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'pen-color')\"\n\t\t>\n\t\t\t<svg lucideChevronDown [class]=\"ui.caretIcon\"></svg>\n\t\t</button>\n\t\t@if (openPalette() === 'pen') {\n\t\t\t<div [class]=\"ui.palette\">\n\t\t\t\t@for (color of ui.penColors; track color) {\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t[class]=\"ui.swatchClass(annotations.penColor() === color)\"\n\t\t\t\t\t\t[style.background-color]=\"color\"\n\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t'pptx.presentationToolbar.penColorValue' | translate: { color: color }\n\t\t\t\t\t\t\"\n\t\t\t\t\t\t(click)=\"pickColor($event, 'pen', color)\"\n\t\t\t\t\t\t(touchend)=\"pickColor($event, 'pen', color)\"\n\t\t\t\t\t></button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t</div>\n\n\t<div [class]=\"ui.group\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"highlighter\"\n\t\t\t[class]=\"ui.toggleClass(annotations.tool() === 'highlighter')\"\n\t\t\t[attr.title]=\"'pptx.presentation.highlighter' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentation.highlighter' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'highlighter')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'highlighter')\"\n\t\t>\n\t\t\t<svg lucideHighlighter [class]=\"ui.icon\"></svg>\n\t\t\t<span [class]=\"ui.swatchBar\" [style.background-color]=\"annotations.highlighterColor()\"></span>\n\t\t</button>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-pptx-present-control=\"highlighter-color\"\n\t\t\t[class]=\"ui.caret\"\n\t\t\t[attr.title]=\"'pptx.presentationToolbar.highlighterColor' | translate\"\n\t\t\t[attr.aria-label]=\"'pptx.presentationToolbar.highlighterColor' | translate\"\n\t\t\t(click)=\"onControlClick($event, 'highlighter-color')\"\n\t\t\t(touchend)=\"onControlTouch($event, 'highlighter-color')\"\n\t\t>\n\t\t\t<svg lucideChevronDown [class]=\"ui.caretIcon\"></svg>\n\t\t</button>\n\t\t@if (openPalette() === 'highlighter') {\n\t\t\t<div [class]=\"ui.palette\">\n\t\t\t\t@for (color of ui.highlighterColors; track color) {\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t[class]=\"ui.swatchClass(annotations.highlighterColor() === color)\"\n\t\t\t\t\t\t[style.background-color]=\"color\"\n\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t'pptx.presentationToolbar.highlighterColorValue' | translate: { color: color }\n\t\t\t\t\t\t\"\n\t\t\t\t\t\t(click)=\"pickColor($event, 'highlighter', color)\"\n\t\t\t\t\t\t(touchend)=\"pickColor($event, 'highlighter', color)\"\n\t\t\t\t\t></button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t</div>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"eraser\"\n\t\t[class]=\"ui.toggleClass(annotations.tool() === 'eraser')\"\n\t\t[attr.title]=\"'pptx.presentation.eraser' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.eraser' | translate\"\n\t\t(click)=\"onControlClick($event, 'eraser')\"\n\t\t(touchend)=\"onControlTouch($event, 'eraser')\"\n\t>\n\t\t<svg lucideEraser [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<!-- One-click blackboard: arms the black screen AND the pen together. -->\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"blackboard\"\n\t\t[class]=\"ui.toggleClass(blackboardActive())\"\n\t\t[attr.title]=\"'pptx.presentation.blackboard' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.blackboard' | translate\"\n\t\t(click)=\"onControlClick($event, 'blackboard')\"\n\t\t(touchend)=\"onControlTouch($event, 'blackboard')\"\n\t>\n\t\t<svg lucidePresentation [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"clear\"\n\t\t[class]=\"ui.clearClass(hasAnnotations())\"\n\t\t[disabled]=\"!hasAnnotations()\"\n\t\t[attr.title]=\"'pptx.presentation.clearAnnotations' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presentation.clearAnnotations' | translate\"\n\t\t(click)=\"onControlClick($event, 'clear')\"\n\t\t(touchend)=\"onControlTouch($event, 'clear')\"\n\t>\n\t\t<svg lucideTrash2 [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<div data-pptx-present-control=\"divider-tools\" [class]=\"ui.divider\"></div>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"presenter-view\"\n\t\t[class]=\"ui.toggleClass(presenterMode())\"\n\t\t[attr.title]=\"'pptx.presenter.presenterView' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.presenterView' | translate\"\n\t\t(click)=\"onControlClick($event, 'presenter-view')\"\n\t\t(touchend)=\"onControlTouch($event, 'presenter-view')\"\n\t>\n\t\t<svg lucidePanelRight [class]=\"ui.icon\"></svg>\n\t</button>\n\n\t<button\n\t\ttype=\"button\"\n\t\tdata-pptx-present-control=\"end\"\n\t\t[class]=\"ui.end\"\n\t\t[attr.title]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t(click)=\"onControlClick($event, 'end')\"\n\t\t(touchend)=\"onControlTouch($event, 'end')\"\n\t>\n\t\t<svg lucideX [class]=\"ui.icon\"></svg>\n\t</button>\n</div>\n", styles: [":host{display:block}\n"] }]
104776
- }], ctorParameters: () => [], propDecorators: { currentSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentSlideIndex", required: true }] }], totalSlides: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalSlides", required: true }] }], presentationStartTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "presentationStartTime", required: false }] }], presenterMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenterMode", required: false }] }], move: [{ type: i0.Output, args: ["move"] }], endPresentation: [{ type: i0.Output, args: ["endPresentation"] }], presenterViewToggle: [{ type: i0.Output, args: ["presenterViewToggle"] }], onDocumentMouseMove: [{
105297
+ }], ctorParameters: () => [], propDecorators: { currentSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentSlideIndex", required: true }] }], totalSlides: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalSlides", required: true }] }], presentationStartTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "presentationStartTime", required: false }] }], presenterMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenterMode", required: false }] }], popupToolbarEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupToolbarEnabled", required: false }] }], move: [{ type: i0.Output, args: ["move"] }], endPresentation: [{ type: i0.Output, args: ["endPresentation"] }], presenterViewToggle: [{ type: i0.Output, args: ["presenterViewToggle"] }], onDocumentMouseMove: [{
104777
105298
  type: HostListener,
104778
105299
  args: ['document:mousemove', ['$event']]
104779
105300
  }], onDocumentMouseDown: [{
@@ -105556,6 +106077,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
105556
106077
  class PresentationOverlayComponent {
105557
106078
  constructor() {
105558
106079
  this.presenterWindow = inject(PresenterWindowService);
106080
+ /**
106081
+ * Optional so this overlay still renders in isolation (Storybook-style
106082
+ * usage, tests): outside a `PowerPointViewerComponent` host that provides
106083
+ * it, external-hyperlink clicks are simply never confirmed.
106084
+ */
106085
+ this.viewerOpts = inject(ViewerOptionsService, { optional: true });
105559
106086
  // ------------------------------------------------------------------
105560
106087
  // Inputs
105561
106088
  // ------------------------------------------------------------------
@@ -105605,6 +106132,15 @@ class PresentationOverlayComponent {
105605
106132
  /** Whether presenter view is up (tints the toolbar's presenter-view toggle). */
105606
106133
  this.presenterMode = input(false, /* @ts-ignore */
105607
106134
  ...(ngDevMode ? [{ debugName: "presenterMode" }] : /* istanbul ignore next */ []));
106135
+ /**
106136
+ * File > Options > Advanced > "Show menu on right mouse click". Off swallows
106137
+ * right-click entirely (no browser menu either), matching React/Vue.
106138
+ */
106139
+ this.showMenuOnRightClick = input(true, /* @ts-ignore */
106140
+ ...(ngDevMode ? [{ debugName: "showMenuOnRightClick" }] : /* istanbul ignore next */ []));
106141
+ /** File > Options > Advanced > "Show popup toolbar" while presenting. */
106142
+ this.showPopupToolbar = input(true, /* @ts-ignore */
106143
+ ...(ngDevMode ? [{ debugName: "showPopupToolbar" }] : /* istanbul ignore next */ []));
105608
106144
  // ------------------------------------------------------------------
105609
106145
  // Outputs
105610
106146
  // ------------------------------------------------------------------
@@ -105674,10 +106210,17 @@ class PresentationOverlayComponent {
105674
106210
  // the shortcut mean something else.
105675
106211
  showAllSlides: () => this.allSlidesOpen.set(true),
105676
106212
  requestClose: () => this.emitClosed(),
106213
+ // Trust Center > "Confirm before opening external hyperlinks" (File >
106214
+ // Options), gating a slide's on-click `a:hlinkClick` action the same way
106215
+ // it gates a text-run hyperlink.
106216
+ confirmExternalHyperlink: (href) => this.viewerOpts?.confirmExternalHyperlink(href) ?? true,
105677
106217
  });
105678
106218
  /** Whether PowerPoint's "See All Slides" navigator is up (Ctrl+S). */
105679
106219
  this.allSlidesOpen = signal(false, /* @ts-ignore */
105680
106220
  ...(ngDevMode ? [{ debugName: "allSlidesOpen" }] : /* istanbul ignore next */ []));
106221
+ /** Slide-show right-click menu position, or null when closed. */
106222
+ this.contextMenuState = signal(null, /* @ts-ignore */
106223
+ ...(ngDevMode ? [{ debugName: "contextMenuState" }] : /* istanbul ignore next */ []));
105681
106224
  /** Template aliases for the navigator's state. */
105682
106225
  this.currentIndex = this.navigator.currentIndex;
105683
106226
  this.endOfShow = this.navigator.endOfShow;
@@ -105958,6 +106501,65 @@ class PresentationOverlayComponent {
105958
106501
  onBodyClick(event) {
105959
106502
  this.input.handleBodyClick(event);
105960
106503
  }
106504
+ /**
106505
+ * Options > Advanced > "Show menu on right mouse click": right-click opens
106506
+ * a minimal Next/Previous/End Show menu (plus pointer tools, See All
106507
+ * Slides, presenter view and the black/white blank screen); off swallows
106508
+ * the click entirely, matching React/Vue.
106509
+ */
106510
+ onStageContextMenu(event) {
106511
+ event.preventDefault();
106512
+ if (!this.showMenuOnRightClick()) {
106513
+ return;
106514
+ }
106515
+ this.contextMenuState.set({ x: event.clientX, y: event.clientY });
106516
+ }
106517
+ /** Route a chosen context-menu action onto this overlay's own handlers. */
106518
+ onContextMenuAction(id) {
106519
+ switch (id) {
106520
+ case 'next':
106521
+ this.navigator.navigate('next');
106522
+ break;
106523
+ case 'previous':
106524
+ this.navigator.navigate('prev');
106525
+ break;
106526
+ case 'seeAllSlides':
106527
+ this.allSlidesOpen.set(true);
106528
+ break;
106529
+ case 'presenterView':
106530
+ this.presenterViewToggle.emit();
106531
+ break;
106532
+ case 'pointerArrow':
106533
+ this.annotations.setTool('none');
106534
+ break;
106535
+ case 'pointerPen':
106536
+ this.annotations.setTool('pen');
106537
+ break;
106538
+ case 'pointerHighlighter':
106539
+ this.annotations.setTool('highlighter');
106540
+ break;
106541
+ case 'pointerLaser':
106542
+ this.annotations.setTool('laser');
106543
+ break;
106544
+ case 'eraseInk':
106545
+ this.annotations.clearAnnotations();
106546
+ break;
106547
+ case 'blankBlack':
106548
+ this.setBlankScreen('black');
106549
+ break;
106550
+ case 'blankWhite':
106551
+ this.setBlankScreen('white');
106552
+ break;
106553
+ case 'endShow':
106554
+ this.emitClosed();
106555
+ break;
106556
+ }
106557
+ }
106558
+ /** Set (or clear) the whole-screen blank, mirroring the keyboard B/W shortcuts. */
106559
+ setBlankScreen(value) {
106560
+ const current = this.presenterWindow.snapshot().blackout;
106561
+ this.presenterWindow.updateSnapshot({ blackout: current === value ? 'none' : value });
106562
+ }
105961
106563
  /** Click on the end screen: exit the show, like PowerPoint's "click to exit". */
105962
106564
  onEndScreenClick(event) {
105963
106565
  event.stopPropagation();
@@ -106014,7 +106616,7 @@ class PresentationOverlayComponent {
106014
106616
  this.closed.emit();
106015
106617
  }
106016
106618
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PresentationOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
106017
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: PresentationOverlayComponent, isStandalone: true, selector: "pptx-presentation-overlay", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, startIndex: { classPropertyName: "startIndex", publicName: "startIndex", isSignal: true, isRequired: false, transformFunction: null }, activeCustomShow: { classPropertyName: "activeCustomShow", publicName: "activeCustomShow", isSignal: true, isRequired: false, transformFunction: null }, showWithAnimation: { classPropertyName: "showWithAnimation", publicName: "showWithAnimation", isSignal: true, isRequired: false, transformFunction: null }, useTimings: { classPropertyName: "useTimings", publicName: "useTimings", isSignal: true, isRequired: false, transformFunction: null }, subtitlesVisible: { classPropertyName: "subtitlesVisible", publicName: "subtitlesVisible", isSignal: true, isRequired: false, transformFunction: null }, sessionEnded: { classPropertyName: "sessionEnded", publicName: "sessionEnded", isSignal: true, isRequired: false, transformFunction: null }, endWithBlackSlide: { classPropertyName: "endWithBlackSlide", publicName: "endWithBlackSlide", isSignal: true, isRequired: false, transformFunction: null }, presenterMode: { classPropertyName: "presenterMode", publicName: "presenterMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { indexChange: "indexChange", closed: "closed", subtitlesChange: "subtitlesChange", presenterViewToggle: "presenterViewToggle", annotationsExit: "annotationsExit" }, host: { listeners: { "document:wheel": "onWheel($event)", "document:fullscreenchange": "onFullscreenChange()", "window:resize": "onWindowResize()", "document:keydown": "onKeyDown($event)" } }, providers: [AnimationPlaybackService, PresentationAnnotationsService, ZoomNavigationService], viewQueries: [{ propertyName: "stageRef", first: true, predicate: ["stage"], descendants: true, isSignal: true }, { propertyName: "rootRef", first: true, predicate: ["root"], descendants: true, isSignal: true }, { propertyName: "toolbarRef", first: true, predicate: PresentationToolbarComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<div #root class=\"pptx-ng-presentation-root\">\n\t<!--\n\t\tSlide counter, rendered first in DOM (before slide content) so a\n\t\tgeneric \"N / M\" text query resolves to it rather than to any slide-text\n\t\trun that happens to read like \"24 / 7\". Position is fixed, so DOM order\n\t\tdoes not affect its on-screen placement.\n\t-->\n\t<span class=\"pptx-ng-presentation-counter\" [ngStyle]=\"counterStyle\">\n\t\t{{ counterLabel() }}\n\t</span>\n\n\t<!-- Black \"End of slide show\" screen: the show has run past its last\n\t slide. It MUST be visible - while it is up the next input either\n\t goes nowhere (backward) or ends the show (forward), so a deck that\n\t kept painting the last slide looked stuck and swallowed advances. -->\n\t@if (endOfShow()) {\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-presentation-end\"\n\t\t\tdata-pptx-end-of-show\n\t\t\t(click)=\"onEndScreenClick($event)\"\n\t\t>\n\t\t\t<span>{{ 'pptx.presentation.endOfSlideShow' | translate }}</span>\n\t\t</button>\n\t}\n\n\t<div\n\t\t#stage\n\t\tclass=\"pptx-ng-presentation-stage\"\n\t\t[ngStyle]=\"stageContainerStyle()\"\n\t\t(click)=\"onBodyClick($event)\"\n\t\t(mouseover)=\"onStageHover($event)\"\n\t\t(mouseout)=\"onStageHoverEnd($event)\"\n\t\t(contextmenu)=\"$event.preventDefault()\"\n\t>\n\t\t<pptx-slide-canvas\n\t\t\t[slide]=\"currentSlide()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zoom]=\"zoom()\"\n\t\t\t[autoFit]=\"false\"\n\t\t\t[interactive]=\"false\"\n\t\t\t[presenting]=\"true\"\n\t\t/>\n\n\t\t@if (activeTransition(); as t) {\n\t\t\t<pptx-presentation-transition-overlay\n\t\t\t\t[outgoingSlide]=\"t.outgoing\"\n\t\t\t\t[incomingSlide]=\"currentSlide()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[transition]=\"t.transition\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t\t(complete)=\"activeTransition.set(null)\"\n\t\t\t/>\n\t\t}\n\n\t\t<!-- Ink annotation overlay (pen/highlighter/eraser/laser). Ctrl+M\n\t\t hides the markup without discarding the strokes. The host carries\n\t\t the shared blackboard z-index so strokes stay visible ABOVE the\n\t\t blackout sheet while the screen is blanked (the stage no longer\n\t\t creates a stacking context, see stageContainerStyle). -->\n\t\t@if (inkMarkupVisible()) {\n\t\t\t<pptx-presentation-annotation-overlay\n\t\t\t\tdata-pptx-annotation-overlay\n\t\t\t\t[style.z-index]=\"annotationOverlayZ()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t/>\n\t\t}\n\t</div>\n\t@if (presenterWindow.snapshot().blackout !== 'none') {\n\t\t<div\n\t\t\tclass=\"presenter-blank\"\n\t\t\tdata-pptx-blackout\n\t\t\t[style.background]=\"presenterWindow.snapshot().blackout\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().pointer?.tool === 'laser') {\n\t\t<div\n\t\t\tclass=\"presenter-laser\"\n\t\t\t[style.left.%]=\"(presenterWindow.snapshot().pointer?.x ?? 0.5) * 100\"\n\t\t\t[style.top.%]=\"(presenterWindow.snapshot().pointer?.y ?? 0.5) * 100\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().subtitlesVisible && presenterWindow.snapshot().caption) {\n\t\t<div class=\"presenter-caption\">{{ presenterWindow.snapshot().caption }}</div>\n\t}\n\n\t<!-- Live-caption (subtitle) bar. -->\n\t<pptx-presentation-subtitle-bar [visible]=\"subtitlesVisible()\" />\n\n\t<!--\n\t\tTouch-only chrome (close button, edge arrows, counter pill). The\n\t\tcomponent stylesheet hides all three unless the device has a coarse\n\t\tpointer, matching React's `PresentationTouchControls`: on a desktop they\n\t\tduplicate the toolbar above and put a SECOND slide counter on screen.\n\n\t\tRendered BEFORE the show toolbar, as React renders its touch controls,\n\t\tbecause both carry the same accessible names (\"Next Slide\", \"Previous\n\t\tSlide\", \"End Presentation\"). On a coarse pointer the toolbar's copies are\n\t\tstill in the DOM but inert (`pointer-events: none`), so whichever comes\n\t\tfirst is what a by-name lookup - a screen reader's, or a spec's `.first()`\n\t\t- resolves to. With the toolbar first, every such lookup landed on a\n\t\tbutton no user could press: it reported itself visible and enabled, and\n\t\tthe tap was swallowed by the overlay. Position is fixed on all of these,\n\t\tso moving them in the DOM does not move them on screen.\n\t-->\n\t<!-- Always-visible close button (top-right, safe-area aware). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-close\"\n\t\t[ngStyle]=\"closeButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'close')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'close')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t>\n\t\t<svg lucideX class=\"h-5 w-5\"></svg>\n\t</button>\n\n\t<!-- Edge navigation buttons (vertically centred, touch-friendly). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-prev\"\n\t\t[ngStyle]=\"prevButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'prev')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'prev')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t>\n\t\t<svg lucideChevronLeft class=\"h-6 w-6\"></svg>\n\t</button>\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-next\"\n\t\t[ngStyle]=\"nextButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'next')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'next')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t>\n\t\t<svg lucideChevronRight class=\"h-6 w-6\"></svg>\n\t</button>\n\n\t<!--\n\t\tThe show toolbar (bottom-centre, auto-hiding): navigation, counter,\n\t\telapsed time, annotation tools, presenter view and end-show, per\n\t\t`PRESENT_TOOLBAR_CONTROLS` in pptx-viewer-shared.\n\t-->\n\t<pptx-presentation-toolbar\n\t\t#toolbar\n\t\t[currentSlideIndex]=\"currentIndex()\"\n\t\t[totalSlides]=\"slides().length\"\n\t\t[presentationStartTime]=\"showStartedAt\"\n\t\t[presenterMode]=\"presenterMode()\"\n\t\t(move)=\"navigator.navigate($event === 1 ? 'next' : 'prev')\"\n\t\t(presenterViewToggle)=\"presenterViewToggle.emit()\"\n\t\t(endPresentation)=\"onToolbarEnd()\"\n\t/>\n\n\t<!--\n\t\tPowerPoint's \"See All Slides\" (Ctrl+S during a show). The same navigator\n\t\tthe presenter console uses, laid over the show itself: the shortcut exists\n\t\tso a presenter can reach a backup slide WITHOUT leaving the show, so it\n\t\tmust not be a door into presenter view.\n\t-->\n\t@if (allSlidesOpen()) {\n\t\t<pptx-presenter-slide-navigator\n\t\t\t[slides]=\"slides()\"\n\t\t\t[current]=\"currentIndex()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t(select)=\"onNavigatorSelect($event)\"\n\t\t\t(close)=\"allSlidesOpen.set(false)\"\n\t\t/>\n\t}\n</div>\n", styles: [":host{display:block;position:fixed;inset:0;z-index:10000;background:#000;cursor:pointer;-webkit-user-select:none;user-select:none;overflow:hidden}.pptx-ng-presentation-root{position:absolute;inset:0;touch-action:pan-y;overflow:hidden}.pptx-ng-presentation-close:hover,.pptx-ng-presentation-nav:hover{background:#000000bf}@media not all and (any-pointer:coarse){.pptx-ng-presentation-close,.pptx-ng-presentation-nav,.pptx-ng-presentation-counter{display:none!important}}.presenter-blank{position:absolute;inset:0;z-index:75;pointer-events:none}.pptx-ng-presentation-end{position:absolute;inset:0;z-index:90;display:flex;align-items:flex-start;border:0;padding:0;background:#000;text-align:left;cursor:default}.pptx-ng-presentation-end span{padding:.75rem 1rem;color:#ffffffb3;font-size:12px}.presenter-laser{position:absolute;z-index:76;width:20px;height:20px;transform:translate(-50%,-50%);border-radius:50%;background:#ef4444;box-shadow:0 0 20px 8px #ef444488;pointer-events:none}.presenter-caption{position:absolute;z-index:77;left:10%;right:10%;bottom:2rem;padding:.75rem 1.5rem;border-radius:.5rem;background:#000c;color:#fff;text-align:center;font-size:1.25rem;pointer-events:none}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationTransitionOverlayComponent, selector: "pptx-presentation-transition-overlay", inputs: ["outgoingSlide", "canvasSize", "transition", "templateElements", "mediaDataUrls", "durationMs", "zoom", "incomingSlide"], outputs: ["complete"] }, { kind: "component", type: PresentationAnnotationOverlayComponent, selector: "pptx-presentation-annotation-overlay", inputs: ["canvasSize", "zoom"] }, { kind: "component", type: PresentationSubtitleBarComponent, selector: "pptx-presentation-subtitle-bar", inputs: ["visible"] }, { kind: "component", type: PresentationToolbarComponent, selector: "pptx-presentation-toolbar", inputs: ["currentSlideIndex", "totalSlides", "presentationStartTime", "presenterMode"], outputs: ["move", "endPresentation", "presenterViewToggle"] }, { kind: "component", type: PresenterSlideNavigatorComponent, selector: "pptx-presenter-slide-navigator", inputs: ["slides", "current", "canvasSize", "mediaDataUrls", "templateElements"], outputs: ["select", "close"] }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
106619
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: PresentationOverlayComponent, isStandalone: true, selector: "pptx-presentation-overlay", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, startIndex: { classPropertyName: "startIndex", publicName: "startIndex", isSignal: true, isRequired: false, transformFunction: null }, activeCustomShow: { classPropertyName: "activeCustomShow", publicName: "activeCustomShow", isSignal: true, isRequired: false, transformFunction: null }, showWithAnimation: { classPropertyName: "showWithAnimation", publicName: "showWithAnimation", isSignal: true, isRequired: false, transformFunction: null }, useTimings: { classPropertyName: "useTimings", publicName: "useTimings", isSignal: true, isRequired: false, transformFunction: null }, subtitlesVisible: { classPropertyName: "subtitlesVisible", publicName: "subtitlesVisible", isSignal: true, isRequired: false, transformFunction: null }, sessionEnded: { classPropertyName: "sessionEnded", publicName: "sessionEnded", isSignal: true, isRequired: false, transformFunction: null }, endWithBlackSlide: { classPropertyName: "endWithBlackSlide", publicName: "endWithBlackSlide", isSignal: true, isRequired: false, transformFunction: null }, presenterMode: { classPropertyName: "presenterMode", publicName: "presenterMode", isSignal: true, isRequired: false, transformFunction: null }, showMenuOnRightClick: { classPropertyName: "showMenuOnRightClick", publicName: "showMenuOnRightClick", isSignal: true, isRequired: false, transformFunction: null }, showPopupToolbar: { classPropertyName: "showPopupToolbar", publicName: "showPopupToolbar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { indexChange: "indexChange", closed: "closed", subtitlesChange: "subtitlesChange", presenterViewToggle: "presenterViewToggle", annotationsExit: "annotationsExit" }, host: { listeners: { "document:wheel": "onWheel($event)", "document:fullscreenchange": "onFullscreenChange()", "window:resize": "onWindowResize()", "document:keydown": "onKeyDown($event)" } }, providers: [AnimationPlaybackService, PresentationAnnotationsService, ZoomNavigationService], viewQueries: [{ propertyName: "stageRef", first: true, predicate: ["stage"], descendants: true, isSignal: true }, { propertyName: "rootRef", first: true, predicate: ["root"], descendants: true, isSignal: true }, { propertyName: "toolbarRef", first: true, predicate: PresentationToolbarComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<div #root class=\"pptx-ng-presentation-root\">\n\t<!--\n\t\tSlide counter, rendered first in DOM (before slide content) so a\n\t\tgeneric \"N / M\" text query resolves to it rather than to any slide-text\n\t\trun that happens to read like \"24 / 7\". Position is fixed, so DOM order\n\t\tdoes not affect its on-screen placement.\n\t-->\n\t<span class=\"pptx-ng-presentation-counter\" [ngStyle]=\"counterStyle\">\n\t\t{{ counterLabel() }}\n\t</span>\n\n\t<!-- Black \"End of slide show\" screen: the show has run past its last\n\t slide. It MUST be visible - while it is up the next input either\n\t goes nowhere (backward) or ends the show (forward), so a deck that\n\t kept painting the last slide looked stuck and swallowed advances. -->\n\t@if (endOfShow()) {\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-presentation-end\"\n\t\t\tdata-pptx-end-of-show\n\t\t\t(click)=\"onEndScreenClick($event)\"\n\t\t>\n\t\t\t<span>{{ 'pptx.presentation.endOfSlideShow' | translate }}</span>\n\t\t</button>\n\t}\n\n\t<div\n\t\t#stage\n\t\tclass=\"pptx-ng-presentation-stage\"\n\t\t[ngStyle]=\"stageContainerStyle()\"\n\t\t(click)=\"onBodyClick($event)\"\n\t\t(mouseover)=\"onStageHover($event)\"\n\t\t(mouseout)=\"onStageHoverEnd($event)\"\n\t\t(contextmenu)=\"onStageContextMenu($event)\"\n\t>\n\t\t<pptx-slide-canvas\n\t\t\t[slide]=\"currentSlide()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zoom]=\"zoom()\"\n\t\t\t[autoFit]=\"false\"\n\t\t\t[interactive]=\"false\"\n\t\t\t[presenting]=\"true\"\n\t\t/>\n\n\t\t@if (activeTransition(); as t) {\n\t\t\t<pptx-presentation-transition-overlay\n\t\t\t\t[outgoingSlide]=\"t.outgoing\"\n\t\t\t\t[incomingSlide]=\"currentSlide()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[transition]=\"t.transition\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t\t(complete)=\"activeTransition.set(null)\"\n\t\t\t/>\n\t\t}\n\n\t\t<!-- Ink annotation overlay (pen/highlighter/eraser/laser). Ctrl+M\n\t\t hides the markup without discarding the strokes. The host carries\n\t\t the shared blackboard z-index so strokes stay visible ABOVE the\n\t\t blackout sheet while the screen is blanked (the stage no longer\n\t\t creates a stacking context, see stageContainerStyle). -->\n\t\t@if (inkMarkupVisible()) {\n\t\t\t<pptx-presentation-annotation-overlay\n\t\t\t\tdata-pptx-annotation-overlay\n\t\t\t\t[style.z-index]=\"annotationOverlayZ()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t/>\n\t\t}\n\t</div>\n\t@if (presenterWindow.snapshot().blackout !== 'none') {\n\t\t<div\n\t\t\tclass=\"presenter-blank\"\n\t\t\tdata-pptx-blackout\n\t\t\t[style.background]=\"presenterWindow.snapshot().blackout\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().pointer?.tool === 'laser') {\n\t\t<div\n\t\t\tclass=\"presenter-laser\"\n\t\t\t[style.left.%]=\"(presenterWindow.snapshot().pointer?.x ?? 0.5) * 100\"\n\t\t\t[style.top.%]=\"(presenterWindow.snapshot().pointer?.y ?? 0.5) * 100\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().subtitlesVisible && presenterWindow.snapshot().caption) {\n\t\t<div class=\"presenter-caption\">{{ presenterWindow.snapshot().caption }}</div>\n\t}\n\n\t<!-- Live-caption (subtitle) bar. -->\n\t<pptx-presentation-subtitle-bar [visible]=\"subtitlesVisible()\" />\n\n\t<!--\n\t\tTouch-only chrome (close button, edge arrows, counter pill). The\n\t\tcomponent stylesheet hides all three unless the device has a coarse\n\t\tpointer, matching React's `PresentationTouchControls`: on a desktop they\n\t\tduplicate the toolbar above and put a SECOND slide counter on screen.\n\n\t\tRendered BEFORE the show toolbar, as React renders its touch controls,\n\t\tbecause both carry the same accessible names (\"Next Slide\", \"Previous\n\t\tSlide\", \"End Presentation\"). On a coarse pointer the toolbar's copies are\n\t\tstill in the DOM but inert (`pointer-events: none`), so whichever comes\n\t\tfirst is what a by-name lookup - a screen reader's, or a spec's `.first()`\n\t\t- resolves to. With the toolbar first, every such lookup landed on a\n\t\tbutton no user could press: it reported itself visible and enabled, and\n\t\tthe tap was swallowed by the overlay. Position is fixed on all of these,\n\t\tso moving them in the DOM does not move them on screen.\n\t-->\n\t<!-- Always-visible close button (top-right, safe-area aware). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-close\"\n\t\t[ngStyle]=\"closeButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'close')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'close')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t>\n\t\t<svg lucideX class=\"h-5 w-5\"></svg>\n\t</button>\n\n\t<!-- Edge navigation buttons (vertically centred, touch-friendly). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-prev\"\n\t\t[ngStyle]=\"prevButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'prev')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'prev')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t>\n\t\t<svg lucideChevronLeft class=\"h-6 w-6\"></svg>\n\t</button>\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-next\"\n\t\t[ngStyle]=\"nextButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'next')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'next')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t>\n\t\t<svg lucideChevronRight class=\"h-6 w-6\"></svg>\n\t</button>\n\n\t<!--\n\t\tThe show toolbar (bottom-centre, auto-hiding): navigation, counter,\n\t\telapsed time, annotation tools, presenter view and end-show, per\n\t\t`PRESENT_TOOLBAR_CONTROLS` in pptx-viewer-shared.\n\t-->\n\t<pptx-presentation-toolbar\n\t\t#toolbar\n\t\t[currentSlideIndex]=\"currentIndex()\"\n\t\t[totalSlides]=\"slides().length\"\n\t\t[presentationStartTime]=\"showStartedAt\"\n\t\t[presenterMode]=\"presenterMode()\"\n\t\t[popupToolbarEnabled]=\"showPopupToolbar()\"\n\t\t(move)=\"navigator.navigate($event === 1 ? 'next' : 'prev')\"\n\t\t(presenterViewToggle)=\"presenterViewToggle.emit()\"\n\t\t(endPresentation)=\"onToolbarEnd()\"\n\t/>\n\n\t<!--\n\t\tPowerPoint's \"See All Slides\" (Ctrl+S during a show). The same navigator\n\t\tthe presenter console uses, laid over the show itself: the shortcut exists\n\t\tso a presenter can reach a backup slide WITHOUT leaving the show, so it\n\t\tmust not be a door into presenter view.\n\t-->\n\t@if (allSlidesOpen()) {\n\t\t<pptx-presenter-slide-navigator\n\t\t\t[slides]=\"slides()\"\n\t\t\t[current]=\"currentIndex()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t(select)=\"onNavigatorSelect($event)\"\n\t\t\t(close)=\"allSlidesOpen.set(false)\"\n\t\t/>\n\t}\n\n\t<!-- Slide-show right-click menu. -->\n\t@if (contextMenuState(); as pos) {\n\t\t<pptx-presentation-context-menu\n\t\t\t[x]=\"pos.x\"\n\t\t\t[y]=\"pos.y\"\n\t\t\t(action)=\"onContextMenuAction($event)\"\n\t\t\t(closed)=\"contextMenuState.set(null)\"\n\t\t/>\n\t}\n</div>\n", styles: [":host{display:block;position:fixed;inset:0;z-index:10000;background:#000;cursor:pointer;-webkit-user-select:none;user-select:none;overflow:hidden}.pptx-ng-presentation-root{position:absolute;inset:0;touch-action:pan-y;overflow:hidden}.pptx-ng-presentation-close:hover,.pptx-ng-presentation-nav:hover{background:#000000bf}@media not all and (any-pointer:coarse){.pptx-ng-presentation-close,.pptx-ng-presentation-nav,.pptx-ng-presentation-counter{display:none!important}}.presenter-blank{position:absolute;inset:0;z-index:75;pointer-events:none}.pptx-ng-presentation-end{position:absolute;inset:0;z-index:90;display:flex;align-items:flex-start;border:0;padding:0;background:#000;text-align:left;cursor:default}.pptx-ng-presentation-end span{padding:.75rem 1rem;color:#ffffffb3;font-size:12px}.presenter-laser{position:absolute;z-index:76;width:20px;height:20px;transform:translate(-50%,-50%);border-radius:50%;background:#ef4444;box-shadow:0 0 20px 8px #ef444488;pointer-events:none}.presenter-caption{position:absolute;z-index:77;left:10%;right:10%;bottom:2rem;padding:.75rem 1.5rem;border-radius:.5rem;background:#000c;color:#fff;text-align:center;font-size:1.25rem;pointer-events:none}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationTransitionOverlayComponent, selector: "pptx-presentation-transition-overlay", inputs: ["outgoingSlide", "canvasSize", "transition", "templateElements", "mediaDataUrls", "durationMs", "zoom", "incomingSlide"], outputs: ["complete"] }, { kind: "component", type: PresentationAnnotationOverlayComponent, selector: "pptx-presentation-annotation-overlay", inputs: ["canvasSize", "zoom"] }, { kind: "component", type: PresentationSubtitleBarComponent, selector: "pptx-presentation-subtitle-bar", inputs: ["visible"] }, { kind: "component", type: PresentationToolbarComponent, selector: "pptx-presentation-toolbar", inputs: ["currentSlideIndex", "totalSlides", "presentationStartTime", "presenterMode", "popupToolbarEnabled"], outputs: ["move", "endPresentation", "presenterViewToggle"] }, { kind: "component", type: PresentationContextMenuComponent, selector: "pptx-presentation-context-menu", inputs: ["x", "y"], outputs: ["closed", "action"] }, { kind: "component", type: PresenterSlideNavigatorComponent, selector: "pptx-presenter-slide-navigator", inputs: ["slides", "current", "canvasSize", "mediaDataUrls", "templateElements"], outputs: ["select", "close"] }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
106018
106620
  }
106019
106621
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PresentationOverlayComponent, decorators: [{
106020
106622
  type: Component,
@@ -106025,13 +106627,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
106025
106627
  PresentationAnnotationOverlayComponent,
106026
106628
  PresentationSubtitleBarComponent,
106027
106629
  PresentationToolbarComponent,
106630
+ PresentationContextMenuComponent,
106028
106631
  PresenterSlideNavigatorComponent,
106029
106632
  TranslatePipe,
106030
106633
  LucideX,
106031
106634
  LucideChevronLeft,
106032
106635
  LucideChevronRight,
106033
- ], providers: [AnimationPlaybackService, PresentationAnnotationsService, ZoomNavigationService], template: "<div #root class=\"pptx-ng-presentation-root\">\n\t<!--\n\t\tSlide counter, rendered first in DOM (before slide content) so a\n\t\tgeneric \"N / M\" text query resolves to it rather than to any slide-text\n\t\trun that happens to read like \"24 / 7\". Position is fixed, so DOM order\n\t\tdoes not affect its on-screen placement.\n\t-->\n\t<span class=\"pptx-ng-presentation-counter\" [ngStyle]=\"counterStyle\">\n\t\t{{ counterLabel() }}\n\t</span>\n\n\t<!-- Black \"End of slide show\" screen: the show has run past its last\n\t slide. It MUST be visible - while it is up the next input either\n\t goes nowhere (backward) or ends the show (forward), so a deck that\n\t kept painting the last slide looked stuck and swallowed advances. -->\n\t@if (endOfShow()) {\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-presentation-end\"\n\t\t\tdata-pptx-end-of-show\n\t\t\t(click)=\"onEndScreenClick($event)\"\n\t\t>\n\t\t\t<span>{{ 'pptx.presentation.endOfSlideShow' | translate }}</span>\n\t\t</button>\n\t}\n\n\t<div\n\t\t#stage\n\t\tclass=\"pptx-ng-presentation-stage\"\n\t\t[ngStyle]=\"stageContainerStyle()\"\n\t\t(click)=\"onBodyClick($event)\"\n\t\t(mouseover)=\"onStageHover($event)\"\n\t\t(mouseout)=\"onStageHoverEnd($event)\"\n\t\t(contextmenu)=\"$event.preventDefault()\"\n\t>\n\t\t<pptx-slide-canvas\n\t\t\t[slide]=\"currentSlide()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zoom]=\"zoom()\"\n\t\t\t[autoFit]=\"false\"\n\t\t\t[interactive]=\"false\"\n\t\t\t[presenting]=\"true\"\n\t\t/>\n\n\t\t@if (activeTransition(); as t) {\n\t\t\t<pptx-presentation-transition-overlay\n\t\t\t\t[outgoingSlide]=\"t.outgoing\"\n\t\t\t\t[incomingSlide]=\"currentSlide()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[transition]=\"t.transition\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t\t(complete)=\"activeTransition.set(null)\"\n\t\t\t/>\n\t\t}\n\n\t\t<!-- Ink annotation overlay (pen/highlighter/eraser/laser). Ctrl+M\n\t\t hides the markup without discarding the strokes. The host carries\n\t\t the shared blackboard z-index so strokes stay visible ABOVE the\n\t\t blackout sheet while the screen is blanked (the stage no longer\n\t\t creates a stacking context, see stageContainerStyle). -->\n\t\t@if (inkMarkupVisible()) {\n\t\t\t<pptx-presentation-annotation-overlay\n\t\t\t\tdata-pptx-annotation-overlay\n\t\t\t\t[style.z-index]=\"annotationOverlayZ()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t/>\n\t\t}\n\t</div>\n\t@if (presenterWindow.snapshot().blackout !== 'none') {\n\t\t<div\n\t\t\tclass=\"presenter-blank\"\n\t\t\tdata-pptx-blackout\n\t\t\t[style.background]=\"presenterWindow.snapshot().blackout\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().pointer?.tool === 'laser') {\n\t\t<div\n\t\t\tclass=\"presenter-laser\"\n\t\t\t[style.left.%]=\"(presenterWindow.snapshot().pointer?.x ?? 0.5) * 100\"\n\t\t\t[style.top.%]=\"(presenterWindow.snapshot().pointer?.y ?? 0.5) * 100\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().subtitlesVisible && presenterWindow.snapshot().caption) {\n\t\t<div class=\"presenter-caption\">{{ presenterWindow.snapshot().caption }}</div>\n\t}\n\n\t<!-- Live-caption (subtitle) bar. -->\n\t<pptx-presentation-subtitle-bar [visible]=\"subtitlesVisible()\" />\n\n\t<!--\n\t\tTouch-only chrome (close button, edge arrows, counter pill). The\n\t\tcomponent stylesheet hides all three unless the device has a coarse\n\t\tpointer, matching React's `PresentationTouchControls`: on a desktop they\n\t\tduplicate the toolbar above and put a SECOND slide counter on screen.\n\n\t\tRendered BEFORE the show toolbar, as React renders its touch controls,\n\t\tbecause both carry the same accessible names (\"Next Slide\", \"Previous\n\t\tSlide\", \"End Presentation\"). On a coarse pointer the toolbar's copies are\n\t\tstill in the DOM but inert (`pointer-events: none`), so whichever comes\n\t\tfirst is what a by-name lookup - a screen reader's, or a spec's `.first()`\n\t\t- resolves to. With the toolbar first, every such lookup landed on a\n\t\tbutton no user could press: it reported itself visible and enabled, and\n\t\tthe tap was swallowed by the overlay. Position is fixed on all of these,\n\t\tso moving them in the DOM does not move them on screen.\n\t-->\n\t<!-- Always-visible close button (top-right, safe-area aware). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-close\"\n\t\t[ngStyle]=\"closeButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'close')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'close')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t>\n\t\t<svg lucideX class=\"h-5 w-5\"></svg>\n\t</button>\n\n\t<!-- Edge navigation buttons (vertically centred, touch-friendly). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-prev\"\n\t\t[ngStyle]=\"prevButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'prev')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'prev')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t>\n\t\t<svg lucideChevronLeft class=\"h-6 w-6\"></svg>\n\t</button>\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-next\"\n\t\t[ngStyle]=\"nextButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'next')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'next')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t>\n\t\t<svg lucideChevronRight class=\"h-6 w-6\"></svg>\n\t</button>\n\n\t<!--\n\t\tThe show toolbar (bottom-centre, auto-hiding): navigation, counter,\n\t\telapsed time, annotation tools, presenter view and end-show, per\n\t\t`PRESENT_TOOLBAR_CONTROLS` in pptx-viewer-shared.\n\t-->\n\t<pptx-presentation-toolbar\n\t\t#toolbar\n\t\t[currentSlideIndex]=\"currentIndex()\"\n\t\t[totalSlides]=\"slides().length\"\n\t\t[presentationStartTime]=\"showStartedAt\"\n\t\t[presenterMode]=\"presenterMode()\"\n\t\t(move)=\"navigator.navigate($event === 1 ? 'next' : 'prev')\"\n\t\t(presenterViewToggle)=\"presenterViewToggle.emit()\"\n\t\t(endPresentation)=\"onToolbarEnd()\"\n\t/>\n\n\t<!--\n\t\tPowerPoint's \"See All Slides\" (Ctrl+S during a show). The same navigator\n\t\tthe presenter console uses, laid over the show itself: the shortcut exists\n\t\tso a presenter can reach a backup slide WITHOUT leaving the show, so it\n\t\tmust not be a door into presenter view.\n\t-->\n\t@if (allSlidesOpen()) {\n\t\t<pptx-presenter-slide-navigator\n\t\t\t[slides]=\"slides()\"\n\t\t\t[current]=\"currentIndex()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t(select)=\"onNavigatorSelect($event)\"\n\t\t\t(close)=\"allSlidesOpen.set(false)\"\n\t\t/>\n\t}\n</div>\n", styles: [":host{display:block;position:fixed;inset:0;z-index:10000;background:#000;cursor:pointer;-webkit-user-select:none;user-select:none;overflow:hidden}.pptx-ng-presentation-root{position:absolute;inset:0;touch-action:pan-y;overflow:hidden}.pptx-ng-presentation-close:hover,.pptx-ng-presentation-nav:hover{background:#000000bf}@media not all and (any-pointer:coarse){.pptx-ng-presentation-close,.pptx-ng-presentation-nav,.pptx-ng-presentation-counter{display:none!important}}.presenter-blank{position:absolute;inset:0;z-index:75;pointer-events:none}.pptx-ng-presentation-end{position:absolute;inset:0;z-index:90;display:flex;align-items:flex-start;border:0;padding:0;background:#000;text-align:left;cursor:default}.pptx-ng-presentation-end span{padding:.75rem 1rem;color:#ffffffb3;font-size:12px}.presenter-laser{position:absolute;z-index:76;width:20px;height:20px;transform:translate(-50%,-50%);border-radius:50%;background:#ef4444;box-shadow:0 0 20px 8px #ef444488;pointer-events:none}.presenter-caption{position:absolute;z-index:77;left:10%;right:10%;bottom:2rem;padding:.75rem 1.5rem;border-radius:.5rem;background:#000c;color:#fff;text-align:center;font-size:1.25rem;pointer-events:none}\n"] }]
106034
- }], ctorParameters: () => [], propDecorators: { slides: [{ type: i0.Input, args: [{ isSignal: true, alias: "slides", required: true }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], startIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "startIndex", required: false }] }], activeCustomShow: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeCustomShow", required: false }] }], showWithAnimation: [{ type: i0.Input, args: [{ isSignal: true, alias: "showWithAnimation", required: false }] }], useTimings: [{ type: i0.Input, args: [{ isSignal: true, alias: "useTimings", required: false }] }], subtitlesVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitlesVisible", required: false }] }], sessionEnded: [{ type: i0.Input, args: [{ isSignal: true, alias: "sessionEnded", required: false }] }], endWithBlackSlide: [{ type: i0.Input, args: [{ isSignal: true, alias: "endWithBlackSlide", required: false }] }], presenterMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenterMode", required: false }] }], indexChange: [{ type: i0.Output, args: ["indexChange"] }], closed: [{ type: i0.Output, args: ["closed"] }], subtitlesChange: [{ type: i0.Output, args: ["subtitlesChange"] }], presenterViewToggle: [{ type: i0.Output, args: ["presenterViewToggle"] }], annotationsExit: [{ type: i0.Output, args: ["annotationsExit"] }], stageRef: [{ type: i0.ViewChild, args: ['stage', { isSignal: true }] }], rootRef: [{ type: i0.ViewChild, args: ['root', { isSignal: true }] }], toolbarRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => PresentationToolbarComponent), { isSignal: true }] }], onWheel: [{
106636
+ ], providers: [AnimationPlaybackService, PresentationAnnotationsService, ZoomNavigationService], template: "<div #root class=\"pptx-ng-presentation-root\">\n\t<!--\n\t\tSlide counter, rendered first in DOM (before slide content) so a\n\t\tgeneric \"N / M\" text query resolves to it rather than to any slide-text\n\t\trun that happens to read like \"24 / 7\". Position is fixed, so DOM order\n\t\tdoes not affect its on-screen placement.\n\t-->\n\t<span class=\"pptx-ng-presentation-counter\" [ngStyle]=\"counterStyle\">\n\t\t{{ counterLabel() }}\n\t</span>\n\n\t<!-- Black \"End of slide show\" screen: the show has run past its last\n\t slide. It MUST be visible - while it is up the next input either\n\t goes nowhere (backward) or ends the show (forward), so a deck that\n\t kept painting the last slide looked stuck and swallowed advances. -->\n\t@if (endOfShow()) {\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-presentation-end\"\n\t\t\tdata-pptx-end-of-show\n\t\t\t(click)=\"onEndScreenClick($event)\"\n\t\t>\n\t\t\t<span>{{ 'pptx.presentation.endOfSlideShow' | translate }}</span>\n\t\t</button>\n\t}\n\n\t<div\n\t\t#stage\n\t\tclass=\"pptx-ng-presentation-stage\"\n\t\t[ngStyle]=\"stageContainerStyle()\"\n\t\t(click)=\"onBodyClick($event)\"\n\t\t(mouseover)=\"onStageHover($event)\"\n\t\t(mouseout)=\"onStageHoverEnd($event)\"\n\t\t(contextmenu)=\"onStageContextMenu($event)\"\n\t>\n\t\t<pptx-slide-canvas\n\t\t\t[slide]=\"currentSlide()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zoom]=\"zoom()\"\n\t\t\t[autoFit]=\"false\"\n\t\t\t[interactive]=\"false\"\n\t\t\t[presenting]=\"true\"\n\t\t/>\n\n\t\t@if (activeTransition(); as t) {\n\t\t\t<pptx-presentation-transition-overlay\n\t\t\t\t[outgoingSlide]=\"t.outgoing\"\n\t\t\t\t[incomingSlide]=\"currentSlide()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[transition]=\"t.transition\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t\t(complete)=\"activeTransition.set(null)\"\n\t\t\t/>\n\t\t}\n\n\t\t<!-- Ink annotation overlay (pen/highlighter/eraser/laser). Ctrl+M\n\t\t hides the markup without discarding the strokes. The host carries\n\t\t the shared blackboard z-index so strokes stay visible ABOVE the\n\t\t blackout sheet while the screen is blanked (the stage no longer\n\t\t creates a stacking context, see stageContainerStyle). -->\n\t\t@if (inkMarkupVisible()) {\n\t\t\t<pptx-presentation-annotation-overlay\n\t\t\t\tdata-pptx-annotation-overlay\n\t\t\t\t[style.z-index]=\"annotationOverlayZ()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t/>\n\t\t}\n\t</div>\n\t@if (presenterWindow.snapshot().blackout !== 'none') {\n\t\t<div\n\t\t\tclass=\"presenter-blank\"\n\t\t\tdata-pptx-blackout\n\t\t\t[style.background]=\"presenterWindow.snapshot().blackout\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().pointer?.tool === 'laser') {\n\t\t<div\n\t\t\tclass=\"presenter-laser\"\n\t\t\t[style.left.%]=\"(presenterWindow.snapshot().pointer?.x ?? 0.5) * 100\"\n\t\t\t[style.top.%]=\"(presenterWindow.snapshot().pointer?.y ?? 0.5) * 100\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().subtitlesVisible && presenterWindow.snapshot().caption) {\n\t\t<div class=\"presenter-caption\">{{ presenterWindow.snapshot().caption }}</div>\n\t}\n\n\t<!-- Live-caption (subtitle) bar. -->\n\t<pptx-presentation-subtitle-bar [visible]=\"subtitlesVisible()\" />\n\n\t<!--\n\t\tTouch-only chrome (close button, edge arrows, counter pill). The\n\t\tcomponent stylesheet hides all three unless the device has a coarse\n\t\tpointer, matching React's `PresentationTouchControls`: on a desktop they\n\t\tduplicate the toolbar above and put a SECOND slide counter on screen.\n\n\t\tRendered BEFORE the show toolbar, as React renders its touch controls,\n\t\tbecause both carry the same accessible names (\"Next Slide\", \"Previous\n\t\tSlide\", \"End Presentation\"). On a coarse pointer the toolbar's copies are\n\t\tstill in the DOM but inert (`pointer-events: none`), so whichever comes\n\t\tfirst is what a by-name lookup - a screen reader's, or a spec's `.first()`\n\t\t- resolves to. With the toolbar first, every such lookup landed on a\n\t\tbutton no user could press: it reported itself visible and enabled, and\n\t\tthe tap was swallowed by the overlay. Position is fixed on all of these,\n\t\tso moving them in the DOM does not move them on screen.\n\t-->\n\t<!-- Always-visible close button (top-right, safe-area aware). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-close\"\n\t\t[ngStyle]=\"closeButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'close')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'close')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t>\n\t\t<svg lucideX class=\"h-5 w-5\"></svg>\n\t</button>\n\n\t<!-- Edge navigation buttons (vertically centred, touch-friendly). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-prev\"\n\t\t[ngStyle]=\"prevButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'prev')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'prev')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t>\n\t\t<svg lucideChevronLeft class=\"h-6 w-6\"></svg>\n\t</button>\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-next\"\n\t\t[ngStyle]=\"nextButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'next')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'next')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t>\n\t\t<svg lucideChevronRight class=\"h-6 w-6\"></svg>\n\t</button>\n\n\t<!--\n\t\tThe show toolbar (bottom-centre, auto-hiding): navigation, counter,\n\t\telapsed time, annotation tools, presenter view and end-show, per\n\t\t`PRESENT_TOOLBAR_CONTROLS` in pptx-viewer-shared.\n\t-->\n\t<pptx-presentation-toolbar\n\t\t#toolbar\n\t\t[currentSlideIndex]=\"currentIndex()\"\n\t\t[totalSlides]=\"slides().length\"\n\t\t[presentationStartTime]=\"showStartedAt\"\n\t\t[presenterMode]=\"presenterMode()\"\n\t\t[popupToolbarEnabled]=\"showPopupToolbar()\"\n\t\t(move)=\"navigator.navigate($event === 1 ? 'next' : 'prev')\"\n\t\t(presenterViewToggle)=\"presenterViewToggle.emit()\"\n\t\t(endPresentation)=\"onToolbarEnd()\"\n\t/>\n\n\t<!--\n\t\tPowerPoint's \"See All Slides\" (Ctrl+S during a show). The same navigator\n\t\tthe presenter console uses, laid over the show itself: the shortcut exists\n\t\tso a presenter can reach a backup slide WITHOUT leaving the show, so it\n\t\tmust not be a door into presenter view.\n\t-->\n\t@if (allSlidesOpen()) {\n\t\t<pptx-presenter-slide-navigator\n\t\t\t[slides]=\"slides()\"\n\t\t\t[current]=\"currentIndex()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t(select)=\"onNavigatorSelect($event)\"\n\t\t\t(close)=\"allSlidesOpen.set(false)\"\n\t\t/>\n\t}\n\n\t<!-- Slide-show right-click menu. -->\n\t@if (contextMenuState(); as pos) {\n\t\t<pptx-presentation-context-menu\n\t\t\t[x]=\"pos.x\"\n\t\t\t[y]=\"pos.y\"\n\t\t\t(action)=\"onContextMenuAction($event)\"\n\t\t\t(closed)=\"contextMenuState.set(null)\"\n\t\t/>\n\t}\n</div>\n", styles: [":host{display:block;position:fixed;inset:0;z-index:10000;background:#000;cursor:pointer;-webkit-user-select:none;user-select:none;overflow:hidden}.pptx-ng-presentation-root{position:absolute;inset:0;touch-action:pan-y;overflow:hidden}.pptx-ng-presentation-close:hover,.pptx-ng-presentation-nav:hover{background:#000000bf}@media not all and (any-pointer:coarse){.pptx-ng-presentation-close,.pptx-ng-presentation-nav,.pptx-ng-presentation-counter{display:none!important}}.presenter-blank{position:absolute;inset:0;z-index:75;pointer-events:none}.pptx-ng-presentation-end{position:absolute;inset:0;z-index:90;display:flex;align-items:flex-start;border:0;padding:0;background:#000;text-align:left;cursor:default}.pptx-ng-presentation-end span{padding:.75rem 1rem;color:#ffffffb3;font-size:12px}.presenter-laser{position:absolute;z-index:76;width:20px;height:20px;transform:translate(-50%,-50%);border-radius:50%;background:#ef4444;box-shadow:0 0 20px 8px #ef444488;pointer-events:none}.presenter-caption{position:absolute;z-index:77;left:10%;right:10%;bottom:2rem;padding:.75rem 1.5rem;border-radius:.5rem;background:#000c;color:#fff;text-align:center;font-size:1.25rem;pointer-events:none}\n"] }]
106637
+ }], ctorParameters: () => [], propDecorators: { slides: [{ type: i0.Input, args: [{ isSignal: true, alias: "slides", required: true }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], startIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "startIndex", required: false }] }], activeCustomShow: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeCustomShow", required: false }] }], showWithAnimation: [{ type: i0.Input, args: [{ isSignal: true, alias: "showWithAnimation", required: false }] }], useTimings: [{ type: i0.Input, args: [{ isSignal: true, alias: "useTimings", required: false }] }], subtitlesVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitlesVisible", required: false }] }], sessionEnded: [{ type: i0.Input, args: [{ isSignal: true, alias: "sessionEnded", required: false }] }], endWithBlackSlide: [{ type: i0.Input, args: [{ isSignal: true, alias: "endWithBlackSlide", required: false }] }], presenterMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenterMode", required: false }] }], showMenuOnRightClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "showMenuOnRightClick", required: false }] }], showPopupToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPopupToolbar", required: false }] }], indexChange: [{ type: i0.Output, args: ["indexChange"] }], closed: [{ type: i0.Output, args: ["closed"] }], subtitlesChange: [{ type: i0.Output, args: ["subtitlesChange"] }], presenterViewToggle: [{ type: i0.Output, args: ["presenterViewToggle"] }], annotationsExit: [{ type: i0.Output, args: ["annotationsExit"] }], stageRef: [{ type: i0.ViewChild, args: ['stage', { isSignal: true }] }], rootRef: [{ type: i0.ViewChild, args: ['root', { isSignal: true }] }], toolbarRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => PresentationToolbarComponent), { isSignal: true }] }], onWheel: [{
106035
106638
  type: HostListener,
106036
106639
  args: ['document:wheel', ['$event']]
106037
106640
  }], onFullscreenChange: [{
@@ -107139,6 +107742,13 @@ class PrintDialogComponent {
107139
107742
  /** Default frame-slides from presentation properties. */
107140
107743
  this.defaultFrameSlides = input(undefined, /* @ts-ignore */
107141
107744
  ...(ngDevMode ? [{ debugName: "defaultFrameSlides" }] : /* istanbul ignore next */ []));
107745
+ /**
107746
+ * File > Options > Advanced > Print seed (`ViewerOptionsService.printDefaults`).
107747
+ * `undefined` (Options > "Use the most recently used print settings") leaves
107748
+ * `printWhat`/`colorMode`/`frameSlides` at their hardcoded defaults below.
107749
+ */
107750
+ this.defaultSettings = input(undefined, /* @ts-ignore */
107751
+ ...(ngDevMode ? [{ debugName: "defaultSettings" }] : /* istanbul ignore next */ []));
107142
107752
  /** Emits the resolved, validated settings when the user clicks Print. */
107143
107753
  this.print = output();
107144
107754
  /** Emits when the dialog is dismissed (Cancel / Escape / backdrop). */
@@ -107181,10 +107791,14 @@ class PrintDialogComponent {
107181
107791
  }
107182
107792
  this._seeded = true;
107183
107793
  const total = this.slides().length;
107794
+ const optionDefaults = this.defaultSettings();
107184
107795
  this.settings.set({
107185
107796
  ...DEFAULT_PRINT_SETTINGS,
107797
+ printWhat: optionDefaults?.printWhat ?? DEFAULT_PRINT_SETTINGS.printWhat,
107798
+ colorMode: optionDefaults?.colorMode ?? DEFAULT_PRINT_SETTINGS.colorMode,
107186
107799
  slidesPerPage: normalizeSlidesPerPage(this.defaultSlidesPerPage()),
107187
- frameSlides: this.defaultFrameSlides() ?? false,
107800
+ frameSlides: optionDefaults?.frameSlides ?? this.defaultFrameSlides() ?? false,
107801
+ scaleToFit: optionDefaults?.scaleToFit ?? DEFAULT_PRINT_SETTINGS.scaleToFit,
107188
107802
  customRangeFrom: 1,
107189
107803
  customRangeTo: Math.max(1, total),
107190
107804
  });
@@ -107217,7 +107831,7 @@ class PrintDialogComponent {
107217
107831
  }
107218
107832
  }
107219
107833
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PrintDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
107220
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.3", type: PrintDialogComponent, isStandalone: true, selector: "pptx-print-dialog", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, activeSlideIndex: { classPropertyName: "activeSlideIndex", publicName: "activeSlideIndex", isSignal: true, isRequired: true, transformFunction: null }, defaultSlidesPerPage: { classPropertyName: "defaultSlidesPerPage", publicName: "defaultSlidesPerPage", isSignal: true, isRequired: false, transformFunction: null }, defaultFrameSlides: { classPropertyName: "defaultFrameSlides", publicName: "defaultFrameSlides", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { print: "print", cancel: "cancel" }, host: { listeners: { "document:keydown": "onKeydown($event)" } }, providers: [IsMobileService], ngImport: i0, template: `
107834
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.3", type: PrintDialogComponent, isStandalone: true, selector: "pptx-print-dialog", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, activeSlideIndex: { classPropertyName: "activeSlideIndex", publicName: "activeSlideIndex", isSignal: true, isRequired: true, transformFunction: null }, defaultSlidesPerPage: { classPropertyName: "defaultSlidesPerPage", publicName: "defaultSlidesPerPage", isSignal: true, isRequired: false, transformFunction: null }, defaultFrameSlides: { classPropertyName: "defaultFrameSlides", publicName: "defaultFrameSlides", isSignal: true, isRequired: false, transformFunction: null }, defaultSettings: { classPropertyName: "defaultSettings", publicName: "defaultSettings", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { print: "print", cancel: "cancel" }, host: { listeners: { "document:keydown": "onKeydown($event)" } }, providers: [IsMobileService], ngImport: i0, template: `
107221
107835
  <div
107222
107836
  class="pptx-ng-print-dialog__backdrop"
107223
107837
  [class.is-mobile]="mobile.isMobile()"
@@ -107332,7 +107946,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
107332
107946
  </div>
107333
107947
  </div>
107334
107948
  `, styles: [".pptx-ng-print-dialog__backdrop{position:fixed;inset:0;z-index:1200;display:flex;align-items:center;justify-content:center;background:#0009;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.pptx-ng-print-dialog{display:flex;flex-direction:column;width:780px;max-width:calc(100vw - 2rem);max-height:90vh;border:1px solid rgba(255,255,255,.12);border-radius:.75rem;background:#1e1e1e;color:#e5e5e5;box-shadow:0 20px 60px #0009}.pptx-ng-print-dialog__header{display:flex;align-items:center;justify-content:space-between;padding:1rem 1.25rem;border-bottom:1px solid rgba(255,255,255,.1)}.pptx-ng-print-dialog__title{margin:0;font-size:.875rem;font-weight:600;color:#fff}.pptx-ng-print-dialog__icon-btn{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;padding:0;border:0;border-radius:.25rem;background:transparent;color:#fff9;font-size:.75rem;cursor:pointer;transition:background .12s,color .12s}.pptx-ng-print-dialog__icon-btn:hover{background:#ffffff1a;color:#fff}.pptx-ng-print-dialog__body{flex:1;overflow-y:auto;padding:1rem 1.25rem}.pptx-ng-print-dialog__footer{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1.25rem;border-top:1px solid rgba(255,255,255,.1)}.pptx-ng-print-dialog__estimate{font-size:.75rem;color:#ffffff80}.pptx-ng-print-dialog__actions{display:flex;gap:.5rem}.pptx-ng-print-dialog__btn{padding:.5rem 1rem;border:1px solid rgba(255,255,255,.15);border-radius:.5rem;background:#ffffff0a;color:#ffffffb3;font-size:.8125rem;cursor:pointer;transition:background .12s,color .12s,border-color .12s}.pptx-ng-print-dialog__btn:hover{background:#ffffff1a;color:#fff}.pptx-ng-print-dialog__btn--primary{border-color:#3b82f6;background:#3b82f6;color:#fff}.pptx-ng-print-dialog__btn--primary:hover{background:#2f6fd6}.pptx-ng-print-dialog__backdrop.is-mobile{align-items:flex-end}.pptx-ng-print-dialog.is-mobile{width:100%;max-width:none;max-height:88dvh;border-left:none;border-right:none;border-bottom:none;border-top-left-radius:1rem;border-top-right-radius:1rem;border-bottom-left-radius:0;border-bottom-right-radius:0;padding-bottom:max(env(safe-area-inset-bottom),0px)}@media(max-width:767px),(pointer:coarse){.pptx-ng-print-dialog__backdrop{align-items:flex-end}.pptx-ng-print-dialog{width:100%;max-width:none;max-height:88dvh;border-left:none;border-right:none;border-bottom:none;border-top-left-radius:1rem;border-top-right-radius:1rem;border-bottom-left-radius:0;border-bottom-right-radius:0;padding-bottom:max(env(safe-area-inset-bottom),0px)}}\n"] }]
107335
- }], ctorParameters: () => [], propDecorators: { slides: [{ type: i0.Input, args: [{ isSignal: true, alias: "slides", required: true }] }], activeSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeSlideIndex", required: true }] }], defaultSlidesPerPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultSlidesPerPage", required: false }] }], defaultFrameSlides: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultFrameSlides", required: false }] }], print: [{ type: i0.Output, args: ["print"] }], cancel: [{ type: i0.Output, args: ["cancel"] }], onKeydown: [{
107949
+ }], ctorParameters: () => [], propDecorators: { slides: [{ type: i0.Input, args: [{ isSignal: true, alias: "slides", required: true }] }], activeSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeSlideIndex", required: true }] }], defaultSlidesPerPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultSlidesPerPage", required: false }] }], defaultFrameSlides: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultFrameSlides", required: false }] }], defaultSettings: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultSettings", required: false }] }], print: [{ type: i0.Output, args: ["print"] }], cancel: [{ type: i0.Output, args: ["cancel"] }], onKeydown: [{
107336
107950
  type: HostListener,
107337
107951
  args: ['document:keydown', ['$event']]
107338
107952
  }] } });
@@ -107638,6 +108252,176 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
107638
108252
  `, styles: [".pptx-ng-props-form{display:flex;flex-direction:column;gap:.75rem}.pptx-ng-props-field{display:flex;flex-direction:column;gap:.375rem}.pptx-ng-props-label{font-size:.75rem;font-weight:500;color:var(--pptx-foreground, #e5e5e5)}.pptx-ng-props-input{width:100%;padding:.375rem .75rem;border-radius:.375rem;border:1px solid var(--pptx-border, #2a2a2a);background:var(--pptx-background, #111);color:var(--pptx-foreground, #e5e5e5);font-size:.8125rem}.pptx-ng-props-input:focus{outline:none;border-color:var(--pptx-primary, #6366f1);box-shadow:0 0 0 1px var(--pptx-primary, #6366f1)}.pptx-ng-props-meta{display:flex;flex-direction:column;gap:.375rem;padding-top:.5rem;border-top:1px solid var(--pptx-border, #2a2a2a)}.pptx-ng-props-meta-row{display:flex;justify-content:space-between;font-size:.75rem}.pptx-ng-props-meta-label{color:var(--pptx-muted-foreground, #9a9a9a)}.pptx-ng-props-meta-value{color:var(--pptx-foreground, #e5e5e5)}.pptx-ng-props-btn{padding:.375rem .75rem;border:none;border-radius:.375rem;background:var(--pptx-muted, #2a2a2a);color:var(--pptx-foreground, #e5e5e5);font-size:.75rem;cursor:pointer}.pptx-ng-props-btn-primary{background:var(--pptx-primary, #6366f1);color:var(--pptx-primary-foreground, #fff)}\n"] }]
107639
108253
  }], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], properties: [{ type: i0.Input, args: [{ isSignal: true, alias: "properties", required: true }] }], save: [{ type: i0.Output, args: ["save"] }], close: [{ type: i0.Output, args: ["close"] }] } });
107640
108254
 
108255
+ /**
108256
+ * quick-access-strip.component.ts: the Quick Access Toolbar strip driven by
108257
+ * File > Options > Quick Access Toolbar.
108258
+ *
108259
+ * Renders the ordered {@link QUICK_ACCESS_COMMAND_CATALOG} commands from
108260
+ * `options.quickAccess.commandIds` as icon buttons (optionally with labels),
108261
+ * emitting the pressed command id; the host maps ids onto its existing
108262
+ * handlers. Replaces the title bar's previously hardcoded Save/Undo/Redo
108263
+ * trio, and is also rendered below the ribbon when the position option is
108264
+ * `below`. Tooltips honour the ScreenTip style via {@link ViewerOptionsService}.
108265
+ */
108266
+ /** Resolve the configured command ids to renderable strip entries. */
108267
+ function resolveQuickAccessItems(commandIds) {
108268
+ const items = [];
108269
+ for (const id of commandIds) {
108270
+ const command = getQuickAccessCommand(id);
108271
+ if (command) {
108272
+ items.push({ id, icon: command.icon, labelKey: command.labelKey });
108273
+ }
108274
+ }
108275
+ return items;
108276
+ }
108277
+ class QuickAccessStripComponent {
108278
+ constructor() {
108279
+ /** The live Quick Access options group (visibility is gated by the host). */
108280
+ this.quickAccess = input.required(/* @ts-ignore */
108281
+ ...(ngDevMode ? [{ debugName: "quickAccess" }] : /* istanbul ignore next */ []));
108282
+ this.canUndo = input(false, /* @ts-ignore */
108283
+ ...(ngDevMode ? [{ debugName: "canUndo" }] : /* istanbul ignore next */ []));
108284
+ this.canRedo = input(false, /* @ts-ignore */
108285
+ ...(ngDevMode ? [{ debugName: "canRedo" }] : /* istanbul ignore next */ []));
108286
+ /** A configured command id was pressed. */
108287
+ this.command = output();
108288
+ this.translate = inject(TranslateService);
108289
+ /** Optional so the strip renders outside a full viewer host too. */
108290
+ this.viewerOpts = inject(ViewerOptionsService, { optional: true });
108291
+ this.tb = TITLE_BAR_CLASSES;
108292
+ this.items = computed(() => resolveQuickAccessItems(this.quickAccess().commandIds), /* @ts-ignore */
108293
+ ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
108294
+ }
108295
+ label(item) {
108296
+ return this.translate.instant(item.labelKey);
108297
+ }
108298
+ /** ScreenTip-styled tooltip (null suppresses the title attribute). */
108299
+ tip(item) {
108300
+ const label = this.label(item);
108301
+ return this.viewerOpts ? (this.viewerOpts.screenTip(label) ?? null) : label;
108302
+ }
108303
+ isDisabled(id) {
108304
+ if (id === 'undo') {
108305
+ return !this.canUndo();
108306
+ }
108307
+ if (id === 'redo') {
108308
+ return !this.canRedo();
108309
+ }
108310
+ return false;
108311
+ }
108312
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: QuickAccessStripComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
108313
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: QuickAccessStripComponent, isStandalone: true, selector: "pptx-quick-access-strip", inputs: { quickAccess: { classPropertyName: "quickAccess", publicName: "quickAccess", isSignal: true, isRequired: true, transformFunction: null }, canUndo: { classPropertyName: "canUndo", publicName: "canUndo", isSignal: true, isRequired: false, transformFunction: null }, canRedo: { classPropertyName: "canRedo", publicName: "canRedo", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { command: "command" }, ngImport: i0, template: `
108314
+ @for (item of items(); track item.id) {
108315
+ <button
108316
+ type="button"
108317
+ [class]="tb.quickButton"
108318
+ [disabled]="isDisabled(item.id)"
108319
+ [attr.title]="tip(item)"
108320
+ [attr.aria-label]="label(item)"
108321
+ (click)="command.emit(item.id)"
108322
+ >
108323
+ @switch (item.icon) {
108324
+ @case ('save') {
108325
+ <svg lucideSave class="h-3.5 w-3.5"></svg>
108326
+ }
108327
+ @case ('undo') {
108328
+ <svg lucideUndo class="h-3.5 w-3.5"></svg>
108329
+ }
108330
+ @case ('redo') {
108331
+ <svg lucideRedo class="h-3.5 w-3.5"></svg>
108332
+ }
108333
+ @case ('play') {
108334
+ <svg lucidePlay class="h-3.5 w-3.5"></svg>
108335
+ }
108336
+ @case ('printer') {
108337
+ <svg lucidePrinter class="h-3.5 w-3.5"></svg>
108338
+ }
108339
+ @case ('fileDown') {
108340
+ <svg lucideFileDown class="h-3.5 w-3.5"></svg>
108341
+ }
108342
+ @case ('plus') {
108343
+ <svg lucidePlus class="h-3.5 w-3.5"></svg>
108344
+ }
108345
+ @case ('spellCheck') {
108346
+ <svg lucideSearch class="h-3.5 w-3.5"></svg>
108347
+ }
108348
+ @case ('zoomIn') {
108349
+ <svg lucideZoomIn class="h-3.5 w-3.5"></svg>
108350
+ }
108351
+ @default {
108352
+ <svg lucideZoomOut class="h-3.5 w-3.5"></svg>
108353
+ }
108354
+ }
108355
+ @if (quickAccess().showCommandLabels) {
108356
+ <span class="pptx-ng-qat-label">{{ label(item) }}</span>
108357
+ }
108358
+ </button>
108359
+ }
108360
+ `, isInline: true, styles: [":host{display:inline-flex;align-items:center;gap:2px}.pptx-ng-qat-label{margin-left:4px;font-size:11px;white-space:nowrap}\n"], dependencies: [{ kind: "component", type: LucideSave, selector: "svg[lucideSave]" }, { kind: "component", type: LucideUndo, selector: "svg[lucideUndo]" }, { kind: "component", type: LucideRedo, selector: "svg[lucideRedo]" }, { kind: "component", type: LucidePlay, selector: "svg[lucidePlay]" }, { kind: "component", type: LucidePrinter, selector: "svg[lucidePrinter]" }, { kind: "component", type: LucideFileDown, selector: "svg[lucideFileDown]" }, { kind: "component", type: LucidePlus, selector: "svg[lucidePlus]" }, { kind: "component", type: LucideSearch, selector: "svg[lucideSearch]" }, { kind: "component", type: LucideZoomIn, selector: "svg[lucideZoomIn]" }, { kind: "component", type: LucideZoomOut, selector: "svg[lucideZoomOut]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
108361
+ }
108362
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: QuickAccessStripComponent, decorators: [{
108363
+ type: Component,
108364
+ args: [{ selector: 'pptx-quick-access-strip', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
108365
+ LucideSave,
108366
+ LucideUndo,
108367
+ LucideRedo,
108368
+ LucidePlay,
108369
+ LucidePrinter,
108370
+ LucideFileDown,
108371
+ LucidePlus,
108372
+ LucideSearch,
108373
+ LucideZoomIn,
108374
+ LucideZoomOut,
108375
+ ], template: `
108376
+ @for (item of items(); track item.id) {
108377
+ <button
108378
+ type="button"
108379
+ [class]="tb.quickButton"
108380
+ [disabled]="isDisabled(item.id)"
108381
+ [attr.title]="tip(item)"
108382
+ [attr.aria-label]="label(item)"
108383
+ (click)="command.emit(item.id)"
108384
+ >
108385
+ @switch (item.icon) {
108386
+ @case ('save') {
108387
+ <svg lucideSave class="h-3.5 w-3.5"></svg>
108388
+ }
108389
+ @case ('undo') {
108390
+ <svg lucideUndo class="h-3.5 w-3.5"></svg>
108391
+ }
108392
+ @case ('redo') {
108393
+ <svg lucideRedo class="h-3.5 w-3.5"></svg>
108394
+ }
108395
+ @case ('play') {
108396
+ <svg lucidePlay class="h-3.5 w-3.5"></svg>
108397
+ }
108398
+ @case ('printer') {
108399
+ <svg lucidePrinter class="h-3.5 w-3.5"></svg>
108400
+ }
108401
+ @case ('fileDown') {
108402
+ <svg lucideFileDown class="h-3.5 w-3.5"></svg>
108403
+ }
108404
+ @case ('plus') {
108405
+ <svg lucidePlus class="h-3.5 w-3.5"></svg>
108406
+ }
108407
+ @case ('spellCheck') {
108408
+ <svg lucideSearch class="h-3.5 w-3.5"></svg>
108409
+ }
108410
+ @case ('zoomIn') {
108411
+ <svg lucideZoomIn class="h-3.5 w-3.5"></svg>
108412
+ }
108413
+ @default {
108414
+ <svg lucideZoomOut class="h-3.5 w-3.5"></svg>
108415
+ }
108416
+ }
108417
+ @if (quickAccess().showCommandLabels) {
108418
+ <span class="pptx-ng-qat-label">{{ label(item) }}</span>
108419
+ }
108420
+ </button>
108421
+ }
108422
+ `, styles: [":host{display:inline-flex;align-items:center;gap:2px}.pptx-ng-qat-label{margin-left:4px;font-size:11px;white-space:nowrap}\n"] }]
108423
+ }], propDecorators: { quickAccess: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickAccess", required: true }] }], canUndo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canUndo", required: false }] }], canRedo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canRedo", required: false }] }], command: [{ type: i0.Output, args: ["command"] }] } });
108424
+
107641
108425
  /**
107642
108426
  * reading-view-overlay.styles.ts: CSS for PowerPoint's Reading View.
107643
108427
  *
@@ -112516,7 +113300,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
112516
113300
  }], propDecorators: { canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }], selectedElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElement", required: false }] }] } });
112517
113301
 
112518
113302
  // Generated by scripts/inline-shared.mjs from package.json. Do not edit.
112519
- const PPTX_ANGULAR_VIEWER_VERSION = "3.0.3";
113303
+ const PPTX_ANGULAR_VIEWER_VERSION = "3.1.1";
112520
113304
 
112521
113305
  /**
112522
113306
  * account-page.component.ts: File > Account content.
@@ -112700,7 +113484,6 @@ const CARD_ICONS = {
112700
113484
  saveAsPptx: 'P',
112701
113485
  saveAsPpsx: '▶',
112702
113486
  saveAsPptm: 'M',
112703
- package: '□',
112704
113487
  pdf: 'PDF',
112705
113488
  png: 'PNG',
112706
113489
  video: '▶',
@@ -112709,7 +113492,6 @@ const CARD_ICONS = {
112709
113492
  copyImage: '▣',
112710
113493
  print: '▧',
112711
113494
  share: '◇',
112712
- sharePackage: '□',
112713
113495
  };
112714
113496
  /**
112715
113497
  * Pure, testable filter: the main (non-footer) backstage nav entries visible
@@ -112733,6 +113515,9 @@ class RibbonFileSectionComponent {
112733
113515
  /** Toolbar buttons the host wants hidden (drops the Export nav entry/page). */
112734
113516
  this.hiddenActions = input([], /* @ts-ignore */
112735
113517
  ...(ngDevMode ? [{ debugName: "hiddenActions" }] : /* istanbul ignore next */ []));
113518
+ /** File > Options > Advanced > "Quickly access this number of Recent Documents". */
113519
+ this.recentPresentationsCount = input(undefined, /* @ts-ignore */
113520
+ ...(ngDevMode ? [{ debugName: "recentPresentationsCount" }] : /* istanbul ignore next */ []));
112736
113521
  /** Optional sign-in hook point for the Account page. Absent/disabled by default. */
112737
113522
  this.accountAuth = input(undefined, /* @ts-ignore */
112738
113523
  ...(ngDevMode ? [{ debugName: "accountAuth" }] : /* istanbul ignore next */ []));
@@ -112743,7 +113528,6 @@ class RibbonFileSectionComponent {
112743
113528
  this.save = output();
112744
113529
  this.savePpsx = output();
112745
113530
  this.savePptm = output();
112746
- this.packageForSharing = output();
112747
113531
  this.exportPng = output();
112748
113532
  this.exportPdf = output();
112749
113533
  this.exportGif = output();
@@ -112791,7 +113575,7 @@ class RibbonFileSectionComponent {
112791
113575
  this.size = formatBackstageSize;
112792
113576
  this.actions = computed(() => this.pageActions(this.page()), /* @ts-ignore */
112793
113577
  ...(ngDevMode ? [{ debugName: "actions" }] : /* istanbul ignore next */ []));
112794
- void (async () => this.recent.set(await listBackstageRecentFiles(this.t)))();
113578
+ void (async () => this.recent.set(await listBackstageRecentFiles(this.t, this.recentPresentationsCount())))();
112795
113579
  }
112796
113580
  date(timestamp) {
112797
113581
  return formatBackstageDate(timestamp, Date.now(), this.t);
@@ -112839,7 +113623,6 @@ class RibbonFileSectionComponent {
112839
113623
  saveAsPptx: this.save,
112840
113624
  saveAsPpsx: this.savePpsx,
112841
113625
  saveAsPptm: this.savePptm,
112842
- package: this.packageForSharing,
112843
113626
  pdf: this.exportPdf,
112844
113627
  png: this.exportPng,
112845
113628
  video: this.exportVideo,
@@ -112848,7 +113631,6 @@ class RibbonFileSectionComponent {
112848
113631
  copyImage: this.copySlideAsImage,
112849
113632
  print: this.print,
112850
113633
  share: this.share,
112851
- sharePackage: this.packageForSharing,
112852
113634
  };
112853
113635
  return backstageCardsFor(page)
112854
113636
  .filter((card) => card.id !== 'saveAsPptm' || this.hasMacros())
@@ -112860,12 +113642,12 @@ class RibbonFileSectionComponent {
112860
113642
  }));
112861
113643
  }
112862
113644
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: RibbonFileSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
112863
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: RibbonFileSectionComponent, isStandalone: true, selector: "pptx-ribbon-file-section", inputs: { fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, slideCount: { classPropertyName: "slideCount", publicName: "slideCount", isSignal: true, isRequired: false, transformFunction: null }, exporting: { classPropertyName: "exporting", publicName: "exporting", isSignal: true, isRequired: false, transformFunction: null }, hasMacros: { classPropertyName: "hasMacros", publicName: "hasMacros", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close", createPresentation: "createPresentation", openFile: "openFile", openRecentFile: "openRecentFile", save: "save", savePpsx: "savePpsx", savePptm: "savePptm", packageForSharing: "packageForSharing", exportPng: "exportPng", exportPdf: "exportPdf", exportGif: "exportGif", exportVideo: "exportVideo", exportJson: "exportJson", copySlideAsImage: "copySlideAsImage", print: "print", info: "info", signatures: "signatures", replace: "replace", openPassword: "openPassword", openFontEmbedding: "openFontEmbedding", openVersionHistory: "openVersionHistory", share: "share", options: "options" }, host: { classAttribute: "contents" }, ngImport: i0, template: "<div\n\tclass=\"bs\"\n\trole=\"dialog\"\n\taria-modal=\"true\"\n\t[attr.aria-label]=\"'pptx.backstage.title' | translate\"\n>\n\t<aside>\n\t\t<button\n\t\t\tclass=\"back\"\n\t\t\ttype=\"button\"\n\t\t\t[attr.aria-label]=\"'pptx.backstage.back' | translate\"\n\t\t\t(click)=\"close.emit()\"\n\t\t>\n\t\t\t<pptx-backstage-nav-icon page=\"back\" />\n\t\t</button>\n\t\t<nav>\n\t\t\t@for (item of mainNav(); track item.id) {\n\t\t\t\t<button type=\"button\" [class.active]=\"page() === item.id\" (click)=\"selectPage(item.id)\">\n\t\t\t\t\t<span><pptx-backstage-nav-icon [page]=\"item.id\" /></span>{{ item.labelKey | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t\t<i></i>\n\t\t\t@for (item of footerNav; track item.id) {\n\t\t\t\t<button type=\"button\" [class.active]=\"page() === item.id\" (click)=\"selectPage(item.id)\">\n\t\t\t\t\t<span><pptx-backstage-nav-icon [page]=\"item.id\" /></span>{{ item.labelKey | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t</nav>\n\t</aside>\n\t<main>\n\t\t<h1>{{ (page() === 'home' ? 'pptx.backstage.greeting' : titleKey()) | translate }}</h1>\n\t\t@if (page() === 'home' || page() === 'new') {\n\t\t\t<h2>{{ 'pptx.backstage.newHeading' | translate }}</h2>\n\t\t\t<div class=\"templates\">\n\t\t\t\t@for (template of templates; track template.id) {\n\t\t\t\t\t<button type=\"button\" (click)=\"create(template.id)\">\n\t\t\t\t\t\t<b [style.background]=\"template.preview\"></b\n\t\t\t\t\t\t><strong>{{ template.nameKey | translate }}</strong\n\t\t\t\t\t\t><small>{{ template.descriptionKey | translate }}</small>\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t@if (page() === 'home' || page() === 'open') {\n\t\t\t<input\n\t\t\t\tclass=\"search\"\n\t\t\t\ttype=\"search\"\n\t\t\t\t[attr.placeholder]=\"'pptx.backstage.searchPlaceholder' | translate\"\n\t\t\t\t[value]=\"query()\"\n\t\t\t\t(input)=\"query.set($any($event.target).value)\"\n\t\t\t/>\n\t\t\t@if (page() === 'open') {\n\t\t\t\t<button class=\"primary\" type=\"button\" (click)=\"run(openFile)\">\n\t\t\t\t\t{{ 'pptx.backstage.browseDevice' | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t\t<h2>{{ 'pptx.backstage.recentHeading' | translate }}</h2>\n\t\t\t<div class=\"recent\">\n\t\t\t\t<header>\n\t\t\t\t\t<span>{{ 'pptx.backstage.columnName' | translate }}</span\n\t\t\t\t\t><span>{{ 'pptx.backstage.columnModified' | translate }}</span\n\t\t\t\t\t><span>{{ 'pptx.backstage.columnSize' | translate }}</span>\n\t\t\t\t</header>\n\t\t\t\t@for (file of visibleRecent(); track file.key) {\n\t\t\t\t\t<button type=\"button\" (click)=\"openRecent(file.key)\">\n\t\t\t\t\t\t<span class=\"name\"\n\t\t\t\t\t\t\t><b>P</b\n\t\t\t\t\t\t\t><span\n\t\t\t\t\t\t\t\t><strong>{{ file.name }}</strong\n\t\t\t\t\t\t\t\t><small>{{ file.location }}</small></span\n\t\t\t\t\t\t\t></span\n\t\t\t\t\t\t><span>{{ date(file.timestamp) }}</span\n\t\t\t\t\t\t><span>{{ size(file.size) }}</span>\n\t\t\t\t\t</button>\n\t\t\t\t} @empty {\n\t\t\t\t\t<p>{{ 'pptx.backstage.noRecent' | translate }}</p>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t@if (actions().length) {\n\t\t\t<div class=\"actions\">\n\t\t\t\t@for (action of actions(); track action.titleKey) {\n\t\t\t\t\t<button type=\"button\" (click)=\"run(action.event)\">\n\t\t\t\t\t\t<b>{{ action.icon }}</b\n\t\t\t\t\t\t><span\n\t\t\t\t\t\t\t><strong>{{ action.titleKey | translate }}</strong\n\t\t\t\t\t\t\t><small>{{ action.bodyKey | translate }}</small></span\n\t\t\t\t\t\t>\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t@if (page() === 'account') {\n\t\t\t<pptx-account-page [accountAuth]=\"accountAuth()\" />\n\t\t}\n\t\t@if (page() === 'options') {\n\t\t\t<section class=\"card\">\n\t\t\t\t<b class=\"avatar\">\u2699</b>\n\t\t\t\t<h2>{{ 'pptx.backstage.optionsTitle' | translate }}</h2>\n\t\t\t\t<p>{{ 'pptx.backstage.optionsBody' | translate }}</p>\n\t\t\t\t<button class=\"primary\" type=\"button\" (click)=\"run(options)\">\n\t\t\t\t\t{{ 'pptx.backstage.openOptions' | translate }}\n\t\t\t\t</button>\n\t\t\t</section>\n\t\t}\n\t\t<footer>\n\t\t\t{{ fileName() || ('pptx.backstage.untitled' | translate) }} \u00B7\n\t\t\t{{ 'pptx.backstage.savedToBrowser' | translate }}\n\t\t</footer>\n\t</main>\n</div>\n", styles: [":host{font-family:Aptos,Segoe UI,sans-serif}.bs{position:fixed;inset:0;z-index:200;display:flex;background:var(--pptx-background, #fafafa);color:var(--pptx-foreground, #242424)}.bs aside{display:flex;width:148px;flex:none;flex-direction:column;border-right:1px solid var(--pptx-border, #d7d7d7);background:var(--pptx-secondary, #f5eee9)}.back{height:48px;border:0;border-bottom:1px solid var(--pptx-border, #ddd);background:none;color:inherit;font-size:22px}.back:hover,nav button:hover,.recent>button:hover{background:var(--pptx-accent, #eadfd8)}nav{display:flex;min-height:0;flex:1;flex-direction:column;padding:8px 0}nav i{flex:1}nav button{display:flex;min-height:40px;align-items:center;gap:12px;padding:0 16px;border:0;border-left:2px solid transparent;background:none;color:inherit;font-size:12px;text-align:left}nav button span{width:16px;font-size:16px;text-align:center}nav button.active{border-left-color:var(--pptx-primary, #c43e1c);background:var(--pptx-card, #fff);color:var(--pptx-primary, #c43e1c)}main{min-width:0;flex:1;overflow:auto;padding:20px clamp(32px,4vw,72px)}h1{margin:0;font-size:24px;font-weight:600}h2{margin:28px 0 18px;font-size:17px}.templates{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:24px}.templates button{border:0;background:none;color:inherit;text-align:left}.templates button>b{display:block;aspect-ratio:16/9;border:1px solid var(--pptx-border, #ccc);box-shadow:0 1px 2px #0002;transition:.15s}.templates button:hover>b{transform:translateY(-2px);border-color:var(--pptx-primary, #c43e1c);box-shadow:0 7px 18px #0002}.templates strong,.templates small{display:block;overflow:hidden;margin-top:8px;font-size:12px;text-overflow:ellipsis;white-space:nowrap}.templates small{margin-top:2px;color:var(--pptx-muted-foreground, #777);font-size:10px}.search{display:block;width:min(540px,100%);height:40px;margin-top:32px;padding:0 14px;border:1px solid var(--pptx-input, #888);background:var(--pptx-card, #fff);color:var(--pptx-card-foreground, #242424)}.search:focus{border-color:var(--pptx-ring, #c43e1c);outline:none}.primary{margin-top:16px;padding:10px 20px;border:0;background:var(--pptx-primary, #c43e1c);color:var(--pptx-primary-foreground, #fff);font-weight:600}.recent{border-top:1px solid var(--pptx-border, #ddd)}.recent header,.recent>button{display:grid;grid-template-columns:1fr 120px 90px;align-items:center;padding:10px 12px}.recent header{color:var(--pptx-muted-foreground, #666);font-size:11px;font-weight:600}.recent>button{width:100%;border:0;border-top:1px solid var(--pptx-border, #e5e5e5);background:none;color:inherit;font-size:11px;text-align:left}.name{display:flex;min-width:0;align-items:center;gap:12px}.name>b{display:grid;width:32px;height:32px;place-items:center;background:var(--pptx-primary, #d24726);color:var(--pptx-primary-foreground, #fff)}.name strong,.name small{display:block;overflow:hidden;font-size:13px;font-weight:400;text-overflow:ellipsis;white-space:nowrap}.name small,.recent p{color:var(--pptx-muted-foreground, #666);font-size:11px}.recent p{text-align:center}.actions{display:grid;max-width:900px;grid-template-columns:1fr 1fr;gap:20px;margin-top:32px}.actions button{display:flex;min-height:112px;gap:16px;padding:20px;border:1px solid var(--pptx-border, #ddd);background:var(--pptx-card, #fff);color:var(--pptx-card-foreground, #242424);text-align:left}.actions button:hover{border-color:var(--pptx-primary, #c43e1c);box-shadow:0 5px 15px #0002}.actions button>b{display:grid;width:40px;height:40px;flex:none;place-items:center;background:var(--pptx-accent, #fbe9e3);color:var(--pptx-primary, #c43e1c)}.actions strong,.actions small{display:block;font-size:15px}.actions small{margin-top:7px;color:var(--pptx-muted-foreground, #666);font-size:12px;line-height:1.5}.card{max-width:760px;margin-top:32px;padding:28px;border:1px solid var(--pptx-border, #ddd);background:var(--pptx-card, #fff);color:var(--pptx-card-foreground, #242424)}.avatar{display:grid;width:56px;height:56px;place-items:center;border-radius:50%;background:var(--pptx-primary, #c43e1c);color:var(--pptx-primary-foreground, #fff);font-size:20px}.card p,footer{color:var(--pptx-muted-foreground, #666)}.card p{line-height:1.6}footer{margin-top:48px;font-size:11px}@media(max-width:640px),(pointer:coarse){.bs{flex-direction:column}.bs aside{width:100%;flex-direction:row;align-items:center;overflow-x:auto;border-right:0;border-bottom:1px solid var(--pptx-border, #d7d7d7)}.back{min-width:48px;flex-shrink:0;border-bottom:0;border-right:1px solid var(--pptx-border, #ddd)}nav{flex-direction:row;align-items:center;padding:0}nav i{display:none}nav button{flex-shrink:0;white-space:nowrap;border-left:0;border-bottom:2px solid transparent;padding:0 12px}nav button.active{border-left-color:transparent;border-bottom-color:var(--pptx-primary, #c43e1c)}main{padding:16px}.actions{grid-template-columns:1fr}.recent header,.recent>button{grid-template-columns:1fr 90px}.recent header span:last-child,.recent>button>span:last-child{display:none}}\n"], dependencies: [{ kind: "component", type: BackstageNavIconComponent, selector: "pptx-backstage-nav-icon", inputs: ["page"] }, { kind: "component", type: AccountPageComponent, selector: "pptx-account-page", inputs: ["accountAuth"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
113645
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: RibbonFileSectionComponent, isStandalone: true, selector: "pptx-ribbon-file-section", inputs: { fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, slideCount: { classPropertyName: "slideCount", publicName: "slideCount", isSignal: true, isRequired: false, transformFunction: null }, exporting: { classPropertyName: "exporting", publicName: "exporting", isSignal: true, isRequired: false, transformFunction: null }, hasMacros: { classPropertyName: "hasMacros", publicName: "hasMacros", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, recentPresentationsCount: { classPropertyName: "recentPresentationsCount", publicName: "recentPresentationsCount", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close", createPresentation: "createPresentation", openFile: "openFile", openRecentFile: "openRecentFile", save: "save", savePpsx: "savePpsx", savePptm: "savePptm", exportPng: "exportPng", exportPdf: "exportPdf", exportGif: "exportGif", exportVideo: "exportVideo", exportJson: "exportJson", copySlideAsImage: "copySlideAsImage", print: "print", info: "info", signatures: "signatures", replace: "replace", openPassword: "openPassword", openFontEmbedding: "openFontEmbedding", openVersionHistory: "openVersionHistory", share: "share", options: "options" }, host: { classAttribute: "contents" }, ngImport: i0, template: "<div\n\tclass=\"bs\"\n\trole=\"dialog\"\n\taria-modal=\"true\"\n\t[attr.aria-label]=\"'pptx.backstage.title' | translate\"\n>\n\t<aside>\n\t\t<button\n\t\t\tclass=\"back\"\n\t\t\ttype=\"button\"\n\t\t\t[attr.aria-label]=\"'pptx.backstage.back' | translate\"\n\t\t\t(click)=\"close.emit()\"\n\t\t>\n\t\t\t<pptx-backstage-nav-icon page=\"back\" />\n\t\t</button>\n\t\t<nav>\n\t\t\t@for (item of mainNav(); track item.id) {\n\t\t\t\t<button type=\"button\" [class.active]=\"page() === item.id\" (click)=\"selectPage(item.id)\">\n\t\t\t\t\t<span><pptx-backstage-nav-icon [page]=\"item.id\" /></span>{{ item.labelKey | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t\t<i></i>\n\t\t\t@for (item of footerNav; track item.id) {\n\t\t\t\t<button type=\"button\" [class.active]=\"page() === item.id\" (click)=\"selectPage(item.id)\">\n\t\t\t\t\t<span><pptx-backstage-nav-icon [page]=\"item.id\" /></span>{{ item.labelKey | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t</nav>\n\t</aside>\n\t<main>\n\t\t<h1>{{ (page() === 'home' ? 'pptx.backstage.greeting' : titleKey()) | translate }}</h1>\n\t\t@if (page() === 'home' || page() === 'new') {\n\t\t\t<h2>{{ 'pptx.backstage.newHeading' | translate }}</h2>\n\t\t\t<div class=\"templates\">\n\t\t\t\t@for (template of templates; track template.id) {\n\t\t\t\t\t<button type=\"button\" (click)=\"create(template.id)\">\n\t\t\t\t\t\t<b [style.background]=\"template.preview\"></b\n\t\t\t\t\t\t><strong>{{ template.nameKey | translate }}</strong\n\t\t\t\t\t\t><small>{{ template.descriptionKey | translate }}</small>\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t@if (page() === 'home' || page() === 'open') {\n\t\t\t<input\n\t\t\t\tclass=\"search\"\n\t\t\t\ttype=\"search\"\n\t\t\t\t[attr.placeholder]=\"'pptx.backstage.searchPlaceholder' | translate\"\n\t\t\t\t[value]=\"query()\"\n\t\t\t\t(input)=\"query.set($any($event.target).value)\"\n\t\t\t/>\n\t\t\t@if (page() === 'open') {\n\t\t\t\t<button class=\"primary\" type=\"button\" (click)=\"run(openFile)\">\n\t\t\t\t\t{{ 'pptx.backstage.browseDevice' | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t\t<h2>{{ 'pptx.backstage.recentHeading' | translate }}</h2>\n\t\t\t<div class=\"recent\">\n\t\t\t\t<header>\n\t\t\t\t\t<span>{{ 'pptx.backstage.columnName' | translate }}</span\n\t\t\t\t\t><span>{{ 'pptx.backstage.columnModified' | translate }}</span\n\t\t\t\t\t><span>{{ 'pptx.backstage.columnSize' | translate }}</span>\n\t\t\t\t</header>\n\t\t\t\t@for (file of visibleRecent(); track file.key) {\n\t\t\t\t\t<button type=\"button\" (click)=\"openRecent(file.key)\">\n\t\t\t\t\t\t<span class=\"name\"\n\t\t\t\t\t\t\t><b>P</b\n\t\t\t\t\t\t\t><span\n\t\t\t\t\t\t\t\t><strong>{{ file.name }}</strong\n\t\t\t\t\t\t\t\t><small>{{ file.location }}</small></span\n\t\t\t\t\t\t\t></span\n\t\t\t\t\t\t><span>{{ date(file.timestamp) }}</span\n\t\t\t\t\t\t><span>{{ size(file.size) }}</span>\n\t\t\t\t\t</button>\n\t\t\t\t} @empty {\n\t\t\t\t\t<p>{{ 'pptx.backstage.noRecent' | translate }}</p>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t@if (actions().length) {\n\t\t\t<div class=\"actions\">\n\t\t\t\t@for (action of actions(); track action.titleKey) {\n\t\t\t\t\t<button type=\"button\" (click)=\"run(action.event)\">\n\t\t\t\t\t\t<b>{{ action.icon }}</b\n\t\t\t\t\t\t><span\n\t\t\t\t\t\t\t><strong>{{ action.titleKey | translate }}</strong\n\t\t\t\t\t\t\t><small>{{ action.bodyKey | translate }}</small></span\n\t\t\t\t\t\t>\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t@if (page() === 'account') {\n\t\t\t<pptx-account-page [accountAuth]=\"accountAuth()\" />\n\t\t}\n\t\t@if (page() === 'options') {\n\t\t\t<section class=\"card\">\n\t\t\t\t<b class=\"avatar\">\u2699</b>\n\t\t\t\t<h2>{{ 'pptx.backstage.optionsTitle' | translate }}</h2>\n\t\t\t\t<p>{{ 'pptx.backstage.optionsBody' | translate }}</p>\n\t\t\t\t<button class=\"primary\" type=\"button\" (click)=\"run(options)\">\n\t\t\t\t\t{{ 'pptx.backstage.openOptions' | translate }}\n\t\t\t\t</button>\n\t\t\t</section>\n\t\t}\n\t\t<footer>\n\t\t\t{{ fileName() || ('pptx.backstage.untitled' | translate) }} \u00B7\n\t\t\t{{ 'pptx.backstage.savedToBrowser' | translate }}\n\t\t</footer>\n\t</main>\n</div>\n", styles: [":host{font-family:Aptos,Segoe UI,sans-serif}.bs{position:fixed;inset:0;z-index:200;display:flex;background:var(--pptx-background, #fafafa);color:var(--pptx-foreground, #242424)}.bs aside{display:flex;width:148px;flex:none;flex-direction:column;border-right:1px solid var(--pptx-border, #d7d7d7);background:var(--pptx-secondary, #f5eee9)}.back{height:48px;border:0;border-bottom:1px solid var(--pptx-border, #ddd);background:none;color:inherit;font-size:22px}.back:hover,nav button:hover,.recent>button:hover{background:var(--pptx-accent, #eadfd8)}nav{display:flex;min-height:0;flex:1;flex-direction:column;padding:8px 0}nav i{flex:1}nav button{display:flex;min-height:40px;align-items:center;gap:12px;padding:0 16px;border:0;border-left:2px solid transparent;background:none;color:inherit;font-size:12px;text-align:left}nav button span{width:16px;font-size:16px;text-align:center}nav button.active{border-left-color:var(--pptx-primary, #c43e1c);background:var(--pptx-card, #fff);color:var(--pptx-primary, #c43e1c)}main{min-width:0;flex:1;overflow:auto;padding:20px clamp(32px,4vw,72px)}h1{margin:0;font-size:24px;font-weight:600}h2{margin:28px 0 18px;font-size:17px}.templates{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:24px}.templates button{border:0;background:none;color:inherit;text-align:left}.templates button>b{display:block;aspect-ratio:16/9;border:1px solid var(--pptx-border, #ccc);box-shadow:0 1px 2px #0002;transition:.15s}.templates button:hover>b{transform:translateY(-2px);border-color:var(--pptx-primary, #c43e1c);box-shadow:0 7px 18px #0002}.templates strong,.templates small{display:block;overflow:hidden;margin-top:8px;font-size:12px;text-overflow:ellipsis;white-space:nowrap}.templates small{margin-top:2px;color:var(--pptx-muted-foreground, #777);font-size:10px}.search{display:block;width:min(540px,100%);height:40px;margin-top:32px;padding:0 14px;border:1px solid var(--pptx-input, #888);background:var(--pptx-card, #fff);color:var(--pptx-card-foreground, #242424)}.search:focus{border-color:var(--pptx-ring, #c43e1c);outline:none}.primary{margin-top:16px;padding:10px 20px;border:0;background:var(--pptx-primary, #c43e1c);color:var(--pptx-primary-foreground, #fff);font-weight:600}.recent{border-top:1px solid var(--pptx-border, #ddd)}.recent header,.recent>button{display:grid;grid-template-columns:1fr 120px 90px;align-items:center;padding:10px 12px}.recent header{color:var(--pptx-muted-foreground, #666);font-size:11px;font-weight:600}.recent>button{width:100%;border:0;border-top:1px solid var(--pptx-border, #e5e5e5);background:none;color:inherit;font-size:11px;text-align:left}.name{display:flex;min-width:0;align-items:center;gap:12px}.name>b{display:grid;width:32px;height:32px;place-items:center;background:var(--pptx-primary, #d24726);color:var(--pptx-primary-foreground, #fff)}.name strong,.name small{display:block;overflow:hidden;font-size:13px;font-weight:400;text-overflow:ellipsis;white-space:nowrap}.name small,.recent p{color:var(--pptx-muted-foreground, #666);font-size:11px}.recent p{text-align:center}.actions{display:grid;max-width:900px;grid-template-columns:1fr 1fr;gap:20px;margin-top:32px}.actions button{display:flex;min-height:112px;gap:16px;padding:20px;border:1px solid var(--pptx-border, #ddd);background:var(--pptx-card, #fff);color:var(--pptx-card-foreground, #242424);text-align:left}.actions button:hover{border-color:var(--pptx-primary, #c43e1c);box-shadow:0 5px 15px #0002}.actions button>b{display:grid;width:40px;height:40px;flex:none;place-items:center;background:var(--pptx-accent, #fbe9e3);color:var(--pptx-primary, #c43e1c)}.actions strong,.actions small{display:block;font-size:15px}.actions small{margin-top:7px;color:var(--pptx-muted-foreground, #666);font-size:12px;line-height:1.5}.card{max-width:760px;margin-top:32px;padding:28px;border:1px solid var(--pptx-border, #ddd);background:var(--pptx-card, #fff);color:var(--pptx-card-foreground, #242424)}.avatar{display:grid;width:56px;height:56px;place-items:center;border-radius:50%;background:var(--pptx-primary, #c43e1c);color:var(--pptx-primary-foreground, #fff);font-size:20px}.card p,footer{color:var(--pptx-muted-foreground, #666)}.card p{line-height:1.6}footer{margin-top:48px;font-size:11px}@media(max-width:640px),(pointer:coarse){.bs{flex-direction:column}.bs aside{width:100%;flex-direction:row;align-items:center;overflow-x:auto;border-right:0;border-bottom:1px solid var(--pptx-border, #d7d7d7)}.back{min-width:48px;flex-shrink:0;border-bottom:0;border-right:1px solid var(--pptx-border, #ddd)}nav{flex-direction:row;align-items:center;padding:0}nav i{display:none}nav button{flex-shrink:0;white-space:nowrap;border-left:0;border-bottom:2px solid transparent;padding:0 12px}nav button.active{border-left-color:transparent;border-bottom-color:var(--pptx-primary, #c43e1c)}main{padding:16px}.actions{grid-template-columns:1fr}.recent header,.recent>button{grid-template-columns:1fr 90px}.recent header span:last-child,.recent>button>span:last-child{display:none}}\n"], dependencies: [{ kind: "component", type: BackstageNavIconComponent, selector: "pptx-backstage-nav-icon", inputs: ["page"] }, { kind: "component", type: AccountPageComponent, selector: "pptx-account-page", inputs: ["accountAuth"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
112864
113646
  }
112865
113647
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: RibbonFileSectionComponent, decorators: [{
112866
113648
  type: Component,
112867
113649
  args: [{ selector: 'pptx-ribbon-file-section', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'contents' }, imports: [BackstageNavIconComponent, AccountPageComponent, TranslatePipe], template: "<div\n\tclass=\"bs\"\n\trole=\"dialog\"\n\taria-modal=\"true\"\n\t[attr.aria-label]=\"'pptx.backstage.title' | translate\"\n>\n\t<aside>\n\t\t<button\n\t\t\tclass=\"back\"\n\t\t\ttype=\"button\"\n\t\t\t[attr.aria-label]=\"'pptx.backstage.back' | translate\"\n\t\t\t(click)=\"close.emit()\"\n\t\t>\n\t\t\t<pptx-backstage-nav-icon page=\"back\" />\n\t\t</button>\n\t\t<nav>\n\t\t\t@for (item of mainNav(); track item.id) {\n\t\t\t\t<button type=\"button\" [class.active]=\"page() === item.id\" (click)=\"selectPage(item.id)\">\n\t\t\t\t\t<span><pptx-backstage-nav-icon [page]=\"item.id\" /></span>{{ item.labelKey | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t\t<i></i>\n\t\t\t@for (item of footerNav; track item.id) {\n\t\t\t\t<button type=\"button\" [class.active]=\"page() === item.id\" (click)=\"selectPage(item.id)\">\n\t\t\t\t\t<span><pptx-backstage-nav-icon [page]=\"item.id\" /></span>{{ item.labelKey | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t</nav>\n\t</aside>\n\t<main>\n\t\t<h1>{{ (page() === 'home' ? 'pptx.backstage.greeting' : titleKey()) | translate }}</h1>\n\t\t@if (page() === 'home' || page() === 'new') {\n\t\t\t<h2>{{ 'pptx.backstage.newHeading' | translate }}</h2>\n\t\t\t<div class=\"templates\">\n\t\t\t\t@for (template of templates; track template.id) {\n\t\t\t\t\t<button type=\"button\" (click)=\"create(template.id)\">\n\t\t\t\t\t\t<b [style.background]=\"template.preview\"></b\n\t\t\t\t\t\t><strong>{{ template.nameKey | translate }}</strong\n\t\t\t\t\t\t><small>{{ template.descriptionKey | translate }}</small>\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t@if (page() === 'home' || page() === 'open') {\n\t\t\t<input\n\t\t\t\tclass=\"search\"\n\t\t\t\ttype=\"search\"\n\t\t\t\t[attr.placeholder]=\"'pptx.backstage.searchPlaceholder' | translate\"\n\t\t\t\t[value]=\"query()\"\n\t\t\t\t(input)=\"query.set($any($event.target).value)\"\n\t\t\t/>\n\t\t\t@if (page() === 'open') {\n\t\t\t\t<button class=\"primary\" type=\"button\" (click)=\"run(openFile)\">\n\t\t\t\t\t{{ 'pptx.backstage.browseDevice' | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t\t<h2>{{ 'pptx.backstage.recentHeading' | translate }}</h2>\n\t\t\t<div class=\"recent\">\n\t\t\t\t<header>\n\t\t\t\t\t<span>{{ 'pptx.backstage.columnName' | translate }}</span\n\t\t\t\t\t><span>{{ 'pptx.backstage.columnModified' | translate }}</span\n\t\t\t\t\t><span>{{ 'pptx.backstage.columnSize' | translate }}</span>\n\t\t\t\t</header>\n\t\t\t\t@for (file of visibleRecent(); track file.key) {\n\t\t\t\t\t<button type=\"button\" (click)=\"openRecent(file.key)\">\n\t\t\t\t\t\t<span class=\"name\"\n\t\t\t\t\t\t\t><b>P</b\n\t\t\t\t\t\t\t><span\n\t\t\t\t\t\t\t\t><strong>{{ file.name }}</strong\n\t\t\t\t\t\t\t\t><small>{{ file.location }}</small></span\n\t\t\t\t\t\t\t></span\n\t\t\t\t\t\t><span>{{ date(file.timestamp) }}</span\n\t\t\t\t\t\t><span>{{ size(file.size) }}</span>\n\t\t\t\t\t</button>\n\t\t\t\t} @empty {\n\t\t\t\t\t<p>{{ 'pptx.backstage.noRecent' | translate }}</p>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t@if (actions().length) {\n\t\t\t<div class=\"actions\">\n\t\t\t\t@for (action of actions(); track action.titleKey) {\n\t\t\t\t\t<button type=\"button\" (click)=\"run(action.event)\">\n\t\t\t\t\t\t<b>{{ action.icon }}</b\n\t\t\t\t\t\t><span\n\t\t\t\t\t\t\t><strong>{{ action.titleKey | translate }}</strong\n\t\t\t\t\t\t\t><small>{{ action.bodyKey | translate }}</small></span\n\t\t\t\t\t\t>\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t@if (page() === 'account') {\n\t\t\t<pptx-account-page [accountAuth]=\"accountAuth()\" />\n\t\t}\n\t\t@if (page() === 'options') {\n\t\t\t<section class=\"card\">\n\t\t\t\t<b class=\"avatar\">\u2699</b>\n\t\t\t\t<h2>{{ 'pptx.backstage.optionsTitle' | translate }}</h2>\n\t\t\t\t<p>{{ 'pptx.backstage.optionsBody' | translate }}</p>\n\t\t\t\t<button class=\"primary\" type=\"button\" (click)=\"run(options)\">\n\t\t\t\t\t{{ 'pptx.backstage.openOptions' | translate }}\n\t\t\t\t</button>\n\t\t\t</section>\n\t\t}\n\t\t<footer>\n\t\t\t{{ fileName() || ('pptx.backstage.untitled' | translate) }} \u00B7\n\t\t\t{{ 'pptx.backstage.savedToBrowser' | translate }}\n\t\t</footer>\n\t</main>\n</div>\n", styles: [":host{font-family:Aptos,Segoe UI,sans-serif}.bs{position:fixed;inset:0;z-index:200;display:flex;background:var(--pptx-background, #fafafa);color:var(--pptx-foreground, #242424)}.bs aside{display:flex;width:148px;flex:none;flex-direction:column;border-right:1px solid var(--pptx-border, #d7d7d7);background:var(--pptx-secondary, #f5eee9)}.back{height:48px;border:0;border-bottom:1px solid var(--pptx-border, #ddd);background:none;color:inherit;font-size:22px}.back:hover,nav button:hover,.recent>button:hover{background:var(--pptx-accent, #eadfd8)}nav{display:flex;min-height:0;flex:1;flex-direction:column;padding:8px 0}nav i{flex:1}nav button{display:flex;min-height:40px;align-items:center;gap:12px;padding:0 16px;border:0;border-left:2px solid transparent;background:none;color:inherit;font-size:12px;text-align:left}nav button span{width:16px;font-size:16px;text-align:center}nav button.active{border-left-color:var(--pptx-primary, #c43e1c);background:var(--pptx-card, #fff);color:var(--pptx-primary, #c43e1c)}main{min-width:0;flex:1;overflow:auto;padding:20px clamp(32px,4vw,72px)}h1{margin:0;font-size:24px;font-weight:600}h2{margin:28px 0 18px;font-size:17px}.templates{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:24px}.templates button{border:0;background:none;color:inherit;text-align:left}.templates button>b{display:block;aspect-ratio:16/9;border:1px solid var(--pptx-border, #ccc);box-shadow:0 1px 2px #0002;transition:.15s}.templates button:hover>b{transform:translateY(-2px);border-color:var(--pptx-primary, #c43e1c);box-shadow:0 7px 18px #0002}.templates strong,.templates small{display:block;overflow:hidden;margin-top:8px;font-size:12px;text-overflow:ellipsis;white-space:nowrap}.templates small{margin-top:2px;color:var(--pptx-muted-foreground, #777);font-size:10px}.search{display:block;width:min(540px,100%);height:40px;margin-top:32px;padding:0 14px;border:1px solid var(--pptx-input, #888);background:var(--pptx-card, #fff);color:var(--pptx-card-foreground, #242424)}.search:focus{border-color:var(--pptx-ring, #c43e1c);outline:none}.primary{margin-top:16px;padding:10px 20px;border:0;background:var(--pptx-primary, #c43e1c);color:var(--pptx-primary-foreground, #fff);font-weight:600}.recent{border-top:1px solid var(--pptx-border, #ddd)}.recent header,.recent>button{display:grid;grid-template-columns:1fr 120px 90px;align-items:center;padding:10px 12px}.recent header{color:var(--pptx-muted-foreground, #666);font-size:11px;font-weight:600}.recent>button{width:100%;border:0;border-top:1px solid var(--pptx-border, #e5e5e5);background:none;color:inherit;font-size:11px;text-align:left}.name{display:flex;min-width:0;align-items:center;gap:12px}.name>b{display:grid;width:32px;height:32px;place-items:center;background:var(--pptx-primary, #d24726);color:var(--pptx-primary-foreground, #fff)}.name strong,.name small{display:block;overflow:hidden;font-size:13px;font-weight:400;text-overflow:ellipsis;white-space:nowrap}.name small,.recent p{color:var(--pptx-muted-foreground, #666);font-size:11px}.recent p{text-align:center}.actions{display:grid;max-width:900px;grid-template-columns:1fr 1fr;gap:20px;margin-top:32px}.actions button{display:flex;min-height:112px;gap:16px;padding:20px;border:1px solid var(--pptx-border, #ddd);background:var(--pptx-card, #fff);color:var(--pptx-card-foreground, #242424);text-align:left}.actions button:hover{border-color:var(--pptx-primary, #c43e1c);box-shadow:0 5px 15px #0002}.actions button>b{display:grid;width:40px;height:40px;flex:none;place-items:center;background:var(--pptx-accent, #fbe9e3);color:var(--pptx-primary, #c43e1c)}.actions strong,.actions small{display:block;font-size:15px}.actions small{margin-top:7px;color:var(--pptx-muted-foreground, #666);font-size:12px;line-height:1.5}.card{max-width:760px;margin-top:32px;padding:28px;border:1px solid var(--pptx-border, #ddd);background:var(--pptx-card, #fff);color:var(--pptx-card-foreground, #242424)}.avatar{display:grid;width:56px;height:56px;place-items:center;border-radius:50%;background:var(--pptx-primary, #c43e1c);color:var(--pptx-primary-foreground, #fff);font-size:20px}.card p,footer{color:var(--pptx-muted-foreground, #666)}.card p{line-height:1.6}footer{margin-top:48px;font-size:11px}@media(max-width:640px),(pointer:coarse){.bs{flex-direction:column}.bs aside{width:100%;flex-direction:row;align-items:center;overflow-x:auto;border-right:0;border-bottom:1px solid var(--pptx-border, #d7d7d7)}.back{min-width:48px;flex-shrink:0;border-bottom:0;border-right:1px solid var(--pptx-border, #ddd)}nav{flex-direction:row;align-items:center;padding:0}nav i{display:none}nav button{flex-shrink:0;white-space:nowrap;border-left:0;border-bottom:2px solid transparent;padding:0 12px}nav button.active{border-left-color:transparent;border-bottom-color:var(--pptx-primary, #c43e1c)}main{padding:16px}.actions{grid-template-columns:1fr}.recent header,.recent>button{grid-template-columns:1fr 90px}.recent header span:last-child,.recent>button>span:last-child{display:none}}\n"] }]
112868
- }], ctorParameters: () => [], propDecorators: { fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], slideCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideCount", required: false }] }], exporting: [{ type: i0.Input, args: [{ isSignal: true, alias: "exporting", required: false }] }], hasMacros: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMacros", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], close: [{ type: i0.Output, args: ["close"] }], createPresentation: [{ type: i0.Output, args: ["createPresentation"] }], openFile: [{ type: i0.Output, args: ["openFile"] }], openRecentFile: [{ type: i0.Output, args: ["openRecentFile"] }], save: [{ type: i0.Output, args: ["save"] }], savePpsx: [{ type: i0.Output, args: ["savePpsx"] }], savePptm: [{ type: i0.Output, args: ["savePptm"] }], packageForSharing: [{ type: i0.Output, args: ["packageForSharing"] }], exportPng: [{ type: i0.Output, args: ["exportPng"] }], exportPdf: [{ type: i0.Output, args: ["exportPdf"] }], exportGif: [{ type: i0.Output, args: ["exportGif"] }], exportVideo: [{ type: i0.Output, args: ["exportVideo"] }], exportJson: [{ type: i0.Output, args: ["exportJson"] }], copySlideAsImage: [{ type: i0.Output, args: ["copySlideAsImage"] }], print: [{ type: i0.Output, args: ["print"] }], info: [{ type: i0.Output, args: ["info"] }], signatures: [{ type: i0.Output, args: ["signatures"] }], replace: [{ type: i0.Output, args: ["replace"] }], openPassword: [{ type: i0.Output, args: ["openPassword"] }], openFontEmbedding: [{ type: i0.Output, args: ["openFontEmbedding"] }], openVersionHistory: [{ type: i0.Output, args: ["openVersionHistory"] }], share: [{ type: i0.Output, args: ["share"] }], options: [{ type: i0.Output, args: ["options"] }] } });
113650
+ }], ctorParameters: () => [], propDecorators: { fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], slideCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideCount", required: false }] }], exporting: [{ type: i0.Input, args: [{ isSignal: true, alias: "exporting", required: false }] }], hasMacros: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMacros", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], recentPresentationsCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "recentPresentationsCount", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], close: [{ type: i0.Output, args: ["close"] }], createPresentation: [{ type: i0.Output, args: ["createPresentation"] }], openFile: [{ type: i0.Output, args: ["openFile"] }], openRecentFile: [{ type: i0.Output, args: ["openRecentFile"] }], save: [{ type: i0.Output, args: ["save"] }], savePpsx: [{ type: i0.Output, args: ["savePpsx"] }], savePptm: [{ type: i0.Output, args: ["savePptm"] }], exportPng: [{ type: i0.Output, args: ["exportPng"] }], exportPdf: [{ type: i0.Output, args: ["exportPdf"] }], exportGif: [{ type: i0.Output, args: ["exportGif"] }], exportVideo: [{ type: i0.Output, args: ["exportVideo"] }], exportJson: [{ type: i0.Output, args: ["exportJson"] }], copySlideAsImage: [{ type: i0.Output, args: ["copySlideAsImage"] }], print: [{ type: i0.Output, args: ["print"] }], info: [{ type: i0.Output, args: ["info"] }], signatures: [{ type: i0.Output, args: ["signatures"] }], replace: [{ type: i0.Output, args: ["replace"] }], openPassword: [{ type: i0.Output, args: ["openPassword"] }], openFontEmbedding: [{ type: i0.Output, args: ["openFontEmbedding"] }], openVersionHistory: [{ type: i0.Output, args: ["openVersionHistory"] }], share: [{ type: i0.Output, args: ["share"] }], options: [{ type: i0.Output, args: ["options"] }] } });
112869
113651
 
112870
113652
  /**
112871
113653
  * ribbon-font-controls.component.ts: the ribbon's reusable Font control group
@@ -115744,7 +116526,6 @@ class RibbonContentComponent {
115744
116526
  this.save = output();
115745
116527
  this.savePpsx = output();
115746
116528
  this.savePptm = output();
115747
- this.packageForSharing = output();
115748
116529
  this.signatures = output();
115749
116530
  this.info = output();
115750
116531
  this.print = output();
@@ -115778,7 +116559,7 @@ class RibbonContentComponent {
115778
116559
  ...(ngDevMode ? [{ debugName: "newShapeType" }] : /* istanbul ignore next */ []));
115779
116560
  }
115780
116561
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: RibbonContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
115781
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: RibbonContentComponent, isStandalone: true, selector: "pptx-ribbon-content", inputs: { activeTab: { classPropertyName: "activeTab", publicName: "activeTab", isSignal: true, isRequired: true, transformFunction: null }, slideIndex: { classPropertyName: "slideIndex", publicName: "slideIndex", isSignal: true, isRequired: false, transformFunction: null }, slideCount: { classPropertyName: "slideCount", publicName: "slideCount", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, selectedElement: { classPropertyName: "selectedElement", publicName: "selectedElement", isSignal: true, isRequired: false, transformFunction: null }, formatPainterActive: { classPropertyName: "formatPainterActive", publicName: "formatPainterActive", isSignal: true, isRequired: false, transformFunction: null }, canActivateFormatPainter: { classPropertyName: "canActivateFormatPainter", publicName: "canActivateFormatPainter", isSignal: true, isRequired: false, transformFunction: null }, exporting: { classPropertyName: "exporting", publicName: "exporting", isSignal: true, isRequired: false, transformFunction: null }, hasMacros: { classPropertyName: "hasMacros", publicName: "hasMacros", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectTab: "selectTab", find: "find", share: "share", openFile: "openFile", openRecentFile: "openRecentFile", createPresentation: "createPresentation", save: "save", savePpsx: "savePpsx", savePptm: "savePptm", packageForSharing: "packageForSharing", signatures: "signatures", info: "info", print: "print", toggleFormatPainter: "toggleFormatPainter", exportPng: "exportPng", exportPdf: "exportPdf", exportGif: "exportGif", exportVideo: "exportVideo", exportJson: "exportJson", copySlideAsImage: "copySlideAsImage", replace: "replace", openSmartArtDialog: "openSmartArtDialog", openEquationDialog: "openEquationDialog", openTemplateGallery: "openTemplateGallery", link: "link", openPassword: "openPassword", openFontEmbedding: "openFontEmbedding", openVersionHistory: "openVersionHistory", openSettings: "openSettings" }, host: { classAttribute: "contents" }, ngImport: i0, template: `
116562
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: RibbonContentComponent, isStandalone: true, selector: "pptx-ribbon-content", inputs: { activeTab: { classPropertyName: "activeTab", publicName: "activeTab", isSignal: true, isRequired: true, transformFunction: null }, slideIndex: { classPropertyName: "slideIndex", publicName: "slideIndex", isSignal: true, isRequired: false, transformFunction: null }, slideCount: { classPropertyName: "slideCount", publicName: "slideCount", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, selectedElement: { classPropertyName: "selectedElement", publicName: "selectedElement", isSignal: true, isRequired: false, transformFunction: null }, formatPainterActive: { classPropertyName: "formatPainterActive", publicName: "formatPainterActive", isSignal: true, isRequired: false, transformFunction: null }, canActivateFormatPainter: { classPropertyName: "canActivateFormatPainter", publicName: "canActivateFormatPainter", isSignal: true, isRequired: false, transformFunction: null }, exporting: { classPropertyName: "exporting", publicName: "exporting", isSignal: true, isRequired: false, transformFunction: null }, hasMacros: { classPropertyName: "hasMacros", publicName: "hasMacros", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectTab: "selectTab", find: "find", share: "share", openFile: "openFile", openRecentFile: "openRecentFile", createPresentation: "createPresentation", save: "save", savePpsx: "savePpsx", savePptm: "savePptm", signatures: "signatures", info: "info", print: "print", toggleFormatPainter: "toggleFormatPainter", exportPng: "exportPng", exportPdf: "exportPdf", exportGif: "exportGif", exportVideo: "exportVideo", exportJson: "exportJson", copySlideAsImage: "copySlideAsImage", replace: "replace", openSmartArtDialog: "openSmartArtDialog", openEquationDialog: "openEquationDialog", openTemplateGallery: "openTemplateGallery", link: "link", openPassword: "openPassword", openFontEmbedding: "openFontEmbedding", openVersionHistory: "openVersionHistory", openSettings: "openSettings" }, host: { classAttribute: "contents" }, ngImport: i0, template: `
115782
116563
  @switch (activeTab()) {
115783
116564
  @case ('file') {
115784
116565
  <pptx-ribbon-file-section
@@ -115793,7 +116574,6 @@ class RibbonContentComponent {
115793
116574
  (save)="save.emit()"
115794
116575
  (savePpsx)="savePpsx.emit()"
115795
116576
  (savePptm)="savePptm.emit()"
115796
- (packageForSharing)="packageForSharing.emit()"
115797
116577
  (exportPng)="exportPng.emit()"
115798
116578
  (exportPdf)="exportPdf.emit()"
115799
116579
  (exportGif)="exportGif.emit()"
@@ -115878,7 +116658,7 @@ class RibbonContentComponent {
115878
116658
  />
115879
116659
  }
115880
116660
  }
115881
- `, isInline: true, dependencies: [{ kind: "component", type: RibbonFileSectionComponent, selector: "pptx-ribbon-file-section", inputs: ["fileName", "slideCount", "exporting", "hasMacros", "hiddenActions", "accountAuth"], outputs: ["close", "createPresentation", "openFile", "openRecentFile", "save", "savePpsx", "savePptm", "packageForSharing", "exportPng", "exportPdf", "exportGif", "exportVideo", "exportJson", "copySlideAsImage", "print", "info", "signatures", "replace", "openPassword", "openFontEmbedding", "openVersionHistory", "share", "options"] }, { kind: "component", type: RibbonHomeSectionComponent, selector: "pptx-ribbon-home-section", inputs: ["slideIndex", "selectedElement", "canEdit", "formatPainterActive", "canActivateFormatPainter"], outputs: ["toggleFormatPainter", "findReplace", "openTemplateGallery", "applyLayout", "resetSlide"] }, { kind: "component", type: RibbonInsertSectionComponent, selector: "pptx-ribbon-insert-section", inputs: ["slideIndex", "newChartType", "newShapeType"], outputs: ["openSmartArtDialog", "openEquationDialog", "openHyperlink", "chartTypeChange", "shapeTypeChange"] }, { kind: "component", type: RibbonFontControlsComponent, selector: "pptx-ribbon-font-controls", inputs: ["slideIndex", "selectedElement"] }, { kind: "component", type: RibbonParagraphControlsComponent, selector: "pptx-ribbon-paragraph-controls", inputs: ["slideIndex", "selectedElement"] }, { kind: "component", type: RibbonArrangeSectionComponent, selector: "pptx-ribbon-arrange-section", inputs: ["slideIndex", "selectedElement", "canEdit", "formatPainterActive", "canActivateFormatPainter"], outputs: ["toggleFormatPainter"] }, { kind: "component", type: RibbonDrawingGroupComponent, selector: "pptx-ribbon-drawing-group", inputs: ["canEdit", "slideIndex", "selectedElement"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
116661
+ `, isInline: true, dependencies: [{ kind: "component", type: RibbonFileSectionComponent, selector: "pptx-ribbon-file-section", inputs: ["fileName", "slideCount", "exporting", "hasMacros", "hiddenActions", "recentPresentationsCount", "accountAuth"], outputs: ["close", "createPresentation", "openFile", "openRecentFile", "save", "savePpsx", "savePptm", "exportPng", "exportPdf", "exportGif", "exportVideo", "exportJson", "copySlideAsImage", "print", "info", "signatures", "replace", "openPassword", "openFontEmbedding", "openVersionHistory", "share", "options"] }, { kind: "component", type: RibbonHomeSectionComponent, selector: "pptx-ribbon-home-section", inputs: ["slideIndex", "selectedElement", "canEdit", "formatPainterActive", "canActivateFormatPainter"], outputs: ["toggleFormatPainter", "findReplace", "openTemplateGallery", "applyLayout", "resetSlide"] }, { kind: "component", type: RibbonInsertSectionComponent, selector: "pptx-ribbon-insert-section", inputs: ["slideIndex", "newChartType", "newShapeType"], outputs: ["openSmartArtDialog", "openEquationDialog", "openHyperlink", "chartTypeChange", "shapeTypeChange"] }, { kind: "component", type: RibbonFontControlsComponent, selector: "pptx-ribbon-font-controls", inputs: ["slideIndex", "selectedElement"] }, { kind: "component", type: RibbonParagraphControlsComponent, selector: "pptx-ribbon-paragraph-controls", inputs: ["slideIndex", "selectedElement"] }, { kind: "component", type: RibbonArrangeSectionComponent, selector: "pptx-ribbon-arrange-section", inputs: ["slideIndex", "selectedElement", "canEdit", "formatPainterActive", "canActivateFormatPainter"], outputs: ["toggleFormatPainter"] }, { kind: "component", type: RibbonDrawingGroupComponent, selector: "pptx-ribbon-drawing-group", inputs: ["canEdit", "slideIndex", "selectedElement"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
115882
116662
  }
115883
116663
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: RibbonContentComponent, decorators: [{
115884
116664
  type: Component,
@@ -115911,7 +116691,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
115911
116691
  (save)="save.emit()"
115912
116692
  (savePpsx)="savePpsx.emit()"
115913
116693
  (savePptm)="savePptm.emit()"
115914
- (packageForSharing)="packageForSharing.emit()"
115915
116694
  (exportPng)="exportPng.emit()"
115916
116695
  (exportPdf)="exportPdf.emit()"
115917
116696
  (exportGif)="exportGif.emit()"
@@ -115998,7 +116777,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
115998
116777
  }
115999
116778
  `,
116000
116779
  }]
116001
- }], propDecorators: { activeTab: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeTab", required: true }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }], slideCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideCount", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], selectedElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElement", required: false }] }], formatPainterActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatPainterActive", required: false }] }], canActivateFormatPainter: [{ type: i0.Input, args: [{ isSignal: true, alias: "canActivateFormatPainter", required: false }] }], exporting: [{ type: i0.Input, args: [{ isSignal: true, alias: "exporting", required: false }] }], hasMacros: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMacros", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], selectTab: [{ type: i0.Output, args: ["selectTab"] }], find: [{ type: i0.Output, args: ["find"] }], share: [{ type: i0.Output, args: ["share"] }], openFile: [{ type: i0.Output, args: ["openFile"] }], openRecentFile: [{ type: i0.Output, args: ["openRecentFile"] }], createPresentation: [{ type: i0.Output, args: ["createPresentation"] }], save: [{ type: i0.Output, args: ["save"] }], savePpsx: [{ type: i0.Output, args: ["savePpsx"] }], savePptm: [{ type: i0.Output, args: ["savePptm"] }], packageForSharing: [{ type: i0.Output, args: ["packageForSharing"] }], signatures: [{ type: i0.Output, args: ["signatures"] }], info: [{ type: i0.Output, args: ["info"] }], print: [{ type: i0.Output, args: ["print"] }], toggleFormatPainter: [{ type: i0.Output, args: ["toggleFormatPainter"] }], exportPng: [{ type: i0.Output, args: ["exportPng"] }], exportPdf: [{ type: i0.Output, args: ["exportPdf"] }], exportGif: [{ type: i0.Output, args: ["exportGif"] }], exportVideo: [{ type: i0.Output, args: ["exportVideo"] }], exportJson: [{ type: i0.Output, args: ["exportJson"] }], copySlideAsImage: [{ type: i0.Output, args: ["copySlideAsImage"] }], replace: [{ type: i0.Output, args: ["replace"] }], openSmartArtDialog: [{ type: i0.Output, args: ["openSmartArtDialog"] }], openEquationDialog: [{ type: i0.Output, args: ["openEquationDialog"] }], openTemplateGallery: [{ type: i0.Output, args: ["openTemplateGallery"] }], link: [{ type: i0.Output, args: ["link"] }], openPassword: [{ type: i0.Output, args: ["openPassword"] }], openFontEmbedding: [{ type: i0.Output, args: ["openFontEmbedding"] }], openVersionHistory: [{ type: i0.Output, args: ["openVersionHistory"] }], openSettings: [{ type: i0.Output, args: ["openSettings"] }] } });
116780
+ }], propDecorators: { activeTab: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeTab", required: true }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }], slideCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideCount", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], selectedElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElement", required: false }] }], formatPainterActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatPainterActive", required: false }] }], canActivateFormatPainter: [{ type: i0.Input, args: [{ isSignal: true, alias: "canActivateFormatPainter", required: false }] }], exporting: [{ type: i0.Input, args: [{ isSignal: true, alias: "exporting", required: false }] }], hasMacros: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMacros", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], selectTab: [{ type: i0.Output, args: ["selectTab"] }], find: [{ type: i0.Output, args: ["find"] }], share: [{ type: i0.Output, args: ["share"] }], openFile: [{ type: i0.Output, args: ["openFile"] }], openRecentFile: [{ type: i0.Output, args: ["openRecentFile"] }], createPresentation: [{ type: i0.Output, args: ["createPresentation"] }], save: [{ type: i0.Output, args: ["save"] }], savePpsx: [{ type: i0.Output, args: ["savePpsx"] }], savePptm: [{ type: i0.Output, args: ["savePptm"] }], signatures: [{ type: i0.Output, args: ["signatures"] }], info: [{ type: i0.Output, args: ["info"] }], print: [{ type: i0.Output, args: ["print"] }], toggleFormatPainter: [{ type: i0.Output, args: ["toggleFormatPainter"] }], exportPng: [{ type: i0.Output, args: ["exportPng"] }], exportPdf: [{ type: i0.Output, args: ["exportPdf"] }], exportGif: [{ type: i0.Output, args: ["exportGif"] }], exportVideo: [{ type: i0.Output, args: ["exportVideo"] }], exportJson: [{ type: i0.Output, args: ["exportJson"] }], copySlideAsImage: [{ type: i0.Output, args: ["copySlideAsImage"] }], replace: [{ type: i0.Output, args: ["replace"] }], openSmartArtDialog: [{ type: i0.Output, args: ["openSmartArtDialog"] }], openEquationDialog: [{ type: i0.Output, args: ["openEquationDialog"] }], openTemplateGallery: [{ type: i0.Output, args: ["openTemplateGallery"] }], link: [{ type: i0.Output, args: ["link"] }], openPassword: [{ type: i0.Output, args: ["openPassword"] }], openFontEmbedding: [{ type: i0.Output, args: ["openFontEmbedding"] }], openVersionHistory: [{ type: i0.Output, args: ["openVersionHistory"] }], openSettings: [{ type: i0.Output, args: ["openSettings"] }] } });
116002
116781
 
116003
116782
  /**
116004
116783
  * ribbon-primary-row.component.ts: the quick-access (top) row of the editor
@@ -116587,6 +117366,14 @@ class RibbonTabListComponent {
116587
117366
  this.tra = TAB_ROW_ACTION_CLASSES;
116588
117367
  this.visibleTabs = computed(() => filterVisibleTabs(TOOLBAR_TABS, this.hiddenActions()), /* @ts-ignore */
116589
117368
  ...(ngDevMode ? [{ debugName: "visibleTabs" }] : /* istanbul ignore next */ []));
117369
+ this.translate = inject(TranslateService);
117370
+ /** Optional so the tab strip renders outside a full viewer host too. */
117371
+ this.viewerOpts = inject(ViewerOptionsService, { optional: true });
117372
+ }
117373
+ /** ScreenTip-styled tab tooltip (null suppresses the title attribute). */
117374
+ tabTip(labelKey) {
117375
+ const label = this.translate.instant(labelKey);
117376
+ return this.viewerOpts ? (this.viewerOpts.screenTip(label) ?? null) : label;
116590
117377
  }
116591
117378
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: RibbonTabListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
116592
117379
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: RibbonTabListComponent, isStandalone: true, selector: "pptx-ribbon-tab-list", inputs: { activeTab: { classPropertyName: "activeTab", publicName: "activeTab", isSignal: true, isRequired: true, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, collabConnected: { classPropertyName: "collabConnected", publicName: "collabConnected", isSignal: true, isRequired: false, transformFunction: null }, connectedCount: { classPropertyName: "connectedCount", publicName: "connectedCount", isSignal: true, isRequired: false, transformFunction: null }, ribbonExpanded: { classPropertyName: "ribbonExpanded", publicName: "ribbonExpanded", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectTab: "selectTab", record: "record", share: "share", toggleRibbonExpanded: "toggleRibbonExpanded" }, ngImport: i0, template: `
@@ -116600,6 +117387,7 @@ class RibbonTabListComponent {
116600
117387
  type="button"
116601
117388
  role="tab"
116602
117389
  [attr.aria-selected]="activeTab() === t.id"
117390
+ [title]="tabTip(t.labelKey)"
116603
117391
  (click)="selectTab.emit(t.id)"
116604
117392
  class="relative whitespace-nowrap px-3.5 py-2 text-[12px] font-medium transition-colors"
116605
117393
  [ngClass]="
@@ -116704,6 +117492,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
116704
117492
  type="button"
116705
117493
  role="tab"
116706
117494
  [attr.aria-selected]="activeTab() === t.id"
117495
+ [title]="tabTip(t.labelKey)"
116707
117496
  (click)="selectTab.emit(t.id)"
116708
117497
  class="relative whitespace-nowrap px-3.5 py-2 text-[12px] font-medium transition-colors"
116709
117498
  [ngClass]="
@@ -116909,7 +117698,6 @@ class RibbonComponent {
116909
117698
  this.save = output();
116910
117699
  this.savePpsx = output();
116911
117700
  this.savePptm = output();
116912
- this.packageForSharing = output();
116913
117701
  /** Emitted when the user toggles the slides panel from the top bar. */
116914
117702
  this.toggleSidebar = output();
116915
117703
  /** Emitted when the user clicks the AI assistant Sparkles toggle. */
@@ -117016,7 +117804,7 @@ class RibbonComponent {
117016
117804
  this.spellCheckChange.emit(enabled);
117017
117805
  }
117018
117806
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: RibbonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
117019
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.3", type: RibbonComponent, isStandalone: true, selector: "pptx-ribbon", inputs: { slideIndex: { classPropertyName: "slideIndex", publicName: "slideIndex", isSignal: true, isRequired: false, transformFunction: null }, slideCount: { classPropertyName: "slideCount", publicName: "slideCount", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, selectedElement: { classPropertyName: "selectedElement", publicName: "selectedElement", isSignal: true, isRequired: false, transformFunction: null }, zoomPercent: { classPropertyName: "zoomPercent", publicName: "zoomPercent", isSignal: true, isRequired: false, transformFunction: null }, formatPainterActive: { classPropertyName: "formatPainterActive", publicName: "formatPainterActive", isSignal: true, isRequired: false, transformFunction: null }, canActivateFormatPainter: { classPropertyName: "canActivateFormatPainter", publicName: "canActivateFormatPainter", isSignal: true, isRequired: false, transformFunction: null }, exporting: { classPropertyName: "exporting", publicName: "exporting", isSignal: true, isRequired: false, transformFunction: null }, hasMacros: { classPropertyName: "hasMacros", publicName: "hasMacros", isSignal: true, isRequired: false, transformFunction: null }, showGrid: { classPropertyName: "showGrid", publicName: "showGrid", isSignal: true, isRequired: false, transformFunction: null }, showRulers: { classPropertyName: "showRulers", publicName: "showRulers", isSignal: true, isRequired: false, transformFunction: null }, showGuides: { classPropertyName: "showGuides", publicName: "showGuides", isSignal: true, isRequired: false, transformFunction: null }, snapToGrid: { classPropertyName: "snapToGrid", publicName: "snapToGrid", isSignal: true, isRequired: false, transformFunction: null }, snapToShape: { classPropertyName: "snapToShape", publicName: "snapToShape", isSignal: true, isRequired: false, transformFunction: null }, eyedropperActive: { classPropertyName: "eyedropperActive", publicName: "eyedropperActive", isSignal: true, isRequired: false, transformFunction: null }, themeGalleryOpen: { classPropertyName: "themeGalleryOpen", publicName: "themeGalleryOpen", isSignal: true, isRequired: false, transformFunction: null }, sidebarCollapsed: { classPropertyName: "sidebarCollapsed", publicName: "sidebarCollapsed", isSignal: true, isRequired: false, transformFunction: null }, inspectorOpen: { classPropertyName: "inspectorOpen", publicName: "inspectorOpen", isSignal: true, isRequired: false, transformFunction: null }, commentsOpen: { classPropertyName: "commentsOpen", publicName: "commentsOpen", isSignal: true, isRequired: false, transformFunction: null }, commentCount: { classPropertyName: "commentCount", publicName: "commentCount", isSignal: true, isRequired: false, transformFunction: null }, findOpen: { classPropertyName: "findOpen", publicName: "findOpen", isSignal: true, isRequired: false, transformFunction: null }, collabConnected: { classPropertyName: "collabConnected", publicName: "collabConnected", isSignal: true, isRequired: false, transformFunction: null }, connectedCount: { classPropertyName: "connectedCount", publicName: "connectedCount", isSignal: true, isRequired: false, transformFunction: null }, spellCheckEnabled: { classPropertyName: "spellCheckEnabled", publicName: "spellCheckEnabled", isSignal: true, isRequired: false, transformFunction: null }, showSubtitles: { classPropertyName: "showSubtitles", publicName: "showSubtitles", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, aiEnabled: { classPropertyName: "aiEnabled", publicName: "aiEnabled", isSignal: true, isRequired: false, transformFunction: null }, aiPanelOpen: { classPropertyName: "aiPanelOpen", publicName: "aiPanelOpen", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null }, activeSlideHidden: { classPropertyName: "activeSlideHidden", publicName: "activeSlideHidden", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { prev: "prev", next: "next", zoomIn: "zoomIn", zoomOut: "zoomOut", zoomReset: "zoomReset", find: "find", present: "present", presenter: "presenter", record: "record", presentFromBeginning: "presentFromBeginning", rehearseTimings: "rehearseTimings", toggleSubtitles: "toggleSubtitles", openSubtitleSettings: "openSubtitleSettings", recordFromBeginning: "recordFromBeginning", recordFromCurrent: "recordFromCurrent", spellCheckChange: "spellCheckChange", share: "share", broadcast: "broadcast", openFile: "openFile", openRecentFile: "openRecentFile", createPresentation: "createPresentation", save: "save", savePpsx: "savePpsx", savePptm: "savePptm", packageForSharing: "packageForSharing", toggleSidebar: "toggleSidebar", toggleAiPanel: "toggleAiPanel", signatures: "signatures", info: "info", print: "print", comments: "comments", a11y: "a11y", shortcuts: "shortcuts", versionHistory: "versionHistory", passwordProtection: "passwordProtection", fontEmbedding: "fontEmbedding", link: "link", openSorter: "openSorter", openReadingView: "openReadingView", openOutlineView: "openOutlineView", openMasterView: "openMasterView", toggleNotes: "toggleNotes", toggleFormatPainter: "toggleFormatPainter", exportPng: "exportPng", exportPdf: "exportPdf", exportGif: "exportGif", exportVideo: "exportVideo", exportJson: "exportJson", copySlideAsImage: "copySlideAsImage", replace: "replace", toggleInspector: "toggleInspector", drawToolChange: "drawToolChange", toggleThemeGallery: "toggleThemeGallery", editTheme: "editTheme", openSlideSize: "openSlideSize", toggleGrid: "toggleGrid", toggleRulers: "toggleRulers", toggleGuides: "toggleGuides", toggleSelectionPane: "toggleSelectionPane", openCustomShows: "openCustomShows", toggleSnapToGrid: "toggleSnapToGrid", toggleSnapToShape: "toggleSnapToShape", addGuide: "addGuide", zoomToFit: "zoomToFit", toggleEyedropper: "toggleEyedropper", openSmartArtDialog: "openSmartArtDialog", openTemplateGallery: "openTemplateGallery", openEquationDialog: "openEquationDialog", openSetUpSlideShow: "openSetUpSlideShow", toggleHideSlide: "toggleHideSlide", openCompare: "openCompare", openPassword: "openPassword", openFontEmbedding: "openFontEmbedding", openVersionHistory: "openVersionHistory", openShortcuts: "openShortcuts", openSettings: "openSettings" }, ngImport: i0, template: `
117807
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.3", type: RibbonComponent, isStandalone: true, selector: "pptx-ribbon", inputs: { slideIndex: { classPropertyName: "slideIndex", publicName: "slideIndex", isSignal: true, isRequired: false, transformFunction: null }, slideCount: { classPropertyName: "slideCount", publicName: "slideCount", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, selectedElement: { classPropertyName: "selectedElement", publicName: "selectedElement", isSignal: true, isRequired: false, transformFunction: null }, zoomPercent: { classPropertyName: "zoomPercent", publicName: "zoomPercent", isSignal: true, isRequired: false, transformFunction: null }, formatPainterActive: { classPropertyName: "formatPainterActive", publicName: "formatPainterActive", isSignal: true, isRequired: false, transformFunction: null }, canActivateFormatPainter: { classPropertyName: "canActivateFormatPainter", publicName: "canActivateFormatPainter", isSignal: true, isRequired: false, transformFunction: null }, exporting: { classPropertyName: "exporting", publicName: "exporting", isSignal: true, isRequired: false, transformFunction: null }, hasMacros: { classPropertyName: "hasMacros", publicName: "hasMacros", isSignal: true, isRequired: false, transformFunction: null }, showGrid: { classPropertyName: "showGrid", publicName: "showGrid", isSignal: true, isRequired: false, transformFunction: null }, showRulers: { classPropertyName: "showRulers", publicName: "showRulers", isSignal: true, isRequired: false, transformFunction: null }, showGuides: { classPropertyName: "showGuides", publicName: "showGuides", isSignal: true, isRequired: false, transformFunction: null }, snapToGrid: { classPropertyName: "snapToGrid", publicName: "snapToGrid", isSignal: true, isRequired: false, transformFunction: null }, snapToShape: { classPropertyName: "snapToShape", publicName: "snapToShape", isSignal: true, isRequired: false, transformFunction: null }, eyedropperActive: { classPropertyName: "eyedropperActive", publicName: "eyedropperActive", isSignal: true, isRequired: false, transformFunction: null }, themeGalleryOpen: { classPropertyName: "themeGalleryOpen", publicName: "themeGalleryOpen", isSignal: true, isRequired: false, transformFunction: null }, sidebarCollapsed: { classPropertyName: "sidebarCollapsed", publicName: "sidebarCollapsed", isSignal: true, isRequired: false, transformFunction: null }, inspectorOpen: { classPropertyName: "inspectorOpen", publicName: "inspectorOpen", isSignal: true, isRequired: false, transformFunction: null }, commentsOpen: { classPropertyName: "commentsOpen", publicName: "commentsOpen", isSignal: true, isRequired: false, transformFunction: null }, commentCount: { classPropertyName: "commentCount", publicName: "commentCount", isSignal: true, isRequired: false, transformFunction: null }, findOpen: { classPropertyName: "findOpen", publicName: "findOpen", isSignal: true, isRequired: false, transformFunction: null }, collabConnected: { classPropertyName: "collabConnected", publicName: "collabConnected", isSignal: true, isRequired: false, transformFunction: null }, connectedCount: { classPropertyName: "connectedCount", publicName: "connectedCount", isSignal: true, isRequired: false, transformFunction: null }, spellCheckEnabled: { classPropertyName: "spellCheckEnabled", publicName: "spellCheckEnabled", isSignal: true, isRequired: false, transformFunction: null }, showSubtitles: { classPropertyName: "showSubtitles", publicName: "showSubtitles", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, aiEnabled: { classPropertyName: "aiEnabled", publicName: "aiEnabled", isSignal: true, isRequired: false, transformFunction: null }, aiPanelOpen: { classPropertyName: "aiPanelOpen", publicName: "aiPanelOpen", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null }, activeSlideHidden: { classPropertyName: "activeSlideHidden", publicName: "activeSlideHidden", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { prev: "prev", next: "next", zoomIn: "zoomIn", zoomOut: "zoomOut", zoomReset: "zoomReset", find: "find", present: "present", presenter: "presenter", record: "record", presentFromBeginning: "presentFromBeginning", rehearseTimings: "rehearseTimings", toggleSubtitles: "toggleSubtitles", openSubtitleSettings: "openSubtitleSettings", recordFromBeginning: "recordFromBeginning", recordFromCurrent: "recordFromCurrent", spellCheckChange: "spellCheckChange", share: "share", broadcast: "broadcast", openFile: "openFile", openRecentFile: "openRecentFile", createPresentation: "createPresentation", save: "save", savePpsx: "savePpsx", savePptm: "savePptm", toggleSidebar: "toggleSidebar", toggleAiPanel: "toggleAiPanel", signatures: "signatures", info: "info", print: "print", comments: "comments", a11y: "a11y", shortcuts: "shortcuts", versionHistory: "versionHistory", passwordProtection: "passwordProtection", fontEmbedding: "fontEmbedding", link: "link", openSorter: "openSorter", openReadingView: "openReadingView", openOutlineView: "openOutlineView", openMasterView: "openMasterView", toggleNotes: "toggleNotes", toggleFormatPainter: "toggleFormatPainter", exportPng: "exportPng", exportPdf: "exportPdf", exportGif: "exportGif", exportVideo: "exportVideo", exportJson: "exportJson", copySlideAsImage: "copySlideAsImage", replace: "replace", toggleInspector: "toggleInspector", drawToolChange: "drawToolChange", toggleThemeGallery: "toggleThemeGallery", editTheme: "editTheme", openSlideSize: "openSlideSize", toggleGrid: "toggleGrid", toggleRulers: "toggleRulers", toggleGuides: "toggleGuides", toggleSelectionPane: "toggleSelectionPane", openCustomShows: "openCustomShows", toggleSnapToGrid: "toggleSnapToGrid", toggleSnapToShape: "toggleSnapToShape", addGuide: "addGuide", zoomToFit: "zoomToFit", toggleEyedropper: "toggleEyedropper", openSmartArtDialog: "openSmartArtDialog", openTemplateGallery: "openTemplateGallery", openEquationDialog: "openEquationDialog", openSetUpSlideShow: "openSetUpSlideShow", toggleHideSlide: "toggleHideSlide", openCompare: "openCompare", openPassword: "openPassword", openFontEmbedding: "openFontEmbedding", openVersionHistory: "openVersionHistory", openShortcuts: "openShortcuts", openSettings: "openSettings" }, ngImport: i0, template: `
117020
117808
  <div
117021
117809
  role="toolbar"
117022
117810
  [attr.aria-label]="'pptx.toolbar.presentationToolbarAria' | translate"
@@ -117072,7 +117860,7 @@ class RibbonComponent {
117072
117860
  />
117073
117861
 
117074
117862
  <div
117075
- class="flex min-h-[82px] flex-nowrap items-stretch gap-0 overflow-x-auto px-1 py-0.5 [&>*]:shrink-0"
117863
+ class="flex min-h-[82px] flex-nowrap items-center gap-0 overflow-x-auto px-1 py-0.5 [&>*]:shrink-0"
117076
117864
  [style.display]="ribbonExpanded() ? null : 'none'"
117077
117865
  >
117078
117866
  <pptx-ribbon-content
@@ -117096,7 +117884,6 @@ class RibbonComponent {
117096
117884
  (save)="save.emit()"
117097
117885
  (savePpsx)="savePpsx.emit()"
117098
117886
  (savePptm)="savePptm.emit()"
117099
- (packageForSharing)="packageForSharing.emit()"
117100
117887
  (signatures)="signatures.emit()"
117101
117888
  (info)="info.emit()"
117102
117889
  (print)="print.emit()"
@@ -117177,7 +117964,7 @@ class RibbonComponent {
117177
117964
  />
117178
117965
  </div>
117179
117966
  </div>
117180
- `, isInline: true, dependencies: [{ kind: "component", type: RibbonPrimaryRowComponent, selector: "pptx-ribbon-primary-row", inputs: ["slideCount", "sidebarCollapsed", "inspectorOpen", "commentsOpen", "commentCount", "hiddenActions", "aiEnabled", "aiPanelOpen"], outputs: ["toggleSidebar", "toggleAiPanel", "toggleComments", "present", "presenter", "broadcast", "openCustomShows", "toggleInspector", "openSettings", "exportPng", "exportPdf", "exportGif", "exportVideo", "print", "info", "a11y", "save", "savePpsx", "savePptm", "copySlideAsImage", "shortcuts", "versionHistory", "passwordProtection", "fontEmbedding", "digitalSignatures"] }, { kind: "component", type: RibbonTabListComponent, selector: "pptx-ribbon-tab-list", inputs: ["activeTab", "canEdit", "collabConnected", "connectedCount", "ribbonExpanded", "hiddenActions"], outputs: ["selectTab", "record", "share", "toggleRibbonExpanded"] }, { kind: "component", type: RibbonContentComponent, selector: "pptx-ribbon-content", inputs: ["activeTab", "slideIndex", "slideCount", "canEdit", "selectedElement", "formatPainterActive", "canActivateFormatPainter", "exporting", "hasMacros", "hiddenActions", "accountAuth"], outputs: ["selectTab", "find", "share", "openFile", "openRecentFile", "createPresentation", "save", "savePpsx", "savePptm", "packageForSharing", "signatures", "info", "print", "toggleFormatPainter", "exportPng", "exportPdf", "exportGif", "exportVideo", "exportJson", "copySlideAsImage", "replace", "openSmartArtDialog", "openEquationDialog", "openTemplateGallery", "link", "openPassword", "openFontEmbedding", "openVersionHistory", "openSettings"] }, { kind: "component", type: RibbonContentSecondaryComponent, selector: "pptx-ribbon-content-secondary", inputs: ["activeTab", "slideIndex", "slideCount", "canEdit", "selectedElement", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "eyedropperActive", "themeGalleryOpen", "spellCheckEnabled", "showSubtitles", "activeSlideHidden", "hiddenActions"], outputs: ["present", "presenter", "record", "presentFromBeginning", "rehearseTimings", "toggleSubtitles", "openSubtitleSettings", "recordFromBeginning", "recordFromCurrent", "spellCheckChange", "broadcast", "print", "comments", "a11y", "link", "openSorter", "openReadingView", "openOutlineView", "openMasterView", "toggleNotes", "toggleInspector", "drawToolChange", "toggleThemeGallery", "editTheme", "openSlideSize", "toggleGrid", "toggleRulers", "toggleGuides", "toggleSelectionPane", "openCustomShows", "toggleSnapToGrid", "toggleSnapToShape", "addGuide", "zoomToFit", "toggleEyedropper", "openSetUpSlideShow", "toggleHideSlide", "openCompare", "openShortcuts", "openSettings"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
117967
+ `, isInline: true, dependencies: [{ kind: "component", type: RibbonPrimaryRowComponent, selector: "pptx-ribbon-primary-row", inputs: ["slideCount", "sidebarCollapsed", "inspectorOpen", "commentsOpen", "commentCount", "hiddenActions", "aiEnabled", "aiPanelOpen"], outputs: ["toggleSidebar", "toggleAiPanel", "toggleComments", "present", "presenter", "broadcast", "openCustomShows", "toggleInspector", "openSettings", "exportPng", "exportPdf", "exportGif", "exportVideo", "print", "info", "a11y", "save", "savePpsx", "savePptm", "copySlideAsImage", "shortcuts", "versionHistory", "passwordProtection", "fontEmbedding", "digitalSignatures"] }, { kind: "component", type: RibbonTabListComponent, selector: "pptx-ribbon-tab-list", inputs: ["activeTab", "canEdit", "collabConnected", "connectedCount", "ribbonExpanded", "hiddenActions"], outputs: ["selectTab", "record", "share", "toggleRibbonExpanded"] }, { kind: "component", type: RibbonContentComponent, selector: "pptx-ribbon-content", inputs: ["activeTab", "slideIndex", "slideCount", "canEdit", "selectedElement", "formatPainterActive", "canActivateFormatPainter", "exporting", "hasMacros", "hiddenActions", "accountAuth"], outputs: ["selectTab", "find", "share", "openFile", "openRecentFile", "createPresentation", "save", "savePpsx", "savePptm", "signatures", "info", "print", "toggleFormatPainter", "exportPng", "exportPdf", "exportGif", "exportVideo", "exportJson", "copySlideAsImage", "replace", "openSmartArtDialog", "openEquationDialog", "openTemplateGallery", "link", "openPassword", "openFontEmbedding", "openVersionHistory", "openSettings"] }, { kind: "component", type: RibbonContentSecondaryComponent, selector: "pptx-ribbon-content-secondary", inputs: ["activeTab", "slideIndex", "slideCount", "canEdit", "selectedElement", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "eyedropperActive", "themeGalleryOpen", "spellCheckEnabled", "showSubtitles", "activeSlideHidden", "hiddenActions"], outputs: ["present", "presenter", "record", "presentFromBeginning", "rehearseTimings", "toggleSubtitles", "openSubtitleSettings", "recordFromBeginning", "recordFromCurrent", "spellCheckChange", "broadcast", "print", "comments", "a11y", "link", "openSorter", "openReadingView", "openOutlineView", "openMasterView", "toggleNotes", "toggleInspector", "drawToolChange", "toggleThemeGallery", "editTheme", "openSlideSize", "toggleGrid", "toggleRulers", "toggleGuides", "toggleSelectionPane", "openCustomShows", "toggleSnapToGrid", "toggleSnapToShape", "addGuide", "zoomToFit", "toggleEyedropper", "openSetUpSlideShow", "toggleHideSlide", "openCompare", "openShortcuts", "openSettings"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
117181
117968
  }
117182
117969
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: RibbonComponent, decorators: [{
117183
117970
  type: Component,
@@ -117248,7 +118035,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
117248
118035
  />
117249
118036
 
117250
118037
  <div
117251
- class="flex min-h-[82px] flex-nowrap items-stretch gap-0 overflow-x-auto px-1 py-0.5 [&>*]:shrink-0"
118038
+ class="flex min-h-[82px] flex-nowrap items-center gap-0 overflow-x-auto px-1 py-0.5 [&>*]:shrink-0"
117252
118039
  [style.display]="ribbonExpanded() ? null : 'none'"
117253
118040
  >
117254
118041
  <pptx-ribbon-content
@@ -117272,7 +118059,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
117272
118059
  (save)="save.emit()"
117273
118060
  (savePpsx)="savePpsx.emit()"
117274
118061
  (savePptm)="savePptm.emit()"
117275
- (packageForSharing)="packageForSharing.emit()"
117276
118062
  (signatures)="signatures.emit()"
117277
118063
  (info)="info.emit()"
117278
118064
  (print)="print.emit()"
@@ -117355,7 +118141,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
117355
118141
  </div>
117356
118142
  `,
117357
118143
  }]
117358
- }], propDecorators: { slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }], slideCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideCount", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], selectedElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElement", required: false }] }], zoomPercent: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomPercent", required: false }] }], formatPainterActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatPainterActive", required: false }] }], canActivateFormatPainter: [{ type: i0.Input, args: [{ isSignal: true, alias: "canActivateFormatPainter", required: false }] }], exporting: [{ type: i0.Input, args: [{ isSignal: true, alias: "exporting", required: false }] }], hasMacros: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMacros", required: false }] }], showGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGrid", required: false }] }], showRulers: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRulers", required: false }] }], showGuides: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGuides", required: false }] }], snapToGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToGrid", required: false }] }], snapToShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToShape", required: false }] }], eyedropperActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "eyedropperActive", required: false }] }], themeGalleryOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "themeGalleryOpen", required: false }] }], sidebarCollapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarCollapsed", required: false }] }], inspectorOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "inspectorOpen", required: false }] }], commentsOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "commentsOpen", required: false }] }], commentCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "commentCount", required: false }] }], findOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "findOpen", required: false }] }], collabConnected: [{ type: i0.Input, args: [{ isSignal: true, alias: "collabConnected", required: false }] }], connectedCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "connectedCount", required: false }] }], spellCheckEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "spellCheckEnabled", required: false }] }], showSubtitles: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSubtitles", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], aiEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiEnabled", required: false }] }], aiPanelOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiPanelOpen", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], prev: [{ type: i0.Output, args: ["prev"] }], next: [{ type: i0.Output, args: ["next"] }], zoomIn: [{ type: i0.Output, args: ["zoomIn"] }], zoomOut: [{ type: i0.Output, args: ["zoomOut"] }], zoomReset: [{ type: i0.Output, args: ["zoomReset"] }], find: [{ type: i0.Output, args: ["find"] }], present: [{ type: i0.Output, args: ["present"] }], presenter: [{ type: i0.Output, args: ["presenter"] }], record: [{ type: i0.Output, args: ["record"] }], presentFromBeginning: [{ type: i0.Output, args: ["presentFromBeginning"] }], rehearseTimings: [{ type: i0.Output, args: ["rehearseTimings"] }], toggleSubtitles: [{ type: i0.Output, args: ["toggleSubtitles"] }], openSubtitleSettings: [{ type: i0.Output, args: ["openSubtitleSettings"] }], recordFromBeginning: [{ type: i0.Output, args: ["recordFromBeginning"] }], recordFromCurrent: [{ type: i0.Output, args: ["recordFromCurrent"] }], spellCheckChange: [{ type: i0.Output, args: ["spellCheckChange"] }], share: [{ type: i0.Output, args: ["share"] }], broadcast: [{ type: i0.Output, args: ["broadcast"] }], openFile: [{ type: i0.Output, args: ["openFile"] }], openRecentFile: [{ type: i0.Output, args: ["openRecentFile"] }], createPresentation: [{ type: i0.Output, args: ["createPresentation"] }], save: [{ type: i0.Output, args: ["save"] }], savePpsx: [{ type: i0.Output, args: ["savePpsx"] }], savePptm: [{ type: i0.Output, args: ["savePptm"] }], packageForSharing: [{ type: i0.Output, args: ["packageForSharing"] }], toggleSidebar: [{ type: i0.Output, args: ["toggleSidebar"] }], toggleAiPanel: [{ type: i0.Output, args: ["toggleAiPanel"] }], signatures: [{ type: i0.Output, args: ["signatures"] }], info: [{ type: i0.Output, args: ["info"] }], print: [{ type: i0.Output, args: ["print"] }], comments: [{ type: i0.Output, args: ["comments"] }], a11y: [{ type: i0.Output, args: ["a11y"] }], shortcuts: [{ type: i0.Output, args: ["shortcuts"] }], versionHistory: [{ type: i0.Output, args: ["versionHistory"] }], passwordProtection: [{ type: i0.Output, args: ["passwordProtection"] }], fontEmbedding: [{ type: i0.Output, args: ["fontEmbedding"] }], link: [{ type: i0.Output, args: ["link"] }], openSorter: [{ type: i0.Output, args: ["openSorter"] }], openReadingView: [{ type: i0.Output, args: ["openReadingView"] }], openOutlineView: [{ type: i0.Output, args: ["openOutlineView"] }], openMasterView: [{ type: i0.Output, args: ["openMasterView"] }], toggleNotes: [{ type: i0.Output, args: ["toggleNotes"] }], toggleFormatPainter: [{ type: i0.Output, args: ["toggleFormatPainter"] }], exportPng: [{ type: i0.Output, args: ["exportPng"] }], exportPdf: [{ type: i0.Output, args: ["exportPdf"] }], exportGif: [{ type: i0.Output, args: ["exportGif"] }], exportVideo: [{ type: i0.Output, args: ["exportVideo"] }], exportJson: [{ type: i0.Output, args: ["exportJson"] }], copySlideAsImage: [{ type: i0.Output, args: ["copySlideAsImage"] }], replace: [{ type: i0.Output, args: ["replace"] }], toggleInspector: [{ type: i0.Output, args: ["toggleInspector"] }], drawToolChange: [{ type: i0.Output, args: ["drawToolChange"] }], toggleThemeGallery: [{ type: i0.Output, args: ["toggleThemeGallery"] }], editTheme: [{ type: i0.Output, args: ["editTheme"] }], openSlideSize: [{ type: i0.Output, args: ["openSlideSize"] }], toggleGrid: [{ type: i0.Output, args: ["toggleGrid"] }], toggleRulers: [{ type: i0.Output, args: ["toggleRulers"] }], toggleGuides: [{ type: i0.Output, args: ["toggleGuides"] }], toggleSelectionPane: [{ type: i0.Output, args: ["toggleSelectionPane"] }], openCustomShows: [{ type: i0.Output, args: ["openCustomShows"] }], toggleSnapToGrid: [{ type: i0.Output, args: ["toggleSnapToGrid"] }], toggleSnapToShape: [{ type: i0.Output, args: ["toggleSnapToShape"] }], addGuide: [{ type: i0.Output, args: ["addGuide"] }], zoomToFit: [{ type: i0.Output, args: ["zoomToFit"] }], toggleEyedropper: [{ type: i0.Output, args: ["toggleEyedropper"] }], openSmartArtDialog: [{ type: i0.Output, args: ["openSmartArtDialog"] }], openTemplateGallery: [{ type: i0.Output, args: ["openTemplateGallery"] }], openEquationDialog: [{ type: i0.Output, args: ["openEquationDialog"] }], openSetUpSlideShow: [{ type: i0.Output, args: ["openSetUpSlideShow"] }], toggleHideSlide: [{ type: i0.Output, args: ["toggleHideSlide"] }], activeSlideHidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeSlideHidden", required: false }] }], openCompare: [{ type: i0.Output, args: ["openCompare"] }], openPassword: [{ type: i0.Output, args: ["openPassword"] }], openFontEmbedding: [{ type: i0.Output, args: ["openFontEmbedding"] }], openVersionHistory: [{ type: i0.Output, args: ["openVersionHistory"] }], openShortcuts: [{ type: i0.Output, args: ["openShortcuts"] }], openSettings: [{ type: i0.Output, args: ["openSettings"] }] } });
118144
+ }], propDecorators: { slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }], slideCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideCount", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], selectedElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElement", required: false }] }], zoomPercent: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomPercent", required: false }] }], formatPainterActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatPainterActive", required: false }] }], canActivateFormatPainter: [{ type: i0.Input, args: [{ isSignal: true, alias: "canActivateFormatPainter", required: false }] }], exporting: [{ type: i0.Input, args: [{ isSignal: true, alias: "exporting", required: false }] }], hasMacros: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMacros", required: false }] }], showGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGrid", required: false }] }], showRulers: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRulers", required: false }] }], showGuides: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGuides", required: false }] }], snapToGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToGrid", required: false }] }], snapToShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToShape", required: false }] }], eyedropperActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "eyedropperActive", required: false }] }], themeGalleryOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "themeGalleryOpen", required: false }] }], sidebarCollapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarCollapsed", required: false }] }], inspectorOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "inspectorOpen", required: false }] }], commentsOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "commentsOpen", required: false }] }], commentCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "commentCount", required: false }] }], findOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "findOpen", required: false }] }], collabConnected: [{ type: i0.Input, args: [{ isSignal: true, alias: "collabConnected", required: false }] }], connectedCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "connectedCount", required: false }] }], spellCheckEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "spellCheckEnabled", required: false }] }], showSubtitles: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSubtitles", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], aiEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiEnabled", required: false }] }], aiPanelOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiPanelOpen", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], prev: [{ type: i0.Output, args: ["prev"] }], next: [{ type: i0.Output, args: ["next"] }], zoomIn: [{ type: i0.Output, args: ["zoomIn"] }], zoomOut: [{ type: i0.Output, args: ["zoomOut"] }], zoomReset: [{ type: i0.Output, args: ["zoomReset"] }], find: [{ type: i0.Output, args: ["find"] }], present: [{ type: i0.Output, args: ["present"] }], presenter: [{ type: i0.Output, args: ["presenter"] }], record: [{ type: i0.Output, args: ["record"] }], presentFromBeginning: [{ type: i0.Output, args: ["presentFromBeginning"] }], rehearseTimings: [{ type: i0.Output, args: ["rehearseTimings"] }], toggleSubtitles: [{ type: i0.Output, args: ["toggleSubtitles"] }], openSubtitleSettings: [{ type: i0.Output, args: ["openSubtitleSettings"] }], recordFromBeginning: [{ type: i0.Output, args: ["recordFromBeginning"] }], recordFromCurrent: [{ type: i0.Output, args: ["recordFromCurrent"] }], spellCheckChange: [{ type: i0.Output, args: ["spellCheckChange"] }], share: [{ type: i0.Output, args: ["share"] }], broadcast: [{ type: i0.Output, args: ["broadcast"] }], openFile: [{ type: i0.Output, args: ["openFile"] }], openRecentFile: [{ type: i0.Output, args: ["openRecentFile"] }], createPresentation: [{ type: i0.Output, args: ["createPresentation"] }], save: [{ type: i0.Output, args: ["save"] }], savePpsx: [{ type: i0.Output, args: ["savePpsx"] }], savePptm: [{ type: i0.Output, args: ["savePptm"] }], toggleSidebar: [{ type: i0.Output, args: ["toggleSidebar"] }], toggleAiPanel: [{ type: i0.Output, args: ["toggleAiPanel"] }], signatures: [{ type: i0.Output, args: ["signatures"] }], info: [{ type: i0.Output, args: ["info"] }], print: [{ type: i0.Output, args: ["print"] }], comments: [{ type: i0.Output, args: ["comments"] }], a11y: [{ type: i0.Output, args: ["a11y"] }], shortcuts: [{ type: i0.Output, args: ["shortcuts"] }], versionHistory: [{ type: i0.Output, args: ["versionHistory"] }], passwordProtection: [{ type: i0.Output, args: ["passwordProtection"] }], fontEmbedding: [{ type: i0.Output, args: ["fontEmbedding"] }], link: [{ type: i0.Output, args: ["link"] }], openSorter: [{ type: i0.Output, args: ["openSorter"] }], openReadingView: [{ type: i0.Output, args: ["openReadingView"] }], openOutlineView: [{ type: i0.Output, args: ["openOutlineView"] }], openMasterView: [{ type: i0.Output, args: ["openMasterView"] }], toggleNotes: [{ type: i0.Output, args: ["toggleNotes"] }], toggleFormatPainter: [{ type: i0.Output, args: ["toggleFormatPainter"] }], exportPng: [{ type: i0.Output, args: ["exportPng"] }], exportPdf: [{ type: i0.Output, args: ["exportPdf"] }], exportGif: [{ type: i0.Output, args: ["exportGif"] }], exportVideo: [{ type: i0.Output, args: ["exportVideo"] }], exportJson: [{ type: i0.Output, args: ["exportJson"] }], copySlideAsImage: [{ type: i0.Output, args: ["copySlideAsImage"] }], replace: [{ type: i0.Output, args: ["replace"] }], toggleInspector: [{ type: i0.Output, args: ["toggleInspector"] }], drawToolChange: [{ type: i0.Output, args: ["drawToolChange"] }], toggleThemeGallery: [{ type: i0.Output, args: ["toggleThemeGallery"] }], editTheme: [{ type: i0.Output, args: ["editTheme"] }], openSlideSize: [{ type: i0.Output, args: ["openSlideSize"] }], toggleGrid: [{ type: i0.Output, args: ["toggleGrid"] }], toggleRulers: [{ type: i0.Output, args: ["toggleRulers"] }], toggleGuides: [{ type: i0.Output, args: ["toggleGuides"] }], toggleSelectionPane: [{ type: i0.Output, args: ["toggleSelectionPane"] }], openCustomShows: [{ type: i0.Output, args: ["openCustomShows"] }], toggleSnapToGrid: [{ type: i0.Output, args: ["toggleSnapToGrid"] }], toggleSnapToShape: [{ type: i0.Output, args: ["toggleSnapToShape"] }], addGuide: [{ type: i0.Output, args: ["addGuide"] }], zoomToFit: [{ type: i0.Output, args: ["zoomToFit"] }], toggleEyedropper: [{ type: i0.Output, args: ["toggleEyedropper"] }], openSmartArtDialog: [{ type: i0.Output, args: ["openSmartArtDialog"] }], openTemplateGallery: [{ type: i0.Output, args: ["openTemplateGallery"] }], openEquationDialog: [{ type: i0.Output, args: ["openEquationDialog"] }], openSetUpSlideShow: [{ type: i0.Output, args: ["openSetUpSlideShow"] }], toggleHideSlide: [{ type: i0.Output, args: ["toggleHideSlide"] }], activeSlideHidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeSlideHidden", required: false }] }], openCompare: [{ type: i0.Output, args: ["openCompare"] }], openPassword: [{ type: i0.Output, args: ["openPassword"] }], openFontEmbedding: [{ type: i0.Output, args: ["openFontEmbedding"] }], openVersionHistory: [{ type: i0.Output, args: ["openVersionHistory"] }], openShortcuts: [{ type: i0.Output, args: ["openShortcuts"] }], openSettings: [{ type: i0.Output, args: ["openSettings"] }] } });
117359
118145
 
117360
118146
  /**
117361
118147
  * selection-pane-helpers.ts: pure display + rename logic behind
@@ -120196,9 +120982,9 @@ function addCategory(element) {
120196
120982
  * const updated = removeCategory(el, 2);
120197
120983
  * ```
120198
120984
  */
120199
- function removeCategory(element, catIndex) {
120985
+ function removeCategory(element, catIndex, followDataPoint = true) {
120200
120986
  const chartData = element.chartData;
120201
- const next = chartData && removeChartCategory(chartData, catIndex);
120987
+ const next = chartData && removeChartCategory(chartData, catIndex, followDataPoint);
120202
120988
  return next ? { ...element, chartData: next } : element;
120203
120989
  }
120204
120990
  // ---------------------------------------------------------------------------
@@ -122205,10 +122991,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
122205
122991
  * @module angular-viewer/chart-data-editor
122206
122992
  */
122207
122993
  class ChartDataEditorComponent {
122994
+ /**
122995
+ * File > Options > Advanced > "Properties follow chart data point for
122996
+ * current workbook". Falls back to PowerPoint's own default (`true`) when
122997
+ * the service is unavailable (standalone unit tests).
122998
+ */
122999
+ followDataPoint() {
123000
+ return this.viewerOpts?.options().advanced.chartPropertiesFollowDataPoint ?? true;
123001
+ }
122208
123002
  constructor() {
122209
123003
  this.translate = inject(TranslateService);
122210
123004
  /** Canvas <-> inspector chart-part selection bridge (viewer-scoped, optional). */
122211
123005
  this.partSelection = inject(ChartPartSelectionService, { optional: true });
123006
+ /** File > Options access (viewer-scoped, optional for standalone unit tests). */
123007
+ this.viewerOpts = inject(ViewerOptionsService, { optional: true });
122212
123008
  this.host = inject(ElementRef);
122213
123009
  this.injector = inject(Injector);
122214
123010
  /** The chart element being edited. */
@@ -122323,10 +123119,10 @@ class ChartDataEditorComponent {
122323
123119
  if (last < 0) {
122324
123120
  return;
122325
123121
  }
122326
- this.elementChange.emit(removeCategory(this.element(), last));
123122
+ this.elementChange.emit(removeCategory(this.element(), last, this.followDataPoint()));
122327
123123
  }
122328
123124
  onRemoveCategory(catIndex) {
122329
- this.elementChange.emit(removeCategory(this.element(), catIndex));
123125
+ this.elementChange.emit(removeCategory(this.element(), catIndex, this.followDataPoint()));
122330
123126
  }
122331
123127
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ChartDataEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
122332
123128
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: ChartDataEditorComponent, isStandalone: true, selector: "pptx-chart-data-editor", inputs: { element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { elementChange: "elementChange" }, ngImport: i0, template: `
@@ -132805,7 +133601,7 @@ class SlideBackgroundCardComponent {
132805
133601
  }
132806
133602
  </section>
132807
133603
  }
132808
- `, isInline: true, styles: [":host{display:block}.bg__color{width:32px;height:22px;padding:1px;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:transparent;cursor:pointer}.bg__file{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.bg__preview{position:relative}.bg__preview img{display:block;width:100%;height:64px;object-fit:cover;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px}.bg__remove{position:absolute;top:2px;right:2px;width:18px;height:18px;padding:0;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));color:var(--pptx-inspector-danger, #d24d4d);line-height:1;cursor:pointer}\n", ".icard{border:1px solid var(--pptx-inspector-border, #333);border-radius:4px;background:var(--pptx-inspector-card-bg, rgba(0, 0, 0, .04));padding:8px;display:grid;gap:6px;font-size:11px}.icard__heading{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--pptx-inspector-muted, #888);margin:0}.icard__row{display:flex;align-items:center;justify-content:space-between;gap:8px}.icard__col{display:flex;flex-direction:column;align-items:stretch;gap:3px}.icard__label{color:var(--pptx-inspector-muted, #888);flex-shrink:0}.icard__value{color:var(--pptx-inspector-muted, #888);text-align:right}.icard__input,.icard__select{box-sizing:border-box;min-width:0;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:3px 5px;font-size:11px;font-family:inherit}.icard__input--number{width:62px;text-align:right}.icard__btn{flex:1;padding:3px 6px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;cursor:pointer;font-size:11px;white-space:nowrap}.icard__btn:disabled{opacity:.5;cursor:default}.icard__btn--danger{flex:0 0 auto;color:var(--pptx-inspector-danger, #d24d4d)}.icard__grid2{display:grid;grid-template-columns:1fr 1fr;gap:6px}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
133604
+ `, isInline: true, styles: [":host{display:block}.bg__color{width:32px;height:22px;padding:1px;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:transparent;cursor:pointer}.bg__file{position:absolute;top:0;left:0;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.bg__preview{position:relative}.bg__preview img{display:block;width:100%;height:64px;object-fit:cover;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px}.bg__remove{position:absolute;top:2px;right:2px;width:18px;height:18px;padding:0;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));color:var(--pptx-inspector-danger, #d24d4d);line-height:1;cursor:pointer}\n", ".icard{border:1px solid var(--pptx-inspector-border, #333);border-radius:4px;background:var(--pptx-inspector-card-bg, rgba(0, 0, 0, .04));padding:8px;display:grid;gap:6px;font-size:11px}.icard__heading{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--pptx-inspector-muted, #888);margin:0}.icard__row{display:flex;align-items:center;justify-content:space-between;gap:8px}.icard__col{display:flex;flex-direction:column;align-items:stretch;gap:3px}.icard__label{color:var(--pptx-inspector-muted, #888);flex-shrink:0}.icard__value{color:var(--pptx-inspector-muted, #888);text-align:right}.icard__input,.icard__select{box-sizing:border-box;min-width:0;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:3px 5px;font-size:11px;font-family:inherit}.icard__input--number{width:62px;text-align:right}.icard__btn{flex:1;padding:3px 6px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;cursor:pointer;font-size:11px;white-space:nowrap}.icard__btn:disabled{opacity:.5;cursor:default}.icard__btn--danger{flex:0 0 auto;color:var(--pptx-inspector-danger, #d24d4d)}.icard__grid2{display:grid;grid-template-columns:1fr 1fr;gap:6px}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
132809
133605
  }
132810
133606
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SlideBackgroundCardComponent, decorators: [{
132811
133607
  type: Component,
@@ -132918,7 +133714,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
132918
133714
  }
132919
133715
  </section>
132920
133716
  }
132921
- `, styles: [":host{display:block}.bg__color{width:32px;height:22px;padding:1px;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:transparent;cursor:pointer}.bg__file{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.bg__preview{position:relative}.bg__preview img{display:block;width:100%;height:64px;object-fit:cover;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px}.bg__remove{position:absolute;top:2px;right:2px;width:18px;height:18px;padding:0;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));color:var(--pptx-inspector-danger, #d24d4d);line-height:1;cursor:pointer}\n", ".icard{border:1px solid var(--pptx-inspector-border, #333);border-radius:4px;background:var(--pptx-inspector-card-bg, rgba(0, 0, 0, .04));padding:8px;display:grid;gap:6px;font-size:11px}.icard__heading{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--pptx-inspector-muted, #888);margin:0}.icard__row{display:flex;align-items:center;justify-content:space-between;gap:8px}.icard__col{display:flex;flex-direction:column;align-items:stretch;gap:3px}.icard__label{color:var(--pptx-inspector-muted, #888);flex-shrink:0}.icard__value{color:var(--pptx-inspector-muted, #888);text-align:right}.icard__input,.icard__select{box-sizing:border-box;min-width:0;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:3px 5px;font-size:11px;font-family:inherit}.icard__input--number{width:62px;text-align:right}.icard__btn{flex:1;padding:3px 6px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;cursor:pointer;font-size:11px;white-space:nowrap}.icard__btn:disabled{opacity:.5;cursor:default}.icard__btn--danger{flex:0 0 auto;color:var(--pptx-inspector-danger, #d24d4d)}.icard__grid2{display:grid;grid-template-columns:1fr 1fr;gap:6px}\n"] }]
133717
+ `, styles: [":host{display:block}.bg__color{width:32px;height:22px;padding:1px;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:transparent;cursor:pointer}.bg__file{position:absolute;top:0;left:0;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.bg__preview{position:relative}.bg__preview img{display:block;width:100%;height:64px;object-fit:cover;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px}.bg__remove{position:absolute;top:2px;right:2px;width:18px;height:18px;padding:0;border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));color:var(--pptx-inspector-danger, #d24d4d);line-height:1;cursor:pointer}\n", ".icard{border:1px solid var(--pptx-inspector-border, #333);border-radius:4px;background:var(--pptx-inspector-card-bg, rgba(0, 0, 0, .04));padding:8px;display:grid;gap:6px;font-size:11px}.icard__heading{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--pptx-inspector-muted, #888);margin:0}.icard__row{display:flex;align-items:center;justify-content:space-between;gap:8px}.icard__col{display:flex;flex-direction:column;align-items:stretch;gap:3px}.icard__label{color:var(--pptx-inspector-muted, #888);flex-shrink:0}.icard__value{color:var(--pptx-inspector-muted, #888);text-align:right}.icard__input,.icard__select{box-sizing:border-box;min-width:0;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;padding:3px 5px;font-size:11px;font-family:inherit}.icard__input--number{width:62px;text-align:right}.icard__btn{flex:1;padding:3px 6px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);color:inherit;border-radius:3px;cursor:pointer;font-size:11px;white-space:nowrap}.icard__btn:disabled{opacity:.5;cursor:default}.icard__btn--danger{flex:0 0 auto;color:var(--pptx-inspector-danger, #d24d4d)}.icard__grid2{display:grid;grid-template-columns:1fr 1fr;gap:6px}\n"] }]
132922
133718
  }], propDecorators: { slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: true }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }] } });
132923
133719
 
132924
133720
  /**
@@ -134618,176 +135414,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
134618
135414
  }]
134619
135415
  }], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], activeName: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeName", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], startCustomizing: [{ type: i0.Input, args: [{ isSignal: true, alias: "startCustomizing", required: false }] }], applyTheme: [{ type: i0.Output, args: ["applyTheme"] }], applyCustomTheme: [{ type: i0.Output, args: ["applyCustomTheme"] }], close: [{ type: i0.Output, args: ["close"] }] } });
134620
135416
 
134621
- /**
134622
- * quick-access-strip.component.ts: the Quick Access Toolbar strip driven by
134623
- * File > Options > Quick Access Toolbar.
134624
- *
134625
- * Renders the ordered {@link QUICK_ACCESS_COMMAND_CATALOG} commands from
134626
- * `options.quickAccess.commandIds` as icon buttons (optionally with labels),
134627
- * emitting the pressed command id; the host maps ids onto its existing
134628
- * handlers. Replaces the title bar's previously hardcoded Save/Undo/Redo
134629
- * trio, and is also rendered below the ribbon when the position option is
134630
- * `below`. Tooltips honour the ScreenTip style via {@link ViewerOptionsService}.
134631
- */
134632
- /** Resolve the configured command ids to renderable strip entries. */
134633
- function resolveQuickAccessItems(commandIds) {
134634
- const items = [];
134635
- for (const id of commandIds) {
134636
- const command = getQuickAccessCommand(id);
134637
- if (command) {
134638
- items.push({ id, icon: command.icon, labelKey: command.labelKey });
134639
- }
134640
- }
134641
- return items;
134642
- }
134643
- class QuickAccessStripComponent {
134644
- constructor() {
134645
- /** The live Quick Access options group (visibility is gated by the host). */
134646
- this.quickAccess = input.required(/* @ts-ignore */
134647
- ...(ngDevMode ? [{ debugName: "quickAccess" }] : /* istanbul ignore next */ []));
134648
- this.canUndo = input(false, /* @ts-ignore */
134649
- ...(ngDevMode ? [{ debugName: "canUndo" }] : /* istanbul ignore next */ []));
134650
- this.canRedo = input(false, /* @ts-ignore */
134651
- ...(ngDevMode ? [{ debugName: "canRedo" }] : /* istanbul ignore next */ []));
134652
- /** A configured command id was pressed. */
134653
- this.command = output();
134654
- this.translate = inject(TranslateService);
134655
- /** Optional so the strip renders outside a full viewer host too. */
134656
- this.viewerOpts = inject(ViewerOptionsService, { optional: true });
134657
- this.tb = TITLE_BAR_CLASSES;
134658
- this.items = computed(() => resolveQuickAccessItems(this.quickAccess().commandIds), /* @ts-ignore */
134659
- ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
134660
- }
134661
- label(item) {
134662
- return this.translate.instant(item.labelKey);
134663
- }
134664
- /** ScreenTip-styled tooltip (null suppresses the title attribute). */
134665
- tip(item) {
134666
- const label = this.label(item);
134667
- return this.viewerOpts ? (this.viewerOpts.screenTip(label) ?? null) : label;
134668
- }
134669
- isDisabled(id) {
134670
- if (id === 'undo') {
134671
- return !this.canUndo();
134672
- }
134673
- if (id === 'redo') {
134674
- return !this.canRedo();
134675
- }
134676
- return false;
134677
- }
134678
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: QuickAccessStripComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
134679
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: QuickAccessStripComponent, isStandalone: true, selector: "pptx-quick-access-strip", inputs: { quickAccess: { classPropertyName: "quickAccess", publicName: "quickAccess", isSignal: true, isRequired: true, transformFunction: null }, canUndo: { classPropertyName: "canUndo", publicName: "canUndo", isSignal: true, isRequired: false, transformFunction: null }, canRedo: { classPropertyName: "canRedo", publicName: "canRedo", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { command: "command" }, ngImport: i0, template: `
134680
- @for (item of items(); track item.id) {
134681
- <button
134682
- type="button"
134683
- [class]="tb.quickButton"
134684
- [disabled]="isDisabled(item.id)"
134685
- [attr.title]="tip(item)"
134686
- [attr.aria-label]="label(item)"
134687
- (click)="command.emit(item.id)"
134688
- >
134689
- @switch (item.icon) {
134690
- @case ('save') {
134691
- <svg lucideSave class="h-3.5 w-3.5"></svg>
134692
- }
134693
- @case ('undo') {
134694
- <svg lucideUndo class="h-3.5 w-3.5"></svg>
134695
- }
134696
- @case ('redo') {
134697
- <svg lucideRedo class="h-3.5 w-3.5"></svg>
134698
- }
134699
- @case ('play') {
134700
- <svg lucidePlay class="h-3.5 w-3.5"></svg>
134701
- }
134702
- @case ('printer') {
134703
- <svg lucidePrinter class="h-3.5 w-3.5"></svg>
134704
- }
134705
- @case ('fileDown') {
134706
- <svg lucideFileDown class="h-3.5 w-3.5"></svg>
134707
- }
134708
- @case ('plus') {
134709
- <svg lucidePlus class="h-3.5 w-3.5"></svg>
134710
- }
134711
- @case ('spellCheck') {
134712
- <svg lucideSearch class="h-3.5 w-3.5"></svg>
134713
- }
134714
- @case ('zoomIn') {
134715
- <svg lucideZoomIn class="h-3.5 w-3.5"></svg>
134716
- }
134717
- @default {
134718
- <svg lucideZoomOut class="h-3.5 w-3.5"></svg>
134719
- }
134720
- }
134721
- @if (quickAccess().showCommandLabels) {
134722
- <span class="pptx-ng-qat-label">{{ label(item) }}</span>
134723
- }
134724
- </button>
134725
- }
134726
- `, isInline: true, styles: [":host{display:inline-flex;align-items:center;gap:2px}.pptx-ng-qat-label{margin-left:4px;font-size:11px;white-space:nowrap}\n"], dependencies: [{ kind: "component", type: LucideSave, selector: "svg[lucideSave]" }, { kind: "component", type: LucideUndo, selector: "svg[lucideUndo]" }, { kind: "component", type: LucideRedo, selector: "svg[lucideRedo]" }, { kind: "component", type: LucidePlay, selector: "svg[lucidePlay]" }, { kind: "component", type: LucidePrinter, selector: "svg[lucidePrinter]" }, { kind: "component", type: LucideFileDown, selector: "svg[lucideFileDown]" }, { kind: "component", type: LucidePlus, selector: "svg[lucidePlus]" }, { kind: "component", type: LucideSearch, selector: "svg[lucideSearch]" }, { kind: "component", type: LucideZoomIn, selector: "svg[lucideZoomIn]" }, { kind: "component", type: LucideZoomOut, selector: "svg[lucideZoomOut]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
134727
- }
134728
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: QuickAccessStripComponent, decorators: [{
134729
- type: Component,
134730
- args: [{ selector: 'pptx-quick-access-strip', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
134731
- LucideSave,
134732
- LucideUndo,
134733
- LucideRedo,
134734
- LucidePlay,
134735
- LucidePrinter,
134736
- LucideFileDown,
134737
- LucidePlus,
134738
- LucideSearch,
134739
- LucideZoomIn,
134740
- LucideZoomOut,
134741
- ], template: `
134742
- @for (item of items(); track item.id) {
134743
- <button
134744
- type="button"
134745
- [class]="tb.quickButton"
134746
- [disabled]="isDisabled(item.id)"
134747
- [attr.title]="tip(item)"
134748
- [attr.aria-label]="label(item)"
134749
- (click)="command.emit(item.id)"
134750
- >
134751
- @switch (item.icon) {
134752
- @case ('save') {
134753
- <svg lucideSave class="h-3.5 w-3.5"></svg>
134754
- }
134755
- @case ('undo') {
134756
- <svg lucideUndo class="h-3.5 w-3.5"></svg>
134757
- }
134758
- @case ('redo') {
134759
- <svg lucideRedo class="h-3.5 w-3.5"></svg>
134760
- }
134761
- @case ('play') {
134762
- <svg lucidePlay class="h-3.5 w-3.5"></svg>
134763
- }
134764
- @case ('printer') {
134765
- <svg lucidePrinter class="h-3.5 w-3.5"></svg>
134766
- }
134767
- @case ('fileDown') {
134768
- <svg lucideFileDown class="h-3.5 w-3.5"></svg>
134769
- }
134770
- @case ('plus') {
134771
- <svg lucidePlus class="h-3.5 w-3.5"></svg>
134772
- }
134773
- @case ('spellCheck') {
134774
- <svg lucideSearch class="h-3.5 w-3.5"></svg>
134775
- }
134776
- @case ('zoomIn') {
134777
- <svg lucideZoomIn class="h-3.5 w-3.5"></svg>
134778
- }
134779
- @default {
134780
- <svg lucideZoomOut class="h-3.5 w-3.5"></svg>
134781
- }
134782
- }
134783
- @if (quickAccess().showCommandLabels) {
134784
- <span class="pptx-ng-qat-label">{{ label(item) }}</span>
134785
- }
134786
- </button>
134787
- }
134788
- `, styles: [":host{display:inline-flex;align-items:center;gap:2px}.pptx-ng-qat-label{margin-left:4px;font-size:11px;white-space:nowrap}\n"] }]
134789
- }], propDecorators: { quickAccess: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickAccess", required: true }] }], canUndo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canUndo", required: false }] }], canRedo: [{ type: i0.Input, args: [{ isSignal: true, alias: "canRedo", required: false }] }], command: [{ type: i0.Output, args: ["command"] }] } });
134790
-
134791
135417
  /**
134792
135418
  * title-bar-search.component.ts: the centred command-search box + results
134793
135419
  * dropdown of the editor title bar.
@@ -135040,6 +135666,23 @@ function narrowToExtraQuickAccess(options) {
135040
135666
  : [],
135041
135667
  };
135042
135668
  }
135669
+ /**
135670
+ * The below-ribbon strip's options, or `null` when nothing renders there:
135671
+ * hidden, position `above`, or no commands beyond the dedicated trio.
135672
+ *
135673
+ * Single source of truth for BOTH sides of the "below the ribbon" placement:
135674
+ * {@link PowerPointViewerComponent} renders the strip precisely when this is
135675
+ * non-null, and this component's own inline strip below suppresses itself
135676
+ * under the identical condition, so the two can never disagree about where
135677
+ * the configured commands show up.
135678
+ */
135679
+ function resolveBelowRibbonQuickAccess(options) {
135680
+ if (!options.visible || options.position !== 'below') {
135681
+ return null;
135682
+ }
135683
+ const narrowed = narrowToExtraQuickAccess(options);
135684
+ return narrowed.commandIds.length > 0 ? narrowed : null;
135685
+ }
135043
135686
  class TitleBarComponent {
135044
135687
  constructor() {
135045
135688
  /** Whether the deck is editable (gates the autosave/quick-access/search chrome). */
@@ -135095,6 +135738,13 @@ class TitleBarComponent {
135095
135738
  */
135096
135739
  this.extraQat = computed(() => narrowToExtraQuickAccess(this.qat()), /* @ts-ignore */
135097
135740
  ...(ngDevMode ? [{ debugName: "extraQat" }] : /* istanbul ignore next */ []));
135741
+ /**
135742
+ * Whether the below-ribbon strip is the one rendering the configured extra
135743
+ * commands right now, so this component's OWN inline strip stands down
135744
+ * instead of showing the same commands twice.
135745
+ */
135746
+ this.belowRibbonActive = computed(() => resolveBelowRibbonQuickAccess(this.qat()) !== null, /* @ts-ignore */
135747
+ ...(ngDevMode ? [{ debugName: "belowRibbonActive" }] : /* istanbul ignore next */ []));
135098
135748
  /** The i18n key for the save-location status text (next to the file name). */
135099
135749
  this.statusKey = computed(() => {
135100
135750
  const status = this.autosaveStatus();
@@ -135214,7 +135864,7 @@ class TitleBarComponent {
135214
135864
  <svg lucideRedo class="h-3.5 w-3.5"></svg>
135215
135865
  </button>
135216
135866
  }
135217
- @if (extraQat().commandIds.length > 0) {
135867
+ @if (extraQat().commandIds.length > 0 && !belowRibbonActive()) {
135218
135868
  <pptx-quick-access-strip
135219
135869
  [quickAccess]="extraQat()"
135220
135870
  (command)="onQuickCommand($event)"
@@ -135336,7 +135986,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
135336
135986
  <svg lucideRedo class="h-3.5 w-3.5"></svg>
135337
135987
  </button>
135338
135988
  }
135339
- @if (extraQat().commandIds.length > 0) {
135989
+ @if (extraQat().commandIds.length > 0 && !belowRibbonActive()) {
135340
135990
  <pptx-quick-access-strip
135341
135991
  [quickAccess]="extraQat()"
135342
135992
  (command)="onQuickCommand($event)"
@@ -140309,6 +140959,15 @@ class ViewerExtraDialogsComponent {
140309
140959
  this.editor = inject(EditorStateService);
140310
140960
  this.loader = inject(LoadContentService);
140311
140961
  this.fonts = inject(EmbeddedFontsService);
140962
+ this.smartArt3D = inject(SmartArt3DService);
140963
+ this.collab = inject(CollaborationService);
140964
+ /** Real runtime availability for the Options > Add-ins pane; see {@link resolveViewerExtraAddinStatus}. */
140965
+ this.addinStatus = computed(() => resolveViewerExtraAddinStatus({
140966
+ smartArt3dEnabled: this.smartArt3D.enabled(),
140967
+ disable3DRendering: this.viewerOpts.options().advanced.disable3DRendering,
140968
+ collaborationConnected: this.collab.connected(),
140969
+ }), /* @ts-ignore */
140970
+ ...(ngDevMode ? [{ debugName: "addinStatus" }] : /* istanbul ignore next */ []));
140312
140971
  /** Distinct font families used across the editable deck. */
140313
140972
  this.usedFontFamilies = computed(() => collectUsedFontFamilies(this.editor.slides()), /* @ts-ignore */
140314
140973
  ...(ngDevMode ? [{ debugName: "usedFontFamilies" }] : /* istanbul ignore next */ []));
@@ -140473,6 +141132,7 @@ class ViewerExtraDialogsComponent {
140473
141132
  <pptx-settings-dialog
140474
141133
  [open]="svc.showSettings()"
140475
141134
  [options]="viewerOpts.options()"
141135
+ [addinStatus]="addinStatus()"
140476
141136
  [themeKey]="themeKey()"
140477
141137
  [availableThemes]="availableThemes()"
140478
141138
  [localeCode]="localeCode()"
@@ -140599,6 +141259,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
140599
141259
  <pptx-settings-dialog
140600
141260
  [open]="svc.showSettings()"
140601
141261
  [options]="viewerOpts.options()"
141262
+ [addinStatus]="addinStatus()"
140602
141263
  [themeKey]="themeKey()"
140603
141264
  [availableThemes]="availableThemes()"
140604
141265
  [localeCode]="localeCode()"
@@ -140660,6 +141321,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
140660
141321
  * the root element (app-wide sharing via `provideViewerTheme`).
140661
141322
  */
140662
141323
  class PowerPointViewerComponent {
141324
+ /** Lift Protected View's read-only lock for the current document (File > Options > Trust Center). */
141325
+ enableEditing() {
141326
+ this.protectedViewDismissed.set(true);
141327
+ }
140663
141328
  /** Flip the AutoSave preference, unless the host forbade autosave outright. */
140664
141329
  toggleAutosave() {
140665
141330
  if (this.autosaveActivation().toggleAvailable) {
@@ -140942,13 +141607,52 @@ class PowerPointViewerComponent {
140942
141607
  /** The `<main>` host; used to locate the live `.pptx-ng-canvas-stage`. */
140943
141608
  this.mainEl = viewChild('mainEl', /* @ts-ignore */
140944
141609
  ...(ngDevMode ? [{ debugName: "mainEl" }] : /* istanbul ignore next */ []));
141610
+ /**
141611
+ * Whether the CURRENT document's Protected View lock was lifted via the
141612
+ * banner's "Enable Editing" button this session. A document the host
141613
+ * opened read-only (`canEditInput()` false) never shows the banner, so
141614
+ * there is nothing to dismiss for it; reset to `false` whenever a new
141615
+ * presentation finishes loading (see the `loader.slides()` effect below),
141616
+ * so re-opening (or opening another) file starts protected again,
141617
+ * mirroring PowerPoint's own per-document banner.
141618
+ */
141619
+ this.protectedViewDismissed = signal(false, /* @ts-ignore */
141620
+ ...(ngDevMode ? [{ debugName: "protectedViewDismissed" }] : /* istanbul ignore next */ []));
140945
141621
  /**
140946
141622
  * Effective edit permission: the host's `canEdit` input gated by Trust
140947
141623
  * Center > "Open presentations in Protected View", which forces the deck
140948
- * read-only while enabled (File > Options wiring, mirrors PowerPoint).
141624
+ * read-only while enabled (File > Options wiring, mirrors PowerPoint),
141625
+ * unless the user has lifted it via `enableEditing()` for this document.
140949
141626
  */
140950
- this.canEdit = computed(() => this.canEditInput() && !this.viewerOpts.options().trust.openInProtectedView, /* @ts-ignore */
141627
+ this.canEdit = computed(() => this.canEditInput() &&
141628
+ (!this.viewerOpts.options().trust.openInProtectedView || this.protectedViewDismissed()), /* @ts-ignore */
140951
141629
  ...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
141630
+ /** Whether the Protected View banner should show: host allows editing, the option still blocks it, and the user hasn't dismissed it yet. */
141631
+ this.protectedViewActive = computed(() => this.canEditInput() &&
141632
+ this.viewerOpts.options().trust.openInProtectedView &&
141633
+ !this.protectedViewDismissed(), /* @ts-ignore */
141634
+ ...(ngDevMode ? [{ debugName: "protectedViewActive" }] : /* istanbul ignore next */ []));
141635
+ /**
141636
+ * Toolbar/ribbon ids to hide: the host's own `hiddenActions` input, UNIONED
141637
+ * with File > Options > Customize Ribbon's `ribbon.hiddenTabIds` (see
141638
+ * {@link mergeHiddenActions}). Every chrome component downstream (ribbon,
141639
+ * title bar, mobile toolbar/menu, status bar) must see BOTH, or ticking a
141640
+ * tab off in Customize Ribbon changes what the pane displays without
141641
+ * changing what actually renders.
141642
+ */
141643
+ this.effectiveHiddenActions = computed(() => mergeHiddenActions(this.hiddenActions(), this.viewerOpts.options().ribbon.hiddenTabIds), /* @ts-ignore */
141644
+ ...(ngDevMode ? [{ debugName: "effectiveHiddenActions" }] : /* istanbul ignore next */ []));
141645
+ /**
141646
+ * File > Options > Quick Access Toolbar > Position "Below the Ribbon": the
141647
+ * configured commands beyond the dedicated Save/Undo/Redo trio (which stay
141648
+ * in the title bar regardless of position), or `null` when the strip has
141649
+ * nothing to show there (hidden, `above`, or no extra commands configured).
141650
+ * {@link TitleBarComponent} independently suppresses its own inline strip
141651
+ * under the identical {@link resolveBelowRibbonQuickAccess} condition, so
141652
+ * the commands render in exactly one place.
141653
+ */
141654
+ this.belowRibbonQuickAccess = computed(() => resolveBelowRibbonQuickAccess(this.viewerOpts.options().quickAccess), /* @ts-ignore */
141655
+ ...(ngDevMode ? [{ debugName: "belowRibbonQuickAccess" }] : /* istanbul ignore next */ []));
140952
141656
  this.activeSlideIndex = signal(0, /* @ts-ignore */
140953
141657
  ...(ngDevMode ? [{ debugName: "activeSlideIndex" }] : /* istanbul ignore next */ []));
140954
141658
  /**
@@ -141344,35 +142048,31 @@ class PowerPointViewerComponent {
141344
142048
  this.viewerOpts.store.setOptions(next);
141345
142049
  }
141346
142050
  });
141347
- // Surface the `smartArt3D` opt-in to the element dispatcher via the
141348
- // viewer-scoped SmartArt3DService.
141349
- effect(() => {
141350
- this.smartArt3DSvc.enabled.set(this.smartArt3D());
141351
- });
141352
- // Surface the `surfaceChart3D` opt-in to the chart element view via the
141353
- // viewer-scoped SurfaceChart3DService.
141354
- effect(() => {
141355
- this.surfaceChart3DSvc.enabled.set(this.surfaceChart3D());
141356
- });
141357
- // Surface the `barChart3D` opt-in to the chart element view via the
141358
- // viewer-scoped BarChart3DService.
141359
- effect(() => {
141360
- this.barChart3DSvc.enabled.set(this.barChart3D());
141361
- });
141362
- // Surface the `lineChart3D` opt-in to the chart element view via the
141363
- // viewer-scoped LineChart3DService.
141364
- effect(() => {
141365
- this.lineChart3DSvc.enabled.set(this.lineChart3D());
141366
- });
141367
- // Surface the `areaChart3D` opt-in to the chart element view via the
141368
- // viewer-scoped AreaChart3DService.
142051
+ // Surface the six 3D opt-in props to their viewer-scoped services, each
142052
+ // ANDed with Options > Advanced > "Disable 3D rendering" (see
142053
+ // `resolve3DRenderingFlags`) so a viewer user can force flat 2D even in a
142054
+ // deck the host enabled 3D for. One effect (not six) so they all react to
142055
+ // the same options-changed signal read.
141369
142056
  effect(() => {
141370
- this.areaChart3DSvc.enabled.set(this.areaChart3D());
142057
+ const effective = resolve3DRenderingFlags({
142058
+ smartArt3D: this.smartArt3D(),
142059
+ surfaceChart3D: this.surfaceChart3D(),
142060
+ barChart3D: this.barChart3D(),
142061
+ lineChart3D: this.lineChart3D(),
142062
+ areaChart3D: this.areaChart3D(),
142063
+ pieChart3D: this.pieChart3D(),
142064
+ }, this.viewerOpts.options());
142065
+ this.smartArt3DSvc.enabled.set(effective.smartArt3D);
142066
+ this.surfaceChart3DSvc.enabled.set(effective.surfaceChart3D);
142067
+ this.barChart3DSvc.enabled.set(effective.barChart3D);
142068
+ this.lineChart3DSvc.enabled.set(effective.lineChart3D);
142069
+ this.areaChart3DSvc.enabled.set(effective.areaChart3D);
142070
+ this.pieChart3DSvc.enabled.set(effective.pieChart3D);
141371
142071
  });
141372
- // Surface the `pieChart3D` opt-in to the chart element view via the
141373
- // viewer-scoped PieChart3DService.
142072
+ // Advanced > "Maximum number of undos", re-applied live on every change
142073
+ // (not just at construction).
141374
142074
  effect(() => {
141375
- this.pieChart3DSvc.enabled.set(this.pieChart3D());
142075
+ this.editor.setHistoryDepth(this.viewerOpts.historyDepth());
141376
142076
  });
141377
142077
  // A new host `content` input supersedes any in-place picked file.
141378
142078
  effect(() => {
@@ -141396,6 +142096,9 @@ class PowerPointViewerComponent {
141396
142096
  untracked(() => {
141397
142097
  this.editor.setSlides(slides, this.loader.sections());
141398
142098
  this.activeSlideIndex.set(0);
142099
+ // A newly opened document is protected again even if the previous
142100
+ // one was unlocked via "Enable Editing" this session.
142101
+ this.protectedViewDismissed.set(false);
141399
142102
  // Adopt `p:showPr/p:custShow/@id`: a deck authored to open into a
141400
142103
  // named custom show must actually play it. A manual pick made later
141401
142104
  // overwrites this and wins until the next deck loads.
@@ -141546,6 +142249,7 @@ class PowerPointViewerComponent {
141546
142249
  slideCount: () => this.slideCount(),
141547
142250
  mergedSlides: () => this.mergedSlides(),
141548
142251
  resolveStage: () => this.stageElement(),
142252
+ imageExportScale: () => this.viewerOpts.imageExportScale(),
141549
142253
  });
141550
142254
  // Hand the find/replace controller a slide-navigation callback so a match
141551
142255
  // can scroll its slide into view.
@@ -141677,6 +142381,33 @@ class PowerPointViewerComponent {
141677
142381
  password: this.dialogs.presentationPassword(),
141678
142382
  passwordProtected: this.dialogs.isPasswordProtected(),
141679
142383
  }),
142384
+ afterSuccessfulSave: (format) => {
142385
+ this.viewerOpts.playFeedback();
142386
+ const filePath = this.filePath();
142387
+ if (format === 'pptx' && filePath && this.viewerOpts.shouldDiscardAutosaveOnSave()) {
142388
+ void deleteAutosaveSnapshot(filePath);
142389
+ }
142390
+ },
142391
+ });
142392
+ // File > Options > Save > "cache retention": a one-time sweep per mount is
142393
+ // enough, since a fresh snapshot only ever lands with a fresh timestamp.
142394
+ void (async () => {
142395
+ try {
142396
+ const snapshots = await listAutosaveSnapshots();
142397
+ const expired = resolveExpiredAutosaveSnapshots(snapshots, this.viewerOpts.options());
142398
+ await Promise.all(expired.map((key) => deleteAutosaveSnapshot(key)));
142399
+ }
142400
+ catch {
142401
+ // Best-effort background maintenance; a blocked IndexedDB skips it.
142402
+ }
142403
+ })();
142404
+ // File > Options > Save > "clear cache on close": also cover the viewer
142405
+ // being destroyed without a page unload (the `beforeunload` listener
142406
+ // above covers the tab actually closing/navigating away).
142407
+ this.destroyRef.onDestroy(() => {
142408
+ if (this.viewerOpts.shouldClearCacheOnClose()) {
142409
+ void this.viewerOpts.clearCache();
142410
+ }
141680
142411
  });
141681
142412
  // Hand the canvas-editing controller the accessors it alone needs from the
141682
142413
  // component (canEdit / active-slide / active-slide-index).
@@ -142392,9 +143123,16 @@ class PowerPointViewerComponent {
142392
143123
  this.activeDrawColor.set(state.color);
142393
143124
  this.activeDrawWidth.set(state.width);
142394
143125
  }
143126
+ /**
143127
+ * Comment/reply author: the host `authorName` input wins, otherwise fall
143128
+ * back to Options > General > "User name" before the generic "You".
143129
+ */
143130
+ commentAuthorName() {
143131
+ return this.authorName() || this.viewerOpts.options().general.userName || 'You';
143132
+ }
142395
143133
  /** Append a comment to the active slide (one history entry). */
142396
143134
  onCommentAdd(text) {
142397
- const next = addCommentToList(this.activeComments(), text, 'You');
143135
+ const next = addCommentToList(this.activeComments(), text, this.commentAuthorName());
142398
143136
  if (next) {
142399
143137
  this.editor.updateSlide(this.activeSlideIndex(), { comments: next });
142400
143138
  }
@@ -142415,7 +143153,7 @@ class PowerPointViewerComponent {
142415
143153
  }
142416
143154
  /** Append a threaded reply under a top-level comment on the active slide. */
142417
143155
  onCommentReply(event) {
142418
- const next = replyToCommentInList(this.activeComments(), event.parentId, event.text, 'You');
143156
+ const next = replyToCommentInList(this.activeComments(), event.parentId, event.text, this.commentAuthorName());
142419
143157
  if (next) {
142420
143158
  this.editor.updateSlide(this.activeSlideIndex(), { comments: next });
142421
143159
  }
@@ -142450,12 +143188,18 @@ class PowerPointViewerComponent {
142450
143188
  onKeyDown(event) {
142451
143189
  this.keyboard.handleKeyDown(event);
142452
143190
  }
143191
+ /** Options > Save > "clear cache on close": wipe recovery snapshots when the tab closes. */
143192
+ clearCacheOnUnload() {
143193
+ if (this.viewerOpts.shouldClearCacheOnClose()) {
143194
+ void this.viewerOpts.clearCache();
143195
+ }
143196
+ }
142453
143197
  /** Resolve the live slide-stage element within `<main>`. */
142454
143198
  stageElement() {
142455
143199
  return (this.mainEl()?.nativeElement.querySelector('.pptx-ng-canvas-stage') ?? undefined);
142456
143200
  }
142457
143201
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PowerPointViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
142458
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", 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 }, autosaveInput: { classPropertyName: "autosaveInput", publicName: "autosave", isSignal: true, isRequired: false, transformFunction: null }, autosaveIntervalMs: { classPropertyName: "autosaveIntervalMs", publicName: "autosaveIntervalMs", 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 }, surfaceChart3D: { classPropertyName: "surfaceChart3D", publicName: "surfaceChart3D", isSignal: true, isRequired: false, transformFunction: null }, barChart3D: { classPropertyName: "barChart3D", publicName: "barChart3D", isSignal: true, isRequired: false, transformFunction: null }, lineChart3D: { classPropertyName: "lineChart3D", publicName: "lineChart3D", isSignal: true, isRequired: false, transformFunction: null }, areaChart3D: { classPropertyName: "areaChart3D", publicName: "areaChart3D", isSignal: true, isRequired: false, transformFunction: null }, pieChart3D: { classPropertyName: "pieChart3D", publicName: "pieChart3D", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, ai: { classPropertyName: "ai", publicName: "ai", 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: `
143202
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", 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 }, autosaveInput: { classPropertyName: "autosaveInput", publicName: "autosave", isSignal: true, isRequired: false, transformFunction: null }, autosaveIntervalMs: { classPropertyName: "autosaveIntervalMs", publicName: "autosaveIntervalMs", 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 }, surfaceChart3D: { classPropertyName: "surfaceChart3D", publicName: "surfaceChart3D", isSignal: true, isRequired: false, transformFunction: null }, barChart3D: { classPropertyName: "barChart3D", publicName: "barChart3D", isSignal: true, isRequired: false, transformFunction: null }, lineChart3D: { classPropertyName: "lineChart3D", publicName: "lineChart3D", isSignal: true, isRequired: false, transformFunction: null }, areaChart3D: { classPropertyName: "areaChart3D", publicName: "areaChart3D", isSignal: true, isRequired: false, transformFunction: null }, pieChart3D: { classPropertyName: "pieChart3D", publicName: "pieChart3D", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, ai: { classPropertyName: "ai", publicName: "ai", 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)", "window:beforeunload": "clearCacheOnUnload()" } }, 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: `
142459
143203
  <div
142460
143204
  class="pptx-ng-viewer"
142461
143205
  [ngClass]="rootClasses()"
@@ -142477,6 +143221,26 @@ class PowerPointViewerComponent {
142477
143221
  <pre class="pptx-ng-error-detail">{{ loader.error() }}</pre>
142478
143222
  </div>
142479
143223
  } @else {
143224
+ @if (protectedViewActive() && chromeVisible()) {
143225
+ <div
143226
+ class="pptx-ng-protected-view-banner flex items-center gap-3 border-b border-amber-700/30 bg-amber-900/20 px-4 py-2"
143227
+ role="status"
143228
+ >
143229
+ <span class="h-4 w-4 shrink-0 text-amber-400" aria-hidden="true">&#128274;</span>
143230
+ <p class="flex-1 text-xs text-amber-200">
143231
+ <strong>{{ 'pptx.security.protectedViewTitle' | translate }}</strong
143232
+ >:
143233
+ {{ 'pptx.options.trust.protectedViewInfo' | translate }}
143234
+ </p>
143235
+ <button
143236
+ type="button"
143237
+ class="shrink-0 rounded border border-amber-600/50 px-3 py-1 text-xs font-medium text-amber-100 transition-colors hover:bg-amber-700/30"
143238
+ (click)="enableEditing()"
143239
+ >
143240
+ {{ 'pptx.security.enableEditing' | translate }}
143241
+ </button>
143242
+ </div>
143243
+ }
142480
143244
  @if (!mobile.isMobile() && chromeVisible()) {
142481
143245
  <pptx-title-bar
142482
143246
  [canEdit]="canEdit()"
@@ -142489,7 +143253,7 @@ class PowerPointViewerComponent {
142489
143253
  [undoLabel]="editor.undoLabel()"
142490
143254
  [redoLabel]="editor.redoLabel()"
142491
143255
  [findReplaceOpen]="findReplace.showFind() || findReplace.showFindReplace()"
142492
- [hiddenActions]="hiddenActions()"
143256
+ [hiddenActions]="effectiveHiddenActions()"
142493
143257
  [quickAccess]="viewerOpts.options().quickAccess"
142494
143258
  (toggleAutosave)="toggleAutosave()"
142495
143259
  (save)="fileIO.saveAsPptx()"
@@ -142504,7 +143268,7 @@ class PowerPointViewerComponent {
142504
143268
  [slideCount]="slideCount()"
142505
143269
  [canEdit]="canEdit()"
142506
143270
  [selectedElement]="selectedElement()"
142507
- [hiddenActions]="hiddenActions()"
143271
+ [hiddenActions]="effectiveHiddenActions()"
142508
143272
  [zoomPercent]="zoomSvc.zoomPercent()"
142509
143273
  [formatPainterActive]="formatPainter.active()"
142510
143274
  [canActivateFormatPainter]="formatPainter.canActivate()"
@@ -142544,7 +143308,6 @@ class PowerPointViewerComponent {
142544
143308
  (save)="fileIO.saveAsPptx()"
142545
143309
  (savePpsx)="fileIO.saveAsPpsx()"
142546
143310
  (savePptm)="fileIO.saveAsPptm()"
142547
- (packageForSharing)="fileIO.packageForSharing()"
142548
143311
  (info)="docProperties.showProperties.set(true)"
142549
143312
  (print)="print.openDialog()"
142550
143313
  (comments)="inspectorPanel.togglePanel('comments')"
@@ -142607,6 +143370,20 @@ class PowerPointViewerComponent {
142607
143370
  [aiPanelOpen]="aiPanelOpen()"
142608
143371
  (toggleAiPanel)="aiPanelOpen.update((v) => !v)"
142609
143372
  />
143373
+
143374
+ @if (belowRibbonQuickAccess(); as belowQuickAccess) {
143375
+ <div
143376
+ class="flex items-center gap-0.5 border-b border-border/60 px-2 py-0.5"
143377
+ data-pptx-quick-access="below"
143378
+ >
143379
+ <pptx-quick-access-strip
143380
+ [quickAccess]="belowQuickAccess"
143381
+ [canUndo]="editor.canUndo()"
143382
+ [canRedo]="editor.canRedo()"
143383
+ (command)="onQuickAccessCommand($event)"
143384
+ />
143385
+ </div>
143386
+ }
142610
143387
  }
142611
143388
 
142612
143389
  @if (mobile.isMobile() && chromeVisible()) {
@@ -142618,7 +143395,7 @@ class PowerPointViewerComponent {
142618
143395
  [menuOpen]="mobileSheetSvc.mobileSheet() === 'menu'"
142619
143396
  [aiEnabled]="aiEnabled()"
142620
143397
  [aiPanelOpen]="aiPanelOpen()"
142621
- [hiddenActions]="hiddenActions()"
143398
+ [hiddenActions]="effectiveHiddenActions()"
142622
143399
  (toggleMenu)="
142623
143400
  mobileSheetSvc.mobileSheet.set(
142624
143401
  mobileSheetSvc.mobileSheet() === 'menu' ? null : 'menu'
@@ -142910,7 +143687,7 @@ class PowerPointViewerComponent {
142910
143687
  [zoomPercent]="zoomSvc.zoomPercent()"
142911
143688
  [sorterActive]="showSorter()"
142912
143689
  [presenting]="presentationMode.presenting()"
142913
- [hiddenActions]="hiddenActions()"
143690
+ [hiddenActions]="effectiveHiddenActions()"
142914
143691
  (toggleNotes)="mobileSheetSvc.toggleNotes()"
142915
143692
  (normalView)="showSorter.set(false)"
142916
143693
  (openSorter)="showSorter.set(true)"
@@ -143021,6 +143798,8 @@ class PowerPointViewerComponent {
143021
143798
  [subtitlesVisible]="presentationMode.subtitlesVisible()"
143022
143799
  [sessionEnded]="audienceSessionEnded()"
143023
143800
  [endWithBlackSlide]="viewerOpts.options().advanced.slideShowEndWithBlackSlide"
143801
+ [showMenuOnRightClick]="viewerOpts.options().advanced.slideShowShowMenuOnRightClick"
143802
+ [showPopupToolbar]="viewerOpts.options().advanced.slideShowShowPopupToolbar"
143024
143803
  [presenterMode]="presentationMode.presentingPresenter()"
143025
143804
  (presenterViewToggle)="presentationMode.togglePresenterView()"
143026
143805
  (subtitlesChange)="presentationMode.subtitlesVisible.set($event)"
@@ -143171,7 +143950,14 @@ class PowerPointViewerComponent {
143171
143950
  <pptx-print-dialog
143172
143951
  [slides]="displaySlidesMut()"
143173
143952
  [activeSlideIndex]="activeSlideIndex()"
143174
- (print)="xport.onPrint($event)"
143953
+ [defaultSettings]="viewerOpts.printDefaults()"
143954
+ (print)="
143955
+ xport.onPrint(
143956
+ $event,
143957
+ viewerOpts.options().advanced.printHiddenSlides,
143958
+ viewerOpts.options().advanced.printHighQuality
143959
+ )
143960
+ "
143175
143961
  (cancel)="print.closeDialog()"
143176
143962
  />
143177
143963
  }
@@ -143260,7 +144046,7 @@ class PowerPointViewerComponent {
143260
144046
  [exporting]="xport.exporting()"
143261
144047
  [showNotes]="mobileSheetSvc.showNotes()"
143262
144048
  [canEdit]="canEdit()"
143263
- [hiddenActions]="hiddenActions()"
144049
+ [hiddenActions]="effectiveHiddenActions()"
143264
144050
  (closed)="mobileSheetSvc.mobileSheet.set(null)"
143265
144051
  (openFind)="findReplace.showFind.set(true)"
143266
144052
  (openSorter)="showSorter.set(true)"
@@ -143335,7 +144121,7 @@ class PowerPointViewerComponent {
143335
144121
  />
143336
144122
  }
143337
144123
  </div>
143338
- `, 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", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationOverlayComponent, selector: "pptx-presentation-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "startIndex", "activeCustomShow", "showWithAnimation", "useTimings", "subtitlesVisible", "sessionEnded", "endWithBlackSlide", "presenterMode"], outputs: ["indexChange", "closed", "subtitlesChange", "presenterViewToggle", "annotationsExit"] }, { kind: "component", type: PresenterViewComponent, selector: "pptx-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime", "isAudienceWindowOpen"], outputs: ["movePresentationSlide", "exit", "openAudienceWindow", "closeAudienceWindow", "navigateToSlide"] }, { kind: "component", type: MobilePresenterViewComponent, selector: "pptx-mobile-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime"], outputs: ["movePresentationSlide", "exit"] }, { kind: "component", type: SlideSorterOverlayComponent, selector: "pptx-slide-sorter-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeIndex", "canEdit"], outputs: ["select", "closed", "deleteSlide", "duplicateSlide", "toggleHiddenSlide"] }, { kind: "component", type: OutlineViewOverlayComponent, selector: "pptx-outline-view-overlay", inputs: ["slides", "canvasSize", "canEdit"], outputs: ["commit", "closed"] }, { kind: "component", type: ReadingViewOverlayComponent, selector: "pptx-reading-view-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeSlideIndex"], outputs: ["exit"] }, { kind: "component", type: SlideDefaultInspectorComponent, selector: "pptx-slide-default-inspector", inputs: ["slideIndex", "canEdit", "selectedElement", "comments"], outputs: ["commentAdd", "commentRemove", "commentResolve", "commentReply"] }, { kind: "component", type: FindBarComponent, selector: "pptx-find-bar", inputs: ["slides"], outputs: ["navigate", "closed"] }, { kind: "component", type: FindReplaceBarComponent, selector: "pptx-find-replace-bar", inputs: ["matchCount", "matchIndex"], outputs: ["find", "navigate", "replaceOne", "replaceAll", "close"] }, { kind: "component", type: SlidesPanelComponent, selector: "pptx-slides-panel", inputs: ["canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select"] }, { kind: "component", type: StatusBarComponent, selector: "pptx-status-bar", inputs: ["slideIndex", "slideCount", "canEdit", "dirty", "autosaveStatus", "notesOpen", "zoomPercent", "sorterActive", "presenting", "hiddenActions"], outputs: ["toggleNotes", "normalView", "openSorter", "slideShow", "zoomIn", "zoomOut", "zoomReset"] }, { kind: "component", type: EditorContextMenuComponent, selector: "pptx-editor-context-menu", inputs: ["x", "y", "slideIndex", "showAiActions"], outputs: ["closed", "askAi", "fixAi", "editHyperlink", "addComment"] }, { kind: "component", type: ExportProgressModalComponent, selector: "pptx-export-progress-modal", inputs: ["open", "title", "progress", "statusMessage"], outputs: ["cancel"] }, { kind: "component", type: CommentMarkersOverlayComponent, selector: "pptx-comment-markers-overlay", inputs: ["comments", "canvasSize"], outputs: ["markerClick"] }, { kind: "component", type: CommentsPanelComponent, selector: "pptx-comments-panel", inputs: ["comments", "authorName"], outputs: ["add", "remove", "resolve", "reply"] }, { 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: MotionPathOverlayComponent, selector: "pptx-motion-path-overlay", inputs: ["element", "animations", "canvasSize", "canEdit"], outputs: ["pathChange"] }, { 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", "activeRoomId", "activeServerUrl", "users"], outputs: ["start", "stop", "close"] }, { kind: "component", type: BroadcastDialogComponent, selector: "pptx-broadcast-dialog", inputs: ["open", "defaults", "active", "connected", "viewerCount", "viewerUrl", "p2p"], outputs: ["start", "stop", "close"] }, { kind: "component", type: MobileBottomBarComponent, selector: "pptx-mobile-bottom-bar", inputs: ["slideCount", "commentCount", "activeSheet"], outputs: ["openSlides", "insert", "openFormat", "openComments", "notes"] }, { kind: "component", type: MobileMenuSheetComponent, selector: "pptx-mobile-menu-sheet", inputs: ["open", "slideCount", "exporting", "showNotes", "canEdit", "hiddenActions"], outputs: ["closed", "openFind", "openSorter", "toggleNotes", "insertText", "present", "openFile", "savePptx", "exportPng", "exportPdf", "exportGif", "exportVideo", "print"] }, { kind: "component", type: MobileSlidesSheetComponent, selector: "pptx-mobile-slides-sheet", inputs: ["open", "slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["closed", "jumpToSlide"] }, { kind: "component", type: MobileToolbarComponent, selector: "pptx-mobile-toolbar", inputs: ["canUndo", "canRedo", "canPresent", "canEdit", "menuOpen", "aiEnabled", "aiPanelOpen", "hiddenActions"], outputs: ["toggleMenu", "toggleAiPanel", "undo", "redo", "share", "save", "present"] }, { kind: "component", type: MasterViewCanvasComponent, selector: "pptx-master-view-canvas", inputs: ["tab", "slideMasters", "activeMasterIndex", "activeLayoutIndex", "notesMaster", "handoutMaster", "canvasSize", "notesCanvasSize", "mediaDataUrls", "editable"], outputs: ["notesMasterChange", "handoutMasterChange", "slideMastersChange"] }, { kind: "component", type: MasterViewSidebarComponent, selector: "pptx-master-view-sidebar", inputs: ["tab", "slideMasters", "notesMaster", "handoutMaster", "activeMasterIndex", "activeLayoutIndex", "handoutSlidesPerPage", "editable"], outputs: ["tabChange", "selectMaster", "selectLayout", "slidesPerPageChange", "backgroundChange", "close"] }, { kind: "component", type: NotesPanelComponent, selector: "pptx-notes-panel", inputs: ["slide", "expanded", "notesStyle"], outputs: ["update", "notesToggle"] }, { kind: "component", type: RibbonComponent, selector: "pptx-ribbon", inputs: ["slideIndex", "slideCount", "canEdit", "selectedElement", "zoomPercent", "formatPainterActive", "canActivateFormatPainter", "exporting", "hasMacros", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "eyedropperActive", "themeGalleryOpen", "sidebarCollapsed", "inspectorOpen", "commentsOpen", "commentCount", "findOpen", "collabConnected", "connectedCount", "spellCheckEnabled", "showSubtitles", "hiddenActions", "aiEnabled", "aiPanelOpen", "accountAuth", "activeSlideHidden"], outputs: ["prev", "next", "zoomIn", "zoomOut", "zoomReset", "find", "present", "presenter", "record", "presentFromBeginning", "rehearseTimings", "toggleSubtitles", "openSubtitleSettings", "recordFromBeginning", "recordFromCurrent", "spellCheckChange", "share", "broadcast", "openFile", "openRecentFile", "createPresentation", "save", "savePpsx", "savePptm", "packageForSharing", "toggleSidebar", "toggleAiPanel", "signatures", "info", "print", "comments", "a11y", "shortcuts", "versionHistory", "passwordProtection", "fontEmbedding", "link", "openSorter", "openReadingView", "openOutlineView", "openMasterView", "toggleNotes", "toggleFormatPainter", "exportPng", "exportPdf", "exportGif", "exportVideo", "exportJson", "copySlideAsImage", "replace", "toggleInspector", "drawToolChange", "toggleThemeGallery", "editTheme", "openSlideSize", "toggleGrid", "toggleRulers", "toggleGuides", "toggleSelectionPane", "openCustomShows", "toggleSnapToGrid", "toggleSnapToShape", "addGuide", "zoomToFit", "toggleEyedropper", "openSmartArtDialog", "openTemplateGallery", "openEquationDialog", "openSetUpSlideShow", "toggleHideSlide", "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", "startCustomizing"], outputs: ["applyTheme", "applyCustomTheme", "close"] }, { kind: "component", type: SelectionPaneComponent, selector: "pptx-selection-pane", inputs: ["elements", "selectedIds"], outputs: ["selectElement", "bringForward", "sendBackward", "toggleHidden", "renameElement"] }, { 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: SlideTemplateGalleryDialogComponent, selector: "pptx-slide-template-gallery-dialog", inputs: ["open", "scheme"], outputs: ["close", "insert"] }, { kind: "component", type: ViewerExtraDialogsComponent, selector: "pptx-viewer-extra-dialogs", inputs: ["activeSlideIndex", "selectedElementId", "filePath", "customShows", "themeKey", "availableThemes", "localeCode", "availableLocales", "aiExportVisible"], outputs: ["restoreContent", "themeKeySelect", "localeSelect"] }, { kind: "component", type: AutosaveRecoveryDialogComponent, selector: "pptx-autosave-recovery-dialog", inputs: ["prompt"], outputs: ["restore", "discard"] }, { kind: "component", type: RehearseTimingsComponent, selector: "pptx-rehearse-timings", inputs: ["summary", "paused", "slideStartedAt", "presentationStartedAt", "timings"], outputs: ["togglePause", "save", "discard"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [/* @ts-ignore */
144124
+ `, 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", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationOverlayComponent, selector: "pptx-presentation-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "startIndex", "activeCustomShow", "showWithAnimation", "useTimings", "subtitlesVisible", "sessionEnded", "endWithBlackSlide", "presenterMode", "showMenuOnRightClick", "showPopupToolbar"], outputs: ["indexChange", "closed", "subtitlesChange", "presenterViewToggle", "annotationsExit"] }, { kind: "component", type: PresenterViewComponent, selector: "pptx-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime", "isAudienceWindowOpen"], outputs: ["movePresentationSlide", "exit", "openAudienceWindow", "closeAudienceWindow", "navigateToSlide"] }, { kind: "component", type: MobilePresenterViewComponent, selector: "pptx-mobile-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime"], outputs: ["movePresentationSlide", "exit"] }, { kind: "component", type: SlideSorterOverlayComponent, selector: "pptx-slide-sorter-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeIndex", "canEdit"], outputs: ["select", "closed", "deleteSlide", "duplicateSlide", "toggleHiddenSlide"] }, { kind: "component", type: OutlineViewOverlayComponent, selector: "pptx-outline-view-overlay", inputs: ["slides", "canvasSize", "canEdit"], outputs: ["commit", "closed"] }, { kind: "component", type: ReadingViewOverlayComponent, selector: "pptx-reading-view-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeSlideIndex"], outputs: ["exit"] }, { kind: "component", type: SlideDefaultInspectorComponent, selector: "pptx-slide-default-inspector", inputs: ["slideIndex", "canEdit", "selectedElement", "comments"], outputs: ["commentAdd", "commentRemove", "commentResolve", "commentReply"] }, { kind: "component", type: FindBarComponent, selector: "pptx-find-bar", inputs: ["slides"], outputs: ["navigate", "closed"] }, { kind: "component", type: FindReplaceBarComponent, selector: "pptx-find-replace-bar", inputs: ["matchCount", "matchIndex"], outputs: ["find", "navigate", "replaceOne", "replaceAll", "close"] }, { kind: "component", type: SlidesPanelComponent, selector: "pptx-slides-panel", inputs: ["canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select"] }, { kind: "component", type: StatusBarComponent, selector: "pptx-status-bar", inputs: ["slideIndex", "slideCount", "canEdit", "dirty", "autosaveStatus", "notesOpen", "zoomPercent", "sorterActive", "presenting", "hiddenActions"], outputs: ["toggleNotes", "normalView", "openSorter", "slideShow", "zoomIn", "zoomOut", "zoomReset"] }, { kind: "component", type: EditorContextMenuComponent, selector: "pptx-editor-context-menu", inputs: ["x", "y", "slideIndex", "showAiActions"], outputs: ["closed", "askAi", "fixAi", "editHyperlink", "addComment"] }, { kind: "component", type: ExportProgressModalComponent, selector: "pptx-export-progress-modal", inputs: ["open", "title", "progress", "statusMessage"], outputs: ["cancel"] }, { kind: "component", type: CommentMarkersOverlayComponent, selector: "pptx-comment-markers-overlay", inputs: ["comments", "canvasSize"], outputs: ["markerClick"] }, { kind: "component", type: CommentsPanelComponent, selector: "pptx-comments-panel", inputs: ["comments", "authorName"], outputs: ["add", "remove", "resolve", "reply"] }, { 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: MotionPathOverlayComponent, selector: "pptx-motion-path-overlay", inputs: ["element", "animations", "canvasSize", "canEdit"], outputs: ["pathChange"] }, { 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", "defaultSettings"], outputs: ["print", "cancel"] }, { kind: "component", type: ShareDialogComponent, selector: "pptx-share-dialog", inputs: ["open", "defaults", "active", "connected", "userCount", "shareUrl", "p2p", "activeRoomId", "activeServerUrl", "users"], outputs: ["start", "stop", "close"] }, { kind: "component", type: BroadcastDialogComponent, selector: "pptx-broadcast-dialog", inputs: ["open", "defaults", "active", "connected", "viewerCount", "viewerUrl", "p2p"], outputs: ["start", "stop", "close"] }, { kind: "component", type: MobileBottomBarComponent, selector: "pptx-mobile-bottom-bar", inputs: ["slideCount", "commentCount", "activeSheet"], outputs: ["openSlides", "insert", "openFormat", "openComments", "notes"] }, { kind: "component", type: MobileMenuSheetComponent, selector: "pptx-mobile-menu-sheet", inputs: ["open", "slideCount", "exporting", "showNotes", "canEdit", "hiddenActions"], outputs: ["closed", "openFind", "openSorter", "toggleNotes", "insertText", "present", "openFile", "savePptx", "exportPng", "exportPdf", "exportGif", "exportVideo", "print"] }, { kind: "component", type: MobileSlidesSheetComponent, selector: "pptx-mobile-slides-sheet", inputs: ["open", "slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["closed", "jumpToSlide"] }, { kind: "component", type: MobileToolbarComponent, selector: "pptx-mobile-toolbar", inputs: ["canUndo", "canRedo", "canPresent", "canEdit", "menuOpen", "aiEnabled", "aiPanelOpen", "hiddenActions"], outputs: ["toggleMenu", "toggleAiPanel", "undo", "redo", "share", "save", "present"] }, { kind: "component", type: MasterViewCanvasComponent, selector: "pptx-master-view-canvas", inputs: ["tab", "slideMasters", "activeMasterIndex", "activeLayoutIndex", "notesMaster", "handoutMaster", "canvasSize", "notesCanvasSize", "mediaDataUrls", "editable"], outputs: ["notesMasterChange", "handoutMasterChange", "slideMastersChange"] }, { kind: "component", type: MasterViewSidebarComponent, selector: "pptx-master-view-sidebar", inputs: ["tab", "slideMasters", "notesMaster", "handoutMaster", "activeMasterIndex", "activeLayoutIndex", "handoutSlidesPerPage", "editable"], outputs: ["tabChange", "selectMaster", "selectLayout", "slidesPerPageChange", "backgroundChange", "close"] }, { kind: "component", type: NotesPanelComponent, selector: "pptx-notes-panel", inputs: ["slide", "expanded", "notesStyle"], outputs: ["update", "notesToggle"] }, { kind: "component", type: QuickAccessStripComponent, selector: "pptx-quick-access-strip", inputs: ["quickAccess", "canUndo", "canRedo"], outputs: ["command"] }, { kind: "component", type: RibbonComponent, selector: "pptx-ribbon", inputs: ["slideIndex", "slideCount", "canEdit", "selectedElement", "zoomPercent", "formatPainterActive", "canActivateFormatPainter", "exporting", "hasMacros", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "eyedropperActive", "themeGalleryOpen", "sidebarCollapsed", "inspectorOpen", "commentsOpen", "commentCount", "findOpen", "collabConnected", "connectedCount", "spellCheckEnabled", "showSubtitles", "hiddenActions", "aiEnabled", "aiPanelOpen", "accountAuth", "activeSlideHidden"], 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", "toggleSidebar", "toggleAiPanel", "signatures", "info", "print", "comments", "a11y", "shortcuts", "versionHistory", "passwordProtection", "fontEmbedding", "link", "openSorter", "openReadingView", "openOutlineView", "openMasterView", "toggleNotes", "toggleFormatPainter", "exportPng", "exportPdf", "exportGif", "exportVideo", "exportJson", "copySlideAsImage", "replace", "toggleInspector", "drawToolChange", "toggleThemeGallery", "editTheme", "openSlideSize", "toggleGrid", "toggleRulers", "toggleGuides", "toggleSelectionPane", "openCustomShows", "toggleSnapToGrid", "toggleSnapToShape", "addGuide", "zoomToFit", "toggleEyedropper", "openSmartArtDialog", "openTemplateGallery", "openEquationDialog", "openSetUpSlideShow", "toggleHideSlide", "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", "startCustomizing"], outputs: ["applyTheme", "applyCustomTheme", "close"] }, { kind: "component", type: SelectionPaneComponent, selector: "pptx-selection-pane", inputs: ["elements", "selectedIds"], outputs: ["selectElement", "bringForward", "sendBackward", "toggleHidden", "renameElement"] }, { 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: SlideTemplateGalleryDialogComponent, selector: "pptx-slide-template-gallery-dialog", inputs: ["open", "scheme"], outputs: ["close", "insert"] }, { kind: "component", type: ViewerExtraDialogsComponent, selector: "pptx-viewer-extra-dialogs", inputs: ["activeSlideIndex", "selectedElementId", "filePath", "customShows", "themeKey", "availableThemes", "localeCode", "availableLocales", "aiExportVisible"], outputs: ["restoreContent", "themeKeySelect", "localeSelect"] }, { kind: "component", type: AutosaveRecoveryDialogComponent, selector: "pptx-autosave-recovery-dialog", inputs: ["prompt"], outputs: ["restore", "discard"] }, { kind: "component", type: RehearseTimingsComponent, selector: "pptx-rehearse-timings", inputs: ["summary", "paused", "slideStartedAt", "presentationStartedAt", "timings"], outputs: ["togglePause", "save", "discard"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [/* @ts-ignore */
143339
144125
  Promise.resolve().then(function () { return aiChatPanel_component; }).then(m => m.AiChatPanelComponent)]] }); }
143340
144126
  }
143341
144127
  i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ngImport: i0, type: PowerPointViewerComponent, resolveDeferredDeps: () => [/* @ts-ignore */
@@ -143384,6 +144170,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
143384
144170
  MasterViewCanvasComponent,
143385
144171
  MasterViewSidebarComponent,
143386
144172
  NotesPanelComponent,
144173
+ QuickAccessStripComponent,
143387
144174
  RibbonComponent,
143388
144175
  TitleBarComponent,
143389
144176
  ThemeGalleryComponent,
@@ -143419,6 +144206,26 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
143419
144206
  <pre class="pptx-ng-error-detail">{{ loader.error() }}</pre>
143420
144207
  </div>
143421
144208
  } @else {
144209
+ @if (protectedViewActive() && chromeVisible()) {
144210
+ <div
144211
+ class="pptx-ng-protected-view-banner flex items-center gap-3 border-b border-amber-700/30 bg-amber-900/20 px-4 py-2"
144212
+ role="status"
144213
+ >
144214
+ <span class="h-4 w-4 shrink-0 text-amber-400" aria-hidden="true">&#128274;</span>
144215
+ <p class="flex-1 text-xs text-amber-200">
144216
+ <strong>{{ 'pptx.security.protectedViewTitle' | translate }}</strong
144217
+ >:
144218
+ {{ 'pptx.options.trust.protectedViewInfo' | translate }}
144219
+ </p>
144220
+ <button
144221
+ type="button"
144222
+ class="shrink-0 rounded border border-amber-600/50 px-3 py-1 text-xs font-medium text-amber-100 transition-colors hover:bg-amber-700/30"
144223
+ (click)="enableEditing()"
144224
+ >
144225
+ {{ 'pptx.security.enableEditing' | translate }}
144226
+ </button>
144227
+ </div>
144228
+ }
143422
144229
  @if (!mobile.isMobile() && chromeVisible()) {
143423
144230
  <pptx-title-bar
143424
144231
  [canEdit]="canEdit()"
@@ -143431,7 +144238,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
143431
144238
  [undoLabel]="editor.undoLabel()"
143432
144239
  [redoLabel]="editor.redoLabel()"
143433
144240
  [findReplaceOpen]="findReplace.showFind() || findReplace.showFindReplace()"
143434
- [hiddenActions]="hiddenActions()"
144241
+ [hiddenActions]="effectiveHiddenActions()"
143435
144242
  [quickAccess]="viewerOpts.options().quickAccess"
143436
144243
  (toggleAutosave)="toggleAutosave()"
143437
144244
  (save)="fileIO.saveAsPptx()"
@@ -143446,7 +144253,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
143446
144253
  [slideCount]="slideCount()"
143447
144254
  [canEdit]="canEdit()"
143448
144255
  [selectedElement]="selectedElement()"
143449
- [hiddenActions]="hiddenActions()"
144256
+ [hiddenActions]="effectiveHiddenActions()"
143450
144257
  [zoomPercent]="zoomSvc.zoomPercent()"
143451
144258
  [formatPainterActive]="formatPainter.active()"
143452
144259
  [canActivateFormatPainter]="formatPainter.canActivate()"
@@ -143486,7 +144293,6 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
143486
144293
  (save)="fileIO.saveAsPptx()"
143487
144294
  (savePpsx)="fileIO.saveAsPpsx()"
143488
144295
  (savePptm)="fileIO.saveAsPptm()"
143489
- (packageForSharing)="fileIO.packageForSharing()"
143490
144296
  (info)="docProperties.showProperties.set(true)"
143491
144297
  (print)="print.openDialog()"
143492
144298
  (comments)="inspectorPanel.togglePanel('comments')"
@@ -143549,6 +144355,20 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
143549
144355
  [aiPanelOpen]="aiPanelOpen()"
143550
144356
  (toggleAiPanel)="aiPanelOpen.update((v) => !v)"
143551
144357
  />
144358
+
144359
+ @if (belowRibbonQuickAccess(); as belowQuickAccess) {
144360
+ <div
144361
+ class="flex items-center gap-0.5 border-b border-border/60 px-2 py-0.5"
144362
+ data-pptx-quick-access="below"
144363
+ >
144364
+ <pptx-quick-access-strip
144365
+ [quickAccess]="belowQuickAccess"
144366
+ [canUndo]="editor.canUndo()"
144367
+ [canRedo]="editor.canRedo()"
144368
+ (command)="onQuickAccessCommand($event)"
144369
+ />
144370
+ </div>
144371
+ }
143552
144372
  }
143553
144373
 
143554
144374
  @if (mobile.isMobile() && chromeVisible()) {
@@ -143560,7 +144380,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
143560
144380
  [menuOpen]="mobileSheetSvc.mobileSheet() === 'menu'"
143561
144381
  [aiEnabled]="aiEnabled()"
143562
144382
  [aiPanelOpen]="aiPanelOpen()"
143563
- [hiddenActions]="hiddenActions()"
144383
+ [hiddenActions]="effectiveHiddenActions()"
143564
144384
  (toggleMenu)="
143565
144385
  mobileSheetSvc.mobileSheet.set(
143566
144386
  mobileSheetSvc.mobileSheet() === 'menu' ? null : 'menu'
@@ -143852,7 +144672,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
143852
144672
  [zoomPercent]="zoomSvc.zoomPercent()"
143853
144673
  [sorterActive]="showSorter()"
143854
144674
  [presenting]="presentationMode.presenting()"
143855
- [hiddenActions]="hiddenActions()"
144675
+ [hiddenActions]="effectiveHiddenActions()"
143856
144676
  (toggleNotes)="mobileSheetSvc.toggleNotes()"
143857
144677
  (normalView)="showSorter.set(false)"
143858
144678
  (openSorter)="showSorter.set(true)"
@@ -143963,6 +144783,8 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
143963
144783
  [subtitlesVisible]="presentationMode.subtitlesVisible()"
143964
144784
  [sessionEnded]="audienceSessionEnded()"
143965
144785
  [endWithBlackSlide]="viewerOpts.options().advanced.slideShowEndWithBlackSlide"
144786
+ [showMenuOnRightClick]="viewerOpts.options().advanced.slideShowShowMenuOnRightClick"
144787
+ [showPopupToolbar]="viewerOpts.options().advanced.slideShowShowPopupToolbar"
143966
144788
  [presenterMode]="presentationMode.presentingPresenter()"
143967
144789
  (presenterViewToggle)="presentationMode.togglePresenterView()"
143968
144790
  (subtitlesChange)="presentationMode.subtitlesVisible.set($event)"
@@ -144113,7 +144935,14 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
144113
144935
  <pptx-print-dialog
144114
144936
  [slides]="displaySlidesMut()"
144115
144937
  [activeSlideIndex]="activeSlideIndex()"
144116
- (print)="xport.onPrint($event)"
144938
+ [defaultSettings]="viewerOpts.printDefaults()"
144939
+ (print)="
144940
+ xport.onPrint(
144941
+ $event,
144942
+ viewerOpts.options().advanced.printHiddenSlides,
144943
+ viewerOpts.options().advanced.printHighQuality
144944
+ )
144945
+ "
144117
144946
  (cancel)="print.closeDialog()"
144118
144947
  />
144119
144948
  }
@@ -144202,7 +145031,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
144202
145031
  [exporting]="xport.exporting()"
144203
145032
  [showNotes]="mobileSheetSvc.showNotes()"
144204
145033
  [canEdit]="canEdit()"
144205
- [hiddenActions]="hiddenActions()"
145034
+ [hiddenActions]="effectiveHiddenActions()"
144206
145035
  (closed)="mobileSheetSvc.mobileSheet.set(null)"
144207
145036
  (openFind)="findReplace.showFind.set(true)"
144208
145037
  (openSorter)="showSorter.set(true)"
@@ -144282,6 +145111,9 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.3", ng
144282
145111
  }], 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 }] }], autosaveInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autosave", required: false }] }], autosaveIntervalMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "autosaveIntervalMs", 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 }] }], surfaceChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceChart3D", required: false }] }], barChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "barChart3D", required: false }] }], lineChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "lineChart3D", required: false }] }], areaChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "areaChart3D", required: false }] }], pieChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "pieChart3D", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], ai: [{ type: i0.Input, args: [{ isSignal: true, alias: "ai", 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: [{
144283
145112
  type: HostListener,
144284
145113
  args: ['document:keydown', ['$event']]
145114
+ }], clearCacheOnUnload: [{
145115
+ type: HostListener,
145116
+ args: ['window:beforeunload']
144285
145117
  }] } }) });
144286
145118
 
144287
145119
  /**
@@ -146580,4 +147412,4 @@ function cn(...values) {
146580
147412
  */
146581
147413
 
146582
147414
  export { ColorChangedImageComponent as $, AFTER_ANIMATION_VALUES as A, AnimationPanelComponent as B, AnimationPlaybackService as C, AutosaveRecoveryDialogComponent as D, AutosaveService as E, BroadcastDialogComponent as F, CHART_EDITOR_STYLES as G, CURSOR_PALETTE as H, CanvasFitService as I, ChartAxisOptionsComponent as J, ChartAxisStyleOptionsComponent as K, ChartComboTypeOptionsComponent as L, ChartDataEditorComponent as M, ChartDataLabelOptionsComponent as N, ChartDatapointMarkerOptionsComponent as O, ChartDatapointOptionsComponent as P, ChartDisplayOptionsComponent as Q, ChartElementViewComponent as R, ChartErrorBarOptionsComponent as S, ChartMarkerOptionsComponent as T, ChartPartSelectionService as U, ChartPrimitivesComponent as V, ChartRendererComponent as W, ChartTrendlineOptionsComponent as X, ChartTypeSelectorComponent as Y, CollaborationCursorsComponent as Z, CollaborationService as _, ALIGN_OPTIONS as a, KeepAnnotationsDialogComponent as a$, CommentMarkersOverlayComponent as a0, CommentsPanelComponent as a1, CommentsService as a2, ComparePanelComponent as a3, ConnectorRendererComponent as a4, ConnectorTextOverlayComponent as a5, CustomShowsComponent as a6, DEFAULT_BOUNDS as a7, DEFAULT_BROADCAST_SERVER_URL as a8, DEFAULT_CANVAS_HEIGHT as a9, ElementRendererComponent as aA, EmbeddedFontsService as aB, EncryptedFileDialogComponent as aC, EquationEditorDialogComponent as aD, EquationRendererComponent as aE, EquationTemplateGalleryComponent as aF, ExportProgressModalComponent as aG, ExportService as aH, FieldContextService as aI, FindBarComponent as aJ, FindReplaceBarComponent as aK, FollowModeBarComponent as aL, FontEmbeddingListComponent as aM, FontEmbeddingPanelComponent as aN, GALLERY_THEME_PRESETS as aO, GRIDLINE_COLOR$1 as aP, GradientPickerComponent as aQ, HANDOUT_OPTIONS as aR, HeaderFooterDialogComponent as aS, HyperlinkDialogComponent as aT, ImagePropertiesPanelComponent as aU, InkDrawingService as aV, InkRendererComponent as aW, InsertSmartArtDialogComponent as aX, InspectorPaneHeaderComponent as aY, InspectorPanelComponent as aZ, IsMobileService as a_, DEFAULT_CANVAS_WIDTH as aa, DEFAULT_COLOR_SCHEME as ab, DEFAULT_FILL_COLOR$1 as ac, DEFAULT_LAYOUT as ad, DEFAULT_PALETTE$1 as ae, DEFAULT_PATTERN_FILL_PRESET as af, DEFAULT_PRINT_SETTINGS as ag, DEFAULT_SLIDE_BACKGROUND as ah, DEFAULT_STROKE_COLOR as ai, DEFAULT_STYLE as aj, DEFAULT_TABLE_ROW_HEIGHT as ak, DEFAULT_TEXT_COLOR$2 as al, DEFAULT_VIEWER_PROFILE as am, DIRECTIONAL_PRESETS as an, DIRECTION_OPTIONS as ao, DocumentPropertiesCardComponent as ap, EMBEDDED_FONTS_STYLE_ID as aq, EMPHASIS_PRESETS as ar, ENTRANCE_PRESETS as as, TEMPLATES as at, EXIT_PRESETS as au, EditorContextMenuComponent as av, EditorHistory as aw, EditorStateService as ax, EditorToolbarComponent as ay, EffectsPanelComponent as az, ANIMATION_PRESET_CATEGORIES as b, RibbonDrawSectionComponent as b$, LOCALE_CATALOG as b0, LONG_PRESS_DURATION_MS as b1, LONG_PRESS_MOVE_TOLERANCE_PX as b2, LoadContentService as b3, LocalPresencePublisher as b4, MAX_ZOOM_SCALE as b5, MIN_ZOOM_SCALE as b6, MOTION_PATH_COLUMNS as b7, MediaPreviewComponent as b8, MediaPropertiesPanelComponent as b9, PresentToolbarAutoHide as bA, PresentationAnnotationOverlayComponent as bB, PresentationAnnotationsService as bC, PresentationOverlayComponent as bD, PresentationPropertiesPanelComponent as bE, PresentationSettingsCardComponent as bF, PresentationSubtitleBarComponent as bG, PresentationToolbarComponent as bH, PresentationTransitionOverlayComponent as bI, PresenterViewComponent as bJ, PresenterWindowService as bK, PrintDialogComponent as bL, PrintService as bM, PrintSettingsPanelComponent as bN, PropertiesDialogComponent as bO, REPEAT_MODE_OPTIONS as bP, RESIZE_HANDLES as bQ, RULER_FONT_SIZE as bR, RULER_THICKNESS as bS, ReadingViewOverlayComponent as bT, RemoteSelectionOverlayComponent as bU, RibbonAnimationGalleryComponent as bV, RibbonAnimationsSectionComponent as bW, RibbonArrangeSectionComponent as bX, RibbonColorPopoverComponent as bY, RibbonComponent as bZ, RibbonDesignSectionComponent as b_, MediaRendererComponent as ba, MediaTrimTimelineComponent as bb, MobileBottomBarComponent as bc, MobileMenuSheetComponent as bd, MobilePresenterViewComponent as be, MobileSheetComponent as bf, MobileSlidesSheetComponent as bg, MobileToolbarComponent as bh, ModalDialogComponent as bi, Model3DRendererComponent as bj, NotesHandoutCardComponent as bk, NotesPanelComponent as bl, NotesToolbarComponent as bm, OleRendererComponent as bn, OutlineViewOverlayComponent as bo, POWER_POINT_VIEWER_PROVIDERS as bp, PPTX_OPEN_ACCEPT as bq, PRESENTATION_OPEN_EXTENSIONS as br, PRESENTER_CHANNEL_NAME as bs, PRESENTER_MSG_ORIGIN as bt, PRESENTER_TIMER_SEGMENT_MS as bu, PX_PER_CM as bv, PX_PER_INCH as bw, PasswordProtectionDialogComponent as bx, PasswordStrengthMeterComponent as by, PowerPointViewerComponent as bz, AUDIENCE_HASH as c, THEME_CATALOG as c$, RibbonDrawingGroupComponent as c0, RibbonEditingSectionComponent as c1, RibbonFileSectionComponent as c2, RibbonFontControlsComponent as c3, RibbonHomeSectionComponent as c4, RibbonHyperlinkButtonComponent as c5, RibbonInsertFieldsComponent as c6, RibbonInsertSectionComponent as c7, RibbonMotionPathGalleryComponent as c8, RibbonParagraphControlsComponent as c9, ShortcutPanelComponent as cA, ShowOptionsFieldsetComponent as cB, ShowSlidesFieldsetComponent as cC, SignatureStrippedDialogComponent as cD, SignaturesPanelComponent as cE, SignaturesService as cF, SlideBackgroundCardComponent as cG, SlideCanvasComponent as cH, SlideDefaultInspectorComponent as cI, SlideDiffChangesComponent as cJ, SlideDiffRowComponent as cK, SlideDiffThumbnailsComponent as cL, SlideSizeCardComponent as cM, SlideSorterOverlayComponent as cN, SlideThemeOverridePanelComponent as cO, SlideTransitionCardComponent as cP, SlidesPanelComponent as cQ, SmartArt3DRendererComponent as cR, SmartArt3DService as cS, SmartArtPreviewComponent as cT, SmartArtPropertiesComponent as cU, SmartArtRendererComponent as cV, StatusBarComponent as cW, TABLE_STRUCTURE_TOGGLES as cX, TEXT_3D_BOTTOM_BEVEL_KEYS as cY, TEXT_3D_TOP_BEVEL_KEYS as cZ, TEXT_DIRECTION_OPTIONS$1 as c_, RibbonPrimaryRowComponent as ca, RibbonReviewSectionComponent as cb, RibbonShapeExtrasComponent as cc, RibbonSlideshowSectionComponent as cd, RibbonTransitionsSectionComponent as ce, RibbonViewSectionComponent as cf, RulerGuidesService as cg, SEQUENCE_OPTIONS as ch, SEVERITY_GROUPS as ci, SEVERITY_LABELS as cj, SHORTCUT_REFERENCE_ITEMS as ck, SLIDE_TRANSITION_KEYFRAMES as cl, DEFAULT_PALETTE as cm, PALETTES$1 as cn, SMART_ART_COLOR_SCHEMES as co, SMART_ART_STYLE_OPTIONS as cp, SUB_ITEM_LABEL as cq, SVG_WARP_PRESETS as cr, SWIPE_MAX_VERTICAL_PX as cs, SWIPE_THRESHOLD_PX as ct, SelectionPaneComponent as cu, SetUpSlideShowDialogComponent as cv, SettingsAppearanceTabComponent as cw, SettingsDialogComponent as cx, SettingsLanguageTabComponent as cy, ShareDialogComponent as cz, AUDIENCE_NONCE_KEY as d, applyAcceptedDiff as d$, TIMING_CURVE_OPTIONS as d0, TRIGGER_OPTIONS as d1, TYPE_LABELS as d2, TableCellAdvancedFillComponent as d3, TableCellFormattingComponent as d4, TableDataEditorComponent as d5, TablePropertiesComponent as d6, TableRendererComponent as d7, TableResizeOverlayComponent as d8, TableSelectionService as d9, ViewerFormatPainterService as dA, ViewerInspectorPanelService as dB, ViewerKeyboardService as dC, ViewerMobileSheetService as dD, ViewerPresentationModeService as dE, ViewerThemeGalleryService as dF, ViewerTouchGesturesService as dG, ViewerZoomService as dH, WEBM_MIME_CANDIDATES as dI, WriteBackScheduler as dJ, ZERO_LINE_COLOR as dK, ZoomNavigationService as dL, ZoomRendererComponent as dM, ZoomTargetService as dN, addCategory as dO, addCommentToList as dP, addGradientStopPatch as dQ, addItem as dR, addSeries as dS, addSubItem as dT, advanceStep as dU, affordanceElements as dV, aiToggleVisible as dW, alignPatch as dX, animationFor as dY, animationPresetLabelKey as dZ, annotationMapToInkInserts as d_, TagsCardComponent as da, Text3DBevelSectionComponent as db, Text3DPanelComponent as dc, TextAdvancedPanelComponent as dd, ThemeEditorFieldsComponent as de, ThemeGalleryComponent as df, ThemeSelectorCardComponent as dg, TitleBarComponent as dh, TitleBarSearchComponent as di, TransitionDirectionPickerComponent as dj, TransitionPreviewComponent as dk, VALIGN_OPTIONS as dl, VIEWER_THEME as dm, VersionHistoryPanelComponent as dn, ViewerCanvasEditingService as dp, ViewerCollabCursorService as dq, ViewerCollaborationSessionService as dr, ViewerCompareService as ds, ViewerCustomShowsService as dt, ViewerDialogsService as du, ViewerDocumentPropertiesService as dv, ViewerExportService as dw, ViewerExtraDialogsComponent as dx, ViewerFileIOService as dy, ViewerFindReplaceService as dz, AVATAR_COLOR_SWATCHES as e, buildZoomContainerStyle as e$, applyAnimationPreset as e0, applyFindReplacements as e1, applyFormatToElement as e2, applyMove as e3, applyResize as e4, asMediaElement as e5, assignUserColor as e6, attachShowVisibilityPause as e7, attachTouchGestures as e8, axisTickValues as e9, buildFontFaceRule as eA, buildGradientFillCss as eB, buildGridlinesAndLabels as eC, buildHyperlinkPatch as eD, buildInkContainerStyle as eE, buildInkStrokes as eF, buildLegend as eG, buildMarkTooltip as eH, buildModel3DContainerStyle as eI, buildModel3DViewModel as eJ, buildOleActionModel as eK, buildOleInfoRows as eL, buildPatternFillCss as eM, buildPrintHtmlDocument as eN, buildPropertiesPatch as eO, buildRegionMapViewModel as eP, buildSaveSlides as eQ, buildShareUrl as eR, buildSmartArtInsertElement as eS, buildSmartArtNodes as eT, buildStockViewModel as eU, buildSurfaceViewModel as eV, buildTableViewModel as eW, buildTreemapViewModel as eX, buildTrimFragment as eY, buildWaterfallViewModel as eZ, buildZeroLine as e_, beginNodeEdit as ea, bevelSizePatch as eb, boolFromEvent as ec, bringForward as ed, bringToFront as ee, buildBarActions as ef, buildBroadcastConfig as eg, buildBroadcastViewerUrl as eh, buildCategoryLabels as ei, buildCellParagraphs as ej, buildChartViewModel as ek, buildChatLogExport as el, buildChatLogMarkdown as em, buildChromeStyle as en, buildClearHyperlinkPatch as eo, buildClickGroups as ep, buildColStyles as eq, buildCollaborationConfig as er, buildComboViewModel as es, buildCssGradientFromShapeStyle as et, buildDuotoneFilter as eu, buildDuotoneFilterId as ev, buildEmbeddedFontStyles as ew, buildEquationElement as ex, buildEquationSegment as ey, buildFallbackViewModel as ez, AXIS_LABEL_COLOR as f, computeSingleSelected as f$, buildZoomViewModel as f0, bulletIndentPx as f1, canAddTopLevelNode as f2, canGroupSelection as f3, canRemoveTopLevelNode as f4, canSetStrokeWidth as f5, canStartBroadcast as f6, canStartShare as f7, canUngroupSelection as f8, canUseClipboard as f9, computeAxisTitlePrimitives as fA, computeBarRects as fB, computeBubbleRadius as fC, computeCornerHandle as fD, computeDistribute as fE, computeDrawingViewBox as fF, computeErrorBarPrimitives as fG, computeFocusTargets as fH, computeGridSpacingPx as fI, computeHandleBoxes as fJ, computeHandoutLayout as fK, computeIsMobile as fL, computeIsTablet as fM, computeLinePoints as fN, computeLinearRegression as fO, computePageCount as fP, computePieLayout as fQ, computePieSlicePath as fR, computePieSlices as fS, computePlotLayout as fT, computeRSquared as fU, computeRadarPoints as fV, computeResizeHandleBoxes as fW, computeRotateHandleBox as fX, computeScatterDots as fY, computeScatterXDomain as fZ, computeSelectionBoxes as f_, captionDisplayText as fa, cellRunStyle as fb, cellStyleToStyleMap as fc, cellTdStyle as fd, changeCountLabel as fe, changeIcon as ff, characterSpacingPatch as fg, chartPreserveAspectRatio as fh, checkFontAvailable as fi, clampCursorPosition as fj, clampGifDimensions as fk, clampIndex as fl, clampNotesFontSize as fm, clampScale as fn, clampStep as fo, clearAllLocalViewerData as fp, clearAudienceContent as fq, cn as fr, collectAccessibilityIssues as fs, collectElementText as ft, collectSlideText as fu, collectStoredChats as fv, collectUsedFontFamilies as fw, columnWidthStyle as fx, commitNodeText as fy, computeAlign as fz, AccessibilityPanelComponent as g, formatFileSize as g$, computeSlideIndices as g0, computeSnap as g1, computeStackedBarRects as g2, computeStackedValueRange as g3, computeTrendlinePrimitives as g4, computeValueRange as g5, convertOmmlToMathMl as g6, copyFormatFromElement as g7, countAccessibilityIssues as g8, countAnnotationStrokes as g9, enableGlowPatch as gA, enableInnerShadowPatch as gB, enableOuterShadowPatch as gC, enableReflectionPatch as gD, enableSoftEdgePatch as gE, encodeGif as gF, endShowMediaCleanup as gG, estimatePageCount as gH, exitPresentationFullscreen as gI, exportAiChatLogs as gJ, extractPathPoints as gK, eyedropperAvailable as gL, fillColorOf$1 as gM, findInSlides as gN, findOwningSlideIndex as gO, findSlideIndexByElementId as gP, firstVisibleIndex as gQ, fitPolynomial as gR, fitZoom as gS, focusTargetChips as gT, fontMimeForFormat as gU, fontSizeOf as gV, forgetSessionDeck as gW, formatAxisValue as gX, formatBytes as gY, formatCursorLabel as gZ, formatElapsed as g_, createAngularAiBridge as ga, createCustomShow as gb, createSwipeDismissDrag as gc, createWebrtcBundle as gd, createWebsocketBundle as ge, cssObjectToStyleMap as gf, currentColorScheme as gg, currentLayout as gh, currentStyle as gi, defaultCssVars as gj, defaultRadius as gk, defaultThemeColors as gl, deleteElementsByIds as gm, deleteVersion as gn, demoteNode as go, deriveModel3DBlobUrl as gp, derivePresenceList as gq, describeSmartArtBounds as gr, disableGlowPatch as gs, disableInnerShadowPatch as gt, disableOuterShadowPatch as gu, disableReflectionPatch as gv, disableSoftEdgePatch as gw, duplicateElementById as gx, durationOf as gy, effectsStateOf as gz, AccessibilityService as h, isPpactionUrl as h$, formatPropertyDate as h0, formatTime as h1, fpsToFrameIntervalMs as h2, generateBroadcastRoomId as h3, generateCommentId as h4, generateCustomShowId as h5, generatePressureCircles as h6, generateTicks as h7, getClrChangeParams as h8, getContainerStyle as h9, getWarpPath as hA, gradientStateFromStyle as hB, gradientStateOf as hC, gradientStatePatch as hD, gridColumns as hE, groupIssuesBySeverity as hF, hasAnimation as hG, hasCopyableFormat as hH, hasExistingLink as hI, hasExitedFullscreen as hJ, hasGradientFill as hK, hasPressureVariation as hL, hasVisibleSlideAfter as hM, headerLabel as hN, imageDimensions as hO, inkViewBox as hP, insertTableElementColumn as hQ, insertTableElementRow as hR, interpolateWidth as hS, isAudienceTab as hT, isBold as hU, isBrowserOpenableMime as hV, isChildNode as hW, isElementInteractive as hX, isInjectableUrl as hY, isItalic as hZ, isLegacyBinaryPresentation as h_, getDuotoneFilterDef as ha, getEffectSoundState as hb, getImageSrc as hc, getLocalStorageUsageSummary as hd, getOleAriaLabel as he, getOleBadgeLabel as hf, getOleDisplayName as hg, getOleDownloadFileName as hh, getOleTypeColor as hi, getOleTypeLabel as hj, getPasswordStrength as hk, getPatternSvg as hl, getPlaceholderStyle as hm, getVersions as hn, getResolvedShapeClipPath as ho, getResolvedShapeClipPathFor as hp, getSessionTabId as hq, getShapeFillStrokeStyle as hr, getSlideBackgroundStyle as hs, getSlideTransitionAnimations as ht, getSmartArtNodeBounds as hu, getSpeechRecognitionCtor as hv, getTextBlockStyle as hw, getTextWarp as hx, getTouchDistance as hy, getWarpCategory as hz, AccountPageComponent as i, patchChartData as i$, isPresenterMessage as i0, isSigned as i1, isSupportedPresentationFile as i2, isTextElement as i3, isTwoTableFocus as i4, isUnderline as i5, isUrlSafe as i6, isValidRoomId as i7, isViewportBackgroundPressTarget as i8, isZoomActivationKey as i9, newChartElement as iA, newEquationElement as iB, newPresetShapeElement as iC, newShapeElement as iD, newSmartArtElement as iE, newTableElement as iF, newTextElement as iG, nextVisibleIndex as iH, nodeBold as iI, nodeEditBox as iJ, nodeFillColor as iK, nodeFontColor as iL, nodeIdFromKey as iM, nodeItalic as iN, nodeStyle as iO, normalizeFontFormat as iP, normalizeSlidesPerPage as iQ, normalizeValue as iR, numFromEvent as iS, ommlToMathml as iT, ooxmlDashToCssBorderStyle as iU, openNativeEyeDropper as iV, overallStatus as iW, paletteColor as iX, parseAudienceNonce as iY, parseNodeTextarea as iZ, partitionSlides as i_, issueTrackKey as ia, issueTypeLabel as ib, keyToLabel as ic, lastVisibleIndex as id, latexToMathml as ie, layoutConnectorPaints as ig, layoutNodeLabels as ih, linePointsToSvgString as ii, lineSpacingPatch as ij, loadAudienceContent as ik, loadSessionDeck as il, mediaFallbackFor as im, mediaSurfaceFor as io, mergeCaptionResults as ip, mergeDown as iq, mergeRight as ir, mergeSelection as is, moveElementBy as it, moveNodeDown as iu, moveNodeUp as iv, msToFrameDelayCs as iw, narrowToCircle as ix, narrowToPolygon as iy, narrowToRect as iz, ActionSettingsPanelComponent as j, rulerDragToGuidePosition as j$, patchChartStyle as j0, patchTableData as j1, patchTextStyle as j2, patternPresetOptions as j3, pendingElementStyles as j4, pickColorByClickFallback as j5, pickFile as j6, pickSupportedMimeType as j7, planGifFrames as j8, planVideoSegments as j9, removeSeries as jA, renderToCanvas as jB, reorderAnimationDown as jC, reorderAnimationUp as jD, replaceInSlides as jE, replaceMatch as jF, requestPresentationFullscreen as jG, resizeElement as jH, resolveCaptionTracks as jI, resolveChartKind as jJ, resolveFontVariant as jK, resolveHyperlinkHref as jL, resolveInteractiveElementId as jM, resolveMediaSrc as jN, resolveOleType as jO, resolveParagraphBullet as jP, resolvePresenterNotes as jQ, resolveProfileInitial as jR, resolveRegionCode as jS, resolveSlideAutoAdvanceMs as jT, resolvePalette as jU, resolveThemeCatalogEntry as jV, resolveTransitionDuration as jW, restoreSessionDeck as jX, revealedElementStyles as jY, routeOrthogonalConnector as jZ, rowStyle as j_, pointsToSvgPathD as ja, presenceToCursors as jb, presentationBaseName as jc, presentationStageStyle as jd, presenterTimerProgress as je, presetByLayout as jf, presetsForCategory as jg, pressuresToWidths as jh, prevVisibleIndex as ji, projectDrawingShapes as jj, promoteNode as jk, provideViewerTheme as jl, radarAngle as jm, radarRingPoints as jn, readAsDataUrl as jo, recordWebm as jp, registerCrossSlideAudio as jq, rememberSessionDeck as jr, removeAnimation as js, removeCategory as jt, removeTableElementColumn as ju, removeCommentFromList as jv, removeElementAnimation as jw, removeGradientStopPatch as jx, removeNode as jy, removeTableElementRow as jz, AdvancedChartEditorComponent as k, sheetAfterNavigate as k$, rulerHighlight as k0, rulerStripTicks as k1, sampleColorFromSlide as k2, sanitizeColor as k3, sanitizeSlideIndex as k4, sanitizeUserName as k5, saveViewerProfile as k6, savedPresentationFileName as k7, scanAvailableFonts as k8, searchSlides as k9, setDataPointMarker as kA, setDelay as kB, setDirection as kC, setDuration as kD, setEffectSound as kE, setElementPosition as kF, setGridlineStyle as kG, setLayout as kH, setLegend as kI, setNodeStyle as kJ, setNodeText as kK, setRepeatCount as kL, setRepeatMode as kM, setSequence as kN, setSeriesChartType as kO, setSeriesColor as kP, setSeriesErrorBars as kQ, setSeriesMarker as kR, setSeriesName as kS, setSeriesTrendline as kT, setSeriesValue as kU, setStyle as kV, setTimingCurve as kW, setTitle as kX, setTrigger as kY, setTriggerShapeId as kZ, shapeStylePatch$1 as k_, seedBroadcastFields as ka, seedHyperlinkDraft as kb, seedPropertiesDraft as kc, seedShareFields as kd, segmentFrameCount as ke, selectValue$2 as kf, sendBackward as kg, sendToBack as kh, sequentialColorScale as ki, serializeWriteBack as kj, seriesColor as kk, setAfterAnimation as kl, setAfterAnimationColor as km, setAnimationEmphasis as kn, setAnimationEntrance as ko, setAnimationExit as kp, setAxis as kq, setAxisLogScale as kr, setAxisTitleStyle as ks, setCategoryLabel as kt, setCellText as ku, setColorScheme as kv, setDataLabels as kw, setDataPointExplosion as kx, setDataPointFill as ky, setDataPointLabel as kz, AiChangeOverlayComponent as l, shouldBlockClickAdvance as l0, shouldUseSvgWarp as l1, showDirectionPicker as l2, showsTemplateAffordance as l3, signatureCountLabel as l4, signatureKey as l5, signatureTimestamp as l6, signerName as l7, statusLabel as l8, slideNumberOf as l9, toggleCommentResolvedInList as lA, toggleNodeBold as lB, toggleNodeItalic as lC, toggleSheet as lD, topLevelNodeCount as lE, transformSelectedTextCase as lF, translationsEn as lG, updateElementById as lH, updateGlowPatch as lI, updateGradientStopPatch as lJ, updateInnerShadowPatch as lK, updateOuterShadowPatch as lL, updateReflectionPatch as lM, vAlignPatch as lN, validatePassword as lO, validatePrintSettings as lP, validateRoomId as lQ, valueToY as lR, vermilionDarkColors as lS, vermilionDarkTheme as lT, vermilionLightColors as lU, vermilionLightTheme as lV, vermilionRadius as lW, waypointsToPathD as lX, worstStatus as lY, zoomTargetSlideIndex as lZ, slidesWithReappliedLayout as la, smartArtNodes as lb, paletteColour as lc, snapToGridStep as ld, splitCursorCell as le, splitMergedCell as lf, statusKind as lg, statusLabel$1 as lh, storeAudienceContent as li, stringFromEvent$5 as lj, strokeColorOf as lk, strokeToInkElement as ll, strokeWidthOf as lm, styleShadowFilter as ln, surfaceColor as lo, textAdvancedPatch as lp, textAdvancedStateFromStyle as lq, textAdvancedStateOf as lr, textColorOf as ls, textDirectionPatch as lt, textStyleOf as lu, textStylePatch as lv, themeStyle as lw, themeToCssVars as lx, thumbnailHeight as ly, thumbnailZoom as lz, AiChatPanelComponent as m, AiChatService as n, AiComposerComponent as o, AiFocusBarComponent as p, AiFocusHighlightOverlayComponent as q, AiHistoryMenuComponent as r, AiHistoryService as s, toChatSummary as t, AiMessageListComponent as u, AiPanelStore as v, AiProposalCardComponent as w, AiSettingsSectionComponent as x, AiToolCallCardComponent as y, AnimationAuthorPanelComponent as z };
146583
- //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-BUPmXMSm.mjs.map
147415
+ //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-MUEM_FFu.mjs.map