pptx-angular-viewer 2.2.1 → 2.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,15 +2,16 @@ import { NgStyle, NgTemplateOutlet, NgClass } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
3
  import { InjectionToken, input, output, computed, ChangeDetectionStrategy, Component, signal, Injectable, inject, DestroyRef, Injector, effect, viewChild, ElementRef, HostListener, afterNextRender, Renderer2, ViewEncapsulation, forwardRef, untracked } from '@angular/core';
4
4
  import { TranslatePipe, TranslateService, translate } from '@ngx-translate/core';
5
- import { THEME_PRESETS, guideEmuToPx, getShapeClipPath, getAdjustmentAwareShapeClipPath, getShapeClipPathFromPreset, getCloudPathForRendering, hasShapeProperties, applyDrawingColorTransforms as applyDrawingColorTransforms$1, hslToRgb as hslToRgb$1, PRESET_COLOR_MAP, isImageLikeElement, hasTextProperties, stripXmlOrderSuffix, orderedXmlKey, MIN_ELEMENT_SIZE as MIN_ELEMENT_SIZE$2, THEME_COLOR_SCHEME_KEYS, getLinkedTextBoxSegments, createBuiltinVariables, resolveCoordinate, svgPathToPolygons, deobfuscateFont, detectFontFormat, getSubstituteFontFamily, checkMissingAltText, checkMissingSlideTitle, checkLowContrast, checkComplexTables, checkBlankSlide, checkDuplicateTitles, createChartElement, PptxMarkdownConverter, ThemePresets, formatCommentTimestamp as formatCommentTimestamp$1, PptxHandler, EncryptedFileError, parseSignatureXml, cloneSlide as cloneSlide$1, cloneTemplateElementsBySlideId as cloneTemplateElementsBySlideId$1, cloneElement as cloneElement$1, updateSmartArtNodeText, setSmartArtNodeStyle, isInkElement, parseDataUrlToBytes, isZoomElement, SvgExporter, applyThemeToData, pptxActionToElementAction, elementActionToPptxAction, setChartTitle, setChartLegend, setChartDataLabels, setChartAxis, setChartSeriesTrendline, setChartSeriesErrorBars, setChartDataPointLabel, setChartAxisLogScale, setChartAxisTitleStyle, setChartAxisGridlineStyle, setChartSeriesMarker, setChartSeriesChartType, setChartDataPointFill, setChartDataPointExplosion, chartDataAddSeries, chartDataRemoveSeries, chartDataAddCategory, chartDataRemoveCategory, chartDataUpdatePoint, chartDataChangeType, getOleObjectTypeLabel, addSmartArtNodeAsChild, removeSmartArtNode, promoteSmartArtNode, demoteSmartArtNode, reorderSmartArtNode, switchSmartArtLayout, SWITCHABLE_LAYOUT_TYPES, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, applyThemeOverrideToSlide, getAnimationPresetInfo } from 'pptx-viewer-core';
5
+ import { THEME_PRESETS, guideEmuToPx, getShapeClipPath, getAdjustmentAwareShapeClipPath, getShapeClipPathFromPreset, getCloudPathForRendering, ooxmlGradientAngleToCssDegrees, hasShapeProperties, applyDrawingColorTransforms as applyDrawingColorTransforms$1, hslToRgb as hslToRgb$1, PRESET_COLOR_MAP, isImageLikeElement, hasTextProperties, stripXmlOrderSuffix, orderedXmlKey, MIN_ELEMENT_SIZE as MIN_ELEMENT_SIZE$2, THEME_COLOR_SCHEME_KEYS, getLinkedTextBoxSegments, createBuiltinVariables, resolveCoordinate, PptxHandler, svgPathToPolygons, deobfuscateFont, detectFontFormat, getSubstituteFontFamily, checkMissingAltText, checkMissingSlideTitle, checkLowContrast, checkComplexTables, checkBlankSlide, checkDuplicateTitles, createChartElement, PptxMarkdownConverter, ThemePresets, formatCommentTimestamp as formatCommentTimestamp$1, EncryptedFileError, parseSignatureXml, cloneSlide as cloneSlide$1, cloneTemplateElementsBySlideId as cloneTemplateElementsBySlideId$1, cloneElement as cloneElement$1, updateSmartArtNodeText, setSmartArtNodeStyle, isInkElement, parseDataUrlToBytes, isZoomElement, SvgExporter, applyThemeToData, pptxActionToElementAction, elementActionToPptxAction, setChartTitle, setChartLegend, setChartDataLabels, setChartAxis, setChartSeriesTrendline, setChartSeriesErrorBars, setChartDataPointLabel, setChartAxisLogScale, setChartAxisTitleStyle, setChartAxisGridlineStyle, setChartSeriesMarker, setChartSeriesChartType, setChartDataPointFill, setChartDataPointExplosion, chartDataAddSeries, chartDataRemoveSeries, chartDataAddCategory, chartDataRemoveCategory, chartDataUpdatePoint, chartDataChangeType, getOleObjectTypeLabel, addSmartArtNodeAsChild, removeSmartArtNode, promoteSmartArtNode, demoteSmartArtNode, reorderSmartArtNode, switchSmartArtLayout, SWITCHABLE_LAYOUT_TYPES, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, applyThemeOverrideToSlide, getAnimationPresetInfo } from 'pptx-viewer-core';
6
6
  import DOMPurify from 'dompurify';
7
7
  import { z } from 'zod';
8
8
  import * as mcp from 'pptx-viewer-mcp';
9
9
  import * as mcpSchemas from 'pptx-viewer-mcp/schemas';
10
10
  import { LucideX, LucideSquare, LucideCircle, LucideSlash, LucideCopy, LucideTrash2, LucideChevronsUp, LucideChevronsDown, LucideArrowUp, LucideArrowDown, LucideGroup, LucideUngroup, LucideTextAlignStart, LucideTextAlignCenter, LucideTextAlignEnd, LucideChevronUp, LucideChevronDown, LucideAlignHorizontalSpaceAround, LucideAlignVerticalSpaceAround, LucideLayers, LucideMessageSquare, LucidePlus, LucideSettings2, LucideStickyNote, LucideDownload, LucideMenu, LucidePresentation, LucideRedo, LucideShare2, LucideSparkles, LucideUndo, LucideChevronRight, LucidePenTool, LucideHighlighter, LucideEraser, LucideMousePointer2, LucideChevronLeft, LucidePlay, LucidePanelRight, LucideMoveRight, LucidePencil, LucideType, LucideMinus, LucideSpline, LucideArrowLeft, LucideFilePlus2, LucideFolderOpen, LucideHome, LucideInfo, LucidePrinter, LucideSave, LucideSettings, LucideUpload, LucideUserRound, LucideAArrowUp, LucideAArrowDown, LucideRemoveFormatting, LucideList, LucideListOrdered, LucideListIndentDecrease, LucideListIndentIncrease, LucideTextAlignJustify, LucideClipboardPaste, LucideFolderPlus, LucideLayoutGrid, LucidePaintbrush, LucideRotateCcw, LucideScissors, LucideImage, LucideVideo, LucideDatabase, LucidePanelLeft, LucideEllipsis, LucideEye, LucideEyeOff, LucideMonitor, LucideColumns2, LucideCheck, LucideSearch, LucideBug, LucideSend, LucideCrosshair, LucideGitMerge, LucidePin, LucidePinOff, LucideWrench, LucideLoaderCircle, LucideTriangleAlert, LucideShapes, LucidePalette, LucideTable, LucideLayoutTemplate, LucideChartColumn, LucideMove, LucideNavigation, LucideFilm, LucideBot, LucideUser } from '@lucide/angular';
11
+ import { XMLParser } from 'fast-xml-parser';
12
+ import JSZip from 'jszip';
11
13
  import { DomSanitizer } from '@angular/platform-browser';
12
14
  import { jsPDF } from 'jspdf';
13
- import JSZip from 'jszip';
14
15
 
15
16
  /**
16
17
  * Default dark-theme color values.
@@ -773,13 +774,20 @@ function sanitizeGradientStops(stops) {
773
774
  .sort((left, right) => left.position - right.position);
774
775
  }
775
776
  /**
776
- * Converts an OOXML gradient angle to a normalised CSS angle in degrees.
777
- * The Vue parser already pre-converts to plain degrees; when `alreadyDegrees`
778
- * is false the input is treated as 60000ths of a degree.
777
+ * Converts an OOXML gradient angle to the equivalent CSS `linear-gradient()`
778
+ * angle, normalised to [0, 360).
779
+ *
780
+ * `a:lin/@ang` is measured clockwise from the positive x-axis (`ang="0"` runs
781
+ * left to right) whereas CSS measures clockwise from "to top" (`0deg` runs
782
+ * bottom to top), so the two sit a quarter turn apart. Feeding an OOXML angle
783
+ * straight into a CSS gradient renders the fill rotated 90 degrees.
784
+ *
785
+ * The parser stores `ShapeStyle.fillGradientAngle` in plain OOXML degrees; when
786
+ * `alreadyDegrees` is false the input is treated as raw 60000ths of a degree.
779
787
  */
780
788
  function convertOoxmlAngleToCss(ooxmlAngle, alreadyDegrees = true) {
781
789
  const deg = alreadyDegrees ? ooxmlAngle : ooxmlAngle / 60000;
782
- return ((deg % 360) + 360) % 360;
790
+ return ooxmlGradientAngleToCssDegrees(deg);
783
791
  }
784
792
  /**
785
793
  * Converts a single gradient stop to a CSS gradient color-stop string,
@@ -1034,7 +1042,9 @@ function buildGradientCss(gradient, context) {
1034
1042
  const normalizedAngle = typeof gradient.fillGradientAngle === 'number' && Number.isFinite(gradient.fillGradientAngle)
1035
1043
  ? gradient.fillGradientAngle
1036
1044
  : 90;
1037
- const effectiveAngle = adjustLinearGradientAngle(normalizedAngle, gradient, context);
1045
+ // `@scaled` / `@rotWithShape` are corrections in OOXML angle space, so they
1046
+ // are applied first and the result converted to CSS degrees exactly once.
1047
+ const effectiveAngle = convertOoxmlAngleToCss(adjustLinearGradientAngle(normalizedAngle, gradient, context));
1038
1048
  // Tile-flip: reflect the stops so a single tile contains one mirrored
1039
1049
  // forward-backward cycle. The repeating/halved tiling is applied by the
1040
1050
  // caller via getGradientTileFlipCss (wired into getComputedFillStyle).
@@ -15827,6 +15837,50 @@ function countTextSegments(textSegments) {
15827
15837
  * in composite animation target IDs (e.g. `"shape3::p0"`).
15828
15838
  */
15829
15839
  const TEXT_BUILD_ID_SEP = '::';
15840
+ /**
15841
+ * The build granularity an animation actually wants, from either of the two
15842
+ * places OOXML records it.
15843
+ *
15844
+ * `p:bldP/@build` (parsed to `buildType`) is the slide-level text build, but
15845
+ * PowerPoint's "Effect Options > Animate text: By letter / By word" writes
15846
+ * `p:iterate` on the effect's own `p:cTn` instead. Only the first was honoured,
15847
+ * so a title authored to fade in letter by letter faded in as one block
15848
+ * (issue #106). `p:iterate type="el"` means "as one object" and stays
15849
+ * unexpanded.
15850
+ */
15851
+ function effectiveTextBuildType(anim) {
15852
+ if (anim.buildType && anim.buildType !== 'allAtOnce') {
15853
+ return anim.buildType;
15854
+ }
15855
+ if (anim.iterate?.type === 'lt') {
15856
+ return 'byChar';
15857
+ }
15858
+ if (anim.iterate?.type === 'wd') {
15859
+ return 'byWord';
15860
+ }
15861
+ return undefined;
15862
+ }
15863
+ /**
15864
+ * Stagger (ms) between consecutive sub-elements of an `p:iterate` build.
15865
+ *
15866
+ * `p:tmAbs` is already milliseconds; `p:tmPct` is a percentage of the effect's
15867
+ * own duration in 1000ths of a percent (PowerPoint's default is `10000`, i.e.
15868
+ * 10%). Returns `undefined` when the animation is not iterate-driven, so the
15869
+ * caller keeps the slide-build defaults.
15870
+ */
15871
+ function iterateStaggerMs(anim, durationMs) {
15872
+ const iterate = anim.iterate;
15873
+ if (!iterate || iterate.type === 'el') {
15874
+ return undefined;
15875
+ }
15876
+ if (typeof iterate.tmAbs === 'number' && Number.isFinite(iterate.tmAbs) && iterate.tmAbs > 0) {
15877
+ return iterate.tmAbs;
15878
+ }
15879
+ if (typeof iterate.tmPct === 'number' && Number.isFinite(iterate.tmPct) && iterate.tmPct > 0) {
15880
+ return Math.max(1, Math.round((iterate.tmPct / 100000) * durationMs));
15881
+ }
15882
+ return undefined;
15883
+ }
15830
15884
  /**
15831
15885
  * Expand text-build animations into per-paragraph, per-word or per-character
15832
15886
  * sub-element animations.
@@ -15842,9 +15896,9 @@ const TEXT_BUILD_ID_SEP = '::';
15842
15896
  function expandTextBuildAnimations(animations, segmentCounts) {
15843
15897
  const result = [];
15844
15898
  for (const anim of animations) {
15845
- const buildType = anim.buildType;
15899
+ const buildType = effectiveTextBuildType(anim);
15846
15900
  const targetId = anim.targetId ?? '';
15847
- if (!buildType || buildType === 'allAtOnce' || !targetId) {
15901
+ if (!buildType || !targetId) {
15848
15902
  result.push(anim);
15849
15903
  continue;
15850
15904
  }
@@ -15874,6 +15928,13 @@ function expandSingleBuildAnimation(anim, buildType, counts, output) {
15874
15928
  }
15875
15929
  return;
15876
15930
  }
15931
+ // An `p:iterate` build overlaps: every letter/word runs the FULL effect
15932
+ // duration and merely starts `stagger` later than the one before, which is
15933
+ // what makes PowerPoint's "by letter" read as a ripple. `withPrevious` steps
15934
+ // accumulate their delay from the previous step's START, so passing the bare
15935
+ // interval as each step's delay yields `base + i * stagger`. The slide-build
15936
+ // (`p:bldP`) path keeps its original end-to-end pacing.
15937
+ const stagger = iterateStaggerMs(anim, baseDuration);
15877
15938
  if (buildType === 'byWord') {
15878
15939
  const wordCounts = counts.wordCounts ?? [];
15879
15940
  let stepIndex = 0;
@@ -15883,10 +15944,18 @@ function expandSingleBuildAnimation(anim, buildType, counts, output) {
15883
15944
  output.push({
15884
15945
  ...anim,
15885
15946
  targetId: `${targetId}${TEXT_BUILD_ID_SEP}w${pIdx}-${wIdx}`,
15886
- trigger: stepIndex === 0 ? anim.trigger : 'afterPrevious',
15887
- durationMs: Math.max(100, Math.round(baseDuration / 2)),
15888
- delayMs: stepIndex === 0 ? (anim.delayMs ?? 0) : 50,
15947
+ trigger: stepIndex === 0
15948
+ ? anim.trigger
15949
+ : stagger !== undefined
15950
+ ? 'withPrevious'
15951
+ : 'afterPrevious',
15952
+ durationMs: stagger !== undefined ? baseDuration : Math.max(100, Math.round(baseDuration / 2)),
15953
+ delayMs: stepIndex === 0 ? (anim.delayMs ?? 0) : (stagger ?? 50),
15954
+ // Only the first sub-step inherits the parent's start delay; the
15955
+ // rest carry the bare stagger, so these must not re-apply it.
15956
+ ...(stepIndex === 0 ? {} : { triggerDelayMs: undefined, startConditions: undefined }),
15889
15957
  buildType: undefined,
15958
+ iterate: undefined,
15890
15959
  });
15891
15960
  stepIndex++;
15892
15961
  }
@@ -15902,10 +15971,18 @@ function expandSingleBuildAnimation(anim, buildType, counts, output) {
15902
15971
  output.push({
15903
15972
  ...anim,
15904
15973
  targetId: `${targetId}${TEXT_BUILD_ID_SEP}c${pIdx}-${cIdx}`,
15905
- trigger: stepIndex === 0 ? anim.trigger : 'afterPrevious',
15906
- durationMs: Math.max(50, Math.round(baseDuration / 4)),
15907
- delayMs: stepIndex === 0 ? (anim.delayMs ?? 0) : 20,
15974
+ trigger: stepIndex === 0
15975
+ ? anim.trigger
15976
+ : stagger !== undefined
15977
+ ? 'withPrevious'
15978
+ : 'afterPrevious',
15979
+ durationMs: stagger !== undefined ? baseDuration : Math.max(50, Math.round(baseDuration / 4)),
15980
+ delayMs: stepIndex === 0 ? (anim.delayMs ?? 0) : (stagger ?? 20),
15981
+ // Only the first sub-step inherits the parent's start delay; the
15982
+ // rest carry the bare stagger, so these must not re-apply it.
15983
+ ...(stepIndex === 0 ? {} : { triggerDelayMs: undefined, startConditions: undefined }),
15908
15984
  buildType: undefined,
15985
+ iterate: undefined,
15909
15986
  });
15910
15987
  stepIndex++;
15911
15988
  }
@@ -16303,6 +16380,45 @@ function buildStepCommand(anim) {
16303
16380
  targetId: anim.targetId ?? '',
16304
16381
  };
16305
16382
  }
16383
+ /** Command name introducing a seek-then-play verb, lower-cased. */
16384
+ const PLAY_FROM_NAME = 'playfrom';
16385
+ /**
16386
+ * An unambiguous decimal-number pattern: each alternative has exactly one way
16387
+ * to match any given string, so there is nothing for the engine to backtrack
16388
+ * over. The original single-regex form (`\s*(-?\d*\.?\d+)?\s*` inside the
16389
+ * parentheses) was ambiguous on both the digits and the surrounding
16390
+ * whitespace, giving polynomial match time on hostile input such as
16391
+ * `playFrom(000...0`.
16392
+ */
16393
+ const DECIMAL_NUMBER = /^-?(?:\d+(?:\.\d+)?|\.\d+)$/u;
16394
+ /**
16395
+ * Parse a `playFrom(<seconds>)` command by slicing rather than by matching a
16396
+ * single ambiguous regex, so run time stays linear in the input length.
16397
+ *
16398
+ * Accepts the same shapes as before: optional whitespace around the name, the
16399
+ * parentheses and the number, and an empty argument list meaning "from 0".
16400
+ * Returns `undefined` when the string is not a `playFrom(...)` call at all, or
16401
+ * when its argument is not a plain decimal number.
16402
+ */
16403
+ function parsePlayFrom(raw) {
16404
+ const lower = raw.toLowerCase();
16405
+ if (!lower.startsWith(PLAY_FROM_NAME) || !lower.endsWith(')')) {
16406
+ return undefined;
16407
+ }
16408
+ const afterName = raw.slice(PLAY_FROM_NAME.length).trimStart();
16409
+ if (!afterName.startsWith('(')) {
16410
+ return undefined;
16411
+ }
16412
+ const inner = afterName.slice(1, -1).trim();
16413
+ if (inner.length === 0) {
16414
+ return { verb: 'playFrom', seekSeconds: 0 };
16415
+ }
16416
+ if (!DECIMAL_NUMBER.test(inner)) {
16417
+ return undefined;
16418
+ }
16419
+ const seconds = Number.parseFloat(inner);
16420
+ return { verb: 'playFrom', seekSeconds: Number.isFinite(seconds) ? Math.max(0, seconds) : 0 };
16421
+ }
16306
16422
  /**
16307
16423
  * Parse an OOXML `p:cmd/@cmd` string into a browser-actionable media verb.
16308
16424
  *
@@ -16322,10 +16438,9 @@ function parseMediaCommand(commandString) {
16322
16438
  if (!raw) {
16323
16439
  return undefined;
16324
16440
  }
16325
- const playFromMatch = raw.match(/^playfrom\s*\(\s*(-?\d*\.?\d+)?\s*\)$/i);
16326
- if (playFromMatch) {
16327
- const seconds = playFromMatch[1] !== undefined ? Number.parseFloat(playFromMatch[1]) : 0;
16328
- return { verb: 'playFrom', seekSeconds: Number.isFinite(seconds) ? Math.max(0, seconds) : 0 };
16441
+ const playFrom = parsePlayFrom(raw);
16442
+ if (playFrom) {
16443
+ return playFrom;
16329
16444
  }
16330
16445
  const lower = raw.toLowerCase();
16331
16446
  if (lower === 'play' || lower === 'resume') {
@@ -16527,13 +16642,17 @@ function buildTimeline(nativeAnimations) {
16527
16642
  const duration = isCommand
16528
16643
  ? 0
16529
16644
  : (singleAnim.durationMs ?? defaultDuration(singleAnim.presetClass));
16530
- const animDelay = singleAnim.delayMs ?? 0;
16645
+ // `delayMs`, `triggerDelayMs` and the start condition's delay are three
16646
+ // views of ONE OOXML quantity: when does this effect start. Adding them
16647
+ // double-counts (a 1s delay played at 2s), so take the governing value.
16648
+ const animDelay = Math.max(singleAnim.delayMs ?? 0,
16531
16649
  // Use the governing condition delay when conditions were present;
16532
16650
  // otherwise fall back to the simple triggerDelayMs (afterDelay) so
16533
16651
  // existing single-condition slides are unchanged.
16534
- const triggerDelay = singleAnim.startConditions && singleAnim.startConditions.length > 0
16652
+ singleAnim.startConditions && singleAnim.startConditions.length > 0
16535
16653
  ? effective.delayMs
16536
- : (singleAnim.triggerDelayMs ?? 0);
16654
+ : (singleAnim.triggerDelayMs ?? 0));
16655
+ const triggerDelay = 0;
16537
16656
  const presetClass = isCommand ? 'emph' : (singleAnim.presetClass ?? 'entr');
16538
16657
  const fill = fillModeForClass(singleAnim.presetClass);
16539
16658
  // Compute repeat / direction
@@ -16662,14 +16781,11 @@ function countDynamicUids(interactiveAnims) {
16662
16781
  * delay between consecutive sub-elements.
16663
16782
  */
