@pixerate/flair 0.35.2 → 0.36.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +2 -2
  3. package/dist/catalog/index.d.ts +3 -3
  4. package/dist/catalog/index.js +2 -2
  5. package/dist/{chunk-VKIDRHBG.js → chunk-6B62CBTP.js} +49 -4
  6. package/dist/chunk-6B62CBTP.js.map +1 -0
  7. package/dist/{chunk-O5QKC2L7.js → chunk-D4GVMDHE.js} +6 -6
  8. package/dist/{chunk-MOLJPWME.js → chunk-G5M777AN.js} +3 -3
  9. package/dist/{chunk-N5HXMQOK.js → chunk-OIRDNPMD.js} +22 -7
  10. package/dist/chunk-OIRDNPMD.js.map +1 -0
  11. package/dist/{chunk-JETRHCP3.js → chunk-XAQ5FWKS.js} +4 -4
  12. package/dist/chunk-XAQ5FWKS.js.map +1 -0
  13. package/dist/{chunk-2O3RMSOE.js → chunk-XFTSWPSX.js} +3 -3
  14. package/dist/{chunk-IHUNCBMF.js → chunk-Z3LKEODP.js} +2 -2
  15. package/dist/cli.js +2 -2
  16. package/dist/editor/index.d.ts +2 -2
  17. package/dist/editor/index.js +3 -3
  18. package/dist/{effect-HL4XF4FD.js → effect-RXOSCAK2.js} +8 -8
  19. package/dist/embed/index.d.ts +2 -2
  20. package/dist/embed/index.js +4 -4
  21. package/dist/index.d.ts +2 -2
  22. package/dist/index.js +12 -4
  23. package/dist/index.js.map +1 -1
  24. package/dist/node.d.ts +2 -2
  25. package/dist/node.js +7 -7
  26. package/dist/react/index.d.ts +2 -2
  27. package/dist/react/index.js +5 -5
  28. package/dist/svelte/index.d.ts +2 -2
  29. package/dist/svelte/index.js +5 -5
  30. package/dist/{svg-DaKRPA9v.d.ts → svg-cunB0HBn.d.ts} +23 -6
  31. package/dist/{types-B4Wjzde0.d.ts → types-CVgiEJyP.d.ts} +1 -1
  32. package/dist/vector/index.d.ts +2 -2
  33. package/dist/vector/index.js +12 -4
  34. package/package.json +1 -1
  35. package/dist/chunk-JETRHCP3.js.map +0 -1
  36. package/dist/chunk-N5HXMQOK.js.map +0 -1
  37. package/dist/chunk-VKIDRHBG.js.map +0 -1
  38. /package/dist/{chunk-O5QKC2L7.js.map → chunk-D4GVMDHE.js.map} +0 -0
  39. /package/dist/{chunk-MOLJPWME.js.map → chunk-G5M777AN.js.map} +0 -0
  40. /package/dist/{chunk-2O3RMSOE.js.map → chunk-XFTSWPSX.js.map} +0 -0
  41. /package/dist/{chunk-IHUNCBMF.js.map → chunk-Z3LKEODP.js.map} +0 -0
  42. /package/dist/{effect-HL4XF4FD.js.map → effect-RXOSCAK2.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @pixerate/flair
2
2
 
3
+ ## 0.36.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ba87bdf: Vector motion takes any cubic-bezier easing: `SvgAnimation.ease` (and `stepProgress`, `stepData`, `animateCount`) accept `[x1, y1, x2, y2]` besides `linear`, `out` and `in-out`, with overshoot for back eases. `svgMotionIssues` checks the curve, and `svgAnimatedMarkup` writes it as an exact SMIL `keySplines` curve (sampled when it overshoots, which SMIL cannot spline). New exports: `SvgEase`, `CubicBezier`, `cubicBezierEase`, `easeFunction`, `isCubicBezier`, `isSvgEase`. Animations exported from `@pixerate/editor`'s animation editor can use their own curves instead of being sampled into linear steps.
8
+
3
9
  ## 0.35.2
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -28,7 +28,7 @@ Flair gives products a library of good-looking, configurable visual effects (her
28
28
  - Scrolling: `iScroll` (the canvas's progress through the viewport, page scroll, velocity, and whether it is scrolling), fed by `ShaderRenderer` and scriptable in `ShaderFrames`; vector effects scrub with the page under `trigger: "scroll"`.
29
29
  - Live previews (`ShaderRenderer`, with optional `{ alpha: true }` for transparent overlays) and many animated or hover-activated thumbnails on one context (`ThumbnailPool`).
30
30
  - Frames at exact times (`ShaderFrames`), looping GIFs, and standalone HTML pages.
31
- - ✒️ **Vector motion (`@pixerate/flair/vector`)**: animated SVG described as data. Catalog vector effects declare their controls in the picture (`{{name: type …}}`), text included. It covers attribute tweens, draw-on strokes, motion along paths, counters (`animateCount` / `formatCount` for DOM elements too), text written letter by letter (`write`, with `scramble` and `caret`), shape morphs between any paths (`morphPaths`, `morphSequence`) and view zooms. Every frame is a pure function of time (`svgFrame`), and `SvgPlayer` plays it (with `scrollTrigger`, `hideWhenPaused`, `reset()`, and `trigger: "hover" | "press" | "click" | "scroll"` to play in answer to the pointer or scrub with the page).
31
+ - ✒️ **Vector motion (`@pixerate/flair/vector`)**: animated SVG described as data. Catalog vector effects declare their controls in the picture (`{{name: type …}}`), text included. A change's `ease` is `linear`, `out`, `in-out` or any CSS cubic-bezier as `[x1, y1, x2, y2]` (overshoot allowed). It covers attribute tweens, draw-on strokes, motion along paths, counters (`animateCount` / `formatCount` for DOM elements too), text written letter by letter (`write`, with `scramble` and `caret`), shape morphs between any paths (`morphPaths`, `morphSequence`) and view zooms. Every frame is a pure function of time (`svgFrame`), and `SvgPlayer` plays it (with `scrollTrigger`, `hideWhenPaused`, `reset()`, and `trigger: "hover" | "press" | "click" | "scroll"` to play in answer to the pointer or scrub with the page).
32
32
  - 🎛️ **Effect editor (`@pixerate/flair/editor`)**:
33
33
  - A headless editor for an effect's source, values, keyframes, presets and timeline.
34
34
  - Built on [`@pixerate/editor`](https://github.com/Pixerate/editor)'s undo history and command registry, with no UI framework assumed.
@@ -285,7 +285,7 @@ img.src = `data:image/svg+xml,${encodeURIComponent(svg)}`; // or save it as stat
285
285
  ```
286
286
 
287
287
  - **Options**: `hold` (ms on the last frame, default 600), `duration` (the loop, default the picture's length plus `hold`), `loop: false` to play once and stay on the last frame, `steps` (ms) for click-triggered effects, `fps` (default 30) for what is sampled, and `idSuffix`.
288
- - **How it is written**: each attribute change is one `<animate>` (a `transform` is one `<animateTransform>` per function), and eases are exact `keySplines`. `draw` animates `stroke-dashoffset`, `along` becomes `<animateMotion>` on the path, `view` animates the `viewBox` (keeping `data-fixed` and `data-nonscaling` elements as the player does), and `solo` toggles `display`. Counts and written text are one `<tspan>` per text, shown in turn, sampled at `fps`. Every element starts on the first frame, so it still shows that where SMIL does not run.
288
+ - **How it is written**: each attribute change is one `<animate>` (a `transform` is one `<animateTransform>` per function), and eases are exact `keySplines` (a cubic-bezier `ease` is written as given, unless it overshoots 0–1, which SMIL cannot spline, so it is sampled). `draw` animates `stroke-dashoffset`, `along` becomes `<animateMotion>` on the path, `view` animates the `viewBox` (keeping `data-fixed` and `data-nonscaling` elements as the player does), and `solo` toggles `display`. Counts and written text are one `<tspan>` per text, shown in turn, sampled at `fps`. Every element starts on the first frame, so it still shows that where SMIL does not run.
289
289
  - **Limits**: a count that changes faster than `fps` can be up to half a sample out. A change cut short by the next one, or a `matrix` transform, is sampled. A `view` that frames an element by id (it needs layout) is left out, as in `svgFrameMarkup`. Attributes SMIL cannot blend change in steps. Ids the picture refers to (gradients, filters, paths followed) get a suffix, a hash of the motion by default, so two files inlined in one page don't clash. `#id` selectors in a `<style>` are not renamed. Interaction triggers (hover, press, click) cannot be written as SMIL, so a click-triggered effect plays its `steps` on a timer.
290
290
  - **Size**: catalog effects come out at 1 to 105 KB (`drip-text` is the largest).
291
291
 
@@ -1,7 +1,7 @@
1
1
  import { a as ControlDef, C as ControlValue } from '../controls-Ec6P0Vpy.js';
2
- import { a as SvgTrigger } from '../svg-DaKRPA9v.js';
3
- import { a as VideoUse, E as EffectDefinition, b as EffectCategory, S as ShaderEffect } from '../types-B4Wjzde0.js';
4
- export { C as CURRENT_COLOR, c as EFFECT_CATEGORIES, d as EFFECT_CATEGORY_GROUPS, e as EffectCategoryGroup, f as EffectPreset, g as VECTOR_CONTROL_TYPES, h as VIDEO_USES, i as VectorControl, V as VectorEffect, j as categoryGroup, k as colorControl, l as isCurrentColor, n as numberControl, r as renderVectorEffect, v as vectorControlDef, m as vectorControlIssues, o as vectorControls, p as vectorEffectControls } from '../types-B4Wjzde0.js';
2
+ import { a as SvgTrigger } from '../svg-cunB0HBn.js';
3
+ import { a as VideoUse, E as EffectDefinition, b as EffectCategory, S as ShaderEffect } from '../types-CVgiEJyP.js';
4
+ export { C as CURRENT_COLOR, c as EFFECT_CATEGORIES, d as EFFECT_CATEGORY_GROUPS, e as EffectCategoryGroup, f as EffectPreset, g as VECTOR_CONTROL_TYPES, h as VIDEO_USES, i as VectorControl, V as VectorEffect, j as categoryGroup, k as colorControl, l as isCurrentColor, n as numberControl, r as renderVectorEffect, v as vectorControlDef, m as vectorControlIssues, o as vectorControls, p as vectorEffectControls } from '../types-CVgiEJyP.js';
5
5
 
6
6
  /**
7
7
  * What an effect takes and how it answers the pointer, worked out from the
@@ -32,10 +32,10 @@ import {
32
32
  vectorControlIssues,
33
33
  vectorControls,
34
34
  vectorEffectControls
35
- } from "../chunk-IHUNCBMF.js";
35
+ } from "../chunk-Z3LKEODP.js";
36
36
  import "../chunk-EHDJ3CPJ.js";
37
37
  import "../chunk-VYOMXE6I.js";
38
- import "../chunk-VKIDRHBG.js";
38
+ import "../chunk-6B62CBTP.js";
39
39
  export {
40
40
  CURRENT_COLOR,
41
41
  EFFECTS,
@@ -358,6 +358,47 @@ var EASES = {
358
358
  "in-out": (t) => t < 0.5 ? 4 * t * t * t : 1 - (-2 * t + 2) ** 3 / 2,
359
359
  out: (t) => 1 - (1 - t) ** 3
360
360
  };
361
+ function isCubicBezier(value) {
362
+ return Array.isArray(value) && value.length === 4 && value.every((n) => typeof n === "number" && Number.isFinite(n)) && value[0] >= 0 && value[0] <= 1 && value[2] >= 0 && value[2] <= 1;
363
+ }
364
+ var isSvgEase = (value) => typeof value === "string" && value in EASES || isCubicBezier(value);
365
+ var bezierCache = /* @__PURE__ */ new Map();
366
+ function cubicBezierEase([x1, y1, x2, y2]) {
367
+ const key = `${x1},${y1},${x2},${y2}`;
368
+ const hit = bezierCache.get(key);
369
+ if (hit) return hit;
370
+ const at = (a, b, s) => 3 * a * (1 - s) ** 2 * s + 3 * b * (1 - s) * s * s + s ** 3;
371
+ const slope = (a, b, s) => 3 * a * (1 - s) ** 2 + 6 * (b - a) * (1 - s) * s + 3 * (1 - b) * s * s;
372
+ const fn = (t) => {
373
+ if (t <= 0) return 0;
374
+ if (t >= 1) return 1;
375
+ let s = t;
376
+ for (let i = 0; i < 8; i++) {
377
+ const dx = at(x1, x2, s) - t;
378
+ if (Math.abs(dx) < 1e-7) return at(y1, y2, s);
379
+ const d = slope(x1, x2, s);
380
+ if (Math.abs(d) < 1e-6) break;
381
+ s -= dx / d;
382
+ }
383
+ let [lo, hi] = [0, 1];
384
+ s = t;
385
+ for (let i = 0; i < 40; i++) {
386
+ const x = at(x1, x2, s);
387
+ if (Math.abs(x - t) < 1e-7) break;
388
+ if (x < t) lo = s;
389
+ else hi = s;
390
+ s = (lo + hi) / 2;
391
+ }
392
+ return at(y1, y2, s);
393
+ };
394
+ if (bezierCache.size > 256) bezierCache.clear();
395
+ bezierCache.set(key, fn);
396
+ return fn;
397
+ }
398
+ function easeFunction(ease, fallback = "in-out") {
399
+ if (ease === void 0) return EASES[fallback];
400
+ return typeof ease === "string" ? EASES[ease] : cubicBezierEase(ease);
401
+ }
361
402
  var STEP_MS = 800;
362
403
  var clamp01 = (t) => t < 0 ? 0 : t > 1 ? 1 : t;
363
404
  function stepStart(steps, step) {
@@ -370,7 +411,7 @@ function stepProgress(steps, timeMs, step, options = {}) {
370
411
  const from = start + (options.delay ?? 0);
371
412
  const ms = options.ms ?? STEP_MS;
372
413
  const t = ms > 0 ? clamp01((timeMs - from) / ms) : timeMs >= from ? 1 : 0;
373
- return EASES[options.ease ?? "in-out"](t);
414
+ return easeFunction(options.ease)(t);
374
415
  }
375
416
  var defaultDataKey = (item, index) => {
376
417
  if (item && typeof item === "object") {
@@ -572,8 +613,8 @@ function svgMotionIssues(motion) {
572
613
  if (a.ms !== void 0 && !(a.ms >= 0)) issues.push(`${where}: \`ms\` must be 0 or more`);
573
614
  if (a.delay !== void 0 && !(a.delay >= 0))
574
615
  issues.push(`${where}: \`delay\` must be 0 or more`);
575
- if (a.ease !== void 0 && !(a.ease in EASES))
576
- issues.push(`${where}: \`ease\` is one of ${Object.keys(EASES).join(", ")}`);
616
+ if (a.ease !== void 0 && !isSvgEase(a.ease))
617
+ issues.push(`${where}: \`ease\` is one of ${Object.keys(EASES).join(", ")}, or a cubic-bezier [x1, y1, x2, y2] with x1 and x2 from 0 to 1`);
577
618
  if (!a.attrs && !a.draw && !a.count && a.write === void 0 && a.view === void 0 && !a.along && a.solo === void 0)
578
619
  issues.push(
579
620
  `${where} changes nothing: give \`attrs\`, \`draw\`, \`count\`, \`write\`, \`view\`, \`along\` or \`solo\``
@@ -618,6 +659,10 @@ export {
618
659
  morphPaths,
619
660
  pathPointAt,
620
661
  EASES,
662
+ isCubicBezier,
663
+ isSvgEase,
664
+ cubicBezierEase,
665
+ easeFunction,
621
666
  STEP_MS,
622
667
  stepStart,
623
668
  stepProgress,
@@ -633,4 +678,4 @@ export {
633
678
  svgOpeningTag,
634
679
  svgMotionIssues
635
680
  };
636
- //# sourceMappingURL=chunk-VKIDRHBG.js.map
681
+ //# sourceMappingURL=chunk-6B62CBTP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/vector/morph.ts","../src/vector/motion.ts"],"sourcesContent":["/**\n * Shape morphing: any SVG paths turned into paths with the same structure, so\n * an `attrs` change on `d` (see `SvgAnimation`) blends one into the other\n * point by point. Pure functions of their arguments, with no DOM.\n */\n\ntype Point = [number, number];\n\n/** One piece of a path: its outline as points, and whether it closes. */\ninterface Ring {\n points: Point[];\n closed: boolean;\n}\n\nexport interface MorphOptions {\n /** Points per piece of the shape (default 72): more follows curves more closely. */\n points?: number;\n /** Decimals in the numbers written (default 2). */\n decimals?: number;\n}\n\n/** Segments a curve is split into before resampling. */\nconst CURVE_STEPS = 24;\n\nconst TOKEN = /[MmLlHhVvCcSsQqTtAaZz]|-?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[-+]?\\d+)?/gi;\n\n/** Arguments each command takes (repeated commands take them again). */\nconst ARGS: Record<string, number> = { m: 2, l: 2, h: 1, v: 1, c: 6, s: 4, q: 4, t: 2, a: 7, z: 0 };\n\n/**\n * The pieces of a path's `d` as outlines: lines kept, curves and arcs split\n * into short lines. Throws on a command it does not know.\n */\nfunction flatten(d: string): Ring[] {\n const stray = d.replace(TOKEN, \"\").replace(/[\\s,]+/g, \"\");\n if (stray) throw new Error(`\"${stray[0]}\" is not a path command`);\n const tokens = d.match(TOKEN) ?? [];\n const rings: Ring[] = [];\n // Typed by a cast: the helpers below assign it, which narrowing would miss.\n let ring = null as Ring | null;\n let x = 0;\n let y = 0;\n let startX = 0;\n let startY = 0;\n // The last control point, for S and T.\n let cx = 0;\n let cy = 0;\n let prev = \"\";\n let i = 0;\n let command = \"\";\n const add = (px: number, py: number) => ring!.points.push([px, py]);\n const begin = (px: number, py: number) => {\n if (ring && ring.points.length) rings.push(ring);\n ring = { points: [[px, py]], closed: false };\n };\n while (i < tokens.length) {\n if (/[a-z]/i.test(tokens[i]!)) command = tokens[i++]!;\n else if (!command) throw new Error(`\"${tokens[i]}\" needs a command (M, L, C, …) before it`);\n const lower = command.toLowerCase();\n if (!(lower in ARGS)) throw new Error(`Unknown path command \"${command}\"`);\n const rel = command !== command.toUpperCase();\n const n = ARGS[lower]!;\n const args = tokens.slice(i, i + n).map(Number);\n if (args.length < n || args.some((v) => Number.isNaN(v))) break;\n i += n;\n const ox = rel ? x : 0;\n const oy = rel ? y : 0;\n if (lower === \"z\") {\n if (ring) {\n ring.closed = true;\n rings.push(ring);\n ring = null;\n }\n x = startX;\n y = startY;\n prev = \"z\";\n // A Z takes no arguments: wait for the next command.\n command = \"\";\n continue;\n }\n if (!ring) begin(x, y);\n switch (lower) {\n case \"m\":\n x = ox + args[0]!;\n y = oy + args[1]!;\n startX = x;\n startY = y;\n begin(x, y);\n // Pairs after a moveto are linetos.\n command = rel ? \"l\" : \"L\";\n break;\n case \"l\":\n x = ox + args[0]!;\n y = oy + args[1]!;\n add(x, y);\n break;\n case \"h\":\n x = ox + args[0]!;\n add(x, y);\n break;\n case \"v\":\n y = (rel ? y : 0) + args[0]!;\n add(x, y);\n break;\n case \"c\":\n case \"s\": {\n let x1: number;\n let y1: number;\n let rest: number[];\n if (lower === \"c\") {\n x1 = ox + args[0]!;\n y1 = oy + args[1]!;\n rest = args.slice(2);\n } else {\n const smooth = prev === \"c\" || prev === \"s\";\n x1 = smooth ? 2 * x - cx : x;\n y1 = smooth ? 2 * y - cy : y;\n rest = args;\n }\n const x2 = ox + rest[0]!;\n const y2 = oy + rest[1]!;\n const ex = ox + rest[2]!;\n const ey = oy + rest[3]!;\n for (let k = 1; k <= CURVE_STEPS; k++) {\n const t = k / CURVE_STEPS;\n const u = 1 - t;\n add(\n u * u * u * x + 3 * u * u * t * x1 + 3 * u * t * t * x2 + t * t * t * ex,\n u * u * u * y + 3 * u * u * t * y1 + 3 * u * t * t * y2 + t * t * t * ey,\n );\n }\n cx = x2;\n cy = y2;\n x = ex;\n y = ey;\n break;\n }\n case \"q\":\n case \"t\": {\n let x1: number;\n let y1: number;\n let ex: number;\n let ey: number;\n if (lower === \"q\") {\n x1 = ox + args[0]!;\n y1 = oy + args[1]!;\n ex = ox + args[2]!;\n ey = oy + args[3]!;\n } else {\n const smooth = prev === \"q\" || prev === \"t\";\n x1 = smooth ? 2 * x - cx : x;\n y1 = smooth ? 2 * y - cy : y;\n ex = ox + args[0]!;\n ey = oy + args[1]!;\n }\n for (let k = 1; k <= CURVE_STEPS; k++) {\n const t = k / CURVE_STEPS;\n const u = 1 - t;\n add(u * u * x + 2 * u * t * x1 + t * t * ex, u * u * y + 2 * u * t * y1 + t * t * ey);\n }\n cx = x1;\n cy = y1;\n x = ex;\n y = ey;\n break;\n }\n case \"a\": {\n const ex = ox + args[5]!;\n const ey = oy + args[6]!;\n for (const p of arcPoints(x, y, args[0]!, args[1]!, args[2]!, args[3]! !== 0, args[4]! !== 0, ex, ey)) add(p[0], p[1]);\n x = ex;\n y = ey;\n break;\n }\n }\n prev = lower;\n }\n if (ring && ring.points.length) rings.push(ring);\n return rings\n .map((r) => {\n // A ring that ends where it starts is closed, Z or not.\n const [a, b] = [r.points[0]!, r.points[r.points.length - 1]!];\n const closes = r.points.length > 2 && Math.hypot(a[0] - b[0], a[1] - b[1]) < 1e-6;\n return { points: closes ? r.points.slice(0, -1) : r.points, closed: r.closed || closes };\n })\n .filter((r) => r.points.length > 1);\n}\n\n/** Points along an SVG arc (endpoint form), not including its start. */\nfunction arcPoints(\n x1: number,\n y1: number,\n rx: number,\n ry: number,\n angle: number,\n large: boolean,\n sweep: boolean,\n x2: number,\n y2: number,\n): Point[] {\n rx = Math.abs(rx);\n ry = Math.abs(ry);\n if (!rx || !ry || (x1 === x2 && y1 === y2)) return [[x2, y2]];\n const phi = (angle * Math.PI) / 180;\n const cos = Math.cos(phi);\n const sin = Math.sin(phi);\n const dx = (x1 - x2) / 2;\n const dy = (y1 - y2) / 2;\n const x1p = cos * dx + sin * dy;\n const y1p = -sin * dx + cos * dy;\n // Radii too small to reach are scaled up, as SVG says.\n const lambda = (x1p * x1p) / (rx * rx) + (y1p * y1p) / (ry * ry);\n if (lambda > 1) {\n rx *= Math.sqrt(lambda);\n ry *= Math.sqrt(lambda);\n }\n const num = rx * rx * ry * ry - rx * rx * y1p * y1p - ry * ry * x1p * x1p;\n const den = rx * rx * y1p * y1p + ry * ry * x1p * x1p;\n const k = (large === sweep ? -1 : 1) * Math.sqrt(Math.max(0, num / den));\n const cxp = (k * rx * y1p) / ry;\n const cyp = (-k * ry * x1p) / rx;\n const cx = cos * cxp - sin * cyp + (x1 + x2) / 2;\n const cy = sin * cxp + cos * cyp + (y1 + y2) / 2;\n const theta = (ux: number, uy: number, vx: number, vy: number) =>\n Math.atan2(ux * vy - uy * vx, ux * vx + uy * vy);\n const start = theta(1, 0, (x1p - cxp) / rx, (y1p - cyp) / ry);\n let delta = theta((x1p - cxp) / rx, (y1p - cyp) / ry, (-x1p - cxp) / rx, (-y1p - cyp) / ry);\n if (!sweep && delta > 0) delta -= 2 * Math.PI;\n if (sweep && delta < 0) delta += 2 * Math.PI;\n const steps = Math.max(2, Math.ceil((Math.abs(delta) / (Math.PI / 2)) * (CURVE_STEPS / 2)));\n const out: Point[] = [];\n for (let s = 1; s <= steps; s++) {\n const t = start + (delta * s) / steps;\n const px = rx * Math.cos(t);\n const py = ry * Math.sin(t);\n out.push([cos * px - sin * py + cx, sin * px + cos * py + cy]);\n }\n out[out.length - 1] = [x2, y2];\n return out;\n}\n\n/**\n * `n` points evenly spaced along a ring. A closed ring goes round once; an\n * open one (a stroke) is resampled as closed by going there and back, so it\n * can turn into a closed shape.\n */\nfunction resample(ring: Ring, n: number): Point[] {\n const pts = ring.closed ? [...ring.points, ring.points[0]!] : [...ring.points, ...ring.points.slice(0, -1).reverse()];\n const lengths = [0];\n for (let i = 1; i < pts.length; i++)\n lengths.push(lengths[i - 1]! + Math.hypot(pts[i]![0] - pts[i - 1]![0], pts[i]![1] - pts[i - 1]![1]));\n const total = lengths[lengths.length - 1]!;\n if (total === 0) return Array.from({ length: n }, () => [pts[0]![0], pts[0]![1]] as Point);\n const out: Point[] = [];\n let j = 1;\n for (let k = 0; k < n; k++) {\n const at = (k / n) * total;\n while (j < lengths.length - 1 && lengths[j]! < at) j++;\n const seg = lengths[j]! - lengths[j - 1]!;\n const t = seg > 0 ? (at - lengths[j - 1]!) / seg : 0;\n const a = pts[j - 1]!;\n const b = pts[j]!;\n out.push([a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t]);\n }\n return out;\n}\n\nconst signedArea = (pts: Point[]) => {\n let sum = 0;\n for (let i = 0; i < pts.length; i++) {\n const a = pts[i]!;\n const b = pts[(i + 1) % pts.length]!;\n sum += a[0] * b[1] - b[0] * a[1];\n }\n return sum / 2;\n};\n\nconst centroid = (pts: Point[]): Point => {\n let x = 0;\n let y = 0;\n for (const p of pts) {\n x += p[0];\n y += p[1];\n }\n return [x / pts.length, y / pts.length];\n};\n\n/** How big a piece is: its area, or for a stroke its length times a little. */\nfunction size(ring: Ring, pts: Point[]): number {\n const area = Math.abs(signedArea(pts));\n if (ring.closed && area > 0) return area;\n let length = 0;\n for (let i = 1; i < ring.points.length; i++)\n length += Math.hypot(ring.points[i]![0] - ring.points[i - 1]![0], ring.points[i]![1] - ring.points[i - 1]![1]);\n return length;\n}\n\ninterface Piece {\n pts: Point[];\n centre: Point;\n size: number;\n}\n\n/**\n * Pairs the pieces of one shape with the slots of the shape before it,\n * nearest and most alike first: a slot left over is empty (a piece that\n * shrinks away), and a piece left over takes an empty slot (it grows).\n */\nfunction assign(before: (Piece | null)[], pieces: Piece[], scale: number): (Piece | null)[] {\n const out: (Piece | null)[] = before.map(() => null);\n const pairs: { slot: number; piece: number; cost: number }[] = [];\n before.forEach((slot, s) => {\n if (!slot) return;\n pieces.forEach((p, i) => {\n const distance = Math.hypot(slot.centre[0] - p.centre[0], slot.centre[1] - p.centre[1]) / scale;\n const likeness = Math.abs(Math.log((slot.size + 1e-9) / (p.size + 1e-9)));\n pairs.push({ slot: s, piece: i, cost: distance + 0.5 * likeness });\n });\n });\n pairs.sort((a, b) => a.cost - b.cost);\n const used = new Set<number>();\n for (const { slot, piece } of pairs) {\n if (out[slot] || used.has(piece)) continue;\n out[slot] = pieces[piece]!;\n used.add(piece);\n }\n let free = 0;\n pieces.forEach((p, i) => {\n if (used.has(i)) return;\n while (out[free] || before[free]) free++;\n out[free] = p;\n });\n return out;\n}\n\n/** `pts` turned and started so it lines up with `ref` point by point (the shortest moves). */\nfunction align(ref: Point[], pts: Point[]): Point[] {\n const n = pts.length;\n let best = pts;\n let bestCost = Infinity;\n for (const candidate of [pts, [...pts].reverse()]) {\n for (let shift = 0; shift < n; shift++) {\n let cost = 0;\n for (let k = 0; k < n && cost < bestCost; k++) {\n const a = ref[k]!;\n const b = candidate[(k + shift) % n]!;\n cost += (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2;\n }\n if (cost < bestCost) {\n bestCost = cost;\n best = candidate.slice(shift).concat(candidate.slice(0, shift));\n }\n }\n }\n return best;\n}\n\n/**\n * Paths with one structure for a sequence of shapes, so each blends into the\n * next (and the last into the first) with `attrs: { d: [a, b] }`. Any path\n * commands work, curves and arcs included, and shapes can have different\n * numbers of pieces (an icon's parts, a letter's holes): pieces are paired by\n * position and size, and one without a partner grows from or shrinks to a\n * point. Draw the results with `fill-rule=\"evenodd\"`, since a piece's\n * direction can change. Throws a sentence when a path cannot be read.\n */\nexport function morphSequence(paths: readonly string[], options: MorphOptions = {}): string[] {\n const n = Math.max(8, Math.round(options.points ?? 72));\n const decimals = options.decimals ?? 2;\n const shapes = paths.map((d, i) => {\n let rings: Ring[];\n try {\n rings = flatten(d);\n } catch (e) {\n throw new Error(`Path ${i + 1} cannot be read: ${(e as Error).message}`);\n }\n if (!rings.length) throw new Error(`Path ${i + 1} draws nothing: give it at least two points`);\n return rings.map((r): Piece => {\n const pts = resample(r, n);\n return { pts, centre: centroid(pts), size: size(r, pts) };\n });\n });\n if (!shapes.length) return [];\n const slots = Math.max(...shapes.map((s) => s.length));\n // How far apart counts as far, from the shapes' extent.\n const xs = shapes.flat().flatMap((p) => p.pts.map((q) => q[0]));\n const ys = shapes.flat().flatMap((p) => p.pts.map((q) => q[1]));\n const scale = Math.max(1e-6, Math.max(...xs) - Math.min(...xs), Math.max(...ys) - Math.min(...ys));\n // Biggest pieces first, so the main outlines keep the first slots.\n const first = [...shapes[0]!].sort((a, b) => b.size - a.size);\n const assigned: (Piece | null)[][] = [[...first, ...Array<null>(slots - first.length).fill(null)]];\n for (let i = 1; i < shapes.length; i++) assigned.push(assign(assigned[i - 1]!, shapes[i]!, scale));\n // An empty slot is a point: where the piece in that slot is in the nearest shape that has one.\n const resolved = assigned.map((shape, i) =>\n shape.map((piece, s): Point[] => {\n if (piece) return piece.pts;\n for (let k = 1; k < shapes.length; k++) {\n const near = assigned[(i + k) % shapes.length]![s] ?? assigned[(i - k + shapes.length) % shapes.length]![s];\n if (near) return Array.from({ length: n }, () => [near.centre[0], near.centre[1]] as Point);\n }\n return Array.from({ length: n }, () => [0, 0] as Point);\n }),\n );\n for (let i = 1; i < resolved.length; i++)\n resolved[i] = resolved[i]!.map((pts, s) => align(resolved[i - 1]![s]!, pts));\n const num = (v: number) => {\n const r = Number(v.toFixed(decimals));\n return String(Object.is(r, -0) ? 0 : r);\n };\n return resolved.map((shape) =>\n shape.map((pts) => `M${pts.map((p) => `${num(p[0])} ${num(p[1])}`).join(\" L\")} Z`).join(\" \"),\n );\n}\n\n/**\n * Two paths turned into paths with one structure, so `attrs: { d: [from, to] }`\n * blends one into the other (see {@link morphSequence}).\n */\nexport function morphPaths(from: string, to: string, options: MorphOptions = {}): [string, string] {\n const [a, b] = morphSequence([from, to], options);\n return [a!, b!];\n}\n\n/**\n * @internal The point `at` (0–1) of the way along a path's `d` by length, as\n * a browser's `getPointAtLength` finds it (moves between pieces not counted),\n * with curves split into short lines. Undefined when `d` does not parse.\n */\nexport function pathPointAt(d: string, at: number): [number, number] | undefined {\n let rings: Ring[];\n try {\n rings = flatten(d);\n } catch {\n return undefined;\n }\n const lines: [Point, Point, number][] = [];\n for (const ring of rings) {\n const pts = ring.closed ? [...ring.points, ring.points[0]!] : ring.points;\n for (let i = 1; i < pts.length; i++)\n lines.push([pts[i - 1]!, pts[i]!, Math.hypot(pts[i]![0] - pts[i - 1]![0], pts[i]![1] - pts[i - 1]![1])]);\n }\n const first = rings[0]?.points[0];\n if (!first) return undefined;\n let left = Math.min(Math.max(at, 0), 1) * lines.reduce((sum, l) => sum + l[2], 0);\n for (const [a, b, length] of lines) {\n if (left <= length && length > 0) return [a[0] + ((b[0] - a[0]) * left) / length, a[1] + ((b[1] - a[1]) * left) / length];\n left -= length;\n }\n const last = lines[lines.length - 1];\n return last ? [last[1][0], last[1][1]] : [first[0], first[1]];\n}\n","/**\n * Vector motion: animated SVG pictures described as data. A picture changes in\n * steps (step 0 when it starts, step n at `steps[n - 1]` ms), and everything\n * here is a pure function of its arguments, so a frame comes out the same\n * however it is reached (played, stepped for a recording, or seeked).\n */\n\n/** Easing curves by name. */\nexport const EASES = {\n linear: (t: number) => t,\n \"in-out\": (t: number) => (t < 0.5 ? 4 * t * t * t : 1 - (-2 * t + 2) ** 3 / 2),\n out: (t: number) => 1 - (1 - t) ** 3,\n} as const;\n\nexport type EaseName = keyof typeof EASES;\n\n/**\n * A CSS `cubic-bezier(x1, y1, x2, y2)` curve: the two control points of a\n * curve from (0, 0) to (1, 1). `x1` and `x2` are 0–1; `y1` and `y2` may go\n * past 0–1 to overshoot (a back ease).\n */\nexport type CubicBezier = readonly [number, number, number, number];\n\n/** An easing: one of {@link EASES} by name, or any {@link CubicBezier} curve. */\nexport type SvgEase = EaseName | CubicBezier;\n\n/** Whether `value` is a {@link CubicBezier}: four finite numbers with `x1` and `x2` in 0–1. */\nexport function isCubicBezier(value: unknown): value is CubicBezier {\n return (\n Array.isArray(value) &&\n value.length === 4 &&\n value.every((n) => typeof n === \"number\" && Number.isFinite(n)) &&\n value[0] >= 0 && value[0] <= 1 && value[2] >= 0 && value[2] <= 1\n );\n}\n\n/** Whether `value` is an easing Flair plays: a name in {@link EASES} or a {@link CubicBezier}. */\nexport const isSvgEase = (value: unknown): value is SvgEase =>\n (typeof value === \"string\" && value in EASES) || isCubicBezier(value);\n\nconst bezierCache = new Map<string, (t: number) => number>();\n\n/** The curve as a function of time (0–1), solved for x by Newton's method with a bisection fallback. */\nexport function cubicBezierEase([x1, y1, x2, y2]: CubicBezier): (t: number) => number {\n const key = `${x1},${y1},${x2},${y2}`;\n const hit = bezierCache.get(key);\n if (hit) return hit;\n const at = (a: number, b: number, s: number) => 3 * a * (1 - s) ** 2 * s + 3 * b * (1 - s) * s * s + s ** 3;\n const slope = (a: number, b: number, s: number) => 3 * a * (1 - s) ** 2 + 6 * (b - a) * (1 - s) * s + 3 * (1 - b) * s * s;\n const fn = (t: number) => {\n if (t <= 0) return 0;\n if (t >= 1) return 1;\n let s = t;\n for (let i = 0; i < 8; i++) {\n const dx = at(x1, x2, s) - t;\n if (Math.abs(dx) < 1e-7) return at(y1, y2, s);\n const d = slope(x1, x2, s);\n if (Math.abs(d) < 1e-6) break;\n s -= dx / d;\n }\n let [lo, hi] = [0, 1];\n s = t;\n for (let i = 0; i < 40; i++) {\n const x = at(x1, x2, s);\n if (Math.abs(x - t) < 1e-7) break;\n if (x < t) lo = s;\n else hi = s;\n s = (lo + hi) / 2;\n }\n return at(y1, y2, s);\n };\n if (bezierCache.size > 256) bezierCache.clear();\n bezierCache.set(key, fn);\n return fn;\n}\n\n/** An easing as a function of time (0–1); `fallback` when it is not given. */\nexport function easeFunction(ease: SvgEase | undefined, fallback: EaseName = \"in-out\"): (t: number) => number {\n if (ease === undefined) return EASES[fallback];\n return typeof ease === \"string\" ? EASES[ease] : cubicBezierEase(ease);\n}\n\n/** How long a change takes by default, in ms. */\nexport const STEP_MS = 800;\n\nconst clamp01 = (t: number) => (t < 0 ? 0 : t > 1 ? 1 : t);\n\n/**\n * When `step` starts, in ms since the media started (step 0 at 0, step n at\n * `steps[n - 1]`), or undefined if it has not started yet.\n */\nexport function stepStart(steps: readonly number[], step: number): number | undefined {\n if (step <= 0) return 0;\n return steps[step - 1];\n}\n\n/**\n * How far a change that plays on `step` (after `delay` ms, over `ms`) has\n * got at `timeMs`, eased: 0 before it starts, 1 once it is over.\n */\nexport function stepProgress(\n steps: readonly number[],\n timeMs: number,\n step: number,\n options: { delay?: number; ms?: number; ease?: SvgEase } = {},\n): number {\n const start = stepStart(steps, step);\n if (start === undefined) return 0;\n const from = start + (options.delay ?? 0);\n const ms = options.ms ?? STEP_MS;\n const t = ms > 0 ? clamp01((timeMs - from) / ms) : timeMs >= from ? 1 : 0;\n return easeFunction(options.ease)(t);\n}\n\n/** The key an item in a list of data keeps from one state to the next. */\nexport type DataKey = (item: unknown, index: number) => string;\n\n/**\n * Keys items by their `id`, `key`, `name` or `label` (or a link's `source`\n * and `target`), else by position.\n */\nexport const defaultDataKey: DataKey = (item, index) => {\n if (item && typeof item === \"object\") {\n const o = item as Record<string, unknown>;\n if (o.source !== undefined && o.target !== undefined)\n return `${String(o.source)}→${String(o.target)}`;\n for (const k of [\"id\", \"key\", \"name\", \"label\"])\n if (typeof o[k] === \"string\" || typeof o[k] === \"number\") return String(o[k]);\n }\n return String(index);\n};\n\n/** Every number in `value` times `k`, so an item can grow from or shrink to nothing. */\nfunction scaled(value: unknown, k: number): unknown {\n if (typeof value === \"number\") return value * k;\n if (Array.isArray(value)) return value.map((v) => scaled(v, k));\n if (value && typeof value === \"object\")\n return Object.fromEntries(Object.entries(value).map(([key, v]) => [key, scaled(v, k)]));\n return value;\n}\n\n/**\n * Data between two states, `u` of the way from `a` to `b`. Numbers blend;\n * lists match their items by key (`keyOf`), so each keeps its identity and\n * moves rather than jumping, with items only in `b` growing from nothing and\n * items only in `a` shrinking away; objects blend field by field; anything\n * else changes halfway.\n */\nexport function lerpData<D>(a: D, b: D, u: number, keyOf: DataKey = defaultDataKey): D {\n if (u <= 0) return a;\n if (u >= 1) return b;\n return blend(a, b, u, keyOf) as D;\n}\n\nfunction blend(a: unknown, b: unknown, u: number, keyOf: DataKey): unknown {\n if (typeof a === \"number\" && typeof b === \"number\") return a + (b - a) * u;\n if (Array.isArray(a) && Array.isArray(b)) {\n const before = new Map(a.map((item, i) => [keyOf(item, i), item]));\n const after = new Set(b.map((item, i) => keyOf(item, i)));\n const out: unknown[] = b.map((item, i) => {\n const key = keyOf(item, i);\n return before.has(key) ? blend(before.get(key), item, u, keyOf) : scaled(item, u);\n });\n a.forEach((item, i) => {\n if (!after.has(keyOf(item, i))) out.push(scaled(item, 1 - u));\n });\n return out;\n }\n if (a && b && typeof a === \"object\" && typeof b === \"object\") {\n const ao = a as Record<string, unknown>;\n const bo = b as Record<string, unknown>;\n return Object.fromEntries(\n [...new Set([...Object.keys(ao), ...Object.keys(bo)])].map((k) => [\n k,\n k in ao && k in bo\n ? blend(ao[k], bo[k], u, keyOf)\n : k in bo\n ? scaled(bo[k], u)\n : scaled(ao[k], 1 - u),\n ]),\n );\n }\n return u < 0.5 ? a : b;\n}\n\n/**\n * The data to show at `timeMs`, for media whose data has a state per step:\n * `states[n]` is shown from step n (the last one stays), reached by moving\n * from the state before it over `ms`.\n */\nexport function stepData<D>(\n states: readonly D[],\n steps: readonly number[],\n timeMs: number,\n options: { ms?: number; ease?: SvgEase; keyOf?: DataKey } = {},\n): D {\n const last = Math.min(steps.length, states.length - 1);\n const to = states[last]!;\n if (last === 0) return to;\n const u = stepProgress(steps, timeMs, last, options);\n return lerpData(states[last - 1]!, to, u, options.keyOf);\n}\n\n// ── SVG media ──────────────────────────────────────────────────────────\n\n/**\n * An animated SVG picture: markup plus changes to its elements. Draw it with\n * `SvgPlayer` (or `svgView`), or compute frames yourself with `svgFrame`.\n */\nexport interface SvgMotion {\n /** One self-contained `<svg>` with a `viewBox`: no scripts, no outside links. */\n svg: string;\n /** Changes to its elements, each on a step. */\n animate?: SvgAnimation[];\n}\n\n/** A box in an SVG's `viewBox` units: `[x, y, width, height]`. */\nexport type SvgBox = readonly [number, number, number, number];\n\n/** A change to one element of an {@link SvgMotion}, or (with `view`) to the whole picture. */\nexport interface SvgAnimation {\n /** The element's `id` in the SVG (not needed for `view`). */\n id?: string;\n /** The step it plays on: 0 (default) when the media starts, 1 with the next shot, and so on. */\n step?: number;\n /** Ms after the step starts. */\n delay?: number;\n /** How long it takes, in ms (default {@link STEP_MS}). */\n ms?: number;\n /** A name in {@link EASES} (default `\"in-out\"`) or a `[x1, y1, x2, y2]` cubic-bezier curve. */\n ease?: SvgEase;\n /**\n * Attributes from one value to another: numbers, colours (`#rrggbb`), or\n * strings whose numbers change while the rest stays the same (a path's\n * `d`, a `transform`, `points`).\n */\n attrs?: Record<string, readonly [string | number, string | number]>;\n /** Draws a line or outline on along its length, from 0 to 1 (or between two fractions). */\n draw?: boolean | readonly [number, number];\n /**\n * Zooms and pans the whole picture to frame a box (`[x, y, width, height]`\n * in the `viewBox`'s units) or an element by id (with a margin round it),\n * from where the last `view` left it (at first, the whole `viewBox`).\n */\n view?: SvgBox | string;\n /**\n * Moves the element along a path (by id) from its start to its end, or\n * between the fractions in `at`; draw the element round (0, 0), like a\n * circle at `cx=\"0\" cy=\"0\"`.\n */\n along?: string;\n /** How far along the path `along` moves the element, from and to (default [0, 1]). */\n at?: readonly [number, number];\n /**\n * Sets the active child index in a solo container (data-solo group or element with multiple children).\n * Hides all siblings except the one at this index (0-based).\n */\n solo?: number;\n /** Counts the element's text from one number to the other. */\n count?: readonly [number, number];\n /** How a count is written: `{n}` stands for the number (\"{n}%\", \"$ {n}M\"). */\n format?: string;\n /** Decimals in a count (default 0). */\n decimals?: number;\n /**\n * Writes this text into the element letter by letter: none of it when the\n * change starts, all of it when it ends (a typewriter).\n */\n write?: string;\n /**\n * With `write`: letters not yet written show characters picked from this\n * string, changing every {@link SCRAMBLE_MS} ms, so the text decodes\n * rather than types. The same time always picks the same characters.\n */\n scramble?: string;\n /** With `write`: shown after the written letters while it writes (\"▌\", \"|\"). */\n caret?: string;\n}\n\n/** How often scrambled letters change, in ms (see `SvgAnimation.scramble`). */\nexport const SCRAMBLE_MS = 50;\n\n/**\n * `text` with `u` (0–1) of its letters written (see `SvgAnimation.write`):\n * the rest scrambled from `scramble` (picked by `timeMs`) or left off, then\n * the caret while it is unfinished. Letters are code points, so emoji and\n * accents are never split.\n */\nexport function writtenText(\n text: string,\n u: number,\n options: { scramble?: string; caret?: string; timeMs?: number } = {},\n): string {\n const letters = Array.from(text);\n const shown = Math.round(clamp01(u) * letters.length);\n let out = letters.slice(0, shown).join(\"\");\n const pool = Array.from(options.scramble ?? \"\");\n if (pool.length) {\n const tick = Math.floor((options.timeMs ?? 0) / SCRAMBLE_MS);\n for (let i = shown; i < letters.length; i++)\n out += /\\s/.test(letters[i]!) ? letters[i] : pool[Math.floor(noise(i, tick) * pool.length)];\n }\n return shown < letters.length && options.caret ? out + options.caret : out;\n}\n\n/** A repeatable 0–1 number for a letter at a tick. */\nfunction noise(i: number, tick: number): number {\n const x = Math.sin(i * 127.1 + tick * 311.7) * 43758.5453;\n return x - Math.floor(x);\n}\n\n/** What one element of an animated SVG shows at a time. */\nexport interface SvgElementFrame {\n attrs: Record<string, string>;\n /** How much of its length is drawn, 0–1. */\n draw?: number;\n text?: string;\n /** Active child index when targeting a solo container. */\n solo?: number;\n /** Where it is along a path: the path's id and the fraction of its length. */\n along?: { path: string; at: number };\n /**\n * The whole picture's framing (on the frame for {@link SVG_PICTURE}): `u`\n * of the way from one view to the next, `null` being the whole `viewBox`.\n */\n view?: { from: SvgBox | string | null; to: SvgBox | string; u: number };\n}\n\n/** The key of the whole picture's frame in {@link svgFrame}'s result (for `view`). */\nexport const SVG_PICTURE = \"\";\n\nconst NUMBER = /-?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[-+]?\\d+)?/gi;\nconst HEX = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;\n\nfunction rgb(hex: string): [number, number, number] {\n let h = hex.slice(1);\n if (h.length === 3) h = [...h].map((c) => c + c).join(\"\");\n return [0, 2, 4].map((i) => parseInt(h.slice(i, i + 2), 16)) as [number, number, number];\n}\n\nconst round = (n: number) => Math.round(n * 1000) / 1000;\n\n/** A value `u` of the way between two attribute values (see `SvgAnimation.attrs`). */\nexport function lerpAttr(a: string | number, b: string | number, u: number): string {\n if (typeof a === \"number\" && typeof b === \"number\") return String(round(a + (b - a) * u));\n const sa = String(a);\n const sb = String(b);\n if (HEX.test(sa) && HEX.test(sb)) {\n const [ca, cb] = [rgb(sa), rgb(sb)];\n return `#${ca\n .map((c, i) =>\n Math.round(c + (cb[i]! - c) * u)\n .toString(16)\n .padStart(2, \"0\"),\n )\n .join(\"\")}`;\n }\n const na = sa.match(NUMBER) ?? [];\n const nb = sb.match(NUMBER) ?? [];\n if (na.length && na.length === nb.length && sa.replace(NUMBER, \"#\") === sb.replace(NUMBER, \"#\")) {\n let i = 0;\n return sa.replace(NUMBER, () => {\n const v = Number(na[i]) + (Number(nb[i]) - Number(na[i])) * u;\n i++;\n return String(round(v));\n });\n }\n return u < 0.5 ? sa : sb;\n}\n\n/** Formats a number for a count animation (`{n}` stands for the rounded number). */\nexport function formatCount(\n value: number,\n options: { decimals?: number; format?: string } = {},\n): string {\n const n = value.toFixed(options.decimals ?? 0);\n return (options.format ?? \"{n}\").replace(\"{n}\", n);\n}\n\nconst startOf = (a: SvgAnimation, steps: readonly number[]) => {\n const s = stepStart(steps, a.step ?? 0);\n return s === undefined ? Infinity : s + (a.delay ?? 0);\n};\n\n/**\n * What each animated element shows at `timeMs`. For each attribute (or\n * line, count or writing) the latest change to have started wins; before the first\n * one starts, the element shows that change's starting value, so something\n * that grows in later is hidden until then.\n */\nexport function svgFrame(\n animations: readonly SvgAnimation[],\n steps: readonly number[],\n timeMs: number,\n): Map<string, SvgElementFrame> {\n // Each property's changes in the order they start (ties: list order).\n const tracks = new Map<string, { anim: SvgAnimation; start: number; index: number }[]>();\n const add = (prop: string, anim: SvgAnimation, index: number) => {\n const key = `${prop === \"view\" ? SVG_PICTURE : anim.id}\\u0000${prop}`;\n const list = tracks.get(key) ?? [];\n list.push({ anim, start: startOf(anim, steps), index });\n tracks.set(key, list);\n };\n animations.forEach((a, i) => {\n for (const name of Object.keys(a.attrs ?? {})) add(`@${name}`, a, i);\n if (a.draw) add(\"draw\", a, i);\n if (a.count) add(\"count\", a, i);\n if (a.write !== undefined) add(\"count\", a, i);\n if (a.solo !== undefined) add(\"solo\", a, i);\n if (a.view !== undefined) add(\"view\", a, i);\n if (a.along) add(\"along\", a, i);\n });\n const frames = new Map<string, SvgElementFrame>();\n for (const [key, list] of tracks) {\n list.sort((x, y) => x.start - y.start || x.index - y.index);\n const [id, prop] = key.split(\"\\u0000\") as [string, string];\n const started = list.filter((c) => c.start <= timeMs);\n const current = started[started.length - 1];\n const anim = (current ?? list[0]!).anim;\n const u = current\n ? stepProgress(steps, timeMs, anim.step ?? 0, {\n delay: anim.delay,\n ms: anim.ms,\n ease: anim.ease,\n })\n : 0;\n const frame = frames.get(id) ?? { attrs: {} };\n if (prop === \"view\") {\n // From where the change before it left the picture.\n const before = current ? list[list.indexOf(current) - 1] : undefined;\n frame.view = { from: before?.anim.view ?? null, to: anim.view!, u };\n } else if (prop === \"along\") {\n const [a, b] = anim.at ?? [0, 1];\n frame.along = { path: anim.along!, at: a + (b - a) * u };\n } else if (prop === \"solo\") {\n frame.solo = anim.solo;\n } else if (prop.startsWith(\"@\")) {\n const [a, b] = anim.attrs![prop.slice(1)]!;\n frame.attrs[prop.slice(1)] = lerpAttr(a, b, u);\n } else if (prop === \"draw\") {\n const [a, b] = anim.draw === true ? [0, 1] : (anim.draw as readonly [number, number]);\n frame.draw = a + (b - a) * u;\n } else if (anim.write !== undefined) {\n frame.text = writtenText(anim.write, u, { scramble: anim.scramble, caret: anim.caret, timeMs });\n } else {\n const [a, b] = anim.count!;\n frame.text = formatCount(a + (b - a) * u, anim);\n }\n frames.set(id, frame);\n }\n return frames;\n}\n\n/**\n * The opening tag of the root element at the start of `markup` (up to its\n * first `>`), cut out without a regular expression, so checks on it stay\n * linear however long or odd the markup is.\n */\nexport function svgOpeningTag(markup: string): string {\n const end = markup.indexOf(\">\");\n return end < 0 ? markup : markup.slice(0, end + 1);\n}\n\n/** Problems with an {@link SvgMotion}, as sentences; none when it can be drawn. */\nexport function svgMotionIssues(motion: unknown): string[] {\n const issues: string[] = [];\n const m = (motion ?? {}) as Partial<SvgMotion>;\n const svg = typeof m.svg === \"string\" ? m.svg.trim() : \"\";\n if (!svg) return [\"`svg` needs the picture's markup: one <svg> element\"];\n if (!/^<svg[\\s>]/i.test(svg) || !svg.toLowerCase().endsWith(\"</svg>\"))\n issues.push(\"`svg` must be one <svg>…</svg> element\");\n if (!/\\sviewBox\\s*=/i.test(svgOpeningTag(svg)))\n issues.push(\"the <svg> needs a `viewBox`, so it scales to where it is placed\");\n if (/<script|<foreignObject|\\son\\w+\\s*=/i.test(svg))\n issues.push(\"`svg` cannot have scripts, event handlers or <foreignObject>\");\n if (/<(animate|animateTransform|animateMotion|set)[\\s/>]/i.test(svg))\n issues.push(\n \"`svg` cannot animate itself (<animate>, <animateTransform>, <animateMotion>, <set>): give changes in `animate`, so every frame is a function of time\",\n );\n if (/(?:href|src)\\s*=\\s*[\"'](?!#|data:image\\/)/i.test(svg))\n issues.push(\"`svg` cannot link outside itself (only #ids and data:image URLs)\");\n const ids = new Set([...svg.matchAll(/\\sid\\s*=\\s*[\"']([^\"']+)[\"']/g)].map((x) => x[1]));\n if (m.animate !== undefined && !Array.isArray(m.animate)) issues.push(\"`animate` must be a list\");\n (Array.isArray(m.animate) ? m.animate : []).forEach((a, i) => {\n const where = `animate[${i}]`;\n if (!a || typeof a !== \"object\") return void issues.push(`${where} is not an animation`);\n if (typeof a.id !== \"string\") {\n if (a.view === undefined) return void issues.push(`${where} needs an \\`id\\``);\n } else if (!ids.has(a.id))\n issues.push(`${where}: there is no element with id \"${a.id}\" in the SVG`);\n if (a.step !== undefined && !(Number.isInteger(a.step) && a.step >= 0))\n issues.push(`${where}: \\`step\\` is a whole number, 0 or more`);\n if (a.ms !== undefined && !(a.ms >= 0)) issues.push(`${where}: \\`ms\\` must be 0 or more`);\n if (a.delay !== undefined && !(a.delay >= 0))\n issues.push(`${where}: \\`delay\\` must be 0 or more`);\n if (a.ease !== undefined && !isSvgEase(a.ease))\n issues.push(`${where}: \\`ease\\` is one of ${Object.keys(EASES).join(\", \")}, or a cubic-bezier [x1, y1, x2, y2] with x1 and x2 from 0 to 1`);\n if (!a.attrs && !a.draw && !a.count && a.write === undefined && a.view === undefined && !a.along && a.solo === undefined)\n issues.push(\n `${where} changes nothing: give \\`attrs\\`, \\`draw\\`, \\`count\\`, \\`write\\`, \\`view\\`, \\`along\\` or \\`solo\\``,\n );\n if (a.solo !== undefined && !(Number.isInteger(a.solo) && a.solo >= 0))\n issues.push(`${where}: \\`solo\\` is an index (whole number, 0 or more)`);\n if (a.view !== undefined) {\n const box = a.view as unknown;\n if (typeof box === \"string\") {\n if (!ids.has(box))\n issues.push(`${where}: \\`view\\` frames \"${box}\", which is not an id in the SVG`);\n } else if (\n !Array.isArray(box) ||\n box.length !== 4 ||\n !box.every((n) => Number.isFinite(n)) ||\n !(box[2] > 0 && box[3] > 0)\n )\n issues.push(\n `${where}: \\`view\\` is [x, y, width, height] (width and height above 0) or an element's id`,\n );\n }\n if (a.along !== undefined) {\n if (typeof a.along !== \"string\" || !ids.has(a.along))\n issues.push(`${where}: \\`along\\` is the id of a path in the SVG`);\n if (typeof a.id !== \"string\")\n issues.push(`${where}: \\`along\\` moves an element: give its \\`id\\``);\n }\n if (\n a.at !== undefined &&\n !(Array.isArray(a.at) && a.at.length === 2 && a.at.every((v) => v >= 0 && v <= 1))\n )\n issues.push(`${where}: \\`at\\` is [from, to] between 0 and 1`);\n for (const [name, pair] of Object.entries(a.attrs ?? {}))\n if (!Array.isArray(pair) || pair.length !== 2)\n issues.push(`${where}: \\`attrs.${name}\\` is [from, to]`);\n if (Array.isArray(a.draw) && a.draw.some((v) => !(v >= 0 && v <= 1)))\n issues.push(`${where}: \\`draw\\` is true or [from, to] between 0 and 1`);\n if (a.count !== undefined && !(Array.isArray(a.count) && a.count.length === 2))\n issues.push(`${where}: \\`count\\` is [from, to]`);\n if (a.write !== undefined && typeof a.write !== \"string\")\n issues.push(`${where}: \\`write\\` is the text to write`);\n if ((a.scramble !== undefined || a.caret !== undefined) && a.write === undefined)\n issues.push(`${where}: \\`scramble\\` and \\`caret\\` go with \\`write\\``);\n });\n return issues;\n}\n"],"mappings":"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","names":[]}
@@ -8,14 +8,14 @@ import {
8
8
  } from "./chunk-Z5EETGR4.js";
9
9
  import {
10
10
  svgAnimatedMarkup
11
- } from "./chunk-N5HXMQOK.js";
11
+ } from "./chunk-OIRDNPMD.js";
12
12
  import {
13
13
  svgFrameMarkup,
14
14
  svgViewBox
15
- } from "./chunk-MOLJPWME.js";
15
+ } from "./chunk-G5M777AN.js";
16
16
  import {
17
17
  subjectValues
18
- } from "./chunk-2O3RMSOE.js";
18
+ } from "./chunk-XFTSWPSX.js";
19
19
  import {
20
20
  wrapSource
21
21
  } from "./chunk-HDYBY3PQ.js";
@@ -28,14 +28,14 @@ import {
28
28
  effectInputs,
29
29
  getEffect,
30
30
  renderVectorEffect
31
- } from "./chunk-IHUNCBMF.js";
31
+ } from "./chunk-Z3LKEODP.js";
32
32
  import {
33
33
  checkControlValue,
34
34
  parseColor
35
35
  } from "./chunk-VYOMXE6I.js";
36
36
  import {
37
37
  svgDuration
38
- } from "./chunk-JETRHCP3.js";
38
+ } from "./chunk-XAQ5FWKS.js";
39
39
 
40
40
  // src/export/effect.ts
41
41
  import { spawn } from "child_process";
@@ -411,4 +411,4 @@ export {
411
411
  effectQueryFromFlags,
412
412
  describeEffect
413
413
  };
414
- //# sourceMappingURL=chunk-O5QKC2L7.js.map
414
+ //# sourceMappingURL=chunk-D4GVMDHE.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  svgDuration
3
- } from "./chunk-JETRHCP3.js";
3
+ } from "./chunk-XAQ5FWKS.js";
4
4
  import {
5
5
  SVG_PICTURE,
6
6
  svgFrame
7
- } from "./chunk-VKIDRHBG.js";
7
+ } from "./chunk-6B62CBTP.js";
8
8
 
9
9
  // src/vector/static.ts
10
10
  var DROPPED = /* @__PURE__ */ new Set(["script", "foreignobject", "iframe", "object", "embed"]);
@@ -155,4 +155,4 @@ export {
155
155
  svgFrameMarkup,
156
156
  svgFrameTree
157
157
  };
158
- //# sourceMappingURL=chunk-MOLJPWME.js.map
158
+ //# sourceMappingURL=chunk-G5M777AN.js.map
@@ -3,21 +3,34 @@ import {
3
3
  serialize,
4
4
  setAttr,
5
5
  svgFrameTree
6
- } from "./chunk-MOLJPWME.js";
6
+ } from "./chunk-G5M777AN.js";
7
7
  import {
8
8
  svgDuration
9
- } from "./chunk-JETRHCP3.js";
9
+ } from "./chunk-XAQ5FWKS.js";
10
10
  import {
11
11
  STEP_MS,
12
12
  SVG_PICTURE,
13
+ easeFunction,
13
14
  pathPointAt,
14
15
  stepStart,
15
16
  svgFrame
16
- } from "./chunk-VKIDRHBG.js";
17
+ } from "./chunk-6B62CBTP.js";
17
18
 
