@remotion/promo-pages 4.0.472 → 4.0.473

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Homepage.js CHANGED
@@ -2332,7 +2332,7 @@ var getComponentsToAddStacksTo = () => componentsToAddStacksTo;
2332
2332
  var addSequenceStackTraces = (component) => {
2333
2333
  componentsToAddStacksTo.push(component);
2334
2334
  };
2335
- var VERSION = "4.0.472";
2335
+ var VERSION = "4.0.473";
2336
2336
  var checkMultipleRemotionVersions = () => {
2337
2337
  if (typeof globalThis === "undefined") {
2338
2338
  return;
@@ -2371,7 +2371,8 @@ __export2(exports_timeline_position_state, {
2371
2371
  useAbsoluteTimelinePosition: () => useAbsoluteTimelinePosition,
2372
2372
  persistCurrentFrame: () => persistCurrentFrame,
2373
2373
  getInitialFrameState: () => getInitialFrameState,
2374
- getFrameForComposition: () => getFrameForComposition
2374
+ getFrameForComposition: () => getFrameForComposition,
2375
+ clampFrameToCompositionRange: () => clampFrameToCompositionRange
2375
2376
  });
2376
2377
  function mulberry32(a) {
2377
2378
  let t = a + 1831565813;
@@ -2508,6 +2509,9 @@ var getFrameForComposition = (composition) => {
2508
2509
  }
2509
2510
  return window.remotion_initialFrame ?? 0;
2510
2511
  };
2512
+ var clampFrameToCompositionRange = (frame, durationInFrames) => {
2513
+ return Math.max(0, Math.min(Math.max(0, durationInFrames - 1), frame));
2514
+ };
2511
2515
  var useTimelinePositionFromContext = (state) => {
2512
2516
  const videoConfig = useVideo();
2513
2517
  const env = useRemotionEnvironment();
@@ -2515,7 +2519,7 @@ var useTimelinePositionFromContext = (state) => {
2515
2519
  return typeof window === "undefined" ? 0 : window.remotion_initialFrame ?? 0;
2516
2520
  }
2517
2521
  const unclamped = state.frame[videoConfig.id] ?? (env.isPlayer ? 0 : getFrameForComposition(videoConfig.id));
2518
- return Math.min(videoConfig.durationInFrames - 1, unclamped);
2522
+ return clampFrameToCompositionRange(unclamped, videoConfig.durationInFrames);
2519
2523
  };
2520
2524
  var useTimelineContext = () => {
2521
2525
  const state = useContext10(TimelineContext);
@@ -2703,7 +2707,6 @@ var sequenceVisualStyleSchema = {
2703
2707
  },
2704
2708
  "style.scale": {
2705
2709
  type: "scale",
2706
- min: 0.05,
2707
2710
  max: 100,
2708
2711
  step: 0.01,
2709
2712
  default: 1,
@@ -2784,6 +2787,11 @@ var sequenceSchema = {
2784
2787
  }
2785
2788
  }
2786
2789
  };
2790
+ var sequenceSchemaWithoutFrom = {
2791
+ hidden: hiddenField,
2792
+ durationInFrames: durationInFramesField,
2793
+ layout: sequenceSchema.layout
2794
+ };
2787
2795
  var sequenceSchemaDefaultLayoutNone = {
2788
2796
  ...sequenceSchema,
2789
2797
  layout: {
@@ -3437,6 +3445,40 @@ var interpolateString = ({
3437
3445
  dimensions
3438
3446
  });
3439
3447
  };
3448
+ var validateTupleOutputRange = (outputRange) => {
3449
+ const dimensions = outputRange[0]?.length;
3450
+ if (dimensions === undefined) {
3451
+ throw new Error("outputRange must have at least 1 element");
3452
+ }
3453
+ if (dimensions === 0) {
3454
+ throw new TypeError("outputRange tuples must contain at least 1 number");
3455
+ }
3456
+ for (const output of outputRange) {
3457
+ if (output.length !== dimensions) {
3458
+ throw new TypeError(`outputRange tuples must all have the same length, but got ${dimensions} and ${output.length}`);
3459
+ }
3460
+ for (const value of output) {
3461
+ if (typeof value !== "number" || !Number.isFinite(value)) {
3462
+ throw new TypeError(`outputRange tuples must contain only finite numbers, but got [${output.join(",")}]`);
3463
+ }
3464
+ }
3465
+ }
3466
+ return dimensions;
3467
+ };
3468
+ var interpolateTuple = ({
3469
+ input,
3470
+ inputRange,
3471
+ outputRange,
3472
+ options
3473
+ }) => {
3474
+ const dimensions = validateTupleOutputRange(outputRange);
3475
+ return new Array(dimensions).fill(true).map((_, axis) => interpolateNumber({
3476
+ input,
3477
+ inputRange,
3478
+ outputRange: outputRange.map((output) => output[axis]),
3479
+ options
3480
+ }));
3481
+ };
3440
3482
  function checkValidInputRange(arr) {
3441
3483
  for (let i = 1;i < arr.length; ++i) {
3442
3484
  if (!(arr[i] > arr[i - 1])) {
@@ -3512,8 +3554,11 @@ function interpolate(input, inputRange, outputRange, options) {
3512
3554
  }
3513
3555
  return interpolateString({ input, inputRange, outputRange, options });
3514
3556
  }
3557
+ if (outputRange.every((output) => Array.isArray(output))) {
3558
+ return interpolateTuple({ input, inputRange, outputRange, options });
3559
+ }
3515
3560
  if (!outputRange.every((output) => typeof output === "number")) {
3516
- throw new TypeError("outputRange must contain only numbers, or supported scale, translate, and rotate strings");
3561
+ throw new TypeError("outputRange must contain only numbers, numeric tuples, or supported scale, translate, and rotate strings");
3517
3562
  }
3518
3563
  checkInfiniteRange("outputRange", outputRange);
3519
3564
  return interpolateNumber({ input, inputRange, outputRange, options });
@@ -4026,8 +4071,9 @@ var interpolateKeyframedStatus = ({
4026
4071
  if (keyframes.length === 0) {
4027
4072
  return null;
4028
4073
  }
4029
- const inputRange = keyframes.map((k) => k.frame);
4030
- const outputs = keyframes.map((k) => k.value);
4074
+ const sortedKeyframes = [...keyframes].sort((a2, b2) => a2.frame - b2.frame);
4075
+ const inputRange = sortedKeyframes.map((k) => k.frame);
4076
+ const outputs = sortedKeyframes.map((k) => k.value);
4031
4077
  if (interpolationFunction === "interpolateColors") {
4032
4078
  if (!outputs.every((v) => typeof v === "string")) {
4033
4079
  return null;
@@ -4877,11 +4923,17 @@ var SequenceRefForwardingFunction = (props, ref) => {
4877
4923
  });
4878
4924
  };
4879
4925
  var SequenceInner = forwardRef3(SequenceRefForwardingFunction);
4926
+ var SequenceWithoutSchema = SequenceInner;
4880
4927
  var Sequence = wrapInSchema({
4881
4928
  Component: SequenceInner,
4882
4929
  schema: sequenceSchema,
4883
4930
  supportsEffects: false
4884
4931
  });
4932
+ var SequenceWithoutFrom = wrapInSchema({
4933
+ Component: SequenceInner,
4934
+ schema: sequenceSchemaWithoutFrom,
4935
+ supportsEffects: false
4936
+ });
4885
4937
  var calculateImageFit = (fit, imageSize, canvasSize) => {
4886
4938
  switch (fit) {
4887
4939
  case "fill": {
@@ -11002,6 +11054,7 @@ var Internals = {
11002
11054
  SequenceStackTracesUpdateContext,
11003
11055
  wrapInSchema,
11004
11056
  sequenceSchema,
11057
+ SequenceWithoutSchema,
11005
11058
  sequenceStyleSchema,
11006
11059
  sequenceVisualStyleSchema,
11007
11060
  sequencePremountSchema,
@@ -11163,6 +11216,7 @@ var SeriesSequenceRefForwardingFunction = ({ children }, _ref) => {
11163
11216
  });
11164
11217
  };
11165
11218
  var SeriesSequence = forwardRef13(SeriesSequenceRefForwardingFunction);
11219
+ var SequenceWithoutSchemaWithRef = SequenceWithoutSchema;
11166
11220
  var SeriesInner = (props2) => {
11167
11221
  const childrenValue = useMemo38(() => {
11168
11222
  let startFrame = 0;
@@ -11205,13 +11259,13 @@ var SeriesInner = (props2) => {
11205
11259
  }
11206
11260
  const currentStartFrame = startFrame + offset;
11207
11261
  startFrame += durationInFramesProp + offset;
11208
- return /* @__PURE__ */ jsx36(Sequence, {
11262
+ return /* @__PURE__ */ jsx36(SequenceWithoutSchemaWithRef, {
11263
+ ref: castedChild.ref,
11209
11264
  name: name || "<Series.Sequence>",
11210
11265
  _remotionInternalDocumentationLink: name ? undefined : "https://www.remotion.dev/docs/series",
11211
11266
  from: currentStartFrame,
11212
11267
  durationInFrames: durationInFramesProp,
11213
11268
  ...passedProps,
11214
- ref: castedChild.ref,
11215
11269
  children: child
11216
11270
  });
11217
11271
  });
@@ -11234,7 +11288,6 @@ var Series = Object.assign(wrapInSchema({
11234
11288
  Sequence: SeriesSequence
11235
11289
  });
11236
11290
  addSequenceStackTraces(Series);
11237
- addSequenceStackTraces(SeriesSequence);
11238
11291
  var validateSpringDuration = (dur) => {
11239
11292
  if (typeof dur === "undefined") {
11240
11293
  return;
@@ -27870,6 +27923,40 @@ var interpolateString2 = ({
27870
27923
  dimensions
27871
27924
  });
27872
27925
  };
27926
+ var validateTupleOutputRange2 = (outputRange) => {
27927
+ const dimensions = outputRange[0]?.length;
27928
+ if (dimensions === undefined) {
27929
+ throw new Error("outputRange must have at least 1 element");
27930
+ }
27931
+ if (dimensions === 0) {
27932
+ throw new TypeError("outputRange tuples must contain at least 1 number");
27933
+ }
27934
+ for (const output of outputRange) {
27935
+ if (output.length !== dimensions) {
27936
+ throw new TypeError(`outputRange tuples must all have the same length, but got ${dimensions} and ${output.length}`);
27937
+ }
27938
+ for (const value of output) {
27939
+ if (typeof value !== "number" || !Number.isFinite(value)) {
27940
+ throw new TypeError(`outputRange tuples must contain only finite numbers, but got [${output.join(",")}]`);
27941
+ }
27942
+ }
27943
+ }
27944
+ return dimensions;
27945
+ };
27946
+ var interpolateTuple2 = ({
27947
+ input,
27948
+ inputRange,
27949
+ outputRange,
27950
+ options: options2
27951
+ }) => {
27952
+ const dimensions = validateTupleOutputRange2(outputRange);
27953
+ return new Array(dimensions).fill(true).map((_, axis) => interpolateNumber2({
27954
+ input,
27955
+ inputRange,
27956
+ outputRange: outputRange.map((output) => output[axis]),
27957
+ options: options2
27958
+ }));
27959
+ };
27873
27960
  function checkValidInputRange2(arr) {
27874
27961
  for (let i = 1;i < arr.length; ++i) {
27875
27962
  if (!(arr[i] > arr[i - 1])) {
@@ -27945,8 +28032,11 @@ function interpolate3(input, inputRange, outputRange, options2) {
27945
28032
  }
27946
28033
  return interpolateString2({ input, inputRange, outputRange, options: options2 });
27947
28034
  }
28035
+ if (outputRange.every((output) => Array.isArray(output))) {
28036
+ return interpolateTuple2({ input, inputRange, outputRange, options: options2 });
28037
+ }
27948
28038
  if (!outputRange.every((output) => typeof output === "number")) {
27949
- throw new TypeError("outputRange must contain only numbers, or supported scale, translate, and rotate strings");
28039
+ throw new TypeError("outputRange must contain only numbers, numeric tuples, or supported scale, translate, and rotate strings");
27950
28040
  }
27951
28041
  checkInfiniteRange2("outputRange", outputRange);
27952
28042
  return interpolateNumber2({ input, inputRange, outputRange, options: options2 });
@@ -28548,7 +28638,6 @@ var sequenceVisualStyleSchema2 = {
28548
28638
  },
28549
28639
  "style.scale": {
28550
28640
  type: "scale",
28551
- min: 0.05,
28552
28641
  max: 100,
28553
28642
  step: 0.01,
28554
28643
  default: 1,
@@ -28629,6 +28718,11 @@ var sequenceSchema2 = {
28629
28718
  }
28630
28719
  }
28631
28720
  };
28721
+ var sequenceSchemaWithoutFrom2 = {
28722
+ hidden: hiddenField2,
28723
+ durationInFrames: durationInFramesField2,
28724
+ layout: sequenceSchema2.layout
28725
+ };
28632
28726
  var sequenceSchemaDefaultLayoutNone2 = {
28633
28727
  ...sequenceSchema2,
28634
28728
  layout: {
@@ -29377,12 +29471,13 @@ var usePlayer = () => {
29377
29471
  }
29378
29472
  const { buffering } = bufferingContext;
29379
29473
  const seek2 = useCallback36((newFrame) => {
29474
+ const frameToSeekTo = config ? Internals.TimelinePosition.clampFrameToCompositionRange(newFrame, config.durationInFrames) : Math.max(0, newFrame);
29380
29475
  if (video?.id) {
29381
- setTimelinePosition((c2) => ({ ...c2, [video.id]: newFrame }));
29476
+ setTimelinePosition((c2) => ({ ...c2, [video.id]: frameToSeekTo }));
29382
29477
  }
29383
- frameRef.current = newFrame;
29384
- emitter.dispatchSeek(newFrame);
29385
- }, [emitter, setTimelinePosition, video?.id]);
29478
+ frameRef.current = frameToSeekTo;
29479
+ emitter.dispatchSeek(frameToSeekTo);
29480
+ }, [config, emitter, setTimelinePosition, video?.id]);
29386
29481
  const play = useCallback36((e) => {
29387
29482
  if (imperativePlaying.current) {
29388
29483
  return;
@@ -40082,7 +40177,7 @@ import {
40082
40177
  import { BufferTarget, StreamTarget } from "mediabunny";
40083
40178
 
40084
40179
  // ../core/dist/esm/version.mjs
40085
- var VERSION2 = "4.0.472";
40180
+ var VERSION2 = "4.0.473";
40086
40181
 
40087
40182
  // ../web-renderer/dist/esm/index.mjs
40088
40183
  import { AudioSample, VideoSample } from "mediabunny";
package/dist/design.js CHANGED
@@ -7134,7 +7134,7 @@ var getComponentsToAddStacksTo = () => componentsToAddStacksTo;
7134
7134
  var addSequenceStackTraces = (component) => {
7135
7135
  componentsToAddStacksTo.push(component);
7136
7136
  };
7137
- var VERSION = "4.0.472";
7137
+ var VERSION = "4.0.473";
7138
7138
  var checkMultipleRemotionVersions = () => {
7139
7139
  if (typeof globalThis === "undefined") {
7140
7140
  return;
@@ -7173,7 +7173,8 @@ __export2(exports_timeline_position_state, {
7173
7173
  useAbsoluteTimelinePosition: () => useAbsoluteTimelinePosition,
7174
7174
  persistCurrentFrame: () => persistCurrentFrame,
7175
7175
  getInitialFrameState: () => getInitialFrameState,
7176
- getFrameForComposition: () => getFrameForComposition
7176
+ getFrameForComposition: () => getFrameForComposition,
7177
+ clampFrameToCompositionRange: () => clampFrameToCompositionRange
7177
7178
  });
7178
7179
  function mulberry32(a) {
7179
7180
  let t = a + 1831565813;
@@ -7310,6 +7311,9 @@ var getFrameForComposition = (composition) => {
7310
7311
  }
7311
7312
  return window.remotion_initialFrame ?? 0;
7312
7313
  };
7314
+ var clampFrameToCompositionRange = (frame, durationInFrames) => {
7315
+ return Math.max(0, Math.min(Math.max(0, durationInFrames - 1), frame));
7316
+ };
7313
7317
  var useTimelinePositionFromContext = (state) => {
7314
7318
  const videoConfig = useVideo();
7315
7319
  const env = useRemotionEnvironment();
@@ -7317,7 +7321,7 @@ var useTimelinePositionFromContext = (state) => {
7317
7321
  return typeof window === "undefined" ? 0 : window.remotion_initialFrame ?? 0;
7318
7322
  }
7319
7323
  const unclamped = state.frame[videoConfig.id] ?? (env.isPlayer ? 0 : getFrameForComposition(videoConfig.id));
7320
- return Math.min(videoConfig.durationInFrames - 1, unclamped);
7324
+ return clampFrameToCompositionRange(unclamped, videoConfig.durationInFrames);
7321
7325
  };
7322
7326
  var useTimelineContext = () => {
7323
7327
  const state = useContext10(TimelineContext);
@@ -7505,7 +7509,6 @@ var sequenceVisualStyleSchema = {
7505
7509
  },
7506
7510
  "style.scale": {
7507
7511
  type: "scale",
7508
- min: 0.05,
7509
7512
  max: 100,
7510
7513
  step: 0.01,
7511
7514
  default: 1,
@@ -7586,6 +7589,11 @@ var sequenceSchema = {
7586
7589
  }
7587
7590
  }
7588
7591
  };
7592
+ var sequenceSchemaWithoutFrom = {
7593
+ hidden: hiddenField,
7594
+ durationInFrames: durationInFramesField,
7595
+ layout: sequenceSchema.layout
7596
+ };
7589
7597
  var sequenceSchemaDefaultLayoutNone = {
7590
7598
  ...sequenceSchema,
7591
7599
  layout: {
@@ -8239,6 +8247,40 @@ var interpolateString = ({
8239
8247
  dimensions
8240
8248
  });
8241
8249
  };
8250
+ var validateTupleOutputRange = (outputRange) => {
8251
+ const dimensions = outputRange[0]?.length;
8252
+ if (dimensions === undefined) {
8253
+ throw new Error("outputRange must have at least 1 element");
8254
+ }
8255
+ if (dimensions === 0) {
8256
+ throw new TypeError("outputRange tuples must contain at least 1 number");
8257
+ }
8258
+ for (const output of outputRange) {
8259
+ if (output.length !== dimensions) {
8260
+ throw new TypeError(`outputRange tuples must all have the same length, but got ${dimensions} and ${output.length}`);
8261
+ }
8262
+ for (const value of output) {
8263
+ if (typeof value !== "number" || !Number.isFinite(value)) {
8264
+ throw new TypeError(`outputRange tuples must contain only finite numbers, but got [${output.join(",")}]`);
8265
+ }
8266
+ }
8267
+ }
8268
+ return dimensions;
8269
+ };
8270
+ var interpolateTuple = ({
8271
+ input,
8272
+ inputRange,
8273
+ outputRange,
8274
+ options
8275
+ }) => {
8276
+ const dimensions = validateTupleOutputRange(outputRange);
8277
+ return new Array(dimensions).fill(true).map((_, axis) => interpolateNumber({
8278
+ input,
8279
+ inputRange,
8280
+ outputRange: outputRange.map((output) => output[axis]),
8281
+ options
8282
+ }));
8283
+ };
8242
8284
  function checkValidInputRange(arr) {
8243
8285
  for (let i = 1;i < arr.length; ++i) {
8244
8286
  if (!(arr[i] > arr[i - 1])) {
@@ -8314,8 +8356,11 @@ function interpolate2(input, inputRange, outputRange, options) {
8314
8356
  }
8315
8357
  return interpolateString({ input, inputRange, outputRange, options });
8316
8358
  }
8359
+ if (outputRange.every((output) => Array.isArray(output))) {
8360
+ return interpolateTuple({ input, inputRange, outputRange, options });
8361
+ }
8317
8362
  if (!outputRange.every((output) => typeof output === "number")) {
8318
- throw new TypeError("outputRange must contain only numbers, or supported scale, translate, and rotate strings");
8363
+ throw new TypeError("outputRange must contain only numbers, numeric tuples, or supported scale, translate, and rotate strings");
8319
8364
  }
8320
8365
  checkInfiniteRange("outputRange", outputRange);
8321
8366
  return interpolateNumber({ input, inputRange, outputRange, options });
@@ -8828,8 +8873,9 @@ var interpolateKeyframedStatus = ({
8828
8873
  if (keyframes.length === 0) {
8829
8874
  return null;
8830
8875
  }
8831
- const inputRange = keyframes.map((k) => k.frame);
8832
- const outputs = keyframes.map((k) => k.value);
8876
+ const sortedKeyframes = [...keyframes].sort((a2, b2) => a2.frame - b2.frame);
8877
+ const inputRange = sortedKeyframes.map((k) => k.frame);
8878
+ const outputs = sortedKeyframes.map((k) => k.value);
8833
8879
  if (interpolationFunction === "interpolateColors") {
8834
8880
  if (!outputs.every((v) => typeof v === "string")) {
8835
8881
  return null;
@@ -9679,11 +9725,17 @@ var SequenceRefForwardingFunction = (props, ref) => {
9679
9725
  });
9680
9726
  };
9681
9727
  var SequenceInner = forwardRef3(SequenceRefForwardingFunction);
9728
+ var SequenceWithoutSchema = SequenceInner;
9682
9729
  var Sequence = wrapInSchema({
9683
9730
  Component: SequenceInner,
9684
9731
  schema: sequenceSchema,
9685
9732
  supportsEffects: false
9686
9733
  });
9734
+ var SequenceWithoutFrom = wrapInSchema({
9735
+ Component: SequenceInner,
9736
+ schema: sequenceSchemaWithoutFrom,
9737
+ supportsEffects: false
9738
+ });
9687
9739
  var calculateImageFit = (fit, imageSize, canvasSize) => {
9688
9740
  switch (fit) {
9689
9741
  case "fill": {
@@ -15804,6 +15856,7 @@ var Internals = {
15804
15856
  SequenceStackTracesUpdateContext,
15805
15857
  wrapInSchema,
15806
15858
  sequenceSchema,
15859
+ SequenceWithoutSchema,
15807
15860
  sequenceStyleSchema,
15808
15861
  sequenceVisualStyleSchema,
15809
15862
  sequencePremountSchema,
@@ -15965,6 +16018,7 @@ var SeriesSequenceRefForwardingFunction = ({ children }, _ref) => {
15965
16018
  });
15966
16019
  };
15967
16020
  var SeriesSequence = forwardRef13(SeriesSequenceRefForwardingFunction);
16021
+ var SequenceWithoutSchemaWithRef = SequenceWithoutSchema;
15968
16022
  var SeriesInner = (props2) => {
15969
16023
  const childrenValue = useMemo38(() => {
15970
16024
  let startFrame = 0;
@@ -16007,13 +16061,13 @@ var SeriesInner = (props2) => {
16007
16061
  }
16008
16062
  const currentStartFrame = startFrame + offset;
16009
16063
  startFrame += durationInFramesProp + offset;
16010
- return /* @__PURE__ */ jsx36(Sequence, {
16064
+ return /* @__PURE__ */ jsx36(SequenceWithoutSchemaWithRef, {
16065
+ ref: castedChild.ref,
16011
16066
  name: name || "<Series.Sequence>",
16012
16067
  _remotionInternalDocumentationLink: name ? undefined : "https://www.remotion.dev/docs/series",
16013
16068
  from: currentStartFrame,
16014
16069
  durationInFrames: durationInFramesProp,
16015
16070
  ...passedProps,
16016
- ref: castedChild.ref,
16017
16071
  children: child
16018
16072
  });
16019
16073
  });
@@ -16036,7 +16090,6 @@ var Series = Object.assign(wrapInSchema({
16036
16090
  Sequence: SeriesSequence
16037
16091
  });
16038
16092
  addSequenceStackTraces(Series);
16039
- addSequenceStackTraces(SeriesSequence);
16040
16093
  var validateSpringDuration = (dur) => {
16041
16094
  if (typeof dur === "undefined") {
16042
16095
  return;
package/dist/experts.js CHANGED
@@ -2332,7 +2332,7 @@ var getComponentsToAddStacksTo = () => componentsToAddStacksTo;
2332
2332
  var addSequenceStackTraces = (component) => {
2333
2333
  componentsToAddStacksTo.push(component);
2334
2334
  };
2335
- var VERSION = "4.0.472";
2335
+ var VERSION = "4.0.473";
2336
2336
  var checkMultipleRemotionVersions = () => {
2337
2337
  if (typeof globalThis === "undefined") {
2338
2338
  return;
@@ -2371,7 +2371,8 @@ __export2(exports_timeline_position_state, {
2371
2371
  useAbsoluteTimelinePosition: () => useAbsoluteTimelinePosition,
2372
2372
  persistCurrentFrame: () => persistCurrentFrame,
2373
2373
  getInitialFrameState: () => getInitialFrameState,
2374
- getFrameForComposition: () => getFrameForComposition
2374
+ getFrameForComposition: () => getFrameForComposition,
2375
+ clampFrameToCompositionRange: () => clampFrameToCompositionRange
2375
2376
  });
2376
2377
  function mulberry32(a) {
2377
2378
  let t = a + 1831565813;
@@ -2508,6 +2509,9 @@ var getFrameForComposition = (composition) => {
2508
2509
  }
2509
2510
  return window.remotion_initialFrame ?? 0;
2510
2511
  };
2512
+ var clampFrameToCompositionRange = (frame, durationInFrames) => {
2513
+ return Math.max(0, Math.min(Math.max(0, durationInFrames - 1), frame));
2514
+ };
2511
2515
  var useTimelinePositionFromContext = (state) => {
2512
2516
  const videoConfig = useVideo();
2513
2517
  const env = useRemotionEnvironment();
@@ -2515,7 +2519,7 @@ var useTimelinePositionFromContext = (state) => {
2515
2519
  return typeof window === "undefined" ? 0 : window.remotion_initialFrame ?? 0;
2516
2520
  }
2517
2521
  const unclamped = state.frame[videoConfig.id] ?? (env.isPlayer ? 0 : getFrameForComposition(videoConfig.id));
2518
- return Math.min(videoConfig.durationInFrames - 1, unclamped);
2522
+ return clampFrameToCompositionRange(unclamped, videoConfig.durationInFrames);
2519
2523
  };
2520
2524
  var useTimelineContext = () => {
2521
2525
  const state = useContext10(TimelineContext);
@@ -2703,7 +2707,6 @@ var sequenceVisualStyleSchema = {
2703
2707
  },
2704
2708
  "style.scale": {
2705
2709
  type: "scale",
2706
- min: 0.05,
2707
2710
  max: 100,
2708
2711
  step: 0.01,
2709
2712
  default: 1,
@@ -2784,6 +2787,11 @@ var sequenceSchema = {
2784
2787
  }
2785
2788
  }
2786
2789
  };
2790
+ var sequenceSchemaWithoutFrom = {
2791
+ hidden: hiddenField,
2792
+ durationInFrames: durationInFramesField,
2793
+ layout: sequenceSchema.layout
2794
+ };
2787
2795
  var sequenceSchemaDefaultLayoutNone = {
2788
2796
  ...sequenceSchema,
2789
2797
  layout: {
@@ -3437,6 +3445,40 @@ var interpolateString = ({
3437
3445
  dimensions
3438
3446
  });
3439
3447
  };
3448
+ var validateTupleOutputRange = (outputRange) => {
3449
+ const dimensions = outputRange[0]?.length;
3450
+ if (dimensions === undefined) {
3451
+ throw new Error("outputRange must have at least 1 element");
3452
+ }
3453
+ if (dimensions === 0) {
3454
+ throw new TypeError("outputRange tuples must contain at least 1 number");
3455
+ }
3456
+ for (const output of outputRange) {
3457
+ if (output.length !== dimensions) {
3458
+ throw new TypeError(`outputRange tuples must all have the same length, but got ${dimensions} and ${output.length}`);
3459
+ }
3460
+ for (const value of output) {
3461
+ if (typeof value !== "number" || !Number.isFinite(value)) {
3462
+ throw new TypeError(`outputRange tuples must contain only finite numbers, but got [${output.join(",")}]`);
3463
+ }
3464
+ }
3465
+ }
3466
+ return dimensions;
3467
+ };
3468
+ var interpolateTuple = ({
3469
+ input,
3470
+ inputRange,
3471
+ outputRange,
3472
+ options
3473
+ }) => {
3474
+ const dimensions = validateTupleOutputRange(outputRange);
3475
+ return new Array(dimensions).fill(true).map((_, axis) => interpolateNumber({
3476
+ input,
3477
+ inputRange,
3478
+ outputRange: outputRange.map((output) => output[axis]),
3479
+ options
3480
+ }));
3481
+ };
3440
3482
  function checkValidInputRange(arr) {
3441
3483
  for (let i = 1;i < arr.length; ++i) {
3442
3484
  if (!(arr[i] > arr[i - 1])) {
@@ -3512,8 +3554,11 @@ function interpolate(input, inputRange, outputRange, options) {
3512
3554
  }
3513
3555
  return interpolateString({ input, inputRange, outputRange, options });
3514
3556
  }
3557
+ if (outputRange.every((output) => Array.isArray(output))) {
3558
+ return interpolateTuple({ input, inputRange, outputRange, options });
3559
+ }
3515
3560
  if (!outputRange.every((output) => typeof output === "number")) {
3516
- throw new TypeError("outputRange must contain only numbers, or supported scale, translate, and rotate strings");
3561
+ throw new TypeError("outputRange must contain only numbers, numeric tuples, or supported scale, translate, and rotate strings");
3517
3562
  }
3518
3563
  checkInfiniteRange("outputRange", outputRange);
3519
3564
  return interpolateNumber({ input, inputRange, outputRange, options });
@@ -4026,8 +4071,9 @@ var interpolateKeyframedStatus = ({
4026
4071
  if (keyframes.length === 0) {
4027
4072
  return null;
4028
4073
  }
4029
- const inputRange = keyframes.map((k) => k.frame);
4030
- const outputs = keyframes.map((k) => k.value);
4074
+ const sortedKeyframes = [...keyframes].sort((a2, b2) => a2.frame - b2.frame);
4075
+ const inputRange = sortedKeyframes.map((k) => k.frame);
4076
+ const outputs = sortedKeyframes.map((k) => k.value);
4031
4077
  if (interpolationFunction === "interpolateColors") {
4032
4078
  if (!outputs.every((v) => typeof v === "string")) {
4033
4079
  return null;
@@ -4877,11 +4923,17 @@ var SequenceRefForwardingFunction = (props, ref) => {
4877
4923
  });
4878
4924
  };
4879
4925
  var SequenceInner = forwardRef3(SequenceRefForwardingFunction);
4926
+ var SequenceWithoutSchema = SequenceInner;
4880
4927
  var Sequence = wrapInSchema({
4881
4928
  Component: SequenceInner,
4882
4929
  schema: sequenceSchema,
4883
4930
  supportsEffects: false
4884
4931
  });
4932
+ var SequenceWithoutFrom = wrapInSchema({
4933
+ Component: SequenceInner,
4934
+ schema: sequenceSchemaWithoutFrom,
4935
+ supportsEffects: false
4936
+ });
4885
4937
  var calculateImageFit = (fit, imageSize, canvasSize) => {
4886
4938
  switch (fit) {
4887
4939
  case "fill": {
@@ -11002,6 +11054,7 @@ var Internals = {
11002
11054
  SequenceStackTracesUpdateContext,
11003
11055
  wrapInSchema,
11004
11056
  sequenceSchema,
11057
+ SequenceWithoutSchema,
11005
11058
  sequenceStyleSchema,
11006
11059
  sequenceVisualStyleSchema,
11007
11060
  sequencePremountSchema,
@@ -11163,6 +11216,7 @@ var SeriesSequenceRefForwardingFunction = ({ children }, _ref) => {
11163
11216
  });
11164
11217
  };
11165
11218
  var SeriesSequence = forwardRef13(SeriesSequenceRefForwardingFunction);
11219
+ var SequenceWithoutSchemaWithRef = SequenceWithoutSchema;
11166
11220
  var SeriesInner = (props2) => {
11167
11221
  const childrenValue = useMemo38(() => {
11168
11222
  let startFrame = 0;
@@ -11205,13 +11259,13 @@ var SeriesInner = (props2) => {
11205
11259
  }
11206
11260
  const currentStartFrame = startFrame + offset;
11207
11261
  startFrame += durationInFramesProp + offset;
11208
- return /* @__PURE__ */ jsx36(Sequence, {
11262
+ return /* @__PURE__ */ jsx36(SequenceWithoutSchemaWithRef, {
11263
+ ref: castedChild.ref,
11209
11264
  name: name || "<Series.Sequence>",
11210
11265
  _remotionInternalDocumentationLink: name ? undefined : "https://www.remotion.dev/docs/series",
11211
11266
  from: currentStartFrame,
11212
11267
  durationInFrames: durationInFramesProp,
11213
11268
  ...passedProps,
11214
- ref: castedChild.ref,
11215
11269
  children: child
11216
11270
  });
11217
11271
  });
@@ -11234,7 +11288,6 @@ var Series = Object.assign(wrapInSchema({
11234
11288
  Sequence: SeriesSequence
11235
11289
  });
11236
11290
  addSequenceStackTraces(Series);
11237
- addSequenceStackTraces(SeriesSequence);
11238
11291
  var validateSpringDuration = (dur) => {
11239
11292
  if (typeof dur === "undefined") {
11240
11293
  return;