hyperframes 0.8.57 → 0.8.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/dist/cli.js +5300 -3428
  2. package/dist/docs/data-attributes.md +2 -1
  3. package/dist/fontLocalizeCli.js +73 -12
  4. package/dist/hyperframe-runtime.js +25 -25
  5. package/dist/hyperframe.manifest.json +1 -1
  6. package/dist/hyperframe.runtime.iife.js +25 -25
  7. package/dist/hyperframes-player.global.js +3 -3
  8. package/dist/registry/localSemantic.js +548 -0
  9. package/dist/skills/hyperframes-cli/SKILL.md +2 -2
  10. package/dist/skills/media-use/SKILL.md +96 -0
  11. package/dist/skills/media-use/audio/assets/sfx/CREDITS.md +35 -0
  12. package/dist/skills/media-use/audio/assets/sfx/chime.mp3 +0 -0
  13. package/dist/skills/media-use/audio/assets/sfx/click-soft.mp3 +0 -0
  14. package/dist/skills/media-use/audio/assets/sfx/click.mp3 +0 -0
  15. package/dist/skills/media-use/audio/assets/sfx/error.mp3 +0 -0
  16. package/dist/skills/media-use/audio/assets/sfx/glitch-1.mp3 +0 -0
  17. package/dist/skills/media-use/audio/assets/sfx/glitch-2.mp3 +0 -0
  18. package/dist/skills/media-use/audio/assets/sfx/glitch-3.mp3 +0 -0
  19. package/dist/skills/media-use/audio/assets/sfx/impact-bass-1.mp3 +0 -0
  20. package/dist/skills/media-use/audio/assets/sfx/impact-bass-2.mp3 +0 -0
  21. package/dist/skills/media-use/audio/assets/sfx/key-press.mp3 +0 -0
  22. package/dist/skills/media-use/audio/assets/sfx/manifest.json +97 -0
  23. package/dist/skills/media-use/audio/assets/sfx/notification.mp3 +0 -0
  24. package/dist/skills/media-use/audio/assets/sfx/ping.mp3 +0 -0
  25. package/dist/skills/media-use/audio/assets/sfx/pop.mp3 +0 -0
  26. package/dist/skills/media-use/audio/assets/sfx/riser.mp3 +0 -0
  27. package/dist/skills/media-use/audio/assets/sfx/sparkle.mp3 +0 -0
  28. package/dist/skills/media-use/audio/assets/sfx/typing.mp3 +0 -0
  29. package/dist/skills/media-use/audio/assets/sfx/whoosh-cinematic.mp3 +0 -0
  30. package/dist/skills/media-use/audio/assets/sfx/whoosh-short.mp3 +0 -0
  31. package/dist/skills/media-use/audio/assets/sfx/whoosh.mp3 +0 -0
  32. package/dist/skills/media-use/audio/references/bgm.md +74 -0
  33. package/dist/skills/media-use/audio/references/captions/authoring.md +163 -0
  34. package/dist/skills/media-use/audio/references/captions/motion.md +87 -0
  35. package/dist/skills/media-use/audio/references/captions/transcript-handling.md +97 -0
  36. package/dist/skills/media-use/audio/references/remove-background.md +143 -0
  37. package/dist/skills/media-use/audio/references/requirements.md +29 -0
  38. package/dist/skills/media-use/audio/references/sfx.md +42 -0
  39. package/dist/skills/media-use/audio/references/transcribe.md +52 -0
  40. package/dist/skills/media-use/audio/references/tts-to-captions.md +26 -0
  41. package/dist/skills/media-use/audio/references/tts.md +165 -0
  42. package/dist/skills/media-use/audio/scripts/audio.mjs +295 -0
  43. package/dist/skills/media-use/audio/scripts/audio.test.mjs +49 -0
  44. package/dist/skills/media-use/audio/scripts/heygen-tts.mjs +121 -0
  45. package/dist/skills/media-use/audio/scripts/lib/audio-meta.mjs +39 -0
  46. package/dist/skills/media-use/audio/scripts/lib/audio-meta.test.mjs +136 -0
  47. package/dist/skills/media-use/audio/scripts/lib/bgm.mjs +257 -0
  48. package/dist/skills/media-use/audio/scripts/lib/bgm.test.mjs +30 -0
  49. package/dist/skills/media-use/audio/scripts/lib/concurrency.mjs +14 -0
  50. package/dist/skills/media-use/audio/scripts/lib/concurrency.test.mjs +41 -0
  51. package/dist/skills/media-use/audio/scripts/lib/heygen.mjs +156 -0
  52. package/dist/skills/media-use/audio/scripts/lib/heygen.test.mjs +103 -0
  53. package/dist/skills/media-use/audio/scripts/lib/python.mjs +63 -0
  54. package/dist/skills/media-use/audio/scripts/lib/python.test.mjs +68 -0
  55. package/dist/skills/media-use/audio/scripts/lib/sfx.mjs +143 -0
  56. package/dist/skills/media-use/audio/scripts/lib/sfx.test.mjs +69 -0
  57. package/dist/skills/media-use/audio/scripts/lib/tts.mjs +379 -0
  58. package/dist/skills/media-use/audio/scripts/lib/tts.spawn.test.mjs +158 -0
  59. package/dist/skills/media-use/audio/scripts/lib/tts.test.mjs +157 -0
  60. package/dist/skills/media-use/audio/scripts/lyria-recipe.py +136 -0
  61. package/dist/skills/media-use/audio/scripts/wait-bgm.mjs +171 -0
  62. package/dist/skills/media-use/audio/scripts/wait-bgm.test.mjs +65 -0
  63. package/dist/skills/media-use/luts/README.md +28 -0
  64. package/dist/skills/media-use/luts/index.json +57 -0
  65. package/dist/skills/media-use/references/audio.md +19 -0
  66. package/dist/skills/media-use/references/grading.md +160 -0
  67. package/dist/skills/media-use/references/media-treatment-recipes.md +929 -0
  68. package/dist/skills/media-use/references/media-treatments.md +202 -0
  69. package/dist/skills/media-use/references/memory.md +36 -0
  70. package/dist/skills/media-use/references/meta.md +61 -0
  71. package/dist/skills/media-use/references/operations.md +325 -0
  72. package/dist/skills/media-use/references/resolve.md +150 -0
  73. package/dist/skills/media-use/references/setup-providers.md +80 -0
  74. package/dist/skills/media-use/references/telemetry-dashboard.md +49 -0
  75. package/dist/skills/media-use/registry/localSemantic.js +548 -0
  76. package/dist/skills/media-use/scripts/audio-duck.mjs +113 -0
  77. package/dist/skills/media-use/scripts/compatibility.test.mjs +27 -0
  78. package/dist/skills/media-use/scripts/dither.mjs +328 -0
  79. package/dist/skills/media-use/scripts/dither.test.mjs +176 -0
  80. package/dist/skills/media-use/scripts/eval.mjs +369 -0
  81. package/dist/skills/media-use/scripts/lib/adopt.mjs +128 -0
  82. package/dist/skills/media-use/scripts/lib/adopt.test.mjs +95 -0
  83. package/dist/skills/media-use/scripts/lib/bgm-provider.mjs +20 -0
  84. package/dist/skills/media-use/scripts/lib/brand-provider.mjs +59 -0
  85. package/dist/skills/media-use/scripts/lib/bundled-sfx-provider.mjs +119 -0
  86. package/dist/skills/media-use/scripts/lib/bundled-sfx-provider.test.mjs +139 -0
  87. package/dist/skills/media-use/scripts/lib/cache.mjs +150 -0
  88. package/dist/skills/media-use/scripts/lib/candidates.mjs +91 -0
  89. package/dist/skills/media-use/scripts/lib/candidates.test.mjs +155 -0
  90. package/dist/skills/media-use/scripts/lib/codex-provider.mjs +161 -0
  91. package/dist/skills/media-use/scripts/lib/codex-provider.test.mjs +34 -0
  92. package/dist/skills/media-use/scripts/lib/coverage.test.mjs +132 -0
  93. package/dist/skills/media-use/scripts/lib/cube-build.mjs +181 -0
  94. package/dist/skills/media-use/scripts/lib/cube-build.test.mjs +80 -0
  95. package/dist/skills/media-use/scripts/lib/cube-validate.mjs +198 -0
  96. package/dist/skills/media-use/scripts/lib/cube-validate.test.mjs +125 -0
  97. package/dist/skills/media-use/scripts/lib/cutlist.mjs +184 -0
  98. package/dist/skills/media-use/scripts/lib/cutlist.test.mjs +162 -0
  99. package/dist/skills/media-use/scripts/lib/duck.mjs +95 -0
  100. package/dist/skills/media-use/scripts/lib/duck.test.mjs +153 -0
  101. package/dist/skills/media-use/scripts/lib/error-diffusion.mjs +230 -0
  102. package/dist/skills/media-use/scripts/lib/error-diffusion.test.mjs +102 -0
  103. package/dist/skills/media-use/scripts/lib/freeze.mjs +62 -0
  104. package/dist/skills/media-use/scripts/lib/freeze.test.mjs +46 -0
  105. package/dist/skills/media-use/scripts/lib/grade-analyzer.mjs +265 -0
  106. package/dist/skills/media-use/scripts/lib/grade-analyzer.test.mjs +285 -0
  107. package/dist/skills/media-use/scripts/lib/heygen-cli.mjs +191 -0
  108. package/dist/skills/media-use/scripts/lib/heygen-cli.test.mjs +301 -0
  109. package/dist/skills/media-use/scripts/lib/heygen-search.mjs +45 -0
  110. package/dist/skills/media-use/scripts/lib/heygen-search.test.mjs +49 -0
  111. package/dist/skills/media-use/scripts/lib/heygen-video-provider.mjs +138 -0
  112. package/dist/skills/media-use/scripts/lib/heygen-video-provider.test.mjs +435 -0
  113. package/dist/skills/media-use/scripts/lib/image-provider.mjs +44 -0
  114. package/dist/skills/media-use/scripts/lib/index-gen.mjs +63 -0
  115. package/dist/skills/media-use/scripts/lib/local-media-search.mjs +32 -0
  116. package/dist/skills/media-use/scripts/lib/local-models.mjs +318 -0
  117. package/dist/skills/media-use/scripts/lib/local-models.test.mjs +220 -0
  118. package/dist/skills/media-use/scripts/lib/local-run.mjs +78 -0
  119. package/dist/skills/media-use/scripts/lib/local-run.test.mjs +121 -0
  120. package/dist/skills/media-use/scripts/lib/logo-provider.mjs +223 -0
  121. package/dist/skills/media-use/scripts/lib/logo-provider.test.mjs +154 -0
  122. package/dist/skills/media-use/scripts/lib/ltx-video-provider.mjs +94 -0
  123. package/dist/skills/media-use/scripts/lib/ltx-video-provider.test.mjs +316 -0
  124. package/dist/skills/media-use/scripts/lib/lut-preset-provider.mjs +271 -0
  125. package/dist/skills/media-use/scripts/lib/lut-preset-provider.test.mjs +199 -0
  126. package/dist/skills/media-use/scripts/lib/manifest.mjs +229 -0
  127. package/dist/skills/media-use/scripts/lib/manifest.test.mjs +388 -0
  128. package/dist/skills/media-use/scripts/lib/match.mjs +47 -0
  129. package/dist/skills/media-use/scripts/lib/media-fetch.mjs +71 -0
  130. package/dist/skills/media-use/scripts/lib/media-fetch.test.mjs +169 -0
  131. package/dist/skills/media-use/scripts/lib/media-search.d.mts +9 -0
  132. package/dist/skills/media-use/scripts/lib/media-search.mjs +107 -0
  133. package/dist/skills/media-use/scripts/lib/mflux-provider.mjs +128 -0
  134. package/dist/skills/media-use/scripts/lib/mflux-provider.test.mjs +174 -0
  135. package/dist/skills/media-use/scripts/lib/misses.mjs +49 -0
  136. package/dist/skills/media-use/scripts/lib/misses.test.mjs +78 -0
  137. package/dist/skills/media-use/scripts/lib/npx-sync.mjs +31 -0
  138. package/dist/skills/media-use/scripts/lib/npx-sync.test.mjs +50 -0
  139. package/dist/skills/media-use/scripts/lib/parakeet-words.mjs +27 -0
  140. package/dist/skills/media-use/scripts/lib/parakeet-words.test.mjs +44 -0
  141. package/dist/skills/media-use/scripts/lib/prefs-store.mjs +180 -0
  142. package/dist/skills/media-use/scripts/lib/prefs-store.test.mjs +189 -0
  143. package/dist/skills/media-use/scripts/lib/probe.mjs +39 -0
  144. package/dist/skills/media-use/scripts/lib/probe.test.mjs +31 -0
  145. package/dist/skills/media-use/scripts/lib/providers.mjs +5 -0
  146. package/dist/skills/media-use/scripts/lib/recipe-store.mjs +367 -0
  147. package/dist/skills/media-use/scripts/lib/recipe-store.test.mjs +367 -0
  148. package/dist/skills/media-use/scripts/lib/registry.mjs +218 -0
  149. package/dist/skills/media-use/scripts/lib/registry.test.mjs +262 -0
  150. package/dist/skills/media-use/scripts/lib/search.mjs +24 -0
  151. package/dist/skills/media-use/scripts/lib/search.test.mjs +32 -0
  152. package/dist/skills/media-use/scripts/lib/sfx-provider.mjs +23 -0
  153. package/dist/skills/media-use/scripts/lib/specs.mjs +132 -0
  154. package/dist/skills/media-use/scripts/lib/specs.test.mjs +157 -0
  155. package/dist/skills/media-use/scripts/lib/stats.mjs +117 -0
  156. package/dist/skills/media-use/scripts/lib/stats.test.mjs +165 -0
  157. package/dist/skills/media-use/scripts/lib/telemetry.mjs +193 -0
  158. package/dist/skills/media-use/scripts/lib/telemetry.test.mjs +373 -0
  159. package/dist/skills/media-use/scripts/lib/tts-local-provider.mjs +92 -0
  160. package/dist/skills/media-use/scripts/lib/tts-local-provider.test.mjs +72 -0
  161. package/dist/skills/media-use/scripts/lib/usage.mjs +57 -0
  162. package/dist/skills/media-use/scripts/lib/usage.test.mjs +54 -0
  163. package/dist/skills/media-use/scripts/lib/voice-provider.mjs +57 -0
  164. package/dist/skills/media-use/scripts/lib/voice-provider.test.mjs +46 -0
  165. package/dist/skills/media-use/scripts/lib/words.mjs +18 -0
  166. package/dist/skills/media-use/scripts/prefs.mjs +70 -0
  167. package/dist/skills/media-use/scripts/recipe.mjs +103 -0
  168. package/dist/skills/media-use/scripts/resolve.mjs +1287 -0
  169. package/dist/skills/media-use/scripts/transcribe.mjs +180 -0
  170. package/dist/skills/media-use/scripts/transcript-cut.mjs +239 -0
  171. package/dist/skills/registry/localSemantic.js +548 -0
  172. package/dist/studio/assets/{hyperframes-player-c23wnIfc.js → hyperframes-player-BBub3ZdI.js} +3 -3
  173. package/dist/studio/assets/{index-IDNr3X1H.js → index-BxZ5Cw5w.js} +1 -1
  174. package/dist/studio/assets/{index-DgkAzx3n.js → index-CI7WON-E.js} +1 -1
  175. package/dist/studio/assets/{index-gbOCDCuZ.js → index-D1KNPijK.js} +192 -192
  176. package/dist/studio/assets/{index-DKJpHYYd.css → index-DZBHG9TW.css} +1 -1
  177. package/dist/studio/index.d.ts +577 -8
  178. package/dist/studio/index.html +2 -2
  179. package/dist/studio/index.js +22537 -21600
  180. package/dist/studio/index.js.map +1 -1
  181. package/dist/studio/styles.css +1 -1
  182. package/package.json +3 -3
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { ButtonHTMLAttributes, ReactNode, ElementType, ComponentPropsWithoutRef, ReactElement, RefObject, MutableRefObject } from 'react';
2
+ import { ButtonHTMLAttributes, ReactNode, ElementType, ComponentPropsWithoutRef, ReactElement, RefObject, MutableRefObject, DragEventHandler, ComponentProps, RefCallback, MouseEvent, CSSProperties, UIEvent, PointerEvent } from 'react';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import { Tabs as Tabs$1 } from '@base-ui/react/tabs';
5
5
  import * as node_modules_cn_dist_types from 'node_modules/cn/dist/types';
