@pixodesk/svg-animator-vue 1.0.15 → 1.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.umd.js CHANGED
@@ -56768,7 +56768,6 @@ ${codeFrame}` : message);
56768
56768
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
56769
56769
  var __hasOwnProp2 = Object.prototype.hasOwnProperty;
56770
56770
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
56771
- var __pow = Math.pow;
56772
56771
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
56773
56772
  var __spreadValues = (a, b) => {
56774
56773
  for (var prop in b || (b = {}))
@@ -56803,7 +56802,10 @@ ${codeFrame}` : message);
56803
56802
  return rec;
56804
56803
  }
56805
56804
  function readAnimatable(raw) {
56806
- if (raw === void 0) return { kind: "absent" };
56805
+ if (raw === void 0) return {
56806
+ kind: "absent"
56807
+ /* Absent */
56808
+ };
56807
56809
  if (Array.isArray(raw)) return { kind: "static", value: raw };
56808
56810
  if (typeof raw === "object") {
56809
56811
  const obj = raw;
@@ -56950,7 +56952,7 @@ ${codeFrame}` : message);
56950
56952
  return outerWrapper;
56951
56953
  }
56952
56954
  function liftBodyTranslate(node, transformation) {
56953
- var _a;
56955
+ var _a, _b, _c;
56954
56956
  const out = {};
56955
56957
  let didLiftAnimate = false;
56956
56958
  const animTr = (_a = node.animate) == null ? void 0 : _a.transform;
@@ -57001,6 +57003,7 @@ ${codeFrame}` : message);
57001
57003
  }
57002
57004
  const transformationHasTranslate = (transformation == null ? void 0 : transformation.translate) !== void 0;
57003
57005
  const stripBodyTranslateOnly = didLiftAnimate || transformationHasTranslate;
57006
+ const liftedAnimateIsAutoOriented = didLiftAnimate && needsOriginOnOuter(((_b = node.animate) == null ? void 0 : _b.transform) || void 0) || didLiftAnimate && needsOriginOnOuter(((_c = out.animate) == null ? void 0 : _c.transform) || void 0);
57004
57007
  if (typeof node.transform === "string") {
57005
57008
  const split = splitTransformString(node.transform);
57006
57009
  if (stripBodyTranslateOnly) {
@@ -57009,6 +57012,8 @@ ${codeFrame}` : message);
57009
57012
  else delete node.transform;
57010
57013
  } else if (isPureTranslateBody(node.transform)) {
57011
57014
  delete node.transform;
57015
+ } else if (liftedAnimateIsAutoOriented && isSingleMatrixBody(node.transform)) {
57016
+ delete node.transform;
57012
57017
  }
57013
57018
  } else if (split.translate) {
57014
57019
  out.transform = split.translate;
@@ -57018,6 +57023,17 @@ ${codeFrame}` : message);
57018
57023
  }
57019
57024
  return out;
57020
57025
  }
57026
+ function isSingleMatrixBody(s) {
57027
+ const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
57028
+ let count = 0;
57029
+ let isMatrix = false;
57030
+ let m;
57031
+ while (m = re.exec(s)) {
57032
+ count++;
57033
+ if (m[1] === "matrix") isMatrix = true;
57034
+ }
57035
+ return count === 1 && isMatrix;
57036
+ }
57021
57037
  function isPureTranslateBody(s) {
57022
57038
  const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
57023
57039
  const ops = [];
@@ -57099,280 +57115,6 @@ ${codeFrame}` : message);
57099
57115
  }
57100
57116
  return false;
57101
57117
  }
57102
- function genId(ctx, prefix) {
57103
- return "_lw_" + prefix + "_" + ctx.nextId++;
57104
- }
57105
- function indexById(node, map) {
57106
- var _a;
57107
- if (typeof node.id === "string") map.set(node.id, node);
57108
- (_a = node.children) == null ? void 0 : _a.forEach((child) => indexById(child, map));
57109
- }
57110
- function spliceDefs(root, defs) {
57111
- if (!defs.length) return;
57112
- const existing = root.children || (root.children = []);
57113
- existing.unshift({ type: "defs", children: defs });
57114
- }
57115
- function clone(value) {
57116
- if (value === null || typeof value !== "object") return value;
57117
- if (Array.isArray(value)) return value.map(clone);
57118
- const out = {};
57119
- for (const k of Object.keys(value)) out[k] = clone(value[k]);
57120
- return out;
57121
- }
57122
- function regenerateIdsInClone(root, ctx) {
57123
- const oldToNew = /* @__PURE__ */ new Map();
57124
- const walkAssign = (n) => {
57125
- var _a;
57126
- if (typeof n.id === "string") {
57127
- const newId = genId(ctx, "retimed");
57128
- oldToNew.set(n.id, newId);
57129
- n.id = newId;
57130
- }
57131
- (_a = n.children) == null ? void 0 : _a.forEach(walkAssign);
57132
- };
57133
- walkAssign(root);
57134
- const rewriteUrl = (s) => s.replace(/url\(#([^)]+)\)/g, (m, oldId) => {
57135
- const newId = oldToNew.get(oldId);
57136
- return newId ? "url(#" + newId + ")" : m;
57137
- });
57138
- const walkRewrite = (n) => {
57139
- var _a;
57140
- if (typeof n.href === "string" && n.href.startsWith("#")) {
57141
- const newId = oldToNew.get(n.href.slice(1));
57142
- if (newId) n.href = "#" + newId;
57143
- }
57144
- for (const k of Object.keys(n)) {
57145
- if (k === "children" || k === "effects" || k === "meta" || k === "href" || k === "id") continue;
57146
- const v = n[k];
57147
- if (typeof v === "string" && v.indexOf("url(#") !== -1) n[k] = rewriteUrl(v);
57148
- }
57149
- (_a = n.children) == null ? void 0 : _a.forEach(walkRewrite);
57150
- };
57151
- walkRewrite(root);
57152
- return oldToNew;
57153
- }
57154
- function applyMaskedByEffect(node, fx, transformation, ctx) {
57155
- if (!fx) return node;
57156
- if (!fx.href) {
57157
- ctx.errors.push("maskedBy.href missing \u2014 cannot build mask");
57158
- return node;
57159
- }
57160
- const maskId = genId(ctx, "mask");
57161
- let content = { type: "use", href: "#" + fx.href };
57162
- content = wrapInverseTransform(content, transformation, ctx);
57163
- const mask = { type: "mask", id: maskId, children: [content] };
57164
- if (fx.maskType) mask.maskType = fx.maskType;
57165
- if (fx.maskUnits) mask.maskUnits = fx.maskUnits;
57166
- if (fx.maskContentUnits) mask.maskContentUnits = fx.maskContentUnits;
57167
- ctx.defs.push(mask);
57168
- node.mask = "url(#" + maskId + ")";
57169
- return node;
57170
- }
57171
- function wrapInverseTransform(inner, fx, ctx) {
57172
- if (!fx) return inner;
57173
- const origin = readStaticOrigin(fx.origin, ctx);
57174
- let n = inner;
57175
- n = wrapInversePart(n, "translate", fx.translate, void 0, ctx);
57176
- n = wrapInversePart(n, "rotate", fx.rotate, origin, ctx);
57177
- n = wrapInversePart(n, "scale", fx.scale, origin, ctx);
57178
- return n;
57179
- }
57180
- function wrapInversePart(inner, part, raw, origin, ctx) {
57181
- if (raw === void 0) return inner;
57182
- const v = readAnimatable(raw);
57183
- if (v.kind === "static") {
57184
- return { type: "g", transform: { value: partsRecord(part, invertPartValue(part, v.value), origin) }, children: [inner] };
57185
- }
57186
- if (v.kind === "animated") {
57187
- return {
57188
- type: "g",
57189
- animate: { transform: { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, invertPartValue(part, kf.value), origin))) } },
57190
- children: [inner]
57191
- };
57192
- }
57193
- return inner;
57194
- }
57195
- function invertPartValue(part, value) {
57196
- if (part === "translate") return [-value[0], -value[1]];
57197
- if (part === "rotate") return -value;
57198
- return [1 / value[0], 1 / value[1]];
57199
- }
57200
- var CONTENT_SUBREF = "content";
57201
- function applyRefAndTransformationEffect(node, ref3, transformation, ctx) {
57202
- if (ref3) {
57203
- const baseId = ref3.baseId;
57204
- if (!baseId) {
57205
- ctx.errors.push("ref: missing baseId");
57206
- } else {
57207
- const targetId = ref3.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(baseId) || baseId : baseId;
57208
- node.href = "#" + targetId;
57209
- }
57210
- }
57211
- return applyTransformationEffect(node, transformation, ctx);
57212
- }
57213
- function applyRepeaterEffect(node, fx, ctx) {
57214
- var _a, _b;
57215
- if (!fx) return node;
57216
- const copies = (_a = fx.copies) != null ? _a : 1;
57217
- if (copies < 1) {
57218
- ctx.errors.push("repeater.copies invalid: " + fx.copies);
57219
- return node;
57220
- }
57221
- const sharedTransform = node.transform;
57222
- const sharedAnimTransform = (_b = node.animate) == null ? void 0 : _b.transform;
57223
- const base = clone(node);
57224
- delete base.transform;
57225
- if (base.animate) {
57226
- delete base.animate.transform;
57227
- if (Object.keys(base.animate).length === 0) delete base.animate;
57228
- }
57229
- const children = [base];
57230
- for (let i = 1; i < copies; i++) {
57231
- const copy = clone(base);
57232
- copy.transform = { value: perCopyParts(fx, i) };
57233
- children.push(copy);
57234
- }
57235
- const wrapper = { type: "g", children };
57236
- if (sharedTransform !== void 0) wrapper.transform = sharedTransform;
57237
- if (sharedAnimTransform !== void 0) wrapper.animate = { transform: sharedAnimTransform };
57238
- return wrapper;
57239
- }
57240
- function perCopyParts(fx, i) {
57241
- const parts = {};
57242
- if (fx.translate) parts.translate = [fx.translate[0] * i, fx.translate[1] * i];
57243
- if (fx.rotate !== void 0) parts.rotate = fx.rotate * i;
57244
- if (fx.scale) parts.scale = [__pow(fx.scale[0] / 100, i), __pow(fx.scale[1] / 100, i)];
57245
- if (fx.origin) parts.origin = [fx.origin[0] * i, fx.origin[1] * i];
57246
- return parts;
57247
- }
57248
- var RETIME_AS_SYMBOL = true;
57249
- function applyRetimeEffect(node, retime, ctx) {
57250
- var _a, _b, _c, _d;
57251
- if (!retime) return node;
57252
- const baseId = retime.baseId;
57253
- if (!baseId) {
57254
- ctx.errors.push("retime: missing baseId");
57255
- return node;
57256
- }
57257
- const target = ctx.idMap.get(baseId);
57258
- if (!target) {
57259
- ctx.warnings.push('retime: target "' + baseId + '" not found');
57260
- return node;
57261
- }
57262
- const start = (_a = retime.start) != null ? _a : 0;
57263
- const stretch = (_b = retime.stretch) != null ? _b : 1;
57264
- if (RETIME_AS_SYMBOL) {
57265
- const symbolClone = clone(target);
57266
- regenerateIdsInClone(symbolClone, ctx);
57267
- const cloneId = genId(ctx, "retime");
57268
- symbolClone.id = cloneId;
57269
- remapKeyframeTimes(symbolClone, start, stretch);
57270
- ctx.defs.push(symbolClone);
57271
- node.href = "#" + cloneId;
57272
- return node;
57273
- }
57274
- const sourceNodes = target.type === "symbol" ? target.children || [] : [target];
57275
- const content = sourceNodes.map((child) => {
57276
- const c = clone(child);
57277
- regenerateIdsInClone(c, ctx);
57278
- remapKeyframeTimes(c, start, stretch);
57279
- return c;
57280
- });
57281
- const g = __spreadProps(__spreadValues({}, node), { type: "g", children: content });
57282
- delete g.href;
57283
- const x = Number((_c = node.x) != null ? _c : 0), y = Number((_d = node.y) != null ? _d : 0);
57284
- if (x || y) {
57285
- const offset = "translate(" + x + "," + y + ")";
57286
- g.transform = typeof g.transform === "string" ? offset + g.transform : offset;
57287
- delete g.x;
57288
- delete g.y;
57289
- }
57290
- return g;
57291
- }
57292
- function remapKeyframeTimes(node, start, stretch) {
57293
- var _a;
57294
- const remap2 = (kfs) => {
57295
- for (const kf of kfs) if (typeof kf.time === "number") kf.time = start + kf.time * stretch;
57296
- };
57297
- if (node.transform && typeof node.transform === "object" && Array.isArray(node.transform.keyframes)) {
57298
- remap2(node.transform.keyframes);
57299
- }
57300
- if (node.animate && typeof node.animate === "object") {
57301
- for (const prop of Object.keys(node.animate)) {
57302
- const anim = node.animate[prop];
57303
- if (anim && Array.isArray(anim.keyframes)) remap2(anim.keyframes);
57304
- }
57305
- }
57306
- (_a = node.children) == null ? void 0 : _a.forEach((child) => remapKeyframeTimes(child, start, stretch));
57307
- }
57308
- function applyTrimPathEffect(node, trimPath, isCombinedShape) {
57309
- var _a;
57310
- if (!trimPath && !isCombinedShape) return node;
57311
- const d = (_a = node.d) != null ? _a : rectToPathD(node);
57312
- if (d === void 0) return node;
57313
- const g = __spreadProps(__spreadValues({}, node), { type: "g" });
57314
- delete g.d;
57315
- const meta = g.meta = __spreadValues({}, g.meta || {});
57316
- const effects = meta.effects = __spreadValues({}, meta.effects || {});
57317
- if (trimPath) effects.trimPath = trimPath;
57318
- effects.isCombinedShape = true;
57319
- g.children = [{ type: "path", d }];
57320
- return g;
57321
- }
57322
- function rectToPathD(node) {
57323
- var _a, _b, _c, _d;
57324
- if (node.type !== "rect") return void 0;
57325
- const x = Number((_a = node.x) != null ? _a : 0), y = Number((_b = node.y) != null ? _b : 0);
57326
- const w = Number((_c = node.width) != null ? _c : 0), h3 = Number((_d = node.height) != null ? _d : 0);
57327
- return "M" + (x + w) + "," + y + "L" + (x + w) + "," + (y + h3) + "L" + x + "," + (y + h3) + "L" + x + "," + y + "L" + (x + w) + "," + y + "z";
57328
- }
57329
- function applyPlayerEffects(root) {
57330
- const ctx = {
57331
- defs: [],
57332
- warnings: [],
57333
- errors: [],
57334
- idMap: /* @__PURE__ */ new Map(),
57335
- nextId: 0,
57336
- contentRefInnerIds: /* @__PURE__ */ new Map()
57337
- };
57338
- const working = clone(root);
57339
- indexById(working, ctx.idMap);
57340
- identifyContentRefTargets(working, ctx, () => genId(ctx, "inner"));
57341
- const afterPass1 = applyPlayerEffects_exceptRetime(working, ctx);
57342
- const out = applyPlayerEffects_retime(afterPass1, ctx);
57343
- spliceDefs(out, ctx.defs);
57344
- return { root: out, defs: ctx.defs, warnings: ctx.warnings, errors: ctx.errors };
57345
- }
57346
- function applyPlayerEffects_exceptRetime(node, ctx) {
57347
- if (node.children) node.children = node.children.map((child) => applyPlayerEffects_exceptRetime(child, ctx));
57348
- const fx = node.effects;
57349
- const originalId = typeof node.id === "string" ? node.id : void 0;
57350
- const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
57351
- if (!fx && !innerIdForContentRef) return node;
57352
- const { transformation, repeater, maskedBy, trimPath, retime, ref: ref3 } = fx != null ? fx : {};
57353
- const isCombinedShape = fx == null ? void 0 : fx.isCombinedShape;
57354
- if (fx) delete node.effects;
57355
- let n = node;
57356
- n = applyTrimPathEffect(n, trimPath, isCombinedShape);
57357
- n = applyRepeaterEffect(n, repeater, ctx);
57358
- n = applyMaskedByEffect(n, maskedBy, transformation, ctx);
57359
- if (innerIdForContentRef) {
57360
- n = splitForContentRef(n, transformation, originalId, innerIdForContentRef, ctx);
57361
- } else {
57362
- n = applyRefAndTransformationEffect(n, ref3, transformation, ctx);
57363
- }
57364
- if (retime) node.effects = { retime };
57365
- if (originalId) ctx.idMap.set(originalId, n);
57366
- return n;
57367
- }
57368
- function applyPlayerEffects_retime(node, ctx) {
57369
- var _a;
57370
- if (node.children) node.children = node.children.map((child) => applyPlayerEffects_retime(child, ctx));
57371
- const retime = (_a = node.effects) == null ? void 0 : _a.retime;
57372
- if (!retime) return node;
57373
- delete node.effects;
57374
- return applyRetimeEffect(node, retime, ctx);
57375
- }
57376
57118
  function pathStr(path) {
57377
57119
  if (!path.length) return ".";
57378
57120
  let result = "";
@@ -57815,6 +57557,15 @@ ${codeFrame}` : message);
57815
57557
  };
57816
57558
  var PX_ANIM_SRC_ATTR_NAME = "data-px-animation-src";
57817
57559
  var PX_ANIM_ATTR_NAME = "_px_animator";
57560
+ var PxAnimatorMode = {
57561
+ auto: "auto",
57562
+ webapi: "webapi",
57563
+ frames: "frames"
57564
+ };
57565
+ var PxAnimatorEngine = {
57566
+ webapi: PxAnimatorMode.webapi,
57567
+ frames: PxAnimatorMode.frames
57568
+ };
57818
57569
  var TEXT_ATTR = "text";
57819
57570
  var TEXT_CONTENT_ATTR = "textContent";
57820
57571
  var INTERNAL_ATTRS = /* @__PURE__ */ new Set([
@@ -57896,7 +57647,7 @@ ${codeFrame}` : message);
57896
57647
  styles: px.record(px.any()).optional()
57897
57648
  }));
57898
57649
  var PxAnimatorConfigSchema = implementsInterface()(px.object({
57899
- mode: px.enum(["auto", "webapi", "frames"]).optional(),
57650
+ mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.webapi, PxAnimatorMode.frames]).optional(),
57900
57651
  duration: px.number().optional(),
57901
57652
  delay: px.number().optional(),
57902
57653
  iterations: px.union([px.number(), px.literal("infinite")]).optional(),
@@ -57935,47 +57686,87 @@ ${codeFrame}` : message);
57935
57686
  autoOrient: px.boolean().optional()
57936
57687
  })
57937
57688
  ]);
57938
- var PxTransformationEffectSchema = px.object({
57689
+ var PxTransformationEffectSchema = implementsInterface()(px.object({
57939
57690
  translate: PxAnimatableVec2Schema.optional(),
57940
57691
  rotate: PxAnimatableNumberSchema.optional(),
57941
57692
  scale: PxAnimatableVec2Schema.optional(),
57942
57693
  skew: PxAnimatableVec2Schema.optional(),
57943
57694
  origin: PxAnimatableVec2Schema.optional()
57944
- });
57945
- var PxRepeaterEffectSchema = px.object({
57695
+ }));
57696
+ var PxRepeaterEffectSchema = implementsInterface()(px.object({
57946
57697
  copies: px.number().optional(),
57947
- translate: px.tuple([px.number(), px.number()]).optional(),
57948
- rotate: px.number().optional(),
57949
- scale: px.tuple([px.number(), px.number()]).optional(),
57950
- // per-copy scale, PERCENT (85 → 0.85)
57951
- origin: px.tuple([px.number(), px.number()]).optional()
57952
- });
57953
- var PxMaskedByEffectSchema = px.object({
57698
+ translate: PxAnimatableVec2Schema.optional(),
57699
+ rotate: PxAnimatableNumberSchema.optional(),
57700
+ scale: PxAnimatableVec2Schema.optional(),
57701
+ origin: PxAnimatableVec2Schema.optional()
57702
+ }));
57703
+ var PxMaskedByEffectSchema = implementsInterface()(px.object({
57954
57704
  href: px.string().optional(),
57955
57705
  maskType: px.string().optional(),
57956
57706
  maskUnits: px.string().optional(),
57957
57707
  maskContentUnits: px.string().optional()
57958
- });
57959
- var PxTrimPathEffectSchema = px.any();
57960
- var PxRetimeEffectSchema = px.object({
57708
+ }));
57709
+ var PxTrimPathEffectSchema = implementsInterface()(px.object({
57710
+ offset: PxAnimatableNumberSchema.optional(),
57711
+ range: PxAnimatableVec2Schema.optional(),
57712
+ trimAllAsOne: px.boolean().optional()
57713
+ }));
57714
+ var PxRetimeEffectSchema = implementsInterface()(px.object({
57961
57715
  baseId: px.string().optional(),
57962
57716
  start: px.number().optional(),
57963
57717
  stretch: px.number().optional(),
57964
57718
  timeCrop: px.tuple([px.number(), px.number()]).optional()
57965
- });
57966
- var PxRefEffectSchema = px.object({
57719
+ }));
57720
+ var PxRefEffectSchema = implementsInterface()(px.object({
57967
57721
  baseId: px.string().optional(),
57968
57722
  type: px.string().optional()
57969
- });
57970
- var PxEffectsSchema = px.object({
57723
+ }));
57724
+ var PxGradientType = {
57725
+ linear: "linear",
57726
+ radial: "radial"
57727
+ };
57728
+ var PxGradientStopSchema = implementsInterface()(px.object({
57729
+ offset: px.number(),
57730
+ color: px.string()
57731
+ }));
57732
+ var PxAnimatableGradientStopsSchema = px.union([
57733
+ px.array(PxGradientStopSchema),
57734
+ px.object({ value: px.array(PxGradientStopSchema) }),
57735
+ px.object({ keyframes: px.array(PxKeyframeSchema) })
57736
+ ]);
57737
+ var PxFillGradientEffectSchema = implementsInterface()(px.object({
57738
+ type: px.enum([PxGradientType.linear, PxGradientType.radial]),
57739
+ p1: px.tuple([px.number(), px.number()]).optional(),
57740
+ p2: px.tuple([px.number(), px.number()]).optional(),
57741
+ c: px.tuple([px.number(), px.number()]).optional(),
57742
+ r: px.number().optional(),
57743
+ fp: px.tuple([px.number(), px.number()]).optional(),
57744
+ stops: PxAnimatableGradientStopsSchema.optional(),
57745
+ gradientUnits: px.string().optional(),
57746
+ spreadMethod: px.string().optional(),
57747
+ gradientTransform: px.string().optional()
57748
+ }));
57749
+ var PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;
57750
+ var PxTextAlongPathEffectSchema = implementsInterface()(px.object({
57751
+ href: px.string(),
57752
+ lengthAdjust: px.string().optional(),
57753
+ method: px.string().optional(),
57754
+ spacing: px.string().optional(),
57755
+ startOffset: PxAnimatableNumberSchema.optional(),
57756
+ textLength: PxAnimatableNumberSchema.optional()
57757
+ }));
57758
+ var PxEffectsSchema = implementsInterface()(px.object({
57971
57759
  transformation: PxTransformationEffectSchema.optional(),
57972
57760
  repeater: PxRepeaterEffectSchema.optional(),
57973
57761
  maskedBy: PxMaskedByEffectSchema.optional(),
57974
57762
  trimPath: PxTrimPathEffectSchema.optional(),
57975
57763
  retime: PxRetimeEffectSchema.optional(),
57976
57764
  isCombinedShape: px.boolean().optional(),
57977
- ref: PxRefEffectSchema.optional()
57978
- });
57765
+ ref: PxRefEffectSchema.optional(),
57766
+ fillGradient: PxFillGradientEffectSchema.optional(),
57767
+ strokeGradient: PxStrokeGradientEffectSchema.optional(),
57768
+ textAlongPath: PxTextAlongPathEffectSchema.optional()
57769
+ }));
57979
57770
  function validateNodeEffects(root, opts) {
57980
57771
  const warnings = [];
57981
57772
  const walk = (node, path) => {
@@ -58001,7 +57792,10 @@ ${codeFrame}` : message);
58001
57792
  // Consumed and removed by `applyPlayerEffects` before any other normalisation
58002
57793
  // (see `createAnimatorImpl`), so downstream code never sees it.
58003
57794
  effects: PxEffectsSchema.optional(),
58004
- animate: PxAnimationDefinitionSchema.optional(),
57795
+ // `PxElementAnimation` (not just `PxAnimationDefinition`) — accepts
57796
+ // string ref / array of refs / inline definition / mixed array; mirrors
57797
+ // `animator.animate` map values and what `processNode` resolves at runtime.
57798
+ animate: PxElementAnimationSchema.optional(),
58005
57799
  style: px.union([px.string(), px.record(px.union([px.string(), px.number()]))]).optional()
58006
57800
  }, PxAttrValueSchema);
58007
57801
  var PxNodeSchema = px.openObject(__spreadProps(__spreadValues({}, PxNodeBase._shape), {
@@ -58046,768 +57840,1558 @@ ${codeFrame}` : message);
58046
57840
  if (!animate) return void 0;
58047
57841
  return Object.entries(animate).map(([id, anim]) => ({ id, animate: anim }));
58048
57842
  }
