@pixodesk/svg-animator-web 1.0.21 → 1.0.24

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.
@@ -0,0 +1,2200 @@
1
+ "use strict";
2
+ var PixodeskAnimator = (() => {
3
+ var __defProp = Object.defineProperty;
4
+ var __defProps = Object.defineProperties;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
11
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12
+ var __spreadValues = (a, b) => {
13
+ for (var prop in b || (b = {}))
14
+ if (__hasOwnProp.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ if (__getOwnPropSymbols)
17
+ for (var prop of __getOwnPropSymbols(b)) {
18
+ if (__propIsEnum.call(b, prop))
19
+ __defNormalProp(a, prop, b[prop]);
20
+ }
21
+ return a;
22
+ };
23
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
24
+ var __export = (target, all) => {
25
+ for (var name in all)
26
+ __defProp(target, name, { get: all[name], enumerable: true });
27
+ };
28
+ var __copyProps = (to, from, except, desc) => {
29
+ if (from && typeof from === "object" || typeof from === "function") {
30
+ for (let key of __getOwnPropNames(from))
31
+ if (!__hasOwnProp.call(to, key) && key !== except)
32
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
33
+ }
34
+ return to;
35
+ };
36
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
+
38
+ // src/index.prerendered.ts
39
+ var index_prerendered_exports = {};
40
+ __export(index_prerendered_exports, {
41
+ PX_ANIMATOR_DATA_KEY: () => PX_ANIMATOR_DATA_KEY,
42
+ createAnimator: () => createPrerenderedAnimator,
43
+ setupAnimationTriggers: () => setupAnimationTriggers
44
+ });
45
+
46
+ // ../svg-animator-core/src/PxAnimatorConstants.ts
47
+ var PxAnimatorMode = {
48
+ auto: "auto",
49
+ waapi: "waapi",
50
+ frames: "frames"
51
+ };
52
+ var PxAnimatorEngine = {
53
+ waapi: PxAnimatorMode.waapi,
54
+ frames: PxAnimatorMode.frames
55
+ };
56
+ var PxLoopExtend = {
57
+ /** Segment from the START; the animation is extended BEFORE the first keyframe
58
+ * (intro loops that run before the main timeline begins). */
59
+ before: "before",
60
+ /** DEFAULT — segment from the END; extended AFTER the last keyframe (idle/outro
61
+ * loops that continue once the main timeline has finished). */
62
+ after: "after"
63
+ };
64
+ function getAnimatorConfig(doc) {
65
+ var _a;
66
+ return (doc == null ? void 0 : doc.animator) || ((_a = doc == null ? void 0 : doc.meta) == null ? void 0 : _a.animator);
67
+ }
68
+ function getDefs(doc) {
69
+ var _a;
70
+ if (!doc) return void 0;
71
+ return (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.definitions;
72
+ }
73
+ function getBindings(doc) {
74
+ var _a;
75
+ if (!doc) return void 0;
76
+ const animateById = (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.animateById;
77
+ if (!animateById) return void 0;
78
+ return Object.entries(animateById).map(([id, anim]) => ({ id, animate: anim }));
79
+ }
80
+
81
+ // ../svg-animator-core/src/PxAnimatorUtil.ts
82
+ function bezierToSvgPath(path, forceCurves = false) {
83
+ var _a, _b, _c, _d;
84
+ const v = path.v;
85
+ const i = path.i;
86
+ const o = path.o;
87
+ const c = path.c;
88
+ if (!v.length) return "";
89
+ const d = [];
90
+ const len = v.length;
91
+ d.push("M" + v[0][0] + "," + v[0][1]);
92
+ for (let idx = 1; idx < len; idx++) {
93
+ const prevV = v[idx - 1];
94
+ const prevO = (_a = o == null ? void 0 : o[idx - 1]) != null ? _a : prevV;
95
+ const currI = (_b = i == null ? void 0 : i[idx]) != null ? _b : v[idx];
96
+ const currV = v[idx];
97
+ const isLine = !forceCurves && (prevO[0] === prevV[0] && prevO[1] === prevV[1]) && (currI[0] === currV[0] && currI[1] === currV[1]);
98
+ if (isLine) {
99
+ d.push("L" + currV[0] + "," + currV[1]);
100
+ } else {
101
+ d.push("C" + prevO[0] + "," + prevO[1] + "," + currI[0] + "," + currI[1] + "," + currV[0] + "," + currV[1]);
102
+ }
103
+ }
104
+ if (c && len > 0) {
105
+ const lastV = v[len - 1];
106
+ const lastO = (_c = o == null ? void 0 : o[len - 1]) != null ? _c : lastV;
107
+ const firstI = (_d = i == null ? void 0 : i[0]) != null ? _d : v[0];
108
+ const firstV = v[0];
109
+ const isLine = !forceCurves && (lastO[0] === lastV[0] && lastO[1] === lastV[1]) && (firstI[0] === firstV[0] && firstI[1] === firstV[1]);
110
+ if (!isLine) {
111
+ d.push("C" + lastO[0] + "," + lastO[1] + "," + firstI[0] + "," + firstI[1] + "," + firstV[0] + "," + firstV[1]);
112
+ }
113
+ d.push("z");
114
+ }
115
+ return d.join("");
116
+ }
117
+ function interpolateNum(a, b, t) {
118
+ return a + (b - a) * t;
119
+ }
120
+ function interpolateVec(a, b, t) {
121
+ const res = [];
122
+ const count = Math.max(a.length, b.length);
123
+ for (let i = 0; i < count; i++) {
124
+ res[i] = interpolateNum(a[i] || 0, b[i] || 0, t);
125
+ }
126
+ return res;
127
+ }
128
+ function interpolateColor(a, b, t) {
129
+ return [
130
+ interpolateNum(a[0] || 0, b[0] || 0, t),
131
+ interpolateNum(a[1] || 0, b[1] || 0, t),
132
+ interpolateNum(a[2] || 0, b[2] || 0, t),
133
+ interpolateNum(a[3] === void 0 ? 1 : a[3], b[3] === void 0 ? 1 : b[3], t)
134
+ ];
135
+ }
136
+ function interpolateBeziers(paths1, paths2, progress) {
137
+ const count = Math.max(paths1.length, paths2.length);
138
+ const res = [];
139
+ for (let i = 0; i < count; i++) {
140
+ res.push(interpolateBezier(paths1[i], paths2[i], progress));
141
+ }
142
+ return res;
143
+ }
144
+ function interpolateBezier(path1, path2, progress) {
145
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
146
+ if (!path1 || !path2) return path1 || path2 || { v: [] };
147
+ const t = Math.min(Math.max(progress, 0), 1);
148
+ const len = Math.min(path1.v.length, path2.v.length);
149
+ const v = [];
150
+ const i = [];
151
+ const o = [];
152
+ for (let idx = 0; idx < len; idx++) {
153
+ const v1 = path1.v[idx];
154
+ const v2 = path2.v[idx];
155
+ v.push(interpolateVec(v1, v2, t));
156
+ const i1 = (_b = (_a = path1.i) == null ? void 0 : _a[idx]) != null ? _b : v1;
157
+ const i2 = (_d = (_c = path2.i) == null ? void 0 : _c[idx]) != null ? _d : v2;
158
+ i.push(interpolateVec(i1, i2, t));
159
+ const o1 = (_f = (_e = path1.o) == null ? void 0 : _e[idx]) != null ? _f : v1;
160
+ const o2 = (_h = (_g = path2.o) == null ? void 0 : _g[idx]) != null ? _h : v2;
161
+ o.push(interpolateVec(o1, o2, t));
162
+ }
163
+ return { v, i: i.length ? i : void 0, o: o.length ? o : void 0, c: (_i = path1.c) != null ? _i : path2.c };
164
+ }
165
+ function remap(value, inMin, inMax, outMin, outMax) {
166
+ if (inMax === inMin) return outMin;
167
+ const t = (value - inMin) / (inMax - inMin);
168
+ return outMin + t * (outMax - outMin);
169
+ }
170
+ function solveCubicBezierX(p1x, p2x, x) {
171
+ if (x <= 0) return 0;
172
+ if (x >= 1) return 1;
173
+ const cx = 3 * p1x;
174
+ const bx = 3 * (p2x - p1x) - cx;
175
+ const ax = 1 - cx - bx;
176
+ function sampleX(t) {
177
+ return ((ax * t + bx) * t + cx) * t;
178
+ }
179
+ function sampleDX(t) {
180
+ return (3 * ax * t + 2 * bx) * t + cx;
181
+ }
182
+ let t2 = x;
183
+ let t0 = 0;
184
+ let t1 = 1;
185
+ for (let i = 0; i < 8; i++) {
186
+ const x2 = sampleX(t2) - x;
187
+ if (Math.abs(x2) < 1e-6) return t2;
188
+ const d2 = sampleDX(t2);
189
+ if (Math.abs(d2) < 1e-6) break;
190
+ t2 -= x2 / d2;
191
+ }
192
+ t2 = x;
193
+ while (t0 < t1) {
194
+ const x2 = sampleX(t2);
195
+ if (Math.abs(x2 - x) < 1e-6) return t2;
196
+ if (x > x2) t0 = t2;
197
+ else t1 = t2;
198
+ t2 = (t1 + t0) / 2;
199
+ }
200
+ return t2;
201
+ }
202
+ function cubicBezier(easing) {
203
+ const [p1x, p1y, p2x, p2y] = easing;
204
+ const cy = 3 * p1y;
205
+ const by = 3 * (p2y - p1y) - cy;
206
+ const ay = 1 - cy - by;
207
+ function sampleCurveY(t) {
208
+ return ((ay * t + by) * t + cy) * t;
209
+ }
210
+ return function(x) {
211
+ return sampleCurveY(solveCubicBezierX(p1x, p2x, x));
212
+ };
213
+ }
214
+ function lerp2(a, b, t) {
215
+ return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t];
216
+ }
217
+ function subdivideCubicBezier(p0, p1, p2, p3, t) {
218
+ const q0 = lerp2(p0, p1, t);
219
+ const q1 = lerp2(p1, p2, t);
220
+ const q2 = lerp2(p2, p3, t);
221
+ const r0 = lerp2(q0, q1, t);
222
+ const r1 = lerp2(q1, q2, t);
223
+ const s = lerp2(r0, r1, t);
224
+ return {
225
+ left: [p0, q0, r0, s],
226
+ right: [s, r1, q2, p3]
227
+ };
228
+ }
229
+ function splitEasing(easing, xFraction) {
230
+ if (!easing) return { left: void 0, right: void 0 };
231
+ if (xFraction <= 0) return { left: void 0, right: easing };
232
+ if (xFraction >= 1) return { left: easing, right: void 0 };
233
+ const [x1, y1, x2, y2] = easing;
234
+ const t = solveCubicBezierX(x1, x2, xFraction);
235
+ const p0 = [0, 0];
236
+ const p1 = [x1, y1];
237
+ const p2 = [x2, y2];
238
+ const p3 = [1, 1];
239
+ const { left, right } = subdivideCubicBezier(p0, p1, p2, p3, t);
240
+ const sx = left[3][0];
241
+ const sy = left[3][1];
242
+ let leftEasing;
243
+ if (sx > 1e-9 && Math.abs(sy) > 1e-9) {
244
+ leftEasing = [
245
+ left[1][0] / sx,
246
+ left[1][1] / sy,
247
+ left[2][0] / sx,
248
+ left[2][1] / sy
249
+ ];
250
+ }
251
+ let rightEasing;
252
+ const rx = 1 - sx;
253
+ const ry = 1 - sy;
254
+ if (rx > 1e-9 && Math.abs(ry) > 1e-9) {
255
+ rightEasing = [
256
+ (right[1][0] - sx) / rx,
257
+ (right[1][1] - sy) / ry,
258
+ (right[2][0] - sx) / rx,
259
+ (right[2][1] - sy) / ry
260
+ ];
261
+ }
262
+ return { left: leftEasing, right: rightEasing };
263
+ }
264
+ function reverseEasing(easing) {
265
+ if (!easing) return void 0;
266
+ return [1 - easing[2], 1 - easing[3], 1 - easing[0], 1 - easing[1]];
267
+ }
268
+ function toRGBA(color) {
269
+ const r = Math.round(color[0] * 255);
270
+ const g = Math.round(color[1] * 255);
271
+ const b = Math.round(color[2] * 255);
272
+ return color.length === 4 ? "rgba(" + r + "," + g + "," + b + "," + color[3] + ")" : "rgb(" + r + "," + g + "," + b + ")";
273
+ }
274
+ function parseRgba(s) {
275
+ var _a;
276
+ const inner = (_a = s.match(/rgba?\((.*)\)/)) == null ? void 0 : _a[1];
277
+ if (!inner) throw new Error("Invalid rgb/rgba format");
278
+ const parts = inner.split(",").map((v) => +v.trim());
279
+ return [parts[0] / 255, parts[1] / 255, parts[2] / 255, ...parts[3] !== void 0 ? [parts[3]] : []];
280
+ }
281
+ function parseHex(s) {
282
+ const hex = s.slice(1);
283
+ const isShort = hex.length <= 4;
284
+ const r = isShort ? hex[0] + hex[0] : hex.slice(0, 2);
285
+ const g = isShort ? hex[1] + hex[1] : hex.slice(2, 4);
286
+ const b = isShort ? hex[2] + hex[2] : hex.slice(4, 6);
287
+ const a = hex.length === 4 ? hex[3] + hex[3] : hex.length === 8 ? hex.slice(6, 8) : null;
288
+ const result = [
289
+ parseInt(r, 16) / 255,
290
+ parseInt(g, 16) / 255,
291
+ parseInt(b, 16) / 255
292
+ ];
293
+ if (a !== null) {
294
+ result.push(parseInt(a, 16) / 255);
295
+ }
296
+ return result;
297
+ }
298
+ function parseColor(s) {
299
+ if (!s) return void 0;
300
+ if (Array.isArray(s)) return s;
301
+ if (typeof s !== "string") return void 0;
302
+ if (s.startsWith("#")) {
303
+ return parseHex(s);
304
+ } else if (s.startsWith("rgb")) {
305
+ return parseRgba(s);
306
+ } else {
307
+ console.warn("Unsupported color format: " + s);
308
+ }
309
+ return void 0;
310
+ }
311
+ var COLOUR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
312
+ var TRANSFORM_FN_NAMES = /* @__PURE__ */ new Set(["translate", "rotate", "scale", "skew"]);
313
+ var PCT_BASED_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
314
+ function composeTransformParts(parts, opts) {
315
+ var _a;
316
+ if (!parts) return "";
317
+ const withUnits = (_a = opts == null ? void 0 : opts.withUnits) != null ? _a : true;
318
+ const segs = [];
319
+ const t = parts.translate;
320
+ const o = parts.origin;
321
+ const r = parts.rotate;
322
+ const k = parts.skew;
323
+ const s = parts.scale;
324
+ const tu = withUnits ? "px" : "";
325
+ const ru = withUnits ? "deg" : "";
326
+ if (t) segs.push("translate(" + t[0] + tu + "," + t[1] + tu + ")");
327
+ if (o) segs.push("translate(" + o[0] + tu + "," + o[1] + tu + ")");
328
+ if (r !== void 0 && r !== null) segs.push("rotate(" + r + ru + ")");
329
+ if (k !== void 0 && k !== null) segs.push("skewX(" + k + ru + ")");
330
+ if (s) segs.push("scale(" + s[0] + "," + s[1] + ")");
331
+ if (o) segs.push("translate(" + -o[0] + tu + "," + -o[1] + tu + ")");
332
+ return segs.join("");
333
+ }
334
+ var STYLE_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
335
+ var DEFAULT_DURATION_MS = 1e3;
336
+ function kebabToCamelCaseWord(kebab) {
337
+ return kebab.includes("-") ? kebab.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()) : kebab;
338
+ }
339
+ function isCamelCaseWord(word) {
340
+ return !word.includes("-") && /[a-z][A-Z]/.test(word);
341
+ }
342
+ var SVG_CAMEL_CASE_ATTRS = /* @__PURE__ */ new Set([
343
+ // Transform/positioning
344
+ "viewBox",
345
+ "preserveAspectRatio",
346
+ // Gradient
347
+ "gradientUnits",
348
+ "gradientTransform",
349
+ "spreadMethod",
350
+ // Pattern
351
+ "patternUnits",
352
+ "patternContentUnits",
353
+ "patternTransform",
354
+ // Clipping/masking
355
+ "clipPathUnits",
356
+ "maskUnits",
357
+ "maskContentUnits",
358
+ // Marker (SVG spec keeps these camelCase, like viewBox)
359
+ "markerUnits",
360
+ "markerWidth",
361
+ "markerHeight",
362
+ "refX",
363
+ "refY",
364
+ // Text
365
+ "textLength",
366
+ "lengthAdjust",
367
+ "startOffset",
368
+ // Filter
369
+ "filterUnits",
370
+ "primitiveUnits",
371
+ "tableValues",
372
+ // feFuncR/G/B/A transfer table (type="table")
373
+ "stdDeviation",
374
+ "baseFrequency",
375
+ "numOctaves",
376
+ "surfaceScale",
377
+ "diffuseConstant",
378
+ "specularConstant",
379
+ "specularExponent",
380
+ "kernelMatrix",
381
+ "kernelUnitLength",
382
+ "edgeMode",
383
+ "preserveAlpha",
384
+ "targetX",
385
+ "targetY"
386
+ // // Animation
387
+ // 'attributeName',
388
+ // 'attributeType',
389
+ // 'calcMode',
390
+ // 'keyTimes',
391
+ // 'keySplines',
392
+ // 'repeatCount',
393
+ // 'repeatDur'
394
+ ]);
395
+ function camelCaseToKebabWordIfNeeded(camel) {
396
+ return SVG_CAMEL_CASE_ATTRS.has(camel) ? camel : camel.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
397
+ }
398
+ function clamp(value, min, max) {
399
+ return Math.max(min, Math.min(value, max));
400
+ }
401
+ function bezier2D_pointAt(P0, P1, P2, P3, t) {
402
+ if (t <= 0) return [P0[0], P0[1]];
403
+ if (t >= 1) return [P3[0], P3[1]];
404
+ const u = 1 - t;
405
+ const u2 = u * u;
406
+ const u3 = u2 * u;
407
+ const t2 = t * t;
408
+ const t3 = t2 * t;
409
+ const w0 = u3;
410
+ const w1 = 3 * t * u2;
411
+ const w2 = 3 * t2 * u;
412
+ const w3 = t3;
413
+ return [
414
+ w0 * P0[0] + w1 * P1[0] + w2 * P2[0] + w3 * P3[0],
415
+ w0 * P0[1] + w1 * P1[1] + w2 * P2[1] + w3 * P3[1]
416
+ ];
417
+ }
418
+ var BEZIER_T_NUDGE = 1e-4;
419
+ function bezier2D_derivativeAt(P0, P1, P2, P3, t) {
420
+ const result = _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t);
421
+ if (result[0] === 0 && result[1] === 0) {
422
+ const nudgedT = t < 0.5 ? t + BEZIER_T_NUDGE : t - BEZIER_T_NUDGE;
423
+ return _bezier2D_derivativeAtRaw(P0, P1, P2, P3, nudgedT);
424
+ }
425
+ return result;
426
+ }
427
+ function _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t) {
428
+ const u = 1 - t;
429
+ const a = 3 * u * u;
430
+ const b = 6 * t * u;
431
+ const c = 3 * t * t;
432
+ return [
433
+ a * (P1[0] - P0[0]) + b * (P2[0] - P1[0]) + c * (P3[0] - P2[0]),
434
+ a * (P1[1] - P0[1]) + b * (P2[1] - P1[1]) + c * (P3[1] - P2[1])
435
+ ];
436
+ }
437
+ function bezier2D_arcLengthLUT(P0, P1, P2, P3, steps = 100) {
438
+ const n = steps + 1;
439
+ const ts = new Float64Array(n);
440
+ const ds = new Float64Array(n);
441
+ let prev = bezier2D_pointAt(P0, P1, P2, P3, 0);
442
+ ts[0] = 0;
443
+ ds[0] = 0;
444
+ let cum = 0;
445
+ for (let i = 1; i < n; i++) {
446
+ const t = i / steps;
447
+ const cur = bezier2D_pointAt(P0, P1, P2, P3, t);
448
+ const dx = cur[0] - prev[0];
449
+ const dy = cur[1] - prev[1];
450
+ cum += Math.sqrt(dx * dx + dy * dy);
451
+ ts[i] = t;
452
+ ds[i] = cum;
453
+ prev = cur;
454
+ }
455
+ return { ts, ds };
456
+ }
457
+ function bezier2D_arcAtT(lut, t) {
458
+ const { ts, ds } = lut;
459
+ const last = ts.length - 1;
460
+ if (t <= ts[0]) return ds[0];
461
+ if (t >= ts[last]) return ds[last];
462
+ let lo = 1, hi = last;
463
+ while (lo < hi) {
464
+ const mid = lo + hi >>> 1;
465
+ if (ts[mid] < t) lo = mid + 1;
466
+ else hi = mid;
467
+ }
468
+ const tPrev = ts[hi - 1];
469
+ const span = ts[hi] - tPrev;
470
+ const frac = span > 0 ? (t - tPrev) / span : 0;
471
+ return ds[hi - 1] + frac * (ds[hi] - ds[hi - 1]);
472
+ }
473
+ function invertEasing(easing) {
474
+ if (!easing) return (y) => y;
475
+ const flipped = [easing[1], easing[0], easing[3], easing[2]];
476
+ return cubicBezier(flipped);
477
+ }
478
+
479
+ // ../svg-animator-core/src/PxMotionPath.ts
480
+ function getKfTranslate(kf) {
481
+ var _a;
482
+ const v = (_a = kf.value) != null ? _a : kf.v;
483
+ if (!v) return void 0;
484
+ if (Array.isArray(v) && v.length >= 2 && typeof v[0] === "number" && typeof v[1] === "number") {
485
+ return [v[0], v[1]];
486
+ }
487
+ const tr = v.translate;
488
+ if (Array.isArray(tr) && tr.length >= 2) return [tr[0], tr[1]];
489
+ return void 0;
490
+ }
491
+ function getKfTime(kf) {
492
+ var _a, _b;
493
+ return (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
494
+ }
495
+ function getKfEasing(kf) {
496
+ var _a;
497
+ return (_a = kf.easing) != null ? _a : kf.e;
498
+ }
499
+ function propAnimIsMotionPath(anim) {
500
+ var _a, _b, _c;
501
+ const kfs = (_a = anim.keyframes) != null ? _a : anim.kfs;
502
+ if (!Array.isArray(kfs)) return false;
503
+ if (anim.autoOrient) return true;
504
+ for (const kf of kfs) {
505
+ if (((_b = kf.tangentIn) != null ? _b : kf.ti) || ((_c = kf.tangentOut) != null ? _c : kf.to)) return true;
506
+ }
507
+ return false;
508
+ }
509
+ var _segmentCache = /* @__PURE__ */ new WeakMap();
510
+ function getSegmentCache(prevKf, nextKf, prevPos, nextPos) {
511
+ var _a, _b;
512
+ let byNext = _segmentCache.get(prevKf);
513
+ const existing = byNext == null ? void 0 : byNext.get(nextKf);
514
+ if (existing) return existing;
515
+ const to = (_a = prevKf.tangentOut) != null ? _a : prevKf.to;
516
+ const ti = (_b = nextKf.tangentIn) != null ? _b : nextKf.ti;
517
+ const P1 = [prevPos[0] + (to ? to[0] : 0), prevPos[1] + (to ? to[1] : 0)];
518
+ const P2 = [nextPos[0] + (ti ? ti[0] : 0), nextPos[1] + (ti ? ti[1] : 0)];
519
+ const lut = bezier2D_arcLengthLUT(prevPos, P1, P2, nextPos);
520
+ const entry = {
521
+ P0: prevPos,
522
+ P1,
523
+ P2,
524
+ P3: nextPos,
525
+ lut,
526
+ totalArc: lut.ds[lut.ds.length - 1]
527
+ };
528
+ if (!byNext) {
529
+ byNext = /* @__PURE__ */ new WeakMap();
530
+ _segmentCache.set(prevKf, byNext);
531
+ }
532
+ byNext.set(nextKf, entry);
533
+ return entry;
534
+ }
535
+ function evaluateMotionPathSegment(prevKf, nextKf, prevPos, nextPos, localProgress, autoOrient) {
536
+ const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
537
+ const t = seg.totalArc === 0 ? localProgress : tFromArcFraction(seg.lut, localProgress);
538
+ const point = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
539
+ if (!autoOrient) return { translate: point };
540
+ const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
541
+ const rotateDeg = Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
542
+ return { translate: point, rotateDeg };
543
+ }
544
+ function tFromArcFraction(lut, arcFrac) {
545
+ const total = lut.ds[lut.ds.length - 1];
546
+ const target = arcFrac * total;
547
+ const { ts, ds } = lut;
548
+ const last = ds.length - 1;
549
+ if (target <= 0) return ts[0];
550
+ if (target >= ds[last]) return ts[last];
551
+ let lo = 1, hi = last;
552
+ while (lo < hi) {
553
+ const mid = lo + hi >>> 1;
554
+ if (ds[mid] < target) lo = mid + 1;
555
+ else hi = mid;
556
+ }
557
+ const dPrev = ds[hi - 1];
558
+ const span = ds[hi] - dPrev;
559
+ const frac = span > 0 ? (target - dPrev) / span : 0;
560
+ return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);
561
+ }
562
+ var DEFAULT_FLATNESS_TOL = 0.5;
563
+ var DEFAULT_ROTATION_TOL = 5;
564
+ var DEFAULT_MAX_SAMPLES = 32;
565
+ function materialiseMotionPathInPropAnim(anim, opts) {
566
+ var _a, _b, _c, _d;
567
+ if (!propAnimIsMotionPath(anim)) return anim;
568
+ const kfs = (_a = anim.keyframes) != null ? _a : anim.kfs;
569
+ if (!Array.isArray(kfs) || kfs.length < 2) return anim;
570
+ const autoOrient = !!anim.autoOrient;
571
+ const flatnessTol = (_b = opts == null ? void 0 : opts.flatnessTolerance) != null ? _b : DEFAULT_FLATNESS_TOL;
572
+ const rotationTol = (_c = opts == null ? void 0 : opts.rotationTolerance) != null ? _c : DEFAULT_ROTATION_TOL;
573
+ const maxSamples = (_d = opts == null ? void 0 : opts.maxSamplesPerSegment) != null ? _d : DEFAULT_MAX_SAMPLES;
574
+ const out = [];
575
+ const firstPos = getKfTranslate(kfs[0]);
576
+ if (!firstPos) return anim;
577
+ const firstRotate = autoOrient ? derivAngleForFirstKf(kfs[0], kfs[1]) : void 0;
578
+ out.push(makeOutKf(
579
+ getKfTime(kfs[0]),
580
+ buildOutKfValue(getKfValueParts(kfs[0]), getKfValueParts(kfs[0]), 0, firstPos, firstRotate, autoOrient)
581
+ ));
582
+ for (let i = 0; i < kfs.length - 1; i++) {
583
+ const prevKf = kfs[i];
584
+ const nextKf = kfs[i + 1];
585
+ const prevPos = getKfTranslate(prevKf);
586
+ const nextPos = getKfTranslate(nextKf);
587
+ if (!prevPos || !nextPos) {
588
+ out.push(makeOutKf(
589
+ getKfTime(nextKf),
590
+ buildOutKfValue(getKfValueParts(nextKf), getKfValueParts(nextKf), 1, nextPos != null ? nextPos : [0, 0], void 0, autoOrient)
591
+ ));
592
+ continue;
593
+ }
594
+ if (autoOrient && i > 0) {
595
+ insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol);
596
+ }
597
+ materialiseSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples);
598
+ }
599
+ const lastInE = getKfEasing(kfs[kfs.length - 1]);
600
+ if (lastInE) out[out.length - 1].e = lastInE;
601
+ if (autoOrient) unwrapAutoOrientRotations(out);
602
+ const result = { kfs: out };
603
+ if (anim.loop !== void 0) result.loop = anim.loop;
604
+ return result;
605
+ }
606
+ function unwrapAutoOrientRotations(kfs) {
607
+ var _a;
608
+ let prev;
609
+ for (const kf of kfs) {
610
+ const v = (_a = kf.v) != null ? _a : kf.value;
611
+ if (!v || typeof v.rotate !== "number") continue;
612
+ if (prev === void 0) {
613
+ prev = v.rotate;
614
+ continue;
615
+ }
616
+ let r = v.rotate;
617
+ while (r - prev > 180) r -= 360;
618
+ while (r - prev < -180) r += 360;
619
+ v.rotate = r;
620
+ prev = r;
621
+ }
622
+ }
623
+ function makeOutKf(time, value) {
624
+ return { t: time, v: value };
625
+ }
626
+ function getKfValueParts(kf) {
627
+ var _a;
628
+ const v = (_a = kf.value) != null ? _a : kf.v;
629
+ if (!v || typeof v !== "object" || Array.isArray(v)) return void 0;
630
+ return v;
631
+ }
632
+ function interpolatePart(prev, next, p) {
633
+ if (prev === void 0) return next;
634
+ if (next === void 0) return prev;
635
+ if (typeof prev === "number" && typeof next === "number") {
636
+ return prev + (next - prev) * p;
637
+ }
638
+ if (Array.isArray(prev) && Array.isArray(next) && prev.length === next.length) {
639
+ const out = new Array(prev.length);
640
+ for (let i = 0; i < prev.length; i++) {
641
+ const a = typeof prev[i] === "number" ? prev[i] : 0;
642
+ const b = typeof next[i] === "number" ? next[i] : 0;
643
+ out[i] = a + (b - a) * p;
644
+ }
645
+ return out;
646
+ }
647
+ return p < 0.5 ? prev : next;
648
+ }
649
+ function buildOutKfValue(prevV, nextV, p, translate, rotateDegFromAutoOrient, autoOrient) {
650
+ const value = { translate };
651
+ const keys = /* @__PURE__ */ new Set();
652
+ if (prevV) for (const k of Object.keys(prevV)) keys.add(k);
653
+ if (nextV) for (const k of Object.keys(nextV)) keys.add(k);
654
+ for (const k of keys) {
655
+ if (k === "translate") continue;
656
+ if (k === "rotate" && autoOrient) continue;
657
+ const pv = prevV == null ? void 0 : prevV[k];
658
+ const nv = nextV == null ? void 0 : nextV[k];
659
+ if (pv === void 0 && nv === void 0) continue;
660
+ value[k] = interpolatePart(pv, nv, p);
661
+ }
662
+ if (rotateDegFromAutoOrient !== void 0) {
663
+ value.rotate = rotateDegFromAutoOrient + explicitRotateAt(prevV, nextV, p);
664
+ }
665
+ return value;
666
+ }
667
+ function explicitRotateAt(prevV, nextV, p) {
668
+ const pv = typeof (prevV == null ? void 0 : prevV.rotate) === "number" ? prevV.rotate : void 0;
669
+ const nv = typeof (nextV == null ? void 0 : nextV.rotate) === "number" ? nextV.rotate : void 0;
670
+ if (pv === void 0 && nv === void 0) return 0;
671
+ const r = interpolatePart(pv, nv, p);
672
+ return typeof r === "number" ? r : 0;
673
+ }
674
+ function derivAngleForFirstKf(kf0, kf1) {
675
+ const p0 = getKfTranslate(kf0);
676
+ const p1 = getKfTranslate(kf1);
677
+ if (!p0 || !p1) return 0;
678
+ const seg = getSegmentCache(kf0, kf1, p0, p1);
679
+ const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, 0);
680
+ return Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
681
+ }
682
+ function wrappedAngleDelta(a, b) {
683
+ let d = a - b;
684
+ while (d > 180) d -= 360;
685
+ while (d < -180) d += 360;
686
+ return d;
687
+ }
688
+ function insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol) {
689
+ var _a;
690
+ const lastKf = out[out.length - 1];
691
+ const lastV = (_a = lastKf.v) != null ? _a : lastKf.value;
692
+ const prevExit = lastV == null ? void 0 : lastV.rotate;
693
+ if (typeof prevExit !== "number") return;
694
+ const boundaryV = getKfValueParts(prevKf);
695
+ const prevExitTangent = prevExit - explicitRotateAt(boundaryV, boundaryV, 0);
696
+ const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
697
+ const tanAtStart = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, 0);
698
+ const nextEntry = Math.atan2(tanAtStart[1], tanAtStart[0]) * 180 / Math.PI;
699
+ const delta = wrappedAngleDelta(nextEntry, prevExitTangent);
700
+ if (Math.abs(delta) <= rotationTol) return;
701
+ const prevTime = getKfTime(prevKf);
702
+ const stepTime = Math.min(prevTime + CORNER_STEP_AFTER_BOUNDARY_MS, (prevTime + getKfTime(nextKf)) / 2);
703
+ const dupValue = buildOutKfValue(
704
+ getKfValueParts(prevKf),
705
+ getKfValueParts(prevKf),
706
+ 0,
707
+ prevPos,
708
+ nextEntry,
709
+ true
710
+ );
711
+ out.push(makeOutKf(stepTime, dupValue));
712
+ }
713
+ var CORNER_STEP_AFTER_BOUNDARY_MS = 0.05;
714
+ function materialiseSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples) {
715
+ const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
716
+ const prevTime = getKfTime(prevKf);
717
+ const nextTime = getKfTime(nextKf);
718
+ const prevEasing = getKfEasing(prevKf);
719
+ const invertFn = invertEasing(prevEasing);
720
+ const prevV = getKfValueParts(prevKf);
721
+ const nextV = getKfValueParts(nextKf);
722
+ const interiorTs = computeSampleTs(seg, autoOrient, flatnessTol, rotationTol, maxSamples);
723
+ const samples = [];
724
+ for (const t of interiorTs) {
725
+ const arc = bezier2D_arcAtT(seg.lut, t);
726
+ const p = clamp(seg.totalArc > 0 ? arc / seg.totalArc : t, 0, 1);
727
+ const u = clamp(invertFn(p), 0, 1);
728
+ const pos = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
729
+ const sample = { u, p, pos };
730
+ if (autoOrient) {
731
+ const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
732
+ sample.rotateDeg = Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
733
+ }
734
+ samples.push(sample);
735
+ }
736
+ let remaining = prevEasing;
737
+ let prevU = 0;
738
+ const startIdx = out.length - 1;
739
+ for (let i = 0; i < samples.length; i++) {
740
+ const s = samples[i];
741
+ const xFrac = prevU < 1 ? clamp((s.u - prevU) / (1 - prevU), 0, 1) : 1;
742
+ const { left, right } = splitEasing(remaining, xFrac);
743
+ const ownerIdx = i === 0 ? startIdx : out.length - 1;
744
+ if (left) out[ownerIdx].e = left;
745
+ else delete out[ownerIdx].e;
746
+ const tGlobal = prevTime + s.u * (nextTime - prevTime);
747
+ const value = buildOutKfValue(prevV, nextV, s.p, s.pos, s.rotateDeg, autoOrient);
748
+ out.push(makeOutKf(tGlobal, value));
749
+ remaining = right;
750
+ prevU = s.u;
751
+ }
752
+ }
753
+ function computeSampleTs(seg, autoOrient, flatnessTol, rotationTol, maxSamples) {
754
+ const extremes = [];
755
+ addAxisExtremes(seg.P0[0], seg.P1[0], seg.P2[0], seg.P3[0], extremes);
756
+ addAxisExtremes(seg.P0[1], seg.P1[1], seg.P2[1], seg.P3[1], extremes);
757
+ extremes.sort((a, b) => a - b);
758
+ const critical = [0];
759
+ for (const t of extremes) {
760
+ if (t > critical[critical.length - 1] + 1e-6 && t < 1 - 1e-6) {
761
+ critical.push(t);
762
+ }
763
+ }
764
+ critical.push(1);
765
+ const out = [];
766
+ const budget = { remaining: maxSamples - critical.length };
767
+ for (let i = 0; i < critical.length - 1; i++) {
768
+ bisect(critical[i], critical[i + 1], out, seg, autoOrient, flatnessTol, rotationTol, budget);
769
+ }
770
+ return out;
771
+ }
772
+ function addAxisExtremes(p0, p1, p2, p3, out) {
773
+ const a = p1 - p0;
774
+ const b = p2 - p1;
775
+ const c = p3 - p2;
776
+ const A = a - 2 * b + c;
777
+ const B = 2 * (b - a);
778
+ const C = a;
779
+ if (Math.abs(A) < 1e-10) {
780
+ if (Math.abs(B) > 1e-10) {
781
+ const t = -C / B;
782
+ if (t > 1e-6 && t < 1 - 1e-6) out.push(t);
783
+ }
784
+ return;
785
+ }
786
+ const disc = B * B - 4 * A * C;
787
+ if (disc < 0) return;
788
+ const sq = Math.sqrt(disc);
789
+ const t1 = (-B - sq) / (2 * A);
790
+ const t2 = (-B + sq) / (2 * A);
791
+ if (t1 > 1e-6 && t1 < 1 - 1e-6) out.push(t1);
792
+ if (t2 > 1e-6 && t2 < 1 - 1e-6) out.push(t2);
793
+ }
794
+ function bisect(tA, tB, out, seg, autoOrient, flatnessTol, rotationTol, budget) {
795
+ const tMid = (tA + tB) / 2;
796
+ const pA = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA);
797
+ const pB = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tB);
798
+ const span = tB - tA;
799
+ const p25 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA + span * 0.25);
800
+ const p50 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tMid);
801
+ const p75 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA + span * 0.75);
802
+ const dev = Math.max(
803
+ perpDist(p25, pA, pB),
804
+ perpDist(p50, pA, pB),
805
+ perpDist(p75, pA, pB)
806
+ );
807
+ let rotOk = true;
808
+ if (autoOrient) {
809
+ const tanA = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, tA);
810
+ const tanB = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, tB);
811
+ const angA = Math.atan2(tanA[1], tanA[0]) * 180 / Math.PI;
812
+ const angB = Math.atan2(tanB[1], tanB[0]) * 180 / Math.PI;
813
+ let delta = Math.abs(angA - angB);
814
+ if (delta > 180) delta = 360 - delta;
815
+ if (delta > rotationTol) rotOk = false;
816
+ }
817
+ if (dev <= flatnessTol && rotOk || budget.remaining <= 0 || span < 1e-6) {
818
+ out.push(tB);
819
+ return;
820
+ }
821
+ budget.remaining -= 1;
822
+ bisect(tA, tMid, out, seg, autoOrient, flatnessTol, rotationTol, budget);
823
+ bisect(tMid, tB, out, seg, autoOrient, flatnessTol, rotationTol, budget);
824
+ }
825
+ function perpDist(q, pA, pB) {
826
+ const dx = pB[0] - pA[0];
827
+ const dy = pB[1] - pA[1];
828
+ const len2 = dx * dx + dy * dy;
829
+ if (len2 < 1e-20) {
830
+ const qdx = q[0] - pA[0];
831
+ const qdy = q[1] - pA[1];
832
+ return Math.sqrt(qdx * qdx + qdy * qdy);
833
+ }
834
+ const cross = (q[0] - pA[0]) * dy - (q[1] - pA[1]) * dx;
835
+ return Math.abs(cross) / Math.sqrt(len2);
836
+ }
837
+
838
+ // ../svg-animator-core/src/PxDefinitions.ts
839
+ var LOOP_JUMP_SHIFT_MS = 10;
840
+ function deepEqualValue(a, b) {
841
+ if (a === b) return true;
842
+ if (typeof a !== typeof b || a === null || b === null || typeof a !== "object") return false;
843
+ if (Array.isArray(a) !== Array.isArray(b)) return false;
844
+ const ka = Object.keys(a);
845
+ const kb = Object.keys(b);
846
+ if (ka.length !== kb.length) return false;
847
+ return ka.every((k) => deepEqualValue(a[k], b[k]));
848
+ }
849
+ function parsePathCommands(d) {
850
+ const tokens = d.split(/([MLCZmlcz]|[\s,]+)/).map((t) => t.trim()).filter((t) => t && t !== ",");
851
+ const commands = [];
852
+ let currentCommand = null;
853
+ for (const token of tokens) {
854
+ if (/[MLCZmlcz]/.test(token)) {
855
+ currentCommand = { type: token, values: [] };
856
+ commands.push(currentCommand);
857
+ } else if (currentCommand) {
858
+ const value = +token;
859
+ currentCommand.values.push(Number.isNaN(value) ? 0 : value);
860
+ }
861
+ }
862
+ return commands;
863
+ }
864
+ function parseSvgPathToBezier(d) {
865
+ const res = [];
866
+ let currentPath;
867
+ const commands = parsePathCommands(d);
868
+ for (const command of commands) {
869
+ const type = command.type;
870
+ const values = command.values;
871
+ if (type === "M" || type === "m") {
872
+ const x = values[0] || 0;
873
+ const y = values[1] || 0;
874
+ currentPath = {
875
+ v: [[x, y]],
876
+ i: [[x, y]],
877
+ o: [[x, y]],
878
+ c: false
879
+ };
880
+ res.push(currentPath);
881
+ continue;
882
+ }
883
+ if (!currentPath) {
884
+ currentPath = {
885
+ v: [[0, 0]],
886
+ i: [[0, 0]],
887
+ o: [[0, 0]],
888
+ c: false
889
+ };
890
+ res.push(currentPath);
891
+ }
892
+ if (type === "L") {
893
+ const x = values[0] || 0;
894
+ const y = values[1] || 0;
895
+ currentPath.v.push([x, y]);
896
+ currentPath.i.push([x, y]);
897
+ currentPath.o.push([x, y]);
898
+ } else if (type === "C") {
899
+ const outX = values[0] || 0;
900
+ const outY = values[1] || 0;
901
+ const inX2 = values[2] || 0;
902
+ const inY2 = values[3] || 0;
903
+ const x2 = values[4] || 0;
904
+ const y2 = values[5] || 0;
905
+ currentPath.o[currentPath.o.length - 1] = [outX, outY];
906
+ currentPath.v.push([x2, y2]);
907
+ currentPath.i.push([inX2, inY2]);
908
+ currentPath.o.push([x2, y2]);
909
+ } else if (type === "Z" || type === "z") {
910
+ currentPath.c = true;
911
+ } else {
912
+ console.warn('Unsupported path command "' + type + '"');
913
+ }
914
+ }
915
+ return res;
916
+ }
917
+ function extractPathData(str) {
918
+ if (str.startsWith("path(") && str.endsWith(")")) {
919
+ return str.slice(5, -1);
920
+ }
921
+ if (/^[MmZzLlHhVvCcSsQqTtAa]/.test(str)) {
922
+ return str;
923
+ }
924
+ return void 0;
925
+ }
926
+ function isPathString(value) {
927
+ return typeof value === "string" && extractPathData(value) !== void 0;
928
+ }
929
+ function normalizePathValue(value) {
930
+ if (value && typeof value === "object" && typeof value.path === "string") {
931
+ const d = extractPathData(value.path);
932
+ return d ? { paths: parseSvgPathToBezier(d) } : value;
933
+ }
934
+ if (value && typeof value === "object" && "paths" in value) {
935
+ const pathsArray = value.paths;
936
+ if (Array.isArray(pathsArray) && pathsArray.length > 0) {
937
+ if (isPathString(pathsArray[0])) {
938
+ const paths = [];
939
+ for (const pathStr of pathsArray) {
940
+ const d = extractPathData(pathStr);
941
+ if (d) {
942
+ paths.push(...parseSvgPathToBezier(d));
943
+ }
944
+ }
945
+ return { paths };
946
+ }
947
+ }
948
+ return value;
949
+ }
950
+ if (Array.isArray(value)) {
951
+ if (value.length > 0 && isPathString(value[0])) {
952
+ const paths = [];
953
+ for (const pathStr of value) {
954
+ const d = extractPathData(pathStr);
955
+ if (d) {
956
+ paths.push(...parseSvgPathToBezier(d));
957
+ }
958
+ }
959
+ return { paths };
960
+ }
961
+ return { paths: value };
962
+ }
963
+ if (isPathString(value)) {
964
+ const d = extractPathData(value);
965
+ return { paths: parseSvgPathToBezier(d) };
966
+ }
967
+ return value;
968
+ }
969
+ function resolveEasing(easing, defs) {
970
+ var _a;
971
+ if (!easing) return void 0;
972
+ if (Array.isArray(easing)) {
973
+ return easing;
974
+ }
975
+ if ((_a = defs == null ? void 0 : defs.easings) == null ? void 0 : _a[easing]) {
976
+ return defs.easings[easing];
977
+ }
978
+ console.warn("Unknown easing name: " + easing);
979
+ return void 0;
980
+ }
981
+ function resolveAnimation(animRef, defs) {
982
+ var _a;
983
+ if (typeof animRef === "string") {
984
+ const resolved = (_a = defs == null ? void 0 : defs.animations) == null ? void 0 : _a[animRef];
985
+ if (!resolved) {
986
+ console.warn("Unknown animation name: " + animRef);
987
+ }
988
+ return resolved;
989
+ }
990
+ return animRef;
991
+ }
992
+ function resolveElementAnimation(animate, defs) {
993
+ if (!animate) return [];
994
+ const results = [];
995
+ if (typeof animate === "string") {
996
+ const resolved = resolveAnimation(animate, defs);
997
+ if (resolved) results.push(resolved);
998
+ } else if (Array.isArray(animate)) {
999
+ for (const item of animate) {
1000
+ const resolved = resolveAnimation(item, defs);
1001
+ if (resolved) results.push(resolved);
1002
+ }
1003
+ } else {
1004
+ results.push(animate);
1005
+ }
1006
+ return results;
1007
+ }
1008
+ function interpolateValue(propName, a, b, t) {
1009
+ var _a, _b;
1010
+ if (propName === "d") {
1011
+ const aPaths = (_a = a == null ? void 0 : a.paths) != null ? _a : Array.isArray(a) ? a : [];
1012
+ const bPaths = (_b = b == null ? void 0 : b.paths) != null ? _b : Array.isArray(b) ? b : [];
1013
+ return { paths: interpolateBeziers(aPaths, bPaths, t) };
1014
+ }
1015
+ if (COLOUR_ATTR_NAMES.has(propName)) {
1016
+ return interpolateColor(a || [0, 0, 0, 1], b || [0, 0, 0, 1], t);
1017
+ }
1018
+ if (propName === "transform" && typeof a === "object" && a !== null && !Array.isArray(a) && typeof b === "object" && b !== null && !Array.isArray(b)) {
1019
+ return interpolateTransformParts(a, b, t);
1020
+ }
1021
+ if (propName === "rotate" && typeof a === "number" && typeof b === "number") {
1022
+ return interpolateNum(a, b, t);
1023
+ }
1024
+ if (TRANSFORM_FN_NAMES.has(propName) || propName === "stroke-dasharray" || propName === "strokeDasharray") {
1025
+ return interpolateVec(a || [], b || [], t);
1026
+ }
1027
+ return interpolateNum(+(a || 0), +(b || 0), t);
1028
+ }
1029
+ function interpolateTransformParts(a, b, t) {
1030
+ const keys = /* @__PURE__ */ new Set([...Object.keys(a != null ? a : {}), ...Object.keys(b != null ? b : {})]);
1031
+ const out = {};
1032
+ for (const k of keys) {
1033
+ const av = a == null ? void 0 : a[k];
1034
+ const bv = b == null ? void 0 : b[k];
1035
+ if (k === "rotate" || k === "skew") {
1036
+ out[k] = interpolateNum(+(av != null ? av : 0), +(bv != null ? bv : 0), t);
1037
+ } else if (k === "translate" || k === "scale" || k === "origin") {
1038
+ const fallback = k === "scale" ? [1, 1] : [0, 0];
1039
+ out[k] = interpolateVec(av || fallback, bv || fallback, t);
1040
+ } else {
1041
+ out[k] = bv != null ? bv : av;
1042
+ }
1043
+ }
1044
+ return out;
1045
+ }
1046
+ function expandLoopKeyframes(propName, keyframes, loop, duration) {
1047
+ var _a, _b, _c, _d, _e;
1048
+ const totalIntervals = keyframes.length - 1;
1049
+ const segCount = clamp((_a = loop.segmentCount) != null ? _a : totalIntervals, 1, totalIntervals);
1050
+ let segKfs;
1051
+ if (loop.extend === PxLoopExtend.before) {
1052
+ segKfs = keyframes.slice(0, segCount + 1);
1053
+ } else {
1054
+ segKfs = keyframes.slice(totalIntervals - segCount);
1055
+ }
1056
+ const firstT = (_b = keyframes[0].t) != null ? _b : 0;
1057
+ const lastT = (_c = keyframes[keyframes.length - 1].t) != null ? _c : 0;
1058
+ let fillStart, fillEnd;
1059
+ if (loop.extend === PxLoopExtend.before) {
1060
+ fillStart = 0;
1061
+ fillEnd = firstT;
1062
+ } else {
1063
+ fillStart = lastT;
1064
+ fillEnd = duration;
1065
+ }
1066
+ const fillDuration = fillEnd - fillStart;
1067
+ if (fillDuration <= 0) return keyframes;
1068
+ const segStartT = (_d = segKfs[0].t) != null ? _d : 0;
1069
+ const segEndT = (_e = segKfs[segKfs.length - 1].t) != null ? _e : 0;
1070
+ const segDuration = segEndT - segStartT;
1071
+ if (segDuration <= 0) return keyframes;
1072
+ const template = segKfs.map((kf) => {
1073
+ var _a2, _b2;
1074
+ return {
1075
+ relT: (kf.t - segStartT) / segDuration,
1076
+ v: kf.v,
1077
+ e: kf.e,
1078
+ tangentIn: (_a2 = kf.tangentIn) != null ? _a2 : kf.ti,
1079
+ tangentOut: (_b2 = kf.tangentOut) != null ? _b2 : kf.to
1080
+ };
1081
+ });
1082
+ const fullReps = Math.floor(fillDuration / segDuration);
1083
+ const remainder = fillDuration - fullReps * segDuration;
1084
+ const partialFraction = remainder / segDuration;
1085
+ const looped = [];
1086
+ const separateBoundary = loop.extend !== PxLoopExtend.before;
1087
+ const originalTerminalKf = keyframes[keyframes.length - 1];
1088
+ function appendRep(repStart, isReversed, partial) {
1089
+ var _a2;
1090
+ let entries;
1091
+ if (isReversed) {
1092
+ entries = [];
1093
+ for (let i = template.length - 1; i >= 0; i--) {
1094
+ entries.push({
1095
+ relT: 1 - template[i].relT,
1096
+ v: template[i].v,
1097
+ // Easing for reversed transition: use reversed easing from the forward "from" keyframe
1098
+ e: i > 0 ? reverseEasing(template[i - 1].e) : void 0,
1099
+ // Reversed traversal swaps each vertex's in/out spatial tangents
1100
+ // (geometry is identical, walked backwards), so curvature and
1101
+ // auto-orientation survive the reversed rep.
1102
+ tangentIn: template[i].tangentOut,
1103
+ tangentOut: template[i].tangentIn
1104
+ });
1105
+ }
1106
+ } else {
1107
+ entries = template;
1108
+ }
1109
+ const cutRelT = partial !== void 0 ? partial : 1;
1110
+ for (let i = 0; i < entries.length; i++) {
1111
+ const entry = entries[i];
1112
+ if (entry.relT > cutRelT + 1e-9) {
1113
+ const prev = entries[i - 1];
1114
+ const intervalSpan = entry.relT - prev.relT;
1115
+ const localFrac = (cutRelT - prev.relT) / intervalSpan;
1116
+ const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
1117
+ const cutValue = interpolateValue(propName, prev.v, entry.v, easedFrac);
1118
+ const { left: leftEasing } = splitEasing(prev.e, localFrac);
1119
+ if (looped.length > 0 && prev.relT <= cutRelT) {
1120
+ looped[looped.length - 1].e = leftEasing;
1121
+ }
1122
+ looped.push({ t: repStart + cutRelT * segDuration, v: cutValue, e: void 0 });
1123
+ return;
1124
+ }
1125
+ const prevKf = looped.length > 0 ? looped[looped.length - 1] : originalTerminalKf;
1126
+ const isBoundary = separateBoundary && i === 0 && prevKf !== void 0 && Math.abs(((_a2 = prevKf.t) != null ? _a2 : 0) - (repStart + entry.relT * segDuration)) < 1e-9;
1127
+ if (isBoundary) {
1128
+ if (deepEqualValue(prevKf.v, entry.v)) continue;
1129
+ if (looped.length > 0) {
1130
+ delete prevKf.tangentIn;
1131
+ delete prevKf.tangentOut;
1132
+ }
1133
+ }
1134
+ const pushed = {
1135
+ t: repStart + entry.relT * segDuration + (isBoundary ? LOOP_JUMP_SHIFT_MS : 0),
1136
+ v: entry.v,
1137
+ e: i < entries.length - 1 ? entry.e : void 0
1138
+ };
1139
+ if (entry.tangentIn) pushed.tangentIn = entry.tangentIn;
1140
+ if (entry.tangentOut) pushed.tangentOut = entry.tangentOut;
1141
+ looped.push(pushed);
1142
+ }
1143
+ }
1144
+ function appendRepTail(repStart, isReversed, tailFraction) {
1145
+ let entries;
1146
+ if (isReversed) {
1147
+ entries = [];
1148
+ for (let i = template.length - 1; i >= 0; i--) {
1149
+ entries.push({
1150
+ relT: 1 - template[i].relT,
1151
+ v: template[i].v,
1152
+ e: i > 0 ? reverseEasing(template[i - 1].e) : void 0,
1153
+ tangentIn: template[i].tangentOut,
1154
+ tangentOut: template[i].tangentIn
1155
+ });
1156
+ }
1157
+ } else {
1158
+ entries = template;
1159
+ }
1160
+ const startRelT = 1 - tailFraction;
1161
+ for (let i = 0; i < entries.length; i++) {
1162
+ const entry = entries[i];
1163
+ if (entry.relT < startRelT - 1e-9) continue;
1164
+ const prev = entries[i - 1];
1165
+ if (prev && prev.relT < startRelT - 1e-9 && entry.relT > startRelT + 1e-9) {
1166
+ const intervalSpan = entry.relT - prev.relT;
1167
+ const localFrac = (startRelT - prev.relT) / intervalSpan;
1168
+ const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
1169
+ const startValue = interpolateValue(propName, prev.v, entry.v, easedFrac);
1170
+ const { right: rightEasing } = splitEasing(prev.e, localFrac);
1171
+ looped.push({ t: repStart, v: startValue, e: rightEasing });
1172
+ }
1173
+ const pushed = {
1174
+ t: repStart + (entry.relT - startRelT) * segDuration,
1175
+ v: entry.v,
1176
+ e: i < entries.length - 1 ? entry.e : void 0
1177
+ };
1178
+ if (entry.tangentIn) pushed.tangentIn = entry.tangentIn;
1179
+ if (entry.tangentOut) pushed.tangentOut = entry.tangentOut;
1180
+ looped.push(pushed);
1181
+ }
1182
+ }
1183
+ if (loop.extend === PxLoopExtend.before) {
1184
+ if (partialFraction > 1e-9) {
1185
+ const isReversed = !!loop.alternate && fullReps % 2 === 0;
1186
+ appendRepTail(fillStart, isReversed, partialFraction);
1187
+ }
1188
+ for (let rep = 0; rep < fullReps; rep++) {
1189
+ const distFromBoundary = fullReps - 1 - rep;
1190
+ const isReversed = !!loop.alternate && distFromBoundary % 2 === 0;
1191
+ const repStart = fillStart + remainder + rep * segDuration;
1192
+ appendRep(repStart, isReversed);
1193
+ }
1194
+ } else {
1195
+ for (let rep = 0; rep < fullReps; rep++) {
1196
+ const isReversed = !!loop.alternate && rep % 2 === 0;
1197
+ const repStart = fillStart + rep * segDuration;
1198
+ appendRep(repStart, isReversed);
1199
+ }
1200
+ if (partialFraction > 1e-9) {
1201
+ const isReversed = !!loop.alternate && fullReps % 2 === 0;
1202
+ const repStart = fillStart + fullReps * segDuration;
1203
+ appendRep(repStart, isReversed, partialFraction);
1204
+ }
1205
+ }
1206
+ if (loop.extend === PxLoopExtend.before) {
1207
+ return [...looped, ...keyframes];
1208
+ } else {
1209
+ return [...keyframes, ...looped];
1210
+ }
1211
+ }
1212
+ function normalizeKeyframes(propName, propAnim, duration, defs) {
1213
+ var _a, _b, _c, _d, _e, _f, _g;
1214
+ const keyframes = propAnim.keyframes || propAnim.kfs || [];
1215
+ const normalized = [];
1216
+ for (const kf of keyframes) {
1217
+ const timePct = (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
1218
+ let value = (_c = kf.value) != null ? _c : kf.v;
1219
+ const easing = (_d = kf.easing) != null ? _d : kf.e;
1220
+ if (propName === "d") {
1221
+ value = normalizePathValue(value);
1222
+ }
1223
+ const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
1224
+ if (COLOUR_ATTR_NAMES.has(propNameKebab)) {
1225
+ value = (_e = parseColor(value)) != null ? _e : value;
1226
+ }
1227
+ const normKf = {
1228
+ t: timePct,
1229
+ v: value,
1230
+ e: resolveEasing(easing, defs)
1231
+ };
1232
+ const tIn = (_f = kf.tangentIn) != null ? _f : kf.ti;
1233
+ const tOut = (_g = kf.tangentOut) != null ? _g : kf.to;
1234
+ if (tIn) normKf.tangentIn = tIn;
1235
+ if (tOut) normKf.tangentOut = tOut;
1236
+ normalized.push(normKf);
1237
+ }
1238
+ normalized.sort((a, b) => {
1239
+ var _a2, _b2;
1240
+ return ((_a2 = a.t) != null ? _a2 : 0) - ((_b2 = b.t) != null ? _b2 : 0);
1241
+ });
1242
+ const loopRaw = propAnim.loop;
1243
+ const loop = loopRaw === true ? {} : loopRaw || void 0;
1244
+ if (loop && normalized.length >= 2) {
1245
+ return expandLoopKeyframes(propName, normalized, loop, duration);
1246
+ }
1247
+ return normalized;
1248
+ }
1249
+ function mergeAnimationDefinitions(animations) {
1250
+ const merged = {};
1251
+ for (const anim of animations) {
1252
+ for (const [prop, propAnim] of Object.entries(anim)) {
1253
+ merged[prop] = propAnim;
1254
+ }
1255
+ }
1256
+ return merged;
1257
+ }
1258
+ var _elementIdCounter = 0;
1259
+ function generateElementId() {
1260
+ return "_px_el_" + ++_elementIdCounter;
1261
+ }
1262
+ function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.waapi) {
1263
+ const normalized = {};
1264
+ for (const [propName, propAnim] of Object.entries(animDef)) {
1265
+ const normalizedKfs = normalizeKeyframes(propName, propAnim, duration, defs);
1266
+ if (normalizedKfs.length > 0) {
1267
+ const out = { kfs: normalizedKfs };
1268
+ if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
1269
+ if (propAnim.loop !== void 0) out.loop = propAnim.loop;
1270
+ normalized[propName] = engine === PxAnimatorEngine.waapi && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
1271
+ }
1272
+ }
1273
+ return normalized;
1274
+ }
1275
+ function getNormalisedBindings(doc, engine = PxAnimatorEngine.waapi) {
1276
+ const animatorConfig = getAnimatorConfig(doc) || {};
1277
+ const defs = getDefs(doc);
1278
+ const duration = animatorConfig.duration || 1e3;
1279
+ const bindings = [];
1280
+ const processAnimation = (id, animate) => {
1281
+ if (!animate) return null;
1282
+ const animDefs = resolveElementAnimation(animate, defs);
1283
+ if (animDefs.length === 0) return null;
1284
+ const merged = mergeAnimationDefinitions(animDefs);
1285
+ const normalizedAnim = normalizeAnimationDefinition(merged, duration, defs, engine);
1286
+ if (Object.keys(normalizedAnim).length === 0) return null;
1287
+ return {
1288
+ id,
1289
+ animate: normalizedAnim
1290
+ };
1291
+ };
1292
+ const docBindings = getBindings(doc);
1293
+ if (docBindings) {
1294
+ for (const binding of docBindings) {
1295
+ const normalized = processAnimation(binding.id, binding.animate);
1296
+ if (normalized) bindings.push(normalized);
1297
+ }
1298
+ }
1299
+ const processNode = (node) => {
1300
+ const inlineAnim = node.animate;
1301
+ if (inlineAnim && Object.keys(inlineAnim).length > 0) {
1302
+ const nodeId = node.id || generateElementId();
1303
+ node.id = nodeId;
1304
+ const normalized = processAnimation(nodeId, inlineAnim);
1305
+ if (normalized) bindings.push(normalized);
1306
+ }
1307
+ if (node.children) {
1308
+ for (let i = 0; i < node.children.length; i++) {
1309
+ processNode(node.children[i]);
1310
+ }
1311
+ }
1312
+ };
1313
+ if (doc.children) {
1314
+ for (let i = 0; i < doc.children.length; i++) {
1315
+ processNode(doc.children[i]);
1316
+ }
1317
+ }
1318
+ return bindings;
1319
+ }
1320
+ function getKeyframesPair(keyframes, progress) {
1321
+ var _a, _b;
1322
+ const last = keyframes.length - 1;
1323
+ let prevKf = keyframes[0];
1324
+ let nextKf = keyframes[last > 0 ? 1 : 0];
1325
+ for (let j = 0; j < last; j++) {
1326
+ const aOff = (_a = keyframes[j].t) != null ? _a : 0;
1327
+ const bOff = (_b = keyframes[j + 1].t) != null ? _b : 0;
1328
+ if (aOff <= progress && progress <= bOff) {
1329
+ prevKf = keyframes[j];
1330
+ nextKf = keyframes[j + 1];
1331
+ break;
1332
+ }
1333
+ if (progress > bOff && j === last - 1) {
1334
+ prevKf = keyframes[last > 0 ? last - 1 : 0];
1335
+ nextKf = keyframes[last];
1336
+ }
1337
+ }
1338
+ return { prevKf, nextKf };
1339
+ }
1340
+ function calcPropertyValue(propName, propAnim, progress) {
1341
+ var _a, _b, _c, _d, _e, _f, _g;
1342
+ const keyframes = propAnim.kfs || propAnim.keyframes || [];
1343
+ if (keyframes.length === 0) return null;
1344
+ const { prevKf, nextKf } = getKeyframesPair(keyframes, progress);
1345
+ let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a = prevKf.t) != null ? _a : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
1346
+ localProgress = clamp(localProgress, 0, 1);
1347
+ const easing = (_c = prevKf.e) != null ? _c : prevKf.easing;
1348
+ if (easing && Array.isArray(easing)) {
1349
+ try {
1350
+ localProgress = cubicBezier(easing)(localProgress);
1351
+ } catch (e) {
1352
+ }
1353
+ }
1354
+ let cssAttrName = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
1355
+ let cssValue = null;
1356
+ const prevV = (_d = prevKf == null ? void 0 : prevKf.v) != null ? _d : prevKf == null ? void 0 : prevKf.value;
1357
+ const nextV = (_e = nextKf == null ? void 0 : nextKf.v) != null ? _e : nextKf == null ? void 0 : nextKf.value;
1358
+ if (cssAttrName === "d") {
1359
+ const prevPaths = (_f = prevV == null ? void 0 : prevV.paths) != null ? _f : Array.isArray(prevV) ? prevV : [];
1360
+ const nextPaths = (_g = nextV == null ? void 0 : nextV.paths) != null ? _g : Array.isArray(nextV) ? nextV : [];
1361
+ cssValue = interpolateBeziers(
1362
+ prevPaths,
1363
+ nextPaths,
1364
+ localProgress
1365
+ ).map((bz) => bezierToSvgPath(bz)).join("");
1366
+ } else if (COLOUR_ATTR_NAMES.has(cssAttrName)) {
1367
+ cssValue = toRGBA(interpolateColor(
1368
+ prevV || [0, 0, 0, 1],
1369
+ nextV || [0, 0, 0, 1],
1370
+ localProgress
1371
+ ));
1372
+ cssAttrName = propName;
1373
+ } else if (cssAttrName === "stroke-dasharray") {
1374
+ cssValue = interpolateVec(
1375
+ prevV || [],
1376
+ nextV || [],
1377
+ localProgress
1378
+ ).join(" ");
1379
+ cssAttrName = propName;
1380
+ } else if (cssAttrName === "transform" && prevV !== null && typeof prevV === "object" && !Array.isArray(prevV)) {
1381
+ const partKeys = /* @__PURE__ */ new Set([
1382
+ ...prevV ? Object.keys(prevV) : [],
1383
+ ...nextV ? Object.keys(nextV) : []
1384
+ ]);
1385
+ const partsResult = {};
1386
+ for (const partKey of partKeys) {
1387
+ const prevPart = prevV == null ? void 0 : prevV[partKey];
1388
+ const nextPart = nextV == null ? void 0 : nextV[partKey];
1389
+ if (partKey === "rotate" || partKey === "skew") {
1390
+ partsResult[partKey] = interpolateNum(+(prevPart != null ? prevPart : 0), +(nextPart != null ? nextPart : 0), localProgress);
1391
+ } else if (partKey === "translate" || partKey === "scale" || partKey === "origin") {
1392
+ const fallback = partKey === "scale" ? [1, 1] : [0, 0];
1393
+ const interp = interpolateVec(prevPart || fallback, nextPart || fallback, localProgress);
1394
+ partsResult[partKey] = interp;
1395
+ }
1396
+ }
1397
+ if (propAnimIsMotionPath(propAnim)) {
1398
+ const prevTr = prevV.translate;
1399
+ const nextTr = nextV.translate;
1400
+ if (Array.isArray(prevTr) && Array.isArray(nextTr)) {
1401
+ const sample = evaluateMotionPathSegment(
1402
+ prevKf,
1403
+ nextKf,
1404
+ [+prevTr[0], +prevTr[1]],
1405
+ [+nextTr[0], +nextTr[1]],
1406
+ localProgress,
1407
+ !!propAnim.autoOrient
1408
+ );
1409
+ partsResult.translate = [sample.translate[0], sample.translate[1]];
1410
+ if (sample.rotateDeg !== void 0) partsResult.rotate = sample.rotateDeg;
1411
+ }
1412
+ }
1413
+ cssValue = composeTransformParts(partsResult, { withUnits: false });
1414
+ cssAttrName = "transform";
1415
+ } else if (cssAttrName === "translate") {
1416
+ const v = interpolateVec(
1417
+ prevV || [0, 0],
1418
+ nextV || [0, 0],
1419
+ localProgress
1420
+ );
1421
+ cssValue = "translate(" + v.join(",") + ")";
1422
+ cssAttrName = "transform";
1423
+ } else if (cssAttrName === "rotate") {
1424
+ const v = interpolateNum(
1425
+ +(prevV || 0),
1426
+ +(nextV || 0),
1427
+ localProgress
1428
+ );
1429
+ cssValue = "rotate(" + v + ")";
1430
+ cssAttrName = "transform";
1431
+ } else if (cssAttrName === "scale") {
1432
+ const v = interpolateVec(
1433
+ prevV || [1, 1],
1434
+ nextV || [1, 1],
1435
+ localProgress
1436
+ );
1437
+ cssValue = "scale(" + v.join(",") + ")";
1438
+ cssAttrName = "transform";
1439
+ } else {
1440
+ const num = interpolateNum(
1441
+ +(prevV || 0),
1442
+ +(nextV || 0),
1443
+ localProgress
1444
+ );
1445
+ cssValue = num;
1446
+ }
1447
+ if (PCT_BASED_ATTR_NAMES.has(cssAttrName) && typeof cssValue === "number") {
1448
+ cssValue = cssValue * 100 + "%";
1449
+ }
1450
+ return { k: cssAttrName, v: cssValue === null ? "" : "" + cssValue };
1451
+ }
1452
+ function calcAnimationValues(animDef, progress) {
1453
+ const result = {};
1454
+ for (const [propName, propAnim] of Object.entries(animDef)) {
1455
+ const computed = calcPropertyValue(propName, propAnim, progress);
1456
+ if (computed) {
1457
+ result[computed.k] = computed.v;
1458
+ }
1459
+ }
1460
+ return result;
1461
+ }
1462
+
1463
+ // ../svg-animator-core/src/PxFrameLoop.ts
1464
+ function requestFrame(cb) {
1465
+ const g = globalThis;
1466
+ if (typeof g.requestAnimationFrame === "function") return g.requestAnimationFrame(cb);
1467
+ return g.setTimeout(cb, 16);
1468
+ }
1469
+ function cancelFrame(handle) {
1470
+ const g = globalThis;
1471
+ if (typeof g.cancelAnimationFrame === "function") {
1472
+ g.cancelAnimationFrame(handle);
1473
+ return;
1474
+ }
1475
+ g.clearTimeout(handle);
1476
+ }
1477
+ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
1478
+ var _a;
1479
+ const config = getAnimatorConfig(doc) || {};
1480
+ const bindings = getNormalisedBindings(doc, PxAnimatorEngine.frames);
1481
+ const _iterations = config.iterations;
1482
+ let iterations = 1;
1483
+ if (typeof _iterations === "number") iterations = _iterations || 1;
1484
+ if (_iterations === "infinite") iterations = Infinity;
1485
+ if (iterations < 1) iterations = 1;
1486
+ const duration = +(config.duration || DEFAULT_DURATION_MS);
1487
+ const totalDuration = duration && iterations ? duration * (iterations === Infinity ? Infinity : iterations) : duration ? (iterations != null ? iterations : 1) * duration : 0;
1488
+ const direction = config.direction || "normal";
1489
+ const fill = (_a = config.fill) != null ? _a : "forwards";
1490
+ const fillsForwards = fill === "forwards" || fill === "both";
1491
+ const fillsBackwards = fill === "backwards" || fill === "both";
1492
+ let timerId = null;
1493
+ let playing = false;
1494
+ let timeBeforeLastStartMs = -(config.delay || 0);
1495
+ let lastStartedTs = 0;
1496
+ let playbackRate = 1;
1497
+ let finishCalled = false;
1498
+ const frameRate = config.frameRate;
1499
+ const minFrameIntervalMs = frameRate && frameRate > 0 ? 1e3 / frameRate : 0;
1500
+ let lastRenderTs = 0;
1501
+ const getRawAnimTime = () => {
1502
+ const runningElapsed = lastStartedTs ? (Date.now() - lastStartedTs) * playbackRate : 0;
1503
+ return timeBeforeLastStartMs + runningElapsed;
1504
+ };
1505
+ const getAnimCurrentTime = () => {
1506
+ let time = getRawAnimTime();
1507
+ if (Number.isFinite(totalDuration) && time > totalDuration) time = totalDuration;
1508
+ if (time < 0) time = 0;
1509
+ return time;
1510
+ };
1511
+ function renderFrame(currentTimeMs) {
1512
+ function getEffectiveProgress() {
1513
+ const safeDuration = duration > 0 ? duration : 1;
1514
+ let rawProgress = 0;
1515
+ let iteration = 0;
1516
+ if (duration > 0) {
1517
+ currentTimeMs = clamp(currentTimeMs, 0, iterations * safeDuration);
1518
+ iteration = Math.max(0, Math.ceil(currentTimeMs / safeDuration) - 1);
1519
+ iteration = Math.min(iteration, iterations - 1);
1520
+ const iterationTime = currentTimeMs - iteration * safeDuration;
1521
+ rawProgress = clamp(iterationTime / safeDuration, 0, 1);
1522
+ } else {
1523
+ rawProgress = currentTimeMs;
1524
+ }
1525
+ let baseProgress = rawProgress;
1526
+ const dir = direction || "normal";
1527
+ let effectiveProgress2 = baseProgress;
1528
+ if (dir === "reverse") {
1529
+ effectiveProgress2 = 1 - baseProgress;
1530
+ } else if (dir === "alternate") {
1531
+ if (iteration % 2 === 1) effectiveProgress2 = 1 - baseProgress;
1532
+ } else if (dir === "alternate-reverse") {
1533
+ if (iteration % 2 === 0) effectiveProgress2 = 1 - baseProgress;
1534
+ }
1535
+ return effectiveProgress2;
1536
+ }
1537
+ let effectiveProgress = getEffectiveProgress();
1538
+ for (const binding of bindings || []) {
1539
+ const animDef = binding.animate;
1540
+ if (!animDef || typeof animDef !== "object" || Array.isArray(animDef)) {
1541
+ console.warn("Empty or unresolved binding", binding);
1542
+ continue;
1543
+ }
1544
+ const computedValues = calcAnimationValues(animDef, effectiveProgress * duration);
1545
+ for (const [attrName, value] of Object.entries(computedValues)) {
1546
+ adapter.setAttribute(binding.id, attrName, value);
1547
+ }
1548
+ }
1549
+ }
1550
+ const tick = () => {
1551
+ var _a2, _b;
1552
+ if (!adapter.isConnected()) {
1553
+ pauseAnim();
1554
+ return;
1555
+ }
1556
+ const currentTime = getAnimCurrentTime();
1557
+ const rawTime = getRawAnimTime();
1558
+ if (rawTime < 0 && playbackRate > 0) {
1559
+ if (fillsBackwards) renderFrame(0);
1560
+ return;
1561
+ }
1562
+ if (playbackRate < 0 && rawTime <= 0) {
1563
+ pauseAnim();
1564
+ renderFrame(0);
1565
+ if (!finishCalled) {
1566
+ finishCalled = true;
1567
+ (_a2 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
1568
+ }
1569
+ return;
1570
+ }
1571
+ if (playbackRate > 0 && totalDuration && Number.isFinite(totalDuration) && currentTime >= totalDuration) {
1572
+ pauseAnim();
1573
+ renderFrame(fillsForwards ? totalDuration : 0);
1574
+ if (!finishCalled) {
1575
+ finishCalled = true;
1576
+ (_b = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _b.call(callbacks);
1577
+ }
1578
+ return;
1579
+ }
1580
+ if (minFrameIntervalMs > 0) {
1581
+ const now = Date.now();
1582
+ if (lastRenderTs && now - lastRenderTs < minFrameIntervalMs) {
1583
+ return;
1584
+ }
1585
+ lastRenderTs = now;
1586
+ }
1587
+ renderFrame(currentTime);
1588
+ };
1589
+ if (config.delay) {
1590
+ if (config.delay < 0) {
1591
+ renderFrame(getAnimCurrentTime());
1592
+ } else if (fillsBackwards) {
1593
+ renderFrame(0);
1594
+ }
1595
+ }
1596
+ const _isPlaying = () => {
1597
+ if (!playing) return false;
1598
+ if (!adapter.isConnected()) {
1599
+ return false;
1600
+ }
1601
+ if (playbackRate < 0) {
1602
+ return getRawAnimTime() > 0;
1603
+ }
1604
+ if (Number.isFinite(totalDuration) && getAnimCurrentTime() >= totalDuration) return false;
1605
+ return true;
1606
+ };
1607
+ const loopAnim = (isFirst) => {
1608
+ if (timerId !== null) {
1609
+ cancelFrame(timerId);
1610
+ timerId = null;
1611
+ }
1612
+ if (!(isFirst || _isPlaying())) {
1613
+ return;
1614
+ }
1615
+ timerId = requestFrame(() => {
1616
+ timerId = null;
1617
+ tick();
1618
+ loopAnim();
1619
+ });
1620
+ };
1621
+ const startAnim = () => {
1622
+ if (playing) return;
1623
+ if (playbackRate >= 0) {
1624
+ if (Number.isFinite(totalDuration) && timeBeforeLastStartMs >= totalDuration) {
1625
+ timeBeforeLastStartMs = 0;
1626
+ }
1627
+ } else {
1628
+ if (timeBeforeLastStartMs <= 0) {
1629
+ if (!Number.isFinite(totalDuration)) {
1630
+ console.warn("play: cannot start reverse playback of an infinite animation from time 0");
1631
+ return;
1632
+ }
1633
+ timeBeforeLastStartMs = totalDuration;
1634
+ }
1635
+ }
1636
+ finishCalled = false;
1637
+ playing = true;
1638
+ lastStartedTs = Date.now();
1639
+ loopAnim(true);
1640
+ };
1641
+ const pauseAnim = () => {
1642
+ if (!playing) return;
1643
+ let raw = getRawAnimTime();
1644
+ if (Number.isFinite(totalDuration) && raw > totalDuration) raw = totalDuration;
1645
+ timeBeforeLastStartMs = raw;
1646
+ lastStartedTs = 0;
1647
+ playing = false;
1648
+ if (timerId !== null) {
1649
+ cancelFrame(timerId);
1650
+ timerId = null;
1651
+ }
1652
+ if (raw >= 0) {
1653
+ renderFrame(raw);
1654
+ } else if (fillsBackwards) {
1655
+ renderFrame(0);
1656
+ }
1657
+ };
1658
+ const cancelAnim = () => {
1659
+ var _a2;
1660
+ pauseAnim();
1661
+ timeBeforeLastStartMs = 0;
1662
+ lastStartedTs = 0;
1663
+ playing = false;
1664
+ finishCalled = false;
1665
+ renderFrame(timeBeforeLastStartMs);
1666
+ (_a2 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a2.call(callbacks);
1667
+ };
1668
+ const finishAnim = (callOnFinish = true) => {
1669
+ var _a2;
1670
+ if (Number.isFinite(totalDuration)) {
1671
+ timeBeforeLastStartMs = totalDuration;
1672
+ } else {
1673
+ timeBeforeLastStartMs = getAnimCurrentTime();
1674
+ }
1675
+ lastStartedTs = 0;
1676
+ playing = false;
1677
+ if (timerId !== null) {
1678
+ cancelFrame(timerId);
1679
+ timerId = null;
1680
+ }
1681
+ renderFrame(fillsForwards ? timeBeforeLastStartMs : 0);
1682
+ if (callOnFinish && !finishCalled) {
1683
+ finishCalled = true;
1684
+ (_a2 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
1685
+ }
1686
+ };
1687
+ const api = {
1688
+ "isReady": () => true,
1689
+ "getRootElement": () => null,
1690
+ "isPlaying": () => {
1691
+ return _isPlaying();
1692
+ },
1693
+ "play": () => {
1694
+ var _a2;
1695
+ startAnim();
1696
+ (_a2 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a2.call(callbacks);
1697
+ },
1698
+ "pause": () => {
1699
+ var _a2;
1700
+ pauseAnim();
1701
+ (_a2 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a2.call(callbacks);
1702
+ },
1703
+ "cancel": () => {
1704
+ cancelAnim();
1705
+ },
1706
+ "finish": () => {
1707
+ finishAnim(true);
1708
+ },
1709
+ "setPlaybackRate": (rate) => {
1710
+ if (!isFinite(rate) || rate === 0) {
1711
+ console.warn("setPlaybackRate: rate must be finite and non-zero");
1712
+ return;
1713
+ }
1714
+ let current = getRawAnimTime();
1715
+ if (Number.isFinite(totalDuration) && current > totalDuration) current = totalDuration;
1716
+ if (rate < 0 !== playbackRate < 0) finishCalled = false;
1717
+ playbackRate = rate;
1718
+ timeBeforeLastStartMs = current;
1719
+ if (playing) lastStartedTs = Date.now();
1720
+ },
1721
+ "getCurrentTime": () => {
1722
+ return getAnimCurrentTime();
1723
+ },
1724
+ "setCurrentTime": (newTime) => {
1725
+ if (newTime < 0) newTime = 0;
1726
+ if (Number.isFinite(totalDuration) && newTime > totalDuration) newTime = totalDuration;
1727
+ timeBeforeLastStartMs = newTime;
1728
+ if (playing) lastStartedTs = Date.now();
1729
+ if (!Number.isFinite(totalDuration) || newTime < totalDuration) finishCalled = false;
1730
+ renderFrame(getAnimCurrentTime());
1731
+ },
1732
+ "destroy": () => {
1733
+ var _a2;
1734
+ api.cancel();
1735
+ (_a2 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
1736
+ }
1737
+ };
1738
+ return api;
1739
+ }
1740
+
1741
+ // src/PxAnimatorTriggers.ts
1742
+ function setupAnimationTriggers(api, config) {
1743
+ const { startOn, outAction = "continue", scrollIntoViewThreshold = 0 } = config;
1744
+ const root = api.getRootElement();
1745
+ if (!root) {
1746
+ console.warn("setupAnimationTriggers: No root element found for animation.");
1747
+ return api;
1748
+ }
1749
+ let reversed = false;
1750
+ const start = () => {
1751
+ if (reversed) {
1752
+ reversed = false;
1753
+ api.setPlaybackRate(1);
1754
+ }
1755
+ api.play();
1756
+ };
1757
+ const handleEndAction = () => {
1758
+ switch (outAction) {
1759
+ case "pause":
1760
+ api.pause();
1761
+ break;
1762
+ case "reset":
1763
+ api.cancel();
1764
+ break;
1765
+ case "reverse":
1766
+ reversed = true;
1767
+ api.setPlaybackRate(-1);
1768
+ api.play();
1769
+ break;
1770
+ case "continue":
1771
+ default:
1772
+ break;
1773
+ }
1774
+ };
1775
+ switch (startOn) {
1776
+ case "load": {
1777
+ const startHandler = () => start();
1778
+ if (document.readyState === "complete") {
1779
+ startHandler();
1780
+ } else {
1781
+ window.addEventListener("load", startHandler, { once: true });
1782
+ }
1783
+ break;
1784
+ }
1785
+ case "mouseOver": {
1786
+ let enteredOnce = false;
1787
+ const mouseOverHandler = () => {
1788
+ enteredOnce = true;
1789
+ start();
1790
+ };
1791
+ const mouseOutHandler = () => {
1792
+ if (enteredOnce) handleEndAction();
1793
+ };
1794
+ root.addEventListener("mouseenter", mouseOverHandler);
1795
+ root.addEventListener("mouseleave", mouseOutHandler);
1796
+ break;
1797
+ }
1798
+ case "click": {
1799
+ const clickHandler = () => {
1800
+ if (api.isPlaying()) {
1801
+ handleEndAction();
1802
+ } else {
1803
+ start();
1804
+ }
1805
+ };
1806
+ root.addEventListener("click", clickHandler);
1807
+ break;
1808
+ }
1809
+ case "scrollIntoView": {
1810
+ const effectiveRatio = (entry) => {
1811
+ var _a, _b;
1812
+ const target = entry.boundingClientRect;
1813
+ const visible = entry.intersectionRect;
1814
+ if (!(target == null ? void 0 : target.height) || !visible) return entry.intersectionRatio;
1815
+ const live = typeof window !== "undefined" && window.innerHeight ? window.innerHeight : Infinity;
1816
+ const declared = (_b = (_a = entry.rootBounds) == null ? void 0 : _a.height) != null ? _b : Infinity;
1817
+ const viewport = Math.min(live, declared);
1818
+ const denom = Math.min(target.height, Number.isFinite(viewport) ? viewport : target.height);
1819
+ return denom > 0 ? visible.height / denom : entry.intersectionRatio;
1820
+ };
1821
+ const thresholdSteps = Array.from({ length: 21 }, (_, i) => i / 20);
1822
+ let wasIntersecting = false;
1823
+ const observer = new IntersectionObserver(
1824
+ (entries) => {
1825
+ entries.forEach((entry) => {
1826
+ if (entry.isIntersecting && effectiveRatio(entry) >= scrollIntoViewThreshold) {
1827
+ wasIntersecting = true;
1828
+ start();
1829
+ } else if (wasIntersecting) {
1830
+ wasIntersecting = false;
1831
+ handleEndAction();
1832
+ }
1833
+ });
1834
+ },
1835
+ { threshold: thresholdSteps }
1836
+ );
1837
+ observer.observe(root);
1838
+ break;
1839
+ }
1840
+ case "programmatic":
1841
+ break;
1842
+ }
1843
+ return api;
1844
+ }
1845
+
1846
+ // src/PxAnimatorFrameLoop.ts
1847
+ function getSelector(id) {
1848
+ return "#" + id;
1849
+ }
1850
+ function createFrameLoopAnimator(doc, adapter, callbacks, rootElement) {
1851
+ const config = getAnimatorConfig(doc) || {};
1852
+ if (!rootElement) {
1853
+ if (doc.id) {
1854
+ const rootSelector = getSelector(doc.id);
1855
+ rootElement = document.querySelector(rootSelector);
1856
+ if (!rootElement) console.warn("createFrameLoopAnimator: No root element found for selector: ", rootSelector);
1857
+ } else {
1858
+ console.warn("createFrameLoopAnimator: No root element provided");
1859
+ }
1860
+ }
1861
+ const basicApi = createBasicFrameLoopAnimator(
1862
+ doc,
1863
+ adapter || createDomAdapter(rootElement),
1864
+ callbacks
1865
+ );
1866
+ const api = __spreadProps(__spreadValues({}, basicApi), {
1867
+ "getRootElement": () => rootElement || null
1868
+ });
1869
+ if (config.trigger) setupAnimationTriggers(api, config.trigger);
1870
+ return api;
1871
+ }
1872
+ function createDomAdapter(rootElement) {
1873
+ const warnedSelectors = /* @__PURE__ */ new Set();
1874
+ const adapter = {
1875
+ isConnected: () => {
1876
+ if (!rootElement) return true;
1877
+ return rootElement.isConnected;
1878
+ },
1879
+ setAttribute: (id, attrName, value) => {
1880
+ attrName = camelCaseToKebabWordIfNeeded(attrName);
1881
+ const selector = getSelector(id);
1882
+ const elements = (rootElement == null ? void 0 : rootElement.querySelectorAll(selector)) || document.querySelectorAll(selector);
1883
+ if (elements.length === 0 && !warnedSelectors.has(selector)) {
1884
+ warnedSelectors.add(selector);
1885
+ console.warn('setAttribute: No elements found for selector "' + selector + '"');
1886
+ }
1887
+ for (let i = 0; i < elements.length; i++) {
1888
+ const element = elements[i];
1889
+ const effectiveAttrName = attrName === "transform" && element.tagName === "pattern" ? "patternTransform" : attrName;
1890
+ element.setAttribute(effectiveAttrName, value);
1891
+ if (STYLE_ATTR_NAMES.has(attrName)) {
1892
+ element.style[attrName] = value;
1893
+ }
1894
+ }
1895
+ }
1896
+ };
1897
+ return adapter;
1898
+ }
1899
+
1900
+ // src/PxAnimatorWebApi.ts
1901
+ function createCssKf(kf, t, propName, unsupportedSet) {
1902
+ var _a, _b;
1903
+ let value = (_a = kf.v) != null ? _a : kf.value;
1904
+ const e = (_b = kf.e) != null ? _b : kf.easing;
1905
+ const cssKf = {
1906
+ offset: t,
1907
+ easing: e && Array.isArray(e) ? "cubic-bezier(" + e.join(",") + ")" : void 0
1908
+ };
1909
+ let cssValue;
1910
+ let cssKey = propName;
1911
+ if (COLOUR_ATTR_NAMES.has(propName) && Array.isArray(value)) {
1912
+ cssValue = toRGBA(value);
1913
+ } else if (propName === "transform" && value !== null && typeof value === "object" && !Array.isArray(value)) {
1914
+ cssValue = composeTransformParts(value, { withUnits: true });
1915
+ cssKey = "transform";
1916
+ } else if (TRANSFORM_FN_NAMES.has(propName)) {
1917
+ if (Array.isArray(value)) {
1918
+ if (propName === "translate") value = value.map((v) => v + "px");
1919
+ value = value.join(",");
1920
+ }
1921
+ if (propName === "rotate") value = value + "deg";
1922
+ cssValue = propName + "(" + value + ")";
1923
+ cssKey = "transform";
1924
+ } else if (propName === "d") {
1925
+ const paths = value && typeof value === "object" && Array.isArray(value.paths) ? value.paths : [];
1926
+ cssValue = 'path("' + paths.map((bz) => bezierToSvgPath(bz, true)).join("") + '")';
1927
+ } else {
1928
+ cssValue = "" + value;
1929
+ }
1930
+ if (!CSS.supports(camelCaseToKebabWordIfNeeded(cssKey), cssValue)) unsupportedSet.add(cssKey);
1931
+ cssKey = kebabToCamelCaseWord(cssKey);
1932
+ cssKf[cssKey] = cssValue;
1933
+ return cssKf;
1934
+ }
1935
+ function clipKeyframesToDuration(propName, keyframes, duration) {
1936
+ var _a, _b, _c, _d, _e;
1937
+ const result = [];
1938
+ for (let i = 0; i < keyframes.length; i++) {
1939
+ const kf = keyframes[i];
1940
+ const t = (_a = kf.t) != null ? _a : 0;
1941
+ if (t < 0) {
1942
+ const next = keyframes[i + 1];
1943
+ if (next && ((_b = next.t) != null ? _b : 0) >= 0) {
1944
+ const nextT = (_c = next.t) != null ? _c : 0;
1945
+ const localFrac = (0 - t) / (nextT - t);
1946
+ const easedFrac = kf.e ? cubicBezier(kf.e)(localFrac) : localFrac;
1947
+ const { right: rightEasing } = splitEasing(kf.e, localFrac);
1948
+ result.push({ t: 0, v: interpolateValue(propName, kf.v, next.v, easedFrac), e: rightEasing });
1949
+ }
1950
+ continue;
1951
+ }
1952
+ if (t > duration) {
1953
+ const prev = keyframes[i - 1];
1954
+ if (prev && ((_d = prev.t) != null ? _d : 0) <= duration) {
1955
+ const prevT = (_e = prev.t) != null ? _e : 0;
1956
+ const localFrac = (duration - prevT) / (t - prevT);
1957
+ const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
1958
+ const { left: leftEasing } = splitEasing(prev.e, localFrac);
1959
+ if (result.length > 0) result[result.length - 1] = __spreadProps(__spreadValues({}, result[result.length - 1]), { e: leftEasing });
1960
+ result.push({ t: duration, v: interpolateValue(propName, prev.v, kf.v, easedFrac), e: void 0 });
1961
+ }
1962
+ break;
1963
+ }
1964
+ result.push(kf);
1965
+ }
1966
+ return result;
1967
+ }
1968
+ function convertToWebApiKeyframes(animDef, unsupportedSet, config) {
1969
+ var _a;
1970
+ const result = /* @__PURE__ */ new Map();
1971
+ for (const [propName, propAnim] of Object.entries(animDef)) {
1972
+ const duration = config.duration || 1;
1973
+ const clippedKeyframes = clipKeyframesToDuration(propName, propAnim.kfs || propAnim.keyframes || [], duration);
1974
+ const cssKeyframes = [];
1975
+ for (let i = 0; i < clippedKeyframes.length; i++) {
1976
+ const kf = clippedKeyframes[i];
1977
+ const t = clamp(((_a = kf.t) != null ? _a : 0) / duration, 0, 1);
1978
+ const cssKf = createCssKf(kf, t, propName, unsupportedSet);
1979
+ if (i === 0 && (cssKf.offset || 0) > 0) {
1980
+ cssKeyframes.push(__spreadProps(__spreadValues({}, cssKf), { offset: 0 }));
1981
+ }
1982
+ cssKeyframes.push(cssKf);
1983
+ }
1984
+ if (cssKeyframes.length > 0 && (cssKeyframes[cssKeyframes.length - 1].offset || 0) < 1) {
1985
+ cssKeyframes.push(__spreadProps(__spreadValues({}, cssKeyframes[cssKeyframes.length - 1]), {
1986
+ offset: 1
1987
+ }));
1988
+ }
1989
+ if (cssKeyframes.length > 0) {
1990
+ result.set(propName, cssKeyframes);
1991
+ }
1992
+ }
1993
+ return result;
1994
+ }
1995
+ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsupportedAttrs) {
1996
+ var _a;
1997
+ const config = getAnimatorConfig(doc) || {};
1998
+ if (!rootElement) {
1999
+ if (doc.id) {
2000
+ const rootSelector = getSelector(doc.id);
2001
+ rootElement = document.querySelector(rootSelector);
2002
+ if (!rootElement) console.warn("createFrameLoopAnimator: No root element found for selector: ", rootSelector);
2003
+ } else {
2004
+ console.warn("createFrameLoopAnimator: No root element provided");
2005
+ }
2006
+ }
2007
+ const bindings = getNormalisedBindings(doc, PxAnimatorEngine.waapi);
2008
+ const animations = [];
2009
+ const _iterations = config.iterations;
2010
+ let iterations;
2011
+ if (typeof _iterations === "number") iterations = _iterations;
2012
+ if (_iterations === "infinite") iterations = Infinity;
2013
+ const unsupportedSet = /* @__PURE__ */ new Set();
2014
+ let finishNotified = false;
2015
+ let removeCalled = false;
2016
+ if (!(bindings == null ? void 0 : bindings.length)) {
2017
+ console.warn("createWebApiAnimator: No animation bindings defined");
2018
+ }
2019
+ for (const binding of bindings || []) {
2020
+ const animDef = binding.animate;
2021
+ if (!animDef || typeof animDef !== "object" || Array.isArray(animDef)) {
2022
+ console.warn("createWebApiAnimator: Empty or unresolved binding", binding);
2023
+ continue;
2024
+ }
2025
+ const selector = getSelector(binding.id);
2026
+ const elements = (rootElement == null ? void 0 : rootElement.querySelectorAll(selector)) || document.querySelectorAll(selector);
2027
+ if (elements.length === 0) {
2028
+ console.warn('createWebApiAnimator: No elements found for selector "' + selector + '"');
2029
+ }
2030
+ const keyframesMap = convertToWebApiKeyframes(animDef, unsupportedSet, config);
2031
+ const positiveDelay = config.delay && config.delay > 0 ? config.delay : void 0;
2032
+ let seekPosition;
2033
+ if (config.delay && config.delay < 0 && config.duration) {
2034
+ const rawSeek = -config.delay;
2035
+ seekPosition = iterations === Infinity ? rawSeek % config.duration : Math.min(rawSeek, config.duration * (iterations != null ? iterations : 1));
2036
+ }
2037
+ const effectOptions = {
2038
+ duration: config.duration,
2039
+ delay: positiveDelay,
2040
+ // Default to 'forwards' so elements hold their final state after the
2041
+ // animation ends — consistent with Lottie and other animation runtimes.
2042
+ // Without this, seeking to the last frame reverts elements to their
2043
+ // pre-animation state (the Web Animations API "after" phase with fill:'none').
2044
+ fill: (_a = config.fill) != null ? _a : "forwards",
2045
+ direction: config.direction,
2046
+ iterations
2047
+ };
2048
+ for (let i = 0; i < elements.length; i++) {
2049
+ const element = elements[i];
2050
+ for (const [, keyframes] of keyframesMap) {
2051
+ if (keyframes.length > 0) {
2052
+ try {
2053
+ const effect = new KeyframeEffect(element, keyframes, effectOptions);
2054
+ const anim = new Animation(effect, document.timeline);
2055
+ if (callbacks == null ? void 0 : callbacks.onFinish) anim.onfinish = () => {
2056
+ var _a2;
2057
+ if (finishNotified) return;
2058
+ finishNotified = true;
2059
+ (_a2 = callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
2060
+ };
2061
+ if (callbacks == null ? void 0 : callbacks.onRemove) anim.onremove = () => {
2062
+ var _a2;
2063
+ if (removeCalled) return;
2064
+ removeCalled = true;
2065
+ (_a2 = callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
2066
+ };
2067
+ if (seekPosition !== void 0) {
2068
+ anim.currentTime = seekPosition;
2069
+ }
2070
+ animations.push(anim);
2071
+ } catch (e) {
2072
+ console.warn(e);
2073
+ }
2074
+ }
2075
+ }
2076
+ }
2077
+ }
2078
+ if (!forceEvenIfHasUnsupportedAttrs && unsupportedSet.size) {
2079
+ console.warn("Unsupported CSS attrs: " + [...unsupportedSet].join(", "));
2080
+ return null;
2081
+ }
2082
+ const api = {
2083
+ "isReady": () => true,
2084
+ "getRootElement": () => rootElement || null,
2085
+ "isPlaying": () => {
2086
+ var _a2;
2087
+ return ((_a2 = animations[0]) == null ? void 0 : _a2.playState) === "running";
2088
+ },
2089
+ "play": () => {
2090
+ var _a2;
2091
+ finishNotified = false;
2092
+ animations.forEach((a) => a.play());
2093
+ (_a2 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a2.call(callbacks);
2094
+ },
2095
+ "pause": () => {
2096
+ var _a2;
2097
+ animations.forEach((a) => a.pause());
2098
+ (_a2 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a2.call(callbacks);
2099
+ },
2100
+ "cancel": () => {
2101
+ var _a2;
2102
+ finishNotified = false;
2103
+ animations.forEach((a) => a.cancel());
2104
+ (_a2 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a2.call(callbacks);
2105
+ },
2106
+ "finish": () => {
2107
+ var _a2;
2108
+ for (const a of animations) {
2109
+ try {
2110
+ if (((_a2 = a.effect) == null ? void 0 : _a2.getTiming().iterations) === Infinity) {
2111
+ a.effect.updateTiming({ iterations: 1 });
2112
+ a.finish();
2113
+ a.effect.updateTiming({ iterations: Infinity });
2114
+ } else {
2115
+ a.finish();
2116
+ }
2117
+ } catch (e) {
2118
+ a.cancel();
2119
+ }
2120
+ }
2121
+ },
2122
+ "setPlaybackRate": (rate) => {
2123
+ animations.forEach((a) => a.playbackRate = rate);
2124
+ return api;
2125
+ },
2126
+ "getCurrentTime": () => {
2127
+ var _a2, _b;
2128
+ const res = (_b = (_a2 = animations[0]) == null ? void 0 : _a2.currentTime) != null ? _b : null;
2129
+ return res !== null ? +res : null;
2130
+ },
2131
+ "setCurrentTime": (time) => {
2132
+ finishNotified = false;
2133
+ animations.forEach((a) => {
2134
+ a.currentTime = time;
2135
+ });
2136
+ },
2137
+ "destroy": () => {
2138
+ var _a2;
2139
+ api.cancel();
2140
+ animations.splice(0, animations.length);
2141
+ if (!removeCalled) {
2142
+ removeCalled = true;
2143
+ (_a2 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
2144
+ }
2145
+ }
2146
+ };
2147
+ if (config.trigger) {
2148
+ setupAnimationTriggers(api, config.trigger);
2149
+ }
2150
+ return api;
2151
+ }
2152
+
2153
+ // src/PxAnimatorBind.ts
2154
+ function finaliseAnimator(animatorConfig, callbacks, make) {
2155
+ let apiRef;
2156
+ let effectiveCallbacks = callbacks;
2157
+ if (animatorConfig.resetOnFinish) {
2158
+ effectiveCallbacks = __spreadProps(__spreadValues({}, callbacks), {
2159
+ onFinish: () => {
2160
+ var _a;
2161
+ (_a = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a.call(callbacks);
2162
+ apiRef == null ? void 0 : apiRef.cancel();
2163
+ }
2164
+ });
2165
+ }
2166
+ const res = make(effectiveCallbacks);
2167
+ apiRef = res;
2168
+ if (animatorConfig.debugInstName) {
2169
+ window[animatorConfig.debugInstName] = res;
2170
+ }
2171
+ return res;
2172
+ }
2173
+ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
2174
+ const animatorConfig = getAnimatorConfig(doc) || {};
2175
+ return finaliseAnimator(animatorConfig, callbacks, (cb) => {
2176
+ if (animatorConfig.mode === PxAnimatorMode.frames) {
2177
+ return createFrameLoopAnimator(doc, adapter, cb, rootElement);
2178
+ }
2179
+ return createWebApiAnimator(
2180
+ doc,
2181
+ cb,
2182
+ rootElement,
2183
+ animatorConfig.mode === PxAnimatorMode.waapi
2184
+ // forcing waapi
2185
+ ) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
2186
+ });
2187
+ }
2188
+ function requireData(options) {
2189
+ if (!(options == null ? void 0 : options.data)) throw new Error("createAnimator: `data` is required");
2190
+ return options.data;
2191
+ }
2192
+ function createPrerenderedAnimator(options) {
2193
+ return bindWithEngineChoice(requireData(options), options.adapter, options.callbacks, null);
2194
+ }
2195
+
2196
+ // src/PxAnimatorKeys.ts
2197
+ var PX_ANIMATOR_DATA_KEY = "data";
2198
+ return __toCommonJS(index_prerendered_exports);
2199
+ })();
2200
+ //# sourceMappingURL=index.prerendered.umd.js.map