videobook 0.0.0-stage → 0.2.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 (565) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/LICENSE +21 -0
  3. package/README.md +195 -2
  4. package/bin/videobook.js +7 -0
  5. package/dist/acestep/client.js +203 -0
  6. package/dist/acestep/config.js +62 -0
  7. package/dist/acestep/errors.js +8 -0
  8. package/dist/acestep/process.js +175 -0
  9. package/dist/alive-captions/analyze.js +117 -0
  10. package/dist/alive-captions/audio.js +179 -0
  11. package/dist/alive-captions/frames.js +59 -0
  12. package/dist/alive-captions/model.js +37 -0
  13. package/dist/alive-captions/schema.js +49 -0
  14. package/dist/alive-captions/track.js +9 -0
  15. package/dist/api-key.js +33 -0
  16. package/dist/app-state.js +56 -0
  17. package/dist/app.js +257 -0
  18. package/dist/archive-b2.js +332 -0
  19. package/dist/archive-store.js +169 -0
  20. package/dist/artifact-label.js +36 -0
  21. package/dist/artifact-refs.js +49 -0
  22. package/dist/asset-tag-extraction.js +169 -0
  23. package/dist/asset-tags.js +228 -0
  24. package/dist/asset-usage.js +23 -0
  25. package/dist/audio-cue.js +71 -0
  26. package/dist/audio-encoding.js +32 -0
  27. package/dist/audio-sync-request.js +1 -0
  28. package/dist/audio-sync.js +223 -0
  29. package/dist/audio-trim-range.js +31 -0
  30. package/dist/book-context.js +31 -0
  31. package/dist/book-manager.js +374 -0
  32. package/dist/catalog-gc.js +26 -0
  33. package/dist/chain-executor.js +815 -0
  34. package/dist/chain-generation.js +115 -0
  35. package/dist/chain-plan.js +746 -0
  36. package/dist/chain-step-review.js +60 -0
  37. package/dist/character-name.js +25 -0
  38. package/dist/chat-generation-routing.js +73 -0
  39. package/dist/chat-generation-settings.js +78 -0
  40. package/dist/chat-models.js +44 -0
  41. package/dist/chat-prompt-rewrite.js +67 -0
  42. package/dist/chat-router.js +628 -0
  43. package/dist/chat-view-actions.js +49 -0
  44. package/dist/cli/args.js +242 -0
  45. package/dist/cli/config-command.js +103 -0
  46. package/dist/cli/doctor-command.js +289 -0
  47. package/dist/cli/entry.js +2 -0
  48. package/dist/cli/key-report.js +16 -0
  49. package/dist/cli/main.js +104 -0
  50. package/dist/cli/mcp-command.js +88 -0
  51. package/dist/cli/mcp-relay.js +51 -0
  52. package/dist/cli/open-browser.js +14 -0
  53. package/dist/cli/run-command.js +231 -0
  54. package/dist/cli/serve-command.js +62 -0
  55. package/dist/cli/setup-command.js +60 -0
  56. package/dist/cli/stdio-guard.js +8 -0
  57. package/dist/cold-open-model.js +7 -0
  58. package/dist/cold-open.js +79 -0
  59. package/dist/command-reference.js +95 -0
  60. package/dist/content-store.js +74 -0
  61. package/dist/cost.js +8 -0
  62. package/dist/crop-geometry.js +23 -0
  63. package/dist/dancing-workflow.js +447 -0
  64. package/dist/data-home.js +44 -0
  65. package/dist/diagnostics.js +109 -0
  66. package/dist/dialog-quality.js +34 -0
  67. package/dist/downloads-dest.js +56 -0
  68. package/dist/editing-moments.js +194 -0
  69. package/dist/elevenlabs-audio-extension.js +66 -0
  70. package/dist/engine.js +54 -0
  71. package/dist/env-file.js +91 -0
  72. package/dist/env-secrets.js +148 -0
  73. package/dist/ffmpeg-binary.js +12 -0
  74. package/dist/ffmpeg.js +425 -0
  75. package/dist/ffprobe-binary.js +77 -0
  76. package/dist/forget-asset.js +216 -0
  77. package/dist/frame-utils.js +27 -0
  78. package/dist/generation-credit-error.js +11 -0
  79. package/dist/generation-input-mentions.js +117 -0
  80. package/dist/generation-input-policy.js +68 -0
  81. package/dist/generation-reference-mentions.js +97 -0
  82. package/dist/goal-characters.js +49 -0
  83. package/dist/goal-plan-v3.js +273 -0
  84. package/dist/goal-plan.js +220 -0
  85. package/dist/goal-planner-prompt.js +28 -0
  86. package/dist/goal-prompt-budget.js +4 -0
  87. package/dist/goal-reference-images.js +25 -0
  88. package/dist/goal-state.js +261 -0
  89. package/dist/goal-stills.js +153 -0
  90. package/dist/goal-store.js +144 -0
  91. package/dist/goal-styles.js +144 -0
  92. package/dist/goal-v3-runtime.js +157 -0
  93. package/dist/guides/character_schema_guide.md +70 -0
  94. package/dist/guides/gpt_image_2_5_prompting_guide.md +21 -0
  95. package/dist/guides/grok_imagine_prompting_guide.md +72 -0
  96. package/dist/guides/image_reproduction_guide.md +84 -0
  97. package/dist/guides/kling_3_0_prompting_guide.md +136 -0
  98. package/dist/guides/nano_banana_pro_prompting_guide.md +28 -0
  99. package/dist/guides/seedance_2_prompting_guide.md +172 -0
  100. package/dist/http-access.js +49 -0
  101. package/dist/http-byte-range.js +31 -0
  102. package/dist/hydration.js +56 -0
  103. package/dist/image-compress.js +77 -0
  104. package/dist/image-edit-default.js +1 -0
  105. package/dist/image-edit-models.js +41 -0
  106. package/dist/image-edit-settings.js +11 -0
  107. package/dist/image-region-edit.js +32 -0
  108. package/dist/image-subject-map.js +523 -0
  109. package/dist/image.js +46 -0
  110. package/dist/index.js +12 -0
  111. package/dist/job-deadline.js +60 -0
  112. package/dist/jobs/_alibaba-upload.js +30 -0
  113. package/dist/jobs/_audio-chunks.js +31 -0
  114. package/dist/jobs/_download-into-asset.js +15 -0
  115. package/dist/jobs/_fal-shared.js +22 -0
  116. package/dist/jobs/_fal-upload.js +35 -0
  117. package/dist/jobs/_image-edit-adapter.js +213 -0
  118. package/dist/jobs/_kie-poll.js +119 -0
  119. package/dist/jobs/_kie-upload.js +32 -0
  120. package/dist/jobs/_lease.js +163 -0
  121. package/dist/jobs/_persist-output.js +19 -0
  122. package/dist/jobs/_storage-retry.js +21 -0
  123. package/dist/jobs/_transcribe.js +245 -0
  124. package/dist/jobs/_translate-transcript.js +270 -0
  125. package/dist/jobs/analyze-alive-captions.js +10 -0
  126. package/dist/jobs/analyze-editing-moments.js +104 -0
  127. package/dist/jobs/analyze-jokes.js +143 -0
  128. package/dist/jobs/analyze-keyword-placement.js +155 -0
  129. package/dist/jobs/analyze-music.js +14 -0
  130. package/dist/jobs/analyze-video.js +282 -0
  131. package/dist/jobs/apply-cuts.js +83 -0
  132. package/dist/jobs/apply-sfx.js +107 -0
  133. package/dist/jobs/archive-clip.js +458 -0
  134. package/dist/jobs/assemble-goal.js +98 -0
  135. package/dist/jobs/audio-boost.js +71 -0
  136. package/dist/jobs/audio-mix.js +161 -0
  137. package/dist/jobs/backfill-asset-tags.js +144 -0
  138. package/dist/jobs/burn-watermark.js +316 -0
  139. package/dist/jobs/change-video-speed.js +176 -0
  140. package/dist/jobs/clean-video-audio.js +207 -0
  141. package/dist/jobs/cold-open.js +166 -0
  142. package/dist/jobs/combine-goal.js +108 -0
  143. package/dist/jobs/complete-provider-task.js +185 -0
  144. package/dist/jobs/copy-library-asset.js +33 -0
  145. package/dist/jobs/cost-estimate-assessment.js +113 -0
  146. package/dist/jobs/crop-image.js +47 -0
  147. package/dist/jobs/crop-video.js +71 -0
  148. package/dist/jobs/describe-image.js +181 -0
  149. package/dist/jobs/detect-scenes.js +33 -0
  150. package/dist/jobs/doctor-fix.js +100 -0
  151. package/dist/jobs/download-video.js +427 -0
  152. package/dist/jobs/enqueue-search-index.js +24 -0
  153. package/dist/jobs/even-split.js +122 -0
  154. package/dist/jobs/export-sequence.js +365 -0
  155. package/dist/jobs/extend-audio.js +229 -0
  156. package/dist/jobs/extract-audio.js +72 -0
  157. package/dist/jobs/extract-frame.js +58 -0
  158. package/dist/jobs/extract-notebook-audio.js +82 -0
  159. package/dist/jobs/extract-notebook-frame.js +93 -0
  160. package/dist/jobs/extract-video-clip.js +8 -0
  161. package/dist/jobs/extract-video-poster.js +55 -0
  162. package/dist/jobs/extract-waveform.js +25 -0
  163. package/dist/jobs/finish-goal.js +255 -0
  164. package/dist/jobs/forget-asset.js +11 -0
  165. package/dist/jobs/generate-acestep-cover.js +219 -0
  166. package/dist/jobs/generate-media.js +70 -0
  167. package/dist/jobs/image-subjects.js +1059 -0
  168. package/dist/jobs/index.js +18 -0
  169. package/dist/jobs/inject-first-frame.js +175 -0
  170. package/dist/jobs/isolate-vocals.js +69 -0
  171. package/dist/jobs/kie-paygate.js +177 -0
  172. package/dist/jobs/label-music-sections.js +5 -0
  173. package/dist/jobs/osg-placement.js +135 -0
  174. package/dist/jobs/pad-video.js +72 -0
  175. package/dist/jobs/plan-goal.js +97 -0
  176. package/dist/jobs/post-record.js +21 -0
  177. package/dist/jobs/post-to-x.js +21 -0
  178. package/dist/jobs/prepare-search-reference.js +190 -0
  179. package/dist/jobs/prepare-temporal-search.js +16 -0
  180. package/dist/jobs/process-audio.js +67 -0
  181. package/dist/jobs/process-image.js +58 -0
  182. package/dist/jobs/process-upload.js +166 -0
  183. package/dist/jobs/process-video.js +438 -0
  184. package/dist/jobs/register-all.js +161 -0
  185. package/dist/jobs/relayout-notebook.js +78 -0
  186. package/dist/jobs/remove-sound.js +299 -0
  187. package/dist/jobs/render-project.js +380 -0
  188. package/dist/jobs/render-qr-outro.js +138 -0
  189. package/dist/jobs/render-timeline.js +283 -0
  190. package/dist/jobs/repair-search-indexes.js +42 -0
  191. package/dist/jobs/replace-video-audio.js +64 -0
  192. package/dist/jobs/restore-archive-clip.js +53 -0
  193. package/dist/jobs/reverse-video.js +53 -0
  194. package/dist/jobs/rewrite-script.js +173 -0
  195. package/dist/jobs/run-notebook.js +3335 -0
  196. package/dist/jobs/semantic-index.js +797 -0
  197. package/dist/jobs/smooth-scene-concat.js +257 -0
  198. package/dist/jobs/splice-video.js +280 -0
  199. package/dist/jobs/split-video.js +127 -0
  200. package/dist/jobs/suggest-cuts.js +149 -0
  201. package/dist/jobs/suggest-sfx.js +135 -0
  202. package/dist/jobs/sync-video-to-audio.js +329 -0
  203. package/dist/jobs/tag-asset.js +266 -0
  204. package/dist/jobs/task-failure.js +16 -0
  205. package/dist/jobs/timewarp-video.js +152 -0
  206. package/dist/jobs/transcribe-video-audio.js +117 -0
  207. package/dist/jobs/transcribe.js +35 -0
  208. package/dist/jobs/translate-transcript.js +55 -0
  209. package/dist/jobs/trim-audio.js +133 -0
  210. package/dist/jobs/trim-video.js +291 -0
  211. package/dist/jobs/xai-paygate.js +26 -0
  212. package/dist/keyword-placement-cache.js +74 -0
  213. package/dist/lazy-render.js +142 -0
  214. package/dist/library-browse.js +78 -0
  215. package/dist/lightning-defaults.js +206 -0
  216. package/dist/load-env.js +12 -0
  217. package/dist/local-search-models.js +206 -0
  218. package/dist/local-upload.js +318 -0
  219. package/dist/logger.js +69 -0
  220. package/dist/media/adapters/alibaba.js +20 -0
  221. package/dist/media/adapters/elevenlabs.js +58 -0
  222. package/dist/media/adapters/fal.js +45 -0
  223. package/dist/media/adapters/index.js +26 -0
  224. package/dist/media/adapters/kie.js +120 -0
  225. package/dist/media/adapters/pending.js +21 -0
  226. package/dist/media/adapters/types.js +5 -0
  227. package/dist/media/adapters/xai.js +18 -0
  228. package/dist/media/catalog.js +236 -0
  229. package/dist/media/complete.js +191 -0
  230. package/dist/media/cost.js +45 -0
  231. package/dist/media/descriptor.js +157 -0
  232. package/dist/media/endpoints.js +11 -0
  233. package/dist/media/frame-options.js +18 -0
  234. package/dist/media/insert-video-timing.js +17 -0
  235. package/dist/media/json-schema.js +75 -0
  236. package/dist/media/legacy-task-types.js +129 -0
  237. package/dist/media/listing.js +24 -0
  238. package/dist/media/model-id.js +14 -0
  239. package/dist/media/preview.js +86 -0
  240. package/dist/media/prompt-dialects.js +65 -0
  241. package/dist/media/ref-fields.js +106 -0
  242. package/dist/media/refs.js +131 -0
  243. package/dist/media/request.js +188 -0
  244. package/dist/media/types.js +6 -0
  245. package/dist/media/wire.js +161 -0
  246. package/dist/media-library.js +535 -0
  247. package/dist/media-output-path.js +33 -0
  248. package/dist/multyculty-workflow.js +757 -0
  249. package/dist/notebook-action-catalog.js +608 -0
  250. package/dist/notebook-cell-outputs.js +726 -0
  251. package/dist/notebook-credit-retry.js +45 -0
  252. package/dist/notebook-fixtures.js +8 -0
  253. package/dist/notebook-generation-contract.js +77 -0
  254. package/dist/notebook-generation-controls.js +145 -0
  255. package/dist/notebook-goal-layout.js +40 -0
  256. package/dist/notebook-graph.js +37 -0
  257. package/dist/notebook-image-edit.js +84 -0
  258. package/dist/notebook-initial-generation-prompt.js +222 -0
  259. package/dist/notebook-live-analysis.js +941 -0
  260. package/dist/notebook-media-ops.js +579 -0
  261. package/dist/notebook-mutations.js +20 -0
  262. package/dist/notebook-placement.js +41 -0
  263. package/dist/notebook-provider-failure.js +87 -0
  264. package/dist/notebook-published-post.js +26 -0
  265. package/dist/notebook-reference-resolver.js +227 -0
  266. package/dist/notebook-relayout.js +270 -0
  267. package/dist/notebook-run-plan.js +519 -0
  268. package/dist/notebook-shots.js +162 -0
  269. package/dist/notebook-workflow.js +856 -0
  270. package/dist/one-password.js +200 -0
  271. package/dist/openai-intelligence.js +99 -0
  272. package/dist/original-media-file.js +12 -0
  273. package/dist/osg-assets.js +36 -0
  274. package/dist/osg-placement-cache.js +64 -0
  275. package/dist/osg-settings.js +27 -0
  276. package/dist/paid-tools.js +22 -0
  277. package/dist/platform-guidance.js +26 -0
  278. package/dist/posts/dropbox-auth.js +91 -0
  279. package/dist/posts/dropbox-upload.js +132 -0
  280. package/dist/posts/icloud-drive.js +134 -0
  281. package/dist/posts/icloud-status.js +64 -0
  282. package/dist/posts/post-contract.js +2 -0
  283. package/dist/posts/post-copy-format.js +43 -0
  284. package/dist/posts/post-copy.js +193 -0
  285. package/dist/posts/post-folder.js +18 -0
  286. package/dist/posts/post-metrics.js +119 -0
  287. package/dist/posts/post-store.js +340 -0
  288. package/dist/posts/x-post-target.js +43 -0
  289. package/dist/preview-payload.js +90 -0
  290. package/dist/prompt-surfaces.js +22 -0
  291. package/dist/provider-prompt-transform.js +77 -0
  292. package/dist/provider-status-link.js +21 -0
  293. package/dist/provider-task-record.js +78 -0
  294. package/dist/provider-task-status.js +47 -0
  295. package/dist/provider-usage.js +294 -0
  296. package/dist/queue.js +810 -0
  297. package/dist/reference-video-duration.js +17 -0
  298. package/dist/remotion/BlurFillVideo.js +51 -0
  299. package/dist/remotion/KeywordGraphicsOverlay.js +68 -0
  300. package/dist/remotion/OsgOverlay.js +30 -0
  301. package/dist/remotion/QrOutroComposition.js +47 -0
  302. package/dist/remotion/RenderComposition.js +11 -0
  303. package/dist/remotion/browser.js +59 -0
  304. package/dist/remotion/constants.js +35 -0
  305. package/dist/remotion/index.js +66 -0
  306. package/dist/remotion/keyword-graphics.js +151 -0
  307. package/dist/remotion/keyword-placement.js +182 -0
  308. package/dist/remotion/osg-spec.js +198 -0
  309. package/dist/remotion/public/qr-outro-impact.wav +0 -0
  310. package/dist/remotion/qr-outro-audio.js +1 -0
  311. package/dist/remotion/qr-outro-spec.js +211 -0
  312. package/dist/remotion/shared-bundle.js +37 -0
  313. package/dist/remotion/subtitles/AliveCaptions.js +83 -0
  314. package/dist/remotion/subtitles/Highlight.js +58 -0
  315. package/dist/remotion/subtitles/Impact.js +67 -0
  316. package/dist/remotion/subtitles/SubtitleOverlay.js +9 -0
  317. package/dist/remotion/subtitles/alive-layout.js +321 -0
  318. package/dist/remotion/subtitles/alive-types.js +17 -0
  319. package/dist/remotion/subtitles/chunker.js +68 -0
  320. package/dist/remotion/subtitles/segments.js +42 -0
  321. package/dist/remotion/subtitles/styles.js +4 -0
  322. package/dist/remotion/subtitles/types.js +1 -0
  323. package/dist/remotion/util.js +18 -0
  324. package/dist/remotion-cancellation.js +15 -0
  325. package/dist/rename-helpers.js +204 -0
  326. package/dist/rhythm/analyze.js +128 -0
  327. package/dist/rhythm/contract.js +14 -0
  328. package/dist/rhythm/draft-model.js +19 -0
  329. package/dist/rhythm/energy.js +133 -0
  330. package/dist/rhythm/fft.js +44 -0
  331. package/dist/rhythm/model.js +71 -0
  332. package/dist/rhythm/music-analysis.js +124 -0
  333. package/dist/rhythm/music-draft.js +261 -0
  334. package/dist/rhythm/onset.js +101 -0
  335. package/dist/rhythm/run-worker.js +51 -0
  336. package/dist/rhythm/score.js +47 -0
  337. package/dist/rhythm/section-labels.js +168 -0
  338. package/dist/rhythm/sequence-rhythm.js +67 -0
  339. package/dist/rhythm/synthesize.js +103 -0
  340. package/dist/rhythm/timing.js +98 -0
  341. package/dist/rhythm/track.js +320 -0
  342. package/dist/rhythm/visual-fit.js +4 -0
  343. package/dist/rhythm/worker.js +25 -0
  344. package/dist/scene-detect.js +200 -0
  345. package/dist/scene-transition.js +12 -0
  346. package/dist/scheduled-posts.js +200 -0
  347. package/dist/search-index-coverage.js +13 -0
  348. package/dist/search-index-media.js +71 -0
  349. package/dist/search-reference-store.js +60 -0
  350. package/dist/search-scoring.js +17 -0
  351. package/dist/serve.js +125 -0
  352. package/dist/server-lock.js +143 -0
  353. package/dist/server.js +42 -0
  354. package/dist/srt.js +16 -0
  355. package/dist/tag-backfill-state.js +121 -0
  356. package/dist/tag-settings.js +30 -0
  357. package/dist/tag-vocabulary.js +237 -0
  358. package/dist/test-queue-cleanup.js +1 -0
  359. package/dist/time-parse.js +50 -0
  360. package/dist/timeline-helpers.js +554 -0
  361. package/dist/timewarp.js +87 -0
  362. package/dist/tools/_image-inputs.js +9 -0
  363. package/dist/tools/_media-refs.js +84 -0
  364. package/dist/tools/_shared.js +59 -0
  365. package/dist/tools/_suggest-shared.js +279 -0
  366. package/dist/tools/add-timeline-audio.js +73 -0
  367. package/dist/tools/alive-captions.js +157 -0
  368. package/dist/tools/analyze-jokes.js +56 -0
  369. package/dist/tools/analyze-video.js +66 -0
  370. package/dist/tools/animate-keywords.js +217 -0
  371. package/dist/tools/api-status.js +42 -0
  372. package/dist/tools/application-commands.js +34 -0
  373. package/dist/tools/apply-cuts.js +112 -0
  374. package/dist/tools/apply-sfx.js +152 -0
  375. package/dist/tools/apply-watermark.js +670 -0
  376. package/dist/tools/archive-clip.js +74 -0
  377. package/dist/tools/asset-history.js +61 -0
  378. package/dist/tools/asset-manifest.js +24 -0
  379. package/dist/tools/asset-tags.js +151 -0
  380. package/dist/tools/assign-slot.js +97 -0
  381. package/dist/tools/audio-boost.js +107 -0
  382. package/dist/tools/audio-mix.js +121 -0
  383. package/dist/tools/book-usage.js +16 -0
  384. package/dist/tools/chain.js +136 -0
  385. package/dist/tools/change-video-speed.js +105 -0
  386. package/dist/tools/chat-history.js +5 -0
  387. package/dist/tools/chat.js +848 -0
  388. package/dist/tools/clean-video-audio.js +97 -0
  389. package/dist/tools/clear-failed-tasks.js +66 -0
  390. package/dist/tools/cold-open.js +114 -0
  391. package/dist/tools/command-plan.js +1680 -0
  392. package/dist/tools/commands.js +1666 -0
  393. package/dist/tools/concat-images.js +236 -0
  394. package/dist/tools/connect-service.js +55 -0
  395. package/dist/tools/copy-file-to-clipboard.js +58 -0
  396. package/dist/tools/create-character.js +114 -0
  397. package/dist/tools/create-qart.js +253 -0
  398. package/dist/tools/create-qr-outro.js +149 -0
  399. package/dist/tools/create-qrbtf.js +215 -0
  400. package/dist/tools/create-watermark.js +97 -0
  401. package/dist/tools/crop-asset.js +18 -0
  402. package/dist/tools/crop-image.js +120 -0
  403. package/dist/tools/crop-video.js +97 -0
  404. package/dist/tools/delete-asset.js +104 -0
  405. package/dist/tools/describe-image.js +69 -0
  406. package/dist/tools/detect-scenes.js +44 -0
  407. package/dist/tools/doctor.js +126 -0
  408. package/dist/tools/download-video.js +114 -0
  409. package/dist/tools/duplicate-asset.js +184 -0
  410. package/dist/tools/edit-timeline.js +59 -0
  411. package/dist/tools/editing-moments.js +105 -0
  412. package/dist/tools/estimate-cost.js +171 -0
  413. package/dist/tools/even-split.js +295 -0
  414. package/dist/tools/export-asset-file.js +22 -0
  415. package/dist/tools/export-asset.js +140 -0
  416. package/dist/tools/export-sequence.js +250 -0
  417. package/dist/tools/export-to-downloads.js +54 -0
  418. package/dist/tools/export-transcript-srt.js +79 -0
  419. package/dist/tools/extend-audio.js +100 -0
  420. package/dist/tools/extract-audio.js +174 -0
  421. package/dist/tools/extract-frame.js +108 -0
  422. package/dist/tools/extract-notebook-audio.js +173 -0
  423. package/dist/tools/extract-notebook-frame.js +160 -0
  424. package/dist/tools/extract-video-clip.js +101 -0
  425. package/dist/tools/generate-media.js +157 -0
  426. package/dist/tools/generation-payload.js +48 -0
  427. package/dist/tools/get-timeline.js +12 -0
  428. package/dist/tools/get-watermark-config.js +38 -0
  429. package/dist/tools/goal.js +644 -0
  430. package/dist/tools/image-subjects.js +711 -0
  431. package/dist/tools/index.js +323 -0
  432. package/dist/tools/inject-first-frame.js +154 -0
  433. package/dist/tools/invert-image.js +70 -0
  434. package/dist/tools/isolate-vocals.js +66 -0
  435. package/dist/tools/list-assets.js +98 -0
  436. package/dist/tools/list-cell-generations.js +225 -0
  437. package/dist/tools/list-elevenlabs-voices.js +163 -0
  438. package/dist/tools/log-wrapper.js +29 -0
  439. package/dist/tools/make-cover-song.js +95 -0
  440. package/dist/tools/mark-asset-seen.js +23 -0
  441. package/dist/tools/media-library.js +245 -0
  442. package/dist/tools/move-timeline-audio.js +35 -0
  443. package/dist/tools/music-analysis.js +60 -0
  444. package/dist/tools/music-draft.js +29 -0
  445. package/dist/tools/pad-video.js +87 -0
  446. package/dist/tools/post-record.js +83 -0
  447. package/dist/tools/post.js +168 -0
  448. package/dist/tools/prompt-history.js +164 -0
  449. package/dist/tools/provider-key-status.js +248 -0
  450. package/dist/tools/qrbtf-render.js +849 -0
  451. package/dist/tools/read-asset-metadata.js +26 -0
  452. package/dist/tools/read-file-at-commit.js +29 -0
  453. package/dist/tools/read-transcript.js +41 -0
  454. package/dist/tools/reconcile-project-work.js +1452 -0
  455. package/dist/tools/recover-asset.js +28 -0
  456. package/dist/tools/remove-sound.js +72 -0
  457. package/dist/tools/remove-timeline-audio.js +34 -0
  458. package/dist/tools/remove-timeline-slot.js +40 -0
  459. package/dist/tools/rename-all.js +434 -0
  460. package/dist/tools/rename-asset.js +34 -0
  461. package/dist/tools/render-settings.js +47 -0
  462. package/dist/tools/render-timeline.js +120 -0
  463. package/dist/tools/render.js +384 -0
  464. package/dist/tools/reorder-character-images.js +45 -0
  465. package/dist/tools/replace-video-audio.js +133 -0
  466. package/dist/tools/restore-archive-clips.js +209 -0
  467. package/dist/tools/restore-asset-version.js +37 -0
  468. package/dist/tools/retry-generation.js +54 -0
  469. package/dist/tools/reverse-video.js +74 -0
  470. package/dist/tools/rewrite-prompt.js +388 -0
  471. package/dist/tools/rewrite-script.js +67 -0
  472. package/dist/tools/schema-from-apicity.js +66 -0
  473. package/dist/tools/search-archive.js +150 -0
  474. package/dist/tools/semantic-search.js +1214 -0
  475. package/dist/tools/sequence-rhythm.js +43 -0
  476. package/dist/tools/set-character-metadata.js +84 -0
  477. package/dist/tools/set-env-secret.js +40 -0
  478. package/dist/tools/set-osg.js +143 -0
  479. package/dist/tools/show-folder.js +37 -0
  480. package/dist/tools/smooth-scene-concat.js +122 -0
  481. package/dist/tools/splice-video.js +149 -0
  482. package/dist/tools/split-video.js +202 -0
  483. package/dist/tools/suggest-cuts.js +45 -0
  484. package/dist/tools/suggest-sfx.js +43 -0
  485. package/dist/tools/sync-video-to-audio.js +115 -0
  486. package/dist/tools/tag-backfill.js +177 -0
  487. package/dist/tools/timewarp-video.js +85 -0
  488. package/dist/tools/tool-def.js +1 -0
  489. package/dist/tools/tool-json-schema.js +116 -0
  490. package/dist/tools/transcribe.js +90 -0
  491. package/dist/tools/translate-subtitles.js +59 -0
  492. package/dist/tools/trim-audio.js +139 -0
  493. package/dist/tools/trim-video.js +168 -0
  494. package/dist/tools/update-script.js +25 -0
  495. package/dist/tools/update-timeline-audio.js +40 -0
  496. package/dist/tools/upload-file.js +41 -0
  497. package/dist/tools/verify-x-mentions.js +141 -0
  498. package/dist/tools/video-editing-command-contract.js +291 -0
  499. package/dist/tools/video-source-reference.js +30 -0
  500. package/dist/tools/video-time-input.js +18 -0
  501. package/dist/tools/videobook-domain.js +2021 -0
  502. package/dist/tools/wait-for-asset-ready.js +143 -0
  503. package/dist/tools/workspace-actions.js +54 -0
  504. package/dist/transcript-projection.js +202 -0
  505. package/dist/transcript-srt.js +33 -0
  506. package/dist/upload.js +76 -0
  507. package/dist/usage-providers.js +25 -0
  508. package/dist/video-analysis-projection.js +46 -0
  509. package/dist/video-poster.js +33 -0
  510. package/dist/video-proxy.js +99 -0
  511. package/dist/vision-regions.js +111 -0
  512. package/dist/voice-actions.js +90 -0
  513. package/dist/voice-audio.js +55 -0
  514. package/dist/voice-config.js +122 -0
  515. package/dist/voice-continuation.js +54 -0
  516. package/dist/voice-contract.js +1 -0
  517. package/dist/voice-http.js +145 -0
  518. package/dist/voice-reply-progress.js +55 -0
  519. package/dist/voice-session.js +992 -0
  520. package/dist/watermark-badge.js +259 -0
  521. package/dist/watermark-config.js +111 -0
  522. package/dist/watermark-handle-position.js +55 -0
  523. package/dist/watermark-platform.js +15 -0
  524. package/dist/watermark-timing.js +16 -0
  525. package/dist/workspace-action-catalog.js +315 -0
  526. package/dist/workspace-action-contract.js +21 -0
  527. package/dist/workspace-action-groups.js +98 -0
  528. package/dist/workspace-action-surfaces.js +7 -0
  529. package/dist/x/account.js +88 -0
  530. package/dist/x/authenticated-handle.js +30 -0
  531. package/dist/x/oauth-flow.js +191 -0
  532. package/dist/x/post-contract.js +1 -0
  533. package/dist/x/post-metadata.js +44 -0
  534. package/dist/x/post-to-x.js +456 -0
  535. package/dist/x/published-post-cell.js +90 -0
  536. package/dist/x/x-tokens.js +69 -0
  537. package/dist/ytdlp-binary.js +65 -0
  538. package/dist/zod-slots.js +334 -0
  539. package/package.json +84 -4
  540. package/ui/assets/alive-captions-BWb5nLKj.css +1 -0
  541. package/ui/assets/alive-captions-DPEr1nKM.js +1 -0
  542. package/ui/assets/confirm-bodies-D8ouHXKy.js +1 -0
  543. package/ui/assets/confirm-bodies-DrMhaXC6.css +1 -0
  544. package/ui/assets/fullscreen-B7nw4YbE.js +1 -0
  545. package/ui/assets/goal-ui-DK-xTCK0.js +2 -0
  546. package/ui/assets/goal-ui-DXdUM2KF.css +1 -0
  547. package/ui/assets/index-DzPAnCUj.css +1 -0
  548. package/ui/assets/index-kS1905s5.js +37 -0
  549. package/ui/assets/inspector-MlzQbTVo.js +1 -0
  550. package/ui/assets/jobs-ui-CoinOWx0.js +1 -0
  551. package/ui/assets/music-video-Cbe80kmQ.js +1 -0
  552. package/ui/assets/music-video-DPaiKKEq.css +1 -0
  553. package/ui/assets/ui-Oirr9VOf.css +1 -0
  554. package/ui/assets/ui-xo_Y1yQg.js +2 -0
  555. package/ui/assets/vendor-D2rfiZ5j.css +1 -0
  556. package/ui/assets/vendor-DfTCWgKm.js +19 -0
  557. package/ui/assets/vendor-flow-BXbeWxW7.js +7 -0
  558. package/ui/assets/vendor-flow-BnuhLJ6X.css +1 -0
  559. package/ui/assets/vendor-icons-CGqhCIXV.js +1 -0
  560. package/ui/assets/vendor-mcp-BTlEJcHV.js +67 -0
  561. package/ui/assets/vendor-react-Dj7D1fD4.js +9 -0
  562. package/ui/assets/vendor-remotion-CH1HXrlc.js +95 -0
  563. package/ui/assets/videobook-Qlp9HQFu.js +20 -0
  564. package/ui/favicon.svg +8 -0
  565. package/ui/index.html +126 -0
