@skyphusion-labs/vivijure-core 0.9.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.
- package/LICENSE +661 -0
- package/README.md +87 -0
- package/dist/audio-routing.d.ts +2 -0
- package/dist/audio-routing.d.ts.map +1 -0
- package/dist/audio-routing.js +4 -0
- package/dist/audio-routing.js.map +1 -0
- package/dist/audio-stage.d.ts +4 -0
- package/dist/audio-stage.d.ts.map +1 -0
- package/dist/audio-stage.js +25 -0
- package/dist/audio-stage.js.map +1 -0
- package/dist/beat-analyze.d.ts +22 -0
- package/dist/beat-analyze.d.ts.map +1 -0
- package/dist/beat-analyze.js +111 -0
- package/dist/beat-analyze.js.map +1 -0
- package/dist/beat-sync-types.d.ts +33 -0
- package/dist/beat-sync-types.d.ts.map +1 -0
- package/dist/beat-sync-types.js +4 -0
- package/dist/beat-sync-types.js.map +1 -0
- package/dist/bundle-assembler.d.ts +54 -0
- package/dist/bundle-assembler.d.ts.map +1 -0
- package/dist/bundle-assembler.js +376 -0
- package/dist/bundle-assembler.js.map +1 -0
- package/dist/bundle-durations.d.ts +5 -0
- package/dist/bundle-durations.d.ts.map +1 -0
- package/dist/bundle-durations.js +68 -0
- package/dist/bundle-durations.js.map +1 -0
- package/dist/bundle-storyboard.d.ts +11 -0
- package/dist/bundle-storyboard.d.ts.map +1 -0
- package/dist/bundle-storyboard.js +82 -0
- package/dist/bundle-storyboard.js.map +1 -0
- package/dist/captions.d.ts +25 -0
- package/dist/captions.d.ts.map +1 -0
- package/dist/captions.js +56 -0
- package/dist/captions.js.map +1 -0
- package/dist/cast-db.d.ts +61 -0
- package/dist/cast-db.d.ts.map +1 -0
- package/dist/cast-db.js +324 -0
- package/dist/cast-db.js.map +1 -0
- package/dist/cast-lora-train.d.ts +18 -0
- package/dist/cast-lora-train.d.ts.map +1 -0
- package/dist/cast-lora-train.js +215 -0
- package/dist/cast-lora-train.js.map +1 -0
- package/dist/cast-loras.d.ts +21 -0
- package/dist/cast-loras.d.ts.map +1 -0
- package/dist/cast-loras.js +69 -0
- package/dist/cast-loras.js.map +1 -0
- package/dist/clip-content-validate.d.ts +43 -0
- package/dist/clip-content-validate.d.ts.map +1 -0
- package/dist/clip-content-validate.js +115 -0
- package/dist/clip-content-validate.js.map +1 -0
- package/dist/clip-job-model.d.ts +42 -0
- package/dist/clip-job-model.d.ts.map +1 -0
- package/dist/clip-job-model.js +8 -0
- package/dist/clip-job-model.js.map +1 -0
- package/dist/clip-validate.d.ts +33 -0
- package/dist/clip-validate.d.ts.map +1 -0
- package/dist/clip-validate.js +247 -0
- package/dist/clip-validate.js.map +1 -0
- package/dist/d1-retry.d.ts +20 -0
- package/dist/d1-retry.d.ts.map +1 -0
- package/dist/d1-retry.js +67 -0
- package/dist/d1-retry.js.map +1 -0
- package/dist/db-env.d.ts +6 -0
- package/dist/db-env.d.ts.map +1 -0
- package/dist/db-env.js +2 -0
- package/dist/db-env.js.map +1 -0
- package/dist/dialogue-lines.d.ts +23 -0
- package/dist/dialogue-lines.d.ts.map +1 -0
- package/dist/dialogue-lines.js +84 -0
- package/dist/dialogue-lines.js.map +1 -0
- package/dist/film-advance-lease.d.ts +9 -0
- package/dist/film-advance-lease.d.ts.map +1 -0
- package/dist/film-advance-lease.js +19 -0
- package/dist/film-advance-lease.js.map +1 -0
- package/dist/film-model.d.ts +415 -0
- package/dist/film-model.d.ts.map +1 -0
- package/dist/film-model.js +541 -0
- package/dist/film-model.js.map +1 -0
- package/dist/film-orchestrator.d.ts +216 -0
- package/dist/film-orchestrator.d.ts.map +1 -0
- package/dist/film-orchestrator.js +2204 -0
- package/dist/film-orchestrator.js.map +1 -0
- package/dist/film-render-bridge.d.ts +26 -0
- package/dist/film-render-bridge.d.ts.map +1 -0
- package/dist/film-render-bridge.js +176 -0
- package/dist/film-render-bridge.js.map +1 -0
- package/dist/finish-hash.d.ts +10 -0
- package/dist/finish-hash.d.ts.map +1 -0
- package/dist/finish-hash.js +60 -0
- package/dist/finish-hash.js.map +1 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/key-safety.d.ts +5 -0
- package/dist/key-safety.d.ts.map +1 -0
- package/dist/key-safety.js +23 -0
- package/dist/key-safety.js.map +1 -0
- package/dist/lora-bundle.d.ts +19 -0
- package/dist/lora-bundle.d.ts.map +1 -0
- package/dist/lora-bundle.js +75 -0
- package/dist/lora-bundle.js.map +1 -0
- package/dist/lora-keys.d.ts +2 -0
- package/dist/lora-keys.d.ts.map +1 -0
- package/dist/lora-keys.js +4 -0
- package/dist/lora-keys.js.map +1 -0
- package/dist/modules/conformance.d.ts +58 -0
- package/dist/modules/conformance.d.ts.map +1 -0
- package/dist/modules/conformance.js +369 -0
- package/dist/modules/conformance.js.map +1 -0
- package/dist/modules/manifest-validate.d.ts +5 -0
- package/dist/modules/manifest-validate.d.ts.map +1 -0
- package/dist/modules/manifest-validate.js +60 -0
- package/dist/modules/manifest-validate.js.map +1 -0
- package/dist/modules/registry.d.ts +184 -0
- package/dist/modules/registry.d.ts.map +1 -0
- package/dist/modules/registry.js +653 -0
- package/dist/modules/registry.js.map +1 -0
- package/dist/modules/render-pipeline.d.ts +38 -0
- package/dist/modules/render-pipeline.d.ts.map +1 -0
- package/dist/modules/render-pipeline.js +40 -0
- package/dist/modules/render-pipeline.js.map +1 -0
- package/dist/modules/types.d.ts +544 -0
- package/dist/modules/types.d.ts.map +1 -0
- package/dist/modules/types.js +57 -0
- package/dist/modules/types.js.map +1 -0
- package/dist/operator-config.d.ts +20 -0
- package/dist/operator-config.d.ts.map +1 -0
- package/dist/operator-config.js +85 -0
- package/dist/operator-config.js.map +1 -0
- package/dist/output-extract.d.ts +8 -0
- package/dist/output-extract.d.ts.map +1 -0
- package/dist/output-extract.js +129 -0
- package/dist/output-extract.js.map +1 -0
- package/dist/planner-prompt.d.ts +12 -0
- package/dist/planner-prompt.d.ts.map +1 -0
- package/dist/planner-prompt.js +337 -0
- package/dist/planner-prompt.js.map +1 -0
- package/dist/planner-yaml.d.ts +15 -0
- package/dist/planner-yaml.d.ts.map +1 -0
- package/dist/planner-yaml.js +157 -0
- package/dist/planner-yaml.js.map +1 -0
- package/dist/platform/fetcher.d.ts +3 -0
- package/dist/platform/fetcher.d.ts.map +1 -0
- package/dist/platform/fetcher.js +7 -0
- package/dist/platform/fetcher.js.map +1 -0
- package/dist/platform/index.d.ts +6 -0
- package/dist/platform/index.d.ts.map +1 -0
- package/dist/platform/index.js +5 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/object-store-r2.d.ts +26 -0
- package/dist/platform/object-store-r2.d.ts.map +1 -0
- package/dist/platform/object-store-r2.js +74 -0
- package/dist/platform/object-store-r2.js.map +1 -0
- package/dist/platform/orchestrator-context.d.ts +20 -0
- package/dist/platform/orchestrator-context.d.ts.map +1 -0
- package/dist/platform/orchestrator-context.js +28 -0
- package/dist/platform/orchestrator-context.js.map +1 -0
- package/dist/platform/r2-types.d.ts +41 -0
- package/dist/platform/r2-types.d.ts.map +1 -0
- package/dist/platform/r2-types.js +3 -0
- package/dist/platform/r2-types.js.map +1 -0
- package/dist/platform/types.d.ts +90 -0
- package/dist/platform/types.d.ts.map +1 -0
- package/dist/platform/types.js +23 -0
- package/dist/platform/types.js.map +1 -0
- package/dist/preflight.d.ts +57 -0
- package/dist/preflight.d.ts.map +1 -0
- package/dist/preflight.js +243 -0
- package/dist/preflight.js.map +1 -0
- package/dist/presign.d.ts +5 -0
- package/dist/presign.d.ts.map +1 -0
- package/dist/presign.js +24 -0
- package/dist/presign.js.map +1 -0
- package/dist/public-id.d.ts +8 -0
- package/dist/public-id.d.ts.map +1 -0
- package/dist/public-id.js +25 -0
- package/dist/public-id.js.map +1 -0
- package/dist/render-adopt.d.ts +3 -0
- package/dist/render-adopt.d.ts.map +1 -0
- package/dist/render-adopt.js +92 -0
- package/dist/render-adopt.js.map +1 -0
- package/dist/render-log.d.ts +25 -0
- package/dist/render-log.d.ts.map +1 -0
- package/dist/render-log.js +139 -0
- package/dist/render-log.js.map +1 -0
- package/dist/render-module-config.d.ts +28 -0
- package/dist/render-module-config.d.ts.map +1 -0
- package/dist/render-module-config.js +124 -0
- package/dist/render-module-config.js.map +1 -0
- package/dist/render-mux.d.ts +18 -0
- package/dist/render-mux.d.ts.map +1 -0
- package/dist/render-mux.js +69 -0
- package/dist/render-mux.js.map +1 -0
- package/dist/render-orchestrator.d.ts +71 -0
- package/dist/render-orchestrator.d.ts.map +1 -0
- package/dist/render-orchestrator.js +376 -0
- package/dist/render-orchestrator.js.map +1 -0
- package/dist/render-sweep.d.ts +5 -0
- package/dist/render-sweep.d.ts.map +1 -0
- package/dist/render-sweep.js +62 -0
- package/dist/render-sweep.js.map +1 -0
- package/dist/renders-db.d.ts +129 -0
- package/dist/renders-db.d.ts.map +1 -0
- package/dist/renders-db.js +752 -0
- package/dist/renders-db.js.map +1 -0
- package/dist/runpod-submit.d.ts +151 -0
- package/dist/runpod-submit.d.ts.map +1 -0
- package/dist/runpod-submit.js +469 -0
- package/dist/runpod-submit.js.map +1 -0
- package/dist/runpod-types.d.ts +2 -0
- package/dist/runpod-types.d.ts.map +1 -0
- package/dist/runpod-types.js +4 -0
- package/dist/runpod-types.js.map +1 -0
- package/dist/scatter-notify.d.ts +4 -0
- package/dist/scatter-notify.d.ts.map +1 -0
- package/dist/scatter-notify.js +43 -0
- package/dist/scatter-notify.js.map +1 -0
- package/dist/scatter-orchestrator-types.d.ts +56 -0
- package/dist/scatter-orchestrator-types.d.ts.map +1 -0
- package/dist/scatter-orchestrator-types.js +3 -0
- package/dist/scatter-orchestrator-types.js.map +1 -0
- package/dist/scatter-orchestrator.d.ts +70 -0
- package/dist/scatter-orchestrator.d.ts.map +1 -0
- package/dist/scatter-orchestrator.js +614 -0
- package/dist/scatter-orchestrator.js.map +1 -0
- package/dist/scatter.d.ts +35 -0
- package/dist/scatter.d.ts.map +1 -0
- package/dist/scatter.js +171 -0
- package/dist/scatter.js.map +1 -0
- package/dist/secret-store.d.ts +5 -0
- package/dist/secret-store.d.ts.map +1 -0
- package/dist/secret-store.js +19 -0
- package/dist/secret-store.js.map +1 -0
- package/dist/shot-durations-parse.d.ts +3 -0
- package/dist/shot-durations-parse.d.ts.map +1 -0
- package/dist/shot-durations-parse.js +43 -0
- package/dist/shot-durations-parse.js.map +1 -0
- package/dist/srt.d.ts +11 -0
- package/dist/srt.d.ts.map +1 -0
- package/dist/srt.js +54 -0
- package/dist/srt.js.map +1 -0
- package/dist/storyboard-ids.d.ts +2 -0
- package/dist/storyboard-ids.d.ts.map +1 -0
- package/dist/storyboard-ids.js +12 -0
- package/dist/storyboard-ids.js.map +1 -0
- package/dist/storyboard-projects-db.d.ts +31 -0
- package/dist/storyboard-projects-db.d.ts.map +1 -0
- package/dist/storyboard-projects-db.js +153 -0
- package/dist/storyboard-projects-db.js.map +1 -0
- package/dist/storyboard-validate.d.ts +72 -0
- package/dist/storyboard-validate.d.ts.map +1 -0
- package/dist/storyboard-validate.js +595 -0
- package/dist/storyboard-validate.js.map +1 -0
- package/dist/structured-events.d.ts +6 -0
- package/dist/structured-events.d.ts.map +1 -0
- package/dist/structured-events.js +15 -0
- package/dist/structured-events.js.map +1 -0
- package/dist/tar.d.ts +9 -0
- package/dist/tar.d.ts.map +1 -0
- package/dist/tar.js +151 -0
- package/dist/tar.js.map +1 -0
- package/dist/voices.d.ts +12 -0
- package/dist/voices.d.ts.map +1 -0
- package/dist/voices.js +37 -0
- package/dist/voices.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
// Film model: the PURE half of the film orchestrator (S6 god-file split). Everything here is
|
|
2
|
+
// data shapes + synchronous logic with NO Env and NO I/O -- the doc-key builders, phase/summary
|
|
3
|
+
// projections, finish-step retry/adoption/convention logic, assemble transport classification,
|
|
4
|
+
// master-chain state helpers, and the stall math. The orchestrator (film-orchestrator.ts) owns
|
|
5
|
+
// every await; it re-exports this module, so importers and tests keep their one entry point.
|
|
6
|
+
import { validateConfig } from "./modules/registry.js";
|
|
7
|
+
import { summarizeJob } from "./clip-job-model.js";
|
|
8
|
+
import { classifyTransientFailure } from "./render-orchestrator.js";
|
|
9
|
+
import { coerceShotId } from "./storyboard-ids.js";
|
|
10
|
+
const filmKey = (id) => `renders/${id}/film-job.json`;
|
|
11
|
+
const clipDocKey = (clipJobId) => `renders/${clipJobId}/clips-job.json`; // matches render-orchestrator
|
|
12
|
+
export { filmKey as filmJobDocKey, clipDocKey as clipJobDocKey };
|
|
13
|
+
/** Map a film job phase to a shard status string for scatter gather decisions. */
|
|
14
|
+
export function filmPhaseToShardStatus(job) {
|
|
15
|
+
if (job.cancelled)
|
|
16
|
+
return "CANCELLED";
|
|
17
|
+
if (job.phase === "done")
|
|
18
|
+
return "COMPLETED";
|
|
19
|
+
if (job.phase === "failed")
|
|
20
|
+
return "FAILED";
|
|
21
|
+
return "IN_PROGRESS";
|
|
22
|
+
}
|
|
23
|
+
/** Pure: join keyframe outputs to scenes by shot_id. A scene with no matching keyframe is dropped
|
|
24
|
+
* and reported in `missing` (so the caller knows which shots the keyframe stage did not produce). */
|
|
25
|
+
export function joinKeyframesToScenes(scenes, keyframes) {
|
|
26
|
+
const byShot = new Map(keyframes.map((k) => [k.shot_id, k.keyframe_key]));
|
|
27
|
+
const matched = [];
|
|
28
|
+
const missing = [];
|
|
29
|
+
for (const sc of scenes) {
|
|
30
|
+
const key = byShot.get(sc.shot_id);
|
|
31
|
+
if (key)
|
|
32
|
+
matched.push({ shot_id: sc.shot_id, keyframe_key: key, prompt: sc.prompt, seconds: sc.seconds });
|
|
33
|
+
else
|
|
34
|
+
missing.push(sc.shot_id);
|
|
35
|
+
}
|
|
36
|
+
return { matched, missing };
|
|
37
|
+
}
|
|
38
|
+
export function clipDeliveries(clipJob) {
|
|
39
|
+
if (!clipJob)
|
|
40
|
+
return undefined;
|
|
41
|
+
const out = [];
|
|
42
|
+
for (const s of clipJob.shots) {
|
|
43
|
+
if (s.status !== "done" || !s.delivered_fps || !s.delivered_frames)
|
|
44
|
+
continue;
|
|
45
|
+
const entry = {
|
|
46
|
+
shot_id: s.shot_id,
|
|
47
|
+
planned_seconds: s.seconds,
|
|
48
|
+
delivered_seconds: Math.round((s.delivered_frames / s.delivered_fps) * 1000) / 1000,
|
|
49
|
+
fps: s.delivered_fps,
|
|
50
|
+
frames: s.delivered_frames,
|
|
51
|
+
};
|
|
52
|
+
if (typeof s.distilled === "boolean")
|
|
53
|
+
entry.distilled = s.distilled;
|
|
54
|
+
out.push(entry);
|
|
55
|
+
}
|
|
56
|
+
return out.length ? out : undefined;
|
|
57
|
+
}
|
|
58
|
+
export function summarizeFinish(shots) {
|
|
59
|
+
return {
|
|
60
|
+
total: shots.length,
|
|
61
|
+
done: shots.filter((s) => s.status === "done").length,
|
|
62
|
+
failed: shots.filter((s) => s.status === "failed").length,
|
|
63
|
+
pending: shots.filter((s) => s.status === "pending").length,
|
|
64
|
+
adopted: shots.filter((s) => (s.adopted?.length ?? 0) > 0).length, // #583: shots with >=1 finish step reused from R2
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export function summarizeFilm(job, clipJob) {
|
|
68
|
+
return {
|
|
69
|
+
film_id: job.film_id, phase: job.phase, error: job.error,
|
|
70
|
+
clips: clipJob ? summarizeJob(clipJob) : undefined,
|
|
71
|
+
clip_deliveries: clipDeliveries(clipJob),
|
|
72
|
+
finish: job.finish_shots ? summarizeFinish(job.finish_shots) : undefined,
|
|
73
|
+
film_key: job.film_key,
|
|
74
|
+
film_finish: job.film_finish,
|
|
75
|
+
finish_unavailable: job.finish_unavailable,
|
|
76
|
+
keyframes_incomplete: job.keyframes_incomplete,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/** Pure: order a set of finished clips by the storyboard's scene order, keeping only shots that
|
|
80
|
+
* produced a clip. The film must play in scene order regardless of which order the clip/finish
|
|
81
|
+
* stages happened to complete in. A shot with no clip is dropped (it never rendered). */
|
|
82
|
+
export function orderFinalClips(scenes, shots) {
|
|
83
|
+
const byShot = new Map(shots.map((s) => [s.shot_id, s.clip_key]));
|
|
84
|
+
const out = [];
|
|
85
|
+
for (const sc of scenes) {
|
|
86
|
+
const clip_key = byShot.get(sc.shot_id);
|
|
87
|
+
if (clip_key)
|
|
88
|
+
out.push({ shot_id: sc.shot_id, clip_key });
|
|
89
|
+
}
|
|
90
|
+
return out;
|
|
91
|
+
}
|
|
92
|
+
/** Pure: fold one finish module's output into the shot -- chain its output clip into the next module,
|
|
93
|
+
* record what it applied, advance the chain index; status -> done when the chain is exhausted. */
|
|
94
|
+
export function applyFinishOutput(fs, out) {
|
|
95
|
+
fs.clip_key = out.clip_key;
|
|
96
|
+
const tags = out.applied || [];
|
|
97
|
+
fs.applied.push(...tags);
|
|
98
|
+
// #662: account THIS run step in the per-step ledger (chain order), so a done shot's ledger covers the
|
|
99
|
+
// whole chain 1:1. `tags` may be empty (a step that ran but reported no marker); the record still
|
|
100
|
+
// accounts the step -- coverage is per-record, not per-tag.
|
|
101
|
+
(fs.ledger ??= []).push({ binding: fs.chain[fs.idx] ?? "", tags: [...tags], reused: false });
|
|
102
|
+
fs.idx += 1;
|
|
103
|
+
fs.poll = undefined;
|
|
104
|
+
fs.attempts = 0; // a step succeeded -> the next step gets a fresh transient-retry budget
|
|
105
|
+
if (fs.idx >= fs.chain.length)
|
|
106
|
+
fs.status = "done"; // else stays pending; next advance submits chain[idx]
|
|
107
|
+
}
|
|
108
|
+
/** Pure: fold an ADOPTED (reused-from-R2, NOT run this pass) finish-step artifact into the shot. Same
|
|
109
|
+
* chain advance as applyFinishOutput, but the step marker lands in `adopted` (the honest reuse channel)
|
|
110
|
+
* and is NEVER pushed into `applied` -- the record must not claim a run that did not happen (#583).
|
|
111
|
+
* `clip_key` is the adopted artifact key; `tag` is the reconstructed step marker (finishStepAppliedTag). */
|
|
112
|
+
export function adoptFinishStepOutput(fs, clip_key, tag) {
|
|
113
|
+
fs.clip_key = clip_key;
|
|
114
|
+
(fs.adopted ??= []).push(tag);
|
|
115
|
+
// #662: account THIS reused step in the per-step ledger (reused:true), so it is PRESENT in the ledger
|
|
116
|
+
// even though its tag lives in `adopted`, not `applied` -- the fix for the "applied drops one tag" report.
|
|
117
|
+
(fs.ledger ??= []).push({ binding: fs.chain[fs.idx] ?? "", tags: [tag], reused: true });
|
|
118
|
+
fs.idx += 1;
|
|
119
|
+
fs.poll = undefined;
|
|
120
|
+
fs.attempts = 0; // a step advanced -> the next step gets a fresh transient-retry budget
|
|
121
|
+
if (fs.idx >= fs.chain.length)
|
|
122
|
+
fs.status = "done";
|
|
123
|
+
}
|
|
124
|
+
/** Pure: fold one speech module's output into the shot. On a REAL enhancement (no `degraded`), thread the
|
|
125
|
+
* new audio_key forward so the next step (and finish) sees the cleaned audio; on an honest soft-degrade,
|
|
126
|
+
* LEAVE audio_key UNCHANGED (the original audio survives) and record the reason -- no fake applied tag,
|
|
127
|
+
* the chain never fails on a polish miss. Advance idx; done when the chain is exhausted. */
|
|
128
|
+
export function applySpeechOutput(ss, out) {
|
|
129
|
+
if (!out.degraded)
|
|
130
|
+
ss.audio_key = out.audio_key; // real enhance threads forward; a degrade keeps the original
|
|
131
|
+
ss.applied.push(...(out.applied || []));
|
|
132
|
+
if (out.degraded)
|
|
133
|
+
ss.degraded = out.degraded;
|
|
134
|
+
ss.idx += 1;
|
|
135
|
+
ss.poll = undefined;
|
|
136
|
+
ss.attempts = 0;
|
|
137
|
+
if (ss.idx >= ss.chain.length)
|
|
138
|
+
ss.status = "done";
|
|
139
|
+
}
|
|
140
|
+
// Bounded transient-retry for a finish-step invocation/poll failure. shot_02 shipped silent because
|
|
141
|
+
// its lip-sync invocation hit a transient blip (the module worker momentarily unreachable / 5xx --
|
|
142
|
+
// a musetalk cold-start race) and went straight to `failed`, where the mid-chain intermediate was
|
|
143
|
+
// then adopted. Now a TRANSIENT failure re-dispatches the step (status stays `pending`) up to the
|
|
144
|
+
// cap; a DETERMINISTIC reject (a 4xx, a real module error, "job failed", "no clip_key") or the cap
|
|
145
|
+
// exhausted goes `failed` -- loud, no spin. Same classify-then-retry discipline as the D1 / assemble
|
|
146
|
+
// transport retries.
|
|
147
|
+
export const FINISH_STEP_MAX_ATTEMPTS = 3;
|
|
148
|
+
/** Classify an invokeModule / pollModule failure string. Transport shapes are transient:
|
|
149
|
+
* "module /invoke -> 503", "module /poll -> 504", "module unreachable: <timeout/network>". A module-
|
|
150
|
+
* logic ok:false (input reject, "job failed", "no clip_key") or a 4xx is deterministic -> fail. */
|
|
151
|
+
export function classifyFinishFailure(error) {
|
|
152
|
+
// #719 unified classifier lives in render-orchestrator; film-model imports from there (never reverse).
|
|
153
|
+
return classifyTransientFailure(error);
|
|
154
|
+
}
|
|
155
|
+
/** Decide whether to re-dispatch a failed finish step or fail it. Pure so the retry contract is
|
|
156
|
+
* unit-testable without a module fetcher. */
|
|
157
|
+
export function classifyFinishRetry(error, priorAttempts, maxAttempts = FINISH_STEP_MAX_ATTEMPTS) {
|
|
158
|
+
if (classifyFinishFailure(error) !== "transient")
|
|
159
|
+
return { action: "fail" };
|
|
160
|
+
const attempts = (priorAttempts ?? 0) + 1;
|
|
161
|
+
return attempts < maxAttempts ? { action: "retry", attempts } : { action: "fail" };
|
|
162
|
+
}
|
|
163
|
+
/** Pure: resolve the validated config for each finish module, in chain order. Each module gets its
|
|
164
|
+
* config_schema defaults (the contract promises config is "already validated against the module's
|
|
165
|
+
* config_schema"); user overrides are keyed by module NAME (what /api/modules exposes), one hop,
|
|
166
|
+
* same words down. Without this a module receives `{}` and falls back to its do-nothing path, so
|
|
167
|
+
* finish-rife no-op'd in the first e2e (issue #75). */
|
|
168
|
+
export function resolveFinishConfigs(serving, finishConfig) {
|
|
169
|
+
return serving.map((m) => validateConfig(m.config_schema, finishConfig?.[m.name]));
|
|
170
|
+
}
|
|
171
|
+
/** Pure: is this finish shot eligible to be adopted from its R2 artifact? R2 PRESENCE IS AUTHORITATIVE
|
|
172
|
+
* -- if <shot>_finished.mp4 is in R2 the work is done regardless of what the RunPod job envelope says.
|
|
173
|
+
* Two cases are adoptable:
|
|
174
|
+
* - `failed`: a module fast-failed a shot whose finished clip is actually in R2 (the GC'd-job path, #141).
|
|
175
|
+
* - `pending` on its LAST chain module with a submitted poll token: a finish job whose RunPod envelope
|
|
176
|
+
* froze at IN_PROGRESS (worker recycled, /status never flips to COMPLETED) so the poll reports
|
|
177
|
+
* pending forever -- but the finish output already landed in R2. Without this the shot pends to the
|
|
178
|
+
* 90min hard-deadline and FALSE-FAILS a complete render (surfaced by RUN #29; sibling of #141/#142).
|
|
179
|
+
* A `pending` shot mid-chain (idx < last) is NOT adopted: its R2 key would be an intermediate module's
|
|
180
|
+
* output, not the chain's final artifact, so the remaining modules must still run. */
|
|
181
|
+
export function finishShotAdoptableFromR2(fs) {
|
|
182
|
+
// Adopt an R2 clip ONLY when it is the chain's FINAL artifact (idx === last). A mid-chain shot's
|
|
183
|
+
// R2 key is an INTERMEDIATE module's output, so adopting it skips the remaining finish modules
|
|
184
|
+
// (e.g. lip-sync) and ships a half-finished, silent clip. This guard protected the `pending` branch
|
|
185
|
+
// but the `failed` branch lacked it, so a mid-chain module failure adopted the intermediate as
|
|
186
|
+
// "done" -- the silent showcase render (lip-sync failed at idx 1 of 4 -> the RIFE intermediate was
|
|
187
|
+
// adopted). The failed branch is the #141 GC'd-job path: a fast-failed shot whose FINAL clip is in R2.
|
|
188
|
+
if (fs.idx !== fs.chain.length - 1)
|
|
189
|
+
return false;
|
|
190
|
+
if (fs.status === "failed")
|
|
191
|
+
return true;
|
|
192
|
+
return fs.status === "pending" && !!fs.poll;
|
|
193
|
+
}
|
|
194
|
+
/** Pure: adopt every adoptable finish shot whose finished clip is present in R2 (the artifact overrides
|
|
195
|
+
* the module's verdict / a stuck envelope). Mutates `finishShots`, returns the number adopted. Mirrors
|
|
196
|
+
* reclaimClipsFromR2 on the clips leg so the two phases recover symmetrically. */
|
|
197
|
+
export function reclaimFinishShotsFromR2(finishShots, present, modules) {
|
|
198
|
+
let adopted = 0;
|
|
199
|
+
for (const fs of finishShots) {
|
|
200
|
+
if (finishShotAdoptableFromR2(fs) && present.has(fs.shot_id)) {
|
|
201
|
+
fs.clip_key = present.get(fs.shot_id);
|
|
202
|
+
fs.status = "done";
|
|
203
|
+
fs.poll = undefined;
|
|
204
|
+
fs.error = undefined; // the finished artifact in R2 is the source of truth
|
|
205
|
+
// #583 honesty: this shot's FINAL step was REUSED from R2, not run this pass -- disclose it in
|
|
206
|
+
// `adopted` (never a fake `applied`-run tag). finishShotAdoptableFromR2 guarantees idx === last,
|
|
207
|
+
// so the reused marker is the last chain step's tag.
|
|
208
|
+
const tag = finishStepAppliedTag(fs, modules);
|
|
209
|
+
(fs.adopted ??= []).push(tag);
|
|
210
|
+
// #662: account the reused FINAL step (idx === last) in the per-step ledger, completing it to
|
|
211
|
+
// chain.length so the adopted shot's ledger reconciles 1:1 to its chain.
|
|
212
|
+
(fs.ledger ??= []).push({ binding: fs.chain[fs.idx] ?? "", tags: [tag], reused: true });
|
|
213
|
+
adopted += 1;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return adopted;
|
|
217
|
+
}
|
|
218
|
+
/** #662 honesty invariant: does this finish shot's per-step ledger reconcile 1:1 to its chain? True unless
|
|
219
|
+
* a DONE shot has a ledger that fails to cover every chain step in order. Absent ledger (a pre-#662 job
|
|
220
|
+
* doc) or a non-done shot (still advancing, or failed mid-chain with a partial ledger) is NOT asserted.
|
|
221
|
+
* The invariant a DONE shot must hold: every chain step is accounted for exactly once (run or reused), so
|
|
222
|
+
* an adopted shot's ledger never looks like it dropped a step (the #245/#249 honesty-ledger discipline). */
|
|
223
|
+
export function finishShotLedgerReconciles(fs) {
|
|
224
|
+
if (fs.status !== "done" || !fs.ledger)
|
|
225
|
+
return true;
|
|
226
|
+
return fs.ledger.length === fs.chain.length && fs.ledger.every((r, i) => r.binding === fs.chain[i]);
|
|
227
|
+
}
|
|
228
|
+
/** Pure: the R2 key the CURRENT finish step (fs.chain[fs.idx]) is expected to write, given its input
|
|
229
|
+
* clip (fs.clip_key). Mirrors each finish module's OWN output-key convention so the orchestrator can
|
|
230
|
+
* check R2 PRESENCE for a step whose RunPod job was GC'd / froze MID-chain (the #141/#166 R2-authoritative
|
|
231
|
+
* pattern, extended from the final step to any step). The modules: finish-rife writes
|
|
232
|
+
* `<project>/clips/<shot>_finished.mp4` (named off the shot id by its container); the append-convention
|
|
233
|
+
* modules derive `<input-base>_<suffix>.<ext>` from the input clip key (musetalk lip-sync -> `_ls`,
|
|
234
|
+
* upscale -> `_up`; see vivijure-musetalk / vivijure-upscale handler.py). Returns null for a module whose
|
|
235
|
+
* convention we do not model (e.g. text-overlay), so an unmodeled step gets NO R2 shortcut and can never
|
|
236
|
+
* be advanced off a sibling step's artifact -- the mid-chain phantom-adopt the silent-render bug warned of. */
|
|
237
|
+
export function finishStepOutputKey(project, fs, modules) {
|
|
238
|
+
const binding = fs.chain[fs.idx] ?? "";
|
|
239
|
+
// Contract-carried convention first (finish_artifacts, S6): the module DECLARES how it names its
|
|
240
|
+
// output, so the core stops reverse-engineering module internals from the binding name.
|
|
241
|
+
const decl = moduleByBinding(modules, binding)?.finish_artifacts;
|
|
242
|
+
if (decl) {
|
|
243
|
+
if (decl.output_key.kind === "shot_named")
|
|
244
|
+
return `renders/${project}/clips/${fs.shot_id}${decl.output_key.filename}`;
|
|
245
|
+
return insertKeySuffix(fs.clip_key, decl.output_key.suffix);
|
|
246
|
+
}
|
|
247
|
+
// Legacy fallback for module deploys predating finish_artifacts: the shipped modules' conventions,
|
|
248
|
+
// derived from the binding name. Returns null for a module whose convention we do not model, so an
|
|
249
|
+
// unmodeled step gets NO R2 shortcut and can never adopt a sibling step's artifact.
|
|
250
|
+
if (/RIFE/i.test(binding))
|
|
251
|
+
return `renders/${project}/clips/${fs.shot_id}_finished.mp4`;
|
|
252
|
+
const suffix = /LIPSYNC|MUSETALK/i.test(binding) ? "_ls" : /UPSCALE/i.test(binding) ? "_up" : null;
|
|
253
|
+
if (!suffix)
|
|
254
|
+
return null;
|
|
255
|
+
return insertKeySuffix(fs.clip_key, suffix);
|
|
256
|
+
}
|
|
257
|
+
/** Insert an artifact suffix into an R2 key before its extension (`a/b.mp4` + `_ls` -> `a/b_ls.mp4`). */
|
|
258
|
+
function insertKeySuffix(key, suffix) {
|
|
259
|
+
const slash = key.lastIndexOf("/");
|
|
260
|
+
const dotInBase = key.slice(slash + 1).lastIndexOf(".");
|
|
261
|
+
if (dotInBase < 0)
|
|
262
|
+
return `${key}${suffix}`;
|
|
263
|
+
const at = slash + 1 + dotInBase;
|
|
264
|
+
return `${key.slice(0, at)}${suffix}${key.slice(at)}`;
|
|
265
|
+
}
|
|
266
|
+
/** The finish module (if any) whose transport-encoded binding ref serves this chain step. */
|
|
267
|
+
function moduleByBinding(modules, binding) {
|
|
268
|
+
return modules?.find((m) => m.binding === binding);
|
|
269
|
+
}
|
|
270
|
+
/** Resolve a `{knob}` / `{knob|default}` applied-tag template against the step's validated config. */
|
|
271
|
+
function resolveAppliedTemplate(tag, cfg) {
|
|
272
|
+
return tag.replace(/\{([A-Za-z0-9_]+)(?:\|([^}]*))?\}/g, (_all, knob, dflt) => {
|
|
273
|
+
const v = cfg[knob];
|
|
274
|
+
return v === undefined ? (dflt ?? "") : String(v);
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
/** Pure: the `applied` tag the CURRENT finish step would report, reconstructed from its validated config
|
|
278
|
+
* so an R2-adopted step (whose job is gone, so its real response is lost) still carries the marker the
|
|
279
|
+
* verifier and UI read (e.g. `lipsync:v15`, `upscale:2x`, `interpolate:2x`). Mirrors each module's own
|
|
280
|
+
* `applied` string. Unmodeled modules get a `<binding>:r2-adopted` marker so the adoption is never silent. */
|
|
281
|
+
export function finishStepAppliedTag(fs, modules) {
|
|
282
|
+
const binding = fs.chain[fs.idx] ?? "";
|
|
283
|
+
const cfg = (fs.configs?.[fs.idx] ?? {});
|
|
284
|
+
// Contract-carried rules first (finish_artifacts.applied, S6): first matching rule wins; a rule
|
|
285
|
+
// with `when` applies only when the named knob equals its literal.
|
|
286
|
+
const rules = moduleByBinding(modules, binding)?.finish_artifacts?.applied;
|
|
287
|
+
if (rules) {
|
|
288
|
+
for (const rule of rules) {
|
|
289
|
+
if (rule.when && cfg[rule.when.knob] !== rule.when.equals)
|
|
290
|
+
continue;
|
|
291
|
+
return resolveAppliedTemplate(rule.tag, cfg);
|
|
292
|
+
}
|
|
293
|
+
return `${binding}:r2-adopted`; // declared rules, none matched: never silent
|
|
294
|
+
}
|
|
295
|
+
// Legacy fallback (module deploys predating finish_artifacts), binding-name derived.
|
|
296
|
+
if (/LIPSYNC|MUSETALK/i.test(binding))
|
|
297
|
+
return `lipsync:${String(cfg.version ?? "v15")}`;
|
|
298
|
+
if (/UPSCALE/i.test(binding))
|
|
299
|
+
return `upscale:${Number(cfg.scale ?? 2)}x`;
|
|
300
|
+
if (/RIFE/i.test(binding))
|
|
301
|
+
return cfg.interpolate === false ? "noop:interpolate-off" : `interpolate:${Number(cfg.interpolation_factor ?? 2)}x`;
|
|
302
|
+
return `${binding}:r2-adopted`;
|
|
303
|
+
}
|
|
304
|
+
export function classifyAssembleTransport(status, priorAttempts, maxAttempts) {
|
|
305
|
+
const transient = status === null || status === 502 || status === 503 || status === 504;
|
|
306
|
+
if (!transient)
|
|
307
|
+
return { state: "ok", attempts: 0 };
|
|
308
|
+
const attempts = priorAttempts + 1;
|
|
309
|
+
const reason = status === null ? "container unreachable" : `gateway ${status}`;
|
|
310
|
+
if (attempts < maxAttempts) {
|
|
311
|
+
return {
|
|
312
|
+
state: "retry",
|
|
313
|
+
attempts,
|
|
314
|
+
error: `assemble retry ${attempts}/${maxAttempts} (${reason}); clips intact, re-attempting next poll`,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
return {
|
|
318
|
+
state: "exhausted",
|
|
319
|
+
attempts,
|
|
320
|
+
error: `video-finish ${reason} after ${attempts} assemble attempts; clips intact in R2 (reset phase to "assemble" to retry)`,
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
// Bounded transient-retry for a master step, the same discipline as a finish step: a transport blip (the
|
|
324
|
+
// module worker momentarily unreachable / a 5xx) re-dispatches the step under the cap. On EXHAUSTION the
|
|
325
|
+
// step soft-degrades (passthrough) -- it does NOT fail the render, because master is a polish step (#249/#77).
|
|
326
|
+
export const MASTER_STEP_MAX_ATTEMPTS = 3;
|
|
327
|
+
// How long the master phase may sit before a frozen step (a RunPod envelope stuck IN_PROGRESS so /poll
|
|
328
|
+
// pends forever) is soft-degraded to a passthrough and the chain advances. Generous: a CPU master of a
|
|
329
|
+
// few-minute bed is well done by now. NOT a hard FAIL (unlike PHASE_HARD_DEADLINE_SECONDS) -- a stuck
|
|
330
|
+
// polish must degrade to the un-mastered bed and still ship the film, never drop it.
|
|
331
|
+
export const MASTER_STALL_SECONDS = 15 * 60;
|
|
332
|
+
/** Pure: total film length (seconds) from the scenes -- the optional `seconds` hint a master module gets
|
|
333
|
+
* (it probes the bed if absent). Returns undefined for a job with no scene durations. */
|
|
334
|
+
export function filmSeconds(job) {
|
|
335
|
+
const total = (job.scenes || []).reduce((a, s) => a + (Number(s.seconds) || 0), 0);
|
|
336
|
+
return total > 0 ? total : undefined;
|
|
337
|
+
}
|
|
338
|
+
/** Pure: the mastered bed's R2 key -- beside the source with a `_mastered` suffix, so the original
|
|
339
|
+
* survives and each chain step writes a fresh, deterministic key (`renders/p/audio/bed.wav` ->
|
|
340
|
+
* `renders/p/audio/bed_mastered.wav`). The core presigns a PUT for this key and passes it to the master
|
|
341
|
+
* module; the extension is `.wav`, the master config default (the master phase does not thread per-user
|
|
342
|
+
* the planner's master config (so a user-selected mp3 lands on a `.mp3` key the container PUT matches).
|
|
343
|
+
* A deterministic key makes a transient-retry re-PUT idempotent (it overwrites, never orphans). */
|
|
344
|
+
export function masteredBedKey(audioKey, format = "wav") {
|
|
345
|
+
const slash = audioKey.lastIndexOf("/");
|
|
346
|
+
const dot = audioKey.lastIndexOf(".");
|
|
347
|
+
const base = dot > slash ? audioKey.slice(0, dot) : audioKey;
|
|
348
|
+
return `${base}_mastered.${format}`;
|
|
349
|
+
}
|
|
350
|
+
/** Pure: fold one master step's SUCCESS output into the chain state, returning the bed key to carry to
|
|
351
|
+
* the next step (and the mux). Advances idx, resets the step's poll + attempts. `applied` tags
|
|
352
|
+
* accumulate; a module soft-degrade (ok:true + output.degraded -- it passed the bed through because it
|
|
353
|
+
* could not do the work) is recorded against the step binding, so a passthrough is never silent (#77).
|
|
354
|
+
* Returns the input bed unchanged when the module returned no usable audio_key. */
|
|
355
|
+
export function applyMasterOutput(m, prevKey, out) {
|
|
356
|
+
const binding = m.chain[m.idx] ?? "";
|
|
357
|
+
const carried = typeof out.audio_key === "string" && out.audio_key.length > 0 ? out.audio_key : prevKey;
|
|
358
|
+
for (const a of out.applied || [])
|
|
359
|
+
m.applied.push(a);
|
|
360
|
+
if (typeof out.degraded === "string" && out.degraded.length > 0)
|
|
361
|
+
m.degraded.push(`${binding}: ${out.degraded}`);
|
|
362
|
+
m.idx += 1;
|
|
363
|
+
m.poll = undefined;
|
|
364
|
+
m.attempts = 0;
|
|
365
|
+
return carried;
|
|
366
|
+
}
|
|
367
|
+
/** Pure: record a step that could NOT run at all (unbound module, a terminal failure, or a stall) as a
|
|
368
|
+
* soft-degrade and advance the cursor. The bed carries through unchanged -- the render never fails on a
|
|
369
|
+
* master miss (#249 / #77). */
|
|
370
|
+
export function degradeMasterStep(m, reason) {
|
|
371
|
+
const binding = m.chain[m.idx] ?? "";
|
|
372
|
+
m.degraded.push(`${binding}: ${reason}`);
|
|
373
|
+
m.idx += 1;
|
|
374
|
+
m.poll = undefined;
|
|
375
|
+
m.attempts = 0;
|
|
376
|
+
}
|
|
377
|
+
/** Pure: true once every master step has run (or degraded). */
|
|
378
|
+
export function masterChainDone(m) {
|
|
379
|
+
return m.idx >= m.chain.length;
|
|
380
|
+
}
|
|
381
|
+
/** Pure: normalize caller scene ids to the canonical `shot_NN` the bundle uses. /api/storyboard/bundle
|
|
382
|
+
* runs validateStoryboard, which coerces every scene id to `shot_<index+1>` in declaration order --
|
|
383
|
+
* so a caller that supplies its own ids (e.g. the Slate bot's `s1`/`s2`) gets a bundle storyboard
|
|
384
|
+
* whose ids do NOT match the film's shot_ids, and the keyframe stage rejects them
|
|
385
|
+
* (`process_shot_ids not in storyboard`). Coerce here with the SAME function so they line up by
|
|
386
|
+
* position (a valid `shot_NN` survives; anything else is renumbered). */
|
|
387
|
+
export function coerceSceneIds(scenes) {
|
|
388
|
+
return (scenes || []).map((s, i) => ({ ...s, shot_id: coerceShotId(s.shot_id, i) }));
|
|
389
|
+
}
|
|
390
|
+
/** Pure: remap dialogue-line shot ids through the SAME positional coercion coerceSceneIds applies to
|
|
391
|
+
* the scenes, keyed off the ORIGINAL (pre-coercion) scene ids. Without this a caller that supplies
|
|
392
|
+
* its own scene ids (`s1`/`s2`) plus dialogue_lines gets a film whose dialogue map is keyed `s1`
|
|
393
|
+
* while every consumer joins on the coerced `shot_01`: the lip-sync finish step reads no audio_key
|
|
394
|
+
* (noop:no-dialogue), buildCaptionCues yields zero cues, and the film ships silent + uncaptioned
|
|
395
|
+
* even though the TTS ran. A line whose id matches no scene is passed through unchanged (same
|
|
396
|
+
* fail-soft posture as the dialogue stage). Canonical `shot_NN` ids survive coerceShotId, so this
|
|
397
|
+
* is a no-op for the planner UI / scatter paths. */
|
|
398
|
+
export function coerceDialogueLineIds(originalScenes, lines) {
|
|
399
|
+
if (!lines || !lines.length)
|
|
400
|
+
return lines;
|
|
401
|
+
const map = new Map();
|
|
402
|
+
(originalScenes || []).forEach((s, i) => {
|
|
403
|
+
if (s && typeof s.shot_id === "string" && s.shot_id.trim())
|
|
404
|
+
map.set(s.shot_id.trim(), coerceShotId(s.shot_id, i));
|
|
405
|
+
});
|
|
406
|
+
return lines.map((l) => {
|
|
407
|
+
const mapped = l && typeof l.shot_id === "string" ? map.get(l.shot_id.trim()) : undefined;
|
|
408
|
+
return mapped && mapped !== l.shot_id ? { ...l, shot_id: mapped } : l;
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
// --------------------------------------------------------------------------- stall recovery (#129)
|
|
412
|
+
// How long a phase may sit without progress before the driver tries to recover it, and the absolute
|
|
413
|
+
// ceiling past which a still-pollable phase is failed loudly rather than left to hang forever. The
|
|
414
|
+
// background sweep (crons */1) calls advanceFilmJob every minute, so a wedged job is rescued or failed
|
|
415
|
+
// within KEYFRAME_STALL_SECONDS of the GPU finishing -- never the silent forever-IN_PROGRESS of #129.
|
|
416
|
+
// Cause: the keyframe / finish module poll() returns pending for any non-COMPLETED RunPod /status,
|
|
417
|
+
// so once RunPod garbage-collects a finished job the poll is pending with no deadline while the GPU
|
|
418
|
+
// output already sits in R2. The keyframe stage writes deterministic keys
|
|
419
|
+
// (renders/<project>/keyframes/<shot>.png), so the core CAN adopt those orphans without re-running
|
|
420
|
+
// the GPU; clips/finish keys are GPU-assigned (not guessable), so those phases get the loud-fail
|
|
421
|
+
// ceiling only (a stuck clips/finish poll is rarer and re-submitting is the human's call).
|
|
422
|
+
export const KEYFRAME_STALL_SECONDS = 20 * 60; // 20min: a project-wide SDXL keyframe pass is well done by now
|
|
423
|
+
export const PHASE_HARD_DEADLINE_SECONDS = 90 * 60; // 90min: absolute ceiling for any one pollable phase
|
|
424
|
+
export const POLLABLE_PHASES = new Set(["keyframe", "clips", "speech", "finish"]);
|
|
425
|
+
/** Seconds the job has sat in its current phase. Falls back to created_at on pre-#129 jobs (no
|
|
426
|
+
* phase_started_at stamp); `now` is injectable so tests do not depend on the wall clock. */
|
|
427
|
+
export function phaseAgeSeconds(job, now = Date.now()) {
|
|
428
|
+
const since = job.phase_started_at ?? job.created_at;
|
|
429
|
+
return Math.max(0, Math.floor((now - since) / 1000));
|
|
430
|
+
}
|
|
431
|
+
/** The phases that advance one shot at a time inside a single phase (the fan-out phases). These are
|
|
432
|
+
* the phases where a long wall-clock is healthy as long as shots keep landing -- which is why the
|
|
433
|
+
* hard ceiling measures them from last_progress_at, not phase_started_at (#704). */
|
|
434
|
+
export const PER_SHOT_PHASES = new Set(["clips", "speech", "finish"]);
|
|
435
|
+
/** Seconds since the last REAL progress, for the hard-ceiling check (#704). A per-shot phase
|
|
436
|
+
* (clips/speech/finish) on a slow local-gpu card lands one clip every few minutes for hours; that is
|
|
437
|
+
* genuine progress, so the 90min ceiling measures from last_progress_at (re-stamped on every finished
|
|
438
|
+
* shot via filmProgressMarker, #136): a phase that keeps landing shots never dies at the ceiling,
|
|
439
|
+
* while 90min since the LAST landed shot still fails loudly. Batch phases (keyframe) keep the
|
|
440
|
+
* phase_started_at clock: no phase-level progress for the whole window really is wedged (#129).
|
|
441
|
+
* Falls back to phase_started_at (then created_at) on jobs with no last_progress_at stamp. */
|
|
442
|
+
export function ceilingAgeSeconds(job, now = Date.now()) {
|
|
443
|
+
if (!PER_SHOT_PHASES.has(job.phase))
|
|
444
|
+
return phaseAgeSeconds(job, now);
|
|
445
|
+
const since = Math.max(job.phase_started_at ?? job.created_at, job.last_progress_at ?? 0);
|
|
446
|
+
return Math.max(0, Math.floor((now - since) / 1000));
|
|
447
|
+
}
|
|
448
|
+
/** Progress fingerprint for the stall signal (#136): the current phase plus how many of its per-shot
|
|
449
|
+
* units are done. Monotonic within a phase (shots only go pending->done) and it changes on every phase
|
|
450
|
+
* transition, so ANY change is genuine forward progress -- which is what re-stamps last_progress_at.
|
|
451
|
+
* Phases with no per-shot fan-out (keyframe/dialogue/assemble/master/mux) report :0, so their stall
|
|
452
|
+
* window runs from when the phase began, exactly as before. */
|
|
453
|
+
export function filmProgressMarker(job, clipJob) {
|
|
454
|
+
let done = 0;
|
|
455
|
+
if (job.phase === "clips")
|
|
456
|
+
done = (clipJob?.shots || []).filter((s) => s.status === "done").length;
|
|
457
|
+
else if (job.phase === "finish")
|
|
458
|
+
done = (job.finish_shots || []).filter((fs) => fs.status === "done").length;
|
|
459
|
+
else if (job.phase === "speech")
|
|
460
|
+
done = (job.speech_shots || []).filter((ss) => ss.status === "done").length;
|
|
461
|
+
return `${job.phase}:${done}`;
|
|
462
|
+
}
|
|
463
|
+
// --------------------------------------------------------------------------- duration honesty (#697/#698)
|
|
464
|
+
//
|
|
465
|
+
// A per-shot finish chain can deliver a TRUNCATED clip (an outlived/retried encode race adopted a
|
|
466
|
+
// partial write) that the pixel gate (#558) cannot catch -- it validates pixel content, not length. The
|
|
467
|
+
// video-finish container is the one component that downloads + normalizes every final clip, so it is the
|
|
468
|
+
// honest place to probe each clip`s ACTUAL assembled duration and hand it back. The Worker then (a) gates
|
|
469
|
+
// each clip against its PLANNED seconds, failing the render loud instead of shipping a 0.085s "4s" shot,
|
|
470
|
+
// and (b) times caption cues to the ACTUAL cut instead of the bundle plan (#698). One probe, both uses.
|
|
471
|
+
/** Default fraction of a shot`s planned seconds an assembled clip must reach before it is treated as a
|
|
472
|
+
* truncation defect (#697) rather than a legitimate beat-trim. Clamped to [0,1]; a 0 disables the gate. */
|
|
473
|
+
export const DEFAULT_CLIP_DURATION_FLOOR = 0.5;
|
|
474
|
+
/** Pure: parse + clamp the per-shot duration-floor knob (env.FILM_CLIP_DURATION_FLOOR) into [0,1].
|
|
475
|
+
* Unset / non-numeric falls back to the default; out-of-range clamps (never throws). */
|
|
476
|
+
export function resolveClipDurationFloor(raw) {
|
|
477
|
+
const n = raw === undefined || raw === "" ? NaN : Number(raw);
|
|
478
|
+
if (!Number.isFinite(n))
|
|
479
|
+
return DEFAULT_CLIP_DURATION_FLOOR;
|
|
480
|
+
return Math.min(1, Math.max(0, n));
|
|
481
|
+
}
|
|
482
|
+
/** Pure: map the video-finish container`s per-clip `clipDurations` array (same order as the clips it was
|
|
483
|
+
* handed) onto shot ids, using the finalClips order the Worker submitted. Non-numeric / negative / missing
|
|
484
|
+
* entries are dropped so absence never fabricates a duration. Returns {} when the container reported none
|
|
485
|
+
* (an older build) -- callers treat an empty map as "no evidence", never as "all zero". */
|
|
486
|
+
export function mapClipDurationsToShots(finalClips, clipDurations) {
|
|
487
|
+
const out = {};
|
|
488
|
+
if (!Array.isArray(clipDurations))
|
|
489
|
+
return out;
|
|
490
|
+
for (let i = 0; i < finalClips.length; i++) {
|
|
491
|
+
const d = clipDurations[i];
|
|
492
|
+
if (typeof d === "number" && Number.isFinite(d) && d >= 0)
|
|
493
|
+
out[finalClips[i].shot_id] = d;
|
|
494
|
+
}
|
|
495
|
+
return out;
|
|
496
|
+
}
|
|
497
|
+
/** Pure: resolve each shot`s PLANNED seconds -- the bundle`s beat-trimmed target_seconds (preferred),
|
|
498
|
+
* else the authored scene seconds. Only positive values are kept (a plan of 0/unknown cannot gate). This
|
|
499
|
+
* mirrors captions.shotDuration`s resolution so the gate and the cue timeline agree on "the plan". */
|
|
500
|
+
export function resolvePlannedSeconds(scenes, bundleDurations) {
|
|
501
|
+
const out = {};
|
|
502
|
+
for (const s of scenes ?? []) {
|
|
503
|
+
if (!s || typeof s.shot_id !== "string")
|
|
504
|
+
continue;
|
|
505
|
+
const fromBundle = bundleDurations[s.shot_id];
|
|
506
|
+
if (typeof fromBundle === "number" && Number.isFinite(fromBundle) && fromBundle > 0) {
|
|
507
|
+
out[s.shot_id] = fromBundle;
|
|
508
|
+
continue;
|
|
509
|
+
}
|
|
510
|
+
if (typeof s.seconds === "number" && Number.isFinite(s.seconds) && s.seconds > 0)
|
|
511
|
+
out[s.shot_id] = s.seconds;
|
|
512
|
+
}
|
|
513
|
+
return out;
|
|
514
|
+
}
|
|
515
|
+
/** Pure per-shot duration honesty gate (#697). Flags every clip with BOTH a known actual duration and a
|
|
516
|
+
* positive plan whose actual < planned * fraction. A shot with no reported actual (older container) or no
|
|
517
|
+
* positive plan is NOT flagged -- the gate fires on EVIDENCE, never on absence, so it can never fail a
|
|
518
|
+
* film just because a duration was unavailable. A fraction of 0 flags nothing (operator off switch). */
|
|
519
|
+
export function findClipDurationShortfalls(finalClips, actual, planned, fraction) {
|
|
520
|
+
const out = [];
|
|
521
|
+
for (const c of finalClips ?? []) {
|
|
522
|
+
if (!c || typeof c.shot_id !== "string")
|
|
523
|
+
continue;
|
|
524
|
+
const a = actual[c.shot_id];
|
|
525
|
+
const p = planned[c.shot_id];
|
|
526
|
+
if (typeof a !== "number" || !Number.isFinite(a) || typeof p !== "number" || !Number.isFinite(p) || p <= 0)
|
|
527
|
+
continue;
|
|
528
|
+
const floor = p * fraction;
|
|
529
|
+
if (a < floor)
|
|
530
|
+
out.push({ shot_id: c.shot_id, actual: a, planned: p, floor });
|
|
531
|
+
}
|
|
532
|
+
return out;
|
|
533
|
+
}
|
|
534
|
+
/** Pure: build the caption-timeline durations map (#698) -- the ACTUAL assembled per-clip seconds win,
|
|
535
|
+
* the bundle plan fills any shot the container did not report, and captions.shotDuration falls back to
|
|
536
|
+
* the authored scene seconds for anything in neither. This is what times cues to the real cut instead of
|
|
537
|
+
* the plan (which drifts on every non-final tier where actual != planned). */
|
|
538
|
+
export function captionDurations(bundleDurations, actualDurations) {
|
|
539
|
+
return { ...bundleDurations, ...(actualDurations ?? {}) };
|
|
540
|
+
}
|
|
541
|
+
//# sourceMappingURL=film-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"film-model.js","sourceRoot":"","sources":["../src/film-model.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,gGAAgG;AAChG,+FAA+F;AAC/F,+FAA+F;AAC/F,6FAA6F;AAG7F,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAiC,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AA2OnD,MAAM,OAAO,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,WAAW,EAAE,gBAAgB,CAAC;AAC9D,MAAM,UAAU,GAAG,CAAC,SAAiB,EAAE,EAAE,CAAC,WAAW,SAAS,iBAAiB,CAAC,CAAC,8BAA8B;AAE/G,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,UAAU,IAAI,aAAa,EAAE,CAAC;AAEjE,kFAAkF;AAClF,MAAM,UAAU,sBAAsB,CAAC,GAAY;IACjD,IAAI,GAAG,CAAC,SAAS;QAAE,OAAO,WAAW,CAAC;IACtC,IAAI,GAAG,CAAC,KAAK,KAAK,MAAM;QAAE,OAAO,WAAW,CAAC;IAC7C,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC5C,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;sGACsG;AACtG,MAAM,UAAU,qBAAqB,CACnC,MAAmB,EACnB,SAAsD;IAEtD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC1E,MAAM,OAAO,GAAiF,EAAE,CAAC;IACjG,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;QACnC,IAAI,GAAG;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;;YACrG,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC9B,CAAC;AAmBD,MAAM,UAAU,cAAc,CAAC,OAAuB;IACpD,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAC9B,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,gBAAgB;YAAE,SAAS;QAC7E,MAAM,KAAK,GAAiB;YAC1B,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,eAAe,EAAE,CAAC,CAAC,OAAO;YAC1B,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI;YACnF,GAAG,EAAE,CAAC,CAAC,aAAa;YACpB,MAAM,EAAE,CAAC,CAAC,gBAAgB;SAC3B,CAAC;QACF,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,SAAS;YAAE,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC;QACpE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AACtC,CAAC;AAuBD,MAAM,UAAU,eAAe,CAAC,KAAmB;IACjD,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM;QACrD,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,MAAM;QACzD,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM;QAC3D,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,kDAAkD;KACtH,CAAC;AACJ,CAAC;AACD,MAAM,UAAU,aAAa,CAAC,GAAY,EAAE,OAAuB;IACjE,OAAO;QACL,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK;QACxD,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;QAClD,eAAe,EAAE,cAAc,CAAC,OAAO,CAAC;QACxC,MAAM,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS;QACxE,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,kBAAkB,EAAE,GAAG,CAAC,kBAAkB;QAC1C,oBAAoB,EAAE,GAAG,CAAC,oBAAoB;KAC/C,CAAC;AACJ,CAAC;AAED;;0FAE0F;AAC1F,MAAM,UAAU,eAAe,CAC7B,MAAmB,EACnB,KAA8C;IAE9C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAClE,MAAM,GAAG,GAA4C,EAAE,CAAC;IACxD,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;QACxB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,QAAQ;YAAE,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;mGACmG;AACnG,MAAM,UAAU,iBAAiB,CAAC,EAAc,EAAE,GAAiB;IACjE,EAAE,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;IAC/B,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IACzB,uGAAuG;IACvG,kGAAkG;IAClG,4DAA4D;IAC5D,CAAC,EAAE,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7F,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IACZ,EAAE,CAAC,IAAI,GAAG,SAAS,CAAC;IACpB,EAAE,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,wEAAwE;IACzF,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,MAAM;QAAE,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,sDAAsD;AAC3G,CAAC;AAED;;;6GAG6G;AAC7G,MAAM,UAAU,qBAAqB,CAAC,EAAc,EAAE,QAAgB,EAAE,GAAW;IACjF,EAAE,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACvB,CAAC,EAAE,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9B,sGAAsG;IACtG,2GAA2G;IAC3G,CAAC,EAAE,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACxF,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IACZ,EAAE,CAAC,IAAI,GAAG,SAAS,CAAC;IACpB,EAAE,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,uEAAuE;IACxF,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,MAAM;QAAE,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC;AACpD,CAAC;AAED;;;6FAG6F;AAC7F,MAAM,UAAU,iBAAiB,CAAC,EAAc,EAAE,GAAiB;IACjE,IAAI,CAAC,GAAG,CAAC,QAAQ;QAAE,EAAE,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,6DAA6D;IAC9G,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;IACxC,IAAI,GAAG,CAAC,QAAQ;QAAE,EAAE,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC7C,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IACZ,EAAE,CAAC,IAAI,GAAG,SAAS,CAAC;IACpB,EAAE,CAAC,QAAQ,GAAG,CAAC,CAAC;IAChB,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,MAAM;QAAE,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC;AACpD,CAAC;AAED,oGAAoG;AACpG,mGAAmG;AACnG,kGAAkG;AAClG,kGAAkG;AAClG,mGAAmG;AACnG,qGAAqG;AACrG,qBAAqB;AACrB,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAE1C;;oGAEoG;AACpG,MAAM,UAAU,qBAAqB,CAAC,KAAyB;IAC7D,uGAAuG;IACvG,OAAO,wBAAwB,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC;AAED;8CAC8C;AAC9C,MAAM,UAAU,mBAAmB,CACjC,KAAyB,EACzB,aAAqB,EACrB,WAAW,GAAW,wBAAwB;IAE9C,IAAI,qBAAqB,CAAC,KAAK,CAAC,KAAK,WAAW;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAC5E,MAAM,QAAQ,GAAG,CAAC,aAAa,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC1C,OAAO,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACrF,CAAC;AAED;;;;wDAIwD;AACxD,MAAM,UAAU,oBAAoB,CAClC,OAAyD,EACzD,YAAiE;IAEjE,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACrF,CAAC;AAED;;;;;;;;;uFASuF;AACvF,MAAM,UAAU,yBAAyB,CAAC,EAAc;IACtD,iGAAiG;IACjG,+FAA+F;IAC/F,oGAAoG;IACpG,+FAA+F;IAC/F,mGAAmG;IACnG,uGAAuG;IACvG,IAAI,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACjD,IAAI,EAAE,CAAC,MAAM,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACxC,OAAO,EAAE,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC;AAC9C,CAAC;AAED;;mFAEmF;AACnF,MAAM,UAAU,wBAAwB,CAAC,WAAyB,EAAE,OAA4B,EAAE,OAA4B;IAC5H,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;QAC7B,IAAI,yBAAyB,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7D,EAAE,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAW,CAAC;YAChD,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC;YACnB,EAAE,CAAC,IAAI,GAAG,SAAS,CAAC;YACpB,EAAE,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC,qDAAqD;YAC3E,+FAA+F;YAC/F,iGAAiG;YACjG,qDAAqD;YACrD,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;YAC9C,CAAC,EAAE,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC9B,8FAA8F;YAC9F,yEAAyE;YACzE,CAAC,EAAE,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YACxF,OAAO,IAAI,CAAC,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;6GAI6G;AAC7G,MAAM,UAAU,0BAA0B,CAAC,EAAc;IACvD,IAAI,EAAE,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACpD,OAAO,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACtG,CAAC;AAED;;;;;;;;gHAQgH;AAChH,MAAM,UAAU,mBAAmB,CAAC,OAAe,EAAE,EAAc,EAAE,OAA4B;IAC/F,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IACvC,iGAAiG;IACjG,wFAAwF;IACxF,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,gBAAgB,CAAC;IACjE,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,KAAK,YAAY;YAAE,OAAO,WAAW,OAAO,UAAU,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;QACtH,OAAO,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC9D,CAAC;IACD,mGAAmG;IACnG,mGAAmG;IACnG,oFAAoF;IACpF,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,WAAW,OAAO,UAAU,EAAE,CAAC,OAAO,eAAe,CAAC;IACxF,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IACnG,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,OAAO,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC9C,CAAC;AAED,yGAAyG;AACzG,SAAS,eAAe,CAAC,GAAW,EAAE,MAAc;IAClD,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACxD,IAAI,SAAS,GAAG,CAAC;QAAE,OAAO,GAAG,GAAG,GAAG,MAAM,EAAE,CAAC;IAC5C,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC;IACjC,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;AACxD,CAAC;AAED,6FAA6F;AAC7F,SAAS,eAAe,CAAC,OAAuC,EAAE,OAAe;IAC/E,OAAO,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;AACrD,CAAC;AAED,sGAAsG;AACtG,SAAS,sBAAsB,CAAC,GAAW,EAAE,GAA4B;IACvE,OAAO,GAAG,CAAC,OAAO,CAAC,oCAAoC,EAAE,CAAC,IAAI,EAAE,IAAY,EAAE,IAAwB,EAAE,EAAE;QACxG,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;QACpB,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;+GAG+G;AAC/G,MAAM,UAAU,oBAAoB,CAAC,EAAc,EAAE,OAA4B;IAC/E,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IACvC,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAA4B,CAAC;IACpE,gGAAgG;IAChG,mEAAmE;IACnE,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,gBAAgB,EAAE,OAAO,CAAC;IAC3E,IAAI,KAAK,EAAE,CAAC;QACV,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM;gBAAE,SAAS;YACpE,OAAO,sBAAsB,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,GAAG,OAAO,aAAa,CAAC,CAAC,6CAA6C;IAC/E,CAAC;IACD,qFAAqF;IACrF,IAAI,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,WAAW,MAAM,CAAC,GAAG,CAAC,OAAO,IAAI,KAAK,CAAC,EAAE,CAAC;IACxF,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,WAAW,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC;IAC1E,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,GAAG,CAAC,WAAW,KAAK,KAAK,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,eAAe,MAAM,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,CAAC,GAAG,CAAC;IAC/I,OAAO,GAAG,OAAO,aAAa,CAAC;AACjC,CAAC;AAoBD,MAAM,UAAU,yBAAyB,CACvC,MAAqB,EACrB,aAAqB,EACrB,WAAmB;IAEnB,MAAM,SAAS,GAAG,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,CAAC;IACxF,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACpD,MAAM,QAAQ,GAAG,aAAa,GAAG,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,WAAW,MAAM,EAAE,CAAC;IAC/E,IAAI,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC3B,OAAO;YACL,KAAK,EAAE,OAAO;YACd,QAAQ;YACR,KAAK,EAAE,kBAAkB,QAAQ,IAAI,WAAW,KAAK,MAAM,0CAA0C;SACtG,CAAC;IACJ,CAAC;IACD,OAAO;QACL,KAAK,EAAE,WAAW;QAClB,QAAQ;QACR,KAAK,EAAE,gBAAgB,MAAM,UAAU,QAAQ,6EAA6E;KAC7H,CAAC;AACJ,CAAC;AAQD,yGAAyG;AACzG,yGAAyG;AACzG,+GAA+G;AAC/G,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAE1C,uGAAuG;AACvG,uGAAuG;AACvG,sGAAsG;AACtG,qFAAqF;AACrF,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,GAAG,EAAE,CAAC;AAE5C;0FAC0F;AAC1F,MAAM,UAAU,WAAW,CAAC,GAA4B;IACtD,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnF,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACvC,CAAC;AAED;;;;;oGAKoG;AACpG,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,MAAM,GAAkB,KAAK;IAC5E,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC7D,OAAO,GAAG,IAAI,aAAa,MAAM,EAAE,CAAC;AACtC,CAAC;AAED;;;;oFAIoF;AACpF,MAAM,UAAU,iBAAiB,CAAC,CAAc,EAAE,OAAe,EAAE,GAAiB;IAClF,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IACrC,MAAM,OAAO,GAAG,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,IAAI,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;IACxG,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,OAAO,IAAI,EAAE;QAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrD,IAAI,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,KAAK,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IAChH,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACX,CAAC,CAAC,IAAI,GAAG,SAAS,CAAC;IACnB,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC;IACf,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;gCAEgC;AAChC,MAAM,UAAU,iBAAiB,CAAC,CAAc,EAAE,MAAc;IAC9D,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IACrC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,KAAK,MAAM,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACX,CAAC,CAAC,IAAI,GAAG,SAAS,CAAC;IACnB,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC;AACjB,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,eAAe,CAAC,CAAc;IAC5C,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;AACjC,CAAC;AAED;;;;;0EAK0E;AAC1E,MAAM,UAAU,cAAc,CAAC,MAAmB;IAChD,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACvF,CAAC;AAED;;;;;;;qDAOqD;AACrD,MAAM,UAAU,qBAAqB,CAAC,cAA2B,EAAE,KAAiC;IAClG,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1C,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACtC,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE;YAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IACpH,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACrB,MAAM,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1F,OAAO,MAAM,IAAI,MAAM,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,oGAAoG;AAEpG,oGAAoG;AACpG,mGAAmG;AACnG,uGAAuG;AACvG,sGAAsG;AACtG,qGAAqG;AACrG,sGAAsG;AACtG,4EAA4E;AAC5E,qGAAqG;AACrG,mGAAmG;AACnG,6FAA6F;AAC7F,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,+DAA+D;AAC9G,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,qDAAqD;AAEzG,MAAM,CAAC,MAAM,eAAe,GAAkC,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAEjH;6FAC6F;AAC7F,MAAM,UAAU,eAAe,CAAC,GAAY,EAAE,GAAG,GAAW,IAAI,CAAC,GAAG,EAAE;IACpE,MAAM,KAAK,GAAG,GAAG,CAAC,gBAAgB,IAAI,GAAG,CAAC,UAAU,CAAC;IACrD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AACvD,CAAC;AAED;;qFAEqF;AACrF,MAAM,CAAC,MAAM,eAAe,GAAkC,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAErG;;;;;;+FAM+F;AAC/F,MAAM,UAAU,iBAAiB,CAAC,GAAY,EAAE,GAAG,GAAW,IAAI,CAAC,GAAG,EAAE;IACtE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,OAAO,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACtE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAgB,IAAI,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,gBAAgB,IAAI,CAAC,CAAC,CAAC;IAC1F,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AACvD,CAAC;AAED;;;;gEAIgE;AAChE,MAAM,UAAU,kBAAkB,CAAC,GAAY,EAAE,OAAuB;IACtE,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,GAAG,CAAC,KAAK,KAAK,OAAO;QAAE,IAAI,GAAG,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;SAC9F,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ;QAAE,IAAI,GAAG,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;SACxG,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ;QAAE,IAAI,GAAG,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IAC7G,OAAO,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;AAChC,CAAC;AAED,2GAA2G;AAC3G,EAAE;AACF,kGAAkG;AAClG,wGAAwG;AACxG,yGAAyG;AACzG,0GAA0G;AAC1G,yGAAyG;AACzG,wGAAwG;AAExG;4GAC4G;AAC5G,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAC;AAE/C;yFACyF;AACzF,MAAM,UAAU,wBAAwB,CAAC,GAAuB;IAC9D,MAAM,CAAC,GAAG,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC9D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,2BAA2B,CAAC;IAC5D,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AAED;;;4FAG4F;AAC5F,MAAM,UAAU,uBAAuB,CACrC,UAAiC,EACjC,aAAsB;IAEtB,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC;QAAE,OAAO,GAAG,CAAC;IAC9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;uGAEuG;AACvG,MAAM,UAAU,qBAAqB,CACnC,MAA8C,EAC9C,eAAuC;IAEvC,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,MAAM,IAAI,EAAE,EAAE,CAAC;QAC7B,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ;YAAE,SAAS;QAClD,MAAM,UAAU,GAAG,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,UAAU,CAAC;YAAC,SAAS;QAAC,CAAC;QAC/H,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,GAAG,CAAC;YAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;IAC/G,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAUD;;;yGAGyG;AACzG,MAAM,UAAU,0BAA0B,CACxC,UAAiC,EACjC,MAA8B,EAC9B,OAA+B,EAC/B,QAAgB;IAEhB,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC;QACjC,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ;YAAE,SAAS;QAClD,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC5B,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC7B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QACrH,MAAM,KAAK,GAAG,CAAC,GAAG,QAAQ,CAAC;QAC3B,IAAI,CAAC,GAAG,KAAK;YAAE,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;+EAG+E;AAC/E,MAAM,UAAU,gBAAgB,CAC9B,eAAuC,EACvC,eAAwC;IAExC,OAAO,EAAE,GAAG,eAAe,EAAE,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,EAAE,CAAC;AAC5D,CAAC"}
|