@clipwright/core 0.19.0 → 0.21.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 (135) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/dist/__fixtures__/queue-promises.d.ts +5 -84
  3. package/dist/__fixtures__/queue-promises.js +7 -84
  4. package/dist/__fixtures__/queue-promises.js.map +1 -1
  5. package/dist/account-actors.d.ts +25 -25
  6. package/dist/account-actors.js +25 -25
  7. package/dist/account-actors.js.map +1 -1
  8. package/dist/account.d.ts +4 -10
  9. package/dist/account.js +6 -12
  10. package/dist/account.js.map +1 -1
  11. package/dist/actor-bounds.d.ts +4 -4
  12. package/dist/actor-bounds.js +4 -4
  13. package/dist/actor-bounds.js.map +1 -1
  14. package/dist/actor-qualities.d.ts +3 -3
  15. package/dist/actor-qualities.js +3 -3
  16. package/dist/actor-qualities.js.map +1 -1
  17. package/dist/actors.d.ts +8 -8
  18. package/dist/actors.js +9 -9
  19. package/dist/actors.js.map +1 -1
  20. package/dist/api-failure.d.ts +28 -129
  21. package/dist/api-failure.js +52 -225
  22. package/dist/api-failure.js.map +1 -1
  23. package/dist/aspect.d.ts +26 -96
  24. package/dist/aspect.js +32 -108
  25. package/dist/aspect.js.map +1 -1
  26. package/dist/contract-dispositions.d.ts +42 -167
  27. package/dist/contract-dispositions.js +54 -184
  28. package/dist/contract-dispositions.js.map +1 -1
  29. package/dist/endpoints.d.ts +5 -5
  30. package/dist/endpoints.js +5 -3
  31. package/dist/endpoints.js.map +1 -1
  32. package/dist/errors.d.ts +33 -101
  33. package/dist/errors.js +42 -108
  34. package/dist/errors.js.map +1 -1
  35. package/dist/faceless-cut-style.d.ts +115 -0
  36. package/dist/faceless-cut-style.js +109 -0
  37. package/dist/faceless-cut-style.js.map +1 -0
  38. package/dist/faceless-image-qualification.d.ts +97 -0
  39. package/dist/faceless-image-qualification.js +145 -0
  40. package/dist/faceless-image-qualification.js.map +1 -0
  41. package/dist/faceless-price.d.ts +21 -0
  42. package/dist/faceless-price.js +25 -0
  43. package/dist/faceless-price.js.map +1 -0
  44. package/dist/faceless-public-plan.d.ts +71 -0
  45. package/dist/faceless-public-plan.js +166 -0
  46. package/dist/faceless-public-plan.js.map +1 -0
  47. package/dist/faceless-public.d.ts +107 -0
  48. package/dist/faceless-public.js +74 -0
  49. package/dist/faceless-public.js.map +1 -0
  50. package/dist/faceless-short-61.d.ts +83 -0
  51. package/dist/faceless-short-61.js +152 -0
  52. package/dist/faceless-short-61.js.map +1 -0
  53. package/dist/faceless-storyboard-timing.d.ts +40 -0
  54. package/dist/faceless-storyboard-timing.js +97 -0
  55. package/dist/faceless-storyboard-timing.js.map +1 -0
  56. package/dist/faceless-storyboard-v2-plan.d.ts +3 -0
  57. package/dist/faceless-storyboard-v2-plan.js +112 -0
  58. package/dist/faceless-storyboard-v2-plan.js.map +1 -0
  59. package/dist/faceless-storyboard-v2-timing.d.ts +63 -0
  60. package/dist/faceless-storyboard-v2-timing.js +143 -0
  61. package/dist/faceless-storyboard-v2-timing.js.map +1 -0
  62. package/dist/faceless-storyboard-v2.d.ts +44 -0
  63. package/dist/faceless-storyboard-v2.js +43 -0
  64. package/dist/faceless-storyboard-v2.js.map +1 -0
  65. package/dist/faceless-storyboard.d.ts +55 -0
  66. package/dist/faceless-storyboard.js +105 -0
  67. package/dist/faceless-storyboard.js.map +1 -0
  68. package/dist/idempotency.d.ts +10 -44
  69. package/dist/idempotency.js +18 -44
  70. package/dist/idempotency.js.map +1 -1
  71. package/dist/index.d.ts +3 -0
  72. package/dist/index.js +24 -25
  73. package/dist/index.js.map +1 -1
  74. package/dist/long-form-pricing.d.ts +4 -4
  75. package/dist/long-form-pricing.js +4 -4
  76. package/dist/long-form-pricing.js.map +1 -1
  77. package/dist/long-form-profile.d.ts +2 -2
  78. package/dist/long-form-profile.js +2 -2
  79. package/dist/long-form-profile.js.map +1 -1
  80. package/dist/pacing.d.ts +1 -1
  81. package/dist/pacing.js +1 -1
  82. package/dist/pacing.js.map +1 -1
  83. package/dist/public-endpoints.d.ts +9 -11
  84. package/dist/public-endpoints.js +11 -13
  85. package/dist/public-endpoints.js.map +1 -1
  86. package/dist/rate-limit.d.ts +23 -130
  87. package/dist/rate-limit.js +27 -132
  88. package/dist/rate-limit.js.map +1 -1
  89. package/dist/render-backend.d.ts +30 -145
  90. package/dist/render-backend.js +4 -27
  91. package/dist/render-backend.js.map +1 -1
  92. package/dist/run-preflight.d.ts +4 -4
  93. package/dist/run-preflight.js +10 -10
  94. package/dist/run-preflight.js.map +1 -1
  95. package/dist/run-static-warnings.d.ts +8 -8
  96. package/dist/run-static-warnings.js +26 -24
  97. package/dist/run-static-warnings.js.map +1 -1
  98. package/dist/runs.d.ts +34 -55
  99. package/dist/runs.js +28 -94
  100. package/dist/runs.js.map +1 -1
  101. package/dist/script-integrity.d.ts +6 -7
  102. package/dist/script-integrity.js +7 -8
  103. package/dist/script-integrity.js.map +1 -1
  104. package/dist/semantic-inserts.d.ts +4 -4
  105. package/dist/semantic-inserts.js +6 -6
  106. package/dist/semantic-inserts.js.map +1 -1
  107. package/dist/skills.d.ts +37 -108
  108. package/dist/skills.js +77 -161
  109. package/dist/skills.js.map +1 -1
  110. package/dist/tts-backend.d.ts +13 -42
  111. package/dist/tts-backend.js +2 -10
  112. package/dist/tts-backend.js.map +1 -1
  113. package/dist/uploads.d.ts +4 -4
  114. package/dist/uploads.js +4 -4
  115. package/dist/uploads.js.map +1 -1
  116. package/dist/vendor-response.d.ts +17 -80
  117. package/dist/vendor-response.js +19 -67
  118. package/dist/vendor-response.js.map +1 -1
  119. package/dist/voice-admission.d.ts +5 -5
  120. package/dist/voice-admission.js +6 -6
  121. package/dist/voice-admission.js.map +1 -1
  122. package/dist/voice-catalog-data.d.ts +2 -2
  123. package/dist/voice-catalog-data.js +2 -2
  124. package/dist/voice-catalog-data.js.map +1 -1
  125. package/dist/voice-catalog.d.ts +5 -5
  126. package/dist/voice-catalog.generated.json +56 -54
  127. package/dist/voice-catalog.js +6 -6
  128. package/dist/voice-catalog.js.map +1 -1
  129. package/dist/voice-listing.d.ts +4 -4
  130. package/dist/voice-listing.js +6 -6
  131. package/dist/voice-listing.js.map +1 -1
  132. package/dist/voices.d.ts +40 -82
  133. package/dist/voices.js +56 -99
  134. package/dist/voices.js.map +1 -1
  135. package/package.json +1 -1
