@remotion/studio 4.0.409 → 4.0.410

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.
@@ -34,7 +34,7 @@ import { Internals as Internals66 } from "remotion";
34
34
 
35
35
  // src/components/Editor.tsx
36
36
  import { PlayerInternals as PlayerInternals19 } from "@remotion/player";
37
- import React178, { useCallback as useCallback136, useEffect as useEffect85, useMemo as useMemo136 } from "react";
37
+ import React178, { useCallback as useCallback136, useEffect as useEffect84, useMemo as useMemo136 } from "react";
38
38
  import { Internals as Internals62 } from "remotion";
39
39
 
40
40
  // src/helpers/colors.ts
@@ -3270,7 +3270,7 @@ var writeStaticFile = async ({
3270
3270
  if (window.remotion_isReadOnlyStudio) {
3271
3271
  throw new Error("writeStaticFile() is not available in read-only Studio");
3272
3272
  }
3273
- const url = new URL("/api/add-asset", window.location.origin);
3273
+ const url = new URL(`${window.remotion_staticBase}/api/add-asset`, window.location.origin);
3274
3274
  if (filePath.includes("\\")) {
3275
3275
  return Promise.reject(new Error("File path cannot contain backslashes"));
3276
3276
  }
@@ -7549,10 +7549,10 @@ var MenuBuildIndicator = () => {
7549
7549
  };
7550
7550
 
7551
7551
  // src/components/SidebarCollapserControls.tsx
7552
- import { useCallback as useCallback92, useContext as useContext59, useEffect as useEffect62 } from "react";
7552
+ import { useCallback as useCallback92, useContext as useContext59, useEffect as useEffect61 } from "react";
7553
7553
 
7554
7554
  // src/components/TopPanel.tsx
7555
- import { useCallback as useCallback91, useContext as useContext58, useEffect as useEffect61, useMemo as useMemo96 } from "react";
7555
+ import { useCallback as useCallback91, useContext as useContext58, useEffect as useEffect60, useMemo as useMemo96 } from "react";
7556
7556
 
7557
7557
  // src/helpers/use-breakpoint.ts
7558
7558
  import { useEffect as useEffect25, useState as useState30 } from "react";
@@ -17608,7 +17608,7 @@ var OptionsPanel = ({ readOnlyStudio }) => {
17608
17608
  };
17609
17609
 
17610
17610
  // src/components/PreviewToolbar.tsx
17611
- import { useContext as useContext55, useEffect as useEffect59, useRef as useRef32, useState as useState61 } from "react";
17611
+ import { useContext as useContext55, useEffect as useEffect58, useRef as useRef32, useState as useState61 } from "react";
17612
17612
  import { Internals as Internals45 } from "remotion";
17613
17613
 
17614
17614
  // src/helpers/should-show-render-button.ts
@@ -18425,14 +18425,7 @@ var PlaybackRateSelector = ({ playbackRate, setPlaybackRate }) => {
18425
18425
 
18426
18426
  // src/components/RenderButton.tsx
18427
18427
  import { PlayerInternals as PlayerInternals14 } from "@remotion/player";
18428
- import {
18429
- useCallback as useCallback89,
18430
- useContext as useContext53,
18431
- useEffect as useEffect58,
18432
- useMemo as useMemo93,
18433
- useRef as useRef31,
18434
- useState as useState60
18435
- } from "react";
18428
+ import { useCallback as useCallback89, useContext as useContext53, useMemo as useMemo93, useRef as useRef31, useState as useState60 } from "react";
18436
18429
  import ReactDOM8 from "react-dom";
18437
18430
  import { Internals as Internals43 } from "remotion";
18438
18431
  import { jsx as jsx175, jsxs as jsxs81, Fragment as Fragment23 } from "react/jsx-runtime";
@@ -18514,6 +18507,34 @@ var RenderButton = ({
18514
18507
  shouldApplyCssTransforms: true
18515
18508
  });
18516
18509
  const refresh = size4?.refresh;
18510
+ const onPointerDown = useCallback89(() => {
18511
+ setDropdownOpened((o) => {
18512
+ if (!o) {
18513
+ refresh?.();
18514
+ }
18515
+ return !o;
18516
+ });
18517
+ }, [refresh]);
18518
+ const onClickDropdown = useCallback89((e) => {
18519
+ e.stopPropagation();
18520
+ const isKeyboardInitiated = e.detail === 0;
18521
+ if (!isKeyboardInitiated) {
18522
+ return;
18523
+ }
18524
+ setDropdownOpened((o) => {
18525
+ if (!o) {
18526
+ refresh?.();
18527
+ window.addEventListener("pointerup", (evt) => {
18528
+ if (!isMenuItem(evt.target)) {
18529
+ setDropdownOpened(false);
18530
+ }
18531
+ }, {
18532
+ once: true
18533
+ });
18534
+ }
18535
+ return !o;
18536
+ });
18537
+ }, [refresh]);
18517
18538
  const connectionStatus = useContext53(StudioServerConnectionCtx).previewServerState.type;
18518
18539
  const shortcut = areKeyboardShortcutsDisabled() ? "" : "(R)";
18519
18540
  const tooltip = connectionStatus === "connected" ? "Export the current composition " + shortcut : "Connect to the Studio server to render";
@@ -18654,46 +18675,6 @@ var RenderButton = ({
18654
18675
  }
18655
18676
  ];
18656
18677
  }, [handleRenderTypeChange]);
18657
- useEffect58(() => {
18658
- const { current } = dropdownRef;
18659
- if (!current) {
18660
- return;
18661
- }
18662
- const onPointerDown = () => {
18663
- return setDropdownOpened((o) => {
18664
- if (!o) {
18665
- refresh?.();
18666
- }
18667
- return !o;
18668
- });
18669
- };
18670
- const onClickDropdown = (e) => {
18671
- e.stopPropagation();
18672
- const isKeyboardInitiated = e.detail === 0;
18673
- if (!isKeyboardInitiated) {
18674
- return;
18675
- }
18676
- return setDropdownOpened((o) => {
18677
- if (!o) {
18678
- refresh?.();
18679
- window.addEventListener("pointerup", (evt) => {
18680
- if (!isMenuItem(evt.target)) {
18681
- setDropdownOpened(false);
18682
- }
18683
- }, {
18684
- once: true
18685
- });
18686
- }
18687
- return !o;
18688
- });
18689
- };
18690
- current.addEventListener("pointerdown", onPointerDown);
18691
- current.addEventListener("click", onClickDropdown);
18692
- return () => {
18693
- current.removeEventListener("pointerdown", onPointerDown);
18694
- current.removeEventListener("click", onClickDropdown);
18695
- };
18696
- }, [refresh]);
18697
18678
  const spaceToBottom = useMemo93(() => {
18698
18679
  const margin2 = 10;
18699
18680
  if (size4 && dropdownOpened) {
@@ -18761,7 +18742,6 @@ var RenderButton = ({
18761
18742
  /* @__PURE__ */ jsx175("button", {
18762
18743
  style: { display: "none" },
18763
18744
  id: "render-modal-button-client",
18764
- disabled: connectionStatus !== "connected" && renderType === "server-render",
18765
18745
  onClick: openClientRenderModal,
18766
18746
  type: "button"
18767
18747
  }),
@@ -18805,6 +18785,8 @@ var RenderButton = ({
18805
18785
  style: dropdownTriggerStyle,
18806
18786
  disabled: connectionStatus !== "connected",
18807
18787
  className: MENU_INITIATOR_CLASSNAME,
18788
+ onPointerDown,
18789
+ onClick: onClickDropdown,
18808
18790
  children: /* @__PURE__ */ jsx175(CaretDown, {})
18809
18791
  })
18810
18792
  ]
@@ -19007,7 +18989,7 @@ var PreviewToolbar = ({ readOnlyStudio, bufferStateDelayInMilliseconds }) => {
19007
18989
  const [loop, setLoop] = useState61(loadLoopOption());
19008
18990
  const isFullscreenSupported = checkFullscreenSupport();
19009
18991
  const isMobileLayout = useMobileLayout();
19010
- useEffect59(() => {
18992
+ useEffect58(() => {
19011
18993
  if (isMobileLayout && previewToolbarRef.current) {
19012
18994
  const updateScrollableIndicatorProps = (target) => {
19013
18995
  const boundingBox = target.getBoundingClientRect();
@@ -19287,7 +19269,7 @@ var SplitterElement = ({ children, type, sticky }) => {
19287
19269
 
19288
19270
  // src/components/Splitter/SplitterHandle.tsx
19289
19271
  import { PlayerInternals as PlayerInternals15 } from "@remotion/player";
19290
- import { useContext as useContext57, useEffect as useEffect60, useRef as useRef34, useState as useState63 } from "react";
19272
+ import { useContext as useContext57, useEffect as useEffect59, useRef as useRef34, useState as useState63 } from "react";
19291
19273
  import { jsx as jsx181 } from "react/jsx-runtime";
19292
19274
  var SPLITTER_HANDLE_SIZE = 3;
19293
19275
  var containerRow2 = {
@@ -19303,7 +19285,7 @@ var SplitterHandle = ({ allowToCollapse, onCollapse }) => {
19303
19285
  }
19304
19286
  const [lastPointerUp, setLastPointerUp] = useState63(() => Date.now());
19305
19287
  const ref = useRef34(null);
19306
- useEffect60(() => {
19288
+ useEffect59(() => {
19307
19289
  if (context.isDragging.current) {
19308
19290
  return;
19309
19291
  }
@@ -19386,7 +19368,7 @@ var SplitterHandle = ({ allowToCollapse, onCollapse }) => {
19386
19368
  }
19387
19369
  };
19388
19370
  }, [allowToCollapse, context, context.flexValue, lastPointerUp, onCollapse]);
19389
- useEffect60(() => {
19371
+ useEffect59(() => {
19390
19372
  const { current } = ref;
19391
19373
  if (!current) {
19392
19374
  return;
@@ -19473,7 +19455,7 @@ var TopPanel = ({ readOnlyStudio, onMounted, drawRef: drawRef2, bufferStateDelay
19473
19455
  }
19474
19456
  return "expanded";
19475
19457
  }, [sidebarCollapsedStateRight]);
19476
- useEffect61(() => {
19458
+ useEffect60(() => {
19477
19459
  onMounted();
19478
19460
  }, [onMounted]);
19479
19461
  const canvasContainerStyle = useMemo96(() => ({
@@ -19643,7 +19625,7 @@ var SidebarCollapserControls = () => {
19643
19625
  toggleLeft,
19644
19626
  toggleRight
19645
19627
  ]);
19646
- useEffect62(() => {
19628
+ useEffect61(() => {
19647
19629
  const left3 = keybindings.registerKeybinding({
19648
19630
  event: "keydown",
19649
19631
  key: "b",
@@ -19721,7 +19703,7 @@ var SidebarCollapserControls = () => {
19721
19703
  import {
19722
19704
  useCallback as useCallback93,
19723
19705
  useContext as useContext60,
19724
- useEffect as useEffect63,
19706
+ useEffect as useEffect62,
19725
19707
  useMemo as useMemo97,
19726
19708
  useState as useState64
19727
19709
  } from "react";
@@ -19773,7 +19755,7 @@ var UpdateCheck = () => {
19773
19755
  });
19774
19756
  return controller;
19775
19757
  }, []);
19776
- useEffect63(() => {
19758
+ useEffect62(() => {
19777
19759
  const abortUpdate = checkForUpdates();
19778
19760
  const abortBugs = checkForBugs();
19779
19761
  return () => {
@@ -20138,7 +20120,7 @@ import { PlayerInternals as PlayerInternals16 } from "@remotion/player";
20138
20120
  import {
20139
20121
  useCallback as useCallback95,
20140
20122
  useContext as useContext63,
20141
- useEffect as useEffect64,
20123
+ useEffect as useEffect63,
20142
20124
  useMemo as useMemo100,
20143
20125
  useRef as useRef35,
20144
20126
  useState as useState66
@@ -20569,7 +20551,7 @@ var Inner2 = () => {
20569
20551
  videoConfig,
20570
20552
  width
20571
20553
  ]);
20572
- useEffect64(() => {
20554
+ useEffect63(() => {
20573
20555
  if (!dragging.dragging) {
20574
20556
  return;
20575
20557
  }
@@ -20580,7 +20562,7 @@ var Inner2 = () => {
20580
20562
  window.removeEventListener("pointerup", onPointerUpScrubbing);
20581
20563
  };
20582
20564
  }, [dragging.dragging, onPointerMoveScrubbing, onPointerUpScrubbing]);
20583
- useEffect64(() => {
20565
+ useEffect63(() => {
20584
20566
  if (inOutDragging.dragging === false) {
20585
20567
  return;
20586
20568
  }
@@ -20756,7 +20738,7 @@ import { SOURCE_MAP_ENDPOINT } from "@remotion/studio-shared";
20756
20738
  import {
20757
20739
  useCallback as useCallback97,
20758
20740
  useContext as useContext64,
20759
- useEffect as useEffect65,
20741
+ useEffect as useEffect64,
20760
20742
  useMemo as useMemo101,
20761
20743
  useState as useState67
20762
20744
  } from "react";
@@ -20845,7 +20827,7 @@ var TimelineStack = ({ isCompact, sequence }) => {
20845
20827
  window.open(getGitRefUrl(window.remotion_gitSource, originalLocation), "_blank");
20846
20828
  }
20847
20829
  }, [canOpenInEditor, canOpenInGitHub, openEditor, originalLocation]);
20848
- useEffect65(() => {
20830
+ useEffect64(() => {
20849
20831
  if (!sequence.stack) {
20850
20832
  return;
20851
20833
  }
@@ -20993,14 +20975,14 @@ var TimelineListItem = ({ nestedDepth, sequence, isCompact }) => {
20993
20975
  };
20994
20976
 
20995
20977
  // src/components/Timeline/TimelineTimeIndicators.tsx
20996
- import { useContext as useContext66, useEffect as useEffect67, useMemo as useMemo103, useRef as useRef37 } from "react";
20978
+ import { useContext as useContext66, useEffect as useEffect66, useMemo as useMemo103, useRef as useRef37 } from "react";
20997
20979
  import { Internals as Internals50 } from "remotion";
20998
20980
 
20999
20981
  // src/components/TimeValue.tsx
21000
20982
  import { PlayerInternals as PlayerInternals17 } from "@remotion/player";
21001
20983
  import {
21002
20984
  useCallback as useCallback99,
21003
- useEffect as useEffect66,
20985
+ useEffect as useEffect65,
21004
20986
  useImperativeHandle as useImperativeHandle14,
21005
20987
  useRef as useRef36
21006
20988
  } from "react";
@@ -21053,7 +21035,7 @@ var TimeValue = () => {
21053
21035
  pause,
21054
21036
  toggle
21055
21037
  }), [seek, play, pause, toggle]);
21056
- useEffect66(() => {
21038
+ useEffect65(() => {
21057
21039
  const gKey = keybindings.registerKeybinding({
21058
21040
  event: "keypress",
21059
21041
  key: "g",
@@ -21166,7 +21148,7 @@ var TimelineTimeIndicators = () => {
21166
21148
  };
21167
21149
  var Inner3 = ({ windowWidth, durationInFrames, fps }) => {
21168
21150
  const ref = useRef37(null);
21169
- useEffect67(() => {
21151
+ useEffect66(() => {
21170
21152
  const currentRef = ref.current;
21171
21153
  if (!currentRef) {
21172
21154
  return;
@@ -21273,7 +21255,7 @@ var TimelineList = ({ timeline }) => {
21273
21255
  };
21274
21256
 
21275
21257
  // src/components/Timeline/TimelinePlayCursorSyncer.tsx
21276
- import { useContext as useContext67, useEffect as useEffect68 } from "react";
21258
+ import { useContext as useContext67, useEffect as useEffect67 } from "react";
21277
21259
  import { Internals as Internals51 } from "remotion";
21278
21260
  var lastTimelinePositionWhileScrolling = null;
21279
21261
  var TimelinePlayCursorSyncer = () => {
@@ -21291,7 +21273,7 @@ var TimelinePlayCursorSyncer = () => {
21291
21273
  setCurrentFps(video.fps);
21292
21274
  }
21293
21275
  const playing = timelineContext.playing ?? false;
21294
- useEffect68(() => {
21276
+ useEffect67(() => {
21295
21277
  if (!video) {
21296
21278
  return;
21297
21279
  }
@@ -21304,7 +21286,7 @@ var TimelinePlayCursorSyncer = () => {
21304
21286
  frame: timelinePosition
21305
21287
  });
21306
21288
  }, [playing, timelineContext, timelinePosition, video]);
21307
- useEffect68(() => {
21289
+ useEffect67(() => {
21308
21290
  const { current } = scrollableRef;
21309
21291
  if (!current) {
21310
21292
  return;
@@ -36307,7 +36289,7 @@ var readAscii = (slice, length) => {
36307
36289
  */
36308
36290
 
36309
36291
  // src/helpers/use-max-media-duration.ts
36310
- import { useEffect as useEffect69, useState as useState68 } from "react";
36292
+ import { useEffect as useEffect68, useState as useState68 } from "react";
36311
36293
  var cache = new Map;
36312
36294
  var getSrc = (s) => {
36313
36295
  if (s.type === "video") {
@@ -36321,7 +36303,7 @@ var getSrc = (s) => {
36321
36303
  var useMaxMediaDuration = (s, fps) => {
36322
36304
  const src = getSrc(s);
36323
36305
  const [maxMediaDuration, setMaxMediaDuration] = useState68(src ? cache.get(src) ?? null : Infinity);
36324
- useEffect69(() => {
36306
+ useEffect68(() => {
36325
36307
  if (!src) {
36326
36308
  return;
36327
36309
  }
@@ -36351,7 +36333,7 @@ var useMaxMediaDuration = (s, fps) => {
36351
36333
 
36352
36334
  // src/components/AudioWaveform.tsx
36353
36335
  import { getAudioData, getWaveformPortion } from "@remotion/media-utils";
36354
- import { useEffect as useEffect70, useMemo as useMemo106, useRef as useRef39, useState as useState69 } from "react";
36336
+ import { useEffect as useEffect69, useMemo as useMemo106, useRef as useRef39, useState as useState69 } from "react";
36355
36337
  import { Internals as Internals52 } from "remotion";
36356
36338
 
36357
36339
  // src/components/AudioWaveformBar.tsx
@@ -36416,14 +36398,14 @@ var AudioWaveform = ({
36416
36398
  throw new Error("Expected video config");
36417
36399
  }
36418
36400
  const canvas = useRef39(null);
36419
- useEffect70(() => {
36401
+ useEffect69(() => {
36420
36402
  const { current } = mountState;
36421
36403
  current.isMounted = true;
36422
36404
  return () => {
36423
36405
  current.isMounted = false;
36424
36406
  };
36425
36407
  }, []);
36426
- useEffect70(() => {
36408
+ useEffect69(() => {
36427
36409
  if (!canvas.current) {
36428
36410
  return;
36429
36411
  }
@@ -36450,7 +36432,7 @@ var AudioWaveform = ({
36450
36432
  context.strokeStyle = LIGHT_TRANSPARENT;
36451
36433
  context.stroke();
36452
36434
  }, [visualizationWidth, metadata, startFrom, volume, doesVolumeChange]);
36453
- useEffect70(() => {
36435
+ useEffect69(() => {
36454
36436
  setError(null);
36455
36437
  getAudioData(src).then((data) => {
36456
36438
  if (mountState.current.isMounted) {
@@ -36625,7 +36607,7 @@ var TimelineSequenceFrame = ({ roundedFrame, premounted, postmounted }) => {
36625
36607
  };
36626
36608
 
36627
36609
  // src/components/Timeline/TimelineVideoInfo.tsx
36628
- import { useEffect as useEffect71, useRef as useRef40, useState as useState70 } from "react";
36610
+ import { useEffect as useEffect70, useRef as useRef40, useState as useState70 } from "react";
36629
36611
  import { useVideoConfig as useVideoConfig5 } from "remotion";
36630
36612
 
36631
36613
  // src/helpers/extract-frames.ts
@@ -36943,12 +36925,12 @@ var TimelineVideoInfo = ({ src, visualizationWidth, startFrom, durationInFrames
36943
36925
  const ref = useRef40(null);
36944
36926
  const [error, setError] = useState70(null);
36945
36927
  const aspectRatio = useRef40(getAspectRatioFromCache(src));
36946
- useEffect71(() => {
36928
+ useEffect70(() => {
36947
36929
  return () => {
36948
36930
  clearFramesForSrc(src);
36949
36931
  };
36950
36932
  }, [src]);
36951
- useEffect71(() => {
36933
+ useEffect70(() => {
36952
36934
  if (error) {
36953
36935
  return;
36954
36936
  }
@@ -37401,13 +37383,13 @@ var EditorContent = ({ readOnlyStudio, children }) => {
37401
37383
  };
37402
37384
 
37403
37385
  // src/components/GlobalKeybindings.tsx
37404
- import { useContext as useContext71, useEffect as useEffect72 } from "react";
37386
+ import { useContext as useContext71, useEffect as useEffect71 } from "react";
37405
37387
  var GlobalKeybindings = () => {
37406
37388
  const keybindings = useKeybinding();
37407
37389
  const { setSelectedModal } = useContext71(ModalsContext);
37408
37390
  const { setCheckerboard } = useContext71(CheckerboardContext);
37409
37391
  const { navigateToNextComposition, navigateToPreviousComposition } = useCompositionNavigation();
37410
- useEffect72(() => {
37392
+ useEffect71(() => {
37411
37393
  const nKey = keybindings.registerKeybinding({
37412
37394
  event: "keypress",
37413
37395
  key: "n",
@@ -37512,8 +37494,13 @@ var GlobalKeybindings = () => {
37512
37494
  import { useContext as useContext85 } from "react";
37513
37495
 
37514
37496
  // src/components/InstallPackage.tsx
37515
- import { apiDocs, descriptions, installableMap } from "@remotion/studio-shared";
37516
- import React145, { useCallback as useCallback101, useContext as useContext73, useEffect as useEffect73 } from "react";
37497
+ import {
37498
+ apiDocs,
37499
+ descriptions,
37500
+ extraPackages,
37501
+ installableMap
37502
+ } from "@remotion/studio-shared";
37503
+ import React145, { useCallback as useCallback101, useContext as useContext73, useEffect as useEffect72 } from "react";
37517
37504
  import { VERSION as VERSION2 } from "remotion";
37518
37505
 
37519
37506
  // src/api/install-package.ts
@@ -37647,7 +37634,7 @@ var InstallPackageModal = ({ packageManager }) => {
37647
37634
  const canSelectPackages = state.type === "idle" && ctx.type === "connected";
37648
37635
  const disabled = !(canSelectPackages || state.type === "done") || selectedPackages.length === 0;
37649
37636
  const { registerKeybinding } = useKeybinding();
37650
- useEffect73(() => {
37637
+ useEffect72(() => {
37651
37638
  if (disabled) {
37652
37639
  return;
37653
37640
  }
@@ -37692,42 +37679,72 @@ var InstallPackageModal = ({ packageManager }) => {
37692
37679
  selectedPackages.length === 1 ? "" : "s",
37693
37680
  ". Check your terminal for progress."
37694
37681
  ]
37695
- }) : /* @__PURE__ */ jsx210("div", {
37682
+ }) : /* @__PURE__ */ jsxs103("div", {
37696
37683
  style: text2,
37697
- children: Object.entries(installableMap).filter(([, install]) => install).map(([pkgShort]) => {
37698
- const pkg = pkgShort === "core" ? "remotion" : `@remotion/${pkgShort}`;
37699
- const isInstalled = window.remotion_installedPackages?.includes(pkg) ?? false;
37700
- const link = apiDocs[pkgShort];
37701
- const description = descriptions[pkgShort];
37702
- if (!link) {
37703
- throw new Error("No link for " + pkg);
37704
- }
37705
- if (!description) {
37706
- throw new Error("No description for " + pkg);
37707
- }
37708
- return /* @__PURE__ */ jsxs103(Row, {
37709
- align: "center",
37710
- children: [
37711
- /* @__PURE__ */ jsx210(Checkbox, {
37712
- checked: map[pkg],
37713
- name: pkg,
37714
- onChange: () => {
37715
- setMap((prev) => ({ ...prev, [pkg]: !prev[pkg] }));
37716
- },
37717
- disabled: !canSelectPackages || isInstalled
37718
- }),
37719
- /* @__PURE__ */ jsx210(Spacing, {
37720
- x: 1.5
37721
- }),
37722
- /* @__PURE__ */ jsx210(InstallablePackageComp, {
37723
- description,
37724
- isInstalled,
37725
- link,
37726
- pkg
37727
- })
37728
- ]
37729
- }, pkg);
37730
- })
37684
+ children: [
37685
+ Object.entries(installableMap).filter(([, install]) => install).map(([pkgShort]) => {
37686
+ const pkg = pkgShort === "core" ? "remotion" : `@remotion/${pkgShort}`;
37687
+ const isInstalled = window.remotion_installedPackages?.includes(pkg) ?? false;
37688
+ const link = apiDocs[pkgShort];
37689
+ const description = descriptions[pkgShort];
37690
+ if (!link) {
37691
+ throw new Error("No link for " + pkg);
37692
+ }
37693
+ if (!description) {
37694
+ throw new Error("No description for " + pkg);
37695
+ }
37696
+ return /* @__PURE__ */ jsxs103(Row, {
37697
+ align: "center",
37698
+ children: [
37699
+ /* @__PURE__ */ jsx210(Checkbox, {
37700
+ checked: map[pkg],
37701
+ name: pkg,
37702
+ onChange: () => {
37703
+ setMap((prev) => ({ ...prev, [pkg]: !prev[pkg] }));
37704
+ },
37705
+ disabled: !canSelectPackages || isInstalled
37706
+ }),
37707
+ /* @__PURE__ */ jsx210(Spacing, {
37708
+ x: 1.5
37709
+ }),
37710
+ /* @__PURE__ */ jsx210(InstallablePackageComp, {
37711
+ description,
37712
+ isInstalled,
37713
+ link,
37714
+ pkg
37715
+ })
37716
+ ]
37717
+ }, pkg);
37718
+ }),
37719
+ extraPackages.map((extraPkg) => {
37720
+ const isInstalled = window.remotion_installedPackages?.includes(extraPkg.name) ?? false;
37721
+ return /* @__PURE__ */ jsxs103(Row, {
37722
+ align: "center",
37723
+ children: [
37724
+ /* @__PURE__ */ jsx210(Checkbox, {
37725
+ checked: map[extraPkg.name],
37726
+ name: extraPkg.name,
37727
+ onChange: () => {
37728
+ setMap((prev) => ({
37729
+ ...prev,
37730
+ [extraPkg.name]: !prev[extraPkg.name]
37731
+ }));
37732
+ },
37733
+ disabled: !canSelectPackages || isInstalled
37734
+ }),
37735
+ /* @__PURE__ */ jsx210(Spacing, {
37736
+ x: 1.5
37737
+ }),
37738
+ /* @__PURE__ */ jsx210(InstallablePackageComp, {
37739
+ description: extraPkg.description,
37740
+ isInstalled,
37741
+ link: extraPkg.docsUrl,
37742
+ pkg: `${extraPkg.name}@${extraPkg.version}`
37743
+ })
37744
+ ]
37745
+ }, extraPkg.name);
37746
+ })
37747
+ ]
37731
37748
  })
37732
37749
  }),
37733
37750
  /* @__PURE__ */ jsx210(ModalFooterContainer, {
@@ -37771,7 +37788,7 @@ var InstallPackageModal = ({ packageManager }) => {
37771
37788
  import { useCallback as useCallback103, useContext as useContext76, useMemo as useMemo112 } from "react";
37772
37789
 
37773
37790
  // src/components/RenderModal/ResolveCompositionBeforeModal.tsx
37774
- import React146, { useContext as useContext74, useEffect as useEffect74, useMemo as useMemo111 } from "react";
37791
+ import React146, { useContext as useContext74, useEffect as useEffect73, useMemo as useMemo111 } from "react";
37775
37792
  import { Internals as Internals56 } from "remotion";
37776
37793
  import { jsx as jsx211, jsxs as jsxs104 } from "react/jsx-runtime";
37777
37794
  var loaderContainer2 = {
@@ -37795,7 +37812,7 @@ var ResolveCompositionBeforeModal = ({ compositionId, children }) => {
37795
37812
  const resolved = Internals56.useResolvedVideoConfig(compositionId);
37796
37813
  const unresolvedContext = useContext74(Internals56.CompositionManager);
37797
37814
  const unresolved = unresolvedContext.compositions.find((c) => compositionId === c.id);
37798
- useEffect74(() => {
37815
+ useEffect73(() => {
37799
37816
  const { current } = Internals56.resolveCompositionsRef;
37800
37817
  if (!current) {
37801
37818
  throw new Error("No ref to trigger composition calc");
@@ -37853,7 +37870,7 @@ var ResolveCompositionBeforeModal = ({ compositionId, children }) => {
37853
37870
  };
37854
37871
 
37855
37872
  // src/components/NewComposition/CodemodFooter.tsx
37856
- import { useCallback as useCallback102, useContext as useContext75, useEffect as useEffect75, useState as useState71 } from "react";
37873
+ import { useCallback as useCallback102, useContext as useContext75, useEffect as useEffect74, useState as useState71 } from "react";
37857
37874
 
37858
37875
  // src/components/NewComposition/DiffPreview.tsx
37859
37876
  import { jsx as jsx212, jsxs as jsxs105 } from "react/jsx-runtime";
@@ -37918,7 +37935,7 @@ var CodemodFooter = ({
37918
37935
  type: "loading"
37919
37936
  });
37920
37937
  const [projectInfo, setProjectInfo] = useState71(null);
37921
- useEffect75(() => {
37938
+ useEffect74(() => {
37922
37939
  const controller = new AbortController;
37923
37940
  getProjectInfo(controller.signal).then((info) => {
37924
37941
  setProjectInfo(info.projectInfo);
@@ -37964,7 +37981,7 @@ var CodemodFooter = ({
37964
37981
  });
37965
37982
  }
37966
37983
  }, [codemod]);
37967
- useEffect75(() => {
37984
+ useEffect74(() => {
37968
37985
  const abortController = new AbortController;
37969
37986
  let aborted = false;
37970
37987
  getCanApplyCodemod(abortController.signal).then(() => {
@@ -37982,7 +37999,7 @@ var CodemodFooter = ({
37982
37999
  }, [codemodStatus, getCanApplyCodemod, setSelectedModal]);
37983
38000
  const disabled = !valid || submitting || projectInfo === null || codemodStatus.type !== "success";
37984
38001
  const { registerKeybinding } = useKeybinding();
37985
- useEffect75(() => {
38002
+ useEffect74(() => {
37986
38003
  if (disabled) {
37987
38004
  return;
37988
38005
  }
@@ -38804,7 +38821,7 @@ var OverrideInputPropsModal = () => {
38804
38821
  import {
38805
38822
  useCallback as useCallback108,
38806
38823
  useContext as useContext80,
38807
- useEffect as useEffect77,
38824
+ useEffect as useEffect76,
38808
38825
  useMemo as useMemo117,
38809
38826
  useRef as useRef42,
38810
38827
  useState as useState76
@@ -39604,7 +39621,7 @@ var QuickSwitcherNoResults = ({ query, mode }) => {
39604
39621
  };
39605
39622
 
39606
39623
  // src/components/QuickSwitcher/QuickSwitcherResult.tsx
39607
- import { useEffect as useEffect76, useMemo as useMemo116, useRef as useRef41, useState as useState75 } from "react";
39624
+ import { useEffect as useEffect75, useMemo as useMemo116, useRef as useRef41, useState as useState75 } from "react";
39608
39625
  import { jsx as jsx222, jsxs as jsxs114, Fragment as Fragment35 } from "react/jsx-runtime";
39609
39626
  var container49 = {
39610
39627
  paddingLeft: 16,
@@ -39636,7 +39653,7 @@ var QuickSwitcherResult = ({ result, selected }) => {
39636
39653
  const [hovered, setIsHovered] = useState75(false);
39637
39654
  const ref = useRef41(null);
39638
39655
  const keybindings = useKeybinding();
39639
- useEffect76(() => {
39656
+ useEffect75(() => {
39640
39657
  const { current } = ref;
39641
39658
  if (!current) {
39642
39659
  return;
@@ -39650,7 +39667,7 @@ var QuickSwitcherResult = ({ result, selected }) => {
39650
39667
  current.removeEventListener("mouseleave", onMouseLeave);
39651
39668
  };
39652
39669
  }, []);
39653
- useEffect76(() => {
39670
+ useEffect75(() => {
39654
39671
  if (!selected) {
39655
39672
  return;
39656
39673
  }
@@ -39667,7 +39684,7 @@ var QuickSwitcherResult = ({ result, selected }) => {
39667
39684
  binding.unregister();
39668
39685
  };
39669
39686
  }, [keybindings, result.onSelected, selected]);
39670
- useEffect76(() => {
39687
+ useEffect75(() => {
39671
39688
  if (selected) {
39672
39689
  ref.current?.scrollIntoView({
39673
39690
  block: "nearest",
@@ -39881,7 +39898,7 @@ var QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio }
39881
39898
  selectedIndex: 0
39882
39899
  };
39883
39900
  });
39884
- useEffect77(() => {
39901
+ useEffect76(() => {
39885
39902
  setState({
39886
39903
  query: mapModeToQuery(initialMode),
39887
39904
  selectedIndex: 0
@@ -39955,7 +39972,7 @@ var QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio }
39955
39972
  };
39956
39973
  });
39957
39974
  }, []);
39958
- useEffect77(() => {
39975
+ useEffect76(() => {
39959
39976
  const binding = keybindings.registerKeybinding({
39960
39977
  key: "ArrowUp",
39961
39978
  callback: onArrowUp,
@@ -39969,7 +39986,7 @@ var QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio }
39969
39986
  binding.unregister();
39970
39987
  };
39971
39988
  }, [keybindings, onArrowDown, onArrowUp]);
39972
- useEffect77(() => {
39989
+ useEffect76(() => {
39973
39990
  if (mode !== "docs") {
39974
39991
  return;
39975
39992
  }
@@ -39994,7 +40011,7 @@ var QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio }
39994
40011
  cancelled = true;
39995
40012
  };
39996
40013
  }, [actualQuery, mode]);
39997
- useEffect77(() => {
40014
+ useEffect76(() => {
39998
40015
  const binding = keybindings.registerKeybinding({
39999
40016
  key: "ArrowDown",
40000
40017
  callback: onArrowDown,
@@ -40648,7 +40665,7 @@ import { getDefaultOutLocation } from "@remotion/studio-shared";
40648
40665
  import {
40649
40666
  useCallback as useCallback128,
40650
40667
  useContext as useContext83,
40651
- useEffect as useEffect80,
40668
+ useEffect as useEffect79,
40652
40669
  useMemo as useMemo128,
40653
40670
  useReducer as useReducer2,
40654
40671
  useRef as useRef44,
@@ -40818,7 +40835,7 @@ import { useCallback as useCallback113 } from "react";
40818
40835
  import { BrowserSafeApis } from "@remotion/renderer/client";
40819
40836
 
40820
40837
  // src/components/RenderModal/CliCopyButton.tsx
40821
- import { useCallback as useCallback112, useEffect as useEffect78, useMemo as useMemo121, useState as useState79 } from "react";
40838
+ import { useCallback as useCallback112, useEffect as useEffect77, useMemo as useMemo121, useState as useState79 } from "react";
40822
40839
  import { jsx as jsx235 } from "react/jsx-runtime";
40823
40840
  var svgStyle2 = {
40824
40841
  width: 16,
@@ -40869,7 +40886,7 @@ var CliCopyButton = ({
40869
40886
  const onPointerLeave = useCallback112(() => {
40870
40887
  setHovered(false);
40871
40888
  }, []);
40872
- useEffect78(() => {
40889
+ useEffect77(() => {
40873
40890
  if (!copied) {
40874
40891
  return;
40875
40892
  }
@@ -42191,14 +42208,14 @@ import { BrowserSafeApis as BrowserSafeApis4 } from "@remotion/renderer/client";
42191
42208
  import { useCallback as useCallback120, useMemo as useMemo123 } from "react";
42192
42209
 
42193
42210
  // src/helpers/use-file-existence.ts
42194
- import { useContext as useContext82, useEffect as useEffect79, useRef as useRef43, useState as useState81 } from "react";
42211
+ import { useContext as useContext82, useEffect as useEffect78, useRef as useRef43, useState as useState81 } from "react";
42195
42212
  var useFileExistence = (outName) => {
42196
42213
  const [exists, setExists] = useState81(false);
42197
42214
  const { previewServerState: state, subscribeToEvent } = useContext82(StudioServerConnectionCtx);
42198
42215
  const clientId = state.type === "connected" ? state.clientId : undefined;
42199
42216
  const currentOutName = useRef43("");
42200
42217
  currentOutName.current = outName;
42201
- useEffect79(() => {
42218
+ useEffect78(() => {
42202
42219
  if (!clientId) {
42203
42220
  return;
42204
42221
  }
@@ -42214,7 +42231,7 @@ var useFileExistence = (outName) => {
42214
42231
  unsubscribeFromFileExistenceWatcher({ file: outName, clientId });
42215
42232
  };
42216
42233
  }, [clientId, outName]);
42217
- useEffect79(() => {
42234
+ useEffect78(() => {
42218
42235
  const listener = (event) => {
42219
42236
  if (event.type !== "watched-file-deleted") {
42220
42237
  return;
@@ -42231,7 +42248,7 @@ var useFileExistence = (outName) => {
42231
42248
  unsub();
42232
42249
  };
42233
42250
  }, [outName, subscribeToEvent]);
42234
- useEffect79(() => {
42251
+ useEffect78(() => {
42235
42252
  const listener = (event) => {
42236
42253
  if (event.type !== "watched-file-undeleted") {
42237
42254
  return;
@@ -44283,7 +44300,7 @@ var RenderModal = ({
44283
44300
  offthreadVideoThreads,
44284
44301
  mediaCacheSizeInBytes
44285
44302
  ]);
44286
- useEffect80(() => {
44303
+ useEffect79(() => {
44287
44304
  return () => {
44288
44305
  isMounted.current = false;
44289
44306
  };
@@ -44452,7 +44469,7 @@ var RenderModal = ({
44452
44469
  onClickVideo();
44453
44470
  }
44454
44471
  }, [renderMode, onClickStill, onClickSequence, onClickVideo]);
44455
- useEffect80(() => {
44472
+ useEffect79(() => {
44456
44473
  if (renderDisabled) {
44457
44474
  return;
44458
44475
  }
@@ -44780,7 +44797,7 @@ import {
44780
44797
  getEncodableAudioCodecs,
44781
44798
  getSupportedAudioCodecsForContainer
44782
44799
  } from "@remotion/web-renderer";
44783
- import { useEffect as useEffect81, useRef as useRef45, useState as useState83 } from "react";
44800
+ import { useEffect as useEffect80, useRef as useRef45, useState as useState83 } from "react";
44784
44801
  var useEncodableAudioCodecs = (container60) => {
44785
44802
  const cacheRef = useRef45({});
44786
44803
  const [codecsByContainer, setCodecsByContainer] = useState83(() => {
@@ -44788,7 +44805,7 @@ var useEncodableAudioCodecs = (container60) => {
44788
44805
  [container60]: getSupportedAudioCodecsForContainer(container60)
44789
44806
  };
44790
44807
  });
44791
- useEffect81(() => {
44808
+ useEffect80(() => {
44792
44809
  const cached = cacheRef.current[container60];
44793
44810
  if (cached) {
44794
44811
  return;
@@ -44822,7 +44839,7 @@ import {
44822
44839
  getEncodableVideoCodecs,
44823
44840
  getSupportedVideoCodecsForContainer
44824
44841
  } from "@remotion/web-renderer";
44825
- import { useEffect as useEffect82, useRef as useRef46, useState as useState84 } from "react";
44842
+ import { useEffect as useEffect81, useRef as useRef46, useState as useState84 } from "react";
44826
44843
  var useEncodableVideoCodecs = (container60) => {
44827
44844
  const cacheRef = useRef46({});
44828
44845
  const [codecsByContainer, setCodecsByContainer] = useState84(() => {
@@ -44830,7 +44847,7 @@ var useEncodableVideoCodecs = (container60) => {
44830
44847
  [container60]: getSupportedVideoCodecsForContainer(container60)
44831
44848
  };
44832
44849
  });
44833
- useEffect82(() => {
44850
+ useEffect81(() => {
44834
44851
  const cached = cacheRef.current[container60];
44835
44852
  if (cached) {
44836
44853
  return;
@@ -45469,7 +45486,7 @@ var WebRenderModalBasic = ({
45469
45486
  };
45470
45487
 
45471
45488
  // src/components/RenderModal/WebRenderModalLicense.tsx
45472
- import { useCallback as useCallback130, useEffect as useEffect83, useState as useState85 } from "react";
45489
+ import { useCallback as useCallback130, useEffect as useEffect82, useState as useState85 } from "react";
45473
45490
 
45474
45491
  // src/icons/check-circle-filled.tsx
45475
45492
  import { jsx as jsx265 } from "react/jsx-runtime";
@@ -45691,7 +45708,7 @@ var WebRenderModalLicense = ({
45691
45708
  }) => {
45692
45709
  const [licenseValidation, setLicenseValidation] = useState85({ valid: true, message: null, details: null });
45693
45710
  const [isLoading, setIsLoading] = useState85(false);
45694
- useEffect83(() => {
45711
+ useEffect82(() => {
45695
45712
  if (licenseKey === null || licenseKey === "free-license") {
45696
45713
  return setLicenseValidation({
45697
45714
  valid: true,
@@ -46525,7 +46542,7 @@ var WebRenderModalWithLoader = (props) => {
46525
46542
  import { useCallback as useCallback135, useMemo as useMemo135 } from "react";
46526
46543
 
46527
46544
  // src/components/CopyButton.tsx
46528
- import { useCallback as useCallback133, useEffect as useEffect84, useState as useState87 } from "react";
46545
+ import { useCallback as useCallback133, useEffect as useEffect83, useState as useState87 } from "react";
46529
46546
  import { jsx as jsx270, jsxs as jsxs145 } from "react/jsx-runtime";
46530
46547
  var iconStyle8 = {
46531
46548
  width: 16,
@@ -46563,7 +46580,7 @@ var CopyButton = ({ textToCopy, label: label12, labelWhenCopied }) => {
46563
46580
  showNotification(`Could not copy: ${err.message}`, 2000);
46564
46581
  });
46565
46582
  }, [textToCopy]);
46566
- useEffect84(() => {
46583
+ useEffect83(() => {
46567
46584
  if (!copied) {
46568
46585
  return;
46569
46586
  }
@@ -46915,7 +46932,7 @@ var Editor = ({ Root, readOnlyStudio }) => {
46915
46932
  triggerOnWindowResize: false,
46916
46933
  shouldApplyCssTransforms: true
46917
46934
  });
46918
- useEffect85(() => {
46935
+ useEffect84(() => {
46919
46936
  if (readOnlyStudio) {
46920
46937
  return;
46921
46938
  }
@@ -47113,7 +47130,7 @@ var ModalsProvider = ({ children }) => {
47113
47130
 
47114
47131
  // src/components/RenderQueue/ClientRenderQueueProcessor.tsx
47115
47132
  import { renderMediaOnWeb, renderStillOnWeb } from "@remotion/web-renderer";
47116
- import { useCallback as useCallback139, useContext as useContext87, useEffect as useEffect86 } from "react";
47133
+ import { useCallback as useCallback139, useContext as useContext87, useEffect as useEffect85 } from "react";
47117
47134
  var downloadBlob = (blob, filename) => {
47118
47135
  const url = URL.createObjectURL(blob);
47119
47136
  const a = document.createElement("a");
@@ -47249,7 +47266,7 @@ var ClientRenderQueueProcessor = () => {
47249
47266
  markClientJobFailed,
47250
47267
  markClientJobCancelled
47251
47268
  ]);
47252
- useEffect86(() => {
47269
+ useEffect85(() => {
47253
47270
  setProcessJobCallback(processJob);
47254
47271
  return () => setProcessJobCallback(null);
47255
47272
  }, [processJob, setProcessJobCallback]);
@@ -47257,7 +47274,7 @@ var ClientRenderQueueProcessor = () => {
47257
47274
  };
47258
47275
 
47259
47276
  // src/components/SetTimelineInOutProvider.tsx
47260
- import { useEffect as useEffect87, useMemo as useMemo141, useState as useState93 } from "react";
47277
+ import { useEffect as useEffect86, useMemo as useMemo141, useState as useState93 } from "react";
47261
47278
 
47262
47279
  // src/state/marks.ts
47263
47280
  var localStorageKey5 = () => `remotion.editor.marksv2`;
@@ -47281,7 +47298,7 @@ var SetTimelineInOutProvider = ({ children }) => {
47281
47298
  setInAndOutFrames
47282
47299
  };
47283
47300
  }, []);
47284
- useEffect87(() => {
47301
+ useEffect86(() => {
47285
47302
  persistMarks(inAndOutFrames);
47286
47303
  }, [inAndOutFrames]);
47287
47304
  return /* @__PURE__ */ jsx280(TimelineInOutContext.Provider, {
@@ -47697,7 +47714,7 @@ var Studio = ({ rootComponent, readOnly }) => {
47697
47714
  };
47698
47715
 
47699
47716
  // src/components/NoRegisterRoot.tsx
47700
- import { useEffect as useEffect88, useState as useState97 } from "react";
47717
+ import { useEffect as useEffect87, useState as useState97 } from "react";
47701
47718
  import { AbsoluteFill as AbsoluteFill6 } from "remotion";
47702
47719
  import { jsx as jsx287, jsxs as jsxs153 } from "react/jsx-runtime";
47703
47720
  var label12 = {
@@ -47719,7 +47736,7 @@ var link5 = {
47719
47736
  };
47720
47737
  var NoRegisterRoot = () => {
47721
47738
  const [show, setShow] = useState97(() => false);
47722
- useEffect88(() => {
47739
+ useEffect87(() => {
47723
47740
  const timeout = setTimeout(() => {
47724
47741
  setShow(true);
47725
47742
  }, 2000);