hyperframes 0.8.64 → 0.8.66

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.
@@ -3656,15 +3656,28 @@ function effectiveThumbnailMode(preferredMode, policy = studioThumbnailRuntimePo
3656
3656
  }
3657
3657
 
3658
3658
  // src/player/store/thumbnailSlice.ts
3659
+ var EVERY_COMPOSITION = "*";
3660
+ function revisionKey(path) {
3661
+ return (path.split(/[?#]/)[0] ?? "").replace(/\\/g, "/").replace(/^\.?\//, "");
3662
+ }
3663
+ function thumbnailRevisionOf(revisions, compositionPath) {
3664
+ return (revisions[EVERY_COMPOSITION] ?? 0) + (revisions[revisionKey(compositionPath)] ?? 0);
3665
+ }
3659
3666
  function createThumbnailSlice(set) {
3660
3667
  return {
3661
3668
  thumbnailMode: defaultThumbnailMode(readStudioUiPreferences().thumbnailMode),
3662
- thumbnailContentRevision: 0,
3669
+ thumbnailRevisions: {},
3663
3670
  setThumbnailMode: (mode) => {
3664
3671
  writeStudioUiPreferences({ thumbnailMode: mode });
3665
3672
  set({ thumbnailMode: mode });
3666
3673
  },
3667
- bumpThumbnailContentRevision: () => set((state) => ({ thumbnailContentRevision: state.thumbnailContentRevision + 1 }))
3674
+ bumpThumbnailRevisions: (compositions) => set(({ thumbnailRevisions }) => {
3675
+ const next = { ...thumbnailRevisions };
3676
+ for (const path of compositions?.map(revisionKey) ?? [EVERY_COMPOSITION]) {
3677
+ next[path] = (next[path] ?? 0) + 1;
3678
+ }
3679
+ return { thumbnailRevisions: next };
3680
+ })
3668
3681
  };
3669
3682
  }
3670
3683
 
@@ -4765,7 +4778,7 @@ import {
4765
4778
  } from "react";
4766
4779
 
4767
4780
  // src/player/components/useTimelineProviderState.tsx
4768
- import { useRef as useRef31, useMemo as useMemo22, useCallback as useCallback21, useState as useState20 } from "react";
4781
+ import { useRef as useRef31, useMemo as useMemo22, useCallback as useCallback21, useState as useState21 } from "react";
4769
4782
 
4770
4783
  // src/hooks/useMusicBeatAnalysis.ts
4771
4784
  import { useEffect as useEffect10, useMemo as useMemo4, useRef as useRef10 } from "react";
@@ -6647,6 +6660,20 @@ function deriveTimelineTransitionSeams(elements) {
6647
6660
  }
6648
6661
  return seams;
6649
6662
  }
6663
+ function deriveTimelineTransitionSeamsByTrack(elements) {
6664
+ const tracks = /* @__PURE__ */ new Map();
6665
+ for (const element of elements) {
6666
+ const track2 = tracks.get(element.track);
6667
+ if (track2) track2.push(element);
6668
+ else tracks.set(element.track, [element]);
6669
+ }
6670
+ const byTrack = /* @__PURE__ */ new Map();
6671
+ for (const [track2, trackElements] of tracks) {
6672
+ const seams = deriveTimelineTransitionSeams(trackElements);
6673
+ if (seams.length > 0) byTrack.set(track2, seams);
6674
+ }
6675
+ return byTrack;
6676
+ }
6650
6677
 
6651
6678
  // src/player/components/timelineZones.ts
6652
6679
  function classifyZone(el) {
@@ -8673,9 +8700,6 @@ function resolveResizingElementIds(resizingClip) {
8673
8700
  if (resizingClip) return [resizingClip.element.key ?? resizingClip.element.id];
8674
8701
  return void 0;
8675
8702
  }
8676
- function resolveRenderClipContent(rowVirtualizationActive, isScrolling, renderClipContent) {
8677
- return rowVirtualizationActive && isScrolling ? void 0 : renderClipContent;
8678
- }
8679
8703
  function shouldIgnoreTimelinePointerDown(target) {
8680
8704
  return target instanceof Element && target.closest("button, input, select, a") !== null;
8681
8705
  }
@@ -13987,12 +14011,48 @@ function useTimelineScrollViewport(scrollRef, resyncShortcutHintOn) {
13987
14011
  return { viewport, showShortcutHint, setScrollRef, syncScrollViewport };
13988
14012
  }
13989
14013
 
14014
+ // src/player/components/timelineClipChildren.tsx
14015
+ import { useState as useState17 } from "react";
14016
+ import { Fragment as Fragment7, jsx as jsx38, jsxs as jsxs26 } from "react/jsx-runtime";
14017
+ function resolveClipRenderContext(element, visibleTimeRange, interactive) {
14018
+ if (interactive) return { priority: "interaction", rich: false };
14019
+ const visible = element.start < visibleTimeRange.end && element.start + element.duration > visibleTimeRange.start;
14020
+ return { priority: visible ? "visible" : "overscan", rich: false };
14021
+ }
14022
+ function ClipLintDot({ element }) {
14023
+ const lint = usePlayerStore((s) => s.lintFindingsByElement.get(element.key ?? element.id));
14024
+ if (!lint || lint.count === 0) return null;
14025
+ return /* @__PURE__ */ jsx38(
14026
+ "span",
14027
+ {
14028
+ className: "absolute w-1.5 h-1.5 rounded-full bg-amber-400",
14029
+ style: { top: 7, right: 7 },
14030
+ title: lint.messages.join("\n")
14031
+ }
14032
+ );
14033
+ }
14034
+ function ClipContentOnceShown({ hold, children }) {
14035
+ const [shown2, setShown] = useState17(!hold);
14036
+ if (!shown2 && !hold) setShown(true);
14037
+ return shown2 ? children : null;
14038
+ }
14039
+ function renderClipChildren(element, clipStyle, renderClipContent, renderClipOverlay, context = { priority: "visible", rich: false }) {
14040
+ return /* @__PURE__ */ jsxs26(Fragment7, { children: [
14041
+ renderClipOverlay?.(element),
14042
+ !renderClipContent && /* @__PURE__ */ jsx38(ClipLintDot, { element }),
14043
+ renderClipContent && // borderRadius: inherit — the clip itself is overflow-visible (keyframe
14044
+ // diamonds hang outside its bounds), so the thumbnail layer must clip
14045
+ // itself to the clip's rounded corners or sharp corners poke out.
14046
+ /* @__PURE__ */ jsx38("div", { className: "absolute inset-0 overflow-hidden", style: { borderRadius: "inherit" }, children: renderClipContent(element, clipStyle, context) })
14047
+ ] });
14048
+ }
14049
+
13990
14050
  // src/player/components/useResolvedTimelineEditCallbacks.ts
13991
14051
  import { useMemo as useMemo12 } from "react";
13992
14052
 
13993
14053
  // src/contexts/TimelineEditContext.tsx
13994
14054
  import { useContext as useContext6, useMemo as useMemo11 } from "react";
13995
- import { jsx as jsx38 } from "react/jsx-runtime";
14055
+ import { jsx as jsx39 } from "react/jsx-runtime";
13996
14056
  var TimelineEditContext = createStableContext(
13997
14057
  "TimelineEditContext",
13998
14058
  null
@@ -14039,7 +14099,7 @@ function TimelineEditProvider({
14039
14099
  value.onTogglePropertyGroupKeyframe
14040
14100
  ]
14041
14101
  );
14042
- return /* @__PURE__ */ jsx38(TimelineEditContext.Provider, { value: memoized, children });
14102
+ return /* @__PURE__ */ jsx39(TimelineEditContext.Provider, { value: memoized, children });
14043
14103
  }
14044
14104
 
14045
14105
  // src/player/components/useResolvedTimelineEditCallbacks.ts
@@ -14573,8 +14633,8 @@ function useTimelineGapHighlights(input) {
14573
14633
  }
14574
14634
 
14575
14635
  // src/player/components/TimelineRazorInteraction.tsx
14576
- import { useCallback as useCallback16, useState as useState17 } from "react";
14577
- import { jsx as jsx39 } from "react/jsx-runtime";
14636
+ import { useCallback as useCallback16, useState as useState18 } from "react";
14637
+ import { jsx as jsx40 } from "react/jsx-runtime";
14578
14638
  function useTimelineRazorInteraction({
14579
14639
  active,
14580
14640
  scrollRef,
@@ -14582,7 +14642,7 @@ function useTimelineRazorInteraction({
14582
14642
  pixelsPerSecond,
14583
14643
  onSplitAll
14584
14644
  }) {
14585
- const [razorGuideX, setRazorGuideX] = useState17(null);
14645
+ const [razorGuideX, setRazorGuideX] = useState18(null);
14586
14646
  const updateRazorGuide = useCallback16(
14587
14647
  (event) => {
14588
14648
  const scroll = scrollRef.current;
@@ -14612,7 +14672,7 @@ function useTimelineRazorInteraction({
14612
14672
  return { razorGuideX, updateRazorGuide, clearRazorGuide, splitAllAtPointer };
14613
14673
  }
14614
14674
  function TimelineRazorGuideOverlay({ x }) {
14615
- return /* @__PURE__ */ jsx39(
14675
+ return /* @__PURE__ */ jsx40(
14616
14676
  "div",
14617
14677
  {
14618
14678
  className: "absolute top-0 bottom-0 pointer-events-none z-10",
@@ -14749,9 +14809,9 @@ function getTimelinePreviewElement(element, resizingClip) {
14749
14809
  }
14750
14810
 
14751
14811
  // src/player/components/useTimelineShiftModifier.ts
14752
- import { useState as useState18 } from "react";
14812
+ import { useState as useState19 } from "react";
14753
14813
  function useTimelineShiftModifier() {
14754
- const [shiftHeld, setShiftHeld] = useState18(false);
14814
+ const [shiftHeld, setShiftHeld] = useState19(false);
14755
14815
  useMountEffect(() => {
14756
14816
  const handleKey = (event) => event.key === "Shift" && setShiftHeld(event.type === "keydown");
14757
14817
  const handleBlur = () => setShiftHeld(false);
@@ -15658,7 +15718,7 @@ import {
15658
15718
  useLayoutEffect as useLayoutEffect4,
15659
15719
  useMemo as useMemo21,
15660
15720
  useRef as useRef30,
15661
- useState as useState19
15721
+ useState as useState20
15662
15722
  } from "react";
15663
15723
 
15664
15724
  // src/player/components/timelineFocusIdentity.ts
@@ -15791,7 +15851,7 @@ function useTimelineRowVirtualization({
15791
15851
  syncScrollViewport
15792
15852
  }) {
15793
15853
  const enabled = STUDIO_TIMELINE_ROW_VIRTUALIZATION_ENABLED;
15794
- const [domFocusedRowKey, setDomFocusedRowKey] = useState19();
15854
+ const [domFocusedRowKey, setDomFocusedRowKey] = useState20();
15795
15855
  const onTimelineFocus = useCallback20((event) => {
15796
15856
  setDomFocusedRowKey(getFocusedTimelineRowKey(event.target));
15797
15857
  }, []);
@@ -15924,7 +15984,7 @@ function useTimelineLogicalFocus(input) {
15924
15984
  }
15925
15985
 
15926
15986
  // src/player/components/useTimelineProviderState.tsx
15927
- import { jsx as jsx40 } from "react/jsx-runtime";
15987
+ import { jsx as jsx41 } from "react/jsx-runtime";
15928
15988
  function useTimelineProviderState({
15929
15989
  onSeek,
15930
15990
  onDrillDown,
@@ -15998,12 +16058,12 @@ function useTimelineProviderState({
15998
16058
  const containerRef = useRef31(null);
15999
16059
  const scrollRef = useRef31(null);
16000
16060
  const activeTool = usePlayerStore((s) => s.activeTool);
16001
- const [hoveredClip, setHoveredClip] = useState20(null);
16061
+ const [hoveredClip, setHoveredClip] = useState21(null);
16002
16062
  const isDragging = useRef31(false);
16003
16063
  const shiftHeld = useTimelineShiftModifier();
16004
- const [showPopover, setShowPopover] = useState20(false);
16005
- const [kfContextMenu, setKfContextMenu] = useState20(null);
16006
- const [clipContextMenu, setClipContextMenu] = useState20(null);
16064
+ const [showPopover, setShowPopover] = useState21(false);
16065
+ const [kfContextMenu, setKfContextMenu] = useState21(null);
16066
+ const [clipContextMenu, setClipContextMenu] = useState21(null);
16007
16067
  const setContainerRef = useCallback21((el) => {
16008
16068
  containerRef.current = el;
16009
16069
  }, []);
@@ -16377,10 +16437,10 @@ function useTimelineProviderState({
16377
16437
  onRazorSplit: editContext.onRazorSplit,
16378
16438
  onRazorSplitAll: editContext.onRazorSplitAll
16379
16439
  };
16380
- const timelineRenderClipContent = resolveRenderClipContent(
16381
- timelineFocus.rowVirtualizationActive,
16382
- viewport.isScrolling,
16383
- renderClipContent
16440
+ const holdNewClipContent = timelineFocus.rowVirtualizationActive && viewport.isScrolling;
16441
+ const timelineRenderClipContent = useMemo22(
16442
+ () => renderClipContent && ((element, style, context) => /* @__PURE__ */ jsx41(ClipContentOnceShown, { hold: holdNewClipContent, children: renderClipContent(element, style, context) })),
16443
+ [holdNewClipContent, renderClipContent]
16384
16444
  );
16385
16445
  const timelineMeta = buildTimelineMeta({
16386
16446
  emptyState: {
@@ -16432,7 +16492,7 @@ function useTimelineProviderState({
16432
16492
  },
16433
16493
  elementCount: timelineElements.length,
16434
16494
  labelColumnWidth: LABEL_COL_W,
16435
- razorGuide: activeTool === "razor" && razorGuideX !== null ? /* @__PURE__ */ jsx40(TimelineRazorGuideOverlay, { x: razorGuideX }) : null
16495
+ razorGuide: activeTool === "razor" && razorGuideX !== null ? /* @__PURE__ */ jsx41(TimelineRazorGuideOverlay, { x: razorGuideX }) : null
16436
16496
  });
16437
16497
  const contextValue = {
16438
16498
  state: {
@@ -16455,18 +16515,18 @@ function useTimelineProviderState({
16455
16515
  }
16456
16516
 
16457
16517
  // src/player/components/TimelineProvider.tsx
16458
- import { jsx as jsx41 } from "react/jsx-runtime";
16518
+ import { jsx as jsx42 } from "react/jsx-runtime";
16459
16519
  var TimelineContext = createContext3(null);
16460
16520
  function TimelineProvider({ children, ...props }) {
16461
16521
  const editContext = useTimelineEditContextValue();
16462
16522
  if (!editContext) {
16463
- return /* @__PURE__ */ jsx41(TimelineEditProvider, { value: props, children: /* @__PURE__ */ jsx41(TimelineProviderState, { ...props, children }) });
16523
+ return /* @__PURE__ */ jsx42(TimelineEditProvider, { value: props, children: /* @__PURE__ */ jsx42(TimelineProviderState, { ...props, children }) });
16464
16524
  }
16465
- return /* @__PURE__ */ jsx41(TimelineProviderState, { ...props, children });
16525
+ return /* @__PURE__ */ jsx42(TimelineProviderState, { ...props, children });
16466
16526
  }
16467
16527
  function TimelineProviderState({ children, ...props }) {
16468
16528
  const value = useTimelineProviderState(props);
16469
- return /* @__PURE__ */ jsx41(TimelineContext.Provider, { value, children });
16529
+ return /* @__PURE__ */ jsx42(TimelineContext.Provider, { value, children });
16470
16530
  }
16471
16531
  function useTimelineContext() {
16472
16532
  const value = useTimelineContextOptional();
@@ -16482,7 +16542,7 @@ import { memo as memo13 } from "react";
16482
16542
 
16483
16543
  // src/player/components/TimelineRuler.tsx
16484
16544
  import { memo as memo9 } from "react";
16485
- import { Fragment as Fragment7, jsx as jsx42, jsxs as jsxs26 } from "react/jsx-runtime";
16545
+ import { Fragment as Fragment8, jsx as jsx43, jsxs as jsxs27 } from "react/jsx-runtime";
16486
16546
  var TimelineRuler = memo9(function TimelineRuler2({
16487
16547
  major,
16488
16548
  minor,
@@ -16502,8 +16562,8 @@ var TimelineRuler = memo9(function TimelineRuler2({
16502
16562
  const beatEntries = getTimelineBeatEntries(beatTimes, beatStrengths, renderTimeRange);
16503
16563
  const avgBeatInterval = beatTimes.length > 1 ? (beatTimes[beatTimes.length - 1] - beatTimes[0]) / (beatTimes.length - 1) : null;
16504
16564
  const showBeats = avgBeatInterval !== null && avgBeatInterval * pps >= 5;
16505
- return /* @__PURE__ */ jsxs26(Fragment7, { children: [
16506
- /* @__PURE__ */ jsx42(
16565
+ return /* @__PURE__ */ jsxs27(Fragment8, { children: [
16566
+ /* @__PURE__ */ jsx43(
16507
16567
  "svg",
16508
16568
  {
16509
16569
  className: "absolute pointer-events-none",
@@ -16513,7 +16573,7 @@ var TimelineRuler = memo9(function TimelineRuler2({
16513
16573
  const x = t * pps;
16514
16574
  const strength = Math.pow(Math.min(1, beatStrength ?? 0.5), 2.2);
16515
16575
  const opacity = 0.08 + strength * 0.62;
16516
- return /* @__PURE__ */ jsx42(
16576
+ return /* @__PURE__ */ jsx43(
16517
16577
  "line",
16518
16578
  {
16519
16579
  "data-timeline-grid-cell": "beat",
@@ -16530,13 +16590,13 @@ var TimelineRuler = memo9(function TimelineRuler2({
16530
16590
  })
16531
16591
  }
16532
16592
  ),
16533
- /* @__PURE__ */ jsxs26(
16593
+ /* @__PURE__ */ jsxs27(
16534
16594
  "div",
16535
16595
  {
16536
16596
  className: "sticky top-0 flex",
16537
16597
  style: { height: RULER_H, width: contentOrigin + trackContentWidth, zIndex: 70 },
16538
16598
  children: [
16539
- /* @__PURE__ */ jsx42(
16599
+ /* @__PURE__ */ jsx43(
16540
16600
  "div",
16541
16601
  {
16542
16602
  className: "sticky left-0 z-12 shrink-0",
@@ -16547,7 +16607,7 @@ var TimelineRuler = memo9(function TimelineRuler2({
16547
16607
  }
16548
16608
  }
16549
16609
  ),
16550
- /* @__PURE__ */ jsxs26(
16610
+ /* @__PURE__ */ jsxs27(
16551
16611
  "div",
16552
16612
  {
16553
16613
  className: "relative overflow-hidden",
@@ -16559,24 +16619,24 @@ var TimelineRuler = memo9(function TimelineRuler2({
16559
16619
  background: theme.shellBackground
16560
16620
  },
16561
16621
  children: [
16562
- minor.map((t) => /* @__PURE__ */ jsx42(
16622
+ minor.map((t) => /* @__PURE__ */ jsx43(
16563
16623
  "div",
16564
16624
  {
16565
16625
  "data-timeline-grid-cell": "minor",
16566
16626
  className: "absolute bottom-0",
16567
16627
  style: { left: t * pps - 0.5 },
16568
- children: /* @__PURE__ */ jsx42("div", { className: "w-px h-2", style: { background: theme.tickMinor } })
16628
+ children: /* @__PURE__ */ jsx43("div", { className: "w-px h-2", style: { background: theme.tickMinor } })
16569
16629
  },
16570
16630
  `m-${t}`
16571
16631
  )),
16572
- major.map((t) => /* @__PURE__ */ jsxs26(
16632
+ major.map((t) => /* @__PURE__ */ jsxs27(
16573
16633
  "div",
16574
16634
  {
16575
16635
  "data-timeline-grid-cell": "major",
16576
16636
  className: "absolute top-0",
16577
16637
  style: { left: t * pps - 0.5 },
16578
16638
  children: [
16579
- /* @__PURE__ */ jsx42(
16639
+ /* @__PURE__ */ jsx43(
16580
16640
  "span",
16581
16641
  {
16582
16642
  className: "absolute font-mono tabular-nums leading-none whitespace-nowrap",
@@ -16589,7 +16649,7 @@ var TimelineRuler = memo9(function TimelineRuler2({
16589
16649
  children: timeDisplayMode === "frame" ? secondsToFrame(t) : formatTimelineTickLabel(t, effectiveDuration, majorTickInterval)
16590
16650
  }
16591
16651
  ),
16592
- /* @__PURE__ */ jsx42("div", { className: "w-px", style: { height: RULER_H, background: theme.tickMajor } })
16652
+ /* @__PURE__ */ jsx43("div", { className: "w-px", style: { height: RULER_H, background: theme.tickMajor } })
16593
16653
  ]
16594
16654
  },
16595
16655
  `M-${t}`
@@ -16604,11 +16664,11 @@ var TimelineRuler = memo9(function TimelineRuler2({
16604
16664
  });
16605
16665
 
16606
16666
  // src/player/components/TimelineRulerPart.tsx
16607
- import { jsx as jsx43 } from "react/jsx-runtime";
16667
+ import { jsx as jsx44 } from "react/jsx-runtime";
16608
16668
  function TimelineRulerPart() {
16609
16669
  const { state } = useTimelineContext();
16610
16670
  const props = state.canvas;
16611
- return /* @__PURE__ */ jsx43(
16671
+ return /* @__PURE__ */ jsx44(
16612
16672
  TimelineRuler,
16613
16673
  {
16614
16674
  major: props.major,
@@ -16627,7 +16687,7 @@ function TimelineRulerPart() {
16627
16687
  }
16628
16688
 
16629
16689
  // src/player/components/PlayheadIndicator.tsx
16630
- import { Fragment as Fragment8, jsx as jsx44, jsxs as jsxs27 } from "react/jsx-runtime";
16690
+ import { Fragment as Fragment9, jsx as jsx45, jsxs as jsxs28 } from "react/jsx-runtime";
16631
16691
  function PlayheadIndicator({
16632
16692
  color = "var(--timeline-accent)",
16633
16693
  glowColor = "var(--timeline-playhead-glow)",
@@ -16637,8 +16697,8 @@ function PlayheadIndicator({
16637
16697
  const HEAD_W = PLAYHEAD_HEAD_W;
16638
16698
  const HEAD_H = 9;
16639
16699
  const HEAD_TOTAL_H = 1 + HEAD_H;
16640
- return /* @__PURE__ */ jsxs27(Fragment8, { children: [
16641
- /* @__PURE__ */ jsx44(
16700
+ return /* @__PURE__ */ jsxs28(Fragment9, { children: [
16701
+ /* @__PURE__ */ jsx45(
16642
16702
  "div",
16643
16703
  {
16644
16704
  "aria-hidden": "true",
@@ -16651,7 +16711,7 @@ function PlayheadIndicator({
16651
16711
  }
16652
16712
  }
16653
16713
  ),
16654
- /* @__PURE__ */ jsx44(
16714
+ /* @__PURE__ */ jsx45(
16655
16715
  "div",
16656
16716
  {
16657
16717
  className: "absolute bottom-0",
@@ -16665,7 +16725,7 @@ function PlayheadIndicator({
16665
16725
  }
16666
16726
  }
16667
16727
  ),
16668
- /* @__PURE__ */ jsx44(
16728
+ /* @__PURE__ */ jsx45(
16669
16729
  "div",
16670
16730
  {
16671
16731
  className: stickyHead ? "sticky" : "absolute",
@@ -16675,7 +16735,7 @@ function PlayheadIndicator({
16675
16735
  // Zero height keeps it from covering rows (sticky strip trick).
16676
16736
  height: stickyHead ? 0 : void 0
16677
16737
  },
16678
- children: /* @__PURE__ */ jsx44(
16738
+ children: /* @__PURE__ */ jsx45(
16679
16739
  "div",
16680
16740
  {
16681
16741
  style: {
@@ -16707,7 +16767,7 @@ import { memo as memo10 } from "react";
16707
16767
  import {
16708
16768
  useEffect as useEffect26,
16709
16769
  useRef as useRef32,
16710
- useState as useState21
16770
+ useState as useState22
16711
16771
  } from "react";
16712
16772
  import {
16713
16773
  HF_AUDIO_FADE_IN_ATTR,
@@ -16715,15 +16775,15 @@ import {
16715
16775
  clampFadesToDuration,
16716
16776
  formatFadeSeconds
16717
16777
  } from "@hyperframes/core/audio-fade";
16718
- import { Fragment as Fragment9, jsx as jsx45, jsxs as jsxs28 } from "react/jsx-runtime";
16778
+ import { Fragment as Fragment10, jsx as jsx46, jsxs as jsxs29 } from "react/jsx-runtime";
16719
16779
  var HANDLE_SIZE = 10;
16720
16780
  var HANDLE_HIT = 16;
16721
16781
  var DRAG_THRESHOLD_PX = 2;
16722
16782
  function TimelineClipFades({ el, pps, widthPx, showHandles }) {
16723
16783
  const { onSetElementAttributeLive, onSetElementAttributeQuiet } = useTimelineEditContextOptional();
16724
16784
  const canEdit = Boolean(onSetElementAttributeLive && onSetElementAttributeQuiet);
16725
- const [draft, setDraft] = useState21(null);
16726
- const [dragging, setDragging] = useState21(null);
16785
+ const [draft, setDraft] = useState22(null);
16786
+ const [dragging, setDragging] = useState22(null);
16727
16787
  const authoredIn = el.fadeIn ?? 0;
16728
16788
  const authoredOut = el.fadeOut ?? 0;
16729
16789
  useEffect26(() => setDraft(null), [authoredIn, authoredOut]);
@@ -16829,8 +16889,8 @@ function TimelineClipFades({ el, pps, widthPx, showHandles }) {
16829
16889
  touchAction: "none",
16830
16890
  outline: "none"
16831
16891
  });
16832
- return /* @__PURE__ */ jsxs28(Fragment9, { children: [
16833
- (showIn || showOut) && /* @__PURE__ */ jsxs28(
16892
+ return /* @__PURE__ */ jsxs29(Fragment10, { children: [
16893
+ (showIn || showOut) && /* @__PURE__ */ jsxs29(
16834
16894
  "svg",
16835
16895
  {
16836
16896
  "aria-hidden": "true",
@@ -16847,8 +16907,8 @@ function TimelineClipFades({ el, pps, widthPx, showHandles }) {
16847
16907
  viewBox: `0 0 ${Math.max(widthPx, 1)} 100`,
16848
16908
  preserveAspectRatio: "none",
16849
16909
  children: [
16850
- showIn && /* @__PURE__ */ jsxs28(Fragment9, { children: [
16851
- /* @__PURE__ */ jsx45(
16910
+ showIn && /* @__PURE__ */ jsxs29(Fragment10, { children: [
16911
+ /* @__PURE__ */ jsx46(
16852
16912
  "polygon",
16853
16913
  {
16854
16914
  "data-testid": "clip-fade-in",
@@ -16857,7 +16917,7 @@ function TimelineClipFades({ el, pps, widthPx, showHandles }) {
16857
16917
  fillOpacity: 0.35
16858
16918
  }
16859
16919
  ),
16860
- /* @__PURE__ */ jsx45(
16920
+ /* @__PURE__ */ jsx46(
16861
16921
  "line",
16862
16922
  {
16863
16923
  x1: 0,
@@ -16871,8 +16931,8 @@ function TimelineClipFades({ el, pps, widthPx, showHandles }) {
16871
16931
  }
16872
16932
  )
16873
16933
  ] }),
16874
- showOut && /* @__PURE__ */ jsxs28(Fragment9, { children: [
16875
- /* @__PURE__ */ jsx45(
16934
+ showOut && /* @__PURE__ */ jsxs29(Fragment10, { children: [
16935
+ /* @__PURE__ */ jsx46(
16876
16936
  "polygon",
16877
16937
  {
16878
16938
  "data-testid": "clip-fade-out",
@@ -16881,7 +16941,7 @@ function TimelineClipFades({ el, pps, widthPx, showHandles }) {
16881
16941
  fillOpacity: 0.35
16882
16942
  }
16883
16943
  ),
16884
- /* @__PURE__ */ jsx45(
16944
+ /* @__PURE__ */ jsx46(
16885
16945
  "line",
16886
16946
  {
16887
16947
  x1: widthPx - outPx,
@@ -16898,8 +16958,8 @@ function TimelineClipFades({ el, pps, widthPx, showHandles }) {
16898
16958
  ]
16899
16959
  }
16900
16960
  ),
16901
- canEdit && /* @__PURE__ */ jsxs28(Fragment9, { children: [
16902
- /* @__PURE__ */ jsx45(
16961
+ canEdit && /* @__PURE__ */ jsxs29(Fragment10, { children: [
16962
+ /* @__PURE__ */ jsx46(
16903
16963
  FadeHandle,
16904
16964
  {
16905
16965
  direction: "in",
@@ -16914,7 +16974,7 @@ function TimelineClipFades({ el, pps, widthPx, showHandles }) {
16914
16974
  onKeyDown: onHandleKeyDown
16915
16975
  }
16916
16976
  ),
16917
- /* @__PURE__ */ jsx45(
16977
+ /* @__PURE__ */ jsx46(
16918
16978
  FadeHandle,
16919
16979
  {
16920
16980
  direction: "out",
@@ -16945,7 +17005,7 @@ function FadeHandle({
16945
17005
  onKeyDown
16946
17006
  }) {
16947
17007
  const label = direction === "in" ? "Fade in" : "Fade out";
16948
- return /* @__PURE__ */ jsx45(
17008
+ return /* @__PURE__ */ jsx46(
16949
17009
  "div",
16950
17010
  {
16951
17011
  role: "slider",
@@ -16965,12 +17025,12 @@ function FadeHandle({
16965
17025
  onKeyDown,
16966
17026
  onClick: (e) => e.stopPropagation(),
16967
17027
  onDoubleClick: (e) => e.stopPropagation(),
16968
- children: /* @__PURE__ */ jsx45(FadeDot, { active: dragging })
17028
+ children: /* @__PURE__ */ jsx46(FadeDot, { active: dragging })
16969
17029
  }
16970
17030
  );
16971
17031
  }
16972
17032
  function FadeDot({ active }) {
16973
- return /* @__PURE__ */ jsx45(
17033
+ return /* @__PURE__ */ jsx46(
16974
17034
  "span",
16975
17035
  {
16976
17036
  "aria-hidden": "true",
@@ -16989,7 +17049,7 @@ function FadeDot({ active }) {
16989
17049
  }
16990
17050
 
16991
17051
  // src/player/components/TimelineClip.tsx
16992
- import { jsx as jsx46, jsxs as jsxs29 } from "react/jsx-runtime";
17052
+ import { jsx as jsx47, jsxs as jsxs30 } from "react/jsx-runtime";
16993
17053
  var TimelineClip = memo10(function TimelineClip2({
16994
17054
  el,
16995
17055
  pps,
@@ -17061,7 +17121,7 @@ var TimelineClip = memo10(function TimelineClip2({
17061
17121
  textAlign: "left",
17062
17122
  transform: isDragging ? "translateY(-1px)" : void 0
17063
17123
  };
17064
- return /* @__PURE__ */ jsxs29(
17124
+ return /* @__PURE__ */ jsxs30(
17065
17125
  "button",
17066
17126
  {
17067
17127
  type: "button",
@@ -17087,7 +17147,7 @@ var TimelineClip = memo10(function TimelineClip2({
17087
17147
  onDoubleClick,
17088
17148
  onContextMenu,
17089
17149
  children: [
17090
- showHandles && capabilities.canTrimStart && /* @__PURE__ */ jsx46(
17150
+ showHandles && capabilities.canTrimStart && /* @__PURE__ */ jsx47(
17091
17151
  "div",
17092
17152
  {
17093
17153
  "aria-hidden": "true",
@@ -17101,7 +17161,7 @@ var TimelineClip = memo10(function TimelineClip2({
17101
17161
  cursor: "col-resize",
17102
17162
  zIndex: 4
17103
17163
  },
17104
- children: /* @__PURE__ */ jsx46(
17164
+ children: /* @__PURE__ */ jsx47(
17105
17165
  "div",
17106
17166
  {
17107
17167
  className: "timeline-clip__handle-bar",
@@ -17119,7 +17179,7 @@ var TimelineClip = memo10(function TimelineClip2({
17119
17179
  )
17120
17180
  }
17121
17181
  ),
17122
- showHandles && capabilities.canTrimEnd && /* @__PURE__ */ jsx46(
17182
+ showHandles && capabilities.canTrimEnd && /* @__PURE__ */ jsx47(
17123
17183
  "div",
17124
17184
  {
17125
17185
  "aria-hidden": "true",
@@ -17133,7 +17193,7 @@ var TimelineClip = memo10(function TimelineClip2({
17133
17193
  cursor: "col-resize",
17134
17194
  zIndex: 4
17135
17195
  },
17136
- children: /* @__PURE__ */ jsx46(
17196
+ children: /* @__PURE__ */ jsx47(
17137
17197
  "div",
17138
17198
  {
17139
17199
  className: "timeline-clip__handle-bar",
@@ -17151,15 +17211,15 @@ var TimelineClip = memo10(function TimelineClip2({
17151
17211
  )
17152
17212
  }
17153
17213
  ),
17154
- showLabel && /* @__PURE__ */ jsx46("span", { className: "timeline-clip__label", children: displayLabel }),
17155
- showDefaultText && /* @__PURE__ */ jsxs29("span", { className: "timeline-clip__timecode", children: [
17214
+ showLabel && /* @__PURE__ */ jsx47("span", { className: "timeline-clip__label", children: displayLabel }),
17215
+ showDefaultText && /* @__PURE__ */ jsxs30("span", { className: "timeline-clip__timecode", children: [
17156
17216
  startLabel,
17157
17217
  "-",
17158
17218
  endLabel,
17159
17219
  "s"
17160
17220
  ] }),
17161
17221
  children,
17162
- (isAudioClip || el.hasAudio) && !isGestureActor && /* @__PURE__ */ jsx46(
17222
+ (isAudioClip || el.hasAudio) && !isGestureActor && /* @__PURE__ */ jsx47(
17163
17223
  TimelineClipFades,
17164
17224
  {
17165
17225
  el,
@@ -17174,7 +17234,7 @@ var TimelineClip = memo10(function TimelineClip2({
17174
17234
  });
17175
17235
 
17176
17236
  // src/player/components/TimelineCompactDiamonds.tsx
17177
- import { jsx as jsx47 } from "react/jsx-runtime";
17237
+ import { jsx as jsx48 } from "react/jsx-runtime";
17178
17238
  function TimelineCompactDiamonds({
17179
17239
  element,
17180
17240
  elementId: elementId2,
@@ -17195,7 +17255,7 @@ function TimelineCompactDiamonds({
17195
17255
  suppressClickRef
17196
17256
  }) {
17197
17257
  const width = Math.max(element.duration * pixelsPerSecond, 4);
17198
- return /* @__PURE__ */ jsx47(
17258
+ return /* @__PURE__ */ jsx48(
17199
17259
  "div",
17200
17260
  {
17201
17261
  className: "absolute pointer-events-none",
@@ -17206,7 +17266,7 @@ function TimelineCompactDiamonds({
17206
17266
  height: rowHeight - 2 * CLIP_Y,
17207
17267
  zIndex: isSelected ? 11 : 6
17208
17268
  },
17209
- children: /* @__PURE__ */ jsx47(
17269
+ children: /* @__PURE__ */ jsx48(
17210
17270
  TimelineClipDiamonds,
17211
17271
  {
17212
17272
  keyframesData,
@@ -17243,7 +17303,7 @@ import {
17243
17303
  useEffect as useEffect27,
17244
17304
  useMemo as useMemo23,
17245
17305
  useRef as useRef37,
17246
- useState as useState26
17306
+ useState as useState27
17247
17307
  } from "react";
17248
17308
  import {
17249
17309
  sampleAutomationLane as sampleAutomationLane5
@@ -17378,7 +17438,7 @@ function withLane(automation, lane) {
17378
17438
  }
17379
17439
 
17380
17440
  // src/player/components/useAutomationLaneGestures.ts
17381
- import { useCallback as useCallback25, useRef as useRef36, useState as useState25 } from "react";
17441
+ import { useCallback as useCallback25, useRef as useRef36, useState as useState26 } from "react";
17382
17442
 
17383
17443
  // src/player/components/automationLaneSelection.ts
17384
17444
  import {
@@ -17443,7 +17503,7 @@ function capturePointer(e) {
17443
17503
  }
17444
17504
 
17445
17505
  // src/player/components/useAutomationEdgeStretch.ts
17446
- import { useCallback as useCallback22, useRef as useRef33, useState as useState22 } from "react";
17506
+ import { useCallback as useCallback22, useRef as useRef33, useState as useState23 } from "react";
17447
17507
  var EDGE_GRAB_PX = 8;
17448
17508
  var EDGE_DRAG_PX = 3;
17449
17509
  var MIN_SELECTION_SEC = 0.02;
@@ -17468,9 +17528,9 @@ function useAutomationEdgeStretch({
17468
17528
  onRangeClear,
17469
17529
  onHint
17470
17530
  }) {
17471
- const [drag, setDrag] = useState22(null);
17531
+ const [drag, setDrag] = useState23(null);
17472
17532
  const crossed = useRef33(false);
17473
- const [hover, setHover] = useState22(false);
17533
+ const [hover, setHover] = useState23(false);
17474
17534
  const edgeAt = useCallback22(
17475
17535
  (clientX) => {
17476
17536
  if (!rangeSelection) return null;
@@ -17574,7 +17634,7 @@ function useAutomationEdgeStretch({
17574
17634
  }
17575
17635
 
17576
17636
  // src/player/components/useAutomationRangeDrag.ts
17577
- import { useCallback as useCallback23, useRef as useRef34, useState as useState23 } from "react";
17637
+ import { useCallback as useCallback23, useRef as useRef34, useState as useState24 } from "react";
17578
17638
 
17579
17639
  // src/player/components/automationLaneDragMath.ts
17580
17640
  var SNAP_SEC = 0.04;
@@ -17692,7 +17752,7 @@ function useAutomationRangeDrag({
17692
17752
  onRangeSelect,
17693
17753
  onRangeClear
17694
17754
  }) {
17695
- const [box, setBox] = useState23(null);
17755
+ const [box, setBox] = useState24(null);
17696
17756
  const crossed = useRef34(false);
17697
17757
  const arm = useCallback23(
17698
17758
  (e) => {
@@ -17735,7 +17795,7 @@ function useAutomationRangeDrag({
17735
17795
  }
17736
17796
 
17737
17797
  // src/player/components/useAutomationSegmentDrag.ts
17738
- import { useCallback as useCallback24, useRef as useRef35, useState as useState24 } from "react";
17798
+ import { useCallback as useCallback24, useRef as useRef35, useState as useState25 } from "react";
17739
17799
  import {
17740
17800
  sampleAutomationLane as sampleAutomationLane3
17741
17801
  } from "@hyperframes/core/audio-automation";
@@ -17753,8 +17813,8 @@ function useAutomationSegmentDrag({
17753
17813
  readOnly,
17754
17814
  onHint
17755
17815
  }) {
17756
- const [dragIndex, setDragIndex] = useState24(null);
17757
- const [hoverIndex, setHoverIndex] = useState24(null);
17816
+ const [dragIndex, setDragIndex] = useState25(null);
17817
+ const [hoverIndex, setHoverIndex] = useState25(null);
17758
17818
  const snapshot3 = useRef35(null);
17759
17819
  const hitIndex = useCallback24(
17760
17820
  (clientX, clientY) => {
@@ -17831,9 +17891,9 @@ function useAutomationLaneGestures({
17831
17891
  duration,
17832
17892
  rangeSelection
17833
17893
  }) {
17834
- const [dragIndex, setDragIndex] = useState25(null);
17835
- const [curveIndex, setCurveIndex] = useState25(null);
17836
- const [hint, setHint] = useState25(null);
17894
+ const [dragIndex, setDragIndex] = useState26(null);
17895
+ const [curveIndex, setCurveIndex] = useState26(null);
17896
+ const [hint, setHint] = useState26(null);
17837
17897
  const stretch = useAutomationEdgeStretch({
17838
17898
  getBox,
17839
17899
  lane,
@@ -17858,7 +17918,7 @@ function useAutomationLaneGestures({
17858
17918
  });
17859
17919
  const dragOrigin = useRef36(null);
17860
17920
  const groupDrag = useRef36(null);
17861
- const [editing, setEditing] = useState25(null);
17921
+ const [editing, setEditing] = useState26(null);
17862
17922
  const rangeDrag = useAutomationRangeDrag({
17863
17923
  pointAt,
17864
17924
  xOf,
@@ -18191,7 +18251,7 @@ function useAutomationLaneGestures({
18191
18251
  }
18192
18252
 
18193
18253
  // src/player/components/AutomationValueInput.tsx
18194
- import { jsx as jsx48 } from "react/jsx-runtime";
18254
+ import { jsx as jsx49 } from "react/jsx-runtime";
18195
18255
  function AutomationValueInput({
18196
18256
  text,
18197
18257
  leftPx,
@@ -18200,7 +18260,7 @@ function AutomationValueInput({
18200
18260
  onCommit,
18201
18261
  onCancel
18202
18262
  }) {
18203
- return /* @__PURE__ */ jsx48(
18263
+ return /* @__PURE__ */ jsx49(
18204
18264
  "input",
18205
18265
  {
18206
18266
  className: "hf-automation-value pointer-events-auto absolute rounded-[3px] border border-panel-border-input bg-panel-bg-2 px-1 font-mono text-[9px] text-panel-text-1",
@@ -18272,7 +18332,7 @@ function generateShape(input) {
18272
18332
  }
18273
18333
 
18274
18334
  // src/player/components/AutomationSelectionMenu.tsx
18275
- import { jsx as jsx49, jsxs as jsxs30 } from "react/jsx-runtime";
18335
+ import { jsx as jsx50, jsxs as jsxs31 } from "react/jsx-runtime";
18276
18336
  var AutomationSelectionMenu = memo11(function AutomationSelectionMenu2({
18277
18337
  x,
18278
18338
  y,
@@ -18289,14 +18349,14 @@ var AutomationSelectionMenu = memo11(function AutomationSelectionMenu2({
18289
18349
  const adjustedX = x + menuWidth > window.innerWidth ? x - menuWidth : x;
18290
18350
  const adjustedY = overflowY > 0 ? y - overflowY - 8 : y;
18291
18351
  return createPortal2(
18292
- /* @__PURE__ */ jsxs30(
18352
+ /* @__PURE__ */ jsxs31(
18293
18353
  "div",
18294
18354
  {
18295
18355
  ref: menuRef,
18296
18356
  className: "hf-automation-menu fixed z-200 min-w-[140px] rounded-sm border border-panel-border-input bg-panel-bg-2 py-1 shadow-lg",
18297
18357
  style: { left: adjustedX, top: adjustedY },
18298
18358
  children: [
18299
- AUTOMATION_SHAPES.map((shape) => /* @__PURE__ */ jsx49(
18359
+ AUTOMATION_SHAPES.map((shape) => /* @__PURE__ */ jsx50(
18300
18360
  "button",
18301
18361
  {
18302
18362
  type: "button",
@@ -18309,8 +18369,8 @@ var AutomationSelectionMenu = memo11(function AutomationSelectionMenu2({
18309
18369
  },
18310
18370
  shape.id
18311
18371
  )),
18312
- /* @__PURE__ */ jsx49("div", { className: "my-1 border-t border-panel-border-input" }),
18313
- /* @__PURE__ */ jsx49(
18372
+ /* @__PURE__ */ jsx50("div", { className: "my-1 border-t border-panel-border-input" }),
18373
+ /* @__PURE__ */ jsx50(
18314
18374
  "button",
18315
18375
  {
18316
18376
  type: "button",
@@ -18370,7 +18430,7 @@ function simplifyPoints(points, range, epsilon = 0.02) {
18370
18430
  }
18371
18431
 
18372
18432
  // src/player/components/AutomationEnvelopePaths.tsx
18373
- import { Fragment as Fragment10, jsx as jsx50, jsxs as jsxs31 } from "react/jsx-runtime";
18433
+ import { Fragment as Fragment11, jsx as jsx51, jsxs as jsxs32 } from "react/jsx-runtime";
18374
18434
  function AutomationEnvelopePaths({
18375
18435
  path,
18376
18436
  lane,
@@ -18381,8 +18441,8 @@ function AutomationEnvelopePaths({
18381
18441
  yOf
18382
18442
  }) {
18383
18443
  const activePath = activeSegment === null ? null : envelopeSegmentPath({ lane, range, index: activeSegment, xOf, yOf });
18384
- return /* @__PURE__ */ jsxs31(Fragment10, { children: [
18385
- /* @__PURE__ */ jsx50(
18444
+ return /* @__PURE__ */ jsxs32(Fragment11, { children: [
18445
+ /* @__PURE__ */ jsx51(
18386
18446
  "path",
18387
18447
  {
18388
18448
  "data-automation-envelope": "",
@@ -18393,7 +18453,7 @@ function AutomationEnvelopePaths({
18393
18453
  opacity: lane.points.length === 0 ? 0.35 : 0.95
18394
18454
  }
18395
18455
  ),
18396
- activePath ? /* @__PURE__ */ jsx50(
18456
+ activePath ? /* @__PURE__ */ jsx51(
18397
18457
  "path",
18398
18458
  {
18399
18459
  "data-automation-segment-active": activeSegment ?? void 0,
@@ -18410,7 +18470,7 @@ function AutomationEnvelopePaths({
18410
18470
  }
18411
18471
 
18412
18472
  // src/player/components/TimelineAutomationLane.tsx
18413
- import { jsx as jsx51, jsxs as jsxs32 } from "react/jsx-runtime";
18473
+ import { jsx as jsx52, jsxs as jsxs33 } from "react/jsx-runtime";
18414
18474
  var POINT_R = 4.9;
18415
18475
  var LANE_BORDER = defaultTimelineTheme.rowBorder;
18416
18476
  function pointInBox(point, box) {
@@ -18437,7 +18497,7 @@ function ReadOnlyNote({
18437
18497
  widthPx
18438
18498
  }) {
18439
18499
  if (!readOnly || !note || !hovered || hasRange) return null;
18440
- return /* @__PURE__ */ jsx51(
18500
+ return /* @__PURE__ */ jsx52(
18441
18501
  "div",
18442
18502
  {
18443
18503
  "data-automation-readonly-note": "",
@@ -18479,7 +18539,7 @@ function TimelineAutomationLane({
18479
18539
  }) {
18480
18540
  const stored = laneFor(automation, target);
18481
18541
  const svgRef = useRef37(null);
18482
- const [draft, setDraft] = useState26(
18542
+ const [draft, setDraft] = useState27(
18483
18543
  null
18484
18544
  );
18485
18545
  const lane = useMemo23(
@@ -18569,8 +18629,8 @@ function TimelineAutomationLane({
18569
18629
  },
18570
18630
  [lane, commitPoints, readOnly]
18571
18631
  );
18572
- const [menuAt, setMenuAt] = useState26(null);
18573
- const [hovered, setHovered] = useState26(false);
18632
+ const [menuAt, setMenuAt] = useState27(null);
18633
+ const [hovered, setHovered] = useState27(false);
18574
18634
  const insertShape = useCallback26(
18575
18635
  (shape) => {
18576
18636
  if (!rangeSelection) return;
@@ -18606,14 +18666,14 @@ function TimelineAutomationLane({
18606
18666
  [readOnly, rangeSelection, pointAt]
18607
18667
  );
18608
18668
  const currentValue = lane.points.length > 0 && playheadSec !== null ? sampleAutomationLane5(lane, playheadSec, range.scale) : null;
18609
- return /* @__PURE__ */ jsxs32(
18669
+ return /* @__PURE__ */ jsxs33(
18610
18670
  "div",
18611
18671
  {
18612
18672
  className: "hf-automation-lane pointer-events-none absolute",
18613
18673
  style: { top: topPx, left: 0, right: 0, height: h },
18614
18674
  "data-automation-lane": target,
18615
18675
  children: [
18616
- /* @__PURE__ */ jsx51(
18676
+ /* @__PURE__ */ jsx52(
18617
18677
  "div",
18618
18678
  {
18619
18679
  "data-automation-lane-border": "",
@@ -18621,7 +18681,7 @@ function TimelineAutomationLane({
18621
18681
  style: { top: 0, left: 0, right: 0, height: 1, background: LANE_BORDER, zIndex: 1 }
18622
18682
  }
18623
18683
  ),
18624
- /* @__PURE__ */ jsxs32(
18684
+ /* @__PURE__ */ jsxs33(
18625
18685
  "svg",
18626
18686
  {
18627
18687
  ref: svgRef,
@@ -18656,8 +18716,8 @@ function TimelineAutomationLane({
18656
18716
  role: "group",
18657
18717
  "aria-label": `${range.label} automation`,
18658
18718
  children: [
18659
- /* @__PURE__ */ jsx51("title", { children: laneTitle(readOnly) }),
18660
- /* @__PURE__ */ jsx51(
18719
+ /* @__PURE__ */ jsx52("title", { children: laneTitle(readOnly) }),
18720
+ /* @__PURE__ */ jsx52(
18661
18721
  "line",
18662
18722
  {
18663
18723
  x1: PAD_X,
@@ -18668,7 +18728,7 @@ function TimelineAutomationLane({
18668
18728
  strokeDasharray: "3 4"
18669
18729
  }
18670
18730
  ),
18671
- rangeSelection ? /* @__PURE__ */ jsx51(
18731
+ rangeSelection ? /* @__PURE__ */ jsx52(
18672
18732
  "rect",
18673
18733
  {
18674
18734
  "data-automation-selection": "",
@@ -18683,7 +18743,7 @@ function TimelineAutomationLane({
18683
18743
  pointerEvents: "none"
18684
18744
  }
18685
18745
  ) : null,
18686
- /* @__PURE__ */ jsx51(
18746
+ /* @__PURE__ */ jsx52(
18687
18747
  AutomationEnvelopePaths,
18688
18748
  {
18689
18749
  path,
@@ -18698,7 +18758,7 @@ function TimelineAutomationLane({
18698
18758
  lane.points.map((p, i) => {
18699
18759
  const inRange = pointInBox(p, rangeSelection);
18700
18760
  const { radius, stroke, strokeWidth } = pointCircleStyle(inRange, i === dragIndex);
18701
- return /* @__PURE__ */ jsx51(
18761
+ return /* @__PURE__ */ jsx52(
18702
18762
  "circle",
18703
18763
  {
18704
18764
  "data-automation-point": i,
@@ -18727,7 +18787,7 @@ function TimelineAutomationLane({
18727
18787
  `${i}-${p.t}`
18728
18788
  );
18729
18789
  }),
18730
- playheadSec !== null && currentValue !== null ? /* @__PURE__ */ jsx51(
18790
+ playheadSec !== null && currentValue !== null ? /* @__PURE__ */ jsx52(
18731
18791
  "circle",
18732
18792
  {
18733
18793
  "data-automation-playhead": "",
@@ -18742,7 +18802,7 @@ function TimelineAutomationLane({
18742
18802
  ]
18743
18803
  }
18744
18804
  ),
18745
- editing ? /* @__PURE__ */ jsx51(
18805
+ editing ? /* @__PURE__ */ jsx52(
18746
18806
  AutomationValueInput,
18747
18807
  {
18748
18808
  text: editing.text,
@@ -18753,7 +18813,7 @@ function TimelineAutomationLane({
18753
18813
  onCancel: gestures.cancelEdit
18754
18814
  }
18755
18815
  ) : null,
18756
- hint ? /* @__PURE__ */ jsx51(
18816
+ hint ? /* @__PURE__ */ jsx52(
18757
18817
  "div",
18758
18818
  {
18759
18819
  className: "hf-automation-hint pointer-events-none absolute rounded-[3px] bg-[var(--timeline-overlay-bg)] px-1 py-0.5 font-mono text-[9px] text-[var(--timeline-text-solid)]",
@@ -18761,7 +18821,7 @@ function TimelineAutomationLane({
18761
18821
  children: hint
18762
18822
  }
18763
18823
  ) : null,
18764
- /* @__PURE__ */ jsx51(
18824
+ /* @__PURE__ */ jsx52(
18765
18825
  ReadOnlyNote,
18766
18826
  {
18767
18827
  readOnly,
@@ -18772,7 +18832,7 @@ function TimelineAutomationLane({
18772
18832
  widthPx
18773
18833
  }
18774
18834
  ),
18775
- menuAt && rangeSelection ? /* @__PURE__ */ jsx51(
18835
+ menuAt && rangeSelection ? /* @__PURE__ */ jsx52(
18776
18836
  AutomationSelectionMenu,
18777
18837
  {
18778
18838
  x: menuAt.x,
@@ -18789,7 +18849,7 @@ function TimelineAutomationLane({
18789
18849
  }
18790
18850
 
18791
18851
  // src/player/components/TimelineAutomationLaneSlot.tsx
18792
- import { Fragment as Fragment11, jsx as jsx52 } from "react/jsx-runtime";
18852
+ import { Fragment as Fragment12, jsx as jsx53 } from "react/jsx-runtime";
18793
18853
  function ClipAutomationLanes({
18794
18854
  element,
18795
18855
  rows,
@@ -18814,10 +18874,10 @@ function ClipAutomationLanes({
18814
18874
  }, [bound]);
18815
18875
  if (rows.length === 0) return null;
18816
18876
  const inClip = currentTime >= element.start && currentTime <= element.start + element.duration;
18817
- return /* @__PURE__ */ jsx52(Fragment11, { children: rows.map(({ lane, rowIndex }) => {
18877
+ return /* @__PURE__ */ jsx53(Fragment12, { children: rows.map(({ lane, rowIndex }) => {
18818
18878
  const range = resolveAutomationRange3(lane.target, bound.chain ?? void 0);
18819
18879
  if (!range) return null;
18820
- return /* @__PURE__ */ jsx52(
18880
+ return /* @__PURE__ */ jsx53(
18821
18881
  TimelineAutomationLane,
18822
18882
  {
18823
18883
  duration: element.duration,
@@ -18870,7 +18930,7 @@ function TimelineAutomationLaneSlot({
18870
18930
  }
18871
18931
  });
18872
18932
  const top = topOffset ?? getTimelineLaneTop(laneCount);
18873
- return /* @__PURE__ */ jsx52(Fragment11, { children: clips.map((element) => /* @__PURE__ */ jsx52(
18933
+ return /* @__PURE__ */ jsx53(Fragment12, { children: clips.map((element) => /* @__PURE__ */ jsx53(
18874
18934
  ClipAutomationLanes,
18875
18935
  {
18876
18936
  element,
@@ -19410,10 +19470,10 @@ import { classifyAudioName as classifyAudioName2 } from "@hyperframes/core/audio
19410
19470
  import { Eye as Eye2, EyeSlash } from "@phosphor-icons/react";
19411
19471
 
19412
19472
  // src/player/components/TrackClipCount.tsx
19413
- import { jsx as jsx53 } from "react/jsx-runtime";
19473
+ import { jsx as jsx54 } from "react/jsx-runtime";
19414
19474
  function TrackClipCount({ clipCount }) {
19415
19475
  if (clipCount < 2) return null;
19416
- return /* @__PURE__ */ jsx53(
19476
+ return /* @__PURE__ */ jsx54(
19417
19477
  "span",
19418
19478
  {
19419
19479
  "aria-label": `${clipCount} clips`,
@@ -19437,13 +19497,13 @@ function trackDisplaySuffix(displayNumber) {
19437
19497
  }
19438
19498
 
19439
19499
  // src/player/components/TimelineTrackPlainHeader.tsx
19440
- import { Fragment as Fragment12, jsx as jsx54, jsxs as jsxs33 } from "react/jsx-runtime";
19500
+ import { Fragment as Fragment13, jsx as jsx55, jsxs as jsxs34 } from "react/jsx-runtime";
19441
19501
  function visibilityButtonLabel(hidden, suffix) {
19442
19502
  return hidden ? `Show track${suffix}` : `Hide track${suffix}`;
19443
19503
  }
19444
19504
  function visibilityButtonIcon(hidden) {
19445
19505
  const Icon = hidden ? EyeSlash : Eye2;
19446
- return /* @__PURE__ */ jsx54(Icon, { size: 14, weight: "bold", "aria-hidden": "true" });
19506
+ return /* @__PURE__ */ jsx55(Icon, { size: 14, weight: "bold", "aria-hidden": "true" });
19447
19507
  }
19448
19508
  function VisibilityButton({
19449
19509
  hidden,
@@ -19452,10 +19512,10 @@ function VisibilityButton({
19452
19512
  visible,
19453
19513
  onToggle
19454
19514
  }) {
19455
- if (!visible) return /* @__PURE__ */ jsx54("span", { "aria-hidden": "true", className: "h-6 w-6 shrink-0" });
19515
+ if (!visible) return /* @__PURE__ */ jsx55("span", { "aria-hidden": "true", className: "h-6 w-6 shrink-0" });
19456
19516
  const suffix = trackDisplaySuffix(trackDisplayNumber2);
19457
19517
  const label = visibilityButtonLabel(hidden, suffix);
19458
- return /* @__PURE__ */ jsx54(
19518
+ return /* @__PURE__ */ jsx55(
19459
19519
  "button",
19460
19520
  {
19461
19521
  type: "button",
@@ -19482,8 +19542,8 @@ function PlainTrackHeader({
19482
19542
  onToggleTrackHidden,
19483
19543
  trailing
19484
19544
  }) {
19485
- return /* @__PURE__ */ jsx54(Fragment12, { children: /* @__PURE__ */ jsxs33("div", { className: "flex min-w-0 items-center gap-1", children: [
19486
- isAudioTrack && /* @__PURE__ */ jsx54(
19545
+ return /* @__PURE__ */ jsx55(Fragment13, { children: /* @__PURE__ */ jsxs34("div", { className: "flex min-w-0 items-center gap-1", children: [
19546
+ isAudioTrack && /* @__PURE__ */ jsx55(
19487
19547
  Music,
19488
19548
  {
19489
19549
  size: 12,
@@ -19492,10 +19552,10 @@ function PlainTrackHeader({
19492
19552
  className: "text-[var(--timeline-text-faint)]"
19493
19553
  }
19494
19554
  ),
19495
- showTrackLabel && /* @__PURE__ */ jsx54("span", { title: trackLabel, className: "min-w-0 truncate text-[11px] leading-tight", children: trackLabel }),
19496
- showTrackLabel && /* @__PURE__ */ jsx54(TrackClipCount, { clipCount }),
19497
- /* @__PURE__ */ jsxs33("div", { className: "ml-auto flex shrink-0 items-center gap-1", children: [
19498
- /* @__PURE__ */ jsx54(
19555
+ showTrackLabel && /* @__PURE__ */ jsx55("span", { title: trackLabel, className: "min-w-0 truncate text-[11px] leading-tight", children: trackLabel }),
19556
+ showTrackLabel && /* @__PURE__ */ jsx55(TrackClipCount, { clipCount }),
19557
+ /* @__PURE__ */ jsxs34("div", { className: "ml-auto flex shrink-0 items-center gap-1", children: [
19558
+ /* @__PURE__ */ jsx55(
19499
19559
  VisibilityButton,
19500
19560
  {
19501
19561
  hidden: isTrackHidden,
@@ -19612,7 +19672,7 @@ function carverAgainst(doc, id) {
19612
19672
  }
19613
19673
 
19614
19674
  // src/player/components/TimelineFxButton.tsx
19615
- import { useEffect as useEffect32, useRef as useRef43, useState as useState27 } from "react";
19675
+ import { useEffect as useEffect32, useRef as useRef43, useState as useState28 } from "react";
19616
19676
  import { createPortal as createPortal3 } from "react-dom";
19617
19677
  import {
19618
19678
  enabledAudioFxNodes,
@@ -19630,7 +19690,7 @@ import {
19630
19690
  } from "@hyperframes/core/audio-fx-presets";
19631
19691
  import { PRESET_PROBLEM } from "@hyperframes/core/audio-fx-copy";
19632
19692
  import { useRef as useRef39 } from "react";
19633
- import { jsx as jsx55, jsxs as jsxs34 } from "react/jsx-runtime";
19693
+ import { jsx as jsx56, jsxs as jsxs35 } from "react/jsx-runtime";
19634
19694
  var FAMILY_LABEL = {
19635
19695
  voice: "Voice",
19636
19696
  repair: "Fix",
@@ -19650,15 +19710,15 @@ function FxPresetMenu({
19650
19710
  onAuditionTracked?.(id);
19651
19711
  };
19652
19712
  const families = trackKind === "music" || trackKind === "sfx" ? HF_AUDIO_FX_PRESET_FAMILIES.filter((f) => f !== "voice") : HF_AUDIO_FX_PRESET_FAMILIES;
19653
- return /* @__PURE__ */ jsx55(
19713
+ return /* @__PURE__ */ jsx56(
19654
19714
  "div",
19655
19715
  {
19656
19716
  className: "hf-fx-preset-menu space-y-1.5 rounded-[4px] border border-panel-border-input p-1.5",
19657
19717
  onMouseLeave: onAudition ? () => onAudition(null) : void 0,
19658
19718
  onBlur: onAudition ? () => onAudition(null) : void 0,
19659
- children: families.map((family) => /* @__PURE__ */ jsxs34("div", { className: "hf-fx-preset-group space-y-0.5", children: [
19660
- /* @__PURE__ */ jsx55("span", { className: "hf-fx-preset-group-label block font-mono text-[9px] uppercase tracking-wide text-panel-text-2", children: FAMILY_LABEL[family] }),
19661
- audioFxPresetsByFamily(family).map((preset) => /* @__PURE__ */ jsxs34(
19719
+ children: families.map((family) => /* @__PURE__ */ jsxs35("div", { className: "hf-fx-preset-group space-y-0.5", children: [
19720
+ /* @__PURE__ */ jsx56("span", { className: "hf-fx-preset-group-label block font-mono text-[9px] uppercase tracking-wide text-panel-text-2", children: FAMILY_LABEL[family] }),
19721
+ audioFxPresetsByFamily(family).map((preset) => /* @__PURE__ */ jsxs35(
19662
19722
  "button",
19663
19723
  {
19664
19724
  type: "button",
@@ -19674,21 +19734,21 @@ function FxPresetMenu({
19674
19734
  onAudition?.(preset.id);
19675
19735
  },
19676
19736
  children: [
19677
- /* @__PURE__ */ jsx55("span", { className: "hf-fx-preset-problem block truncate text-[10px]", children: PRESET_PROBLEM[preset.id] ?? preset.description }),
19678
- /* @__PURE__ */ jsxs34("span", { className: "block truncate font-mono text-[9px] text-panel-text-2", children: [
19679
- /* @__PURE__ */ jsx55("span", { className: "hf-fx-preset-name", children: preset.label }),
19680
- /* @__PURE__ */ jsxs34("span", { className: "hf-fx-preset-count", children: [
19737
+ /* @__PURE__ */ jsx56("span", { className: "hf-fx-preset-problem block truncate text-[10px]", children: PRESET_PROBLEM[preset.id] ?? preset.description }),
19738
+ /* @__PURE__ */ jsxs35("span", { className: "block truncate font-mono text-[9px] text-panel-text-2", children: [
19739
+ /* @__PURE__ */ jsx56("span", { className: "hf-fx-preset-name", children: preset.label }),
19740
+ /* @__PURE__ */ jsxs35("span", { className: "hf-fx-preset-count", children: [
19681
19741
  " \xB7 ",
19682
19742
  preset.nodes.length,
19683
19743
  " effect",
19684
19744
  preset.nodes.length === 1 ? "" : "s"
19685
19745
  ] })
19686
19746
  ] }),
19687
- onAudition ? /* @__PURE__ */ jsxs34("span", { className: "hf-fx-preset-wave", "aria-hidden": "true", children: [
19688
- /* @__PURE__ */ jsx55("span", {}),
19689
- /* @__PURE__ */ jsx55("span", {}),
19690
- /* @__PURE__ */ jsx55("span", {}),
19691
- /* @__PURE__ */ jsx55("span", {})
19747
+ onAudition ? /* @__PURE__ */ jsxs35("span", { className: "hf-fx-preset-wave", "aria-hidden": "true", children: [
19748
+ /* @__PURE__ */ jsx56("span", {}),
19749
+ /* @__PURE__ */ jsx56("span", {}),
19750
+ /* @__PURE__ */ jsx56("span", {}),
19751
+ /* @__PURE__ */ jsx56("span", {})
19692
19752
  ] }) : null
19693
19753
  ]
19694
19754
  },
@@ -19852,7 +19912,7 @@ function useFxAudition(chain, onChainPreview, onAuditionTransport) {
19852
19912
  }
19853
19913
 
19854
19914
  // src/components/editor/TimelineFxPopover.tsx
19855
- import { jsx as jsx56, jsxs as jsxs35 } from "react/jsx-runtime";
19915
+ import { jsx as jsx57, jsxs as jsxs36 } from "react/jsx-runtime";
19856
19916
  var POPOVER_WIDTH = 260;
19857
19917
  var VIEWPORT_MARGIN4 = 8;
19858
19918
  var MIN_POPOVER_HEIGHT = 160;
@@ -19921,7 +19981,7 @@ function TimelineFxPopover({
19921
19981
  audition(null);
19922
19982
  onClose();
19923
19983
  };
19924
- return /* @__PURE__ */ jsxs35(
19984
+ return /* @__PURE__ */ jsxs36(
19925
19985
  "div",
19926
19986
  {
19927
19987
  ref: rootRef,
@@ -19932,7 +19992,7 @@ function TimelineFxPopover({
19932
19992
  onKeyDown,
19933
19993
  onPointerDown: (event) => event.stopPropagation(),
19934
19994
  children: [
19935
- /* @__PURE__ */ jsx56("div", { className: "min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx56(
19995
+ /* @__PURE__ */ jsx57("div", { className: "min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx57(
19936
19996
  FxPresetMenu,
19937
19997
  {
19938
19998
  trackKind,
@@ -19941,8 +20001,8 @@ function TimelineFxPopover({
19941
20001
  onAuditionTracked: (id) => trackPresetAuditioned(id, { trackKind })
19942
20002
  }
19943
20003
  ) }),
19944
- /* @__PURE__ */ jsxs35("div", { className: "mt-2 flex shrink-0 items-center justify-between border-t border-white/10 pt-2 text-[10px] text-white/55", children: [
19945
- /* @__PURE__ */ jsx56(
20004
+ /* @__PURE__ */ jsxs36("div", { className: "mt-2 flex shrink-0 items-center justify-between border-t border-white/10 pt-2 text-[10px] text-white/55", children: [
20005
+ /* @__PURE__ */ jsx57(
19946
20006
  "button",
19947
20007
  {
19948
20008
  type: "button",
@@ -19954,7 +20014,7 @@ function TimelineFxPopover({
19954
20014
  children: "+ effect"
19955
20015
  }
19956
20016
  ),
19957
- /* @__PURE__ */ jsx56(
20017
+ /* @__PURE__ */ jsx57(
19958
20018
  "button",
19959
20019
  {
19960
20020
  type: "button",
@@ -20028,7 +20088,7 @@ function useAuditionTransport() {
20028
20088
  }
20029
20089
 
20030
20090
  // src/player/components/TimelineFxButton.tsx
20031
- import { jsx as jsx57, jsxs as jsxs36 } from "react/jsx-runtime";
20091
+ import { jsx as jsx58, jsxs as jsxs37 } from "react/jsx-runtime";
20032
20092
  var GROUP_DIALOG_SIZE = { width: 256, height: 160 };
20033
20093
  function groupDialogPosition(anchorRect) {
20034
20094
  const { left, top } = resolveFloatingPanelPosition(
@@ -20047,11 +20107,11 @@ function GroupNameDialog({
20047
20107
  onCancel,
20048
20108
  onConfirm
20049
20109
  }) {
20050
- const [label, setLabel] = useState27(defaultLabel ?? "Voiceover");
20110
+ const [label, setLabel] = useState28(defaultLabel ?? "Voiceover");
20051
20111
  const inputRef = useRef43(null);
20052
20112
  useEffect32(() => inputRef.current?.select(), []);
20053
20113
  if (refusal) {
20054
- return /* @__PURE__ */ jsx57(
20114
+ return /* @__PURE__ */ jsx58(
20055
20115
  "div",
20056
20116
  {
20057
20117
  role: "dialog",
@@ -20064,12 +20124,12 @@ function GroupNameDialog({
20064
20124
  event.stopPropagation();
20065
20125
  onCancel();
20066
20126
  },
20067
- children: /* @__PURE__ */ jsx57("p", { children: refusal })
20127
+ children: /* @__PURE__ */ jsx58("p", { children: refusal })
20068
20128
  }
20069
20129
  );
20070
20130
  }
20071
20131
  const confirm = () => onConfirm(label.trim() || defaultLabel || "Voiceover");
20072
- return /* @__PURE__ */ jsxs36(
20132
+ return /* @__PURE__ */ jsxs37(
20073
20133
  "div",
20074
20134
  {
20075
20135
  role: "dialog",
@@ -20085,8 +20145,8 @@ function GroupNameDialog({
20085
20145
  if (event.key === "Enter") confirm();
20086
20146
  },
20087
20147
  children: [
20088
- /* @__PURE__ */ jsx57("p", { className: "mb-1.5 font-medium text-[var(--timeline-text-solid)]", children: "Name this group" }),
20089
- /* @__PURE__ */ jsx57(
20148
+ /* @__PURE__ */ jsx58("p", { className: "mb-1.5 font-medium text-[var(--timeline-text-solid)]", children: "Name this group" }),
20149
+ /* @__PURE__ */ jsx58(
20090
20150
  "input",
20091
20151
  {
20092
20152
  ref: inputRef,
@@ -20097,13 +20157,13 @@ function GroupNameDialog({
20097
20157
  className: "w-full rounded-sm border border-[var(--timeline-border-strong)] bg-[var(--timeline-input-bg)] px-1.5 py-1 text-[11px] text-[var(--timeline-text-solid)] outline-hidden focus:border-[var(--timeline-accent)]"
20098
20158
  }
20099
20159
  ),
20100
- /* @__PURE__ */ jsxs36("p", { className: "mt-2 leading-snug", children: [
20160
+ /* @__PURE__ */ jsxs37("p", { className: "mt-2 leading-snug", children: [
20101
20161
  "Effects you add to the group apply to ",
20102
20162
  clipCount === 2 ? "both" : `all ${clipCount}`,
20103
20163
  " clips at once, and they share one volume."
20104
20164
  ] }),
20105
- /* @__PURE__ */ jsxs36("div", { className: "mt-2.5 flex justify-end gap-1.5", children: [
20106
- /* @__PURE__ */ jsx57(
20165
+ /* @__PURE__ */ jsxs37("div", { className: "mt-2.5 flex justify-end gap-1.5", children: [
20166
+ /* @__PURE__ */ jsx58(
20107
20167
  "button",
20108
20168
  {
20109
20169
  type: "button",
@@ -20112,7 +20172,7 @@ function GroupNameDialog({
20112
20172
  children: "Cancel"
20113
20173
  }
20114
20174
  ),
20115
- /* @__PURE__ */ jsx57(
20175
+ /* @__PURE__ */ jsx58(
20116
20176
  "button",
20117
20177
  {
20118
20178
  type: "button",
@@ -20135,9 +20195,9 @@ function parseFxChainOrEmpty(raw) {
20135
20195
  }
20136
20196
  }
20137
20197
  function TimelineFxButton(props) {
20138
- const [open, setOpen] = useState27(false);
20198
+ const [open, setOpen] = useState28(false);
20139
20199
  const buttonRef = useRef43(null);
20140
- const [anchorRect, setAnchorRect] = useState27(null);
20200
+ const [anchorRect, setAnchorRect] = useState28(null);
20141
20201
  const transport = useAuditionTransport();
20142
20202
  const borrowedMute = useRef43(false);
20143
20203
  const openAt = () => {
@@ -20145,8 +20205,8 @@ function TimelineFxButton(props) {
20145
20205
  setOpen(true);
20146
20206
  };
20147
20207
  if (props.variant === "group-pointer") {
20148
- return /* @__PURE__ */ jsxs36("div", { className: "relative shrink-0", children: [
20149
- /* @__PURE__ */ jsx57(
20208
+ return /* @__PURE__ */ jsxs37("div", { className: "relative shrink-0", children: [
20209
+ /* @__PURE__ */ jsx58(
20150
20210
  "button",
20151
20211
  {
20152
20212
  type: "button",
@@ -20164,7 +20224,7 @@ function TimelineFxButton(props) {
20164
20224
  }
20165
20225
  ),
20166
20226
  open && anchorRect && createPortal3(
20167
- /* @__PURE__ */ jsx57(
20227
+ /* @__PURE__ */ jsx58(
20168
20228
  GroupNameDialog,
20169
20229
  {
20170
20230
  refusal: props.refusal,
@@ -20184,8 +20244,8 @@ function TimelineFxButton(props) {
20184
20244
  }
20185
20245
  const chain = parseFxChainOrEmpty(props.fxChainRaw);
20186
20246
  const nodeCount = enabledAudioFxNodes(chain).length;
20187
- return /* @__PURE__ */ jsxs36("div", { className: "relative shrink-0", children: [
20188
- /* @__PURE__ */ jsxs36(
20247
+ return /* @__PURE__ */ jsxs37("div", { className: "relative shrink-0", children: [
20248
+ /* @__PURE__ */ jsxs37(
20189
20249
  "button",
20190
20250
  {
20191
20251
  type: "button",
@@ -20206,7 +20266,7 @@ function TimelineFxButton(props) {
20206
20266
  }
20207
20267
  ),
20208
20268
  open && anchorRect && createPortal3(
20209
- /* @__PURE__ */ jsx57(
20269
+ /* @__PURE__ */ jsx58(
20210
20270
  TimelineFxPopover,
20211
20271
  {
20212
20272
  anchorRect,
@@ -20230,14 +20290,14 @@ function TimelineFxButton(props) {
20230
20290
  }
20231
20291
 
20232
20292
  // src/player/components/LayerDisclosureRow.tsx
20233
- import { jsx as jsx58, jsxs as jsxs37 } from "react/jsx-runtime";
20293
+ import { jsx as jsx59, jsxs as jsxs38 } from "react/jsx-runtime";
20234
20294
  function LaneToggleButton({
20235
20295
  name,
20236
20296
  isExpanded,
20237
20297
  lanesId,
20238
20298
  onToggle
20239
20299
  }) {
20240
- return /* @__PURE__ */ jsx58(
20300
+ return /* @__PURE__ */ jsx59(
20241
20301
  "button",
20242
20302
  {
20243
20303
  type: "button",
@@ -20252,7 +20312,7 @@ function LaneToggleButton({
20252
20312
  event.stopPropagation();
20253
20313
  onToggle();
20254
20314
  },
20255
- children: /* @__PURE__ */ jsx58("span", { "aria-hidden": "true", children: "\u223F" })
20315
+ children: /* @__PURE__ */ jsx59("span", { "aria-hidden": "true", children: "\u223F" })
20256
20316
  }
20257
20317
  );
20258
20318
  }
@@ -20266,7 +20326,7 @@ function LayerDisclosureRow({
20266
20326
  onToggleClipExpanded,
20267
20327
  children
20268
20328
  }) {
20269
- return /* @__PURE__ */ jsxs37(
20329
+ return /* @__PURE__ */ jsxs38(
20270
20330
  "div",
20271
20331
  {
20272
20332
  className: "absolute left-0 top-0 flex items-center gap-1.5 overflow-hidden px-1.5 text-[11px]",
@@ -20277,7 +20337,7 @@ function LayerDisclosureRow({
20277
20337
  background: gutterBackground
20278
20338
  },
20279
20339
  children: [
20280
- /* @__PURE__ */ jsx58(
20340
+ /* @__PURE__ */ jsx59(
20281
20341
  "span",
20282
20342
  {
20283
20343
  "aria-hidden": "true",
@@ -20285,10 +20345,10 @@ function LayerDisclosureRow({
20285
20345
  children: "\u25C7"
20286
20346
  }
20287
20347
  ),
20288
- /* @__PURE__ */ jsx58("span", { title: name, className: "min-w-0 flex-1 truncate font-medium leading-tight", children: name }),
20289
- /* @__PURE__ */ jsx58(TrackClipCount, { clipCount }),
20348
+ /* @__PURE__ */ jsx59("span", { title: name, className: "min-w-0 flex-1 truncate font-medium leading-tight", children: name }),
20349
+ /* @__PURE__ */ jsx59(TrackClipCount, { clipCount }),
20290
20350
  children,
20291
- /* @__PURE__ */ jsx58(
20351
+ /* @__PURE__ */ jsx59(
20292
20352
  LaneToggleButton,
20293
20353
  {
20294
20354
  name,
@@ -20438,7 +20498,7 @@ function resolveLaneHeaderState(lane, currentTime, clipPercentage) {
20438
20498
  }
20439
20499
 
20440
20500
  // src/player/components/trackHeaderLabelRows.tsx
20441
- import { jsx as jsx59, jsxs as jsxs38 } from "react/jsx-runtime";
20501
+ import { jsx as jsx60, jsxs as jsxs39 } from "react/jsx-runtime";
20442
20502
  function PropertyGroupNavigation({
20443
20503
  navigation,
20444
20504
  label,
@@ -20452,8 +20512,8 @@ function PropertyGroupNavigation({
20452
20512
  onSeek?.(expandedElement.start + keyframe.percentage / 100 * expandedElement.duration);
20453
20513
  }
20454
20514
  };
20455
- return /* @__PURE__ */ jsxs38("span", { className: "flex shrink-0 items-center gap-0.5", children: [
20456
- /* @__PURE__ */ jsx59(
20515
+ return /* @__PURE__ */ jsxs39("span", { className: "flex shrink-0 items-center gap-0.5", children: [
20516
+ /* @__PURE__ */ jsx60(
20457
20517
  "button",
20458
20518
  {
20459
20519
  type: "button",
@@ -20468,7 +20528,7 @@ function PropertyGroupNavigation({
20468
20528
  }
20469
20529
  ),
20470
20530
  children,
20471
- /* @__PURE__ */ jsx59(
20531
+ /* @__PURE__ */ jsx60(
20472
20532
  "button",
20473
20533
  {
20474
20534
  type: "button",
@@ -20504,7 +20564,7 @@ function PropertyGroupHeaderRow({
20504
20564
  currentTime,
20505
20565
  clipPercentage
20506
20566
  );
20507
- return /* @__PURE__ */ jsxs38(
20567
+ return /* @__PURE__ */ jsxs39(
20508
20568
  "div",
20509
20569
  {
20510
20570
  id: timelineLogicalRowCellId(lanesId, timelinePropertyRowId(elementId2, lane.group), "header"),
@@ -20524,25 +20584,25 @@ function PropertyGroupHeaderRow({
20524
20584
  background: gutterBackground
20525
20585
  },
20526
20586
  children: [
20527
- /* @__PURE__ */ jsxs38("span", { className: "relative h-full w-3 shrink-0", "aria-hidden": "true", children: [
20528
- /* @__PURE__ */ jsx59(
20587
+ /* @__PURE__ */ jsxs39("span", { className: "relative h-full w-3 shrink-0", "aria-hidden": "true", children: [
20588
+ /* @__PURE__ */ jsx60(
20529
20589
  "span",
20530
20590
  {
20531
20591
  className: "absolute left-1.5 top-0 w-px bg-white/15",
20532
20592
  style: { height: isLastLane ? "50%" : "100%" }
20533
20593
  }
20534
20594
  ),
20535
- /* @__PURE__ */ jsx59("span", { className: "absolute left-1.5 top-1/2 h-px w-1.5 bg-white/15" })
20595
+ /* @__PURE__ */ jsx60("span", { className: "absolute left-1.5 top-1/2 h-px w-1.5 bg-white/15" })
20536
20596
  ] }),
20537
- /* @__PURE__ */ jsx59("span", { className: "w-[46px] shrink-0 truncate text-white", title: label, children: label }),
20538
- /* @__PURE__ */ jsx59(
20597
+ /* @__PURE__ */ jsx60("span", { className: "w-[46px] shrink-0 truncate text-white", title: label, children: label }),
20598
+ /* @__PURE__ */ jsx60(
20539
20599
  PropertyGroupNavigation,
20540
20600
  {
20541
20601
  navigation,
20542
20602
  label,
20543
20603
  expandedElement,
20544
20604
  onSeek,
20545
- children: /* @__PURE__ */ jsx59(
20605
+ children: /* @__PURE__ */ jsx60(
20546
20606
  "button",
20547
20607
  {
20548
20608
  type: "button",
@@ -20561,7 +20621,7 @@ function PropertyGroupHeaderRow({
20561
20621
  )
20562
20622
  }
20563
20623
  ),
20564
- /* @__PURE__ */ jsx59(
20624
+ /* @__PURE__ */ jsx60(
20565
20625
  "span",
20566
20626
  {
20567
20627
  className: "min-w-0 flex-1 truncate text-right tabular-nums text-white/45",
@@ -20587,7 +20647,7 @@ function AutomationLaneHeaderRow({
20587
20647
  isCarve,
20588
20648
  onReveal
20589
20649
  }) {
20590
- return /* @__PURE__ */ jsxs38(
20650
+ return /* @__PURE__ */ jsxs39(
20591
20651
  "div",
20592
20652
  {
20593
20653
  "data-automation-lane-label": label,
@@ -20600,17 +20660,17 @@ function AutomationLaneHeaderRow({
20600
20660
  background: gutterBackground
20601
20661
  },
20602
20662
  children: [
20603
- /* @__PURE__ */ jsxs38("span", { className: "relative h-full w-3 shrink-0", "aria-hidden": "true", children: [
20604
- /* @__PURE__ */ jsx59(
20663
+ /* @__PURE__ */ jsxs39("span", { className: "relative h-full w-3 shrink-0", "aria-hidden": "true", children: [
20664
+ /* @__PURE__ */ jsx60(
20605
20665
  "span",
20606
20666
  {
20607
20667
  className: "absolute left-1.5 top-0 w-px bg-white/15",
20608
20668
  style: { height: isLastLane ? "50%" : "100%" }
20609
20669
  }
20610
20670
  ),
20611
- /* @__PURE__ */ jsx59("span", { className: "absolute left-1.5 top-1/2 h-px w-1.5 bg-white/15" })
20671
+ /* @__PURE__ */ jsx60("span", { className: "absolute left-1.5 top-1/2 h-px w-1.5 bg-white/15" })
20612
20672
  ] }),
20613
- /* @__PURE__ */ jsxs38(
20673
+ /* @__PURE__ */ jsxs39(
20614
20674
  "button",
20615
20675
  {
20616
20676
  type: "button",
@@ -20625,8 +20685,8 @@ function AutomationLaneHeaderRow({
20625
20685
  onReveal?.();
20626
20686
  },
20627
20687
  children: [
20628
- /* @__PURE__ */ jsx59("span", { "data-automation-lane-name": "", className: "truncate font-mono text-[9px] text-white/70", children: name }),
20629
- param ? /* @__PURE__ */ jsx59(
20688
+ /* @__PURE__ */ jsx60("span", { "data-automation-lane-name": "", className: "truncate font-mono text-[9px] text-white/70", children: name }),
20689
+ param ? /* @__PURE__ */ jsx60(
20630
20690
  "span",
20631
20691
  {
20632
20692
  "data-automation-lane-param": "",
@@ -20634,7 +20694,7 @@ function AutomationLaneHeaderRow({
20634
20694
  children: param
20635
20695
  }
20636
20696
  ) : null,
20637
- alsoAutomatedBy ? /* @__PURE__ */ jsxs38(
20697
+ alsoAutomatedBy ? /* @__PURE__ */ jsxs39(
20638
20698
  "span",
20639
20699
  {
20640
20700
  "data-automation-lane-also": "",
@@ -20649,7 +20709,7 @@ function AutomationLaneHeaderRow({
20649
20709
  ]
20650
20710
  }
20651
20711
  ),
20652
- onRemove && target !== null && !isCarve && /* @__PURE__ */ jsx59(
20712
+ onRemove && target !== null && !isCarve && /* @__PURE__ */ jsx60(
20653
20713
  "button",
20654
20714
  {
20655
20715
  type: "button",
@@ -20671,7 +20731,7 @@ function AutomationLaneHeaderRow({
20671
20731
 
20672
20732
  // src/player/components/TimelineTrackHeader.tsx
20673
20733
  import { useMemo as useMemo26 } from "react";
20674
- import { Fragment as Fragment13, jsx as jsx60, jsxs as jsxs39 } from "react/jsx-runtime";
20734
+ import { Fragment as Fragment14, jsx as jsx61, jsxs as jsxs40 } from "react/jsx-runtime";
20675
20735
  var GROUP_MEMBER_RAIL = "var(--timeline-accent-rail)";
20676
20736
  var GROUP_MEMBER_INDENT = 14;
20677
20737
  var GROUP_MEMBER_TINT = "var(--timeline-group-member-tint)";
@@ -20791,7 +20851,7 @@ function TimelineTrackHeader({
20791
20851
  if (!allGroupableClipIds || allGroupableClipIds.length < 2) return;
20792
20852
  void onGroupClips(allGroupableClipIds, mintGroupId(doc), label);
20793
20853
  };
20794
- return /* @__PURE__ */ jsxs39(
20854
+ return /* @__PURE__ */ jsxs40(
20795
20855
  "div",
20796
20856
  {
20797
20857
  role: "rowheader",
@@ -20813,12 +20873,12 @@ function TimelineTrackHeader({
20813
20873
  } : {}
20814
20874
  },
20815
20875
  children: [
20816
- !isKeyframeLayer ? /* @__PURE__ */ jsx60(Fragment13, { children: /* @__PURE__ */ jsx60(
20876
+ !isKeyframeLayer ? /* @__PURE__ */ jsx61(Fragment14, { children: /* @__PURE__ */ jsx61(
20817
20877
  "div",
20818
20878
  {
20819
20879
  className: showTrackLabel ? "flex flex-col justify-center gap-0.5 px-1.5 text-[var(--timeline-handle)]" : "flex flex-col items-center justify-center gap-0.5",
20820
20880
  style: { height: TRACK_H },
20821
- children: /* @__PURE__ */ jsx60(
20881
+ children: /* @__PURE__ */ jsx61(
20822
20882
  PlainTrackHeader,
20823
20883
  {
20824
20884
  trackNumber,
@@ -20829,8 +20889,8 @@ function TimelineTrackHeader({
20829
20889
  isTrackHidden,
20830
20890
  isAudioTrack,
20831
20891
  onToggleTrackHidden,
20832
- trailing: /* @__PURE__ */ jsxs39(Fragment13, { children: [
20833
- singleAudioClip && /* @__PURE__ */ jsx60(
20892
+ trailing: /* @__PURE__ */ jsxs40(Fragment14, { children: [
20893
+ singleAudioClip && /* @__PURE__ */ jsx61(
20834
20894
  TimelineFxButton,
20835
20895
  {
20836
20896
  variant: "chain",
@@ -20848,7 +20908,7 @@ function TimelineTrackHeader({
20848
20908
  onOpenRack: () => openClipFxRack(singleAudioClip)
20849
20909
  }
20850
20910
  ),
20851
- clipCount > 1 && !isTrackGrouped && (isAudioTrack ? canGroupWholeTrack : isVideoWithAudioTrack) && /* @__PURE__ */ jsx60(
20911
+ clipCount > 1 && !isTrackGrouped && (isAudioTrack ? canGroupWholeTrack : isVideoWithAudioTrack) && /* @__PURE__ */ jsx61(
20852
20912
  TimelineFxButton,
20853
20913
  {
20854
20914
  variant: "group-pointer",
@@ -20858,7 +20918,7 @@ function TimelineTrackHeader({
20858
20918
  onGroupClips: groupUngroupedClips
20859
20919
  }
20860
20920
  ),
20861
- disclosable && /* @__PURE__ */ jsx60(
20921
+ disclosable && /* @__PURE__ */ jsx61(
20862
20922
  LaneToggleButton,
20863
20923
  {
20864
20924
  name: laneOwnerName,
@@ -20871,7 +20931,7 @@ function TimelineTrackHeader({
20871
20931
  }
20872
20932
  )
20873
20933
  }
20874
- ) }) : /* @__PURE__ */ jsx60(Fragment13, { children: /* @__PURE__ */ jsx60(
20934
+ ) }) : /* @__PURE__ */ jsx61(Fragment14, { children: /* @__PURE__ */ jsx61(
20875
20935
  LayerDisclosureRow,
20876
20936
  {
20877
20937
  name: laneOwnerName,
@@ -20881,7 +20941,7 @@ function TimelineTrackHeader({
20881
20941
  columnWidth: showTrackLabel ? LABEL_COL_W : contentOrigin,
20882
20942
  lanesId,
20883
20943
  onToggleClipExpanded,
20884
- children: /* @__PURE__ */ jsx60(
20944
+ children: /* @__PURE__ */ jsx61(
20885
20945
  VisibilityButton,
20886
20946
  {
20887
20947
  hidden: isTrackHidden,
@@ -20893,7 +20953,7 @@ function TimelineTrackHeader({
20893
20953
  )
20894
20954
  }
20895
20955
  ) }),
20896
- isExpanded && keyframeClip && lanes.map((lane, laneIndex) => /* @__PURE__ */ jsx60(
20956
+ isExpanded && keyframeClip && lanes.map((lane, laneIndex) => /* @__PURE__ */ jsx61(
20897
20957
  PropertyGroupHeaderRow,
20898
20958
  {
20899
20959
  lanesId,
@@ -20913,7 +20973,7 @@ function TimelineTrackHeader({
20913
20973
  )),
20914
20974
  isExpanded && automationRows.map((row, index) => {
20915
20975
  const revealTarget = row.target;
20916
- return /* @__PURE__ */ jsx60(
20976
+ return /* @__PURE__ */ jsx61(
20917
20977
  AutomationLaneHeaderRow,
20918
20978
  {
20919
20979
  target: row.target,
@@ -20950,7 +21010,7 @@ import {
20950
21010
  } from "@hyperframes/core/audio-fx";
20951
21011
 
20952
21012
  // src/player/components/TimelineTrackRow.tsx
20953
- import { jsx as jsx61, jsxs as jsxs40 } from "react/jsx-runtime";
21013
+ import { jsx as jsx62, jsxs as jsxs41 } from "react/jsx-runtime";
20954
21014
  function TimelineTrackRow({
20955
21015
  index,
20956
21016
  rowKey,
@@ -20966,7 +21026,7 @@ function TimelineTrackRow({
20966
21026
  rovingTargetId = null,
20967
21027
  children
20968
21028
  }) {
20969
- return /* @__PURE__ */ jsxs40(
21029
+ return /* @__PURE__ */ jsxs41(
20970
21030
  "div",
20971
21031
  {
20972
21032
  role: "rowgroup",
@@ -20981,7 +21041,7 @@ function TimelineTrackRow({
20981
21041
  borderBottom: `1px solid ${borderColor}`
20982
21042
  },
20983
21043
  children: [
20984
- /* @__PURE__ */ jsx61(
21044
+ /* @__PURE__ */ jsx62(
20985
21045
  "div",
20986
21046
  {
20987
21047
  role: "row",
@@ -21003,7 +21063,7 @@ function TimelineTrackRow({
21003
21063
  return (
21004
21064
  // ponytail: aria-owns maps this hidden logical row onto the two visible
21005
21065
  // property-lane cells without duplicating interactive controls.
21006
- /* @__PURE__ */ jsxs40(
21066
+ /* @__PURE__ */ jsxs41(
21007
21067
  "div",
21008
21068
  {
21009
21069
  role: "row",
@@ -21013,7 +21073,7 @@ function TimelineTrackRow({
21013
21073
  "data-timeline-logical-row-id": row.id,
21014
21074
  className: "sr-only",
21015
21075
  children: [
21016
- /* @__PURE__ */ jsx61(
21076
+ /* @__PURE__ */ jsx62(
21017
21077
  "div",
21018
21078
  {
21019
21079
  role: "rowheader",
@@ -21022,7 +21082,7 @@ function TimelineTrackRow({
21022
21082
  children: group
21023
21083
  }
21024
21084
  ),
21025
- /* @__PURE__ */ jsxs40(
21085
+ /* @__PURE__ */ jsxs41(
21026
21086
  "div",
21027
21087
  {
21028
21088
  role: "gridcell",
@@ -21048,13 +21108,13 @@ function TimelineTrackRow({
21048
21108
  }
21049
21109
 
21050
21110
  // src/player/components/TimelineGroupHeader.tsx
21051
- import { jsx as jsx62, jsxs as jsxs41 } from "react/jsx-runtime";
21111
+ import { jsx as jsx63, jsxs as jsxs42 } from "react/jsx-runtime";
21052
21112
  function GroupNameButton({
21053
21113
  label,
21054
21114
  memberCount,
21055
21115
  onOpenFxRack
21056
21116
  }) {
21057
- return /* @__PURE__ */ jsxs41(
21117
+ return /* @__PURE__ */ jsxs42(
21058
21118
  "button",
21059
21119
  {
21060
21120
  type: "button",
@@ -21068,7 +21128,7 @@ function GroupNameButton({
21068
21128
  onOpenFxRack();
21069
21129
  },
21070
21130
  children: [
21071
- /* @__PURE__ */ jsx62(
21131
+ /* @__PURE__ */ jsx63(
21072
21132
  "span",
21073
21133
  {
21074
21134
  "aria-hidden": "true",
@@ -21076,8 +21136,8 @@ function GroupNameButton({
21076
21136
  children: "\u25A4"
21077
21137
  }
21078
21138
  ),
21079
- /* @__PURE__ */ jsx62("span", { title: label, className: "min-w-0 truncate text-left font-medium leading-tight", children: label }),
21080
- /* @__PURE__ */ jsx62(
21139
+ /* @__PURE__ */ jsx63("span", { title: label, className: "min-w-0 truncate text-left font-medium leading-tight", children: label }),
21140
+ /* @__PURE__ */ jsx63(
21081
21141
  "span",
21082
21142
  {
21083
21143
  className: "shrink-0 rounded-full bg-[var(--timeline-tick-major)] px-1 text-[9px] leading-[14px] tabular-nums text-[var(--timeline-handle)]",
@@ -21106,7 +21166,7 @@ function TimelineGroupHeader({
21106
21166
  columnWidth,
21107
21167
  theme
21108
21168
  }) {
21109
- return /* @__PURE__ */ jsxs41(
21169
+ return /* @__PURE__ */ jsxs42(
21110
21170
  "div",
21111
21171
  {
21112
21172
  role: "rowheader",
@@ -21120,7 +21180,7 @@ function TimelineGroupHeader({
21120
21180
  borderRight: `1px solid ${theme.gutterBorder}`
21121
21181
  },
21122
21182
  children: [
21123
- /* @__PURE__ */ jsx62(
21183
+ /* @__PURE__ */ jsx63(
21124
21184
  "button",
21125
21185
  {
21126
21186
  type: "button",
@@ -21134,12 +21194,12 @@ function TimelineGroupHeader({
21134
21194
  event.stopPropagation();
21135
21195
  onToggleExpanded();
21136
21196
  },
21137
- children: /* @__PURE__ */ jsx62("span", { "aria-hidden": "true", children: isExpanded ? "\u25BE" : "\u25B8" })
21197
+ children: /* @__PURE__ */ jsx63("span", { "aria-hidden": "true", children: isExpanded ? "\u25BE" : "\u25B8" })
21138
21198
  }
21139
21199
  ),
21140
- /* @__PURE__ */ jsx62(GroupNameButton, { label, memberCount, onOpenFxRack }),
21141
- /* @__PURE__ */ jsxs41("div", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
21142
- /* @__PURE__ */ jsx62(
21200
+ /* @__PURE__ */ jsx63(GroupNameButton, { label, memberCount, onOpenFxRack }),
21201
+ /* @__PURE__ */ jsxs42("div", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
21202
+ /* @__PURE__ */ jsx63(
21143
21203
  TimelineFxButton,
21144
21204
  {
21145
21205
  fxChainRaw: fxChain,
@@ -21149,7 +21209,7 @@ function TimelineGroupHeader({
21149
21209
  onOpenRack: onOpenFxRack
21150
21210
  }
21151
21211
  ),
21152
- laneCount > 0 && /* @__PURE__ */ jsxs41(
21212
+ laneCount > 0 && /* @__PURE__ */ jsxs42(
21153
21213
  "button",
21154
21214
  {
21155
21215
  type: "button",
@@ -21164,8 +21224,8 @@ function TimelineGroupHeader({
21164
21224
  onToggleLanes();
21165
21225
  },
21166
21226
  children: [
21167
- /* @__PURE__ */ jsx62("span", { "aria-hidden": "true", children: "\u223F" }),
21168
- /* @__PURE__ */ jsx62("span", { className: "text-[9px] tabular-nums text-[var(--timeline-handle)]", children: laneCount })
21227
+ /* @__PURE__ */ jsx63("span", { "aria-hidden": "true", children: "\u223F" }),
21228
+ /* @__PURE__ */ jsx63("span", { className: "text-[9px] tabular-nums text-[var(--timeline-handle)]", children: laneCount })
21169
21229
  ]
21170
21230
  }
21171
21231
  )
@@ -21179,13 +21239,13 @@ function TimelineGroupHeader({
21179
21239
  import { sampleAutomationLane as sampleAutomationLane7 } from "@hyperframes/core/audio-automation";
21180
21240
 
21181
21241
  // src/hooks/useLivePlayheadTime.ts
21182
- import { useEffect as useEffect33, useRef as useRef44, useState as useState28 } from "react";
21242
+ import { useEffect as useEffect33, useRef as useRef44, useState as useState29 } from "react";
21183
21243
  var THROTTLE_MS = 33;
21184
21244
  function useLivePlayheadTime() {
21185
21245
  const storeTime = usePlayerStore((s) => s.currentTime);
21186
21246
  const isPlaying = usePlayerStore((s) => s.isPlaying);
21187
21247
  const liveRef = useRef44(storeTime);
21188
- const [, forceRender] = useState28(0);
21248
+ const [, forceRender] = useState29(0);
21189
21249
  if (!isPlaying) liveRef.current = storeTime;
21190
21250
  useEffect33(() => {
21191
21251
  if (!isPlaying) return;
@@ -21208,7 +21268,7 @@ function useLivePlayheadTime() {
21208
21268
  }
21209
21269
 
21210
21270
  // src/player/components/TimelineGroupLaneLabels.tsx
21211
- import { Fragment as Fragment14, jsx as jsx63, jsxs as jsxs42 } from "react/jsx-runtime";
21271
+ import { Fragment as Fragment15, jsx as jsx64, jsxs as jsxs43 } from "react/jsx-runtime";
21212
21272
  function TimelineGroupLaneLabels({
21213
21273
  groupElement,
21214
21274
  groupLabel: groupLabel2,
@@ -21220,12 +21280,12 @@ function TimelineGroupLaneLabels({
21220
21280
  }) {
21221
21281
  const currentTime = useLivePlayheadTime();
21222
21282
  const laneGroups = groupAutomationLanes([groupElement]);
21223
- return /* @__PURE__ */ jsx63(Fragment14, { children: laneGroups.map((laneGroup, index) => {
21283
+ return /* @__PURE__ */ jsx64(Fragment15, { children: laneGroups.map((laneGroup, index) => {
21224
21284
  const lane = laneGroup.entries[0]?.lane;
21225
21285
  if (!lane) return null;
21226
21286
  const parts = { name: laneGroup.name, param: laneGroup.param };
21227
21287
  const value = sampleAutomationLane7(lane, currentTime);
21228
- return /* @__PURE__ */ jsxs42(
21288
+ return /* @__PURE__ */ jsxs43(
21229
21289
  "button",
21230
21290
  {
21231
21291
  type: "button",
@@ -21247,7 +21307,7 @@ function TimelineGroupLaneLabels({
21247
21307
  onReveal?.(lane.target);
21248
21308
  },
21249
21309
  children: [
21250
- /* @__PURE__ */ jsx63(
21310
+ /* @__PURE__ */ jsx64(
21251
21311
  "span",
21252
21312
  {
21253
21313
  "aria-hidden": "true",
@@ -21255,11 +21315,11 @@ function TimelineGroupLaneLabels({
21255
21315
  children: "\u25A4"
21256
21316
  }
21257
21317
  ),
21258
- /* @__PURE__ */ jsxs42("span", { className: "flex min-w-0 flex-1 flex-col justify-center leading-tight", children: [
21259
- /* @__PURE__ */ jsx63("span", { className: "truncate font-mono text-[9px] text-[var(--timeline-text-bright)]", children: parts.name }),
21260
- parts.param ? /* @__PURE__ */ jsx63("span", { className: "truncate font-mono text-[9px] text-[var(--timeline-text-dim)]", children: parts.param }) : null
21318
+ /* @__PURE__ */ jsxs43("span", { className: "flex min-w-0 flex-1 flex-col justify-center leading-tight", children: [
21319
+ /* @__PURE__ */ jsx64("span", { className: "truncate font-mono text-[9px] text-[var(--timeline-text-bright)]", children: parts.name }),
21320
+ parts.param ? /* @__PURE__ */ jsx64("span", { className: "truncate font-mono text-[9px] text-[var(--timeline-text-dim)]", children: parts.param }) : null
21261
21321
  ] }),
21262
- /* @__PURE__ */ jsx63("span", { className: "shrink-0 font-mono text-[9px] tabular-nums text-[var(--timeline-handle)]", children: value.toFixed(2) })
21322
+ /* @__PURE__ */ jsx64("span", { className: "shrink-0 font-mono text-[9px] tabular-nums text-[var(--timeline-handle)]", children: value.toFixed(2) })
21263
21323
  ]
21264
21324
  },
21265
21325
  lane.target
@@ -21268,7 +21328,7 @@ function TimelineGroupLaneLabels({
21268
21328
  }
21269
21329
 
21270
21330
  // src/player/components/TimelineGroupRow.tsx
21271
- import { jsx as jsx64, jsxs as jsxs43 } from "react/jsx-runtime";
21331
+ import { jsx as jsx65, jsxs as jsxs44 } from "react/jsx-runtime";
21272
21332
  var GROUP_LANE_ACCENT = "var(--timeline-accent)";
21273
21333
  function TimelineGroupRow({
21274
21334
  index,
@@ -21316,7 +21376,7 @@ function TimelineGroupRow({
21316
21376
  })
21317
21377
  );
21318
21378
  };
21319
- return /* @__PURE__ */ jsxs43(
21379
+ return /* @__PURE__ */ jsxs44(
21320
21380
  TimelineTrackRow,
21321
21381
  {
21322
21382
  index,
@@ -21332,13 +21392,13 @@ function TimelineGroupRow({
21332
21392
  borderColor: theme.rowBorder,
21333
21393
  rovingTargetId,
21334
21394
  children: [
21335
- /* @__PURE__ */ jsxs43(
21395
+ /* @__PURE__ */ jsxs44(
21336
21396
  "div",
21337
21397
  {
21338
21398
  className: "sticky left-0 z-12 shrink-0",
21339
21399
  style: { width: contentOrigin >= LABEL_COL_W ? LABEL_COL_W : contentOrigin },
21340
21400
  children: [
21341
- /* @__PURE__ */ jsx64(
21401
+ /* @__PURE__ */ jsx65(
21342
21402
  TimelineGroupHeader,
21343
21403
  {
21344
21404
  label: group.label,
@@ -21357,7 +21417,7 @@ function TimelineGroupRow({
21357
21417
  theme
21358
21418
  }
21359
21419
  ),
21360
- isLaneOpen && /* @__PURE__ */ jsx64(
21420
+ isLaneOpen && /* @__PURE__ */ jsx65(
21361
21421
  TimelineGroupLaneLabels,
21362
21422
  {
21363
21423
  groupElement,
@@ -21376,14 +21436,14 @@ function TimelineGroupRow({
21376
21436
  // slot positions absolutely, so mounted straight on the row it resolved
21377
21437
  // against the row instead and drew the envelope across the label gutter
21378
21438
  // from x=0.
21379
- /* @__PURE__ */ jsx64(
21439
+ /* @__PURE__ */ jsx65(
21380
21440
  "div",
21381
21441
  {
21382
21442
  role: "gridcell",
21383
21443
  "aria-colindex": 2,
21384
21444
  style: { width: trackContentWidth, marginLeft: contentGutter },
21385
21445
  className: "relative",
21386
- children: /* @__PURE__ */ jsx64(
21446
+ children: /* @__PURE__ */ jsx65(
21387
21447
  TimelineAutomationLaneSlot,
21388
21448
  {
21389
21449
  elements: [groupElement],
@@ -23178,36 +23238,6 @@ function createClipGestureHandlers(el, elementKey3, previewElement, capabilities
23178
23238
  return { onResizeStart, onPointerDown, onClick };
23179
23239
  }
23180
23240
 
23181
- // src/player/components/timelineClipChildren.tsx
23182
- import { Fragment as Fragment15, jsx as jsx65, jsxs as jsxs44 } from "react/jsx-runtime";
23183
- function resolveClipRenderContext(element, visibleTimeRange, interactive) {
23184
- if (interactive) return { priority: "interaction", rich: false };
23185
- const visible = element.start < visibleTimeRange.end && element.start + element.duration > visibleTimeRange.start;
23186
- return { priority: visible ? "visible" : "overscan", rich: false };
23187
- }
23188
- function ClipLintDot({ element }) {
23189
- const lint = usePlayerStore((s) => s.lintFindingsByElement.get(element.key ?? element.id));
23190
- if (!lint || lint.count === 0) return null;
23191
- return /* @__PURE__ */ jsx65(
23192
- "span",
23193
- {
23194
- className: "absolute w-1.5 h-1.5 rounded-full bg-amber-400",
23195
- style: { top: 7, right: 7 },
23196
- title: lint.messages.join("\n")
23197
- }
23198
- );
23199
- }
23200
- function renderClipChildren(element, clipStyle, renderClipContent, renderClipOverlay, context = { priority: "visible", rich: false }) {
23201
- return /* @__PURE__ */ jsxs44(Fragment15, { children: [
23202
- renderClipOverlay?.(element),
23203
- !renderClipContent && /* @__PURE__ */ jsx65(ClipLintDot, { element }),
23204
- renderClipContent && // borderRadius: inherit — the clip itself is overflow-visible (keyframe
23205
- // diamonds hang outside its bounds), so the thumbnail layer must clip
23206
- // itself to the clip's rounded corners or sharp corners poke out.
23207
- /* @__PURE__ */ jsx65("div", { className: "absolute inset-0 overflow-hidden", style: { borderRadius: "inherit" }, children: renderClipContent(element, clipStyle, context) })
23208
- ] });
23209
- }
23210
-
23211
23241
  // src/player/components/useTimelineKeyboardActor.ts
23212
23242
  import { useCallback as useCallback29, useMemo as useMemo28 } from "react";
23213
23243
  function eventTarget(event) {
@@ -23416,8 +23446,7 @@ function TimelineClipJoins({
23416
23446
  // src/player/components/TimelineTransitionOverlays.tsx
23417
23447
  import { Fragment as Fragment16, jsx as jsx68, jsxs as jsxs46 } from "react/jsx-runtime";
23418
23448
  function TimelineTransitionOverlays({
23419
- transitionElements,
23420
- track: track2,
23449
+ seams,
23421
23450
  rowElements,
23422
23451
  rowBackground,
23423
23452
  pixelsPerSecond,
@@ -23425,9 +23454,6 @@ function TimelineTransitionOverlays({
23425
23454
  clipBarHeight
23426
23455
  }) {
23427
23456
  const top = CLIP_Y + (clipBarHeight ?? rowHeight - 2 * CLIP_Y) / 2;
23428
- const seams = deriveTimelineTransitionSeams(transitionElements).filter(
23429
- (seam) => seam.incoming.track === track2
23430
- );
23431
23457
  return /* @__PURE__ */ jsxs46(Fragment16, { children: [
23432
23458
  /* @__PURE__ */ jsx68(
23433
23459
  TimelineClipJoins,
@@ -23523,8 +23549,8 @@ function TimelineLanes({
23523
23549
  const expandedClipIds = usePlayerStore((s) => s.expandedClipIds);
23524
23550
  const { collapsedGroupIds, expandedLaneOwnerIds, toggleGroupExpanded, toggleLaneOwnerExpanded } = useTimelineGroupDisclosure();
23525
23551
  const automationLanes = useAutomationLanes();
23526
- const allTransitionElements = useMemo29(
23527
- () => tracks.flatMap(([, elements]) => elements.map(getPreviewElement)),
23552
+ const transitionSeamsByTrack = useMemo29(
23553
+ () => deriveTimelineTransitionSeamsByTrack(tracks.flatMap(([, els]) => els.map(getPreviewElement))),
23528
23554
  [getPreviewElement, tracks]
23529
23555
  );
23530
23556
  const compositionDuration = usePlayerStore((s) => s.duration);
@@ -23901,8 +23927,7 @@ function TimelineLanes({
23901
23927
  /* @__PURE__ */ jsx69(
23902
23928
  TimelineTransitionOverlays,
23903
23929
  {
23904
- transitionElements: allTransitionElements,
23905
- track: trackNum,
23930
+ seams: transitionSeamsByTrack.get(trackNum) ?? [],
23906
23931
  rowElements: draggedClip?.started ? [] : automationElements,
23907
23932
  rowBackground,
23908
23933
  pixelsPerSecond: pps,
@@ -24211,7 +24236,7 @@ var TimelineCanvas = memo13(function TimelineCanvas2() {
24211
24236
  import { useEffect as useEffect35 } from "react";
24212
24237
 
24213
24238
  // src/player/components/EditModal.tsx
24214
- import { useState as useState29, useCallback as useCallback30, useMemo as useMemo30, useRef as useRef45 } from "react";
24239
+ import { useState as useState30, useCallback as useCallback30, useMemo as useMemo30, useRef as useRef45 } from "react";
24215
24240
 
24216
24241
  // src/utils/clipboard.ts
24217
24242
  function copyWithSelection(text) {
@@ -24287,14 +24312,14 @@ function EditPopover({ rangeStart, rangeEnd, anchorX, anchorY, onClose }) {
24287
24312
  const start = Math.min(rangeStart, rangeEnd);
24288
24313
  const end = Math.max(rangeStart, rangeEnd);
24289
24314
  const storageKey = draftKey(start, end);
24290
- const [prompt, setPromptState] = useState29(() => readDraft(storageKey));
24315
+ const [prompt, setPromptState] = useState30(() => readDraft(storageKey));
24291
24316
  const setPrompt = (value) => {
24292
24317
  setPromptState(value);
24293
24318
  writeDraft(storageKey, value);
24294
24319
  };
24295
- const [copiedAgentPrompt, setCopiedAgentPrompt] = useState29(false);
24296
- const [copiedPromptOnly, setCopiedPromptOnly] = useState29(false);
24297
- const [copyError, setCopyError] = useState29(false);
24320
+ const [copiedAgentPrompt, setCopiedAgentPrompt] = useState30(false);
24321
+ const [copiedPromptOnly, setCopiedPromptOnly] = useState30(false);
24322
+ const [copyError, setCopyError] = useState30(false);
24298
24323
  const popoverRef = useRef45(null);
24299
24324
  const textareaRef = useRef45(null);
24300
24325
  const elementsInRange = useMemo30(() => {
@@ -24431,7 +24456,7 @@ function EditPopover({ rangeStart, rangeEnd, anchorX, anchorY, onClose }) {
24431
24456
  }
24432
24457
 
24433
24458
  // src/player/components/KeyframeDiamondContextMenu.tsx
24434
- import { useState as useState30 } from "react";
24459
+ import { useState as useState31 } from "react";
24435
24460
  import { createPortal as createPortal4 } from "react-dom";
24436
24461
 
24437
24462
  // src/player/components/menuKeyboardNav.ts
@@ -24492,7 +24517,7 @@ function KeyframeDiamondContextMenu({
24492
24517
  animationId: state.animationId
24493
24518
  };
24494
24519
  useMenuKeyboardNav(menuRef);
24495
- const [copyStatus, setCopyStatus] = useState30("idle");
24520
+ const [copyStatus, setCopyStatus] = useState31("idle");
24496
24521
  const handleCopyProperties = async () => {
24497
24522
  if (!onCopyProperties) return;
24498
24523
  const result = await onCopyProperties(state.elementId, keyframe);
@@ -25203,7 +25228,7 @@ var Timeline = Object.assign(TimelineComposed, {
25203
25228
  });
25204
25229
 
25205
25230
  // src/player/components/VideoThumbnail.tsx
25206
- import { memo as memo17, useCallback as useCallback32, useMemo as useMemo31, useRef as useRef47, useState as useState31 } from "react";
25231
+ import { memo as memo17, useCallback as useCallback32, useMemo as useMemo31, useRef as useRef47, useState as useState32 } from "react";
25207
25232
 
25208
25233
  // src/hooks/useThumbnailLease.ts
25209
25234
  import { useCallback as useCallback31, useLayoutEffect as useLayoutEffect5, useRef as useRef46, useSyncExternalStore as useSyncExternalStore2 } from "react";
@@ -25241,6 +25266,7 @@ var ThumbnailScheduler = class {
25241
25266
  nextLeaseId = 1;
25242
25267
  nextSequence = 1;
25243
25268
  scrolling = false;
25269
+ previewReloading = false;
25244
25270
  cacheBytes = 0;
25245
25271
  waveformCacheBytes = 0;
25246
25272
  activeByBucket = { video: 0, composition: 0, general: 0 };
@@ -25274,7 +25300,8 @@ var ThumbnailScheduler = class {
25274
25300
  disposed: false,
25275
25301
  cached: false,
25276
25302
  lastAccess: this.nextSequence++,
25277
- snapshot: Object.freeze({ status: "queued" })
25303
+ snapshot: Object.freeze({ status: "queued" }),
25304
+ preempted: false
25278
25305
  };
25279
25306
  this.entries.set(scopedKey, entry2);
25280
25307
  }
@@ -25323,6 +25350,23 @@ var ThumbnailScheduler = class {
25323
25350
  this.scrolling = scrolling;
25324
25351
  if (!scrolling) this.pump();
25325
25352
  }
25353
+ /**
25354
+ * Hold server-rendered composition thumbnails while the preview loads a new document: both
25355
+ * are served by the same Studio server, and the preview is what the person is waiting for.
25356
+ */
25357
+ setPreviewReloading(reloading) {
25358
+ if (this.previewReloading === reloading) return;
25359
+ this.previewReloading = reloading;
25360
+ if (!reloading) {
25361
+ this.pump();
25362
+ return;
25363
+ }
25364
+ for (const entry2 of this.entries.values()) {
25365
+ if (entry2.state !== "loading" || entry2.request.kind !== "composition") continue;
25366
+ entry2.preempted = true;
25367
+ entry2.controller?.abort();
25368
+ }
25369
+ }
25326
25370
  /** Evict project cache entries that are no longer owned by mounted consumers. */
25327
25371
  invalidateProject(projectId) {
25328
25372
  for (const [key2, entry2] of this.entries) {
@@ -25365,6 +25409,7 @@ var ThumbnailScheduler = class {
25365
25409
  });
25366
25410
  for (const entry2 of queued) {
25367
25411
  if (this.scrolling && entry2.request.rich) continue;
25412
+ if (this.previewReloading && entry2.request.kind === "composition") continue;
25368
25413
  const bucket = concurrencyBucket(entry2.request.kind);
25369
25414
  if (this.activeByBucket[bucket] >= this.bucketLimit(bucket)) continue;
25370
25415
  this.start(entry2, bucket);
@@ -25385,6 +25430,7 @@ var ThumbnailScheduler = class {
25385
25430
  this.deleteEntry(entry2.scopedKey, entry2);
25386
25431
  return;
25387
25432
  }
25433
+ if (this.requeuePreempted(entry2)) return;
25388
25434
  entry2.state = "error";
25389
25435
  entry2.error = errorFrom(reason);
25390
25436
  entry2.failedAt = this.now();
@@ -25401,6 +25447,7 @@ var ThumbnailScheduler = class {
25401
25447
  acceptResult(entry2, controller, result) {
25402
25448
  if (controller.signal.aborted || this.entries.get(entry2.scopedKey) !== entry2) {
25403
25449
  this.safeDispose(result.dispose);
25450
+ this.requeuePreempted(entry2);
25404
25451
  return;
25405
25452
  }
25406
25453
  this.validateResult(result);
@@ -25414,6 +25461,14 @@ var ThumbnailScheduler = class {
25414
25461
  this.evict();
25415
25462
  if (!entry2.cached && entry2.leases.size === 0) this.deleteEntry(entry2.scopedKey, entry2);
25416
25463
  }
25464
+ requeuePreempted(entry2) {
25465
+ if (!entry2.preempted || this.entries.get(entry2.scopedKey) !== entry2) return false;
25466
+ entry2.preempted = false;
25467
+ entry2.state = "queued";
25468
+ entry2.snapshot = Object.freeze({ status: "queued" });
25469
+ this.notify(entry2);
25470
+ return true;
25471
+ }
25417
25472
  validateResult(result) {
25418
25473
  if (Number.isFinite(result.weight) && result.weight >= 0) return;
25419
25474
  this.safeDispose(result.dispose);
@@ -25824,7 +25879,7 @@ var VideoThumbnail = memo17(function VideoThumbnail2({
25824
25879
  sessionEpoch = 0,
25825
25880
  priority = "visible"
25826
25881
  }) {
25827
- const [containerWidth, setContainerWidth] = useState31(0);
25882
+ const [containerWidth, setContainerWidth] = useState32(0);
25828
25883
  const observerRef = useRef47(null);
25829
25884
  const requestFrameCount = quantizeThumbnailFrameCount(
25830
25885
  computeThumbnailStrip(containerWidth, 16 / 9).frameCount
@@ -25924,7 +25979,7 @@ var VideoThumbnail = memo17(function VideoThumbnail2({
25924
25979
  });
25925
25980
 
25926
25981
  // src/player/components/CompositionThumbnail.tsx
25927
- import { memo as memo18, useCallback as useCallback33, useMemo as useMemo32, useRef as useRef48, useState as useState32 } from "react";
25982
+ import { memo as memo18, useCallback as useCallback33, useMemo as useMemo32, useRef as useRef48, useState as useState33 } from "react";
25928
25983
  import { jsx as jsx82, jsxs as jsxs58 } from "react/jsx-runtime";
25929
25984
  var CLIP_HEIGHT = 66;
25930
25985
  var THUMBNAIL_URL_VERSION = "v3";
@@ -25952,6 +26007,10 @@ function buildCompositionThumbnailUrl({
25952
26007
  }
25953
26008
  return thumbnailUrl2.toString();
25954
26009
  }
26010
+ function compositionPathOfPreviewUrl(previewUrl) {
26011
+ const match = /\/preview\/comp\/([^?#]+)/.exec(previewUrl);
26012
+ return match?.[1] ? decodeURIComponent(match[1]) : "index.html";
26013
+ }
25955
26014
  async function loadCompositionImage(url, signal) {
25956
26015
  const response = await fetch(url, { signal });
25957
26016
  if (!response.ok) throw new Error(`Composition thumbnail failed (${response.status})`);
@@ -25983,7 +26042,7 @@ var CompositionThumbnail = memo18(function CompositionThumbnail2({
25983
26042
  contentRevision = 0,
25984
26043
  priority = "visible"
25985
26044
  }) {
25986
- const [containerWidth, setContainerWidth] = useState32(0);
26045
+ const [containerWidth, setContainerWidth] = useState33(0);
25987
26046
  const observerRef = useRef48(null);
25988
26047
  const url = buildCompositionThumbnailUrl({
25989
26048
  previewUrl,
@@ -27739,7 +27798,7 @@ function useTimelineSyncCallbacks({
27739
27798
  }
27740
27799
 
27741
27800
  // src/player/hooks/useShadowPreviewReload.ts
27742
- import { useCallback as useCallback36, useRef as useRef51, useState as useState33 } from "react";
27801
+ import { useCallback as useCallback36, useRef as useRef51, useState as useState34 } from "react";
27743
27802
 
27744
27803
  // src/utils/studioDebug.ts
27745
27804
  function makeStudioDebugLogger(name) {
@@ -27797,7 +27856,7 @@ function useShadowPreviewReload({
27797
27856
  const budgetGenRef = useRef51(null);
27798
27857
  const cancelPendingLoadRef = useRef51(() => {
27799
27858
  });
27800
- const [previewSlots, setPreviewSlots] = useState33([{ gen: 0, role: "live" }]);
27859
+ const [previewSlots, setPreviewSlots] = useState34([{ gen: 0, role: "live" }]);
27801
27860
  const stopPendingShadow = useCallback36(() => {
27802
27861
  clearTimeout(readyTimerRef.current);
27803
27862
  budgetGenRef.current = null;
@@ -27814,6 +27873,7 @@ function useShadowPreviewReload({
27814
27873
  isRefreshingRef.current = false;
27815
27874
  pendingSeekRef.current = null;
27816
27875
  setPreviewSlots(planShadowDiscard);
27876
+ thumbnailScheduler.setPreviewReloading(false);
27817
27877
  const message = `The preview did not reload (${cause}). The previous preview is still showing.`;
27818
27878
  logReload("shadow-failed", { cause });
27819
27879
  console.error(`[studio] ${message}`);
@@ -27835,6 +27895,7 @@ function useShadowPreviewReload({
27835
27895
  applyPreviewAudioState();
27836
27896
  setPreviewSlots((prev) => planShadowPromotion(prev, gen));
27837
27897
  onPromotedRef.current?.();
27898
+ thumbnailScheduler.setPreviewReloading(false);
27838
27899
  },
27839
27900
  [stopPendingShadow, iframeRef, attachIframeShortcutListeners, applyPreviewAudioState]
27840
27901
  );
@@ -27900,6 +27961,7 @@ function useShadowPreviewReload({
27900
27961
  budgetGenRef.current = gen;
27901
27962
  armReadyTimer(gen);
27902
27963
  setPreviewSlots((prev) => planShadowReload(prev, gen, url));
27964
+ thumbnailScheduler.setPreviewReloading(true);
27903
27965
  },
27904
27966
  [stopPendingShadow, armReadyTimer]
27905
27967
  );
@@ -27910,6 +27972,7 @@ function useShadowPreviewReload({
27910
27972
  isRefreshingRef.current = false;
27911
27973
  pendingSeekRef.current = null;
27912
27974
  setPreviewSlots(planShadowDiscard);
27975
+ thumbnailScheduler.setPreviewReloading(false);
27913
27976
  }, [stopPendingShadow, isRefreshingRef, pendingSeekRef]);
27914
27977
  useMountEffect(() => {
27915
27978
  const onVisibilityChange = () => {
@@ -27924,6 +27987,7 @@ function useShadowPreviewReload({
27924
27987
  return () => {
27925
27988
  document.removeEventListener("visibilitychange", onVisibilityChange);
27926
27989
  stopPendingShadow();
27990
+ thumbnailScheduler.setPreviewReloading(false);
27927
27991
  };
27928
27992
  });
27929
27993
  return {
@@ -28794,16 +28858,16 @@ function useTimelinePlayer({
28794
28858
  import { useCallback as useCallback41, useMemo as useMemo33 } from "react";
28795
28859
 
28796
28860
  // src/components/nle/NLEContext.tsx
28797
- import { useContext as useContext8, useState as useState35, useCallback as useCallback40, useRef as useRef54, useEffect as useEffect38 } from "react";
28861
+ import { useContext as useContext8, useState as useState36, useCallback as useCallback40, useRef as useRef54, useEffect as useEffect38 } from "react";
28798
28862
 
28799
28863
  // src/components/nle/useCompositionStack.ts
28800
- import { useState as useState34, useCallback as useCallback39, useRef as useRef53, useEffect as useEffect37 } from "react";
28864
+ import { useState as useState35, useCallback as useCallback39, useRef as useRef53, useEffect as useEffect37 } from "react";
28801
28865
  function useCompositionStack({
28802
28866
  projectId,
28803
28867
  activeCompositionPath,
28804
28868
  onCompositionChange
28805
28869
  }) {
28806
- const [compositionStack, setCompositionStack] = useState34([
28870
+ const [compositionStack, setCompositionStack] = useState35([
28807
28871
  {
28808
28872
  id: "master",
28809
28873
  label: "Master",
@@ -28821,7 +28885,7 @@ function useCompositionStack({
28821
28885
  });
28822
28886
  }, []);
28823
28887
  const masterSeekRef = useRef53(0);
28824
- const [compIdToSrc, setCompIdToSrc] = useState34(/* @__PURE__ */ new Map());
28888
+ const [compIdToSrc, setCompIdToSrc] = useState35(/* @__PURE__ */ new Map());
28825
28889
  const compIdToSrcRef = useRef53(compIdToSrc);
28826
28890
  compIdToSrcRef.current = compIdToSrc;
28827
28891
  const handleNavigateComposition = useCallback39(
@@ -28955,7 +29019,7 @@ function NLEProvider({
28955
29019
  usePlayerStore.getState().beginTimelineSession(projectId);
28956
29020
  useAssetPreviewStore.getState().clearPreviewAsset();
28957
29021
  }, [projectId]);
28958
- const [previewCompositionSize, setPreviewCompositionSize] = useState35(null);
29022
+ const [previewCompositionSize, setPreviewCompositionSize] = useState36(null);
28959
29023
  const prevRefreshKeyRef = useRef54(refreshKey);
28960
29024
  useEffect38(() => {
28961
29025
  if (refreshKey === prevRefreshKeyRef.current) return;
@@ -29081,7 +29145,7 @@ function NLEProvider({
29081
29145
  });
29082
29146
  }, [compIdToSrc]);
29083
29147
  const hasLoadedOnceRef = useRef54(false);
29084
- const [compositionLoading, setCompositionLoadingRaw] = useState35(true);
29148
+ const [compositionLoading, setCompositionLoadingRaw] = useState36(true);
29085
29149
  const setCompositionLoading = useCallback40((loading) => {
29086
29150
  if (!loading) hasLoadedOnceRef.current = true;
29087
29151
  if (loading && hasLoadedOnceRef.current) return;
@@ -29200,7 +29264,7 @@ function readPreviewCompositionSize(iframe) {
29200
29264
  }
29201
29265
 
29202
29266
  // src/components/nle/NLEPreview.tsx
29203
- import { memo as memo19, useCallback as useCallback43, useEffect as useEffect39, useRef as useRef56, useState as useState36 } from "react";
29267
+ import { memo as memo19, useCallback as useCallback43, useEffect as useEffect39, useRef as useRef56, useState as useState37 } from "react";
29204
29268
 
29205
29269
  // src/components/nle/previewZoom.ts
29206
29270
  var MIN_PREVIEW_ZOOM_PERCENT = 25;
@@ -29434,11 +29498,11 @@ var NLEPreview = memo19(function NLEPreview2({
29434
29498
  }, [activeKey, resetPreviewSlots]);
29435
29499
  const liveGenRef = useRef56(null);
29436
29500
  const reportPreviewFirstFrame = usePreviewFirstFrameTelemetry(previewSlots);
29437
- const [compositionSize, setCompositionSize] = useState36(null);
29501
+ const [compositionSize, setCompositionSize] = useState37(null);
29438
29502
  const gutterPx = usePreviewGuidesStore((s) => s.rulerVisible ? RULER_GUTTER_PX : 0);
29439
- const [stageSize, setStageSize] = useState36(() => resolvePreviewStageSize(0, 0, null, portrait));
29503
+ const [stageSize, setStageSize] = useState37(() => resolvePreviewStageSize(0, 0, null, portrait));
29440
29504
  const zoomRef = useRef56(loadInitialZoom());
29441
- const [settledZoom, setSettledZoom] = useState36(() => zoomRef.current);
29505
+ const [settledZoom, setSettledZoom] = useState37(() => zoomRef.current);
29442
29506
  const hudRef = useRef56(null);
29443
29507
  const hudTimerRef = useRef56(null);
29444
29508
  const settleTimerRef = useRef56(null);
@@ -29840,7 +29904,7 @@ function CompositionBreadcrumb({ stack, onNavigate }) {
29840
29904
  }
29841
29905
 
29842
29906
  // src/components/nle/usePreviewBlockDrop.ts
29843
- import { useCallback as useCallback44, useRef as useRef57, useState as useState37 } from "react";
29907
+ import { useCallback as useCallback44, useRef as useRef57, useState as useState38 } from "react";
29844
29908
 
29845
29909
  // src/components/editor/previewReadOnlyContext.tsx
29846
29910
  import { useContext as useContext9, useMemo as useMemo34 } from "react";
@@ -29908,7 +29972,7 @@ function usePreviewBlockDrop({
29908
29972
  onBlockDrop: onBlockDropProp
29909
29973
  }) {
29910
29974
  const onBlockDrop = usePreviewReadOnly() ? void 0 : onBlockDropProp;
29911
- const [isDragOver, setIsDragOver] = useState37(false);
29975
+ const [isDragOver, setIsDragOver] = useState38(false);
29912
29976
  const dragDepthRef = useRef57(0);
29913
29977
  const handleDragEnter = useCallback44(
29914
29978
  (e) => {
@@ -30111,7 +30175,7 @@ function AssetPreviewOverlay() {
30111
30175
  import { memo as memo20, useRef as useRef60 } from "react";
30112
30176
 
30113
30177
  // src/components/editor/useDomEditCompositionRect.ts
30114
- import { useState as useState38 } from "react";
30178
+ import { useState as useState39 } from "react";
30115
30179
 
30116
30180
  // src/components/editor/overlayFrameLoop.ts
30117
30181
  var AWAKE_MS = 400;
@@ -30239,7 +30303,7 @@ function useDomEditCompositionRect({
30239
30303
  iframeRef,
30240
30304
  overlayRef
30241
30305
  }) {
30242
- const [compRect, setCompRect] = useState38({
30306
+ const [compRect, setCompRect] = useState39({
30243
30307
  left: 0,
30244
30308
  top: 0,
30245
30309
  width: 0,
@@ -30280,7 +30344,7 @@ function safeBoxInsetPercent(boxPercent) {
30280
30344
  }
30281
30345
 
30282
30346
  // src/components/editor/PreviewOverlayProvider.tsx
30283
- import { createContext as createContext4, useContext as useContext10, useRef as useRef59, useState as useState39 } from "react";
30347
+ import { createContext as createContext4, useContext as useContext10, useRef as useRef59, useState as useState40 } from "react";
30284
30348
 
30285
30349
  // src/components/editor/usePreviewCompositionRect.ts
30286
30350
  import { useEffect as useEffect41, useRef as useRef58 } from "react";
@@ -30322,7 +30386,7 @@ function readSnapPrefs() {
30322
30386
  }
30323
30387
  function PreviewOverlayProvider({ iframe, children }) {
30324
30388
  const overlayRef = useRef59(null);
30325
- const [snapPrefs, setSnapPrefs] = useState39(readSnapPrefs);
30389
+ const [snapPrefs, setSnapPrefs] = useState40(readSnapPrefs);
30326
30390
  const rulerVisible = usePreviewGuidesStore((state) => state.rulerVisible);
30327
30391
  const safeMarginsVisible = usePreviewGuidesStore((state) => state.safeMarginsVisible);
30328
30392
  const liveIframe = useLivePreviewIframe();
@@ -31100,7 +31164,7 @@ function TimelinePane({
31100
31164
  import { useCallback as useCallback59 } from "react";
31101
31165
 
31102
31166
  // src/captions/components/CaptionOverlay.tsx
31103
- import { memo as memo22, useEffect as useEffect43, useState as useState40, useCallback as useCallback48, useRef as useRef63 } from "react";
31167
+ import { memo as memo22, useEffect as useEffect43, useState as useState41, useCallback as useCallback48, useRef as useRef63 } from "react";
31104
31168
 
31105
31169
  // src/captions/keyboard.ts
31106
31170
  var CAPTION_NUDGE_KEYS = /* @__PURE__ */ new Set(["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"]);
@@ -31325,7 +31389,7 @@ var CaptionOverlay = memo22(function CaptionOverlay2({ iframeRef }) {
31325
31389
  const selectedSegmentIds = useCaptionStore((s) => s.selectedSegmentIds);
31326
31390
  const selectSegment = useCaptionStore((s) => s.selectSegment);
31327
31391
  const clearSelection = useCaptionStore((s) => s.clearSelection);
31328
- const [wordBoxes, setWordBoxes] = useState40([]);
31392
+ const [wordBoxes, setWordBoxes] = useState41([]);
31329
31393
  const overlayRef = useRef63(null);
31330
31394
  const modelRef = useRef63(model);
31331
31395
  modelRef.current = model;
@@ -31733,7 +31797,7 @@ var CaptionOverlay = memo22(function CaptionOverlay2({ iframeRef }) {
31733
31797
  import { memo as memo25, useEffect as useEffect51, useMemo as useMemo37, useRef as useRef73 } from "react";
31734
31798
 
31735
31799
  // src/components/editor/marqueeCommit.ts
31736
- import { useCallback as useCallback49, useRef as useRef64, useState as useState41 } from "react";
31800
+ import { useCallback as useCallback49, useRef as useRef64, useState as useState42 } from "react";
31737
31801
 
31738
31802
  // src/utils/studioPreviewHelpers.ts
31739
31803
  var FULL_BLEED_RATIO = 0.95;
@@ -32771,8 +32835,8 @@ async function runMarqueeIntersection(rect, candidates, activeCompositionPath) {
32771
32835
  }
32772
32836
  function useMarqueeGestures(deps) {
32773
32837
  const marqueeRef = useRef64(null);
32774
- const [marqueeRect, setMarqueeRect] = useState41(null);
32775
- const [candidateRects, setCandidateRects] = useState41([]);
32838
+ const [marqueeRect, setMarqueeRect] = useState42(null);
32839
+ const [candidateRects, setCandidateRects] = useState42([]);
32776
32840
  const candidatesRef = useRef64(null);
32777
32841
  const commitMarquee = useCallback49(
32778
32842
  async (rect, additive) => {
@@ -32895,11 +32959,11 @@ function MarqueeOverlay({ candidateRects, marqueeRect }) {
32895
32959
  }
32896
32960
 
32897
32961
  // src/components/editor/useZOrderCrossedFlash.tsx
32898
- import { useCallback as useCallback50, useEffect as useEffect44, useRef as useRef65, useState as useState42 } from "react";
32962
+ import { useCallback as useCallback50, useEffect as useEffect44, useRef as useRef65, useState as useState43 } from "react";
32899
32963
  import { jsx as jsx95 } from "react/jsx-runtime";
32900
32964
  var Z_ORDER_CROSSED_FLASH_MS = 600;
32901
32965
  function useZOrderCrossedFlash({ overlayRef, iframeRef }) {
32902
- const [zOrderFlashRect, setZOrderFlashRect] = useState42(null);
32966
+ const [zOrderFlashRect, setZOrderFlashRect] = useState43(null);
32903
32967
  const timeoutRef = useRef65(null);
32904
32968
  useEffect44(
32905
32969
  () => () => {
@@ -32939,7 +33003,7 @@ function ZOrderCrossedFlash({ rect }) {
32939
33003
  }
32940
33004
 
32941
33005
  // src/components/editor/useCanvasContextMenuState.ts
32942
- import { useCallback as useCallback51, useEffect as useEffect45, useState as useState43 } from "react";
33006
+ import { useCallback as useCallback51, useEffect as useEffect45, useState as useState44 } from "react";
32943
33007
  function useCanvasContextMenuState({
32944
33008
  selection,
32945
33009
  selectionRef,
@@ -32947,7 +33011,7 @@ function useCanvasContextMenuState({
32947
33011
  onCanvasPointerMoveRef,
32948
33012
  onSelectionChangeRef
32949
33013
  }) {
32950
- const [contextMenu, setContextMenu] = useState43(null);
33014
+ const [contextMenu, setContextMenu] = useState44(null);
32951
33015
  const closeContextMenu = useCallback51(() => setContextMenu(null), []);
32952
33016
  useEffect45(() => {
32953
33017
  if (!contextMenu) return;
@@ -33039,7 +33103,7 @@ function hasDomEditRotationChanged(initialAngle, nextAngle) {
33039
33103
  }
33040
33104
 
33041
33105
  // src/components/editor/useDomEditOverlayRects.ts
33042
- import { useRef as useRef66, useState as useState44 } from "react";
33106
+ import { useRef as useRef66, useState as useState45 } from "react";
33043
33107
  function childRectsEqual(a, b) {
33044
33108
  if (a.length !== b.length) return false;
33045
33109
  for (let i = 0; i < a.length; i++) {
@@ -33056,10 +33120,10 @@ function useDomEditOverlayRects({
33056
33120
  hoverSelectionRef,
33057
33121
  rafPausedRef
33058
33122
  }) {
33059
- const [overlayRect, setOverlayRectState] = useState44(null);
33060
- const [hoverRect, setHoverRectState] = useState44(null);
33061
- const [groupOverlayItems, setGroupOverlayItemsState] = useState44([]);
33062
- const [childRects, setChildRectsState] = useState44([]);
33123
+ const [overlayRect, setOverlayRectState] = useState45(null);
33124
+ const [hoverRect, setHoverRectState] = useState45(null);
33125
+ const [groupOverlayItems, setGroupOverlayItemsState] = useState45([]);
33126
+ const [childRects, setChildRectsState] = useState45([]);
33063
33127
  const overlayRectRef = useRef66(null);
33064
33128
  const hoverRectRef = useRef66(null);
33065
33129
  const groupOverlayItemsRef = useRef66([]);
@@ -33396,16 +33460,22 @@ function roundRotationAngle(angle) {
33396
33460
  function normalizeStudioFileChangePath(path) {
33397
33461
  return path.trim().replace(/\\/g, "/").replace(/^\.?\//, "");
33398
33462
  }
33463
+ function asPayloadRecord(payload) {
33464
+ return payload && typeof payload === "object" ? payload : null;
33465
+ }
33399
33466
  function readFileChangeField(payload, key2) {
33400
- if (!payload || typeof payload !== "object") return null;
33401
- const record = payload;
33402
- const value = record[key2];
33467
+ const value = asPayloadRecord(payload)?.[key2];
33403
33468
  return typeof value === "string" ? value : null;
33404
33469
  }
33405
33470
  function readStudioFileChangePath(payload) {
33406
33471
  const path = readFileChangeField(payload, "path") ?? readFileChangeField(payload, "filePath");
33407
33472
  return path === null ? null : normalizeStudioFileChangePath(path);
33408
33473
  }
33474
+ function readFileChangeAffectedCompositions(payload) {
33475
+ const value = asPayloadRecord(payload)?.affectedCompositions;
33476
+ if (!Array.isArray(value) || !value.every((path) => typeof path === "string")) return null;
33477
+ return value.map(normalizeStudioFileChangePath);
33478
+ }
33409
33479
 
33410
33480
  // src/components/editor/gsapAnimatesProperty.ts
33411
33481
  function gsapAnimatesProperty(el, ...props) {
@@ -34144,6 +34214,20 @@ function hasRemainingTimelineTime(owner) {
34144
34214
  if (time == null) return true;
34145
34215
  return time < duration;
34146
34216
  }
34217
+ function hasPausedAncestor(owner) {
34218
+ let ancestor = owner.parent;
34219
+ for (let depth = 0; depth < 32 && ancestor && typeof ancestor === "object"; depth++) {
34220
+ const node = ancestor;
34221
+ const paused = node.paused;
34222
+ try {
34223
+ if (typeof paused === "function" && paused.call(node)) return true;
34224
+ } catch {
34225
+ return false;
34226
+ }
34227
+ ancestor = node.parent;
34228
+ }
34229
+ return false;
34230
+ }
34147
34231
  function isTimelinePlaying(owner) {
34148
34232
  if (!owner) return false;
34149
34233
  const isPlaying = owner.isPlaying;
@@ -34169,6 +34253,7 @@ function isTimelinePlaying(owner) {
34169
34253
  return false;
34170
34254
  }
34171
34255
  }
34256
+ if (hasPausedAncestor(owner)) return false;
34172
34257
  return hasRemainingTimelineTime(owner);
34173
34258
  }
34174
34259
  const isActive = owner.isActive;
@@ -36263,7 +36348,7 @@ var SnapGuideOverlay = memo23(function SnapGuideOverlay2({
36263
36348
  });
36264
36349
 
36265
36350
  // src/components/editor/DomEditCropHandles.tsx
36266
- import { useEffect as useEffect47, useRef as useRef69, useState as useState45 } from "react";
36351
+ import { useEffect as useEffect47, useRef as useRef69, useState as useState46 } from "react";
36267
36352
  import { Fragment as Fragment25, jsx as jsx98, jsxs as jsxs69 } from "react/jsx-runtime";
36268
36353
  var EDGE_HIT_THICKNESS = 12;
36269
36354
  var EDGE_HIT_LENGTH = 32;
@@ -36297,14 +36382,14 @@ function DomEditCropHandles({
36297
36382
  onStyleCommit
36298
36383
  }) {
36299
36384
  const gestureRef = useRef69(null);
36300
- const [dragging, setDragging] = useState45(false);
36301
- const [hotEdge, setHotEdge] = useState45(null);
36385
+ const [dragging, setDragging] = useState46(false);
36386
+ const [hotEdge, setHotEdge] = useState46(null);
36302
36387
  const cropStateFor = (element) => {
36303
36388
  const parsed = readElementCropInsets(element);
36304
36389
  const { radius, ...insets } = parsed ?? { top: 0, right: 0, bottom: 0, left: 0, radius: 0 };
36305
36390
  return { element, croppable: parsed !== null, insets, radius };
36306
36391
  };
36307
- const [state, setState] = useState45(() => cropStateFor(selection.element));
36392
+ const [state, setState] = useState46(() => cropStateFor(selection.element));
36308
36393
  if (state.element !== selection.element) {
36309
36394
  setState(cropStateFor(selection.element));
36310
36395
  }
@@ -36982,7 +37067,7 @@ var CanvasContextMenu = memo24(function CanvasContextMenu2({
36982
37067
  import { useRef as useRef71 } from "react";
36983
37068
 
36984
37069
  // src/components/editor/InlineTextToolbar.tsx
36985
- import { useCallback as useCallback53, useEffect as useEffect48, useState as useState46 } from "react";
37070
+ import { useCallback as useCallback53, useEffect as useEffect48, useState as useState47 } from "react";
36986
37071
 
36987
37072
  // src/components/editor/inlineTextStyleRange.ts
36988
37073
  import {
@@ -37483,7 +37568,7 @@ function InlineTextToolbar({
37483
37568
  session,
37484
37569
  iframe
37485
37570
  }) {
37486
- const [placement, setPlacement] = useState46(null);
37571
+ const [placement, setPlacement] = useState47(null);
37487
37572
  const refresh = useCallback53(() => {
37488
37573
  setPlacement(session && iframe ? placeOverSelection(session.element, iframe) : null);
37489
37574
  }, [session, iframe]);
@@ -37673,7 +37758,7 @@ function toPickerColour(value, doc) {
37673
37758
  }
37674
37759
 
37675
37760
  // src/hooks/useInlineTextEdit.ts
37676
- import { useCallback as useCallback54, useEffect as useEffect49, useRef as useRef70, useState as useState47 } from "react";
37761
+ import { useCallback as useCallback54, useEffect as useEffect49, useRef as useRef70, useState as useState48 } from "react";
37677
37762
  import { sanitizeRichTextChildren } from "@hyperframes/core/rich-text-sanitize";
37678
37763
  var EDITABLE = "true";
37679
37764
  var EDITING_OUTLINE = "2px solid #3CE6AC";
@@ -37689,7 +37774,7 @@ function useInlineTextEdit({
37689
37774
  onPause
37690
37775
  }) {
37691
37776
  const readOnly = usePreviewReadOnly();
37692
- const [session, setSession] = useState47(null);
37777
+ const [session, setSession] = useState48(null);
37693
37778
  const openRef = useRef70(null);
37694
37779
  const framesRef = useRef70(null);
37695
37780
  const teardown = useCallback54(() => {
@@ -37939,7 +38024,7 @@ function useInlineTextEditing(selectionRef) {
37939
38024
  }
37940
38025
 
37941
38026
  // src/components/editor/useOffCanvasIndicators.ts
37942
- import { useEffect as useEffect50, useRef as useRef72, useState as useState48 } from "react";
38027
+ import { useEffect as useEffect50, useRef as useRef72, useState as useState49 } from "react";
37943
38028
 
37944
38029
  // src/components/editor/offCanvasIndicatorGeometry.ts
37945
38030
  function rounded(value) {
@@ -38096,7 +38181,7 @@ function useOffCanvasIndicators({
38096
38181
  activeCompositionPath
38097
38182
  }) {
38098
38183
  const offCanvasElementsRef = useRef72(/* @__PURE__ */ new Map());
38099
- const [offCanvasRects, setOffCanvasRects] = useState48([]);
38184
+ const [offCanvasRects, setOffCanvasRects] = useState49([]);
38100
38185
  const offCanvasDirtyRef = useRef72(true);
38101
38186
  const offCanvasSigRef = useRef72("");
38102
38187
  const offCanvasObserverRef = useRef72(null);
@@ -38512,7 +38597,7 @@ import {
38512
38597
  useLayoutEffect as useLayoutEffect6,
38513
38598
  useReducer,
38514
38599
  useRef as useRef74,
38515
- useState as useState49,
38600
+ useState as useState50,
38516
38601
  useSyncExternalStore as useSyncExternalStore4
38517
38602
  } from "react";
38518
38603
 
@@ -39347,7 +39432,7 @@ function TopologyLens({ iframeRef, activeCompositionPath }) {
39347
39432
  const overlayRef = useRef74(null);
39348
39433
  const state = useTopologyLensState();
39349
39434
  const reducedMotion = useSyncExternalStore4(subscribeReducedMotion, getReducedMotion, () => false);
39350
- const [measured, setMeasured] = useState49(null);
39435
+ const [measured, setMeasured] = useState50(null);
39351
39436
  const callId = state.phase === "hidden" ? null : state.callId;
39352
39437
  const handle = state.phase === "hidden" ? null : state.target.handle;
39353
39438
  const phase = state.phase;
@@ -39624,7 +39709,7 @@ function writeKeyframeCache(sourceFile, elementId2, data) {
39624
39709
  }
39625
39710
 
39626
39711
  // src/components/editor/MotionPathOverlay.tsx
39627
- import { memo as memo26, useEffect as useEffect54, useRef as useRef76, useState as useState51 } from "react";
39712
+ import { memo as memo26, useEffect as useEffect54, useRef as useRef76, useState as useState52 } from "react";
39628
39713
 
39629
39714
  // src/hooks/gestureTransaction.ts
39630
39715
  var transactionCounter = 0;
@@ -40355,7 +40440,7 @@ function commitCreatePath(targetSelector, position, x, y, commit) {
40355
40440
  }
40356
40441
 
40357
40442
  // src/components/editor/useMotionPathData.ts
40358
- import { useEffect as useEffect53, useRef as useRef75, useState as useState50 } from "react";
40443
+ import { useEffect as useEffect53, useRef as useRef75, useState as useState51 } from "react";
40359
40444
 
40360
40445
  // src/hooks/gsapRuntimeKeyframes.ts
40361
40446
  import { buildArcPath } from "@hyperframes/core/gsap-parser-acorn";
@@ -40662,13 +40747,13 @@ function hasMotionPathPlugin(iframe) {
40662
40747
  }
40663
40748
  }
40664
40749
  function useMotionPathData(iframeRef, selector) {
40665
- const [rect, setRect] = useState50(null);
40666
- const [geometry, setGeometry] = useState50(null);
40750
+ const [rect, setRect] = useState51(null);
40751
+ const [geometry, setGeometry] = useState51(null);
40667
40752
  const resolvedForRef = useRef75(null);
40668
40753
  const geometryResolved = resolvedForRef.current === selector;
40669
- const [visibleInPreview, setVisibleInPreview] = useState50(true);
40670
- const [home, setHome] = useState50(null);
40671
- const [pScale, setPScale] = useState50(1);
40754
+ const [visibleInPreview, setVisibleInPreview] = useState51(true);
40755
+ const [home, setHome] = useState51(null);
40756
+ const [pScale, setPScale] = useState51(1);
40672
40757
  useEffect53(() => {
40673
40758
  if (!selector) {
40674
40759
  setRect(null);
@@ -40754,10 +40839,10 @@ var MotionPathOverlay = memo26(function MotionPathOverlay2({
40754
40839
  iframeRef,
40755
40840
  selectorFor(selection)
40756
40841
  );
40757
- const [draft, setDraft] = useState51(null);
40758
- const [ghost, setGhost] = useState51(null);
40759
- const [hoverNode, setHoverNode] = useState51(null);
40760
- const [kfMenu, setKfMenu] = useState51(null);
40842
+ const [draft, setDraft] = useState52(null);
40843
+ const [ghost, setGhost] = useState52(null);
40844
+ const [hoverNode, setHoverNode] = useState52(null);
40845
+ const [kfMenu, setKfMenu] = useState52(null);
40761
40846
  const activeKeyframePct = usePlayerStore((s) => s.activeKeyframePct);
40762
40847
  const timelineElement = usePlayerStore((state) => {
40763
40848
  if (!selection) return void 0;
@@ -41111,11 +41196,11 @@ var MotionPathOverlay = memo26(function MotionPathOverlay2({
41111
41196
  });
41112
41197
 
41113
41198
  // src/components/editor/SnapToolbar.tsx
41114
- import { memo as memo27, useCallback as useCallback55, useEffect as useEffect55, useRef as useRef77, useState as useState52 } from "react";
41199
+ import { memo as memo27, useCallback as useCallback55, useEffect as useEffect55, useRef as useRef77, useState as useState53 } from "react";
41115
41200
  import { MagnetStraight, GridFour, Path, Ruler, FrameCorners } from "@phosphor-icons/react";
41116
41201
  import { jsx as jsx108, jsxs as jsxs78 } from "react/jsx-runtime";
41117
41202
  var SnapToolbar = memo27(function SnapToolbar2() {
41118
- const [gridPopoverOpen, setGridPopoverOpen] = useState52(false);
41203
+ const [gridPopoverOpen, setGridPopoverOpen] = useState53(false);
41119
41204
  const { state, actions } = usePreviewOverlayContext();
41120
41205
  const { snapPrefs: prefs, rulerVisible, safeMarginsVisible } = state;
41121
41206
  const motionPathCreateAvailable = usePlayerStore((s) => s.motionPathCreateAvailable);
@@ -41327,7 +41412,7 @@ var GridOverlay = memo28(function GridOverlay2() {
41327
41412
  });
41328
41413
 
41329
41414
  // src/hooks/useCompositionDimensions.ts
41330
- import { useEffect as useEffect56, useState as useState53 } from "react";
41415
+ import { useEffect as useEffect56, useState as useState54 } from "react";
41331
41416
  function readCompositionSizeMessage(data) {
41332
41417
  if (!isStageSizeMessage(data)) return null;
41333
41418
  const message = data;
@@ -41351,7 +41436,7 @@ function readPositiveDimensions(width, height) {
41351
41436
  return { width: parsedWidth, height: parsedHeight };
41352
41437
  }
41353
41438
  function useCompositionDimensions(iframeRef) {
41354
- const [compositionDimensions, setCompositionDimensions] = useState53(
41439
+ const [compositionDimensions, setCompositionDimensions] = useState54(
41355
41440
  null
41356
41441
  );
41357
41442
  const livePreviewIframe = useLivePreviewIframe();
@@ -43519,7 +43604,7 @@ function PreviewOverlays({
43519
43604
  import { useCallback as useCallback61, useMemo as useMemo39 } from "react";
43520
43605
 
43521
43606
  // src/hooks/useGsapTweenCache.ts
43522
- import { useEffect as useEffect58, useMemo as useMemo38, useRef as useRef80, useState as useState54, useCallback as useCallback60 } from "react";
43607
+ import { useEffect as useEffect58, useMemo as useMemo38, useRef as useRef80, useState as useState55, useCallback as useCallback60 } from "react";
43523
43608
 
43524
43609
  // src/hooks/gsapRuntimeReaders.ts
43525
43610
  import { classifyPropertyGroup as classifyPropertyGroup3 } from "@hyperframes/core/gsap-parser";
@@ -44448,9 +44533,9 @@ function getAnimationsForElement(animations, target, element) {
44448
44533
  );
44449
44534
  }
44450
44535
  function useGsapAnimationsForElement(projectId, sourceFile, target, version, iframeRef) {
44451
- const [allAnimations, setAllAnimations] = useState54([]);
44452
- const [multipleTimelines, setMultipleTimelines] = useState54(false);
44453
- const [unsupportedTimelinePattern, setUnsupportedTimelinePattern] = useState54(false);
44536
+ const [allAnimations, setAllAnimations] = useState55([]);
44537
+ const [multipleTimelines, setMultipleTimelines] = useState55(false);
44538
+ const [unsupportedTimelinePattern, setUnsupportedTimelinePattern] = useState55(false);
44454
44539
  const lastFetchKeyRef = useRef80("");
44455
44540
  const retryTimerRef = useRef80(null);
44456
44541
  const domClipChildrenKey = usePlayerStore(
@@ -44638,7 +44723,7 @@ function useGsapAnimationsForElement(projectId, sourceFile, target, version, ifr
44638
44723
  return { animations, multipleTimelines, unsupportedTimelinePattern };
44639
44724
  }
44640
44725
  function useGsapCacheVersion() {
44641
- const [version, setVersion] = useState54(0);
44726
+ const [version, setVersion] = useState55(0);
44642
44727
  const bump = useCallback60(() => setVersion((v) => v + 1), []);
44643
44728
  return { version, bump };
44644
44729
  }
@@ -47146,7 +47231,7 @@ var AudioWaveform = memo30(function AudioWaveform2({
47146
47231
  });
47147
47232
 
47148
47233
  // src/player/components/ImageThumbnail.tsx
47149
- import { memo as memo31, useCallback as useCallback66, useMemo as useMemo43, useRef as useRef84, useState as useState55 } from "react";
47234
+ import { memo as memo31, useCallback as useCallback66, useMemo as useMemo43, useRef as useRef84, useState as useState56 } from "react";
47150
47235
  import { jsx as jsx114, jsxs as jsxs83 } from "react/jsx-runtime";
47151
47236
  var ImageThumbnail = memo31(function ImageThumbnail2({
47152
47237
  imageSrc,
@@ -47157,7 +47242,7 @@ var ImageThumbnail = memo31(function ImageThumbnail2({
47157
47242
  priority = "visible",
47158
47243
  rich = false
47159
47244
  }) {
47160
- const [containerWidth, setContainerWidth] = useState55(0);
47245
+ const [containerWidth, setContainerWidth] = useState56(0);
47161
47246
  const observerRef = useRef84(null);
47162
47247
  const request = useMemo43(
47163
47248
  () => ({
@@ -47327,7 +47412,7 @@ function useRenderClipContent({
47327
47412
  const thumbnailMode = usePlayerStore((s) => s.thumbnailMode);
47328
47413
  const effectiveMode = effectiveThumbnailMode(thumbnailMode);
47329
47414
  const sessionEpoch = usePlayerStore((s) => s.timelineSessionEpoch);
47330
- const contentRevision = usePlayerStore((s) => s.thumbnailContentRevision);
47415
+ const thumbnailRevisions = usePlayerStore((s) => s.thumbnailRevisions);
47331
47416
  const elements = usePlayerStore((s) => s.elements);
47332
47417
  return useCallback67(
47333
47418
  // Pre-existing clip-content dispatcher; reduced by extracting renderAudioClip.
@@ -47355,7 +47440,7 @@ function useRenderClipContent({
47355
47440
  duration: el.duration,
47356
47441
  projectId: pid,
47357
47442
  sessionEpoch,
47358
- contentRevision,
47443
+ contentRevision: thumbnailRevisionOf(thumbnailRevisions, compSrc),
47359
47444
  priority: context.priority,
47360
47445
  rich: context.rich
47361
47446
  });
@@ -47374,7 +47459,10 @@ function useRenderClipContent({
47374
47459
  duration: el.duration,
47375
47460
  projectId: pid,
47376
47461
  sessionEpoch,
47377
- contentRevision,
47462
+ contentRevision: thumbnailRevisionOf(
47463
+ thumbnailRevisions,
47464
+ compositionPathOfPreviewUrl(activePreviewUrl)
47465
+ ),
47378
47466
  priority: context.priority,
47379
47467
  rich: context.rich
47380
47468
  });
@@ -47416,7 +47504,7 @@ function useRenderClipContent({
47416
47504
  duration: el.duration,
47417
47505
  projectId: pid,
47418
47506
  sessionEpoch,
47419
- contentRevision,
47507
+ contentRevision: thumbnailRevisionOf(thumbnailRevisions, "index.html"),
47420
47508
  priority: context.priority,
47421
47509
  rich: context.rich
47422
47510
  });
@@ -47430,7 +47518,7 @@ function useRenderClipContent({
47430
47518
  effectiveTimelineDuration,
47431
47519
  effectiveMode,
47432
47520
  sessionEpoch,
47433
- contentRevision,
47521
+ thumbnailRevisions,
47434
47522
  elements
47435
47523
  ]
47436
47524
  );
@@ -47567,7 +47655,7 @@ var SourceEditor = memo32(function SourceEditor2({
47567
47655
  });
47568
47656
 
47569
47657
  // src/components/editor/PropertyPanel.tsx
47570
- import { memo as memo36, useMemo as useMemo59, useRef as useRef116, useState as useState99 } from "react";
47658
+ import { memo as memo36, useMemo as useMemo59, useRef as useRef116, useState as useState100 } from "react";
47571
47659
 
47572
47660
  // src/components/editor/InspectorHeaderActions.tsx
47573
47661
  import { Eye as Eye3, EyeSlash as EyeSlash2 } from "@phosphor-icons/react";
@@ -48224,13 +48312,13 @@ function buildElementInfoText(element, sourceLabel, gsapAnimations, previewIfram
48224
48312
  }
48225
48313
 
48226
48314
  // src/components/editor/propertyPanelPrimitives.tsx
48227
- import { useCallback as useCallback71, useEffect as useEffect66, useRef as useRef88, useState as useState58 } from "react";
48315
+ import { useCallback as useCallback71, useEffect as useEffect66, useRef as useRef88, useState as useState59 } from "react";
48228
48316
 
48229
48317
  // src/components/editor/propertyPanelCommitField.tsx
48230
- import { useEffect as useEffect65, useRef as useRef87, useState as useState57 } from "react";
48318
+ import { useEffect as useEffect65, useRef as useRef87, useState as useState58 } from "react";
48231
48319
 
48232
48320
  // src/components/editor/useInspectorGestureTransaction.ts
48233
- import { useCallback as useCallback70, useEffect as useEffect64, useRef as useRef86, useState as useState56 } from "react";
48321
+ import { useCallback as useCallback70, useEffect as useEffect64, useRef as useRef86, useState as useState57 } from "react";
48234
48322
  function isPromiseCommit(result) {
48235
48323
  return Boolean(result && typeof result.then === "function");
48236
48324
  }
@@ -48330,7 +48418,7 @@ function useInspectorGestureDraft({
48330
48418
  onPreview,
48331
48419
  onCommit
48332
48420
  }) {
48333
- const [draft, setDraft] = useState56(sourceValue);
48421
+ const [draft, setDraft] = useState57(sourceValue);
48334
48422
  const transaction = useInspectorGestureTransaction({
48335
48423
  sourceValue,
48336
48424
  onPreview: (next) => {
@@ -48363,7 +48451,7 @@ function CommitField({
48363
48451
  onPreview,
48364
48452
  onCommit
48365
48453
  }) {
48366
- const [draft, setDraft] = useState57(value);
48454
+ const [draft, setDraft] = useState58(value);
48367
48455
  const valueRef = useRef87(value);
48368
48456
  const draftRef = useRef87(draft);
48369
48457
  const inputRef = useRef87(null);
@@ -48632,7 +48720,7 @@ function SliderControl({
48632
48720
  onCommit
48633
48721
  }) {
48634
48722
  const track2 = useTrackDesignInput();
48635
- const [draft, setDraft] = useState58(value);
48723
+ const [draft, setDraft] = useState59(value);
48636
48724
  const commitTimerRef = useRef88(null);
48637
48725
  const interactionChangedRef = useRef88(false);
48638
48726
  const valueRef = useRef88(value);
@@ -48750,7 +48838,7 @@ function Section({
48750
48838
  accessory,
48751
48839
  defaultCollapsed = false
48752
48840
  }) {
48753
- const [collapsed, setCollapsed] = useState58(defaultCollapsed);
48841
+ const [collapsed, setCollapsed] = useState59(defaultCollapsed);
48754
48842
  const collapseIcon = /* @__PURE__ */ jsx119(
48755
48843
  "svg",
48756
48844
  {
@@ -48874,7 +48962,7 @@ function createTransformCommitHandlers({
48874
48962
  import { resolveEditingSections } from "@hyperframes/core/editing";
48875
48963
 
48876
48964
  // src/components/editor/propertyPanelMediaSection.tsx
48877
- import { useEffect as useEffect67, useState as useState59 } from "react";
48965
+ import { useEffect as useEffect67, useState as useState60 } from "react";
48878
48966
  import {
48879
48967
  AUDIO_GAIN_FADER_MAX as AUDIO_GAIN_FADER_MAX2,
48880
48968
  AUDIO_GAIN_FADER_MIN as AUDIO_GAIN_FADER_MIN2,
@@ -48913,11 +49001,11 @@ function MediaSection({
48913
49001
  const sourceDuration = Number.parseFloat(element.dataAttributes["source-duration"] ?? "") || el.duration || 0;
48914
49002
  const mediaStartMax = Math.max(30, Math.ceil(sourceDuration || mediaStart + 10));
48915
49003
  const srcAttr = el.getAttribute("src") ?? "";
48916
- const [copied, setCopied] = useState59(false);
48917
- const [removeBusy, setRemoveBusy] = useState59(false);
48918
- const [removeProgress, setRemoveProgress] = useState59(null);
48919
- const [createPlate, setCreatePlate] = useState59(false);
48920
- const [quality, setQuality] = useState59("balanced");
49004
+ const [copied, setCopied] = useState60(false);
49005
+ const [removeBusy, setRemoveBusy] = useState60(false);
49006
+ const [removeProgress, setRemoveProgress] = useState60(null);
49007
+ const [createPlate, setCreatePlate] = useState60(false);
49008
+ const [quality, setQuality] = useState60("balanced");
48921
49009
  const absoluteSrc = projectDir && srcAttr && !srcAttr.startsWith("http") ? `${projectDir}/${srcAttr}` : srcAttr;
48922
49010
  const projectSrc = srcAttr && !/^(?:https?:|data:|blob:)/i.test(srcAttr) ? stripQueryAndHash(srcAttr.startsWith("./") ? srcAttr.slice(2) : srcAttr) : "";
48923
49011
  const canRemoveBackground = Boolean(onRemoveBackground && isVisualMedia && projectSrc);
@@ -49231,14 +49319,14 @@ function MediaSection({
49231
49319
  import { isHfColorGradingActive as isHfColorGradingActive2 } from "@hyperframes/core/color-grading";
49232
49320
 
49233
49321
  // src/components/editor/propertyPanelColorGradingControls.tsx
49234
- import { useMemo as useMemo45, useRef as useRef90, useState as useState61 } from "react";
49322
+ import { useMemo as useMemo45, useRef as useRef90, useState as useState62 } from "react";
49235
49323
  import {
49236
49324
  HF_COLOR_GRADING_PRESETS,
49237
49325
  normalizeHfColorGrading
49238
49326
  } from "@hyperframes/core/color-grading";
49239
49327
 
49240
49328
  // src/components/editor/propertyPanelColorGradingSlider.tsx
49241
- import { useCallback as useCallback72, useEffect as useEffect68, useRef as useRef89, useState as useState60 } from "react";
49329
+ import { useCallback as useCallback72, useEffect as useEffect68, useRef as useRef89, useState as useState61 } from "react";
49242
49330
  import { jsx as jsx121, jsxs as jsxs87 } from "react/jsx-runtime";
49243
49331
  var SLIDER_THUMB_SIZE = 10;
49244
49332
  var SLIDER_THUMB_RADIUS = SLIDER_THUMB_SIZE / 2;
@@ -49275,8 +49363,8 @@ function ColorGradingSliderControl({
49275
49363
  settings
49276
49364
  }) {
49277
49365
  const track2 = useTrackDesignInput();
49278
- const [draftState, setDraftState] = useState60(null);
49279
- const [inputDraft, setInputDraft] = useState60(null);
49366
+ const [draftState, setDraftState] = useState61(null);
49367
+ const [inputDraft, setInputDraft] = useState61(null);
49280
49368
  const commitTimerRef = useRef89(null);
49281
49369
  const interactionChangedRef = useRef89(false);
49282
49370
  const valueRef = useRef89(value);
@@ -49671,10 +49759,10 @@ function ColorGradingControls({
49671
49759
  }) {
49672
49760
  const track2 = useTrackDesignInput();
49673
49761
  const lutInputRef = useRef90(null);
49674
- const [lutOpen, setLutOpen] = useState61(false);
49675
- const [detailSettings, setDetailSettings] = useState61(null);
49676
- const [lutImporting, setLutImporting] = useState61(false);
49677
- const [lutImportError, setLutImportError] = useState61(null);
49762
+ const [lutOpen, setLutOpen] = useState62(false);
49763
+ const [detailSettings, setDetailSettings] = useState62(null);
49764
+ const [lutImporting, setLutImporting] = useState62(false);
49765
+ const [lutImportError, setLutImportError] = useState62(null);
49678
49766
  const lutAssets = useMemo45(
49679
49767
  () => assets.filter((asset) => LUT_EXT.test(asset)).sort((a, b) => a.localeCompare(b)),
49680
49768
  [assets]
@@ -49955,7 +50043,7 @@ function ColorGradingControls({
49955
50043
  }
49956
50044
 
49957
50045
  // src/components/editor/useColorGradingController.ts
49958
- import { useCallback as useCallback74, useEffect as useEffect70, useMemo as useMemo46, useRef as useRef92, useState as useState63 } from "react";
50046
+ import { useCallback as useCallback74, useEffect as useEffect70, useMemo as useMemo46, useRef as useRef92, useState as useState64 } from "react";
49959
50047
  import {
49960
50048
  HF_COLOR_GRADING_ATTR,
49961
50049
  hasHfColorGradingAuthoredValues,
@@ -50023,7 +50111,7 @@ function addStudioPendingEditFlushListener(handler) {
50023
50111
  }
50024
50112
 
50025
50113
  // src/components/editor/useColorGradingPreviews.ts
50026
- import { useCallback as useCallback73, useEffect as useEffect69, useRef as useRef91, useState as useState62 } from "react";
50114
+ import { useCallback as useCallback73, useEffect as useEffect69, useRef as useRef91, useState as useState63 } from "react";
50027
50115
  import {
50028
50116
  HF_COLOR_GRADING_ACTIVE_EFFECT_KEYS,
50029
50117
  HF_COLOR_GRADING_EFFECT_APPLY_DEFAULTS,
@@ -50092,11 +50180,11 @@ function useColorGradingPreviews({
50092
50180
  previewIframeRef,
50093
50181
  postColorGrading
50094
50182
  }) {
50095
- const [state, setState] = useState62(() => ({
50183
+ const [state, setState] = useState63(() => ({
50096
50184
  identityKey,
50097
50185
  previews: emptyPreviews()
50098
50186
  }));
50099
- const [request, setRequest] = useState62(null);
50187
+ const [request, setRequest] = useState63(null);
50100
50188
  const animatedRef = useRef91(null);
50101
50189
  if (state.identityKey !== identityKey) {
50102
50190
  setState({ identityKey, previews: emptyPreviews() });
@@ -50368,11 +50456,11 @@ function useColorGradingController({
50368
50456
  onSetAttributeLive,
50369
50457
  onApplyScope
50370
50458
  }) {
50371
- const [grading, setGrading] = useState63(() => readColorGradingFromElement(element));
50372
- const [compareEnabled, setCompareEnabled] = useState63(false);
50373
- const [applyScope, setApplyScope] = useState63("source-file");
50374
- const [applyBusy, setApplyBusy] = useState63(false);
50375
- const [runtimeStatus, setRuntimeStatus] = useState63(() => ({
50459
+ const [grading, setGrading] = useState64(() => readColorGradingFromElement(element));
50460
+ const [compareEnabled, setCompareEnabled] = useState64(false);
50461
+ const [applyScope, setApplyScope] = useState64("source-file");
50462
+ const [applyBusy, setApplyBusy] = useState64(false);
50463
+ const [runtimeStatus, setRuntimeStatus] = useState64(() => ({
50376
50464
  state: "pending",
50377
50465
  message: "Waiting for runtime"
50378
50466
  }));
@@ -50380,7 +50468,7 @@ function useColorGradingController({
50380
50468
  () => selectedMediaAssetPath(element, projectId),
50381
50469
  [element, projectId]
50382
50470
  );
50383
- const [mediaMetadata, setMediaMetadata] = useState63(null);
50471
+ const [mediaMetadata, setMediaMetadata] = useState64(null);
50384
50472
  const persistTimerRef = useRef92(null);
50385
50473
  const pendingPersistValueRef = useRef92(void 0);
50386
50474
  const pendingPersistGradingRef = useRef92(null);
@@ -50893,10 +50981,10 @@ function ColorGradingSection({
50893
50981
  }
50894
50982
 
50895
50983
  // src/components/editor/propertyPanelSections.tsx
50896
- import { useEffect as useEffect76, useRef as useRef97, useState as useState72 } from "react";
50984
+ import { useEffect as useEffect76, useRef as useRef97, useState as useState73 } from "react";
50897
50985
 
50898
50986
  // src/components/editor/propertyPanelColor.tsx
50899
- import { useCallback as useCallback75, useEffect as useEffect71, useLayoutEffect as useLayoutEffect7, useRef as useRef93, useState as useState64 } from "react";
50987
+ import { useCallback as useCallback75, useEffect as useEffect71, useLayoutEffect as useLayoutEffect7, useRef as useRef93, useState as useState65 } from "react";
50900
50988
  import { createPortal as createPortal8 } from "react-dom";
50901
50989
  import { jsx as jsx124, jsxs as jsxs90 } from "react/jsx-runtime";
50902
50990
  var COLOR_PICKER_SIZE = { width: 292, height: 386 };
@@ -51015,12 +51103,12 @@ function ColorField({
51015
51103
  const track2 = useTrackDesignInput();
51016
51104
  const buttonRef = useRef93(null);
51017
51105
  const panelRef = useRef93(null);
51018
- const [open, setOpen] = useState64(false);
51019
- const [panelPosition, setPanelPosition] = useState64(null);
51020
- const [draftColor, setDraftColor] = useState64(() => colorFromCss(value));
51106
+ const [open, setOpen] = useState65(false);
51107
+ const [panelPosition, setPanelPosition] = useState65(null);
51108
+ const [draftColor, setDraftColor] = useState65(() => colorFromCss(value));
51021
51109
  const draftColorRef = useRef93(draftColor);
51022
51110
  draftColorRef.current = draftColor;
51023
- const [hexDraft, setHexDraft] = useState64(() => toHexColor(colorFromCss(value)).toUpperCase());
51111
+ const [hexDraft, setHexDraft] = useState65(() => toHexColor(colorFromCss(value)).toUpperCase());
51024
51112
  const hsv = rgbToHsv(draftColor);
51025
51113
  const hueColor = formatCssColor({
51026
51114
  ...hsvToRgb({ hue: hsv.hue, saturation: 1, value: 1 }),
@@ -51403,7 +51491,7 @@ function ColorField({
51403
51491
  }
51404
51492
 
51405
51493
  // src/components/editor/propertyPanelFont.tsx
51406
- import { useEffect as useEffect72, useMemo as useMemo47, useRef as useRef94, useState as useState65 } from "react";
51494
+ import { useEffect as useEffect72, useMemo as useMemo47, useRef as useRef94, useState as useState66 } from "react";
51407
51495
 
51408
51496
  // src/components/editor/fontAssets.ts
51409
51497
  var FONT_EXT_RE = /\.(eot|otf|ttc|ttf|woff2?)$/i;
@@ -51520,16 +51608,16 @@ function FontFamilyField({
51520
51608
  const containerRef = useRef94(null);
51521
51609
  const inputRef = useRef94(null);
51522
51610
  const fontInputRef = useRef94(null);
51523
- const [open, setOpen] = useState65(false);
51524
- const [query, setQuery] = useState65("");
51525
- const [activeIndex, setActiveIndex] = useState65(-1);
51526
- const [localFonts, setLocalFonts] = useState65([]);
51527
- const [localFontData, setLocalFontData] = useState65([]);
51528
- const [googleFonts, setGoogleFonts] = useState65(() => [...POPULAR_GOOGLE_FONT_FAMILIES]);
51529
- const [loadingLocalFonts, setLoadingLocalFonts] = useState65(false);
51530
- const [loadingGoogleFonts, setLoadingGoogleFonts] = useState65(false);
51531
- const [importingFonts, setImportingFonts] = useState65(false);
51532
- const [fontNotice, setFontNotice] = useState65(null);
51611
+ const [open, setOpen] = useState66(false);
51612
+ const [query, setQuery] = useState66("");
51613
+ const [activeIndex, setActiveIndex] = useState66(-1);
51614
+ const [localFonts, setLocalFonts] = useState66([]);
51615
+ const [localFontData, setLocalFontData] = useState66([]);
51616
+ const [googleFonts, setGoogleFonts] = useState66(() => [...POPULAR_GOOGLE_FONT_FAMILIES]);
51617
+ const [loadingLocalFonts, setLoadingLocalFonts] = useState66(false);
51618
+ const [loadingGoogleFonts, setLoadingGoogleFonts] = useState66(false);
51619
+ const [importingFonts, setImportingFonts] = useState66(false);
51620
+ const [fontNotice, setFontNotice] = useState66(null);
51533
51621
  const canQueryLocalFonts = typeof window !== "undefined" && typeof window.queryLocalFonts === "function";
51534
51622
  const commitFontFamily = (nextValue) => {
51535
51623
  if (nextValue !== value) track2("select", "Font family");
@@ -51887,10 +51975,10 @@ function FontFamilyField({
51887
51975
  import { useEffect as useEffect74 } from "react";
51888
51976
 
51889
51977
  // src/components/panels/VariablesBindElement.tsx
51890
- import { useMemo as useMemo48, useState as useState67 } from "react";
51978
+ import { useMemo as useMemo48, useState as useState68 } from "react";
51891
51979
 
51892
51980
  // src/components/panels/VariablesValueControls.tsx
51893
- import { useState as useState66 } from "react";
51981
+ import { useState as useState67 } from "react";
51894
51982
  import { jsx as jsx126, jsxs as jsxs92 } from "react/jsx-runtime";
51895
51983
  var VARIABLES_INPUT_CLASS = "w-full bg-neutral-900 border border-neutral-800 rounded-sm px-2 py-1 text-[10px] text-neutral-200 focus:outline-hidden focus:border-neutral-700";
51896
51984
  function DraftTextInput({
@@ -51904,7 +51992,7 @@ function DraftTextInput({
51904
51992
  max,
51905
51993
  step
51906
51994
  }) {
51907
- const [draft, setDraft] = useState66(null);
51995
+ const [draft, setDraft] = useState67(null);
51908
51996
  return /* @__PURE__ */ jsx126(
51909
51997
  "input",
51910
51998
  {
@@ -51945,7 +52033,7 @@ function ColorControl({
51945
52033
  onCommit
51946
52034
  }) {
51947
52035
  const colorValue = typeof current === "string" ? current : "#000000";
51948
- const [draft, setDraft] = useState66(null);
52036
+ const [draft, setDraft] = useState67(null);
51949
52037
  return /* @__PURE__ */ jsxs92("div", { className: "flex items-center gap-2", children: [
51950
52038
  /* @__PURE__ */ jsx126(
51951
52039
  "input",
@@ -51977,7 +52065,7 @@ function NumberControl({
51977
52065
  }) {
51978
52066
  const numberValue = typeof current === "number" ? current : Number(current) || 0;
51979
52067
  const hasRange = decl.min !== void 0 && decl.max !== void 0;
51980
- const [dragValue, setDragValue] = useState66(null);
52068
+ const [dragValue, setDragValue] = useState67(null);
51981
52069
  const commitDrag = () => {
51982
52070
  if (dragValue !== null && dragValue !== numberValue) onCommit(dragValue);
51983
52071
  setDragValue(null);
@@ -52167,8 +52255,8 @@ function VariablesBindElement({
52167
52255
  sdkSession,
52168
52256
  onBind
52169
52257
  }) {
52170
- const [activeKey, setActiveKey] = useState67(null);
52171
- const [idDraft, setIdDraft] = useState67("");
52258
+ const [activeKey, setActiveKey] = useState68(null);
52259
+ const [idDraft, setIdDraft] = useState68("");
52172
52260
  const actions = useMemo48(() => buildBindActions(selection, sdkSession), [selection, sdkSession]);
52173
52261
  if (actions.length === 0) return null;
52174
52262
  const active = actions.find((a) => a.key === activeKey) ?? null;
@@ -52280,7 +52368,7 @@ function uniqueId(base2, existing) {
52280
52368
  }
52281
52369
 
52282
52370
  // src/contexts/VariablePromoteContext.tsx
52283
- import { useContext as useContext12, useEffect as useEffect73, useMemo as useMemo49, useState as useState68 } from "react";
52371
+ import { useContext as useContext12, useEffect as useEffect73, useMemo as useMemo49, useState as useState69 } from "react";
52284
52372
  import { jsx as jsx128 } from "react/jsx-runtime";
52285
52373
  var VariablePromoteContext = createStableContext(
52286
52374
  "VariablePromoteContext",
@@ -52298,7 +52386,7 @@ function VariablePromoteProvider({
52298
52386
  onPersistError,
52299
52387
  children
52300
52388
  }) {
52301
- const [revision, setRevision] = useState68(0);
52389
+ const [revision, setRevision] = useState69(0);
52302
52390
  useEffect73(() => {
52303
52391
  if (!session) return;
52304
52392
  return session.on("change", () => setRevision((r) => r + 1));
@@ -52411,7 +52499,7 @@ function PromotableControl({
52411
52499
  }
52412
52500
 
52413
52501
  // src/components/editor/propertyPanelStyleSections.tsx
52414
- import { useEffect as useEffect75, useRef as useRef96, useState as useState71 } from "react";
52502
+ import { useEffect as useEffect75, useRef as useRef96, useState as useState72 } from "react";
52415
52503
 
52416
52504
  // src/components/editor/gradientValue.ts
52417
52505
  var RADIAL_SIZE_KEYWORDS = [
@@ -52755,7 +52843,7 @@ function parseColorString(value) {
52755
52843
  }
52756
52844
 
52757
52845
  // src/components/editor/propertyPanelFill.tsx
52758
- import { useMemo as useMemo50, useRef as useRef95, useState as useState69 } from "react";
52846
+ import { useMemo as useMemo50, useRef as useRef95, useState as useState70 } from "react";
52759
52847
 
52760
52848
  // src/components/icons/ReverseGradientIcon.tsx
52761
52849
  import { jsx as jsx130, jsxs as jsxs95 } from "react/jsx-runtime";
@@ -52828,8 +52916,8 @@ function ImageFillField({
52828
52916
  }) {
52829
52917
  const track2 = useTrackDesignInput();
52830
52918
  const fileInputRef = useRef95(null);
52831
- const [uploading, setUploading] = useState69(false);
52832
- const [uploadError, setUploadError] = useState69(null);
52919
+ const [uploading, setUploading] = useState70(false);
52920
+ const [uploadError, setUploadError] = useState70(null);
52833
52921
  const imageAssets = useMemo50(() => assets.filter((a) => IMAGE_EXT.test(a)), [assets]);
52834
52922
  const selectedAsset = useMemo50(
52835
52923
  () => resolveSelectedAsset(value, sourceFile, imageAssets),
@@ -53217,7 +53305,7 @@ function GradientField({
53217
53305
  }
53218
53306
 
53219
53307
  // src/components/editor/BorderRadiusEditor.tsx
53220
- import { useCallback as useCallback76, useState as useState70 } from "react";
53308
+ import { useCallback as useCallback76, useState as useState71 } from "react";
53221
53309
  import { jsx as jsx132, jsxs as jsxs97 } from "react/jsx-runtime";
53222
53310
  var PREVIEW_W = 72;
53223
53311
  var PREVIEW_H = 52;
@@ -53238,7 +53326,7 @@ function BorderRadiusEditor({
53238
53326
  onCommit
53239
53327
  }) {
53240
53328
  const uniform = tl === tr && tr === br && br === bl;
53241
- const [linked, setLinked] = useState70(uniform);
53329
+ const [linked, setLinked] = useState71(uniform);
53242
53330
  const maxVal = Math.max(tl, tr, br, bl, 1);
53243
53331
  const sTL = scaleRadius(tl, maxVal);
53244
53332
  const sTR = scaleRadius(tr, maxVal);
@@ -53440,7 +53528,7 @@ function StyleSections({
53440
53528
  const backgroundImage = styles["background-image"] ?? "none";
53441
53529
  const hasTextControls = isTextEditableSelection(element);
53442
53530
  const fillMode = backgroundImage && backgroundImage !== "none" ? backgroundImage.includes("gradient") ? "Gradient" : "Image" : "Solid";
53443
- const [preferredFillMode, setPreferredFillMode] = useState71(fillMode);
53531
+ const [preferredFillMode, setPreferredFillMode] = useState72(fillMode);
53444
53532
  const imageUrl = extractBackgroundImageUrl(backgroundImage);
53445
53533
  const lastGradientRef = useRef96(
53446
53534
  backgroundImage.includes("gradient") ? backgroundImage : null
@@ -53897,7 +53985,7 @@ function TextAreaField({
53897
53985
  onCommit
53898
53986
  }) {
53899
53987
  const track2 = useTrackDesignInput();
53900
- const [draft, setDraft] = useState72(value);
53988
+ const [draft, setDraft] = useState73(value);
53901
53989
  const textareaRef = useRef97(null);
53902
53990
  const commitTimerRef = useRef97(null);
53903
53991
  const interactionChangedRef = useRef97(false);
@@ -54208,7 +54296,7 @@ function TextSection({
54208
54296
  }) {
54209
54297
  const track2 = useTrackDesignInput();
54210
54298
  const hasTextControls = isTextEditableSelection(element);
54211
- const [activeTextFieldKey, setActiveTextFieldKey] = useState72(
54299
+ const [activeTextFieldKey, setActiveTextFieldKey] = useState73(
54212
54300
  element.textFields[0]?.key ?? null
54213
54301
  );
54214
54302
  useEffect76(() => {
@@ -54309,11 +54397,11 @@ function TextSection({
54309
54397
  import { memo as memo35 } from "react";
54310
54398
 
54311
54399
  // src/components/editor/GsapAnimationList.tsx
54312
- import { useCallback as useCallback79, useState as useState74 } from "react";
54400
+ import { useCallback as useCallback79, useState as useState75 } from "react";
54313
54401
  import { useShallow } from "zustand/react/shallow";
54314
54402
 
54315
54403
  // src/components/editor/AnimationCard.tsx
54316
- import { memo as memo34, useCallback as useCallback78, useEffect as useEffect77, useMemo as useMemo51, useRef as useRef98, useState as useState73 } from "react";
54404
+ import { memo as memo34, useCallback as useCallback78, useEffect as useEffect77, useMemo as useMemo51, useRef as useRef98, useState as useState74 } from "react";
54317
54405
  import { SUPPORTED_EASES, SUPPORTED_PROPS } from "@hyperframes/core/gsap-constants";
54318
54406
 
54319
54407
  // src/components/editor/gsapAnimationHelpers.ts
@@ -54831,11 +54919,11 @@ var AnimationCard = memo34(function AnimationCard2({
54831
54919
  onSetAllKeyframeEases,
54832
54920
  onUnroll
54833
54921
  }) {
54834
- const [expanded, setExpanded] = useState73(defaultExpanded);
54835
- const [addingProp, setAddingProp] = useState73(false);
54836
- const [addingFromProp, setAddingFromProp] = useState73(false);
54837
- const [expandedKfPct, setExpandedKfPct] = useState73(null);
54838
- const [focusedCollidingAnimationTargets, setFocusedCollidingAnimationTargets] = useState73();
54922
+ const [expanded, setExpanded] = useState74(defaultExpanded);
54923
+ const [addingProp, setAddingProp] = useState74(false);
54924
+ const [addingFromProp, setAddingFromProp] = useState74(false);
54925
+ const [expandedKfPct, setExpandedKfPct] = useState74(null);
54926
+ const [focusedCollidingAnimationTargets, setFocusedCollidingAnimationTargets] = useState74();
54839
54927
  const cardRef = useRef98(null);
54840
54928
  const pendingAutoScrollRef = useRef98(false);
54841
54929
  useEffect77(() => {
@@ -54910,7 +54998,7 @@ var AnimationCard = memo34(function AnimationCard2({
54910
54998
  },
54911
54999
  [animation.id, onUpdateMeta]
54912
55000
  );
54913
- const [copied, setCopied] = useState73(false);
55001
+ const [copied, setCopied] = useState74(false);
54914
55002
  const methodLabel = METHOD_LABELS[animation.method] ?? animation.method;
54915
55003
  const easeName = (animation.keyframes ? animation.keyframes.easeEach : void 0) ?? animation.ease ?? "none";
54916
55004
  const easeLabel = easeName.startsWith("custom(") ? "Custom curve" : EASE_LABELS[easeName] ?? easeName;
@@ -55342,7 +55430,7 @@ function GsapAnimationList({
55342
55430
  ...callbacks
55343
55431
  }) {
55344
55432
  const track2 = useTrackDesignInput();
55345
- const [addMenuOpen, setAddMenuOpen] = useState74(false);
55433
+ const [addMenuOpen, setAddMenuOpen] = useState75(false);
55346
55434
  const trackedCallbacks = withTrackedGsapAnimationCallbacks(callbacks, track2);
55347
55435
  const { focusedEaseSegment, timelineProjectId, timelineSessionEpoch, selectedElementId } = usePlayerStore(
55348
55436
  useShallow((state) => ({
@@ -55416,10 +55504,10 @@ var GsapAnimationSection = memo35(function GsapAnimationSection2({
55416
55504
  });
55417
55505
 
55418
55506
  // src/components/editor/propertyPanel3dTransform.tsx
55419
- import { useState as useState76 } from "react";
55507
+ import { useState as useState77 } from "react";
55420
55508
 
55421
55509
  // src/components/editor/Transform3DCube.tsx
55422
- import { useEffect as useEffect78, useRef as useRef99, useState as useState75 } from "react";
55510
+ import { useEffect as useEffect78, useRef as useRef99, useState as useState76 } from "react";
55423
55511
 
55424
55512
  // src/components/editor/transform3dProjection.ts
55425
55513
  var DEG = Math.PI / 180;
@@ -55533,8 +55621,8 @@ function Transform3DCube({
55533
55621
  onKeyframe,
55534
55622
  keyframed
55535
55623
  }) {
55536
- const [draft, setDraft] = useState75(null);
55537
- const [depthDraft, setDepthDraft] = useState75(null);
55624
+ const [draft, setDraft] = useState76(null);
55625
+ const [depthDraft, setDepthDraft] = useState76(null);
55538
55626
  const dragRef = useRef99(null);
55539
55627
  const shown2 = draft ?? pose;
55540
55628
  const shownZ = depthDraft ?? z;
@@ -55930,7 +56018,7 @@ function PropertyPanel3dTransform({
55930
56018
  onConvertToKeyframes,
55931
56019
  onLivePreviewProps
55932
56020
  }) {
55933
- const [collapsed, setCollapsed] = useState76(false);
56021
+ const [collapsed, setCollapsed] = useState77(false);
55934
56022
  const ctx3 = {
55935
56023
  element,
55936
56024
  gsapRuntimeValues,
@@ -56063,7 +56151,7 @@ function PropertyPanel3dTransform({
56063
56151
  }
56064
56152
 
56065
56153
  // src/components/editor/PropertyPanelFlat.tsx
56066
- import { useEffect as useEffect98, useMemo as useMemo58, useRef as useRef115, useState as useState98 } from "react";
56154
+ import { useEffect as useEffect98, useMemo as useMemo58, useRef as useRef115, useState as useState99 } from "react";
56067
56155
  import { useShallow as useShallow2 } from "zustand/react/shallow";
56068
56156
 
56069
56157
  // src/components/editor/audioFxSummary.ts
@@ -56273,10 +56361,10 @@ function PropertyPanelFlatFooter({
56273
56361
  }
56274
56362
 
56275
56363
  // src/components/editor/propertyPanelFlatPrimitives.tsx
56276
- import { useEffect as useEffect80, useRef as useRef101, useState as useState78 } from "react";
56364
+ import { useEffect as useEffect80, useRef as useRef101, useState as useState79 } from "react";
56277
56365
 
56278
56366
  // src/components/editor/propertyPanelFlatSliderReadout.tsx
56279
- import { useEffect as useEffect79, useRef as useRef100, useState as useState77 } from "react";
56367
+ import { useEffect as useEffect79, useRef as useRef100, useState as useState78 } from "react";
56280
56368
  import { jsx as jsx147 } from "react/jsx-runtime";
56281
56369
  function FlatSliderReadout({
56282
56370
  label,
@@ -56286,9 +56374,9 @@ function FlatSliderReadout({
56286
56374
  onCommitText,
56287
56375
  onCommitted
56288
56376
  }) {
56289
- const [editing, setEditing] = useState77(false);
56290
- const [text, setText] = useState77("");
56291
- const [invalid, setInvalid] = useState77(false);
56377
+ const [editing, setEditing] = useState78(false);
56378
+ const [text, setText] = useState78("");
56379
+ const [invalid, setInvalid] = useState78(false);
56292
56380
  const inputRef = useRef100(null);
56293
56381
  const editable = Boolean(onCommitText) && !disabled;
56294
56382
  useEffect79(() => {
@@ -56634,7 +56722,7 @@ function FlatSlider({
56634
56722
  onCommitText
56635
56723
  }) {
56636
56724
  const track2 = useTrackDesignInput();
56637
- const [draft, setDraft] = useState78(value);
56725
+ const [draft, setDraft] = useState79(value);
56638
56726
  const commitTimerRef = useRef101(null);
56639
56727
  const lastCommitAtRef = useRef101(0);
56640
56728
  const pendingRef = useRef101(null);
@@ -56857,7 +56945,7 @@ function isSelectionHidden(fromTimeline, element) {
56857
56945
  }
56858
56946
 
56859
56947
  // src/components/editor/propertyPanelFlatTextSection.tsx
56860
- import { useEffect as useEffect81, useState as useState79 } from "react";
56948
+ import { useEffect as useEffect81, useState as useState80 } from "react";
56861
56949
  import { Fragment as Fragment36, jsx as jsx151, jsxs as jsxs114 } from "react/jsx-runtime";
56862
56950
  var ALIGN_OPTIONS = [
56863
56951
  { key: "left", label: "left", node: "L" },
@@ -57066,10 +57154,10 @@ function FlatTextSection({
57066
57154
  onRemoveTextField
57067
57155
  }) {
57068
57156
  const track2 = useTrackDesignInput();
57069
- const [activeFieldKey, setActiveFieldKey] = useState79(
57157
+ const [activeFieldKey, setActiveFieldKey] = useState80(
57070
57158
  element.textFields[0]?.key ?? null
57071
57159
  );
57072
- const [autoFocusFieldKey, setAutoFocusFieldKey] = useState79(null);
57160
+ const [autoFocusFieldKey, setAutoFocusFieldKey] = useState80(null);
57073
57161
  useEffect81(() => {
57074
57162
  const nextFields = element.textFields;
57075
57163
  setActiveFieldKey((current) => {
@@ -57222,7 +57310,7 @@ function FlatTextLayerList({
57222
57310
  }
57223
57311
 
57224
57312
  // src/components/editor/propertyPanelFlatStyleSections.tsx
57225
- import { useEffect as useEffect82, useState as useState80 } from "react";
57313
+ import { useEffect as useEffect82, useState as useState81 } from "react";
57226
57314
 
57227
57315
  // src/components/editor/propertyPanelFlatStyleHelpers.ts
57228
57316
  var STROKE_STYLE_OPTIONS = [
@@ -57340,7 +57428,7 @@ function FlatFillFields({
57340
57428
  const backgroundImage = styles["background-image"] ?? "none";
57341
57429
  const hasTextControls = isTextEditableSelection(element);
57342
57430
  const fillMode = backgroundImage && backgroundImage !== "none" ? backgroundImage.includes("gradient") ? "Gradient" : "Image" : "Solid";
57343
- const [preferredFillMode, setPreferredFillMode] = useState80(fillMode);
57431
+ const [preferredFillMode, setPreferredFillMode] = useState81(fillMode);
57344
57432
  const imageUrl = extractBackgroundImageUrl(backgroundImage);
57345
57433
  useEffect82(() => {
57346
57434
  setPreferredFillMode(fillMode);
@@ -58233,7 +58321,7 @@ function motionSectionLabel(args) {
58233
58321
  }
58234
58322
 
58235
58323
  // src/components/editor/propertyPanelAudioFxGroup.tsx
58236
- import { useMemo as useMemo54, useState as useState86 } from "react";
58324
+ import { useMemo as useMemo54, useState as useState87 } from "react";
58237
58325
  import {
58238
58326
  HF_AUDIO_FX_ATTR as HF_AUDIO_FX_ATTR6,
58239
58327
  HF_AUDIO_FX_DATA_KEY as HF_AUDIO_FX_DATA_KEY2,
@@ -58296,7 +58384,7 @@ function automationAttrValue(automation) {
58296
58384
  }
58297
58385
 
58298
58386
  // src/components/editor/propertyPanelFxSection.tsx
58299
- import { useCallback as useCallback82, useEffect as useEffect85, useMemo as useMemo53, useRef as useRef103, useState as useState84 } from "react";
58387
+ import { useCallback as useCallback82, useEffect as useEffect85, useMemo as useMemo53, useRef as useRef103, useState as useState85 } from "react";
58300
58388
 
58301
58389
  // src/components/editor/audioFxRevealTarget.ts
58302
58390
  import { parseAutomationTarget as parseAutomationTarget2 } from "@hyperframes/core/audio-automation";
@@ -58376,7 +58464,7 @@ import { DEFAULT_CARVE } from "@hyperframes/core/audio-carve";
58376
58464
  import { fxAutomationTarget as fxAutomationTarget2 } from "@hyperframes/core/audio-automation";
58377
58465
 
58378
58466
  // src/components/editor/propertyPanelFxControls.tsx
58379
- import { useCallback as useCallback80, useEffect as useEffect83, useRef as useRef102, useState as useState81 } from "react";
58467
+ import { useCallback as useCallback80, useEffect as useEffect83, useRef as useRef102, useState as useState82 } from "react";
58380
58468
  import { jsx as jsx157, jsxs as jsxs120 } from "react/jsx-runtime";
58381
58469
  function toSlider(p, value) {
58382
58470
  if (p.scale !== "log" || p.min <= 0) return value;
@@ -58423,11 +58511,11 @@ function FxParamRow({
58423
58511
  onAutomate,
58424
58512
  onRemoveAutomation
58425
58513
  }) {
58426
- const [dragging, setDragging] = useState81(false);
58427
- const [local, setLocal] = useState81(value);
58514
+ const [dragging, setDragging] = useState82(false);
58515
+ const [local, setLocal] = useState82(value);
58428
58516
  const latest = useRef102(value);
58429
- const [pending2, setPending] = useState81(null);
58430
- const [typing, setTyping] = useState81(null);
58517
+ const [pending2, setPending] = useState82(null);
58518
+ const [typing, setTyping] = useState82(null);
58431
58519
  const edited = useRef102(false);
58432
58520
  useEffect83(() => {
58433
58521
  if (!dragging) setLocal(value);
@@ -59085,7 +59173,7 @@ function CarveAnalysis({
59085
59173
  }
59086
59174
 
59087
59175
  // src/components/editor/propertyPanelFxEqModule.tsx
59088
- import { useCallback as useCallback81, useEffect as useEffect84, useState as useState82 } from "react";
59176
+ import { useCallback as useCallback81, useEffect as useEffect84, useState as useState83 } from "react";
59089
59177
  import {
59090
59178
  audioEqSummary,
59091
59179
  HF_AUDIO_EQ_RANGE_DB
@@ -59105,8 +59193,8 @@ function Fader2({
59105
59193
  onPreview,
59106
59194
  onCommit
59107
59195
  }) {
59108
- const [local, setLocal] = useState82(band.gain);
59109
- const [dragging, setDragging] = useState82(false);
59196
+ const [local, setLocal] = useState83(band.gain);
59197
+ const [dragging, setDragging] = useState83(false);
59110
59198
  useEffect84(() => {
59111
59199
  if (!dragging) setLocal(band.gain);
59112
59200
  }, [band.gain, dragging]);
@@ -59243,7 +59331,7 @@ function FxEqModule({
59243
59331
  import { getAudioFxPreset as getAudioFxPreset3 } from "@hyperframes/core/audio-fx-presets";
59244
59332
 
59245
59333
  // src/components/editor/propertyPanelFxNodeRow.tsx
59246
- import { useMemo as useMemo52, useState as useState83 } from "react";
59334
+ import { useMemo as useMemo52, useState as useState84 } from "react";
59247
59335
  import {
59248
59336
  defaultAudioFxParams as defaultAudioFxParams3,
59249
59337
  getAudioFxDef as getAudioFxDef3
@@ -59677,7 +59765,7 @@ function FxNodeRow({
59677
59765
  () => def && primary ? { ...def, params: def.params.filter((p) => p.key === primary) } : def,
59678
59766
  [def, primary]
59679
59767
  );
59680
- const [details, setDetails] = useState83(false);
59768
+ const [details, setDetails] = useState84(false);
59681
59769
  if (!registryDef || !def || !onlyPrimary) return null;
59682
59770
  const oneKnob = primary !== null || derived !== null;
59683
59771
  const copy = EFFECT_COPY[node.type];
@@ -60230,9 +60318,9 @@ function FxSection({
60230
60318
  const presetAutomated = automatedPresets ?? /* @__PURE__ */ new Set();
60231
60319
  const previewCarve = onCarvePreview ?? onCarveChange;
60232
60320
  const showCarve = !carvedAgainstBy && (sourceOptions.length > 0 || carve !== null);
60233
- const [adding, setAdding] = useState84(false);
60234
- const [picking, setPicking] = useState84(false);
60235
- const [openNode, setOpenNode] = useState84(0);
60321
+ const [adding, setAdding] = useState85(false);
60322
+ const [picking, setPicking] = useState85(false);
60323
+ const [openNode, setOpenNode] = useState85(0);
60236
60324
  const mutate = useCallback82(
60237
60325
  (nodes) => onChainChange({ ...chain, nodes }),
60238
60326
  [chain, onChainChange]
@@ -60318,7 +60406,7 @@ function FxSection({
60318
60406
  },
60319
60407
  [chain.nodes, mutate, onRemoveNodeAutomation, trackKind]
60320
60408
  );
60321
- const [carveOpen, setCarveOpen] = useState84(true);
60409
+ const [carveOpen, setCarveOpen] = useState85(true);
60322
60410
  const carveNodes = useMemo53(() => chain.nodes.filter((n) => n.fromCarve), [chain.nodes]);
60323
60411
  const handBuilt = useMemo53(
60324
60412
  () => chain.nodes.map((node, i) => ({ node, i })).filter(({ node }) => !node.fromCarve && !node.fromEq),
@@ -60334,7 +60422,7 @@ function FxSection({
60334
60422
  }
60335
60423
  return out;
60336
60424
  }, [handBuilt]);
60337
- const [collapsedRuns, setCollapsedRuns] = useState84(/* @__PURE__ */ new Set());
60425
+ const [collapsedRuns, setCollapsedRuns] = useState85(/* @__PURE__ */ new Set());
60338
60426
  const eqIds = useMemo53(() => audioEqIds(chain), [chain]);
60339
60427
  const positions = useMemo53(() => {
60340
60428
  const map = /* @__PURE__ */ new Map();
@@ -60342,9 +60430,9 @@ function FxSection({
60342
60430
  for (const { i } of handBuilt) map.set(i, ++at);
60343
60431
  return map;
60344
60432
  }, [handBuilt, eqIds.length, showCarve]);
60345
- const [openEq, setOpenEq] = useState84(null);
60346
- const [consumedRevealNonce, setConsumedRevealNonce] = useState84(null);
60347
- const [pendingReveal, setPendingReveal] = useState84(null);
60433
+ const [openEq, setOpenEq] = useState85(null);
60434
+ const [consumedRevealNonce, setConsumedRevealNonce] = useState85(null);
60435
+ const [pendingReveal, setPendingReveal] = useState85(null);
60348
60436
  const rootRef = useRef103(null);
60349
60437
  if (revealNonce != null && revealNonce !== consumedRevealNonce) {
60350
60438
  setConsumedRevealNonce(revealNonce);
@@ -60857,7 +60945,7 @@ import {
60857
60945
  } from "@hyperframes/core/audio-groups";
60858
60946
 
60859
60947
  // src/components/editor/useFxLevelling.ts
60860
- import { useRef as useRef106, useState as useState85 } from "react";
60948
+ import { useRef as useRef106, useState as useState86 } from "react";
60861
60949
  import {
60862
60950
  HF_AUDIO_FX_ATTR as HF_AUDIO_FX_ATTR5,
60863
60951
  serializeAudioFxChain as serializeAudioFxChain4
@@ -60915,7 +61003,7 @@ function useFxLevelling(element, chain, automation, onSetAttributeQuiet, onSetAt
60915
61003
  }
60916
61004
  };
60917
61005
  const auditionTransport = useAuditionTransport();
60918
- const [auditioningLevel, setAuditioningLevel] = useState85(false);
61006
+ const [auditioningLevel, setAuditioningLevel] = useState86(false);
60919
61007
  const auditionRun = useRef106(0);
60920
61008
  const stopLevelAudition = () => {
60921
61009
  setAuditioningLevel(false);
@@ -61070,7 +61158,7 @@ function AudioFxGroup({
61070
61158
  }
61071
61159
  };
61072
61160
  const removeNodeAutomation = (nodeId) => removeNodesAutomation([nodeId]);
61073
- const [analysing, setAnalysing] = useState86(false);
61161
+ const [analysing, setAnalysing] = useState87(false);
61074
61162
  const storeElements = usePlayerStore((s) => s.elements);
61075
61163
  const signalPath = useMemo54(() => {
61076
61164
  const doc = element.element?.ownerDocument;
@@ -61208,13 +61296,13 @@ function useVolumeAutomation(element, currentTime, onSetAttributeQuiet) {
61208
61296
  }
61209
61297
 
61210
61298
  // src/components/editor/useAudioFxRevealSection.ts
61211
- import { useEffect as useEffect88, useState as useState87 } from "react";
61299
+ import { useEffect as useEffect88, useState as useState88 } from "react";
61212
61300
  function useAudioFxRevealSection(input) {
61213
61301
  const revealedAudioFxTarget = usePlayerStore((s) => s.revealedAudioFxTarget);
61214
61302
  const timelineProjectId = usePlayerStore((s) => s.timelineProjectId);
61215
61303
  const timelineSessionEpoch = usePlayerStore((s) => s.timelineSessionEpoch);
61216
61304
  const clearRevealedAudioFxTarget = usePlayerStore((s) => s.clearRevealedAudioFxTarget);
61217
- const [consumed, setConsumed] = useState87(null);
61305
+ const [consumed, setConsumed] = useState88(null);
61218
61306
  useEffect88(() => {
61219
61307
  if (consumed === null) return;
61220
61308
  return () => clearRevealedAudioFxTarget(consumed);
@@ -61230,7 +61318,7 @@ function useAudioFxRevealSection(input) {
61230
61318
  }
61231
61319
 
61232
61320
  // src/components/editor/propertyPanelFlatMediaSection.tsx
61233
- import { useEffect as useEffect89, useState as useState88 } from "react";
61321
+ import { useEffect as useEffect89, useState as useState89 } from "react";
61234
61322
 
61235
61323
  // src/components/editor/propertyPanelFlatToggle.tsx
61236
61324
  import { jsx as jsx169, jsxs as jsxs130 } from "react/jsx-runtime";
@@ -61384,11 +61472,11 @@ function FlatMediaSection({
61384
61472
  const objectFit = styles["object-fit"] || "contain";
61385
61473
  const objectPosition = styles["object-position"] || "center";
61386
61474
  const srcAttr = el.getAttribute("src") ?? "";
61387
- const [copied, setCopied] = useState88(false);
61388
- const [removeBusy, setRemoveBusy] = useState88(false);
61389
- const [removeProgress, setRemoveProgress] = useState88(null);
61390
- const [createPlate, setCreatePlate] = useState88(false);
61391
- const [quality, setQuality] = useState88("balanced");
61475
+ const [copied, setCopied] = useState89(false);
61476
+ const [removeBusy, setRemoveBusy] = useState89(false);
61477
+ const [removeProgress, setRemoveProgress] = useState89(null);
61478
+ const [createPlate, setCreatePlate] = useState89(false);
61479
+ const [quality, setQuality] = useState89("balanced");
61392
61480
  const absoluteSrc = projectDir && srcAttr && !srcAttr.startsWith("http") ? `${projectDir}/${srcAttr}` : srcAttr;
61393
61481
  const projectSrc = srcAttr && !/^(?:https?:|data:|blob:)/i.test(srcAttr) ? stripQueryAndHash(srcAttr.startsWith("./") ? srcAttr.slice(2) : srcAttr) : "";
61394
61482
  const canRemoveBackground = Boolean(onRemoveBackground && isVisualMedia && projectSrc);
@@ -61748,7 +61836,7 @@ function createGsapLivePreview(iframeRef) {
61748
61836
  }
61749
61837
 
61750
61838
  // src/components/editor/propertyPanelFlatColorGradingSection.tsx
61751
- import { useEffect as useEffect95, useMemo as useMemo56, useRef as useRef114, useState as useState94 } from "react";
61839
+ import { useEffect as useEffect95, useMemo as useMemo56, useRef as useRef114, useState as useState95 } from "react";
61752
61840
  import {
61753
61841
  HF_COLOR_GRADING_GRADE_PRESETS,
61754
61842
  normalizeHfColorGrading as normalizeHfColorGrading5,
@@ -61780,7 +61868,7 @@ function presetPreviewHandlers({
61780
61868
  }
61781
61869
 
61782
61870
  // src/components/editor/propertyPanelColorCurves.tsx
61783
- import { useState as useState90 } from "react";
61871
+ import { useState as useState91 } from "react";
61784
61872
 
61785
61873
  // src/components/editor/propertyPanelColorCurveGraph.tsx
61786
61874
  import { useMemo as useMemo55, useRef as useRef107 } from "react";
@@ -62206,7 +62294,7 @@ function formatPointValue(value, tab, axis) {
62206
62294
  }
62207
62295
 
62208
62296
  // src/components/editor/propertyPanelGradingNumberField.tsx
62209
- import { useEffect as useEffect90, useRef as useRef108, useState as useState89 } from "react";
62297
+ import { useEffect as useEffect90, useRef as useRef108, useState as useState90 } from "react";
62210
62298
  import { jsx as jsx172, jsxs as jsxs133 } from "react/jsx-runtime";
62211
62299
  function GradingNumberField({
62212
62300
  label,
@@ -62224,7 +62312,7 @@ function GradingNumberField({
62224
62312
  onSettle,
62225
62313
  onCancel
62226
62314
  }) {
62227
- const [draft, setDraft] = useState89(() => formatValue2(value));
62315
+ const [draft, setDraft] = useState90(() => formatValue2(value));
62228
62316
  const focusedRef = useRef108(false);
62229
62317
  const cancelBlurRef = useRef108(false);
62230
62318
  const baselineRef = useRef108(value);
@@ -62313,8 +62401,8 @@ function ColorCurves({
62313
62401
  onPreview,
62314
62402
  onCommit
62315
62403
  }) {
62316
- const [activeKey, setActiveKey] = useState90("master");
62317
- const [selectedIndex, setSelectedIndex] = useState90(null);
62404
+ const [activeKey, setActiveKey] = useState91("master");
62405
+ const [selectedIndex, setSelectedIndex] = useState91(null);
62318
62406
  const { draft, setDraft, transaction } = useInspectorGestureDraft({
62319
62407
  sourceValue: value,
62320
62408
  onPreview,
@@ -62458,10 +62546,10 @@ function ColorCurves({
62458
62546
  }
62459
62547
 
62460
62548
  // src/components/editor/propertyPanelColorScopes.tsx
62461
- import { useEffect as useEffect92, useRef as useRef110, useState as useState92 } from "react";
62549
+ import { useEffect as useEffect92, useRef as useRef110, useState as useState93 } from "react";
62462
62550
 
62463
62551
  // src/components/editor/useColorGradingScopes.ts
62464
- import { useEffect as useEffect91, useRef as useRef109, useState as useState91 } from "react";
62552
+ import { useEffect as useEffect91, useRef as useRef109, useState as useState92 } from "react";
62465
62553
 
62466
62554
  // src/components/editor/colorGradingFrameAnalysis.ts
62467
62555
  import {
@@ -62618,9 +62706,9 @@ function useColorGradingScopes({
62618
62706
  captureFrame,
62619
62707
  refreshKey
62620
62708
  }) {
62621
- const [analysis, setAnalysis] = useState91(null);
62622
- const [status, setStatus] = useState91("idle");
62623
- const [refreshVersion, setRefreshVersion] = useState91(0);
62709
+ const [analysis, setAnalysis] = useState92(null);
62710
+ const [status, setStatus] = useState92("idle");
62711
+ const [refreshVersion, setRefreshVersion] = useState92(0);
62624
62712
  const captureRef = useRef109(captureFrame);
62625
62713
  captureRef.current = captureFrame;
62626
62714
  useEffect91(() => {
@@ -62797,8 +62885,8 @@ function PropertyPanelColorScopes({
62797
62885
  captureFrame,
62798
62886
  refreshKey
62799
62887
  }) {
62800
- const [open, setOpen] = useState92(false);
62801
- const [mode, setMode] = useState92("waveform");
62888
+ const [open, setOpen] = useState93(false);
62889
+ const [mode, setMode] = useState93("waveform");
62802
62890
  const canvasRef = useRef110(null);
62803
62891
  const { analysis, status, refresh } = useColorGradingScopes({
62804
62892
  open,
@@ -62869,7 +62957,7 @@ function PropertyPanelColorScopes({
62869
62957
  }
62870
62958
 
62871
62959
  // src/components/editor/propertyPanelColorSecondary.tsx
62872
- import { useEffect as useEffect93, useRef as useRef111, useState as useState93 } from "react";
62960
+ import { useEffect as useEffect93, useRef as useRef111, useState as useState94 } from "react";
62873
62961
  import {
62874
62962
  getHfColorGradingCapabilities,
62875
62963
  normalizeHfColorGrading as normalizeHfColorGrading4
@@ -62913,12 +63001,12 @@ function PropertyPanelColorSecondary({
62913
63001
  captureFrame,
62914
63002
  onCommit
62915
63003
  }) {
62916
- const [selectedIndex, setSelectedIndex] = useState93(0);
62917
- const [sampleFrame, setSampleFrame] = useState93(null);
62918
- const [samplePixels, setSamplePixels] = useState93(null);
62919
- const [showMatte, setShowMatte] = useState93(false);
62920
- const [captureError, setCaptureError] = useState93(null);
62921
- const [sampling, setSampling] = useState93(false);
63004
+ const [selectedIndex, setSelectedIndex] = useState94(0);
63005
+ const [sampleFrame, setSampleFrame] = useState94(null);
63006
+ const [samplePixels, setSamplePixels] = useState94(null);
63007
+ const [showMatte, setShowMatte] = useState94(false);
63008
+ const [captureError, setCaptureError] = useState94(null);
63009
+ const [sampling, setSampling] = useState94(false);
62922
63010
  const matteCanvasRef = useRef111(null);
62923
63011
  const activeIndex = Math.min(selectedIndex, Math.max(0, secondaries.length - 1));
62924
63012
  const selected = secondaries[activeIndex];
@@ -63767,8 +63855,8 @@ function FlatColorGradingSection({
63767
63855
  }) {
63768
63856
  const track2 = useTrackDesignInput();
63769
63857
  const lutInputRef = useRef114(null);
63770
- const [lutOpen, setLutOpen] = useState94(false);
63771
- const [detailSettingsOpen, setDetailSettingsOpen] = useState94(null);
63858
+ const [lutOpen, setLutOpen] = useState95(false);
63859
+ const [detailSettingsOpen, setDetailSettingsOpen] = useState95(null);
63772
63860
  const lutAssets = useMemo56(
63773
63861
  () => assets.filter((asset) => LUT_EXT.test(asset)).sort((a, b) => a.localeCompare(b)),
63774
63862
  [assets]
@@ -64154,7 +64242,7 @@ function FlatColorGradingSection({
64154
64242
  }
64155
64243
 
64156
64244
  // src/components/editor/propertyPanelFlatEffectsSection.tsx
64157
- import { useEffect as useEffect96, useState as useState95 } from "react";
64245
+ import { useEffect as useEffect96, useState as useState96 } from "react";
64158
64246
  import {
64159
64247
  HF_COLOR_GRADING_EFFECT_APPLY_DEFAULTS as HF_COLOR_GRADING_EFFECT_APPLY_DEFAULTS3,
64160
64248
  HF_COLOR_GRADING_EFFECT_PRESETS,
@@ -64530,9 +64618,9 @@ function FlatEffectsSection({
64530
64618
  }) {
64531
64619
  const track2 = useTrackDesignInput();
64532
64620
  const activeEffects = EFFECT_SPECS.filter((effect) => grading.effects[effect.key] > 1e-4);
64533
- const [catalogOpen, setCatalogOpen] = useState95(activeEffects.length === 0);
64534
- const [catalogGroup, setCatalogGroup] = useState95(EFFECT_GROUPS[0].label);
64535
- const [selectedKey, setSelectedKey] = useState95(
64621
+ const [catalogOpen, setCatalogOpen] = useState96(activeEffects.length === 0);
64622
+ const [catalogGroup, setCatalogGroup] = useState96(EFFECT_GROUPS[0].label);
64623
+ const [selectedKey, setSelectedKey] = useState96(
64536
64624
  activeEffects[0]?.key ?? null
64537
64625
  );
64538
64626
  const selectedEffect = activeEffects.find((effect) => effect.key === selectedKey) ?? activeEffects[0] ?? null;
@@ -64921,10 +65009,10 @@ function FlatEffectsSection({
64921
65009
  }
64922
65010
 
64923
65011
  // src/components/editor/propertyPanelFlatOverlaysSection.tsx
64924
- import { useState as useState97 } from "react";
65012
+ import { useState as useState98 } from "react";
64925
65013
 
64926
65014
  // src/hooks/useBlockCatalog.ts
64927
- import { useState as useState96, useEffect as useEffect97, useMemo as useMemo57 } from "react";
65015
+ import { useState as useState97, useEffect as useEffect97, useMemo as useMemo57 } from "react";
64928
65016
 
64929
65017
  // src/utils/blockCategories.ts
64930
65018
  import {
@@ -64967,11 +65055,11 @@ function loadCatalog() {
64967
65055
  return catalogRequest;
64968
65056
  }
64969
65057
  function useBlockCatalog() {
64970
- const [blocks, setBlocks] = useState96(() => catalogCache ?? []);
64971
- const [loading, setLoading] = useState96(catalogCache === null);
64972
- const [error, setError] = useState96(null);
64973
- const [search, setSearch] = useState96("");
64974
- const [category, setCategory] = useState96(null);
65058
+ const [blocks, setBlocks] = useState97(() => catalogCache ?? []);
65059
+ const [loading, setLoading] = useState97(catalogCache === null);
65060
+ const [error, setError] = useState97(null);
65061
+ const [search, setSearch] = useState97("");
65062
+ const [category, setCategory] = useState97(null);
64975
65063
  useEffect97(() => {
64976
65064
  if (catalogCache) return;
64977
65065
  let cancelled = false;
@@ -65039,8 +65127,8 @@ function FlatOverlaysSection({
65039
65127
  const track2 = useTrackDesignInput();
65040
65128
  const { blocks, loading, error } = useBlockCatalog();
65041
65129
  const overlays = filterMediaTreatmentOverlays(blocks);
65042
- const [adding, setAdding] = useState97(null);
65043
- const [previewing, setPreviewing] = useState97(null);
65130
+ const [adding, setAdding] = useState98(null);
65131
+ const [previewing, setPreviewing] = useState98(null);
65044
65132
  if (loading) {
65045
65133
  return /* @__PURE__ */ jsx181("div", { className: "py-4 text-center text-[10px] text-panel-text-4", children: "Loading overlays\u2026" });
65046
65134
  }
@@ -65207,7 +65295,7 @@ function PropertyPanelFlat({
65207
65295
  onUpdateSegmentEase,
65208
65296
  onSetAllKeyframeEases
65209
65297
  }) {
65210
- const [openGroupId, setOpenGroupId] = useState98(
65298
+ const [openGroupId, setOpenGroupId] = useState99(
65211
65299
  () => isTextEditableSelection(element) ? "text" : showEditableSections ? "style" : sections.media ? "media" : (
65212
65300
  // An `<hf-audio-group>` has no style, no layout and no media — its
65213
65301
  // chain is the only reason to select one. Without this the fallback
@@ -65225,7 +65313,7 @@ function PropertyPanelFlat({
65225
65313
  );
65226
65314
  const storeElements = usePlayerStore((state) => state.elements);
65227
65315
  const renderedElementId = scopedElementKey(element);
65228
- const [consumedFocus, setConsumedFocus] = useState98(focusedEaseSegment);
65316
+ const [consumedFocus, setConsumedFocus] = useState99(focusedEaseSegment);
65229
65317
  if (focusedEaseSegment !== consumedFocus) {
65230
65318
  setConsumedFocus(focusedEaseSegment);
65231
65319
  const focusesThisPanel = focusedEaseSegment !== null && // A request from a previous project/session/selection is stale: it must
@@ -65246,7 +65334,7 @@ function PropertyPanelFlat({
65246
65334
  reveal.consume(reveal.revealNonce);
65247
65335
  setOpenGroupId("audio-fx");
65248
65336
  }
65249
- const [justToggledIds, setJustToggledIds] = useState98([]);
65337
+ const [justToggledIds, setJustToggledIds] = useState99([]);
65250
65338
  const justToggledTimeoutRef = useRef115(null);
65251
65339
  const panelBodyRef = useRef115(null);
65252
65340
  useEffect98(() => {
@@ -65856,7 +65944,7 @@ var PropertyPanel = memo36(function PropertyPanel2(props) {
65856
65944
  } = props;
65857
65945
  const styles = element?.computedStyles ?? EMPTY_STYLES;
65858
65946
  const { showToast } = useStudioShellContext();
65859
- const [clipboardCopied, setClipboardCopied] = useState99(false);
65947
+ const [clipboardCopied, setClipboardCopied] = useState100(false);
65860
65948
  const clipboardTimerRef = useRef116(void 0);
65861
65949
  const timelineElements = usePlayerStore((s) => s.elements);
65862
65950
  const selectedElementId = usePlayerStore((s) => s.selectedElementId);
@@ -66261,11 +66349,11 @@ var PropertyPanel = memo36(function PropertyPanel2(props) {
66261
66349
  });
66262
66350
 
66263
66351
  // src/components/editor/FileTree.tsx
66264
- import { memo as memo38, useState as useState101, useCallback as useCallback84, useMemo as useMemo61, useRef as useRef118 } from "react";
66352
+ import { memo as memo38, useState as useState102, useCallback as useCallback84, useMemo as useMemo61, useRef as useRef118 } from "react";
66265
66353
  import { Plus as Plus2, FolderSimplePlus as FolderSimplePlus2 } from "@phosphor-icons/react";
66266
66354
 
66267
66355
  // src/components/editor/FileTreeNodes.tsx
66268
- import { memo as memo37, useState as useState100, useCallback as useCallback83, useMemo as useMemo60, useRef as useRef117, useEffect as useEffect99 } from "react";
66356
+ import { memo as memo37, useState as useState101, useCallback as useCallback83, useMemo as useMemo60, useRef as useRef117, useEffect as useEffect99 } from "react";
66269
66357
  import {
66270
66358
  PencilSimple,
66271
66359
  Copy,
@@ -66541,8 +66629,8 @@ function InlineInput({
66541
66629
  }) {
66542
66630
  const inputRef = useRef117(null);
66543
66631
  const committedRef = useRef117(false);
66544
- const [value, setValue] = useState100(defaultValue);
66545
- const [error, setError] = useState100(null);
66632
+ const [value, setValue] = useState101(defaultValue);
66633
+ const [error, setError] = useState101(null);
66546
66634
  const validate = (name) => {
66547
66635
  if (/[/\\]/.test(name)) return "Name can't contain / or \\";
66548
66636
  if (name.includes("..")) return "Name can't contain ..";
@@ -66746,7 +66834,7 @@ var TreeFolder = memo37(function TreeFolder2({
66746
66834
  dragOverFolder,
66747
66835
  lintFindingsByFile
66748
66836
  }) {
66749
- const [isOpen, setIsOpen] = useState100(defaultOpen);
66837
+ const [isOpen, setIsOpen] = useState101(defaultOpen);
66750
66838
  const toggle = useCallback83(() => setIsOpen((v) => !v), []);
66751
66839
  const children = useMemo60(() => sortChildren(node.children), [node.children]);
66752
66840
  const Chevron = isOpen ? ChevronDown : ChevronRight;
@@ -66881,10 +66969,10 @@ var FileTree = memo38(function FileTree2({
66881
66969
  }) {
66882
66970
  const tree = useMemo61(() => buildTree(files), [files]);
66883
66971
  const children = useMemo61(() => sortChildren(tree.children), [tree]);
66884
- const [contextMenu, setContextMenu] = useState101(null);
66885
- const [inlineInput, setInlineInput] = useState101(null);
66886
- const [deleteTarget, setDeleteTarget] = useState101(null);
66887
- const [dragOverFolder, setDragOverFolder] = useState101(null);
66972
+ const [contextMenu, setContextMenu] = useState102(null);
66973
+ const [inlineInput, setInlineInput] = useState102(null);
66974
+ const [deleteTarget, setDeleteTarget] = useState102(null);
66975
+ const [dragOverFolder, setDragOverFolder] = useState102(null);
66888
66976
  const dragSourceRef = useRef118(null);
66889
66977
  const hasFileOps = !!(onCreateFile || onCreateFolder || onDeleteFile || onRenameFile || onDuplicateFile);
66890
66978
  const handleContextMenu = useCallback84(
@@ -67147,7 +67235,7 @@ var FileTree = memo38(function FileTree2({
67147
67235
  });
67148
67236
 
67149
67237
  // src/App.tsx
67150
- import { useState as useState152, useCallback as useCallback177, useRef as useRef185, useMemo as useMemo77, useLayoutEffect as useLayoutEffect10 } from "react";
67238
+ import { useState as useState153, useCallback as useCallback177, useRef as useRef185, useMemo as useMemo77, useLayoutEffect as useLayoutEffect10 } from "react";
67151
67239
 
67152
67240
  // src/hooks/useRightPanelIntents.ts
67153
67241
  import { useCallback as useCallback85, useEffect as useEffect100, useRef as useRef119 } from "react";
@@ -67198,7 +67286,7 @@ function useRightPanelIntent() {
67198
67286
  }
67199
67287
 
67200
67288
  // src/components/renders/useRenderQueue.ts
67201
- import { useState as useState103, useEffect as useEffect102, useCallback as useCallback87, useRef as useRef121, useMemo as useMemo62 } from "react";
67289
+ import { useState as useState104, useEffect as useEffect102, useCallback as useCallback87, useRef as useRef121, useMemo as useMemo62 } from "react";
67202
67290
 
67203
67291
  // src/components/renders/serverError.ts
67204
67292
  async function readServerError(res) {
@@ -67216,7 +67304,7 @@ async function readServerError(res) {
67216
67304
  }
67217
67305
 
67218
67306
  // src/components/renders/useFfmpegStatus.ts
67219
- import { useCallback as useCallback86, useEffect as useEffect101, useRef as useRef120, useState as useState102 } from "react";
67307
+ import { useCallback as useCallback86, useEffect as useEffect101, useRef as useRef120, useState as useState103 } from "react";
67220
67308
  function ffmpegInstallMessage(status) {
67221
67309
  const title = status?.title ?? "FFmpeg not found";
67222
67310
  const remedy = status?.command ?? status?.hint;
@@ -67245,8 +67333,8 @@ async function probe() {
67245
67333
  }
67246
67334
  }
67247
67335
  function useFfmpegStatus() {
67248
- const [status, setStatus] = useState102(cached4);
67249
- const [checking, setChecking] = useState102(cached4 === null);
67336
+ const [status, setStatus] = useState103(cached4);
67337
+ const [checking, setChecking] = useState103(cached4 === null);
67250
67338
  const mounted = useRef120(true);
67251
67339
  useEffect101(() => {
67252
67340
  mounted.current = true;
@@ -67440,9 +67528,9 @@ function writeHiddenIds(projectId, ids) {
67440
67528
  }
67441
67529
  }
67442
67530
  function useRenderQueue(projectId, activeCompPathRef) {
67443
- const [jobs, setJobs] = useState103([]);
67444
- const [loadError, setLoadError] = useState103(null);
67445
- const [actionError, setActionError] = useState103(null);
67531
+ const [jobs, setJobs] = useState104([]);
67532
+ const [loadError, setLoadError] = useState104(null);
67533
+ const [actionError, setActionError] = useState104(null);
67446
67534
  const { status: ffmpeg, checking: ffmpegChecking, recheck: recheckFfmpeg } = useFfmpegStatus();
67447
67535
  const ffmpegMissing = ffmpeg !== null && !ffmpeg.ok;
67448
67536
  const eventSourceRef = useRef121(null);
@@ -67760,7 +67848,7 @@ function useRenderQueue(projectId, activeCompPathRef) {
67760
67848
  }
67761
67849
 
67762
67850
  // src/components/LintModal.tsx
67763
- import { useRef as useRef123, useState as useState104 } from "react";
67851
+ import { useRef as useRef123, useState as useState105 } from "react";
67764
67852
  import { XIcon, WarningIcon, CheckCircleIcon, CaretRightIcon } from "@phosphor-icons/react";
67765
67853
 
67766
67854
  // src/components/ui/useDialogBehavior.ts
@@ -67834,8 +67922,8 @@ function LintModal({
67834
67922
  const errors = findings.filter((f) => f.severity === "error");
67835
67923
  const warnings = findings.filter((f) => f.severity === "warning");
67836
67924
  const hasIssues = findings.length > 0;
67837
- const [copied, setCopied] = useState104(false);
67838
- const [copyFailed, setCopyFailed] = useState104(false);
67925
+ const [copied, setCopied] = useState105(false);
67926
+ const [copyFailed, setCopyFailed] = useState105(false);
67839
67927
  const containerRef = useRef123(null);
67840
67928
  const { requestClose } = useDialogBehavior({ open: true, onClose, containerRef });
67841
67929
  const handleCopyToAgent = async () => {
@@ -67938,7 +68026,7 @@ ${pathLine}${lines.join("\n\n")}`;
67938
68026
  }
67939
68027
 
67940
68028
  // src/components/AskAgentModal.tsx
67941
- import { useState as useState105, useRef as useRef124 } from "react";
68029
+ import { useState as useState106, useRef as useRef124 } from "react";
67942
68030
  import { jsx as jsx190, jsxs as jsxs149 } from "react/jsx-runtime";
67943
68031
  function getAgentModalPositionStyle(anchorPoint) {
67944
68032
  if (!anchorPoint || typeof window === "undefined") return void 0;
@@ -67964,7 +68052,7 @@ function AskAgentModal({
67964
68052
  onSubmit,
67965
68053
  onClose
67966
68054
  }) {
67967
- const [value, setValue] = useState105("");
68055
+ const [value, setValue] = useState106("");
67968
68056
  const inputRef = useRef124(null);
67969
68057
  const containerRef = useRef124(null);
67970
68058
  const modalPositionStyle = getAgentModalPositionStyle(anchorPoint);
@@ -68130,7 +68218,7 @@ function StudioToast({ message, tone, leaving, onDismiss }) {
68130
68218
  }
68131
68219
 
68132
68220
  // src/components/feedback/StudioFeedbackCard.tsx
68133
- import { memo as memo39, useState as useState106, useCallback as useCallback89, useRef as useRef125, useEffect as useEffect104 } from "react";
68221
+ import { memo as memo39, useState as useState107, useCallback as useCallback89, useRef as useRef125, useEffect as useEffect104 } from "react";
68134
68222
 
68135
68223
  // src/components/feedback/projectProvenance.ts
68136
68224
  var CONFIG_FILE = "hyperframes.json";
@@ -68207,13 +68295,13 @@ var THANKS_MS = 1e4;
68207
68295
  var INTERVIEW_URL = "https://calendar.app.google/yRHT7oPsHWcqFfFv5";
68208
68296
  var RATINGS = Array.from({ length: 11 }, (_, n) => n);
68209
68297
  var StudioFeedbackCard = memo39(function StudioFeedbackCard2() {
68210
- const [request, setRequest] = useState106(null);
68211
- const [step, setStep] = useState106("rating");
68212
- const [rating, setRating] = useState106(null);
68213
- const [followUp, setFollowUp] = useState106(FAILURE_FOLLOW_UP);
68214
- const [comment, setComment] = useState106("");
68215
- const [hint, setHint] = useState106(null);
68216
- const [exiting, setExiting] = useState106(false);
68298
+ const [request, setRequest] = useState107(null);
68299
+ const [step, setStep] = useState107("rating");
68300
+ const [rating, setRating] = useState107(null);
68301
+ const [followUp, setFollowUp] = useState107(FAILURE_FOLLOW_UP);
68302
+ const [comment, setComment] = useState107("");
68303
+ const [hint, setHint] = useState107(null);
68304
+ const [exiting, setExiting] = useState107(false);
68217
68305
  const inputRef = useRef125(null);
68218
68306
  const timerRef = useRef125(null);
68219
68307
  const stateRef = useRef125({ request, rating, step });
@@ -68549,7 +68637,7 @@ function SaveQueuePausedBanner({ message, onRetry }) {
68549
68637
  }
68550
68638
 
68551
68639
  // src/components/ExternalFileConflictBanner.tsx
68552
- import { useRef as useRef126, useState as useState107 } from "react";
68640
+ import { useRef as useRef126, useState as useState108 } from "react";
68553
68641
  import { Fragment as Fragment50, jsx as jsx195, jsxs as jsxs154 } from "react/jsx-runtime";
68554
68642
  function errorMessage(error) {
68555
68643
  return error instanceof Error ? error.message : String(error);
@@ -68708,7 +68796,7 @@ function FailedDraftReview({
68708
68796
  function ExternalFileConflictBanner({
68709
68797
  coordinator
68710
68798
  }) {
68711
- const [reviewing, setReviewing] = useState107(false);
68799
+ const [reviewing, setReviewing] = useState108(false);
68712
68800
  const blocked = coordinator.blocked;
68713
68801
  if (!blocked) return null;
68714
68802
  const conflict = blocked.status === "conflict" ? blocked : null;
@@ -68779,10 +68867,10 @@ function ExternalFileConflictBanner({
68779
68867
  }
68780
68868
 
68781
68869
  // src/components/ProjectUnreachableBanner.tsx
68782
- import { useEffect as useEffect105, useState as useState108 } from "react";
68870
+ import { useEffect as useEffect105, useState as useState109 } from "react";
68783
68871
  import { Fragment as Fragment51, jsx as jsx196, jsxs as jsxs155 } from "react/jsx-runtime";
68784
68872
  function ProjectUnreachableBanner({ projectId }) {
68785
- const [served, setServed] = useState108(null);
68873
+ const [served, setServed] = useState109(null);
68786
68874
  useEffect105(() => {
68787
68875
  let cancelled = false;
68788
68876
  fetch("/api/projects").then((res) => res.ok ? res.json() : { projects: [] }).then((data) => {
@@ -68992,7 +69080,7 @@ function useCaptionSync(projectId) {
68992
69080
  }
68993
69081
 
68994
69082
  // src/hooks/usePersistentEditHistory.ts
68995
- import { useCallback as useCallback91, useEffect as useEffect106, useMemo as useMemo63, useRef as useRef128, useState as useState109 } from "react";
69083
+ import { useCallback as useCallback91, useEffect as useEffect106, useMemo as useMemo63, useRef as useRef128, useState as useState110 } from "react";
68996
69084
 
68997
69085
  // src/utils/editHistory.ts
68998
69086
  var DEFAULT_MAX_ENTRIES = 100;
@@ -69349,8 +69437,8 @@ function usePersistentEditHistory(options) {
69349
69437
  [options.storage]
69350
69438
  );
69351
69439
  const now2 = options.now ?? Date.now;
69352
- const [state, setState] = useState109(() => createEmptyEditHistory());
69353
- const [loaded, setLoaded] = useState109(false);
69440
+ const [state, setState] = useState110(() => createEmptyEditHistory());
69441
+ const [loaded, setLoaded] = useState110(false);
69354
69442
  const projectId = options.projectId;
69355
69443
  const storeRef = useRef128(null);
69356
69444
  const storeProjectIdRef = useRef128(null);
@@ -69492,13 +69580,13 @@ function usePanelLayout(initialState2) {
69492
69580
  }
69493
69581
 
69494
69582
  // src/hooks/useFileManager.ts
69495
- import { useState as useState111, useCallback as useCallback96, useRef as useRef132 } from "react";
69583
+ import { useState as useState112, useCallback as useCallback96, useRef as useRef132 } from "react";
69496
69584
 
69497
69585
  // src/hooks/useFileTree.ts
69498
- import { useState as useState110, useCallback as useCallback93, useEffect as useEffect108, useMemo as useMemo64, useRef as useRef130 } from "react";
69586
+ import { useState as useState111, useCallback as useCallback93, useEffect as useEffect108, useMemo as useMemo64, useRef as useRef130 } from "react";
69499
69587
  var EMPTY_FILE_LIST = [];
69500
69588
  function useFileTree({ projectId, projectIdRef }) {
69501
- const [fetched, setFetched] = useState110(null);
69589
+ const [fetched, setFetched] = useState111(null);
69502
69590
  const current = fetched?.projectId === projectId ? fetched : null;
69503
69591
  const fileTree = current?.fileTree ?? EMPTY_FILE_LIST;
69504
69592
  const compositionPaths = current?.compositionPaths ?? EMPTY_FILE_LIST;
@@ -69840,8 +69928,8 @@ function useFileManager({
69840
69928
  recordEdit,
69841
69929
  setRefreshKey
69842
69930
  }) {
69843
- const [editingFile, setEditingFile] = useState111(null);
69844
- const [revealSourceOffset, setRevealSourceOffset] = useState111(null);
69931
+ const [editingFile, setEditingFile] = useState112(null);
69932
+ const [revealSourceOffset, setRevealSourceOffset] = useState112(null);
69845
69933
  const editingPathRef = useRef132(editingFile?.path);
69846
69934
  editingPathRef.current = editingFile?.path;
69847
69935
  const projectIdRef = useRef132(projectId);
@@ -70192,7 +70280,7 @@ function useFileManager({
70192
70280
  }
70193
70281
 
70194
70282
  // src/hooks/usePreviewPersistence.ts
70195
- import { useCallback as useCallback97, useRef as useRef133, useState as useState112 } from "react";
70283
+ import { useCallback as useCallback97, useRef as useRef133, useState as useState113 } from "react";
70196
70284
 
70197
70285
  // src/utils/gsapUndoRestore.ts
70198
70286
  function elementIdentityKey(el) {
@@ -70427,7 +70515,7 @@ function usePreviewPersistence({
70427
70515
  reloadPreview
70428
70516
  }) {
70429
70517
  void _recordEdit;
70430
- const [domEditSaveQueuePaused, setDomEditSaveQueuePaused] = useState112(null);
70518
+ const [domEditSaveQueuePaused, setDomEditSaveQueuePaused] = useState113(null);
70431
70519
  const domTextCommitVersionRef = useRef133(0);
70432
70520
  const showToastRef = useRef133(showToast);
70433
70521
  showToastRef.current = showToast;
@@ -70525,9 +70613,9 @@ function usePreviewPersistence({
70525
70613
  }
70526
70614
 
70527
70615
  // src/hooks/usePreviewDocumentVersion.ts
70528
- import { useCallback as useCallback98, useEffect as useEffect109, useRef as useRef134, useState as useState113 } from "react";
70616
+ import { useCallback as useCallback98, useEffect as useEffect109, useRef as useRef134, useState as useState114 } from "react";
70529
70617
  function usePreviewDocumentVersion() {
70530
- const [previewDocumentVersion, setPreviewDocumentVersion] = useState113(0);
70618
+ const [previewDocumentVersion, setPreviewDocumentVersion] = useState114(0);
70531
70619
  const refreshTimersRef = useRef134([]);
70532
70620
  const refresh = useCallback98(() => {
70533
70621
  for (const id of refreshTimersRef.current) clearTimeout(id);
@@ -72910,7 +72998,7 @@ function persistTimelineMoveEditsAtomically(edits, coalesceKey, operation, deps,
72910
72998
  import { useCallback as useCallback133 } from "react";
72911
72999
 
72912
73000
  // src/hooks/useAskAgentModal.ts
72913
- import { useState as useState114, useCallback as useCallback111, useRef as useRef142, useEffect as useEffect110 } from "react";
73001
+ import { useState as useState115, useCallback as useCallback111, useRef as useRef142, useEffect as useEffect110 } from "react";
72914
73002
  function useAskAgentModal({
72915
73003
  activeCompPath,
72916
73004
  projectDir,
@@ -72919,13 +73007,13 @@ function useAskAgentModal({
72919
73007
  domEditSelectionRef,
72920
73008
  domEditSelection
72921
73009
  }) {
72922
- const [agentPromptTagSnippet, setAgentPromptTagSnippet] = useState114();
72923
- const [agentPromptSelectionContext, setAgentPromptSelectionContext] = useState114();
72924
- const [agentModalAnchorPoint, setAgentModalAnchorPoint] = useState114(
73010
+ const [agentPromptTagSnippet, setAgentPromptTagSnippet] = useState115();
73011
+ const [agentPromptSelectionContext, setAgentPromptSelectionContext] = useState115();
73012
+ const [agentModalAnchorPoint, setAgentModalAnchorPoint] = useState115(
72925
73013
  null
72926
73014
  );
72927
- const [copiedAgentPrompt, setCopiedAgentPrompt] = useState114(false);
72928
- const [agentModalOpen, setAgentModalOpen] = useState114(false);
73015
+ const [copiedAgentPrompt, setCopiedAgentPrompt] = useState115(false);
73016
+ const [agentModalOpen, setAgentModalOpen] = useState115(false);
72929
73017
  const copiedAgentTimerRef = useRef142(null);
72930
73018
  const preloadAgentPromptSnippet = useCallback111(
72931
73019
  async (selection) => {
@@ -73022,7 +73110,7 @@ function useAskAgentModal({
73022
73110
  }
73023
73111
 
73024
73112
  // src/hooks/useDomSelection.ts
73025
- import { useState as useState115, useCallback as useCallback112, useRef as useRef143, useEffect as useEffect112 } from "react";
73113
+ import { useState as useState116, useCallback as useCallback112, useRef as useRef143, useEffect as useEffect112 } from "react";
73026
73114
 
73027
73115
  // src/utils/domEditHelpers.ts
73028
73116
  function domEditSelectionsTargetSame(a, b) {
@@ -73245,10 +73333,10 @@ function useDomSelection({
73245
73333
  refreshKey,
73246
73334
  rightPanelTab
73247
73335
  }) {
73248
- const [domEditSelection, setDomEditSelection] = useState115(null);
73249
- const [domEditGroupSelections, setDomEditGroupSelections] = useState115([]);
73250
- const [domEditHoverSelection, setDomEditHoverSelection] = useState115(null);
73251
- const [activeGroupElement, setActiveGroupElementState] = useState115(null);
73336
+ const [domEditSelection, setDomEditSelection] = useState116(null);
73337
+ const [domEditGroupSelections, setDomEditGroupSelections] = useState116([]);
73338
+ const [domEditHoverSelection, setDomEditHoverSelection] = useState116(null);
73339
+ const [activeGroupElement, setActiveGroupElementState] = useState116(null);
73252
73340
  const rightPanelTabRef = useRef143(rightPanelTab);
73253
73341
  rightPanelTabRef.current = rightPanelTab;
73254
73342
  const domEditSelectionRef = useRef143(domEditSelection);
@@ -79445,7 +79533,7 @@ function useSdkSelectionSync(session, domEditSelection, domEditGroupSelections)
79445
79533
  import { useEffect as useEffect119 } from "react";
79446
79534
 
79447
79535
  // src/hooks/useSdkSession.ts
79448
- import { useState as useState116, useEffect as useEffect118, useCallback as useCallback134, useRef as useRef154 } from "react";
79536
+ import { useState as useState117, useEffect as useEffect118, useCallback as useCallback134, useRef as useRef154 } from "react";
79449
79537
  import { openComposition as openComposition3 } from "@hyperframes/sdk";
79450
79538
 
79451
79539
  // src/hooks/externalFileReloadBus.ts
@@ -79555,7 +79643,7 @@ function disposeSdkSession(session) {
79555
79643
  }
79556
79644
  }
79557
79645
  function useSdkSession(projectId, activeCompPath, fileTree = [], fileTreeLoaded = false) {
79558
- const [ownedSession, setOwnedSession] = useState116(null);
79646
+ const [ownedSession, setOwnedSession] = useState117(null);
79559
79647
  const ownedSessionRef = useRef154(null);
79560
79648
  const sessionOwnersRef = useRef154(/* @__PURE__ */ new WeakMap());
79561
79649
  const generationRef = useRef154(0);
@@ -79563,10 +79651,10 @@ function useSdkSession(projectId, activeCompPath, fileTree = [], fileTreeLoaded
79563
79651
  projectIdRef.current = projectId;
79564
79652
  const activeCompPathRef = useRef154(activeCompPath);
79565
79653
  activeCompPathRef.current = activeCompPath;
79566
- const [reloadToken, setReloadToken] = useState116(0);
79654
+ const [reloadToken, setReloadToken] = useState117(0);
79567
79655
  const reloadTokenRef = useRef154(reloadToken);
79568
79656
  reloadTokenRef.current = reloadToken;
79569
- const [unreachableProject, setUnreachableProject] = useState116(null);
79657
+ const [unreachableProject, setUnreachableProject] = useState117(null);
79570
79658
  useEffect118(
79571
79659
  () => addExternalFileReloadListener((changedPath) => {
79572
79660
  if (changedPath === activeCompPathRef.current) setReloadToken((token) => token + 1);
@@ -79785,7 +79873,7 @@ async function deleteExternalConflictSnapshot(projectId, filePath) {
79785
79873
  }
79786
79874
 
79787
79875
  // src/hooks/useExternalFileChangeCoordinator.ts
79788
- import { useCallback as useCallback135, useEffect as useEffect120, useRef as useRef155, useState as useState117 } from "react";
79876
+ import { useCallback as useCallback135, useEffect as useEffect120, useRef as useRef155, useState as useState118 } from "react";
79789
79877
  function testHotAdapter() {
79790
79878
  const value = globalThis.__HF_STUDIO_HOT_TEST_ADAPTER__;
79791
79879
  if (!value || typeof value !== "object") return null;
@@ -79836,7 +79924,7 @@ function useExternalFileChangeCoordinator({
79836
79924
  resetSaveQueues,
79837
79925
  onAcceptedPersistedFileChange
79838
79926
  }) {
79839
- const [blocked, setBlocked] = useState117(null);
79927
+ const [blocked, setBlocked] = useState118(null);
79840
79928
  const generationRef = useRef155(0);
79841
79929
  const mountedRef = useRef155(true);
79842
79930
  const lastEventIdentityRef = useRef155(null);
@@ -79933,7 +80021,7 @@ function useExternalFileChangeCoordinator({
79933
80021
  }
79934
80022
  if (!mountedRef.current || generation !== generationRef.current) return;
79935
80023
  setBlocked(null);
79936
- onAcceptedPersistedFileChange(path);
80024
+ onAcceptedPersistedFileChange(path, readFileChangeAffectedCompositions(payload));
79937
80025
  reloadAcceptedGeneration(path);
79938
80026
  return;
79939
80027
  }
@@ -80043,7 +80131,7 @@ function useExternalFileChangeCoordinator({
80043
80131
  const ownWriteToken = consumeStudioWriteToken(token);
80044
80132
  const ownContentEcho = content != null && isSelfWriteEcho(path, content);
80045
80133
  if (ownWriteToken || ownContentEcho) {
80046
- onAcceptedPersistedFileChange(path);
80134
+ onAcceptedPersistedFileChange(path, readFileChangeAffectedCompositions(payload));
80047
80135
  logReload("suppressed", {
80048
80136
  path,
80049
80137
  why: ownWriteToken ? "own write token" : "own content echo"
@@ -80088,7 +80176,7 @@ function useExternalFileChangeCoordinator({
80088
80176
  onUseExternalFile?.(path, external);
80089
80177
  await deleteConflictSnapshot?.(projectId, path);
80090
80178
  setBlocked(null);
80091
- onAcceptedPersistedFileChange(path);
80179
+ onAcceptedPersistedFileChange(path, readFileChangeAffectedCompositions(current.payload));
80092
80180
  reloadAcceptedGeneration(path);
80093
80181
  },
80094
80182
  [
@@ -80170,8 +80258,10 @@ function useStudioExternalFileChanges({
80170
80258
  }) {
80171
80259
  const { flushPendingSourceSave, discardPendingSourceSave } = fileManager;
80172
80260
  const { drainPendingDomEditSaves, resetDomEditSaveQueueBreaker } = previewPersistence;
80173
- const bumpThumbnailContentRevision = usePlayerStore(
80174
- (state) => state.bumpThumbnailContentRevision
80261
+ const bumpThumbnailRevisions = usePlayerStore((state) => state.bumpThumbnailRevisions);
80262
+ const onAcceptedPersistedFileChange = useCallback136(
80263
+ (_path, affectedCompositions) => bumpThumbnailRevisions(affectedCompositions),
80264
+ [bumpThumbnailRevisions]
80175
80265
  );
80176
80266
  const drainPendingChanges = useCallback136(async () => {
80177
80267
  const source = await flushPendingSourceSave();
@@ -80200,12 +80290,12 @@ function useStudioExternalFileChanges({
80200
80290
  readProjectFile: fileManager.readProjectFile,
80201
80291
  onUseExternalFile: fileManager.updateEditingFileContent,
80202
80292
  resetSaveQueues: resetDomEditSaveQueueBreaker,
80203
- onAcceptedPersistedFileChange: bumpThumbnailContentRevision
80293
+ onAcceptedPersistedFileChange
80204
80294
  });
80205
80295
  }
80206
80296
 
80207
80297
  // src/hooks/useBlockHandlers.ts
80208
- import { useCallback as useCallback137, useMemo as useMemo67, useRef as useRef156, useState as useState118 } from "react";
80298
+ import { useCallback as useCallback137, useMemo as useMemo67, useRef as useRef156, useState as useState119 } from "react";
80209
80299
 
80210
80300
  // src/utils/blockInstaller.ts
80211
80301
  function getMaxZIndexFromIframe(iframe) {
@@ -80395,7 +80485,7 @@ function useBlockHandlers({
80395
80485
  setRightCollapsed,
80396
80486
  setRightPanelTab
80397
80487
  }) {
80398
- const [activeBlockParams, setActiveBlockParams] = useState118(null);
80488
+ const [activeBlockParams, setActiveBlockParams] = useState119(null);
80399
80489
  const blockCtx = useMemo67(
80400
80490
  () => ({
80401
80491
  activeCompPath: blockCtxDeps.activeCompPath,
@@ -81644,9 +81734,9 @@ function useCaptionDetection({
81644
81734
  }
81645
81735
 
81646
81736
  // src/hooks/useConsoleErrorCapture.ts
81647
- import { useCallback as useCallback141, useEffect as useEffect123, useRef as useRef160, useState as useState119 } from "react";
81737
+ import { useCallback as useCallback141, useEffect as useEffect123, useRef as useRef160, useState as useState120 } from "react";
81648
81738
  function useConsoleErrorCapture(previewIframe) {
81649
- const [consoleErrors, setConsoleErrors] = useState119(null);
81739
+ const [consoleErrors, setConsoleErrors] = useState120(null);
81650
81740
  const consoleErrorsRef = useRef160([]);
81651
81741
  const resetErrors = useCallback141(() => {
81652
81742
  consoleErrorsRef.current = [];
@@ -81717,15 +81807,15 @@ function useConsoleErrorCapture(previewIframe) {
81717
81807
  }
81718
81808
 
81719
81809
  // src/hooks/useFrameCapture.ts
81720
- import { useState as useState120, useCallback as useCallback142, useRef as useRef161 } from "react";
81810
+ import { useState as useState121, useCallback as useCallback142, useRef as useRef161 } from "react";
81721
81811
  function useFrameCapture({
81722
81812
  projectId,
81723
81813
  activeCompPath,
81724
81814
  showToast,
81725
81815
  waitForPendingDomEditSaves
81726
81816
  }) {
81727
- const [captureFrameTime, setCaptureFrameTime] = useState120(0);
81728
- const [capturing, setCapturing] = useState120(false);
81817
+ const [captureFrameTime, setCaptureFrameTime] = useState121(0);
81818
+ const [capturing, setCapturing] = useState121(false);
81729
81819
  const capturingRef = useRef161(false);
81730
81820
  useMountEffect(() => {
81731
81821
  setCaptureFrameTime(usePlayerStore.getState().currentTime);
@@ -81811,7 +81901,7 @@ function useFrameCapture({
81811
81901
  }
81812
81902
 
81813
81903
  // src/hooks/useLintModal.ts
81814
- import { useState as useState121, useCallback as useCallback143, useEffect as useEffect124, useRef as useRef162, useMemo as useMemo69 } from "react";
81904
+ import { useState as useState122, useCallback as useCallback143, useEffect as useEffect124, useRef as useRef162, useMemo as useMemo69 } from "react";
81815
81905
  function parseFinding(f) {
81816
81906
  return {
81817
81907
  severity: f.severity === "error" ? "error" : "warning",
@@ -81822,9 +81912,9 @@ function parseFinding(f) {
81822
81912
  };
81823
81913
  }
81824
81914
  function useLintModal(projectId, refreshKey) {
81825
- const [lintModal, setLintModal] = useState121(null);
81826
- const [linting, setLinting] = useState121(false);
81827
- const [backgroundFindings, setBackgroundFindings] = useState121([]);
81915
+ const [lintModal, setLintModal] = useState122(null);
81916
+ const [linting, setLinting] = useState122(false);
81917
+ const [backgroundFindings, setBackgroundFindings] = useState122([]);
81828
81918
  const autoLintRanRef = useRef162(false);
81829
81919
  const runLint = useCallback143(
81830
81920
  async (opts) => {
@@ -81902,13 +81992,13 @@ function useLintModal(projectId, refreshKey) {
81902
81992
  }
81903
81993
 
81904
81994
  // src/hooks/useToast.ts
81905
- import { useState as useState122, useCallback as useCallback144, useRef as useRef163 } from "react";
81995
+ import { useState as useState123, useCallback as useCallback144, useRef as useRef163 } from "react";
81906
81996
  var AUTO_DISMISS_MS2 = 4e3;
81907
81997
  var EXIT_MS2 = 160;
81908
81998
  var MAX_TOASTS = 3;
81909
81999
  var nextToastId = 1;
81910
82000
  function useToast() {
81911
- const [toasts, setToasts] = useState122([]);
82001
+ const [toasts, setToasts] = useState123([]);
81912
82002
  const timersRef = useRef163(/* @__PURE__ */ new Map());
81913
82003
  const clearTimer = useCallback144((id) => {
81914
82004
  const timer = timersRef.current.get(id);
@@ -81959,7 +82049,7 @@ function useToast() {
81959
82049
  }
81960
82050
 
81961
82051
  // src/hooks/useStudioUrlState.ts
81962
- import { useCallback as useCallback145, useEffect as useEffect125, useRef as useRef164, useState as useState123 } from "react";
82052
+ import { useCallback as useCallback145, useEffect as useEffect125, useRef as useRef164, useState as useState124 } from "react";
81963
82053
 
81964
82054
  // src/utils/studioUrlState.ts
81965
82055
  var VALID_TABS = ["layers", "design", "renders", "slideshow", "variables"];
@@ -82194,7 +82284,7 @@ function useStudioUrlState({
82194
82284
  const hydratedSeekRef = useRef164(initialState2.currentTime == null);
82195
82285
  const hydratedInitialTimeRef = useRef164(initialState2.currentTime == null);
82196
82286
  const hydratedSelectionRef = useRef164(initialState2.selection == null);
82197
- const [selectionHydrated, setSelectionHydrated] = useState123(initialState2.selection == null);
82287
+ const [selectionHydrated, setSelectionHydrated] = useState124(initialState2.selection == null);
82198
82288
  const pendingSelectionRef = useRef164(initialState2.selection);
82199
82289
  const stableTimeRef = useRef164(initialState2.currentTime);
82200
82290
  const selectionApplySeqRef = useRef164(0);
@@ -82425,10 +82515,10 @@ function useGlobalFileDrop(handleTimelineFileDrop) {
82425
82515
  }
82426
82516
 
82427
82517
  // src/hooks/useGestureCommit.ts
82428
- import { useState as useState125, useCallback as useCallback148, useRef as useRef166, useEffect as useEffect127 } from "react";
82518
+ import { useState as useState126, useCallback as useCallback148, useRef as useRef166, useEffect as useEffect127 } from "react";
82429
82519
 
82430
82520
  // src/hooks/useGestureRecording.ts
82431
- import { useCallback as useCallback147, useEffect as useEffect126, useRef as useRef165, useState as useState124 } from "react";
82521
+ import { useCallback as useCallback147, useEffect as useEffect126, useRef as useRef165, useState as useState125 } from "react";
82432
82522
  function readBasePosition(element, iframeEl) {
82433
82523
  let baseOpacity = 1;
82434
82524
  let baseScale = 1;
@@ -82571,8 +82661,8 @@ function releaseRuntimePreview(r) {
82571
82661
  r.runtime = null;
82572
82662
  }
82573
82663
  function useGestureRecording() {
82574
- const [isRecording, setIsRecording] = useState124(false);
82575
- const [recordingDuration, setRecordingDuration] = useState124(0);
82664
+ const [isRecording, setIsRecording] = useState125(false);
82665
+ const [recordingDuration, setRecordingDuration] = useState125(0);
82576
82666
  const isRecordingRef = useRef165(false);
82577
82667
  const refs = useRef165(createRecordingRefs());
82578
82668
  const samplesRef = useRef165(refs.current.samples);
@@ -82955,7 +83045,7 @@ function useGestureCommit({
82955
83045
  readOnlyPreview
82956
83046
  }) {
82957
83047
  const gestureRecording = useGestureRecording();
82958
- const [gestureState, setGestureState] = useState125("idle");
83048
+ const [gestureState, setGestureState] = useState126("idle");
82959
83049
  const gestureStateRef = useRef166("idle");
82960
83050
  const recordingAutoStopRef = useRef166(void 0);
82961
83051
  const recordingStartTimeRef = useRef166(0);
@@ -83315,7 +83405,7 @@ var GestureTrailOverlay = memo40(function GestureTrailOverlay2({
83315
83405
  import { useCallback as useCallback156 } from "react";
83316
83406
 
83317
83407
  // src/components/MediaPreview.tsx
83318
- import { useState as useState126 } from "react";
83408
+ import { useState as useState127 } from "react";
83319
83409
  import { jsx as jsx198, jsxs as jsxs157 } from "react/jsx-runtime";
83320
83410
  function MediaErrorPanel({ name, filePath }) {
83321
83411
  return /* @__PURE__ */ jsxs157("div", { className: "flex flex-col items-center justify-center h-full p-4 bg-neutral-950 gap-2", children: [
@@ -83345,7 +83435,7 @@ function MediaErrorPanel({ name, filePath }) {
83345
83435
  function MediaPreview({ projectId, filePath }) {
83346
83436
  const serveUrl = buildProjectApiPath(projectId, `/preview/${filePath}`);
83347
83437
  const name = filePath.split("/").pop() ?? filePath;
83348
- const [failedPath, setFailedPath] = useState126(null);
83438
+ const [failedPath, setFailedPath] = useState127(null);
83349
83439
  const failed2 = failedPath === filePath;
83350
83440
  const setFailed = () => setFailedPath(filePath);
83351
83441
  if (failed2) return /* @__PURE__ */ jsx198(MediaErrorPanel, { name, filePath });
@@ -83431,7 +83521,7 @@ function MediaPreview({ projectId, filePath }) {
83431
83521
  }
83432
83522
 
83433
83523
  // src/components/sidebar/AssetsTab.tsx
83434
- import { memo as memo41, useState as useState132, useCallback as useCallback152, useRef as useRef170, useMemo as useMemo74, useEffect as useEffect133 } from "react";
83524
+ import { memo as memo41, useState as useState133, useCallback as useCallback152, useRef as useRef170, useMemo as useMemo74, useEffect as useEffect133 } from "react";
83435
83525
 
83436
83526
  // src/components/ui/SearchInput.tsx
83437
83527
  import { jsx as jsx199, jsxs as jsxs158 } from "react/jsx-runtime";
@@ -83542,11 +83632,11 @@ var CATEGORY_LABELS = {
83542
83632
  var FILTER_ORDER = ["audio", "images", "video", "fonts"];
83543
83633
 
83544
83634
  // src/components/sidebar/AudioRow.tsx
83545
- import { useState as useState128, useRef as useRef168, useEffect as useEffect129, useCallback as useCallback150 } from "react";
83635
+ import { useState as useState129, useRef as useRef168, useEffect as useEffect129, useCallback as useCallback150 } from "react";
83546
83636
  import { classifyWebAudioMediaRoute } from "@hyperframes/core/runtime/web-audio-route";
83547
83637
 
83548
83638
  // src/components/sidebar/AssetContextMenu.tsx
83549
- import { useCallback as useCallback149, useEffect as useEffect128, useLayoutEffect as useLayoutEffect8, useRef as useRef167, useState as useState127 } from "react";
83639
+ import { useCallback as useCallback149, useEffect as useEffect128, useLayoutEffect as useLayoutEffect8, useRef as useRef167, useState as useState128 } from "react";
83550
83640
  import { Fragment as Fragment53, jsx as jsx200, jsxs as jsxs159 } from "react/jsx-runtime";
83551
83641
  function isValidAssetName(name) {
83552
83642
  return name.length > 0 && !/[/\\]/.test(name) && !name.includes("..");
@@ -83562,10 +83652,10 @@ function ContextMenu3({
83562
83652
  onAddAtPlayhead
83563
83653
  }) {
83564
83654
  const menuRef = useRef167(null);
83565
- const [pos, setPos] = useState127({ x, y });
83566
- const [mode, setMode] = useState127("menu");
83567
- const [renameDraft, setRenameDraft] = useState127(() => filename(asset));
83568
- const [renameError, setRenameError] = useState127(null);
83655
+ const [pos, setPos] = useState128({ x, y });
83656
+ const [mode, setMode] = useState128("menu");
83657
+ const [renameDraft, setRenameDraft] = useState128(() => filename(asset));
83658
+ const [renameError, setRenameError] = useState128(null);
83569
83659
  useLayoutEffect8(() => {
83570
83660
  const el = menuRef.current;
83571
83661
  if (!el) return;
@@ -83809,9 +83899,9 @@ function AudioRow({
83809
83899
  onRename,
83810
83900
  onAddAssetToTimeline
83811
83901
  }) {
83812
- const [contextMenu, setContextMenu] = useState128(null);
83813
- const [playing, setPlaying] = useState128(false);
83814
- const [bars, setBars] = useState128([]);
83902
+ const [contextMenu, setContextMenu] = useState129(null);
83903
+ const [playing, setPlaying] = useState129(false);
83904
+ const [bars, setBars] = useState129([]);
83815
83905
  const audioRef = useRef168(null);
83816
83906
  const actxRef = useRef168(null);
83817
83907
  const analyserRef = useRef168(null);
@@ -84043,7 +84133,7 @@ function AudioRow({
84043
84133
  }
84044
84134
 
84045
84135
  // src/components/sidebar/GlobalAssetsView.tsx
84046
- import { useEffect as useEffect130, useMemo as useMemo73, useState as useState129 } from "react";
84136
+ import { useEffect as useEffect130, useMemo as useMemo73, useState as useState130 } from "react";
84047
84137
  import { jsx as jsx202, jsxs as jsxs161 } from "react/jsx-runtime";
84048
84138
  function globalAssetRows(records, query = "") {
84049
84139
  const q = query.trim().toLowerCase();
@@ -84058,7 +84148,7 @@ function globalAssetRows(records, query = "") {
84058
84148
  }));
84059
84149
  }
84060
84150
  function GlobalAssetsView({ searchQuery }) {
84061
- const [records, setRecords] = useState129(null);
84151
+ const [records, setRecords] = useState130(null);
84062
84152
  useEffect130(() => {
84063
84153
  let cancelled = false;
84064
84154
  fetch("/api/assets/global").then((r) => r.ok ? r.json() : { assets: [] }).then((d) => {
@@ -84102,17 +84192,17 @@ function GlobalAssetsView({ searchQuery }) {
84102
84192
  }
84103
84193
 
84104
84194
  // src/components/sidebar/AssetCard.tsx
84105
- import { useState as useState131, useEffect as useEffect132, useRef as useRef169, useCallback as useCallback151 } from "react";
84195
+ import { useState as useState132, useEffect as useEffect132, useRef as useRef169, useCallback as useCallback151 } from "react";
84106
84196
 
84107
84197
  // src/components/ui/VideoFrameThumbnail.tsx
84108
- import { useState as useState130, useEffect as useEffect131 } from "react";
84198
+ import { useState as useState131, useEffect as useEffect131 } from "react";
84109
84199
  import { jsx as jsx203 } from "react/jsx-runtime";
84110
84200
  function VideoFrameThumbnail({
84111
84201
  src,
84112
84202
  fallbackLabel
84113
84203
  }) {
84114
- const [frame, setFrame] = useState130(null);
84115
- const [failed2, setFailed] = useState130(false);
84204
+ const [frame, setFrame] = useState131(null);
84205
+ const [failed2, setFailed] = useState131(false);
84116
84206
  useEffect131(() => {
84117
84207
  setFailed(false);
84118
84208
  const video = document.createElement("video");
@@ -84179,7 +84269,7 @@ function openAssetContextMenu(e, setContextMenu) {
84179
84269
  setContextMenu({ x: e.clientX, y: e.clientY });
84180
84270
  }
84181
84271
  function useProbedDuration(src, skip) {
84182
- const [duration, setDuration] = useState131(void 0);
84272
+ const [duration, setDuration] = useState132(void 0);
84183
84273
  useEffect132(() => {
84184
84274
  if (skip) return;
84185
84275
  let cancelled = false;
@@ -84230,9 +84320,9 @@ function AssetCard({
84230
84320
  onRename,
84231
84321
  onAddAssetToTimeline
84232
84322
  }) {
84233
- const [contextMenu, setContextMenu] = useState131(null);
84234
- const [hovered, setHovered] = useState131(false);
84235
- const [imgError, setImgError] = useState131(false);
84323
+ const [contextMenu, setContextMenu] = useState132(null);
84324
+ const [hovered, setHovered] = useState132(false);
84325
+ const [imgError, setImgError] = useState132(false);
84236
84326
  const isCopied = copyFeedback?.path === asset && copyFeedback.ok;
84237
84327
  const fullName = asset.split("/").pop() ?? asset;
84238
84328
  const name = basename2(asset);
@@ -84374,7 +84464,7 @@ function FontRow({
84374
84464
  onRename,
84375
84465
  onAddAssetToTimeline
84376
84466
  }) {
84377
- const [contextMenu, setContextMenu] = useState131(null);
84467
+ const [contextMenu, setContextMenu] = useState132(null);
84378
84468
  const name = basename2(asset);
84379
84469
  const extension = ext(asset);
84380
84470
  const isCopied = copyFeedback?.path === asset && copyFeedback.ok;
@@ -84569,14 +84659,14 @@ var AssetsTab = memo41(function AssetsTab2({
84569
84659
  onAddAssetToTimeline
84570
84660
  }) {
84571
84661
  const fileInputRef = useRef170(null);
84572
- const [dragOver, setDragOver] = useState132(false);
84573
- const [copyFeedback, setCopyFeedback] = useState132(null);
84574
- const [importing, setImporting] = useState132(false);
84575
- const [activeFilter, setActiveFilter] = useState132("all");
84576
- const [usageFilter, setUsageFilter] = useState132("all");
84577
- const [searchQuery, setSearchQuery] = useState132("");
84578
- const [viewMode, setViewMode] = useState132("local");
84579
- const [manifest, setManifest] = useState132(/* @__PURE__ */ new Map());
84662
+ const [dragOver, setDragOver] = useState133(false);
84663
+ const [copyFeedback, setCopyFeedback] = useState133(null);
84664
+ const [importing, setImporting] = useState133(false);
84665
+ const [activeFilter, setActiveFilter] = useState133("all");
84666
+ const [usageFilter, setUsageFilter] = useState133("all");
84667
+ const [searchQuery, setSearchQuery] = useState133("");
84668
+ const [viewMode, setViewMode] = useState133("local");
84669
+ const [manifest, setManifest] = useState133(/* @__PURE__ */ new Map());
84580
84670
  const manifest404Ref = useRef170(/* @__PURE__ */ new Set());
84581
84671
  const assetsKey = assets.join("|");
84582
84672
  useEffect133(() => {
@@ -84836,20 +84926,20 @@ var AssetsTab = memo41(function AssetsTab2({
84836
84926
  });
84837
84927
 
84838
84928
  // src/components/sidebar/BlocksTab.tsx
84839
- import { memo as memo42, useState as useState134, useCallback as useCallback154, useRef as useRef172, useEffect as useEffect135 } from "react";
84929
+ import { memo as memo42, useState as useState135, useCallback as useCallback154, useRef as useRef172, useEffect as useEffect135 } from "react";
84840
84930
  import { createPortal as createPortal9 } from "react-dom";
84841
84931
 
84842
84932
  // src/components/sidebar/PromptPreviewModal.tsx
84843
- import { useState as useState133, useCallback as useCallback153, useEffect as useEffect134, useRef as useRef171 } from "react";
84933
+ import { useState as useState134, useCallback as useCallback153, useEffect as useEffect134, useRef as useRef171 } from "react";
84844
84934
  import { jsx as jsx206, jsxs as jsxs164 } from "react/jsx-runtime";
84845
84935
  function PromptPreviewModal({
84846
84936
  title,
84847
84937
  prompt,
84848
84938
  onClose
84849
84939
  }) {
84850
- const [value, setValue] = useState133(prompt);
84851
- const [copyState, setCopyState] = useState133("idle");
84852
- const [entered, setEntered] = useState133(false);
84940
+ const [value, setValue] = useState134(prompt);
84941
+ const [copyState, setCopyState] = useState134("idle");
84942
+ const [entered, setEntered] = useState134(false);
84853
84943
  const containerRef = useRef171(null);
84854
84944
  const textareaRef = useRef171(null);
84855
84945
  const valueRef = useRef171(value);
@@ -84962,7 +85052,7 @@ function PromptPreviewModal({
84962
85052
  import { jsx as jsx207, jsxs as jsxs165 } from "react/jsx-runtime";
84963
85053
  var BlocksTab = memo42(function BlocksTab2({ onAddBlock, onPreviewBlock }) {
84964
85054
  const { loading, error, search, setSearch, category, setCategory, filteredBlocks } = useBlockCatalog();
84965
- const [promptModal, setPromptModal] = useState134(null);
85055
+ const [promptModal, setPromptModal] = useState135(null);
84966
85056
  if (loading) {
84967
85057
  return /* @__PURE__ */ jsx207("div", { className: "flex flex-1 items-center justify-center text-neutral-600 text-xs", children: "Loading blocks\u2026" });
84968
85058
  }
@@ -85147,8 +85237,8 @@ function BlockCard({
85147
85237
  onShowPrompt,
85148
85238
  onPreview
85149
85239
  }) {
85150
- const [hovered, setHovered] = useState134(false);
85151
- const [addState, setAddState] = useState134("idle");
85240
+ const [hovered, setHovered] = useState135(false);
85241
+ const [addState, setAddState] = useState135("idle");
85152
85242
  const hoverTimer = useRef172(null);
85153
85243
  const colors = getCategoryColors(category);
85154
85244
  const needsWebGL = tags?.includes("html-in-canvas") || tags?.includes("webgl");
@@ -85327,7 +85417,7 @@ function BlockCard({
85327
85417
  }
85328
85418
 
85329
85419
  // src/components/sidebar/CompositionsTab.tsx
85330
- import { memo as memo43, useCallback as useCallback155, useEffect as useEffect136, useRef as useRef173, useState as useState135 } from "react";
85420
+ import { memo as memo43, useCallback as useCallback155, useEffect as useEffect136, useRef as useRef173, useState as useState136 } from "react";
85331
85421
  import { jsx as jsx208, jsxs as jsxs166 } from "react/jsx-runtime";
85332
85422
  var DEFAULT_PREVIEW_STAGE = { width: 1920, height: 1080 };
85333
85423
  var CARD_W = 80;
@@ -85397,10 +85487,10 @@ function CompCard({
85397
85487
  onAddToTimeline,
85398
85488
  contentRevision
85399
85489
  }) {
85400
- const [hovered, setHovered] = useState135(false);
85401
- const [stageSize, setStageSize] = useState135(DEFAULT_PREVIEW_STAGE);
85402
- const [livePreviewLoaded, setLivePreviewLoaded] = useState135(false);
85403
- const [failedThumbnailUrl, setFailedThumbnailUrl] = useState135(null);
85490
+ const [hovered, setHovered] = useState136(false);
85491
+ const [stageSize, setStageSize] = useState136(DEFAULT_PREVIEW_STAGE);
85492
+ const [livePreviewLoaded, setLivePreviewLoaded] = useState136(false);
85493
+ const [failedThumbnailUrl, setFailedThumbnailUrl] = useState136(null);
85404
85494
  const iframeRef = useRef173(null);
85405
85495
  const hoverTimer = useRef173(null);
85406
85496
  const syncTimer = useRef173(null);
@@ -85627,7 +85717,7 @@ var CompositionsTab = memo43(function CompositionsTab2({
85627
85717
  isRendering,
85628
85718
  lintFindingsByFile
85629
85719
  }) {
85630
- const contentRevision = usePlayerStore((state) => state.thumbnailContentRevision);
85720
+ const thumbnailRevisions = usePlayerStore((state) => state.thumbnailRevisions);
85631
85721
  if (compositions.length === 0) {
85632
85722
  return /* @__PURE__ */ jsx208("div", { className: "flex-1 flex items-center justify-center px-4", children: /* @__PURE__ */ jsx208("p", { className: "text-xs text-neutral-600 text-center", children: "No compositions found" }) });
85633
85723
  }
@@ -85643,7 +85733,7 @@ var CompositionsTab = memo43(function CompositionsTab2({
85643
85733
  onAddToTimeline: onAddToTimeline ? () => onAddToTimeline(comp) : void 0,
85644
85734
  isRendering,
85645
85735
  lintInfo: lintFindingsByFile?.get(comp),
85646
- contentRevision
85736
+ contentRevision: thumbnailRevisionOf(thumbnailRevisions, comp)
85647
85737
  },
85648
85738
  `${projectId}:${comp}`
85649
85739
  )) });
@@ -85883,10 +85973,10 @@ function CodeBody({
85883
85973
  import { useCallback as useCallback172 } from "react";
85884
85974
 
85885
85975
  // src/components/editor/LayersPanel.tsx
85886
- import { memo as memo44, useState as useState137, useCallback as useCallback158, useEffect as useEffect137, useRef as useRef175 } from "react";
85976
+ import { memo as memo44, useState as useState138, useCallback as useCallback158, useEffect as useEffect137, useRef as useRef175 } from "react";
85887
85977
 
85888
85978
  // src/components/editor/useLayerDrag.ts
85889
- import { useRef as useRef174, useState as useState136, useCallback as useCallback157 } from "react";
85979
+ import { useRef as useRef174, useState as useState137, useCallback as useCallback157 } from "react";
85890
85980
  var DRAG_THRESHOLD_PX4 = 4;
85891
85981
  function isLayerDraggable(layer) {
85892
85982
  if (!(layer.selector || layer.id)) return false;
@@ -85954,8 +86044,8 @@ function useLayerDrag({
85954
86044
  onSingleSibling
85955
86045
  }) {
85956
86046
  const dragRef = useRef174(null);
85957
- const [dragKey, setDragKey] = useState136(null);
85958
- const [insertionLineY, setInsertionLineY] = useState136(null);
86047
+ const [dragKey, setDragKey] = useState137(null);
86048
+ const [insertionLineY, setInsertionLineY] = useState137(null);
85959
86049
  const handleRowPointerDown = useCallback157(
85960
86050
  (layerIndex, e) => {
85961
86051
  if (e.button !== 0) return;
@@ -86157,8 +86247,8 @@ var LayersPanel = memo44(function LayersPanel2() {
86157
86247
  handleDomZIndexReorderCommit,
86158
86248
  setActiveGroupElement
86159
86249
  } = useDomEditContext();
86160
- const [layers, setLayers] = useState137([]);
86161
- const [collapsed, setCollapsed] = useState137({});
86250
+ const [layers, setLayers] = useState138([]);
86251
+ const [collapsed, setCollapsed] = useState138({});
86162
86252
  const prevDocVersionRef = useRef175(0);
86163
86253
  const scrollContainerRef = useRef175(null);
86164
86254
  const mirrorLayerReorderToTimeline = useLayerReorderTimelineMirror();
@@ -86497,13 +86587,13 @@ var LayersPanel = memo44(function LayersPanel2() {
86497
86587
  });
86498
86588
 
86499
86589
  // src/captions/components/CaptionPropertyPanel.tsx
86500
- import { memo as memo46, useCallback as useCallback160, useState as useState139 } from "react";
86590
+ import { memo as memo46, useCallback as useCallback160, useState as useState140 } from "react";
86501
86591
 
86502
86592
  // src/captions/components/CaptionAnimationPanel.tsx
86503
86593
  import { memo as memo45, useCallback as useCallback159 } from "react";
86504
86594
 
86505
86595
  // src/captions/components/shared.tsx
86506
- import { useEffect as useEffect138, useRef as useRef176, useState as useState138 } from "react";
86596
+ import { useEffect as useEffect138, useRef as useRef176, useState as useState139 } from "react";
86507
86597
  import { jsx as jsx213, jsxs as jsxs170 } from "react/jsx-runtime";
86508
86598
  var inputCls = "w-full bg-neutral-900 border border-neutral-800 rounded-sm px-1.5 py-0.5 text-2xs text-neutral-200 font-mono outline-hidden focus:border-studio-accent disabled:opacity-40 disabled:cursor-not-allowed";
86509
86599
  function Section2({ label, children }) {
@@ -86528,7 +86618,7 @@ function NumberField2({
86528
86618
  ariaLabel,
86529
86619
  onCommit
86530
86620
  }) {
86531
- const [draft, setDraft] = useState138(null);
86621
+ const [draft, setDraft] = useState139(null);
86532
86622
  const focusedRef = useRef176(false);
86533
86623
  useEffect138(() => {
86534
86624
  if (!focusedRef.current) setDraft(null);
@@ -86824,7 +86914,7 @@ var CaptionPropertyPanel = memo46(function CaptionPropertyPanel2({
86824
86914
  const selectedGroupId = useCaptionStore((s) => s.selectedGroupId);
86825
86915
  const updateSelectedStyle = useCaptionStore((s) => s.updateSelectedStyle);
86826
86916
  const updateGroupStyle = useCaptionStore((s) => s.updateGroupStyle);
86827
- const [activeTab, setActiveTab] = useState139("style");
86917
+ const [activeTab, setActiveTab] = useState140("style");
86828
86918
  const firstSegmentId = selectedSegmentIds.size > 0 ? [...selectedSegmentIds][0] : void 0;
86829
86919
  const firstSegment = model?.segments.get(firstSegmentId ?? "");
86830
86920
  let ownerGroupId = null;
@@ -87022,7 +87112,7 @@ var CaptionPropertyPanel = memo46(function CaptionPropertyPanel2({
87022
87112
  });
87023
87113
 
87024
87114
  // src/components/editor/BlockParamsPanel.tsx
87025
- import { memo as memo47, useCallback as useCallback161, useEffect as useEffect139, useRef as useRef177, useState as useState140 } from "react";
87115
+ import { memo as memo47, useCallback as useCallback161, useEffect as useEffect139, useRef as useRef177, useState as useState141 } from "react";
87026
87116
  import { jsx as jsx216, jsxs as jsxs173 } from "react/jsx-runtime";
87027
87117
  var BlockParamsPanel = memo47(function BlockParamsPanel2({
87028
87118
  blockName,
@@ -87033,7 +87123,7 @@ var BlockParamsPanel = memo47(function BlockParamsPanel2({
87033
87123
  }) {
87034
87124
  const fileManager = useFileManagerContextOptional();
87035
87125
  const { setRefreshKey } = useStudioPlaybackContext();
87036
- const [values, setValues] = useState140(() => {
87126
+ const [values, setValues] = useState141(() => {
87037
87127
  const initial = {};
87038
87128
  for (const p of params) {
87039
87129
  initial[p.key] = p.default;
@@ -87043,7 +87133,7 @@ var BlockParamsPanel = memo47(function BlockParamsPanel2({
87043
87133
  const appliedRef = useRef177(
87044
87134
  Object.fromEntries(params.map((p) => [p.key, p.default]))
87045
87135
  );
87046
- const [commitState, setCommitState] = useState140({ tone: "idle" });
87136
+ const [commitState, setCommitState] = useState141({ tone: "idle" });
87047
87137
  const commitTimersRef = useRef177(/* @__PURE__ */ new Map());
87048
87138
  const commitParamNow = useCallback161(
87049
87139
  async (key2, nextValue) => {
@@ -87253,12 +87343,12 @@ function ParamControl({
87253
87343
  import { memo as memo51 } from "react";
87254
87344
 
87255
87345
  // src/components/renders/RenderQueue.tsx
87256
- import { memo as memo50, useState as useState143, useRef as useRef179, useEffect as useEffect141, useLayoutEffect as useLayoutEffect9, useId as useId7 } from "react";
87346
+ import { memo as memo50, useState as useState144, useRef as useRef179, useEffect as useEffect141, useLayoutEffect as useLayoutEffect9, useId as useId7 } from "react";
87257
87347
  import { createPortal as createPortal10 } from "react-dom";
87258
87348
  import { CANVAS_DIMENSIONS } from "@hyperframes/parsers";
87259
87349
 
87260
87350
  // src/components/renders/RenderQueueItem.tsx
87261
- import { memo as memo48, useCallback as useCallback162, useState as useState141 } from "react";
87351
+ import { memo as memo48, useCallback as useCallback162, useState as useState142 } from "react";
87262
87352
  import { Fragment as Fragment58, jsx as jsx217, jsxs as jsxs174 } from "react/jsx-runtime";
87263
87353
  function formatDuration2(ms) {
87264
87354
  if (ms < 1e3) return `${ms}ms`;
@@ -87277,9 +87367,9 @@ var RenderQueueItem = memo48(function RenderQueueItem2({
87277
87367
  onDelete,
87278
87368
  onCancel
87279
87369
  }) {
87280
- const [hovered, setHovered] = useState141(false);
87281
- const [videoReady, setVideoReady] = useState141(false);
87282
- const [confirmingDelete, setConfirmingDelete] = useState141(false);
87370
+ const [hovered, setHovered] = useState142(false);
87371
+ const [videoReady, setVideoReady] = useState142(false);
87372
+ const [confirmingDelete, setConfirmingDelete] = useState142(false);
87283
87373
  const fileSrc = buildProjectApiPath(projectId, `/renders/file/${job.filename}`);
87284
87374
  const handleOpen = useCallback162(() => {
87285
87375
  window.open(fileSrc, "_blank");
@@ -87484,7 +87574,7 @@ var RenderQueueItem = memo48(function RenderQueueItem2({
87484
87574
  });
87485
87575
 
87486
87576
  // src/components/renders/FfmpegRequiredNotice.tsx
87487
- import { memo as memo49, useEffect as useEffect140, useRef as useRef178, useState as useState142 } from "react";
87577
+ import { memo as memo49, useEffect as useEffect140, useRef as useRef178, useState as useState143 } from "react";
87488
87578
  import { jsx as jsx218, jsxs as jsxs175 } from "react/jsx-runtime";
87489
87579
  var DOWNLOAD_URL = "https://ffmpeg.org/download.html";
87490
87580
  var CUE_MS = 1600;
@@ -87494,8 +87584,8 @@ var FfmpegRequiredNotice = memo49(function FfmpegRequiredNotice2({
87494
87584
  checking,
87495
87585
  onRecheck
87496
87586
  }) {
87497
- const [copied, setCopied] = useState142(false);
87498
- const [recheckFailed, setRecheckFailed] = useState142(false);
87587
+ const [copied, setCopied] = useState143(false);
87588
+ const [recheckFailed, setRecheckFailed] = useState143(false);
87499
87589
  const wasChecking = useRef178(false);
87500
87590
  const cueTimer = useRef178(void 0);
87501
87591
  useEffect140(() => {
@@ -87625,8 +87715,8 @@ var FORMAT_INFO = {
87625
87715
  };
87626
87716
  var FORMAT_PANEL_SIZE = { width: 208, height: 150 };
87627
87717
  function FormatInfoTooltip({ format }) {
87628
- const [open, setOpen] = useState143(false);
87629
- const [position, setPosition] = useState143(null);
87718
+ const [open, setOpen] = useState144(false);
87719
+ const [position, setPosition] = useState144(null);
87630
87720
  const triggerRef = useRef179(null);
87631
87721
  const timeoutRef = useRef179(void 0);
87632
87722
  const panelId = useId7();
@@ -87747,10 +87837,10 @@ function FormatExportButton({
87747
87837
  onRecheckFfmpeg
87748
87838
  }) {
87749
87839
  const persisted = getPersistedRenderSettings();
87750
- const [format, setFormat] = useState143(persisted.format);
87751
- const [quality, setQuality] = useState143(persisted.quality);
87752
- const [resolution, setResolution] = useState143("auto");
87753
- const [fps, setFps] = useState143(persisted.fps);
87840
+ const [format, setFormat] = useState144(persisted.format);
87841
+ const [quality, setQuality] = useState144(persisted.quality);
87842
+ const [resolution, setResolution] = useState144("auto");
87843
+ const [fps, setFps] = useState144(persisted.fps);
87754
87844
  const missingFfmpeg = ffmpeg && !ffmpeg.ok ? ffmpeg : null;
87755
87845
  const showQuality = format !== "mov";
87756
87846
  return /* @__PURE__ */ jsxs176("div", { className: "flex flex-col gap-3", children: [
@@ -88032,11 +88122,11 @@ var RenderQueuePanel = memo51(function RenderQueuePanel2() {
88032
88122
  });
88033
88123
 
88034
88124
  // src/components/panels/SlideshowPanel.tsx
88035
- import { useState as useState145, useEffect as useEffect142, useCallback as useCallback164, useRef as useRef180 } from "react";
88125
+ import { useState as useState146, useEffect as useEffect142, useCallback as useCallback164, useRef as useRef180 } from "react";
88036
88126
  import { parseSlideshowManifest } from "@hyperframes/core/slideshow";
88037
88127
 
88038
88128
  // src/components/panels/SlideshowSubPanels.tsx
88039
- import { useState as useState144, useCallback as useCallback163, useId as useId8 } from "react";
88129
+ import { useState as useState145, useCallback as useCallback163, useId as useId8 } from "react";
88040
88130
  import { jsx as jsx221, jsxs as jsxs177 } from "react/jsx-runtime";
88041
88131
  function SectionHeader({
88042
88132
  children,
@@ -88222,7 +88312,7 @@ function BranchTree({
88222
88312
  selectedSequenceId,
88223
88313
  onSelectBranchSlide
88224
88314
  }) {
88225
- const [newLabel, setNewLabel] = useState144("");
88315
+ const [newLabel, setNewLabel] = useState145("");
88226
88316
  const inputId = useId8();
88227
88317
  const handleCreate = useCallback163(() => {
88228
88318
  const label = newLabel.trim();
@@ -88283,9 +88373,9 @@ function BranchItem({
88283
88373
  selectedSequenceId,
88284
88374
  onSelectBranchSlide
88285
88375
  }) {
88286
- const [editing, setEditing] = useState144(false);
88287
- const [draft, setDraft] = useState144(seq.label);
88288
- const [confirmingDelete, setConfirmingDelete] = useState144(false);
88376
+ const [editing, setEditing] = useState145(false);
88377
+ const [draft, setDraft] = useState145(seq.label);
88378
+ const [confirmingDelete, setConfirmingDelete] = useState145(false);
88289
88379
  const commitRename = useCallback163(() => {
88290
88380
  const label = draft.trim();
88291
88381
  if (label && label !== seq.label) onRename(seq.id, label);
@@ -88413,8 +88503,8 @@ function HotspotTool({
88413
88503
  onAddHotspot,
88414
88504
  onRemoveHotspot
88415
88505
  }) {
88416
- const [targetSequenceId, setTargetSequenceId] = useState144("");
88417
- const [hotspotLabel, setHotspotLabel] = useState144("");
88506
+ const [targetSequenceId, setTargetSequenceId] = useState145("");
88507
+ const [hotspotLabel, setHotspotLabel] = useState145("");
88418
88508
  const hotspots = slide?.hotspots ?? [];
88419
88509
  const selectedElementId = domEditSelection?.element?.id ?? null;
88420
88510
  const selectedHfId = domEditSelection?.hfId ?? null;
@@ -88707,19 +88797,19 @@ function makeSlideshowNotesController() {
88707
88797
  function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
88708
88798
  const { editingFile } = useFileManagerContext();
88709
88799
  const compHtml = editingFile?.content ?? null;
88710
- const [manifest, setManifest] = useState145(() => {
88800
+ const [manifest, setManifest] = useState146(() => {
88711
88801
  if (!compHtml) return { slides: [] };
88712
88802
  return safeParseManifest(compHtml);
88713
88803
  });
88714
- const [selectedSceneId, setSelectedSceneId] = useState145(null);
88715
- const [selectedSequenceId, setSelectedSequenceId] = useState145(null);
88716
- const [expandedSections, setExpandedSections] = useState145(
88804
+ const [selectedSceneId, setSelectedSceneId] = useState146(null);
88805
+ const [selectedSequenceId, setSelectedSequenceId] = useState146(null);
88806
+ const [expandedSections, setExpandedSections] = useState146(
88717
88807
  () => /* @__PURE__ */ new Set(["slides", "inspector"])
88718
88808
  );
88719
- const [persistError, setPersistError] = useState145(false);
88720
- const [retrying, setRetrying] = useState145(false);
88809
+ const [persistError, setPersistError] = useState146(false);
88810
+ const [retrying, setRetrying] = useState146(false);
88721
88811
  const undoStackRef = useRef180([]);
88722
- const [undoDepth, setUndoDepth] = useState145(0);
88812
+ const [undoDepth, setUndoDepth] = useState146(0);
88723
88813
  const currentTime = usePlayerStore((s) => s.currentTime);
88724
88814
  const { domEditSelection } = useDomEditSelectionContext();
88725
88815
  const manifestRef = useRef180(manifest);
@@ -89048,7 +89138,7 @@ function SlideshowPanel({ scenes, onPersist, onPersistNotes }) {
89048
89138
  }
89049
89139
 
89050
89140
  // src/components/panels/VariablesPanel.tsx
89051
- import { memo as memo52, useCallback as useCallback168, useEffect as useEffect144, useMemo as useMemo75, useState as useState149 } from "react";
89141
+ import { memo as memo52, useCallback as useCallback168, useEffect as useEffect144, useMemo as useMemo75, useState as useState150 } from "react";
89052
89142
 
89053
89143
  // src/hooks/useVariablesPersist.ts
89054
89144
  import { useCallback as useCallback165 } from "react";
@@ -89096,10 +89186,10 @@ function useVariablesPersist({
89096
89186
  }
89097
89187
 
89098
89188
  // src/components/panels/VariablesOtherCompositions.tsx
89099
- import { useCallback as useCallback167, useState as useState148 } from "react";
89189
+ import { useCallback as useCallback167, useState as useState149 } from "react";
89100
89190
 
89101
89191
  // src/hooks/useProjectCompositionVariables.ts
89102
- import { useCallback as useCallback166, useEffect as useEffect143, useState as useState146 } from "react";
89192
+ import { useCallback as useCallback166, useEffect as useEffect143, useState as useState147 } from "react";
89103
89193
  import { openComposition as openComposition4 } from "@hyperframes/sdk";
89104
89194
  async function readGroup(path, readProjectFile) {
89105
89195
  let content;
@@ -89122,7 +89212,7 @@ async function readGroup(path, readProjectFile) {
89122
89212
  }
89123
89213
  }
89124
89214
  function useProjectCompositionVariables(fileTree, excludePath, readProjectFile, refreshKey) {
89125
- const [groups, setGroups] = useState146([]);
89215
+ const [groups, setGroups] = useState147([]);
89126
89216
  useEffect143(() => {
89127
89217
  let cancelled = false;
89128
89218
  const htmlFiles = fileTree.filter((p) => p.endsWith(".html") && p !== excludePath);
@@ -89172,7 +89262,7 @@ function useEditVariablesInFile(deps) {
89172
89262
  }
89173
89263
 
89174
89264
  // src/components/panels/VariablesDeclarationForm.tsx
89175
- import { useState as useState147 } from "react";
89265
+ import { useState as useState148 } from "react";
89176
89266
  import { jsx as jsx223, jsxs as jsxs179 } from "react/jsx-runtime";
89177
89267
  var VARIABLE_TYPES = [
89178
89268
  "string",
@@ -89314,8 +89404,8 @@ function DeclarationForm({
89314
89404
  onSubmit,
89315
89405
  onCancel
89316
89406
  }) {
89317
- const [draft, setDraft] = useState147(initial);
89318
- const [error, setError] = useState147(null);
89407
+ const [draft, setDraft] = useState148(initial);
89408
+ const [error, setError] = useState148(null);
89319
89409
  const editingExisting = initial.id.length > 0;
89320
89410
  const set = (patch) => setDraft((d) => ({ ...d, ...patch }));
89321
89411
  const submit = () => {
@@ -89505,7 +89595,7 @@ function VariablesOtherCompositions({
89505
89595
  recordEdit,
89506
89596
  reloadPreview
89507
89597
  }) {
89508
- const [selfRefresh, setSelfRefresh] = useState148(0);
89598
+ const [selfRefresh, setSelfRefresh] = useState149(0);
89509
89599
  const groups = useProjectCompositionVariables(
89510
89600
  fileTree,
89511
89601
  excludePath,
@@ -89518,7 +89608,7 @@ function VariablesOtherCompositions({
89518
89608
  recordEdit,
89519
89609
  reloadPreview
89520
89610
  });
89521
- const [editingKey, setEditingKey] = useState148(null);
89611
+ const [editingKey, setEditingKey] = useState149(null);
89522
89612
  const onSave = useCallback167(
89523
89613
  (path, decl) => {
89524
89614
  setEditingKey(null);
@@ -89728,13 +89818,13 @@ var VariablesPanel = memo52(function VariablesPanel2({
89728
89818
  const effectiveCompPath = activeCompPath ?? resolveMasterCompositionPath(compositions);
89729
89819
  const previewValues = usePreviewVariablesStore((s) => s.values);
89730
89820
  const setPreviewValues = usePreviewVariablesStore((s) => s.setValues);
89731
- const [revision, setRevision] = useState149(0);
89821
+ const [revision, setRevision] = useState150(0);
89732
89822
  useEffect144(() => {
89733
89823
  if (!sdkSession) return;
89734
89824
  return sdkSession.on("change", () => setRevision((r) => r + 1));
89735
89825
  }, [sdkSession]);
89736
- const [addOpen, setAddOpen] = useState149(false);
89737
- const [editingId, setEditingId] = useState149(null);
89826
+ const [addOpen, setAddOpen] = useState150(false);
89827
+ const [editingId, setEditingId] = useState150(null);
89738
89828
  const persistVariables = useVariablesPersist({
89739
89829
  sdkSession,
89740
89830
  activeCompPath: effectiveCompPath,
@@ -91612,7 +91702,7 @@ function StudioSplash({ waiting }) {
91612
91702
  }
91613
91703
 
91614
91704
  // src/hooks/useServerConnection.ts
91615
- import { useEffect as useEffect148, useState as useState150 } from "react";
91705
+ import { useEffect as useEffect148, useState as useState151 } from "react";
91616
91706
  async function resolveHashProject(id) {
91617
91707
  try {
91618
91708
  const res = await fetch(`/api/projects/${encodeURIComponent(id)}`);
@@ -91642,9 +91732,9 @@ function reportHashVerdict(stage, verdict) {
91642
91732
  });
91643
91733
  }
91644
91734
  function useServerConnection() {
91645
- const [projectId, setProjectId] = useState150(null);
91646
- const [resolving, setResolving] = useState150(true);
91647
- const [waitingForServer, setWaitingForServer] = useState150(false);
91735
+ const [projectId, setProjectId] = useState151(null);
91736
+ const [resolving, setResolving] = useState151(true);
91737
+ const [waitingForServer, setWaitingForServer] = useState151(false);
91648
91738
  useMountEffect(() => {
91649
91739
  const hashProjectId = parseProjectIdFromHash(window.location.hash);
91650
91740
  let cancelled = false;
@@ -91735,7 +91825,7 @@ function useTimelineAddAtPlayhead(addAsset, addComposition) {
91735
91825
  }
91736
91826
 
91737
91827
  // src/hooks/useActiveComposition.ts
91738
- import { useState as useState151 } from "react";
91828
+ import { useState as useState152 } from "react";
91739
91829
 
91740
91830
  // src/hooks/useHydrateActiveCompPathFromUrl.ts
91741
91831
  import { useEffect as useEffect150 } from "react";
@@ -91839,8 +91929,8 @@ function useActiveComposition({
91839
91929
  setEditingFile,
91840
91930
  showToast
91841
91931
  }) {
91842
- const [activeCompPath, setActiveCompPath] = useState151(null);
91843
- const [activeCompPathHydrated, setActiveCompPathHydrated] = useState151(
91932
+ const [activeCompPath, setActiveCompPath] = useState152(null);
91933
+ const [activeCompPathHydrated, setActiveCompPathHydrated] = useState152(
91844
91934
  () => isHydratedFromUrlState(initialUrlStateRef.current)
91845
91935
  );
91846
91936
  useResetSelectionOnProjectSwitch({
@@ -91880,12 +91970,12 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
91880
91970
  const { projectId, resolving, waitingForServer } = useServerConnection();
91881
91971
  const initialUrlStateRef = useRef185(readStudioUrlStateFromWindow());
91882
91972
  useStudioSessionStart(projectId, resolving, waitingForServer);
91883
- const [compIdToSrc, setCompIdToSrc] = useState152(/* @__PURE__ */ new Map());
91973
+ const [compIdToSrc, setCompIdToSrc] = useState153(/* @__PURE__ */ new Map());
91884
91974
  const previewIframe = useOwnPreviewIframe();
91885
- const [compositionLoading, setCompositionLoading] = useState152(true);
91886
- const [refreshKey, setRefreshKey] = useState152(0);
91975
+ const [compositionLoading, setCompositionLoading] = useState153(true);
91976
+ const [refreshKey, setRefreshKey] = useState153(0);
91887
91977
  const [previewDocumentVersion, refreshPreviewDocumentVersion] = usePreviewDocumentVersion();
91888
- const [blockPreview, setBlockPreview] = useState152(null);
91978
+ const [blockPreview, setBlockPreview] = useState153(null);
91889
91979
  const previewIframeRef = useRef185(null);
91890
91980
  const captionEditMode = useCaptionStore((s) => s.isEditMode);
91891
91981
  const captionHasSelection = useCaptionStore((s) => s.selectedSegmentIds.size > 0);
@@ -92387,10 +92477,10 @@ function StudioApp({ readOnlyPreview = false, readOnlyPreviewReason } = {}) {
92387
92477
  }
92388
92478
 
92389
92479
  // src/hooks/useElementPicker.ts
92390
- import { useState as useState153, useCallback as useCallback178, useRef as useRef186 } from "react";
92480
+ import { useState as useState154, useCallback as useCallback178, useRef as useRef186 } from "react";
92391
92481
  function useElementPicker(iframeRef, options) {
92392
- const [isPickMode, setIsPickMode] = useState153(false);
92393
- const [pickedElement, setPickedElement] = useState153(null);
92482
+ const [isPickMode, setIsPickMode] = useState154(false);
92483
+ const [pickedElement, setPickedElement] = useState154(null);
92394
92484
  const activeOverrideRef = useRef186(null);
92395
92485
  const getActiveIframe = useCallback178(() => {
92396
92486
  return activeOverrideRef.current ?? iframeRef.current;