18
19
  // src/vector/animated.ts
19
20
  var SPLINES = { linear: "0 0 1 1", in: "0.3333 0 0.6667 0", out: "0.3333 1 0.6667 1" };
20
21
  var HALFWAY = { linear: 0.5, "in-out": 0.5, out: 1 - 0.5 ** (1 / 3) };
22
+ function halfway(ease) {
23
+ if (typeof ease === "string") return HALFWAY[ease];
24
+ const f = easeFunction(ease);
25
+ let [lo, hi] = [0, 1];
26
+ for (let i = 0; i < 40; i++) {
27
+ const mid = (lo + hi) / 2;
28
+ if (f(mid) < 0.5) lo = mid;
29
+ else hi = mid;
30
+ }
31
+ return hi;
32
+ }
33
+ var splineOf = (shape) => typeof shape === "string" ? SPLINES[shape] : shape.map((n) => String(+n.toFixed(4))).join(" ");
21
34
  var NUMBER = /-?(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?/gi;
22
35
  var HEX = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;
23
36
  var TRANSFORMS = /* @__PURE__ */ new Set(["transform", "gradienttransform", "patterntransform"]);
@@ -93,7 +106,7 @@ function timing(keys, loop, repeat, discrete = false) {
93
106
  ...clock(loop, repeat),
94
107
  keyTimes: keys.map((k) => String(+(k.t / loop).toFixed(5))).join(";"),
95
108
  calcMode: discrete ? "discrete" : spline ? "spline" : "linear",
96
- keySplines: spline ? keys.slice(1).map((k) => SPLINES[k.shape]).join(";") : void 0
109
+ keySplines: spline ? keys.slice(1).map((k) => splineOf(k.shape)).join(";") : void 0
97
110
  };
98
111
  }
