pptx-angular-viewer 1.31.4 → 1.31.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -2,7 +2,7 @@ import { NgStyle, NgTemplateOutlet, NgClass } from '@angular/common';
|
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
3
|
import { InjectionToken, input, output, computed, ChangeDetectionStrategy, Component, signal, Injectable, inject, Injector, DestroyRef, effect, viewChild, ElementRef, HostListener, afterNextRender, forwardRef, untracked } from '@angular/core';
|
|
4
4
|
import { TranslatePipe, TranslateService, translate } from '@ngx-translate/core';
|
|
5
|
-
import { guideEmuToPx, getShapeClipPath, getAdjustmentAwareShapeClipPath, getShapeClipPathFromPreset, getCloudPathForRendering, hasShapeProperties, applyDrawingColorTransforms as applyDrawingColorTransforms$1, hslToRgb as hslToRgb$1, PRESET_COLOR_MAP, isImageLikeElement, hasTextProperties, stripXmlOrderSuffix, orderedXmlKey, MIN_ELEMENT_SIZE as MIN_ELEMENT_SIZE$2, THEME_COLOR_SCHEME_KEYS, getLinkedTextBoxSegments, svgPathToPolygons, deobfuscateFont, detectFontFormat, getSubstituteFontFamily, checkMissingAltText, checkMissingSlideTitle, checkLowContrast, checkComplexTables, checkBlankSlide, checkDuplicateTitles, createChartElement, 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, THEME_PRESETS, getAnimationPresetInfo } from 'pptx-viewer-core';
|
|
5
|
+
import { guideEmuToPx, getShapeClipPath, getAdjustmentAwareShapeClipPath, getShapeClipPathFromPreset, getCloudPathForRendering, hasShapeProperties, applyDrawingColorTransforms as applyDrawingColorTransforms$1, hslToRgb as hslToRgb$1, PRESET_COLOR_MAP, isImageLikeElement, hasTextProperties, stripXmlOrderSuffix, orderedXmlKey, MIN_ELEMENT_SIZE as MIN_ELEMENT_SIZE$2, THEME_COLOR_SCHEME_KEYS, getLinkedTextBoxSegments, createBuiltinVariables, resolveCoordinate, svgPathToPolygons, deobfuscateFont, detectFontFormat, getSubstituteFontFamily, checkMissingAltText, checkMissingSlideTitle, checkLowContrast, checkComplexTables, checkBlankSlide, checkDuplicateTitles, createChartElement, 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, THEME_PRESETS, getAnimationPresetInfo } from 'pptx-viewer-core';
|
|
6
6
|
export { SWITCHABLE_LAYOUT_TYPES, addSmartArtNode, addSmartArtNodeAsChild, chartDataAddCategory, chartDataAddSeries, chartDataChangeType, chartDataRemoveCategory, chartDataRemoveSeries, chartDataUpdatePoint, demoteSmartArtNode, promoteSmartArtNode, removeSmartArtNode, reorderSmartArtNode, switchSmartArtLayout, updateSmartArtNodeText } from 'pptx-viewer-core';
|
|
7
7
|
import DOMPurify from 'dompurify';
|
|
8
8
|
import { LucideX, LucideSquare, LucideCircle, LucideSlash, LucideCopy, LucideTrash2, LucideChevronsUp, LucideChevronsDown, LucideArrowUp, LucideArrowDown, LucideGroup, LucideUngroup, LucideTextAlignStart, LucideTextAlignCenter, LucideTextAlignEnd, LucideChevronUp, LucideChevronDown, LucideAlignHorizontalSpaceAround, LucideAlignVerticalSpaceAround, LucideChevronRight, LucidePenTool, LucideHighlighter, LucideEraser, LucideMousePointer2, LucideChevronLeft, LucidePlay, LucideSparkles, LucidePanelRight, LucideMoveRight, LucidePencil, LucideType, LucideMinus, LucideSpline, LucideArrowLeft, LucideDownload, LucideFilePlus2, LucideFolderOpen, LucideHome, LucideInfo, LucidePrinter, LucideSave, LucideSettings, LucideShare2, LucideUpload, LucideUserRound, LucideAArrowUp, LucideAArrowDown, LucideRemoveFormatting, LucideList, LucideListOrdered, LucideListIndentDecrease, LucideListIndentIncrease, LucideTextAlignJustify, LucidePlus, LucideClipboardPaste, LucideFolderPlus, LucideLayoutGrid, LucidePaintbrush, LucideRotateCcw, LucideScissors, LucideImage, LucideVideo, LucideDatabase, LucideLayers, LucidePanelLeft, LucideMessageSquare, LucideEllipsis, LucideEye, LucideEyeOff, LucideSettings2, LucideStickyNote, LucideMonitor, LucideColumns2, LucidePresentation, LucideCheck, LucideUndo, LucideRedo, LucideSearch } from '@lucide/angular';
|
|
@@ -770,6 +770,36 @@ function getGradientTileFlipCss(mode) {
|
|
|
770
770
|
return undefined;
|
|
771
771
|
}
|
|
772
772
|
}
|
|
773
|
+
/**
|
|
774
|
+
* Builds the `background-size` / `background-position` / `background-repeat`
|
|
775
|
+
* that confine a gradient to the rectangle described by `a:gradFill/a:tileRect`.
|
|
776
|
+
*
|
|
777
|
+
* `tileRect` LTRB values are 0..1 insets from each edge, so the tile covers
|
|
778
|
+
* `(1 - l - r)` x `(1 - t - b)` of the shape, offset by `l`/`t`. Returns
|
|
779
|
+
* `undefined` when the rect is missing, degenerate, or effectively full-bleed
|
|
780
|
+
* (no meaningful inset), so callers fall through to the plain gradient.
|
|
781
|
+
*/
|
|
782
|
+
function getGradientTileRectCss(tileRect) {
|
|
783
|
+
if (!tileRect) {
|
|
784
|
+
return undefined;
|
|
785
|
+
}
|
|
786
|
+
const { l, t, r, b } = tileRect;
|
|
787
|
+
const sizeW = 1 - l - r;
|
|
788
|
+
const sizeH = 1 - t - b;
|
|
789
|
+
if (sizeW <= 0 || sizeH <= 0) {
|
|
790
|
+
return undefined;
|
|
791
|
+
}
|
|
792
|
+
if (Math.abs(sizeW - 1) < 0.001 && Math.abs(sizeH - 1) < 0.001) {
|
|
793
|
+
return undefined;
|
|
794
|
+
}
|
|
795
|
+
const posX = 1 - sizeW > 0.001 ? (l / (1 - sizeW)) * 100 : 0;
|
|
796
|
+
const posY = 1 - sizeH > 0.001 ? (t / (1 - sizeH)) * 100 : 0;
|
|
797
|
+
return {
|
|
798
|
+
backgroundSize: `${Math.round(sizeW * 100)}% ${Math.round(sizeH * 100)}%`,
|
|
799
|
+
backgroundPosition: `${Math.round(posX)}% ${Math.round(posY)}%`,
|
|
800
|
+
backgroundRepeat: 'no-repeat',
|
|
801
|
+
};
|
|
802
|
+
}
|
|
773
803
|
/**
|
|
774
804
|
* Creates a reflected (mirrored) copy of gradient stops for tile-flip
|
|
775
805
|
* rendering. The original stops run 0->100; the result packs one full
|
|
@@ -796,6 +826,36 @@ function buildReflectedGradientStops(stops) {
|
|
|
796
826
|
}));
|
|
797
827
|
return [...forward, ...reversed];
|
|
798
828
|
}
|
|
829
|
+
/** Normalise a degree value into the [0, 360) range. */
|
|
830
|
+
function normalizeDegrees(deg) {
|
|
831
|
+
return ((deg % 360) + 360) % 360;
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* Apply `a:lin/@scaled` (aspect-ratio) and `a:gradFill/@rotWithShape`
|
|
835
|
+
* corrections to a linear-gradient angle. A no-op when no geometry context is
|
|
836
|
+
* supplied or neither attribute is in force, so callers that pass only a style
|
|
837
|
+
* keep the raw authored angle.
|
|
838
|
+
*/
|
|
839
|
+
function adjustLinearGradientAngle(angle, gradient, context) {
|
|
840
|
+
if (!context) {
|
|
841
|
+
return angle;
|
|
842
|
+
}
|
|
843
|
+
let result = angle;
|
|
844
|
+
const { width, height, rotation } = context;
|
|
845
|
+
if (gradient.fillGradientScaled !== false &&
|
|
846
|
+
typeof width === 'number' &&
|
|
847
|
+
typeof height === 'number' &&
|
|
848
|
+
width > 0 &&
|
|
849
|
+
height > 0 &&
|
|
850
|
+
width !== height) {
|
|
851
|
+
const rad = (result * Math.PI) / 180;
|
|
852
|
+
result = normalizeDegrees((Math.atan2(height * Math.sin(rad), width * Math.cos(rad)) * 180) / Math.PI);
|
|
853
|
+
}
|
|
854
|
+
if (gradient.fillGradientRotWithShape === false && typeof rotation === 'number') {
|
|
855
|
+
result = normalizeDegrees(result - rotation);
|
|
856
|
+
}
|
|
857
|
+
return result;
|
|
858
|
+
}
|
|
799
859
|
/**
|
|
800
860
|
* Converts a structured OOXML gradient on a `ShapeStyle` to a CSS
|
|
801
861
|
* `linear-gradient(...)` / `radial-gradient(...)` string.
|
|
@@ -810,9 +870,11 @@ function buildReflectedGradientStops(stops) {
|
|
|
810
870
|
* a radial), matching the React port.
|
|
811
871
|
*
|
|
812
872
|
* @param gradient - The shape style carrying gradient configuration.
|
|
873
|
+
* @param context - Optional element geometry enabling `@scaled` /
|
|
874
|
+
* `@rotWithShape` angle corrections (linear only).
|
|
813
875
|
* @returns A CSS gradient string, or `undefined`.
|
|
814
876
|
*/
|
|
815
|
-
function buildGradientCss(gradient) {
|
|
877
|
+
function buildGradientCss(gradient, context) {
|
|
816
878
|
if (!gradient || gradient.fillMode !== 'gradient') {
|
|
817
879
|
return undefined;
|
|
818
880
|
}
|
|
@@ -836,12 +898,13 @@ function buildGradientCss(gradient) {
|
|
|
836
898
|
const normalizedAngle = typeof gradient.fillGradientAngle === 'number' && Number.isFinite(gradient.fillGradientAngle)
|
|
837
899
|
? gradient.fillGradientAngle
|
|
838
900
|
: 90;
|
|
901
|
+
const effectiveAngle = adjustLinearGradientAngle(normalizedAngle, gradient, context);
|
|
839
902
|
// Tile-flip: reflect the stops so a single tile contains one mirrored
|
|
840
903
|
// forward-backward cycle. The repeating/halved tiling is applied by the
|
|
841
904
|
// caller via getGradientTileFlipCss (wired into getComputedFillStyle).
|
|
842
905
|
const flip = gradient.fillGradientFlip;
|
|
843
906
|
const linearStops = flip && flip !== 'none' ? buildReflectedGradientStops(stops) : stops;
|
|
844
|
-
return `linear-gradient(${Math.round(
|
|
907
|
+
return `linear-gradient(${Math.round(effectiveAngle)}deg, ${linearStops
|
|
845
908
|
.map(toCssGradientStop)
|
|
846
909
|
.join(', ')})`;
|
|
847
910
|
}
|
|
@@ -1251,9 +1314,16 @@ const OOXML_PATTERN_PRESETS = [
|
|
|
1251
1314
|
* empty-ish object when no fill applies (so callers can spread the result
|
|
1252
1315
|
* safely).
|
|
1253
1316
|
*
|
|
1254
|
-
*
|
|
1317
|
+
* A child of a group whose fill is `a:grpFill` (`fillMode === "group"`)
|
|
1318
|
+
* inherits the group's resolved fill: pass the parent group's `ShapeStyle`
|
|
1319
|
+
* (`GroupPptxElement.groupFill`) as {@link parentGroupFill} and it is resolved
|
|
1320
|
+
* in the child's own box.
|
|
1321
|
+
*
|
|
1322
|
+
* @param element - The PPTX element to resolve a fill for.
|
|
1323
|
+
* @param parentGroupFill - The enclosing group's fill style, used only when the
|
|
1324
|
+
* element's own fill is `a:grpFill`.
|
|
1255
1325
|
*/
|
|
1256
|
-
function getComputedFillStyle(element) {
|
|
1326
|
+
function getComputedFillStyle(element, parentGroupFill) {
|
|
1257
1327
|
if (!hasShapeProperties(element)) {
|
|
1258
1328
|
return undefined;
|
|
1259
1329
|
}
|
|
@@ -1261,6 +1331,20 @@ function getComputedFillStyle(element) {
|
|
|
1261
1331
|
if (!ss) {
|
|
1262
1332
|
return {};
|
|
1263
1333
|
}
|
|
1334
|
+
// grpFill inheritance: paint the parent group's resolved fill in this
|
|
1335
|
+
// child's box. Without a parent fill there is nothing to inherit.
|
|
1336
|
+
if (ss.fillMode === 'group') {
|
|
1337
|
+
return parentGroupFill ? resolveComputedFill(parentGroupFill, element) : {};
|
|
1338
|
+
}
|
|
1339
|
+
return resolveComputedFill(ss, element);
|
|
1340
|
+
}
|
|
1341
|
+
/**
|
|
1342
|
+
* Resolves a concrete {@link ComputedFillStyle} from a {@link ShapeStyle} in the
|
|
1343
|
+
* context of `element` (id namespaces pattern filters; geometry drives gradient
|
|
1344
|
+
* `@scaled`/`@rotWithShape` corrections). Split out so grpFill children can
|
|
1345
|
+
* resolve the parent group's style through the identical pipeline.
|
|
1346
|
+
*/
|
|
1347
|
+
function resolveComputedFill(ss, element) {
|
|
1264
1348
|
// 1. Image fill — highest priority.
|
|
1265
1349
|
const imageFillUrl = ss.fillMode === 'image' && ss.fillImageUrl ? ss.fillImageUrl : undefined;
|
|
1266
1350
|
if (imageFillUrl) {
|
|
@@ -1273,7 +1357,12 @@ function getComputedFillStyle(element) {
|
|
|
1273
1357
|
};
|
|
1274
1358
|
}
|
|
1275
1359
|
// 2. Gradient (structured, with prebuilt-string fallback).
|
|
1276
|
-
const
|
|
1360
|
+
const geometry = {
|
|
1361
|
+
rotation: element.rotation,
|
|
1362
|
+
width: element.width,
|
|
1363
|
+
height: element.height,
|
|
1364
|
+
};
|
|
1365
|
+
const gradient = buildGradientCss(ss, geometry) ?? (ss.fillMode === 'gradient' ? ss.fillGradient : undefined);
|
|
1277
1366
|
if (gradient) {
|
|
1278
1367
|
// Tile-flip applies only to structured linear gradients: buildGradientCss
|
|
1279
1368
|
// reflects the stops, and the matching halved/repeating background-size +
|
|
@@ -1290,6 +1379,16 @@ function getComputedFillStyle(element) {
|
|
|
1290
1379
|
backgroundRepeat: tileFlip.backgroundRepeat,
|
|
1291
1380
|
};
|
|
1292
1381
|
}
|
|
1382
|
+
// tileRect confines the gradient to a sub-rectangle of the shape.
|
|
1383
|
+
const tileRect = ss.fillMode === 'gradient' ? getGradientTileRectCss(ss.fillGradientTileRect) : undefined;
|
|
1384
|
+
if (tileRect) {
|
|
1385
|
+
return {
|
|
1386
|
+
backgroundImage: gradient,
|
|
1387
|
+
backgroundSize: tileRect.backgroundSize,
|
|
1388
|
+
backgroundPosition: tileRect.backgroundPosition,
|
|
1389
|
+
backgroundRepeat: tileRect.backgroundRepeat,
|
|
1390
|
+
};
|
|
1391
|
+
}
|
|
1293
1392
|
return { backgroundImage: gradient };
|
|
1294
1393
|
}
|
|
1295
1394
|
// 3. Pattern fill.
|
|
@@ -7008,6 +7107,38 @@ function buildCartesianAxes(chartData, layout, primaryRange, secondaryRange, cat
|
|
|
7008
7107
|
function categoryTotals(series, catCount) {
|
|
7009
7108
|
return Array.from({ length: catCount }, (_, ci) => series.reduce((sum, s) => sum + Math.abs(s.values[ci] ?? 0), 0));
|
|
7010
7109
|
}
|
|
7110
|
+
/**
|
|
7111
|
+
* Blend a `#RRGGBB` colour halfway toward white. Returns the input unchanged
|
|
7112
|
+
* when it is not a parseable 6-digit hex (e.g. a named colour or gradient ref).
|
|
7113
|
+
*/
|
|
7114
|
+
function blendToWhite(color) {
|
|
7115
|
+
const match = /^#?([0-9a-f]{6})$/iu.exec(color.trim());
|
|
7116
|
+
if (!match) {
|
|
7117
|
+
return color;
|
|
7118
|
+
}
|
|
7119
|
+
const value = Number.parseInt(match[1], 16);
|
|
7120
|
+
const mix = (channel) => Math.round(channel + (255 - channel) * 0.5);
|
|
7121
|
+
const r = mix((value >> 16) & 0xff);
|
|
7122
|
+
const g = mix((value >> 8) & 0xff);
|
|
7123
|
+
const b = mix(value & 0xff);
|
|
7124
|
+
return `#${((r << 16) | (g << 8) | b).toString(16).padStart(6, '0').toUpperCase()}`;
|
|
7125
|
+
}
|
|
7126
|
+
/**
|
|
7127
|
+
* Apply PowerPoint's `c:invertIfNegative` treatment to a bar fill: when the
|
|
7128
|
+
* point value is negative and invert-if-negative is set (a per-point `c:dPt`
|
|
7129
|
+
* override wins over the series-level flag), the bar is drawn in a lightened
|
|
7130
|
+
* fill. Convention: a 50% blend of the base fill toward white. PowerPoint has no
|
|
7131
|
+
* single canonical inverted colour; a lightened same-hue fill echoes its default
|
|
7132
|
+
* "hollow" appearance and is deterministic across bindings.
|
|
7133
|
+
*/
|
|
7134
|
+
function invertNegativeFill(series, pointIndex, value, baseFill) {
|
|
7135
|
+
if (value >= 0) {
|
|
7136
|
+
return baseFill;
|
|
7137
|
+
}
|
|
7138
|
+
const point = series.dataPoints?.find((p) => p.idx === pointIndex);
|
|
7139
|
+
const invert = point?.invertIfNegative ?? series.invertIfNegative ?? false;
|
|
7140
|
+
return invert ? blendToWhite(baseFill) : baseFill;
|
|
7141
|
+
}
|
|
7011
7142
|
/**
|
|
7012
7143
|
* Bar primitives for clustered / stacked / percentStacked, honouring a secondary
|
|
7013
7144
|
* value range for secondary-mapped series (clustered only). Returns rects + data
|
|
@@ -7019,29 +7150,45 @@ function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, se
|
|
|
7019
7150
|
const series = chartData.series;
|
|
7020
7151
|
const palette = chartData.colorPalette;
|
|
7021
7152
|
const showLabels = chartData.style?.hasDataLabels;
|
|
7153
|
+
// Single-series bar/column with c:varyColors=1 gives every category a distinct
|
|
7154
|
+
// palette colour (a per-point c:dPt fill still wins). Multi-series charts keep
|
|
7155
|
+
// their per-series colours (varyColors has no cross-series meaning there).
|
|
7156
|
+
const varyColorsSingle = chartData.varyColors === true && series.length === 1;
|
|
7022
7157
|
if (grouping === 'clustered') {
|
|
7023
7158
|
const seriesCount = Math.max(series.length, 1);
|
|
7024
7159
|
const barGroupWidth = layout.plotWidth / Math.max(catCount, 1);
|
|
7025
|
-
|
|
7026
|
-
|
|
7160
|
+
// Honour c:gapWidth (gap between clusters, % of a bar width) when parsed;
|
|
7161
|
+
// otherwise keep the legacy 0.7-of-group heuristic byte-for-byte.
|
|
7162
|
+
const singleBarWidth = chartData.barGapWidth !== undefined
|
|
7163
|
+
? barGroupWidth / (seriesCount + Math.max(chartData.barGapWidth, 0) / 100)
|
|
7164
|
+
: (barGroupWidth * 0.7) / seriesCount;
|
|
7165
|
+
// Honour c:overlap (% overlap between adjacent series). overlap=0 reproduces
|
|
7166
|
+
// the original side-by-side layout exactly.
|
|
7167
|
+
const overlap = chartData.barOverlap ?? 0;
|
|
7168
|
+
const step = singleBarWidth * (1 - overlap / 100);
|
|
7169
|
+
const clusterWidth = singleBarWidth + step * (seriesCount - 1);
|
|
7170
|
+
const groupOffset = (barGroupWidth - clusterWidth) / 2;
|
|
7027
7171
|
for (let displayIndex = 0; displayIndex < catCount; displayIndex++) {
|
|
7028
7172
|
const sourceIndex = sourceIndices[displayIndex] ?? displayIndex;
|
|
7029
7173
|
for (let si = 0; si < series.length; si++) {
|
|
7030
7174
|
const val = series[si].values[sourceIndex] ?? 0;
|
|
7031
|
-
const x = layout.plotLeft + barGroupWidth * displayIndex + groupOffset +
|
|
7175
|
+
const x = layout.plotLeft + barGroupWidth * displayIndex + groupOffset + step * si;
|
|
7032
7176
|
const activeRange = secondaryIdx.has(si) && secondaryRange ? secondaryRange : primaryRange;
|
|
7033
7177
|
const zeroY = valueToY(0, activeRange, layout.plotTop, layout.plotBottom);
|
|
7034
7178
|
const valY = valueToY(val, activeRange, layout.plotTop, layout.plotBottom);
|
|
7035
7179
|
const y = Math.min(zeroY, valY);
|
|
7036
7180
|
const h = Math.max(Math.abs(zeroY - valY), 1);
|
|
7181
|
+
const baseFill = varyColorsSingle
|
|
7182
|
+
? resolveVaryColorFill(series[si], sourceIndex, paletteColor(sourceIndex, palette))
|
|
7183
|
+
: (resolveDataPointFill(series[si], sourceIndex, paletteColor(si, palette)) ??
|
|
7184
|
+
seriesColor(series[si], si, palette));
|
|
7037
7185
|
primitives.push({
|
|
7038
7186
|
kind: 'rect',
|
|
7039
7187
|
x,
|
|
7040
7188
|
y,
|
|
7041
7189
|
w: singleBarWidth,
|
|
7042
7190
|
h,
|
|
7043
|
-
fill:
|
|
7044
|
-
seriesColor(series[si], si, palette),
|
|
7191
|
+
fill: invertNegativeFill(series[si], sourceIndex, val, baseFill),
|
|
7045
7192
|
rx: 1,
|
|
7046
7193
|
part: { role: 'dataPoint', seriesIndex: si, pointIndex: sourceIndex },
|
|
7047
7194
|
});
|
|
@@ -7076,6 +7223,8 @@ function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, se
|
|
|
7076
7223
|
if (r.seriesIndex !== undefined && r.pointIndex !== undefined) {
|
|
7077
7224
|
const sourcePointIndex = sourceIndices[r.pointIndex] ?? r.pointIndex;
|
|
7078
7225
|
fill = resolveDataPointFill(series[r.seriesIndex], sourcePointIndex, r.fill) ?? r.fill;
|
|
7226
|
+
const value = series[r.seriesIndex].values[sourcePointIndex] ?? 0;
|
|
7227
|
+
fill = invertNegativeFill(series[r.seriesIndex], sourcePointIndex, value, fill);
|
|
7079
7228
|
part = { role: 'dataPoint', seriesIndex: r.seriesIndex, pointIndex: sourcePointIndex };
|
|
7080
7229
|
}
|
|
7081
7230
|
primitives.push({ kind: 'rect', x: r.x, y: r.y, w: r.w, h: r.h, fill, rx: 1, part });
|
|
@@ -7110,14 +7259,15 @@ function buildBars(chartData, catCount, layout, primaryRange, secondaryRange, se
|
|
|
7110
7259
|
const topY = valueToY(top, primaryRange, layout.plotTop, layout.plotBottom);
|
|
7111
7260
|
const y = Math.min(baseY, topY);
|
|
7112
7261
|
const h = Math.max(Math.abs(baseY - topY), 0.5);
|
|
7262
|
+
const pctBaseFill = resolveDataPointFill(series[si], sourceIndex, paletteColor(si, palette)) ??
|
|
7263
|
+
seriesColor(series[si], si, palette);
|
|
7113
7264
|
primitives.push({
|
|
7114
7265
|
kind: 'rect',
|
|
7115
7266
|
x,
|
|
7116
7267
|
y,
|
|
7117
7268
|
w: barW,
|
|
7118
7269
|
h,
|
|
7119
|
-
fill:
|
|
7120
|
-
seriesColor(series[si], si, palette),
|
|
7270
|
+
fill: invertNegativeFill(series[si], sourceIndex, rawVal, pctBaseFill),
|
|
7121
7271
|
part: { role: 'dataPoint', seriesIndex: si, pointIndex: sourceIndex },
|
|
7122
7272
|
});
|
|
7123
7273
|
if (showLabels && Math.abs(val) > 0) {
|
|
@@ -7178,6 +7328,181 @@ function pushClusteredStackedLabels(series, sourceIndices, catCount, layout, ran
|
|
|
7178
7328
|
}
|
|
7179
7329
|
}
|
|
7180
7330
|
|
|
7331
|
+
/**
|
|
7332
|
+
* chart-line-path.ts: bezier smoothing for line-series paths.
|
|
7333
|
+
*
|
|
7334
|
+
* OOXML line/scatter series may set `c:smooth`, which PowerPoint renders as a
|
|
7335
|
+
* smoothed curve through the data points rather than straight segments. This
|
|
7336
|
+
* helper converts a point list into an SVG path `d` string using a Catmull-Rom
|
|
7337
|
+
* spline expressed as cubic beziers, so every binding can render the smoothed
|
|
7338
|
+
* line identically.
|
|
7339
|
+
*
|
|
7340
|
+
* @module chart-line-path
|
|
7341
|
+
*/
|
|
7342
|
+
/**
|
|
7343
|
+
* Build a smoothed cubic-bezier path `d` through `points` (Catmull-Rom spline).
|
|
7344
|
+
* Returns a straight `M…L…` fallback for fewer than three points.
|
|
7345
|
+
*/
|
|
7346
|
+
function smoothLinePath(points) {
|
|
7347
|
+
if (points.length === 0) {
|
|
7348
|
+
return '';
|
|
7349
|
+
}
|
|
7350
|
+
if (points.length === 1) {
|
|
7351
|
+
return `M${points[0].x.toFixed(2)},${points[0].y.toFixed(2)}`;
|
|
7352
|
+
}
|
|
7353
|
+
if (points.length === 2) {
|
|
7354
|
+
return `M${points[0].x.toFixed(2)},${points[0].y.toFixed(2)} L${points[1].x.toFixed(2)},${points[1].y.toFixed(2)}`;
|
|
7355
|
+
}
|
|
7356
|
+
let d = `M${points[0].x.toFixed(2)},${points[0].y.toFixed(2)}`;
|
|
7357
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
7358
|
+
const p0 = points[i - 1] ?? points[i];
|
|
7359
|
+
const p1 = points[i];
|
|
7360
|
+
const p2 = points[i + 1];
|
|
7361
|
+
const p3 = points[i + 2] ?? p2;
|
|
7362
|
+
const cp1x = p1.x + (p2.x - p0.x) / 6;
|
|
7363
|
+
const cp1y = p1.y + (p2.y - p0.y) / 6;
|
|
7364
|
+
const cp2x = p2.x - (p3.x - p1.x) / 6;
|
|
7365
|
+
const cp2y = p2.y - (p3.y - p1.y) / 6;
|
|
7366
|
+
d += ` C${cp1x.toFixed(2)},${cp1y.toFixed(2)} ${cp2x.toFixed(2)},${cp2y.toFixed(2)} ${p2.x.toFixed(2)},${p2.y.toFixed(2)}`;
|
|
7367
|
+
}
|
|
7368
|
+
return d;
|
|
7369
|
+
}
|
|
7370
|
+
|
|
7371
|
+
/**
|
|
7372
|
+
* chart-marker-shape.ts: framework-agnostic marker-symbol primitive builder for
|
|
7373
|
+
* line / scatter / area chart data points.
|
|
7374
|
+
*
|
|
7375
|
+
* OOXML line/scatter series carry a `c:marker` with a `c:symbol` (circle,
|
|
7376
|
+
* diamond, square, triangle, star, x, plus, dot, dash, none, ...) and an
|
|
7377
|
+
* optional `c:size` (2-72 points). The base view-model historically drew every
|
|
7378
|
+
* data point as a fixed-radius circle, ignoring both. This helper resolves the
|
|
7379
|
+
* parsed marker into the correct `SvgPrimitive` at the requested size, and
|
|
7380
|
+
* returns `null` for `symbol === 'none'` so no dot is drawn.
|
|
7381
|
+
*
|
|
7382
|
+
* @module chart-marker-shape
|
|
7383
|
+
*/
|
|
7384
|
+
/** Resolve the drawn radius (px) from the parsed point size or the default. */
|
|
7385
|
+
function markerRadius(size, defaultRadius) {
|
|
7386
|
+
if (size === undefined || !Number.isFinite(size) || size <= 0) {
|
|
7387
|
+
return defaultRadius;
|
|
7388
|
+
}
|
|
7389
|
+
// OOXML marker size is a point diameter; treat 1pt ~ 1px at chart scale.
|
|
7390
|
+
return size / 2;
|
|
7391
|
+
}
|
|
7392
|
+
/** Build the SVG points string for a regular/irregular polygon vertex list. */
|
|
7393
|
+
function polygonPoints(vertices) {
|
|
7394
|
+
return vertices.map(([x, y]) => `${x.toFixed(2)},${y.toFixed(2)}`).join(' ');
|
|
7395
|
+
}
|
|
7396
|
+
function starVertices(cx, cy, r) {
|
|
7397
|
+
const inner = r * 0.5;
|
|
7398
|
+
const out = [];
|
|
7399
|
+
for (let i = 0; i < 10; i++) {
|
|
7400
|
+
const radius = i % 2 === 0 ? r : inner;
|
|
7401
|
+
const angle = -Math.PI / 2 + (Math.PI * i) / 5;
|
|
7402
|
+
out.push([cx + radius * Math.cos(angle), cy + radius * Math.sin(angle)]);
|
|
7403
|
+
}
|
|
7404
|
+
return out;
|
|
7405
|
+
}
|
|
7406
|
+
/**
|
|
7407
|
+
* Build the marker primitive for one data point, honouring `symbol` and `size`.
|
|
7408
|
+
* Returns `null` when `symbol === 'none'` (draw nothing).
|
|
7409
|
+
*/
|
|
7410
|
+
function buildMarkerPrimitive(input) {
|
|
7411
|
+
const { symbol, cx, cy, fill, part } = input;
|
|
7412
|
+
if (symbol === 'none') {
|
|
7413
|
+
return null;
|
|
7414
|
+
}
|
|
7415
|
+
const r = markerRadius(input.size, input.defaultRadius);
|
|
7416
|
+
const stroke = fill;
|
|
7417
|
+
switch (symbol) {
|
|
7418
|
+
case 'square':
|
|
7419
|
+
return { kind: 'rect', x: cx - r, y: cy - r, w: r * 2, h: r * 2, fill, part };
|
|
7420
|
+
case 'dash':
|
|
7421
|
+
return { kind: 'rect', x: cx - r, y: cy - r * 0.32, w: r * 2, h: r * 0.64, fill, part };
|
|
7422
|
+
case 'diamond':
|
|
7423
|
+
return {
|
|
7424
|
+
kind: 'polygon',
|
|
7425
|
+
points: polygonPoints([
|
|
7426
|
+
[cx, cy - r],
|
|
7427
|
+
[cx + r, cy],
|
|
7428
|
+
[cx, cy + r],
|
|
7429
|
+
[cx - r, cy],
|
|
7430
|
+
]),
|
|
7431
|
+
fill,
|
|
7432
|
+
stroke,
|
|
7433
|
+
strokeWidth: 0,
|
|
7434
|
+
part,
|
|
7435
|
+
};
|
|
7436
|
+
case 'triangle':
|
|
7437
|
+
return {
|
|
7438
|
+
kind: 'polygon',
|
|
7439
|
+
points: polygonPoints([
|
|
7440
|
+
[cx, cy - r],
|
|
7441
|
+
[cx + r * 0.9, cy + r * 0.75],
|
|
7442
|
+
[cx - r * 0.9, cy + r * 0.75],
|
|
7443
|
+
]),
|
|
7444
|
+
fill,
|
|
7445
|
+
stroke,
|
|
7446
|
+
strokeWidth: 0,
|
|
7447
|
+
part,
|
|
7448
|
+
};
|
|
7449
|
+
case 'star':
|
|
7450
|
+
return {
|
|
7451
|
+
kind: 'polygon',
|
|
7452
|
+
points: polygonPoints(starVertices(cx, cy, r)),
|
|
7453
|
+
fill,
|
|
7454
|
+
stroke,
|
|
7455
|
+
strokeWidth: 0,
|
|
7456
|
+
part,
|
|
7457
|
+
};
|
|
7458
|
+
case 'plus':
|
|
7459
|
+
return {
|
|
7460
|
+
kind: 'path',
|
|
7461
|
+
d: `M${(cx - r).toFixed(2)},${cy.toFixed(2)} L${(cx + r).toFixed(2)},${cy.toFixed(2)} M${cx.toFixed(2)},${(cy - r).toFixed(2)} L${cx.toFixed(2)},${(cy + r).toFixed(2)}`,
|
|
7462
|
+
fill: 'none',
|
|
7463
|
+
stroke,
|
|
7464
|
+
strokeWidth: Math.max(1, r * 0.4),
|
|
7465
|
+
part,
|
|
7466
|
+
};
|
|
7467
|
+
case 'x':
|
|
7468
|
+
return {
|
|
7469
|
+
kind: 'path',
|
|
7470
|
+
d: `M${(cx - r).toFixed(2)},${(cy - r).toFixed(2)} L${(cx + r).toFixed(2)},${(cy + r).toFixed(2)} M${(cx + r).toFixed(2)},${(cy - r).toFixed(2)} L${(cx - r).toFixed(2)},${(cy + r).toFixed(2)}`,
|
|
7471
|
+
fill: 'none',
|
|
7472
|
+
stroke,
|
|
7473
|
+
strokeWidth: Math.max(1, r * 0.4),
|
|
7474
|
+
part,
|
|
7475
|
+
};
|
|
7476
|
+
case 'dot':
|
|
7477
|
+
return { kind: 'circle', cx, cy, r: Math.max(r * 0.6, 1), fill, part };
|
|
7478
|
+
default:
|
|
7479
|
+
// circle / auto / picture / undefined -> filled circle.
|
|
7480
|
+
return { kind: 'circle', cx, cy, r, fill, part };
|
|
7481
|
+
}
|
|
7482
|
+
}
|
|
7483
|
+
|
|
7484
|
+
/**
|
|
7485
|
+
* Build the marker for a data point (honouring `marker.symbol`/`size`) and push
|
|
7486
|
+
* it, unless the symbol is `none`. Shared by the line / area / scatter builders.
|
|
7487
|
+
*/
|
|
7488
|
+
function pushMarker(out, series, cx, cy, fill, defaultRadius, part, opacity) {
|
|
7489
|
+
const m = buildMarkerPrimitive({
|
|
7490
|
+
symbol: series.marker?.symbol,
|
|
7491
|
+
size: series.marker?.size,
|
|
7492
|
+
cx,
|
|
7493
|
+
cy,
|
|
7494
|
+
fill,
|
|
7495
|
+
defaultRadius,
|
|
7496
|
+
part,
|
|
7497
|
+
});
|
|
7498
|
+
if (!m) {
|
|
7499
|
+
return;
|
|
7500
|
+
}
|
|
7501
|
+
if (opacity !== undefined) {
|
|
7502
|
+
m.opacity = opacity;
|
|
7503
|
+
}
|
|
7504
|
+
out.push(m);
|
|
7505
|
+
}
|
|
7181
7506
|
/** Build line-chart primitives, honouring a secondary value range per series. */
|
|
7182
7507
|
function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, secondaryIdx, sourceIndices, xPositions) {
|
|
7183
7508
|
const primitives = [];
|
|
@@ -7195,24 +7520,29 @@ function buildLines(chartData, catCount, layout, primaryRange, secondaryRange, s
|
|
|
7195
7520
|
x: xPositions?.[index] ?? point.x,
|
|
7196
7521
|
}));
|
|
7197
7522
|
const c = seriesColor(series, si, chartData.colorPalette);
|
|
7198
|
-
|
|
7199
|
-
|
|
7200
|
-
|
|
7201
|
-
|
|
7202
|
-
|
|
7203
|
-
|
|
7204
|
-
|
|
7205
|
-
|
|
7206
|
-
|
|
7207
|
-
|
|
7208
|
-
|
|
7209
|
-
|
|
7210
|
-
|
|
7211
|
-
|
|
7212
|
-
|
|
7213
|
-
|
|
7214
|
-
|
|
7523
|
+
// c:smooth draws a bezier path through the points; otherwise a polyline.
|
|
7524
|
+
const seriesPart = { role: 'series', seriesIndex: si };
|
|
7525
|
+
primitives.push(series.smooth
|
|
7526
|
+
? {
|
|
7527
|
+
kind: 'path',
|
|
7528
|
+
d: smoothLinePath(pts),
|
|
7529
|
+
stroke: c,
|
|
7530
|
+
strokeWidth: 2.4,
|
|
7531
|
+
fill: 'none',
|
|
7532
|
+
part: seriesPart,
|
|
7533
|
+
}
|
|
7534
|
+
: {
|
|
7535
|
+
kind: 'polyline',
|
|
7536
|
+
points: linePointsToSvgString(pts),
|
|
7537
|
+
stroke: c,
|
|
7538
|
+
strokeWidth: 2.4,
|
|
7539
|
+
fill: 'none',
|
|
7540
|
+
part: seriesPart,
|
|
7215
7541
|
});
|
|
7542
|
+
pts.forEach((pt, displayIndex) => {
|
|
7543
|
+
const idx = sourceIndices[displayIndex] ?? displayIndex;
|
|
7544
|
+
const part = { role: 'dataPoint', seriesIndex: si, pointIndex: idx };
|
|
7545
|
+
pushMarker(primitives, series, pt.x, pt.y, resolveDataPointFill(series, idx, c) ?? c, 2.5, part);
|
|
7216
7546
|
});
|
|
7217
7547
|
if (showLabels) {
|
|
7218
7548
|
displayValues.forEach((val, displayIndex) => {
|
|
@@ -7274,19 +7604,9 @@ function buildAreas(chartData, catCount, layout, range, sourceIndices, xPosition
|
|
|
7274
7604
|
part: { role: 'series', seriesIndex: si },
|
|
7275
7605
|
});
|
|
7276
7606
|
pts.forEach((pt, displayIndex) => {
|
|
7277
|
-
const
|
|
7278
|
-
|
|
7279
|
-
|
|
7280
|
-
cx: pt.x,
|
|
7281
|
-
cy: pt.y,
|
|
7282
|
-
r: 2,
|
|
7283
|
-
fill: resolveDataPointFill(series, sourceIndex, c) ?? c,
|
|
7284
|
-
part: {
|
|
7285
|
-
role: 'dataPoint',
|
|
7286
|
-
seriesIndex: si,
|
|
7287
|
-
pointIndex: sourceIndex,
|
|
7288
|
-
},
|
|
7289
|
-
});
|
|
7607
|
+
const idx = sourceIndices[displayIndex] ?? displayIndex;
|
|
7608
|
+
const part = { role: 'dataPoint', seriesIndex: si, pointIndex: idx };
|
|
7609
|
+
pushMarker(primitives, series, pt.x, pt.y, resolveDataPointFill(series, idx, c) ?? c, 2, part);
|
|
7290
7610
|
});
|
|
7291
7611
|
if (showLabels) {
|
|
7292
7612
|
displayValues.forEach((val, displayIndex) => {
|
|
@@ -7321,15 +7641,8 @@ function buildScatter(chartData, layout, range) {
|
|
|
7321
7641
|
const c = seriesColor(series, si, chartData.colorPalette);
|
|
7322
7642
|
const dots = computeScatterDots(series.values, maxXIndex, layout, range, xValues);
|
|
7323
7643
|
dots.forEach((dot, vi) => {
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
cx: dot.cx,
|
|
7327
|
-
cy: dot.cy,
|
|
7328
|
-
r: 4,
|
|
7329
|
-
fill: resolveDataPointFill(series, vi, c) ?? c,
|
|
7330
|
-
opacity: 0.85,
|
|
7331
|
-
part: { role: 'dataPoint', seriesIndex: si, pointIndex: vi },
|
|
7332
|
-
});
|
|
7644
|
+
const part = { role: 'dataPoint', seriesIndex: si, pointIndex: vi };
|
|
7645
|
+
pushMarker(primitives, series, dot.cx, dot.cy, resolveDataPointFill(series, vi, c) ?? c, 4, part, 0.85);
|
|
7333
7646
|
});
|
|
7334
7647
|
if (showLabels) {
|
|
7335
7648
|
series.values.forEach((val, vi) => {
|
|
@@ -7400,6 +7713,163 @@ function buildBubbles(chartData, layout, range) {
|
|
|
7400
7713
|
return { primitives, dataLabels };
|
|
7401
7714
|
}
|
|
7402
7715
|
|
|
7716
|
+
/**
|
|
7717
|
+
* chart-helper-lines.ts: shared drop-line / hi-low-line / up-down-bar primitives.
|
|
7718
|
+
*
|
|
7719
|
+
* OOXML line and stock charts may declare `c:dropLines`, `c:hiLowLines`, and
|
|
7720
|
+
* `c:upDownBars` on the chart-type container. Historically these rendered only
|
|
7721
|
+
* in the React chart chrome (drop/hi-low), and up-down bars nowhere, so the
|
|
7722
|
+
* framework-agnostic view-model (Vue / Angular / Vanilla / Svelte) never drew
|
|
7723
|
+
* them. These pure builders project each into `SvgPrimitive[]` so every binding
|
|
7724
|
+
* renders them from a single source.
|
|
7725
|
+
*
|
|
7726
|
+
* dropLines - a vertical line from each data point down to the axis baseline.
|
|
7727
|
+
* hiLowLines - a vertical line spanning the highest and lowest series value
|
|
7728
|
+
* in each category (requires >= 2 series).
|
|
7729
|
+
* upDownBars - a bar between the first and last series value in each category,
|
|
7730
|
+
* coloured by whether the last value rose or fell (>= 2 series).
|
|
7731
|
+
*
|
|
7732
|
+
* @module chart-helper-lines
|
|
7733
|
+
*/
|
|
7734
|
+
/** X pixel for a category index, preferring an explicit x-position. */
|
|
7735
|
+
function categoryX$2(index, catCount, layout, options) {
|
|
7736
|
+
const explicit = options.xPositions?.[index];
|
|
7737
|
+
if (explicit !== undefined) {
|
|
7738
|
+
return explicit;
|
|
7739
|
+
}
|
|
7740
|
+
if (options.mode === 'bar') {
|
|
7741
|
+
const slot = layout.plotWidth / Math.max(catCount, 1);
|
|
7742
|
+
return layout.plotLeft + slot * index + slot / 2;
|
|
7743
|
+
}
|
|
7744
|
+
const maxIdx = Math.max(catCount - 1, 1);
|
|
7745
|
+
return layout.plotLeft + (index / maxIdx) * layout.plotWidth;
|
|
7746
|
+
}
|
|
7747
|
+
/** SVG dash pattern for a helper-line dash style, if any. */
|
|
7748
|
+
function dashFor(dashStyle) {
|
|
7749
|
+
if (!dashStyle || dashStyle === 'solid') {
|
|
7750
|
+
return undefined;
|
|
7751
|
+
}
|
|
7752
|
+
return dashStyle === 'dot' || dashStyle === 'sysDot' ? '1 2' : '4 3';
|
|
7753
|
+
}
|
|
7754
|
+
/**
|
|
7755
|
+
* Drop lines: a vertical line from every data point down to the value-axis
|
|
7756
|
+
* baseline (`range.min`). Returns `[]` when `c:dropLines` is absent.
|
|
7757
|
+
*/
|
|
7758
|
+
function computeDropLinePrimitives(chartData, layout, range, catCount, options) {
|
|
7759
|
+
const style = chartData.dropLines;
|
|
7760
|
+
if (!style) {
|
|
7761
|
+
return [];
|
|
7762
|
+
}
|
|
7763
|
+
const baselineY = valueToY(range.min, range, layout.plotTop, layout.plotBottom);
|
|
7764
|
+
const dashArray = dashFor(style.dashStyle);
|
|
7765
|
+
const out = [];
|
|
7766
|
+
for (const series of chartData.series) {
|
|
7767
|
+
series.values.forEach((val, vi) => {
|
|
7768
|
+
const x = categoryX$2(vi, catCount, layout, options);
|
|
7769
|
+
out.push({
|
|
7770
|
+
kind: 'line',
|
|
7771
|
+
x1: x,
|
|
7772
|
+
y1: valueToY(val, range, layout.plotTop, layout.plotBottom),
|
|
7773
|
+
x2: x,
|
|
7774
|
+
y2: baselineY,
|
|
7775
|
+
stroke: style.color ?? '#94a3b8',
|
|
7776
|
+
strokeWidth: style.width ?? 0.8,
|
|
7777
|
+
dashArray,
|
|
7778
|
+
});
|
|
7779
|
+
});
|
|
7780
|
+
}
|
|
7781
|
+
return out;
|
|
7782
|
+
}
|
|
7783
|
+
/**
|
|
7784
|
+
* Hi-low lines: a vertical line joining the highest and lowest series value in
|
|
7785
|
+
* each category. Returns `[]` when `c:hiLowLines` is absent or fewer than two
|
|
7786
|
+
* series are present.
|
|
7787
|
+
*/
|
|
7788
|
+
function computeHiLowLinePrimitives(chartData, layout, range, catCount, options) {
|
|
7789
|
+
const style = chartData.hiLowLines;
|
|
7790
|
+
if (!style || chartData.series.length < 2) {
|
|
7791
|
+
return [];
|
|
7792
|
+
}
|
|
7793
|
+
const dashArray = dashFor(style.dashStyle);
|
|
7794
|
+
const out = [];
|
|
7795
|
+
for (let vi = 0; vi < catCount; vi++) {
|
|
7796
|
+
let high = Number.NEGATIVE_INFINITY;
|
|
7797
|
+
let low = Number.POSITIVE_INFINITY;
|
|
7798
|
+
for (const series of chartData.series) {
|
|
7799
|
+
const v = series.values[vi];
|
|
7800
|
+
if (v !== undefined) {
|
|
7801
|
+
high = Math.max(high, v);
|
|
7802
|
+
low = Math.min(low, v);
|
|
7803
|
+
}
|
|
7804
|
+
}
|
|
7805
|
+
if (!Number.isFinite(high) || !Number.isFinite(low)) {
|
|
7806
|
+
continue;
|
|
7807
|
+
}
|
|
7808
|
+
const x = categoryX$2(vi, catCount, layout, options);
|
|
7809
|
+
out.push({
|
|
7810
|
+
kind: 'line',
|
|
7811
|
+
x1: x,
|
|
7812
|
+
y1: valueToY(high, range, layout.plotTop, layout.plotBottom),
|
|
7813
|
+
x2: x,
|
|
7814
|
+
y2: valueToY(low, range, layout.plotTop, layout.plotBottom),
|
|
7815
|
+
stroke: style.color ?? '#334155',
|
|
7816
|
+
strokeWidth: style.width ?? 1,
|
|
7817
|
+
dashArray,
|
|
7818
|
+
});
|
|
7819
|
+
}
|
|
7820
|
+
return out;
|
|
7821
|
+
}
|
|
7822
|
+
/**
|
|
7823
|
+
* Up-down bars: a bar between the first and last series value in each category.
|
|
7824
|
+
* Rising categories (last >= first) use the `upBars` fill, falling ones the
|
|
7825
|
+
* `downBars` fill. Returns `[]` when `c:upDownBars` is absent or fewer than two
|
|
7826
|
+
* series are present.
|
|
7827
|
+
*/
|
|
7828
|
+
function computeUpDownBarPrimitives(chartData, layout, range, catCount, options) {
|
|
7829
|
+
const bars = chartData.upDownBars;
|
|
7830
|
+
if (!bars || chartData.series.length < 2) {
|
|
7831
|
+
return [];
|
|
7832
|
+
}
|
|
7833
|
+
const first = chartData.series[0];
|
|
7834
|
+
const last = chartData.series[chartData.series.length - 1];
|
|
7835
|
+
const slot = layout.plotWidth / Math.max(catCount, 1);
|
|
7836
|
+
const gapWidth = bars.gapWidth ?? 150;
|
|
7837
|
+
const barW = Math.max(slot / (1 + Math.max(gapWidth, 0) / 100), 1);
|
|
7838
|
+
const upFill = bars.upBars?.fillColor ?? '#e2e8f0';
|
|
7839
|
+
const downFill = bars.downBars?.fillColor ?? '#334155';
|
|
7840
|
+
const out = [];
|
|
7841
|
+
for (let vi = 0; vi < catCount; vi++) {
|
|
7842
|
+
const firstVal = first.values[vi];
|
|
7843
|
+
const lastVal = last.values[vi];
|
|
7844
|
+
if (firstVal === undefined || lastVal === undefined) {
|
|
7845
|
+
continue;
|
|
7846
|
+
}
|
|
7847
|
+
const firstY = valueToY(firstVal, range, layout.plotTop, layout.plotBottom);
|
|
7848
|
+
const lastY = valueToY(lastVal, range, layout.plotTop, layout.plotBottom);
|
|
7849
|
+
const x = categoryX$2(vi, catCount, layout, options) - barW / 2;
|
|
7850
|
+
out.push({
|
|
7851
|
+
kind: 'rect',
|
|
7852
|
+
x,
|
|
7853
|
+
y: Math.min(firstY, lastY),
|
|
7854
|
+
w: barW,
|
|
7855
|
+
h: Math.max(Math.abs(firstY - lastY), 1),
|
|
7856
|
+
fill: lastVal >= firstVal ? upFill : downFill,
|
|
7857
|
+
});
|
|
7858
|
+
}
|
|
7859
|
+
return out;
|
|
7860
|
+
}
|
|
7861
|
+
/**
|
|
7862
|
+
* Convenience: all three helper-line families for a chart, concatenated.
|
|
7863
|
+
* Drawn under the series marks by the caller (they push the data marks first).
|
|
7864
|
+
*/
|
|
7865
|
+
function computeHelperLinePrimitives(chartData, layout, range, catCount, options) {
|
|
7866
|
+
return [
|
|
7867
|
+
...computeUpDownBarPrimitives(chartData, layout, range, catCount, options),
|
|
7868
|
+
...computeDropLinePrimitives(chartData, layout, range, catCount, options),
|
|
7869
|
+
...computeHiLowLinePrimitives(chartData, layout, range, catCount, options),
|
|
7870
|
+
];
|
|
7871
|
+
}
|
|
7872
|
+
|
|
7403
7873
|
function categoryX$1(displayIndex, count, layout, spacing) {
|
|
7404
7874
|
if (spacing === 'bar') {
|
|
7405
7875
|
return layout.plotLeft + (layout.plotWidth / Math.max(count, 1)) * (displayIndex + 0.5);
|
|
@@ -8573,7 +9043,19 @@ function buildCartesianViewModel(element, chartData, categoryLabels, kind) {
|
|
|
8573
9043
|
else {
|
|
8574
9044
|
plot = buildBubbles(chartData, layout, primaryRange);
|
|
8575
9045
|
}
|
|
8576
|
-
|
|
9046
|
+
// Drop lines / hi-low lines / up-down bars (line + area kinds). Drawn behind
|
|
9047
|
+
// the series marks so the data stays legible on top.
|
|
9048
|
+
const helperLines = kind === 'line' || kind === 'area'
|
|
9049
|
+
? computeHelperLinePrimitives(chartData, layout, primaryRange, catCount, {
|
|
9050
|
+
mode: 'line',
|
|
9051
|
+
xPositions: horizontalAxis.xPositions,
|
|
9052
|
+
})
|
|
9053
|
+
: [];
|
|
9054
|
+
const primitives = [
|
|
9055
|
+
...helperLines,
|
|
9056
|
+
...plot.primitives,
|
|
9057
|
+
...horizontalAxis.tickMarks,
|
|
9058
|
+
];
|
|
8577
9059
|
// Overlays (depth): regression trendlines, error bars, axis titles, data table.
|
|
8578
9060
|
const overlays = [
|
|
8579
9061
|
...computeTrendlinePrimitives(displayChartData, catCount, layout, primaryRange, catAxisStyle, chartData.colorPalette),
|
|
@@ -8656,6 +9138,9 @@ function buildComboViewModel(element, chartData, categoryLabels) {
|
|
|
8656
9138
|
const { legend, legendX, legendY, legendAnchor } = buildLegend(chartData.series, chartData.colorPalette, layout.svgWidth, legendPos, layout.svgHeight, layout.plotTop);
|
|
8657
9139
|
const primitives = [];
|
|
8658
9140
|
const dataLabels = [];
|
|
9141
|
+
// Drop / hi-low / up-down helper lines, drawn behind the combo marks.
|
|
9142
|
+
const helperOpts = { mode: 'line', xPositions: horizontalAxis.xPositions };
|
|
9143
|
+
primitives.push(...computeHelperLinePrimitives(chartData, layout, primaryRange, catCount, helperOpts));
|
|
8659
9144
|
const barSeries = chartData.series.slice(0, 1);
|
|
8660
9145
|
if (barSeries[0]) {
|
|
8661
9146
|
const barRange = rangeForSeries$1(0, primaryRange, secondaryRange, secondaryIndexes);
|
|
@@ -11320,16 +11805,28 @@ function computePieLayout(elementWidth, elementHeight, chartData, isDoughnut) {
|
|
|
11320
11805
|
const cx = size / 2;
|
|
11321
11806
|
const cy = titleOffset + (size - titleOffset - legendOffset) / 2;
|
|
11322
11807
|
const outerR = Math.max((size - titleOffset - legendOffset) * 0.42, 0);
|
|
11323
|
-
|
|
11808
|
+
// Honour c:holeSize (10-90% of the outer diameter) when parsed; otherwise
|
|
11809
|
+
// keep the legacy 0.55 ratio byte-for-byte.
|
|
11810
|
+
const holeRatio = isDoughnut && chartData.doughnutHoleSize !== undefined
|
|
11811
|
+
? Math.min(Math.max(chartData.doughnutHoleSize, 10), 90) / 100
|
|
11812
|
+
: 0.55;
|
|
11813
|
+
const innerR = isDoughnut ? outerR * holeRatio : 0;
|
|
11324
11814
|
return { cx, cy, outerR, innerR, size };
|
|
11325
11815
|
}
|
|
11326
|
-
function computePieSlices(values, cx, cy, outerR, innerR) {
|
|
11816
|
+
function computePieSlices(values, cx, cy, outerR, innerR, options) {
|
|
11327
11817
|
const total = values.reduce((s, v) => s + Math.abs(v), 0) || 1;
|
|
11328
|
-
let cumAngle = -Math.PI / 2;
|
|
11329
|
-
return values.map((val) => {
|
|
11818
|
+
let cumAngle = options?.startAngle ?? -Math.PI / 2;
|
|
11819
|
+
return values.map((val, i) => {
|
|
11330
11820
|
const sliceAngle = (Math.abs(val) / total) * Math.PI * 2;
|
|
11331
11821
|
const startAngle = cumAngle;
|
|
11332
11822
|
cumAngle += sliceAngle;
|
|
11823
|
+
// A c:explosion pulls the slice outward along its bisector.
|
|
11824
|
+
const explosion = options?.explosions?.[i] ?? 0;
|
|
11825
|
+
if (explosion > 0) {
|
|
11826
|
+
const mid = (startAngle + cumAngle) / 2;
|
|
11827
|
+
const offset = outerR * (explosion / 100);
|
|
11828
|
+
return computePieSlicePath(cx + Math.cos(mid) * offset, cy + Math.sin(mid) * offset, outerR, innerR, startAngle, cumAngle);
|
|
11829
|
+
}
|
|
11333
11830
|
return computePieSlicePath(cx, cy, outerR, innerR, startAngle, cumAngle);
|
|
11334
11831
|
});
|
|
11335
11832
|
}
|
|
@@ -11541,7 +12038,13 @@ function buildPieViewModel(element, chartData, categoryLabels, isDoughnut) {
|
|
|
11541
12038
|
const svgHeight = Math.max(size, 60);
|
|
11542
12039
|
const pieSeries = chartData.series[0];
|
|
11543
12040
|
const values = pieSeries?.values ?? [];
|
|
11544
|
-
|
|
12041
|
+
// c:firstSliceAng rotates the pie clockwise from 12 o'clock; c:explosion (per
|
|
12042
|
+
// series or per c:dPt) pulls slices outward.
|
|
12043
|
+
const startAngle = -Math.PI / 2 + ((chartData.firstSliceAngle ?? 0) * Math.PI) / 180;
|
|
12044
|
+
const explosions = pieSeries
|
|
12045
|
+
? values.map((_v, i) => resolveDataPointExplosion(pieSeries, i))
|
|
12046
|
+
: undefined;
|
|
12047
|
+
const slices = computePieSlices(values, cx, cy, outerR, innerR, { startAngle, explosions });
|
|
11545
12048
|
const primitives = slices.map(({ d }, i) => ({
|
|
11546
12049
|
kind: 'path',
|
|
11547
12050
|
d,
|
|
@@ -14222,6 +14725,51 @@ class AnimationSequencer {
|
|
|
14222
14725
|
* @module render/animation-timeline-builder
|
|
14223
14726
|
*/
|
|
14224
14727
|
// ==========================================================================
|
|
14728
|
+
// Unmapped-preset safety net
|
|
14729
|
+
// ==========================================================================
|
|
14730
|
+
/**
|
|
14731
|
+
* Resolve a fallback {@link EffectName} for an animation whose preset we do
|
|
14732
|
+
* not model (no static effect and no dynamic keyframe).
|
|
14733
|
+
*
|
|
14734
|
+
* Without this, an unmapped animation was silently dropped, which broke slide
|
|
14735
|
+
* visibility semantics: an unmapped **entrance** was never registered as
|
|
14736
|
+
* hidden-until-its-start, so it stayed visible from the very first frame; an
|
|
14737
|
+
* unmapped **exit** never hid its element. We substitute a neutral fade so the
|
|
14738
|
+
* element still transitions in (entrance) or out (exit) at the correct time.
|
|
14739
|
+
*
|
|
14740
|
+
* Emphasis / motion-path presets carry no show/hide semantics, so a missing
|
|
14741
|
+
* one is safe to skip and returns `undefined`.
|
|
14742
|
+
*/
|
|
14743
|
+
/**
|
|
14744
|
+
* Map an animation's parsed `accel`/`decel` fractions to a CSS timing function.
|
|
14745
|
+
* PowerPoint's acceleration eases the effect in, deceleration eases it out, and
|
|
14746
|
+
* both together ease in-and-out. With neither set we keep the neutral `ease`
|
|
14747
|
+
* default so existing decks are unchanged.
|
|
14748
|
+
*/
|
|
14749
|
+
function cssEasingForAnimation(anim) {
|
|
14750
|
+
const hasAccel = anim.accel !== undefined && anim.accel > 0;
|
|
14751
|
+
const hasDecel = anim.decel !== undefined && anim.decel > 0;
|
|
14752
|
+
if (hasAccel && hasDecel) {
|
|
14753
|
+
return 'ease-in-out';
|
|
14754
|
+
}
|
|
14755
|
+
if (hasAccel) {
|
|
14756
|
+
return 'ease-in';
|
|
14757
|
+
}
|
|
14758
|
+
if (hasDecel) {
|
|
14759
|
+
return 'ease-out';
|
|
14760
|
+
}
|
|
14761
|
+
return 'ease';
|
|
14762
|
+
}
|
|
14763
|
+
function fallbackEffectForClass(presetClass) {
|
|
14764
|
+
if (presetClass === 'entr') {
|
|
14765
|
+
return 'fadeIn';
|
|
14766
|
+
}
|
|
14767
|
+
if (presetClass === 'exit') {
|
|
14768
|
+
return 'fadeOut';
|
|
14769
|
+
}
|
|
14770
|
+
return undefined;
|
|
14771
|
+
}
|
|
14772
|
+
// ==========================================================================
|
|
14225
14773
|
// Timeline builder
|
|
14226
14774
|
// ==========================================================================
|
|
14227
14775
|
/**
|
|
@@ -14284,10 +14832,15 @@ function buildTimeline(nativeAnimations) {
|
|
|
14284
14832
|
for (const anim of regularAnims) {
|
|
14285
14833
|
const expandedSteps = expandIterateAnimation(anim);
|
|
14286
14834
|
for (const singleAnim of expandedSteps) {
|
|
14287
|
-
|
|
14835
|
+
let effect = resolveEffect(singleAnim);
|
|
14288
14836
|
const dynamic = effect ? undefined : buildDynamicKeyframe(singleAnim, dynamicUid++);
|
|
14289
14837
|
if (!effect && !dynamic) {
|
|
14290
|
-
|
|
14838
|
+
// Unmapped preset: fall back so an entrance is still hidden until
|
|
14839
|
+
// its start and an exit still hides, rather than being dropped.
|
|
14840
|
+
effect = fallbackEffectForClass(singleAnim.presetClass);
|
|
14841
|
+
if (!effect) {
|
|
14842
|
+
continue;
|
|
14843
|
+
}
|
|
14291
14844
|
}
|
|
14292
14845
|
const keyframe = effect ? cssKeyframeName(effect) : dynamic.keyframeName;
|
|
14293
14846
|
if (effect) {
|
|
@@ -14351,7 +14904,8 @@ function buildTimeline(nativeAnimations) {
|
|
|
14351
14904
|
delayMs = animDelay + triggerDelay;
|
|
14352
14905
|
}
|
|
14353
14906
|
const iterStr = iterCount === Infinity ? 'infinite' : String(iterCount);
|
|
14354
|
-
const
|
|
14907
|
+
const easing = cssEasingForAnimation(singleAnim);
|
|
14908
|
+
const cssAnimation = `${keyframe} ${duration}ms ${easing} ${delayMs}ms ${iterStr} ${direction} ${fill}`;
|
|
14355
14909
|
currentGroup.push({
|
|
14356
14910
|
elementId,
|
|
14357
14911
|
cssAnimation,
|
|
@@ -14452,10 +15006,14 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
|
|
|
14452
15006
|
const seqGroups = [];
|
|
14453
15007
|
let seqGroup = [];
|
|
14454
15008
|
for (const anim of anims) {
|
|
14455
|
-
|
|
15009
|
+
let effect = resolveEffect(anim);
|
|
14456
15010
|
const dynamic = effect ? undefined : buildDynamicKeyframe(anim, dynamicUid++);
|
|
14457
15011
|
if (!effect && !dynamic) {
|
|
14458
|
-
|
|
15012
|
+
// Same unmapped-preset safety net as the main timeline loop.
|
|
15013
|
+
effect = fallbackEffectForClass(anim.presetClass);
|
|
15014
|
+
if (!effect) {
|
|
15015
|
+
continue;
|
|
15016
|
+
}
|
|
14459
15017
|
}
|
|
14460
15018
|
const keyframe = effect ? cssKeyframeName(effect) : dynamic.keyframeName;
|
|
14461
15019
|
if (effect) {
|
|
@@ -14495,7 +15053,8 @@ function buildSequenceGroups(animsByKey, entranceIds, neededKeyframes, dynamicBl
|
|
|
14495
15053
|
delayMs = animDelay + triggerDelay;
|
|
14496
15054
|
}
|
|
14497
15055
|
const iterStr = iterCount === Infinity ? 'infinite' : String(iterCount);
|
|
14498
|
-
const
|
|
15056
|
+
const easing = cssEasingForAnimation(anim);
|
|
15057
|
+
const cssAnimation = `${keyframe} ${duration}ms ${easing} ${delayMs}ms ${iterStr} ${direction} ${fill}`;
|
|
14499
15058
|
seqGroup.push({
|
|
14500
15059
|
elementId,
|
|
14501
15060
|
cssAnimation,
|
|
@@ -16264,6 +16823,174 @@ function resolveCellBorderCss(entry, tableData, pos, resolve) {
|
|
|
16264
16823
|
return applied ? css : undefined;
|
|
16265
16824
|
}
|
|
16266
16825
|
|
|
16826
|
+
// ---------------------------------------------------------------------------
|
|
16827
|
+
// Theme colour helpers (tint / shade) — mirrors React viewer/utils/theme.ts
|
|
16828
|
+
// ---------------------------------------------------------------------------
|
|
16829
|
+
/** Parse a 6-digit hex colour (`#RRGGBB` or `RRGGBB`) into RGB components. */
|
|
16830
|
+
function hexToRgb$2(hex) {
|
|
16831
|
+
const clean = hex.replace(/^#/u, '');
|
|
16832
|
+
return {
|
|
16833
|
+
r: parseInt(clean.substring(0, 2), 16),
|
|
16834
|
+
g: parseInt(clean.substring(2, 4), 16),
|
|
16835
|
+
b: parseInt(clean.substring(4, 6), 16),
|
|
16836
|
+
};
|
|
16837
|
+
}
|
|
16838
|
+
/** Convert RGB components back to a `#RRGGBB` string. */
|
|
16839
|
+
function rgbToHex$1(r, g, b) {
|
|
16840
|
+
const clamp = (v) => Math.max(0, Math.min(255, Math.round(v)));
|
|
16841
|
+
return `#${clamp(r).toString(16).padStart(2, '0').toUpperCase()}${clamp(g).toString(16).padStart(2, '0').toUpperCase()}${clamp(b).toString(16).padStart(2, '0').toUpperCase()}`;
|
|
16842
|
+
}
|
|
16843
|
+
/** Compute a tinted (lighter) colour. `tintFactor` in 0-1 (1 = white). */
|
|
16844
|
+
function tintColor$1(hex, tintFactor) {
|
|
16845
|
+
const { r, g, b } = hexToRgb$2(hex);
|
|
16846
|
+
return rgbToHex$1(r + (255 - r) * tintFactor, g + (255 - g) * tintFactor, b + (255 - b) * tintFactor);
|
|
16847
|
+
}
|
|
16848
|
+
/** Compute a shaded (darker) colour. `shadeFactor` in 0-1 (1 = black). */
|
|
16849
|
+
function shadeColor$1(hex, shadeFactor) {
|
|
16850
|
+
const { r, g, b } = hexToRgb$2(hex);
|
|
16851
|
+
return rgbToHex$1(r * (1 - shadeFactor), g * (1 - shadeFactor), b * (1 - shadeFactor));
|
|
16852
|
+
}
|
|
16853
|
+
/** Apply a fill's tint/shade to a resolved base hex colour. */
|
|
16854
|
+
function applyTintShade(base, fill) {
|
|
16855
|
+
let color = base;
|
|
16856
|
+
if (fill.tint !== undefined && fill.tint > 0) {
|
|
16857
|
+
color = tintColor$1(color, fill.tint / 100_000);
|
|
16858
|
+
}
|
|
16859
|
+
if (fill.shade !== undefined && fill.shade > 0) {
|
|
16860
|
+
color = shadeColor$1(color, 1 - fill.shade / 100_000);
|
|
16861
|
+
}
|
|
16862
|
+
return color;
|
|
16863
|
+
}
|
|
16864
|
+
/**
|
|
16865
|
+
* Resolve a {@link ParsedTableStyleFill} to a concrete CSS hex colour using the
|
|
16866
|
+
* supplied colour scheme. Honours a scheme colour first, then an explicit sRGB
|
|
16867
|
+
* `color`. Returns `undefined` when neither resolves (e.g. gradient/pattern/no
|
|
16868
|
+
* fill, or a scheme key absent from the theme).
|
|
16869
|
+
*/
|
|
16870
|
+
function resolveStyleFillColor(fill, colorScheme) {
|
|
16871
|
+
if (!fill) {
|
|
16872
|
+
return undefined;
|
|
16873
|
+
}
|
|
16874
|
+
let base;
|
|
16875
|
+
if (fill.schemeColor && colorScheme) {
|
|
16876
|
+
base = colorScheme[fill.schemeColor];
|
|
16877
|
+
}
|
|
16878
|
+
if (!base && fill.color) {
|
|
16879
|
+
base = fill.color;
|
|
16880
|
+
}
|
|
16881
|
+
if (!base) {
|
|
16882
|
+
return undefined;
|
|
16883
|
+
}
|
|
16884
|
+
return applyTintShade(base, fill);
|
|
16885
|
+
}
|
|
16886
|
+
/** Clear every background-related key so a higher layer replaces cleanly. */
|
|
16887
|
+
function clearBackground(css) {
|
|
16888
|
+
delete css.background;
|
|
16889
|
+
delete css.backgroundColor;
|
|
16890
|
+
delete css.backgroundImage;
|
|
16891
|
+
}
|
|
16892
|
+
/** Build a CSS gradient string from a parsed table-style gradient fill. */
|
|
16893
|
+
function gradientCssFromFill(fill, colorScheme) {
|
|
16894
|
+
const gradient = fill.gradient;
|
|
16895
|
+
if (!gradient || gradient.stops.length === 0) {
|
|
16896
|
+
return undefined;
|
|
16897
|
+
}
|
|
16898
|
+
const shapeLike = {
|
|
16899
|
+
fillMode: 'gradient',
|
|
16900
|
+
fillGradientType: gradient.type,
|
|
16901
|
+
fillGradientAngle: gradient.angle ?? 90,
|
|
16902
|
+
fillGradientStops: gradient.stops.map((stop) => ({
|
|
16903
|
+
color: resolveStyleFillColor(stop.fill, colorScheme) ?? stop.fill.color ?? '#000000',
|
|
16904
|
+
position: stop.position,
|
|
16905
|
+
})),
|
|
16906
|
+
};
|
|
16907
|
+
return buildGradientCss(shapeLike);
|
|
16908
|
+
}
|
|
16909
|
+
/**
|
|
16910
|
+
* Apply a {@link ParsedTableStyleFill} onto a {@link TableCellCss} background.
|
|
16911
|
+
* Handles no-fill (transparent), gradient, preset pattern, and solid (scheme or
|
|
16912
|
+
* sRGB) fills. When the fill is absent or unresolvable, falls back to
|
|
16913
|
+
* `fallback` as a solid background colour. Returns `true` when anything was set.
|
|
16914
|
+
*/
|
|
16915
|
+
function applyStyleFill(fill, colorScheme, css, fallback) {
|
|
16916
|
+
if (fill?.noFill) {
|
|
16917
|
+
clearBackground(css);
|
|
16918
|
+
css.backgroundColor = 'transparent';
|
|
16919
|
+
return true;
|
|
16920
|
+
}
|
|
16921
|
+
if (fill?.gradient) {
|
|
16922
|
+
const gradientCss = gradientCssFromFill(fill, colorScheme);
|
|
16923
|
+
if (gradientCss) {
|
|
16924
|
+
clearBackground(css);
|
|
16925
|
+
css.background = gradientCss;
|
|
16926
|
+
return true;
|
|
16927
|
+
}
|
|
16928
|
+
}
|
|
16929
|
+
if (fill?.pattern) {
|
|
16930
|
+
const fg = normalizeHexColor$1(resolveStyleFillColor(fill.pattern.foreground, colorScheme), '#000000');
|
|
16931
|
+
const bg = normalizeHexColor$1(resolveStyleFillColor(fill.pattern.background, colorScheme), '#ffffff');
|
|
16932
|
+
const svg = getPatternSvg$1(fill.pattern.preset, fg, bg);
|
|
16933
|
+
clearBackground(css);
|
|
16934
|
+
if (svg) {
|
|
16935
|
+
css.backgroundImage = `url("data:image/svg+xml,${encodeURIComponent(svg)}")`;
|
|
16936
|
+
}
|
|
16937
|
+
css.backgroundColor = bg;
|
|
16938
|
+
return true;
|
|
16939
|
+
}
|
|
16940
|
+
const color = resolveStyleFillColor(fill, colorScheme) ?? fallback;
|
|
16941
|
+
if (color) {
|
|
16942
|
+
clearBackground(css);
|
|
16943
|
+
css.backgroundColor = color;
|
|
16944
|
+
return true;
|
|
16945
|
+
}
|
|
16946
|
+
return false;
|
|
16947
|
+
}
|
|
16948
|
+
/**
|
|
16949
|
+
* Apply text properties from a {@link ParsedTableStyleText} entry into a
|
|
16950
|
+
* {@link TableCellCss} object. Returns `true` when any property was set.
|
|
16951
|
+
*/
|
|
16952
|
+
function applyStyleText(text, colorScheme, css) {
|
|
16953
|
+
if (!text) {
|
|
16954
|
+
return false;
|
|
16955
|
+
}
|
|
16956
|
+
let applied = false;
|
|
16957
|
+
if (text.bold) {
|
|
16958
|
+
css.fontWeight = 700;
|
|
16959
|
+
applied = true;
|
|
16960
|
+
}
|
|
16961
|
+
if (text.italic) {
|
|
16962
|
+
css.fontStyle = 'italic';
|
|
16963
|
+
applied = true;
|
|
16964
|
+
}
|
|
16965
|
+
if (text.underline) {
|
|
16966
|
+
css.textDecorationLine = 'underline';
|
|
16967
|
+
applied = true;
|
|
16968
|
+
}
|
|
16969
|
+
if (text.fontFace) {
|
|
16970
|
+
css.fontFamily = text.fontFace;
|
|
16971
|
+
applied = true;
|
|
16972
|
+
}
|
|
16973
|
+
if (text.fontSchemeColor && colorScheme) {
|
|
16974
|
+
const base = colorScheme[text.fontSchemeColor];
|
|
16975
|
+
if (base) {
|
|
16976
|
+
let color = base;
|
|
16977
|
+
if (text.fontTint !== undefined && text.fontTint > 0) {
|
|
16978
|
+
color = tintColor$1(color, text.fontTint / 100_000);
|
|
16979
|
+
}
|
|
16980
|
+
if (text.fontShade !== undefined && text.fontShade > 0) {
|
|
16981
|
+
color = shadeColor$1(color, 1 - text.fontShade / 100_000);
|
|
16982
|
+
}
|
|
16983
|
+
css.color = color;
|
|
16984
|
+
applied = true;
|
|
16985
|
+
}
|
|
16986
|
+
}
|
|
16987
|
+
else if (text.fontColor) {
|
|
16988
|
+
css.color = text.fontColor;
|
|
16989
|
+
applied = true;
|
|
16990
|
+
}
|
|
16991
|
+
return applied;
|
|
16992
|
+
}
|
|
16993
|
+
|
|
16267
16994
|
/**
|
|
16268
16995
|
* Convert a {@link CellTextRun}'s per-run formatting to an inline CSS style
|
|
16269
16996
|
* object suitable for a `<span>` element.
|
|
@@ -16323,97 +17050,6 @@ function cellPatternFillCss(style) {
|
|
|
16323
17050
|
const fallback = style.patternFillBackground ?? style.backgroundColor;
|
|
16324
17051
|
return fallback ? { backgroundColor: fallback } : null;
|
|
16325
17052
|
}
|
|
16326
|
-
// ---------------------------------------------------------------------------
|
|
16327
|
-
// Theme colour helpers (tint / shade) — mirrors React viewer/utils/theme.ts
|
|
16328
|
-
// ---------------------------------------------------------------------------
|
|
16329
|
-
/** Parse a 6-digit hex colour (`#RRGGBB` or `RRGGBB`) into RGB components. */
|
|
16330
|
-
function hexToRgb$2(hex) {
|
|
16331
|
-
const clean = hex.replace(/^#/u, '');
|
|
16332
|
-
return {
|
|
16333
|
-
r: parseInt(clean.substring(0, 2), 16),
|
|
16334
|
-
g: parseInt(clean.substring(2, 4), 16),
|
|
16335
|
-
b: parseInt(clean.substring(4, 6), 16),
|
|
16336
|
-
};
|
|
16337
|
-
}
|
|
16338
|
-
/** Convert RGB components back to a `#RRGGBB` string. */
|
|
16339
|
-
function rgbToHex$1(r, g, b) {
|
|
16340
|
-
const clamp = (v) => Math.max(0, Math.min(255, Math.round(v)));
|
|
16341
|
-
return `#${clamp(r).toString(16).padStart(2, '0').toUpperCase()}${clamp(g).toString(16).padStart(2, '0').toUpperCase()}${clamp(b).toString(16).padStart(2, '0').toUpperCase()}`;
|
|
16342
|
-
}
|
|
16343
|
-
/**
|
|
16344
|
-
* Compute a tinted (lighter) version of a colour.
|
|
16345
|
-
* `tintFactor` is 0–1 where 1 = white and 0 = original.
|
|
16346
|
-
*/
|
|
16347
|
-
function tintColor$1(hex, tintFactor) {
|
|
16348
|
-
const { r, g, b } = hexToRgb$2(hex);
|
|
16349
|
-
return rgbToHex$1(r + (255 - r) * tintFactor, g + (255 - g) * tintFactor, b + (255 - b) * tintFactor);
|
|
16350
|
-
}
|
|
16351
|
-
/**
|
|
16352
|
-
* Compute a shaded (darker) version of a colour.
|
|
16353
|
-
* `shadeFactor` is 0–1 where 1 = black and 0 = original.
|
|
16354
|
-
*/
|
|
16355
|
-
function shadeColor$1(hex, shadeFactor) {
|
|
16356
|
-
const { r, g, b } = hexToRgb$2(hex);
|
|
16357
|
-
return rgbToHex$1(r * (1 - shadeFactor), g * (1 - shadeFactor), b * (1 - shadeFactor));
|
|
16358
|
-
}
|
|
16359
|
-
/**
|
|
16360
|
-
* Resolve a {@link ParsedTableStyleFill} to a CSS hex colour using the
|
|
16361
|
-
* supplied colour scheme. Returns `undefined` when the scheme colour key
|
|
16362
|
-
* cannot be found.
|
|
16363
|
-
*/
|
|
16364
|
-
function resolveStyleFillColor(fill, colorScheme) {
|
|
16365
|
-
if (!fill) {
|
|
16366
|
-
return undefined;
|
|
16367
|
-
}
|
|
16368
|
-
if (!colorScheme) {
|
|
16369
|
-
return undefined;
|
|
16370
|
-
}
|
|
16371
|
-
const base = colorScheme[fill.schemeColor];
|
|
16372
|
-
if (!base) {
|
|
16373
|
-
return undefined;
|
|
16374
|
-
}
|
|
16375
|
-
let color = base;
|
|
16376
|
-
if (fill.tint !== undefined && fill.tint > 0) {
|
|
16377
|
-
color = tintColor$1(color, fill.tint / 100_000);
|
|
16378
|
-
}
|
|
16379
|
-
if (fill.shade !== undefined && fill.shade > 0) {
|
|
16380
|
-
color = shadeColor$1(color, 1 - fill.shade / 100_000);
|
|
16381
|
-
}
|
|
16382
|
-
return color;
|
|
16383
|
-
}
|
|
16384
|
-
/**
|
|
16385
|
-
* Apply text properties from a {@link ParsedTableStyleText} entry into a
|
|
16386
|
-
* {@link TableCellCss} object. Returns `true` when any property was set.
|
|
16387
|
-
*/
|
|
16388
|
-
function applyStyleText(text, colorScheme, css) {
|
|
16389
|
-
if (!text) {
|
|
16390
|
-
return false;
|
|
16391
|
-
}
|
|
16392
|
-
let applied = false;
|
|
16393
|
-
if (text.bold) {
|
|
16394
|
-
css.fontWeight = 700;
|
|
16395
|
-
applied = true;
|
|
16396
|
-
}
|
|
16397
|
-
if (text.italic) {
|
|
16398
|
-
css.fontStyle = 'italic';
|
|
16399
|
-
applied = true;
|
|
16400
|
-
}
|
|
16401
|
-
if (text.fontSchemeColor && colorScheme) {
|
|
16402
|
-
const base = colorScheme[text.fontSchemeColor];
|
|
16403
|
-
if (base) {
|
|
16404
|
-
let color = base;
|
|
16405
|
-
if (text.fontTint !== undefined && text.fontTint > 0) {
|
|
16406
|
-
color = tintColor$1(color, text.fontTint / 100_000);
|
|
16407
|
-
}
|
|
16408
|
-
if (text.fontShade !== undefined && text.fontShade > 0) {
|
|
16409
|
-
color = shadeColor$1(color, 1 - text.fontShade / 100_000);
|
|
16410
|
-
}
|
|
16411
|
-
css.color = color;
|
|
16412
|
-
applied = true;
|
|
16413
|
-
}
|
|
16414
|
-
}
|
|
16415
|
-
return applied;
|
|
16416
|
-
}
|
|
16417
17053
|
/**
|
|
16418
17054
|
* Look up the table style entry for a style GUID, trying both the raw value
|
|
16419
17055
|
* and the braced-upper-case normalisation that OOXML uses.
|
|
@@ -16642,9 +17278,7 @@ function getTableCellBandStyle(tableData, rowIndex, cellIndex, rowCount, columnC
|
|
|
16642
17278
|
let applied = false;
|
|
16643
17279
|
// ── Whole-table fill (lowest priority layer). ──
|
|
16644
17280
|
if (styleEntry?.wholeTblFill) {
|
|
16645
|
-
|
|
16646
|
-
if (wholeBg) {
|
|
16647
|
-
style.backgroundColor = wholeBg;
|
|
17281
|
+
if (applyStyleFill(styleEntry.wholeTblFill, colorScheme, style, '')) {
|
|
16648
17282
|
applied = true;
|
|
16649
17283
|
}
|
|
16650
17284
|
}
|
|
@@ -16659,16 +17293,12 @@ function getTableCellBandStyle(tableData, rowIndex, cellIndex, rowCount, columnC
|
|
|
16659
17293
|
const rowCycle = Math.max(tableData.bandRowCycle ?? 1, 1);
|
|
16660
17294
|
const bandGroup = Math.floor(bandIndex / rowCycle) % 2;
|
|
16661
17295
|
if (bandGroup === 0) {
|
|
16662
|
-
|
|
16663
|
-
|
|
16664
|
-
applied = true;
|
|
16665
|
-
}
|
|
17296
|
+
applyStyleFill(styleEntry?.band1HFill, colorScheme, style, 'rgba(217, 226, 243, 0.5)');
|
|
17297
|
+
applyStyleText(styleEntry?.band1HText, colorScheme, style);
|
|
16666
17298
|
applied = true;
|
|
16667
17299
|
}
|
|
16668
17300
|
else if (styleEntry?.band2HFill) {
|
|
16669
|
-
|
|
16670
|
-
if (band2Bg) {
|
|
16671
|
-
style.backgroundColor = band2Bg;
|
|
17301
|
+
if (applyStyleFill(styleEntry.band2HFill, colorScheme, style, '')) {
|
|
16672
17302
|
applyStyleText(styleEntry.band2HText, colorScheme, style);
|
|
16673
17303
|
applied = true;
|
|
16674
17304
|
}
|
|
@@ -16683,21 +17313,19 @@ function getTableCellBandStyle(tableData, rowIndex, cellIndex, rowCount, columnC
|
|
|
16683
17313
|
if (!skipCol) {
|
|
16684
17314
|
const colCycle = Math.max(tableData.bandColCycle ?? 1, 1);
|
|
16685
17315
|
const colBandGroup = Math.floor(colBandIndex / colCycle) % 2;
|
|
17316
|
+
// Column banding yields to row banding when both apply to this cell.
|
|
17317
|
+
const canOverride = !style.backgroundColor || !tableData.bandedRows;
|
|
16686
17318
|
if (colBandGroup === 0) {
|
|
16687
|
-
if (
|
|
16688
|
-
|
|
17319
|
+
if (canOverride) {
|
|
17320
|
+
applyStyleFill(styleEntry?.band1VFill, colorScheme, style, 'rgba(217, 226, 243, 0.35)');
|
|
16689
17321
|
applyStyleText(styleEntry?.band1VText, colorScheme, style);
|
|
16690
17322
|
applied = true;
|
|
16691
17323
|
}
|
|
16692
17324
|
}
|
|
16693
|
-
else if (styleEntry?.band2VFill) {
|
|
16694
|
-
if (
|
|
16695
|
-
|
|
16696
|
-
|
|
16697
|
-
style.backgroundColor = band2Bg;
|
|
16698
|
-
applyStyleText(styleEntry.band2VText, colorScheme, style);
|
|
16699
|
-
applied = true;
|
|
16700
|
-
}
|
|
17325
|
+
else if (styleEntry?.band2VFill && canOverride) {
|
|
17326
|
+
if (applyStyleFill(styleEntry.band2VFill, colorScheme, style, '')) {
|
|
17327
|
+
applyStyleText(styleEntry.band2VText, colorScheme, style);
|
|
17328
|
+
applied = true;
|
|
16701
17329
|
}
|
|
16702
17330
|
}
|
|
16703
17331
|
}
|
|
@@ -16705,7 +17333,7 @@ function getTableCellBandStyle(tableData, rowIndex, cellIndex, rowCount, columnC
|
|
|
16705
17333
|
// ── Header row (first row). ──
|
|
16706
17334
|
if (tableData.firstRowHeader && rowIndex === 0) {
|
|
16707
17335
|
style.fontWeight = 700;
|
|
16708
|
-
|
|
17336
|
+
applyStyleFill(styleEntry?.firstRowFill, colorScheme, style, 'rgba(68, 114, 196, 0.85)');
|
|
16709
17337
|
style.color = '#ffffff';
|
|
16710
17338
|
applyStyleText(styleEntry?.firstRowText, colorScheme, style);
|
|
16711
17339
|
applied = true;
|
|
@@ -16714,10 +17342,7 @@ function getTableCellBandStyle(tableData, rowIndex, cellIndex, rowCount, columnC
|
|
|
16714
17342
|
if (tableData.lastRow && rowIndex === rowCount - 1) {
|
|
16715
17343
|
style.fontWeight = 700;
|
|
16716
17344
|
if (styleEntry?.lastRowFill) {
|
|
16717
|
-
|
|
16718
|
-
if (lastRowBg) {
|
|
16719
|
-
style.backgroundColor = lastRowBg;
|
|
16720
|
-
}
|
|
17345
|
+
applyStyleFill(styleEntry.lastRowFill, colorScheme, style, '');
|
|
16721
17346
|
}
|
|
16722
17347
|
const borderColor = resolveFill(styleEntry?.firstRowFill, 'rgba(68, 114, 196, 0.7)');
|
|
16723
17348
|
style.borderTop = `2px solid ${borderColor}`;
|
|
@@ -16728,10 +17353,7 @@ function getTableCellBandStyle(tableData, rowIndex, cellIndex, rowCount, columnC
|
|
|
16728
17353
|
if (tableData.firstCol && cellIndex === 0) {
|
|
16729
17354
|
style.fontWeight = 700;
|
|
16730
17355
|
if (styleEntry?.firstColFill) {
|
|
16731
|
-
|
|
16732
|
-
if (firstColBg) {
|
|
16733
|
-
style.backgroundColor = firstColBg;
|
|
16734
|
-
}
|
|
17356
|
+
applyStyleFill(styleEntry.firstColFill, colorScheme, style, '');
|
|
16735
17357
|
}
|
|
16736
17358
|
applyStyleText(styleEntry?.firstColText, colorScheme, style);
|
|
16737
17359
|
applied = true;
|
|
@@ -16740,14 +17362,46 @@ function getTableCellBandStyle(tableData, rowIndex, cellIndex, rowCount, columnC
|
|
|
16740
17362
|
if (tableData.lastCol && cellIndex === columnCount - 1) {
|
|
16741
17363
|
style.fontWeight = 700;
|
|
16742
17364
|
if (styleEntry?.lastColFill) {
|
|
16743
|
-
|
|
16744
|
-
if (lastColBg) {
|
|
16745
|
-
style.backgroundColor = lastColBg;
|
|
16746
|
-
}
|
|
17365
|
+
applyStyleFill(styleEntry.lastColFill, colorScheme, style, '');
|
|
16747
17366
|
}
|
|
16748
17367
|
applyStyleText(styleEntry?.lastColText, colorScheme, style);
|
|
16749
17368
|
applied = true;
|
|
16750
17369
|
}
|
|
17370
|
+
// ── Corner cells (highest fill/text precedence, issue #95). ──
|
|
17371
|
+
// Each corner overrides the intersection of a first/last row with a
|
|
17372
|
+
// first/last column (CT_TableStyle, ECMA-376 §21.1.3.16): nw = top-left,
|
|
17373
|
+
// ne = top-right, sw = bottom-left, se = bottom-right. Only applies when
|
|
17374
|
+
// both the row and column emphasis are active for this cell.
|
|
17375
|
+
if (styleEntry) {
|
|
17376
|
+
const atTop = Boolean(tableData.firstRowHeader) && rowIndex === 0;
|
|
17377
|
+
const atBottom = Boolean(tableData.lastRow) && rowIndex === rowCount - 1;
|
|
17378
|
+
const atLeft = Boolean(tableData.firstCol) && cellIndex === 0;
|
|
17379
|
+
const atRight = Boolean(tableData.lastCol) && cellIndex === columnCount - 1;
|
|
17380
|
+
let cornerFill;
|
|
17381
|
+
let cornerText = undefined;
|
|
17382
|
+
if (atTop && atLeft) {
|
|
17383
|
+
cornerFill = styleEntry.nwCellFill;
|
|
17384
|
+
cornerText = styleEntry.nwCellText;
|
|
17385
|
+
}
|
|
17386
|
+
else if (atTop && atRight) {
|
|
17387
|
+
cornerFill = styleEntry.neCellFill;
|
|
17388
|
+
cornerText = styleEntry.neCellText;
|
|
17389
|
+
}
|
|
17390
|
+
else if (atBottom && atLeft) {
|
|
17391
|
+
cornerFill = styleEntry.swCellFill;
|
|
17392
|
+
cornerText = styleEntry.swCellText;
|
|
17393
|
+
}
|
|
17394
|
+
else if (atBottom && atRight) {
|
|
17395
|
+
cornerFill = styleEntry.seCellFill;
|
|
17396
|
+
cornerText = styleEntry.seCellText;
|
|
17397
|
+
}
|
|
17398
|
+
if (cornerFill && applyStyleFill(cornerFill, colorScheme, style, '')) {
|
|
17399
|
+
applied = true;
|
|
17400
|
+
}
|
|
17401
|
+
if (applyStyleText(cornerText, colorScheme, style)) {
|
|
17402
|
+
applied = true;
|
|
17403
|
+
}
|
|
17404
|
+
}
|
|
16751
17405
|
// ── Table-style borders (issue #71). ──
|
|
16752
17406
|
// Resolve gridlines/edges the cell inherits from the table style and let
|
|
16753
17407
|
// them supersede the hardcoded total-row line above. Per-cell explicit
|
|
@@ -23938,6 +24592,9 @@ function waypointsToPathD(waypoints) {
|
|
|
23938
24592
|
/**
|
|
23939
24593
|
* Compute connection sites for a rectangular bounding box. Returns the four
|
|
23940
24594
|
* edge midpoints in element-local coordinates: top, right, bottom, left.
|
|
24595
|
+
*
|
|
24596
|
+
* This is the fallback used for shapes whose real connection sites are
|
|
24597
|
+
* unknown (preset shapes without a parsed `a:cxnLst`).
|
|
23941
24598
|
*/
|
|
23942
24599
|
function getConnectionSites(width, height) {
|
|
23943
24600
|
return [
|
|
@@ -23947,6 +24604,36 @@ function getConnectionSites(width, height) {
|
|
|
23947
24604
|
{ x: 0, y: height / 2, index: 3 }, // left center
|
|
23948
24605
|
];
|
|
23949
24606
|
}
|
|
24607
|
+
/**
|
|
24608
|
+
* Resolve the connection sites of a shape element in element-local pixel
|
|
24609
|
+
* coordinates.
|
|
24610
|
+
*
|
|
24611
|
+
* When the shape carries typed custom-geometry connection sites (parsed from
|
|
24612
|
+
* `a:custGeom/a:cxnLst/a:cxn`), each `a:pos` formula is evaluated against the
|
|
24613
|
+
* shape's path coordinate space and scaled to the element's pixel box, so a
|
|
24614
|
+
* connector referencing `stCxn/@idx` on a non-rectangular shape attaches near
|
|
24615
|
+
* the real site rather than collapsing to an edge midpoint. Shapes with no
|
|
24616
|
+
* known sites fall back to the four edge midpoints.
|
|
24617
|
+
*/
|
|
24618
|
+
function getShapeConnectionSites(shape) {
|
|
24619
|
+
const geo = shape;
|
|
24620
|
+
const cxn = geo.customGeometryConnectionSites;
|
|
24621
|
+
if (!cxn || cxn.length === 0) {
|
|
24622
|
+
return getConnectionSites(shape.width, shape.height);
|
|
24623
|
+
}
|
|
24624
|
+
// Path coordinate space the `a:pos` formulas are expressed in. Fall back to
|
|
24625
|
+
// the element's pixel dimensions (scale factor 1) when unavailable.
|
|
24626
|
+
const pathW = geo.pathWidth && geo.pathWidth > 0 ? geo.pathWidth : shape.width;
|
|
24627
|
+
const pathH = geo.pathHeight && geo.pathHeight > 0 ? geo.pathHeight : shape.height;
|
|
24628
|
+
const vars = createBuiltinVariables({ w: pathW, h: pathH });
|
|
24629
|
+
const scaleX = pathW > 0 ? shape.width / pathW : 1;
|
|
24630
|
+
const scaleY = pathH > 0 ? shape.height / pathH : 1;
|
|
24631
|
+
return cxn.map((site, index) => ({
|
|
24632
|
+
x: resolveCoordinate(site.posX, vars) * scaleX,
|
|
24633
|
+
y: resolveCoordinate(site.posY, vars) * scaleY,
|
|
24634
|
+
index,
|
|
24635
|
+
}));
|
|
24636
|
+
}
|
|
23950
24637
|
/**
|
|
23951
24638
|
* Find all connectors on the slide that reference any of the given element IDs
|
|
23952
24639
|
* via `connectorStartConnection`/`connectorEndConnection`, and recalculate
|
|
@@ -24006,7 +24693,7 @@ function computeConnectorGeometry(connector, startConn, endConn, elementMap) {
|
|
|
24006
24693
|
if (!startShape) {
|
|
24007
24694
|
return null;
|
|
24008
24695
|
}
|
|
24009
|
-
const sites =
|
|
24696
|
+
const sites = getShapeConnectionSites(startShape);
|
|
24010
24697
|
const siteIndex = startConn.connectionSiteIndex ?? 0;
|
|
24011
24698
|
const site = sites[siteIndex] ?? sites[0];
|
|
24012
24699
|
sx = startShape.x + site.x;
|
|
@@ -24024,7 +24711,7 @@ function computeConnectorGeometry(connector, startConn, endConn, elementMap) {
|
|
|
24024
24711
|
if (!endShape) {
|
|
24025
24712
|
return null;
|
|
24026
24713
|
}
|
|
24027
|
-
const sites =
|
|
24714
|
+
const sites = getShapeConnectionSites(endShape);
|
|
24028
24715
|
const siteIndex = endConn.connectionSiteIndex ?? 0;
|
|
24029
24716
|
const site = sites[siteIndex] ?? sites[0];
|
|
24030
24717
|
ex = endShape.x + site.x;
|
|
@@ -24034,12 +24721,25 @@ function computeConnectorGeometry(connector, startConn, endConn, elementMap) {
|
|
|
24034
24721
|
ex = connector.x + connector.width;
|
|
24035
24722
|
ey = connector.y + connector.height;
|
|
24036
24723
|
}
|
|
24724
|
+
// Recompute the flip flags from the relative order of the resolved
|
|
24725
|
+
// endpoints. `getConnectorPathGeometry` derives the start/end corners
|
|
24726
|
+
// (and hence line direction / arrowheads) from these flags:
|
|
24727
|
+
// flipH => start at local x=width, end at x=0
|
|
24728
|
+
// flipV => start at local y=height, end at y=0
|
|
24729
|
+
// Since the bounding box is anchored at min(sx,ex)/min(sy,ey), a start that
|
|
24730
|
+
// sits to the right of / below the end must be drawn from the far corner,
|
|
24731
|
+
// i.e. flipH when ex < sx and flipV when ey < sy. Equal coordinates keep the
|
|
24732
|
+
// flag false so a purely vertical / horizontal line is not spuriously flipped.
|
|
24733
|
+
const flipHorizontal = ex < sx;
|
|
24734
|
+
const flipVertical = ey < sy;
|
|
24037
24735
|
return {
|
|
24038
24736
|
id: connector.id,
|
|
24039
24737
|
x: Math.min(sx, ex),
|
|
24040
24738
|
y: Math.min(sy, ey),
|
|
24041
24739
|
width: Math.abs(ex - sx) || 1,
|
|
24042
24740
|
height: Math.abs(ey - sy) || 1,
|
|
24741
|
+
flipHorizontal,
|
|
24742
|
+
flipVertical,
|
|
24043
24743
|
};
|
|
24044
24744
|
}
|
|
24045
24745
|
/**
|
|
@@ -24060,13 +24760,23 @@ function applyReroutedConnectors(elements, rerouted) {
|
|
|
24060
24760
|
if (!update) {
|
|
24061
24761
|
return el;
|
|
24062
24762
|
}
|
|
24063
|
-
|
|
24763
|
+
const next = {
|
|
24064
24764
|
...el,
|
|
24065
24765
|
x: update.x,
|
|
24066
24766
|
y: update.y,
|
|
24067
24767
|
width: update.width,
|
|
24068
24768
|
height: update.height,
|
|
24069
24769
|
};
|
|
24770
|
+
// Only overwrite the flip flags when the reroute recomputed them, so
|
|
24771
|
+
// callers that build ReroutedConnector without flip data (e.g. tests or
|
|
24772
|
+
// non-endpoint updates) leave the connector's existing flags intact.
|
|
24773
|
+
if (update.flipHorizontal !== undefined) {
|
|
24774
|
+
next.flipHorizontal = update.flipHorizontal;
|
|
24775
|
+
}
|
|
24776
|
+
if (update.flipVertical !== undefined) {
|
|
24777
|
+
next.flipVertical = update.flipVertical;
|
|
24778
|
+
}
|
|
24779
|
+
return next;
|
|
24070
24780
|
});
|
|
24071
24781
|
}
|
|
24072
24782
|
|
|
@@ -27882,6 +28592,322 @@ const DEFAULT_TRANSITION_DURATION_MS$1 = 1000;
|
|
|
27882
28592
|
/** Easing applied to every transition animation. */
|
|
27883
28593
|
const EASE = 'ease-in-out';
|
|
27884
28594
|
|
|
28595
|
+
/**
|
|
28596
|
+
* `p14-transition-keyframes` — CSS `@keyframes` for the 18 additional Office
|
|
28597
|
+
* 2010 (`p14` namespace) slide transitions, complementing the core
|
|
28598
|
+
* `slide-transition-keyframes`. All names share the `pptx-tr-*` prefix.
|
|
28599
|
+
*
|
|
28600
|
+
* Split into two string blocks purely to keep individual definitions grouped;
|
|
28601
|
+
* {@link P14_TRANSITION_KEYFRAMES_ALL} concatenates both for one-shot injection,
|
|
28602
|
+
* while {@link P14_TRANSITION_KEYFRAMES} / {@link P14_TRANSITION_KEYFRAMES_2}
|
|
28603
|
+
* preserve the React binding's original two-part public surface.
|
|
28604
|
+
*
|
|
28605
|
+
* @module render/p14-transition-keyframes
|
|
28606
|
+
*/
|
|
28607
|
+
/** Part 1: conveyor / doors / ferris / flash / flythrough / gallery / glitter / honeycomb / pan. */
|
|
28608
|
+
const P14_TRANSITION_KEYFRAMES = `
|
|
28609
|
+
/* ── Conveyor (translate X with staggered timing) ──────────────────── */
|
|
28610
|
+
@keyframes pptx-tr-conveyor-in-from-right {
|
|
28611
|
+
from { transform: translateX(100%) rotateY(-30deg); }
|
|
28612
|
+
60% { transform: translateX(20%) rotateY(-10deg); }
|
|
28613
|
+
to { transform: translateX(0) rotateY(0deg); }
|
|
28614
|
+
}
|
|
28615
|
+
@keyframes pptx-tr-conveyor-out-to-left {
|
|
28616
|
+
from { transform: translateX(0) rotateY(0deg); }
|
|
28617
|
+
40% { transform: translateX(-20%) rotateY(10deg); }
|
|
28618
|
+
to { transform: translateX(-100%) rotateY(30deg); }
|
|
28619
|
+
}
|
|
28620
|
+
@keyframes pptx-tr-conveyor-in-from-left {
|
|
28621
|
+
from { transform: translateX(-100%) rotateY(30deg); }
|
|
28622
|
+
60% { transform: translateX(-20%) rotateY(10deg); }
|
|
28623
|
+
to { transform: translateX(0) rotateY(0deg); }
|
|
28624
|
+
}
|
|
28625
|
+
@keyframes pptx-tr-conveyor-out-to-right {
|
|
28626
|
+
from { transform: translateX(0) rotateY(0deg); }
|
|
28627
|
+
40% { transform: translateX(20%) rotateY(-10deg); }
|
|
28628
|
+
to { transform: translateX(100%) rotateY(-30deg); }
|
|
28629
|
+
}
|
|
28630
|
+
|
|
28631
|
+
/* ── Doors (clip-path from center split) ──────────────────────────── */
|
|
28632
|
+
@keyframes pptx-tr-doors-horz {
|
|
28633
|
+
from { clip-path: inset(0 50%); }
|
|
28634
|
+
to { clip-path: inset(0 0); }
|
|
28635
|
+
}
|
|
28636
|
+
@keyframes pptx-tr-doors-vert {
|
|
28637
|
+
from { clip-path: inset(50% 0); }
|
|
28638
|
+
to { clip-path: inset(0 0); }
|
|
28639
|
+
}
|
|
28640
|
+
|
|
28641
|
+
/* ── Ferris (rotate elements around center) ───────────────────────── */
|
|
28642
|
+
@keyframes pptx-tr-ferris-in-from-right {
|
|
28643
|
+
from { transform: translateX(80%) rotate(45deg) scale(0.6); opacity: 0; }
|
|
28644
|
+
to { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
|
|
28645
|
+
}
|
|
28646
|
+
@keyframes pptx-tr-ferris-out-to-left {
|
|
28647
|
+
from { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
|
|
28648
|
+
to { transform: translateX(-80%) rotate(-45deg) scale(0.6); opacity: 0; }
|
|
28649
|
+
}
|
|
28650
|
+
@keyframes pptx-tr-ferris-in-from-left {
|
|
28651
|
+
from { transform: translateX(-80%) rotate(-45deg) scale(0.6); opacity: 0; }
|
|
28652
|
+
to { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
|
|
28653
|
+
}
|
|
28654
|
+
@keyframes pptx-tr-ferris-out-to-right {
|
|
28655
|
+
from { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
|
|
28656
|
+
to { transform: translateX(80%) rotate(45deg) scale(0.6); opacity: 0; }
|
|
28657
|
+
}
|
|
28658
|
+
|
|
28659
|
+
/* ── Flash (bright flash opacity burst) ──────────────────────────── */
|
|
28660
|
+
@keyframes pptx-tr-flash-white {
|
|
28661
|
+
0% { opacity: 1; }
|
|
28662
|
+
30% { opacity: 0; }
|
|
28663
|
+
50% { opacity: 0; }
|
|
28664
|
+
100% { opacity: 1; }
|
|
28665
|
+
}
|
|
28666
|
+
@keyframes pptx-tr-flash-in {
|
|
28667
|
+
0% { opacity: 0; }
|
|
28668
|
+
50% { opacity: 0; }
|
|
28669
|
+
70% { opacity: 1; }
|
|
28670
|
+
100% { opacity: 1; }
|
|
28671
|
+
}
|
|
28672
|
+
|
|
28673
|
+
/* ── Flythrough (scale + translate Z-axis feel) ──────────────────── */
|
|
28674
|
+
@keyframes pptx-tr-flythrough-in {
|
|
28675
|
+
from { transform: scale(4) translateZ(200px); opacity: 0; filter: blur(8px); }
|
|
28676
|
+
to { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
|
|
28677
|
+
}
|
|
28678
|
+
@keyframes pptx-tr-flythrough-out {
|
|
28679
|
+
from { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
|
|
28680
|
+
to { transform: scale(0.1) translateZ(-200px); opacity: 0; filter: blur(8px); }
|
|
28681
|
+
}
|
|
28682
|
+
@keyframes pptx-tr-flythrough-reverse-in {
|
|
28683
|
+
from { transform: scale(0.1) translateZ(-200px); opacity: 0; filter: blur(8px); }
|
|
28684
|
+
to { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
|
|
28685
|
+
}
|
|
28686
|
+
@keyframes pptx-tr-flythrough-reverse-out {
|
|
28687
|
+
from { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
|
|
28688
|
+
to { transform: scale(4) translateZ(200px); opacity: 0; filter: blur(8px); }
|
|
28689
|
+
}
|
|
28690
|
+
|
|
28691
|
+
/* ── Gallery (translate with perspective) ─────────────────────────── */
|
|
28692
|
+
@keyframes pptx-tr-gallery-in-from-right {
|
|
28693
|
+
from { transform: perspective(800px) translateX(100%) rotateY(-45deg); opacity: 0.5; }
|
|
28694
|
+
to { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
|
|
28695
|
+
}
|
|
28696
|
+
@keyframes pptx-tr-gallery-out-to-left {
|
|
28697
|
+
from { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
|
|
28698
|
+
to { transform: perspective(800px) translateX(-100%) rotateY(45deg); opacity: 0.5; }
|
|
28699
|
+
}
|
|
28700
|
+
@keyframes pptx-tr-gallery-in-from-left {
|
|
28701
|
+
from { transform: perspective(800px) translateX(-100%) rotateY(45deg); opacity: 0.5; }
|
|
28702
|
+
to { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
|
|
28703
|
+
}
|
|
28704
|
+
@keyframes pptx-tr-gallery-out-to-right {
|
|
28705
|
+
from { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
|
|
28706
|
+
to { transform: perspective(800px) translateX(100%) rotateY(-45deg); opacity: 0.5; }
|
|
28707
|
+
}
|
|
28708
|
+
|
|
28709
|
+
/* ── Glitter (particle dissolve effect) ──────────────────────────── */
|
|
28710
|
+
@keyframes pptx-tr-glitter-in {
|
|
28711
|
+
from { opacity: 0; filter: brightness(1.5) contrast(1.3) blur(2px); }
|
|
28712
|
+
60% { opacity: 0.7; filter: brightness(1.2) contrast(1.1) blur(1px); }
|
|
28713
|
+
to { opacity: 1; filter: brightness(1) contrast(1) blur(0); }
|
|
28714
|
+
}
|
|
28715
|
+
|
|
28716
|
+
/* ── Honeycomb (hexagonal reveal) ────────────────────────────────── */
|
|
28717
|
+
@keyframes pptx-tr-honeycomb-in {
|
|
28718
|
+
from {
|
|
28719
|
+
clip-path: polygon(50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%);
|
|
28720
|
+
opacity: 0;
|
|
28721
|
+
}
|
|
28722
|
+
to {
|
|
28723
|
+
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
|
|
28724
|
+
opacity: 1;
|
|
28725
|
+
}
|
|
28726
|
+
}
|
|
28727
|
+
@keyframes pptx-tr-honeycomb-out {
|
|
28728
|
+
from { opacity: 1; }
|
|
28729
|
+
to { opacity: 0; filter: blur(2px); }
|
|
28730
|
+
}
|
|
28731
|
+
|
|
28732
|
+
/* ── Pan (large-scale translate) ─────────────────────────────────── */
|
|
28733
|
+
@keyframes pptx-tr-pan-from-right {
|
|
28734
|
+
from { transform: translateX(100%); }
|
|
28735
|
+
to { transform: translateX(0); }
|
|
28736
|
+
}
|
|
28737
|
+
@keyframes pptx-tr-pan-to-left {
|
|
28738
|
+
from { transform: translateX(0); }
|
|
28739
|
+
to { transform: translateX(-100%); }
|
|
28740
|
+
}
|
|
28741
|
+
@keyframes pptx-tr-pan-from-left {
|
|
28742
|
+
from { transform: translateX(-100%); }
|
|
28743
|
+
to { transform: translateX(0); }
|
|
28744
|
+
}
|
|
28745
|
+
@keyframes pptx-tr-pan-to-right {
|
|
28746
|
+
from { transform: translateX(0); }
|
|
28747
|
+
to { transform: translateX(100%); }
|
|
28748
|
+
}
|
|
28749
|
+
@keyframes pptx-tr-pan-from-bottom {
|
|
28750
|
+
from { transform: translateY(100%); }
|
|
28751
|
+
to { transform: translateY(0); }
|
|
28752
|
+
}
|
|
28753
|
+
@keyframes pptx-tr-pan-to-top {
|
|
28754
|
+
from { transform: translateY(0); }
|
|
28755
|
+
to { transform: translateY(-100%); }
|
|
28756
|
+
}
|
|
28757
|
+
@keyframes pptx-tr-pan-from-top {
|
|
28758
|
+
from { transform: translateY(-100%); }
|
|
28759
|
+
to { transform: translateY(0); }
|
|
28760
|
+
}
|
|
28761
|
+
@keyframes pptx-tr-pan-to-bottom {
|
|
28762
|
+
from { transform: translateY(0); }
|
|
28763
|
+
to { transform: translateY(100%); }
|
|
28764
|
+
}
|
|
28765
|
+
`;
|
|
28766
|
+
/** Part 2: prism / reveal / ripple / shred / switch / vortex / warp / wheelReverse / window. */
|
|
28767
|
+
const P14_TRANSITION_KEYFRAMES_2 = `
|
|
28768
|
+
/* ── Prism (3D rotation via perspective transform) ───────────────── */
|
|
28769
|
+
@keyframes pptx-tr-prism-in-from-right {
|
|
28770
|
+
from { transform: perspective(800px) rotateY(-90deg) translateX(50%); opacity: 0; }
|
|
28771
|
+
to { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
|
|
28772
|
+
}
|
|
28773
|
+
@keyframes pptx-tr-prism-out-to-left {
|
|
28774
|
+
from { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
|
|
28775
|
+
to { transform: perspective(800px) rotateY(90deg) translateX(-50%); opacity: 0; }
|
|
28776
|
+
}
|
|
28777
|
+
@keyframes pptx-tr-prism-in-from-left {
|
|
28778
|
+
from { transform: perspective(800px) rotateY(90deg) translateX(-50%); opacity: 0; }
|
|
28779
|
+
to { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
|
|
28780
|
+
}
|
|
28781
|
+
@keyframes pptx-tr-prism-out-to-right {
|
|
28782
|
+
from { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
|
|
28783
|
+
to { transform: perspective(800px) rotateY(-90deg) translateX(50%); opacity: 0; }
|
|
28784
|
+
}
|
|
28785
|
+
@keyframes pptx-tr-prism-in-from-bottom {
|
|
28786
|
+
from { transform: perspective(800px) rotateX(90deg) translateY(50%); opacity: 0; }
|
|
28787
|
+
to { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
|
|
28788
|
+
}
|
|
28789
|
+
@keyframes pptx-tr-prism-out-to-top {
|
|
28790
|
+
from { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
|
|
28791
|
+
to { transform: perspective(800px) rotateX(-90deg) translateY(-50%); opacity: 0; }
|
|
28792
|
+
}
|
|
28793
|
+
@keyframes pptx-tr-prism-in-from-top {
|
|
28794
|
+
from { transform: perspective(800px) rotateX(-90deg) translateY(-50%); opacity: 0; }
|
|
28795
|
+
to { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
|
|
28796
|
+
}
|
|
28797
|
+
@keyframes pptx-tr-prism-out-to-bottom {
|
|
28798
|
+
from { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
|
|
28799
|
+
to { transform: perspective(800px) rotateX(90deg) translateY(50%); opacity: 0; }
|
|
28800
|
+
}
|
|
28801
|
+
|
|
28802
|
+
/* ── Reveal (slide away reveal) ──────────────────────────────────── */
|
|
28803
|
+
@keyframes pptx-tr-reveal-out-to-right {
|
|
28804
|
+
from { transform: translateX(0); }
|
|
28805
|
+
to { transform: translateX(100%); }
|
|
28806
|
+
}
|
|
28807
|
+
@keyframes pptx-tr-reveal-out-to-left {
|
|
28808
|
+
from { transform: translateX(0); }
|
|
28809
|
+
to { transform: translateX(-100%); }
|
|
28810
|
+
}
|
|
28811
|
+
@keyframes pptx-tr-reveal-in {
|
|
28812
|
+
from { opacity: 0.5; }
|
|
28813
|
+
to { opacity: 1; }
|
|
28814
|
+
}
|
|
28815
|
+
|
|
28816
|
+
/* ── Ripple (expanding ring clip-path) ───────────────────────────── */
|
|
28817
|
+
@keyframes pptx-tr-ripple-in {
|
|
28818
|
+
from { clip-path: circle(0% at 50% 50%); opacity: 0.5; }
|
|
28819
|
+
30% { clip-path: circle(20% at 50% 50%); opacity: 0.7; }
|
|
28820
|
+
60% { clip-path: circle(50% at 50% 50%); opacity: 0.9; }
|
|
28821
|
+
to { clip-path: circle(75% at 50% 50%); opacity: 1; }
|
|
28822
|
+
}
|
|
28823
|
+
|
|
28824
|
+
/* ── Shred (fragmented clip-path pieces) ─────────────────────────── */
|
|
28825
|
+
@keyframes pptx-tr-shred-strips-in {
|
|
28826
|
+
from { clip-path: inset(0 100% 0 0); opacity: 0; }
|
|
28827
|
+
30% { clip-path: inset(0 60% 0 0); opacity: 0.5; }
|
|
28828
|
+
to { clip-path: inset(0); opacity: 1; }
|
|
28829
|
+
}
|
|
28830
|
+
@keyframes pptx-tr-shred-rectangles-in {
|
|
28831
|
+
from { clip-path: inset(50%); opacity: 0; }
|
|
28832
|
+
40% { clip-path: inset(20%); opacity: 0.6; }
|
|
28833
|
+
to { clip-path: inset(0); opacity: 1; }
|
|
28834
|
+
}
|
|
28835
|
+
@keyframes pptx-tr-shred-out {
|
|
28836
|
+
from { opacity: 1; }
|
|
28837
|
+
to { opacity: 0; filter: blur(2px); }
|
|
28838
|
+
}
|
|
28839
|
+
|
|
28840
|
+
/* ── Switch (flip/rotate swap) ───────────────────────────────────── */
|
|
28841
|
+
@keyframes pptx-tr-switch-in-from-right {
|
|
28842
|
+
from { transform: perspective(800px) rotateY(-180deg); opacity: 0; }
|
|
28843
|
+
to { transform: perspective(800px) rotateY(0deg); opacity: 1; }
|
|
28844
|
+
}
|
|
28845
|
+
@keyframes pptx-tr-switch-out-to-left {
|
|
28846
|
+
from { transform: perspective(800px) rotateY(0deg); opacity: 1; }
|
|
28847
|
+
to { transform: perspective(800px) rotateY(180deg); opacity: 0; }
|
|
28848
|
+
}
|
|
28849
|
+
@keyframes pptx-tr-switch-in-from-left {
|
|
28850
|
+
from { transform: perspective(800px) rotateY(180deg); opacity: 0; }
|
|
28851
|
+
to { transform: perspective(800px) rotateY(0deg); opacity: 1; }
|
|
28852
|
+
}
|
|
28853
|
+
@keyframes pptx-tr-switch-out-to-right {
|
|
28854
|
+
from { transform: perspective(800px) rotateY(0deg); opacity: 1; }
|
|
28855
|
+
to { transform: perspective(800px) rotateY(-180deg); opacity: 0; }
|
|
28856
|
+
}
|
|
28857
|
+
|
|
28858
|
+
/* ── Vortex (rotate + scale spiral) ──────────────────────────────── */
|
|
28859
|
+
@keyframes pptx-tr-vortex-in {
|
|
28860
|
+
from { transform: rotate(720deg) scale(0); opacity: 0; }
|
|
28861
|
+
to { transform: rotate(0deg) scale(1); opacity: 1; }
|
|
28862
|
+
}
|
|
28863
|
+
@keyframes pptx-tr-vortex-out {
|
|
28864
|
+
from { transform: rotate(0deg) scale(1); opacity: 1; }
|
|
28865
|
+
to { transform: rotate(-720deg) scale(0); opacity: 0; }
|
|
28866
|
+
}
|
|
28867
|
+
|
|
28868
|
+
/* ── Warp (skew distortion) ──────────────────────────────────────── */
|
|
28869
|
+
@keyframes pptx-tr-warp-in {
|
|
28870
|
+
from { transform: scale(0.3) skewX(30deg) skewY(15deg); opacity: 0; }
|
|
28871
|
+
50% { transform: scale(0.8) skewX(-5deg) skewY(-3deg); opacity: 0.7; }
|
|
28872
|
+
to { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; }
|
|
28873
|
+
}
|
|
28874
|
+
@keyframes pptx-tr-warp-out {
|
|
28875
|
+
from { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; }
|
|
28876
|
+
50% { transform: scale(0.8) skewX(5deg) skewY(3deg); opacity: 0.7; }
|
|
28877
|
+
to { transform: scale(0.3) skewX(-30deg) skewY(-15deg); opacity: 0; }
|
|
28878
|
+
}
|
|
28879
|
+
@keyframes pptx-tr-warp-reverse-in {
|
|
28880
|
+
from { transform: scale(3) skewX(-20deg) skewY(-10deg); opacity: 0; filter: blur(4px); }
|
|
28881
|
+
to { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; filter: blur(0); }
|
|
28882
|
+
}
|
|
28883
|
+
@keyframes pptx-tr-warp-reverse-out {
|
|
28884
|
+
from { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; filter: blur(0); }
|
|
28885
|
+
to { transform: scale(3) skewX(20deg) skewY(10deg); opacity: 0; filter: blur(4px); }
|
|
28886
|
+
}
|
|
28887
|
+
|
|
28888
|
+
/* ── WheelReverse (reverse wheel rotation) ───────────────────────── */
|
|
28889
|
+
@keyframes pptx-tr-wheel-reverse-in {
|
|
28890
|
+
from { clip-path: circle(0% at 50% 50%); transform: rotate(180deg); }
|
|
28891
|
+
to { clip-path: circle(75% at 50% 50%); transform: rotate(0deg); }
|
|
28892
|
+
}
|
|
28893
|
+
|
|
28894
|
+
/* ── Window (scale from center with border) ──────────────────────── */
|
|
28895
|
+
@keyframes pptx-tr-window-horz {
|
|
28896
|
+
from { clip-path: inset(0 50%); }
|
|
28897
|
+
to { clip-path: inset(0 0); }
|
|
28898
|
+
}
|
|
28899
|
+
@keyframes pptx-tr-window-vert {
|
|
28900
|
+
from { clip-path: inset(50% 0); }
|
|
28901
|
+
to { clip-path: inset(0 0); }
|
|
28902
|
+
}
|
|
28903
|
+
@keyframes pptx-tr-window-out {
|
|
28904
|
+
from { opacity: 1; transform: scale(1); }
|
|
28905
|
+
to { opacity: 0; transform: scale(0.9); }
|
|
28906
|
+
}
|
|
28907
|
+
`;
|
|
28908
|
+
/** Both p14 keyframe blocks concatenated, for single `<style>` injection. */
|
|
28909
|
+
const P14_TRANSITION_KEYFRAMES_ALL = `${P14_TRANSITION_KEYFRAMES}\n${P14_TRANSITION_KEYFRAMES_2}`;
|
|
28910
|
+
|
|
27885
28911
|
/**
|
|
27886
28912
|
* `slide-transition-keyframes` — the full `@keyframes` block backing every
|
|
27887
28913
|
* resolved slide transition. Inject it once per overlay via a `<style>` element
|
|
@@ -27896,9 +28922,14 @@ const EASE = 'ease-in-out';
|
|
|
27896
28922
|
* same string — the bindings historically exported it under both names, so the
|
|
27897
28923
|
* alias preserves their public surface.
|
|
27898
28924
|
*
|
|
28925
|
+
* The faithful Office 2010 (`p14`) keyframes are appended (via
|
|
28926
|
+
* {@link P14_TRANSITION_KEYFRAMES_ALL}) so the exotic / 3-D transitions routed
|
|
28927
|
+
* through `getP14TransitionAnimations` animate wherever this block is injected,
|
|
28928
|
+
* with no per-binding wiring.
|
|
28929
|
+
*
|
|
27899
28930
|
* @module render/slide-transition-keyframes
|
|
27900
28931
|
*/
|
|
27901
|
-
const
|
|
28932
|
+
const CORE_SLIDE_TRANSITION_KEYFRAMES = `
|
|
27902
28933
|
/* ── Fade ───────────────────────────────────────────────────────────── */
|
|
27903
28934
|
@keyframes pptx-tr-fade-in {
|
|
27904
28935
|
from { opacity: 0; }
|
|
@@ -28161,641 +29192,18 @@ const SLIDE_TRANSITION_KEYFRAMES = `
|
|
|
28161
29192
|
to { clip-path: circle(75% at 50% 50%); transform: rotate(0deg); }
|
|
28162
29193
|
}
|
|
28163
29194
|
`;
|
|
29195
|
+
/**
|
|
29196
|
+
* The full slide-transition `@keyframes` block: the classic set plus the
|
|
29197
|
+
* faithful Office 2010 (`p14`) keyframes, so both the classic and exotic / 3-D
|
|
29198
|
+
* transitions animate wherever this single string is injected.
|
|
29199
|
+
*/
|
|
29200
|
+
const SLIDE_TRANSITION_KEYFRAMES = `${CORE_SLIDE_TRANSITION_KEYFRAMES}\n${P14_TRANSITION_KEYFRAMES_ALL}`;
|
|
28164
29201
|
/**
|
|
28165
29202
|
* Alias of {@link SLIDE_TRANSITION_KEYFRAMES} under the `_CSS` name the Vue
|
|
28166
29203
|
* binding historically exported.
|
|
28167
29204
|
*/
|
|
28168
29205
|
const SLIDE_TRANSITION_KEYFRAMES_CSS = SLIDE_TRANSITION_KEYFRAMES;
|
|
28169
29206
|
|
|
28170
|
-
/**
|
|
28171
|
-
* `slide-transition-css` — pure mapping from a {@link PptxSlideTransition}
|
|
28172
|
-
* (type + duration + direction/orientation) to the CSS `animation` shorthand
|
|
28173
|
-
* pieces used by each binding's presentation-mode transition overlay during a
|
|
28174
|
-
* slide change.
|
|
28175
|
-
*
|
|
28176
|
-
* Consolidates the React `transition-resolver` / `transition-helpers` /
|
|
28177
|
-
* `transition-keyframes` trio, the Vue `slide-transition-css`, and the Angular
|
|
28178
|
-
* `transition-helpers` into one framework-agnostic module:
|
|
28179
|
-
*
|
|
28180
|
-
* - {@link getSlideTransitionAnimations} resolves a transition to the
|
|
28181
|
-
* `animation` shorthand strings for the outgoing (old) and incoming (new)
|
|
28182
|
-
* slide layers, plus whether the outgoing layer sits on top.
|
|
28183
|
-
* - the `@keyframes` referenced live in `slide-transition-keyframes`
|
|
28184
|
-
* (`SLIDE_TRANSITION_KEYFRAMES`), injected once via a `<style>` element.
|
|
28185
|
-
*
|
|
28186
|
-
* Superset note: the exotic / 3-D transition family (`pan`/`gallery`/
|
|
28187
|
-
* `conveyor`/`reveal`/`doors`/`switch`/`flythrough`/`ferris`/`prism`/`ripple`/
|
|
28188
|
-
* `honeycomb`/`glitter`/`shred`/`flash`) is approximated with the closest
|
|
28189
|
-
* well-tested 2-D case (originally an Angular-only refinement) rather than a
|
|
28190
|
-
* plain fade. Truly-unknown types still fall back to a symmetrical cross-fade.
|
|
28191
|
-
* A more faithful per-effect p14 keyframe set is available separately via
|
|
28192
|
-
* `p14-transition-keyframes` + {@link getP14TransitionAnimations}.
|
|
28193
|
-
*
|
|
28194
|
-
* Everything here is pure and unit-testable: no framework imports, no DOM.
|
|
28195
|
-
*
|
|
28196
|
-
* @module render/slide-transition-css
|
|
28197
|
-
*/
|
|
28198
|
-
/**
|
|
28199
|
-
* Map a {@link PptxTransitionType} (+ duration/direction/orient/spokes) to the
|
|
28200
|
-
* concrete CSS `animation` descriptors for the outgoing and incoming layers.
|
|
28201
|
-
*
|
|
28202
|
-
* Unknown types fall back to a symmetrical cross-fade.
|
|
28203
|
-
*/
|
|
28204
|
-
function getSlideTransitionAnimations(type, durationMs, direction, orient, spokes) {
|
|
28205
|
-
const dur = `${durationMs}ms`;
|
|
28206
|
-
// `spokes` is reserved for future wheel spoke-count support; forwarded only
|
|
28207
|
-
// through recursive calls (random/pull/exotic aliases).
|
|
28208
|
-
void spokes;
|
|
28209
|
-
switch (type) {
|
|
28210
|
-
case 'none':
|
|
28211
|
-
case 'cut':
|
|
28212
|
-
return INSTANT;
|
|
28213
|
-
case 'fade':
|
|
28214
|
-
return {
|
|
28215
|
-
outgoing: `pptx-tr-fade-out ${dur} ${EASE} forwards`,
|
|
28216
|
-
incoming: `pptx-tr-fade-in ${dur} ${EASE} forwards`,
|
|
28217
|
-
outgoingOnTop: true,
|
|
28218
|
-
};
|
|
28219
|
-
case 'push': {
|
|
28220
|
-
const dir = resolveDirection(direction, 'left');
|
|
28221
|
-
const configs = {
|
|
28222
|
-
left: {
|
|
28223
|
-
outgoing: `pptx-tr-push-out-to-left ${dur} ${EASE} forwards`,
|
|
28224
|
-
incoming: `pptx-tr-push-in-from-right ${dur} ${EASE} forwards`,
|
|
28225
|
-
outgoingOnTop: false,
|
|
28226
|
-
},
|
|
28227
|
-
right: {
|
|
28228
|
-
outgoing: `pptx-tr-push-out-to-right ${dur} ${EASE} forwards`,
|
|
28229
|
-
incoming: `pptx-tr-push-in-from-left ${dur} ${EASE} forwards`,
|
|
28230
|
-
outgoingOnTop: false,
|
|
28231
|
-
},
|
|
28232
|
-
up: {
|
|
28233
|
-
outgoing: `pptx-tr-push-out-to-top ${dur} ${EASE} forwards`,
|
|
28234
|
-
incoming: `pptx-tr-push-in-from-bottom ${dur} ${EASE} forwards`,
|
|
28235
|
-
outgoingOnTop: false,
|
|
28236
|
-
},
|
|
28237
|
-
down: {
|
|
28238
|
-
outgoing: `pptx-tr-push-out-to-bottom ${dur} ${EASE} forwards`,
|
|
28239
|
-
incoming: `pptx-tr-push-in-from-top ${dur} ${EASE} forwards`,
|
|
28240
|
-
outgoingOnTop: false,
|
|
28241
|
-
},
|
|
28242
|
-
};
|
|
28243
|
-
return configs[dir];
|
|
28244
|
-
}
|
|
28245
|
-
case 'wipe': {
|
|
28246
|
-
const dir = resolveDirection(direction, 'left');
|
|
28247
|
-
const wipeNames = {
|
|
28248
|
-
left: `pptx-tr-wipe-from-left ${dur} ${EASE} forwards`,
|
|
28249
|
-
right: `pptx-tr-wipe-from-right ${dur} ${EASE} forwards`,
|
|
28250
|
-
up: `pptx-tr-wipe-from-top ${dur} ${EASE} forwards`,
|
|
28251
|
-
down: `pptx-tr-wipe-from-bottom ${dur} ${EASE} forwards`,
|
|
28252
|
-
};
|
|
28253
|
-
return {
|
|
28254
|
-
outgoing: 'none',
|
|
28255
|
-
incoming: wipeNames[dir],
|
|
28256
|
-
outgoingOnTop: false,
|
|
28257
|
-
};
|
|
28258
|
-
}
|
|
28259
|
-
case 'cover': {
|
|
28260
|
-
const dir = resolveDirection8(direction, 'left');
|
|
28261
|
-
const coverMap = {
|
|
28262
|
-
left: `pptx-tr-cover-from-left ${dur} ${EASE} forwards`,
|
|
28263
|
-
right: `pptx-tr-cover-from-right ${dur} ${EASE} forwards`,
|
|
28264
|
-
up: `pptx-tr-cover-from-top ${dur} ${EASE} forwards`,
|
|
28265
|
-
down: `pptx-tr-cover-from-bottom ${dur} ${EASE} forwards`,
|
|
28266
|
-
lu: `pptx-tr-cover-from-lu ${dur} ${EASE} forwards`,
|
|
28267
|
-
ld: `pptx-tr-cover-from-ld ${dur} ${EASE} forwards`,
|
|
28268
|
-
ru: `pptx-tr-cover-from-ru ${dur} ${EASE} forwards`,
|
|
28269
|
-
rd: `pptx-tr-cover-from-rd ${dur} ${EASE} forwards`,
|
|
28270
|
-
};
|
|
28271
|
-
return {
|
|
28272
|
-
outgoing: 'none',
|
|
28273
|
-
incoming: coverMap[dir],
|
|
28274
|
-
outgoingOnTop: false,
|
|
28275
|
-
};
|
|
28276
|
-
}
|
|
28277
|
-
case 'uncover': {
|
|
28278
|
-
const dir = resolveDirection8(direction, 'left');
|
|
28279
|
-
const uncoverMap = {
|
|
28280
|
-
left: `pptx-tr-uncover-to-left ${dur} ${EASE} forwards`,
|
|
28281
|
-
right: `pptx-tr-uncover-to-right ${dur} ${EASE} forwards`,
|
|
28282
|
-
up: `pptx-tr-uncover-to-top ${dur} ${EASE} forwards`,
|
|
28283
|
-
down: `pptx-tr-uncover-to-bottom ${dur} ${EASE} forwards`,
|
|
28284
|
-
lu: `pptx-tr-uncover-to-lu ${dur} ${EASE} forwards`,
|
|
28285
|
-
ld: `pptx-tr-uncover-to-ld ${dur} ${EASE} forwards`,
|
|
28286
|
-
ru: `pptx-tr-uncover-to-ru ${dur} ${EASE} forwards`,
|
|
28287
|
-
rd: `pptx-tr-uncover-to-rd ${dur} ${EASE} forwards`,
|
|
28288
|
-
};
|
|
28289
|
-
return {
|
|
28290
|
-
outgoing: uncoverMap[dir],
|
|
28291
|
-
incoming: 'none',
|
|
28292
|
-
outgoingOnTop: true,
|
|
28293
|
-
};
|
|
28294
|
-
}
|
|
28295
|
-
case 'split': {
|
|
28296
|
-
const o = resolveOrientation(undefined, orient);
|
|
28297
|
-
const isOut = direction !== 'in';
|
|
28298
|
-
if (isOut) {
|
|
28299
|
-
return {
|
|
28300
|
-
outgoing: 'none',
|
|
28301
|
-
incoming: o === 'vert'
|
|
28302
|
-
? `pptx-tr-split-v-out ${dur} ${EASE} forwards`
|
|
28303
|
-
: `pptx-tr-split-h-out ${dur} ${EASE} forwards`,
|
|
28304
|
-
outgoingOnTop: false,
|
|
28305
|
-
};
|
|
28306
|
-
}
|
|
28307
|
-
return {
|
|
28308
|
-
outgoing: o === 'vert'
|
|
28309
|
-
? `pptx-tr-split-v-in ${dur} ${EASE} forwards`
|
|
28310
|
-
: `pptx-tr-split-h-in ${dur} ${EASE} forwards`,
|
|
28311
|
-
incoming: 'none',
|
|
28312
|
-
outgoingOnTop: true,
|
|
28313
|
-
};
|
|
28314
|
-
}
|
|
28315
|
-
case 'dissolve':
|
|
28316
|
-
return {
|
|
28317
|
-
outgoing: `pptx-tr-fade-out ${dur} ${EASE} forwards`,
|
|
28318
|
-
incoming: `pptx-tr-dissolve-in ${dur} ${EASE} forwards`,
|
|
28319
|
-
outgoingOnTop: true,
|
|
28320
|
-
};
|
|
28321
|
-
case 'circle':
|
|
28322
|
-
return {
|
|
28323
|
-
outgoing: 'none',
|
|
28324
|
-
incoming: `pptx-tr-circle-in ${dur} ${EASE} forwards`,
|
|
28325
|
-
outgoingOnTop: false,
|
|
28326
|
-
};
|
|
28327
|
-
case 'diamond':
|
|
28328
|
-
return {
|
|
28329
|
-
outgoing: 'none',
|
|
28330
|
-
incoming: `pptx-tr-diamond-in ${dur} ${EASE} forwards`,
|
|
28331
|
-
outgoingOnTop: false,
|
|
28332
|
-
};
|
|
28333
|
-
case 'plus':
|
|
28334
|
-
return {
|
|
28335
|
-
outgoing: 'none',
|
|
28336
|
-
incoming: `pptx-tr-plus-in ${dur} ${EASE} forwards`,
|
|
28337
|
-
outgoingOnTop: false,
|
|
28338
|
-
};
|
|
28339
|
-
case 'wedge':
|
|
28340
|
-
return {
|
|
28341
|
-
outgoing: 'none',
|
|
28342
|
-
incoming: `pptx-tr-wedge-in ${dur} ${EASE} forwards`,
|
|
28343
|
-
outgoingOnTop: false,
|
|
28344
|
-
};
|
|
28345
|
-
case 'wheel':
|
|
28346
|
-
return {
|
|
28347
|
-
outgoing: 'none',
|
|
28348
|
-
incoming: `pptx-tr-wheel-in ${dur} ${EASE} forwards`,
|
|
28349
|
-
outgoingOnTop: false,
|
|
28350
|
-
};
|
|
28351
|
-
case 'zoom':
|
|
28352
|
-
return {
|
|
28353
|
-
outgoing: `pptx-tr-zoom-out ${dur} ${EASE} forwards`,
|
|
28354
|
-
incoming: `pptx-tr-zoom-in ${dur} ${EASE} forwards`,
|
|
28355
|
-
outgoingOnTop: true,
|
|
28356
|
-
};
|
|
28357
|
-
case 'blinds': {
|
|
28358
|
-
const o = resolveOrientation(direction, orient);
|
|
28359
|
-
return {
|
|
28360
|
-
outgoing: 'none',
|
|
28361
|
-
incoming: o === 'vert'
|
|
28362
|
-
? `pptx-tr-blinds-v ${dur} ${EASE} forwards`
|
|
28363
|
-
: `pptx-tr-blinds-h ${dur} ${EASE} forwards`,
|
|
28364
|
-
outgoingOnTop: false,
|
|
28365
|
-
};
|
|
28366
|
-
}
|
|
28367
|
-
case 'checker':
|
|
28368
|
-
return {
|
|
28369
|
-
outgoing: `pptx-tr-fade-out ${dur} ${EASE} forwards`,
|
|
28370
|
-
incoming: `pptx-tr-checker-in ${dur} ${EASE} forwards`,
|
|
28371
|
-
outgoingOnTop: true,
|
|
28372
|
-
};
|
|
28373
|
-
case 'comb': {
|
|
28374
|
-
const o = resolveOrientation(direction, orient);
|
|
28375
|
-
return {
|
|
28376
|
-
outgoing: 'none',
|
|
28377
|
-
incoming: o === 'vert'
|
|
28378
|
-
? `pptx-tr-comb-v ${dur} ${EASE} forwards`
|
|
28379
|
-
: `pptx-tr-comb-h ${dur} ${EASE} forwards`,
|
|
28380
|
-
outgoingOnTop: false,
|
|
28381
|
-
};
|
|
28382
|
-
}
|
|
28383
|
-
case 'strips': {
|
|
28384
|
-
const stripDir = direction === 'lu' || direction === 'ld' || direction === 'ru' || direction === 'rd'
|
|
28385
|
-
? direction
|
|
28386
|
-
: 'lu';
|
|
28387
|
-
return {
|
|
28388
|
-
outgoing: 'none',
|
|
28389
|
-
incoming: `pptx-tr-strips-${stripDir} ${dur} ${EASE} forwards`,
|
|
28390
|
-
outgoingOnTop: false,
|
|
28391
|
-
};
|
|
28392
|
-
}
|
|
28393
|
-
case 'randomBar': {
|
|
28394
|
-
const o = resolveOrientation(direction, orient);
|
|
28395
|
-
return {
|
|
28396
|
-
outgoing: 'none',
|
|
28397
|
-
incoming: o === 'vert'
|
|
28398
|
-
? `pptx-tr-randombar-v ${dur} ${EASE} forwards`
|
|
28399
|
-
: `pptx-tr-randombar-h ${dur} ${EASE} forwards`,
|
|
28400
|
-
outgoingOnTop: false,
|
|
28401
|
-
};
|
|
28402
|
-
}
|
|
28403
|
-
case 'newsflash':
|
|
28404
|
-
return {
|
|
28405
|
-
outgoing: `pptx-tr-fade-out ${dur} ${EASE} forwards`,
|
|
28406
|
-
incoming: `pptx-tr-newsflash-in ${dur} ${EASE} forwards`,
|
|
28407
|
-
outgoingOnTop: false,
|
|
28408
|
-
};
|
|
28409
|
-
// `pull` is the directional alias of `uncover`.
|
|
28410
|
-
case 'pull':
|
|
28411
|
-
return getSlideTransitionAnimations('uncover', durationMs, direction, orient, spokes);
|
|
28412
|
-
case 'morph':
|
|
28413
|
-
return {
|
|
28414
|
-
outgoing: `pptx-tr-fade-out ${dur} ${EASE} forwards`,
|
|
28415
|
-
incoming: `pptx-tr-fade-in ${dur} ${EASE} forwards`,
|
|
28416
|
-
outgoingOnTop: true,
|
|
28417
|
-
};
|
|
28418
|
-
case 'random': {
|
|
28419
|
-
const randomType = RANDOM_ELIGIBLE_TYPES[Math.floor(Math.random() * RANDOM_ELIGIBLE_TYPES.length)];
|
|
28420
|
-
return getSlideTransitionAnimations(randomType, durationMs, direction, orient, spokes);
|
|
28421
|
-
}
|
|
28422
|
-
// ── Exotic / 3-D transitions — approximated with the closest well-tested
|
|
28423
|
-
// 2-D CSS behaviour (delegates to an existing case rather than emitting a
|
|
28424
|
-
// plain fade). A faithful per-effect keyframe set is available via
|
|
28425
|
-
// `getP14TransitionAnimations`.
|
|
28426
|
-
case 'pan':
|
|
28427
|
-
case 'gallery':
|
|
28428
|
-
case 'conveyor':
|
|
28429
|
-
return getSlideTransitionAnimations('push', durationMs, direction, orient, spokes);
|
|
28430
|
-
case 'reveal':
|
|
28431
|
-
return getSlideTransitionAnimations('wipe', durationMs, direction, orient, spokes);
|
|
28432
|
-
case 'doors':
|
|
28433
|
-
return getSlideTransitionAnimations('split', durationMs, direction, orient, spokes);
|
|
28434
|
-
case 'switch':
|
|
28435
|
-
case 'flythrough':
|
|
28436
|
-
case 'ferris':
|
|
28437
|
-
case 'prism':
|
|
28438
|
-
return getSlideTransitionAnimations('zoom', durationMs, direction, orient, spokes);
|
|
28439
|
-
case 'ripple':
|
|
28440
|
-
case 'honeycomb':
|
|
28441
|
-
case 'glitter':
|
|
28442
|
-
case 'shred':
|
|
28443
|
-
return getSlideTransitionAnimations('dissolve', durationMs, direction, orient, spokes);
|
|
28444
|
-
case 'flash':
|
|
28445
|
-
return getSlideTransitionAnimations('fade', durationMs, direction, orient, spokes);
|
|
28446
|
-
// Fallback (unknown / not-yet-mapped type) — symmetrical cross-fade.
|
|
28447
|
-
default:
|
|
28448
|
-
return {
|
|
28449
|
-
outgoing: `pptx-tr-fade-out ${dur} ${EASE} forwards`,
|
|
28450
|
-
incoming: `pptx-tr-fade-in ${dur} ${EASE} forwards`,
|
|
28451
|
-
outgoingOnTop: true,
|
|
28452
|
-
};
|
|
28453
|
-
}
|
|
28454
|
-
}
|
|
28455
|
-
/**
|
|
28456
|
-
* Convenience wrapper that reads everything off a {@link PptxSlideTransition},
|
|
28457
|
-
* applying the React/Vue default duration when none is set. `none`/`cut` and a
|
|
28458
|
-
* transition with a non-positive duration resolve to {@link INSTANT}.
|
|
28459
|
-
*/
|
|
28460
|
-
function resolveSlideTransition(transition) {
|
|
28461
|
-
if (!transition || transition.type === 'none' || transition.type === 'cut') {
|
|
28462
|
-
return INSTANT;
|
|
28463
|
-
}
|
|
28464
|
-
const durationMs = typeof transition.durationMs === 'number' && transition.durationMs > 0
|
|
28465
|
-
? transition.durationMs
|
|
28466
|
-
: DEFAULT_TRANSITION_DURATION_MS$1;
|
|
28467
|
-
return getSlideTransitionAnimations(transition.type, durationMs, transition.direction, transition.orient, transition.spokes);
|
|
28468
|
-
}
|
|
28469
|
-
/**
|
|
28470
|
-
* The effective duration (ms) for a transition under the React/Vue policy — the
|
|
28471
|
-
* configured `durationMs`, or {@link DEFAULT_TRANSITION_DURATION_MS} when
|
|
28472
|
-
* unset/invalid. `none`/`cut` resolve to `0` (instant).
|
|
28473
|
-
*/
|
|
28474
|
-
function resolveTransitionDurationMs(transition) {
|
|
28475
|
-
if (!transition || transition.type === 'none' || transition.type === 'cut') {
|
|
28476
|
-
return 0;
|
|
28477
|
-
}
|
|
28478
|
-
return typeof transition.durationMs === 'number' && transition.durationMs > 0
|
|
28479
|
-
? transition.durationMs
|
|
28480
|
-
: DEFAULT_TRANSITION_DURATION_MS$1;
|
|
28481
|
-
}
|
|
28482
|
-
|
|
28483
|
-
/**
|
|
28484
|
-
* `p14-transition-keyframes` — CSS `@keyframes` for the 18 additional Office
|
|
28485
|
-
* 2010 (`p14` namespace) slide transitions, complementing the core
|
|
28486
|
-
* `slide-transition-keyframes`. All names share the `pptx-tr-*` prefix.
|
|
28487
|
-
*
|
|
28488
|
-
* Split into two string blocks purely to keep individual definitions grouped;
|
|
28489
|
-
* {@link P14_TRANSITION_KEYFRAMES_ALL} concatenates both for one-shot injection,
|
|
28490
|
-
* while {@link P14_TRANSITION_KEYFRAMES} / {@link P14_TRANSITION_KEYFRAMES_2}
|
|
28491
|
-
* preserve the React binding's original two-part public surface.
|
|
28492
|
-
*
|
|
28493
|
-
* @module render/p14-transition-keyframes
|
|
28494
|
-
*/
|
|
28495
|
-
/** Part 1: conveyor / doors / ferris / flash / flythrough / gallery / glitter / honeycomb / pan. */
|
|
28496
|
-
const P14_TRANSITION_KEYFRAMES = `
|
|
28497
|
-
/* ── Conveyor (translate X with staggered timing) ──────────────────── */
|
|
28498
|
-
@keyframes pptx-tr-conveyor-in-from-right {
|
|
28499
|
-
from { transform: translateX(100%) rotateY(-30deg); }
|
|
28500
|
-
60% { transform: translateX(20%) rotateY(-10deg); }
|
|
28501
|
-
to { transform: translateX(0) rotateY(0deg); }
|
|
28502
|
-
}
|
|
28503
|
-
@keyframes pptx-tr-conveyor-out-to-left {
|
|
28504
|
-
from { transform: translateX(0) rotateY(0deg); }
|
|
28505
|
-
40% { transform: translateX(-20%) rotateY(10deg); }
|
|
28506
|
-
to { transform: translateX(-100%) rotateY(30deg); }
|
|
28507
|
-
}
|
|
28508
|
-
@keyframes pptx-tr-conveyor-in-from-left {
|
|
28509
|
-
from { transform: translateX(-100%) rotateY(30deg); }
|
|
28510
|
-
60% { transform: translateX(-20%) rotateY(10deg); }
|
|
28511
|
-
to { transform: translateX(0) rotateY(0deg); }
|
|
28512
|
-
}
|
|
28513
|
-
@keyframes pptx-tr-conveyor-out-to-right {
|
|
28514
|
-
from { transform: translateX(0) rotateY(0deg); }
|
|
28515
|
-
40% { transform: translateX(20%) rotateY(-10deg); }
|
|
28516
|
-
to { transform: translateX(100%) rotateY(-30deg); }
|
|
28517
|
-
}
|
|
28518
|
-
|
|
28519
|
-
/* ── Doors (clip-path from center split) ──────────────────────────── */
|
|
28520
|
-
@keyframes pptx-tr-doors-horz {
|
|
28521
|
-
from { clip-path: inset(0 50%); }
|
|
28522
|
-
to { clip-path: inset(0 0); }
|
|
28523
|
-
}
|
|
28524
|
-
@keyframes pptx-tr-doors-vert {
|
|
28525
|
-
from { clip-path: inset(50% 0); }
|
|
28526
|
-
to { clip-path: inset(0 0); }
|
|
28527
|
-
}
|
|
28528
|
-
|
|
28529
|
-
/* ── Ferris (rotate elements around center) ───────────────────────── */
|
|
28530
|
-
@keyframes pptx-tr-ferris-in-from-right {
|
|
28531
|
-
from { transform: translateX(80%) rotate(45deg) scale(0.6); opacity: 0; }
|
|
28532
|
-
to { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
|
|
28533
|
-
}
|
|
28534
|
-
@keyframes pptx-tr-ferris-out-to-left {
|
|
28535
|
-
from { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
|
|
28536
|
-
to { transform: translateX(-80%) rotate(-45deg) scale(0.6); opacity: 0; }
|
|
28537
|
-
}
|
|
28538
|
-
@keyframes pptx-tr-ferris-in-from-left {
|
|
28539
|
-
from { transform: translateX(-80%) rotate(-45deg) scale(0.6); opacity: 0; }
|
|
28540
|
-
to { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
|
|
28541
|
-
}
|
|
28542
|
-
@keyframes pptx-tr-ferris-out-to-right {
|
|
28543
|
-
from { transform: translateX(0) rotate(0deg) scale(1); opacity: 1; }
|
|
28544
|
-
to { transform: translateX(80%) rotate(45deg) scale(0.6); opacity: 0; }
|
|
28545
|
-
}
|
|
28546
|
-
|
|
28547
|
-
/* ── Flash (bright flash opacity burst) ──────────────────────────── */
|
|
28548
|
-
@keyframes pptx-tr-flash-white {
|
|
28549
|
-
0% { opacity: 1; }
|
|
28550
|
-
30% { opacity: 0; }
|
|
28551
|
-
50% { opacity: 0; }
|
|
28552
|
-
100% { opacity: 1; }
|
|
28553
|
-
}
|
|
28554
|
-
@keyframes pptx-tr-flash-in {
|
|
28555
|
-
0% { opacity: 0; }
|
|
28556
|
-
50% { opacity: 0; }
|
|
28557
|
-
70% { opacity: 1; }
|
|
28558
|
-
100% { opacity: 1; }
|
|
28559
|
-
}
|
|
28560
|
-
|
|
28561
|
-
/* ── Flythrough (scale + translate Z-axis feel) ──────────────────── */
|
|
28562
|
-
@keyframes pptx-tr-flythrough-in {
|
|
28563
|
-
from { transform: scale(4) translateZ(200px); opacity: 0; filter: blur(8px); }
|
|
28564
|
-
to { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
|
|
28565
|
-
}
|
|
28566
|
-
@keyframes pptx-tr-flythrough-out {
|
|
28567
|
-
from { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
|
|
28568
|
-
to { transform: scale(0.1) translateZ(-200px); opacity: 0; filter: blur(8px); }
|
|
28569
|
-
}
|
|
28570
|
-
@keyframes pptx-tr-flythrough-reverse-in {
|
|
28571
|
-
from { transform: scale(0.1) translateZ(-200px); opacity: 0; filter: blur(8px); }
|
|
28572
|
-
to { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
|
|
28573
|
-
}
|
|
28574
|
-
@keyframes pptx-tr-flythrough-reverse-out {
|
|
28575
|
-
from { transform: scale(1) translateZ(0); opacity: 1; filter: blur(0); }
|
|
28576
|
-
to { transform: scale(4) translateZ(200px); opacity: 0; filter: blur(8px); }
|
|
28577
|
-
}
|
|
28578
|
-
|
|
28579
|
-
/* ── Gallery (translate with perspective) ─────────────────────────── */
|
|
28580
|
-
@keyframes pptx-tr-gallery-in-from-right {
|
|
28581
|
-
from { transform: perspective(800px) translateX(100%) rotateY(-45deg); opacity: 0.5; }
|
|
28582
|
-
to { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
|
|
28583
|
-
}
|
|
28584
|
-
@keyframes pptx-tr-gallery-out-to-left {
|
|
28585
|
-
from { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
|
|
28586
|
-
to { transform: perspective(800px) translateX(-100%) rotateY(45deg); opacity: 0.5; }
|
|
28587
|
-
}
|
|
28588
|
-
@keyframes pptx-tr-gallery-in-from-left {
|
|
28589
|
-
from { transform: perspective(800px) translateX(-100%) rotateY(45deg); opacity: 0.5; }
|
|
28590
|
-
to { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
|
|
28591
|
-
}
|
|
28592
|
-
@keyframes pptx-tr-gallery-out-to-right {
|
|
28593
|
-
from { transform: perspective(800px) translateX(0) rotateY(0deg); opacity: 1; }
|
|
28594
|
-
to { transform: perspective(800px) translateX(100%) rotateY(-45deg); opacity: 0.5; }
|
|
28595
|
-
}
|
|
28596
|
-
|
|
28597
|
-
/* ── Glitter (particle dissolve effect) ──────────────────────────── */
|
|
28598
|
-
@keyframes pptx-tr-glitter-in {
|
|
28599
|
-
from { opacity: 0; filter: brightness(1.5) contrast(1.3) blur(2px); }
|
|
28600
|
-
60% { opacity: 0.7; filter: brightness(1.2) contrast(1.1) blur(1px); }
|
|
28601
|
-
to { opacity: 1; filter: brightness(1) contrast(1) blur(0); }
|
|
28602
|
-
}
|
|
28603
|
-
|
|
28604
|
-
/* ── Honeycomb (hexagonal reveal) ────────────────────────────────── */
|
|
28605
|
-
@keyframes pptx-tr-honeycomb-in {
|
|
28606
|
-
from {
|
|
28607
|
-
clip-path: polygon(50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%);
|
|
28608
|
-
opacity: 0;
|
|
28609
|
-
}
|
|
28610
|
-
to {
|
|
28611
|
-
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
|
|
28612
|
-
opacity: 1;
|
|
28613
|
-
}
|
|
28614
|
-
}
|
|
28615
|
-
@keyframes pptx-tr-honeycomb-out {
|
|
28616
|
-
from { opacity: 1; }
|
|
28617
|
-
to { opacity: 0; filter: blur(2px); }
|
|
28618
|
-
}
|
|
28619
|
-
|
|
28620
|
-
/* ── Pan (large-scale translate) ─────────────────────────────────── */
|
|
28621
|
-
@keyframes pptx-tr-pan-from-right {
|
|
28622
|
-
from { transform: translateX(100%); }
|
|
28623
|
-
to { transform: translateX(0); }
|
|
28624
|
-
}
|
|
28625
|
-
@keyframes pptx-tr-pan-to-left {
|
|
28626
|
-
from { transform: translateX(0); }
|
|
28627
|
-
to { transform: translateX(-100%); }
|
|
28628
|
-
}
|
|
28629
|
-
@keyframes pptx-tr-pan-from-left {
|
|
28630
|
-
from { transform: translateX(-100%); }
|
|
28631
|
-
to { transform: translateX(0); }
|
|
28632
|
-
}
|
|
28633
|
-
@keyframes pptx-tr-pan-to-right {
|
|
28634
|
-
from { transform: translateX(0); }
|
|
28635
|
-
to { transform: translateX(100%); }
|
|
28636
|
-
}
|
|
28637
|
-
@keyframes pptx-tr-pan-from-bottom {
|
|
28638
|
-
from { transform: translateY(100%); }
|
|
28639
|
-
to { transform: translateY(0); }
|
|
28640
|
-
}
|
|
28641
|
-
@keyframes pptx-tr-pan-to-top {
|
|
28642
|
-
from { transform: translateY(0); }
|
|
28643
|
-
to { transform: translateY(-100%); }
|
|
28644
|
-
}
|
|
28645
|
-
@keyframes pptx-tr-pan-from-top {
|
|
28646
|
-
from { transform: translateY(-100%); }
|
|
28647
|
-
to { transform: translateY(0); }
|
|
28648
|
-
}
|
|
28649
|
-
@keyframes pptx-tr-pan-to-bottom {
|
|
28650
|
-
from { transform: translateY(0); }
|
|
28651
|
-
to { transform: translateY(100%); }
|
|
28652
|
-
}
|
|
28653
|
-
`;
|
|
28654
|
-
/** Part 2: prism / reveal / ripple / shred / switch / vortex / warp / wheelReverse / window. */
|
|
28655
|
-
const P14_TRANSITION_KEYFRAMES_2 = `
|
|
28656
|
-
/* ── Prism (3D rotation via perspective transform) ───────────────── */
|
|
28657
|
-
@keyframes pptx-tr-prism-in-from-right {
|
|
28658
|
-
from { transform: perspective(800px) rotateY(-90deg) translateX(50%); opacity: 0; }
|
|
28659
|
-
to { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
|
|
28660
|
-
}
|
|
28661
|
-
@keyframes pptx-tr-prism-out-to-left {
|
|
28662
|
-
from { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
|
|
28663
|
-
to { transform: perspective(800px) rotateY(90deg) translateX(-50%); opacity: 0; }
|
|
28664
|
-
}
|
|
28665
|
-
@keyframes pptx-tr-prism-in-from-left {
|
|
28666
|
-
from { transform: perspective(800px) rotateY(90deg) translateX(-50%); opacity: 0; }
|
|
28667
|
-
to { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
|
|
28668
|
-
}
|
|
28669
|
-
@keyframes pptx-tr-prism-out-to-right {
|
|
28670
|
-
from { transform: perspective(800px) rotateY(0deg) translateX(0); opacity: 1; }
|
|
28671
|
-
to { transform: perspective(800px) rotateY(-90deg) translateX(50%); opacity: 0; }
|
|
28672
|
-
}
|
|
28673
|
-
@keyframes pptx-tr-prism-in-from-bottom {
|
|
28674
|
-
from { transform: perspective(800px) rotateX(90deg) translateY(50%); opacity: 0; }
|
|
28675
|
-
to { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
|
|
28676
|
-
}
|
|
28677
|
-
@keyframes pptx-tr-prism-out-to-top {
|
|
28678
|
-
from { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
|
|
28679
|
-
to { transform: perspective(800px) rotateX(-90deg) translateY(-50%); opacity: 0; }
|
|
28680
|
-
}
|
|
28681
|
-
@keyframes pptx-tr-prism-in-from-top {
|
|
28682
|
-
from { transform: perspective(800px) rotateX(-90deg) translateY(-50%); opacity: 0; }
|
|
28683
|
-
to { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
|
|
28684
|
-
}
|
|
28685
|
-
@keyframes pptx-tr-prism-out-to-bottom {
|
|
28686
|
-
from { transform: perspective(800px) rotateX(0deg) translateY(0); opacity: 1; }
|
|
28687
|
-
to { transform: perspective(800px) rotateX(90deg) translateY(50%); opacity: 0; }
|
|
28688
|
-
}
|
|
28689
|
-
|
|
28690
|
-
/* ── Reveal (slide away reveal) ──────────────────────────────────── */
|
|
28691
|
-
@keyframes pptx-tr-reveal-out-to-right {
|
|
28692
|
-
from { transform: translateX(0); }
|
|
28693
|
-
to { transform: translateX(100%); }
|
|
28694
|
-
}
|
|
28695
|
-
@keyframes pptx-tr-reveal-out-to-left {
|
|
28696
|
-
from { transform: translateX(0); }
|
|
28697
|
-
to { transform: translateX(-100%); }
|
|
28698
|
-
}
|
|
28699
|
-
@keyframes pptx-tr-reveal-in {
|
|
28700
|
-
from { opacity: 0.5; }
|
|
28701
|
-
to { opacity: 1; }
|
|
28702
|
-
}
|
|
28703
|
-
|
|
28704
|
-
/* ── Ripple (expanding ring clip-path) ───────────────────────────── */
|
|
28705
|
-
@keyframes pptx-tr-ripple-in {
|
|
28706
|
-
from { clip-path: circle(0% at 50% 50%); opacity: 0.5; }
|
|
28707
|
-
30% { clip-path: circle(20% at 50% 50%); opacity: 0.7; }
|
|
28708
|
-
60% { clip-path: circle(50% at 50% 50%); opacity: 0.9; }
|
|
28709
|
-
to { clip-path: circle(75% at 50% 50%); opacity: 1; }
|
|
28710
|
-
}
|
|
28711
|
-
|
|
28712
|
-
/* ── Shred (fragmented clip-path pieces) ─────────────────────────── */
|
|
28713
|
-
@keyframes pptx-tr-shred-strips-in {
|
|
28714
|
-
from { clip-path: inset(0 100% 0 0); opacity: 0; }
|
|
28715
|
-
30% { clip-path: inset(0 60% 0 0); opacity: 0.5; }
|
|
28716
|
-
to { clip-path: inset(0); opacity: 1; }
|
|
28717
|
-
}
|
|
28718
|
-
@keyframes pptx-tr-shred-rectangles-in {
|
|
28719
|
-
from { clip-path: inset(50%); opacity: 0; }
|
|
28720
|
-
40% { clip-path: inset(20%); opacity: 0.6; }
|
|
28721
|
-
to { clip-path: inset(0); opacity: 1; }
|
|
28722
|
-
}
|
|
28723
|
-
@keyframes pptx-tr-shred-out {
|
|
28724
|
-
from { opacity: 1; }
|
|
28725
|
-
to { opacity: 0; filter: blur(2px); }
|
|
28726
|
-
}
|
|
28727
|
-
|
|
28728
|
-
/* ── Switch (flip/rotate swap) ───────────────────────────────────── */
|
|
28729
|
-
@keyframes pptx-tr-switch-in-from-right {
|
|
28730
|
-
from { transform: perspective(800px) rotateY(-180deg); opacity: 0; }
|
|
28731
|
-
to { transform: perspective(800px) rotateY(0deg); opacity: 1; }
|
|
28732
|
-
}
|
|
28733
|
-
@keyframes pptx-tr-switch-out-to-left {
|
|
28734
|
-
from { transform: perspective(800px) rotateY(0deg); opacity: 1; }
|
|
28735
|
-
to { transform: perspective(800px) rotateY(180deg); opacity: 0; }
|
|
28736
|
-
}
|
|
28737
|
-
@keyframes pptx-tr-switch-in-from-left {
|
|
28738
|
-
from { transform: perspective(800px) rotateY(180deg); opacity: 0; }
|
|
28739
|
-
to { transform: perspective(800px) rotateY(0deg); opacity: 1; }
|
|
28740
|
-
}
|
|
28741
|
-
@keyframes pptx-tr-switch-out-to-right {
|
|
28742
|
-
from { transform: perspective(800px) rotateY(0deg); opacity: 1; }
|
|
28743
|
-
to { transform: perspective(800px) rotateY(-180deg); opacity: 0; }
|
|
28744
|
-
}
|
|
28745
|
-
|
|
28746
|
-
/* ── Vortex (rotate + scale spiral) ──────────────────────────────── */
|
|
28747
|
-
@keyframes pptx-tr-vortex-in {
|
|
28748
|
-
from { transform: rotate(720deg) scale(0); opacity: 0; }
|
|
28749
|
-
to { transform: rotate(0deg) scale(1); opacity: 1; }
|
|
28750
|
-
}
|
|
28751
|
-
@keyframes pptx-tr-vortex-out {
|
|
28752
|
-
from { transform: rotate(0deg) scale(1); opacity: 1; }
|
|
28753
|
-
to { transform: rotate(-720deg) scale(0); opacity: 0; }
|
|
28754
|
-
}
|
|
28755
|
-
|
|
28756
|
-
/* ── Warp (skew distortion) ──────────────────────────────────────── */
|
|
28757
|
-
@keyframes pptx-tr-warp-in {
|
|
28758
|
-
from { transform: scale(0.3) skewX(30deg) skewY(15deg); opacity: 0; }
|
|
28759
|
-
50% { transform: scale(0.8) skewX(-5deg) skewY(-3deg); opacity: 0.7; }
|
|
28760
|
-
to { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; }
|
|
28761
|
-
}
|
|
28762
|
-
@keyframes pptx-tr-warp-out {
|
|
28763
|
-
from { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; }
|
|
28764
|
-
50% { transform: scale(0.8) skewX(5deg) skewY(3deg); opacity: 0.7; }
|
|
28765
|
-
to { transform: scale(0.3) skewX(-30deg) skewY(-15deg); opacity: 0; }
|
|
28766
|
-
}
|
|
28767
|
-
@keyframes pptx-tr-warp-reverse-in {
|
|
28768
|
-
from { transform: scale(3) skewX(-20deg) skewY(-10deg); opacity: 0; filter: blur(4px); }
|
|
28769
|
-
to { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; filter: blur(0); }
|
|
28770
|
-
}
|
|
28771
|
-
@keyframes pptx-tr-warp-reverse-out {
|
|
28772
|
-
from { transform: scale(1) skewX(0deg) skewY(0deg); opacity: 1; filter: blur(0); }
|
|
28773
|
-
to { transform: scale(3) skewX(20deg) skewY(10deg); opacity: 0; filter: blur(4px); }
|
|
28774
|
-
}
|
|
28775
|
-
|
|
28776
|
-
/* ── WheelReverse (reverse wheel rotation) ───────────────────────── */
|
|
28777
|
-
@keyframes pptx-tr-wheel-reverse-in {
|
|
28778
|
-
from { clip-path: circle(0% at 50% 50%); transform: rotate(180deg); }
|
|
28779
|
-
to { clip-path: circle(75% at 50% 50%); transform: rotate(0deg); }
|
|
28780
|
-
}
|
|
28781
|
-
|
|
28782
|
-
/* ── Window (scale from center with border) ──────────────────────── */
|
|
28783
|
-
@keyframes pptx-tr-window-horz {
|
|
28784
|
-
from { clip-path: inset(0 50%); }
|
|
28785
|
-
to { clip-path: inset(0 0); }
|
|
28786
|
-
}
|
|
28787
|
-
@keyframes pptx-tr-window-vert {
|
|
28788
|
-
from { clip-path: inset(50% 0); }
|
|
28789
|
-
to { clip-path: inset(0 0); }
|
|
28790
|
-
}
|
|
28791
|
-
@keyframes pptx-tr-window-out {
|
|
28792
|
-
from { opacity: 1; transform: scale(1); }
|
|
28793
|
-
to { opacity: 0; transform: scale(0.9); }
|
|
28794
|
-
}
|
|
28795
|
-
`;
|
|
28796
|
-
/** Both p14 keyframe blocks concatenated, for single `<style>` injection. */
|
|
28797
|
-
const P14_TRANSITION_KEYFRAMES_ALL = `${P14_TRANSITION_KEYFRAMES}\n${P14_TRANSITION_KEYFRAMES_2}`;
|
|
28798
|
-
|
|
28799
29207
|
/**
|
|
28800
29208
|
* `p14-transition-css` — animation resolver for the Office 2010 (`p14`
|
|
28801
29209
|
* namespace) slide transitions. Maps each p14 transition type to the faithful
|
|
@@ -28840,7 +29248,10 @@ function resolveCardinal(direction) {
|
|
|
28840
29248
|
return 'left';
|
|
28841
29249
|
}
|
|
28842
29250
|
}
|
|
28843
|
-
/**
|
|
29251
|
+
/**
|
|
29252
|
+
* Build a directional pair using the bare `to-X` / `from-Y` suffixes (the `pan`
|
|
29253
|
+
* keyframes use this naming).
|
|
29254
|
+
*/
|
|
28844
29255
|
function directionalPair(direction, prefix, dur, ease) {
|
|
28845
29256
|
const dir = resolveCardinal(direction);
|
|
28846
29257
|
const opposites = {
|
|
@@ -28856,6 +29267,25 @@ function directionalPair(direction, prefix, dur, ease) {
|
|
|
28856
29267
|
outgoingOnTop: false,
|
|
28857
29268
|
};
|
|
28858
29269
|
}
|
|
29270
|
+
/**
|
|
29271
|
+
* Build a directional pair using the explicit `out-to-X` / `in-from-Y` suffixes
|
|
29272
|
+
* (the `prism` keyframes use this naming, matching conveyor/switch/gallery).
|
|
29273
|
+
*/
|
|
29274
|
+
function cardinalOutInPair(direction, prefix, dur, ease) {
|
|
29275
|
+
const dir = resolveCardinal(direction);
|
|
29276
|
+
const map = {
|
|
29277
|
+
left: ['out-to-left', 'in-from-right'],
|
|
29278
|
+
right: ['out-to-right', 'in-from-left'],
|
|
29279
|
+
up: ['out-to-top', 'in-from-bottom'],
|
|
29280
|
+
down: ['out-to-bottom', 'in-from-top'],
|
|
29281
|
+
};
|
|
29282
|
+
const [outSuffix, inSuffix] = map[dir];
|
|
29283
|
+
return {
|
|
29284
|
+
outgoing: `${prefix}-${outSuffix} ${dur} ${ease} forwards`,
|
|
29285
|
+
incoming: `${prefix}-${inSuffix} ${dur} ${ease} forwards`,
|
|
29286
|
+
outgoingOnTop: false,
|
|
29287
|
+
};
|
|
29288
|
+
}
|
|
28859
29289
|
/**
|
|
28860
29290
|
* Return CSS animation descriptors for p14 transition types. Returns
|
|
28861
29291
|
* `undefined` when the type is not a p14 transition.
|
|
@@ -28955,7 +29385,7 @@ function getP14TransitionAnimations(type, durationMs, direction, orient) {
|
|
|
28955
29385
|
case 'pan':
|
|
28956
29386
|
return directionalPair(direction, 'pptx-tr-pan', dur, ease);
|
|
28957
29387
|
case 'prism':
|
|
28958
|
-
return
|
|
29388
|
+
return cardinalOutInPair(direction, 'pptx-tr-prism', dur, ease);
|
|
28959
29389
|
case 'reveal': {
|
|
28960
29390
|
const lr = resolveLR(direction);
|
|
28961
29391
|
return {
|
|
@@ -29039,6 +29469,314 @@ function getP14TransitionAnimations(type, durationMs, direction, orient) {
|
|
|
29039
29469
|
}
|
|
29040
29470
|
}
|
|
29041
29471
|
|
|
29472
|
+
/**
|
|
29473
|
+
* `slide-transition-css` — pure mapping from a {@link PptxSlideTransition}
|
|
29474
|
+
* (type + duration + direction/orientation) to the CSS `animation` shorthand
|
|
29475
|
+
* pieces used by each binding's presentation-mode transition overlay during a
|
|
29476
|
+
* slide change.
|
|
29477
|
+
*
|
|
29478
|
+
* Consolidates the React `transition-resolver` / `transition-helpers` /
|
|
29479
|
+
* `transition-keyframes` trio, the Vue `slide-transition-css`, and the Angular
|
|
29480
|
+
* `transition-helpers` into one framework-agnostic module:
|
|
29481
|
+
*
|
|
29482
|
+
* - {@link getSlideTransitionAnimations} resolves a transition to the
|
|
29483
|
+
* `animation` shorthand strings for the outgoing (old) and incoming (new)
|
|
29484
|
+
* slide layers, plus whether the outgoing layer sits on top.
|
|
29485
|
+
* - the `@keyframes` referenced live in `slide-transition-keyframes`
|
|
29486
|
+
* (`SLIDE_TRANSITION_KEYFRAMES`), injected once via a `<style>` element.
|
|
29487
|
+
*
|
|
29488
|
+
* Superset note: the exotic / 3-D transition family (`pan`/`gallery`/
|
|
29489
|
+
* `conveyor`/`reveal`/`doors`/`switch`/`flythrough`/`ferris`/`prism`/`ripple`/
|
|
29490
|
+
* `honeycomb`/`glitter`/`shred`/`flash`/`vortex`/`warp`/`wheelReverse`/`window`)
|
|
29491
|
+
* is rendered faithfully by delegating to {@link getP14TransitionAnimations}
|
|
29492
|
+
* (its `@keyframes` live in `p14-transition-keyframes` and are folded into
|
|
29493
|
+
* `SLIDE_TRANSITION_KEYFRAMES`). The classic set and the newer p15 cinematic
|
|
29494
|
+
* types with no dedicated keyframes (`cube`/`flip`/`rotate`/`orbit`/`fracture`/
|
|
29495
|
+
* `peelOff`/`pageCurl*`/`airplane`/`origami`, etc.) fall back to a symmetrical
|
|
29496
|
+
* cross-fade.
|
|
29497
|
+
*
|
|
29498
|
+
* Everything here is pure and unit-testable: no framework imports, no DOM.
|
|
29499
|
+
*
|
|
29500
|
+
* @module render/slide-transition-css
|
|
29501
|
+
*/
|
|
29502
|
+
/**
|
|
29503
|
+
* Map a {@link PptxTransitionType} (+ duration/direction/orient/spokes) to the
|
|
29504
|
+
* concrete CSS `animation` descriptors for the outgoing and incoming layers.
|
|
29505
|
+
*
|
|
29506
|
+
* Unknown types fall back to a symmetrical cross-fade.
|
|
29507
|
+
*/
|
|
29508
|
+
function getSlideTransitionAnimations(type, durationMs, direction, orient, spokes) {
|
|
29509
|
+
const dur = `${durationMs}ms`;
|
|
29510
|
+
// `spokes` is reserved for future wheel spoke-count support; forwarded only
|
|
29511
|
+
// through recursive calls (random / pull aliases).
|
|
29512
|
+
void spokes;
|
|
29513
|
+
// Prefer the faithful Office 2010 (p14) keyframe set for the exotic / 3-D
|
|
29514
|
+
// transition family (conveyor/doors/ferris/flash/flythrough/gallery/glitter/
|
|
29515
|
+
// honeycomb/pan/prism/reveal/ripple/shred/switch/vortex/warp/wheelReverse/
|
|
29516
|
+
// window). Returns `undefined` for the classic set, which falls through to
|
|
29517
|
+
// the 2-D CSS cases below. The p14 `@keyframes` are folded into
|
|
29518
|
+
// `SLIDE_TRANSITION_KEYFRAMES`, so every binding that injects that block
|
|
29519
|
+
// animates these faithfully with no per-binding wiring.
|
|
29520
|
+
const p14 = getP14TransitionAnimations(type, durationMs, direction, orient);
|
|
29521
|
+
if (p14) {
|
|
29522
|
+
return p14;
|
|
29523
|
+
}
|
|
29524
|
+
switch (type) {
|
|
29525
|
+
case 'none':
|
|
29526
|
+
case 'cut':
|
|
29527
|
+
return INSTANT;
|
|
29528
|
+
case 'fade':
|
|
29529
|
+
return {
|
|
29530
|
+
outgoing: `pptx-tr-fade-out ${dur} ${EASE} forwards`,
|
|
29531
|
+
incoming: `pptx-tr-fade-in ${dur} ${EASE} forwards`,
|
|
29532
|
+
outgoingOnTop: true,
|
|
29533
|
+
};
|
|
29534
|
+
case 'push': {
|
|
29535
|
+
const dir = resolveDirection(direction, 'left');
|
|
29536
|
+
const configs = {
|
|
29537
|
+
left: {
|
|
29538
|
+
outgoing: `pptx-tr-push-out-to-left ${dur} ${EASE} forwards`,
|
|
29539
|
+
incoming: `pptx-tr-push-in-from-right ${dur} ${EASE} forwards`,
|
|
29540
|
+
outgoingOnTop: false,
|
|
29541
|
+
},
|
|
29542
|
+
right: {
|
|
29543
|
+
outgoing: `pptx-tr-push-out-to-right ${dur} ${EASE} forwards`,
|
|
29544
|
+
incoming: `pptx-tr-push-in-from-left ${dur} ${EASE} forwards`,
|
|
29545
|
+
outgoingOnTop: false,
|
|
29546
|
+
},
|
|
29547
|
+
up: {
|
|
29548
|
+
outgoing: `pptx-tr-push-out-to-top ${dur} ${EASE} forwards`,
|
|
29549
|
+
incoming: `pptx-tr-push-in-from-bottom ${dur} ${EASE} forwards`,
|
|
29550
|
+
outgoingOnTop: false,
|
|
29551
|
+
},
|
|
29552
|
+
down: {
|
|
29553
|
+
outgoing: `pptx-tr-push-out-to-bottom ${dur} ${EASE} forwards`,
|
|
29554
|
+
incoming: `pptx-tr-push-in-from-top ${dur} ${EASE} forwards`,
|
|
29555
|
+
outgoingOnTop: false,
|
|
29556
|
+
},
|
|
29557
|
+
};
|
|
29558
|
+
return configs[dir];
|
|
29559
|
+
}
|
|
29560
|
+
case 'wipe': {
|
|
29561
|
+
const dir = resolveDirection(direction, 'left');
|
|
29562
|
+
const wipeNames = {
|
|
29563
|
+
left: `pptx-tr-wipe-from-left ${dur} ${EASE} forwards`,
|
|
29564
|
+
right: `pptx-tr-wipe-from-right ${dur} ${EASE} forwards`,
|
|
29565
|
+
up: `pptx-tr-wipe-from-top ${dur} ${EASE} forwards`,
|
|
29566
|
+
down: `pptx-tr-wipe-from-bottom ${dur} ${EASE} forwards`,
|
|
29567
|
+
};
|
|
29568
|
+
return {
|
|
29569
|
+
outgoing: 'none',
|
|
29570
|
+
incoming: wipeNames[dir],
|
|
29571
|
+
outgoingOnTop: false,
|
|
29572
|
+
};
|
|
29573
|
+
}
|
|
29574
|
+
case 'cover': {
|
|
29575
|
+
const dir = resolveDirection8(direction, 'left');
|
|
29576
|
+
const coverMap = {
|
|
29577
|
+
left: `pptx-tr-cover-from-left ${dur} ${EASE} forwards`,
|
|
29578
|
+
right: `pptx-tr-cover-from-right ${dur} ${EASE} forwards`,
|
|
29579
|
+
up: `pptx-tr-cover-from-top ${dur} ${EASE} forwards`,
|
|
29580
|
+
down: `pptx-tr-cover-from-bottom ${dur} ${EASE} forwards`,
|
|
29581
|
+
lu: `pptx-tr-cover-from-lu ${dur} ${EASE} forwards`,
|
|
29582
|
+
ld: `pptx-tr-cover-from-ld ${dur} ${EASE} forwards`,
|
|
29583
|
+
ru: `pptx-tr-cover-from-ru ${dur} ${EASE} forwards`,
|
|
29584
|
+
rd: `pptx-tr-cover-from-rd ${dur} ${EASE} forwards`,
|
|
29585
|
+
};
|
|
29586
|
+
return {
|
|
29587
|
+
outgoing: 'none',
|
|
29588
|
+
incoming: coverMap[dir],
|
|
29589
|
+
outgoingOnTop: false,
|
|
29590
|
+
};
|
|
29591
|
+
}
|
|
29592
|
+
case 'uncover': {
|
|
29593
|
+
const dir = resolveDirection8(direction, 'left');
|
|
29594
|
+
const uncoverMap = {
|
|
29595
|
+
left: `pptx-tr-uncover-to-left ${dur} ${EASE} forwards`,
|
|
29596
|
+
right: `pptx-tr-uncover-to-right ${dur} ${EASE} forwards`,
|
|
29597
|
+
up: `pptx-tr-uncover-to-top ${dur} ${EASE} forwards`,
|
|
29598
|
+
down: `pptx-tr-uncover-to-bottom ${dur} ${EASE} forwards`,
|
|
29599
|
+
lu: `pptx-tr-uncover-to-lu ${dur} ${EASE} forwards`,
|
|
29600
|
+
ld: `pptx-tr-uncover-to-ld ${dur} ${EASE} forwards`,
|
|
29601
|
+
ru: `pptx-tr-uncover-to-ru ${dur} ${EASE} forwards`,
|
|
29602
|
+
rd: `pptx-tr-uncover-to-rd ${dur} ${EASE} forwards`,
|
|
29603
|
+
};
|
|
29604
|
+
return {
|
|
29605
|
+
outgoing: uncoverMap[dir],
|
|
29606
|
+
incoming: 'none',
|
|
29607
|
+
outgoingOnTop: true,
|
|
29608
|
+
};
|
|
29609
|
+
}
|
|
29610
|
+
case 'split': {
|
|
29611
|
+
const o = resolveOrientation(undefined, orient);
|
|
29612
|
+
const isOut = direction !== 'in';
|
|
29613
|
+
if (isOut) {
|
|
29614
|
+
return {
|
|
29615
|
+
outgoing: 'none',
|
|
29616
|
+
incoming: o === 'vert'
|
|
29617
|
+
? `pptx-tr-split-v-out ${dur} ${EASE} forwards`
|
|
29618
|
+
: `pptx-tr-split-h-out ${dur} ${EASE} forwards`,
|
|
29619
|
+
outgoingOnTop: false,
|
|
29620
|
+
};
|
|
29621
|
+
}
|
|
29622
|
+
return {
|
|
29623
|
+
outgoing: o === 'vert'
|
|
29624
|
+
? `pptx-tr-split-v-in ${dur} ${EASE} forwards`
|
|
29625
|
+
: `pptx-tr-split-h-in ${dur} ${EASE} forwards`,
|
|
29626
|
+
incoming: 'none',
|
|
29627
|
+
outgoingOnTop: true,
|
|
29628
|
+
};
|
|
29629
|
+
}
|
|
29630
|
+
case 'dissolve':
|
|
29631
|
+
return {
|
|
29632
|
+
outgoing: `pptx-tr-fade-out ${dur} ${EASE} forwards`,
|
|
29633
|
+
incoming: `pptx-tr-dissolve-in ${dur} ${EASE} forwards`,
|
|
29634
|
+
outgoingOnTop: true,
|
|
29635
|
+
};
|
|
29636
|
+
case 'circle':
|
|
29637
|
+
return {
|
|
29638
|
+
outgoing: 'none',
|
|
29639
|
+
incoming: `pptx-tr-circle-in ${dur} ${EASE} forwards`,
|
|
29640
|
+
outgoingOnTop: false,
|
|
29641
|
+
};
|
|
29642
|
+
case 'diamond':
|
|
29643
|
+
return {
|
|
29644
|
+
outgoing: 'none',
|
|
29645
|
+
incoming: `pptx-tr-diamond-in ${dur} ${EASE} forwards`,
|
|
29646
|
+
outgoingOnTop: false,
|
|
29647
|
+
};
|
|
29648
|
+
case 'plus':
|
|
29649
|
+
return {
|
|
29650
|
+
outgoing: 'none',
|
|
29651
|
+
incoming: `pptx-tr-plus-in ${dur} ${EASE} forwards`,
|
|
29652
|
+
outgoingOnTop: false,
|
|
29653
|
+
};
|
|
29654
|
+
case 'wedge':
|
|
29655
|
+
return {
|
|
29656
|
+
outgoing: 'none',
|
|
29657
|
+
incoming: `pptx-tr-wedge-in ${dur} ${EASE} forwards`,
|
|
29658
|
+
outgoingOnTop: false,
|
|
29659
|
+
};
|
|
29660
|
+
case 'wheel':
|
|
29661
|
+
return {
|
|
29662
|
+
outgoing: 'none',
|
|
29663
|
+
incoming: `pptx-tr-wheel-in ${dur} ${EASE} forwards`,
|
|
29664
|
+
outgoingOnTop: false,
|
|
29665
|
+
};
|
|
29666
|
+
case 'zoom':
|
|
29667
|
+
return {
|
|
29668
|
+
outgoing: `pptx-tr-zoom-out ${dur} ${EASE} forwards`,
|
|
29669
|
+
incoming: `pptx-tr-zoom-in ${dur} ${EASE} forwards`,
|
|
29670
|
+
outgoingOnTop: true,
|
|
29671
|
+
};
|
|
29672
|
+
case 'blinds': {
|
|
29673
|
+
const o = resolveOrientation(direction, orient);
|
|
29674
|
+
return {
|
|
29675
|
+
outgoing: 'none',
|
|
29676
|
+
incoming: o === 'vert'
|
|
29677
|
+
? `pptx-tr-blinds-v ${dur} ${EASE} forwards`
|
|
29678
|
+
: `pptx-tr-blinds-h ${dur} ${EASE} forwards`,
|
|
29679
|
+
outgoingOnTop: false,
|
|
29680
|
+
};
|
|
29681
|
+
}
|
|
29682
|
+
case 'checker':
|
|
29683
|
+
return {
|
|
29684
|
+
outgoing: `pptx-tr-fade-out ${dur} ${EASE} forwards`,
|
|
29685
|
+
incoming: `pptx-tr-checker-in ${dur} ${EASE} forwards`,
|
|
29686
|
+
outgoingOnTop: true,
|
|
29687
|
+
};
|
|
29688
|
+
case 'comb': {
|
|
29689
|
+
const o = resolveOrientation(direction, orient);
|
|
29690
|
+
return {
|
|
29691
|
+
outgoing: 'none',
|
|
29692
|
+
incoming: o === 'vert'
|
|
29693
|
+
? `pptx-tr-comb-v ${dur} ${EASE} forwards`
|
|
29694
|
+
: `pptx-tr-comb-h ${dur} ${EASE} forwards`,
|
|
29695
|
+
outgoingOnTop: false,
|
|
29696
|
+
};
|
|
29697
|
+
}
|
|
29698
|
+
case 'strips': {
|
|
29699
|
+
const stripDir = direction === 'lu' || direction === 'ld' || direction === 'ru' || direction === 'rd'
|
|
29700
|
+
? direction
|
|
29701
|
+
: 'lu';
|
|
29702
|
+
return {
|
|
29703
|
+
outgoing: 'none',
|
|
29704
|
+
incoming: `pptx-tr-strips-${stripDir} ${dur} ${EASE} forwards`,
|
|
29705
|
+
outgoingOnTop: false,
|
|
29706
|
+
};
|
|
29707
|
+
}
|
|
29708
|
+
case 'randomBar': {
|
|
29709
|
+
const o = resolveOrientation(direction, orient);
|
|
29710
|
+
return {
|
|
29711
|
+
outgoing: 'none',
|
|
29712
|
+
incoming: o === 'vert'
|
|
29713
|
+
? `pptx-tr-randombar-v ${dur} ${EASE} forwards`
|
|
29714
|
+
: `pptx-tr-randombar-h ${dur} ${EASE} forwards`,
|
|
29715
|
+
outgoingOnTop: false,
|
|
29716
|
+
};
|
|
29717
|
+
}
|
|
29718
|
+
case 'newsflash':
|
|
29719
|
+
return {
|
|
29720
|
+
outgoing: `pptx-tr-fade-out ${dur} ${EASE} forwards`,
|
|
29721
|
+
incoming: `pptx-tr-newsflash-in ${dur} ${EASE} forwards`,
|
|
29722
|
+
outgoingOnTop: false,
|
|
29723
|
+
};
|
|
29724
|
+
// `pull` is the directional alias of `uncover`.
|
|
29725
|
+
case 'pull':
|
|
29726
|
+
return getSlideTransitionAnimations('uncover', durationMs, direction, orient, spokes);
|
|
29727
|
+
case 'morph':
|
|
29728
|
+
return {
|
|
29729
|
+
outgoing: `pptx-tr-fade-out ${dur} ${EASE} forwards`,
|
|
29730
|
+
incoming: `pptx-tr-fade-in ${dur} ${EASE} forwards`,
|
|
29731
|
+
outgoingOnTop: true,
|
|
29732
|
+
};
|
|
29733
|
+
case 'random': {
|
|
29734
|
+
const randomType = RANDOM_ELIGIBLE_TYPES[Math.floor(Math.random() * RANDOM_ELIGIBLE_TYPES.length)];
|
|
29735
|
+
return getSlideTransitionAnimations(randomType, durationMs, direction, orient, spokes);
|
|
29736
|
+
}
|
|
29737
|
+
// The exotic / 3-D transition family (conveyor/doors/ferris/flash/
|
|
29738
|
+
// flythrough/gallery/glitter/honeycomb/pan/prism/reveal/ripple/shred/
|
|
29739
|
+
// switch/vortex/warp/wheelReverse/window) is handled faithfully above via
|
|
29740
|
+
// `getP14TransitionAnimations` and never reaches this switch.
|
|
29741
|
+
// Fallback (unknown / not-yet-mapped type, e.g. the p15 cinematic set:
|
|
29742
|
+
// cube/flip/rotate/orbit/fracture/peelOff/pageCurl*/airplane/origami)
|
|
29743
|
+
// — symmetrical cross-fade.
|
|
29744
|
+
default:
|
|
29745
|
+
return {
|
|
29746
|
+
outgoing: `pptx-tr-fade-out ${dur} ${EASE} forwards`,
|
|
29747
|
+
incoming: `pptx-tr-fade-in ${dur} ${EASE} forwards`,
|
|
29748
|
+
outgoingOnTop: true,
|
|
29749
|
+
};
|
|
29750
|
+
}
|
|
29751
|
+
}
|
|
29752
|
+
/**
|
|
29753
|
+
* Convenience wrapper that reads everything off a {@link PptxSlideTransition},
|
|
29754
|
+
* applying the React/Vue default duration when none is set. `none`/`cut` and a
|
|
29755
|
+
* transition with a non-positive duration resolve to {@link INSTANT}.
|
|
29756
|
+
*/
|
|
29757
|
+
function resolveSlideTransition(transition) {
|
|
29758
|
+
if (!transition || transition.type === 'none' || transition.type === 'cut') {
|
|
29759
|
+
return INSTANT;
|
|
29760
|
+
}
|
|
29761
|
+
const durationMs = typeof transition.durationMs === 'number' && transition.durationMs > 0
|
|
29762
|
+
? transition.durationMs
|
|
29763
|
+
: DEFAULT_TRANSITION_DURATION_MS$1;
|
|
29764
|
+
return getSlideTransitionAnimations(transition.type, durationMs, transition.direction, transition.orient, transition.spokes);
|
|
29765
|
+
}
|
|
29766
|
+
/**
|
|
29767
|
+
* The effective duration (ms) for a transition under the React/Vue policy — the
|
|
29768
|
+
* configured `durationMs`, or {@link DEFAULT_TRANSITION_DURATION_MS} when
|
|
29769
|
+
* unset/invalid. `none`/`cut` resolve to `0` (instant).
|
|
29770
|
+
*/
|
|
29771
|
+
function resolveTransitionDurationMs(transition) {
|
|
29772
|
+
if (!transition || transition.type === 'none' || transition.type === 'cut') {
|
|
29773
|
+
return 0;
|
|
29774
|
+
}
|
|
29775
|
+
return typeof transition.durationMs === 'number' && transition.durationMs > 0
|
|
29776
|
+
? transition.durationMs
|
|
29777
|
+
: DEFAULT_TRANSITION_DURATION_MS$1;
|
|
29778
|
+
}
|
|
29779
|
+
|
|
29042
29780
|
/**
|
|
29043
29781
|
* SmartArt layout engine — pure colour / style / tree / family-resolution
|
|
29044
29782
|
* helpers shared by the React, Vue, and Angular bindings.
|
|
@@ -29872,6 +30610,29 @@ function computeTargetLayout(nodes, box, palette, style, elementId) {
|
|
|
29872
30610
|
* `import … from 'pptx-viewer-shared'` (or a thin binding shim) yields the full
|
|
29873
30611
|
* surface the renderers and colocated tests expect.
|
|
29874
30612
|
*/
|
|
30613
|
+
/**
|
|
30614
|
+
* Expand a colour palette across `count` nodes.
|
|
30615
|
+
*
|
|
30616
|
+
* For `span`, distributes the nodes evenly along the palette and interpolates
|
|
30617
|
+
* intermediate colours in HSL space (honouring `hueDirection`), so e.g. a
|
|
30618
|
+
* two-colour "colorful range" scheme fades smoothly across many nodes. For
|
|
30619
|
+
* `cycle`/`repeat`/unset, wraps the palette by index (the historic behaviour).
|
|
30620
|
+
*/
|
|
30621
|
+
function interpolateSmartArtPalette(palette, count, method, hueDirection) {
|
|
30622
|
+
if (count <= 0 || palette.length === 0) {
|
|
30623
|
+
return [];
|
|
30624
|
+
}
|
|
30625
|
+
if (method !== 'span' || palette.length < 2 || count <= palette.length) {
|
|
30626
|
+
return Array.from({ length: count }, (_, i) => palette[i % palette.length]);
|
|
30627
|
+
}
|
|
30628
|
+
const segments = palette.length - 1;
|
|
30629
|
+
return Array.from({ length: count }, (_, i) => {
|
|
30630
|
+
const pos = (i / (count - 1)) * segments;
|
|
30631
|
+
const lower = Math.min(Math.floor(pos), segments - 1);
|
|
30632
|
+
const frac = pos - lower;
|
|
30633
|
+
return interpolateColor(palette[lower], palette[lower + 1], frac, 'hsl', hueDirection);
|
|
30634
|
+
});
|
|
30635
|
+
}
|
|
29875
30636
|
/**
|
|
29876
30637
|
* Compute the SVG layout for a SmartArt element when drawing shapes are absent.
|
|
29877
30638
|
*
|
|
@@ -29882,32 +30643,40 @@ function computeTargetLayout(nodes, box, palette, style, elementId) {
|
|
|
29882
30643
|
* @param elementId - Element ID (used for stable SVG key generation).
|
|
29883
30644
|
* @param resolvedLayoutType - Layout type string from the core parser.
|
|
29884
30645
|
* @param layout - Named layout preset.
|
|
30646
|
+
* @param interpolation - Optional colour-list span/cycle interpolation
|
|
30647
|
+
* (from the diagram's colour scheme). When `span`,
|
|
30648
|
+
* the palette is expanded into a per-node gradient
|
|
30649
|
+
* before layout; otherwise the palette is used
|
|
30650
|
+
* as-is and cycled by the family computers.
|
|
29885
30651
|
* @returns Complete layout geometry for the resolved family.
|
|
29886
30652
|
*/
|
|
29887
|
-
function computeSmartArtLayout(nodes, box, palette, style, elementId, resolvedLayoutType, layout) {
|
|
30653
|
+
function computeSmartArtLayout(nodes, box, palette, style, elementId, resolvedLayoutType, layout, interpolation) {
|
|
29888
30654
|
const flat = flattenNodes(nodes);
|
|
29889
30655
|
const family = resolveLayoutFamily(nodes, resolvedLayoutType, layout);
|
|
30656
|
+
const pal = interpolation?.method === 'span'
|
|
30657
|
+
? interpolateSmartArtPalette(palette, flat.length, 'span', interpolation.hueDirection)
|
|
30658
|
+
: palette;
|
|
29890
30659
|
switch (family) {
|
|
29891
30660
|
case 'list':
|
|
29892
|
-
return computeListLayout(flat, box,
|
|
30661
|
+
return computeListLayout(flat, box, pal, style, elementId);
|
|
29893
30662
|
case 'process':
|
|
29894
|
-
return computeProcessLayout(flat, box,
|
|
30663
|
+
return computeProcessLayout(flat, box, pal, style, elementId);
|
|
29895
30664
|
case 'cycle':
|
|
29896
|
-
return computeCycleLayout(flat, box,
|
|
30665
|
+
return computeCycleLayout(flat, box, pal, style, elementId);
|
|
29897
30666
|
case 'hierarchy':
|
|
29898
|
-
return computeHierarchyLayout(nodes, box,
|
|
30667
|
+
return computeHierarchyLayout(nodes, box, pal, style, elementId);
|
|
29899
30668
|
case 'matrix':
|
|
29900
|
-
return computeMatrixLayout(flat, box,
|
|
30669
|
+
return computeMatrixLayout(flat, box, pal, style, elementId);
|
|
29901
30670
|
case 'radial':
|
|
29902
|
-
return computeRadialLayout(flat, box,
|
|
30671
|
+
return computeRadialLayout(flat, box, pal, style, elementId);
|
|
29903
30672
|
case 'pyramid':
|
|
29904
|
-
return computePyramidLayout(flat, box,
|
|
30673
|
+
return computePyramidLayout(flat, box, pal, style, elementId);
|
|
29905
30674
|
case 'venn':
|
|
29906
|
-
return computeVennLayout(flat, box,
|
|
30675
|
+
return computeVennLayout(flat, box, pal, style, elementId);
|
|
29907
30676
|
case 'funnel':
|
|
29908
|
-
return computeFunnelLayout(flat, box,
|
|
30677
|
+
return computeFunnelLayout(flat, box, pal, style, elementId);
|
|
29909
30678
|
case 'target':
|
|
29910
|
-
return computeTargetLayout(flat, box,
|
|
30679
|
+
return computeTargetLayout(flat, box, pal, style, elementId);
|
|
29911
30680
|
}
|
|
29912
30681
|
}
|
|
29913
30682
|
|
|
@@ -37323,6 +38092,20 @@ function updateViewerPreference(preferences, key, value) {
|
|
|
37323
38092
|
function shouldLoopContinuously(input) {
|
|
37324
38093
|
return Boolean(input.loopContinuously) || input.showType === 'kiosk';
|
|
37325
38094
|
}
|
|
38095
|
+
/**
|
|
38096
|
+
* PowerPoint's "On Mouse Click" advance gate. An on-slide click / tap / swipe
|
|
38097
|
+
* advances the show only when the current slide's transition allows it: a slide
|
|
38098
|
+
* whose transition sets `advanceOnClick` to false is advanced solely by timings
|
|
38099
|
+
* or by explicit navigation (keyboard, on-screen next/prev buttons). An
|
|
38100
|
+
* undefined flag defaults to allowed, preserving the historical
|
|
38101
|
+
* click-to-advance behaviour.
|
|
38102
|
+
*
|
|
38103
|
+
* Only the click / tap / swipe advance may consult this. Keyboard, on-screen
|
|
38104
|
+
* next/prev buttons and timed auto-advance must never be gated by it.
|
|
38105
|
+
*/
|
|
38106
|
+
function isClickAdvanceAllowed(slide) {
|
|
38107
|
+
return slide?.transition?.advanceOnClick !== false;
|
|
38108
|
+
}
|
|
37326
38109
|
function applyRehearsalTimings(slides, timings) {
|
|
37327
38110
|
return slides.map((slide, index) => {
|
|
37328
38111
|
const advanceAfterMs = timings[index];
|
|
@@ -68154,6 +68937,16 @@ function hasExitedFullscreen(doc) {
|
|
|
68154
68937
|
return !d?.fullscreenElement;
|
|
68155
68938
|
}
|
|
68156
68939
|
|
|
68940
|
+
/**
|
|
68941
|
+
* Whether a click/tap/swipe advance must be swallowed instead of moving to the
|
|
68942
|
+
* next slide. A click still steps the current slide's remaining animation
|
|
68943
|
+
* builds, so this only blocks once they are exhausted (`playbackComplete`) and
|
|
68944
|
+
* only when the slide's transition sets advanceOnClick to false. Keyboard and
|
|
68945
|
+
* the on-screen next/prev buttons never consult this.
|
|
68946
|
+
*/
|
|
68947
|
+
function shouldBlockClickAdvance(playbackComplete, slide) {
|
|
68948
|
+
return playbackComplete && !isClickAdvanceAllowed(slide);
|
|
68949
|
+
}
|
|
68157
68950
|
/**
|
|
68158
68951
|
* Clamp `index` to the valid range [0, count - 1].
|
|
68159
68952
|
* Returns 0 when `count` is 0 to avoid -1 states.
|
|
@@ -68941,8 +69734,16 @@ class PresentationOverlayComponent {
|
|
|
68941
69734
|
getScale: () => 1,
|
|
68942
69735
|
callbacks: {
|
|
68943
69736
|
onSwipe: (direction) => {
|
|
68944
|
-
// direction 1 = swipe right (previous), -1 = swipe left (next).
|
|
68945
|
-
|
|
69737
|
+
// direction 1 = swipe right (previous), -1 = swipe left (next). A
|
|
69738
|
+
// swipe is PowerPoint's on-click advance, so the forward case is
|
|
69739
|
+
// gated by the current slide's advanceOnClick flag; a backward
|
|
69740
|
+
// swipe is explicit navigation and never gated.
|
|
69741
|
+
if (direction === 1) {
|
|
69742
|
+
this.navigate('prev');
|
|
69743
|
+
}
|
|
69744
|
+
else {
|
|
69745
|
+
this.advanceFromClick();
|
|
69746
|
+
}
|
|
68946
69747
|
},
|
|
68947
69748
|
},
|
|
68948
69749
|
});
|
|
@@ -69053,6 +69854,19 @@ class PresentationOverlayComponent {
|
|
|
69053
69854
|
if (this.annotations.tool() !== 'none') {
|
|
69054
69855
|
return;
|
|
69055
69856
|
}
|
|
69857
|
+
this.advanceFromClick();
|
|
69858
|
+
}
|
|
69859
|
+
/**
|
|
69860
|
+
* Click/tap/swipe advance. Like every forward step it first reveals the
|
|
69861
|
+
* current slide's next animation build; only once the builds are exhausted
|
|
69862
|
+
* does it advance the slide, and then only when the slide's transition allows
|
|
69863
|
+
* click-advance (advanceOnClick !== false). Keyboard and the on-screen
|
|
69864
|
+
* next/prev buttons call navigate() directly and are never gated.
|
|
69865
|
+
*/
|
|
69866
|
+
advanceFromClick() {
|
|
69867
|
+
if (shouldBlockClickAdvance(this.playback.isComplete(), this.currentSlide())) {
|
|
69868
|
+
return;
|
|
69869
|
+
}
|
|
69056
69870
|
this.navigate('next');
|
|
69057
69871
|
}
|
|
69058
69872
|
/** Toggle an annotation tool (clicking the active one disarms it). */
|
|
@@ -74130,7 +74944,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
74130
74944
|
}], propDecorators: { canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }] } });
|
|
74131
74945
|
|
|
74132
74946
|
// Generated by scripts/inline-shared.mjs from package.json. Do not edit.
|
|
74133
|
-
const PPTX_ANGULAR_VIEWER_VERSION = "1.31.
|
|
74947
|
+
const PPTX_ANGULAR_VIEWER_VERSION = "1.31.4";
|
|
74134
74948
|
|
|
74135
74949
|
/**
|
|
74136
74950
|
* account-page.component.ts: File > Account content.
|
|
@@ -100957,5 +101771,5 @@ function cn(...values) {
|
|
|
100957
101771
|
* Generated bundle index. Do not edit.
|
|
100958
101772
|
*/
|
|
100959
101773
|
|
|
100960
|
-
export { ALIGN_OPTIONS, AUDIENCE_HASH, AUDIENCE_NONCE_KEY, AVATAR_COLOR_SWATCHES, AccessibilityPanelComponent, AccessibilityService, AccountPageComponent, ActionSettingsPanelComponent, AdvancedChartEditorComponent, AnimationAuthorPanelComponent, AnimationPanelComponent, AnimationPlaybackService, AutosaveService, BroadcastDialogComponent, CHART_EDITOR_STYLES, CURSOR_PALETTE, CanvasFitService, ChartAxisOptionsComponent, ChartAxisStyleOptionsComponent, ChartComboTypeOptionsComponent, ChartDataEditorComponent, ChartDataLabelOptionsComponent, ChartDatapointOptionsComponent, ChartDisplayOptionsComponent, ChartElementViewComponent, ChartErrorBarOptionsComponent, ChartMarkerOptionsComponent, ChartPartSelectionService, ChartPrimitivesComponent, ChartRendererComponent, ChartTrendlineOptionsComponent, CollaborationCursorsComponent, CollaborationService, ColorChangedImageComponent, CommentsPanelComponent, CommentsService, ComparePanelComponent, ConnectorRendererComponent, ConnectorTextOverlayComponent, CustomShowsComponent, DATA_TABLE_HEADER_H, DATA_TABLE_KEY_W, DATA_TABLE_PADDING, DATA_TABLE_ROW_H, DEFAULT_BOUNDS, DEFAULT_BROADCAST_SERVER_URL, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, DEFAULT_COLOR_SCHEME, DEFAULT_FILL_COLOR, DEFAULT_LAYOUT, DEFAULT_PALETTE$1 as DEFAULT_PALETTE, DEFAULT_PRINT_SETTINGS, DEFAULT_SLIDE_BACKGROUND, DEFAULT_STROKE_COLOR, DEFAULT_STYLE, DEFAULT_TABLE_ROW_HEIGHT, DEFAULT_TEXT_COLOR$1 as DEFAULT_TEXT_COLOR, DEFAULT_VIEWER_PROFILE, DIRECTIONAL_PRESETS, DIRECTION_OPTIONS, DocumentPropertiesCardComponent, EMBEDDED_FONTS_STYLE_ID, EMPHASIS_PRESETS, ENTRANCE_PRESETS, TEMPLATES as EQUATION_TEMPLATES, EXIT_PRESETS, EditorContextMenuComponent, EditorHistory, EditorStateService, EditorToolbarComponent, EffectsPanelComponent, ElementRendererComponent, EmbeddedFontsService, EncryptedFileDialogComponent, EquationEditorDialogComponent, EquationRendererComponent, EquationTemplateGalleryComponent, ExportProgressModalComponent, ExportService, FieldContextService, FindBarComponent, FindReplaceBarComponent, FollowModeBarComponent, FontEmbeddingListComponent, FontEmbeddingPanelComponent, GALLERY_THEME_PRESETS, GradientPickerComponent, HANDOUT_OPTIONS, HeaderFooterDialogComponent, HyperlinkDialogComponent, ImagePropertiesPanelComponent, InkDrawingService, InkRendererComponent, InsertSmartArtDialogComponent, InspectorPaneHeaderComponent, InspectorPanelComponent, IsMobileService, KeepAnnotationsDialogComponent, LOCALE_CATALOG, LONG_PRESS_DURATION_MS, LONG_PRESS_MOVE_TOLERANCE_PX, LoadContentService, LocalPresencePublisher, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, MediaPreviewComponent, MediaPropertiesPanelComponent, MediaRendererComponent, MediaTrimTimelineComponent, MobileBottomBarComponent, MobileMenuSheetComponent, MobilePresenterViewComponent, MobileSheetComponent, MobileSlidesSheetComponent, MobileToolbarComponent, ModalDialogComponent, Model3DRendererComponent, NotesHandoutCardComponent, NotesPanelComponent, NotesToolbarComponent, OleRendererComponent, POWER_POINT_VIEWER_PROVIDERS, PRESENTER_CHANNEL_NAME, PRESENTER_MSG_ORIGIN, PasswordProtectionDialogComponent, PasswordStrengthMeterComponent, PowerPointViewerComponent, PresentationAnnotationOverlayComponent, PresentationAnnotationsService, PresentationOverlayComponent, PresentationPropertiesPanelComponent, PresentationSettingsCardComponent, PresentationSubtitleBarComponent, PresentationTransitionOverlayComponent, PresenterViewComponent, PresenterWindowService, PrintDialogComponent, PrintService, PrintSettingsPanelComponent, PropertiesDialogComponent, REPEAT_MODE_OPTIONS, RESIZE_HANDLES, RULER_THICKNESS, RemoteSelectionOverlayComponent, RibbonAnimationsSectionComponent, RibbonArrangeSectionComponent, RibbonColorPopoverComponent, RibbonComponent, RibbonDesignSectionComponent, RibbonDrawSectionComponent, RibbonDrawingGroupComponent, RibbonEditingSectionComponent, RibbonFileSectionComponent, RibbonFontControlsComponent, RibbonHomeSectionComponent, RibbonInsertFieldsComponent, RibbonInsertSectionComponent, RibbonParagraphControlsComponent, RibbonPrimaryRowComponent, RibbonReviewSectionComponent, RibbonSlideshowSectionComponent, RibbonTransitionsSectionComponent, RibbonViewSectionComponent, RulerGuidesService, SEQUENCE_OPTIONS, SEVERITY_GROUPS, SEVERITY_LABELS, SHORTCUT_REFERENCE_ITEMS, SLIDE_PX_PER_INCH, SLIDE_TRANSITION_KEYFRAMES, DEFAULT_PALETTE as SMARTART_DEFAULT_PALETTE, PALETTES$1 as SMARTART_PALETTES, SMART_ART_COLOR_SCHEMES, SMART_ART_STYLE_OPTIONS, SUB_ITEM_LABEL, SVG_WARP_PRESETS, SWIPE_MAX_VERTICAL_PX, SWIPE_THRESHOLD_PX, SelectionPaneComponent, SetUpSlideShowDialogComponent, SettingsAppearanceTabComponent, SettingsDialogComponent, SettingsLanguageTabComponent, ShareDialogComponent, ShortcutPanelComponent, ShowOptionsFieldsetComponent, ShowSlidesFieldsetComponent, SignatureStrippedDialogComponent, SignaturesPanelComponent, SignaturesService, SlideCanvasComponent, SlideDefaultInspectorComponent, SlideDiffChangesComponent, SlideDiffRowComponent, SlideDiffThumbnailsComponent, SlideSizeCardComponent, SlideSorterOverlayComponent, SlideThemeOverridePanelComponent, SlidesPanelComponent, SmartArt3DRendererComponent, SmartArt3DService, SmartArtPreviewComponent, SmartArtPropertiesComponent, SmartArtRendererComponent, StatusBarComponent, TABLE_STRUCTURE_TOGGLES, TEXT_DIRECTION_OPTIONS$1 as TEXT_DIRECTION_OPTIONS, THEME_CATALOG, TIMING_CURVE_OPTIONS, TRIGGER_OPTIONS, TYPE_LABELS, TableCellAdvancedFillComponent, TableCellFormattingComponent, TableDataEditorComponent, TablePropertiesComponent, TableRendererComponent, TableResizeOverlayComponent, TableSelectionService, TextAdvancedPanelComponent, ThemeEditorFieldsComponent, ThemeGalleryComponent, ThemeSelectorCardComponent, TitleBarComponent, VALIGN_OPTIONS, VIEWER_THEME, VersionHistoryPanelComponent, ViewerCanvasEditingService, ViewerCollabCursorService, ViewerCollaborationSessionService, ViewerCompareService, ViewerCustomShowsService, ViewerDialogsService, ViewerDocumentPropertiesService, ViewerExportService, ViewerExtraDialogsComponent, ViewerFileIOService, ViewerFindReplaceService, ViewerFormatPainterService, ViewerInspectorPanelService, ViewerKeyboardService, ViewerMobileSheetService, ViewerPresentationModeService, ViewerThemeGalleryService, ViewerTouchGesturesService, ViewerZoomService, WEBM_MIME_CANDIDATES, WriteBackScheduler, ZoomNavigationService, ZoomRendererComponent, ZoomTargetService, addCategory, addCommentToList, addGradientStopPatch, addItem, addSeries, addSubItem, advanceStep, alignPatch, animationFor, annotationMapToInkInserts, applyAcceptedDiff, applyAnimationPreset, applyFindReplacements, applyFormatToElement, applyMove, applyResize, applyTableStylePreset, asMediaElement, assignUserColor, attachTouchGestures, beginNodeEdit, boolFromEvent, bringForward, bringToFront, buildBarActions, buildBroadcastConfig, buildBroadcastViewerUrl, buildCategoryLabels, buildCellParagraphs, buildChartViewModel, buildChromeStyle, buildClearHyperlinkPatch, buildClickGroups, buildColStyles, buildCollaborationConfig, buildComboViewModel, buildCssGradientFromShapeStyle, buildDuotoneFilter, buildDuotoneFilterId, buildEmbeddedFontStyles, buildEquationElement, buildEquationSegment, buildFallbackViewModel, buildFontFaceRule, buildGradientFillCss, buildGridlinesAndLabels, buildHyperlinkPatch, buildInkContainerStyle, buildInkStrokes, buildLegend, buildModel3DContainerStyle, buildModel3DViewModel, buildOleActionModel, buildOleInfoRows, buildPatternFillCss, buildPrintHtmlDocument as buildPrintDocument, buildPropertiesPatch, buildRegionMapViewModel, buildSaveSlides, buildShareUrl, buildSmartArtInsertElement, buildSmartArtNodes, buildStockViewModel, buildSurfaceViewModel, buildTableViewModel, buildTreemapViewModel, buildTrimFragment, buildWaterfallViewModel, buildZeroLine, buildZoomContainerStyle, buildZoomViewModel, bulletIndentPx, canAddTopLevelNode, canRemoveTopLevelNode, canStartBroadcast, canStartShare, canUseClipboard, captionDisplayText, cellRunStyle, cellStyleToStyleMap, cellTdStyle, changeCountLabel, changeIcon, characterSpacingPatch, checkFontAvailable, clampCursorPosition, clampGifDimensions, clampIndex, clampNotesFontSize, clampScale, clampStep, clearAllLocalViewerData, clearAudienceContent, cn, collectAccessibilityIssues, collectElementText, collectSlideText, collectUsedFontFamilies, columnWidthStyle, commitNodeText, computeAlign, computeAxisTitlePrimitives, computeBarRects, computeBubbleRadius, computeCornerHandle, computeDataTablePrimitives, computeDistribute, computeDrawingViewBox, computeErrorBarPrimitives, computeHandleBoxes, computeHandoutLayout, computeIsMobile, computeIsTablet, computeLinePoints, computeLinearRegression, computePageCount, computePieLayout, computePieSlicePath, computePieSlices, computePlotLayout, computeRSquared, computeRadarPoints, computeScatterDots, computeSelectionBoxes, computeSingleSelected, computeSlideIndices, computeSnap, computeStackedBarRects, computeStackedValueRange, computeTextLines, computeTimerProgress, computeTrendlinePrimitives, computeValueRange, convertOmmlToMathMl, copyFormatFromElement, countAccessibilityIssues, countAnnotationStrokes, createCustomShow, createSwipeDismissDrag, createWebrtcBundle, createWebsocketBundle, cssObjectToStyleMap, currentColorScheme, currentLayout, currentStyle, defaultCssVars, defaultRadius, defaultThemeColors, deleteElementsByIds, deleteVersion as deleteRecoveryVersion, demoteNode, deriveModel3DBlobUrl, derivePresenceList, describeSmartArtBounds, disableGlowPatch, disableInnerShadowPatch, disableOuterShadowPatch, disableReflectionPatch, disableSoftEdgePatch, duplicateElementById, durationOf, effectsStateOf, enableGlowPatch, enableInnerShadowPatch, enableOuterShadowPatch, enableReflectionPatch, enableSoftEdgePatch, encodeGif, estimatePageCount, evenColumnWidths, evenRowHeights, exitPresentationFullscreen, extractPathPoints, eyedropperAvailable, fillColorOf, findInSlides, findOwningSlideIndex, findSlideIndexByElementId, fitPolynomial, fitZoom, fontMimeForFormat, fontSizeOf, formatAutoNumber, formatAxisValue, formatBytes, formatCursorLabel, formatElapsed, formatFileSize, formatPropertyDate, formatTime, fpsToFrameIntervalMs, generateBroadcastRoomId, generateCommentId, generateCustomShowId, generatePressureCircles, generateRulerTicks, getClrChangeParams, getContainerStyle, getDuotoneFilterDef, getImageSrc, getLocalStorageUsageSummary, getOleAriaLabel, getOleBadgeLabel, getOleDisplayName, getOleDownloadFileName, getOleTypeColor, getOleTypeLabel, getPasswordStrength, getPatternSvg, getPlaceholderStyle, getVersions as getRecoveryVersions, getResolvedShapeClipPath, getResolvedShapeClipPathFor, getShapeFillStrokeStyle, getSlideBackgroundStyle, getSlideTransitionAnimations, getSmartArtNodeBounds, getSpeechRecognitionCtor, getTextBlockStyle, getTextWarp, getTouchDistance, getWarpCategory, getWarpPath, gradientStateFromStyle, gradientStateOf, gradientStatePatch, gridColumns, groupElements, groupIssuesBySeverity, hasAnimation, hasCopyableFormat, hasExistingLink, hasExitedFullscreen, hasGradientFill, hasPressureVariation, headerLabel, inkViewBox, insertColumn, insertRow, interpolateWidth, isAudienceTab, isBold, isBrowserOpenableMime, isChildNode, isElementInteractive, isInjectableUrl, isItalic, isPpactionUrl, isPresenterMessage, isSigned, isTextElement, isUnderline, isUrlSafe, isValidRoomId, isViewportBackgroundPressTarget, isZoomActivationKey, issueTrackKey, issueTypeLabel, keyToLabel, latexToMathml, linePointsToSvgString, lineSpacingPatch, loadAudienceContent, mergeCaptionResults, mergeDown, mergeRight, mergeSelection, moveElementBy, moveNodeDown, moveNodeUp, msToFrameDelayCs, narrowToCircle, narrowToPolygon, narrowToRect, newChartElement, newEquationElement, newPresetShapeElement, newShapeElement, newSmartArtElement, newTableElement, newTextElement, nextVisibleIndex, nodeBold, nodeEditBox, nodeFillColor, nodeFontColor, nodeIdFromKey, nodeItalic, nodeStyle, normalizeFontFormat, normalizeSlidesPerPage, normalizeValue, numFromEvent, ommlToMathml, ooxmlDashToCssBorderStyle, openNativeEyeDropper, overallStatus, paletteColor, parseAudienceNonce, parseNodeTextarea, partitionSlides, patchChartData, patchChartStyle, patchTableData, patchTextStyle, pendingElementStyles, pickColorByClickFallback, pickSupportedMimeType, planGifFrames, planVideoSegments, pointsToSvgPathD, presenceToCursors, presetByLayout, presetsForCategory, pressuresToWidths, prevVisibleIndex, projectDrawingShapes, promoteNode, provideViewerTheme, radarAngle, radarRingPoints, recordWebm, redistributeColumnWidth, removeAnimation, removeCategory, removeColumn, removeCommentFromList, removeElementAnimation, removeGradientStopPatch, removeNode, removeRow, removeSeries, renderToCanvas, reorderAnimationDown, reorderAnimationUp, replaceInSlides, replaceMatch, requestPresentationFullscreen, resizeElement, resolveCaptionTracks, resolveChartKind, resolveFontVariant, resolveHyperlinkHref, resolveInteractiveElementId, resolveMediaSrc, resolveOleType, resolveParagraphBullet, resolvePresenterNotes, resolveProfileInitial, resolveRegionCode, resolvePalette as resolveSmartArtPalette, resolveThemeCatalogEntry, resolveTransitionDuration, revealedElementStyles, routeOrthogonalConnector, rowStyle, sampleColorFromSlide, sanitizeColor, sanitizeSlideIndex, sanitizeUserName, saveViewerProfile, scanAvailableFonts, searchSlides, seedBroadcastFields, seedHyperlinkDraft, seedPropertiesDraft, seedShareFields, segmentFrameCount, selectValue$2 as selectValue, sendBackward, sendToBack, sequentialColorScale, serializeWriteBack, seriesColor, setAnimationEmphasis, setAnimationEntrance, setAnimationExit, setAxis, setAxisLogScale, setAxisTitleStyle, setCategoryLabel, setCellText, setColorScheme, setDataLabels, setDataPointExplosion, setDataPointFill, setDataPointLabel, setDelay, setDirection, setDuration, setElementPosition, setGridlineStyle, setLayout, setLegend, setNodeStyle, setNodeText, setRepeatCount, setRepeatMode, setSequence, setSeriesChartType, setSeriesColor, setSeriesErrorBars, setSeriesMarker, setSeriesName, setSeriesTrendline, setSeriesValue, setStyle, setTimingCurve, setTitle, setTrigger, setTriggerShapeId, shapeStylePatch, sheetAfterNavigate, shouldUseSvgWarp, showDirectionPicker, showsTemplateAffordance, signatureCountLabel, signatureKey, signatureTimestamp, signerName, statusLabel as slideDiffStatusLabel, slideNumberOf, smartArtNodes, paletteColour as smartArtPaletteColour, snapToGridStep, splitCursorCell, splitMergedCell, statusKind, statusLabel$1 as statusLabel, storeAudienceContent, stringFromEvent$5 as stringFromEvent, strokeColorOf, strokeToInkElement, styleShadowFilter, textAdvancedPatch, textAdvancedStateFromStyle, textAdvancedStateOf, textColorOf, textDirectionPatch, textStyleOf, textStylePatch, themeStyle, themeToCssVars, thumbnailHeight, thumbnailZoom, toggleCommentResolvedInList, toggleNodeBold, toggleNodeItalic, toggleSheet, topLevelNodeCount, transformSelectedTextCase, translationsEn, ungroupElements, updateElementById, updateGlowPatch, updateGradientStopPatch, updateInnerShadowPatch, updateOuterShadowPatch, updateReflectionPatch, vAlignPatch, validatePassword, validatePrintSettings, validateRoomId, valueToY, vermilionDarkColors, vermilionDarkTheme, vermilionLightColors, vermilionLightTheme, vermilionRadius, waypointsToPathD, worstStatus, zoomTargetSlideIndex };
|
|
101774
|
+
export { ALIGN_OPTIONS, AUDIENCE_HASH, AUDIENCE_NONCE_KEY, AVATAR_COLOR_SWATCHES, AccessibilityPanelComponent, AccessibilityService, AccountPageComponent, ActionSettingsPanelComponent, AdvancedChartEditorComponent, AnimationAuthorPanelComponent, AnimationPanelComponent, AnimationPlaybackService, AutosaveService, BroadcastDialogComponent, CHART_EDITOR_STYLES, CURSOR_PALETTE, CanvasFitService, ChartAxisOptionsComponent, ChartAxisStyleOptionsComponent, ChartComboTypeOptionsComponent, ChartDataEditorComponent, ChartDataLabelOptionsComponent, ChartDatapointOptionsComponent, ChartDisplayOptionsComponent, ChartElementViewComponent, ChartErrorBarOptionsComponent, ChartMarkerOptionsComponent, ChartPartSelectionService, ChartPrimitivesComponent, ChartRendererComponent, ChartTrendlineOptionsComponent, CollaborationCursorsComponent, CollaborationService, ColorChangedImageComponent, CommentsPanelComponent, CommentsService, ComparePanelComponent, ConnectorRendererComponent, ConnectorTextOverlayComponent, CustomShowsComponent, DATA_TABLE_HEADER_H, DATA_TABLE_KEY_W, DATA_TABLE_PADDING, DATA_TABLE_ROW_H, DEFAULT_BOUNDS, DEFAULT_BROADCAST_SERVER_URL, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, DEFAULT_COLOR_SCHEME, DEFAULT_FILL_COLOR, DEFAULT_LAYOUT, DEFAULT_PALETTE$1 as DEFAULT_PALETTE, DEFAULT_PRINT_SETTINGS, DEFAULT_SLIDE_BACKGROUND, DEFAULT_STROKE_COLOR, DEFAULT_STYLE, DEFAULT_TABLE_ROW_HEIGHT, DEFAULT_TEXT_COLOR$1 as DEFAULT_TEXT_COLOR, DEFAULT_VIEWER_PROFILE, DIRECTIONAL_PRESETS, DIRECTION_OPTIONS, DocumentPropertiesCardComponent, EMBEDDED_FONTS_STYLE_ID, EMPHASIS_PRESETS, ENTRANCE_PRESETS, TEMPLATES as EQUATION_TEMPLATES, EXIT_PRESETS, EditorContextMenuComponent, EditorHistory, EditorStateService, EditorToolbarComponent, EffectsPanelComponent, ElementRendererComponent, EmbeddedFontsService, EncryptedFileDialogComponent, EquationEditorDialogComponent, EquationRendererComponent, EquationTemplateGalleryComponent, ExportProgressModalComponent, ExportService, FieldContextService, FindBarComponent, FindReplaceBarComponent, FollowModeBarComponent, FontEmbeddingListComponent, FontEmbeddingPanelComponent, GALLERY_THEME_PRESETS, GradientPickerComponent, HANDOUT_OPTIONS, HeaderFooterDialogComponent, HyperlinkDialogComponent, ImagePropertiesPanelComponent, InkDrawingService, InkRendererComponent, InsertSmartArtDialogComponent, InspectorPaneHeaderComponent, InspectorPanelComponent, IsMobileService, KeepAnnotationsDialogComponent, LOCALE_CATALOG, LONG_PRESS_DURATION_MS, LONG_PRESS_MOVE_TOLERANCE_PX, LoadContentService, LocalPresencePublisher, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, MediaPreviewComponent, MediaPropertiesPanelComponent, MediaRendererComponent, MediaTrimTimelineComponent, MobileBottomBarComponent, MobileMenuSheetComponent, MobilePresenterViewComponent, MobileSheetComponent, MobileSlidesSheetComponent, MobileToolbarComponent, ModalDialogComponent, Model3DRendererComponent, NotesHandoutCardComponent, NotesPanelComponent, NotesToolbarComponent, OleRendererComponent, POWER_POINT_VIEWER_PROVIDERS, PRESENTER_CHANNEL_NAME, PRESENTER_MSG_ORIGIN, PasswordProtectionDialogComponent, PasswordStrengthMeterComponent, PowerPointViewerComponent, PresentationAnnotationOverlayComponent, PresentationAnnotationsService, PresentationOverlayComponent, PresentationPropertiesPanelComponent, PresentationSettingsCardComponent, PresentationSubtitleBarComponent, PresentationTransitionOverlayComponent, PresenterViewComponent, PresenterWindowService, PrintDialogComponent, PrintService, PrintSettingsPanelComponent, PropertiesDialogComponent, REPEAT_MODE_OPTIONS, RESIZE_HANDLES, RULER_THICKNESS, RemoteSelectionOverlayComponent, RibbonAnimationsSectionComponent, RibbonArrangeSectionComponent, RibbonColorPopoverComponent, RibbonComponent, RibbonDesignSectionComponent, RibbonDrawSectionComponent, RibbonDrawingGroupComponent, RibbonEditingSectionComponent, RibbonFileSectionComponent, RibbonFontControlsComponent, RibbonHomeSectionComponent, RibbonInsertFieldsComponent, RibbonInsertSectionComponent, RibbonParagraphControlsComponent, RibbonPrimaryRowComponent, RibbonReviewSectionComponent, RibbonSlideshowSectionComponent, RibbonTransitionsSectionComponent, RibbonViewSectionComponent, RulerGuidesService, SEQUENCE_OPTIONS, SEVERITY_GROUPS, SEVERITY_LABELS, SHORTCUT_REFERENCE_ITEMS, SLIDE_PX_PER_INCH, SLIDE_TRANSITION_KEYFRAMES, DEFAULT_PALETTE as SMARTART_DEFAULT_PALETTE, PALETTES$1 as SMARTART_PALETTES, SMART_ART_COLOR_SCHEMES, SMART_ART_STYLE_OPTIONS, SUB_ITEM_LABEL, SVG_WARP_PRESETS, SWIPE_MAX_VERTICAL_PX, SWIPE_THRESHOLD_PX, SelectionPaneComponent, SetUpSlideShowDialogComponent, SettingsAppearanceTabComponent, SettingsDialogComponent, SettingsLanguageTabComponent, ShareDialogComponent, ShortcutPanelComponent, ShowOptionsFieldsetComponent, ShowSlidesFieldsetComponent, SignatureStrippedDialogComponent, SignaturesPanelComponent, SignaturesService, SlideCanvasComponent, SlideDefaultInspectorComponent, SlideDiffChangesComponent, SlideDiffRowComponent, SlideDiffThumbnailsComponent, SlideSizeCardComponent, SlideSorterOverlayComponent, SlideThemeOverridePanelComponent, SlidesPanelComponent, SmartArt3DRendererComponent, SmartArt3DService, SmartArtPreviewComponent, SmartArtPropertiesComponent, SmartArtRendererComponent, StatusBarComponent, TABLE_STRUCTURE_TOGGLES, TEXT_DIRECTION_OPTIONS$1 as TEXT_DIRECTION_OPTIONS, THEME_CATALOG, TIMING_CURVE_OPTIONS, TRIGGER_OPTIONS, TYPE_LABELS, TableCellAdvancedFillComponent, TableCellFormattingComponent, TableDataEditorComponent, TablePropertiesComponent, TableRendererComponent, TableResizeOverlayComponent, TableSelectionService, TextAdvancedPanelComponent, ThemeEditorFieldsComponent, ThemeGalleryComponent, ThemeSelectorCardComponent, TitleBarComponent, VALIGN_OPTIONS, VIEWER_THEME, VersionHistoryPanelComponent, ViewerCanvasEditingService, ViewerCollabCursorService, ViewerCollaborationSessionService, ViewerCompareService, ViewerCustomShowsService, ViewerDialogsService, ViewerDocumentPropertiesService, ViewerExportService, ViewerExtraDialogsComponent, ViewerFileIOService, ViewerFindReplaceService, ViewerFormatPainterService, ViewerInspectorPanelService, ViewerKeyboardService, ViewerMobileSheetService, ViewerPresentationModeService, ViewerThemeGalleryService, ViewerTouchGesturesService, ViewerZoomService, WEBM_MIME_CANDIDATES, WriteBackScheduler, ZoomNavigationService, ZoomRendererComponent, ZoomTargetService, addCategory, addCommentToList, addGradientStopPatch, addItem, addSeries, addSubItem, advanceStep, alignPatch, animationFor, annotationMapToInkInserts, applyAcceptedDiff, applyAnimationPreset, applyFindReplacements, applyFormatToElement, applyMove, applyResize, applyTableStylePreset, asMediaElement, assignUserColor, attachTouchGestures, beginNodeEdit, boolFromEvent, bringForward, bringToFront, buildBarActions, buildBroadcastConfig, buildBroadcastViewerUrl, buildCategoryLabels, buildCellParagraphs, buildChartViewModel, buildChromeStyle, buildClearHyperlinkPatch, buildClickGroups, buildColStyles, buildCollaborationConfig, buildComboViewModel, buildCssGradientFromShapeStyle, buildDuotoneFilter, buildDuotoneFilterId, buildEmbeddedFontStyles, buildEquationElement, buildEquationSegment, buildFallbackViewModel, buildFontFaceRule, buildGradientFillCss, buildGridlinesAndLabels, buildHyperlinkPatch, buildInkContainerStyle, buildInkStrokes, buildLegend, buildModel3DContainerStyle, buildModel3DViewModel, buildOleActionModel, buildOleInfoRows, buildPatternFillCss, buildPrintHtmlDocument as buildPrintDocument, buildPropertiesPatch, buildRegionMapViewModel, buildSaveSlides, buildShareUrl, buildSmartArtInsertElement, buildSmartArtNodes, buildStockViewModel, buildSurfaceViewModel, buildTableViewModel, buildTreemapViewModel, buildTrimFragment, buildWaterfallViewModel, buildZeroLine, buildZoomContainerStyle, buildZoomViewModel, bulletIndentPx, canAddTopLevelNode, canRemoveTopLevelNode, canStartBroadcast, canStartShare, canUseClipboard, captionDisplayText, cellRunStyle, cellStyleToStyleMap, cellTdStyle, changeCountLabel, changeIcon, characterSpacingPatch, checkFontAvailable, clampCursorPosition, clampGifDimensions, clampIndex, clampNotesFontSize, clampScale, clampStep, clearAllLocalViewerData, clearAudienceContent, cn, collectAccessibilityIssues, collectElementText, collectSlideText, collectUsedFontFamilies, columnWidthStyle, commitNodeText, computeAlign, computeAxisTitlePrimitives, computeBarRects, computeBubbleRadius, computeCornerHandle, computeDataTablePrimitives, computeDistribute, computeDrawingViewBox, computeErrorBarPrimitives, computeHandleBoxes, computeHandoutLayout, computeIsMobile, computeIsTablet, computeLinePoints, computeLinearRegression, computePageCount, computePieLayout, computePieSlicePath, computePieSlices, computePlotLayout, computeRSquared, computeRadarPoints, computeScatterDots, computeSelectionBoxes, computeSingleSelected, computeSlideIndices, computeSnap, computeStackedBarRects, computeStackedValueRange, computeTextLines, computeTimerProgress, computeTrendlinePrimitives, computeValueRange, convertOmmlToMathMl, copyFormatFromElement, countAccessibilityIssues, countAnnotationStrokes, createCustomShow, createSwipeDismissDrag, createWebrtcBundle, createWebsocketBundle, cssObjectToStyleMap, currentColorScheme, currentLayout, currentStyle, defaultCssVars, defaultRadius, defaultThemeColors, deleteElementsByIds, deleteVersion as deleteRecoveryVersion, demoteNode, deriveModel3DBlobUrl, derivePresenceList, describeSmartArtBounds, disableGlowPatch, disableInnerShadowPatch, disableOuterShadowPatch, disableReflectionPatch, disableSoftEdgePatch, duplicateElementById, durationOf, effectsStateOf, enableGlowPatch, enableInnerShadowPatch, enableOuterShadowPatch, enableReflectionPatch, enableSoftEdgePatch, encodeGif, estimatePageCount, evenColumnWidths, evenRowHeights, exitPresentationFullscreen, extractPathPoints, eyedropperAvailable, fillColorOf, findInSlides, findOwningSlideIndex, findSlideIndexByElementId, fitPolynomial, fitZoom, fontMimeForFormat, fontSizeOf, formatAutoNumber, formatAxisValue, formatBytes, formatCursorLabel, formatElapsed, formatFileSize, formatPropertyDate, formatTime, fpsToFrameIntervalMs, generateBroadcastRoomId, generateCommentId, generateCustomShowId, generatePressureCircles, generateRulerTicks, getClrChangeParams, getContainerStyle, getDuotoneFilterDef, getImageSrc, getLocalStorageUsageSummary, getOleAriaLabel, getOleBadgeLabel, getOleDisplayName, getOleDownloadFileName, getOleTypeColor, getOleTypeLabel, getPasswordStrength, getPatternSvg, getPlaceholderStyle, getVersions as getRecoveryVersions, getResolvedShapeClipPath, getResolvedShapeClipPathFor, getShapeFillStrokeStyle, getSlideBackgroundStyle, getSlideTransitionAnimations, getSmartArtNodeBounds, getSpeechRecognitionCtor, getTextBlockStyle, getTextWarp, getTouchDistance, getWarpCategory, getWarpPath, gradientStateFromStyle, gradientStateOf, gradientStatePatch, gridColumns, groupElements, groupIssuesBySeverity, hasAnimation, hasCopyableFormat, hasExistingLink, hasExitedFullscreen, hasGradientFill, hasPressureVariation, headerLabel, inkViewBox, insertColumn, insertRow, interpolateWidth, isAudienceTab, isBold, isBrowserOpenableMime, isChildNode, isElementInteractive, isInjectableUrl, isItalic, isPpactionUrl, isPresenterMessage, isSigned, isTextElement, isUnderline, isUrlSafe, isValidRoomId, isViewportBackgroundPressTarget, isZoomActivationKey, issueTrackKey, issueTypeLabel, keyToLabel, latexToMathml, linePointsToSvgString, lineSpacingPatch, loadAudienceContent, mergeCaptionResults, mergeDown, mergeRight, mergeSelection, moveElementBy, moveNodeDown, moveNodeUp, msToFrameDelayCs, narrowToCircle, narrowToPolygon, narrowToRect, newChartElement, newEquationElement, newPresetShapeElement, newShapeElement, newSmartArtElement, newTableElement, newTextElement, nextVisibleIndex, nodeBold, nodeEditBox, nodeFillColor, nodeFontColor, nodeIdFromKey, nodeItalic, nodeStyle, normalizeFontFormat, normalizeSlidesPerPage, normalizeValue, numFromEvent, ommlToMathml, ooxmlDashToCssBorderStyle, openNativeEyeDropper, overallStatus, paletteColor, parseAudienceNonce, parseNodeTextarea, partitionSlides, patchChartData, patchChartStyle, patchTableData, patchTextStyle, pendingElementStyles, pickColorByClickFallback, pickSupportedMimeType, planGifFrames, planVideoSegments, pointsToSvgPathD, presenceToCursors, presetByLayout, presetsForCategory, pressuresToWidths, prevVisibleIndex, projectDrawingShapes, promoteNode, provideViewerTheme, radarAngle, radarRingPoints, recordWebm, redistributeColumnWidth, removeAnimation, removeCategory, removeColumn, removeCommentFromList, removeElementAnimation, removeGradientStopPatch, removeNode, removeRow, removeSeries, renderToCanvas, reorderAnimationDown, reorderAnimationUp, replaceInSlides, replaceMatch, requestPresentationFullscreen, resizeElement, resolveCaptionTracks, resolveChartKind, resolveFontVariant, resolveHyperlinkHref, resolveInteractiveElementId, resolveMediaSrc, resolveOleType, resolveParagraphBullet, resolvePresenterNotes, resolveProfileInitial, resolveRegionCode, resolvePalette as resolveSmartArtPalette, resolveThemeCatalogEntry, resolveTransitionDuration, revealedElementStyles, routeOrthogonalConnector, rowStyle, sampleColorFromSlide, sanitizeColor, sanitizeSlideIndex, sanitizeUserName, saveViewerProfile, scanAvailableFonts, searchSlides, seedBroadcastFields, seedHyperlinkDraft, seedPropertiesDraft, seedShareFields, segmentFrameCount, selectValue$2 as selectValue, sendBackward, sendToBack, sequentialColorScale, serializeWriteBack, seriesColor, setAnimationEmphasis, setAnimationEntrance, setAnimationExit, setAxis, setAxisLogScale, setAxisTitleStyle, setCategoryLabel, setCellText, setColorScheme, setDataLabels, setDataPointExplosion, setDataPointFill, setDataPointLabel, setDelay, setDirection, setDuration, setElementPosition, setGridlineStyle, setLayout, setLegend, setNodeStyle, setNodeText, setRepeatCount, setRepeatMode, setSequence, setSeriesChartType, setSeriesColor, setSeriesErrorBars, setSeriesMarker, setSeriesName, setSeriesTrendline, setSeriesValue, setStyle, setTimingCurve, setTitle, setTrigger, setTriggerShapeId, shapeStylePatch, sheetAfterNavigate, shouldBlockClickAdvance, shouldUseSvgWarp, showDirectionPicker, showsTemplateAffordance, signatureCountLabel, signatureKey, signatureTimestamp, signerName, statusLabel as slideDiffStatusLabel, slideNumberOf, smartArtNodes, paletteColour as smartArtPaletteColour, snapToGridStep, splitCursorCell, splitMergedCell, statusKind, statusLabel$1 as statusLabel, storeAudienceContent, stringFromEvent$5 as stringFromEvent, strokeColorOf, strokeToInkElement, styleShadowFilter, textAdvancedPatch, textAdvancedStateFromStyle, textAdvancedStateOf, textColorOf, textDirectionPatch, textStyleOf, textStylePatch, themeStyle, themeToCssVars, thumbnailHeight, thumbnailZoom, toggleCommentResolvedInList, toggleNodeBold, toggleNodeItalic, toggleSheet, topLevelNodeCount, transformSelectedTextCase, translationsEn, ungroupElements, updateElementById, updateGlowPatch, updateGradientStopPatch, updateInnerShadowPatch, updateOuterShadowPatch, updateReflectionPatch, vAlignPatch, validatePassword, validatePrintSettings, validateRoomId, valueToY, vermilionDarkColors, vermilionDarkTheme, vermilionLightColors, vermilionLightTheme, vermilionRadius, waypointsToPathD, worstStatus, zoomTargetSlideIndex };
|
|
100961
101775
|
//# sourceMappingURL=pptx-angular-viewer.mjs.map
|