@pixerate/editor 0.90.0 → 0.92.0

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.
@@ -98,6 +98,15 @@ interface VideoTranscriptWord {
98
98
  start: number;
99
99
  end: number;
100
100
  }
101
+ /** A smaller copy of an asset's media for the preview (see `VideoAsset.proxies`). */
102
+ interface VideoAssetProxy {
103
+ /** Its size as a fraction of the original (0.5 = half width and height). */
104
+ scale: number;
105
+ /** What the preview loads instead of the original. */
106
+ src: string;
107
+ width?: number;
108
+ height?: number;
109
+ }
101
110
  /** A piece of source media. The project refers to it by id; `src` is whatever the host can load. */
102
111
  interface VideoAsset {
103
112
  id: string;
@@ -116,6 +125,12 @@ interface VideoAsset {
116
125
  poster?: string;
117
126
  /** What is said in it, word by word, timed in the source (see `parseVideoTranscript`). */
118
127
  transcript?: VideoTranscriptWord[];
128
+ /**
129
+ * Smaller copies of a video for smooth editing (see `videoProxyFfmpeg`). The preview plays the
130
+ * one its preview scale picks; exports and EDLs always use `src`. A proxy must have the same
131
+ * length and timing as the original.
132
+ */
133
+ proxies?: VideoAssetProxy[];
119
134
  }
120
135
  type VideoTrackKind = 'video' | 'audio';
121
136
  interface VideoTrack {
@@ -315,7 +330,28 @@ interface VideoColorClip extends VideoClipBase {
315
330
  type: 'color';
316
331
  color: string;
317
332
  }
318
- type VideoClip = VideoMediaClip | VideoTextClip | VideoColorClip;
333
+ /**
334
+ * A compound clip: a nested sequence (see `VideoProject.sequences`) played as one picture and one
335
+ * sound. It plays the sequence's own time from `in`, at normal speed. Its opacity, transform, blend,
336
+ * grade, fades, transitions and animations apply to the sequence's composite, not to each of its
337
+ * clips; its volume and fades apply to the sequence's mixed sound.
338
+ */
339
+ interface VideoSequenceClip extends VideoClipBase {
340
+ type: 'sequence';
341
+ /** The id of the sequence it plays (in `project.sequences`). */
342
+ sequence: string;
343
+ /** Where in the sequence's time it starts (ms, default 0). */
344
+ in?: number;
345
+ /** Gain on the sequence's sound (1 = unchanged, default 1), or keyframes. */
346
+ volume?: VideoAnimatable;
347
+ /** Silences the sequence's sound. */
348
+ muted?: boolean;
349
+ /** Shape of the sound's fade in (default linear). */
350
+ fadeInCurve?: VideoFadeCurve;
351
+ /** Shape of the sound's fade out (default linear). */
352
+ fadeOutCurve?: VideoFadeCurve;
353
+ }
354
+ type VideoClip = VideoMediaClip | VideoTextClip | VideoColorClip | VideoSequenceClip;
319
355
  type VideoClipType = VideoClip['type'];
320
356
  /**
321
357
  * How a clip is placed where others already are: `refuse` an overlap (the default), `overwrite`
@@ -324,7 +360,7 @@ type VideoClipType = VideoClip['type'];
324
360
  */
325
361
  type VideoPlacementMode = 'refuse' | 'overwrite' | 'insert';
326
362
  declare const VIDEO_PLACEMENT_MODES: readonly ["refuse", "overwrite", "insert"];
327
- declare const VIDEO_CLIP_TYPES: readonly ["media", "text", "color"];
363
+ declare const VIDEO_CLIP_TYPES: readonly ["media", "text", "color", "sequence"];
328
364
  interface VideoMarker {
329
365
  id: string;
330
366
  time: number;
@@ -332,6 +368,17 @@ interface VideoMarker {
332
368
  /** CSS colour. */
333
369
  color?: string;
334
370
  }
371
+ /**
372
+ * A nested sequence: tracks of clips with their own timeline from 0, played inside the project by
373
+ * compound clips (`type: 'sequence'`). Its frame is the project's frame size, transparent where no
374
+ * clip covers it. A sequence may hold compound clips of other sequences, but never itself (directly
375
+ * or through others).
376
+ */
377
+ interface VideoSequence {
378
+ id: string;
379
+ name?: string;
380
+ tracks: VideoTrack[];
381
+ }
335
382
  interface VideoProject {
336
383
  version: 1;
337
384
  name?: string;
@@ -344,6 +391,8 @@ interface VideoProject {
344
391
  background?: string;
345
392
  assets: VideoAsset[];
346
393
  tracks: VideoTrack[];
394
+ /** Nested sequences that compound clips play (see `VideoSequence`). */
395
+ sequences?: VideoSequence[];
347
396
  markers?: VideoMarker[];
348
397
  }
349
398
 
@@ -369,13 +418,17 @@ declare function parseVideoGradeLut(v: unknown, path: string): VideoGradeLut | u
369
418
  declare function parseVideoTransition(v: unknown, path: string): VideoTransition | undefined;
370
419
  declare function parseVideoTranscriptWords(v: unknown, path: string): VideoTranscriptWord[] | undefined;
371
420
  declare function parseVideoAsset(v: unknown, path?: string): VideoAsset;
421
+ declare function parseVideoAssetProxies(v: unknown, path: string): VideoAssetProxy[] | undefined;
372
422
  declare function parseVideoClip(v: unknown, path?: string): VideoClip;
373
423
  declare function parseVideoTrack(v: unknown, path?: string): VideoTrack;
424
+ /** A nested sequence `{ id, name, tracks }` (see `VideoSequence`). */
425
+ declare function parseVideoSequence(v: unknown, path?: string): VideoSequence;
374
426
  declare function parseVideoMarker(v: unknown, path?: string): VideoMarker;
375
427
  /**
376
428
  * Reads a project from JSON text or an object, checking every field. Throws an error naming the
377
429
  * first bad field (`tracks[0].clips[2].duration must be greater than 0.`). Ids must be unique
378
- * within assets, tracks, clips and markers. Overlaps and missing media are left to
430
+ * within assets, tracks, sequences, clips (across the project and its sequences) and markers.
431
+ * Overlaps, missing media and sequences, and sequences that contain themselves are left to
379
432
  * `checkVideoProject`, so a project with problems can still be opened and fixed.
380
433
  */
381
434
  declare function parseVideoProject(input: unknown): VideoProject;
@@ -399,7 +452,10 @@ declare const videoClipEnd: (clip: VideoClip) => number;
399
452
  declare const videoTrackSyncLocked: (track: VideoTrack) => boolean;
400
453
  /** Playback speed of a clip (1 for titles and colours). */
401
454
  declare const videoClipSpeed: (clip: VideoClip) => number;
402
- /** The stretch of source a media clip plays (ms), or `null` for titles and colours. */
455
+ /**
456
+ * The stretch of source a media clip plays (ms), or of its sequence's time a compound plays; `null`
457
+ * for titles and colours.
458
+ */
403
459
  declare function videoClipSourceRange(clip: VideoClip): {
404
460
  in: number;
405
461
  out: number;
@@ -433,6 +489,22 @@ declare const formatVideoSeconds: (time: number) => string;
433
489
  /** Whether an asset carries sound: audio, or video not marked `hasAudio: false`. */
434
490
  declare const videoAssetHasSound: (asset: VideoAsset | undefined) => boolean;
435
491
  declare function videoAssetMap(project: VideoProject): Map<string, VideoAsset>;
492
+ declare function videoSequenceMap(project: VideoProject): Map<string, VideoSequence>;
493
+ /** A sequence's length: the end of its last clip (ms). */
494
+ declare function videoSequenceDuration(sequence: Pick<VideoSequence, 'tracks'>): number;
495
+ /** The sequences a sequence's compound clips play directly (ids, in order, without repeats). */
496
+ declare const videoSequenceChildren: (sequence: Pick<VideoSequence, "tracks">) => string[];
497
+ /**
498
+ * A path of sequence ids that leads from `id` back to itself through compound clips (`[a, b, a]`),
499
+ * or `null` when it contains no cycle. Evaluating and exporting skip a compound that would close
500
+ * one, and `checkVideoProject` reports it.
501
+ */
502
+ declare function findVideoSequenceCycle(project: VideoProject, id: string): string[] | null;
503
+ /** Every track with its sequence (`undefined` for the project's own), the project's first. */
504
+ declare function allVideoTracks(project: VideoProject): {
505
+ sequence?: string;
506
+ track: VideoTrack;
507
+ }[];
436
508
  /** A track's clips in timeline order. */
437
509
  declare function sortedVideoClips(track: VideoTrack): VideoClip[];
438
510
  interface VideoClipLocation {
@@ -443,7 +515,14 @@ interface VideoClipLocation {
443
515
  index: number;
444
516
  }
445
517
  declare function findVideoClip(project: VideoProject, id: string): VideoClipLocation | null;
518
+ /** Every clip id in the project, its sequences' clips included (ids are unique across them). */
446
519
  declare function allVideoClipIds(project: VideoProject): string[];
520
+ /** The sequence a clip inside a sequence belongs to, with its track; `null` for clips of the project's own tracks (or no clip). */
521
+ declare function findVideoSequenceClip(project: VideoProject, id: string): {
522
+ sequence: VideoSequence;
523
+ track: VideoTrack;
524
+ clip: VideoClip;
525
+ } | null;
447
526
  /** Total length: the end of the last clip (ms). */
448
527
  declare function videoProjectDuration(project: VideoProject): number;
449
528
  /** The clip that ends where `clip` starts on its track (a cut), if any. */
@@ -453,9 +532,10 @@ declare function videoClipAfter(track: VideoTrack, clip: VideoClip): VideoClip |
453
532
  /**
454
533
  * Timeline time (ms) a clip can run past its edges into source media: before its in point
455
534
  * (`before`) and after its out point (`after`). Unlimited for stills, titles, colours and media
456
- * whose length is unknown.
535
+ * whose length is unknown. A compound's handles are its sequence's time before `in` and after its
536
+ * out point (pass `sequences`; without them they count as unlimited).
457
537
  */
458
- declare function videoClipHandles(clip: VideoClip, assets: Map<string, VideoAsset>): {
538
+ declare function videoClipHandles(clip: VideoClip, assets: Map<string, VideoAsset>, sequences?: Map<string, VideoSequence>): {
459
539
  before: number;
460
540
  after: number;
461
541
  };
@@ -503,13 +583,15 @@ declare function videoClipKeyframes(clip: VideoClip): {
503
583
  keys: ReturnType<typeof videoKeysOf>;
504
584
  }[];
505
585
  type VideoIssueSeverity = 'error' | 'warning' | 'note';
506
- declare const VIDEO_ISSUE_CODES: readonly ["missing-asset", "wrong-track", "overlap", "source-overrun", "transition-without-cut", "transition-too-long", "transition-handles", "fades-too-long", "animations-too-long", "animation-keyed", "keyframes-outside-clip", "unknown-duration", "unused-asset", "marker-past-end", "empty"];
586
+ declare const VIDEO_ISSUE_CODES: readonly ["missing-asset", "missing-sequence", "sequence-cycle", "wrong-track", "overlap", "source-overrun", "transition-without-cut", "transition-too-long", "transition-handles", "fades-too-long", "animations-too-long", "animation-keyed", "keyframes-outside-clip", "unknown-duration", "unused-asset", "unused-sequence", "marker-past-end", "empty"];
507
587
  type VideoIssueCode = (typeof VIDEO_ISSUE_CODES)[number];
508
588
  interface VideoIssue {
509
589
  code: VideoIssueCode;
510
590
  severity: VideoIssueSeverity;
511
591
  /** One sentence saying what is wrong and how to fix it. */
512
592
  message: string;
593
+ /** The sequence whose track it is about (absent for the project's own tracks). */
594
+ sequence?: string;
513
595
  track?: string;
514
596
  clip?: string;
515
597
  asset?: string;
@@ -521,7 +603,8 @@ declare const videoIssueKey: (i: VideoIssue) => string;
521
603
  * Everything wrong with a project, errors first: clips pointing at missing media or sitting on the
522
604
  * wrong kind of track, overlaps, clips running past the end of their source, transitions with no
523
605
  * cut to play over or not enough media either side of it, and softer notes (unused assets, markers
524
- * past the end). Edits never add errors (see `applyVideoEdits`), so errors only come from a loaded file.
606
+ * past the end). Sequences' tracks are checked the same way, and compound clips must play a
607
+ * sequence that exists, does not contain itself and is long enough. Edits never add errors (see `applyVideoEdits`), so errors only come from a loaded file.
525
608
  */
526
609
  declare function checkVideoProject(project: VideoProject): VideoIssue[];
527
610
 
@@ -738,15 +821,29 @@ interface VideoRect {
738
821
  }
739
822
  /** One picture in a frame, in draw order (first is at the back). */
740
823
  interface VideoLayer {
741
- /** The clip it comes from, or `transition:<clip>` for a dip's colour. */
824
+ /**
825
+ * The clip it comes from, or `transition:<clip>` for a dip's colour. Inside a compound clip it is
826
+ * the path of clip ids from the project's own track (`compound/inner`), so the same sequence
827
+ * played twice gives distinct layers.
828
+ */
742
829
  clip: string;
830
+ /** The track it is on (inside a compound: the sequence's track). */
743
831
  track: string;
744
832
  type: VideoClip['type'];
745
833
  /** For media: the asset, its kind and `src`, and the moment of the source to show (ms). */
746
834
  asset?: string;
747
835
  assetKind?: VideoAsset['kind'];
748
836
  src?: string;
837
+ /** For media: the moment of the source to show (ms); for a compound: the moment of its sequence. */
749
838
  sourceTime?: number;
839
+ /** For a compound: the sequence it plays. */
840
+ sequence?: string;
841
+ /**
842
+ * For a compound: the sequence's frame at `sourceTime`, back to front in the sequence's own frame
843
+ * (the project's size, transparent where nothing covers it). They are drawn together as one
844
+ * picture, which this layer's rect, rotation, opacity, blend, grade, wipe and iris then apply to.
845
+ */
846
+ layers?: VideoLayer[];
750
847
  /** 0–1, after fades and transitions. */
751
848
  opacity: number;
752
849
  /** Where the fitted picture sits before rotation (its centre is the rotation centre). */
@@ -780,13 +877,15 @@ interface VideoLayer {
780
877
  }
781
878
  /** One sound playing at a moment. */
782
879
  interface VideoAudioSource {
880
+ /** The clip it comes from (inside a compound: the path of clip ids, `compound/inner`). */
783
881
  clip: string;
882
+ /** The track it is on (inside a compound: the sequence's track). */
784
883
  track: string;
785
884
  asset: string;
786
885
  src: string;
787
886
  /** The moment of the source playing (ms). */
788
887
  sourceTime: number;
789
- /** Gain after clip and track volume, fades and transitions (0 = silent). */
888
+ /** Gain after clip and track volume, fades and transitions, and those of any compound it plays in (0 = silent). */
790
889
  gain: number;
791
890
  speed: number;
792
891
  }
@@ -828,16 +927,23 @@ declare const videoTransitionEase: (progress: number) => number;
828
927
  /** Gain of a fade shape `x` of the way up (0–1); a fade out uses the time left, so it mirrors the fade in. */
829
928
  declare function videoFadeCurveGain(curve: VideoFadeCurve | undefined, x: number): number;
830
929
  /**
831
- * A media clip's own gain at clip time `clipTime` (ms): its volume (or volume keyframes) times its
930
+ * A media or compound clip's own gain at clip time `clipTime` (ms): its volume (or volume keyframes) times its
832
931
  * shaped fades. Leaves out track volume and transitions, which depend on the timeline around it.
833
932
  */
834
933
  declare function videoClipSoundGain(clip: VideoClip, clipTime: number): number;
835
934
  /**
836
935
  * What plays at `time` (ms): the pictures to draw, back to front, with their placement, opacity
837
936
  * and the moment of source each shows, and the sounds with their gain. A pure function of the
838
- * project and the time, so previews, exporters and agents all agree on every frame.
937
+ * project and the time, so previews, exporters and agents all agree on every frame. A compound
938
+ * clip is one layer holding its sequence's frame (`layers`), and its sounds are mixed in with the
939
+ * compound's volume, fades and transitions.
839
940
  */
840
941
  declare function videoFrameAt(project: VideoProject, time: number): VideoFrame;
942
+ /**
943
+ * Every layer of a frame that draws a picture of its own, compounds opened up (each compound's
944
+ * layers in place of it), back to front. Hosts use it to find the media a frame needs.
945
+ */
946
+ declare function videoFrameLeafLayers(layers: readonly VideoLayer[]): VideoLayer[];
841
947
 
842
948
  /**
843
949
  * Sound levels of a piece of audio, small enough to keep for every asset: a pyramid of min / max
@@ -1533,7 +1639,11 @@ interface VideoSvgOptions {
1533
1639
  /** The loaded table of a grade's LUT `src`; drawn as an approximation (curves and a matrix). Without it LUTs are left out. */
1534
1640
  lutFor?: (src: string) => VideoLut | null | undefined;
1535
1641
  }
1536
- /** A frame as standalone SVG: images and posters as `<image>`, video without one as a labelled box. */
1642
+ /**
1643
+ * A frame as standalone SVG: images and posters as `<image>`, video without one as a labelled box.
1644
+ * A compound clip is a `<g>` (isolated, so blends inside it mix only with its own layers) holding
1645
+ * its sequence's layers scaled into its rect, with its opacity, blend, grade filter and clips on it.
1646
+ */
1537
1647
  declare function videoFrameToSvg(frame: VideoFrame, options?: VideoSvgOptions, assets?: VideoProject['assets']): string;
1538
1648
  /** The project at `time` as SVG. */
1539
1649
  declare function videoProjectSvg(project: VideoProject, time: number, options?: VideoSvgOptions): string;
@@ -1555,7 +1665,10 @@ type VideoCanvasContext = Pick<CanvasRenderingContext2D, 'save' | 'restore' | 'f
1555
1665
  lineWidth: number;
1556
1666
  strokeRect(x: number, y: number, w: number, h: number): void;
1557
1667
  };
1558
- /** An offscreen canvas `drawVideoFrame` draws a LUT-graded layer on before running its pixels through the LUT. */
1668
+ /**
1669
+ * An offscreen canvas `drawVideoFrame` draws on: a compound clip's layers before laying them on the
1670
+ * frame as one picture, or a LUT-graded layer before running its pixels through the LUT.
1671
+ */
1559
1672
  interface VideoScratchCanvas {
1560
1673
  canvas: CanvasImageSource;
1561
1674
  ctx: VideoCanvasContext & Pick<CanvasRenderingContext2D, 'getImageData' | 'putImageData' | 'clearRect'>;
@@ -1565,8 +1678,13 @@ interface VideoDrawOptions {
1565
1678
  defineSvgFilter?: (id: string, markup: string) => void;
1566
1679
  /** The loaded table of a grade's LUT `src`, or nothing while it loads (the layer is drawn without it). */
1567
1680
  lutFor?: (src: string) => VideoLut | null | undefined;
1568
- /** A cleared-on-use offscreen canvas of the given canvas-pixel size, for LUT layers (none: LUTs are left out). */
1569
- scratch?: (width: number, height: number) => VideoScratchCanvas | null;
1681
+ /**
1682
+ * An offscreen canvas of the given canvas-pixel size, for compound clips and LUT layers; `slot`
1683
+ * numbers the ones in use at once (a compound inside a compound needs its own), so return the
1684
+ * same canvas for the same slot and a different one for each slot. Without it LUTs are left out
1685
+ * and a compound's layers are drawn straight onto the frame, without its opacity, blend and grade.
1686
+ */
1687
+ scratch?: (width: number, height: number, slot: number) => VideoScratchCanvas | null;
1570
1688
  }
1571
1689
  /**
1572
1690
  * Draws a frame on a 2D canvas scaled by `scale` (canvas pixels per frame pixel). `sourceFor`
@@ -1575,7 +1693,8 @@ interface VideoDrawOptions {
1575
1693
  * balance there refers to an SVG filter, which `options.defineSvgFilter` is given to put in the page
1576
1694
  * (without it, white balance is left out of the canvas). A grade's LUT needs `options.lutFor` and
1577
1695
  * `options.scratch`: the layer is drawn on the scratch canvas, its pixels run through the LUT, and
1578
- * the result is laid on the frame with the layer's opacity and blend.
1696
+ * the result is laid on the frame with the layer's opacity and blend. A compound clip's layers are
1697
+ * drawn on a scratch canvas of their own (transparent), which is then drawn like a picture.
1579
1698
  */
1580
1699
  declare function drawVideoFrame(ctx: VideoCanvasContext, frame: VideoFrame, sourceFor: (layer: VideoLayer) => CanvasImageSource | null, scale?: number, options?: VideoDrawOptions): void;
1581
1700
 
@@ -1592,8 +1711,8 @@ interface VideoEdlOptions {
1592
1711
  /**
1593
1712
  * One track as a CMX 3600 edit decision list, for conforming in another NLE: an event per clip with
1594
1713
  * source and record timecode at the project's frame rate (drop-frame at 29.97 and 59.94), dissolves (`D`) for crossfades, dips and
1595
- * wipes (`W001`), `M2` lines for speed changes, and `* FROM CLIP NAME` comments. Titles and colour
1596
- * clips become black (`BL`) events.
1714
+ * wipes (`W001`), `M2` lines for speed changes, and `* FROM CLIP NAME` comments. Titles, colour
1715
+ * clips and compound clips (not flattened yet) become black (`BL`) events.
1597
1716
  */
1598
1717
  declare function toVideoEdl(project: VideoProject, options?: VideoEdlOptions): string;
1599
1718
  interface VideoFfmpegOptions {
@@ -1671,6 +1790,8 @@ interface VideoFfmpegExport {
1671
1790
  }
1672
1791
  /** Escapes a value for a filter option inside a filtergraph (option level, then graph level). */
1673
1792
  declare const ffmpegFilterValue: (s: string) => string;
1793
+ /** Quotes an argument for a POSIX shell when it needs it. */
1794
+ declare const videoShellQuote: (s: string) => string;
1674
1795
  /**
1675
1796
  * The project as an ffmpeg command: each clip an input trimmed to what it plays (plus transition
1676
1797
  * overlap), scaled and placed as `videoFrameAt` places it, faded, and overlaid on a background in
@@ -1686,18 +1807,250 @@ declare function toVideoFfmpeg(project: VideoProject, options?: VideoFfmpegOptio
1686
1807
  */
1687
1808
  declare function toVideoLoudnessMeasure(project: VideoProject, options?: Pick<VideoFfmpegOptions, 'resolve' | 'loudness'>): VideoFfmpegExport;
1688
1809
 
1810
+ /**
1811
+ * How large a picture the preview plays: `full` (the original), a fraction (0.5 = half size, using
1812
+ * the smallest proxy at least that large), or `auto` (what the preview canvas shows).
1813
+ */
1814
+ type VideoPreviewScale = 'auto' | 'full' | number;
1815
+ /** The scales a preview-scale control offers, besides `auto` and `full`. */
1816
+ declare const VIDEO_PROXY_SCALES: readonly [0.5, 0.25];
1817
+ /** The proxy the preview plays at `scale` (0–1]: the smallest at least that large, else `null` (play the original). */
1818
+ declare function videoAssetProxy(asset: Pick<VideoAsset, 'proxies'> | undefined, scale: number): VideoAssetProxy | null;
1819
+ /** The `src` the preview plays for an asset at `scale`: a proxy's, or the original's. */
1820
+ declare const videoPreviewSrc: (asset: VideoAsset | undefined, scale: number, fallback?: string) => string;
1821
+ /** A preview scale as a fraction: `full` is 1, `auto` is `shown` (the canvas's resolution, at most 1). */
1822
+ declare function resolveVideoPreviewScale(scale: VideoPreviewScale | undefined, shown: number): number;
1823
+ interface VideoProxyOptions {
1824
+ /** Size of the proxy as a fraction of the original (default 0.5). */
1825
+ scale?: number;
1826
+ /** Output file (default: the source's name with `.proxy-50.mp4`, for scale 0.5). */
1827
+ output?: string;
1828
+ /** The path or URL ffmpeg should open (default the asset's `src`). */
1829
+ resolve?: (asset: VideoAsset) => string;
1830
+ /** Frames between keyframes (default 12): short, so seeking and scrubbing decode little. */
1831
+ gop?: number;
1832
+ /** x264 quality (default 28: small files; proxies are for editing, not viewing). */
1833
+ crf?: number;
1834
+ }
1835
+ /** A proxy's file name next to `src`: `clip.mov` at 0.5 → `clip.proxy-50.mp4`. */
1836
+ declare function videoProxyName(src: string, scale?: number): string;
1837
+ /** An ffmpeg command making an asset's proxy, and the proxy entry to add once it exists. */
1838
+ interface VideoProxyCommand {
1839
+ asset: string;
1840
+ args: string[];
1841
+ /** One shell line. */
1842
+ command: string;
1843
+ /** The entry for `VideoAsset.proxies` (its `src` is the output; map it to a URL the preview can load if needed). */
1844
+ proxy: VideoAssetProxy;
1845
+ }
1846
+ /**
1847
+ * The ffmpeg command for a proxy of a video asset: scaled to `scale` (even sizes), H.264 with a
1848
+ * short keyframe interval (`gop`) and no B-frames so seeking is cheap, `fastdecode`, the sound
1849
+ * kept as AAC, and `faststart` so a browser can play it while it loads.
1850
+ */
1851
+ declare function videoProxyFfmpeg(asset: VideoAsset, options?: VideoProxyOptions): VideoProxyCommand;
1852
+ /** Commands for every video asset (or those listed) without a proxy at `scale`. */
1853
+ declare function videoProxyPlan(project: VideoProject, options?: VideoProxyOptions & {
1854
+ assets?: readonly string[];
1855
+ output?: never;
1856
+ }): VideoProxyCommand[];
1857
+ /** The choices a preview-size control offers, with labels: `value` round-trips through `parseVideoPreviewScale`. */
1858
+ declare const VIDEO_PREVIEW_SCALE_OPTIONS: readonly {
1859
+ value: string;
1860
+ label: string;
1861
+ scale: VideoPreviewScale;
1862
+ }[];
1863
+ /** A preview-size control's value back as a scale (`auto` for anything unknown). */
1864
+ declare const parseVideoPreviewScale: (value: string) => VideoPreviewScale;
1865
+ /** Whether any asset has proxies (so a preview-size control is worth showing). */
1866
+ declare const videoProjectHasProxies: (project: VideoProject) => boolean;
1867
+
1868
+ /**
1869
+ * A cache of decoded source frames for the preview, with prefetch ahead of the playhead, after the
1870
+ * way Blender's sequencer caches strips: scrubbing and stepping show cached frames at once instead
1871
+ * of waiting for a `<video>` to seek. It is host-side and optional: give a `VideoFrameCache` to the
1872
+ * controller (`frameCache`) or the preview engine.
1873
+ *
1874
+ * Frames are keyed by the file the preview plays (the asset's `src`, or the proxy it picks) and the
1875
+ * source frame, not by clip: every clip of an asset shares them, and edits never invalidate them.
1876
+ * Eviction removes the frames furthest from the playhead, counting frames behind it (against the
1877
+ * play direction) as further, and never touches the prefetch window.
1878
+ */
1879
+
1880
+ /** The source frame showing at a source time (ms) on an `fps` grid: a frame shows from its start. */
1881
+ declare const videoSourceFrame: (sourceTime: number, fps: number) => number;
1882
+ /** The middle of a source frame (ms): where a decoder should seek, away from the frame's edges. */
1883
+ declare const videoSourceFrameTime: (frame: number, fps: number) => number;
1884
+ /** A cache key: the file and the source frame. */
1885
+ declare const videoFrameCacheKey: (src: string, frame: number) => string;
1886
+ /** A frame the preview will need: the file, the source frame and when on the timeline it shows. */
1887
+ interface VideoFrameRequest {
1888
+ key: string;
1889
+ src: string;
1890
+ frame: number;
1891
+ /** Where to seek in the source (ms): the middle of the frame. */
1892
+ sourceTime: number;
1893
+ /** When it shows on the timeline (ms). */
1894
+ time: number;
1895
+ }
1896
+ /** The video layers' source frames at timeline `time`, as the preview would play them. */
1897
+ declare function videoFrameRequestsAt(project: VideoProject, time: number, srcFor?: (layer: VideoLayer) => string | undefined): VideoFrameRequest[];
1898
+ /**
1899
+ * The frames to have ready from `time` over the next `window` ms (backwards with `direction` -1),
1900
+ * a frame apart, nearest first, each key once.
1901
+ */
1902
+ declare function planVideoPrefetch(project: VideoProject, time: number, options?: {
1903
+ window?: number;
1904
+ direction?: 1 | -1;
1905
+ srcFor?: (layer: VideoLayer) => string | undefined;
1906
+ }): VideoFrameRequest[];
1907
+ /** A cached frame's bookkeeping for eviction. */
1908
+ interface VideoCacheEntryInfo {
1909
+ key: string;
1910
+ /** When it last showed (or will show) on the timeline (ms). */
1911
+ time: number;
1912
+ bytes: number;
1913
+ }
1914
+ /**
1915
+ * Which entries to drop to get under `maxBytes`: never those in the prefetch window
1916
+ * (`protect`), then the furthest from the playhead first, with frames behind it (against
1917
+ * `direction`) counted `behind` times as far (default 2), so the way you are going is kept.
1918
+ */
1919
+ declare function videoCacheEvictions(entries: readonly VideoCacheEntryInfo[], options: {
1920
+ playhead: number;
1921
+ maxBytes: number;
1922
+ direction?: 1 | -1;
1923
+ behind?: number;
1924
+ protect?: ReadonlySet<string>;
1925
+ }): string[];
1926
+ /** A decoded frame: anything `drawImage` takes, with its size (`close` is called when it is evicted). */
1927
+ interface VideoDecodedFrame {
1928
+ image: CanvasImageSource & {
1929
+ close?: () => void;
1930
+ };
1931
+ width: number;
1932
+ height: number;
1933
+ }
1934
+ /** Decodes the frame of `src` at a source time (ms). */
1935
+ type VideoFrameDecoder = (src: string, sourceTime: number) => Promise<VideoDecodedFrame>;
1936
+ interface VideoFrameCacheOptions {
1937
+ /** How frames are decoded for prefetch (default in a browser: `createVideoElementDecoder()`; elsewhere none, so only frames the preview hands over are kept). */
1938
+ decode?: VideoFrameDecoder | null;
1939
+ /** Memory budget in bytes (4 a pixel; default 512 MB). */
1940
+ maxBytes?: number;
1941
+ /** How far ahead of the playhead to prefetch (ms, default 2000; 0 turns prefetch off). */
1942
+ prefetch?: number;
1943
+ /** How much further frames behind the playhead count when evicting (default 2). */
1944
+ behind?: number;
1945
+ /** Frames decoded at once (default 2). */
1946
+ concurrency?: number;
1947
+ /** Copies a ready media element's current picture (default `createImageBitmap`), to keep frames the preview has shown. */
1948
+ capture?: (source: CanvasImageSource) => Promise<VideoDecodedFrame | null>;
1949
+ }
1950
+ /** The cache's state, for a status line and agents. */
1951
+ interface VideoFrameCacheStats {
1952
+ frames: number;
1953
+ bytes: number;
1954
+ maxBytes: number;
1955
+ hits: number;
1956
+ misses: number;
1957
+ /** Frames being decoded or waiting to be. */
1958
+ pending: number;
1959
+ prefetch: number;
1960
+ }
1961
+ /**
1962
+ * Decoded source frames for the preview, filled ahead of the playhead and evicted by distance from
1963
+ * it (see the module notes). `VideoPreviewEngine` calls `update` as the playhead moves, draws hits
1964
+ * from `get` while paused or while an element seeks, and hands over frames it has shown.
1965
+ */
1966
+ declare class VideoFrameCache {
1967
+ private readonly options;
1968
+ private readonly entries;
1969
+ private readonly inFlight;
1970
+ private queue;
1971
+ private protect;
1972
+ private readonly listeners;
1973
+ private playhead;
1974
+ private direction;
1975
+ private hits;
1976
+ private misses;
1977
+ private bytes;
1978
+ private generation;
1979
+ private destroyed;
1980
+ private srcFor;
1981
+ readonly maxBytes: number;
1982
+ readonly prefetch: number;
1983
+ private readonly decode;
1984
+ constructor(options?: VideoFrameCacheOptions);
1985
+ /** The cached frame of `src` showing at a source time (ms), on the project's `fps` grid. Counts a hit or a miss. */
1986
+ get(src: string, sourceTime: number, fps: number): CanvasImageSource | undefined;
1987
+ /** Whether a frame is cached, without counting it. */
1988
+ has(src: string, sourceTime: number, fps: number): boolean;
1989
+ /** Keeps a decoded frame (replacing any with the same key), then evicts to the budget. */
1990
+ put(request: Pick<VideoFrameRequest, 'key' | 'time'>, frame: VideoDecodedFrame): void;
1991
+ /** Keeps what a ready media element shows now as the frame of `src` at `sourceTime` (async; does nothing if it is cached). */
1992
+ capture(src: string, sourceTime: number, fps: number, time: number, source: CanvasImageSource): void;
1993
+ /**
1994
+ * Follows the playhead: protects the prefetch window, evicts to the budget, and queues the
1995
+ * window's missing frames for decoding (nearest first). `srcFor` gives the file a layer plays.
1996
+ */
1997
+ update(project: VideoProject, time: number, options?: {
1998
+ playing?: boolean;
1999
+ direction?: 1 | -1;
2000
+ srcFor?: (layer: VideoLayer) => string | undefined;
2001
+ }): void;
2002
+ /**
2003
+ * The stretches of the timeline whose video frames are all cached, between `from` and `to` (ms),
2004
+ * for the files the preview last played (its `srcFor`, e.g. proxies) unless `srcFor` is given.
2005
+ * `step` (ms, at least a frame) samples more coarsely.
2006
+ */
2007
+ cachedRanges(project: VideoProject, options?: {
2008
+ from?: number;
2009
+ to?: number;
2010
+ srcFor?: (layer: VideoLayer) => string | undefined;
2011
+ step?: number;
2012
+ }): {
2013
+ start: number;
2014
+ end: number;
2015
+ }[];
2016
+ stats(): VideoFrameCacheStats;
2017
+ /** Called when frames arrive or leave. */
2018
+ subscribe(listener: () => void): () => void;
2019
+ /** Drops every frame (closing them) and the queue. */
2020
+ clear(): void;
2021
+ /** Clears and stops decoding for good. */
2022
+ destroy(): void;
2023
+ private pump;
2024
+ private evict;
2025
+ private drop;
2026
+ private emit;
2027
+ }
2028
+ /**
2029
+ * A browser decoder for prefetch: one hidden, muted `<video>` per file, seeking to each requested
2030
+ * time in turn and copying the picture with `createImageBitmap` once it is presented
2031
+ * (`requestVideoFrameCallback` where the browser has it, else `seeked`). Media from another origin
2032
+ * needs CORS, as for scopes.
2033
+ */
2034
+ declare function createVideoElementDecoder(options?: {
2035
+ createVideo?: () => HTMLVideoElement;
2036
+ timeout?: number;
2037
+ }): VideoFrameDecoder;
2038
+
1689
2039
  /** What a preview follows: a `VideoEditorController` fits. */
1690
2040
  interface VideoPreviewSource {
1691
2041
  getState(): {
1692
2042
  project: VideoProject;
1693
2043
  time: number;
1694
2044
  playing: boolean;
2045
+ previewScale?: VideoPreviewScale;
1695
2046
  };
1696
2047
  subscribe(listener: () => void): () => void;
1697
2048
  /** Where to publish the drawn pixels (a controller has one), for scopes and agents. */
1698
2049
  previewPixels?: VideoPreviewPixels;
1699
2050
  /** Where grades' LUTs load from (a controller has one). */
1700
2051
  luts?: VideoLutCache;
2052
+ /** Decoded source frames with prefetch (a controller has one when the host gives it). */
2053
+ frameCache?: VideoFrameCache | null;
1701
2054
  }
1702
2055
  /** The parts of a media element the preview drives (so tests can pass fakes). */
1703
2056
  interface VideoPreviewMedia {
@@ -1726,6 +2079,8 @@ interface VideoPreviewImage {
1726
2079
  interface VideoPreviewOptions {
1727
2080
  /** Canvas pixels per frame pixel (default: fits the canvas's displayed width at the device pixel ratio, at most 1). */
1728
2081
  resolution?: number;
2082
+ /** How large a picture to play, overriding the source's `previewScale` (see `VideoPreviewScale`). */
2083
+ previewScale?: VideoPreviewScale;
1729
2084
  /** How far (ms) a playing element may drift from the timeline before it is re-seeked (default 200). */
1730
2085
  tolerance?: number;
1731
2086
  /** Makes media and image elements (default `document.createElement`). */
@@ -1745,13 +2100,19 @@ interface VideoPreviewOptions {
1745
2100
  * tool (default: the source's `previewPixels`). `null` publishes nothing.
1746
2101
  */
1747
2102
  pixels?: VideoPreviewPixels | null;
2103
+ /**
2104
+ * Decoded source frames to draw while paused, scrubbing or waiting for a seek, prefetched ahead
2105
+ * of the playhead (default: the source's `frameCache`; `null` uses none).
2106
+ */
2107
+ frameCache?: VideoFrameCache | null;
1748
2108
  /** Where grades' LUTs load from (default: the source's `luts`). Without one, LUTs are left out. */
1749
2109
  luts?: VideoLutCache | null;
1750
2110
  /**
1751
- * Makes the offscreen canvas LUT-graded layers are drawn on (default: a `<canvas>` with
1752
- * `willReadFrequently`). LUTs run on the CPU, so a lower `resolution` keeps playback smooth.
2111
+ * Makes an offscreen canvas compound clips and LUT-graded layers are drawn on (default: a
2112
+ * `<canvas>` with `willReadFrequently`), once per `slot` (see `VideoDrawOptions.scratch`). LUTs
2113
+ * run on the CPU, so a lower `resolution` keeps playback smooth.
1753
2114
  */
1754
- createScratch?: (width: number, height: number) => VideoScratchCanvas | null;
2115
+ createScratch?: (width: number, height: number, slot: number) => VideoScratchCanvas | null;
1755
2116
  }
1756
2117
  /**
1757
2118
  * Plays a project in the browser: keeps one `<video>` or `<audio>` element per playing clip in step
@@ -1776,8 +2137,13 @@ declare class VideoPreviewEngine {
1776
2137
  private drawn;
1777
2138
  private complete;
1778
2139
  private readonly lutCache;
2140
+ private readonly frameCache;
2141
+ private readonly unsubscribeFrames;
2142
+ private srcFor;
2143
+ private playing;
2144
+ private fps;
1779
2145
  private readonly unsubscribeLuts;
1780
- private scratchCanvas;
2146
+ private readonly scratchCanvases;
1781
2147
  constructor(source: VideoPreviewSource, canvas: {
1782
2148
  width: number;
1783
2149
  height: number;
@@ -1794,6 +2160,8 @@ declare class VideoPreviewEngine {
1794
2160
  update(): void;
1795
2161
  private redraw;
1796
2162
  private sourceFor;
2163
+ /** Canvas pixels per frame pixel: the option, else the displayed width at the device pixel ratio (at most 1). */
2164
+ private resolutionFor;
1797
2165
  private draw;
1798
2166
  /** A grade's LUT once loaded; while it loads (or if it fails) the frame is drawn without it and counts as incomplete. */
1799
2167
  private readonly lutFor;
@@ -1820,6 +2188,13 @@ interface VideoEditorOptions {
1820
2188
  audioPeaks?: VideoAudioPeaksCache | VideoAudioPeaksLoader;
1821
2189
  /** Where grades' LUT files (`.cube`) come from: a shared cache, or a loader (default: `fetch` each `src`). */
1822
2190
  luts?: VideoLutCache | VideoLutLoader;
2191
+ /** How large a picture the preview plays (default `auto`: a proxy as large as the canvas shows, if the asset has one). */
2192
+ previewScale?: VideoPreviewScale;
2193
+ /**
2194
+ * Decoded source frames with prefetch for the preview (see `VideoFrameCache`): scrubbing and
2195
+ * stepping then show cached frames at once. Host-side and optional (default none).
2196
+ */
2197
+ frameCache?: VideoFrameCache;
1823
2198
  }
1824
2199
  /** A snapshot of the editor. The same object is returned until something changes. */
1825
2200
  interface VideoEditorState {
@@ -1843,6 +2218,8 @@ interface VideoEditorState {
1843
2218
  canRedo: boolean;
1844
2219
  undoLabel: string;
1845
2220
  redoLabel: string;
2221
+ /** How large a picture the preview plays: `auto`, `full` or a fraction that picks a proxy. */
2222
+ previewScale: VideoPreviewScale;
1846
2223
  /** Bumped on every change. */
1847
2224
  revision: number;
1848
2225
  }
@@ -1863,10 +2240,13 @@ declare class VideoEditorController {
1863
2240
  readonly previewPixels: VideoPreviewPixels;
1864
2241
  /** Grades' LUTs, loaded on demand for the preview, SVG frames and agents. */
1865
2242
  readonly luts: VideoLutCache;
2243
+ /** The host's frame cache, if it gave one (the preview fills and reads it). */
2244
+ readonly frameCache: VideoFrameCache | null;
1866
2245
  private project;
1867
2246
  private issues;
1868
2247
  private selection;
1869
2248
  private readOnly;
2249
+ private previewScale;
1870
2250
  private error;
1871
2251
  private revision;
1872
2252
  private applying;
@@ -1901,6 +2281,12 @@ declare class VideoEditorController {
1901
2281
  clearHistory?: boolean;
1902
2282
  }): VideoEditResult;
1903
2283
  setReadOnly(readOnly: boolean): void;
2284
+ /**
2285
+ * Sets how large a picture the preview plays: `full` (the originals), a fraction such as 0.5
2286
+ * (the smallest proxy at least that large, else the original) or `auto` (as large as the canvas
2287
+ * shows). A view setting, not part of the project: no undo step.
2288
+ */
2289
+ setPreviewScale(scale: VideoPreviewScale): void;
1904
2290
  /** Selects clips (unknown ids are dropped). `add` toggles them into the current selection. */
1905
2291
  select(clips: readonly string[] | null, options?: {
1906
2292
  add?: boolean;
@@ -1972,8 +2358,320 @@ interface VideoEditorToolProviderOptions {
1972
2358
  /** How long `get_video_scopes` waits for the preview to finish drawing a frame (ms, default 5000). */
1973
2359
  framePixelsTimeout?: number;
1974
2360
  }
1975
- /** A project as agents see it: settings, assets, and each track's clips in order with their times. */
2361
+ /** A sequence as agents see it: its length, the sequences it nests, who plays it, and (with `tracks`) its tracks and clips. */
2362
+ declare function describeVideoSequence(project: VideoProject, sequence: VideoSequence, tracks?: boolean): {
2363
+ tracks: {
2364
+ clips: ({
2365
+ source?: {
2366
+ in: number;
2367
+ out: number;
2368
+ } | null | undefined;
2369
+ end: number;
2370
+ type: "media";
2371
+ asset: string;
2372
+ in?: number;
2373
+ speed?: number;
2374
+ timeRemap?: VideoKeyframes;
2375
+ volume?: VideoAnimatable;
2376
+ muted?: boolean;
2377
+ fadeInCurve?: VideoFadeCurve;
2378
+ fadeOutCurve?: VideoFadeCurve;
2379
+ id: string;
2380
+ name?: string;
2381
+ start: number;
2382
+ duration: number;
2383
+ opacity?: VideoAnimatable;
2384
+ transform?: VideoTransform;
2385
+ fit?: VideoFit;
2386
+ blend?: VideoBlendMode;
2387
+ grade?: VideoGrade;
2388
+ animateIn?: VideoClipAnimation;
2389
+ animateOut?: VideoClipAnimation;
2390
+ fadeIn?: number;
2391
+ fadeOut?: number;
2392
+ transition?: VideoTransition;
2393
+ } | {
2394
+ source?: {
2395
+ in: number;
2396
+ out: number;
2397
+ } | null | undefined;
2398
+ end: number;
2399
+ type: "text";
2400
+ text: string;
2401
+ color?: string;
2402
+ fontSize?: number;
2403
+ fontFamily?: string;
2404
+ fontWeight?: number;
2405
+ background?: string;
2406
+ id: string;
2407
+ name?: string;
2408
+ start: number;
2409
+ duration: number;
2410
+ opacity?: VideoAnimatable;
2411
+ transform?: VideoTransform;
2412
+ fit?: VideoFit;
2413
+ blend?: VideoBlendMode;
2414
+ grade?: VideoGrade;
2415
+ animateIn?: VideoClipAnimation;
2416
+ animateOut?: VideoClipAnimation;
2417
+ fadeIn?: number;
2418
+ fadeOut?: number;
2419
+ transition?: VideoTransition;
2420
+ } | {
2421
+ source?: {
2422
+ in: number;
2423
+ out: number;
2424
+ } | null | undefined;
2425
+ end: number;
2426
+ type: "color";
2427
+ color: string;
2428
+ id: string;
2429
+ name?: string;
2430
+ start: number;
2431
+ duration: number;
2432
+ opacity?: VideoAnimatable;
2433
+ transform?: VideoTransform;
2434
+ fit?: VideoFit;
2435
+ blend?: VideoBlendMode;
2436
+ grade?: VideoGrade;
2437
+ animateIn?: VideoClipAnimation;
2438
+ animateOut?: VideoClipAnimation;
2439
+ fadeIn?: number;
2440
+ fadeOut?: number;
2441
+ transition?: VideoTransition;
2442
+ } | {
2443
+ source?: {
2444
+ in: number;
2445
+ out: number;
2446
+ } | null | undefined;
2447
+ end: number;
2448
+ type: "sequence";
2449
+ sequence: string;
2450
+ in?: number;
2451
+ volume?: VideoAnimatable;
2452
+ muted?: boolean;
2453
+ fadeInCurve?: VideoFadeCurve;
2454
+ fadeOutCurve?: VideoFadeCurve;
2455
+ id: string;
2456
+ name?: string;
2457
+ start: number;
2458
+ duration: number;
2459
+ opacity?: VideoAnimatable;
2460
+ transform?: VideoTransform;
2461
+ fit?: VideoFit;
2462
+ blend?: VideoBlendMode;
2463
+ grade?: VideoGrade;
2464
+ animateIn?: VideoClipAnimation;
2465
+ animateOut?: VideoClipAnimation;
2466
+ fadeIn?: number;
2467
+ fadeOut?: number;
2468
+ transition?: VideoTransition;
2469
+ })[];
2470
+ volume?: number | undefined;
2471
+ syncLocked?: boolean | undefined;
2472
+ locked?: boolean | undefined;
2473
+ hidden?: boolean | undefined;
2474
+ muted?: boolean | undefined;
2475
+ name?: string | undefined;
2476
+ id: string;
2477
+ kind: VideoTrackKind;
2478
+ index: number;
2479
+ }[];
2480
+ cycle?: string[] | undefined;
2481
+ duration: number;
2482
+ clipCount: number;
2483
+ nests: string[];
2484
+ usedBy: {
2485
+ track: string;
2486
+ start: number;
2487
+ end: number;
2488
+ source: {
2489
+ in: number;
2490
+ out: number;
2491
+ };
2492
+ inSequence?: string | undefined;
2493
+ clip: string;
2494
+ }[];
2495
+ name?: string | undefined;
2496
+ id: string;
2497
+ } | {
2498
+ trackCount: number;
2499
+ cycle?: string[] | undefined;
2500
+ duration: number;
2501
+ clipCount: number;
2502
+ nests: string[];
2503
+ usedBy: {
2504
+ track: string;
2505
+ start: number;
2506
+ end: number;
2507
+ source: {
2508
+ in: number;
2509
+ out: number;
2510
+ };
2511
+ inSequence?: string | undefined;
2512
+ clip: string;
2513
+ }[];
2514
+ name?: string | undefined;
2515
+ id: string;
2516
+ };
2517
+ /** A project as agents see it: settings, assets, each track's clips in order with their times, and a summary of each sequence. */
1976
2518
  declare function describeVideoProject(project: VideoProject): {
2519
+ markers: VideoMarker[];
2520
+ sequences?: ({
2521
+ tracks: {
2522
+ clips: ({
2523
+ source?: {
2524
+ in: number;
2525
+ out: number;
2526
+ } | null | undefined;
2527
+ end: number;
2528
+ type: "media";
2529
+ asset: string;
2530
+ in?: number;
2531
+ speed?: number;
2532
+ timeRemap?: VideoKeyframes;
2533
+ volume?: VideoAnimatable;
2534
+ muted?: boolean;
2535
+ fadeInCurve?: VideoFadeCurve;
2536
+ fadeOutCurve?: VideoFadeCurve;
2537
+ id: string;
2538
+ name?: string;
2539
+ start: number;
2540
+ duration: number;
2541
+ opacity?: VideoAnimatable;
2542
+ transform?: VideoTransform;
2543
+ fit?: VideoFit;
2544
+ blend?: VideoBlendMode;
2545
+ grade?: VideoGrade;
2546
+ animateIn?: VideoClipAnimation;
2547
+ animateOut?: VideoClipAnimation;
2548
+ fadeIn?: number;
2549
+ fadeOut?: number;
2550
+ transition?: VideoTransition;
2551
+ } | {
2552
+ source?: {
2553
+ in: number;
2554
+ out: number;
2555
+ } | null | undefined;
2556
+ end: number;
2557
+ type: "text";
2558
+ text: string;
2559
+ color?: string;
2560
+ fontSize?: number;
2561
+ fontFamily?: string;
2562
+ fontWeight?: number;
2563
+ background?: string;
2564
+ id: string;
2565
+ name?: string;
2566
+ start: number;
2567
+ duration: number;
2568
+ opacity?: VideoAnimatable;
2569
+ transform?: VideoTransform;
2570
+ fit?: VideoFit;
2571
+ blend?: VideoBlendMode;
2572
+ grade?: VideoGrade;
2573
+ animateIn?: VideoClipAnimation;
2574
+ animateOut?: VideoClipAnimation;
2575
+ fadeIn?: number;
2576
+ fadeOut?: number;
2577
+ transition?: VideoTransition;
2578
+ } | {
2579
+ source?: {
2580
+ in: number;
2581
+ out: number;
2582
+ } | null | undefined;
2583
+ end: number;
2584
+ type: "color";
2585
+ color: string;
2586
+ id: string;
2587
+ name?: string;
2588
+ start: number;
2589
+ duration: number;
2590
+ opacity?: VideoAnimatable;
2591
+ transform?: VideoTransform;
2592
+ fit?: VideoFit;
2593
+ blend?: VideoBlendMode;
2594
+ grade?: VideoGrade;
2595
+ animateIn?: VideoClipAnimation;
2596
+ animateOut?: VideoClipAnimation;
2597
+ fadeIn?: number;
2598
+ fadeOut?: number;
2599
+ transition?: VideoTransition;
2600
+ } | {
2601
+ source?: {
2602
+ in: number;
2603
+ out: number;
2604
+ } | null | undefined;
2605
+ end: number;
2606
+ type: "sequence";
2607
+ sequence: string;
2608
+ in?: number;
2609
+ volume?: VideoAnimatable;
2610
+ muted?: boolean;
2611
+ fadeInCurve?: VideoFadeCurve;
2612
+ fadeOutCurve?: VideoFadeCurve;
2613
+ id: string;
2614
+ name?: string;
2615
+ start: number;
2616
+ duration: number;
2617
+ opacity?: VideoAnimatable;
2618
+ transform?: VideoTransform;
2619
+ fit?: VideoFit;
2620
+ blend?: VideoBlendMode;
2621
+ grade?: VideoGrade;
2622
+ animateIn?: VideoClipAnimation;
2623
+ animateOut?: VideoClipAnimation;
2624
+ fadeIn?: number;
2625
+ fadeOut?: number;
2626
+ transition?: VideoTransition;
2627
+ })[];
2628
+ volume?: number | undefined;
2629
+ syncLocked?: boolean | undefined;
2630
+ locked?: boolean | undefined;
2631
+ hidden?: boolean | undefined;
2632
+ muted?: boolean | undefined;
2633
+ name?: string | undefined;
2634
+ id: string;
2635
+ kind: VideoTrackKind;
2636
+ index: number;
2637
+ }[];
2638
+ cycle?: string[] | undefined;
2639
+ duration: number;
2640
+ clipCount: number;
2641
+ nests: string[];
2642
+ usedBy: {
2643
+ track: string;
2644
+ start: number;
2645
+ end: number;
2646
+ source: {
2647
+ in: number;
2648
+ out: number;
2649
+ };
2650
+ inSequence?: string | undefined;
2651
+ clip: string;
2652
+ }[];
2653
+ name?: string | undefined;
2654
+ id: string;
2655
+ } | {
2656
+ trackCount: number;
2657
+ cycle?: string[] | undefined;
2658
+ duration: number;
2659
+ clipCount: number;
2660
+ nests: string[];
2661
+ usedBy: {
2662
+ track: string;
2663
+ start: number;
2664
+ end: number;
2665
+ source: {
2666
+ in: number;
2667
+ out: number;
2668
+ };
2669
+ inSequence?: string | undefined;
2670
+ clip: string;
2671
+ }[];
2672
+ name?: string | undefined;
2673
+ id: string;
2674
+ })[] | undefined;
1977
2675
  assets: ({
1978
2676
  id: string;
1979
2677
  kind: VideoAssetKind;
@@ -1984,6 +2682,7 @@ declare function describeVideoProject(project: VideoProject): {
1984
2682
  height?: number;
1985
2683
  hasAudio?: boolean;
1986
2684
  poster?: string;
2685
+ proxies?: VideoAssetProxy[];
1987
2686
  } | {
1988
2687
  transcriptWords: number;
1989
2688
  id: string;
@@ -1995,6 +2694,7 @@ declare function describeVideoProject(project: VideoProject): {
1995
2694
  height?: number;
1996
2695
  hasAudio?: boolean;
1997
2696
  poster?: string;
2697
+ proxies?: VideoAssetProxy[];
1998
2698
  })[];
1999
2699
  tracks: {
2000
2700
  clips: ({
@@ -2075,6 +2775,33 @@ declare function describeVideoProject(project: VideoProject): {
2075
2775
  fadeIn?: number;
2076
2776
  fadeOut?: number;
2077
2777
  transition?: VideoTransition;
2778
+ } | {
2779
+ source?: {
2780
+ in: number;
2781
+ out: number;
2782
+ } | null | undefined;
2783
+ end: number;
2784
+ type: "sequence";
2785
+ sequence: string;
2786
+ in?: number;
2787
+ volume?: VideoAnimatable;
2788
+ muted?: boolean;
2789
+ fadeInCurve?: VideoFadeCurve;
2790
+ fadeOutCurve?: VideoFadeCurve;
2791
+ id: string;
2792
+ name?: string;
2793
+ start: number;
2794
+ duration: number;
2795
+ opacity?: VideoAnimatable;
2796
+ transform?: VideoTransform;
2797
+ fit?: VideoFit;
2798
+ blend?: VideoBlendMode;
2799
+ grade?: VideoGrade;
2800
+ animateIn?: VideoClipAnimation;
2801
+ animateOut?: VideoClipAnimation;
2802
+ fadeIn?: number;
2803
+ fadeOut?: number;
2804
+ transition?: VideoTransition;
2078
2805
  })[];
2079
2806
  volume?: number | undefined;
2080
2807
  syncLocked?: boolean | undefined;
@@ -2086,7 +2813,6 @@ declare function describeVideoProject(project: VideoProject): {
2086
2813
  kind: VideoTrackKind;
2087
2814
  index: number;
2088
2815
  }[];
2089
- markers: VideoMarker[];
2090
2816
  background?: string | undefined;
2091
2817
  width: number;
2092
2818
  height: number;
@@ -2131,8 +2857,8 @@ declare const VIDEO_BLEND_MODE_LABELS: Readonly<Record<VideoBlendMode, string>>;
2131
2857
  /** Names for the sound fade curves, for menus. */
2132
2858
  declare const VIDEO_FADE_CURVE_LABELS: Readonly<Record<VideoFadeCurve, string>>;
2133
2859
  declare function videoClipTint(clip: VideoClip, asset?: VideoAsset): string;
2134
- /** A short label for a clip on the timeline. */
2135
- declare function videoClipLabel(clip: VideoClip, asset?: VideoAsset): string;
2860
+ /** A short label for a clip on the timeline (pass the sequence a compound clip plays, for its name). */
2861
+ declare function videoClipLabel(clip: VideoClip, asset?: VideoAsset, sequence?: VideoSequence): string;
2136
2862
  type VideoClipDragMode = 'move' | 'trim-start' | 'trim-end';
2137
2863
  interface VideoClipDragInput {
2138
2864
  clip: string;
@@ -2230,4 +2956,4 @@ declare function videoKeyframeToggleEdit(project: VideoProject, clipId: string,
2230
2956
  */
2231
2957
  declare function videoLutEdits(project: VideoProject, clips: readonly string[], lut: VideoGradeLut | null): VideoEdit[];
2232
2958
 
2233
- export { type CreateVideoProjectOptions, type NewVideoClip, VIDEO_BLEND_MODES, VIDEO_BLEND_MODE_LABELS, VIDEO_CLIP_ANIMATION_DURATION, VIDEO_CLIP_ANIMATION_EFFECTS, VIDEO_CLIP_ANIMATION_LABELS, VIDEO_CLIP_TYPES, VIDEO_DEFAULT_FILLERS, VIDEO_DEFAULT_STILL_DURATION, VIDEO_DEFAULT_TITLE_DURATION, VIDEO_EASE_NAMES, VIDEO_EDIT_OPS, VIDEO_FADE_CURVES, VIDEO_FADE_CURVE_LABELS, VIDEO_FITS, VIDEO_GRADE_CONTROLS, VIDEO_GRADE_PRESETS, VIDEO_GRADE_PRESET_NAMES, VIDEO_ISSUE_CODES, VIDEO_KEYFRAME_LIMITS, VIDEO_KEYFRAME_PROPERTIES, VIDEO_LUT_MAX_SIZE, VIDEO_PEAK_BLOCK, VIDEO_PLACEMENT_MODES, VIDEO_SCOPE_KINDS, VIDEO_TIME_EPSILON, VIDEO_TRANSFORM_PROPERTIES, VIDEO_TRANSITION_LABELS, VIDEO_TRANSITION_TYPES, VIDEO_VECTORSCOPE_TARGETS, VIDEO_WIPE_DIRECTIONS, type VideoAnimatable, type VideoAsset, type VideoAssetKind, type VideoAudioLevel, type VideoAudioPeaks, VideoAudioPeaksCache, type VideoAudioPeaksLoader, type VideoAudioSource, type VideoBlendMode, type VideoCanvasContext, type VideoClip, type VideoClipAnimation, type VideoClipAnimationEffect, type VideoClipDragInput, type VideoClipDragMode, type VideoClipDragPlan, type VideoClipLocation, type VideoClipType, type VideoColorClip, type VideoDrawOptions, type VideoEase, type VideoEdit, type VideoEditOp, type VideoEditOutcome, type VideoEditResult, VideoEditorController, type VideoEditorOptions, type VideoEditorState, type VideoEditorToolProviderOptions, type VideoEdlOptions, type VideoExposureOptions, type VideoExposureStats, type VideoFadeCurve, type VideoFfmpegExport, type VideoFfmpegOptions, type VideoFit, type VideoFrame, type VideoGap, type VideoGrade, type VideoGradeControl, type VideoGradeLut, type VideoGradePreset, type VideoGradeSetting, type VideoGradeStep, type VideoHistogram, type VideoIssue, type VideoIssueCode, type VideoIssueSeverity, type VideoKey, type VideoKeyframeProperty, type VideoKeyframeRow, type VideoKeyframes, type VideoLayer, type VideoLoudnessMeasurement, type VideoLoudnessTarget, type VideoLut, VideoLutCache, type VideoLutLoader, type VideoLutSvgApproximation, type VideoMarker, type VideoMediaClip, type VideoMediaProbe, type VideoPauseOptions, type VideoPixels, type VideoPlacementMode, VideoPreviewEngine, type VideoPreviewImage, type VideoPreviewMedia, type VideoPreviewOptions, VideoPreviewPixels, type VideoPreviewSnapshot, type VideoPreviewSource, type VideoProject, type VideoRect, type VideoRulerTick, type VideoScopeImage, type VideoScopeKind, type VideoScopeOptions, type VideoScopeSummary, type VideoScopesPanelReading, type VideoScratchCanvas, type VideoSilenceOptions, type VideoSnapOptions, type VideoSpeedSegment, type VideoSvgOptions, type VideoTextClip, type VideoTimelineWord, type VideoTrack, type VideoTrackKind, type VideoTranscriptRange, type VideoTranscriptWord, type VideoTransform, type VideoTransition, type VideoTransitionType, type VideoVectorscope, type VideoWaveform, type VideoWaveformMode, type VideoWipeDirection, allVideoClipIds, applyVideoEdits, applyVideoGrade, applyVideoLut, applyVideoLutToPixels, buildVideoAudioPeaks, checkVideoProject, checkVideoTimeRemap, createVideoEditorToolProvider, createVideoProject, decodeVideoAudioPeaks, describeVideoProject, drawVideoFrame, ffmpegFilterValue, findVideoAudioSilences, findVideoClip, findVideoFillers, findVideoGaps, findVideoTranscriptPauses, findVideoTranscriptText, formatVideoSeconds, formatVideoTimecode, formatVideoTimecodeFrames, isVideoDropFrameRate, isVideoKeyframes, mergeVideoRanges, nextFreeVideoSlot, normalizeVideoGrade, normalizeVideoGradeLut, normalizeVideoWord, parseVideoAnimatable, parseVideoAsset, parseVideoClip, parseVideoClipAnimation, parseVideoCubeLut, parseVideoGrade, parseVideoGradeLut, parseVideoKeyframes, parseVideoLoudnessMeasurement, parseVideoMarker, parseVideoProject, parseVideoTimeRemap, parseVideoTrack, parseVideoTranscript, parseVideoTranscriptWords, parseVideoTransform, parseVideoTransition, placeVideoRect, planVideoClipDrag, probeVideoMedia, readVideoScopesPanel, removeVideoKey, retimeVideoAnimatable, setVideoKey, snapToVideoFrame, snapVideoTime, sortVideoKeys, sortedVideoClips, splitVideoAnimatable, summarizeVideoScopes, toVideoEdl, toVideoFfmpeg, toVideoLoudnessMeasure, videoAssetDropEdit, videoAssetHasSound, videoAssetKindOf, videoAssetMap, videoAudioLevels, videoAudioPeakRange, videoAudioPeakSpans, videoAudioPeaksDuration, videoChroma, videoClipAfter, videoClipAnimated, videoClipAnimationProperties, videoClipAnimationSpans, videoClipBefore, videoClipEnd, videoClipHandles, videoClipKeyframes, videoClipLabel, videoClipOverhang, videoClipShowsWaveform, videoClipSoundGain, videoClipSourceRange, videoClipSourceTime, videoClipSpeed, videoClipSpeedAt, videoClipTint, videoClipWaveform, videoClipWaveformPath, videoClipsAt, videoContactSheetSvg, videoDragLabel, videoDropTracks, videoEaseBezier, videoEaseProgress, videoExposureNotes, videoExposureStats, videoFadeCurveGain, videoFrameAt, videoFrameDuration, videoFrameToSvg, videoFrames, videoFreezeFrameEdit, videoGradeCssFilter, videoGradeFfmpegFilters, videoGradeGainsFilterId, videoGradeLook, videoGradePreset, videoGradeStepMatrix, videoGradeStepSvgValues, videoGradeSteps, videoGradeSvgDefs, videoGradeSvgFilter, videoHistogram, videoHistogramImage, videoHourFrames, videoIrisRadius, videoIssueKey, videoKeyframeBreakpoints, videoKeyframeFfmpegExpr, videoKeyframeRows, videoKeyframeToggleEdit, videoKeyframeValueEdit, videoKeysOf, videoLuma, videoLumaWaveform, videoLutEdits, videoLutFromFunction, videoLutSvgApproximation, videoLutSvgPrimitives, videoLutToCube, videoOverlap, videoPeakDb, videoProjectDuration, videoProjectSvg, videoRemoveRangesEdits, videoRulerTicks, videoScopeImage, videoSlowMotionRamp, videoSnapPoints, videoSpeedRampEdit, videoSpeedRampKeys, videoTextStyle, videoTimeRemapBreakpoints, videoTimeRemapSpan, videoTimecodeFrames, videoTimelineTranscript, videoTitleFrame, videoTrackSyncLocked, videoTranscriptEdit, videoTranscriptTrack, videoTransformAt, videoTransitionAudioCurve, videoTransitionEase, videoTransitionHasDirection, videoValueAt, videoVectorscope, videoVectorscopeAngle, videoVectorscopeImage, videoVectorscopePoint, videoWaveformImage, videoWaveformPath, videoWipeRect, videoWordAt, videoWordsRange };
2959
+ export { type CreateVideoProjectOptions, type NewVideoClip, VIDEO_BLEND_MODES, VIDEO_BLEND_MODE_LABELS, VIDEO_CLIP_ANIMATION_DURATION, VIDEO_CLIP_ANIMATION_EFFECTS, VIDEO_CLIP_ANIMATION_LABELS, VIDEO_CLIP_TYPES, VIDEO_DEFAULT_FILLERS, VIDEO_DEFAULT_STILL_DURATION, VIDEO_DEFAULT_TITLE_DURATION, VIDEO_EASE_NAMES, VIDEO_EDIT_OPS, VIDEO_FADE_CURVES, VIDEO_FADE_CURVE_LABELS, VIDEO_FITS, VIDEO_GRADE_CONTROLS, VIDEO_GRADE_PRESETS, VIDEO_GRADE_PRESET_NAMES, VIDEO_ISSUE_CODES, VIDEO_KEYFRAME_LIMITS, VIDEO_KEYFRAME_PROPERTIES, VIDEO_LUT_MAX_SIZE, VIDEO_PEAK_BLOCK, VIDEO_PLACEMENT_MODES, VIDEO_PREVIEW_SCALE_OPTIONS, VIDEO_PROXY_SCALES, VIDEO_SCOPE_KINDS, VIDEO_TIME_EPSILON, VIDEO_TRANSFORM_PROPERTIES, VIDEO_TRANSITION_LABELS, VIDEO_TRANSITION_TYPES, VIDEO_VECTORSCOPE_TARGETS, VIDEO_WIPE_DIRECTIONS, type VideoAnimatable, type VideoAsset, type VideoAssetKind, type VideoAssetProxy, type VideoAudioLevel, type VideoAudioPeaks, VideoAudioPeaksCache, type VideoAudioPeaksLoader, type VideoAudioSource, type VideoBlendMode, type VideoCacheEntryInfo, type VideoCanvasContext, type VideoClip, type VideoClipAnimation, type VideoClipAnimationEffect, type VideoClipDragInput, type VideoClipDragMode, type VideoClipDragPlan, type VideoClipLocation, type VideoClipType, type VideoColorClip, type VideoDecodedFrame, type VideoDrawOptions, type VideoEase, type VideoEdit, type VideoEditOp, type VideoEditOutcome, type VideoEditResult, VideoEditorController, type VideoEditorOptions, type VideoEditorState, type VideoEditorToolProviderOptions, type VideoEdlOptions, type VideoExposureOptions, type VideoExposureStats, type VideoFadeCurve, type VideoFfmpegExport, type VideoFfmpegOptions, type VideoFit, type VideoFrame, VideoFrameCache, type VideoFrameCacheOptions, type VideoFrameCacheStats, type VideoFrameDecoder, type VideoFrameRequest, type VideoGap, type VideoGrade, type VideoGradeControl, type VideoGradeLut, type VideoGradePreset, type VideoGradeSetting, type VideoGradeStep, type VideoHistogram, type VideoIssue, type VideoIssueCode, type VideoIssueSeverity, type VideoKey, type VideoKeyframeProperty, type VideoKeyframeRow, type VideoKeyframes, type VideoLayer, type VideoLoudnessMeasurement, type VideoLoudnessTarget, type VideoLut, VideoLutCache, type VideoLutLoader, type VideoLutSvgApproximation, type VideoMarker, type VideoMediaClip, type VideoMediaProbe, type VideoPauseOptions, type VideoPixels, type VideoPlacementMode, VideoPreviewEngine, type VideoPreviewImage, type VideoPreviewMedia, type VideoPreviewOptions, VideoPreviewPixels, type VideoPreviewScale, type VideoPreviewSnapshot, type VideoPreviewSource, type VideoProject, type VideoProxyCommand, type VideoProxyOptions, type VideoRect, type VideoRulerTick, type VideoScopeImage, type VideoScopeKind, type VideoScopeOptions, type VideoScopeSummary, type VideoScopesPanelReading, type VideoScratchCanvas, type VideoSequence, type VideoSequenceClip, type VideoSilenceOptions, type VideoSnapOptions, type VideoSpeedSegment, type VideoSvgOptions, type VideoTextClip, type VideoTimelineWord, type VideoTrack, type VideoTrackKind, type VideoTranscriptRange, type VideoTranscriptWord, type VideoTransform, type VideoTransition, type VideoTransitionType, type VideoVectorscope, type VideoWaveform, type VideoWaveformMode, type VideoWipeDirection, allVideoClipIds, allVideoTracks, applyVideoEdits, applyVideoGrade, applyVideoLut, applyVideoLutToPixels, buildVideoAudioPeaks, checkVideoProject, checkVideoTimeRemap, createVideoEditorToolProvider, createVideoElementDecoder, createVideoProject, decodeVideoAudioPeaks, describeVideoProject, describeVideoSequence, drawVideoFrame, ffmpegFilterValue, findVideoAudioSilences, findVideoClip, findVideoFillers, findVideoGaps, findVideoSequenceClip, findVideoSequenceCycle, findVideoTranscriptPauses, findVideoTranscriptText, formatVideoSeconds, formatVideoTimecode, formatVideoTimecodeFrames, isVideoDropFrameRate, isVideoKeyframes, mergeVideoRanges, nextFreeVideoSlot, normalizeVideoGrade, normalizeVideoGradeLut, normalizeVideoWord, parseVideoAnimatable, parseVideoAsset, parseVideoAssetProxies, parseVideoClip, parseVideoClipAnimation, parseVideoCubeLut, parseVideoGrade, parseVideoGradeLut, parseVideoKeyframes, parseVideoLoudnessMeasurement, parseVideoMarker, parseVideoPreviewScale, parseVideoProject, parseVideoSequence, parseVideoTimeRemap, parseVideoTrack, parseVideoTranscript, parseVideoTranscriptWords, parseVideoTransform, parseVideoTransition, placeVideoRect, planVideoClipDrag, planVideoPrefetch, probeVideoMedia, readVideoScopesPanel, removeVideoKey, resolveVideoPreviewScale, retimeVideoAnimatable, setVideoKey, snapToVideoFrame, snapVideoTime, sortVideoKeys, sortedVideoClips, splitVideoAnimatable, summarizeVideoScopes, toVideoEdl, toVideoFfmpeg, toVideoLoudnessMeasure, videoAssetDropEdit, videoAssetHasSound, videoAssetKindOf, videoAssetMap, videoAssetProxy, videoAudioLevels, videoAudioPeakRange, videoAudioPeakSpans, videoAudioPeaksDuration, videoCacheEvictions, videoChroma, videoClipAfter, videoClipAnimated, videoClipAnimationProperties, videoClipAnimationSpans, videoClipBefore, videoClipEnd, videoClipHandles, videoClipKeyframes, videoClipLabel, videoClipOverhang, videoClipShowsWaveform, videoClipSoundGain, videoClipSourceRange, videoClipSourceTime, videoClipSpeed, videoClipSpeedAt, videoClipTint, videoClipWaveform, videoClipWaveformPath, videoClipsAt, videoContactSheetSvg, videoDragLabel, videoDropTracks, videoEaseBezier, videoEaseProgress, videoExposureNotes, videoExposureStats, videoFadeCurveGain, videoFrameAt, videoFrameCacheKey, videoFrameDuration, videoFrameLeafLayers, videoFrameRequestsAt, videoFrameToSvg, videoFrames, videoFreezeFrameEdit, videoGradeCssFilter, videoGradeFfmpegFilters, videoGradeGainsFilterId, videoGradeLook, videoGradePreset, videoGradeStepMatrix, videoGradeStepSvgValues, videoGradeSteps, videoGradeSvgDefs, videoGradeSvgFilter, videoHistogram, videoHistogramImage, videoHourFrames, videoIrisRadius, videoIssueKey, videoKeyframeBreakpoints, videoKeyframeFfmpegExpr, videoKeyframeRows, videoKeyframeToggleEdit, videoKeyframeValueEdit, videoKeysOf, videoLuma, videoLumaWaveform, videoLutEdits, videoLutFromFunction, videoLutSvgApproximation, videoLutSvgPrimitives, videoLutToCube, videoOverlap, videoPeakDb, videoPreviewSrc, videoProjectDuration, videoProjectHasProxies, videoProjectSvg, videoProxyFfmpeg, videoProxyName, videoProxyPlan, videoRemoveRangesEdits, videoRulerTicks, videoScopeImage, videoSequenceChildren, videoSequenceDuration, videoSequenceMap, videoShellQuote, videoSlowMotionRamp, videoSnapPoints, videoSourceFrame, videoSourceFrameTime, videoSpeedRampEdit, videoSpeedRampKeys, videoTextStyle, videoTimeRemapBreakpoints, videoTimeRemapSpan, videoTimecodeFrames, videoTimelineTranscript, videoTitleFrame, videoTrackSyncLocked, videoTranscriptEdit, videoTranscriptTrack, videoTransformAt, videoTransitionAudioCurve, videoTransitionEase, videoTransitionHasDirection, videoValueAt, videoVectorscope, videoVectorscopeAngle, videoVectorscopeImage, videoVectorscopePoint, videoWaveformImage, videoWaveformPath, videoWipeRect, videoWordAt, videoWordsRange };