@@ -0,0 +1,334 @@
1
+ /**
2
+ * Read array-cardinality constraints from a Zod schema.
3
+ *
4
+ * Covers the three patterns used in @apicity provider schemas for reference-asset
5
+ * fields: optional/required array, tuple (fixed-length), and single string.
6
+ *
7
+ * Reads Zod 4 internals (`_def.type`, `_def.checks[]._zod.def`) — every
8
+ * @apicity/* provider is unified on `zod ^4.4.3` (and the app's own zod is 4.x),
9
+ * so the prior Zod-3 straddling readers were dropped.
10
+ *
11
+ * The returned `max: null` means "unbounded per the Zod schema" — the UI should
12
+ * render an add-more affordance rather than a fixed slot count.
13
+ */
14
+ function defOf(schema) {
15
+ if (!schema || typeof schema !== "object")
16
+ return null;
17
+ const def = schema._def;
18
+ return def && typeof def === "object" ? def : null;
19
+ }
20
+ // Call sites keep the (unused) Zod-3 name argument so the ~30 call sites read
21
+ // `isType(x, "ZodFoo", "foo")` unchanged; only the Zod-4 `_def.type` is matched.
22
+ function isType(schema, _v3Name, v4Name) {
23
+ return defOf(schema)?.type === v4Name;
24
+ }
25
+ function readArrayBounds(def) {
26
+ let min = 0;
27
+ let max = null;
28
+ for (const c of def.checks ?? []) {
29
+ const cdef = c?._zod?.def;
30
+ if (!cdef)
31
+ continue;
32
+ if (cdef.check === "min_length" && typeof cdef.minimum === "number")
33
+ min = cdef.minimum;
34
+ if (cdef.check === "max_length" && typeof cdef.maximum === "number")
35
+ max = cdef.maximum;
36
+ }
37
+ return { min, max };
38
+ }
39
+ function unwrapOptional(schema) {
40
+ let cur = schema;
41
+ let optional = false;
42
+ let def = defOf(cur);
43
+ while (def &&
44
+ (isType(cur, "ZodOptional", "optional") ||
45
+ isType(cur, "ZodNullable", "nullable") ||
46
+ isType(cur, "ZodDefault", "default") ||
47
+ isType(cur, "ZodEffects", "effects") ||
48
+ isType(cur, "ZodPipe", "pipe"))) {
49
+ const isEffectsLike = isType(cur, "ZodEffects", "effects") || isType(cur, "ZodPipe", "pipe");
50
+ if (!isEffectsLike)
51
+ optional = true;
52
+ const next = isEffectsLike ? (def.schema ?? def.innerType) : def.innerType;
53
+ if (!next)
54
+ break;
55
+ cur = next;
56
+ def = defOf(cur);
57
+ }
58
+ return { inner: cur, optional };
59
+ }
60
+ export function readSlotConstraints(schema, options) {
61
+ if (!schema)
62
+ return null;
63
+ const { inner, optional } = unwrapOptional(schema);
64
+ const def = defOf(inner);
65
+ if (!def)
66
+ return null;
67
+ if (isType(inner, "ZodTuple", "tuple")) {
68
+ const len = def.items?.length ?? 0;
69
+ return { min: optional && !options?.whenPresent ? 0 : len, max: len };
70
+ }
71
+ if (isType(inner, "ZodArray", "array")) {
72
+ const { min, max } = readArrayBounds(def);
73
+ return { min: optional && !options?.whenPresent ? 0 : min, max };
74
+ }
75
+ if (isType(inner, "ZodString", "string")) {
76
+ return { min: optional && !options?.whenPresent ? 0 : 1, max: 1 };
77
+ }
78
+ return null;
79
+ }
80
+ /**
81
+ * Strip Optional/Nullable/Default/Effects/Pipe wrappers down to the inner schema.
82
+ *
83
+ * Unlike `readSlotConstraints`'s unwrap, this also peels `ZodDefault` — the
84
+ * @apicity npm packages wrap several enum fields in `.default(...)` where the
85
+ * local build used `.optional()`.
86
+ */
87
+ function unwrapToCore(schema) {
88
+ let cur = schema;
89
+ let def = defOf(cur);
90
+ while (def &&
91
+ (isType(cur, "ZodOptional", "optional") ||
92
+ isType(cur, "ZodNullable", "nullable") ||
93
+ isType(cur, "ZodDefault", "default") ||
94
+ isType(cur, "ZodEffects", "effects") ||
95
+ isType(cur, "ZodPipe", "pipe"))) {
96
+ const isEffectsLike = isType(cur, "ZodEffects", "effects") || isType(cur, "ZodPipe", "pipe");
97
+ const next = isEffectsLike ? (def.schema ?? def.innerType) : def.innerType;
98
+ if (!next)
99
+ break;
100
+ cur = next;
101
+ def = defOf(cur);
102
+ }
103
+ return cur;
104
+ }
105
+ function toStringList(raw) {
106
+ const arr = Array.isArray(raw)
107
+ ? raw
108
+ : raw && typeof raw === "object"
109
+ ? Object.values(raw)
110
+ : [];
111
+ return arr.filter((v) => typeof v === "string");
112
+ }
113
+ /**
114
+ * Read the string values of a (possibly wrapped) `ZodEnum`.
115
+ *
116
+ * Zod 4 stores enum values as an object map under `_def.entries`; this
117
+ * normalizes them to a plain string tuple.
118
+ *
119
+ * Throws if `schema` does not resolve to an enum — these feed MCP tool input
120
+ * schemas, so a silent empty list would be a worse failure than a loud one.
121
+ */
122
+ function enumOptions(schema) {
123
+ const def = defOf(unwrapToCore(schema));
124
+ const values = toStringList(def?.entries);
125
+ if (values.length === 0) {
126
+ throw new Error("enumOptions: schema did not resolve to a non-empty ZodEnum");
127
+ }
128
+ return values;
129
+ }
130
+ export function zodDefault(schema) {
131
+ let cur = schema;
132
+ let def = defOf(cur);
133
+ while (def) {
134
+ if (isType(cur, "ZodDefault", "default")) {
135
+ const raw = def.defaultValue;
136
+ return {
137
+ hasDefault: true,
138
+ value: typeof raw === "function" ? raw() : raw,
139
+ };
140
+ }
141
+ if (!isType(cur, "ZodOptional", "optional") &&
142
+ !isType(cur, "ZodNullable", "nullable") &&
143
+ !isType(cur, "ZodEffects", "effects") &&
144
+ !isType(cur, "ZodPipe", "pipe")) {
145
+ break;
146
+ }
147
+ const isEffectsLike = isType(cur, "ZodEffects", "effects") || isType(cur, "ZodPipe", "pipe");
148
+ const next = isEffectsLike ? (def.schema ?? def.innerType) : def.innerType;
149
+ if (!next)
150
+ break;
151
+ cur = next;
152
+ def = defOf(cur);
153
+ }
154
+ return { hasDefault: false };
155
+ }
156
+ export function zodIsRequired(schema) {
157
+ let cur = schema;
158
+ let def = defOf(cur);
159
+ while (def) {
160
+ if (isType(cur, "ZodOptional", "optional") || isType(cur, "ZodDefault", "default")) {
161
+ return false;
162
+ }
163
+ if (isType(cur, "ZodNullable", "nullable")) {
164
+ const next = def.innerType;
165
+ if (!next)
166
+ break;
167
+ cur = next;
168
+ def = defOf(cur);
169
+ continue;
170
+ }
171
+ if (!isType(cur, "ZodEffects", "effects") && !isType(cur, "ZodPipe", "pipe")) {
172
+ return true;
173
+ }
174
+ const next = def.schema ?? def.innerType;
175
+ if (!next)
176
+ break;
177
+ cur = next;
178
+ def = defOf(cur);
179
+ }
180
+ return true;
181
+ }
182
+ function readNumberChecks(def) {
183
+ let min;
184
+ let max;
185
+ let exclusiveMin = false;
186
+ let exclusiveMax = false;
187
+ let int = false;
188
+ for (const raw of (def.checks ?? [])) {
189
+ const cdef = raw._zod?.def;
190
+ if (!cdef)
191
+ continue;
192
+ if (cdef.check === "number_format" && cdef.format === "safeint")
193
+ int = true;
194
+ else if (cdef.check === "greater_than" && typeof cdef.value === "number") {
195
+ min = cdef.value;
196
+ exclusiveMin = cdef.inclusive === false;
197
+ }
198
+ else if (cdef.check === "less_than" && typeof cdef.value === "number") {
199
+ max = cdef.value;
200
+ exclusiveMax = cdef.inclusive === false;
201
+ }
202
+ }
203
+ return {
204
+ min,
205
+ max,
206
+ int,
207
+ ...(exclusiveMin ? { exclusiveMin } : {}),
208
+ ...(exclusiveMax ? { exclusiveMax } : {}),
209
+ };
210
+ }
211
+ /**
212
+ * Read the numeric range of a (possibly wrapped) `ZodNumber`. For a
213
+ * `ZodUnion<[ZodNumber, ZodString]>` (grok image-to-video `duration`) the number
214
+ * branch is read. Returns null if the schema is not a number / number-union.
215
+ */
216
+ export function zodNumberRange(schema) {
217
+ if (!schema)
218
+ return null;
219
+ let inner = unwrapToCore(schema);
220
+ if (isType(inner, "ZodUnion", "union")) {
221
+ const def = defOf(inner);
222
+ const options = (def?.options ?? []);
223
+ const numberOpt = options.find((o) => isType(o, "ZodNumber", "number"));
224
+ if (!numberOpt)
225
+ return null;
226
+ inner = numberOpt;
227
+ }
228
+ if (!isType(inner, "ZodNumber", "number"))
229
+ return null;
230
+ const def = defOf(inner);
231
+ return def ? readNumberChecks(def) : null;
232
+ }
233
+ export function zodFiniteNumberOptions(schema) {
234
+ if (!schema)
235
+ return null;
236
+ const inner = unwrapToCore(schema);
237
+ const def = defOf(inner);
238
+ if (!def)
239
+ return null;
240
+ const branches = isType(inner, "ZodUnion", "union")
241
+ ? (def.options ?? [])
242
+ : [inner];
243
+ const values = [];
244
+ for (const branch of branches) {
245
+ const core = unwrapToCore(branch);
246
+ const branchDef = defOf(core);
247
+ if (!branchDef)
248
+ return null;
249
+ if (isType(core, "ZodLiteral", "literal")) {
250
+ const literals = (branchDef.values ?? []).filter((value) => typeof value === "number");
251
+ if (literals.length !== (branchDef.values ?? []).length)
252
+ return null;
253
+ values.push(...literals);
254
+ continue;
255
+ }
256
+ if (!isType(core, "ZodNumber", "number"))
257
+ return null;
258
+ const range = readNumberChecks(branchDef);
259
+ if (!range.int || range.min === undefined || range.max === undefined || range.max - range.min > 1_000) {
260
+ return null;
261
+ }
262
+ for (let value = range.min; value <= range.max; value++)
263
+ values.push(value);
264
+ }
265
+ return values.length > 0 ? [...new Set(values)] : null;
266
+ }
267
+ function readStringLength(def, which) {
268
+ for (const raw of (def.checks ?? [])) {
269
+ const cdef = raw._zod?.def;
270
+ if (!cdef)
271
+ continue;
272
+ if (which === "min" && cdef.check === "min_length" && typeof cdef.minimum === "number")
273
+ return cdef.minimum;
274
+ if (which === "max" && cdef.check === "max_length" && typeof cdef.maximum === "number")
275
+ return cdef.maximum;
276
+ }
277
+ return undefined;
278
+ }
279
+ /** Max string length of a (possibly wrapped) `ZodString`, or undefined. */
280
+ export function zodStringMaxLength(schema) {
281
+ if (!schema)
282
+ return undefined;
283
+ const inner = unwrapToCore(schema);
284
+ if (!isType(inner, "ZodString", "string"))
285
+ return undefined;
286
+ const def = defOf(inner);
287
+ return def ? readStringLength(def, "max") : undefined;
288
+ }
289
+ /** Min string length of a (possibly wrapped) `ZodString`, or undefined. */
290
+ export function zodStringMinLength(schema) {
291
+ if (!schema)
292
+ return undefined;
293
+ const inner = unwrapToCore(schema);
294
+ if (!isType(inner, "ZodString", "string"))
295
+ return undefined;
296
+ const def = defOf(inner);
297
+ return def ? readStringLength(def, "min") : undefined;
298
+ }
299
+ /** True when the (possibly wrapped) schema resolves to a `ZodBoolean`. */
300
+ export function zodIsBoolean(schema) {
301
+ if (!schema)
302
+ return false;
303
+ return isType(unwrapToCore(schema), "ZodBoolean", "boolean");
304
+ }
305
+ /**
306
+ * Like {@link enumOptions} but returns null instead of throwing when the schema
307
+ * is not a `ZodEnum`, so callers can attempt-enum-then-fall-through to numeric /
308
+ * string / boolean handling.
309
+ */
310
+ export function zodEnumOptionsOrNull(schema) {
311
+ try {
312
+ return enumOptions(schema);
313
+ }
314
+ catch {
315
+ return null;
316
+ }
317
+ }
318
+ /**
319
+ * Read the enum options from a `ZodUnion` that contains a `ZodEnum` branch
320
+ * (e.g. fal `image_size`: an enum of named sizes unioned with a custom
321
+ * width/height object). Returns the first enum branch's options, or null if the
322
+ * schema is not such a union.
323
+ */
324
+ export function zodUnionEnumOptions(schema) {
325
+ const def = defOf(unwrapToCore(schema));
326
+ if (!def || def.type !== "union")
327
+ return null;
328
+ for (const opt of (def.options ?? [])) {
329
+ const opts = zodEnumOptionsOrNull(opt);
330
+ if (opts)
331
+ return opts;
332
+ }
333
+ return null;
334
+ }
package/package.json CHANGED
@@ -1,6 +1,86 @@
1
1
  {
2
2
  "name": "videobook",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.0",
4
+ "description": "Local-first MCP server and web UI for AI video creation: notebooks, generation, editing, rendering and publishing.",
5
+ "keywords": [
6
+ "mcp",
7
+ "model-context-protocol",
8
+ "video",
9
+ "notebook",
10
+ "ai",
11
+ "remotion",
12
+ "ffmpeg",
13
+ "cli"
14
+ ],
15
+ "license": "MIT",
16
+ "homepage": "https://www.npmjs.com/package/videobook",
17
+ "type": "module",
18
+ "bin": {
19
+ "videobook": "bin/videobook.js"
20
+ },
21
+ "files": [
22
+ "bin",
23
+ "dist",
24
+ "ui",
25
+ "CHANGELOG.md"
26
+ ],
27
+ "engines": {
28
+ "node": ">=22"
29
+ },
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "scripts": {
34
+ "build": "node ../scripts/build-server.mjs",
35
+ "prepack": "npm --prefix .. run build:package",
36
+ "start": "node dist/index.js"
37
+ },
38
+ "dependencies": {
39
+ "@apicity/alibaba": "^0.16.1",
40
+ "@apicity/b2": "^0.16.1",
41
+ "@apicity/cost": "^0.16.1",
42
+ "@apicity/dropbox": "^0.16.1",
43
+ "@apicity/elevenlabs": "^0.16.1",
44
+ "@apicity/fal": "^0.16.1",
45
+ "@apicity/free-media-upload": "^0.16.1",
46
+ "@apicity/kie": "^0.16.1",
47
+ "@apicity/kimicoding": "^0.16.1",
48
+ "@apicity/openai": "^0.16.1",
49
+ "@apicity/x": "^0.16.1",
50
+ "@apicity/xai": "^0.16.1",
51
+ "@devmehq/open-graph-extractor": "^1.1.1",
52
+ "@ffprobe-installer/ffprobe": "2.1.2",
53
+ "@modelcontextprotocol/client": "^2.2.0",
54
+ "@modelcontextprotocol/node": "2.0.0",
55
+ "@modelcontextprotocol/server": "^2.0.0",
56
+ "@remotion/bundler": "4.0.494",
57
+ "@remotion/google-fonts": "4.0.494",
58
+ "@remotion/renderer": "4.0.494",
59
+ "cors": "^2.8.6",
60
+ "dotenv": "^17.3.1",
61
+ "express": "^5.2.1",
62
+ "ffmpeg-static": "^5.3.0",
63
+ "ffmpeggy": "^3.1.3",
64
+ "heic-decode": "^2.1.0",
65
+ "hono": "^4.12.31",
66
+ "qrcode": "^1.5.4",
67
+ "react": "^19.2.0",
68
+ "react-dom": "^19.2.0",
69
+ "remotion": "4.0.494",
70
+ "sharp": "0.35.5",
71
+ "uuid": "^14.0.0",
72
+ "videobook-engine": "5.7.0",
73
+ "ws": "^8.21.0",
74
+ "ytdlp-nodejs": "^3.4.4",
75
+ "zod": "^4.4.3"
76
+ },
77
+ "devDependencies": {
78
+ "@types/cors": "^2.8.19",
79
+ "@types/express": "^5.0.6",
80
+ "@types/heic-decode": "^2.0.0",
81
+ "@types/node": "^25.3.3",
82
+ "@types/qrcode": "^1.5.6",
83
+ "jsqr": "^1.4.0",
84
+ "typescript": "^5.9.3"
85
+ }
86
+ }
@@ -0,0 +1 @@
1
+ .alive-studio{--alive-accent: var(--green, #72e7aa);--alive-bright: #d5f8e4;--alive-muted: #7fa892;--alive-warn: #f0a860;--alive-cyan: var(--cyan, #63c7d8);--alive-line: #1d4432;--alive-panel: #07150e;--alive-field: #0a1c14;position:fixed;inset:0;width:100%;height:100dvh;max-width:none;max-height:none;margin:0;padding:0;overflow:hidden;border:0;color:var(--ink, #a9d6bf);background:var(--surface-deep, #04120c);font-family:JetBrains Mono,ui-monospace,monospace;font-size:12px}.alive-studio::backdrop{background:var(--surface-deep, #04120c)}.alive-studio *,.alive-studio *:before,.alive-studio *:after{box-sizing:border-box}.alive-studio button,.alive-studio input{font:inherit}.alive-studio button{min-height:36px;padding:0 12px;border:1px solid var(--alive-line);border-radius:6px;color:var(--ink, #a9d6bf);background:var(--alive-field);cursor:pointer}.alive-studio button:hover:not(:disabled),.alive-studio button[aria-pressed=true]{border-color:var(--alive-accent);color:var(--alive-bright);background:#123a28}.alive-studio button:focus-visible,.alive-studio input:focus-visible{outline:2px solid var(--alive-accent);outline-offset:1px}.alive-studio button:disabled{cursor:default;opacity:.45}.alive-studio .alive-primary{border-color:var(--alive-accent);color:#04120c;background:var(--alive-accent);font-weight:700}.alive-studio .alive-primary:hover:not(:disabled){color:#04120c;background:var(--alive-bright)}.alive-studio .alive-primary.alive-warn{border-color:var(--alive-warn);background:var(--alive-warn)}.alive-studio .alive-secondary{font-weight:700}.alive-studio-body,.alive-studio-message{display:grid;height:100%;min-height:0;padding:0 20px 14px;gap:12px}.alive-studio-body{grid-template-rows:auto minmax(0,1fr) auto;grid-template-columns:minmax(0,1fr)}.alive-studio-message{grid-template-rows:auto 1fr}.alive-studio-message p{place-self:center;color:var(--alive-muted);font-size:13px}.alive-header{display:flex;align-items:center;gap:12px;flex-wrap:wrap;min-height:56px;padding:8px 0;border-bottom:1px solid #133325}.alive-header h2{margin:0;font-size:15px;color:var(--alive-bright)}.alive-muted{color:var(--alive-muted)}.alive-spacer{flex:1 1 auto}.alive-close{width:36px;padding:0!important;display:grid;place-items:center}.alive-segmented{display:flex;gap:6px}.alive-segmented button{flex:1 1 0;font-weight:700}.alive-main{display:grid;grid-template-columns:minmax(220px,300px) minmax(0,1fr) minmax(240px,316px);gap:16px;min-height:0}.alive-panel{min-height:0;border:1px solid #133325;border-radius:8px;background:var(--alive-panel)}.alive-transcript{display:grid;grid-template-rows:auto minmax(0,1fr);overflow:hidden}.alive-panel-header{padding:12px 14px 8px;border-bottom:1px solid #133325}.alive-panel-header h3{margin:0;font-size:13px;color:var(--alive-bright)}.alive-panel-header p{margin:4px 0 0;font-size:11px;color:var(--alive-muted)}.alive-transcript-list{overflow-y:auto;padding:10px;display:grid;align-content:start;gap:12px}.alive-phrase{display:grid;gap:6px}.alive-phrase-head{display:flex;justify-content:space-between;padding:0 4px;font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--alive-muted)}.alive-phrase[data-active] .alive-phrase-head{color:var(--alive-accent)}.alive-phrase-words{display:flex;flex-wrap:wrap;gap:4px}.alive-studio .alive-word{display:grid;gap:2px;min-height:40px;padding:4px 8px;text-align:left}.alive-word span{font-weight:700;font-size:13px}.alive-word small{font-size:10px;color:var(--alive-muted)}.alive-studio .alive-word[data-active]{border-color:var(--alive-accent);background:#123a28;color:var(--alive-bright)}.alive-studio .alive-word[data-drifted]{border-color:var(--alive-warn)}.alive-word[data-drifted] small{color:var(--alive-warn)}.alive-stage{padding:8px;border-radius:8px;background:var(--alive-field);display:grid;grid-template-rows:minmax(0,1fr) auto;gap:8px;min-height:0;justify-items:center}.alive-player{width:100%;height:100%;border-radius:6px;overflow:hidden}.alive-status{margin:0;justify-self:stretch;color:var(--alive-bright);font-size:12px;min-height:18px}.alive-settings{display:grid;align-content:start;gap:16px;padding:14px;overflow-y:auto}.alive-field{display:grid;gap:6px}.alive-field h4{margin:0;font-size:11px;font-weight:400;letter-spacing:.08em;text-transform:uppercase;color:var(--alive-muted)}.alive-hint{margin:0;font-size:11px;line-height:1.5;color:var(--alive-muted)}.alive-warning{color:var(--alive-warn)}.alive-toggle{display:flex;align-items:center;gap:10px;min-height:36px;color:var(--alive-bright);cursor:pointer}.alive-toggle input{width:16px;height:16px;margin:0;accent-color:var(--alive-accent)}.alive-swatches{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.alive-studio .alive-swatches>button{width:40px;height:40px;min-height:40px;padding:6px}.alive-studio .alive-swatches>button[aria-pressed=true]{border:2px solid var(--alive-bright)}.alive-swatches>button span{display:block;width:100%;height:100%;border-radius:3px}.alive-color-input{display:flex;align-items:center;gap:6px;color:var(--alive-muted)}.alive-color-input input{width:40px;height:36px;padding:2px;border:1px solid var(--alive-line);border-radius:6px;background:var(--alive-field)}.alive-timeline{display:grid;gap:8px;padding:10px 14px}.alive-transport{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.alive-studio .alive-transport>button[aria-label]{width:40px;padding:0;display:grid;place-items:center}.alive-studio .alive-play{border-color:var(--alive-accent);background:var(--alive-accent);color:#04120c}.alive-clock{margin-left:6px;min-width:76px;color:var(--alive-bright);font-size:14px}.alive-drift{color:var(--alive-accent)}.alive-drift[data-drifted]{color:var(--alive-warn)}.alive-lanes{display:grid;grid-template-columns:64px minmax(0,1fr);gap:10px}.alive-lane-labels{display:grid;grid-template-rows:18px 72px 30px 24px;gap:6px;font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:var(--alive-muted);align-items:center}.alive-lane-scroll{overflow-x:auto;overflow-y:hidden}.alive-lane-tracks{position:relative;display:grid;grid-template-rows:18px 72px 30px 24px;gap:6px;cursor:pointer}.alive-lane-tracks>div{position:relative}.alive-lane-tracks .alive-lane-ruler{border-bottom:1px solid #133325}.alive-lane-ruler span{position:absolute;top:0;transform:translate(-50%);font-size:10px;color:var(--alive-muted)}.alive-lane-tracks .alive-lane-audio{border-radius:4px;background:var(--alive-field);overflow:hidden}.alive-lane-audio svg{position:absolute;inset:6px 0;width:100%;height:calc(100% - 12px)}.alive-lane-audio path{fill:#2f6a4f}.alive-onset{position:absolute;top:0;bottom:0;width:2px;background:var(--alive-warn)}.alive-chip,.alive-stack-bar{position:absolute;top:0;bottom:0;display:flex;align-items:center;overflow:hidden;white-space:nowrap;border:1px solid var(--alive-line);border-radius:4px;padding:0 4px;font-size:10px}.alive-chip{font-weight:700;color:var(--alive-bright);background:#123a28}.alive-chip[data-active]{color:#04120c;background:var(--alive-accent);border-color:var(--alive-accent)}.alive-chip[data-drifted]{border-color:var(--alive-warn)}.alive-stack-bar{padding:0 8px;color:var(--alive-muted);background:var(--alive-field)}.alive-stack-bar[data-active]{color:var(--alive-bright);border-color:var(--alive-accent);background:#123a28}.alive-playhead{position:absolute;top:0;bottom:0;width:2px;margin-left:-1px;background:var(--alive-bright);pointer-events:none}.alive-legend{display:flex;gap:18px;flex-wrap:wrap;padding-left:74px;font-size:11px;color:var(--alive-muted)}.alive-legend span{display:flex;align-items:center;gap:6px}.alive-legend i{display:inline-block}.alive-legend-chip{width:10px;height:10px;border-radius:2px;background:var(--alive-accent)}.alive-legend-drift{width:10px;height:10px;border-radius:2px;border:1px solid var(--alive-warn)}.alive-legend-onset{width:2px;height:12px;background:var(--alive-warn)}@media(max-width:1100px){.alive-studio{overflow-y:auto}.alive-studio-body{height:auto;grid-template-rows:auto auto auto}.alive-main{grid-template-columns:minmax(0,1fr)}.alive-transcript{max-height:260px}.alive-stage{order:-1}.alive-player{height:auto;width:100%;max-height:70dvh}.alive-header h2{font-size:14px}.alive-header .alive-muted{flex-basis:100%;order:3}}
@@ -0,0 +1 @@
1
+ import{c as F,j as t,a as A}from"./vendor-react-Dj7D1fD4.js";import{u as be,a as xe,V as Se,A as pe,P as Ne}from"./vendor-remotion-CH1HXrlc.js";import{ea as Ce,eb as ke,ec as we,ed as $e,ee as Pe,ef as de,eg as Te,eh as me,ei as Re,ej as Ae,ek as Me,el as _e,em as Ee,en as Oe,eo as fe,bu as We}from"./videobook-Qlp9HQFu.js";import{g as Le,a6 as ze,_ as Fe,h as He,X as Ie}from"./vendor-icons-CGqhCIXV.js";import"./vendor-DfTCWgKm.js";import"./vendor-mcp-BTlEJcHV.js";const Be={face:"#63c7d8",text:"#f0a860",graphic:"#f0a860"};function De(a){const e=F.c(25),{phrase:s,cue:n,settings:o,sourceWidth:c,sourceHeight:l}=a,{width:i,height:h}=xe();let r,f,m,d;if(e[0]!==h||e[1]!==s.id||e[2]!==s.regions||e[3]!==o||e[4]!==l||e[5]!==c||e[6]!==i){const j={sourceWidth:c,sourceHeight:l,targetWidth:i,targetHeight:h};let v;e[11]!==s.regions||e[12]!==o?(v=new Set($e(s.regions,o)),e[11]=s.regions,e[12]=o,e[13]=v):v=e[13];const C=v;let y;e[14]!==i?(y=Math.round(i/480),e[14]=i,e[15]=y):y=e[15],f=Math.max(2,y),r=pe,e[16]===Symbol.for("react.memo_cache_sentinel")?(m={pointerEvents:"none"},e[16]=m):m=e[16],d=s.regions.map((w,$)=>{const b=Pe(w,j);return t.jsx("div",{style:{position:"absolute",left:b.x*i,top:b.y*h,width:b.width*i,height:b.height*h,border:`${f}px dashed ${Be[w.kind]}`,opacity:C.has(w)?1:.4,borderRadius:f*2}},`${s.id}-${$}`)}),e[0]=h,e[1]=s.id,e[2]=s.regions,e[3]=o,e[4]=l,e[5]=c,e[6]=i,e[7]=r,e[8]=f,e[9]=m,e[10]=d}else r=e[7],f=e[8],m=e[9],d=e[10];let g;e[17]!==n.column||e[18]!==f?(g=t.jsx(Ue,{column:n.column,stroke:f}),e[17]=n.column,e[18]=f,e[19]=g):g=e[19];let u;return e[20]!==r||e[21]!==m||e[22]!==d||e[23]!==g?(u=t.jsxs(r,{style:m,children:[d,g]}),e[20]=r,e[21]=m,e[22]=d,e[23]=g,e[24]=u):u=e[24],u}function Ue(a){const e=F.c(7),{column:s,stroke:n}=a,o=`${Math.max(1,n/2)}px dashed rgba(114, 231, 170, 0.6)`,c=n*2;let l;return e[0]!==s.height||e[1]!==s.width||e[2]!==s.x||e[3]!==s.y||e[4]!==o||e[5]!==c?(l=t.jsx("div",{style:{position:"absolute",left:s.x,top:s.y,width:s.width,height:s.height,border:o,borderRadius:c}}),e[0]=s.height,e[1]=s.width,e[2]=s.x,e[3]=s.y,e[4]=o,e[5]=c,e[6]=l):l=e[6],l}function Ke(a){const e=F.c(34),{mediaUrl:s,sourceWidth:n,sourceHeight:o,cues:c,phrases:l,settings:i,showRegions:h}=a,r=be(),{fps:f,width:m,height:d}=xe();let g;e[0]!==d||e[1]!==o||e[2]!==n||e[3]!==m?(g=ke({sourceWidth:n,sourceHeight:o,targetWidth:m,targetHeight:d}),e[0]=d,e[1]=o,e[2]=n,e[3]=m,e[4]=g):g=e[4];const u=g,j=r/f;let v;e[5]!==c||e[6]!==j?(v=Ce(c,j),e[5]=c,e[6]=j,e[7]=v):v=e[7];const C=v;let y;e[8]!==C||e[9]!==l?(y=C?l.find(M=>M.id===C.id):void 0,e[8]=C,e[9]=l,e[10]=y):y=e[10];const w=y;let $;e[11]===Symbol.for("react.memo_cache_sentinel")?($={background:"#000000"},e[11]=$):$=e[11];let b;e[12]!==u.height||e[13]!==u.width||e[14]!==u.x||e[15]!==u.y?(b={position:"absolute",left:u.x,top:u.y,width:u.width,height:u.height},e[12]=u.height,e[13]=u.width,e[14]=u.x,e[15]=u.y,e[16]=b):b=e[16];let N;e[17]!==s||e[18]!==b?(N=t.jsx(Se,{src:s,style:b}),e[17]=s,e[18]=b,e[19]=N):N=e[19];let P;e[20]!==C||e[21]!==w||e[22]!==i||e[23]!==h||e[24]!==o||e[25]!==n?(P=h&&C&&w&&t.jsx(De,{phrase:w,cue:C,settings:i,sourceWidth:n,sourceHeight:o}),e[20]=C,e[21]=w,e[22]=i,e[23]=h,e[24]=o,e[25]=n,e[26]=P):P=e[26];let x;e[27]!==c||e[28]!==i?(x=t.jsx(we,{cues:c,settings:i,strokeWidth:6,strokeColor:"#000000",shadowBlur:6,shadowOpacity:60}),e[27]=c,e[28]=i,e[29]=x):x=e[29];let k;return e[30]!==N||e[31]!==P||e[32]!==x?(k=t.jsxs(pe,{style:$,children:[N,P,x]}),e[30]=N,e[31]=P,e[32]=x,e[33]=k):k=e[33],k}const ue=[{id:"stack",label:"Stack",hint:"Words land one by one and build a stacked block beside the subject, each line sized to fill the column."},{id:"punch",label:"Punch",hint:"One word at a time, as big as the free space allows. Best on fast verses."},{id:"karaoke",label:"Karaoke",hint:"The whole stacked phrase shows dimmed and lights up word by word."}],Ve=[{id:"pop",label:"Pop"},{id:"slam",label:"Slam"},{id:"rise",label:"Rise"}],Ge=[{name:"Green",color:"#72E7AA"},{name:"Pink",color:"#F0B9D0"},{name:"Cyan",color:"#63C7D8"},{name:"Amber",color:"#E7C372"}];function Xe(a,e){if(!a.drifted)return de(a.start);const s=a.driftMs>0?"+":"";return e?`${de(a.start)} · snapped`:`${de(a.start)} · ${s}${a.driftMs}ms`}function qe(a){const e=F.c(21),{rows:s,phraseLabels:n,activePhrase:o,time:c,snapped:l,onSeek:i}=a;let h;e[0]===Symbol.for("react.memo_cache_sentinel")?(h=t.jsx("h3",{children:"Transcript"}),e[0]=h):h=e[0];let r;e[1]!==s.length?(r=t.jsxs("header",{className:"alive-panel-header",children:[h,t.jsxs("p",{children:[s.length," words · timed to the vocal"]})]}),e[1]=s.length,e[2]=r):r=e[2];let f;if(e[3]!==o||e[4]!==i||e[5]!==n||e[6]!==s||e[7]!==l||e[8]!==c){let g;e[10]!==o||e[11]!==i||e[12]!==s||e[13]!==l||e[14]!==c?(g=(u,j)=>t.jsxs("div",{className:"alive-phrase","data-active":j===o||void 0,children:[t.jsxs("div",{className:"alive-phrase-head",children:[t.jsxs("span",{children:["Phrase ",j+1]}),t.jsx("span",{children:u})]}),t.jsx("div",{className:"alive-phrase-words",children:s.filter(v=>v.phraseIndex===j).map(v=>t.jsxs("button",{type:"button",className:"alive-word","data-active":c>=v.start&&c<v.end||void 0,"data-drifted":v.drifted&&!l||void 0,onClick:()=>i(v.start+.03),children:[t.jsx("span",{children:v.text}),t.jsx("small",{children:Xe(v,l)})]},v.key))})]},`${j}-${u}`),e[10]=o,e[11]=i,e[12]=s,e[13]=l,e[14]=c,e[15]=g):g=e[15],f=n.map(g),e[3]=o,e[4]=i,e[5]=n,e[6]=s,e[7]=l,e[8]=c,e[9]=f}else f=e[9];let m;e[16]!==f?(m=t.jsx("div",{className:"alive-transcript-list",children:f}),e[16]=f,e[17]=m):m=e[17];let d;return e[18]!==r||e[19]!==m?(d=t.jsxs("section",{className:"alive-panel alive-transcript","aria-label":"Transcript",children:[r,m]}),e[18]=r,e[19]=m,e[20]=d):d=e[20],d}function ve(a){const e=F.c(10),{label:s,options:n,value:o,onChange:c}=a;let l;if(e[0]!==c||e[1]!==n||e[2]!==o){let h;e[4]!==c||e[5]!==o?(h=r=>t.jsx("button",{type:"button","aria-pressed":r.id===o,onClick:()=>c(r.id),children:r.label},r.id),e[4]=c,e[5]=o,e[6]=h):h=e[6],l=n.map(h),e[0]=c,e[1]=n,e[2]=o,e[3]=l}else l=e[3];let i;return e[7]!==s||e[8]!==l?(i=t.jsx("div",{className:"alive-segmented",role:"group","aria-label":s,children:l}),e[7]=s,e[8]=l,e[9]=i):i=e[9],i}function re(a){const e=F.c(8),{checked:s,onChange:n,children:o}=a;let c;e[0]!==n?(c=h=>n(h.target.checked),e[0]=n,e[1]=c):c=e[1];let l;e[2]!==s||e[3]!==c?(l=t.jsx("input",{type:"checkbox",checked:s,onChange:c}),e[2]=s,e[3]=c,e[4]=l):l=e[4];let i;return e[5]!==o||e[6]!==l?(i=t.jsxs("label",{className:"alive-toggle",children:[l,o]}),e[5]=o,e[6]=l,e[7]=i):i=e[7],i}function Ye(a){const e=F.c(69),{settings:s,showRegions:n,regionsAnalyzed:o,working:c,onChange:l,onShowRegions:i,onReanalyze:h}=a;let r;e[0]!==s.style?(r=ue.find(S=>S.id===s.style)?.hint,e[0]=s.style,e[1]=r):r=e[1];const f=r;let m;e[2]===Symbol.for("react.memo_cache_sentinel")?(m=t.jsx("h4",{children:"Style"}),e[2]=m):m=e[2];let d;e[3]!==l?(d=S=>l({style:S}),e[3]=l,e[4]=d):d=e[4];let g;e[5]!==s.style||e[6]!==d?(g=t.jsx(ve,{label:"Caption style",options:ue,value:s.style,onChange:d}),e[5]=s.style,e[6]=d,e[7]=g):g=e[7];let u;e[8]!==f?(u=t.jsx("p",{className:"alive-hint",children:f}),e[8]=f,e[9]=u):u=e[9];let j;e[10]!==g||e[11]!==u?(j=t.jsxs("div",{className:"alive-field",children:[m,g,u]}),e[10]=g,e[11]=u,e[12]=j):j=e[12];let v;e[13]===Symbol.for("react.memo_cache_sentinel")?(v=t.jsx("h4",{children:"Word entrance"}),e[13]=v):v=e[13];let C;e[14]!==l?(C=S=>l({motion:S}),e[14]=l,e[15]=C):C=e[15];let y;e[16]!==s.motion||e[17]!==C?(y=t.jsxs("div",{className:"alive-field",children:[v,t.jsx(ve,{label:"Word entrance",options:Ve,value:s.motion,onChange:C})]}),e[16]=s.motion,e[17]=C,e[18]=y):y=e[18];let w;e[19]===Symbol.for("react.memo_cache_sentinel")?(w=t.jsx("h4",{children:"Frame awareness"}),e[19]=w):w=e[19];let $;e[20]!==l?($=S=>l({avoidFaces:S}),e[20]=l,e[21]=$):$=e[21];let b;e[22]!==s.avoidFaces||e[23]!==$?(b=t.jsx(re,{checked:s.avoidFaces,onChange:$,children:"Keep words off faces"}),e[22]=s.avoidFaces,e[23]=$,e[24]=b):b=e[24];let N;e[25]!==l?(N=S=>l({avoidText:S}),e[25]=l,e[26]=N):N=e[26];let P;e[27]!==s.avoidText||e[28]!==N?(P=t.jsx(re,{checked:s.avoidText,onChange:N,children:"Keep words off on-screen text"}),e[27]=s.avoidText,e[28]=N,e[29]=P):P=e[29];let x;e[30]!==i||e[31]!==n?(x=t.jsx(re,{checked:n,onChange:i,children:"Show detected regions"}),e[30]=i,e[31]=n,e[32]=x):x=e[32];let k;e[33]!==o?(k=!o&&t.jsx("p",{className:"alive-hint alive-warning",children:"Face and text detection did not run, so stacks use the default columns. Set OPENAI_API_KEY and re-run the analysis."}),e[33]=o,e[34]=k):k=e[34];let M;e[35]!==b||e[36]!==P||e[37]!==x||e[38]!==k?(M=t.jsxs("div",{className:"alive-field",children:[w,b,P,x,k]}),e[35]=b,e[36]=P,e[37]=x,e[38]=k,e[39]=M):M=e[39];let D;e[40]===Symbol.for("react.memo_cache_sentinel")?(D=t.jsx("h4",{children:"Audio"}),e[40]=D):D=e[40];let O;e[41]!==l?(O=S=>l({energySizing:S}),e[41]=l,e[42]=O):O=e[42];let _;e[43]!==s.energySizing||e[44]!==O?(_=t.jsxs("div",{className:"alive-field",children:[D,t.jsx(re,{checked:s.energySizing,onChange:O,children:"Size words by vocal energy"})]}),e[43]=s.energySizing,e[44]=O,e[45]=_):_=e[45];let H;e[46]===Symbol.for("react.memo_cache_sentinel")?(H=t.jsx("h4",{children:"Hit color"}),e[46]=H):H=e[46];let W;e[47]!==l||e[48]!==s.hitColor?(W=Ge.map(S=>t.jsx("button",{type:"button","aria-label":S.name,"aria-pressed":s.hitColor.toUpperCase()===S.color,onClick:()=>l({hitColor:S.color}),children:t.jsx("span",{style:{background:S.color}})},S.color)),e[47]=l,e[48]=s.hitColor,e[49]=W):W=e[49];let R;e[50]===Symbol.for("react.memo_cache_sentinel")?(R=t.jsx("span",{children:"Text"}),e[50]=R):R=e[50];let p;e[51]!==l?(p=S=>l({textColor:S.target.value.toUpperCase()}),e[51]=l,e[52]=p):p=e[52];let L;e[53]!==s.textColor||e[54]!==p?(L=t.jsxs("label",{className:"alive-color-input",children:[R,t.jsx("input",{type:"color",value:s.textColor,onChange:p})]}),e[53]=s.textColor,e[54]=p,e[55]=L):L=e[55];let I;e[56]!==W||e[57]!==L?(I=t.jsxs("div",{className:"alive-field",children:[H,t.jsxs("div",{className:"alive-swatches",children:[W,L]})]}),e[56]=W,e[57]=L,e[58]=I):I=e[58];let z;e[59]!==h||e[60]!==c?(z=t.jsx("div",{className:"alive-field",children:t.jsx("button",{type:"button",className:"alive-secondary",disabled:c,onClick:h,children:"Re-run analysis"})}),e[59]=h,e[60]=c,e[61]=z):z=e[61];let B;return e[62]!==M||e[63]!==_||e[64]!==I||e[65]!==z||e[66]!==j||e[67]!==y?(B=t.jsxs("section",{className:"alive-panel alive-settings","aria-label":"Caption settings",children:[j,y,M,_,I,z]}),e[62]=M,e[63]=_,e[64]=I,e[65]=z,e[66]=j,e[67]=y,e[68]=B):B=e[68],B}const Je=90;function U(a,e){return`${Math.max(0,a)/e*100}%`}function Qe(a,e,s){if(e.count===0)return`All ${s} words already sit on their vocal onsets`;if(a)return`${e.count} words snapped to their vocal onsets`;const n=e.minMs===e.maxMs?`${e.maxMs}`:`${e.minMs}–${e.maxMs}`;return`${e.count} words start ${n} ms off the vocal`}function Ze(a){const e=a>120?10:a>30?5:1,s=[];for(let n=0;n<=a;n+=e)s.push(n);return s}function et(a,e,s){const n=F.c(5),o=A.useRef(null);let c,l;return n[0]!==e||n[1]!==s||n[2]!==a?(c=()=>{const i=o.current;if(!i||!s)return;const h=a/e*i.scrollWidth;(h<i.scrollLeft||h>i.scrollLeft+i.clientWidth*.85)&&(i.scrollLeft=Math.max(0,h-i.clientWidth*.2))},l=[a,e,s],n[0]=e,n[1]=s,n[2]=a,n[3]=c,n[4]=l):(c=n[3],l=n[4]),A.useEffect(c,l),o}function tt(a){const e=F.c(105),{duration:s,fps:n,time:o,playing:c,envelope:l,rows:i,cues:h,activeCue:r,snapped:f,drift:m}=a,d=Math.max(s,.1),g=et(o,d,c);let u;e[0]!==a||e[1]!==d?(u=T=>{const E=T.currentTarget.getBoundingClientRect();a.onSeek((T.clientX-E.left)/E.width*d)},e[0]=a,e[1]=d,e[2]=u):u=e[2];const j=u;let v;e[3]!==a?(v=()=>a.onStep(-1),e[3]=a,e[4]=v):v=e[4];let C;e[5]===Symbol.for("react.memo_cache_sentinel")?(C=t.jsx(Le,{size:16}),e[5]=C):C=e[5];let y;e[6]!==v?(y=t.jsx("button",{type:"button","aria-label":"Previous frame",onClick:v,children:C}),e[6]=v,e[7]=y):y=e[7];const w=c?"Pause":"Play";let $;e[8]!==c?($=c?t.jsx(ze,{size:16}):t.jsx(Fe,{size:16}),e[8]=c,e[9]=$):$=e[9];let b;e[10]!==a.onTogglePlay||e[11]!==w||e[12]!==$?(b=t.jsx("button",{type:"button",className:"alive-play","aria-label":w,onClick:a.onTogglePlay,children:$}),e[10]=a.onTogglePlay,e[11]=w,e[12]=$,e[13]=b):b=e[13];let N;e[14]!==a?(N=()=>a.onStep(1),e[14]=a,e[15]=N):N=e[15];let P;e[16]===Symbol.for("react.memo_cache_sentinel")?(P=t.jsx(He,{size:16}),e[16]=P):P=e[16];let x;e[17]!==N?(x=t.jsx("button",{type:"button","aria-label":"Next frame",onClick:N,children:P}),e[17]=N,e[18]=x):x=e[18];let k;e[19]!==o?(k=de(o),e[19]=o,e[20]=k):k=e[20];let M;e[21]!==k?(M=t.jsx("strong",{className:"alive-clock",children:k}),e[21]=k,e[22]=M):M=e[22];const D=Math.floor(o*n),O=Math.floor(d*n);let _;e[23]!==D||e[24]!==O?(_=t.jsxs("span",{className:"alive-muted",children:["frame ",D," / ",O]}),e[23]=D,e[24]=O,e[25]=_):_=e[25];let H;e[26]===Symbol.for("react.memo_cache_sentinel")?(H=t.jsx("span",{className:"alive-spacer"}),e[26]=H):H=e[26];const W=m.count>0&&!f||void 0;let R;e[27]!==m||e[28]!==i.length||e[29]!==f?(R=Qe(f,m,i.length),e[27]=m,e[28]=i.length,e[29]=f,e[30]=R):R=e[30];let p;e[31]!==W||e[32]!==R?(p=t.jsx("span",{className:"alive-drift","data-drifted":W,children:R}),e[31]=W,e[32]=R,e[33]=p):p=e[33];const L=f?"alive-secondary":"alive-primary alive-warn",I=m.count===0,z=f?"Use transcript timing":"Snap words to audio";let B;e[34]!==a.onToggleSnap||e[35]!==L||e[36]!==I||e[37]!==z?(B=t.jsx("button",{type:"button",className:L,disabled:I,onClick:a.onToggleSnap,children:z}),e[34]=a.onToggleSnap,e[35]=L,e[36]=I,e[37]=z,e[38]=B):B=e[38];let S;e[39]!==M||e[40]!==_||e[41]!==p||e[42]!==B||e[43]!==y||e[44]!==b||e[45]!==x?(S=t.jsxs("div",{className:"alive-transport",children:[y,b,x,M,_,H,p,B]}),e[39]=M,e[40]=_,e[41]=p,e[42]=B,e[43]=y,e[44]=b,e[45]=x,e[46]=S):S=e[46];let ne;e[47]===Symbol.for("react.memo_cache_sentinel")?(ne=t.jsxs("div",{className:"alive-lane-labels","aria-hidden":"true",children:[t.jsx("span",{className:"alive-lane-ruler"}),t.jsx("span",{className:"alive-lane-audio",children:"Audio"}),t.jsx("span",{className:"alive-lane-words",children:"Words"}),t.jsx("span",{className:"alive-lane-stacks",children:"Stacks"})]}),e[47]=ne):ne=e[47];const he=d*Je;let K;e[48]!==he?(K={minWidth:he},e[48]=he,e[49]=K):K=e[49];let V;e[50]!==d?(V=Ze(d).map(T=>t.jsxs("span",{style:{left:U(T,d)},children:[T,"s"]},T)),e[50]=d,e[51]=V):V=e[51];let G;e[52]!==V?(G=t.jsx("div",{className:"alive-lane-ruler",children:V}),e[52]=V,e[53]=G):G=e[53];let X;e[54]!==l?(X=Te(l),e[54]=l,e[55]=X):X=e[55];let q;e[56]!==X?(q=t.jsx("svg",{viewBox:"0 0 1000 100",preserveAspectRatio:"none","aria-hidden":"true",children:t.jsx("path",{d:X})}),e[56]=X,e[57]=q):q=e[57];let Y;e[58]!==i||e[59]!==d||e[60]!==f?(Y=!f&&i.filter(st).map(T=>t.jsx("span",{className:"alive-onset",style:{left:U(T.onset,d)}},T.key)),e[58]=i,e[59]=d,e[60]=f,e[61]=Y):Y=e[61];let J;e[62]!==q||e[63]!==Y?(J=t.jsxs("div",{className:"alive-lane-audio",children:[q,Y]}),e[62]=q,e[63]=Y,e[64]=J):J=e[64];let Q;if(e[65]!==i||e[66]!==d||e[67]!==f||e[68]!==o){let T;e[70]!==d||e[71]!==f||e[72]!==o?(T=E=>t.jsx("span",{className:"alive-chip","data-active":o>=E.start&&o<E.end||void 0,"data-drifted":E.drifted&&!f||void 0,style:{left:U(E.start,d),width:U(E.end-E.start,d)},children:E.text},E.key),e[70]=d,e[71]=f,e[72]=o,e[73]=T):T=e[73],Q=i.map(T),e[65]=i,e[66]=d,e[67]=f,e[68]=o,e[69]=Q}else Q=e[69];let Z;e[74]!==Q?(Z=t.jsx("div",{className:"alive-lane-words",children:Q}),e[74]=Q,e[75]=Z):Z=e[75];let ee;if(e[76]!==r||e[77]!==h||e[78]!==d){let T;e[80]!==r||e[81]!==d?(T=(E,ye)=>t.jsx("span",{className:"alive-stack-bar","data-active":ye===r||void 0,style:{left:U(E.start,d),width:U(E.end-E.start,d)},children:me(E)},E.id),e[80]=r,e[81]=d,e[82]=T):T=e[82],ee=h.map(T),e[76]=r,e[77]=h,e[78]=d,e[79]=ee}else ee=e[79];let te;e[83]!==ee?(te=t.jsx("div",{className:"alive-lane-stacks",children:ee}),e[83]=ee,e[84]=te):te=e[84];let se;e[85]!==d||e[86]!==o?(se=U(o,d),e[85]=d,e[86]=o,e[87]=se):se=e[87];let le;e[88]!==se?(le=t.jsx("span",{className:"alive-playhead",style:{left:se}}),e[88]=se,e[89]=le):le=e[89];let ae;e[90]!==j||e[91]!==K||e[92]!==G||e[93]!==J||e[94]!==Z||e[95]!==te||e[96]!==le?(ae=t.jsxs("div",{className:"alive-lane-tracks",style:K,onClick:j,role:"presentation",children:[G,J,Z,te,le]}),e[90]=j,e[91]=K,e[92]=G,e[93]=J,e[94]=Z,e[95]=te,e[96]=le,e[97]=ae):ae=e[97];let ie;e[98]!==g||e[99]!==ae?(ie=t.jsxs("div",{className:"alive-lanes",children:[ne,t.jsx("div",{className:"alive-lane-scroll",ref:g,children:ae})]}),e[98]=g,e[99]=ae,e[100]=ie):ie=e[100];let oe;e[101]===Symbol.for("react.memo_cache_sentinel")?(oe=t.jsxs("div",{className:"alive-legend","aria-hidden":"true",children:[t.jsxs("span",{children:[t.jsx("i",{className:"alive-legend-chip"}),"Transcript word"]}),t.jsxs("span",{children:[t.jsx("i",{className:"alive-legend-drift"}),"Word off its vocal onset"]}),t.jsxs("span",{children:[t.jsx("i",{className:"alive-legend-onset"}),"Detected vocal onset"]})]}),e[101]=oe):oe=e[101];let ce;return e[102]!==S||e[103]!==ie?(ce=t.jsxs("section",{className:"alive-panel alive-timeline","aria-label":"Caption timeline",children:[S,ie,oe]}),e[102]=S,e[103]=ie,e[104]=ce):ce=e[104],ce}function st(a){return a.drifted}const ge=30;function lt(a){const e=F.c(3),s=A.useRef(null);let n,o;return e[0]!==a?(n=()=>{const c=s.current;return c?.showModal(),c?.querySelector(".alive-close")?.focus(),()=>{c?.close(),We(a)}},o=[a],e[0]=a,e[1]=n,e[2]=o):(n=e[1],o=e[2]),A.useEffect(n,o),s}function at(a){const e=F.c(6),[s,n]=A.useState(0),[o,c]=A.useState(!1);let l,i;e[0]!==a?(l=()=>{const r=a.current;if(!r)return;const f=g=>n(g.detail.frame),m=()=>c(!0),d=()=>c(!1);return r.addEventListener("frameupdate",f),r.addEventListener("play",m),r.addEventListener("pause",d),()=>{r.removeEventListener("frameupdate",f),r.removeEventListener("play",m),r.removeEventListener("pause",d)}},i=[a],e[0]=a,e[1]=l,e[2]=i):(l=e[1],i=e[2]),A.useEffect(l,i);let h;return e[3]!==s||e[4]!==o?(h={frame:s,playing:o},e[3]=s,e[4]=o,e[5]=h):h=e[5],h}function ft(a){const e=F.c(14),{asset:s,state:n,returnFocus:o,onClose:c}=a,l=lt(o),i=`Alive captions for ${s.label}`;let h;e[0]!==c?(h=m=>{m.preventDefault(),c()},e[0]=c,e[1]=h):h=e[1];let r;e[2]!==s.label||e[3]!==c||e[4]!==a||e[5]!==n.data||e[6]!==n.message||e[7]!==n.status?(r=n.status==="ready"?t.jsx(it,{...a,data:n.data}):t.jsxs("div",{className:"alive-studio-message",children:[t.jsx(je,{label:s.label,detail:null,onClose:c}),t.jsx("p",{role:n.status==="error"?"alert":"status",children:n.status==="error"?n.message:"Analysing vocals, phrases and faces…"})]}),e[2]=s.label,e[3]=c,e[4]=a,e[5]=n.data,e[6]=n.message,e[7]=n.status,e[8]=r):r=e[8];let f;return e[9]!==l||e[10]!==i||e[11]!==h||e[12]!==r?(f=t.jsx("dialog",{className:"alive-studio","aria-label":i,onCancel:h,ref:l,children:r}),e[9]=l,e[10]=i,e[11]=h,e[12]=r,e[13]=f):f=e[13],f}function je(a){const e=F.c(12),{label:s,detail:n,onClose:o,children:c}=a;let l;e[0]===Symbol.for("react.memo_cache_sentinel")?(l=t.jsx("h2",{children:"Alive captions"}),e[0]=l):l=e[0];const i=n?` · ${n}`:"";let h;e[1]!==s||e[2]!==i?(h=t.jsxs("span",{className:"alive-muted",children:[s,i]}),e[1]=s,e[2]=i,e[3]=h):h=e[3];let r;e[4]===Symbol.for("react.memo_cache_sentinel")?(r=t.jsx("span",{className:"alive-spacer"}),e[4]=r):r=e[4];let f;e[5]===Symbol.for("react.memo_cache_sentinel")?(f=t.jsx(Ie,{size:16}),e[5]=f):f=e[5];let m;e[6]!==o?(m=t.jsx("button",{type:"button",className:"alive-close","aria-label":"Close alive captions",onClick:o,children:f}),e[6]=o,e[7]=m):m=e[7];let d;return e[8]!==c||e[9]!==h||e[10]!==m?(d=t.jsxs("header",{className:"alive-header",children:[l,h,r,c,m]}),e[8]=c,e[9]=h,e[10]=m,e[11]=d):d=e[11],d}function it({asset:a,data:e,onClose:s,onSave:n,onRender:o,onReanalyze:c}){const{analysis:l}=e,i=Math.round(a.fps??ge)||ge,h=Math.max(1,Math.round(l.durationSeconds*i)),[r,f]=A.useState(e.settings),[m,d]=A.useState(()=>Re(a.width,a.height)),[g,u]=A.useState(!0),[j,v]=A.useState(null),[C,y]=A.useState(null),w=A.useRef(null),{frame:$,playing:b}=at(w),N=$/i,P=A.useMemo(()=>Ae(l,m),[l,m]),x=A.useMemo(()=>Me(l.phrases,r,P),[l.phrases,r,P]),k=A.useMemo(()=>_e(l,r),[l,r]),M=A.useMemo(()=>Ee(k),[k]),D=A.useMemo(()=>({mediaUrl:a.mediaUrl,sourceWidth:l.sourceWidth,sourceHeight:l.sourceHeight,cues:x,phrases:l.phrases,settings:r,showRegions:g}),[a.mediaUrl,l,x,r,g]),O=Oe(x,N),_=p=>w.current?.seekTo(Math.max(0,Math.min(h-1,Math.round(p*i)))),H=p=>f(L=>({...L,...p})),W=async(p,L,I)=>{v(p),y(null);try{await L(),y(I)}catch(z){y(z instanceof Error?z.message:String(z))}finally{v(null)}},R=fe.find(p=>p.id===m)??fe[0];return t.jsxs("div",{className:"alive-studio-body",children:[t.jsxs(je,{label:a.label,detail:`${l.sourceWidth}×${l.sourceHeight} · ${i} fps`,onClose:s,children:[t.jsx("div",{className:"alive-segmented",role:"group","aria-label":"Preview orientation",children:fe.map(p=>t.jsx("button",{type:"button","aria-pressed":p.id===m,onClick:()=>d(p.id),children:p.label},p.id))}),t.jsx("button",{type:"button",className:"alive-secondary",disabled:j!==null,onClick:()=>{W("Saving",()=>n(r),"Saved. Renders of this video now use alive captions.")},children:"Save"}),t.jsxs("button",{type:"button",className:"alive-primary",disabled:j!==null,onClick:()=>{W("Rendering",()=>o(r,m),`Saved and queued a ${R.label} render.`)},children:["Render ",R.label]})]}),t.jsxs("div",{className:"alive-main",children:[t.jsx(qe,{rows:k,phraseLabels:x.map(me),activePhrase:O,time:N,snapped:r.snapToOnsets,onSeek:_}),t.jsxs("div",{className:"alive-stage",children:[t.jsx("div",{className:"alive-player",style:{aspectRatio:`${R.width} / ${R.height}`},children:t.jsx(Ne,{ref:w,component:Ke,inputProps:D,durationInFrames:h,fps:i,compositionWidth:R.width,compositionHeight:R.height,style:{width:"100%",height:"100%"},clickToPlay:!0,spaceKeyToPlayOrPause:!0})}),t.jsx("p",{className:"alive-status",role:"status",children:j?`${j}…`:C??(O>=0?`${me(x[O])} · ${x[O].lines.length} lines`:"Between phrases")})]}),t.jsx(Ye,{settings:r,showRegions:g,regionsAnalyzed:l.regionsAnalyzed,working:j!==null,onChange:H,onShowRegions:u,onReanalyze:()=>{W("Re-running analysis",c,"Analysis refreshed.")}})]}),t.jsx(tt,{duration:l.durationSeconds,fps:i,time:N,playing:b,envelope:l.envelope,rows:k,cues:x,activeCue:O,snapped:r.snapToOnsets,drift:M,onSeek:_,onStep:p=>_(N+p/i),onTogglePlay:()=>w.current?.toggle(),onToggleSnap:()=>H({snapToOnsets:!r.snapToOnsets})})]})}export{ft as AliveCaptionsStudio};