cozyclay 2.0.2 → 2.1.1

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 (262) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +17 -2
  3. package/THIRD_PARTY_NOTICES.md +8 -0
  4. package/bin/agent/agent-routes.mjs +211 -36
  5. package/bin/agent/agent-runner.mjs +98 -4
  6. package/bin/agent/codex-client.mjs +2 -1
  7. package/bin/agent/fal-contract.mjs +0 -17
  8. package/bin/agent/h3-preservation.mjs +6 -8
  9. package/bin/agent/provider-keys.mjs +1 -1
  10. package/bin/agent/providers.mjs +124 -3
  11. package/bin/agent/script-tool.mjs +74 -0
  12. package/bin/agent/session-store.mjs +5 -5
  13. package/bin/agent/studio-prompt.mjs +2 -1
  14. package/bin/agent/studio-rebase.mjs +314 -0
  15. package/bin/agent/studio-tools.mjs +21 -14
  16. package/bin/agent/supervisor.mjs +311 -0
  17. package/bin/agent/video-adapters.mjs +0 -7
  18. package/bin/codex-auth.mjs +4 -4
  19. package/bin/live/cli.mjs +23 -8
  20. package/bin/live/client.mjs +1 -1
  21. package/bin/live/studio.mjs +5 -2
  22. package/bin/mcp-runtime.mjs +2 -2
  23. package/bin/telemetry-state.mjs +3 -3
  24. package/dist/app/index.html +6 -6
  25. package/dist/assets/analytics-C9pMpW7s.js +1 -0
  26. package/dist/assets/app-B_2XB9rw.css +1 -0
  27. package/dist/assets/app-DAuvKPP8.js +4920 -0
  28. package/dist/assets/{demo-ByeYp-dY.js → demo-CvKuBgy5.js} +1 -1
  29. package/dist/assets/{first-shot-handoff-DgT28ZiV.js → first-shot-handoff-msLI71g1.js} +1 -1
  30. package/dist/assets/{landing-BaXkpFip.js → landing-ChUvB_zL.js} +1 -1
  31. package/dist/assets/scene-asset-sync-DKkpjKBV.js +19 -0
  32. package/dist/assets/{shot-prompt-CbqWcWYi.css → scene-asset-sync-DjJ_cJ2R.css} +1 -1
  33. package/dist/assets/{ticket-BcmsnHn5.js → ticket-BPk2Ni95.js} +1 -1
  34. package/dist/assets/workflow-jJRBR94Z.js +179 -0
  35. package/dist/cozyclay-package.json +1 -1
  36. package/dist/index.html +328 -222
  37. package/dist/llms.txt +14 -0
  38. package/dist/sitemap.xml +1 -1
  39. package/dist/workflow/index.html +4 -4
  40. package/mcp/LIVE-PROTOCOL.md +23 -2
  41. package/mcp/README.md +37 -2
  42. package/mcp/ardy-prompts.mjs +1 -1
  43. package/mcp/image-file.mjs +132 -0
  44. package/mcp/live-hub.mjs +2 -2
  45. package/mcp/package.json +1 -0
  46. package/mcp/runtime/package-lock.json +7 -0
  47. package/mcp/runtime/package.json +1 -0
  48. package/mcp/server.mjs +0 -6
  49. package/mcp/tool-handlers.mjs +289 -87
  50. package/package.json +11 -2
  51. package/src/App.jsx +813 -278
  52. package/src/agent-image-client.js +94 -0
  53. package/src/analytics.js +47 -3
  54. package/src/app-stage.jsx +129 -2745
  55. package/src/ardy/auto-physics.js +6 -16
  56. package/src/ardy/collision-blockers.js +3 -7
  57. package/src/ardy/fix-collisions.js +5 -35
  58. package/src/ardy/ik-drag.js +86 -5
  59. package/src/ardy/ik-key-json.js +3 -1
  60. package/src/ardy/ik.js +15 -13
  61. package/src/ardy/motion-calibration.js +1 -1
  62. package/src/ardy/npz.js +0 -8
  63. package/src/ardy/physics-panel.jsx +3 -2
  64. package/src/ardy/physics-review.js +3 -2
  65. package/src/ardy/physics-support.js +1 -1
  66. package/src/ardy/physics-surface.js +1 -1
  67. package/src/ardy/platform-fit-panel.jsx +2 -1
  68. package/src/ardy/playback.js +1 -5
  69. package/src/ardy/range-pin.js +2 -2
  70. package/src/ardy/root-drop.js +0 -1
  71. package/src/ardy/timeline.css +184 -6
  72. package/src/ardy/timeline.jsx +121 -36
  73. package/src/ardy/to-cskel27.js +0 -2
  74. package/src/ardy/waypoints.js +0 -3
  75. package/src/ardy-bridge-contract.js +281 -0
  76. package/src/asset-pane.jsx +19 -9
  77. package/src/auto-color.js +1 -1
  78. package/src/burn-in.js +1 -1
  79. package/src/camera-block.js +1 -1
  80. package/src/camera-follow.js +75 -32
  81. package/src/camera-move.js +0 -6
  82. package/src/camera-tutorial.jsx +6 -7
  83. package/src/character-kind.js +79 -0
  84. package/src/command-bus.js +76 -17
  85. package/src/commands/cast.js +31 -7
  86. package/src/commands/elements/object.js +1 -1
  87. package/src/commands/elements/shot.js +1 -1
  88. package/src/commands/elements.js +1 -1
  89. package/src/commands/export.js +3 -3
  90. package/src/commands/motion.js +2 -2
  91. package/src/commands/objects.js +105 -10
  92. package/src/commands/project.js +15 -2
  93. package/src/commands/sculpt-images.js +53 -0
  94. package/src/commands/shot.js +88 -10
  95. package/src/commands/view.js +10 -4
  96. package/src/coplanar-depth.js +216 -0
  97. package/src/cuts.js +7 -6
  98. package/src/domains/cast.js +60 -43
  99. package/src/domains/motion/motion-intent-codec.js +50 -0
  100. package/src/domains/motion/motion-range-pin-rules.js +23 -0
  101. package/src/domains/motion/motion-video-capture.js +664 -0
  102. package/src/domains/motion.js +253 -742
  103. package/src/domains/objects.js +106 -5
  104. package/src/domains/scenes.js +79 -28
  105. package/src/domains/shots.js +33 -7
  106. package/src/error-boundary.jsx +1 -1
  107. package/src/execution-telemetry.js +5 -5
  108. package/src/facing-marks.js +14 -1
  109. package/src/first-success-guide.jsx +35 -4
  110. package/src/gizmo-claim.js +3 -1
  111. package/src/grid-floor.jsx +1 -4
  112. package/src/hierarchy-model.js +48 -35
  113. package/src/hierarchy-panel.css +1 -0
  114. package/src/hierarchy-panel.jsx +54 -102
  115. package/src/history.js +0 -2
  116. package/src/i2v-motion-client.js +1 -4
  117. package/src/ime.js +6 -0
  118. package/src/keyframe-pack.js +15 -6
  119. package/src/line-edit.js +4 -4
  120. package/src/live-control.js +6 -6
  121. package/src/matte-editor.js +2 -8
  122. package/src/matte.js +0 -19
  123. package/src/mesh-graph-clone.js +16 -2
  124. package/src/mesh-sniff.js +0 -1
  125. package/src/monotone-cubic.js +40 -0
  126. package/src/motion-store.js +4 -4
  127. package/src/motion-trail.js +5 -11
  128. package/src/multimodel-ingest.js +1 -3
  129. package/src/object-catalog.jsx +7 -5
  130. package/src/object-gizmo.jsx +45 -31
  131. package/src/object-path.js +310 -67
  132. package/src/object-travel.js +224 -0
  133. package/src/otio.js +8 -3
  134. package/src/panels/CharacterTransformPanel.jsx +24 -6
  135. package/src/panels/ObjectTransformPanel.jsx +4 -3
  136. package/src/panels/PoseImagePanel.jsx +205 -0
  137. package/src/panels/PromptBlocksPanel.jsx +3 -1
  138. package/src/panels/ProxyFigurePanel.jsx +56 -0
  139. package/src/panels/ReferenceImageField.jsx +1 -1
  140. package/src/panels/RigControlPanel.jsx +24 -3
  141. package/src/panels/RigPanel.jsx +2 -1
  142. package/src/panels/SculptPanel.jsx +405 -0
  143. package/src/panels/SubjectBox.jsx +1 -1
  144. package/src/panels/SubjectsPanel.jsx +0 -2
  145. package/src/panels/VideoCapturePanel.jsx +2 -1
  146. package/src/panels/pose-image.css +42 -0
  147. package/src/panels/pose.css +3 -0
  148. package/src/panels/sculpt.css +162 -0
  149. package/src/plan-diagram.js +184 -0
  150. package/src/planview.jsx +127 -80
  151. package/src/playground.js +3 -5
  152. package/src/pose-fade.js +77 -0
  153. package/src/pose-gizmo.css +23 -0
  154. package/src/pose-gizmo.js +96 -0
  155. package/src/posestudio.jsx +134 -83
  156. package/src/project-browser.css +53 -0
  157. package/src/project-browser.jsx +49 -4
  158. package/src/project.js +55 -24
  159. package/src/props.jsx +177 -36
  160. package/src/proxy-figure.jsx +69 -0
  161. package/src/range-pin-panel.jsx +0 -1
  162. package/src/receipt-findings.js +20 -0
  163. package/src/render-passes.js +0 -1
  164. package/src/resource-status.jsx +1 -1
  165. package/src/root-path.js +48 -0
  166. package/src/route-owner.js +52 -0
  167. package/src/scene-asset-cache.js +1 -2
  168. package/src/scene-assets.js +12 -4
  169. package/src/scene-fbx.js +1 -1
  170. package/src/scene-mesh-cache.js +0 -1
  171. package/src/scene-objects.js +319 -19
  172. package/src/scenes.js +58 -9
  173. package/src/sculpt-blueprint.js +65 -0
  174. package/src/sculpt-compare.js +384 -0
  175. package/src/sculpt-geometry.js +141 -0
  176. package/src/sculpt-mode.js +168 -0
  177. package/src/sculpt-recipe.js +385 -0
  178. package/src/sculpt-run.js +351 -0
  179. package/src/sculpt-stage.jsx +221 -0
  180. package/src/settings-menu.jsx +1 -1
  181. package/src/shell/BoardSlot.jsx +341 -0
  182. package/src/shell/BottomDock.jsx +60 -16
  183. package/src/shell/CompositionGuideButton.jsx +20 -0
  184. package/src/shell/DetailsSlot.jsx +26 -6
  185. package/src/shell/MenuBar.jsx +78 -6
  186. package/src/shell/OutlinerSlot.jsx +3 -1
  187. package/src/shell/ShotPreviewHeader.jsx +17 -0
  188. package/src/shell/TopBar.jsx +18 -3
  189. package/src/shell/ViewportToolbar.jsx +36 -31
  190. package/src/shell/dock.css +239 -0
  191. package/src/shell/glass-regions.css +3 -2
  192. package/src/shell/log-store.js +4 -4
  193. package/src/shell/mode.css +20 -0
  194. package/src/shell/studio-shell-context.js +4 -1
  195. package/src/shell/viewport.css +12 -0
  196. package/src/shot-authoring.js +69 -6
  197. package/src/stable-items.js +1 -1
  198. package/src/stage-attach-frames.js +169 -0
  199. package/src/stage-canvas-rigs.jsx +402 -0
  200. package/src/stage-capture.jsx +216 -0
  201. package/src/stage-characters.jsx +302 -0
  202. package/src/stage-editor-gizmos.jsx +1229 -0
  203. package/src/stage-labels-ko.js +204 -0
  204. package/src/stage-startup-defaults.js +182 -0
  205. package/src/starter-scenes.js +1 -1
  206. package/src/storyboard.js +24 -5
  207. package/src/studio-actions.js +42 -9
  208. package/src/studio-agent-commands.js +213 -23
  209. package/src/studio-agent-context.js +11 -9
  210. package/src/studio-agent-motion.js +2 -1
  211. package/src/studio-agent-protocol.js +60 -24
  212. package/src/studio-app-binding.js +56 -23
  213. package/src/studio-contact-sheet.js +3 -3
  214. package/src/studio-elements.js +11 -2
  215. package/src/studio-geometry-facts.js +114 -0
  216. package/src/styles.css +92 -9
  217. package/src/ui-scrub.js +4 -4
  218. package/src/ui.jsx +6 -4
  219. package/src/use-asset-shelf.js +60 -0
  220. package/src/use-camera-tutorial.js +50 -0
  221. package/src/use-embed-bridge.js +12 -0
  222. package/src/use-first-success-prompt.js +7 -0
  223. package/src/use-i2v-capture-modal.js +15 -0
  224. package/src/use-sculpt-mode.js +95 -0
  225. package/src/workflow/AgentPanel.jsx +106 -18
  226. package/src/workflow/WorkflowBuilder.jsx +1 -1
  227. package/src/workflow/agent-client.js +113 -45
  228. package/src/workflow/agent-panel.css +35 -0
  229. package/src/workflow/attachment-image.js +1 -1
  230. package/src/workflow/canvas-commands.js +3 -3
  231. package/src/workflow/cozy-scene-node.js +3 -3
  232. package/src/workflow/local-workflow.js +2 -2
  233. package/src/workflow/motion-input.js +3 -3
  234. package/src/workflow/node-schema.js +1 -1
  235. package/src/workflow/scene-asset-sync.js +2 -9
  236. package/src/workflow/shot-prompt-node.js +1 -1
  237. package/src/workflow/video-contract.js +1 -1
  238. package/src/workflow/workflow-resources.js +0 -8
  239. package/src/workflow-send.js +87 -0
  240. package/tools/ardy/__pycache__/cclay_gvhmr_worker.cpython-313.pyc +0 -0
  241. package/tools/check-eslint.mjs +57 -0
  242. package/tools/check-knip.mjs +60 -0
  243. package/tools/check-loc.mjs +54 -0
  244. package/tools/demo-worker/api-client.mjs +7 -13
  245. package/tools/demo-worker/generate.mjs +2 -4
  246. package/tools/eslint-baseline.json +23 -0
  247. package/tools/gt-render/browser.mjs +23 -0
  248. package/tools/headless-studio.mjs +85 -0
  249. package/tools/kimodo/effector-constraints.mjs +4 -4
  250. package/tools/kimodo/generate.mjs +1 -1
  251. package/tools/knip-baseline.json +331 -0
  252. package/tools/loc-baseline.json +126 -0
  253. package/tools/process-supervisor.mjs +1 -1
  254. package/tools/projflow/replay.mjs +4 -4
  255. package/tools/projflow/runner.mjs +3 -3
  256. package/tools/qa/studio-control-count.mjs +2 -0
  257. package/tools/run-tests.mjs +95 -7
  258. package/dist/assets/analytics-MVZOEW8O.js +0 -1
  259. package/dist/assets/app-BxBLC6GT.js +0 -4876
  260. package/dist/assets/app-CJdxvnrl.css +0 -1
  261. package/dist/assets/shot-prompt-hN0j_O-p.js +0 -17
  262. package/dist/assets/workflow-B5XZwVfe.js +0 -179