16664
16783
  function expandIterateAnimation(anim) {
16665
- const iterate = anim.iterate;
16666
- if (!iterate || iterate.type === 'el') {
16667
- return [anim];
16668
- }
16669
- // We return the original animation unchanged for now
16670
- // iterate expansion is handled at a higher level by the text-build system
16671
- // when buildType is set. When iterate is present without a matching
16672
- // buildType, we still return the original to avoid dropping the animation.
16784
+ // Expansion happens upstream, in `expandTextBuildAnimations`: splitting text
16785
+ // needs the target element's paragraph/word/character counts, which the
16786
+ // timeline builder does not have (it only sees animations). By the time an
16787
+ // animation reaches here it has already been split into per-letter or
16788
+ // per-word sub-animations, so there is nothing left to do.
16673
16789
  return [anim];
16674
16790
  }
16675
16791
  /**
@@ -16701,8 +16817,9 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
16701
16817
  const elementId = anim.targetId ?? '';
16702
16818
  const seqTrigger = anim.trigger ?? 'onShapeClick';
16703
16819
  const duration = anim.durationMs ?? defaultDuration(anim.presetClass);
16704
- const animDelay = anim.delayMs ?? 0;
16705
- const triggerDelay = anim.triggerDelayMs ?? 0;
16820
+ // Same single-quantity rule as the main sequence: never sum the two.
16821
+ const animDelay = Math.max(anim.delayMs ?? 0, anim.triggerDelayMs ?? 0);
16822
+ const triggerDelay = 0;
16706
16823
  const presetClass = anim.presetClass ?? 'entr';
16707
16824
  const fill = fillModeForClass(anim.presetClass);
16708
16825
  const iterCount = anim.repeatCount ?? 1;
@@ -17095,7 +17212,7 @@ class TimelineEngine {
17095
17212
  function buildSegmentCounts(slide, nativeAnims) {
17096
17213
  const segmentCounts = new Map();
17097
17214
  for (const anim of nativeAnims) {
17098
- if (anim.buildType && anim.buildType !== 'allAtOnce' && anim.targetId) {
17215
+ if (effectiveTextBuildType(anim) && anim.targetId) {
17099
17216
  const el = slide.elements.find((e) => e.id === anim.targetId);
17100
17217
  if (el && hasTextProperties(el) && el.textSegments && el.textSegments.length > 0) {
17101
17218
  segmentCounts.set(anim.targetId, countTextSegments(el.textSegments));
@@ -29844,6 +29961,23 @@ function createDepartureChannel(roomId, awareness, factory) {
29844
29961
  };
29845
29962
  }
29846
29963
 
29964
+ /**
29965
+ * collaboration-writeback.ts: elected-writer (role 'owner') PPTX write-back.
29966
+ *
29967
+ * Only the session owner persists snapshots, eliminating last-save-wins races.
29968
+ * On a debounced trigger it reloads the retained source bytes, overlays the
29969
+ * live Y.Doc slides (optionally merging back a binding's separately-stored
29970
+ * master/layout template elements via `mergeTemplateElements`, so template
29971
+ * edits survive), re-serializes to PPTX bytes, and hands them to
29972
+ * `config.onWriteBack`.
29973
+ *
29974
+ * Framework-agnostic: every binding (Vue, Svelte, Vanilla) shares this single
29975
+ * implementation instead of maintaining its own near-identical copy. A
29976
+ * binding without template-mode editing simply omits `getTemplateElements`/
29977
+ * `mergeTemplateElements`. Angular keeps its own class-based
29978
+ * `WriteBackScheduler` (a different calling convention tied to its DI style),
29979
+ * not a duplicate of this one.
29980
+ */
29847
29981
  const DEFAULT_DEBOUNCE_MS = 5_000;
