pptx-angular-viewer 2.3.0 → 2.5.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, 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, 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.
@@ -15836,6 +15837,50 @@ function countTextSegments(textSegments) {
15836
15837
  * in composite animation target IDs (e.g. `"shape3::p0"`).
15837
15838
  */
15838
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
+ }
15839
15884
  /**
15840
15885
  * Expand text-build animations into per-paragraph, per-word or per-character
15841
15886
  * sub-element animations.
@@ -15851,9 +15896,9 @@ const TEXT_BUILD_ID_SEP = '::';
15851
15896
  function expandTextBuildAnimations(animations, segmentCounts) {
15852
15897
  const result = [];
15853
15898
  for (const anim of animations) {
15854
- const buildType = anim.buildType;
15899
+ const buildType = effectiveTextBuildType(anim);
15855
15900
  const targetId = anim.targetId ?? '';
15856
- if (!buildType || buildType === 'allAtOnce' || !targetId) {
15901
+ if (!buildType || !targetId) {
15857
15902
  result.push(anim);
15858
15903
  continue;
15859
15904
  }
@@ -15866,13 +15911,109 @@ function expandTextBuildAnimations(animations, segmentCounts) {
15866
15911
  }
15867
15912
  return result;
15868
15913
  }
15914
+ /**
15915
+ * The within-paragraph granularity an effect's own `p:iterate` asks for, or
15916
+ * `undefined` when it animates the text as one object (`type="el"`, or absent).
15917
+ *
15918
+ * This is INDEPENDENT of `p:bldP/@build`: the slide build says how the text is
15919
+ * grouped into steps ("by paragraph"), while `p:iterate` says how each step is
15920
+ * subdivided in time ("by letter"). PowerPoint composes the two; reading only
15921
+ * the build type made a by-paragraph credit line authored to ripple in letter by
15922
+ * letter appear as one solid block (issue #106).
15923
+ */
15924
+ function iterateGranularity(anim) {
15925
+ if (anim.iterate?.type === 'lt') {
15926
+ return 'byChar';
15927
+ }
15928
+ if (anim.iterate?.type === 'wd') {
15929
+ return 'byWord';
15930
+ }
15931
+ return undefined;
15932
+ }
15933
+ /** Per-piece sub-element id prefix and per-paragraph piece count for a split. */
15934
+ function pieceCounts(kind, counts) {
15935
+ return kind === 'byChar'
15936
+ ? { token: 'c', perParagraph: counts.charCounts ?? [] }
15937
+ : { token: 'w', perParagraph: counts.wordCounts ?? [] };
15938
+ }
15939
+ /**
15940
+ * Emit one staggered sub-animation per letter / word.
15941
+ *
15942
+ * An `p:iterate` build overlaps: every piece runs the FULL effect duration and
15943
+ * merely starts `stagger` later than the one before, which is what makes
15944
+ * PowerPoint's "by letter" read as a ripple. `withPrevious` steps accumulate
15945
+ * their delay from the previous step's START, so passing the bare interval as
15946
+ * each step's delay yields `base + i * stagger`. The slide-build (`p:bldP`) path
15947
+ * keeps its original end-to-end pacing.
15948
+ *
15949
+ * `newClickStepPerParagraph` reproduces a by-paragraph build: paragraph 0 starts
15950
+ * with the parent effect, and every later paragraph waits for its own click,
15951
+ * with its pieces rippling from there.
15952
+ */
15953
+ function emitStaggeredPieces(anim, kind, counts, output, newClickStepPerParagraph) {
15954
+ const targetId = anim.targetId ?? '';
15955
+ const baseDuration = anim.durationMs ?? 500;
15956
+ const stagger = iterateStaggerMs(anim, baseDuration);
15957
+ const { token, perParagraph } = pieceCounts(kind, counts);
15958
+ const fallbackDuration = kind === 'byChar'
15959
+ ? Math.max(50, Math.round(baseDuration / 4))
15960
+ : Math.max(100, Math.round(baseDuration / 2));
15961
+ const fallbackStagger = kind === 'byChar' ? 20 : 50;
15962
+ let stepIndex = 0;
15963
+ for (let pIdx = 0; pIdx < counts.paragraphCount; pIdx++) {
15964
+ const pieces = perParagraph[pIdx] ?? 0;
15965
+ for (let i = 0; i < pieces; i++) {
15966
+ const opensParagraph = i === 0;
15967
+ const isFirstStep = stepIndex === 0;
15968
+ const startsClickStep = newClickStepPerParagraph && opensParagraph && !isFirstStep;
15969
+ output.push({
15970
+ ...anim,
15971
+ targetId: `${targetId}${TEXT_BUILD_ID_SEP}${token}${pIdx}-${i}`,
15972
+ trigger: isFirstStep
15973
+ ? anim.trigger
15974
+ : startsClickStep
15975
+ ? 'onClick'
15976
+ : stagger !== undefined
15977
+ ? 'withPrevious'
15978
+ : 'afterPrevious',
15979
+ durationMs: stagger !== undefined ? baseDuration : fallbackDuration,
15980
+ delayMs: isFirstStep
15981
+ ? (anim.delayMs ?? 0)
15982
+ : startsClickStep
15983
+ ? 0
15984
+ : (stagger ?? fallbackStagger),
15985
+ // Only the first sub-step inherits the parent's start delay; the
15986
+ // rest carry the bare stagger, so these must not re-apply it.
15987
+ // They are synthetic chain steps rather than OOXML `p:par`
15988
+ // siblings, so they also drop the wrapper index: their delay is
15989
+ // an interval off the step before, not an offset from the group.
15990
+ ...(isFirstStep
15991
+ ? {}
15992
+ : {
15993
+ triggerDelayMs: undefined,
15994
+ startConditions: undefined,
15995
+ parGroupIndex: undefined,
15996
+ }),
15997
+ buildType: undefined,
15998
+ iterate: undefined,
15999
+ });
16000
+ stepIndex++;
16001
+ }
16002
+ }
16003
+ }
15869
16004
  /**
15870
16005
  * Expand a single text-build animation into sub-element animations.
15871
16006
  */