58049
- function bezierToSvgPath(path) {
58050
- var _a, _b, _c, _d;
58051
- const v = path.v;
58052
- const i = path.i;
58053
- const o = path.o;
58054
- const c = path.c;
58055
- if (!v.length) return "";
58056
- const d = [];
58057
- const len = v.length;
58058
- d.push("M" + v[0][0] + "," + v[0][1]);
58059
- for (let idx = 1; idx < len; idx++) {
58060
- const prevV = v[idx - 1];
58061
- const prevO = (_a = o == null ? void 0 : o[idx - 1]) != null ? _a : prevV;
58062
- const currI = (_b = i == null ? void 0 : i[idx]) != null ? _b : v[idx];
58063
- const currV = v[idx];
58064
- const isLine = prevO[0] === prevV[0] && prevO[1] === prevV[1] && (currI[0] === currV[0] && currI[1] === currV[1]);
58065
- if (isLine) {
58066
- d.push("L" + currV[0] + "," + currV[1]);
58067
- } else {
58068
- d.push("C" + prevO[0] + "," + prevO[1] + "," + currI[0] + "," + currI[1] + "," + currV[0] + "," + currV[1]);
57843
+ function deepClonePxNode(value) {
57844
+ if (value === null || typeof value !== "object") return value;
57845
+ if (Array.isArray(value)) return value.map(deepClonePxNode);
57846
+ const out = {};
57847
+ for (const k of Object.keys(value)) out[k] = deepClonePxNode(value[k]);
57848
+ return out;
57849
+ }
57850
+ function regenerateIdsAndRewriteRefs(root, genId3) {
57851
+ const oldToNew = /* @__PURE__ */ new Map();
57852
+ const walkAssign = (n) => {
57853
+ var _a;
57854
+ if (typeof n.id === "string") {
57855
+ const newId = genId3();
57856
+ oldToNew.set(n.id, newId);
57857
+ n.id = newId;
58069
57858
  }
58070
- }
58071
- if (c && len > 0) {
58072
- const lastV = v[len - 1];
58073
- const lastO = (_c = o == null ? void 0 : o[len - 1]) != null ? _c : lastV;
58074
- const firstI = (_d = i == null ? void 0 : i[0]) != null ? _d : v[0];
58075
- const firstV = v[0];
58076
- const isLine = lastO[0] === lastV[0] && lastO[1] === lastV[1] && (firstI[0] === firstV[0] && firstI[1] === firstV[1]);
58077
- if (!isLine) {
58078
- d.push("C" + lastO[0] + "," + lastO[1] + "," + firstI[0] + "," + firstI[1] + "," + firstV[0] + "," + firstV[1]);
57859
+ (_a = n.children) == null ? void 0 : _a.forEach(walkAssign);
57860
+ };
57861
+ walkAssign(root);
57862
+ const rewriteUrl = (s) => s.replace(/url\(#([^)]+)\)/g, (m, oldId) => {
57863
+ const newId = oldToNew.get(oldId);
57864
+ return newId ? "url(#" + newId + ")" : m;
57865
+ });
57866
+ const walkRewrite = (n) => {
57867
+ var _a;
57868
+ if (typeof n.href === "string" && n.href.startsWith("#")) {
57869
+ const newId = oldToNew.get(n.href.slice(1));
57870
+ if (newId) n.href = "#" + newId;
58079
57871
  }
58080
- d.push("z");
58081
- }
58082
- return d.join("");
57872
+ for (const k of Object.keys(n)) {
57873
+ if (k === "children" || k === "effects" || k === "meta" || k === "animate" || k === "href" || k === "id") continue;
57874
+ const v = n[k];
57875
+ if (typeof v === "string" && v.indexOf("url(#") !== -1) {
57876
+ n[k] = rewriteUrl(v);
57877
+ }
57878
+ }
57879
+ (_a = n.children) == null ? void 0 : _a.forEach(walkRewrite);
57880
+ };
57881
+ walkRewrite(root);
57882
+ return oldToNew;
58083
57883
  }
58084
- function interpolateNum(a, b, t) {
58085
- return a + (b - a) * t;
57884
+ function toFiniteNum(v) {
57885
+ const n = typeof v === "number" ? v : typeof v === "string" ? parseFloat(v) : NaN;
57886
+ return Number.isFinite(n) ? n : 0;
58086
57887
  }
58087
- function interpolateVec(a, b, t) {
58088
- const res = [];
58089
- const count = Math.max(a.length, b.length);
58090
- for (let i = 0; i < count; i++) {
58091
- res[i] = interpolateNum(a[i] || 0, b[i] || 0, t);
57888
+ function applyUseOffsetToG(gNode) {
57889
+ var _a;
57890
+ const x = toFiniteNum(gNode.x);
57891
+ const y = toFiniteNum(gNode.y);
57892
+ delete gNode.x;
57893
+ delete gNode.y;
57894
+ if (!x && !y) return gNode;
57895
+ const offset = "translate(" + x + "," + y + ")";
57896
+ const carriesTransform = gNode.transform !== void 0 || gNode.animate !== void 0;
57897
+ if (carriesTransform) {
57898
+ const inner = { type: "g", transform: offset, children: (_a = gNode.children) != null ? _a : [] };
57899
+ gNode.children = [inner];
57900
+ } else {
57901
+ gNode.transform = offset;
58092
57902
  }
58093
- return res;
57903
+ return gNode;
58094
57904
  }
58095
- function interpolateColor(a, b, t) {
58096
- return [
58097
- interpolateNum(a[0] || 0, b[0] || 0, t),
58098
- interpolateNum(a[1] || 0, b[1] || 0, t),
58099
- interpolateNum(a[2] || 0, b[2] || 0, t),
58100
- interpolateNum(a[3] === void 0 ? 1 : a[3], b[3] === void 0 ? 1 : b[3], t)
58101
- ];
57905
+ function genId(ctx, prefix) {
57906
+ return "_lw_" + prefix + "_" + ctx.nextId++;
58102
57907
  }
58103
- function interpolateBeziers(paths1, paths2, progress) {
58104
- const count = Math.max(paths1.length, paths2.length);
58105
- const res = [];
58106
- for (let i = 0; i < count; i++) {
58107
- res.push(interpolateBezier(paths1[i], paths2[i], progress));
58108
- }
58109
- return res;
57908
+ function stripHash(href) {
57909
+ return typeof href === "string" ? href.replace(/^#/, "") : void 0;
58110
57910
  }
58111
- function interpolateBezier(path1, path2, progress) {
58112
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
58113
- if (!path1 || !path2) return path1 || path2 || { v: [] };
58114
- const t = Math.min(Math.max(progress, 0), 1);
58115
- const len = Math.min(path1.v.length, path2.v.length);
58116
- const v = [];
58117
- const i = [];
58118
- const o = [];
58119
- for (let idx = 0; idx < len; idx++) {
58120
- const v1 = path1.v[idx];
58121
- const v2 = path2.v[idx];
58122
- v.push(interpolateVec(v1, v2, t));
58123
- const i1 = (_b = (_a = path1.i) == null ? void 0 : _a[idx]) != null ? _b : v1;
58124
- const i2 = (_d = (_c = path2.i) == null ? void 0 : _c[idx]) != null ? _d : v2;
58125
- i.push(interpolateVec(i1, i2, t));
58126
- const o1 = (_f = (_e = path1.o) == null ? void 0 : _e[idx]) != null ? _f : v1;
58127
- const o2 = (_h = (_g = path2.o) == null ? void 0 : _g[idx]) != null ? _h : v2;
58128
- o.push(interpolateVec(o1, o2, t));
58129
- }
58130
- return { v, i: i.length ? i : void 0, o: o.length ? o : void 0, c: (_i = path1.c) != null ? _i : path2.c };
57911
+ function indexById(node, map) {
57912
+ var _a;
57913
+ if (typeof node.id === "string") map.set(node.id, node);
57914
+ (_a = node.children) == null ? void 0 : _a.forEach((child) => indexById(child, map));
58131
57915
  }
58132
- function remap(value, inMin, inMax, outMin, outMax) {
58133
- if (inMax === inMin) return outMin;
58134
- const t = (value - inMin) / (inMax - inMin);
58135
- return outMin + t * (outMax - outMin);
57916
+ function spliceDefs(root, defs) {
57917
+ if (!defs.length) return;
57918
+ const existing = root.children || (root.children = []);
57919
+ existing.unshift({ type: "defs", children: defs });
58136
57920
  }
58137
- function solveCubicBezierX(p1x, p2x, x) {
58138
- if (x <= 0) return 0;
58139
- if (x >= 1) return 1;
58140
- const cx = 3 * p1x;
58141
- const bx = 3 * (p2x - p1x) - cx;
58142
- const ax = 1 - cx - bx;
58143
- function sampleX(t) {
58144
- return ((ax * t + bx) * t + cx) * t;
57921
+ var clone = deepClonePxNode;
57922
+ function regenerateIdsInClone(root, ctx) {
57923
+ return regenerateIdsAndRewriteRefs(root, () => genId(ctx, "retimed"));
57924
+ }
57925
+ function applyFillGradientEffect(node, fx, ctx) {
57926
+ return applyGradient(node, fx, ctx, "fill");
57927
+ }
57928
+ function applyStrokeGradientEffect(node, fx, ctx) {
57929
+ return applyGradient(node, fx, ctx, "stroke");
57930
+ }
57931
+ function applyGradient(node, fx, ctx, attr) {
57932
+ if (!fx) return node;
57933
+ const id = genId(ctx, "grad");
57934
+ const def = synthesiseGradientDef(fx, id, ctx);
57935
+ ctx.defs.push(def);
57936
+ node[attr] = "url(#" + id + ")";
57937
+ return node;
57938
+ }
57939
+ function synthesiseGradientDef(fx, id, ctx) {
57940
+ const out = {
57941
+ type: fx.type === PxGradientType.radial ? "radialGradient" : "linearGradient",
57942
+ id
57943
+ };
57944
+ if (fx.type === PxGradientType.linear) {
57945
+ if (fx.p1) {
57946
+ out.x1 = String(fx.p1[0]);
57947
+ out.y1 = String(fx.p1[1]);
57948
+ }
57949
+ if (fx.p2) {
57950
+ out.x2 = String(fx.p2[0]);
57951
+ out.y2 = String(fx.p2[1]);
57952
+ }
57953
+ } else {
57954
+ if (fx.c) {
57955
+ out.cx = String(fx.c[0]);
57956
+ out.cy = String(fx.c[1]);
57957
+ }
57958
+ if (fx.r !== void 0) out.r = String(fx.r);
57959
+ if (fx.fp) {
57960
+ out.fx = String(fx.fp[0]);
57961
+ out.fy = String(fx.fp[1]);
57962
+ }
58145
57963
  }
58146
- function sampleDX(t) {
58147
- return (3 * ax * t + 2 * bx) * t + cx;
57964
+ if (fx.gradientUnits) out.gradientUnits = fx.gradientUnits;
57965
+ if (fx.spreadMethod) out.spreadMethod = fx.spreadMethod;
57966
+ if (fx.gradientTransform) out.gradientTransform = fx.gradientTransform;
57967
+ out.children = buildStopChildren(fx.stops, ctx);
57968
+ return out;
57969
+ }
57970
+ function buildStopChildren(stops, ctx) {
57971
+ var _a, _b, _c, _d;
57972
+ if (!stops) return [];
57973
+ if (Array.isArray(stops)) return stops.map(staticStopNode);
57974
+ if (typeof stops === "object" && Array.isArray(stops.value)) {
57975
+ return stops.value.map(staticStopNode);
58148
57976
  }
58149
- let t2 = x;
58150
- let t0 = 0;
58151
- let t1 = 1;
58152
- for (let i = 0; i < 8; i++) {
58153
- const x2 = sampleX(t2) - x;
58154
- if (Math.abs(x2) < 1e-6) return t2;
58155
- const d2 = sampleDX(t2);
58156
- if (Math.abs(d2) < 1e-6) break;
58157
- t2 -= x2 / d2;
57977
+ const animBlock = stops;
57978
+ const kfs = animBlock.keyframes;
57979
+ if (!Array.isArray(kfs) || !kfs.length) return [];
57980
+ let stopCount = 0;
57981
+ for (const kf of kfs) {
57982
+ const v = (_a = kf.value) != null ? _a : kf.v;
57983
+ if (Array.isArray(v) && v.length > stopCount) stopCount = v.length;
58158
57984
  }
58159
- t2 = x;
58160
- while (t0 < t1) {
58161
- const x2 = sampleX(t2);
58162
- if (Math.abs(x2 - x) < 1e-6) return t2;
58163
- if (x > x2) t0 = t2;
58164
- else t1 = t2;
58165
- t2 = (t1 + t0) / 2;
57985
+ if (!stopCount) return [];
57986
+ const firstKfValue = (_b = kfs[0].value) != null ? _b : kfs[0].v;
57987
+ const baselineStops = [];
57988
+ for (let i = 0; i < stopCount; i++) {
57989
+ const s = (_d = (_c = firstKfValue == null ? void 0 : firstKfValue[i]) != null ? _c : prevDefinedStop(kfs, 0, i)) != null ? _d : { offset: i / Math.max(1, stopCount - 1), color: "#000000" };
57990
+ baselineStops.push({ offset: s.offset, color: s.color });
58166
57991
  }
58167
- return t2;
57992
+ return baselineStops.map((bs, i) => animatedStopNode(bs, kfs, i, ctx));
58168
57993
  }
58169
- function cubicBezier(easing) {
58170
- const [p1x, p1y, p2x, p2y] = easing;
58171
- const cy = 3 * p1y;
58172
- const by = 3 * (p2y - p1y) - cy;
58173
- const ay = 1 - cy - by;
58174
- function sampleCurveY(t) {
58175
- return ((ay * t + by) * t + cy) * t;
58176
- }
58177
- return function(x) {
58178
- return sampleCurveY(solveCubicBezierX(p1x, p2x, x));
57994
+ function staticStopNode(s) {
57995
+ return {
57996
+ type: "stop",
57997
+ offset: formatOffset(s.offset),
57998
+ stopColor: s.color
58179
57999
  };
58180
58000
  }
58181
- function lerp2(a, b, t) {
58182
- return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t];
58183
- }
58184
- function subdivideCubicBezier(p0, p1, p2, p3, t) {
58185
- const q0 = lerp2(p0, p1, t);
58186
- const q1 = lerp2(p1, p2, t);
58187
- const q2 = lerp2(p2, p3, t);
58188
- const r0 = lerp2(q0, q1, t);
58189
- const r1 = lerp2(q1, q2, t);
58190
- const s = lerp2(r0, r1, t);
58191
- return {
58192
- left: [p0, q0, r0, s],
58193
- right: [s, r1, q2, p3]
58001
+ function animatedStopNode(baseline, kfs, stopIdx, _ctx) {
58002
+ var _a, _b, _c, _d, _e;
58003
+ const colorKfs = [];
58004
+ const offsetKfs = [];
58005
+ let offsetVaries = false;
58006
+ for (const kf of kfs) {
58007
+ const t = (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
58008
+ const arr = (_c = kf.value) != null ? _c : kf.v;
58009
+ const sliced = (_d = arr == null ? void 0 : arr[stopIdx]) != null ? _d : prevDefinedStop(kfs, kfs.indexOf(kf), stopIdx);
58010
+ if (!sliced) continue;
58011
+ const easing = (_e = kf.easing) != null ? _e : kf.e;
58012
+ const colorOut = { time: t, value: sliced.color };
58013
+ if (easing !== void 0) colorOut.easing = easing;
58014
+ colorKfs.push(colorOut);
58015
+ const offsetOut = { time: t, value: sliced.offset };
58016
+ if (easing !== void 0) offsetOut.easing = easing;
58017
+ offsetKfs.push(offsetOut);
58018
+ if (sliced.offset !== baseline.offset) offsetVaries = true;
58019
+ }
58020
+ const stop = {
58021
+ type: "stop",
58022
+ offset: formatOffset(baseline.offset),
58023
+ stopColor: baseline.color
58194
58024
  };
58025
+ const animate = {};
58026
+ if (colorKfs.length) animate.stopColor = { keyframes: colorKfs };
58027
+ if (offsetVaries && offsetKfs.length) animate.offset = { keyframes: offsetKfs };
58028
+ if (Object.keys(animate).length) stop.animate = animate;
58029
+ return stop;
58195
58030
  }
58196
- function splitEasing(easing, xFraction) {
58197
- if (!easing) return { left: void 0, right: void 0 };
58198
- if (xFraction <= 0) return { left: void 0, right: easing };
58199
- if (xFraction >= 1) return { left: easing, right: void 0 };
58200
- const [x1, y1, x2, y2] = easing;
58201
- const t = solveCubicBezierX(x1, x2, xFraction);
58202
- const p0 = [0, 0];
58203
- const p1 = [x1, y1];
58204
- const p2 = [x2, y2];
58205
- const p3 = [1, 1];
58206
- const { left, right } = subdivideCubicBezier(p0, p1, p2, p3, t);
58207
- const sx = left[3][0];
58208
- const sy = left[3][1];
58209
- let leftEasing;
58210
- if (sx > 1e-9 && Math.abs(sy) > 1e-9) {
58211
- leftEasing = [
58212
- left[1][0] / sx,
58213
- left[1][1] / sy,
58214
- left[2][0] / sx,
58215
- left[2][1] / sy
58216
- ];
58031
+ function prevDefinedStop(kfs, fromIdx, stopIdx) {
58032
+ var _a, _b;
58033
+ for (let i = fromIdx; i >= 0; i--) {
58034
+ const arr = (_a = kfs[i].value) != null ? _a : kfs[i].v;
58035
+ if (arr == null ? void 0 : arr[stopIdx]) return arr[stopIdx];
58217
58036
  }
58218
- let rightEasing;
58219
- const rx = 1 - sx;
58220
- const ry = 1 - sy;
58221
- if (rx > 1e-9 && Math.abs(ry) > 1e-9) {
58222
- rightEasing = [
58223
- (right[1][0] - sx) / rx,
58224
- (right[1][1] - sy) / ry,
58225
- (right[2][0] - sx) / rx,
58226
- (right[2][1] - sy) / ry
58227
- ];
58037
+ for (let i = fromIdx + 1; i < kfs.length; i++) {
58038
+ const arr = (_b = kfs[i].value) != null ? _b : kfs[i].v;
58039
+ if (arr == null ? void 0 : arr[stopIdx]) return arr[stopIdx];
58228
58040
  }
58229
- return { left: leftEasing, right: rightEasing };
58041
+ return void 0;
58230
58042
  }
58231
- function reverseEasing(easing) {
58232
- if (!easing) return void 0;
58233
- return [1 - easing[2], 1 - easing[3], 1 - easing[0], 1 - easing[1]];
58043
+ function formatOffset(o) {
58044
+ const pct = Math.round(o * 1e3) / 10;
58045
+ return pct + "%";
58234
58046
  }
58235
- function toRGBA(color) {
58236
- const r = Math.round(color[0] * 255);
58237
- const g = Math.round(color[1] * 255);
58238
- const b = Math.round(color[2] * 255);
58239
- return color.length === 4 ? "rgba(" + r + "," + g + "," + b + "," + color[3] + ")" : "rgb(" + r + "," + g + "," + b + ")";
58047
+ function applyMaskedByEffect(node, fx, transformation, ctx) {
58048
+ if (!fx) return node;
58049
+ if (!fx.href) {
58050
+ ctx.errors.push("maskedBy.href missing \u2014 cannot build mask");
58051
+ return node;
58052
+ }
58053
+ const maskId = genId(ctx, "mask");
58054
+ let content = { type: "use", href: "#" + fx.href };
58055
+ if (transformation) {
58056
+ content = wrapInverseTransform(content, transformation, ctx);
58057
+ } else if (hasAnimateTransform(node)) {
58058
+ content = wrapInverseAnimatedBodyTransform(content, node, ctx);
58059
+ } else {
58060
+ const bodyStatic = readTransformationFromBody(node);
58061
+ if (bodyStatic) content = wrapInverseTransform(content, bodyStatic, ctx);
58062
+ }
58063
+ const includeTargetOwn = transformation === void 0 && !nodeHasBodyTransform(node);
58064
+ content = wrapAncestorChainCompensation(content, node, fx.href, ctx, includeTargetOwn);
58065
+ const mask = { type: "mask", id: maskId, children: [content] };
58066
+ if (fx.maskType) mask.maskType = fx.maskType;
58067
+ if (fx.maskUnits) mask.maskUnits = fx.maskUnits;
58068
+ if (fx.maskContentUnits) mask.maskContentUnits = fx.maskContentUnits;
58069
+ ctx.defs.push(mask);
58070
+ node.mask = "url(#" + maskId + ")";
58071
+ return node;
58240
58072
  }
58241
- function parseRgba(s) {
58242
- var _a;
58243
- const inner = (_a = s.match(/rgba?\((.*)\)/)) == null ? void 0 : _a[1];
58244
- if (!inner) throw new Error("Invalid rgb/rgba format");
58245
- const parts = inner.split(",").map((v) => +v.trim());
58246
- return [parts[0] / 255, parts[1] / 255, parts[2] / 255, ...parts[3] !== void 0 ? [parts[3]] : []];
58073
+ function wrapInverseTransform(inner, fx, ctx) {
58074
+ if (!fx) return inner;
58075
+ const origin = readStaticOrigin(fx.origin, ctx);
58076
+ let n = inner;
58077
+ n = wrapInversePart(n, "translate", fx.translate, void 0, ctx);
58078
+ n = wrapInversePart(n, "rotate", fx.rotate, origin, ctx);
58079
+ n = wrapInversePart(n, "scale", fx.scale, origin, ctx);
58080
+ return n;
58247
58081
  }
58248
- function parseHex(s) {
58249
- const hex = s.slice(1);
58250
- const isShort = hex.length <= 4;
58251
- const r = isShort ? hex[0] + hex[0] : hex.slice(0, 2);
58252
- const g = isShort ? hex[1] + hex[1] : hex.slice(2, 4);
58253
- const b = isShort ? hex[2] + hex[2] : hex.slice(4, 6);
58254
- const a = hex.length === 4 ? hex[3] + hex[3] : hex.length === 8 ? hex.slice(6, 8) : null;
58255
- const result = [
58256
- parseInt(r, 16) / 255,
58257
- parseInt(g, 16) / 255,
58258
- parseInt(b, 16) / 255
58259
- ];
58260
- if (a !== null) {
58261
- result.push(parseInt(a, 16) / 255);
58082
+ function wrapInversePart(inner, part, raw, origin, ctx) {
58083
+ if (raw === void 0) return inner;
58084
+ const normalisedRaw = part === "scale" && Array.isArray(raw) ? [raw[0] / 100, raw[1] / 100] : raw;
58085
+ const v = readAnimatable(normalisedRaw);
58086
+ if (v.kind === "static") {
58087
+ return { type: "g", transform: { value: partsRecord(part, invertPartValue(part, v.value), origin) }, children: [inner] };
58262
58088
  }
58263
- return result;
58264
- }
58265
- function parseColor(s) {
58266
- if (!s) return void 0;
58267
- if (Array.isArray(s)) return s;
58268
- if (typeof s !== "string") return void 0;
58269
- if (s.startsWith("#")) {
58270
- return parseHex(s);
58271
- } else if (s.startsWith("rgb")) {
58272
- return parseRgba(s);
58273
- } else {
58274
- console.warn("Unsupported color format: " + s);
58089
+ if (v.kind === "animated") {
58090
+ return {
58091
+ type: "g",
58092
+ animate: { transform: { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, invertPartValue(part, kf.value), origin))) } },
58093
+ children: [inner]
58094
+ };
58275
58095
  }
58276
- return void 0;
58277
- }
58278
- var COLOUR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
58279
- var TRANSFORM_FN_NAMES = /* @__PURE__ */ new Set(["translate", "rotate", "scale", "skew"]);
58280
- var PCT_BASED_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
58281
- function composeTransformParts(parts, opts) {
58282
- var _a;
58283
- if (!parts) return "";
58284
- const withUnits = (_a = opts == null ? void 0 : opts.withUnits) != null ? _a : true;
58285
- const segs = [];
58286
- const t = parts.translate;
58287
- const o = parts.origin;
58288
- const r = parts.rotate;
58289
- const s = parts.scale;
58290
- const tu = withUnits ? "px" : "";
58291
- const ru = withUnits ? "deg" : "";
58292
- if (t) segs.push("translate(" + t[0] + tu + "," + t[1] + tu + ")");
58293
- if (o) segs.push("translate(" + o[0] + tu + "," + o[1] + tu + ")");
58294
- if (r !== void 0 && r !== null) segs.push("rotate(" + r + ru + ")");
58295
- if (s) segs.push("scale(" + s[0] + "," + s[1] + ")");
58296
- if (o) segs.push("translate(" + -o[0] + tu + "," + -o[1] + tu + ")");
58297
- return segs.join("");
58298
- }
58299
- var STYLE_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
58300
- var DEFAULT_DURATION_MS = 1e3;
58301
- function kebabToCamelCaseWord(kebab) {
58302
- return kebab.includes("-") ? kebab.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()) : kebab;
58303
- }
58304
- function isCamelCaseWord(word) {
58305
- return !word.includes("-") && /[a-z][A-Z]/.test(word);
58306
- }
58307
- var SVG_CAMEL_CASE_ATTRS = /* @__PURE__ */ new Set([
58308
- // Transform/positioning
58309
- "viewBox",
58310
- "preserveAspectRatio",
58311
- // Gradient
58312
- "gradientUnits",
58313
- "gradientTransform",
58314
- "spreadMethod",
58315
- // Pattern
58316
- "patternUnits",
58317
- "patternContentUnits",
58318
- "patternTransform",
58319
- // Clipping/masking
58320
- "clipPathUnits",
58321
- "maskUnits",
58322
- "maskContentUnits",
58323
- // Text
58324
- "textLength",
58325
- "lengthAdjust",
58326
- "startOffset",
58327
- // Filter
58328
- "filterUnits",
58329
- "primitiveUnits",
58330
- "stdDeviation",
58331
- "baseFrequency",
58332
- "numOctaves",
58333
- "surfaceScale",
58334
- "diffuseConstant",
58335
- "specularConstant",
58336
- "specularExponent",
58337
- "kernelMatrix",
58338
- "kernelUnitLength",
58339
- "edgeMode",
58340
- "preserveAlpha",
58341
- "targetX",
58342
- "targetY"
58343
- // // Animation
58344
- // 'attributeName',
58345
- // 'attributeType',
58346
- // 'calcMode',
58347
- // 'keyTimes',
58348
- // 'keySplines',
58349
- // 'repeatCount',
58350
- // 'repeatDur'
58351
- ]);
58352
- function camelCaseToKebabWordIfNeeded(camel) {
58353
- return SVG_CAMEL_CASE_ATTRS.has(camel) ? camel : camel.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
58354
- }
58355
- function clamp(value, min, max) {
58356
- return Math.max(min, Math.min(value, max));
58096
+ return inner;
58357
58097
  }
58358
- function bezier2D_pointAt(P0, P1, P2, P3, t) {
58359
- if (t <= 0) return [P0[0], P0[1]];
58360
- if (t >= 1) return [P3[0], P3[1]];
58361
- const u = 1 - t;
58362
- const u2 = u * u;
58363
- const u3 = u2 * u;
58364
- const t2 = t * t;
58365
- const t3 = t2 * t;
58366
- const w0 = u3;
58367
- const w1 = 3 * t * u2;
58368
- const w2 = 3 * t2 * u;
58369
- const w3 = t3;
58370
- return [
58371
- w0 * P0[0] + w1 * P1[0] + w2 * P2[0] + w3 * P3[0],
58372
- w0 * P0[1] + w1 * P1[1] + w2 * P2[1] + w3 * P3[1]
58373
- ];
58098
+ function invertPartValue(part, value) {
58099
+ if (part === "translate") return [-value[0], -value[1]];
58100
+ if (part === "rotate") return -value;
58101
+ return [1 / value[0], 1 / value[1]];
58374
58102
  }
58375
- var BEZIER_T_NUDGE = 1e-4;
58376
- function bezier2D_derivativeAt(P0, P1, P2, P3, t) {
58377
- const result = _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t);
58378
- if (result[0] === 0 && result[1] === 0) {
58379
- const nudgedT = t < 0.5 ? t + BEZIER_T_NUDGE : t - BEZIER_T_NUDGE;
58380
- return _bezier2D_derivativeAtRaw(P0, P1, P2, P3, nudgedT);
58103
+ function wrapInverseAnimatedBodyTransform(inner, node, _ctx) {
58104
+ var _a;
58105
+ const animate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
58106
+ const animTr = animate == null ? void 0 : animate.transform;
58107
+ const kfs = animTr && typeof animTr === "object" && Array.isArray(animTr.keyframes) ? animTr.keyframes : void 0;
58108
+ if (!kfs || !kfs.length) return inner;
58109
+ const translateKfs = [];
58110
+ const rotateKfs = [];
58111
+ const scaleKfs = [];
58112
+ for (const kf of kfs) {
58113
+ const v = ((_a = kf.value) != null ? _a : kf.v) || {};
58114
+ const baseKf = keyframeWith(kf, void 0);
58115
+ if (Array.isArray(v.translate)) {
58116
+ translateKfs.push(__spreadProps(__spreadValues({}, baseKf), { value: { translate: [-v.translate[0], -v.translate[1]] } }));
58117
+ }
58118
+ if (typeof v.rotate === "number") {
58119
+ const rec = { rotate: -v.rotate };
58120
+ if (Array.isArray(v.origin)) rec.origin = [v.origin[0], v.origin[1]];
58121
+ rotateKfs.push(__spreadProps(__spreadValues({}, baseKf), { value: rec }));
58122
+ }
58123
+ if (Array.isArray(v.scale)) {
58124
+ const rec = { scale: [1 / v.scale[0], 1 / v.scale[1]] };
58125
+ if (Array.isArray(v.origin)) rec.origin = [v.origin[0], v.origin[1]];
58126
+ scaleKfs.push(__spreadProps(__spreadValues({}, baseKf), { value: rec }));
58127
+ }
58381
58128
  }
58382
- return result;
58129
+ let n = inner;
58130
+ if (translateKfs.length) n = { type: "g", animate: { transform: { keyframes: translateKfs } }, children: [n] };
58131
+ if (rotateKfs.length) n = { type: "g", animate: { transform: { keyframes: rotateKfs } }, children: [n] };
58132
+ if (scaleKfs.length) n = { type: "g", animate: { transform: { keyframes: scaleKfs } }, children: [n] };
58133
+ return n;
58383
58134
  }
58384
- function _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t) {
58385
- const u = 1 - t;
58386
- const a = 3 * u * u;
58387
- const b = 6 * t * u;
58388
- const c = 3 * t * t;
58389
- return [
58390
- a * (P1[0] - P0[0]) + b * (P2[0] - P1[0]) + c * (P3[0] - P2[0]),
58391
- a * (P1[1] - P0[1]) + b * (P2[1] - P1[1]) + c * (P3[1] - P2[1])
58392
- ];
58135
+ function nodeHasBodyTransform(node) {
58136
+ if (typeof node.transform === "string") return true;
58137
+ if (node.transform && typeof node.transform === "object") return true;
58138
+ return hasAnimateTransform(node);
58393
58139
  }
58394
- function bezier2D_arcLengthLUT(P0, P1, P2, P3, steps = 100) {
58395
- const n = steps + 1;
58396
- const ts = new Float64Array(n);
58397
- const ds = new Float64Array(n);
58398
- let prev = bezier2D_pointAt(P0, P1, P2, P3, 0);
58399
- ts[0] = 0;
58400
- ds[0] = 0;
58401
- let cum = 0;
58402
- for (let i = 1; i < n; i++) {
58403
- const t = i / steps;
58404
- const cur = bezier2D_pointAt(P0, P1, P2, P3, t);
58405
- const dx = cur[0] - prev[0];
58406
- const dy = cur[1] - prev[1];
58407
- cum += Math.sqrt(dx * dx + dy * dy);
58408
- ts[i] = t;
58409
- ds[i] = cum;
58410
- prev = cur;
58411
- }
58412
- return { ts, ds };
58140
+ function hasAnimateTransform(node) {
58141
+ const animate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
58142
+ return !!(animate && animate.transform);
58413
58143
  }
58414
- function bezier2D_tForDistance(lut, distance) {
58415
- const { ts, ds } = lut;
58416
- const last = ds.length - 1;
58417
- if (distance <= 0) return ts[0];
58418
- if (distance >= ds[last]) return ts[last];
58419
- let lo = 1;
58420
- let hi = last;
58421
- while (lo < hi) {
58422
- const mid = lo + hi >>> 1;
58423
- if (ds[mid] < distance) lo = mid + 1;
58424
- else hi = mid;
58144
+ function readTransformationFromBody(node) {
58145
+ if (typeof node.transform === "string") {
58146
+ const parts = parseTransformStringToParts(node.transform);
58147
+ if (!parts) return void 0;
58148
+ const out = {};
58149
+ if (parts.translate) out.translate = parts.translate;
58150
+ if (parts.rotate !== void 0) out.rotate = parts.rotate;
58151
+ if (parts.scale) out.scale = { value: parts.scale };
58152
+ if (parts.origin) out.origin = parts.origin;
58153
+ return Object.keys(out).length ? out : void 0;
58425
58154
  }
58426
- const dPrev = ds[hi - 1];
58427
- const dCur = ds[hi];
58428
- const span = dCur - dPrev;
58429
- const frac = span > 0 ? (distance - dPrev) / span : 0;
58430
- return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);
58155
+ return void 0;
58431
58156
  }
58432
- var SVG_NS = "http://www.w3.org/2000/svg";
58433
- var ALLOWED_SVG_TAGS_LOWER_CASE = new Set([
58434
- "svg",
58435
- "g",
58436
- "path",
58437
- "circle",
58438
- "ellipse",
58439
- "rect",
58440
- "line",
58441
- "polyline",
58442
- "polygon",
58443
- "text",
58444
- "tspan",
58445
- "textPath",
58446
- "defs",
58447
- "clipPath",
58448
- "mask",
58449
- "pattern",
58450
- "linearGradient",
58451
- "radialGradient",
58452
- "stop",
58453
- "use",
58454
- "symbol",
58455
- "marker",
58456
- "filter",
58457
- "feGaussianBlur",
58458
- "feOffset",
58459
- "feBlend",
58460
- "feColorMatrix",
58461
- "feMerge",
58462
- "feMergeNode"
58463
- ].map((tagName) => tagName.toLowerCase()));
58464
- var ALLOWED_RESOURCE_ATTRIBUTES = [
58465
- "href",
58466
- // <use>
58467
- "src",
58468
- // <image>
58469
- "filter",
58470
- // url(#filterId)
58471
- "clipPath",
58472
- // clip-path="url(#clipPathId)"
58473
- "mask",
58474
- // url(#maskId)
58475
- "markerStart",
58476
- // marker-start="url(#markerId)"
58477
- "markerMid",
58478
- // marker-mid="url(#markerId)"
58479
- "markerEnd"
58480
- // marker-end="url(#markerId)"
58481
- // 'fill', // url(#gradientId) or url(#patternId)
58482
- // 'stroke', // url(#gradientId) or url(#patternId)
58483
- // Don't allow 'cursor', can use external SVG, // url(cursor.svg)
58484
- ];
58485
- var ALLOWED_RESOURCE_ATTRIBUTES_SET = new Set(ALLOWED_RESOURCE_ATTRIBUTES);
58486
- var ALLOWED_ATTRIBUTES = [
58487
- "href",
58488
- "src",
58489
- // Presentation
58490
- "fill",
58491
- "fillOpacity",
58492
- "fillRule",
58493
- "stroke",
58494
- "strokeWidth",
58495
- "strokeOpacity",
58496
- "strokeLinecap",
58497
- "strokeLinejoin",
58498
- "strokeMiterlimit",
58499
- "strokeDasharray",
58500
- "strokeDashoffset",
58501
- "opacity",
58502
- "transform",
58503
- // Geometry
58504
- "x",
58505
- "y",
58506
- "cx",
58507
- "cy",
58508
- "r",
58509
- "rx",
58510
- "ry",
58511
- "width",
58512
- "height",
58513
- "d",
58514
- "x1",
58515
- "y1",
58516
- "x2",
58517
- "y2",
58518
- "points",
58519
- "dx",
58520
- "dy",
58521
- // Font
58522
- "fontSize",
58523
- "fontFamily",
58524
- "fontWeight",
58525
- "fontStyle",
58526
- // Text
58527
- "textAnchor",
58528
- "letterSpacing",
58529
- "wordSpacing",
58530
- "space",
58531
- "xml:space",
58532
- "textDecoration",
58533
- "textTransform",
58534
- "whiteSpace",
58535
- "white-space",
58536
- "dominantBaseline",
58537
- "alignmentBaseline",
58538
- "rotate",
58539
- // per-glyph rotation array, currently not supported
58540
- // Structure
58541
- "id",
58542
- "class",
58543
- "viewBox",
58544
- "preserveAspectRatio",
58545
- // Gradient/Pattern
58546
- "offset",
58547
- "stopColor",
58548
- "stopOpacity",
58549
- "gradientTransform",
58550
- // Clippath/Mask
58551
- "clipPath",
58552
- "mask",
58553
- // Motion path
58554
- "offsetPath",
58555
- "offsetDistance",
58556
- "offsetRotate",
58557
- "offsetAnchor",
58558
- "offsetPosition",
58559
- // Text path
58560
- "startOffset",
58561
- "textLength",
58562
- "lengthAdjust",
58563
- // Filter
58564
- "filter",
58565
- "stdDeviation",
58566
- "in",
58567
- "in2",
58568
- "result",
58569
- "mode",
58570
- ...ALLOWED_RESOURCE_ATTRIBUTES
58571
- ];
58572
- var ALLOWED_ATTRIBUTES_LOW_SET = new Set(ALLOWED_ATTRIBUTES.map((str) => str.toLowerCase()));
58573
- function sanitiseAttributeValue(name, value) {
58574
- const nameLower = name.toLowerCase();
58575
- if (!ALLOWED_ATTRIBUTES_LOW_SET.has(nameLower)) {
58576
- console.warn("Attribute not in whitelist: ", nameLower);
58577
- return void 0;
58157
+ function parseTransformStringToParts(s) {
58158
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
58159
+ const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
58160
+ let m;
58161
+ const ops = [];
58162
+ while ((m = re.exec(s)) !== null) {
58163
+ const args = m[2].split(/[\s,]+/).filter((a) => a.length > 0).map(Number);
58164
+ ops.push({ name: m[1], args });
58578
58165
  }
58579
- if (nameLower === "fill" || nameLower === "stroke" || nameLower === "stopColor") {
58580
- const str = String(value);
58581
- if (str.includes("url(") && !/^url\(#[^)]+\)$/.test(str)) {
58582
- console.warn('Attribute "' + nameLower + '" blocked: url() references must be internal url(#id), got:', value);
58583
- return void 0;
58166
+ if (!ops.length) return void 0;
58167
+ const last = ops[ops.length - 1];
58168
+ if (last.name === "translate") {
58169
+ for (let j = ops.length - 2; j >= 0; j--) {
58170
+ const cand = ops[j];
58171
+ if (cand.name !== "translate") continue;
58172
+ const ox = (_a = cand.args[0]) != null ? _a : 0;
58173
+ const oy = (_b = cand.args[1]) != null ? _b : 0;
58174
+ const lx = (_c = last.args[0]) != null ? _c : 0;
58175
+ const ly = (_d = last.args[1]) != null ? _d : 0;
58176
+ if (lx !== -ox || ly !== -oy) continue;
58177
+ const out2 = {};
58178
+ out2.origin = [ox, oy];
58179
+ for (let k = 0; k < j; k++) {
58180
+ if (ops[k].name === "translate") {
58181
+ const tx = (_e = ops[k].args[0]) != null ? _e : 0;
58182
+ const ty = (_f = ops[k].args[1]) != null ? _f : 0;
58183
+ out2.translate = out2.translate ? [out2.translate[0] + tx, out2.translate[1] + ty] : [tx, ty];
58184
+ }
58185
+ }
58186
+ for (let k = j + 1; k < ops.length - 1; k++) {
58187
+ const op = ops[k];
58188
+ if (op.name === "rotate") out2.rotate = ((_g = out2.rotate) != null ? _g : 0) + ((_h = op.args[0]) != null ? _h : 0);
58189
+ else if (op.name === "scale") {
58190
+ const sx = (_i = op.args[0]) != null ? _i : 1;
58191
+ const sy = op.args.length > 1 ? op.args[1] : sx;
58192
+ out2.scale = out2.scale ? [out2.scale[0] * sx, out2.scale[1] * sy] : [sx, sy];
58193
+ }
58194
+ }
58195
+ return out2;
58584
58196
  }
58585
- return value;
58586
58197
  }
58587
- if (ALLOWED_RESOURCE_ATTRIBUTES_SET.has(nameLower)) {
58588
- const str = String(value);
58589
- if (str.startsWith("#")) {
58590
- return value;
58591
- }
58592
- if (/^url\(#[^)]+\)$/.test(str)) {
58593
- return value;
58198
+ let translate;
58199
+ let rotate;
58200
+ let scale;
58201
+ for (const op of ops) {
58202
+ if (op.name === "translate") {
58203
+ const dx = (_j = op.args[0]) != null ? _j : 0;
58204
+ const dy = (_k = op.args[1]) != null ? _k : 0;
58205
+ translate = translate ? [translate[0] + dx, translate[1] + dy] : [dx, dy];
58206
+ } else if (op.name === "rotate") {
58207
+ rotate = (rotate != null ? rotate : 0) + ((_l = op.args[0]) != null ? _l : 0);
58208
+ } else if (op.name === "scale") {
58209
+ const sx = (_m = op.args[0]) != null ? _m : 1;
58210
+ const sy = op.args.length > 1 ? op.args[1] : sx;
58211
+ scale = scale ? [scale[0] * sx, scale[1] * sy] : [sx, sy];
58594
58212
  }
58595
- return void 0;
58596
58213
  }
58597
- return value;
58214
+ const out = {};
58215
+ if (translate) out.translate = translate;
58216
+ if (rotate !== void 0) out.rotate = rotate;
58217
+ if (scale) out.scale = scale;
58218
+ return Object.keys(out).length ? out : void 0;
58598
58219
  }
58599
- function createElement(tagName, normalisedProps, style, children, textContent) {
58600
- if (!ALLOWED_SVG_TAGS_LOWER_CASE.has(tagName.toLowerCase())) {
58601
- console.warn("Attribute not in whitelist: ", tagName);
58602
- return null;
58603
- }
58604
- const element = document.createElementNS(SVG_NS, tagName);
58605
- for (const propName in normalisedProps) {
58606
- element.setAttribute(
58607
- camelCaseToKebabWordIfNeeded(propName),
58608
- sanitiseAttributeValue(propName, normalisedProps[propName])
58609
- );
58220
+ function wrapAncestorChainCompensation(inner, maskedNode, sourceId, ctx, includeTargetOwn) {
58221
+ const sourceNode = ctx.idMap.get(sourceId);
58222
+ const targetAncestors = ctx.maskAncestorChains.get(maskedNode) || [];
58223
+ const targetOwn = includeTargetOwn ? extractTranslateOnly(maskedNode, ctx) : void 0;
58224
+ const targetChain = targetOwn ? [...targetAncestors, targetOwn] : targetAncestors;
58225
+ const sourceChain = sourceNode && ctx.maskAncestorChains.get(sourceNode) || [];
58226
+ if (!targetChain.length && !sourceChain.length) return inner;
58227
+ const times = /* @__PURE__ */ new Set();
58228
+ for (const a of targetChain) if (a.translateKeyframes) for (const kf of a.translateKeyframes) times.add(kf.time);
58229
+ for (const a of sourceChain) if (a.translateKeyframes) for (const kf of a.translateKeyframes) times.add(kf.time);
58230
+ const animated = times.size > 0;
58231
+ if (!animated) {
58232
+ const tgt = sumStaticTranslate(targetChain);
58233
+ const src = sumStaticTranslate(sourceChain);
58234
+ const dx = src[0] - tgt[0];
58235
+ const dy = src[1] - tgt[1];
58236
+ if (dx === 0 && dy === 0) return inner;
58237
+ return { type: "g", transform: "translate(" + dx + "," + dy + ")", children: [inner] };
58610
58238
  }
58611
- if (style) {
58612
- for (const styleProp in style) {
58613
- element.style[styleProp] = String(style[styleProp]);
58239
+ const sortedTimes = Array.from(times).sort((a, b) => a - b);
58240
+ const keyframes = sortedTimes.map((t) => {
58241
+ const tgt = sumTranslateAt(targetChain, t);
58242
+ const src = sumTranslateAt(sourceChain, t);
58243
+ return { time: t, value: { translate: [src[0] - tgt[0], src[1] - tgt[1]] } };
58244
+ });
58245
+ return { type: "g", animate: { transform: { keyframes } }, children: [inner] };
58246
+ }
58247
+ function sumStaticTranslate(chain) {
58248
+ let x = 0, y = 0;
58249
+ for (const a of chain) {
58250
+ if (a.translate) {
58251
+ x += a.translate[0];
58252
+ y += a.translate[1];
58614
58253
  }
58615
58254
  }
58616
- if (children) {
58617
- for (const child of children) {
58618
- element.appendChild(child);
58255
+ return [x, y];
58256
+ }
58257
+ function sumTranslateAt(chain, t) {
58258
+ let x = 0, y = 0;
58259
+ for (const a of chain) {
58260
+ if (a.translateKeyframes && a.translateKeyframes.length) {
58261
+ const v = interpKfs(a.translateKeyframes, t);
58262
+ x += v[0];
58263
+ y += v[1];
58264
+ } else if (a.translate) {
58265
+ x += a.translate[0];
58266
+ y += a.translate[1];
58619
58267
  }
58620
58268
  }
58621
- if (textContent) element.textContent = textContent;
58622
- return element;
58269
+ return [x, y];
58623
58270
  }
58624
- function resolveStyle(style, defs) {
58625
- var _a;
58626
- if (!style) return void 0;
58627
- if (typeof style === "string") {
58628
- return (_a = defs == null ? void 0 : defs.styles) == null ? void 0 : _a[style];
58271
+ function interpKfs(kfs, t) {
58272
+ if (t <= kfs[0].time) return kfs[0].value;
58273
+ if (t >= kfs[kfs.length - 1].time) return kfs[kfs.length - 1].value;
58274
+ for (let i = 1; i < kfs.length; i++) {
58275
+ if (t <= kfs[i].time) {
58276
+ const prev = kfs[i - 1];
58277
+ const cur = kfs[i];
58278
+ const a = (t - prev.time) / (cur.time - prev.time);
58279
+ return [prev.value[0] + (cur.value[0] - prev.value[0]) * a, prev.value[1] + (cur.value[1] - prev.value[1]) * a];
58280
+ }
58629
58281
  }
58630
- return style;
58282
+ return kfs[kfs.length - 1].value;
58631
58283
  }
58632
- function getNormalizedProps(props) {
58633
- const propsCopy = {};
58634
- for (const key of Object.keys(props)) {
58635
- if (INTERNAL_ATTRS.has(key)) continue;
58636
- if (key === "style") continue;
58637
- let value = props[key];
58638
- if (COLOUR_ATTR_NAMES.has(key) && Array.isArray(value)) {
58639
- propsCopy[key] = toRGBA(value);
58640
- } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && value.value && typeof value.value === "object") {
58641
- propsCopy["transform"] = composeTransformParts(value.value, { withUnits: false });
58642
- } else if (TRANSFORM_FN_NAMES.has(key)) {
58643
- if (Array.isArray(value)) {
58644
- if (key === "translate") value = value.map((v) => v + "px");
58645
- value = value.join(",");
58284
+ function collectMaskAncestorChains(root, ctx) {
58285
+ const interestingNodes = /* @__PURE__ */ new Set();
58286
+ const collectInterestingNodes = (n) => {
58287
+ var _a, _b;
58288
+ const href = (_b = (_a = n.effects) == null ? void 0 : _a.maskedBy) == null ? void 0 : _b.href;
58289
+ if (typeof href === "string") {
58290
+ interestingNodes.add(n);
58291
+ const sourceNode = ctx.idMap.get(href);
58292
+ if (sourceNode) interestingNodes.add(sourceNode);
58293
+ }
58294
+ if (Array.isArray(n.children)) for (const ch of n.children) collectInterestingNodes(ch);
58295
+ };
58296
+ collectInterestingNodes(root);
58297
+ if (interestingNodes.size === 0) return;
58298
+ const walk = (node, chain) => {
58299
+ if (interestingNodes.has(node)) ctx.maskAncestorChains.set(node, chain);
58300
+ if (Array.isArray(node.children)) {
58301
+ const own = extractTranslateOnly(node, ctx);
58302
+ const next = own ? [...chain, own] : chain;
58303
+ for (const ch of node.children) walk(ch, next);
58304
+ }
58305
+ };
58306
+ walk(root, []);
58307
+ }
58308
+ function extractTranslateOnly(node, ctx) {
58309
+ var _a, _b, _c;
58310
+ const tr = node.transform;
58311
+ const animateBlock = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate.transform : void 0;
58312
+ if (tr === void 0 && !animateBlock) return void 0;
58313
+ const out = {};
58314
+ if (typeof tr === "string") {
58315
+ const parts = parseTranslateOnlyFromString(tr, ctx);
58316
+ if (parts) out.translate = parts;
58317
+ } else if (tr && typeof tr === "object") {
58318
+ const value = tr.value;
58319
+ if (value && typeof value === "object" && Array.isArray(value.translate)) {
58320
+ out.translate = [value.translate[0] || 0, value.translate[1] || 0];
58321
+ }
58322
+ if (value && (value.rotate !== void 0 || value.scale !== void 0 || value.skew !== void 0)) {
58323
+ ctx.warnings.push("maskedBy ancestor: non-translate transform parts ignored (rotate/scale not yet supported)");
58324
+ }
58325
+ }
58326
+ if (animateBlock && Array.isArray(animateBlock.keyframes)) {
58327
+ const kfs = animateBlock.keyframes;
58328
+ const translateKfs = [];
58329
+ for (const kf of kfs) {
58330
+ const v = (_a = kf.value) != null ? _a : kf.v;
58331
+ const t = (_c = (_b = kf.time) != null ? _b : kf.t) != null ? _c : 0;
58332
+ if (v && typeof v === "object" && Array.isArray(v.translate)) {
58333
+ translateKfs.push({ time: t, value: [v.translate[0] || 0, v.translate[1] || 0] });
58334
+ if (v.rotate !== void 0 || v.scale !== void 0 || v.skew !== void 0) {
58335
+ ctx.warnings.push("maskedBy ancestor: animated non-translate parts ignored");
58336
+ }
58646
58337
  }
58647
- if (key === "rotate") value = value + "deg";
58648
- propsCopy["transform"] = key + "(" + value + ")";
58649
- } else if (value !== void 0 && value !== null) {
58650
- propsCopy[key] = String(value);
58651
58338
  }
58339
+ if (translateKfs.length) out.translateKeyframes = translateKfs;
58652
58340
  }
58653
- return propsCopy;
58341
+ return out.translate || out.translateKeyframes ? out : void 0;
58654
58342
  }
58655
- function renderNode(node, defs) {
58656
- if (!node) return null;
58657
- const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
58658
- const nodeDefs = getDefs(node) || defs;
58659
- const resolvedStyle = resolveStyle(style, nodeDefs);
58660
- let childElements;
58661
- if (children) {
58662
- for (const ch of children) {
58663
- const child = renderNode(ch, nodeDefs);
58664
- if (child) {
58665
- if (!childElements) childElements = [];
58666
- childElements.push(child);
58667
- }
58343
+ function parseTranslateOnlyFromString(s, ctx) {
58344
+ const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
58345
+ let m;
58346
+ let x = 0, y = 0;
58347
+ let seen = false;
58348
+ let droppedNonTranslate = false;
58349
+ while ((m = re.exec(s)) !== null) {
58350
+ const name = m[1];
58351
+ const args = m[2].split(/[\s,]+/).filter((a) => a.length > 0).map(Number);
58352
+ if (name === "translate") {
58353
+ x += args[0] || 0;
58354
+ y += args[1] || 0;
58355
+ seen = true;
58356
+ } else {
58357
+ droppedNonTranslate = true;
58668
58358
  }
58669
58359
  }
58670
- return createElement(
58671
- type || "g",
58672
- getNormalizedProps(props),
58673
- resolvedStyle,
58674
- childElements,
58675
- props[TEXT_ATTR] || props[TEXT_CONTENT_ATTR]
58676
- );
58360
+ if (droppedNonTranslate) ctx.warnings.push("maskedBy ancestor: non-translate transform in string ignored: " + s);
58361
+ return seen ? [x, y] : void 0;
58677
58362
  }
58678
- function setupAnimationTriggers(api, config) {
58679
- const { startOn, outAction = "continue", scrollIntoViewThreshold = 0.5 } = config;
58680
- const root = api.getRootElement();
58681
- if (!root) {
58682
- console.warn("setupAnimationTriggers: No root element found for animation.");
58683
- return api;
58363
+ var CONTENT_SUBREF = "content";
58364
+ function applyRefAndTransformationEffect(node, ref3, transformation, ctx) {
58365
+ if (ref3) {
58366
+ const baseId = ref3.baseId;
58367
+ if (!baseId) {
58368
+ ctx.errors.push("ref: missing baseId");
58369
+ } else {
58370
+ const targetId = ref3.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(baseId) || baseId : baseId;
58371
+ node.href = "#" + targetId;
58372
+ }
58684
58373
  }
58685
- const start = () => {
58686
- api.play();
58687
- };
58688
- const handleEndAction = () => {
58689
- switch (outAction) {
58690
- case "pause":
58691
- api.pause();
58692
- break;
58693
- case "reset":
58694
- api.cancel();
58695
- break;
58696
- case "reverse":
58697
- api.play();
58698
- break;
58699
- case "continue":
58700
- default:
58701
- break;
58374
+ return applyTransformationEffect(node, transformation, ctx);
58375
+ }
58376
+ function applyRepeaterEffect(node, fx, ctx) {
58377
+ var _a, _b;
58378
+ if (!fx) return node;
58379
+ const copies = (_a = fx.copies) != null ? _a : 1;
58380
+ if (copies < 1) {
58381
+ ctx.errors.push("repeater.copies invalid: " + fx.copies);
58382
+ return node;
58383
+ }
58384
+ const sharedTransform = node.transform;
58385
+ const sharedAnimTransform = (_b = node.animate) == null ? void 0 : _b.transform;
58386
+ const base = clone(node);
58387
+ delete base.transform;
58388
+ if (base.animate) {
58389
+ delete base.animate.transform;
58390
+ if (Object.keys(base.animate).length === 0) delete base.animate;
58391
+ }
58392
+ const children = [base];
58393
+ for (let i = 1; i < copies; i++) {
58394
+ const baseClone = clone(base);
58395
+ const synthFx = synthesisePerCopyFx(fx, i);
58396
+ const wrapped = synthFx ? applyTransformationEffect(baseClone, synthFx, ctx) : baseClone;
58397
+ children.push(wrapped);
58398
+ }
58399
+ const wrapper = { type: "g", children };
58400
+ if (sharedTransform !== void 0) wrapper.transform = sharedTransform;
58401
+ if (sharedAnimTransform !== void 0) wrapper.animate = { transform: sharedAnimTransform };
58402
+ return wrapper;
58403
+ }
58404
+ function synthesisePerCopyFx(fx, i) {
58405
+ const out = {};
58406
+ if (fx.translate !== void 0) {
58407
+ out.translate = mapAnimatableVec2(fx.translate, (v) => [v[0] * i, v[1] * i]);
58408
+ }
58409
+ if (fx.rotate !== void 0) {
58410
+ out.rotate = mapAnimatableNumber(fx.rotate, (v) => v * i);
58411
+ }
58412
+ if (fx.scale !== void 0) {
58413
+ out.scale = synthesiseScale(fx.scale, i);
58414
+ }
58415
+ if (fx.origin !== void 0) {
58416
+ out.origin = fx.origin;
58417
+ }
58418
+ return Object.keys(out).length ? out : void 0;
58419
+ }
58420
+ function mapAnimatableVec2(raw, fn) {
58421
+ if (Array.isArray(raw)) return fn(raw);
58422
+ if (raw && typeof raw === "object") {
58423
+ const obj = raw;
58424
+ if (Array.isArray(obj.keyframes)) {
58425
+ return __spreadProps(__spreadValues({}, obj), {
58426
+ keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps(__spreadValues({}, kf), { value: fn(kf.value) }) : kf)
58427
+ });
58702
58428
  }
58703
- };
58704
- switch (startOn) {
58705
- case "load": {
58706
- const startHandler = () => start();
58707
- if (document.readyState === "complete") {
58708
- startHandler();
58709
- } else {
58710
- window.addEventListener("load", startHandler, { once: true });
58711
- }
58712
- break;
58429
+ if (obj.value !== void 0) {
58430
+ return __spreadProps(__spreadValues({}, obj), { value: fn(obj.value) });
58713
58431
  }
58714
- case "mouseOver": {
58715
- const mouseOverHandler = () => start();
58716
- const mouseOutHandler = () => handleEndAction();
58717
- root.addEventListener("mouseenter", mouseOverHandler);
58718
- root.addEventListener("mouseleave", mouseOutHandler);
58719
- break;
58432
+ }
58433
+ return raw;
58434
+ }
58435
+ function mapAnimatableNumber(raw, fn) {
58436
+ if (typeof raw === "number") return fn(raw);
58437
+ if (raw && typeof raw === "object") {
58438
+ const obj = raw;
58439
+ if (Array.isArray(obj.keyframes)) {
58440
+ return __spreadProps(__spreadValues({}, obj), {
58441
+ keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps(__spreadValues({}, kf), { value: fn(kf.value) }) : kf)
58442
+ });
58720
58443
  }
58721
- case "click": {
58722
- const clickHandler = () => {
58723
- if (api.isPlaying()) {
58724
- handleEndAction();
58725
- } else {
58726
- start();
58727
- }
58728
- };
58729
- root.addEventListener("click", clickHandler);
58730
- break;
58444
+ if (obj.value !== void 0) {
58445
+ return __spreadProps(__spreadValues({}, obj), { value: fn(obj.value) });
58731
58446
  }
58732
- case "scrollIntoView": {
58733
- const observer = new IntersectionObserver(
58734
- (entries) => {
58735
- entries.forEach((entry) => {
58736
- if (entry.isIntersecting && entry.intersectionRatio >= scrollIntoViewThreshold) {
58737
- start();
58738
- } else {
58739
- handleEndAction();
58740
- }
58741
- });
58742
- },
58743
- { threshold: scrollIntoViewThreshold }
58744
- );
58745
- observer.observe(root);
58746
- break;
58447
+ }
58448
+ return raw;
58449
+ }
58450
+ function synthesiseScale(raw, i) {
58451
+ const scalePowerFromPercent = (v) => [Math.pow(v[0] / 100, i), Math.pow(v[1] / 100, i)];
58452
+ const scalePowerFromUnits = (v) => [Math.pow(v[0], i), Math.pow(v[1], i)];
58453
+ if (Array.isArray(raw)) {
58454
+ return { value: scalePowerFromPercent(raw) };
58455
+ }
58456
+ if (raw && typeof raw === "object") {
58457
+ const obj = raw;
58458
+ if (Array.isArray(obj.keyframes)) {
58459
+ return __spreadProps(__spreadValues({}, obj), {
58460
+ keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps(__spreadValues({}, kf), { value: scalePowerFromUnits(kf.value) }) : kf)
58461
+ });
58462
+ }
58463
+ if (obj.value !== void 0) {
58464
+ return __spreadProps(__spreadValues({}, obj), { value: scalePowerFromPercent(obj.value) });
58747
58465
  }
58748
- case "programmatic":
58749
- break;
58750
58466
  }
58751
- return api;
58467
+ return raw;
58752
58468
  }
58753
- function propAnimIsMotionPath(anim) {
58469
+ var RETIME_MATERIALISATION_MODE_INLINE_G = false;
58470
+ function asRetime(r) {
58471
+ var _a, _b;
58472
+ return { start: (_a = r.start) != null ? _a : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
58473
+ }
58474
+ function concatRetime(child, parent) {
58475
+ return {
58476
+ start: parent.start + parent.stretch * child.start,
58477
+ stretch: parent.stretch * child.stretch
58478
+ };
58479
+ }
58480
+ function applyAllRetimeEffects(root, ctx) {
58754
58481
  var _a;
58755
- const kfs = (_a = anim.keyframes) != null ? _a : anim.kfs;
58756
- if (!Array.isArray(kfs)) return false;
58757
- if (anim.autoOrient) return true;
58758
- for (const kf of kfs) {
58759
- if (kf.tangentIn || kf.tangentOut) return true;
58482
+ ctx.idMap.clear();
58483
+ indexById(root, ctx.idMap);
58484
+ const sites = [];
58485
+ const collect = (n) => {
58486
+ var _a2, _b;
58487
+ if ((_a2 = n.effects) == null ? void 0 : _a2.retime) sites.push(n);
58488
+ (_b = n.children) == null ? void 0 : _b.forEach(collect);
58489
+ };
58490
+ collect(root);
58491
+ for (const useNode of sites) {
58492
+ const retime = (_a = useNode.effects) == null ? void 0 : _a.retime;
58493
+ if (!retime) continue;
58494
+ delete useNode.effects.retime;
58495
+ if (Object.keys(useNode.effects).length === 0) delete useNode.effects;
58496
+ materialiseRetime(useNode, asRetime(retime), ctx);
58760
58497
  }
58761
- return false;
58762
58498
  }
58763
- var _segmentCache = /* @__PURE__ */ new WeakMap();
58764
- function getSegmentCache(prevKf, nextKf, prevPos, nextPos) {
58765
- const existing = _segmentCache.get(prevKf);
58766
- if (existing) return existing;
58767
- const to = prevKf.tangentOut;
58768
- const ti = nextKf.tangentIn;
58769
- const P1 = [prevPos[0] + (to ? to[0] : 0), prevPos[1] + (to ? to[1] : 0)];
58770
- const P2 = [nextPos[0] + (ti ? ti[0] : 0), nextPos[1] + (ti ? ti[1] : 0)];
58771
- const lut = bezier2D_arcLengthLUT(prevPos, P1, P2, nextPos);
58772
- const entry = {
58773
- P0: prevPos,
58774
- P1,
58775
- P2,
58776
- P3: nextPos,
58777
- lut,
58778
- totalArc: lut.ds[lut.ds.length - 1]
58499
+ function materialiseRetime(useNode, retime, ctx) {
58500
+ const targetId = stripHash(useNode.href);
58501
+ if (!targetId) {
58502
+ ctx.errors.push("retime: <use> has no href to follow");
58503
+ return;
58504
+ }
58505
+ const chainRootId = buildChainClone(targetId, retime, ctx, /* @__PURE__ */ new Set());
58506
+ if (!chainRootId) return;
58507
+ if (RETIME_MATERIALISATION_MODE_INLINE_G) {
58508
+ const cloneNode = ctx.idMap.get(chainRootId);
58509
+ useNode.type = "g";
58510
+ delete useNode.href;
58511
+ useNode.children = [cloneNode];
58512
+ applyUseOffsetToG(useNode);
58513
+ ctx.defs = ctx.defs.filter((d) => d !== cloneNode);
58514
+ } else {
58515
+ useNode.href = "#" + chainRootId;
58516
+ }
58517
+ }
58518
+ function buildChainClone(targetId, accum, ctx, chain) {
58519
+ var _a, _b;
58520
+ if (chain.has(targetId)) {
58521
+ ctx.errors.push('retime: loop via "' + targetId + '"');
58522
+ return void 0;
58523
+ }
58524
+ const target = ctx.idMap.get(targetId);
58525
+ if (!target) {
58526
+ ctx.warnings.push('retime: target "' + targetId + '" not found');
58527
+ return void 0;
58528
+ }
58529
+ const cloneNode = clone(target);
58530
+ regenerateIdsInClone(cloneNode, ctx);
58531
+ if (target.type === "use") {
58532
+ remapKeyframeTimesOnly(cloneNode, accum.start, accum.stretch);
58533
+ } else {
58534
+ remapKeyframeTimes(cloneNode, accum.start, accum.stretch);
58535
+ }
58536
+ if ((_a = cloneNode.effects) == null ? void 0 : _a.retime) {
58537
+ delete cloneNode.effects.retime;
58538
+ if (Object.keys(cloneNode.effects).length === 0) delete cloneNode.effects;
58539
+ }
58540
+ if (target.type === "use" && target.href) {
58541
+ const subId = stripHash(target.href);
58542
+ if (subId) {
58543
+ const innerRetime = (_b = target.effects) == null ? void 0 : _b.retime;
58544
+ const subAccum = innerRetime ? concatRetime(asRetime(innerRetime), accum) : accum;
58545
+ const subChain = new Set(chain);
58546
+ subChain.add(targetId);
58547
+ const subId2 = buildChainClone(subId, subAccum, ctx, subChain);
58548
+ if (subId2) cloneNode.href = "#" + subId2;
58549
+ }
58550
+ }
58551
+ ctx.defs.push(cloneNode);
58552
+ if (typeof cloneNode.id === "string") ctx.idMap.set(cloneNode.id, cloneNode);
58553
+ return typeof cloneNode.id === "string" ? cloneNode.id : void 0;
58554
+ }
58555
+ function remapKeyframeTimes(node, start, stretch) {
58556
+ var _a;
58557
+ remapKeyframeTimesOnly(node, start, stretch);
58558
+ (_a = node.children) == null ? void 0 : _a.forEach((c) => remapKeyframeTimes(c, start, stretch));
58559
+ }
58560
+ function remapKeyframeTimesOnly(node, start, stretch) {
58561
+ const remap2 = (kfs) => {
58562
+ for (const kf of kfs) if (typeof kf.time === "number") kf.time = start + kf.time * stretch;
58779
58563
  };
58780
- _segmentCache.set(prevKf, entry);
58781
- return entry;
58564
+ if (node.transform && typeof node.transform === "object" && Array.isArray(node.transform.keyframes)) {
58565
+ remap2(node.transform.keyframes);
58566
+ }
58567
+ if (node.animate && typeof node.animate === "object") {
58568
+ for (const prop of Object.keys(node.animate)) {
58569
+ const anim = node.animate[prop];
58570
+ if (anim && Array.isArray(anim.keyframes)) remap2(anim.keyframes);
58571
+ }
58572
+ }
58782
58573
  }
58783
- function evaluateMotionPathSegment(prevKf, nextKf, prevPos, nextPos, localProgress, autoOrient) {
58784
- const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
58785
- const t = seg.totalArc === 0 ? localProgress : bezier2D_tForDistance(seg.lut, localProgress * seg.totalArc);
58786
- const point = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
58787
- if (!autoOrient) return { translate: point };
58788
- const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
58789
- const rotateDeg = Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
58790
- return { translate: point, rotateDeg };
58574
+ function applyTextAlongPathEffect(node, fx, _ctx) {
58575
+ var _a;
58576
+ if (!fx) return node;
58577
+ const href = typeof fx.href === "string" && !fx.href.startsWith("#") ? "#" + fx.href : fx.href;
58578
+ const textPath = {
58579
+ type: "textPath",
58580
+ href,
58581
+ children: (_a = node.children) != null ? _a : []
58582
+ };
58583
+ if (fx.lengthAdjust !== void 0) textPath.lengthAdjust = fx.lengthAdjust;
58584
+ if (fx.method !== void 0) textPath.method = fx.method;
58585
+ if (fx.spacing !== void 0) textPath.spacing = fx.spacing;
58586
+ applyAnimatableNumber(textPath, "startOffset", fx.startOffset);
58587
+ applyAnimatableNumber(textPath, "textLength", fx.textLength);
58588
+ node.children = [textPath];
58589
+ return node;
58791
58590
  }
58792
- function parsePathCommands(d) {
58793
- const tokens = d.split(/([MLCZmlcz]|[\s,]+)/).map((t) => t.trim()).filter((t) => t && t !== ",");
58794
- const commands = [];
58795
- let currentCommand = null;
58796
- for (const token of tokens) {
58797
- if (/[MLCZmlcz]/.test(token)) {
58798
- currentCommand = { type: token, values: [] };
58799
- commands.push(currentCommand);
58800
- } else if (currentCommand) {
58801
- const value = +token;
58802
- currentCommand.values.push(Number.isNaN(value) ? 0 : value);
58591
+ function applyAnimatableNumber(node, attrName, raw) {
58592
+ if (raw === void 0 || raw === null) return;
58593
+ if (typeof raw === "number") {
58594
+ node[attrName] = String(raw);
58595
+ return;
58596
+ }
58597
+ if (typeof raw === "object") {
58598
+ const obj = raw;
58599
+ if (Array.isArray(obj.keyframes)) {
58600
+ const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
58601
+ const animate = __spreadValues({}, prevAnimate || {});
58602
+ animate[attrName] = { keyframes: obj.keyframes };
58603
+ node.animate = animate;
58604
+ return;
58605
+ }
58606
+ if (typeof obj.value === "number") {
58607
+ node[attrName] = String(obj.value);
58608
+ return;
58803
58609
  }
58804
58610
  }
58805
- return commands;
58806
58611
  }
58807
- function parseSvgPathToBezier(d) {
58808
- const res = [];
58809
- let currentPath;
58810
- const commands = parsePathCommands(d);
58612
+ function bezierToSvgPath(path) {
58613
+ var _a, _b, _c, _d;
58614
+ const v = path.v;
58615
+ const i = path.i;
58616
+ const o = path.o;
58617
+ const c = path.c;
58618
+ if (!v.length) return "";
58619
+ const d = [];
58620
+ const len = v.length;
58621
+ d.push("M" + v[0][0] + "," + v[0][1]);
58622
+ for (let idx = 1; idx < len; idx++) {
58623
+ const prevV = v[idx - 1];
58624
+ const prevO = (_a = o == null ? void 0 : o[idx - 1]) != null ? _a : prevV;
58625
+ const currI = (_b = i == null ? void 0 : i[idx]) != null ? _b : v[idx];
58626
+ const currV = v[idx];
58627
+ const isLine = prevO[0] === prevV[0] && prevO[1] === prevV[1] && (currI[0] === currV[0] && currI[1] === currV[1]);
58628
+ if (isLine) {
58629
+ d.push("L" + currV[0] + "," + currV[1]);
58630
+ } else {
58631
+ d.push("C" + prevO[0] + "," + prevO[1] + "," + currI[0] + "," + currI[1] + "," + currV[0] + "," + currV[1]);
58632
+ }
58633
+ }
58634
+ if (c && len > 0) {
58635
+ const lastV = v[len - 1];
58636
+ const lastO = (_c = o == null ? void 0 : o[len - 1]) != null ? _c : lastV;
58637
+ const firstI = (_d = i == null ? void 0 : i[0]) != null ? _d : v[0];
58638
+ const firstV = v[0];
58639
+ const isLine = lastO[0] === lastV[0] && lastO[1] === lastV[1] && (firstI[0] === firstV[0] && firstI[1] === firstV[1]);
58640
+ if (!isLine) {
58641
+ d.push("C" + lastO[0] + "," + lastO[1] + "," + firstI[0] + "," + firstI[1] + "," + firstV[0] + "," + firstV[1]);
58642
+ }
58643
+ d.push("z");
58644
+ }
58645
+ return d.join("");
58646
+ }
58647
+ function interpolateNum(a, b, t) {
58648
+ return a + (b - a) * t;
58649
+ }
58650
+ function interpolateVec(a, b, t) {
58651
+ const res = [];
58652
+ const count = Math.max(a.length, b.length);
58653
+ for (let i = 0; i < count; i++) {
58654
+ res[i] = interpolateNum(a[i] || 0, b[i] || 0, t);
58655
+ }
58656
+ return res;
58657
+ }
58658
+ function interpolateColor(a, b, t) {
58659
+ return [
58660
+ interpolateNum(a[0] || 0, b[0] || 0, t),
58661
+ interpolateNum(a[1] || 0, b[1] || 0, t),
58662
+ interpolateNum(a[2] || 0, b[2] || 0, t),
58663
+ interpolateNum(a[3] === void 0 ? 1 : a[3], b[3] === void 0 ? 1 : b[3], t)
58664
+ ];
58665
+ }
58666
+ function interpolateBeziers(paths1, paths2, progress) {
58667
+ const count = Math.max(paths1.length, paths2.length);
58668
+ const res = [];
58669
+ for (let i = 0; i < count; i++) {
58670
+ res.push(interpolateBezier(paths1[i], paths2[i], progress));
58671
+ }
58672
+ return res;
58673
+ }
58674
+ function interpolateBezier(path1, path2, progress) {
58675
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
58676
+ if (!path1 || !path2) return path1 || path2 || { v: [] };
58677
+ const t = Math.min(Math.max(progress, 0), 1);
58678
+ const len = Math.min(path1.v.length, path2.v.length);
58679
+ const v = [];
58680
+ const i = [];
58681
+ const o = [];
58682
+ for (let idx = 0; idx < len; idx++) {
58683
+ const v1 = path1.v[idx];
58684
+ const v2 = path2.v[idx];
58685
+ v.push(interpolateVec(v1, v2, t));
58686
+ const i1 = (_b = (_a = path1.i) == null ? void 0 : _a[idx]) != null ? _b : v1;
58687
+ const i2 = (_d = (_c = path2.i) == null ? void 0 : _c[idx]) != null ? _d : v2;
58688
+ i.push(interpolateVec(i1, i2, t));
58689
+ const o1 = (_f = (_e = path1.o) == null ? void 0 : _e[idx]) != null ? _f : v1;
58690
+ const o2 = (_h = (_g = path2.o) == null ? void 0 : _g[idx]) != null ? _h : v2;
58691
+ o.push(interpolateVec(o1, o2, t));
58692
+ }
58693
+ return { v, i: i.length ? i : void 0, o: o.length ? o : void 0, c: (_i = path1.c) != null ? _i : path2.c };
58694
+ }
58695
+ function remap(value, inMin, inMax, outMin, outMax) {
58696
+ if (inMax === inMin) return outMin;
58697
+ const t = (value - inMin) / (inMax - inMin);
58698
+ return outMin + t * (outMax - outMin);
58699
+ }
58700
+ function solveCubicBezierX(p1x, p2x, x) {
58701
+ if (x <= 0) return 0;
58702
+ if (x >= 1) return 1;
58703
+ const cx = 3 * p1x;
58704
+ const bx = 3 * (p2x - p1x) - cx;
58705
+ const ax = 1 - cx - bx;
58706
+ function sampleX(t) {
58707
+ return ((ax * t + bx) * t + cx) * t;
58708
+ }
58709
+ function sampleDX(t) {
58710
+ return (3 * ax * t + 2 * bx) * t + cx;
58711
+ }
58712
+ let t2 = x;
58713
+ let t0 = 0;
58714
+ let t1 = 1;
58715
+ for (let i = 0; i < 8; i++) {
58716
+ const x2 = sampleX(t2) - x;
58717
+ if (Math.abs(x2) < 1e-6) return t2;
58718
+ const d2 = sampleDX(t2);
58719
+ if (Math.abs(d2) < 1e-6) break;
58720
+ t2 -= x2 / d2;
58721
+ }
58722
+ t2 = x;
58723
+ while (t0 < t1) {
58724
+ const x2 = sampleX(t2);
58725
+ if (Math.abs(x2 - x) < 1e-6) return t2;
58726
+ if (x > x2) t0 = t2;
58727
+ else t1 = t2;
58728
+ t2 = (t1 + t0) / 2;
58729
+ }
58730
+ return t2;
58731
+ }
58732
+ function cubicBezier(easing) {
58733
+ const [p1x, p1y, p2x, p2y] = easing;
58734
+ const cy = 3 * p1y;
58735
+ const by = 3 * (p2y - p1y) - cy;
58736
+ const ay = 1 - cy - by;
58737
+ function sampleCurveY(t) {
58738
+ return ((ay * t + by) * t + cy) * t;
58739
+ }
58740
+ return function(x) {
58741
+ return sampleCurveY(solveCubicBezierX(p1x, p2x, x));
58742
+ };
58743
+ }
58744
+ function lerp2(a, b, t) {
58745
+ return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t];
58746
+ }
58747
+ function subdivideCubicBezier(p0, p1, p2, p3, t) {
58748
+ const q0 = lerp2(p0, p1, t);
58749
+ const q1 = lerp2(p1, p2, t);
58750
+ const q2 = lerp2(p2, p3, t);
58751
+ const r0 = lerp2(q0, q1, t);
58752
+ const r1 = lerp2(q1, q2, t);
58753
+ const s = lerp2(r0, r1, t);
58754
+ return {
58755
+ left: [p0, q0, r0, s],
58756
+ right: [s, r1, q2, p3]
58757
+ };
58758
+ }
58759
+ function splitEasing(easing, xFraction) {
58760
+ if (!easing) return { left: void 0, right: void 0 };
58761
+ if (xFraction <= 0) return { left: void 0, right: easing };
58762
+ if (xFraction >= 1) return { left: easing, right: void 0 };
58763
+ const [x1, y1, x2, y2] = easing;
58764
+ const t = solveCubicBezierX(x1, x2, xFraction);
58765
+ const p0 = [0, 0];
58766
+ const p1 = [x1, y1];
58767
+ const p2 = [x2, y2];
58768
+ const p3 = [1, 1];
58769
+ const { left, right } = subdivideCubicBezier(p0, p1, p2, p3, t);
58770
+ const sx = left[3][0];
58771
+ const sy = left[3][1];
58772
+ let leftEasing;
58773
+ if (sx > 1e-9 && Math.abs(sy) > 1e-9) {
58774
+ leftEasing = [
58775
+ left[1][0] / sx,
58776
+ left[1][1] / sy,
58777
+ left[2][0] / sx,
58778
+ left[2][1] / sy
58779
+ ];
58780
+ }
58781
+ let rightEasing;
58782
+ const rx = 1 - sx;
58783
+ const ry = 1 - sy;
58784
+ if (rx > 1e-9 && Math.abs(ry) > 1e-9) {
58785
+ rightEasing = [
58786
+ (right[1][0] - sx) / rx,
58787
+ (right[1][1] - sy) / ry,
58788
+ (right[2][0] - sx) / rx,
58789
+ (right[2][1] - sy) / ry
58790
+ ];
58791
+ }
58792
+ return { left: leftEasing, right: rightEasing };
58793
+ }
58794
+ function reverseEasing(easing) {
58795
+ if (!easing) return void 0;
58796
+ return [1 - easing[2], 1 - easing[3], 1 - easing[0], 1 - easing[1]];
58797
+ }
58798
+ function toRGBA(color) {
58799
+ const r = Math.round(color[0] * 255);
58800
+ const g = Math.round(color[1] * 255);
58801
+ const b = Math.round(color[2] * 255);
58802
+ return color.length === 4 ? "rgba(" + r + "," + g + "," + b + "," + color[3] + ")" : "rgb(" + r + "," + g + "," + b + ")";
58803
+ }
58804
+ function parseRgba(s) {
58805
+ var _a;
58806
+ const inner = (_a = s.match(/rgba?\((.*)\)/)) == null ? void 0 : _a[1];
58807
+ if (!inner) throw new Error("Invalid rgb/rgba format");
58808
+ const parts = inner.split(",").map((v) => +v.trim());
58809
+ return [parts[0] / 255, parts[1] / 255, parts[2] / 255, ...parts[3] !== void 0 ? [parts[3]] : []];
58810
+ }
58811
+ function parseHex(s) {
58812
+ const hex = s.slice(1);
58813
+ const isShort = hex.length <= 4;
58814
+ const r = isShort ? hex[0] + hex[0] : hex.slice(0, 2);
58815
+ const g = isShort ? hex[1] + hex[1] : hex.slice(2, 4);
58816
+ const b = isShort ? hex[2] + hex[2] : hex.slice(4, 6);
58817
+ const a = hex.length === 4 ? hex[3] + hex[3] : hex.length === 8 ? hex.slice(6, 8) : null;
58818
+ const result = [
58819
+ parseInt(r, 16) / 255,
58820
+ parseInt(g, 16) / 255,
58821
+ parseInt(b, 16) / 255
58822
+ ];
58823
+ if (a !== null) {
58824
+ result.push(parseInt(a, 16) / 255);
58825
+ }
58826
+ return result;
58827
+ }
58828
+ function parseColor(s) {
58829
+ if (!s) return void 0;
58830
+ if (Array.isArray(s)) return s;
58831
+ if (typeof s !== "string") return void 0;
58832
+ if (s.startsWith("#")) {
58833
+ return parseHex(s);
58834
+ } else if (s.startsWith("rgb")) {
58835
+ return parseRgba(s);
58836
+ } else {
58837
+ console.warn("Unsupported color format: " + s);
58838
+ }
58839
+ return void 0;
58840
+ }
58841
+ var COLOUR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
58842
+ var TRANSFORM_FN_NAMES = /* @__PURE__ */ new Set(["translate", "rotate", "scale", "skew"]);
58843
+ var PCT_BASED_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
58844
+ function composeTransformParts(parts, opts) {
58845
+ var _a;
58846
+ if (!parts) return "";
58847
+ const withUnits = (_a = opts == null ? void 0 : opts.withUnits) != null ? _a : true;
58848
+ const segs = [];
58849
+ const t = parts.translate;
58850
+ const o = parts.origin;
58851
+ const r = parts.rotate;
58852
+ const s = parts.scale;
58853
+ const tu = withUnits ? "px" : "";
58854
+ const ru = withUnits ? "deg" : "";
58855
+ if (t) segs.push("translate(" + t[0] + tu + "," + t[1] + tu + ")");
58856
+ if (o) segs.push("translate(" + o[0] + tu + "," + o[1] + tu + ")");
58857
+ if (r !== void 0 && r !== null) segs.push("rotate(" + r + ru + ")");
58858
+ if (s) segs.push("scale(" + s[0] + "," + s[1] + ")");
58859
+ if (o) segs.push("translate(" + -o[0] + tu + "," + -o[1] + tu + ")");
58860
+ return segs.join("");
58861
+ }
58862
+ var STYLE_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
58863
+ var DEFAULT_DURATION_MS = 1e3;
58864
+ function kebabToCamelCaseWord(kebab) {
58865
+ return kebab.includes("-") ? kebab.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()) : kebab;
58866
+ }
58867
+ function isCamelCaseWord(word) {
58868
+ return !word.includes("-") && /[a-z][A-Z]/.test(word);
58869
+ }
58870
+ var SVG_CAMEL_CASE_ATTRS = /* @__PURE__ */ new Set([
58871
+ // Transform/positioning
58872
+ "viewBox",
58873
+ "preserveAspectRatio",
58874
+ // Gradient
58875
+ "gradientUnits",
58876
+ "gradientTransform",
58877
+ "spreadMethod",
58878
+ // Pattern
58879
+ "patternUnits",
58880
+ "patternContentUnits",
58881
+ "patternTransform",
58882
+ // Clipping/masking
58883
+ "clipPathUnits",
58884
+ "maskUnits",
58885
+ "maskContentUnits",
58886
+ // Marker (SVG spec keeps these camelCase, like viewBox)
58887
+ "markerUnits",
58888
+ "markerWidth",
58889
+ "markerHeight",
58890
+ "refX",
58891
+ "refY",
58892
+ // Text
58893
+ "textLength",
58894
+ "lengthAdjust",
58895
+ "startOffset",
58896
+ // Filter
58897
+ "filterUnits",
58898
+ "primitiveUnits",
58899
+ "stdDeviation",
58900
+ "baseFrequency",
58901
+ "numOctaves",
58902
+ "surfaceScale",
58903
+ "diffuseConstant",
58904
+ "specularConstant",
58905
+ "specularExponent",
58906
+ "kernelMatrix",
58907
+ "kernelUnitLength",
58908
+ "edgeMode",
58909
+ "preserveAlpha",
58910
+ "targetX",
58911
+ "targetY"
58912
+ // // Animation
58913
+ // 'attributeName',
58914
+ // 'attributeType',
58915
+ // 'calcMode',
58916
+ // 'keyTimes',
58917
+ // 'keySplines',
58918
+ // 'repeatCount',
58919
+ // 'repeatDur'
58920
+ ]);
58921
+ function camelCaseToKebabWordIfNeeded(camel) {
58922
+ return SVG_CAMEL_CASE_ATTRS.has(camel) ? camel : camel.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
58923
+ }
58924
+ function clamp(value, min, max) {
58925
+ return Math.max(min, Math.min(value, max));
58926
+ }
58927
+ function bezier2D_pointAt(P0, P1, P2, P3, t) {
58928
+ if (t <= 0) return [P0[0], P0[1]];
58929
+ if (t >= 1) return [P3[0], P3[1]];
58930
+ const u = 1 - t;
58931
+ const u2 = u * u;
58932
+ const u3 = u2 * u;
58933
+ const t2 = t * t;
58934
+ const t3 = t2 * t;
58935
+ const w0 = u3;
58936
+ const w1 = 3 * t * u2;
58937
+ const w2 = 3 * t2 * u;
58938
+ const w3 = t3;
58939
+ return [
58940
+ w0 * P0[0] + w1 * P1[0] + w2 * P2[0] + w3 * P3[0],
58941
+ w0 * P0[1] + w1 * P1[1] + w2 * P2[1] + w3 * P3[1]
58942
+ ];
58943
+ }
58944
+ var BEZIER_T_NUDGE = 1e-4;
58945
+ function bezier2D_derivativeAt(P0, P1, P2, P3, t) {
58946
+ const result = _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t);
58947
+ if (result[0] === 0 && result[1] === 0) {
58948
+ const nudgedT = t < 0.5 ? t + BEZIER_T_NUDGE : t - BEZIER_T_NUDGE;
58949
+ return _bezier2D_derivativeAtRaw(P0, P1, P2, P3, nudgedT);
58950
+ }
58951
+ return result;
58952
+ }
58953
+ function _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t) {
58954
+ const u = 1 - t;
58955
+ const a = 3 * u * u;
58956
+ const b = 6 * t * u;
58957
+ const c = 3 * t * t;
58958
+ return [
58959
+ a * (P1[0] - P0[0]) + b * (P2[0] - P1[0]) + c * (P3[0] - P2[0]),
58960
+ a * (P1[1] - P0[1]) + b * (P2[1] - P1[1]) + c * (P3[1] - P2[1])
58961
+ ];
58962
+ }
58963
+ function bezier2D_arcLengthLUT(P0, P1, P2, P3, steps = 100) {
58964
+ const n = steps + 1;
58965
+ const ts = new Float64Array(n);
58966
+ const ds = new Float64Array(n);
58967
+ let prev = bezier2D_pointAt(P0, P1, P2, P3, 0);
58968
+ ts[0] = 0;
58969
+ ds[0] = 0;
58970
+ let cum = 0;
58971
+ for (let i = 1; i < n; i++) {
58972
+ const t = i / steps;
58973
+ const cur = bezier2D_pointAt(P0, P1, P2, P3, t);
58974
+ const dx = cur[0] - prev[0];
58975
+ const dy = cur[1] - prev[1];
58976
+ cum += Math.sqrt(dx * dx + dy * dy);
58977
+ ts[i] = t;
58978
+ ds[i] = cum;
58979
+ prev = cur;
58980
+ }
58981
+ return { ts, ds };
58982
+ }
58983
+ function bezier2D_arcAtT(lut, t) {
58984
+ const { ts, ds } = lut;
58985
+ const last = ts.length - 1;
58986
+ if (t <= ts[0]) return ds[0];
58987
+ if (t >= ts[last]) return ds[last];
58988
+ let lo = 1, hi = last;
58989
+ while (lo < hi) {
58990
+ const mid = lo + hi >>> 1;
58991
+ if (ts[mid] < t) lo = mid + 1;
58992
+ else hi = mid;
58993
+ }
58994
+ const tPrev = ts[hi - 1];
58995
+ const span = ts[hi] - tPrev;
58996
+ const frac = span > 0 ? (t - tPrev) / span : 0;
58997
+ return ds[hi - 1] + frac * (ds[hi] - ds[hi - 1]);
58998
+ }
58999
+ function invertEasing(easing) {
59000
+ if (!easing) return (y) => y;
59001
+ const flipped = [easing[1], easing[0], easing[3], easing[2]];
59002
+ return cubicBezier(flipped);
59003
+ }
59004
+ function getKfTranslate(kf) {
59005
+ var _a;
59006
+ const v = (_a = kf.value) != null ? _a : kf.v;
59007
+ if (!v) return void 0;
59008
+ if (Array.isArray(v) && v.length >= 2 && typeof v[0] === "number" && typeof v[1] === "number") {
59009
+ return [v[0], v[1]];
59010
+ }
59011
+ const tr = v.translate;
59012
+ if (Array.isArray(tr) && tr.length >= 2) return [tr[0], tr[1]];
59013
+ return void 0;
59014
+ }
59015
+ function getKfTime(kf) {
59016
+ var _a, _b;
59017
+ return (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
59018
+ }
59019
+ function getKfEasing(kf) {
59020
+ var _a;
59021
+ return (_a = kf.easing) != null ? _a : kf.e;
59022
+ }
59023
+ function propAnimIsMotionPath(anim) {
59024
+ var _a, _b, _c;
59025
+ const kfs = (_a = anim.keyframes) != null ? _a : anim.kfs;
59026
+ if (!Array.isArray(kfs)) return false;
59027
+ if (anim.autoOrient) return true;
59028
+ for (const kf of kfs) {
59029
+ if (((_b = kf.tangentIn) != null ? _b : kf.ti) || ((_c = kf.tangentOut) != null ? _c : kf.to)) return true;
59030
+ }
59031
+ return false;
59032
+ }
59033
+ var _segmentCache = /* @__PURE__ */ new WeakMap();
59034
+ function getSegmentCache(prevKf, nextKf, prevPos, nextPos) {
59035
+ var _a, _b;
59036
+ const existing = _segmentCache.get(prevKf);
59037
+ if (existing) return existing;
59038
+ const to = (_a = prevKf.tangentOut) != null ? _a : prevKf.to;
59039
+ const ti = (_b = nextKf.tangentIn) != null ? _b : nextKf.ti;
59040
+ const P1 = [prevPos[0] + (to ? to[0] : 0), prevPos[1] + (to ? to[1] : 0)];
59041
+ const P2 = [nextPos[0] + (ti ? ti[0] : 0), nextPos[1] + (ti ? ti[1] : 0)];
59042
+ const lut = bezier2D_arcLengthLUT(prevPos, P1, P2, nextPos);
59043
+ const entry = {
59044
+ P0: prevPos,
59045
+ P1,
59046
+ P2,
59047
+ P3: nextPos,
59048
+ lut,
59049
+ totalArc: lut.ds[lut.ds.length - 1]
59050
+ };
59051
+ _segmentCache.set(prevKf, entry);
59052
+ return entry;
59053
+ }
59054
+ function evaluateMotionPathSegment(prevKf, nextKf, prevPos, nextPos, localProgress, autoOrient) {
59055
+ const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
59056
+ const t = seg.totalArc === 0 ? localProgress : tFromArcFraction(seg.lut, localProgress);
59057
+ const point = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
59058
+ if (!autoOrient) return { translate: point };
59059
+ const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
59060
+ const rotateDeg = Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
59061
+ return { translate: point, rotateDeg };
59062
+ }
59063
+ function tFromArcFraction(lut, arcFrac) {
59064
+ const total = lut.ds[lut.ds.length - 1];
59065
+ const target = arcFrac * total;
59066
+ const { ts, ds } = lut;
59067
+ const last = ds.length - 1;
59068
+ if (target <= 0) return ts[0];
59069
+ if (target >= ds[last]) return ts[last];
59070
+ let lo = 1, hi = last;
59071
+ while (lo < hi) {
59072
+ const mid = lo + hi >>> 1;
59073
+ if (ds[mid] < target) lo = mid + 1;
59074
+ else hi = mid;
59075
+ }
59076
+ const dPrev = ds[hi - 1];
59077
+ const span = ds[hi] - dPrev;
59078
+ const frac = span > 0 ? (target - dPrev) / span : 0;
59079
+ return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);
59080
+ }
59081
+ var DEFAULT_FLATNESS_TOL = 0.5;
59082
+ var DEFAULT_ROTATION_TOL = 5;
59083
+ var DEFAULT_MAX_SAMPLES = 32;
59084
+ function materialiseMotionPathInPropAnim(anim, opts) {
59085
+ var _a, _b, _c, _d;
59086
+ if (!propAnimIsMotionPath(anim)) return anim;
59087
+ const kfs = (_a = anim.keyframes) != null ? _a : anim.kfs;
59088
+ if (!Array.isArray(kfs) || kfs.length < 2) return anim;
59089
+ const autoOrient = !!anim.autoOrient;
59090
+ const flatnessTol = (_b = opts == null ? void 0 : opts.flatnessTolerance) != null ? _b : DEFAULT_FLATNESS_TOL;
59091
+ const rotationTol = (_c = opts == null ? void 0 : opts.rotationTolerance) != null ? _c : DEFAULT_ROTATION_TOL;
59092
+ const maxSamples = (_d = opts == null ? void 0 : opts.maxSamplesPerSegment) != null ? _d : DEFAULT_MAX_SAMPLES;
59093
+ const out = [];
59094
+ const firstPos = getKfTranslate(kfs[0]);
59095
+ if (!firstPos) return anim;
59096
+ const firstRotate = autoOrient ? derivAngleForFirstKf(kfs[0], kfs[1]) : void 0;
59097
+ out.push(makeOutKf(
59098
+ getKfTime(kfs[0]),
59099
+ buildOutKfValue(getKfValueParts(kfs[0]), getKfValueParts(kfs[0]), 0, firstPos, firstRotate, autoOrient)
59100
+ ));
59101
+ for (let i = 0; i < kfs.length - 1; i++) {
59102
+ const prevKf = kfs[i];
59103
+ const nextKf = kfs[i + 1];
59104
+ const prevPos = getKfTranslate(prevKf);
59105
+ const nextPos = getKfTranslate(nextKf);
59106
+ if (!prevPos || !nextPos) {
59107
+ out.push(makeOutKf(
59108
+ getKfTime(nextKf),
59109
+ buildOutKfValue(getKfValueParts(nextKf), getKfValueParts(nextKf), 1, nextPos != null ? nextPos : [0, 0], void 0, autoOrient)
59110
+ ));
59111
+ continue;
59112
+ }
59113
+ if (autoOrient && i > 0) {
59114
+ insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol);
59115
+ }
59116
+ materialiseSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples);
59117
+ }
59118
+ const lastInE = getKfEasing(kfs[kfs.length - 1]);
59119
+ if (lastInE) out[out.length - 1].e = lastInE;
59120
+ if (autoOrient) unwrapAutoOrientRotations(out);
59121
+ const result = { kfs: out };
59122
+ if (anim.loop !== void 0) result.loop = anim.loop;
59123
+ return result;
59124
+ }
59125
+ function unwrapAutoOrientRotations(kfs) {
59126
+ var _a;
59127
+ let prev;
59128
+ for (const kf of kfs) {
59129
+ const v = (_a = kf.v) != null ? _a : kf.value;
59130
+ if (!v || typeof v.rotate !== "number") continue;
59131
+ if (prev === void 0) {
59132
+ prev = v.rotate;
59133
+ continue;
59134
+ }
59135
+ let r = v.rotate;
59136
+ while (r - prev > 180) r -= 360;
59137
+ while (r - prev < -180) r += 360;
59138
+ v.rotate = r;
59139
+ prev = r;
59140
+ }
59141
+ }
59142
+ function makeOutKf(time, value) {
59143
+ return { t: time, v: value };
59144
+ }
59145
+ function getKfValueParts(kf) {
59146
+ var _a;
59147
+ const v = (_a = kf.value) != null ? _a : kf.v;
59148
+ if (!v || typeof v !== "object" || Array.isArray(v)) return void 0;
59149
+ return v;
59150
+ }
59151
+ function interpolatePart(prev, next, p) {
59152
+ if (prev === void 0) return next;
59153
+ if (next === void 0) return prev;
59154
+ if (typeof prev === "number" && typeof next === "number") {
59155
+ return prev + (next - prev) * p;
59156
+ }
59157
+ if (Array.isArray(prev) && Array.isArray(next) && prev.length === next.length) {
59158
+ const out = new Array(prev.length);
59159
+ for (let i = 0; i < prev.length; i++) {
59160
+ const a = typeof prev[i] === "number" ? prev[i] : 0;
59161
+ const b = typeof next[i] === "number" ? next[i] : 0;
59162
+ out[i] = a + (b - a) * p;
59163
+ }
59164
+ return out;
59165
+ }
59166
+ return p < 0.5 ? prev : next;
59167
+ }
59168
+ function buildOutKfValue(prevV, nextV, p, translate, rotateDegFromAutoOrient, autoOrient) {
59169
+ const value = { translate };
59170
+ const keys = /* @__PURE__ */ new Set();
59171
+ if (prevV) for (const k of Object.keys(prevV)) keys.add(k);
59172
+ if (nextV) for (const k of Object.keys(nextV)) keys.add(k);
59173
+ for (const k of keys) {
59174
+ if (k === "translate") continue;
59175
+ if (k === "rotate" && autoOrient) continue;
59176
+ const pv = prevV == null ? void 0 : prevV[k];
59177
+ const nv = nextV == null ? void 0 : nextV[k];
59178
+ if (pv === void 0 && nv === void 0) continue;
59179
+ value[k] = interpolatePart(pv, nv, p);
59180
+ }
59181
+ if (rotateDegFromAutoOrient !== void 0) value.rotate = rotateDegFromAutoOrient;
59182
+ return value;
59183
+ }
59184
+ function derivAngleForFirstKf(kf0, kf1) {
59185
+ const p0 = getKfTranslate(kf0);
59186
+ const p1 = getKfTranslate(kf1);
59187
+ if (!p0 || !p1) return 0;
59188
+ const seg = getSegmentCache(kf0, kf1, p0, p1);
59189
+ const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, 0);
59190
+ return Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
59191
+ }
59192
+ function wrappedAngleDelta(a, b) {
59193
+ let d = a - b;
59194
+ while (d > 180) d -= 360;
59195
+ while (d < -180) d += 360;
59196
+ return d;
59197
+ }
59198
+ function insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol) {
59199
+ var _a;
59200
+ const lastKf = out[out.length - 1];
59201
+ const lastV = (_a = lastKf.v) != null ? _a : lastKf.value;
59202
+ const prevExit = lastV == null ? void 0 : lastV.rotate;
59203
+ if (typeof prevExit !== "number") return;
59204
+ const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
59205
+ const tanAtStart = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, 0);
59206
+ const nextEntry = Math.atan2(tanAtStart[1], tanAtStart[0]) * 180 / Math.PI;
59207
+ const delta = wrappedAngleDelta(nextEntry, prevExit);
59208
+ if (Math.abs(delta) <= rotationTol) return;
59209
+ const dupValue = buildOutKfValue(
59210
+ getKfValueParts(prevKf),
59211
+ getKfValueParts(prevKf),
59212
+ 0,
59213
+ prevPos,
59214
+ nextEntry,
59215
+ true
59216
+ );
59217
+ out.push(makeOutKf(getKfTime(prevKf), dupValue));
59218
+ }
59219
+ function materialiseSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples) {
59220
+ const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
59221
+ const prevTime = getKfTime(prevKf);
59222
+ const nextTime = getKfTime(nextKf);
59223
+ const prevEasing = getKfEasing(prevKf);
59224
+ const invertFn = invertEasing(prevEasing);
59225
+ const prevV = getKfValueParts(prevKf);
59226
+ const nextV = getKfValueParts(nextKf);
59227
+ const interiorTs = computeSampleTs(seg, autoOrient, flatnessTol, rotationTol, maxSamples);
59228
+ const samples = [];
59229
+ for (const t of interiorTs) {
59230
+ const arc = bezier2D_arcAtT(seg.lut, t);
59231
+ const p = clamp(seg.totalArc > 0 ? arc / seg.totalArc : t, 0, 1);
59232
+ const u = clamp(invertFn(p), 0, 1);
59233
+ const pos = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
59234
+ const sample = { u, p, pos };
59235
+ if (autoOrient) {
59236
+ const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
59237
+ sample.rotateDeg = Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
59238
+ }
59239
+ samples.push(sample);
59240
+ }
59241
+ let remaining = prevEasing;
59242
+ let prevU = 0;
59243
+ const startIdx = out.length - 1;
59244
+ for (let i = 0; i < samples.length; i++) {
59245
+ const s = samples[i];
59246
+ const xFrac = prevU < 1 ? clamp((s.u - prevU) / (1 - prevU), 0, 1) : 1;
59247
+ const { left, right } = splitEasing(remaining, xFrac);
59248
+ const ownerIdx = i === 0 ? startIdx : out.length - 1;
59249
+ if (left) out[ownerIdx].e = left;
59250
+ else delete out[ownerIdx].e;
59251
+ const tGlobal = prevTime + s.u * (nextTime - prevTime);
59252
+ const value = buildOutKfValue(prevV, nextV, s.p, s.pos, s.rotateDeg, autoOrient);
59253
+ out.push(makeOutKf(tGlobal, value));
59254
+ remaining = right;
59255
+ prevU = s.u;
59256
+ }
59257
+ }
59258
+ function computeSampleTs(seg, autoOrient, flatnessTol, rotationTol, maxSamples) {
59259
+ const extremes = [];
59260
+ addAxisExtremes(seg.P0[0], seg.P1[0], seg.P2[0], seg.P3[0], extremes);
59261
+ addAxisExtremes(seg.P0[1], seg.P1[1], seg.P2[1], seg.P3[1], extremes);
59262
+ extremes.sort((a, b) => a - b);
59263
+ const critical = [0];
59264
+ for (const t of extremes) {
59265
+ if (t > critical[critical.length - 1] + 1e-6 && t < 1 - 1e-6) {
59266
+ critical.push(t);
59267
+ }
59268
+ }
59269
+ critical.push(1);
59270
+ const out = [];
59271
+ const budget = { remaining: maxSamples - critical.length };
59272
+ for (let i = 0; i < critical.length - 1; i++) {
59273
+ bisect(critical[i], critical[i + 1], out, seg, autoOrient, flatnessTol, rotationTol, budget);
59274
+ }
59275
+ return out;
59276
+ }
59277
+ function addAxisExtremes(p0, p1, p2, p3, out) {
59278
+ const a = p1 - p0;
59279
+ const b = p2 - p1;
59280
+ const c = p3 - p2;
59281
+ const A = a - 2 * b + c;
59282
+ const B = 2 * (b - a);
59283
+ const C = a;
59284
+ if (Math.abs(A) < 1e-10) {
59285
+ if (Math.abs(B) > 1e-10) {
59286
+ const t = -C / B;
59287
+ if (t > 1e-6 && t < 1 - 1e-6) out.push(t);
59288
+ }
59289
+ return;
59290
+ }
59291
+ const disc = B * B - 4 * A * C;
59292
+ if (disc < 0) return;
59293
+ const sq = Math.sqrt(disc);
59294
+ const t1 = (-B - sq) / (2 * A);
59295
+ const t2 = (-B + sq) / (2 * A);
59296
+ if (t1 > 1e-6 && t1 < 1 - 1e-6) out.push(t1);
59297
+ if (t2 > 1e-6 && t2 < 1 - 1e-6) out.push(t2);
59298
+ }
59299
+ function bisect(tA, tB, out, seg, autoOrient, flatnessTol, rotationTol, budget) {
59300
+ const tMid = (tA + tB) / 2;
59301
+ const pA = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA);
59302
+ const pB = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tB);
59303
+ const span = tB - tA;
59304
+ const p25 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA + span * 0.25);
59305
+ const p50 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tMid);
59306
+ const p75 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA + span * 0.75);
59307
+ const dev = Math.max(
59308
+ perpDist(p25, pA, pB),
59309
+ perpDist(p50, pA, pB),
59310
+ perpDist(p75, pA, pB)
59311
+ );
59312
+ let rotOk = true;
59313
+ if (autoOrient) {
59314
+ const tanA = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, tA);
59315
+ const tanB = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, tB);
59316
+ const angA = Math.atan2(tanA[1], tanA[0]) * 180 / Math.PI;
59317
+ const angB = Math.atan2(tanB[1], tanB[0]) * 180 / Math.PI;
59318
+ let delta = Math.abs(angA - angB);
59319
+ if (delta > 180) delta = 360 - delta;
59320
+ if (delta > rotationTol) rotOk = false;
59321
+ }
59322
+ if (dev <= flatnessTol && rotOk || budget.remaining <= 0 || span < 1e-6) {
59323
+ out.push(tB);
59324
+ return;
59325
+ }
59326
+ budget.remaining -= 1;
59327
+ bisect(tA, tMid, out, seg, autoOrient, flatnessTol, rotationTol, budget);
59328
+ bisect(tMid, tB, out, seg, autoOrient, flatnessTol, rotationTol, budget);
59329
+ }
59330
+ function perpDist(q, pA, pB) {
59331
+ const dx = pB[0] - pA[0];
59332
+ const dy = pB[1] - pA[1];
59333
+ const len2 = dx * dx + dy * dy;
59334
+ if (len2 < 1e-20) {
59335
+ const qdx = q[0] - pA[0];
59336
+ const qdy = q[1] - pA[1];
59337
+ return Math.sqrt(qdx * qdx + qdy * qdy);
59338
+ }
59339
+ const cross = (q[0] - pA[0]) * dy - (q[1] - pA[1]) * dx;
59340
+ return Math.abs(cross) / Math.sqrt(len2);
59341
+ }
59342
+ function materialiseMotionPathsInTree(root, opts) {
59343
+ const out = walkAndMaterialise(root, opts);
59344
+ return out != null ? out : root;
59345
+ }
59346
+ function walkAndMaterialise(node, opts) {
59347
+ let newChildren;
59348
+ if (node.children) {
59349
+ for (let i = 0; i < node.children.length; i++) {
59350
+ const ch = node.children[i];
59351
+ const ret = walkAndMaterialise(ch, opts);
59352
+ if (ret !== null) {
59353
+ if (!newChildren) newChildren = node.children.slice();
59354
+ newChildren[i] = ret;
59355
+ }
59356
+ }
59357
+ }
59358
+ let newAnimate;
59359
+ const animBucket = node.animate;
59360
+ if (animBucket && typeof animBucket === "object" && !Array.isArray(animBucket)) {
59361
+ const animDef = animBucket;
59362
+ const transformAnim = animDef.transform;
59363
+ if (transformAnim && typeof transformAnim === "object" && propAnimIsMotionPath(transformAnim)) {
59364
+ const materialised = materialiseMotionPathInPropAnim(transformAnim, opts);
59365
+ if (materialised !== transformAnim) {
59366
+ newAnimate = __spreadProps(__spreadValues({}, animDef), { transform: materialised });
59367
+ }
59368
+ }
59369
+ }
59370
+ if (!newChildren && !newAnimate) return null;
59371
+ const cloned = __spreadValues({}, node);
59372
+ if (newChildren) cloned.children = newChildren;
59373
+ if (newAnimate) cloned.animate = newAnimate;
59374
+ return cloned;
59375
+ }
59376
+ function parsePathCommands(d) {
59377
+ const tokens = d.split(/([MLCZmlcz]|[\s,]+)/).map((t) => t.trim()).filter((t) => t && t !== ",");
59378
+ const commands = [];
59379
+ let currentCommand = null;
59380
+ for (const token of tokens) {
59381
+ if (/[MLCZmlcz]/.test(token)) {
59382
+ currentCommand = { type: token, values: [] };
59383
+ commands.push(currentCommand);
59384
+ } else if (currentCommand) {
59385
+ const value = +token;
59386
+ currentCommand.values.push(Number.isNaN(value) ? 0 : value);
59387
+ }
59388
+ }
59389
+ return commands;
59390
+ }
59391
+ function parseSvgPathToBezier(d) {
59392
+ const res = [];
59393
+ let currentPath;
59394
+ const commands = parsePathCommands(d);
58811
59395
  for (const command of commands) {
58812
59396
  const type = command.type;
58813
59397
  const values = command.values;
@@ -58823,478 +59407,1291 @@ ${codeFrame}` : message);
58823
59407
  res.push(currentPath);
58824
59408
  continue;
58825
59409
  }
58826
- if (!currentPath) {
58827
- currentPath = {
58828
- v: [[0, 0]],
58829
- i: [[0, 0]],
58830
- o: [[0, 0]],
58831
- c: false
58832
- };
58833
- res.push(currentPath);
59410
+ if (!currentPath) {
59411
+ currentPath = {
59412
+ v: [[0, 0]],
59413
+ i: [[0, 0]],
59414
+ o: [[0, 0]],
59415
+ c: false
59416
+ };
59417
+ res.push(currentPath);
59418
+ }
59419
+ if (type === "L") {
59420
+ const x = values[0] || 0;
59421
+ const y = values[1] || 0;
59422
+ currentPath.v.push([x, y]);
59423
+ currentPath.i.push([x, y]);
59424
+ currentPath.o.push([x, y]);
59425
+ } else if (type === "C") {
59426
+ const outX = values[0] || 0;
59427
+ const outY = values[1] || 0;
59428
+ const inX2 = values[2] || 0;
59429
+ const inY2 = values[3] || 0;
59430
+ const x2 = values[4] || 0;
59431
+ const y2 = values[5] || 0;
59432
+ currentPath.o[currentPath.o.length - 1] = [outX, outY];
59433
+ currentPath.v.push([x2, y2]);
59434
+ currentPath.i.push([inX2, inY2]);
59435
+ currentPath.o.push([x2, y2]);
59436
+ } else if (type === "Z" || type === "z") {
59437
+ currentPath.c = true;
59438
+ } else {
59439
+ console.warn('Unsupported path command "' + type + '"');
59440
+ }
59441
+ }
59442
+ return res;
59443
+ }
59444
+ function extractPathData(str) {
59445
+ if (str.startsWith("path(") && str.endsWith(")")) {
59446
+ return str.slice(5, -1);
59447
+ }
59448
+ if (/^[MmZzLlHhVvCcSsQqTtAa]/.test(str)) {
59449
+ return str;
59450
+ }
59451
+ return void 0;
59452
+ }
59453
+ function isPathString(value) {
59454
+ return typeof value === "string" && extractPathData(value) !== void 0;
59455
+ }
59456
+ function normalizePathValue(value) {
59457
+ if (value && typeof value === "object" && typeof value.path === "string") {
59458
+ const d = extractPathData(value.path);
59459
+ return d ? { paths: parseSvgPathToBezier(d) } : value;
59460
+ }
59461
+ if (value && typeof value === "object" && "paths" in value) {
59462
+ const pathsArray = value.paths;
59463
+ if (Array.isArray(pathsArray) && pathsArray.length > 0) {
59464
+ if (isPathString(pathsArray[0])) {
59465
+ const paths = [];
59466
+ for (const pathStr2 of pathsArray) {
59467
+ const d = extractPathData(pathStr2);
59468
+ if (d) {
59469
+ paths.push(...parseSvgPathToBezier(d));
59470
+ }
59471
+ }
59472
+ return { paths };
59473
+ }
59474
+ }
59475
+ return value;
59476
+ }
59477
+ if (Array.isArray(value)) {
59478
+ if (value.length > 0 && isPathString(value[0])) {
59479
+ const paths = [];
59480
+ for (const pathStr2 of value) {
59481
+ const d = extractPathData(pathStr2);
59482
+ if (d) {
59483
+ paths.push(...parseSvgPathToBezier(d));
59484
+ }
59485
+ }
59486
+ return { paths };
59487
+ }
59488
+ return { paths: value };
59489
+ }
59490
+ if (isPathString(value)) {
59491
+ const d = extractPathData(value);
59492
+ return { paths: parseSvgPathToBezier(d) };
59493
+ }
59494
+ return value;
59495
+ }
59496
+ function resolveEasing(easing, defs) {
59497
+ var _a;
59498
+ if (!easing) return void 0;
59499
+ if (Array.isArray(easing)) {
59500
+ return easing;
59501
+ }
59502
+ if ((_a = defs == null ? void 0 : defs.easings) == null ? void 0 : _a[easing]) {
59503
+ return defs.easings[easing];
59504
+ }
59505
+ console.warn("Unknown easing name: " + easing);
59506
+ return void 0;
59507
+ }
59508
+ function resolveAnimation(animRef, defs) {
59509
+ var _a;
59510
+ if (typeof animRef === "string") {
59511
+ const resolved = (_a = defs == null ? void 0 : defs.animations) == null ? void 0 : _a[animRef];
59512
+ if (!resolved) {
59513
+ console.warn("Unknown animation name: " + animRef);
59514
+ }
59515
+ return resolved;
59516
+ }
59517
+ return animRef;
59518
+ }
59519
+ function resolveElementAnimation(animate, defs) {
59520
+ if (!animate) return [];
59521
+ const results = [];
59522
+ if (typeof animate === "string") {
59523
+ const resolved = resolveAnimation(animate, defs);
59524
+ if (resolved) results.push(resolved);
59525
+ } else if (Array.isArray(animate)) {
59526
+ for (const item of animate) {
59527
+ const resolved = resolveAnimation(item, defs);
59528
+ if (resolved) results.push(resolved);
58834
59529
  }
58835
- if (type === "L") {
58836
- const x = values[0] || 0;
58837
- const y = values[1] || 0;
58838
- currentPath.v.push([x, y]);
58839
- currentPath.i.push([x, y]);
58840
- currentPath.o.push([x, y]);
58841
- } else if (type === "C") {
58842
- const outX = values[0] || 0;
58843
- const outY = values[1] || 0;
58844
- const inX2 = values[2] || 0;
58845
- const inY2 = values[3] || 0;
58846
- const x2 = values[4] || 0;
58847
- const y2 = values[5] || 0;
58848
- currentPath.o[currentPath.o.length - 1] = [outX, outY];
58849
- currentPath.v.push([x2, y2]);
58850
- currentPath.i.push([inX2, inY2]);
58851
- currentPath.o.push([x2, y2]);
58852
- } else if (type === "Z" || type === "z") {
58853
- currentPath.c = true;
59530
+ } else {
59531
+ results.push(animate);
59532
+ }
59533
+ return results;
59534
+ }
59535
+ function interpolateValue(propName, a, b, t) {
59536
+ var _a, _b;
59537
+ if (propName === "d") {
59538
+ const aPaths = (_a = a == null ? void 0 : a.paths) != null ? _a : Array.isArray(a) ? a : [];
59539
+ const bPaths = (_b = b == null ? void 0 : b.paths) != null ? _b : Array.isArray(b) ? b : [];
59540
+ return { paths: interpolateBeziers(aPaths, bPaths, t) };
59541
+ }
59542
+ if (COLOUR_ATTR_NAMES.has(propName)) {
59543
+ return interpolateColor(a || [0, 0, 0, 1], b || [0, 0, 0, 1], t);
59544
+ }
59545
+ if (propName === "transform" && typeof a === "object" && a !== null && !Array.isArray(a) && typeof b === "object" && b !== null && !Array.isArray(b)) {
59546
+ return interpolateTransformParts(a, b, t);
59547
+ }
59548
+ if (propName === "rotate" && typeof a === "number" && typeof b === "number") {
59549
+ return interpolateNum(a, b, t);
59550
+ }
59551
+ if (TRANSFORM_FN_NAMES.has(propName) || propName === "stroke-dasharray" || propName === "strokeDasharray") {
59552
+ return interpolateVec(a || [], b || [], t);
59553
+ }
59554
+ return interpolateNum(+(a || 0), +(b || 0), t);
59555
+ }
59556
+ function interpolateTransformParts(a, b, t) {
59557
+ const keys = /* @__PURE__ */ new Set([...Object.keys(a != null ? a : {}), ...Object.keys(b != null ? b : {})]);
59558
+ const out = {};
59559
+ for (const k of keys) {
59560
+ const av = a == null ? void 0 : a[k];
59561
+ const bv = b == null ? void 0 : b[k];
59562
+ if (k === "rotate") {
59563
+ out[k] = interpolateNum(+(av != null ? av : 0), +(bv != null ? bv : 0), t);
59564
+ } else if (k === "translate" || k === "scale" || k === "origin") {
59565
+ const fallback = k === "scale" ? [1, 1] : [0, 0];
59566
+ out[k] = interpolateVec(av || fallback, bv || fallback, t);
58854
59567
  } else {
58855
- console.warn('Unsupported path command "' + type + '"');
59568
+ out[k] = bv != null ? bv : av;
59569
+ }
59570
+ }
59571
+ return out;
59572
+ }
59573
+ function expandLoopKeyframes(propName, keyframes, loop, duration) {
59574
+ var _a, _b, _c, _d, _e;
59575
+ const totalIntervals = keyframes.length - 1;
59576
+ const segCount = clamp((_a = loop.segmentCount) != null ? _a : totalIntervals, 1, totalIntervals);
59577
+ let segKfs;
59578
+ if (loop.before) {
59579
+ segKfs = keyframes.slice(0, segCount + 1);
59580
+ } else {
59581
+ segKfs = keyframes.slice(totalIntervals - segCount);
59582
+ }
59583
+ const firstT = (_b = keyframes[0].t) != null ? _b : 0;
59584
+ const lastT = (_c = keyframes[keyframes.length - 1].t) != null ? _c : 0;
59585
+ let fillStart, fillEnd;
59586
+ if (loop.before) {
59587
+ fillStart = 0;
59588
+ fillEnd = firstT;
59589
+ } else {
59590
+ fillStart = lastT;
59591
+ fillEnd = duration;
59592
+ }
59593
+ const fillDuration = fillEnd - fillStart;
59594
+ if (fillDuration <= 0) return keyframes;
59595
+ const segStartT = (_d = segKfs[0].t) != null ? _d : 0;
59596
+ const segEndT = (_e = segKfs[segKfs.length - 1].t) != null ? _e : 0;
59597
+ const segDuration = segEndT - segStartT;
59598
+ if (segDuration <= 0) return keyframes;
59599
+ const template = segKfs.map((kf) => {
59600
+ var _a2, _b2;
59601
+ return {
59602
+ relT: (kf.t - segStartT) / segDuration,
59603
+ v: kf.v,
59604
+ e: kf.e,
59605
+ tangentIn: (_a2 = kf.tangentIn) != null ? _a2 : kf.ti,
59606
+ tangentOut: (_b2 = kf.tangentOut) != null ? _b2 : kf.to
59607
+ };
59608
+ });
59609
+ const fullReps = Math.floor(fillDuration / segDuration);
59610
+ const remainder = fillDuration - fullReps * segDuration;
59611
+ const partialFraction = remainder / segDuration;
59612
+ const looped = [];
59613
+ function appendRep(repStart, isReversed, partial) {
59614
+ let entries;
59615
+ if (isReversed) {
59616
+ entries = [];
59617
+ for (let i = template.length - 1; i >= 0; i--) {
59618
+ entries.push({
59619
+ relT: 1 - template[i].relT,
59620
+ v: template[i].v,
59621
+ // Easing for reversed transition: use reversed easing from the forward "from" keyframe
59622
+ e: i > 0 ? reverseEasing(template[i - 1].e) : void 0,
59623
+ // Reversed traversal swaps each vertex's in/out spatial tangents
59624
+ // (geometry is identical, walked backwards), so curvature and
59625
+ // auto-orientation survive the reversed rep.
59626
+ tangentIn: template[i].tangentOut,
59627
+ tangentOut: template[i].tangentIn
59628
+ });
59629
+ }
59630
+ } else {
59631
+ entries = template;
59632
+ }
59633
+ const cutRelT = partial !== void 0 ? partial : 1;
59634
+ for (let i = 0; i < entries.length; i++) {
59635
+ const entry = entries[i];
59636
+ if (entry.relT > cutRelT + 1e-9) {
59637
+ const prev = entries[i - 1];
59638
+ const intervalSpan = entry.relT - prev.relT;
59639
+ const localFrac = (cutRelT - prev.relT) / intervalSpan;
59640
+ const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
59641
+ const cutValue = interpolateValue(propName, prev.v, entry.v, easedFrac);
59642
+ const { left: leftEasing } = splitEasing(prev.e, localFrac);
59643
+ if (looped.length > 0 && prev.relT <= cutRelT) {
59644
+ looped[looped.length - 1].e = leftEasing;
59645
+ }
59646
+ looped.push({ t: repStart + cutRelT * segDuration, v: cutValue, e: void 0 });
59647
+ return;
59648
+ }
59649
+ const pushed = {
59650
+ t: repStart + entry.relT * segDuration,
59651
+ v: entry.v,
59652
+ e: i < entries.length - 1 ? entry.e : void 0
59653
+ };
59654
+ if (entry.tangentIn) pushed.tangentIn = entry.tangentIn;
59655
+ if (entry.tangentOut) pushed.tangentOut = entry.tangentOut;
59656
+ looped.push(pushed);
59657
+ }
59658
+ }
59659
+ for (let rep = 0; rep < fullReps; rep++) {
59660
+ const distFromBoundary = loop.before ? fullReps - 1 - rep : rep;
59661
+ const isReversed = !!loop.alternate && distFromBoundary % 2 === 0;
59662
+ const repStart = fillStart + rep * segDuration;
59663
+ appendRep(repStart, isReversed);
59664
+ }
59665
+ if (partialFraction > 1e-9) {
59666
+ const isReversed = !!loop.alternate && fullReps % 2 === 0;
59667
+ const repStart = fillStart + fullReps * segDuration;
59668
+ appendRep(repStart, isReversed, partialFraction);
59669
+ }
59670
+ if (loop.before) {
59671
+ return [...looped, ...keyframes];
59672
+ } else {
59673
+ return [...keyframes, ...looped];
59674
+ }
59675
+ }
59676
+ function normalizeKeyframes(propName, propAnim, duration, defs) {
59677
+ var _a, _b, _c, _d, _e, _f, _g;
59678
+ const keyframes = propAnim.keyframes || propAnim.kfs || [];
59679
+ const normalized = [];
59680
+ for (const kf of keyframes) {
59681
+ const timePct = (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
59682
+ let value = (_c = kf.value) != null ? _c : kf.v;
59683
+ const easing = (_d = kf.easing) != null ? _d : kf.e;
59684
+ if (propName === "d") {
59685
+ value = normalizePathValue(value);
59686
+ }
59687
+ const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
59688
+ if (COLOUR_ATTR_NAMES.has(propNameKebab)) {
59689
+ value = (_e = parseColor(value)) != null ? _e : value;
59690
+ }
59691
+ const normKf = {
59692
+ t: timePct,
59693
+ v: value,
59694
+ e: resolveEasing(easing, defs)
59695
+ };
59696
+ const tIn = (_f = kf.tangentIn) != null ? _f : kf.ti;
59697
+ const tOut = (_g = kf.tangentOut) != null ? _g : kf.to;
59698
+ if (tIn) normKf.tangentIn = tIn;
59699
+ if (tOut) normKf.tangentOut = tOut;
59700
+ normalized.push(normKf);
59701
+ }
59702
+ normalized.sort((a, b) => {
59703
+ var _a2, _b2;
59704
+ return ((_a2 = a.t) != null ? _a2 : 0) - ((_b2 = b.t) != null ? _b2 : 0);
59705
+ });
59706
+ const loopRaw = propAnim.loop;
59707
+ const loop = loopRaw === true ? {} : loopRaw || void 0;
59708
+ if (loop && normalized.length >= 2) {
59709
+ return expandLoopKeyframes(propName, normalized, loop, duration);
59710
+ }
59711
+ return normalized;
59712
+ }
59713
+ function mergeAnimationDefinitions(animations) {
59714
+ const merged = {};
59715
+ for (const anim of animations) {
59716
+ for (const [prop, propAnim] of Object.entries(anim)) {
59717
+ merged[prop] = propAnim;
59718
+ }
59719
+ }
59720
+ return merged;
59721
+ }
59722
+ function materialiseInternalLoopsInPropAnim(propName, propAnim, duration) {
59723
+ var _a;
59724
+ const loopRaw = propAnim.loop;
59725
+ if (loopRaw === void 0 || loopRaw === null || loopRaw === false) return propAnim;
59726
+ const loop = loopRaw === true ? {} : loopRaw;
59727
+ const rawKfs = (_a = propAnim.keyframes) != null ? _a : propAnim.kfs;
59728
+ if (!Array.isArray(rawKfs) || rawKfs.length < 2) return propAnim;
59729
+ const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
59730
+ const isColour = COLOUR_ATTR_NAMES.has(propNameKebab);
59731
+ const kfs = rawKfs.map((kf) => {
59732
+ var _a2, _b, _c, _d, _e, _f, _g, _h;
59733
+ const t = (_a2 = kf.t) != null ? _a2 : kf.time;
59734
+ let v = (_b = kf.v) != null ? _b : kf.value;
59735
+ if (propName === "d") v = normalizePathValue(v);
59736
+ if (isColour) v = (_c = parseColor(v)) != null ? _c : v;
59737
+ const e = (_d = kf.e) != null ? _d : kf.easing;
59738
+ const out2 = { t, v, e };
59739
+ if ((_e = kf.tangentIn) != null ? _e : kf.ti) out2.tangentIn = (_f = kf.tangentIn) != null ? _f : kf.ti;
59740
+ if ((_g = kf.tangentOut) != null ? _g : kf.to) out2.tangentOut = (_h = kf.tangentOut) != null ? _h : kf.to;
59741
+ return out2;
59742
+ });
59743
+ const expanded = expandLoopKeyframes(propName, kfs, loop, duration);
59744
+ const out = { kfs: expanded };
59745
+ if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
59746
+ return out;
59747
+ }
59748
+ function materialiseInternalLoopsInTree(root, duration) {
59749
+ const ret = walkAndMaterialiseLoops(root, duration);
59750
+ return ret != null ? ret : root;
59751
+ }
59752
+ function walkAndMaterialiseLoops(node, duration) {
59753
+ let newChildren;
59754
+ if (node.children) {
59755
+ for (let i = 0; i < node.children.length; i++) {
59756
+ const ret = walkAndMaterialiseLoops(node.children[i], duration);
59757
+ if (ret !== null) {
59758
+ if (!newChildren) newChildren = node.children.slice();
59759
+ newChildren[i] = ret;
59760
+ }
59761
+ }
59762
+ }
59763
+ let newAnimate;
59764
+ const animBucket = node.animate;
59765
+ if (animBucket && typeof animBucket === "object" && !Array.isArray(animBucket)) {
59766
+ const animDef = animBucket;
59767
+ for (const propName of Object.keys(animDef)) {
59768
+ const propAnim = animDef[propName];
59769
+ const materialised = materialiseInternalLoopsInPropAnim(propName, propAnim, duration);
59770
+ if (materialised !== propAnim) {
59771
+ if (!newAnimate) newAnimate = __spreadValues({}, animDef);
59772
+ newAnimate[propName] = materialised;
59773
+ }
59774
+ }
59775
+ }
59776
+ if (!newChildren && !newAnimate) return null;
59777
+ const cloned = __spreadValues({}, node);
59778
+ if (newChildren) cloned.children = newChildren;
59779
+ if (newAnimate) cloned.animate = newAnimate;
59780
+ return cloned;
59781
+ }
59782
+ var _elementIdCounter = 0;
59783
+ function generateElementId() {
59784
+ return "_px_el_" + ++_elementIdCounter;
59785
+ }
59786
+ function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.webapi) {
59787
+ const normalized = {};
59788
+ for (const [propName, propAnim] of Object.entries(animDef)) {
59789
+ const normalizedKfs = normalizeKeyframes(propName, propAnim, duration, defs);
59790
+ if (normalizedKfs.length > 0) {
59791
+ const out = { kfs: normalizedKfs };
59792
+ if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
59793
+ if (propAnim.loop !== void 0) out.loop = propAnim.loop;
59794
+ normalized[propName] = engine === PxAnimatorEngine.webapi && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
59795
+ }
59796
+ }
59797
+ return normalized;
59798
+ }
59799
+ function getNormalisedBindings(doc, engine = PxAnimatorEngine.webapi) {
59800
+ const animatorConfig = getAnimatorConfig(doc) || {};
59801
+ const defs = getDefs(doc);
59802
+ const duration = animatorConfig.duration || 1e3;
59803
+ const bindings = [];
59804
+ const processAnimation = (id, animate) => {
59805
+ if (!animate) return null;
59806
+ const animDefs = resolveElementAnimation(animate, defs);
59807
+ if (animDefs.length === 0) return null;
59808
+ const merged = mergeAnimationDefinitions(animDefs);
59809
+ const normalizedAnim = normalizeAnimationDefinition(merged, duration, defs, engine);
59810
+ if (Object.keys(normalizedAnim).length === 0) return null;
59811
+ return {
59812
+ id,
59813
+ animate: normalizedAnim
59814
+ };
59815
+ };
59816
+ const docBindings = getBindings(doc);
59817
+ if (docBindings) {
59818
+ for (const binding of docBindings) {
59819
+ const normalized = processAnimation(binding.id, binding.animate);
59820
+ if (normalized) bindings.push(normalized);
59821
+ }
59822
+ }
59823
+ const processNode = (node) => {
59824
+ const inlineAnim = node.animate;
59825
+ if (inlineAnim && Object.keys(inlineAnim).length > 0) {
59826
+ const nodeId = node.id || generateElementId();
59827
+ node.id = nodeId;
59828
+ const normalized = processAnimation(nodeId, inlineAnim);
59829
+ if (normalized) bindings.push(normalized);
59830
+ }
59831
+ if (node.children) {
59832
+ for (let i = 0; i < node.children.length; i++) {
59833
+ processNode(node.children[i]);
59834
+ }
59835
+ }
59836
+ };
59837
+ if (doc.children) {
59838
+ for (let i = 0; i < doc.children.length; i++) {
59839
+ processNode(doc.children[i]);
58856
59840
  }
58857
59841
  }
58858
- return res;
59842
+ return bindings;
58859
59843
  }
58860
- function extractPathData(str) {
58861
- if (str.startsWith("path(") && str.endsWith(")")) {
58862
- return str.slice(5, -1);
58863
- }
58864
- if (/^[MmZzLlHhVvCcSsQqTtAa]/.test(str)) {
58865
- return str;
59844
+ function getKeyframesPair(keyframes, progress) {
59845
+ var _a, _b;
59846
+ let prevKf = keyframes[0];
59847
+ let nextKf = keyframes[keyframes.length - 1];
59848
+ for (let j = 0; j < keyframes.length - 1; j++) {
59849
+ const aOff = (_a = keyframes[j].t) != null ? _a : 0;
59850
+ const bOff = (_b = keyframes[j + 1].t) != null ? _b : 0;
59851
+ if (aOff <= progress && progress <= bOff) {
59852
+ prevKf = keyframes[j];
59853
+ nextKf = keyframes[j + 1];
59854
+ break;
59855
+ }
58866
59856
  }
58867
- return void 0;
58868
- }
58869
- function isPathString(value) {
58870
- return typeof value === "string" && extractPathData(value) !== void 0;
59857
+ return { prevKf, nextKf };
58871
59858
  }
58872
- function normalizePathValue(value) {
58873
- if (value && typeof value === "object" && typeof value.path === "string") {
58874
- const d = extractPathData(value.path);
58875
- return d ? { paths: parseSvgPathToBezier(d) } : value;
59859
+ function calcPropertyValue(propName, propAnim, progress) {
59860
+ var _a, _b, _c, _d, _e, _f, _g;
59861
+ const keyframes = propAnim.kfs || propAnim.keyframes || [];
59862
+ if (keyframes.length === 0) return null;
59863
+ const { prevKf, nextKf } = getKeyframesPair(keyframes, progress);
59864
+ let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a = prevKf.t) != null ? _a : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
59865
+ localProgress = clamp(localProgress, 0, 1);
59866
+ const easing = (_c = prevKf.e) != null ? _c : prevKf.easing;
59867
+ if (easing && Array.isArray(easing)) {
59868
+ try {
59869
+ localProgress = cubicBezier(easing)(localProgress);
59870
+ } catch (e) {
59871
+ }
58876
59872
  }
58877
- if (value && typeof value === "object" && "paths" in value) {
58878
- const pathsArray = value.paths;
58879
- if (Array.isArray(pathsArray) && pathsArray.length > 0) {
58880
- if (isPathString(pathsArray[0])) {
58881
- const paths = [];
58882
- for (const pathStr2 of pathsArray) {
58883
- const d = extractPathData(pathStr2);
58884
- if (d) {
58885
- paths.push(...parseSvgPathToBezier(d));
58886
- }
58887
- }
58888
- return { paths };
59873
+ let cssAttrName = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
59874
+ let cssValue = null;
59875
+ const prevV = (_d = prevKf == null ? void 0 : prevKf.v) != null ? _d : prevKf == null ? void 0 : prevKf.value;
59876
+ const nextV = (_e = nextKf == null ? void 0 : nextKf.v) != null ? _e : nextKf == null ? void 0 : nextKf.value;
59877
+ if (cssAttrName === "d") {
59878
+ const prevPaths = (_f = prevV == null ? void 0 : prevV.paths) != null ? _f : Array.isArray(prevV) ? prevV : [];
59879
+ const nextPaths = (_g = nextV == null ? void 0 : nextV.paths) != null ? _g : Array.isArray(nextV) ? nextV : [];
59880
+ cssValue = interpolateBeziers(
59881
+ prevPaths,
59882
+ nextPaths,
59883
+ localProgress
59884
+ ).map((bz) => bezierToSvgPath(bz)).join("");
59885
+ } else if (COLOUR_ATTR_NAMES.has(cssAttrName)) {
59886
+ cssValue = toRGBA(interpolateColor(
59887
+ prevV || [0, 0, 0, 1],
59888
+ nextV || [0, 0, 0, 1],
59889
+ localProgress
59890
+ ));
59891
+ cssAttrName = propName;
59892
+ } else if (cssAttrName === "stroke-dasharray") {
59893
+ cssValue = interpolateVec(
59894
+ prevV || [],
59895
+ nextV || [],
59896
+ localProgress
59897
+ ).join(" ");
59898
+ cssAttrName = propName;
59899
+ } else if (cssAttrName === "transform" && prevV !== null && typeof prevV === "object" && !Array.isArray(prevV)) {
59900
+ const partKeys = /* @__PURE__ */ new Set([
59901
+ ...prevV ? Object.keys(prevV) : [],
59902
+ ...nextV ? Object.keys(nextV) : []
59903
+ ]);
59904
+ const partsResult = {};
59905
+ for (const partKey of partKeys) {
59906
+ const prevPart = prevV == null ? void 0 : prevV[partKey];
59907
+ const nextPart = nextV == null ? void 0 : nextV[partKey];
59908
+ if (partKey === "rotate") {
59909
+ partsResult.rotate = interpolateNum(+(prevPart != null ? prevPart : 0), +(nextPart != null ? nextPart : 0), localProgress);
59910
+ } else if (partKey === "translate" || partKey === "scale" || partKey === "origin") {
59911
+ const fallback = partKey === "scale" ? [1, 1] : [0, 0];
59912
+ const interp = interpolateVec(prevPart || fallback, nextPart || fallback, localProgress);
59913
+ partsResult[partKey] = interp;
58889
59914
  }
58890
59915
  }
58891
- return value;
58892
- }
58893
- if (Array.isArray(value)) {
58894
- if (value.length > 0 && isPathString(value[0])) {
58895
- const paths = [];
58896
- for (const pathStr2 of value) {
58897
- const d = extractPathData(pathStr2);
58898
- if (d) {
58899
- paths.push(...parseSvgPathToBezier(d));
58900
- }
59916
+ if (propAnimIsMotionPath(propAnim)) {
59917
+ const prevTr = prevV.translate;
59918
+ const nextTr = nextV.translate;
59919
+ if (Array.isArray(prevTr) && Array.isArray(nextTr)) {
59920
+ const sample = evaluateMotionPathSegment(
59921
+ prevKf,
59922
+ nextKf,
59923
+ [+prevTr[0], +prevTr[1]],
59924
+ [+nextTr[0], +nextTr[1]],
59925
+ localProgress,
59926
+ !!propAnim.autoOrient
59927
+ );
59928
+ partsResult.translate = [sample.translate[0], sample.translate[1]];
59929
+ if (sample.rotateDeg !== void 0) partsResult.rotate = sample.rotateDeg;
58901
59930
  }
58902
- return { paths };
58903
59931
  }
58904
- return { paths: value };
59932
+ cssValue = composeTransformParts(partsResult, { withUnits: false });
59933
+ cssAttrName = "transform";
59934
+ } else if (cssAttrName === "translate") {
59935
+ const v = interpolateVec(
59936
+ prevV || [0, 0],
59937
+ nextV || [0, 0],
59938
+ localProgress
59939
+ );
59940
+ cssValue = "translate(" + v.join(",") + ")";
59941
+ cssAttrName = "transform";
59942
+ } else if (cssAttrName === "rotate") {
59943
+ const v = interpolateNum(
59944
+ +(prevV || 0),
59945
+ +(nextV || 0),
59946
+ localProgress
59947
+ );
59948
+ cssValue = "rotate(" + v + ")";
59949
+ cssAttrName = "transform";
59950
+ } else if (cssAttrName === "scale") {
59951
+ const v = interpolateVec(
59952
+ prevV || [1, 1],
59953
+ nextV || [1, 1],
59954
+ localProgress
59955
+ );
59956
+ cssValue = "scale(" + v.join(",") + ")";
59957
+ cssAttrName = "transform";
59958
+ } else {
59959
+ const num2 = interpolateNum(
59960
+ +(prevV || 0),
59961
+ +(nextV || 0),
59962
+ localProgress
59963
+ );
59964
+ cssValue = num2;
58905
59965
  }
58906
- if (isPathString(value)) {
58907
- const d = extractPathData(value);
58908
- return { paths: parseSvgPathToBezier(d) };
59966
+ if (PCT_BASED_ATTR_NAMES.has(cssAttrName) && typeof cssValue === "number") {
59967
+ cssValue = cssValue * 100 + "%";
58909
59968
  }
58910
- return value;
59969
+ return { k: cssAttrName, v: cssValue === null ? "" : "" + cssValue };
58911
59970
  }
58912
- function resolveEasing(easing, defs) {
58913
- var _a;
58914
- if (!easing) return void 0;
58915
- if (Array.isArray(easing)) {
58916
- return easing;
59971
+ function calcAnimationValues(animDef, progress) {
59972
+ const result = {};
59973
+ for (const [propName, propAnim] of Object.entries(animDef)) {
59974
+ const computed3 = calcPropertyValue(propName, propAnim, progress);
59975
+ if (computed3) {
59976
+ result[computed3.k] = computed3.v;
59977
+ }
58917
59978
  }
58918
- if ((_a = defs == null ? void 0 : defs.easings) == null ? void 0 : _a[easing]) {
58919
- return defs.easings[easing];
59979
+ return result;
59980
+ }
59981
+ function applyTrimPathEffect(node, trimPath, isCombinedShape, ctx) {
59982
+ if (!trimPath) return node;
59983
+ const trimAllAsOne = !!trimPath.trimAllAsOne;
59984
+ const leafEntries = [];
59985
+ let acc = 0;
59986
+ const measure = (n) => {
59987
+ if (Array.isArray(n.children) && n.children.length > 0) {
59988
+ for (const ch of n.children) measure(ch);
59989
+ return;
59990
+ }
59991
+ const d = typeof n.d === "string" ? n.d : rectToPathD(n);
59992
+ if (d === void 0) return;
59993
+ const subpaths = parseSvgPathToBezier(d);
59994
+ if (!subpaths.length) return;
59995
+ const entry = { leaf: n, subpaths: [] };
59996
+ for (const sp of subpaths) {
59997
+ if (!trimAllAsOne) acc = 0;
59998
+ const lengthPx = pxBezierPathLength(sp);
59999
+ entry.subpaths.push({ subpath: sp, lengthPx, startOffsetPx: acc });
60000
+ acc += lengthPx;
60001
+ }
60002
+ leafEntries.push(entry);
60003
+ };
60004
+ measure(node);
60005
+ if (!leafEntries.length) return node;
60006
+ const chainLengthPx = acc;
60007
+ if (trimAllAsOne && chainLengthPx < 1e-3) return node;
60008
+ const offsetReadRaw = readAnimatable(trimPath.offset);
60009
+ const offsetRead = offsetReadRaw.kind === "absent" ? { kind: "static", value: 0 } : offsetReadRaw;
60010
+ const rangeReadRaw = readRangeWithCrossings(trimPath.range);
60011
+ const rangeRead = rangeReadRaw.kind === "absent" ? { kind: "static", value: [0, 1] } : rangeReadRaw;
60012
+ const offsetValues = readScalarValues(offsetRead);
60013
+ const minOffset = offsetValues.length ? Math.min(...offsetValues) : 0;
60014
+ const maxOffset = offsetValues.length ? Math.max(...offsetValues) : 0;
60015
+ const minMaxOffset = [minOffset, maxOffset];
60016
+ if (leafEntries.length === 1 && leafEntries[0].leaf === node && leafEntries[0].subpaths.length === 1) {
60017
+ const entry = leafEntries[0];
60018
+ const sp = entry.subpaths[0];
60019
+ const pathLengthPx = trimAllAsOne ? chainLengthPx : sp.lengthPx;
60020
+ if (pathLengthPx < 1e-3) return node;
60021
+ const startOffsetPct = trimAllAsOne ? sp.startOffsetPx / pathLengthPx : 0;
60022
+ return collapseLeafWithTrim(entry.leaf, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead);
58920
60023
  }
58921
- console.warn("Unknown easing name: " + easing);
58922
- return void 0;
60024
+ const replacements = /* @__PURE__ */ new Map();
60025
+ for (const entry of leafEntries) {
60026
+ const newChildren = [];
60027
+ for (const sp of entry.subpaths) {
60028
+ const pathLengthPx = trimAllAsOne ? chainLengthPx : sp.lengthPx;
60029
+ if (pathLengthPx < 1e-3) continue;
60030
+ const startOffsetPct = trimAllAsOne ? sp.startOffsetPx / pathLengthPx : 0;
60031
+ newChildren.push(...buildSubpathNodes(entry.leaf, sp.subpath, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead, ctx));
60032
+ }
60033
+ replacements.set(entry.leaf, wrapLeafAsGroup(entry.leaf, newChildren));
60034
+ }
60035
+ const swap = (n) => {
60036
+ const r = replacements.get(n);
60037
+ if (r) return r;
60038
+ if (Array.isArray(n.children) && n.children.length > 0) {
60039
+ return __spreadProps(__spreadValues({}, n), { children: n.children.map(swap) });
60040
+ }
60041
+ return n;
60042
+ };
60043
+ return swap(node);
58923
60044
  }
58924
- function resolveAnimation(animRef, defs) {
60045
+ function wrapLeafAsGroup(leaf, children) {
60046
+ const wrapper = __spreadProps(__spreadValues({}, leaf), { type: "g", children });
60047
+ delete wrapper.d;
60048
+ delete wrapper.strokeDasharray;
60049
+ delete wrapper.strokeDashoffset;
60050
+ delete wrapper.effects;
60051
+ return wrapper;
60052
+ }
60053
+ function buildSubpathNodes(leaf, subpath, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead, ctx) {
60054
+ const offsetToDashOffset = makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset);
60055
+ const rangeToDasharray = makeRangeToDasharray(pathLengthPx, minMaxOffset);
60056
+ const dashOffsetAttr = computeAnimAttr(offsetRead, offsetToDashOffset);
60057
+ const dashArrayAttr = computeAnimAttr(rangeRead, rangeToDasharray);
60058
+ const strokeOpacityAttr = computeOpacityFromRange(rangeRead);
60059
+ const dStr = bezierToSvgPath(subpath);
60060
+ const base = makeBareSubpath(dStr);
60061
+ applyAttr(base, "strokeDasharray", dashArrayAttr);
60062
+ applyAttr(base, "strokeDashoffset", dashOffsetAttr);
60063
+ applyAttr(base, "strokeOpacity", strokeOpacityAttr);
60064
+ return [base];
60065
+ }
60066
+ function collapseLeafWithTrim(leaf, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead) {
60067
+ const offsetToDashOffset = makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset);
60068
+ const rangeToDasharray = makeRangeToDasharray(pathLengthPx, minMaxOffset);
60069
+ const node = __spreadValues({}, leaf);
60070
+ delete node.effects;
60071
+ applyAttr(node, "strokeDasharray", computeAnimAttr(rangeRead, rangeToDasharray));
60072
+ applyAttr(node, "strokeDashoffset", computeAnimAttr(offsetRead, offsetToDashOffset));
60073
+ applyAttr(node, "strokeOpacity", computeOpacityFromRange(rangeRead));
60074
+ return node;
60075
+ }
60076
+ function makeBareSubpath(dStr) {
60077
+ return { type: "path", d: dStr };
60078
+ }
60079
+ var SMALL_PADDING_PX = 1;
60080
+ function makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset) {
60081
+ const [minIdx] = getOffsetIndexRange(minMaxOffset);
60082
+ return (offsetVal) => pathLengthPx * (-offsetVal - minIdx + startOffsetPct) + SMALL_PADDING_PX;
60083
+ }
60084
+ function makeRangeToDasharray(pathLengthPx, minMaxOffset) {
60085
+ const [minIdx, maxIdx] = getOffsetIndexRange(minMaxOffset);
60086
+ const repeats = maxIdx - minIdx + 1;
60087
+ return (rangeVal) => {
60088
+ const a = clamp(rangeVal[0], 0, 1);
60089
+ const b = clamp(rangeVal[1], 0, 1);
60090
+ const minR = Math.min(a, b);
60091
+ const maxR = Math.max(a, b);
60092
+ const out = [0];
60093
+ let gap = SMALL_PADDING_PX;
60094
+ for (let i = 0; i < repeats; i++) {
60095
+ out.push(gap + minR * pathLengthPx);
60096
+ out.push((maxR - minR) * pathLengthPx);
60097
+ gap = (1 - maxR) * pathLengthPx;
60098
+ }
60099
+ out.push(gap + SMALL_PADDING_PX);
60100
+ return out;
60101
+ };
60102
+ }
60103
+ function getOffsetIndexRange(minMaxOffset) {
60104
+ return [
60105
+ Math.floor(Math.min(-minMaxOffset[0], -minMaxOffset[1])),
60106
+ Math.ceil(Math.max(-minMaxOffset[0], -minMaxOffset[1]))
60107
+ ];
60108
+ }
60109
+ function readScalarValues(r) {
58925
60110
  var _a;
58926
- if (typeof animRef === "string") {
58927
- const resolved = (_a = defs == null ? void 0 : defs.animations) == null ? void 0 : _a[animRef];
58928
- if (!resolved) {
58929
- console.warn("Unknown animation name: " + animRef);
58930
- }
58931
- return resolved;
60111
+ if (r.kind === "absent") return [];
60112
+ if (r.kind === "static") return [r.value];
60113
+ const out = [];
60114
+ for (const kf of r.keyframes) {
60115
+ const v = (_a = kf.value) != null ? _a : kf.v;
60116
+ if (typeof v === "number") out.push(v);
58932
60117
  }
58933
- return animRef;
60118
+ return out;
58934
60119
  }
58935
- function resolveElementAnimation(animate, defs) {
58936
- if (!animate) return [];
58937
- const results = [];
58938
- if (typeof animate === "string") {
58939
- const resolved = resolveAnimation(animate, defs);
58940
- if (resolved) results.push(resolved);
58941
- } else if (Array.isArray(animate)) {
58942
- for (const item of animate) {
58943
- const resolved = resolveAnimation(item, defs);
58944
- if (resolved) results.push(resolved);
60120
+ function computeAnimAttr(read, map) {
60121
+ if (read.kind === "absent") return void 0;
60122
+ if (read.kind === "static") return { kind: "static", value: map(read.value) };
60123
+ return {
60124
+ kind: "animated",
60125
+ keyframes: read.keyframes.map((kf) => {
60126
+ var _a, _b, _c, _d;
60127
+ return {
60128
+ time: (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0,
60129
+ value: map((_c = kf.value) != null ? _c : kf.v),
60130
+ easing: (_d = kf.easing) != null ? _d : kf.e
60131
+ };
60132
+ })
60133
+ };
60134
+ }
60135
+ function applyAttr(node, attrName, attr) {
60136
+ if (!attr) return;
60137
+ if (attr.kind === "static") {
60138
+ node[attrName] = attr.value;
60139
+ return;
60140
+ }
60141
+ const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
60142
+ const animate = __spreadValues({}, prevAnimate || {});
60143
+ animate[attrName] = { keyframes: attr.keyframes };
60144
+ node.animate = animate;
60145
+ }
60146
+ function computeOpacityFromRange(rangeRead) {
60147
+ var _a, _b, _c, _d, _e, _f;
60148
+ const hide = (v) => v[0] === v[1];
60149
+ if (rangeRead.kind === "absent") return void 0;
60150
+ if (rangeRead.kind === "static") return hide(rangeRead.value) ? { kind: "static", value: 0 } : void 0;
60151
+ const kfs = rangeRead.keyframes;
60152
+ let anyHide = false;
60153
+ let allHide = true;
60154
+ for (const kf of kfs) {
60155
+ if (hide((_a = kf.value) != null ? _a : kf.v)) anyHide = true;
60156
+ else allHide = false;
60157
+ }
60158
+ if (!anyHide) return void 0;
60159
+ if (allHide) return { kind: "static", value: 0 };
60160
+ const out = [];
60161
+ for (let i = 0; i < kfs.length; i++) {
60162
+ const kf = kfs[i];
60163
+ const prevKf = i > 0 ? kfs[i - 1] : void 0;
60164
+ const nextKf = i < kfs.length - 1 ? kfs[i + 1] : void 0;
60165
+ const t = (_c = (_b = kf.time) != null ? _b : kf.t) != null ? _c : 0;
60166
+ const thisHide = hide((_d = kf.value) != null ? _d : kf.v);
60167
+ const prevHide = prevKf ? thisHide && hide((_e = prevKf.value) != null ? _e : prevKf.v) : thisHide;
60168
+ const nextHide = nextKf ? thisHide && hide((_f = nextKf.value) != null ? _f : nextKf.v) : thisHide;
60169
+ if (prevHide && !nextHide) {
60170
+ out.push({ time: t, value: 0 });
60171
+ out.push({ time: t + 1, value: 1 });
60172
+ } else if (!prevHide && nextHide) {
60173
+ out.push({ time: t - 1, value: 1 });
60174
+ out.push({ time: t, value: 0 });
58945
60175
  }
58946
- } else {
58947
- results.push(animate);
58948
60176
  }
58949
- return results;
60177
+ if (out.length <= 1) return void 0;
60178
+ return { kind: "animated", keyframes: out };
58950
60179
  }
58951
- function interpolateValue(propName, a, b, t) {
58952
- var _a, _b;
58953
- if (propName === "d") {
58954
- const aPaths = (_a = a == null ? void 0 : a.paths) != null ? _a : Array.isArray(a) ? a : [];
58955
- const bPaths = (_b = b == null ? void 0 : b.paths) != null ? _b : Array.isArray(b) ? b : [];
58956
- return { paths: interpolateBeziers(aPaths, bPaths, t) };
60180
+ function readRangeWithCrossings(raw) {
60181
+ const r = readAnimatable(raw);
60182
+ if (r.kind !== "animated") return r;
60183
+ const kfs = r.keyframes.map((kf) => {
60184
+ var _a, _b, _c, _d;
60185
+ return {
60186
+ time: (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0,
60187
+ value: (_c = kf.value) != null ? _c : kf.v,
60188
+ easing: (_d = kf.easing) != null ? _d : kf.e
60189
+ };
60190
+ });
60191
+ const hasReverse = kfs.some((kf) => kf.value[0] > kf.value[1]);
60192
+ if (!hasReverse) {
60193
+ return {
60194
+ kind: "animated",
60195
+ keyframes: kfs.map((kf) => ({ time: kf.time, value: kf.value, easing: kf.easing }))
60196
+ };
60197
+ }
60198
+ const crossingTimes = [];
60199
+ for (let i = 1; i < kfs.length; i++) {
60200
+ const prev = kfs[i - 1];
60201
+ const cur = kfs[i];
60202
+ const dPrev = prev.value[1] - prev.value[0];
60203
+ const dCur = cur.value[1] - cur.value[0];
60204
+ if (dPrev * dCur < 0) {
60205
+ const t = bisectionForRangeCrossing(prev, cur);
60206
+ if (t !== null && t > prev.time && t < cur.time) {
60207
+ crossingTimes.push(Math.round(t));
60208
+ }
60209
+ }
60210
+ }
60211
+ const uniqueTs = Array.from(new Set(crossingTimes)).sort((a, b) => a - b);
60212
+ const out = [];
60213
+ let j = 0;
60214
+ for (const kf of kfs) {
60215
+ while (j < uniqueTs.length && uniqueTs[j] < kf.time) {
60216
+ const t = uniqueTs[j++];
60217
+ const v2 = interpolateRangeAt(kfs, t);
60218
+ const m = (v2[0] + v2[1]) / 2;
60219
+ out.push({ time: t, value: [m, m] });
60220
+ }
60221
+ const v = kf.value[0] > kf.value[1] ? [kf.value[1], kf.value[0]] : kf.value;
60222
+ out.push({ time: kf.time, value: v, easing: kf.easing });
60223
+ }
60224
+ while (j < uniqueTs.length) {
60225
+ const t = uniqueTs[j++];
60226
+ const v = interpolateRangeAt(kfs, t);
60227
+ const m = (v[0] + v[1]) / 2;
60228
+ out.push({ time: t, value: [m, m] });
58957
60229
  }
58958
- if (COLOUR_ATTR_NAMES.has(propName)) {
58959
- return interpolateColor(a || [0, 0, 0, 1], b || [0, 0, 0, 1], t);
60230
+ return { kind: "animated", keyframes: out };
60231
+ }
60232
+ function bisectionForRangeCrossing(prev, cur) {
60233
+ const f = (t) => {
60234
+ const a = (t - prev.time) / (cur.time - prev.time);
60235
+ const v0 = prev.value[0] + (cur.value[0] - prev.value[0]) * a;
60236
+ const v1 = prev.value[1] + (cur.value[1] - prev.value[1]) * a;
60237
+ return v1 - v0;
60238
+ };
60239
+ let lo = prev.time, hi = cur.time;
60240
+ let fLo = f(lo);
60241
+ if (fLo === 0) return lo;
60242
+ const fHi = f(hi);
60243
+ if (fHi === 0) return hi;
60244
+ if (fLo * fHi > 0) return null;
60245
+ for (let i = 0; i < 100; i++) {
60246
+ const mid = (lo + hi) / 2;
60247
+ const fMid = f(mid);
60248
+ if (fMid === 0 || Math.abs(hi - lo) < 1e-4) return mid;
60249
+ if (fLo * fMid < 0) {
60250
+ hi = mid;
60251
+ } else {
60252
+ lo = mid;
60253
+ fLo = fMid;
60254
+ }
58960
60255
  }
58961
- if (TRANSFORM_FN_NAMES.has(propName) || propName === "stroke-dasharray" || propName === "strokeDasharray") {
58962
- return interpolateVec(a || [], b || [], t);
60256
+ return (lo + hi) / 2;
60257
+ }
60258
+ function interpolateRangeAt(kfs, t) {
60259
+ if (t <= kfs[0].time) return kfs[0].value;
60260
+ if (t >= kfs[kfs.length - 1].time) return kfs[kfs.length - 1].value;
60261
+ for (let i = 1; i < kfs.length; i++) {
60262
+ if (t <= kfs[i].time) {
60263
+ const prev = kfs[i - 1];
60264
+ const cur = kfs[i];
60265
+ const a = (t - prev.time) / (cur.time - prev.time);
60266
+ return [
60267
+ prev.value[0] + (cur.value[0] - prev.value[0]) * a,
60268
+ prev.value[1] + (cur.value[1] - prev.value[1]) * a
60269
+ ];
60270
+ }
58963
60271
  }
58964
- return interpolateNum(+(a || 0), +(b || 0), t);
60272
+ return kfs[kfs.length - 1].value;
58965
60273
  }
58966
- function expandLoopKeyframes(propName, keyframes, loop, duration) {
58967
- var _a, _b, _c, _d, _e;
58968
- const totalIntervals = keyframes.length - 1;
58969
- const segCount = clamp((_a = loop.segmentCount) != null ? _a : totalIntervals, 1, totalIntervals);
58970
- let segKfs;
58971
- if (loop.before) {
58972
- segKfs = keyframes.slice(0, segCount + 1);
58973
- } else {
58974
- segKfs = keyframes.slice(totalIntervals - segCount);
60274
+ function pxBezierPathLength(path) {
60275
+ const v = path.v;
60276
+ if (!v || v.length < 2) return 0;
60277
+ let total = 0;
60278
+ for (let i = 0; i < v.length - 1; i++) {
60279
+ total += segmentLength(path, i, i + 1);
58975
60280
  }
58976
- const firstT = (_b = keyframes[0].t) != null ? _b : 0;
58977
- const lastT = (_c = keyframes[keyframes.length - 1].t) != null ? _c : 0;
58978
- let fillStart, fillEnd;
58979
- if (loop.before) {
58980
- fillStart = 0;
58981
- fillEnd = firstT;
60281
+ if (path.c && v.length > 1) {
60282
+ total += segmentLength(path, v.length - 1, 0);
60283
+ }
60284
+ return total;
60285
+ }
60286
+ function segmentLength(path, from, to) {
60287
+ var _a, _b, _c, _d;
60288
+ const v = path.v;
60289
+ const p0 = v[from];
60290
+ const p3 = v[to];
60291
+ const p1 = (_b = (_a = path.o) == null ? void 0 : _a[from]) != null ? _b : p0;
60292
+ const p2 = (_d = (_c = path.i) == null ? void 0 : _c[to]) != null ? _d : p3;
60293
+ const lut = bezier2D_arcLengthLUT(p0, p1, p2, p3);
60294
+ return lut.ds[lut.ds.length - 1];
60295
+ }
60296
+ function rectToPathD(node) {
60297
+ var _a, _b, _c, _d;
60298
+ if (node.type !== "rect") return void 0;
60299
+ const x = Number((_a = node.x) != null ? _a : 0), y = Number((_b = node.y) != null ? _b : 0);
60300
+ const w = Number((_c = node.width) != null ? _c : 0), h3 = Number((_d = node.height) != null ? _d : 0);
60301
+ return "M" + (x + w) + "," + y + "L" + (x + w) + "," + (y + h3) + "L" + x + "," + (y + h3) + "L" + x + "," + y + "L" + (x + w) + "," + y + "z";
60302
+ }
60303
+ function applyPlayerEffects(root) {
60304
+ const ctx = {
60305
+ defs: [],
60306
+ warnings: [],
60307
+ errors: [],
60308
+ idMap: /* @__PURE__ */ new Map(),
60309
+ nextId: 0,
60310
+ contentRefInnerIds: /* @__PURE__ */ new Map(),
60311
+ maskAncestorChains: /* @__PURE__ */ new Map()
60312
+ };
60313
+ const working = clone(root);
60314
+ indexById(working, ctx.idMap);
60315
+ identifyContentRefTargets(working, ctx, () => genId(ctx, "inner"));
60316
+ collectMaskAncestorChains(working, ctx);
60317
+ const afterPass1 = applyPlayerEffects_exceptRetime(working, ctx);
60318
+ const out = applyPlayerEffects_retime(afterPass1, ctx);
60319
+ spliceDefs(out, ctx.defs);
60320
+ return { root: out, defs: ctx.defs, warnings: ctx.warnings, errors: ctx.errors };
60321
+ }
60322
+ function applyPlayerEffects_exceptRetime(node, ctx) {
60323
+ if (node.children) node.children = node.children.map((child) => applyPlayerEffects_exceptRetime(child, ctx));
60324
+ const fx = node.effects;
60325
+ const originalId = typeof node.id === "string" ? node.id : void 0;
60326
+ const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
60327
+ if (!fx && !innerIdForContentRef) return node;
60328
+ const { transformation, repeater, maskedBy, trimPath, retime, ref: ref3, fillGradient, strokeGradient, textAlongPath } = fx != null ? fx : {};
60329
+ const isCombinedShape = fx == null ? void 0 : fx.isCombinedShape;
60330
+ if (fx) delete node.effects;
60331
+ let n = node;
60332
+ n = applyTextAlongPathEffect(n, textAlongPath, ctx);
60333
+ n = applyFillGradientEffect(n, fillGradient, ctx);
60334
+ n = applyStrokeGradientEffect(n, strokeGradient, ctx);
60335
+ n = applyTrimPathEffect(n, trimPath, isCombinedShape, ctx);
60336
+ n = applyRepeaterEffect(n, repeater, ctx);
60337
+ n = applyMaskedByEffect(n, maskedBy, transformation, ctx);
60338
+ if (innerIdForContentRef) {
60339
+ n = splitForContentRef(n, transformation, originalId, innerIdForContentRef, ctx);
58982
60340
  } else {
58983
- fillStart = lastT;
58984
- fillEnd = duration;
60341
+ n = applyRefAndTransformationEffect(n, ref3, transformation, ctx);
58985
60342
  }
58986
- const fillDuration = fillEnd - fillStart;
58987
- if (fillDuration <= 0) return keyframes;
58988
- const segStartT = (_d = segKfs[0].t) != null ? _d : 0;
58989
- const segEndT = (_e = segKfs[segKfs.length - 1].t) != null ? _e : 0;
58990
- const segDuration = segEndT - segStartT;
58991
- if (segDuration <= 0) return keyframes;
58992
- const template = segKfs.map((kf) => ({
58993
- relT: (kf.t - segStartT) / segDuration,
58994
- v: kf.v,
58995
- e: kf.e
58996
- }));
58997
- const fullReps = Math.floor(fillDuration / segDuration);
58998
- const remainder = fillDuration - fullReps * segDuration;
58999
- const partialFraction = remainder / segDuration;
59000
- const looped = [];
59001
- function appendRep(repStart, isReversed, partial) {
59002
- let entries;
59003
- if (isReversed) {
59004
- entries = [];
59005
- for (let i = template.length - 1; i >= 0; i--) {
59006
- entries.push({
59007
- relT: 1 - template[i].relT,
59008
- v: template[i].v,
59009
- // Easing for reversed transition: use reversed easing from the forward "from" keyframe
59010
- e: i > 0 ? reverseEasing(template[i - 1].e) : void 0
59011
- });
60343
+ if (retime) node.effects = { retime };
60344
+ if (originalId) ctx.idMap.set(originalId, n);
60345
+ return n;
60346
+ }
60347
+ function applyPlayerEffects_retime(node, ctx) {
60348
+ applyAllRetimeEffects(node, ctx);
60349
+ return node;
60350
+ }
60351
+ function materialiseAnimatedUseInstances(root) {
60352
+ var _a;
60353
+ const idMap = buildIdMap(root);
60354
+ const animatedIds = computeAnimatedSubtreeIds(root, idMap);
60355
+ if (animatedIds.size === 0) return root;
60356
+ let idCounter = 0;
60357
+ const genId3 = () => "_lw_use_mat_" + ++idCounter;
60358
+ const defsCollector = [];
60359
+ const walked = walkAndMaterialise2(root, idMap, animatedIds, genId3, defsCollector);
60360
+ if (defsCollector.length === 0) return walked;
60361
+ const defsNode = { type: "defs", children: defsCollector };
60362
+ const newChildren = [...(_a = walked.children) != null ? _a : [], defsNode];
60363
+ return __spreadProps(__spreadValues({}, walked), { children: newChildren });
60364
+ }
60365
+ function buildIdMap(root) {
60366
+ const map = /* @__PURE__ */ new Map();
60367
+ const visit = (n) => {
60368
+ var _a;
60369
+ if (typeof n.id === "string") map.set(n.id, n);
60370
+ (_a = n.children) == null ? void 0 : _a.forEach(visit);
60371
+ };
60372
+ visit(root);
60373
+ return map;
60374
+ }
60375
+ function computeAnimatedSubtreeIds(root, idMap) {
60376
+ const cache = /* @__PURE__ */ new WeakMap();
60377
+ const result = /* @__PURE__ */ new Set();
60378
+ const hasAnim = (n, visiting) => {
60379
+ const cached = cache.get(n);
60380
+ if (cached !== void 0) return cached;
60381
+ if (visiting.has(n)) return false;
60382
+ visiting.add(n);
60383
+ let r = false;
60384
+ if (n.animate && typeof n.animate === "object" && !Array.isArray(n.animate)) {
60385
+ for (const _ in n.animate) {
60386
+ r = true;
60387
+ break;
59012
60388
  }
59013
- } else {
59014
- entries = template;
59015
60389
  }
59016
- const cutRelT = partial !== void 0 ? partial : 1;
59017
- for (let i = 0; i < entries.length; i++) {
59018
- const entry = entries[i];
59019
- if (entry.relT > cutRelT + 1e-9) {
59020
- const prev = entries[i - 1];
59021
- const intervalSpan = entry.relT - prev.relT;
59022
- const localFrac = (cutRelT - prev.relT) / intervalSpan;
59023
- const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
59024
- const cutValue = interpolateValue(propName, prev.v, entry.v, easedFrac);
59025
- const { left: leftEasing } = splitEasing(prev.e, localFrac);
59026
- if (looped.length > 0 && prev.relT <= cutRelT) {
59027
- looped[looped.length - 1].e = leftEasing;
60390
+ if (!r && n.children) {
60391
+ for (const ch of n.children) {
60392
+ if (hasAnim(ch, visiting)) {
60393
+ r = true;
60394
+ break;
59028
60395
  }
59029
- looped.push({ t: repStart + cutRelT * segDuration, v: cutValue, e: void 0 });
59030
- return;
59031
60396
  }
59032
- looped.push({
59033
- t: repStart + entry.relT * segDuration,
59034
- v: entry.v,
59035
- e: i < entries.length - 1 ? entry.e : void 0
59036
- });
59037
60397
  }
60398
+ if (!r && n.type === "use" && typeof n.href === "string") {
60399
+ const targetId = stripHash2(n.href);
60400
+ const target = targetId ? idMap.get(targetId) : void 0;
60401
+ if (target) r = hasAnim(target, visiting);
60402
+ }
60403
+ visiting.delete(n);
60404
+ cache.set(n, r);
60405
+ return r;
60406
+ };
60407
+ for (const [id, node] of idMap) {
60408
+ if (hasAnim(node, /* @__PURE__ */ new Set())) result.add(id);
59038
60409
  }
59039
- for (let rep = 0; rep < fullReps; rep++) {
59040
- const distFromBoundary = loop.before ? fullReps - 1 - rep : rep;
59041
- const isReversed = !!loop.alternate && distFromBoundary % 2 === 0;
59042
- const repStart = fillStart + rep * segDuration;
59043
- appendRep(repStart, isReversed);
59044
- }
59045
- if (partialFraction > 1e-9) {
59046
- const isReversed = !!loop.alternate && fullReps % 2 === 0;
59047
- const repStart = fillStart + fullReps * segDuration;
59048
- appendRep(repStart, isReversed, partialFraction);
59049
- }
59050
- if (loop.before) {
59051
- return [...looped, ...keyframes];
59052
- } else {
59053
- return [...keyframes, ...looped];
60410
+ return result;
60411
+ }
60412
+ function stripHash2(href) {
60413
+ if (typeof href !== "string") return void 0;
60414
+ return href.startsWith("#") ? href.slice(1) : href;
60415
+ }
60416
+ function materialiseOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector) {
60417
+ const clone2 = deepClonePxNode(target);
60418
+ regenerateIdsAndRewriteRefs(clone2, genId3);
60419
+ const rewrittenClone = clone2.type === "symbol" ? rewriteSymbolRootToGroup(clone2, genId3, defsCollector) : clone2;
60420
+ const materialisedClone = walkAndMaterialise2(rewrittenClone, idMap, animatedIds, genId3, defsCollector);
60421
+ const newNode = __spreadProps(__spreadValues({}, useNode), { type: "g", children: [materialisedClone] });
60422
+ delete newNode.href;
60423
+ return applyUseOffsetToG(newNode);
60424
+ }
60425
+ function rewriteSymbolRootToGroup(symbolNode, genId3, defsCollector) {
60426
+ const viewBox = parseViewBox(symbolNode.viewBox);
60427
+ const g = __spreadProps(__spreadValues({}, symbolNode), { type: "g" });
60428
+ delete g.viewBox;
60429
+ delete g.preserveAspectRatio;
60430
+ delete g.width;
60431
+ delete g.height;
60432
+ if (!viewBox) return g;
60433
+ const [vbX, vbY, vbW, vbH] = viewBox;
60434
+ if (vbX !== 0 || vbY !== 0) {
60435
+ g.transform = "translate(" + -vbX + "," + -vbY + ")";
59054
60436
  }
60437
+ const clipId = genId3();
60438
+ defsCollector.push({
60439
+ type: "clipPath",
60440
+ id: clipId,
60441
+ children: [{ type: "rect", x: vbX, y: vbY, width: vbW, height: vbH }]
60442
+ });
60443
+ g.clipPath = "url(#" + clipId + ")";
60444
+ return g;
59055
60445
  }
59056
- function normalizeKeyframes(propName, propAnim, duration, defs) {
59057
- var _a, _b, _c, _d, _e;
59058
- const keyframes = propAnim.keyframes || propAnim.kfs || [];
59059
- const normalized = [];
59060
- for (const kf of keyframes) {
59061
- const timePct = (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
59062
- let value = (_c = kf.value) != null ? _c : kf.v;
59063
- const easing = (_d = kf.easing) != null ? _d : kf.e;
59064
- if (propName === "d") {
59065
- value = normalizePathValue(value);
59066
- }
59067
- if (COLOUR_ATTR_NAMES.has(propName)) {
59068
- value = (_e = parseColor(value)) != null ? _e : value;
60446
+ function parseViewBox(v) {
60447
+ if (typeof v !== "string") return void 0;
60448
+ const parts = v.trim().split(/[\s,]+/).map(Number);
60449
+ if (parts.length < 4 || parts.some((n) => !Number.isFinite(n))) return void 0;
60450
+ return [parts[0], parts[1], parts[2], parts[3]];
60451
+ }
60452
+ function walkAndMaterialise2(node, idMap, animatedIds, genId3, defsCollector) {
60453
+ if (node.type === "use" && typeof node.href === "string") {
60454
+ const targetId = stripHash2(node.href);
60455
+ if (targetId && animatedIds.has(targetId)) {
60456
+ const target = idMap.get(targetId);
60457
+ if (target) return materialiseOneUse(node, target, idMap, animatedIds, genId3, defsCollector);
59069
60458
  }
59070
- normalized.push({
59071
- t: timePct,
59072
- v: value,
59073
- e: resolveEasing(easing, defs)
59074
- });
59075
60459
  }
59076
- normalized.sort((a, b) => {
59077
- var _a2, _b2;
59078
- return ((_a2 = a.t) != null ? _a2 : 0) - ((_b2 = b.t) != null ? _b2 : 0);
60460
+ if (!node.children) return node;
60461
+ let changed = false;
60462
+ const newChildren = node.children.map((ch) => {
60463
+ const m = walkAndMaterialise2(ch, idMap, animatedIds, genId3, defsCollector);
60464
+ if (m !== ch) changed = true;
60465
+ return m;
59079
60466
  });
59080
- const loopRaw = propAnim.loop;
59081
- const loop = loopRaw === true ? {} : loopRaw || void 0;
59082
- if (loop && normalized.length >= 2) {
59083
- return expandLoopKeyframes(propName, normalized, loop, duration);
59084
- }
59085
- return normalized;
60467
+ return changed ? __spreadProps(__spreadValues({}, node), { children: newChildren }) : node;
59086
60468
  }
59087
- function mergeAnimationDefinitions(animations) {
59088
- const merged = {};
59089
- for (const anim of animations) {
59090
- for (const [prop, propAnim] of Object.entries(anim)) {
59091
- merged[prop] = propAnim;
59092
- }
60469
+ function materialiseAllInTree(doc, engine, opts) {
60470
+ var _a, _b;
60471
+ let root = applyPlayerEffects(doc).root;
60472
+ const duration = (_b = (_a = getAnimatorConfig(root)) == null ? void 0 : _a.duration) != null ? _b : DEFAULT_DURATION_MS;
60473
+ root = materialiseInternalLoopsInTree(root, duration);
60474
+ if (engine === PxAnimatorEngine.webapi) {
60475
+ root = materialiseMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
60476
+ root = materialiseAnimatedUseInstances(root);
59093
60477
  }
59094
- return merged;
60478
+ return root;
59095
60479
  }
59096
- var _elementIdCounter = 0;
59097
- function generateElementId() {
59098
- return "_px_el_" + ++_elementIdCounter;
60480
+ var SVG_NS = "http://www.w3.org/2000/svg";
60481
+ var DISALLOWED_SVG_TAGS_LOWER = /* @__PURE__ */ new Set([
60482
+ "script",
60483
+ "foreignobject"
60484
+ ]);
60485
+ var URL_VALUE_ATTRS_LOWER = /* @__PURE__ */ new Set([
60486
+ "href",
60487
+ // <use>, <image>
60488
+ "xlink:href",
60489
+ // legacy <use>
60490
+ "src",
60491
+ // <image>
60492
+ "filter",
60493
+ // url(#filterId)
60494
+ "clippath",
60495
+ // clip-path="url(#…)"
60496
+ "mask",
60497
+ // url(#maskId)
60498
+ "markerstart",
60499
+ // marker-start="url(#…)"
60500
+ "markermid",
60501
+ // marker-mid="url(#…)"
60502
+ "markerend"
60503
+ // marker-end="url(#…)"
60504
+ ]);
60505
+ var IMAGE_REF_ATTRS_LOWER = /* @__PURE__ */ new Set(["href", "xlink:href", "src"]);
60506
+ var DATA_RASTER_IMAGE_RE = /^data:image\/(?:png|jpe?g|gif|webp|bmp);base64,/i;
60507
+ function isDangerousAttrName(nameLower) {
60508
+ if (nameLower.startsWith("on")) return true;
60509
+ return false;
59099
60510
  }
59100
- function normalizeAnimationDefinition(animDef, duration, defs) {
59101
- const normalized = {};
59102
- for (const [propName, propAnim] of Object.entries(animDef)) {
59103
- const normalizedKfs = normalizeKeyframes(propName, propAnim, duration, defs);
59104
- if (normalizedKfs.length > 0) {
59105
- normalized[propName] = { kfs: normalizedKfs };
59106
- }
60511
+ function sanitiseAttributeValue(name, value) {
60512
+ const nameLower = name.toLowerCase();
60513
+ if (isDangerousAttrName(nameLower)) {
60514
+ console.warn("Attribute blocked (event handler / dangerous): ", nameLower);
60515
+ return void 0;
59107
60516
  }
59108
- return normalized;
59109
- }
59110
- function getNormalisedBindings(doc) {
59111
- const animatorConfig = getAnimatorConfig(doc) || {};
59112
- const defs = getDefs(doc);
59113
- const duration = animatorConfig.duration || 1e3;
59114
- const bindings = [];
59115
- const processAnimation = (id, animate) => {
59116
- if (!animate) return null;
59117
- const animDefs = resolveElementAnimation(animate, defs);
59118
- if (animDefs.length === 0) return null;
59119
- const merged = mergeAnimationDefinitions(animDefs);
59120
- const normalizedAnim = normalizeAnimationDefinition(merged, duration, defs);
59121
- if (Object.keys(normalizedAnim).length === 0) return null;
59122
- return {
59123
- id,
59124
- animate: normalizedAnim
59125
- };
59126
- };
59127
- const docBindings = getBindings(doc);
59128
- if (docBindings) {
59129
- for (const binding of docBindings) {
59130
- const normalized = processAnimation(binding.id, binding.animate);
59131
- if (normalized) bindings.push(normalized);
60517
+ if (nameLower === "fill" || nameLower === "stroke" || nameLower === "stopcolor") {
60518
+ const str = String(value);
60519
+ if (str.includes("url(") && !/^url\(#[^)]+\)$/.test(str)) {
60520
+ console.warn('Attribute "' + nameLower + '" blocked: url() must be internal url(#id), got:', value);
60521
+ return void 0;
59132
60522
  }
60523
+ return value;
59133
60524
  }
59134
- const processNode = (node) => {
59135
- const inlineAnim = node.animate;
59136
- if (inlineAnim && Object.keys(inlineAnim).length > 0) {
59137
- const nodeId = node.id || generateElementId();
59138
- node.id = nodeId;
59139
- const normalized = processAnimation(nodeId, inlineAnim);
59140
- if (normalized) bindings.push(normalized);
59141
- }
59142
- if (node.children) {
59143
- for (let i = 0; i < node.children.length; i++) {
59144
- processNode(node.children[i]);
59145
- }
59146
- }
59147
- };
59148
- if (doc.children) {
59149
- for (let i = 0; i < doc.children.length; i++) {
59150
- processNode(doc.children[i]);
60525
+ if (URL_VALUE_ATTRS_LOWER.has(nameLower)) {
60526
+ const str = String(value);
60527
+ if (str.startsWith("#")) return value;
60528
+ if (/^url\(#[^)]+\)$/.test(str)) return value;
60529
+ if (IMAGE_REF_ATTRS_LOWER.has(nameLower) && DATA_RASTER_IMAGE_RE.test(str)) return value;
60530
+ console.warn('Attribute "' + nameLower + '" blocked: must be #id, url(#id), or base64 raster data: URI, got:', value);
60531
+ return void 0;
60532
+ }
60533
+ return value;
60534
+ }
60535
+ function createElement(tagName, normalisedProps, style, children, textContent) {
60536
+ if (DISALLOWED_SVG_TAGS_LOWER.has(tagName.toLowerCase())) {
60537
+ console.warn("SVG tag blocked (dangerous): ", tagName);
60538
+ return null;
60539
+ }
60540
+ const element = document.createElementNS(SVG_NS, tagName);
60541
+ for (const propName in normalisedProps) {
60542
+ const sanitised = sanitiseAttributeValue(propName, normalisedProps[propName]);
60543
+ if (sanitised === void 0) continue;
60544
+ element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitised);
60545
+ }
60546
+ if (style) {
60547
+ for (const styleProp in style) {
60548
+ element.style[styleProp] = String(style[styleProp]);
59151
60549
  }
59152
60550
  }
59153
- return bindings;
59154
- }
59155
- function getKeyframesPair(keyframes, progress) {
59156
- var _a, _b;
59157
- let prevKf = keyframes[0];
59158
- let nextKf = keyframes[keyframes.length - 1];
59159
- for (let j = 0; j < keyframes.length - 1; j++) {
59160
- const aOff = (_a = keyframes[j].t) != null ? _a : 0;
59161
- const bOff = (_b = keyframes[j + 1].t) != null ? _b : 0;
59162
- if (aOff <= progress && progress <= bOff) {
59163
- prevKf = keyframes[j];
59164
- nextKf = keyframes[j + 1];
59165
- break;
60551
+ if (children) {
60552
+ for (const child of children) {
60553
+ element.appendChild(child);
59166
60554
  }
59167
60555
  }
59168
- return { prevKf, nextKf };
60556
+ if (textContent) element.textContent = textContent;
60557
+ return element;
59169
60558
  }
59170
- function calcPropertyValue(propName, propAnim, progress) {
59171
- var _a, _b, _c, _d, _e, _f, _g;
59172
- const keyframes = propAnim.kfs || propAnim.keyframes || [];
59173
- if (keyframes.length === 0) return null;
59174
- const { prevKf, nextKf } = getKeyframesPair(keyframes, progress);
59175
- let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a = prevKf.t) != null ? _a : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
59176
- localProgress = clamp(localProgress, 0, 1);
59177
- const easing = (_c = prevKf.e) != null ? _c : prevKf.easing;
59178
- if (easing && Array.isArray(easing)) {
59179
- try {
59180
- localProgress = cubicBezier(easing)(localProgress);
59181
- } catch (e) {
59182
- }
60559
+ function resolveStyle(style, defs) {
60560
+ var _a;
60561
+ if (!style) return void 0;
60562
+ if (typeof style === "string") {
60563
+ return (_a = defs == null ? void 0 : defs.styles) == null ? void 0 : _a[style];
59183
60564
  }
59184
- let cssAttrName = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
59185
- let cssValue = null;
59186
- const prevV = (_d = prevKf == null ? void 0 : prevKf.v) != null ? _d : prevKf == null ? void 0 : prevKf.value;
59187
- const nextV = (_e = nextKf == null ? void 0 : nextKf.v) != null ? _e : nextKf == null ? void 0 : nextKf.value;
59188
- if (cssAttrName === "d") {
59189
- const prevPaths = (_f = prevV == null ? void 0 : prevV.paths) != null ? _f : Array.isArray(prevV) ? prevV : [];
59190
- const nextPaths = (_g = nextV == null ? void 0 : nextV.paths) != null ? _g : Array.isArray(nextV) ? nextV : [];
59191
- cssValue = interpolateBeziers(
59192
- prevPaths,
59193
- nextPaths,
59194
- localProgress
59195
- ).map((bz) => bezierToSvgPath(bz)).join("");
59196
- } else if (COLOUR_ATTR_NAMES.has(cssAttrName)) {
59197
- cssValue = toRGBA(interpolateColor(
59198
- prevV || [0, 0, 0, 1],
59199
- nextV || [0, 0, 0, 1],
59200
- localProgress
59201
- ));
59202
- cssAttrName = propName;
59203
- } else if (cssAttrName === "stroke-dasharray") {
59204
- cssValue = interpolateVec(
59205
- prevV || [],
59206
- nextV || [],
59207
- localProgress
59208
- ).join(" ");
59209
- cssAttrName = propName;
59210
- } else if (cssAttrName === "transform" && prevV !== null && typeof prevV === "object" && !Array.isArray(prevV)) {
59211
- const partKeys = /* @__PURE__ */ new Set([
59212
- ...prevV ? Object.keys(prevV) : [],
59213
- ...nextV ? Object.keys(nextV) : []
59214
- ]);
59215
- const partsResult = {};
59216
- for (const partKey of partKeys) {
59217
- const prevPart = prevV == null ? void 0 : prevV[partKey];
59218
- const nextPart = nextV == null ? void 0 : nextV[partKey];
59219
- if (partKey === "rotate") {
59220
- partsResult.rotate = interpolateNum(+(prevPart != null ? prevPart : 0), +(nextPart != null ? nextPart : 0), localProgress);
59221
- } else if (partKey === "translate" || partKey === "scale" || partKey === "origin") {
59222
- const fallback = partKey === "scale" ? [1, 1] : [0, 0];
59223
- const interp = interpolateVec(prevPart || fallback, nextPart || fallback, localProgress);
59224
- partsResult[partKey] = interp;
60565
+ return style;
60566
+ }
60567
+ function getNormalizedProps(props) {
60568
+ const propsCopy = {};
60569
+ for (const rawKey of Object.keys(props)) {
60570
+ const key = kebabToCamelCaseWord(rawKey);
60571
+ if (INTERNAL_ATTRS.has(key)) continue;
60572
+ if (key === "style") continue;
60573
+ let value = props[rawKey];
60574
+ if (COLOUR_ATTR_NAMES.has(key) && Array.isArray(value)) {
60575
+ propsCopy[key] = toRGBA(value);
60576
+ } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && value.value && typeof value.value === "object") {
60577
+ propsCopy["transform"] = composeTransformParts(value.value, { withUnits: false });
60578
+ } else if (TRANSFORM_FN_NAMES.has(key)) {
60579
+ if (Array.isArray(value)) {
60580
+ if (key === "translate") value = value.map((v) => v + "px");
60581
+ value = value.join(",");
59225
60582
  }
60583
+ if (key === "rotate") value = value + "deg";
60584
+ propsCopy["transform"] = key + "(" + value + ")";
60585
+ } else if (value !== void 0 && value !== null) {
60586
+ propsCopy[key] = String(value);
59226
60587
  }
59227
- if (propAnimIsMotionPath(propAnim)) {
59228
- const prevTr = prevV.translate;
59229
- const nextTr = nextV.translate;
59230
- if (Array.isArray(prevTr) && Array.isArray(nextTr)) {
59231
- const sample = evaluateMotionPathSegment(
59232
- prevKf,
59233
- nextKf,
59234
- [+prevTr[0], +prevTr[1]],
59235
- [+nextTr[0], +nextTr[1]],
59236
- localProgress,
59237
- !!propAnim.autoOrient
59238
- );
59239
- partsResult.translate = [sample.translate[0], sample.translate[1]];
59240
- if (sample.rotateDeg !== void 0) partsResult.rotate = sample.rotateDeg;
60588
+ }
60589
+ return propsCopy;
60590
+ }
60591
+ function renderNode(node, defs) {
60592
+ if (!node) return null;
60593
+ const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
60594
+ const nodeDefs = getDefs(node) || defs;
60595
+ const resolvedStyle = resolveStyle(style, nodeDefs);
60596
+ let childElements;
60597
+ if (children) {
60598
+ for (const ch of children) {
60599
+ const child = renderNode(ch, nodeDefs);
60600
+ if (child) {
60601
+ if (!childElements) childElements = [];
60602
+ childElements.push(child);
59241
60603
  }
59242
60604
  }
59243
- cssValue = composeTransformParts(partsResult, { withUnits: false });
59244
- cssAttrName = "transform";
59245
- } else if (cssAttrName === "translate") {
59246
- const v = interpolateVec(
59247
- prevV || [0, 0],
59248
- nextV || [0, 0],
59249
- localProgress
59250
- );
59251
- cssValue = "translate(" + v.join(",") + ")";
59252
- cssAttrName = "transform";
59253
- } else if (cssAttrName === "rotate") {
59254
- const v = interpolateNum(
59255
- +(prevV || 0),
59256
- +(nextV || 0),
59257
- localProgress
59258
- );
59259
- cssValue = "rotate(" + v + ")";
59260
- cssAttrName = "transform";
59261
- } else if (cssAttrName === "scale") {
59262
- const v = interpolateVec(
59263
- prevV || [1, 1],
59264
- nextV || [1, 1],
59265
- localProgress
59266
- );
59267
- cssValue = "scale(" + v.join(",") + ")";
59268
- cssAttrName = "transform";
59269
- } else {
59270
- const num2 = interpolateNum(
59271
- +(prevV || 0),
59272
- +(nextV || 0),
59273
- localProgress
59274
- );
59275
- cssValue = num2;
59276
- }
59277
- if (PCT_BASED_ATTR_NAMES.has(cssAttrName) && typeof cssValue === "number") {
59278
- cssValue = cssValue * 100 + "%";
59279
60605
  }
59280
- return { k: cssAttrName, v: cssValue === null ? "" : "" + cssValue };
60606
+ return createElement(
60607
+ type || "g",
60608
+ getNormalizedProps(props),
60609
+ resolvedStyle,
60610
+ childElements,
60611
+ props[TEXT_ATTR] || props[TEXT_CONTENT_ATTR]
60612
+ );
59281
60613
  }
59282
- function calcAnimationValues(animDef, progress) {
59283
- const result = {};
59284
- for (const [propName, propAnim] of Object.entries(animDef)) {
59285
- const computed3 = calcPropertyValue(propName, propAnim, progress);
59286
- if (computed3) {
59287
- result[computed3.k] = computed3.v;
60614
+ function setupAnimationTriggers(api, config) {
60615
+ const { startOn, outAction = "continue", scrollIntoViewThreshold = 0.5 } = config;
60616
+ const root = api.getRootElement();
60617
+ if (!root) {
60618
+ console.warn("setupAnimationTriggers: No root element found for animation.");
60619
+ return api;
60620
+ }
60621
+ const start = () => {
60622
+ api.play();
60623
+ };
60624
+ const handleEndAction = () => {
60625
+ switch (outAction) {
60626
+ case "pause":
60627
+ api.pause();
60628
+ break;
60629
+ case "reset":
60630
+ api.cancel();
60631
+ break;
60632
+ case "reverse":
60633
+ api.play();
60634
+ break;
60635
+ case "continue":
60636
+ default:
60637
+ break;
60638
+ }
60639
+ };
60640
+ switch (startOn) {
60641
+ case "load": {
60642
+ const startHandler = () => start();
60643
+ if (document.readyState === "complete") {
60644
+ startHandler();
60645
+ } else {
60646
+ window.addEventListener("load", startHandler, { once: true });
60647
+ }
60648
+ break;
60649
+ }
60650
+ case "mouseOver": {
60651
+ const mouseOverHandler = () => start();
60652
+ const mouseOutHandler = () => handleEndAction();
60653
+ root.addEventListener("mouseenter", mouseOverHandler);
60654
+ root.addEventListener("mouseleave", mouseOutHandler);
60655
+ break;
59288
60656
  }
60657
+ case "click": {
60658
+ const clickHandler = () => {
60659
+ if (api.isPlaying()) {
60660
+ handleEndAction();
60661
+ } else {
60662
+ start();
60663
+ }
60664
+ };
60665
+ root.addEventListener("click", clickHandler);
60666
+ break;
60667
+ }
60668
+ case "scrollIntoView": {
60669
+ const observer = new IntersectionObserver(
60670
+ (entries) => {
60671
+ entries.forEach((entry) => {
60672
+ if (entry.isIntersecting && entry.intersectionRatio >= scrollIntoViewThreshold) {
60673
+ start();
60674
+ } else {
60675
+ handleEndAction();
60676
+ }
60677
+ });
60678
+ },
60679
+ { threshold: scrollIntoViewThreshold }
60680
+ );
60681
+ observer.observe(root);
60682
+ break;
60683
+ }
60684
+ case "programmatic":
60685
+ break;
59289
60686
  }
59290
- return result;
60687
+ return api;
59291
60688
  }
59292
60689
  function getSelector(id) {
59293
60690
  return "#" + id;
59294
60691
  }
59295
60692
  function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
59296
60693
  const config = getAnimatorConfig(doc) || {};
59297
- const bindings = getNormalisedBindings(doc);
60694
+ const bindings = getNormalisedBindings(doc, PxAnimatorEngine.frames);
59298
60695
  const _iterations = config.iterations;
59299
60696
  let iterations = 1;
59300
60697
  if (typeof _iterations === "number") iterations = _iterations || 1;
@@ -59412,6 +60809,10 @@ ${codeFrame}` : message);
59412
60809
  };
59413
60810
  const startAnim = () => {
59414
60811
  if (playing) return;
60812
+ if (Number.isFinite(totalDuration) && timeBeforeLastStartMs >= totalDuration) {
60813
+ timeBeforeLastStartMs = 0;
60814
+ finishCalled = false;
60815
+ }
59415
60816
  playing = true;
59416
60817
  lastStartedTs = Date.now();
59417
60818
  loopAnim(true);
@@ -59642,7 +61043,6 @@ ${codeFrame}` : message);
59642
61043
  function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsupportedAttrs) {
59643
61044
  var _a;
59644
61045
  const config = getAnimatorConfig(doc) || {};
59645
- const bindings = getNormalisedBindings(doc);
59646
61046
  if (!rootElement) {
59647
61047
  if (doc.id) {
59648
61048
  const rootSelector = getSelector(doc.id);
@@ -59652,6 +61052,7 @@ ${codeFrame}` : message);
59652
61052
  console.warn("createFrameLoopAnimator: No root element provided");
59653
61053
  }
59654
61054
  }
61055
+ const bindings = getNormalisedBindings(doc, PxAnimatorEngine.webapi);
59655
61056
  const animations = [];
59656
61057
  const _iterations = config.iterations;
59657
61058
  let iterations;
@@ -59781,15 +61182,15 @@ ${codeFrame}` : message);
59781
61182
  function createAnimatorFromConfig(doc, adapter, callbacks, rootElement) {
59782
61183
  const animatorConfig = getAnimatorConfig(doc) || {};
59783
61184
  let res;
59784
- if (animatorConfig.mode === "frames") {
61185
+ if (animatorConfig.mode === PxAnimatorMode.frames) {
59785
61186
  res = createFrameLoopAnimator(doc, adapter, callbacks, rootElement);
59786
61187
  } else {
59787
61188
  res = createWebApiAnimator(
59788
61189
  doc,
59789
61190
  callbacks,
59790
61191
  rootElement,
59791
- animatorConfig.mode === "webapi"
59792
- // Forcing "webapi"
61192
+ animatorConfig.mode === PxAnimatorMode.webapi
61193
+ // forcing webapi
59793
61194
  ) || createFrameLoopAnimator(doc, adapter, callbacks, rootElement);
59794
61195
  }
59795
61196
  if (animatorConfig.debugInstName) {
@@ -59911,9 +61312,10 @@ ${codeFrame}` : message);
59911
61312
  function createAnimatorImpl(doc, adapter, callbacks, containerElement) {
59912
61313
  const effectsWarnings = validateNodeEffects(doc);
59913
61314
  for (const w of effectsWarnings) console.warn("[PxAnimator] effects shape warning:", w);
59914
- doc = applyPlayerEffects(doc).root;
59915
61315
  const animatorConfig = getAnimatorConfig(doc) || {};
59916
61316
  animatorConfig.debug = true;
61317
+ const engine = animatorConfig.mode === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.webapi;
61318
+ doc = materialiseAllInTree(doc, engine);
59917
61319
  let rootElement = null;
59918
61320
  if (containerElement && doc.children) {
59919
61321
  doc = generateNewIds(doc);