pptx-angular-viewer 4.3.0 → 4.4.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.
@@ -2,7 +2,7 @@ import { NgStyle, NgTemplateOutlet, NgClass } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
3
  import { InjectionToken, input, output, inject, computed, ChangeDetectionStrategy, Component, signal, Injectable, DestroyRef, viewChild, effect, Injector, untracked, ElementRef, HostListener, afterNextRender, Renderer2, ViewEncapsulation, CUSTOM_ELEMENTS_SCHEMA, Directive, forwardRef, linkedSignal } from '@angular/core';
4
4
  import { TranslateService, TranslatePipe, translate } from '@ngx-translate/core';
5
- import { THEME_PRESETS, guideEmuToPx, evaluateCustomGeometryPathData, getShapeClipPath, getAdjustmentAwareClipPath, getShapeClipPathFromPreset, getCloudPathForRendering, evaluateCustomGeometryPaths, customGeometryPathsToSvgSubpaths, evaluatePresetShape, hasShapeProperties, ooxmlGradientAngleToCssDegrees, getShapeType, isImageLikeElement as isImageLikeElement$1, getElementTextContent, getRoundRectRadiusPx as getRoundRectRadiusPx$1, applyDrawingColorTransforms as applyDrawingColorTransforms$1, hslToRgb as hslToRgb$1, PRESET_COLOR_MAP, getSubstituteFontFamily, parsePanoseString, hasTextProperties, evaluateGuides, deobfuscateFont, detectFontFormat, stripXmlOrderSuffix, orderedXmlKey, parseDataUrlToBytes, sampleFirstPixelColorFromBytes, flattenChartUserShapes, chartDataChangeType, isParetoChartData, resolveDisplayedChartTypeName, chartDataAddSeries, chartDataRemoveSeries, chartDataAddCategory, chartDataRemoveCategory, chartDataUpdatePoint, resolveThemeColorRef, rebuildTableStructureInRawXml, updateCellTextInRawXml, deepCloneData, cloneTemplateElementsBySlideId, cloneSlide, MIN_ELEMENT_SIZE as MIN_ELEMENT_SIZE$1, EMU_PER_PX as EMU_PER_PX$2, DEFAULT_POWERPOINT_TABLE_STYLE_ID, DEFAULT_SCHEME_COLOR_MAP as DEFAULT_SCHEME_COLOR_MAP$1, formatAutoNumberMarker, createAutoNumberSequence, nextAutoNumber, breakAutoNumberRun, ELEMENT_PARAGRAPH_GEOMETRY_KEYS, getLinkedTextBoxSegments, deriveSlideTitle, svgPathToPolygons, THEME_COLOR_SCHEME_KEYS, createBuiltinVariables, resolveCoordinate, getPresetConnectionSites, getConnectorPathGeometry, resolveCustomGeometryToken, resolveCustomGeometryGuideContext, lookupPresetShape, normalizeStShapeType, PptxHandler, styleStroke, strokeFor, fitFontSize, nodeTextStyle, truncate, nodeOpacity, nodeStroke, nodeFill, styleShadow, buildTree, treeWidth, treeDepth, gearPoints, flattenNodes, interpretSmartArtLayout, addSmartArtNode, removeSmartArtNode, demoteSmartArtNode, promoteSmartArtNode, reorderSmartArtNode, createEditorId, makeStoreAwareId, reassignDescendantIds, checkMissingAltText, checkMissingSlideTitle, checkLowContrast, checkComplexTables, checkBlankSlide, checkDuplicateTitles, createChartElement, createImageElement, THEME_COLOR_PALETTE_COLUMNS, hexToRgbChannels as hexToRgbChannels$2, rgbToHsl as rgbToHsl$1, renameSlideMaster, deleteSlideMaster, duplicateSlideMaster, insertSlideMaster, renameLayout, deleteLayout, duplicateLayout, insertLayout, detectFileFormat, cloneElement, duplicateElement, resolveModifyVerifierAlgorithmName, verifyModifyPassword, TABLE_STYLE_PART_SEQUENCE, serializePptxToJson, PPTX_JSON_MIME_TYPE, PptxMarkdownConverter, ThemePresets, formatCommentTimestamp as formatCommentTimestamp$1, EncryptedFileError, decodeXmlEntities, parseSignatureXml, groupElements, ungroupElements, updateSmartArtNodeText, setSmartArtNodeStyle, isInkElement, isZoomElement, SvgExporter, applyThemeToData, reResolveElementColors, pptxActionToElementAction, elementActionToPptxAction, setChartTitle, setChartLegend, setChartDataLabels, setChartAxis, setChartSeriesTrendline, setChartSeriesErrorBars, setChartDataPointLabel, setChartAxisLogScale, setChartAxisTitleStyle, setChartAxisGridlineStyle, setChartSeriesMarker, setChartSeriesChartType, setChartDataPointFill, setChartDataPointMarker, setChartDataPointExplosion, getOleSheetGrid, getOleDocumentParagraphs, getOleNestedDeckDetail, applyOleSheetCellEdit, applyOleDocumentParagraphEdit, applyOleNestedDeckElementTextEdit, replaceOleFile, getOleObjectTypeLabel, addSmartArtNodeAsChild, switchSmartArtLayout, SWITCHABLE_LAYOUT_TYPES, normalizeTableStyleGuid, createTableStyleEntry, addTableStyleToMap, deleteTableStyleFromMap, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, applyThemeOverrideToSlide, TRANSITION_VALID_DIRECTIONS } from 'pptx-viewer-core';
5
+ import { THEME_PRESETS, guideEmuToPx, evaluateCustomGeometryPathData, getShapeClipPath, getAdjustmentAwareClipPath, getShapeClipPathFromPreset, getCloudPathForRendering, evaluateCustomGeometryPaths, customGeometryPathsToSvgSubpaths, evaluatePresetShape, hasShapeProperties, ooxmlGradientAngleToCssDegrees, getShapeType, isImageLikeElement as isImageLikeElement$1, getElementTextContent, getRoundRectRadiusPx as getRoundRectRadiusPx$1, applyDrawingColorTransforms as applyDrawingColorTransforms$1, hslToRgb as hslToRgb$1, PRESET_COLOR_MAP, getSubstituteFontFamily, parsePanoseString, hasTextProperties, evaluateGuides, deobfuscateFont, detectFontFormat, stripXmlOrderSuffix, orderedXmlKey, parseDataUrlToBytes, sampleFirstPixelColorFromBytes, flattenChartUserShapes, chartDataChangeType, isParetoChartData, resolveDisplayedChartTypeName, chartDataAddSeries, chartDataRemoveSeries, chartDataAddCategory, chartDataRemoveCategory, chartDataUpdatePoint, resolveThemeColorRef, rebuildTableStructureInRawXml, updateCellTextInRawXml, deepCloneData, cloneTemplateElementsBySlideId, cloneSlide, MIN_ELEMENT_SIZE as MIN_ELEMENT_SIZE$1, EMU_PER_PX as EMU_PER_PX$2, DEFAULT_POWERPOINT_TABLE_STYLE_ID, DEFAULT_SCHEME_COLOR_MAP as DEFAULT_SCHEME_COLOR_MAP$1, formatAutoNumberMarker, createAutoNumberSequence, nextAutoNumber, breakAutoNumberRun, ELEMENT_PARAGRAPH_GEOMETRY_KEYS, getLinkedTextBoxSegments, deriveSlideTitle, svgPathToPolygons, THEME_COLOR_SCHEME_KEYS, createBuiltinVariables, resolveCoordinate, getPresetConnectionSites, getConnectorPathGeometry, resolveCustomGeometryToken, resolveCustomGeometryGuideContext, lookupPresetShape, normalizeStShapeType, PptxHandler, styleStroke, strokeFor, fitFontSize, nodeTextStyle, truncate, nodeOpacity, nodeStroke, nodeFill, styleShadow, buildTree, treeWidth, treeDepth, gearPoints, flattenNodes, interpretSmartArtLayout, addSmartArtNode, removeSmartArtNode, demoteSmartArtNode, promoteSmartArtNode, reorderSmartArtNode, createEditorId, makeStoreAwareId, reassignDescendantIds, checkMissingAltText, checkMissingSlideTitle, checkLowContrast, checkComplexTables, checkBlankSlide, checkDuplicateTitles, createChartElement, createImageElement, THEME_COLOR_PALETTE_COLUMNS, hexToRgbChannels as hexToRgbChannels$2, rgbToHsl as rgbToHsl$1, renameSlideMaster, deleteSlideMaster, duplicateSlideMaster, insertSlideMaster, renameLayout, deleteLayout, duplicateLayout, insertLayout, detectFileFormat, cloneElement, duplicateElement, resolveModifyVerifierAlgorithmName, verifyModifyPassword, TABLE_STYLE_PART_SEQUENCE, serializePptxToJson, PPTX_JSON_MIME_TYPE, PptxMarkdownConverter, ThemePresets, formatCommentTimestamp as formatCommentTimestamp$1, EncryptedFileError, decodeXmlEntities, parseSignatureXml, groupElements, ungroupElements, updateSmartArtNodeText, setSmartArtNodeStyle, isInkElement, isZoomElement, SvgExporter, applyThemeToData, reResolveElementColors, pptxActionToElementAction, elementActionToPptxAction, setChartTitle, setChartLegend, setChartDataLabels, setChartAxis, setChartSeriesTrendline, setChartSeriesErrorBars, setChartDataPointLabel, setChartAxisLogScale, setChartAxisTitleStyle, setChartAxisGridlineStyle, setChartSeriesMarker, setChartSeriesChartType, setChartDataPointFill, setChartDataPointMarker, setChartDataPointExplosion, getOleSheetGrid, getOleDocumentParagraphs, getOleNestedDeckDetail, applyOleSheetCellEdit, applyOleDocumentParagraphEdit, applyOleNestedDeckElementTextEdit, replaceOleFile, getOleObjectTypeLabel, addSmartArtNodeAsChild, switchSmartArtLayout, SWITCHABLE_LAYOUT_TYPES, normalizeTableStyleGuid, createTableStyleEntry, addTableStyleToMap, deleteTableStyleFromMap, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, applyThemeOverrideToSlide, TRANSITION_VALID_DIRECTIONS, TRANSITION_PATTERN_OPTIONS, TRANSITION_THRUBLK_TYPES } from 'pptx-viewer-core';
6
6
  import { parse } from 'opentype.js';
7
7
  import DOMPurify from 'dompurify';
8
8
  import { z } from 'zod';
@@ -11,8 +11,8 @@ import * as mcpSchemas from 'pptx-viewer-mcp/schemas';
11
11
  import { LucideX, LucideSquare, LucideCircle, LucideSlash, LucideCopy, LucideTrash2, LucideChevronsUp, LucideChevronsDown, LucideArrowUp, LucideArrowDown, LucideGroup, LucideUngroup, LucideTextAlignStart, LucideTextAlignCenter, LucideTextAlignEnd, LucideChevronUp, LucideChevronDown, LucideAlignHorizontalSpaceAround, LucideAlignVerticalSpaceAround, LucidePlus, LucidePaintbrush, LucideFilter, LucideLayers, LucideMessageSquare, 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, 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';
12
12
  import { XMLParser } from 'fast-xml-parser';
13
13
  import JSZip from 'jszip';
14
- import { DomSanitizer } from '@angular/platform-browser';
15
14
  import { jsPDF } from 'jspdf';
15
+ import { DomSanitizer } from '@angular/platform-browser';
16
16
 
17
17
  const CHECKBOX_STYLES = `
18
18
  :host {
@@ -29689,6 +29689,89 @@ function advanceChartMarkDrag(state, clientX, clientY, rect) {
29689
29689
  return { chartData, value };
29690
29690
  }
29691
29691
 
29692
+ /**
29693
+ * `animation-mask-hole-reveal` — the "In" direction reveal for the Box,
29694
+ * Circle, Diamond and Plus entrance effects.
29695
+ *
29696
+ * COM-verified (PowerPoint `Sequence.AddEffect` with
29697
+ * `EffectParameters.Direction = msoAnimDirectionIn`, `CreateVideo` frame
29698
+ * capture): "In" is the geometric INVERSE of `animation-mask-reveal`'s
29699
+ * `boxOut`/`circleOut`/`diamondOut`/`plusOut` shapes. Instead of a solid
29700
+ * shape growing from a point at centre outward, a HOLE shaped like the
29701
+ * preset (inscribed touching the element's own edges/edge-midpoints) shrinks
29702
+ * from that inscribed size down to nothing, so the element appears to fill
29703
+ * in from its own edges/corners inward, like a closing picture frame. Every
29704
+ * `PptxAnimationPreset` named `boxIn`/`circleIn`/`diamondIn`/`plusIn`
29705
+ * (`presetId` 4/6/8/13, entrance class) previously reused the `xOut` shapes
29706
+ * verbatim, which is PowerPoint's `msoAnimDirectionOut` visual, not `In` -
29707
+ * the wrong direction for what is, by far, the common case (it is also the
29708
+ * direction this project's own writer always authors,
29709
+ * `animation-behavior-simple-filters.ts`'s hardcoded `filter: 'box(in)'`).
29710
+ *
29711
+ * Implemented with `mask-composite: exclude` (boolean XOR) against an
29712
+ * always-solid base layer: XORing a solid layer with a shape inverts that
29713
+ * shape, exactly the "cut a hole out of a solid" operation needed. `plusIn`
29714
+ * unions its two independent bars first (`add`) before excluding the union:
29715
+ * sequential exclude of two overlapping shapes would incorrectly re-reveal
29716
+ * their overlap, since XOR-ing twice cancels out.
29717
+ *
29718
+ * @module render/animation-mask-hole-reveal
29719
+ */
29720
+ const SOLID$1 = 'linear-gradient(#000, #000)';
29721
+ const HOLE_IMAGE = {
29722
+ box: SOLID$1,
29723
+ // `mask-size: 100% 100%` on this gradient draws an ellipse inscribed
29724
+ // touching all four edge midpoints, matching the COM capture exactly.
29725
+ circle: 'radial-gradient(circle, #000 0%, #000 100%)',
29726
+ // This polygon's points already touch the edge midpoints at 100% size
29727
+ // (no headroom needed, unlike `diamondOut`'s growing-past-corners variant).
29728
+ diamond: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpolygon points='50,0 100,50 50,100 0,50' fill='%23000'/%3E%3C/svg%3E")`,
29729
+ };
29730
+ /** Kebab-case declarations for a box/circle/diamond hole reveal (hidden = full hole, shown = no hole). */
29731
+ function maskHoleDecl(shape, phase) {
29732
+ const holeSize = phase === 'hidden' ? '100% 100%' : '0% 0%';
29733
+ return [
29734
+ `mask-image: ${HOLE_IMAGE[shape]}, ${SOLID$1};`,
29735
+ 'mask-position: center, center;',
29736
+ 'mask-repeat: no-repeat, no-repeat;',
29737
+ `mask-size: ${holeSize}, 100% 100%;`,
29738
+ 'mask-composite: add, exclude;',
29739
+ ].join(' ');
29740
+ }
29741
+ /** CamelCase inline-style map for a box/circle/diamond hole reveal's HIDDEN state. */
29742
+ function maskHoleInitialStyle(shape) {
29743
+ return {
29744
+ maskImage: `${HOLE_IMAGE[shape]}, ${SOLID$1}`,
29745
+ maskPosition: 'center, center',
29746
+ maskRepeat: 'no-repeat, no-repeat',
29747
+ maskSize: '100% 100%, 100% 100%',
29748
+ maskComposite: 'add, exclude',
29749
+ opacity: 1,
29750
+ };
29751
+ }
29752
+ /** Kebab-case declarations for the Plus hole reveal (two bars, unioned then excluded from a solid base). */
29753
+ function maskPlusHoleDecl(phase) {
29754
+ const barSize = phase === 'hidden' ? '100%' : '0%';
29755
+ return [
29756
+ `mask-image: ${SOLID$1}, ${SOLID$1}, ${SOLID$1};`,
29757
+ 'mask-position: center, center, center;',
29758
+ 'mask-repeat: no-repeat, no-repeat, no-repeat;',
29759
+ `mask-size: 100% ${barSize}, ${barSize} 100%, 100% 100%;`,
29760
+ 'mask-composite: add, add, exclude;',
29761
+ ].join(' ');
29762
+ }
29763
+ /** CamelCase inline-style map for the Plus hole reveal's HIDDEN state. */
29764
+ function maskPlusHoleInitialStyle() {
29765
+ return {
29766
+ maskImage: `${SOLID$1}, ${SOLID$1}, ${SOLID$1}`,
29767
+ maskPosition: 'center, center, center',
29768
+ maskRepeat: 'no-repeat, no-repeat, no-repeat',
29769
+ maskSize: '100% 100%, 100% 100%, 100% 100%',
29770
+ maskComposite: 'add, add, exclude',
29771
+ opacity: 1,
29772
+ };
29773
+ }
29774
+
29692
29775
  /**
29693
29776
  * `animation-mask-reveal`: CSS `mask`-based reveal states for the clip family
29694
29777
  * of entrance/exit effects (wipe, peek, blinds, split, box, random bars).
@@ -30266,8 +30349,8 @@ const ANIMATION_KEYFRAMES_CSS = `
30266
30349
  to { ${maskEdgeDecl('top', 'shown')} opacity: 1; }
30267
30350
  }
30268
30351
  @keyframes ${KEYFRAME_PREFIX}-boxIn {
30269
- from { ${maskShapeDecl('boxOut', 'hidden')} opacity: 1; }
30270
- to { ${maskShapeDecl('boxOut', 'shown')} opacity: 1; }
30352
+ from { ${maskHoleDecl('box', 'hidden')} opacity: 1; }
30353
+ to { ${maskHoleDecl('box', 'shown')} opacity: 1; }
30271
30354
  }
30272
30355
  @keyframes ${KEYFRAME_PREFIX}-floatIn {
30273
30356
  from { opacity: 0; transform: translateY(40px); }
@@ -30490,14 +30573,31 @@ const EMPHASIS_PRESET_VALUES = [
30490
30573
  'wave',
30491
30574
  'boldFlash',
30492
30575
  ];
30493
- /** Trigger option values for the trigger selector. */
30576
+ /**
30577
+ * Trigger option values for the trigger selector. `afterDelay` was
30578
+ * previously Vue-only (its own hand-rolled copy of this list was the only one
30579
+ * that included it) even though every binding already has an unconditional
30580
+ * "Delay (ms)" field (`PptxElementAnimation.delayMs`) and the write path
30581
+ * (`animation-write-mappings-motion.ts`) already handles it: react/angular/
30582
+ * svelte were simply missing an option their own model and UI could already
30583
+ * serve.
30584
+ */
30494
30585
  const TRIGGER_VALUES = [
30495
30586
  'onClick',
30496
30587
  'onShapeClick',
30497
30588
  'onHover',
30498
30589
  'afterPrevious',
30499
30590
  'withPrevious',
30591
+ 'afterDelay',
30500
30592
  ];
30593
+ /**
30594
+ * Trigger options WITH their `pptx.animation.trigger.<value>` i18n key,
30595
+ * derived from {@link TRIGGER_VALUES}. Four of the five bindings hand-rolled
30596
+ * an identical (but incomplete, see {@link TRIGGER_VALUES}) `{ value,
30597
+ * labelKey }` array. This is the single list every binding's trigger
30598
+ * `<select>` should map to `<option>`s.
30599
+ */
30600
+ const TRIGGER_OPTIONS = TRIGGER_VALUES.map((value) => ({ value, labelKey: `pptx.animation.trigger.${value}` }));
30501
30601
  /** Timing-curve option values. */
30502
30602
  const TIMING_CURVE_VALUES = [
30503
30603
  'ease',
@@ -33673,12 +33773,12 @@ const ENTRANCE_KEYFRAME_DEFINITIONS = {
33673
33773
  to { ${blindsDecl('horizontal', 1)} opacity: 1; }
33674
33774
  }`,
33675
33775
  boxIn: `@keyframes pptx-boxIn {
33676
- from { ${maskShapeDecl('boxOut', 'hidden')} opacity: 1; }
33677
- to { ${maskShapeDecl('boxOut', 'shown')} opacity: 1; }
33776
+ from { ${maskHoleDecl('box', 'hidden')} opacity: 1; }
33777
+ to { ${maskHoleDecl('box', 'shown')} opacity: 1; }
33678
33778
  }`,
33679
33779
  circleIn: `@keyframes pptx-circleIn {
33680
- from { ${maskShapeDecl('circleOut', 'hidden')} opacity: 1; }
33681
- to { ${maskShapeDecl('circleOut', 'shown')} opacity: 1; }
33780
+ from { ${maskHoleDecl('circle', 'hidden')} opacity: 1; }
33781
+ to { ${maskHoleDecl('circle', 'shown')} opacity: 1; }
33682
33782
  }`,
33683
33783
  floatIn: `@keyframes pptx-floatIn {
33684
33784
  from { opacity: 0; transform: translateY(40px); }
@@ -33749,12 +33849,12 @@ const ENTRANCE_KEYFRAME_DEFINITIONS = {
33749
33849
  to { opacity: 1; transform: rotate(0deg) scale(1); }
33750
33850
  }`,
33751
33851
  diamondIn: `@keyframes pptx-diamondIn {
33752
- from { ${maskShapeDecl('diamondOut', 'hidden')} opacity: 1; }
33753
- to { ${maskShapeDecl('diamondOut', 'shown')} opacity: 1; }
33852
+ from { ${maskHoleDecl('diamond', 'hidden')} opacity: 1; }
33853
+ to { ${maskHoleDecl('diamond', 'shown')} opacity: 1; }
33754
33854
  }`,
33755
33855
  plusIn: `@keyframes pptx-plusIn {
33756
- from { ${maskShapeDecl('plusOut', 'hidden')} opacity: 1; }
33757
- to { ${maskShapeDecl('plusOut', 'shown')} opacity: 1; }
33856
+ from { ${maskPlusHoleDecl('hidden')} opacity: 1; }
33857
+ to { ${maskPlusHoleDecl('shown')} opacity: 1; }
33758
33858
  }`,
33759
33859
  wedgeIn: `@keyframes pptx-wedgeIn {
33760
33860
  from { ${maskShapeDecl('wedgeOut', 'hidden')} opacity: 1; }
@@ -36056,11 +36156,33 @@ function resolveGeometryStops(kind, component, box) {
36056
36156
  */
36057
36157
  const BOUNCE_SETTLE_SAMPLES = 16;
36058
36158
  /**
36059
- * How many decaying oscillations the settle phase completes. Not fitted
36060
- * against PowerPoint `CreateVideo` frame captures (no local capture pipeline
36061
- * was available for this change); chosen to read as a plausible "overshoot,
36062
- * bounce twice, settle" curve. Revisit with real frame data if the shape
36063
- * turns out to visibly disagree with PowerPoint's own Bounce End effect.
36159
+ * How many decaying oscillations the settle phase completes. Still NOT
36160
+ * fitted against a confirmed PowerPoint `CreateVideo` capture of a real
36161
+ * `bounceEnd` behaviour; chosen to read as a plausible "overshoot, bounce
36162
+ * twice, settle" curve.
36163
+ *
36164
+ * A 2026-09-25 attempt to fit this against real frame data was inconclusive
36165
+ * and is recorded here so the next attempt does not repeat it blind: there is
36166
+ * no COM-scriptable way found to AUTHOR `p14:bounceEnd` (it is not exposed on
36167
+ * `Effect`/`Effect.EffectParameters`/`Effect.Timing`), so the attempt hand-
36168
+ * wrote `p14:bounceEnd="40000"` onto a COM-authored Fly In's `<p:anim>`
36169
+ * (wrapped in `mc:AlternateContent`/`mc:Choice Requires="p14"`, mirroring how
36170
+ * this project already wraps other p14/p15 extensions) and re-opened that
36171
+ * file in PowerPoint for `CreateVideo`. PowerPoint accepted the file (no
36172
+ * repair prompt) and exported it, but pixel-measuring the shape's leading
36173
+ * edge across 60fps frames showed a perfectly smooth, monotonic ramp with NO
36174
+ * overshoot or oscillation at all - the opposite of the current
36175
+ * approximation's shape. That could mean either (a) the hand-authored file
36176
+ * does not actually trigger PowerPoint's own bounceEnd rendering (most
36177
+ * likely, since - unlike every other COM measurement in this codebase - this
36178
+ * one could not be validated by having PowerPoint itself WRITE the attribute
36179
+ * and reading it back), or (b) `CreateVideo`'s export path does not apply
36180
+ * this particular enhancement even when authored normally. Neither could be
36181
+ * confirmed, so the constants below were deliberately left unchanged rather
36182
+ * than "fitted" to an unverified curve. A real fix needs either a confirmed-
36183
+ * bouncing real-world corpus fixture (verified via PowerPoint's own live
36184
+ * on-screen preview, not just `CreateVideo`) or a COM/UI automation path that
36185
+ * actually sets Bounce End through the Effect Options dialog.
36064
36186
  */
36065
36187
  const BOUNCE_OSCILLATIONS = 2.5;
36066
36188
  /**
@@ -39157,6 +39279,8 @@ const ENTRANCE_EFFECTS = new Set([
39157
39279
  'blindsIn',
39158
39280
  'boxIn',
39159
39281
  'circleIn',
39282
+ 'diamondIn',
39283
+ 'plusIn',
39160
39284
  'floatIn',
39161
39285
  'riseUp',
39162
39286
  'swivel',
@@ -39233,9 +39357,13 @@ function getInitialStyleForEffect(effect) {
39233
39357
  case 'blindsIn':
39234
39358
  return maskEdgeInitialStyle('top');
39235
39359
  case 'boxIn':
39236
- return maskShapeInitialStyle('boxOut');
39360
+ return maskHoleInitialStyle('box');
39237
39361
  case 'circleIn':
39238
- return maskShapeInitialStyle('circleOut');
39362
+ return maskHoleInitialStyle('circle');
39363
+ case 'diamondIn':
39364
+ return maskHoleInitialStyle('diamond');
39365
+ case 'plusIn':
39366
+ return maskPlusHoleInitialStyle();
39239
39367
  case 'peekIn':
39240
39368
  return maskEdgeInitialStyle('bottom');
39241
39369
  case 'randomBarsIn':
@@ -53101,6 +53229,7 @@ const translationsEn = {
53101
53229
  'pptx.media.startAutomatically': 'Automatically',
53102
53230
  'pptx.media.playAcrossSlides': 'Play across slides',
53103
53231
  'pptx.media.fullScreen': 'Full screen',
53232
+ 'pptx.media.onlineVideoTitle': 'Online video',
53104
53233
  'pptx.media.hideWhenNotPlaying': 'Hide when not playing',
53105
53234
  'pptx.media.bookmarks': 'Bookmarks',
53106
53235
  'pptx.media.bookmark': 'Bookmark',
@@ -53176,6 +53305,12 @@ const translationsEn = {
53176
53305
  'pptx.compare.noDifferences': 'No differences',
53177
53306
  'pptx.compare.summary': '{{added}} added, {{removed}} removed, {{changed}} changed',
53178
53307
  'pptx.compare.title': 'Compare',
53308
+ // Canvas context menu (empty slide right-click)
53309
+ 'pptx.canvasContextMenu.formatBackground': 'Format Background...',
53310
+ 'pptx.canvasContextMenu.gridAndGuides': 'Grid and Guides',
53311
+ 'pptx.canvasContextMenu.layout': 'Layout',
53312
+ 'pptx.canvasContextMenu.resetSlide': 'Reset Slide',
53313
+ 'pptx.canvasContextMenu.ruler': 'Ruler',
53179
53314
  // Context menu
53180
53315
  'pptx.contextMenu.addComment': 'Add Comment',
53181
53316
  'pptx.contextMenu.bringForward': 'Bring Forward',
@@ -53186,7 +53321,10 @@ const translationsEn = {
53186
53321
  'pptx.contextMenu.deleteColumn': 'Delete Column',
53187
53322
  'pptx.contextMenu.deleteRow': 'Delete Row',
53188
53323
  'pptx.contextMenu.duplicate': 'Duplicate',
53324
+ 'pptx.contextMenu.editAltText': 'Edit Alt Text...',
53189
53325
  'pptx.contextMenu.editHyperlink': 'Edit Hyperlink',
53326
+ 'pptx.contextMenu.editText': 'Edit Text',
53327
+ 'pptx.contextMenu.formatShape': 'Format Shape...',
53190
53328
  'pptx.contextMenu.group': 'Group',
53191
53329
  'pptx.contextMenu.insertColumnLeft': 'Insert Column Left',
53192
53330
  'pptx.contextMenu.insertColumnRight': 'Insert Column Right',
@@ -53195,10 +53333,19 @@ const translationsEn = {
53195
53333
  'pptx.contextMenu.mergeCells': 'Merge Right',
53196
53334
  'pptx.contextMenu.mergeSelectedCells': 'Merge Selected Cells',
53197
53335
  'pptx.contextMenu.paste': 'Paste',
53336
+ 'pptx.contextMenu.saveAsPicture': 'Save as Picture...',
53198
53337
  'pptx.contextMenu.sendBackward': 'Send Backward',
53199
53338
  'pptx.contextMenu.sendToBack': 'Send to Back',
53339
+ 'pptx.contextMenu.sizeAndPosition': 'Size and Position...',
53200
53340
  'pptx.contextMenu.splitCell': 'Split Cell',
53201
53341
  'pptx.contextMenu.ungroup': 'Ungroup',
53342
+ // Paste Special (Ctrl+Alt+V) and the post-paste Paste Options toolbar
53343
+ 'pptx.pasteSpecial.dialogTitle': 'Paste Special',
53344
+ 'pptx.pasteSpecial.keepSourceFormatting': 'Keep Source Formatting',
53345
+ 'pptx.pasteSpecial.keepTextOnly': 'Keep Text Only',
53346
+ 'pptx.pasteSpecial.optionsLabel': 'Paste Options',
53347
+ 'pptx.pasteSpecial.picture': 'Picture',
53348
+ 'pptx.pasteSpecial.useDestinationTheme': 'Use Destination Theme',
53202
53349
  // Digital signatures (additions)
53203
53350
  'pptx.digitalSignatures.badge': 'Signed',
53204
53351
  'pptx.digitalSignatures.editWarning': 'Editing this presentation will invalidate its digital signatures.',
@@ -53545,6 +53692,12 @@ const translationsEn = {
53545
53692
  'pptx.transition.morphOption.byObject': 'By Object',
53546
53693
  'pptx.transition.morphOption.byWord': 'By Word',
53547
53694
  'pptx.transition.morphOption.byChar': 'By Character',
53695
+ 'pptx.transition.pattern': 'Pattern',
53696
+ 'pptx.transition.pattern.diamond': 'Diamond',
53697
+ 'pptx.transition.pattern.hexagon': 'Hexagon',
53698
+ 'pptx.transition.pattern.strip': 'Strips',
53699
+ 'pptx.transition.pattern.rectangle': 'Rectangles',
53700
+ 'pptx.transition.thruBlk': 'Through black',
53548
53701
  // Context menu / editor toolbar (Angular/Vue-specific additions)
53549
53702
  'pptx.contextMenu.ariaLabel': 'Context menu',
53550
53703
  'pptx.editorToolbar.ariaLabel': 'Editor toolbar',
@@ -56282,15 +56435,6 @@ function buildSlideTemplateSlide(templateId, slideId, slideNumber, options = {})
56282
56435
  };
56283
56436
  }
56284
56437
 
56285
- /**
56286
- * ole-actions.ts - framework-agnostic helpers for the OLE download/open UI.
56287
- *
56288
- * Shared by the binding OLE renderers to format the recovered embedded payload
56289
- * size and decide whether its MIME type can be opened directly in a browser tab
56290
- * (vs download-only). Pure functions, no framework or DOM dependencies.
56291
- *
56292
- * @module shared/render/ole-actions
56293
- */
56294
56438
  const BYTE_UNITS = ['bytes', 'KB', 'MB', 'GB', 'TB'];
56295
56439
  /**
56296
56440
  * Human-readable binary file size (1024-based), e.g. `1 byte`, `0 bytes`,
@@ -56340,6 +56484,27 @@ function isBrowserOpenableMime(mime) {
56340
56484
  value === 'application/xml' ||
56341
56485
  value === 'application/xhtml+xml');
56342
56486
  }
56487
+ /**
56488
+ * Whether an OLE element's interactive Download / (browser-openable) Open
56489
+ * action bar should render at all.
56490
+ *
56491
+ * Mirrors {@link import('./media-playback').mediaTransportVisible}'s two
56492
+ * non-interactive surfaces: a still of a slide (thumbnail rail, presenter
56493
+ * console panes, a slide-transition overlay, an export raster) and the live
56494
+ * presentation stage never offer element-level browser chrome, only the
56495
+ * editable canvas does. Unlike media transport there is no per-binding
56496
+ * "what the canvas already does" divergence to preserve: every binding's own
56497
+ * authoring canvas already shows these actions, so the rule reduces to
56498
+ * "the editable canvas, and nowhere else".
56499
+ *
56500
+ * This matters beyond correctness: a slide thumbnail is rendered INSIDE a
56501
+ * `<button aria-label="Go to slide N">` in every binding, so an OLE preview's
56502
+ * own Download/Open `<button>` rendered there is invalid, un-clickable
56503
+ * (nested-interactive-control) markup, not merely an unwanted affordance.
56504
+ */
56505
+ function oleActionsVisible(surface) {
56506
+ return !surface.presenting && !surface.preview;
56507
+ }
56343
56508
 
56344
56509
  /** Brand colour per OLE application type. */
56345
56510
  const TYPE_COLORS = {
@@ -77111,6 +77276,64 @@ function interpolatePaths(from, to, t) {
77111
77276
  return result;
77112
77277
  }
77113
77278
 
77279
+ /**
77280
+ * `slide-transition-directional-fx` — direction/pattern-aware `@keyframes` for
77281
+ * `vortex`, `ripple` and `glitter`, split out of `p14-transition-keyframes` to
77282
+ * keep that module under the project's per-file LOC budget.
77283
+ *
77284
+ * These three p14 transitions previously played one fixed animation regardless
77285
+ * of the authored `@dir`/`@pattern` (COM-verified valid direction sets now live
77286
+ * in `TRANSITION_VALID_DIRECTIONS`, core): a deck authored with, say,
77287
+ * `p14:vortex dir="d"` played identically to `dir="u"`. The variants below are
77288
+ * this project's own approximation (not individually frame-matched against
77289
+ * PowerPoint's `CreateVideo` output the way e.g. `slide-transition-cinematic`'s
77290
+ * fallOver was), chosen to read as a plausible directional version of the
77291
+ * existing non-directional keyframe while genuinely varying per token.
77292
+ *
77293
+ * @module render/slide-transition-directional-fx
77294
+ */
77295
+ /** Vortex: rotate + scale spiral, biased toward the authored direction. */
77296
+ const VORTEX_DIRECTIONAL_KEYFRAMES = `
77297
+ @keyframes pptx-tr-vortex-in-left { from { transform: translateX(-40%) rotate(720deg) scale(0); opacity: 0; } to { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; } }
77298
+ @keyframes pptx-tr-vortex-out-left { from { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; } to { transform: translateX(-40%) rotate(-720deg) scale(0); opacity: 0; } }
77299
+ @keyframes pptx-tr-vortex-in-right { from { transform: translateX(40%) rotate(-720deg) scale(0); opacity: 0; } to { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; } }
77300
+ @keyframes pptx-tr-vortex-out-right { from { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; } to { transform: translateX(40%) rotate(720deg) scale(0); opacity: 0; } }
77301
+ @keyframes pptx-tr-vortex-in-up { from { transform: translateY(-40%) rotate(720deg) scale(0); opacity: 0; } to { transform: translateY(0) rotate(0deg) scale(1); opacity: 1; } }
77302
+ @keyframes pptx-tr-vortex-out-up { from { transform: translateY(0) rotate(0deg) scale(1); opacity: 1; } to { transform: translateY(-40%) rotate(-720deg) scale(0); opacity: 0; } }
77303
+ @keyframes pptx-tr-vortex-in-down { from { transform: translateY(40%) rotate(-720deg) scale(0); opacity: 0; } to { transform: translateY(0) rotate(0deg) scale(1); opacity: 1; } }
77304
+ @keyframes pptx-tr-vortex-out-down { from { transform: translateY(0) rotate(0deg) scale(1); opacity: 1; } to { transform: translateY(40%) rotate(720deg) scale(0); opacity: 0; } }
77305
+ `;
77306
+ /**
77307
+ * Ripple: expanding-ring clip-path, originating from the authored diagonal
77308
+ * corner instead of always the slide centre. `TRANSITION_VALID_DIRECTIONS`
77309
+ * only offers the four diagonals (`lu`/`ld`/`ru`/`rd`, COM-verified); the
77310
+ * unset default keeps the existing centre-origin `pptx-tr-ripple-in`.
77311
+ */
77312
+ const RIPPLE_DIRECTIONAL_KEYFRAMES = `
77313
+ @keyframes pptx-tr-ripple-in-lu { from { clip-path: circle(0% at 0% 0%); opacity: 0.5; } 30% { clip-path: circle(20% at 0% 0%); opacity: 0.7; } 60% { clip-path: circle(55% at 0% 0%); opacity: 0.9; } to { clip-path: circle(150% at 0% 0%); opacity: 1; } }
77314
+ @keyframes pptx-tr-ripple-in-ru { from { clip-path: circle(0% at 100% 0%); opacity: 0.5; } 30% { clip-path: circle(20% at 100% 0%); opacity: 0.7; } 60% { clip-path: circle(55% at 100% 0%); opacity: 0.9; } to { clip-path: circle(150% at 100% 0%); opacity: 1; } }
77315
+ @keyframes pptx-tr-ripple-in-ld { from { clip-path: circle(0% at 0% 100%); opacity: 0.5; } 30% { clip-path: circle(20% at 0% 100%); opacity: 0.7; } 60% { clip-path: circle(55% at 0% 100%); opacity: 0.9; } to { clip-path: circle(150% at 0% 100%); opacity: 1; } }
77316
+ @keyframes pptx-tr-ripple-in-rd { from { clip-path: circle(0% at 100% 100%); opacity: 0.5; } 30% { clip-path: circle(20% at 100% 100%); opacity: 0.7; } 60% { clip-path: circle(55% at 100% 100%); opacity: 0.9; } to { clip-path: circle(150% at 100% 100%); opacity: 1; } }
77317
+ `;
77318
+ /**
77319
+ * Glitter: particle dissolve, biased by direction (a small drift toward the
77320
+ * authored edge) and by pattern (diamond keeps the original saturate/contrast
77321
+ * dissolve; hexagon adds a hue-rotate sweep so the two patterns read as
77322
+ * genuinely different sparkle textures, matching `p14:glitter/@pattern`).
77323
+ */
77324
+ const GLITTER_DIRECTIONAL_KEYFRAMES = `
77325
+ @keyframes pptx-tr-glitter-diamond-in-l { from { opacity: 0; transform: translateX(-6%); filter: brightness(1.5) contrast(1.3) blur(2px); } 60% { opacity: 0.7; transform: translateX(-2%); filter: brightness(1.2) contrast(1.1) blur(1px); } to { opacity: 1; transform: translateX(0); filter: brightness(1) contrast(1) blur(0); } }
77326
+ @keyframes pptx-tr-glitter-diamond-in-r { from { opacity: 0; transform: translateX(6%); filter: brightness(1.5) contrast(1.3) blur(2px); } 60% { opacity: 0.7; transform: translateX(2%); filter: brightness(1.2) contrast(1.1) blur(1px); } to { opacity: 1; transform: translateX(0); filter: brightness(1) contrast(1) blur(0); } }
77327
+ @keyframes pptx-tr-glitter-diamond-in-u { from { opacity: 0; transform: translateY(-6%); filter: brightness(1.5) contrast(1.3) blur(2px); } 60% { opacity: 0.7; transform: translateY(-2%); filter: brightness(1.2) contrast(1.1) blur(1px); } to { opacity: 1; transform: translateY(0); filter: brightness(1) contrast(1) blur(0); } }
77328
+ @keyframes pptx-tr-glitter-diamond-in-d { from { opacity: 0; transform: translateY(6%); filter: brightness(1.5) contrast(1.3) blur(2px); } 60% { opacity: 0.7; transform: translateY(2%); filter: brightness(1.2) contrast(1.1) blur(1px); } to { opacity: 1; transform: translateY(0); filter: brightness(1) contrast(1) blur(0); } }
77329
+ @keyframes pptx-tr-glitter-hexagon-in-l { from { opacity: 0; transform: translateX(-6%); filter: brightness(1.5) contrast(1.3) blur(2px) hue-rotate(20deg); } 60% { opacity: 0.7; transform: translateX(-2%); filter: brightness(1.2) contrast(1.1) blur(1px) hue-rotate(8deg); } to { opacity: 1; transform: translateX(0); filter: brightness(1) contrast(1) blur(0) hue-rotate(0deg); } }
77330
+ @keyframes pptx-tr-glitter-hexagon-in-r { from { opacity: 0; transform: translateX(6%); filter: brightness(1.5) contrast(1.3) blur(2px) hue-rotate(20deg); } 60% { opacity: 0.7; transform: translateX(2%); filter: brightness(1.2) contrast(1.1) blur(1px) hue-rotate(8deg); } to { opacity: 1; transform: translateX(0); filter: brightness(1) contrast(1) blur(0) hue-rotate(0deg); } }
77331
+ @keyframes pptx-tr-glitter-hexagon-in-u { from { opacity: 0; transform: translateY(-6%); filter: brightness(1.5) contrast(1.3) blur(2px) hue-rotate(20deg); } 60% { opacity: 0.7; transform: translateY(-2%); filter: brightness(1.2) contrast(1.1) blur(1px) hue-rotate(8deg); } to { opacity: 1; transform: translateY(0); filter: brightness(1) contrast(1) blur(0) hue-rotate(0deg); } }
77332
+ @keyframes pptx-tr-glitter-hexagon-in-d { from { opacity: 0; transform: translateY(6%); filter: brightness(1.5) contrast(1.3) blur(2px) hue-rotate(20deg); } 60% { opacity: 0.7; transform: translateY(2%); filter: brightness(1.2) contrast(1.1) blur(1px) hue-rotate(8deg); } to { opacity: 1; transform: translateY(0); filter: brightness(1) contrast(1) blur(0) hue-rotate(0deg); } }
77333
+ `;
77334
+ /** All directional-fx keyframes concatenated, for one-shot `<style>` injection. */
77335
+ const DIRECTIONAL_FX_KEYFRAMES = `${VORTEX_DIRECTIONAL_KEYFRAMES}\n${RIPPLE_DIRECTIONAL_KEYFRAMES}\n${GLITTER_DIRECTIONAL_KEYFRAMES}`;
77336
+
77114
77337
  /**
77115
77338
  * `slide-transition-prism`: the `p:prism` (Office generic 3-D perspective
77116
77339
  * rotation) slide-transition `@keyframes`, split out of `p14-transition-keyframes`
@@ -77476,7 +77699,7 @@ ${WARP_TRANSITION_KEYFRAMES}
77476
77699
  }
77477
77700
  `;
77478
77701
  /** Both p14 keyframe blocks concatenated, for single `<style>` injection. */
77479
- const P14_TRANSITION_KEYFRAMES_ALL = `${P14_TRANSITION_KEYFRAMES}\n${P14_TRANSITION_KEYFRAMES_2}`;
77702
+ const P14_TRANSITION_KEYFRAMES_ALL = `${P14_TRANSITION_KEYFRAMES}\n${P14_TRANSITION_KEYFRAMES_2}\n${DIRECTIONAL_FX_KEYFRAMES}`;
77480
77703
 
77481
77704
  /**
77482
77705
  * `slide-transition-box`: the p15/p14 "Box" slide transition
@@ -77557,6 +77780,84 @@ const BOX_TRANSITION_KEYFRAMES = `
77557
77780
  /* ── Box (faces separate and recede in depth, unlike Cube's flush hinge) ── */${prismDepthPair('box', 'left', 'X', -1)}${prismDepthPair('box', 'right', 'X', 1)}${prismDepthPair('box', 'up', 'Y', -1)}${prismDepthPair('box', 'down', 'Y', 1)}
77558
77781
  `;
77559
77782
 
77783
+ /**
77784
+ * `slide-transition-cinematic-mirror` — the "Right" (`invX="1"`) mirror of the
77785
+ * seven directional p15 cinematic presets whose default keyframes live in
77786
+ * `slide-transition-cinematic` (`fallOver`, `drape`, `wind`, `peelOff`,
77787
+ * `pageCurlSingle`, `pageCurlDouble`, `airplane`, `origami` are the eight
77788
+ * `P15_INVX_PRESETS`; `wind` already had a mirrored pair and stays there).
77789
+ * Split into its own module to keep `slide-transition-cinematic` under the
77790
+ * project's per-file LOC budget.
77791
+ *
77792
+ * `fallOver`'s mirror is COM-measured: `CreateVideo` on a deck authored with
77793
+ * `ppEffectFallOverLeft` vs `ppEffectFallOverRight` shows the slide toppling
77794
+ * off a hinge anchored at the BOTTOM-LEFT corner (Left) vs BOTTOM-RIGHT corner
77795
+ * (Right) - a true horizontal mirror, not a symmetric top-hinge topple. The
77796
+ * other six were not individually frame-captured; their mirrors apply the same
77797
+ * "flip every horizontal component" rule (negate translateX/rotateY/skewX,
77798
+ * swap left<->right transform-origins) that `fallOver`'s measurement confirms
77799
+ * is the right general shape for this preset family.
77800
+ *
77801
+ * @module render/slide-transition-cinematic-mirror
77802
+ */
77803
+ /** Fall Over: COM-measured bottom-right hinge (mirror of the bottom-left default). */
77804
+ const FALLOVER_RIGHT_KEYFRAMES = `
77805
+ @keyframes pptx-tr-fallover-out-right {
77806
+ 0% { transform: perspective(1400px) rotate3d(1, -1, 0, 0deg) scale(1); transform-origin: bottom right; opacity: 1; }
77807
+ 55% { transform: perspective(1400px) rotate3d(1, -1, 0, 45deg) scale(.92); transform-origin: bottom right; opacity: .85; }
77808
+ 100% { transform: perspective(1400px) rotate3d(1, -1, 0, 85deg) scale(.7); transform-origin: bottom right; opacity: 0; }
77809
+ }
77810
+ `;
77811
+ /** Drape: mirrored fabric drape, biased to fall from the right instead of the left. */
77812
+ const DRAPE_RIGHT_KEYFRAMES = `
77813
+ @keyframes pptx-tr-drape-in-right {
77814
+ from { transform: perspective(1600px) rotateX(-55deg) rotateZ(4deg) scale(1.15); transform-origin: top right; opacity: 0; }
77815
+ to { transform: perspective(1600px) rotateX(0deg) rotateZ(0deg) scale(1); transform-origin: top right; opacity: 1; }
77816
+ }
77817
+ `;
77818
+ /** Peel Off: mirrored corner (top-left peel instead of top-right). */
77819
+ const PEELOFF_RIGHT_KEYFRAMES = `
77820
+ @keyframes pptx-tr-peeloff-out-right {
77821
+ from { transform: perspective(1400px) rotate3d(1, -1, 0, 0deg); transform-origin: top left; opacity: 1; }
77822
+ to { transform: perspective(1400px) rotate3d(1, -1, 0, 110deg); transform-origin: top left; opacity: .15; }
77823
+ }
77824
+ `;
77825
+ /** Page Curl: mirrored curl off the left edge (single fold) / into the right edge (double's incoming fold). */
77826
+ const PAGECURL_RIGHT_KEYFRAMES = `
77827
+ @keyframes pptx-tr-pagecurl-out-right {
77828
+ from { transform: perspective(1600px) rotateY(0deg); transform-origin: left center; opacity: 1; }
77829
+ to { transform: perspective(1600px) rotateY(155deg); transform-origin: left center; opacity: .25; }
77830
+ }
77831
+ @keyframes pptx-tr-pagecurl-double-in-right {
77832
+ from { transform: perspective(1600px) rotateY(-155deg); transform-origin: right center; opacity: .25; }
77833
+ to { transform: perspective(1600px) rotateY(0deg); transform-origin: right center; opacity: 1; }
77834
+ }
77835
+ `;
77836
+ /** Airplane: mirrored flight path, banking away to the left instead of the right. */
77837
+ const AIRPLANE_RIGHT_KEYFRAMES = `
77838
+ @keyframes pptx-tr-airplane-out-right {
77839
+ 0% { transform: perspective(1200px) translate3d(0, 0, 0) rotate3d(-1, -1, 0, 0deg) scale(1); opacity: 1; }
77840
+ 40% { transform: perspective(1200px) translate3d(-10%, -10%, 0) rotate3d(-1, -1, 0, 25deg) scale(.85); opacity: 1; }
77841
+ 100% { transform: perspective(1200px) translate3d(-150%, -70%, 0) rotate3d(-1, -1, 1, 70deg) scale(.05); opacity: 0; }
77842
+ }
77843
+ `;
77844
+ /** Origami: mirrored fold, creasing from the top-right instead of top-left. */
77845
+ const ORIGAMI_RIGHT_KEYFRAMES = `
77846
+ @keyframes pptx-tr-origami-out-right {
77847
+ 0% { transform: perspective(1400px) rotateX(0deg) rotateZ(0deg) translateY(0) scale(1); transform-origin: top right; opacity: 1; filter: brightness(1); }
77848
+ 45% { transform: perspective(1400px) rotateX(-52deg) rotateZ(-3deg) translateY(2%) scale(.96); transform-origin: top right; opacity: 1; filter: brightness(.82); }
77849
+ 70% { transform: perspective(1400px) rotateX(-84deg) rotateZ(-3deg) translateY(8%) scale(.88); transform-origin: top right; opacity: .8; filter: brightness(.68); }
77850
+ 100% { transform: perspective(1400px) rotateX(-125deg) rotateZ(-3deg) translateY(30%) scale(.68); transform-origin: top right; opacity: 0; filter: brightness(.55); }
77851
+ }
77852
+ @keyframes pptx-tr-origami-in-right {
77853
+ 0% { transform: perspective(1400px) rotateX(62deg) rotateZ(3deg) scale(.94); transform-origin: bottom left; opacity: 0; filter: brightness(.7); }
77854
+ 30% { transform: perspective(1400px) rotateX(62deg) rotateZ(3deg) scale(.94); transform-origin: bottom left; opacity: .65; filter: brightness(.75); }
77855
+ 100% { transform: perspective(1400px) rotateX(0deg) rotateZ(0deg) scale(1); transform-origin: bottom left; opacity: 1; filter: brightness(1); }
77856
+ }
77857
+ `;
77858
+ /** All mirrored keyframes concatenated, for one-shot `<style>` injection. */
77859
+ const CINEMATIC_MIRROR_KEYFRAMES = `${FALLOVER_RIGHT_KEYFRAMES}\n${DRAPE_RIGHT_KEYFRAMES}\n${PEELOFF_RIGHT_KEYFRAMES}\n${PAGECURL_RIGHT_KEYFRAMES}\n${AIRPLANE_RIGHT_KEYFRAMES}\n${ORIGAMI_RIGHT_KEYFRAMES}`;
77860
+
77560
77861
  /**
77561
77862
  * `slide-transition-rotate`: the p15/p14 "Rotate" slide transition
77562
77863
  * (`<p14:prism isContent="1"/>`, `prismFamilyTypeForFlags` in
@@ -77628,6 +77929,10 @@ const ROTATE_TRANSITION_KEYFRAMES = `
77628
77929
  *
77629
77930
  * @module render/slide-transition-cinematic
77630
77931
  */
77932
+ /** `true` when the resolved direction is the "Right" (`invX="1"`) mirror. */
77933
+ function isRight(direction) {
77934
+ return resolveDirection(direction, 'left') === 'right';
77935
+ }
77631
77936
  /** Build one directional 3-D pair (`cube` / `flip` / `orbit`) from a resolved dir. */
77632
77937
  function threeDPair(prefix, dir, dur, outgoingOnTop) {
77633
77938
  return {
@@ -77670,15 +77975,18 @@ function getCinematicTransitionAnimations(type, durationMs, direction, orient) {
77670
77975
  // keyframes did (an incoming board toppling onto a stationary
77671
77976
  // outgoing). The incoming slide needs no animation of its own: it is
77672
77977
  // simply uncovered as the falling outgoing layer fades away on top.
77978
+ // `direction` (`invX`) is ALSO COM-measured (see
77979
+ // `slide-transition-cinematic-mirror`): Left topples off a
77980
+ // bottom-left hinge, Right off a bottom-right one.
77673
77981
  return {
77674
- outgoing: `pptx-tr-fallover-out ${dur} ${EASE} forwards`,
77982
+ outgoing: `${isRight(direction) ? 'pptx-tr-fallover-out-right' : 'pptx-tr-fallover-out'} ${dur} ${EASE} forwards`,
77675
77983
  incoming: 'none',
77676
77984
  outgoingOnTop: true,
77677
77985
  };
77678
77986
  case 'drape':
77679
77987
  return {
77680
77988
  outgoing: 'none',
77681
- incoming: `pptx-tr-drape-in ${dur} ${EASE} forwards`,
77989
+ incoming: `${isRight(direction) ? 'pptx-tr-drape-in-right' : 'pptx-tr-drape-in'} ${dur} ${EASE} forwards`,
77682
77990
  outgoingOnTop: false,
77683
77991
  };
77684
77992
  case 'curtains':
@@ -77715,37 +78023,47 @@ function getCinematicTransitionAnimations(type, durationMs, direction, orient) {
77715
78023
  incoming: `pptx-tr-crush-in ${dur} ${EASE} forwards`,
77716
78024
  outgoingOnTop: true,
77717
78025
  };
77718
- case 'peelOff':
78026
+ case 'peelOff': {
77719
78027
  // Outgoing peels off a corner, revealing the stationary incoming.
78028
+ const right = isRight(direction);
77720
78029
  return {
77721
- outgoing: `pptx-tr-peeloff-out ${dur} ${EASE} forwards`,
78030
+ outgoing: `${right ? 'pptx-tr-peeloff-out-right' : 'pptx-tr-peeloff-out'} ${dur} ${EASE} forwards`,
77722
78031
  incoming: 'none',
77723
78032
  outgoingOnTop: true,
77724
78033
  };
77725
- case 'pageCurlSingle':
78034
+ }
78035
+ case 'pageCurlSingle': {
78036
+ const right = isRight(direction);
77726
78037
  return {
77727
- outgoing: `pptx-tr-pagecurl-out ${dur} ${EASE} forwards`,
78038
+ outgoing: `${right ? 'pptx-tr-pagecurl-out-right' : 'pptx-tr-pagecurl-out'} ${dur} ${EASE} forwards`,
77728
78039
  incoming: 'none',
77729
78040
  outgoingOnTop: true,
77730
78041
  };
77731
- case 'pageCurlDouble':
78042
+ }
78043
+ case 'pageCurlDouble': {
78044
+ const right = isRight(direction);
77732
78045
  return {
77733
- outgoing: `pptx-tr-pagecurl-out ${dur} ${EASE} forwards`,
77734
- incoming: `pptx-tr-pagecurl-double-in ${dur} ${EASE} forwards`,
78046
+ outgoing: `${right ? 'pptx-tr-pagecurl-out-right' : 'pptx-tr-pagecurl-out'} ${dur} ${EASE} forwards`,
78047
+ incoming: `${right ? 'pptx-tr-pagecurl-double-in-right' : 'pptx-tr-pagecurl-double-in'} ${dur} ${EASE} forwards`,
77735
78048
  outgoingOnTop: true,
77736
78049
  };
77737
- case 'airplane':
78050
+ }
78051
+ case 'airplane': {
78052
+ const right = isRight(direction);
77738
78053
  return {
77739
- outgoing: `pptx-tr-airplane-out ${dur} ${EASE} forwards`,
78054
+ outgoing: `${right ? 'pptx-tr-airplane-out-right' : 'pptx-tr-airplane-out'} ${dur} ${EASE} forwards`,
77740
78055
  incoming: `pptx-tr-fade-in ${dur} ${EASE} forwards`,
77741
78056
  outgoingOnTop: true,
77742
78057
  };
77743
- case 'origami':
78058
+ }
78059
+ case 'origami': {
78060
+ const right = isRight(direction);
77744
78061
  return {
77745
- outgoing: `pptx-tr-origami-out ${dur} ${EASE} forwards`,
77746
- incoming: `pptx-tr-origami-in ${dur} ${EASE} forwards`,
78062
+ outgoing: `${right ? 'pptx-tr-origami-out-right' : 'pptx-tr-origami-out'} ${dur} ${EASE} forwards`,
78063
+ incoming: `${right ? 'pptx-tr-origami-in-right' : 'pptx-tr-origami-in'} ${dur} ${EASE} forwards`,
77747
78064
  outgoingOnTop: true,
77748
78065
  };
78066
+ }
77749
78067
  default:
77750
78068
  return undefined;
77751
78069
  }
@@ -77839,6 +78157,7 @@ ${ROTATE_TRANSITION_KEYFRAMES}
77839
78157
  moment is brief and already mid-fade, so no line artifact survives. */
77840
78158
  @keyframes pptx-tr-origami-out { 0% { transform: perspective(1400px) rotateX(0deg) translateY(0) scale(1); transform-origin: top center; opacity: 1; filter: brightness(1); } 45% { transform: perspective(1400px) rotateX(-52deg) translateY(2%) scale(.96); transform-origin: top center; opacity: 1; filter: brightness(.82); } 70% { transform: perspective(1400px) rotateX(-84deg) translateY(8%) scale(.88); transform-origin: top center; opacity: .8; filter: brightness(.68); } 100% { transform: perspective(1400px) rotateX(-125deg) translateY(30%) scale(.68); transform-origin: top center; opacity: 0; filter: brightness(.55); } }
77841
78159
  @keyframes pptx-tr-origami-in { 0% { transform: perspective(1400px) rotateX(62deg) scale(.94); transform-origin: bottom center; opacity: 0; filter: brightness(.7); } 30% { transform: perspective(1400px) rotateX(62deg) scale(.94); transform-origin: bottom center; opacity: .65; filter: brightness(.75); } 100% { transform: perspective(1400px) rotateX(0deg) scale(1); transform-origin: bottom center; opacity: 1; filter: brightness(1); } }
78160
+ ${CINEMATIC_MIRROR_KEYFRAMES}
77842
78161
  `;
77843
78162
 
77844
78163
  /**
@@ -78895,6 +79214,50 @@ const SLIDE_TRANSITION_KEYFRAMES = `${CORE_SLIDE_TRANSITION_KEYFRAMES}\n${WIPE_M
78895
79214
  */
78896
79215
  const SLIDE_TRANSITION_KEYFRAMES_CSS = SLIDE_TRANSITION_KEYFRAMES;
78897
79216
 
79217
+ /** `p14:vortex`: rotate + scale spiral, biased toward the authored `@dir`. */
79218
+ function getVortexAnimations(durationMs, direction, ease) {
79219
+ const dur = `${durationMs}ms`;
79220
+ const dir = resolveDirection(direction, 'left');
79221
+ return {
79222
+ outgoing: `pptx-tr-vortex-out-${dir} ${dur} ${ease} forwards`,
79223
+ incoming: `pptx-tr-vortex-in-${dir} ${dur} ${ease} forwards`,
79224
+ outgoingOnTop: true,
79225
+ };
79226
+ }
79227
+ /**
79228
+ * `p14:ripple`: expanding-ring clip-path from the authored diagonal corner, or
79229
+ * the slide centre when `@dir` is absent (PowerPoint's "From Center" default,
79230
+ * COM-verified: no other cardinal/diagonal token exists for this type besides
79231
+ * the four `TRANSITION_VALID_DIRECTIONS` diagonals).
79232
+ */
79233
+ function getRippleAnimations(durationMs, direction, ease) {
79234
+ const dur = `${durationMs}ms`;
79235
+ const dir = resolveDirection8(direction, 'left');
79236
+ const corner = dir === 'lu' || dir === 'ld' || dir === 'ru' || dir === 'rd' ? dir : undefined;
79237
+ return {
79238
+ outgoing: 'none',
79239
+ incoming: corner
79240
+ ? `pptx-tr-ripple-in-${corner} ${dur} ${ease} forwards`
79241
+ : `pptx-tr-ripple-in ${dur} ${ease} forwards`,
79242
+ outgoingOnTop: false,
79243
+ };
79244
+ }
79245
+ /**
79246
+ * `p14:glitter`: particle dissolve, biased by `@dir` and varied by
79247
+ * `@pattern` (`diamond` default vs `hexagon`, COM-verified two-value set).
79248
+ */
79249
+ function getGlitterAnimations(durationMs, direction, pattern, ease) {
79250
+ const dur = `${durationMs}ms`;
79251
+ const dir = resolveDirection(direction, 'left');
79252
+ const dirToken = dir === 'left' ? 'l' : dir === 'right' ? 'r' : dir === 'up' ? 'u' : 'd';
79253
+ const family = pattern === 'hexagon' ? 'hexagon' : 'diamond';
79254
+ return {
79255
+ outgoing: `pptx-tr-fade-out ${dur} ${ease} forwards`,
79256
+ incoming: `pptx-tr-glitter-${family}-in-${dirToken} ${dur} ${ease} forwards`,
79257
+ outgoingOnTop: true,
79258
+ };
79259
+ }
79260
+
78898
79261
  /**
78899
79262
  * `p14-transition-css` — animation resolver for the Office 2010 (`p14`
78900
79263
  * namespace) slide transitions. Maps each p14 transition type to the faithful
@@ -79062,11 +79425,7 @@ function getP14TransitionAnimations(type, durationMs, direction, orient, pattern
79062
79425
  };
79063
79426
  }
79064
79427
  case 'glitter':
79065
- return {
79066
- outgoing: `pptx-tr-fade-out ${dur} ${ease} forwards`,
79067
- incoming: `pptx-tr-glitter-in ${dur} ${ease} forwards`,
79068
- outgoingOnTop: true,
79069
- };
79428
+ return getGlitterAnimations(durationMs, direction, pattern, ease);
79070
79429
  case 'honeycomb':
79071
79430
  return {
79072
79431
  outgoing: `pptx-tr-honeycomb-out ${dur} ${ease} forwards`,
@@ -79088,11 +79447,7 @@ function getP14TransitionAnimations(type, durationMs, direction, orient, pattern
79088
79447
  };
79089
79448
  }
79090
79449
  case 'ripple':
79091
- return {
79092
- outgoing: 'none',
79093
- incoming: `pptx-tr-ripple-in ${dur} ${ease} forwards`,
79094
- outgoingOnTop: false,
79095
- };
79450
+ return getRippleAnimations(durationMs, direction, ease);
79096
79451
  case 'shred': {
79097
79452
  // `p14:shred` names its tile shape via the SEPARATE `@_pattern`
79098
79453
  // attribute (`strip` | `rectangle`), not `@_dir` (which is the
@@ -79125,11 +79480,7 @@ function getP14TransitionAnimations(type, durationMs, direction, orient, pattern
79125
79480
  };
79126
79481
  }
79127
79482
  case 'vortex':
79128
- return {
79129
- outgoing: `pptx-tr-vortex-out ${dur} ${ease} forwards`,
79130
- incoming: `pptx-tr-vortex-in ${dur} ${ease} forwards`,
79131
- outgoingOnTop: true,
79132
- };
79483
+ return getVortexAnimations(durationMs, direction, ease);
79133
79484
  case 'warp': {
79134
79485
  const isOut = direction === 'out';
79135
79486
  if (isOut) {
@@ -79638,8 +79989,12 @@ const TRANSITION_MORPH_OPTIONS = [
79638
79989
  * Transition types whose OOXML attribute is `dir="horz|vert"` (an orientation)
79639
79990
  * rather than one of the cardinal/diagonal direction tokens, so the inspector
79640
79991
  * must show a two-button orientation toggle instead of the arrow grid.
79992
+ *
79993
+ * `doors` and `window` are COM-verified: PowerPoint's own `PpEntryEffect`
79994
+ * enumeration saves `<p14:doors dir="vert"/>` / bare (horz default), and
79995
+ * likewise for `p14:window`, exactly like `blinds`/`checker`.
79641
79996
  */
79642
- const TRANSITION_ORIENTATION_TYPES = new Set(['blinds', 'checker', 'comb', 'randomBar']);
79997
+ const TRANSITION_ORIENTATION_TYPES = new Set(['blinds', 'checker', 'comb', 'randomBar', 'doors', 'window']);
79643
79998
  /** Arrow glyph shown on a direction button, keyed by OOXML direction token. */
79644
79999
  const TRANSITION_DIR_ARROWS = {
79645
80000
  l: '←',
@@ -92504,6 +92859,14 @@ function mapEditorKey(input, guard = {}) {
92504
92859
  if (mod && !alt && key.toLowerCase() === 'h') {
92505
92860
  return { action: 'findReplace' };
92506
92861
  }
92862
+ // Ctrl/Cmd+Alt+V (Paste Special) is exempt from the typing gate for the
92863
+ // same reason Ctrl+F is: PowerPoint offers Paste Special with the caret
92864
+ // sitting inside a text box, and `isTextInputTarget` still keeps it out of
92865
+ // a foreign input/textarea/select. It shares plain Paste's `canPaste`
92866
+ // guard so a host with nothing internal to offer leaves it to the browser.
92867
+ if (mod && alt && key.toLowerCase() === 'v' && !state.isTextInputTarget) {
92868
+ return state.canPaste === false ? NO_ACTION$1 : { action: 'pasteSpecial' };
92869
+ }
92507
92870
  // Alignment, font-size stepping, format painter, hyperlink and clear-format
92508
92871
  // are PowerPoint text commands: their main use is a caret or a text range
92509
92872
  // mid-edit, which the typing gate below would otherwise swallow entirely.
@@ -92917,7 +93280,7 @@ function hasMultipleSelectedTableCells(cells, tableData) {
92917
93280
  }
92918
93281
  return false;
92919
93282
  }
92920
- const LABEL_KEYS = {
93283
+ const LABEL_KEYS$1 = {
92921
93284
  copy: 'pptx.contextMenu.copy',
92922
93285
  cut: 'pptx.contextMenu.cut',
92923
93286
  paste: 'pptx.contextMenu.paste',
@@ -92942,14 +93305,19 @@ const LABEL_KEYS = {
92942
93305
  'table-split': 'pptx.contextMenu.splitCell',
92943
93306
  group: 'pptx.contextMenu.group',
92944
93307
  ungroup: 'pptx.contextMenu.ungroup',
93308
+ 'edit-text': 'pptx.contextMenu.editText',
93309
+ 'save-as-picture': 'pptx.contextMenu.saveAsPicture',
93310
+ 'edit-alt-text': 'pptx.contextMenu.editAltText',
93311
+ 'size-and-position': 'pptx.contextMenu.sizeAndPosition',
93312
+ 'format-shape': 'pptx.contextMenu.formatShape',
92945
93313
  delete: 'pptx.contextMenu.delete',
92946
93314
  };
92947
93315
  /** The i18n key for a command, so a binding never spells one out itself. */
92948
93316
  function contextMenuLabelKey(id) {
92949
- return LABEL_KEYS[id];
93317
+ return LABEL_KEYS$1[id];
92950
93318
  }
92951
- function entry$1(id, extra = {}) {
92952
- return { id, labelKey: LABEL_KEYS[id], ...extra };
93319
+ function entry$2(id, extra = {}) {
93320
+ return { id, labelKey: LABEL_KEYS$1[id], ...extra };
92953
93321
  }
92954
93322
  /** The table row / column / merge block, empty when no cell is selected. */
92955
93323
  function tableEntries(table) {
@@ -92957,27 +93325,34 @@ function tableEntries(table) {
92957
93325
  return [];
92958
93326
  }
92959
93327
  const rowsAndColumns = [
92960
- entry$1('table-insert-row-above', { separatorBefore: true }),
92961
- entry$1('table-insert-row-below'),
92962
- entry$1('table-delete-row'),
92963
- entry$1('table-insert-col-left'),
92964
- entry$1('table-insert-col-right'),
92965
- entry$1('table-delete-col'),
93328
+ entry$2('table-insert-row-above', { separatorBefore: true }),
93329
+ entry$2('table-insert-row-below'),
93330
+ entry$2('table-delete-row'),
93331
+ entry$2('table-insert-col-left'),
93332
+ entry$2('table-insert-col-right'),
93333
+ entry$2('table-delete-col'),
92966
93334
  ];
92967
93335
  // A block selection merges as a block; a cell that already spans can only be
92968
93336
  // split; anything else offers the two pairwise merges.
92969
93337
  if (table.hasMultiCellSelection) {
92970
- return [...rowsAndColumns, entry$1('table-merge-selected', { separatorBefore: true })];
93338
+ return [...rowsAndColumns, entry$2('table-merge-selected', { separatorBefore: true })];
92971
93339
  }
92972
93340
  if (table.isMergedCell) {
92973
- return [...rowsAndColumns, entry$1('table-split', { separatorBefore: true })];
93341
+ return [...rowsAndColumns, entry$2('table-split', { separatorBefore: true })];
92974
93342
  }
92975
93343
  return [
92976
93344
  ...rowsAndColumns,
92977
- entry$1('table-merge-right', { separatorBefore: true }),
92978
- entry$1('table-merge-down'),
93345
+ entry$2('table-merge-right', { separatorBefore: true }),
93346
+ entry$2('table-merge-down'),
92979
93347
  ];
92980
93348
  }
93349
+ /**
93350
+ * Element types PowerPoint lets you type directly into from the context menu's
93351
+ * "Edit Text" entry: plain text boxes and any autoshape. Tables, charts,
93352
+ * pictures and the like open their own editors instead (a double-click on the
93353
+ * cell, no generic "Edit Text").
93354
+ */
93355
+ const TEXT_EDITABLE_ELEMENT_TYPES = new Set(['text', 'shape']);
92981
93356
  /**
92982
93357
  * The menu for `context`, in order, separators included.
92983
93358
  *
@@ -92989,36 +93364,224 @@ function buildContextMenuEntries(context = {}) {
92989
93364
  const { elementType, table, hasMultiSelection, aiEnabled, hasClipboard, selectionGroupable } = context;
92990
93365
  const lockedOut = selectionGroupable === false;
92991
93366
  const entries = [
92992
- entry$1('copy'),
92993
- entry$1('cut'),
92994
- entry$1('paste', hasClipboard === false ? { disabled: true } : {}),
92995
- entry$1('duplicate'),
92996
- entry$1('bring-forward', { separatorBefore: true }),
92997
- entry$1('send-backward'),
92998
- entry$1('bring-front'),
92999
- entry$1('send-back'),
93367
+ entry$2('copy'),
93368
+ entry$2('cut'),
93369
+ entry$2('paste', hasClipboard === false ? { disabled: true } : {}),
93370
+ entry$2('duplicate'),
93000
93371
  ];
93372
+ if (elementType && TEXT_EDITABLE_ELEMENT_TYPES.has(elementType)) {
93373
+ entries.push(entry$2('edit-text'));
93374
+ }
93375
+ entries.push(entry$2('bring-forward', { separatorBefore: true }), entry$2('send-backward'), entry$2('bring-front'), entry$2('send-back'));
93001
93376
  if (aiEnabled) {
93002
- entries.push(entry$1('ai-ask', { separatorBefore: true }), entry$1('ai-fix'));
93377
+ entries.push(entry$2('ai-ask', { separatorBefore: true }), entry$2('ai-fix'));
93003
93378
  }
93004
- entries.push(entry$1('comment', { separatorBefore: true }), entry$1('hyperlink'));
93379
+ entries.push(entry$2('comment', { separatorBefore: true }), entry$2('hyperlink'));
93005
93380
  entries.push(...tableEntries(table));
93006
93381
  if (hasMultiSelection) {
93007
- entries.push(entry$1('group', { separatorBefore: true, ...(lockedOut ? { disabled: true } : {}) }));
93382
+ entries.push(entry$2('group', { separatorBefore: true, ...(lockedOut ? { disabled: true } : {}) }));
93008
93383
  }
93009
93384
  if (elementType === 'group') {
93010
- entries.push(entry$1('ungroup', {
93385
+ entries.push(entry$2('ungroup', {
93011
93386
  separatorBefore: !hasMultiSelection,
93012
93387
  ...(lockedOut ? { disabled: true } : {}),
93013
93388
  }));
93014
93389
  }
93015
- entries.push(entry$1('delete', {
93016
- separatorBefore: !hasMultiSelection && elementType !== 'group',
93017
- danger: true,
93018
- }));
93390
+ // PowerPoint's own "Format Object" cluster: alt text, save-as-picture,
93391
+ // size/position and the format pane, grouped together ahead of Delete.
93392
+ entries.push(entry$2('save-as-picture', { separatorBefore: true }), entry$2('edit-alt-text'), entry$2('size-and-position'), entry$2('format-shape'));
93393
+ entries.push(entry$2('delete', { separatorBefore: true, danger: true }));
93019
93394
  return entries;
93020
93395
  }
93021
93396
 
93397
+ /**
93398
+ * The right-click menu for the empty slide canvas (no element under the
93399
+ * cursor), as distinct from {@link ./context-menu-commands}'s per-element menu.
93400
+ *
93401
+ * Right-clicking empty canvas used to do nothing at all in every binding: React
93402
+ * and Vue both bailed out early (`getElementIdFromEvent` returns `null`, so the
93403
+ * handler just returns) rather than opening a menu, and the other three never
93404
+ * wired a handler for it either. PowerPoint offers Paste, Layout, Reset,
93405
+ * Format Background and view toggles (Grid and Guides, Ruler) from this menu;
93406
+ * this module is the one list every binding renders instead of five omissions.
93407
+ *
93408
+ * @module render/canvas-context-menu-commands
93409
+ */
93410
+ const LABEL_KEYS = {
93411
+ paste: 'pptx.contextMenu.paste',
93412
+ layout: 'pptx.canvasContextMenu.layout',
93413
+ 'reset-slide': 'pptx.canvasContextMenu.resetSlide',
93414
+ 'format-background': 'pptx.canvasContextMenu.formatBackground',
93415
+ 'grid-and-guides': 'pptx.canvasContextMenu.gridAndGuides',
93416
+ ruler: 'pptx.canvasContextMenu.ruler',
93417
+ };
93418
+ /** The i18n key for a command, so a binding never spells one out itself. */
93419
+ function canvasContextMenuLabelKey(id) {
93420
+ return LABEL_KEYS[id];
93421
+ }
93422
+ function entry$1(id, extra = {}) {
93423
+ return { id, labelKey: LABEL_KEYS[id], ...extra };
93424
+ }
93425
+ /**
93426
+ * The empty-canvas menu for `context`, in order, separators included:
93427
+ * Paste; Layout, Reset Slide; Format Background; Grid and Guides, Ruler.
93428
+ */
93429
+ function buildCanvasContextMenuEntries(context = {}) {
93430
+ const { hasClipboard, showGrid, showRulers } = context;
93431
+ return [
93432
+ entry$1('paste', hasClipboard === false ? { disabled: true } : {}),
93433
+ entry$1('layout', { separatorBefore: true }),
93434
+ entry$1('reset-slide'),
93435
+ entry$1('format-background', { separatorBefore: true }),
93436
+ entry$1('grid-and-guides', { separatorBefore: true, checked: Boolean(showGrid) }),
93437
+ entry$1('ruler', { checked: Boolean(showRulers) }),
93438
+ ];
93439
+ }
93440
+
93441
+ /**
93442
+ * The DOM attribute a binding puts on its section wrapper so this module can
93443
+ * find it, e.g. `<div data-pptx-inspector-section="transform">`.
93444
+ */
93445
+ const INSPECTOR_SECTION_ATTRIBUTE = 'data-pptx-inspector-section';
93446
+ /** The section a command should reveal, or `null` when it does not target one. */
93447
+ function contextMenuInspectorAnchor(id) {
93448
+ switch (id) {
93449
+ case 'size-and-position':
93450
+ return 'transform';
93451
+ case 'format-shape':
93452
+ return 'fill-stroke';
93453
+ case 'edit-alt-text':
93454
+ return 'alt-text';
93455
+ default:
93456
+ return null;
93457
+ }
93458
+ }
93459
+ /**
93460
+ * Scroll the tagged section into view, when present. Call after the binding
93461
+ * has switched to the properties tab and let it mount/render; a section that
93462
+ * is not tagged (or not yet mounted) is silently skipped, so this is always
93463
+ * safe to call.
93464
+ */
93465
+ function scrollInspectorSectionIntoView(doc, anchor) {
93466
+ const node = doc.querySelector(`[${INSPECTOR_SECTION_ATTRIBUTE}="${anchor}"]`);
93467
+ node?.scrollIntoView({ behavior: 'smooth', block: 'start' });
93468
+ }
93469
+
93470
+ /**
93471
+ * The four options, in the order PowerPoint's Paste Options toolbar shows
93472
+ * them (Keep Source Formatting is the default/first icon).
93473
+ */
93474
+ const PASTE_SPECIAL_OPTIONS = [
93475
+ { id: 'keep-source-formatting', labelKey: 'pptx.pasteSpecial.keepSourceFormatting' },
93476
+ { id: 'use-destination-theme', labelKey: 'pptx.pasteSpecial.useDestinationTheme' },
93477
+ { id: 'picture', labelKey: 'pptx.pasteSpecial.picture' },
93478
+ { id: 'keep-text-only', labelKey: 'pptx.pasteSpecial.keepTextOnly' },
93479
+ ];
93480
+ /** Whether `element` carries any text "Keep Text Only" could keep. */
93481
+ function pasteElementHasText(element) {
93482
+ return 'text' in element && typeof element.text === 'string' && element.text.trim().length > 0;
93483
+ }
93484
+ /**
93485
+ * Strip the explicit colour/font overrides "Use Destination Theme" should
93486
+ * drop, so the normal Element -> Placeholder -> Layout -> Master -> Theme
93487
+ * resolution cascade supplies the destination deck's own theme colours and
93488
+ * fonts instead of the ones the source deck baked in.
93489
+ *
93490
+ * This clears solid fill/stroke colours and their theme-colour references
93491
+ * (both are "the source's opinion") and any explicit run/paragraph font
93492
+ * family override, but leaves gradient stops, images and non-colour effects
93493
+ * alone: PowerPoint's own "Use Destination Theme" only ever changes colour
93494
+ * scheme and font scheme, never geometry or imagery.
93495
+ */
93496
+ function stripSourceThemeOverrides(element) {
93497
+ const next = structuredClone(element);
93498
+ if ('shapeStyle' in next && next.shapeStyle) {
93499
+ const style = { ...next.shapeStyle };
93500
+ delete style.fillColor;
93501
+ delete style.fillColorRef;
93502
+ delete style.strokeColor;
93503
+ delete style.strokeColorRef;
93504
+ next.shapeStyle = style;
93505
+ }
93506
+ if ('textStyle' in next && next.textStyle) {
93507
+ const style = { ...next.textStyle };
93508
+ delete style.color;
93509
+ delete style.fontFamily;
93510
+ next.textStyle = style;
93511
+ }
93512
+ if ('textSegments' in next && Array.isArray(next.textSegments)) {
93513
+ next.textSegments = next.textSegments.map((segment) => {
93514
+ const style = segment.style ? { ...segment.style } : undefined;
93515
+ if (!style) {
93516
+ return segment;
93517
+ }
93518
+ delete style.color;
93519
+ delete style.fontFamily;
93520
+ return { ...segment, style };
93521
+ });
93522
+ }
93523
+ return next;
93524
+ }
93525
+ /** Reduce `element` to a bare text box holding only its plain text content. */
93526
+ function toTextOnly(element) {
93527
+ if (!pasteElementHasText(element)) {
93528
+ // Nothing to keep: PowerPoint disables this choice for a picture/media/
93529
+ // table with no text of its own, so a caller should not have offered it,
93530
+ // but degrading to an unchanged clone (rather than an empty text box) is
93531
+ // the safer fallback if it did.
93532
+ return element;
93533
+ }
93534
+ return {
93535
+ type: 'text',
93536
+ id: element.id,
93537
+ x: element.x,
93538
+ y: element.y,
93539
+ width: element.width,
93540
+ height: element.height,
93541
+ rotation: element.rotation,
93542
+ text: 'text' in element ? element.text : undefined,
93543
+ };
93544
+ }
93545
+ /**
93546
+ * Apply `format` to an already-cloned pasted element (fresh id and cascade
93547
+ * offset already applied by `cloneElementForPaste`). `keep-source-formatting`
93548
+ * and `picture` are no-ops here: the former is the clone as-is, the latter is
93549
+ * built separately by {@link buildRasterPictureElement} once the binding has
93550
+ * rasterized it.
93551
+ */
93552
+ function applyPasteSpecialFormat(element, format) {
93553
+ switch (format) {
93554
+ case 'use-destination-theme':
93555
+ return stripSourceThemeOverrides(element);
93556
+ case 'keep-text-only':
93557
+ return toTextOnly(element);
93558
+ case 'keep-source-formatting':
93559
+ case 'picture':
93560
+ default:
93561
+ return element;
93562
+ }
93563
+ }
93564
+ /**
93565
+ * Build the "Picture" paste result: the pasted element's own id/position/
93566
+ * rotation, but reduced to a flattened raster image. The binding rasterizes
93567
+ * the mounted clone's DOM node (the same `rasterizeElement` pipeline
93568
+ * `save-as-picture.ts` uses) and hands the resulting data URL here; this
93569
+ * function only assembles the resulting element so the decision of what a
93570
+ * "Picture" paste contains stays in one place for all five bindings.
93571
+ */
93572
+ function buildRasterPictureElement(element, dataUrl) {
93573
+ return {
93574
+ type: 'picture',
93575
+ id: element.id,
93576
+ x: element.x,
93577
+ y: element.y,
93578
+ width: element.width,
93579
+ height: element.height,
93580
+ rotation: element.rotation,
93581
+ imageData: dataUrl,
93582
+ };
93583
+ }
93584
+
93022
93585
  /**
93023
93586
  * action-buttons.ts: Action-button insertion (Insert > Action) shared across
93024
93587
  * bindings. Builds the OOXML built-in action-button shapes: a labelled
@@ -98021,6 +98584,102 @@ function shouldShowMediaFullscreenStopButton(input) {
98021
98584
  return isMediaFullscreenActive(input);
98022
98585
  }
98023
98586
 
98587
+ /**
98588
+ * The `<iframe allow="...">` Permissions Policy value every binding's
98589
+ * online-video embed uses, so a provider capability (fullscreen, PiP) reaches
98590
+ * all five at once instead of drifting per hand-ported copy.
98591
+ */
98592
+ const ONLINE_VIDEO_IFRAME_ALLOW = 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; fullscreen';
98593
+ /**
98594
+ * The `<iframe sandbox="...">` value every binding's online-video embed uses.
98595
+ * YouTube/Vimeo's own player needs `allow-scripts` (it is a full web app) and
98596
+ * `allow-same-origin` (their own origin, never the host page's, so this does
98597
+ * not weaken the host); `allow-popups` covers the player's "Share"/"Watch on
98598
+ * YouTube" links, and `allow-presentation` its cast button. Deliberately
98599
+ * narrower than "no sandbox at all": still blocks top-level navigation and
98600
+ * form submission from the embedded page.
98601
+ */
98602
+ const ONLINE_VIDEO_IFRAME_SANDBOX = 'allow-scripts allow-same-origin allow-popups allow-presentation';
98603
+ /** Extract a YouTube video id from a `youtube.com`/`youtu.be` URL, in any of its common forms. */
98604
+ function youtubeVideoId(url) {
98605
+ const host = url.hostname.replace(/^www\./, '').toLowerCase();
98606
+ if (host === 'youtu.be') {
98607
+ const id = url.pathname.split('/').filter(Boolean)[0];
98608
+ return id || undefined;
98609
+ }
98610
+ if (host !== 'youtube.com' && host !== 'm.youtube.com' && host !== 'youtube-nocookie.com') {
98611
+ return undefined;
98612
+ }
98613
+ if (url.pathname.startsWith('/embed/')) {
98614
+ return url.pathname.slice('/embed/'.length).split('/')[0] || undefined;
98615
+ }
98616
+ const watchId = url.searchParams.get('v');
98617
+ if (watchId) {
98618
+ return watchId;
98619
+ }
98620
+ const shortsMatch = /^\/shorts\/([^/]+)/.exec(url.pathname);
98621
+ if (shortsMatch) {
98622
+ return shortsMatch[1];
98623
+ }
98624
+ return undefined;
98625
+ }
98626
+ /** Extract a Vimeo video id from a `vimeo.com`/`player.vimeo.com` URL. */
98627
+ function vimeoVideoId(url) {
98628
+ const host = url.hostname.replace(/^www\./, '').toLowerCase();
98629
+ if (host === 'player.vimeo.com') {
98630
+ const match = /^\/video\/(\d+)/.exec(url.pathname);
98631
+ return match?.[1];
98632
+ }
98633
+ if (host !== 'vimeo.com') {
98634
+ return undefined;
98635
+ }
98636
+ const match = /^\/(?:channels\/[^/]+\/|groups\/[^/]+\/videos\/)?(\d+)/.exec(url.pathname);
98637
+ return match?.[1];
98638
+ }
98639
+ /**
98640
+ * Resolve a linked media URL to an iframe-embeddable web-video URL, or
98641
+ * `undefined` when it is not a recognised web-video host (a plain linked
98642
+ * media file, which plays through `<video>`/`<audio>` as usual).
98643
+ *
98644
+ * Only meaningful for LINKED media: an embedded (`r:embed`) video is always
98645
+ * a real media file inside the package, never a web page.
98646
+ */
98647
+ function resolveOnlineVideoEmbed(mediaPath, isLinked) {
98648
+ if (!isLinked || !mediaPath) {
98649
+ return undefined;
98650
+ }
98651
+ let url;
98652
+ try {
98653
+ url = new URL(mediaPath);
98654
+ }
98655
+ catch {
98656
+ return undefined;
98657
+ }
98658
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
98659
+ return undefined;
98660
+ }
98661
+ const youtubeId = youtubeVideoId(url);
98662
+ if (youtubeId) {
98663
+ return { embedUrl: `https://www.youtube.com/embed/${youtubeId}` };
98664
+ }
98665
+ const vimeoId = vimeoVideoId(url);
98666
+ if (vimeoId) {
98667
+ return { embedUrl: `https://player.vimeo.com/video/${vimeoId}` };
98668
+ }
98669
+ return undefined;
98670
+ }
98671
+ /**
98672
+ * Convenience wrapper over {@link resolveOnlineVideoEmbed} for a full
98673
+ * `PptxElement`: `undefined` for anything but a linked `media`/`video`
98674
+ * element whose URL resolves to a recognised web-video host.
98675
+ */
98676
+ function getOnlineVideoEmbed(element) {
98677
+ if (element.type !== 'media' || element.mediaType !== 'video') {
98678
+ return undefined;
98679
+ }
98680
+ return resolveOnlineVideoEmbed(element.mediaPath, element.isLinked);
98681
+ }
98682
+
98024
98683
  /**
98025
98684
  * Attach trim-end stop and fade in/out scheduling to a media element for as
98026
98685
  * long as it keeps playing. Re-arms on every `play` (a manual replay, a loop,
@@ -98487,6 +99146,11 @@ function buildSummaryZoomView(element, lookup, translate) {
98487
99146
  number: String(slideNumber),
98488
99147
  })
98489
99148
  : `Zoom to section ${label}, slide ${slideNumber}`,
99149
+ // `CT_ZoomObjectProperties/@returnToParent`'s schema default is `true`
99150
+ // when absent (see `ZoomPptxElement.returnToParent`'s doc comment), so
99151
+ // this reads the effective value, not `Boolean(target.returnToParent)`.
99152
+ returnToParent: target.returnToParent !== false,
99153
+ transitionDurationMs: target.transitionDurationMs,
98490
99154
  };
98491
99155
  });
98492
99156
  return {
@@ -100959,6 +101623,102 @@ function titleBarStyleAttr() {
100959
101623
  .join(';');
100960
101624
  }
100961
101625
 
101626
+ /**
101627
+ * Resolve the click target for a Slide Zoom or Section Zoom element (NOT a
101628
+ * Summary Zoom, whose tiles each carry their own values; see
101629
+ * {@link resolveSummaryZoomTileNavigationTarget}).
101630
+ */
101631
+ function resolveZoomNavigationTarget(element) {
101632
+ if (element.zoomType === 'summary') {
101633
+ return undefined;
101634
+ }
101635
+ return {
101636
+ targetSlideIndex: element.targetSlideIndex,
101637
+ targetSectionId: element.targetSectionId,
101638
+ returnToParent: element.returnToParent !== false,
101639
+ transitionDurationMs: element.transitionDurationMs,
101640
+ };
101641
+ }
101642
+ /** Resolve the click target for one Summary Zoom tile (its own `zmPr`, not the container's mirrored copy). */
101643
+ function resolveSummaryZoomTileNavigationTarget(tile) {
101644
+ if (!tile) {
101645
+ return undefined;
101646
+ }
101647
+ return {
101648
+ targetSlideIndex: tile.targetSlideIndex,
101649
+ targetSectionId: tile.sectionId,
101650
+ returnToParent: tile.returnToParent !== false,
101651
+ transitionDurationMs: tile.transitionDurationMs,
101652
+ };
101653
+ }
101654
+ /**
101655
+ * The last slide index (inclusive) of the zoom's target range: for a Section
101656
+ * Zoom / Summary Zoom tile, the last slide of the contiguous run of slides
101657
+ * sharing `targetSectionId` starting at `targetSlideIndex` (sections are
101658
+ * always contiguous); for a plain Slide Zoom (no section), just the target
101659
+ * slide itself.
101660
+ */
101661
+ function resolveZoomExcursionEndIndex(target, slides) {
101662
+ if (!target.targetSectionId) {
101663
+ return target.targetSlideIndex;
101664
+ }
101665
+ let end = target.targetSlideIndex;
101666
+ for (let i = target.targetSlideIndex + 1; i < slides.length; i++) {
101667
+ if (slides[i]?.sectionId !== target.targetSectionId) {
101668
+ break;
101669
+ }
101670
+ end = i;
101671
+ }
101672
+ return end;
101673
+ }
101674
+ /**
101675
+ * Begin tracking a zoom excursion for a click on `target`, or `undefined`
101676
+ * when the target's `returnToParent` is not set (a plain, one-way jump).
101677
+ */
101678
+ function beginZoomExcursion(target, returnSlideIndex, slides) {
101679
+ if (!target.returnToParent) {
101680
+ return undefined;
101681
+ }
101682
+ return {
101683
+ returnSlideIndex,
101684
+ endSlideIndex: resolveZoomExcursionEndIndex(target, slides),
101685
+ transitionDurationMs: target.transitionDurationMs,
101686
+ };
101687
+ }
101688
+ /**
101689
+ * Decide the next slide for a forward advance step, given a pending zoom
101690
+ * excursion. When the show is currently sitting on the excursion's last
101691
+ * slide, the step returns to the zoom's origin slide (and clears the
101692
+ * excursion) instead of `naturalNextIndex`. Otherwise the excursion is left
101693
+ * untouched and `naturalNextIndex` is used as-is. Backward steps should not
101694
+ * call this (PowerPoint's return jump is forward-only); a caller stepping
101695
+ * backward keeps its excursion by simply not calling this helper.
101696
+ */
101697
+ function resolveForwardSlideWithZoomReturn(currentSlideIndex, naturalNextIndex, excursion) {
101698
+ if (excursion && currentSlideIndex === excursion.endSlideIndex) {
101699
+ return {
101700
+ nextSlideIndex: excursion.returnSlideIndex,
101701
+ excursion: undefined,
101702
+ returnedToZoom: true,
101703
+ };
101704
+ }
101705
+ return { nextSlideIndex: naturalNextIndex, excursion, returnedToZoom: false };
101706
+ }
101707
+ /**
101708
+ * A synthetic `zoom`-type transition carrying the zoom's own `transitionDur`,
101709
+ * for a binding's transition executor to play INSTEAD of the destination
101710
+ * slide's own authored `<p:transition>` when navigating a Zoom click or its
101711
+ * automatic return. `undefined` when the zoom omitted `@transitionDur`
101712
+ * (per the field's doc comment, that means "use the destination slide's own
101713
+ * transition", so the caller should fall through to its normal resolution).
101714
+ */
101715
+ function buildZoomTransitionOverride(transitionDurationMs) {
101716
+ if (typeof transitionDurationMs !== 'number' || transitionDurationMs <= 0) {
101717
+ return undefined;
101718
+ }
101719
+ return { type: 'zoom', durationMs: transitionDurationMs };
101720
+ }
101721
+
100962
101722
  /**
100963
101723
  * Command-search data for the PowerPoint-style "Tell me what you want to do"
100964
101724
  * search bar. Provides searchable command entries grouped by category, each
@@ -107340,7 +108100,7 @@ function resetThreeRendererHostForTests() {
107340
108100
  }
107341
108101
 
107342
108102
  const loaders = {
107343
- chart: async () => (await import('./pptx-angular-viewer-chart-3d-view-scene-CN_ecxxS.mjs')).mountChart3DView,
108103
+ chart: async () => (await import('./pptx-angular-viewer-chart-3d-view-scene-Y6KGBCeN.mjs')).mountChart3DView,
107344
108104
  smartart: async () => (await import('./pptx-angular-viewer-view-scene-C5oUG9yl.mjs')).mountSmartArt3DView,
107345
108105
  };
107346
108106
  /** Resolve the scene factory for a spec kind. */
@@ -112661,6 +113421,69 @@ async function rasterResultToPngDataUrl(result) {
112661
113421
  });
112662
113422
  }
112663
113423
 
113424
+ /**
113425
+ * "Save as Picture" (the element context-menu command PowerPoint offers on
113426
+ * pictures, shapes, charts and SmartArt alike): rasterise one already-mounted
113427
+ * element node to PNG and hand it straight to the browser's download
113428
+ * mechanism.
113429
+ *
113430
+ * Every binding already rasterises a single element for other purposes
113431
+ * (export-to-PNG, "copy slide as image"): this module is the same
113432
+ * `rasterizeElement` + `rasterResultToPngBlob` + `downloadBlob` pipeline, with
113433
+ * the one extra step (a default file name) a context-menu command needs and a
113434
+ * plain export button does not. Kept here, once, instead of five bindings
113435
+ * each re-deriving the tiled/untiled branch and the download call.
113436
+ *
113437
+ * @module export/save-element-as-picture
113438
+ */
113439
+ /**
113440
+ * Build the default download name for a saved element picture, e.g.
113441
+ * `My Shape.png` or `Picture 1.png` when the element has no display name.
113442
+ *
113443
+ * @param elementName - The element's own name/title, when the host tracks one.
113444
+ * @param fallbackLabel - A translated generic label ("Picture", "Shape", ...)
113445
+ * used when `elementName` is empty; each binding supplies its own
113446
+ * translator so the fallback is localised without this module importing i18n.
113447
+ */
113448
+ function elementPictureFilename(elementName, fallbackLabel) {
113449
+ const base = elementName?.trim() || fallbackLabel;
113450
+ return sanitizeDownloadFilename(`${base}.png`);
113451
+ }
113452
+ /**
113453
+ * Rasterise `node` (an attached element, `naturalWidth` x `naturalHeight` CSS
113454
+ * pixels) and immediately download it as a PNG.
113455
+ *
113456
+ * @param node - The mounted DOM node for the single element (not the whole slide).
113457
+ * @param naturalWidth - The element's un-scaled width in CSS pixels.
113458
+ * @param naturalHeight - The element's un-scaled height in CSS pixels.
113459
+ * @param doc - The owner document (matches `rasterizeElement`'s signature; a
113460
+ * presentation-mode or popped-out window may render into a different one).
113461
+ * @param filename - The suggested download name; sanitized by `downloadBlob`.
113462
+ * @param options - Forwarded to `rasterizeElement` (scale, background,
113463
+ * the binding's `html2canvasFallback` driver, etc.).
113464
+ */
113465
+ async function saveElementAsPicture(node, naturalWidth, naturalHeight, doc, filename, options) {
113466
+ const result = await rasterizeElement(node, naturalWidth, naturalHeight, doc, options);
113467
+ const blob = await rasterResultToPngBlob(result);
113468
+ downloadBlob(blob, filename);
113469
+ }
113470
+ /**
113471
+ * Rasterise `node` to a PNG data URL rather than downloading it: the same
113472
+ * pipeline as {@link saveElementAsPicture}, for Paste Special / Paste
113473
+ * Options's "Picture" format, which needs the pixels as an embeddable
113474
+ * `imageData` string, not a file on disk.
113475
+ *
113476
+ * @param node - The mounted DOM node for the single element (not the whole slide).
113477
+ * @param naturalWidth - The element's un-scaled width in CSS pixels.
113478
+ * @param naturalHeight - The element's un-scaled height in CSS pixels.
113479
+ * @param doc - The owner document.
113480
+ * @param options - Forwarded to `rasterizeElement`.
113481
+ */
113482
+ async function rasterizeElementToDataUrl(node, naturalWidth, naturalHeight, doc, options) {
113483
+ const result = await rasterizeElement(node, naturalWidth, naturalHeight, doc, options);
113484
+ return rasterResultToPngDataUrl(result);
113485
+ }
113486
+
112664
113487
  /**
112665
113488
  * Framework-agnostic EXPORT helpers shared by the React, Vue, and Angular
112666
113489
  * `pptx-viewer` bindings. These are the PURE portions of the export pipeline —
@@ -114678,7 +115501,7 @@ function createLocalStorageBackend(namespace) {
114678
115501
  /** Try IndexedDB first; fall back to localStorage on any failure. */
114679
115502
  async function resolveBackend(dbName, namespace) {
114680
115503
  try {
114681
- const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-CQafSmT3.mjs');
115504
+ const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-BgAmw1ty.mjs');
114682
115505
  const db = await openChatDb(dbName);
114683
115506
  return createIdbBackend(db);
114684
115507
  }
@@ -119504,6 +120327,21 @@ function runContextMenuCommand(id, actions) {
119504
120327
  case 'delete':
119505
120328
  actions.remove();
119506
120329
  break;
120330
+ case 'edit-text':
120331
+ actions.editText();
120332
+ break;
120333
+ case 'save-as-picture':
120334
+ actions.saveAsPicture();
120335
+ break;
120336
+ case 'edit-alt-text':
120337
+ actions.editAltText();
120338
+ break;
120339
+ case 'size-and-position':
120340
+ actions.sizeAndPosition();
120341
+ break;
120342
+ case 'format-shape':
120343
+ actions.formatShape();
120344
+ break;
119507
120345
  default:
119508
120346
  break;
119509
120347
  }
@@ -120608,6 +121446,13 @@ class EditorStateService {
120608
121446
  /** Whether the clipboard holds copied elements (enables paste). */
120609
121447
  this.hasClipboard = signal(false, /* @ts-ignore */
120610
121448
  ...(ngDevMode ? [{ debugName: "hasClipboard" }] : /* istanbul ignore next */ []));
121449
+ // ── Paste Special / Paste Options ──────────────────────────────────────
121450
+ /** Ctrl/Cmd+Alt+V dialog visibility. */
121451
+ this.isPasteSpecialDialogOpen = signal(false, /* @ts-ignore */
121452
+ ...(ngDevMode ? [{ debugName: "isPasteSpecialDialogOpen" }] : /* istanbul ignore next */ []));
121453
+ /** The Paste Options toolbar's target: the elements a normal paste just inserted. */
121454
+ this.pasteOptionsToolbar = signal(null, /* @ts-ignore */
121455
+ ...(ngDevMode ? [{ debugName: "pasteOptionsToolbar" }] : /* istanbul ignore next */ []));
120611
121456
  this.idCounter = 0;
120612
121457
  }
120613
121458
  /**
@@ -121089,6 +121934,54 @@ class EditorStateService {
121089
121934
  this.selectedIds.set(newIds);
121090
121935
  this.dirty.set(true);
121091
121936
  this.syncHistory();
121937
+ // A plain paste IS "Keep Source Formatting": each clone is its own
121938
+ // pristine source, so the Paste Options toolbar's later choices always
121939
+ // re-derive from it, never from an already-transformed element.
121940
+ this.pasteOptionsToolbar.set(additions.map((sourceClone) => ({ id: sourceClone.id, sourceClone })));
121941
+ }
121942
+ /**
121943
+ * Paste Special (Ctrl+Alt+V) / the dialog's OK: paste the clipboard with one
121944
+ * of the four PowerPoint formats already applied, and hand back each
121945
+ * inserted element's id alongside its own pristine "Keep Source Formatting"
121946
+ * clone, so the Paste Options toolbar can re-derive from it non-cumulatively.
121947
+ */
121948
+ pasteWithFormat(slideIndex, format) {
121949
+ if (this.clipboard.length === 0) {
121950
+ return [];
121951
+ }
121952
+ const slides = this.slides();
121953
+ if (!slides[slideIndex]) {
121954
+ return [];
121955
+ }
121956
+ this.history.record(this.captureSnapshot(), this.t('pptx.undoAction.paste'));
121957
+ const sourceClones = this.clipboard.map((el) => cloneElementForPaste(el, { intoTemplate: isTemplateElementId(el.id) }));
121958
+ // "Picture" is inserted as the plain clone first (there is nothing to
121959
+ // rasterize before it is mounted); every other format applies immediately.
121960
+ const additions = sourceClones.map((clone) => format === 'picture' ? clone : applyPasteSpecialFormat(clone, format));
121961
+ this.slides.set(slides.map((slide, i) => i === slideIndex ? { ...slide, elements: [...slide.elements, ...additions] } : slide));
121962
+ this.selectedIds.set(additions.map((el) => el.id));
121963
+ this.dirty.set(true);
121964
+ this.syncHistory();
121965
+ const entries = sourceClones.map((sourceClone, i) => ({ id: additions[i].id, sourceClone }));
121966
+ this.pasteOptionsToolbar.set(entries);
121967
+ return entries;
121968
+ }
121969
+ /**
121970
+ * Re-derive already-pasted elements (the Paste Options toolbar) from their
121971
+ * own pristine source clones. Non-cumulative: every choice starts over from
121972
+ * the clone `pasteWithFormat` returned, matching PowerPoint's own toolbar.
121973
+ * "Picture" is handled by the caller (it needs a DOM rasterize step this
121974
+ * service does not perform) via a plain `updateElement` call instead.
121975
+ */
121976
+ reformatPasted(slideIndex, entries, format) {
121977
+ const slides = this.slides();
121978
+ const slide = slides[slideIndex];
121979
+ if (!slide) {
121980
+ return;
121981
+ }
121982
+ const byId = new Map(entries.map((e) => [e.id, applyPasteSpecialFormat(e.sourceClone, format)]));
121983
+ this.slides.set(slides.map((s, i) => i === slideIndex ? { ...s, elements: s.elements.map((el) => byId.get(el.id) ?? el) } : s));
121984
+ this.dirty.set(true);
121092
121985
  }
121093
121986
  // ── Element insertion ────────────────────────────────────────────────────
121094
121987
  /** Append a new element to a slide (records history) and select it. */
@@ -121394,6 +122287,258 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
121394
122287
  type: Injectable
121395
122288
  }] });
121396
122289
 
122290
+ /**
122291
+ * swipe-dismiss.ts: Reusable pointer-drag-to-dismiss gesture for a docked
122292
+ * sheet/panel that lives in normal document flow (not a fixed overlay), so a
122293
+ * downward swipe is surfaced as a live drag offset (applied via a CSS
122294
+ * transform) rather than relying on a native overlay's dismiss gesture.
122295
+ *
122296
+ * Shared by the mobile notes sheet and the mobile inspector host in
122297
+ * {@link PowerPointViewerComponent}, which both need identical drag-to-dismiss
122298
+ * behaviour, differing only in what happens once the drag clears the
122299
+ * threshold (their own `onDismiss` callback).
122300
+ */
122301
+ /** Downward drag distance (px) past which releasing the pointer dismisses. Matches `pptx-mobile-sheet`'s DISMISS_THRESHOLD. */
122302
+ const DISMISS_THRESHOLD_PX = 120;
122303
+ /**
122304
+ * Create an independent swipe-to-dismiss drag tracker. `onDismiss` fires once,
122305
+ * on pointer-up, when the downward drag exceeded {@link DISMISS_THRESHOLD_PX}.
122306
+ */
122307
+ function createSwipeDismissDrag(onDismiss) {
122308
+ const dragYSignal = signal(0, /* @ts-ignore */
122309
+ ...(ngDevMode ? [{ debugName: "dragYSignal" }] : /* istanbul ignore next */ []));
122310
+ const draggingSignal = signal(false, /* @ts-ignore */
122311
+ ...(ngDevMode ? [{ debugName: "draggingSignal" }] : /* istanbul ignore next */ []));
122312
+ let startY = null;
122313
+ return {
122314
+ dragY: dragYSignal,
122315
+ dragging: draggingSignal,
122316
+ onPointerDown(event) {
122317
+ startY = event.clientY;
122318
+ draggingSignal.set(true);
122319
+ event.target.setPointerCapture?.(event.pointerId);
122320
+ },
122321
+ onPointerMove(event) {
122322
+ if (startY === null) {
122323
+ return;
122324
+ }
122325
+ dragYSignal.set(Math.max(0, event.clientY - startY));
122326
+ },
122327
+ onPointerUp(event) {
122328
+ if (startY === null) {
122329
+ return;
122330
+ }
122331
+ const delta = event.clientY - startY;
122332
+ startY = null;
122333
+ draggingSignal.set(false);
122334
+ event.target.releasePointerCapture?.(event.pointerId);
122335
+ if (delta > DISMISS_THRESHOLD_PX) {
122336
+ onDismiss();
122337
+ }
122338
+ dragYSignal.set(0);
122339
+ },
122340
+ };
122341
+ }
122342
+
122343
+ /**
122344
+ * viewer-inspector-panel.service.ts: Viewer-scoped state + logic for the
122345
+ * single right-docked inspector host: which explicit tool panel (comments /
122346
+ * accessibility / signatures / selection) is toggled on, the derived "what
122347
+ * should the host actually show" precedence (explicit panel → element →
122348
+ * slide default), its mobile-only swipe-to-dismiss drag, and the accessible
122349
+ * label per shown content.
122350
+ *
122351
+ * Extracted from {@link PowerPointViewerComponent}: the component binds the
122352
+ * accessors it alone owns (canEdit / selected-element / active-slide) via
122353
+ * {@link bind}; the template reads the signals/computeds off the injected
122354
+ * instance directly (same pattern as `session`/`xport`).
122355
+ *
122356
+ * Provide it once on the viewer component (`providers: [ViewerInspectorPanelService]`).
122357
+ */
122358
+ class ViewerInspectorPanelService {
122359
+ constructor() {
122360
+ this.mobile = inject(IsMobileService);
122361
+ /** Active right-docked tool panel (comments / accessibility / selection), or null. */
122362
+ this.activePanel = signal(null, /* @ts-ignore */
122363
+ ...(ngDevMode ? [{ debugName: "activePanel" }] : /* istanbul ignore next */ []));
122364
+ /** True once the user swiped the inspector away on mobile (until reopened). */
122365
+ this.mobileInspectorHidden = signal(false, /* @ts-ignore */
122366
+ ...(ngDevMode ? [{ debugName: "mobileInspectorHidden" }] : /* istanbul ignore next */ []));
122367
+ /**
122368
+ * True once the user has explicitly closed the format (element/slide)
122369
+ * panel via the ribbon toggle - independent of selection, mirroring
122370
+ * React's/Vue's own open/closed toggle state. Never affects the explicit
122371
+ * tool panels (comments/accessibility/signatures/selection), which show
122372
+ * regardless of this flag.
122373
+ *
122374
+ * Starts closed on mobile so the canvas owns the screen on first paint and
122375
+ * the format pane's tab strip (with its own Comments button) never collides
122376
+ * with the mobile bottom bar; the bottom bar's "Format" slot opens it
122377
+ * explicitly instead. Mirrors React's `isInspectorPaneOpen` initializer
122378
+ * (open on desktop, closed under the mobile breakpoint).
122379
+ */
122380
+ this.formatPanelClosed = signal(this.mobile.isMobile(), /* @ts-ignore */
122381
+ ...(ngDevMode ? [{ debugName: "formatPanelClosed" }] : /* istanbul ignore next */ []));
122382
+ /**
122383
+ * Swipe-to-dismiss drag for the inspector host. The host docks in-flow below
122384
+ * the canvas on mobile (same keyboard-reachability reason as the notes
122385
+ * sheet), so the gesture is wired here rather than via a fixed-overlay
122386
+ * dismiss. Clearing the past-threshold drag also closes any open tool panel.
122387
+ */
122388
+ this.inspectorDrag = createSwipeDismissDrag(() => this.dismissMobileInspector());
122389
+ this.host = null;
122390
+ /**
122391
+ * Which panel the single inspector host should show, applying the original
122392
+ * first-match precedence (explicit tool panels → element → slide default).
122393
+ * `accessibility`/`signatures` render regardless of edit mode; the rest need
122394
+ * `canEdit`.
122395
+ */
122396
+ this.inspectorContent = computed(() => {
122397
+ const host = this.requireHost();
122398
+ const panel = this.activePanel();
122399
+ if (panel === 'accessibility') {
122400
+ return 'accessibility';
122401
+ }
122402
+ if (panel === 'signatures') {
122403
+ return 'signatures';
122404
+ }
122405
+ if (!host.canEdit()) {
122406
+ return null;
122407
+ }
122408
+ if (panel === 'comments') {
122409
+ return 'comments';
122410
+ }
122411
+ if (panel === 'selection') {
122412
+ return 'selection';
122413
+ }
122414
+ if (host.selectedElement()) {
122415
+ return 'element';
122416
+ }
122417
+ if (host.activeSlide()) {
122418
+ return 'slide';
122419
+ }
122420
+ return null;
122421
+ }, /* @ts-ignore */
122422
+ ...(ngDevMode ? [{ debugName: "inspectorContent" }] : /* istanbul ignore next */ []));
122423
+ /**
122424
+ * `inspectorContent`, but the format (element/slide) view collapses to
122425
+ * `null` once the user has explicitly closed it via the ribbon toggle.
122426
+ * Explicit tool panels (comments/accessibility/etc.) are untouched.
122427
+ */
122428
+ this.formatPanelContent = computed(() => {
122429
+ const content = this.inspectorContent();
122430
+ if ((content === 'element' || content === 'slide') && this.formatPanelClosed()) {
122431
+ return null;
122432
+ }
122433
+ return content;
122434
+ }, /* @ts-ignore */
122435
+ ...(ngDevMode ? [{ debugName: "formatPanelContent" }] : /* istanbul ignore next */ []));
122436
+ /**
122437
+ * Whether the right-docked inspector is showing the format panel (element or
122438
+ * slide properties). Drives the top-bar inspector-toggle active state.
122439
+ */
122440
+ this.inspectorPaneOpen = computed(() => {
122441
+ const content = this.formatPanelContent();
122442
+ return content === 'element' || content === 'slide';
122443
+ }, /* @ts-ignore */
122444
+ ...(ngDevMode ? [{ debugName: "inspectorPaneOpen" }] : /* istanbul ignore next */ []));
122445
+ /** Inspector content, but null on mobile once the user has swiped it away. */
122446
+ this.visibleInspectorKind = computed(() => this.mobile.isMobile() && this.mobileInspectorHidden() ? null : this.formatPanelContent(), /* @ts-ignore */
122447
+ ...(ngDevMode ? [{ debugName: "visibleInspectorKind" }] : /* istanbul ignore next */ []));
122448
+ /** Accessible-label translation key for the inspector host, by active content. */
122449
+ this.inspectorLabel = computed(() => {
122450
+ switch (this.inspectorContent()) {
122451
+ case 'accessibility':
122452
+ return 'pptx.accessibility.title';
122453
+ case 'signatures':
122454
+ return 'pptx.viewer.digitalSignatures';
122455
+ case 'comments':
122456
+ return 'pptx.toolbar.comments';
122457
+ case 'selection':
122458
+ return 'pptx.selectionPane.title';
122459
+ case 'element':
122460
+ return 'pptx.inspector.properties';
122461
+ case 'slide':
122462
+ return 'pptx.inspector.properties';
122463
+ default:
122464
+ return '';
122465
+ }
122466
+ }, /* @ts-ignore */
122467
+ ...(ngDevMode ? [{ debugName: "inspectorLabel" }] : /* istanbul ignore next */ []));
122468
+ /**
122469
+ * Ribbon "toggle inspector" action: if a tool panel is active, return to
122470
+ * the format (element/slide) view; otherwise toggle the format view's
122471
+ * open/closed state, matching React's and Vue's independent open/close
122472
+ * toggle (closing/opening is not tied to selection changes).
122473
+ */
122474
+ /**
122475
+ * Monotonic counter bumped by {@link openAnimationPanel}; the inspector
122476
+ * panel reacts to every change by expanding its Animation section, so a
122477
+ * user who collapsed it by hand gets it back on the next ribbon click.
122478
+ */
122479
+ this.animationPanelRequest = signal(0, /* @ts-ignore */
122480
+ ...(ngDevMode ? [{ debugName: "animationPanelRequest" }] : /* istanbul ignore next */ []));
122481
+ }
122482
+ /** Wire the host accessors (called once from the component constructor). */
122483
+ bind(host) {
122484
+ this.host = host;
122485
+ }
122486
+ requireHost() {
122487
+ if (!this.host) {
122488
+ throw new Error('ViewerInspectorPanelService.bind() was not called');
122489
+ }
122490
+ return this.host;
122491
+ }
122492
+ /**
122493
+ * Dismiss the mobile bottom-sheet inspector (backdrop tap or a past-threshold
122494
+ * swipe-down): hide the host until reopened and clear any explicit tool panel.
122495
+ */
122496
+ dismissMobileInspector() {
122497
+ this.mobileInspectorHidden.set(true);
122498
+ this.activePanel.set(null);
122499
+ }
122500
+ /** Toggle a right-docked tool panel (clicking the active one closes it). */
122501
+ togglePanel(panel) {
122502
+ this.activePanel.update((current) => (current === panel ? null : panel));
122503
+ // Tapping a panel button re-opens the host even after a swipe-dismiss.
122504
+ this.mobileInspectorHidden.set(false);
122505
+ }
122506
+ /**
122507
+ * Mobile bottom-bar "Format" slot: close any explicit tool panel, reopen
122508
+ * the format (element/slide) view, and undo a prior swipe-dismiss so the
122509
+ * pane is guaranteed to surface (React parity: the Format button opens the
122510
+ * inspector that starts closed on mobile).
122511
+ */
122512
+ openFormatPanel() {
122513
+ this.activePanel.set(null);
122514
+ this.formatPanelClosed.set(false);
122515
+ this.mobileInspectorHidden.set(false);
122516
+ }
122517
+ /**
122518
+ * Ribbon "Animation Panel": surface the format view like
122519
+ * {@link openFormatPanel} AND expand the inspector's Animation section
122520
+ * (React's `onOpenAnimationPanel` lands on those controls directly).
122521
+ */
122522
+ openAnimationPanel() {
122523
+ this.openFormatPanel();
122524
+ this.animationPanelRequest.update((n) => n + 1);
122525
+ }
122526
+ toggleFormatPanel() {
122527
+ if (this.activePanel() !== null) {
122528
+ this.activePanel.set(null);
122529
+ this.formatPanelClosed.set(false);
122530
+ }
122531
+ else {
122532
+ this.formatPanelClosed.update((closed) => !closed);
122533
+ }
122534
+ }
122535
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ViewerInspectorPanelService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
122536
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ViewerInspectorPanelService }); }
122537
+ }
122538
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ViewerInspectorPanelService, decorators: [{
122539
+ type: Injectable
122540
+ }] });
122541
+
121397
122542
  /**
121398
122543
  * editor-context-menu.component.ts: Right-click context menu for the Angular
121399
122544
  * PPTX editor.
@@ -121463,9 +122608,20 @@ class EditorContextMenuComponent {
121463
122608
  this.editHyperlink = output();
121464
122609
  /** "Add Comment": open the right-docked comments panel, as React does. */
121465
122610
  this.addComment = output();
122611
+ /**
122612
+ * "Edit Text": the host owns the same inline-text-edit entry point a
122613
+ * double-click uses, so the menu just asks for it on the current element.
122614
+ */
122615
+ this.editText = output();
122616
+ /**
122617
+ * "Save as Picture": the host owns the DOM lookup + html2canvas fallback
122618
+ * driver this needs, so the menu asks for it on the current element.
122619
+ */
122620
+ this.saveAsPicture = output();
121466
122621
  this.editor = inject(EditorStateService);
121467
122622
  this.tableSelection = inject(TableSelectionService, { optional: true });
121468
122623
  this.host = inject(ElementRef);
122624
+ this.inspectorPanel = inject(ViewerInspectorPanelService);
121469
122625
  /**
121470
122626
  * The table element + cell selection the menu should act on, or null when the
121471
122627
  * current selection is not a single table with a selected cell. Drives the
@@ -121532,6 +122688,11 @@ class EditorContextMenuComponent {
121532
122688
  group: () => this.editor.groupSelected(this.slideIndex()),
121533
122689
  ungroup: () => this.editor.ungroupSelected(this.slideIndex()),
121534
122690
  remove: () => this.editor.deleteSelected(this.slideIndex()),
122691
+ editText: () => this.editText.emit(),
122692
+ saveAsPicture: () => this.saveAsPicture.emit(),
122693
+ editAltText: () => this.focusInspectorSection('edit-alt-text'),
122694
+ sizeAndPosition: () => this.focusInspectorSection('size-and-position'),
122695
+ formatShape: () => this.focusInspectorSection('format-shape'),
121535
122696
  applyTable: (op) => this.applyTable(op),
121536
122697
  };
121537
122698
  }
@@ -121554,6 +122715,24 @@ class EditorContextMenuComponent {
121554
122715
  runContextMenuCommand(id, this.actions);
121555
122716
  this.closed.emit();
121556
122717
  }
122718
+ /**
122719
+ * "Edit Alt Text" / "Size and Position" / "Format Shape": open the
122720
+ * properties tab (clearing any explicit tool panel so the element view
122721
+ * shows through) and, once the panel has re-rendered, scroll the matching
122722
+ * inspector section into view. A binding-wide no-op when the section has
122723
+ * not been tagged, so this never fails loudly.
122724
+ */
122725
+ focusInspectorSection(commandId) {
122726
+ this.inspectorPanel.formatPanelClosed.set(false);
122727
+ this.inspectorPanel.activePanel.set(null);
122728
+ const anchor = contextMenuInspectorAnchor(commandId);
122729
+ if (!anchor) {
122730
+ return;
122731
+ }
122732
+ requestAnimationFrame(() => {
122733
+ requestAnimationFrame(() => scrollInspectorSectionIntoView(document, anchor));
122734
+ });
122735
+ }
121557
122736
  /**
121558
122737
  * Run a pure table transform on the current table context and commit the
121559
122738
  * result through the editor (one undoable history entry).
@@ -121575,7 +122754,7 @@ class EditorContextMenuComponent {
121575
122754
  }
121576
122755
  }
121577
122756
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: EditorContextMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
121578
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: EditorContextMenuComponent, isStandalone: true, selector: "pptx-editor-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 }, slideIndex: { classPropertyName: "slideIndex", publicName: "slideIndex", isSignal: true, isRequired: true, transformFunction: null }, showAiActions: { classPropertyName: "showAiActions", publicName: "showAiActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed", askAi: "askAi", fixAi: "fixAi", editHyperlink: "editHyperlink", addComment: "addComment" }, 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: `
122757
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: EditorContextMenuComponent, isStandalone: true, selector: "pptx-editor-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 }, slideIndex: { classPropertyName: "slideIndex", publicName: "slideIndex", isSignal: true, isRequired: true, transformFunction: null }, showAiActions: { classPropertyName: "showAiActions", publicName: "showAiActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed", askAi: "askAi", fixAi: "fixAi", editHyperlink: "editHyperlink", addComment: "addComment", editText: "editText", saveAsPicture: "saveAsPicture" }, 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: `
121579
122758
  <!-- data-pptx-context-menu is the neutral cross-binding hook for "this is
121580
122759
  the canvas context menu", alongside the role. -->
121581
122760
  <ul
@@ -121637,7 +122816,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
121637
122816
  '[style.--pptx-ctx-x]': 'x() + "px"',
121638
122817
  '[style.--pptx-ctx-y]': 'y() + "px"',
121639
122818
  }, 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"] }]
121640
- }], propDecorators: { x: [{ type: i0.Input, args: [{ isSignal: true, alias: "x", required: true }] }], y: [{ type: i0.Input, args: [{ isSignal: true, alias: "y", required: true }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: true }] }], showAiActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAiActions", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], askAi: [{ type: i0.Output, args: ["askAi"] }], fixAi: [{ type: i0.Output, args: ["fixAi"] }], editHyperlink: [{ type: i0.Output, args: ["editHyperlink"] }], addComment: [{ type: i0.Output, args: ["addComment"] }], onEscape: [{
122819
+ }], propDecorators: { x: [{ type: i0.Input, args: [{ isSignal: true, alias: "x", required: true }] }], y: [{ type: i0.Input, args: [{ isSignal: true, alias: "y", required: true }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: true }] }], showAiActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAiActions", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], askAi: [{ type: i0.Output, args: ["askAi"] }], fixAi: [{ type: i0.Output, args: ["fixAi"] }], editHyperlink: [{ type: i0.Output, args: ["editHyperlink"] }], addComment: [{ type: i0.Output, args: ["addComment"] }], editText: [{ type: i0.Output, args: ["editText"] }], saveAsPicture: [{ type: i0.Output, args: ["saveAsPicture"] }], onEscape: [{
121641
122820
  type: HostListener,
121642
122821
  args: ['document:keydown.escape']
121643
122822
  }], onDocumentPointerDown: [{
@@ -122524,6 +123703,167 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
122524
123703
  `, styles: [".pptx-ng-export-progress__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-export-progress{display:flex;flex-direction:column;width:min(92vw,384px);padding:1.5rem;border:1px solid rgba(255,255,255,.12);border-radius:.75rem;background:#1e1e1e;color:#e5e5e5;box-shadow:0 20px 60px #0009}.pptx-ng-export-progress__title{margin:0 0 1rem;font-size:.875rem;font-weight:600;color:#fff}.pptx-ng-export-progress__track{width:100%;height:.625rem;margin-bottom:.75rem;overflow:hidden;border-radius:9999px;background:#ffffff1f}.pptx-ng-export-progress__fill{height:100%;border-radius:9999px;background:#2563eb;transition:width .3s ease-out}.pptx-ng-export-progress__status{display:flex;align-items:center;justify-content:space-between;margin-bottom:1rem;font-size:.75rem;color:#fff9}.pptx-ng-export-progress__pct{font-variant-numeric:tabular-nums}.pptx-ng-export-progress__actions{display:flex;justify-content:flex-end}.pptx-ng-export-progress__btn{padding:.375rem 1rem;font-size:.75rem;color:#e5e5e5;border:1px solid rgba(255,255,255,.16);border-radius:.375rem;background:#ffffff0f;cursor:pointer;transition:background .15s ease}.pptx-ng-export-progress__btn:hover{background:#ffffff1f}\n"] }]
122525
123704
  }], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], progress: [{ type: i0.Input, args: [{ isSignal: true, alias: "progress", required: false }] }], statusMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "statusMessage", required: false }] }], cancel: [{ type: i0.Output, args: ["cancel"] }] } });
122526
123705
 
123706
+ /**
123707
+ * A drop-in replacement for `html2canvas(element, options)` that first
123708
+ * resolves any oklch / oklab / lch / lab / color() values in the cloned
123709
+ * DOM to rgb()/hex, preventing parse errors in html2canvas <= 1.x, then
123710
+ * applies the CSS preprocessing pipeline.
123711
+ *
123712
+ * Usage:
123713
+ * ```ts
123714
+ * import { renderToCanvas } from '../lib/canvas-export';
123715
+ * const canvas = await renderToCanvas(element, { scale: 2 });
123716
+ * ```
123717
+ */
123718
+ async function renderToCanvas(element, options = {}) {
123719
+ const userOnClone = options.onclone;
123720
+ const { default: html2canvasPro } = await import('html2canvas-pro');
123721
+ return html2canvasPro(element, {
123722
+ ...options,
123723
+ onclone: async (doc, clonedEl) => {
123724
+ prepareExportClone(clonedEl);
123725
+ await normalizeColorsForCapture(doc, clonedEl);
123726
+ preprocessCssForCapture(clonedEl);
123727
+ if (typeof userOnClone === 'function') {
123728
+ userOnClone(doc, clonedEl);
123729
+ }
123730
+ },
123731
+ });
123732
+ }
123733
+
123734
+ /**
123735
+ * Pure export helper utilities: thin re-export shim.
123736
+ *
123737
+ * The page-size / orientation / file-name maths now lives once in
123738
+ * `pptx-viewer-shared` (`export/pdf-page-size`), inlined here at build time via
123739
+ * `../internal/shared-src`. This module preserves the historical import path for
123740
+ * the Angular export service, components, and tests.
123741
+ */
123742
+
123743
+ /**
123744
+ * Tile-aware rasterisation + tiled-PDF assembly, split out of
123745
+ * `export.service.ts` to keep that file under the file-size budget.
123746
+ *
123747
+ * Every raster entry point here goes through the shared `foreignObject`
123748
+ * fidelity pipeline (`pptx-viewer-shared`'s `rasterizeElement` /
123749
+ * `rasterizeElementTiledToCanvas` / `rasterizeElementTiles`), with
123750
+ * `html2canvas-pro` kept only as the documented fallback driver. This is the
123751
+ * one place in the Angular binding that touches that driver directly.
123752
+ */
123753
+ /**
123754
+ * The `html2canvasFallback` driver every shared rasterize call needs, bound
123755
+ * to one element, so the html2canvas-pro adapter is written once, not
123756
+ * hand-copied per raster entry point.
123757
+ */
123758
+ function html2canvasFallbackFor(el) {
123759
+ return (sourceRect, outputSize) => renderToCanvas(el, {
123760
+ ignoreElements: isExportIgnoredElement,
123761
+ scale: outputSize.width / (sourceRect.width || 1),
123762
+ x: sourceRect.x,
123763
+ y: sourceRect.y,
123764
+ width: sourceRect.width,
123765
+ height: sourceRect.height,
123766
+ });
123767
+ }
123768
+ /** The element's natural (1x) CSS-pixel size the shared rasterizers scale from. */
123769
+ function naturalSizeOf(el) {
123770
+ const rect = el.getBoundingClientRect();
123771
+ return { width: rect.width || el.offsetWidth, height: rect.height || el.offsetHeight };
123772
+ }
123773
+ /**
123774
+ * Rasterize `el` to a PNG `Blob` via the shared `foreignObject` -> vector-SVG
123775
+ * -> html2canvas fallback chain (preserves backdrop-filter, CSS custom
123776
+ * properties and 3D transforms html2canvas cannot), tiling transparently
123777
+ * for a resolution beyond the browser's canvas cap - for PNG download and
123778
+ * "copy slide as image", whose PNG encoder can consume tiled output.
123779
+ */
123780
+ async function renderElementPngBlob(el, scale = 2) {
123781
+ const { width, height } = naturalSizeOf(el);
123782
+ const result = await rasterizeElement(el, width, height, el.ownerDocument, {
123783
+ scale,
123784
+ html2canvasFallback: html2canvasFallbackFor(el),
123785
+ });
123786
+ return rasterResultToPngBlob(result);
123787
+ }
123788
+ /**
123789
+ * `renderElementPngBlob`'s data-URL sibling: for a caller (Paste Special's
123790
+ * "Picture" format) that needs the pixels embedded as a data URL, not a
123791
+ * `Blob` to download.
123792
+ */
123793
+ async function renderElementPngDataUrl(el, scale = 2) {
123794
+ const { width, height } = naturalSizeOf(el);
123795
+ const result = await rasterizeElement(el, width, height, el.ownerDocument, {
123796
+ scale,
123797
+ html2canvasFallback: html2canvasFallbackFor(el),
123798
+ });
123799
+ return rasterResultToPngDataUrl(result);
123800
+ }
123801
+ /**
123802
+ * Rasterize a single element to a single full-resolution canvas via the
123803
+ * shared `foreignObject` fidelity pipeline, tiling and stitching
123804
+ * transparently (never reducing the requested scale) so the result is always
123805
+ * one canvas - for GIF/video/print, which can only consume one image per
123806
+ * frame/page. Capture each slide's canvas *while that slide is the live
123807
+ * DOM*: the viewer reuses one stage node, so a deferred capture would yield
123808
+ * the same (last) slide for every page.
123809
+ */
123810
+ async function renderElementTiled(el, scale = 2) {
123811
+ const { width, height } = naturalSizeOf(el);
123812
+ const result = await rasterizeElementTiledToCanvas(el, width, height, el.ownerDocument, {
123813
+ scale,
123814
+ html2canvasFallback: html2canvasFallbackFor(el),
123815
+ });
123816
+ return result.canvas;
123817
+ }
123818
+ /**
123819
+ * Rasterize a single element to its raw per-tile canvases via the shared
123820
+ * `foreignObject` fidelity pipeline, tiling transparently when the requested
123821
+ * resolution exceeds the browser's canvas cap - for PDF pages, which have no
123822
+ * canvas-size limit of their own and so can place several small tile images
123823
+ * instead of needing one oversized canvas.
123824
+ */
123825
+ async function renderElementTilesRaster(el, scale = 2) {
123826
+ const { width, height } = naturalSizeOf(el);
123827
+ return rasterizeElementTiles(el, width, height, el.ownerDocument, {
123828
+ scale,
123829
+ html2canvasFallback: html2canvasFallbackFor(el),
123830
+ });
123831
+ }
123832
+ /**
123833
+ * Assemble a multi-page PDF from pre-rendered per-slide tile sets (one page
123834
+ * per entry) and trigger a download. Each tile is placed at its proportional
123835
+ * position on the page (`placeTileOnPage`); a single-tile slide (the
123836
+ * overwhelming majority) degrades to exactly one full-page image per page,
123837
+ * unchanged from before tiling existed. Escapes the browser canvas cap:
123838
+ * every tile is individually small, and a PDF page has no canvas-size limit
123839
+ * of its own.
123840
+ *
123841
+ * @param pages - One entry per slide, in order, each captured while
123842
+ * its slide was the live stage (`renderElementTilesRaster`).
123843
+ * @param canvasWidth - Slide canvas width in pixels (for aspect ratio).
123844
+ * @param canvasHeight - Slide canvas height in pixels (for aspect ratio).
123845
+ * @param fileName - Suggested download file name (unsafe chars stripped).
123846
+ */
123847
+ function buildTiledPdf(pages, canvasWidth, canvasHeight, fileName) {
123848
+ if (pages.length === 0) {
123849
+ throw new Error('[ExportService] No slide pages provided for PDF export');
123850
+ }
123851
+ const { width: pageW, height: pageH, orientation } = pdfPageSize(canvasWidth, canvasHeight);
123852
+ const doc = new jsPDF({ orientation, unit: 'pt', format: [pageW, pageH] });
123853
+ for (let i = 0; i < pages.length; i++) {
123854
+ if (i > 0) {
123855
+ doc.addPage([pageW, pageH], orientation);
123856
+ }
123857
+ const { fullWidth, fullHeight, tiles } = pages[i];
123858
+ for (const tile of tiles) {
123859
+ const jpegBytes = canvasToJpegData(tile.canvas, 0.92).bytes;
123860
+ const placement = placeTileOnPage(tile, fullWidth, fullHeight, pageW, pageH);
123861
+ doc.addImage(jpegBytes, 'JPEG', placement.x, placement.y, placement.width, placement.height);
123862
+ }
123863
+ }
123864
+ doc.save(sanitizeDownloadFilename(fileName));
123865
+ }
123866
+
122527
123867
  /**
122528
123868
  * Thin re-export shim → vendored `pptx-viewer-shared` (`render/slide-search`).
122529
123869
  *
@@ -130124,6 +131464,7 @@ class MediaRendererComponent {
130124
131464
  this.fallbackIcon = computed(() => mediaFallbackIcon(this.fallback(), this.mediaKind()), /* @ts-ignore */
130125
131465
  ...(ngDevMode ? [{ debugName: "fallbackIcon" }] : /* istanbul ignore next */ []));
130126
131466
  this.translate = inject(TranslateService);
131467
+ this.sanitizer = inject(DomSanitizer);
130127
131468
  this.fallbackLabel = computed(() => {
130128
131469
  const key = mediaFallbackLabelKey(this.fallback(), this.mediaKind());
130129
131470
  return key === undefined ? '' : this.translate.instant(key);
@@ -130153,6 +131494,28 @@ class MediaRendererComponent {
130153
131494
  return media ? resolveMediaSrc(media, this.mediaDataUrls()) : undefined;
130154
131495
  }, /* @ts-ignore */
130155
131496
  ...(ngDevMode ? [{ debugName: "mediaSrc" }] : /* istanbul ignore next */ []));
131497
+ /**
131498
+ * A linked YouTube/Vimeo URL is a web page, not a media stream: `<video
131499
+ * src>` cannot decode it and shows nothing. Resolved to the provider's own
131500
+ * iframe-embeddable URL; a normal linked/embedded media file (`mediaSrc`
131501
+ * resolves to a Blob/data URL) keeps using the native `<video>` below.
131502
+ *
131503
+ * `bypassSecurityTrustResourceUrl` is safe here: `getOnlineVideoEmbed`
131504
+ * only ever builds `https://www.youtube.com/embed/<id>` or
131505
+ * `https://player.vimeo.com/video/<id>`, never an author-controlled raw
131506
+ * string, so there is nothing for Angular's resource-URL sanitizer to
131507
+ * usefully block. Without it Angular strips the binding to `about:blank`.
131508
+ */
131509
+ this.onlineVideoEmbedUrl = computed(() => {
131510
+ const embedUrl = getOnlineVideoEmbed(this.element())?.embedUrl;
131511
+ return embedUrl ? this.sanitizer.bypassSecurityTrustResourceUrl(embedUrl) : undefined;
131512
+ }, /* @ts-ignore */
131513
+ ...(ngDevMode ? [{ debugName: "onlineVideoEmbedUrl" }] : /* istanbul ignore next */ []));
131514
+ this.onlineVideoTitle = computed(() => this.translate.instant('pptx.media.onlineVideoTitle'), /* @ts-ignore */
131515
+ ...(ngDevMode ? [{ debugName: "onlineVideoTitle" }] : /* istanbul ignore next */ []));
131516
+ /** Shared Permissions Policy / sandbox values; see `online-video.ts`'s doc comments. */
131517
+ this.onlineVideoAllow = ONLINE_VIDEO_IFRAME_ALLOW;
131518
+ this.onlineVideoSandbox = ONLINE_VIDEO_IFRAME_SANDBOX;
130156
131519
  this.mediaKind = computed(() => asMediaElement(this.element())?.mediaType, /* @ts-ignore */
130157
131520
  ...(ngDevMode ? [{ debugName: "mediaKind" }] : /* istanbul ignore next */ []));
130158
131521
  this.loop = computed(() => asMediaElement(this.element())?.loop === true, /* @ts-ignore */
@@ -130254,7 +131617,18 @@ class MediaRendererComponent {
130254
131617
  @if (hitTargetStyle(); as hit) {
130255
131618
  <div aria-hidden="true" data-pptx-hit-target="true" [ngStyle]="hit"></div>
130256
131619
  }
130257
- @if (mediaSrc(); as src) {
131620
+ @if (onlineVideoEmbedUrl(); as embedUrl) {
131621
+ <iframe
131622
+ class="pptx-ng-media-el pptx-ng-media-video"
131623
+ [class.pptx-ng-media-inert]="interactive()"
131624
+ [src]="embedUrl"
131625
+ [title]="onlineVideoTitle()"
131626
+ [attr.allow]="onlineVideoAllow"
131627
+ [attr.sandbox]="onlineVideoSandbox"
131628
+ allowfullscreen
131629
+ style="border: 0"
131630
+ ></iframe>
131631
+ } @else if (mediaSrc(); as src) {
130258
131632
  @if (mediaKind() === 'audio') {
130259
131633
  <audio
130260
131634
  #mediaEl
@@ -130372,7 +131746,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
130372
131746
  @if (hitTargetStyle(); as hit) {
130373
131747
  <div aria-hidden="true" data-pptx-hit-target="true" [ngStyle]="hit"></div>
130374
131748
  }
130375
- @if (mediaSrc(); as src) {
131749
+ @if (onlineVideoEmbedUrl(); as embedUrl) {
131750
+ <iframe
131751
+ class="pptx-ng-media-el pptx-ng-media-video"
131752
+ [class.pptx-ng-media-inert]="interactive()"
131753
+ [src]="embedUrl"
131754
+ [title]="onlineVideoTitle()"
131755
+ [attr.allow]="onlineVideoAllow"
131756
+ [attr.sandbox]="onlineVideoSandbox"
131757
+ allowfullscreen
131758
+ style="border: 0"
131759
+ ></iframe>
131760
+ } @else if (mediaSrc(); as src) {
130376
131761
  @if (mediaKind() === 'audio') {
130377
131762
  <audio
130378
131763
  #mediaEl
@@ -130794,6 +132179,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
130794
132179
  function getOleDownloadFileName(el) {
130795
132180
  return el.oleEmbeddedFileName ?? el.fileName ?? 'embedded-object';
130796
132181
  }
132182
+ /**
132183
+ * Whether {@link OleRendererComponent}'s Download / Open action bar may
132184
+ * render at all, mirroring `media-renderer-helpers.ts`'s `mediaSurfaceFor`.
132185
+ *
132186
+ * A still of a slide (thumbnail rail, presenter console panes, export
132187
+ * raster) renders this component INSIDE a
132188
+ * `<button aria-label="Go to slide N">`, so the action bar's own `<button>`
132189
+ * would otherwise be invalid, un-clickable nested-button markup; the live
132190
+ * presentation stage never offers element-level browser chrome either. See
132191
+ * the shared `oleActionsVisible` decision.
132192
+ */
132193
+ function oleActionsVisibleFor(interactive, presenting) {
132194
+ return oleActionsVisible(mediaSurfaceOf({ interactive, presenting }));
132195
+ }
130797
132196
  /**
130798
132197
  * Build the descriptive info rows shown in the OLE caption.
130799
132198
  *
@@ -130873,6 +132272,24 @@ class OleRendererComponent {
130873
132272
  /** The element to render. Must be `type === 'ole'`. */
130874
132273
  this.element = input.required(/* @ts-ignore */
130875
132274
  ...(ngDevMode ? [{ debugName: "element" }] : /* istanbul ignore next */ []));
132275
+ /** True only on the main editable canvas; see `showActions`. */
132276
+ this.interactive = input(true, /* @ts-ignore */
132277
+ ...(ngDevMode ? [{ debugName: "interactive" }] : /* istanbul ignore next */ []));
132278
+ /** True only on the live presentation stage; see `showActions`. */
132279
+ this.presenting = input(false, /* @ts-ignore */
132280
+ ...(ngDevMode ? [{ debugName: "presenting" }] : /* istanbul ignore next */ []));
132281
+ /**
132282
+ * Whether the Download / Open action bar may render at all.
132283
+ *
132284
+ * A still of a slide (thumbnail rail, presenter console panes, export
132285
+ * raster) renders this component INSIDE a
132286
+ * `<button aria-label="Go to slide N">`, so the action bar's own
132287
+ * `<button>` would otherwise be invalid, un-clickable nested-button
132288
+ * markup; the live presentation stage never offers element-level browser
132289
+ * chrome either.
132290
+ */
132291
+ this.showActions = computed(() => oleActionsVisibleFor(this.interactive(), this.presenting()), /* @ts-ignore */
132292
+ ...(ngDevMode ? [{ debugName: "showActions" }] : /* istanbul ignore next */ []));
130876
132293
  /** Narrowed OLE element: undefined when the input is not `type === 'ole'`. */
130877
132294
  this.ole = computed(() => {
130878
132295
  const el = this.element();
@@ -130971,12 +132388,12 @@ class OleRendererComponent {
130971
132388
  }
130972
132389
  }
130973
132390
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: OleRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
130974
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: OleRendererComponent, isStandalone: true, selector: "pptx-ole-renderer", inputs: { element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"pptx-ng-ole\" role=\"img\" [attr.aria-label]=\"ariaLabel()\" [attr.title]=\"infoTitle()\">\n\t@if (previewSrc()) {\n\t\t<!-- Preview image with type-badge overlay -->\n\t\t<div class=\"pptx-ng-ole-preview\">\n\t\t\t<img\n\t\t\t\t[src]=\"previewSrc()\"\n\t\t\t\t[attr.alt]=\"ariaLabel()\"\n\t\t\t\tclass=\"pptx-ng-ole-img\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t/>\n\t\t\t<svg class=\"pptx-ng-ole-badge\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\">\n\t\t\t\t<rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"3\" [attr.fill]=\"typeColor()\" />\n\t\t\t\t<text\n\t\t\t\t\tx=\"12\"\n\t\t\t\t\ty=\"16\"\n\t\t\t\t\ttext-anchor=\"middle\"\n\t\t\t\t\tfill=\"white\"\n\t\t\t\t\t[attr.font-size]=\"badgeLabel().length > 4 ? 6 : 10\"\n\t\t\t\t\tfont-weight=\"bold\"\n\t\t\t\t>\n\t\t\t\t\t{{ badgeLabel() }}\n\t\t\t\t</text>\n\t\t\t</svg>\n\t\t</div>\n\t} @else {\n\t\t<!-- Type-specific placeholder box -->\n\t\t<div class=\"pptx-ng-ole-placeholder\" [ngStyle]=\"placeholderStyle()\">\n\t\t\t<svg width=\"36\" height=\"36\" viewBox=\"0 0 24 24\" fill=\"none\">\n\t\t\t\t@for (shape of iconShapes(); track $index) {\n\t\t\t\t\t@switch (shape.tag) {\n\t\t\t\t\t\t@case ('rect') {\n\t\t\t\t\t\t\t<rect\n\t\t\t\t\t\t\t\t[attr.x]=\"shape.attrs['x']\"\n\t\t\t\t\t\t\t\t[attr.y]=\"shape.attrs['y']\"\n\t\t\t\t\t\t\t\t[attr.width]=\"shape.attrs['width']\"\n\t\t\t\t\t\t\t\t[attr.height]=\"shape.attrs['height']\"\n\t\t\t\t\t\t\t\t[attr.rx]=\"shape.attrs['rx']\"\n\t\t\t\t\t\t\t\t[attr.stroke]=\"typeColor()\"\n\t\t\t\t\t\t\t\t[attr.stroke-width]=\"shape.attrs['stroke-width']\"\n\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@case ('line') {\n\t\t\t\t\t\t\t<line\n\t\t\t\t\t\t\t\t[attr.x1]=\"shape.attrs['x1']\"\n\t\t\t\t\t\t\t\t[attr.y1]=\"shape.attrs['y1']\"\n\t\t\t\t\t\t\t\t[attr.x2]=\"shape.attrs['x2']\"\n\t\t\t\t\t\t\t\t[attr.y2]=\"shape.attrs['y2']\"\n\t\t\t\t\t\t\t\t[attr.stroke]=\"typeColor()\"\n\t\t\t\t\t\t\t\t[attr.stroke-width]=\"shape.attrs['stroke-width']\"\n\t\t\t\t\t\t\t\t[attr.stroke-linecap]=\"shape.attrs['stroke-linecap']\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@case ('text') {\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t[attr.x]=\"shape.attrs['x']\"\n\t\t\t\t\t\t\t\t[attr.y]=\"shape.attrs['y']\"\n\t\t\t\t\t\t\t\ttext-anchor=\"middle\"\n\t\t\t\t\t\t\t\t[attr.fill]=\"typeColor()\"\n\t\t\t\t\t\t\t\t[attr.font-size]=\"shape.attrs['font-size']\"\n\t\t\t\t\t\t\t\tfont-weight=\"bold\"\n\t\t\t\t\t\t\t\t[attr.font-style]=\"shape.attrs['font-style']\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{{ shape.text }}\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</svg>\n\t\t\t<span class=\"pptx-ng-ole-name\" [ngStyle]=\"{ color: typeColor() }\">{{ displayName() }}</span>\n\t\t\t@if (fileName()) {\n\t\t\t\t<span class=\"pptx-ng-ole-sublabel\">{{ typeLabel() }}</span>\n\t\t\t}\n\t\t</div>\n\t}\n\t@if (actions().canDownload) {\n\t\t<!--\n\t\t\tDownload / Open actions for the recovered embedded payload.\n\t\t\tPointer events are isolated so clicking an action never starts a\n\t\t\tselection/drag of the underlying element; the controls are\n\t\t\tkeyboard-focusable and only paint on hover / focus-within.\n\t\t-->\n\t\t<div\n\t\t\tclass=\"pptx-ng-ole-actions\"\n\t\t\t(pointerdown)=\"$event.stopPropagation()\"\n\t\t\t(mousedown)=\"$event.stopPropagation()\"\n\t\t>\n\t\t\t<a\n\t\t\t\tclass=\"pptx-ng-ole-action\"\n\t\t\t\t[href]=\"actions().downloadHref\"\n\t\t\t\t[attr.download]=\"actions().downloadFileName\"\n\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t'pptx.ole.downloadFileAria' | translate: { file: actions().downloadFileName }\n\t\t\t\t\"\n\t\t\t\t(click)=\"$event.stopPropagation()\"\n\t\t\t>\n\t\t\t\t{{ 'pptx.ole.download' | translate }}\n\t\t\t</a>\n\t\t\t@if (actions().canOpen) {\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-ole-action\"\n\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t'pptx.ole.openFileAria' | translate: { file: actions().downloadFileName }\n\t\t\t\t\t\"\n\t\t\t\t\t(click)=\"$event.stopPropagation(); openEmbedded()\"\n\t\t\t\t>\n\t\t\t\t\t{{ 'pptx.ole.open' | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t</div>\n\t}\n</div>\n", styles: [".pptx-ng-ole{position:relative;box-sizing:border-box;width:100%;height:100%}.pptx-ng-ole-preview{position:relative;width:100%;height:100%}.pptx-ng-ole-img{width:100%;height:100%;object-fit:contain;pointer-events:none;-webkit-user-select:none;user-select:none;display:block}.pptx-ng-ole-badge{position:absolute;bottom:4px;right:4px;z-index:10}.pptx-ng-ole-placeholder{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;pointer-events:none;box-sizing:border-box}.pptx-ng-ole-name{margin-top:8px;font-size:12px;font-weight:500;max-width:90%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pptx-ng-ole-sublabel{margin-top:2px;font-size:10px;color:#00000073;max-width:90%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pptx-ng-ole-actions{position:absolute;bottom:4px;left:4px;display:flex;gap:4px;z-index:11;opacity:0;transition:opacity .12s ease-in-out}.pptx-ng-ole:hover .pptx-ng-ole-actions,.pptx-ng-ole-actions:focus-within{opacity:1}.pptx-ng-ole-action{font-size:11px;line-height:1;padding:4px 8px;border-radius:4px;background-color:#000000b8;color:#fff;text-decoration:none;cursor:pointer;white-space:nowrap;pointer-events:auto}.pptx-ng-ole-action:hover{background-color:#000000d9}.pptx-ng-ole-action:focus-visible{outline:2px solid #fff;outline-offset:1px}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
132391
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: OleRendererComponent, isStandalone: true, selector: "pptx-ole-renderer", inputs: { element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, presenting: { classPropertyName: "presenting", publicName: "presenting", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"pptx-ng-ole\" role=\"img\" [attr.aria-label]=\"ariaLabel()\" [attr.title]=\"infoTitle()\">\n\t@if (previewSrc()) {\n\t\t<!-- Preview image with type-badge overlay -->\n\t\t<div class=\"pptx-ng-ole-preview\">\n\t\t\t<img\n\t\t\t\t[src]=\"previewSrc()\"\n\t\t\t\t[attr.alt]=\"ariaLabel()\"\n\t\t\t\tclass=\"pptx-ng-ole-img\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t/>\n\t\t\t<svg class=\"pptx-ng-ole-badge\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\">\n\t\t\t\t<rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"3\" [attr.fill]=\"typeColor()\" />\n\t\t\t\t<text\n\t\t\t\t\tx=\"12\"\n\t\t\t\t\ty=\"16\"\n\t\t\t\t\ttext-anchor=\"middle\"\n\t\t\t\t\tfill=\"white\"\n\t\t\t\t\t[attr.font-size]=\"badgeLabel().length > 4 ? 6 : 10\"\n\t\t\t\t\tfont-weight=\"bold\"\n\t\t\t\t>\n\t\t\t\t\t{{ badgeLabel() }}\n\t\t\t\t</text>\n\t\t\t</svg>\n\t\t</div>\n\t} @else {\n\t\t<!-- Type-specific placeholder box -->\n\t\t<div class=\"pptx-ng-ole-placeholder\" [ngStyle]=\"placeholderStyle()\">\n\t\t\t<svg width=\"36\" height=\"36\" viewBox=\"0 0 24 24\" fill=\"none\">\n\t\t\t\t@for (shape of iconShapes(); track $index) {\n\t\t\t\t\t@switch (shape.tag) {\n\t\t\t\t\t\t@case ('rect') {\n\t\t\t\t\t\t\t<rect\n\t\t\t\t\t\t\t\t[attr.x]=\"shape.attrs['x']\"\n\t\t\t\t\t\t\t\t[attr.y]=\"shape.attrs['y']\"\n\t\t\t\t\t\t\t\t[attr.width]=\"shape.attrs['width']\"\n\t\t\t\t\t\t\t\t[attr.height]=\"shape.attrs['height']\"\n\t\t\t\t\t\t\t\t[attr.rx]=\"shape.attrs['rx']\"\n\t\t\t\t\t\t\t\t[attr.stroke]=\"typeColor()\"\n\t\t\t\t\t\t\t\t[attr.stroke-width]=\"shape.attrs['stroke-width']\"\n\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@case ('line') {\n\t\t\t\t\t\t\t<line\n\t\t\t\t\t\t\t\t[attr.x1]=\"shape.attrs['x1']\"\n\t\t\t\t\t\t\t\t[attr.y1]=\"shape.attrs['y1']\"\n\t\t\t\t\t\t\t\t[attr.x2]=\"shape.attrs['x2']\"\n\t\t\t\t\t\t\t\t[attr.y2]=\"shape.attrs['y2']\"\n\t\t\t\t\t\t\t\t[attr.stroke]=\"typeColor()\"\n\t\t\t\t\t\t\t\t[attr.stroke-width]=\"shape.attrs['stroke-width']\"\n\t\t\t\t\t\t\t\t[attr.stroke-linecap]=\"shape.attrs['stroke-linecap']\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@case ('text') {\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t[attr.x]=\"shape.attrs['x']\"\n\t\t\t\t\t\t\t\t[attr.y]=\"shape.attrs['y']\"\n\t\t\t\t\t\t\t\ttext-anchor=\"middle\"\n\t\t\t\t\t\t\t\t[attr.fill]=\"typeColor()\"\n\t\t\t\t\t\t\t\t[attr.font-size]=\"shape.attrs['font-size']\"\n\t\t\t\t\t\t\t\tfont-weight=\"bold\"\n\t\t\t\t\t\t\t\t[attr.font-style]=\"shape.attrs['font-style']\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{{ shape.text }}\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</svg>\n\t\t\t<span class=\"pptx-ng-ole-name\" [ngStyle]=\"{ color: typeColor() }\">{{ displayName() }}</span>\n\t\t\t@if (fileName()) {\n\t\t\t\t<span class=\"pptx-ng-ole-sublabel\">{{ typeLabel() }}</span>\n\t\t\t}\n\t\t</div>\n\t}\n\t@if (actions().canDownload && showActions()) {\n\t\t<!--\n\t\t\tDownload / Open actions for the recovered embedded payload.\n\t\t\tPointer events are isolated so clicking an action never starts a\n\t\t\tselection/drag of the underlying element; the controls are\n\t\t\tkeyboard-focusable and only paint on hover / focus-within.\n\t\t-->\n\t\t<div\n\t\t\tclass=\"pptx-ng-ole-actions\"\n\t\t\t(pointerdown)=\"$event.stopPropagation()\"\n\t\t\t(mousedown)=\"$event.stopPropagation()\"\n\t\t>\n\t\t\t<a\n\t\t\t\tclass=\"pptx-ng-ole-action\"\n\t\t\t\t[href]=\"actions().downloadHref\"\n\t\t\t\t[attr.download]=\"actions().downloadFileName\"\n\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t'pptx.ole.downloadFileAria' | translate: { file: actions().downloadFileName }\n\t\t\t\t\"\n\t\t\t\t(click)=\"$event.stopPropagation()\"\n\t\t\t>\n\t\t\t\t{{ 'pptx.ole.download' | translate }}\n\t\t\t</a>\n\t\t\t@if (actions().canOpen) {\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-ole-action\"\n\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t'pptx.ole.openFileAria' | translate: { file: actions().downloadFileName }\n\t\t\t\t\t\"\n\t\t\t\t\t(click)=\"$event.stopPropagation(); openEmbedded()\"\n\t\t\t\t>\n\t\t\t\t\t{{ 'pptx.ole.open' | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t</div>\n\t}\n</div>\n", styles: [".pptx-ng-ole{position:relative;box-sizing:border-box;width:100%;height:100%}.pptx-ng-ole-preview{position:relative;width:100%;height:100%}.pptx-ng-ole-img{width:100%;height:100%;object-fit:contain;pointer-events:none;-webkit-user-select:none;user-select:none;display:block}.pptx-ng-ole-badge{position:absolute;bottom:4px;right:4px;z-index:10}.pptx-ng-ole-placeholder{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;pointer-events:none;box-sizing:border-box}.pptx-ng-ole-name{margin-top:8px;font-size:12px;font-weight:500;max-width:90%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pptx-ng-ole-sublabel{margin-top:2px;font-size:10px;color:#00000073;max-width:90%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pptx-ng-ole-actions{position:absolute;bottom:4px;left:4px;display:flex;gap:4px;z-index:11;opacity:0;transition:opacity .12s ease-in-out}.pptx-ng-ole:hover .pptx-ng-ole-actions,.pptx-ng-ole-actions:focus-within{opacity:1}.pptx-ng-ole-action{font-size:11px;line-height:1;padding:4px 8px;border-radius:4px;background-color:#000000b8;color:#fff;text-decoration:none;cursor:pointer;white-space:nowrap;pointer-events:auto}.pptx-ng-ole-action:hover{background-color:#000000d9}.pptx-ng-ole-action:focus-visible{outline:2px solid #fff;outline-offset:1px}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
130975
132392
  }
130976
132393
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: OleRendererComponent, decorators: [{
130977
132394
  type: Component,
130978
- args: [{ selector: 'pptx-ole-renderer', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgStyle, TranslatePipe], template: "<div class=\"pptx-ng-ole\" role=\"img\" [attr.aria-label]=\"ariaLabel()\" [attr.title]=\"infoTitle()\">\n\t@if (previewSrc()) {\n\t\t<!-- Preview image with type-badge overlay -->\n\t\t<div class=\"pptx-ng-ole-preview\">\n\t\t\t<img\n\t\t\t\t[src]=\"previewSrc()\"\n\t\t\t\t[attr.alt]=\"ariaLabel()\"\n\t\t\t\tclass=\"pptx-ng-ole-img\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t/>\n\t\t\t<svg class=\"pptx-ng-ole-badge\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\">\n\t\t\t\t<rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"3\" [attr.fill]=\"typeColor()\" />\n\t\t\t\t<text\n\t\t\t\t\tx=\"12\"\n\t\t\t\t\ty=\"16\"\n\t\t\t\t\ttext-anchor=\"middle\"\n\t\t\t\t\tfill=\"white\"\n\t\t\t\t\t[attr.font-size]=\"badgeLabel().length > 4 ? 6 : 10\"\n\t\t\t\t\tfont-weight=\"bold\"\n\t\t\t\t>\n\t\t\t\t\t{{ badgeLabel() }}\n\t\t\t\t</text>\n\t\t\t</svg>\n\t\t</div>\n\t} @else {\n\t\t<!-- Type-specific placeholder box -->\n\t\t<div class=\"pptx-ng-ole-placeholder\" [ngStyle]=\"placeholderStyle()\">\n\t\t\t<svg width=\"36\" height=\"36\" viewBox=\"0 0 24 24\" fill=\"none\">\n\t\t\t\t@for (shape of iconShapes(); track $index) {\n\t\t\t\t\t@switch (shape.tag) {\n\t\t\t\t\t\t@case ('rect') {\n\t\t\t\t\t\t\t<rect\n\t\t\t\t\t\t\t\t[attr.x]=\"shape.attrs['x']\"\n\t\t\t\t\t\t\t\t[attr.y]=\"shape.attrs['y']\"\n\t\t\t\t\t\t\t\t[attr.width]=\"shape.attrs['width']\"\n\t\t\t\t\t\t\t\t[attr.height]=\"shape.attrs['height']\"\n\t\t\t\t\t\t\t\t[attr.rx]=\"shape.attrs['rx']\"\n\t\t\t\t\t\t\t\t[attr.stroke]=\"typeColor()\"\n\t\t\t\t\t\t\t\t[attr.stroke-width]=\"shape.attrs['stroke-width']\"\n\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@case ('line') {\n\t\t\t\t\t\t\t<line\n\t\t\t\t\t\t\t\t[attr.x1]=\"shape.attrs['x1']\"\n\t\t\t\t\t\t\t\t[attr.y1]=\"shape.attrs['y1']\"\n\t\t\t\t\t\t\t\t[attr.x2]=\"shape.attrs['x2']\"\n\t\t\t\t\t\t\t\t[attr.y2]=\"shape.attrs['y2']\"\n\t\t\t\t\t\t\t\t[attr.stroke]=\"typeColor()\"\n\t\t\t\t\t\t\t\t[attr.stroke-width]=\"shape.attrs['stroke-width']\"\n\t\t\t\t\t\t\t\t[attr.stroke-linecap]=\"shape.attrs['stroke-linecap']\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@case ('text') {\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t[attr.x]=\"shape.attrs['x']\"\n\t\t\t\t\t\t\t\t[attr.y]=\"shape.attrs['y']\"\n\t\t\t\t\t\t\t\ttext-anchor=\"middle\"\n\t\t\t\t\t\t\t\t[attr.fill]=\"typeColor()\"\n\t\t\t\t\t\t\t\t[attr.font-size]=\"shape.attrs['font-size']\"\n\t\t\t\t\t\t\t\tfont-weight=\"bold\"\n\t\t\t\t\t\t\t\t[attr.font-style]=\"shape.attrs['font-style']\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{{ shape.text }}\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</svg>\n\t\t\t<span class=\"pptx-ng-ole-name\" [ngStyle]=\"{ color: typeColor() }\">{{ displayName() }}</span>\n\t\t\t@if (fileName()) {\n\t\t\t\t<span class=\"pptx-ng-ole-sublabel\">{{ typeLabel() }}</span>\n\t\t\t}\n\t\t</div>\n\t}\n\t@if (actions().canDownload) {\n\t\t<!--\n\t\t\tDownload / Open actions for the recovered embedded payload.\n\t\t\tPointer events are isolated so clicking an action never starts a\n\t\t\tselection/drag of the underlying element; the controls are\n\t\t\tkeyboard-focusable and only paint on hover / focus-within.\n\t\t-->\n\t\t<div\n\t\t\tclass=\"pptx-ng-ole-actions\"\n\t\t\t(pointerdown)=\"$event.stopPropagation()\"\n\t\t\t(mousedown)=\"$event.stopPropagation()\"\n\t\t>\n\t\t\t<a\n\t\t\t\tclass=\"pptx-ng-ole-action\"\n\t\t\t\t[href]=\"actions().downloadHref\"\n\t\t\t\t[attr.download]=\"actions().downloadFileName\"\n\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t'pptx.ole.downloadFileAria' | translate: { file: actions().downloadFileName }\n\t\t\t\t\"\n\t\t\t\t(click)=\"$event.stopPropagation()\"\n\t\t\t>\n\t\t\t\t{{ 'pptx.ole.download' | translate }}\n\t\t\t</a>\n\t\t\t@if (actions().canOpen) {\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-ole-action\"\n\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t'pptx.ole.openFileAria' | translate: { file: actions().downloadFileName }\n\t\t\t\t\t\"\n\t\t\t\t\t(click)=\"$event.stopPropagation(); openEmbedded()\"\n\t\t\t\t>\n\t\t\t\t\t{{ 'pptx.ole.open' | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t</div>\n\t}\n</div>\n", styles: [".pptx-ng-ole{position:relative;box-sizing:border-box;width:100%;height:100%}.pptx-ng-ole-preview{position:relative;width:100%;height:100%}.pptx-ng-ole-img{width:100%;height:100%;object-fit:contain;pointer-events:none;-webkit-user-select:none;user-select:none;display:block}.pptx-ng-ole-badge{position:absolute;bottom:4px;right:4px;z-index:10}.pptx-ng-ole-placeholder{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;pointer-events:none;box-sizing:border-box}.pptx-ng-ole-name{margin-top:8px;font-size:12px;font-weight:500;max-width:90%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pptx-ng-ole-sublabel{margin-top:2px;font-size:10px;color:#00000073;max-width:90%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pptx-ng-ole-actions{position:absolute;bottom:4px;left:4px;display:flex;gap:4px;z-index:11;opacity:0;transition:opacity .12s ease-in-out}.pptx-ng-ole:hover .pptx-ng-ole-actions,.pptx-ng-ole-actions:focus-within{opacity:1}.pptx-ng-ole-action{font-size:11px;line-height:1;padding:4px 8px;border-radius:4px;background-color:#000000b8;color:#fff;text-decoration:none;cursor:pointer;white-space:nowrap;pointer-events:auto}.pptx-ng-ole-action:hover{background-color:#000000d9}.pptx-ng-ole-action:focus-visible{outline:2px solid #fff;outline-offset:1px}\n"] }]
130979
- }], propDecorators: { element: [{ type: i0.Input, args: [{ isSignal: true, alias: "element", required: true }] }] } });
132395
+ args: [{ selector: 'pptx-ole-renderer', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgStyle, TranslatePipe], template: "<div class=\"pptx-ng-ole\" role=\"img\" [attr.aria-label]=\"ariaLabel()\" [attr.title]=\"infoTitle()\">\n\t@if (previewSrc()) {\n\t\t<!-- Preview image with type-badge overlay -->\n\t\t<div class=\"pptx-ng-ole-preview\">\n\t\t\t<img\n\t\t\t\t[src]=\"previewSrc()\"\n\t\t\t\t[attr.alt]=\"ariaLabel()\"\n\t\t\t\tclass=\"pptx-ng-ole-img\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t/>\n\t\t\t<svg class=\"pptx-ng-ole-badge\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\">\n\t\t\t\t<rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"3\" [attr.fill]=\"typeColor()\" />\n\t\t\t\t<text\n\t\t\t\t\tx=\"12\"\n\t\t\t\t\ty=\"16\"\n\t\t\t\t\ttext-anchor=\"middle\"\n\t\t\t\t\tfill=\"white\"\n\t\t\t\t\t[attr.font-size]=\"badgeLabel().length > 4 ? 6 : 10\"\n\t\t\t\t\tfont-weight=\"bold\"\n\t\t\t\t>\n\t\t\t\t\t{{ badgeLabel() }}\n\t\t\t\t</text>\n\t\t\t</svg>\n\t\t</div>\n\t} @else {\n\t\t<!-- Type-specific placeholder box -->\n\t\t<div class=\"pptx-ng-ole-placeholder\" [ngStyle]=\"placeholderStyle()\">\n\t\t\t<svg width=\"36\" height=\"36\" viewBox=\"0 0 24 24\" fill=\"none\">\n\t\t\t\t@for (shape of iconShapes(); track $index) {\n\t\t\t\t\t@switch (shape.tag) {\n\t\t\t\t\t\t@case ('rect') {\n\t\t\t\t\t\t\t<rect\n\t\t\t\t\t\t\t\t[attr.x]=\"shape.attrs['x']\"\n\t\t\t\t\t\t\t\t[attr.y]=\"shape.attrs['y']\"\n\t\t\t\t\t\t\t\t[attr.width]=\"shape.attrs['width']\"\n\t\t\t\t\t\t\t\t[attr.height]=\"shape.attrs['height']\"\n\t\t\t\t\t\t\t\t[attr.rx]=\"shape.attrs['rx']\"\n\t\t\t\t\t\t\t\t[attr.stroke]=\"typeColor()\"\n\t\t\t\t\t\t\t\t[attr.stroke-width]=\"shape.attrs['stroke-width']\"\n\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@case ('line') {\n\t\t\t\t\t\t\t<line\n\t\t\t\t\t\t\t\t[attr.x1]=\"shape.attrs['x1']\"\n\t\t\t\t\t\t\t\t[attr.y1]=\"shape.attrs['y1']\"\n\t\t\t\t\t\t\t\t[attr.x2]=\"shape.attrs['x2']\"\n\t\t\t\t\t\t\t\t[attr.y2]=\"shape.attrs['y2']\"\n\t\t\t\t\t\t\t\t[attr.stroke]=\"typeColor()\"\n\t\t\t\t\t\t\t\t[attr.stroke-width]=\"shape.attrs['stroke-width']\"\n\t\t\t\t\t\t\t\t[attr.stroke-linecap]=\"shape.attrs['stroke-linecap']\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@case ('text') {\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t[attr.x]=\"shape.attrs['x']\"\n\t\t\t\t\t\t\t\t[attr.y]=\"shape.attrs['y']\"\n\t\t\t\t\t\t\t\ttext-anchor=\"middle\"\n\t\t\t\t\t\t\t\t[attr.fill]=\"typeColor()\"\n\t\t\t\t\t\t\t\t[attr.font-size]=\"shape.attrs['font-size']\"\n\t\t\t\t\t\t\t\tfont-weight=\"bold\"\n\t\t\t\t\t\t\t\t[attr.font-style]=\"shape.attrs['font-style']\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{{ shape.text }}\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</svg>\n\t\t\t<span class=\"pptx-ng-ole-name\" [ngStyle]=\"{ color: typeColor() }\">{{ displayName() }}</span>\n\t\t\t@if (fileName()) {\n\t\t\t\t<span class=\"pptx-ng-ole-sublabel\">{{ typeLabel() }}</span>\n\t\t\t}\n\t\t</div>\n\t}\n\t@if (actions().canDownload && showActions()) {\n\t\t<!--\n\t\t\tDownload / Open actions for the recovered embedded payload.\n\t\t\tPointer events are isolated so clicking an action never starts a\n\t\t\tselection/drag of the underlying element; the controls are\n\t\t\tkeyboard-focusable and only paint on hover / focus-within.\n\t\t-->\n\t\t<div\n\t\t\tclass=\"pptx-ng-ole-actions\"\n\t\t\t(pointerdown)=\"$event.stopPropagation()\"\n\t\t\t(mousedown)=\"$event.stopPropagation()\"\n\t\t>\n\t\t\t<a\n\t\t\t\tclass=\"pptx-ng-ole-action\"\n\t\t\t\t[href]=\"actions().downloadHref\"\n\t\t\t\t[attr.download]=\"actions().downloadFileName\"\n\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t'pptx.ole.downloadFileAria' | translate: { file: actions().downloadFileName }\n\t\t\t\t\"\n\t\t\t\t(click)=\"$event.stopPropagation()\"\n\t\t\t>\n\t\t\t\t{{ 'pptx.ole.download' | translate }}\n\t\t\t</a>\n\t\t\t@if (actions().canOpen) {\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-ole-action\"\n\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t'pptx.ole.openFileAria' | translate: { file: actions().downloadFileName }\n\t\t\t\t\t\"\n\t\t\t\t\t(click)=\"$event.stopPropagation(); openEmbedded()\"\n\t\t\t\t>\n\t\t\t\t\t{{ 'pptx.ole.open' | translate }}\n\t\t\t\t</button>\n\t\t\t}\n\t\t</div>\n\t}\n</div>\n", styles: [".pptx-ng-ole{position:relative;box-sizing:border-box;width:100%;height:100%}.pptx-ng-ole-preview{position:relative;width:100%;height:100%}.pptx-ng-ole-img{width:100%;height:100%;object-fit:contain;pointer-events:none;-webkit-user-select:none;user-select:none;display:block}.pptx-ng-ole-badge{position:absolute;bottom:4px;right:4px;z-index:10}.pptx-ng-ole-placeholder{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;pointer-events:none;box-sizing:border-box}.pptx-ng-ole-name{margin-top:8px;font-size:12px;font-weight:500;max-width:90%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pptx-ng-ole-sublabel{margin-top:2px;font-size:10px;color:#00000073;max-width:90%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pptx-ng-ole-actions{position:absolute;bottom:4px;left:4px;display:flex;gap:4px;z-index:11;opacity:0;transition:opacity .12s ease-in-out}.pptx-ng-ole:hover .pptx-ng-ole-actions,.pptx-ng-ole-actions:focus-within{opacity:1}.pptx-ng-ole-action{font-size:11px;line-height:1;padding:4px 8px;border-radius:4px;background-color:#000000b8;color:#fff;text-decoration:none;cursor:pointer;white-space:nowrap;pointer-events:auto}.pptx-ng-ole-action:hover{background-color:#000000d9}.pptx-ng-ole-action:focus-visible{outline:2px solid #fff;outline-offset:1px}\n"] }]
132396
+ }], propDecorators: { element: [{ type: i0.Input, args: [{ isSignal: true, alias: "element", required: true }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], presenting: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenting", required: false }] }] } });
130980
132397
 
130981
132398
  /** The element's SmartArt data, or `undefined` when it isn't a SmartArt element. */
130982
132399
  function getSmartArtData(element) {
@@ -131628,11 +133045,11 @@ class ZoomNavigationService {
131628
133045
  this.handler = handler;
131629
133046
  }
131630
133047
  /**
131631
- * Navigate the running presentation to a zoom element's target slide.
131632
- * No-op when no handler has been registered.
133048
+ * Navigate the running presentation to a zoom's target. No-op when no
133049
+ * handler has been registered.
131633
133050
  */
131634
- navigateToZoomTarget(targetSlideIndex) {
131635
- this.handler?.(targetSlideIndex);
133051
+ navigateToZoomTarget(target) {
133052
+ this.handler?.(target);
131636
133053
  }
131637
133054
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ZoomNavigationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
131638
133055
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ZoomNavigationService }); }
@@ -131866,15 +133283,18 @@ class ZoomRendererComponent {
131866
133283
  ...(ngDevMode ? [{ debugName: "interactive" }] : /* istanbul ignore next */ []));
131867
133284
  }
131868
133285
  /** Navigate to the zoom target; no-op when the tile is not interactive. */
131869
- activate(target = this.vm().targetSlideIndex) {
133286
+ activate() {
131870
133287
  const vm = this.vm();
131871
133288
  if (!this.zoomNavigation || !vm.zoom) {
131872
133289
  return;
131873
133290
  }
131874
- this.zoomNavigation.navigateToZoomTarget(target);
133291
+ const target = resolveZoomNavigationTarget(vm.zoom);
133292
+ if (target) {
133293
+ this.zoomNavigation.navigateToZoomTarget(target);
133294
+ }
131875
133295
  }
131876
- activateSummary(event, target) {
131877
- if (!this.interactive()) {
133296
+ activateSummary(event, tile) {
133297
+ if (!this.interactive() || !this.zoomNavigation) {
131878
133298
  return;
131879
133299
  }
131880
133300
  if (event instanceof KeyboardEvent && !isZoomActivationKey(event.key)) {
@@ -131882,7 +133302,12 @@ class ZoomRendererComponent {
131882
133302
  }
131883
133303
  event.preventDefault();
131884
133304
  event.stopPropagation();
131885
- this.activate(target);
133305
+ this.zoomNavigation.navigateToZoomTarget({
133306
+ targetSlideIndex: tile.targetSlideIndex,
133307
+ targetSectionId: tile.sectionId,
133308
+ returnToParent: tile.returnToParent,
133309
+ transitionDurationMs: tile.transitionDurationMs,
133310
+ });
131886
133311
  }
131887
133312
  onClick(event) {
131888
133313
  if (!this.interactive()) {
@@ -131934,8 +133359,8 @@ class ZoomRendererComponent {
131934
133359
  [attr.aria-label]="tile.ariaLabel"
131935
133360
  [attr.role]="interactive() ? 'button' : null"
131936
133361
  [attr.tabindex]="interactive() ? 0 : null"
131937
- (click)="activateSummary($event, tile.targetSlideIndex)"
131938
- (keydown)="activateSummary($event, tile.targetSlideIndex)"
133362
+ (click)="activateSummary($event, tile)"
133363
+ (keydown)="activateSummary($event, tile)"
131939
133364
  style="overflow:hidden;border:1px solid rgba(0,0,0,0.12)"
131940
133365
  >
131941
133366
  @if (tile.imageSrc) {
@@ -132019,8 +133444,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
132019
133444
  [attr.aria-label]="tile.ariaLabel"
132020
133445
  [attr.role]="interactive() ? 'button' : null"
132021
133446
  [attr.tabindex]="interactive() ? 0 : null"
132022
- (click)="activateSummary($event, tile.targetSlideIndex)"
132023
- (keydown)="activateSummary($event, tile.targetSlideIndex)"
133447
+ (click)="activateSummary($event, tile)"
133448
+ (keydown)="activateSummary($event, tile)"
132024
133449
  style="overflow:hidden;border:1px solid rgba(0,0,0,0.12)"
132025
133450
  >
132026
133451
  @if (tile.imageSrc) {
@@ -132132,7 +133557,7 @@ class ElementRendererGraphicsComponent {
132132
133557
  this.tableChange = output();
132133
133558
  }
132134
133559
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ElementRendererGraphicsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
132135
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: ElementRendererGraphicsComponent, isStandalone: true, selector: "pptx-element-renderer-graphics", inputs: { element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, presenting: { classPropertyName: "presenting", publicName: "presenting", isSignal: true, isRequired: false, transformFunction: null }, exposeElementId: { classPropertyName: "exposeElementId", publicName: "exposeElementId", isSignal: true, isRequired: false, transformFunction: null }, elementMarked: { classPropertyName: "elementMarked", publicName: "elementMarked", isSignal: true, isRequired: false, transformFunction: null }, elementIdAttr: { classPropertyName: "elementIdAttr", publicName: "elementIdAttr", isSignal: true, isRequired: false, transformFunction: null }, rootPointerEvents: { classPropertyName: "rootPointerEvents", publicName: "rootPointerEvents", isSignal: true, isRequired: false, transformFunction: null }, containerStyle: { classPropertyName: "containerStyle", publicName: "containerStyle", isSignal: true, isRequired: false, transformFunction: null }, textStyleOverrideCss: { classPropertyName: "textStyleOverrideCss", publicName: "textStyleOverrideCss", isSignal: true, isRequired: false, transformFunction: null }, animationState: { classPropertyName: "animationState", publicName: "animationState", isSignal: true, isRequired: false, transformFunction: null }, smartArt3D: { classPropertyName: "smartArt3D", publicName: "smartArt3D", isSignal: true, isRequired: false, transformFunction: null }, placeholderLabel: { classPropertyName: "placeholderLabel", publicName: "placeholderLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellCommit: "cellCommit", tableChange: "tableChange" }, host: { classAttribute: "contents" }, ngImport: i0, template: "@switch (true) {\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[editable]=\"editable()\"\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[editable]=\"editable()\"\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[editable]=\"editable()\"\n\t\t\t[presenting]=\"presenting()\"\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[editable]=\"editable()\"\n\t\t\t[presenting]=\"presenting()\"\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[editable]=\"editable()\"\n\t\t\t[presenting]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[textStyle]=\"animationState()?.textStyle\"\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<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides a SmartArt node caption's own\n\t\t\t inline bold/italic/underline/size, which plain CSS inheritance\n\t\t\t cannot reach. See `animation-text-style-css.ts`. -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<!-- Interaction-only hit target for a degenerate SmartArt; see `hitTargetStyle`. -->\n\t\t\t@if (hitTargetStyle(); as hit) {\n\t\t\t\t<div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n\t\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<!-- Interaction-only hit target for a degenerate OLE object; see `hitTargetStyle`. -->\n\t\t\t@if (hitTargetStyle(); as hit) {\n\t\t\t\t<div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n\t\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<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides a chart title/label/legend's\n\t\t\t own SVG text attributes, which plain CSS inheritance cannot\n\t\t\t reach. See `animation-text-style-css.ts`. -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<!-- Interaction-only hit target for a degenerate chart; see `hitTargetStyle`. -->\n\t\t\t@if (hitTargetStyle(); as hit) {\n\t\t\t\t<div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n\t\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<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides a table cell's own inline\n\t\t\t bold/italic/underline/size, which plain CSS inheritance cannot\n\t\t\t reach. See `animation-text-style-css.ts`. -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<!-- Interaction-only hit target for a degenerate table; see `hitTargetStyle`. -->\n\t\t\t@if (hitTargetStyle(); as hit) {\n\t\t\t\t<div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n\t\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 === '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[editable]=\"editable()\"\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}\n", dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: DynamicStyleComponent, selector: "pptx-dynamic-style", inputs: ["css"] }, { kind: "component", type: InkRendererComponent, selector: "pptx-ink-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "replay", "editable", "markElement", "exposeElementId"] }, { kind: "component", type: ContentPartRendererComponent, selector: "pptx-content-part-renderer", inputs: ["element", "zIndex", "replay", "editable", "markElement", "exposeElementId"] }, { kind: "component", type: ZoomRendererComponent, selector: "pptx-zoom-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "markElement", "editable", "presenting"] }, { kind: "component", type: Model3DRendererComponent, selector: "pptx-model3d-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "interactive", "markElement", "exposeElementId", "editable", "presenting"] }, { kind: "component", type: SmartArt3DRendererComponent, selector: "pptx-smart-art-3d-renderer", inputs: ["element", "zIndex", "canEdit", "markElement", "editable", "presenting", "textStyle"] }, { kind: "component", type: SmartArtRendererComponent, selector: "pptx-smart-art-renderer", inputs: ["element", "editable", "animationState"] }, { kind: "component", type: OleRendererComponent, selector: "pptx-ole-renderer", inputs: ["element"] }, { kind: "component", type: ChartElementViewComponent, selector: "pptx-chart-element-view", inputs: ["element", "editable", "animationState"] }, { kind: "component", type: TableRendererComponent, selector: "pptx-table-renderer", inputs: ["element", "editable"], outputs: ["cellCommit", "tableChange"] }, { kind: "component", type: MediaRendererComponent, selector: "pptx-media-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "interactive", "marked", "editable", "exposeElementId", "presenting", "placeholderLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
133560
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: ElementRendererGraphicsComponent, isStandalone: true, selector: "pptx-element-renderer-graphics", inputs: { element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, presenting: { classPropertyName: "presenting", publicName: "presenting", isSignal: true, isRequired: false, transformFunction: null }, exposeElementId: { classPropertyName: "exposeElementId", publicName: "exposeElementId", isSignal: true, isRequired: false, transformFunction: null }, elementMarked: { classPropertyName: "elementMarked", publicName: "elementMarked", isSignal: true, isRequired: false, transformFunction: null }, elementIdAttr: { classPropertyName: "elementIdAttr", publicName: "elementIdAttr", isSignal: true, isRequired: false, transformFunction: null }, rootPointerEvents: { classPropertyName: "rootPointerEvents", publicName: "rootPointerEvents", isSignal: true, isRequired: false, transformFunction: null }, containerStyle: { classPropertyName: "containerStyle", publicName: "containerStyle", isSignal: true, isRequired: false, transformFunction: null }, textStyleOverrideCss: { classPropertyName: "textStyleOverrideCss", publicName: "textStyleOverrideCss", isSignal: true, isRequired: false, transformFunction: null }, animationState: { classPropertyName: "animationState", publicName: "animationState", isSignal: true, isRequired: false, transformFunction: null }, smartArt3D: { classPropertyName: "smartArt3D", publicName: "smartArt3D", isSignal: true, isRequired: false, transformFunction: null }, placeholderLabel: { classPropertyName: "placeholderLabel", publicName: "placeholderLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellCommit: "cellCommit", tableChange: "tableChange" }, host: { classAttribute: "contents" }, ngImport: i0, template: "@switch (true) {\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[editable]=\"editable()\"\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[editable]=\"editable()\"\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[editable]=\"editable()\"\n\t\t\t[presenting]=\"presenting()\"\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[editable]=\"editable()\"\n\t\t\t[presenting]=\"presenting()\"\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[editable]=\"editable()\"\n\t\t\t[presenting]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[textStyle]=\"animationState()?.textStyle\"\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<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides a SmartArt node caption's own\n\t\t\t inline bold/italic/underline/size, which plain CSS inheritance\n\t\t\t cannot reach. See `animation-text-style-css.ts`. -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<!-- Interaction-only hit target for a degenerate SmartArt; see `hitTargetStyle`. -->\n\t\t\t@if (hitTargetStyle(); as hit) {\n\t\t\t\t<div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n\t\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<!-- Interaction-only hit target for a degenerate OLE object; see `hitTargetStyle`. -->\n\t\t\t@if (hitTargetStyle(); as hit) {\n\t\t\t\t<div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n\t\t\t}\n\t\t\t<pptx-ole-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[interactive]=\"interactive()\"\n\t\t\t\t[presenting]=\"presenting()\"\n\t\t\t/>\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<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides a chart title/label/legend's\n\t\t\t own SVG text attributes, which plain CSS inheritance cannot\n\t\t\t reach. See `animation-text-style-css.ts`. -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<!-- Interaction-only hit target for a degenerate chart; see `hitTargetStyle`. -->\n\t\t\t@if (hitTargetStyle(); as hit) {\n\t\t\t\t<div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n\t\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<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides a table cell's own inline\n\t\t\t bold/italic/underline/size, which plain CSS inheritance cannot\n\t\t\t reach. See `animation-text-style-css.ts`. -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<!-- Interaction-only hit target for a degenerate table; see `hitTargetStyle`. -->\n\t\t\t@if (hitTargetStyle(); as hit) {\n\t\t\t\t<div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n\t\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 === '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[editable]=\"editable()\"\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}\n", dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: DynamicStyleComponent, selector: "pptx-dynamic-style", inputs: ["css"] }, { kind: "component", type: InkRendererComponent, selector: "pptx-ink-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "replay", "editable", "markElement", "exposeElementId"] }, { kind: "component", type: ContentPartRendererComponent, selector: "pptx-content-part-renderer", inputs: ["element", "zIndex", "replay", "editable", "markElement", "exposeElementId"] }, { kind: "component", type: ZoomRendererComponent, selector: "pptx-zoom-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "markElement", "editable", "presenting"] }, { kind: "component", type: Model3DRendererComponent, selector: "pptx-model3d-renderer", inputs: ["element", "zIndex", "mediaDataUrls", "interactive", "markElement", "exposeElementId", "editable", "presenting"] }, { kind: "component", type: SmartArt3DRendererComponent, selector: "pptx-smart-art-3d-renderer", inputs: ["element", "zIndex", "canEdit", "markElement", "editable", "presenting", "textStyle"] }, { kind: "component", type: SmartArtRendererComponent, selector: "pptx-smart-art-renderer", inputs: ["element", "editable", "animationState"] }, { kind: "component", type: OleRendererComponent, selector: "pptx-ole-renderer", inputs: ["element", "interactive", "presenting"] }, { kind: "component", type: ChartElementViewComponent, selector: "pptx-chart-element-view", inputs: ["element", "editable", "animationState"] }, { kind: "component", type: TableRendererComponent, selector: "pptx-table-renderer", inputs: ["element", "editable"], outputs: ["cellCommit", "tableChange"] }, { kind: "component", type: MediaRendererComponent, selector: "pptx-media-renderer", inputs: ["element", "mediaDataUrls", "zIndex", "interactive", "marked", "editable", "exposeElementId", "presenting", "placeholderLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
132136
133561
  }
132137
133562
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ElementRendererGraphicsComponent, decorators: [{
132138
133563
  type: Component,
@@ -132149,7 +133574,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
132149
133574
  ChartElementViewComponent,
132150
133575
  TableRendererComponent,
132151
133576
  MediaRendererComponent,
132152
- ], template: "@switch (true) {\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[editable]=\"editable()\"\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[editable]=\"editable()\"\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[editable]=\"editable()\"\n\t\t\t[presenting]=\"presenting()\"\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[editable]=\"editable()\"\n\t\t\t[presenting]=\"presenting()\"\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[editable]=\"editable()\"\n\t\t\t[presenting]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[textStyle]=\"animationState()?.textStyle\"\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<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides a SmartArt node caption's own\n\t\t\t inline bold/italic/underline/size, which plain CSS inheritance\n\t\t\t cannot reach. See `animation-text-style-css.ts`. -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<!-- Interaction-only hit target for a degenerate SmartArt; see `hitTargetStyle`. -->\n\t\t\t@if (hitTargetStyle(); as hit) {\n\t\t\t\t<div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n\t\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<!-- Interaction-only hit target for a degenerate OLE object; see `hitTargetStyle`. -->\n\t\t\t@if (hitTargetStyle(); as hit) {\n\t\t\t\t<div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n\t\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<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides a chart title/label/legend's\n\t\t\t own SVG text attributes, which plain CSS inheritance cannot\n\t\t\t reach. See `animation-text-style-css.ts`. -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<!-- Interaction-only hit target for a degenerate chart; see `hitTargetStyle`. -->\n\t\t\t@if (hitTargetStyle(); as hit) {\n\t\t\t\t<div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n\t\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<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides a table cell's own inline\n\t\t\t bold/italic/underline/size, which plain CSS inheritance cannot\n\t\t\t reach. See `animation-text-style-css.ts`. -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<!-- Interaction-only hit target for a degenerate table; see `hitTargetStyle`. -->\n\t\t\t@if (hitTargetStyle(); as hit) {\n\t\t\t\t<div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n\t\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 === '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[editable]=\"editable()\"\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}\n" }]
133577
+ ], template: "@switch (true) {\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[editable]=\"editable()\"\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[editable]=\"editable()\"\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[editable]=\"editable()\"\n\t\t\t[presenting]=\"presenting()\"\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[editable]=\"editable()\"\n\t\t\t[presenting]=\"presenting()\"\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[editable]=\"editable()\"\n\t\t\t[presenting]=\"presenting()\"\n\t\t\t[markElement]=\"elementMarked()\"\n\t\t\t[textStyle]=\"animationState()?.textStyle\"\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<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides a SmartArt node caption's own\n\t\t\t inline bold/italic/underline/size, which plain CSS inheritance\n\t\t\t cannot reach. See `animation-text-style-css.ts`. -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<!-- Interaction-only hit target for a degenerate SmartArt; see `hitTargetStyle`. -->\n\t\t\t@if (hitTargetStyle(); as hit) {\n\t\t\t\t<div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n\t\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<!-- Interaction-only hit target for a degenerate OLE object; see `hitTargetStyle`. -->\n\t\t\t@if (hitTargetStyle(); as hit) {\n\t\t\t\t<div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n\t\t\t}\n\t\t\t<pptx-ole-renderer\n\t\t\t\t[element]=\"element()\"\n\t\t\t\t[interactive]=\"interactive()\"\n\t\t\t\t[presenting]=\"presenting()\"\n\t\t\t/>\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<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides a chart title/label/legend's\n\t\t\t own SVG text attributes, which plain CSS inheritance cannot\n\t\t\t reach. See `animation-text-style-css.ts`. -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<!-- Interaction-only hit target for a degenerate chart; see `hitTargetStyle`. -->\n\t\t\t@if (hitTargetStyle(); as hit) {\n\t\t\t\t<div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n\t\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<!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n\t\t\t Change Font Style/Size) overrides a table cell's own inline\n\t\t\t bold/italic/underline/size, which plain CSS inheritance cannot\n\t\t\t reach. See `animation-text-style-css.ts`. -->\n\t\t\t<pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n\t\t\t<!-- Interaction-only hit target for a degenerate table; see `hitTargetStyle`. -->\n\t\t\t@if (hitTargetStyle(); as hit) {\n\t\t\t\t<div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n\t\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 === '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[editable]=\"editable()\"\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}\n" }]
132153
133578
  }], 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 }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], presenting: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenting", required: false }] }], exposeElementId: [{ type: i0.Input, args: [{ isSignal: true, alias: "exposeElementId", required: false }] }], elementMarked: [{ type: i0.Input, args: [{ isSignal: true, alias: "elementMarked", required: false }] }], elementIdAttr: [{ type: i0.Input, args: [{ isSignal: true, alias: "elementIdAttr", required: false }] }], rootPointerEvents: [{ type: i0.Input, args: [{ isSignal: true, alias: "rootPointerEvents", required: false }] }], containerStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "containerStyle", required: false }] }], textStyleOverrideCss: [{ type: i0.Input, args: [{ isSignal: true, alias: "textStyleOverrideCss", required: false }] }], animationState: [{ type: i0.Input, args: [{ isSignal: true, alias: "animationState", required: false }] }], smartArt3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "smartArt3D", required: false }] }], placeholderLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholderLabel", required: false }] }], cellCommit: [{ type: i0.Output, args: ["cellCommit"] }], tableChange: [{ type: i0.Output, args: ["tableChange"] }] } });
132154
133579
 
132155
133580
  /**
@@ -139564,6 +140989,224 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
139564
140989
  `, styles: [".pptx-ng-outline-root{position:fixed;inset:0;z-index:1300;display:flex;flex-direction:column;background:#171717;color:#f5f5f5}.pptx-ng-outline-bar{display:flex;align-items:center;gap:.75rem;padding:.5rem 1rem;border-bottom:1px solid rgb(255 255 255 / .1)}.pptx-ng-outline-title{font-size:.875rem;font-weight:600}.pptx-ng-outline-hint{flex:1 1 auto;overflow:hidden;font-size:.6875rem;color:#ffffff80;text-overflow:ellipsis;white-space:nowrap}.pptx-ng-outline-btn{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;color:#fffc;background:transparent;border:0;border-radius:.25rem;cursor:pointer}.pptx-ng-outline-btn:hover{color:#fff;background:#ffffff26}.pptx-ng-outline-rows{flex:1 1 auto;min-height:0;overflow:auto;padding:.75rem 1rem}.pptx-ng-outline-row{display:flex;align-items:center;gap:.5rem;padding:.125rem 0}.pptx-ng-outline-number{width:1.5rem;flex:0 0 auto;font-size:.625rem;font-variant-numeric:tabular-nums;color:#fff6;text-align:right}.pptx-ng-outline-input{width:100%;padding:.125rem .25rem;font-size:.8125rem;color:#fffc;background:transparent;border:0;border-radius:.25rem;outline:none}.pptx-ng-outline-input.is-title{font-size:.875rem;font-weight:600;color:#f5f5f5}.pptx-ng-outline-input:focus{background:#ffffff1a}\n"] }]
139565
140990
  }], propDecorators: { slides: [{ type: i0.Input, args: [{ isSignal: true, alias: "slides", required: false }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], commit: [{ type: i0.Output, args: ["commit"] }], closed: [{ type: i0.Output, args: ["closed"] }], rowsHost: [{ type: i0.ViewChild, args: ['rowsHost', { isSignal: true }] }] } });
139566
140991
 
140992
+ /**
140993
+ * paste-options-toolbar.component.ts: the small icon-strip PowerPoint anchors
140994
+ * to the bottom-right corner of a just-pasted element, offering the same four
140995
+ * formats as the Paste Special dialog as a one-click follow-up. Dismissed by
140996
+ * any subsequent pointerdown or keydown, same as the element context menu.
140997
+ *
140998
+ * Selector: `pptx-paste-options-toolbar`
140999
+ *
141000
+ * Angular port of the React `PasteOptionsToolbar.tsx` / Vue `PasteOptionsToolbar.vue`.
141001
+ */
141002
+ class PasteOptionsToolbarComponent {
141003
+ constructor() {
141004
+ /** The just-pasted element's id, or null when the toolbar should be hidden. */
141005
+ this.elementId = input(null, /* @ts-ignore */
141006
+ ...(ngDevMode ? [{ debugName: "elementId" }] : /* istanbul ignore next */ []));
141007
+ this.choose = output();
141008
+ this.dismiss = output();
141009
+ this.options = PASTE_SPECIAL_OPTIONS;
141010
+ this.rect = signal(null, /* @ts-ignore */
141011
+ ...(ngDevMode ? [{ debugName: "rect" }] : /* istanbul ignore next */ []));
141012
+ effect(() => {
141013
+ const id = this.elementId();
141014
+ this.removeListeners?.();
141015
+ this.removeListeners = undefined;
141016
+ if (!id) {
141017
+ this.rect.set(null);
141018
+ return;
141019
+ }
141020
+ // One frame for the pasted element to mount before measuring it.
141021
+ requestAnimationFrame(() => this.measure(id));
141022
+ });
141023
+ }
141024
+ measure(id) {
141025
+ const node = document.querySelector(`[data-element-id="${id}"]`);
141026
+ if (!node) {
141027
+ this.rect.set(null);
141028
+ return;
141029
+ }
141030
+ const box = node.getBoundingClientRect();
141031
+ this.rect.set({ left: box.right, top: box.bottom });
141032
+ const onOutsideEvent = () => this.dismiss.emit();
141033
+ // Deferred so the paste action's OWN pointerdown/keydown does not
141034
+ // immediately dismiss the toolbar it just opened.
141035
+ window.setTimeout(() => {
141036
+ window.addEventListener('pointerdown', onOutsideEvent, true);
141037
+ window.addEventListener('keydown', onOutsideEvent, true);
141038
+ }, 0);
141039
+ this.removeListeners = () => {
141040
+ window.removeEventListener('pointerdown', onOutsideEvent, true);
141041
+ window.removeEventListener('keydown', onOutsideEvent, true);
141042
+ };
141043
+ }
141044
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PasteOptionsToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
141045
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: PasteOptionsToolbarComponent, isStandalone: true, selector: "pptx-paste-options-toolbar", inputs: { elementId: { classPropertyName: "elementId", publicName: "elementId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { choose: "choose", dismiss: "dismiss" }, ngImport: i0, template: `
141046
+ @if (elementId() && rect(); as position) {
141047
+ <div
141048
+ role="toolbar"
141049
+ tabindex="-1"
141050
+ [attr.aria-label]="'pptx.pasteSpecial.optionsLabel' | translate"
141051
+ data-pptx-paste-options
141052
+ class="pptx-ng-paste-options"
141053
+ [style.left.px]="position.left + 4"
141054
+ [style.top.px]="position.top + 4"
141055
+ (mousedown)="$event.stopPropagation()"
141056
+ >
141057
+ @for (option of options; track option.id) {
141058
+ <button
141059
+ type="button"
141060
+ class="pptx-ng-paste-options-btn"
141061
+ [attr.title]="option.labelKey | translate"
141062
+ [attr.aria-label]="option.labelKey | translate"
141063
+ (click)="choose.emit(option.id)"
141064
+ >
141065
+ {{ option.labelKey | translate }}
141066
+ </button>
141067
+ }
141068
+ </div>
141069
+ }
141070
+ `, isInline: true, styles: [".pptx-ng-paste-options{position:fixed;z-index:1100;display:flex;align-items:center;gap:.125rem;padding:.25rem;border:1px solid var(--pptx-border, #374151);border-radius:.25rem;background:var(--pptx-popover, #111827);box-shadow:0 10px 25px #00000059}.pptx-ng-paste-options-btn{padding:.25rem .5rem;border:none;border-radius:.25rem;background:transparent;color:var(--pptx-foreground, #f3f4f6);font-size:.6875rem;white-space:nowrap;cursor:pointer}.pptx-ng-paste-options-btn:hover{background:var(--pptx-accent, #1f2937)}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
141071
+ }
141072
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PasteOptionsToolbarComponent, decorators: [{
141073
+ type: Component,
141074
+ args: [{ selector: 'pptx-paste-options-toolbar', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslatePipe], template: `
141075
+ @if (elementId() && rect(); as position) {
141076
+ <div
141077
+ role="toolbar"
141078
+ tabindex="-1"
141079
+ [attr.aria-label]="'pptx.pasteSpecial.optionsLabel' | translate"
141080
+ data-pptx-paste-options
141081
+ class="pptx-ng-paste-options"
141082
+ [style.left.px]="position.left + 4"
141083
+ [style.top.px]="position.top + 4"
141084
+ (mousedown)="$event.stopPropagation()"
141085
+ >
141086
+ @for (option of options; track option.id) {
141087
+ <button
141088
+ type="button"
141089
+ class="pptx-ng-paste-options-btn"
141090
+ [attr.title]="option.labelKey | translate"
141091
+ [attr.aria-label]="option.labelKey | translate"
141092
+ (click)="choose.emit(option.id)"
141093
+ >
141094
+ {{ option.labelKey | translate }}
141095
+ </button>
141096
+ }
141097
+ </div>
141098
+ }
141099
+ `, styles: [".pptx-ng-paste-options{position:fixed;z-index:1100;display:flex;align-items:center;gap:.125rem;padding:.25rem;border:1px solid var(--pptx-border, #374151);border-radius:.25rem;background:var(--pptx-popover, #111827);box-shadow:0 10px 25px #00000059}.pptx-ng-paste-options-btn{padding:.25rem .5rem;border:none;border-radius:.25rem;background:transparent;color:var(--pptx-foreground, #f3f4f6);font-size:.6875rem;white-space:nowrap;cursor:pointer}.pptx-ng-paste-options-btn:hover{background:var(--pptx-accent, #1f2937)}\n"] }]
141100
+ }], ctorParameters: () => [], propDecorators: { elementId: [{ type: i0.Input, args: [{ isSignal: true, alias: "elementId", required: false }] }], choose: [{ type: i0.Output, args: ["choose"] }], dismiss: [{ type: i0.Output, args: ["dismiss"] }] } });
141101
+
141102
+ /**
141103
+ * paste-special-dialog.component.ts: Ctrl/Cmd+Alt+V. Offers the four Paste
141104
+ * Special formats PowerPoint's own dialog offers (Keep Source Formatting,
141105
+ * Use Destination Theme, Picture, Keep Text Only), sourced from
141106
+ * `pptx-viewer-shared` so the option set and its labels cannot drift from the
141107
+ * post-paste "Paste Options" toolbar or the other four bindings.
141108
+ *
141109
+ * Selector: `pptx-paste-special-dialog`
141110
+ *
141111
+ * Angular port of the React `PasteSpecialDialog.tsx` / Vue `PasteSpecialDialog.vue`.
141112
+ */
141113
+ class PasteSpecialDialogComponent {
141114
+ constructor() {
141115
+ /** Whether the dialog is visible. */
141116
+ this.open = input(false, /* @ts-ignore */
141117
+ ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
141118
+ /** Fired when the dialog is cancelled (backdrop, Escape, or Cancel). */
141119
+ this.cancel = output();
141120
+ /** Fired with the chosen format when OK is pressed. */
141121
+ this.confirm = output();
141122
+ this.options = PASTE_SPECIAL_OPTIONS;
141123
+ this.selected = signal('keep-source-formatting', /* @ts-ignore */
141124
+ ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
141125
+ // Reset to the default choice every time the dialog opens.
141126
+ effect(() => {
141127
+ if (this.open()) {
141128
+ this.selected.set('keep-source-formatting');
141129
+ }
141130
+ });
141131
+ }
141132
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PasteSpecialDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
141133
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: PasteSpecialDialogComponent, isStandalone: true, selector: "pptx-paste-special-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cancel: "cancel", confirm: "confirm" }, ngImport: i0, template: `
141134
+ <pptx-modal-dialog
141135
+ [open]="open()"
141136
+ [title]="'pptx.pasteSpecial.dialogTitle' | translate"
141137
+ (close)="cancel.emit()"
141138
+ >
141139
+ <ul class="pptx-ng-paste-special-list">
141140
+ @for (option of options; track option.id) {
141141
+ <li>
141142
+ <label class="pptx-ng-paste-special-option">
141143
+ <input
141144
+ type="radio"
141145
+ name="paste-special-format"
141146
+ [checked]="selected() === option.id"
141147
+ (change)="selected.set(option.id)"
141148
+ />
141149
+ {{ option.labelKey | translate }}
141150
+ </label>
141151
+ </li>
141152
+ }
141153
+ </ul>
141154
+
141155
+ <div footer>
141156
+ <button type="button" class="pptx-ng-paste-special-btn" (click)="cancel.emit()">
141157
+ {{ 'pptx.common.cancel' | translate }}
141158
+ </button>
141159
+ <button
141160
+ type="button"
141161
+ class="pptx-ng-paste-special-btn pptx-ng-paste-special-btn-primary"
141162
+ (click)="confirm.emit(selected())"
141163
+ >
141164
+ {{ 'pptx.common.ok' | translate }}
141165
+ </button>
141166
+ </div>
141167
+ </pptx-modal-dialog>
141168
+ `, isInline: true, styles: [".pptx-ng-paste-special-list{display:flex;flex-direction:column;gap:.125rem;margin:0;padding:0;list-style:none}.pptx-ng-paste-special-option{display:flex;align-items:center;gap:.5rem;padding:.375rem .5rem;border-radius:.25rem;font-size:.8125rem;color:var(--pptx-foreground, #f3f4f6);cursor:pointer}.pptx-ng-paste-special-option:hover{background:var(--pptx-accent, #1f2937)}.pptx-ng-paste-special-btn{padding:.5rem 1rem;border:1px solid var(--pptx-border, #374151);border-radius:.375rem;background:var(--pptx-background, #030712);color:var(--pptx-foreground, #f3f4f6);font-size:.8125rem;font-weight:500;cursor:pointer}.pptx-ng-paste-special-btn:hover{background:var(--pptx-accent, #1f2937)}.pptx-ng-paste-special-btn-primary{border-color:var(--pptx-primary, #6366f1);background:var(--pptx-primary, #6366f1);color:#fff}.pptx-ng-paste-special-btn-primary:hover{filter:brightness(1.1)}\n"], dependencies: [{ kind: "component", type: ModalDialogComponent, selector: "pptx-modal-dialog", inputs: ["open", "title", "closeDisabled", "busy"], outputs: ["close"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
141169
+ }
141170
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PasteSpecialDialogComponent, decorators: [{
141171
+ type: Component,
141172
+ args: [{ selector: 'pptx-paste-special-dialog', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [ModalDialogComponent, TranslatePipe], template: `
141173
+ <pptx-modal-dialog
141174
+ [open]="open()"
141175
+ [title]="'pptx.pasteSpecial.dialogTitle' | translate"
141176
+ (close)="cancel.emit()"
141177
+ >
141178
+ <ul class="pptx-ng-paste-special-list">
141179
+ @for (option of options; track option.id) {
141180
+ <li>
141181
+ <label class="pptx-ng-paste-special-option">
141182
+ <input
141183
+ type="radio"
141184
+ name="paste-special-format"
141185
+ [checked]="selected() === option.id"
141186
+ (change)="selected.set(option.id)"
141187
+ />
141188
+ {{ option.labelKey | translate }}
141189
+ </label>
141190
+ </li>
141191
+ }
141192
+ </ul>
141193
+
141194
+ <div footer>
141195
+ <button type="button" class="pptx-ng-paste-special-btn" (click)="cancel.emit()">
141196
+ {{ 'pptx.common.cancel' | translate }}
141197
+ </button>
141198
+ <button
141199
+ type="button"
141200
+ class="pptx-ng-paste-special-btn pptx-ng-paste-special-btn-primary"
141201
+ (click)="confirm.emit(selected())"
141202
+ >
141203
+ {{ 'pptx.common.ok' | translate }}
141204
+ </button>
141205
+ </div>
141206
+ </pptx-modal-dialog>
141207
+ `, styles: [".pptx-ng-paste-special-list{display:flex;flex-direction:column;gap:.125rem;margin:0;padding:0;list-style:none}.pptx-ng-paste-special-option{display:flex;align-items:center;gap:.5rem;padding:.375rem .5rem;border-radius:.25rem;font-size:.8125rem;color:var(--pptx-foreground, #f3f4f6);cursor:pointer}.pptx-ng-paste-special-option:hover{background:var(--pptx-accent, #1f2937)}.pptx-ng-paste-special-btn{padding:.5rem 1rem;border:1px solid var(--pptx-border, #374151);border-radius:.375rem;background:var(--pptx-background, #030712);color:var(--pptx-foreground, #f3f4f6);font-size:.8125rem;font-weight:500;cursor:pointer}.pptx-ng-paste-special-btn:hover{background:var(--pptx-accent, #1f2937)}.pptx-ng-paste-special-btn-primary{border-color:var(--pptx-primary, #6366f1);background:var(--pptx-primary, #6366f1);color:#fff}.pptx-ng-paste-special-btn-primary:hover{filter:brightness(1.1)}\n"] }]
141208
+ }], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], cancel: [{ type: i0.Output, args: ["cancel"] }], confirm: [{ type: i0.Output, args: ["confirm"] }] } });
141209
+
139567
141210
  /**
139568
141211
  * Families the user registered from a local font file this session
139569
141212
  * (File > Options > Fonts, off by default).
@@ -139600,154 +141243,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
139600
141243
  type: Injectable
139601
141244
  }] });
139602
141245
 
139603
- /**
139604
- * A drop-in replacement for `html2canvas(element, options)` that first
139605
- * resolves any oklch / oklab / lch / lab / color() values in the cloned
139606
- * DOM to rgb()/hex, preventing parse errors in html2canvas <= 1.x, then
139607
- * applies the CSS preprocessing pipeline.
139608
- *
139609
- * Usage:
139610
- * ```ts
139611
- * import { renderToCanvas } from '../lib/canvas-export';
139612
- * const canvas = await renderToCanvas(element, { scale: 2 });
139613
- * ```
139614
- */
139615
- async function renderToCanvas(element, options = {}) {
139616
- const userOnClone = options.onclone;
139617
- const { default: html2canvasPro } = await import('html2canvas-pro');
139618
- return html2canvasPro(element, {
139619
- ...options,
139620
- onclone: async (doc, clonedEl) => {
139621
- prepareExportClone(clonedEl);
139622
- await normalizeColorsForCapture(doc, clonedEl);
139623
- preprocessCssForCapture(clonedEl);
139624
- if (typeof userOnClone === 'function') {
139625
- userOnClone(doc, clonedEl);
139626
- }
139627
- },
139628
- });
139629
- }
139630
-
139631
- /**
139632
- * Pure export helper utilities: thin re-export shim.
139633
- *
139634
- * The page-size / orientation / file-name maths now lives once in
139635
- * `pptx-viewer-shared` (`export/pdf-page-size`), inlined here at build time via
139636
- * `../internal/shared-src`. This module preserves the historical import path for
139637
- * the Angular export service, components, and tests.
139638
- */
139639
-
139640
- /**
139641
- * Tile-aware rasterisation + tiled-PDF assembly, split out of
139642
- * `export.service.ts` to keep that file under the file-size budget.
139643
- *
139644
- * Every raster entry point here goes through the shared `foreignObject`
139645
- * fidelity pipeline (`pptx-viewer-shared`'s `rasterizeElement` /
139646
- * `rasterizeElementTiledToCanvas` / `rasterizeElementTiles`), with
139647
- * `html2canvas-pro` kept only as the documented fallback driver. This is the
139648
- * one place in the Angular binding that touches that driver directly.
139649
- */
139650
- /**
139651
- * The `html2canvasFallback` driver every shared rasterize call needs, bound
139652
- * to one element, so the html2canvas-pro adapter is written once, not
139653
- * hand-copied per raster entry point.
139654
- */
139655
- function html2canvasFallbackFor(el) {
139656
- return (sourceRect, outputSize) => renderToCanvas(el, {
139657
- ignoreElements: isExportIgnoredElement,
139658
- scale: outputSize.width / (sourceRect.width || 1),
139659
- x: sourceRect.x,
139660
- y: sourceRect.y,
139661
- width: sourceRect.width,
139662
- height: sourceRect.height,
139663
- });
139664
- }
139665
- /** The element's natural (1x) CSS-pixel size the shared rasterizers scale from. */
139666
- function naturalSizeOf(el) {
139667
- const rect = el.getBoundingClientRect();
139668
- return { width: rect.width || el.offsetWidth, height: rect.height || el.offsetHeight };
139669
- }
139670
- /**
139671
- * Rasterize `el` to a PNG `Blob` via the shared `foreignObject` -> vector-SVG
139672
- * -> html2canvas fallback chain (preserves backdrop-filter, CSS custom
139673
- * properties and 3D transforms html2canvas cannot), tiling transparently
139674
- * for a resolution beyond the browser's canvas cap - for PNG download and
139675
- * "copy slide as image", whose PNG encoder can consume tiled output.
139676
- */
139677
- async function renderElementPngBlob(el, scale = 2) {
139678
- const { width, height } = naturalSizeOf(el);
139679
- const result = await rasterizeElement(el, width, height, el.ownerDocument, {
139680
- scale,
139681
- html2canvasFallback: html2canvasFallbackFor(el),
139682
- });
139683
- return rasterResultToPngBlob(result);
139684
- }
139685
- /**
139686
- * Rasterize a single element to a single full-resolution canvas via the
139687
- * shared `foreignObject` fidelity pipeline, tiling and stitching
139688
- * transparently (never reducing the requested scale) so the result is always
139689
- * one canvas - for GIF/video/print, which can only consume one image per
139690
- * frame/page. Capture each slide's canvas *while that slide is the live
139691
- * DOM*: the viewer reuses one stage node, so a deferred capture would yield
139692
- * the same (last) slide for every page.
139693
- */
139694
- async function renderElementTiled(el, scale = 2) {
139695
- const { width, height } = naturalSizeOf(el);
139696
- const result = await rasterizeElementTiledToCanvas(el, width, height, el.ownerDocument, {
139697
- scale,
139698
- html2canvasFallback: html2canvasFallbackFor(el),
139699
- });
139700
- return result.canvas;
139701
- }
139702
- /**
139703
- * Rasterize a single element to its raw per-tile canvases via the shared
139704
- * `foreignObject` fidelity pipeline, tiling transparently when the requested
139705
- * resolution exceeds the browser's canvas cap - for PDF pages, which have no
139706
- * canvas-size limit of their own and so can place several small tile images
139707
- * instead of needing one oversized canvas.
139708
- */
139709
- async function renderElementTilesRaster(el, scale = 2) {
139710
- const { width, height } = naturalSizeOf(el);
139711
- return rasterizeElementTiles(el, width, height, el.ownerDocument, {
139712
- scale,
139713
- html2canvasFallback: html2canvasFallbackFor(el),
139714
- });
139715
- }
139716
- /**
139717
- * Assemble a multi-page PDF from pre-rendered per-slide tile sets (one page
139718
- * per entry) and trigger a download. Each tile is placed at its proportional
139719
- * position on the page (`placeTileOnPage`); a single-tile slide (the
139720
- * overwhelming majority) degrades to exactly one full-page image per page,
139721
- * unchanged from before tiling existed. Escapes the browser canvas cap:
139722
- * every tile is individually small, and a PDF page has no canvas-size limit
139723
- * of its own.
139724
- *
139725
- * @param pages - One entry per slide, in order, each captured while
139726
- * its slide was the live stage (`renderElementTilesRaster`).
139727
- * @param canvasWidth - Slide canvas width in pixels (for aspect ratio).
139728
- * @param canvasHeight - Slide canvas height in pixels (for aspect ratio).
139729
- * @param fileName - Suggested download file name (unsafe chars stripped).
139730
- */
139731
- function buildTiledPdf(pages, canvasWidth, canvasHeight, fileName) {
139732
- if (pages.length === 0) {
139733
- throw new Error('[ExportService] No slide pages provided for PDF export');
139734
- }
139735
- const { width: pageW, height: pageH, orientation } = pdfPageSize(canvasWidth, canvasHeight);
139736
- const doc = new jsPDF({ orientation, unit: 'pt', format: [pageW, pageH] });
139737
- for (let i = 0; i < pages.length; i++) {
139738
- if (i > 0) {
139739
- doc.addPage([pageW, pageH], orientation);
139740
- }
139741
- const { fullWidth, fullHeight, tiles } = pages[i];
139742
- for (const tile of tiles) {
139743
- const jpegBytes = canvasToJpegData(tile.canvas, 0.92).bytes;
139744
- const placement = placeTileOnPage(tile, fullWidth, fullHeight, pageW, pageH);
139745
- doc.addImage(jpegBytes, 'JPEG', placement.x, placement.y, placement.width, placement.height);
139746
- }
139747
- }
139748
- doc.save(sanitizeDownloadFilename(fileName));
139749
- }
139750
-
139751
141246
  /** Export one parsed slide as resolution-independent SVG markup. */
139752
141247
  function exportSlideToSvg(slide, width, height, options) {
139753
141248
  return SvgExporter.exportSlide(slide, width, height, options);
@@ -142390,258 +143885,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
142390
143885
  type: Injectable
142391
143886
  }] });
142392
143887
 
142393
- /**
142394
- * swipe-dismiss.ts: Reusable pointer-drag-to-dismiss gesture for a docked
142395
- * sheet/panel that lives in normal document flow (not a fixed overlay), so a
142396
- * downward swipe is surfaced as a live drag offset (applied via a CSS
142397
- * transform) rather than relying on a native overlay's dismiss gesture.
142398
- *
142399
- * Shared by the mobile notes sheet and the mobile inspector host in
142400
- * {@link PowerPointViewerComponent}, which both need identical drag-to-dismiss
142401
- * behaviour, differing only in what happens once the drag clears the
142402
- * threshold (their own `onDismiss` callback).
142403
- */
142404
- /** Downward drag distance (px) past which releasing the pointer dismisses. Matches `pptx-mobile-sheet`'s DISMISS_THRESHOLD. */
142405
- const DISMISS_THRESHOLD_PX = 120;
142406
- /**
142407
- * Create an independent swipe-to-dismiss drag tracker. `onDismiss` fires once,
142408
- * on pointer-up, when the downward drag exceeded {@link DISMISS_THRESHOLD_PX}.
142409
- */
142410
- function createSwipeDismissDrag(onDismiss) {
142411
- const dragYSignal = signal(0, /* @ts-ignore */
142412
- ...(ngDevMode ? [{ debugName: "dragYSignal" }] : /* istanbul ignore next */ []));
142413
- const draggingSignal = signal(false, /* @ts-ignore */
142414
- ...(ngDevMode ? [{ debugName: "draggingSignal" }] : /* istanbul ignore next */ []));
142415
- let startY = null;
142416
- return {
142417
- dragY: dragYSignal,
142418
- dragging: draggingSignal,
142419
- onPointerDown(event) {
142420
- startY = event.clientY;
142421
- draggingSignal.set(true);
142422
- event.target.setPointerCapture?.(event.pointerId);
142423
- },
142424
- onPointerMove(event) {
142425
- if (startY === null) {
142426
- return;
142427
- }
142428
- dragYSignal.set(Math.max(0, event.clientY - startY));
142429
- },
142430
- onPointerUp(event) {
142431
- if (startY === null) {
142432
- return;
142433
- }
142434
- const delta = event.clientY - startY;
142435
- startY = null;
142436
- draggingSignal.set(false);
142437
- event.target.releasePointerCapture?.(event.pointerId);
142438
- if (delta > DISMISS_THRESHOLD_PX) {
142439
- onDismiss();
142440
- }
142441
- dragYSignal.set(0);
142442
- },
142443
- };
142444
- }
142445
-
142446
- /**
142447
- * viewer-inspector-panel.service.ts: Viewer-scoped state + logic for the
142448
- * single right-docked inspector host: which explicit tool panel (comments /
142449
- * accessibility / signatures / selection) is toggled on, the derived "what
142450
- * should the host actually show" precedence (explicit panel → element →
142451
- * slide default), its mobile-only swipe-to-dismiss drag, and the accessible
142452
- * label per shown content.
142453
- *
142454
- * Extracted from {@link PowerPointViewerComponent}: the component binds the
142455
- * accessors it alone owns (canEdit / selected-element / active-slide) via
142456
- * {@link bind}; the template reads the signals/computeds off the injected
142457
- * instance directly (same pattern as `session`/`xport`).
142458
- *
142459
- * Provide it once on the viewer component (`providers: [ViewerInspectorPanelService]`).
142460
- */
142461
- class ViewerInspectorPanelService {
142462
- constructor() {
142463
- this.mobile = inject(IsMobileService);
142464
- /** Active right-docked tool panel (comments / accessibility / selection), or null. */
142465
- this.activePanel = signal(null, /* @ts-ignore */
142466
- ...(ngDevMode ? [{ debugName: "activePanel" }] : /* istanbul ignore next */ []));
142467
- /** True once the user swiped the inspector away on mobile (until reopened). */
142468
- this.mobileInspectorHidden = signal(false, /* @ts-ignore */
142469
- ...(ngDevMode ? [{ debugName: "mobileInspectorHidden" }] : /* istanbul ignore next */ []));
142470
- /**
142471
- * True once the user has explicitly closed the format (element/slide)
142472
- * panel via the ribbon toggle - independent of selection, mirroring
142473
- * React's/Vue's own open/closed toggle state. Never affects the explicit
142474
- * tool panels (comments/accessibility/signatures/selection), which show
142475
- * regardless of this flag.
142476
- *
142477
- * Starts closed on mobile so the canvas owns the screen on first paint and
142478
- * the format pane's tab strip (with its own Comments button) never collides
142479
- * with the mobile bottom bar; the bottom bar's "Format" slot opens it
142480
- * explicitly instead. Mirrors React's `isInspectorPaneOpen` initializer
142481
- * (open on desktop, closed under the mobile breakpoint).
142482
- */
142483
- this.formatPanelClosed = signal(this.mobile.isMobile(), /* @ts-ignore */
142484
- ...(ngDevMode ? [{ debugName: "formatPanelClosed" }] : /* istanbul ignore next */ []));
142485
- /**
142486
- * Swipe-to-dismiss drag for the inspector host. The host docks in-flow below
142487
- * the canvas on mobile (same keyboard-reachability reason as the notes
142488
- * sheet), so the gesture is wired here rather than via a fixed-overlay
142489
- * dismiss. Clearing the past-threshold drag also closes any open tool panel.
142490
- */
142491
- this.inspectorDrag = createSwipeDismissDrag(() => this.dismissMobileInspector());
142492
- this.host = null;
142493
- /**
142494
- * Which panel the single inspector host should show, applying the original
142495
- * first-match precedence (explicit tool panels → element → slide default).
142496
- * `accessibility`/`signatures` render regardless of edit mode; the rest need
142497
- * `canEdit`.
142498
- */
142499
- this.inspectorContent = computed(() => {
142500
- const host = this.requireHost();
142501
- const panel = this.activePanel();
142502
- if (panel === 'accessibility') {
142503
- return 'accessibility';
142504
- }
142505
- if (panel === 'signatures') {
142506
- return 'signatures';
142507
- }
142508
- if (!host.canEdit()) {
142509
- return null;
142510
- }
142511
- if (panel === 'comments') {
142512
- return 'comments';
142513
- }
142514
- if (panel === 'selection') {
142515
- return 'selection';
142516
- }
142517
- if (host.selectedElement()) {
142518
- return 'element';
142519
- }
142520
- if (host.activeSlide()) {
142521
- return 'slide';
142522
- }
142523
- return null;
142524
- }, /* @ts-ignore */
142525
- ...(ngDevMode ? [{ debugName: "inspectorContent" }] : /* istanbul ignore next */ []));
142526
- /**
142527
- * `inspectorContent`, but the format (element/slide) view collapses to
142528
- * `null` once the user has explicitly closed it via the ribbon toggle.
142529
- * Explicit tool panels (comments/accessibility/etc.) are untouched.
142530
- */
142531
- this.formatPanelContent = computed(() => {
142532
- const content = this.inspectorContent();
142533
- if ((content === 'element' || content === 'slide') && this.formatPanelClosed()) {
142534
- return null;
142535
- }
142536
- return content;
142537
- }, /* @ts-ignore */
142538
- ...(ngDevMode ? [{ debugName: "formatPanelContent" }] : /* istanbul ignore next */ []));
142539
- /**
142540
- * Whether the right-docked inspector is showing the format panel (element or
142541
- * slide properties). Drives the top-bar inspector-toggle active state.
142542
- */
142543
- this.inspectorPaneOpen = computed(() => {
142544
- const content = this.formatPanelContent();
142545
- return content === 'element' || content === 'slide';
142546
- }, /* @ts-ignore */
142547
- ...(ngDevMode ? [{ debugName: "inspectorPaneOpen" }] : /* istanbul ignore next */ []));
142548
- /** Inspector content, but null on mobile once the user has swiped it away. */
142549
- this.visibleInspectorKind = computed(() => this.mobile.isMobile() && this.mobileInspectorHidden() ? null : this.formatPanelContent(), /* @ts-ignore */
142550
- ...(ngDevMode ? [{ debugName: "visibleInspectorKind" }] : /* istanbul ignore next */ []));
142551
- /** Accessible-label translation key for the inspector host, by active content. */
142552
- this.inspectorLabel = computed(() => {
142553
- switch (this.inspectorContent()) {
142554
- case 'accessibility':
142555
- return 'pptx.accessibility.title';
142556
- case 'signatures':
142557
- return 'pptx.viewer.digitalSignatures';
142558
- case 'comments':
142559
- return 'pptx.toolbar.comments';
142560
- case 'selection':
142561
- return 'pptx.selectionPane.title';
142562
- case 'element':
142563
- return 'pptx.inspector.properties';
142564
- case 'slide':
142565
- return 'pptx.inspector.properties';
142566
- default:
142567
- return '';
142568
- }
142569
- }, /* @ts-ignore */
142570
- ...(ngDevMode ? [{ debugName: "inspectorLabel" }] : /* istanbul ignore next */ []));
142571
- /**
142572
- * Ribbon "toggle inspector" action: if a tool panel is active, return to
142573
- * the format (element/slide) view; otherwise toggle the format view's
142574
- * open/closed state, matching React's and Vue's independent open/close
142575
- * toggle (closing/opening is not tied to selection changes).
142576
- */
142577
- /**
142578
- * Monotonic counter bumped by {@link openAnimationPanel}; the inspector
142579
- * panel reacts to every change by expanding its Animation section, so a
142580
- * user who collapsed it by hand gets it back on the next ribbon click.
142581
- */
142582
- this.animationPanelRequest = signal(0, /* @ts-ignore */
142583
- ...(ngDevMode ? [{ debugName: "animationPanelRequest" }] : /* istanbul ignore next */ []));
142584
- }
142585
- /** Wire the host accessors (called once from the component constructor). */
142586
- bind(host) {
142587
- this.host = host;
142588
- }
142589
- requireHost() {
142590
- if (!this.host) {
142591
- throw new Error('ViewerInspectorPanelService.bind() was not called');
142592
- }
142593
- return this.host;
142594
- }
142595
- /**
142596
- * Dismiss the mobile bottom-sheet inspector (backdrop tap or a past-threshold
142597
- * swipe-down): hide the host until reopened and clear any explicit tool panel.
142598
- */
142599
- dismissMobileInspector() {
142600
- this.mobileInspectorHidden.set(true);
142601
- this.activePanel.set(null);
142602
- }
142603
- /** Toggle a right-docked tool panel (clicking the active one closes it). */
142604
- togglePanel(panel) {
142605
- this.activePanel.update((current) => (current === panel ? null : panel));
142606
- // Tapping a panel button re-opens the host even after a swipe-dismiss.
142607
- this.mobileInspectorHidden.set(false);
142608
- }
142609
- /**
142610
- * Mobile bottom-bar "Format" slot: close any explicit tool panel, reopen
142611
- * the format (element/slide) view, and undo a prior swipe-dismiss so the
142612
- * pane is guaranteed to surface (React parity: the Format button opens the
142613
- * inspector that starts closed on mobile).
142614
- */
142615
- openFormatPanel() {
142616
- this.activePanel.set(null);
142617
- this.formatPanelClosed.set(false);
142618
- this.mobileInspectorHidden.set(false);
142619
- }
142620
- /**
142621
- * Ribbon "Animation Panel": surface the format view like
142622
- * {@link openFormatPanel} AND expand the inspector's Animation section
142623
- * (React's `onOpenAnimationPanel` lands on those controls directly).
142624
- */
142625
- openAnimationPanel() {
142626
- this.openFormatPanel();
142627
- this.animationPanelRequest.update((n) => n + 1);
142628
- }
142629
- toggleFormatPanel() {
142630
- if (this.activePanel() !== null) {
142631
- this.activePanel.set(null);
142632
- this.formatPanelClosed.set(false);
142633
- }
142634
- else {
142635
- this.formatPanelClosed.update((closed) => !closed);
142636
- }
142637
- }
142638
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ViewerInspectorPanelService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
142639
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ViewerInspectorPanelService }); }
142640
- }
142641
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ViewerInspectorPanelService, decorators: [{
142642
- type: Injectable
142643
- }] });
142644
-
142645
143888
  /** Paragraph alignment or clear-character-formatting, applied to the selection. */
142646
143889
  function applyTextCommand(editor, slideIndex, element, patch, inlineEditing) {
142647
143890
  patchTextStyle(editor, slideIndex, element, patch, inlineEditing?.readInlineSnapshot(), (next) => inlineEditing?.formatInlineSnapshot(next) ?? false);
@@ -143536,6 +144779,9 @@ class ViewerKeyboardService {
143536
144779
  case 'cycleSelectionPrev':
143537
144780
  this.cycleSelection(idx, 'prev');
143538
144781
  break;
144782
+ case 'pasteSpecial':
144783
+ this.editor.isPasteSpecialDialogOpen.set(true);
144784
+ break;
143539
144785
  default:
143540
144786
  break;
143541
144787
  }
@@ -145557,6 +146803,21 @@ class PresentationShowNavigator {
145557
146803
  if (direction === 'next' && this.deps.playback.advance()) {
145558
146804
  return;
145559
146805
  }
146806
+ // A Slide Zoom / Section Zoom / Summary Zoom tile whose `zmPr` set
146807
+ // `returnToParent` armed an excursion (see `navigateToZoomTarget`). Once a
146808
+ // FORWARD advance reaches the last slide of that target's range, jump
146809
+ // back to the zoom's origin slide instead of continuing linearly through
146810
+ // the deck; PowerPoint's return jump is forward-only, so `prev` never
146811
+ // consults this.
146812
+ if (direction === 'next') {
146813
+ const excursion = this.zoomExcursion;
146814
+ const step = resolveForwardSlideWithZoomReturn(this.currentIndex(), undefined, excursion);
146815
+ if (step.returnedToZoom && step.nextSlideIndex !== undefined) {
146816
+ this.zoomExcursion = step.excursion;
146817
+ this.goToSlide(step.nextSlideIndex, buildZoomTransitionOverride(excursion?.transitionDurationMs));
146818
+ return;
146819
+ }
146820
+ }
145560
146821
  if (direction === 'prev') {
145561
146822
  // A slide entered backward shows its builds already complete. The next
145562
146823
  // back press replays them from the start rather than leaving the slide,
@@ -145629,11 +146890,17 @@ class PresentationShowNavigator {
145629
146890
  this.commit(next, transition);
145630
146891
  }
145631
146892
  /**
145632
- * Jump directly to `index` (clamped). Used by zoom tiles and by on-slide
145633
- * Action Settings (`ppaction://hlinksldjump`); ENTERS the target slide, so
145634
- * PowerPoint plays its transition exactly as a forward step does.
146893
+ * Jump directly to `index` (clamped). Used by on-slide Action Settings
146894
+ * (`ppaction://hlinksldjump`) and by {@link navigateToZoomTarget}; ENTERS
146895
+ * the target slide, so PowerPoint plays its transition exactly as a forward
146896
+ * step does.
146897
+ *
146898
+ * @param transitionOverride Play this transition INSTEAD of the
146899
+ * destination's own authored `<p:transition>`. Set by a Slide Zoom /
146900
+ * Section Zoom / Summary Zoom navigation that authored its own
146901
+ * `zmPr/@transitionDur` (see `buildZoomTransitionOverride`).
145635
146902
  */
145636
- goToSlide(index) {
146903
+ goToSlide(index, transitionOverride) {
145637
146904
  const slides = this.deps.slides();
145638
146905
  const count = slides.length;
145639
146906
  if (count === 0) {
@@ -145646,7 +146913,26 @@ class PresentationShowNavigator {
145646
146913
  }
145647
146914
  const incoming = slides[next];
145648
146915
  const outgoing = slides[current];
145649
- this.commit(next, incoming?.transition && outgoing ? { outgoing, transition: incoming.transition } : null);
146916
+ const transition = transitionOverride
146917
+ ? outgoing
146918
+ ? { outgoing, transition: transitionOverride }
146919
+ : null
146920
+ : incoming?.transition && outgoing
146921
+ ? { outgoing, transition: incoming.transition }
146922
+ : null;
146923
+ this.commit(next, transition);
146924
+ }
146925
+ /**
146926
+ * Handle a Slide Zoom / Section Zoom / Summary Zoom tile click: navigates
146927
+ * to the target slide, playing the zoom's own `zmPr/@transitionDur` when
146928
+ * authored, and (when `returnToParent` is set) arms an excursion so the
146929
+ * next forward `navigate('next')` past the target's range returns to the
146930
+ * slide the zoom was clicked from instead of continuing linearly through
146931
+ * the deck.
146932
+ */
146933
+ navigateToZoomTarget(target) {
146934
+ this.zoomExcursion = beginZoomExcursion(target, this.currentIndex(), this.deps.slides());
146935
+ this.goToSlide(target.targetSlideIndex, buildZoomTransitionOverride(target.transitionDurationMs));
145650
146936
  }
145651
146937
  /**
145652
146938
  * The single place a slide change becomes visible: set the transition, move
@@ -147877,7 +149163,7 @@ class PresentationOverlayComponent {
147877
149163
  this.playback.setStyleApplier(() => this.stageAnimator.applyAnimationStyles({ onlyWhenStaged: true }));
147878
149164
  // Wire the zoom-navigation context to this overlay's slide navigation so a
147879
149165
  // descendant zoom tile can jump to its target slide on click.
147880
- this.zoomNavigation.setHandler((index) => this.navigator.goToSlide(index));
149166
+ this.zoomNavigation.setHandler((target) => this.navigator.navigateToZoomTarget(target));
147881
149167
  // Rebuild the native-animation controller for the current slide (seeds the
147882
149168
  // pre-build state so entrance-animated elements start hidden) and publish its
147883
149169
  // per-slide keyframes CSS.
@@ -150919,26 +152205,6 @@ const EMPHASIS_PRESETS = [
150919
152205
  { value: 'wave', label: 'Wave', labelKey: 'pptx.animation.preset.wave' },
150920
152206
  { value: 'boldFlash', label: 'Bold Flash', labelKey: 'pptx.animation.preset.boldFlash' },
150921
152207
  ];
150922
- /** Trigger options for the trigger selector. */
150923
- const TRIGGER_OPTIONS = [
150924
- { value: 'onClick', label: 'On Click', labelKey: 'pptx.animation.trigger.onClick' },
150925
- {
150926
- value: 'onShapeClick',
150927
- label: 'On Shape Click',
150928
- labelKey: 'pptx.animation.trigger.onShapeClick',
150929
- },
150930
- { value: 'onHover', label: 'On Hover', labelKey: 'pptx.animation.trigger.onHover' },
150931
- {
150932
- value: 'afterPrevious',
150933
- label: 'After Previous',
150934
- labelKey: 'pptx.animation.trigger.afterPrevious',
150935
- },
150936
- {
150937
- value: 'withPrevious',
150938
- label: 'With Previous',
150939
- labelKey: 'pptx.animation.trigger.withPrevious',
150940
- },
150941
- ];
150942
152208
  /** Timing curve options. */
150943
152209
  const TIMING_CURVE_OPTIONS = [
150944
152210
  { value: 'ease', label: 'Ease', labelKey: 'pptx.animation.timingCurve.ease' },
@@ -155459,7 +156725,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
155459
156725
  }], 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 }] }] } });
155460
156726
 
155461
156727
  // Generated by scripts/inline-shared.mjs from package.json. Do not edit.
155462
- const PPTX_ANGULAR_VIEWER_VERSION = "4.2.0";
156728
+ const PPTX_ANGULAR_VIEWER_VERSION = "4.3.0";
155463
156729
 
155464
156730
  /**
155465
156731
  * account-page.component.ts: File > Account content.
@@ -161007,7 +162273,11 @@ class AccessibilityTextPanelComponent {
161007
162273
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AccessibilityTextPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
161008
162274
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: AccessibilityTextPanelComponent, isStandalone: true, selector: "pptx-accessibility-text-panel", inputs: { element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { patch: "patch" }, ngImport: i0, template: `
161009
162275
  @if (fields().showAltText || fields().showTitle) {
161010
- <div class="pptx-ng-accessibility-text" data-pptx-accessibility-text>
162276
+ <div
162277
+ class="pptx-ng-accessibility-text"
162278
+ data-pptx-accessibility-text
162279
+ data-pptx-inspector-section="alt-text"
162280
+ >
161011
162281
  @if (fields().showAltText) {
161012
162282
  <label class="field field--stacked">
161013
162283
  <span>{{ 'pptx.elementAccessibility.altText' | translate }}</span>
@@ -161038,7 +162308,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
161038
162308
  type: Component,
161039
162309
  args: [{ selector: 'pptx-accessibility-text-panel', standalone: true, imports: [TranslatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: `
161040
162310
  @if (fields().showAltText || fields().showTitle) {
161041
- <div class="pptx-ng-accessibility-text" data-pptx-accessibility-text>
162311
+ <div
162312
+ class="pptx-ng-accessibility-text"
162313
+ data-pptx-accessibility-text
162314
+ data-pptx-inspector-section="alt-text"
162315
+ >
161042
162316
  @if (fields().showAltText) {
161043
162317
  <label class="field field--stacked">
161044
162318
  <span>{{ 'pptx.elementAccessibility.altText' | translate }}</span>
@@ -176001,7 +177275,7 @@ class InspectorPanelComponent {
176001
177275
  -->
176002
177276
  <aside [class]="inspectorClass()" [attr.aria-label]="'pptx.inspector.properties' | translate">
176003
177277
  <!-- ── Transform: Position & Size ─────────────────────────────────── -->
176004
- <section class="pptx-ng-inspector__section">
177278
+ <section class="pptx-ng-inspector__section" data-pptx-inspector-section="transform">
176005
177279
  <h3 class="pptx-ng-inspector__heading">{{ 'pptx.inspector.transform' | translate }}</h3>
176006
177280
 
176007
177281
  @if (elementKey(); as key) {
@@ -176090,7 +177364,7 @@ class InspectorPanelComponent {
176090
177364
 
176091
177365
  <!-- ── Shape fill & stroke (shape-style elements only) ────────────── -->
176092
177366
  @if (hasShape()) {
176093
- <section class="pptx-ng-inspector__section">
177367
+ <section class="pptx-ng-inspector__section" data-pptx-inspector-section="fill-stroke">
176094
177368
  <h3 class="pptx-ng-inspector__heading">{{ 'pptx.inspector.fillStroke' | translate }}</h3>
176095
177369
 
176096
177370
  @if (elementKey(); as key) {
@@ -176529,7 +177803,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
176529
177803
  -->
176530
177804
  <aside [class]="inspectorClass()" [attr.aria-label]="'pptx.inspector.properties' | translate">
176531
177805
  <!-- ── Transform: Position & Size ─────────────────────────────────── -->
176532
- <section class="pptx-ng-inspector__section">
177806
+ <section class="pptx-ng-inspector__section" data-pptx-inspector-section="transform">
176533
177807
  <h3 class="pptx-ng-inspector__heading">{{ 'pptx.inspector.transform' | translate }}</h3>
176534
177808
 
176535
177809
  @if (elementKey(); as key) {
@@ -176618,7 +177892,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
176618
177892
 
176619
177893
  <!-- ── Shape fill & stroke (shape-style elements only) ────────────── -->
176620
177894
  @if (hasShape()) {
176621
- <section class="pptx-ng-inspector__section">
177895
+ <section class="pptx-ng-inspector__section" data-pptx-inspector-section="fill-stroke">
176622
177896
  <h3 class="pptx-ng-inspector__heading">{{ 'pptx.inspector.fillStroke' | translate }}</h3>
176623
177897
 
176624
177898
  @if (elementKey(); as key) {
@@ -178201,6 +179475,112 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
178201
179475
  `, styles: [":host{display:block}.dir--grid{display:inline-grid;grid-template-columns:repeat(3,22px);gap:2px}.dir--row{display:flex;gap:3px}.dir__btn{min-width:22px;height:22px;padding:0 4px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;color:inherit;font:inherit;font-size:11px;line-height:1;cursor:pointer}.dir__btn:disabled{opacity:.5;cursor:default}.dir__btn.is-active{background:var(--pptx-inspector-active, #0078d4);border-color:var(--pptx-inspector-active, #0078d4);color:#fff}.dir__spacer{width:22px;height:22px}\n"] }]
178202
179476
  }], propDecorators: { directions: [{ type: i0.Input, args: [{ isSignal: true, alias: "directions", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], pick: [{ type: i0.Output, args: ["pick"] }] } });
178203
179477
 
179478
+ /**
179479
+ * transition-extra-options.component.ts: the "Pattern" button row (glitter's
179480
+ * diamond/hexagon, shred's strip/rectangle) and "Through Black" checkbox for
179481
+ * the slide-transition card, split out of `slide-transition-card.component.ts`
179482
+ * to keep it under the project's per-file LOC budget. Mirrors React's inline
179483
+ * pattern/thruBlk controls in `inspector/SlideTransitionSection.tsx`.
179484
+ *
179485
+ * Selector: `pptx-transition-extra-options`
179486
+ *
179487
+ * @module viewer/transition-extra-options
179488
+ */
179489
+ class TransitionExtraOptionsComponent {
179490
+ constructor() {
179491
+ /** Valid pattern tokens for the current transition type, or undefined. */
179492
+ this.patternOptions = input(undefined, /* @ts-ignore */
179493
+ ...(ngDevMode ? [{ debugName: "patternOptions" }] : /* istanbul ignore next */ []));
179494
+ /** Currently selected pattern token, if any. */
179495
+ this.value = input(undefined, /* @ts-ignore */
179496
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
179497
+ /** Whether the Through Black checkbox should render at all. */
179498
+ this.showThruBlk = input(false, /* @ts-ignore */
179499
+ ...(ngDevMode ? [{ debugName: "showThruBlk" }] : /* istanbul ignore next */ []));
179500
+ /** Current `thruBlk` value. */
179501
+ this.thruBlk = input(undefined, /* @ts-ignore */
179502
+ ...(ngDevMode ? [{ debugName: "thruBlk" }] : /* istanbul ignore next */ []));
179503
+ /** Whether the controls are inert (read-only deck). */
179504
+ this.disabled = input(false, /* @ts-ignore */
179505
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
179506
+ /** The pattern token the user chose. */
179507
+ this.patternPick = output();
179508
+ /** The new `thruBlk` value the user chose. */
179509
+ this.thruBlkChange = output();
179510
+ }
179511
+ onThruBlk(event) {
179512
+ this.thruBlkChange.emit(event.target.checked);
179513
+ }
179514
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TransitionExtraOptionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
179515
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: TransitionExtraOptionsComponent, isStandalone: true, selector: "pptx-transition-extra-options", inputs: { patternOptions: { classPropertyName: "patternOptions", publicName: "patternOptions", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, showThruBlk: { classPropertyName: "showThruBlk", publicName: "showThruBlk", isSignal: true, isRequired: false, transformFunction: null }, thruBlk: { classPropertyName: "thruBlk", publicName: "thruBlk", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { patternPick: "patternPick", thruBlkChange: "thruBlkChange" }, ngImport: i0, template: `
179516
+ @if (patternOptions(); as patterns) {
179517
+ <div class="icard__col">
179518
+ <span class="icard__label">{{ 'pptx.transition.pattern' | translate }}</span>
179519
+ <div class="pattern">
179520
+ @for (pattern of patterns; track pattern) {
179521
+ <button
179522
+ type="button"
179523
+ class="pattern__btn"
179524
+ [class.is-active]="(value() ?? patterns[0]) === pattern"
179525
+ [disabled]="disabled()"
179526
+ [attr.aria-pressed]="(value() ?? patterns[0]) === pattern"
179527
+ (click)="patternPick.emit(pattern)"
179528
+ >
179529
+ {{ 'pptx.transition.pattern.' + pattern | translate }}
179530
+ </button>
179531
+ }
179532
+ </div>
179533
+ </div>
179534
+ }
179535
+ @if (showThruBlk()) {
179536
+ <label class="check">
179537
+ <pptx-ui-checkbox
179538
+ [disabled]="disabled()"
179539
+ [checked]="thruBlk() === true"
179540
+ [attr.aria-label]="'pptx.transition.thruBlk' | translate"
179541
+ (change)="onThruBlk($event)"
179542
+ ></pptx-ui-checkbox>
179543
+ <span>{{ 'pptx.transition.thruBlk' | translate }}</span>
179544
+ </label>
179545
+ }
179546
+ `, isInline: true, styles: [":host{display:contents}.pattern{display:flex;gap:4px}.pattern__btn{padding:2px 8px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;color:inherit;font:inherit;font-size:11px;cursor:pointer}.pattern__btn:disabled{opacity:.5;cursor:default}.pattern__btn.is-active{background:var(--pptx-inspector-active, #0078d4);border-color:var(--pptx-inspector-active, #0078d4);color:#fff}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
179547
+ }
179548
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TransitionExtraOptionsComponent, decorators: [{
179549
+ type: Component,
179550
+ args: [{ selector: 'pptx-transition-extra-options', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslatePipe], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: `
179551
+ @if (patternOptions(); as patterns) {
179552
+ <div class="icard__col">
179553
+ <span class="icard__label">{{ 'pptx.transition.pattern' | translate }}</span>
179554
+ <div class="pattern">
179555
+ @for (pattern of patterns; track pattern) {
179556
+ <button
179557
+ type="button"
179558
+ class="pattern__btn"
179559
+ [class.is-active]="(value() ?? patterns[0]) === pattern"
179560
+ [disabled]="disabled()"
179561
+ [attr.aria-pressed]="(value() ?? patterns[0]) === pattern"
179562
+ (click)="patternPick.emit(pattern)"
179563
+ >
179564
+ {{ 'pptx.transition.pattern.' + pattern | translate }}
179565
+ </button>
179566
+ }
179567
+ </div>
179568
+ </div>
179569
+ }
179570
+ @if (showThruBlk()) {
179571
+ <label class="check">
179572
+ <pptx-ui-checkbox
179573
+ [disabled]="disabled()"
179574
+ [checked]="thruBlk() === true"
179575
+ [attr.aria-label]="'pptx.transition.thruBlk' | translate"
179576
+ (change)="onThruBlk($event)"
179577
+ ></pptx-ui-checkbox>
179578
+ <span>{{ 'pptx.transition.thruBlk' | translate }}</span>
179579
+ </label>
179580
+ }
179581
+ `, styles: [":host{display:contents}.pattern{display:flex;gap:4px}.pattern__btn{padding:2px 8px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;color:inherit;font:inherit;font-size:11px;cursor:pointer}.pattern__btn:disabled{opacity:.5;cursor:default}.pattern__btn.is-active{background:var(--pptx-inspector-active, #0078d4);border-color:var(--pptx-inspector-active, #0078d4);color:#fff}\n"] }]
179582
+ }], propDecorators: { patternOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "patternOptions", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], showThruBlk: [{ type: i0.Input, args: [{ isSignal: true, alias: "showThruBlk", required: false }] }], thruBlk: [{ type: i0.Input, args: [{ isSignal: true, alias: "thruBlk", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], patternPick: [{ type: i0.Output, args: ["patternPick"] }], thruBlkChange: [{ type: i0.Output, args: ["thruBlkChange"] }] } });
179583
+
178204
179584
  /**
178205
179585
  * transition-preview.component.ts: click-to-play thumbnail of the configured
178206
179586
  * slide transition, mirroring React's `inspector/TransitionPreview.tsx`.
@@ -178407,6 +179787,10 @@ class SlideTransitionCardComponent {
178407
179787
  return valid && valid.length > 0 ? valid : undefined;
178408
179788
  }, /* @ts-ignore */
178409
179789
  ...(ngDevMode ? [{ debugName: "directionTokens" }] : /* istanbul ignore next */ []));
179790
+ this.patternOptions = computed(() => TRANSITION_PATTERN_OPTIONS[this.transitionType()], /* @ts-ignore */
179791
+ ...(ngDevMode ? [{ debugName: "patternOptions" }] : /* istanbul ignore next */ []));
179792
+ this.hasThruBlk = computed(() => TRANSITION_THRUBLK_TYPES.has(this.transitionType()), /* @ts-ignore */
179793
+ ...(ngDevMode ? [{ debugName: "hasThruBlk" }] : /* istanbul ignore next */ []));
178410
179794
  this.orientation = computed(() => this.transition()?.orient ?? 'horz', /* @ts-ignore */
178411
179795
  ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
178412
179796
  this.spokes = computed(() => this.transition()?.spokes ?? 4, /* @ts-ignore */
@@ -178426,6 +179810,12 @@ class SlideTransitionCardComponent {
178426
179810
  onOrientation(orient) {
178427
179811
  this.patch({ orient });
178428
179812
  }
179813
+ onPattern(pattern) {
179814
+ this.patch({ pattern });
179815
+ }
179816
+ onThruBlk(thruBlk) {
179817
+ this.patch({ thruBlk });
179818
+ }
178429
179819
  onSpokes(event) {
178430
179820
  const spokes = clampTransitionNumber(Number(event.target.value), MIN_SPOKES, MAX_SPOKES);
178431
179821
  if (spokes !== null) {
@@ -178509,6 +179899,16 @@ class SlideTransitionCardComponent {
178509
179899
  </div>
178510
179900
  }
178511
179901
 
179902
+ <pptx-transition-extra-options
179903
+ [patternOptions]="patternOptions()"
179904
+ [value]="transition()?.pattern"
179905
+ [showThruBlk]="hasThruBlk()"
179906
+ [thruBlk]="transition()?.thruBlk"
179907
+ [disabled]="!canEdit()"
179908
+ (patternPick)="onPattern($event)"
179909
+ (thruBlkChange)="onThruBlk($event)"
179910
+ />
179911
+
178512
179912
  @if (isWheel()) {
178513
179913
  <label class="icard__row">
178514
179914
  <span class="icard__label">{{ 'pptx.transition.spokes' | translate }}</span>
@@ -178597,11 +179997,16 @@ class SlideTransitionCardComponent {
178597
179997
  }
178598
179998
  </section>
178599
179999
  }
178600
- `, isInline: true, styles: [":host{display:block}.orient{display:flex;gap:4px}.orient__btn{padding:3px 8px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;color:inherit;font:inherit;font-size:11px;cursor:pointer}.orient__btn:disabled{opacity:.5;cursor:default}.orient__btn.is-active{background:var(--pptx-inspector-active, #0078d4);border-color:var(--pptx-inspector-active, #0078d4);color:#fff}.check{display:flex;align-items:center;gap:6px}.sound{margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\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{--pptx-select-control-bg: var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));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__web-select{width:96px}.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}@media(max-width:767px){.icard__input,.icard__select,.icard__web-select{min-height:44px}.icard__btn{min-width:44px;min-height:44px}}\n"], dependencies: [{ kind: "component", type: TransitionDirectionPickerComponent, selector: "pptx-transition-direction-picker", inputs: ["directions", "value", "disabled"], outputs: ["pick"] }, { kind: "component", type: TransitionPreviewComponent, selector: "pptx-transition-preview", inputs: ["transition"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
180000
+ `, isInline: true, styles: [":host{display:block}.orient{display:flex;gap:4px}.orient__btn{padding:3px 8px;background:var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));border:1px solid var(--pptx-inspector-border, #444);border-radius:3px;color:inherit;font:inherit;font-size:11px;cursor:pointer}.orient__btn:disabled{opacity:.5;cursor:default}.orient__btn.is-active{background:var(--pptx-inspector-active, #0078d4);border-color:var(--pptx-inspector-active, #0078d4);color:#fff}.check{display:flex;align-items:center;gap:6px}.sound{margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\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{--pptx-select-control-bg: var(--pptx-inspector-input-bg, rgba(0, 0, 0, .06));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__web-select{width:96px}.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}@media(max-width:767px){.icard__input,.icard__select,.icard__web-select{min-height:44px}.icard__btn{min-width:44px;min-height:44px}}\n"], dependencies: [{ kind: "component", type: TransitionDirectionPickerComponent, selector: "pptx-transition-direction-picker", inputs: ["directions", "value", "disabled"], outputs: ["pick"] }, { kind: "component", type: TransitionExtraOptionsComponent, selector: "pptx-transition-extra-options", inputs: ["patternOptions", "value", "showThruBlk", "thruBlk", "disabled"], outputs: ["patternPick", "thruBlkChange"] }, { kind: "component", type: TransitionPreviewComponent, selector: "pptx-transition-preview", inputs: ["transition"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
178601
180001
  }
178602
180002
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SlideTransitionCardComponent, decorators: [{
178603
180003
  type: Component,
178604
- args: [{ schemas: [CUSTOM_ELEMENTS_SCHEMA], selector: 'pptx-slide-transition-card', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslatePipe, TransitionDirectionPickerComponent, TransitionPreviewComponent], template: `
180004
+ args: [{ schemas: [CUSTOM_ELEMENTS_SCHEMA], selector: 'pptx-slide-transition-card', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
180005
+ TranslatePipe,
180006
+ TransitionDirectionPickerComponent,
180007
+ TransitionExtraOptionsComponent,
180008
+ TransitionPreviewComponent,
180009
+ ], template: `
178605
180010
  @if (activeSlide()) {
178606
180011
  <section class="icard">
178607
180012
  <h3 class="icard__heading">{{ 'pptx.slideInspector.slideTransition' | translate }}</h3>
@@ -178655,6 +180060,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
178655
180060
  </div>
178656
180061
  }
178657
180062
 
180063
+ <pptx-transition-extra-options
180064
+ [patternOptions]="patternOptions()"
180065
+ [value]="transition()?.pattern"
180066
+ [showThruBlk]="hasThruBlk()"
180067
+ [thruBlk]="transition()?.thruBlk"
180068
+ [disabled]="!canEdit()"
180069
+ (patternPick)="onPattern($event)"
180070
+ (thruBlkChange)="onThruBlk($event)"
180071
+ />
180072
+
178658
180073
  @if (isWheel()) {
178659
180074
  <label class="icard__row">
178660
180075
  <span class="icard__label">{{ 'pptx.transition.spokes' | translate }}</span>
@@ -188976,6 +190391,75 @@ class PowerPointViewerComponent {
188976
190391
  this.inspectorPanel.mobileInspectorHidden.set(false);
188977
190392
  this.inspectorPanel.activePanel.set('comments');
188978
190393
  }
190394
+ /** Context-menu "Edit Text": same entry point a double-click uses. */
190395
+ onContextMenuEditText() {
190396
+ const id = this.selectedElement()?.id;
190397
+ if (id) {
190398
+ this.canvasEditing.onTextEditStart(id);
190399
+ }
190400
+ }
190401
+ /**
190402
+ * Context-menu "Save as Picture": rasterise the right-clicked element's
190403
+ * own DOM node (found the same way the canvas resolves a click target) and
190404
+ * download it, reusing the same raster/download pipeline every other
190405
+ * export button in this binding already goes through.
190406
+ */
190407
+ onContextMenuSaveAsPicture() {
190408
+ const element = this.selectedElement();
190409
+ if (!element) {
190410
+ return;
190411
+ }
190412
+ const node = document.querySelector(`[data-element-id="${element.id}"]`);
190413
+ if (!node) {
190414
+ return;
190415
+ }
190416
+ void renderElementPngBlob(node, 2).then((blob) => {
190417
+ downloadBlob(blob, elementPictureFilename(element.name, 'Picture'));
190418
+ return undefined;
190419
+ });
190420
+ }
190421
+ /**
190422
+ * Paste Special dialog OK: paste the clipboard with `format` applied. For
190423
+ * "Picture", the plain clone is inserted first (there is nothing to
190424
+ * rasterize before it is mounted); this waits one frame, then rasterises
190425
+ * each inserted node and replaces it, the same DOM lookup/raster pipeline
190426
+ * "Save as Picture" already uses.
190427
+ */
190428
+ onPasteSpecialConfirm(format) {
190429
+ this.editor.isPasteSpecialDialogOpen.set(false);
190430
+ const entries = this.editor.pasteWithFormat(this.activeSlideIndex(), format);
190431
+ if (format !== 'picture' || entries.length === 0) {
190432
+ return;
190433
+ }
190434
+ requestAnimationFrame(() => {
190435
+ for (const { id, sourceClone } of entries) {
190436
+ void this.rasterizePastedNodeAsPicture(id, sourceClone);
190437
+ }
190438
+ });
190439
+ }
190440
+ /** Paste Options toolbar: re-derive the already-pasted element(s) from their own pristine clone. */
190441
+ onPasteOptionsChoose(format) {
190442
+ const entries = this.editor.pasteOptionsToolbar();
190443
+ if (!entries) {
190444
+ return;
190445
+ }
190446
+ if (format === 'picture') {
190447
+ for (const { id, sourceClone } of entries) {
190448
+ void this.rasterizePastedNodeAsPicture(id, sourceClone);
190449
+ }
190450
+ return;
190451
+ }
190452
+ this.editor.reformatPasted(this.activeSlideIndex(), entries, format);
190453
+ }
190454
+ /** Rasterise the mounted node for `elementId` and replace it with a picture, or no-op if unmounted. */
190455
+ async rasterizePastedNodeAsPicture(elementId, sourceClone) {
190456
+ const node = document.querySelector(`[data-element-id="${elementId}"]`);
190457
+ if (!node) {
190458
+ return;
190459
+ }
190460
+ const dataUrl = await renderElementPngDataUrl(node, 2);
190461
+ this.editor.updateElement(this.activeSlideIndex(), elementId, buildRasterPictureElement(sourceClone, dataUrl));
190462
+ }
188979
190463
  /** Canvas marker click: bring the comments panel on screen (same as above). */
188980
190464
  onCommentMarkerClick() {
188981
190465
  this.inspectorPanel.mobileInspectorHidden.set(false);
@@ -190159,10 +191643,23 @@ class PowerPointViewerComponent {
190159
191643
  (fixAi)="onContextMenuFixAi()"
190160
191644
  (editHyperlink)="docProperties.showHyperlink.set(true)"
190161
191645
  (addComment)="onContextMenuAddComment()"
191646
+ (editText)="onContextMenuEditText()"
191647
+ (saveAsPicture)="onContextMenuSaveAsPicture()"
190162
191648
  (closed)="canvasEditing.contextMenuPos.set(null)"
190163
191649
  />
190164
191650
  }
190165
191651
 
191652
+ <pptx-paste-special-dialog
191653
+ [open]="editor.isPasteSpecialDialogOpen()"
191654
+ (cancel)="editor.isPasteSpecialDialogOpen.set(false)"
191655
+ (confirm)="onPasteSpecialConfirm($event)"
191656
+ />
191657
+ <pptx-paste-options-toolbar
191658
+ [elementId]="editor.pasteOptionsToolbar()?.[0]?.id ?? null"
191659
+ (choose)="onPasteOptionsChoose($event)"
191660
+ (dismiss)="editor.pasteOptionsToolbar.set(null)"
191661
+ />
191662
+
190166
191663
  <pptx-theme-gallery
190167
191664
  [open]="themeGallery.showThemeGallery()"
190168
191665
  [startCustomizing]="themeEditorRequested()"
@@ -190402,7 +191899,7 @@ class PowerPointViewerComponent {
190402
191899
  (dismissAll)="loadNotices.dismissAllToasts()"
190403
191900
  />
190404
191901
  </div>
190405
- `, 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", "fitPadding", "maxFitScale", "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", "listSession", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationOverlayComponent, selector: "pptx-presentation-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "startIndex", "activeCustomShow", "authoredRange", "loopContinuously", "showWithAnimation", "useTimings", "subtitlesVisible", "sessionEnded", "endWithBlackSlide", "pixelateMosaicAnimation", "presenterMode", "showMenuOnRightClick", "showPopupToolbar"], outputs: ["indexChange", "closed", "subtitlesChange", "presenterViewToggle", "annotationsExit", "customShowRequest", "endOfShowChange"] }, { kind: "component", type: PresenterViewComponent, selector: "pptx-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "authoredRange", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime", "isAudienceWindowOpen"], outputs: ["movePresentationSlide", "exit", "openAudienceWindow", "closeAudienceWindow", "navigateToSlide"] }, { kind: "component", type: MobilePresenterViewComponent, selector: "pptx-mobile-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "authoredRange", "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", "modernCommentAuthors"], 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", "modernCommentAuthors"], outputs: ["add", "remove", "resolve", "reply"] }, { kind: "component", type: CompatToastsComponent, selector: "pptx-compat-toasts", inputs: ["toasts", "rightInset", "bottomInset"], outputs: ["dismissOne", "dismissAll"] }, { kind: "component", type: ReadOnlyBannerComponent, selector: "pptx-readonly-banner", inputs: ["kind", "messageKey", "passwordPromptOpen", "passwordError", "checkingPassword"], outputs: ["editAnyway", "dismiss", "submitPassword", "cancelPassword"] }, { 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", "crudActions"], outputs: ["tabChange", "selectMaster", "selectLayout", "slidesPerPageChange", "backgroundChange", "close", "crudAction"] }, { 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", "savePpt", "toggleSidebar", "toggleAiPanel", "signatures", "info", "print", "comments", "a11y", "shortcuts", "versionHistory", "passwordProtection", "fontEmbedding", "link", "goToNormalView", "openSorter", "openReadingView", "openOutlineView", "openMasterView", "toggleNotes", "toggleFormatPainter", "exportPng", "exportPdf", "exportGif", "exportVideo", "exportJson", "copySlideAsImage", "replace", "toggleInspector", "openAnimationPanel", "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", "discarding"], 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 */
191902
+ `, 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", "fitPadding", "maxFitScale", "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", "listSession", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationOverlayComponent, selector: "pptx-presentation-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "startIndex", "activeCustomShow", "authoredRange", "loopContinuously", "showWithAnimation", "useTimings", "subtitlesVisible", "sessionEnded", "endWithBlackSlide", "pixelateMosaicAnimation", "presenterMode", "showMenuOnRightClick", "showPopupToolbar"], outputs: ["indexChange", "closed", "subtitlesChange", "presenterViewToggle", "annotationsExit", "customShowRequest", "endOfShowChange"] }, { kind: "component", type: PresenterViewComponent, selector: "pptx-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "authoredRange", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime", "isAudienceWindowOpen"], outputs: ["movePresentationSlide", "exit", "openAudienceWindow", "closeAudienceWindow", "navigateToSlide"] }, { kind: "component", type: MobilePresenterViewComponent, selector: "pptx-mobile-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "authoredRange", "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", "modernCommentAuthors"], 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", "editText", "saveAsPicture"] }, { 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", "modernCommentAuthors"], outputs: ["add", "remove", "resolve", "reply"] }, { kind: "component", type: CompatToastsComponent, selector: "pptx-compat-toasts", inputs: ["toasts", "rightInset", "bottomInset"], outputs: ["dismissOne", "dismissAll"] }, { kind: "component", type: ReadOnlyBannerComponent, selector: "pptx-readonly-banner", inputs: ["kind", "messageKey", "passwordPromptOpen", "passwordError", "checkingPassword"], outputs: ["editAnyway", "dismiss", "submitPassword", "cancelPassword"] }, { 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: PasteSpecialDialogComponent, selector: "pptx-paste-special-dialog", inputs: ["open"], outputs: ["cancel", "confirm"] }, { kind: "component", type: PasteOptionsToolbarComponent, selector: "pptx-paste-options-toolbar", inputs: ["elementId"], outputs: ["choose", "dismiss"] }, { 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", "crudActions"], outputs: ["tabChange", "selectMaster", "selectLayout", "slidesPerPageChange", "backgroundChange", "close", "crudAction"] }, { 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", "savePpt", "toggleSidebar", "toggleAiPanel", "signatures", "info", "print", "comments", "a11y", "shortcuts", "versionHistory", "passwordProtection", "fontEmbedding", "link", "goToNormalView", "openSorter", "openReadingView", "openOutlineView", "openMasterView", "toggleNotes", "toggleFormatPainter", "exportPng", "exportPdf", "exportGif", "exportVideo", "exportJson", "copySlideAsImage", "replace", "toggleInspector", "openAnimationPanel", "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", "discarding"], 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 */
190406
191903
  Promise.resolve().then(function () { return aiChatPanel_component; }).then(m => m.AiChatPanelComponent)]] }); }
190407
191904
  }
190408
191905
  i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.6", ngImport: i0, type: PowerPointViewerComponent, resolveDeferredDeps: () => [/* @ts-ignore */
@@ -190446,6 +191943,8 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.6", ng
190446
191943
  PrintDialogComponent,
190447
191944
  ShareDialogComponent,
190448
191945
  BroadcastDialogComponent,
191946
+ PasteSpecialDialogComponent,
191947
+ PasteOptionsToolbarComponent,
190449
191948
  MobileBottomBarComponent,
190450
191949
  MobileMenuSheetComponent,
190451
191950
  MobileSlidesSheetComponent,
@@ -191192,10 +192691,23 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.6", ng
191192
192691
  (fixAi)="onContextMenuFixAi()"
191193
192692
  (editHyperlink)="docProperties.showHyperlink.set(true)"
191194
192693
  (addComment)="onContextMenuAddComment()"
192694
+ (editText)="onContextMenuEditText()"
192695
+ (saveAsPicture)="onContextMenuSaveAsPicture()"
191195
192696
  (closed)="canvasEditing.contextMenuPos.set(null)"
191196
192697
  />
191197
192698
  }
191198
192699
 
192700
+ <pptx-paste-special-dialog
192701
+ [open]="editor.isPasteSpecialDialogOpen()"
192702
+ (cancel)="editor.isPasteSpecialDialogOpen.set(false)"
192703
+ (confirm)="onPasteSpecialConfirm($event)"
192704
+ />
192705
+ <pptx-paste-options-toolbar
192706
+ [elementId]="editor.pasteOptionsToolbar()?.[0]?.id ?? null"
192707
+ (choose)="onPasteOptionsChoose($event)"
192708
+ (dismiss)="editor.pasteOptionsToolbar.set(null)"
192709
+ />
192710
+
191199
192711
  <pptx-theme-gallery
191200
192712
  [open]="themeGallery.showThemeGallery()"
191201
192713
  [startCustomizing]="themeEditorRequested()"
@@ -193503,14 +195015,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
193503
195015
  * - `resetRequested` : user pressed Reset (back to before the first group)
193504
195016
  * - `seek` : user clicked a step row (jump to that step index)
193505
195017
  */
193506
- const TRIGGER_LABEL_KEYS = [
193507
- { value: 'onClick', key: 'pptx.animation.trigger.onClick' },
193508
- { value: 'onShapeClick', key: 'pptx.animation.trigger.onClick' },
193509
- { value: 'onHover', key: 'pptx.animation.trigger.onHover' },
193510
- { value: 'withPrevious', key: 'pptx.animation.trigger.withPrevious' },
193511
- { value: 'afterPrevious', key: 'pptx.animation.trigger.afterPrevious' },
193512
- { value: 'afterDelay', key: 'pptx.animation.trigger.afterDelay' },
193513
- ];
195018
+ /**
195019
+ * Trigger label lookup, derived from shared's `TRIGGER_OPTIONS` instead of a
195020
+ * hand-maintained copy: this file's own former copy mislabelled
195021
+ * `onShapeClick` with `onClick`'s key (both resolved to the same "On Click"
195022
+ * text, so a Shape Click trigger never showed as itself in the playback
195023
+ * panel's step list).
195024
+ */
195025
+ const TRIGGER_LABEL_KEYS = TRIGGER_OPTIONS.map((option) => ({ value: option.value, key: option.labelKey }));
193514
195026
  /**
193515
195027
  * The step's effect name.
193516
195028
  *
@@ -193852,5 +195364,5 @@ function cn(...values) {
193852
195364
  * Generated bundle index. Do not edit.
193853
195365
  */
193854
195366
 
193855
- export { ChartAxisOptionsComponent as $, AFTER_ANIMATION_VALUES as A, ActionSettingsPanelComponent as B, CHART_3D_DRAG_THRESHOLD_PX as C, AdvancedChartEditorComponent as D, AiChangeOverlayComponent as E, AiChatPanelComponent as F, AiChatService as G, AiComposerComponent as H, AiFocusBarComponent as I, AiFocusHighlightOverlayComponent as J, AiHistoryMenuComponent as K, AiHistoryService as L, AiMessageListComponent as M, AiPanelStore as N, AiProposalCardComponent as O, AiSettingsSectionComponent as P, AiToolCallCardComponent as Q, AnimationAuthorPanelComponent as R, AnimationPanelComponent as S, AnimationPlaybackService as T, AutosaveRecoveryDialogComponent as U, AutosaveService as V, BroadcastDialogComponent as W, CHART_EDITOR_STYLES as X, CINEMATIC_TRANSITION_KEYFRAMES as Y, CURSOR_PALETTE as Z, CanvasFitService as _, renderChartTextSvg as a, ExportProgressModalComponent as a$, ChartAxisStyleOptionsComponent as a0, ChartComboTypeOptionsComponent as a1, ChartDataEditorComponent as a2, ChartDataLabelOptionsComponent as a3, ChartDatapointMarkerOptionsComponent as a4, ChartDatapointOptionsComponent as a5, ChartDisplayOptionsComponent as a6, ChartElementViewComponent as a7, ChartErrorBarOptionsComponent as a8, ChartMarkerOptionsComponent as a9, DEFAULT_SLIDE_BACKGROUND as aA, DEFAULT_STROKE_COLOR as aB, DEFAULT_STYLE as aC, DEFAULT_TABLE_ROW_HEIGHT as aD, DEFAULT_TEXT_COLOR$2 as aE, DEFAULT_VIEWER_PROFILE as aF, DIRECTIONAL_PRESETS as aG, DIRECTION_OPTIONS as aH, DocumentPropertiesCardComponent as aI, EASE as aJ, EFFECT_SOUND_CATALOGUE as aK, EMBEDDED_FONTS_STYLE_ID as aL, EMPHASIS_PRESETS as aM, ENTRANCE_PRESETS as aN, TEMPLATES as aO, EXIT_PRESETS as aP, EditorContextMenuComponent as aQ, EditorHistory as aR, EditorStateService as aS, EditorToolbarComponent as aT, EffectsPanelComponent as aU, ElementRendererComponent as aV, EmbeddedFontsService as aW, EncryptedFileDialogComponent as aX, EquationEditorDialogComponent as aY, EquationRendererComponent as aZ, EquationTemplateGalleryComponent as a_, ChartPartSelectionService as aa, ChartPrimitivesComponent as ab, ChartRendererComponent as ac, ChartTrendlineOptionsComponent as ad, ChartTypeSelectorComponent as ae, CollaborationCursorsComponent as af, CollaborationService as ag, ColorChangedImageComponent as ah, CommentMarkersOverlayComponent as ai, CommentsPanelComponent as aj, CommentsService as ak, ComparePanelComponent as al, ConnectorRendererComponent as am, ConnectorTextOverlayComponent as an, CustomShowsComponent as ao, DEFAULT_BOUNDS as ap, DEFAULT_BROADCAST_SERVER_URL as aq, DEFAULT_CANVAS_HEIGHT as ar, DEFAULT_CANVAS_WIDTH as as, DEFAULT_COLOR_SCHEME as at, DEFAULT_FILL_COLOR$1 as au, DEFAULT_LAYOUT as av, DEFAULT_MORPH_DURATION_MS as aw, DEFAULT_PALETTE$1 as ax, DEFAULT_PATTERN_FILL_PRESET as ay, DEFAULT_PRINT_SETTINGS as az, appendChartLegendSvg as b, PresentToolbarAutoHide as b$, ExportService as b0, FieldContextService as b1, FindBarComponent as b2, FindReplaceBarComponent as b3, FollowModeBarComponent as b4, FontEmbeddingListComponent as b5, FontEmbeddingPanelComponent as b6, GALLERY_THEME_PRESETS as b7, GOOGLE_WEBFONTS_LINK_ID as b8, GRIDLINE_COLOR$1 as b9, MobileBottomBarComponent as bA, MobileMenuSheetComponent as bB, MobilePresenterViewComponent as bC, MobileSheetComponent as bD, MobileSlidesSheetComponent as bE, MobileToolbarComponent as bF, ModalDialogComponent as bG, Model3DRendererComponent as bH, NotesHandoutCardComponent as bI, NotesPanelComponent as bJ, NotesToolbarComponent as bK, OleRendererComponent as bL, OutlineViewOverlayComponent as bM, P14_TRANSITION_KEYFRAMES as bN, P14_TRANSITION_KEYFRAMES_2 as bO, P14_TRANSITION_KEYFRAMES_ALL as bP, POWER_POINT_VIEWER_PROVIDERS as bQ, PPTX_OPEN_ACCEPT as bR, PRESENTATION_OPEN_EXTENSIONS as bS, PRESENTER_CHANNEL_NAME as bT, PRESENTER_MSG_ORIGIN as bU, PRESENTER_TIMER_SEGMENT_MS as bV, PX_PER_CM as bW, PX_PER_INCH as bX, PasswordProtectionDialogComponent as bY, PasswordStrengthMeterComponent as bZ, PowerPointViewerComponent as b_, GoogleWebfontsService as ba, GradientPickerComponent as bb, HANDOUT_OPTIONS as bc, HeaderFooterDialogComponent as bd, HyperlinkDialogComponent as be, INSTANT as bf, ImagePropertiesPanelComponent as bg, InkDrawingService as bh, InkRendererComponent as bi, InsertSmartArtDialogComponent as bj, InspectorPaneHeaderComponent as bk, InspectorPanelComponent as bl, IsMobileService as bm, KeepAnnotationsDialogComponent as bn, LOCALE_CATALOG as bo, LONG_PRESS_DURATION_MS as bp, LONG_PRESS_MOVE_TOLERANCE_PX as bq, LoadContentService as br, LocalPresencePublisher as bs, MAX_ZOOM_SCALE as bt, MIN_ZOOM_SCALE as bu, MOTION_PATH_COLUMNS as bv, MediaPreviewComponent as bw, MediaPropertiesPanelComponent as bx, MediaRendererComponent as by, MediaTrimTimelineComponent as bz, createSvgEl as c, SettingsAppearanceTabComponent as c$, PresentationAnnotationOverlayComponent as c0, PresentationAnnotationsService as c1, PresentationOverlayComponent as c2, PresentationPropertiesPanelComponent as c3, PresentationSettingsCardComponent as c4, PresentationSubtitleBarComponent as c5, PresentationToolbarComponent as c6, PresentationTransitionOverlayComponent as c7, PresenterViewComponent as c8, PresenterWindowService as c9, RibbonInsertSectionComponent as cA, RibbonMotionPathGalleryComponent as cB, RibbonParagraphControlsComponent as cC, RibbonPrimaryRowComponent as cD, RibbonReviewSectionComponent as cE, RibbonShapeExtrasComponent as cF, RibbonSlideshowSectionComponent as cG, RibbonTransitionsSectionComponent as cH, RibbonViewSectionComponent as cI, RulerGuidesService as cJ, SEQUENCE_OPTIONS as cK, SEVERITY_GROUPS as cL, SEVERITY_LABELS as cM, DEFAULT_TRANSITION_DURATION_MS$1 as cN, SHORTCUT_REFERENCE_ITEMS as cO, SLIDE_TRANSITION_KEYFRAMES as cP, SLIDE_TRANSITION_KEYFRAMES_CSS as cQ, DEFAULT_PALETTE as cR, PALETTES as cS, SMART_ART_COLOR_SCHEMES as cT, SMART_ART_STYLE_OPTIONS as cU, SUB_ITEM_LABEL as cV, SVG_WARP_PRESETS as cW, SWIPE_MAX_VERTICAL_PX as cX, SWIPE_THRESHOLD_PX as cY, SelectionPaneComponent as cZ, SetUpSlideShowDialogComponent as c_, PrintDialogComponent as ca, PrintService as cb, PrintSettingsPanelComponent as cc, PropertiesDialogComponent as cd, RANDOM_ELIGIBLE_TYPES as ce, REPEAT_MODE_OPTIONS as cf, RESIZE_HANDLES as cg, RULER_FONT_SIZE as ch, RULER_THICKNESS as ci, ReadingViewOverlayComponent as cj, RemoteSelectionOverlayComponent as ck, Rendering3DService as cl, RibbonAnimationGalleryComponent as cm, RibbonAnimationsSectionComponent as cn, RibbonArrangeSectionComponent as co, RibbonColorPopoverComponent as cp, RibbonComponent as cq, RibbonDesignSectionComponent as cr, RibbonDrawSectionComponent as cs, RibbonDrawingGroupComponent as ct, RibbonEditingSectionComponent as cu, RibbonFileSectionComponent as cv, RibbonFontControlsComponent as cw, RibbonHomeSectionComponent as cx, RibbonHyperlinkButtonComponent as cy, RibbonInsertFieldsComponent as cz, dragAnchorViewY as d, ViewerDocumentPropertiesService as d$, SettingsDialogComponent as d0, SettingsLanguageTabComponent as d1, ShareDialogComponent as d2, ShortcutPanelComponent as d3, ShowOptionsFieldsetComponent as d4, ShowSlidesFieldsetComponent as d5, SignatureStrippedDialogComponent as d6, SignaturesPanelComponent as d7, SignaturesService as d8, SlideBackgroundCardComponent as d9, TableCellFormattingComponent as dA, TableDataEditorComponent as dB, TablePropertiesComponent as dC, TableRendererComponent as dD, TableResizeOverlayComponent as dE, TableSelectionService as dF, TagsCardComponent as dG, Text3DBevelSectionComponent as dH, Text3DPanelComponent as dI, TextAdvancedPanelComponent as dJ, ThemeEditorFieldsComponent as dK, ThemeGalleryComponent as dL, ThemeSelectorCardComponent as dM, TitleBarComponent as dN, TitleBarSearchComponent as dO, TransitionDirectionPickerComponent as dP, TransitionPreviewComponent as dQ, VALIGN_OPTIONS as dR, VIEWER_THEME as dS, VersionHistoryPanelComponent as dT, ViewerCanvasEditingService as dU, ViewerCollabCursorService as dV, ViewerCollaborationSessionService as dW, ViewerCollaborationShellService as dX, ViewerCompareService as dY, ViewerCustomShowsService as dZ, ViewerDialogsService as d_, SlideCanvasComponent as da, SlideDefaultInspectorComponent as db, SlideDiffChangesComponent as dc, SlideDiffRowComponent as dd, SlideDiffThumbnailsComponent as de, SlideSizeCardComponent as df, SlideSorterOverlayComponent as dg, SlideThemeOverridePanelComponent as dh, SlideTransitionCardComponent as di, SlidesPanelComponent as dj, SmartArt3DRendererComponent as dk, SmartArtPreviewComponent as dl, SmartArtPropertiesComponent as dm, SmartArtRendererComponent as dn, StatusBarComponent as dp, TABLE_STRUCTURE_TOGGLES as dq, TEXT_3D_BOTTOM_BEVEL_KEYS as dr, TEXT_3D_TOP_BEVEL_KEYS as ds, TEXT_DIRECTION_OPTIONS$1 as dt, THEME_CATALOG as du, TIMING_CURVE_OPTIONS as dv, TRANSITION_SPEED_DURATION_MS as dw, TRIGGER_OPTIONS as dx, TYPE_LABELS as dy, TableCellAdvancedFillComponent as dz, advanceChartValueDrag as e, buildCssGradientFromShapeStyle as e$, ViewerExportService as e0, ViewerExtraDialogsComponent as e1, ViewerFileIOService as e2, ViewerFindReplaceService as e3, ViewerFormatPainterService as e4, ViewerInspectorPanelService as e5, ViewerKeyboardService as e6, ViewerMobileSheetService as e7, ViewerPresentationModeService as e8, ViewerThemeGalleryService as e9, applyMove as eA, applyResize as eB, asMediaElement as eC, assignUserColor as eD, attachShowVisibilityPause as eE, attachTouchGestures as eF, axisTickValues as eG, beginDrawingNodeEdit as eH, beginNodeEdit as eI, bevelSizePatch as eJ, boolFromEvent as eK, bringForward as eL, bringToFront as eM, buildBarActions as eN, buildBroadcastConfig as eO, buildBroadcastViewerUrl as eP, buildCategoryLabels as eQ, buildCellParagraphs as eR, buildChartViewModel as eS, buildChatLogExport as eT, buildChatLogMarkdown as eU, buildChromeStyle as eV, buildClearHyperlinkPatch as eW, buildClickGroups as eX, buildColStyles as eY, buildCollaborationConfig as eZ, buildComboViewModel as e_, ViewerTouchGesturesService as ea, ViewerZoomService as eb, WEBM_MIME_CANDIDATES as ec, WHEEL_SPOKE_COUNTS as ed, WriteBackScheduler as ee, ZERO_LINE_COLOR as ef, ZoomNavigationService as eg, ZoomRendererComponent as eh, ZoomTargetService as ei, addCategory as ej, addCommentToList as ek, addGradientStopPatch as el, addItem as em, addSeries as en, addSubItem as eo, advanceStep as ep, affordanceElements as eq, aiToggleVisible as er, alignPatch as es, animationFor as et, animationPresetLabelKey as eu, annotationMapToInkInserts as ev, applyAcceptedDiff as ew, applyAnimationPreset as ex, applyFindReplacements as ey, applyFormatToElement as ez, buildBarChart3DHoverTooltip as f, clearAllLocalViewerData as f$, buildDuotoneFilter as f0, buildDuotoneFilterId as f1, buildEmbeddedFontStyles as f2, buildEquationElement as f3, buildEquationSegment as f4, buildFallbackViewModel as f5, buildFontFaceRule as f6, buildGradientFillCss as f7, buildGridlinesAndLabels as f8, buildHyperlinkPatch as f9, buildZoomContainerStyle as fA, buildZoomViewModel as fB, bulletIndentPx as fC, canAddTopLevelNode as fD, canEditSmartArtNodes as fE, canGroupSelection as fF, canRemoveTopLevelNode as fG, canSetStrokeWidth as fH, canStartBroadcast as fI, canStartShare as fJ, canUngroupSelection as fK, canUseClipboard as fL, captionDisplayText as fM, cellRunStyle as fN, cellStyleToStyleMap as fO, cellTdStyle as fP, changeCountLabel as fQ, changeIcon as fR, characterSpacingPatch as fS, chartPreserveAspectRatio as fT, checkFontAvailable as fU, clampCursorPosition as fV, clampGifDimensions as fW, clampIndex as fX, clampNotesFontSize as fY, clampScale as fZ, clampStep as f_, buildInkContainerStyle as fa, buildInkStrokes as fb, buildLegend as fc, buildLiveInkStrokeView as fd, buildMarkTooltip as fe, buildModel3DContainerStyle as ff, buildModel3DViewModel as fg, buildOleActionModel as fh, buildOleInfoRows as fi, buildPatternFillCss as fj, buildPieViewModel as fk, buildPrintHtmlDocument as fl, buildPropertiesPatch as fm, buildRadarViewModel as fn, buildRegionMapViewModel as fo, buildSaveSlides as fp, buildShareUrl as fq, buildSmartArtInsertElement as fr, buildSmartArtNodes as fs, buildStockViewModel as ft, buildSurfaceViewModel as fu, buildTableViewModel as fv, buildTreemapViewModel as fw, buildTrimFragment as fx, buildWaterfallViewModel as fy, buildZeroLine as fz, beginChartValueDrag as g, demoteNode as g$, clearAudienceContent as g0, cn as g1, collectAccessibilityIssues as g2, collectElementText as g3, collectSlideText as g4, collectStoredChats as g5, collectUsedFontFamilies as g6, columnWidthStyle as g7, commitNodeText as g8, computeAlign as g9, computeSelectionBoxes as gA, computeSingleSelected as gB, computeSlideIndices as gC, computeSnap as gD, computeStackedBarRects as gE, computeStackedValueRange as gF, computeTrendlinePrimitives as gG, computeValueRange as gH, convertOmmlToMathMl as gI, copyFormatFromElement as gJ, countAccessibilityIssues as gK, countAnnotationStrokes as gL, createAngularAiBridge as gM, createCustomShow as gN, createImageElementFromFile as gO, createSwipeDismissDrag as gP, createWebrtcBundle as gQ, createWebsocketBundle as gR, cssObjectToStyleMap as gS, currentColorScheme as gT, currentLayout as gU, currentStyle as gV, defaultCssVars as gW, defaultRadius as gX, defaultThemeColors as gY, deleteElementsByIds as gZ, deleteVersion as g_, computeAxisTitlePrimitives as ga, computeBarRects as gb, computeBubbleRadius as gc, computeCornerHandle as gd, computeDistribute as ge, computeDrawingViewBox as gf, computeErrorBarPrimitives as gg, computeFocusTargets as gh, computeGridSpacingPx as gi, computeHandleBoxes as gj, computeHandoutLayout as gk, computeIsMobile as gl, computeIsTablet as gm, computeLinePoints as gn, computeLinearRegression as go, computePageCount as gp, computePieLayout as gq, computePieSlicePath as gr, computePieSlices as gs, computePlotLayout as gt, computeRSquared as gu, computeRadarPoints as gv, computeResizeHandleBoxes as gw, computeRotateHandleBox as gx, computeScatterDots as gy, computeScatterXDomain as gz, createSurfaceChart3DScene as h, getP14TransitionAnimations as h$, deriveModel3DBlobUrl as h0, derivePresenceList as h1, describeCollaborationShellState as h2, describeSmartArtBounds as h3, disableGlowPatch as h4, disableInnerShadowPatch as h5, disableOuterShadowPatch as h6, disableReflectionPatch as h7, disableSoftEdgePatch as h8, duplicateElementById as h9, formatBytes as hA, formatCursorLabel as hB, formatElapsed as hC, formatFileSize as hD, formatInlineListStyle as hE, formatPropertyDate as hF, formatTime as hG, fpsToFrameIntervalMs as hH, generateBroadcastRoomId as hI, generateCommentId as hJ, generateCustomShowId as hK, generatePressureCircles as hL, generateTicks as hM, getCinematicTransitionAnimations as hN, getClrChangeParams as hO, getContainerStyle as hP, getDuotoneFilterDef as hQ, getEffectSoundAsset as hR, getEffectSoundState as hS, getImageSrc as hT, getLocalStorageUsageSummary as hU, getOleAriaLabel as hV, getOleBadgeLabel as hW, getOleDisplayName as hX, getOleDownloadFileName as hY, getOleTypeColor as hZ, getOleTypeLabel as h_, durationOf as ha, effectsStateOf as hb, enableGlowPatch as hc, enableInnerShadowPatch as hd, enableOuterShadowPatch as he, enableReflectionPatch as hf, enableSoftEdgePatch as hg, encodeGif as hh, endShowMediaCleanup as hi, estimatePageCount as hj, exitPresentationFullscreen as hk, exportAiChatLogs as hl, extractPathPoints as hm, eyedropperAvailable as hn, fillColorOf$1 as ho, findInSlides as hp, findOwningSlideIndex as hq, findSlideIndexByElementId as hr, firstVisibleIndex as hs, fitPolynomial as ht, fitZoom as hu, focusTargetChips as hv, fontMimeForFormat as hw, fontSizeOf as hx, forgetSessionDeck as hy, formatAxisValue as hz, isChartInteractionArmed as i, layoutNodeLabels as i$, getPasswordStrength as i0, getPatternSvg as i1, getPlaceholderStyle as i2, getVersions as i3, getResolvedShapeClipPath as i4, getResolvedShapeClipPathFor as i5, getSessionTabId as i6, getShapeFillStrokeStyle as i7, getSlideBackgroundStyle as i8, getSlideTransitionAnimations as i9, insertTableElementRow as iA, interpolateWidth as iB, isAudienceTab as iC, isBold as iD, isBrowserOpenableMime as iE, isChildNode as iF, isElementInteractive as iG, isInjectableUrl as iH, isItalic as iI, isLegacyBinaryPresentation as iJ, isPpactionUrl as iK, isPresenterMessage as iL, isSigned as iM, isSupportedPresentationFile as iN, isTextElement as iO, isTwoTableFocus as iP, isUnderline as iQ, isUrlSafe as iR, isValidRoomId as iS, isViewportBackgroundPressTarget as iT, isZoomActivationKey as iU, issueTrackKey as iV, issueTypeLabel as iW, keyToLabel as iX, lastVisibleIndex as iY, latexToMathml as iZ, layoutConnectorPaints as i_, getSmartArtNodeBounds as ia, getSpeechRecognitionCtor as ib, getTextBlockStyle as ic, getTextWarp as id, getTouchDistance as ie, getWarpCategory as ig, getWarpPath as ih, gradientStateFromStyle as ii, gradientStateOf as ij, gradientStatePatch as ik, gradientStopColorCommitPatch as il, gridColumns as im, groupIssuesBySeverity as io, hasAnimation as ip, hasCopyableFormat as iq, hasExistingLink as ir, hasExitedFullscreen as is, hasGradientFill as it, hasPressureVariation as iu, hasVisibleSlideAfter as iv, headerLabel as iw, imageDimensions as ix, inkViewBox as iy, insertTableElementColumn as iz, createPieChart3DScene as j, presetsForCategory as j$, linePointsToSvgString as j0, lineSpacingPatch as j1, loadAudienceContent as j2, loadSessionDeck as j3, mediaFallbackFor as j4, mediaSurfaceFor as j5, mergeCaptionResults as j6, mergeDown as j7, mergeRight as j8, mergeSelection as j9, numFromEvent as jA, ommlToMathml as jB, ooxmlDashToCssBorderStyle as jC, openNativeEyeDropper as jD, overallStatus as jE, paletteColor as jF, parseAudienceNonce as jG, parseNodeTextarea as jH, partitionSlides as jI, patchChartData as jJ, patchChartStyle as jK, patchTableData as jL, patchTextStyle as jM, patternPresetOptions as jN, pendingElementStyles as jO, pickColorByClickFallback as jP, pickFile as jQ, pickSupportedMimeType as jR, planGifFrames as jS, planVideoSegments as jT, pointFromPointerEvent as jU, pointsToSvgPathD as jV, presenceToCursors as jW, presentationBaseName as jX, presentationStageStyle as jY, presenterTimerProgress as jZ, presetByLayout as j_, mergeTablesDirective as ja, moveElementBy as jb, moveNodeDown as jc, moveNodeUp as jd, msToFrameDelayCs as je, narrowToCircle as jf, narrowToPolygon as jg, narrowToRect as jh, newChartElement as ji, newEquationElement as jj, newPresetShapeElement as jk, newShapeElement as jl, newSmartArtElement as jm, newTableElement as jn, newTextElement as jo, nextVisibleIndex as jp, nodeBold as jq, nodeEditBox as jr, nodeFillColor as js, nodeFontColor as jt, nodeIdFromKey as ju, nodeItalic as jv, nodeStyle as jw, normalizeFontFormat as jx, normalizeSlidesPerPage as jy, normalizeValue as jz, createAreaChart3DScene as k, searchSlides as k$, pressuresToWidths as k0, prevVisibleIndex as k1, projectDrawingShapes as k2, promoteNode as k3, provideViewerTheme as k4, radarAngle as k5, radarRingPoints as k6, readAsDataUrl as k7, recordWebm as k8, registerCrossSlideAudio as k9, resolveOrientation as kA, resolveParagraphBullet as kB, resolvePresenterNotes as kC, resolveProfileInitial as kD, resolveRegionCode as kE, resolveRibbonCanGroup as kF, resolveSlideAutoAdvanceMs as kG, resolveSlideTransition as kH, resolvePalette as kI, resolveThemeCatalogEntry as kJ, resolveTransitionDuration as kK, resolveTransitionDurationMs as kL, resolveWheelSpokeCount as kM, restoreSessionDeck as kN, revealedElementStyles as kO, routeOrthogonalConnector as kP, rowStyle as kQ, rulerDragToGuidePosition as kR, rulerHighlight as kS, rulerStripTicks as kT, sampleColorFromSlide as kU, sanitizeColor as kV, sanitizeSlideIndex as kW, sanitizeUserName as kX, saveViewerProfile as kY, savedPresentationFileName as kZ, scanAvailableFonts as k_, rememberSessionDeck as ka, removeAnimation as kb, removeCategory as kc, removeTableElementColumn as kd, removeCommentFromList as ke, removeElementAnimation as kf, removeGradientStopPatch as kg, removeNode as kh, removeTableElementRow as ki, removeSeries as kj, renderToCanvas as kk, reorderAnimationDown as kl, reorderAnimationUp as km, replaceInSlides as kn, replaceMatch as ko, requestPresentationFullscreen as kp, resizeElement as kq, resolveCaptionTracks as kr, resolveChartKind as ks, resolveDirection as kt, resolveDirection8 as ku, resolveFontVariant as kv, resolveHyperlinkHref as kw, resolveInteractiveElementId as kx, resolveMediaSrc as ky, resolveOleType as kz, createLineChart3DScene as l, signerName as l$, seedBroadcastFields as l0, seedHyperlinkDraft as l1, seedPropertiesDraft as l2, seedShareFields as l3, segmentFrameCount as l4, selectValue$3 as l5, sendBackward as l6, sendToBack as l7, sequentialColorScale as l8, serializeWriteBack as l9, setLegend as lA, setNodeStyle as lB, setNodeText as lC, setRepeatCount as lD, setRepeatMode as lE, setSequence as lF, setSeriesChartType as lG, setSeriesColor as lH, setSeriesErrorBars as lI, setSeriesMarker as lJ, setSeriesName as lK, setSeriesTrendline as lL, setSeriesValue as lM, setStyle as lN, setTimingCurve as lO, setTitle as lP, setTrigger as lQ, setTriggerShapeId as lR, shapeStylePatch$1 as lS, sheetAfterNavigate as lT, shouldBlockClickAdvance as lU, shouldUseSvgWarp as lV, showDirectionPicker as lW, showsTemplateAffordance as lX, signatureCountLabel as lY, signatureKey as lZ, signatureTimestamp as l_, seriesColor as la, seriesXValues as lb, setAfterAnimation as lc, setAfterAnimationColor as ld, setAnimationEmphasis as le, setAnimationEntrance as lf, setAnimationExit as lg, setAxis as lh, setAxisLogScale as li, setAxisTitleStyle as lj, setCategoryLabel as lk, setCellText as ll, setColorScheme as lm, setDataLabels as ln, setDataPointExplosion as lo, setDataPointFill as lp, setDataPointLabel as lq, setDataPointMarker as lr, setDelay as ls, setDirection as lt, setDuration as lu, setEffectSound as lv, setEffectStockSound as lw, setElementPosition as lx, setGridlineStyle as ly, setLayout as lz, createBarChart3DScene as m, statusLabel as m0, slideNumberOf as m1, slidesWithReappliedLayout as m2, smartArtNodes as m3, paletteColour as m4, snapToGridStep as m5, splitCursorCell as m6, splitMergedCell as m7, statusKind as m8, statusLabel$1 as m9, updateElementById as mA, updateGlowPatch as mB, updateGradientStopPatch as mC, updateInnerShadowPatch as mD, updateOuterShadowPatch as mE, updateReflectionPatch as mF, vAlignPatch as mG, validatePassword as mH, validatePrintSettings as mI, validateRoomId as mJ, valueToY as mK, vermilionDarkColors as mL, vermilionDarkTheme as mM, vermilionLightColors as mN, vermilionLightTheme as mO, vermilionRadius as mP, waypointsToPathD as mQ, withManualLayouts as mR, worstStatus as mS, zoomTargetSlideIndex as mT, storeAudienceContent as ma, stringFromEvent$5 as mb, strokeColorOf as mc, strokeToInkElement as md, strokeWidthOf as me, styleShadowFilter as mf, surfaceColor as mg, textAdvancedPatch as mh, textAdvancedStateFromStyle as mi, textAdvancedStateOf as mj, textColorOf as mk, textDirectionPatch as ml, textFontSizePatch as mm, textStyleOf as mn, textStylePatch as mo, themeStyle as mp, themeToCssVars as mq, thumbnailHeight as mr, thumbnailZoom as ms, toggleCommentResolvedInList as mt, toggleNodeBold as mu, toggleNodeItalic as mv, toggleSheet as mw, topLevelNodeCount as mx, transformSelectedTextCase as my, translationsEn as mz, ALIGN_OPTIONS as n, ANIMATION_PRESET_CATEGORIES as o, AUDIENCE_HASH as p, AUDIENCE_NONCE_KEY as q, renderChartLineSvg as r, shade as s, toChatSummary as t, AVATAR_COLOR_SWATCHES as u, AXIS_LABEL_COLOR as v, AccessibilityPanelComponent as w, AccessibilityService as x, AccessibilityTextPanelComponent as y, AccountPageComponent as z };
193856
- //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-Dom_SGx5.mjs.map
195367
+ export { ChartAxisOptionsComponent as $, AFTER_ANIMATION_VALUES as A, ActionSettingsPanelComponent as B, CHART_3D_DRAG_THRESHOLD_PX as C, AdvancedChartEditorComponent as D, AiChangeOverlayComponent as E, AiChatPanelComponent as F, AiChatService as G, AiComposerComponent as H, AiFocusBarComponent as I, AiFocusHighlightOverlayComponent as J, AiHistoryMenuComponent as K, AiHistoryService as L, AiMessageListComponent as M, AiPanelStore as N, AiProposalCardComponent as O, AiSettingsSectionComponent as P, AiToolCallCardComponent as Q, AnimationAuthorPanelComponent as R, AnimationPanelComponent as S, AnimationPlaybackService as T, AutosaveRecoveryDialogComponent as U, AutosaveService as V, BroadcastDialogComponent as W, CHART_EDITOR_STYLES as X, CINEMATIC_TRANSITION_KEYFRAMES as Y, CURSOR_PALETTE as Z, CanvasFitService as _, renderChartTextSvg as a, ExportProgressModalComponent as a$, ChartAxisStyleOptionsComponent as a0, ChartComboTypeOptionsComponent as a1, ChartDataEditorComponent as a2, ChartDataLabelOptionsComponent as a3, ChartDatapointMarkerOptionsComponent as a4, ChartDatapointOptionsComponent as a5, ChartDisplayOptionsComponent as a6, ChartElementViewComponent as a7, ChartErrorBarOptionsComponent as a8, ChartMarkerOptionsComponent as a9, DEFAULT_SLIDE_BACKGROUND as aA, DEFAULT_STROKE_COLOR as aB, DEFAULT_STYLE as aC, DEFAULT_TABLE_ROW_HEIGHT as aD, DEFAULT_TEXT_COLOR$2 as aE, DEFAULT_VIEWER_PROFILE as aF, DIRECTIONAL_PRESETS as aG, DIRECTION_OPTIONS as aH, DocumentPropertiesCardComponent as aI, EASE as aJ, EFFECT_SOUND_CATALOGUE as aK, EMBEDDED_FONTS_STYLE_ID as aL, EMPHASIS_PRESETS as aM, ENTRANCE_PRESETS as aN, TEMPLATES as aO, EXIT_PRESETS as aP, EditorContextMenuComponent as aQ, EditorHistory as aR, EditorStateService as aS, EditorToolbarComponent as aT, EffectsPanelComponent as aU, ElementRendererComponent as aV, EmbeddedFontsService as aW, EncryptedFileDialogComponent as aX, EquationEditorDialogComponent as aY, EquationRendererComponent as aZ, EquationTemplateGalleryComponent as a_, ChartPartSelectionService as aa, ChartPrimitivesComponent as ab, ChartRendererComponent as ac, ChartTrendlineOptionsComponent as ad, ChartTypeSelectorComponent as ae, CollaborationCursorsComponent as af, CollaborationService as ag, ColorChangedImageComponent as ah, CommentMarkersOverlayComponent as ai, CommentsPanelComponent as aj, CommentsService as ak, ComparePanelComponent as al, ConnectorRendererComponent as am, ConnectorTextOverlayComponent as an, CustomShowsComponent as ao, DEFAULT_BOUNDS as ap, DEFAULT_BROADCAST_SERVER_URL as aq, DEFAULT_CANVAS_HEIGHT as ar, DEFAULT_CANVAS_WIDTH as as, DEFAULT_COLOR_SCHEME as at, DEFAULT_FILL_COLOR$1 as au, DEFAULT_LAYOUT as av, DEFAULT_MORPH_DURATION_MS as aw, DEFAULT_PALETTE$1 as ax, DEFAULT_PATTERN_FILL_PRESET as ay, DEFAULT_PRINT_SETTINGS as az, appendChartLegendSvg as b, PresentToolbarAutoHide as b$, ExportService as b0, FieldContextService as b1, FindBarComponent as b2, FindReplaceBarComponent as b3, FollowModeBarComponent as b4, FontEmbeddingListComponent as b5, FontEmbeddingPanelComponent as b6, GALLERY_THEME_PRESETS as b7, GOOGLE_WEBFONTS_LINK_ID as b8, GRIDLINE_COLOR$1 as b9, MobileBottomBarComponent as bA, MobileMenuSheetComponent as bB, MobilePresenterViewComponent as bC, MobileSheetComponent as bD, MobileSlidesSheetComponent as bE, MobileToolbarComponent as bF, ModalDialogComponent as bG, Model3DRendererComponent as bH, NotesHandoutCardComponent as bI, NotesPanelComponent as bJ, NotesToolbarComponent as bK, OleRendererComponent as bL, OutlineViewOverlayComponent as bM, P14_TRANSITION_KEYFRAMES as bN, P14_TRANSITION_KEYFRAMES_2 as bO, P14_TRANSITION_KEYFRAMES_ALL as bP, POWER_POINT_VIEWER_PROVIDERS as bQ, PPTX_OPEN_ACCEPT as bR, PRESENTATION_OPEN_EXTENSIONS as bS, PRESENTER_CHANNEL_NAME as bT, PRESENTER_MSG_ORIGIN as bU, PRESENTER_TIMER_SEGMENT_MS as bV, PX_PER_CM as bW, PX_PER_INCH as bX, PasswordProtectionDialogComponent as bY, PasswordStrengthMeterComponent as bZ, PowerPointViewerComponent as b_, GoogleWebfontsService as ba, GradientPickerComponent as bb, HANDOUT_OPTIONS as bc, HeaderFooterDialogComponent as bd, HyperlinkDialogComponent as be, INSTANT as bf, ImagePropertiesPanelComponent as bg, InkDrawingService as bh, InkRendererComponent as bi, InsertSmartArtDialogComponent as bj, InspectorPaneHeaderComponent as bk, InspectorPanelComponent as bl, IsMobileService as bm, KeepAnnotationsDialogComponent as bn, LOCALE_CATALOG as bo, LONG_PRESS_DURATION_MS as bp, LONG_PRESS_MOVE_TOLERANCE_PX as bq, LoadContentService as br, LocalPresencePublisher as bs, MAX_ZOOM_SCALE as bt, MIN_ZOOM_SCALE as bu, MOTION_PATH_COLUMNS as bv, MediaPreviewComponent as bw, MediaPropertiesPanelComponent as bx, MediaRendererComponent as by, MediaTrimTimelineComponent as bz, createSvgEl as c, SettingsAppearanceTabComponent as c$, PresentationAnnotationOverlayComponent as c0, PresentationAnnotationsService as c1, PresentationOverlayComponent as c2, PresentationPropertiesPanelComponent as c3, PresentationSettingsCardComponent as c4, PresentationSubtitleBarComponent as c5, PresentationToolbarComponent as c6, PresentationTransitionOverlayComponent as c7, PresenterViewComponent as c8, PresenterWindowService as c9, RibbonInsertSectionComponent as cA, RibbonMotionPathGalleryComponent as cB, RibbonParagraphControlsComponent as cC, RibbonPrimaryRowComponent as cD, RibbonReviewSectionComponent as cE, RibbonShapeExtrasComponent as cF, RibbonSlideshowSectionComponent as cG, RibbonTransitionsSectionComponent as cH, RibbonViewSectionComponent as cI, RulerGuidesService as cJ, SEQUENCE_OPTIONS as cK, SEVERITY_GROUPS as cL, SEVERITY_LABELS as cM, DEFAULT_TRANSITION_DURATION_MS$1 as cN, SHORTCUT_REFERENCE_ITEMS as cO, SLIDE_TRANSITION_KEYFRAMES as cP, SLIDE_TRANSITION_KEYFRAMES_CSS as cQ, DEFAULT_PALETTE as cR, PALETTES as cS, SMART_ART_COLOR_SCHEMES as cT, SMART_ART_STYLE_OPTIONS as cU, SUB_ITEM_LABEL as cV, SVG_WARP_PRESETS as cW, SWIPE_MAX_VERTICAL_PX as cX, SWIPE_THRESHOLD_PX as cY, SelectionPaneComponent as cZ, SetUpSlideShowDialogComponent as c_, PrintDialogComponent as ca, PrintService as cb, PrintSettingsPanelComponent as cc, PropertiesDialogComponent as cd, RANDOM_ELIGIBLE_TYPES as ce, REPEAT_MODE_OPTIONS as cf, RESIZE_HANDLES as cg, RULER_FONT_SIZE as ch, RULER_THICKNESS as ci, ReadingViewOverlayComponent as cj, RemoteSelectionOverlayComponent as ck, Rendering3DService as cl, RibbonAnimationGalleryComponent as cm, RibbonAnimationsSectionComponent as cn, RibbonArrangeSectionComponent as co, RibbonColorPopoverComponent as cp, RibbonComponent as cq, RibbonDesignSectionComponent as cr, RibbonDrawSectionComponent as cs, RibbonDrawingGroupComponent as ct, RibbonEditingSectionComponent as cu, RibbonFileSectionComponent as cv, RibbonFontControlsComponent as cw, RibbonHomeSectionComponent as cx, RibbonHyperlinkButtonComponent as cy, RibbonInsertFieldsComponent as cz, dragAnchorViewY as d, ViewerDocumentPropertiesService as d$, SettingsDialogComponent as d0, SettingsLanguageTabComponent as d1, ShareDialogComponent as d2, ShortcutPanelComponent as d3, ShowOptionsFieldsetComponent as d4, ShowSlidesFieldsetComponent as d5, SignatureStrippedDialogComponent as d6, SignaturesPanelComponent as d7, SignaturesService as d8, SlideBackgroundCardComponent as d9, TableCellFormattingComponent as dA, TableDataEditorComponent as dB, TablePropertiesComponent as dC, TableRendererComponent as dD, TableResizeOverlayComponent as dE, TableSelectionService as dF, TagsCardComponent as dG, Text3DBevelSectionComponent as dH, Text3DPanelComponent as dI, TextAdvancedPanelComponent as dJ, ThemeEditorFieldsComponent as dK, ThemeGalleryComponent as dL, ThemeSelectorCardComponent as dM, TitleBarComponent as dN, TitleBarSearchComponent as dO, TransitionDirectionPickerComponent as dP, TransitionPreviewComponent as dQ, VALIGN_OPTIONS as dR, VIEWER_THEME as dS, VersionHistoryPanelComponent as dT, ViewerCanvasEditingService as dU, ViewerCollabCursorService as dV, ViewerCollaborationSessionService as dW, ViewerCollaborationShellService as dX, ViewerCompareService as dY, ViewerCustomShowsService as dZ, ViewerDialogsService as d_, SlideCanvasComponent as da, SlideDefaultInspectorComponent as db, SlideDiffChangesComponent as dc, SlideDiffRowComponent as dd, SlideDiffThumbnailsComponent as de, SlideSizeCardComponent as df, SlideSorterOverlayComponent as dg, SlideThemeOverridePanelComponent as dh, SlideTransitionCardComponent as di, SlidesPanelComponent as dj, SmartArt3DRendererComponent as dk, SmartArtPreviewComponent as dl, SmartArtPropertiesComponent as dm, SmartArtRendererComponent as dn, StatusBarComponent as dp, TABLE_STRUCTURE_TOGGLES as dq, TEXT_3D_BOTTOM_BEVEL_KEYS as dr, TEXT_3D_TOP_BEVEL_KEYS as ds, TEXT_DIRECTION_OPTIONS$1 as dt, THEME_CATALOG as du, TIMING_CURVE_OPTIONS as dv, TRANSITION_SPEED_DURATION_MS as dw, TRIGGER_OPTIONS as dx, TYPE_LABELS as dy, TableCellAdvancedFillComponent as dz, advanceChartValueDrag as e, buildCssGradientFromShapeStyle as e$, ViewerExportService as e0, ViewerExtraDialogsComponent as e1, ViewerFileIOService as e2, ViewerFindReplaceService as e3, ViewerFormatPainterService as e4, ViewerInspectorPanelService as e5, ViewerKeyboardService as e6, ViewerMobileSheetService as e7, ViewerPresentationModeService as e8, ViewerThemeGalleryService as e9, applyMove as eA, applyResize as eB, asMediaElement as eC, assignUserColor as eD, attachShowVisibilityPause as eE, attachTouchGestures as eF, axisTickValues as eG, beginDrawingNodeEdit as eH, beginNodeEdit as eI, bevelSizePatch as eJ, boolFromEvent as eK, bringForward as eL, bringToFront as eM, buildBarActions as eN, buildBroadcastConfig as eO, buildBroadcastViewerUrl as eP, buildCategoryLabels as eQ, buildCellParagraphs as eR, buildChartViewModel as eS, buildChatLogExport as eT, buildChatLogMarkdown as eU, buildChromeStyle as eV, buildClearHyperlinkPatch as eW, buildClickGroups as eX, buildColStyles as eY, buildCollaborationConfig as eZ, buildComboViewModel as e_, ViewerTouchGesturesService as ea, ViewerZoomService as eb, WEBM_MIME_CANDIDATES as ec, WHEEL_SPOKE_COUNTS as ed, WriteBackScheduler as ee, ZERO_LINE_COLOR as ef, ZoomNavigationService as eg, ZoomRendererComponent as eh, ZoomTargetService as ei, addCategory as ej, addCommentToList as ek, addGradientStopPatch as el, addItem as em, addSeries as en, addSubItem as eo, advanceStep as ep, affordanceElements as eq, aiToggleVisible as er, alignPatch as es, animationFor as et, animationPresetLabelKey as eu, annotationMapToInkInserts as ev, applyAcceptedDiff as ew, applyAnimationPreset as ex, applyFindReplacements as ey, applyFormatToElement as ez, buildBarChart3DHoverTooltip as f, clearAllLocalViewerData as f$, buildDuotoneFilter as f0, buildDuotoneFilterId as f1, buildEmbeddedFontStyles as f2, buildEquationElement as f3, buildEquationSegment as f4, buildFallbackViewModel as f5, buildFontFaceRule as f6, buildGradientFillCss as f7, buildGridlinesAndLabels as f8, buildHyperlinkPatch as f9, buildZoomContainerStyle as fA, buildZoomViewModel as fB, bulletIndentPx as fC, canAddTopLevelNode as fD, canEditSmartArtNodes as fE, canGroupSelection as fF, canRemoveTopLevelNode as fG, canSetStrokeWidth as fH, canStartBroadcast as fI, canStartShare as fJ, canUngroupSelection as fK, canUseClipboard as fL, captionDisplayText as fM, cellRunStyle as fN, cellStyleToStyleMap as fO, cellTdStyle as fP, changeCountLabel as fQ, changeIcon as fR, characterSpacingPatch as fS, chartPreserveAspectRatio as fT, checkFontAvailable as fU, clampCursorPosition as fV, clampGifDimensions as fW, clampIndex as fX, clampNotesFontSize as fY, clampScale as fZ, clampStep as f_, buildInkContainerStyle as fa, buildInkStrokes as fb, buildLegend as fc, buildLiveInkStrokeView as fd, buildMarkTooltip as fe, buildModel3DContainerStyle as ff, buildModel3DViewModel as fg, buildOleActionModel as fh, buildOleInfoRows as fi, buildPatternFillCss as fj, buildPieViewModel as fk, buildPrintHtmlDocument as fl, buildPropertiesPatch as fm, buildRadarViewModel as fn, buildRegionMapViewModel as fo, buildSaveSlides as fp, buildShareUrl as fq, buildSmartArtInsertElement as fr, buildSmartArtNodes as fs, buildStockViewModel as ft, buildSurfaceViewModel as fu, buildTableViewModel as fv, buildTreemapViewModel as fw, buildTrimFragment as fx, buildWaterfallViewModel as fy, buildZeroLine as fz, beginChartValueDrag as g, demoteNode as g$, clearAudienceContent as g0, cn as g1, collectAccessibilityIssues as g2, collectElementText as g3, collectSlideText as g4, collectStoredChats as g5, collectUsedFontFamilies as g6, columnWidthStyle as g7, commitNodeText as g8, computeAlign as g9, computeSelectionBoxes as gA, computeSingleSelected as gB, computeSlideIndices as gC, computeSnap as gD, computeStackedBarRects as gE, computeStackedValueRange as gF, computeTrendlinePrimitives as gG, computeValueRange as gH, convertOmmlToMathMl as gI, copyFormatFromElement as gJ, countAccessibilityIssues as gK, countAnnotationStrokes as gL, createAngularAiBridge as gM, createCustomShow as gN, createImageElementFromFile as gO, createSwipeDismissDrag as gP, createWebrtcBundle as gQ, createWebsocketBundle as gR, cssObjectToStyleMap as gS, currentColorScheme as gT, currentLayout as gU, currentStyle as gV, defaultCssVars as gW, defaultRadius as gX, defaultThemeColors as gY, deleteElementsByIds as gZ, deleteVersion as g_, computeAxisTitlePrimitives as ga, computeBarRects as gb, computeBubbleRadius as gc, computeCornerHandle as gd, computeDistribute as ge, computeDrawingViewBox as gf, computeErrorBarPrimitives as gg, computeFocusTargets as gh, computeGridSpacingPx as gi, computeHandleBoxes as gj, computeHandoutLayout as gk, computeIsMobile as gl, computeIsTablet as gm, computeLinePoints as gn, computeLinearRegression as go, computePageCount as gp, computePieLayout as gq, computePieSlicePath as gr, computePieSlices as gs, computePlotLayout as gt, computeRSquared as gu, computeRadarPoints as gv, computeResizeHandleBoxes as gw, computeRotateHandleBox as gx, computeScatterDots as gy, computeScatterXDomain as gz, createSurfaceChart3DScene as h, getP14TransitionAnimations as h$, deriveModel3DBlobUrl as h0, derivePresenceList as h1, describeCollaborationShellState as h2, describeSmartArtBounds as h3, disableGlowPatch as h4, disableInnerShadowPatch as h5, disableOuterShadowPatch as h6, disableReflectionPatch as h7, disableSoftEdgePatch as h8, duplicateElementById as h9, formatBytes as hA, formatCursorLabel as hB, formatElapsed as hC, formatFileSize as hD, formatInlineListStyle as hE, formatPropertyDate as hF, formatTime as hG, fpsToFrameIntervalMs as hH, generateBroadcastRoomId as hI, generateCommentId as hJ, generateCustomShowId as hK, generatePressureCircles as hL, generateTicks as hM, getCinematicTransitionAnimations as hN, getClrChangeParams as hO, getContainerStyle as hP, getDuotoneFilterDef as hQ, getEffectSoundAsset as hR, getEffectSoundState as hS, getImageSrc as hT, getLocalStorageUsageSummary as hU, getOleAriaLabel as hV, getOleBadgeLabel as hW, getOleDisplayName as hX, getOleDownloadFileName as hY, getOleTypeColor as hZ, getOleTypeLabel as h_, durationOf as ha, effectsStateOf as hb, enableGlowPatch as hc, enableInnerShadowPatch as hd, enableOuterShadowPatch as he, enableReflectionPatch as hf, enableSoftEdgePatch as hg, encodeGif as hh, endShowMediaCleanup as hi, estimatePageCount as hj, exitPresentationFullscreen as hk, exportAiChatLogs as hl, extractPathPoints as hm, eyedropperAvailable as hn, fillColorOf$1 as ho, findInSlides as hp, findOwningSlideIndex as hq, findSlideIndexByElementId as hr, firstVisibleIndex as hs, fitPolynomial as ht, fitZoom as hu, focusTargetChips as hv, fontMimeForFormat as hw, fontSizeOf as hx, forgetSessionDeck as hy, formatAxisValue as hz, isChartInteractionArmed as i, layoutNodeLabels as i$, getPasswordStrength as i0, getPatternSvg as i1, getPlaceholderStyle as i2, getVersions as i3, getResolvedShapeClipPath as i4, getResolvedShapeClipPathFor as i5, getSessionTabId as i6, getShapeFillStrokeStyle as i7, getSlideBackgroundStyle as i8, getSlideTransitionAnimations as i9, insertTableElementRow as iA, interpolateWidth as iB, isAudienceTab as iC, isBold as iD, isBrowserOpenableMime as iE, isChildNode as iF, isElementInteractive as iG, isInjectableUrl as iH, isItalic as iI, isLegacyBinaryPresentation as iJ, isPpactionUrl as iK, isPresenterMessage as iL, isSigned as iM, isSupportedPresentationFile as iN, isTextElement as iO, isTwoTableFocus as iP, isUnderline as iQ, isUrlSafe as iR, isValidRoomId as iS, isViewportBackgroundPressTarget as iT, isZoomActivationKey as iU, issueTrackKey as iV, issueTypeLabel as iW, keyToLabel as iX, lastVisibleIndex as iY, latexToMathml as iZ, layoutConnectorPaints as i_, getSmartArtNodeBounds as ia, getSpeechRecognitionCtor as ib, getTextBlockStyle as ic, getTextWarp as id, getTouchDistance as ie, getWarpCategory as ig, getWarpPath as ih, gradientStateFromStyle as ii, gradientStateOf as ij, gradientStatePatch as ik, gradientStopColorCommitPatch as il, gridColumns as im, groupIssuesBySeverity as io, hasAnimation as ip, hasCopyableFormat as iq, hasExistingLink as ir, hasExitedFullscreen as is, hasGradientFill as it, hasPressureVariation as iu, hasVisibleSlideAfter as iv, headerLabel as iw, imageDimensions as ix, inkViewBox as iy, insertTableElementColumn as iz, createPieChart3DScene as j, presetByLayout as j$, linePointsToSvgString as j0, lineSpacingPatch as j1, loadAudienceContent as j2, loadSessionDeck as j3, mediaFallbackFor as j4, mediaSurfaceFor as j5, mergeCaptionResults as j6, mergeDown as j7, mergeRight as j8, mergeSelection as j9, numFromEvent as jA, oleActionsVisibleFor as jB, ommlToMathml as jC, ooxmlDashToCssBorderStyle as jD, openNativeEyeDropper as jE, overallStatus as jF, paletteColor as jG, parseAudienceNonce as jH, parseNodeTextarea as jI, partitionSlides as jJ, patchChartData as jK, patchChartStyle as jL, patchTableData as jM, patchTextStyle as jN, patternPresetOptions as jO, pendingElementStyles as jP, pickColorByClickFallback as jQ, pickFile as jR, pickSupportedMimeType as jS, planGifFrames as jT, planVideoSegments as jU, pointFromPointerEvent as jV, pointsToSvgPathD as jW, presenceToCursors as jX, presentationBaseName as jY, presentationStageStyle as jZ, presenterTimerProgress as j_, mergeTablesDirective as ja, moveElementBy as jb, moveNodeDown as jc, moveNodeUp as jd, msToFrameDelayCs as je, narrowToCircle as jf, narrowToPolygon as jg, narrowToRect as jh, newChartElement as ji, newEquationElement as jj, newPresetShapeElement as jk, newShapeElement as jl, newSmartArtElement as jm, newTableElement as jn, newTextElement as jo, nextVisibleIndex as jp, nodeBold as jq, nodeEditBox as jr, nodeFillColor as js, nodeFontColor as jt, nodeIdFromKey as ju, nodeItalic as jv, nodeStyle as jw, normalizeFontFormat as jx, normalizeSlidesPerPage as jy, normalizeValue as jz, createAreaChart3DScene as k, scanAvailableFonts as k$, presetsForCategory as k0, pressuresToWidths as k1, prevVisibleIndex as k2, projectDrawingShapes as k3, promoteNode as k4, provideViewerTheme as k5, radarAngle as k6, radarRingPoints as k7, readAsDataUrl as k8, recordWebm as k9, resolveOleType as kA, resolveOrientation as kB, resolveParagraphBullet as kC, resolvePresenterNotes as kD, resolveProfileInitial as kE, resolveRegionCode as kF, resolveRibbonCanGroup as kG, resolveSlideAutoAdvanceMs as kH, resolveSlideTransition as kI, resolvePalette as kJ, resolveThemeCatalogEntry as kK, resolveTransitionDuration as kL, resolveTransitionDurationMs as kM, resolveWheelSpokeCount as kN, restoreSessionDeck as kO, revealedElementStyles as kP, routeOrthogonalConnector as kQ, rowStyle as kR, rulerDragToGuidePosition as kS, rulerHighlight as kT, rulerStripTicks as kU, sampleColorFromSlide as kV, sanitizeColor as kW, sanitizeSlideIndex as kX, sanitizeUserName as kY, saveViewerProfile as kZ, savedPresentationFileName as k_, registerCrossSlideAudio as ka, rememberSessionDeck as kb, removeAnimation as kc, removeCategory as kd, removeTableElementColumn as ke, removeCommentFromList as kf, removeElementAnimation as kg, removeGradientStopPatch as kh, removeNode as ki, removeTableElementRow as kj, removeSeries as kk, renderToCanvas as kl, reorderAnimationDown as km, reorderAnimationUp as kn, replaceInSlides as ko, replaceMatch as kp, requestPresentationFullscreen as kq, resizeElement as kr, resolveCaptionTracks as ks, resolveChartKind as kt, resolveDirection as ku, resolveDirection8 as kv, resolveFontVariant as kw, resolveHyperlinkHref as kx, resolveInteractiveElementId as ky, resolveMediaSrc as kz, createLineChart3DScene as l, signatureTimestamp as l$, searchSlides as l0, seedBroadcastFields as l1, seedHyperlinkDraft as l2, seedPropertiesDraft as l3, seedShareFields as l4, segmentFrameCount as l5, selectValue$3 as l6, sendBackward as l7, sendToBack as l8, sequentialColorScale as l9, setLayout as lA, setLegend as lB, setNodeStyle as lC, setNodeText as lD, setRepeatCount as lE, setRepeatMode as lF, setSequence as lG, setSeriesChartType as lH, setSeriesColor as lI, setSeriesErrorBars as lJ, setSeriesMarker as lK, setSeriesName as lL, setSeriesTrendline as lM, setSeriesValue as lN, setStyle as lO, setTimingCurve as lP, setTitle as lQ, setTrigger as lR, setTriggerShapeId as lS, shapeStylePatch$1 as lT, sheetAfterNavigate as lU, shouldBlockClickAdvance as lV, shouldUseSvgWarp as lW, showDirectionPicker as lX, showsTemplateAffordance as lY, signatureCountLabel as lZ, signatureKey as l_, serializeWriteBack as la, seriesColor as lb, seriesXValues as lc, setAfterAnimation as ld, setAfterAnimationColor as le, setAnimationEmphasis as lf, setAnimationEntrance as lg, setAnimationExit as lh, setAxis as li, setAxisLogScale as lj, setAxisTitleStyle as lk, setCategoryLabel as ll, setCellText as lm, setColorScheme as ln, setDataLabels as lo, setDataPointExplosion as lp, setDataPointFill as lq, setDataPointLabel as lr, setDataPointMarker as ls, setDelay as lt, setDirection as lu, setDuration as lv, setEffectSound as lw, setEffectStockSound as lx, setElementPosition as ly, setGridlineStyle as lz, createBarChart3DScene as m, signerName as m0, statusLabel as m1, slideNumberOf as m2, slidesWithReappliedLayout as m3, smartArtNodes as m4, paletteColour as m5, snapToGridStep as m6, splitCursorCell as m7, splitMergedCell as m8, statusKind as m9, translationsEn as mA, updateElementById as mB, updateGlowPatch as mC, updateGradientStopPatch as mD, updateInnerShadowPatch as mE, updateOuterShadowPatch as mF, updateReflectionPatch as mG, vAlignPatch as mH, validatePassword as mI, validatePrintSettings as mJ, validateRoomId as mK, valueToY as mL, vermilionDarkColors as mM, vermilionDarkTheme as mN, vermilionLightColors as mO, vermilionLightTheme as mP, vermilionRadius as mQ, waypointsToPathD as mR, withManualLayouts as mS, worstStatus as mT, zoomTargetSlideIndex as mU, statusLabel$1 as ma, storeAudienceContent as mb, stringFromEvent$5 as mc, strokeColorOf as md, strokeToInkElement as me, strokeWidthOf as mf, styleShadowFilter as mg, surfaceColor as mh, textAdvancedPatch as mi, textAdvancedStateFromStyle as mj, textAdvancedStateOf as mk, textColorOf as ml, textDirectionPatch as mm, textFontSizePatch as mn, textStyleOf as mo, textStylePatch as mp, themeStyle as mq, themeToCssVars as mr, thumbnailHeight as ms, thumbnailZoom as mt, toggleCommentResolvedInList as mu, toggleNodeBold as mv, toggleNodeItalic as mw, toggleSheet as mx, topLevelNodeCount as my, transformSelectedTextCase as mz, ALIGN_OPTIONS as n, ANIMATION_PRESET_CATEGORIES as o, AUDIENCE_HASH as p, AUDIENCE_NONCE_KEY as q, renderChartLineSvg as r, shade as s, toChatSummary as t, AVATAR_COLOR_SWATCHES as u, AXIS_LABEL_COLOR as v, AccessibilityPanelComponent as w, AccessibilityService as x, AccessibilityTextPanelComponent as y, AccountPageComponent as z };
195368
+ //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-16Hf0_zW.mjs.map