versioncam 0.1.3 → 0.3.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 (99) hide show
  1. package/CHANGELOG.md +174 -0
  2. package/README.md +152 -15
  3. package/dist/cli/commands/check.js +45 -4
  4. package/dist/cli/commands/check.js.map +1 -1
  5. package/dist/cli/commands/doctor.js +39 -2
  6. package/dist/cli/commands/doctor.js.map +1 -1
  7. package/dist/cli/commands/init.js +25 -0
  8. package/dist/cli/commands/init.js.map +1 -1
  9. package/dist/cli/commands/preview.js +10 -1
  10. package/dist/cli/commands/preview.js.map +1 -1
  11. package/dist/cli/commands/publish.d.ts +17 -0
  12. package/dist/cli/commands/publish.js +203 -0
  13. package/dist/cli/commands/publish.js.map +1 -0
  14. package/dist/cli/commands/record.js +2 -0
  15. package/dist/cli/commands/record.js.map +1 -1
  16. package/dist/cli/commands/render.d.ts +17 -0
  17. package/dist/cli/commands/render.js +98 -21
  18. package/dist/cli/commands/render.js.map +1 -1
  19. package/dist/cli/cwd.d.ts +46 -0
  20. package/dist/cli/cwd.js +102 -0
  21. package/dist/cli/cwd.js.map +1 -0
  22. package/dist/cli/main.js +19 -2
  23. package/dist/cli/main.js.map +1 -1
  24. package/dist/cli/usage.d.ts +3 -2
  25. package/dist/cli/usage.js +17 -4
  26. package/dist/cli/usage.js.map +1 -1
  27. package/dist/config.d.ts +35 -1
  28. package/dist/config.js +44 -0
  29. package/dist/config.js.map +1 -1
  30. package/dist/core/camera-track.d.ts +63 -0
  31. package/dist/core/camera-track.js +230 -0
  32. package/dist/core/camera-track.js.map +1 -0
  33. package/dist/core/camera.d.ts +14 -1
  34. package/dist/core/camera.js +18 -2
  35. package/dist/core/camera.js.map +1 -1
  36. package/dist/core/follow.d.ts +129 -0
  37. package/dist/core/follow.js +151 -0
  38. package/dist/core/follow.js.map +1 -0
  39. package/dist/core/motion-defaults.d.ts +29 -0
  40. package/dist/core/motion-defaults.js +29 -0
  41. package/dist/core/motion-defaults.js.map +1 -1
  42. package/dist/core/timeline.d.ts +10 -2
  43. package/dist/core/timeline.js.map +1 -1
  44. package/dist/driver/clip.d.ts +6 -0
  45. package/dist/driver/clip.js +6 -3
  46. package/dist/driver/clip.js.map +1 -1
  47. package/dist/driver/reports.d.ts +34 -2
  48. package/dist/driver/reports.js +31 -3
  49. package/dist/driver/reports.js.map +1 -1
  50. package/dist/driver/session.d.ts +36 -1
  51. package/dist/driver/session.js +72 -14
  52. package/dist/driver/session.js.map +1 -1
  53. package/dist/index.d.ts +11 -3
  54. package/dist/index.js +6 -2
  55. package/dist/index.js.map +1 -1
  56. package/dist/loader.d.ts +7 -1
  57. package/dist/loader.js +23 -8
  58. package/dist/loader.js.map +1 -1
  59. package/dist/page/assets/index-fZtacWyp.js +2 -0
  60. package/dist/page/index.html +1 -1
  61. package/dist/publish/client.d.ts +38 -0
  62. package/dist/publish/client.js +118 -0
  63. package/dist/publish/client.js.map +1 -0
  64. package/dist/publish/index.d.ts +12 -0
  65. package/dist/publish/index.js +11 -0
  66. package/dist/publish/index.js.map +1 -0
  67. package/dist/publish/manifest.d.ts +46 -0
  68. package/dist/publish/manifest.js +133 -0
  69. package/dist/publish/manifest.js.map +1 -0
  70. package/dist/publish/protocol.d.ts +203 -0
  71. package/dist/publish/protocol.js +56 -0
  72. package/dist/publish/protocol.js.map +1 -0
  73. package/dist/render/encode.d.ts +27 -1
  74. package/dist/render/encode.js +115 -37
  75. package/dist/render/encode.js.map +1 -1
  76. package/dist/render/presentation.d.ts +12 -0
  77. package/dist/render/presentation.js +15 -0
  78. package/dist/render/presentation.js.map +1 -1
  79. package/dist/render/render.js +19 -1
  80. package/dist/render/render.js.map +1 -1
  81. package/dist/render/sampling.d.ts +13 -0
  82. package/dist/render/sampling.js +47 -19
  83. package/dist/render/sampling.js.map +1 -1
  84. package/dist/render/scenes.d.ts +16 -0
  85. package/dist/render/scenes.js +108 -0
  86. package/dist/render/scenes.js.map +1 -0
  87. package/dist/render/sequence.d.ts +21 -1
  88. package/dist/render/sequence.js +71 -14
  89. package/dist/render/sequence.js.map +1 -1
  90. package/dist/review/review.js +46 -21
  91. package/dist/review/review.js.map +1 -1
  92. package/dsl.md +37 -0
  93. package/package.json +6 -2
  94. package/plugin/README.md +7 -2
  95. package/plugin/agents/versioncam-reviewer.md +3 -2
  96. package/plugin/skills/versioncam/SKILL.md +60 -14
  97. package/plugin/skills/versioncam/authoring.md +6 -1
  98. package/plugin/skills/versioncam/onboarding.md +17 -17
  99. package/dist/page/assets/index-DUom5amc.js +0 -1
