@pixerate/editor 0.87.0 → 0.89.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.
Files changed (72) hide show
  1. package/THIRD_PARTY_NOTICES.md +8 -2
  2. package/dist/agent/index.cjs +28 -28
  3. package/dist/agent/index.js +3 -3
  4. package/dist/canvas/index.cjs +3 -3
  5. package/dist/canvas/index.cjs.map +1 -1
  6. package/dist/canvas/index.js +16 -16
  7. package/dist/{chunk-TYOAJDFD.cjs → chunk-66IMF6OD.cjs} +3 -3
  8. package/dist/{chunk-TYOAJDFD.cjs.map → chunk-66IMF6OD.cjs.map} +1 -1
  9. package/dist/chunk-D4ZCU72J.js +604 -0
  10. package/dist/chunk-D4ZCU72J.js.map +1 -0
  11. package/dist/{chunk-IMSX4IVG.js → chunk-FWEO3HSL.js} +4 -4
  12. package/dist/chunk-H543GD6T.cjs +1696 -0
  13. package/dist/chunk-H543GD6T.cjs.map +1 -0
  14. package/dist/{chunk-ROXFP2LQ.cjs → chunk-HNDSPZ5T.cjs} +4 -4
  15. package/dist/{chunk-ROXFP2LQ.cjs.map → chunk-HNDSPZ5T.cjs.map} +1 -1
  16. package/dist/{chunk-MXF4DP2C.cjs → chunk-J3B45HTA.cjs} +74 -74
  17. package/dist/{chunk-MXF4DP2C.cjs.map → chunk-J3B45HTA.cjs.map} +1 -1
  18. package/dist/{chunk-GNO5PEMH.js → chunk-OK7T2LHK.js} +2 -2
  19. package/dist/chunk-P5TPUNBZ.js +1696 -0
  20. package/dist/chunk-P5TPUNBZ.js.map +1 -0
  21. package/dist/chunk-PDCITYBT.cjs +416 -0
  22. package/dist/chunk-PDCITYBT.cjs.map +1 -0
  23. package/dist/{chunk-RKJDBXTY.cjs → chunk-T4XWVPJK.cjs} +3 -3
  24. package/dist/{chunk-RKJDBXTY.cjs.map → chunk-T4XWVPJK.cjs.map} +1 -1
  25. package/dist/{chunk-ZQNDSUZO.js → chunk-UKI64KUD.js} +6 -6
  26. package/dist/{chunk-SVW2UNUC.js → chunk-WON34HKM.js} +2 -2
  27. package/dist/chunk-YLB2WVNA.js +416 -0
  28. package/dist/chunk-YLB2WVNA.js.map +1 -0
  29. package/dist/chunk-ZOOEX3WT.cjs +604 -0
  30. package/dist/chunk-ZOOEX3WT.cjs.map +1 -0
  31. package/dist/extensions/index.cjs +6 -6
  32. package/dist/extensions/index.cjs.map +1 -1
  33. package/dist/extensions/index.js +5 -5
  34. package/dist/image-editor/index.cjs +4387 -690
  35. package/dist/image-editor/index.cjs.map +1 -1
  36. package/dist/image-editor/index.d.cts +1677 -590
  37. package/dist/image-editor/index.d.ts +1677 -590
  38. package/dist/image-editor/index.js +4273 -576
  39. package/dist/image-editor/index.js.map +1 -1
  40. package/dist/index.cjs +27 -27
  41. package/dist/index.cjs.map +1 -1
  42. package/dist/index.js +10 -10
  43. package/dist/paint/index.cjs +38 -0
  44. package/dist/paint/index.cjs.map +1 -0
  45. package/dist/paint/index.d.cts +167 -0
  46. package/dist/paint/index.d.ts +167 -0
  47. package/dist/paint/index.js +38 -0
  48. package/dist/paint/index.js.map +1 -0
  49. package/dist/raster/index.cjs +121 -0
  50. package/dist/raster/index.cjs.map +1 -0
  51. package/dist/raster/index.d.cts +365 -0
  52. package/dist/raster/index.d.ts +365 -0
  53. package/dist/raster/index.js +121 -0
  54. package/dist/raster/index.js.map +1 -0
  55. package/dist/serializers/index.cjs +4 -4
  56. package/dist/serializers/index.cjs.map +1 -1
  57. package/dist/serializers/index.js +3 -3
  58. package/dist/surface-fJhkmNQn.d.cts +181 -0
  59. package/dist/surface-fJhkmNQn.d.ts +181 -0
  60. package/dist/video-editor/index.cjs +930 -503
  61. package/dist/video-editor/index.cjs.map +1 -1
  62. package/dist/video-editor/index.d.cts +158 -11
  63. package/dist/video-editor/index.d.ts +158 -11
  64. package/dist/video-editor/index.js +841 -414
  65. package/dist/video-editor/index.js.map +1 -1
  66. package/package.json +13 -2
  67. package/skills/pixerate-image-editor/SKILL.md +111 -11
  68. package/skills/pixerate-video-editor/SKILL.md +11 -2
  69. /package/dist/{chunk-IMSX4IVG.js.map → chunk-FWEO3HSL.js.map} +0 -0
  70. /package/dist/{chunk-GNO5PEMH.js.map → chunk-OK7T2LHK.js.map} +0 -0
  71. /package/dist/{chunk-ZQNDSUZO.js.map → chunk-UKI64KUD.js.map} +0 -0
  72. /package/dist/{chunk-SVW2UNUC.js.map → chunk-WON34HKM.js.map} +0 -0
@@ -191,9 +191,18 @@ declare const videoTransitionAudioCurve: (t: VideoTransition) => VideoFadeCurve;
191
191
  */
192
192
  type VideoBlendMode = 'normal' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' | 'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' | 'difference' | 'exclusion' | 'add';
193
193
  declare const VIDEO_BLEND_MODES: readonly ["normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light", "difference", "exclusion", "add"];
