pixi-effects 0.26.3 → 0.27.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +12 -10
  3. package/ai/CHAT.md +1 -1
  4. package/ai/chat-template.html +4 -6
  5. package/dist/{Base-CpdDs4HT.d.ts → Base-CKGl6jCo.d.ts} +2 -4
  6. package/dist/{Base-TbBhHPrG.d.cts → Base-DjhdL8B1.d.cts} +2 -4
  7. package/dist/Composition-BJVY5HP7.js +7 -0
  8. package/dist/{Composition-3O7L2VL5.js.map → Composition-BJVY5HP7.js.map} +1 -1
  9. package/dist/Composition-YW2G6EXL.cjs +16 -0
  10. package/dist/{Composition-EE3KEE2L.cjs.map → Composition-YW2G6EXL.cjs.map} +1 -1
  11. package/dist/Controller.d.cts +2 -3
  12. package/dist/Controller.d.ts +2 -3
  13. package/dist/{Movie-BkP82KXS.d.ts → Movie-CbYwTs6U.d.cts} +2 -3
  14. package/dist/{Movie-BWLLWRRe.d.cts → Movie-ILKq2fw_.d.ts} +2 -3
  15. package/dist/Presenter.d.cts +2 -3
  16. package/dist/Presenter.d.ts +2 -3
  17. package/dist/{blendModes-YV43K6E7.cjs → blendModes-HDOP6R7T.cjs} +5 -5
  18. package/dist/{blendModes-YV43K6E7.cjs.map → blendModes-HDOP6R7T.cjs.map} +1 -1
  19. package/dist/{blendModes-G3NOAU3T.js → blendModes-PAVTW3BO.js} +4 -4
  20. package/dist/{blendModes-G3NOAU3T.js.map → blendModes-PAVTW3BO.js.map} +1 -1
  21. package/dist/{chunk-TLYTYBWX.js → chunk-45QKLD6M.js} +9 -11
  22. package/dist/chunk-45QKLD6M.js.map +1 -0
  23. package/dist/{chunk-WMMZDPWK.js → chunk-AR3HVHKF.js} +7 -11
  24. package/dist/chunk-AR3HVHKF.js.map +1 -0
  25. package/dist/{chunk-A225HYSY.cjs → chunk-ETKTRQL2.cjs} +970 -258
  26. package/dist/chunk-ETKTRQL2.cjs.map +1 -0
  27. package/dist/{chunk-3DLYAPK7.cjs → chunk-P4GY3Z4G.cjs} +5 -5
  28. package/dist/{chunk-3DLYAPK7.cjs.map → chunk-P4GY3Z4G.cjs.map} +1 -1
  29. package/dist/{chunk-AXZUKNXF.js → chunk-TYWFKCPY.js} +4 -4
  30. package/dist/{chunk-AXZUKNXF.js.map → chunk-TYWFKCPY.js.map} +1 -1
  31. package/dist/{chunk-IIDBEYQH.cjs → chunk-VH5R473P.cjs} +91 -95
  32. package/dist/chunk-VH5R473P.cjs.map +1 -0
  33. package/dist/{chunk-FXAHNPBP.js → chunk-X42BGR6P.js} +950 -241
  34. package/dist/chunk-X42BGR6P.js.map +1 -0
  35. package/dist/{chunk-ECA2WNRX.cjs → chunk-ZMAD3KJU.cjs} +9 -11
  36. package/dist/chunk-ZMAD3KJU.cjs.map +1 -0
  37. package/dist/index.cjs +102 -105
  38. package/dist/index.cjs.map +1 -1
  39. package/dist/index.d.cts +16 -14
  40. package/dist/index.d.ts +16 -14
  41. package/dist/index.js +48 -33
  42. package/dist/index.js.map +1 -1
  43. package/dist/loader.css +1 -1
  44. package/dist/{music-3O5MDQXY.js → music-JVRNXHQ5.js} +34 -7
  45. package/dist/music-JVRNXHQ5.js.map +1 -0
  46. package/dist/{music-4O367SPR.cjs → music-YPUZTWTN.cjs} +34 -6
  47. package/dist/music-YPUZTWTN.cjs.map +1 -0
  48. package/dist/three.cjs +6 -6
  49. package/dist/three.d.cts +2 -3
  50. package/dist/three.d.ts +2 -3
  51. package/dist/three.js +2 -2
  52. package/dist/{types-DSGwN5w1.d.cts → types-BNVsBBZf.d.cts} +130 -3
  53. package/dist/{types-DSGwN5w1.d.ts → types-BNVsBBZf.d.ts} +130 -3
  54. package/docs/api.md +5 -1
  55. package/docs/dsl.md +13 -15
  56. package/llms-full.txt +24 -22
  57. package/llms.txt +1 -1
  58. package/package.json +4 -5
  59. package/skills/pixi-effects/SKILL.md +1 -1
  60. package/skills/pixi-effects/reference/cheatsheet.md +1 -1
  61. package/skills/pixi-effects/reference/pitfalls.md +3 -3
  62. package/skills/pixi-effects/reference/recipes.md +1 -1
  63. package/skills/pixi-effects/template.html +6 -8
  64. package/dist/Composition-3O7L2VL5.js +0 -7
  65. package/dist/Composition-EE3KEE2L.cjs +0 -16
  66. package/dist/chunk-A225HYSY.cjs.map +0 -1
  67. package/dist/chunk-ECA2WNRX.cjs.map +0 -1
  68. package/dist/chunk-FXAHNPBP.js.map +0 -1
  69. package/dist/chunk-IIDBEYQH.cjs.map +0 -1
  70. package/dist/chunk-TLYTYBWX.js.map +0 -1
  71. package/dist/chunk-WMMZDPWK.js.map +0 -1
  72. package/dist/music-3O5MDQXY.js.map +0 -1
  73. package/dist/music-4O367SPR.cjs.map +0 -1
@@ -1,43 +1,9 @@
1
- import { collectPropKeys, describeLayer } from './chunk-TLYTYBWX.js';
1
+ import { collectPropKeys, describeLayer } from './chunk-45QKLD6M.js';
2
2
  import { suggestName, warnUnknownOptions } from './chunk-BXOCEZ4U.js';
3
3
  import * as PIXI from 'pixi.js';
4
4
  import { Rectangle, Container, Color, GraphicsPath, Sprite, Texture, Graphics, Assets, FillGradient, Text, Filter, GlProgram, defaultFilterVert, GpuProgram, UniformGroup } from 'pixi.js';
5
- import { gsap } from 'gsap';
6
5
 
7
- // src/expr/random.ts
8
- function mix(h) {
9
- h = Math.imul(h ^ h >>> 16, 2246822507);
10
- h = Math.imul(h ^ h >>> 13, 3266489909);
11
- return (h ^ h >>> 16) >>> 0;
12
- }
13
- function fold(n) {
14
- if (!Number.isFinite(n)) return 0;
15
- const i = Math.floor(n);
16
- const f = n - i;
17
- return (i | 0) ^ Math.imul(Math.floor(f * 1048576), 2654435761);
18
- }
19
- function rand(seed) {
20
- return mix(fold(seed) + 2654435769) / 4294967296;
21
- }
22
- function random(seed) {
23
- let a = fold(seed) + 1831565813 | 0;
24
- return () => {
25
- a = a + 1831565813 | 0;
26
- let t = Math.imul(a ^ a >>> 15, 1 | a);
27
- t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
28
- return ((t ^ t >>> 14) >>> 0) / 4294967296;
29
- };
30
- }
31
- function noise(x, seed = 0) {
32
- if (!Number.isFinite(x)) return 0;
33
- const i = Math.floor(x);
34
- const f = x - i;
35
- const s = fold(seed) * 668265261;
36
- const a = mix((i | 0) + s) / 2147483648 - 1;
37
- const b = mix((i + 1 | 0) + s) / 2147483648 - 1;
38
- const u = f * f * f * (f * (f * 6 - 15) + 10);
39
- return a + (b - a) * u;
40
- }
6
+ // src/core/spring.ts
41
7
  var SETTLE_TOL = 5e-3;
42
8
  var DEFAULTS = { mass: 1, stiffness: 100, damping: 10 };