29848
29982
  function createWriteBackScheduler(deps) {
29849
29983
  let timer = null;
@@ -29870,7 +30004,6 @@ function createWriteBackScheduler(deps) {
29870
30004
  return;
29871
30005
  }
29872
30006
  try {
29873
- const { PptxHandler } = await import('pptx-viewer-core');
29874
30007
  const handler = new PptxHandler();
29875
30008
  await handler.load(sourceBytes.buffer);
29876
30009
  const slides = readSlidesFromYDoc(ydoc);
@@ -37642,6 +37775,20 @@ function buildShareConfig(fields) {
37642
37775
  * conversion. DOM-free; each binding renders the returned `NotesSpan[]` spec
37643
37776
  * into its own `<span>`/`<br>` nodes.
37644
37777
  */
37778
+ /**
37779
+ * Whether a click on the presenter console's current-slide pane should advance
37780
+ * the show.
37781
+ *
37782
+ * PowerPoint's presenter console advances when you click the big slide, which
37783
+ * is how presenters actually drive a deck - the Next button and the keyboard
37784
+ * are the fallbacks, not the primary control. The exception is an active
37785
+ * drawing tool: pen, highlighter and eraser own the pointer, so clicking then
37786
+ * annotates instead of jumping the deck out from under the stroke. The laser
37787
+ * only tracks the cursor and does not consume clicks, so it still advances.
37788
+ */
37789
+ function presenterPaneAdvancesOnClick(tool) {
37790
+ return tool === undefined || tool === 'none' || tool === 'laser';
37791
+ }
37645
37792
  /** Minimum font size (px) for speaker notes in presenter view. */
37646
37793
  const NOTES_FONT_SIZE_MIN = 10;
37647
37794
  /** Maximum font size (px) for speaker notes in presenter view. */
@@ -37711,6 +37858,122 @@ function notesSegmentsToSpans(segments) {
37711
37858
  });
37712
37859
  }
37713
37860
 
37861
+ /**
37862
+ * `text-build-spans` - framework-agnostic spec for rendering a staged text
37863
+ * build (by paragraph / word / letter).
37864
+ *
37865
+ * `expandTextBuildAnimations` splits one animation into per-paragraph,
37866
+ * per-word or per-character sub-animations keyed `<elementId>::p0` /
37867
+ * `::w0-3` / `::c0-7`. Something then has to split the RENDERED text the same
37868
+ * way and attach each sub-animation to its own span, or the build has no
37869
+ * visible effect and the whole box fades as one.
37870
+ *
37871
+ * React did that inline in JSX, which left the other four bindings with no
37872
+ * by-letter animation at all. This module returns the split as plain data so
37873
+ * every binding can render it with its own primitives - the same shape as
37874
+ * `notesSegmentsToSpans`.
37875
+ *
37876
+ * @module render/text-build-spans
37877
+ */
37878
+ /**
37879
+ * Flatten runs into `[character, style]` pairs so a split can carry each
37880
+ * character's own formatting through.
37881
+ */
37882
+ function charactersWithStyle(runs) {
37883
+ const out = [];
37884
+ for (const run of runs) {
37885
+ for (const ch of run.text) {
37886
+ out.push({ ch, style: run.style });
37887
+ }
37888
+ }
37889
+ return out;
37890
+ }
37891
+ function stateSpan(animId, text, states, style) {
37892
+ const state = states.get(animId);
37893
+ return {
37894
+ animId,
37895
+ text,
37896
+ hidden: state?.visible === false,
37897
+ cssAnimation: state?.cssAnimation,
37898
+ style,
37899
+ };
37900
+ }
37901
+ /**
37902
+ * Resolve how a paragraph should be split, or `undefined` when no staged build
37903
+ * targets it (the overwhelmingly common case - callers render normally then).
37904
+ *
37905
+ * Detection mirrors the ids `expandTextBuildAnimations` emits: a paragraph
37906
+ * build registers `::p<i>`, a word build `::w<i>-0`, a char build `::c<i>-0`.
37907
+ *
37908
+ * @param elementId - The owning element's id.
37909
+ * @param paraIndex - Index of this paragraph within the element's text.
37910
+ * @param runs - The paragraph's styled runs, in order.
37911
+ * @param states - Live sub-element animation states for the slide.
37912
+ */
37913
+ function buildTextBuildSpec(elementId, paraIndex, runs, states) {
37914
+ if (!states || states.size === 0) {
37915
+ return undefined;
37916
+ }
37917
+ const paraKey = `${elementId}${TEXT_BUILD_ID_SEP}p${paraIndex}`;
37918
+ const paraState = states.get(paraKey);
37919
+ if (paraState) {
37920
+ return {
37921
+ granularity: 'paragraph',
37922
+ animId: paraKey,
37923
+ hidden: paraState.visible === false,
37924
+ cssAnimation: paraState.cssAnimation,
37925
+ };
37926
+ }
37927
+ const characters = charactersWithStyle(runs);
37928
+ if (states.has(`${elementId}${TEXT_BUILD_ID_SEP}w${paraIndex}-0`)) {
37929
+ const spans = [];
37930
+ let wordIndex = 0;
37931
+ let current = null;
37932
+ // Whitespace stays its own unanimated piece so the paragraph wraps and
37933
+ // spaces exactly as it does unanimated. A word that straddles a run
37934
+ // boundary keeps the style of the run it started in.
37935
+ const flush = () => {
37936
+ if (!current) {
37937
+ return;
37938
+ }
37939
+ spans.push(stateSpan(`${elementId}${TEXT_BUILD_ID_SEP}w${paraIndex}-${wordIndex}`, current.text, states, current.style));
37940
+ wordIndex++;
37941
+ current = null;
37942
+ };
37943
+ for (const { ch, style } of characters) {
37944
+ if (/\s/u.test(ch)) {
37945
+ flush();
37946
+ spans.push({ text: ch, hidden: false, style });
37947
+ continue;
37948
+ }
37949
+ current =
37950
+ current === null ? { text: ch, style } : { text: current.text + ch, style: current.style };
37951
+ }
37952
+ flush();
37953
+ return { granularity: 'word', spans };
37954
+ }
37955
+ if (states.has(`${elementId}${TEXT_BUILD_ID_SEP}c${paraIndex}-0`)) {
37956
+ const spans = characters.map((entry, index) => stateSpan(`${elementId}${TEXT_BUILD_ID_SEP}c${paraIndex}-${index}`, entry.ch, states, entry.style));
37957
+ return { granularity: 'char', spans };
37958
+ }
37959
+ return undefined;
37960
+ }
37961
+ /**
37962
+ * The inline style a {@link TextBuildSpan} (or a paragraph-level spec) needs.
37963
+ * Returned as a plain record so each binding can apply it however it applies
37964
+ * styles; `display: inline` keeps the wrapper from breaking text layout.
37965
+ */
37966
+ function textBuildSpanStyle(span) {
37967
+ const style = { display: 'inline' };
37968
+ if (span.hidden) {
37969
+ style.visibility = 'hidden';
37970
+ }
37971
+ if (span.cssAnimation) {
37972
+ style.animation = span.cssAnimation;
37973
+ }
37974
+ return style;
37975
+ }
37976
+
37714
37977
  const PRESENTER_ZOOM_MIN = 1;
37715
37978
  const PRESENTER_ZOOM_MAX = 4;
37716
37979
  const PRESENTER_ZOOM_STEP = 0.5;
@@ -47551,6 +47814,7 @@ const translationsEn = {
47551
47814
  'pptx.presentation.highlighter': 'Highlighter',
47552
47815
  'pptx.presentation.eraser': 'Eraser',
47553
47816
  'pptx.presentation.laserPointer': 'Laser Pointer',
47817
+ 'pptx.presentation.endOfSlideShow': 'End of slide show, click to exit.',
47554
47818
  'pptx.presentation.pointerTools': 'Pointer Options',
47555
47819
  // Selection pane
47556
47820
  'pptx.selectionPane.title': 'Selection Pane',
@@ -51911,7 +52175,7 @@ function createLocalStorageBackend(namespace) {
51911
52175
  /** Try IndexedDB first; fall back to localStorage on any failure. */
51912
52176
  async function resolveBackend(dbName, namespace) {
51913
52177
  try {
51914
- const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-DW2bO-jk.mjs');
52178
+ const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-B1LY08QA.mjs');
51915
52179
  const db = await openChatDb(dbName);
51916
52180
  return createIdbBackend(db);
51917
52181
  }
@@ -54621,7 +54885,6 @@ const WRITE_BACK_DEBOUNCE_MS = 5_000;
54621
54885
  * handler so package parts the CRDT does not carry (media, fonts, rels) survive.
54622
54886
  */
54623
54887
  async function serializeWriteBack(ydoc, sourceBytes, templateElements) {
54624
- const { PptxHandler } = await import('pptx-viewer-core');
54625
54888
  const handler = new PptxHandler();
54626
54889
  await handler.load(sourceBytes.buffer);
54627
54890
  const slides = buildSaveSlides(readSlidesFromYDoc(ydoc), templateElements);
@@ -56104,16 +56367,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
56104
56367
  }], ctorParameters: () => [] });
56105
56368
  /**
56106
56369
  * Parse digital signatures from a `.pptx` ZIP buffer (best-effort; returns an
56107
- * empty array when there are none or parsing fails). `jszip`/`fast-xml-parser`
56108
- * are imported lazily so they stay out of the main chunk. Mirrors the Vue
56109
- * port's `parseSignaturesFromBuffer`.
56370
+ * empty array when there are none or parsing fails). Mirrors the Vue port's
56371
+ * `parseSignaturesFromBuffer`.
56372
+ *
56373
+ * `jszip`/`fast-xml-parser` are imported statically on purpose: `PptxHandler`
56374
+ * (imported above) already pulls both into the same chunk, so a dynamic import
56375
+ * here cannot move them anywhere. It only made bundlers emit
56376
+ * INEFFECTIVE_DYNAMIC_IMPORT.
56110
56377
  */
56111
56378
  async function parseSignaturesFromBuffer(buffer) {
56112
56379
  try {
56113
- const [{ default: JSZip }, { XMLParser }] = await Promise.all([
56114
- import('jszip'),
56115
- import('fast-xml-parser'),
56116
- ]);
56117
56380
  const zip = await JSZip.loadAsync(buffer);
56118
56381
  const parser = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: '@_' });
56119
56382
  const result = [];
@@ -67843,6 +68106,31 @@ class ElementRendererComponent {
67843
68106
  */
67844
68107
  animationState = computed(() => this.playback?.presentationElementStates().get(this.element().id), /* @ts-ignore */
67845
68108
  ...(ngDevMode ? [{ debugName: "animationState" }] : /* istanbul ignore next */ []));
68109
+ /**
68110
+ * Per-paragraph split for a staged text build (by paragraph / word / letter),
68111
+ * or `undefined` entries to render the runs normally. PowerPoint's "Animate
68112
+ * text: By letter" needs the rendered text split to match the per-character
68113
+ * sub-animations, otherwise the whole box just fades as one.
68114
+ */
68115
+ textBuildSpecs = computed(() => {
68116
+ const states = this.playback?.presentationElementStates();
68117
+ if (!states || states.size === 0) {
68118
+ return [];
68119
+ }
68120
+ const id = this.element().id;
68121
+ return this.paragraphs().map((para, paraIndex) => buildTextBuildSpec(id, paraIndex, para.runs
68122
+ .filter((run) => run.text !== '\n')
68123
+ .map((run) => ({ text: run.text, style: run.style })), states));
68124
+ }, /* @ts-ignore */
68125
+ ...(ngDevMode ? [{ debugName: "textBuildSpecs" }] : /* istanbul ignore next */ []));
68126
+ /** Whole-paragraph text, for the paragraph-level build wrapper. */
68127
+ paragraphText(para) {
68128
+ return para.runs.map((run) => run.text).join('');
68129
+ }
68130
+ /** Style for one build piece, merged over the run's own style. */
68131
+ buildSpanStyle(span) {
68132
+ return { ...(span.style ?? {}), ...textBuildSpanStyle(span) };
68133
+ }
67846
68134
  containerStyle = computed(() => ({
67847
68135
  ...getContainerStyle(this.element(), this.zIndex()),
67848
68136
  ...this.templateAffordanceStyle(),
@@ -68215,6 +68503,25 @@ class ElementRendererComponent {
68215
68503
  >{{ para.bulletMarker }}&nbsp;</span
68216
68504
  >
68217
68505
  }
68506
+ @if (textBuildSpecs()[$index]; as spec) {
68507
+ <!-- Staged text build: render the split pieces so each one
68508
+ carries its own sub-animation. -->
68509
+ @if (spec.granularity === 'paragraph') {
68510
+ <span
68511
+ [attr.data-anim-id]="spec.animId"
68512
+ [ngStyle]="buildSpanStyle(spec)"
68513
+ >{{ paragraphText(para) }}</span
68514
+ >
68515
+ } @else {
68516
+ @for (span of spec.spans ?? []; track $index) {
68517
+ <span
68518
+ [attr.data-anim-id]="span.animId"
68519
+ [ngStyle]="buildSpanStyle(span)"
68520
+ >{{ span.text }}</span
68521
+ >
68522
+ }
68523
+ }
68524
+ } @else {
68218
68525
  @for (run of para.runs; track $index) {
68219
68526
  @if (run.equationXml) {
68220
68527
  <pptx-equation-renderer
@@ -68241,6 +68548,7 @@ class ElementRendererComponent {
68241
68548
  <span [ngStyle]="run.style">{{ run.text }}</span>
68242
68549
  }
68243
68550
  }
68551
+ }
68244
68552
  </p>
68245
68553
  }
68246
68554
  </div>
@@ -68555,6 +68863,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
68555
68863
  >{{ para.bulletMarker }}&nbsp;</span
68556
68864
  >
68557
68865
  }
68866
+ @if (textBuildSpecs()[$index]; as spec) {
68867
+ <!-- Staged text build: render the split pieces so each one
68868
+ carries its own sub-animation. -->
68869
+ @if (spec.granularity === 'paragraph') {
68870
+ <span
68871
+ [attr.data-anim-id]="spec.animId"
68872
+ [ngStyle]="buildSpanStyle(spec)"
68873
+ >{{ paragraphText(para) }}</span
68874
+ >
68875
+ } @else {
68876
+ @for (span of spec.spans ?? []; track $index) {
68877
+ <span
68878
+ [attr.data-anim-id]="span.animId"
68879
+ [ngStyle]="buildSpanStyle(span)"
68880
+ >{{ span.text }}</span
68881
+ >
68882
+ }
68883
+ }
68884
+ } @else {
68558
68885
  @for (run of para.runs; track $index) {
68559
68886
  @if (run.equationXml) {
68560
68887
  <pptx-equation-renderer
@@ -68581,6 +68908,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
68581
68908
  <span [ngStyle]="run.style">{{ run.text }}</span>
68582
68909
  }
68583
68910
  }
68911
+ }
68584
68912
  </p>
68585
68913
  }
68586
68914
  </div>
@@ -78009,6 +78337,22 @@ function fitZoom(canvasW, canvasH, vw, vh) {
78009
78337
  }
78010
78338
  return Math.min(vw / canvasW, vh / canvasH);
78011
78339
  }
78340
+ /**
78341
+ * Whether a visible (non-hidden) slide exists strictly AFTER `current`.
78342
+ *
78343
+ * `nextVisibleIndex` wraps modulo the deck length, which makes a show loop for
78344
+ * ever. PowerPoint only loops when "Loop continuously until Esc" is set;
78345
+ * otherwise running past the last slide ends the show. Callers use this to tell
78346
+ * "there is a next slide" from "we just wrapped".
78347
+ */
78348
+ function hasVisibleSlideAfter(current, slides) {
78349
+ for (let index = current + 1; index < slides.length; index++) {
78350
+ if (!slides[index].hidden) {
78351
+ return true;
78352
+ }
78353
+ }
78354
+ return false;
78355
+ }
78012
78356
 
78013
78357
  /** Compatibility barrel for shared live-caption helpers and structural types. */
78014
78358
 
@@ -78195,6 +78539,28 @@ function resolveTransitionDuration(durationMs) {
78195
78539
  : DEFAULT_TRANSITION_DURATION_MS;
78196
78540
  return Math.max(MIN_TRANSITION_DURATION_MS, raw);
78197
78541
  }
78542
+ // ---------------------------------------------------------------------------
78543
+ // Outgoing-layer geometry
78544
+ // ---------------------------------------------------------------------------
78545
+ /**
78546
+ * Footprint (px) of the outgoing slide box inside the transition overlay.
78547
+ *
78548
+ * It has to be the ZOOMED slide size, because the overlay sits inside the same
78549
+ * stage container as the live `pptx-slide-canvas` and that canvas is already
78550
+ * rendering at the stage zoom. Sizing the box at the intrinsic canvas size (and
78551
+ * leaving the inner canvas at `zoom=1`) makes the leaving slide animate out at
78552
+ * 100% while the arriving slide is full-screen, which reads as the slide
78553
+ * snapping small the moment a transition starts.
78554
+ *
78555
+ * A missing or non-positive zoom degrades to 1 rather than collapsing the box.
78556
+ */
78557
+ function transitionSlideBoxSize(canvasSize, zoom) {
78558
+ const safeZoom = Number.isFinite(zoom) && zoom > 0 ? zoom : 1;
78559
+ return {
78560
+ width: Math.max(canvasSize.width * safeZoom, 1),
78561
+ height: Math.max(canvasSize.height * safeZoom, 1),
78562
+ };
78563
+ }
78198
78564
 
78199
78565
  /** DOM id of the singleton <style> tag holding the transition keyframes. */
78200
78566
  const KEYFRAMES_STYLE_ID = 'pptx-ng-slide-transition-keyframes';
@@ -78236,6 +78602,8 @@ function ensureTransitionKeyframes() {
78236
78602
  * - `templateElements`: master/layout elements behind the outgoing slide
78237
78603
  * - `mediaDataUrls` : data-URL map for media assets
78238
78604
  * - `durationMs` : explicit override; otherwise derived from `transition`
78605
+ * - `zoom` : the stage's live zoom, so the outgoing slide animates
78606
+ * at the same size as the incoming one
78239
78607
  *
78240
78608
  * Outputs:
78241
78609
  * - `complete`: emits void when the transition animation completes
@@ -78261,6 +78629,14 @@ class PresentationTransitionOverlayComponent {
78261
78629
  /** Explicit duration override (ms). When omitted, derived from `transition`. */
78262
78630
  durationMs = input(undefined, /* @ts-ignore */
78263
78631
  ...(ngDevMode ? [{ debugName: "durationMs" }] : /* istanbul ignore next */ []));
78632
+ /**
78633
+ * The stage's live zoom (the same value the underlying `pptx-slide-canvas`
78634
+ * renders at). The outgoing layer MUST use it: left at 1 the leaving slide
78635
+ * animates out at its intrinsic size over a full-screen incoming slide,
78636
+ * which reads as the slide snapping small the instant a transition starts.
78637
+ */
78638
+ zoom = input(1, /* @ts-ignore */
78639
+ ...(ngDevMode ? [{ debugName: "zoom" }] : /* istanbul ignore next */ []));
78264
78640
  // ------------------------------------------------------------------
78265
78641
  // Outputs
78266
78642
  // ------------------------------------------------------------------
@@ -78330,12 +78706,17 @@ class PresentationTransitionOverlayComponent {
78330
78706
  return style;
78331
78707
  }, /* @ts-ignore */
78332
78708
  ...(ngDevMode ? [{ debugName: "layerStyle" }] : /* istanbul ignore next */ []));
78333
- /** Fixed-size slide box (the SlideCanvas auto-fits within it). */
78709
+ /**
78710
+ * Slide box sized to the ZOOMED slide footprint, matching the stage's own
78711
+ * `pptx-slide-canvas`. The inner canvas renders at the same `zoom` with
78712
+ * `autoFit` off, so the outgoing slide is pixel-for-pixel the size of the
78713
+ * incoming one for the whole animation.
78714
+ */
78334
78715
  slideBoxStyle = computed(() => {
78335
- const size = this.canvasSize();
78716
+ const box = transitionSlideBoxSize(this.canvasSize(), this.zoom());
78336
78717
  return {
78337
- width: `${Math.max(size.width, 1)}px`,
78338
- height: `${Math.max(size.height, 1)}px`,
78718
+ width: `${box.width}px`,
78719
+ height: `${box.height}px`,
78339
78720
  'transform-origin': 'center',
78340
78721
  };
78341
78722
  }, /* @ts-ignore */
@@ -78382,7 +78763,7 @@ class PresentationTransitionOverlayComponent {
78382
78763
  }
78383
78764
  }
78384
78765
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PresentationTransitionOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
78385
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: PresentationTransitionOverlayComponent, isStandalone: true, selector: "pptx-presentation-transition-overlay", inputs: { outgoingSlide: { classPropertyName: "outgoingSlide", publicName: "outgoingSlide", isSignal: true, isRequired: true, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, transition: { classPropertyName: "transition", publicName: "transition", isSignal: true, isRequired: true, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, durationMs: { classPropertyName: "durationMs", publicName: "durationMs", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { complete: "complete" }, host: { attributes: { "data-pptx-transition-overlay": "" } }, ngImport: i0, template: `
78766
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: PresentationTransitionOverlayComponent, isStandalone: true, selector: "pptx-presentation-transition-overlay", inputs: { outgoingSlide: { classPropertyName: "outgoingSlide", publicName: "outgoingSlide", isSignal: true, isRequired: true, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, transition: { classPropertyName: "transition", publicName: "transition", isSignal: true, isRequired: true, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, durationMs: { classPropertyName: "durationMs", publicName: "durationMs", isSignal: true, isRequired: false, transformFunction: null }, zoom: { classPropertyName: "zoom", publicName: "zoom", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { complete: "complete" }, host: { attributes: { "data-pptx-transition-overlay": "" } }, ngImport: i0, template: `
78386
78767
  <div
78387
78768
  class="pptx-ng-transition-layer"
78388
78769
  data-pptx-transition-layer="outgoing"
@@ -78393,7 +78774,8 @@ class PresentationTransitionOverlayComponent {
78393
78774
  [slide]="layerSlide()"
78394
78775
  [canvasSize]="canvasSize()"
78395
78776
  [mediaDataUrls]="mediaDataUrls()"
78396
- [zoom]="1"
78777
+ [zoom]="zoom()"
78778
+ [autoFit]="false"
78397
78779
  [interactive]="false"
78398
78780
  />
78399
78781
  </div>
@@ -78413,13 +78795,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
78413
78795
  [slide]="layerSlide()"
78414
78796
  [canvasSize]="canvasSize()"
78415
78797
  [mediaDataUrls]="mediaDataUrls()"
78416
- [zoom]="1"
78798
+ [zoom]="zoom()"
78799
+ [autoFit]="false"
78417
78800
  [interactive]="false"
78418
78801
  />
78419
78802
  </div>
78420
78803
  </div>
78421
78804
  `, styles: [":host{display:block;position:absolute;inset:0;overflow:hidden;pointer-events:none}.pptx-ng-transition-layer{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}\n"] }]
78422
- }], ctorParameters: () => [], propDecorators: { outgoingSlide: [{ type: i0.Input, args: [{ isSignal: true, alias: "outgoingSlide", required: true }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], transition: [{ type: i0.Input, args: [{ isSignal: true, alias: "transition", required: true }] }], templateElements: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateElements", required: false }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], durationMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "durationMs", required: false }] }], complete: [{ type: i0.Output, args: ["complete"] }] } });
78805
+ }], ctorParameters: () => [], propDecorators: { outgoingSlide: [{ type: i0.Input, args: [{ isSignal: true, alias: "outgoingSlide", required: true }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], transition: [{ type: i0.Input, args: [{ isSignal: true, alias: "transition", required: true }] }], templateElements: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateElements", required: false }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], durationMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "durationMs", required: false }] }], zoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoom", required: false }] }], complete: [{ type: i0.Output, args: ["complete"] }] } });
78423
78806
 
78424
78807
  /**
78425
78808
  * PresentationOverlayComponent: full-viewport black overlay that renders
@@ -78499,6 +78882,14 @@ class PresentationOverlayComponent {
78499
78882
  /** PowerPoint's Ctrl+M: hide ink markup without discarding the strokes. */
78500
78883
  inkMarkupVisible = signal(true, /* @ts-ignore */
78501
78884
  ...(ngDevMode ? [{ debugName: "inkMarkupVisible" }] : /* istanbul ignore next */ []));
78885
+ /**
78886
+ * True once the show has run past its last slide and the black "End of slide
78887
+ * show" screen is up. It MUST be surfaced: while it is up the next input
78888
+ * either goes nowhere (backward) or ends the show (forward), so a deck that
78889
+ * kept painting its last slide looked stuck and swallowed every advance.
78890
+ */
78891
+ endOfShow = signal(false, /* @ts-ignore */
78892
+ ...(ngDevMode ? [{ debugName: "endOfShow" }] : /* istanbul ignore next */ []));
78502
78893
  syncExternalIndex = effect(() => {
78503
78894
  const count = this.slides().length;
78504
78895
  if (count === 0) {
@@ -78959,6 +79350,12 @@ class PresentationOverlayComponent {
78959
79350
  }
78960
79351
  this.navigate('next');
78961
79352
  }
79353
+ /** Click on the end screen: exit the show, like PowerPoint's "click to exit". */
79354
+ onEndScreenClick(event) {
79355
+ event.stopPropagation();
79356
+ this.endOfShow.set(false);
79357
+ this.emitClosed();
79358
+ }
78962
79359
  /** Toggle an annotation tool (clicking the active one disarms it). */
78963
79360
  selectTool(tool) {
78964
79361
  this.annotations.setTool(tool);
@@ -79010,6 +79407,15 @@ class PresentationOverlayComponent {
79010
79407
  if (count === 0) {
79011
79408
  return;
79012
79409
  }
79410
+ // While the end screen is up a forward input ends the show (PowerPoint's
79411
+ // "click to exit") and a backward input just dismisses it.
79412
+ if (this.endOfShow()) {
79413
+ this.endOfShow.set(false);
79414
+ if (direction === 'next') {
79415
+ this.emitClosed();
79416
+ }
79417
+ return;
79418
+ }
79013
79419
  // On forward navigation, first reveal the next click-group of element
79014
79420
  // animations; only advance the slide once the slide's builds are exhausted.
79015
79421
  if (direction === 'next' && this.playback.advance()) {
@@ -79031,6 +79437,13 @@ class PresentationOverlayComponent {
79031
79437
  next = clampIndex(count - 1, count);
79032
79438
  break;
79033
79439
  }
79440
+ if (direction === 'next' && !hasVisibleSlideAfter(current, slides)) {
79441
+ // Nothing further to advance to. `nextVisibleIndex` would wrap back to
79442
+ // the first slide and loop for ever; PowerPoint only loops when "Loop
79443
+ // continuously until Esc" is set, so end the show instead.
79444
+ this.endOfShow.set(true);
79445
+ return;
79446
+ }
79034
79447
  if (next !== current) {
79035
79448
  // Play the incoming slide's transition (if any) over the new slide,
79036
79449
  // animating the outgoing slide out. Forward navigation only, matching
@@ -79091,6 +79504,21 @@ class PresentationOverlayComponent {
79091
79504
  {{ counterLabel() }}
79092
79505
  </span>
79093
79506
 
79507
+ <!-- Black "End of slide show" screen: the show has run past its last
79508
+ slide. It MUST be visible - while it is up the next input either
79509
+ goes nowhere (backward) or ends the show (forward), so a deck that
79510
+ kept painting the last slide looked stuck and swallowed advances. -->
79511
+ @if (endOfShow()) {
79512
+ <button
79513
+ type="button"
79514
+ class="pptx-ng-presentation-end"
79515
+ data-pptx-end-of-show
79516
+ (click)="onEndScreenClick($event)"
79517
+ >
79518
+ <span>{{ 'pptx.presentation.endOfSlideShow' | translate }}</span>
79519
+ </button>
79520
+ }
79521
+
79094
79522
  <div
79095
79523
  #stage
79096
79524
  class="pptx-ng-presentation-stage"
@@ -79116,6 +79544,7 @@ class PresentationOverlayComponent {
79116
79544
  [canvasSize]="canvasSize()"
79117
79545
  [transition]="t.transition"
79118
79546
  [mediaDataUrls]="mediaDataUrls()"
79547
+ [zoom]="zoom()"
79119
79548
  (complete)="activeTransition.set(null)"
79120
79549
  />
79121
79550
  }
@@ -79232,7 +79661,7 @@ class PresentationOverlayComponent {
79232
79661
  <svg lucideChevronRight class="h-6 w-6"></svg>
79233
79662
  </button>
79234
79663
  </div>
79235
- `, isInline: true, styles: [":host{display:block;position:fixed;inset:0;z-index:10000;background:#000;cursor:pointer;-webkit-user-select:none;user-select:none}.pptx-ng-presentation-root{position:absolute;inset:0;touch-action:pan-y}.pptx-ng-presentation-close:hover,.pptx-ng-presentation-nav:hover{background:#000000bf}.pptx-ng-presentation-tools{position:absolute;bottom:max(1rem,env(safe-area-inset-bottom));left:1rem;display:flex;gap:.25rem;padding:.25rem;border-radius:.5rem;background:#0000008c;z-index:80}.pptx-ng-presentation-tools button{width:2rem;height:2rem;border:none;border-radius:.35rem;background:transparent;color:#fff;font-size:1rem;cursor:pointer}.pptx-ng-presentation-tools button:hover{background:#ffffff26}.pptx-ng-presentation-tools button.is-active{background:#ffffff4d}.presenter-blank{position:absolute;inset:0;z-index:75}.presenter-laser{position:absolute;z-index:76;width:20px;height:20px;transform:translate(-50%,-50%);border-radius:50%;background:#ef4444;box-shadow:0 0 20px 8px #ef444488;pointer-events:none}.presenter-caption{position:absolute;z-index:77;left:10%;right:10%;bottom:2rem;padding:.75rem 1.5rem;border-radius:.5rem;background:#000c;color:#fff;text-align:center;font-size:1.25rem;pointer-events:none}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationTransitionOverlayComponent, selector: "pptx-presentation-transition-overlay", inputs: ["outgoingSlide", "canvasSize", "transition", "templateElements", "mediaDataUrls", "durationMs"], outputs: ["complete"] }, { kind: "component", type: PresentationAnnotationOverlayComponent, selector: "pptx-presentation-annotation-overlay", inputs: ["canvasSize", "zoom"] }, { kind: "component", type: PresentationSubtitleBarComponent, selector: "pptx-presentation-subtitle-bar", inputs: ["visible"] }, { kind: "component", type: LucidePenTool, selector: "svg[lucidePenTool]" }, { kind: "component", type: LucideHighlighter, selector: "svg[lucideHighlighter]" }, { kind: "component", type: LucideEraser, selector: "svg[lucideEraser]" }, { kind: "component", type: LucideMousePointer2, selector: "svg[lucideMousePointer2]" }, { kind: "component", type: LucideTrash2, selector: "svg[lucideTrash2]" }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
79664
+ `, isInline: true, styles: [":host{display:block;position:fixed;inset:0;z-index:10000;background:#000;cursor:pointer;-webkit-user-select:none;user-select:none}.pptx-ng-presentation-root{position:absolute;inset:0;touch-action:pan-y}.pptx-ng-presentation-close:hover,.pptx-ng-presentation-nav:hover{background:#000000bf}.pptx-ng-presentation-tools{position:absolute;bottom:max(1rem,env(safe-area-inset-bottom));left:1rem;display:flex;gap:.25rem;padding:.25rem;border-radius:.5rem;background:#0000008c;z-index:80}.pptx-ng-presentation-tools button{width:2rem;height:2rem;border:none;border-radius:.35rem;background:transparent;color:#fff;font-size:1rem;cursor:pointer}.pptx-ng-presentation-tools button:hover{background:#ffffff26}.pptx-ng-presentation-tools button.is-active{background:#ffffff4d}.presenter-blank{position:absolute;inset:0;z-index:75}.pptx-ng-presentation-end{position:absolute;inset:0;z-index:90;display:flex;align-items:flex-start;border:0;padding:0;background:#000;text-align:left;cursor:default}.pptx-ng-presentation-end span{padding:.75rem 1rem;color:#ffffffb3;font-size:12px}.presenter-laser{position:absolute;z-index:76;width:20px;height:20px;transform:translate(-50%,-50%);border-radius:50%;background:#ef4444;box-shadow:0 0 20px 8px #ef444488;pointer-events:none}.presenter-caption{position:absolute;z-index:77;left:10%;right:10%;bottom:2rem;padding:.75rem 1.5rem;border-radius:.5rem;background:#000c;color:#fff;text-align:center;font-size:1.25rem;pointer-events:none}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationTransitionOverlayComponent, selector: "pptx-presentation-transition-overlay", inputs: ["outgoingSlide", "canvasSize", "transition", "templateElements", "mediaDataUrls", "durationMs", "zoom"], outputs: ["complete"] }, { kind: "component", type: PresentationAnnotationOverlayComponent, selector: "pptx-presentation-annotation-overlay", inputs: ["canvasSize", "zoom"] }, { kind: "component", type: PresentationSubtitleBarComponent, selector: "pptx-presentation-subtitle-bar", inputs: ["visible"] }, { kind: "component", type: LucidePenTool, selector: "svg[lucidePenTool]" }, { kind: "component", type: LucideHighlighter, selector: "svg[lucideHighlighter]" }, { kind: "component", type: LucideEraser, selector: "svg[lucideEraser]" }, { kind: "component", type: LucideMousePointer2, selector: "svg[lucideMousePointer2]" }, { kind: "component", type: LucideTrash2, selector: "svg[lucideTrash2]" }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
79236
79665
  }
79237
79666
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PresentationOverlayComponent, decorators: [{
79238
79667
  type: Component,
@@ -79263,6 +79692,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
79263
79692
  {{ counterLabel() }}
79264
79693
  </span>
79265
79694
 
79695
+ <!-- Black "End of slide show" screen: the show has run past its last
79696
+ slide. It MUST be visible - while it is up the next input either
79697
+ goes nowhere (backward) or ends the show (forward), so a deck that
79698
+ kept painting the last slide looked stuck and swallowed advances. -->
79699
+ @if (endOfShow()) {
79700
+ <button
79701
+ type="button"
79702
+ class="pptx-ng-presentation-end"
79703
+ data-pptx-end-of-show
79704
+ (click)="onEndScreenClick($event)"
79705
+ >
79706
+ <span>{{ 'pptx.presentation.endOfSlideShow' | translate }}</span>
79707
+ </button>
79708
+ }
79709
+
79266
79710
  <div
79267
79711
  #stage
79268
79712
  class="pptx-ng-presentation-stage"
@@ -79288,6 +79732,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
79288
79732
  [canvasSize]="canvasSize()"
79289
79733
  [transition]="t.transition"
79290
79734
  [mediaDataUrls]="mediaDataUrls()"
79735
+ [zoom]="zoom()"
79291
79736
  (complete)="activeTransition.set(null)"
79292
79737
  />
79293
79738
  }
@@ -79404,7 +79849,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
79404
79849
  <svg lucideChevronRight class="h-6 w-6"></svg>
79405
79850
  </button>
79406
79851
  </div>
79407
- `, styles: [":host{display:block;position:fixed;inset:0;z-index:10000;background:#000;cursor:pointer;-webkit-user-select:none;user-select:none}.pptx-ng-presentation-root{position:absolute;inset:0;touch-action:pan-y}.pptx-ng-presentation-close:hover,.pptx-ng-presentation-nav:hover{background:#000000bf}.pptx-ng-presentation-tools{position:absolute;bottom:max(1rem,env(safe-area-inset-bottom));left:1rem;display:flex;gap:.25rem;padding:.25rem;border-radius:.5rem;background:#0000008c;z-index:80}.pptx-ng-presentation-tools button{width:2rem;height:2rem;border:none;border-radius:.35rem;background:transparent;color:#fff;font-size:1rem;cursor:pointer}.pptx-ng-presentation-tools button:hover{background:#ffffff26}.pptx-ng-presentation-tools button.is-active{background:#ffffff4d}.presenter-blank{position:absolute;inset:0;z-index:75}.presenter-laser{position:absolute;z-index:76;width:20px;height:20px;transform:translate(-50%,-50%);border-radius:50%;background:#ef4444;box-shadow:0 0 20px 8px #ef444488;pointer-events:none}.presenter-caption{position:absolute;z-index:77;left:10%;right:10%;bottom:2rem;padding:.75rem 1.5rem;border-radius:.5rem;background:#000c;color:#fff;text-align:center;font-size:1.25rem;pointer-events:none}\n"] }]
79852
+ `, styles: [":host{display:block;position:fixed;inset:0;z-index:10000;background:#000;cursor:pointer;-webkit-user-select:none;user-select:none}.pptx-ng-presentation-root{position:absolute;inset:0;touch-action:pan-y}.pptx-ng-presentation-close:hover,.pptx-ng-presentation-nav:hover{background:#000000bf}.pptx-ng-presentation-tools{position:absolute;bottom:max(1rem,env(safe-area-inset-bottom));left:1rem;display:flex;gap:.25rem;padding:.25rem;border-radius:.5rem;background:#0000008c;z-index:80}.pptx-ng-presentation-tools button{width:2rem;height:2rem;border:none;border-radius:.35rem;background:transparent;color:#fff;font-size:1rem;cursor:pointer}.pptx-ng-presentation-tools button:hover{background:#ffffff26}.pptx-ng-presentation-tools button.is-active{background:#ffffff4d}.presenter-blank{position:absolute;inset:0;z-index:75}.pptx-ng-presentation-end{position:absolute;inset:0;z-index:90;display:flex;align-items:flex-start;border:0;padding:0;background:#000;text-align:left;cursor:default}.pptx-ng-presentation-end span{padding:.75rem 1rem;color:#ffffffb3;font-size:12px}.presenter-laser{position:absolute;z-index:76;width:20px;height:20px;transform:translate(-50%,-50%);border-radius:50%;background:#ef4444;box-shadow:0 0 20px 8px #ef444488;pointer-events:none}.presenter-caption{position:absolute;z-index:77;left:10%;right:10%;bottom:2rem;padding:.75rem 1.5rem;border-radius:.5rem;background:#000c;color:#fff;text-align:center;font-size:1.25rem;pointer-events:none}\n"] }]
79408
79853
  }], ctorParameters: () => [], propDecorators: { slides: [{ type: i0.Input, args: [{ isSignal: true, alias: "slides", required: true }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], startIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "startIndex", required: false }] }], showWithAnimation: [{ type: i0.Input, args: [{ isSignal: true, alias: "showWithAnimation", required: false }] }], subtitlesVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitlesVisible", required: false }] }], indexChange: [{ type: i0.Output, args: ["indexChange"] }], closed: [{ type: i0.Output, args: ["closed"] }], subtitlesChange: [{ type: i0.Output, args: ["subtitlesChange"] }], annotationsExit: [{ type: i0.Output, args: ["annotationsExit"] }], stageRef: [{ type: i0.ViewChild, args: ['stage', { isSignal: true }] }], rootRef: [{ type: i0.ViewChild, args: ['root', { isSignal: true }] }], onFullscreenChange: [{
79409
79854
  type: HostListener,
79410
79855
  args: ['document:fullscreenchange']
@@ -79595,6 +80040,20 @@ class PresenterViewComponent {
79595
80040
  ...(ngDevMode ? [{ debugName: "progressValue" }] : /* istanbul ignore next */ []));
79596
80041
  slideBadge = computed(() => slideLabel(this.currentSlideIndex(), this.slides().length), /* @ts-ignore */
79597
80042
  ...(ngDevMode ? [{ debugName: "slideBadge" }] : /* istanbul ignore next */ []));
80043
+ /**
80044
+ * Clicking the current-slide pane advances the show, the way PowerPoint's
80045
+ * presenter console does: it is how presenters actually drive a deck, with
80046
+ * the Next button and the keyboard as fallbacks. A drawing tool owns the
80047
+ * pointer instead, so clicking then annotates rather than jumping the deck
80048
+ * out from under the stroke.
80049
+ */
80050
+ paneAdvancesOnClick = computed(() => presenterPaneAdvancesOnClick(this.presenterWindow.snapshot().pointer?.tool), /* @ts-ignore */
80051
+ ...(ngDevMode ? [{ debugName: "paneAdvancesOnClick" }] : /* istanbul ignore next */ []));
80052
+ onSlidePaneClick() {
80053
+ if (this.paneAdvancesOnClick()) {
80054
+ this.movePresentationSlide.emit(1);
80055
+ }
80056
+ }
79598
80057
  counterLabel = computed(() => slideCounter(this.currentSlideIndex(), this.slides().length), /* @ts-ignore */
79599
80058
  ...(ngDevMode ? [{ debugName: "counterLabel" }] : /* istanbul ignore next */ []));
79600
80059
  notesBodyStyle = computed(() => ({
@@ -79648,7 +80107,13 @@ class PresenterViewComponent {
79648
80107
  />
79649
80108
  <div class="pptx-ng-presenter-body">
79650
80109
  <!-- Current slide (≈70%) -->
79651
- <div class="pptx-ng-presenter-current">
80110
+ <div
80111
+ class="pptx-ng-presenter-current"
80112
+ [class.pptx-ng-presenter-current--advances]="paneAdvancesOnClick()"
80113
+ role="presentation"
80114
+ data-pptx-presenter-slide
80115
+ (click)="onSlidePaneClick()"
80116
+ >
79652
80117
  <div class="pptx-ng-presenter-preview-stage">
79653
80118
  <pptx-slide-canvas
79654
80119
  [slide]="currentPreviewSlide()"
@@ -79817,7 +80282,7 @@ class PresenterViewComponent {
79817
80282
  } @else {
79818
80283
  <div class="pptx-ng-presenter-empty">{{ 'pptx.presenter.noSlides' | translate }}</div>
79819
80284
  }
79820
- `, isInline: true, styles: [":host{position:absolute;inset:0;z-index:50;display:flex;flex-direction:column;background:#0b0b0c;color:#f5f5f5;font-family:system-ui,sans-serif}.pptx-ng-presenter-body{display:flex;flex:1 1 auto;min-height:0}.pptx-ng-presenter-current{flex:7 1 0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#000;padding:1rem;min-width:0}.pptx-ng-presenter-preview-stage{width:100%;max-width:100%;min-height:0}.pptx-ng-presenter-slide-badge{margin-top:.5rem;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.75rem;color:#ffffff80;-webkit-user-select:none;user-select:none}.pptx-ng-presenter-side{flex:3 1 0;display:flex;flex-direction:column;background:#18181b;border-left:1px solid rgba(255,255,255,.12);min-width:260px;max-width:440px}.pptx-ng-presenter-header,.pptx-ng-presenter-nav,.pptx-ng-presenter-next{padding:.5rem 1rem;border-bottom:1px solid rgba(255,255,255,.08)}.pptx-ng-presenter-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem}.pptx-ng-presenter-label{font-size:.625rem;text-transform:uppercase;letter-spacing:.06em;color:#ffffff8c}.pptx-ng-presenter-clock{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:1.125rem}.pptx-ng-presenter-elapsed{color:#6ea8fe}.pptx-ng-presenter-iconbtn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:6px;background:transparent;color:#ffffffb3;cursor:pointer;font-size:1rem;line-height:1}.pptx-ng-presenter-iconbtn:hover{background:#ffffff1a;color:#fff}.pptx-ng-presenter-iconbtn:disabled{opacity:.3;cursor:not-allowed}.pptx-ng-presenter-nav{display:flex;align-items:center;justify-content:space-between}.pptx-ng-presenter-navbtn{display:inline-flex;align-items:center;gap:.375rem;padding:.375rem .75rem;border:none;border-radius:6px;background:#ffffff14;color:#f5f5f5;cursor:pointer;font-size:.75rem}.pptx-ng-presenter-navbtn:hover:not(:disabled){background:#ffffff29}.pptx-ng-presenter-navbtn:disabled{opacity:.4;cursor:not-allowed}.pptx-ng-presenter-counter{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.875rem}.pptx-ng-presenter-next-empty{display:flex;align-items:center;justify-content:center;height:4rem;border:1px solid rgba(255,255,255,.15);border-radius:6px;background:#ffffff0a;font-size:.75rem;font-style:italic;color:#ffffff80}.pptx-ng-presenter-notes{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;padding:.75rem 1rem}.pptx-ng-presenter-notes-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:.5rem}.pptx-ng-presenter-notes-size{display:flex;align-items:center;gap:.25rem}.pptx-ng-presenter-notes-size-value{min-width:28px;text-align:center;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.625rem;color:#ffffff8c;-webkit-user-select:none;user-select:none}.pptx-ng-presenter-notes-body{flex:1 1 auto;overflow-y:auto;border:1px solid rgba(255,255,255,.15);border-radius:6px;background:#ffffff0a;padding:.5rem .75rem;white-space:pre-wrap;line-height:1.5}.pptx-ng-presenter-notes-empty{font-style:italic;color:#ffffff80}.pptx-ng-presenter-progress{height:6px;width:100%;background:#ffffff1f;flex:0 0 auto}.pptx-ng-presenter-progress-fill{height:100%;background:#6ea8fe;transition:width 1s linear}.pptx-ng-presenter-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#fff9}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresenterControlsComponent, selector: "pptx-presenter-controls", inputs: ["snapshot", "audienceOpen", "slides", "current", "canvasSize", "mediaDataUrls"], outputs: ["patch", "navigate", "audience", "end"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
80285
+ `, isInline: true, styles: [":host{position:absolute;inset:0;z-index:50;display:flex;flex-direction:column;background:var(--pptx-card, #0b0b0c);color:var(--pptx-foreground, #f5f5f5);font-family:system-ui,sans-serif}.pptx-ng-presenter-body{display:flex;flex:1 1 auto;min-height:0}.pptx-ng-presenter-current--advances{cursor:pointer}.pptx-ng-presenter-current{flex:7 1 0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#000;padding:1rem;min-width:0}.pptx-ng-presenter-preview-stage{width:100%;max-width:100%;min-height:0}.pptx-ng-presenter-slide-badge{margin-top:.5rem;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.75rem;color:#ffffff80;-webkit-user-select:none;user-select:none}.pptx-ng-presenter-side{flex:3 1 0;display:flex;flex-direction:column;background:var(--pptx-background, #18181b);border-left:1px solid var(--pptx-border, rgba(255, 255, 255, .12));min-width:260px;max-width:440px}.pptx-ng-presenter-header,.pptx-ng-presenter-nav,.pptx-ng-presenter-next{padding:.5rem 1rem;border-bottom:1px solid var(--pptx-border, rgba(255, 255, 255, .12))}.pptx-ng-presenter-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem}.pptx-ng-presenter-label{font-size:.625rem;text-transform:uppercase;letter-spacing:.06em;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .55))}.pptx-ng-presenter-clock{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:1.125rem}.pptx-ng-presenter-elapsed{color:var(--pptx-primary, #6ea8fe)}.pptx-ng-presenter-iconbtn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:6px;background:transparent;color:var(--pptx-foreground, rgba(255, 255, 255, .7));cursor:pointer;font-size:1rem;line-height:1}.pptx-ng-presenter-iconbtn:hover{background:var(--pptx-secondary, rgba(255, 255, 255, .1));color:#fff}.pptx-ng-presenter-iconbtn:disabled{opacity:.3;cursor:not-allowed}.pptx-ng-presenter-nav{display:flex;align-items:center;justify-content:space-between}.pptx-ng-presenter-navbtn{display:inline-flex;align-items:center;gap:.375rem;padding:.375rem .75rem;border:none;border-radius:6px;background:var(--pptx-secondary, rgba(255, 255, 255, .08));color:var(--pptx-foreground, #f5f5f5);cursor:pointer;font-size:.75rem}.pptx-ng-presenter-navbtn:hover:not(:disabled){background:#ffffff29}.pptx-ng-presenter-navbtn:disabled{opacity:.4;cursor:not-allowed}.pptx-ng-presenter-counter{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.875rem}.pptx-ng-presenter-next-empty{display:flex;align-items:center;justify-content:center;height:4rem;border:1px solid var(--pptx-border, rgba(255, 255, 255, .12));border-radius:6px;background:var(--pptx-muted, rgba(255, 255, 255, .04));font-size:.75rem;font-style:italic;color:#ffffff80}.pptx-ng-presenter-notes{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;padding:.75rem 1rem}.pptx-ng-presenter-notes-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:.5rem}.pptx-ng-presenter-notes-size{display:flex;align-items:center;gap:.25rem}.pptx-ng-presenter-notes-size-value{min-width:28px;text-align:center;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.625rem;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .55));-webkit-user-select:none;user-select:none}.pptx-ng-presenter-notes-body{flex:1 1 auto;overflow-y:auto;border:1px solid var(--pptx-border, rgba(255, 255, 255, .12));border-radius:6px;background:var(--pptx-muted, rgba(255, 255, 255, .04));padding:.5rem .75rem;white-space:pre-wrap;line-height:1.5}.pptx-ng-presenter-notes-empty{font-style:italic;color:#ffffff80}.pptx-ng-presenter-progress{height:6px;width:100%;background:#ffffff1f;flex:0 0 auto}.pptx-ng-presenter-progress-fill{height:100%;background:#6ea8fe;transition:width 1s linear}.pptx-ng-presenter-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#fff9}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresenterControlsComponent, selector: "pptx-presenter-controls", inputs: ["snapshot", "audienceOpen", "slides", "current", "canvasSize", "mediaDataUrls"], outputs: ["patch", "navigate", "audience", "end"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
79821
80286
  }
79822
80287
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PresenterViewComponent, decorators: [{
79823
80288
  type: Component,
@@ -79837,7 +80302,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
79837
80302
  />
79838
80303
  <div class="pptx-ng-presenter-body">
79839
80304
  <!-- Current slide (≈70%) -->
79840
- <div class="pptx-ng-presenter-current">
80305
+ <div
80306
+ class="pptx-ng-presenter-current"
80307
+ [class.pptx-ng-presenter-current--advances]="paneAdvancesOnClick()"
80308
+ role="presentation"
80309
+ data-pptx-presenter-slide
80310
+ (click)="onSlidePaneClick()"
80311
+ >
79841
80312
  <div class="pptx-ng-presenter-preview-stage">
79842
80313
  <pptx-slide-canvas
79843
80314
  [slide]="currentPreviewSlide()"
@@ -80006,7 +80477,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
80006
80477
  } @else {
80007
80478
  <div class="pptx-ng-presenter-empty">{{ 'pptx.presenter.noSlides' | translate }}</div>
80008
80479
  }
80009
- `, styles: [":host{position:absolute;inset:0;z-index:50;display:flex;flex-direction:column;background:#0b0b0c;color:#f5f5f5;font-family:system-ui,sans-serif}.pptx-ng-presenter-body{display:flex;flex:1 1 auto;min-height:0}.pptx-ng-presenter-current{flex:7 1 0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#000;padding:1rem;min-width:0}.pptx-ng-presenter-preview-stage{width:100%;max-width:100%;min-height:0}.pptx-ng-presenter-slide-badge{margin-top:.5rem;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.75rem;color:#ffffff80;-webkit-user-select:none;user-select:none}.pptx-ng-presenter-side{flex:3 1 0;display:flex;flex-direction:column;background:#18181b;border-left:1px solid rgba(255,255,255,.12);min-width:260px;max-width:440px}.pptx-ng-presenter-header,.pptx-ng-presenter-nav,.pptx-ng-presenter-next{padding:.5rem 1rem;border-bottom:1px solid rgba(255,255,255,.08)}.pptx-ng-presenter-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem}.pptx-ng-presenter-label{font-size:.625rem;text-transform:uppercase;letter-spacing:.06em;color:#ffffff8c}.pptx-ng-presenter-clock{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:1.125rem}.pptx-ng-presenter-elapsed{color:#6ea8fe}.pptx-ng-presenter-iconbtn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:6px;background:transparent;color:#ffffffb3;cursor:pointer;font-size:1rem;line-height:1}.pptx-ng-presenter-iconbtn:hover{background:#ffffff1a;color:#fff}.pptx-ng-presenter-iconbtn:disabled{opacity:.3;cursor:not-allowed}.pptx-ng-presenter-nav{display:flex;align-items:center;justify-content:space-between}.pptx-ng-presenter-navbtn{display:inline-flex;align-items:center;gap:.375rem;padding:.375rem .75rem;border:none;border-radius:6px;background:#ffffff14;color:#f5f5f5;cursor:pointer;font-size:.75rem}.pptx-ng-presenter-navbtn:hover:not(:disabled){background:#ffffff29}.pptx-ng-presenter-navbtn:disabled{opacity:.4;cursor:not-allowed}.pptx-ng-presenter-counter{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.875rem}.pptx-ng-presenter-next-empty{display:flex;align-items:center;justify-content:center;height:4rem;border:1px solid rgba(255,255,255,.15);border-radius:6px;background:#ffffff0a;font-size:.75rem;font-style:italic;color:#ffffff80}.pptx-ng-presenter-notes{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;padding:.75rem 1rem}.pptx-ng-presenter-notes-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:.5rem}.pptx-ng-presenter-notes-size{display:flex;align-items:center;gap:.25rem}.pptx-ng-presenter-notes-size-value{min-width:28px;text-align:center;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.625rem;color:#ffffff8c;-webkit-user-select:none;user-select:none}.pptx-ng-presenter-notes-body{flex:1 1 auto;overflow-y:auto;border:1px solid rgba(255,255,255,.15);border-radius:6px;background:#ffffff0a;padding:.5rem .75rem;white-space:pre-wrap;line-height:1.5}.pptx-ng-presenter-notes-empty{font-style:italic;color:#ffffff80}.pptx-ng-presenter-progress{height:6px;width:100%;background:#ffffff1f;flex:0 0 auto}.pptx-ng-presenter-progress-fill{height:100%;background:#6ea8fe;transition:width 1s linear}.pptx-ng-presenter-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#fff9}\n"] }]
80480
+ `, styles: [":host{position:absolute;inset:0;z-index:50;display:flex;flex-direction:column;background:var(--pptx-card, #0b0b0c);color:var(--pptx-foreground, #f5f5f5);font-family:system-ui,sans-serif}.pptx-ng-presenter-body{display:flex;flex:1 1 auto;min-height:0}.pptx-ng-presenter-current--advances{cursor:pointer}.pptx-ng-presenter-current{flex:7 1 0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#000;padding:1rem;min-width:0}.pptx-ng-presenter-preview-stage{width:100%;max-width:100%;min-height:0}.pptx-ng-presenter-slide-badge{margin-top:.5rem;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.75rem;color:#ffffff80;-webkit-user-select:none;user-select:none}.pptx-ng-presenter-side{flex:3 1 0;display:flex;flex-direction:column;background:var(--pptx-background, #18181b);border-left:1px solid var(--pptx-border, rgba(255, 255, 255, .12));min-width:260px;max-width:440px}.pptx-ng-presenter-header,.pptx-ng-presenter-nav,.pptx-ng-presenter-next{padding:.5rem 1rem;border-bottom:1px solid var(--pptx-border, rgba(255, 255, 255, .12))}.pptx-ng-presenter-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem}.pptx-ng-presenter-label{font-size:.625rem;text-transform:uppercase;letter-spacing:.06em;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .55))}.pptx-ng-presenter-clock{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:1.125rem}.pptx-ng-presenter-elapsed{color:var(--pptx-primary, #6ea8fe)}.pptx-ng-presenter-iconbtn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:6px;background:transparent;color:var(--pptx-foreground, rgba(255, 255, 255, .7));cursor:pointer;font-size:1rem;line-height:1}.pptx-ng-presenter-iconbtn:hover{background:var(--pptx-secondary, rgba(255, 255, 255, .1));color:#fff}.pptx-ng-presenter-iconbtn:disabled{opacity:.3;cursor:not-allowed}.pptx-ng-presenter-nav{display:flex;align-items:center;justify-content:space-between}.pptx-ng-presenter-navbtn{display:inline-flex;align-items:center;gap:.375rem;padding:.375rem .75rem;border:none;border-radius:6px;background:var(--pptx-secondary, rgba(255, 255, 255, .08));color:var(--pptx-foreground, #f5f5f5);cursor:pointer;font-size:.75rem}.pptx-ng-presenter-navbtn:hover:not(:disabled){background:#ffffff29}.pptx-ng-presenter-navbtn:disabled{opacity:.4;cursor:not-allowed}.pptx-ng-presenter-counter{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.875rem}.pptx-ng-presenter-next-empty{display:flex;align-items:center;justify-content:center;height:4rem;border:1px solid var(--pptx-border, rgba(255, 255, 255, .12));border-radius:6px;background:var(--pptx-muted, rgba(255, 255, 255, .04));font-size:.75rem;font-style:italic;color:#ffffff80}.pptx-ng-presenter-notes{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;padding:.75rem 1rem}.pptx-ng-presenter-notes-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:.5rem}.pptx-ng-presenter-notes-size{display:flex;align-items:center;gap:.25rem}.pptx-ng-presenter-notes-size-value{min-width:28px;text-align:center;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.625rem;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .55));-webkit-user-select:none;user-select:none}.pptx-ng-presenter-notes-body{flex:1 1 auto;overflow-y:auto;border:1px solid var(--pptx-border, rgba(255, 255, 255, .12));border-radius:6px;background:var(--pptx-muted, rgba(255, 255, 255, .04));padding:.5rem .75rem;white-space:pre-wrap;line-height:1.5}.pptx-ng-presenter-notes-empty{font-style:italic;color:#ffffff80}.pptx-ng-presenter-progress{height:6px;width:100%;background:#ffffff1f;flex:0 0 auto}.pptx-ng-presenter-progress-fill{height:100%;background:#6ea8fe;transition:width 1s linear}.pptx-ng-presenter-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#fff9}\n"] }]
80010
80481
  }], ctorParameters: () => [], propDecorators: { slides: [{ type: i0.Input, args: [{ isSignal: true, alias: "slides", required: true }] }], currentSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentSlideIndex", required: true }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], templateElements: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateElements", required: false }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], presentationStartTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "presentationStartTime", required: false }] }], isAudienceWindowOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "isAudienceWindowOpen", required: false }] }], movePresentationSlide: [{ type: i0.Output, args: ["movePresentationSlide"] }], exit: [{ type: i0.Output, args: ["exit"] }], openAudienceWindow: [{ type: i0.Output, args: ["openAudienceWindow"] }], closeAudienceWindow: [{ type: i0.Output, args: ["closeAudienceWindow"] }], navigateToSlide: [{ type: i0.Output, args: ["navigateToSlide"] }] } });
80011
80482
 
80012
80483
  /**
@@ -84044,7 +84515,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
84044
84515
  }], propDecorators: { canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }] } });
84045
84516
 
84046
84517
  // Generated by scripts/inline-shared.mjs from package.json. Do not edit.
84047
- const PPTX_ANGULAR_VIEWER_VERSION = "2.2.0";
84518
+ const PPTX_ANGULAR_VIEWER_VERSION = "2.3.0";
84048
84519
 
84049
84520
  /**
84050
84521
  * account-page.component.ts: File > Account content.
@@ -94352,7 +94823,9 @@ class GradientPickerComponent {
94352
94823
  if (s.type === 'radial') {
94353
94824
  return `radial-gradient(circle, ${stopsCss})`;
94354
94825
  }
94355
- return `linear-gradient(${s.angle}deg, ${stopsCss})`;
94826
+ // `state.angle` is the authored OOXML angle, so the preview strip has to
94827
+ // convert it the same way the canvas renderer does or it lies by 90deg.
94828
+ return `linear-gradient(${ooxmlGradientAngleToCssDegrees(s.angle)}deg, ${stopsCss})`;
94356
94829
  }, /* @ts-ignore */
94357
94830
  ...(ngDevMode ? [{ debugName: "previewCss" }] : /* istanbul ignore next */ []));
94358
94831
  // ── Type ─────────────────────────────────────────────────────────────────
@@ -96864,6 +97337,10 @@ function evenRowHeights(td) {
96864
97337
  /**
96865
97338
  * Build a CSS gradient string from structured cell-style gradient fields, so
96866
97339
  * the renderer (which reads `gradientFillCss`) shows an edited gradient live.
97340
+ *
97341
+ * `angle` is `PptxTableCellStyle.gradientFillAngle`, stored in the OOXML
97342
+ * `a:lin/@ang` convention (clockwise from +x) so it round-trips to the file
97343
+ * unchanged; CSS measures clockwise from "to top", a quarter turn away.
96867
97344
  */
96868
97345
  function buildGradientFillCss(stops, type, angle) {
96869
97346
  const ordered = [...stops].sort((a, b) => a.position - b.position);
@@ -96871,7 +97348,7 @@ function buildGradientFillCss(stops, type, angle) {
96871
97348
  if (type === 'radial') {
96872
97349
  return `radial-gradient(circle, ${parts})`;
96873
97350
  }
96874
- return `linear-gradient(${Math.round(angle)}deg, ${parts})`;
97351
+ return `linear-gradient(${Math.round(ooxmlGradientAngleToCssDegrees(angle))}deg, ${parts})`;
96875
97352
  }
96876
97353
 
96877
97354
  /**
@@ -112857,5 +113334,5 @@ function cn(...values) {
112857
113334
  * Generated bundle index. Do not edit.
112858
113335
  */
112859
113336
 
112860
- export { DATA_TABLE_KEY_W as $, ALIGN_OPTIONS as A, BroadcastDialogComponent as B, CHART_EDITOR_STYLES as C, ChartAxisOptionsComponent as D, ChartAxisStyleOptionsComponent as E, ChartComboTypeOptionsComponent as F, ChartDataEditorComponent as G, ChartDataLabelOptionsComponent as H, ChartDatapointOptionsComponent as I, ChartDisplayOptionsComponent as J, ChartElementViewComponent as K, ChartErrorBarOptionsComponent as L, ChartMarkerOptionsComponent as M, ChartPartSelectionService as N, ChartPrimitivesComponent as O, ChartRendererComponent as P, ChartTrendlineOptionsComponent as Q, CollaborationCursorsComponent as R, CollaborationService as S, ColorChangedImageComponent as T, CommentsPanelComponent as U, CommentsService as V, ComparePanelComponent as W, ConnectorRendererComponent as X, ConnectorTextOverlayComponent as Y, CustomShowsComponent as Z, DATA_TABLE_HEADER_H as _, AUDIENCE_HASH as a, MIN_ZOOM_SCALE as a$, DATA_TABLE_PADDING as a0, DATA_TABLE_ROW_H as a1, DEFAULT_BOUNDS as a2, DEFAULT_BROADCAST_SERVER_URL as a3, DEFAULT_CANVAS_HEIGHT as a4, DEFAULT_CANVAS_WIDTH as a5, DEFAULT_COLOR_SCHEME as a6, DEFAULT_FILL_COLOR as a7, DEFAULT_LAYOUT as a8, DEFAULT_PALETTE$1 as a9, ExportProgressModalComponent as aA, ExportService as aB, FieldContextService as aC, FindBarComponent as aD, FindReplaceBarComponent as aE, FollowModeBarComponent as aF, FontEmbeddingListComponent as aG, FontEmbeddingPanelComponent as aH, GALLERY_THEME_PRESETS as aI, GradientPickerComponent as aJ, HANDOUT_OPTIONS as aK, HeaderFooterDialogComponent as aL, HyperlinkDialogComponent as aM, ImagePropertiesPanelComponent as aN, InkDrawingService as aO, InkRendererComponent as aP, InsertSmartArtDialogComponent as aQ, InspectorPaneHeaderComponent as aR, InspectorPanelComponent as aS, IsMobileService as aT, KeepAnnotationsDialogComponent as aU, LOCALE_CATALOG as aV, LONG_PRESS_DURATION_MS as aW, LONG_PRESS_MOVE_TOLERANCE_PX as aX, LoadContentService as aY, LocalPresencePublisher as aZ, MAX_ZOOM_SCALE as a_, DEFAULT_PRINT_SETTINGS as aa, DEFAULT_SLIDE_BACKGROUND as ab, DEFAULT_STROKE_COLOR as ac, DEFAULT_STYLE as ad, DEFAULT_TABLE_ROW_HEIGHT as ae, DEFAULT_TEXT_COLOR$1 as af, DEFAULT_VIEWER_PROFILE as ag, DIRECTIONAL_PRESETS as ah, DIRECTION_OPTIONS as ai, DocumentPropertiesCardComponent as aj, EMBEDDED_FONTS_STYLE_ID as ak, EMPHASIS_PRESETS as al, ENTRANCE_PRESETS as am, TEMPLATES as an, EXIT_PRESETS as ao, EditorContextMenuComponent as ap, EditorHistory as aq, EditorStateService as ar, EditorToolbarComponent as as, EffectsPanelComponent as at, ElementRendererComponent as au, EmbeddedFontsService as av, EncryptedFileDialogComponent as aw, EquationEditorDialogComponent as ax, EquationRendererComponent as ay, EquationTemplateGalleryComponent as az, AUDIENCE_NONCE_KEY as b, SLIDE_PX_PER_INCH as b$, MediaPreviewComponent as b0, MediaPropertiesPanelComponent as b1, MediaRendererComponent as b2, MediaTrimTimelineComponent as b3, MobileBottomBarComponent as b4, MobileMenuSheetComponent as b5, MobilePresenterViewComponent as b6, MobileSheetComponent as b7, MobileSlidesSheetComponent as b8, MobileToolbarComponent as b9, RESIZE_HANDLES as bA, RULER_THICKNESS as bB, RemoteSelectionOverlayComponent as bC, RibbonAnimationsSectionComponent as bD, RibbonArrangeSectionComponent as bE, RibbonColorPopoverComponent as bF, RibbonComponent as bG, RibbonDesignSectionComponent as bH, RibbonDrawSectionComponent as bI, RibbonDrawingGroupComponent as bJ, RibbonEditingSectionComponent as bK, RibbonFileSectionComponent as bL, RibbonFontControlsComponent as bM, RibbonHomeSectionComponent as bN, RibbonInsertFieldsComponent as bO, RibbonInsertSectionComponent as bP, RibbonParagraphControlsComponent as bQ, RibbonPrimaryRowComponent as bR, RibbonReviewSectionComponent as bS, RibbonSlideshowSectionComponent as bT, RibbonTransitionsSectionComponent as bU, RibbonViewSectionComponent as bV, RulerGuidesService as bW, SEQUENCE_OPTIONS as bX, SEVERITY_GROUPS as bY, SEVERITY_LABELS as bZ, SHORTCUT_REFERENCE_ITEMS as b_, ModalDialogComponent as ba, Model3DRendererComponent as bb, NotesHandoutCardComponent as bc, NotesPanelComponent as bd, NotesToolbarComponent as be, OleRendererComponent as bf, POWER_POINT_VIEWER_PROVIDERS as bg, PRESENTER_CHANNEL_NAME as bh, PRESENTER_MSG_ORIGIN as bi, PasswordProtectionDialogComponent as bj, PasswordStrengthMeterComponent as bk, PowerPointViewerComponent as bl, PresentationAnnotationOverlayComponent as bm, PresentationAnnotationsService as bn, PresentationOverlayComponent as bo, PresentationPropertiesPanelComponent as bp, PresentationSettingsCardComponent as bq, PresentationSubtitleBarComponent as br, PresentationTransitionOverlayComponent as bs, PresenterViewComponent as bt, PresenterWindowService as bu, PrintDialogComponent as bv, PrintService as bw, PrintSettingsPanelComponent as bx, PropertiesDialogComponent as by, REPEAT_MODE_OPTIONS as bz, AVATAR_COLOR_SWATCHES as c, ViewerDocumentPropertiesService as c$, SLIDE_TRANSITION_KEYFRAMES as c0, DEFAULT_PALETTE as c1, PALETTES$1 as c2, SMART_ART_COLOR_SCHEMES as c3, SMART_ART_STYLE_OPTIONS as c4, SUB_ITEM_LABEL as c5, SVG_WARP_PRESETS as c6, SWIPE_MAX_VERTICAL_PX as c7, SWIPE_THRESHOLD_PX as c8, SelectionPaneComponent as c9, TABLE_STRUCTURE_TOGGLES as cA, TEXT_DIRECTION_OPTIONS$1 as cB, THEME_CATALOG as cC, TIMING_CURVE_OPTIONS as cD, TRIGGER_OPTIONS as cE, TYPE_LABELS as cF, TableCellAdvancedFillComponent as cG, TableCellFormattingComponent as cH, TableDataEditorComponent as cI, TablePropertiesComponent as cJ, TableRendererComponent as cK, TableResizeOverlayComponent as cL, TableSelectionService as cM, TextAdvancedPanelComponent as cN, ThemeEditorFieldsComponent as cO, ThemeGalleryComponent as cP, ThemeSelectorCardComponent as cQ, TitleBarComponent as cR, VALIGN_OPTIONS as cS, VIEWER_THEME as cT, VersionHistoryPanelComponent as cU, ViewerCanvasEditingService as cV, ViewerCollabCursorService as cW, ViewerCollaborationSessionService as cX, ViewerCompareService as cY, ViewerCustomShowsService as cZ, ViewerDialogsService as c_, SetUpSlideShowDialogComponent as ca, SettingsAppearanceTabComponent as cb, SettingsDialogComponent as cc, SettingsLanguageTabComponent as cd, ShareDialogComponent as ce, ShortcutPanelComponent as cf, ShowOptionsFieldsetComponent as cg, ShowSlidesFieldsetComponent as ch, SignatureStrippedDialogComponent as ci, SignaturesPanelComponent as cj, SignaturesService as ck, SlideCanvasComponent as cl, SlideDefaultInspectorComponent as cm, SlideDiffChangesComponent as cn, SlideDiffRowComponent as co, SlideDiffThumbnailsComponent as cp, SlideSizeCardComponent as cq, SlideSorterOverlayComponent as cr, SlideThemeOverridePanelComponent as cs, SlidesPanelComponent as ct, SmartArt3DRendererComponent as cu, SmartArt3DService as cv, SmartArtPreviewComponent as cw, SmartArtPropertiesComponent as cx, SmartArtRendererComponent as cy, StatusBarComponent as cz, AccessibilityPanelComponent as d, buildFallbackViewModel as d$, ViewerExportService as d0, ViewerExtraDialogsComponent as d1, ViewerFileIOService as d2, ViewerFindReplaceService as d3, ViewerFormatPainterService as d4, ViewerInspectorPanelService as d5, ViewerKeyboardService as d6, ViewerMobileSheetService as d7, ViewerPresentationModeService as d8, ViewerThemeGalleryService as d9, asMediaElement as dA, assignUserColor as dB, attachTouchGestures as dC, beginNodeEdit as dD, boolFromEvent as dE, bringForward as dF, bringToFront as dG, buildBarActions as dH, buildBroadcastConfig as dI, buildBroadcastViewerUrl as dJ, buildCategoryLabels as dK, buildCellParagraphs as dL, buildChartViewModel as dM, buildChatLogExport as dN, buildChatLogMarkdown as dO, buildChromeStyle as dP, buildClearHyperlinkPatch as dQ, buildClickGroups as dR, buildColStyles as dS, buildCollaborationConfig as dT, buildComboViewModel as dU, buildCssGradientFromShapeStyle as dV, buildDuotoneFilter as dW, buildDuotoneFilterId as dX, buildEmbeddedFontStyles as dY, buildEquationElement as dZ, buildEquationSegment as d_, ViewerTouchGesturesService as da, ViewerZoomService as db, WEBM_MIME_CANDIDATES as dc, WriteBackScheduler as dd, ZoomNavigationService as de, ZoomRendererComponent as df, ZoomTargetService as dg, addCategory as dh, addCommentToList as di, addGradientStopPatch as dj, addItem as dk, addSeries as dl, addSubItem as dm, advanceStep as dn, aiToggleVisible as dp, alignPatch as dq, animationFor as dr, annotationMapToInkInserts as ds, applyAcceptedDiff as dt, applyAnimationPreset as du, applyFindReplacements as dv, applyFormatToElement as dw, applyMove as dx, applyResize as dy, applyTableStylePreset as dz, AccessibilityService as e, computeDataTablePrimitives as e$, buildFontFaceRule as e0, buildGradientFillCss as e1, buildGridlinesAndLabels as e2, buildHyperlinkPatch as e3, buildInkContainerStyle as e4, buildInkStrokes as e5, buildLegend as e6, buildModel3DContainerStyle as e7, buildModel3DViewModel as e8, buildOleActionModel as e9, cellStyleToStyleMap as eA, cellTdStyle as eB, changeCountLabel as eC, changeIcon as eD, characterSpacingPatch as eE, checkFontAvailable as eF, clampCursorPosition as eG, clampGifDimensions as eH, clampIndex as eI, clampNotesFontSize as eJ, clampScale as eK, clampStep as eL, clearAllLocalViewerData as eM, clearAudienceContent as eN, cn as eO, collectAccessibilityIssues as eP, collectElementText as eQ, collectSlideText as eR, collectStoredChats as eS, collectUsedFontFamilies as eT, columnWidthStyle as eU, commitNodeText as eV, computeAlign as eW, computeAxisTitlePrimitives as eX, computeBarRects as eY, computeBubbleRadius as eZ, computeCornerHandle as e_, buildOleInfoRows as ea, buildPatternFillCss as eb, buildPrintHtmlDocument as ec, buildPropertiesPatch as ed, buildRegionMapViewModel as ee, buildSaveSlides as ef, buildShareUrl as eg, buildSmartArtInsertElement as eh, buildSmartArtNodes as ei, buildStockViewModel as ej, buildSurfaceViewModel as ek, buildTableViewModel as el, buildTreemapViewModel as em, buildTrimFragment as en, buildWaterfallViewModel as eo, buildZeroLine as ep, buildZoomContainerStyle as eq, buildZoomViewModel as er, bulletIndentPx as es, canAddTopLevelNode as et, canRemoveTopLevelNode as eu, canStartBroadcast as ev, canStartShare as ew, canUseClipboard as ex, captionDisplayText as ey, cellRunStyle as ez, AccountPageComponent as f, encodeGif as f$, computeDistribute as f0, computeDrawingViewBox as f1, computeErrorBarPrimitives as f2, computeFocusTargets as f3, computeHandleBoxes as f4, computeHandoutLayout as f5, computeIsMobile as f6, computeIsTablet as f7, computeLinePoints as f8, computeLinearRegression as f9, createWebsocketBundle as fA, cssObjectToStyleMap as fB, currentColorScheme as fC, currentLayout as fD, currentStyle as fE, defaultCssVars as fF, defaultRadius as fG, defaultThemeColors as fH, deleteElementsByIds as fI, deleteVersion as fJ, demoteNode as fK, deriveModel3DBlobUrl as fL, derivePresenceList as fM, describeSmartArtBounds as fN, disableGlowPatch as fO, disableInnerShadowPatch as fP, disableOuterShadowPatch as fQ, disableReflectionPatch as fR, disableSoftEdgePatch as fS, duplicateElementById as fT, durationOf as fU, effectsStateOf as fV, enableGlowPatch as fW, enableInnerShadowPatch as fX, enableOuterShadowPatch as fY, enableReflectionPatch as fZ, enableSoftEdgePatch as f_, computePageCount as fa, computePieLayout as fb, computePieSlicePath as fc, computePieSlices as fd, computePlotLayout as fe, computeRSquared as ff, computeRadarPoints as fg, computeScatterDots as fh, computeSelectionBoxes as fi, computeSingleSelected as fj, computeSlideIndices as fk, computeSnap as fl, computeStackedBarRects as fm, computeStackedValueRange as fn, computeTextLines as fo, computeTimerProgress as fp, computeTrendlinePrimitives as fq, computeValueRange as fr, convertOmmlToMathMl as fs, copyFormatFromElement as ft, countAccessibilityIssues as fu, countAnnotationStrokes as fv, createAngularAiBridge as fw, createCustomShow as fx, createSwipeDismissDrag as fy, createWebrtcBundle as fz, ActionSettingsPanelComponent as g, hasAnimation as g$, estimatePageCount as g0, evenColumnWidths as g1, evenRowHeights as g2, exitPresentationFullscreen as g3, exportAiChatLogs as g4, extractPathPoints as g5, eyedropperAvailable as g6, fillColorOf as g7, findInSlides as g8, findOwningSlideIndex as g9, getOleBadgeLabel as gA, getOleDisplayName as gB, getOleDownloadFileName as gC, getOleTypeColor as gD, getOleTypeLabel as gE, getPasswordStrength as gF, getPatternSvg as gG, getPlaceholderStyle as gH, getVersions as gI, getResolvedShapeClipPath as gJ, getResolvedShapeClipPathFor as gK, getShapeFillStrokeStyle as gL, getSlideBackgroundStyle as gM, getSlideTransitionAnimations as gN, getSmartArtNodeBounds as gO, getSpeechRecognitionCtor as gP, getTextBlockStyle as gQ, getTextWarp as gR, getTouchDistance as gS, getWarpCategory as gT, getWarpPath as gU, gradientStateFromStyle as gV, gradientStateOf as gW, gradientStatePatch as gX, gridColumns as gY, groupElements as gZ, groupIssuesBySeverity as g_, findSlideIndexByElementId as ga, fitPolynomial as gb, fitZoom as gc, focusTargetChips as gd, fontMimeForFormat as ge, fontSizeOf as gf, formatAutoNumber as gg, formatAxisValue as gh, formatBytes as gi, formatCursorLabel as gj, formatElapsed as gk, formatFileSize as gl, formatPropertyDate as gm, formatTime as gn, fpsToFrameIntervalMs as go, generateBroadcastRoomId as gp, generateCommentId as gq, generateCustomShowId as gr, generatePressureCircles as gs, generateRulerTicks as gt, getClrChangeParams as gu, getContainerStyle as gv, getDuotoneFilterDef as gw, getImageSrc as gx, getLocalStorageUsageSummary as gy, getOleAriaLabel as gz, AdvancedChartEditorComponent as h, numFromEvent as h$, hasCopyableFormat as h0, hasExistingLink as h1, hasExitedFullscreen as h2, hasGradientFill as h3, hasPressureVariation as h4, headerLabel as h5, inkViewBox as h6, insertColumn as h7, insertRow as h8, interpolateWidth as h9, mergeRight as hA, mergeSelection as hB, moveElementBy as hC, moveNodeDown as hD, moveNodeUp as hE, msToFrameDelayCs as hF, narrowToCircle as hG, narrowToPolygon as hH, narrowToRect as hI, newChartElement as hJ, newEquationElement as hK, newPresetShapeElement as hL, newShapeElement as hM, newSmartArtElement as hN, newTableElement as hO, newTextElement as hP, nextVisibleIndex as hQ, nodeBold as hR, nodeEditBox as hS, nodeFillColor as hT, nodeFontColor as hU, nodeIdFromKey as hV, nodeItalic as hW, nodeStyle as hX, normalizeFontFormat as hY, normalizeSlidesPerPage as hZ, normalizeValue as h_, isAudienceTab as ha, isBold as hb, isBrowserOpenableMime as hc, isChildNode as hd, isElementInteractive as he, isInjectableUrl as hf, isItalic as hg, isPpactionUrl as hh, isPresenterMessage as hi, isSigned as hj, isTextElement as hk, isTwoTableFocus as hl, isUnderline as hm, isUrlSafe as hn, isValidRoomId as ho, isViewportBackgroundPressTarget as hp, isZoomActivationKey as hq, issueTrackKey as hr, issueTypeLabel as hs, keyToLabel as ht, latexToMathml as hu, linePointsToSvgString as hv, lineSpacingPatch as hw, loadAudienceContent as hx, mergeCaptionResults as hy, mergeDown as hz, AiChangeOverlayComponent as i, routeOrthogonalConnector as i$, ommlToMathml as i0, ooxmlDashToCssBorderStyle as i1, openNativeEyeDropper as i2, overallStatus as i3, paletteColor as i4, parseAudienceNonce as i5, parseNodeTextarea as i6, partitionSlides as i7, patchChartData as i8, patchChartStyle as i9, removeElementAnimation as iA, removeGradientStopPatch as iB, removeNode as iC, removeRow as iD, removeSeries as iE, renderToCanvas as iF, reorderAnimationDown as iG, reorderAnimationUp as iH, replaceInSlides as iI, replaceMatch as iJ, requestPresentationFullscreen as iK, resizeElement as iL, resolveCaptionTracks as iM, resolveChartKind as iN, resolveFontVariant as iO, resolveHyperlinkHref as iP, resolveInteractiveElementId as iQ, resolveMediaSrc as iR, resolveOleType as iS, resolveParagraphBullet as iT, resolvePresenterNotes as iU, resolveProfileInitial as iV, resolveRegionCode as iW, resolvePalette as iX, resolveThemeCatalogEntry as iY, resolveTransitionDuration as iZ, revealedElementStyles as i_, patchTableData as ia, patchTextStyle as ib, pendingElementStyles as ic, pickColorByClickFallback as id, pickSupportedMimeType as ie, planGifFrames as ig, planVideoSegments as ih, pointsToSvgPathD as ii, presenceToCursors as ij, presetByLayout as ik, presetsForCategory as il, pressuresToWidths as im, prevVisibleIndex as io, projectDrawingShapes as ip, promoteNode as iq, provideViewerTheme as ir, radarAngle as is, radarRingPoints as it, recordWebm as iu, redistributeColumnWidth as iv, removeAnimation as iw, removeCategory as ix, removeColumn as iy, removeCommentFromList as iz, AiChatPanelComponent as j, signatureKey as j$, rowStyle as j0, sampleColorFromSlide as j1, sanitizeColor as j2, sanitizeSlideIndex as j3, sanitizeUserName as j4, saveViewerProfile as j5, scanAvailableFonts as j6, searchSlides as j7, seedBroadcastFields as j8, seedHyperlinkDraft as j9, setGridlineStyle as jA, setLayout as jB, setLegend as jC, setNodeStyle as jD, setNodeText as jE, setRepeatCount as jF, setRepeatMode as jG, setSequence as jH, setSeriesChartType as jI, setSeriesColor as jJ, setSeriesErrorBars as jK, setSeriesMarker as jL, setSeriesName as jM, setSeriesTrendline as jN, setSeriesValue as jO, setStyle as jP, setTimingCurve as jQ, setTitle as jR, setTrigger as jS, setTriggerShapeId as jT, shapeStylePatch as jU, sheetAfterNavigate as jV, shouldBlockClickAdvance as jW, shouldUseSvgWarp as jX, showDirectionPicker as jY, showsTemplateAffordance as jZ, signatureCountLabel as j_, seedPropertiesDraft as ja, seedShareFields as jb, segmentFrameCount as jc, selectValue$2 as jd, sendBackward as je, sendToBack as jf, sequentialColorScale as jg, serializeWriteBack as jh, seriesColor as ji, setAnimationEmphasis as jj, setAnimationEntrance as jk, setAnimationExit as jl, setAxis as jm, setAxisLogScale as jn, setAxisTitleStyle as jo, setCategoryLabel as jp, setCellText as jq, setColorScheme as jr, setDataLabels as js, setDataPointExplosion as jt, setDataPointFill as ju, setDataPointLabel as jv, setDelay as jw, setDirection as jx, setDuration as jy, setElementPosition as jz, AiChatService as k, signatureTimestamp as k0, signerName as k1, statusLabel as k2, slideNumberOf as k3, smartArtNodes as k4, paletteColour as k5, snapToGridStep as k6, splitCursorCell as k7, splitMergedCell as k8, statusKind as k9, updateGlowPatch as kA, updateGradientStopPatch as kB, updateInnerShadowPatch as kC, updateOuterShadowPatch as kD, updateReflectionPatch as kE, vAlignPatch as kF, validatePassword as kG, validatePrintSettings as kH, validateRoomId as kI, valueToY as kJ, vermilionDarkColors as kK, vermilionDarkTheme as kL, vermilionLightColors as kM, vermilionLightTheme as kN, vermilionRadius as kO, waypointsToPathD as kP, worstStatus as kQ, zoomTargetSlideIndex as kR, statusLabel$1 as ka, storeAudienceContent as kb, stringFromEvent$5 as kc, strokeColorOf as kd, strokeToInkElement as ke, styleShadowFilter as kf, textAdvancedPatch as kg, textAdvancedStateFromStyle as kh, textAdvancedStateOf as ki, textColorOf as kj, textDirectionPatch as kk, textStyleOf as kl, textStylePatch as km, themeStyle as kn, themeToCssVars as ko, thumbnailHeight as kp, thumbnailZoom as kq, toggleCommentResolvedInList as kr, toggleNodeBold as ks, toggleNodeItalic as kt, toggleSheet as ku, topLevelNodeCount as kv, transformSelectedTextCase as kw, translationsEn as kx, ungroupElements as ky, updateElementById as kz, AiComposerComponent as l, AiFocusBarComponent as m, AiFocusHighlightOverlayComponent as n, AiMessageListComponent as o, AiPanelStore as p, AiProposalCardComponent as q, AiSettingsSectionComponent as r, AiToolCallCardComponent as s, toChatSummary as t, AnimationAuthorPanelComponent as u, AnimationPanelComponent as v, AnimationPlaybackService as w, AutosaveService as x, CURSOR_PALETTE as y, CanvasFitService as z };
112861
- //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-BrBDSqiy.mjs.map
113337
+ export { DATA_TABLE_KEY_W as $, ALIGN_OPTIONS as A, BroadcastDialogComponent as B, CHART_EDITOR_STYLES as C, ChartAxisOptionsComponent as D, ChartAxisStyleOptionsComponent as E, ChartComboTypeOptionsComponent as F, ChartDataEditorComponent as G, ChartDataLabelOptionsComponent as H, ChartDatapointOptionsComponent as I, ChartDisplayOptionsComponent as J, ChartElementViewComponent as K, ChartErrorBarOptionsComponent as L, ChartMarkerOptionsComponent as M, ChartPartSelectionService as N, ChartPrimitivesComponent as O, ChartRendererComponent as P, ChartTrendlineOptionsComponent as Q, CollaborationCursorsComponent as R, CollaborationService as S, ColorChangedImageComponent as T, CommentsPanelComponent as U, CommentsService as V, ComparePanelComponent as W, ConnectorRendererComponent as X, ConnectorTextOverlayComponent as Y, CustomShowsComponent as Z, DATA_TABLE_HEADER_H as _, AUDIENCE_HASH as a, MIN_ZOOM_SCALE as a$, DATA_TABLE_PADDING as a0, DATA_TABLE_ROW_H as a1, DEFAULT_BOUNDS as a2, DEFAULT_BROADCAST_SERVER_URL as a3, DEFAULT_CANVAS_HEIGHT as a4, DEFAULT_CANVAS_WIDTH as a5, DEFAULT_COLOR_SCHEME as a6, DEFAULT_FILL_COLOR as a7, DEFAULT_LAYOUT as a8, DEFAULT_PALETTE$1 as a9, ExportProgressModalComponent as aA, ExportService as aB, FieldContextService as aC, FindBarComponent as aD, FindReplaceBarComponent as aE, FollowModeBarComponent as aF, FontEmbeddingListComponent as aG, FontEmbeddingPanelComponent as aH, GALLERY_THEME_PRESETS as aI, GradientPickerComponent as aJ, HANDOUT_OPTIONS as aK, HeaderFooterDialogComponent as aL, HyperlinkDialogComponent as aM, ImagePropertiesPanelComponent as aN, InkDrawingService as aO, InkRendererComponent as aP, InsertSmartArtDialogComponent as aQ, InspectorPaneHeaderComponent as aR, InspectorPanelComponent as aS, IsMobileService as aT, KeepAnnotationsDialogComponent as aU, LOCALE_CATALOG as aV, LONG_PRESS_DURATION_MS as aW, LONG_PRESS_MOVE_TOLERANCE_PX as aX, LoadContentService as aY, LocalPresencePublisher as aZ, MAX_ZOOM_SCALE as a_, DEFAULT_PRINT_SETTINGS as aa, DEFAULT_SLIDE_BACKGROUND as ab, DEFAULT_STROKE_COLOR as ac, DEFAULT_STYLE as ad, DEFAULT_TABLE_ROW_HEIGHT as ae, DEFAULT_TEXT_COLOR$1 as af, DEFAULT_VIEWER_PROFILE as ag, DIRECTIONAL_PRESETS as ah, DIRECTION_OPTIONS as ai, DocumentPropertiesCardComponent as aj, EMBEDDED_FONTS_STYLE_ID as ak, EMPHASIS_PRESETS as al, ENTRANCE_PRESETS as am, TEMPLATES as an, EXIT_PRESETS as ao, EditorContextMenuComponent as ap, EditorHistory as aq, EditorStateService as ar, EditorToolbarComponent as as, EffectsPanelComponent as at, ElementRendererComponent as au, EmbeddedFontsService as av, EncryptedFileDialogComponent as aw, EquationEditorDialogComponent as ax, EquationRendererComponent as ay, EquationTemplateGalleryComponent as az, AUDIENCE_NONCE_KEY as b, SLIDE_PX_PER_INCH as b$, MediaPreviewComponent as b0, MediaPropertiesPanelComponent as b1, MediaRendererComponent as b2, MediaTrimTimelineComponent as b3, MobileBottomBarComponent as b4, MobileMenuSheetComponent as b5, MobilePresenterViewComponent as b6, MobileSheetComponent as b7, MobileSlidesSheetComponent as b8, MobileToolbarComponent as b9, RESIZE_HANDLES as bA, RULER_THICKNESS as bB, RemoteSelectionOverlayComponent as bC, RibbonAnimationsSectionComponent as bD, RibbonArrangeSectionComponent as bE, RibbonColorPopoverComponent as bF, RibbonComponent as bG, RibbonDesignSectionComponent as bH, RibbonDrawSectionComponent as bI, RibbonDrawingGroupComponent as bJ, RibbonEditingSectionComponent as bK, RibbonFileSectionComponent as bL, RibbonFontControlsComponent as bM, RibbonHomeSectionComponent as bN, RibbonInsertFieldsComponent as bO, RibbonInsertSectionComponent as bP, RibbonParagraphControlsComponent as bQ, RibbonPrimaryRowComponent as bR, RibbonReviewSectionComponent as bS, RibbonSlideshowSectionComponent as bT, RibbonTransitionsSectionComponent as bU, RibbonViewSectionComponent as bV, RulerGuidesService as bW, SEQUENCE_OPTIONS as bX, SEVERITY_GROUPS as bY, SEVERITY_LABELS as bZ, SHORTCUT_REFERENCE_ITEMS as b_, ModalDialogComponent as ba, Model3DRendererComponent as bb, NotesHandoutCardComponent as bc, NotesPanelComponent as bd, NotesToolbarComponent as be, OleRendererComponent as bf, POWER_POINT_VIEWER_PROVIDERS as bg, PRESENTER_CHANNEL_NAME as bh, PRESENTER_MSG_ORIGIN as bi, PasswordProtectionDialogComponent as bj, PasswordStrengthMeterComponent as bk, PowerPointViewerComponent as bl, PresentationAnnotationOverlayComponent as bm, PresentationAnnotationsService as bn, PresentationOverlayComponent as bo, PresentationPropertiesPanelComponent as bp, PresentationSettingsCardComponent as bq, PresentationSubtitleBarComponent as br, PresentationTransitionOverlayComponent as bs, PresenterViewComponent as bt, PresenterWindowService as bu, PrintDialogComponent as bv, PrintService as bw, PrintSettingsPanelComponent as bx, PropertiesDialogComponent as by, REPEAT_MODE_OPTIONS as bz, AVATAR_COLOR_SWATCHES as c, ViewerDocumentPropertiesService as c$, SLIDE_TRANSITION_KEYFRAMES as c0, DEFAULT_PALETTE as c1, PALETTES$1 as c2, SMART_ART_COLOR_SCHEMES as c3, SMART_ART_STYLE_OPTIONS as c4, SUB_ITEM_LABEL as c5, SVG_WARP_PRESETS as c6, SWIPE_MAX_VERTICAL_PX as c7, SWIPE_THRESHOLD_PX as c8, SelectionPaneComponent as c9, TABLE_STRUCTURE_TOGGLES as cA, TEXT_DIRECTION_OPTIONS$1 as cB, THEME_CATALOG as cC, TIMING_CURVE_OPTIONS as cD, TRIGGER_OPTIONS as cE, TYPE_LABELS as cF, TableCellAdvancedFillComponent as cG, TableCellFormattingComponent as cH, TableDataEditorComponent as cI, TablePropertiesComponent as cJ, TableRendererComponent as cK, TableResizeOverlayComponent as cL, TableSelectionService as cM, TextAdvancedPanelComponent as cN, ThemeEditorFieldsComponent as cO, ThemeGalleryComponent as cP, ThemeSelectorCardComponent as cQ, TitleBarComponent as cR, VALIGN_OPTIONS as cS, VIEWER_THEME as cT, VersionHistoryPanelComponent as cU, ViewerCanvasEditingService as cV, ViewerCollabCursorService as cW, ViewerCollaborationSessionService as cX, ViewerCompareService as cY, ViewerCustomShowsService as cZ, ViewerDialogsService as c_, SetUpSlideShowDialogComponent as ca, SettingsAppearanceTabComponent as cb, SettingsDialogComponent as cc, SettingsLanguageTabComponent as cd, ShareDialogComponent as ce, ShortcutPanelComponent as cf, ShowOptionsFieldsetComponent as cg, ShowSlidesFieldsetComponent as ch, SignatureStrippedDialogComponent as ci, SignaturesPanelComponent as cj, SignaturesService as ck, SlideCanvasComponent as cl, SlideDefaultInspectorComponent as cm, SlideDiffChangesComponent as cn, SlideDiffRowComponent as co, SlideDiffThumbnailsComponent as cp, SlideSizeCardComponent as cq, SlideSorterOverlayComponent as cr, SlideThemeOverridePanelComponent as cs, SlidesPanelComponent as ct, SmartArt3DRendererComponent as cu, SmartArt3DService as cv, SmartArtPreviewComponent as cw, SmartArtPropertiesComponent as cx, SmartArtRendererComponent as cy, StatusBarComponent as cz, AccessibilityPanelComponent as d, buildFallbackViewModel as d$, ViewerExportService as d0, ViewerExtraDialogsComponent as d1, ViewerFileIOService as d2, ViewerFindReplaceService as d3, ViewerFormatPainterService as d4, ViewerInspectorPanelService as d5, ViewerKeyboardService as d6, ViewerMobileSheetService as d7, ViewerPresentationModeService as d8, ViewerThemeGalleryService as d9, asMediaElement as dA, assignUserColor as dB, attachTouchGestures as dC, beginNodeEdit as dD, boolFromEvent as dE, bringForward as dF, bringToFront as dG, buildBarActions as dH, buildBroadcastConfig as dI, buildBroadcastViewerUrl as dJ, buildCategoryLabels as dK, buildCellParagraphs as dL, buildChartViewModel as dM, buildChatLogExport as dN, buildChatLogMarkdown as dO, buildChromeStyle as dP, buildClearHyperlinkPatch as dQ, buildClickGroups as dR, buildColStyles as dS, buildCollaborationConfig as dT, buildComboViewModel as dU, buildCssGradientFromShapeStyle as dV, buildDuotoneFilter as dW, buildDuotoneFilterId as dX, buildEmbeddedFontStyles as dY, buildEquationElement as dZ, buildEquationSegment as d_, ViewerTouchGesturesService as da, ViewerZoomService as db, WEBM_MIME_CANDIDATES as dc, WriteBackScheduler as dd, ZoomNavigationService as de, ZoomRendererComponent as df, ZoomTargetService as dg, addCategory as dh, addCommentToList as di, addGradientStopPatch as dj, addItem as dk, addSeries as dl, addSubItem as dm, advanceStep as dn, aiToggleVisible as dp, alignPatch as dq, animationFor as dr, annotationMapToInkInserts as ds, applyAcceptedDiff as dt, applyAnimationPreset as du, applyFindReplacements as dv, applyFormatToElement as dw, applyMove as dx, applyResize as dy, applyTableStylePreset as dz, AccessibilityService as e, computeDataTablePrimitives as e$, buildFontFaceRule as e0, buildGradientFillCss as e1, buildGridlinesAndLabels as e2, buildHyperlinkPatch as e3, buildInkContainerStyle as e4, buildInkStrokes as e5, buildLegend as e6, buildModel3DContainerStyle as e7, buildModel3DViewModel as e8, buildOleActionModel as e9, cellStyleToStyleMap as eA, cellTdStyle as eB, changeCountLabel as eC, changeIcon as eD, characterSpacingPatch as eE, checkFontAvailable as eF, clampCursorPosition as eG, clampGifDimensions as eH, clampIndex as eI, clampNotesFontSize as eJ, clampScale as eK, clampStep as eL, clearAllLocalViewerData as eM, clearAudienceContent as eN, cn as eO, collectAccessibilityIssues as eP, collectElementText as eQ, collectSlideText as eR, collectStoredChats as eS, collectUsedFontFamilies as eT, columnWidthStyle as eU, commitNodeText as eV, computeAlign as eW, computeAxisTitlePrimitives as eX, computeBarRects as eY, computeBubbleRadius as eZ, computeCornerHandle as e_, buildOleInfoRows as ea, buildPatternFillCss as eb, buildPrintHtmlDocument as ec, buildPropertiesPatch as ed, buildRegionMapViewModel as ee, buildSaveSlides as ef, buildShareUrl as eg, buildSmartArtInsertElement as eh, buildSmartArtNodes as ei, buildStockViewModel as ej, buildSurfaceViewModel as ek, buildTableViewModel as el, buildTreemapViewModel as em, buildTrimFragment as en, buildWaterfallViewModel as eo, buildZeroLine as ep, buildZoomContainerStyle as eq, buildZoomViewModel as er, bulletIndentPx as es, canAddTopLevelNode as et, canRemoveTopLevelNode as eu, canStartBroadcast as ev, canStartShare as ew, canUseClipboard as ex, captionDisplayText as ey, cellRunStyle as ez, AccountPageComponent as f, encodeGif as f$, computeDistribute as f0, computeDrawingViewBox as f1, computeErrorBarPrimitives as f2, computeFocusTargets as f3, computeHandleBoxes as f4, computeHandoutLayout as f5, computeIsMobile as f6, computeIsTablet as f7, computeLinePoints as f8, computeLinearRegression as f9, createWebsocketBundle as fA, cssObjectToStyleMap as fB, currentColorScheme as fC, currentLayout as fD, currentStyle as fE, defaultCssVars as fF, defaultRadius as fG, defaultThemeColors as fH, deleteElementsByIds as fI, deleteVersion as fJ, demoteNode as fK, deriveModel3DBlobUrl as fL, derivePresenceList as fM, describeSmartArtBounds as fN, disableGlowPatch as fO, disableInnerShadowPatch as fP, disableOuterShadowPatch as fQ, disableReflectionPatch as fR, disableSoftEdgePatch as fS, duplicateElementById as fT, durationOf as fU, effectsStateOf as fV, enableGlowPatch as fW, enableInnerShadowPatch as fX, enableOuterShadowPatch as fY, enableReflectionPatch as fZ, enableSoftEdgePatch as f_, computePageCount as fa, computePieLayout as fb, computePieSlicePath as fc, computePieSlices as fd, computePlotLayout as fe, computeRSquared as ff, computeRadarPoints as fg, computeScatterDots as fh, computeSelectionBoxes as fi, computeSingleSelected as fj, computeSlideIndices as fk, computeSnap as fl, computeStackedBarRects as fm, computeStackedValueRange as fn, computeTextLines as fo, computeTimerProgress as fp, computeTrendlinePrimitives as fq, computeValueRange as fr, convertOmmlToMathMl as fs, copyFormatFromElement as ft, countAccessibilityIssues as fu, countAnnotationStrokes as fv, createAngularAiBridge as fw, createCustomShow as fx, createSwipeDismissDrag as fy, createWebrtcBundle as fz, ActionSettingsPanelComponent as g, hasAnimation as g$, estimatePageCount as g0, evenColumnWidths as g1, evenRowHeights as g2, exitPresentationFullscreen as g3, exportAiChatLogs as g4, extractPathPoints as g5, eyedropperAvailable as g6, fillColorOf as g7, findInSlides as g8, findOwningSlideIndex as g9, getOleBadgeLabel as gA, getOleDisplayName as gB, getOleDownloadFileName as gC, getOleTypeColor as gD, getOleTypeLabel as gE, getPasswordStrength as gF, getPatternSvg as gG, getPlaceholderStyle as gH, getVersions as gI, getResolvedShapeClipPath as gJ, getResolvedShapeClipPathFor as gK, getShapeFillStrokeStyle as gL, getSlideBackgroundStyle as gM, getSlideTransitionAnimations as gN, getSmartArtNodeBounds as gO, getSpeechRecognitionCtor as gP, getTextBlockStyle as gQ, getTextWarp as gR, getTouchDistance as gS, getWarpCategory as gT, getWarpPath as gU, gradientStateFromStyle as gV, gradientStateOf as gW, gradientStatePatch as gX, gridColumns as gY, groupElements as gZ, groupIssuesBySeverity as g_, findSlideIndexByElementId as ga, fitPolynomial as gb, fitZoom as gc, focusTargetChips as gd, fontMimeForFormat as ge, fontSizeOf as gf, formatAutoNumber as gg, formatAxisValue as gh, formatBytes as gi, formatCursorLabel as gj, formatElapsed as gk, formatFileSize as gl, formatPropertyDate as gm, formatTime as gn, fpsToFrameIntervalMs as go, generateBroadcastRoomId as gp, generateCommentId as gq, generateCustomShowId as gr, generatePressureCircles as gs, generateRulerTicks as gt, getClrChangeParams as gu, getContainerStyle as gv, getDuotoneFilterDef as gw, getImageSrc as gx, getLocalStorageUsageSummary as gy, getOleAriaLabel as gz, AdvancedChartEditorComponent as h, normalizeValue as h$, hasCopyableFormat as h0, hasExistingLink as h1, hasExitedFullscreen as h2, hasGradientFill as h3, hasPressureVariation as h4, hasVisibleSlideAfter as h5, headerLabel as h6, inkViewBox as h7, insertColumn as h8, insertRow as h9, mergeDown as hA, mergeRight as hB, mergeSelection as hC, moveElementBy as hD, moveNodeDown as hE, moveNodeUp as hF, msToFrameDelayCs as hG, narrowToCircle as hH, narrowToPolygon as hI, narrowToRect as hJ, newChartElement as hK, newEquationElement as hL, newPresetShapeElement as hM, newShapeElement as hN, newSmartArtElement as hO, newTableElement as hP, newTextElement as hQ, nextVisibleIndex as hR, nodeBold as hS, nodeEditBox as hT, nodeFillColor as hU, nodeFontColor as hV, nodeIdFromKey as hW, nodeItalic as hX, nodeStyle as hY, normalizeFontFormat as hZ, normalizeSlidesPerPage as h_, interpolateWidth as ha, isAudienceTab as hb, isBold as hc, isBrowserOpenableMime as hd, isChildNode as he, isElementInteractive as hf, isInjectableUrl as hg, isItalic as hh, isPpactionUrl as hi, isPresenterMessage as hj, isSigned as hk, isTextElement as hl, isTwoTableFocus as hm, isUnderline as hn, isUrlSafe as ho, isValidRoomId as hp, isViewportBackgroundPressTarget as hq, isZoomActivationKey as hr, issueTrackKey as hs, issueTypeLabel as ht, keyToLabel as hu, latexToMathml as hv, linePointsToSvgString as hw, lineSpacingPatch as hx, loadAudienceContent as hy, mergeCaptionResults as hz, AiChangeOverlayComponent as i, revealedElementStyles as i$, numFromEvent as i0, ommlToMathml as i1, ooxmlDashToCssBorderStyle as i2, openNativeEyeDropper as i3, overallStatus as i4, paletteColor as i5, parseAudienceNonce as i6, parseNodeTextarea as i7, partitionSlides as i8, patchChartData as i9, removeCommentFromList as iA, removeElementAnimation as iB, removeGradientStopPatch as iC, removeNode as iD, removeRow as iE, removeSeries as iF, renderToCanvas as iG, reorderAnimationDown as iH, reorderAnimationUp as iI, replaceInSlides as iJ, replaceMatch as iK, requestPresentationFullscreen as iL, resizeElement as iM, resolveCaptionTracks as iN, resolveChartKind as iO, resolveFontVariant as iP, resolveHyperlinkHref as iQ, resolveInteractiveElementId as iR, resolveMediaSrc as iS, resolveOleType as iT, resolveParagraphBullet as iU, resolvePresenterNotes as iV, resolveProfileInitial as iW, resolveRegionCode as iX, resolvePalette as iY, resolveThemeCatalogEntry as iZ, resolveTransitionDuration as i_, patchChartStyle as ia, patchTableData as ib, patchTextStyle as ic, pendingElementStyles as id, pickColorByClickFallback as ie, pickSupportedMimeType as ig, planGifFrames as ih, planVideoSegments as ii, pointsToSvgPathD as ij, presenceToCursors as ik, presetByLayout as il, presetsForCategory as im, pressuresToWidths as io, prevVisibleIndex as ip, projectDrawingShapes as iq, promoteNode as ir, provideViewerTheme as is, radarAngle as it, radarRingPoints as iu, recordWebm as iv, redistributeColumnWidth as iw, removeAnimation as ix, removeCategory as iy, removeColumn as iz, AiChatPanelComponent as j, signatureCountLabel as j$, routeOrthogonalConnector as j0, rowStyle as j1, sampleColorFromSlide as j2, sanitizeColor as j3, sanitizeSlideIndex as j4, sanitizeUserName as j5, saveViewerProfile as j6, scanAvailableFonts as j7, searchSlides as j8, seedBroadcastFields as j9, setElementPosition as jA, setGridlineStyle as jB, setLayout as jC, setLegend as jD, setNodeStyle as jE, setNodeText as jF, setRepeatCount as jG, setRepeatMode as jH, setSequence as jI, setSeriesChartType as jJ, setSeriesColor as jK, setSeriesErrorBars as jL, setSeriesMarker as jM, setSeriesName as jN, setSeriesTrendline as jO, setSeriesValue as jP, setStyle as jQ, setTimingCurve as jR, setTitle as jS, setTrigger as jT, setTriggerShapeId as jU, shapeStylePatch as jV, sheetAfterNavigate as jW, shouldBlockClickAdvance as jX, shouldUseSvgWarp as jY, showDirectionPicker as jZ, showsTemplateAffordance as j_, seedHyperlinkDraft as ja, seedPropertiesDraft as jb, seedShareFields as jc, segmentFrameCount as jd, selectValue$2 as je, sendBackward as jf, sendToBack as jg, sequentialColorScale as jh, serializeWriteBack as ji, seriesColor as jj, setAnimationEmphasis as jk, setAnimationEntrance as jl, setAnimationExit as jm, setAxis as jn, setAxisLogScale as jo, setAxisTitleStyle as jp, setCategoryLabel as jq, setCellText as jr, setColorScheme as js, setDataLabels as jt, setDataPointExplosion as ju, setDataPointFill as jv, setDataPointLabel as jw, setDelay as jx, setDirection as jy, setDuration as jz, AiChatService as k, signatureKey as k0, signatureTimestamp as k1, signerName as k2, statusLabel as k3, slideNumberOf as k4, smartArtNodes as k5, paletteColour as k6, snapToGridStep as k7, splitCursorCell as k8, splitMergedCell as k9, updateElementById as kA, updateGlowPatch as kB, updateGradientStopPatch as kC, updateInnerShadowPatch as kD, updateOuterShadowPatch as kE, updateReflectionPatch as kF, vAlignPatch as kG, validatePassword as kH, validatePrintSettings as kI, validateRoomId as kJ, valueToY as kK, vermilionDarkColors as kL, vermilionDarkTheme as kM, vermilionLightColors as kN, vermilionLightTheme as kO, vermilionRadius as kP, waypointsToPathD as kQ, worstStatus as kR, zoomTargetSlideIndex as kS, statusKind as ka, statusLabel$1 as kb, storeAudienceContent as kc, stringFromEvent$5 as kd, strokeColorOf as ke, strokeToInkElement as kf, styleShadowFilter as kg, textAdvancedPatch as kh, textAdvancedStateFromStyle as ki, textAdvancedStateOf as kj, textColorOf as kk, textDirectionPatch as kl, textStyleOf as km, textStylePatch as kn, themeStyle as ko, themeToCssVars as kp, thumbnailHeight as kq, thumbnailZoom as kr, toggleCommentResolvedInList as ks, toggleNodeBold as kt, toggleNodeItalic as ku, toggleSheet as kv, topLevelNodeCount as kw, transformSelectedTextCase as kx, translationsEn as ky, ungroupElements as kz, AiComposerComponent as l, AiFocusBarComponent as m, AiFocusHighlightOverlayComponent as n, AiMessageListComponent as o, AiPanelStore as p, AiProposalCardComponent as q, AiSettingsSectionComponent as r, AiToolCallCardComponent as s, toChatSummary as t, AnimationAuthorPanelComponent as u, AnimationPanelComponent as v, AnimationPlaybackService as w, AutosaveService as x, CURSOR_PALETTE as y, CanvasFitService as z };
113338
+ //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-Dora2fol.mjs.map