@remotion/studio 4.0.487 → 4.0.489

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.
@@ -447,19 +447,55 @@ var KeybindingContextProvider = ({ children }) => {
447
447
  });
448
448
  };
449
449
 
450
+ // src/helpers/studio-runtime-config.ts
451
+ import { DEFAULT_TIMELINE_TRACKS } from "@remotion/studio-shared";
452
+ var DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS = 300;
453
+ var defaultStudioRuntimeConfig = {
454
+ askAIEnabled: false,
455
+ bufferStateDelayInMilliseconds: null,
456
+ experimentalClientSideRenderingEnabled: false,
457
+ interactivityEnabled: true,
458
+ keyboardShortcutsEnabled: true,
459
+ maxTimelineTracks: null
460
+ };
461
+ var getStudioRuntimeConfig = () => {
462
+ if (typeof window === "undefined") {
463
+ return defaultStudioRuntimeConfig;
464
+ }
465
+ return window.remotion_studioConfig ?? defaultStudioRuntimeConfig;
466
+ };
467
+ var getStudioAskAIEnabled = () => {
468
+ return getStudioRuntimeConfig().askAIEnabled;
469
+ };
470
+ var getStudioInteractivityEnabled = () => {
471
+ return getStudioRuntimeConfig().interactivityEnabled;
472
+ };
473
+ var getStudioKeyboardShortcutsEnabled = () => {
474
+ return getStudioRuntimeConfig().keyboardShortcutsEnabled;
475
+ };
476
+ var getStudioExperimentalClientSideRenderingEnabled = () => {
477
+ return getStudioRuntimeConfig().experimentalClientSideRenderingEnabled;
478
+ };
479
+ var getStudioMaxTimelineTracks = () => {
480
+ return getStudioRuntimeConfig().maxTimelineTracks ?? DEFAULT_TIMELINE_TRACKS;
481
+ };
482
+ var getStudioBufferStateDelayInMilliseconds = () => {
483
+ return getStudioRuntimeConfig().bufferStateDelayInMilliseconds ?? DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS;
484
+ };
485
+
450
486
  // src/helpers/use-keybinding.ts