43
9
  function springResponse(t, { mass: m, stiffness: k, damping: c }) {
@@ -119,19 +85,6 @@ function parseSpring(name) {
119
85
  const [mass, stiffness, damping] = (m[2] ?? "").split(",").map((s) => s.trim()).filter(Boolean).map(Number);
120
86
  return complete({ mass, stiffness, damping });
121
87
  }
122
- var registered = false;
123
- function registerSpringEases() {
124
- if (registered) return;
125
- registered = true;
126
- const base = springEase();
127
- const ease = (p) => base(p);
128
- ease.config = (mass, stiffness, damping) => {
129
- const bad = [mass, stiffness, damping].some((v) => v !== void 0 && !(typeof v === "number" && v > 0 && Number.isFinite(v)));
130
- return springEase(bad ? {} : { mass, stiffness, damping });
131
- };
132
- gsap.registerEase("spring", ease);
133
- for (const [name, p] of Object.entries(SPRING_PRESETS)) gsap.registerEase(`spring.${name}`, springEase(p));
134
- }
135
88
  var autoWarned = /* @__PURE__ */ new Set();
136
89
  function kfDuration(kf) {
137
90
  if (kf.duration !== "auto") return kf.duration ?? 0;
@@ -144,7 +97,837 @@ function kfDuration(kf) {
144
97
  }
145
98
  return 0.5;
146
99
  }
147
- registerSpringEases();
100
+
101
+ // src/core/cubicBezier.ts
102
+ function cubicBezierEase(x1, y1, x2, y2) {
103
+ const cx = 3 * x1, bx = 3 * (x2 - x1) - cx, ax = 1 - cx - bx;
104
+ const cy = 3 * y1, by = 3 * (y2 - y1) - cy, ay = 1 - cy - by;
105
+ const X = (t) => ((ax * t + bx) * t + cx) * t;
106
+ const Y = (t) => ((ay * t + by) * t + cy) * t;
107
+ const dX = (t) => (3 * ax * t + 2 * bx) * t + cx;
108
+ return (p) => {
109
+ if (p <= 0) return 0;
110
+ if (p >= 1) return 1;
111
+ let t = p;
112
+ for (let i = 0; i < 8; i++) {
113
+ const err = X(t) - p;
114
+ if (Math.abs(err) < 1e-9) return Y(t);
115
+ const d = dX(t);
116
+ if (Math.abs(d) < 1e-6) break;
117
+ t -= err / d;
118
+ }
119
+ let lo = 0, hi = 1;
120
+ t = p;
121
+ for (let i = 0; i < 60; i++) {
122
+ const x = X(t);
123
+ if (Math.abs(x - p) < 1e-10) break;
124
+ if (x < p) lo = t;
125
+ else hi = t;
126
+ t = (lo + hi) / 2;
127
+ }
128
+ return Y(t);
129
+ };
130
+ }
131
+ var NUM = String.raw`\s*(-?(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)\s*`;
132
+ var RE = new RegExp(`^\\s*cubic-bezier\\(${NUM},${NUM},${NUM},${NUM}\\)\\s*$`, "i");
133
+ function parseCubicBezier(name) {
134
+ const m = RE.exec(name);
135
+ return m && !cubicBezierProblem(name) ? [Number(m[1]), Number(m[2]), Number(m[3]), Number(m[4])] : null;
136
+ }
137
+ function cubicBezierProblem(name) {
138
+ const m = RE.exec(name);
139
+ if (!m) return 'expected "cubic-bezier(x1, y1, x2, y2)" with four numbers, like CSS';
140
+ const x1 = Number(m[1]), x2 = Number(m[3]);
141
+ if (x1 < 0 || x1 > 1 || x2 < 0 || x2 > 1) return "x1 and x2 must be between 0 and 1 (y1 and y2 may overshoot)";
142
+ return null;
143
+ }
144
+
145
+ // src/core/pure/ease.ts
146
+ var PI = Math.PI;
147
+ var power = (strength) => ({
148
+ in: (p) => Math.pow(p, strength),
149
+ out: (p) => 1 - Math.pow(1 - p, strength),
150
+ inOut: (p) => p < 0.5 ? 0.5 * Math.pow(2 * p, strength) : 1 - 0.5 * Math.pow(2 * (1 - p), strength)
151
+ });
152
+ var fromOut = (out) => ({
153
+ in: (p) => 1 - out(1 - p),
154
+ out,
155
+ inOut: (p) => p < 0.5 ? 0.5 * (1 - out(1 - 2 * p)) : 0.5 + 0.5 * out(2 * p - 1)
156
+ });
157
+ var mirrored = (easeIn) => ({
158
+ in: easeIn,
159
+ out: (p) => 1 - easeIn(1 - p),
160
+ inOut: (p) => p < 0.5 ? easeIn(p * 2) / 2 : 1 - easeIn((1 - p) * 2) / 2
161
+ });
162
+ var sine = mirrored((p) => p === 1 ? 1 : -Math.cos(p * PI / 2) + 1);
163
+ var circ = mirrored((p) => -(Math.sqrt(1 - p * p) - 1));
164
+ var expoIn = (p) => Math.pow(2, 10 * (p - 1)) * p + p * p * p * p * p * p * (1 - p);
165
+ var expo = {
166
+ in: expoIn,
167
+ out: (p) => 1 - expoIn(1 - p),
168
+ inOut: (p) => p < 0.5 ? expoIn(p * 2) / 2 : 1 - expoIn((1 - p) * 2) / 2
169
+ };
170
+ var bounceOut = (p) => {
171
+ if (p < 1 / 2.75) return 7.5625 * p * p;
172
+ if (p < 2 / 2.75) {
173
+ p -= 1.5 / 2.75;
174
+ return 7.5625 * p * p + 0.75;
175
+ }
176
+ if (p < 2.5 / 2.75) {
177
+ p -= 2.25 / 2.75;
178
+ return 7.5625 * p * p + 0.9375;
179
+ }
180
+ p -= 2.625 / 2.75;
181
+ return 7.5625 * p * p + 0.984375;
182
+ };
183
+ var bounce = fromOut(bounceOut);
184
+ function back(s = 1.70158) {
185
+ const out = (p) => p ? (p -= 1, p * p * ((s + 1) * p + s) + 1) : 0;
186
+ return fromOut(out);
187
+ }
188
+ function elastic(amplitude, period) {
189
+ const make = (per0) => {
190
+ const amp = amplitude ?? 1;
191
+ const a = amp >= 1 ? amp : 1;
192
+ const per = per0 / (amp < 1 ? amp : 1);
193
+ const s = per / (2 * PI) * Math.asin(1 / a);
194
+ const k = 2 * PI / per;
195
+ return fromOut((p) => p === 0 ? 0 : p === 1 ? 1 : a * Math.pow(2, -10 * p) * Math.sin((p - s) * k) + 1);
196
+ };
197
+ const usual = make(period ?? 0.3);
198
+ return { in: usual.in, out: usual.out, inOut: period === void 0 ? make(0.45).inOut : usual.inOut };
199
+ }
200
+ function steps(n) {
201
+ const count = Math.max(1, Math.floor(n) || 1);
202
+ return (p) => p <= 0 ? 0 : p >= 1 ? 1 : Math.min(1, Math.floor(p * (count + 1)) / count);
203
+ }
204
+ var FAMILY = {
205
+ power1: () => power(2),
206
+ power2: () => power(3),
207
+ power3: () => power(4),
208
+ power4: () => power(5),
209
+ quad: () => power(2),
210
+ cubic: () => power(3),
211
+ quart: () => power(4),
212
+ quint: () => power(5),
213
+ strong: () => power(5),
214
+ sine: () => sine,
215
+ circ: () => circ,
216
+ expo: () => expo,
217
+ bounce: () => bounce,
218
+ back: (a) => back(a[0]),
219
+ elastic: (a) => elastic(a[0], a[1])
220
+ };
221
+ var LINEAR = (p) => p;
222
+ var DEFAULT = power(2).out;
223
+ var cache = /* @__PURE__ */ new Map();
224
+ function lookup(name) {
225
+ let hit = cache.get(name);
226
+ if (hit === void 0) {
227
+ hit = parse(name.trim());
228
+ cache.set(name, hit);
229
+ }
230
+ return hit;
231
+ }
232
+ function pureEase(name) {
233
+ return (typeof name === "string" ? lookup(name) : null) ?? DEFAULT;
234
+ }
235
+ function isEaseName(name) {
236
+ return typeof name === "string" && lookup(name) !== null;
237
+ }
238
+ function parse(raw) {
239
+ const s = raw.toLowerCase();
240
+ if (s === "none" || s === "linear" || s === "linear.easenone") return LINEAR;
241
+ if (/^spring/.test(s)) {
242
+ const sp = parseSpring(raw);
243
+ return sp ? springEase(sp) : null;
244
+ }
245
+ if (/^cubic-bezier/.test(s)) {
246
+ const c = parseCubicBezier(raw);
247
+ return c ? cubicBezierEase(...c) : LINEAR;
248
+ }
249
+ const st = /^steps\(\s*([^)]*)\)$/.exec(s);
250
+ if (st) return steps(Number(st[1]));
251
+ if (/^[a-z][a-z0-9]*$/.test(raw) && FAMILY[raw]) return FAMILY[raw]([]).out;
252
+ const m = /^([a-z0-9]+)\.(?:ease)?(in|out|inout)(?:\(([^)]*)\))?$/.exec(s);
253
+ if (!m) return null;
254
+ const make = FAMILY[m[1]];
255
+ if (!make) return null;
256
+ const args = (m[3] ?? "").split(",").map((x) => x.trim()).filter(Boolean).map(Number).filter((n) => Number.isFinite(n));
257
+ const trio = make(args);
258
+ return m[2] === "in" ? trio.in : m[2] === "out" ? trio.out : trio.inOut;
259
+ }
260
+
261
+ // src/core/pure/colorLerp.ts
262
+ function parseCssColor(s) {
263
+ const v = s.trim();
264
+ let m = /^#([0-9a-f]{3,4})$/i.exec(v);
265
+ if (m) {
266
+ const h = m[1];
267
+ const d = (i) => parseInt(h[i] + h[i], 16);
268
+ return [d(0), d(1), d(2), h.length === 4 ? d(3) / 255 : 1];
269
+ }
270
+ m = /^#([0-9a-f]{6})([0-9a-f]{2})?$/i.exec(v);
271
+ if (m) {
272
+ const n = parseInt(m[1], 16);
273
+ return [n >> 16 & 255, n >> 8 & 255, n & 255, m[2] ? parseInt(m[2], 16) / 255 : 1];
274
+ }
275
+ m = /^rgba?\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*(?:,\s*(-?[\d.]+)\s*)?\)$/i.exec(v);
276
+ if (m) return [Number(m[1]), Number(m[2]), Number(m[3]), m[4] === void 0 ? 1 : Number(m[4])];
277
+ return null;
278
+ }
279
+ function rgbInterp(a, b, fallback = () => null) {
280
+ const ca = parseCssColor(a) ?? fallback(a), cb = parseCssColor(b) ?? fallback(b);
281
+ if (!ca || !cb) return (p) => p >= 1 ? b : a;
282
+ return (p) => {
283
+ if (p === 0) return a;
284
+ if (p === 1) return b;
285
+ const ch = (i) => Math.round(ca[i] + (cb[i] - ca[i]) * p);
286
+ const al = Math.round((ca[3] + (cb[3] - ca[3]) * p) * 1e4) / 1e4;
287
+ return `rgba(${ch(0)},${ch(1)},${ch(2)},${al})`;
288
+ };
289
+ }
290
+
291
+ // src/core/pure/props.ts
292
+ var DEG = Math.PI / 180;
293
+ var num = (obj, key, id, unit = 1) => ({
294
+ id,
295
+ kind: "num",
296
+ unit,
297
+ round: 1e6,
298
+ get: () => Number(obj()?.[key]),
299
+ set: (v) => {
300
+ const o = obj();
301
+ if (o) o[key] = v;
302
+ }
303
+ });
304
+ function xy(target, base, which, unit = 1) {
305
+ const o = () => target[base];
306
+ const ax = num(o, "x", `${base}.x`, unit), ay = num(o, "y", `${base}.y`, unit);
307
+ return which === "x" ? [ax] : which === "y" ? [ay] : [ax, ay];
308
+ }
309
+ var VEC = [
310
+ ["scale", "scale", 1],
311
+ ["anchor", "anchor", 1],
312
+ ["pivot", "pivot", 1],
313
+ ["skew", "skew", DEG],
314
+ ["position", "position", 1],
315
+ ["tilePosition", "tilePosition", 1],
316
+ ["tileScale", "tileScale", 1]
317
+ ];
318
+ var PIXI_INERT = /* @__PURE__ */ new Set(["fillColor", "fillAlpha"]);
319
+ function pixiAccessors(target, key) {
320
+ for (const [name, base, unit] of VEC) {
321
+ if (key === name) return xy(target, base, "both", unit);
322
+ if (key === `${name}X`) return xy(target, base, "x", unit);
323
+ if (key === `${name}Y`) return xy(target, base, "y", unit);
324
+ }
325
+ switch (key) {
326
+ case "rotation":
327
+ return [{ id: "rotation", kind: "num", unit: DEG, round: 1e5, exactEnd: true, get: () => Number(target.rotation), set: (v) => {
328
+ target.rotation = v;
329
+ } }];
330
+ case "tint":
331
+ return [{ id: "tint", kind: "color", unit: 1, round: 1, get: () => Number(target.tint), set: (v) => {
332
+ target.tint = v;
333
+ } }];
334
+ case "autoAlpha":
335
+ return [
336
+ { id: "alpha", kind: "num", unit: 1, round: 1e6, get: () => Number(target.alpha), set: (v) => {
337
+ target.alpha = v;
338
+ } },
339
+ // `visible` follows the autoAlpha tweens only, not a plain `alpha` tween on the same layer: a channel of its own
340
+ { id: "visible#auto", kind: "num", unit: 1, round: 1e6, always: true, get: () => Number(target.alpha), set: (v) => {
341
+ target.visible = v !== 0;
342
+ } }
343
+ ];
344
+ default:
345
+ return null;
346
+ }
347
+ }
348
+ function rawAccessor(target, key) {
349
+ return { id: key, kind: "raw", unit: 1, round: 1, get: () => target[key], set: (v) => {
350
+ target[key] = v;
351
+ } };
352
+ }
353
+ function cssAccessor(target, key) {
354
+ return { id: key, kind: "css", unit: 1, round: 1, get: () => target[key], set: (v) => {
355
+ target[key] = v;
356
+ } };
357
+ }
358
+ function plainAccessor(target, key) {
359
+ return { id: key, kind: "num", unit: 1, round: 1e6, get: () => Number(target[key]), set: (v) => {
360
+ target[key] = v;
361
+ } };
362
+ }
363
+ function parseColor(v) {
364
+ if (typeof v === "number") return v;
365
+ if (typeof v !== "string") return null;
366
+ const s = v.trim();
367
+ let m = /^#([0-9a-f]{3})$/i.exec(s);
368
+ if (m) {
369
+ const h = m[1];
370
+ return parseInt(h[0] + h[0] + h[1] + h[1] + h[2] + h[2], 16);
371
+ }
372
+ m = /^#([0-9a-f]{6})(?:[0-9a-f]{2})?$/i.exec(s);
373
+ if (m) return parseInt(m[1], 16);
374
+ m = /^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i.exec(s);
375
+ if (m) return Number(m[1]) << 16 | Number(m[2]) << 8 | Number(m[3]);
376
+ return null;
377
+ }
378
+ function lerpColor(from, to, p) {
379
+ const r = lerpByte(from >> 16 & 255, to >> 16 & 255, p);
380
+ const g = lerpByte(from >> 8 & 255, to >> 8 & 255, p);
381
+ const b = lerpByte(from & 255, to & 255, p);
382
+ return r << 16 | g << 8 | b;
383
+ }
384
+ function lerpByte(a, b, p) {
385
+ return Math.trunc(a + (b - a) * p);
386
+ }
387
+
388
+ // src/core/pure/PureTimeline.ts
389
+ var quantize = (x) => Math.round(x * 1e7) / 1e7 || 0;
390
+ var TINY = 1e-8;
391
+ var spacer = (duration) => ({ spacer: true, duration });
392
+ var parseRel = (v) => {
393
+ if (typeof v === "number") return { rel: false, n: v };
394
+ if (typeof v === "string") {
395
+ const m = /^([+-])=\s*(-?\d*\.?\d+(?:e[+-]?\d+)?)$/i.exec(v.trim());
396
+ if (m) return { rel: true, n: (m[1] === "-" ? -1 : 1) * parseFloat(m[2]) };
397
+ const n = parseFloat(v);
398
+ if (Number.isFinite(n) && String(n) === v.trim()) return { rel: false, n };
399
+ }
400
+ return null;
401
+ };
402
+ var RESERVED = /* @__PURE__ */ new Set(["duration", "ease", "repeat", "yoyo", "repeatDelay", "onUpdate", "delay"]);
403
+ var CALLBACKS = ["onStart", "onComplete", "onRepeat", "onReverseComplete"];
404
+ var saidCallbacks = false;
405
+ var PureTimeline = class _PureTimeline {
406
+ defaultEase;
407
+ channels = /* @__PURE__ */ new Map();
408
+ channelList = [];
409
+ children = [];
410
+ spans = 0;
411
+ now = 0;
412
+ order = 0;
413
+ killed = false;
414
+ prepared = false;
415
+ constructor(opts = {}) {
416
+ this.defaultEase = opts.defaults?.ease ?? "none";
417
+ }
418
+ // --- building ------------------------------------------------------------------------------------------
419
+ /** Adds a child timeline (played with its local time) or a spacer that lengthens this one. */
420
+ add(child, at) {
421
+ const start = at ?? this.spans;
422
+ if ("spacer" in child) {
423
+ this.spans = Math.max(this.spans, start + child.duration);
424
+ } else if (!(child instanceof _PureTimeline)) {
425
+ this.spans = Math.max(this.spans, start + child.duration());
426
+ } else {
427
+ this.children.push({ child, start: quantize(start), order: this.order++, exclusive: false, last: NaN });
428
+ this.prepared = false;
429
+ this.spans = Math.max(this.spans, start + child.duration());
430
+ }
431
+ return this;
432
+ }
433
+ set(target, vars, at) {
434
+ return this.build(target, null, { ...vars, duration: 0 }, at, "set");
435
+ }
436
+ to(target, vars, at) {
437
+ return this.build(target, null, vars, at, "to");
438
+ }
439
+ from(target, vars, at) {
440
+ return this.build(target, null, vars, at, "from");
441
+ }
442
+ fromTo(target, fromVars, toVars, at) {
443
+ return this.build(target, fromVars, toVars, at, "fromTo");
444
+ }
445
+ build(target, fromVars, vars, at, kind) {
446
+ const t = target;
447
+ const start = quantize((at ?? this.spans) + (Number(vars.delay) || 0));
448
+ const dur = quantize(Math.max(0, vars.duration ?? 0));
449
+ for (const cb of CALLBACKS) if (cb in vars) {
450
+ if (!saidCallbacks) {
451
+ saidCallbacks = true;
452
+ console.warn(`pixi-effects: the timeline does not run ${cb}: what a tween does must be a value of the time (use onUpdate for a redraw); it is ignored`);
453
+ }
454
+ }
455
+ const repeat = Math.max(0, Math.floor(vars.repeat ?? 0));
456
+ const yoyo = !!vars.yoyo;
457
+ const repeatDelay = Math.max(0, vars.repeatDelay ?? 0);
458
+ const easeName = vars.ease ?? this.defaultEase;
459
+ const ease = typeof easeName === "function" ? easeName : pureEase(easeName);
460
+ const given = (v) => {
461
+ const out = /* @__PURE__ */ new Map();
462
+ for (const key of Object.keys(v)) {
463
+ if (RESERVED.has(key) || key === "pixi" || CALLBACKS.includes(key)) continue;
464
+ const value = v[key];
465
+ const acc = parseRel(value) ? plainAccessor(t, key) : typeof value === "string" && parseCssColor(value) ? cssAccessor(t, key) : rawAccessor(t, key);
466
+ out.set(acc.id, { acc, value });
467
+ }
468
+ if (v.pixi) for (const key of Object.keys(v.pixi)) {
469
+ const accs = pixiAccessors(t, key);
470
+ if (!accs) {
471
+ if (!PIXI_INERT.has(key)) console.warn(`pixi-effects: the timeline has no "${key}" shorthand yet; it is ignored`);
472
+ continue;
473
+ }
474
+ for (const acc of accs) out.set(acc.id, { acc, value: v.pixi[key] });
475
+ }
476
+ return out;
477
+ };
478
+ const ends = given(vars);
479
+ const starts = fromVars ? given(fromVars) : /* @__PURE__ */ new Map();
480
+ const ids = kind === "fromTo" ? [.../* @__PURE__ */ new Set([...starts.keys(), ...ends.keys()])] : [...ends.keys()];
481
+ let lastAlpha;
482
+ for (const id of ids) {
483
+ const e = ends.get(id), f = starts.get(id);
484
+ const acc = (e ?? f).acc;
485
+ const ch = this.channel(t, acc);
486
+ const cur = acc.get();
487
+ const color = acc.kind === "color";
488
+ const endSpec = e ? read(e.value, acc) : null;
489
+ if (e && !endSpec && acc.kind === "color") console.warn(`pixi-effects: the timeline cannot read the colour ${JSON.stringify(e.value)} (use #rgb, #rrggbb, rgb(...) or a number); this tween is skipped`);
490
+ const fromSpec = f ? read(f.value, acc) : null;
491
+ let from = null, to, toRel = false;
492
+ if (kind === "from") {
493
+ const g = endSpec ?? { rel: false, n: cur };
494
+ from = g.rel ? cur + g.n : g.n;
495
+ to = cur;
496
+ acc.set(from);
497
+ } else if (kind === "fromTo") {
498
+ if (fromSpec) from = fromSpec.rel ? cur + fromSpec.n : fromSpec.n;
499
+ if (endSpec) {
500
+ to = endSpec.n;
501
+ toRel = endSpec.rel;
502
+ } else to = cur;
503
+ if (from !== null) acc.set(from);
504
+ } else {
505
+ if (!endSpec) continue;
506
+ to = endSpec.n;
507
+ toRel = endSpec.rel;
508
+ }
509
+ if (color && toRel) toRel = false;
510
+ const seg = {
511
+ channel: ch,
512
+ kind,
513
+ createCur: cur,
514
+ start,
515
+ dur,
516
+ ease,
517
+ repeat,
518
+ yoyo,
519
+ repeatDelay,
520
+ from,
521
+ to,
522
+ toRel,
523
+ from0: from,
524
+ to0: to,
525
+ toRel0: toRel,
526
+ onUpdate: vars.onUpdate,
527
+ order: this.order++
528
+ };
529
+ if (id === "visible#auto") seg.partner = lastAlpha;
530
+ else if (id === "alpha") lastAlpha = seg;
531
+ ch.segs.push(seg);
532
+ ch.dirty = true;
533
+ this.prepared = false;
534
+ }
535
+ const total = dur * (repeat + 1) + repeatDelay * repeat;
536
+ this.spans = Math.max(this.spans, start + total);
537
+ return this;
538
+ }
539
+ channel(target, acc) {
540
+ let m = this.channels.get(target);
541
+ if (!m) this.channels.set(target, m = /* @__PURE__ */ new Map());
542
+ let ch = m.get(acc.id);
543
+ if (!ch) {
544
+ ch = { target, acc, pre: NaN, last: NaN, segs: [], dirty: false };
545
+ m.set(acc.id, ch);
546
+ this.channelList.push(ch);
547
+ }
548
+ return ch;
549
+ }
550
+ /**
551
+ * A property moved by a function of the caller (a colour in OKLab, a gradient): `to` and `from` say how to get the two ends from
552
+ * the value before the segment, `make` the interpolator between them. The value is only written while the segment is the last
553
+ * one that has started, so nothing is read or kept between two frames.
554
+ */
555
+ tweenValue(spec) {
556
+ const acc = { id: spec.id, kind: "fn", unit: 1, round: 1, get: spec.get, set: spec.set, make: spec.make };
557
+ const ch = this.channel(spec.holder, acc);
558
+ const start = quantize(spec.at);
559
+ const dur = quantize(Math.max(0, spec.duration));
560
+ const repeat = Math.max(0, Math.floor(spec.repeat ?? 0));
561
+ const repeatDelay = Math.max(0, spec.repeatDelay ?? 0);
562
+ const ease = typeof spec.ease === "function" ? spec.ease : pureEase(spec.ease);
563
+ ch.segs.push({
564
+ channel: ch,
565
+ kind: "to",
566
+ createCur: null,
567
+ start,
568
+ dur,
569
+ ease,
570
+ repeat,
571
+ yoyo: !!spec.yoyo,
572
+ repeatDelay,
573
+ from: null,
574
+ to: null,
575
+ toRel: false,
576
+ from0: null,
577
+ to0: null,
578
+ toRel0: false,
579
+ order: this.order++,
580
+ fnFrom: spec.from,
581
+ fnTo: spec.to,
582
+ fnMake: spec.make,
583
+ write: spec.set
584
+ });
585
+ ch.dirty = true;
586
+ this.prepared = false;
587
+ this.spans = Math.max(this.spans, start + dur * (repeat + 1) + repeatDelay * repeat);
588
+ return this;
589
+ }
590
+ /**
591
+ * A write that is undone when time goes back before it: the property is `value` from `at` on, and what it was before otherwise.
592
+ * `holder` and `id` name the property, so a set and the tweens of the same property are one channel; `write` is the way the caller
593
+ * writes it (it may do more than assign: redraw), and runs again whenever this set is what the property shows.
594
+ */
595
+ setValue(holder, id, at, read2, write2, value) {
596
+ const acc = { id, kind: typeof value === "number" ? "num" : "raw", unit: 1, round: 1e6, get: read2, set: write2 };
597
+ const ch = this.channel(holder, acc);
598
+ ch.segs.push({
599
+ channel: ch,
600
+ kind: "set",
601
+ createCur: null,
602
+ start: quantize(at),
603
+ dur: 0,
604
+ ease: pureEase("none"),
605
+ repeat: 0,
606
+ yoyo: false,
607
+ repeatDelay: 0,
608
+ from: null,
609
+ to: value,
610
+ toRel: false,
611
+ from0: null,
612
+ to0: value,
613
+ toRel0: false,
614
+ order: this.order++,
615
+ step: true,
616
+ write: write2,
617
+ onUpdate: () => write2(read2())
618
+ });
619
+ ch.dirty = true;
620
+ this.prepared = false;
621
+ this.spans = Math.max(this.spans, quantize(at));
622
+ return this;
623
+ }
624
+ // --- reading -------------------------------------------------------------------------------------------
625
+ /** What the timeline will write, for tools and tests: every segment of this timeline and of the ones under it, starts in this timeline's time. */
626
+ segments(offset = 0) {
627
+ const out = [];
628
+ for (const ch of this.channelList) {
629
+ for (const s of ch.segs) {
630
+ out.push({ target: ch.target, id: ch.acc.id, start: s.start + offset, duration: s.dur, repeat: s.repeat, yoyo: s.yoyo, repeatDelay: s.repeatDelay, kind: s.step ? "set" : s.kind });
631
+ }
632
+ }
633
+ for (const c of this.children) out.push(...c.child.segments(offset + c.start));
634
+ return out;
635
+ }
636
+ /** How many timelines are directly under this one. */
637
+ timelines() {
638
+ return this.children.length;
639
+ }
640
+ duration() {
641
+ return this.spans;
642
+ }
643
+ time(value) {
644
+ if (value === void 0) return this.now;
645
+ if (this.killed) return this;
646
+ this.now = value;
647
+ if (!this.prepared) {
648
+ this.prepareDeep();
649
+ const counts = /* @__PURE__ */ new Map();
650
+ this.countChannels(counts);
651
+ this.markExclusive(counts);
652
+ }
653
+ this.evaluate(quantize(value));
654
+ return this;
655
+ }
656
+ /** GSAP's name for `time(t)`. */
657
+ seek(t) {
658
+ return this.time(t);
659
+ }
660
+ progress(p) {
661
+ if (p === void 0) return this.spans > 0 ? this.now / this.spans : 0;
662
+ return this.time(p * this.spans);
663
+ }
664
+ kill() {
665
+ this.killed = true;
666
+ this.channels.clear();
667
+ this.channelList.length = 0;
668
+ this.children.length = 0;
669
+ }
670
+ // --- evaluation ----------------------------------------------------------------------------------------
671
+ /**
672
+ * What GSAP ended up with once it had been played to the end and back (what Movie used to do at build), as rules that depend
673
+ * on the segments of a property only:
674
+ * - a `from` / `fromTo` shows its start from the moment it is built, so a `to` that comes first starts at the start of the
675
+ * `from` built last, else at the property's own value;
676
+ * - a `to` (and a `set`) starts where the segment before it ended;
677
+ * - a `from` ends where the segment before it ended, or, with none before, where the property was when it was built;
678
+ * - before the first segment the property shows that segment's start.
679
+ */
680
+ prepare(ch) {
681
+ if (!ch.dirty) return;
682
+ ch.segs.sort((a, b) => a.start - b.start || a.order - b.order);
683
+ ch.dirty = false;
684
+ let latest = null;
685
+ for (const s of ch.segs) if ((s.kind === "from" || s.kind === "fromTo") && s.from0 !== null && (!latest || s.order > latest.order)) latest = s;
686
+ ch.base0 ??= { v: ch.acc.get() };
687
+ let cur = latest ? latest.from0 : ch.base0.v;
688
+ const base = cur;
689
+ let first = true;
690
+ for (const s of ch.segs) {
691
+ const before = cur;
692
+ s.from = s.from0;
693
+ s.to = s.to0;
694
+ s.toRel = s.toRel0;
695
+ if (s.fnTo) {
696
+ s.from = s.fnFrom ? s.fnFrom(cur) : cur;
697
+ s.to = s.fnTo(s.from, before, base);
698
+ s.interp = void 0;
699
+ } else {
700
+ if (s.partner) {
701
+ s.from = s.partner.from;
702
+ s.to = s.partner.to;
703
+ }
704
+ if (s.from === null) s.from = cur;
705
+ if (s.kind === "from") s.to = first ? s.createCur : cur;
706
+ if (s.toRel) {
707
+ s.to = s.from + s.to;
708
+ s.toRel = false;
709
+ }
710
+ }
711
+ if (first) ch.pre = s.fnTo ? before : s.from;
712
+ cur = endValue(s);
713
+ first = false;
714
+ }
715
+ }
716
+ /** Every channel of this timeline and of its children reads the property it starts from before any of them writes. */
717
+ prepareDeep() {
718
+ if (this.prepared) return;
719
+ this.prepared = true;
720
+ for (const ch of this.channelList) this.prepare(ch);
721
+ this.children.sort((a, b) => a.start - b.start || a.order - b.order);
722
+ for (const c of this.children) {
723
+ c.last = NaN;
724
+ c.child.prepareDeep();
725
+ }
726
+ }
727
+ /** How many channels write each (target, property) in this timeline and everything under it. */
728
+ countChannels(into) {
729
+ for (const ch of this.channelList) {
730
+ let m = into.get(ch.target);
731
+ if (!m) into.set(ch.target, m = /* @__PURE__ */ new Map());
732
+ m.set(ch.acc.id, (m.get(ch.acc.id) ?? 0) + 1);
733
+ }
734
+ for (const c of this.children) c.child.countChannels(into);
735
+ }
736
+ isExclusive(counts) {
737
+ for (const ch of this.channelList) if ((counts.get(ch.target)?.get(ch.acc.id) ?? 0) > 1) return false;
738
+ return this.children.every((c) => c.child.isExclusive(counts));
739
+ }
740
+ markExclusive(counts) {
741
+ for (const c of this.children) {
742
+ c.exclusive = c.child.isExclusive(counts);
743
+ c.child.markExclusive(counts);
744
+ }
745
+ }
746
+ evaluate(t) {
747
+ this.prepareDeep();
748
+ for (const ch of this.channelList) {
749
+ const segs = ch.segs;
750
+ let lo = 0, hi = segs.length;
751
+ while (lo < hi) {
752
+ const mid = lo + hi >> 1;
753
+ if (segs[mid].start <= t + TINY) lo = mid + 1;
754
+ else hi = mid;
755
+ }
756
+ let k = lo - 1;
757
+ while (k >= 0 && segs[k].repeat > 0 && t - segs[k].start <= TINY) k--;
758
+ const seg = k >= 0 ? segs[k] : null;
759
+ if (!seg) {
760
+ const pre = settle(ch.acc, ch.pre);
761
+ write(ch, segs[0], pre);
762
+ const head = segs[0];
763
+ if (pre !== ch.last) {
764
+ ch.last = pre;
765
+ head?.onUpdate?.();
766
+ }
767
+ continue;
768
+ }
769
+ const v = mix(seg, ratioAt(seg, t), over);
770
+ write(ch, seg, v);
771
+ if (v !== ch.last) {
772
+ ch.last = v;
773
+ seg.onUpdate?.();
774
+ }
775
+ }
776
+ for (const c of this.children) {
777
+ const local = Math.min(Math.max(t - c.start, 0), c.child.duration());
778
+ if (c.exclusive && local === c.last) continue;
779
+ c.last = local;
780
+ c.child.now = local;
781
+ c.child.evaluate(quantize(local));
782
+ }
783
+ }
784
+ };
785
+ function write(ch, seg, v) {
786
+ if (!ch.acc.always && ch.acc.get() === v) return;
787
+ (seg?.write ?? ch.acc.set)(v);
788
+ }
789
+ function endValue(s) {
790
+ if (s.dur === 0 && s.repeat === 0) return s.to;
791
+ return s.yoyo && s.repeat % 2 === 1 ? s.from : s.to;
792
+ }
793
+ function read(value, acc) {
794
+ if (acc.kind === "raw" || acc.kind === "css") return { rel: false, n: value };
795
+ if (acc.kind === "color") {
796
+ const c = parseColor(value);
797
+ return c === null ? null : { rel: false, n: c };
798
+ }
799
+ const r = parseRel(value);
800
+ return r ? { rel: r.rel, n: r.n * acc.unit } : null;
801
+ }
802
+ function settle(acc, v) {
803
+ return acc.kind !== "num" ? v : Math.round(v * acc.round) / acc.round;
804
+ }
805
+ var over = false;
806
+ function mix(s, r, ended) {
807
+ const acc = s.channel.acc;
808
+ if (s.step) return s.to;
809
+ if (s.fnMake) {
810
+ const interp = s.interp ??= s.fnMake(s.from, s.to);
811
+ return interp(Math.round(r * 1e6) / 1e6);
812
+ }
813
+ if (acc.kind === "raw") return s.to;
814
+ if (acc.kind === "css") return (s.interp ??= rgbInterp(String(s.from), String(s.to)))(r);
815
+ if (acc.kind === "color") return ended ? endValue(s) : lerpColor(s.from, s.to, r);
816
+ if ((ended || r === 1) && acc.exactEnd) return endValue(s);
817
+ const k = acc.round;
818
+ return Math.round((s.from + (s.to - s.from) * r) * k) / k;
819
+ }
820
+ function ratioAt(s, t) {
821
+ const lt = t - s.start;
822
+ over = true;
823
+ if (s.dur === 0) return 1;
824
+ const total = s.dur * (s.repeat + 1) + s.repeatDelay * s.repeat;
825
+ if (quantize(lt) >= quantize(total) - TINY) return endRatio(s);
826
+ over = false;
827
+ let i = 0;
828
+ let within = lt;
829
+ if (s.repeat > 0) {
830
+ const period = s.dur + s.repeatDelay;
831
+ const q = quantize(lt);
832
+ i = Math.min(s.repeat, Math.max(0, Math.floor(lt / period)));
833
+ while (i > 0 && q <= quantize(i * period)) i--;
834
+ while (i < s.repeat && q > quantize((i + 1) * period)) i++;
835
+ within = quantize(lt - i * period);
836
+ }
837
+ let p = within >= s.dur ? 1 : within <= 0 ? 0 : within / s.dur;
838
+ if (s.yoyo && i % 2 === 1) p = 1 - p;
839
+ return s.ease(p);
840
+ }
841
+ function endRatio(s) {
842
+ return s.yoyo && s.repeat % 2 === 1 ? 0 : 1;
843
+ }
844
+
845
+ // src/core/timelineEngine.ts
846
+ function createTimeline(opts = {}) {
847
+ return new PureTimeline({ paused: opts.paused, defaults: { ease: opts.defaults?.ease ?? "power1.out" } });
848
+ }
849
+ function lengthen(timeline, duration) {
850
+ timeline.add(spacer(duration));
851
+ }
852
+ function parseEase(name) {
853
+ return pureEase(name);
854
+ }
855
+ function setNow(target, vars) {
856
+ const t = target;
857
+ for (const key of Object.keys(vars)) {
858
+ if (key === "pixi") {
859
+ for (const k of Object.keys(vars.pixi)) {
860
+ const accs = pixiAccessors(t, k);
861
+ if (!accs) {
862
+ if (!PIXI_INERT.has(k)) console.warn(`pixi-effects: "${k}" is not a property a keyframe or initial can set; it is ignored`);
863
+ continue;
864
+ }
865
+ const raw = vars.pixi[k];
866
+ for (const acc of accs) {
867
+ const n = acc.kind === "color" ? colorNumber(raw) : Number(raw) * acc.unit;
868
+ if (!Number.isNaN(n)) acc.set(n);
869
+ }
870
+ }
871
+ } else {
872
+ const v = vars[key];
873
+ plainAccessor(t, key).set(typeof v === "number" ? Math.round(v * 1e6) / 1e6 : v);
874
+ }
875
+ }
876
+ }
877
+ function colorNumber(v) {
878
+ const c = parseColor(v);
879
+ if (c === null) {
880
+ console.warn(`pixi-effects: cannot read the colour ${JSON.stringify(v)} (use #rgb, #rrggbb, rgb(...) or a number); it is left as it was`);
881
+ return NaN;
882
+ }
883
+ return c;
884
+ }
885
+ function viaPixi(s) {
886
+ try {
887
+ const [r, g, b, a] = new Color(s).toArray();
888
+ return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), a];
889
+ } catch {
890
+ return null;
891
+ }
892
+ }
893
+ function interpolateColors(a, b) {
894
+ return rgbInterp(a, b, viaPixi);
895
+ }
896
+
897
+ // src/expr/random.ts
898
+ function mix2(h) {
899
+ h = Math.imul(h ^ h >>> 16, 2246822507);
900
+ h = Math.imul(h ^ h >>> 13, 3266489909);
901
+ return (h ^ h >>> 16) >>> 0;
902
+ }
903
+ function fold(n) {
904
+ if (!Number.isFinite(n)) return 0;
905
+ const i = Math.floor(n);
906
+ const f = n - i;
907
+ return (i | 0) ^ Math.imul(Math.floor(f * 1048576), 2654435761);
908
+ }
909
+ function rand(seed) {
910
+ return mix2(fold(seed) + 2654435769) / 4294967296;
911
+ }
912
+ function random(seed) {
913
+ let a = fold(seed) + 1831565813 | 0;
914
+ return () => {
915
+ a = a + 1831565813 | 0;
916
+ let t = Math.imul(a ^ a >>> 15, 1 | a);
917
+ t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
918
+ return ((t ^ t >>> 14) >>> 0) / 4294967296;
919
+ };
920
+ }
921
+ function noise(x, seed = 0) {
922
+ if (!Number.isFinite(x)) return 0;
923
+ const i = Math.floor(x);
924
+ const f = x - i;
925
+ const s = fold(seed) * 668265261;
926
+ const a = mix2((i | 0) + s) / 2147483648 - 1;
927
+ const b = mix2((i + 1 | 0) + s) / 2147483648 - 1;
928
+ const u = f * f * f * (f * (f * 6 - 15) + 10);
929
+ return a + (b - a) * u;
930
+ }
148
931
 
