@pixodesk/svg-animator-react 1.0.22 → 1.0.26

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
@@ -1936,8 +1936,9 @@ var PixodeskAnimatorReact = (() => {
1936
1936
  }
1937
1937
  isValid(raw, ctx, path) {
1938
1938
  var _a;
1939
- if (this.schemas.some((s) => s.isValid(raw))) return true;
1940
- ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": no union member matched for value " + ((_a = JSON.stringify(raw)) != null ? _a : "").slice(0, 60));
1939
+ const probe = ctx && { errors: [], warnings: [], strict: ctx.strict };
1940
+ if (this.schemas.some((s) => s.isValid(raw, probe, path ? [...path] : void 0))) return true;
1941
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": no union member matched for value " + ((_a = JSON.stringify(raw)) != null ? _a : "").slice(0, 240));
1941
1942
  return false;
1942
1943
  }
1943
1944
  _canSanitize(raw) {
@@ -2013,6 +2014,7 @@ var PixodeskAnimatorReact = (() => {
2013
2014
  if (ctx == null ? void 0 : ctx.strict) {
2014
2015
  for (const key of Object.keys(obj)) {
2015
2016
  if (key in this._shape) continue;
2017
+ if (obj[key] === void 0) continue;
2016
2018
  p.push(key);
2017
2019
  ctx.errors.push(pathStr(p) + ": unexpected extra key");
2018
2020
  p.pop();
@@ -2153,6 +2155,23 @@ var PixodeskAnimatorReact = (() => {
2153
2155
  return true;
2154
2156
  }
2155
2157
  };
2158
+ var Defined = class extends Base {
2159
+ constructor() {
2160
+ super(...arguments);
2161
+ this._default = void 0;
2162
+ }
2163
+ sanitize(raw) {
2164
+ return raw;
2165
+ }
2166
+ isValid(raw, ctx, path) {
2167
+ if (raw !== void 0) return true;
2168
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": required value is missing");
2169
+ return false;
2170
+ }
2171
+ _canSanitize(raw) {
2172
+ return raw !== void 0;
2173
+ }
2174
+ };
2156
2175
  var Lazy = class extends Base {
2157
2176
  constructor(fn, _default) {
2158
2177
  super();
@@ -2250,6 +2269,8 @@ var PixodeskAnimatorReact = (() => {
2250
2269
  record: (value) => new Rec(value),
2251
2270
  /** Passes anything through unchanged — always valid. */
2252
2271
  any: () => new Any(),
2272
+ /** Anything EXCEPT `undefined` — an open type whose presence is required (V6). */
2273
+ defined: () => new Defined(),
2253
2274
  /** Fixed-length tuple — validates element count and each position individually. */
2254
2275
  tuple: (schemas) => new Tuple(schemas),
2255
2276
  /** Defers schema creation — required for recursive types. Must supply a default value. */
@@ -2259,13 +2280,52 @@ var PixodeskAnimatorReact = (() => {
2259
2280
  var PX_ANIM_ATTR_NAME = "_px_animator";
2260
2281
  var PxAnimatorMode = {
2261
2282
  auto: "auto",
2262
- webapi: "webapi",
2283
+ waapi: "waapi",
2263
2284
  frames: "frames"
2264
2285
  };
2265
2286
  var PxAnimatorEngine = {
2266
- webapi: PxAnimatorMode.webapi,
2287
+ waapi: PxAnimatorMode.waapi,
2267
2288
  frames: PxAnimatorMode.frames
2268
2289
  };
2290
+ var PxLoopExtend = {
2291
+ /** Segment from the START; the animation is extended BEFORE the first keyframe
2292
+ * (intro loops that run before the main timeline begins). */
2293
+ before: "before",
2294
+ /** DEFAULT — segment from the END; extended AFTER the last keyframe (idle/outro
2295
+ * loops that continue once the main timeline has finished). */
2296
+ after: "after"
2297
+ };
2298
+ var PxMaskType = {
2299
+ luminance: "luminance",
2300
+ alpha: "alpha"
2301
+ };
2302
+ var PxUnits = {
2303
+ userSpaceOnUse: "userSpaceOnUse",
2304
+ objectBoundingBox: "objectBoundingBox"
2305
+ };
2306
+ var PxCloneType = {
2307
+ content: "content"
2308
+ };
2309
+ var PxPathOverflow = {
2310
+ clip: "clip",
2311
+ extend: "extend"
2312
+ };
2313
+ var PxLengthAdjust = {
2314
+ spacing: "spacing",
2315
+ spacingAndGlyphs: "spacingAndGlyphs"
2316
+ };
2317
+ var PxTextPathMethod = {
2318
+ align: "align",
2319
+ stretch: "stretch"
2320
+ };
2321
+ var PxTextPathSpacing = {
2322
+ auto: "auto",
2323
+ exact: "exact"
2324
+ };
2325
+ var PxTrimSubPaths = {
2326
+ separate: "separate",
2327
+ combined: "combined"
2328
+ };
2269
2329
  var TEXT_ATTR = "text";
2270
2330
  var TEXT_CONTENT_ATTR = "textContent";
2271
2331
  var INTERNAL_ATTRS = /* @__PURE__ */ new Set([
@@ -2274,9 +2334,45 @@ var PixodeskAnimatorReact = (() => {
2274
2334
  "animator",
2275
2335
  "meta",
2276
2336
  "animate",
2337
+ "effects",
2277
2338
  TEXT_ATTR,
2278
2339
  TEXT_CONTENT_ATTR
2279
2340
  ]);
2341
+ var PxGradientUnits = {
2342
+ userSpaceOnUse: "userSpaceOnUse",
2343
+ objectBoundingBox: "objectBoundingBox"
2344
+ };
2345
+ var PxGradientSpreadMethod = {
2346
+ pad: "pad",
2347
+ reflect: "reflect",
2348
+ repeat: "repeat"
2349
+ };
2350
+ var PxGradientType = {
2351
+ linear: "linear",
2352
+ radial: "radial"
2353
+ };
2354
+ function isPxElementFileFormat(fileJson) {
2355
+ if (!(fileJson && typeof fileJson === "object" && !Array.isArray(fileJson))) {
2356
+ return false;
2357
+ }
2358
+ return fileJson["type"] === "svg";
2359
+ }
2360
+ function getAnimatorConfig(doc) {
2361
+ var _a;
2362
+ return (doc == null ? void 0 : doc.animator) || ((_a = doc == null ? void 0 : doc.meta) == null ? void 0 : _a.animator);
2363
+ }
2364
+ function getDefs(doc) {
2365
+ var _a;
2366
+ if (!doc) return void 0;
2367
+ return (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.definitions;
2368
+ }
2369
+ function getBindings(doc) {
2370
+ var _a;
2371
+ if (!doc) return void 0;
2372
+ const animateById = (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.animateById;
2373
+ if (!animateById) return void 0;
2374
+ return Object.entries(animateById).map(([id, anim]) => ({ id, animate: anim }));
2375
+ }
2280
2376
  var PxEasingOrRefSchema = px.union([
2281
2377
  px.string(),
2282
2378
  px.tuple([px.number(), px.number(), px.number(), px.number()])
@@ -2288,13 +2384,15 @@ var PixodeskAnimatorReact = (() => {
2288
2384
  px.array(px.number()),
2289
2385
  px.lazy(() => PxTransformPartsSchema, {}),
2290
2386
  px.object({ path: px.string() }),
2291
- px.lazy(() => px.object({ paths: px.array(PxBezierPathSchema) }), { paths: [] })
2387
+ px.lazy(() => px.object({ paths: px.array(PxBezierPathSchema) }), { paths: [] }),
2388
+ // Gradient `stops` timeline — each kf value is the full stops-array snapshot.
2389
+ px.lazy(() => px.array(PxGradientStopSchema), [])
2292
2390
  ]));
2293
2391
  var PxKeyframeSchema = implementsInterface()(px.object({
2294
2392
  time: px.number().optional(),
2295
2393
  t: px.number().optional(),
2296
- value: px.any().optional(),
2297
- v: px.any().optional(),
2394
+ value: PxKeyframeValueSchema.optional(),
2395
+ v: PxKeyframeValueSchema.optional(),
2298
2396
  easing: PxEasingOrRefSchema.optional(),
2299
2397
  e: PxEasingOrRefSchema.optional(),
2300
2398
  tangentOut: px.tuple([px.number(), px.number()]).optional(),
@@ -2308,10 +2406,11 @@ var PixodeskAnimatorReact = (() => {
2308
2406
  }));
2309
2407
  var PxLoopSchema = implementsInterface()(px.object({
2310
2408
  segmentCount: px.number().optional(),
2311
- before: px.boolean().optional(),
2409
+ extend: px.enum([PxLoopExtend.before, PxLoopExtend.after]).optional(),
2312
2410
  alternate: px.boolean().optional()
2313
2411
  }));
2314
2412
  var PxPropertyAnimationSchema = implementsInterface()(px.object({
2413
+ value: PxKeyframeValueSchema.optional(),
2315
2414
  keyframes: px.array(PxKeyframeSchema).optional(),
2316
2415
  kfs: px.array(PxKeyframeSchema).optional(),
2317
2416
  loop: px.union([PxLoopSchema, px.boolean()]).optional(),
@@ -2326,6 +2425,7 @@ var PixodeskAnimatorReact = (() => {
2326
2425
  }));
2327
2426
  var PxTransformValueSchema = px.union([
2328
2427
  px.string(),
2428
+ PxTransformPartsSchema,
2329
2429
  px.object({ value: PxTransformPartsSchema }),
2330
2430
  PxPropertyAnimationSchema
2331
2431
  ]);
@@ -2360,9 +2460,11 @@ var PixodeskAnimatorReact = (() => {
2360
2460
  glyphs: px.record(PxGlyphFontSchema).optional()
2361
2461
  }));
2362
2462
  var PxAnimatorConfigSchema = implementsInterface()(px.object({
2363
- mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.webapi, PxAnimatorMode.frames]).optional(),
2463
+ mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.waapi, PxAnimatorMode.frames]).optional(),
2364
2464
  duration: px.number().optional(),
2365
2465
  delay: px.number().optional(),
2466
+ // LAW (SCHEMA-DESIGN R3, S10): the ONE sanctioned string-in-number union
2467
+ // (CSS animation-iteration-count familiarity) — do not add more mixed unions.
2366
2468
  iterations: px.union([px.number(), px.literal("infinite")]).optional(),
2367
2469
  fill: px.enum(["forwards", "backwards", "both", "none"]).optional(),
2368
2470
  direction: px.enum(["normal", "reverse", "alternate", "alternate-reverse"]).optional(),
@@ -2370,9 +2472,8 @@ var PixodeskAnimatorReact = (() => {
2370
2472
  trigger: PxTriggerSchema.optional(),
2371
2473
  resetOnFinish: px.boolean().optional(),
2372
2474
  definitions: PxDefsSchema.optional(),
2373
- animate: px.record(PxElementAnimationSchema).optional(),
2374
- timeline: px.string().optional(),
2375
- debug: px.boolean().optional(),
2475
+ animateById: px.record(PxElementAnimationSchema).optional(),
2476
+ timelineSource: px.string().optional(),
2376
2477
  debugInstName: px.string().optional()
2377
2478
  }));
2378
2479
  var PxBindingSchema = implementsInterface()(px.object({
@@ -2382,26 +2483,29 @@ var PixodeskAnimatorReact = (() => {
2382
2483
  var PxAttrValueSchema = px.union([
2383
2484
  px.string(),
2384
2485
  px.number(),
2385
- px.object({ value: px.any() }),
2386
- PxPropertyAnimationSchema
2486
+ px.array(px.number()),
2487
+ // Structured static — `{value: …}` (read-accepted transitional spelling, S1).
2488
+ // `defined`, not `any`: the KEY's presence is what identifies this branch (V6).
2489
+ px.object({ value: px.defined() }),
2490
+ // Bare transform parts record — the canonical static `transform` on the wire (T2).
2491
+ PxTransformPartsSchema
2387
2492
  ]);
2388
2493
  var PxAnimatableNumberSchema = px.union([
2389
2494
  px.number(),
2390
2495
  px.object({ value: px.number() }),
2391
- px.object({
2392
- keyframes: px.array(PxKeyframeSchema),
2393
- autoOrient: px.boolean().optional()
2394
- })
2496
+ PxPropertyAnimationSchema
2395
2497
  ]);
2396
2498
  var PxAnimatableVec2Schema = px.union([
2397
2499
  px.tuple([px.number(), px.number()]),
2398
2500
  px.object({ value: px.tuple([px.number(), px.number()]) }),
2399
- px.object({
2400
- keyframes: px.array(PxKeyframeSchema),
2401
- autoOrient: px.boolean().optional()
2402
- })
2501
+ PxPropertyAnimationSchema
2502
+ ]);
2503
+ var PxAnimatableStringSchema = px.union([
2504
+ px.string(),
2505
+ px.object({ value: px.string() }),
2506
+ PxPropertyAnimationSchema
2403
2507
  ]);
2404
- var PxTransformationEffectSchema = implementsInterface()(px.object({
2508
+ var PxTransformByEffectSchema = implementsInterface()(px.object({
2405
2509
  translate: PxAnimatableVec2Schema.optional(),
2406
2510
  rotate: PxAnimatableNumberSchema.optional(),
2407
2511
  scale: PxAnimatableVec2Schema.optional(),
@@ -2409,42 +2513,46 @@ var PixodeskAnimatorReact = (() => {
2409
2513
  origin: PxAnimatableVec2Schema.optional()
2410
2514
  }));
2411
2515
  var PxRepeaterEffectSchema = implementsInterface()(px.object({
2516
+ // STATIC config, not a channel (V2/SCHEMA-DESIGN R5): the copy COUNT is read
2517
+ // once at expansion time and never sampled — plain number, no `keyframes`.
2412
2518
  copies: px.number().optional(),
2413
2519
  translate: PxAnimatableVec2Schema.optional(),
2414
2520
  rotate: PxAnimatableNumberSchema.optional(),
2521
+ skew: PxAnimatableNumberSchema.optional(),
2415
2522
  scale: PxAnimatableVec2Schema.optional(),
2416
2523
  origin: PxAnimatableVec2Schema.optional()
2417
2524
  }));
2418
2525
  var PxMaskedByEffectSchema = implementsInterface()(px.object({
2419
- href: px.string().optional(),
2420
- maskType: px.string().optional(),
2421
- maskUnits: px.string().optional(),
2422
- maskContentUnits: px.string().optional()
2526
+ sourceId: px.string().optional(),
2527
+ maskType: px.enum([PxMaskType.luminance, PxMaskType.alpha]).optional(),
2528
+ maskUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
2529
+ maskContentUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
2530
+ x: px.number().optional(),
2531
+ y: px.number().optional(),
2532
+ width: px.number().optional(),
2533
+ height: px.number().optional()
2423
2534
  }));
2424
2535
  var PxClipPathEffectSchema = implementsInterface()(px.object({
2425
- d: px.string().optional(),
2536
+ d: PxAnimatableStringSchema.optional(),
2426
2537
  animate: PxPropertyAnimationSchema.optional()
2427
2538
  }));
2428
2539
  var PxTrimPathEffectSchema = implementsInterface()(px.object({
2429
2540
  offset: PxAnimatableNumberSchema.optional(),
2430
2541
  range: PxAnimatableVec2Schema.optional(),
2431
- trimAllAsOne: px.boolean().optional()
2542
+ subPaths: px.enum([PxTrimSubPaths.separate, PxTrimSubPaths.combined]).optional()
2432
2543
  }));
2433
2544
  var PxRetimeEffectSchema = implementsInterface()(px.object({
2434
- baseId: px.string().optional(),
2545
+ sourceId: px.string().optional(),
2435
2546
  start: px.number().optional(),
2436
2547
  stretch: px.number().optional(),
2437
2548
  timeCrop: px.tuple([px.number(), px.number()]).optional()
2438
2549
  }));
2439
2550
  var PxCloneEffectSchema = implementsInterface()(px.object({
2440
- type: px.string().optional(),
2441
- baseId: px.string().optional(),
2551
+ // Contextual kind — the `type` convention, see `PxNodeBase.type`.
2552
+ type: px.enum([PxCloneType.content]).optional(),
2553
+ sourceId: px.string().optional(),
2442
2554
  retime: PxRetimeEffectSchema.optional()
2443
2555
  }));
2444
- var PxGradientType = {
2445
- linear: "linear",
2446
- radial: "radial"
2447
- };
2448
2556
  var PxGradientStopSchema = implementsInterface()(px.object({
2449
2557
  offset: px.number(),
2450
2558
  color: px.string()
@@ -2452,39 +2560,28 @@ var PixodeskAnimatorReact = (() => {
2452
2560
  var PxAnimatableGradientStopsSchema = px.union([
2453
2561
  px.array(PxGradientStopSchema),
2454
2562
  px.object({ value: px.array(PxGradientStopSchema) }),
2455
- px.object({ keyframes: px.array(PxKeyframeSchema) })
2563
+ PxPropertyAnimationSchema
2456
2564
  ]);
2457
- var PxGradientGeometryAnimationSchema = implementsInterface()(px.object({
2458
- gradientX1: PxPropertyAnimationSchema.optional(),
2459
- gradientY1: PxPropertyAnimationSchema.optional(),
2460
- gradientX2: PxPropertyAnimationSchema.optional(),
2461
- gradientY2: PxPropertyAnimationSchema.optional(),
2462
- gradientCx: PxPropertyAnimationSchema.optional(),
2463
- gradientCy: PxPropertyAnimationSchema.optional(),
2464
- gradientFx: PxPropertyAnimationSchema.optional(),
2465
- gradientFy: PxPropertyAnimationSchema.optional(),
2466
- gradientR: PxPropertyAnimationSchema.optional()
2467
- }));
2468
2565
  var PxFillGradientEffectSchema = implementsInterface()(px.object({
2566
+ // Contextual kind — the `type` convention, see `PxNodeBase.type`.
2469
2567
  type: px.enum([PxGradientType.linear, PxGradientType.radial]),
2470
- p1: px.tuple([px.number(), px.number()]).optional(),
2471
- p2: px.tuple([px.number(), px.number()]).optional(),
2472
- c: px.tuple([px.number(), px.number()]).optional(),
2473
- r: px.number().optional(),
2474
- fp: px.tuple([px.number(), px.number()]).optional(),
2568
+ p1: PxAnimatableVec2Schema.optional(),
2569
+ p2: PxAnimatableVec2Schema.optional(),
2570
+ c: PxAnimatableVec2Schema.optional(),
2571
+ r: PxAnimatableNumberSchema.optional(),
2572
+ fp: PxAnimatableVec2Schema.optional(),
2475
2573
  stops: PxAnimatableGradientStopsSchema.optional(),
2476
- gradientUnits: px.string().optional(),
2477
- spreadMethod: px.string().optional(),
2478
- gradientTransform: px.string().optional(),
2479
- animate: PxGradientGeometryAnimationSchema.optional()
2574
+ gradientUnits: px.enum([PxGradientUnits.userSpaceOnUse, PxGradientUnits.objectBoundingBox]).optional(),
2575
+ spreadMethod: px.enum([PxGradientSpreadMethod.pad, PxGradientSpreadMethod.reflect, PxGradientSpreadMethod.repeat]).optional(),
2576
+ gradientTransform: px.string().optional()
2480
2577
  }));
2481
2578
  var PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;
2482
2579
  var PxTextPathEffectSchema = implementsInterface()(px.object({
2483
2580
  path: px.string(),
2484
- pathOverflow: px.string().optional(),
2485
- lengthAdjust: px.string().optional(),
2486
- method: px.string().optional(),
2487
- spacing: px.string().optional(),
2581
+ pathOverflow: px.enum([PxPathOverflow.clip, PxPathOverflow.extend]).optional(),
2582
+ lengthAdjust: px.enum([PxLengthAdjust.spacing, PxLengthAdjust.spacingAndGlyphs]).optional(),
2583
+ method: px.enum([PxTextPathMethod.align, PxTextPathMethod.stretch]).optional(),
2584
+ spacing: px.enum([PxTextPathSpacing.auto, PxTextPathSpacing.exact]).optional(),
2488
2585
  startOffset: PxAnimatableNumberSchema.optional(),
2489
2586
  textLength: PxAnimatableNumberSchema.optional()
2490
2587
  }));
@@ -2492,13 +2589,12 @@ var PixodeskAnimatorReact = (() => {
2492
2589
  useGlyphs: px.boolean().optional()
2493
2590
  }));
2494
2591
  var PxEffectsSchema = implementsInterface()(px.object({
2495
- transformation: PxTransformationEffectSchema.optional(),
2592
+ transformBy: PxTransformByEffectSchema.optional(),
2496
2593
  repeater: PxRepeaterEffectSchema.optional(),
2497
2594
  maskedBy: PxMaskedByEffectSchema.optional(),
2498
2595
  clipPath: PxClipPathEffectSchema.optional(),
2499
2596
  trimPath: PxTrimPathEffectSchema.optional(),
2500
2597
  clone: PxCloneEffectSchema.optional(),
2501
- isCombinedShape: px.boolean().optional(),
2502
2598
  fillGradient: PxFillGradientEffectSchema.optional(),
2503
2599
  strokeGradient: PxStrokeGradientEffectSchema.optional(),
2504
2600
  textPath: PxTextPathEffectSchema.optional(),
@@ -2522,6 +2618,14 @@ var PixodeskAnimatorReact = (() => {
2522
2618
  return warnings;
2523
2619
  }
2524
2620
  var PxNodeBase = px.openObject({
2621
+ // CONVENTION (SCHEMA-DESIGN R1 / issues N4): `type` is the ONE word for "what
2622
+ // kind of thing is this", discriminated by its CARRIER — here the node TAG
2623
+ // (`rect`, `text`), and inside a sub-object that object's kind (`clone.type`,
2624
+ // `fillGradient.type`, editor `preset.type`). Each sits in its own object, so
2625
+ // the carrier disambiguates completely; synonyms (`cloneKind`, `presetShape`)
2626
+ // would add words that all mean "type" and still need the carrier to read.
2627
+ // Guarding a `type` SLOT against a wrong VALUE is the job of strict enums
2628
+ // (issues V3), never of distinct key names.
2525
2629
  type: px.string(),
2526
2630
  id: px.string().optional(),
2527
2631
  meta: px.any().optional(),
@@ -2531,7 +2635,7 @@ var PixodeskAnimatorReact = (() => {
2531
2635
  effects: PxEffectsSchema.optional(),
2532
2636
  // `PxElementAnimation` (not just `PxAnimationDefinition`) — accepts
2533
2637
  // string ref / array of refs / inline definition / mixed array; mirrors
2534
- // `animator.animate` map values and what `processNode` resolves at runtime.
2638
+ // `animator.animateById` map values and what `processNode` resolves at runtime.
2535
2639
  animate: PxElementAnimationSchema.optional(),
2536
2640
  style: px.union([px.string(), px.record(px.union([px.string(), px.number()]))]).optional()
2537
2641
  }, PxAttrValueSchema);
@@ -2539,8 +2643,10 @@ var PixodeskAnimatorReact = (() => {
2539
2643
  children: px.lazy(() => px.array(PxNodeSchema), []).optional()
2540
2644
  }), PxAttrValueSchema);
2541
2645
  var PxSvgNodeExtra = px.object({
2542
- width: px.number().optional(),
2543
- height: px.number().optional(),
2646
+ // `"100%"` and other SVG length strings are legal here — a number-only slot rejected
2647
+ // real documents (e.g. apple-store-look-14-main.json) at the root <svg>.
2648
+ width: px.union([px.number(), px.string()]).optional(),
2649
+ height: px.union([px.number(), px.string()]).optional(),
2544
2650
  viewBox: px.string().optional(),
2545
2651
  animator: PxAnimatorConfigSchema.optional()
2546
2652
  });
@@ -2555,28 +2661,6 @@ var PixodeskAnimatorReact = (() => {
2555
2661
  o: px.array(px.array(px.number())).optional(),
2556
2662
  c: px.boolean().optional()
2557
2663
  }));
2558
- function isPxElementFileFormat(fileJson) {
2559
- if (!(fileJson && typeof fileJson === "object" && !Array.isArray(fileJson))) {
2560
- return false;
2561
- }
2562
- return fileJson["type"] === "svg" || fileJson["tagName"] === "svg";
2563
- }
2564
- function getAnimatorConfig(doc) {
2565
- var _a, _b;
2566
- return (doc == null ? void 0 : doc.animator) || ((_a = doc == null ? void 0 : doc.meta) == null ? void 0 : _a.animator) || (doc == null ? void 0 : doc.animation) || ((_b = doc == null ? void 0 : doc.meta) == null ? void 0 : _b.animation);
2567
- }
2568
- function getDefs(doc) {
2569
- var _a;
2570
- if (!doc) return void 0;
2571
- return (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.definitions;
2572
- }
2573
- function getBindings(doc) {
2574
- var _a;
2575
- if (!doc) return void 0;
2576
- const animate = (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.animate;
2577
- if (!animate) return void 0;
2578
- return Object.entries(animate).map(([id, anim]) => ({ id, animate: anim }));
2579
- }
2580
2664
  function bezierToSvgPath(path, forceCurves = false) {
2581
2665
  var _a, _b, _c, _d;
2582
2666
  const v = path.v;
@@ -3027,7 +3111,7 @@ var PixodeskAnimatorReact = (() => {
3027
3111
  "flood-color",
3028
3112
  "lighting-color"
3029
3113
  ]);
3030
- const directIdRefAttrs = /* @__PURE__ */ new Set(["baseId", "targetId", "boundElementId"]);
3114
+ const directIdRefAttrs = /* @__PURE__ */ new Set(["sourceId", "targetId", "boundElementId"]);
3031
3115
  function collectIds(node) {
3032
3116
  if (!node || typeof node !== "object") return;
3033
3117
  if (node.id && typeof node.id === "string") {
@@ -3065,9 +3149,10 @@ var PixodeskAnimatorReact = (() => {
3065
3149
  } else if (urlRefAttrs.has(key)) {
3066
3150
  node[key] = replaceUrlRefs(value, idMap);
3067
3151
  } else if (directIdRefAttrs.has(key)) {
3068
- const newId = idMap.get(value);
3152
+ const hasHash = value.startsWith("#");
3153
+ const newId = idMap.get(hasHash ? value.slice(1) : value);
3069
3154
  if (newId) {
3070
- node[key] = newId;
3155
+ node[key] = hasHash ? "#" + newId : newId;
3071
3156
  }
3072
3157
  } else if (value.includes("url(#")) {
3073
3158
  node[key] = replaceUrlRefs(value, idMap);
@@ -3085,14 +3170,14 @@ var PixodeskAnimatorReact = (() => {
3085
3170
  }
3086
3171
  collectIds(cloned);
3087
3172
  updateRefs(cloned);
3088
- const docAnimate = (_a = cloned.animator) == null ? void 0 : _a.animate;
3173
+ const docAnimate = (_a = cloned.animator) == null ? void 0 : _a.animateById;
3089
3174
  if (docAnimate && typeof docAnimate === "object") {
3090
3175
  const updatedAnimate = {};
3091
3176
  for (const [id, anim] of Object.entries(docAnimate)) {
3092
3177
  const newId = (_b = idMap.get(id)) != null ? _b : id;
3093
3178
  updatedAnimate[newId] = anim;
3094
3179
  }
3095
- cloned.animator = __spreadProps2(__spreadValues2({}, cloned.animator), { animate: updatedAnimate });
3180
+ cloned.animator = __spreadProps2(__spreadValues2({}, cloned.animator), { animateById: updatedAnimate });
3096
3181
  }
3097
3182
  return cloned;
3098
3183
  }
@@ -3181,8 +3266,9 @@ var PixodeskAnimatorReact = (() => {
3181
3266
  let value = props[rawKey];
3182
3267
  if (COLOUR_ATTR_NAMES.has(key) && Array.isArray(value)) {
3183
3268
  propsCopy[key] = toRGBA(value);
3184
- } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && value.value && typeof value.value === "object") {
3185
- propsCopy["transform"] = composeTransformParts(value.value, { withUnits: false });
3269
+ } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && !value.keyframes && !value.kfs) {
3270
+ const parts = value.value && typeof value.value === "object" ? value.value : value;
3271
+ propsCopy["transform"] = composeTransformParts(parts, { withUnits: false });
3186
3272
  } else if (TRANSFORM_FN_NAMES.has(key)) {
3187
3273
  if (Array.isArray(value)) {
3188
3274
  if (key === "translate") value = value.map((v) => v + "px");
@@ -3190,6 +3276,8 @@ var PixodeskAnimatorReact = (() => {
3190
3276
  }
3191
3277
  if (key === "rotate") value = value + "deg";
3192
3278
  propsCopy["transform"] = key + "(" + value + ")";
3279
+ } else if (Array.isArray(value)) {
3280
+ propsCopy[key] = value.join(",");
3193
3281
  } else if (value !== void 0 && value !== null) {
3194
3282
  propsCopy[key] = String(value);
3195
3283
  }
@@ -3587,6 +3675,16 @@ var PixodeskAnimatorReact = (() => {
3587
3675
  if (newAnimate) cloned.animate = newAnimate;
3588
3676
  return cloned;
3589
3677
  }
3678
+ var LOOP_JUMP_SHIFT_MS = 1;
3679
+ function deepEqualValue(a, b) {
3680
+ if (a === b) return true;
3681
+ if (typeof a !== typeof b || a === null || b === null || typeof a !== "object") return false;
3682
+ if (Array.isArray(a) !== Array.isArray(b)) return false;
3683
+ const ka = Object.keys(a);
3684
+ const kb = Object.keys(b);
3685
+ if (ka.length !== kb.length) return false;
3686
+ return ka.every((k) => deepEqualValue(a[k], b[k]));
3687
+ }
3590
3688
  function parsePathCommands(d) {
3591
3689
  const tokens = d.split(/([MLCZmlcz]|[\s,]+)/).map((t) => t.trim()).filter((t) => t && t !== ",");
3592
3690
  const commands = [];
@@ -3789,7 +3887,7 @@ var PixodeskAnimatorReact = (() => {
3789
3887
  const totalIntervals = keyframes.length - 1;
3790
3888
  const segCount = clamp((_a = loop.segmentCount) != null ? _a : totalIntervals, 1, totalIntervals);
3791
3889
  let segKfs;
3792
- if (loop.before) {
3890
+ if (loop.extend === PxLoopExtend.before) {
3793
3891
  segKfs = keyframes.slice(0, segCount + 1);
3794
3892
  } else {
3795
3893
  segKfs = keyframes.slice(totalIntervals - segCount);
@@ -3797,7 +3895,7 @@ var PixodeskAnimatorReact = (() => {
3797
3895
  const firstT = (_b = keyframes[0].t) != null ? _b : 0;
3798
3896
  const lastT = (_c = keyframes[keyframes.length - 1].t) != null ? _c : 0;
3799
3897
  let fillStart, fillEnd;
3800
- if (loop.before) {
3898
+ if (loop.extend === PxLoopExtend.before) {
3801
3899
  fillStart = 0;
3802
3900
  fillEnd = firstT;
3803
3901
  } else {
@@ -3824,7 +3922,12 @@ var PixodeskAnimatorReact = (() => {
3824
3922
  const remainder = fillDuration - fullReps * segDuration;
3825
3923
  const partialFraction = remainder / segDuration;
3826
3924
  const looped = [];
3925
+ const separateBoundary = loop.extend !== PxLoopExtend.before;
3926
+ const originalTerminalKf = keyframes[keyframes.length - 1];
3927
+ let terminalEasingOverride;
3928
+ let hasTerminalEasingOverride = false;
3827
3929
  function appendRep(repStart, isReversed, partial) {
3930
+ var _a2;
3828
3931
  let entries;
3829
3932
  if (isReversed) {
3830
3933
  entries = [];
@@ -3860,8 +3963,26 @@ var PixodeskAnimatorReact = (() => {
3860
3963
  looped.push({ t: repStart + cutRelT * segDuration, v: cutValue, e: void 0 });
3861
3964
  return;
3862
3965
  }
3966
+ const prevKf = looped.length > 0 ? looped[looped.length - 1] : originalTerminalKf;
3967
+ const isBoundary = separateBoundary && i === 0 && prevKf !== void 0 && Math.abs(((_a2 = prevKf.t) != null ? _a2 : 0) - (repStart + entry.relT * segDuration)) < 1e-9;
3968
+ if (isBoundary) {
3969
+ if (deepEqualValue(prevKf.v, entry.v)) {
3970
+ if (looped.length > 0) {
3971
+ prevKf.e = entry.e;
3972
+ prevKf.tangentOut = entry.tangentOut;
3973
+ } else {
3974
+ terminalEasingOverride = entry.e;
3975
+ hasTerminalEasingOverride = true;
3976
+ }
3977
+ continue;
3978
+ }
3979
+ if (looped.length > 0) {
3980
+ delete prevKf.tangentIn;
3981
+ delete prevKf.tangentOut;
3982
+ }
3983
+ }
3863
3984
  const pushed = {
3864
- t: repStart + entry.relT * segDuration,
3985
+ t: repStart + entry.relT * segDuration + (isBoundary ? LOOP_JUMP_SHIFT_MS : 0),
3865
3986
  v: entry.v,
3866
3987
  e: i < entries.length - 1 ? entry.e : void 0
3867
3988
  };
@@ -3909,7 +4030,7 @@ var PixodeskAnimatorReact = (() => {
3909
4030
  looped.push(pushed);
3910
4031
  }
3911
4032
  }
3912
- if (loop.before) {
4033
+ if (loop.extend === PxLoopExtend.before) {
3913
4034
  if (partialFraction > 1e-9) {
3914
4035
  const isReversed = !!loop.alternate && fullReps % 2 === 0;
3915
4036
  appendRepTail(fillStart, isReversed, partialFraction);
@@ -3932,9 +4053,14 @@ var PixodeskAnimatorReact = (() => {
3932
4053
  appendRep(repStart, isReversed, partialFraction);
3933
4054
  }
3934
4055
  }
3935
- if (loop.before) {
4056
+ if (loop.extend === PxLoopExtend.before) {
3936
4057
  return [...looped, ...keyframes];
3937
4058
  } else {
4059
+ if (hasTerminalEasingOverride && keyframes.length > 0) {
4060
+ const head = keyframes.slice(0, -1);
4061
+ const tail = __spreadProps2(__spreadValues2({}, keyframes[keyframes.length - 1]), { e: terminalEasingOverride });
4062
+ return [...head, tail, ...looped];
4063
+ }
3938
4064
  return [...keyframes, ...looped];
3939
4065
  }
3940
4066
  }
@@ -4048,20 +4174,23 @@ var PixodeskAnimatorReact = (() => {
4048
4174
  function generateElementId() {
4049
4175
  return "_px_el_" + ++_elementIdCounter;
4050
4176
  }
4051
- function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.webapi) {
4177
+ function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.waapi) {
4052
4178
  const normalized = {};
4053
4179
  for (const [propName, propAnim] of Object.entries(animDef)) {
4180
+ if (propName === "transform" && propAnim.alongPathMode === "offsetPath" && animDef["offsetDistance"] !== void 0) {
4181
+ continue;
4182
+ }
4054
4183
  const normalizedKfs = normalizeKeyframes(propName, propAnim, duration, defs);
4055
4184
  if (normalizedKfs.length > 0) {
4056
4185
  const out = { kfs: normalizedKfs };
4057
4186
  if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
4058
4187
  if (propAnim.loop !== void 0) out.loop = propAnim.loop;
4059
- normalized[propName] = engine === PxAnimatorEngine.webapi && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
4188
+ normalized[propName] = engine === PxAnimatorEngine.waapi && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
4060
4189
  }
4061
4190
  }
4062
4191
  return normalized;
4063
4192
  }
4064
- function getNormalisedBindings(doc, engine = PxAnimatorEngine.webapi) {
4193
+ function getNormalisedBindings(doc, engine = PxAnimatorEngine.waapi) {
4065
4194
  const animatorConfig = getAnimatorConfig(doc) || {};
4066
4195
  const defs = getDefs(doc);
4067
4196
  const duration = animatorConfig.duration || 1e3;
@@ -4466,7 +4595,7 @@ var PixodeskAnimatorReact = (() => {
4466
4595
  return rec;
4467
4596
  }
4468
4597
  function readAnimatable(raw) {
4469
- var _a, _b;
4598
+ var _a, _b, _c;
4470
4599
  if (raw === void 0) return {
4471
4600
  kind: "absent"
4472
4601
  /* Absent */
@@ -4476,13 +4605,34 @@ var PixodeskAnimatorReact = (() => {
4476
4605
  const obj = raw;
4477
4606
  const kfs = (_a = obj.keyframes) != null ? _a : obj.kfs;
4478
4607
  if (kfs) {
4479
- return { kind: "animated", keyframes: kfs.map(normaliseKeyframe), autoOrient: obj.autoOrient, loop: obj.loop };
4608
+ const out = { kind: "animated", keyframes: kfs.map(normaliseKeyframe), autoOrient: obj.autoOrient, loop: obj.loop };
4609
+ const base = (_b = obj.value) != null ? _b : obj.v;
4610
+ if (base !== void 0 && out.kind === "animated") out.base = base;
4611
+ return out;
4480
4612
  }
4481
- const staticValue = (_b = obj.value) != null ? _b : obj.v;
4613
+ const staticValue = (_c = obj.value) != null ? _c : obj.v;
4482
4614
  if (staticValue !== void 0) return { kind: "static", value: staticValue };
4483
4615
  }
4484
4616
  return { kind: "static", value: raw };
4485
4617
  }
4618
+ function writeAnimatableChannel(node, attrName, read, opts) {
4619
+ var _a, _b, _c, _d;
4620
+ const toOut = (v) => (opts == null ? void 0 : opts.asString) && v !== void 0 && v !== null ? String(v) : v;
4621
+ if (read.kind === "absent") return;
4622
+ if (read.kind === "static") {
4623
+ node[attrName] = toOut(read.value);
4624
+ return;
4625
+ }
4626
+ const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
4627
+ const animate = __spreadValues2({}, prevAnimate || {});
4628
+ const block = { keyframes: read.keyframes };
4629
+ if (read.loop !== void 0) block.loop = read.loop;
4630
+ if (read.autoOrient !== void 0) block.autoOrient = read.autoOrient;
4631
+ animate[attrName] = block;
4632
+ node.animate = animate;
4633
+ const baseline = (_d = (_b = read.base) != null ? _b : (_a = read.keyframes[0]) == null ? void 0 : _a.value) != null ? _d : (_c = read.keyframes[0]) == null ? void 0 : _c.v;
4634
+ if (baseline !== void 0) node[attrName] = toOut(baseline);
4635
+ }
4486
4636
  function normaliseKeyframe(kf) {
4487
4637
  if (!kf || typeof kf !== "object") return kf;
4488
4638
  const k = kf;
@@ -4502,7 +4652,7 @@ var PixodeskAnimatorReact = (() => {
4502
4652
  const o = readAnimatable(raw);
4503
4653
  if (o.kind === "absent") return void 0;
4504
4654
  if (o.kind === "static") return o.value;
4505
- ctx.warnings.push("transformation.origin: animated origin approximated by its first keyframe");
4655
+ ctx.warnings.push("transformBy.origin: animated origin approximated by its first keyframe");
4506
4656
  return (_a = o.keyframes[0]) == null ? void 0 : _a.value;
4507
4657
  }
4508
4658
  function keyframeWith(kf, value) {
@@ -4513,7 +4663,7 @@ var PixodeskAnimatorReact = (() => {
4513
4663
  if (kf.tangentIn !== void 0) out.tangentIn = kf.tangentIn;
4514
4664
  return out;
4515
4665
  }
4516
- function applyTransformationEffect(node, fx, ctx) {
4666
+ function applyTransformByEffect(node, fx, ctx) {
4517
4667
  if (!fx) return node;
4518
4668
  delete node.transform;
4519
4669
  let n = node;
@@ -4549,6 +4699,10 @@ var PixodeskAnimatorReact = (() => {
4549
4699
  } else {
4550
4700
  n = wrapTransformPart(n, "translate", fx.translate, ctx);
4551
4701
  }
4702
+ if (n !== node && node.id) {
4703
+ n.id = node.id;
4704
+ delete node.id;
4705
+ }
4552
4706
  return n;
4553
4707
  }
4554
4708
  function translateHasAutoOrient(translate) {
@@ -4558,8 +4712,6 @@ var PixodeskAnimatorReact = (() => {
4558
4712
  return Array.isArray(obj.keyframes) && obj.keyframes.some((kf) => kf.tangentOut || kf.tangentIn);
4559
4713
  }
4560
4714
  function normalizeScale(raw) {
4561
- if (raw === void 0) return void 0;
4562
- if (Array.isArray(raw)) return [raw[0] / 100, raw[1] / 100];
4563
4715
  return raw;
4564
4716
  }
4565
4717
  function wrapTransformPart(inner, part, raw, ctx) {
@@ -4600,34 +4752,54 @@ var PixodeskAnimatorReact = (() => {
4600
4752
  }
4601
4753
  return inner;
4602
4754
  }
4755
+ function genId(ctx, prefix) {
4756
+ return "_lw_" + prefix + "_" + ctx.nextId++;
4757
+ }
4758
+ function stripHash2(href) {
4759
+ return typeof href === "string" ? href.replace(/^#/, "") : void 0;
4760
+ }
4761
+ function indexById(node, map) {
4762
+ var _a;
4763
+ if (typeof node.id === "string") map.set(node.id, node);
4764
+ (_a = node.children) == null ? void 0 : _a.forEach((child) => indexById(child, map));
4765
+ }
4766
+ function spliceDefs(root, defs) {
4767
+ if (!defs.length) return;
4768
+ const existing = root.children || (root.children = []);
4769
+ existing.unshift({ type: "defs", children: defs });
4770
+ }
4771
+ var clone = deepClonePxNode;
4772
+ function regenerateIdsInClone(root, ctx) {
4773
+ return regenerateIdsAndRewriteRefs(root, () => genId(ctx, "retimed"));
4774
+ }
4603
4775
  function identifyContentRefTargets(node, ctx, allocator) {
4604
4776
  var _a, _b, _c;
4605
4777
  if (node.type === "use" && ((_b = (_a = node.effects) == null ? void 0 : _a.clone) == null ? void 0 : _b.type) === "content") {
4606
- const baseId = node.effects.clone.baseId;
4607
- if (typeof baseId === "string" && baseId && !ctx.contentRefInnerIds.has(baseId)) {
4608
- ctx.contentRefInnerIds.set(baseId, allocator(baseId));
4778
+ const sourceId = stripHash2(node.effects.clone.sourceId);
4779
+ if (typeof sourceId === "string" && sourceId && !ctx.contentRefInnerIds.has(sourceId)) {
4780
+ ctx.contentRefInnerIds.set(sourceId, allocator(sourceId));
4609
4781
  }
4610
4782
  }
4611
4783
  (_c = node.children) == null ? void 0 : _c.forEach((c) => identifyContentRefTargets(c, ctx, allocator));
4612
4784
  }
4613
- function splitForContentRef(node, transformation, originalId, innerId, ctx) {
4614
- const outerBody = liftBodyTranslate(node, transformation);
4785
+ function splitForContentRef(node, transformBy, originalId, innerId, ctx) {
4786
+ const outerBody = liftBodyTranslate(node, transformBy);
4615
4787
  if (typeof node.id === "string") delete node.id;
4616
- const { outer: outerTr, inner: innerTr } = splitTransformationEffect(transformation);
4788
+ const { outer: outerTr, inner: innerTr } = splitTransformByEffect(transformBy);
4617
4789
  let innerNode = node;
4618
- innerNode = applyTransformationEffect(innerNode, innerTr, ctx);
4790
+ innerNode = applyTransformByEffect(innerNode, innerTr, ctx);
4619
4791
  const innerWrapper = { type: "g", id: innerId, children: [innerNode] };
4620
4792
  let outerWrapper = { type: "g", id: originalId, children: [innerWrapper] };
4621
4793
  if (outerBody.transform !== void 0) outerWrapper.transform = outerBody.transform;
4622
4794
  if (outerBody.animate !== void 0) outerWrapper.animate = outerBody.animate;
4623
4795
  if (outerTr) {
4624
4796
  delete outerWrapper.id;
4625
- outerWrapper = applyTransformationEffect(outerWrapper, outerTr, ctx);
4797
+ outerWrapper = applyTransformByEffect(outerWrapper, outerTr, ctx);
4626
4798
  outerWrapper.id = originalId;
4627
4799
  }
4628
4800
  return outerWrapper;
4629
4801
  }
4630
- function liftBodyTranslate(node, transformation) {
4802
+ function liftBodyTranslate(node, transformBy) {
4631
4803
  var _a, _b, _c;
4632
4804
  const out = {};
4633
4805
  let didLiftAnimate = false;
@@ -4681,7 +4853,7 @@ var PixodeskAnimatorReact = (() => {
4681
4853
  didLiftAnimate = true;
4682
4854
  }
4683
4855
  }
4684
- const transformationHasTranslate = (transformation == null ? void 0 : transformation.translate) !== void 0;
4856
+ const transformationHasTranslate = (transformBy == null ? void 0 : transformBy.translate) !== void 0;
4685
4857
  const stripBodyTranslateOnly = didLiftAnimate || transformationHasTranslate;
4686
4858
  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);
4687
4859
  if (typeof node.transform === "string") {
@@ -4700,6 +4872,24 @@ var PixodeskAnimatorReact = (() => {
4700
4872
  if (split.rest) node.transform = split.rest;
4701
4873
  else delete node.transform;
4702
4874
  }
4875
+ } else if (node.transform && typeof node.transform === "object" && !Array.isArray(node.transform) && !node.transform.keyframes && !node.transform.kfs) {
4876
+ const wrapped = node.transform.value;
4877
+ const isWrapped = !!(wrapped && typeof wrapped === "object");
4878
+ const value = isWrapped ? wrapped : node.transform;
4879
+ const rewrap = (rec) => isWrapped ? { value: rec } : rec;
4880
+ if (Array.isArray(value.translate)) {
4881
+ const rest = __spreadValues2({}, value);
4882
+ delete rest.translate;
4883
+ const hasRest = Object.keys(rest).length > 0;
4884
+ if (stripBodyTranslateOnly) {
4885
+ if (hasRest) node.transform = rewrap(rest);
4886
+ else delete node.transform;
4887
+ } else {
4888
+ out.transform = rewrap({ translate: value.translate });
4889
+ if (hasRest) node.transform = rewrap(rest);
4890
+ else delete node.transform;
4891
+ }
4892
+ }
4703
4893
  }
4704
4894
  return out;
4705
4895
  }
@@ -4769,7 +4959,7 @@ var PixodeskAnimatorReact = (() => {
4769
4959
  const nums = m[1].split(/[\s,]+/).filter(Boolean).map(Number);
4770
4960
  return [nums[0] || 0, nums[1] || 0];
4771
4961
  }
4772
- function splitTransformationEffect(fx) {
4962
+ function splitTransformByEffect(fx) {
4773
4963
  if (!fx) return {};
4774
4964
  const originOnOuter = needsOriginOnOuter(fx.translate);
4775
4965
  const innerHasPivotedPart = fx.rotate !== void 0 || fx.scale !== void 0;
@@ -4795,26 +4985,6 @@ var PixodeskAnimatorReact = (() => {
4795
4985
  }
4796
4986
  return false;
4797
4987
  }
4798
- function genId(ctx, prefix) {
4799
- return "_lw_" + prefix + "_" + ctx.nextId++;
4800
- }
4801
- function stripHash2(href) {
4802
- return typeof href === "string" ? href.replace(/^#/, "") : void 0;
4803
- }
4804
- function indexById(node, map) {
4805
- var _a;
4806
- if (typeof node.id === "string") map.set(node.id, node);
4807
- (_a = node.children) == null ? void 0 : _a.forEach((child) => indexById(child, map));
4808
- }
4809
- function spliceDefs(root, defs) {
4810
- if (!defs.length) return;
4811
- const existing = root.children || (root.children = []);
4812
- existing.unshift({ type: "defs", children: defs });
4813
- }
4814
- var clone = deepClonePxNode;
4815
- function regenerateIdsInClone(root, ctx) {
4816
- return regenerateIdsAndRewriteRefs(root, () => genId(ctx, "retimed"));
4817
- }
4818
4988
  function applyFillGradientEffect(node, fx, ctx) {
4819
4989
  return applyGradient(node, fx, ctx, "fill");
4820
4990
  }
@@ -4835,62 +5005,63 @@ var PixodeskAnimatorReact = (() => {
4835
5005
  id
4836
5006
  };
4837
5007
  if (fx.type === PxGradientType.linear) {
4838
- if (fx.p1) {
4839
- out.x1 = String(fx.p1[0]);
4840
- out.y1 = String(fx.p1[1]);
4841
- }
4842
- if (fx.p2) {
4843
- out.x2 = String(fx.p2[0]);
4844
- out.y2 = String(fx.p2[1]);
4845
- }
5008
+ applyGeomVec(out, "x1", "y1", fx.p1);
5009
+ applyGeomVec(out, "x2", "y2", fx.p2);
4846
5010
  } else {
4847
- if (fx.c) {
4848
- out.cx = String(fx.c[0]);
4849
- out.cy = String(fx.c[1]);
4850
- }
4851
- if (fx.r !== void 0) out.r = String(fx.r);
4852
- if (fx.fp) {
4853
- out.fx = String(fx.fp[0]);
4854
- out.fy = String(fx.fp[1]);
4855
- }
5011
+ applyGeomVec(out, "cx", "cy", fx.c);
5012
+ applyGeomNumber(out, "r", fx.r);
5013
+ applyGeomVec(out, "fx", "fy", fx.fp);
4856
5014
  }
4857
5015
  if (fx.gradientUnits) out.gradientUnits = fx.gradientUnits;
4858
5016
  if (fx.spreadMethod) out.spreadMethod = fx.spreadMethod;
4859
5017
  if (fx.gradientTransform) out.gradientTransform = fx.gradientTransform;
4860
- const animate = fx.animate;
4861
- if (animate) {
4862
- const mapped = {};
4863
- for (const wireKey of Object.keys(animate)) {
4864
- const attr = GRADIENT_ANIM_CHANNEL_TO_ATTR[wireKey];
4865
- if (attr) mapped[attr] = animate[wireKey];
4866
- }
4867
- if (Object.keys(mapped).length) out.animate = mapped;
4868
- }
4869
5018
  out.children = buildStopChildren(fx.stops, ctx);
4870
5019
  return out;
4871
5020
  }
4872
- var GRADIENT_ANIM_CHANNEL_TO_ATTR = {
4873
- gradientX1: "x1",
4874
- gradientY1: "y1",
4875
- gradientX2: "x2",
4876
- gradientY2: "y2",
4877
- gradientCx: "cx",
4878
- gradientCy: "cy",
4879
- gradientFx: "fx",
4880
- gradientFy: "fy",
4881
- gradientR: "r"
4882
- };
5021
+ function applyGeomVec(out, xAttr, yAttr, raw) {
5022
+ var _a, _b, _c;
5023
+ const read = readAnimatable(raw);
5024
+ if (read.kind === "absent") return;
5025
+ if (read.kind === "static") {
5026
+ out[xAttr] = String(read.value[0]);
5027
+ out[yAttr] = String(read.value[1]);
5028
+ return;
5029
+ }
5030
+ const axisChannel = (idx) => {
5031
+ const block = {
5032
+ keyframes: read.keyframes.map((kf) => {
5033
+ const axisKf = { time: kf.time, value: Array.isArray(kf.value) ? kf.value[idx] : void 0 };
5034
+ if (kf.easing !== void 0) axisKf.easing = kf.easing;
5035
+ return axisKf;
5036
+ })
5037
+ };
5038
+ if (read.loop !== void 0) block.loop = read.loop;
5039
+ return block;
5040
+ };
5041
+ const animate = (_a = out.animate) != null ? _a : {};
5042
+ animate[xAttr] = axisChannel(0);
5043
+ animate[yAttr] = axisChannel(1);
5044
+ out.animate = animate;
5045
+ const baseline = (_c = read.base) != null ? _c : (_b = read.keyframes[0]) == null ? void 0 : _b.value;
5046
+ if (Array.isArray(baseline)) {
5047
+ out[xAttr] = String(baseline[0]);
5048
+ out[yAttr] = String(baseline[1]);
5049
+ }
5050
+ }
5051
+ function applyGeomNumber(out, attrName, raw) {
5052
+ const read = readAnimatable(raw);
5053
+ if (read.kind === "absent") return;
5054
+ writeAnimatableChannel(out, attrName, read, { asString: true });
5055
+ }
4883
5056
  function buildStopChildren(stops, ctx) {
4884
5057
  var _a, _b, _c, _d;
4885
5058
  if (!stops) return [];
4886
- if (Array.isArray(stops)) return stops.map(staticStopNode);
4887
- if (typeof stops === "object" && Array.isArray(stops.value)) {
4888
- return stops.value.map(staticStopNode);
4889
- }
4890
- const animBlock = stops;
4891
- const kfs = animBlock.keyframes;
4892
- if (!Array.isArray(kfs) || !kfs.length) return [];
4893
- const loopFromSource = animBlock.loop;
5059
+ const read = readAnimatable(stops);
5060
+ if (read.kind === "absent") return [];
5061
+ if (read.kind === "static") return Array.isArray(read.value) ? read.value.map(staticStopNode) : [];
5062
+ const kfs = read.keyframes;
5063
+ if (!kfs.length) return [];
5064
+ const loopFromSource = read.loop;
4894
5065
  let stopCount = 0;
4895
5066
  for (const kf of kfs) {
4896
5067
  const v = (_a = kf.value) != null ? _a : kf.v;
@@ -4965,36 +5136,60 @@ var PixodeskAnimatorReact = (() => {
4965
5136
  return pct + "%";
4966
5137
  }
4967
5138
  function applyClipPathEffect(node, fx, ctx) {
5139
+ var _a, _b;
4968
5140
  if (!fx || !fx.d && !fx.animate) return node;
4969
5141
  const clipId = genId(ctx, "clip");
4970
- const pathChild = { type: "path", d: fx.d };
4971
- if (fx.animate) pathChild.animate = { d: fx.animate };
5142
+ const pathChild = { type: "path" };
5143
+ const read = readAnimatable(fx.d);
5144
+ if (read.kind !== "absent") {
5145
+ if (read.kind === "static") {
5146
+ pathChild.d = pathString(read.value);
5147
+ } else {
5148
+ writeAnimatableChannel(pathChild, "d", read);
5149
+ if (pathChild.d !== void 0) pathChild.d = pathString(pathChild.d);
5150
+ }
5151
+ }
5152
+ if (fx.animate && !((_a = pathChild.animate) == null ? void 0 : _a.d)) {
5153
+ const animate = (_b = pathChild.animate) != null ? _b : {};
5154
+ animate.d = fx.animate;
5155
+ pathChild.animate = animate;
5156
+ }
4972
5157
  ctx.defs.push({ type: "clipPath", id: clipId, children: [pathChild] });
4973
5158
  node.clipPath = "url(#" + clipId + ")";
4974
5159
  return node;
4975
5160
  }
4976
- function applyMaskedByEffect(node, fx, transformation, ctx) {
5161
+ function pathString(v) {
5162
+ if (typeof v === "string") return v;
5163
+ if (v && typeof v === "object" && typeof v.path === "string") return v.path;
5164
+ return void 0;
5165
+ }
5166
+ function applyMaskedByEffect(node, fx, transformBy, ctx) {
4977
5167
  if (!fx) return node;
4978
- if (!fx.href) {
4979
- ctx.errors.push("maskedBy.href missing \u2014 cannot build mask");
5168
+ const sourceId = stripHash2(fx.sourceId);
5169
+ if (!sourceId) {
5170
+ ctx.errors.push("maskedBy.sourceId missing \u2014 cannot build mask");
4980
5171
  return node;
4981
5172
  }
4982
5173
  const maskId = genId(ctx, "mask");
4983
- let content = { type: "use", href: "#" + fx.href };
4984
- if (transformation) {
4985
- content = wrapInverseTransform(content, transformation, ctx);
5174
+ let content = { type: "use", href: "#" + sourceId };
5175
+ if (transformBy) {
5176
+ content = wrapInverseTransform(content, transformBy, ctx);
4986
5177
  } else if (hasAnimateTransform(node)) {
4987
5178
  content = wrapInverseAnimatedBodyTransform(content, node, ctx);
4988
5179
  } else {
4989
5180
  const bodyStatic = readTransformationFromBody(node);
4990
5181
  if (bodyStatic) content = wrapInverseTransform(content, bodyStatic, ctx);
4991
5182
  }
4992
- const includeTargetOwn = transformation === void 0 && !nodeHasBodyTransform(node);
4993
- content = wrapAncestorChainCompensation(content, node, fx.href, ctx, includeTargetOwn);
5183
+ const includeTargetOwn = transformBy === void 0 && !nodeHasBodyTransform(node);
5184
+ content = wrapAncestorChainCompensation(content, node, sourceId, ctx, includeTargetOwn);
4994
5185
  const mask = { type: "mask", id: maskId, children: [content] };
4995
5186
  if (fx.maskType) mask.maskType = fx.maskType;
4996
5187
  if (fx.maskUnits) mask.maskUnits = fx.maskUnits;
4997
5188
  if (fx.maskContentUnits) mask.maskContentUnits = fx.maskContentUnits;
5189
+ if (fx.x !== void 0) mask.x = String(fx.x);
5190
+ if (fx.y !== void 0) mask.y = String(fx.y);
5191
+ if (fx.width !== void 0) mask.width = String(fx.width);
5192
+ if (fx.height !== void 0) mask.height = String(fx.height);
4998
5193
  ctx.defs.push(mask);
4999
5194
  node.mask = "url(#" + maskId + ")";
5000
5195
  return node;
@@ -5101,6 +5296,19 @@ var PixodeskAnimatorReact = (() => {
5101
5296
  if (parts.origin) out.origin = parts.origin;
5102
5297
  return Object.keys(out).length ? out : void 0;
5103
5298
  }
5299
+ if (node.transform && typeof node.transform === "object" && !node.transform.keyframes && !node.transform.kfs) {
5300
+ const wrapped = node.transform.value;
5301
+ const value = wrapped && typeof wrapped === "object" ? wrapped : node.transform;
5302
+ if (value && typeof value === "object") {
5303
+ const out = {};
5304
+ if (Array.isArray(value.translate)) out.translate = value.translate;
5305
+ if (typeof value.rotate === "number") out.rotate = value.rotate;
5306
+ if (typeof value.skew === "number") out.skew = value.skew;
5307
+ if (Array.isArray(value.scale)) out.scale = { value: value.scale };
5308
+ if (Array.isArray(value.origin)) out.origin = value.origin;
5309
+ return Object.keys(out).length ? out : void 0;
5310
+ }
5311
+ }
5104
5312
  return void 0;
5105
5313
  }
5106
5314
  function parseTransformStringToParts(s) {
@@ -5234,10 +5442,10 @@ var PixodeskAnimatorReact = (() => {
5234
5442
  const interestingNodes = /* @__PURE__ */ new Set();
5235
5443
  const collectInterestingNodes = (n) => {
5236
5444
  var _a, _b;
5237
- const href = (_b = (_a = n.effects) == null ? void 0 : _a.maskedBy) == null ? void 0 : _b.href;
5238
- if (typeof href === "string") {
5445
+ const maskSourceId = stripHash2((_b = (_a = n.effects) == null ? void 0 : _a.maskedBy) == null ? void 0 : _b.sourceId);
5446
+ if (typeof maskSourceId === "string") {
5239
5447
  interestingNodes.add(n);
5240
- const sourceNode = ctx.idMap.get(href);
5448
+ const sourceNode = ctx.idMap.get(maskSourceId);
5241
5449
  if (sourceNode) interestingNodes.add(sourceNode);
5242
5450
  }
5243
5451
  if (Array.isArray(n.children)) for (const ch of n.children) collectInterestingNodes(ch);
@@ -5263,8 +5471,9 @@ var PixodeskAnimatorReact = (() => {
5263
5471
  if (typeof tr === "string") {
5264
5472
  const parts = parseTranslateOnlyFromString(tr, ctx);
5265
5473
  if (parts) out.translate = parts;
5266
- } else if (tr && typeof tr === "object") {
5267
- const value = tr.value;
5474
+ } else if (tr && typeof tr === "object" && !tr.keyframes && !tr.kfs) {
5475
+ const wrapped = tr.value;
5476
+ const value = wrapped && typeof wrapped === "object" ? wrapped : tr;
5268
5477
  if (value && typeof value === "object" && Array.isArray(value.translate)) {
5269
5478
  out.translate = [value.translate[0] || 0, value.translate[1] || 0];
5270
5479
  }
@@ -5312,17 +5521,17 @@ var PixodeskAnimatorReact = (() => {
5312
5521
  var CONTENT_SUBREF = "content";
5313
5522
  function applyRefHref(node, clone2, ctx) {
5314
5523
  if (!clone2) return;
5315
- const baseId = clone2.baseId;
5316
- if (!baseId) {
5317
- if (clone2.type === CONTENT_SUBREF) ctx.errors.push("clone: content ref missing baseId");
5524
+ const sourceId = stripHash2(clone2.sourceId);
5525
+ if (!sourceId) {
5526
+ if (clone2.type === CONTENT_SUBREF) ctx.errors.push("clone: content ref missing sourceId");
5318
5527
  return;
5319
5528
  }
5320
- const targetId = clone2.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(baseId) || baseId : baseId;
5529
+ const targetId = clone2.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(sourceId) || sourceId : sourceId;
5321
5530
  node.href = "#" + targetId;
5322
5531
  }
5323
- function applyRefAndTransformationEffect(node, clone2, transformation, ctx) {
5532
+ function applyRefAndTransformationEffect(node, clone2, transformBy, ctx) {
5324
5533
  applyRefHref(node, clone2, ctx);
5325
- return applyTransformationEffect(node, transformation, ctx);
5534
+ return applyTransformByEffect(node, transformBy, ctx);
5326
5535
  }
5327
5536
  function applyRepeaterEffect(node, fx, ctx) {
5328
5537
  var _a, _b;
@@ -5345,7 +5554,7 @@ var PixodeskAnimatorReact = (() => {
5345
5554
  for (let i = 1; i < copies; i++) {
5346
5555
  const baseClone = clone(base);
5347
5556
  const synthFx = synthesisePerCopyFx(fx, i);
5348
- const wrapped = synthFx ? applyTransformationEffect(baseClone, synthFx, ctx) : baseClone;
5557
+ const wrapped = synthFx ? applyTransformByEffect(baseClone, synthFx, ctx) : baseClone;
5349
5558
  children.push(wrapped);
5350
5559
  }
5351
5560
  const wrapper = { type: "g", children };
@@ -5357,10 +5566,13 @@ var PixodeskAnimatorReact = (() => {
5357
5566
  function synthesisePerCopyFx(fx, i) {
5358
5567
  const out = {};
5359
5568
  if (fx.translate !== void 0) {
5360
- out.translate = mapAnimatableVec2(fx.translate, (v) => [v[0] * i, v[1] * i]);
5569
+ out.translate = mapAnimatable(fx.translate, (v) => [v[0] * i, v[1] * i]);
5361
5570
  }
5362
5571
  if (fx.rotate !== void 0) {
5363
- out.rotate = mapAnimatableNumber(fx.rotate, (v) => v * i);
5572
+ out.rotate = mapAnimatable(fx.rotate, (v) => v * i);
5573
+ }
5574
+ if (fx.skew !== void 0) {
5575
+ out.skew = mapAnimatable(fx.skew, (v) => v * i);
5364
5576
  }
5365
5577
  if (fx.scale !== void 0) {
5366
5578
  out.scale = synthesiseScale(fx.scale, i);
@@ -5370,63 +5582,50 @@ var PixodeskAnimatorReact = (() => {
5370
5582
  }
5371
5583
  return Object.keys(out).length ? out : void 0;
5372
5584
  }
5373
- function mapAnimatableVec2(raw, fn) {
5374
- if (Array.isArray(raw)) return fn(raw);
5375
- if (raw && typeof raw === "object") {
5376
- const obj = raw;
5377
- if (Array.isArray(obj.keyframes)) {
5378
- return __spreadProps2(__spreadValues2({}, obj), {
5379
- keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps2(__spreadValues2({}, kf), { value: fn(kf.value) }) : kf)
5380
- });
5381
- }
5382
- if (obj.value !== void 0) {
5383
- return __spreadProps2(__spreadValues2({}, obj), { value: fn(obj.value) });
5384
- }
5585
+ function mapAnimatable(raw, fn, wrapStatic = false) {
5586
+ const read = readAnimatable(raw);
5587
+ if (read.kind === "absent") return raw;
5588
+ if (read.kind === "static") {
5589
+ const mapped = fn(read.value);
5590
+ const wasRawStatic = typeof raw === "number" || Array.isArray(raw);
5591
+ return wasRawStatic && !wrapStatic ? mapped : { value: mapped };
5385
5592
  }
5386
- return raw;
5387
- }
5388
- function mapAnimatableNumber(raw, fn) {
5389
- if (typeof raw === "number") return fn(raw);
5390
- if (raw && typeof raw === "object") {
5391
- const obj = raw;
5392
- if (Array.isArray(obj.keyframes)) {
5393
- return __spreadProps2(__spreadValues2({}, obj), {
5394
- keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps2(__spreadValues2({}, kf), { value: fn(kf.value) }) : kf)
5395
- });
5396
- }
5397
- if (obj.value !== void 0) {
5398
- return __spreadProps2(__spreadValues2({}, obj), { value: fn(obj.value) });
5399
- }
5400
- }
5401
- return raw;
5593
+ const out = {
5594
+ keyframes: read.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps2(__spreadValues2({}, kf), { value: fn(kf.value) }) : kf)
5595
+ };
5596
+ if (read.loop !== void 0) out.loop = read.loop;
5597
+ if (read.autoOrient !== void 0) out.autoOrient = read.autoOrient;
5598
+ if (read.base !== void 0) out.value = fn(read.base);
5599
+ return out;
5402
5600
  }
5403
5601
  function synthesiseScale(raw, i) {
5404
- const scalePowerFromPercent = (v) => [Math.pow(v[0] / 100, i), Math.pow(v[1] / 100, i)];
5405
- const scalePowerFromUnits = (v) => [Math.pow(v[0], i), Math.pow(v[1], i)];
5406
- if (Array.isArray(raw)) {
5407
- return { value: scalePowerFromPercent(raw) };
5408
- }
5409
- if (raw && typeof raw === "object") {
5410
- const obj = raw;
5411
- if (Array.isArray(obj.keyframes)) {
5412
- return __spreadProps2(__spreadValues2({}, obj), {
5413
- keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps2(__spreadValues2({}, kf), { value: scalePowerFromUnits(kf.value) }) : kf)
5414
- });
5415
- }
5416
- if (obj.value !== void 0) {
5417
- return __spreadProps2(__spreadValues2({}, obj), { value: scalePowerFromPercent(obj.value) });
5418
- }
5419
- }
5420
- return raw;
5602
+ const scalePower = (v) => [Math.pow(v[0], i), Math.pow(v[1], i)];
5603
+ return mapAnimatable(raw, scalePower, true);
5421
5604
  }
5422
5605
  var RETIME_MATERIALISATION_MODE_INLINE_G = false;
5423
5606
  function asRetime(r) {
5424
5607
  var _a, _b;
5425
- if (r.timeCrop) {
5426
- console.warn("retime: `timeCrop` is not supported yet and will be ignored");
5427
- }
5428
5608
  return { start: (_a = r.start) != null ? _a : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
5429
5609
  }
5610
+ var CROP_EDGE_MS = 1;
5611
+ function applyTimeCrop(useNode, crop, ctx) {
5612
+ const [start, end] = crop;
5613
+ if (!Number.isFinite(start) || !Number.isFinite(end)) {
5614
+ ctx.warnings.push("retime: timeCrop is not a pair of finite numbers \u2014 ignored");
5615
+ return;
5616
+ }
5617
+ const keyframes = end <= start ? [{ time: 0, value: 0 }] : [
5618
+ ...start > 0 ? [{ time: Math.max(0, start - CROP_EDGE_MS), value: 0 }] : [],
5619
+ { time: Math.max(0, start), value: 1 },
5620
+ { time: end, value: 1 },
5621
+ { time: end + CROP_EDGE_MS, value: 0 }
5622
+ ];
5623
+ const inner = __spreadValues2({}, useNode);
5624
+ for (const k of Object.keys(useNode)) delete useNode[k];
5625
+ useNode.type = "g";
5626
+ useNode.children = [inner];
5627
+ useNode.animate = { opacity: { keyframes } };
5628
+ }
5430
5629
  function concatRetime(child, parent) {
5431
5630
  return {
5432
5631
  start: parent.start + parent.stretch * child.start,
@@ -5486,8 +5685,10 @@ var PixodeskAnimatorReact = (() => {
5486
5685
  for (const useNode of sites) {
5487
5686
  const retime = readCloneRetime(useNode);
5488
5687
  if (!retime) continue;
5688
+ const crop = retime.timeCrop;
5489
5689
  clearCloneRetime(useNode);
5490
5690
  materialiseRetime(useNode, asRetime(retime), ctx);
5691
+ if (crop) applyTimeCrop(useNode, crop, ctx);
5491
5692
  }
5492
5693
  }
5493
5694
  function materialiseRetime(useNode, retime, ctx) {
@@ -5730,14 +5931,11 @@ var PixodeskAnimatorReact = (() => {
5730
5931
  }
5731
5932
  var EXTEND_MARGIN_FRAC = 0.15;
5732
5933
  function numRange(v) {
5733
- if (typeof v === "number") return { min: v, max: v };
5734
- if (v && typeof v === "object") {
5735
- const o = v;
5736
- if (typeof o.value === "number") return { min: o.value, max: o.value };
5737
- if (Array.isArray(o.keyframes) && o.keyframes.length) {
5738
- const vals = o.keyframes.map((k) => Number(k.value) || 0);
5739
- return { min: Math.min(...vals), max: Math.max(...vals) };
5740
- }
5934
+ const read = readAnimatable(v);
5935
+ if (read.kind === "static" && typeof read.value === "number") return { min: read.value, max: read.value };
5936
+ if (read.kind === "animated" && read.keyframes.length) {
5937
+ const vals = read.keyframes.map((k) => Number(k.value) || 0);
5938
+ return { min: Math.min(...vals), max: Math.max(...vals) };
5741
5939
  }
5742
5940
  return { min: 0, max: 0 };
5743
5941
  }
@@ -5757,11 +5955,16 @@ var PixodeskAnimatorReact = (() => {
5757
5955
  var r3 = (n) => Math.round(n * 1e3) / 1e3;
5758
5956
  function shiftAnimatable(v, by) {
5759
5957
  if (!by || v === void 0 || v === null) return v;
5760
- if (typeof v === "number") return v + by;
5761
- const o = v;
5762
- if (typeof o.value === "number") return __spreadProps2(__spreadValues2({}, o), { value: o.value + by });
5763
- if (Array.isArray(o.keyframes)) return __spreadProps2(__spreadValues2({}, o), { keyframes: o.keyframes.map((k) => __spreadProps2(__spreadValues2({}, k), { value: (Number(k.value) || 0) + by })) });
5764
- return v;
5958
+ const read = readAnimatable(v);
5959
+ if (read.kind === "absent") return v;
5960
+ if (read.kind === "static") return typeof v === "number" ? read.value + by : { value: read.value + by };
5961
+ const out = {
5962
+ keyframes: read.keyframes.map((k) => __spreadProps2(__spreadValues2({}, k), { value: (Number(k.value) || 0) + by }))
5963
+ };
5964
+ if (read.loop !== void 0) out.loop = read.loop;
5965
+ if (read.autoOrient !== void 0) out.autoOrient = read.autoOrient;
5966
+ if (read.base !== void 0) out.value = read.base + by;
5967
+ return out;
5765
5968
  }
5766
5969
  function extendedPathForBrowser(pathD, opts) {
5767
5970
  var _a;
@@ -5817,26 +6020,7 @@ var PixodeskAnimatorReact = (() => {
5817
6020
  }
5818
6021
  function applyAnimatableNumber(node, attrName, raw) {
5819
6022
  if (raw === void 0 || raw === null) return;
5820
- if (typeof raw === "number") {
5821
- node[attrName] = String(raw);
5822
- return;
5823
- }
5824
- if (typeof raw === "object" && raw !== null) {
5825
- const obj = raw;
5826
- if (Array.isArray(obj.keyframes)) {
5827
- const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
5828
- const animate = __spreadValues2({}, prevAnimate || {});
5829
- const block = { keyframes: obj.keyframes };
5830
- if (obj.loop !== void 0) block.loop = obj.loop;
5831
- animate[attrName] = block;
5832
- node.animate = animate;
5833
- return;
5834
- }
5835
- if (typeof obj.value === "number") {
5836
- node[attrName] = String(obj.value);
5837
- return;
5838
- }
5839
- }
6023
+ writeAnimatableChannel(node, attrName, readAnimatable(raw), { asString: true });
5840
6024
  }
5841
6025
  var jsonElementFactory = (type, props, children) => {
5842
6026
  const node = { type };
@@ -6024,13 +6208,13 @@ var PixodeskAnimatorReact = (() => {
6024
6208
  if (y !== void 0) pen.y = y;
6025
6209
  pen.x += (_a2 = parseLen(el.dx)) != null ? _a2 : 0;
6026
6210
  pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
6027
- const content = (_c2 = str(el[TEXT_ATTR])) != null ? _c2 : str(el[TEXT_CONTENT_ATTR]);
6211
+ const content = (_c2 = str(el[TEXT_CONTENT_ATTR])) != null ? _c2 : str(el[TEXT_ATTR]);
6028
6212
  if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
6029
6213
  if (el.children) for (const ch of el.children) walk(ch, s);
6030
6214
  };
6031
6215
  const rootStyle = rootStyleOf(node);
6032
6216
  if (node.children) for (const ch of node.children) walk(ch, rootStyle);
6033
- const rootContent = (_c = str(node[TEXT_ATTR])) != null ? _c : str(node[TEXT_CONTENT_ATTR]);
6217
+ const rootContent = (_c = str(node[TEXT_CONTENT_ATTR])) != null ? _c : str(node[TEXT_ATTR]);
6034
6218
  if (rootContent && !((_d = node.children) == null ? void 0 : _d.length)) renderChars(rootContent, rootStyle);
6035
6219
  const anchor = str(node.textAnchor);
6036
6220
  if (anchor === "middle" || anchor === "end") {
@@ -6048,7 +6232,7 @@ var PixodeskAnimatorReact = (() => {
6048
6232
  const walk = (el, parentStyle) => {
6049
6233
  var _a, _b, _c;
6050
6234
  const s = resolveStyle2(el, parentStyle);
6051
- const content = (_a = str(el[TEXT_ATTR])) != null ? _a : str(el[TEXT_CONTENT_ATTR]);
6235
+ const content = (_a = str(el[TEXT_CONTENT_ATTR])) != null ? _a : str(el[TEXT_ATTR]);
6052
6236
  if (content && !((_b = el.children) == null ? void 0 : _b.length)) {
6053
6237
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
6054
6238
  if (gf) {
@@ -6272,9 +6456,9 @@ var PixodeskAnimatorReact = (() => {
6272
6456
  }
6273
6457
  return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
6274
6458
  }
6275
- function applyTrimPathEffect(node, trimPath, isCombinedShape, ctx) {
6459
+ function applyTrimPathEffect(node, trimPath, ctx) {
6276
6460
  if (!trimPath) return node;
6277
- const trimAllAsOne = !!trimPath.trimAllAsOne;
6461
+ const combined = trimPath.subPaths === PxTrimSubPaths.combined;
6278
6462
  const leafEntries = [];
6279
6463
  const measure = (n) => {
6280
6464
  if (Array.isArray(n.children) && n.children.length > 0) {
@@ -6295,16 +6479,16 @@ var PixodeskAnimatorReact = (() => {
6295
6479
  measure(node);
6296
6480
  if (!leafEntries.length) return node;
6297
6481
  let acc = 0;
6298
- const iterOrder = trimAllAsOne ? [...leafEntries].reverse() : leafEntries;
6482
+ const iterOrder = combined ? [...leafEntries].reverse() : leafEntries;
6299
6483
  for (const entry of iterOrder) {
6300
6484
  for (const sp of entry.subpaths) {
6301
- if (!trimAllAsOne) acc = 0;
6485
+ if (!combined) acc = 0;
6302
6486
  sp.startOffsetPx = acc;
6303
6487
  acc += sp.lengthPx;
6304
6488
  }
6305
6489
  }
6306
6490
  const chainLengthPx = acc;
6307
- if (trimAllAsOne && chainLengthPx < 1e-3) return node;
6491
+ if (combined && chainLengthPx < 1e-3) return node;
6308
6492
  const offsetReadRaw = readAnimatable(trimPath.offset);
6309
6493
  const offsetRead = offsetReadRaw.kind === "absent" ? { kind: "static", value: 0 } : offsetReadRaw;
6310
6494
  const rangeReadRaw = readRangeWithCrossings(trimPath.range);
@@ -6316,18 +6500,18 @@ var PixodeskAnimatorReact = (() => {
6316
6500
  if (leafEntries.length === 1 && leafEntries[0].leaf === node && leafEntries[0].subpaths.length === 1) {
6317
6501
  const entry = leafEntries[0];
6318
6502
  const sp = entry.subpaths[0];
6319
- const pathLengthPx = trimAllAsOne ? chainLengthPx : sp.lengthPx;
6503
+ const pathLengthPx = combined ? chainLengthPx : sp.lengthPx;
6320
6504
  if (pathLengthPx < 1e-3) return node;
6321
- const startOffsetPct = trimAllAsOne ? sp.startOffsetPx / pathLengthPx : 0;
6505
+ const startOffsetPct = combined ? sp.startOffsetPx / pathLengthPx : 0;
6322
6506
  return collapseLeafWithTrim(entry.leaf, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead);
6323
6507
  }
6324
6508
  const replacements = /* @__PURE__ */ new Map();
6325
6509
  for (const entry of leafEntries) {
6326
6510
  const newChildren = [];
6327
6511
  for (const sp of entry.subpaths) {
6328
- const pathLengthPx = trimAllAsOne ? chainLengthPx : sp.lengthPx;
6512
+ const pathLengthPx = combined ? chainLengthPx : sp.lengthPx;
6329
6513
  if (pathLengthPx < 1e-3) continue;
6330
- const startOffsetPct = trimAllAsOne ? sp.startOffsetPx / pathLengthPx : 0;
6514
+ const startOffsetPct = combined ? sp.startOffsetPx / pathLengthPx : 0;
6331
6515
  newChildren.push(...buildSubpathNodes(entry.leaf, sp.subpath, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead, ctx));
6332
6516
  }
6333
6517
  replacements.set(entry.leaf, wrapLeafAsGroup(entry.leaf, newChildren));
@@ -6434,22 +6618,8 @@ var PixodeskAnimatorReact = (() => {
6434
6618
  };
6435
6619
  }
6436
6620
  function applyAttr(node, attrName, attr) {
6437
- var _a, _b;
6438
6621
  if (!attr) return;
6439
- if (attr.kind === "static") {
6440
- node[attrName] = attr.value;
6441
- return;
6442
- }
6443
- const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
6444
- const animate = __spreadValues2({}, prevAnimate || {});
6445
- const block = { keyframes: attr.keyframes };
6446
- if (attr.loop !== void 0) block.loop = attr.loop;
6447
- animate[attrName] = block;
6448
- node.animate = animate;
6449
- const firstKf = attr.keyframes[0];
6450
- if (firstKf && ((_a = firstKf.value) != null ? _a : firstKf.v) !== void 0) {
6451
- node[attrName] = (_b = firstKf.value) != null ? _b : firstKf.v;
6452
- }
6622
+ writeAnimatableChannel(node, attrName, attr);
6453
6623
  }
6454
6624
  var OPACITY_STEP_MS = 10;
6455
6625
  function computeOpacityFromRange(rangeRead) {
@@ -6631,9 +6801,9 @@ var PixodeskAnimatorReact = (() => {
6631
6801
  nextId: 0,
6632
6802
  contentRefInnerIds: /* @__PURE__ */ new Map(),
6633
6803
  maskAncestorChains: /* @__PURE__ */ new Map(),
6634
- // Resolved engine: `frames` ONLY when explicitly set; auto/webapi/unset →
6635
- // webapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
6636
- engine: ((_a = getAnimatorConfig(root)) == null ? void 0 : _a.mode) === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.webapi,
6804
+ // Resolved engine: `frames` ONLY when explicitly set; auto/waapi/unset →
6805
+ // waapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
6806
+ engine: ((_a = getAnimatorConfig(root)) == null ? void 0 : _a.mode) === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.waapi,
6637
6807
  glyphs: (_b = getDefs(root)) == null ? void 0 : _b.glyphs
6638
6808
  };
6639
6809
  const working = clone(root);
@@ -6651,8 +6821,7 @@ var PixodeskAnimatorReact = (() => {
6651
6821
  const originalId = typeof node.id === "string" ? node.id : void 0;
6652
6822
  const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
6653
6823
  if (!fx && !innerIdForContentRef) return node;
6654
- const { transformation, repeater, maskedBy, clipPath, trimPath, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
6655
- const isCombinedShape = fx == null ? void 0 : fx.isCombinedShape;
6824
+ const { transformBy, repeater, maskedBy, clipPath, trimPath, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
6656
6825
  if (fx) delete node.effects;
6657
6826
  let n = node;
6658
6827
  let consumedByGlyphs = false;
@@ -6672,15 +6841,15 @@ var PixodeskAnimatorReact = (() => {
6672
6841
  if (!consumedByGlyphs) n = applyTextPathEffect(n, textPath, ctx);
6673
6842
  n = applyFillGradientEffect(n, fillGradient, ctx);
6674
6843
  n = applyStrokeGradientEffect(n, strokeGradient, ctx);
6675
- n = applyTrimPathEffect(n, trimPath, isCombinedShape, ctx);
6844
+ n = applyTrimPathEffect(n, trimPath, ctx);
6676
6845
  n = applyRepeaterEffect(n, repeater, ctx);
6677
- n = applyMaskedByEffect(n, maskedBy, transformation, ctx);
6846
+ n = applyMaskedByEffect(n, maskedBy, transformBy, ctx);
6678
6847
  n = applyClipPathEffect(n, clipPath, ctx);
6679
6848
  if (innerIdForContentRef) {
6680
6849
  applyRefHref(n, cloneFx, ctx);
6681
- n = splitForContentRef(n, transformation, originalId, innerIdForContentRef, ctx);
6850
+ n = splitForContentRef(n, transformBy, originalId, innerIdForContentRef, ctx);
6682
6851
  } else {
6683
- n = applyRefAndTransformationEffect(n, cloneFx, transformation, ctx);
6852
+ n = applyRefAndTransformationEffect(n, cloneFx, transformBy, ctx);
6684
6853
  }
6685
6854
  if (cloneFx == null ? void 0 : cloneFx.retime) node.effects = { clone: { retime: cloneFx.retime } };
6686
6855
  if (originalId) ctx.idMap.set(originalId, n);
@@ -6690,12 +6859,141 @@ var PixodeskAnimatorReact = (() => {
6690
6859
  applyAllRetimeEffects(node, ctx);
6691
6860
  return node;
6692
6861
  }
6862
+ var kfTime = (kf) => {
6863
+ var _a, _b;
6864
+ return (_b = (_a = kf.t) != null ? _a : kf.time) != null ? _b : 0;
6865
+ };
6866
+ var kfValue = (kf) => {
6867
+ var _a;
6868
+ return (_a = kf.v) != null ? _a : kf.value;
6869
+ };
6870
+ var kfEasing = (kf) => {
6871
+ var _a;
6872
+ return (_a = kf.e) != null ? _a : kf.easing;
6873
+ };
6874
+ var kfTangentIn = (kf) => {
6875
+ var _a;
6876
+ return (_a = kf.tangentIn) != null ? _a : kf.ti;
6877
+ };
6878
+ var kfTangentOut = (kf) => {
6879
+ var _a;
6880
+ return (_a = kf.tangentOut) != null ? _a : kf.to;
6881
+ };
6882
+ function cubicAt(p0, c1, c2, p1, t) {
6883
+ const u = 1 - t;
6884
+ const a = u * u * u, b = 3 * u * u * t, c = 3 * u * t * t, d = t * t * t;
6885
+ return [
6886
+ a * p0[0] + b * c1[0] + c * c2[0] + d * p1[0],
6887
+ a * p0[1] + b * c1[1] + c * c2[1] + d * p1[1]
6888
+ ];
6889
+ }
6890
+ function cubicLength(p0, c1, c2, p1, steps = 64) {
6891
+ let len = 0;
6892
+ let prev = p0;
6893
+ for (let i = 1; i <= steps; i++) {
6894
+ const pt = cubicAt(p0, c1, c2, p1, i / steps);
6895
+ len += Math.hypot(pt[0] - prev[0], pt[1] - prev[1]);
6896
+ prev = pt;
6897
+ }
6898
+ return len;
6899
+ }
6900
+ var fmt2 = (n) => {
6901
+ const r = Math.round(n * 1e4) / 1e4;
6902
+ return Object.is(r, -0) ? "0" : String(r);
6903
+ };
6904
+ function buildOffsetPath(propAnim) {
6905
+ var _a, _b, _c, _d;
6906
+ if (propAnim.alongPathMode !== "offsetPath") return void 0;
6907
+ const kfs = (_a = propAnim.keyframes) != null ? _a : propAnim.kfs;
6908
+ if (!kfs || kfs.length < 2) return void 0;
6909
+ const first = kfValue(kfs[0]);
6910
+ const anchor = (first == null ? void 0 : first.origin) && first.origin.length >= 2 ? [first.origin[0], first.origin[1]] : [0, 0];
6911
+ const points = [];
6912
+ for (const kf of kfs) {
6913
+ const v = kfValue(kf);
6914
+ const tr = v == null ? void 0 : v.translate;
6915
+ if (!tr || tr.length < 2) return void 0;
6916
+ const parts = Object.keys(v);
6917
+ if (parts.some((p) => p !== "translate" && p !== "origin")) return void 0;
6918
+ const o = (_b = v == null ? void 0 : v.origin) != null ? _b : [0, 0];
6919
+ if (o[0] !== anchor[0] || o[1] !== anchor[1]) return void 0;
6920
+ points.push([tr[0] + anchor[0], tr[1] + anchor[1]]);
6921
+ }
6922
+ if (!kfs.some((kf) => kfTangentIn(kf) || kfTangentOut(kf))) return void 0;
6923
+ let d = "M" + fmt2(points[0][0]) + "," + fmt2(points[0][1]);
6924
+ const segLens = [];
6925
+ for (let i = 0; i < points.length - 1; i++) {
6926
+ const p0 = points[i], p1 = points[i + 1];
6927
+ const to = (_c = kfTangentOut(kfs[i])) != null ? _c : [0, 0];
6928
+ const ti = (_d = kfTangentIn(kfs[i + 1])) != null ? _d : [0, 0];
6929
+ const c1 = [p0[0] + to[0], p0[1] + to[1]];
6930
+ const c2 = [p1[0] + ti[0], p1[1] + ti[1]];
6931
+ d += "C" + fmt2(c1[0]) + "," + fmt2(c1[1]) + "," + fmt2(c2[0]) + "," + fmt2(c2[1]) + "," + fmt2(p1[0]) + "," + fmt2(p1[1]);
6932
+ segLens.push(cubicLength(p0, c1, c2, p1));
6933
+ }
6934
+ const total = segLens.reduce((a, b) => a + b, 0);
6935
+ if (!(total > 0)) return void 0;
6936
+ const distanceKfs = [];
6937
+ let cum = 0;
6938
+ for (let i = 0; i < kfs.length; i++) {
6939
+ if (i > 0) cum += segLens[i - 1];
6940
+ const out = { t: kfTime(kfs[i]), v: cum / total };
6941
+ const e = kfEasing(kfs[i]);
6942
+ if (e !== void 0) out.e = e;
6943
+ distanceKfs.push(out);
6944
+ }
6945
+ return { pathStr: d, distanceKfs, autoOrient: !!propAnim.autoOrient, anchor };
6946
+ }
6947
+ function materialiseOffsetPathsInTree(root) {
6948
+ const walk = (node) => {
6949
+ var _a;
6950
+ let out = node;
6951
+ const anim = node.animate;
6952
+ const transform = anim == null ? void 0 : anim["transform"];
6953
+ if (transform) {
6954
+ const built = buildOffsetPath(transform);
6955
+ if (built) {
6956
+ const newAnimate = __spreadValues2({}, anim);
6957
+ delete newAnimate["transform"];
6958
+ const distance = { keyframes: built.distanceKfs };
6959
+ if (transform.loop !== void 0) distance.loop = transform.loop;
6960
+ newAnimate["offsetDistance"] = distance;
6961
+ const staticTr = node.transform;
6962
+ let newTransform = staticTr;
6963
+ if (staticTr && typeof staticTr === "object") {
6964
+ const t = __spreadValues2({}, staticTr);
6965
+ delete t["translate"];
6966
+ delete t["origin"];
6967
+ newTransform = Object.keys(t).length ? t : void 0;
6968
+ }
6969
+ out = __spreadProps2(__spreadValues2({}, node), {
6970
+ animate: newAnimate,
6971
+ style: __spreadProps2(__spreadValues2({}, node.style), {
6972
+ offsetPath: "path('" + built.pathStr + "')",
6973
+ offsetAnchor: fmt2(built.anchor[0]) + "px " + fmt2(built.anchor[1]) + "px",
6974
+ offsetRotate: built.autoOrient ? "auto" : "0deg",
6975
+ offsetDistance: "0%"
6976
+ })
6977
+ });
6978
+ if (newTransform !== void 0) out.transform = newTransform;
6979
+ else delete out.transform;
6980
+ }
6981
+ }
6982
+ if ((_a = out.children) == null ? void 0 : _a.length) {
6983
+ const children = out.children.map(walk);
6984
+ if (children.some((c, i) => c !== out.children[i])) out = __spreadProps2(__spreadValues2({}, out), { children });
6985
+ }
6986
+ return out;
6987
+ };
6988
+ return walk(root);
6989
+ }
6693
6990
  function materialiseAllInTree(doc, engine, opts) {
6694
6991
  var _a, _b;
6695
6992
  let root = applyPlayerEffects(doc).root;
6993
+ root = materialiseOffsetPathsInTree(root);
6696
6994
  const duration = (_b = (_a = getAnimatorConfig(root)) == null ? void 0 : _a.duration) != null ? _b : DEFAULT_DURATION_MS;
6697
6995
  root = materialiseInternalLoopsInTree(root, duration);
6698
- if (engine === PxAnimatorEngine.webapi) {
6996
+ if (engine === PxAnimatorEngine.waapi) {
6699
6997
  root = materialiseMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
6700
6998
  root = materialiseAnimatedUseInstances(root);
6701
6999
  root = pruneUnreferencedDefs(root);
@@ -7007,62 +7305,6 @@ var PixodeskAnimatorReact = (() => {
7007
7305
  };
7008
7306
  return api;
7009
7307
  }
7010
- var SVG_NS = "http://www.w3.org/2000/svg";
7011
- function createElement(tagName, normalisedProps, style, children, textContent) {
7012
- if (DISALLOWED_SVG_TAGS_LOWER.has(tagName.toLowerCase())) {
7013
- console.warn("SVG tag blocked (dangerous): ", tagName);
7014
- return null;
7015
- }
7016
- const element = document.createElementNS(SVG_NS, tagName);
7017
- for (const propName in normalisedProps) {
7018
- const sanitised = sanitiseAttributeValue(propName, normalisedProps[propName]);
7019
- if (sanitised === void 0) continue;
7020
- if (CSS_ONLY_STYLE_PROPS.has(propName)) {
7021
- element.style[propName] = String(sanitised);
7022
- continue;
7023
- }
7024
- element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitised);
7025
- }
7026
- if (style) {
7027
- for (const styleProp in style) {
7028
- element.style[styleProp] = String(style[styleProp]);
7029
- }
7030
- }
7031
- if (children) {
7032
- for (const child of children) {
7033
- element.appendChild(child);
7034
- }
7035
- }
7036
- if (textContent) element.textContent = textContent;
7037
- return element;
7038
- }
7039
- function renderNode(node, defs) {
7040
- if (!node) return null;
7041
- const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
7042
- const feFuncType = props.funcType;
7043
- if (feFuncType !== void 0) delete props.funcType;
7044
- const nodeDefs = getDefs(node) || defs;
7045
- const resolvedStyle = resolveStyle(style, nodeDefs);
7046
- let childElements;
7047
- if (children) {
7048
- for (const ch of children) {
7049
- const child = renderNode(ch, nodeDefs);
7050
- if (child) {
7051
- if (!childElements) childElements = [];
7052
- childElements.push(child);
7053
- }
7054
- }
7055
- }
7056
- const element = createElement(
7057
- type || "g",
7058
- getNormalizedProps(props),
7059
- resolvedStyle,
7060
- childElements,
7061
- props[TEXT_ATTR] || props[TEXT_CONTENT_ATTR]
7062
- );
7063
- if (element && feFuncType !== void 0) element.setAttribute("type", feFuncType);
7064
- return element;
7065
- }
7066
7308
  function setupAnimationTriggers(api, config) {
7067
7309
  const { startOn, outAction = "continue", scrollIntoViewThreshold = 0 } = config;
7068
7310
  const root = api.getRootElement();
@@ -7244,10 +7486,12 @@ var PixodeskAnimatorReact = (() => {
7244
7486
  } else if (propName === "d") {
7245
7487
  const paths = value && typeof value === "object" && Array.isArray(value.paths) ? value.paths : [];
7246
7488
  cssValue = 'path("' + paths.map((bz) => bezierToSvgPath(bz, true)).join("") + '")';
7489
+ } else if (PCT_BASED_ATTR_NAMES.has(propName) && typeof value === "number") {
7490
+ cssValue = value * 100 + "%";
7247
7491
  } else {
7248
7492
  cssValue = "" + value;
7249
7493
  }
7250
- if (!CSS.supports(cssKey, cssValue)) unsupportedSet.add(cssKey);
7494
+ if (!CSS.supports(camelCaseToKebabWordIfNeeded(cssKey), cssValue)) unsupportedSet.add(cssKey);
7251
7495
  cssKey = kebabToCamelCaseWord(cssKey);
7252
7496
  cssKf[cssKey] = cssValue;
7253
7497
  return cssKf;
@@ -7324,7 +7568,7 @@ var PixodeskAnimatorReact = (() => {
7324
7568
  console.warn("createFrameLoopAnimator: No root element provided");
7325
7569
  }
7326
7570
  }
7327
- const bindings = getNormalisedBindings(doc, PxAnimatorEngine.webapi);
7571
+ const bindings = getNormalisedBindings(doc, PxAnimatorEngine.waapi);
7328
7572
  const animations = [];
7329
7573
  const _iterations = config.iterations;
7330
7574
  let iterations;
@@ -7469,8 +7713,7 @@ var PixodeskAnimatorReact = (() => {
7469
7713
  }
7470
7714
  return api;
7471
7715
  }
7472
- function createAnimatorFromConfig(doc, adapter, callbacks, rootElement) {
7473
- const animatorConfig = getAnimatorConfig(doc) || {};
7716
+ function finaliseAnimator(animatorConfig, callbacks, make) {
7474
7717
  let apiRef;
7475
7718
  let effectiveCallbacks = callbacks;
7476
7719
  if (animatorConfig.resetOnFinish) {
@@ -7482,29 +7725,92 @@ var PixodeskAnimatorReact = (() => {
7482
7725
  }
7483
7726
  });
7484
7727
  }
7485
- let res;
7486
- if (animatorConfig.mode === PxAnimatorMode.frames) {
7487
- res = createFrameLoopAnimator(doc, adapter, effectiveCallbacks, rootElement);
7488
- } else {
7489
- res = createWebApiAnimator(
7490
- doc,
7491
- effectiveCallbacks,
7492
- rootElement,
7493
- animatorConfig.mode === PxAnimatorMode.webapi
7494
- // forcing webapi
7495
- ) || createFrameLoopAnimator(doc, adapter, effectiveCallbacks, rootElement);
7496
- }
7728
+ const res = make(effectiveCallbacks);
7497
7729
  apiRef = res;
7498
7730
  if (animatorConfig.debugInstName) {
7499
7731
  window[animatorConfig.debugInstName] = res;
7500
7732
  }
7501
7733
  return res;
7502
7734
  }
7735
+ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
7736
+ const animatorConfig = getAnimatorConfig(doc) || {};
7737
+ return finaliseAnimator(animatorConfig, callbacks, (cb) => {
7738
+ if (animatorConfig.mode === PxAnimatorMode.frames) {
7739
+ return createFrameLoopAnimator(doc, adapter, cb, rootElement);
7740
+ }
7741
+ return createWebApiAnimator(
7742
+ doc,
7743
+ cb,
7744
+ rootElement,
7745
+ animatorConfig.mode === PxAnimatorMode.waapi
7746
+ // forcing waapi
7747
+ ) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
7748
+ });
7749
+ }
7750
+ var SVG_NS = "http://www.w3.org/2000/svg";
7751
+ function createElement(tagName, normalisedProps, style, children, textContent) {
7752
+ if (DISALLOWED_SVG_TAGS_LOWER.has(tagName.toLowerCase())) {
7753
+ console.warn("SVG tag blocked (dangerous): ", tagName);
7754
+ return null;
7755
+ }
7756
+ const element = document.createElementNS(SVG_NS, tagName);
7757
+ for (const propName in normalisedProps) {
7758
+ const sanitised = sanitiseAttributeValue(propName, normalisedProps[propName]);
7759
+ if (sanitised === void 0) continue;
7760
+ if (CSS_ONLY_STYLE_PROPS.has(propName)) {
7761
+ element.style[propName] = String(sanitised);
7762
+ continue;
7763
+ }
7764
+ element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitised);
7765
+ }
7766
+ if (style) {
7767
+ for (const styleProp in style) {
7768
+ element.style[styleProp] = String(style[styleProp]);
7769
+ }
7770
+ }
7771
+ if (children) {
7772
+ for (const child of children) {
7773
+ element.appendChild(child);
7774
+ }
7775
+ }
7776
+ if (textContent) element.textContent = textContent;
7777
+ return element;
7778
+ }
7779
+ function renderNode(node, defs) {
7780
+ if (!node) return null;
7781
+ const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
7782
+ const domType = props.domType;
7783
+ if (domType !== void 0) delete props.domType;
7784
+ const nodeDefs = getDefs(node) || defs;
7785
+ const resolvedStyle = resolveStyle(style, nodeDefs);
7786
+ let childElements;
7787
+ if (children) {
7788
+ for (const ch of children) {
7789
+ const child = renderNode(ch, nodeDefs);
7790
+ if (child) {
7791
+ if (!childElements) childElements = [];
7792
+ childElements.push(child);
7793
+ }
7794
+ }
7795
+ }
7796
+ const element = createElement(
7797
+ type || "g",
7798
+ getNormalizedProps(props),
7799
+ resolvedStyle,
7800
+ childElements,
7801
+ props[TEXT_CONTENT_ATTR] || props[TEXT_ATTR]
7802
+ );
7803
+ if (element && domType !== void 0) element.setAttribute("type", domType);
7804
+ return element;
7805
+ }
7806
+ function createAnimatorFromConfig(doc, adapter, callbacks, rootElement) {
7807
+ return bindWithEngineChoice(doc, adapter, callbacks, rootElement);
7808
+ }
7503
7809
  function createAnimatorImpl(doc, adapter, callbacks, containerElement) {
7504
7810
  const effectsWarnings = validateNodeEffects(doc);
7505
7811
  for (const w of effectsWarnings) console.warn("[PxAnimator] effects shape warning:", w);
7506
7812
  const animatorConfig = getAnimatorConfig(doc) || {};
7507
- const engine = animatorConfig.mode === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.webapi;
7813
+ const engine = animatorConfig.mode === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.waapi;
7508
7814
  doc = materialiseAllInTree(doc, engine);
7509
7815
  let rootElement = null;
7510
7816
  if (containerElement) {