cozyclay 2.1.1 → 3.0.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 (577) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.md +12 -30
  3. package/bin/agent/agent-routes.mjs +40 -113
  4. package/bin/agent/agent-runner.mjs +9 -10
  5. package/bin/agent/cliproxy-provider.mjs +135 -0
  6. package/bin/agent/credential-store.mjs +30 -7
  7. package/bin/agent/pi-tools.mjs +4 -1
  8. package/bin/agent/provider-keys.mjs +32 -0
  9. package/bin/agent/provider-login.mjs +110 -0
  10. package/bin/agent/provider-routes.mjs +99 -0
  11. package/bin/agent/providers.mjs +19 -97
  12. package/bin/agent/script-tool.mjs +17 -4
  13. package/bin/agent/studio-motion-reference.mjs +23 -0
  14. package/bin/agent/studio-prompt.mjs +1 -1
  15. package/bin/agent/studio-rebase-text.mjs +32 -0
  16. package/bin/agent/studio-rebase.mjs +26 -39
  17. package/bin/agent/studio-tools.mjs +9 -28
  18. package/bin/agent/tool-arguments.mjs +49 -0
  19. package/bin/agent/turn-frames.mjs +66 -0
  20. package/bin/codex-auth.mjs +9 -2
  21. package/bin/cozyclay.mjs +10 -116
  22. package/bin/live/cli.mjs +3 -3
  23. package/bin/mcp-runtime.mjs +2 -12
  24. package/bin/package-signature.mjs +0 -4
  25. package/dist/app/index.html +7 -6
  26. package/dist/assets/EXRLoader-CvVIvGVE.js +1 -0
  27. package/dist/assets/analytics-C9sUnndd.js +1 -0
  28. package/dist/assets/app-CCh--1Hc.js +5087 -0
  29. package/dist/assets/app-f-fkV5uP.css +1 -0
  30. package/dist/assets/compile-worker-CkxiD6lH.js +5 -0
  31. package/dist/assets/fflate.module-KbGj5-H6.js +5 -0
  32. package/dist/assets/{first-shot-handoff-msLI71g1.js → first-shot-handoff-CC4xe4HM.js} +1 -1
  33. package/dist/assets/{landing-ChUvB_zL.js → landing-DjHD8u7k.js} +1 -1
  34. package/dist/assets/scene-asset-sync-Hx_FzdOH.js +20 -0
  35. package/dist/assets/scene-asset-sync-_S8NQl5B.css +1 -0
  36. package/dist/assets/workflow-C4yKH1p4.js +179 -0
  37. package/dist/cozyclay-package.json +1 -1
  38. package/dist/index.html +3 -3
  39. package/dist/sw.js +3 -6
  40. package/dist/workflow/index.html +5 -4
  41. package/mcp/LIVE-PROTOCOL.md +7 -47
  42. package/mcp/README.md +16 -26
  43. package/mcp/live-hub.mjs +6 -10
  44. package/mcp/package.json +1 -3
  45. package/mcp/tool-handlers.mjs +4 -168
  46. package/package.json +3 -22
  47. package/src/App.jsx +150 -2624
  48. package/src/agent-progress.js +79 -0
  49. package/src/agent-turn-mark.js +30 -0
  50. package/src/analytics.js +1 -19
  51. package/src/app-context.js +5 -0
  52. package/src/app-stage.jsx +2 -34
  53. package/src/asset-pane.jsx +6 -5
  54. package/src/camera-block.js +21 -0
  55. package/src/camera-direction.js +120 -0
  56. package/src/character-kind.js +3 -9
  57. package/src/command-bus.js +8 -6
  58. package/src/commands/cast.js +5 -34
  59. package/src/commands/elements/character.js +1 -1
  60. package/src/commands/elements/motion.js +1 -6
  61. package/src/commands/elements/object.js +6 -2
  62. package/src/commands/elements/shot.js +4 -1
  63. package/src/commands/elements.js +38 -14
  64. package/src/commands/index.js +3 -1
  65. package/src/commands/kits.js +37 -0
  66. package/src/commands/motion-timing.js +57 -0
  67. package/src/commands/motion.js +9 -152
  68. package/src/commands/motion3-compile.js +65 -0
  69. package/src/commands/motion3.js +207 -0
  70. package/src/commands/objects.js +6 -4
  71. package/src/commands/shot.js +49 -11
  72. package/src/commands/stage.js +14 -1
  73. package/src/commands/view.js +4 -1
  74. package/src/document-mirrors.js +42 -0
  75. package/src/document-store.js +4 -0
  76. package/src/domains/cast.js +19 -194
  77. package/src/domains/motion/motion-range-pin-rules.js +1 -1
  78. package/src/domains/motion/take-source.js +51 -0
  79. package/src/domains/motion.js +60 -1838
  80. package/src/domains/scenes.js +12 -55
  81. package/src/domains/shots.js +2 -2
  82. package/src/domains/stage.js +4 -2
  83. package/src/draft-ghost.js +46 -0
  84. package/src/draft-ghost.jsx +129 -0
  85. package/src/dualview.jsx +4 -3
  86. package/src/effects/EffectsLayer.jsx +112 -0
  87. package/src/effects/effect-meshes.js +232 -0
  88. package/src/effects/effect-record.js +103 -0
  89. package/src/effects/emitter.js +59 -0
  90. package/src/effects/simulate.js +261 -0
  91. package/src/effects/state.js +59 -0
  92. package/src/execution-telemetry.js +2 -3
  93. package/src/first-success-guide.jsx +5 -5
  94. package/src/ghost-set.js +257 -0
  95. package/src/held-object-edit.jsx +113 -0
  96. package/src/held-object-pose.js +175 -0
  97. package/src/hierarchy-model.js +1 -1
  98. package/src/hierarchy-panel.jsx +1 -1
  99. package/src/imported-mesh.jsx +103 -0
  100. package/src/kits/held.js +84 -0
  101. package/src/kits/index.js +70 -0
  102. package/src/kits/smoking.js +57 -0
  103. package/src/light-blockers.js +93 -0
  104. package/src/motion/beat-board-model.js +84 -0
  105. package/src/motion/beat-board.css +124 -0
  106. package/src/motion/beat-board.jsx +59 -0
  107. package/src/motion/center-of-mass.js +66 -0
  108. package/src/motion/fix-collisions.js +850 -0
  109. package/src/motion/physics-review.js +118 -0
  110. package/src/{ardy → motion}/physics-support.js +1 -76
  111. package/src/motion/rig-snapshot.js +22 -0
  112. package/src/motion/take-segments.jsx +140 -0
  113. package/src/{ardy → motion}/timeline-coordinates.js +0 -21
  114. package/src/{ardy → motion}/timeline.css +1 -2
  115. package/src/{ardy → motion}/timeline.jsx +42 -413
  116. package/src/motion/waypoints.js +76 -0
  117. package/src/motion3/beats.js +83 -0
  118. package/src/motion3/body.js +158 -0
  119. package/src/motion3/bones.js +47 -0
  120. package/src/motion3/carried.js +47 -0
  121. package/src/motion3/compile-job.js +75 -0
  122. package/src/motion3/compile-worker.js +10 -0
  123. package/src/motion3/compiler/anchors.js +105 -0
  124. package/src/motion3/compiler/arm-orient.js +128 -0
  125. package/src/motion3/compiler/channels.js +125 -0
  126. package/src/motion3/compiler/compile.js +205 -0
  127. package/src/motion3/compiler/gait-rhythm.js +97 -0
  128. package/src/motion3/compiler/grip.js +171 -0
  129. package/src/motion3/compiler/head-steady.js +48 -0
  130. package/src/motion3/compiler/hold.js +134 -0
  131. package/src/motion3/compiler/idle.js +113 -0
  132. package/src/motion3/compiler/limbs.js +170 -0
  133. package/src/motion3/compiler/math.js +72 -0
  134. package/src/motion3/compiler/pose.js +162 -0
  135. package/src/motion3/compiler/quat.js +49 -0
  136. package/src/motion3/compiler/skeleton.js +74 -0
  137. package/src/motion3/compiler/validate-common.js +32 -0
  138. package/src/motion3/compiler/validate-goals.js +118 -0
  139. package/src/motion3/compiler/validate-objects.js +143 -0
  140. package/src/motion3/compiler/validate-parts.js +116 -0
  141. package/src/motion3/compiler/validate.js +122 -0
  142. package/src/motion3/compiler/vocab.js +73 -0
  143. package/src/motion3/compiler/walk-pelvis.js +275 -0
  144. package/src/motion3/compiler/walk.js +207 -0
  145. package/src/motion3/compiler/wrist-clamp.js +32 -0
  146. package/src/motion3/delta.js +47 -0
  147. package/src/motion3/describe.js +174 -0
  148. package/src/motion3/docs.js +27 -0
  149. package/src/motion3/edit-carry.js +21 -0
  150. package/src/motion3/fix/ease.js +16 -0
  151. package/src/motion3/fix/ground.js +37 -0
  152. package/src/motion3/fix/index.js +52 -0
  153. package/src/motion3/fix/push.js +71 -0
  154. package/src/motion3/fix/reach.js +46 -0
  155. package/src/motion3/fix/retime.js +79 -0
  156. package/src/motion3/fix/self.js +211 -0
  157. package/src/motion3/fix/slide.js +70 -0
  158. package/src/motion3/fix/turn.js +51 -0
  159. package/src/motion3/follow.js +39 -0
  160. package/src/motion3/free-motion.js +173 -0
  161. package/src/motion3/grip-choice.js +130 -0
  162. package/src/motion3/hold-plan.js +157 -0
  163. package/src/motion3/json-patch.js +77 -0
  164. package/src/motion3/key-aim.js +105 -0
  165. package/src/motion3/key-edit.js +82 -0
  166. package/src/motion3/lenient.js +127 -0
  167. package/src/motion3/object-keys.js +236 -0
  168. package/src/motion3/object-pose.js +182 -0
  169. package/src/motion3/object-tracks.js +12 -0
  170. package/src/motion3/pipeline.js +102 -0
  171. package/src/motion3/playback.js +51 -0
  172. package/src/motion3/probes.js +91 -0
  173. package/src/motion3/qa/body-checks.js +34 -0
  174. package/src/motion3/qa/check-names.js +14 -0
  175. package/src/motion3/qa/checks.js +121 -0
  176. package/src/motion3/qa/contact-checks.js +51 -0
  177. package/src/motion3/qa/explain.js +80 -0
  178. package/src/motion3/qa/fmt.js +5 -0
  179. package/src/motion3/qa/foot-checks.js +72 -0
  180. package/src/motion3/qa/geometry.js +77 -0
  181. package/src/motion3/qa/goals.js +191 -0
  182. package/src/motion3/qa/ground.js +60 -0
  183. package/src/motion3/qa/hints-contact.js +179 -0
  184. package/src/motion3/qa/hints-goal.js +160 -0
  185. package/src/motion3/qa/hints-knee.js +24 -0
  186. package/src/motion3/qa/hints-motion.js +209 -0
  187. package/src/motion3/qa/hints-object.js +91 -0
  188. package/src/motion3/qa/index.js +42 -0
  189. package/src/motion3/qa/key-checks.js +82 -0
  190. package/src/motion3/qa/near.js +96 -0
  191. package/src/motion3/qa/object-checks.js +135 -0
  192. package/src/motion3/qa/patch.js +161 -0
  193. package/src/motion3/qa/severity.js +38 -0
  194. package/src/motion3/qa/spec-checks.js +65 -0
  195. package/src/motion3/qa/style.js +218 -0
  196. package/src/motion3/qa/wrist-checks.js +69 -0
  197. package/src/motion3/qa/wrist-obs.js +60 -0
  198. package/src/motion3/refs.js +120 -0
  199. package/src/motion3/repair-tune.js +121 -0
  200. package/src/motion3/repair.js +83 -0
  201. package/src/motion3/report.js +67 -0
  202. package/src/motion3/rigs/index.js +14 -0
  203. package/src/motion3/rigs/x-bot-tpose-body.json +1 -0
  204. package/src/motion3/rigs/x-bot-tpose.json +1 -0
  205. package/src/motion3/rigs/y-bot-tpose-body.json +1 -0
  206. package/src/motion3/rigs/y-bot-tpose.json +1 -0
  207. package/src/motion3/scene.js +60 -0
  208. package/src/motion3/schema/brief.js +89 -0
  209. package/src/motion3/schema/fields.js +44 -0
  210. package/src/motion3/schema/spec-examples.js +46 -0
  211. package/src/motion3/schema/topics.js +111 -0
  212. package/src/motion3/schema/types.js +147 -0
  213. package/src/motion3/search.js +117 -0
  214. package/src/motion3/second-hand.js +112 -0
  215. package/src/motion3/skills/basic.js +82 -0
  216. package/src/motion3/skills/book.js +76 -0
  217. package/src/motion3/skills/car.js +145 -0
  218. package/src/motion3/skills/frames-auto.js +29 -0
  219. package/src/motion3/skills/index.js +83 -0
  220. package/src/motion3/skills/info.js +65 -0
  221. package/src/motion3/skills/smoke-kit.js +109 -0
  222. package/src/motion3/skills/smoke.js +160 -0
  223. package/src/motion3/spec-store.js +59 -0
  224. package/src/motion3/take-edit.js +155 -0
  225. package/src/motion3/take.js +63 -0
  226. package/src/motion3/timeline.js +127 -0
  227. package/src/motion3/views.js +121 -0
  228. package/src/motion3/walk-plan.js +119 -0
  229. package/src/object-catalog.jsx +7 -1
  230. package/src/object-colors.js +98 -0
  231. package/src/object-gizmo-parts.js +115 -0
  232. package/src/object-gizmo.jsx +37 -122
  233. package/src/object-glow.js +139 -0
  234. package/src/object-hidden.js +33 -0
  235. package/src/object-look.js +196 -0
  236. package/src/object-size.js +10 -0
  237. package/src/object-travel.js +71 -6
  238. package/src/panels/CameraPanel.jsx +7 -7
  239. package/src/panels/HdrEnvironmentControls.jsx +59 -0
  240. package/src/panels/LightPanel.jsx +25 -4
  241. package/src/panels/ObjectLookPanel.jsx +88 -0
  242. package/src/panels/PosePanel.jsx +2 -17
  243. package/src/panels/RigControlPanel.jsx +5 -53
  244. package/src/panels/SubjectBox.jsx +4 -1
  245. package/src/panels/details.css +14 -0
  246. package/src/posestudio.jsx +4 -27
  247. package/src/project-browser.jsx +3 -4
  248. package/src/project-resources.js +18 -31
  249. package/src/project.js +13 -104
  250. package/src/props.jsx +25 -280
  251. package/src/rail-dot-drag.js +23 -0
  252. package/src/render-passes.js +10 -0
  253. package/src/resource-status.jsx +1 -0
  254. package/src/result-modal.jsx +4 -19
  255. package/src/room.jsx +20 -12
  256. package/src/scene-assets.js +8 -6
  257. package/src/scene-light-place.js +72 -0
  258. package/src/scene-lights.jsx +148 -0
  259. package/src/scene-objects.js +31 -139
  260. package/src/scenes.js +15 -105
  261. package/src/semantic-edit.js +2 -5
  262. package/src/set-pieces.jsx +183 -0
  263. package/src/settings-menu.jsx +3 -11
  264. package/src/shell/BottomDock.jsx +9 -51
  265. package/src/shell/DetailsSlot.jsx +16 -200
  266. package/src/shell/GhostsMenuGroup.jsx +74 -0
  267. package/src/shell/LibrarySlot.jsx +1 -3
  268. package/src/shell/MenuBar.jsx +3 -3
  269. package/src/shell/PreferencesDialog.jsx +15 -264
  270. package/src/shell/PreferencesSlot.jsx +2 -8
  271. package/src/shell/TopBar.jsx +5 -84
  272. package/src/shell/ViewportToolbar.jsx +10 -70
  273. package/src/shell/agent-glass.css +19 -6
  274. package/src/shell/details-selection.js +42 -0
  275. package/src/shell/ghosts-menu.css +22 -0
  276. package/src/shell/glass-regions.css +29 -3
  277. package/src/shell/preferences.css +6 -1
  278. package/src/shot-authoring.js +4 -7
  279. package/src/soft-shadows.js +37 -0
  280. package/src/stage-attach-frames.js +12 -12
  281. package/src/stage-canvas-rigs.jsx +3 -3
  282. package/src/stage-capture.jsx +42 -8
  283. package/src/stage-characters.jsx +22 -216
  284. package/src/stage-editor-gizmos.jsx +6 -6
  285. package/src/stage-environment.js +93 -0
  286. package/src/stage-hdr-builtins.js +107 -0
  287. package/src/stage-hdr-image.js +116 -0
  288. package/src/stage-hdr-library.js +70 -0
  289. package/src/stage-hdr-map.js +94 -0
  290. package/src/stage-hdr.js +130 -0
  291. package/src/stage-lighting.js +149 -0
  292. package/src/stage-occlusion.js +210 -0
  293. package/src/stage-sky.jsx +159 -0
  294. package/src/stage-startup-defaults.js +5 -9
  295. package/src/studio-actions.js +12 -14
  296. package/src/studio-agent-commands.js +19 -16
  297. package/src/studio-agent-motion.js +9 -9
  298. package/src/studio-agent-protocol.js +41 -71
  299. package/src/studio-app-binding.js +25 -45
  300. package/src/studio-asset-list.js +17 -0
  301. package/src/studio-contact-sheet.js +37 -5
  302. package/src/studio-elements.js +27 -7
  303. package/src/studio-entity-bounds.js +18 -0
  304. package/src/studio-error-codes.js +8 -0
  305. package/src/studio-export-framing.js +152 -0
  306. package/src/studio-lighting-check.js +103 -0
  307. package/src/studio-motion-visual.js +150 -0
  308. package/src/studio-schema-errors.js +80 -0
  309. package/src/studio-support-gap.js +74 -0
  310. package/src/styles.css +1 -19
  311. package/src/timeline-defaults.js +5 -0
  312. package/src/timeline-extent.js +8 -20
  313. package/src/tutorial-walk.js +17 -0
  314. package/src/ui-scrub.js +1 -1
  315. package/src/use-shot-camera-tracks.js +12 -0
  316. package/src/view-ghosts.js +97 -0
  317. package/src/view-ghosts.jsx +49 -0
  318. package/src/workflow/AgentPanel.jsx +47 -166
  319. package/src/workflow/AgentProgressCard.jsx +107 -0
  320. package/src/workflow/AgentReplyText.jsx +37 -0
  321. package/src/workflow/AgentTurnSteps.jsx +84 -0
  322. package/src/workflow/LoginPanel.jsx +140 -0
  323. package/src/workflow/WorkflowBuilder.jsx +7 -23
  324. package/src/workflow/agent-client.js +54 -51
  325. package/src/workflow/agent-panel.css +71 -1
  326. package/src/workflow/agent-progress-card.css +167 -0
  327. package/src/workflow/agent-progress-view.js +47 -0
  328. package/src/workflow/agent-turn-steps.css +113 -0
  329. package/src/workflow/agent-turn.js +191 -0
  330. package/src/workflow/login-client.js +34 -0
  331. package/src/workflow/motion-input.js +18 -31
  332. package/src/workflow/node-schema.js +1 -1
  333. package/src/workflow/reply-markdown.js +69 -0
  334. package/src/workflow/scene-asset-sync.js +8 -8
  335. package/tools/agent-session-stats.mjs +61 -0
  336. package/tools/dev-full.mjs +5 -56
  337. package/tools/eslint-baseline.json +12 -13
  338. package/tools/knip-baseline.json +0 -179
  339. package/tools/loc-baseline.json +31 -81
  340. package/tools/motion3/extract-body.mjs +103 -0
  341. package/tools/motion3/extract-rig.mjs +85 -0
  342. package/tools/process-supervisor.mjs +0 -88
  343. package/tools/run-tests.mjs +8 -124
  344. package/bin/agent/motion-runtime.mjs +0 -76
  345. package/dist/ardy/cskel27-rest.json +0 -557
  346. package/dist/assets/analytics-C9pMpW7s.js +0 -1
  347. package/dist/assets/app-B_2XB9rw.css +0 -1
  348. package/dist/assets/app-DAuvKPP8.js +0 -4920
  349. package/dist/assets/config-Bx7pYsD9.js +0 -1
  350. package/dist/assets/config-DeoFTYzb.css +0 -1
  351. package/dist/assets/demo-CvKuBgy5.js +0 -1
  352. package/dist/assets/scene-asset-sync-DKkpjKBV.js +0 -19
  353. package/dist/assets/scene-asset-sync-DjJ_cJ2R.css +0 -1
  354. package/dist/assets/ticket-BPk2Ni95.js +0 -1
  355. package/dist/assets/workflow-jJRBR94Z.js +0 -179
  356. package/dist/demo/walk-then-stop.npz +0 -0
  357. package/mcp/ardy-prompts.mjs +0 -218
  358. package/src/ardy/auto-fix-panel.css +0 -108
  359. package/src/ardy/auto-physics.js +0 -1194
  360. package/src/ardy/client.js +0 -153
  361. package/src/ardy/convert.js +0 -313
  362. package/src/ardy/cskel27-neutral.js +0 -39
  363. package/src/ardy/cskel27.js +0 -77
  364. package/src/ardy/export.js +0 -165
  365. package/src/ardy/fix-collisions.js +0 -2257
  366. package/src/ardy/foot-lock.js +0 -230
  367. package/src/ardy/motion-calibration.js +0 -118
  368. package/src/ardy/motion-edit.js +0 -213
  369. package/src/ardy/motion-url.js +0 -55
  370. package/src/ardy/mp4-duration.js +0 -102
  371. package/src/ardy/npz.js +0 -595
  372. package/src/ardy/physics-panel.css +0 -21
  373. package/src/ardy/physics-panel.jsx +0 -89
  374. package/src/ardy/physics-refine.js +0 -111
  375. package/src/ardy/physics-review.js +0 -567
  376. package/src/ardy/physics-temporal.js +0 -54
  377. package/src/ardy/platform-fit-panel.css +0 -64
  378. package/src/ardy/platform-fit-panel.jsx +0 -41
  379. package/src/ardy/platform-fit.js +0 -326
  380. package/src/ardy/playback.js +0 -711
  381. package/src/ardy/pose-pin.js +0 -97
  382. package/src/ardy/prompt-clips.js +0 -30
  383. package/src/ardy/retime.js +0 -211
  384. package/src/ardy/root-drop.js +0 -369
  385. package/src/ardy/timeline-resize.js +0 -13
  386. package/src/ardy/to-cskel27.js +0 -225
  387. package/src/ardy/trim.js +0 -33
  388. package/src/ardy/waypoints.js +0 -369
  389. package/src/ardy-bridge-contract.js +0 -281
  390. package/src/domains/motion/motion-video-capture.js +0 -664
  391. package/src/i2v-motion-client.js +0 -77
  392. package/src/i2v-motion-studio.jsx +0 -180
  393. package/src/line-edit.js +0 -1348
  394. package/src/motion/generation.js +0 -105
  395. package/src/motion-readiness-ui.jsx +0 -67
  396. package/src/motion-readiness.js +0 -40
  397. package/src/motion-resources.js +0 -177
  398. package/src/motion-store.js +0 -65
  399. package/src/motion-trail.js +0 -601
  400. package/src/multimodel-ingest.js +0 -394
  401. package/src/panels/PromptBlocksPanel.jsx +0 -444
  402. package/src/panels/VideoCapturePanel.jsx +0 -181
  403. package/src/pose-extract/browser.js +0 -42
  404. package/src/pose-extract/detector.js +0 -100
  405. package/src/pose-extract/fit.js +0 -227
  406. package/src/pose-extract/image-frame.js +0 -51
  407. package/src/pose-extract/index.js +0 -58
  408. package/src/pose-extract/keyframes.js +0 -74
  409. package/src/pose-extract/landmarks.js +0 -162
  410. package/src/pose-extract/mirror.js +0 -153
  411. package/src/pose-extract/take.js +0 -131
  412. package/src/pose-extract/video-frames.js +0 -91
  413. package/src/take-recipe.js +0 -165
  414. package/src/trail-key-conflicts.js +0 -39
  415. package/src/trail-pick.js +0 -59
  416. package/src/use-i2v-capture-modal.js +0 -15
  417. package/tools/ardy/BRIDGE.md +0 -37
  418. package/tools/ardy/GVHMR-NPZ.md +0 -68
  419. package/tools/ardy/README.md +0 -124
  420. package/tools/ardy/__pycache__/cclay_gvhmr_worker.cpython-313.pyc +0 -0
  421. package/tools/ardy/artifacts.mjs +0 -34
  422. package/tools/ardy/bridge.mjs +0 -1732
  423. package/tools/ardy/bvh-cskel27.mjs +0 -1265
  424. package/tools/ardy/cclay_constrained_generate.py +0 -561
  425. package/tools/ardy/cclay_gvhmr_worker.py +0 -264
  426. package/tools/ardy/cclay_motion_edit.py +0 -510
  427. package/tools/ardy/cclay_sequence_generate.py +0 -705
  428. package/tools/ardy/cclay_worker.py +0 -304
  429. package/tools/ardy/dump-npz.py +0 -205
  430. package/tools/ardy/extract-rest.mjs +0 -299
  431. package/tools/ardy/extract.mjs +0 -507
  432. package/tools/ardy/footage.mjs +0 -467
  433. package/tools/ardy/gvhmr-floor.mjs +0 -102
  434. package/tools/ardy/gvhmr-to-cskel27.mjs +0 -21
  435. package/tools/ardy/gvhmr_fastpath.py +0 -168
  436. package/tools/ardy/gvhmr_trajectory.py +0 -240
  437. package/tools/ardy/merge-text-encoder.py +0 -160
  438. package/tools/ardy/mocap-metrics.mjs +0 -200
  439. package/tools/ardy/mocap-quality-gate.mjs +0 -110
  440. package/tools/ardy/motion-stabilize.mjs +0 -348
  441. package/tools/ardy/npz.mjs +0 -414
  442. package/tools/ardy/pose-to-npz.mjs +0 -106
  443. package/tools/ardy/prompt-limits.mjs +0 -5
  444. package/tools/ardy/run-edit-on-box.sh +0 -73
  445. package/tools/ardy/run-local.mjs +0 -233
  446. package/tools/ardy/run-on-box.sh +0 -593
  447. package/tools/ardy/run-sequence-on-box.sh +0 -177
  448. package/tools/ardy/runners/gvhmr-worker.mjs +0 -206
  449. package/tools/ardy/runners/index.mjs +0 -18
  450. package/tools/ardy/runners/local.mjs +0 -455
  451. package/tools/ardy/runners/proc.mjs +0 -125
  452. package/tools/ardy/runners/remote.mjs +0 -252
  453. package/tools/ardy/setup-local.mjs +0 -189
  454. package/tools/ardy/setup-text-encoder-on-box.sh +0 -93
  455. package/tools/ardy/setup-text-encoder.py +0 -306
  456. package/tools/ardy/smpl-cskel27.mjs +0 -178
  457. package/tools/ardy/visual-qa.mjs +0 -196
  458. package/tools/ardy/vq-car.mjs +0 -52
  459. package/tools/bench/EXP3.md +0 -61
  460. package/tools/bench/cclay_bench_extract_incam.py +0 -125
  461. package/tools/bench/cclay_bench_extract_obs.py +0 -204
  462. package/tools/bench/cclay_bench_runner.py +0 -42
  463. package/tools/bench/cube-contact.mjs +0 -162
  464. package/tools/bench/exp3.mjs +0 -152
  465. package/tools/bench/extract-bench-lib.mjs +0 -216
  466. package/tools/bench/extract-bench.mjs +0 -302
  467. package/tools/bench/fal-generate.mjs +0 -88
  468. package/tools/bench/fit/README.md +0 -189
  469. package/tools/bench/fit/camera.mjs +0 -59
  470. package/tools/bench/fit/contact.mjs +0 -419
  471. package/tools/bench/fit/footlock.mjs +0 -234
  472. package/tools/bench/fit/motion.mjs +0 -85
  473. package/tools/bench/fit/pin.mjs +0 -27
  474. package/tools/bench/fit/remote.mjs +0 -105
  475. package/tools/bench/fit-bench.mjs +0 -126
  476. package/tools/bench/fit-sanity.mjs +0 -45
  477. package/tools/bench/metrics.mjs +0 -313
  478. package/tools/bench/obs/depth.mjs +0 -258
  479. package/tools/bench/obs/extrinsics.mjs +0 -175
  480. package/tools/bench/obs/fit_mannequin_betas.py +0 -340
  481. package/tools/bench/obs/ground.mjs +0 -294
  482. package/tools/bench/obs/heading.mjs +0 -151
  483. package/tools/bench/obs/ladder.mjs +0 -555
  484. package/tools/bench/obs/mannequin-betas.json +0 -124
  485. package/tools/bench/obs/remote.mjs +0 -83
  486. package/tools/bench/obs/rest_joints.py +0 -52
  487. package/tools/bench/obs/ybot-targets.mjs +0 -49
  488. package/tools/bench/obs-bench.mjs +0 -520
  489. package/tools/bench/score.mjs +0 -343
  490. package/tools/bench/summarize.mjs +0 -86
  491. package/tools/demo-worker/README.md +0 -137
  492. package/tools/demo-worker/api-client.mjs +0 -233
  493. package/tools/demo-worker/generate.mjs +0 -301
  494. package/tools/demo-worker/index.mjs +0 -466
  495. package/tools/demo-worker/sign-core.mjs +0 -112
  496. package/tools/demo-worker/sign.mjs +0 -161
  497. package/tools/gt-render/browser.mjs +0 -182
  498. package/tools/gt-render/camera-math.mjs +0 -276
  499. package/tools/gt-render/page.mjs +0 -267
  500. package/tools/gt-render/render.mjs +0 -514
  501. package/tools/gt-render/scene-box.mjs +0 -31
  502. package/tools/gt-render/take-transform.mjs +0 -87
  503. package/tools/kimodo/compare-seam.mjs +0 -108
  504. package/tools/kimodo/constraints.mjs +0 -244
  505. package/tools/kimodo/edit.mjs +0 -259
  506. package/tools/kimodo/effector-constraints.mjs +0 -200
  507. package/tools/kimodo/generate.mjs +0 -646
  508. package/tools/kimodo/local-output.mjs +0 -265
  509. package/tools/kimodo/measure-pose.mjs +0 -65
  510. package/tools/kimodo/measure-preserve.mjs +0 -899
  511. package/tools/kimodo/measure-waypoints.mjs +0 -55
  512. package/tools/kimodo/mlx-generate.py +0 -111
  513. package/tools/kimodo/pose-constraints.mjs +0 -248
  514. package/tools/kimodo/preserve-mask.mjs +0 -543
  515. package/tools/kimodo/read-npz.mjs +0 -189
  516. package/tools/kimodo/run-edit-on-box.mjs +0 -155
  517. package/tools/kimodo/run-sequence-on-box.mjs +0 -178
  518. package/tools/kimodo/runner.mjs +0 -284
  519. package/tools/kimodo/seam-batch.mjs +0 -77
  520. package/tools/kimodo/setup-local.mjs +0 -30
  521. package/tools/kimodo/setup-on-box.sh +0 -339
  522. package/tools/kimodo/soma77-to-cskel27.mjs +0 -305
  523. package/tools/morphgs/assets/gen_truth.py +0 -39
  524. package/tools/morphgs/assets/mesh_ori_rig.txt +0 -27
  525. package/tools/morphgs/assets/playback-check.mjs +0 -30
  526. package/tools/morphgs/demo-gate.sh +0 -26
  527. package/tools/morphgs/fbx2morphgs.mjs +0 -68
  528. package/tools/morphgs/morphgs-to-cskel27.mjs +0 -105
  529. package/tools/morphgs/patches/preprocess_src-none-mode.patch +0 -76
  530. package/tools/morphgs/setup-on-cluster.sh +0 -126
  531. package/tools/projflow/driver.py +0 -1069
  532. package/tools/projflow/generate.mjs +0 -805
  533. package/tools/projflow/hml22-to-cskel27.mjs +0 -735
  534. package/tools/projflow/line-edit-job.mjs +0 -547
  535. package/tools/projflow/replay.mjs +0 -452
  536. package/tools/projflow/runner.mjs +0 -269
  537. package/tools/projflow/service.mjs +0 -742
  538. package/tools/track/DESIGN.md +0 -513
  539. package/tools/track/backfill-provenance.mjs +0 -116
  540. package/tools/track/budget.mjs +0 -8
  541. package/tools/track/check-rig.mjs +0 -209
  542. package/tools/track/diagnostics.schema.json +0 -60
  543. package/tools/track/export-rig.mjs +0 -256
  544. package/tools/track/fallback.mjs +0 -7
  545. package/tools/track/fk-parity-fixture.mjs +0 -161
  546. package/tools/track/gate.mjs +0 -349
  547. package/tools/track/masks.mjs +0 -318
  548. package/tools/track/metrics.mjs +0 -201
  549. package/tools/track/publish-obs.mjs +0 -108
  550. package/tools/track/py/check_env.py +0 -61
  551. package/tools/track/py/eval_lr.py +0 -229
  552. package/tools/track/py/lr_viterbi.py +0 -294
  553. package/tools/track/py/masks.py +0 -405
  554. package/tools/track/py/objective.py +0 -382
  555. package/tools/track/py/rig.py +0 -508
  556. package/tools/track/py/scene.py +0 -326
  557. package/tools/track/py/test_joint_indices.py +0 -123
  558. package/tools/track/py/test_lr_viterbi.py +0 -195
  559. package/tools/track/py/test_masks.py +0 -229
  560. package/tools/track/py/test_rig.py +0 -288
  561. package/tools/track/py/test_scene.py +0 -354
  562. package/tools/track/py/test_track.py +0 -328
  563. package/tools/track/py/track.py +0 -411
  564. package/tools/track/remote.mjs +0 -140
  565. package/tools/track/rig-dump.mjs +0 -227
  566. package/tools/track/run-box-tests.mjs +0 -14
  567. package/tools/track/run-box.mjs +0 -168
  568. package/tools/track/setup-box.sh +0 -59
  569. package/tools/track/study-2d.mjs +0 -728
  570. /package/src/{ardy → motion}/collision-blockers.js +0 -0
  571. /package/src/{ardy → motion}/ground.js +0 -0
  572. /package/src/{ardy → motion}/ik-drag.js +0 -0
  573. /package/src/{ardy → motion}/ik-key-json.js +0 -0
  574. /package/src/{ardy → motion}/ik.js +0 -0
  575. /package/src/{ardy → motion}/physics-surface.js +0 -0
  576. /package/src/{ardy → motion}/playback-clock.js +0 -0
  577. /package/src/{ardy → motion}/range-pin.js +0 -0