149
932
  // src/expr/Parser.ts
150
933
  var FUNCS = {
@@ -305,7 +1088,7 @@ function parsePrimary(c) {
305
1088
  }
306
1089
  throw new Error(`unexpected token "${t.type}"`);
307
1090
  }
308
- function parse(src) {
1091
+ function parse2(src) {
309
1092
  const c = new Cursor(tokenize(src));
310
1093
  const node = parseExpr(c);
311
1094
  if (c.peek()) throw new Error("trailing input");
@@ -355,7 +1138,7 @@ function evaluateExpr(source, scope) {
355
1138
  let ast = astCache.get(source);
356
1139
  if (ast === void 0) {
357
1140
  try {
358
- ast = parse(source);
1141
+ ast = parse2(source);
359
1142
  } catch (e) {
360
1143
  console.warn(`pixi-effects: expression failed: ${source}`, e);
361
1144
  ast = ZERO_NODE;
@@ -407,56 +1190,6 @@ function looksLikeColorString(s) {
407
1190
  if (s.charCodeAt(0) === 35) return true;
408
1191
  return /^(rgb|hsl|oklab|oklch|lab|lch)\b/i.test(s);
409
1192
  }
410
- function cubicBezierEase(x1, y1, x2, y2) {
411
- const cx = 3 * x1, bx = 3 * (x2 - x1) - cx, ax = 1 - cx - bx;
412
- const cy = 3 * y1, by = 3 * (y2 - y1) - cy, ay = 1 - cy - by;
413
- const X = (t) => ((ax * t + bx) * t + cx) * t;
414
- const Y = (t) => ((ay * t + by) * t + cy) * t;
415
- const dX = (t) => (3 * ax * t + 2 * bx) * t + cx;
416
- return (p) => {
417
- if (p <= 0) return 0;
418
- if (p >= 1) return 1;
419
- let t = p;
420
- for (let i = 0; i < 8; i++) {
421
- const err = X(t) - p;
422
- if (Math.abs(err) < 1e-9) return Y(t);
423
- const d = dX(t);
424
- if (Math.abs(d) < 1e-6) break;
425
- t -= err / d;
426
- }
427
- let lo = 0, hi = 1;
428
- t = p;
429
- for (let i = 0; i < 60; i++) {
430
- const x = X(t);
431
- if (Math.abs(x - p) < 1e-10) break;
432
- if (x < p) lo = t;
433
- else hi = t;
434
- t = (lo + hi) / 2;
435
- }
436
- return Y(t);
437
- };
438
- }
439
- var NUM = String.raw`\s*(-?(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)\s*`;
440
- var RE = new RegExp(`^\\s*cubic-bezier\\(${NUM},${NUM},${NUM},${NUM}\\)\\s*$`, "i");
441
- function cubicBezierProblem(name) {
442
- const m = RE.exec(name);
443
- if (!m) return 'expected "cubic-bezier(x1, y1, x2, y2)" with four numbers, like CSS';
444
- const x1 = Number(m[1]), x2 = Number(m[3]);
445
- if (x1 < 0 || x1 > 1 || x2 < 0 || x2 > 1) return "x1 and x2 must be between 0 and 1 (y1 and y2 may overshoot)";
446
- return null;
447
- }
448
- var registered2 = false;
449
- function registerCubicBezierEase() {
450
- if (registered2) return;
451
- registered2 = true;
452
- const base = ((p) => p);
453
- base.config = (x1, y1, x2, y2) => {
454
- const bad = [x1, y1, x2, y2].some((v) => typeof v !== "number" || !Number.isFinite(v)) || x1 < 0 || x1 > 1 || x2 < 0 || x2 > 1;
455
- return bad ? (p) => p : cubicBezierEase(x1, y1, x2, y2);
456
- };
457
- gsap.registerEase("cubic-bezier", base);
458
- }
459
- registerCubicBezierEase();
460
1193
 
461
1194
  // src/core/ease.ts
462
1195
  var FAMILIES = ["power1", "power2", "power3", "power4", "back", "elastic", "bounce", "circ", "expo", "sine"];
@@ -468,7 +1201,7 @@ function checkEase(ease, where) {
468
1201
  const problem = springProblem(ease);
469
1202
  if (!problem || warned.has(ease)) return;
470
1203
  warned.add(ease);
471
- console.warn(`pixi-effects: ${where}: unknown ease "${ease}" \u2014 ${problem}. GSAP would run it as its default ease, power1.out.`);
1204
+ console.warn(`pixi-effects: ${where}: unknown ease "${ease}" \u2014 ${problem}. It runs as its default ease, power1.out.`);
472
1205
  return;
473
1206
  }
474
1207
  if (/^\s*cubic-bezier/i.test(ease)) {
@@ -478,20 +1211,19 @@ function checkEase(ease, where) {
478
1211
  console.warn(`pixi-effects: ${where}: unknown ease "${ease}" \u2014 ${problem}. It runs as 'none' (a straight line).`);
479
1212
  return;
480
1213
  }
481
- const found = gsap.parseEase(ease);
482
- if (typeof found === "function") return;
1214
+ if (isEaseName(ease)) return;
483
1215
  if (warned.has(ease)) return;
484
1216
  warned.add(ease);
485
1217
  if (ease === "") {
486
- console.warn(`pixi-effects: ${where}: an empty ease (GSAP would run its default, power1.out): write 'none' for no easing, or a name such as 'power2.out'`);
1218
+ console.warn(`pixi-effects: ${where}: an empty ease (it would run as power1.out): write 'none' for no easing, or a name such as 'power2.out'`);
487
1219
  return;
488
1220
  }
489
- if (found && /^power[1-4]$/i.test(ease)) {
1221
+ if (/^(power[1-4]|quad|cubic|quart|quint|strong|back|elastic|bounce|circ|expo|sine)$/i.test(ease)) {
490
1222
  console.warn(`pixi-effects: ${where}: "${ease}" is a family, not an ease \u2014 write ${ease.toLowerCase()}.out, ${ease.toLowerCase()}.in or ${ease.toLowerCase()}.inOut`);
491
1223
  return;
492
1224
  }
493
1225
  const guess = suggestName(ease, EASE_NAMES);
494
- console.warn(`pixi-effects: ${where}: unknown ease "${ease}"${guess ? ` \u2014 did you mean "${guess}"?` : ""} (GSAP would run it as its default ease, power1.out). Examples: ${EASE_NAMES.slice(0, 7).join(", ")}, back.out(1.7), elastic.out(1, 0.3), steps(8)`);
1226
+ console.warn(`pixi-effects: ${where}: unknown ease "${ease}"${guess ? ` \u2014 did you mean "${guess}"?` : ""} (it runs as its default ease, power1.out). Examples: ${EASE_NAMES.slice(0, 7).join(", ")}, back.out(1.7), elastic.out(1, 0.3), steps(8)`);
495
1227
  }
496
1228
 
497
1229
  // src/core/Timeline.ts
@@ -593,16 +1325,7 @@ var PIXI_SHORTHANDS = /* @__PURE__ */ new Set([
593
1325
  "tileScaleX",
594
1326
  "tileScaleY",
595
1327
  "tint",
596
- "colorize",
597
- "colorizeAmount",
598
- "colorMatrixFilter",
599
- "blur",
600
- "blurX",
601
- "blurY",
602
- "blurPadding",
603
1328
  "autoAlpha",
604
- "lineColor",
605
- "lineAlpha",
606
1329
  "fillColor",
607
1330
  "fillAlpha"
608
1331
  ]);
@@ -716,13 +1439,13 @@ function applyInitial(target, initial, scope, skipKeys = [], routers) {
716
1439
  if (!initial) return;
717
1440
  const resolved = normalizeProps(initial, scope, { skipKeys, where: "initial" });
718
1441
  const { rest, routed } = splitRouted(resolved, routers);
719
- for (const r of routed) gsap.set(r.target, { [r.prop]: r.value });
1442
+ for (const r of routed) setNow(r.target, { [r.prop]: r.value });
720
1443
  const { ownProps, filterProps } = partitionProps(rest);
721
- if (Object.keys(ownProps).length > 0) gsap.set(target, pixiwrap(ownProps));
1444
+ if (Object.keys(ownProps).length > 0) setNow(target, pixiwrap(ownProps));
722
1445
  for (const [name, props] of Object.entries(filterProps)) {
723
1446
  const f = findFilter(target, name);
724
1447
  if (!f) continue;
725
- gsap.set(f, props);
1448
+ setNow(f, props);
726
1449
  }
727
1450
  }
728
1451
 
@@ -1157,7 +1880,7 @@ var GrainFilter = class extends Filter {
1157
1880
  };
1158
1881
  var WARP_KINDS = ["wave", "haze"];
1159
1882
  var OPTION_KEYS = ["kind", "strength", "scale", "speed", "angle", "seed"];
1160
- var DEG = Math.PI / 180;
1883
+ var DEG2 = Math.PI / 180;
1161
1884
  var HASH_GL2 = `
1162
1885
  uint hash(uint x) { x ^= x >> 16; x *= 0x7feb352du; x ^= x >> 15; x *= 0x846ca68bu; x ^= x >> 16; return x; }
1163
1886
  float lattice(ivec2 p, uint k) {
@@ -1329,7 +2052,7 @@ var WarpFilter = class extends Filter {
1329
2052
  uStrength: { value: strength, type: "f32" },
1330
2053
  uScale: { value: scale, type: "f32" },
1331
2054
  uSpeed: { value: speed, type: "f32" },
1332
- uAngle: { value: angle * DEG, type: "f32" },
2055
+ uAngle: { value: angle * DEG2, type: "f32" },
1333
2056
  uSeed: { value: Math.floor(seed), type: "f32" },
1334
2057
  uMode: { value: kind === "haze" ? 1 : 0, type: "f32" },
1335
2058
  uTime: { value: 0, type: "f32" }
@@ -1367,10 +2090,10 @@ var WarpFilter = class extends Filter {
1367
2090
  this.u.uSpeed = v;
1368
2091
  }
1369
2092
  get angle() {
1370
- return this.u.uAngle / DEG;
2093
+ return this.u.uAngle / DEG2;
1371
2094
  }
1372
2095
  set angle(v) {
1373
- this.u.uAngle = v * DEG;
2096
+ this.u.uAngle = v * DEG2;
1374
2097
  }
1375
2098
  get seed() {
1376
2099
  return this.u.uSeed;
@@ -1648,6 +2371,8 @@ var NullSequence = class extends Sequence {
1648
2371
  this.buildFilters();
1649
2372
  }
1650
2373
  };
2374
+
2375
+ // src/core/remap.ts
1651
2376
  var BAGS = ["set", "to", "from"];
1652
2377
  function timeRemapOf(spec, prop = "time") {
1653
2378
  const hasInitial = !!spec.initial && "time" in spec.initial;
@@ -1728,7 +2453,7 @@ function bindClock(timeline, clock, prop, remap, duration, at, scope) {
1728
2453
  timeline.fromTo(clock, { [prop]: from }, { [prop]: from + s * duration, duration, ease: "none" }, at);
1729
2454
  }
1730
2455
  function clockTable(remap, prop, duration, at, scope, to) {
1731
- const probe = gsap.timeline({ paused: true });
2456
+ const probe = createTimeline({ paused: true });
1732
2457
  const clock = { [prop]: remap.start ?? 0 };
1733
2458
  bindClock(probe, clock, prop, remap, duration, at, scope);
1734
2459
  probe.time(probe.duration());
@@ -1760,7 +2485,7 @@ function clockTable(remap, prop, duration, at, scope, to) {
1760
2485
  }
1761
2486
 
1762
2487
  // src/space/math.ts
1763
- var DEG2 = Math.PI / 180;
2488
+ var DEG3 = Math.PI / 180;
1764
2489
  var DEFAULT_FOV = 40;
1765
2490
  var MIN_FOV = 1;
1766
2491
  var MAX_FOV = 179;
@@ -1770,7 +2495,7 @@ function clampFov(fov) {
1770
2495
  return Math.min(MAX_FOV, Math.max(MIN_FOV, fov));
1771
2496
  }
1772
2497
  function homeDistance(compHeight, fovDeg) {
1773
- return compHeight / 2 / Math.tan(clampFov(fovDeg) * DEG2 / 2);
2498
+ return compHeight / 2 / Math.tan(clampFov(fovDeg) * DEG3 / 2);
1774
2499
  }
1775
2500
  function homeCamera(compW, compH, fov = DEFAULT_FOV) {
1776
2501
  return {
@@ -1824,7 +2549,7 @@ function cameraBasis(cam, compW, compH) {
1824
2549
  fx,
1825
2550
  fy,
1826
2551
  fz,
1827
- focal: compH / 2 / Math.tan(clampFov(cam.fov) * DEG2 / 2),
2552
+ focal: compH / 2 / Math.tan(clampFov(cam.fov) * DEG3 / 2),
1828
2553
  halfW: compW / 2,
1829
2554
  halfH: compH / 2
1830
2555
  };
@@ -1888,12 +2613,12 @@ function looksLikeLayerName(s) {
1888
2613
  var isName = (v, known) => typeof v === "string" && (known.has(v) || looksLikeLayerName(v));
1889
2614
  function focusNames(props, known) {
1890
2615
  const out = [];
1891
- const read = (bag) => {
2616
+ const read2 = (bag) => {
1892
2617
  const v = bag?.focus;
1893
2618
  if (isName(v, known)) out.push(v);
1894
2619
  };
1895
- read(props.initial);
1896
- for (const kf of props.keyframes ?? []) for (const bag of [kf.set, kf.to, kf.from]) read(bag);
2620
+ read2(props.initial);
2621
+ for (const kf of props.keyframes ?? []) for (const bag of [kf.set, kf.to, kf.from]) read2(bag);
1897
2622
  return out;
1898
2623
  }
1899
2624
  function withFocusResolved(props, zOf, known = /* @__PURE__ */ new Set()) {
@@ -2058,7 +2783,7 @@ function smoothstep(e0, e1, x) {
2058
2783
  const t = Math.min(1, Math.max(0, (x - e0) / (e1 - e0)));
2059
2784
  return t * t * (3 - 2 * t);
2060
2785
  }
2061
- var DEG3 = Math.PI / 180;
2786
+ var DEG4 = Math.PI / 180;
2062
2787
  function norm(v) {
2063
2788
  const l = Math.hypot(v.x, v.y, v.z) || 1;
2064
2789
  return { x: v.x / l, y: v.y / l, z: v.z / l };
@@ -2066,7 +2791,7 @@ function norm(v) {
2066
2791
  var dot = (a, b) => a.x * b.x + a.y * b.y + a.z * b.z;
2067
2792
  var sub = (a, b) => ({ x: a.x - b.x, y: a.y - b.y, z: a.z - b.z });
2068
2793
  function coneCos(l) {
2069
- const half = Math.min(179, Math.max(0, l.coneAngle)) * DEG3 / 2;
2794
+ const half = Math.min(179, Math.max(0, l.coneAngle)) * DEG4 / 2;
2070
2795
  const inner = half * (1 - Math.min(1, Math.max(0, l.coneFeather)));
2071
2796
  const cosOuter = Math.cos(half);
2072
2797
  const cosInner = Math.max(Math.cos(inner), cosOuter + 1e-4);
@@ -2200,24 +2925,8 @@ var LightSequence = class extends Sequence {
2200
2925
  };
2201
2926
 
2202
2927
  // src/core/revertibleSet.ts
2203
- function revertibleSet(timeline, at, read, write, value) {
2204
- let p = 0;
2205
- let before;
2206
- const proxy = {
2207
- get p() {
2208
- return p;
2209
- },
2210
- set p(next) {
2211
- if (next >= 1 && p < 1) {
2212
- before = read();
2213
- write(value);
2214
- } else if (next < 1 && p >= 1) {
2215
- write(before);
2216
- }
2217
- p = next;
2218
- }
2219
- };
2220
- timeline.set(proxy, { p: 1 }, at);
2928
+ function revertibleSet(timeline, at, read2, write2, value, property) {
2929
+ timeline.setValue(property?.[0] ?? read2, property?.[1] ?? "set", at, read2, write2, value);
2221
2930
  }
2222
2931
 
2223
2932
  // src/expr/colorInterp.ts
@@ -2356,30 +3065,26 @@ function shortestHueDelta(from, to) {
2356
3065
  // src/expr/colorTween.ts
2357
3066
  var css = (c) => typeof c === "number" ? "#" + c.toString(16).padStart(6, "0") : c;
2358
3067
  function tweenColor(timeline, target, key, fromValue, toValue, duration, ease, at, colorSpace, onUpdate, loop = {}) {
2359
- let interp = null;
2360
- const proxy = { p: 0 };
2361
- timeline.fromTo(
2362
- proxy,
2363
- { p: 0 },
2364
- {
2365
- p: 1,
2366
- duration,
2367
- ease,
2368
- ...loop,
2369
- onStart: () => {
2370
- const start = fromValue !== void 0 ? fromValue : target[key];
2371
- if (start === void 0) return;
2372
- interp = colorSpace === "rgb" ? gsap.utils.interpolate(css(start), css(toValue)) : buildColorInterp(start, toValue, colorSpace);
2373
- },
2374
- onUpdate: () => {
2375
- if (interp) {
2376
- target[key] = interp(proxy.p);
2377
- if (onUpdate) onUpdate();
2378
- }
2379
- }
3068
+ const none = () => void 0;
3069
+ timeline.tweenValue({
3070
+ holder: target,
3071
+ id: key,
3072
+ get: () => target[key],
3073
+ set: (v) => {
3074
+ if (v === void 0) return;
3075
+ target[key] = v;
3076
+ if (onUpdate) onUpdate();
2380
3077
  },
2381
- at
2382
- );
3078
+ from: fromValue !== void 0 ? () => fromValue : void 0,
3079
+ to: () => toValue,
3080
+ make: (a, b) => a === void 0 ? none : colorSpace === "rgb" ? interpolateColors(css(a), css(b)) : buildColorInterp(a, b, colorSpace),
3081
+ duration,
3082
+ ease,
3083
+ at,
3084
+ repeat: loop.repeat,
3085
+ yoyo: loop.yoyo,
3086
+ repeatDelay: loop.repeatDelay
3087
+ });
2383
3088
  }
2384
3089
 
2385
3090
  // src/sequences/Image.ts
@@ -2422,7 +3127,7 @@ var ImageSequence = class extends Sequence {
2422
3127
  const sprite = this.target;
2423
3128
  revertibleSet(timeline, at, () => sprite.tint, (c) => {
2424
3129
  sprite.tint = c;
2425
- }, setTint);
3130
+ }, setTint, [sprite, "tint"]);
2426
3131
  }
2427
3132
  if (toTint !== void 0) {
2428
3133
  tweenColor(
@@ -2577,37 +3282,37 @@ function validateGradientKeyframes(spec, who, warn = (m) => console.warn(m), kin
2577
3282
  if (animated && !start) say("a keyframe animates fillGradient but the layer has none to start from: give it a fillGradient first (top level or in initial)");
2578
3283
  }
2579
3284
  function tweenGradient(timeline, holder, fromPatch, toPatch, duration, ease, at, colorSpace, onChange, loop = {}) {
2580
- let a = null, b = null;
2581
- let resting = null;
2582
- let colors = [];
2583
- const proxy = { p: 0 };
2584
- timeline.fromTo(proxy, { p: 0 }, {
2585
- p: 1,
2586
- duration,
2587
- ease,
2588
- ...loop,
2589
- onStart: () => {
2590
- const live = holder.grad;
2591
- a = fromPatch !== void 0 ? mergeGrad(live, fromPatch) : live;
2592
- if (toPatch === void 0) resting ??= live;
2593
- b = toPatch !== void 0 ? mergeGrad(a, toPatch) : resting;
2594
- colors = a.stops.map((s, i) => colorSpace === "rgb" ? gsap.utils.interpolate(s.color, b.stops[i].color) : buildColorInterp(s.color, b.stops[i].color, colorSpace));
3285
+ timeline.tweenValue({
3286
+ holder,
3287
+ id: "grad",
3288
+ get: () => holder.grad,
3289
+ set: (g) => {
3290
+ holder.grad = g;
3291
+ onChange();
2595
3292
  },
2596
- onUpdate: () => {
2597
- if (!a || !b) return;
2598
- const t = proxy.p;
2599
- const l = (x, y) => x + (y - x) * t;
2600
- holder.grad = {
2601
- type: a.type,
2602
- angle: l(a.angle, b.angle),
2603
- center: [l(a.center[0], b.center[0]), l(a.center[1], b.center[1])],
2604
- innerRadius: l(a.innerRadius, b.innerRadius),
2605
- radius: l(a.radius, b.radius),
2606
- stops: a.stops.map((s, i) => ({ offset: l(s.offset, b.stops[i].offset), color: colors[i](t) }))
3293
+ from: fromPatch !== void 0 ? (prev) => mergeGrad(prev, fromPatch) : void 0,
3294
+ to: (start, prev) => toPatch !== void 0 ? mergeGrad(start, toPatch) : prev,
3295
+ make: (a, b) => {
3296
+ const colors = a.stops.map((s, i) => colorSpace === "rgb" ? interpolateColors(s.color, b.stops[i].color) : buildColorInterp(s.color, b.stops[i].color, colorSpace));
3297
+ return (t) => {
3298
+ const l = (x, y) => x + (y - x) * t;
3299
+ return {
3300
+ type: a.type,
3301
+ angle: l(a.angle, b.angle),
3302
+ center: [l(a.center[0], b.center[0]), l(a.center[1], b.center[1])],
3303
+ innerRadius: l(a.innerRadius, b.innerRadius),
3304
+ radius: l(a.radius, b.radius),
3305
+ stops: a.stops.map((s, i) => ({ offset: l(s.offset, b.stops[i].offset), color: colors[i](t) }))
3306
+ };
2607
3307
  };
2608
- onChange();
2609
- }
2610
- }, at);
3308
+ },
3309
+ duration,
3310
+ ease,
3311
+ at,
3312
+ repeat: loop.repeat,
3313
+ yoyo: loop.yoyo,
3314
+ repeatDelay: loop.repeatDelay
3315
+ });
2611
3316
  }
2612
3317
  var PAINT_SIZE = 512;
2613
3318
  var GradientPainter = class {
@@ -2652,16 +3357,20 @@ function bindGradientKeyframes(timeline, holder, keyframes, duration, offset, co
2652
3357
  const at = offset + resolveAt(kf.at, duration);
2653
3358
  const setV = bag(kf.set), fromV = bag(kf.from), toV = bag(kf.to);
2654
3359
  if (setV !== void 0) {
2655
- revertibleSet(
2656
- timeline,
2657
- at,
2658
- () => ({ state: holder.grad }),
2659
- (v) => {
2660
- holder.grad = v.state ?? mergeGrad(holder.grad, v.patch);
3360
+ timeline.tweenValue({
3361
+ holder,
3362
+ id: "grad",
3363
+ get: () => holder.grad,
3364
+ set: (g) => {
3365
+ holder.grad = g;
2661
3366
  onChange();
2662
3367
  },
2663
- { patch: setV }
2664
- );
3368
+ to: (start) => mergeGrad(start, setV),
3369
+ make: (_a, b) => () => b,
3370
+ duration: 0,
3371
+ ease: "none",
3372
+ at
3373
+ });
2665
3374
  }
2666
3375
  if (fromV !== void 0 || toV !== void 0) {
2667
3376
  tweenGradient(timeline, holder, fromV, toV, kfDuration(kf), kf.ease ?? "none", at, colorSpace, onChange, loopVars(kf));
@@ -2853,7 +3562,7 @@ function bindCounterKeyframes(timeline, state, key, refresh, keyframes, parentDu
2853
3562
  revertibleSet(timeline, at, () => state[key], (n) => {
2854
3563
  state[key] = n;
2855
3564
  refresh();
2856
- }, v);
3565
+ }, v, [state, key]);
2857
3566
  }
2858
3567
  if (toV !== void 0 && fromV !== void 0) {
2859
3568
  timeline.fromTo(
@@ -2869,7 +3578,7 @@ function bindCounterKeyframes(timeline, state, key, refresh, keyframes, parentDu
2869
3578
  }
2870
3579
  }
2871
3580
  }
2872
- function bindTextKeyframes(timeline, keyframes, parentDuration, origin, read, write, who) {
3581
+ function bindTextKeyframes(timeline, keyframes, parentDuration, origin, read2, write2, who) {
2873
3582
  for (const kf of keyframes) {
2874
3583
  for (const [what, props] of [["to", kf.to], ["from", kf.from]]) {
2875
3584
  if (props && props.text !== void 0) {
@@ -2878,7 +3587,7 @@ function bindTextKeyframes(timeline, keyframes, parentDuration, origin, read, wr
2878
3587
  }
2879
3588
  const t = kf.set?.text;
2880
3589
  if (t === void 0) continue;
2881
- revertibleSet(timeline, origin + resolveAt(kf.at, parentDuration), read, write, String(t));
3590
+ revertibleSet(timeline, origin + resolveAt(kf.at, parentDuration), read2, write2, String(t));
2882
3591
  }
2883
3592
  }
2884
3593
  function animates(keyframes, key) {
@@ -2900,7 +3609,7 @@ function bindFillKeyframes(timeline, text, keyframes, parentDuration, offset, co
2900
3609
  revertibleSet(timeline, at, () => state.fill, (c) => {
2901
3610
  state.fill = c;
2902
3611
  writeFill();
2903
- }, setFill);
3612
+ }, setFill, [state, "fill"]);
2904
3613
  }
2905
3614
  if (toFill !== void 0) {
2906
3615
  tweenColor(
@@ -2975,7 +3684,7 @@ var AudioSequence = class extends Sequence {
2975
3684
  const raw = spec;
2976
3685
  if (raw.asset !== void 0) console.warn(`pixi-effects: ${who}: has both asset and music \u2014 the music plays; remove one`);
2977
3686
  if (raw.sfx !== void 0) console.warn(`pixi-effects: ${who}: has both sfx and music \u2014 the music plays; remove one`);
2978
- const { resolveMusic, renderMusic, musicLength, musicKey } = await import('./music-3O5MDQXY.js');
3687
+ const { resolveMusic, renderMusic, renderMusicAsync, musicLength, musicKey } = await import('./music-JVRNXHQ5.js');
2979
3688
  const music = resolveMusic(spec.music, who);
2980
3689
  if (!music) return;
2981
3690
  const natural = musicLength(music);
@@ -2992,7 +3701,7 @@ var AudioSequence = class extends Sequence {
2992
3701
  this.duration = length;
2993
3702
  const loop = !!spec.loop;
2994
3703
  this._source = "music";
2995
- this._synth = { key: musicKey(music, length, loop), render: (sr) => renderMusic(music, sr, length, loop) };
3704
+ this._synth = { key: musicKey(music, length, loop), render: (sr) => renderMusic(music, sr, length, loop), renderAsync: (sr, pace) => renderMusicAsync(music, sr, length, loop, pace) };
2996
3705
  }
2997
3706
  bindTimeline(_timeline) {
2998
3707
  }
@@ -3505,8 +4214,8 @@ var VideoSequence = class extends Sequence {
3505
4214
  currentTime = v;
3506
4215
  seq._cur = v;
3507
4216
  const mySeq = ++seq._drawSeq;
3508
- const lookup = sourceLookup(v, seq._sourceDuration, !!seq.spec.loop);
3509
- seq._cache.getFrameAt(lookup).then((frame) => {
4217
+ const lookup2 = sourceLookup(v, seq._sourceDuration, !!seq.spec.loop);
4218
+ seq._cache.getFrameAt(lookup2).then((frame) => {
3510
4219
  if (mySeq !== seq._drawSeq) return;
3511
4220
  if (!frame || !seq._ctx) return;
3512
4221
  seq._ctx.drawImage(frame, 0, 0);
@@ -3560,10 +4269,10 @@ var VideoSequence = class extends Sequence {
3560
4269
  const time = this._cur;
3561
4270
  if (!this.keepHidden && !this.target?.renderable) return;
3562
4271
  const mySeq = ++this._drawSeq;
3563
- const lookup = sourceLookup(time, this._sourceDuration, !!this.spec.loop);
4272
+ const lookup2 = sourceLookup(time, this._sourceDuration, !!this.spec.loop);
3564
4273
  let frame = null;
3565
4274
  try {
3566
- frame = await this._cache.getFrameAt(lookup);
4275
+ frame = await this._cache.getFrameAt(lookup2);
3567
4276
  } catch (err) {
3568
4277
  console.warn("pixi-effects: awaitFrameAt failed at", time, "s \u2014", err);
3569
4278
  return;
@@ -3971,7 +4680,7 @@ function seedGeometry(state, spec, scope) {
3971
4680
  const initial = spec.initial ?? {};
3972
4681
  for (const k of keys) {
3973
4682
  const v = spec[k] ?? initial[k];
3974
- if (v !== void 0) state[k] = num(v, scope);
4683
+ if (v !== void 0) state[k] = num2(v, scope);
3975
4684
  }
3976
4685
  }
3977
4686
  var STROKE_CAPS = ["butt", "round", "square"];
@@ -4089,7 +4798,7 @@ function drawEllipseFromState(g, s) {
4089
4798
  const ay = s.anchorY ?? 0.5;
4090
4799
  g.ellipse((0.5 - ax) * 2 * rx, (0.5 - ay) * 2 * ry, rx, ry);
4091
4800
  }
4092
- var DEG4 = Math.PI / 180;
4801
+ var DEG5 = Math.PI / 180;
4093
4802
  function drawArcFromState(g, s) {
4094
4803
  const r = s.radius ?? 0;
4095
4804
  const ri = Math.max(0, Math.min(s.innerRadius ?? 0, r));
@@ -4104,7 +4813,7 @@ function drawArcFromState(g, s) {
4104
4813
  }
4105
4814
  endDeg = startDeg + Math.sign(endDeg - startDeg) * 359.999;
4106
4815
  }
4107
- const a0 = startDeg * DEG4, a1 = endDeg * DEG4;
4816
+ const a0 = startDeg * DEG5, a1 = endDeg * DEG5;
4108
4817
  const ccw = a1 < a0;
4109
4818
  if (filled) g.moveTo(r * Math.cos(a0), r * Math.sin(a0));
4110
4819
  g.arc(0, 0, r, a0, a1, ccw);
@@ -4118,10 +4827,10 @@ function drawArcFromState(g, s) {
4118
4827
  g.closePath();
4119
4828
  }
4120
4829
  function makeLineDraw(spec, scope) {
4121
- const fx = num(spec.from[0], scope);
4122
- const fy = num(spec.from[1], scope);
4123
- const tx = num(spec.to[0], scope);
4124
- const ty = num(spec.to[1], scope);
4830
+ const fx = num2(spec.from[0], scope);
4831
+ const fy = num2(spec.from[1], scope);
4832
+ const tx = num2(spec.to[0], scope);
4833
+ const ty = num2(spec.to[1], scope);
4125
4834
  return (g) => {
4126
4835
  g.moveTo(fx, fy);
4127
4836
  g.lineTo(tx, ty);
@@ -4131,7 +4840,7 @@ function makePolygonDraw(spec, scope) {
4131
4840
  if (spec.points.length === 0) return () => {
4132
4841
  };
4133
4842
  const flat = [];
4134
- for (const [x, y] of spec.points) flat.push(num(x, scope), num(y, scope));
4843
+ for (const [x, y] of spec.points) flat.push(num2(x, scope), num2(y, scope));
4135
4844
  const closed = !spec.open;
4136
4845
  return (g) => {
4137
4846
  g.poly(flat, closed);
@@ -4197,12 +4906,12 @@ function makeOutline(spec, scope, s, morph) {
4197
4906
  return [ellipseOutline((0.5 - (s.anchorX ?? 0.5)) * 2 * rx, (0.5 - (s.anchorY ?? 0.5)) * 2 * ry, rx, ry)];
4198
4907
  };
4199
4908
  case "line": {
4200
- const lines = [{ pts: [num(spec.from[0], scope), num(spec.from[1], scope), num(spec.to[0], scope), num(spec.to[1], scope)], closed: false }];
4909
+ const lines = [{ pts: [num2(spec.from[0], scope), num2(spec.from[1], scope), num2(spec.to[0], scope), num2(spec.to[1], scope)], closed: false }];
4201
4910
  return () => lines;
4202
4911
  }
4203
4912
  case "polygon": {
4204
4913
  const pts = [];
4205
- for (const [x, y] of spec.points) pts.push(num(x, scope), num(y, scope));
4914
+ for (const [x, y] of spec.points) pts.push(num2(x, scope), num2(y, scope));
4206
4915
  const lines = pts.length >= 4 ? [{ pts, closed: !spec.open }] : [];
4207
4916
  return () => lines;
4208
4917
  }
@@ -4230,7 +4939,7 @@ function bindLiveKeyframes(timeline, state, liveKeys, keyframes, parentDuration,
4230
4939
  const live2 = state;
4231
4940
  revertibleSet(timeline, at, () => live2[k], (v2) => {
4232
4941
  live2[k] = v2;
4233
- }, resolved);
4942
+ }, resolved, [live2, k]);
4234
4943
  }
4235
4944
  }
4236
4945
  }
@@ -4274,7 +4983,7 @@ function tweenLiveKey(timeline, state, key, fromValue, toValue, duration, ease,
4274
4983
  }
4275
4984
  }
4276
4985
  }
4277
- function num(v, scope) {
4986
+ function num2(v, scope) {
4278
4987
  if (typeof v === "number") return v;
4279
4988
  if (isExpr(v)) return evaluateExpr(v, scope);
4280
4989
  const parsed = parseFloat(v);
@@ -4282,7 +4991,7 @@ function num(v, scope) {
4282
4991
  }
4283
4992
  function numOrZero(v, scope) {
4284
4993
  if (typeof v === "number") return v;
4285
- if (typeof v === "string") return num(v, scope);
4994
+ if (typeof v === "string") return num2(v, scope);
4286
4995
  return 0;
4287
4996
  }
4288
4997
 
@@ -4331,13 +5040,13 @@ var SHADER_BUILTINS = ["iResolution", "iTime", "iFrame"];
4331
5040
  var SHADER_MISSING = ["iMouse", "iChannel0", "iChannel1", "iChannel2", "iChannel3", "iDate", "iTimeDelta", "iSampleRate"];
4332
5041
  var IDENT = /^[A-Za-z_][A-Za-z0-9_]*$/;
4333
5042
  var HEX = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
4334
- var RESERVED = new Set(`attribute const uniform varying break continue do for while if else in out inout float int void bool true false discard return
5043
+ var RESERVED2 = new Set(`attribute const uniform varying break continue do for while if else in out inout float int void bool true false discard return
4335
5044
  mat2 mat3 mat4 mat2x2 mat2x3 mat2x4 mat3x2 mat3x3 mat3x4 mat4x2 mat4x3 mat4x4 vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 uvec2 uvec3 uvec4 uint
4336
5045
  sampler2D sampler3D samplerCube sampler2DShadow samplerCubeShadow sampler2DArray sampler2DArrayShadow isampler2D isampler3D isamplerCube isampler2DArray
4337
5046
  usampler2D usampler3D usamplerCube usampler2DArray struct layout centroid flat smooth precision invariant highp mediump lowp
4338
5047
  sample patch subroutine common partition active asm class union enum typedef template this resource goto inline noinline public static extern external
4339
5048
  interface long short double half fixed unsigned superp input output hvec2 hvec3 hvec4 fvec2 fvec3 fvec4 dvec2 dvec3 dvec4 filter sizeof cast namespace using`.split(/\s+/));
4340
- var isIdent = (name) => IDENT.test(name) && !name.startsWith("gl_") && !name.includes("__") && !RESERVED.has(name) && !SHADER_BUILTINS.includes(name);
5049
+ var isIdent = (name) => IDENT.test(name) && !name.startsWith("gl_") && !name.includes("__") && !RESERVED2.has(name) && !SHADER_BUILTINS.includes(name);
4341
5050
  function uniformType(v) {
4342
5051
  if (typeof v === "number") return Number.isFinite(v) ? "float" : null;
4343
5052
  if (typeof v === "string") return HEX.test(v) ? "vec3" : null;
@@ -4675,7 +5384,7 @@ function resolveDim(v, scope) {
4675
5384
  var _CompositionSequence = null;
4676
5385
  async function getCompositionSequence() {
4677
5386
  if (!_CompositionSequence) {
4678
- _CompositionSequence = (await import('./Composition-3O7L2VL5.js')).CompositionSequence;
5387
+ _CompositionSequence = (await import('./Composition-BJVY5HP7.js')).CompositionSequence;
4679
5388
  }
4680
5389
  return _CompositionSequence;
4681
5390
  }
@@ -4717,6 +5426,6 @@ async function buildSequenceTree(specs, parent, root) {
4717
5426
  return out;
4718
5427
  }
4719
5428
 
4720
- export { CameraSequence, DEFAULT_FOV, DEG2 as DEG, FALLOFFS, LIGHT_KINDS, LIGHT_PROPS, LightSequence, MANY_BLURRED, MAX_BLUR, MAX_CASTERS, MAX_LIGHTS, MIN_BLUR, NEAR, NullSequence, SHADOW_TAPS, Sequence, bindClock, blurRadius, buildScope, buildSequenceTree, cameraBasis, checkEase, clockTable, contentLength, ensureFilterLibrary, evaluateExpr, flattenSvgPath, focusProblems, homeCamera, homeDistance, layerInitialZ, layerToWorld, lightLevel, noise, packLights, projectLayer, projectPoint, rand, random, registerSequenceType, remapOf, resolveAt, timeRemapOf };
4721
- //# sourceMappingURL=chunk-FXAHNPBP.js.map
4722
- //# sourceMappingURL=chunk-FXAHNPBP.js.map
5429
+ export { CameraSequence, DEFAULT_FOV, DEG3 as DEG, FALLOFFS, LIGHT_KINDS, LIGHT_PROPS, LightSequence, MANY_BLURRED, MAX_BLUR, MAX_CASTERS, MAX_LIGHTS, MIN_BLUR, NEAR, NullSequence, SHADOW_TAPS, Sequence, bindClock, blurRadius, buildScope, buildSequenceTree, cameraBasis, checkEase, clockTable, contentLength, createTimeline, ensureFilterLibrary, evaluateExpr, flattenSvgPath, focusProblems, homeCamera, homeDistance, layerInitialZ, layerToWorld, lengthen, lightLevel, noise, packLights, parseEase, projectLayer, projectPoint, rand, random, registerSequenceType, remapOf, resolveAt, timeRemapOf };
5430
+ //# sourceMappingURL=chunk-X42BGR6P.js.map
5431
+ //# sourceMappingURL=chunk-X42BGR6P.js.map