@@ -0,0 +1,46 @@
1
+ /**
2
+ * `--cwd <dir>`: run a command as if from `<dir>`.
3
+ *
4
+ * Every command works in the directory that holds `versioncam.config.ts`:
5
+ * the config, `.env.recording` and `.env`, `.versioncam/`, and any relative
6
+ * path a command is given or prints are that directory's. In a monorepo the
7
+ * app is one directory among many, and whatever runs versioncam may be
8
+ * somewhere else: a script at the repository root, or an agent whose session
9
+ * started inside the app, below its config, and which may not `cd` out of
10
+ * the directory it started in.
11
+ *
12
+ * Its own module so a test can reach it without running the CLI.
13
+ */
14
+ /**
15
+ * `--cwd <dir>` or `--cwd=<dir>`, taken out of the arguments, from anywhere
16
+ * among them. If it is given twice, the last one counts.
17
+ *
18
+ * Anywhere, not only before the command's name, because what an agent may
19
+ * run is a prefix: the reviewer is allowed `npx versioncam frame *` and
20
+ * nothing else, so its flag has to be able to come after `frame`.
21
+ */
22
+ export declare function takeCwd(argv: string[]): {
23
+ cwd: string | undefined;
24
+ rest: string[];
25
+ };
26
+ /**
27
+ * The versioncam a config in `dir` imports: the first `node_modules/versioncam`
28
+ * from `dir` up, which is where Node looks for a bare `import "versioncam"`.
29
+ * Null where there is none.
30
+ *
31
+ * Resolved through symlinks, so an `npm link` or a pnpm store compares as
32
+ * the directory it really is.
33
+ */
34
+ export declare function versioncamFrom(dir: string): string | null;
35
+ /**
36
+ * Move into `dir` for the rest of the command, or say why not.
37
+ *
38
+ * Only the directory moves, though, and not the versioncam running: `npx`
39
+ * finds the binary in the directory it runs in and in those above it, never
40
+ * below. Run from above an app that has versioncam in its own
41
+ * `node_modules`, it runs another copy, or downloads the latest one, and that
42
+ * copy would record with a Chromium the app never pinned, beside a config
43
+ * that imports the app's own. So a directory whose own versioncam is not the
44
+ * one running is refused, with how to run its own.
45
+ */
46
+ export declare function enterCwd(dir: string): void;
@@ -0,0 +1,102 @@
1
+ import { existsSync, readFileSync, realpathSync, statSync } from "node:fs";
2
+ import { dirname, join, relative, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ /**
5
+ * `--cwd <dir>`: run a command as if from `<dir>`.
6
+ *
7
+ * Every command works in the directory that holds `versioncam.config.ts`:
8
+ * the config, `.env.recording` and `.env`, `.versioncam/`, and any relative
9
+ * path a command is given or prints are that directory's. In a monorepo the
10
+ * app is one directory among many, and whatever runs versioncam may be
11
+ * somewhere else: a script at the repository root, or an agent whose session
12
+ * started inside the app, below its config, and which may not `cd` out of
13
+ * the directory it started in.
14
+ *
15
+ * Its own module so a test can reach it without running the CLI.
16
+ */
17
+ /**
18
+ * `--cwd <dir>` or `--cwd=<dir>`, taken out of the arguments, from anywhere
19
+ * among them. If it is given twice, the last one counts.
20
+ *
21
+ * Anywhere, not only before the command's name, because what an agent may
22
+ * run is a prefix: the reviewer is allowed `npx versioncam frame *` and
23
+ * nothing else, so its flag has to be able to come after `frame`.
24
+ */
25
+ export function takeCwd(argv) {
26
+ let cwd;
27
+ const rest = [];
28
+ for (let i = 0; i < argv.length; i++) {
29
+ const arg = argv[i];
30
+ if (arg !== "--cwd" && !arg.startsWith("--cwd=")) {
31
+ rest.push(arg);
32
+ continue;
33
+ }
34
+ const value = arg === "--cwd" ? argv[++i] : arg.slice("--cwd=".length);
35
+ // A flag where the directory should be is a directory left out, not a
36
+ // directory called `--draft`.
37
+ if (!value || value.startsWith("-")) {
38
+ throw new Error("`--cwd` needs a directory: versioncam <command> --cwd <dir>");
39
+ }
40
+ cwd = value;
41
+ }
42
+ return { cwd, rest };
43
+ }
44
+ /**
45
+ * The versioncam a config in `dir` imports: the first `node_modules/versioncam`
46
+ * from `dir` up, which is where Node looks for a bare `import "versioncam"`.
47
+ * Null where there is none.
48
+ *
49
+ * Resolved through symlinks, so an `npm link` or a pnpm store compares as
50
+ * the directory it really is.
51
+ */
52
+ export function versioncamFrom(dir) {
53
+ for (let at = resolve(dir);; at = dirname(at)) {
54
+ const candidate = join(at, "node_modules", "versioncam");
55
+ if (existsSync(join(candidate, "package.json"))) {
56
+ return realpathSync(candidate);
57
+ }
58
+ if (dirname(at) === at)
59
+ return null;
60
+ }
61
+ }
62
+ /** This package, where it really is: two levels above this file. */
63
+ const RUNNING = realpathSync(resolve(dirname(fileURLToPath(import.meta.url)), "..", ".."));
64
+ /** "versioncam 0.1.3 in <dir>", without the version if it cannot be read. */
65
+ function nameOf(pkg) {
66
+ try {
67
+ const { version } = JSON.parse(readFileSync(join(pkg, "package.json"), "utf8"));
68
+ if (version)
69
+ return `versioncam ${version} in ${pkg}`;
70
+ }
71
+ catch {
72
+ // Named by its directory alone, which is the part that matters.
73
+ }
74
+ return `versioncam in ${pkg}`;
75
+ }
76
+ /**
77
+ * Move into `dir` for the rest of the command, or say why not.
78
+ *
79
+ * Only the directory moves, though, and not the versioncam running: `npx`
80
+ * finds the binary in the directory it runs in and in those above it, never
81
+ * below. Run from above an app that has versioncam in its own
82
+ * `node_modules`, it runs another copy, or downloads the latest one, and that
83
+ * copy would record with a Chromium the app never pinned, beside a config
84
+ * that imports the app's own. So a directory whose own versioncam is not the
85
+ * one running is refused, with how to run its own.
86
+ */
87
+ export function enterCwd(dir) {
88
+ const target = resolve(dir);
89
+ if (!existsSync(target) || !statSync(target).isDirectory()) {
90
+ throw new Error(`\`--cwd ${dir}\`: there is no directory ${target}.`);
91
+ }
92
+ const theirs = versioncamFrom(target);
93
+ if (theirs !== null && theirs !== RUNNING) {
94
+ const shown = relative(process.cwd(), target) || ".";
95
+ throw new Error(`\`--cwd ${dir}\`: that directory has its own ${nameOf(theirs)}, ` +
96
+ `and this is ${nameOf(RUNNING)}.\n` +
97
+ "npx looks for versioncam in the directory it runs in and in those above it, never below.\n" +
98
+ `Run the directory's own instead: cd ${shown}, then the same command without --cwd.`);
99
+ }
100
+ process.chdir(target);
101
+ }
102
+ //# sourceMappingURL=cwd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cwd.js","sourceRoot":"","sources":["../../src/cli/cwd.ts"],"names":[],"mappings":"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"}
package/dist/cli/main.js CHANGED
@@ -10,16 +10,20 @@ import { install } from "./commands/install.js";
10
10
  import { login } from "./commands/login.js";
11
11
  import { measure } from "./commands/measure.js";
12
12
  import { preview } from "./commands/preview.js";
13
+ import { publish } from "./commands/publish.js";
13
14
  import { record } from "./commands/record.js";
14
15
  import { render } from "./commands/render.js";
15
16
  import { review } from "./commands/review.js";
16
17
  import { sheet } from "./commands/sheet.js";
17
18
  import { stability } from "./commands/stability.js";
18
19
  import { loadEnvFiles } from "../env.js";
20
+ import { enterCwd, takeCwd } from "./cwd.js";
19
21
  import { USAGE } from "./usage.js";
22
+ import { RECORDER_VERSION } from "../driver/clip.js";
20
23
  const COMMANDS = {
21
24
  record,
22
25
  render,
26
+ publish,
23
27
  check,
24
28
  stability,
25
29
  sheet,
@@ -35,13 +39,20 @@ const COMMANDS = {
35
39
  init,
36
40
  };
37
41
  async function main() {
38
- const argv = process.argv.slice(2);
42
+ // `--cwd` comes out first: it takes a value, which the parsing below would
43
+ // otherwise read as the command's name.
44
+ const { cwd, rest: argv } = takeCwd(process.argv.slice(2));
39
45
  // `--help` is a flag, not a positional, so it never reaches `positionals`.
40
46
  // Asking for help is a success; being given nothing is not.
41
47
  if (argv.some((a) => a === "--help" || a === "-h" || a === "help")) {
42
48
  process.stdout.write(USAGE);
43
49
  return 0;
44
50
  }
51
+ // For a script that must know what it is driving before it drives it.
52
+ if (argv.length === 1 && (argv[0] === "--version" || argv[0] === "-v")) {
53
+ process.stdout.write(`${RECORDER_VERSION}\n`);
54
+ return 0;
55
+ }
45
56
  const { positionals } = parseArgs({
46
57
  args: argv,
47
58
  strict: false,
@@ -57,8 +68,14 @@ async function main() {
57
68
  process.stderr.write(`Unknown command "${name}".\n\n${USAGE}`);
58
69
  return 1;
59
70
  }
71
+ // Before the environment files, which are that directory's too.
72
+ if (cwd !== undefined)
73
+ enterCwd(cwd);
60
74
  loadEnvFiles(process.cwd());
61
- return command(process.argv.slice(3));
75
+ // The command's own arguments: everything but its name, wherever the name
76
+ // was, which is first unless a flag came before it.
77
+ const at = argv.indexOf(name);
78
+ return command([...argv.slice(0, at), ...argv.slice(at + 1)]);
62
79
  }
63
80
  main().then((code) => {
64
81
  process.exitCode = code;
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@
9
9
  *
10
10
  * Grouped by the stage of the work each command belongs to, in the order a
11
11
  * repository meets them. A flat list of seventeen commands left a newcomer to
12
- * work out that `inspect` comes before `record` and `sheet` after it.
12
+ * work out that `inspect` comes before `record` and `sheet` after it. The
13
+ * last group is not a stage but a way to run any of them.
13
14
  */
14
- export declare const USAGE = "versioncam: record and render demo clips of a real app\n\nSet up\n versioncam install the Chromium this version of versioncam records with\n --with-deps and its system libraries (Linux CI)\n versioncam init install the authoring skill into .claude/\n --into <dir> into <dir>/versioncam/ instead, for another host\n --force overwrite files that are already there\n versioncam doctor check this machine can record, and that the app starts\n versioncam login sign in once and save the browser session\n\nWrite\n versioncam inspect <path> what a clip can click, and where each name came from\n --json machine-readable\n versioncam measure <path> <sel> where a selector's matches are, and what they say\n versioncam dsl the clip DSL: every method, its options and defaults\n\nRecord\n versioncam record [id\u2026] drive the app and capture frames\n --draft 15fps at CSS scale: cheap, for writing clips\n versioncam check [id\u2026] record every clip; exit 1 if any breaks\n versioncam stability [id\u2026] record each clip twice the same way; stable or not\n --runs <n> how many times (default 2)\n --full at full quality rather than draft\n\nReview\n versioncam sheet <id> an eight-frame contact sheet\n --at-marks sample the beats instead of even spacing\n versioncam frame <id> <n> one frame at output size, to a png\n --t <seconds> pick the frame by time instead\n --at <label> or by the beat it shows\n versioncam review <id> the checks that need no eyes; PASS/FAIL, exit 0/1\n --beats <file> [{ label, expect }] the clip promised\n --min <s> --max <s> duration bounds (default 9 and 11)\n versioncam preview <id> open the scrubber in a real browser\n --scene <id> preview a scene instead\n --frame <n> start at this frame\n\nOutput\n versioncam render [id\u2026] composite and encode what has been recorded\n --scene <id> render a designed scene (repeatable)\n --sequence stitch the results into one piece\n\nRun from a directory containing versioncam.config.ts.\n";
15
+ export declare const USAGE = "versioncam: record and render demo clips of a real app\n\nSet up\n versioncam install the Chromium this version of versioncam records with\n --with-deps and its system libraries (Linux CI)\n versioncam init install the authoring skill into .claude/\n --into <dir> into <dir>/versioncam/ instead, for another host\n --force overwrite files that are already there\n versioncam doctor check this machine can record, and that the app starts\n versioncam login sign in once and save the browser session\n\nWrite\n versioncam inspect <path> what a clip can click, and where each name came from\n --json machine-readable\n versioncam measure <path> <sel> where a selector's matches are, and what they say\n versioncam dsl the clip DSL: every method, its options and defaults\n\nRecord\n versioncam record [id\u2026] drive the app and capture frames\n --draft 15fps at CSS scale: cheap, for writing clips\n versioncam check [id\u2026] record every clip; exit 1 if any breaks\n --report <file> and write each clip's result there, as JSON\n versioncam stability [id\u2026] record each clip twice the same way; stable or not\n --runs <n> how many times (default 2)\n --full at full quality rather than draft\n\nReview\n versioncam sheet <id> an eight-frame contact sheet\n --at-marks sample the beats instead of even spacing\n versioncam frame <id> <n> one frame at output size, to a png\n --t <seconds> pick the frame by time instead\n --at <label> or by the beat it shows\n versioncam review <id> the checks that need no eyes; PASS/FAIL, exit 0/1\n --beats <file> [{ label, expect }] the clip promised\n --min <s> --max <s> duration bounds (default 9 and 11)\n versioncam preview <id> open the scrubber in a real browser\n --scene <id> preview a scene instead\n --frame <n> start at this frame\n\nOutput\n versioncam render [id\u2026] composite and encode recordings and scenes\n no ids: every one, stale recordings included\n --scene <id> and this scene, whatever the ids say (repeatable)\n --sequence stitch the results into one piece\n --report <file> and write what it made there, as JSON\n\nPublish\n versioncam publish [id\u2026] send the recordings and their checks to version.cam\n --dry-run print what would be sent, and send nothing\n --report <file> and write the living URLs there, as JSON\n\nFrom another directory\n versioncam <command> --cwd <dir> as if run in <dir>, which holds versioncam.config.ts\n versioncam --version which versioncam this is\n\nRun from a directory containing versioncam.config.ts, or name it with --cwd.\n";
package/dist/cli/usage.js CHANGED
@@ -9,7 +9,8 @@
9
9
  *
10
10
  * Grouped by the stage of the work each command belongs to, in the order a
11
11
  * repository meets them. A flat list of seventeen commands left a newcomer to
12
- * work out that `inspect` comes before `record` and `sheet` after it.
12
+ * work out that `inspect` comes before `record` and `sheet` after it. The
13
+ * last group is not a stage but a way to run any of them.
13
14
  */
14
15
  export const USAGE = `versioncam: record and render demo clips of a real app
15
16
 
@@ -32,6 +33,7 @@ Record
32
33
  versioncam record [id…] drive the app and capture frames
33
34
  --draft 15fps at CSS scale: cheap, for writing clips
34
35
  versioncam check [id…] record every clip; exit 1 if any breaks
36
+ --report <file> and write each clip's result there, as JSON
35
37
  versioncam stability [id…] record each clip twice the same way; stable or not
36
38
  --runs <n> how many times (default 2)
37
39
  --full at full quality rather than draft
@@ -50,10 +52,21 @@ Review
50
52
  --frame <n> start at this frame
51
53
 
52
54
  Output
53
- versioncam render [id…] composite and encode what has been recorded
54
- --scene <id> render a designed scene (repeatable)
55
+ versioncam render [id…] composite and encode recordings and scenes
56
+ no ids: every one, stale recordings included
57
+ --scene <id> and this scene, whatever the ids say (repeatable)
55
58
  --sequence stitch the results into one piece
59
+ --report <file> and write what it made there, as JSON
56
60
 
57
- Run from a directory containing versioncam.config.ts.
61
+ Publish
62
+ versioncam publish [id…] send the recordings and their checks to version.cam
63
+ --dry-run print what would be sent, and send nothing
64
+ --report <file> and write the living URLs there, as JSON
65
+
66
+ From another directory
67
+ versioncam <command> --cwd <dir> as if run in <dir>, which holds versioncam.config.ts
68
+ versioncam --version which versioncam this is
69
+
70
+ Run from a directory containing versioncam.config.ts, or name it with --cwd.
58
71
  `;
59
72
  //# sourceMappingURL=usage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/cli/usage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CpB,CAAC"}
1
+ {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/cli/usage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwDpB,CAAC"}
package/dist/config.d.ts CHANGED
@@ -31,6 +31,25 @@ export type Presentation = {
31
31
  padding?: number;
32
32
  /** "auto" puts it below the app when padded, and over it when not. */
33
33
  caption?: "auto" | "below" | "overlay" | "none";
34
+ /**
35
+ * Where a caption over the app sits: `{ left: n }` or `{ right: n }`,
36
+ * pixels of the video in from that side, which also picks the bottom
37
+ * corner. Default `{ left: 40 }`.
38
+ *
39
+ * An app keeps its own controls in a corner as often as not (an account
40
+ * menu at the foot of a sidebar, a map's legend), and a caption fixed over
41
+ * one hides what a clip may be pointing at. Ignored when the caption sits
42
+ * below the app, where there is nothing of the app to cover.
43
+ */
44
+ captionInset?: CaptionInset;
45
+ };
46
+ /** One side and a distance from it, as CSS's `left` and `right` say it. */
47
+ export type CaptionInset = {
48
+ left: number;
49
+ right?: never;
50
+ } | {
51
+ right: number;
52
+ left?: never;
34
53
  };
35
54
  export type AuthConfig = {
36
55
  storageState: string;
@@ -167,9 +186,17 @@ export type RecorderConfig = {
167
186
  cursorScale?: number;
168
187
  presentation?: Presentation;
169
188
  };
170
- /** Output width; the height follows the viewport's aspect. */
189
+ /**
190
+ * Output width; the height follows the viewport's aspect. `threads` fixes
191
+ * how many threads each encoder uses. The bytes an encoder writes depend on
192
+ * its thread count, which by default follows the machine's cores, so two
193
+ * machines render the same recording to different files; fixing it is what
194
+ * makes a render reproducible anywhere, and what version.cam's renderer
195
+ * does. `VERSIONCAM_FFMPEG_THREADS` sets it for one run.
196
+ */
171
197
  output?: {
172
198
  width?: number;
199
+ threads?: number;
173
200
  };
174
201
  motion?: Partial<Motion>;
175
202
  /** Module whose default export is `Record<string, Scene>`. */
@@ -213,6 +240,8 @@ export type ResolvedConfig = {
213
240
  width: number;
214
241
  height: number;
215
242
  };
243
+ /** Threads per encoder, or null for ffmpeg's own choice. */
244
+ encoderThreads: number | null;
216
245
  motion: Motion;
217
246
  scenes: string | null;
218
247
  sequence: string[] | null;
@@ -246,5 +275,10 @@ export type RenderConfig = {
246
275
  presentation: Presentation | null;
247
276
  };
248
277
  motion: Motion;
278
+ /**
279
+ * The scenes module's path. The page is served a bundle of it, and names
280
+ * the file it came from when it cannot read the scenes out of it.
281
+ */
282
+ scenes: string | null;
249
283
  };
250
284
  export declare function renderConfigOf(config: ResolvedConfig): RenderConfig;
package/dist/config.js CHANGED
@@ -7,12 +7,50 @@ export function defineRecorder(config) {
7
7
  function fail(field, why) {
8
8
  throw new Error(`versioncam config: \`${field}\` ${why}`);
9
9
  }
10
+ /**
11
+ * The environment wins over the config, so a machine (version.cam's renderer,
12
+ * a CI job) can pin the thread count of a repository that does not.
13
+ */
14
+ function threadsOf(configured) {
15
+ const fromEnv = process.env.VERSIONCAM_FFMPEG_THREADS;
16
+ if (fromEnv !== undefined && fromEnv !== "") {
17
+ const n = Number(fromEnv);
18
+ if (!Number.isInteger(n) || n < 1) {
19
+ throw new Error(`VERSIONCAM_FFMPEG_THREADS must be a whole number of 1 or more, got "${fromEnv}".`);
20
+ }
21
+ return n;
22
+ }
23
+ if (configured === undefined)
24
+ return null;
25
+ return positiveInt(configured, "output.threads");
26
+ }
10
27
  function positiveInt(value, field) {
11
28
  if (!Number.isInteger(value) || value <= 0) {
12
29
  fail(field, `must be a positive integer, got ${value}`);
13
30
  }
14
31
  return value;
15
32
  }
33
+ /**
34
+ * A caption inset names one side, and a distance that keeps the caption on
35
+ * the video.
36
+ *
37
+ * Checked because a caption placed off the video fails the way nothing in
38
+ * the presentation layer should: without an error, and without a caption.
39
+ */
40
+ function checkCaptionInset(inset, outputWidth) {
41
+ const field = "theme.presentation.captionInset";
42
+ const given = inset;
43
+ const sides = ["left", "right"].filter((side) => given?.[side] !== undefined);
44
+ if (given === null || sides.length !== 1) {
45
+ fail(field, "must be `{ left: n }` or `{ right: n }`, one side only");
46
+ }
47
+ const px = given[sides[0]];
48
+ if (typeof px !== "number" || !(px >= 0 && px < outputWidth)) {
49
+ // Quoted when it is a string, or `"40"` would read as the 40 it is not.
50
+ const got = typeof px === "string" ? JSON.stringify(px) : String(px);
51
+ fail(`${field}.${sides[0]}`, `must be pixels of the video, from 0 to under its width of ${outputWidth}, got ${got}`);
52
+ }
53
+ }
16
54
  /**
17
55
  * Output dimensions follow the viewport's aspect.
18
56
  *
@@ -89,7 +127,11 @@ export function resolveConfig(config, root) {
89
127
  const outDir = abs(config.outDir ?? ".versioncam");
90
128
  const outputWidth = config.output?.width ?? 1920;
91
129
  positiveInt(outputWidth, "output.width");
130
+ const encoderThreads = threadsOf(config.output?.threads);
92
131
  const baseUrl = config.baseUrl.replace(/\/+$/, "");
132
+ if (presentation?.captionInset !== undefined) {
133
+ checkCaptionInset(presentation.captionInset, outputWidth);
134
+ }
93
135
  return {
94
136
  root,
95
137
  baseUrl,
@@ -139,6 +181,7 @@ export function resolveConfig(config, root) {
139
181
  presentation: presentation ?? null,
140
182
  },
141
183
  output: outputSize(viewport, outputWidth),
184
+ encoderThreads,
142
185
  motion: { ...MOTION, ...config.motion },
143
186
  scenes: config.scenes ? abs(config.scenes) : null,
144
187
  sequence: config.sequence ?? null,
@@ -149,6 +192,7 @@ export function renderConfigOf(config) {
149
192
  output: config.output,
150
193
  theme: config.theme,
151
194
  motion: config.motion,
195
+ scenes: config.scenes,
152
196
  };
153
197
  }
154
198
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AA0OnD,qEAAqE;AACrE,MAAM,UAAU,cAAc,CAAC,MAAsB;IACnD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,IAAI,CAAC,KAAa,EAAE,GAAW;IACtC,MAAM,IAAI,KAAK,CAAC,wBAAwB,KAAK,MAAM,GAAG,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED;;;GAGG;AACH,SAAS,SAAS,CAAC,UAA8B;IAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC;IACtD,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;QAC5C,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CACb,uEAAuE,OAAO,IAAI,CACnF,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAO,WAAW,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,WAAW,CAAC,KAAa,EAAE,KAAa;IAC/C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QAC3C,IAAI,CAAC,KAAK,EAAE,mCAAmC,KAAK,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,SAAS,iBAAiB,CAAC,KAAmB,EAAE,WAAmB;IACjE,MAAM,KAAK,GAAG,iCAAiC,CAAC;IAChD,MAAM,KAAK,GAAG,KAAmD,CAAC;IAClE,MAAM,KAAK,GAAI,CAAC,MAAM,EAAE,OAAO,CAAW,CAAC,MAAM,CAC/C,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,KAAK,SAAS,CACtC,CAAC;IACF,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,KAAK,EAAE,wDAAwD,CAAC,CAAC;IACxE,CAAC;IACD,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,WAAW,CAAC,EAAE,CAAC;QAC7D,wEAAwE;QACxE,MAAM,GAAG,GAAG,OAAO,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACrE,IAAI,CACF,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,EACtB,6DAA6D,WAAW,SAAS,GAAG,EAAE,CACvF,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CACxB,QAA2C,EAC3C,KAAa;IAEb,MAAM,KAAK,GAAG,CAAC,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IACzD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;AACtD,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,gBAAgB,CACvB,MAAuB,EACvB,OAAe,EACf,IAAY;IAEZ,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACvE,IAAI,CAAC,mBAAmB,EAAE,4BAA4B,CAAC,CAAC;IAC1D,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC;IAClC,2EAA2E;IAC3E,yEAAyE;IACzE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACtE,IAAI,CAAC,eAAe,EAAE,+BAA+B,GAAG,EAAE,CAAC,CAAC;IAC9D,CAAC;IACD,MAAM,SAAS,GAAG,WAAW,CAC3B,MAAM,CAAC,SAAS,IAAI,OAAO,EAC3B,qBAAqB,CACtB,CAAC;IACF,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,GAAG;QACH,GAAG,EAAE,MAAM,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC;QAChE,SAAS;QACT,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;QAClE,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,EAAE;KACtB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,MAAsB,EACtB,IAAY;IAEZ,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtE,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACjC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IACjE,WAAW,CAAC,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC;IAC9C,WAAW,CAAC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAEhD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QACzB,IAAI,CAAC,KAAK,EAAE,gCAAgC,GAAG,EAAE,CAAC,CAAC;IAErD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;QACpD,IAAI,CAAC,KAAK,EAAE,8CAA8C,GAAG,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,EAAE,iBAAiB,IAAI,EAAE,CAAC;IAClE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,iBAAiB,CAAC,IAAI,iBAAiB,GAAG,CAAC,EAAE,CAAC;QAClE,IAAI,CACF,2BAA2B,EAC3B,wCAAwC,iBAAiB,EAAE,CAC5D,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,MAAM,QAAQ,GAAG,OAAO,MAAM,CAAC,IAAI,CAAC,YAAY,KAAK,QAAQ,CAAC;QAC9D,MAAM,QAAQ,GAAG,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,UAAU,CAAC;QACzD,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,IAAI,CAAC,MAAM,EAAE,oDAAoD,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC;IAChD,IAAI,YAAY,EAAE,OAAO,KAAK,SAAS,EAAE,CAAC;QACxC,MAAM,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,4BAA4B,EAAE,kCAAkC,CAAC,EAAE,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,aAAa,CAAC,CAAC;IACnD,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,IAAI,CAAC;IACjD,WAAW,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IACzC,MAAM,cAAc,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAEnD,IAAI,YAAY,EAAE,YAAY,KAAK,SAAS,EAAE,CAAC;QAC7C,iBAAiB,CAAC,YAAY,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO;QACL,IAAI;QACJ,OAAO;QACP,SAAS,EAAE,MAAM,CAAC,SAAS;YACzB,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC;YACnD,CAAC,CAAC,IAAI;QACR,QAAQ;QACR,GAAG;QACH,GAAG;QACH,KAAK,EACH,MAAM,CAAC,KAAK,KAAK,SAAS;YACxB,CAAC,CAAC,CAAC,oBAAoB,CAAC;YACxB,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;gBAC3B,CAAC,CAAC,MAAM,CAAC,KAAK;gBACd,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;QACtB,MAAM;QACN,aAAa,EAAE,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC;QAC5C,SAAS,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC;QACjC,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC;QACnC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI;QACzB,MAAM,EAAE;YACN,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,IAAI,GAAG;YACtC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,IAAI,MAAM;YAC7C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE;YACrC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,IAAI;SACpC;QACD,OAAO,EAAE;YACP,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,IAAI,IAAI;YAClC,iBAAiB,EAAE,iBAAiB;SACrC;QACD,MAAM,EAAE;YACN,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,IAAI,CAAC;YAC1C,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,IAAI,EAAE;SAC5C;QACD,WAAW,EAAE;YACX,CAAC,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,IAAI,IAAI;YAChC,CAAC,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,IAAI,IAAI;SACjC;QACD,KAAK,EAAE;YACL,IAAI,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,IAAI,sBAAsB,CAAC;YAC5D,UAAU,EAAE,MAAM,CAAC,KAAK,EAAE,UAAU,IAAI,KAAK;YAC7C,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,IAAI,OAAO;SACxC;QACD,KAAK,EAAE;YACL,kEAAkE;YAClE,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,IAAI,SAAS;YACzC,WAAW,EAAE,MAAM,CAAC,KAAK,EAAE,WAAW,IAAI,GAAG;YAC7C,YAAY,EAAE,YAAY,IAAI,IAAI;SACnC;QACD,MAAM,EAAE,UAAU,CAAC,QAAQ,EAAE,WAAW,CAAC;QACzC,cAAc;QACd,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE;QACvC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI;QACjD,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,IAAI;KAClC,CAAC;AACJ,CAAC;AAkBD,MAAM,UAAU,cAAc,CAAC,MAAsB;IACnD,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,63 @@
1
+ import type { Viewport } from "./camera.js";
2
+ import type { FollowSpec } from "./follow.js";
3
+ import type { CameraKey, CursorTrack, Rect, Vec2 } from "./timeline.js";
4
+ /**
5
+ * What a clip asked the camera to do, and when: one per `s.camera.*` call.
6
+ *
7
+ * The session keeps these rather than writing camera keys as it goes,
8
+ * because a camera that follows the cursor depends on where the cursor goes
9
+ * *after* the write, and that is only known once the clip has run. The
10
+ * driver never needs the camera while it records: it captures the whole
11
+ * viewport, and the camera is a crop drawn afterwards.
12
+ */
13
+ export type CameraWrite =
14
+ /** `zoom`, `to` and `reset`: glide to a framing and stay there. */
15
+ {
16
+ t: number;
17
+ kind: "frame";
18
+ rect: Rect;
19
+ durationMs: number;
20
+ }
21
+ /** Follow the cursor, until the next write. */
22
+ | {
23
+ t: number;
24
+ kind: "follow";
25
+ spec: FollowSpec;
26
+ durationMs: number;
27
+ }
28
+ /** Stop following, and come to rest on the framing the follow was heading for. */
29
+ | {
30
+ t: number;
31
+ kind: "release";
32
+ };
33
+ export type TrackContext = {
34
+ viewport: Viewport;
35
+ fps: number;
36
+ durationFrames: number;
37
+ cursor: CursorTrack;
38
+ /** Where the cursor rests before the track's first step. */
39
+ cursorStart: Vec2;
40
+ };
41
+ /**
42
+ * Turn a clip's camera writes into the keys the renderer interpolates.
43
+ *
44
+ * Every write starts from where the camera is, moving or not, and blends
45
+ * from there to where it is going:
46
+ *
47
+ * camera(t) = interpolateRect(before(t), destination(t), minjerk(u))
48
+ *
49
+ * where `before` is the camera as it would have gone on without this write,
50
+ * and `u` runs from 0 to 1 over the write's duration. Min-jerk has no slope
51
+ * at either end, so the camera's velocity is continuous where a blend starts
52
+ * and where it ends: entering a follow from a keyed zoom, leaving it for a
53
+ * reset, or a zoom written while another is still under way. That last one
54
+ * used to wait for the move before it to finish and then run short, because
55
+ * each glide set off from the previous glide's target.
56
+ *
57
+ * A clip that never follows and never writes a move while another is under
58
+ * way gets exactly the keys it always got: a hold where each write starts and
59
+ * a min-jerk key where it ends. Every other clip gets the camera sampled at
60
+ * each frame (the `"linear"` keys), since a blend between two moving framings
61
+ * is no longer a glide between two keys.
62
+ */
63
+ export declare function cameraTrack(writes: readonly CameraWrite[], context: TrackContext): CameraKey[];