@@ -1 +1 @@
1
- import{b as e,d as t}from"./analytics-MVZOEW8O.js";import"./config-Bx7pYsD9.js";t().then(()=>e(`hosted:composer_viewed`));var n=`아직 동작하지 않는 기능입니다. This feature is not available yet.`;Object.freeze({active_job_exists:`You already have a motion in progress. Follow that ticket before starting another.`,daily_cap:`You have reached today's motion limit. Please come back tomorrow.`,queue_full:`The queue is full right now. Please try again in a little while.`,turnstile_failed:`The security check could not be verified. Complete it again and try once more.`,signed_in_required:`Sign in before creating a motion.`,invalid_prompt:`Enter a motion prompt within the allowed character limit.`,submissions_disabled:`New submissions are paused for maintenance. Please try again later.`});function r(e){return typeof document>`u`?null:document.getElementById(e)}function i(e=``){let t=r(`session-notice`);t&&(t.textContent=e,t.hidden=!e)}function a(e,{activeToken:t=null}={}){let n=r(`form-message`);if(n&&(n.replaceChildren(),e&&(n.append(document.createTextNode(e)),t))){let e=document.createElement(`a`);e.href=`/d/?t=${encodeURIComponent(t)}`,e.textContent=` Open your current ticket.`,n.append(e)}}function o(){r(`job-form`)?.addEventListener(`submit`,e=>{e.preventDefault(),a(n)}),document.querySelectorAll(`[data-provider], [data-prompt]`).forEach(e=>{e.addEventListener(`click`,()=>a(n))})}function s(){let e=r(`session-status`);e&&(e.textContent=`Preview`),i(n),r(`turnstile-widget`)?.closest(`.turnstile-wrap`)?.classList.add(`is-hidden`),o()}function c(){s()}typeof document<`u`&&(document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,c,{once:!0}):c());
1
+ import{d as e,x as t}from"./analytics-C9pMpW7s.js";import"./config-Bx7pYsD9.js";e().then(()=>t(`hosted:composer_viewed`));var n=`아직 동작하지 않는 기능입니다. This feature is not available yet.`;Object.freeze({active_job_exists:`You already have a motion in progress. Follow that ticket before starting another.`,daily_cap:`You have reached today's motion limit. Please come back tomorrow.`,queue_full:`The queue is full right now. Please try again in a little while.`,turnstile_failed:`The security check could not be verified. Complete it again and try once more.`,signed_in_required:`Sign in before creating a motion.`,invalid_prompt:`Enter a motion prompt within the allowed character limit.`,submissions_disabled:`New submissions are paused for maintenance. Please try again later.`});function r(e){return typeof document>`u`?null:document.getElementById(e)}function i(e=``){let t=r(`session-notice`);t&&(t.textContent=e,t.hidden=!e)}function a(e,{activeToken:t=null}={}){let n=r(`form-message`);if(n&&(n.replaceChildren(),e&&(n.append(document.createTextNode(e)),t))){let e=document.createElement(`a`);e.href=`/d/?t=${encodeURIComponent(t)}`,e.textContent=` Open your current ticket.`,n.append(e)}}function o(){r(`job-form`)?.addEventListener(`submit`,e=>{e.preventDefault(),a(n)}),document.querySelectorAll(`[data-provider], [data-prompt]`).forEach(e=>{e.addEventListener(`click`,()=>a(n))})}function s(){let e=r(`session-status`);e&&(e.textContent=`Preview`),i(n),r(`turnstile-widget`)?.closest(`.turnstile-wrap`)?.classList.add(`is-hidden`),o()}function c(){s()}typeof document<`u`&&(document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,c,{once:!0}):c());
@@ -1 +1 @@
1
- import{b as e,d as t,s as n,u as r}from"./analytics-MVZOEW8O.js";var i=new Set([`fly`,`walk`,`dolly`,`orbit`,`shot`,`rail`,`play`]),a=new Set([`query`,`settings`,`landing`]);function o({surface:o,startSource:s},{now:c=()=>performance.now(),initialize:l=t,capture:u=e,optedOut:d=r}={}){let f={surface:o===`playground`?`playground`:`studio`,tutorial_version:1},p=c(),m=new Map,h=new Set,g=`fly`,_=!1,v=!1,y=!1,b=[],x=()=>(d()&&(y=!0),y&&(b=[]),!y),S=(e,t={})=>{if(!x())return;let n={...f,...t};v?u(e,n):b.push([e,n])},C=(e,t)=>{!i.has(e)||m.has(e)||(m.set(e,t),S(`tutorial:step_entered`,{step_kind:e}))};return S(`tutorial:started`,{start_source:a.has(s)?s:`settings`}),C(`fly`,p),{ready:Promise.resolve(l()).then(()=>{if(v=!0,!x())return;let e=b;b=[];for(let[t,n]of e){if(!x())break;u(t,n)}}),observe(e,t){if(_)return;let r=c();g=i.has(t)?t:null;for(let t of e)!i.has(t)||h.has(t)||(C(t,r),h.add(t),S(`tutorial:step_completed`,{step_kind:t,elapsed_bucket:n(r-m.get(t))}));C(g,r),h.size===i.size&&(_=!0,S(`tutorial:completed`,{elapsed_bucket:n(r-p)}))},dismiss(){_||(_=!0,S(`tutorial:dismissed`,{step_kind:g}))}}}var s=`cozyclay.camera-tutorial-terminal.v1`;function c(e){try{return JSON.parse((e??globalThis.localStorage)?.getItem(s)||`null`)}catch{return null}}function l(e){let t=c(e);return t?.dismissed===!0||t?.completed===!0||t?.export_started===!0}function u(e,t){try{(t??globalThis.localStorage)?.setItem(s,JSON.stringify({[e]:!0}))}catch{}}function d(e){let t=l(e);return{canShow(e){return!t&&[`shot`,`rail`,`play`].every(t=>e.has(t))},complete(){u(`completed`,e)},dismiss(){t=!0,u(`dismissed`,e)},exportStarted(){t=!0,u(`export_started`,e)}}}export{o as i,d as n,u as r,l as t};
1
+ import{d as e,s as t,u as n,x as r}from"./analytics-C9pMpW7s.js";var i=new Set([`fly`,`walk`,`dolly`,`orbit`,`shot`,`rail`,`play`]),a=new Set([`query`,`settings`,`landing`]);function o({surface:o,startSource:s},{now:c=()=>performance.now(),initialize:l=e,capture:u=r,optedOut:d=n}={}){let f={surface:o===`playground`?`playground`:`studio`,tutorial_version:1},p=c(),m=new Map,h=new Set,g=`fly`,_=!1,v=!1,y=!1,b=[],x=()=>(d()&&(y=!0),y&&(b=[]),!y),S=(e,t={})=>{if(!x())return;let n={...f,...t};v?u(e,n):b.push([e,n])},C=(e,t)=>{!i.has(e)||m.has(e)||(m.set(e,t),S(`tutorial:step_entered`,{step_kind:e}))};return S(`tutorial:started`,{start_source:a.has(s)?s:`settings`}),C(`fly`,p),{ready:Promise.resolve(l()).then(()=>{if(v=!0,!x())return;let e=b;b=[];for(let[t,n]of e){if(!x())break;u(t,n)}}),observe(e,n){if(_)return;let r=c();g=i.has(n)?n:null;for(let n of e)!i.has(n)||h.has(n)||(C(n,r),h.add(n),S(`tutorial:step_completed`,{step_kind:n,elapsed_bucket:t(r-m.get(n))}));C(g,r),h.size===i.size&&(_=!0,S(`tutorial:completed`,{elapsed_bucket:t(r-p)}))},dismiss(){_||(_=!0,S(`tutorial:dismissed`,{step_kind:g}))}}}var s=`cozyclay.camera-tutorial-terminal.v1`;function c(e){try{return JSON.parse((e??globalThis.localStorage)?.getItem(s)||`null`)}catch{return null}}function l(e){let t=c(e);return t?.dismissed===!0||t?.completed===!0||t?.export_started===!0}function u(e,t){try{(t??globalThis.localStorage)?.setItem(s,JSON.stringify({[e]:!0}))}catch{}}function d(e){let t=l(e);return{canShow(e){return!t&&[`shot`,`rail`,`play`].every(t=>e.has(t))},complete(){u(`completed`,e)},dismiss(){t=!0,u(`dismissed`,e)},exportStarted(){t=!0,u(`export_started`,e)}}}export{o as i,d as n,u as r,l as t};
@@ -1 +1 @@
1
- import"./analytics-MVZOEW8O.js";import{i as e,n as t}from"./first-shot-handoff-DgT28ZiV.js";(()=>{let n=document.getElementById(`playground`),r=document.getElementById(`try`),i=document.getElementById(`tutorial-steps`),a=document.getElementById(`tutorial-card`),o=document.getElementById(`tutorial-card-step`),s=document.getElementById(`tutorial-now`),c=document.getElementById(`tutorial-done`),l=document.getElementById(`playground-start`),u=document.getElementById(`playground-full`),d=document.getElementById(`playground-close`),f=document.getElementById(`playground-download`),p=document.getElementById(`playground-download-status`),m=document.getElementById(`playground-download-error`),h=document.getElementById(`playground-handoff-dismiss`),g=()=>matchMedia(`(min-width: 721px) and (hover: hover)`).matches,_=[`w`,`a`,`s`,`d`,`q`,`e`],v=new Set,y=[{kind:`fly`,label:`Look`,how:()=>`Right-drag to look around.`},{kind:`walk`,label:`Walk`,how:()=>`Keep the right button held and press each key once: `+_.map(e=>`<kbd data-done="${+!!v.has(e)}">${e.toUpperCase()}</kbd>`).join(` `)+`. W A S D walk, Q E crane.`},{kind:`dolly`,label:`Dolly`,how:()=>`Scroll to push in and pull out.`},{kind:`orbit`,label:`Orbit`,how:()=>`Hold <kbd>Alt</kbd> (<kbd>⌥ Option</kbd> on Mac) and left-drag to circle the character.`},{kind:`shot`,label:`Shot`,how:()=>`Click <b>+ Add shot</b> in the Shots lane below. That is your cut.`},{kind:`rail`,label:`Rail`,how:()=>`Click the shot block, then <b>Draw rail</b>, and drag a line across the map that pops up. That line is the dolly move.`},{kind:`play`,label:`Play`,how:()=>`You are looking through the shot camera now, full-screen. Press <b>▶</b> in the transport to ride your rail; <kbd>Esc</kbd> hands the view back to the free camera.`}],b=new Set,x=null,S=null,C=null,w=!1,T=!1,E=!1,D=()=>{},O=()=>{let e=n.dataset.state===`live`,t=e?y.find(e=>!b.has(e.kind)):null;e&&S?.observe(b,t?.kind??null),i.innerHTML=y.map((e,n)=>`<li data-done="${+!!b.has(e.kind)}" data-current="${+(t===e)}">${n+1} ${e.label}</li>`).join(``),a.hidden=!t||w,i.hidden=w,t&&(o.textContent=`${y.indexOf(t)+1} / ${y.length}`,s.innerHTML=t.how()),c.hidden=!(e&&!w&&(C?.canShow(b)||E)),e&&!t&&C?.complete(),x?.contentWindow?.postMessage({type:`cozyclay:playground-hint`,kind:w?null:t?.kind??null},`*`),e&&!t&&!O.reported&&(O.reported=!0,window.posthog?.capture&&window.posthog.capture(`landing:playground_tutorial_done`))};window.addEventListener(`message`,e=>{if(e.data?.type!==`cozyclay:playground-nav`||!x||e.source!==x.contentWindow||e.origin!==window.location.origin)return;let t=e.data.kind;if(!(!y.some(e=>e.kind===t)||b.has(t))){if(t===`walk`&&(typeof e.data.key==`string`&&v.add(e.data.key),!_.every(e=>v.has(e)))){O();return}b.add(t),O()}});let k=({dismiss:e=!0}={})=>{e&&S?.dismiss(),e&&x&&C?.dismiss(),C=null,T=!1,E=!1,f.disabled=!1,m.hidden=!0,p.hidden=!0,S=null,D(),x&&x.remove(),x=null,n.dataset.state=``,l.hidden=!1,r.classList.remove(`playground-live`),b.clear(),v.clear(),O()};l.addEventListener(`click`,()=>{if(!g())return;x&&k({dismiss:!1}),C=t(),w=!1,S=e({surface:`playground`,startSource:`landing`}),x=document.createElement(`iframe`),x.src=`/app/?embed=playground&scene=/scenes/city-block.cclayproject`,x.title=`CozyClay playground`,x.allow=`fullscreen; pointer-lock`,x.loading=`eager`,n.appendChild(x),n.dataset.state=`loading`,l.hidden=!0;let i=()=>{n.dataset.state===`loading`&&(D(),n.dataset.state=`live`,r.classList.add(`playground-live`),O())},a=e=>{e.data?.type===`cozyclay:playground-ready`&&e.source===x?.contentWindow&&e.origin===window.location.origin&&i()};window.addEventListener(`message`,a);let o=setTimeout(i,15e3);D=()=>{clearTimeout(o),window.removeEventListener(`message`,a)},window.posthog?.capture&&window.posthog.capture(`landing:playground_started`)}),u.addEventListener(`click`,()=>{x?.requestFullscreen&&x.requestFullscreen()}),h.addEventListener(`click`,()=>{C?.dismiss(),S?.dismiss(),w=!0,E=!1,m.hidden=!0,O()}),f.addEventListener(`click`,()=>{!x||T||(C?.exportStarted(),T=!0,E=!0,f.disabled=!0,m.hidden=!0,p.hidden=!1,p.textContent=`Preparing your edited project…`,x.contentWindow.postMessage({type:`cozyclay:playground-export`},`*`))}),window.addEventListener(`message`,e=>{if(e.data?.type!==`cozyclay:playground-export-result`||!T||!x||e.source!==x.contentWindow||e.origin!==window.location.origin)return;if(T=!1,f.disabled=!1,typeof e.data.serialized!=`string`||!e.data.serialized){p.hidden=!0,m.hidden=!1,m.textContent=`The project could not be prepared. Your edits are still here; try Download my project again.`;return}let t=new Blob([e.data.serialized],{type:`application/json`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`city-block.cclayproject`,r.click(),setTimeout(()=>URL.revokeObjectURL(n),1e3),f.dataset.state=`copied`,E=!1,p.textContent=`Project download requested. Open city-block.cclayproject in your local Studio, then use Export.`,O(),setTimeout(()=>{f.dataset.state=``},1400),window.posthog?.capture&&window.posthog.capture(`landing:playground_scene_downloaded`)}),d.addEventListener(`click`,k),document.querySelectorAll(`button.copy[data-copy]`).forEach(e=>{e.addEventListener(`click`,async()=>{try{await navigator.clipboard.writeText(e.dataset.copy),e.dataset.state=`copied`,setTimeout(()=>{e.dataset.state=``},1400)}catch{}})}),O()})();
1
+ import"./analytics-C9pMpW7s.js";import{i as e,n as t}from"./first-shot-handoff-msLI71g1.js";(()=>{let n=document.getElementById(`playground`),r=document.getElementById(`try`),i=document.getElementById(`tutorial-steps`),a=document.getElementById(`tutorial-card`),o=document.getElementById(`tutorial-card-step`),s=document.getElementById(`tutorial-now`),c=document.getElementById(`tutorial-done`),l=document.getElementById(`playground-start`),u=document.getElementById(`playground-full`),d=document.getElementById(`playground-close`),f=document.getElementById(`playground-download`),p=document.getElementById(`playground-download-status`),m=document.getElementById(`playground-download-error`),h=document.getElementById(`playground-handoff-dismiss`),g=()=>matchMedia(`(min-width: 721px) and (hover: hover)`).matches,_=[`w`,`a`,`s`,`d`,`q`,`e`],v=new Set,y=[{kind:`fly`,label:`Look`,how:()=>`Right-drag to look around.`},{kind:`walk`,label:`Walk`,how:()=>`Keep the right button held and press each key once: `+_.map(e=>`<kbd data-done="${+!!v.has(e)}">${e.toUpperCase()}</kbd>`).join(` `)+`. W A S D walk, Q E crane.`},{kind:`dolly`,label:`Dolly`,how:()=>`Scroll to push in and pull out.`},{kind:`orbit`,label:`Orbit`,how:()=>`Hold <kbd>Alt</kbd> (<kbd>⌥ Option</kbd> on Mac) and left-drag to circle the character.`},{kind:`shot`,label:`Shot`,how:()=>`Click <b>+ Add shot</b> in the Shots lane below. That is your cut.`},{kind:`rail`,label:`Rail`,how:()=>`Click the shot block, then <b>Draw rail</b>, and drag a line across the map that pops up. That line is the dolly move.`},{kind:`play`,label:`Play`,how:()=>`You are looking through the shot camera now, full-screen. Press <b>▶</b> in the transport to ride your rail; <kbd>Esc</kbd> hands the view back to the free camera.`}],b=new Set,x=null,S=null,C=null,w=!1,T=!1,E=!1,D=()=>{},O=()=>{let e=n.dataset.state===`live`,t=e?y.find(e=>!b.has(e.kind)):null;e&&S?.observe(b,t?.kind??null),i.innerHTML=y.map((e,n)=>`<li data-done="${+!!b.has(e.kind)}" data-current="${+(t===e)}">${n+1} ${e.label}</li>`).join(``),a.hidden=!t||w,i.hidden=w,t&&(o.textContent=`${y.indexOf(t)+1} / ${y.length}`,s.innerHTML=t.how()),c.hidden=!(e&&!w&&(C?.canShow(b)||E)),e&&!t&&C?.complete(),x?.contentWindow?.postMessage({type:`cozyclay:playground-hint`,kind:w?null:t?.kind??null},`*`),e&&!t&&!O.reported&&(O.reported=!0,window.posthog?.capture&&window.posthog.capture(`landing:playground_tutorial_done`))};window.addEventListener(`message`,e=>{if(e.data?.type!==`cozyclay:playground-nav`||!x||e.source!==x.contentWindow||e.origin!==window.location.origin)return;let t=e.data.kind;if(!(!y.some(e=>e.kind===t)||b.has(t))){if(t===`walk`&&(typeof e.data.key==`string`&&v.add(e.data.key),!_.every(e=>v.has(e)))){O();return}b.add(t),O()}});let k=({dismiss:e=!0}={})=>{e&&S?.dismiss(),e&&x&&C?.dismiss(),C=null,T=!1,E=!1,f.disabled=!1,m.hidden=!0,p.hidden=!0,S=null,D(),x&&x.remove(),x=null,n.dataset.state=``,l.hidden=!1,r.classList.remove(`playground-live`),b.clear(),v.clear(),O()};l.addEventListener(`click`,()=>{if(!g())return;x&&k({dismiss:!1}),C=t(),w=!1,S=e({surface:`playground`,startSource:`landing`}),x=document.createElement(`iframe`),x.src=`/app/?embed=playground&scene=/scenes/city-block.cclayproject`,x.title=`CozyClay playground`,x.allow=`fullscreen; pointer-lock`,x.loading=`eager`,n.appendChild(x),n.dataset.state=`loading`,l.hidden=!0;let i=()=>{n.dataset.state===`loading`&&(D(),n.dataset.state=`live`,r.classList.add(`playground-live`),O())},a=e=>{e.data?.type===`cozyclay:playground-ready`&&e.source===x?.contentWindow&&e.origin===window.location.origin&&i()};window.addEventListener(`message`,a);let o=setTimeout(i,15e3);D=()=>{clearTimeout(o),window.removeEventListener(`message`,a)},window.posthog?.capture&&window.posthog.capture(`landing:playground_started`)}),u.addEventListener(`click`,()=>{x?.requestFullscreen&&x.requestFullscreen()}),h.addEventListener(`click`,()=>{C?.dismiss(),S?.dismiss(),w=!0,E=!1,m.hidden=!0,O()}),f.addEventListener(`click`,()=>{!x||T||(C?.exportStarted(),T=!0,E=!0,f.disabled=!0,m.hidden=!0,p.hidden=!1,p.textContent=`Preparing your edited project…`,x.contentWindow.postMessage({type:`cozyclay:playground-export`},`*`))}),window.addEventListener(`message`,e=>{if(e.data?.type!==`cozyclay:playground-export-result`||!T||!x||e.source!==x.contentWindow||e.origin!==window.location.origin)return;if(T=!1,f.disabled=!1,typeof e.data.serialized!=`string`||!e.data.serialized){p.hidden=!0,m.hidden=!1,m.textContent=`The project could not be prepared. Your edits are still here; try Download my project again.`;return}let t=new Blob([e.data.serialized],{type:`application/json`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`city-block.cclayproject`,r.click(),setTimeout(()=>URL.revokeObjectURL(n),1e3),f.dataset.state=`copied`,E=!1,p.textContent=`Project download requested. Open city-block.cclayproject in your local Studio, then use Export.`,O(),setTimeout(()=>{f.dataset.state=``},1400),window.posthog?.capture&&window.posthog.capture(`landing:playground_scene_downloaded`)}),d.addEventListener(`click`,k),document.querySelectorAll(`button.copy[data-copy]`).forEach(e=>{e.addEventListener(`click`,async()=>{try{await navigator.clipboard.writeText(e.dataset.copy),e.dataset.state=`copied`,setTimeout(()=>{e.dataset.state=``},1400)}catch{}})}),O()})();