15872
16007
  function expandSingleBuildAnimation(anim, buildType, counts, output) {
15873
16008
  const targetId = anim.targetId ?? '';
15874
- const baseDuration = anim.durationMs ?? 500;
15875
16009
  if (buildType === 'byParagraph') {
16010
+ // A by-paragraph build whose effect also iterates by letter / word still
16011
+ // ripples inside each paragraph; only the step boundaries are paragraphs.
16012
+ const granularity = iterateGranularity(anim);
16013
+ if (granularity) {
16014
+ emitStaggeredPieces(anim, granularity, counts, output, true);
16015
+ return;
16016
+ }
15876
16017
  for (let i = 0; i < counts.paragraphCount; i++) {
15877
16018
  output.push({
15878
16019
  ...anim,
@@ -15883,42 +16024,8 @@ function expandSingleBuildAnimation(anim, buildType, counts, output) {
15883
16024
  }
15884
16025
  return;
15885
16026
  }
15886
- if (buildType === 'byWord') {
15887
- const wordCounts = counts.wordCounts ?? [];
15888
- let stepIndex = 0;
15889
- for (let pIdx = 0; pIdx < counts.paragraphCount; pIdx++) {
15890
- const wc = wordCounts[pIdx] ?? 0;
15891
- for (let wIdx = 0; wIdx < wc; wIdx++) {
15892
- output.push({
15893
- ...anim,
15894
- targetId: `${targetId}${TEXT_BUILD_ID_SEP}w${pIdx}-${wIdx}`,
15895
- trigger: stepIndex === 0 ? anim.trigger : 'afterPrevious',
15896
- durationMs: Math.max(100, Math.round(baseDuration / 2)),
15897
- delayMs: stepIndex === 0 ? (anim.delayMs ?? 0) : 50,
15898
- buildType: undefined,
15899
- });
15900
- stepIndex++;
15901
- }
15902
- }
15903
- return;
15904
- }
15905
- if (buildType === 'byChar') {
15906
- const charCounts = counts.charCounts ?? [];
15907
- let stepIndex = 0;
15908
- for (let pIdx = 0; pIdx < counts.paragraphCount; pIdx++) {
15909
- const cc = charCounts[pIdx] ?? 0;
15910
- for (let cIdx = 0; cIdx < cc; cIdx++) {
15911
- output.push({
15912
- ...anim,
15913
- targetId: `${targetId}${TEXT_BUILD_ID_SEP}c${pIdx}-${cIdx}`,
15914
- trigger: stepIndex === 0 ? anim.trigger : 'afterPrevious',
15915
- durationMs: Math.max(50, Math.round(baseDuration / 4)),
15916
- delayMs: stepIndex === 0 ? (anim.delayMs ?? 0) : 20,
15917
- buildType: undefined,
15918
- });
15919
- stepIndex++;
15920
- }
15921
- }
16027
+ if (buildType === 'byWord' || buildType === 'byChar') {
16028
+ emitStaggeredPieces(anim, buildType, counts, output, false);
15922
16029
  return;
15923
16030
  }
15924
16031
  // Unknown build type — keep original
@@ -16524,6 +16631,19 @@ function buildTimeline(nativeAnimations) {
16524
16631
  let currentGroup = [];
16525
16632
  /** Whether the current group was started by an onClick trigger. */
16526
16633
  let currentGroupIsClick = false;
16634
+ /**
16635
+ * Whether the current group's OOXML click step begins on slide entry rather
16636
+ * than on a click (`groupAutoStart` from the parse layer).
16637
+ */
16638
+ let currentGroupAutoStart = false;
16639
+ /**
16640
+ * Effect-wrapper (`p:par`) index of the sub-group being filled, and the time
16641
+ * that wrapper starts relative to the click group. Siblings of one wrapper all
16642
+ * measure their delay from `subGroupStartMs`; a new wrapper chains off the
16643
+ * previous step instead.
16644
+ */
16645
+ let subGroupIndex;
16646
+ let subGroupStartMs = 0;
16527
16647
  for (const anim of regularAnims) {
16528
16648
  const expandedSteps = expandIterateAnimation(anim);
16529
16649
  for (const singleAnim of expandedSteps) {
@@ -16574,13 +16694,17 @@ function buildTimeline(nativeAnimations) {
16574
16694
  const duration = isCommand
16575
16695
  ? 0
16576
16696
  : (singleAnim.durationMs ?? defaultDuration(singleAnim.presetClass));
16577
- const animDelay = singleAnim.delayMs ?? 0;
16697
+ // `delayMs`, `triggerDelayMs` and the start condition's delay are three
16698
+ // views of ONE OOXML quantity: when does this effect start. Adding them
16699
+ // double-counts (a 1s delay played at 2s), so take the governing value.
16700
+ const animDelay = Math.max(singleAnim.delayMs ?? 0,
16578
16701
  // Use the governing condition delay when conditions were present;
16579
16702
  // otherwise fall back to the simple triggerDelayMs (afterDelay) so
16580
16703
  // existing single-condition slides are unchanged.
16581
- const triggerDelay = singleAnim.startConditions && singleAnim.startConditions.length > 0
16704
+ singleAnim.startConditions && singleAnim.startConditions.length > 0
16582
16705
  ? effective.delayMs
16583
- : (singleAnim.triggerDelayMs ?? 0);
16706
+ : (singleAnim.triggerDelayMs ?? 0));
16707
+ const triggerDelay = 0;
16584
16708
  const presetClass = isCommand ? 'emph' : (singleAnim.presetClass ?? 'entr');
16585
16709
  const fill = fillModeForClass(singleAnim.presetClass);
16586
16710
  // Compute repeat / direction
@@ -16599,24 +16723,41 @@ function buildTimeline(nativeAnimations) {
16599
16723
  // Flush current group if non-empty
16600
16724
  if (currentGroup.length > 0) {
16601
16725
  const group = finalizeClickGroup(currentGroup);
16602
- if (!currentGroupIsClick && clickGroups.length > 0) {
16726
+ if (currentGroupAutoStart || (!currentGroupIsClick && clickGroups.length > 0)) {
16603
16727
  group.autoAdvance = true;
16604
16728
  }
16605
16729
  clickGroups.push(group);
16606
16730
  }
16607
16731
  currentGroup = [];
16608
16732
  currentGroupIsClick = isOnClick || isFirstAnimation;
16733
+ // A group the deck marks as auto-starting plays on slide entry. This
16734
+ // is how PowerPoint renders a deck whose opening effects are "With
16735
+ // Previous"; without it the first group was always click-gated and
16736
+ // the slide showed nothing until the viewer clicked.
16737
+ currentGroupAutoStart = !isOnClick && singleAnim.groupAutoStart === true;
16738
+ subGroupIndex = singleAnim.parGroupIndex;
16739
+ subGroupStartMs = 0;
16609
16740
  }
16610
16741
  // Compute delay relative to start of this click-group
16742
+ const prevStep = currentGroup.length > 0 ? currentGroup[currentGroup.length - 1] : undefined;
16611
16743
  let delayMs;
16612
- if (trigger === 'withPrevious' && currentGroup.length > 0) {
16613
- const prev = currentGroup[currentGroup.length - 1];
16614
- delayMs = prev.delayMs + animDelay + triggerDelay;
16744
+ if (singleAnim.parGroupIndex !== undefined && prevStep) {
16745
+ if (singleAnim.parGroupIndex !== subGroupIndex) {
16746
+ // New effect wrapper: it starts with (withPrevious) or after
16747
+ // (afterPrevious / afterDelay) the step that came before it.
16748
+ subGroupIndex = singleAnim.parGroupIndex;
16749
+ subGroupStartMs =
16750
+ trigger === 'withPrevious' ? prevStep.delayMs : prevStep.delayMs + prevStep.durationMs;
16751
+ }
16752
+ // Siblings of one wrapper are simultaneous in OOXML: each `@delay` is
16753
+ // an offset from the wrapper, never a chain off the previous effect.
16754
+ delayMs = subGroupStartMs + animDelay + triggerDelay;
16615
16755
  }
16616
- else if ((trigger === 'afterPrevious' || trigger === 'afterDelay') &&
16617
- currentGroup.length > 0) {
16618
- const prev = currentGroup[currentGroup.length - 1];
16619
- delayMs = prev.delayMs + prev.durationMs + animDelay + triggerDelay;
16756
+ else if (trigger === 'withPrevious' && prevStep) {
16757
+ delayMs = prevStep.delayMs + animDelay + triggerDelay;
16758
+ }
16759
+ else if ((trigger === 'afterPrevious' || trigger === 'afterDelay') && prevStep) {
16760
+ delayMs = prevStep.delayMs + prevStep.durationMs + animDelay + triggerDelay;
16620
16761
  }
16621
16762
  else {
16622
16763
  delayMs = animDelay + triggerDelay;
@@ -16646,15 +16787,15 @@ function buildTimeline(nativeAnimations) {
16646
16787
  // Flush last group
16647
16788
  if (currentGroup.length > 0) {
16648
16789
  const group = finalizeClickGroup(currentGroup);
16649
- if (!currentGroupIsClick && clickGroups.length > 0) {
16790
+ if (currentGroupAutoStart || (!currentGroupIsClick && clickGroups.length > 0)) {
16650
16791
  group.autoAdvance = true;
16651
16792
  }
16652
16793
  clickGroups.push(group);
16653
16794
  }
16654
16795
  // Compute auto-advance delay for auto-advance groups
16655
- for (let i = 1; i < clickGroups.length; i++) {
16656
- if (clickGroups[i].autoAdvance) {
16657
- clickGroups[i].autoAdvanceDelayMs = 0;
16796
+ for (const group of clickGroups) {
16797
+ if (group.autoAdvance) {
16798
+ group.autoAdvanceDelayMs = 0;
16658
16799
  }
16659
16800
  }
16660
16801
  // Build interactive sequence click-groups
@@ -16709,14 +16850,11 @@ function countDynamicUids(interactiveAnims) {
16709
16850
  * delay between consecutive sub-elements.
16710
16851
  */
16711
16852
  function expandIterateAnimation(anim) {
16712
- const iterate = anim.iterate;
16713
- if (!iterate || iterate.type === 'el') {
16714
- return [anim];
16715
- }
16716
- // We return the original animation unchanged for now
16717
- // iterate expansion is handled at a higher level by the text-build system
16718
- // when buildType is set. When iterate is present without a matching
16719
- // buildType, we still return the original to avoid dropping the animation.
16853
+ // Expansion happens upstream, in `expandTextBuildAnimations`: splitting text
16854
+ // needs the target element's paragraph/word/character counts, which the
16855
+ // timeline builder does not have (it only sees animations). By the time an
16856
+ // animation reaches here it has already been split into per-letter or
16857
+ // per-word sub-animations, so there is nothing left to do.
16720
16858
  return [anim];
16721
16859
  }
16722
16860
  /**
@@ -16748,8 +16886,9 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
16748
16886
  const elementId = anim.targetId ?? '';
16749
16887
  const seqTrigger = anim.trigger ?? 'onShapeClick';
16750
16888
  const duration = anim.durationMs ?? defaultDuration(anim.presetClass);
16751
- const animDelay = anim.delayMs ?? 0;
16752
- const triggerDelay = anim.triggerDelayMs ?? 0;
16889
+ // Same single-quantity rule as the main sequence: never sum the two.
16890
+ const animDelay = Math.max(anim.delayMs ?? 0, anim.triggerDelayMs ?? 0);
16891
+ const triggerDelay = 0;
16753
16892
  const presetClass = anim.presetClass ?? 'entr';
16754
16893
  const fill = fillModeForClass(anim.presetClass);
16755
16894
  const iterCount = anim.repeatCount ?? 1;
@@ -17067,6 +17206,34 @@ class TimelineEngine {
17067
17206
  resetHover(triggerShapeId) {
17068
17207
  this.hoverGroupIndexes.delete(triggerShapeId);
17069
17208
  }
17209
+ /**
17210
+ * Jump to the END of the timeline: every click-group counted as played, every
17211
+ * entrance revealed and every exit applied, with no CSS animation attached so
17212
+ * nothing replays.
17213
+ *
17214
+ * This is what PowerPoint shows when you step BACKWARD onto a slide: it
17215
+ * appears with its builds already complete, and a further back press walks
17216
+ * them off again. Re-running the timeline from zero instead made a deck whose
17217
+ * opening build auto-starts restart its animation every time the presenter
17218
+ * stepped back onto it.
17219
+ */
17220
+ completeAll() {
17221
+ this.reset();
17222
+ for (const group of this.timeline.clickGroups) {
17223
+ for (const step of group.steps) {
17224
+ if (step.build || step.colorTargets) {
17225
+ this.activeSteps.set(step.elementId, step);
17226
+ }
17227
+ if (step.presetClass === 'entr') {
17228
+ this.revealedElements.add(step.elementId);
17229
+ }
17230
+ if (step.presetClass === 'exit') {
17231
+ this.exitedElements.add(step.elementId);
17232
+ }
17233
+ }
17234
+ }
17235
+ this.currentGroupIndex = this.timeline.clickGroups.length - 1;
17236
+ }
17070
17237
  /**
17071
17238
  * Reset the engine to its initial state (no animations played).
17072
17239
  */
@@ -17142,7 +17309,7 @@ class TimelineEngine {
17142
17309
  function buildSegmentCounts(slide, nativeAnims) {
17143
17310
  const segmentCounts = new Map();
17144
17311
  for (const anim of nativeAnims) {
17145
- if (anim.buildType && anim.buildType !== 'allAtOnce' && anim.targetId) {
17312
+ if (effectiveTextBuildType(anim) && anim.targetId) {
17146
17313
  const el = slide.elements.find((e) => e.id === anim.targetId);
17147
17314
  if (el && hasTextProperties(el) && el.textSegments && el.textSegments.length > 0) {
17148
17315
  segmentCounts.set(anim.targetId, countTextSegments(el.textSegments));
@@ -17230,6 +17397,14 @@ class PresentationAnimationController {
17230
17397
  reset() {
17231
17398
  this.engine.reset();
17232
17399
  }
17400
+ /**
17401
+ * Seed the slide as fully built: every group counted as played, nothing
17402
+ * animating. Bindings use it when the presenter steps BACKWARD onto a slide,
17403
+ * which PowerPoint shows with its builds already complete.
17404
+ */
17405
+ completeAll() {
17406
+ this.engine.completeAll();
17407
+ }
17233
17408
  // -----------------------------------------------------------------------
17234
17409
  // Interactive + hover sequences (delegated to the engine)
17235
17410
  // -----------------------------------------------------------------------
@@ -29891,6 +30066,23 @@ function createDepartureChannel(roomId, awareness, factory) {
29891
30066
  };
29892
30067
  }
29893
30068
 
30069
+ /**
30070
+ * collaboration-writeback.ts: elected-writer (role 'owner') PPTX write-back.
30071
+ *
30072
+ * Only the session owner persists snapshots, eliminating last-save-wins races.
30073
+ * On a debounced trigger it reloads the retained source bytes, overlays the
30074
+ * live Y.Doc slides (optionally merging back a binding's separately-stored
30075
+ * master/layout template elements via `mergeTemplateElements`, so template
30076
+ * edits survive), re-serializes to PPTX bytes, and hands them to
30077
+ * `config.onWriteBack`.
30078
+ *
30079
+ * Framework-agnostic: every binding (Vue, Svelte, Vanilla) shares this single
30080
+ * implementation instead of maintaining its own near-identical copy. A
30081
+ * binding without template-mode editing simply omits `getTemplateElements`/
30082
+ * `mergeTemplateElements`. Angular keeps its own class-based
30083
+ * `WriteBackScheduler` (a different calling convention tied to its DI style),
30084
+ * not a duplicate of this one.
30085
+ */
29894
30086
  const DEFAULT_DEBOUNCE_MS = 5_000;
29895
30087
  function createWriteBackScheduler(deps) {
29896
30088
  let timer = null;
@@ -29917,7 +30109,6 @@ function createWriteBackScheduler(deps) {
29917
30109
  return;
29918
30110
  }
29919
30111
  try {
29920
- const { PptxHandler } = await import('pptx-viewer-core');
29921
30112
  const handler = new PptxHandler();
29922
30113
  await handler.load(sourceBytes.buffer);
29923
30114
  const slides = readSlidesFromYDoc(ydoc);
@@ -37772,6 +37963,122 @@ function notesSegmentsToSpans(segments) {
37772
37963
  });
37773
37964
  }
37774
37965
 
37966
+ /**
37967
+ * `text-build-spans` - framework-agnostic spec for rendering a staged text
37968
+ * build (by paragraph / word / letter).
37969
+ *
37970
+ * `expandTextBuildAnimations` splits one animation into per-paragraph,
37971
+ * per-word or per-character sub-animations keyed `<elementId>::p0` /
37972
+ * `::w0-3` / `::c0-7`. Something then has to split the RENDERED text the same
37973
+ * way and attach each sub-animation to its own span, or the build has no
37974
+ * visible effect and the whole box fades as one.
37975
+ *
37976
+ * React did that inline in JSX, which left the other four bindings with no
37977
+ * by-letter animation at all. This module returns the split as plain data so
37978
+ * every binding can render it with its own primitives - the same shape as
37979
+ * `notesSegmentsToSpans`.
37980
+ *
37981
+ * @module render/text-build-spans
37982
+ */
37983
+ /**
37984
+ * Flatten runs into `[character, style]` pairs so a split can carry each
37985
+ * character's own formatting through.
37986
+ */
37987
+ function charactersWithStyle(runs) {
37988
+ const out = [];
37989
+ for (const run of runs) {
37990
+ for (const ch of run.text) {
37991
+ out.push({ ch, style: run.style });
37992
+ }
37993
+ }
37994
+ return out;
37995
+ }
37996
+ function stateSpan(animId, text, states, style) {
37997
+ const state = states.get(animId);
37998
+ return {
37999
+ animId,
38000
+ text,
38001
+ hidden: state?.visible === false,
38002
+ cssAnimation: state?.cssAnimation,
38003
+ style,
38004
+ };
38005
+ }
38006
+ /**
38007
+ * Resolve how a paragraph should be split, or `undefined` when no staged build
38008
+ * targets it (the overwhelmingly common case - callers render normally then).
38009
+ *
38010
+ * Detection mirrors the ids `expandTextBuildAnimations` emits: a paragraph
38011
+ * build registers `::p<i>`, a word build `::w<i>-0`, a char build `::c<i>-0`.
38012
+ *
38013
+ * @param elementId - The owning element's id.
38014
+ * @param paraIndex - Index of this paragraph within the element's text.
38015
+ * @param runs - The paragraph's styled runs, in order.
38016
+ * @param states - Live sub-element animation states for the slide.
38017
+ */
38018
+ function buildTextBuildSpec(elementId, paraIndex, runs, states) {
38019
+ if (!states || states.size === 0) {
38020
+ return undefined;
38021
+ }
38022
+ const paraKey = `${elementId}${TEXT_BUILD_ID_SEP}p${paraIndex}`;
38023
+ const paraState = states.get(paraKey);
38024
+ if (paraState) {
38025
+ return {
38026
+ granularity: 'paragraph',
38027
+ animId: paraKey,
38028
+ hidden: paraState.visible === false,
38029
+ cssAnimation: paraState.cssAnimation,
38030
+ };
38031
+ }
38032
+ const characters = charactersWithStyle(runs);
38033
+ if (states.has(`${elementId}${TEXT_BUILD_ID_SEP}w${paraIndex}-0`)) {
38034
+ const spans = [];
38035
+ let wordIndex = 0;
38036
+ let current = null;
38037
+ // Whitespace stays its own unanimated piece so the paragraph wraps and
38038
+ // spaces exactly as it does unanimated. A word that straddles a run
38039
+ // boundary keeps the style of the run it started in.
38040
+ const flush = () => {
38041
+ if (!current) {
38042
+ return;
38043
+ }
38044
+ spans.push(stateSpan(`${elementId}${TEXT_BUILD_ID_SEP}w${paraIndex}-${wordIndex}`, current.text, states, current.style));
38045
+ wordIndex++;
38046
+ current = null;
38047
+ };
38048
+ for (const { ch, style } of characters) {
38049
+ if (/\s/u.test(ch)) {
38050
+ flush();
38051
+ spans.push({ text: ch, hidden: false, style });
38052
+ continue;
38053
+ }
38054
+ current =
38055
+ current === null ? { text: ch, style } : { text: current.text + ch, style: current.style };
38056
+ }
38057
+ flush();
38058
+ return { granularity: 'word', spans };
38059
+ }
38060
+ if (states.has(`${elementId}${TEXT_BUILD_ID_SEP}c${paraIndex}-0`)) {
38061
+ const spans = characters.map((entry, index) => stateSpan(`${elementId}${TEXT_BUILD_ID_SEP}c${paraIndex}-${index}`, entry.ch, states, entry.style));
38062
+ return { granularity: 'char', spans };
38063
+ }
38064
+ return undefined;
38065
+ }
38066
+ /**
38067
+ * The inline style a {@link TextBuildSpan} (or a paragraph-level spec) needs.
38068
+ * Returned as a plain record so each binding can apply it however it applies
38069
+ * styles; `display: inline` keeps the wrapper from breaking text layout.
38070
+ */
38071
+ function textBuildSpanStyle(span) {
38072
+ const style = { display: 'inline' };
38073
+ if (span.hidden) {
38074
+ style.visibility = 'hidden';
38075
+ }
38076
+ if (span.cssAnimation) {
38077
+ style.animation = span.cssAnimation;
38078
+ }
38079
+ return style;
38080
+ }
38081
+
37775
38082
  const PRESENTER_ZOOM_MIN = 1;
37776
38083
  const PRESENTER_ZOOM_MAX = 4;
37777
38084
  const PRESENTER_ZOOM_STEP = 0.5;
@@ -38266,6 +38573,92 @@ async function clearAudienceContent(sessionId) {
38266
38573
  }
38267
38574
  }
38268
38575
 
38576
+ /**
38577
+ * `audience-display`: the policy that governs a tab opened as a presenter's
38578
+ * **audience display** (the second window a presenter puts on the projector).
38579
+ *
38580
+ * That tab is a mirror of the presenter's screen, not an editor. It is the same
38581
+ * viewer application as the presenter's, so without an explicit policy every
38582
+ * ordinary "leave the slide show" path (Escape, the exit button, leaving
38583
+ * fullscreen, the presenter's end-of-session signal) drops the audience into
38584
+ * the full editing chrome: ribbon, thumbnails and inspector, live in front of
38585
+ * the room (issue #106).
38586
+ *
38587
+ * The rule is therefore absolute: **an audience display never returns to edit
38588
+ * mode.** When the presenter ends the show the tab closes itself; browsers that
38589
+ * refuse `window.close()` (a tab the script did not open, or one the user
38590
+ * re-navigated) leave the end-of-slide-show screen up instead.
38591
+ *
38592
+ * Framework-agnostic: every binding routes its exit paths through
38593
+ * {@link mayLeaveSlideShow} and its presenter-exit handler through
38594
+ * {@link endAudienceDisplay}.
38595
+ *
38596
+ * @module render/audience-display
38597
+ */
38598
+ /**
38599
+ * Whether a URL hash marks the tab as an audience display.
38600
+ *
38601
+ * Accepts the bare hash and the `#pptx-audience&nonce=<uuid>` form the
38602
+ * presenter opens. Safe to call with `undefined` (non-browser contexts).
38603
+ */
38604
+ function isAudienceDisplayHash(hash) {
38605
+ return typeof hash === 'string' && hash.startsWith(PRESENTATION_HASH);
38606
+ }
38607
+ /** Whether the current tab is an audience display. False outside a browser. */
38608
+ function isAudienceDisplayTab() {
38609
+ if (typeof window === 'undefined') {
38610
+ return false;
38611
+ }
38612
+ return isAudienceDisplayHash(window.location.hash);
38613
+ }
38614
+ /**
38615
+ * Whether a tab may leave the slide show for the editor.
38616
+ *
38617
+ * Bindings call this from EVERY exit path (Escape, the toolbar's end button,
38618
+ * the advance past the end-of-show screen, fullscreen change). An audience
38619
+ * display always answers `false`, so its editing chrome is unreachable.
38620
+ *
38621
+ * @param isAudienceDisplay - Pass the binding's audience-tab check; defaults to
38622
+ * {@link isAudienceDisplayTab} so callers with no state can omit it.
38623
+ */
38624
+ function mayLeaveSlideShow(isAudienceDisplay = isAudienceDisplayTab()) {
38625
+ return !isAudienceDisplay;
38626
+ }
38627
+ /**
38628
+ * Whether this tab may drive the deck from its own input.
38629
+ *
38630
+ * An audience display mirrors the presenter's screen, so its keyboard, clicks,
38631
+ * taps and swipes must not navigate. When they did, a stray key moved the
38632
+ * audience off the presenter's slide and the next presenter snapshot yanked it
38633
+ * straight back, which reads as the display refusing to turn the page.
38634
+ *
38635
+ * @param isAudienceDisplay - Pass the binding's audience-tab check; defaults to
38636
+ * {@link isAudienceDisplayTab} so callers with no state can omit it.
38637
+ */
38638
+ function acceptsPresentationInput(isAudienceDisplay = isAudienceDisplayTab()) {
38639
+ return !isAudienceDisplay;
38640
+ }
38641
+ /**
38642
+ * Act on the presenter's `presenter-exit` signal inside an audience tab.
38643
+ *
38644
+ * Attempts to close the tab. Returns `true` when the binding must raise its
38645
+ * end-of-slide-show screen because the tab is still open: `window.close()` is
38646
+ * refused for tabs the script did not open, and closing is asynchronous, so the
38647
+ * caller always shows the screen and simply never sees it if the tab goes away.
38648
+ */
38649
+ function endAudienceDisplay(win = globalThis.window) {
38650
+ if (!win) {
38651
+ return true;
38652
+ }
38653
+ try {
38654
+ win.close();
38655
+ }
38656
+ catch {
38657
+ // Browsers refuse close() for tabs they did not script-open.
38658
+ }
38659
+ return !win.closed;
38660
+ }
38661
+
38269
38662
  /**
38270
38663
  * EyeDropper colour sampler (framework-agnostic).
38271
38664
  *
@@ -47612,6 +48005,7 @@ const translationsEn = {
47612
48005
  'pptx.presentation.highlighter': 'Highlighter',
47613
48006
  'pptx.presentation.eraser': 'Eraser',
47614
48007
  'pptx.presentation.laserPointer': 'Laser Pointer',
48008
+ 'pptx.presentation.endOfSlideShow': 'End of slide show, click to exit.',
47615
48009
  'pptx.presentation.pointerTools': 'Pointer Options',
47616
48010
  // Selection pane
47617
48011
  'pptx.selectionPane.title': 'Selection Pane',
@@ -51972,7 +52366,7 @@ function createLocalStorageBackend(namespace) {
51972
52366
  /** Try IndexedDB first; fall back to localStorage on any failure. */
51973
52367
  async function resolveBackend(dbName, namespace) {
51974
52368
  try {
51975
- const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-BSVKLMXQ.mjs');
52369
+ const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-DzzfR5jW.mjs');
51976
52370
  const db = await openChatDb(dbName);
51977
52371
  return createIdbBackend(db);
51978
52372
  }
@@ -54682,7 +55076,6 @@ const WRITE_BACK_DEBOUNCE_MS = 5_000;
54682
55076
  * handler so package parts the CRDT does not carry (media, fonts, rels) survive.
54683
55077
  */
54684
55078
  async function serializeWriteBack(ydoc, sourceBytes, templateElements) {
54685
- const { PptxHandler } = await import('pptx-viewer-core');
54686
55079
  const handler = new PptxHandler();
54687
55080
  await handler.load(sourceBytes.buffer);
54688
55081
  const slides = buildSaveSlides(readSlidesFromYDoc(ydoc), templateElements);
@@ -56165,16 +56558,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
56165
56558
  }], ctorParameters: () => [] });
56166
56559
  /**
56167
56560
  * Parse digital signatures from a `.pptx` ZIP buffer (best-effort; returns an
56168
- * empty array when there are none or parsing fails). `jszip`/`fast-xml-parser`
56169
- * are imported lazily so they stay out of the main chunk. Mirrors the Vue
56170
- * port's `parseSignaturesFromBuffer`.
56561
+ * empty array when there are none or parsing fails). Mirrors the Vue port's
56562
+ * `parseSignaturesFromBuffer`.
56563
+ *
56564
+ * `jszip`/`fast-xml-parser` are imported statically on purpose: `PptxHandler`
56565
+ * (imported above) already pulls both into the same chunk, so a dynamic import
56566
+ * here cannot move them anywhere. It only made bundlers emit
56567
+ * INEFFECTIVE_DYNAMIC_IMPORT.
56171
56568
  */
56172
56569
  async function parseSignaturesFromBuffer(buffer) {
56173
56570
  try {
56174
- const [{ default: JSZip }, { XMLParser }] = await Promise.all([
56175
- import('jszip'),
56176
- import('fast-xml-parser'),
56177
- ]);
56178
56571
  const zip = await JSZip.loadAsync(buffer);
56179
56572
  const parser = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: '@_' });
56180
56573
  const result = [];
@@ -62210,9 +62603,10 @@ class AnimationPlaybackService {
62210
62603
  * (entrance-animated elements start hidden). Auto-plays the first click-group
62211
62604
  * when the slide opens with a withPrevious / afterPrevious / afterDelay build.
62212
62605
  */
62213
- setSlide(slide, showWithAnimation) {
62606
+ setSlide(slide, showWithAnimation, options) {
62214
62607
  this.showWithAnimation = showWithAnimation;
62215
62608
  this.clearTimers();
62609
+ this.seededCompleted = false;
62216
62610
  if (!slide || !this.animationsEnabled()) {
62217
62611
  this.controller = null;
62218
62612
  this.presentationElementStates.set(new Map());
@@ -62232,6 +62626,16 @@ class AnimationPlaybackService {
62232
62626
  this.hoverTriggerShapeIds.set(controller.hoverTriggerShapeIds);
62233
62627
  this.presentationElementStates.set(controller.computeStates());
62234
62628
  this.syncComplete();
62629
+ // Stepping backward onto a slide shows it with every build already
62630
+ // complete, the way PowerPoint does: nothing plays, nothing is scheduled,
62631
+ // and a further back press replays the slide from the start.
62632
+ if (options?.completed) {
62633
+ this.seededCompleted = controller.hasMoreSteps();
62634
+ controller.completeAll();
62635
+ this.presentationElementStates.set(controller.computeStates());
62636
+ this.syncComplete();
62637
+ return;
62638
+ }
62235
62639
  // Auto-play the first group when the slide opens with a withPrevious /
62236
62640
  // afterPrevious / afterDelay build (mirrors React's entrance auto-play).
62237
62641
  if (controller.hasMoreSteps()) {
@@ -62249,6 +62653,16 @@ class AnimationPlaybackService {
62249
62653
  }
62250
62654
  }
62251
62655
  }
62656
+ /**
62657
+ * True while the active slide shows its builds as already complete because
62658
+ * the presenter stepped BACKWARD onto it. The next back press replays the
62659
+ * slide instead of leaving it (PowerPoint's behaviour).
62660
+ */
62661
+ seededCompleted = false;
62662
+ /** Whether the active slide was seeded as fully built (backward entry). */
62663
+ isSeededCompleted() {
62664
+ return this.seededCompleted;
62665
+ }
62252
62666
  // ------------------------------------------------------------------
62253
62667
  // Playback controls
62254
62668
  // ------------------------------------------------------------------
@@ -67904,6 +68318,31 @@ class ElementRendererComponent {
67904
68318
  */
67905
68319
  animationState = computed(() => this.playback?.presentationElementStates().get(this.element().id), /* @ts-ignore */
67906
68320
  ...(ngDevMode ? [{ debugName: "animationState" }] : /* istanbul ignore next */ []));
68321
+ /**
68322
+ * Per-paragraph split for a staged text build (by paragraph / word / letter),
68323
+ * or `undefined` entries to render the runs normally. PowerPoint's "Animate
68324
+ * text: By letter" needs the rendered text split to match the per-character
68325
+ * sub-animations, otherwise the whole box just fades as one.
68326
+ */
68327
+ textBuildSpecs = computed(() => {
68328
+ const states = this.playback?.presentationElementStates();
68329
+ if (!states || states.size === 0) {
68330
+ return [];
68331
+ }
68332
+ const id = this.element().id;
68333
+ return this.paragraphs().map((para, paraIndex) => buildTextBuildSpec(id, paraIndex, para.runs
68334
+ .filter((run) => run.text !== '\n')
68335
+ .map((run) => ({ text: run.text, style: run.style })), states));
68336
+ }, /* @ts-ignore */
68337
+ ...(ngDevMode ? [{ debugName: "textBuildSpecs" }] : /* istanbul ignore next */ []));
68338
+ /** Whole-paragraph text, for the paragraph-level build wrapper. */
68339
+ paragraphText(para) {
68340
+ return para.runs.map((run) => run.text).join('');
68341
+ }
68342
+ /** Style for one build piece, merged over the run's own style. */
68343
+ buildSpanStyle(span) {
68344
+ return { ...(span.style ?? {}), ...textBuildSpanStyle(span) };
68345
+ }
67907
68346
  containerStyle = computed(() => ({
67908
68347
  ...getContainerStyle(this.element(), this.zIndex()),
67909
68348
  ...this.templateAffordanceStyle(),
@@ -68276,6 +68715,25 @@ class ElementRendererComponent {
68276
68715
  >{{ para.bulletMarker }}&nbsp;</span
68277
68716
  >
68278
68717
  }
68718
+ @if (textBuildSpecs()[$index]; as spec) {
68719
+ <!-- Staged text build: render the split pieces so each one
68720
+ carries its own sub-animation. -->
68721
+ @if (spec.granularity === 'paragraph') {
68722
+ <span
68723
+ [attr.data-anim-id]="spec.animId"
68724
+ [ngStyle]="buildSpanStyle(spec)"
68725
+ >{{ paragraphText(para) }}</span
68726
+ >
68727
+ } @else {
68728
+ @for (span of spec.spans ?? []; track $index) {
68729
+ <span
68730
+ [attr.data-anim-id]="span.animId"
68731
+ [ngStyle]="buildSpanStyle(span)"
68732
+ >{{ span.text }}</span
68733
+ >
68734
+ }
68735
+ }
68736
+ } @else {
68279
68737
  @for (run of para.runs; track $index) {
68280
68738
  @if (run.equationXml) {
68281
68739
  <pptx-equation-renderer
@@ -68302,6 +68760,7 @@ class ElementRendererComponent {
68302
68760
  <span [ngStyle]="run.style">{{ run.text }}</span>
68303
68761
  }
68304
68762
  }
68763
+ }
68305
68764
  </p>
68306
68765
  }
68307
68766
  </div>
@@ -68616,6 +69075,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
68616
69075
  >{{ para.bulletMarker }}&nbsp;</span
68617
69076
  >
68618
69077
  }
69078
+ @if (textBuildSpecs()[$index]; as spec) {
69079
+ <!-- Staged text build: render the split pieces so each one
69080
+ carries its own sub-animation. -->
69081
+ @if (spec.granularity === 'paragraph') {
69082
+ <span
69083
+ [attr.data-anim-id]="spec.animId"
69084
+ [ngStyle]="buildSpanStyle(spec)"
69085
+ >{{ paragraphText(para) }}</span
69086
+ >
69087
+ } @else {
69088
+ @for (span of spec.spans ?? []; track $index) {
69089
+ <span
69090
+ [attr.data-anim-id]="span.animId"
69091
+ [ngStyle]="buildSpanStyle(span)"
69092
+ >{{ span.text }}</span
69093
+ >
69094
+ }
69095
+ }
69096
+ } @else {
68619
69097
  @for (run of para.runs; track $index) {
68620
69098
  @if (run.equationXml) {
68621
69099
  <pptx-equation-renderer
@@ -68642,6 +69120,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
68642
69120
  <span [ngStyle]="run.style">{{ run.text }}</span>
68643
69121
  }
68644
69122
  }
69123
+ }
68645
69124
  </p>
68646
69125
  }
68647
69126
  </div>
@@ -76564,8 +77043,9 @@ class PresenterWindowService {
76564
77043
  onSlide(message.slideIndex);
76565
77044
  }
76566
77045
  else if (message.type === 'presenter-exit') {
77046
+ // The host decides what an ended session looks like (close the tab,
77047
+ // else show the end screen). It must never land in the editor.
76567
77048
  onExit();
76568
- window.close();
76569
77049
  }
76570
77050
  };
76571
77051
  channel.addEventListener('message', onMessage);
@@ -78070,6 +78550,22 @@ function fitZoom(canvasW, canvasH, vw, vh) {
78070
78550
  }
78071
78551
  return Math.min(vw / canvasW, vh / canvasH);
78072
78552
  }
78553
+ /**
78554
+ * Whether a visible (non-hidden) slide exists strictly AFTER `current`.
78555
+ *
78556
+ * `nextVisibleIndex` wraps modulo the deck length, which makes a show loop for
78557
+ * ever. PowerPoint only loops when "Loop continuously until Esc" is set;
78558
+ * otherwise running past the last slide ends the show. Callers use this to tell
78559
+ * "there is a next slide" from "we just wrapped".
78560
+ */
78561
+ function hasVisibleSlideAfter(current, slides) {
78562
+ for (let index = current + 1; index < slides.length; index++) {
78563
+ if (!slides[index].hidden) {
78564
+ return true;
78565
+ }
78566
+ }
78567
+ return false;
78568
+ }
78073
78569
 
78074
78570
  /** Compatibility barrel for shared live-caption helpers and structural types. */
78075
78571
 
@@ -78579,6 +79075,13 @@ class PresentationOverlayComponent {
78579
79075
  ...(ngDevMode ? [{ debugName: "showWithAnimation" }] : /* istanbul ignore next */ []));
78580
79076
  subtitlesVisible = input(false, /* @ts-ignore */
78581
79077
  ...(ngDevMode ? [{ debugName: "subtitlesVisible" }] : /* istanbul ignore next */ []));
79078
+ /**
79079
+ * Set by an audience display when the presenter ends the session and the
79080
+ * browser refuses to close the tab. It raises the black end-of-slide-show
79081
+ * screen so the room never sees the editing chrome.
79082
+ */
79083
+ sessionEnded = input(false, /* @ts-ignore */
79084
+ ...(ngDevMode ? [{ debugName: "sessionEnded" }] : /* istanbul ignore next */ []));
78582
79085
  // ------------------------------------------------------------------
78583
79086
  // Outputs
78584
79087
  // ------------------------------------------------------------------
@@ -78599,6 +79102,26 @@ class PresentationOverlayComponent {
78599
79102
  /** PowerPoint's Ctrl+M: hide ink markup without discarding the strokes. */
78600
79103
  inkMarkupVisible = signal(true, /* @ts-ignore */
78601
79104
  ...(ngDevMode ? [{ debugName: "inkMarkupVisible" }] : /* istanbul ignore next */ []));
79105
+ /**
79106
+ * True once the show has run past its last slide and the black "End of slide
79107
+ * show" screen is up. It MUST be surfaced: while it is up the next input
79108
+ * either goes nowhere (backward) or ends the show (forward), so a deck that
79109
+ * kept painting its last slide looked stuck and swallowed every advance.
79110
+ */
79111
+ endOfShow = signal(false, /* @ts-ignore */
79112
+ ...(ngDevMode ? [{ debugName: "endOfShow" }] : /* istanbul ignore next */ []));
79113
+ /**
79114
+ * Set just before a BACKWARD slide change so the slide effect seeds the
79115
+ * incoming slide as fully built.
79116
+ */
79117
+ pendingCompletedEntry = false;
79118
+ /** Mirror the host's audience "session ended" flag onto the end screen. */
79119
+ syncSessionEnded = effect(() => {
79120
+ if (this.sessionEnded()) {
79121
+ this.endOfShow.set(true);
79122
+ }
79123
+ }, /* @ts-ignore */
79124
+ ...(ngDevMode ? [{ debugName: "syncSessionEnded" }] : /* istanbul ignore next */ []));
78602
79125
  syncExternalIndex = effect(() => {
78603
79126
  const count = this.slides().length;
78604
79127
  if (count === 0) {
@@ -78666,7 +79189,9 @@ class PresentationOverlayComponent {
78666
79189
  // pre-build state so entrance-animated elements start hidden) and publish its
78667
79190
  // per-slide keyframes CSS.
78668
79191
  effect(() => {
78669
- this.playback.setSlide(this.currentSlide(), this.showWithAnimation());
79192
+ const completed = this.pendingCompletedEntry;
79193
+ this.pendingCompletedEntry = false;
79194
+ this.playback.setSlide(this.currentSlide(), this.showWithAnimation(), { completed });
78670
79195
  this.slideKeyframes.set(this.playback.keyframesCss());
78671
79196
  });
78672
79197
  // Apply each element's native-animation state (visibility, CSS animation,
@@ -78967,6 +79492,12 @@ class PresentationOverlayComponent {
78967
79492
  /** Digit buffer backing PowerPoint's "type a slide number, then Enter" jump. */
78968
79493
  keyBuffer = createPresentationKeyBuffer();
78969
79494
  onKeyDown(event) {
79495
+ // An audience display mirrors the presenter's screen. If its own keyboard
79496
+ // navigated, a stray key moved it off the presenter's slide and the next
79497
+ // snapshot yanked it back, which reads as the display refusing to advance.
79498
+ if (!acceptsPresentationInput()) {
79499
+ return;
79500
+ }
78970
79501
  const mapped = mapPresentationKey(event, this.keyBuffer);
78971
79502
  if (mapped.action === 'none') {
78972
79503
  return;
@@ -79054,11 +79585,22 @@ class PresentationOverlayComponent {
79054
79585
  * next/prev buttons call navigate() directly and are never gated.
79055
79586
  */
79056
79587
  advanceFromClick() {
79588
+ // An audience display never drives itself: a tap or swipe of its own would
79589
+ // move it off the presenter's slide, and the next snapshot would drag it back.
79590
+ if (!acceptsPresentationInput()) {
79591
+ return;
79592
+ }
79057
79593
  if (shouldBlockClickAdvance(this.playback.isComplete(), this.currentSlide())) {
79058
79594
  return;
79059
79595
  }
79060
79596
  this.navigate('next');
79061
79597
  }
79598
+ /** Click on the end screen: exit the show, like PowerPoint's "click to exit". */
79599
+ onEndScreenClick(event) {
79600
+ event.stopPropagation();
79601
+ this.endOfShow.set(false);
79602
+ this.emitClosed();
79603
+ }
79062
79604
  /** Toggle an annotation tool (clicking the active one disarms it). */
79063
79605
  selectTool(tool) {
79064
79606
  this.annotations.setTool(tool);
@@ -79110,11 +79652,31 @@ class PresentationOverlayComponent {
79110
79652
  if (count === 0) {
79111
79653
  return;
79112
79654
  }
79655
+ // While the end screen is up a forward input ends the show (PowerPoint's
79656
+ // "click to exit") and a backward input just dismisses it.
79657
+ if (this.endOfShow()) {
79658
+ this.endOfShow.set(false);
79659
+ if (direction === 'next') {
79660
+ this.emitClosed();
79661
+ }
79662
+ return;
79663
+ }
79113
79664
  // On forward navigation, first reveal the next click-group of element
79114
79665
  // animations; only advance the slide once the slide's builds are exhausted.
79115
79666
  if (direction === 'next' && this.playback.advance()) {
79116
79667
  return;
79117
79668
  }
79669
+ if (direction === 'prev') {
79670
+ // A slide entered backward shows its builds already complete. The next
79671
+ // back press replays them from the start rather than leaving the slide,
79672
+ // so a presenter who overshot can watch the build again (PowerPoint).
79673
+ if (this.playback.isSeededCompleted()) {
79674
+ this.playback.setSlide(this.currentSlide(), this.showWithAnimation());
79675
+ return;
79676
+ }
79677
+ // PowerPoint shows a slide you step BACK onto with its builds played.
79678
+ this.pendingCompletedEntry = true;
79679
+ }
79118
79680
  const current = this.currentIndex();
79119
79681
  let next;
79120
79682
  switch (direction) {
@@ -79131,6 +79693,13 @@ class PresentationOverlayComponent {
79131
79693
  next = clampIndex(count - 1, count);
79132
79694
  break;
79133
79695
  }
79696
+ if (direction === 'next' && !hasVisibleSlideAfter(current, slides)) {
79697
+ // Nothing further to advance to. `nextVisibleIndex` would wrap back to
79698
+ // the first slide and loop for ever; PowerPoint only loops when "Loop
79699
+ // continuously until Esc" is set, so end the show instead.
79700
+ this.endOfShow.set(true);
79701
+ return;
79702
+ }
79134
79703
  if (next !== current) {
79135
79704
  // Play the incoming slide's transition (if any) over the new slide,
79136
79705
  // animating the outgoing slide out. Forward navigation only, matching
@@ -79169,6 +79738,12 @@ class PresentationOverlayComponent {
79169
79738
  this.indexChange.emit(next);
79170
79739
  }
79171
79740
  emitClosed() {
79741
+ // An audience display mirrors the presenter's screen: Escape, leaving
79742
+ // fullscreen and the advance past the end screen must never hand the room
79743
+ // the editing chrome.
79744
+ if (!mayLeaveSlideShow()) {
79745
+ return;
79746
+ }
79172
79747
  if (this.closing) {
79173
79748
  return;
79174
79749
  }
@@ -79179,7 +79754,7 @@ class PresentationOverlayComponent {
79179
79754
  this.closed.emit();
79180
79755
  }
79181
79756
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PresentationOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
79182
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: PresentationOverlayComponent, isStandalone: true, selector: "pptx-presentation-overlay", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, startIndex: { classPropertyName: "startIndex", publicName: "startIndex", isSignal: true, isRequired: false, transformFunction: null }, showWithAnimation: { classPropertyName: "showWithAnimation", publicName: "showWithAnimation", isSignal: true, isRequired: false, transformFunction: null }, subtitlesVisible: { classPropertyName: "subtitlesVisible", publicName: "subtitlesVisible", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { indexChange: "indexChange", closed: "closed", subtitlesChange: "subtitlesChange", annotationsExit: "annotationsExit" }, host: { listeners: { "document:fullscreenchange": "onFullscreenChange()", "window:resize": "onWindowResize()", "document:keydown": "onKeyDown($event)" } }, providers: [AnimationPlaybackService, PresentationAnnotationsService, ZoomNavigationService], viewQueries: [{ propertyName: "stageRef", first: true, predicate: ["stage"], descendants: true, isSignal: true }, { propertyName: "rootRef", first: true, predicate: ["root"], descendants: true, isSignal: true }], ngImport: i0, template: `
79757
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: PresentationOverlayComponent, isStandalone: true, selector: "pptx-presentation-overlay", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, startIndex: { classPropertyName: "startIndex", publicName: "startIndex", isSignal: true, isRequired: false, transformFunction: null }, showWithAnimation: { classPropertyName: "showWithAnimation", publicName: "showWithAnimation", isSignal: true, isRequired: false, transformFunction: null }, subtitlesVisible: { classPropertyName: "subtitlesVisible", publicName: "subtitlesVisible", isSignal: true, isRequired: false, transformFunction: null }, sessionEnded: { classPropertyName: "sessionEnded", publicName: "sessionEnded", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { indexChange: "indexChange", closed: "closed", subtitlesChange: "subtitlesChange", annotationsExit: "annotationsExit" }, host: { listeners: { "document:fullscreenchange": "onFullscreenChange()", "window:resize": "onWindowResize()", "document:keydown": "onKeyDown($event)" } }, providers: [AnimationPlaybackService, PresentationAnnotationsService, ZoomNavigationService], viewQueries: [{ propertyName: "stageRef", first: true, predicate: ["stage"], descendants: true, isSignal: true }, { propertyName: "rootRef", first: true, predicate: ["root"], descendants: true, isSignal: true }], ngImport: i0, template: `
79183
79758
  <div #root class="pptx-ng-presentation-root">
79184
79759
  <!--
79185
79760
  Slide counter, rendered first in DOM (before slide content) so a
@@ -79191,6 +79766,21 @@ class PresentationOverlayComponent {
79191
79766
  {{ counterLabel() }}
79192
79767
  </span>
79193
79768
 
79769
+ <!-- Black "End of slide show" screen: the show has run past its last
79770
+ slide. It MUST be visible - while it is up the next input either
79771
+ goes nowhere (backward) or ends the show (forward), so a deck that
79772
+ kept painting the last slide looked stuck and swallowed advances. -->
79773
+ @if (endOfShow()) {
79774
+ <button
79775
+ type="button"
79776
+ class="pptx-ng-presentation-end"
79777
+ data-pptx-end-of-show
79778
+ (click)="onEndScreenClick($event)"
79779
+ >
79780
+ <span>{{ 'pptx.presentation.endOfSlideShow' | translate }}</span>
79781
+ </button>
79782
+ }
79783
+
79194
79784
  <div
79195
79785
  #stage
79196
79786
  class="pptx-ng-presentation-stage"
@@ -79333,7 +79923,7 @@ class PresentationOverlayComponent {
79333
79923
  <svg lucideChevronRight class="h-6 w-6"></svg>
79334
79924
  </button>
79335
79925
  </div>
79336
- `, 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", "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 });
79926
+ `, 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 });
79337
79927
  }
79338
79928
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PresentationOverlayComponent, decorators: [{
79339
79929
  type: Component,
@@ -79364,6 +79954,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
79364
79954
  {{ counterLabel() }}
79365
79955
  </span>
79366
79956
 
79957
+ <!-- Black "End of slide show" screen: the show has run past its last
79958
+ slide. It MUST be visible - while it is up the next input either
79959
+ goes nowhere (backward) or ends the show (forward), so a deck that
79960
+ kept painting the last slide looked stuck and swallowed advances. -->
79961
+ @if (endOfShow()) {
79962
+ <button
79963
+ type="button"
79964
+ class="pptx-ng-presentation-end"
79965
+ data-pptx-end-of-show
79966
+ (click)="onEndScreenClick($event)"
79967
+ >
79968
+ <span>{{ 'pptx.presentation.endOfSlideShow' | translate }}</span>
79969
+ </button>
79970
+ }
79971
+
79367
79972
  <div
79368
79973
  #stage
79369
79974
  class="pptx-ng-presentation-stage"
@@ -79506,8 +80111,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
79506
80111
  <svg lucideChevronRight class="h-6 w-6"></svg>
79507
80112
  </button>
79508
80113
  </div>
79509
- `, 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"] }]
79510
- }], 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: [{
80114
+ `, 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"] }]
80115
+ }], 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 }] }], sessionEnded: [{ type: i0.Input, args: [{ isSignal: true, alias: "sessionEnded", 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: [{
79511
80116
  type: HostListener,
79512
80117
  args: ['document:fullscreenchange']
79513
80118
  }], onWindowResize: [{
@@ -79697,6 +80302,20 @@ class PresenterViewComponent {
79697
80302
  ...(ngDevMode ? [{ debugName: "progressValue" }] : /* istanbul ignore next */ []));
79698
80303
  slideBadge = computed(() => slideLabel(this.currentSlideIndex(), this.slides().length), /* @ts-ignore */
79699
80304
  ...(ngDevMode ? [{ debugName: "slideBadge" }] : /* istanbul ignore next */ []));
80305
+ /**
80306
+ * Clicking the current-slide pane advances the show, the way PowerPoint's
80307
+ * presenter console does: it is how presenters actually drive a deck, with
80308
+ * the Next button and the keyboard as fallbacks. A drawing tool owns the
80309
+ * pointer instead, so clicking then annotates rather than jumping the deck
80310
+ * out from under the stroke.
80311
+ */
80312
+ paneAdvancesOnClick = computed(() => presenterPaneAdvancesOnClick(this.presenterWindow.snapshot().pointer?.tool), /* @ts-ignore */
80313
+ ...(ngDevMode ? [{ debugName: "paneAdvancesOnClick" }] : /* istanbul ignore next */ []));
80314
+ onSlidePaneClick() {
80315
+ if (this.paneAdvancesOnClick()) {
80316
+ this.movePresentationSlide.emit(1);
80317
+ }
80318
+ }
79700
80319
  counterLabel = computed(() => slideCounter(this.currentSlideIndex(), this.slides().length), /* @ts-ignore */
79701
80320
  ...(ngDevMode ? [{ debugName: "counterLabel" }] : /* istanbul ignore next */ []));
79702
80321
  notesBodyStyle = computed(() => ({
@@ -79750,7 +80369,13 @@ class PresenterViewComponent {
79750
80369
  />
79751
80370
  <div class="pptx-ng-presenter-body">
79752
80371
  <!-- Current slide (≈70%) -->
79753
- <div class="pptx-ng-presenter-current">
80372
+ <div
80373
+ class="pptx-ng-presenter-current"
80374
+ [class.pptx-ng-presenter-current--advances]="paneAdvancesOnClick()"
80375
+ role="presentation"
80376
+ data-pptx-presenter-slide
80377
+ (click)="onSlidePaneClick()"
80378
+ >
79754
80379
  <div class="pptx-ng-presenter-preview-stage">
79755
80380
  <pptx-slide-canvas
79756
80381
  [slide]="currentPreviewSlide()"
@@ -79919,7 +80544,7 @@ class PresenterViewComponent {
79919
80544
  } @else {
79920
80545
  <div class="pptx-ng-presenter-empty">{{ 'pptx.presenter.noSlides' | translate }}</div>
79921
80546
  }
79922
- `, 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 });
80547
+ `, 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 });
79923
80548
  }
79924
80549
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PresenterViewComponent, decorators: [{
79925
80550
  type: Component,
@@ -79939,7 +80564,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
79939
80564
  />
79940
80565
  <div class="pptx-ng-presenter-body">
79941
80566
  <!-- Current slide (≈70%) -->
79942
- <div class="pptx-ng-presenter-current">
80567
+ <div
80568
+ class="pptx-ng-presenter-current"
80569
+ [class.pptx-ng-presenter-current--advances]="paneAdvancesOnClick()"
80570
+ role="presentation"
80571
+ data-pptx-presenter-slide
80572
+ (click)="onSlidePaneClick()"
80573
+ >
79943
80574
  <div class="pptx-ng-presenter-preview-stage">
79944
80575
  <pptx-slide-canvas
79945
80576
  [slide]="currentPreviewSlide()"
@@ -80108,7 +80739,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
80108
80739
  } @else {
80109
80740
  <div class="pptx-ng-presenter-empty">{{ 'pptx.presenter.noSlides' | translate }}</div>
80110
80741
  }
80111
- `, 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"] }]
80742
+ `, 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"] }]
80112
80743
  }], 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"] }] } });
80113
80744
 
80114
80745
  /**
@@ -84146,7 +84777,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
84146
84777
  }], propDecorators: { canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }] } });
84147
84778
 
84148
84779
  // Generated by scripts/inline-shared.mjs from package.json. Do not edit.
84149
- const PPTX_ANGULAR_VIEWER_VERSION = "2.2.1";
84780
+ const PPTX_ANGULAR_VIEWER_VERSION = "2.4.0";
84150
84781
 
84151
84782
  /**
84152
84783
  * account-page.component.ts: File > Account content.
@@ -108363,6 +108994,13 @@ class PowerPointViewerComponent {
108363
108994
  ...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
108364
108995
  activeSlideIndex = signal(0, /* @ts-ignore */
108365
108996
  ...(ngDevMode ? [{ debugName: "activeSlideIndex" }] : /* istanbul ignore next */ []));
108997
+ /**
108998
+ * True in an audience display once the presenter ended the session and the
108999
+ * browser refused to close this tab: the overlay then shows the black
109000
+ * end-of-slide-show screen rather than falling back to the editor.
109001
+ */
109002
+ audienceSessionEnded = signal(false, /* @ts-ignore */
109003
+ ...(ngDevMode ? [{ debugName: "audienceSessionEnded" }] : /* istanbul ignore next */ []));
108366
109004
  /** Slides to display: the editable deck when `canEdit`, else the loaded deck. */
108367
109005
  displaySlides = computed(() => this.canEdit() ? this.editor.slides() : this.loader.slides(), /* @ts-ignore */
108368
109006
  ...(ngDevMode ? [{ debugName: "displaySlides" }] : /* istanbul ignore next */ []));
@@ -108942,7 +109580,15 @@ class PowerPointViewerComponent {
108942
109580
  },
108943
109581
  });
108944
109582
  if (parseAudienceNonce()) {
108945
- const disconnectAudience = this.presenterWindow.connectAudience((index) => this.activeSlideIndex.set(index), () => this.presentationMode.presenting.set(false));
109583
+ const disconnectAudience = this.presenterWindow.connectAudience((index) => this.activeSlideIndex.set(index),
109584
+ // The presenter ended the session. Close this tab; when the browser
109585
+ // refuses, raise the end-of-slide-show screen. Leaving presentation
109586
+ // mode would drop the room into the editor.
109587
+ () => {
109588
+ if (endAudienceDisplay(window)) {
109589
+ this.audienceSessionEnded.set(true);
109590
+ }
109591
+ });
108946
109592
  this.presentationMode.presenting.set(true);
108947
109593
  this.destroyRef.onDestroy(disconnectAudience);
108948
109594
  }
@@ -110049,6 +110695,7 @@ class PowerPointViewerComponent {
110049
110695
  [startIndex]="customShowsCtl.presentationStartIndex()"
110050
110696
  [showWithAnimation]="loader.presentationProperties().showWithAnimation"
110051
110697
  [subtitlesVisible]="presentationMode.subtitlesVisible()"
110698
+ [sessionEnded]="audienceSessionEnded()"
110052
110699
  (subtitlesChange)="presentationMode.subtitlesVisible.set($event)"
110053
110700
  (indexChange)="presentationMode.onPresentationIndexChange($event)"
110054
110701
  (annotationsExit)="presentationMode.onPresentationAnnotationsExit($event)"
@@ -110327,7 +110974,7 @@ class PowerPointViewerComponent {
110327
110974
  />
110328
110975
  }
110329
110976
  </div>
110330
- `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationOverlayComponent, selector: "pptx-presentation-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "startIndex", "showWithAnimation", "subtitlesVisible"], outputs: ["indexChange", "closed", "subtitlesChange", "annotationsExit"] }, { kind: "component", type: PresenterViewComponent, selector: "pptx-presenter-view", inputs: ["slides", "currentSlideIndex", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime", "isAudienceWindowOpen"], outputs: ["movePresentationSlide", "exit", "openAudienceWindow", "closeAudienceWindow", "navigateToSlide"] }, { kind: "component", type: MobilePresenterViewComponent, selector: "pptx-mobile-presenter-view", inputs: ["slides", "currentSlideIndex", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime"], outputs: ["movePresentationSlide", "exit"] }, { kind: "component", type: SlideSorterOverlayComponent, selector: "pptx-slide-sorter-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select", "closed"] }, { kind: "component", type: SlideDefaultInspectorComponent, selector: "pptx-slide-default-inspector", inputs: ["slideIndex", "canEdit", "selectedElement", "comments"], outputs: ["commentAdd", "commentRemove", "commentResolve"] }, { kind: "component", type: FindBarComponent, selector: "pptx-find-bar", inputs: ["slides"], outputs: ["navigate", "closed"] }, { kind: "component", type: FindReplaceBarComponent, selector: "pptx-find-replace-bar", inputs: ["matchCount", "matchIndex"], outputs: ["find", "navigate", "replaceOne", "replaceAll", "close"] }, { kind: "component", type: SlidesPanelComponent, selector: "pptx-slides-panel", inputs: ["canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select"] }, { kind: "component", type: StatusBarComponent, selector: "pptx-status-bar", inputs: ["slideIndex", "slideCount", "canEdit", "dirty", "autosaveStatus", "notesOpen", "zoomPercent", "sorterActive", "presenting", "hiddenActions"], outputs: ["toggleNotes", "normalView", "openSorter", "slideShow", "zoomIn", "zoomOut", "zoomReset"] }, { kind: "component", type: EditorContextMenuComponent, selector: "pptx-editor-context-menu", inputs: ["x", "y", "slideIndex", "showAiActions"], outputs: ["closed", "askAi", "fixAi"] }, { kind: "component", type: ExportProgressModalComponent, selector: "pptx-export-progress-modal", inputs: ["open", "title", "progress", "statusMessage"], outputs: ["cancel"] }, { kind: "component", type: CommentsPanelComponent, selector: "pptx-comments-panel", inputs: ["comments", "authorName"], outputs: ["add", "remove", "resolve"] }, { kind: "component", type: SignaturesPanelComponent, selector: "pptx-signatures-panel", inputs: ["signatures"] }, { kind: "component", type: AccessibilityPanelComponent, selector: "pptx-accessibility-panel", inputs: ["issues"], outputs: ["selectSlide"] }, { kind: "component", type: CollaborationCursorsComponent, selector: "pptx-collaboration-cursors", inputs: ["cursors", "zoom"] }, { kind: "component", type: RemoteSelectionOverlayComponent, selector: "pptx-remote-selection-overlay", inputs: ["presences", "elements", "activeSlideIndex", "zoom"] }, { kind: "component", type: FollowModeBarComponent, selector: "pptx-follow-mode-bar", inputs: ["presences", "followedClientId"], outputs: ["follow"] }, { kind: "component", type: PropertiesDialogComponent, selector: "pptx-properties-dialog", inputs: ["open", "properties"], outputs: ["save", "close"] }, { kind: "component", type: HyperlinkDialogComponent, selector: "pptx-hyperlink-dialog", inputs: ["open", "element"], outputs: ["save", "close"] }, { kind: "component", type: PrintDialogComponent, selector: "pptx-print-dialog", inputs: ["slides", "activeSlideIndex", "defaultSlidesPerPage", "defaultFrameSlides"], outputs: ["print", "cancel"] }, { kind: "component", type: ShareDialogComponent, selector: "pptx-share-dialog", inputs: ["open", "defaults", "active", "connected", "userCount", "shareUrl", "p2p"], outputs: ["start", "stop", "close"] }, { kind: "component", type: BroadcastDialogComponent, selector: "pptx-broadcast-dialog", inputs: ["open", "defaults", "active", "connected", "viewerCount", "viewerUrl", "p2p"], outputs: ["start", "stop", "close"] }, { kind: "component", type: MobileBottomBarComponent, selector: "pptx-mobile-bottom-bar", inputs: ["slideCount", "commentCount", "activeSheet"], outputs: ["openSlides", "insert", "openFormat", "openComments", "notes"] }, { kind: "component", type: MobileMenuSheetComponent, selector: "pptx-mobile-menu-sheet", inputs: ["open", "slideCount", "exporting", "showNotes", "canEdit", "hiddenActions"], outputs: ["closed", "openFind", "openSorter", "toggleNotes", "insertText", "present", "openFile", "savePptx", "exportPng", "exportPdf", "exportGif", "exportVideo", "print"] }, { kind: "component", type: MobileSlidesSheetComponent, selector: "pptx-mobile-slides-sheet", inputs: ["open", "slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["closed", "jumpToSlide"] }, { kind: "component", type: MobileToolbarComponent, selector: "pptx-mobile-toolbar", inputs: ["canUndo", "canRedo", "canPresent", "canEdit", "menuOpen", "aiEnabled", "aiPanelOpen", "hiddenActions"], outputs: ["toggleMenu", "toggleAiPanel", "undo", "redo", "share", "save", "present"] }, { kind: "component", type: MasterViewCanvasComponent, selector: "pptx-master-view-canvas", inputs: ["tab", "slideMasters", "activeMasterIndex", "activeLayoutIndex", "notesMaster", "handoutMaster", "canvasSize", "notesCanvasSize", "mediaDataUrls", "editable"], outputs: ["notesMasterChange", "handoutMasterChange"] }, { kind: "component", type: MasterViewSidebarComponent, selector: "pptx-master-view-sidebar", inputs: ["tab", "slideMasters", "notesMaster", "handoutMaster", "activeMasterIndex", "activeLayoutIndex", "handoutSlidesPerPage"], outputs: ["tabChange", "selectMaster", "selectLayout", "slidesPerPageChange", "backgroundChange", "close"] }, { kind: "component", type: NotesPanelComponent, selector: "pptx-notes-panel", inputs: ["slide", "expanded"], outputs: ["update", "notesToggle"] }, { kind: "component", type: RibbonComponent, selector: "pptx-ribbon", inputs: ["slideIndex", "slideCount", "canEdit", "selectedElement", "zoomPercent", "formatPainterActive", "canActivateFormatPainter", "exporting", "hasMacros", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "eyedropperActive", "themeGalleryOpen", "sidebarCollapsed", "inspectorOpen", "commentsOpen", "commentCount", "findOpen", "collabConnected", "connectedCount", "spellCheckEnabled", "showSubtitles", "hiddenActions", "aiEnabled", "aiPanelOpen", "accountAuth"], outputs: ["prev", "next", "zoomIn", "zoomOut", "zoomReset", "find", "present", "presenter", "record", "presentFromBeginning", "rehearseTimings", "toggleSubtitles", "openSubtitleSettings", "recordFromBeginning", "recordFromCurrent", "spellCheckChange", "share", "broadcast", "openFile", "openRecentFile", "createPresentation", "save", "savePpsx", "savePptm", "packageForSharing", "toggleSidebar", "toggleAiPanel", "signatures", "info", "print", "comments", "a11y", "link", "openSorter", "openMasterView", "toggleNotes", "toggleFormatPainter", "exportPng", "exportPdf", "exportGif", "exportVideo", "copySlideAsImage", "replace", "toggleInspector", "drawToolChange", "toggleThemeGallery", "toggleGrid", "toggleRulers", "toggleGuides", "toggleSelectionPane", "openCustomShows", "toggleSnapToGrid", "toggleSnapToShape", "addGuide", "zoomToFit", "toggleEyedropper", "openSmartArtDialog", "openEquationDialog", "openSetUpSlideShow", "openCompare", "openPassword", "openFontEmbedding", "openVersionHistory", "openShortcuts", "openSettings"] }, { kind: "component", type: TitleBarComponent, selector: "pptx-title-bar", inputs: ["canEdit", "fileName", "isDirty", "autosaveStatus", "autosaveEnabled", "canUndo", "canRedo", "undoLabel", "redoLabel", "findReplaceOpen", "hiddenActions", "quickAccess"], outputs: ["toggleAutosave", "save", "undo", "redo", "quickCommand", "toggleFindReplace", "commandSearch"] }, { kind: "component", type: ThemeGalleryComponent, selector: "pptx-theme-gallery", inputs: ["open", "activeName", "theme"], outputs: ["applyTheme", "applyCustomTheme", "close"] }, { kind: "component", type: SelectionPaneComponent, selector: "pptx-selection-pane", inputs: ["elements", "selectedIds"], outputs: ["selectElement", "bringForward", "sendBackward", "toggleHidden"] }, { kind: "component", type: CustomShowsComponent, selector: "pptx-custom-shows", inputs: ["open", "slides", "customShows", "activeCustomShowId"], outputs: ["create", "remove", "update", "setActive", "close"] }, { kind: "component", type: InsertSmartArtDialogComponent, selector: "pptx-insert-smart-art-dialog", inputs: ["open"], outputs: ["close", "insert"] }, { kind: "component", type: ViewerExtraDialogsComponent, selector: "pptx-viewer-extra-dialogs", inputs: ["activeSlideIndex", "selectedElementId", "filePath", "customShows", "themeKey", "availableThemes", "localeCode", "availableLocales", "aiExportVisible"], outputs: ["restoreContent", "themeKeySelect", "localeSelect"] }, { kind: "component", type: RehearseTimingsComponent, selector: "pptx-rehearse-timings", inputs: ["summary", "paused", "slideStartedAt", "presentationStartedAt", "timings"], outputs: ["togglePause", "save", "discard"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [/* @ts-ignore */
110977
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "interactive", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationOverlayComponent, selector: "pptx-presentation-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "startIndex", "showWithAnimation", "subtitlesVisible", "sessionEnded"], outputs: ["indexChange", "closed", "subtitlesChange", "annotationsExit"] }, { kind: "component", type: PresenterViewComponent, selector: "pptx-presenter-view", inputs: ["slides", "currentSlideIndex", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime", "isAudienceWindowOpen"], outputs: ["movePresentationSlide", "exit", "openAudienceWindow", "closeAudienceWindow", "navigateToSlide"] }, { kind: "component", type: MobilePresenterViewComponent, selector: "pptx-mobile-presenter-view", inputs: ["slides", "currentSlideIndex", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime"], outputs: ["movePresentationSlide", "exit"] }, { kind: "component", type: SlideSorterOverlayComponent, selector: "pptx-slide-sorter-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select", "closed"] }, { kind: "component", type: SlideDefaultInspectorComponent, selector: "pptx-slide-default-inspector", inputs: ["slideIndex", "canEdit", "selectedElement", "comments"], outputs: ["commentAdd", "commentRemove", "commentResolve"] }, { kind: "component", type: FindBarComponent, selector: "pptx-find-bar", inputs: ["slides"], outputs: ["navigate", "closed"] }, { kind: "component", type: FindReplaceBarComponent, selector: "pptx-find-replace-bar", inputs: ["matchCount", "matchIndex"], outputs: ["find", "navigate", "replaceOne", "replaceAll", "close"] }, { kind: "component", type: SlidesPanelComponent, selector: "pptx-slides-panel", inputs: ["canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select"] }, { kind: "component", type: StatusBarComponent, selector: "pptx-status-bar", inputs: ["slideIndex", "slideCount", "canEdit", "dirty", "autosaveStatus", "notesOpen", "zoomPercent", "sorterActive", "presenting", "hiddenActions"], outputs: ["toggleNotes", "normalView", "openSorter", "slideShow", "zoomIn", "zoomOut", "zoomReset"] }, { kind: "component", type: EditorContextMenuComponent, selector: "pptx-editor-context-menu", inputs: ["x", "y", "slideIndex", "showAiActions"], outputs: ["closed", "askAi", "fixAi"] }, { kind: "component", type: ExportProgressModalComponent, selector: "pptx-export-progress-modal", inputs: ["open", "title", "progress", "statusMessage"], outputs: ["cancel"] }, { kind: "component", type: CommentsPanelComponent, selector: "pptx-comments-panel", inputs: ["comments", "authorName"], outputs: ["add", "remove", "resolve"] }, { kind: "component", type: SignaturesPanelComponent, selector: "pptx-signatures-panel", inputs: ["signatures"] }, { kind: "component", type: AccessibilityPanelComponent, selector: "pptx-accessibility-panel", inputs: ["issues"], outputs: ["selectSlide"] }, { kind: "component", type: CollaborationCursorsComponent, selector: "pptx-collaboration-cursors", inputs: ["cursors", "zoom"] }, { kind: "component", type: RemoteSelectionOverlayComponent, selector: "pptx-remote-selection-overlay", inputs: ["presences", "elements", "activeSlideIndex", "zoom"] }, { kind: "component", type: FollowModeBarComponent, selector: "pptx-follow-mode-bar", inputs: ["presences", "followedClientId"], outputs: ["follow"] }, { kind: "component", type: PropertiesDialogComponent, selector: "pptx-properties-dialog", inputs: ["open", "properties"], outputs: ["save", "close"] }, { kind: "component", type: HyperlinkDialogComponent, selector: "pptx-hyperlink-dialog", inputs: ["open", "element"], outputs: ["save", "close"] }, { kind: "component", type: PrintDialogComponent, selector: "pptx-print-dialog", inputs: ["slides", "activeSlideIndex", "defaultSlidesPerPage", "defaultFrameSlides"], outputs: ["print", "cancel"] }, { kind: "component", type: ShareDialogComponent, selector: "pptx-share-dialog", inputs: ["open", "defaults", "active", "connected", "userCount", "shareUrl", "p2p"], outputs: ["start", "stop", "close"] }, { kind: "component", type: BroadcastDialogComponent, selector: "pptx-broadcast-dialog", inputs: ["open", "defaults", "active", "connected", "viewerCount", "viewerUrl", "p2p"], outputs: ["start", "stop", "close"] }, { kind: "component", type: MobileBottomBarComponent, selector: "pptx-mobile-bottom-bar", inputs: ["slideCount", "commentCount", "activeSheet"], outputs: ["openSlides", "insert", "openFormat", "openComments", "notes"] }, { kind: "component", type: MobileMenuSheetComponent, selector: "pptx-mobile-menu-sheet", inputs: ["open", "slideCount", "exporting", "showNotes", "canEdit", "hiddenActions"], outputs: ["closed", "openFind", "openSorter", "toggleNotes", "insertText", "present", "openFile", "savePptx", "exportPng", "exportPdf", "exportGif", "exportVideo", "print"] }, { kind: "component", type: MobileSlidesSheetComponent, selector: "pptx-mobile-slides-sheet", inputs: ["open", "slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["closed", "jumpToSlide"] }, { kind: "component", type: MobileToolbarComponent, selector: "pptx-mobile-toolbar", inputs: ["canUndo", "canRedo", "canPresent", "canEdit", "menuOpen", "aiEnabled", "aiPanelOpen", "hiddenActions"], outputs: ["toggleMenu", "toggleAiPanel", "undo", "redo", "share", "save", "present"] }, { kind: "component", type: MasterViewCanvasComponent, selector: "pptx-master-view-canvas", inputs: ["tab", "slideMasters", "activeMasterIndex", "activeLayoutIndex", "notesMaster", "handoutMaster", "canvasSize", "notesCanvasSize", "mediaDataUrls", "editable"], outputs: ["notesMasterChange", "handoutMasterChange"] }, { kind: "component", type: MasterViewSidebarComponent, selector: "pptx-master-view-sidebar", inputs: ["tab", "slideMasters", "notesMaster", "handoutMaster", "activeMasterIndex", "activeLayoutIndex", "handoutSlidesPerPage"], outputs: ["tabChange", "selectMaster", "selectLayout", "slidesPerPageChange", "backgroundChange", "close"] }, { kind: "component", type: NotesPanelComponent, selector: "pptx-notes-panel", inputs: ["slide", "expanded"], outputs: ["update", "notesToggle"] }, { kind: "component", type: RibbonComponent, selector: "pptx-ribbon", inputs: ["slideIndex", "slideCount", "canEdit", "selectedElement", "zoomPercent", "formatPainterActive", "canActivateFormatPainter", "exporting", "hasMacros", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "eyedropperActive", "themeGalleryOpen", "sidebarCollapsed", "inspectorOpen", "commentsOpen", "commentCount", "findOpen", "collabConnected", "connectedCount", "spellCheckEnabled", "showSubtitles", "hiddenActions", "aiEnabled", "aiPanelOpen", "accountAuth"], outputs: ["prev", "next", "zoomIn", "zoomOut", "zoomReset", "find", "present", "presenter", "record", "presentFromBeginning", "rehearseTimings", "toggleSubtitles", "openSubtitleSettings", "recordFromBeginning", "recordFromCurrent", "spellCheckChange", "share", "broadcast", "openFile", "openRecentFile", "createPresentation", "save", "savePpsx", "savePptm", "packageForSharing", "toggleSidebar", "toggleAiPanel", "signatures", "info", "print", "comments", "a11y", "link", "openSorter", "openMasterView", "toggleNotes", "toggleFormatPainter", "exportPng", "exportPdf", "exportGif", "exportVideo", "copySlideAsImage", "replace", "toggleInspector", "drawToolChange", "toggleThemeGallery", "toggleGrid", "toggleRulers", "toggleGuides", "toggleSelectionPane", "openCustomShows", "toggleSnapToGrid", "toggleSnapToShape", "addGuide", "zoomToFit", "toggleEyedropper", "openSmartArtDialog", "openEquationDialog", "openSetUpSlideShow", "openCompare", "openPassword", "openFontEmbedding", "openVersionHistory", "openShortcuts", "openSettings"] }, { kind: "component", type: TitleBarComponent, selector: "pptx-title-bar", inputs: ["canEdit", "fileName", "isDirty", "autosaveStatus", "autosaveEnabled", "canUndo", "canRedo", "undoLabel", "redoLabel", "findReplaceOpen", "hiddenActions", "quickAccess"], outputs: ["toggleAutosave", "save", "undo", "redo", "quickCommand", "toggleFindReplace", "commandSearch"] }, { kind: "component", type: ThemeGalleryComponent, selector: "pptx-theme-gallery", inputs: ["open", "activeName", "theme"], outputs: ["applyTheme", "applyCustomTheme", "close"] }, { kind: "component", type: SelectionPaneComponent, selector: "pptx-selection-pane", inputs: ["elements", "selectedIds"], outputs: ["selectElement", "bringForward", "sendBackward", "toggleHidden"] }, { kind: "component", type: CustomShowsComponent, selector: "pptx-custom-shows", inputs: ["open", "slides", "customShows", "activeCustomShowId"], outputs: ["create", "remove", "update", "setActive", "close"] }, { kind: "component", type: InsertSmartArtDialogComponent, selector: "pptx-insert-smart-art-dialog", inputs: ["open"], outputs: ["close", "insert"] }, { kind: "component", type: ViewerExtraDialogsComponent, selector: "pptx-viewer-extra-dialogs", inputs: ["activeSlideIndex", "selectedElementId", "filePath", "customShows", "themeKey", "availableThemes", "localeCode", "availableLocales", "aiExportVisible"], outputs: ["restoreContent", "themeKeySelect", "localeSelect"] }, { kind: "component", type: RehearseTimingsComponent, selector: "pptx-rehearse-timings", inputs: ["summary", "paused", "slideStartedAt", "presentationStartedAt", "timings"], outputs: ["togglePause", "save", "discard"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [/* @ts-ignore */
110331
110978
  Promise.resolve().then(function () { return aiChatPanel_component; }).then(m => m.AiChatPanelComponent)]] });
110332
110979
  }
110333
110980
  i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.0.8", ngImport: i0, type: PowerPointViewerComponent, resolveDeferredDeps: () => [/* @ts-ignore */
@@ -110834,6 +111481,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.0.8", ng
110834
111481
  [startIndex]="customShowsCtl.presentationStartIndex()"
110835
111482
  [showWithAnimation]="loader.presentationProperties().showWithAnimation"
110836
111483
  [subtitlesVisible]="presentationMode.subtitlesVisible()"
111484
+ [sessionEnded]="audienceSessionEnded()"
110837
111485
  (subtitlesChange)="presentationMode.subtitlesVisible.set($event)"
110838
111486
  (indexChange)="presentationMode.onPresentationIndexChange($event)"
110839
111487
  (annotationsExit)="presentationMode.onPresentationAnnotationsExit($event)"
@@ -112965,5 +113613,5 @@ function cn(...values) {
112965
113613
  * Generated bundle index. Do not edit.
112966
113614
  */
112967
113615
 
112968
- 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 };
112969
- //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-CcgJ4fgi.mjs.map
113616
+ 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 };
113617
+ //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-bV0DbHDY.mjs.map