@@ -1,444 +0,0 @@
1
- import { useState } from "react";
2
- import Foldout from "./Foldout.jsx";
3
- import { ko, isKo } from "../locale.js";
4
- import { Field, Dropdown } from "../ui.jsx";
5
- import { LINE_EDIT_TRACK_OPTIONS, MIN_CURVE_POINTS, lineTrackLabel } from "../app-stage.jsx";
6
- import { LINE_EDIT_PINS_MAX, DRAG_RADIUS_MIN, DRAG_RADIUS_MAX, MAX_LINE_POINTS, PINNED_CURVE_ENDS } from "../line-edit.js";
7
- import { motionReadinessMessage, MotionReadiness } from "../motion-readiness-ui.jsx";
8
- import { useCastTransaction } from '../domains/cast.js';
9
- import { useMotionCommands } from '../domains/motion.js';
10
- import { useStudioShell } from '../shell/studio-shell-context.js';
11
- import "./motion.css";
12
-
13
- export default function PromptBlocksPanel({
14
- isCharacterSelection, promptBlocksReveal, promptClips, selectedPromptId, setSelectedPromptId,
15
- setArdyPrompt, setTlFrame, tlFrameCount, ardySeed, changeArdySeed, motion, lineEditMode,
16
- toggleLineEditMode, linePreviewUrl, lineCurve, lineDrifted, lineTrack, setLineTrack, linePinMode,
17
- setLinePinMode, linePins, lineClipFrames, lineEditRange, setLineRange, lineRadius, changeLineRadius,
18
- lineCurveDirty, lineEditFrom, lineEditTo, lineCurvePointCount, lineDriftHint, lineCurveHidden,
19
- linePreviewBusy, linePreviewMs, linePreviewError, generationBusy, bridgeChecking, bridge,
20
- lineReadinessState, runLineEdit, openMotionSetup, recheckMotionHealth, resetLineCurve, exitLineEditMode,
21
- readinessState, ardyRunning, cancelArdy, ardyStatus, ardyOutcome,
22
- }) {
23
- const { run, begin, commit, characterId } = useCastTransaction();
24
- const { refineDisabledReason, workflowMode, previsMode } = useStudioShell();
25
- const selectedClip = promptClips.find((clip) => clip.id === selectedPromptId) ?? null;
26
- const refineReason = refineDisabledReason();
27
- // A storyboard has no prompt blocks to author or edit.
28
- if (previsMode === "storyboard") return null;
29
- // Generate, Start over, Take it again and Add block live in the top bar's
30
- // Generate Motion button and its caret menu, their one home (R1).
31
- return (
32
- <>
33
- <Foldout hidden={!isCharacterSelection} defaultOpen={false} openSignal={promptBlocksReveal} title={ko("Prompt Blocks", "프롬프트 블록")}>
34
- <p className="inspector-hint">{ko("Blocks define what is generated over each frame range. Selecting one also moves editing context to that prompt.", "블록은 각 프레임 범위에서 생성될 내용을 정합니다. 블록을 선택하면 편집 기준도 해당 프롬프트로 이동합니다.")}</p>
35
- <div className="inspector-list">
36
- {promptClips.map((clip) => (
37
- <button
38
- type="button"
39
- key={clip.id}
40
- className={selectedPromptId === clip.id ? "active" : ""}
41
- onClick={() => {
42
- setSelectedPromptId(clip.id);
43
- setArdyPrompt(clip.text);
44
- setTlFrame(Math.min(clip.startFrame, tlFrameCount - 1));
45
- }}
46
- >
47
- <span>{clip.text || ko("Untitled motion", "이름 없는 모션")}</span>
48
- <small>{clip.startFrame}–{clip.endFrame}f</small>
49
- </button>
50
- ))}
51
- </div>
52
- {selectedClip && (
53
- <Field label={ko("Range", "구간")}>
54
- <span className="motion-block-range" data-block-range={`${selectedClip.startFrame}-${selectedClip.endFrame}`}>
55
- {selectedClip.startFrame}–{selectedClip.endFrame} f
56
- </span>
57
- </Field>
58
- )}
59
- {selectedPromptId && (
60
- <Field label={ko("Prompt", "프롬프트")}>
61
- <input
62
- type="text"
63
- value={promptClips.find((clip) => clip.id === selectedPromptId)?.text ?? ""}
64
- onBlur={commit}
65
- onChange={(event) => {
66
- begin();
67
- run('character.changePromptBlock', { characterId, id: selectedPromptId, text: event.target.value });
68
- setArdyPrompt(event.target.value);
69
- }}
70
- placeholder={ko("describe this motion block", "이 모션 블록을 설명하세요")}
71
- />
72
- </Field>
73
- )}
74
- {/* The seed belongs with the button that consumes it. Duration does
75
- not appear at all: the blocks' own frame ranges are the length. */}
76
- <Field label={ko("Seed", "시드")}>
77
- <input
78
- type="text"
79
- inputMode="numeric"
80
- value={ardySeed}
81
- onChange={(e) => changeArdySeed(e.target.value)}
82
- placeholder={ko("empty = random", "비우면 랜덤")}
83
- />
84
- </Field>
85
- {/* Scheduled inpainting used to live here, beside the batch button.
86
- It now folds into Scene > Advanced above the timeline (contract
87
- C12): it is a dial on a regeneration, so it belongs with the
88
- regeneration entry rather than with the block list. */}
89
- {/* Line editing (contract C6). It sits beside the preserve slider
90
- because it answers the same question from the other side —
91
- preserve says how much of the take to KEEP, a line says exactly
92
- where one joint must GO — and because both need a take with a
93
- bridge source, so the whole section is absent until there is one
94
- rather than present and inert. */}
95
- {motion?.url && (
96
- <Field label={ko("Line editing", "라인 편집")}>
97
- {/* Refine: the take bar's second entry, until it becomes motion tool E. */}
98
- <button
99
- type="button"
100
- className={"btn full" + (lineEditMode ? " primary" : "")}
101
- data-take-mode="refine"
102
- data-disabled-reason={refineReason || undefined}
103
- aria-pressed={lineEditMode}
104
- title={ko(
105
- "The joint's own path is drawn on the viewport — grab a point on it and pull, or draw a new path on empty space; the joint then follows it exactly. The view still orbits normally (Alt+drag).",
106
- "관절이 지나가는 궤적이 뷰포트에 그려집니다 — 궤적 위의 점을 잡아 끌거나, 빈 곳에 새 궤적을 그리면 관절이 그 경로를 정확히 따라갑니다. 시점은 평소처럼 돌릴 수 있어요 (Alt+드래그).",
107
- )}
108
- onClick={toggleLineEditMode}
109
- >
110
- {lineEditMode ? ko("Path editing on", "궤적 편집 켜짐") : ko("Drag the path", "궤적을 잡아 끌기")}
111
- </button>
112
- {lineEditMode && (
113
- <div
114
- className="line-edit-panel"
115
- data-line-preview={linePreviewUrl ? "true" : undefined}
116
- // "The line is detached from this view" — the panel's own copy of
117
- // what the stage already carries, so a test (or a screenshot) can
118
- // read the state from whichever of the two it is looking at.
119
- data-line-drift={lineCurve && lineDrifted ? "true" : undefined}
120
- >
121
- <Field label={ko("Joint", "관절")}>
122
- <Dropdown
123
- value={lineTrack}
124
- options={LINE_EDIT_TRACK_OPTIONS}
125
- onChange={setLineTrack}
126
- ariaLabel={ko("Joint whose path is edited", "궤적을 편집할 관절")}
127
- />
128
- </Field>
129
- {/* THE GESTURE SELECTOR. Pressing on the joint is how BOTH a
130
- curve drag and a pin start, so the two cannot share a
131
- press and a modal toggle is the honest way to say which
132
- one the next press means. Named for what it does at the
133
- moment it does it, not for the wire field. */}
134
- <button
135
- type="button"
136
- className={"btn full" + (linePinMode ? " primary" : "")}
137
- data-line-pin-mode={linePinMode ? "true" : "false"}
138
- onClick={() => setLinePinMode((on) => !on)}
139
- >
140
- {linePinMode
141
- ? ko("Pinning moments", "순간 찍는 중")
142
- : ko("Pin a moment", "순간 찍기")}
143
- </button>
144
- {linePinMode && (
145
- <p className="inspector-hint">
146
- {linePins.length
147
- ? (isKo
148
- ? `${linePins.length}개(최대 ${LINE_EDIT_PINS_MAX}개)를 찍었어요 — 프레임 ${linePins.map((pin) => pin.frame).join(", ")}. 사이 동작은 모델이 채웁니다`
149
- : `${linePins.length} pinned (max ${LINE_EDIT_PINS_MAX}) — frames ${linePins.map((pin) => pin.frame).join(", ")}. The model fills the movement between them`)
150
- : ko(
151
- "Scrub to a moment, then drag the green handle to where the joint should be. The take keeps its own timing; only that instant is pinned.",
152
- "원하는 순간으로 재생 위치를 옮긴 뒤, 초록 손잡이를 관절이 있어야 할 자리로 끌어 주세요. 그 순간만 고정되고 나머지 타이밍은 그대로예요.",
153
- )}
154
- </p>
155
- )}
156
- {/* No range picker exists elsewhere in the app that a line
157
- edit could borrow, so the whole clip is the default and
158
- these two numbers only ever NARROW it. endFrame is
159
- exclusive, like every other half-open range on this wire. */}
160
- <Field label={ko("Frame range", "프레임 구간")}>
161
- <div className="line-edit-range-row">
162
- <input
163
- type="number"
164
- min={0}
165
- max={Math.max(0, lineClipFrames - 2)}
166
- value={lineEditRange?.startFrame ?? 0}
167
- onChange={(event) => setLineRange((current) => ({
168
- startFrame: Math.round(Number(event.target.value)) || 0,
169
- endFrame: current?.endFrame ?? lineClipFrames,
170
- }))}
171
- />
172
- <span aria-hidden="true">–</span>
173
- <input
174
- type="number"
175
- min={2}
176
- max={lineClipFrames}
177
- value={lineEditRange?.endFrame ?? lineClipFrames}
178
- onChange={(event) => setLineRange((current) => ({
179
- startFrame: current?.startFrame ?? 0,
180
- endFrame: Math.round(Number(event.target.value)) || 0,
181
- }))}
182
- />
183
- </div>
184
- </Field>
185
- {/* How far a pull carries along the path, in FRAMES — the
186
- sigma of the Gaussian falloff, said in the unit the user
187
- is looking at. Narrow is a beat, wide is a whole gesture. */}
188
- <Field label={ko("Influence", "영향 범위")}>
189
- <div className="line-edit-radius-row">
190
- <input
191
- type="range"
192
- min={DRAG_RADIUS_MIN}
193
- max={DRAG_RADIUS_MAX}
194
- step={1}
195
- value={lineRadius}
196
- aria-label={ko("How many frames a pull carries along the path", "잡아당길 때 궤적을 따라 함께 움직이는 프레임 수")}
197
- onChange={(event) => changeLineRadius(event.target.value)}
198
- />
199
- <span className="line-edit-radius-value">
200
- {isKo ? `${lineRadius}프레임` : `${lineRadius} frames`}
201
- </span>
202
- </div>
203
- </Field>
204
- <p className="inspector-hint">
205
- {lineCurveDirty
206
- ? (isKo
207
- ? `${lineEditFrom}–${lineEditTo} 프레임을 편집했어요 — ${lineCurvePointCount}개 점(최대 ${MAX_LINE_POINTS}개)을 보내고, 양 끝은 원래 궤적에서 부드럽게 이어져 이음매가 튀지 않아요. 다시 끌거나 다시 그려서 다듬을 수 있어요`
208
- : `Frames ${lineEditFrom}–${lineEditTo} edited — ${lineCurvePointCount} points (max ${MAX_LINE_POINTS}); both ends ease out of the original path, so the seams do not pop. Pull it again, or draw over it, to refine`)
209
- : ko(
210
- "Draw along the path to reroute that section — the frames you drew over become the range, and the take's own timing is kept. Or grab a yellow dot and pull.",
211
- "궤적을 따라 그리면 그 구간만 새로 지나갑니다 — 그린 만큼이 편집 구간이 되고, 원래 속도감은 그대로 유지돼요. 노란 점을 잡아 끌어도 됩니다.",
212
- )}
213
- </p>
214
- {/* The one thing users assume a modal viewport tool takes away.
215
- Said out loud, because "can I still orbit?" is the first
216
- question and the answer decides whether the mode is usable. */}
217
- {/* THE DETACHED STATE. Said inline, next to the edit it is about,
218
- and in the same words the refused gesture answers with. It is
219
- a status, not a warning: nothing was lost and nothing needs
220
- doing — the only thing that changed is that the line cannot be
221
- drawn in a view it was not aimed through. */}
222
- {lineCurve && lineDrifted && (
223
- <p className="inspector-hint line-edit-drift" aria-live="polite">
224
- {lineDriftHint()}
225
- </p>
226
- )}
227
- <p className="inspector-hint">
228
- {lineCurveDirty
229
- ? ko(
230
- "You can still orbit (Alt+drag), pan and fly freely — the edit survives it. It was aimed through one lens, so while the view is elsewhere the line is drawn ghosted and a new pull waits; Generate, undo and Reset work from anywhere.",
231
- "시점은 자유롭게 돌리고(Alt+드래그) 옮길 수 있어요 — 편집은 그대로 남습니다. 다만 이 궤적은 처음 시점 기준이라, 시점을 옮기면 흐리게만 보이고 새로 끌기는 잠시 멈춰요. 생성·되돌리기·원래대로는 언제든 됩니다.",
232
- )
233
- : ko(
234
- "You can still orbit (Alt+drag), pan and fly freely; the path follows the view until you pull or draw it.",
235
- "시점은 평소처럼 자유롭게 돌리고(Alt+드래그) 옮길 수 있어요. 끌거나 그리기 전까지 궤적은 시점을 따라갑니다.",
236
- )}
237
- </p>
238
- {lineEditRange && lineEditRange.endFrame - lineEditRange.startFrame < MIN_CURVE_POINTS && (
239
- <p className="inspector-hint">
240
- {isKo
241
- ? `구간이 너무 짧아요 — 양 끝 ${PINNED_CURVE_ENDS}프레임씩이 고정이라 ${MIN_CURVE_POINTS}프레임 이상이어야 잡을 점이 생겨요`
242
- : `This range is too short — with ${PINNED_CURVE_ENDS} pinned frames at each end it needs at least ${MIN_CURVE_POINTS} frames before anything can be grabbed`}
243
- </p>
244
- )}
245
- {lineCurveHidden > 0 && (
246
- <p className="inspector-hint">
247
- {isKo
248
- ? `${lineCurveHidden}프레임이 화면 밖이라 잡을 수 없어요 — 구간 전체가 보이도록 카메라를 잡아 주세요`
249
- : `${lineCurveHidden} frame(s) are outside the frame and cannot be grabbed — frame the whole range in view`}
250
- </p>
251
- )}
252
- {/* ------------------------- the preview line -------------------
253
- One quiet row that says which of three things is true: a
254
- draft is being made, a draft is on screen (and how long it
255
- took), or the last one failed and the curve is still here.
256
- Deliberately not a spinner over the viewport — the artist
257
- is LOOKING at the viewport, and the answer arrives there. */}
258
- {linePreviewBusy && (
259
- <p className="inspector-hint line-preview-busy" aria-live="polite">
260
- {ko("Previewing the pull…", "당긴 결과 미리보는 중…")}
261
- </p>
262
- )}
263
- {!linePreviewBusy && linePreviewUrl && (
264
- <p className="inspector-hint line-preview-live">
265
- {ko(
266
- "The viewport is showing this edit at full quality — press Generate to keep it as the take.",
267
- "뷰포트가 지금 이 편집의 최종 품질 결과예요 — 아래 생성을 누르면 테이크로 확정됩니다.",
268
- )}
269
- {linePreviewMs > 0 && (
270
- <span className="line-preview-time">
271
- {isKo ? ` 미리보기 ${(linePreviewMs / 1000).toFixed(1)}s` : ` preview ${(linePreviewMs / 1000).toFixed(1)}s`}
272
- </span>
273
- )}
274
- </p>
275
- )}
276
- {/* A failed draft is not a failed edit: the pull survives it and
277
- the button below still runs the real thing. */}
278
- {linePreviewError && (
279
- <p className="inspector-hint line-preview-error">
280
- {isKo ? `미리보기 실패 — ${linePreviewError} (생성은 그대로 됩니다)` : `Preview failed — ${linePreviewError} (Generate still works)`}
281
- </p>
282
- )}
283
- <button
284
- type="button"
285
- className="btn primary full generate"
286
- disabled={!lineCurveDirty || generationBusy || bridgeChecking || bridge === null}
287
- title={generationBusy ? ko("A generation is already running", "이미 생성이 돌고 있어요")
288
- : !lineCurveDirty
289
- ? ko("Pull the path on the viewport first", "먼저 뷰포트에서 궤적을 잡아당겨 주세요")
290
- : motionReadinessMessage(lineReadinessState)}
291
- onClick={runLineEdit}
292
- >
293
- {ko("Generate the line edit", "라인 편집 생성")}
294
- </button>
295
- <MotionReadiness state={lineReadinessState} checking={bridgeChecking} onSetup={() => openMotionSetup("line")} onRetry={recheckMotionHealth} />
296
- <button type="button" className="btn ghost full" disabled={!lineCurveDirty} onClick={resetLineCurve}>
297
- {ko("Reset the curve", "원래대로")}
298
- </button>
299
- <button type="button" className="btn ghost full" onClick={exitLineEditMode}>
300
- {ko("Exit line editing (Esc)", "라인 편집 끝내기 (Esc)")}
301
- </button>
302
- </div>
303
- )}
304
- </Field>
305
- )}
306
- {ardyRunning && (
307
- <button type="button" className="btn ghost full" onClick={cancelArdy}>
308
- {ko("Cancel run", "실행 취소")}
309
- </button>
310
- )}
311
- {!lineEditMode && <MotionReadiness state={readinessState} checking={bridgeChecking} onSetup={openMotionSetup} onRetry={recheckMotionHealth} />}
312
- {ardyRunning && ardyStatus && <p className="ardy-status" role="status">{ardyStatus}</p>}
313
- {!ardyRunning && ardyOutcome?.ok === false && <p className="ardy-status" role="alert">{ardyOutcome.message}</p>}
314
- {!ardyRunning && ardyOutcome?.ok === true && <p className="ardy-status" role="status">{ko("Motion generation complete", "모션 생성 완료")}</p>}
315
- {motion?.url && <MotionAdvanced />}
316
- </Foldout>
317
- <TakesSection hidden={!isCharacterSelection || workflowMode === "scene" || workflowMode === "camera"} />
318
- </>
319
- );
320
- }
321
-
322
- /* Motion › Advanced: the dials that decide how much of the loaded take a
323
- regeneration keeps. Folded away because the default (half preserved, whole
324
- body free) is right almost always. */
325
- function MotionAdvanced() {
326
- const { preserveStrength, setPreserveStrength, waypointMode, preserveTracksLine } = useStudioShell();
327
- const [open, setOpen] = useState(false);
328
- return (
329
- <div className="motion-advanced">
330
- <button type="button" className="motion-advanced-head" aria-expanded={open} onClick={() => setOpen((value) => !value)}>
331
- <span className="v2-details-foldout-arrow foldout-arrow" data-open={open ? "true" : "false"} aria-hidden="true" />
332
- {ko("Advanced", "고급")}
333
- </button>
334
- {open && (
335
- <div className="motion-advanced-body">
336
- <label className="row">
337
- <span>{ko("Keep current take", "현재 테이크 유지")}</span>
338
- <input
339
- type="range"
340
- data-preserve-strength
341
- min={0}
342
- max={1}
343
- step={0.05}
344
- value={preserveStrength}
345
- title={ko(
346
- "How hard the regeneration holds the loaded take outside the frames you edited.",
347
- "수정하지 않은 프레임에서 로드된 테이크를 얼마나 강하게 유지할지 정합니다.",
348
- )}
349
- onChange={(event) => setPreserveStrength(Number(event.target.value))}
350
- />
351
- <span className="val preserve-strength-value">{Math.round(preserveStrength * 100)}%</span>
352
- </label>
353
- {/* The slider value IS the preserve strength: 0 (left) is a fresh
354
- take and 1 (right) holds the original hardest. */}
355
- <p className="inspector-hint motion-preserve-scale">
356
- <span>{ko("generate fresh", "새로 생성")}</span>
357
- <span>{ko("keep original", "원본 유지")}</span>
358
- </p>
359
- {waypointMode && preserveStrength > 0 && (
360
- <p className="inspector-hint">
361
- {ko(
362
- "the drawn path replaces the root; the body keeps the take's style",
363
- "경로는 새로 그려지고, 동작 스타일은 원본을 유지해요",
364
- )}
365
- </p>
366
- )}
367
- {preserveStrength > 0 && preserveTracksLine && (
368
- <p className="inspector-hint preserve-tracks-summary">{preserveTracksLine}</p>
369
- )}
370
- </div>
371
- )}
372
- </div>
373
- );
374
- }
375
-
376
- /* Takes (G6): every successful run leaves a checkpoint. Clicking a row loads
377
- that take back and restores the recipe it was saved with; loading never
378
- drops a row, so an experiment can always be walked back. */
379
- function TakesSection({ hidden }) {
380
- const { run } = useMotionCommands();
381
- const { takeVersions, takeSourceUrl, takeRecipe, replayNotices, linePreviewUrl } = useStudioShell();
382
- return (
383
- <Foldout hidden={hidden} title={ko("Takes", "테이크")}>
384
- <div
385
- className="motion-takes"
386
- data-take-source={takeSourceUrl || undefined}
387
- // The draft's url beside the take's own, so "the viewport swapped but
388
- // the take did not" is one comparison rather than an inference.
389
- data-line-preview={linePreviewUrl ? "true" : undefined}
390
- data-line-preview-url={linePreviewUrl || undefined}
391
- >
392
- {takeVersions.length > 0 ? (
393
- <div className="motion-take-list" role="group" aria-label={ko("Take versions", "테이크 버전")}>
394
- {takeVersions.map((entry, index) => {
395
- const current = entry.motionUrl === takeSourceUrl;
396
- return (
397
- <button
398
- type="button"
399
- key={entry.motionUrl}
400
- className={"motion-take-row" + (current ? " current" : "")}
401
- data-version-url={entry.motionUrl}
402
- data-version-current={current ? "true" : undefined}
403
- aria-pressed={current}
404
- title={`${entry.label} · ${new Date(entry.savedAt).toLocaleTimeString()}`}
405
- onClick={() => run('motion.loadVersion', { motionUrl: entry.motionUrl })}
406
- >
407
- <span className="motion-take-index">v{index + 1}</span>
408
- <span className="motion-take-label">{entry.label}</span>
409
- <span className="motion-take-time">
410
- {new Date(entry.savedAt).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", hourCycle: "h23" })}
411
- </span>
412
- </button>
413
- );
414
- })}
415
- </div>
416
- ) : (
417
- <p className="inspector-hint">{ko("No takes yet. Generate creates one.", "아직 테이크가 없어요. 생성하면 하나가 생깁니다.")}</p>
418
- )}
419
- {/* C10's per-entry replay verdict. Non-blocking: the take is loaded,
420
- one refinement just did not survive the trip onto it. */}
421
- {replayNotices.map((entry) => (
422
- <p className="inspector-hint replay-notice" key={`${entry.index}-${entry.track}`} data-replay-index={entry.index} data-replay-track={entry.track}>
423
- {entry.ok === false
424
- ? (isKo
425
- ? `다듬기 ${entry.index + 1}(${lineTrackLabel(entry.track)})은 다시 적용되지 않았어요 — 나머지는 그대로 이어졌습니다${entry.error ? ` (${entry.error})` : ""}`
426
- : `Refinement ${entry.index + 1} (${lineTrackLabel(entry.track)}) was not re-applied — the rest carried over${entry.error ? ` (${entry.error})` : ""}`)
427
- : (isKo
428
- ? `다듬기 ${entry.index + 1}(${lineTrackLabel(entry.track)})은 블록 경계에 걸쳐 있어요 — 결과가 이전과 조금 다를 수 있습니다`
429
- : `Refinement ${entry.index + 1} (${lineTrackLabel(entry.track)}) straddles a block boundary — the result may differ slightly from before`)}
430
- </p>
431
- ))}
432
- {/* A seedless recipe is an IMPORTED take: it reloads but cannot be
433
- rebuilt, so the footer says so rather than printing "seed null". */}
434
- {takeRecipe && (
435
- <p className="motion-takes-footer take-recipe-summary">
436
- {isKo
437
- ? `시드 ${Number.isInteger(takeRecipe.seed) ? takeRecipe.seed : "알 수 없음(불러온 테이크)"} · 블록 ${takeRecipe.blocks.length}개 · 다듬기 ${takeRecipe.lineEdits.length}개`
438
- : `Seed ${Number.isInteger(takeRecipe.seed) ? takeRecipe.seed : "unknown (imported take)"} · ${takeRecipe.blocks.length} block(s) · ${takeRecipe.lineEdits.length} refinement(s)`}
439
- </p>
440
- )}
441
- </div>
442
- </Foldout>
443
- );
444
- }
@@ -1,181 +0,0 @@
1
- import Foldout from "./Foldout.jsx";
2
- import { ko, isKo } from "../locale.js";
3
- import { footageSummary, trajectoryReceipt, segmentationReceipt } from "../multimodel-ingest.js";
4
- import { isImeComposing } from "../ime.js";
5
-
6
- export default function VideoCapturePanel({
7
- isCharacterSelection, multiModelStatus, multiModelStage, multiModelFileRef, chooseMultiModelFile,
8
- multiModelSource, multiModelUrl, setMultiModelUrl, useMultiModelUrl, pasteMultiModelUrl,
9
- multiModelProgress, multiModelError, multiModelFootage, extractMultiModelMotion, multiModelExtract,
10
- multiModelTake, multiModelExtractProgress, multiModelExtractError, activeChar, bridge,
11
- }) {
12
- return (
13
- <Foldout hidden={!isCharacterSelection} defaultOpen={false} title={ko("Video capture", "영상 모캡")}>
14
- <div className="multimodel-card v2-details-video-card">
15
- <div className="multimodel-card-head">
16
- <div>
17
- <strong>{ko("Footage → motion", "영상 → 모션")}</strong>
18
- <span>{ko("Prepare a source inside the Motion workspace.", "모션 작업공간에서 입력 영상을 준비하세요.")}</span>
19
- </div>
20
- <span className={"multimodel-status " + multiModelStatus}>
21
- {multiModelStatus === "ready"
22
- ? ko("READY", "준비됨")
23
- : multiModelStatus === "error"
24
- ? ko("CHECK", "확인 필요")
25
- : multiModelStatus === "busy"
26
- ? (multiModelStage === "fetching" ? ko("FETCHING", "받는 중") : ko("PROBING", "분석 중"))
27
- : ko("IDLE", "대기")}
28
- </span>
29
- </div>
30
- <div className="multimodel-input-block">
31
- <div className="multimodel-input-label">
32
- <strong>{ko("Local video file", "로컬 비디오 파일")}</strong>
33
- <span>{ko("Upload from this computer", "이 컴퓨터에서 업로드")}</span>
34
- </div>
35
- <div className="multimodel-source-row">
36
- <button type="button" className="btn ghost" onClick={() => multiModelFileRef.current?.click()}>
37
- {ko("Choose video", "영상 선택")}
38
- </button>
39
- <input ref={multiModelFileRef} className="multimodel-file-input" type="file" accept="video/*" onChange={chooseMultiModelFile} />
40
- <span className="multimodel-file-name">{multiModelSource?.kind === "file" ? multiModelSource.name : ko("No file selected", "파일이 선택되지 않음")}</span>
41
- </div>
42
- </div>
43
- <div className="multimodel-input-block">
44
- <div className="multimodel-input-label">
45
- <strong>{ko("Video URL", "비디오 URL")}</strong>
46
- <span>{ko("Use a hosted or local route", "호스팅 또는 로컬 경로 사용")}</span>
47
- </div>
48
- <input
49
- className="multimodel-url-input"
50
- type="text"
51
- value={multiModelUrl}
52
- onChange={(event) => setMultiModelUrl(event.target.value)}
53
- onKeyDown={(event) => { if (event.key === "Enter" && !isImeComposing(event)) useMultiModelUrl(); }}
54
- placeholder={ko("https://…/boxing.mp4", "https://…/boxing.mp4")}
55
- aria-label={ko("Multi-Model video URL", "멀티 모델 영상 URL")}
56
- spellCheck={false}
57
- />
58
- <div className="multimodel-url-actions">
59
- <button type="button" className="btn ghost" onClick={pasteMultiModelUrl}>
60
- {ko("Paste", "붙여넣기")}
61
- </button>
62
- <button type="button" className="btn ghost" onClick={() => setMultiModelUrl("")} disabled={!multiModelUrl}>
63
- {ko("Clear", "지우기")}
64
- </button>
65
- <button type="button" className="btn primary" onClick={useMultiModelUrl} disabled={!multiModelUrl.trim()}>
66
- {ko("Use URL", "URL 사용")}
67
- </button>
68
- </div>
69
- </div>
70
- {multiModelStatus === "busy" && (
71
- <div className="multimodel-progress">
72
- <div className="multimodel-progress-track">
73
- <div
74
- className={"multimodel-progress-bar" + (multiModelProgress === null ? " indeterminate" : "")}
75
- style={multiModelProgress === null ? undefined : { width: `${Math.round(multiModelProgress * 100)}%` }}
76
- />
77
- </div>
78
- <span>
79
- {multiModelStage === "fetching"
80
- ? (multiModelProgress === null
81
- ? ko("Downloading…", "다운로드 중…")
82
- : `${Math.round(multiModelProgress * 100)}%`)
83
- : ko("Decoding…", "디코딩 중…")}
84
- </span>
85
- </div>
86
- )}
87
- {multiModelError && <p className="multimodel-error">{multiModelError}</p>}
88
- {multiModelFootage && (
89
- <div className="multimodel-receipt">
90
- <video className="multimodel-preview" src={multiModelFootage.objectUrl} muted playsInline preload="metadata" />
91
- <div className="multimodel-receipt-body">
92
- <strong>{multiModelSource?.name}</strong>
93
- <span>{footageSummary(multiModelFootage)}</span>
94
- <span className="multimodel-receipt-timeline">
95
- {isKo
96
- ? `타임라인 0–${multiModelFootage.frames - 1} 프레임으로 맞춤`
97
- : `Timeline sized to frames 0–${multiModelFootage.frames - 1}`}
98
- </span>
99
- </div>
100
- </div>
101
- )}
102
- {multiModelFootage && (
103
- <div className="multimodel-extract">
104
- <button
105
- type="button"
106
- className="btn primary"
107
- onClick={extractMultiModelMotion}
108
- disabled={multiModelExtract === "running"}
109
- >
110
- {multiModelExtract === "running"
111
- ? ko("Extracting…", "추출 중…")
112
- : multiModelTake
113
- ? ko("Extract again", "다시 추출")
114
- : ko("Extract motion", "모션 추출")}
115
- </button>
116
- {multiModelExtract === "running" && (
117
- <div className="multimodel-progress">
118
- <div className="multimodel-progress-track">
119
- <div
120
- className={"multimodel-progress-bar" + (multiModelExtractProgress === null ? " indeterminate" : "")}
121
- style={multiModelExtractProgress === null ? undefined : { width: `${Math.round(multiModelExtractProgress * 100)}%` }}
122
- />
123
- </div>
124
- <span>
125
- {multiModelExtractProgress === null
126
- ? ko("Engine…", "엔진 준비…")
127
- : `${Math.round(multiModelExtractProgress * 100)}%`}
128
- </span>
129
- </div>
130
- )}
131
- {multiModelExtract === "error" && <p className="multimodel-error">{multiModelExtractError}</p>}
132
- {multiModelTake && (
133
- <p className="multimodel-extract-receipt">
134
- {multiModelTake.gpu
135
- ? (isKo
136
- ? `GVHMR 테이크 ${multiModelTake.frames}프레임 추출됨 — 타임라인에서 재생하세요`
137
- : `GVHMR take extracted, ${multiModelTake.frames} frames — press play on the timeline`)
138
- : (isKo
139
- ? `${multiModelTake.frames}프레임 테이크 구움 (실측 ${multiModelTake.fitted} · 유지 ${multiModelTake.held}) — 타임라인에서 재생하세요`
140
- : `Baked a ${multiModelTake.frames}-frame take (${multiModelTake.fitted} measured · ${multiModelTake.held} held) — press play on the timeline`)}
141
- </p>
142
- )}
143
- {multiModelTake?.trajectory && <p className="multimodel-note" data-testid="trajectory-receipt">{trajectoryReceipt(multiModelTake.trajectory, isKo)}</p>}
144
- {multiModelTake?.segmentation && <p className="multimodel-note" data-testid="segmentation-receipt">{segmentationReceipt(multiModelTake.segmentation, isKo)}</p>}
145
- {multiModelTake?.quality && <p className="multimodel-note" data-testid="mocap-quality-receipt">
146
- {multiModelTake.quality.pass
147
- ? ko("Mocap quality gate passed", "모캡 품질 게이트 통과")
148
- : ko(`Mocap quality warning: ${multiModelTake.quality.checks?.filter((check) => !check.pass).map((check) => check.name).join(", ") || "review required"}`, `모캡 품질 게이트 경고: ${multiModelTake.quality.checks?.filter((check) => !check.pass).map((check) => check.name).join(", ") || "확인 필요"}`)}
149
- </p>}
150
- {multiModelTake?.gpu && Math.abs(activeChar.y ?? 0) > .001 && <p className="multimodel-note" data-testid="trajectory-stage-offset">{isKo ? `씬 높이 ${(activeChar.y * 100).toFixed(1)}cm가 모션에 추가돼요 (Subject → Y)` : `Scene height ${(activeChar.y * 100).toFixed(1)}cm is added to the motion (Subject → Y)`}</p>}
151
- {multiModelTake?.persons > 1 && (
152
- <p className="multimodel-extract-receipt">
153
- {isKo
154
- ? `${multiModelTake.persons}명의 테이크를 각 인물 레이어에 배치했어요`
155
- : `${multiModelTake.persons} performers landed on their own subject layers`}
156
- </p>
157
- )}
158
- {multiModelExtract === "idle" && !multiModelTake && (
159
- <p className="multimodel-note">
160
- {bridge === null
161
- ? ko("Checking for the dev bridge…", "개발 브리지를 확인하는 중…")
162
- : bridge.ok && bridge.extractionBackend === "gvhmr"
163
- ? ko(
164
- "GVHMR extraction runs on the GPU box (about a minute per 15 s of footage).",
165
- "GVHMR 추출은 GPU 박스에서 돌아갑니다(영상 15초당 약 1분)."
166
- )
167
- : ko(
168
- "GVHMR extraction is unavailable until the local GPU bridge is connected.",
169
- "로컬 GPU 브리지가 연결될 때까지 GVHMR 추출을 사용할 수 없어요."
170
- )}
171
- </p>
172
- )}
173
- </div>
174
- )}
175
- <p className="multimodel-note">
176
- {ko("Locked-off footage with both performers in frame is best.", "두 사람이 함께 보이는 고정 카메라 영상이 가장 적합합니다.")}
177
- </p>
178
- </div>
179
- </Foldout>
180
- );
181
- }