pptx-angular-viewer 4.24.3 → 4.26.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 +65 -0
- package/README.md +9 -9
- package/ng-package.json +25 -0
- package/package.json +45 -20
- package/scripts/finalize-dist.mjs +24 -0
- package/scripts/inline-shared.mjs +43 -0
- package/tsconfig.lib.json +13 -0
- package/vitest-setup.ts +12 -0
- package/fesm2022/pptx-angular-viewer-bar-chart-3d-hit-test-B6eCwecE.mjs +0 -9855
- package/fesm2022/pptx-angular-viewer-bar-chart-3d-hit-test-B6eCwecE.mjs.map +0 -1
- package/fesm2022/pptx-angular-viewer-chart-3d-view-scene-IqColhvd.mjs +0 -1594
- package/fesm2022/pptx-angular-viewer-chart-3d-view-scene-IqColhvd.mjs.map +0 -1
- package/fesm2022/pptx-angular-viewer-chat-history-idb-7dzD77Ju.mjs +0 -73
- package/fesm2022/pptx-angular-viewer-chat-history-idb-7dzD77Ju.mjs.map +0 -1
- package/fesm2022/pptx-angular-viewer-chat-history-store-Ckeu-olx.mjs +0 -121
- package/fesm2022/pptx-angular-viewer-chat-history-store-Ckeu-olx.mjs.map +0 -1
- package/fesm2022/pptx-angular-viewer-view-overflow-BBD8nZlq.mjs +0 -1418
- package/fesm2022/pptx-angular-viewer-view-overflow-BBD8nZlq.mjs.map +0 -1
- package/fesm2022/pptx-angular-viewer-view-scene-htTUkvvA.mjs +0 -836
- package/fesm2022/pptx-angular-viewer-view-scene-htTUkvvA.mjs.map +0 -1
- package/fesm2022/pptx-angular-viewer.mjs +0 -169944
- package/fesm2022/pptx-angular-viewer.mjs.map +0 -1
- package/i18n/de.cjs +0 -4165
- package/i18n/de.d.cts +0 -3
- package/i18n/de.d.mts +0 -3
- package/i18n/de.mjs +0 -4138
- package/i18n/es.cjs +0 -4165
- package/i18n/es.d.cts +0 -3
- package/i18n/es.d.mts +0 -3
- package/i18n/es.mjs +0 -4138
- package/i18n/fr.cjs +0 -4165
- package/i18n/fr.d.cts +0 -3
- package/i18n/fr.d.mts +0 -3
- package/i18n/fr.mjs +0 -4138
- package/i18n/zh-CN.cjs +0 -4198
- package/i18n/zh-CN.d.cts +0 -3
- package/i18n/zh-CN.d.mts +0 -3
- package/i18n/zh-CN.mjs +0 -4171
- package/pptx-angular-viewer.css +0 -2
- package/types/pptx-angular-viewer.d.ts +0 -60042
- package/types/pptx-angular-viewer.d.ts.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pptx-angular-viewer-view-overflow-BBD8nZlq.mjs","names":["DEG_PER_UNIT"],"sources":["../../src/internal/shared-src/render/visual-3d-bevel-light.ts","../../src/internal/shared-src/render/visual-3d-bevel-lighting-profile.ts","../../src/internal/shared-src/render/visual-3d-bevel-lighting-material.ts","../../src/internal/shared-src/render/visual-3d-bevel-lighting-tables.ts","../../src/internal/shared-src/render/visual-3d-constants.ts","../../src/internal/shared-src/render/visual-3d-camera-presets.ts","../../src/internal/shared-src/render/smartart-3d-scene-camera.ts","../../src/internal/shared-src/render/smartart-3d-style-path.ts","../../src/internal/shared-src/render/smartart-3d-solid.ts","../../src/internal/shared-src/render/smartart-3d-light-rig.ts","../../src/internal/shared-src/render/smartart-3d-lighting.ts","../../src/internal/shared-src/render/smartart-3d-vertex-shading.ts","../../src/internal/shared-src/render/smartart-3d-drawing-solid.ts","../../src/internal/shared-src/three-view/renderer-host.ts","../../src/internal/shared-src/three-view/view-overflow.ts"],"sourcesContent":["/**\n * `a:lightRig/@dir` -> top-bevel highlight/shadow direction (framework-agnostic).\n *\n * COM-measured 2026-09 (real PowerPoint, `Slide.Export`, a mid-grey 2in\n * square with a wide `a:bevelT` circle profile, `Depth = 0`): sampling\n * brightness at the top/right/bottom/left edge bands under each of the 8\n * `a:lightRig/@dir` values shows the highlight snaps to exactly ONE of the 4\n * cardinal edges, never a blend of two:\n *\n * ```\n * dir top right bottom left (brightness, mid-grey centre = 138)\n * t 163 92 105 120\n * tr 163 113 90 100 <- same dominant edge (top) as `t`\n * r 121 159 97 105\n * br 101 159 117 91 <- same dominant edge (right) as `r`\n * b 113 120 165 93\n * bl 96 99 165 114 <- same dominant edge (bottom) as `b`\n * l 95 106 124 160\n * tl 115 90 103 160 <- same dominant edge (left) as `l`\n * ```\n *\n * Each diagonal (`tr`/`br`/`bl`/`tl`) reproduces the SAME dominant edge as\n * the cardinal direction it follows going clockwise (`t`->`tr`, `r`->`br`,\n * `b`->`bl`, `l`->`tl`), i.e. the dominant edge is the compass direction at\n * `floor(angle / 90) * 90`, not a diagonal blend the way the pre-existing\n * (direction-blind) implementation's hardcoded top-left diagonal highlight\n * implied.\n *\n * A second, larger campaign (2026-09) re-ran this exact brightness scan for\n * ALL 12 `a:bevelT/@prst` profiles (`relaxedInset`, `circle`, `slope`,\n * `cross`, `angle`, `softRound`, `convex`, `coolSlant`, `divot`, `riblet`,\n * `hardEdge`, `artDeco`) x all 8 directions at a wide (24pt) depth, plus a\n * 6pt-vs-24pt depth check for 3 representative profiles:\n *\n * - 9 of the 12 profiles (every one above except `softRound`, `slope` and\n * `hardEdge`) reproduced the exact same cardinal-snap pattern as `circle`,\n * confirming {@link getBevelHighlightDirection}'s direction mapping\n * generalises across profile SHAPE, not just `circle`.\n * - `softRound` measured the OPPOSITE cardinal edge as its highlight for\n * every one of the 8 directions (e.g. `dir=\"t\"` lit up the BOTTOM edge,\n * not the top): {@link isBevelProfileInverted} flags this so\n * `visual-3d.ts`'s `getBevelShadow` negates the resolved vector for this\n * one profile. Physically plausible: a \"soft round\" transition can read as\n * a rounded INSET (a shallow groove catching shadow from the light side)\n * rather than `circle`'s rounded OUTSET (a dome catching highlight),\n * inverting which edge faces the light.\n * - `slope` and `hardEdge` measured UNIFORM brightness (no directional signal\n * at all) at the same 0.15in-from-edge sample point every other profile\n * used, and a follow-up fine-grained radial scan (offsets from 0.01in to\n * 0.3in) found only a universal, direction-INDEPENDENT darkening right at\n * the crisp fold (both the \"highlight\" and \"opposite\" edges darkened by a\n * similar amount within the first ~0.05in for BOTH profiles), consistent\n * with a real single-flat-facet self-shadowed seam rather than a smooth\n * directional gradient. No sampling depth tested recovered a clean\n * cardinal-snap signal for these two, so their direction handling is left\n * unverified/inconclusive rather than encoding a guess from noisy data;\n * they still render with the shared cardinal-snap direction (a reasonable\n * approximation, just not independently confirmed the way the other 10\n * profiles now are).\n * - The highlight/shadow band's on-screen WIDTH scales with the bevel's\n * actual size (confirmed for `circle`, `angle` and `softRound` at 6pt vs.\n * 24pt: the 6pt bevel's directional signal collapsed to background within\n * ~0.1in of the edge, the 24pt bevel's extended to ~0.3in, roughly\n * matching the 4x depth ratio). This was already the existing behaviour\n * (`visual-3d.ts`'s `getBevelShadow` derives its inset-shadow offsets from\n * the shape's ACTUAL `bevelTopWidth`/`Height` in px, not a fixed\n * constant), so no code change was needed for this finding; it is now\n * COM-confirmed rather than assumed.\n *\n * @module render/visual-3d-bevel-light\n */\n\n/** Compass angle (degrees, clockwise from `t` = 0) for each `a:lightRig/@dir` token. */\nconst DIRECTION_ANGLE: Record<string, number> = {\n\tt: 0,\n\ttr: 45,\n\tr: 90,\n\tbr: 135,\n\tb: 180,\n\tbl: 225,\n\tl: 270,\n\ttl: 315,\n};\n\n/** A highlight direction as a unit-ish (dx, dy) vector in CSS inset-shadow offset space. */\nexport interface BevelLightVector {\n\tdx: number;\n\tdy: number;\n}\n\n/** The 4 cardinal highlight directions, keyed by the `floor(angle / 90) * 90` bucket. */\nconst CARDINAL_VECTORS: Record<number, BevelLightVector> = {\n\t0: { dx: 0, dy: -1 }, // t\n\t90: { dx: 1, dy: 0 }, // r\n\t180: { dx: 0, dy: 1 }, // b\n\t270: { dx: -1, dy: 0 }, // l\n};\n\n/**\n * Resolve the TOP bevel's highlight direction from `a:lightRig/@dir`.\n * Falls back to the pre-existing top-left diagonal default when the\n * direction is missing/unrecognised, so an authored deck with no light rig\n * (or an unmapped direction) keeps rendering exactly as before this module\n * existed.\n */\nexport function getBevelHighlightDirection(\n\tlightRigDirection: string | undefined,\n): BevelLightVector {\n\tif (!lightRigDirection) {\n\t\treturn { dx: -1, dy: -1 };\n\t}\n\tconst angle = DIRECTION_ANGLE[lightRigDirection];\n\tif (angle === undefined) {\n\t\treturn { dx: -1, dy: -1 };\n\t}\n\tconst bucket = Math.floor(angle / 90) * 90;\n\treturn CARDINAL_VECTORS[bucket] ?? { dx: -1, dy: -1 };\n}\n\n/**\n * Whether a `a:bevelT/@prst` profile measured an INVERTED highlight/shadow\n * relative to the shared cardinal-snap direction (see the module doc\n * comment): true only for `softRound`, which lit up the edge OPPOSITE the\n * light-rig direction in every one of the 8 directions tested.\n */\nexport function isBevelProfileInverted(bevelType: string): boolean {\n\treturn bevelType === 'softRound';\n}\n","/**\n * `a:bevelT/@prst` profile -> SVG height-map shape.\n *\n * Split out of `visual-3d-bevel-lighting-tables.ts` to keep both files under\n * the repo's ~300 LOC guideline; see that module's doc comment for the other\n * two axes (light rig elevation, material response) and the highlight\n * DIRECTION, which is resolved separately in `visual-3d-bevel-light.ts`.\n *\n * @module render/visual-3d-bevel-lighting-profile\n */\n\n/** How wide/sharp a bevel profile's SVG height-map ramp is, and how strongly it carries a directional signal. */\nexport interface BevelProfileHeightMap {\n\t/** `feGaussianBlur` `stdDeviation` factor, multiplied by the bevel's own (width+height)/2 in px. */\n\tblurFactor: number;\n\t/** `feMorphology` `radius` factor (erode), or `undefined` for a pure-blur (smooth, curved) profile. */\n\tmorphologyFactor?: number;\n\t/** Relief height (`surfaceScale`) factor: 1 = full, less for a shallow/steep-walled profile. */\n\tsurfaceScaleFactor: number;\n\t/**\n\t * `true` for the two profiles (`slope`, `hardEdge`) COM-measured (see\n\t * `visual-3d-bevel-light`) to show NO clean directional brightness signal\n\t * at any sampled depth, only a crisp, near-uniform self-shadowed seam. This\n\t * is about which CARDINAL EDGE lights up (or doesn't), independent of the\n\t * cross-section ramp SHAPE the factors below now target - see this\n\t * module's doc comment. Kept as a flag so callers/tests can assert on it\n\t * rather than re-deriving it from the two factors above.\n\t */\n\tmeasuredUniform: boolean;\n\t/**\n\t * Non-monotonic height REMAP for the three profiles (`relaxedInset`,\n\t * `slope`, `hardEdge`) whose COM cross-section is a genuine\n\t * bright-bump-then-dark-trough double transition (see this module's doc\n\t * comment), which the `blurFactor`/`morphologyFactor`/`surfaceScaleFactor`\n\t * ramp above cannot reproduce on its own: that ramp only ever builds a\n\t * single monotonic height field (alpha blurred, optionally eroded), so its\n\t * diffuse/specular response can rise-then-settle but never\n\t * rise-then-undershoot-then-settle.\n\t *\n\t * When present, `visual-3d-bevel-lighting.ts` feeds the monotonic ramp\n\t * through an SVG `feComponentTransfer`/`feFuncA type=\"table\"` BEFORE\n\t * lighting it: `feFuncA` linearly interpolates between these stops across\n\t * the input domain `[0, 1]`, so a table that rises then falls then rises\n\t * again reshapes the height field's spatial derivative (and therefore its\n\t * surface normal, and therefore its diffuse/specular brightness) into a\n\t * genuine two-lobe profile, even though the INPUT ramp it remaps is still\n\t * monotonic. This is the \"genuinely non-monotonic (two-lobe) height-map\"\n\t * the pre-2026-09-16 doc comment below flagged as out of scope; it is\n\t * cheap to build this way because `feComponentTransfer` remaps a value\n\t * pointwise, so it needs no new geometry primitive, just a reshaping stage\n\t * between the existing blur/erode step and `feDiffuseLighting`.\n\t *\n\t * Each profile's table is the profile's own pinned 24pt COM cross-section\n\t * curve (`visual-3d-bevel-lighting-tables.test.ts`'s\n\t * `MEASURED_24PT_CURVES`, 10 points from the top edge inward), normalised\n\t * to `[0, 1]` via `(brightness - min) / (max - min)`. This is a deliberate\n\t * choice, not a claim of a rigorously inverted lighting model: for a\n\t * gently-curved, primarily-diffuse height field the rendered brightness\n\t * tracks the local height fairly directly, so reusing the MEASURED\n\t * brightness curve's own shape as the height-remap curve reproduces the\n\t * measured peak/trough/recovery POSITIONS closely without solving the\n\t * (non-invertible in closed form) diffuse/specular equations backwards.\n\t * Verified structurally (`visual-3d-bevel-lighting.test.ts`): each table\n\t * is non-monotonic (has an interior local max followed by an interior\n\t * local min before recovering), and the generated filter markup carries\n\t * the `feComponentTransfer` stage only for these three profiles. NOT\n\t * independently re-verified against a fresh COM render (no new\n\t * `Slide.Export` measurement was taken for this change; the existing 2026-\n\t * 09 pins above are the ground truth reused here), so treat the exact\n\t * on-screen brightness as an analytical/geometric fit against already-\n\t * measured data, not a newly pixel-verified match.\n\t */\n\theightTransferTable?: readonly number[];\n}\n\n/**\n * `a:bevelT/@prst` (and `bevelB`, which shares the same profile vocabulary)\n * -> height-map shape. ECMA-376 20.1.10.9 describes each profile's silhouette\n * (a \"circular\", \"flat sloped\", \"crossed\", \"art-deco stepped\" etc.\n * cross-section); these factors were ORIGINALLY grouped into 3\n * physically-motivated buckets by that description (curved / faceted /\n * steep-narrow) rather than 12 independent hand-tuned entries, reasoned from\n * ECMA-376 alone.\n *\n * COM-MEASURED 2026-09 (real PowerPoint `Slide.Export`, mid-grey `matte`\n * square, `threePt` rig / `dir=\"t\"`, `orthographicFront` camera, both a 6pt\n * and a 24pt `a:bevelT`, a line of 40 brightness samples from the top edge\n * inward for all 12 profiles): fitting these SAME 3 factors (grid search,\n * minimum RMSE against the measured curve, both depths jointly) against real\n * cross-section data overturned the bucket story for 3 profiles.\n * `circle`/`convex`/`softRound`/`divot` (curved) and `angle`/`cross`/\n * `coolSlant`/`riblet`/`artDeco` (faceted) fit closely (RMSE 1-7 brightness\n * units) with factors in the same rough range as the original reasoning, so\n * their bucket membership held up. `relaxedInset`, `slope` and `hardEdge`\n * did NOT: all three measured a genuine BRIGHT-BUMP-THEN-DARK-TROUGH double\n * transition partway through the ramp (e.g. `hardEdge` at 24pt: baseline 133\n * -> peaks ~139 -> drops to 67 -> recovers), which this filter's single\n * monotonic blur(+erode) height map (one bell-shaped slope lobe) cannot\n * reproduce on its own - the original 3-parameter fit pushed\n * `surfaceScaleFactor` to the largest tested value trying to reach the\n * trough depth, landing the LARGEST relief factor of any profile, the\n * opposite of the pre-2026-09 \"slope/hardEdge are low-relief\" assumption\n * (`slope`/`hardEdge` were previously reasoned as \"steep/narrow\" with\n * REDUCED relief; `relaxedInset` was previously grouped as \"curved\" with\n * full relief and no erode at all), but still only reached RMSE 12-19\n * against the measured curve (versus 1-7 for the other 9).\n *\n * **2026-09-16: closed via a height-remap stage.** These three profiles now\n * also carry a `heightTransferTable` (see that field's own doc comment\n * above): an `feComponentTransfer`/`feFuncA type=\"table\"` reshaping stage,\n * inserted between the existing blur(+erode) ramp and the lighting\n * primitives, remaps the monotonic ramp through each profile's own measured\n * bright-bump-then-dark-trough curve shape. The three factors below (blur/\n * morphology/surfaceScale) are UNCHANGED and still control the underlying\n * ramp's width and crispness; the new field supplies the genuinely\n * non-monotonic (two-lobe) height response this doc comment previously\n * flagged as needing a new primitive chain, without actually needing one.\n * This was NOT re-verified against a fresh COM render (see\n * `heightTransferTable`'s doc comment); it is an analytical/geometric fit\n * against the SAME measured curves pinned below, not a new measurement - see\n * `docs/guide/limitations.md` and `docs/guide/visual-effects.md` for the\n * current framing.\n *\n * The direction-independence these three still show (`measuredUniform`) is\n * unaffected: it is a separate, already-COM-confirmed finding (see\n * `visual-3d-bevel-light.ts`'s module doc comment) about which CARDINAL EDGE\n * lights up, not about the cross-section ramp shape this campaign measures.\n * Scripts (scratch, not committed, same convention as `com-acceptance.mjs`):\n * `scripts/make-bevel-profile-fixture.mjs` (fixture, all 12\n * profiles x 2 depths), `scripts/measure-bevel-profile-com.ps1`\n * (COM export + 40-point sampler), `scripts/fit-bevel-profile-com.mjs`\n * (grid-search fit; a closed-form Gaussian-CDF reimplementation of the\n * primitive chain, not a headless-browser render - Playwright's Chromium\n * launch hangs indefinitely via a plain script in this environment, though\n * `bunx playwright test` itself works fine, used to independently verify the\n * metal/circle routing conclusion in `visual-3d-bevel-lighting-routing.ts`).\n * The raw 10-point-per-profile table (24pt depth) is pinned in\n * `visual-3d-bevel-lighting-tables.test.ts`; the full 40-point x 2-depth\n * table is in the task report.\n */\nexport const BEVEL_PROFILE_HEIGHT_MAP: Record<string, BevelProfileHeightMap> = {\n\tcircle: { blurFactor: 0.35, surfaceScaleFactor: 0.65, measuredUniform: false },\n\tconvex: {\n\t\tblurFactor: 0.18,\n\t\tmorphologyFactor: 0.4,\n\t\tsurfaceScaleFactor: 0.2,\n\t\tmeasuredUniform: false,\n\t},\n\tsoftRound: {\n\t\tblurFactor: 0.25,\n\t\tmorphologyFactor: 0.4,\n\t\tsurfaceScaleFactor: 0.65,\n\t\tmeasuredUniform: false,\n\t},\n\trelaxedInset: {\n\t\tblurFactor: 0.35,\n\t\tmorphologyFactor: 0.5,\n\t\tsurfaceScaleFactor: 1.5,\n\t\tmeasuredUniform: false,\n\t\t// Normalised (0-1) directly from the pinned 24pt COM cross-section\n\t\t// curve (`visual-3d-bevel-lighting-tables.test.ts`'s\n\t\t// `MEASURED_24PT_CURVES.relaxedInset`, brightness 113.0/135.7/139.0/\n\t\t// 137.0/60.0/85.3/126.3/133.0/133.0/133.0): peaks at stop 2, troughs at\n\t\t// stop 4, recovers to flat by stop 6. See `heightTransferTable`'s doc\n\t\t// comment.\n\t\theightTransferTable: [0.671, 0.958, 1.0, 0.975, 0.0, 0.32, 0.839, 0.924, 0.924, 0.924],\n\t},\n\tdivot: { blurFactor: 0.18, surfaceScaleFactor: 0.5, measuredUniform: false },\n\tangle: {\n\t\tblurFactor: 0.35,\n\t\tmorphologyFactor: 0.4,\n\t\tsurfaceScaleFactor: 0.35,\n\t\tmeasuredUniform: false,\n\t},\n\tcross: {\n\t\tblurFactor: 0.12,\n\t\tmorphologyFactor: 0.18,\n\t\tsurfaceScaleFactor: 0.2,\n\t\tmeasuredUniform: false,\n\t},\n\tcoolSlant: {\n\t\tblurFactor: 0.25,\n\t\tmorphologyFactor: 0.06,\n\t\tsurfaceScaleFactor: 0.5,\n\t\tmeasuredUniform: false,\n\t},\n\triblet: {\n\t\tblurFactor: 0.25,\n\t\tsurfaceScaleFactor: 0.5,\n\t\tmeasuredUniform: false,\n\t},\n\tartDeco: {\n\t\tblurFactor: 0.18,\n\t\tmorphologyFactor: 0.32,\n\t\tsurfaceScaleFactor: 0.35,\n\t\tmeasuredUniform: false,\n\t},\n\t// `relaxedInset`/`slope`/`hardEdge` (see this table's doc comment): COM\n\t// measured a genuine BRIGHT-BUMP-THEN-DARK-TROUGH double transition for\n\t// all three, which the blur(+erode) ramp's ORIGINAL 3 factors alone cannot\n\t// reproduce (its height field has one bell-shaped slope lobe, so the\n\t// diffuse/specular response can only rise-then-settle, never\n\t// rise-then-undershoot-then-settle). These 3 factors are kept as the\n\t// closest achievable fit for the underlying ramp's width/crispness; each\n\t// profile's `heightTransferTable` (see that field's doc comment) supplies\n\t// the actual non-monotonic double transition on top of that ramp.\n\tslope: {\n\t\tblurFactor: 0.55,\n\t\tmorphologyFactor: 0.5,\n\t\tsurfaceScaleFactor: 1.5,\n\t\tmeasuredUniform: true,\n\t\t// Normalised from `MEASURED_24PT_CURVES.slope` (114.0/134.7/133.3/\n\t\t// 133.0/91.7/110.0/96.0/133.0/133.0/133.0): peaks at stop 1, dips at\n\t\t// stop 4, a second shallower dip at stop 6, recovers by stop 7.\n\t\theightTransferTable: [0.519, 1.0, 0.967, 0.96, 0.0, 0.426, 0.1, 0.96, 0.96, 0.96],\n\t},\n\thardEdge: {\n\t\tblurFactor: 0.55,\n\t\tmorphologyFactor: 0.5,\n\t\tsurfaceScaleFactor: 1.5,\n\t\tmeasuredUniform: true,\n\t\t// Normalised from `MEASURED_24PT_CURVES.hardEdge` (111.7/135.0/133.0/\n\t\t// 133.0/102.7/104.0/128.3/133.0/133.0/133.0): peaks at stop 1, troughs\n\t\t// at stop 4, recovers by stop 6.\n\t\theightTransferTable: [0.279, 1.0, 0.938, 0.938, 0.0, 0.04, 0.793, 0.938, 0.938, 0.938],\n\t},\n};\n\nconst DEFAULT_HEIGHT_MAP: BevelProfileHeightMap = {\n\tblurFactor: 0.4,\n\tsurfaceScaleFactor: 0.8,\n\tmeasuredUniform: false,\n};\n\nexport function getBevelProfileHeightMap(bevelType: string): BevelProfileHeightMap {\n\treturn BEVEL_PROFILE_HEIGHT_MAP[bevelType] ?? DEFAULT_HEIGHT_MAP;\n}\n","/**\n * Material -> `feDiffuseLighting`/`feSpecularLighting` response table.\n *\n * Split out of `visual-3d-bevel-lighting-tables.ts` to keep both files under\n * the repo's ~300 LOC guideline; see that module's doc comment for the other\n * two axes (bevel profile height-map shape, light rig elevation).\n *\n * @module render/visual-3d-bevel-lighting-material\n */\n\nimport type { MaterialPresetType } from 'pptx-viewer-core';\n\n/** feDiffuseLighting/feSpecularLighting constants for a material preset. */\nexport interface MaterialLighting {\n\tdiffuseConstant: number;\n\tspecularConstant: number;\n\tspecularExponent: number;\n\t/** `lighting-color` for both primitives; a hex string. */\n\tlightingColor: string;\n\t/**\n\t * Multiplies the profile-derived `surfaceScale` (default 1 = unchanged).\n\t * Calibrated per material against the COM highlight/shadow table (see\n\t * this module's doc comment): a material whose true shadow-side\n\t * reflectance sits far above a fully-shadowed (`N.L <= 0`, clamped to\n\t * black) diffuse response needs a SHALLOWER effective height map (a\n\t * smaller multiplier) so fewer height-map texels clamp to zero at the\n\t * measurement offset, not a differently-shaped one.\n\t */\n\tsurfaceScaleMultiplier: number;\n\t/**\n\t * Caps the `feSpecularLighting` light's OWN elevation at this value\n\t * (degrees), independent of the diffuse `a:lightRig` elevation table.\n\t * `undefined` (every material except `metal`) means the specular light\n\t * reuses the diffuse elevation unchanged, today's behaviour. See\n\t * `visual-3d-bevel-lighting.ts`'s module doc for why this exists: at a\n\t * flat (unbevelled) normal, `feSpecularLighting`'s closed-form hot-spot\n\t * brightness is `specularConstant * max(0, N.H)^specularExponent`, and\n\t * `N.H` -> 1 as the light elevation -> 90deg, so a high-elevation rig\n\t * (`flat`, `contrasting`, `threePt`, ...) saturates the ENTIRE shape, not\n\t * just its bevel band, for any material with a non-negligible\n\t * `specularConstant`. Capping only the SPECULAR light's elevation (never\n\t * the diffuse one, so diffuse shading is untouched) bounds `N.H` below 1\n\t * for those rigs while leaving already-low-elevation rigs (`morning`,\n\t * `sunrise`, ...) unchanged, since `Math.min(rigElevationDeg, cap)` is a\n\t * no-op below the cap.\n\t */\n\tspecularElevationCapDeg?: number;\n}\n\nconst white = '#ffffff';\n\n/**\n * `a:sp3d/@prstMaterial` -> lighting response. COM-measured (2026-09, real\n * PowerPoint, `Slide.Export`, 0.15in-from-edge sample) comparing `matte`\n * against `metal` at `dir=\"t\"`/`\"r\"`/`\"b\"`/`\"l\"` for `circle`/`angle`/\n * `hardEdge`/`softRound` (32 samples; mean highlight/shadow brightness,\n * 0-255, averaged over direction): `metal` measured UNIFORMLY BRIGHTER than\n * `matte` at BOTH the highlight and shadow sample points in every profile\n * (circle 221/178 vs 137/90, angle 141/86 vs 139/64, hardEdge 137/137 vs\n * 133/133, softRound 85/141 vs 63/139) - consistent with a higher overall\n * reflectivity - but did NOT measure a higher highlight-minus-shadow\n * CONTRAST at this fixed sample distance: contrast was about equal for\n * `circle` (43 vs 47) and LOWER for `metal` on `angle` (55 vs 75) and\n * `softRound` (56 vs 76 in magnitude). This does not confirm the \"narrower,\n * sharper specular falloff\" story this module's `specularConstant`/\n * `specularExponent` tuning assumes; a plausible explanation is that a real\n * metal specular peak sits closer than 0.15in to the edge, so a fixed-offset\n * sample already reads past it into a brighter but flatter region - but that\n * is inference from this one campaign, not a second confirmed measurement at\n * a different offset. A live render-vs-COM check (`visual-3d-bevel-lighting\n * .ts`'s module doc table) found this module's `metal` numbers give a mixed\n * result: `matte` improved clearly over the old box-shadow approach (56.3 ->\n * 34.8 mean error) while `metal` did not (61.2 -> 59.7, and `metal`/`circle`\n * specifically got WORSE, 54.9 -> 80.1) - the constants below were therefore\n * flagged UNVALIDATED for `metal`, and `metal`/`circle` was ROUTED to the\n * legacy box-shadow model (`visual-3d-bevel-lighting-routing.ts`). The other\n * materials are positioned between/around the `matte`/`metal` anchors by\n * category (glossy plastics near `metal` but softer, matte/powder variants\n * near `matte`), not independently COM-measured at all.\n *\n * RESOLVED for `metal`/`circle` (2026-09, the bevel-profile cross-section\n * campaign, `visual-3d-bevel-lighting-tables.ts`'s `BEVEL_PROFILE_HEIGHT_MAP`\n * doc comment): re-fitting `circle`'s profile-table entry against real COM\n * cross-section data (unrelated to material tuning) changed\n * `surfaceScaleFactor` from 1 to 0.65, and with these SAME `metal` constants\n * (unchanged from the paragraph above) that alone brought `metal`/`circle`'s\n * mean error to 39.5 against the SAME 54.9 baseline - confirmed against\n * fresh COM ground truth AND an actual headless-Chromium rasterisation of\n * the real filter chain (not just the closed-form model this module's own\n * campaigns otherwise used), so `metal`/`circle` no longer routes; see\n * `visual-3d-bevel-lighting-routing.ts`'s doc comment for the numbers and a\n * separate, NOT-landed attempt at fixing the flat-interior specular\n * saturation defect below.\n */\nexport const MATERIAL_LIGHTING: Record<MaterialPresetType, MaterialLighting> = {\n\tmatte: {\n\t\tdiffuseConstant: 0.9,\n\t\tspecularConstant: 0.02,\n\t\tspecularExponent: 4,\n\t\tlightingColor: white,\n\t\tsurfaceScaleMultiplier: 1,\n\t},\n\twarmMatte: {\n\t\tdiffuseConstant: 0.9,\n\t\tspecularConstant: 0.03,\n\t\tspecularExponent: 4,\n\t\tlightingColor: '#fff4e6',\n\t\tsurfaceScaleMultiplier: 1,\n\t},\n\tpowder: {\n\t\tdiffuseConstant: 0.85,\n\t\tspecularConstant: 0.02,\n\t\tspecularExponent: 4,\n\t\tlightingColor: white,\n\t\tsurfaceScaleMultiplier: 1,\n\t},\n\ttranslucentPowder: {\n\t\tdiffuseConstant: 0.8,\n\t\tspecularConstant: 0.08,\n\t\tspecularExponent: 6,\n\t\tlightingColor: white,\n\t\tsurfaceScaleMultiplier: 1,\n\t},\n\tplastic: {\n\t\tdiffuseConstant: 0.85,\n\t\tspecularConstant: 0.35,\n\t\tspecularExponent: 12,\n\t\tlightingColor: white,\n\t\tsurfaceScaleMultiplier: 1,\n\t},\n\tclear: {\n\t\tdiffuseConstant: 0.7,\n\t\tspecularConstant: 0.45,\n\t\tspecularExponent: 16,\n\t\tlightingColor: white,\n\t\tsurfaceScaleMultiplier: 1,\n\t},\n\tsoftEdge: {\n\t\tdiffuseConstant: 0.85,\n\t\tspecularConstant: 0.15,\n\t\tspecularExponent: 8,\n\t\tlightingColor: white,\n\t\tsurfaceScaleMultiplier: 1,\n\t},\n\tdkEdge: {\n\t\tdiffuseConstant: 0.75,\n\t\tspecularConstant: 0.2,\n\t\tspecularExponent: 14,\n\t\tlightingColor: '#f0f0f0',\n\t\tsurfaceScaleMultiplier: 1,\n\t},\n\tsoftmetal: {\n\t\tdiffuseConstant: 0.65,\n\t\tspecularConstant: 0.6,\n\t\tspecularExponent: 16,\n\t\tlightingColor: white,\n\t\tsurfaceScaleMultiplier: 1,\n\t},\n\t// Re-calibrated (2026-09, manual coordinate search evaluated against the\n\t// real render-vs-COM pipeline used throughout this module, all 4\n\t// `a:lightRig/@dir` values): the previous (diffuseConstant 0.55,\n\t// specularConstant 0.9, specularExponent 28, surfaceScaleMultiplier\n\t// implicitly 1) combination regressed `circle` specifically (54.9 ->\n\t// 80.1 mean error). This combination (surfaceScaleMultiplier 0.35,\n\t// diffuseConstant raised to 0.75) VERIFIED to bring `angle`, `hardEdge`\n\t// and `softRound` at or below the box-shadow baseline in EVERY direction\n\t// (`angle`: baseline ~70, now ~19-27; `hardEdge`: baseline ~69.5, now 44;\n\t// `softRound`: baseline ~50, now 6.5-19). `circle` alone could NOT be\n\t// brought below baseline with any tested combination of these four\n\t// MATERIAL parameters (tried down to `surfaceScaleMultiplier` 0.15 and up\n\t// to 2.5) against the then-current (ECMA-376-reasoned) profile table, and\n\t// was routed to the legacy `box-shadow` model instead of shipping a\n\t// regression. SUPERSEDED 2026-09: re-fitting the PROFILE table's own\n\t// `circle` entry against real COM data (a change orthogonal to these\n\t// material constants) resolved it without touching the numbers below; see\n\t// this file's module doc comment and `visual-3d-bevel-lighting-routing\n\t// .ts`.\n\t//\n\t// A SEPARATE, more severe issue was found (2026-09, while attempting an\n\t// ambient/wrap-term fix for the `circle` routing above) that this\n\t// calibration was never tested against: `specularConstant: 0.9` combined\n\t// with `specularExponent: 24` was tuned against `threePt` at its OLD\n\t// (pre-COM-calibration) `elevationDeg` of 45. `LIGHT_RIG_LIGHTING`'s real\n\t// per-rig COM campaign now measures `threePt` at `elevationDeg: 74`, and\n\t// several other rigs (`contrasting`, the `flat`/`legacyFlat*` family) sit\n\t// at 90. `feSpecularLighting`'s hot-spot brightness at a FLAT height-map\n\t// region (i.e. the shape's plain, non-bevelled interior, not just the\n\t// bevel band: N = (0,0,1) there regardless of `a:bevelT/@prst`, so this\n\t// is independent of bevel PROFILE) is `specularConstant *\n\t// max(0, N.H)^specularExponent`; solving that formula directly (not\n\t// rendered, the closed form) gives 0.135 at elevation 45 (small, as the\n\t// original calibration assumed) but 0.71 at elevation 74 and 0.9 (the\n\t// full `specularConstant`, N.H=1 exactly) at elevation 90 - confirmed by\n\t// actually rendering the real filter chain (a pure-SVG render matching\n\t// `resolveLayer`'s output byte-for-byte): a `metal`/`circle` square under\n\t// `threePt` now samples FULLY SATURATED (255,255,255) at its edge bands\n\t// AND its flat center alike, not just a shadow-side clamp. This means the\n\t// `circle`-only routing above no longer isolates the real defect for\n\t// these rigs: the whole shape washes out, so an ambient/wrap term on the\n\t// diffuse layer (which only helps the shadow-clamp problem) would not by\n\t// itself bring metal back under the box-shadow baseline. This is a\n\t// STRUCTURAL gap (this filter drives diffuse falloff and the specular\n\t// hot-spot from the SAME `feDistantLight` elevation, but a coupling this\n\t// codebase's simplified model never validated), not specific to `circle`\n\t// or to this pass's elevation recalibration (`flat`'s elevationDeg was\n\t// already ~90 before this campaign, so the same saturation already\n\t// existed for `metal` under the `flat` rig family; the campaign only\n\t// widened which rigs trigger it, by correcting `threePt`/`contrasting`\n\t// toward their real measured values). Re-tuning `specularConstant`/\n\t// `specularExponent` (or decoupling a separate specular elevation from\n\t// the diffuse one) needs its own COM campaign and was NOT done here; see\n\t// `docs/guide/limitations.md`.\n\t// RESOLVED (2026-09-24): the structural \"same feDistantLight elevation\n\t// drives diffuse falloff AND the specular hot-spot\" coupling described\n\t// above is fixed by `specularElevationCapDeg` (see `MaterialLighting`'s\n\t// doc comment): `Math.min(rigElevationDeg, 45)` bounds the SPECULAR\n\t// light's own elevation, leaving diffuse shading (and every low-elevation\n\t// rig, which is already below the cap) untouched. A joint coordinate\n\t// search of `specularElevationCapDeg`/`specularConstant`/\n\t// `specularExponent` (surfaceScaleMultiplier held fixed at 0.35, since\n\t// lowering it flattens the DIFFUSE band too and was a different, already\n\t// separately-calibrated defect) against real COM ground truth (`Slide\n\t// .Export`, mid-grey square, 24pt bevel, headless-Chromium rasterisation\n\t// of the ACTUAL filter chain, same pipeline as this module's other\n\t// campaigns) - 134 conditions: all 8 `com-main`-campaign rigs x 12\n\t// profiles, plus all 19 `com-rigs`-campaign rigs x `circle`/`angle`, all\n\t// `dir=\"t\"`, full 96-sample cross-section MAE (not just the 2-edge-point\n\t// sample the earlier campaigns used, which cannot see this\n\t// flat-interior defect) - found specularConstant 0.5/specularExponent\n\t// 16/cap 45deg: mean absolute error (0-255) fell from 75.0 (the previous,\n\t// coupled-elevation constants) to 36.4 on this set, driven mostly by the\n\t// flat-interior term (centerAE 89.2 -> 20.4). The two previously-tried\n\t// remediations documented in `visual-3d-bevel-lighting.ts`'s module doc\n\t// (a FIXED specular elevation with the OLD specularConstant/Exponent, and\n\t// specular-band masking) are superseded by this cap + re-fit; see that\n\t// module's doc for their numbers. Every OTHER material is a structural\n\t// no-op (no `specularElevationCapDeg`), so this cannot regress them.\n\tmetal: {\n\t\tdiffuseConstant: 0.75,\n\t\tspecularConstant: 0.5,\n\t\tspecularExponent: 16,\n\t\tlightingColor: white,\n\t\tsurfaceScaleMultiplier: 0.35,\n\t\tspecularElevationCapDeg: 45,\n\t},\n\tflat: {\n\t\tdiffuseConstant: 0.9,\n\t\tspecularConstant: 0,\n\t\tspecularExponent: 1,\n\t\tlightingColor: white,\n\t\tsurfaceScaleMultiplier: 1,\n\t},\n\tlegacyMatte: {\n\t\tdiffuseConstant: 0.88,\n\t\tspecularConstant: 0.02,\n\t\tspecularExponent: 4,\n\t\tlightingColor: white,\n\t\tsurfaceScaleMultiplier: 1,\n\t},\n\tlegacyPlastic: {\n\t\tdiffuseConstant: 0.82,\n\t\tspecularConstant: 0.3,\n\t\tspecularExponent: 10,\n\t\tlightingColor: white,\n\t\tsurfaceScaleMultiplier: 1,\n\t},\n\t// Not independently calibrated; positioned near the calibrated `metal`\n\t// entry (same category) rather than the pre-calibration guess.\n\tlegacyMetal: {\n\t\tdiffuseConstant: 0.7,\n\t\tspecularConstant: 0.8,\n\t\tspecularExponent: 22,\n\t\tlightingColor: white,\n\t\tsurfaceScaleMultiplier: 0.45,\n\t},\n\tlegacyWireframe: {\n\t\tdiffuseConstant: 0.9,\n\t\tspecularConstant: 0.05,\n\t\tspecularExponent: 6,\n\t\tlightingColor: white,\n\t\tsurfaceScaleMultiplier: 1,\n\t},\n};\n\n/**\n * PowerPoint's documented default `prstMaterial` (ECMA-376 20.1.10.50) when\n * `a:sp3d` carries a bevel but no explicit material attribute.\n */\nconst DEFAULT_MATERIAL: MaterialPresetType = 'warmMatte';\n\nexport function getMaterialLighting(material: string | undefined): MaterialLighting {\n\tconst key = (material as MaterialPresetType | undefined) ?? DEFAULT_MATERIAL;\n\treturn MATERIAL_LIGHTING[key] ?? MATERIAL_LIGHTING[DEFAULT_MATERIAL];\n}\n","/**\n * Data tables for the real SVG lighting bevel filter (framework-agnostic).\n *\n * Split out of `visual-3d-bevel-lighting.ts` to keep that module under the\n * repo's ~300 LOC guideline. Three independent axes feed the filter this\n * module's data drives: bevel PROFILE shape (`a:bevelT/@prst`, ECMA-376\n * 20.1.10.9 `ST_BevelPresetType`, re-exported here but defined in\n * `visual-3d-bevel-lighting-profile.ts`, itself split out for the same LOC\n * reason), light rig ELEVATION/specular character (`a:lightRig/@rig`,\n * ECMA-376 20.1.10.36 `ST_LightRigType`, defined below), and MATERIAL\n * response (`a:sp3d/@prstMaterial`, ECMA-376 20.1.10.50 `ST_PresetMaterialType`,\n * re-exported from `visual-3d-bevel-lighting-material.ts`).\n * The highlight/shadow DIRECTION (azimuth) itself is mostly resolved\n * elsewhere: `visual-3d-bevel-light`'s already COM-measured cardinal-snap\n * vector supplies the base azimuth from `a:lightRig/@dir`, and this module's\n * `LIGHT_RIG_LIGHTING.invertedDirection` (COM-measured, see that export's own\n * doc comment) supplies the one further correction that vector doesn't\n * cover: 10 of the 27 rigs flip which cardinal edge lights up.\n *\n * An early COM check (2026-09, PowerPoint `Slide.Export`, mid-grey 1.4in\n * square, `circle`/matte, `dir=\"t\"`, sampled 0.15in from the top and bottom\n * edges) did NOT confirm the then-assumed \"harsh has higher contrast than\n * threePt\" ordering at that sample distance: measured contrast (highlight\n * brightness minus shadow brightness, 0-255) was `threePt` 47, `soft` 38,\n * `flat` 0 (exactly, matching `flat`'s intentional no-op design), and `harsh`\n * only -4. A full 27-rig, two-direction (`dir=\"t\"` and the perpendicular\n * `dir=\"r\"`) follow-up campaign (see `LIGHT_RIG_LIGHTING`'s doc comment)\n * resolved this: `harsh`'s -4 was not noise or a narrower falloff band, it\n * was `harsh` being one of the 10 `invertedDirection` rigs (highlight on the\n * edge OPPOSITE `dir`, so its small measured value is a near-flat rig with\n * the \"wrong\" sign, not a sharp rig sampled past its falloff). See\n * `visual-3d-bevel-lighting.ts`'s module doc for the (separately real)\n * profile x material x direction COM comparison table.\n *\n * @module render/visual-3d-bevel-lighting-tables\n */\n\nexport {\n\tBEVEL_PROFILE_HEIGHT_MAP,\n\tgetBevelProfileHeightMap,\n} from './visual-3d-bevel-lighting-profile';\nexport type { BevelProfileHeightMap } from './visual-3d-bevel-lighting-profile';\n\n/** Light elevation (degrees, 0 = grazing, 90 = straight-on) and specular sharpness bucket for a light rig. */\nexport interface LightRigLighting {\n\televationDeg: number;\n\t/** `feSpecularLighting`'s `specularExponent` multiplier (1 = neutral). */\n\tspecularSharpness: number;\n\t/**\n\t * `true` when this rig's measured highlight sits on the edge OPPOSITE\n\t * `a:lightRig/@dir` rather than the edge `dir` points at (see this\n\t * module's doc comment). Combines with (multiplies) the bevel-profile\n\t * inversion `isBevelProfileInverted` already applies, the same way that\n\t * flag and the top/bottom-bevel inversion already combine.\n\t */\n\tinvertedDirection?: boolean;\n}\n\n/**\n * `a:lightRig/@rig` -> elevation/sharpness/direction. COM-CALIBRATED\n * (2026-09, real PowerPoint `Slide.Export`, mid-grey #808080 1.4in square,\n * `matte`/`circle`, 24pt bevel, `orthographicFront`, all 27 `ST_LightRigType`\n * tokens, sampled 0.15in from edge, Rec.709 luminance): a `dir=\"t\"` campaign\n * (sampling the top/bottom edges) and an independent `dir=\"r\"` campaign\n * (sampling left/right) were run for every rig; the two agreed on both sign\n * and magnitude for all 27 rigs (mean absolute difference under 1 brightness\n * unit), confirming `a:lightRig/@dir` genuinely rotates each rig's effective\n * azimuth (not a fixed, `dir`-independent offset) and that the per-rig\n * finding below is repeatable, not sampling noise. Scripts (scratch, not\n * committed, same convention as `com-acceptance.mjs`):\n * `scripts/_scratch-make-lightrig-fixture.mjs` (dir=\"t\" fixture, all 27\n * rigs), `scripts/_scratch-make-lightrig-fixture-dirR.mjs` (dir=\"r\"\n * counterpart), `scripts/_scratch-measure-sample.ps1` (generic COM\n * `Slide.Export` + pixel sampler). Raw per-rig table (brightness 0-255,\n * `contrast` = highlight edge minus opposite edge, averaged between the two\n * campaigns):\n *\n * ```\n * rig contrast elevationDeg invertedDirection\n * legacyHarsh2 49.0 73 false\n * threePt 47.5 74 false\n * legacyNormal2 43.0 75 false\n * soft 38.5 77 false\n * legacyFlat2 37.0 77 false\n * flood 15.5 85 false\n * legacyHarsh1 0.0 90 false\n * legacyFlat1 -0.5 90 false\n * legacyFlat3 0.0 90 false\n * legacyNormal1 0.0 90 false\n * legacyNormal3 0.0 90 false\n * legacyHarsh3 0.0 90 false\n * contrasting 0.0 90 false\n * flat 0.0 90 false\n * glow 0.0 90 false\n * brightRoom 0.0 90 false\n * harsh -4.0 89 true\n * balanced -6.0 88 true\n * twoPt -30.5 79 true\n * legacyFlat4 -37.0 77 true\n * legacyNormal4 -43.0 75 true\n * legacyHarsh4 -49.0 73 true\n * sunset -74.0 64 true\n * freezing -79.1 62 true\n * chilly -80.2 62 true\n * sunrise -88.6 59 true\n * morning -101.1 54 true\n * ```\n *\n * `elevationDeg` was fit (not guessed) by rendering the ACTUAL production SVG\n * filter primitive chain (`visual-3d-bevel-lighting.ts`'s\n * `resolveLayer`/`renderLayerPrimitives`, reusing the SAME `getBevelProfile\n * HeightMap('circle')`/`getMaterialLighting('matte')` table lookups this\n * module already exports) for `elevationDeg` swept 5..90 in 5deg steps at the\n * identical geometry, taking a pure-SVG (no `foreignObject`, so the canvas\n * read-back isn't tainted) screenshot-equivalent raster via a headless\n * Chromium `<canvas>` draw, and sampling the SAME 0.15in-from-edge points.\n * That render-side sweep is monotonically decreasing in contrast across\n * `elevationDeg` 45..90 (117 down to 0 brightness units), which covers every\n * measured `|contrast|` above (max 101.1); each rig's `elevationDeg` is the\n * piecewise-linear inverse of its measured `|contrast|` against that curve\n * (`scripts/_scratch-lightrig-calibration-gen.mjs` + a canvas sampler\n * embedded in `scripts/_scratch-sample-host.html`, both scratch/uncommitted).\n * `specularSharpness` was NOT part of this campaign (only `elevationDeg`/\n * `invertedDirection` were COM-fit) and keeps its pre-existing REASONED\n * per-family value.\n *\n * The most consequential finding is `invertedDirection`: 10 of the 27 rigs\n * (`harsh`, `balanced`, `twoPt`, the `*4` legacy variant of each `legacy{Flat,\n * Normal,Harsh}` family, and all 5 weather rigs `morning`/`sunrise`/`sunset`/\n * `chilly`/`freezing`) measure their highlight on the edge OPPOSITE\n * `a:lightRig/@dir`, not the edge `dir` points at - the previous reasoned\n * table had no way to represent this (a single `elevationDeg` cannot flip\n * azimuth) and silently got the highlight side backwards for all 10.\n * `legacyFlat2`/`legacyNormal2`/`legacyHarsh2` and their `*4` mirror twins\n * are NOT interchangeable within a \"legacy family\" the way the old table\n * assumed (both grouped to one shared value): `*1`/`*3` measure a clean\n * `elevationDeg=90` (no directional signal at that sample offset) while `*2`\n * is normal-direction and `*4` is its exact `invertedDirection` mirror\n * (matching magnitude, opposite sign) - each of the 4 numbered variants in a\n * legacy family is now its own table entry rather than 4 copies of one value.\n */\nexport const LIGHT_RIG_LIGHTING: Record<string, LightRigLighting> = {\n\tflat: { elevationDeg: 90, specularSharpness: 0.3 },\n\tlegacyFlat1: { elevationDeg: 90, specularSharpness: 0.3 },\n\tlegacyFlat2: { elevationDeg: 77, specularSharpness: 0.3 },\n\tlegacyFlat3: { elevationDeg: 90, specularSharpness: 0.3 },\n\tlegacyFlat4: { elevationDeg: 77, specularSharpness: 0.3, invertedDirection: true },\n\tharsh: { elevationDeg: 89, specularSharpness: 1.6, invertedDirection: true },\n\tcontrasting: { elevationDeg: 90, specularSharpness: 1.5 },\n\tlegacyHarsh1: { elevationDeg: 90, specularSharpness: 1.5 },\n\tlegacyHarsh2: { elevationDeg: 73, specularSharpness: 1.4 },\n\tlegacyHarsh3: { elevationDeg: 90, specularSharpness: 1.5 },\n\tlegacyHarsh4: { elevationDeg: 73, specularSharpness: 1.4, invertedDirection: true },\n\tsoft: { elevationDeg: 77, specularSharpness: 0.6 },\n\tflood: { elevationDeg: 85, specularSharpness: 0.7 },\n\tglow: { elevationDeg: 90, specularSharpness: 0.5 },\n\tbrightRoom: { elevationDeg: 90, specularSharpness: 0.65 },\n\tmorning: { elevationDeg: 54, specularSharpness: 0.75, invertedDirection: true },\n\tsunrise: { elevationDeg: 59, specularSharpness: 0.8, invertedDirection: true },\n\tsunset: { elevationDeg: 64, specularSharpness: 0.8, invertedDirection: true },\n\tchilly: { elevationDeg: 62, specularSharpness: 0.6, invertedDirection: true },\n\tfreezing: { elevationDeg: 62, specularSharpness: 0.6, invertedDirection: true },\n\tthreePt: { elevationDeg: 74, specularSharpness: 1 },\n\tbalanced: { elevationDeg: 88, specularSharpness: 0.95, invertedDirection: true },\n\ttwoPt: { elevationDeg: 79, specularSharpness: 1, invertedDirection: true },\n\tlegacyNormal1: { elevationDeg: 90, specularSharpness: 1 },\n\tlegacyNormal2: { elevationDeg: 75, specularSharpness: 1 },\n\tlegacyNormal3: { elevationDeg: 90, specularSharpness: 1 },\n\tlegacyNormal4: { elevationDeg: 75, specularSharpness: 1, invertedDirection: true },\n};\n\nconst DEFAULT_LIGHT_RIG: LightRigLighting = { elevationDeg: 45, specularSharpness: 1 };\n\nexport function getLightRigLighting(rigType: string | undefined): LightRigLighting {\n\tif (!rigType) {\n\t\treturn DEFAULT_LIGHT_RIG;\n\t}\n\treturn LIGHT_RIG_LIGHTING[rigType] ?? DEFAULT_LIGHT_RIG;\n}\n\nexport { getMaterialLighting, MATERIAL_LIGHTING } from './visual-3d-bevel-lighting-material';\nexport type { MaterialLighting } from './visual-3d-bevel-lighting-material';\n","/**\n * Shared constants for the CSS-based 3D approximation (framework-agnostic).\n *\n * @module render/visual-3d-constants\n */\n\n/**\n * EMU per CSS pixel. PowerPoint stores 3D dimensions in English Metric Units;\n * the React layer uses the same constant (9525). Defined locally to keep the\n * 3D modules self-contained.\n */\nexport const EMU_PER_PX = 9525;\n\n/**\n * Maximum stacked shadow layers for extrusion (performance guard). Matches the\n * React engine — each layer is a single box-shadow, so 40 is still performant.\n */\nexport const MAX_EXTRUSION_LAYERS = 40;\n","/**\n * Legacy camera-preset -> rotateX/rotateY/rotateZ + perspective-distance\n * table (framework-agnostic).\n *\n * Split out of `visual-3d-camera.ts` to keep that file under the repo's LOC\n * guideline. As of the 2026-09 off-axis-camera homography wave (see\n * `visual-3d-camera-homography`'s module doc comment), this table's angles\n * are ONLY the actual rendered transform for a preset with no COM-measured\n * homography, or when an explicit `a:camera/a:rot`/`@fov`/`@zoom` override is\n * present; for every other preset it now serves solely as an extrusion\n * panel-visibility/shading DIRECTION HINT (`visual-3d-camera`'s\n * `cameraFlatFace` doc comment explains why a pure front-face measurement\n * cannot always recover this, e.g. `isometricTopUp` vs `isometricBottomUp`).\n *\n * @module render/visual-3d-camera-presets\n */\n\n/**\n * Camera preset configuration: reference perspective distance (px, at\n * `visual-3d-camera-fov`'s `REFERENCE_SIZE_PX`) and base rotation angles (in degrees). These\n * approximate the OOXML camera preset positions.\n */\nexport interface CameraPresetConfig {\n\t/** Reference CSS perspective distance in px at `visual-3d-camera-fov`'s `REFERENCE_SIZE_PX`, or `undefined` for a parallel (non-perspective) projection. */\n\tperspectiveRefPx?: number;\n\trotateX: number;\n\trotateY: number;\n\trotateZ: number;\n\t/** COM-calibrated `perspective-origin` (% of the element's box); only used on the explicit-override/no-homography fallback path. */\n\tperspectiveOriginXPct?: number;\n\tperspectiveOriginYPct?: number;\n}\n\n/**\n * Reference perspective distance (px, at `visual-3d-camera-fov`'s `REFERENCE_SIZE_PX`) used for\n * an explicit rotation with no camera preset at all. Matches the pre-existing\n * flat `800px` fallback.\n */\nexport const DEFAULT_CUSTOM_REF_PX = 800;\n\nexport const CAMERA_PRESET_MAP: Record<string, CameraPresetConfig> = {\n\torthographicFront: { rotateX: 0, rotateY: 0, rotateZ: 0 },\n\tperspectiveFront: { perspectiveRefPx: 1000, rotateX: 0, rotateY: 0, rotateZ: 0 },\n\tperspectiveAbove: { perspectiveRefPx: 1000, rotateX: 20, rotateY: 0, rotateZ: 0 },\n\tperspectiveBelow: { perspectiveRefPx: 1000, rotateX: -20, rotateY: 0, rotateZ: 0 },\n\tperspectiveLeft: { perspectiveRefPx: 1000, rotateX: 0, rotateY: -20, rotateZ: 0 },\n\tperspectiveRight: { perspectiveRefPx: 1000, rotateX: 0, rotateY: 20, rotateZ: 0 },\n\tperspectiveAboveLeftFacing: { perspectiveRefPx: 1000, rotateX: 20, rotateY: -25, rotateZ: 0 },\n\tperspectiveAboveRightFacing: { perspectiveRefPx: 1000, rotateX: 20, rotateY: 25, rotateZ: 0 },\n\tperspectiveContrastingLeftFacing: {\n\t\tperspectiveRefPx: 800,\n\t\trotateX: 15,\n\t\trotateY: -30,\n\t\trotateZ: 0,\n\t\tperspectiveOriginXPct: 93,\n\t\tperspectiveOriginYPct: 0,\n\t},\n\tperspectiveContrastingRightFacing: {\n\t\tperspectiveRefPx: 800,\n\t\trotateX: 15,\n\t\trotateY: 30,\n\t\trotateZ: 0,\n\t\tperspectiveOriginXPct: 7,\n\t\tperspectiveOriginYPct: 0,\n\t},\n\tperspectiveHeroicLeftFacing: { perspectiveRefPx: 600, rotateX: 10, rotateY: -35, rotateZ: 0 },\n\tperspectiveHeroicRightFacing: { perspectiveRefPx: 600, rotateX: 10, rotateY: 35, rotateZ: 0 },\n\tperspectiveHeroicExtremeLeftFacing: {\n\t\tperspectiveRefPx: 500,\n\t\trotateX: 8,\n\t\trotateY: -45,\n\t\trotateZ: 0,\n\t\tperspectiveOriginXPct: 32,\n\t\tperspectiveOriginYPct: 42,\n\t},\n\tperspectiveHeroicExtremeRightFacing: {\n\t\tperspectiveRefPx: 500,\n\t\trotateX: 8,\n\t\trotateY: 45,\n\t\trotateZ: 0,\n\t\tperspectiveOriginXPct: 68,\n\t\tperspectiveOriginYPct: 42,\n\t},\n\tperspectiveRelaxed: { perspectiveRefPx: 1200, rotateX: 10, rotateY: 0, rotateZ: 0 },\n\tperspectiveRelaxedModerately: { perspectiveRefPx: 1400, rotateX: 5, rotateY: 0, rotateZ: 0 },\n\t// No `perspectiveRefPx` on any isometric* preset: COM-measured real\n\t// PowerPoint output shows a true parallelogram (parallel projection, not\n\t// perspective) for these, see `visual-3d-camera`'s module doc comment.\n\tisometricLeftDown: { rotateX: -35, rotateY: 45, rotateZ: 0 },\n\tisometricRightUp: { rotateX: -35, rotateY: -45, rotateZ: 0 },\n\tisometricLeftUp: { rotateX: 35, rotateY: 45, rotateZ: 0 },\n\tisometricRightDown: { rotateX: 35, rotateY: -45, rotateZ: 0 },\n\tisometricTopUp: { rotateX: -55, rotateY: 0, rotateZ: 45 },\n\tisometricTopDown: { rotateX: -55, rotateY: 0, rotateZ: -45 },\n\tisometricBottomUp: { rotateX: 55, rotateY: 0, rotateZ: 45 },\n\tisometricBottomDown: { rotateX: 55, rotateY: 0, rotateZ: -45 },\n\tisometricOffAxis1Left: { rotateX: -30, rotateY: 30, rotateZ: 0 },\n\tisometricOffAxis1Right: { rotateX: -30, rotateY: -30, rotateZ: 0 },\n\tisometricOffAxis1Top: { rotateX: -45, rotateY: 0, rotateZ: 30 },\n\tisometricOffAxis2Left: { rotateX: -30, rotateY: 20, rotateZ: 0 },\n\tisometricOffAxis2Right: { rotateX: -30, rotateY: -20, rotateZ: 0 },\n\tisometricOffAxis2Top: { rotateX: -45, rotateY: 0, rotateZ: -30 },\n\tisometricOffAxis3Left: { rotateX: -25, rotateY: 35, rotateZ: 0 },\n\tisometricOffAxis3Right: { rotateX: -25, rotateY: -35, rotateZ: 0 },\n\tisometricOffAxis3Bottom: { rotateX: 45, rotateY: 0, rotateZ: 30 },\n\tisometricOffAxis4Left: { rotateX: -25, rotateY: 25, rotateZ: 0 },\n\tisometricOffAxis4Right: { rotateX: -25, rotateY: -25, rotateZ: 0 },\n\tisometricOffAxis4Bottom: { rotateX: 45, rotateY: 0, rotateZ: -30 },\n\tobliqueTopLeft: { perspectiveRefPx: 900, rotateX: -20, rotateY: 20, rotateZ: 0 },\n\tobliqueTop: { perspectiveRefPx: 900, rotateX: -25, rotateY: 0, rotateZ: 0 },\n\tobliqueTopRight: { perspectiveRefPx: 900, rotateX: -20, rotateY: -20, rotateZ: 0 },\n\tobliqueLeft: { perspectiveRefPx: 900, rotateX: 0, rotateY: 25, rotateZ: 0 },\n\tobliqueRight: { perspectiveRefPx: 900, rotateX: 0, rotateY: -25, rotateZ: 0 },\n\tobliqueBottomLeft: { perspectiveRefPx: 900, rotateX: 20, rotateY: 20, rotateZ: 0 },\n\tobliqueBottom: { perspectiveRefPx: 900, rotateX: 25, rotateY: 0, rotateZ: 0 },\n\tobliqueBottomRight: { perspectiveRefPx: 900, rotateX: 20, rotateY: -20, rotateZ: 0 },\n\t// Pre-2007 (legacy) WordArt/AutoShape 3-D camera names. Schema-legal but not\n\t// exposed in the modern \"3-D Rotation\" gallery; they only surface via files\n\t// round-tripped from legacy Office or hand-authored XML.\n\tlegacyObliqueTopLeft: { perspectiveRefPx: 900, rotateX: -20, rotateY: 20, rotateZ: 0 },\n\tlegacyObliqueTop: { perspectiveRefPx: 900, rotateX: -25, rotateY: 0, rotateZ: 0 },\n\tlegacyObliqueTopRight: { perspectiveRefPx: 900, rotateX: -20, rotateY: -20, rotateZ: 0 },\n\tlegacyObliqueLeft: { perspectiveRefPx: 900, rotateX: 0, rotateY: 25, rotateZ: 0 },\n\tlegacyObliqueFront: { perspectiveRefPx: 900, rotateX: 0, rotateY: 0, rotateZ: 0 },\n\tlegacyObliqueRight: { perspectiveRefPx: 900, rotateX: 0, rotateY: -25, rotateZ: 0 },\n\tlegacyObliqueBottomLeft: { perspectiveRefPx: 900, rotateX: 20, rotateY: 20, rotateZ: 0 },\n\tlegacyObliqueBottom: { perspectiveRefPx: 900, rotateX: 25, rotateY: 0, rotateZ: 0 },\n\tlegacyObliqueBottomRight: { perspectiveRefPx: 900, rotateX: 20, rotateY: -20, rotateZ: 0 },\n\tlegacyPerspectiveTopLeft: { perspectiveRefPx: 700, rotateX: -30, rotateY: 30, rotateZ: 0 },\n\tlegacyPerspectiveTop: { perspectiveRefPx: 700, rotateX: -35, rotateY: 0, rotateZ: 0 },\n\tlegacyPerspectiveTopRight: { perspectiveRefPx: 700, rotateX: -30, rotateY: -30, rotateZ: 0 },\n\tlegacyPerspectiveLeft: { perspectiveRefPx: 700, rotateX: 0, rotateY: 35, rotateZ: 0 },\n\tlegacyPerspectiveFront: { perspectiveRefPx: 700, rotateX: 0, rotateY: 0, rotateZ: 0 },\n\tlegacyPerspectiveRight: { perspectiveRefPx: 700, rotateX: 0, rotateY: -35, rotateZ: 0 },\n\tlegacyPerspectiveBottomLeft: { perspectiveRefPx: 700, rotateX: 30, rotateY: 30, rotateZ: 0 },\n\tlegacyPerspectiveBottom: { perspectiveRefPx: 700, rotateX: 35, rotateY: 0, rotateZ: 0 },\n\tlegacyPerspectiveBottomRight: { perspectiveRefPx: 700, rotateX: 30, rotateY: -30, rotateZ: 0 },\n};\n","/**\n * Whole-diagram camera for the SmartArt scene quick styles\n * (framework-agnostic, pure).\n *\n * Rotation convention (degrees): a diagram point `P` is turned by\n * `R = Rz(rev) . Rx(lat) . Ry(-lon)` about the diagram centre, then projected\n * along -z. Its orthographic front-face projection is exactly the\n * COM-validated `a:camera/a:rot` model in `visual-3d-camera-parametric.ts`\n * (`x = X cos lon`, `y = Y cos lat - X sin lat sin lon`, then a `rev` roll),\n * so an explicit `a:rot` is used as authored.\n *\n * Presets without `a:rot` take their pose from {@link SCENE_CAMERA_PRESETS}:\n * the COM-measured unit-square homographies of `visual-3d-camera-homography`\n * fitted to this pinhole model (rotation + camera distance, in multiples of\n * the measured 2in square's side). The distance is absolute: the SmartArt\n * scene-style exports show a whole diagram under `perspectiveLeft` with far\n * stronger foreshortening than a 2in shape, so it is converted to layout px\n * ({@link MEASURED_SQUARE_PX}) rather than scaled to the diagram. A preset\n * missing from the table falls back to the legacy `CAMERA_PRESET_MAP` angles.\n * `@fov` is not modelled.\n *\n * @module render/smartart-3d-scene-camera\n */\nimport type { Pptx3DScene } from 'pptx-viewer-core';\n\nimport type { SmartArt3DCamera } from './smartart-3d-solid-types';\nimport type { Vec3 } from './smartart-3d-types';\nimport { CAMERA_PRESET_MAP } from './visual-3d-camera-presets';\n\n/** A fitted preset pose; `distance` absent means a parallel projection. */\ninterface ScenePresetPose {\n\tlat: number;\n\tlon: number;\n\trev: number;\n\tdistance?: number;\n}\n\n/** Camera distance used for a perspective preset with no fitted pose. */\nconst DEFAULT_PERSPECTIVE_DISTANCE = 6;\n\n/** Side of the COM measurement square the preset distances are in: 2in at 96 px/in. */\nexport const MEASURED_SQUARE_PX = 192;\n\n/**\n * Presets the SmartArt scene quick styles use (plus their mirror images),\n * fitted from `CAMERA_HOMOGRAPHY_MAP`.\n */\nexport const SCENE_CAMERA_PRESETS: Record<string, ScenePresetPose> = {\n\torthographicFront: { lat: 0, lon: 0, rev: 0 },\n\tperspectiveFront: { lat: 0, lon: 0, rev: 0, distance: 160 },\n\tperspectiveLeft: { lat: 0, lon: 20.4, rev: 0, distance: 8.3 },\n\tperspectiveRight: { lat: 0, lon: -20.4, rev: 0, distance: 8.3 },\n\tperspectiveRelaxed: { lat: -50.8, lon: 0.3, rev: -0.2, distance: 7.8 },\n\tperspectiveRelaxedModerately: { lat: -35.1, lon: 0, rev: 0, distance: 7.9 },\n\tperspectiveHeroicExtremeRightFacing: { lat: 8, lon: -36.1, rev: 2.1, distance: 4.2 },\n\tperspectiveHeroicExtremeLeftFacing: { lat: 8, lon: 36.1, rev: -2.1, distance: 4.2 },\n\tisometricOffAxis2Left: { lat: 18, lon: 26, rev: 0 },\n\tisometricOffAxis2Right: { lat: 18, lon: -26, rev: 0 },\n};\n\nconst DEG_PER_UNIT = 60000;\n\nfunction toDeg(value: number | undefined): number {\n\treturn value ? value / DEG_PER_UNIT : 0;\n}\n\n/**\n * `a:camera/@zoom` as a fraction. Core passes the raw ST_PositivePercentage\n * (`95000` = 95%); a value already in fraction form is kept.\n */\nfunction normalizeZoom(value: number | undefined): number {\n\tif (!value || value <= 0) {\n\t\treturn 1;\n\t}\n\treturn value > 10 ? value / 100000 : value;\n}\n\nfunction presetPose(preset: string): ScenePresetPose {\n\tconst fitted = SCENE_CAMERA_PRESETS[preset];\n\tif (fitted) {\n\t\treturn fitted;\n\t}\n\tconst legacy = CAMERA_PRESET_MAP[preset];\n\tconst perspective = preset.startsWith('perspective');\n\treturn {\n\t\tlat: legacy?.rotateX ?? 0,\n\t\tlon: legacy?.rotateY ?? 0,\n\t\trev: legacy?.rotateZ ?? 0,\n\t\t...(perspective ? { distance: DEFAULT_PERSPECTIVE_DISTANCE } : {}),\n\t};\n}\n\n/**\n * The diagram camera for a quick style's `dgm:scene3d`, or `undefined` when\n * it leaves the diagram face-on (no scene, or an `orthographicFront` camera\n * with no rotation), where the flat framing already matches PowerPoint.\n */\nexport function resolveSmartArt3DCamera(\n\tscene: Pptx3DScene | undefined,\n): SmartArt3DCamera | undefined {\n\tif (!scene) {\n\t\treturn undefined;\n\t}\n\tconst preset = scene.cameraPreset ?? 'orthographicFront';\n\tconst pose = presetPose(preset);\n\tconst hasRot =\n\t\tscene.cameraRotX !== undefined ||\n\t\tscene.cameraRotY !== undefined ||\n\t\tscene.cameraRotZ !== undefined;\n\tconst latDeg = hasRot ? toDeg(scene.cameraRotX) : pose.lat;\n\tconst lonDeg = hasRot ? toDeg(scene.cameraRotY) : pose.lon;\n\tconst revDeg = hasRot ? toDeg(scene.cameraRotZ) : pose.rev;\n\tconst distance = pose.distance === undefined ? undefined : pose.distance * MEASURED_SQUARE_PX;\n\tconst zoom = normalizeZoom(scene.cameraZoom);\n\tif (latDeg === 0 && lonDeg === 0 && revDeg === 0 && distance === undefined && zoom === 1) {\n\t\treturn undefined;\n\t}\n\treturn {\n\t\tprojection: distance === undefined ? 'orthographic' : 'perspective',\n\t\tlatDeg,\n\t\tlonDeg,\n\t\trevDeg,\n\t\tdistance: distance ?? 0,\n\t\tzoom,\n\t};\n}\n\n/**\n * The camera's rotation as a row-major 3x3 matrix (`R = Rz(rev) . Rx(lat) .\n * Ry(-lon)`).\n */\nexport function smartArt3DCameraMatrix(camera: SmartArt3DCamera): number[] {\n\tconst rad = Math.PI / 180;\n\tconst cl = Math.cos(camera.latDeg * rad);\n\tconst sl = Math.sin(camera.latDeg * rad);\n\tconst co = Math.cos(-camera.lonDeg * rad);\n\tconst so = Math.sin(-camera.lonDeg * rad);\n\tconst cr = Math.cos(camera.revDeg * rad);\n\tconst sr = Math.sin(camera.revDeg * rad);\n\t// Rx(lat) . Ry(-lon)\n\tconst m = [co, 0, so, sl * so, cl, -sl * co, -cl * so, sl, cl * co];\n\t// Rz(rev) . m\n\treturn [\n\t\tcr * m[0] - sr * m[3],\n\t\tcr * m[1] - sr * m[4],\n\t\tcr * m[2] - sr * m[5],\n\t\tsr * m[0] + cr * m[3],\n\t\tsr * m[1] + cr * m[4],\n\t\tsr * m[2] + cr * m[5],\n\t\tm[6],\n\t\tm[7],\n\t\tm[8],\n\t];\n}\n\n/**\n * The camera position in diagram space (before the rotation), for per-point\n * view directions: `R^T . (0, 0, distance)`. `undefined` for a parallel\n * projection.\n */\nexport function smartArt3DEyeInDiagram(camera: SmartArt3DCamera): Vec3 | undefined {\n\tif (camera.projection !== 'perspective') {\n\t\treturn undefined;\n\t}\n\tconst m = smartArt3DCameraMatrix(camera);\n\t// Third row of R, i.e. the third column of R^T, times the distance.\n\treturn { x: m[6] * camera.distance, y: m[7] * camera.distance, z: m[8] * camera.distance };\n}\n","/**\n * Which 3D pipeline a SmartArt quick style needs, decided from the cached\n * drawing alone (framework-agnostic, pure).\n *\n * PowerPoint caches three shapes of quick style in `ppt/diagrams/drawing*.xml`:\n *\n * - **flat** (Simple Fill .. Intense Effect): no `a:sp3d` on any shape.\n * - **bevel** (Polished, Inset, Cartoon, Powder): every shape carries its own\n * `a:scene3d` (always `orthographicFront`) plus an `a:sp3d` bevel, so the\n * 2D layout stays undistorted and only the edges are lit.\n * - **scene** (Brick, Flat, Metallic, Sunset, Bird's Eye Scene): shapes carry\n * only `a:sp3d`; the one camera for the whole diagram lives in the quick\n * style part (`dgm:styleDef/dgm:scene3d`).\n *\n * Working rule: any shape with `scene3d` -> bevel; else any shape with a\n * non-empty `shape3d` -> scene; else flat.\n *\n * @module render/smartart-3d-style-path\n */\nimport type { Pptx3DShape, PptxSmartArtDrawingShape } from 'pptx-viewer-core';\n\nimport type { SmartArt3DStyleCategory } from './smartart-3d-types';\n\n/** Whether an `a:sp3d` carries anything that changes the rendered solid. */\nexport function hasSmartArtShape3D(shape3d: Pptx3DShape | undefined): boolean {\n\tif (!shape3d) {\n\t\treturn false;\n\t}\n\treturn (\n\t\t(shape3d.extrusionHeight ?? 0) > 0 ||\n\t\t(shape3d.contourWidth ?? 0) > 0 ||\n\t\t(shape3d.bevelTopWidth ?? 0) > 0 ||\n\t\t(shape3d.bevelTopHeight ?? 0) > 0 ||\n\t\tshape3d.bevelTopType !== undefined ||\n\t\t(shape3d.bevelBottomWidth ?? 0) > 0 ||\n\t\tshape3d.bevelBottomType !== undefined\n\t);\n}\n\n/** Decide the 3D pipeline for a SmartArt's cached drawing shapes. */\nexport function resolveSmartArt3DStylePath(\n\tshapes: readonly Pick<PptxSmartArtDrawingShape, 'scene3d' | 'shape3d'>[],\n): SmartArt3DStyleCategory {\n\tif (shapes.some((shape) => shape.scene3d !== undefined)) {\n\t\treturn 'bevel';\n\t}\n\tif (shapes.some((shape) => hasSmartArtShape3D(shape.shape3d))) {\n\t\treturn 'scene';\n\t}\n\treturn 'flat';\n}\n","/**\n * Resolve a SmartArt cached shape's `a:sp3d` into the pixel-space\n * {@link SmartArt3DSolid} the lit 3D scene builds (framework-agnostic, pure).\n *\n * @module render/smartart-3d-solid\n */\nimport type { Pptx3DShape } from 'pptx-viewer-core';\n\nimport type { SmartArt3DBevel, SmartArt3DSolid } from './smartart-3d-solid-types';\nimport { hasSmartArtShape3D } from './smartart-3d-style-path';\nimport { EMU_PER_PX } from './visual-3d-constants';\n\n/** ECMA-376 default `a:bevelT`/`a:bevelB` width and height: 76200 EMU (6pt). */\nconst DEFAULT_BEVEL_EMU = 76200;\n\n/**\n * Largest fraction of a shape's half-extent a bevel may eat into. PowerPoint\n * shrinks an over-wide bevel so the two opposite bands never cross.\n */\nconst MAX_BEVEL_FRACTION = 0.9;\n\nfunction resolveBevel(\n\ttype: string | undefined,\n\twidthEmu: number | undefined,\n\theightEmu: number | undefined,\n\tmaxWidth: number,\n): SmartArt3DBevel | undefined {\n\tif (type === undefined && widthEmu === undefined && heightEmu === undefined) {\n\t\treturn undefined;\n\t}\n\tif (type === 'none') {\n\t\treturn undefined;\n\t}\n\tconst width = Math.min((widthEmu ?? DEFAULT_BEVEL_EMU) / EMU_PER_PX, maxWidth);\n\tconst height = (heightEmu ?? DEFAULT_BEVEL_EMU) / EMU_PER_PX;\n\tif (width <= 0 || height <= 0) {\n\t\treturn undefined;\n\t}\n\treturn { width, height, profile: type ?? 'circle' };\n}\n\n/**\n * The lit solid for one shape, or `undefined` when its `a:sp3d` changes\n * nothing (the shape then renders as a flat face).\n *\n * @param halfExtent - half of the shape's smaller side, in layout px (bounds\n * the bevel width).\n */\nexport function resolveSmartArt3DSolid(\n\tshape3d: Pptx3DShape | undefined,\n\thalfExtent: number,\n): SmartArt3DSolid | undefined {\n\tif (!shape3d || !hasSmartArtShape3D(shape3d)) {\n\t\treturn undefined;\n\t}\n\tconst maxWidth = Math.max(0, halfExtent * MAX_BEVEL_FRACTION);\n\tconst bevelTop = resolveBevel(\n\t\tshape3d.bevelTopType,\n\t\tshape3d.bevelTopWidth,\n\t\tshape3d.bevelTopHeight,\n\t\tmaxWidth,\n\t);\n\tconst bevelBottom = resolveBevel(\n\t\tshape3d.bevelBottomType,\n\t\tshape3d.bevelBottomWidth,\n\t\tshape3d.bevelBottomHeight,\n\t\tmaxWidth,\n\t);\n\treturn {\n\t\t...(bevelTop ? { bevelTop } : {}),\n\t\t...(bevelBottom ? { bevelBottom } : {}),\n\t\textrusion: Math.max(0, (shape3d.extrusionHeight ?? 0) / EMU_PER_PX),\n\t\t...(shape3d.extrusionColor ? { extrusionColor: shape3d.extrusionColor } : {}),\n\t\tcontourWidth: Math.max(0, (shape3d.contourWidth ?? 0) / EMU_PER_PX),\n\t\t...(shape3d.contourColor ? { contourColor: shape3d.contourColor } : {}),\n\t\tmaterial: shape3d.presetMaterial ?? 'warmMatte',\n\t};\n}\n","/**\n * The specular lights of a SmartArt 3D light rig (framework-agnostic, pure).\n *\n * PowerPoint's `a:lightRig` presets are several directional lights, not one.\n * The single-light tables in `visual-3d-bevel-lighting-tables.ts` capture\n * what a rig does to a BEVEL (the key light's elevation and which edge it\n * lights); they say nothing about the other lights, which only show where a\n * specular material meets a changing view direction. A perspective scene\n * camera is exactly that case: every point of a flat face is seen from a\n * slightly different angle, so a metal face picks up the broad sweep of a\n * light the bevel campaign never saw (Metallic Scene: `threePt` + `metal`\n * under `perspectiveLeft`, bright at the diagram's top-left and fading to the\n * plain fill at its bottom-right).\n *\n * Under a perspective scene camera, each rig listed here replaces the default\n * highlight (one light above the key light's azimuth) with its own lights. A\n * parallel view keeps the default: the bevel constants in\n * `smartart-3d-lighting.ts` were fitted against the bevel quick styles with\n * that highlight, and the `threePt` light below over-brightens Inset's bevel\n * bands (every layout's Inset export regressed with it). Azimuths are relative to the key\n * light's (the snapped `a:lightRig/@dir` turned by the rig's `rev`),\n * counter-clockwise in diagram space; `intensity` scales the material's own\n * specular constant and `sharpness` its exponent.\n *\n * `threePt`'s highlight light was fitted to the Metallic Scene export\n * (`e2e/fixtures/three-d-parity/gt/sa-012.webp`): 838 face samples mapped\n * back onto the diagram plane through the fitted scene camera, Blinn lobe,\n * mean absolute error 2.3 (0-255) against a fill + white highlight. Adding\n * the default highlight to the fit gave it a zero weight, so the default is\n * replaced rather than kept.\n *\n * @module render/smartart-3d-light-rig\n */\n\n/** One specular light of a rig. */\nexport interface SmartArt3DRigLight {\n\t/** Azimuth relative to the key light, degrees, counter-clockwise. */\n\tazimuthDeg: number;\n\t/** Elevation above the diagram plane, degrees. */\n\televationDeg: number;\n\t/** Multiplier on the material's specular constant. */\n\tintensity: number;\n\t/** Multiplier on the material's specular exponent. */\n\tsharpness: number;\n}\n\n/** Elevation of the default highlight light, degrees. */\nconst DEFAULT_HIGHLIGHT_ELEVATION_DEG = 60;\n\nconst DEFAULT_HIGHLIGHT: readonly SmartArt3DRigLight[] = [\n\t{ azimuthDeg: 0, elevationDeg: DEFAULT_HIGHLIGHT_ELEVATION_DEG, intensity: 1, sharpness: 1 },\n];\n\n/** Rigs whose specular lights are known (see the module doc). */\nexport const SMARTART_RIG_SPECULAR_LIGHTS: Record<string, readonly SmartArt3DRigLight[]> = {\n\tthreePt: [{ azimuthDeg: 64, elevationDeg: 44, intensity: 4.6, sharpness: 3 }],\n};\n\n/**\n * The specular lights of a rig: its own under a perspective scene camera,\n * otherwise (or for a rig not listed) the default single highlight.\n */\nexport function smartArt3DRigSpecularLights(\n\trig: string | undefined,\n\tperspective: boolean,\n): readonly SmartArt3DRigLight[] {\n\tconst own = perspective && rig ? SMARTART_RIG_SPECULAR_LIGHTS[rig] : undefined;\n\treturn own ?? DEFAULT_HIGHLIGHT;\n}\n\n/** The key (diffuse) light of a rig, relative to the snapped `a:lightRig/@dir`. */\nexport interface SmartArt3DRigKeyLight {\n\t/** Azimuth relative to the key light's direction, degrees, counter-clockwise. */\n\tazimuthDeg: number;\n\t/** Elevation above the diagram plane, degrees. */\n\televationDeg: number;\n}\n\n/**\n * Key-light elevations under a scene camera, fitted per rig against the scene\n * quick styles' exports (whole-slide MAE over all eight layouts of each\n * style in `e2e/fixtures/three-d-parity/gt/`, sweeping the elevation):\n * `flat` (Brick Scene, isometric) 4.18 -> 3.94 at 40, `threePt` (Metallic\n * Scene) 3.89 -> 3.60 at 90, `morning` (Sunset Scene) 3.63 -> 3.53 at 60,\n * `soft` (Bird's Eye Scene) 3.69 -> 3.12 at 80. Under a parallel view the\n * grazing default stays: raising it made Polished (`flat`) and Cartoon\n * (`contrasting`) worse, because the bevel constants were fitted with it.\n */\nexport const SMARTART_RIG_SCENE_KEY_LIGHTS: Record<string, SmartArt3DRigKeyLight> = {\n\tflat: { azimuthDeg: 0, elevationDeg: 40 },\n\tthreePt: { azimuthDeg: 0, elevationDeg: 90 },\n\tmorning: { azimuthDeg: 0, elevationDeg: 60 },\n\tsoft: { azimuthDeg: 0, elevationDeg: 80 },\n};\n\n/**\n * A rig's own key light under a scene camera, or `undefined` for the default\n * (a grazing light from `@dir`, fitted against the bevel quick styles).\n */\nexport function smartArt3DRigKeyLight(\n\trig: string | undefined,\n\tsceneCamera: boolean,\n): SmartArt3DRigKeyLight | undefined {\n\treturn sceneCamera && rig ? SMARTART_RIG_SCENE_KEY_LIGHTS[rig] : undefined;\n}\n","/**\n * Per-vertex shading for the lit SmartArt 3D solids (framework-agnostic,\n * pure).\n *\n * The three.js layer paints every lit surface unlit (`MeshBasicMaterial`)\n * and applies `colour * mul + add` from here, per vertex, in display (sRGB)\n * space. Normalising the diffuse term by the value of a surface facing the\n * viewer keeps a front face at exactly its authored fill (PowerPoint's own\n * exports show a flat face unchanged by every rig and material, see\n * `visual-3d-bevel-lighting.ts`), so only tilted surfaces (bevel bands,\n * extrusion walls, a whole diagram turned by a scene camera) change colour.\n *\n * Reuses the shared bevel tables: the key light's azimuth comes from\n * `getBevelHighlightDirection` (the COM-measured cardinal snap of\n * `a:lightRig/@dir`) and the material response from `getMaterialLighting`.\n * The elevation and ambient share were fitted against the SmartArt bevel\n * quick-style exports in `e2e/fixtures/three-d-parity/gt`.\n *\n * @module render/smartart-3d-lighting\n */\nimport { smartArt3DRigKeyLight, smartArt3DRigSpecularLights } from './smartart-3d-light-rig';\nimport type { SmartArt3DLighting } from './smartart-3d-solid-types';\nimport type { Vec3 } from './smartart-3d-types';\nimport { getBevelHighlightDirection } from './visual-3d-bevel-light';\nimport { getMaterialLighting } from './visual-3d-bevel-lighting-tables';\n\n/** The resolved light for one solid: a key light plus a material response. */\nexport interface SmartArt3DLightModel {\n\t/** Unit vector toward the key (diffuse) light (diagram space: y-up, +z toward the viewer). */\n\tlight: Vec3;\n\t/** The rig's specular lights (see `smartart-3d-light-rig.ts`). */\n\thighlights: SmartArt3DHighlight[];\n\t/** Share of the diffuse response that does not depend on the normal. */\n\tambient: number;\n\tdiffuse: number;\n\t/**\n\t * Linear per-channel factor the rig applies to every surface, including a\n\t * face-on one (see {@link RIG_FACE_READING}).\n\t */\n\ttint: [number, number, number];\n}\n\n/** One specular light, resolved to diagram space. */\nexport interface SmartArt3DHighlight {\n\t/** Unit vector toward the light. */\n\tdirection: Vec3;\n\t/** Specular weight (material constant times the rig light's intensity). */\n\tweight: number;\n\t/** Specular exponent (material exponent times the rig light's sharpness). */\n\texponent: number;\n}\n\n/** A vertex's shading: display colour = `fill * mul + add` (per channel, 0..1). */\nexport interface SmartArt3DShade {\n\tmul: number;\n\tadd: number;\n}\n\n/**\n * Key light elevation above the diagram plane, degrees. Low: the bevel\n * exports keep a surface facing away from the light close to the face colour\n * (Polished's bottom band) while a band tilted toward it doubles in\n * brightness (Polished's top band), which only a grazing key light gives.\n */\nconst KEY_ELEVATION_DEG = 5;\n/** Ambient share of the diffuse response. */\nconst AMBIENT = 0.5;\n/** Scales the material table's specular constant to this shading model. */\nconst SPECULAR_GAIN = 0.6;\n\nconst VIEW: Vec3 = { x: 0, y: 0, z: 1 };\n\n/** The mid-grey reading every rig is measured against. */\nconst RIG_REFERENCE_GREY = 127;\n\n/**\n * What a face-on `#7f7f7f` shape reads under a rig (sRGB 0..255). `morning`\n * is the COM measurement quoted in `visual-3d-bevel-lighting.ts`; `soft` is\n * read off the Bird's Eye Scene export (accent1 face, converted to the grey\n * equivalent in linear light, which also reproduces the `morning` export of\n * Sunset Scene). Rigs not listed leave a face-on surface at its fill, as\n * `flat` and `threePt` measure.\n */\nconst RIG_FACE_READING: Record<string, [number, number, number]> = {\n\tmorning: [112, 108, 98],\n\tsoft: [121, 121, 121],\n};\n\nfunction srgbChannelToLinear(c: number): number {\n\treturn c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;\n}\n\nfunction rigTint(rig: string | undefined): [number, number, number] {\n\tconst reading = rig ? RIG_FACE_READING[rig] : undefined;\n\tif (!reading) {\n\t\treturn [1, 1, 1];\n\t}\n\tconst reference = srgbChannelToLinear(RIG_REFERENCE_GREY / 255);\n\treturn reading.map((c) => srgbChannelToLinear(c / 255) / reference) as [number, number, number];\n}\n\nfunction dot(a: Vec3, b: Vec3): number {\n\treturn a.x * b.x + a.y * b.y + a.z * b.z;\n}\n\nfunction normalize(v: Vec3): Vec3 {\n\tconst len = Math.hypot(v.x, v.y, v.z) || 1;\n\treturn { x: v.x / len, y: v.y / len, z: v.z / len };\n}\n\n/**\n * Resolve the light model for a rig and an `a:sp3d/@prstMaterial`.\n *\n * @param perspective - the solid is seen through a perspective scene camera,\n * which switches on the rig's own specular lights (see\n * `smartart-3d-light-rig.ts`).\n * @param sceneCamera - the diagram is turned by a quick-style scene camera\n * (perspective or not), which switches on the rig's own key light.\n */\nexport function resolveSmartArt3DLightModel(\n\tlighting: SmartArt3DLighting | undefined,\n\tmaterial: string | undefined,\n\tperspective = false,\n\tsceneCamera = perspective,\n): SmartArt3DLightModel {\n\t// CSS space (y-down) -> view space (y-up), then the rig's own revolution.\n\tconst snap = getBevelHighlightDirection(lighting?.direction ?? 't');\n\tconst rev = ((lighting?.revDeg ?? 0) * Math.PI) / 180;\n\tconst ax = snap.dx;\n\tconst ay = -snap.dy;\n\tconst az = Math.hypot(ax, ay) || 1;\n\tconst azX = (ax * Math.cos(rev) - ay * Math.sin(rev)) / az;\n\tconst azY = (ax * Math.sin(rev) + ay * Math.cos(rev)) / az;\n\tconst toward = (elevationDeg: number, azimuthDeg = 0): Vec3 => {\n\t\tconst elevation = (elevationDeg * Math.PI) / 180;\n\t\tconst turn = (azimuthDeg * Math.PI) / 180;\n\t\tconst dx = azX * Math.cos(turn) - azY * Math.sin(turn);\n\t\tconst dy = azX * Math.sin(turn) + azY * Math.cos(turn);\n\t\treturn normalize({\n\t\t\tx: dx * Math.cos(elevation),\n\t\t\ty: dy * Math.cos(elevation),\n\t\t\tz: Math.sin(elevation),\n\t\t});\n\t};\n\tconst response = getMaterialLighting(material);\n\tconst specular = response.specularConstant * SPECULAR_GAIN;\n\tconst key = smartArt3DRigKeyLight(lighting?.rig, sceneCamera);\n\treturn {\n\t\tlight: key ? toward(key.elevationDeg, key.azimuthDeg) : toward(KEY_ELEVATION_DEG),\n\t\thighlights: smartArt3DRigSpecularLights(lighting?.rig, perspective).map((rigLight) => ({\n\t\t\tdirection: toward(rigLight.elevationDeg, rigLight.azimuthDeg),\n\t\t\tweight: specular * rigLight.intensity,\n\t\t\texponent: response.specularExponent * rigLight.sharpness,\n\t\t})),\n\t\tambient: AMBIENT,\n\t\tdiffuse: response.diffuseConstant,\n\t\ttint: rigTint(lighting?.rig),\n\t};\n}\n\n/**\n * Shade one unit normal (diagram space).\n *\n * @param eye - unit direction from the surface point toward the camera. When\n * omitted (a face-on, parallel view) the specular term is measured against a\n * face-on surface, so a normal facing the viewer returns exactly\n * `{ mul: 1, add: 0 }`. A perspective scene camera passes the real per-point\n * direction instead, and its faces pick up the moving highlight a metal\n * diagram shows in the Metallic Scene export.\n */\nexport function shadeSmartArt3DNormal(\n\tnormal: Vec3,\n\tmodel: SmartArt3DLightModel,\n\teye?: Vec3,\n): SmartArt3DShade {\n\tconst lambert = (n: Vec3): number =>\n\t\tmodel.ambient + model.diffuse * Math.max(0, dot(n, model.light));\n\tconst mul = lambert(normal) / lambert(VIEW);\n\tconst view = eye ?? VIEW;\n\tlet add = 0;\n\tfor (const highlight of model.highlights) {\n\t\tconst half = normalize({\n\t\t\tx: highlight.direction.x + view.x,\n\t\t\ty: highlight.direction.y + view.y,\n\t\t\tz: highlight.direction.z + view.z,\n\t\t});\n\t\tconst peak = (n: Vec3): number => Math.max(0, dot(n, half)) ** highlight.exponent;\n\t\tadd += highlight.weight * Math.max(0, peak(normal) - (eye ? 0 : peak(VIEW)));\n\t}\n\treturn { mul, add };\n}\n","/**\n * Per-vertex colour factors for a lit SmartArt 3D solid (framework-agnostic,\n * pure).\n *\n * The three.js layer paints a solid with `MeshBasicMaterial` (base colour or\n * gradient map) times a per-vertex colour. This module computes that vertex\n * colour so the displayed (sRGB) result is `base * mul + add` from\n * `shadeSmartArt3DNormal`, with the division done in linear space because\n * three multiplies linear values.\n *\n * @module render/smartart-3d-vertex-shading\n */\nimport type { SmartArt3DLightModel } from './smartart-3d-lighting';\nimport { shadeSmartArt3DNormal } from './smartart-3d-lighting';\nimport type { Point2, Vec3 } from './smartart-3d-types';\n\n/** An sRGB colour, channels 0..1. */\nexport type Rgb = [number, number, number];\n\n/** sRGB channel (0..1) -> linear. */\nexport function srgbToLinear(c: number): number {\n\treturn c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;\n}\n\n/** `#rrggbb` -> sRGB channels 0..1 (black when unparsable). */\nexport function hexToRgb(hex: string): Rgb {\n\tconst match = /^#?([0-9a-f]{6})$/iu.exec(hex.trim());\n\tif (!match) {\n\t\treturn [0, 0, 0];\n\t}\n\tconst n = Number.parseInt(match[1], 16);\n\treturn [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255];\n}\n\nfunction normalizeVec(v: Vec3): Vec3 {\n\tconst len = Math.hypot(v.x, v.y, v.z) || 1;\n\treturn { x: v.x / len, y: v.y / len, z: v.z / len };\n}\n\n/** Floor for a base channel, so the linear ratio stays finite on black. */\nconst MIN_LINEAR = 1e-4;\n\n/**\n * Vertex colours (3 floats per vertex, linear factors) for a triangle list.\n *\n * @param positions - mesh-local xyz per vertex.\n * @param normals - mesh-local unit normals per vertex.\n * @param baseAt - the sRGB base colour painted at a mesh-local point.\n * @param eye - camera position in mesh-local space, for a perspective scene\n * camera; omitted for a parallel view.\n *\n * The light is fixed to the diagram, not the camera: a scene camera turning\n * the diagram does not relight its faces (the scene-style exports keep every\n * face at the same colour however far it is turned).\n */\nexport function shadeSmartArt3DVertices(\n\tpositions: readonly number[],\n\tnormals: readonly number[],\n\tbaseAt: (p: Point2) => Rgb,\n\tmodel: SmartArt3DLightModel,\n\teye?: Vec3,\n): Float32Array {\n\tconst out = new Float32Array(positions.length);\n\tfor (let i = 0; i < positions.length; i += 3) {\n\t\tconst normal = { x: normals[i], y: normals[i + 1], z: normals[i + 2] };\n\t\tconst toEye = eye\n\t\t\t? normalizeVec({\n\t\t\t\t\tx: eye.x - positions[i],\n\t\t\t\t\ty: eye.y - positions[i + 1],\n\t\t\t\t\tz: eye.z - positions[i + 2],\n\t\t\t\t})\n\t\t\t: undefined;\n\t\tconst { mul, add } = shadeSmartArt3DNormal(normal, model, toEye);\n\t\tconst base = baseAt({ x: positions[i], y: positions[i + 1] });\n\t\tfor (let c = 0; c < 3; c++) {\n\t\t\tconst target = Math.min(1, Math.max(0, base[c] * mul + add));\n\t\t\tconst linBase = Math.max(MIN_LINEAR, srgbToLinear(base[c]));\n\t\t\tout[i + c] = (srgbToLinear(target) / linBase) * model.tint[c];\n\t\t}\n\t}\n\treturn out;\n}\n","/**\n * The lit (bevel / scene quick style) half of the cached-drawing SmartArt 3D\n * model: per-shape solids and gradients, plus the diagram's light rig and\n * camera (framework-agnostic, pure).\n *\n * `smartart-3d-drawing-model.ts` builds the flat meshes; this module decorates\n * them when {@link resolveSmartArt3DStylePath} picks `'bevel'` or `'scene'`.\n *\n * @module render/smartart-3d-drawing-solid\n */\nimport type { PptxSmartArtData, PptxSmartArtDrawingShape } from 'pptx-viewer-core';\n\nimport { resolveSmartArt3DCamera } from './smartart-3d-scene-camera';\nimport { resolveSmartArt3DSolid } from './smartart-3d-solid';\nimport type {\n\tSmartArt3DCamera,\n\tSmartArt3DGradient,\n\tSmartArt3DLighting,\n} from './smartart-3d-solid-types';\nimport type { Point2, SmartArt3DMesh, SmartArt3DStyleCategory } from './smartart-3d-types';\nimport type { Rgb } from './smartart-3d-vertex-shading';\nimport { hexToRgb } from './smartart-3d-vertex-shading';\nimport type { RenderedShape } from './smartart-drawing';\nimport { EMU_PER_PX } from './visual-3d-constants';\n\nconst DEG_PER_UNIT = 60000;\n\nfunction percent(value: string | undefined, fallback: number): number {\n\tconst parsed = value === undefined ? Number.NaN : Number.parseFloat(value);\n\treturn Number.isFinite(parsed) ? parsed / 100 : fallback;\n}\n\n/**\n * The shape's gradient in mesh-local space, or `undefined` for a plain fill.\n *\n * @param toLocal - maps a viewBox point (y-down, before the shape's own\n * rotation / flip) to mesh-local space (y-up, rotation applied).\n */\nexport function buildSmartArt3DGradient(\n\trendered: RenderedShape,\n\ttoLocal: (p: Point2) => Point2,\n): SmartArt3DGradient | undefined {\n\tconst gradient = rendered.gradient;\n\tif (!gradient || gradient.stops.length === 0) {\n\t\treturn undefined;\n\t}\n\tconst at = (fx: number, fy: number): Point2 =>\n\t\ttoLocal({ x: rendered.x + fx * rendered.width, y: rendered.y + fy * rendered.height });\n\tconst stops = gradient.stops.map((stop) => ({\n\t\toffset: Math.max(0, Math.min(1, percent(stop.offset, 0))),\n\t\tcolor: stop.color,\n\t}));\n\tif (gradient.kind === 'radial') {\n\t\tconst cx = percent(gradient.cx, 0.5);\n\t\tconst cy = percent(gradient.cy, 0.5);\n\t\tconst r = percent(gradient.r, 0.5);\n\t\treturn { kind: 'radial', from: at(cx, cy), to: at(cx + r, cy), stops };\n\t}\n\treturn {\n\t\tkind: 'linear',\n\t\tfrom: at(percent(gradient.x1, 0), percent(gradient.y1, 0)),\n\t\tto: at(percent(gradient.x2, 1), percent(gradient.y2, 0)),\n\t\tstops,\n\t};\n}\n\n/** Where a mesh-local point falls along a gradient, 0..1. */\nexport function smartArt3DGradientCoordinate(p: Point2, gradient: SmartArt3DGradient): number {\n\tconst dx = gradient.to.x - gradient.from.x;\n\tconst dy = gradient.to.y - gradient.from.y;\n\tconst lengthSq = dx * dx + dy * dy;\n\tif (lengthSq <= 0) {\n\t\treturn 0;\n\t}\n\tconst u =\n\t\tgradient.kind === 'radial'\n\t\t\t? Math.hypot(p.x - gradient.from.x, p.y - gradient.from.y) / Math.sqrt(lengthSq)\n\t\t\t: ((p.x - gradient.from.x) * dx + (p.y - gradient.from.y) * dy) / lengthSq;\n\treturn Math.max(0, Math.min(1, u));\n}\n\n/** The sRGB colour a gradient paints at a mesh-local point (stops interpolated in sRGB, as SVG does). */\nexport function smartArt3DGradientColor(gradient: SmartArt3DGradient, p: Point2): Rgb {\n\tconst u = smartArt3DGradientCoordinate(p, gradient);\n\tconst stops = gradient.stops;\n\tif (u <= stops[0].offset) {\n\t\treturn hexToRgb(stops[0].color);\n\t}\n\tfor (let i = 1; i < stops.length; i++) {\n\t\tconst b = stops[i];\n\t\tif (u <= b.offset) {\n\t\t\tconst a = stops[i - 1];\n\t\t\tconst span = b.offset - a.offset;\n\t\t\tconst f = span > 0 ? (u - a.offset) / span : 1;\n\t\t\tconst ca = hexToRgb(a.color);\n\t\t\tconst cb = hexToRgb(b.color);\n\t\t\treturn [\n\t\t\t\tca[0] + (cb[0] - ca[0]) * f,\n\t\t\t\tca[1] + (cb[1] - ca[1]) * f,\n\t\t\t\tca[2] + (cb[2] - ca[2]) * f,\n\t\t\t];\n\t\t}\n\t}\n\treturn hexToRgb(stops[stops.length - 1].color);\n}\n\n/** Give a flat mesh its lit solid and gradient, from its cached shape. */\nexport function decorateSmartArt3DMesh(\n\tmesh: SmartArt3DMesh,\n\tshape: PptxSmartArtDrawingShape,\n\trendered: RenderedShape,\n\ttoLocal: (p: Point2) => Point2,\n): void {\n\tmesh.flat = false;\n\tconst solid = resolveSmartArt3DSolid(\n\t\tshape.shape3d,\n\t\tMath.min(rendered.width, rendered.height) / 2,\n\t);\n\tif (solid) {\n\t\tmesh.solid = solid;\n\t}\n\tconst textExtrusion = (shape.text3d?.extrusionHeight ?? 0) / EMU_PER_PX;\n\tif (mesh.textBlock && textExtrusion > 0) {\n\t\tmesh.textBlock.extrusion = textExtrusion;\n\t\tif (shape.text3d?.extrusionColor) {\n\t\t\tmesh.textBlock.extrusionColor = shape.text3d.extrusionColor;\n\t\t}\n\t}\n\tconst gradient = buildSmartArt3DGradient(rendered, toLocal);\n\tif (gradient) {\n\t\tmesh.gradient = gradient;\n\t}\n}\n\n/** The light rig and camera for a lit diagram. */\nexport function resolveSmartArt3DSceneSetup(\n\tdata: PptxSmartArtData,\n\tcategory: SmartArt3DStyleCategory,\n): { lighting?: SmartArt3DLighting; camera?: SmartArt3DCamera } {\n\tif (category === 'flat') {\n\t\treturn {};\n\t}\n\tconst diagramScene = data.quickStyle?.scene3d;\n\tconst rigScene =\n\t\tcategory === 'bevel'\n\t\t\t? (data.drawingShapes?.find((s) => s.scene3d?.lightRigType)?.scene3d ?? diagramScene)\n\t\t\t: diagramScene;\n\tconst lighting: SmartArt3DLighting = {\n\t\trig: rigScene?.lightRigType ?? 'threePt',\n\t\tdirection: rigScene?.lightRigDirection ?? 't',\n\t\trevDeg: (rigScene?.lightRigRotZ ?? 0) / DEG_PER_UNIT,\n\t};\n\tconst camera = category === 'scene' ? resolveSmartArt3DCamera(diagramScene) : undefined;\n\treturn { lighting, ...(camera ? { camera } : {}) };\n}\n","/**\n * One shared WebGL context for every `<pptx-three-view>` on the page.\n *\n * Browsers cap live WebGL contexts at roughly 16 per page and silently kill\n * the oldest when a new one is created. Before this host, every 3D chart and\n * SmartArt graphic (on the slide AND in each thumbnail) created its own\n * `WebGLRenderer`, so a deck with more than a handful of them rendered a\n * blank main slide: its context was the one the thumbnails had evicted.\n *\n * Here a single offscreen `WebGLRenderer` draws each dirty view into the top\n * left of its own drawing buffer, and the pixels are copied straight onto\n * the view's own 2D `<canvas>` in the same task (so no\n * `preserveDrawingBuffer` is needed). Views render on demand only: a scene\n * asks for a frame when something changed, and only scenes that report\n * `isAnimating()` keep getting frames. A 2D canvas is also something every\n * export path (html2canvas, `toDataURL`) can read, which a WebGL canvas\n * without `preserveDrawingBuffer` is not.\n *\n * @module three-view/renderer-host\n */\nimport type * as THREE from 'three';\n\nimport type { ThreeModule } from './types';\n\n/** Largest backing-store edge a single view is drawn at, in device pixels. */\nexport const MAX_VIEW_PIXELS = 4096;\n\n/** A view the host draws: its target canvas, its size, and how to draw it. */\nexport interface HostedView {\n\t/** The 2D canvas the view's pixels are copied onto. */\n\treadonly canvas: HTMLCanvasElement;\n\t/** Current backing size in device pixels. */\n\tpixelSize: () => { width: number; height: number };\n\t/** Whether the view is currently worth drawing (connected and on screen). */\n\tisVisible: () => boolean;\n\t/** Draw the scene; the host has already set viewport, scissor and cleared. */\n\tdraw: (renderer: THREE.WebGLRenderer) => void;\n\t/** `true` while the view wants continuous frames. */\n\tisAnimating: () => boolean;\n}\n\n/** The shared host's public surface. */\nexport interface ThreeRendererHost {\n\t/** `false` when WebGL could not be initialised at all (caller falls back to 2D). */\n\treadonly available: boolean;\n\tregister: (view: HostedView) => void;\n\tunregister: (view: HostedView) => void;\n\trequestRender: (view: HostedView) => void;\n\t/** Draw every pending view immediately (tests, export). */\n\tflushNow: () => void;\n\t/** Draw one registered view immediately, even when it is off screen (export snapshots). */\n\tdrawNow: (view: HostedView) => void;\n}\n\ninterface HostState {\n\tthree: ThreeModule;\n\trenderer: THREE.WebGLRenderer | null;\n\tviews: Set<HostedView>;\n\tdirty: Set<HostedView>;\n\tframe: number;\n\tlost: boolean;\n\tbufferWidth: number;\n\tbufferHeight: number;\n}\n\nfunction createRenderer(three: ThreeModule, state: HostState): THREE.WebGLRenderer | null {\n\ttry {\n\t\tconst renderer = new three.WebGLRenderer({\n\t\t\tantialias: true,\n\t\t\talpha: true,\n\t\t\t// An antialiased edge resolves to colour x coverage over the\n\t\t\t// transparent clear: premultiplied. Declaring the buffer straight\n\t\t\t// alpha made every edge composite too dark (a #D9D9D9 gridline\n\t\t\t// half-covering a pixel landed at #B6B6B6 on white).\n\t\t\tpremultipliedAlpha: true,\n\t\t\tpowerPreference: 'default',\n\t\t});\n\t\trenderer.setPixelRatio(1);\n\t\trenderer.outputColorSpace = three.SRGBColorSpace;\n\t\trenderer.autoClear = false;\n\t\tconst canvas = renderer.domElement;\n\t\tcanvas.addEventListener('webglcontextlost', (event) => {\n\t\t\tevent.preventDefault();\n\t\t\tstate.lost = true;\n\t\t});\n\t\tcanvas.addEventListener('webglcontextrestored', () => {\n\t\t\tstate.lost = false;\n\t\t\tfor (const view of state.views) {\n\t\t\t\tstate.dirty.add(view);\n\t\t\t}\n\t\t\tschedule(state);\n\t\t});\n\t\treturn renderer;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/** Grow (never shrink) the shared drawing buffer so it can hold a `width` x `height` view. */\nfunction ensureBuffer(state: HostState, width: number, height: number): void {\n\tconst renderer = state.renderer;\n\tif (!renderer || (width <= state.bufferWidth && height <= state.bufferHeight)) {\n\t\treturn;\n\t}\n\tstate.bufferWidth = Math.min(MAX_VIEW_PIXELS, Math.max(state.bufferWidth, width));\n\tstate.bufferHeight = Math.min(MAX_VIEW_PIXELS, Math.max(state.bufferHeight, height));\n\trenderer.setSize(state.bufferWidth, state.bufferHeight, false);\n}\n\nfunction drawView(state: HostState, view: HostedView): void {\n\tconst renderer = state.renderer;\n\tif (!renderer) {\n\t\treturn;\n\t}\n\tconst size = view.pixelSize();\n\tconst width = Math.max(1, Math.min(MAX_VIEW_PIXELS, Math.round(size.width)));\n\tconst height = Math.max(1, Math.min(MAX_VIEW_PIXELS, Math.round(size.height)));\n\tensureBuffer(state, width, height);\n\t// WebGL's viewport origin is bottom-left; anchoring the view at the TOP of\n\t// the buffer means the pixels land at source (0, 0) for drawImage below.\n\tconst y = state.bufferHeight - height;\n\trenderer.setViewport(0, y, width, height);\n\trenderer.setScissor(0, y, width, height);\n\trenderer.setScissorTest(true);\n\trenderer.setClearColor(0x000000, 0);\n\trenderer.clear(true, true, true);\n\tview.draw(renderer);\n\n\tconst target = view.canvas;\n\tif (target.width !== width || target.height !== height) {\n\t\ttarget.width = width;\n\t\ttarget.height = height;\n\t}\n\tconst ctx = target.getContext('2d');\n\tif (!ctx) {\n\t\treturn;\n\t}\n\tctx.clearRect(0, 0, width, height);\n\tctx.drawImage(renderer.domElement, 0, 0, width, height, 0, 0, width, height);\n}\n\nfunction flush(state: HostState): void {\n\tstate.frame = 0;\n\tif (state.lost || !state.renderer) {\n\t\treturn;\n\t}\n\tconst pending = [...state.dirty];\n\tstate.dirty.clear();\n\tfor (const view of pending) {\n\t\tif (!state.views.has(view)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (!view.isVisible()) {\n\t\t\t// Remember it: it draws as soon as it becomes visible again.\n\t\t\tstate.dirty.add(view);\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tdrawView(state, view);\n\t\t} catch (error) {\n\t\t\t// One broken scene must never stop every other view from drawing.\n\t\t\tconsole.error('[pptx-three-view] scene render failed', error);\n\t\t\tcontinue;\n\t\t}\n\t\tif (view.isAnimating()) {\n\t\t\tstate.dirty.add(view);\n\t\t}\n\t}\n\tconst anyVisibleDirty = [...state.dirty].some((v) => v.isVisible());\n\tif (anyVisibleDirty) {\n\t\tschedule(state);\n\t}\n}\n\nfunction schedule(state: HostState): void {\n\tif (state.frame !== 0 || typeof requestAnimationFrame === 'undefined') {\n\t\treturn;\n\t}\n\tstate.frame = requestAnimationFrame(() => flush(state));\n}\n\nlet sharedHost: ThreeRendererHost | null = null;\n\n/**\n * The page-wide renderer host, created on first use from the given `three`\n * module. Every later call returns the same host, whatever module it passes.\n */\nexport function getThreeRendererHost(three: ThreeModule): ThreeRendererHost {\n\tif (sharedHost) {\n\t\treturn sharedHost;\n\t}\n\tconst state: HostState = {\n\t\tthree,\n\t\trenderer: null,\n\t\tviews: new Set(),\n\t\tdirty: new Set(),\n\t\tframe: 0,\n\t\tlost: false,\n\t\tbufferWidth: 0,\n\t\tbufferHeight: 0,\n\t};\n\tstate.renderer = createRenderer(three, state);\n\tconst host: ThreeRendererHost = {\n\t\tavailable: state.renderer !== null,\n\t\tregister(view) {\n\t\t\tstate.views.add(view);\n\t\t\tstate.dirty.add(view);\n\t\t\tschedule(state);\n\t\t},\n\t\tunregister(view) {\n\t\t\tstate.views.delete(view);\n\t\t\tstate.dirty.delete(view);\n\t\t},\n\t\trequestRender(view) {\n\t\t\tif (!state.views.has(view)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tstate.dirty.add(view);\n\t\t\tschedule(state);\n\t\t},\n\t\tflushNow() {\n\t\t\tif (state.frame !== 0 && typeof cancelAnimationFrame !== 'undefined') {\n\t\t\t\tcancelAnimationFrame(state.frame);\n\t\t\t}\n\t\t\tflush(state);\n\t\t},\n\t\tdrawNow(view) {\n\t\t\tif (state.lost || !state.renderer || !state.views.has(view)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tstate.dirty.delete(view);\n\t\t\ttry {\n\t\t\t\tdrawView(state, view);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[pptx-three-view] scene render failed', error);\n\t\t\t}\n\t\t},\n\t};\n\tsharedHost = host;\n\treturn host;\n}\n\n/** Test hook: forget the shared host so the next call builds a fresh one. */\nexport function resetThreeRendererHostForTests(): void {\n\tsharedHost = null;\n}\n","/**\n * Drawing past the element box (framework-agnostic, pure).\n *\n * PowerPoint draws a scene-style SmartArt diagram through its camera without\n * clipping it to the graphic frame: a turned diagram can reach above the\n * frame (Brick Scene) or below it (Sunset, Bird's Eye). A scene reports how\n * far its drawing reaches past each edge as fractions of the element box\n * ({@link ThreeViewOverflow}); `<pptx-three-view>` then grows its canvas (CSS\n * box and drawing buffer) by that much on each side and the scene widens its\n * camera frustum by the same amount, so the part inside the element box is\n * drawn exactly where it was before.\n *\n * @module three-view/view-overflow\n */\nimport { MAX_VIEW_PIXELS } from './renderer-host';\nimport type { ThreeViewOverflow, ThreeViewSize } from './types';\n\n/** Largest overflow on any one side, as a fraction of the element box. */\nexport const MAX_THREE_VIEW_OVERFLOW = 0.5;\n\n/** Headroom added past the measured reach, so an antialiased edge is not cut. */\nconst OVERFLOW_MARGIN = 0.01;\n\n/** No overflow. */\nexport const NO_THREE_VIEW_OVERFLOW: ThreeViewOverflow = { top: 0, right: 0, bottom: 0, left: 0 };\n\nfunction side(reach: number): number {\n\tif (!(reach > 0)) {\n\t\treturn 0;\n\t}\n\treturn Math.min(MAX_THREE_VIEW_OVERFLOW, reach + OVERFLOW_MARGIN);\n}\n\n/**\n * The overflow of points in normalised device coordinates (x right, y up,\n * the element box spanning -1..1 on both axes).\n */\nexport function threeViewOverflowFromNdc(\n\tpoints: readonly { x: number; y: number }[],\n): ThreeViewOverflow {\n\tif (points.length === 0) {\n\t\treturn NO_THREE_VIEW_OVERFLOW;\n\t}\n\tlet minX = Infinity;\n\tlet maxX = -Infinity;\n\tlet minY = Infinity;\n\tlet maxY = -Infinity;\n\tfor (const p of points) {\n\t\tif (!Number.isFinite(p.x) || !Number.isFinite(p.y)) {\n\t\t\tcontinue;\n\t\t}\n\t\tminX = Math.min(minX, p.x);\n\t\tmaxX = Math.max(maxX, p.x);\n\t\tminY = Math.min(minY, p.y);\n\t\tmaxY = Math.max(maxY, p.y);\n\t}\n\tif (minX > maxX) {\n\t\treturn NO_THREE_VIEW_OVERFLOW;\n\t}\n\treturn {\n\t\ttop: side((maxY - 1) / 2),\n\t\tright: side((maxX - 1) / 2),\n\t\tbottom: side((-1 - minY) / 2),\n\t\tleft: side((-1 - minX) / 2),\n\t};\n}\n\n/** Whether an overflow reaches past any edge. */\nexport function hasThreeViewOverflow(overflow: ThreeViewOverflow | null | undefined): boolean {\n\treturn Boolean(\n\t\toverflow &&\n\t\t(overflow.top > 0 || overflow.right > 0 || overflow.bottom > 0 || overflow.left > 0),\n\t);\n}\n\n/** Whether two overflows differ. */\nexport function threeViewOverflowChanged(a: ThreeViewOverflow, b: ThreeViewOverflow): boolean {\n\treturn a.top !== b.top || a.right !== b.right || a.bottom !== b.bottom || a.left !== b.left;\n}\n\n/** The drawing buffer size of a view grown by its overflow. */\nexport function overflowPixelSize(\n\tsize: ThreeViewSize,\n\toverflow: ThreeViewOverflow,\n): { width: number; height: number } {\n\tconst clamp = (px: number): number => Math.max(1, Math.min(MAX_VIEW_PIXELS, Math.round(px)));\n\treturn {\n\t\twidth: clamp(size.pixelWidth * (1 + overflow.left + overflow.right)),\n\t\theight: clamp(size.pixelHeight * (1 + overflow.top + overflow.bottom)),\n\t};\n}\n\n/**\n * The camera view offset (three's `setViewOffset` arguments) that frames the\n * grown buffer: the element box stays the camera's full frame, and the\n * sub-window starts `left`/`top` before it and is correspondingly larger.\n */\nexport function overflowViewOffset(\n\tsize: ThreeViewSize,\n\toverflow: ThreeViewOverflow,\n): { fullWidth: number; fullHeight: number; x: number; y: number; width: number; height: number } {\n\tconst fullWidth = Math.max(1, size.pixelWidth);\n\tconst fullHeight = Math.max(1, size.pixelHeight);\n\treturn {\n\t\tfullWidth,\n\t\tfullHeight,\n\t\tx: -overflow.left * fullWidth,\n\t\ty: -overflow.top * fullHeight,\n\t\twidth: fullWidth * (1 + overflow.left + overflow.right),\n\t\theight: fullHeight * (1 + overflow.top + overflow.bottom),\n\t};\n}\n\n/**\n * CSS for the canvas of a view with an overflow: percentages of the element\n * box, so it tracks the box without re-measuring. Empty for no overflow.\n */\nexport function overflowCanvasCss(overflow: ThreeViewOverflow): string {\n\tif (!hasThreeViewOverflow(overflow)) {\n\t\treturn '';\n\t}\n\tconst pct = (v: number): string => `${Number((v * 100).toFixed(4))}%`;\n\treturn [\n\t\t`left:${pct(-overflow.left)}`,\n\t\t`top:${pct(-overflow.top)}`,\n\t\t`width:${pct(1 + overflow.left + overflow.right)}`,\n\t\t`height:${pct(1 + overflow.top + overflow.bottom)}`,\n\t].join(';');\n}\n"],"mappings":"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"}
|