451
- if (!process.env.KEYBOARD_SHORTCUTS_ENABLED) {
487
+ if (!getStudioKeyboardShortcutsEnabled()) {
452
488
  console.warn("Keyboard shortcuts disabled either due to: a) --disable-keyboard-shortcuts being passed b) Config.setKeyboardShortcutsEnabled(false) being set or c) a Remotion version mismatch.");
453
489
  }
454
490
  var areKeyboardShortcutsDisabled = () => {
455
- return !process.env.KEYBOARD_SHORTCUTS_ENABLED;
491
+ return !getStudioKeyboardShortcutsEnabled();
456
492
  };
457
493
  var useKeybinding = () => {
458
494
  const [paneId] = useState3(() => String(Math.random()));
459
495
  const context = useContext(KeybindingContext);
460
496
  const { isHighestContext } = useZIndex();
461
497
  const registerKeybinding = useCallback2((options) => {
462
- if (!process.env.KEYBOARD_SHORTCUTS_ENABLED) {
498
+ if (!getStudioKeyboardShortcutsEnabled()) {
463
499
  return {
464
500
  unregister: () => {
465
501
  return;
@@ -2278,7 +2314,7 @@ var MenuContent = ({
2278
2314
  return containerStyles;
2279
2315
  }, [fixedHeight, isMobileLayout]);
2280
2316
  useEffect8(() => {
2281
- if (!keybindings.isHighestContext || !process.env.KEYBOARD_SHORTCUTS_ENABLED) {
2317
+ if (!keybindings.isHighestContext || !getStudioKeyboardShortcutsEnabled()) {
2282
2318
  return;
2283
2319
  }
2284
2320
  const onKeyDown = (event) => {
@@ -4168,7 +4204,7 @@ var pickColor = () => {
4168
4204
  };
4169
4205
 
4170
4206
  // src/helpers/show-browser-rendering.ts
4171
- var SHOW_BROWSER_RENDERING = Boolean(process.env.EXPERIMENTAL_CLIENT_SIDE_RENDERING_ENABLED);
4207
+ var SHOW_BROWSER_RENDERING = getStudioExperimentalClientSideRenderingEnabled();
4172
4208
 
4173
4209
  // src/helpers/use-menu-structure.tsx
4174
4210
  import { jsx as jsx29 } from "react/jsx-runtime";
@@ -4812,7 +4848,7 @@ var useMenuStructure = (closeMenu, readOnlyStudio) => {
4812
4848
  label: "Tools",
4813
4849
  leaveLeftPadding: false,
4814
4850
  items: [
4815
- process.env.ASK_AI_ENABLED ? {
4851
+ getStudioAskAIEnabled() ? {
4816
4852
  id: "ask-ai",
4817
4853
  value: "ask-ai",
4818
4854
  label: "Ask AI",
@@ -7676,12 +7712,12 @@ var TimelineZoomContext = ({ children }) => {
7676
7712
  // src/components/Canvas.tsx
7677
7713
  import {
7678
7714
  ASSET_DRAG_MIME_TYPE as ASSET_DRAG_MIME_TYPE2,
7679
- COMPOSITION_DRAG_MIME_TYPE as COMPOSITION_DRAG_MIME_TYPE2,
7680
7715
  COMPONENT_DRAG_MIME_TYPE as COMPONENT_DRAG_MIME_TYPE2,
7716
+ COMPOSITION_DRAG_MIME_TYPE as COMPOSITION_DRAG_MIME_TYPE2,
7681
7717
  ELEMENT_DRAG_MIME_TYPE as ELEMENT_DRAG_MIME_TYPE3,
7682
7718
  parseAssetDragData,
7683
- parseCompositionDragData,
7684
7719
  parseComponentDragData,
7720
+ parseCompositionDragData,
7685
7721
  parseSfxDragData,
7686
7722
  SFX_DRAG_MIME_TYPE as SFX_DRAG_MIME_TYPE2
7687
7723
  } from "@remotion/studio-shared";
@@ -7963,21 +7999,191 @@ var getRemoteAssetUrlFromDataTransfer = (dataTransfer) => {
7963
7999
  return isHttpUrl(plainText) ? plainText : null;
7964
8000
  };
7965
8001
 
8002
+ // src/components/ConfirmationDialog.tsx
8003
+ import {
8004
+ useCallback as useCallback28,
8005
+ useContext as useContext13,
8006
+ useEffect as useEffect25,
8007
+ useMemo as useMemo32,
8008
+ useRef as useRef15
8009
+ } from "react";
8010
+
8011
+ // src/components/ModalButton.tsx
8012
+ import { useMemo as useMemo31 } from "react";
8013
+ import { jsx as jsx57 } from "react/jsx-runtime";
8014
+ var buttonStyle2 = {
8015
+ backgroundColor: BLUE,
8016
+ color: WHITE
8017
+ };
8018
+ var ModalButton = (props) => {
8019
+ const style5 = useMemo31(() => {
8020
+ return {
8021
+ ...buttonStyle2,
8022
+ backgroundColor: props.disabled ? BLUE_DISABLED : BLUE
8023
+ };
8024
+ }, [props.disabled]);
8025
+ return /* @__PURE__ */ jsx57(Button, {
8026
+ ...props,
8027
+ style: style5
8028
+ });
8029
+ };
8030
+
8031
+ // src/components/ModalFooter.tsx
8032
+ import { jsx as jsx58 } from "react/jsx-runtime";
8033
+ var content = {
8034
+ padding: 12,
8035
+ paddingRight: 12,
8036
+ flex: 1,
8037
+ fontSize: 13,
8038
+ minWidth: 500
8039
+ };
8040
+ var ModalFooterContainer = ({ children }) => {
8041
+ return /* @__PURE__ */ jsx58("div", {
8042
+ style: { ...content, borderTop: BORDER_BLACK },
8043
+ children
8044
+ });
8045
+ };
8046
+
8047
+ // src/components/ConfirmationDialog.tsx
8048
+ import { jsx as jsx59, jsxs as jsxs28 } from "react/jsx-runtime";
8049
+ var content2 = {
8050
+ padding: 16,
8051
+ fontSize: 14,
8052
+ flex: 1,
8053
+ minWidth: 420,
8054
+ maxWidth: 560,
8055
+ lineHeight: 1.4
8056
+ };
8057
+ var useConfirmationDialog = () => {
8058
+ const { setSelectedModal } = useContext13(ModalsContext);
8059
+ return useCallback28((options) => {
8060
+ return new Promise((resolve) => {
8061
+ let settled = false;
8062
+ const settle = (result) => {
8063
+ if (settled) {
8064
+ return;
8065
+ }
8066
+ settled = true;
8067
+ resolve(result);
8068
+ };
8069
+ setSelectedModal({
8070
+ type: "confirmation-dialog",
8071
+ id: String(Math.random()),
8072
+ title: options.title,
8073
+ message: options.message,
8074
+ confirmLabel: options.confirmLabel ?? "Continue",
8075
+ cancelLabel: options.cancelLabel ?? "Cancel",
8076
+ onConfirm: () => settle(true),
8077
+ onCancel: () => settle(false)
8078
+ });
8079
+ });
8080
+ }, [setSelectedModal]);
8081
+ };
8082
+ var ConfirmationDialog = ({ state }) => {
8083
+ const { setSelectedModal } = useContext13(ModalsContext);
8084
+ const settledRef = useRef15(false);
8085
+ const closeCurrentModal = useCallback28(() => {
8086
+ setSelectedModal((modal) => modal?.type === "confirmation-dialog" && modal.id === state.id ? null : modal);
8087
+ }, [setSelectedModal, state.id]);
8088
+ const settle = useCallback28((confirmed) => {
8089
+ if (settledRef.current) {
8090
+ return;
8091
+ }
8092
+ settledRef.current = true;
8093
+ closeCurrentModal();
8094
+ if (confirmed) {
8095
+ state.onConfirm();
8096
+ } else {
8097
+ state.onCancel();
8098
+ }
8099
+ }, [closeCurrentModal, state]);
8100
+ useEffect25(() => {
8101
+ return () => {
8102
+ if (settledRef.current) {
8103
+ return;
8104
+ }
8105
+ settledRef.current = true;
8106
+ state.onCancel();
8107
+ };
8108
+ }, [state]);
8109
+ const onCancel = useCallback28(() => {
8110
+ settle(false);
8111
+ }, [settle]);
8112
+ const onConfirm = useCallback28(() => {
8113
+ settle(true);
8114
+ }, [settle]);
8115
+ const onSubmit = useCallback28((e) => {
8116
+ e.preventDefault();
8117
+ onConfirm();
8118
+ }, [onConfirm]);
8119
+ const cancelStyle = useMemo32(() => {
8120
+ return {
8121
+ minWidth: 90
8122
+ };
8123
+ }, []);
8124
+ return /* @__PURE__ */ jsxs28(ModalContainer, {
8125
+ onOutsideClick: onCancel,
8126
+ onEscape: onCancel,
8127
+ children: [
8128
+ /* @__PURE__ */ jsx59(ModalHeader, {
8129
+ title: state.title,
8130
+ onClose: onCancel
8131
+ }),
8132
+ /* @__PURE__ */ jsxs28("form", {
8133
+ onSubmit,
8134
+ children: [
8135
+ /* @__PURE__ */ jsx59("div", {
8136
+ style: content2,
8137
+ children: state.message
8138
+ }),
8139
+ /* @__PURE__ */ jsx59(ModalFooterContainer, {
8140
+ children: /* @__PURE__ */ jsxs28(Row, {
8141
+ align: "center",
8142
+ children: [
8143
+ /* @__PURE__ */ jsx59(Flex, {}),
8144
+ /* @__PURE__ */ jsx59(Button, {
8145
+ onClick: onCancel,
8146
+ style: cancelStyle,
8147
+ children: state.cancelLabel
8148
+ }),
8149
+ /* @__PURE__ */ jsx59(Spacing, {
8150
+ x: 1
8151
+ }),
8152
+ /* @__PURE__ */ jsxs28(ModalButton, {
8153
+ onClick: onConfirm,
8154
+ autoFocus: true,
8155
+ children: [
8156
+ state.confirmLabel,
8157
+ /* @__PURE__ */ jsx59(ShortcutHint, {
8158
+ keyToPress: "↵",
8159
+ cmdOrCtrl: false
8160
+ })
8161
+ ]
8162
+ })
8163
+ ]
8164
+ })
8165
+ })
8166
+ ]
8167
+ })
8168
+ ]
8169
+ });
8170
+ };
8171
+
7966
8172
  // src/components/EditorGuides/index.tsx
7967
8173
  import { useContext as useContext19, useMemo as useMemo39 } from "react";
7968
8174
  import { Internals as Internals22 } from "remotion";
7969
8175
 
7970
8176
  // src/helpers/use-studio-canvas-dimensions.ts
7971
8177
  import { PlayerInternals as PlayerInternals7 } from "@remotion/player";
7972
- import { useContext as useContext13, useMemo as useMemo31 } from "react";
8178
+ import { useContext as useContext14, useMemo as useMemo33 } from "react";
7973
8179
  import { Internals as Internals12 } from "remotion";
7974
8180
  var useStudioCanvasDimensions = ({
7975
8181
  canvasSize,
7976
8182
  contentDimensions,
7977
8183
  assetMetadata
7978
8184
  }) => {
7979
- const { size: previewSize } = useContext13(Internals12.PreviewSizeContext);
7980
- const { centerX, centerY, scale } = useMemo31(() => {
8185
+ const { size: previewSize } = useContext14(Internals12.PreviewSizeContext);
8186
+ const { centerX, centerY, scale } = useMemo33(() => {
7981
8187
  if (contentDimensions === "none" || contentDimensions === null || assetMetadata && (assetMetadata.type === "not-found" || assetMetadata.type === "metadata-error") || !canvasSize) {
7982
8188
  return {
7983
8189
  centerX: previewSize.translation.x,
@@ -7999,7 +8205,7 @@ var useStudioCanvasDimensions = ({
7999
8205
  previewSize.translation.x,
8000
8206
  assetMetadata
8001
8207
  ]);
8002
- const canvasPosition = useMemo31(() => {
8208
+ const canvasPosition = useMemo33(() => {
8003
8209
  return {
8004
8210
  left: centerX - previewSize.translation.x,
8005
8211
  top: centerY - previewSize.translation.y,
@@ -8086,9 +8292,9 @@ var getRulerGuideHighlight = ({
8086
8292
 
8087
8293
  // src/components/ContextMenu.tsx
8088
8294
  import { PlayerInternals as PlayerInternals8 } from "@remotion/player";
8089
- import React44, { useCallback as useCallback28, useEffect as useEffect25, useMemo as useMemo32, useRef as useRef15, useState as useState24 } from "react";
8295
+ import React46, { useCallback as useCallback29, useEffect as useEffect26, useMemo as useMemo34, useRef as useRef16, useState as useState24 } from "react";
8090
8296
  import ReactDOM4 from "react-dom";
8091
- import { jsx as jsx57, jsxs as jsxs28, Fragment as Fragment11 } from "react/jsx-runtime";
8297
+ import { jsx as jsx60, jsxs as jsxs29, Fragment as Fragment11 } from "react/jsx-runtime";
8092
8298
  var CONTEXT_MENU_Z_INDEX = 1001;
8093
8299
  var contextMenuFullScreenOverlay = {
8094
8300
  ...fullScreenOverlay,
@@ -8107,25 +8313,25 @@ var notifyContextMenuOpened = (id) => {
8107
8313
  }));
8108
8314
  };
8109
8315
  var ContextMenuPortal = ({ sizeSource, currentZIndex, onHide, opened, values }) => {
8110
- const menuRef = useRef15(null);
8316
+ const menuRef = useRef16(null);
8111
8317
  const size2 = PlayerInternals8.useElementSize(sizeSource, {
8112
8318
  triggerOnWindowResize: true,
8113
8319
  shouldApplyCssTransforms: true
8114
8320
  });
8115
8321
  const isMobileLayout = useMobileLayout();
8116
- const spaceToBottom = useMemo32(() => {
8322
+ const spaceToBottom = useMemo34(() => {
8117
8323
  if (size2) {
8118
8324
  return size2.windowSize.height - opened.top;
8119
8325
  }
8120
8326
  return 0;
8121
8327
  }, [opened.top, size2]);
8122
- const spaceToTop = useMemo32(() => {
8328
+ const spaceToTop = useMemo34(() => {
8123
8329
  if (size2) {
8124
8330
  return opened.top;
8125
8331
  }
8126
8332
  return 0;
8127
8333
  }, [opened.top, size2]);
8128
- const portalStyle = useMemo32(() => {
8334
+ const portalStyle = useMemo34(() => {
8129
8335
  if (!size2) {
8130
8336
  return;
8131
8337
  }
@@ -8157,7 +8363,7 @@ var ContextMenuPortal = ({ sizeSource, currentZIndex, onHide, opened, values })
8157
8363
  spaceToTop,
8158
8364
  spaceToBottom
8159
8365
  ]);
8160
- useEffect25(() => {
8366
+ useEffect26(() => {
8161
8367
  const preventNativeContextMenu = (event) => {
8162
8368
  event.preventDefault();
8163
8369
  };
@@ -8166,7 +8372,7 @@ var ContextMenuPortal = ({ sizeSource, currentZIndex, onHide, opened, values })
8166
8372
  window.removeEventListener("contextmenu", preventNativeContextMenu, true);
8167
8373
  };
8168
8374
  }, []);
8169
- useEffect25(() => {
8375
+ useEffect26(() => {
8170
8376
  const dismissWithoutClickThrough = (event) => {
8171
8377
  if (event.button !== 0) {
8172
8378
  return;
@@ -8184,26 +8390,26 @@ var ContextMenuPortal = ({ sizeSource, currentZIndex, onHide, opened, values })
8184
8390
  window.removeEventListener("pointerdown", dismissWithoutClickThrough, true);
8185
8391
  };
8186
8392
  }, [onHide]);
8187
- const onMenuPointerDown = useCallback28((e) => {
8393
+ const onMenuPointerDown = useCallback29((e) => {
8188
8394
  e.stopPropagation();
8189
8395
  }, []);
8190
8396
  if (!portalStyle) {
8191
8397
  return null;
8192
8398
  }
8193
- return ReactDOM4.createPortal(/* @__PURE__ */ jsx57("div", {
8399
+ return ReactDOM4.createPortal(/* @__PURE__ */ jsx60("div", {
8194
8400
  style: contextMenuFullScreenOverlay,
8195
- children: /* @__PURE__ */ jsx57("div", {
8401
+ children: /* @__PURE__ */ jsx60("div", {
8196
8402
  style: contextMenuOuterPortal,
8197
8403
  className: "css-reset",
8198
- children: /* @__PURE__ */ jsx57(HigherZIndex, {
8404
+ children: /* @__PURE__ */ jsx60(HigherZIndex, {
8199
8405
  onOutsideClick: onHide,
8200
8406
  onEscape: onHide,
8201
8407
  outsideClickButton: "primary",
8202
- children: /* @__PURE__ */ jsx57("div", {
8408
+ children: /* @__PURE__ */ jsx60("div", {
8203
8409
  ref: menuRef,
8204
8410
  style: portalStyle,
8205
8411
  onPointerDown: onMenuPointerDown,
8206
- children: /* @__PURE__ */ jsx57(MenuContent, {
8412
+ children: /* @__PURE__ */ jsx60(MenuContent, {
8207
8413
  onNextMenu: noop,
8208
8414
  onPreviousMenu: noop,
8209
8415
  values,
@@ -8218,7 +8424,7 @@ var ContextMenuPortal = ({ sizeSource, currentZIndex, onHide, opened, values })
8218
8424
  })
8219
8425
  }), getPortal(currentZIndex));
8220
8426
  };
8221
- var ContextMenu = React44.forwardRef(({
8427
+ var ContextMenu = React46.forwardRef(({
8222
8428
  children,
8223
8429
  values,
8224
8430
  onOpen,
@@ -8226,11 +8432,11 @@ var ContextMenu = React44.forwardRef(({
8226
8432
  className: className2 = undefined,
8227
8433
  onPointerDown = undefined
8228
8434
  }, forwardedRef) => {
8229
- const ref = useRef15(null);
8230
- const idRef = useRef15(nextContextMenuId++);
8435
+ const ref = useRef16(null);
8436
+ const idRef = useRef16(nextContextMenuId++);
8231
8437
  const [opened, setOpened] = useState24({ type: "not-open" });
8232
8438
  const { currentZIndex } = useZIndex();
8233
- const setRef = useCallback28((node) => {
8439
+ const setRef = useCallback29((node) => {
8234
8440
  ref.current = node;
8235
8441
  if (typeof forwardedRef === "function") {
8236
8442
  forwardedRef(node);
@@ -8240,7 +8446,7 @@ var ContextMenu = React44.forwardRef(({
8240
8446
  forwardedRef.current = node;
8241
8447
  }
8242
8448
  }, [forwardedRef]);
8243
- useEffect25(() => {
8449
+ useEffect26(() => {
8244
8450
  const { current } = ref;
8245
8451
  if (!current) {
8246
8452
  return;
@@ -8260,10 +8466,10 @@ var ContextMenu = React44.forwardRef(({
8260
8466
  current.removeEventListener("contextmenu", onClick);
8261
8467
  };
8262
8468
  }, [onOpen]);
8263
- const onHide = useCallback28(() => {
8469
+ const onHide = useCallback29(() => {
8264
8470
  setOpened({ type: "not-open" });
8265
8471
  }, []);
8266
- useEffect25(() => {
8472
+ useEffect26(() => {
8267
8473
  const onOtherContextMenuOpened = (event) => {
8268
8474
  if (event.detail === idRef.current) {
8269
8475
  return;
@@ -8275,9 +8481,9 @@ var ContextMenu = React44.forwardRef(({
8275
8481
  window.removeEventListener(contextMenuOpenedEvent, onOtherContextMenuOpened);
8276
8482
  };
8277
8483
  }, [onHide]);
8278
- return /* @__PURE__ */ jsxs28(Fragment11, {
8484
+ return /* @__PURE__ */ jsxs29(Fragment11, {
8279
8485
  children: [
8280
- /* @__PURE__ */ jsx57("div", {
8486
+ /* @__PURE__ */ jsx60("div", {
8281
8487
  ref: setRef,
8282
8488
  onContextMenu: () => false,
8283
8489
  style: style5,
@@ -8285,7 +8491,7 @@ var ContextMenu = React44.forwardRef(({
8285
8491
  onPointerDown,
8286
8492
  children
8287
8493
  }),
8288
- opened.type === "open" ? /* @__PURE__ */ jsx57(ContextMenuPortal, {
8494
+ opened.type === "open" ? /* @__PURE__ */ jsx60(ContextMenuPortal, {
8289
8495
  sizeSource: ref,
8290
8496
  currentZIndex,
8291
8497
  onHide,
@@ -8297,15 +8503,15 @@ var ContextMenu = React44.forwardRef(({
8297
8503
  });
8298
8504
  ContextMenu.displayName = "ContextMenu";
8299
8505
  var ContextMenuForTarget = ({ triggerRef, values, onOpen }) => {
8300
- const idRef = useRef15(nextContextMenuId++);
8506
+ const idRef = useRef16(nextContextMenuId++);
8301
8507
  const [opened, setOpened] = useState24({ type: "not-open" });
8302
8508
  const [openedValues, setOpenedValues] = useState24(values);
8303
8509
  const [body, setBody] = useState24(null);
8304
8510
  const { currentZIndex } = useZIndex();
8305
- useEffect25(() => {
8511
+ useEffect26(() => {
8306
8512
  setBody(document.body);
8307
8513
  }, []);
8308
- useEffect25(() => {
8514
+ useEffect26(() => {
8309
8515
  const { current } = triggerRef;
8310
8516
  if (!current) {
8311
8517
  return;
@@ -8332,10 +8538,10 @@ var ContextMenuForTarget = ({ triggerRef, values, onOpen }) => {
8332
8538
  current.removeEventListener("contextmenu", onClick);
8333
8539
  };
8334
8540
  }, [onOpen, triggerRef, values]);
8335
- const onHide = useCallback28(() => {
8541
+ const onHide = useCallback29(() => {
8336
8542
  setOpened({ type: "not-open" });
8337
8543
  }, []);
8338
- useEffect25(() => {
8544
+ useEffect26(() => {
8339
8545
  const onOtherContextMenuOpened = (event) => {
8340
8546
  if (event.detail === idRef.current) {
8341
8547
  return;
@@ -8347,7 +8553,7 @@ var ContextMenuForTarget = ({ triggerRef, values, onOpen }) => {
8347
8553
  window.removeEventListener(contextMenuOpenedEvent, onOtherContextMenuOpened);
8348
8554
  };
8349
8555
  }, [onHide]);
8350
- return opened.type === "open" ? /* @__PURE__ */ jsx57(ContextMenuPortal, {
8556
+ return opened.type === "open" ? /* @__PURE__ */ jsx60(ContextMenuPortal, {
8351
8557
  sizeSource: body,
8352
8558
  currentZIndex,
8353
8559
  onHide,
@@ -8357,9 +8563,9 @@ var ContextMenuForTarget = ({ triggerRef, values, onOpen }) => {
8357
8563
  };
8358
8564
 
8359
8565
  // src/components/ForceSpecificCursor.tsx
8360
- import React45, { useMemo as useMemo33 } from "react";
8361
- import { jsx as jsx58 } from "react/jsx-runtime";
8362
- var ref = React45.createRef();
8566
+ import React47, { useMemo as useMemo35 } from "react";
8567
+ import { jsx as jsx61 } from "react/jsx-runtime";
8568
+ var ref = React47.createRef();
8363
8569
  var forceSpecificCursor = (cursor) => {
8364
8570
  if (!ref.current) {
8365
8571
  throw new Error("ForceSpecificCursor is not mounted");
@@ -8376,7 +8582,7 @@ var stopForcingSpecificCursor = () => {
8376
8582
  };
8377
8583
  var Z_INDEX_FORCE_SPECIFIC_CURSOR = 100;
8378
8584
  var ForceSpecificCursor = () => {
8379
- const style5 = useMemo33(() => {
8585
+ const style5 = useMemo35(() => {
8380
8586
  return {
8381
8587
  position: "fixed",
8382
8588
  inset: 0,
@@ -8384,7 +8590,7 @@ var ForceSpecificCursor = () => {
8384
8590
  pointerEvents: "none"
8385
8591
  };
8386
8592
  }, []);
8387
- return /* @__PURE__ */ jsx58("div", {
8593
+ return /* @__PURE__ */ jsx61("div", {
8388
8594
  ref,
8389
8595
  style: style5
8390
8596
  });
@@ -8420,6 +8626,9 @@ import {
8420
8626
  Internals as Internals21
8421
8627
  } from "remotion";
8422
8628
 
8629
+ // src/helpers/interactivity-enabled.ts
8630
+ var studioInteractivityEnabled = getStudioInteractivityEnabled();
8631
+
8423
8632
  // src/helpers/timeline-node-path-key.ts
8424
8633
  import { stringifySequenceExpandedRowKey } from "@remotion/studio-shared";
8425
8634
  var timelineNodePathInfoToKey = (info) => [
@@ -8429,7 +8638,7 @@ var timelineNodePathInfoToKey = (info) => [
8429
8638
  ].join(".");
8430
8639
 
8431
8640
  // src/components/ExpandedTracksProvider.tsx
8432
- import { createContext as createContext14, useCallback as useCallback29, useMemo as useMemo34, useState as useState25 } from "react";
8641
+ import { createContext as createContext14, useCallback as useCallback30, useMemo as useMemo36, useState as useState25 } from "react";
8433
8642
 
8434
8643
  // src/helpers/migrate-expanded-tracks-for-subscription-key.ts
8435
8644
  import { stringifySequenceExpandedRowKey as stringifySequenceExpandedRowKey2 } from "@remotion/studio-shared";
@@ -8456,7 +8665,7 @@ var migrateExpandedTracksForSubscriptionKey = (prev, oldKey, newKey) => {
8456
8665
  };
8457
8666
 
8458
8667
  // src/components/ExpandedTracksProvider.tsx
8459
- import { jsx as jsx59 } from "react/jsx-runtime";
8668
+ import { jsx as jsx62 } from "react/jsx-runtime";
8460
8669
  var SESSION_STORAGE_KEY = "remotion.editor.expandedTracks";
8461
8670
  var onlyCollapsedTrackValues = (state) => {
8462
8671
  const result = {};
@@ -8511,7 +8720,7 @@ var ExpandedTracksSetterContext = createContext14({
8511
8720
  });
8512
8721
  var ExpandedTracksProvider = ({ children }) => {
8513
8722
  const [expandedTracks, setExpandedTracks] = useState25(loadExpandedTracks);
8514
- const expandParentTracks = useCallback29((nodePathInfo) => {
8723
+ const expandParentTracks = useCallback30((nodePathInfo) => {
8515
8724
  const keysToExpand = [];
8516
8725
  for (let i = 0;i < nodePathInfo.auxiliaryKeys.length; i++) {
8517
8726
  keysToExpand.push(timelineNodePathInfoToKey({
@@ -8538,7 +8747,7 @@ var ExpandedTracksProvider = ({ children }) => {
8538
8747
  return next;
8539
8748
  });
8540
8749
  }, []);
8541
- const toggleTrack = useCallback29((nodePathInfo) => {
8750
+ const toggleTrack = useCallback30((nodePathInfo) => {
8542
8751
  setExpandedTracks((prev) => {
8543
8752
  const key2 = timelineNodePathInfoToKey(nodePathInfo);
8544
8753
  const next = { ...prev };
@@ -8552,7 +8761,7 @@ var ExpandedTracksProvider = ({ children }) => {
8552
8761
  return next;
8553
8762
  });
8554
8763
  }, []);
8555
- const migrateExpandedTracks = useCallback29((oldKey, newKey) => {
8764
+ const migrateExpandedTracks = useCallback30((oldKey, newKey) => {
8556
8765
  setExpandedTracks((prev) => {
8557
8766
  const next = migrateExpandedTracksForSubscriptionKey(prev, oldKey, newKey);
8558
8767
  if (!next) {
@@ -8562,17 +8771,17 @@ var ExpandedTracksProvider = ({ children }) => {
8562
8771
  return next;
8563
8772
  });
8564
8773
  }, []);
8565
- const getterValue = useMemo34(() => ({
8774
+ const getterValue = useMemo36(() => ({
8566
8775
  getIsExpanded: (nodePathInfo) => expandedTracks[timelineNodePathInfoToKey(nodePathInfo)] ?? true
8567
8776
  }), [expandedTracks]);
8568
- const setterValue = useMemo34(() => ({
8777
+ const setterValue = useMemo36(() => ({
8569
8778
  expandParentTracks,
8570
8779
  toggleTrack,
8571
8780
  migrateExpandedTracksForSubscriptionKey: migrateExpandedTracks
8572
8781
  }), [expandParentTracks, toggleTrack, migrateExpandedTracks]);
8573
- return /* @__PURE__ */ jsx59(ExpandedTracksSetterContext.Provider, {
8782
+ return /* @__PURE__ */ jsx62(ExpandedTracksSetterContext.Provider, {
8574
8783
  value: setterValue,
8575
- children: /* @__PURE__ */ jsx59(ExpandedTracksGetterContext.Provider, {
8784
+ children: /* @__PURE__ */ jsx62(ExpandedTracksGetterContext.Provider, {
8576
8785
  value: getterValue,
8577
8786
  children
8578
8787
  })
@@ -8769,7 +8978,7 @@ import {
8769
8978
  parseEffectClipboardDataResult,
8770
8979
  parseEffectPropClipboardDataResult
8771
8980
  } from "@remotion/studio-shared";
8772
- import { useContext as useContext14, useEffect as useEffect26 } from "react";
8981
+ import { useContext as useContext15, useEffect as useEffect27 } from "react";
8773
8982
  import {
8774
8983
  Internals as Internals16
8775
8984
  } from "remotion";
@@ -9713,14 +9922,14 @@ var getPasteEffectPropTarget = ({
9713
9922
  };
9714
9923
  var TimelineClipboardKeybindings = () => {
9715
9924
  const keybindings = useKeybinding();
9716
- const { previewServerState } = useContext14(StudioServerConnectionCtx);
9925
+ const { previewServerState } = useContext15(StudioServerConnectionCtx);
9717
9926
  const { canSelect } = useTimelineSelection();
9718
9927
  const currentSelection = useCurrentTimelineSelectionStateAsRef();
9719
- const propStatusesRef = useContext14(Internals16.VisualModePropStatusesRefContext);
9720
- const { setPropStatuses } = useContext14(Internals16.VisualModeSettersContext);
9721
- const sequencesRef = useContext14(Internals16.SequenceManagerRefContext);
9722
- const { overrideIdToNodePathMappings } = useContext14(Internals16.OverrideIdsToNodePathsGettersContext);
9723
- useEffect26(() => {
9928
+ const propStatusesRef = useContext15(Internals16.VisualModePropStatusesRefContext);
9929
+ const { setPropStatuses } = useContext15(Internals16.VisualModeSettersContext);
9930
+ const sequencesRef = useContext15(Internals16.SequenceManagerRefContext);
9931
+ const { overrideIdToNodePathMappings } = useContext15(Internals16.OverrideIdsToNodePathsGettersContext);
9932
+ useEffect27(() => {
9724
9933
  if (!canSelect || previewServerState.type !== "connected") {
9725
9934
  return;
9726
9935
  }
@@ -9987,176 +10196,6 @@ import { LINEAR_KEYFRAME_EASING as LINEAR_KEYFRAME_EASING2 } from "@remotion/stu
9987
10196
  import { useContext as useContext16, useEffect as useEffect28, useRef as useRef17 } from "react";
9988
10197
  import { Internals as Internals20 } from "remotion";
9989
10198
 
9990
- // src/components/ConfirmationDialog.tsx
9991
- import {
9992
- useCallback as useCallback30,
9993
- useContext as useContext15,
9994
- useEffect as useEffect27,
9995
- useMemo as useMemo36,
9996
- useRef as useRef16
9997
- } from "react";
9998
-
9999
- // src/components/ModalButton.tsx
10000
- import { useMemo as useMemo35 } from "react";
10001
- import { jsx as jsx60 } from "react/jsx-runtime";
10002
- var buttonStyle2 = {
10003
- backgroundColor: BLUE,
10004
- color: WHITE
10005
- };
10006
- var ModalButton = (props) => {
10007
- const style5 = useMemo35(() => {
10008
- return {
10009
- ...buttonStyle2,
10010
- backgroundColor: props.disabled ? BLUE_DISABLED : BLUE
10011
- };
10012
- }, [props.disabled]);
10013
- return /* @__PURE__ */ jsx60(Button, {
10014
- ...props,
10015
- style: style5
10016
- });
10017
- };
10018
-
10019
- // src/components/ModalFooter.tsx
10020
- import { jsx as jsx61 } from "react/jsx-runtime";
10021
- var content = {
10022
- padding: 12,
10023
- paddingRight: 12,
10024
- flex: 1,
10025
- fontSize: 13,
10026
- minWidth: 500
10027
- };
10028
- var ModalFooterContainer = ({ children }) => {
10029
- return /* @__PURE__ */ jsx61("div", {
10030
- style: { ...content, borderTop: BORDER_BLACK },
10031
- children
10032
- });
10033
- };
10034
-
10035
- // src/components/ConfirmationDialog.tsx
10036
- import { jsx as jsx62, jsxs as jsxs29 } from "react/jsx-runtime";
10037
- var content2 = {
10038
- padding: 16,
10039
- fontSize: 14,
10040
- flex: 1,
10041
- minWidth: 420,
10042
- maxWidth: 560,
10043
- lineHeight: 1.4
10044
- };
10045
- var useConfirmationDialog = () => {
10046
- const { setSelectedModal } = useContext15(ModalsContext);
10047
- return useCallback30((options) => {
10048
- return new Promise((resolve) => {
10049
- let settled = false;
10050
- const settle = (result) => {
10051
- if (settled) {
10052
- return;
10053
- }
10054
- settled = true;
10055
- resolve(result);
10056
- };
10057
- setSelectedModal({
10058
- type: "confirmation-dialog",
10059
- id: String(Math.random()),
10060
- title: options.title,
10061
- message: options.message,
10062
- confirmLabel: options.confirmLabel ?? "Continue",
10063
- cancelLabel: options.cancelLabel ?? "Cancel",
10064
- onConfirm: () => settle(true),
10065
- onCancel: () => settle(false)
10066
- });
10067
- });
10068
- }, [setSelectedModal]);
10069
- };
10070
- var ConfirmationDialog = ({ state }) => {
10071
- const { setSelectedModal } = useContext15(ModalsContext);
10072
- const settledRef = useRef16(false);
10073
- const closeCurrentModal = useCallback30(() => {
10074
- setSelectedModal((modal) => modal?.type === "confirmation-dialog" && modal.id === state.id ? null : modal);
10075
- }, [setSelectedModal, state.id]);
10076
- const settle = useCallback30((confirmed) => {
10077
- if (settledRef.current) {
10078
- return;
10079
- }
10080
- settledRef.current = true;
10081
- closeCurrentModal();
10082
- if (confirmed) {
10083
- state.onConfirm();
10084
- } else {
10085
- state.onCancel();
10086
- }
10087
- }, [closeCurrentModal, state]);
10088
- useEffect27(() => {
10089
- return () => {
10090
- if (settledRef.current) {
10091
- return;
10092
- }
10093
- settledRef.current = true;
10094
- state.onCancel();
10095
- };
10096
- }, [state]);
10097
- const onCancel = useCallback30(() => {
10098
- settle(false);
10099
- }, [settle]);
10100
- const onConfirm = useCallback30(() => {
10101
- settle(true);
10102
- }, [settle]);
10103
- const onSubmit = useCallback30((e) => {
10104
- e.preventDefault();
10105
- onConfirm();
10106
- }, [onConfirm]);
10107
- const cancelStyle = useMemo36(() => {
10108
- return {
10109
- minWidth: 90
10110
- };
10111
- }, []);
10112
- return /* @__PURE__ */ jsxs29(ModalContainer, {
10113
- onOutsideClick: onCancel,
10114
- onEscape: onCancel,
10115
- children: [
10116
- /* @__PURE__ */ jsx62(ModalHeader, {
10117
- title: state.title,
10118
- onClose: onCancel
10119
- }),
10120
- /* @__PURE__ */ jsxs29("form", {
10121
- onSubmit,
10122
- children: [
10123
- /* @__PURE__ */ jsx62("div", {
10124
- style: content2,
10125
- children: state.message
10126
- }),
10127
- /* @__PURE__ */ jsx62(ModalFooterContainer, {
10128
- children: /* @__PURE__ */ jsxs29(Row, {
10129
- align: "center",
10130
- children: [
10131
- /* @__PURE__ */ jsx62(Flex, {}),
10132
- /* @__PURE__ */ jsx62(Button, {
10133
- onClick: onCancel,
10134
- style: cancelStyle,
10135
- children: state.cancelLabel
10136
- }),
10137
- /* @__PURE__ */ jsx62(Spacing, {
10138
- x: 1
10139
- }),
10140
- /* @__PURE__ */ jsxs29(ModalButton, {
10141
- onClick: onConfirm,
10142
- autoFocus: true,
10143
- children: [
10144
- state.confirmLabel,
10145
- /* @__PURE__ */ jsx62(ShortcutHint, {
10146
- keyToPress: "↵",
10147
- cmdOrCtrl: false
10148
- })
10149
- ]
10150
- })
10151
- ]
10152
- })
10153
- })
10154
- ]
10155
- })
10156
- ]
10157
- });
10158
- };
10159
-
10160
10199
  // src/components/Timeline/delete-selected-timeline-item.ts
10161
10200
  import { Internals as Internals17 } from "remotion";
10162
10201
 
@@ -12004,7 +12043,7 @@ var TimelineSelectionProvider = ({ children }) => {
12004
12043
  const { canvasContent } = useContext17(Internals21.CompositionManager);
12005
12044
  const timelineSelectionScope = canvasContent?.type === "composition" ? canvasContent.compositionId : null;
12006
12045
  const { expandParentTracks } = useContext17(ExpandedTracksSetterContext);
12007
- const canSelect = previewServerState.type === "connected" && !window.remotion_isReadOnlyStudio;
12046
+ const canSelect = studioInteractivityEnabled && previewServerState.type === "connected" && !window.remotion_isReadOnlyStudio;
12008
12047
  const [selectedItems, setSelectedItems] = useState26([]);
12009
12048
  const selectionAnchor = useRef18(null);
12010
12049
  const selectionScope = useRef18(null);
@@ -21709,7 +21748,7 @@ var SelectedOutlineOverlay = ({
21709
21748
  selectItem(item, interaction, undefined, { reveal: true });
21710
21749
  }, [selectItem]);
21711
21750
  const outlineTargets = useMemo50(() => {
21712
- if (!editorShowOutlines) {
21751
+ if (!studioInteractivityEnabled || !editorShowOutlines) {
21713
21752
  return [];
21714
21753
  }
21715
21754
  const selectedSequenceKeys = getSelectedSequenceKeys(selectedItems);
@@ -22571,6 +22610,31 @@ var ResetZoomButton = ({ onClick }) => {
22571
22610
 
22572
22611
  // src/components/Canvas.tsx
22573
22612
  import { jsx as jsx84, jsxs as jsxs41, Fragment as Fragment17 } from "react/jsx-runtime";
22613
+ var elementInstallCompositionIdStyle = {
22614
+ fontFamily: "monospace",
22615
+ fontSize: 13
22616
+ };
22617
+ var elementInstallCodeDetailsStyle = {
22618
+ marginTop: 12,
22619
+ fontSize: 13
22620
+ };
22621
+ var elementInstallCodeSummaryStyle = {
22622
+ cursor: "pointer",
22623
+ fontSize: 13,
22624
+ fontWeight: 500
22625
+ };
22626
+ var elementInstallCodeBlockStyle = {
22627
+ marginTop: 8,
22628
+ marginBottom: 0,
22629
+ maxHeight: 240,
22630
+ overflow: "auto",
22631
+ padding: 12,
22632
+ borderRadius: 6,
22633
+ backgroundColor: "rgba(255, 255, 255, 0.06)",
22634
+ fontSize: 12,
22635
+ lineHeight: 1.5,
22636
+ whiteSpace: "pre"
22637
+ };
22574
22638
  var getContainerStyle = (editorZoomGestures) => ({
22575
22639
  flex: 1,
22576
22640
  display: "flex",
@@ -22705,12 +22769,18 @@ var Canvas = ({ canvasContent, size: size2 }) => {
22705
22769
  const suppressWheelFromWebKitPinchRef = useRef29(false);
22706
22770
  const touchPinchRef = useRef29(null);
22707
22771
  const keybindings = useKeybinding();
22772
+ const confirm = useConfirmationDialog();
22708
22773
  const config = Internals34.useUnsafeVideoConfig();
22709
22774
  const areRulersVisible = useIsRulerVisible();
22710
22775
  const { editorShowGuides } = useContext32(EditorShowGuidesContext);
22711
22776
  const { compositions } = useContext32(Internals34.CompositionManager);
22712
- const { previewServerState } = useContext32(StudioServerConnectionCtx);
22777
+ const { previewServerState, subscribeToEvent } = useContext32(StudioServerConnectionCtx);
22778
+ const previewServerClientId = previewServerState.type === "connected" ? previewServerState.clientId : null;
22713
22779
  const [isAddingAsset, setIsAddingAsset] = useState39(false);
22780
+ const [installingElementName, setInstallingElementName] = useState39(null);
22781
+ const [pendingElementInstallRequests, setPendingElementInstallRequests] = useState39([]);
22782
+ const [activeElementInstallRequest, setActiveElementInstallRequest] = useState39(null);
22783
+ const lastFocusedAtRef = useRef29(typeof document === "undefined" || document.hasFocus() ? Date.now() : null);
22714
22784
  const [assetResolution, setAssetResolution] = useState39(null);
22715
22785
  const currentCompositionId = canvasContent.type === "composition" ? canvasContent.compositionId : null;
22716
22786
  const currentComposition = useMemo52(() => {
@@ -22725,7 +22795,8 @@ var Canvas = ({ canvasContent, size: size2 }) => {
22725
22795
  compositionFile,
22726
22796
  compositionId: currentCompositionId
22727
22797
  });
22728
- const canDropAssets = previewServerState.type === "connected" && !window.remotion_isReadOnlyStudio && compositionComponentInfo?.canAddSequence === true && currentCompositionId !== null && compositionFile !== null && !isAddingAsset;
22798
+ const canInstallElements = previewServerClientId !== null && !window.remotion_isReadOnlyStudio && compositionComponentInfo?.canAddSequence === true && currentCompositionId !== null && compositionFile !== null;
22799
+ const canDropAssets = canInstallElements && !isAddingAsset;
22729
22800
  const contentDimensions = useMemo52(() => {
22730
22801
  if ((canvasContent.type === "asset" || canvasContent.type === "output" || canvasContent.type === "output-blob") && assetResolution && assetResolution.type === "found") {
22731
22802
  return assetResolution.dimensions;
@@ -23081,6 +23152,146 @@ var Canvas = ({ canvasContent, size: size2 }) => {
23081
23152
  useEffect40(() => {
23082
23153
  fetchMetadata();
23083
23154
  }, [fetchMetadata]);
23155
+ const updateElementInstallTarget = useCallback43((requestId) => {
23156
+ if (previewServerClientId === null) {
23157
+ return;
23158
+ }
23159
+ callApi("/api/update-element-install-target", {
23160
+ requestId,
23161
+ clientId: previewServerClientId,
23162
+ compositionFile: canInstallElements ? compositionFile : null,
23163
+ compositionId: canInstallElements ? currentCompositionId : null,
23164
+ canInstall: canInstallElements,
23165
+ lastFocusedAt: lastFocusedAtRef.current,
23166
+ readOnly: window.remotion_isReadOnlyStudio
23167
+ }).catch(() => {
23168
+ return;
23169
+ });
23170
+ }, [
23171
+ canInstallElements,
23172
+ compositionFile,
23173
+ currentCompositionId,
23174
+ previewServerClientId
23175
+ ]);
23176
+ useEffect40(() => {
23177
+ const markFocused = () => {
23178
+ lastFocusedAtRef.current = Date.now();
23179
+ };
23180
+ window.addEventListener("focus", markFocused);
23181
+ document.addEventListener("pointerdown", markFocused, { capture: true });
23182
+ return () => {
23183
+ window.removeEventListener("focus", markFocused);
23184
+ document.removeEventListener("pointerdown", markFocused, { capture: true });
23185
+ };
23186
+ }, []);
23187
+ useEffect40(() => {
23188
+ return subscribeToEvent("request-element-install-target", (event) => {
23189
+ if (event.type !== "request-element-install-target") {
23190
+ return;
23191
+ }
23192
+ updateElementInstallTarget(event.requestId);
23193
+ });
23194
+ }, [subscribeToEvent, updateElementInstallTarget]);
23195
+ useEffect40(() => {
23196
+ if (installingElementName === null) {
23197
+ return;
23198
+ }
23199
+ const previousTitle = document.title;
23200
+ document.title = `\uD83D\uDCE6 Install ${installingElementName} - Remotion Studio`;
23201
+ return () => {
23202
+ document.title = previousTitle;
23203
+ };
23204
+ }, [installingElementName]);
23205
+ useEffect40(() => {
23206
+ if (previewServerClientId === null) {
23207
+ return;
23208
+ }
23209
+ return subscribeToEvent("element-install-request", (event) => {
23210
+ if (event.type !== "element-install-request" || event.request.clientId !== previewServerClientId) {
23211
+ return;
23212
+ }
23213
+ setPendingElementInstallRequests((requests) => [
23214
+ ...requests,
23215
+ event.request
23216
+ ]);
23217
+ });
23218
+ }, [previewServerClientId, subscribeToEvent]);
23219
+ useEffect40(() => {
23220
+ if (activeElementInstallRequest !== null || pendingElementInstallRequests.length === 0) {
23221
+ return;
23222
+ }
23223
+ const [nextRequest, ...remainingRequests] = pendingElementInstallRequests;
23224
+ if (!nextRequest) {
23225
+ throw new Error("Expected pending Element install request");
23226
+ }
23227
+ setActiveElementInstallRequest(nextRequest);
23228
+ setPendingElementInstallRequests(remainingRequests);
23229
+ }, [activeElementInstallRequest, pendingElementInstallRequests]);
23230
+ useEffect40(() => {
23231
+ if (activeElementInstallRequest === null) {
23232
+ return;
23233
+ }
23234
+ let canceled = false;
23235
+ const handleInstallRequest = async () => {
23236
+ setInstallingElementName(activeElementInstallRequest.element.displayName);
23237
+ const accepted = await confirm({
23238
+ title: "Install Element",
23239
+ message: /* @__PURE__ */ jsxs41(Fragment17, {
23240
+ children: [
23241
+ "Install “",
23242
+ activeElementInstallRequest.element.displayName,
23243
+ "” into",
23244
+ " ",
23245
+ /* @__PURE__ */ jsx84("code", {
23246
+ style: elementInstallCompositionIdStyle,
23247
+ children: activeElementInstallRequest.compositionId
23248
+ }),
23249
+ " ",
23250
+ "composition? This will create an Element source file and update the composition source.",
23251
+ /* @__PURE__ */ jsxs41("details", {
23252
+ style: elementInstallCodeDetailsStyle,
23253
+ children: [
23254
+ /* @__PURE__ */ jsx84("summary", {
23255
+ style: elementInstallCodeSummaryStyle,
23256
+ children: "Preview Element source"
23257
+ }),
23258
+ /* @__PURE__ */ jsx84("pre", {
23259
+ style: elementInstallCodeBlockStyle,
23260
+ children: /* @__PURE__ */ jsx84("code", {
23261
+ children: activeElementInstallRequest.element.sourceCode
23262
+ })
23263
+ })
23264
+ ]
23265
+ })
23266
+ ]
23267
+ }),
23268
+ confirmLabel: "Install",
23269
+ cancelLabel: "Cancel"
23270
+ });
23271
+ if (accepted && !canceled) {
23272
+ await insertElement({
23273
+ element: activeElementInstallRequest.element,
23274
+ compositionFile: activeElementInstallRequest.compositionFile,
23275
+ compositionId: activeElementInstallRequest.compositionId,
23276
+ dropPosition: null
23277
+ });
23278
+ }
23279
+ };
23280
+ handleInstallRequest().finally(() => {
23281
+ if (canceled) {
23282
+ return;
23283
+ }
23284
+ setInstallingElementName(null);
23285
+ setActiveElementInstallRequest(null);
23286
+ }).catch((err) => {
23287
+ setTimeout(() => {
23288
+ throw err;
23289
+ }, 0);
23290
+ });
23291
+ return () => {
23292
+ canceled = true;
23293
+ };
23294
+ }, [activeElementInstallRequest, confirm]);
23084
23295
  const onDragOver = useCallback43((event) => {
23085
23296
  if (!canDropAssets || !isFileDragEvent(event) && !isAssetDragEvent(event) && !isCompositionDragEvent(event) && !isComponentDragEvent(event) && !isElementDragEvent(event) && !isSfxDragEvent(event) && !isRemoteAssetDragEvent(event) || !isDragEventInsideCanvas(event)) {
23086
23297
  return;
@@ -26733,6 +26944,9 @@ var VisualControlsProvider = ({ children }) => {
26733
26944
  if (!env.isStudio) {
26734
26945
  return value;
26735
26946
  }
26947
+ if (!studioInteractivityEnabled) {
26948
+ return value;
26949
+ }
26736
26950
  if (!z) {
26737
26951
  return value;
26738
26952
  }
@@ -33123,7 +33337,7 @@ var DefaultInspector = ({ composition, currentDefaultProps, readOnlyStudio, setD
33123
33337
  const { handles: visualControlHandles } = useContext55(VisualControlsContext);
33124
33338
  const [defaultPropsMode, setDefaultPropsMode] = useState68("schema");
33125
33339
  const compositionId = composition?.id ?? null;
33126
- const hasVisualControls = Object.keys(visualControlHandles).length > 0;
33340
+ const hasVisualControls = studioInteractivityEnabled && Object.keys(visualControlHandles).length > 0;
33127
33341
  useEffect60(() => {
33128
33342
  setDefaultPropsMode("schema");
33129
33343
  }, [compositionId]);
@@ -48108,7 +48322,7 @@ var GlobalKeybindings = ({ readOnlyStudio }) => {
48108
48322
  commandCtrlKey: true,
48109
48323
  preventDefault: true
48110
48324
  });
48111
- const cmdIKey = process.env.ASK_AI_ENABLED ? keybindings.registerKeybinding({
48325
+ const cmdIKey = getStudioAskAIEnabled() ? keybindings.registerKeybinding({
48112
48326
  event: "keydown",
48113
48327
  key: "i",
48114
48328
  callback: () => {
@@ -48206,9 +48420,8 @@ import React208, { useCallback as useCallback166, useContext as useContext120, u
48206
48420
  import { Internals as Internals98 } from "remotion";
48207
48421
 
48208
48422
  // src/components/Timeline/MaxTimelineTracks.tsx
48209
- import { DEFAULT_TIMELINE_TRACKS } from "@remotion/studio-shared";
48210
48423
  import { jsxs as jsxs129 } from "react/jsx-runtime";
48211
- var MAX_TIMELINE_TRACKS = typeof process.env.MAX_TIMELINE_TRACKS === "undefined" || process.env.MAX_TIMELINE_TRACKS === null ? DEFAULT_TIMELINE_TRACKS : Number(process.env.MAX_TIMELINE_TRACKS);
48424
+ var MAX_TIMELINE_TRACKS = getStudioMaxTimelineTracks();
48212
48425
  var MAX_TIMELINE_TRACKS_NOTICE_HEIGHT = 24;
48213
48426
  var container40 = {
48214
48427
  height: MAX_TIMELINE_TRACKS_NOTICE_HEIGHT,
@@ -48804,7 +49017,7 @@ var TimelineDragHandler = () => {
48804
49017
  ref: sliderAreaRef,
48805
49018
  style: containerStyle9,
48806
49019
  ...{ [TIMELINE_SCRUBBER_ATTR]: true },
48807
- children: video ? /* @__PURE__ */ jsx260(TimelineDragHandlerInnerMemo, {}) : null
49020
+ children: video && studioInteractivityEnabled ? /* @__PURE__ */ jsx260(TimelineDragHandlerInnerMemo, {}) : null
48808
49021
  });
48809
49022
  };
48810
49023
  var TimelineDragHandlerInner = () => {
@@ -49871,6 +50084,7 @@ var TimelineSequenceItem = ({
49871
50084
  const nodePath = nodePathInfo?.sequenceSubscriptionKey ?? null;
49872
50085
  const { previewServerState } = useContext111(StudioServerConnectionCtx);
49873
50086
  const previewConnected = previewServerState.type === "connected";
50087
+ const previewInteractive = previewConnected && studioInteractivityEnabled;
49874
50088
  const { getIsExpanded } = useContext111(ExpandedTracksGetterContext);
49875
50089
  const { toggleTrack } = useContext111(ExpandedTracksSetterContext);
49876
50090
  const { setPropStatuses } = useContext111(Internals91.VisualModeSettersContext);
@@ -49907,7 +50121,7 @@ var TimelineSequenceItem = ({
49907
50121
  propStatusesForOverride,
49908
50122
  saveName
49909
50123
  } = useRenameSequence({
49910
- clientId: previewServerState.type === "connected" ? previewServerState.clientId : null,
50124
+ clientId: previewInteractive && previewServerState.type === "connected" ? previewServerState.clientId : null,
49911
50125
  nodePathInfo,
49912
50126
  sequence,
49913
50127
  validatedLocation
@@ -49915,22 +50129,22 @@ var TimelineSequenceItem = ({
49915
50129
  const canDeleteFromSource = Boolean(nodePath && validatedLocation?.source);
49916
50130
  const nodePathKey = useMemo170(() => nodePath ? Internals91.makeSequencePropsSubscriptionKey(nodePath) : null, [nodePath]);
49917
50131
  const parentId = sequence.parent ?? null;
49918
- const canReorderSequence = previewConnected && Boolean(nodePath && nodePathKey && validatedLocation?.source) && nodePathInfo?.numberOfSequencesWithThisNodePath === 1;
49919
- const canHandleSequenceDrag = previewConnected;
50132
+ const canReorderSequence = previewInteractive && Boolean(nodePath && nodePathKey && validatedLocation?.source) && nodePathInfo?.numberOfSequencesWithThisNodePath === 1;
50133
+ const canHandleSequenceDrag = previewInteractive;
49920
50134
  const confirm = useConfirmationDialog();
49921
- const deleteDisabled = useMemo170(() => !previewConnected || !sequence.controls || !canDeleteFromSource, [previewConnected, sequence.controls, canDeleteFromSource]);
50135
+ const deleteDisabled = useMemo170(() => !previewInteractive || !sequence.controls || !canDeleteFromSource, [previewInteractive, sequence.controls, canDeleteFromSource]);
49922
50136
  const duplicateDisabled = deleteDisabled;
49923
- const disableInteractivityDisabled = !previewConnected || !sequence.showInTimeline || !nodePath || !validatedLocation?.source;
50137
+ const disableInteractivityDisabled = !previewInteractive || !sequence.showInTimeline || !nodePath || !validatedLocation?.source;
49924
50138
  const onDuplicateSequenceFromSource = useCallback162(() => {
49925
- if (!validatedLocation?.source || !nodePathInfo) {
50139
+ if (duplicateDisabled || !validatedLocation?.source || !nodePathInfo) {
49926
50140
  return;
49927
50141
  }
49928
50142
  duplicateSequencesFromSource([nodePathInfo], confirm).catch(() => {
49929
50143
  return;
49930
50144
  });
49931
- }, [confirm, nodePathInfo, validatedLocation?.source]);
50145
+ }, [confirm, duplicateDisabled, nodePathInfo, validatedLocation?.source]);
49932
50146
  const onDeleteSequenceFromSource = useCallback162(async () => {
49933
- if (!validatedLocation?.source || !nodePath) {
50147
+ if (deleteDisabled || !validatedLocation?.source || !nodePath) {
49934
50148
  return;
49935
50149
  }
49936
50150
  if (nodePathInfo && nodePathInfo.numberOfSequencesWithThisNodePath > 1) {
@@ -49960,7 +50174,13 @@ var TimelineSequenceItem = ({
49960
50174
  } catch (err) {
49961
50175
  showNotification(err.message, 4000);
49962
50176
  }
49963
- }, [confirm, nodePath, validatedLocation?.source, nodePathInfo]);
50177
+ }, [
50178
+ confirm,
50179
+ deleteDisabled,
50180
+ nodePath,
50181
+ validatedLocation?.source,
50182
+ nodePathInfo
50183
+ ]);
49964
50184
  const onDisableSequenceInteractivity = useCallback162(() => {
49965
50185
  if (disableInteractivityDisabled || !nodePath || !validatedLocation?.source || previewServerState.type !== "connected") {
49966
50186
  return;
@@ -50195,8 +50415,8 @@ var TimelineSequenceItem = ({
50195
50415
  ...effectDropHighlight
50196
50416
  } : inner2;
50197
50417
  }, [effectDropHovered, inner2]);
50198
- const hasExpandableContent = Boolean(sequence.controls) || sequence.effects.length > 0;
50199
- const canToggleVisibility = previewConnected && Boolean(sequence.controls) && nodePath !== null && validatedLocation !== null && codeHiddenStatus !== undefined && codeHiddenStatus !== null && codeHiddenStatus.status === "static";
50418
+ const hasExpandableContent = studioInteractivityEnabled && (Boolean(sequence.controls) || sequence.effects.length > 0);
50419
+ const canToggleVisibility = previewInteractive && Boolean(sequence.controls) && nodePath !== null && validatedLocation !== null && codeHiddenStatus !== undefined && codeHiddenStatus !== null && codeHiddenStatus.status === "static";
50200
50420
  const onSequenceDoubleClick = useCallback162((e) => {
50201
50421
  if (isTimelineSelectionModifierEvent(e)) {
50202
50422
  e.stopPropagation();
@@ -50218,7 +50438,7 @@ var TimelineSequenceItem = ({
50218
50438
  await saveName(name);
50219
50439
  }, [saveName]);
50220
50440
  React195.useEffect(() => {
50221
- if (!canRenameSelectedSequence || !process.env.KEYBOARD_SHORTCUTS_ENABLED) {
50441
+ if (!canRenameSelectedSequence || !getStudioKeyboardShortcutsEnabled()) {
50222
50442
  setIsRenaming(false);
50223
50443
  return;
50224
50444
  }
@@ -50249,7 +50469,7 @@ var TimelineSequenceItem = ({
50249
50469
  setIsRenaming(true);
50250
50470
  }, [canRenameThisSequence]);
50251
50471
  const freezeFrameMenuItem = useSequenceFreezeFrameMenuItem({
50252
- clientId: previewServerState.type === "connected" ? previewServerState.clientId : null,
50472
+ clientId: previewInteractive && previewServerState.type === "connected" ? previewServerState.clientId : null,
50253
50473
  nodePath,
50254
50474
  propStatusesForOverride,
50255
50475
  sequence,
@@ -50258,7 +50478,7 @@ var TimelineSequenceItem = ({
50258
50478
  timelinePosition,
50259
50479
  validatedSource: validatedLocation?.source ?? null
50260
50480
  });
50261
- const canAddEffect = nodePathInfo?.supportsEffects === true && previewServerState.type === "connected" && Boolean(validatedLocation?.source);
50481
+ const canAddEffect = nodePathInfo?.supportsEffects === true && previewInteractive && Boolean(validatedLocation?.source);
50262
50482
  const onAddEffect = useCallback162(() => {
50263
50483
  if (!canAddEffect || previewServerState.type !== "connected" || !nodePath || !validatedLocation?.source) {
50264
50484
  return;
@@ -50287,7 +50507,7 @@ var TimelineSequenceItem = ({
50287
50507
  disableInteractivityDisabled,
50288
50508
  duplicateDisabled,
50289
50509
  fileLocation,
50290
- includeSourceEditItems: true,
50510
+ includeSourceEditItems: studioInteractivityEnabled,
50291
50511
  onDeleteSequenceFromSource,
50292
50512
  onDisableSequenceInteractivity,
50293
50513
  onDuplicateSequenceFromSource,
@@ -50295,7 +50515,7 @@ var TimelineSequenceItem = ({
50295
50515
  originalLocation,
50296
50516
  selectAsset,
50297
50517
  sequence,
50298
- sourceActions: [
50518
+ sourceActions: studioInteractivityEnabled ? [
50299
50519
  ...nodePathInfo?.supportsEffects ? [
50300
50520
  {
50301
50521
  type: "item",
@@ -50329,7 +50549,7 @@ var TimelineSequenceItem = ({
50329
50549
  value: "rename-sequence"
50330
50550
  },
50331
50551
  ...freezeFrameMenuItem ? [freezeFrameMenuItem] : []
50332
- ]
50552
+ ] : []
50333
50553
  });
50334
50554
  }, [
50335
50555
  assetLinkInfo,
@@ -50353,7 +50573,7 @@ var TimelineSequenceItem = ({
50353
50573
  selectAsset,
50354
50574
  sequence
50355
50575
  ]);
50356
- const canDropEffect = previewServerState.type === "connected" && nodePath !== null && validatedLocation !== null && sequence.controls?.supportsEffects === true;
50576
+ const canDropEffect = previewInteractive && nodePath !== null && validatedLocation !== null && sequence.controls?.supportsEffects === true;
50357
50577
  const sequenceReorderLineStyle = useMemo170(() => {
50358
50578
  if (!sequenceDropIndicator) {
50359
50579
  return null;
@@ -50409,7 +50629,7 @@ var TimelineSequenceItem = ({
50409
50629
  onInvoked: onToggleVisibility
50410
50630
  }) : /* @__PURE__ */ jsx268(TimelineLayerEyeSpacer, {}),
50411
50631
  arrow: hasExpandableContent && nodePathInfo !== null ? /* @__PURE__ */ jsx268(TimelineSequenceExpandArrow, {
50412
- disabled: !previewConnected,
50632
+ disabled: !previewInteractive,
50413
50633
  isExpanded,
50414
50634
  nodePathInfo,
50415
50635
  onToggleExpand,
@@ -50479,7 +50699,7 @@ var TimelineSequenceItem = ({
50479
50699
  onOpen: selectable ? onSelect : null,
50480
50700
  children: draggableTrackRow
50481
50701
  }) : draggableTrackRow,
50482
- previewConnected && isExpanded && hasExpandableContent && nodePathInfo && validatedLocation ? /* @__PURE__ */ jsx268(TimelineExpandedSection, {
50702
+ previewConnected && studioInteractivityEnabled && isExpanded && hasExpandableContent && nodePathInfo && validatedLocation ? /* @__PURE__ */ jsx268(TimelineExpandedSection, {
50483
50703
  sequence,
50484
50704
  validatedLocation,
50485
50705
  nodePathInfo,
@@ -53228,11 +53448,12 @@ var TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffset
53228
53448
  const propStatusesForOverride = useMemo176(() => {
53229
53449
  return nodePath ? Internals97.getPropStatusesCtx(propStatuses, nodePath) : undefined;
53230
53450
  }, [propStatuses, nodePath]);
53231
- const durationCanUpdate = Boolean(propStatusesForOverride?.durationInFrames?.status === "static");
53232
- const fromCanUpdate = Boolean(propStatusesForOverride?.from?.status === "static");
53233
- const trimBeforeCanUpdate = Boolean(propStatusesForOverride?.trimBefore?.status === "static");
53451
+ const durationCanUpdate = Boolean(studioInteractivityEnabled && propStatusesForOverride?.durationInFrames?.status === "static");
53452
+ const fromCanUpdate = Boolean(studioInteractivityEnabled && propStatusesForOverride?.from?.status === "static");
53453
+ const trimBeforeCanUpdate = Boolean(studioInteractivityEnabled && propStatusesForOverride?.trimBefore?.status === "static");
53234
53454
  const { previewServerState } = useContext118(StudioServerConnectionCtx);
53235
53455
  const previewConnected = previewServerState.type === "connected";
53456
+ const previewInteractive = previewConnected && studioInteractivityEnabled;
53236
53457
  const { setPropStatuses } = useContext118(Internals97.VisualModeSettersContext);
53237
53458
  const timelinePosition = Internals97.Timeline.useTimelinePosition();
53238
53459
  const selectAsset = useSelectAsset();
@@ -53252,9 +53473,9 @@ var TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffset
53252
53473
  });
53253
53474
  }, [canOpenInEditor, originalLocation]);
53254
53475
  const canDeleteFromSource = Boolean(nodePath && validatedLocation?.source);
53255
- const deleteDisabled = !previewConnected || !s.controls || !canDeleteFromSource;
53476
+ const deleteDisabled = !previewInteractive || !s.controls || !canDeleteFromSource;
53256
53477
  const duplicateDisabled = deleteDisabled;
53257
- const disableInteractivityDisabled = !previewConnected || !s.showInTimeline || !nodePath || !validatedLocation?.source;
53478
+ const disableInteractivityDisabled = !previewInteractive || !s.showInTimeline || !nodePath || !validatedLocation?.source;
53258
53479
  const mediaSrc = s.type === "audio" || s.type === "video" || s.type === "image" ? s.src : null;
53259
53480
  const assetLinkInfo = useMemo176(() => mediaSrc ? getTimelineAssetLinkInfo(mediaSrc) : null, [mediaSrc]);
53260
53481
  const onDuplicateSequenceFromSource = useCallback165(() => {
@@ -53321,7 +53542,7 @@ var TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffset
53321
53542
  validatedLocation?.source
53322
53543
  ]);
53323
53544
  const freezeFrameMenuItem = useSequenceFreezeFrameMenuItem({
53324
- clientId: previewServerState.type === "connected" ? previewServerState.clientId : null,
53545
+ clientId: previewInteractive && previewServerState.type === "connected" ? previewServerState.clientId : null,
53325
53546
  nodePath,
53326
53547
  propStatusesForOverride,
53327
53548
  sequence: s,
@@ -53341,7 +53562,7 @@ var TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffset
53341
53562
  disableInteractivityDisabled,
53342
53563
  duplicateDisabled,
53343
53564
  fileLocation,
53344
- includeSourceEditItems: true,
53565
+ includeSourceEditItems: studioInteractivityEnabled,
53345
53566
  onDeleteSequenceFromSource,
53346
53567
  onDisableSequenceInteractivity,
53347
53568
  onDuplicateSequenceFromSource,
@@ -53349,7 +53570,7 @@ var TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffset
53349
53570
  originalLocation,
53350
53571
  selectAsset,
53351
53572
  sequence: s,
53352
- sourceActions: freezeFrameMenuItem ? [freezeFrameMenuItem] : []
53573
+ sourceActions: studioInteractivityEnabled && freezeFrameMenuItem ? [freezeFrameMenuItem] : []
53353
53574
  });
53354
53575
  }, [
53355
53576
  assetLinkInfo,
@@ -53576,6 +53797,7 @@ var TimelineContextMenuArea = ({ children }) => {
53576
53797
  const [isAddingAsset, setIsAddingAsset] = useState100(false);
53577
53798
  const { previewServerState } = useContext120(StudioServerConnectionCtx);
53578
53799
  const previewConnected = previewServerState.type === "connected";
53800
+ const previewInteractive = previewConnected && studioInteractivityEnabled;
53579
53801
  const currentCompositionId = canvasContent?.type === "composition" ? canvasContent.compositionId : null;
53580
53802
  const currentComposition = useMemo179(() => {
53581
53803
  if (currentCompositionId === null) {
@@ -53589,8 +53811,8 @@ var TimelineContextMenuArea = ({ children }) => {
53589
53811
  compositionFile,
53590
53812
  compositionId: currentCompositionId
53591
53813
  });
53592
- const canInsertSolid = previewConnected && compositionComponentInfo?.canAddSequence === true && currentCompositionId !== null && compositionFile !== null && videoConfig !== null && !isAddingSolid;
53593
- const canInsertAsset = previewConnected && !window.remotion_isReadOnlyStudio && compositionComponentInfo?.canAddSequence === true && currentCompositionId !== null && compositionFile !== null && !isAddingAsset;
53814
+ const canInsertSolid = previewInteractive && compositionComponentInfo?.canAddSequence === true && currentCompositionId !== null && compositionFile !== null && videoConfig !== null && !isAddingSolid;
53815
+ const canInsertAsset = previewInteractive && !window.remotion_isReadOnlyStudio && compositionComponentInfo?.canAddSequence === true && currentCompositionId !== null && compositionFile !== null && !isAddingAsset;
53594
53816
  const insertSolid = useCallback166(async () => {
53595
53817
  if (!canInsertSolid || currentCompositionId === null || compositionFile === null || videoConfig === null) {
53596
53818
  return;
@@ -53682,6 +53904,7 @@ var TimelineInner = () => {
53682
53904
  const { overrideIdToNodePathMappings } = useContext120(Internals98.OverrideIdsToNodePathsGettersContext);
53683
53905
  const { previewServerState } = useContext120(StudioServerConnectionCtx);
53684
53906
  const previewConnected = previewServerState.type === "connected";
53907
+ const previewInteractive = previewConnected && studioInteractivityEnabled;
53685
53908
  const videoConfigIsNull = videoConfig === null;
53686
53909
  const timeline = useMemo179(() => {
53687
53910
  if (videoConfigIsNull) {
@@ -53703,7 +53926,7 @@ var TimelineInner = () => {
53703
53926
  return /* @__PURE__ */ jsxs147(TimelineContextMenuArea, {
53704
53927
  children: [
53705
53928
  sequences.map((sequence) => {
53706
- if (!shouldSubscribeToSequenceProps(sequence, previewConnected)) {
53929
+ if (!shouldSubscribeToSequenceProps(sequence, previewInteractive)) {
53707
53930
  return null;
53708
53931
  }
53709
53932
  return /* @__PURE__ */ jsx284(SubscribeToNodePaths, {
@@ -53714,15 +53937,15 @@ var TimelineInner = () => {
53714
53937
  effects: sequence.effects
53715
53938
  }, sequence.id);
53716
53939
  }),
53717
- /* @__PURE__ */ jsx284(SequencePropsObserver, {}),
53940
+ studioInteractivityEnabled ? /* @__PURE__ */ jsx284(SequencePropsObserver, {}) : null,
53718
53941
  /* @__PURE__ */ jsx284(TimelineKeyframeTracksProvider, {
53719
53942
  tracks: filtered,
53720
53943
  children: /* @__PURE__ */ jsxs147(TimelineSelectableItemsProvider, {
53721
53944
  timeline: shown,
53722
53945
  children: [
53723
- /* @__PURE__ */ jsx284(TimelineSelectAllKeybindings, {
53946
+ studioInteractivityEnabled ? /* @__PURE__ */ jsx284(TimelineSelectAllKeybindings, {
53724
53947
  timeline: shown
53725
- }),
53948
+ }) : null,
53726
53949
  /* @__PURE__ */ jsx284(TimelineHeightContainer, {
53727
53950
  shown,
53728
53951
  hasBeenCut,
@@ -53762,7 +53985,7 @@ var TimelineInner = () => {
53762
53985
  /* @__PURE__ */ jsx284(TimelineInOutPointer, {}),
53763
53986
  /* @__PURE__ */ jsx284(TimelineTimeIndicators, {}),
53764
53987
  /* @__PURE__ */ jsx284(TimelineDragHandler, {}),
53765
- /* @__PURE__ */ jsx284(TimelineInOutDragHandler, {}),
53988
+ studioInteractivityEnabled ? /* @__PURE__ */ jsx284(TimelineInOutDragHandler, {}) : null,
53766
53989
  /* @__PURE__ */ jsx284(TimelineSlider, {})
53767
53990
  ]
53768
53991
  })
@@ -57488,7 +57711,7 @@ var KeyboardShortcutsExplainer = () => {
57488
57711
  })
57489
57712
  ]
57490
57713
  }),
57491
- process.env.ASK_AI_ENABLED && /* @__PURE__ */ jsxs165(Fragment57, {
57714
+ getStudioAskAIEnabled() && /* @__PURE__ */ jsxs165(Fragment57, {
57492
57715
  children: [
57493
57716
  /* @__PURE__ */ jsx306("br", {}),
57494
57717
  /* @__PURE__ */ jsx306("div", {
@@ -66067,7 +66290,7 @@ var Modals = ({ readOnlyStudio }) => {
66067
66290
  modalContextType && modalContextType.type === "confirmation-dialog" && /* @__PURE__ */ jsx362(ConfirmationDialog, {
66068
66291
  state: modalContextType
66069
66292
  }),
66070
- process.env.ASK_AI_ENABLED && /* @__PURE__ */ jsx362(AskAiModal, {})
66293
+ getStudioAskAIEnabled() && /* @__PURE__ */ jsx362(AskAiModal, {})
66071
66294
  ]
66072
66295
  });
66073
66296
  };
@@ -66155,8 +66378,7 @@ var background = {
66155
66378
  flexDirection: "column",
66156
66379
  position: "absolute"
66157
66380
  };
66158
- var DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS = 300;
66159
- var BUFFER_STATE_DELAY_IN_MILLISECONDS = typeof process.env.BUFFER_STATE_DELAY_IN_MILLISECONDS === "undefined" || process.env.BUFFER_STATE_DELAY_IN_MILLISECONDS === null ? DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS : Number(process.env.BUFFER_STATE_DELAY_IN_MILLISECONDS);
66381
+ var BUFFER_STATE_DELAY_IN_MILLISECONDS = getStudioBufferStateDelayInMilliseconds();
66160
66382
  var Editor = ({ Root, readOnlyStudio }) => {
66161
66383
  const [drawElement, setDrawElement] = useState126(null);
66162
66384
  const size3 = PlayerInternals23.useElementSize(drawElement, {