@@ -0,0 +1,40 @@
1
+ import { type StoryboardProposal } from "./faceless-storyboard.js";
2
+ type WordTiming = {
3
+ word: string;
4
+ startSec: number;
5
+ endSec: number;
6
+ };
7
+ type PhraseRange = {
8
+ wordStart: number;
9
+ wordEnd: number;
10
+ accentWord: number;
11
+ };
12
+ type Cut = {
13
+ afterWord: number;
14
+ frame: number;
15
+ reason: string;
16
+ };
17
+ export type StoryboardFramePlan = {
18
+ version: "faceless_storyboard_61_v1";
19
+ outputFrames: 1522;
20
+ script: string;
21
+ captionPhrases: PhraseRange[];
22
+ narrationStartFrame: number;
23
+ shots: Array<{
24
+ id: string;
25
+ mediaType: "video" | "image";
26
+ startFrame: number;
27
+ endFrame: number;
28
+ motion?: "PAN_UP" | "PAN_DOWN";
29
+ beatIds: string[];
30
+ cutAfterWord?: number;
31
+ cutReason?: string;
32
+ }>;
33
+ rejectedCandidates: Cut[];
34
+ imageBudget: {
35
+ allowance: 24;
36
+ remaining: number;
37
+ };
38
+ };
39
+ export declare function planStoryboardFrames(input: StoryboardProposal, words: readonly WordTiming[], narrationStartFrame: number): StoryboardFramePlan;
40
+ export {};
@@ -0,0 +1,97 @@
1
+ import { assertStoryboardWords, parseStoryboardProposal, storyboardImageBudget } from "./faceless-storyboard.js";
2
+ const priority = { place: 4, reveal: 4, action: 3, emphasis: 1 };
3
+ function better(candidate, current) {
4
+ return !current || candidate.score > current.score ||
5
+ (candidate.score === current.score && candidate.penalty < current.penalty);
6
+ }
7
+ export function planStoryboardFrames(input, words, narrationStartFrame) {
8
+ const proposal = parseStoryboardProposal(input);
9
+ assertStoryboardWords(proposal.script, words);
10
+ if (!Number.isSafeInteger(narrationStartFrame) || narrationStartFrame < 0 || narrationStartFrame >= 1522) {
11
+ throw new Error("invalid narration start frame");
12
+ }
13
+ const speechEnd = narrationStartFrame / 25 + words[words.length - 1].endSec;
14
+ if (speechEnd > 1522 / 25)
15
+ throw new Error("narration exceeds output duration");
16
+ if (1522 / 25 - speechEnd > 0.5 + 1e-9)
17
+ throw new Error("narration leaves more than 0.5 seconds tail");
18
+ const candidates = proposal.beats.slice(1).map((beat, i) => {
19
+ const afterWord = beat.wordStart - 1;
20
+ const previous = words[afterWord];
21
+ const next = words[afterWord + 1];
22
+ const edgeSec = next.startSec > previous.endSec ? (previous.endSec + next.startSec) / 2 : next.startSec;
23
+ const frame = narrationStartFrame + Math.round(edgeSec * 25);
24
+ if (!Number.isSafeInteger(frame) || frame <= 0 || frame >= 1522)
25
+ throw new Error("cut outside output");
26
+ const time = (frame - narrationStartFrame) / 25;
27
+ const inside = words.some(w => time - w.startSec > 1 / 25 + 1e-9 && w.endSec - time > 1 / 25 + 1e-9);
28
+ return { afterWord, frame, reason: beat.reason, beatIndex: i + 1, priority: priority[beat.reason],
29
+ ...(inside ? { rejection: "cut more than one frame inside timed word" } : {}) };
30
+ });
31
+ const opener = candidates[0];
32
+ if (opener.rejection || opener.frame < 75 || opener.frame > 125) {
33
+ throw new Error("no feasible storyboard: mandatory VIDEO boundary violates timing");
34
+ }
35
+ const nodes = [...candidates, { frame: 1522, beatIndex: proposal.beats.length, priority: 0, afterWord: words.length - 1, reason: "output end" }];
36
+ const states = nodes.map(() => Array(20));
37
+ states[0][0] = { score: opener.priority, penalty: 0, previous: -1 };
38
+ for (let end = 1; end < nodes.length; end++) {
39
+ const destination = nodes[end];
40
+ if ("rejection" in destination && destination.rejection)
41
+ continue;
42
+ for (let start = 0; start < end; start++) {
43
+ const duration = destination.frame - nodes[start].frame;
44
+ if (duration < 25 || duration > 150)
45
+ continue;
46
+ for (let count = 1; count <= 19; count++) {
47
+ const prior = states[start][count - 1];
48
+ if (!prior)
49
+ continue;
50
+ const state = { score: prior.score + destination.priority,
51
+ penalty: prior.penalty + Math.abs(duration - 68.75), previous: start };
52
+ if (better(state, states[end][count]))
53
+ states[end][count] = state;
54
+ }
55
+ }
56
+ }
57
+ const last = nodes.length - 1;
58
+ let imageCount = 0;
59
+ let best;
60
+ for (let count = 1; count <= 19; count++) {
61
+ const state = states[last][count];
62
+ if (state && better(state, best)) {
63
+ best = state;
64
+ imageCount = count;
65
+ }
66
+ }
67
+ if (!best)
68
+ throw new Error("no feasible storyboard within scene duration and image budget limits");
69
+ const chosen = [last];
70
+ let cursor = last;
71
+ for (let count = imageCount; count > 0; count--) {
72
+ cursor = states[cursor][count].previous;
73
+ chosen.push(cursor);
74
+ }
75
+ chosen.reverse();
76
+ const selected = new Set(chosen);
77
+ const shots = [];
78
+ let startFrame = 0;
79
+ let beatStart = 0;
80
+ for (const [shotIndex, nodeIndex] of chosen.entries()) {
81
+ const node = nodes[nodeIndex];
82
+ shots.push({ id: proposal.beats[beatStart].id, mediaType: shotIndex === 0 ? "video" : "image",
83
+ startFrame, endFrame: node.frame,
84
+ ...(shotIndex > 0 ? { motion: shotIndex % 2 === 1 ? "PAN_UP" : "PAN_DOWN" } : {}),
85
+ beatIds: proposal.beats.slice(beatStart, node.beatIndex).map(b => b.id),
86
+ ...(nodeIndex < last ? { cutAfterWord: node.afterWord, cutReason: node.reason } : {}), });
87
+ startFrame = node.frame;
88
+ beatStart = node.beatIndex;
89
+ }
90
+ return { version: proposal.version, outputFrames: 1522, script: proposal.script,
91
+ captionPhrases: proposal.captionPhrases, narrationStartFrame, shots,
92
+ rejectedCandidates: candidates.flatMap((candidate, i) => selected.has(i) ? [] : [{
93
+ afterWord: candidate.afterWord, frame: candidate.frame,
94
+ reason: candidate.rejection ?? `unselected ${candidate.reason} boundary under timing and image budget constraints`,
95
+ }]), imageBudget: storyboardImageBudget(imageCount, 2) };
96
+ }
97
+ //# sourceMappingURL=faceless-storyboard-timing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"faceless-storyboard-timing.js","sourceRoot":"","sources":["../src/faceless-storyboard-timing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { StoryboardV2FramePlan } from "./faceless-storyboard-v2-timing.js";
2
+ import type { WordTiming } from "./tts-backend.js";
3
+ export declare function parseStoryboardV2Plan(input: unknown, words: readonly WordTiming[]): StoryboardV2FramePlan;
@@ -0,0 +1,112 @@
1
+ import { assertStoryboardWords } from "./faceless-storyboard.js";
2
+ const phases = ["setup", "development", "climax", "resolution"];
3
+ const reasons = ["action", "place", "reveal", "emphasis"];
4
+ function record(value, keys) {
5
+ if (!value || typeof value !== "object" || Array.isArray(value) ||
6
+ Object.keys(value).some(key => !keys.includes(key)))
7
+ throw new Error("invalid storyboard v2 object or unknown fields");
8
+ return value;
9
+ }
10
+ function uint(value) { return Number.isSafeInteger(value) && value >= 0; }
11
+ function finite(value) { return typeof value === "number" && Number.isFinite(value) && value >= 0; }
12
+ function label(value) { return typeof value === "string" && value.trim().length > 0; }
13
+ function score(value) {
14
+ const s = record(value, ["semanticValue", "cutCost", "pacePenalty", "net"]);
15
+ if (!finite(s.semanticValue) || !finite(s.cutCost) || !finite(s.pacePenalty) ||
16
+ typeof s.net !== "number" || !Number.isFinite(s.net) ||
17
+ Math.abs(s.net - (s.semanticValue - s.cutCost - s.pacePenalty)) > 1e-8)
18
+ throw new Error("invalid storyboard v2 score");
19
+ }
20
+ export function parseStoryboardV2Plan(input, words) {
21
+ const raw = record(input, ["version", "outputFrames", "script", "narrationStartFrame", "captionPhrases", "shots", "rejectedCandidates", "scoreBreakdown"]);
22
+ if (raw.version !== "faceless_storyboard_61_v2" || raw.outputFrames !== 1522 || !label(raw.script) ||
23
+ !uint(raw.narrationStartFrame) || raw.narrationStartFrame > 50 ||
24
+ !Array.isArray(raw.shots) || raw.shots.length < 2 ||
25
+ !Array.isArray(raw.captionPhrases) || !raw.captionPhrases.length || !Array.isArray(raw.rejectedCandidates)) {
26
+ throw new Error("invalid storyboard v2 frame plan");
27
+ }
28
+ assertStoryboardWords(raw.script, words);
29
+ if (raw.narrationStartFrame + words.at(-1).endSec * 25 > 1522 + 1e-9 ||
30
+ 1522 - raw.narrationStartFrame - words.at(-1).endSec * 25 > 12.5 + 1e-9)
31
+ throw new Error("invalid storyboard v2 narration tail");
32
+ let captionEnd = 0;
33
+ for (const phrase of raw.captionPhrases) {
34
+ const p = record(phrase, ["wordStart", "wordEnd", "accentWord"]);
35
+ if (!uint(p.wordStart) || !uint(p.wordEnd) || !uint(p.accentWord) || p.wordStart !== captionEnd || p.wordStart >= p.wordEnd ||
36
+ p.wordEnd > words.length || p.accentWord < p.wordStart || p.accentWord >= p.wordEnd)
37
+ throw new Error("invalid storyboard v2 caption");
38
+ captionEnd = p.wordEnd;
39
+ }
40
+ if (captionEnd !== words.length)
41
+ throw new Error("incomplete storyboard v2 captions");
42
+ const ids = new Set();
43
+ const beatIds = new Set();
44
+ let end = 0;
45
+ let previousWord = -1;
46
+ let previousPhase = -1;
47
+ let semanticValue = 0, cutCost = 0, pacePenalty = 0, total = 0, cuts = 0;
48
+ for (const [i, value] of raw.shots.entries()) {
49
+ const shot = record(value, ["id", "mediaType", "startFrame", "endFrame", "beatIds", "phase", "mergedPhases", "motion", "panExceptionReason", "cutAfterWord", "cutReason", "score"]);
50
+ if (!label(shot.id) || ids.has(shot.id))
51
+ throw new Error("duplicate or invalid storyboard v2 shot ID");
52
+ ids.add(shot.id);
53
+ if (!uint(shot.startFrame) || !uint(shot.endFrame) || shot.startFrame !== end || shot.endFrame > 1522 ||
54
+ shot.endFrame - shot.startFrame < (i ? 25 : 50) || shot.endFrame - shot.startFrame > (i ? 150 : 125) ||
55
+ shot.mediaType !== (i ? "image" : "video") || (i ? !(typeof shot.motion === "string" && ["PAN_UP", "PAN_DOWN"].includes(shot.motion)) : shot.motion !== undefined) ||
56
+ !Array.isArray(shot.beatIds) || !shot.beatIds.length || !shot.beatIds.every(label) ||
57
+ !(typeof shot.phase === "string" && phases.includes(shot.phase)) || phases.indexOf(shot.phase) < previousPhase ||
58
+ (shot.mergedPhases !== undefined && (!Array.isArray(shot.mergedPhases) || !shot.mergedPhases.length || !shot.mergedPhases.every(p => phases.includes(p)))) ||
59
+ (shot.panExceptionReason !== undefined && (!i || !label(shot.panExceptionReason))))
60
+ throw new Error("invalid storyboard v2 shot coverage, duration, or fields");
61
+ for (const beat of shot.beatIds) {
62
+ if (beatIds.has(beat))
63
+ throw new Error("duplicate storyboard v2 beat ID");
64
+ beatIds.add(beat);
65
+ }
66
+ previousPhase = phases.indexOf(shot.phase);
67
+ end = shot.endFrame;
68
+ score(shot.score);
69
+ const s = shot.score;
70
+ semanticValue += s.semanticValue;
71
+ cutCost += s.cutCost;
72
+ pacePenalty += s.pacePenalty;
73
+ total += s.net;
74
+ if (i < raw.shots.length - 1) {
75
+ if (!uint(shot.cutAfterWord) || shot.cutAfterWord <= previousWord || shot.cutAfterWord >= words.length - 1 ||
76
+ !(typeof shot.cutReason === "string" && reasons.includes(shot.cutReason)))
77
+ throw new Error("invalid storyboard v2 cut word or reason");
78
+ const previous = words[shot.cutAfterWord];
79
+ const next = words[shot.cutAfterWord + 1];
80
+ const edgeSec = next.startSec > previous.endSec ? (previous.endSec + next.startSec) / 2 : next.startSec;
81
+ const frame = raw.narrationStartFrame + Math.round(edgeSec * 25);
82
+ const sec = (shot.endFrame - raw.narrationStartFrame) / 25;
83
+ if (shot.endFrame !== frame || words.some(w => sec - w.startSec > 1 / 25 + 1e-9 && w.endSec - sec > 1 / 25 + 1e-9)) {
84
+ throw new Error("storyboard v2 cut lies mid-word or differs from measured boundary");
85
+ }
86
+ previousWord = shot.cutAfterWord;
87
+ cuts++;
88
+ }
89
+ else if (shot.cutAfterWord !== undefined || shot.cutReason !== undefined)
90
+ throw new Error("final storyboard v2 shot cannot end in a cut");
91
+ }
92
+ if (end !== 1522)
93
+ throw new Error("incomplete storyboard v2 output coverage");
94
+ for (const value of raw.rejectedCandidates) {
95
+ const candidate = record(value, ["afterWord", "frame", "beatId", "reason", "semanticValue", "cutCost", "pacePenalty", "net"]);
96
+ if (!uint(candidate.afterWord) || candidate.afterWord >= words.length - 1 || !uint(candidate.frame) || candidate.frame > 1522 ||
97
+ !label(candidate.beatId) || !label(candidate.reason) || !finite(candidate.semanticValue) || !finite(candidate.cutCost) ||
98
+ (candidate.pacePenalty !== null && !finite(candidate.pacePenalty)) ||
99
+ (candidate.net !== null && (typeof candidate.net !== "number" || !Number.isFinite(candidate.net))) ||
100
+ ((candidate.pacePenalty === null) !== (candidate.net === null)))
101
+ throw new Error("invalid storyboard v2 rejected candidate");
102
+ }
103
+ const summary = record(raw.scoreBreakdown, ["semanticValue", "cutCost", "pacePenalty", "total", "cuts"]);
104
+ if (!finite(summary.semanticValue) || !finite(summary.cutCost) || !finite(summary.pacePenalty) ||
105
+ typeof summary.total !== "number" || !Number.isFinite(summary.total) || !uint(summary.cuts) ||
106
+ Math.abs(summary.semanticValue - semanticValue) > 1e-8 || Math.abs(summary.cutCost - cutCost) > 1e-8 ||
107
+ Math.abs(summary.pacePenalty - pacePenalty) > 1e-8 || Math.abs(summary.total - total) > 1e-8 || summary.cuts !== cuts) {
108
+ throw new Error("invalid storyboard v2 score breakdown");
109
+ }
110
+ return raw;
111
+ }
112
+ //# sourceMappingURL=faceless-storyboard-v2-plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"faceless-storyboard-v2-plan.js","sourceRoot":"","sources":["../src/faceless-storyboard-v2-plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import { type StoryboardV2Proposal } from "./faceless-storyboard-v2.js";
2
+ import type { CutStyleProfile } from "./faceless-cut-style.js";
3
+ import type { WordTiming } from "./tts-backend.js";
4
+ type Phase = StoryboardV2Proposal["beats"][number]["phase"];
5
+ type Score = {
6
+ semanticValue: number;
7
+ cutCost: number;
8
+ pacePenalty: number;
9
+ net: number;
10
+ };
11
+ export type StoryboardV2FramePlan = {
12
+ version: "faceless_storyboard_61_v2";
13
+ outputFrames: 1522;
14
+ script: string;
15
+ captionPhrases: StoryboardV2Proposal["captionPhrases"];
16
+ narrationStartFrame: number;
17
+ shots: Array<{
18
+ id: string;
19
+ mediaType: "video" | "image";
20
+ startFrame: number;
21
+ endFrame: number;
22
+ beatIds: string[];
23
+ phase: Phase;
24
+ mergedPhases?: Phase[];
25
+ motion?: "PAN_UP" | "PAN_DOWN";
26
+ panExceptionReason?: string;
27
+ cutAfterWord?: number;
28
+ cutReason?: string;
29
+ score: Score;
30
+ }>;
31
+ /** Rejected scores are local incoming-edge estimates, not alternate complete-path scores.
32
+ * Null pacePenalty/net means no feasible incoming edge was reachable. */
33
+ rejectedCandidates: Array<{
34
+ afterWord: number;
35
+ frame: number;
36
+ beatId: string;
37
+ reason: string;
38
+ semanticValue: number;
39
+ cutCost: number;
40
+ pacePenalty: number | null;
41
+ net: number | null;
42
+ }>;
43
+ scoreBreakdown: {
44
+ semanticValue: number;
45
+ cutCost: number;
46
+ pacePenalty: number;
47
+ total: number;
48
+ cuts: number;
49
+ };
50
+ };
51
+ declare const semantic: {
52
+ readonly place: 4;
53
+ readonly reveal: 4;
54
+ readonly action: 3;
55
+ readonly emphasis: 1;
56
+ };
57
+ /** Shared semantic objective; duration feasibility belongs to each profile. */
58
+ export declare function facelessCutScore(reason: keyof typeof semantic | null, duration: number, range: {
59
+ p25: number | null;
60
+ p75: number | null;
61
+ }): Score;
62
+ export declare function planStoryboardV2(input: StoryboardV2Proposal, words: readonly WordTiming[], narrationStartFrame: number, style: CutStyleProfile): StoryboardV2FramePlan;
63
+ export {};
@@ -0,0 +1,143 @@
1
+ import { assertStoryboardWords } from "./faceless-storyboard.js";
2
+ import { parseStoryboardV2 } from "./faceless-storyboard-v2.js";
3
+ const semantic = { place: 4, reveal: 4, action: 3, emphasis: 1 };
4
+ const CUT_COST = 2;
5
+ const OUTPUT_FRAMES = 1522;
6
+ const FPS = 25;
7
+ /** Shared semantic objective; duration feasibility belongs to each profile. */
8
+ export function facelessCutScore(reason, duration, range) {
9
+ const value = reason === null ? 0 : semantic[reason];
10
+ const cost = reason === null ? 0 : CUT_COST;
11
+ const distance = duration < range.p25 ? range.p25 - duration : duration > range.p75 ? duration - range.p75 : 0;
12
+ const penalty = 0.25 * distance / FPS;
13
+ return { semanticValue: value, cutCost: cost, pacePenalty: penalty, net: value - cost - penalty };
14
+ }
15
+ function better(a, b) {
16
+ if (!b)
17
+ return true;
18
+ if (Math.abs(a.total - b.total) > 1e-9)
19
+ return a.total > b.total;
20
+ if (a.cuts !== b.cuts)
21
+ return a.cuts < b.cuts;
22
+ for (let i = 0; i < a.path.length; i++) {
23
+ if (a.path[i] !== b.path[i])
24
+ return a.path[i] < b.path[i];
25
+ }
26
+ return false;
27
+ }
28
+ export function planStoryboardV2(input, words, narrationStartFrame, style) {
29
+ const proposal = parseStoryboardV2(input);
30
+ assertStoryboardWords(proposal.script, words);
31
+ if (!Number.isSafeInteger(narrationStartFrame) || narrationStartFrame < 0 || narrationStartFrame > 50) {
32
+ throw new Error("invalid narration start frame");
33
+ }
34
+ const speechEndFrame = narrationStartFrame + words.at(-1).endSec * FPS;
35
+ if (speechEndFrame > OUTPUT_FRAMES + 1e-9)
36
+ throw new Error("narration exceeds output duration");
37
+ if (OUTPUT_FRAMES - speechEndFrame > 12.5 + 1e-9)
38
+ throw new Error("narration leaves more than 0.5 seconds tail");
39
+ const candidates = proposal.beats.slice(1).map((beat, i) => {
40
+ const afterWord = beat.wordStart - 1;
41
+ const previous = words[afterWord];
42
+ const next = words[afterWord + 1];
43
+ const edgeSec = next.startSec > previous.endSec ? (previous.endSec + next.startSec) / 2 : next.startSec;
44
+ const frame = narrationStartFrame + Math.round(edgeSec * FPS);
45
+ const time = (frame - narrationStartFrame) / FPS;
46
+ const inside = words.some(w => time - w.startSec > 1 / FPS + 1e-9 && w.endSec - time > 1 / FPS + 1e-9);
47
+ return { beatIndex: i + 1, afterWord, frame, reason: beat.reason,
48
+ ...(frame <= 0 || frame >= OUTPUT_FRAMES ? { invalidReason: "candidate lies outside output frames" } : {}),
49
+ ...(inside ? { invalidReason: "candidate lies more than one frame inside a timed word" } : {}) };
50
+ });
51
+ const opener = candidates[0];
52
+ if (opener.invalidReason || opener.frame < 50 || opener.frame > 125) {
53
+ throw new Error(`no feasible storyboard: mandatory VIDEO boundary violates timing${opener.invalidReason ? ` (${opener.invalidReason})` : ""}`);
54
+ }
55
+ const nodes = [...candidates, { beatIndex: proposal.beats.length, afterWord: words.length - 1, frame: OUTPUT_FRAMES, reason: "output end" }];
56
+ const final = nodes.length - 1;
57
+ const states = Array(nodes.length);
58
+ const openerValue = semantic[proposal.beats[1].reason];
59
+ states[0] = { total: openerValue - CUT_COST, semantic: openerValue, cutCost: CUT_COST, pacePenalty: 0,
60
+ cuts: 1, path: [0], previous: -1, edge: { semanticValue: openerValue, cutCost: CUT_COST, pacePenalty: 0, net: openerValue - CUT_COST } };
61
+ function pacePenalty(start, end) {
62
+ const phase = proposal.beats[nodes[start].beatIndex].phase;
63
+ const phaseRange = style.pacing.by_phase[phase];
64
+ const range = phaseRange && phaseRange.n > 0 ? phaseRange : style.pacing.global_image_frames;
65
+ const duration = nodes[end].frame - nodes[start].frame;
66
+ return facelessCutScore(null, duration, range).pacePenalty;
67
+ }
68
+ for (let end = 1; end <= final; end++) {
69
+ const destination = nodes[end];
70
+ if (destination.invalidReason)
71
+ continue;
72
+ const value = end === final ? 0 : semantic[proposal.beats[destination.beatIndex].reason];
73
+ const cost = end === final ? 0 : CUT_COST;
74
+ for (let start = 0; start < end; start++) {
75
+ const prior = states[start];
76
+ if (!prior)
77
+ continue;
78
+ const duration = destination.frame - nodes[start].frame;
79
+ if (duration < 25 || duration > 150)
80
+ continue;
81
+ const penalty = pacePenalty(start, end);
82
+ const edge = { semanticValue: value, cutCost: cost, pacePenalty: penalty, net: value - cost - penalty };
83
+ const next = { total: prior.total + edge.net, semantic: prior.semantic + value,
84
+ cutCost: prior.cutCost + cost, pacePenalty: prior.pacePenalty + penalty,
85
+ cuts: prior.cuts + (end === final ? 0 : 1), path: [...prior.path, end], previous: start, edge };
86
+ if (better(next, states[end]))
87
+ states[end] = next;
88
+ }
89
+ }
90
+ const best = states[final];
91
+ if (!best)
92
+ throw new Error("no feasible storyboard within VIDEO and IMAGE duration bounds");
93
+ const selected = new Set(best.path);
94
+ const shots = [];
95
+ let startFrame = 0;
96
+ let beatStart = 0;
97
+ for (const [shotIndex, nodeIndex] of best.path.entries()) {
98
+ const node = nodes[nodeIndex];
99
+ const current = states[nodeIndex];
100
+ const included = proposal.beats.slice(beatStart, node.beatIndex);
101
+ const phases = [...new Set(included.map(b => b.phase))];
102
+ const holdMotion = style.motion.pan_transition_n > 0 && style.motion.pan_flip_probability !== null && style.motion.pan_flip_probability < 0.5;
103
+ const motion = shotIndex === 0 ? undefined : holdMotion ? "PAN_UP" : shotIndex % 2 === 1 ? "PAN_UP" : "PAN_DOWN";
104
+ shots.push({ id: included[0].id, mediaType: shotIndex === 0 ? "video" : "image", startFrame, endFrame: node.frame,
105
+ beatIds: included.map(b => b.id), phase: included[0].phase,
106
+ ...(phases.length > 1 ? { mergedPhases: phases } : {}),
107
+ ...(motion ? { motion } : {}),
108
+ ...(holdMotion && shotIndex > 1 ? { panExceptionReason: "style profile favors holding PAN direction" } : {}),
109
+ ...(nodeIndex < final ? { cutAfterWord: node.afterWord, cutReason: node.reason } : {}),
110
+ score: current.edge });
111
+ startFrame = node.frame;
112
+ beatStart = node.beatIndex;
113
+ }
114
+ const rejectedCandidates = candidates.flatMap((candidate, index) => {
115
+ if (selected.has(index))
116
+ return [];
117
+ let possiblePenalty = null;
118
+ if (!candidate.invalidReason) {
119
+ for (let start = 0; start < index; start++) {
120
+ if (!states[start])
121
+ continue;
122
+ const duration = candidate.frame - nodes[start].frame;
123
+ if (duration < 25 || duration > 150)
124
+ continue;
125
+ const penalty = pacePenalty(start, index);
126
+ possiblePenalty = possiblePenalty === null ? penalty : Math.min(possiblePenalty, penalty);
127
+ }
128
+ }
129
+ const value = semantic[proposal.beats[candidate.beatIndex].reason];
130
+ const reason = candidate.invalidReason ?? (possiblePenalty === null
131
+ ? "no reachable preceding IMAGE shot within 25–150 frames"
132
+ : value < CUT_COST ? "semantic value does not cover fixed cut cost"
133
+ : "lower total path score or deterministic tie break after IMAGE duration and pace costs");
134
+ return [{ afterWord: candidate.afterWord, frame: candidate.frame, beatId: proposal.beats[candidate.beatIndex].id,
135
+ reason, semanticValue: value, cutCost: CUT_COST, pacePenalty: possiblePenalty,
136
+ net: possiblePenalty === null ? null : value - CUT_COST - possiblePenalty }];
137
+ });
138
+ return { version: proposal.version, outputFrames: OUTPUT_FRAMES, script: proposal.script,
139
+ captionPhrases: proposal.captionPhrases, narrationStartFrame, shots, rejectedCandidates,
140
+ scoreBreakdown: { semanticValue: best.semantic, cutCost: best.cutCost,
141
+ pacePenalty: best.pacePenalty, total: best.total, cuts: best.cuts } };
142
+ }
143
+ //# sourceMappingURL=faceless-storyboard-v2-timing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"faceless-storyboard-v2-timing.js","sourceRoot":"","sources":["../src/faceless-storyboard-v2-timing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { z } from "zod";
2
+ declare const proposal: z.ZodObject<{
3
+ version: z.ZodLiteral<"faceless_storyboard_61_v2">;
4
+ premise: z.ZodString;
5
+ script: z.ZodString;
6
+ provenance: z.ZodDiscriminatedUnion<[z.ZodObject<{
7
+ kind: z.ZodLiteral<"fixture">;
8
+ }, z.core.$strict>, z.ZodObject<{
9
+ kind: z.ZodLiteral<"model">;
10
+ model: z.ZodString;
11
+ promptSha256: z.ZodString;
12
+ responseSha256: z.ZodString;
13
+ }, z.core.$strict>], "kind">;
14
+ beats: z.ZodArray<z.ZodObject<{
15
+ id: z.ZodString;
16
+ wordStart: z.ZodNumber;
17
+ wordEnd: z.ZodNumber;
18
+ reason: z.ZodEnum<{
19
+ action: "action";
20
+ emphasis: "emphasis";
21
+ place: "place";
22
+ reveal: "reveal";
23
+ }>;
24
+ mediaType: z.ZodEnum<{
25
+ image: "image";
26
+ video: "video";
27
+ }>;
28
+ visualPrompt: z.ZodString;
29
+ phase: z.ZodEnum<{
30
+ climax: "climax";
31
+ development: "development";
32
+ resolution: "resolution";
33
+ setup: "setup";
34
+ }>;
35
+ }, z.core.$strict>>;
36
+ captionPhrases: z.ZodArray<z.ZodObject<{
37
+ wordStart: z.ZodNumber;
38
+ wordEnd: z.ZodNumber;
39
+ accentWord: z.ZodNumber;
40
+ }, z.core.$strict>>;
41
+ }, z.core.$strict>;
42
+ export type StoryboardV2Proposal = z.infer<typeof proposal>;
43
+ export declare function parseStoryboardV2(input: unknown): StoryboardV2Proposal;
44
+ export {};
@@ -0,0 +1,43 @@
1
+ import { z } from "zod";
2
+ import { parseStoryboardProposal } from "./faceless-storyboard.js";
3
+ const nonblank = z.string().trim().min(1);
4
+ const index = z.number().int().nonnegative();
5
+ const sha256 = z.string().regex(/^[0-9a-fA-F]{64}$/);
6
+ const phase = z.enum(["setup", "development", "climax", "resolution"]);
7
+ const phaseOrder = { setup: 0, development: 1, climax: 2, resolution: 3 };
8
+ const proposal = z.strictObject({
9
+ version: z.literal("faceless_storyboard_61_v2"),
10
+ premise: nonblank,
11
+ script: nonblank,
12
+ provenance: z.discriminatedUnion("kind", [
13
+ z.strictObject({ kind: z.literal("fixture") }),
14
+ z.strictObject({ kind: z.literal("model"), model: nonblank, promptSha256: sha256, responseSha256: sha256 }),
15
+ ]),
16
+ beats: z.array(z.strictObject({
17
+ id: nonblank, wordStart: index, wordEnd: index,
18
+ reason: z.enum(["action", "place", "reveal", "emphasis"]),
19
+ mediaType: z.enum(["video", "image"]), visualPrompt: nonblank, phase,
20
+ })).min(2),
21
+ captionPhrases: z.array(z.strictObject({ wordStart: index, wordEnd: index, accentWord: index })).min(1),
22
+ });
23
+ export function parseStoryboardV2(input) {
24
+ const parsed = proposal.parse(input);
25
+ const { beats, version: _version, ...v1Fields } = parsed;
26
+ parseStoryboardProposal({
27
+ ...v1Fields,
28
+ version: "faceless_storyboard_61_v1",
29
+ beats: beats.map(({ phase: _phase, ...beat }) => beat),
30
+ });
31
+ if (parsed.provenance.kind === "model") {
32
+ const wordCount = parsed.script.normalize("NFKC").match(/[\p{L}\p{N}\p{M}]+(?:['’][\p{L}\p{N}\p{M}]+)*/gu)?.length ?? 0;
33
+ if (wordCount < 155 || wordCount > 165)
34
+ throw new Error("model storyboard requires 155–165 spoken words");
35
+ }
36
+ for (let i = 1; i < beats.length; i++) {
37
+ if (phaseOrder[beats[i].phase] < phaseOrder[beats[i - 1].phase]) {
38
+ throw new Error("storyboard phases must be ordered");
39
+ }
40
+ }
41
+ return parsed;
42
+ }
43
+ //# sourceMappingURL=faceless-storyboard-v2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"faceless-storyboard-v2.js","sourceRoot":"","sources":["../src/faceless-storyboard-v2.ts"],"names":[],"mappings":"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"}