194
+ /** A 3D LUT a grade applies after its other steps (see `VideoGrade.lut`). */
195
+ interface VideoGradeLut {
196
+ /** A `.cube` file: whatever the host can load (URL, path) and the exporter can open. */
197
+ src: string;
198
+ /** How much of the LUT's change to apply, 0–1 (default 1). */
199
+ strength?: number;
200
+ /** A label for the look (default the file's TITLE or name). */
201
+ name?: string;
202
+ }
194
203
  /**
195
204
  * Colour correction for a clip's picture (see `VIDEO_GRADE_CONTROLS` for ranges). Applied in a fixed
196
- * order: exposure, contrast, saturation, hue, then white balance (temperature and tint).
205
+ * order: exposure, contrast, saturation, hue, white balance (temperature and tint), then the LUT.
197
206
  */
198
207
  interface VideoGrade {
199
208
  /** Stops: +1 doubles every channel (default 0). */
@@ -208,6 +217,8 @@ interface VideoGrade {
208
217
  temperature?: number;
209
218
  /** -1 (green) to 1 (magenta); default 0. */
210
219
  tint?: number;
220
+ /** A 3D LUT (a `.cube` file) applied last, mixed in at its `strength`. */
221
+ lut?: VideoGradeLut;
211
222
  }
212
223
  /**
213
224
  * How a clip enters or leaves: `fade`; `rise` (up into place) or `drop` (down into place);
@@ -354,6 +365,7 @@ declare function parseVideoTransform(v: unknown, path: string): VideoTransform |
354
365
  declare function parseVideoTimeRemap(v: unknown, speed: unknown, path: string): VideoKeyframes | undefined;
355
366
  declare function parseVideoClipAnimation(v: unknown, path: string): VideoClipAnimation | undefined;
356
367
  declare function parseVideoGrade(v: unknown, path: string): VideoGrade | undefined;
368
+ declare function parseVideoGradeLut(v: unknown, path: string): VideoGradeLut | undefined;
357
369
  declare function parseVideoTransition(v: unknown, path: string): VideoTransition | undefined;
358
370
  declare function parseVideoTranscriptWords(v: unknown, path: string): VideoTranscriptWord[] | undefined;
359
371
  declare function parseVideoAsset(v: unknown, path?: string): VideoAsset;
@@ -931,6 +943,83 @@ declare class VideoAudioPeaksCache {
931
943
  private emit;
932
944
  }
933
945
 
946
+ /**
947
+ * 3D LUTs for grades: `.cube` files read into a lattice and applied with tetrahedral
948
+ * interpolation, as ffmpeg's `lut3d=interp=tetrahedral` and grading apps apply them, so the
949
+ * preview and the export agree. A grade's LUT (`VideoGrade.lut`) runs after its other steps and is
950
+ * mixed with the picture before it by `strength`.
951
+ */
952
+ /** A 3D LUT: `size`³ output colours, red changing fastest, then green, then blue (the `.cube` order). */
953
+ interface VideoLut {
954
+ title?: string;
955
+ size: number;
956
+ /** Input values mapped to the first and last lattice points, per channel (default 0 and 1). */
957
+ domainMin: [number, number, number];
958
+ domainMax: [number, number, number];
959
+ /** `size³ × 3` output values. */
960
+ data: Float32Array;
961
+ }
962
+ /** Largest `LUT_3D_SIZE` read (129³ rows is about 2 million). */
963
+ declare const VIDEO_LUT_MAX_SIZE = 129;
964
+ /** Reads a `.cube` file's 3D table. Errors give the line and what is wrong. */
965
+ declare function parseVideoCubeLut(text: string): VideoLut;
966
+ /** A LUT of `size` points a side built from a colour function (each channel 0–1 in and out). */
967
+ declare function videoLutFromFunction(size: number, fn: (rgb: [number, number, number]) => readonly [number, number, number], title?: string): VideoLut;
968
+ /** A LUT as `.cube` text. */
969
+ declare function videoLutToCube(lut: VideoLut): string;
970
+ /**
971
+ * A colour (each channel 0–1) through a LUT with tetrahedral interpolation: the lattice cube
972
+ * around the colour is split into six tetrahedra along its grey diagonal, and the colour is mixed
973
+ * from the four corners of the one it falls in. Greys stay on the diagonal, unlike trilinear.
974
+ */
975
+ declare function applyVideoLut(lut: VideoLut, rgb: readonly [number, number, number], out?: [number, number, number]): [number, number, number];
976
+ /** Runs RGBA pixels (0–255, as `ImageData` has them) through a LUT in place, mixed with the originals by `strength` (0–1). Transparent pixels are left alone. */
977
+ declare function applyVideoLutToPixels(lut: VideoLut, data: {
978
+ length: number;
979
+ [i: number]: number;
980
+ }, strength?: number): void;
981
+ /**
982
+ * An SVG approximation of a LUT for SVG frames, which have no 3D tables: per-channel curves taken
983
+ * along the LUT's grey axis (`feComponentTransfer` tables), then the colour matrix that best fits
984
+ * the rest (least squares over the lattice). Exact for LUTs that are curves or a matrix; close for
985
+ * most looks. The preview and the export apply the LUT itself.
986
+ */
987
+ interface VideoLutSvgApproximation {
988
+ /** Per-channel curve tables (`tableValues`), each 0–1. */
989
+ tables: [number[], number[], number[]];
990
+ /** A 3 × 4 matrix (rows r, g, b; columns r, g, b, offset) applied after the curves. */
991
+ matrix: number[][];
992
+ }
993
+ declare function videoLutSvgApproximation(lut: VideoLut): VideoLutSvgApproximation;
994
+ /** Where LUT files come from: their text for a `src` (default: `fetch`). */
995
+ type VideoLutLoader = (src: string) => Promise<string | VideoLut>;
996
+ /**
997
+ * Loaded LUTs by `src`, read once and shared by the preview, SVG frames and agent tools
998
+ * (`VideoEditorController.luts`). Listeners hear when one loads or fails.
999
+ */
1000
+ declare class VideoLutCache {
1001
+ private readonly loader;
1002
+ private readonly ready;
1003
+ private readonly pending;
1004
+ private readonly failed;
1005
+ private readonly listeners;
1006
+ constructor(loader?: VideoLutLoader);
1007
+ /** The LUT if loaded, without starting to load it. */
1008
+ peek(src: string): VideoLut | undefined;
1009
+ /** The LUT if loaded; otherwise `undefined`, and loading starts (once) unless it failed. */
1010
+ get(src: string): VideoLut | undefined;
1011
+ /** Why loading a LUT failed, if it did. */
1012
+ error(src: string): string | undefined;
1013
+ /** The LUT, loading and reading it if needed. Rejects with a readable error. */
1014
+ load(src: string): Promise<VideoLut>;
1015
+ /** Uses a LUT the host already has (`.cube` text or a parsed LUT), under `src`. */
1016
+ set(src: string, lut: VideoLut | string): VideoLut;
1017
+ /** Forgets a failure so the next `get` tries again. */
1018
+ retry(src: string): void;
1019
+ subscribe(fn: () => void): () => void;
1020
+ private emit;
1021
+ }
1022
+
934
1023
  /**
935
1024
  * Colour correction as a fixed series of colour-matrix steps on gamma-encoded sRGB, each clamped
936
1025
  * to 0–1, in the same order everywhere: exposure, contrast, saturation, hue, then white balance.
@@ -939,8 +1028,10 @@ declare class VideoAudioPeaksCache {
939
1028
  * formulas, so the preview, SVG frames and the export agree.
940
1029
  */
941
1030
  /** One slider of a grade: its range, default and step, for schemas, inspectors and clamping. */
1031
+ /** The numeric settings of a grade (everything but its LUT). */
1032
+ type VideoGradeSetting = Exclude<keyof VideoGrade, 'lut'>;
942
1033
  interface VideoGradeControl {
943
- key: keyof VideoGrade;
1034
+ key: VideoGradeSetting;
944
1035
  label: string;
945
1036
  min: number;
946
1037
  max: number;
@@ -984,10 +1075,14 @@ declare const VIDEO_GRADE_PRESETS: {
984
1075
  };
985
1076
  type VideoGradePreset = keyof typeof VIDEO_GRADE_PRESETS;
986
1077
  declare const VIDEO_GRADE_PRESET_NAMES: VideoGradePreset[];
1078
+ /** A LUT setting with its strength clamped to 0–1 (and 1 left out); `undefined` without a `src` or at strength 0. */
1079
+ declare function normalizeVideoGradeLut(lut: VideoGradeLut | undefined): VideoGradeLut | undefined;
987
1080
  /** A grade with every value clamped to its range and zero values left out; `undefined` when nothing is left. */
988
1081
  declare function normalizeVideoGrade(grade: VideoGrade | undefined): VideoGrade | undefined;
989
1082
  /** A preset at `amount` (0–1, default 1) of its strength. */
990
1083
  declare function videoGradePreset(name: VideoGradePreset, amount?: number): VideoGrade | undefined;
1084
+ /** A preset look on a grade, keeping the grade's LUT (a look replaces only the settings). */
1085
+ declare function videoGradeLook(current: VideoGrade | undefined, name: VideoGradePreset, amount?: number): VideoGrade | undefined;
991
1086
  /** One step of a grade. */
992
1087
  type VideoGradeStep = {
993
1088
  kind: 'brightness';
@@ -1014,12 +1109,23 @@ declare function videoGradeSteps(grade: VideoGrade | undefined): VideoGradeStep[
1014
1109
  * Filter Effects spec gives for `saturate` and `hue-rotate`.
1015
1110
  */
1016
1111
  declare function videoGradeStepMatrix(step: VideoGradeStep): number[][];
1017
- /** An RGB colour (0–255 each) through a grade, as the preview and export draw it. */
1018
- declare function applyVideoGrade(grade: VideoGrade | undefined, rgb: readonly [number, number, number]): [number, number, number];
1112
+ /**
1113
+ * An RGB colour (0–255 each) through a grade, as the preview and export draw it. A grade's LUT is
1114
+ * applied when its table is passed as `lut` (else it is left out).
1115
+ */
1116
+ declare function applyVideoGrade(grade: VideoGrade | undefined, rgb: readonly [number, number, number], lut?: VideoLut | null): [number, number, number];
1019
1117
  /** The `values` of an SVG `feColorMatrix type="matrix"` for a step. */
1020
1118
  declare function videoGradeStepSvgValues(step: VideoGradeStep): string;
1021
- /** An SVG `<filter>` applying a grade, steps in order (each clamps, as CSS filters do). */
1022
- declare function videoGradeSvgFilter(id: string, grade: VideoGrade | undefined): string;
1119
+ /**
1120
+ * SVG filter primitives approximating a LUT (see `videoLutSvgApproximation`) on the result of the
1121
+ * primitives before them, mixed with it by `strength`.
1122
+ */
1123
+ declare function videoLutSvgPrimitives(lut: VideoLut, strength?: number): string;
1124
+ /**
1125
+ * An SVG `<filter>` applying a grade, steps in order (each clamps, as CSS filters do). With the
1126
+ * grade's LUT table (`lut`), an approximation of it follows (SVG has no 3D tables).
1127
+ */
1128
+ declare function videoGradeSvgFilter(id: string, grade: VideoGrade | undefined, lut?: VideoLut | null): string;
1023
1129
  /** Id of the SVG filter for a white-balance step: the same gains always get the same id. */
1024
1130
  declare const videoGradeGainsFilterId: (step: Extract<VideoGradeStep, {
1025
1131
  kind: "gains";
@@ -1424,6 +1530,8 @@ interface VideoSvgOptions {
1424
1530
  imageFor?: (layer: VideoLayer, frame: VideoFrame) => string | null;
1425
1531
  /** Frame rate for the timecode on placeholders (default 30). */
1426
1532
  fps?: number;
1533
+ /** The loaded table of a grade's LUT `src`; drawn as an approximation (curves and a matrix). Without it LUTs are left out. */
1534
+ lutFor?: (src: string) => VideoLut | null | undefined;
1427
1535
  }
1428
1536
  /** A frame as standalone SVG: images and posters as `<image>`, video without one as a labelled box. */
1429
1537
  declare function videoFrameToSvg(frame: VideoFrame, options?: VideoSvgOptions, assets?: VideoProject['assets']): string;
@@ -1447,16 +1555,29 @@ type VideoCanvasContext = Pick<CanvasRenderingContext2D, 'save' | 'restore' | 'f
1447
1555
  lineWidth: number;
1448
1556
  strokeRect(x: number, y: number, w: number, h: number): void;
1449
1557
  };
1558
+ /** An offscreen canvas `drawVideoFrame` draws a LUT-graded layer on before running its pixels through the LUT. */
1559
+ interface VideoScratchCanvas {
1560
+ canvas: CanvasImageSource;
1561
+ ctx: VideoCanvasContext & Pick<CanvasRenderingContext2D, 'getImageData' | 'putImageData' | 'clearRect'>;
1562
+ }
1563
+ interface VideoDrawOptions {
1564
+ /** Puts an SVG filter (white balance) in the page, so the canvas's `filter: url(#id)` finds it. */
1565
+ defineSvgFilter?: (id: string, markup: string) => void;
1566
+ /** The loaded table of a grade's LUT `src`, or nothing while it loads (the layer is drawn without it). */
1567
+ 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;
1570
+ }
1450
1571
  /**
1451
1572
  * Draws a frame on a 2D canvas scaled by `scale` (canvas pixels per frame pixel). `sourceFor`
1452
1573
  * returns what to draw for a media layer (a `<video>` seeked to `layer.sourceTime`, an `<img>`,
1453
1574
  * an `ImageBitmap`…) or `null` for a placeholder box. Grades become the context's `filter`; white
1454
1575
  * balance there refers to an SVG filter, which `options.defineSvgFilter` is given to put in the page
1455
- * (without it, white balance is left out of the canvas).
1576
+ * (without it, white balance is left out of the canvas). A grade's LUT needs `options.lutFor` and
1577
+ * `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.
1456
1579
  */
1457
- declare function drawVideoFrame(ctx: VideoCanvasContext, frame: VideoFrame, sourceFor: (layer: VideoLayer) => CanvasImageSource | null, scale?: number, options?: {
1458
- defineSvgFilter?: (id: string, markup: string) => void;
1459
- }): void;
1580
+ declare function drawVideoFrame(ctx: VideoCanvasContext, frame: VideoFrame, sourceFor: (layer: VideoLayer) => CanvasImageSource | null, scale?: number, options?: VideoDrawOptions): void;
1460
1581
 
1461
1582
  interface VideoEdlOptions {
1462
1583
  /** Track to export (default: the bottom video track, V1 in most NLEs). */
@@ -1480,6 +1601,8 @@ interface VideoFfmpegOptions {
1480
1601
  output?: string;
1481
1602
  /** The path or URL ffmpeg should open for an asset (default its `src`). */
1482
1603
  resolve?: (asset: VideoAsset) => string;
1604
+ /** The path ffmpeg's `lut3d` should read for a grade's LUT `src` (default the `src`; it must be a local file). */
1605
+ resolveLut?: (src: string) => string;
1483
1606
  /** Default `libx264`. */
1484
1607
  videoCodec?: string;
1485
1608
  /** Default `aac`. */
@@ -1573,6 +1696,8 @@ interface VideoPreviewSource {
1573
1696
  subscribe(listener: () => void): () => void;
1574
1697
  /** Where to publish the drawn pixels (a controller has one), for scopes and agents. */
1575
1698
  previewPixels?: VideoPreviewPixels;
1699
+ /** Where grades' LUTs load from (a controller has one). */
1700
+ luts?: VideoLutCache;
1576
1701
  }
1577
1702
  /** The parts of a media element the preview drives (so tests can pass fakes). */
1578
1703
  interface VideoPreviewMedia {
@@ -1620,6 +1745,13 @@ interface VideoPreviewOptions {
1620
1745
  * tool (default: the source's `previewPixels`). `null` publishes nothing.
1621
1746
  */
1622
1747
  pixels?: VideoPreviewPixels | null;
1748
+ /** Where grades' LUTs load from (default: the source's `luts`). Without one, LUTs are left out. */
1749
+ luts?: VideoLutCache | null;
1750
+ /**
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.
1753
+ */
1754
+ createScratch?: (width: number, height: number) => VideoScratchCanvas | null;
1623
1755
  }
1624
1756
  /**
1625
1757
  * Plays a project in the browser: keeps one `<video>` or `<audio>` element per playing clip in step
@@ -1643,6 +1775,9 @@ declare class VideoPreviewEngine {
1643
1775
  private readonly pixelsTarget;
1644
1776
  private drawn;
1645
1777
  private complete;
1778
+ private readonly lutCache;
1779
+ private readonly unsubscribeLuts;
1780
+ private scratchCanvas;
1646
1781
  constructor(source: VideoPreviewSource, canvas: {
1647
1782
  width: number;
1648
1783
  height: number;
@@ -1660,6 +1795,9 @@ declare class VideoPreviewEngine {
1660
1795
  private redraw;
1661
1796
  private sourceFor;
1662
1797
  private draw;
1798
+ /** A grade's LUT once loaded; while it loads (or if it fails) the frame is drawn without it and counts as incomplete. */
1799
+ private readonly lutFor;
1800
+ private readonly scratch;
1663
1801
  private readonly defineSvgFilter;
1664
1802
  /** Stops following the editor and releases every media element. */
1665
1803
  destroy(): void;
@@ -1680,6 +1818,8 @@ interface VideoEditorOptions {
1680
1818
  * loader for one (default: fetch and decode each asset's `src` with Web Audio, in a browser).
1681
1819
  */
1682
1820
  audioPeaks?: VideoAudioPeaksCache | VideoAudioPeaksLoader;
1821
+ /** Where grades' LUT files (`.cube`) come from: a shared cache, or a loader (default: `fetch` each `src`). */
1822
+ luts?: VideoLutCache | VideoLutLoader;
1683
1823
  }
1684
1824
  /** A snapshot of the editor. The same object is returned until something changes. */
1685
1825
  interface VideoEditorState {
@@ -1721,6 +1861,8 @@ declare class VideoEditorController {
1721
1861
  readonly audioPeaks: VideoAudioPeaksCache;
1722
1862
  /** The pixels the preview last drew, for scopes and `get_video_scopes` (a `VideoPreviewEngine` fills it). */
1723
1863
  readonly previewPixels: VideoPreviewPixels;
1864
+ /** Grades' LUTs, loaded on demand for the preview, SVG frames and agents. */
1865
+ readonly luts: VideoLutCache;
1724
1866
  private project;
1725
1867
  private issues;
1726
1868
  private selection;
@@ -2082,5 +2224,10 @@ declare function videoKeyframeValueEdit(project: VideoProject, clipId: string, p
2082
2224
  * the plain value into keys), or removes the key there (the last one leaves its value plain).
2083
2225
  */
2084
2226
  declare function videoKeyframeToggleEdit(project: VideoProject, clipId: string, property: VideoKeyframeProperty, time: number): VideoEdit | null;
2227
+ /**
2228
+ * Edits giving clips a grade LUT (keeping their other grade settings), or taking it off with
2229
+ * `null`. Clips without a grade change are left out; one `controller.apply` makes it one undo step.
2230
+ */
2231
+ declare function videoLutEdits(project: VideoProject, clips: readonly string[], lut: VideoGradeLut | null): VideoEdit[];
2085
2232
 
2086
- 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_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 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 VideoGradePreset, 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 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 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, buildVideoAudioPeaks, checkVideoProject, checkVideoTimeRemap, createVideoEditorToolProvider, createVideoProject, decodeVideoAudioPeaks, describeVideoProject, drawVideoFrame, ffmpegFilterValue, findVideoAudioSilences, findVideoClip, findVideoFillers, findVideoGaps, findVideoTranscriptPauses, findVideoTranscriptText, formatVideoSeconds, formatVideoTimecode, formatVideoTimecodeFrames, isVideoDropFrameRate, isVideoKeyframes, mergeVideoRanges, nextFreeVideoSlot, normalizeVideoGrade, normalizeVideoWord, parseVideoAnimatable, parseVideoAsset, parseVideoClip, parseVideoClipAnimation, parseVideoGrade, 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, videoGradePreset, videoGradeStepMatrix, videoGradeStepSvgValues, videoGradeSteps, videoGradeSvgDefs, videoGradeSvgFilter, videoHistogram, videoHistogramImage, videoHourFrames, videoIrisRadius, videoIssueKey, videoKeyframeBreakpoints, videoKeyframeFfmpegExpr, videoKeyframeRows, videoKeyframeToggleEdit, videoKeyframeValueEdit, videoKeysOf, videoLuma, videoLumaWaveform, 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 };
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 };
@@ -191,9 +191,18 @@ declare const videoTransitionAudioCurve: (t: VideoTransition) => VideoFadeCurve;
191
191
  */
192
192
  type VideoBlendMode = 'normal' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' | 'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' | 'difference' | 'exclusion' | 'add';
193
193
  declare const VIDEO_BLEND_MODES: readonly ["normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light", "difference", "exclusion", "add"];
194
+ /** A 3D LUT a grade applies after its other steps (see `VideoGrade.lut`). */
195
+ interface VideoGradeLut {
196
+ /** A `.cube` file: whatever the host can load (URL, path) and the exporter can open. */
197
+ src: string;
198
+ /** How much of the LUT's change to apply, 0–1 (default 1). */
199
+ strength?: number;
200
+ /** A label for the look (default the file's TITLE or name). */
201
+ name?: string;
202
+ }
194
203
  /**
195
204
  * Colour correction for a clip's picture (see `VIDEO_GRADE_CONTROLS` for ranges). Applied in a fixed
196
- * order: exposure, contrast, saturation, hue, then white balance (temperature and tint).
205
+ * order: exposure, contrast, saturation, hue, white balance (temperature and tint), then the LUT.
197
206
  */
198
207
  interface VideoGrade {
199
208
  /** Stops: +1 doubles every channel (default 0). */
@@ -208,6 +217,8 @@ interface VideoGrade {
208
217
  temperature?: number;
209
218
  /** -1 (green) to 1 (magenta); default 0. */
210
219
  tint?: number;
220
+ /** A 3D LUT (a `.cube` file) applied last, mixed in at its `strength`. */
221
+ lut?: VideoGradeLut;
211
222
  }
212
223
  /**
213
224
  * How a clip enters or leaves: `fade`; `rise` (up into place) or `drop` (down into place);
@@ -354,6 +365,7 @@ declare function parseVideoTransform(v: unknown, path: string): VideoTransform |
354
365
  declare function parseVideoTimeRemap(v: unknown, speed: unknown, path: string): VideoKeyframes | undefined;
355
366
  declare function parseVideoClipAnimation(v: unknown, path: string): VideoClipAnimation | undefined;
356
367
  declare function parseVideoGrade(v: unknown, path: string): VideoGrade | undefined;
368
+ declare function parseVideoGradeLut(v: unknown, path: string): VideoGradeLut | undefined;
357
369
  declare function parseVideoTransition(v: unknown, path: string): VideoTransition | undefined;
358
370
  declare function parseVideoTranscriptWords(v: unknown, path: string): VideoTranscriptWord[] | undefined;
359
371
  declare function parseVideoAsset(v: unknown, path?: string): VideoAsset;
@@ -931,6 +943,83 @@ declare class VideoAudioPeaksCache {
931
943
  private emit;
932
944
  }
933
945
 
946
+ /**
947
+ * 3D LUTs for grades: `.cube` files read into a lattice and applied with tetrahedral
948
+ * interpolation, as ffmpeg's `lut3d=interp=tetrahedral` and grading apps apply them, so the
949
+ * preview and the export agree. A grade's LUT (`VideoGrade.lut`) runs after its other steps and is
950
+ * mixed with the picture before it by `strength`.
951
+ */
952
+ /** A 3D LUT: `size`³ output colours, red changing fastest, then green, then blue (the `.cube` order). */
953
+ interface VideoLut {
954
+ title?: string;
955
+ size: number;
956
+ /** Input values mapped to the first and last lattice points, per channel (default 0 and 1). */
957
+ domainMin: [number, number, number];
958
+ domainMax: [number, number, number];
959
+ /** `size³ × 3` output values. */
960
+ data: Float32Array;
961
+ }
962
+ /** Largest `LUT_3D_SIZE` read (129³ rows is about 2 million). */
963
+ declare const VIDEO_LUT_MAX_SIZE = 129;
964
+ /** Reads a `.cube` file's 3D table. Errors give the line and what is wrong. */
965
+ declare function parseVideoCubeLut(text: string): VideoLut;
966
+ /** A LUT of `size` points a side built from a colour function (each channel 0–1 in and out). */
967
+ declare function videoLutFromFunction(size: number, fn: (rgb: [number, number, number]) => readonly [number, number, number], title?: string): VideoLut;
968
+ /** A LUT as `.cube` text. */
969
+ declare function videoLutToCube(lut: VideoLut): string;
970
+ /**
971
+ * A colour (each channel 0–1) through a LUT with tetrahedral interpolation: the lattice cube
972
+ * around the colour is split into six tetrahedra along its grey diagonal, and the colour is mixed
973
+ * from the four corners of the one it falls in. Greys stay on the diagonal, unlike trilinear.
974
+ */
975
+ declare function applyVideoLut(lut: VideoLut, rgb: readonly [number, number, number], out?: [number, number, number]): [number, number, number];
976
+ /** Runs RGBA pixels (0–255, as `ImageData` has them) through a LUT in place, mixed with the originals by `strength` (0–1). Transparent pixels are left alone. */
977
+ declare function applyVideoLutToPixels(lut: VideoLut, data: {
978
+ length: number;
979
+ [i: number]: number;
980
+ }, strength?: number): void;
981
+ /**
982
+ * An SVG approximation of a LUT for SVG frames, which have no 3D tables: per-channel curves taken
983
+ * along the LUT's grey axis (`feComponentTransfer` tables), then the colour matrix that best fits
984
+ * the rest (least squares over the lattice). Exact for LUTs that are curves or a matrix; close for
985
+ * most looks. The preview and the export apply the LUT itself.
986
+ */
987
+ interface VideoLutSvgApproximation {
988
+ /** Per-channel curve tables (`tableValues`), each 0–1. */
989
+ tables: [number[], number[], number[]];
990
+ /** A 3 × 4 matrix (rows r, g, b; columns r, g, b, offset) applied after the curves. */
991
+ matrix: number[][];
992
+ }
993
+ declare function videoLutSvgApproximation(lut: VideoLut): VideoLutSvgApproximation;
994
+ /** Where LUT files come from: their text for a `src` (default: `fetch`). */
995
+ type VideoLutLoader = (src: string) => Promise<string | VideoLut>;
996
+ /**
997
+ * Loaded LUTs by `src`, read once and shared by the preview, SVG frames and agent tools
998
+ * (`VideoEditorController.luts`). Listeners hear when one loads or fails.
999
+ */
1000
+ declare class VideoLutCache {
1001
+ private readonly loader;
1002
+ private readonly ready;
1003
+ private readonly pending;
1004
+ private readonly failed;
1005
+ private readonly listeners;
1006
+ constructor(loader?: VideoLutLoader);
1007
+ /** The LUT if loaded, without starting to load it. */
1008
+ peek(src: string): VideoLut | undefined;
1009
+ /** The LUT if loaded; otherwise `undefined`, and loading starts (once) unless it failed. */
1010
+ get(src: string): VideoLut | undefined;
1011
+ /** Why loading a LUT failed, if it did. */
1012
+ error(src: string): string | undefined;
1013
+ /** The LUT, loading and reading it if needed. Rejects with a readable error. */
1014
+ load(src: string): Promise<VideoLut>;
1015
+ /** Uses a LUT the host already has (`.cube` text or a parsed LUT), under `src`. */
1016
+ set(src: string, lut: VideoLut | string): VideoLut;
1017
+ /** Forgets a failure so the next `get` tries again. */
1018
+ retry(src: string): void;
1019
+ subscribe(fn: () => void): () => void;
1020
+ private emit;
1021
+ }
1022
+
934
1023
  /**
935
1024
  * Colour correction as a fixed series of colour-matrix steps on gamma-encoded sRGB, each clamped
936
1025
  * to 0–1, in the same order everywhere: exposure, contrast, saturation, hue, then white balance.
@@ -939,8 +1028,10 @@ declare class VideoAudioPeaksCache {
939
1028
  * formulas, so the preview, SVG frames and the export agree.
940
1029
  */
941
1030
  /** One slider of a grade: its range, default and step, for schemas, inspectors and clamping. */
1031
+ /** The numeric settings of a grade (everything but its LUT). */
1032
+ type VideoGradeSetting = Exclude<keyof VideoGrade, 'lut'>;
942
1033
  interface VideoGradeControl {
943
- key: keyof VideoGrade;
1034
+ key: VideoGradeSetting;
944
1035
  label: string;
945
1036
  min: number;
946
1037
  max: number;
@@ -984,10 +1075,14 @@ declare const VIDEO_GRADE_PRESETS: {
984
1075
  };
985
1076
  type VideoGradePreset = keyof typeof VIDEO_GRADE_PRESETS;
986
1077
  declare const VIDEO_GRADE_PRESET_NAMES: VideoGradePreset[];
1078
+ /** A LUT setting with its strength clamped to 0–1 (and 1 left out); `undefined` without a `src` or at strength 0. */
1079
+ declare function normalizeVideoGradeLut(lut: VideoGradeLut | undefined): VideoGradeLut | undefined;
987
1080
  /** A grade with every value clamped to its range and zero values left out; `undefined` when nothing is left. */
988
1081
  declare function normalizeVideoGrade(grade: VideoGrade | undefined): VideoGrade | undefined;
989
1082
  /** A preset at `amount` (0–1, default 1) of its strength. */
990
1083
  declare function videoGradePreset(name: VideoGradePreset, amount?: number): VideoGrade | undefined;
1084
+ /** A preset look on a grade, keeping the grade's LUT (a look replaces only the settings). */
1085
+ declare function videoGradeLook(current: VideoGrade | undefined, name: VideoGradePreset, amount?: number): VideoGrade | undefined;
991
1086
  /** One step of a grade. */
992
1087
  type VideoGradeStep = {
993
1088
  kind: 'brightness';
@@ -1014,12 +1109,23 @@ declare function videoGradeSteps(grade: VideoGrade | undefined): VideoGradeStep[
1014
1109
  * Filter Effects spec gives for `saturate` and `hue-rotate`.
1015
1110
  */
1016
1111
  declare function videoGradeStepMatrix(step: VideoGradeStep): number[][];
1017
- /** An RGB colour (0–255 each) through a grade, as the preview and export draw it. */
1018
- declare function applyVideoGrade(grade: VideoGrade | undefined, rgb: readonly [number, number, number]): [number, number, number];
1112
+ /**
1113
+ * An RGB colour (0–255 each) through a grade, as the preview and export draw it. A grade's LUT is
1114
+ * applied when its table is passed as `lut` (else it is left out).
1115
+ */
1116
+ declare function applyVideoGrade(grade: VideoGrade | undefined, rgb: readonly [number, number, number], lut?: VideoLut | null): [number, number, number];
1019
1117
  /** The `values` of an SVG `feColorMatrix type="matrix"` for a step. */
1020
1118
  declare function videoGradeStepSvgValues(step: VideoGradeStep): string;
1021
- /** An SVG `<filter>` applying a grade, steps in order (each clamps, as CSS filters do). */
1022
- declare function videoGradeSvgFilter(id: string, grade: VideoGrade | undefined): string;
1119
+ /**
1120
+ * SVG filter primitives approximating a LUT (see `videoLutSvgApproximation`) on the result of the
1121
+ * primitives before them, mixed with it by `strength`.
1122
+ */
1123
+ declare function videoLutSvgPrimitives(lut: VideoLut, strength?: number): string;
1124
+ /**
1125
+ * An SVG `<filter>` applying a grade, steps in order (each clamps, as CSS filters do). With the
1126
+ * grade's LUT table (`lut`), an approximation of it follows (SVG has no 3D tables).
1127
+ */
1128
+ declare function videoGradeSvgFilter(id: string, grade: VideoGrade | undefined, lut?: VideoLut | null): string;
1023
1129
  /** Id of the SVG filter for a white-balance step: the same gains always get the same id. */
1024
1130
  declare const videoGradeGainsFilterId: (step: Extract<VideoGradeStep, {
1025
1131
  kind: "gains";
@@ -1424,6 +1530,8 @@ interface VideoSvgOptions {
1424
1530
  imageFor?: (layer: VideoLayer, frame: VideoFrame) => string | null;
1425
1531
  /** Frame rate for the timecode on placeholders (default 30). */
1426
1532
  fps?: number;
1533
+ /** The loaded table of a grade's LUT `src`; drawn as an approximation (curves and a matrix). Without it LUTs are left out. */
1534
+ lutFor?: (src: string) => VideoLut | null | undefined;
1427
1535
  }
1428
1536
  /** A frame as standalone SVG: images and posters as `<image>`, video without one as a labelled box. */
1429
1537
  declare function videoFrameToSvg(frame: VideoFrame, options?: VideoSvgOptions, assets?: VideoProject['assets']): string;
@@ -1447,16 +1555,29 @@ type VideoCanvasContext = Pick<CanvasRenderingContext2D, 'save' | 'restore' | 'f
1447
1555
  lineWidth: number;
1448
1556
  strokeRect(x: number, y: number, w: number, h: number): void;
1449
1557
  };
1558
+ /** An offscreen canvas `drawVideoFrame` draws a LUT-graded layer on before running its pixels through the LUT. */
1559
+ interface VideoScratchCanvas {
1560
+ canvas: CanvasImageSource;
1561
+ ctx: VideoCanvasContext & Pick<CanvasRenderingContext2D, 'getImageData' | 'putImageData' | 'clearRect'>;
1562
+ }
1563
+ interface VideoDrawOptions {
1564
+ /** Puts an SVG filter (white balance) in the page, so the canvas's `filter: url(#id)` finds it. */
1565
+ defineSvgFilter?: (id: string, markup: string) => void;
1566
+ /** The loaded table of a grade's LUT `src`, or nothing while it loads (the layer is drawn without it). */
1567
+ 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;
1570
+ }
1450
1571
  /**
1451
1572
  * Draws a frame on a 2D canvas scaled by `scale` (canvas pixels per frame pixel). `sourceFor`
1452
1573
  * returns what to draw for a media layer (a `<video>` seeked to `layer.sourceTime`, an `<img>`,
1453
1574
  * an `ImageBitmap`…) or `null` for a placeholder box. Grades become the context's `filter`; white
1454
1575
  * balance there refers to an SVG filter, which `options.defineSvgFilter` is given to put in the page
1455
- * (without it, white balance is left out of the canvas).
1576
+ * (without it, white balance is left out of the canvas). A grade's LUT needs `options.lutFor` and
1577
+ * `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.
1456
1579
  */
1457
- declare function drawVideoFrame(ctx: VideoCanvasContext, frame: VideoFrame, sourceFor: (layer: VideoLayer) => CanvasImageSource | null, scale?: number, options?: {
1458
- defineSvgFilter?: (id: string, markup: string) => void;
1459
- }): void;
1580
+ declare function drawVideoFrame(ctx: VideoCanvasContext, frame: VideoFrame, sourceFor: (layer: VideoLayer) => CanvasImageSource | null, scale?: number, options?: VideoDrawOptions): void;
1460
1581
 
1461
1582
  interface VideoEdlOptions {
1462
1583
  /** Track to export (default: the bottom video track, V1 in most NLEs). */
@@ -1480,6 +1601,8 @@ interface VideoFfmpegOptions {
1480
1601
  output?: string;
1481
1602
  /** The path or URL ffmpeg should open for an asset (default its `src`). */
1482
1603
  resolve?: (asset: VideoAsset) => string;
1604
+ /** The path ffmpeg's `lut3d` should read for a grade's LUT `src` (default the `src`; it must be a local file). */
1605
+ resolveLut?: (src: string) => string;
1483
1606
  /** Default `libx264`. */
1484
1607
  videoCodec?: string;
1485
1608
  /** Default `aac`. */
@@ -1573,6 +1696,8 @@ interface VideoPreviewSource {
1573
1696
  subscribe(listener: () => void): () => void;
1574
1697
  /** Where to publish the drawn pixels (a controller has one), for scopes and agents. */
1575
1698
  previewPixels?: VideoPreviewPixels;
1699
+ /** Where grades' LUTs load from (a controller has one). */
1700
+ luts?: VideoLutCache;
1576
1701
  }
1577
1702
  /** The parts of a media element the preview drives (so tests can pass fakes). */
1578
1703
  interface VideoPreviewMedia {
@@ -1620,6 +1745,13 @@ interface VideoPreviewOptions {
1620
1745
  * tool (default: the source's `previewPixels`). `null` publishes nothing.
1621
1746
  */
1622
1747
  pixels?: VideoPreviewPixels | null;
1748
+ /** Where grades' LUTs load from (default: the source's `luts`). Without one, LUTs are left out. */
1749
+ luts?: VideoLutCache | null;
1750
+ /**
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.
1753
+ */
1754
+ createScratch?: (width: number, height: number) => VideoScratchCanvas | null;
1623
1755
  }
1624
1756
  /**
1625
1757
  * Plays a project in the browser: keeps one `<video>` or `<audio>` element per playing clip in step
@@ -1643,6 +1775,9 @@ declare class VideoPreviewEngine {
1643
1775
  private readonly pixelsTarget;
1644
1776
  private drawn;
1645
1777
  private complete;
1778
+ private readonly lutCache;
1779
+ private readonly unsubscribeLuts;
1780
+ private scratchCanvas;
1646
1781
  constructor(source: VideoPreviewSource, canvas: {
1647
1782
  width: number;
1648
1783
  height: number;
@@ -1660,6 +1795,9 @@ declare class VideoPreviewEngine {
1660
1795
  private redraw;
1661
1796
  private sourceFor;
1662
1797
  private draw;
1798
+ /** A grade's LUT once loaded; while it loads (or if it fails) the frame is drawn without it and counts as incomplete. */
1799
+ private readonly lutFor;
1800
+ private readonly scratch;
1663
1801
  private readonly defineSvgFilter;
1664
1802
  /** Stops following the editor and releases every media element. */
1665
1803
  destroy(): void;
@@ -1680,6 +1818,8 @@ interface VideoEditorOptions {
1680
1818
  * loader for one (default: fetch and decode each asset's `src` with Web Audio, in a browser).
1681
1819
  */
1682
1820
  audioPeaks?: VideoAudioPeaksCache | VideoAudioPeaksLoader;
1821
+ /** Where grades' LUT files (`.cube`) come from: a shared cache, or a loader (default: `fetch` each `src`). */
1822
+ luts?: VideoLutCache | VideoLutLoader;
1683
1823
  }
1684
1824
  /** A snapshot of the editor. The same object is returned until something changes. */
1685
1825
  interface VideoEditorState {
@@ -1721,6 +1861,8 @@ declare class VideoEditorController {
1721
1861
  readonly audioPeaks: VideoAudioPeaksCache;
1722
1862
  /** The pixels the preview last drew, for scopes and `get_video_scopes` (a `VideoPreviewEngine` fills it). */
1723
1863
  readonly previewPixels: VideoPreviewPixels;
1864
+ /** Grades' LUTs, loaded on demand for the preview, SVG frames and agents. */
1865
+ readonly luts: VideoLutCache;
1724
1866
  private project;
1725
1867
  private issues;
1726
1868
  private selection;
@@ -2082,5 +2224,10 @@ declare function videoKeyframeValueEdit(project: VideoProject, clipId: string, p
2082
2224
  * the plain value into keys), or removes the key there (the last one leaves its value plain).
2083
2225
  */
2084
2226
  declare function videoKeyframeToggleEdit(project: VideoProject, clipId: string, property: VideoKeyframeProperty, time: number): VideoEdit | null;
2227
+ /**
2228
+ * Edits giving clips a grade LUT (keeping their other grade settings), or taking it off with
2229
+ * `null`. Clips without a grade change are left out; one `controller.apply` makes it one undo step.
2230
+ */
2231
+ declare function videoLutEdits(project: VideoProject, clips: readonly string[], lut: VideoGradeLut | null): VideoEdit[];
2085
2232
 
2086
- 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_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 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 VideoGradePreset, 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 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 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, buildVideoAudioPeaks, checkVideoProject, checkVideoTimeRemap, createVideoEditorToolProvider, createVideoProject, decodeVideoAudioPeaks, describeVideoProject, drawVideoFrame, ffmpegFilterValue, findVideoAudioSilences, findVideoClip, findVideoFillers, findVideoGaps, findVideoTranscriptPauses, findVideoTranscriptText, formatVideoSeconds, formatVideoTimecode, formatVideoTimecodeFrames, isVideoDropFrameRate, isVideoKeyframes, mergeVideoRanges, nextFreeVideoSlot, normalizeVideoGrade, normalizeVideoWord, parseVideoAnimatable, parseVideoAsset, parseVideoClip, parseVideoClipAnimation, parseVideoGrade, 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, videoGradePreset, videoGradeStepMatrix, videoGradeStepSvgValues, videoGradeSteps, videoGradeSvgDefs, videoGradeSvgFilter, videoHistogram, videoHistogramImage, videoHourFrames, videoIrisRadius, videoIssueKey, videoKeyframeBreakpoints, videoKeyframeFfmpegExpr, videoKeyframeRows, videoKeyframeToggleEdit, videoKeyframeValueEdit, videoKeysOf, videoLuma, videoLumaWaveform, 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 };
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 };