99
112
  var clock = (loop, repeat) => ({
@@ -181,12 +194,14 @@ function svgAnimatedMarkup(motion, options = {}) {
181
194
  const ease = c.anim.ease ?? "in-out";
182
195
  const pair = prop.startsWith("@") ? c.anim.attrs[prop.slice(1)] : void 0;
183
196
  if (pair && !blends(pair[0], pair[1])) {
184
- const at = c.start + ms * HALFWAY[ease];
197
+ const at = c.start + ms * halfway(ease);
185
198
  if (at < next) {
186
199
  push(at, value(k, c.start));
187
200
  push(at, value(k, end));
188
201
  }
189
- } else if (!sampled && end === c.start + ms && ease !== "linear") {
202
+ } else if (!sampled && end === c.start + ms && typeof ease !== "string" && ease.every((n) => n >= 0 && n <= 1)) {
203
+ push(end, value(k, end), ease);
204
+ } else if (!sampled && end === c.start + ms && ease !== "linear" && typeof ease === "string") {
190
205
  if (ease === "in-out") push(c.start + ms / 2, value(k, c.start + ms / 2), "in");
191
206
  push(end, value(k, end), "out");
192
207
  } else if (!sampled && ease === "linear") push(end, value(k, end));
@@ -404,4 +419,4 @@ function scopeIds(svg, suffix) {
404
419
  export {
405
420
  svgAnimatedMarkup
406
421
  };
407
- //# sourceMappingURL=chunk-N5HXMQOK.js.map
422
+ //# sourceMappingURL=chunk-OIRDNPMD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/vector/animated.ts"],"sourcesContent":["/**\n * An {@link SvgMotion} as one self-contained animated `.svg` file, with no\n * DOM and no script: its changes written as SMIL (`<animate>`,\n * `<animateTransform>`, `<animateMotion>`), so it plays on its own wherever\n * an SVG image does (an `<img src>`, a file opened directly, inline markup).\n */\n\nimport { pathPointAt } from \"./morph.js\";\nimport {\n STEP_MS,\n SVG_PICTURE,\n stepStart,\n easeFunction,\n svgFrame,\n type CubicBezier,\n type EaseName,\n type SvgAnimation,\n type SvgEase,\n type SvgBox,\n type SvgElementFrame,\n type SvgMotion,\n} from \"./motion.js\";\nimport { getAttr, serialize, setAttr, svgFrameTree, type SvgNode } from \"./static.js\";\nimport { svgDuration } from \"./svg.js\";\n\nexport interface AnimatedSvgOptions {\n /** Loop length in ms (default: `svgDuration(motion, steps)` + `hold`). */\n duration?: number;\n /** Ms to rest on the last frame before looping (default 600, like `SvgPlayer`). */\n hold?: number;\n /** Loop forever (default true); false plays once and holds the last frame. */\n loop?: boolean;\n /** Step start times in ms, for pictures that change on steps (like `SvgPlayer`'s `steps`). */\n steps?: readonly number[];\n /**\n * Samples per second for what cannot be written exactly (counts, written\n * text, a change cut short by the next, a `matrix` transform); default 30.\n */\n fps?: number;\n /**\n * Added to the ids the picture refers to (its gradients, filters, clips,\n * paths followed), so two files inlined in one page each use their own.\n * Default: a hash of the motion, so the same motion gives the same file;\n * `\"\"` keeps ids as written.\n */\n idSuffix?: string;\n}\n\n/**\n * How a value gets to a keyframe from the one before: the shapes `EASES` are\n * made of, or a cubic-bezier curve written as it is.\n */\ntype Shape = \"linear\" | \"in\" | \"out\" | CubicBezier;\n\n/** A channel's value at a time, reached from the keyframe before along `shape`. */\ninterface Key {\n t: number;\n v: string;\n shape: Shape;\n}\n\n/** One change to a channel, when it starts. */\ninterface Change {\n anim: SvgAnimation;\n start: number;\n}\n\n/**\n * Cubic Bézier timing for each shape. `out` (1 − (1 − t)³) is exactly the\n * curve (0, 1, 1, 1), and `in-out` is `in` (t³, the curve (0, 0, 0, 1)) to\n * its middle then `out`, so eases are written exactly, not sampled.\n */\nconst SPLINES: Record<Extract<Shape, string>, string> = { linear: \"0 0 1 1\", in: \"0.3333 0 0.6667 0\", out: \"0.3333 1 0.6667 1\" };\n\n/** When a named ease is halfway (where a value that cannot blend switches), as a share of its time. */\nconst HALFWAY: Record<EaseName, number> = { linear: 0.5, \"in-out\": 0.5, out: 1 - 0.5 ** (1 / 3) };\n\n/** When an ease is first halfway, as a share of its time. */\nfunction halfway(ease: SvgEase): number {\n if (typeof ease === \"string\") return HALFWAY[ease];\n const f = easeFunction(ease);\n let [lo, hi] = [0, 1];\n for (let i = 0; i < 40; i++) {\n const mid = (lo + hi) / 2;\n if (f(mid) < 0.5) lo = mid;\n else hi = mid;\n }\n return hi;\n}\n\n/** SMIL key splines: a shape's control points, written as given. */\nconst splineOf = (shape: Shape) => (typeof shape === \"string\" ? SPLINES[shape] : shape.map((n) => String(+n.toFixed(4))).join(\" \"));\n\nconst NUMBER = /-?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[-+]?\\d+)?/gi;\nconst HEX = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;\nconst TRANSFORMS = new Set([\"transform\", \"gradienttransform\", \"patterntransform\"]);\nconst URL_REF = /url\\(\\s*(['\"]?)#([^'\")\\s]+)\\1\\s*\\)/g;\n\n/** Whether `lerpAttr` blends two values (else it switches halfway), so SMIL can interpolate them. */\nfunction blends(a: string | number, b: string | number): boolean {\n if (typeof a === \"number\" && typeof b === \"number\") return true;\n const [sa, sb] = [String(a), String(b)];\n if (HEX.test(sa) && HEX.test(sb)) return true;\n const na = sa.match(NUMBER) ?? [];\n return na.length > 0 && na.length === (sb.match(NUMBER) ?? []).length && sa.replace(NUMBER, \"#\") === sb.replace(NUMBER, \"#\");\n}\n\nconst num = (n: number) => String(+n.toFixed(3));\n\n/** A short, stable hash of a string, for default id suffixes. */\nfunction hash(s: string): string {\n let h = 0x811c9dc5;\n for (let i = 0; i < s.length; i++) h = Math.imul(h ^ s.charCodeAt(i), 0x01000193);\n return (h >>> 0).toString(36);\n}\n\n/** An element: `<tag attrs/>`. */\nconst node = (tag: string, attrs: Record<string, string | undefined>, children: SvgNode[\"children\"] = []): SvgNode => ({\n tag,\n attrs: Object.entries(attrs).filter((e): e is [string, string] => e[1] !== undefined),\n children,\n});\n\n/**\n * The transform functions in a `transform` value, with their arguments:\n * `translate(10 20) rotate(45)` → [[\"translate\", [10, 20]], [\"rotate\", [45]]].\n */\nfunction transformList(value: string): [string, number[]][] {\n return [...value.matchAll(/([a-z]+)\\s*\\(([^)]*)\\)/gi)].map((m) => [m[1]!, (m[2]!.match(NUMBER) ?? []).map(Number)]);\n}\n\n/** A transform list as one matrix [a b c d e f]. */\nfunction transformMatrix(value: string): number[] {\n let m = [1, 0, 0, 1, 0, 0];\n const times = (n: number[]) => {\n const [a, b, c, d, e, f] = m as [number, number, number, number, number, number];\n m = [a * n[0]! + c * n[1]!, b * n[0]! + d * n[1]!, a * n[2]! + c * n[3]!, b * n[2]! + d * n[3]!, a * n[4]! + c * n[5]! + e, b * n[4]! + d * n[5]! + f];\n };\n const rad = Math.PI / 180;\n for (const [name, [p = 0, q, r = 0, s = 0, t = 0, u = 0]] of transformList(value)) {\n if (name === \"translate\") times([1, 0, 0, 1, p, q ?? 0]);\n else if (name === \"scale\") times([p, 0, 0, q ?? p, 0, 0]);\n else if (name === \"rotate\") {\n const [cos, sin] = [Math.cos(p * rad), Math.sin(p * rad)];\n const [cx, cy] = [q ?? 0, r];\n times([1, 0, 0, 1, cx, cy]);\n times([cos, sin, -sin, cos, 0, 0]);\n times([1, 0, 0, 1, -cx, -cy]);\n } else if (name === \"skewX\") times([1, 0, Math.tan(p * rad), 1, 0, 0]);\n else if (name === \"skewY\") times([1, Math.tan(p * rad), 0, 1, 0, 0]);\n else if (name === \"matrix\") times([p, q ?? 0, r, s, t, u]);\n }\n return m;\n}\n\n/** A matrix as translate · rotate · skewX · scale (degrees), the order SMIL can add them in. */\nfunction decompose([a, b, c, d, e, f]: number[]): [number, number, number, number, number, number] {\n const sx = Math.hypot(a!, b!);\n const angle = sx ? Math.atan2(b!, a!) : 0;\n const [cos, sin] = [Math.cos(angle), Math.sin(angle)];\n const sy = -sin * c! + cos * d!;\n const skew = sy ? Math.atan((cos * c! + sin * d!) / sy) : 0;\n return [e!, f!, (angle * 180) / Math.PI, (skew * 180) / Math.PI, sx, sy];\n}\n\n/** A shape's outline as a path `d`, for following it with `along`. */\nfunction outline(el: SvgNode): string | undefined {\n const at = (name: string) => Number(getAttr(el, name) ?? 0);\n switch (el.tag.toLowerCase()) {\n case \"path\":\n return getAttr(el, \"d\");\n case \"line\":\n return `M${at(\"x1\")} ${at(\"y1\")}L${at(\"x2\")} ${at(\"y2\")}`;\n case \"polyline\":\n case \"polygon\":\n return `M${getAttr(el, \"points\") ?? \"\"}${el.tag.toLowerCase() === \"polygon\" ? \"Z\" : \"\"}`;\n default:\n return undefined;\n }\n}\n\n/**\n * The timing attributes that play `keys` over the loop: `keyTimes` and,\n * where a key eases in, `keySplines`. Keys at the same time are a jump.\n */\nfunction timing(keys: readonly Key[], loop: number, repeat: boolean, discrete = false): Record<string, string | undefined> {\n const spline = !discrete && keys.some((k, i) => i > 0 && k.shape !== \"linear\");\n return {\n ...clock(loop, repeat),\n keyTimes: keys.map((k) => String(+(k.t / loop).toFixed(5))).join(\";\"),\n calcMode: discrete ? \"discrete\" : spline ? \"spline\" : \"linear\",\n keySplines: spline ? keys.slice(1).map((k) => splineOf(k.shape)).join(\";\") : undefined,\n };\n}\n\n/** How long an animation runs, and whether it repeats or holds its end. */\nconst clock = (loop: number, repeat: boolean) => ({\n dur: `${+(loop / 1000).toFixed(4)}s`,\n repeatCount: repeat ? \"indefinite\" : undefined,\n fill: repeat ? undefined : \"freeze\",\n});\n\n/** Keys with their repeats dropped: a key between two of the same value, or a copy of the one before. */\nfunction collapse(keys: Key[]): Key[] {\n const out: Key[] = [];\n keys.forEach((k, i) => {\n const prev = out[out.length - 1];\n if (prev && prev.v === k.v && (prev.t === k.t || (keys[i + 1]?.v === k.v && i < keys.length - 1))) return;\n out.push(k);\n });\n return out;\n}\n\n/** Keys reduced to where the value changes, for a discrete animation (the last at a time wins). */\nfunction runs(keys: readonly Key[]): Key[] {\n const out: Key[] = [];\n for (const k of keys) {\n const prev = out[out.length - 1];\n if (prev?.t === k.t) out.pop();\n if (out[out.length - 1]?.v !== k.v) out.push(k);\n }\n return out;\n}\n\n/**\n * The {@link SvgMotion} as one animated SVG file that plays and loops on its\n * own, as `SvgPlayer` plays it, with no script: save it as `.svg`, put it in\n * an `<img src>`, or inline it. Each element starts as the motion's first\n * frame, so it still shows that where SMIL does not run.\n *\n * Attribute changes become one `<animate>` per attribute (`<animateTransform>`\n * per function of a `transform`), with the eases written exactly as splines;\n * `draw` animates `stroke-dashoffset`; `along` becomes `<animateMotion>` on\n * the path; `view` animates the root `viewBox` (keeping `data-fixed` and\n * `data-nonscaling` elements as the player does); `solo` toggles `display`.\n * Counts and written text are sampled at `fps`, each text shown in its own\n * `<tspan>` in turn.\n *\n * Limits: a `view` that frames an element by id stays where it is (it needs\n * layout, as in `svgFrameMarkup`); `style` and other attributes SMIL cannot\n * interpolate change in steps; ids are suffixed only where the picture\n * refers to them (CSS `#id` selectors in a `<style>` are left as written).\n * Undefined when `motion.svg` is not an `<svg>`.\n */\nexport function svgAnimatedMarkup(motion: SvgMotion, options: AnimatedSvgOptions = {}): string | undefined {\n const steps = options.steps ?? [];\n const repeat = options.loop ?? true;\n const fps = options.fps ?? 30;\n const loop = Math.max(1, options.duration ?? svgDuration(motion, steps) + (options.hold ?? 600));\n const animations = motion.animate ?? [];\n const tree = svgFrameTree(motion, steps, 0);\n if (!tree) return undefined;\n const { svg, byId, whole } = tree;\n\n // Each property's changes in the order they start, as `svgFrame` keeps them.\n const tracks = new Map<string, Change[]>();\n animations.forEach((anim) => {\n const s = stepStart(steps, anim.step ?? 0);\n const start = s === undefined ? Infinity : s + (anim.delay ?? 0);\n const add = (prop: string) => {\n const key = `${prop === \"view\" ? SVG_PICTURE : anim.id}\\u0000${prop}`;\n tracks.set(key, [...(tracks.get(key) ?? []), { anim, start }]);\n };\n for (const name of Object.keys(anim.attrs ?? {})) add(`@${name}`);\n if (anim.draw) add(\"draw\");\n if (anim.count || anim.write !== undefined) add(\"text\");\n if (anim.solo !== undefined) add(\"solo\");\n if (anim.view !== undefined) add(\"view\");\n if (anim.along) add(\"along\");\n });\n for (const list of tracks.values()) list.sort((x, y) => x.start - y.start);\n\n const frames = new Map<number, Map<string, SvgElementFrame>>();\n const frameAt = (t: number) => {\n let f = frames.get(t);\n if (!f) frames.set(t, (f = svgFrame(animations, steps, t)));\n return f;\n };\n const boxOf = (v: SvgBox | string | null) => (v === null ? whole : typeof v === \"string\" ? undefined : v);\n /** A channel's value in a frame, as written into the file. */\n const read = (frame: Map<string, SvgElementFrame>, id: string, prop: string): string | undefined => {\n const f = frame.get(id);\n if (!f) return undefined;\n if (prop.startsWith(\"@\")) return f.attrs[prop.slice(1)];\n if (prop === \"draw\") return f.draw === undefined ? undefined : num(1 - f.draw);\n if (prop === \"along\") return f.along && num(f.along.at);\n if (prop === \"solo\") return f.solo === undefined ? undefined : String(f.solo);\n if (prop === \"text\") return f.text;\n if (!f.view) return undefined;\n const [a, b] = [boxOf(f.view.from), boxOf(f.view.to)];\n const box = a && b ? a.map((n, i) => n + (b[i]! - n) * f.view!.u) : (b ?? a ?? whole);\n return box?.map(num).join(\" \");\n };\n\n /**\n * A channel's keyframes over the loop: before its first change its start,\n * then each change from its start to its end (or the next change), eased\n * exactly or (with `sampled`, or when cut short) sampled at `fps`.\n */\n const keyframes = (id: string, prop: string, list: readonly Change[], sampled = false): Key[] => {\n const shown = list.filter((c, i) => c.start < loop && !(list[i + 1] && list[i + 1]!.start <= c.start));\n // A change alone (with the one before it, where a view starts) gives its own value at any time.\n const value = (k: number, t: number) =>\n read(svgFrame(shown.slice(Math.max(0, k - 1), k + 1).map((c) => c.anim), steps, t), id, prop) ?? \"\";\n const keys: Key[] = [];\n const push = (t: number, v: string, shape: Shape = \"linear\") => keys.push({ t, v, shape });\n if (!shown.length) return [];\n push(0, read(frameAt(0), id, prop) ?? value(0, 0));\n shown.forEach((c, k) => {\n const next = Math.min(shown[k + 1]?.start ?? loop, loop);\n const ms = c.anim.ms ?? STEP_MS;\n const end = Math.min(c.start + ms, next);\n // Held until it starts, where it may jump.\n push(c.start, keys[keys.length - 1]!.v);\n push(c.start, value(k, c.start));\n if (!(ms > 0)) return;\n const ease = c.anim.ease ?? \"in-out\";\n const pair = prop.startsWith(\"@\") ? c.anim.attrs![prop.slice(1)]! : undefined;\n if (pair && !blends(pair[0], pair[1])) {\n const at = c.start + ms * halfway(ease);\n if (at < next) {\n push(at, value(k, c.start));\n push(at, value(k, end));\n }\n } else if (!sampled && end === c.start + ms && typeof ease !== \"string\" && ease.every((n) => n >= 0 && n <= 1)) {\n // SMIL takes any curve whose control points stay within 0–1.\n push(end, value(k, end), ease);\n } else if (!sampled && end === c.start + ms && ease !== \"linear\" && typeof ease === \"string\") {\n if (ease === \"in-out\") push(c.start + ms / 2, value(k, c.start + ms / 2), \"in\");\n push(end, value(k, end), \"out\");\n } else if (!sampled && ease === \"linear\") push(end, value(k, end));\n else {\n for (let t = c.start + 1000 / fps; t < end; t += 1000 / fps) push(t, value(k, t));\n push(end, value(k, end));\n }\n });\n if (keys[keys.length - 1]!.t < loop) push(loop, keys[keys.length - 1]!.v);\n return collapse(keys);\n };\n\n /** Times to sample text at: every 1/fps, and wherever a change starts or ends. */\n const sampleTimes = (list: readonly Change[]) => {\n const times = new Set<number>();\n for (let t = 0; t < loop; t += 1000 / fps) times.add(+t.toFixed(3));\n for (const c of list)\n for (const t of [c.start, c.start + (c.anim.ms ?? STEP_MS)]) if (t < loop) times.add(t);\n return [...times].sort((a, b) => a - b);\n };\n\n // What to add to each element, appended once all are worked out (so a solo's children stay as written).\n const added = new Map<SvgNode, SvgNode[]>();\n const add = (el: SvgNode, ...anims: SvgNode[]) => added.set(el, [...(added.get(el) ?? []), ...anims]);\n const animate = (name: string, keys: readonly Key[], values = keys.map((k) => k.v), discrete = false) =>\n node(\"animate\", { attributeName: name, values: values.join(\";\"), ...timing(keys, loop, repeat, discrete) });\n const followers = new Set(animations.filter((a) => a.along).map((a) => a.id));\n let viewKeys: Key[] | undefined;\n\n for (const [key, list] of tracks) {\n const [id, prop] = key.split(\"\\u0000\") as [string, string];\n const el = id === SVG_PICTURE ? svg : byId.get(id);\n if (!el) continue;\n const name = prop.slice(1);\n if (prop === \"text\") {\n // One <tspan> per text it shows, each shown in its turn.\n const own = list.map((c) => c.anim);\n const text = (t: number) => read(svgFrame(own, steps, t), id, prop) ?? \"\";\n const shown: Key[] = [];\n let last = -1;\n for (const t of sampleTimes(list)) {\n const v = text(t);\n if (shown.length && v !== shown[shown.length - 1]!.v) {\n let [lo, hi] = [last, t];\n while (hi - lo > 0.5) {\n const mid = (lo + hi) / 2;\n if (text(mid) === shown[shown.length - 1]!.v) lo = mid;\n else hi = mid;\n }\n // One change between them is placed exactly; several (a fast count) change at the middle.\n shown.push({ t: text(hi) === v ? hi : (last + t) / 2, v, shape: \"linear\" });\n }\n if (v !== shown[shown.length - 1]?.v) shown.push({ t, v, shape: \"linear\" });\n last = t;\n }\n const texts = [...new Set(shown.map((k) => k.v))];\n el.children = texts.map((value, i) => {\n const keys = runs(shown.map((k) => ({ ...k, v: k.v === value ? \"inline\" : \"none\" })));\n const span = node(\"tspan\", { display: i === 0 ? undefined : \"none\" }, [value]);\n if (keys.length > 1) span.children.push(animate(\"display\", keys, undefined, true));\n return span;\n });\n continue;\n }\n if (prop.startsWith(\"@\") && TRANSFORMS.has(name.toLowerCase())) {\n if (followers.has(id) && name === \"transform\") continue;\n let keys = keyframes(id, prop, list);\n if (keys.length < 2) continue;\n const lists = keys.map((k) => transformList(k.v));\n const shape = (l: [string, number[]][]) => l.map(([f, args]) => `${f}${args.length}`).join(\" \");\n if (lists.every((l) => shape(l) === shape(lists[0]!)) && !/matrix|skewY/.test(shape(lists[0]!))) {\n // The same functions throughout: each animated on its own, added up in order.\n lists[0]!.forEach(([type], j) =>\n add(el, node(\"animateTransform\", {\n attributeName: name,\n type,\n additive: j ? \"sum\" : undefined,\n values: lists.map((l) => l[j]![1].map(num).join(\" \")).join(\";\"),\n ...timing(keys, loop, repeat),\n })),\n );\n } else {\n // Anything else as translate · rotate · skewX · scale, sampled, with the angle kept continuous.\n keys = keyframes(id, prop, list, true);\n const parts = keys.map((k) => decompose(transformMatrix(k.v)));\n parts.forEach((p, i) => {\n const before = parts[i - 1];\n if (before) p[2] += 360 * Math.round((before[2] - p[2]) / 360);\n });\n const types: [string, (p: number[]) => number[]][] = [\n [\"translate\", (p) => [p[0]!, p[1]!]],\n [\"rotate\", (p) => [p[2]!]],\n [\"skewX\", (p) => [p[3]!]],\n [\"scale\", (p) => [p[4]!, p[5]!]],\n ];\n types.forEach(([type, pick], j) =>\n add(el, node(\"animateTransform\", {\n attributeName: name,\n type,\n additive: j ? \"sum\" : undefined,\n values: parts.map((p) => pick(p).map(num).join(\" \")).join(\";\"),\n ...timing(keys, loop, repeat),\n })),\n );\n }\n continue;\n }\n if (prop === \"along\") {\n const paths = new Set(list.map((c) => c.anim.along!));\n const pathEl = byId.get([...paths][0]!);\n const d = pathEl && outline(pathEl);\n if (!d) continue;\n const point = (at: string) => pathPointAt(d, Number(at));\n const first = point(read(frameAt(0), id, prop) ?? \"0\");\n if (first) setAttr(el, \"transform\", `translate(${num(first[0])} ${num(first[1])})`);\n if (paths.size === 1 && pathEl.tag.toLowerCase() === \"path\") {\n // The browser follows the path itself: the markup's place (for no SMIL) set aside while it does.\n const keys = keyframes(id, prop, list);\n add(\n el,\n node(\"animateTransform\", { attributeName: \"transform\", type: \"translate\", values: \"0 0\", ...clock(loop, repeat) }),\n node(\"animateMotion\", { keyPoints: keys.map((k) => k.v).join(\";\"), ...timing(keys, loop, repeat) }, [\n node(\"mpath\", { href: `#${[...paths][0]}` }),\n ]),\n );\n } else {\n // Along several paths, or a shape SMIL cannot follow: its points, sampled.\n const keys = sampleTimes(list).map((t): Key => {\n const f = frameAt(t).get(id)?.along;\n const p = f && byId.get(f.path) && pathPointAt(outline(byId.get(f.path)!) ?? \"\", f.at);\n return { t, v: p ? `${num(p[0])} ${num(p[1])}` : \"0 0\", shape: \"linear\" };\n });\n keys.push({ t: loop, v: keys[keys.length - 1]!.v, shape: \"linear\" });\n const ks = collapse(keys);\n add(el, node(\"animateTransform\", { attributeName: \"transform\", type: \"translate\", values: ks.map((k) => k.v).join(\";\"), ...timing(ks, loop, repeat) }));\n }\n continue;\n }\n const keys = keyframes(id, prop, list);\n if (keys.length < 2) continue;\n if (prop === \"solo\") {\n const shown = runs(keys);\n let i = 0;\n for (const child of el.children) {\n if (typeof child === \"string\") continue;\n const index = String(i++);\n const toggles = runs(shown.map((k) => ({ ...k, v: k.v === index ? \"inline\" : \"none\" })));\n if (toggles.length > 1) add(child, animate(\"display\", toggles, undefined, true));\n }\n } else if (prop === \"view\") {\n viewKeys = keys;\n add(svg, animate(\"viewBox\", keys));\n } else add(el, animate(prop === \"draw\" ? \"stroke-dashoffset\" : name, keys));\n }\n\n if (viewKeys && whole) {\n // As the view zooms, `data-nonscaling` elements keep their size and `data-fixed` ones their place.\n const boxes = viewKeys.map((k) => k.v.split(\" \").map(Number));\n const all: SvgNode[] = [];\n const walk = (n: SvgNode) => {\n all.push(n);\n for (const c of n.children) if (typeof c !== \"string\") walk(c);\n };\n walk(svg);\n const zooms = boxes.map((b) => num(b[2]! / whole[2]));\n for (const el of all.filter((n) => getAttr(n, \"data-nonscaling\") !== undefined)) {\n setAttr(el, \"transform\", zooms[0] === \"1\" ? undefined : `scale(${zooms[0]})`);\n add(el, node(\"animateTransform\", { attributeName: \"transform\", type: \"scale\", values: zooms.join(\";\"), ...timing(viewKeys, loop, repeat) }));\n }\n const fixed = all.filter((n) => getAttr(n, \"data-fixed\") !== undefined);\n const top = fixed.filter((n) => !fixed.some((f) => f !== n && contains(f, n)));\n if (top.length) {\n for (const el of top) for (const n of all) n.children = n.children.filter((c) => c !== el);\n // A layer that maps the whole picture onto the view as it moves (as a nested <svg> with the\n // whole viewBox would, but with transforms, which images animate where they do not re-lay out one).\n const fit = boxes.map(([x, y, w, h]) => {\n const k = Math.min(w! / whole[2], h! / whole[3]);\n return { at: `${num(x! + (w! - whole[2] * k) / 2 - whole[0] * k)} ${num(y! + (h! - whole[3] * k) / 2 - whole[1] * k)}`, k: num(k) };\n });\n const layer = node(\"g\", { transform: `translate(${fit[0]!.at}) scale(${fit[0]!.k})` }, top);\n add(\n layer,\n node(\"animateTransform\", { attributeName: \"transform\", type: \"translate\", values: fit.map((f) => f.at).join(\";\"), ...timing(viewKeys, loop, repeat) }),\n node(\"animateTransform\", { attributeName: \"transform\", type: \"scale\", additive: \"sum\", values: fit.map((f) => f.k).join(\";\"), ...timing(viewKeys, loop, repeat) }),\n );\n svg.children.push(layer);\n }\n }\n\n for (const [el, anims] of added) el.children.push(...anims);\n scopeIds(svg, options.idSuffix ?? hash(motion.svg + JSON.stringify(animations)));\n setAttr(svg, \"width\", \"100%\");\n setAttr(svg, \"height\", \"100%\");\n setAttr(svg, \"xmlns\", \"http://www.w3.org/2000/svg\");\n const markup = serialize(svg);\n // Read as XML (an image, a file), `xlink:` attributes need their namespace declared.\n return /\\sxlink:/.test(markup) && !/\\sxmlns:xlink=/.test(markup)\n ? markup.replace(/^<svg/, '<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\"')\n : markup;\n}\n\nconst contains = (outer: SvgNode, inner: SvgNode): boolean =>\n outer.children.some((c) => c === inner || (typeof c !== \"string\" && contains(c, inner)));\n\n/**\n * Gives the ids the picture refers to (by `url(#…)` or `href=\"#…\"`) `-suffix`,\n * and points the references at them, as a live player does.\n */\nfunction scopeIds(svg: SvgNode, suffix: string) {\n if (!suffix) return;\n const all: SvgNode[] = [];\n const walk = (n: SvgNode) => {\n all.push(n);\n for (const c of n.children) if (typeof c !== \"string\") walk(c);\n };\n walk(svg);\n const referred = new Set<string>();\n for (const n of all) {\n const css = n.tag.toLowerCase() === \"style\" ? n.children.filter((c): c is string => typeof c === \"string\") : [];\n for (const [name, value] of [...n.attrs, ...css.map((c) => [\"\", c] as const)]) {\n if (/^(xlink:)?href$/i.test(name) && value.startsWith(\"#\")) referred.add(value.slice(1));\n for (const m of value.matchAll(URL_REF)) referred.add(m[2]!);\n }\n }\n const ids = new Map<string, string>();\n for (const n of all) {\n const id = getAttr(n, \"id\");\n if (id && referred.has(id) && !ids.has(id)) ids.set(id, `${id}-${suffix}`);\n }\n if (!ids.size) return;\n const scoped = (value: string) =>\n value.replace(URL_REF, (whole, quote: string, id: string) => (ids.has(id) ? `url(${quote}#${ids.get(id)}${quote})` : whole));\n for (const n of all) {\n for (const attr of n.attrs) {\n if (attr[0] === \"id\") attr[1] = ids.get(attr[1]) ?? attr[1];\n else if (/^(xlink:)?href$/i.test(attr[0])) attr[1] = attr[1].startsWith(\"#\") && ids.has(attr[1].slice(1)) ? `#${ids.get(attr[1].slice(1))}` : attr[1];\n else attr[1] = scoped(attr[1]);\n }\n if (n.tag.toLowerCase() === \"style\") n.children = n.children.map((c) => (typeof c === \"string\" ? scoped(c) : c));\n }\n}\n"],"mappings":"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","names":["add","keys"]}
@@ -2,13 +2,13 @@ import {
2
2
  realClock
3
3
  } from "./chunk-WMZQCUFJ.js";
4
4
  import {
5
- EASES,
6
5
  STEP_MS,
7
6
  SVG_PICTURE,
7
+ easeFunction,
8
8
  formatCount,
9
9
  svgFrame,
10
10
  svgOpeningTag
11
- } from "./chunk-VKIDRHBG.js";
11
+ } from "./chunk-6B62CBTP.js";
12
12
 
13
13
  // src/vector/svg.ts
14
14
  var SVG_NS = "http://www.w3.org/2000/svg";
@@ -528,7 +528,7 @@ function animateCount(options) {
528
528
  const clock = options.clock ?? realClock;
529
529
  const ms = options.ms ?? STEP_MS;
530
530
  const delay = options.delay ?? 0;
531
- const ease = EASES[options.ease ?? "out"];
531
+ const ease = easeFunction(options.ease, "out");
532
532
  const start = clock.now();
533
533
  let stopped = false;
534
534
  const emit = (u) => {
@@ -564,4 +564,4 @@ export {
564
564
  SvgPlayer,
565
565
  animateCount
566
566
  };
567
- //# sourceMappingURL=chunk-JETRHCP3.js.map
567
+ //# sourceMappingURL=chunk-XAQ5FWKS.js.map