pptx-angular-viewer 3.14.0 → 3.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/fesm2022/{pptx-angular-viewer-chat-history-idb-C08A1rjA.mjs → pptx-angular-viewer-chat-history-idb-DIH9Texq.mjs} +2 -2
- package/fesm2022/{pptx-angular-viewer-chat-history-idb-C08A1rjA.mjs.map → pptx-angular-viewer-chat-history-idb-DIH9Texq.mjs.map} +1 -1
- package/fesm2022/{pptx-angular-viewer-pptx-angular-viewer-CrlToiB1.mjs → pptx-angular-viewer-pptx-angular-viewer-CVv5SsHZ.mjs} +430 -249
- package/fesm2022/{pptx-angular-viewer-pptx-angular-viewer-CrlToiB1.mjs.map → pptx-angular-viewer-pptx-angular-viewer-CVv5SsHZ.mjs.map} +1 -1
- package/fesm2022/pptx-angular-viewer.mjs +1 -1
- package/package.json +2 -2
- package/types/pptx-angular-viewer.d.ts +1 -1
|
@@ -7793,6 +7793,33 @@ function glyphEnvelopeMatrix(x0, x1, edge0, edge1, nomTop, nomBottom) {
|
|
|
7793
7793
|
* file, e.g. a signature font on the reader's OS with no webfont match),
|
|
7794
7794
|
* `text-warp-envelope-layout.ts` falls back to the existing per-glyph affine
|
|
7795
7795
|
* / piecewise-affine-slice transform, unchanged.
|
|
7796
|
+
*
|
|
7797
|
+
* COM-verified 2026-09-11 (an 8-shape Arimo Bold fixture, `textCanUp`/
|
|
7798
|
+
* `textCanDown`/`textInflate`/`textDeflate` at default and extreme `adj`): an
|
|
7799
|
+
* outline-vs-PowerPoint ink-scan comparison found a large interior-column
|
|
7800
|
+
* mismatch (~30-40% of box height, max 58-80%) that traced NOT to this
|
|
7801
|
+
* module's point-mapping (verified correct: the affine fallback, driven by
|
|
7802
|
+
* the identical inputs, showed the same error to within measurement noise),
|
|
7803
|
+
* but to `text-warp-envelope-layout.ts`'s `nomTop`/`nomBottom` - the
|
|
7804
|
+
* "undeformed" reference band both this module and the affine path map a
|
|
7805
|
+
* glyph's points FROM - being a fixed fraction of box height regardless of
|
|
7806
|
+
* the actual text's real (font-metric) size. See
|
|
7807
|
+
* `measureLineAscent`'s doc comment there for the fix and the re-measured
|
|
7808
|
+
* numbers. A separate, larger, NOT-yet-fixed gap the same investigation
|
|
7809
|
+
* found: real PowerPoint spaces envelope-warped glyphs to fill the box's own
|
|
7810
|
+
* width edge-to-edge (`textCanUp`/`textCanDown` additionally non-uniformly,
|
|
7811
|
+
* cylinder-projection-like) rather than centring the text at its natural
|
|
7812
|
+
* advance width the way `measureGlyphAdvances`/`startX` do today - out of
|
|
7813
|
+
* scope for that fix, left as an open, separately-scoped issue.
|
|
7814
|
+
*
|
|
7815
|
+
* Open question, not root-caused: the same investigation's COM fixture had
|
|
7816
|
+
* to be rendered from a deck that embeds no font at all (`warp-outline-
|
|
7817
|
+
* noembed-clean.pptx`, Arimo installed as a Windows user font instead) -
|
|
7818
|
+
* PowerPoint refused to open an earlier variant of the SAME fixture that
|
|
7819
|
+
* embedded Arimo Bold as a `ppt/fonts/{guid}.fntdata` part (obfuscated per
|
|
7820
|
+
* ECMA-376 14.2.1, wired via `p:embeddedFontLst`/`embedTrueTypeFonts="1"`)
|
|
7821
|
+
* with error `0x808D1001`. Left as an open note for whoever next touches
|
|
7822
|
+
* embedded-font packaging or generates a COM fixture that needs one.
|
|
7796
7823
|
*/
|
|
7797
7824
|
/**
|
|
7798
7825
|
* Map `y` (a point on the glyph's nominal, undeformed `[nomTop, nomBottom]`
|
|
@@ -8057,6 +8084,65 @@ function measureGlyphAdvances(text, font) {
|
|
|
8057
8084
|
}
|
|
8058
8085
|
return advances;
|
|
8059
8086
|
}
|
|
8087
|
+
/**
|
|
8088
|
+
* The real (ink-measured) ascent of `segments`' text at their own font
|
|
8089
|
+
* sizes, as the tallest `actualBoundingBoxAscent` across every segment on
|
|
8090
|
+
* the line (not a per-character average - one tall glyph anywhere on the
|
|
8091
|
+
* line sets the reference the whole line warps against, matching how a
|
|
8092
|
+
* single baseline/cap-height pair governs a real text run).
|
|
8093
|
+
*
|
|
8094
|
+
* `buildGlyphEnvelope` used to map every glyph's nominal band from a FIXED
|
|
8095
|
+
* `NOMINAL_ENVELOPE_BAND` fraction of the box height (0.15..0.85), assuming
|
|
8096
|
+
* a glyph's own cap height fills that whole span. COM-measured (2026-09-11,
|
|
8097
|
+
* `text-warp-glyph-outline.ts`'s doc comment): for an 8-shape WordArt
|
|
8098
|
+
* fixture (Arimo Bold 44pt captions in 100pt-tall boxes, the `textCanUp` /
|
|
8099
|
+
* `textCanDown` / `textInflate` / `textDeflate` presets at both default and
|
|
8100
|
+
* extreme `adj`), real cap height reaches only about `t = 0.57` of that
|
|
8101
|
+
* nominal span, not `t = 0`, so every glyph's mapped top undershot the
|
|
8102
|
+
* curve's own top edge by the same amount - an outline-vs-COM interior-
|
|
8103
|
+
* column ink-scan comparison measured ~30-40% of box height mean error (max
|
|
8104
|
+
* 58-80%) on BOTH the outline path and the affine fallback alike (both use
|
|
8105
|
+
* this same nominal band, so both shared the bug identically: the residual
|
|
8106
|
+
* lived here, not in the outline point-mapping math). Anchoring `nomTop` to
|
|
8107
|
+
* the line's REAL measured ascent instead - clamped to never exceed the
|
|
8108
|
+
* historical fixed band, so a line whose font genuinely fills (or exceeds)
|
|
8109
|
+
* the nominal span keeps the old, already-validated behaviour unchanged -
|
|
8110
|
+
* dropped the `textInflate`/`textDeflate` interior mean error to ~2.6-2.9%
|
|
8111
|
+
* (max ~9-10%), in the range `text-warp-glyph-slicing.ts`'s doc comment
|
|
8112
|
+
* already documents as the residual once this band mismatch is not also
|
|
8113
|
+
* present. The `textCanUp`/`textCanDown` cases still show an elevated
|
|
8114
|
+
* residual (their interior mean measured ~6-20% even after this fix) that
|
|
8115
|
+
* further investigation traced to a SEPARATE, larger issue: real PowerPoint
|
|
8116
|
+
* spaces envelope-warped glyphs to fill the box's own width edge-to-edge
|
|
8117
|
+
* (measured ink spanning ~99.9% of box width) rather than centering the
|
|
8118
|
+
* text at its natural (unstretched) advance width the way `startX`/
|
|
8119
|
+
* `measureGlyphAdvances` do today, with `textCanUp`/`textCanDown` additionally
|
|
8120
|
+
* showing non-uniform (cylinder-projection-like) horizontal spacing this fix
|
|
8121
|
+
* does not address - both are horizontal-layout gaps, out of scope for this
|
|
8122
|
+
* (purely vertical) band fix and left as an open, separately-scoped issue.
|
|
8123
|
+
*
|
|
8124
|
+
* Returns `undefined` with no DOM (SSR, or a test environment without a 2D
|
|
8125
|
+
* canvas context), so a caller falls back to the previous fixed-fraction
|
|
8126
|
+
* band unchanged, exactly like {@link measureGlyphAdvances}'s own fallback.
|
|
8127
|
+
*/
|
|
8128
|
+
function measureLineAscent(segments) {
|
|
8129
|
+
const ctx = getMeasureCtx$1();
|
|
8130
|
+
if (!ctx) {
|
|
8131
|
+
return undefined;
|
|
8132
|
+
}
|
|
8133
|
+
let maxAscent = 0;
|
|
8134
|
+
for (const segment of segments) {
|
|
8135
|
+
if (!segment.text) {
|
|
8136
|
+
continue;
|
|
8137
|
+
}
|
|
8138
|
+
ctx.font = toCanvasFont$1(segment.font);
|
|
8139
|
+
const ascent = ctx.measureText(segment.text).actualBoundingBoxAscent;
|
|
8140
|
+
if (Number.isFinite(ascent) && ascent > maxAscent) {
|
|
8141
|
+
maxAscent = ascent;
|
|
8142
|
+
}
|
|
8143
|
+
}
|
|
8144
|
+
return maxAscent > 0 ? maxAscent : undefined;
|
|
8145
|
+
}
|
|
8060
8146
|
function startX(align, width, lineWidth) {
|
|
8061
8147
|
if (align === 'right') {
|
|
8062
8148
|
return width - lineWidth;
|
|
@@ -8094,7 +8180,13 @@ function buildGlyphEnvelope(preset, segments, width, height, align, adj, adj2, l
|
|
|
8094
8180
|
const safeLineIndex = Math.min(Math.max(0, Math.floor(lineIndex)), safeLineCount - 1);
|
|
8095
8181
|
const perSegmentAdvances = segments.map((seg) => measureGlyphAdvances(seg.text, seg.font));
|
|
8096
8182
|
const lineWidth = perSegmentAdvances.reduce((sum, advances) => sum + advances.reduce((s, w) => s + w, 0), 0);
|
|
8097
|
-
const { top:
|
|
8183
|
+
const { top: fixedBandTop, bottom: nomBottom } = sliceBand(height * NOMINAL_ENVELOPE_BAND.top, height * NOMINAL_ENVELOPE_BAND.bottom, safeLineIndex, safeLineCount);
|
|
8184
|
+
// Prefer the line's own real ink ascent over the fixed-fraction band (see
|
|
8185
|
+
// `measureLineAscent`'s doc comment for why): never LOWER than the fixed
|
|
8186
|
+
// band's top, so a line whose font already fills (or exceeds) the nominal
|
|
8187
|
+
// span keeps today's behaviour unchanged.
|
|
8188
|
+
const realAscent = measureLineAscent(segments);
|
|
8189
|
+
const nomTop = realAscent !== undefined ? Math.max(fixedBandTop, nomBottom - realAscent) : fixedBandTop;
|
|
8098
8190
|
const placements = [];
|
|
8099
8191
|
let x = startX(align, width, lineWidth);
|
|
8100
8192
|
segments.forEach((segment, segIdx) => {
|
|
@@ -38133,6 +38225,147 @@ function isBevelProfileInverted(bevelType) {
|
|
|
38133
38225
|
return bevelType === 'softRound';
|
|
38134
38226
|
}
|
|
38135
38227
|
|
|
38228
|
+
/**
|
|
38229
|
+
* `a:bevelT/@prst` profile -> SVG height-map shape.
|
|
38230
|
+
*
|
|
38231
|
+
* Split out of `visual-3d-bevel-lighting-tables.ts` to keep both files under
|
|
38232
|
+
* the repo's ~300 LOC guideline; see that module's doc comment for the other
|
|
38233
|
+
* two axes (light rig elevation, material response) and the highlight
|
|
38234
|
+
* DIRECTION, which is resolved separately in `visual-3d-bevel-light.ts`.
|
|
38235
|
+
*
|
|
38236
|
+
* @module render/visual-3d-bevel-lighting-profile
|
|
38237
|
+
*/
|
|
38238
|
+
/**
|
|
38239
|
+
* `a:bevelT/@prst` (and `bevelB`, which shares the same profile vocabulary)
|
|
38240
|
+
* -> height-map shape. ECMA-376 20.1.10.9 describes each profile's silhouette
|
|
38241
|
+
* (a "circular", "flat sloped", "crossed", "art-deco stepped" etc.
|
|
38242
|
+
* cross-section); these factors were ORIGINALLY grouped into 3
|
|
38243
|
+
* physically-motivated buckets by that description (curved / faceted /
|
|
38244
|
+
* steep-narrow) rather than 12 independent hand-tuned entries, reasoned from
|
|
38245
|
+
* ECMA-376 alone.
|
|
38246
|
+
*
|
|
38247
|
+
* COM-MEASURED 2026-09 (real PowerPoint `Slide.Export`, mid-grey `matte`
|
|
38248
|
+
* square, `threePt` rig / `dir="t"`, `orthographicFront` camera, both a 6pt
|
|
38249
|
+
* and a 24pt `a:bevelT`, a line of 40 brightness samples from the top edge
|
|
38250
|
+
* inward for all 12 profiles): fitting these SAME 3 factors (grid search,
|
|
38251
|
+
* minimum RMSE against the measured curve, both depths jointly) against real
|
|
38252
|
+
* cross-section data overturned the bucket story for 3 profiles.
|
|
38253
|
+
* `circle`/`convex`/`softRound`/`divot` (curved) and `angle`/`cross`/
|
|
38254
|
+
* `coolSlant`/`riblet`/`artDeco` (faceted) fit closely (RMSE 1-7 brightness
|
|
38255
|
+
* units) with factors in the same rough range as the original reasoning, so
|
|
38256
|
+
* their bucket membership held up. `relaxedInset`, `slope` and `hardEdge`
|
|
38257
|
+
* did NOT: all three measured a genuine BRIGHT-BUMP-THEN-DARK-TROUGH double
|
|
38258
|
+
* transition partway through the ramp (e.g. `hardEdge` at 24pt: baseline 133
|
|
38259
|
+
* -> peaks ~139 -> drops to 67 -> recovers), which this filter's single
|
|
38260
|
+
* monotonic blur(+erode) height map (one bell-shaped slope lobe) cannot
|
|
38261
|
+
* reproduce - the fit pushes `surfaceScaleFactor` to the largest tested
|
|
38262
|
+
* value trying to reach the trough depth, landing the LARGEST relief factor
|
|
38263
|
+
* of any profile, the opposite of the pre-2026-09 "slope/hardEdge are
|
|
38264
|
+
* low-relief" assumption (`slope`/`hardEdge` were previously reasoned as
|
|
38265
|
+
* "steep/narrow" with REDUCED relief; `relaxedInset` was previously grouped
|
|
38266
|
+
* as "curved" with full relief and no erode at all). Their factors below are
|
|
38267
|
+
* therefore the closest achievable fit within this 3-parameter chain, not a
|
|
38268
|
+
* claim of a clean match (RMSE 12-19, versus 1-7 for the other 9); a proper
|
|
38269
|
+
* fix needs a genuinely non-monotonic (two-lobe) height-map primitive chain,
|
|
38270
|
+
* out of scope for this pass - see `docs/guide/limitations.md`. The
|
|
38271
|
+
* direction-independence these three still show (`measuredUniform`) is
|
|
38272
|
+
* unaffected: it is a separate, already-COM-confirmed finding (see
|
|
38273
|
+
* `visual-3d-bevel-light.ts`'s module doc comment) about which CARDINAL EDGE
|
|
38274
|
+
* lights up, not about the cross-section ramp shape this campaign measures.
|
|
38275
|
+
* Scripts (scratch, not committed, same convention as `com-acceptance.mjs`):
|
|
38276
|
+
* `scripts/make-bevel-profile-fixture.mjs` (fixture, all 12
|
|
38277
|
+
* profiles x 2 depths), `scripts/measure-bevel-profile-com.ps1`
|
|
38278
|
+
* (COM export + 40-point sampler), `scripts/fit-bevel-profile-com.mjs`
|
|
38279
|
+
* (grid-search fit; a closed-form Gaussian-CDF reimplementation of the
|
|
38280
|
+
* primitive chain, not a headless-browser render - Playwright's Chromium
|
|
38281
|
+
* launch hangs indefinitely via a plain script in this environment, though
|
|
38282
|
+
* `bunx playwright test` itself works fine, used to independently verify the
|
|
38283
|
+
* metal/circle routing conclusion in `visual-3d-bevel-lighting-routing.ts`).
|
|
38284
|
+
* The raw 10-point-per-profile table (24pt depth) is pinned in
|
|
38285
|
+
* `visual-3d-bevel-lighting-tables.test.ts`; the full 40-point x 2-depth
|
|
38286
|
+
* table is in the task report.
|
|
38287
|
+
*/
|
|
38288
|
+
const BEVEL_PROFILE_HEIGHT_MAP = {
|
|
38289
|
+
circle: { blurFactor: 0.35, surfaceScaleFactor: 0.65, measuredUniform: false },
|
|
38290
|
+
convex: {
|
|
38291
|
+
blurFactor: 0.18,
|
|
38292
|
+
morphologyFactor: 0.4,
|
|
38293
|
+
surfaceScaleFactor: 0.2,
|
|
38294
|
+
measuredUniform: false,
|
|
38295
|
+
},
|
|
38296
|
+
softRound: {
|
|
38297
|
+
blurFactor: 0.25,
|
|
38298
|
+
morphologyFactor: 0.4,
|
|
38299
|
+
surfaceScaleFactor: 0.65,
|
|
38300
|
+
measuredUniform: false,
|
|
38301
|
+
},
|
|
38302
|
+
relaxedInset: {
|
|
38303
|
+
blurFactor: 0.35,
|
|
38304
|
+
morphologyFactor: 0.5,
|
|
38305
|
+
surfaceScaleFactor: 1.5,
|
|
38306
|
+
measuredUniform: false,
|
|
38307
|
+
},
|
|
38308
|
+
divot: { blurFactor: 0.18, surfaceScaleFactor: 0.5, measuredUniform: false },
|
|
38309
|
+
angle: {
|
|
38310
|
+
blurFactor: 0.35,
|
|
38311
|
+
morphologyFactor: 0.4,
|
|
38312
|
+
surfaceScaleFactor: 0.35,
|
|
38313
|
+
measuredUniform: false,
|
|
38314
|
+
},
|
|
38315
|
+
cross: {
|
|
38316
|
+
blurFactor: 0.12,
|
|
38317
|
+
morphologyFactor: 0.18,
|
|
38318
|
+
surfaceScaleFactor: 0.2,
|
|
38319
|
+
measuredUniform: false,
|
|
38320
|
+
},
|
|
38321
|
+
coolSlant: {
|
|
38322
|
+
blurFactor: 0.25,
|
|
38323
|
+
morphologyFactor: 0.06,
|
|
38324
|
+
surfaceScaleFactor: 0.5,
|
|
38325
|
+
measuredUniform: false,
|
|
38326
|
+
},
|
|
38327
|
+
riblet: {
|
|
38328
|
+
blurFactor: 0.25,
|
|
38329
|
+
surfaceScaleFactor: 0.5,
|
|
38330
|
+
measuredUniform: false,
|
|
38331
|
+
},
|
|
38332
|
+
artDeco: {
|
|
38333
|
+
blurFactor: 0.18,
|
|
38334
|
+
morphologyFactor: 0.32,
|
|
38335
|
+
surfaceScaleFactor: 0.35,
|
|
38336
|
+
measuredUniform: false,
|
|
38337
|
+
},
|
|
38338
|
+
// `relaxedInset`/`slope`/`hardEdge` (see this table's doc comment): COM
|
|
38339
|
+
// measured a genuine BRIGHT-BUMP-THEN-DARK-TROUGH double transition for
|
|
38340
|
+
// all three, which a single monotonic blur(+erode) ramp cannot reproduce
|
|
38341
|
+
// (its height field has one bell-shaped slope lobe, so the diffuse/
|
|
38342
|
+
// specular response can only rise-then-settle, never rise-then-undershoot-
|
|
38343
|
+
// then-settle). These factors are the closest achievable fit within the
|
|
38344
|
+
// existing 3-parameter primitive chain (the grid search pushed
|
|
38345
|
+
// `surfaceScaleFactor` to its upper bound trying to reach the measured
|
|
38346
|
+
// trough depth), not a claim of a clean match; see the doc comment.
|
|
38347
|
+
slope: {
|
|
38348
|
+
blurFactor: 0.55,
|
|
38349
|
+
morphologyFactor: 0.5,
|
|
38350
|
+
surfaceScaleFactor: 1.5,
|
|
38351
|
+
measuredUniform: true,
|
|
38352
|
+
},
|
|
38353
|
+
hardEdge: {
|
|
38354
|
+
blurFactor: 0.55,
|
|
38355
|
+
morphologyFactor: 0.5,
|
|
38356
|
+
surfaceScaleFactor: 1.5,
|
|
38357
|
+
measuredUniform: true,
|
|
38358
|
+
},
|
|
38359
|
+
};
|
|
38360
|
+
const DEFAULT_HEIGHT_MAP = {
|
|
38361
|
+
blurFactor: 0.4,
|
|
38362
|
+
surfaceScaleFactor: 0.8,
|
|
38363
|
+
measuredUniform: false,
|
|
38364
|
+
};
|
|
38365
|
+
function getBevelProfileHeightMap(bevelType) {
|
|
38366
|
+
return BEVEL_PROFILE_HEIGHT_MAP[bevelType] ?? DEFAULT_HEIGHT_MAP;
|
|
38367
|
+
}
|
|
38368
|
+
|
|
38136
38369
|
/**
|
|
38137
38370
|
* Material -> `feDiffuseLighting`/`feSpecularLighting` response table.
|
|
38138
38371
|
*
|
|
@@ -38165,12 +38398,26 @@ const white = '#ffffff';
|
|
|
38165
38398
|
* .ts`'s module doc table) found this module's `metal` numbers give a mixed
|
|
38166
38399
|
* result: `matte` improved clearly over the old box-shadow approach (56.3 ->
|
|
38167
38400
|
* 34.8 mean error) while `metal` did not (61.2 -> 59.7, and `metal`/`circle`
|
|
38168
|
-
* specifically got WORSE, 54.9 -> 80.1) - the constants below
|
|
38169
|
-
* flagged
|
|
38170
|
-
*
|
|
38171
|
-
* around the `matte`/`metal` anchors by
|
|
38172
|
-
* `metal` but softer, matte/powder variants
|
|
38173
|
-
* COM-measured at all.
|
|
38401
|
+
* specifically got WORSE, 54.9 -> 80.1) - the constants below were therefore
|
|
38402
|
+
* flagged UNVALIDATED for `metal`, and `metal`/`circle` was ROUTED to the
|
|
38403
|
+
* legacy box-shadow model (`visual-3d-bevel-lighting-routing.ts`). The other
|
|
38404
|
+
* materials are positioned between/around the `matte`/`metal` anchors by
|
|
38405
|
+
* category (glossy plastics near `metal` but softer, matte/powder variants
|
|
38406
|
+
* near `matte`), not independently COM-measured at all.
|
|
38407
|
+
*
|
|
38408
|
+
* RESOLVED for `metal`/`circle` (2026-09, the bevel-profile cross-section
|
|
38409
|
+
* campaign, `visual-3d-bevel-lighting-tables.ts`'s `BEVEL_PROFILE_HEIGHT_MAP`
|
|
38410
|
+
* doc comment): re-fitting `circle`'s profile-table entry against real COM
|
|
38411
|
+
* cross-section data (unrelated to material tuning) changed
|
|
38412
|
+
* `surfaceScaleFactor` from 1 to 0.65, and with these SAME `metal` constants
|
|
38413
|
+
* (unchanged from the paragraph above) that alone brought `metal`/`circle`'s
|
|
38414
|
+
* mean error to 39.5 against the SAME 54.9 baseline - confirmed against
|
|
38415
|
+
* fresh COM ground truth AND an actual headless-Chromium rasterisation of
|
|
38416
|
+
* the real filter chain (not just the closed-form model this module's own
|
|
38417
|
+
* campaigns otherwise used), so `metal`/`circle` no longer routes; see
|
|
38418
|
+
* `visual-3d-bevel-lighting-routing.ts`'s doc comment for the numbers and a
|
|
38419
|
+
* separate, NOT-landed attempt at fixing the flat-interior specular
|
|
38420
|
+
* saturation defect below.
|
|
38174
38421
|
*/
|
|
38175
38422
|
const MATERIAL_LIGHTING = {
|
|
38176
38423
|
matte: {
|
|
@@ -38247,10 +38494,14 @@ const MATERIAL_LIGHTING = {
|
|
|
38247
38494
|
// (`angle`: baseline ~70, now ~19-27; `hardEdge`: baseline ~69.5, now 44;
|
|
38248
38495
|
// `softRound`: baseline ~50, now 6.5-19). `circle` alone could NOT be
|
|
38249
38496
|
// brought below baseline with any tested combination of these four
|
|
38250
|
-
// parameters (tried down to `surfaceScaleMultiplier` 0.15 and up
|
|
38251
|
-
//
|
|
38252
|
-
//
|
|
38253
|
-
//
|
|
38497
|
+
// MATERIAL parameters (tried down to `surfaceScaleMultiplier` 0.15 and up
|
|
38498
|
+
// to 2.5) against the then-current (ECMA-376-reasoned) profile table, and
|
|
38499
|
+
// was routed to the legacy `box-shadow` model instead of shipping a
|
|
38500
|
+
// regression. SUPERSEDED 2026-09: re-fitting the PROFILE table's own
|
|
38501
|
+
// `circle` entry against real COM data (a change orthogonal to these
|
|
38502
|
+
// material constants) resolved it without touching the numbers below; see
|
|
38503
|
+
// this file's module doc comment and `visual-3d-bevel-lighting-routing
|
|
38504
|
+
// .ts`.
|
|
38254
38505
|
//
|
|
38255
38506
|
// A SEPARATE, more severe issue was found (2026-09, while attempting an
|
|
38256
38507
|
// ambient/wrap-term fix for the `circle` routing above) that this
|
|
@@ -38347,9 +38598,12 @@ function getMaterialLighting(material) {
|
|
|
38347
38598
|
* Split out of `visual-3d-bevel-lighting.ts` to keep that module under the
|
|
38348
38599
|
* repo's ~300 LOC guideline. Three independent axes feed the filter this
|
|
38349
38600
|
* module's data drives: bevel PROFILE shape (`a:bevelT/@prst`, ECMA-376
|
|
38350
|
-
* 20.1.10.9 `ST_BevelPresetType
|
|
38351
|
-
*
|
|
38352
|
-
*
|
|
38601
|
+
* 20.1.10.9 `ST_BevelPresetType`, re-exported here but defined in
|
|
38602
|
+
* `visual-3d-bevel-lighting-profile.ts`, itself split out for the same LOC
|
|
38603
|
+
* reason), light rig ELEVATION/specular character (`a:lightRig/@rig`,
|
|
38604
|
+
* ECMA-376 20.1.10.36 `ST_LightRigType`, defined below), and MATERIAL
|
|
38605
|
+
* response (`a:sp3d/@prstMaterial`, ECMA-376 20.1.10.50 `ST_PresetMaterialType`,
|
|
38606
|
+
* re-exported from `visual-3d-bevel-lighting-material.ts`).
|
|
38353
38607
|
* The highlight/shadow DIRECTION (azimuth) itself is mostly resolved
|
|
38354
38608
|
* elsewhere: `visual-3d-bevel-light`'s already COM-measured cardinal-snap
|
|
38355
38609
|
* vector supplies the base azimuth from `a:lightRig/@dir`, and this module's
|
|
@@ -38374,80 +38628,6 @@ function getMaterialLighting(material) {
|
|
|
38374
38628
|
*
|
|
38375
38629
|
* @module render/visual-3d-bevel-lighting-tables
|
|
38376
38630
|
*/
|
|
38377
|
-
/**
|
|
38378
|
-
* `a:bevelT/@prst` (and `bevelB`, which shares the same profile vocabulary)
|
|
38379
|
-
* -> height-map shape. ECMA-376 20.1.10.9 describes each profile's silhouette
|
|
38380
|
-
* (a "circular", "flat sloped", "crossed", "art-deco stepped" etc. cross-
|
|
38381
|
-
* section); this table groups the 12 values by that description into 3
|
|
38382
|
-
* physically-motivated buckets rather than 12 independent hand-tuned entries:
|
|
38383
|
-
*
|
|
38384
|
-
* - **Curved** (`circle`, `convex`, `softRound`, `relaxedInset`, `divot`):
|
|
38385
|
-
* a smooth, rounded cross-section -> wide Gaussian-only ramp, full relief.
|
|
38386
|
-
* - **Faceted** (`angle`, `cross`, `coolSlant`, `riblet`, `artDeco`): a flat
|
|
38387
|
-
* angled facet with a visible crease -> a medium blur PLUS a light erode so
|
|
38388
|
-
* the ramp gets a crisper inner edge (the crease), full relief.
|
|
38389
|
-
* - **Steep/narrow** (`slope`, `hardEdge`): COM-measured to show no clean
|
|
38390
|
-
* directional signal (see {@link BevelProfileHeightMap.measuredUniform});
|
|
38391
|
-
* a narrow, heavily-eroded ramp with reduced relief reproduces that
|
|
38392
|
-
* physically instead of guessing a highlight side.
|
|
38393
|
-
*/
|
|
38394
|
-
const BEVEL_PROFILE_HEIGHT_MAP = {
|
|
38395
|
-
circle: { blurFactor: 0.55, surfaceScaleFactor: 1, measuredUniform: false },
|
|
38396
|
-
convex: { blurFactor: 0.6, surfaceScaleFactor: 1.05, measuredUniform: false },
|
|
38397
|
-
softRound: { blurFactor: 0.5, surfaceScaleFactor: 0.9, measuredUniform: false },
|
|
38398
|
-
relaxedInset: { blurFactor: 0.45, surfaceScaleFactor: 0.85, measuredUniform: false },
|
|
38399
|
-
divot: { blurFactor: 0.4, surfaceScaleFactor: 0.8, measuredUniform: false },
|
|
38400
|
-
angle: {
|
|
38401
|
-
blurFactor: 0.32,
|
|
38402
|
-
morphologyFactor: 0.12,
|
|
38403
|
-
surfaceScaleFactor: 1,
|
|
38404
|
-
measuredUniform: false,
|
|
38405
|
-
},
|
|
38406
|
-
cross: {
|
|
38407
|
-
blurFactor: 0.3,
|
|
38408
|
-
morphologyFactor: 0.15,
|
|
38409
|
-
surfaceScaleFactor: 0.95,
|
|
38410
|
-
measuredUniform: false,
|
|
38411
|
-
},
|
|
38412
|
-
coolSlant: {
|
|
38413
|
-
blurFactor: 0.28,
|
|
38414
|
-
morphologyFactor: 0.14,
|
|
38415
|
-
surfaceScaleFactor: 0.95,
|
|
38416
|
-
measuredUniform: false,
|
|
38417
|
-
},
|
|
38418
|
-
riblet: {
|
|
38419
|
-
blurFactor: 0.26,
|
|
38420
|
-
morphologyFactor: 0.18,
|
|
38421
|
-
surfaceScaleFactor: 0.9,
|
|
38422
|
-
measuredUniform: false,
|
|
38423
|
-
},
|
|
38424
|
-
artDeco: {
|
|
38425
|
-
blurFactor: 0.24,
|
|
38426
|
-
morphologyFactor: 0.2,
|
|
38427
|
-
surfaceScaleFactor: 1,
|
|
38428
|
-
measuredUniform: false,
|
|
38429
|
-
},
|
|
38430
|
-
slope: {
|
|
38431
|
-
blurFactor: 0.12,
|
|
38432
|
-
morphologyFactor: 0.35,
|
|
38433
|
-
surfaceScaleFactor: 0.4,
|
|
38434
|
-
measuredUniform: true,
|
|
38435
|
-
},
|
|
38436
|
-
hardEdge: {
|
|
38437
|
-
blurFactor: 0.1,
|
|
38438
|
-
morphologyFactor: 0.4,
|
|
38439
|
-
surfaceScaleFactor: 0.35,
|
|
38440
|
-
measuredUniform: true,
|
|
38441
|
-
},
|
|
38442
|
-
};
|
|
38443
|
-
const DEFAULT_HEIGHT_MAP = {
|
|
38444
|
-
blurFactor: 0.4,
|
|
38445
|
-
surfaceScaleFactor: 0.8,
|
|
38446
|
-
measuredUniform: false,
|
|
38447
|
-
};
|
|
38448
|
-
function getBevelProfileHeightMap(bevelType) {
|
|
38449
|
-
return BEVEL_PROFILE_HEIGHT_MAP[bevelType] ?? DEFAULT_HEIGHT_MAP;
|
|
38450
|
-
}
|
|
38451
38631
|
/**
|
|
38452
38632
|
* `a:lightRig/@rig` -> elevation/sharpness/direction. COM-CALIBRATED
|
|
38453
38633
|
* (2026-09, real PowerPoint `Slide.Export`, mid-grey #808080 1.4in square,
|
|
@@ -38638,7 +38818,7 @@ function resolveLayer(index, bevelType, widthEmu, heightEmu, isBottom, scene, ma
|
|
|
38638
38818
|
|
|
38639
38819
|
/**
|
|
38640
38820
|
* Legacy `box-shadow` routing for a `material`/profile combination the SVG
|
|
38641
|
-
* lighting filter cannot
|
|
38821
|
+
* lighting filter cannot beat.
|
|
38642
38822
|
*
|
|
38643
38823
|
* Split out of `visual-3d-bevel-lighting.ts` to keep that file under the
|
|
38644
38824
|
* repo's ~300 LOC guideline.
|
|
@@ -38646,26 +38826,45 @@ function resolveLayer(index, bevelType, widthEmu, heightEmu, isBottom, scene, ma
|
|
|
38646
38826
|
* @module render/visual-3d-bevel-lighting-routing
|
|
38647
38827
|
*/
|
|
38648
38828
|
/**
|
|
38649
|
-
* `material|profile` pairs that
|
|
38650
|
-
* approach
|
|
38651
|
-
* .
|
|
38652
|
-
*
|
|
38653
|
-
* `metal|circle
|
|
38654
|
-
* `specularExponent
|
|
38655
|
-
*
|
|
38656
|
-
*
|
|
38657
|
-
*
|
|
38658
|
-
* `
|
|
38659
|
-
*
|
|
38660
|
-
*
|
|
38661
|
-
*
|
|
38662
|
-
*
|
|
38663
|
-
*
|
|
38664
|
-
*
|
|
38665
|
-
*
|
|
38666
|
-
*
|
|
38667
|
-
|
|
38668
|
-
|
|
38829
|
+
* `material|profile` pairs that measure WORSE than the legacy `box-shadow`
|
|
38830
|
+
* approach and therefore route to the legacy model instead of shipping a
|
|
38831
|
+
* regression. Empty as of the 2026-09 bevel-profile-cross-section campaign
|
|
38832
|
+
* (`visual-3d-bevel-lighting-tables.ts`'s `BEVEL_PROFILE_HEIGHT_MAP` doc
|
|
38833
|
+
* comment): `metal|circle` was the one routed pair (a grid search over
|
|
38834
|
+
* `diffuseConstant`/`specularConstant`/`specularExponent`/
|
|
38835
|
+
* `surfaceScaleMultiplier` against the OLD, ECMA-376-reasoned profile table
|
|
38836
|
+
* could not bring it at or below baseline in any direction - see this file's
|
|
38837
|
+
* git history for that campaign's numbers). Re-fitting `circle`'s
|
|
38838
|
+
* `BEVEL_PROFILE_HEIGHT_MAP` entry against real COM cross-section data
|
|
38839
|
+
* (`surfaceScaleFactor` 1 -> 0.65) changed the balance enough that the
|
|
38840
|
+
* UNCHANGED material constants now beat the box-shadow baseline in every
|
|
38841
|
+
* `a:lightRig/@dir`, confirmed two ways: fresh COM ground truth (mid-grey
|
|
38842
|
+
* `circle`/metal square, 24pt bevel, `threePt` rig, all 4 directions,
|
|
38843
|
+
* 0.15in-from-edge highlight+shadow sampling, script
|
|
38844
|
+
* `scripts/make-bevel-material-fixture.mjs` +
|
|
38845
|
+
* `measure-bevel-material-com.ps1`) and an ACTUAL headless-Chromium
|
|
38846
|
+
* rasterisation of the real filter primitive chain (a one-off Playwright
|
|
38847
|
+
* spec, not committed) sampled the same points: mean absolute error 39.5
|
|
38848
|
+
* (baseline was 54.9). The same real-browser check also re-confirmed
|
|
38849
|
+
* `angle`/`hardEdge`/`softRound` still beat their baselines (41.5/62.0/27.5
|
|
38850
|
+
* against baselines ~70/~69.5/~50) with the new profile table, so nothing
|
|
38851
|
+
* newly regressed.
|
|
38852
|
+
*
|
|
38853
|
+
* A candidate fix for the SEPARATE flat-interior specular-saturation defect
|
|
38854
|
+
* (masking `feSpecularLighting`'s contribution to the actual curved bevel
|
|
38855
|
+
* band via a `feComponentTransfer`/`feColorMatrix` triangle-of-height mask,
|
|
38856
|
+
* `1 - |2*height-1|`, zero at the flat cap) was measured against the same
|
|
38857
|
+
* real-browser pipeline for all 4 profiles and made EVERY ONE of them worse,
|
|
38858
|
+
* often drastically (`circle` 39.5 -> 103.5, `angle` 41.5 -> 104.0,
|
|
38859
|
+
* `hardEdge` 62.0 -> 94.0, `softRound` 27.5 -> 89.0): the mask's `feFuncA
|
|
38860
|
+
* type="table" tableValues="0 1 0"` zeroes specular well before COM's real
|
|
38861
|
+
* highlight has decayed at the 0.15in sample offset (the mask, tuned only to
|
|
38862
|
+
* the height VALUE crossing 0.5, does not track where the actual specular
|
|
38863
|
+
* lobe sits for a high `specularExponent`), so this attempt was measured and
|
|
38864
|
+
* NOT landed. See `docs/guide/limitations.md` for the still-open
|
|
38865
|
+
* flat-interior saturation defect this was meant to fix.
|
|
38866
|
+
*/
|
|
38867
|
+
const LEGACY_BEVEL_ROUTING = new Set();
|
|
38669
38868
|
/**
|
|
38670
38869
|
* Whether a `material`/`profile` combination is routed to the legacy
|
|
38671
38870
|
* `box-shadow` bevel model instead of the SVG lighting filter.
|
|
@@ -38737,12 +38936,12 @@ function isRoutedToLegacyBevelShadow(material, profile) {
|
|
|
38737
38936
|
* `metal`/`circle` below its baseline in any direction (the two targets pull
|
|
38738
38937
|
* in opposite directions as `surfaceScale` changes - see
|
|
38739
38938
|
* `visual-3d-bevel-lighting-routing.ts`'s `isRoutedToLegacyBevelShadow` doc
|
|
38740
|
-
* comment), so `metal`/`circle`
|
|
38741
|
-
*
|
|
38742
|
-
*
|
|
38743
|
-
*
|
|
38744
|
-
*
|
|
38745
|
-
*
|
|
38939
|
+
* comment), so `metal`/`circle` ROUTED to the legacy `box-shadow` model at
|
|
38940
|
+
* the time (SUPERSEDED 2026-09 below; it no longer routes). The "before"
|
|
38941
|
+
* numbers are large because this campaign scores absolute brightness match,
|
|
38942
|
+
* not just highlight/shadow SIGN agreement (all `getBevelShadow`'s
|
|
38943
|
+
* box-shadow output was previously verified against). Scripts: scratch
|
|
38944
|
+
* tooling, same convention as `com-acceptance.mjs`.
|
|
38746
38945
|
*
|
|
38747
38946
|
* ## Re-run against the CURRENT `threePt` elevationDeg (2026-09, post-lightRig-recalibration)
|
|
38748
38947
|
*
|
|
@@ -38800,6 +38999,16 @@ function isRoutedToLegacyBevelShadow(material, profile) {
|
|
|
38800
38999
|
* material against this same COM ground truth. Neither was completed in
|
|
38801
39000
|
* this pass; see `docs/guide/limitations.md`.
|
|
38802
39001
|
*
|
|
39002
|
+
* ## 2026-09 bevel-profile cross-section + specular-masking follow-up
|
|
39003
|
+
*
|
|
39004
|
+
* Kept in the files they most directly touch (LOC budget): the 12
|
|
39005
|
+
* `a:bevelT/@prst` height-map SHAPES were fit against real COM cross-section
|
|
39006
|
+
* curves for the first time (`visual-3d-bevel-lighting-tables.ts`'s doc +
|
|
39007
|
+
* pinned table in its `.test.ts`), changing `circle`'s `surfaceScaleFactor`
|
|
39008
|
+
* enough that `metal`/`circle` now beats baseline unrouted; a follow-up
|
|
39009
|
+
* specular-band-masking attempt at the saturation defect above was measured
|
|
39010
|
+
* and made things WORSE (`visual-3d-bevel-lighting-routing.ts`'s doc).
|
|
39011
|
+
*
|
|
38803
39012
|
* @module render/visual-3d-bevel-lighting
|
|
38804
39013
|
*/
|
|
38805
39014
|
/**
|
|
@@ -39236,19 +39445,13 @@ function applyHomography(h, p) {
|
|
|
39236
39445
|
*
|
|
39237
39446
|
* 1. The shape's flat picture plane is a unit square in its own local XY
|
|
39238
39447
|
* plane (`z=0`), corners at `(-0.5,-0.5) .. (0.5,0.5)`.
|
|
39239
|
-
* 2. Each corner is projected by {@link projectCorner}:
|
|
39240
|
-
*
|
|
39241
|
-
*
|
|
39242
|
-
*
|
|
39243
|
-
*
|
|
39244
|
-
*
|
|
39245
|
-
*
|
|
39246
|
-
* 3. The pinhole secondary term's focal length is `f = 1/tan(fov/2)` (the
|
|
39247
|
-
* same FOV <-> perspective-distance relationship `visual-3d-camera-fov`
|
|
39248
|
-
* already uses), so `lat=lon=rev=0` reproduces an EXACT identity
|
|
39249
|
-
* homography - the same trivial case `orthographicFront` is COM-measured
|
|
39250
|
-
* to produce - by construction (the secondary term is architecturally
|
|
39251
|
-
* zero whenever either axis is zero, so this holds regardless of `fov`).
|
|
39448
|
+
* 2. Each corner is projected by {@link projectCorner}: an ORTHOGRAPHIC
|
|
39449
|
+
* (parallel, no perspective divide) rotation-composition transform - see
|
|
39450
|
+
* that function's own doc comment for the exact formula and its
|
|
39451
|
+
* derivation.
|
|
39452
|
+
* 3. `lat=lon=rev=0` reproduces an EXACT identity homography - the same
|
|
39453
|
+
* trivial case `orthographicFront` is COM-measured to produce - by
|
|
39454
|
+
* construction (`cos(0)=1`, every other term vanishes).
|
|
39252
39455
|
* 4. `rev` (roll about the view axis) commutes with the projection: rolling
|
|
39253
39456
|
* the camera about its own aim axis is exactly a 2D rotation of the
|
|
39254
39457
|
* already-projected image, applied here as a post-projection step rather
|
|
@@ -39259,88 +39462,96 @@ function applyHomography(h, p) {
|
|
|
39259
39462
|
* `visual-3d-camera-homography`'s existing `homographyToMatrix3d`
|
|
39260
39463
|
* embedding unchanged.
|
|
39261
39464
|
*
|
|
39262
|
-
* ## COM validation
|
|
39465
|
+
* ## COM validation, round 2: the 27-point lat x lon x rev grid (2026-09)
|
|
39466
|
+
*
|
|
39467
|
+
* The first campaign (single COM measurement per case, see history) found
|
|
39468
|
+
* the primary per-axis cosine scale exact for any single-axis `a:rot`, but a
|
|
39469
|
+
* damped pinhole-perspective "secondary term" (weighted by
|
|
39470
|
+
* `sin(lat)*sin(lon)`, FOV-dependent) under-predicted a genuinely combined
|
|
39471
|
+
* pose (`lat=35.26deg lon=45deg rev=45deg`) by ~25-29% relative corner error,
|
|
39472
|
+
* repeatably across two independent measurements. That secondary term is
|
|
39473
|
+
* REPLACED here, not patched: a fresh 27-point grid (`lat in {0, 25,
|
|
39474
|
+
* 35.26deg}` x `lon in {0, 25, 45deg}` x `rev in {0, 25, 45deg}`, including
|
|
39475
|
+
* both prior points exactly) was rendered via real PowerPoint COM
|
|
39476
|
+
* (`Slide.Export`, 144px/in, flat 2in `prst="orthographicFront"` + `a:rot`
|
|
39477
|
+
* squares) and each cell's 4 corners extracted by convex-hull fit (the
|
|
39478
|
+
* boundary/hull/quad-simplification method `visual-3d-camera-homography.ts`
|
|
39479
|
+
* already validated, NOT the fragile "4 extreme pixels" shortcut the first
|
|
39480
|
+
* campaign used, which silently mis-ordered corners for any near-45deg `rev`
|
|
39481
|
+
* by matching against UNDISTORTED reference positions - a large rotation's
|
|
39482
|
+
* true nearest axis-aligned corner is not its physical origin; fixed by
|
|
39483
|
+
* matching against a cosine-scale-plus-rev PRIOR position instead).
|
|
39484
|
+
*
|
|
39485
|
+
* Fitting the 27 measured cells against every hypothesis in the task brief
|
|
39486
|
+
* (Euler order lon-then-lat vs lat-then-lon vs the old damped-pinhole model;
|
|
39487
|
+
* orthographic vs a true perspective divide at the override's own FOV;
|
|
39488
|
+
* rotation about the shape centre - confirmed by near-zero centroid shift
|
|
39489
|
+
* uncorrelated with a cell's distance from the canvas centre, ruling out a
|
|
39490
|
+
* slide-centre pivot) found an EXACT closed form: keep `x` as the
|
|
39491
|
+
* already-validated pure cosine scale (COM-confirmed independent of `lat`:
|
|
39492
|
+
* the same `lon=45deg` cells produced identical `x` at `lat=25deg` and
|
|
39493
|
+
* `lat=35.26deg`), and add a rotation-composition cross term to `y` ONLY,
|
|
39494
|
+
* with a NEGATIVE sign relative to the naive `Ry(lon).Rx(lat)` composition
|
|
39495
|
+
* this module's first attempt used:
|
|
39263
39496
|
*
|
|
39264
|
-
*
|
|
39265
|
-
*
|
|
39266
|
-
*
|
|
39267
|
-
*
|
|
39268
|
-
*
|
|
39269
|
-
*
|
|
39270
|
-
*
|
|
39271
|
-
*
|
|
39272
|
-
* `
|
|
39273
|
-
*
|
|
39497
|
+
* ```
|
|
39498
|
+
* x = X * cos(lon)
|
|
39499
|
+
* y = Y * cos(lat) - X * sin(lat) * sin(lon)
|
|
39500
|
+
* ```
|
|
39501
|
+
*
|
|
39502
|
+
* Across all 27 grid cells (script: `gen-fixture.mjs` -> `measure.ps1` ->
|
|
39503
|
+
* `solve-corners.mjs` -> `fit-model.mjs`, scratch/one-off, not committed):
|
|
39504
|
+
* average max-corner error 0.61%, median well under 1%, worst 3 cells (all
|
|
39505
|
+
* `rev=25deg`, an "ugly" non-axis-aligned roll angle that maximises
|
|
39506
|
+
* antialiasing-boundary noise at a 288px-side element, not a systematic
|
|
39507
|
+
* lat/lon pattern) at 2.10% / 1.96% / 1.70% - see the raw per-cell table
|
|
39508
|
+
* below. This lands the combined case in the SAME ~1% band as the
|
|
39509
|
+
* single-axis cases, closing the ~25-29% gap the first campaign left open,
|
|
39510
|
+
* with NO fov/zoom dependency at all: the model is purely orthographic, so
|
|
39511
|
+
* `ParametricCameraParams.fovRad` is now unused by {@link projectCorner}
|
|
39512
|
+
* (kept in the type for API stability; `@fov`/`@zoom` were not
|
|
39513
|
+
* independently varied by this campaign, only held at their
|
|
39514
|
+
* `orthographicFront` default, so this does not claim they have no effect
|
|
39515
|
+
* under some other combination this grid did not cover).
|
|
39516
|
+
*
|
|
39517
|
+
* Raw per-cell max-corner error (fraction of the square's own side, sorted
|
|
39518
|
+
* worst-first; `lat=35.26` is the isometric angle `atan(1/sqrt(2))`, reusing
|
|
39519
|
+
* the first campaign's own combined-case angle set):
|
|
39274
39520
|
*
|
|
39275
39521
|
* ```
|
|
39276
|
-
*
|
|
39277
|
-
*
|
|
39278
|
-
*
|
|
39279
|
-
*
|
|
39522
|
+
* lat25_lon0_rev25 2.098% lat25_lon0_rev0 0.390%
|
|
39523
|
+
* lat0_lon45_rev25 1.959% lat25_lon0_rev45 0.362%
|
|
39524
|
+
* lat35.26_lon45_rev25 1.696% lat35.26_lon0_rev45 0.353%
|
|
39525
|
+
* lat0_lon25_rev25 0.776% lat0_lon25_rev45 0.349%
|
|
39526
|
+
* lat25_lon25_rev25 0.756% lat35.26_lon0_rev25 0.347%
|
|
39527
|
+
* lat25_lon25_rev45 0.735% lat35.26_lon45_rev45 0.347%
|
|
39528
|
+
* lat0_lon0_rev45 0.669% lat25_lon45_rev0 0.342%
|
|
39529
|
+
* lat35.26_lon25_rev45 0.654% lat25_lon25_rev0 0.323%
|
|
39530
|
+
* lat35.26_lon25_rev25 0.585% lat35.26_lon45_rev0 0.312%
|
|
39531
|
+
* lat0_lon0_rev0 0.491% lat35.26_lon25_rev0 0.304%
|
|
39532
|
+
* lat0_lon45_rev0 0.450% lat25_lon45_rev25 0.292%
|
|
39533
|
+
* lat25_lon45_rev45 0.420% lat0_lon0_rev25 0.259%
|
|
39534
|
+
* lat0_lon45_rev45 0.404%
|
|
39535
|
+
* lat35.26_lon0_rev0 0.402% (avg 0.610%, max 2.098%)
|
|
39280
39536
|
* ```
|
|
39281
39537
|
*
|
|
39282
|
-
*
|
|
39283
|
-
*
|
|
39284
|
-
*
|
|
39285
|
-
*
|
|
39286
|
-
*
|
|
39287
|
-
*
|
|
39288
|
-
*
|
|
39289
|
-
*
|
|
39290
|
-
*
|
|
39291
|
-
*
|
|
39292
|
-
*
|
|
39293
|
-
*
|
|
39294
|
-
*
|
|
39295
|
-
*
|
|
39296
|
-
* symmetric per-axis scale with NO keystone and NO centre shift, which the
|
|
39297
|
-
* old model could not represent either (it always keystones via
|
|
39298
|
-
* `perspective()`). `lon`'s sign was independently isolated and COM-checked
|
|
39299
|
-
* (a positive `lon` measured a symmetric width shrink, matching this
|
|
39300
|
-
* module).
|
|
39301
|
-
*
|
|
39302
|
-
* `lat`'s sign is NOT independently observable from a single-axis case:
|
|
39303
|
-
* `cos` is an even function, so this module's primary term produces the
|
|
39304
|
-
* IDENTICAL homography for `lat=+25deg` and `lat=-25deg` in isolation (no
|
|
39305
|
-
* `lon`) - proven analytically, and confirmed by a real `lat=25deg only`
|
|
39306
|
-
* COM measurement (2026-09, same 2in-square/144px-in methodology) matching
|
|
39307
|
-
* this module's prediction to within 1px on every one of the 4 measured
|
|
39308
|
-
* corners (predicted top/bottom edge at y=56.7/317.7 vs measured 56/317,
|
|
39309
|
-
* width unchanged both sides). Sign only becomes observable jointly with
|
|
39310
|
-
* `lon` (the secondary term), which the combined case below already
|
|
39311
|
-
* exercises; a single-axis case genuinely cannot add information here.
|
|
39312
|
-
*
|
|
39313
|
-
* `rev`'s sign WAS independently isolated: a real `rev=45deg only` COM
|
|
39314
|
-
* measurement (lat=lon=0) produced a diamond-oriented square whose 4 extreme
|
|
39315
|
-
* points matched this module's predicted corner-to-extreme mapping (which
|
|
39316
|
-
* original corner becomes the new top/right/bottom/left vertex) for a
|
|
39317
|
-
* POSITIVE `rev`, each within about 10 degrees of angle from the shape's own
|
|
39318
|
-
* centre (a small, consistent systematic offset in the SAME rotational
|
|
39319
|
-
* sense across all 4 points, not a sign flip) - this module's `rev` sign
|
|
39320
|
-
* convention is therefore COM-confirmed, not merely architecturally
|
|
39321
|
-
* plausible.
|
|
39322
|
-
*
|
|
39323
|
-
* A second, independent combined-case measurement (a fresh fixture, same
|
|
39324
|
-
* lat=35.26/lon=45/rev=45 angles) reproduced the same ~25-29% relative
|
|
39325
|
-
* corner error as the original campaign above (70.8px average this time, vs
|
|
39326
|
-
* 82px originally, both on a 288px element) - confirming the combined-case
|
|
39327
|
-
* residual is a real, repeatable limitation of this module's secondary term,
|
|
39328
|
-
* not measurement noise from a single run. The fixture/export/pixel-sampling
|
|
39329
|
-
* scripts used for all of this measurement were scratch, one-off tooling
|
|
39330
|
-
* (not committed - see the task report for the methodology if reproducing).
|
|
39538
|
+
* `lon`'s sign was independently isolated and COM-checked in the first
|
|
39539
|
+
* campaign (a positive `lon` measured a symmetric width shrink, matching
|
|
39540
|
+
* this module) and is unaffected by the cross-term replacement (`x` is
|
|
39541
|
+
* unchanged). `lat`'s sign is not independently observable from a
|
|
39542
|
+
* single-axis case (`cos` is even) but IS observable jointly with `lon` via
|
|
39543
|
+
* the cross term; the 27-point grid's fit (rather than an isolated
|
|
39544
|
+
* combined-case check) is itself the confirmation this module's `lat` sign
|
|
39545
|
+
* convention is correct across the whole grid, not just one pose. `rev`'s
|
|
39546
|
+
* sign was independently isolated in the first campaign (a real `rev=45deg
|
|
39547
|
+
* only` measurement matched this module's predicted corner-to-extreme
|
|
39548
|
+
* mapping for a positive `rev`) and is reused unchanged here: it is still
|
|
39549
|
+
* applied as a simple post-projection 2D roll, and the fit above already
|
|
39550
|
+
* exercises every `rev` level jointly with every `lat`/`lon` combination
|
|
39551
|
+
* without needing a different composition order.
|
|
39331
39552
|
*
|
|
39332
39553
|
* @module render/visual-3d-camera-parametric
|
|
39333
39554
|
*/
|
|
39334
|
-
function rotateX(v, angle) {
|
|
39335
|
-
const c = Math.cos(angle);
|
|
39336
|
-
const s = Math.sin(angle);
|
|
39337
|
-
return { x: v.x, y: v.y * c - v.z * s, z: v.y * s + v.z * c };
|
|
39338
|
-
}
|
|
39339
|
-
function rotateY(v, angle) {
|
|
39340
|
-
const c = Math.cos(angle);
|
|
39341
|
-
const s = Math.sin(angle);
|
|
39342
|
-
return { x: v.x * c + v.z * s, y: v.y, z: -v.x * s + v.z * c };
|
|
39343
|
-
}
|
|
39344
39555
|
function rotate2d(p, angle) {
|
|
39345
39556
|
if (angle === 0) {
|
|
39346
39557
|
return p;
|
|
@@ -39353,52 +39564,22 @@ function rotate2d(p, angle) {
|
|
|
39353
39564
|
* Project one local unit-square corner `(x, y)` (already centred, y-up)
|
|
39354
39565
|
* through the camera.
|
|
39355
39566
|
*
|
|
39356
|
-
*
|
|
39357
|
-
*
|
|
39358
|
-
*
|
|
39359
|
-
* `
|
|
39360
|
-
*
|
|
39361
|
-
*
|
|
39362
|
-
*
|
|
39363
|
-
*
|
|
39364
|
-
*
|
|
39365
|
-
*
|
|
39366
|
-
*
|
|
39367
|
-
*
|
|
39368
|
-
* pinhole formula's deviation from the cosine term) is blended in only when
|
|
39369
|
-
* BOTH `lat` and `lon` are nonzero at once (weighted by `sin(lat)*sin(lon)`,
|
|
39370
|
-
* which is exactly 0 for any single-axis rotation, so that COM-validated
|
|
39371
|
-
* case is reproduced UNCHANGED). This mirrors the preset table's own
|
|
39372
|
-
* two-axis families (`*Facing`/`Contrasting*`/`Heroic*`) genuinely needing a
|
|
39373
|
-
* skew a pure scale cannot represent. `fov` modulates this secondary term's
|
|
39374
|
-
* strength (a wider FOV -> a nearer, more exaggerated camera -> more
|
|
39375
|
-
* foreshortening), the only place `@fov`/`@zoom` affect this model: no COM
|
|
39376
|
-
* data varies FOV independently for an override, so treat this coupling as
|
|
39377
|
-
* physically-motivated but NOT independently calibrated, unlike the
|
|
39378
|
-
* COM-validated primary term.
|
|
39567
|
+
* `x` is a pure per-axis cosine foreshortening (`x = X*cos(lon)`), COM-
|
|
39568
|
+
* confirmed independent of `lat` (see the module doc comment): the 27-point
|
|
39569
|
+
* grid's `lon=45deg` cells produced the identical `x` at both `lat=25deg`
|
|
39570
|
+
* and `lat=35.26deg`. `y` gets the SAME cosine scale on its own axis
|
|
39571
|
+
* (`Y*cos(lat)`) plus a rotation-composition cross term, `-X*sin(lat)*
|
|
39572
|
+
* sin(lon)`, that is exactly 0 whenever EITHER axis is 0 (so both the
|
|
39573
|
+
* identity and every single-axis case reproduce their already-COM-validated
|
|
39574
|
+
* result unchanged) and otherwise fits the 27-point grid to within ~1% on
|
|
39575
|
+
* average (see the module doc comment for the full per-cell table). This is
|
|
39576
|
+
* a purely ORTHOGRAPHIC transform (no perspective divide, no `fov`
|
|
39577
|
+
* dependency): a genuine pinhole projection was one of the hypotheses tested
|
|
39578
|
+
* against the grid and fit measurably worse than this cross term.
|
|
39379
39579
|
*/
|
|
39380
39580
|
function projectCorner(localX, localY, params) {
|
|
39381
|
-
const
|
|
39382
|
-
const
|
|
39383
|
-
let x = localX * scaleX;
|
|
39384
|
-
let y = localY * scaleY;
|
|
39385
|
-
const twoAxisWeight = Math.sin(params.latRad) * Math.sin(params.lonRad);
|
|
39386
|
-
if (twoAxisWeight !== 0) {
|
|
39387
|
-
const f = 1 / Math.tan(params.fovRad / 2);
|
|
39388
|
-
const local = { x: localX, y: localY, z: 0 };
|
|
39389
|
-
// R^T * P, where R = Ry(lon) . Rx(lat): apply Ry(-lon) then Rx(-lat).
|
|
39390
|
-
const viewNoTranslate = rotateX(rotateY(local, -params.lonRad), -params.latRad);
|
|
39391
|
-
const viewZ = viewNoTranslate.z - f;
|
|
39392
|
-
// Guard a degenerate camera-through-the-plane case (should not occur
|
|
39393
|
-
// for any realistic lat/lon): skip the secondary term rather than
|
|
39394
|
-
// divide by ~0.
|
|
39395
|
-
if (Math.abs(viewZ) > 1e-6) {
|
|
39396
|
-
const pinholeX = (f * viewNoTranslate.x) / -viewZ;
|
|
39397
|
-
const pinholeY = (f * viewNoTranslate.y) / -viewZ;
|
|
39398
|
-
x += (pinholeX - localX * scaleX) * Math.abs(twoAxisWeight);
|
|
39399
|
-
y += (pinholeY - localY * scaleY) * Math.abs(twoAxisWeight);
|
|
39400
|
-
}
|
|
39401
|
-
}
|
|
39581
|
+
const x = localX * Math.cos(params.lonRad);
|
|
39582
|
+
const y = localY * Math.cos(params.latRad) - localX * Math.sin(params.latRad) * Math.sin(params.lonRad);
|
|
39402
39583
|
return rotate2d({ x, y }, params.revRad);
|
|
39403
39584
|
}
|
|
39404
39585
|
/**
|
|
@@ -103016,7 +103197,7 @@ function createLocalStorageBackend(namespace) {
|
|
|
103016
103197
|
/** Try IndexedDB first; fall back to localStorage on any failure. */
|
|
103017
103198
|
async function resolveBackend(dbName, namespace) {
|
|
103018
103199
|
try {
|
|
103019
|
-
const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-
|
|
103200
|
+
const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-DIH9Texq.mjs');
|
|
103020
103201
|
const db = await openChatDb(dbName);
|
|
103021
103202
|
return createIdbBackend(db);
|
|
103022
103203
|
}
|
|
@@ -142944,7 +143125,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
|
|
|
142944
143125
|
}], propDecorators: { canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }], selectedElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElement", required: false }] }] } });
|
|
142945
143126
|
|
|
142946
143127
|
// Generated by scripts/inline-shared.mjs from package.json. Do not edit.
|
|
142947
|
-
const PPTX_ANGULAR_VIEWER_VERSION = "3.
|
|
143128
|
+
const PPTX_ANGULAR_VIEWER_VERSION = "3.14.0";
|
|
142948
143129
|
|
|
142949
143130
|
/**
|
|
142950
143131
|
* account-page.component.ts: File > Account content.
|
|
@@ -181406,4 +181587,4 @@ function cn(...values) {
|
|
|
181406
181587
|
*/
|
|
181407
181588
|
|
|
181408
181589
|
export { CollaborationService as $, AFTER_ANIMATION_VALUES as A, AnimationAuthorPanelComponent as B, AnimationPanelComponent as C, AnimationPlaybackService as D, AutosaveRecoveryDialogComponent as E, AutosaveService as F, BroadcastDialogComponent as G, CHART_EDITOR_STYLES as H, CURSOR_PALETTE as I, CanvasFitService as J, ChartAxisOptionsComponent as K, ChartAxisStyleOptionsComponent as L, ChartComboTypeOptionsComponent as M, ChartDataEditorComponent as N, ChartDataLabelOptionsComponent as O, ChartDatapointMarkerOptionsComponent as P, ChartDatapointOptionsComponent as Q, ChartDisplayOptionsComponent as R, ChartElementViewComponent as S, ChartErrorBarOptionsComponent as T, ChartMarkerOptionsComponent as U, ChartPartSelectionService as V, ChartPrimitivesComponent as W, ChartRendererComponent as X, ChartTrendlineOptionsComponent as Y, ChartTypeSelectorComponent as Z, CollaborationCursorsComponent as _, ALIGN_OPTIONS as a, InsertSmartArtDialogComponent as a$, ColorChangedImageComponent as a0, CommentMarkersOverlayComponent as a1, CommentsPanelComponent as a2, CommentsService as a3, ComparePanelComponent as a4, ConnectorRendererComponent as a5, ConnectorTextOverlayComponent as a6, CustomShowsComponent as a7, DEFAULT_BOUNDS as a8, DEFAULT_BROADCAST_SERVER_URL as a9, EditorToolbarComponent as aA, EffectsPanelComponent as aB, ElementRendererComponent as aC, EmbeddedFontsService as aD, EncryptedFileDialogComponent as aE, EquationEditorDialogComponent as aF, EquationRendererComponent as aG, EquationTemplateGalleryComponent as aH, ExportProgressModalComponent as aI, ExportService as aJ, FieldContextService as aK, FindBarComponent as aL, FindReplaceBarComponent as aM, FollowModeBarComponent as aN, FontEmbeddingListComponent as aO, FontEmbeddingPanelComponent as aP, GALLERY_THEME_PRESETS as aQ, GOOGLE_WEBFONTS_LINK_ID as aR, GRIDLINE_COLOR$1 as aS, GoogleWebfontsService as aT, GradientPickerComponent as aU, HANDOUT_OPTIONS as aV, HeaderFooterDialogComponent as aW, HyperlinkDialogComponent as aX, ImagePropertiesPanelComponent as aY, InkDrawingService as aZ, InkRendererComponent as a_, DEFAULT_CANVAS_HEIGHT as aa, DEFAULT_CANVAS_WIDTH as ab, DEFAULT_COLOR_SCHEME as ac, DEFAULT_FILL_COLOR$1 as ad, DEFAULT_LAYOUT as ae, DEFAULT_PALETTE$1 as af, DEFAULT_PATTERN_FILL_PRESET as ag, DEFAULT_PRINT_SETTINGS as ah, DEFAULT_SLIDE_BACKGROUND as ai, DEFAULT_STROKE_COLOR as aj, DEFAULT_STYLE as ak, DEFAULT_TABLE_ROW_HEIGHT as al, DEFAULT_TEXT_COLOR$2 as am, DEFAULT_VIEWER_PROFILE as an, DIRECTIONAL_PRESETS as ao, DIRECTION_OPTIONS as ap, DocumentPropertiesCardComponent as aq, EFFECT_SOUND_CATALOGUE as ar, EMBEDDED_FONTS_STYLE_ID as as, EMPHASIS_PRESETS as at, ENTRANCE_PRESETS as au, TEMPLATES as av, EXIT_PRESETS as aw, EditorContextMenuComponent as ax, EditorHistory as ay, EditorStateService as az, ANIMATION_PRESET_CATEGORIES as b, RibbonArrangeSectionComponent as b$, InspectorPaneHeaderComponent as b0, InspectorPanelComponent as b1, IsMobileService as b2, KeepAnnotationsDialogComponent as b3, LOCALE_CATALOG as b4, LONG_PRESS_DURATION_MS as b5, LONG_PRESS_MOVE_TOLERANCE_PX as b6, LoadContentService as b7, LocalPresencePublisher as b8, MAX_ZOOM_SCALE as b9, PX_PER_INCH as bA, PasswordProtectionDialogComponent as bB, PasswordStrengthMeterComponent as bC, PowerPointViewerComponent as bD, PresentToolbarAutoHide as bE, PresentationAnnotationOverlayComponent as bF, PresentationAnnotationsService as bG, PresentationOverlayComponent as bH, PresentationPropertiesPanelComponent as bI, PresentationSettingsCardComponent as bJ, PresentationSubtitleBarComponent as bK, PresentationToolbarComponent as bL, PresentationTransitionOverlayComponent as bM, PresenterViewComponent as bN, PresenterWindowService as bO, PrintDialogComponent as bP, PrintService as bQ, PrintSettingsPanelComponent as bR, PropertiesDialogComponent as bS, REPEAT_MODE_OPTIONS as bT, RESIZE_HANDLES as bU, RULER_FONT_SIZE as bV, RULER_THICKNESS as bW, ReadingViewOverlayComponent as bX, RemoteSelectionOverlayComponent as bY, RibbonAnimationGalleryComponent as bZ, RibbonAnimationsSectionComponent as b_, MIN_ZOOM_SCALE as ba, MOTION_PATH_COLUMNS as bb, MediaPreviewComponent as bc, MediaPropertiesPanelComponent as bd, MediaRendererComponent as be, MediaTrimTimelineComponent as bf, MobileBottomBarComponent as bg, MobileMenuSheetComponent as bh, MobilePresenterViewComponent as bi, MobileSheetComponent as bj, MobileSlidesSheetComponent as bk, MobileToolbarComponent as bl, ModalDialogComponent as bm, Model3DRendererComponent as bn, NotesHandoutCardComponent as bo, NotesPanelComponent as bp, NotesToolbarComponent as bq, OleRendererComponent as br, OutlineViewOverlayComponent as bs, POWER_POINT_VIEWER_PROVIDERS as bt, PPTX_OPEN_ACCEPT as bu, PRESENTATION_OPEN_EXTENSIONS as bv, PRESENTER_CHANNEL_NAME as bw, PRESENTER_MSG_ORIGIN as bx, PRESENTER_TIMER_SEGMENT_MS as by, PX_PER_CM as bz, AUDIENCE_HASH as c, TABLE_STRUCTURE_TOGGLES as c$, RibbonColorPopoverComponent as c0, RibbonComponent as c1, RibbonDesignSectionComponent as c2, RibbonDrawSectionComponent as c3, RibbonDrawingGroupComponent as c4, RibbonEditingSectionComponent as c5, RibbonFileSectionComponent as c6, RibbonFontControlsComponent as c7, RibbonHomeSectionComponent as c8, RibbonHyperlinkButtonComponent as c9, SettingsAppearanceTabComponent as cA, SettingsDialogComponent as cB, SettingsLanguageTabComponent as cC, ShareDialogComponent as cD, ShortcutPanelComponent as cE, ShowOptionsFieldsetComponent as cF, ShowSlidesFieldsetComponent as cG, SignatureStrippedDialogComponent as cH, SignaturesPanelComponent as cI, SignaturesService as cJ, SlideBackgroundCardComponent as cK, SlideCanvasComponent as cL, SlideDefaultInspectorComponent as cM, SlideDiffChangesComponent as cN, SlideDiffRowComponent as cO, SlideDiffThumbnailsComponent as cP, SlideSizeCardComponent as cQ, SlideSorterOverlayComponent as cR, SlideThemeOverridePanelComponent as cS, SlideTransitionCardComponent as cT, SlidesPanelComponent as cU, SmartArt3DRendererComponent as cV, SmartArt3DService as cW, SmartArtPreviewComponent as cX, SmartArtPropertiesComponent as cY, SmartArtRendererComponent as cZ, StatusBarComponent as c_, RibbonInsertFieldsComponent as ca, RibbonInsertSectionComponent as cb, RibbonMotionPathGalleryComponent as cc, RibbonParagraphControlsComponent as cd, RibbonPrimaryRowComponent as ce, RibbonReviewSectionComponent as cf, RibbonShapeExtrasComponent as cg, RibbonSlideshowSectionComponent as ch, RibbonTransitionsSectionComponent as ci, RibbonViewSectionComponent as cj, RulerGuidesService as ck, SEQUENCE_OPTIONS as cl, SEVERITY_GROUPS as cm, SEVERITY_LABELS as cn, SHORTCUT_REFERENCE_ITEMS as co, SLIDE_TRANSITION_KEYFRAMES as cp, DEFAULT_PALETTE as cq, PALETTES$1 as cr, SMART_ART_COLOR_SCHEMES as cs, SMART_ART_STYLE_OPTIONS as ct, SUB_ITEM_LABEL as cu, SVG_WARP_PRESETS as cv, SWIPE_MAX_VERTICAL_PX as cw, SWIPE_THRESHOLD_PX as cx, SelectionPaneComponent as cy, SetUpSlideShowDialogComponent as cz, AUDIENCE_NONCE_KEY as d, alignPatch as d$, TEXT_3D_BOTTOM_BEVEL_KEYS as d0, TEXT_3D_TOP_BEVEL_KEYS as d1, TEXT_DIRECTION_OPTIONS$1 as d2, THEME_CATALOG as d3, TIMING_CURVE_OPTIONS as d4, TRIGGER_OPTIONS as d5, TYPE_LABELS as d6, TableCellAdvancedFillComponent as d7, TableCellFormattingComponent as d8, TableDataEditorComponent as d9, ViewerExportService as dA, ViewerExtraDialogsComponent as dB, ViewerFileIOService as dC, ViewerFindReplaceService as dD, ViewerFormatPainterService as dE, ViewerInspectorPanelService as dF, ViewerKeyboardService as dG, ViewerMobileSheetService as dH, ViewerPresentationModeService as dI, ViewerThemeGalleryService as dJ, ViewerTouchGesturesService as dK, ViewerZoomService as dL, WEBM_MIME_CANDIDATES as dM, WriteBackScheduler as dN, ZERO_LINE_COLOR as dO, ZoomNavigationService as dP, ZoomRendererComponent as dQ, ZoomTargetService as dR, addCategory as dS, addCommentToList as dT, addGradientStopPatch as dU, addItem as dV, addSeries as dW, addSubItem as dX, advanceStep as dY, affordanceElements as dZ, aiToggleVisible as d_, TablePropertiesComponent as da, TableRendererComponent as db, TableResizeOverlayComponent as dc, TableSelectionService as dd, TagsCardComponent as de, Text3DBevelSectionComponent as df, Text3DPanelComponent as dg, TextAdvancedPanelComponent as dh, ThemeEditorFieldsComponent as di, ThemeGalleryComponent as dj, ThemeSelectorCardComponent as dk, TitleBarComponent as dl, TitleBarSearchComponent as dm, TransitionDirectionPickerComponent as dn, TransitionPreviewComponent as dp, VALIGN_OPTIONS as dq, VIEWER_THEME as dr, VersionHistoryPanelComponent as ds, ViewerCanvasEditingService as dt, ViewerCollabCursorService as du, ViewerCollaborationSessionService as dv, ViewerCompareService as dw, ViewerCustomShowsService as dx, ViewerDialogsService as dy, ViewerDocumentPropertiesService as dz, AVATAR_COLOR_SWATCHES as e, buildStockViewModel as e$, animationFor as e0, animationPresetLabelKey as e1, annotationMapToInkInserts as e2, applyAcceptedDiff as e3, applyAnimationPreset as e4, applyFindReplacements as e5, applyFormatToElement as e6, applyMove as e7, applyResize as e8, asMediaElement as e9, buildEmbeddedFontStyles as eA, buildEquationElement as eB, buildEquationSegment as eC, buildFallbackViewModel as eD, buildFontFaceRule as eE, buildGradientFillCss as eF, buildGridlinesAndLabels as eG, buildHyperlinkPatch as eH, buildInkContainerStyle as eI, buildInkStrokes as eJ, buildLegend as eK, buildLiveInkStrokeView as eL, buildMarkTooltip as eM, buildModel3DContainerStyle as eN, buildModel3DViewModel as eO, buildOleActionModel as eP, buildOleInfoRows as eQ, buildPatternFillCss as eR, buildPieViewModel as eS, buildPrintHtmlDocument as eT, buildPropertiesPatch as eU, buildRadarViewModel as eV, buildRegionMapViewModel as eW, buildSaveSlides as eX, buildShareUrl as eY, buildSmartArtInsertElement as eZ, buildSmartArtNodes as e_, assignUserColor as ea, attachShowVisibilityPause as eb, attachTouchGestures as ec, axisTickValues as ed, beginNodeEdit as ee, bevelSizePatch as ef, boolFromEvent as eg, bringForward as eh, bringToFront as ei, buildBarActions as ej, buildBroadcastConfig as ek, buildBroadcastViewerUrl as el, buildCategoryLabels as em, buildCellParagraphs as en, buildChartViewModel as eo, buildChatLogExport as ep, buildChatLogMarkdown as eq, buildChromeStyle as er, buildClearHyperlinkPatch as es, buildClickGroups as et, buildColStyles as eu, buildCollaborationConfig as ev, buildComboViewModel as ew, buildCssGradientFromShapeStyle as ex, buildDuotoneFilter as ey, buildDuotoneFilterId as ez, AXIS_LABEL_COLOR as f, computePlotLayout as f$, buildSurfaceViewModel as f0, buildTableViewModel as f1, buildTreemapViewModel as f2, buildTrimFragment as f3, buildWaterfallViewModel as f4, buildZeroLine as f5, buildZoomContainerStyle as f6, buildZoomViewModel as f7, bulletIndentPx as f8, canAddTopLevelNode as f9, collectAccessibilityIssues as fA, collectElementText as fB, collectSlideText as fC, collectStoredChats as fD, collectUsedFontFamilies as fE, columnWidthStyle as fF, commitNodeText as fG, computeAlign as fH, computeAxisTitlePrimitives as fI, computeBarRects as fJ, computeBubbleRadius as fK, computeCornerHandle as fL, computeDistribute as fM, computeDrawingViewBox as fN, computeErrorBarPrimitives as fO, computeFocusTargets as fP, computeGridSpacingPx as fQ, computeHandleBoxes as fR, computeHandoutLayout as fS, computeIsMobile as fT, computeIsTablet as fU, computeLinePoints as fV, computeLinearRegression as fW, computePageCount as fX, computePieLayout as fY, computePieSlicePath as fZ, computePieSlices as f_, canEditSmartArtNodes as fa, canGroupSelection as fb, canRemoveTopLevelNode as fc, canSetStrokeWidth as fd, canStartBroadcast as fe, canStartShare as ff, canUngroupSelection as fg, canUseClipboard as fh, captionDisplayText as fi, cellRunStyle as fj, cellStyleToStyleMap as fk, cellTdStyle as fl, changeCountLabel as fm, changeIcon as fn, characterSpacingPatch as fo, chartPreserveAspectRatio as fp, checkFontAvailable as fq, clampCursorPosition as fr, clampGifDimensions as fs, clampIndex as ft, clampNotesFontSize as fu, clampScale as fv, clampStep as fw, clearAllLocalViewerData as fx, clearAudienceContent as fy, cn as fz, AccessibilityPanelComponent as g, focusTargetChips as g$, computeRSquared as g0, computeRadarPoints as g1, computeResizeHandleBoxes as g2, computeRotateHandleBox as g3, computeScatterDots as g4, computeScatterXDomain as g5, computeSelectionBoxes as g6, computeSingleSelected as g7, computeSlideIndices as g8, computeSnap as g9, disableGlowPatch as gA, disableInnerShadowPatch as gB, disableOuterShadowPatch as gC, disableReflectionPatch as gD, disableSoftEdgePatch as gE, duplicateElementById as gF, durationOf as gG, effectsStateOf as gH, enableGlowPatch as gI, enableInnerShadowPatch as gJ, enableOuterShadowPatch as gK, enableReflectionPatch as gL, enableSoftEdgePatch as gM, encodeGif as gN, endShowMediaCleanup as gO, estimatePageCount as gP, exitPresentationFullscreen as gQ, exportAiChatLogs as gR, extractPathPoints as gS, eyedropperAvailable as gT, fillColorOf$1 as gU, findInSlides as gV, findOwningSlideIndex as gW, findSlideIndexByElementId as gX, firstVisibleIndex as gY, fitPolynomial as gZ, fitZoom as g_, computeStackedBarRects as ga, computeStackedValueRange as gb, computeTrendlinePrimitives as gc, computeValueRange as gd, convertOmmlToMathMl as ge, copyFormatFromElement as gf, countAccessibilityIssues as gg, countAnnotationStrokes as gh, createAngularAiBridge as gi, createCustomShow as gj, createSwipeDismissDrag as gk, createWebrtcBundle as gl, createWebsocketBundle as gm, cssObjectToStyleMap as gn, currentColorScheme as go, currentLayout as gp, currentStyle as gq, defaultCssVars as gr, defaultRadius as gs, defaultThemeColors as gt, deleteElementsByIds as gu, deleteVersion as gv, demoteNode as gw, deriveModel3DBlobUrl as gx, derivePresenceList as gy, describeSmartArtBounds as gz, AccessibilityService as h, insertTableElementRow as h$, fontMimeForFormat as h0, fontSizeOf as h1, forgetSessionDeck as h2, formatAxisValue as h3, formatBytes as h4, formatCursorLabel as h5, formatElapsed as h6, formatFileSize as h7, formatPropertyDate as h8, formatTime as h9, getShapeFillStrokeStyle as hA, getSlideBackgroundStyle as hB, getSlideTransitionAnimations as hC, getSmartArtNodeBounds as hD, getSpeechRecognitionCtor as hE, getTextBlockStyle as hF, getTextWarp as hG, getTouchDistance as hH, getWarpCategory as hI, getWarpPath as hJ, gradientStateFromStyle as hK, gradientStateOf as hL, gradientStatePatch as hM, gradientStopColorCommitPatch as hN, gridColumns as hO, groupIssuesBySeverity as hP, hasAnimation as hQ, hasCopyableFormat as hR, hasExistingLink as hS, hasExitedFullscreen as hT, hasGradientFill as hU, hasPressureVariation as hV, hasVisibleSlideAfter as hW, headerLabel as hX, imageDimensions as hY, inkViewBox as hZ, insertTableElementColumn as h_, fpsToFrameIntervalMs as ha, generateBroadcastRoomId as hb, generateCommentId as hc, generateCustomShowId as hd, generatePressureCircles as he, generateTicks as hf, getClrChangeParams as hg, getContainerStyle as hh, getDuotoneFilterDef as hi, getEffectSoundAsset as hj, getEffectSoundState as hk, getImageSrc as hl, getLocalStorageUsageSummary as hm, getOleAriaLabel as hn, getOleBadgeLabel as ho, getOleDisplayName as hp, getOleDownloadFileName as hq, getOleTypeColor as hr, getOleTypeLabel as hs, getPasswordStrength as ht, getPatternSvg as hu, getPlaceholderStyle as hv, getVersions as hw, getResolvedShapeClipPath as hx, getResolvedShapeClipPathFor as hy, getSessionTabId as hz, AccessibilityTextPanelComponent as i, normalizeSlidesPerPage as i$, interpolateWidth as i0, isAudienceTab as i1, isBold as i2, isBrowserOpenableMime as i3, isChildNode as i4, isElementInteractive as i5, isInjectableUrl as i6, isItalic as i7, isLegacyBinaryPresentation as i8, isPpactionUrl as i9, mergeDown as iA, mergeRight as iB, mergeSelection as iC, mergeTablesDirective as iD, moveElementBy as iE, moveNodeDown as iF, moveNodeUp as iG, msToFrameDelayCs as iH, narrowToCircle as iI, narrowToPolygon as iJ, narrowToRect as iK, newChartElement as iL, newEquationElement as iM, newPresetShapeElement as iN, newShapeElement as iO, newSmartArtElement as iP, newTableElement as iQ, newTextElement as iR, nextVisibleIndex as iS, nodeBold as iT, nodeEditBox as iU, nodeFillColor as iV, nodeFontColor as iW, nodeIdFromKey as iX, nodeItalic as iY, nodeStyle as iZ, normalizeFontFormat as i_, isPresenterMessage as ia, isSigned as ib, isSupportedPresentationFile as ic, isTextElement as id, isTwoTableFocus as ie, isUnderline as ig, isUrlSafe as ih, isValidRoomId as ii, isViewportBackgroundPressTarget as ij, isZoomActivationKey as ik, issueTrackKey as il, issueTypeLabel as im, keyToLabel as io, lastVisibleIndex as ip, latexToMathml as iq, layoutConnectorPaints as ir, layoutNodeLabels as is, linePointsToSvgString as it, lineSpacingPatch as iu, loadAudienceContent as iv, loadSessionDeck as iw, mediaFallbackFor as ix, mediaSurfaceFor as iy, mergeCaptionResults as iz, AccountPageComponent as j, resolveParagraphBullet as j$, normalizeValue as j0, numFromEvent as j1, ommlToMathml as j2, ooxmlDashToCssBorderStyle as j3, openNativeEyeDropper as j4, overallStatus as j5, paletteColor as j6, parseAudienceNonce as j7, parseNodeTextarea as j8, partitionSlides as j9, readAsDataUrl as jA, recordWebm as jB, registerCrossSlideAudio as jC, rememberSessionDeck as jD, removeAnimation as jE, removeCategory as jF, removeTableElementColumn as jG, removeCommentFromList as jH, removeElementAnimation as jI, removeGradientStopPatch as jJ, removeNode as jK, removeTableElementRow as jL, removeSeries as jM, renderToCanvas as jN, reorderAnimationDown as jO, reorderAnimationUp as jP, replaceInSlides as jQ, replaceMatch as jR, requestPresentationFullscreen as jS, resizeElement as jT, resolveCaptionTracks as jU, resolveChartKind as jV, resolveFontVariant as jW, resolveHyperlinkHref as jX, resolveInteractiveElementId as jY, resolveMediaSrc as jZ, resolveOleType as j_, patchChartData as ja, patchChartStyle as jb, patchTableData as jc, patchTextStyle as jd, patternPresetOptions as je, pendingElementStyles as jf, pickColorByClickFallback as jg, pickFile as jh, pickSupportedMimeType as ji, planGifFrames as jj, planVideoSegments as jk, pointFromPointerEvent as jl, pointsToSvgPathD as jm, presenceToCursors as jn, presentationBaseName as jo, presentationStageStyle as jp, presenterTimerProgress as jq, presetByLayout as jr, presetsForCategory as js, pressuresToWidths as jt, prevVisibleIndex as ju, projectDrawingShapes as jv, promoteNode as jw, provideViewerTheme as jx, radarAngle as jy, radarRingPoints as jz, ActionSettingsPanelComponent as k, setSequence as k$, resolvePresenterNotes as k0, resolveProfileInitial as k1, resolveRegionCode as k2, resolveRibbonCanGroup as k3, resolveSlideAutoAdvanceMs as k4, resolvePalette as k5, resolveThemeCatalogEntry as k6, resolveTransitionDuration as k7, restoreSessionDeck as k8, revealedElementStyles as k9, setAnimationEmphasis as kA, setAnimationEntrance as kB, setAnimationExit as kC, setAxis as kD, setAxisLogScale as kE, setAxisTitleStyle as kF, setCategoryLabel as kG, setCellText as kH, setColorScheme as kI, setDataLabels as kJ, setDataPointExplosion as kK, setDataPointFill as kL, setDataPointLabel as kM, setDataPointMarker as kN, setDelay as kO, setDirection as kP, setDuration as kQ, setEffectSound as kR, setEffectStockSound as kS, setElementPosition as kT, setGridlineStyle as kU, setLayout as kV, setLegend as kW, setNodeStyle as kX, setNodeText as kY, setRepeatCount as kZ, setRepeatMode as k_, routeOrthogonalConnector as ka, rowStyle as kb, rulerDragToGuidePosition as kc, rulerHighlight as kd, rulerStripTicks as ke, sampleColorFromSlide as kf, sanitizeColor as kg, sanitizeSlideIndex as kh, sanitizeUserName as ki, saveViewerProfile as kj, savedPresentationFileName as kk, scanAvailableFonts as kl, searchSlides as km, seedBroadcastFields as kn, seedHyperlinkDraft as ko, seedPropertiesDraft as kp, seedShareFields as kq, segmentFrameCount as kr, selectValue$3 as ks, sendBackward as kt, sendToBack as ku, sequentialColorScale as kv, serializeWriteBack as kw, seriesColor as kx, setAfterAnimation as ky, setAfterAnimationColor as kz, AdvancedChartEditorComponent as l, updateReflectionPatch as l$, setSeriesChartType as l0, setSeriesColor as l1, setSeriesErrorBars as l2, setSeriesMarker as l3, setSeriesName as l4, setSeriesTrendline as l5, setSeriesValue as l6, setStyle as l7, setTimingCurve as l8, setTitle as l9, strokeWidthOf as lA, styleShadowFilter as lB, surfaceColor as lC, textAdvancedPatch as lD, textAdvancedStateFromStyle as lE, textAdvancedStateOf as lF, textColorOf as lG, textDirectionPatch as lH, textFontSizePatch as lI, textStyleOf as lJ, textStylePatch as lK, themeStyle as lL, themeToCssVars as lM, thumbnailHeight as lN, thumbnailZoom as lO, toggleCommentResolvedInList as lP, toggleNodeBold as lQ, toggleNodeItalic as lR, toggleSheet as lS, topLevelNodeCount as lT, transformSelectedTextCase as lU, translationsEn as lV, updateElementById as lW, updateGlowPatch as lX, updateGradientStopPatch as lY, updateInnerShadowPatch as lZ, updateOuterShadowPatch as l_, setTrigger as la, setTriggerShapeId as lb, shapeStylePatch$1 as lc, sheetAfterNavigate as ld, shouldBlockClickAdvance as le, shouldUseSvgWarp as lf, showDirectionPicker as lg, showsTemplateAffordance as lh, signatureCountLabel as li, signatureKey as lj, signatureTimestamp as lk, signerName as ll, statusLabel as lm, slideNumberOf as ln, slidesWithReappliedLayout as lo, smartArtNodes as lp, paletteColour as lq, snapToGridStep as lr, splitCursorCell as ls, splitMergedCell as lt, statusKind as lu, statusLabel$1 as lv, storeAudienceContent as lw, stringFromEvent$5 as lx, strokeColorOf as ly, strokeToInkElement as lz, AiChangeOverlayComponent as m, vAlignPatch as m0, validatePassword as m1, validatePrintSettings as m2, validateRoomId as m3, valueToY as m4, vermilionDarkColors as m5, vermilionDarkTheme as m6, vermilionLightColors as m7, vermilionLightTheme as m8, vermilionRadius as m9, waypointsToPathD as ma, withManualLayouts as mb, worstStatus as mc, zoomTargetSlideIndex as md, AiChatPanelComponent as n, AiChatService as o, AiComposerComponent as p, AiFocusBarComponent as q, AiFocusHighlightOverlayComponent as r, AiHistoryMenuComponent as s, toChatSummary as t, AiHistoryService as u, AiMessageListComponent as v, AiPanelStore as w, AiProposalCardComponent as x, AiSettingsSectionComponent as y, AiToolCallCardComponent as z };
|
|
181409
|
-
//# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-
|
|
181590
|
+
//# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-CVv5SsHZ.mjs.map
|