@@ -8,9 +8,9 @@ import { Menu as Menu$1 } from '@base-ui/react/menu';
8
8
  import { Popover as Popover$1 } from '@base-ui/react/popover';
9
9
  import { RuntimeTimelineClipIdentity, HyperframePickerElementInfo } from '@hyperframes/core';
10
10
  import { GsapAnimation, PropertyGroupName } from '@hyperframes/core/gsap-parser';
11
+ import { MusicBeatAnalysis } from '@hyperframes/core/beats';
11
12
  import * as zustand from 'zustand';
12
13
  import { StoreApi } from 'zustand';
13
- import { MusicBeatAnalysis } from '@hyperframes/core/beats';
14
14
  import { GsapAnimation as GsapAnimation$1, ArcPathSegment } from '@hyperframes/parsers/gsap-parser';
15
15
  import { CanvasResolution } from '@hyperframes/parsers';
16
16
  import { Composition } from '@hyperframes/sdk';
@@ -336,6 +336,8 @@ interface PlayerControlsProps {
336
336
  }
337
337
  declare const PlayerControls: react.NamedExoticComponent<PlayerControlsProps>;
338
338
 
339
+ declare function TimelineRulerPart(): react_jsx_runtime.JSX.Element;
340
+
339
341
  interface UserBeat {
340
342
  time: number;
341
343
  strength: number;
@@ -566,13 +568,13 @@ interface PlaybackReadinessSlice {
566
568
  }
567
569
  declare function createPlaybackReadinessSlice(set: StoreApi<PlaybackReadinessSlice>["setState"]): PlaybackReadinessSlice;
568
570
 
569
- interface TimelineTimeRange {
571
+ interface TimelineTimeRange$1 {
570
572
  t0: number;
571
573
  t1: number;
572
574
  }
573
575
  interface RangeSelectionSlice {
574
576
  /** Shift-drag ruler range in seconds, normalized so t0 <= t1. */
575
- rangeSelection: TimelineTimeRange | null;
577
+ rangeSelection: TimelineTimeRange$1 | null;
576
578
  }
577
579
 
578
580
  /**
@@ -629,6 +631,11 @@ interface TimelineElement {
629
631
  playbackRate?: number;
630
632
  sourceDuration?: number;
631
633
  volume?: number;
634
+ /** `data-has-audio="true"` on a video: its sound is mixed, so it takes audio affordances (fades). */
635
+ hasAudio?: boolean;
636
+ /** Clip-edge fades from `data-fade-in` / `data-fade-out`, seconds; absent means none. */
637
+ fadeIn?: number;
638
+ fadeOut?: number;
632
639
  /** Verbatim `data-fx-chain` / `data-automation`; see automationLaneData. */
633
640
  fxChain?: string;
634
641
  automation?: string;
@@ -1081,6 +1088,12 @@ interface TimelineStackingReorderIntent {
1081
1088
  }
1082
1089
 
1083
1090
  type BlockedTimelineEditIntent = "move" | "resize-start" | "resize-end";
1091
+ interface TimelineRangeSelection {
1092
+ start: number;
1093
+ end: number;
1094
+ anchorX: number;
1095
+ anchorY: number;
1096
+ }
1084
1097
 
1085
1098
  /**
1086
1099
  * Durability report for a patch-batches commit. `durable === false` means the
@@ -1280,6 +1293,12 @@ interface TimelineEditCallbacks {
1280
1293
  onTogglePropertyGroupKeyframe?: (element: TimelineElement, target: TimelinePropertyGroupKeyframeToggle) => Promise<void> | void;
1281
1294
  }
1282
1295
 
1296
+ interface TimelineTrackStyle {
1297
+ clip: string;
1298
+ accent: string;
1299
+ label: string;
1300
+ clipActive?: string;
1301
+ }
1283
1302
  interface TimelineTheme {
1284
1303
  shellBackground: string;
1285
1304
  shellBorder: string;
@@ -1332,7 +1351,7 @@ interface TimelineProps extends TimelineDropCallbacks, TimelineEditOverrides {
1332
1351
  onDeleteElement?: (element: TimelineElement) => Promise<void> | void;
1333
1352
  onSelectElement?: (element: TimelineElement | null) => void;
1334
1353
  /** Notification only; null when cleared. The value lives in usePlayerStore.rangeSelection. */
1335
- onRangeSelect?: (range: TimelineTimeRange | null) => void;
1354
+ onRangeSelect?: (range: TimelineTimeRange$1 | null) => void;
1336
1355
  onCopyClip?: () => boolean;
1337
1356
  onPasteClip?: () => Promise<void>;
1338
1357
  onDuplicateClip?: () => Promise<boolean>;
@@ -1340,7 +1359,528 @@ interface TimelineProps extends TimelineDropCallbacks, TimelineEditOverrides {
1340
1359
  theme?: Partial<TimelineTheme>;
1341
1360
  }
1342
1361
 
1343
- declare const Timeline: react.NamedExoticComponent<TimelineProps>;
1362
+ interface TimelineEmptyStateProps {
1363
+ isDragOver: boolean;
1364
+ onFileDrop?: boolean;
1365
+ onDragOver: DragEventHandler<HTMLDivElement>;
1366
+ onDragLeave: DragEventHandler<HTMLDivElement>;
1367
+ onDrop: DragEventHandler<HTMLDivElement>;
1368
+ }
1369
+ declare function TimelineEmptyState({ isDragOver, onFileDrop, onDragOver, onDragLeave, onDrop, }: TimelineEmptyStateProps): react_jsx_runtime.JSX.Element;
1370
+
1371
+ interface Rect {
1372
+ left: number;
1373
+ top: number;
1374
+ width: number;
1375
+ height: number;
1376
+ }
1377
+
1378
+ type TimelineSnapType = "beat" | "playhead" | "clip-edge";
1379
+ interface TimelineSnapTarget {
1380
+ time: number;
1381
+ type: TimelineSnapType;
1382
+ }
1383
+
1384
+ interface DraggedClipState {
1385
+ /** Pointer captured by the stable viewport coordinator for this gesture. */
1386
+ pointerId: number;
1387
+ element: TimelineElement;
1388
+ originClientX: number;
1389
+ originClientY: number;
1390
+ originScrollLeft: number;
1391
+ originScrollTop: number;
1392
+ pointerClientX: number;
1393
+ pointerClientY: number;
1394
+ pointerOffsetX: number;
1395
+ pointerOffsetY: number;
1396
+ previewStart: number;
1397
+ previewTrack: number;
1398
+ /**
1399
+ * The lane the POINTER aims at (from the drag's vertical position), before
1400
+ * collision resolution. `previewTrack` is where the clip actually LANDS —
1401
+ * which may differ from `desiredTrack` when the aimed span is occupied and the
1402
+ * collision rules bump the dragged clip to a free lane. The commit reads this
1403
+ * to tell a deliberate VERTICAL lane change (pointer aimed at another lane →
1404
+ * stacking sync allowed) from a plain HORIZONTAL drag whose clip merely got
1405
+ * bumped sideways (never touches z). Optional: when absent the commit falls
1406
+ * back to `previewTrack` (pre-existing behaviour).
1407
+ */
1408
+ desiredTrack?: number;
1409
+ /**
1410
+ * When non-null, the drop inserts a NEW track at this visual row boundary
1411
+ * (0 = above the top lane, trackOrder.length = below the bottom) instead of
1412
+ * landing on previewTrack. Drives the insertion-line indicator.
1413
+ */
1414
+ insertRow: number | null;
1415
+ /** Snap target the clip will land on, for the guide highlight. */
1416
+ snapTime: number | null;
1417
+ snapType: TimelineSnapType | null;
1418
+ started: boolean;
1419
+ }
1420
+ interface ResizingClipState {
1421
+ /** Pointer captured by the stable viewport coordinator for this gesture. */
1422
+ pointerId: number;
1423
+ element: TimelineElement;
1424
+ edge: "start" | "end";
1425
+ originClientX: number;
1426
+ /**
1427
+ * scrollLeft at gesture start. Edge auto-scroll moves the content under a
1428
+ * stationary pointer, so the trim math folds (current − origin) scrollLeft
1429
+ * into the pointer x — mirroring resolveTimelineMove's scroll compensation.
1430
+ * Optional so pre-existing constructors/tests stay valid; when absent the
1431
+ * first preview update captures the current scrollLeft.
1432
+ */
1433
+ originScrollLeft?: number;
1434
+ previewStart: number;
1435
+ previewDuration: number;
1436
+ previewPlaybackStart?: number;
1437
+ /** Snap target the trimmed edge landed on, for the guide highlight. */
1438
+ snapTime?: number | null;
1439
+ snapType?: TimelineSnapType | null;
1440
+ /** Coordinator-owned group projection; canonical elements change only on commit. */
1441
+ groupPreview?: readonly {
1442
+ key: string;
1443
+ start: number;
1444
+ duration: number;
1445
+ playbackStart?: number;
1446
+ }[];
1447
+ started: boolean;
1448
+ }
1449
+ interface BlockedClipState {
1450
+ pointerId: number;
1451
+ element: TimelineElement;
1452
+ intent: BlockedTimelineEditIntent;
1453
+ originClientX: number;
1454
+ originClientY: number;
1455
+ started: boolean;
1456
+ }
1457
+
1458
+ interface TimelineTimeRange {
1459
+ readonly start: number;
1460
+ readonly end: number;
1461
+ }
1462
+ interface TimelineClipInterval {
1463
+ readonly element: TimelineElement;
1464
+ readonly identity: string;
1465
+ readonly ordinal: number;
1466
+ readonly start: number;
1467
+ readonly end: number;
1468
+ }
1469
+ interface TimelineClipRowIndex {
1470
+ readonly byStart: readonly TimelineClipInterval[];
1471
+ readonly treeLeafCount: number;
1472
+ readonly maxPositiveEndTree: readonly number[];
1473
+ readonly maxPointStartTree: readonly number[];
1474
+ readonly byIdentity: ReadonlyMap<string, readonly TimelineClipInterval[]>;
1475
+ }
1476
+ interface TimelineClipIndex {
1477
+ readonly rows: ReadonlyMap<number, TimelineClipRowIndex>;
1478
+ }
1479
+
1480
+ interface TimelineRowGeometry {
1481
+ readonly rowKeys: readonly number[];
1482
+ readonly rowHeights: readonly number[];
1483
+ /** Cumulative row boundaries, including the final bottom boundary. */
1484
+ readonly rowOffsets: readonly number[];
1485
+ readonly rowsHeight: number;
1486
+ readonly canvasHeight: number;
1487
+ getRowIndex(rowKey: number): number;
1488
+ getRowHeight(row: number): number;
1489
+ getRowTop(row: number): number;
1490
+ getRowFromY(contentY: number): number;
1491
+ getRowPositionFromY(contentY: number): {
1492
+ rowFloat: number;
1493
+ row: number;
1494
+ fraction: number;
1495
+ rowHeight: number;
1496
+ };
1497
+ }
1498
+
1499
+ type TrackVisualStyle = TimelineTrackStyle;
1500
+
1501
+ interface TimelineVirtualRow {
1502
+ readonly index: number;
1503
+ readonly rowKey: number;
1504
+ }
1505
+
1506
+ /**
1507
+ * Pure geometry for the LIVE multi-selection drag preview.
1508
+ *
1509
+ * Visual model (matches main): while a selected clip is dragged, ALL selected
1510
+ * clips move together LIVE as one rigid formation following the cursor. The
1511
+ * GRABBED clip is drawn as the free-floating ghost; every OTHER selected member
1512
+ * ("passenger") slides by the SAME time delta via a cheap compositor
1513
+ * `translateX` (no re-layout). Passengers do NOT stay still, and they do NOT lag
1514
+ * behind individually — the whole formation moves by one delta, spacing locked.
1515
+ *
1516
+ * That single delta is the GRABBED clip's `draggedPreviewStart − draggedOriginStart`.
1517
+ * The preview start is ALREADY group-clamped upstream (updateDraggedClipPreview
1518
+ * runs clampGroupMoveDelta before setting it), so this delta is the clamped delta:
1519
+ * the instant any member would cross 0 the grabbed clip stops and every passenger
1520
+ * stops with it — the formation never deforms. On DROP the commit shifts every
1521
+ * selected clip by this same delta (see timelineClipDragCommit / useTimelineClipDrag).
1522
+ *
1523
+ * Track changes apply to the grabbed clip only (mirroring the commit); passengers
1524
+ * keep their lanes, so only their x moves.
1525
+ */
1526
+ interface MultiDragPreviewInput {
1527
+ /** The drag is live (past the movement threshold). */
1528
+ dragStarted: boolean;
1529
+ /** Key of the clip under the pointer. */
1530
+ draggedKey: string;
1531
+ /** The dragged clip's committed start (pre-drag). */
1532
+ draggedOriginStart: number;
1533
+ /** The dragged clip's live preview start (already group-clamped upstream). */
1534
+ draggedPreviewStart: number;
1535
+ /** The current multi-selection (store.selectedElementIds). */
1536
+ selectedKeys: ReadonlySet<string>;
1537
+ }
1538
+
1539
+ /** One resolved audio group, positioned in the row order. */
1540
+ interface TimelineTrackGroupInfo {
1541
+ id: string;
1542
+ label: string;
1543
+ /**
1544
+ * Synthetic sort key for the group's own row — the same fractional-key
1545
+ * convention sub-composition expansion already uses (see
1546
+ * timelineTrackDisplay.ts): the first (lowest) member track's number minus
1547
+ * 0.5, so it slots in immediately above that member.
1548
+ */
1549
+ anchorKey: number;
1550
+ /** Member track numbers, ascending. */
1551
+ memberTracks: number[];
1552
+ /**
1553
+ * Every clip under this group, in member-track order — INDEPENDENT of whether
1554
+ * the group is expanded.
1555
+ *
1556
+ * Collapsing a group stops emitting its member rows into `tracks`, so anything
1557
+ * that recovered member elements by looking them up there got an empty list in
1558
+ * the default (collapsed) state — silently disabling the
1559
+ * automation-lane count, and the bus strip's member labels. Membership is not
1560
+ * a display concern, so it does not travel through the display list.
1561
+ */
1562
+ memberElements: TimelineElement[];
1563
+ /** The group element's `data-volume`, mirrored from a member's parse (B7's slider). */
1564
+ volume: number;
1565
+ /** The group element's `data-hidden`, mirrored from a member's parse (B5's group mute). */
1566
+ hidden: boolean;
1567
+ /** The group element's serialized `data-fx-chain`, mirrored from a member's parse (C1's FX entry). */
1568
+ fxChain?: string;
1569
+ /** The group element's serialized `data-automation` — the group's OWN lanes,
1570
+ * which are what its `∿` discloses (groups doc §5). */
1571
+ automation?: string;
1572
+ }
1573
+
1574
+ interface TimelineLogicalItem {
1575
+ id: string;
1576
+ kind: "clip" | "keyframe" | "ease";
1577
+ rowId: string;
1578
+ elementId: string;
1579
+ /** The item's time anchor. Clips use their midpoint; ease controls use the segment midpoint. */
1580
+ time: number;
1581
+ keyframeTarget?: TimelineKeyframeTarget;
1582
+ }
1583
+ interface TimelineLogicalRow {
1584
+ id: string;
1585
+ kind: "row";
1586
+ physicalTrackKey: number;
1587
+ logicalIndex: number;
1588
+ level: 1 | 2 | 3;
1589
+ parentId: string | null;
1590
+ elementId: string | null;
1591
+ /** Set only on a group's own row (level 1, no clips of its own). */
1592
+ groupId?: string;
1593
+ expandable: boolean;
1594
+ expanded: boolean;
1595
+ propertyGroup?: PropertyGroupName;
1596
+ items: readonly TimelineLogicalItem[];
1597
+ }
1598
+
1599
+ /**
1600
+ * Props shared by the scroll container ({@link import("./TimelineCanvas")}) and
1601
+ * the lane renderer ({@link import("./TimelineLanes")}). TimelineCanvas passes
1602
+ * these straight through via spread, so they are declared once here and both
1603
+ * prop types compose from this base — no duplicated prop list. Kept in its own
1604
+ * module so neither side has to import the other just to name the contract.
1605
+ */
1606
+ interface TimelineLaneBaseProps {
1607
+ pps: number;
1608
+ contentOrigin: number;
1609
+ contentGutter: number;
1610
+ trackContentWidth: number;
1611
+ theme: TimelineTheme;
1612
+ displayTrackOrder: number[];
1613
+ rowHeights: readonly number[];
1614
+ rowGeometry: TimelineRowGeometry;
1615
+ virtualRows: readonly TimelineVirtualRow[];
1616
+ logicalRows: readonly TimelineLogicalRow[];
1617
+ focusedTargetId: string | null;
1618
+ rowsVirtualized: boolean;
1619
+ clipIndex: TimelineClipIndex;
1620
+ renderTimeRange: TimelineTimeRange;
1621
+ visibleTimeRange: TimelineTimeRange;
1622
+ pinnedClipIdentities: ReadonlySet<string>;
1623
+ trackOrder: number[];
1624
+ tracks: [number, TimelineElement[]][];
1625
+ trackStyles: Map<number, TrackVisualStyle>;
1626
+ laneCounts: ReadonlyMap<string, number>;
1627
+ selectedElementId: string | null;
1628
+ selectedElementIds: Set<string>;
1629
+ hoveredClip: string | null;
1630
+ draggedClip: DraggedClipState | null;
1631
+ blockedClipRef: React.RefObject<BlockedClipState | null>;
1632
+ suppressClickRef: React.RefObject<boolean>;
1633
+ scrollRef: React.RefObject<HTMLDivElement | null>;
1634
+ renderClipContent?: (element: TimelineElement, style: {
1635
+ clip: string;
1636
+ label: string;
1637
+ }, context: TimelineClipRenderContext) => ReactNode;
1638
+ renderClipOverlay?: (element: TimelineElement) => ReactNode;
1639
+ onDrillDown?: (element: TimelineElement) => void;
1640
+ onSelectElement?: (element: TimelineElement | null) => void;
1641
+ setHoveredClip: (key: string | null) => void;
1642
+ setShowPopover: (v: boolean) => void;
1643
+ setRangeSelection: (v: null) => void;
1644
+ setResizingClip: (v: ResizingClipState | null) => void;
1645
+ setDraggedClip: (v: DraggedClipState | null) => void;
1646
+ setSelectedElementId: (id: string | null) => void;
1647
+ shiftClickClipRef: React.RefObject<{
1648
+ element: TimelineElement;
1649
+ anchorX: number;
1650
+ anchorY: number;
1651
+ } | null>;
1652
+ getPreviewElement: (element: TimelineElement) => TimelineElement;
1653
+ getTrackStyle: (tag: string) => TrackVisualStyle;
1654
+ keyframeCache?: Map<string, KeyframeCacheEntry>;
1655
+ gsapAnimations: Map<string, GsapAnimation[]>;
1656
+ selectedKeyframes: Set<string>;
1657
+ currentTime: number;
1658
+ onSeek?: (time: number) => void;
1659
+ onSelectSegment?: (elementId: string, target: TimelineKeyframeTarget) => void;
1660
+ onClickKeyframe?: (element: TimelineElement, target: TimelineKeyframeTarget) => void;
1661
+ onShiftClickKeyframe?: (elementId: string, target: TimelineKeyframeTarget) => void;
1662
+ onContextMenuKeyframe?: (e: React.MouseEvent, elementId: string, target: TimelineKeyframeTarget) => void;
1663
+ onMoveKeyframe?: (elementId: string, keyframe: TimelineKeyframeTarget, toClipPercentage: number, propertyGroup?: string, tweenPercentage?: number, animationId?: string) => Promise<boolean>;
1664
+ onContextMenuClip?: (e: React.MouseEvent, element: TimelineElement) => void;
1665
+ /**
1666
+ * Right-click on EMPTY lane space (not on a clip — those preventDefault
1667
+ * before this fires — not the gutter/ruler, not below the lanes). `time` is
1668
+ * the timeline time (seconds) under the pointer on that lane.
1669
+ */
1670
+ onContextMenuLane?: (e: React.MouseEvent, track: number, time: number) => void;
1671
+ beatAnalysis?: MusicBeatAnalysis | null;
1672
+ /** Resolved audio groups, positioned in row order — see useTimelineTrackDerivations. */
1673
+ groups: readonly TimelineTrackGroupInfo[];
1674
+ }
1675
+
1676
+ /** An empty interval on the lane, [start, end) in seconds. */
1677
+ interface TrackGapInterval {
1678
+ start: number;
1679
+ end: number;
1680
+ }
1681
+
1682
+ /**
1683
+ * One lane's gap strips for the TimelineCanvas overlay.
1684
+ *
1685
+ * kind "hover" — the gap(s) a hovered "Close gap" / "Close all gaps" menu
1686
+ * row would collapse: the loud affordance.
1687
+ * kind "selected" — every empty interval on a click-selected clip's lane: the
1688
+ * quiet always-on hint (single click-selection only — a
1689
+ * marquee multi-select spans lanes and would paint noise).
1690
+ */
1691
+ interface TimelineLaneGapStrips {
1692
+ track: number;
1693
+ intervals: TrackGapInterval[];
1694
+ kind: "hover" | "selected";
1695
+ }
1696
+
1697
+ interface KeyframeDiamondContextMenuState {
1698
+ x: number;
1699
+ y: number;
1700
+ /** Timeline project session that created this portaled target. */
1701
+ sessionEpoch?: number;
1702
+ element: TimelineElement;
1703
+ elementId: string;
1704
+ percentage: number;
1705
+ tweenPercentage?: number;
1706
+ propertyGroup?: string;
1707
+ animationId?: string;
1708
+ currentEase?: string;
1709
+ }
1710
+
1711
+ type TimelineCanvasState = Omit<TimelineLaneBaseProps, "setRangeSelection" | "setResizingClip" | "setDraggedClip" | "renderClipContent" | "renderClipOverlay"> & {
1712
+ major: number[];
1713
+ minor: number[];
1714
+ totalH: number;
1715
+ effectiveDuration: number;
1716
+ majorTickInterval: number;
1717
+ rangeSelection: TimelineRangeSelection | null;
1718
+ marqueeRect: Rect | null;
1719
+ resizingClip: ResizingClipState | null;
1720
+ isScrubbing: boolean;
1721
+ playheadRef: React.RefObject<HTMLDivElement | null>;
1722
+ laneGapStrips: TimelineLaneGapStrips[];
1723
+ dropPreview: TimelineDropPlacement | null;
1724
+ setRangeSelection: (value: TimelineRangeSelection | null) => void;
1725
+ setResizingClip: (value: ResizingClipState | null) => void;
1726
+ setDraggedClip: (value: TimelineLaneBaseProps["draggedClip"]) => void;
1727
+ beatDragging: boolean;
1728
+ onResizeElement: TimelineEditCallbacks["onResizeElement"];
1729
+ onMoveElement: TimelineEditCallbacks["onMoveElement"];
1730
+ draggedElement: TimelineElement | null;
1731
+ snapGuide: TimelineSnapTarget | null;
1732
+ multiDragPreview: MultiDragPreviewInput | null;
1733
+ onToggleTrackHidden: TimelineEditCallbacks["onToggleTrackHidden"];
1734
+ onTogglePropertyGroupKeyframe: TimelineEditCallbacks["onTogglePropertyGroupKeyframe"];
1735
+ onRazorSplit: TimelineEditCallbacks["onRazorSplit"];
1736
+ onRazorSplitAll: TimelineEditCallbacks["onRazorSplitAll"];
1737
+ };
1738
+ interface ClipContextMenuState {
1739
+ x: number;
1740
+ y: number;
1741
+ element: TimelineElement;
1742
+ sessionEpoch: number;
1743
+ }
1744
+ interface TrackGapContextMenuState {
1745
+ x: number;
1746
+ y: number;
1747
+ gapWidth: number | null;
1748
+ canCloseGap: boolean;
1749
+ canCloseAllGaps: boolean;
1750
+ hasAnyGaps: boolean;
1751
+ }
1752
+ interface TimelineOverlaysState {
1753
+ elements: readonly TimelineElement[];
1754
+ elementsRef: {
1755
+ current: readonly TimelineElement[];
1756
+ };
1757
+ theme: TimelineTheme;
1758
+ showShortcutHint: boolean;
1759
+ showPopover: boolean;
1760
+ rangeSelection: TimelineRangeSelection | null;
1761
+ setShowPopover: (value: boolean) => void;
1762
+ setRangeSelection: (value: TimelineRangeSelection | null) => void;
1763
+ kfContextMenu: KeyframeDiamondContextMenuState | null;
1764
+ setKfContextMenu: (value: KeyframeDiamondContextMenuState | null) => void;
1765
+ onDeleteKeyframe: TimelineEditCallbacks["onDeleteKeyframe"];
1766
+ onDeleteAllKeyframes: TimelineEditCallbacks["onDeleteAllKeyframes"];
1767
+ onMoveKeyframeToPlayhead: TimelineEditCallbacks["onMoveKeyframeToPlayhead"];
1768
+ clipContextMenu: ClipContextMenuState | null;
1769
+ setClipContextMenu: (value: ClipContextMenuState | null) => void;
1770
+ currentTime: number;
1771
+ onSplitElement: TimelineEditCallbacks["onSplitElement"];
1772
+ pinZoomBeforeEdit: () => void;
1773
+ onDeleteElement?: (element: TimelineElement) => Promise<void> | void;
1774
+ onCopyClip?: () => boolean;
1775
+ onPasteClip?: () => Promise<void>;
1776
+ onDuplicateClip?: () => Promise<boolean>;
1777
+ canPasteClip?: () => boolean;
1778
+ gapContextMenu: TrackGapContextMenuState | null;
1779
+ onDismissGapContextMenu: () => void;
1780
+ onCloseTrackGap: () => void;
1781
+ onCloseAllTrackGaps: () => void;
1782
+ onHoverGapAction: (action: "close-gap" | "close-all" | null) => void;
1783
+ }
1784
+ interface TimelineContainerProps {
1785
+ ref: RefCallback<HTMLDivElement>;
1786
+ "aria-label": string;
1787
+ "data-timeline-element-count": number;
1788
+ className: string;
1789
+ onMouseMove: (event: MouseEvent<HTMLDivElement>) => void;
1790
+ onMouseLeave: () => void;
1791
+ style: CSSProperties;
1792
+ }
1793
+ interface TimelineViewportProps {
1794
+ ref: RefCallback<HTMLDivElement>;
1795
+ "data-timeline-scroll-viewport": boolean;
1796
+ "data-timeline-auto-scroll-left-inset": number;
1797
+ tabIndex: number;
1798
+ className: string;
1799
+ onScroll: (event: UIEvent<HTMLDivElement>) => void;
1800
+ onFocus: (event: React.FocusEvent<HTMLDivElement>) => void;
1801
+ onBlur: (event: React.FocusEvent<HTMLDivElement>) => void;
1802
+ onDragOver: (event: React.DragEvent<HTMLDivElement>) => void;
1803
+ onDragLeave: (event: React.DragEvent<HTMLDivElement>) => void;
1804
+ onDrop: (event: React.DragEvent<HTMLDivElement>) => void;
1805
+ onPointerDown: (event: PointerEvent<HTMLDivElement>) => void;
1806
+ onPointerMove: (event: PointerEvent<HTMLDivElement>) => void;
1807
+ onPointerUp: (event: PointerEvent<HTMLDivElement>) => void;
1808
+ onPointerCancel: (event: PointerEvent<HTMLDivElement>) => void;
1809
+ onLostPointerCapture: (event: PointerEvent<HTMLDivElement>) => void;
1810
+ }
1811
+ interface TimelineState {
1812
+ timelineReady: boolean;
1813
+ elements: readonly TimelineElement[];
1814
+ selectedElementId: string | null;
1815
+ sessionEpoch: number;
1816
+ keyframeCache: Map<string, KeyframeCacheEntry>;
1817
+ canvas: TimelineCanvasState;
1818
+ overlays: TimelineOverlaysState;
1819
+ }
1820
+ interface TimelineActions {
1821
+ renderClipContent: TimelineLaneBaseProps["renderClipContent"];
1822
+ renderClipOverlay: TimelineLaneBaseProps["renderClipOverlay"];
1823
+ setFocusedEaseSegment: (target: {
1824
+ animationId: string;
1825
+ collidingAnimationTargets?: AnimationKeyframeTarget[];
1826
+ tweenPercentage: number;
1827
+ elementId: string;
1828
+ }) => void;
1829
+ }
1830
+ interface TimelineMeta {
1831
+ emptyState: ComponentProps<typeof TimelineEmptyState>;
1832
+ containerProps: TimelineContainerProps;
1833
+ viewportProps: TimelineViewportProps;
1834
+ razorGuide: ReactNode;
1835
+ }
1836
+ interface TimelineContextValue {
1837
+ state: TimelineState;
1838
+ actions: TimelineActions;
1839
+ meta: TimelineMeta;
1840
+ }
1841
+ declare function TimelineProvider({ children, ...props }: TimelineProps & {
1842
+ children: ReactNode;
1843
+ }): react_jsx_runtime.JSX.Element;
1844
+ declare function useTimelineContext(): TimelineContextValue;
1845
+
1846
+ declare function TimelineOverlays(): react_jsx_runtime.JSX.Element;
1847
+
1848
+ /** The provider-backed canvas shell. */
1849
+ declare function TimelineFrame(): react_jsx_runtime.JSX.Element;
1850
+ /** The provider-backed ruler. */
1851
+ declare const TimelineRuler: typeof TimelineRulerPart;
1852
+ /**
1853
+ * The provider-backed lane renderer. TimelineFrame remains the composed Studio
1854
+ * canvas; this part is exported for hosts that own the canvas arrangement.
1855
+ */
1856
+ declare function TimelineLanes(): react_jsx_runtime.JSX.Element;
1857
+ /** The provider-backed playhead indicator. */
1858
+ declare function TimelinePlayhead(): react_jsx_runtime.JSX.Element;
1859
+ /** The provider-backed razor guide. */
1860
+ declare function TimelineRazorGuide(): react.ReactNode;
1861
+
1862
+ declare function TimelineEmptyStatePart(): react_jsx_runtime.JSX.Element;
1863
+ declare function TimelineShortcutHint(): react_jsx_runtime.JSX.Element;
1864
+ declare function TimelineEditPopover(): react_jsx_runtime.JSX.Element;
1865
+ declare function TimelineClipMenu(): react_jsx_runtime.JSX.Element;
1866
+ declare function TimelineKeyframeMenu(): react_jsx_runtime.JSX.Element;
1867
+ declare function TimelineGapMenu(): react_jsx_runtime.JSX.Element;
1868
+
1869
+ declare const Timeline: react.NamedExoticComponent<TimelineProps> & {
1870
+ Provider: typeof TimelineProvider;
1871
+ Frame: typeof TimelineFrame;
1872
+ Ruler: typeof TimelineRulerPart;
1873
+ Lanes: typeof TimelineLanes;
1874
+ Playhead: typeof TimelinePlayhead;
1875
+ RazorGuide: typeof TimelineRazorGuide;
1876
+ ShortcutHint: typeof TimelineShortcutHint;
1877
+ EditPopover: typeof TimelineEditPopover;
1878
+ ClipMenu: typeof TimelineClipMenu;
1879
+ KeyframeMenu: typeof TimelineKeyframeMenu;
1880
+ GapMenu: typeof TimelineGapMenu;
1881
+ EmptyState: typeof TimelineEmptyStatePart;
1882
+ Overlays: typeof TimelineOverlays;
1883
+ };
1344
1884
 
1345
1885
  type ThumbnailPriority = "overscan" | "visible" | "interaction";
1346
1886
 
@@ -1455,6 +1995,35 @@ declare function useTimelinePlayer({ onShadowPromoted, onPreviewReloadFailed, }?
1455
1995
  resetPreviewSlots: () => void;
1456
1996
  };
1457
1997
 
1998
+ interface PlayerHandleElement {
1999
+ id: string;
2000
+ start: number;
2001
+ end: number;
2002
+ selector?: string;
2003
+ sourceFile?: string;
2004
+ compositionSrc?: string;
2005
+ }
2006
+ type PlayerHandleListener = () => void;
2007
+ type PlayerHandleTimeListener = (time: number) => void;
2008
+ interface PlayerHandle {
2009
+ ready: boolean;
2010
+ playing: boolean;
2011
+ seek: (seconds: number) => boolean;
2012
+ play: () => void;
2013
+ pause: () => void;
2014
+ togglePlay: () => void;
2015
+ readonly currentTime: number;
2016
+ duration: number;
2017
+ elements: PlayerHandleElement[];
2018
+ subscribe: (listener: PlayerHandleListener) => () => void;
2019
+ subscribeTime: (listener: PlayerHandleTimeListener) => () => void;
2020
+ }
2021
+ /**
2022
+ * Reads and controls the shell player. Call this under EditorShell/NLEProvider;
2023
+ * the provider owns the mounted preview iframe and the single player instance.
2024
+ */
2025
+ declare function usePlayerHandle(): PlayerHandle;
2026
+
1458
2027
  declare function formatTime(time: number): string;
1459
2028
 
1460
2029
  interface TimelineEditCallbackDeps {
@@ -2258,7 +2827,7 @@ interface TimelinePaneProps {
2258
2827
  onCompositionDrop?: (sourcePath: string, placement: Pick<TimelineElement, "start" | "track">) => Promise<void> | void;
2259
2828
  onBlockedEditAttempt?: (element: TimelineElement, intent: BlockedTimelineEditIntent) => void;
2260
2829
  onSelectTimelineElement?: (element: TimelineElement | null) => void;
2261
- onRangeSelect?: (range: TimelineTimeRange | null) => void;
2830
+ onRangeSelect?: (range: TimelineTimeRange$1 | null) => void;
2262
2831
  /** Copy/paste/duplicate act on the store's own selection, not a passed
2263
2832
  * element, so unlike onDeleteElement they need no composition-basis wrapper. */
2264
2833
  onCopyClip?: () => boolean;
@@ -2273,4 +2842,4 @@ declare function TimelineEditProvider({ value, children, }: {
2273
2842
  children: ReactNode;
2274
2843
  }): react_jsx_runtime.JSX.Element;
2275
2844
 
2276
- export { type AgentModalAnchorPoint, type AgentPromptElementInfo, AskAgentModal, type AskAgentModalProps, type BlockedTimelineEditIntent, Button, type ButtonSize, type ButtonVariant, type CanEditTimelineElement, CompositionBreadcrumb, type CompositionDimensions, type CompositionLevel, CompositionThumbnail, ContextMenu, type EditHistoryHandle, EditorShell, type EditorShellProps, type ExternalFileChangeBlockedState, type ExternalFileChangeCoordinatorHandle, ExternalFileConflictBanner, type FfmpegStatus, FileTree, GridOverlay, HyperframesLoader, type HyperframesLoaderProps, HyperframesLogo, IconButton, Input, type InputProps, Menu, MenuItem, type MenuItemTone, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuShortcut, NLEPreview, NumberField, type NumberFieldProps, type PatchOperation, type PersistedRenderSettings, type PickedElement, Player, PlayerControls, Popover, type PopupPreviewState, type DomEditCompositionRect as PreviewCompositionRect, PreviewGuides, PreviewOverlayProvider, type PreviewOverlayProviderProps, type PreviewSnapPreferences, type PreviewState, PropertyPanel, type RenderJob, RenderQueue, type RenderQueueProps, type ResolutionPreset, Select, type SelectOption, type SelectProps, Slider, type SliderProps, SnapToolbar, SourceEditor, type StartRenderOptions, StudioApp, StudioFileConflictError, type StudioPendingEditsDrainResult, Tab, TabPanel, Tabs, TabsList, Timeline, type TimelineEditCallbacks, type TimelineEditPermission, TimelineEditProvider, type TimelineElement, TimelinePane, type TimelinePaneProps, type TimelineTimeRange, Toggle, type ToggleProps, Tooltip, type UseEditHistoryActionsOptions, type UsePersistentEditHistoryOptions, type UseProjectFileWriterOptions, type UseTimelineEditingOptions, VideoThumbnail, applyPatch, buildPickerAgentContextPreview, buildPickerAgentPrompt, buttonBase, buttonSizes, buttonVariants, cn, fieldBase, fieldText, findElementBlock, flushStudioPendingEdits, formatTime, getPersistedRenderSettings, liveTime, mergeStyleIntoTag, parseStyleString, persistRenderSettings, popupSurface, resolveIframe, resolveSourceFile, useEditHistoryActions, useElementPicker, usePersistentEditHistory, usePlayerStore, usePreviewCompositionRect, usePreviewGuidesStore, usePreviewOverlayContext, useProjectFileWriter, useRenderQueue, useTimelineEditing, useTimelinePlayer };
2845
+ export { type AgentModalAnchorPoint, type AgentPromptElementInfo, AskAgentModal, type AskAgentModalProps, type BlockedTimelineEditIntent, Button, type ButtonSize, type ButtonVariant, type CanEditTimelineElement, CompositionBreadcrumb, type CompositionDimensions, type CompositionLevel, CompositionThumbnail, ContextMenu, type EditHistoryHandle, EditorShell, type EditorShellProps, type ExternalFileChangeBlockedState, type ExternalFileChangeCoordinatorHandle, ExternalFileConflictBanner, type FfmpegStatus, FileTree, GridOverlay, HyperframesLoader, type HyperframesLoaderProps, HyperframesLogo, IconButton, Input, type InputProps, Menu, MenuItem, type MenuItemTone, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuShortcut, NLEPreview, NumberField, type NumberFieldProps, type PatchOperation, type PersistedRenderSettings, type PickedElement, Player, PlayerControls, type PlayerHandle, type PlayerHandleElement, type PlayerHandleListener, type PlayerHandleTimeListener, Popover, type PopupPreviewState, type DomEditCompositionRect as PreviewCompositionRect, PreviewGuides, PreviewOverlayProvider, type PreviewOverlayProviderProps, type PreviewSnapPreferences, type PreviewState, PropertyPanel, type RenderJob, RenderQueue, type RenderQueueProps, type ResolutionPreset, Select, type SelectOption, type SelectProps, Slider, type SliderProps, SnapToolbar, SourceEditor, type StartRenderOptions, StudioApp, StudioFileConflictError, type StudioPendingEditsDrainResult, Tab, TabPanel, Tabs, TabsList, Timeline, TimelineClipMenu, type TimelineEditCallbacks, type TimelineEditPermission, TimelineEditPopover, TimelineEditProvider, type TimelineElement, TimelineEmptyStatePart, TimelineFrame, TimelineGapMenu, TimelineKeyframeMenu, TimelineLanes, TimelineOverlays, TimelinePane, type TimelinePaneProps, TimelinePlayhead, TimelineProvider, TimelineRazorGuide, TimelineRuler, TimelineShortcutHint, type TimelineTheme, type TimelineTimeRange$1 as TimelineTimeRange, Toggle, type ToggleProps, Tooltip, type UseEditHistoryActionsOptions, type UsePersistentEditHistoryOptions, type UseProjectFileWriterOptions, type UseTimelineEditingOptions, VideoThumbnail, applyPatch, buildPickerAgentContextPreview, buildPickerAgentPrompt, buttonBase, buttonSizes, buttonVariants, cn, fieldBase, fieldText, findElementBlock, flushStudioPendingEdits, formatTime, getPersistedRenderSettings, liveTime, mergeStyleIntoTag, parseStyleString, persistRenderSettings, popupSurface, resolveIframe, resolveSourceFile, useEditHistoryActions, useElementPicker, usePersistentEditHistory, usePlayerHandle, usePlayerStore, usePreviewCompositionRect, usePreviewGuidesStore, usePreviewOverlayContext, useProjectFileWriter, useRenderQueue, useTimelineContext, useTimelineEditing, useTimelinePlayer };
@@ -5,8 +5,8 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
6
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
7
7
  <title>HyperFrames Studio</title>
8
- <script type="module" crossorigin src="/assets/index-gbOCDCuZ.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-DKJpHYYd.css">
8
+ <script type="module" crossorigin src="/assets/index-D1KNPijK.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-DZBHG9TW.css">
10
10
  </head>
11
11
  <body>
12
12
  <div data-hf-id="hf-aph5" id="root"></div>