@remotion/vercel 4.0.507 → 4.0.509

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 (2) hide show
  1. package/dist/esm/index.mjs +1362 -164
  2. package/package.json +4 -4
@@ -115,6 +115,498 @@ import { statSync } from "fs";
115
115
  import { RenderInternals } from "@remotion/renderer";
116
116
 
117
117
  // ../core/dist/esm/no-react.mjs
118
+ var NEWTON_ITERATIONS = 4;
119
+ var NEWTON_MIN_SLOPE = 0.001;
120
+ var SUBDIVISION_PRECISION = 0.0000001;
121
+ var SUBDIVISION_MAX_ITERATIONS = 10;
122
+ var kSplineTableSize = 11;
123
+ var kSampleStepSize = 1 / (kSplineTableSize - 1);
124
+ var float32ArraySupported = typeof Float32Array === "function";
125
+ function a(aA1, aA2) {
126
+ return 1 - 3 * aA2 + 3 * aA1;
127
+ }
128
+ function b(aA1, aA2) {
129
+ return 3 * aA2 - 6 * aA1;
130
+ }
131
+ function c(aA1) {
132
+ return 3 * aA1;
133
+ }
134
+ function calcBezier(aT, aA1, aA2) {
135
+ return ((a(aA1, aA2) * aT + b(aA1, aA2)) * aT + c(aA1)) * aT;
136
+ }
137
+ function getSlope(aT, aA1, aA2) {
138
+ return 3 * a(aA1, aA2) * aT * aT + 2 * b(aA1, aA2) * aT + c(aA1);
139
+ }
140
+ function binarySubdivide({
141
+ aX,
142
+ _aA,
143
+ _aB,
144
+ mX1,
145
+ mX2
146
+ }) {
147
+ let currentX;
148
+ let currentT;
149
+ let i = 0;
150
+ let aA = _aA;
151
+ let aB = _aB;
152
+ do {
153
+ currentT = aA + (aB - aA) / 2;
154
+ currentX = calcBezier(currentT, mX1, mX2) - aX;
155
+ if (currentX > 0) {
156
+ aB = currentT;
157
+ } else {
158
+ aA = currentT;
159
+ }
160
+ } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
161
+ return currentT;
162
+ }
163
+ function newtonRaphsonIterate(aX, _aGuessT, mX1, mX2) {
164
+ let aGuessT = _aGuessT;
165
+ for (let i = 0;i < NEWTON_ITERATIONS; ++i) {
166
+ const currentSlope = getSlope(aGuessT, mX1, mX2);
167
+ if (currentSlope === 0) {
168
+ return aGuessT;
169
+ }
170
+ const currentX = calcBezier(aGuessT, mX1, mX2) - aX;
171
+ aGuessT -= currentX / currentSlope;
172
+ }
173
+ return aGuessT;
174
+ }
175
+ function bezier(mX1, mY1, mX2, mY2) {
176
+ if (!(mX1 >= 0 && mX1 <= 1 && mX2 >= 0 && mX2 <= 1)) {
177
+ throw new Error("bezier x values must be in [0, 1] range");
178
+ }
179
+ const sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
180
+ if (mX1 !== mY1 || mX2 !== mY2) {
181
+ for (let i = 0;i < kSplineTableSize; ++i) {
182
+ sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
183
+ }
184
+ }
185
+ function getTForX(aX) {
186
+ let intervalStart = 0;
187
+ let currentSample = 1;
188
+ const lastSample = kSplineTableSize - 1;
189
+ for (;currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
190
+ intervalStart += kSampleStepSize;
191
+ }
192
+ --currentSample;
193
+ const dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
194
+ const guessForT = intervalStart + dist * kSampleStepSize;
195
+ const initialSlope = getSlope(guessForT, mX1, mX2);
196
+ if (initialSlope >= NEWTON_MIN_SLOPE) {
197
+ return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
198
+ }
199
+ if (initialSlope === 0) {
200
+ return guessForT;
201
+ }
202
+ return binarySubdivide({
203
+ aX,
204
+ _aA: intervalStart,
205
+ _aB: intervalStart + kSampleStepSize,
206
+ mX1,
207
+ mX2
208
+ });
209
+ }
210
+ return function(x) {
211
+ const clampedX = Math.min(1, Math.max(0, x));
212
+ if (mX1 === mY1 && mX2 === mY2) {
213
+ return clampedX;
214
+ }
215
+ if (clampedX === 0) {
216
+ return 0;
217
+ }
218
+ if (clampedX === 1) {
219
+ return 1;
220
+ }
221
+ return calcBezier(getTForX(clampedX), mY1, mY2);
222
+ };
223
+ }
224
+ var validateFrame = ({
225
+ allowFloats,
226
+ durationInFrames,
227
+ frame
228
+ }) => {
229
+ if (typeof frame === "undefined") {
230
+ throw new TypeError(\`Argument missing for parameter "frame"\`);
231
+ }
232
+ if (typeof frame !== "number") {
233
+ throw new TypeError(\`Argument passed for "frame" is not a number: \${frame}\`);
234
+ }
235
+ if (!Number.isFinite(frame)) {
236
+ throw new RangeError(\`Frame \${frame} is not finite\`);
237
+ }
238
+ if (frame % 1 !== 0 && !allowFloats) {
239
+ throw new RangeError(\`Argument for frame must be an integer, but got \${frame}\`);
240
+ }
241
+ if (frame < 0 && frame < -durationInFrames) {
242
+ throw new RangeError(\`Cannot use frame \${frame}: Duration of composition is \${durationInFrames}, therefore the lowest frame that can be rendered is \${-durationInFrames}\`);
243
+ }
244
+ if (frame > durationInFrames - 1) {
245
+ throw new RangeError(\`Cannot use frame \${frame}: Duration of composition is \${durationInFrames}, therefore the highest frame that can be rendered is \${durationInFrames - 1}\`);
246
+ }
247
+ };
248
+ function validateFps(fps, location, isGif) {
249
+ if (typeof fps !== "number") {
250
+ throw new Error(\`"fps" must be a number, but you passed a value of type \${typeof fps} \${location}\`);
251
+ }
252
+ if (!Number.isFinite(fps)) {
253
+ throw new Error(\`"fps" must be a finite, but you passed \${fps} \${location}\`);
254
+ }
255
+ if (isNaN(fps)) {
256
+ throw new Error(\`"fps" must not be NaN, but got \${fps} \${location}\`);
257
+ }
258
+ if (fps <= 0) {
259
+ throw new TypeError(\`"fps" must be positive, but got \${fps} \${location}\`);
260
+ }
261
+ if (isGif && fps > 50) {
262
+ throw new TypeError(\`The FPS for a GIF cannot be higher than 50. Use the --every-nth-frame option to lower the FPS: https://remotion.dev/docs/render-as-gif\`);
263
+ }
264
+ }
265
+ var validateSpringDuration = (dur) => {
266
+ if (typeof dur === "undefined") {
267
+ return;
268
+ }
269
+ if (typeof dur !== "number") {
270
+ throw new TypeError(\`A "duration" of a spring must be a "number" but is "\${typeof dur}"\`);
271
+ }
272
+ if (Number.isNaN(dur)) {
273
+ throw new TypeError('A "duration" of a spring is NaN, which it must not be');
274
+ }
275
+ if (!Number.isFinite(dur)) {
276
+ throw new TypeError('A "duration" of a spring must be finite, but is ' + dur);
277
+ }
278
+ if (dur <= 0) {
279
+ throw new TypeError('A "duration" of a spring must be positive, but is ' + dur);
280
+ }
281
+ };
282
+ var defaultSpringConfig = {
283
+ damping: 10,
284
+ mass: 1,
285
+ stiffness: 100,
286
+ overshootClamping: false
287
+ };
288
+ var advanceCache = {};
289
+ function advance({
290
+ animation,
291
+ now,
292
+ config
293
+ }) {
294
+ const { toValue, lastTimestamp, current, velocity } = animation;
295
+ const deltaTime = Math.min(now - lastTimestamp, 64);
296
+ if (config.damping <= 0) {
297
+ throw new Error("Spring damping must be greater than 0, otherwise the spring() animation will never end, causing an infinite loop.");
298
+ }
299
+ const c2 = config.damping;
300
+ const m = config.mass;
301
+ const k = config.stiffness;
302
+ const cacheKey = [
303
+ toValue,
304
+ lastTimestamp,
305
+ current,
306
+ velocity,
307
+ c2,
308
+ m,
309
+ k,
310
+ now
311
+ ].join("-");
312
+ if (advanceCache[cacheKey]) {
313
+ return advanceCache[cacheKey];
314
+ }
315
+ const v0 = -velocity;
316
+ const x0 = toValue - current;
317
+ const zeta = c2 / (2 * Math.sqrt(k * m));
318
+ const omega0 = Math.sqrt(k / m);
319
+ const omega1 = omega0 * Math.sqrt(1 - zeta ** 2);
320
+ const t = deltaTime / 1000;
321
+ const sin1 = Math.sin(omega1 * t);
322
+ const cos1 = Math.cos(omega1 * t);
323
+ const underDampedEnvelope = Math.exp(-zeta * omega0 * t);
324
+ const underDampedFrag1 = underDampedEnvelope * (sin1 * ((v0 + zeta * omega0 * x0) / omega1) + x0 * cos1);
325
+ const underDampedPosition = toValue - underDampedFrag1;
326
+ const underDampedVelocity = zeta * omega0 * underDampedFrag1 - underDampedEnvelope * (cos1 * (v0 + zeta * omega0 * x0) - omega1 * x0 * sin1);
327
+ const criticallyDampedEnvelope = Math.exp(-omega0 * t);
328
+ const criticallyDampedPosition = toValue - criticallyDampedEnvelope * (x0 + (v0 + omega0 * x0) * t);
329
+ const criticallyDampedVelocity = criticallyDampedEnvelope * (v0 * (t * omega0 - 1) + t * x0 * omega0 * omega0);
330
+ const animationNode = {
331
+ toValue,
332
+ prevPosition: current,
333
+ lastTimestamp: now,
334
+ current: zeta < 1 ? underDampedPosition : criticallyDampedPosition,
335
+ velocity: zeta < 1 ? underDampedVelocity : criticallyDampedVelocity
336
+ };
337
+ advanceCache[cacheKey] = animationNode;
338
+ return animationNode;
339
+ }
340
+ var calculationCache = {};
341
+ function springCalculation({
342
+ frame,
343
+ fps,
344
+ config = {}
345
+ }) {
346
+ const from = 0;
347
+ const to = 1;
348
+ const cacheKey = [
349
+ frame,
350
+ fps,
351
+ config.damping,
352
+ config.mass,
353
+ config.overshootClamping,
354
+ config.stiffness
355
+ ].join("-");
356
+ if (calculationCache[cacheKey]) {
357
+ return calculationCache[cacheKey];
358
+ }
359
+ let animation = {
360
+ lastTimestamp: 0,
361
+ current: from,
362
+ toValue: to,
363
+ velocity: 0,
364
+ prevPosition: 0
365
+ };
366
+ const frameClamped = Math.max(0, frame);
367
+ const unevenRest = frameClamped % 1;
368
+ for (let f = 0;f <= Math.floor(frameClamped); f++) {
369
+ if (f === Math.floor(frameClamped)) {
370
+ f += unevenRest;
371
+ }
372
+ const time = f / fps * 1000;
373
+ animation = advance({
374
+ animation,
375
+ now: time,
376
+ config: {
377
+ ...defaultSpringConfig,
378
+ ...config
379
+ }
380
+ });
381
+ }
382
+ calculationCache[cacheKey] = animation;
383
+ return animation;
384
+ }
385
+ var cache = new Map;
386
+ function measureSpring({
387
+ fps,
388
+ config = {},
389
+ threshold = 0.005
390
+ }) {
391
+ if (typeof threshold !== "number") {
392
+ throw new TypeError(\`threshold must be a number, got \${threshold} of type \${typeof threshold}\`);
393
+ }
394
+ if (threshold === 0) {
395
+ return Infinity;
396
+ }
397
+ if (threshold === 1) {
398
+ return 0;
399
+ }
400
+ if (isNaN(threshold)) {
401
+ throw new TypeError("Threshold is NaN");
402
+ }
403
+ if (!Number.isFinite(threshold)) {
404
+ throw new TypeError("Threshold is not finite");
405
+ }
406
+ if (threshold < 0) {
407
+ throw new TypeError("Threshold is below 0");
408
+ }
409
+ const cacheKey = [
410
+ fps,
411
+ config.damping,
412
+ config.mass,
413
+ config.overshootClamping,
414
+ config.stiffness,
415
+ threshold
416
+ ].join("-");
417
+ if (cache.has(cacheKey)) {
418
+ return cache.get(cacheKey);
419
+ }
420
+ validateFps(fps, "to the measureSpring() function", false);
421
+ let frame = 0;
422
+ let finishedFrame = 0;
423
+ const calc = () => {
424
+ return springCalculation({
425
+ fps,
426
+ frame,
427
+ config
428
+ });
429
+ };
430
+ let animation = calc();
431
+ const calcDifference = () => {
432
+ return Math.abs(animation.current - animation.toValue);
433
+ };
434
+ let difference = calcDifference();
435
+ while (difference >= threshold) {
436
+ frame++;
437
+ animation = calc();
438
+ difference = calcDifference();
439
+ }
440
+ finishedFrame = frame;
441
+ for (let i = 0;i < 20; i++) {
442
+ frame++;
443
+ animation = calc();
444
+ difference = calcDifference();
445
+ if (difference >= threshold) {
446
+ i = 0;
447
+ finishedFrame = frame + 1;
448
+ }
449
+ }
450
+ cache.set(cacheKey, finishedFrame);
451
+ return finishedFrame;
452
+ }
453
+ function spring({
454
+ frame: passedFrame,
455
+ fps,
456
+ config = {},
457
+ from = 0,
458
+ to = 1,
459
+ durationInFrames: passedDurationInFrames,
460
+ durationRestThreshold,
461
+ delay = 0,
462
+ reverse = false
463
+ }) {
464
+ validateSpringDuration(passedDurationInFrames);
465
+ validateFrame({
466
+ frame: passedFrame,
467
+ durationInFrames: Infinity,
468
+ allowFloats: true
469
+ });
470
+ validateFps(fps, "to spring()", false);
471
+ const needsToCalculateNaturalDuration = reverse || typeof passedDurationInFrames !== "undefined";
472
+ const naturalDuration = needsToCalculateNaturalDuration ? measureSpring({
473
+ fps,
474
+ config,
475
+ threshold: durationRestThreshold
476
+ }) : undefined;
477
+ const naturalDurationGetter = needsToCalculateNaturalDuration ? {
478
+ get: () => naturalDuration
479
+ } : {
480
+ get: () => {
481
+ throw new Error("did not calculate natural duration, this is an error with Remotion. Please report");
482
+ }
483
+ };
484
+ const reverseProcessed = reverse ? (passedDurationInFrames ?? naturalDurationGetter.get()) - passedFrame : passedFrame;
485
+ const delayProcessed = reverseProcessed + (reverse ? delay : -delay);
486
+ const durationProcessed = passedDurationInFrames === undefined ? delayProcessed : delayProcessed / (passedDurationInFrames / naturalDurationGetter.get());
487
+ if (passedDurationInFrames && delayProcessed > passedDurationInFrames) {
488
+ return to;
489
+ }
490
+ const spr = springCalculation({
491
+ fps,
492
+ frame: durationProcessed,
493
+ config
494
+ });
495
+ const inner = config.overshootClamping ? to >= from ? Math.min(spr.current, to) : Math.max(spr.current, to) : spr.current;
496
+ const interpolated = from === 0 && to === 1 ? inner : interpolate(inner, [0, 1], [from, to]);
497
+ return interpolated;
498
+ }
499
+ var clampUnit = (t) => Math.min(1, Math.max(0, t));
500
+ var springEasingDurationInFrames = 30;
501
+
502
+ class Easing {
503
+ static step0(n) {
504
+ return n > 0 ? 1 : 0;
505
+ }
506
+ static step1(n) {
507
+ return n >= 1 ? 1 : 0;
508
+ }
509
+ static linear(t) {
510
+ return t;
511
+ }
512
+ static ease(t) {
513
+ return Easing.bezier(0.42, 0, 1, 1)(t);
514
+ }
515
+ static quad(t) {
516
+ return t * t;
517
+ }
518
+ static cubic(t) {
519
+ return t * t * t;
520
+ }
521
+ static poly(n) {
522
+ return (t) => t ** n;
523
+ }
524
+ static sin(t) {
525
+ return 1 - Math.cos(t * Math.PI / 2);
526
+ }
527
+ static circle(t) {
528
+ const u = clampUnit(t);
529
+ return 1 - Math.sqrt(1 - u * u);
530
+ }
531
+ static exp(t) {
532
+ return 2 ** (10 * (t - 1));
533
+ }
534
+ static elastic(bounciness = 1) {
535
+ const p = bounciness * Math.PI;
536
+ return (t) => 1 - Math.cos(t * Math.PI / 2) ** 3 * Math.cos(t * p);
537
+ }
538
+ static back(s = 1.70158) {
539
+ return (t) => t * t * ((s + 1) * t - s);
540
+ }
541
+ static spring({
542
+ allowTail = false,
543
+ durationRestThreshold,
544
+ ...config
545
+ } = {}) {
546
+ const easing = (t) => {
547
+ if (t <= 0) {
548
+ return 0;
549
+ }
550
+ if (!allowTail && t >= 1) {
551
+ return 1;
552
+ }
553
+ if (allowTail) {
554
+ return spring({
555
+ fps: springEasingDurationInFrames,
556
+ frame: t * measureSpring({
557
+ fps: springEasingDurationInFrames,
558
+ config,
559
+ threshold: durationRestThreshold
560
+ }),
561
+ config
562
+ });
563
+ }
564
+ return spring({
565
+ fps: springEasingDurationInFrames,
566
+ frame: t * springEasingDurationInFrames,
567
+ config,
568
+ durationInFrames: springEasingDurationInFrames,
569
+ durationRestThreshold
570
+ });
571
+ };
572
+ return Object.assign(easing, {
573
+ remotionShouldExtendRight: allowTail
574
+ });
575
+ }
576
+ static bounce(t) {
577
+ const u = clampUnit(t);
578
+ if (u < 1 / 2.75) {
579
+ return 7.5625 * u * u;
580
+ }
581
+ if (u < 2 / 2.75) {
582
+ const t2_ = u - 1.5 / 2.75;
583
+ return 7.5625 * t2_ * t2_ + 0.75;
584
+ }
585
+ if (u < 2.5 / 2.75) {
586
+ const t2_ = u - 2.25 / 2.75;
587
+ return 7.5625 * t2_ * t2_ + 0.9375;
588
+ }
589
+ const t2 = u - 2.625 / 2.75;
590
+ return 7.5625 * t2 * t2 + 0.984375;
591
+ }
592
+ static bezier(x1, y1, x2, y2) {
593
+ return bezier(x1, y1, x2, y2);
594
+ }
595
+ static in(easing) {
596
+ return easing;
597
+ }
598
+ static out(easing) {
599
+ return (t) => 1 - easing(1 - t);
600
+ }
601
+ static inOut(easing) {
602
+ return (t) => {
603
+ if (t < 0.5) {
604
+ return easing(t * 2) / 2;
605
+ }
606
+ return 1 - easing((1 - t) * 2) / 2;
607
+ };
608
+ }
609
+ }
118
610
  var normalizeNumber = (value) => {
119
611
  return Math.round(value * 1e6) / 1e6;
120
612
  };
@@ -185,10 +677,13 @@ var transformOriginCenter = { value: 50, unit: "%" };
185
677
  var stringifyNumber = (value) => {
186
678
  return String(normalizeNumber(value));
187
679
  };
680
+
681
+ class UnsupportedStringInterpolationValueError extends TypeError {
682
+ }
188
683
  var parseStringInterpolationComponent = (component, value) => {
189
684
  const match = cssNumberRegex.exec(component);
190
685
  if (match === null) {
191
- throw new TypeError(\`Cannot interpolate "\${value}" because "\${component}" is not a supported scale, translate, or rotate value\`);
686
+ throw new UnsupportedStringInterpolationValueError(\`Cannot interpolate "\${value}" because "\${component}" is not a supported scale, translate, or rotate value\`);
192
687
  }
193
688
  const unit = match[2] ?? null;
194
689
  const numberValue = Number(match[1]);
@@ -305,9 +800,45 @@ var parseTransformOriginValue = (output, parts) => {
305
800
  });
306
801
  return {
307
802
  kind: "translate",
308
- values: [x.value, y.value, z.value],
309
- units: [x.unit, y.unit, z.unit],
310
- dimensions: parts[2] === undefined ? 2 : 3
803
+ values: [x.value, y.value, z.value, 0],
804
+ units: [x.unit, y.unit, z.unit, null],
805
+ dimensions: parts[2] === undefined ? 2 : 3,
806
+ axisRotation: false
807
+ };
808
+ };
809
+ var parseAxisRotationValue = (output) => {
810
+ const parts = output.trim().split(/\\s+/);
811
+ const keywordAxis = parts.length === 2 ? parts[0].toLowerCase() : null;
812
+ if (keywordAxis === "x" || keywordAxis === "y" || keywordAxis === "z") {
813
+ const keywordAngle = parseStringInterpolationComponent(parts[1], output);
814
+ if (keywordAngle.kind !== "rotate") {
815
+ return null;
816
+ }
817
+ return {
818
+ kind: "rotate",
819
+ values: keywordAxis === "x" ? [1, 0, 0, keywordAngle.value] : keywordAxis === "y" ? [0, 1, 0, keywordAngle.value] : [0, 0, 1, keywordAngle.value],
820
+ units: [null, null, null, keywordAngle.unit],
821
+ dimensions: 4,
822
+ axisRotation: true
823
+ };
824
+ }
825
+ if (parts.length !== 4) {
826
+ return null;
827
+ }
828
+ const axis = parts.slice(0, 3).map(Number);
829
+ if (!axis.every(Number.isFinite)) {
830
+ return null;
831
+ }
832
+ const vectorAngle = parseStringInterpolationComponent(parts[3], output);
833
+ if (vectorAngle.kind !== "rotate") {
834
+ return null;
835
+ }
836
+ return {
837
+ kind: "rotate",
838
+ values: [axis[0], axis[1], axis[2], vectorAngle.value],
839
+ units: [null, null, null, vectorAngle.unit],
840
+ dimensions: 4,
841
+ axisRotation: true
311
842
  };
312
843
  };
313
844
  var parseStringInterpolationValue = (output) => {
@@ -317,11 +848,16 @@ var parseStringInterpolationValue = (output) => {
317
848
  }
318
849
  return {
319
850
  kind: "scale",
320
- values: [output, output, 1],
321
- units: [null, null, null],
322
- dimensions: 1
851
+ values: [output, output, 1, 0],
852
+ units: [null, null, null, null],
853
+ dimensions: 1,
854
+ axisRotation: false
323
855
  };
324
856
  }
857
+ const axisRotation = parseAxisRotationValue(output);
858
+ if (axisRotation !== null) {
859
+ return axisRotation;
860
+ }
325
861
  const parts = output.trim().split(/\\s+/);
326
862
  if (parts.length < 1 || parts.length > 3 || parts[0] === "") {
327
863
  throw new TypeError(\`String outputRange values must contain 1 to 3 components, but got "\${output}"\`);
@@ -342,24 +878,35 @@ var parseStringInterpolationValue = (output) => {
342
878
  const z = parsed[2]?.value ?? 1;
343
879
  return {
344
880
  kind,
345
- values: [x, y, z],
346
- units: [null, null, null],
347
- dimensions: parsed.length
881
+ values: [x, y, z, 0],
882
+ units: [null, null, null, null],
883
+ dimensions: parsed.length,
884
+ axisRotation: false
348
885
  };
349
886
  }
350
887
  return {
351
888
  kind,
352
- values: [parsed[0].value, parsed[1]?.value ?? 0, parsed[2]?.value ?? 0],
353
- units: [parsed[0].unit, parsed[1]?.unit ?? null, parsed[2]?.unit ?? null],
354
- dimensions: parsed.length
889
+ values: [parsed[0].value, parsed[1]?.value ?? 0, parsed[2]?.value ?? 0, 0],
890
+ units: [
891
+ parsed[0].unit,
892
+ parsed[1]?.unit ?? null,
893
+ parsed[2]?.unit ?? null,
894
+ null
895
+ ],
896
+ dimensions: parsed.length,
897
+ axisRotation: false
355
898
  };
356
899
  };
357
900
  var serializeStringInterpolationValue = ({
358
901
  kind,
359
902
  values,
360
903
  units,
361
- dimensions
904
+ dimensions,
905
+ axisRotation
362
906
  }) => {
907
+ if (axisRotation) {
908
+ return \`\${stringifyNumber(values[0])} \${stringifyNumber(values[1])} \${stringifyNumber(values[2])} \${stringifyNumber(values[3])}\${units[3]}\`;
909
+ }
363
910
  if (kind === "scale") {
364
911
  return values.slice(0, dimensions).map((value) => stringifyNumber(value)).join(" ");
365
912
  }
@@ -527,7 +1074,26 @@ var interpolateString = ({
527
1074
  outputRange,
528
1075
  options
529
1076
  }) => {
530
- const parsedOutputRange = outputRange.map(parseStringInterpolationValue);
1077
+ const initiallyParsedOutputRange = outputRange.map(parseStringInterpolationValue);
1078
+ const hasAxisRotation = initiallyParsedOutputRange.some((parsed) => parsed.axisRotation);
1079
+ const parsedOutputRange = hasAxisRotation ? initiallyParsedOutputRange.map((parsed) => {
1080
+ if (parsed.kind !== "rotate") {
1081
+ return parsed;
1082
+ }
1083
+ if (parsed.axisRotation) {
1084
+ return parsed;
1085
+ }
1086
+ if (parsed.dimensions !== 1) {
1087
+ throw new TypeError("Cannot interpolate a multi-angle rotate value with an axis rotation");
1088
+ }
1089
+ return {
1090
+ kind: "rotate",
1091
+ values: [0, 0, 1, parsed.values[0]],
1092
+ units: [null, null, null, parsed.units[0]],
1093
+ dimensions: 4,
1094
+ axisRotation: true
1095
+ };
1096
+ }) : initiallyParsedOutputRange;
531
1097
  const kind = parsedOutputRange[0]?.kind;
532
1098
  if (kind === undefined) {
533
1099
  throw new Error("outputRange must have at least 1 element");
@@ -539,12 +1105,16 @@ var interpolateString = ({
539
1105
  }
540
1106
  const dimensions = Math.max(...parsedOutputRange.map((parsed) => parsed.dimensions));
541
1107
  const units = [
1108
+ null,
542
1109
  null,
543
1110
  null,
544
1111
  null
545
1112
  ];
546
1113
  if (kind !== "scale") {
547
1114
  for (let axis = 0;axis < dimensions; axis++) {
1115
+ if (hasAxisRotation && axis < 3) {
1116
+ continue;
1117
+ }
548
1118
  for (const parsed of parsedOutputRange) {
549
1119
  const unit = parsed.units[axis];
550
1120
  if (unit === null) {
@@ -563,7 +1133,7 @@ var interpolateString = ({
563
1133
  }
564
1134
  }
565
1135
  }
566
- const values = [0, 0, 0];
1136
+ const values = [0, 0, 0, 0];
567
1137
  for (let axis = 0;axis < dimensions; axis++) {
568
1138
  values[axis] = interpolateNumber({
569
1139
  input,
@@ -576,9 +1146,56 @@ var interpolateString = ({
576
1146
  kind,
577
1147
  values,
578
1148
  units,
579
- dimensions
1149
+ dimensions,
1150
+ axisRotation: hasAxisRotation
580
1151
  });
581
1152
  };
1153
+ var interpolateDiscreteString = ({
1154
+ input,
1155
+ inputRange,
1156
+ outputRange,
1157
+ options
1158
+ }) => {
1159
+ if (inputRange.length === 1) {
1160
+ return outputRange[0];
1161
+ }
1162
+ for (let segmentIndex = 0;segmentIndex < inputRange.length - 1; segmentIndex++) {
1163
+ if (resolveEasingForSegment({
1164
+ easing: options?.easing,
1165
+ segmentIndex
1166
+ }) !== Easing.step1) {
1167
+ throw new TypeError("Non-numeric strings can only be interpolated using Easing.step1");
1168
+ }
1169
+ }
1170
+ const posterizedInput = options?.posterize === undefined ? input : Math.floor(input / options.posterize) * options.posterize;
1171
+ const inputMin = inputRange[0];
1172
+ const inputMax = inputRange[inputRange.length - 1];
1173
+ let resolvedInput = posterizedInput;
1174
+ if (resolvedInput < inputMin) {
1175
+ if (options?.extrapolateLeft === "identity") {
1176
+ throw new TypeError('extrapolateLeft: "identity" is not supported for non-numeric strings');
1177
+ }
1178
+ if (options?.extrapolateLeft === "wrap") {
1179
+ const wrapRange = inputMax - inputMin;
1180
+ resolvedInput = ((resolvedInput - inputMin) % wrapRange + wrapRange) % wrapRange + inputMin;
1181
+ } else {
1182
+ return outputRange[0];
1183
+ }
1184
+ }
1185
+ if (resolvedInput > inputMax) {
1186
+ if (options?.extrapolateRight === "identity") {
1187
+ throw new TypeError('extrapolateRight: "identity" is not supported for non-numeric strings');
1188
+ }
1189
+ if (options?.extrapolateRight === "wrap") {
1190
+ const wrapRange = inputMax - inputMin;
1191
+ resolvedInput = ((resolvedInput - inputMin) % wrapRange + wrapRange) % wrapRange + inputMin;
1192
+ } else {
1193
+ return outputRange[outputRange.length - 1];
1194
+ }
1195
+ }
1196
+ const range = findRange(resolvedInput, inputRange);
1197
+ return resolvedInput >= inputRange[range + 1] ? outputRange[range + 1] : outputRange[range];
1198
+ };
582
1199
  var validateTupleOutputRange = (outputRange) => {
583
1200
  const dimensions = outputRange[0]?.length;
584
1201
  if (dimensions === undefined) {
@@ -693,7 +1310,30 @@ function interpolate(input, inputRange, outputRange, options) {
693
1310
  if (!outputRange.every((output) => typeof output === "string" || typeof output === "number")) {
694
1311
  throw new TypeError("outputRange must contain only numbers, or supported scale, translate, and rotate strings");
695
1312
  }
696
- return interpolateString({ input, inputRange, outputRange, options });
1313
+ try {
1314
+ return interpolateString({ input, inputRange, outputRange, options });
1315
+ } catch (error) {
1316
+ if (!outputRange.every((output) => typeof output === "string")) {
1317
+ throw error;
1318
+ }
1319
+ const hasNonNumericString = outputRange.some((output) => {
1320
+ try {
1321
+ parseStringInterpolationValue(output);
1322
+ return false;
1323
+ } catch (parseError) {
1324
+ return parseError instanceof UnsupportedStringInterpolationValueError;
1325
+ }
1326
+ });
1327
+ if (!hasNonNumericString) {
1328
+ throw error;
1329
+ }
1330
+ return interpolateDiscreteString({
1331
+ input,
1332
+ inputRange,
1333
+ outputRange,
1334
+ options
1335
+ });
1336
+ }
697
1337
  }
698
1338
  if (outputRange.every((output) => Array.isArray(output))) {
699
1339
  return interpolateTuple({ input, inputRange, outputRange, options });
@@ -1162,8 +1802,8 @@ function hslToRgb(h, s, l) {
1162
1802
  const p = 2 * l - q;
1163
1803
  const r = hue2rgb(p, q, h + 1 / 3);
1164
1804
  const g = hue2rgb(p, q, h);
1165
- const b = hue2rgb(p, q, h - 1 / 3);
1166
- return Math.round(r * 255) << 24 | Math.round(g * 255) << 16 | Math.round(b * 255) << 8;
1805
+ const b2 = hue2rgb(p, q, h - 1 / 3);
1806
+ return Math.round(r * 255) << 24 | Math.round(g * 255) << 16 | Math.round(b2 * 255) << 8;
1167
1807
  }
1168
1808
  function parse255(str) {
1169
1809
  const int = Number.parseInt(str, 10);
@@ -1227,25 +1867,25 @@ function parseModernAlpha(str) {
1227
1867
  }
1228
1868
  return Math.max(0, Math.min(1, Number.parseFloat(str)));
1229
1869
  }
1230
- function linearToSrgb(c) {
1231
- if (c <= 0.0031308)
1232
- return 12.92 * c;
1233
- return 1.055 * c ** (1 / 2.4) - 0.055;
1870
+ function linearToSrgb(c2) {
1871
+ if (c2 <= 0.0031308)
1872
+ return 12.92 * c2;
1873
+ return 1.055 * c2 ** (1 / 2.4) - 0.055;
1234
1874
  }
1235
1875
  function clamp01(v) {
1236
1876
  return Math.max(0, Math.min(1, v));
1237
1877
  }
1238
- function rgbFloatToInt(r, g, b, alpha) {
1878
+ function rgbFloatToInt(r, g, b2, alpha) {
1239
1879
  const ri = Math.round(clamp01(r) * 255);
1240
1880
  const gi = Math.round(clamp01(g) * 255);
1241
- const bi = Math.round(clamp01(b) * 255);
1881
+ const bi = Math.round(clamp01(b2) * 255);
1242
1882
  const ai = Math.round(clamp01(alpha) * 255);
1243
1883
  return (ri << 24 | gi << 16 | bi << 8 | ai) >>> 0;
1244
1884
  }
1245
- function oklabToSrgb(L, a, b) {
1246
- const l_ = L + 0.3963377774 * a + 0.2158037573 * b;
1247
- const m_ = L - 0.1055613458 * a - 0.0638541728 * b;
1248
- const s_ = L - 0.0894841775 * a - 1.291485548 * b;
1885
+ function oklabToSrgb(L, a2, b2) {
1886
+ const l_ = L + 0.3963377774 * a2 + 0.2158037573 * b2;
1887
+ const m_ = L - 0.1055613458 * a2 - 0.0638541728 * b2;
1888
+ const s_ = L - 0.0894841775 * a2 - 1.291485548 * b2;
1249
1889
  const l = l_ * l_ * l_;
1250
1890
  const m = m_ * m_ * m_;
1251
1891
  const s = s_ * s_ * s_;
@@ -1254,15 +1894,15 @@ function oklabToSrgb(L, a, b) {
1254
1894
  const bLin = -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s;
1255
1895
  return [linearToSrgb(rLin), linearToSrgb(gLin), linearToSrgb(bLin)];
1256
1896
  }
1257
- function labToSrgb(L, a, b) {
1897
+ function labToSrgb(L, a2, b2) {
1258
1898
  const epsilon = 216 / 24389;
1259
1899
  const kappa = 24389 / 27;
1260
1900
  const Xn = 0.95047;
1261
1901
  const Yn = 1;
1262
1902
  const Zn = 1.08883;
1263
1903
  const fy = (L + 16) / 116;
1264
- const fx = a / 500 + fy;
1265
- const fz = fy - b / 200;
1904
+ const fx = a2 / 500 + fy;
1905
+ const fz = fy - b2 / 200;
1266
1906
  const fx3 = fx * fx * fx;
1267
1907
  const fz3 = fz * fz * fz;
1268
1908
  const xr = fx3 > epsilon ? fx3 : (116 * fx - 16) / kappa;
@@ -1494,27 +2134,27 @@ function normalizeColor(color) {
1494
2134
  const H = parseHueAngle(match[3]);
1495
2135
  const alpha = parseModernAlpha(match[4]);
1496
2136
  const hRad = H * Math.PI / 180;
1497
- const [r, g, b] = oklabToSrgb(L, C * Math.cos(hRad), C * Math.sin(hRad));
1498
- return rgbFloatToInt(r, g, b, alpha);
2137
+ const [r, g, b2] = oklabToSrgb(L, C * Math.cos(hRad), C * Math.sin(hRad));
2138
+ return rgbFloatToInt(r, g, b2, alpha);
1499
2139
  }
1500
2140
  }
1501
2141
  if (matchers.oklab) {
1502
2142
  if (match = matchers.oklab.exec(color)) {
1503
2143
  const L = parseModernComponent(match[1], 1);
1504
- const a = parseModernComponent(match[2], 0.4);
1505
- const b = parseModernComponent(match[3], 0.4);
2144
+ const a2 = parseModernComponent(match[2], 0.4);
2145
+ const b2 = parseModernComponent(match[3], 0.4);
1506
2146
  const alpha = parseModernAlpha(match[4]);
1507
- const [r, g, bl] = oklabToSrgb(L, a, b);
2147
+ const [r, g, bl] = oklabToSrgb(L, a2, b2);
1508
2148
  return rgbFloatToInt(r, g, bl, alpha);
1509
2149
  }
1510
2150
  }
1511
2151
  if (matchers.lab) {
1512
2152
  if (match = matchers.lab.exec(color)) {
1513
2153
  const L = parseModernComponent(match[1], 100);
1514
- const a = parseModernComponent(match[2], 125);
1515
- const b = parseModernComponent(match[3], 125);
2154
+ const a2 = parseModernComponent(match[2], 125);
2155
+ const b2 = parseModernComponent(match[3], 125);
1516
2156
  const alpha = parseModernAlpha(match[4]);
1517
- const [r, g, bl] = labToSrgb(L, a, b);
2157
+ const [r, g, bl] = labToSrgb(L, a2, b2);
1518
2158
  return rgbFloatToInt(r, g, bl, alpha);
1519
2159
  }
1520
2160
  }
@@ -1593,30 +2233,6 @@ var serializeScaleValue = ([x, y, z]) => {
1593
2233
  return \`\${normalizedX} \${normalizedY} \${normalizedZ}\`;
1594
2234
  };
1595
2235
  var ENABLE_V5_BREAKING_CHANGES = false;
1596
- var validateFrame = ({
1597
- allowFloats,
1598
- durationInFrames,
1599
- frame
1600
- }) => {
1601
- if (typeof frame === "undefined") {
1602
- throw new TypeError(\`Argument missing for parameter "frame"\`);
1603
- }
1604
- if (typeof frame !== "number") {
1605
- throw new TypeError(\`Argument passed for "frame" is not a number: \${frame}\`);
1606
- }
1607
- if (!Number.isFinite(frame)) {
1608
- throw new RangeError(\`Frame \${frame} is not finite\`);
1609
- }
1610
- if (frame % 1 !== 0 && !allowFloats) {
1611
- throw new RangeError(\`Argument for frame must be an integer, but got \${frame}\`);
1612
- }
1613
- if (frame < 0 && frame < -durationInFrames) {
1614
- throw new RangeError(\`Cannot use frame \${frame}: Duration of composition is \${durationInFrames}, therefore the lowest frame that can be rendered is \${-durationInFrames}\`);
1615
- }
1616
- if (frame > durationInFrames - 1) {
1617
- throw new RangeError(\`Cannot use frame \${frame}: Duration of composition is \${durationInFrames}, therefore the highest frame that can be rendered is \${durationInFrames - 1}\`);
1618
- }
1619
- };
1620
2236
  var validCodecs = [
1621
2237
  "h264",
1622
2238
  "h265",
@@ -1688,23 +2304,6 @@ function validateDurationInFrames(durationInFrames, options) {
1688
2304
  throw new TypeError(\`The "durationInFrames" prop \${component} must be finite, but got \${durationInFrames}.\`);
1689
2305
  }
1690
2306
  }
1691
- function validateFps(fps, location, isGif) {
1692
- if (typeof fps !== "number") {
1693
- throw new Error(\`"fps" must be a number, but you passed a value of type \${typeof fps} \${location}\`);
1694
- }
1695
- if (!Number.isFinite(fps)) {
1696
- throw new Error(\`"fps" must be a finite, but you passed \${fps} \${location}\`);
1697
- }
1698
- if (isNaN(fps)) {
1699
- throw new Error(\`"fps" must not be NaN, but got \${fps} \${location}\`);
1700
- }
1701
- if (fps <= 0) {
1702
- throw new TypeError(\`"fps" must be positive, but got \${fps} \${location}\`);
1703
- }
1704
- if (isGif && fps > 50) {
1705
- throw new TypeError(\`The FPS for a GIF cannot be higher than 50. Use the --every-nth-frame option to lower the FPS: https://remotion.dev/docs/render-as-gif\`);
1706
- }
1707
- }
1708
2307
  var getExpectedMediaFrameUncorrected = ({
1709
2308
  frame,
1710
2309
  playbackRate,
@@ -1874,6 +2473,498 @@ import { RenderInternals } from "@remotion/renderer";
1874
2473
  import { put } from "@vercel/blob";
1875
2474
 
1876
2475
  // ../core/dist/esm/no-react.mjs
2476
+ var NEWTON_ITERATIONS = 4;
2477
+ var NEWTON_MIN_SLOPE = 0.001;
2478
+ var SUBDIVISION_PRECISION = 0.0000001;
2479
+ var SUBDIVISION_MAX_ITERATIONS = 10;
2480
+ var kSplineTableSize = 11;
2481
+ var kSampleStepSize = 1 / (kSplineTableSize - 1);
2482
+ var float32ArraySupported = typeof Float32Array === "function";
2483
+ function a(aA1, aA2) {
2484
+ return 1 - 3 * aA2 + 3 * aA1;
2485
+ }
2486
+ function b(aA1, aA2) {
2487
+ return 3 * aA2 - 6 * aA1;
2488
+ }
2489
+ function c(aA1) {
2490
+ return 3 * aA1;
2491
+ }
2492
+ function calcBezier(aT, aA1, aA2) {
2493
+ return ((a(aA1, aA2) * aT + b(aA1, aA2)) * aT + c(aA1)) * aT;
2494
+ }
2495
+ function getSlope(aT, aA1, aA2) {
2496
+ return 3 * a(aA1, aA2) * aT * aT + 2 * b(aA1, aA2) * aT + c(aA1);
2497
+ }
2498
+ function binarySubdivide({
2499
+ aX,
2500
+ _aA,
2501
+ _aB,
2502
+ mX1,
2503
+ mX2
2504
+ }) {
2505
+ let currentX;
2506
+ let currentT;
2507
+ let i = 0;
2508
+ let aA = _aA;
2509
+ let aB = _aB;
2510
+ do {
2511
+ currentT = aA + (aB - aA) / 2;
2512
+ currentX = calcBezier(currentT, mX1, mX2) - aX;
2513
+ if (currentX > 0) {
2514
+ aB = currentT;
2515
+ } else {
2516
+ aA = currentT;
2517
+ }
2518
+ } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
2519
+ return currentT;
2520
+ }
2521
+ function newtonRaphsonIterate(aX, _aGuessT, mX1, mX2) {
2522
+ let aGuessT = _aGuessT;
2523
+ for (let i = 0;i < NEWTON_ITERATIONS; ++i) {
2524
+ const currentSlope = getSlope(aGuessT, mX1, mX2);
2525
+ if (currentSlope === 0) {
2526
+ return aGuessT;
2527
+ }
2528
+ const currentX = calcBezier(aGuessT, mX1, mX2) - aX;
2529
+ aGuessT -= currentX / currentSlope;
2530
+ }
2531
+ return aGuessT;
2532
+ }
2533
+ function bezier(mX1, mY1, mX2, mY2) {
2534
+ if (!(mX1 >= 0 && mX1 <= 1 && mX2 >= 0 && mX2 <= 1)) {
2535
+ throw new Error("bezier x values must be in [0, 1] range");
2536
+ }
2537
+ const sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
2538
+ if (mX1 !== mY1 || mX2 !== mY2) {
2539
+ for (let i = 0;i < kSplineTableSize; ++i) {
2540
+ sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
2541
+ }
2542
+ }
2543
+ function getTForX(aX) {
2544
+ let intervalStart = 0;
2545
+ let currentSample = 1;
2546
+ const lastSample = kSplineTableSize - 1;
2547
+ for (;currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
2548
+ intervalStart += kSampleStepSize;
2549
+ }
2550
+ --currentSample;
2551
+ const dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
2552
+ const guessForT = intervalStart + dist * kSampleStepSize;
2553
+ const initialSlope = getSlope(guessForT, mX1, mX2);
2554
+ if (initialSlope >= NEWTON_MIN_SLOPE) {
2555
+ return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
2556
+ }
2557
+ if (initialSlope === 0) {
2558
+ return guessForT;
2559
+ }
2560
+ return binarySubdivide({
2561
+ aX,
2562
+ _aA: intervalStart,
2563
+ _aB: intervalStart + kSampleStepSize,
2564
+ mX1,
2565
+ mX2
2566
+ });
2567
+ }
2568
+ return function(x) {
2569
+ const clampedX = Math.min(1, Math.max(0, x));
2570
+ if (mX1 === mY1 && mX2 === mY2) {
2571
+ return clampedX;
2572
+ }
2573
+ if (clampedX === 0) {
2574
+ return 0;
2575
+ }
2576
+ if (clampedX === 1) {
2577
+ return 1;
2578
+ }
2579
+ return calcBezier(getTForX(clampedX), mY1, mY2);
2580
+ };
2581
+ }
2582
+ var validateFrame = ({
2583
+ allowFloats,
2584
+ durationInFrames,
2585
+ frame
2586
+ }) => {
2587
+ if (typeof frame === "undefined") {
2588
+ throw new TypeError(\`Argument missing for parameter "frame"\`);
2589
+ }
2590
+ if (typeof frame !== "number") {
2591
+ throw new TypeError(\`Argument passed for "frame" is not a number: \${frame}\`);
2592
+ }
2593
+ if (!Number.isFinite(frame)) {
2594
+ throw new RangeError(\`Frame \${frame} is not finite\`);
2595
+ }
2596
+ if (frame % 1 !== 0 && !allowFloats) {
2597
+ throw new RangeError(\`Argument for frame must be an integer, but got \${frame}\`);
2598
+ }
2599
+ if (frame < 0 && frame < -durationInFrames) {
2600
+ throw new RangeError(\`Cannot use frame \${frame}: Duration of composition is \${durationInFrames}, therefore the lowest frame that can be rendered is \${-durationInFrames}\`);
2601
+ }
2602
+ if (frame > durationInFrames - 1) {
2603
+ throw new RangeError(\`Cannot use frame \${frame}: Duration of composition is \${durationInFrames}, therefore the highest frame that can be rendered is \${durationInFrames - 1}\`);
2604
+ }
2605
+ };
2606
+ function validateFps(fps, location, isGif) {
2607
+ if (typeof fps !== "number") {
2608
+ throw new Error(\`"fps" must be a number, but you passed a value of type \${typeof fps} \${location}\`);
2609
+ }
2610
+ if (!Number.isFinite(fps)) {
2611
+ throw new Error(\`"fps" must be a finite, but you passed \${fps} \${location}\`);
2612
+ }
2613
+ if (isNaN(fps)) {
2614
+ throw new Error(\`"fps" must not be NaN, but got \${fps} \${location}\`);
2615
+ }
2616
+ if (fps <= 0) {
2617
+ throw new TypeError(\`"fps" must be positive, but got \${fps} \${location}\`);
2618
+ }
2619
+ if (isGif && fps > 50) {
2620
+ throw new TypeError(\`The FPS for a GIF cannot be higher than 50. Use the --every-nth-frame option to lower the FPS: https://remotion.dev/docs/render-as-gif\`);
2621
+ }
2622
+ }
2623
+ var validateSpringDuration = (dur) => {
2624
+ if (typeof dur === "undefined") {
2625
+ return;
2626
+ }
2627
+ if (typeof dur !== "number") {
2628
+ throw new TypeError(\`A "duration" of a spring must be a "number" but is "\${typeof dur}"\`);
2629
+ }
2630
+ if (Number.isNaN(dur)) {
2631
+ throw new TypeError('A "duration" of a spring is NaN, which it must not be');
2632
+ }
2633
+ if (!Number.isFinite(dur)) {
2634
+ throw new TypeError('A "duration" of a spring must be finite, but is ' + dur);
2635
+ }
2636
+ if (dur <= 0) {
2637
+ throw new TypeError('A "duration" of a spring must be positive, but is ' + dur);
2638
+ }
2639
+ };
2640
+ var defaultSpringConfig = {
2641
+ damping: 10,
2642
+ mass: 1,
2643
+ stiffness: 100,
2644
+ overshootClamping: false
2645
+ };
2646
+ var advanceCache = {};
2647
+ function advance({
2648
+ animation,
2649
+ now,
2650
+ config
2651
+ }) {
2652
+ const { toValue, lastTimestamp, current, velocity } = animation;
2653
+ const deltaTime = Math.min(now - lastTimestamp, 64);
2654
+ if (config.damping <= 0) {
2655
+ throw new Error("Spring damping must be greater than 0, otherwise the spring() animation will never end, causing an infinite loop.");
2656
+ }
2657
+ const c2 = config.damping;
2658
+ const m = config.mass;
2659
+ const k = config.stiffness;
2660
+ const cacheKey = [
2661
+ toValue,
2662
+ lastTimestamp,
2663
+ current,
2664
+ velocity,
2665
+ c2,
2666
+ m,
2667
+ k,
2668
+ now
2669
+ ].join("-");
2670
+ if (advanceCache[cacheKey]) {
2671
+ return advanceCache[cacheKey];
2672
+ }
2673
+ const v0 = -velocity;
2674
+ const x0 = toValue - current;
2675
+ const zeta = c2 / (2 * Math.sqrt(k * m));
2676
+ const omega0 = Math.sqrt(k / m);
2677
+ const omega1 = omega0 * Math.sqrt(1 - zeta ** 2);
2678
+ const t = deltaTime / 1000;
2679
+ const sin1 = Math.sin(omega1 * t);
2680
+ const cos1 = Math.cos(omega1 * t);
2681
+ const underDampedEnvelope = Math.exp(-zeta * omega0 * t);
2682
+ const underDampedFrag1 = underDampedEnvelope * (sin1 * ((v0 + zeta * omega0 * x0) / omega1) + x0 * cos1);
2683
+ const underDampedPosition = toValue - underDampedFrag1;
2684
+ const underDampedVelocity = zeta * omega0 * underDampedFrag1 - underDampedEnvelope * (cos1 * (v0 + zeta * omega0 * x0) - omega1 * x0 * sin1);
2685
+ const criticallyDampedEnvelope = Math.exp(-omega0 * t);
2686
+ const criticallyDampedPosition = toValue - criticallyDampedEnvelope * (x0 + (v0 + omega0 * x0) * t);
2687
+ const criticallyDampedVelocity = criticallyDampedEnvelope * (v0 * (t * omega0 - 1) + t * x0 * omega0 * omega0);
2688
+ const animationNode = {
2689
+ toValue,
2690
+ prevPosition: current,
2691
+ lastTimestamp: now,
2692
+ current: zeta < 1 ? underDampedPosition : criticallyDampedPosition,
2693
+ velocity: zeta < 1 ? underDampedVelocity : criticallyDampedVelocity
2694
+ };
2695
+ advanceCache[cacheKey] = animationNode;
2696
+ return animationNode;
2697
+ }
2698
+ var calculationCache = {};
2699
+ function springCalculation({
2700
+ frame,
2701
+ fps,
2702
+ config = {}
2703
+ }) {
2704
+ const from = 0;
2705
+ const to = 1;
2706
+ const cacheKey = [
2707
+ frame,
2708
+ fps,
2709
+ config.damping,
2710
+ config.mass,
2711
+ config.overshootClamping,
2712
+ config.stiffness
2713
+ ].join("-");
2714
+ if (calculationCache[cacheKey]) {
2715
+ return calculationCache[cacheKey];
2716
+ }
2717
+ let animation = {
2718
+ lastTimestamp: 0,
2719
+ current: from,
2720
+ toValue: to,
2721
+ velocity: 0,
2722
+ prevPosition: 0
2723
+ };
2724
+ const frameClamped = Math.max(0, frame);
2725
+ const unevenRest = frameClamped % 1;
2726
+ for (let f = 0;f <= Math.floor(frameClamped); f++) {
2727
+ if (f === Math.floor(frameClamped)) {
2728
+ f += unevenRest;
2729
+ }
2730
+ const time = f / fps * 1000;
2731
+ animation = advance({
2732
+ animation,
2733
+ now: time,
2734
+ config: {
2735
+ ...defaultSpringConfig,
2736
+ ...config
2737
+ }
2738
+ });
2739
+ }
2740
+ calculationCache[cacheKey] = animation;
2741
+ return animation;
2742
+ }
2743
+ var cache = new Map;
2744
+ function measureSpring({
2745
+ fps,
2746
+ config = {},
2747
+ threshold = 0.005
2748
+ }) {
2749
+ if (typeof threshold !== "number") {
2750
+ throw new TypeError(\`threshold must be a number, got \${threshold} of type \${typeof threshold}\`);
2751
+ }
2752
+ if (threshold === 0) {
2753
+ return Infinity;
2754
+ }
2755
+ if (threshold === 1) {
2756
+ return 0;
2757
+ }
2758
+ if (isNaN(threshold)) {
2759
+ throw new TypeError("Threshold is NaN");
2760
+ }
2761
+ if (!Number.isFinite(threshold)) {
2762
+ throw new TypeError("Threshold is not finite");
2763
+ }
2764
+ if (threshold < 0) {
2765
+ throw new TypeError("Threshold is below 0");
2766
+ }
2767
+ const cacheKey = [
2768
+ fps,
2769
+ config.damping,
2770
+ config.mass,
2771
+ config.overshootClamping,
2772
+ config.stiffness,
2773
+ threshold
2774
+ ].join("-");
2775
+ if (cache.has(cacheKey)) {
2776
+ return cache.get(cacheKey);
2777
+ }
2778
+ validateFps(fps, "to the measureSpring() function", false);
2779
+ let frame = 0;
2780
+ let finishedFrame = 0;
2781
+ const calc = () => {
2782
+ return springCalculation({
2783
+ fps,
2784
+ frame,
2785
+ config
2786
+ });
2787
+ };
2788
+ let animation = calc();
2789
+ const calcDifference = () => {
2790
+ return Math.abs(animation.current - animation.toValue);
2791
+ };
2792
+ let difference = calcDifference();
2793
+ while (difference >= threshold) {
2794
+ frame++;
2795
+ animation = calc();
2796
+ difference = calcDifference();
2797
+ }
2798
+ finishedFrame = frame;
2799
+ for (let i = 0;i < 20; i++) {
2800
+ frame++;
2801
+ animation = calc();
2802
+ difference = calcDifference();
2803
+ if (difference >= threshold) {
2804
+ i = 0;
2805
+ finishedFrame = frame + 1;
2806
+ }
2807
+ }
2808
+ cache.set(cacheKey, finishedFrame);
2809
+ return finishedFrame;
2810
+ }
2811
+ function spring({
2812
+ frame: passedFrame,
2813
+ fps,
2814
+ config = {},
2815
+ from = 0,
2816
+ to = 1,
2817
+ durationInFrames: passedDurationInFrames,
2818
+ durationRestThreshold,
2819
+ delay = 0,
2820
+ reverse = false
2821
+ }) {
2822
+ validateSpringDuration(passedDurationInFrames);
2823
+ validateFrame({
2824
+ frame: passedFrame,
2825
+ durationInFrames: Infinity,
2826
+ allowFloats: true
2827
+ });
2828
+ validateFps(fps, "to spring()", false);
2829
+ const needsToCalculateNaturalDuration = reverse || typeof passedDurationInFrames !== "undefined";
2830
+ const naturalDuration = needsToCalculateNaturalDuration ? measureSpring({
2831
+ fps,
2832
+ config,
2833
+ threshold: durationRestThreshold
2834
+ }) : undefined;
2835
+ const naturalDurationGetter = needsToCalculateNaturalDuration ? {
2836
+ get: () => naturalDuration
2837
+ } : {
2838
+ get: () => {
2839
+ throw new Error("did not calculate natural duration, this is an error with Remotion. Please report");
2840
+ }
2841
+ };
2842
+ const reverseProcessed = reverse ? (passedDurationInFrames ?? naturalDurationGetter.get()) - passedFrame : passedFrame;
2843
+ const delayProcessed = reverseProcessed + (reverse ? delay : -delay);
2844
+ const durationProcessed = passedDurationInFrames === undefined ? delayProcessed : delayProcessed / (passedDurationInFrames / naturalDurationGetter.get());
2845
+ if (passedDurationInFrames && delayProcessed > passedDurationInFrames) {
2846
+ return to;
2847
+ }
2848
+ const spr = springCalculation({
2849
+ fps,
2850
+ frame: durationProcessed,
2851
+ config
2852
+ });
2853
+ const inner = config.overshootClamping ? to >= from ? Math.min(spr.current, to) : Math.max(spr.current, to) : spr.current;
2854
+ const interpolated = from === 0 && to === 1 ? inner : interpolate(inner, [0, 1], [from, to]);
2855
+ return interpolated;
2856
+ }
2857
+ var clampUnit = (t) => Math.min(1, Math.max(0, t));
2858
+ var springEasingDurationInFrames = 30;
2859
+
2860
+ class Easing {
2861
+ static step0(n) {
2862
+ return n > 0 ? 1 : 0;
2863
+ }
2864
+ static step1(n) {
2865
+ return n >= 1 ? 1 : 0;
2866
+ }
2867
+ static linear(t) {
2868
+ return t;
2869
+ }
2870
+ static ease(t) {
2871
+ return Easing.bezier(0.42, 0, 1, 1)(t);
2872
+ }
2873
+ static quad(t) {
2874
+ return t * t;
2875
+ }
2876
+ static cubic(t) {
2877
+ return t * t * t;
2878
+ }
2879
+ static poly(n) {
2880
+ return (t) => t ** n;
2881
+ }
2882
+ static sin(t) {
2883
+ return 1 - Math.cos(t * Math.PI / 2);
2884
+ }
2885
+ static circle(t) {
2886
+ const u = clampUnit(t);
2887
+ return 1 - Math.sqrt(1 - u * u);
2888
+ }
2889
+ static exp(t) {
2890
+ return 2 ** (10 * (t - 1));
2891
+ }
2892
+ static elastic(bounciness = 1) {
2893
+ const p = bounciness * Math.PI;
2894
+ return (t) => 1 - Math.cos(t * Math.PI / 2) ** 3 * Math.cos(t * p);
2895
+ }
2896
+ static back(s = 1.70158) {
2897
+ return (t) => t * t * ((s + 1) * t - s);
2898
+ }
2899
+ static spring({
2900
+ allowTail = false,
2901
+ durationRestThreshold,
2902
+ ...config
2903
+ } = {}) {
2904
+ const easing = (t) => {
2905
+ if (t <= 0) {
2906
+ return 0;
2907
+ }
2908
+ if (!allowTail && t >= 1) {
2909
+ return 1;
2910
+ }
2911
+ if (allowTail) {
2912
+ return spring({
2913
+ fps: springEasingDurationInFrames,
2914
+ frame: t * measureSpring({
2915
+ fps: springEasingDurationInFrames,
2916
+ config,
2917
+ threshold: durationRestThreshold
2918
+ }),
2919
+ config
2920
+ });
2921
+ }
2922
+ return spring({
2923
+ fps: springEasingDurationInFrames,
2924
+ frame: t * springEasingDurationInFrames,
2925
+ config,
2926
+ durationInFrames: springEasingDurationInFrames,
2927
+ durationRestThreshold
2928
+ });
2929
+ };
2930
+ return Object.assign(easing, {
2931
+ remotionShouldExtendRight: allowTail
2932
+ });
2933
+ }
2934
+ static bounce(t) {
2935
+ const u = clampUnit(t);
2936
+ if (u < 1 / 2.75) {
2937
+ return 7.5625 * u * u;
2938
+ }
2939
+ if (u < 2 / 2.75) {
2940
+ const t2_ = u - 1.5 / 2.75;
2941
+ return 7.5625 * t2_ * t2_ + 0.75;
2942
+ }
2943
+ if (u < 2.5 / 2.75) {
2944
+ const t2_ = u - 2.25 / 2.75;
2945
+ return 7.5625 * t2_ * t2_ + 0.9375;
2946
+ }
2947
+ const t2 = u - 2.625 / 2.75;
2948
+ return 7.5625 * t2 * t2 + 0.984375;
2949
+ }
2950
+ static bezier(x1, y1, x2, y2) {
2951
+ return bezier(x1, y1, x2, y2);
2952
+ }
2953
+ static in(easing) {
2954
+ return easing;
2955
+ }
2956
+ static out(easing) {
2957
+ return (t) => 1 - easing(1 - t);
2958
+ }
2959
+ static inOut(easing) {
2960
+ return (t) => {
2961
+ if (t < 0.5) {
2962
+ return easing(t * 2) / 2;
2963
+ }
2964
+ return 1 - easing((1 - t) * 2) / 2;
2965
+ };
2966
+ }
2967
+ }
1877
2968
  var normalizeNumber = (value) => {
1878
2969
  return Math.round(value * 1e6) / 1e6;
1879
2970
  };
@@ -1944,10 +3035,13 @@ var transformOriginCenter = { value: 50, unit: "%" };
1944
3035
  var stringifyNumber = (value) => {
1945
3036
  return String(normalizeNumber(value));
1946
3037
  };
3038
+
3039
+ class UnsupportedStringInterpolationValueError extends TypeError {
3040
+ }
1947
3041
  var parseStringInterpolationComponent = (component, value) => {
1948
3042
  const match = cssNumberRegex.exec(component);
1949
3043
  if (match === null) {
1950
- throw new TypeError(\`Cannot interpolate "\${value}" because "\${component}" is not a supported scale, translate, or rotate value\`);
3044
+ throw new UnsupportedStringInterpolationValueError(\`Cannot interpolate "\${value}" because "\${component}" is not a supported scale, translate, or rotate value\`);
1951
3045
  }
1952
3046
  const unit = match[2] ?? null;
1953
3047
  const numberValue = Number(match[1]);
@@ -2064,9 +3158,45 @@ var parseTransformOriginValue = (output, parts) => {
2064
3158
  });
2065
3159
  return {
2066
3160
  kind: "translate",
2067
- values: [x.value, y.value, z.value],
2068
- units: [x.unit, y.unit, z.unit],
2069
- dimensions: parts[2] === undefined ? 2 : 3
3161
+ values: [x.value, y.value, z.value, 0],
3162
+ units: [x.unit, y.unit, z.unit, null],
3163
+ dimensions: parts[2] === undefined ? 2 : 3,
3164
+ axisRotation: false
3165
+ };
3166
+ };
3167
+ var parseAxisRotationValue = (output) => {
3168
+ const parts = output.trim().split(/\\s+/);
3169
+ const keywordAxis = parts.length === 2 ? parts[0].toLowerCase() : null;
3170
+ if (keywordAxis === "x" || keywordAxis === "y" || keywordAxis === "z") {
3171
+ const keywordAngle = parseStringInterpolationComponent(parts[1], output);
3172
+ if (keywordAngle.kind !== "rotate") {
3173
+ return null;
3174
+ }
3175
+ return {
3176
+ kind: "rotate",
3177
+ values: keywordAxis === "x" ? [1, 0, 0, keywordAngle.value] : keywordAxis === "y" ? [0, 1, 0, keywordAngle.value] : [0, 0, 1, keywordAngle.value],
3178
+ units: [null, null, null, keywordAngle.unit],
3179
+ dimensions: 4,
3180
+ axisRotation: true
3181
+ };
3182
+ }
3183
+ if (parts.length !== 4) {
3184
+ return null;
3185
+ }
3186
+ const axis = parts.slice(0, 3).map(Number);
3187
+ if (!axis.every(Number.isFinite)) {
3188
+ return null;
3189
+ }
3190
+ const vectorAngle = parseStringInterpolationComponent(parts[3], output);
3191
+ if (vectorAngle.kind !== "rotate") {
3192
+ return null;
3193
+ }
3194
+ return {
3195
+ kind: "rotate",
3196
+ values: [axis[0], axis[1], axis[2], vectorAngle.value],
3197
+ units: [null, null, null, vectorAngle.unit],
3198
+ dimensions: 4,
3199
+ axisRotation: true
2070
3200
  };
2071
3201
  };
2072
3202
  var parseStringInterpolationValue = (output) => {
@@ -2076,11 +3206,16 @@ var parseStringInterpolationValue = (output) => {
2076
3206
  }
2077
3207
  return {
2078
3208
  kind: "scale",
2079
- values: [output, output, 1],
2080
- units: [null, null, null],
2081
- dimensions: 1
3209
+ values: [output, output, 1, 0],
3210
+ units: [null, null, null, null],
3211
+ dimensions: 1,
3212
+ axisRotation: false
2082
3213
  };
2083
3214
  }
3215
+ const axisRotation = parseAxisRotationValue(output);
3216
+ if (axisRotation !== null) {
3217
+ return axisRotation;
3218
+ }
2084
3219
  const parts = output.trim().split(/\\s+/);
2085
3220
  if (parts.length < 1 || parts.length > 3 || parts[0] === "") {
2086
3221
  throw new TypeError(\`String outputRange values must contain 1 to 3 components, but got "\${output}"\`);
@@ -2101,24 +3236,35 @@ var parseStringInterpolationValue = (output) => {
2101
3236
  const z = parsed[2]?.value ?? 1;
2102
3237
  return {
2103
3238
  kind,
2104
- values: [x, y, z],
2105
- units: [null, null, null],
2106
- dimensions: parsed.length
3239
+ values: [x, y, z, 0],
3240
+ units: [null, null, null, null],
3241
+ dimensions: parsed.length,
3242
+ axisRotation: false
2107
3243
  };
2108
3244
  }
2109
3245
  return {
2110
3246
  kind,
2111
- values: [parsed[0].value, parsed[1]?.value ?? 0, parsed[2]?.value ?? 0],
2112
- units: [parsed[0].unit, parsed[1]?.unit ?? null, parsed[2]?.unit ?? null],
2113
- dimensions: parsed.length
3247
+ values: [parsed[0].value, parsed[1]?.value ?? 0, parsed[2]?.value ?? 0, 0],
3248
+ units: [
3249
+ parsed[0].unit,
3250
+ parsed[1]?.unit ?? null,
3251
+ parsed[2]?.unit ?? null,
3252
+ null
3253
+ ],
3254
+ dimensions: parsed.length,
3255
+ axisRotation: false
2114
3256
  };
2115
3257
  };
2116
3258
  var serializeStringInterpolationValue = ({
2117
3259
  kind,
2118
3260
  values,
2119
3261
  units,
2120
- dimensions
3262
+ dimensions,
3263
+ axisRotation
2121
3264
  }) => {
3265
+ if (axisRotation) {
3266
+ return \`\${stringifyNumber(values[0])} \${stringifyNumber(values[1])} \${stringifyNumber(values[2])} \${stringifyNumber(values[3])}\${units[3]}\`;
3267
+ }
2122
3268
  if (kind === "scale") {
2123
3269
  return values.slice(0, dimensions).map((value) => stringifyNumber(value)).join(" ");
2124
3270
  }
@@ -2286,7 +3432,26 @@ var interpolateString = ({
2286
3432
  outputRange,
2287
3433
  options
2288
3434
  }) => {
2289
- const parsedOutputRange = outputRange.map(parseStringInterpolationValue);
3435
+ const initiallyParsedOutputRange = outputRange.map(parseStringInterpolationValue);
3436
+ const hasAxisRotation = initiallyParsedOutputRange.some((parsed) => parsed.axisRotation);
3437
+ const parsedOutputRange = hasAxisRotation ? initiallyParsedOutputRange.map((parsed) => {
3438
+ if (parsed.kind !== "rotate") {
3439
+ return parsed;
3440
+ }
3441
+ if (parsed.axisRotation) {
3442
+ return parsed;
3443
+ }
3444
+ if (parsed.dimensions !== 1) {
3445
+ throw new TypeError("Cannot interpolate a multi-angle rotate value with an axis rotation");
3446
+ }
3447
+ return {
3448
+ kind: "rotate",
3449
+ values: [0, 0, 1, parsed.values[0]],
3450
+ units: [null, null, null, parsed.units[0]],
3451
+ dimensions: 4,
3452
+ axisRotation: true
3453
+ };
3454
+ }) : initiallyParsedOutputRange;
2290
3455
  const kind = parsedOutputRange[0]?.kind;
2291
3456
  if (kind === undefined) {
2292
3457
  throw new Error("outputRange must have at least 1 element");
@@ -2298,12 +3463,16 @@ var interpolateString = ({
2298
3463
  }
2299
3464
  const dimensions = Math.max(...parsedOutputRange.map((parsed) => parsed.dimensions));
2300
3465
  const units = [
3466
+ null,
2301
3467
  null,
2302
3468
  null,
2303
3469
  null
2304
3470
  ];
2305
3471
  if (kind !== "scale") {
2306
3472
  for (let axis = 0;axis < dimensions; axis++) {
3473
+ if (hasAxisRotation && axis < 3) {
3474
+ continue;
3475
+ }
2307
3476
  for (const parsed of parsedOutputRange) {
2308
3477
  const unit = parsed.units[axis];
2309
3478
  if (unit === null) {
@@ -2322,7 +3491,7 @@ var interpolateString = ({
2322
3491
  }
2323
3492
  }
2324
3493
  }
2325
- const values = [0, 0, 0];
3494
+ const values = [0, 0, 0, 0];
2326
3495
  for (let axis = 0;axis < dimensions; axis++) {
2327
3496
  values[axis] = interpolateNumber({
2328
3497
  input,
@@ -2335,9 +3504,56 @@ var interpolateString = ({
2335
3504
  kind,
2336
3505
  values,
2337
3506
  units,
2338
- dimensions
3507
+ dimensions,
3508
+ axisRotation: hasAxisRotation
2339
3509
  });
2340
3510
  };
3511
+ var interpolateDiscreteString = ({
3512
+ input,
3513
+ inputRange,
3514
+ outputRange,
3515
+ options
3516
+ }) => {
3517
+ if (inputRange.length === 1) {
3518
+ return outputRange[0];
3519
+ }
3520
+ for (let segmentIndex = 0;segmentIndex < inputRange.length - 1; segmentIndex++) {
3521
+ if (resolveEasingForSegment({
3522
+ easing: options?.easing,
3523
+ segmentIndex
3524
+ }) !== Easing.step1) {
3525
+ throw new TypeError("Non-numeric strings can only be interpolated using Easing.step1");
3526
+ }
3527
+ }
3528
+ const posterizedInput = options?.posterize === undefined ? input : Math.floor(input / options.posterize) * options.posterize;
3529
+ const inputMin = inputRange[0];
3530
+ const inputMax = inputRange[inputRange.length - 1];
3531
+ let resolvedInput = posterizedInput;
3532
+ if (resolvedInput < inputMin) {
3533
+ if (options?.extrapolateLeft === "identity") {
3534
+ throw new TypeError('extrapolateLeft: "identity" is not supported for non-numeric strings');
3535
+ }
3536
+ if (options?.extrapolateLeft === "wrap") {
3537
+ const wrapRange = inputMax - inputMin;
3538
+ resolvedInput = ((resolvedInput - inputMin) % wrapRange + wrapRange) % wrapRange + inputMin;
3539
+ } else {
3540
+ return outputRange[0];
3541
+ }
3542
+ }
3543
+ if (resolvedInput > inputMax) {
3544
+ if (options?.extrapolateRight === "identity") {
3545
+ throw new TypeError('extrapolateRight: "identity" is not supported for non-numeric strings');
3546
+ }
3547
+ if (options?.extrapolateRight === "wrap") {
3548
+ const wrapRange = inputMax - inputMin;
3549
+ resolvedInput = ((resolvedInput - inputMin) % wrapRange + wrapRange) % wrapRange + inputMin;
3550
+ } else {
3551
+ return outputRange[outputRange.length - 1];
3552
+ }
3553
+ }
3554
+ const range = findRange(resolvedInput, inputRange);
3555
+ return resolvedInput >= inputRange[range + 1] ? outputRange[range + 1] : outputRange[range];
3556
+ };
2341
3557
  var validateTupleOutputRange = (outputRange) => {
2342
3558
  const dimensions = outputRange[0]?.length;
2343
3559
  if (dimensions === undefined) {
@@ -2452,7 +3668,30 @@ function interpolate(input, inputRange, outputRange, options) {
2452
3668
  if (!outputRange.every((output) => typeof output === "string" || typeof output === "number")) {
2453
3669
  throw new TypeError("outputRange must contain only numbers, or supported scale, translate, and rotate strings");
2454
3670
  }
2455
- return interpolateString({ input, inputRange, outputRange, options });
3671
+ try {
3672
+ return interpolateString({ input, inputRange, outputRange, options });
3673
+ } catch (error) {
3674
+ if (!outputRange.every((output) => typeof output === "string")) {
3675
+ throw error;
3676
+ }
3677
+ const hasNonNumericString = outputRange.some((output) => {
3678
+ try {
3679
+ parseStringInterpolationValue(output);
3680
+ return false;
3681
+ } catch (parseError) {
3682
+ return parseError instanceof UnsupportedStringInterpolationValueError;
3683
+ }
3684
+ });
3685
+ if (!hasNonNumericString) {
3686
+ throw error;
3687
+ }
3688
+ return interpolateDiscreteString({
3689
+ input,
3690
+ inputRange,
3691
+ outputRange,
3692
+ options
3693
+ });
3694
+ }
2456
3695
  }
2457
3696
  if (outputRange.every((output) => Array.isArray(output))) {
2458
3697
  return interpolateTuple({ input, inputRange, outputRange, options });
@@ -2921,8 +4160,8 @@ function hslToRgb(h, s, l) {
2921
4160
  const p = 2 * l - q;
2922
4161
  const r = hue2rgb(p, q, h + 1 / 3);
2923
4162
  const g = hue2rgb(p, q, h);
2924
- const b = hue2rgb(p, q, h - 1 / 3);
2925
- return Math.round(r * 255) << 24 | Math.round(g * 255) << 16 | Math.round(b * 255) << 8;
4163
+ const b2 = hue2rgb(p, q, h - 1 / 3);
4164
+ return Math.round(r * 255) << 24 | Math.round(g * 255) << 16 | Math.round(b2 * 255) << 8;
2926
4165
  }
2927
4166
  function parse255(str) {
2928
4167
  const int = Number.parseInt(str, 10);
@@ -2986,25 +4225,25 @@ function parseModernAlpha(str) {
2986
4225
  }
2987
4226
  return Math.max(0, Math.min(1, Number.parseFloat(str)));
2988
4227
  }
2989
- function linearToSrgb(c) {
2990
- if (c <= 0.0031308)
2991
- return 12.92 * c;
2992
- return 1.055 * c ** (1 / 2.4) - 0.055;
4228
+ function linearToSrgb(c2) {
4229
+ if (c2 <= 0.0031308)
4230
+ return 12.92 * c2;
4231
+ return 1.055 * c2 ** (1 / 2.4) - 0.055;
2993
4232
  }
2994
4233
  function clamp01(v) {
2995
4234
  return Math.max(0, Math.min(1, v));
2996
4235
  }
2997
- function rgbFloatToInt(r, g, b, alpha) {
4236
+ function rgbFloatToInt(r, g, b2, alpha) {
2998
4237
  const ri = Math.round(clamp01(r) * 255);
2999
4238
  const gi = Math.round(clamp01(g) * 255);
3000
- const bi = Math.round(clamp01(b) * 255);
4239
+ const bi = Math.round(clamp01(b2) * 255);
3001
4240
  const ai = Math.round(clamp01(alpha) * 255);
3002
4241
  return (ri << 24 | gi << 16 | bi << 8 | ai) >>> 0;
3003
4242
  }
3004
- function oklabToSrgb(L, a, b) {
3005
- const l_ = L + 0.3963377774 * a + 0.2158037573 * b;
3006
- const m_ = L - 0.1055613458 * a - 0.0638541728 * b;
3007
- const s_ = L - 0.0894841775 * a - 1.291485548 * b;
4243
+ function oklabToSrgb(L, a2, b2) {
4244
+ const l_ = L + 0.3963377774 * a2 + 0.2158037573 * b2;
4245
+ const m_ = L - 0.1055613458 * a2 - 0.0638541728 * b2;
4246
+ const s_ = L - 0.0894841775 * a2 - 1.291485548 * b2;
3008
4247
  const l = l_ * l_ * l_;
3009
4248
  const m = m_ * m_ * m_;
3010
4249
  const s = s_ * s_ * s_;
@@ -3013,15 +4252,15 @@ function oklabToSrgb(L, a, b) {
3013
4252
  const bLin = -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s;
3014
4253
  return [linearToSrgb(rLin), linearToSrgb(gLin), linearToSrgb(bLin)];
3015
4254
  }
3016
- function labToSrgb(L, a, b) {
4255
+ function labToSrgb(L, a2, b2) {
3017
4256
  const epsilon = 216 / 24389;
3018
4257
  const kappa = 24389 / 27;
3019
4258
  const Xn = 0.95047;
3020
4259
  const Yn = 1;
3021
4260
  const Zn = 1.08883;
3022
4261
  const fy = (L + 16) / 116;
3023
- const fx = a / 500 + fy;
3024
- const fz = fy - b / 200;
4262
+ const fx = a2 / 500 + fy;
4263
+ const fz = fy - b2 / 200;
3025
4264
  const fx3 = fx * fx * fx;
3026
4265
  const fz3 = fz * fz * fz;
3027
4266
  const xr = fx3 > epsilon ? fx3 : (116 * fx - 16) / kappa;
@@ -3253,27 +4492,27 @@ function normalizeColor(color) {
3253
4492
  const H = parseHueAngle(match[3]);
3254
4493
  const alpha = parseModernAlpha(match[4]);
3255
4494
  const hRad = H * Math.PI / 180;
3256
- const [r, g, b] = oklabToSrgb(L, C * Math.cos(hRad), C * Math.sin(hRad));
3257
- return rgbFloatToInt(r, g, b, alpha);
4495
+ const [r, g, b2] = oklabToSrgb(L, C * Math.cos(hRad), C * Math.sin(hRad));
4496
+ return rgbFloatToInt(r, g, b2, alpha);
3258
4497
  }
3259
4498
  }
3260
4499
  if (matchers.oklab) {
3261
4500
  if (match = matchers.oklab.exec(color)) {
3262
4501
  const L = parseModernComponent(match[1], 1);
3263
- const a = parseModernComponent(match[2], 0.4);
3264
- const b = parseModernComponent(match[3], 0.4);
4502
+ const a2 = parseModernComponent(match[2], 0.4);
4503
+ const b2 = parseModernComponent(match[3], 0.4);
3265
4504
  const alpha = parseModernAlpha(match[4]);
3266
- const [r, g, bl] = oklabToSrgb(L, a, b);
4505
+ const [r, g, bl] = oklabToSrgb(L, a2, b2);
3267
4506
  return rgbFloatToInt(r, g, bl, alpha);
3268
4507
  }
3269
4508
  }
3270
4509
  if (matchers.lab) {
3271
4510
  if (match = matchers.lab.exec(color)) {
3272
4511
  const L = parseModernComponent(match[1], 100);
3273
- const a = parseModernComponent(match[2], 125);
3274
- const b = parseModernComponent(match[3], 125);
4512
+ const a2 = parseModernComponent(match[2], 125);
4513
+ const b2 = parseModernComponent(match[3], 125);
3275
4514
  const alpha = parseModernAlpha(match[4]);
3276
- const [r, g, bl] = labToSrgb(L, a, b);
4515
+ const [r, g, bl] = labToSrgb(L, a2, b2);
3277
4516
  return rgbFloatToInt(r, g, bl, alpha);
3278
4517
  }
3279
4518
  }
@@ -3352,30 +4591,6 @@ var serializeScaleValue = ([x, y, z]) => {
3352
4591
  return \`\${normalizedX} \${normalizedY} \${normalizedZ}\`;
3353
4592
  };
3354
4593
  var ENABLE_V5_BREAKING_CHANGES = false;
3355
- var validateFrame = ({
3356
- allowFloats,
3357
- durationInFrames,
3358
- frame
3359
- }) => {
3360
- if (typeof frame === "undefined") {
3361
- throw new TypeError(\`Argument missing for parameter "frame"\`);
3362
- }
3363
- if (typeof frame !== "number") {
3364
- throw new TypeError(\`Argument passed for "frame" is not a number: \${frame}\`);
3365
- }
3366
- if (!Number.isFinite(frame)) {
3367
- throw new RangeError(\`Frame \${frame} is not finite\`);
3368
- }
3369
- if (frame % 1 !== 0 && !allowFloats) {
3370
- throw new RangeError(\`Argument for frame must be an integer, but got \${frame}\`);
3371
- }
3372
- if (frame < 0 && frame < -durationInFrames) {
3373
- throw new RangeError(\`Cannot use frame \${frame}: Duration of composition is \${durationInFrames}, therefore the lowest frame that can be rendered is \${-durationInFrames}\`);
3374
- }
3375
- if (frame > durationInFrames - 1) {
3376
- throw new RangeError(\`Cannot use frame \${frame}: Duration of composition is \${durationInFrames}, therefore the highest frame that can be rendered is \${durationInFrames - 1}\`);
3377
- }
3378
- };
3379
4594
  var validCodecs = [
3380
4595
  "h264",
3381
4596
  "h265",
@@ -3447,23 +4662,6 @@ function validateDurationInFrames(durationInFrames, options) {
3447
4662
  throw new TypeError(\`The "durationInFrames" prop \${component} must be finite, but got \${durationInFrames}.\`);
3448
4663
  }
3449
4664
  }
3450
- function validateFps(fps, location, isGif) {
3451
- if (typeof fps !== "number") {
3452
- throw new Error(\`"fps" must be a number, but you passed a value of type \${typeof fps} \${location}\`);
3453
- }
3454
- if (!Number.isFinite(fps)) {
3455
- throw new Error(\`"fps" must be a finite, but you passed \${fps} \${location}\`);
3456
- }
3457
- if (isNaN(fps)) {
3458
- throw new Error(\`"fps" must not be NaN, but got \${fps} \${location}\`);
3459
- }
3460
- if (fps <= 0) {
3461
- throw new TypeError(\`"fps" must be positive, but got \${fps} \${location}\`);
3462
- }
3463
- if (isGif && fps > 50) {
3464
- throw new TypeError(\`The FPS for a GIF cannot be higher than 50. Use the --every-nth-frame option to lower the FPS: https://remotion.dev/docs/render-as-gif\`);
3465
- }
3466
- }
3467
4665
  var getExpectedMediaFrameUncorrected = ({
3468
4666
  frame,
3469
4667
  playbackRate,