@pixodesk/svg-animator-react 1.0.16 → 1.0.18

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
@@ -1770,6 +1770,7 @@ var PixodeskAnimatorReact = (() => {
1770
1770
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
1771
1771
  var __hasOwnProp2 = Object.prototype.hasOwnProperty;
1772
1772
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
1773
+ var __pow = Math.pow;
1773
1774
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1774
1775
  var __spreadValues = (a, b) => {
1775
1776
  for (var prop in b || (b = {}))
@@ -1812,7 +1813,7 @@ var PixodeskAnimatorReact = (() => {
1812
1813
  if (typeof raw === "object") {
1813
1814
  const obj = raw;
1814
1815
  if (obj.keyframes) {
1815
- return { kind: "animated", keyframes: obj.keyframes, autoOrient: obj.autoOrient };
1816
+ return { kind: "animated", keyframes: obj.keyframes, autoOrient: obj.autoOrient, loop: obj.loop };
1816
1817
  }
1817
1818
  if (obj.value !== void 0) return { kind: "static", value: obj.value };
1818
1819
  }
@@ -1900,6 +1901,7 @@ var PixodeskAnimatorReact = (() => {
1900
1901
  if (v.kind === "animated") {
1901
1902
  const animTr = { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, kf.value, void 0))) };
1902
1903
  if (v.autoOrient) animTr.autoOrient = true;
1904
+ if (v.loop !== void 0) animTr.loop = v.loop;
1903
1905
  return {
1904
1906
  type: "g",
1905
1907
  animate: { transform: animTr },
@@ -1918,9 +1920,11 @@ var PixodeskAnimatorReact = (() => {
1918
1920
  return { type: "g", transform: { value: { translate: sign(v.value) } }, children: [inner] };
1919
1921
  }
1920
1922
  if (v.kind === "animated") {
1923
+ const animTr = { keyframes: v.keyframes.map((kf) => keyframeWith(kf, { translate: sign(kf.value) })) };
1924
+ if (v.loop !== void 0) animTr.loop = v.loop;
1921
1925
  return {
1922
1926
  type: "g",
1923
- animate: { transform: { keyframes: v.keyframes.map((kf) => keyframeWith(kf, { translate: sign(kf.value) })) } },
1927
+ animate: { transform: animTr },
1924
1928
  children: [inner]
1925
1929
  };
1926
1930
  }
@@ -1928,8 +1932,8 @@ var PixodeskAnimatorReact = (() => {
1928
1932
  }
1929
1933
  function identifyContentRefTargets(node, ctx, allocator) {
1930
1934
  var _a, _b, _c;
1931
- if (node.type === "use" && ((_b = (_a = node.effects) == null ? void 0 : _a.ref) == null ? void 0 : _b.type) === "content") {
1932
- const baseId = node.effects.ref.baseId;
1935
+ if (node.type === "use" && ((_b = (_a = node.effects) == null ? void 0 : _a.clone) == null ? void 0 : _b.type) === "content") {
1936
+ const baseId = node.effects.clone.baseId;
1933
1937
  if (typeof baseId === "string" && baseId && !ctx.contentRefInnerIds.has(baseId)) {
1934
1938
  ctx.contentRefInnerIds.set(baseId, allocator(baseId));
1935
1939
  }
@@ -1977,6 +1981,8 @@ var PixodeskAnimatorReact = (() => {
1977
1981
  });
1978
1982
  const outerAnimTr = { keyframes: outerKfs };
1979
1983
  if (animTr.autoOrient) outerAnimTr.autoOrient = true;
1984
+ const srcLoop = animTr.loop;
1985
+ if (srcLoop !== void 0) outerAnimTr.loop = srcLoop;
1980
1986
  out.animate = { transform: outerAnimTr };
1981
1987
  const innerHasPivotedPart = kfs.some((kf) => {
1982
1988
  const v = kf.value || {};
@@ -1998,7 +2004,9 @@ var PixodeskAnimatorReact = (() => {
1998
2004
  delete node.animate.transform;
1999
2005
  if (node.animate && Object.keys(node.animate).length === 0) delete node.animate;
2000
2006
  } else {
2001
- node.animate.transform = { keyframes: innerKfs };
2007
+ const innerAnimTr = { keyframes: innerKfs };
2008
+ if (srcLoop !== void 0) innerAnimTr.loop = srcLoop;
2009
+ node.animate.transform = innerAnimTr;
2002
2010
  }
2003
2011
  didLiftAnimate = true;
2004
2012
  }
@@ -2643,10 +2651,22 @@ var PixodeskAnimatorReact = (() => {
2643
2651
  outAction: px.enum(["continue", "pause", "reset", "reverse"]).optional(),
2644
2652
  scrollIntoViewThreshold: px.number().optional()
2645
2653
  }));
2654
+ var PxGlyphSchema = implementsInterface()(px.object({
2655
+ width: px.number(),
2656
+ d: px.string()
2657
+ }));
2658
+ var PxGlyphFontSchema = implementsInterface()(px.object({
2659
+ fFamily: px.string(),
2660
+ style: px.string(),
2661
+ ascent: px.number(),
2662
+ unitsPerEm: px.number(),
2663
+ glyphs: px.record(PxGlyphSchema)
2664
+ }));
2646
2665
  var PxDefsSchema = implementsInterface()(px.object({
2647
2666
  easings: px.record(px.tuple([px.number(), px.number(), px.number(), px.number()])).optional(),
2648
2667
  animations: px.record(PxAnimationDefinitionSchema).optional(),
2649
- styles: px.record(px.any()).optional()
2668
+ styles: px.record(px.any()).optional(),
2669
+ glyphs: px.record(PxGlyphFontSchema).optional()
2650
2670
  }));
2651
2671
  var PxAnimatorConfigSchema = implementsInterface()(px.object({
2652
2672
  mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.webapi, PxAnimatorMode.frames]).optional(),
@@ -2719,9 +2739,10 @@ var PixodeskAnimatorReact = (() => {
2719
2739
  stretch: px.number().optional(),
2720
2740
  timeCrop: px.tuple([px.number(), px.number()]).optional()
2721
2741
  }));
2722
- var PxRefEffectSchema = implementsInterface()(px.object({
2742
+ var PxCloneEffectSchema = implementsInterface()(px.object({
2743
+ type: px.string().optional(),
2723
2744
  baseId: px.string().optional(),
2724
- type: px.string().optional()
2745
+ retime: PxRetimeEffectSchema.optional()
2725
2746
  }));
2726
2747
  var PxGradientType = {
2727
2748
  linear: "linear",
@@ -2757,17 +2778,20 @@ var PixodeskAnimatorReact = (() => {
2757
2778
  startOffset: PxAnimatableNumberSchema.optional(),
2758
2779
  textLength: PxAnimatableNumberSchema.optional()
2759
2780
  }));
2781
+ var PxTextEffectSchema = implementsInterface()(px.object({
2782
+ useGlyphs: px.boolean().optional()
2783
+ }));
2760
2784
  var PxEffectsSchema = implementsInterface()(px.object({
2761
2785
  transformation: PxTransformationEffectSchema.optional(),
2762
2786
  repeater: PxRepeaterEffectSchema.optional(),
2763
2787
  maskedBy: PxMaskedByEffectSchema.optional(),
2764
2788
  trimPath: PxTrimPathEffectSchema.optional(),
2765
- retime: PxRetimeEffectSchema.optional(),
2789
+ clone: PxCloneEffectSchema.optional(),
2766
2790
  isCombinedShape: px.boolean().optional(),
2767
- ref: PxRefEffectSchema.optional(),
2768
2791
  fillGradient: PxFillGradientEffectSchema.optional(),
2769
2792
  strokeGradient: PxStrokeGradientEffectSchema.optional(),
2770
- textAlongPath: PxTextAlongPathEffectSchema.optional()
2793
+ textAlongPath: PxTextAlongPathEffectSchema.optional(),
2794
+ text: PxTextEffectSchema.optional()
2771
2795
  }));
2772
2796
  function validateNodeEffects(root, opts) {
2773
2797
  const warnings = [];
@@ -2979,6 +3003,7 @@ var PixodeskAnimatorReact = (() => {
2979
3003
  const animBlock = stops;
2980
3004
  const kfs = animBlock.keyframes;
2981
3005
  if (!Array.isArray(kfs) || !kfs.length) return [];
3006
+ const loopFromSource = animBlock.loop;
2982
3007
  let stopCount = 0;
2983
3008
  for (const kf of kfs) {
2984
3009
  const v = (_a = kf.value) != null ? _a : kf.v;
@@ -2991,7 +3016,7 @@ var PixodeskAnimatorReact = (() => {
2991
3016
  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" };
2992
3017
  baselineStops.push({ offset: s.offset, color: s.color });
2993
3018
  }
2994
- return baselineStops.map((bs, i) => animatedStopNode(bs, kfs, i, ctx));
3019
+ return baselineStops.map((bs, i) => animatedStopNode(bs, kfs, i, ctx, loopFromSource));
2995
3020
  }
2996
3021
  function staticStopNode(s) {
2997
3022
  return {
@@ -3000,7 +3025,7 @@ var PixodeskAnimatorReact = (() => {
3000
3025
  stopColor: s.color
3001
3026
  };
3002
3027
  }
3003
- function animatedStopNode(baseline, kfs, stopIdx, _ctx) {
3028
+ function animatedStopNode(baseline, kfs, stopIdx, _ctx, loop) {
3004
3029
  var _a, _b, _c, _d, _e;
3005
3030
  const colorKfs = [];
3006
3031
  const offsetKfs = [];
@@ -3025,8 +3050,14 @@ var PixodeskAnimatorReact = (() => {
3025
3050
  stopColor: baseline.color
3026
3051
  };
3027
3052
  const animate = {};
3028
- if (colorKfs.length) animate.stopColor = { keyframes: colorKfs };
3029
- if (offsetVaries && offsetKfs.length) animate.offset = { keyframes: offsetKfs };
3053
+ if (colorKfs.length) {
3054
+ animate.stopColor = { keyframes: colorKfs };
3055
+ if (loop !== void 0) animate.stopColor.loop = loop;
3056
+ }
3057
+ if (offsetVaries && offsetKfs.length) {
3058
+ animate.offset = { keyframes: offsetKfs };
3059
+ if (loop !== void 0) animate.offset.loop = loop;
3060
+ }
3030
3061
  if (Object.keys(animate).length) stop.animate = animate;
3031
3062
  return stop;
3032
3063
  }
@@ -3089,9 +3120,11 @@ var PixodeskAnimatorReact = (() => {
3089
3120
  return { type: "g", transform: { value: partsRecord(part, invertPartValue(part, v.value), origin) }, children: [inner] };
3090
3121
  }
3091
3122
  if (v.kind === "animated") {
3123
+ const animTr = { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, invertPartValue(part, kf.value), origin))) };
3124
+ if (v.loop !== void 0) animTr.loop = v.loop;
3092
3125
  return {
3093
3126
  type: "g",
3094
- animate: { transform: { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, invertPartValue(part, kf.value), origin))) } },
3127
+ animate: { transform: animTr },
3095
3128
  children: [inner]
3096
3129
  };
3097
3130
  }
@@ -3128,10 +3161,16 @@ var PixodeskAnimatorReact = (() => {
3128
3161
  scaleKfs.push(__spreadProps(__spreadValues({}, baseKf), { value: rec }));
3129
3162
  }
3130
3163
  }
3164
+ const srcLoop = animTr == null ? void 0 : animTr.loop;
3165
+ const withLoop = (kfs2) => {
3166
+ const block = { keyframes: kfs2 };
3167
+ if (srcLoop !== void 0) block.loop = srcLoop;
3168
+ return block;
3169
+ };
3131
3170
  let n = inner;
3132
- if (translateKfs.length) n = { type: "g", animate: { transform: { keyframes: translateKfs } }, children: [n] };
3133
- if (rotateKfs.length) n = { type: "g", animate: { transform: { keyframes: rotateKfs } }, children: [n] };
3134
- if (scaleKfs.length) n = { type: "g", animate: { transform: { keyframes: scaleKfs } }, children: [n] };
3171
+ if (translateKfs.length) n = { type: "g", animate: { transform: withLoop(translateKfs) }, children: [n] };
3172
+ if (rotateKfs.length) n = { type: "g", animate: { transform: withLoop(rotateKfs) }, children: [n] };
3173
+ if (scaleKfs.length) n = { type: "g", animate: { transform: withLoop(scaleKfs) }, children: [n] };
3135
3174
  return n;
3136
3175
  }
3137
3176
  function nodeHasBodyTransform(node) {
@@ -3363,16 +3402,18 @@ var PixodeskAnimatorReact = (() => {
3363
3402
  return seen ? [x, y] : void 0;
3364
3403
  }
3365
3404
  var CONTENT_SUBREF = "content";
3366
- function applyRefAndTransformationEffect(node, ref, transformation, ctx) {
3367
- if (ref) {
3368
- const baseId = ref.baseId;
3369
- if (!baseId) {
3370
- ctx.errors.push("ref: missing baseId");
3371
- } else {
3372
- const targetId = ref.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(baseId) || baseId : baseId;
3373
- node.href = "#" + targetId;
3374
- }
3405
+ function applyRefHref(node, clone2, ctx) {
3406
+ if (!clone2) return;
3407
+ const baseId = clone2.baseId;
3408
+ if (!baseId) {
3409
+ if (clone2.type === CONTENT_SUBREF) ctx.errors.push("clone: content ref missing baseId");
3410
+ return;
3375
3411
  }
3412
+ const targetId = clone2.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(baseId) || baseId : baseId;
3413
+ node.href = "#" + targetId;
3414
+ }
3415
+ function applyRefAndTransformationEffect(node, clone2, transformation, ctx) {
3416
+ applyRefHref(node, clone2, ctx);
3376
3417
  return applyTransformationEffect(node, transformation, ctx);
3377
3418
  }
3378
3419
  function applyRepeaterEffect(node, fx, ctx) {
@@ -3479,22 +3520,32 @@ var PixodeskAnimatorReact = (() => {
3479
3520
  stretch: parent.stretch * child.stretch
3480
3521
  };
3481
3522
  }
3482
- function applyAllRetimeEffects(root, ctx) {
3523
+ function readCloneRetime(n) {
3524
+ var _a, _b;
3525
+ return (_b = (_a = n.effects) == null ? void 0 : _a.clone) == null ? void 0 : _b.retime;
3526
+ }
3527
+ function clearCloneRetime(n) {
3483
3528
  var _a;
3529
+ const clone2 = (_a = n.effects) == null ? void 0 : _a.clone;
3530
+ if (!clone2) return;
3531
+ delete clone2.retime;
3532
+ if (Object.keys(clone2).length === 0) delete n.effects.clone;
3533
+ if (n.effects && Object.keys(n.effects).length === 0) delete n.effects;
3534
+ }
3535
+ function applyAllRetimeEffects(root, ctx) {
3484
3536
  ctx.idMap.clear();
3485
3537
  indexById(root, ctx.idMap);
3486
3538
  const sites = [];
3487
3539
  const collect = (n) => {
3488
- var _a2, _b;
3489
- if ((_a2 = n.effects) == null ? void 0 : _a2.retime) sites.push(n);
3490
- (_b = n.children) == null ? void 0 : _b.forEach(collect);
3540
+ var _a;
3541
+ if (readCloneRetime(n)) sites.push(n);
3542
+ (_a = n.children) == null ? void 0 : _a.forEach(collect);
3491
3543
  };
3492
3544
  collect(root);
3493
3545
  for (const useNode of sites) {
3494
- const retime = (_a = useNode.effects) == null ? void 0 : _a.retime;
3546
+ const retime = readCloneRetime(useNode);
3495
3547
  if (!retime) continue;
3496
- delete useNode.effects.retime;
3497
- if (Object.keys(useNode.effects).length === 0) delete useNode.effects;
3548
+ clearCloneRetime(useNode);
3498
3549
  materialiseRetime(useNode, asRetime(retime), ctx);
3499
3550
  }
3500
3551
  }
@@ -3518,7 +3569,6 @@ var PixodeskAnimatorReact = (() => {
3518
3569
  }
3519
3570
  }
3520
3571
  function buildChainClone(targetId, accum, ctx, chain) {
3521
- var _a, _b;
3522
3572
  if (chain.has(targetId)) {
3523
3573
  ctx.errors.push('retime: loop via "' + targetId + '"');
3524
3574
  return void 0;
@@ -3535,25 +3585,43 @@ var PixodeskAnimatorReact = (() => {
3535
3585
  } else {
3536
3586
  remapKeyframeTimes(cloneNode, accum.start, accum.stretch);
3537
3587
  }
3538
- if ((_a = cloneNode.effects) == null ? void 0 : _a.retime) {
3539
- delete cloneNode.effects.retime;
3540
- if (Object.keys(cloneNode.effects).length === 0) delete cloneNode.effects;
3541
- }
3588
+ clearCloneRetime(cloneNode);
3542
3589
  if (target.type === "use" && target.href) {
3543
3590
  const subId = stripHash(target.href);
3544
3591
  if (subId) {
3545
- const innerRetime = (_b = target.effects) == null ? void 0 : _b.retime;
3592
+ const innerRetime = readCloneRetime(target);
3546
3593
  const subAccum = innerRetime ? concatRetime(asRetime(innerRetime), accum) : accum;
3547
3594
  const subChain = new Set(chain);
3548
3595
  subChain.add(targetId);
3549
3596
  const subId2 = buildChainClone(subId, subAccum, ctx, subChain);
3550
3597
  if (subId2) cloneNode.href = "#" + subId2;
3551
3598
  }
3599
+ } else {
3600
+ materialiseNestedRetimeUses(cloneNode, accum, ctx, chain, targetId);
3552
3601
  }
3553
3602
  ctx.defs.push(cloneNode);
3554
3603
  if (typeof cloneNode.id === "string") ctx.idMap.set(cloneNode.id, cloneNode);
3555
3604
  return typeof cloneNode.id === "string" ? cloneNode.id : void 0;
3556
3605
  }
3606
+ function materialiseNestedRetimeUses(node, accum, ctx, chain, parentTargetId) {
3607
+ const visit = (n) => {
3608
+ var _a;
3609
+ const retime = readCloneRetime(n);
3610
+ if (n.type === "use" && retime && n.href) {
3611
+ const subId = stripHash(n.href);
3612
+ if (subId) {
3613
+ const subAccum = concatRetime(asRetime(retime), accum);
3614
+ const subChain = new Set(chain);
3615
+ subChain.add(parentTargetId);
3616
+ const subId2 = buildChainClone(subId, subAccum, ctx, subChain);
3617
+ if (subId2) n.href = "#" + subId2;
3618
+ }
3619
+ clearCloneRetime(n);
3620
+ }
3621
+ (_a = n.children) == null ? void 0 : _a.forEach(visit);
3622
+ };
3623
+ visit(node);
3624
+ }
3557
3625
  function remapKeyframeTimes(node, start, stretch) {
3558
3626
  var _a;
3559
3627
  remapKeyframeTimesOnly(node, start, stretch);
@@ -3596,12 +3664,14 @@ var PixodeskAnimatorReact = (() => {
3596
3664
  node[attrName] = String(raw);
3597
3665
  return;
3598
3666
  }
3599
- if (typeof raw === "object") {
3667
+ if (typeof raw === "object" && raw !== null) {
3600
3668
  const obj = raw;
3601
3669
  if (Array.isArray(obj.keyframes)) {
3602
3670
  const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
3603
3671
  const animate = __spreadValues({}, prevAnimate || {});
3604
- animate[attrName] = { keyframes: obj.keyframes };
3672
+ const block = { keyframes: obj.keyframes };
3673
+ if (obj.loop !== void 0) block.loop = obj.loop;
3674
+ animate[attrName] = block;
3605
3675
  node.animate = animate;
3606
3676
  return;
3607
3677
  }
@@ -3611,6 +3681,57 @@ var PixodeskAnimatorReact = (() => {
3611
3681
  }
3612
3682
  }
3613
3683
  }
3684
+ var jsonElementFactory = (type, props, children) => {
3685
+ const node = { type };
3686
+ for (const k in props) if (props[k] !== void 0) node[k] = props[k];
3687
+ const arr = Array.isArray(children) ? children.filter((c) => c != null) : children != null ? [children] : [];
3688
+ if (arr.length) node.children = arr;
3689
+ return node;
3690
+ };
3691
+ function fmt(v, decimals) {
3692
+ return Math.round(v) === v ? "" + Math.round(v) : v.toFixed(decimals);
3693
+ }
3694
+ function pack(nums, decimals) {
3695
+ let s = "";
3696
+ for (let i = 0; i < nums.length; i++) {
3697
+ const str2 = fmt(nums[i], decimals);
3698
+ if (i > 0 && str2.charCodeAt(0) !== 45) s += " ";
3699
+ s += str2;
3700
+ }
3701
+ return s;
3702
+ }
3703
+ function apply(m, x, y) {
3704
+ return [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];
3705
+ }
3706
+ var TOKEN_RE = /([MLCQZ])|(-?\d*\.?\d+(?:e[-+]?\d+)?)/gi;
3707
+ function transformPathData(d, m, decimals = 2) {
3708
+ const tokens = [];
3709
+ let match;
3710
+ TOKEN_RE.lastIndex = 0;
3711
+ while ((match = TOKEN_RE.exec(d)) !== null) tokens.push(match[0]);
3712
+ let out = "";
3713
+ let i = 0;
3714
+ const num2 = () => parseFloat(tokens[i++]);
3715
+ while (i < tokens.length) {
3716
+ const cmd = tokens[i++];
3717
+ if (cmd === "M" || cmd === "L") {
3718
+ const [x, y] = apply(m, num2(), num2());
3719
+ out += cmd + pack([x, y], decimals);
3720
+ } else if (cmd === "C") {
3721
+ const [x1, y1] = apply(m, num2(), num2());
3722
+ const [x2, y2] = apply(m, num2(), num2());
3723
+ const [x, y] = apply(m, num2(), num2());
3724
+ out += "C" + pack([x1, y1, x2, y2, x, y], decimals);
3725
+ } else if (cmd === "Q") {
3726
+ const [x1, y1] = apply(m, num2(), num2());
3727
+ const [x, y] = apply(m, num2(), num2());
3728
+ out += "Q" + pack([x1, y1, x, y], decimals);
3729
+ } else if (cmd === "Z" || cmd === "z") {
3730
+ out += "Z";
3731
+ }
3732
+ }
3733
+ return out;
3734
+ }
3614
3735
  function bezierToSvgPath(path) {
3615
3736
  var _a, _b, _c, _d;
3616
3737
  const v = path.v;
@@ -3982,6 +4103,24 @@ var PixodeskAnimatorReact = (() => {
3982
4103
  }
3983
4104
  return { ts, ds };
3984
4105
  }
4106
+ function bezier2D_tForDistance(lut, distance) {
4107
+ const { ts, ds } = lut;
4108
+ const last = ds.length - 1;
4109
+ if (distance <= 0) return ts[0];
4110
+ if (distance >= ds[last]) return ts[last];
4111
+ let lo = 1;
4112
+ let hi = last;
4113
+ while (lo < hi) {
4114
+ const mid = lo + hi >>> 1;
4115
+ if (ds[mid] < distance) lo = mid + 1;
4116
+ else hi = mid;
4117
+ }
4118
+ const dPrev = ds[hi - 1];
4119
+ const dCur = ds[hi];
4120
+ const span = dCur - dPrev;
4121
+ const frac = span > 0 ? (distance - dPrev) / span : 0;
4122
+ return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);
4123
+ }
3985
4124
  function bezier2D_arcAtT(lut, t) {
3986
4125
  const { ts, ds } = lut;
3987
4126
  const last = ts.length - 1;
@@ -4003,6 +4142,435 @@ var PixodeskAnimatorReact = (() => {
4003
4142
  const flipped = [easing[1], easing[0], easing[3], easing[2]];
4004
4143
  return cubicBezier(flipped);
4005
4144
  }
4145
+ var LUT_STEPS = 48;
4146
+ var CMD_RE = /[MmLlHhVvCcSsQqTtAaZz]/;
4147
+ function tokenize(d) {
4148
+ const tokens = [];
4149
+ const re = /([MmLlHhVvCcSsQqTtAaZz])|(-?\d*\.?\d+(?:[eE][-+]?\d+)?)/g;
4150
+ let m;
4151
+ while ((m = re.exec(d)) !== null) tokens.push(m[0]);
4152
+ return tokens;
4153
+ }
4154
+ function quadToCubic(P0, Qc, P3) {
4155
+ return {
4156
+ P1: [P0[0] + 2 / 3 * (Qc[0] - P0[0]), P0[1] + 2 / 3 * (Qc[1] - P0[1])],
4157
+ P2: [P3[0] + 2 / 3 * (Qc[0] - P3[0]), P3[1] + 2 / 3 * (Qc[1] - P3[1])]
4158
+ };
4159
+ }
4160
+ function parseCubics(d) {
4161
+ const tokens = tokenize(d);
4162
+ const segs = [];
4163
+ let i = 0;
4164
+ let cx = 0, cy = 0;
4165
+ let sx = 0, sy = 0;
4166
+ let pcx = 0, pcy = 0;
4167
+ let pqx = 0, pqy = 0;
4168
+ let prevCmd = "";
4169
+ const num2 = () => parseFloat(tokens[i++]);
4170
+ const push = (P1, P2, P3) => {
4171
+ const P0 = [cx, cy];
4172
+ const lut = bezier2D_arcLengthLUT(P0, P1, P2, P3, LUT_STEPS);
4173
+ segs.push({ P0, P1, P2, P3, lut, len: lut.ds[lut.ds.length - 1] });
4174
+ cx = P3[0];
4175
+ cy = P3[1];
4176
+ };
4177
+ const pushLine = (x, y) => {
4178
+ push(
4179
+ [cx + (x - cx) / 3, cy + (y - cy) / 3],
4180
+ [cx + 2 * (x - cx) / 3, cy + 2 * (y - cy) / 3],
4181
+ [x, y]
4182
+ );
4183
+ };
4184
+ while (i < tokens.length) {
4185
+ let cmd = tokens[i];
4186
+ if (CMD_RE.test(cmd)) i++;
4187
+ else cmd = prevCmd === "M" ? "L" : prevCmd === "m" ? "l" : prevCmd;
4188
+ const rel = cmd >= "a";
4189
+ const U = cmd.toUpperCase();
4190
+ if (U === "Z") {
4191
+ pushLine(sx, sy);
4192
+ cx = sx;
4193
+ cy = sy;
4194
+ prevCmd = cmd;
4195
+ continue;
4196
+ }
4197
+ if (U === "M") {
4198
+ const x = num2() + (rel ? cx : 0), y = num2() + (rel ? cy : 0);
4199
+ cx = x;
4200
+ cy = y;
4201
+ sx = x;
4202
+ sy = y;
4203
+ prevCmd = cmd;
4204
+ continue;
4205
+ }
4206
+ if (U === "L") {
4207
+ pushLine(num2() + (rel ? cx : 0), num2() + (rel ? cy : 0));
4208
+ } else if (U === "H") {
4209
+ pushLine(num2() + (rel ? cx : 0), cy);
4210
+ } else if (U === "V") {
4211
+ pushLine(cx, num2() + (rel ? cy : 0));
4212
+ } else if (U === "C") {
4213
+ const p1 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4214
+ const p2 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4215
+ const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4216
+ pcx = p2[0];
4217
+ pcy = p2[1];
4218
+ push(p1, p2, p3);
4219
+ } else if (U === "S") {
4220
+ const smooth = prevCmd.toUpperCase() === "C" || prevCmd.toUpperCase() === "S";
4221
+ const p1 = smooth ? [2 * cx - pcx, 2 * cy - pcy] : [cx, cy];
4222
+ const p2 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4223
+ const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4224
+ pcx = p2[0];
4225
+ pcy = p2[1];
4226
+ push(p1, p2, p3);
4227
+ } else if (U === "Q") {
4228
+ const qc = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4229
+ const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4230
+ pqx = qc[0];
4231
+ pqy = qc[1];
4232
+ const { P1, P2 } = quadToCubic([cx, cy], qc, p3);
4233
+ push(P1, P2, p3);
4234
+ } else if (U === "T") {
4235
+ const smooth = prevCmd.toUpperCase() === "Q" || prevCmd.toUpperCase() === "T";
4236
+ const qc = smooth ? [2 * cx - pqx, 2 * cy - pqy] : [cx, cy];
4237
+ const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4238
+ pqx = qc[0];
4239
+ pqy = qc[1];
4240
+ const { P1, P2 } = quadToCubic([cx, cy], qc, p3);
4241
+ push(P1, P2, p3);
4242
+ } else if (U === "A") {
4243
+ i += 5;
4244
+ pushLine(num2() + (rel ? cx : 0), num2() + (rel ? cy : 0));
4245
+ } else {
4246
+ i++;
4247
+ continue;
4248
+ }
4249
+ prevCmd = cmd;
4250
+ }
4251
+ return segs.length ? segs : null;
4252
+ }
4253
+ function clamp2(v, lo, hi) {
4254
+ return v < lo ? lo : v > hi ? hi : v;
4255
+ }
4256
+ function createPathSampler(d) {
4257
+ const segs = parseCubics(d);
4258
+ if (!segs) return null;
4259
+ const cum = new Float64Array(segs.length + 1);
4260
+ for (let k = 0; k < segs.length; k++) cum[k + 1] = cum[k] + segs[k].len;
4261
+ const totalLength = cum[segs.length];
4262
+ const start = segs[0].P0, end = segs[segs.length - 1].P3;
4263
+ const closed = Math.hypot(end[0] - start[0], end[1] - start[1]) < 1e-3;
4264
+ const sampleOn = (dist) => {
4265
+ let k = 0;
4266
+ while (k < segs.length - 1 && dist > cum[k + 1]) k++;
4267
+ const seg = segs[k];
4268
+ const local = dist - cum[k];
4269
+ const t = seg.len > 0 ? bezier2D_tForDistance(seg.lut, local) : 0;
4270
+ const [x, y] = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
4271
+ const [dx, dy] = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
4272
+ return { x, y, angle: Math.atan2(dy, dx) };
4273
+ };
4274
+ return {
4275
+ totalLength,
4276
+ sampleAtDistance(dist) {
4277
+ if (!closed && (dist < 0 || dist > totalLength)) {
4278
+ const edge = dist < 0 ? 0 : totalLength;
4279
+ const p = sampleOn(edge);
4280
+ const over = dist - edge;
4281
+ return { x: p.x + Math.cos(p.angle) * over, y: p.y + Math.sin(p.angle) * over, angle: p.angle };
4282
+ }
4283
+ return sampleOn(clamp2(dist, 0, totalLength));
4284
+ }
4285
+ };
4286
+ }
4287
+ var DEFAULT_FONT_SIZE = 16;
4288
+ var TEXT_ATTR_KEYS = [
4289
+ "fontFamily",
4290
+ "fontSize",
4291
+ "fontWeight",
4292
+ "fontStyle",
4293
+ "textAnchor",
4294
+ "letterSpacing",
4295
+ "wordSpacing",
4296
+ "textDecoration",
4297
+ "textTransform",
4298
+ "whiteSpace",
4299
+ "x",
4300
+ "y",
4301
+ "dx",
4302
+ "dy",
4303
+ "lengthAdjust",
4304
+ "fill",
4305
+ "stroke",
4306
+ "strokeWidth",
4307
+ "effects",
4308
+ TEXT_ATTR,
4309
+ TEXT_CONTENT_ATTR,
4310
+ "xml:space"
4311
+ ];
4312
+ function parseLen(v) {
4313
+ if (typeof v === "number") return v;
4314
+ if (typeof v === "string") {
4315
+ const n = parseFloat(v);
4316
+ return isNaN(n) ? void 0 : n;
4317
+ }
4318
+ return void 0;
4319
+ }
4320
+ function str(v) {
4321
+ return typeof v === "string" ? v : void 0;
4322
+ }
4323
+ function resolveStyle(node, parent) {
4324
+ var _a, _b, _c, _d, _e, _f, _g;
4325
+ return {
4326
+ fontFamily: (_a = str(node.fontFamily)) != null ? _a : parent.fontFamily,
4327
+ fontSize: (_b = parseLen(node.fontSize)) != null ? _b : parent.fontSize,
4328
+ fill: (_c = node.fill) != null ? _c : parent.fill,
4329
+ stroke: (_d = node.stroke) != null ? _d : parent.stroke,
4330
+ strokeWidth: (_e = node.strokeWidth) != null ? _e : parent.strokeWidth,
4331
+ letterSpacing: (_f = parseLen(node.letterSpacing)) != null ? _f : parent.letterSpacing,
4332
+ wordSpacing: (_g = parseLen(node.wordSpacing)) != null ? _g : parent.wordSpacing
4333
+ };
4334
+ }
4335
+ function rootStyleOf(node) {
4336
+ var _a, _b, _c;
4337
+ return {
4338
+ fontFamily: str(node.fontFamily),
4339
+ fontSize: (_a = parseLen(node.fontSize)) != null ? _a : DEFAULT_FONT_SIZE,
4340
+ fill: node.fill,
4341
+ stroke: node.stroke,
4342
+ strokeWidth: node.strokeWidth,
4343
+ letterSpacing: (_b = parseLen(node.letterSpacing)) != null ? _b : 0,
4344
+ wordSpacing: (_c = parseLen(node.wordSpacing)) != null ? _c : 0
4345
+ };
4346
+ }
4347
+ function paintOf(s) {
4348
+ const p = {};
4349
+ if (s.fill !== void 0) p.fill = s.fill;
4350
+ if (s.stroke !== void 0) p.stroke = s.stroke;
4351
+ if (s.strokeWidth !== void 0) p.strokeWidth = s.strokeWidth;
4352
+ return p;
4353
+ }
4354
+ function glyphFontFor(s, glyphs, soleFont, warnings) {
4355
+ var _a;
4356
+ const gf = s.fontFamily ? glyphs[s.fontFamily] : soleFont;
4357
+ if (!gf) warnings == null ? void 0 : warnings.push('textGlyphs: no glyphs for font "' + ((_a = s.fontFamily) != null ? _a : "") + '"');
4358
+ return gf;
4359
+ }
4360
+ function soleFontOf(glyphs) {
4361
+ const names = Object.keys(glyphs);
4362
+ return names.length === 1 ? glyphs[names[0]] : void 0;
4363
+ }
4364
+ function materialiseGlyphTextHorizontal(node, opts) {
4365
+ var _a, _b, _c, _d;
4366
+ const { glyphs, create = jsonElementFactory, warnings } = opts;
4367
+ const soleFont = soleFontOf(glyphs);
4368
+ const pen = { x: (_a = parseLen(node.x)) != null ? _a : 0, y: (_b = parseLen(node.y)) != null ? _b : 0 };
4369
+ const placements = [];
4370
+ const lines = [{ start: pen.x, end: pen.x }];
4371
+ let line = 0;
4372
+ const renderChars = (content, s) => {
4373
+ const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4374
+ if (!gf) return;
4375
+ const scale = s.fontSize / gf.unitsPerEm;
4376
+ const paint = paintOf(s);
4377
+ for (let i = 0; i < content.length; i++) {
4378
+ const ch = content.charAt(i);
4379
+ const g = gf.glyphs[ch];
4380
+ if (g && g.d) placements.push({ glyphD: g.d, m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });
4381
+ pen.x += (g ? g.width : 0) * scale + s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
4382
+ lines[line].end = pen.x;
4383
+ }
4384
+ };
4385
+ const walk = (el, parentStyle) => {
4386
+ var _a2, _b2, _c2, _d2;
4387
+ const s = resolveStyle(el, parentStyle);
4388
+ const x = parseLen(el.x);
4389
+ const y = parseLen(el.y);
4390
+ if (x !== void 0) {
4391
+ pen.x = x;
4392
+ line = lines.length;
4393
+ lines.push({ start: pen.x, end: pen.x });
4394
+ }
4395
+ if (y !== void 0) pen.y = y;
4396
+ pen.x += (_a2 = parseLen(el.dx)) != null ? _a2 : 0;
4397
+ pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
4398
+ const content = (_c2 = str(el[TEXT_ATTR])) != null ? _c2 : str(el[TEXT_CONTENT_ATTR]);
4399
+ if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
4400
+ if (el.children) for (const ch of el.children) walk(ch, s);
4401
+ };
4402
+ const rootStyle = rootStyleOf(node);
4403
+ if (node.children) for (const ch of node.children) walk(ch, rootStyle);
4404
+ const rootContent = (_c = str(node[TEXT_ATTR])) != null ? _c : str(node[TEXT_CONTENT_ATTR]);
4405
+ if (rootContent && !((_d = node.children) == null ? void 0 : _d.length)) renderChars(rootContent, rootStyle);
4406
+ const anchor = str(node.textAnchor);
4407
+ if (anchor === "middle" || anchor === "end") {
4408
+ for (const p of placements) {
4409
+ const w = lines[p.line].end - lines[p.line].start;
4410
+ const shift = anchor === "middle" ? -w / 2 : -w;
4411
+ p.m = [p.scale, 0, 0, p.scale, p.x + shift, p.y];
4412
+ }
4413
+ }
4414
+ return toGroup(node, buildPaths(placements, create, warnings), create);
4415
+ }
4416
+ function collectAlongPathCells(node, glyphs, soleFont, warnings) {
4417
+ const cells = [];
4418
+ let adv = 0;
4419
+ const walk = (el, parentStyle) => {
4420
+ var _a, _b;
4421
+ const s = resolveStyle(el, parentStyle);
4422
+ const content = (_a = str(el[TEXT_ATTR])) != null ? _a : str(el[TEXT_CONTENT_ATTR]);
4423
+ if (content && !((_b = el.children) == null ? void 0 : _b.length)) {
4424
+ const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4425
+ if (gf) {
4426
+ const scale = s.fontSize / gf.unitsPerEm;
4427
+ const paint = paintOf(s);
4428
+ for (let i = 0; i < content.length; i++) {
4429
+ const ch = content.charAt(i);
4430
+ const g = gf.glyphs[ch];
4431
+ const glyphAdv = (g ? g.width : 0) * scale;
4432
+ if (g && g.d) cells.push({ glyphD: g.d, widthEm: g.width, scale, paint, midBase: adv + glyphAdv / 2 });
4433
+ adv += glyphAdv + s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
4434
+ }
4435
+ }
4436
+ }
4437
+ if (el.children) for (const ch of el.children) walk(ch, s);
4438
+ };
4439
+ walk(node, rootStyleOf(node));
4440
+ return { cells, width: adv };
4441
+ }
4442
+ function alongAffine(sampler, dist, scale, widthEm) {
4443
+ const { x, y, angle } = sampler.sampleAtDistance(dist);
4444
+ const cos = Math.cos(angle), sin = Math.sin(angle), hw = widthEm / 2;
4445
+ return [scale * cos, scale * sin, -scale * sin, scale * cos, x - scale * cos * hw, y - scale * sin * hw];
4446
+ }
4447
+ function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLength) {
4448
+ var _a;
4449
+ const { glyphs, create = jsonElementFactory, warnings } = opts;
4450
+ const sampler = pathD ? createPathSampler(pathD) : null;
4451
+ if (!sampler) {
4452
+ warnings == null ? void 0 : warnings.push("textGlyphs: unparsable along-path geometry");
4453
+ return null;
4454
+ }
4455
+ const soleFont = soleFontOf(glyphs);
4456
+ const { cells, width } = collectAlongPathCells(node, glyphs, soleFont, warnings);
4457
+ if (!cells.length) return toGroup(node, [], create);
4458
+ if (textLength && textLength > 0 && width > 0) {
4459
+ const k = textLength / width;
4460
+ for (const c of cells) c.midBase *= k;
4461
+ }
4462
+ const so = readAnimatable(startOffset);
4463
+ if (so.kind === "animated" && so.keyframes.length >= 2) {
4464
+ return toGroup(node, buildAnimatedAlongPath(cells, sampler, so.keyframes, so.loop, create), create);
4465
+ }
4466
+ const base = so.kind === "animated" ? Number((_a = so.keyframes[0]) == null ? void 0 : _a.value) || 0 : so.kind === "static" ? Number(so.value) || 0 : 0;
4467
+ const placements = cells.map((c) => ({
4468
+ glyphD: c.glyphD,
4469
+ paint: c.paint,
4470
+ m: alongAffine(sampler, base + c.midBase, c.scale, c.widthEm)
4471
+ }));
4472
+ return toGroup(node, buildPaths(placements, create, warnings), create);
4473
+ }
4474
+ var ALONG_PATH_MAX_STEPS = 48;
4475
+ var ALONG_PATH_MAX_STEPS_PER_SEGMENT = 64;
4476
+ function roundN(v, n) {
4477
+ const f = __pow(10, n);
4478
+ return Math.round(v * f) / f;
4479
+ }
4480
+ function buildAnimatedAlongPath(cells, sampler, sokfs, loop, create) {
4481
+ const step = Math.max(sampler.totalLength / ALONG_PATH_MAX_STEPS, 0.5);
4482
+ const timeOf = (kf) => Number(kf.time) || 0;
4483
+ const offOf = (kf) => Number(kf.value) || 0;
4484
+ const out = [];
4485
+ for (const c of cells) {
4486
+ const centred = [c.scale, 0, 0, c.scale, -c.scale * (c.widthEm / 2), 0];
4487
+ const d = transformPathData(c.glyphD, centred);
4488
+ const sampleKf = (dist, time) => {
4489
+ const { x, y, angle } = sampler.sampleAtDistance(dist);
4490
+ return {
4491
+ time,
4492
+ value: {
4493
+ [
4494
+ "translate"
4495
+ /* Translate */
4496
+ ]: [roundN(x, 3), roundN(y, 3)],
4497
+ [
4498
+ "rotate"
4499
+ /* Rotate */
4500
+ ]: roundN(angle * 180 / Math.PI, 3)
4501
+ }
4502
+ };
4503
+ };
4504
+ const kfs = [sampleKf(offOf(sokfs[0]) + c.midBase, timeOf(sokfs[0]))];
4505
+ for (let k = 1; k < sokfs.length; k++) {
4506
+ const t0 = timeOf(sokfs[k - 1]), t1 = timeOf(sokfs[k]);
4507
+ const o0 = offOf(sokfs[k - 1]), o1 = offOf(sokfs[k]);
4508
+ const n = Math.min(ALONG_PATH_MAX_STEPS_PER_SEGMENT, Math.max(1, Math.ceil(Math.abs(o1 - o0) / step)));
4509
+ for (let s = 1; s <= n; s++) {
4510
+ const f = s / n;
4511
+ kfs.push(sampleKf(o0 + f * (o1 - o0) + c.midBase, t0 + f * (t1 - t0)));
4512
+ }
4513
+ }
4514
+ const transform = { keyframes: kfs };
4515
+ if (loop !== void 0) transform.loop = loop;
4516
+ out.push(create("path", __spreadProps(__spreadValues({ d }, paintProps(c.paint)), { animate: { transform } }), []));
4517
+ }
4518
+ return out;
4519
+ }
4520
+ function paintProps(paint) {
4521
+ const p = {};
4522
+ if (paint.fill !== void 0) p.fill = paint.fill;
4523
+ if (paint.stroke !== void 0) p.stroke = paint.stroke;
4524
+ if (paint.strokeWidth !== void 0) p.strokeWidth = paint.strokeWidth;
4525
+ return p;
4526
+ }
4527
+ function buildPaths(placements, create, warnings) {
4528
+ var _a, _b, _c;
4529
+ if (!placements.length) {
4530
+ warnings == null ? void 0 : warnings.push("textGlyphs: nothing to render");
4531
+ return [];
4532
+ }
4533
+ const byPaint = /* @__PURE__ */ new Map();
4534
+ for (const p of placements) {
4535
+ const key = JSON.stringify([(_a = p.paint.fill) != null ? _a : null, (_b = p.paint.stroke) != null ? _b : null, (_c = p.paint.strokeWidth) != null ? _c : null]);
4536
+ const baked = transformPathData(p.glyphD, p.m);
4537
+ const entry = byPaint.get(key);
4538
+ if (entry) entry.d += baked;
4539
+ else byPaint.set(key, { paint: p.paint, d: baked });
4540
+ }
4541
+ const out = [];
4542
+ for (const { paint, d } of byPaint.values()) out.push(create("path", __spreadValues({ d }, paintProps(paint)), []));
4543
+ return out;
4544
+ }
4545
+ function toGroup(node, children, create) {
4546
+ const gProps = {};
4547
+ for (const k of Object.keys(node)) {
4548
+ if (k === "type" || k === "children" || TEXT_ATTR_KEYS.indexOf(k) !== -1) continue;
4549
+ gProps[k] = node[k];
4550
+ }
4551
+ if (gProps.style && typeof gProps.style === "object") {
4552
+ const style = __spreadValues({}, gProps.style);
4553
+ delete style["white-space"];
4554
+ if (Object.keys(style).length) gProps.style = style;
4555
+ else delete gProps.style;
4556
+ }
4557
+ return create("g", gProps, children);
4558
+ }
4559
+ function applyTextGlyphsEffect(node, fx, ctx) {
4560
+ if (!(fx == null ? void 0 : fx.useGlyphs)) return node;
4561
+ if (!ctx.glyphs) {
4562
+ ctx.warnings.push("textGlyphs: no definitions.glyphs \u2014 left as native <text>");
4563
+ return node;
4564
+ }
4565
+ return materialiseGlyphTextHorizontal(node, { glyphs: ctx.glyphs, warnings: ctx.warnings });
4566
+ }
4567
+ function applyTextGlyphsAlongPath(node, ctx, pathD, startOffset, textLength) {
4568
+ if (!ctx.glyphs) {
4569
+ ctx.warnings.push("textGlyphs: no definitions.glyphs");
4570
+ return null;
4571
+ }
4572
+ return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength);
4573
+ }
4006
4574
  function getKfTranslate(kf) {
4007
4575
  var _a;
4008
4576
  const v = (_a = kf.value) != null ? _a : kf.v;
@@ -4443,12 +5011,12 @@ var PixodeskAnimatorReact = (() => {
4443
5011
  }
4444
5012
  return res;
4445
5013
  }
4446
- function extractPathData(str) {
4447
- if (str.startsWith("path(") && str.endsWith(")")) {
4448
- return str.slice(5, -1);
5014
+ function extractPathData(str2) {
5015
+ if (str2.startsWith("path(") && str2.endsWith(")")) {
5016
+ return str2.slice(5, -1);
4449
5017
  }
4450
- if (/^[MmZzLlHhVvCcSsQqTtAa]/.test(str)) {
4451
- return str;
5018
+ if (/^[MmZzLlHhVvCcSsQqTtAa]/.test(str2)) {
5019
+ return str2;
4452
5020
  }
4453
5021
  return void 0;
4454
5022
  }
@@ -4658,16 +5226,67 @@ var PixodeskAnimatorReact = (() => {
4658
5226
  looped.push(pushed);
4659
5227
  }
4660
5228
  }
4661
- for (let rep = 0; rep < fullReps; rep++) {
4662
- const distFromBoundary = loop.before ? fullReps - 1 - rep : rep;
4663
- const isReversed = !!loop.alternate && distFromBoundary % 2 === 0;
4664
- const repStart = fillStart + rep * segDuration;
4665
- appendRep(repStart, isReversed);
5229
+ function appendRepTail(repStart, isReversed, tailFraction) {
5230
+ let entries;
5231
+ if (isReversed) {
5232
+ entries = [];
5233
+ for (let i = template.length - 1; i >= 0; i--) {
5234
+ entries.push({
5235
+ relT: 1 - template[i].relT,
5236
+ v: template[i].v,
5237
+ e: i > 0 ? reverseEasing(template[i - 1].e) : void 0,
5238
+ tangentIn: template[i].tangentOut,
5239
+ tangentOut: template[i].tangentIn
5240
+ });
5241
+ }
5242
+ } else {
5243
+ entries = template;
5244
+ }
5245
+ const startRelT = 1 - tailFraction;
5246
+ for (let i = 0; i < entries.length; i++) {
5247
+ const entry = entries[i];
5248
+ if (entry.relT < startRelT - 1e-9) continue;
5249
+ const prev = entries[i - 1];
5250
+ if (prev && prev.relT < startRelT - 1e-9 && entry.relT > startRelT + 1e-9) {
5251
+ const intervalSpan = entry.relT - prev.relT;
5252
+ const localFrac = (startRelT - prev.relT) / intervalSpan;
5253
+ const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
5254
+ const startValue = interpolateValue(propName, prev.v, entry.v, easedFrac);
5255
+ const { right: rightEasing } = splitEasing(prev.e, localFrac);
5256
+ looped.push({ t: repStart, v: startValue, e: rightEasing });
5257
+ }
5258
+ const pushed = {
5259
+ t: repStart + (entry.relT - startRelT) * segDuration,
5260
+ v: entry.v,
5261
+ e: i < entries.length - 1 ? entry.e : void 0
5262
+ };
5263
+ if (entry.tangentIn) pushed.tangentIn = entry.tangentIn;
5264
+ if (entry.tangentOut) pushed.tangentOut = entry.tangentOut;
5265
+ looped.push(pushed);
5266
+ }
4666
5267
  }
4667
- if (partialFraction > 1e-9) {
4668
- const isReversed = !!loop.alternate && fullReps % 2 === 0;
4669
- const repStart = fillStart + fullReps * segDuration;
4670
- appendRep(repStart, isReversed, partialFraction);
5268
+ if (loop.before) {
5269
+ if (partialFraction > 1e-9) {
5270
+ const isReversed = !!loop.alternate && fullReps % 2 === 0;
5271
+ appendRepTail(fillStart, isReversed, partialFraction);
5272
+ }
5273
+ for (let rep = 0; rep < fullReps; rep++) {
5274
+ const distFromBoundary = fullReps - 1 - rep;
5275
+ const isReversed = !!loop.alternate && distFromBoundary % 2 === 0;
5276
+ const repStart = fillStart + remainder + rep * segDuration;
5277
+ appendRep(repStart, isReversed);
5278
+ }
5279
+ } else {
5280
+ for (let rep = 0; rep < fullReps; rep++) {
5281
+ const isReversed = !!loop.alternate && rep % 2 === 0;
5282
+ const repStart = fillStart + rep * segDuration;
5283
+ appendRep(repStart, isReversed);
5284
+ }
5285
+ if (partialFraction > 1e-9) {
5286
+ const isReversed = !!loop.alternate && fullReps % 2 === 0;
5287
+ const repStart = fillStart + fullReps * segDuration;
5288
+ appendRep(repStart, isReversed, partialFraction);
5289
+ }
4671
5290
  }
4672
5291
  if (loop.before) {
4673
5292
  return [...looped, ...keyframes];
@@ -4984,7 +5603,6 @@ var PixodeskAnimatorReact = (() => {
4984
5603
  if (!trimPath) return node;
4985
5604
  const trimAllAsOne = !!trimPath.trimAllAsOne;
4986
5605
  const leafEntries = [];
4987
- let acc = 0;
4988
5606
  const measure = (n) => {
4989
5607
  if (Array.isArray(n.children) && n.children.length > 0) {
4990
5608
  for (const ch of n.children) measure(ch);
@@ -4996,15 +5614,22 @@ var PixodeskAnimatorReact = (() => {
4996
5614
  if (!subpaths.length) return;
4997
5615
  const entry = { leaf: n, subpaths: [] };
4998
5616
  for (const sp of subpaths) {
4999
- if (!trimAllAsOne) acc = 0;
5000
5617
  const lengthPx = pxBezierPathLength(sp);
5001
- entry.subpaths.push({ subpath: sp, lengthPx, startOffsetPx: acc });
5002
- acc += lengthPx;
5618
+ entry.subpaths.push({ subpath: sp, lengthPx, startOffsetPx: 0 });
5003
5619
  }
5004
5620
  leafEntries.push(entry);
5005
5621
  };
5006
5622
  measure(node);
5007
5623
  if (!leafEntries.length) return node;
5624
+ let acc = 0;
5625
+ const iterOrder = trimAllAsOne ? [...leafEntries].reverse() : leafEntries;
5626
+ for (const entry of iterOrder) {
5627
+ for (const sp of entry.subpaths) {
5628
+ if (!trimAllAsOne) acc = 0;
5629
+ sp.startOffsetPx = acc;
5630
+ acc += sp.lengthPx;
5631
+ }
5632
+ }
5008
5633
  const chainLengthPx = acc;
5009
5634
  if (trimAllAsOne && chainLengthPx < 1e-3) return node;
5010
5635
  const offsetReadRaw = readAnimatable(trimPath.offset);
@@ -5131,10 +5756,12 @@ var PixodeskAnimatorReact = (() => {
5131
5756
  value: map((_c = kf.value) != null ? _c : kf.v),
5132
5757
  easing: (_d = kf.easing) != null ? _d : kf.e
5133
5758
  };
5134
- })
5759
+ }),
5760
+ loop: read.loop
5135
5761
  };
5136
5762
  }
5137
5763
  function applyAttr(node, attrName, attr) {
5764
+ var _a, _b;
5138
5765
  if (!attr) return;
5139
5766
  if (attr.kind === "static") {
5140
5767
  node[attrName] = attr.value;
@@ -5142,9 +5769,16 @@ var PixodeskAnimatorReact = (() => {
5142
5769
  }
5143
5770
  const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
5144
5771
  const animate = __spreadValues({}, prevAnimate || {});
5145
- animate[attrName] = { keyframes: attr.keyframes };
5772
+ const block = { keyframes: attr.keyframes };
5773
+ if (attr.loop !== void 0) block.loop = attr.loop;
5774
+ animate[attrName] = block;
5146
5775
  node.animate = animate;
5776
+ const firstKf = attr.keyframes[0];
5777
+ if (firstKf && ((_a = firstKf.value) != null ? _a : firstKf.v) !== void 0) {
5778
+ node[attrName] = (_b = firstKf.value) != null ? _b : firstKf.v;
5779
+ }
5147
5780
  }
5781
+ var OPACITY_STEP_MS = 10;
5148
5782
  function computeOpacityFromRange(rangeRead) {
5149
5783
  var _a, _b, _c, _d, _e, _f;
5150
5784
  const hide = (v) => v[0] === v[1];
@@ -5170,9 +5804,9 @@ var PixodeskAnimatorReact = (() => {
5170
5804
  const nextHide = nextKf ? thisHide && hide((_f = nextKf.value) != null ? _f : nextKf.v) : thisHide;
5171
5805
  if (prevHide && !nextHide) {
5172
5806
  out.push({ time: t, value: 0 });
5173
- out.push({ time: t + 1, value: 1 });
5807
+ out.push({ time: t + OPACITY_STEP_MS, value: 1 });
5174
5808
  } else if (!prevHide && nextHide) {
5175
- out.push({ time: t - 1, value: 1 });
5809
+ out.push({ time: t - OPACITY_STEP_MS, value: 1 });
5176
5810
  out.push({ time: t, value: 0 });
5177
5811
  }
5178
5812
  }
@@ -5303,6 +5937,7 @@ var PixodeskAnimatorReact = (() => {
5303
5937
  return "M" + (x + w) + "," + y + "L" + (x + w) + "," + (y + h) + "L" + x + "," + (y + h) + "L" + x + "," + y + "L" + (x + w) + "," + y + "z";
5304
5938
  }
5305
5939
  function applyPlayerEffects(root) {
5940
+ var _a, _b;
5306
5941
  const ctx = {
5307
5942
  defs: [],
5308
5943
  warnings: [],
@@ -5310,7 +5945,11 @@ var PixodeskAnimatorReact = (() => {
5310
5945
  idMap: /* @__PURE__ */ new Map(),
5311
5946
  nextId: 0,
5312
5947
  contentRefInnerIds: /* @__PURE__ */ new Map(),
5313
- maskAncestorChains: /* @__PURE__ */ new Map()
5948
+ maskAncestorChains: /* @__PURE__ */ new Map(),
5949
+ // Resolved engine: `frames` ONLY when explicitly set; auto/webapi/unset →
5950
+ // webapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
5951
+ engine: ((_a = getAnimatorConfig(root)) == null ? void 0 : _a.mode) === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.webapi,
5952
+ glyphs: (_b = getDefs(root)) == null ? void 0 : _b.glyphs
5314
5953
  };
5315
5954
  const working = clone(root);
5316
5955
  indexById(working, ctx.idMap);
@@ -5322,27 +5961,46 @@ var PixodeskAnimatorReact = (() => {
5322
5961
  return { root: out, defs: ctx.defs, warnings: ctx.warnings, errors: ctx.errors };
5323
5962
  }
5324
5963
  function applyPlayerEffects_exceptRetime(node, ctx) {
5964
+ var _a;
5325
5965
  if (node.children) node.children = node.children.map((child) => applyPlayerEffects_exceptRetime(child, ctx));
5326
5966
  const fx = node.effects;
5327
5967
  const originalId = typeof node.id === "string" ? node.id : void 0;
5328
5968
  const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
5329
5969
  if (!fx && !innerIdForContentRef) return node;
5330
- const { transformation, repeater, maskedBy, trimPath, retime, ref, fillGradient, strokeGradient, textAlongPath } = fx != null ? fx : {};
5970
+ const { transformation, repeater, maskedBy, trimPath, clone: cloneFx, fillGradient, strokeGradient, textAlongPath, text } = fx != null ? fx : {};
5331
5971
  const isCombinedShape = fx == null ? void 0 : fx.isCombinedShape;
5332
5972
  if (fx) delete node.effects;
5333
5973
  let n = node;
5334
- n = applyTextAlongPathEffect(n, textAlongPath, ctx);
5974
+ let consumedByGlyphs = false;
5975
+ if (text == null ? void 0 : text.useGlyphs) {
5976
+ if (textAlongPath) {
5977
+ const pathNode = typeof textAlongPath.href === "string" ? ctx.idMap.get(textAlongPath.href) : void 0;
5978
+ const pathD = pathNode && typeof pathNode.d === "string" ? pathNode.d : void 0;
5979
+ const rawTL = textAlongPath.textLength;
5980
+ const textLength = typeof rawTL === "number" ? rawTL : rawTL && typeof rawTL === "object" ? typeof rawTL.value === "number" ? rawTL.value : Array.isArray(rawTL.keyframes) && rawTL.keyframes.length ? Number((_a = rawTL.keyframes[0]) == null ? void 0 : _a.value) : void 0 : void 0;
5981
+ const glyphed = applyTextGlyphsAlongPath(n, ctx, pathD, textAlongPath.startOffset, textLength);
5982
+ if (glyphed) {
5983
+ n = glyphed;
5984
+ consumedByGlyphs = true;
5985
+ }
5986
+ } else {
5987
+ n = applyTextGlyphsEffect(n, text, ctx);
5988
+ consumedByGlyphs = true;
5989
+ }
5990
+ }
5991
+ if (!consumedByGlyphs) n = applyTextAlongPathEffect(n, textAlongPath, ctx);
5335
5992
  n = applyFillGradientEffect(n, fillGradient, ctx);
5336
5993
  n = applyStrokeGradientEffect(n, strokeGradient, ctx);
5337
5994
  n = applyTrimPathEffect(n, trimPath, isCombinedShape, ctx);
5338
5995
  n = applyRepeaterEffect(n, repeater, ctx);
5339
5996
  n = applyMaskedByEffect(n, maskedBy, transformation, ctx);
5340
5997
  if (innerIdForContentRef) {
5998
+ applyRefHref(n, cloneFx, ctx);
5341
5999
  n = splitForContentRef(n, transformation, originalId, innerIdForContentRef, ctx);
5342
6000
  } else {
5343
- n = applyRefAndTransformationEffect(n, ref, transformation, ctx);
6001
+ n = applyRefAndTransformationEffect(n, cloneFx, transformation, ctx);
5344
6002
  }
5345
- if (retime) node.effects = { retime };
6003
+ if (cloneFx == null ? void 0 : cloneFx.retime) node.effects = { clone: { retime: cloneFx.retime } };
5346
6004
  if (originalId) ctx.idMap.set(originalId, n);
5347
6005
  return n;
5348
6006
  }
@@ -5357,13 +6015,30 @@ var PixodeskAnimatorReact = (() => {
5357
6015
  if (animatedIds.size === 0) return root;
5358
6016
  let idCounter = 0;
5359
6017
  const genId3 = () => "_lw_use_mat_" + ++idCounter;
6018
+ const rootViewport = readRootViewport(root);
5360
6019
  const defsCollector = [];
5361
- const walked = walkAndMaterialise2(root, idMap, animatedIds, genId3, defsCollector);
6020
+ const walked = walkAndMaterialise2(root, idMap, animatedIds, genId3, defsCollector, rootViewport);
5362
6021
  if (defsCollector.length === 0) return walked;
5363
6022
  const defsNode = { type: "defs", children: defsCollector };
5364
6023
  const newChildren = [...(_a = walked.children) != null ? _a : [], defsNode];
5365
6024
  return __spreadProps(__spreadValues({}, walked), { children: newChildren });
5366
6025
  }
6026
+ function readRootViewport(root) {
6027
+ const vb = parseViewBox(root.viewBox);
6028
+ if (vb) return [vb[2], vb[3]];
6029
+ const w = numericAttr(root.width);
6030
+ const h = numericAttr(root.height);
6031
+ if (w !== void 0 && h !== void 0) return [w, h];
6032
+ return [1, 1];
6033
+ }
6034
+ function numericAttr(v) {
6035
+ if (typeof v === "number") return v;
6036
+ if (typeof v === "string") {
6037
+ const n = parseFloat(v);
6038
+ return Number.isFinite(n) ? n : void 0;
6039
+ }
6040
+ return void 0;
6041
+ }
5367
6042
  function buildIdMap(root) {
5368
6043
  const map = /* @__PURE__ */ new Map();
5369
6044
  const visit = (n) => {
@@ -5415,16 +6090,22 @@ var PixodeskAnimatorReact = (() => {
5415
6090
  if (typeof href !== "string") return void 0;
5416
6091
  return href.startsWith("#") ? href.slice(1) : href;
5417
6092
  }
5418
- function materialiseOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector) {
6093
+ function materialiseOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector, rootViewport) {
6094
+ var _a, _b, _c, _d;
5419
6095
  const clone2 = deepClonePxNode(target);
5420
6096
  regenerateIdsAndRewriteRefs(clone2, genId3);
5421
- const rewrittenClone = clone2.type === "symbol" ? rewriteSymbolRootToGroup(clone2, genId3, defsCollector) : clone2;
5422
- const materialisedClone = walkAndMaterialise2(rewrittenClone, idMap, animatedIds, genId3, defsCollector);
6097
+ const symbolViewBox = clone2.type === "symbol" ? parseViewBox(clone2.viewBox) : void 0;
6098
+ const useW = (_b = (_a = numericAttr(useNode.width)) != null ? _a : symbolViewBox == null ? void 0 : symbolViewBox[2]) != null ? _b : rootViewport[0];
6099
+ const useH = (_d = (_c = numericAttr(useNode.height)) != null ? _c : symbolViewBox == null ? void 0 : symbolViewBox[3]) != null ? _d : rootViewport[1];
6100
+ const rewrittenClone = clone2.type === "symbol" ? rewriteSymbolRootToGroup(clone2, genId3, defsCollector, useW, useH) : clone2;
6101
+ const materialisedClone = walkAndMaterialise2(rewrittenClone, idMap, animatedIds, genId3, defsCollector, rootViewport);
5423
6102
  const newNode = __spreadProps(__spreadValues({}, useNode), { type: "g", children: [materialisedClone] });
5424
6103
  delete newNode.href;
6104
+ delete newNode.width;
6105
+ delete newNode.height;
5425
6106
  return applyUseOffsetToG(newNode);
5426
6107
  }
5427
- function rewriteSymbolRootToGroup(symbolNode, genId3, defsCollector) {
6108
+ function rewriteSymbolRootToGroup(symbolNode, genId3, defsCollector, useW, useH) {
5428
6109
  const viewBox = parseViewBox(symbolNode.viewBox);
5429
6110
  const g = __spreadProps(__spreadValues({}, symbolNode), { type: "g" });
5430
6111
  delete g.viewBox;
@@ -5433,9 +6114,14 @@ var PixodeskAnimatorReact = (() => {
5433
6114
  delete g.height;
5434
6115
  if (!viewBox) return g;
5435
6116
  const [vbX, vbY, vbW, vbH] = viewBox;
5436
- if (vbX !== 0 || vbY !== 0) {
5437
- g.transform = "translate(" + -vbX + "," + -vbY + ")";
5438
- }
6117
+ const scale = vbW > 0 && vbH > 0 ? Math.min(useW / vbW, useH / vbH) : 1;
6118
+ const xOff = (useW - vbW * scale) / 2;
6119
+ const yOff = (useH - vbH * scale) / 2;
6120
+ const parts = [];
6121
+ if (xOff !== 0 || yOff !== 0) parts.push("translate(" + xOff + "," + yOff + ")");
6122
+ if (scale !== 1) parts.push("scale(" + scale + ")");
6123
+ if (vbX !== 0 || vbY !== 0) parts.push("translate(" + -vbX + "," + -vbY + ")");
6124
+ if (parts.length) g.transform = parts.join("");
5439
6125
  const clipId = genId3();
5440
6126
  defsCollector.push({
5441
6127
  type: "clipPath",
@@ -5451,18 +6137,18 @@ var PixodeskAnimatorReact = (() => {
5451
6137
  if (parts.length < 4 || parts.some((n) => !Number.isFinite(n))) return void 0;
5452
6138
  return [parts[0], parts[1], parts[2], parts[3]];
5453
6139
  }
5454
- function walkAndMaterialise2(node, idMap, animatedIds, genId3, defsCollector) {
6140
+ function walkAndMaterialise2(node, idMap, animatedIds, genId3, defsCollector, rootViewport) {
5455
6141
  if (node.type === "use" && typeof node.href === "string") {
5456
6142
  const targetId = stripHash2(node.href);
5457
6143
  if (targetId && animatedIds.has(targetId)) {
5458
6144
  const target = idMap.get(targetId);
5459
- if (target) return materialiseOneUse(node, target, idMap, animatedIds, genId3, defsCollector);
6145
+ if (target) return materialiseOneUse(node, target, idMap, animatedIds, genId3, defsCollector, rootViewport);
5460
6146
  }
5461
6147
  }
5462
6148
  if (!node.children) return node;
5463
6149
  let changed = false;
5464
6150
  const newChildren = node.children.map((ch) => {
5465
- const m = walkAndMaterialise2(ch, idMap, animatedIds, genId3, defsCollector);
6151
+ const m = walkAndMaterialise2(ch, idMap, animatedIds, genId3, defsCollector, rootViewport);
5466
6152
  if (m !== ch) changed = true;
5467
6153
  return m;
5468
6154
  });
@@ -5476,6 +6162,36 @@ var PixodeskAnimatorReact = (() => {
5476
6162
  if (engine === PxAnimatorEngine.webapi) {
5477
6163
  root = materialiseMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
5478
6164
  root = materialiseAnimatedUseInstances(root);
6165
+ root = pruneUnreferencedDefs(root);
6166
+ }
6167
+ return root;
6168
+ }
6169
+ function pruneUnreferencedDefs(root) {
6170
+ const stripHash3 = (h) => h.startsWith("#") ? h.slice(1) : h;
6171
+ const walk = (n, fn) => {
6172
+ var _a;
6173
+ fn(n);
6174
+ (_a = n.children) == null ? void 0 : _a.forEach((c) => walk(c, fn));
6175
+ };
6176
+ let changed = true;
6177
+ while (changed) {
6178
+ changed = false;
6179
+ const referenced = /* @__PURE__ */ new Set();
6180
+ walk(root, (n) => {
6181
+ if (n.type === "use" && typeof n.href === "string") referenced.add(stripHash3(n.href));
6182
+ });
6183
+ walk(root, (n) => {
6184
+ if (!n.children) return;
6185
+ let kept = n.children;
6186
+ if (n.type === "defs") {
6187
+ kept = kept.filter((c) => !((c.type === "g" || c.type === "symbol") && typeof c.id === "string" && !referenced.has(c.id)));
6188
+ }
6189
+ kept = kept.filter((c) => !(c.type === "defs" && (!c.children || c.children.length === 0)));
6190
+ if (kept.length !== n.children.length) {
6191
+ n.children = kept;
6192
+ changed = true;
6193
+ }
6194
+ });
5479
6195
  }
5480
6196
  return root;
5481
6197
  }
@@ -5506,6 +6222,13 @@ var PixodeskAnimatorReact = (() => {
5506
6222
  ]);
5507
6223
  var IMAGE_REF_ATTRS_LOWER = /* @__PURE__ */ new Set(["href", "xlink:href", "src"]);
5508
6224
  var DATA_RASTER_IMAGE_RE = /^data:image\/(?:png|jpe?g|gif|webp|bmp);base64,/i;
6225
+ var DATA_SVG_IMAGE_RE = /^data:image\/svg\+xml(?:;[^,]*)?,/i;
6226
+ var DATA_IMAGE_BASE64_PAYLOAD_RE = /^data:image\/[^;,]*;base64,([A-Za-z0-9+/]{8})/i;
6227
+ var BASE64_RASTER_MAGICS = ["iVBORw0K", "/9j/", "R0lGOD", "UklGR", "Qk"];
6228
+ function isContentSniffedRasterImage(str2) {
6229
+ const m = DATA_IMAGE_BASE64_PAYLOAD_RE.exec(str2);
6230
+ return !!m && BASE64_RASTER_MAGICS.some((magic) => m[1].startsWith(magic));
6231
+ }
5509
6232
  function isDangerousAttrName(nameLower) {
5510
6233
  if (nameLower.startsWith("on")) return true;
5511
6234
  return false;
@@ -5517,19 +6240,19 @@ var PixodeskAnimatorReact = (() => {
5517
6240
  return void 0;
5518
6241
  }
5519
6242
  if (nameLower === "fill" || nameLower === "stroke" || nameLower === "stopcolor") {
5520
- const str = String(value);
5521
- if (str.includes("url(") && !/^url\(#[^)]+\)$/.test(str)) {
6243
+ const str2 = String(value);
6244
+ if (str2.includes("url(") && !/^url\(#[^)]+\)$/.test(str2)) {
5522
6245
  console.warn('Attribute "' + nameLower + '" blocked: url() must be internal url(#id), got:', value);
5523
6246
  return void 0;
5524
6247
  }
5525
6248
  return value;
5526
6249
  }
5527
6250
  if (URL_VALUE_ATTRS_LOWER.has(nameLower)) {
5528
- const str = String(value);
5529
- if (str.startsWith("#")) return value;
5530
- if (/^url\(#[^)]+\)$/.test(str)) return value;
5531
- if (IMAGE_REF_ATTRS_LOWER.has(nameLower) && DATA_RASTER_IMAGE_RE.test(str)) return value;
5532
- console.warn('Attribute "' + nameLower + '" blocked: must be #id, url(#id), or base64 raster data: URI, got:', value);
6251
+ const str2 = String(value);
6252
+ if (str2.startsWith("#")) return value;
6253
+ if (/^url\(#[^)]+\)$/.test(str2)) return value;
6254
+ if (IMAGE_REF_ATTRS_LOWER.has(nameLower) && (DATA_RASTER_IMAGE_RE.test(str2) || DATA_SVG_IMAGE_RE.test(str2) || isContentSniffedRasterImage(str2))) return value;
6255
+ console.warn('Attribute "' + nameLower + '" blocked: must be #id, url(#id), or data:image/\u2026 URI, got:', value);
5533
6256
  return void 0;
5534
6257
  }
5535
6258
  return value;
@@ -5558,7 +6281,7 @@ var PixodeskAnimatorReact = (() => {
5558
6281
  if (textContent) element.textContent = textContent;
5559
6282
  return element;
5560
6283
  }
5561
- function resolveStyle(style, defs) {
6284
+ function resolveStyle2(style, defs) {
5562
6285
  var _a;
5563
6286
  if (!style) return void 0;
5564
6287
  if (typeof style === "string") {
@@ -5594,7 +6317,7 @@ var PixodeskAnimatorReact = (() => {
5594
6317
  if (!node) return null;
5595
6318
  const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
5596
6319
  const nodeDefs = getDefs(node) || defs;
5597
- const resolvedStyle = resolveStyle(style, nodeDefs);
6320
+ const resolvedStyle = resolveStyle2(style, nodeDefs);
5598
6321
  let childElements;
5599
6322
  if (children) {
5600
6323
  for (const ch of children) {