aitu-app 0.9.0 → 0.9.2

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 (59) hide show
  1. package/README.md +3 -3
  2. package/assets/{CanvasAudioPlayer-cp00LGgR.js → CanvasAudioPlayer-C_USx5uz.js} +1 -1
  3. package/assets/{ComicCreator-CAmJF3JX.js → ComicCreator-qGQaXp7h.js} +2 -2
  4. package/assets/DeferredAIInputBar-CPykEFYX.css +1 -0
  5. package/assets/DeferredAIInputBar-LmZGQCLT.js +107 -0
  6. package/assets/{DrawnixDeferredFeatures-DIznfzB7.js → DrawnixDeferredFeatures-Hy_-quZ1.js} +1 -1
  7. package/assets/{KnowledgeBaseContent-CxilHI-j.js → KnowledgeBaseContent-DSKNA70H.js} +8 -8
  8. package/assets/{MVCreator-ZrinzYPm.js → MVCreator-C3iClDLU.js} +12 -10
  9. package/assets/{ModelBenchmarkWorkbench-DbesnX6E.js → ModelBenchmarkWorkbench-BxwdcZ0q.js} +2 -2
  10. package/assets/{MusicAnalyzer-BzXD1qYH.js → MusicAnalyzer-f_T6_YPJ.js} +2 -2
  11. package/assets/{ParametersDropdown-DBQCDv3g.js → ParametersDropdown-CTSN3ClD.js} +1 -1
  12. package/assets/{PromptHistoryTool-CUCIE0Ld.js → PromptHistoryTool-DV-8RSdz.js} +2 -2
  13. package/assets/{ResizableDivider-CdfJF8GW.js → ResizableDivider-CUQBmPpx.js} +1 -1
  14. package/assets/TaskQueuePanel-CtjY1W4t.js +1 -0
  15. package/assets/{VideoAnalyzer-wtxorxD3.js → VideoAnalyzer-BBVBSONO.js} +3 -3
  16. package/assets/{VideoAnalyzer-C90c84gt.js → VideoAnalyzer-BmAjGvN8.js} +1 -1
  17. package/assets/{ai-chat-B5qFht2H.js → ai-chat-BO5vbKZW.js} +5 -5
  18. package/assets/{ai-generation-preferences-service-CvWbMxv3.js → ai-generation-preferences-service-ZmPTR-wz.js} +1 -1
  19. package/assets/{batch-image-generation-Bo3h_Eop.js → batch-image-generation-BLBSv-t6.js} +6 -6
  20. package/assets/{diagram-engines-C9ewAq_o.js → diagram-engines-CSzW_-6N.js} +2 -2
  21. package/assets/{editor-engines-CvxZrFyB.js → editor-engines-C573k8UM.js} +1 -1
  22. package/assets/{index-Dw6PsLbq.js → index-BT-rxxI3.js} +2 -2
  23. package/assets/{index-BCqdmg38.js → index-Dw_8lcIi.js} +1 -1
  24. package/assets/{index-BSlnQdcy.js → index-IHNaVKGH.js} +1 -1
  25. package/assets/{index-CjBeKr1R.js → index-N8asYyaz.js} +1 -1
  26. package/assets/{index-CylhK_f5.js → index-jxwTv7c1.js} +1 -1
  27. package/assets/{index.es-BKVY-J2g.js → index.es-BLXvmueB.js} +1 -1
  28. package/assets/{jspdf.es.min-BM9ML7Zw.js → jspdf.es.min-DxWvbkh4.js} +2 -2
  29. package/assets/{markdown-to-drawnix-COS1iVyq.js → markdown-to-drawnix-BVFYnimo.js} +2 -2
  30. package/assets/{mermaid-to-drawnix-oplawQO0.js → mermaid-to-drawnix-nGs2aeZ7.js} +2 -2
  31. package/assets/{model-benchmark-launcher-DD4vN0Ca.js → model-benchmark-launcher-DAWoSySc.js} +1 -1
  32. package/assets/{photo-wall-splitter-CbKqFOIV.js → photo-wall-splitter-CCUURzGk.js} +1 -1
  33. package/assets/{prompt-utils-7t-jk6n6.js → prompt-utils-MF_LILNU.js} +1 -1
  34. package/assets/{settings-dialog-D2yEWl8J.js → settings-dialog-Ac7R-_CG.js} +1 -1
  35. package/assets/{skill-dsl-parser-C-utRXFg.js → skill-dsl-parser-Do9iAYbB.js} +1 -1
  36. package/assets/{startup-app-DxX-P1pm.js → startup-app-eD_rQhSh.js} +531 -527
  37. package/assets/{task-sync-Dr7Nza2v.js → task-sync-BJVOunRa.js} +1 -1
  38. package/assets/{tool-windows-BIjc1zsU.js → tool-windows-CmgL3thd.js} +17 -17
  39. package/assets/ttd-dialog-B12v0SVY.js +6 -0
  40. package/assets/{ttd-dialog-submit-shortcut-yUk15rsg.js → ttd-dialog-submit-shortcut-C2lJygXA.js} +1 -1
  41. package/assets/useCharacters-BAKE4TeJ.js +2 -0
  42. package/assets/{useMediaViewer-CEvHYype.js → useMediaViewer-BGw5RkSR.js} +1 -1
  43. package/assets/{useWorkflowSubmission-Cxhdsl2b.js → useWorkflowSubmission-iAPmKke9.js} +6 -6
  44. package/assets/{video-recovery-service-CB8hyRf5.js → video-recovery-service-CW7bErP2.js} +1 -1
  45. package/assets/{workflow-generation-utils-JoRODaP7.js → workflow-generation-utils-DhIVnOHO.js} +2 -2
  46. package/assets/workflow-submission-service-Ce0cpj8E.js +4 -0
  47. package/changelog.json +18 -13
  48. package/idle-prefetch-manifest.json +306 -306
  49. package/manifest.json +3 -3
  50. package/package.json +1 -1
  51. package/precache-manifest.json +6 -6
  52. package/sw.js +1 -1
  53. package/version.json +6 -3
  54. package/assets/DeferredAIInputBar-CzMATNng.js +0 -107
  55. package/assets/DeferredAIInputBar-D_e6qG1y.css +0 -1
  56. package/assets/TaskQueuePanel-oLG4DAzJ.js +0 -1
  57. package/assets/ttd-dialog-CNSSc4wk.js +0 -6
  58. package/assets/useCharacters-DzXMuknh.js +0 -2
  59. package/assets/workflow-submission-service-BIGFW4s4.js +0 -4
@@ -1,4 +1,4 @@
1
- import{nl as ns,nm as os,nn as is,no as ls,np as cs,a1 as Jt,nq as ds,m$ as st,n6 as Xt,nr as Da,ns as us,nt as ms,nc as Oa,r as s,n0 as Tt,aw as ye,bz as Ce,dA as fs,dB as $e,bg as He,am as ze,f0 as ha,aB as rt,j as t,n3 as Ba,n4 as La,aA as Nt,n5 as Qt,mI as Fa,mL as za,mN as Ua,mW as ps,mO as hs,mP as vs,mQ as gs,bB as _s,nu as bs,nv as ys,nb as Ss,mh as va,ck as Is,nd as ga,iU as Cs,iW as xs,ji as js,M as et,nf as ws,ne as _a,h9 as Ct,db as Ft,gT as Ga,ng as zt,nh as ba,ni as ks,b7 as Ms,R as ut,E as tt,nw as Ts,nx as Ns,ef as Ut,eK as ya,nj as As,mz as xt,mA as $s,mB as Ps,$ as Es,c1 as Rs,mD as Vs,mE as Ds,mF as Os}from"./startup-app-DxX-P1pm.js";import{e as Bs}from"./task-sync-Dr7Nza2v.js";import{F as Ls,M as Sa}from"./tool-windows-BIjc1zsU.js";import{i as nt,m as Ne,K as ea,v as Ia,R as Ca,q as Gt,V as Fs}from"./ai-chat-B5qFht2H.js";import{c as xa,f as ja,g as zs,d as Us}from"./ai-generation-preferences-service-CvWbMxv3.js";/* empty css */import{R as Gs}from"./ResizableDivider-CdfJF8GW.js";import{r as Ks,a as Hs,b as wa,w as Kt,d as Ws,g as Ys,f as qs}from"./workflow-generation-utils-JoRODaP7.js";import{P as ka}from"./ParametersDropdown-DBQCDv3g.js";/* empty css */import{u as Js}from"./VideoAnalyzer-C90c84gt.js";/* empty css */import"./startup-runtime-DTmhLESk.js";const At="mv-creator:records",Zs=50;async function $t(){return ns(At)}async function Ma(e){return is(At,e,Zs)}async function le(e,o){return os(At,e,o)}async function Xs(e){return ls(At,e)}const Qs=10,Ka="原创性与合规要求:若音乐、歌词、创作 Brief 或用户提示词包含知名影视、动画、游戏、音乐、品牌、角色、商标、Logo、台词、歌词或受保护作品名称,不要复刻或仿写,不要使用原名称、标志性造型、独特服装、台词、歌词、镜头或世界观;请改写为原创的泛化角色、场景、音乐情绪和视觉元素,并保持商业可用。";function Ha(e,o,i,m){return{id:Jt(),createdAt:Date.now(),label:o,prompt:i,shots:structuredClone(e),...m!=null&&m.characters?{characters:structuredClone(m.characters)}:{},...m!=null&&m.videoStyle?{videoStyle:m.videoStyle}:{}}}function Wa(e,o){return ds(e,"storyboardVersions",o,Qs,{editedShots:o.shots})}const Mt=cs;function er(e,o){return ms(e,"storyboardVersions",o,{getVersionPatch:i=>({editedShots:i.shots,...i.characters?{characters:structuredClone(i.characters)}:{},...i.videoStyle?{videoStyle:i.videoStyle}:{}}),getOriginalPatch:i=>{var u;const m=(u=i.storyboardVersions)==null?void 0:u[i.storyboardVersions.length-1];return m?{editedShots:[...m.shots]}:null},originalVersionId:Mt})}function Ke(e,o){return us(e,"storyboardVersions",o)}function Ya(e,o=e.editedShots||[]){var $,M,S;const i=e.selectedClipDuration||o.reduce((v,W)=>Math.max(v,W.endTime||0),0),m=($=e.musicStyleTags)==null?void 0:$.filter(Boolean).join(", "),u=e.characters||[],y=Oa(e.creativeBrief),_=["# 爆款MV脚本","",`**音乐标题:** ${e.musicTitle||"-"}`,`**音乐风格:** ${m||"-"}`,`**时长:** ${i||0}s`,`**画面比例:** ${e.aspectRatio||"16x9"}`,`**视频风格:** ${e.videoStyle||"-"}`];y&&_.push("","## 创作 Brief","",y),(M=e.musicLyrics)!=null&&M.trim()&&_.push("","## 歌词","",e.musicLyrics.trim()),(S=e.rewritePrompt)!=null&&S.trim()&&_.push("","## 改编提示词","",e.rewritePrompt.trim()),u.length>0&&(_.push("","## 角色设定",""),u.forEach((v,W)=>{_.push(`### ${W+1}. ${v.name||v.id}`),_.push(`- ID:${v.id}`),_.push(`- 外观提示词:${v.description||"-"}`),v.referenceImageUrl&&_.push(`- 参考图:${v.referenceImageUrl}`),_.push("")}));const k=o.map((v,W)=>{var L;return[`### ${W+1}. ${v.label||`镜头 ${W+1}`} (${v.startTime}s-${v.endTime}s)`,"",`**画面描述:** ${v.description||"-"}`,"",`**旁白:** ${v.narration||"-"}`,v.dialogue?`
1
+ import{nt as ns,nu as os,nv as is,nw as ls,nx as cs,a1 as Jt,ny as ds,n7 as st,ne as Xt,nz as Da,nA as us,nB as ms,nk as Oa,r as s,n8 as Tt,aw as ye,bz as Ce,dA as fs,dB as $e,bg as He,am as Fe,f0 as ha,aB as rt,j as t,nb as Ba,nc as La,aA as Nt,nd as Qt,mQ as za,mT as Fa,mV as Ua,n2 as ps,mW as hs,mX as vs,mY as gs,bB as _s,nC as bs,nD as ys,nj as Ss,mp as va,ck as Is,nl as ga,iV as Cs,iX as xs,jo as js,M as et,nn as ws,nm as _a,ha as Ct,db as zt,gT as Ga,no as Ft,np as ba,nq as ks,b7 as Ms,R as ut,E as tt,nE as Ts,nF as Ns,ef as Ut,eK as ya,nr as As,mH as xt,mI as $s,mJ as Ps,$ as Es,c1 as Vs,mL as Rs,mM as Ds,mN as Os}from"./startup-app-eD_rQhSh.js";import{e as Bs}from"./task-sync-BJVOunRa.js";import{E as Ls,M as Sa}from"./tool-windows-CmgL3thd.js";import{i as nt,m as Ne,K as ea,v as Ia,R as Ca,q as Gt,V as zs}from"./ai-chat-BO5vbKZW.js";import{c as xa,f as ja,g as Fs,d as Us}from"./ai-generation-preferences-service-ZmPTR-wz.js";/* empty css */import{R as Gs}from"./ResizableDivider-CUQBmPpx.js";import{r as Ks,a as Hs,b as wa,w as Kt,d as Ws,g as Ys,f as qs}from"./workflow-generation-utils-DhIVnOHO.js";import{P as ka}from"./ParametersDropdown-CTSN3ClD.js";/* empty css */import{u as Js}from"./VideoAnalyzer-BmAjGvN8.js";/* empty css */import"./startup-runtime-DTmhLESk.js";const At="mv-creator:records",Zs=50;async function $t(){return ns(At)}async function Ma(e){return is(At,e,Zs)}async function le(e,o){return os(At,e,o)}async function Xs(e){return ls(At,e)}const Qs=10,Ka="原创性与合规要求:若音乐、歌词、创作 Brief 或用户提示词包含知名影视、动画、游戏、音乐、品牌、角色、商标、Logo、台词、歌词或受保护作品名称,不要复刻或仿写,不要使用原名称、标志性造型、独特服装、台词、歌词、镜头或世界观;请改写为原创的泛化角色、场景、音乐情绪和视觉元素,并保持商业可用。";function Ha(e,o,i,m){return{id:Jt(),createdAt:Date.now(),label:o,prompt:i,shots:structuredClone(e),...m!=null&&m.characters?{characters:structuredClone(m.characters)}:{},...m!=null&&m.videoStyle?{videoStyle:m.videoStyle}:{}}}function Wa(e,o){return ds(e,"storyboardVersions",o,Qs,{editedShots:o.shots})}const Mt=cs;function er(e,o){return ms(e,"storyboardVersions",o,{getVersionPatch:i=>({editedShots:i.shots,...i.characters?{characters:structuredClone(i.characters)}:{},...i.videoStyle?{videoStyle:i.videoStyle}:{}}),getOriginalPatch:i=>{var u;const m=(u=i.storyboardVersions)==null?void 0:u[i.storyboardVersions.length-1];return m?{editedShots:[...m.shots]}:null},originalVersionId:Mt})}function Ke(e,o){return us(e,"storyboardVersions",o)}function Ya(e,o=e.editedShots||[]){var $,M,S;const i=e.selectedClipDuration||o.reduce((v,W)=>Math.max(v,W.endTime||0),0),m=($=e.musicStyleTags)==null?void 0:$.filter(Boolean).join(", "),u=e.characters||[],y=Oa(e.creativeBrief),_=["# 爆款MV脚本","",`**音乐标题:** ${e.musicTitle||"-"}`,`**音乐风格:** ${m||"-"}`,`**时长:** ${i||0}s`,`**画面比例:** ${e.aspectRatio||"16x9"}`,`**视频风格:** ${e.videoStyle||"-"}`];y&&_.push("","## 创作 Brief","",y),(M=e.musicLyrics)!=null&&M.trim()&&_.push("","## 歌词","",e.musicLyrics.trim()),(S=e.rewritePrompt)!=null&&S.trim()&&_.push("","## 改编提示词","",e.rewritePrompt.trim()),u.length>0&&(_.push("","## 角色设定",""),u.forEach((v,W)=>{_.push(`### ${W+1}. ${v.name||v.id}`),_.push(`- ID:${v.id}`),_.push(`- 外观提示词:${v.description||"-"}`),v.referenceImageUrl&&_.push(`- 参考图:${v.referenceImageUrl}`),_.push("")}));const k=o.map((v,W)=>{var L;return[`### ${W+1}. ${v.label||`镜头 ${W+1}`} (${v.startTime}s-${v.endTime}s)`,"",`**画面描述:** ${v.description||"-"}`,"",`**旁白:** ${v.narration||"-"}`,v.dialogue?`
2
2
  **角色对白:** ${v.dialogue}`:"",v.dialogue_speakers?`
3
3
  **对白角色:** ${v.dialogue_speakers}`:"",v.speech_relation?`
4
4
  **语音关系:** ${v.speech_relation}`:"",v.camera_movement?`
@@ -16,7 +16,7 @@ ${k.join(`
16
16
 
17
17
  ---
18
18
 
19
- `)}`}function tr(e){const{musicTitle:o,musicStyleTags:i,musicLyrics:m,clipDuration:u,videoModel:y,segmentDuration:_,aspectRatio:k,videoStyle:$,creativeBrief:M,hasAudio:S}=e,v=st(y),W=_||parseInt(v.defaultDuration,10)||8,F=[{label:`${W}秒`,value:String(W)}],L=Xt(u,F),{segments:p,actualTotal:I,isFixed:z,overflow:T}=L,N=p.length,U=z?`视频模型(${y})为固定时长模型,每段固定 ${p[0]} 秒。实际总时长:${I} 秒(${N} 段)${T>0?`,比音乐时长 ${u} 秒多出 ${T} 秒`:""}。`:`分段方案:${p.map((ce,J)=>`第${J+1}段 ${ce}s`).join("、")},实际总时长 ${I} 秒。`,Q=[o?`- 标题:${o}`:"",i!=null&&i.length?`- 风格标签:${i.join(", ")}`:"",`- 时长:${u}秒`,m?`- 歌词:
19
+ `)}`}function tr(e){const{musicTitle:o,musicStyleTags:i,musicLyrics:m,clipDuration:u,videoModel:y,segmentDuration:_,aspectRatio:k,videoStyle:$,creativeBrief:M,hasAudio:S}=e,v=st(y),W=_||parseInt(v.defaultDuration,10)||8,z=[{label:`${W}秒`,value:String(W)}],L=Xt(u,z),{segments:p,actualTotal:I,isFixed:F,overflow:T}=L,N=p.length,U=F?`视频模型(${y})为固定时长模型,每段固定 ${p[0]} 秒。实际总时长:${I} 秒(${N} 段)${T>0?`,比音乐时长 ${u} 秒多出 ${T} 秒`:""}。`:`分段方案:${p.map((ce,J)=>`第${J+1}段 ${ce}s`).join("、")},实际总时长 ${I} 秒。`,Q=[o?`- 标题:${o}`:"",i!=null&&i.length?`- 风格标签:${i.join(", ")}`:"",`- 时长:${u}秒`,m?`- 歌词:
20
20
  ${m}`:""].filter(Boolean).join(`
21
21
  `),te=S?`
22
22
  ⚠️ 重要:本次请求附带了音频文件。你必须先完整听完这段音乐,基于你听到的实际节奏、节拍、情绪变化来编排分镜,而不是仅凭歌词文本猜测。
@@ -50,6 +50,7 @@ ${Da(M,"mv")}
50
50
  2. 为每个角色生成:id("char_1", "char_2"...)、name(展示名)、description(英文外貌描述,包含发型、服装、体型、肤色等,可直接用于文生图)
51
51
  3. 每个镜头标注 character_ids(该镜头涉及的角色 ID 列表,无角色则为空数组)
52
52
  4. first_frame_prompt 中若有角色,必须包含对应角色的完整外貌描述,并明确沿用同一人物身份、脸型五官、发型、体型、年龄感、完整服装款式、服装颜色、材质和配饰,不得重新设计衣服;同时每个镜头必须写入本镜头独有的视觉锚点(动作阶段、主体位置、角色关系、道具状态、镜头角度或情绪节奏),避免不同片段只复用相同场景/角色/风格描述;last_frame_prompt 可为空,只有确实需要独立尾帧图时才填写,非空时必须保持同一人物、同一发型、同一套衣服和同一配饰
53
+ 5. 创作 Brief、歌词意象、相似案例和相似剧情只作背景,不要覆盖首帧/尾帧、角色设定和每段音乐时间点的画面任务;不要把相似剧情复述进 first_frame_prompt 或 last_frame_prompt。
53
54
 
54
55
  分镜规划步骤(请严格按顺序执行):
55
56
  ${te}
@@ -72,7 +73,7 @@ ${te}
72
73
  2. startTime 从 0 开始,每个镜头的 startTime = 上一个镜头的 endTime
73
74
  3. 镜头之间要有视觉连贯性(共同视觉元素、运镜方向延续、色调一致)
74
75
  4. 所有字段使用与音乐信息或创作 Brief 一致的语言
75
- 5. 视频模型单段通常只有 8-15 秒;连续超过单段时长的内容必须拆成多个连续镜头。连续拆分时,第 N+1 段的 first_frame_prompt 就是第 N 段的尾帧状态,第 N 段 last_frame_prompt 留空字符串;只有最后一段、非连续转场、明确需要独立结束定格时才填写 last_frame_prompt
76
+ 5. 视频模型单段通常只有 8-15 秒;连续超过单段时长的内容必须拆成多个连续镜头。连续拆分时,第 N+1 段的 first_frame_prompt 只描述当前段起始画面,可包含第 N 段结尾的短视觉锚点(主体位置、动作瞬间、光线方向),不要写上一段剧情经过;第 N 段 last_frame_prompt 留空字符串;只有最后一段、非连续转场、明确需要独立结束定格时才填写 last_frame_prompt
76
77
 
77
78
  每个镜头输出字段:
78
79
  - id: 镜头ID(如 "shot_1")
@@ -85,7 +86,7 @@ ${te}
85
86
  - narration: 旁白(MV 通常为空字符串)
86
87
  - camera_movement: 运镜方式(必须匹配该段音乐的节奏感)
87
88
  - first_frame_prompt: 首帧图片提示词(精确描述主体位置、动作起始状态、构图、光线与背景;必须写入本镜头独有的视觉锚点、差异化动作起点、构图角度和角色关系,避免只复用同一角色外貌、同一场景和同一泛化风格;若该镜头有角色,必须包含对应角色的完整外貌、发型、脸部特征、体型、年龄感、服装款式、服装颜色、材质和配饰)
88
- - last_frame_prompt: 尾帧图片提示词,可为空字符串(只有需要独立尾帧图时才填写;若下一段首帧自然承接为本段尾帧,则填 "";非空时必须沿用同一人物和同一套服装,只改变结尾姿态、表情、动作定格、构图、光线或背景)
89
+ - last_frame_prompt: 尾帧图片提示词,可为空字符串(只有需要独立尾帧图时才填写;若下一段首帧自然承接为本段尾帧,则填 "";非空时必须沿用同一人物和同一套服装,只改变本镜头结尾姿态、表情、动作定格、构图、光线或背景,不写下一镜头剧情)
89
90
  - transition_hint: 转场方式(cut/dissolve/match_cut/fade_to_black)
90
91
  - character_ids: 该镜头涉及的角色 ID 列表(无角色则为空数组 [])
91
92
 
@@ -95,7 +96,7 @@ ${te}
95
96
  { "id": "char_1", "name": "角色名", "description": "English appearance description for text-to-image" }
96
97
  ],
97
98
  "shots": [ ...镜头数组... ]
98
- }`}function ar(e){var J;const{record:o,currentShots:i,rewritePrompt:m,videoModel:u,segmentDuration:y,videoStyle:_}=e,k=o.selectedClipDuration||30,$=o.characters||[],M=$.length>0,S=st(u),v=y||parseInt(S.defaultDuration,10)||8,W=[{label:`${v}秒`,value:String(v)}],F=Xt(k,W),{segments:L,actualTotal:p,isFixed:I,overflow:z}=F,T=L.length,N=I?`视频模型(${u})为固定时长模型,每段固定 ${L[0]} 秒。实际总时长:${p} 秒(${T} 段)${z>0?`,比音乐时长 ${k} 秒多出 ${z} 秒`:""}。`:`分段方案:${L.map((b,ge)=>`第${ge+1}段 ${b}s`).join("、")},实际总时长 ${p} 秒。`,U=[o.musicTitle?`- 标题:${o.musicTitle}`:"",(J=o.musicStyleTags)!=null&&J.length?`- 风格标签:${o.musicStyleTags.join(", ")}`:"",`- 时长:${k}秒`,o.musicLyrics?`- 歌词:
99
+ }`}function ar(e){var J;const{record:o,currentShots:i,rewritePrompt:m,videoModel:u,segmentDuration:y,videoStyle:_}=e,k=o.selectedClipDuration||30,$=o.characters||[],M=$.length>0,S=st(u),v=y||parseInt(S.defaultDuration,10)||8,W=[{label:`${v}秒`,value:String(v)}],z=Xt(k,W),{segments:L,actualTotal:p,isFixed:I,overflow:F}=z,T=L.length,N=I?`视频模型(${u})为固定时长模型,每段固定 ${L[0]} 秒。实际总时长:${p} 秒(${T} 段)${F>0?`,比音乐时长 ${k} 秒多出 ${F} 秒`:""}。`:`分段方案:${L.map((b,ge)=>`第${ge+1}段 ${b}s`).join("、")},实际总时长 ${p} 秒。`,U=[o.musicTitle?`- 标题:${o.musicTitle}`:"",(J=o.musicStyleTags)!=null&&J.length?`- 风格标签:${o.musicStyleTags.join(", ")}`:"",`- 时长:${k}秒`,o.musicLyrics?`- 歌词:
99
100
  ${o.musicLyrics}`:""].filter(Boolean).join(`
100
101
  `),Q=JSON.stringify(i.map(b=>({id:b.id,label:b.label,type:b.type,startTime:b.startTime,endTime:b.endTime,duration:b.duration,description:b.description,narration:b.narration||"",first_frame_prompt:b.first_frame_prompt,last_frame_prompt:b.last_frame_prompt,camera_movement:b.camera_movement,character_ids:b.character_ids||[]}))),te=_||o.videoStyle||"",ce=Da(o.creativeBrief,"mv");return`你是一个专业的 MV 脚本改编专家。请基于以下 MV 分镜脚本,根据用户提示词进行改编。
101
102
 
@@ -140,6 +141,7 @@ ${Ka}
140
141
 
141
142
  步骤衔接要求:
142
143
  - 第3步生成首帧/视频时不会继续读取“用户改编提示词”原文;必须把改编意图落实到 description、first_frame_prompt、必要时的 last_frame_prompt、characters 和 video_style 中。
144
+ - 用户改编提示词中的故事、相似案例或相似剧情只作背景,不要复述到 first_frame_prompt/last_frame_prompt;每个镜头优先执行音乐时间段、角色一致性和关键帧画面。
143
145
  - 不要依赖后续生成步骤再理解“改编要求”,每个镜头字段本身要可直接生成。
144
146
  - 改编后逐镜头检查 first_frame_prompt,不得高度相似;相邻镜头可以共享连续性元素,但必须有清晰不同的动作阶段、构图或角色关系。
145
147
 
@@ -148,8 +150,8 @@ ${Ka}
148
150
  2. 运镜方向延续,不能突然反向
149
151
  3. 所有镜头统一色调和光线风格
150
152
  4. 动作连贯,上一镜头结尾动作延续到下一镜头开头
151
- 5. 单段视频模型通常只能生成 8-15 秒;连续超过单段时长的内容应拆成多个连续片段,并把“上一段结尾状态”写进下一段 first_frame_prompt。此时上一段 last_frame_prompt 必须留空字符串,生成页会直接复用下一段首帧作为上一段尾帧。
152
- 6. 只有最后一段、非连续转场、明确需要独立结束定格或与下一段首帧不一致时,才填写 last_frame_prompt;不要为每段都强行生成尾帧图。
153
+ 5. 单段视频模型通常只能生成 8-15 秒;连续超过单段时长的内容应拆成多个连续片段。下一段 first_frame_prompt 只描述当前段起始画面,可包含上一段结尾的短视觉锚点(主体位置、动作瞬间、光线方向),不要写上一段剧情经过;此时上一段 last_frame_prompt 必须留空字符串,生成页会直接复用下一段首帧作为上一段尾帧。
154
+ 6. 只有最后一段、非连续转场、明确需要独立结束定格或与下一段首帧不一致时,才填写 last_frame_prompt;不要为每段都强行生成尾帧图,非空尾帧只写本镜头结束画面,不写下一镜头剧情。
153
155
 
154
156
  返回 JSON 对象(不要 markdown 格式),格式如下:
155
157
  {
@@ -158,6 +160,6 @@ ${Ka}
158
160
  { "id": "char_1", "name": "角色名", "description": "English appearance description for text-to-image" }
159
161
  ],
160
162
  "shots": [ ...镜头数组,每个元素包含 id、startTime、endTime、duration、description、narration、first_frame_prompt、last_frame_prompt、camera_movement、label、type、transition_hint、character_ids 字段... ]
161
- }`}const Ht="mv-creator:video-model",Wt="mv-creator:storyboard-model",Ta="gemini-2.5-pro",Na="AI 分镜草稿";function sr(e,o){return(e.purpose||e.directorStyle||e.narrativeStyle||o||Na).trim().slice(0,24)||Na}const rr=({existingRecord:e,onComplete:o,onRecordsChange:i,onNext:m})=>{const[u,y]=s.useState((e==null?void 0:e.videoStyle)||""),[_,k]=s.useState(()=>Tt(e==null?void 0:e.creativeBrief)),[$,M]=s.useState([]),[S,v]=s.useState((e==null?void 0:e.selectedClipId)||null),[W,F]=s.useState(!1),L=nt("video"),[p,I]=s.useState(()=>(e==null?void 0:e.videoModel)||ye(Ht,"veo3").modelId),[z,T]=s.useState(()=>(e==null?void 0:e.videoModelRef)||ye(Ht,"veo3").modelRef),N=s.useMemo(()=>st(p),[p]),[U,Q]=s.useState(()=>(e==null?void 0:e.segmentDuration)||parseInt(N.defaultDuration,10)||8),te=s.useMemo(()=>(N.durationOptions||[]).map(c=>({value:parseInt(c.value,10),label:c.label})),[N]),ce=nt("text"),J=s.useMemo(()=>ce.filter(c=>/^gemini/i.test(c.id)),[ce]),[b,ge]=s.useState(()=>ye(Wt,Ta).modelId),[se,We]=s.useState(()=>ye(Wt,Ta).modelRef),[q,De]=s.useState(!1),[ee,_e]=s.useState(""),re=s.useRef(!1),xe=s.useRef(),ne=s.useRef(e||null);s.useEffect(()=>{e&&(y(e.videoStyle||""),k(Tt(e.creativeBrief)),v(e.selectedClipId||null))},[e]),s.useEffect(()=>{ne.current=e||null},[e]),s.useEffect(()=>{M([])},[e==null?void 0:e.id]);const de=(e==null?void 0:e.editedShots)||[];s.useEffect(()=>{de.length>0&&F(!0)},[de.length]);const ue=e==null?void 0:e.id;s.useEffect(()=>{if(ue)return clearTimeout(xe.current),xe.current=setTimeout(async()=>{const c=ne.current;if(!c||c.id!==ue)return;const g={videoStyle:u,creativeBrief:_,videoModel:p,videoModelRef:z,segmentDuration:U},Y=await le(ue,g);i(Y),o({...c,...g})},500),()=>clearTimeout(xe.current)},[ue,u,_,p,z,U,o,i]),s.useEffect(()=>{var ae;const c=e==null?void 0:e.pendingStoryboardTaskId;if(!c){_e("");return}const g=Ce.getTask(c);if((g==null?void 0:g.status)==="failed"){_e(`分镜生成失败: ${((ae=g.error)==null?void 0:ae.message)||"未知错误"}`);return}if((g==null?void 0:g.status)==="completed"){_e("");return}const Y=Ce.observeTaskUpdates().subscribe(pe=>{var we;pe.task.id===c&&(pe.task.status==="failed"?_e(`分镜生成失败: ${((we=pe.task.error)==null?void 0:we.message)||"未知错误"}`):pe.task.status==="completed"&&_e(""))});return()=>Y.unsubscribe()},[e==null?void 0:e.pendingStoryboardTaskId]);const[fe,Oe]=s.useState([]);s.useEffect(()=>{let c=!1;return fs.getAllTasks({type:He.AUDIO,status:$e.COMPLETED,includeArchived:!0}).then(g=>{if(c)return;const Y=[];for(const ae of g){const pe=Bs(ae);for(const we of pe)Y.push({...we,prompt:String(ae.params.prompt||"")})}Oe(Y)}).catch(()=>{}),()=>{c=!0}},[]);const he=s.useMemo(()=>{var c;return S&&(((c=e==null?void 0:e.generatedClips)==null?void 0:c.find(g=>g.clipId===S))||fe.find(g=>g.clipId===S))||null},[S,e==null?void 0:e.generatedClips,fe]),je=(he==null?void 0:he.audioUrl)||(S?e==null?void 0:e.selectedClipAudioUrl:null),be=(e==null?void 0:e.selectedClipDuration)||(he==null?void 0:he.duration)||30,oe=s.useCallback(()=>{ze.trackUIInteraction({area:"popular_mv_tool",action:"music_tool_opened",control:"open_music_tool",source:"mv_creator_analyze_page",metadata:{existingAudioClipsCount:fe.length}});const c=ha.getPrimaryToolState("mv-creator"),g=c==null?void 0:c.position,Y=g?{x:g.x+((c==null?void 0:c.tool.defaultWidth)||520)+16,y:g.y}:void 0;ha.openTool(Ls.manifest,{launchMode:"reuse",position:Y})},[fe.length]),Be=s.useCallback(async c=>{var Y;ze.trackUIInteraction({area:"popular_mv_tool",action:"music_clip_selected",control:"select_music_clip",source:"mv_creator_analyze_page",metadata:{hasClipId:!!c.clipId,hasAudioUrl:!!c.audioUrl,duration:c.duration}});let g=e||null;if(g){const ae=g.generatedClips||[],d={generatedClips:ae.some(P=>P.clipId===c.clipId)?ae:[...ae,c],selectedClipId:c.clipId,selectedClipDuration:c.duration??null,selectedClipAudioUrl:c.audioUrl,musicTitle:g.musicTitle||c.title||""},R=await le(g.id,d);i(R),o({...g,...d})}else{const ae=c.title||((Y=c.prompt)==null?void 0:Y.slice(0,20))||"已有音频";g={id:Jt(),createdAt:Date.now(),sourceLabel:ae,starred:!1,musicTitle:c.title||"",generatedClips:[c],selectedClipId:c.clipId,selectedClipDuration:c.duration??null,selectedClipAudioUrl:c.audioUrl};const pe=await Ma(g);i(pe),o(g)}v(c.clipId),_e("")},[e,o,i]),Pe=s.useCallback((c,g)=>{I(c),T(g||null),rt(Ht,c,g);const Y=st(c);Q(parseInt(Y.defaultDuration,10)||8)},[]),Se=s.useCallback((c,g)=>{ge(c),We(g||null),rt(Wt,c,g)},[]),Le=s.useCallback(async()=>{if(re.current)return;if(!je){_e("请先选择配乐");return}re.current=!0;const c=e||{id:Jt(),createdAt:Date.now(),sourceLabel:sr(_,u),starred:!1,musicTitle:"",generatedClips:[],selectedClipId:null,selectedClipDuration:null,selectedClipAudioUrl:null};ze.trackUIInteraction({area:"popular_mv_tool",action:"storyboard_generation_started",control:"generate_storyboard",source:"mv_creator_analyze_page",metadata:{hasSelectedClip:!!je,clipDuration:be,segmentDuration:U,hasStoryboardModelRef:!!se,hasVideoModelRef:!!z}}),De(!0),_e("");try{const g=tr({musicTitle:c.musicTitle,musicStyleTags:c.musicStyleTags,musicLyrics:c.musicLyrics,clipDuration:be,videoModel:p,segmentDuration:U,aspectRatio:c.aspectRatio||"16x9",videoStyle:u,creativeBrief:_,hasAudio:!!je}),ae={pendingStoryboardTaskId:Ce.createTask({prompt:g,model:b,modelRef:se,mvCreatorAction:"storyboard",mvCreatorRecordId:c.id,knowledgeContextRefs:$,audioCacheUrl:je},He.CHAT).id,videoModel:p,videoModelRef:z,segmentDuration:U,videoStyle:u,creativeBrief:_,aspectRatio:c.aspectRatio||"16x9"},pe={...c,...ae},we=e?await le(c.id,ae):await Ma(pe);i(we),o(pe),_e("分镜规划任务已提交,等待 AI 生成...")}catch(g){_e(g instanceof Error?g.message:"提交失败")}finally{De(!1),re.current=!1}},[e,be,p,z,U,u,_,b,se,$,je,o,i]);return t.jsxs("div",{className:"va-page",children:[de.length>0&&t.jsx("button",{className:"va-collapse-toggle",onClick:()=>F(c=>!c),children:W?"▶ 展开配置":"▼ 收起配置"}),!W&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"ma-card ma-card--grow",children:[t.jsxs("div",{className:"ma-card-header",children:[t.jsxs("span",{children:["选择配乐 (",fe.length,")"]}),t.jsx("button",{className:"ma-chip ma-chip--accent",style:{cursor:"pointer",fontSize:"11px",padding:"2px 8px"},onClick:oe,children:"+ 生成新音乐"})]}),fe.length===0?t.jsxs("div",{className:"ma-hint",children:["暂无已完成的音频,",t.jsx("button",{onClick:oe,style:{background:"none",border:"none",color:"#E67E22",cursor:"pointer",textDecoration:"underline",padding:0,font:"inherit"},children:"去生成音乐"})]}):t.jsx("div",{className:"ma-clips-gallery",children:fe.map((c,g)=>{var Y;return t.jsxs("div",{className:`ma-clip-row ${S===c.clipId?"is-selected":""}`,onClick:()=>Be(c),style:{cursor:"pointer"},children:[c.imageUrl?t.jsx("img",{src:c.imageUrl,alt:"",className:"ma-clip-thumb",referrerPolicy:"no-referrer"}):t.jsx("div",{className:"ma-clip-thumb ma-clip-thumb--placeholder",children:"♪"}),t.jsxs("div",{className:"ma-clip-meta",children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"4px"},children:[t.jsx("span",{className:"ma-clip-title",children:c.title||((Y=c.prompt)==null?void 0:Y.slice(0,30))||c.clipId}),S===c.clipId&&t.jsx("span",{className:"ma-chip ma-chip--accent",style:{flexShrink:0,padding:"0 4px",fontSize:"10px",height:"16px",lineHeight:"14px"},children:"已选"})]}),c.duration!=null&&t.jsxs("span",{className:"ma-clip-duration",children:[Math.round(c.duration),"s"]})]}),t.jsx("audio",{controls:!0,src:c.audioUrl,preload:"metadata",className:"ma-clip-player",onClick:ae=>ae.stopPropagation()})]},`${c.clipId||g}`)})})]}),t.jsx(Ba,{value:_,onChange:k,workflow:"mv",videoStyle:u,onVideoStyleChange:y}),S&&t.jsx(La,{selectedModel:p,selectedSelectionKey:Ne(p,z),onSelectModel:Pe,models:L,segmentDuration:U,durationOptions:te,onSegmentDurationChange:Q}),t.jsxs("div",{className:"ma-card mv-storyboard-control-card",children:[ee&&t.jsx("div",{className:"ma-progress mv-storyboard-message",children:ee}),t.jsxs("div",{className:"mv-storyboard-control-row",children:[t.jsxs("div",{className:"mv-storyboard-field mv-storyboard-field--knowledge",children:[t.jsx("label",{className:"mv-storyboard-field-label",children:"知识库上下文"}),t.jsx(ea,{value:$,onChange:M,disabled:q,className:"mv-knowledge-context-selector mv-knowledge-context-selector--inline"})]}),t.jsxs("div",{className:"mv-storyboard-field mv-storyboard-field--model",children:[t.jsx("label",{className:"mv-storyboard-field-label",children:"AI 分镜模型"}),t.jsx(Nt,{models:J,selectedModel:b,selectedSelectionKey:Ne(b,se),onSelect:(c,g)=>Se(c,g),variant:"form",placement:"auto",disabled:q})]}),t.jsx("button",{className:"va-analyze-btn va-analyze-btn--inline mv-storyboard-generate-btn",onClick:Le,disabled:q,children:q?"提交中...":de.length>0?"重新生成分镜":"AI 生成分镜"})]})]})]}),de.length>0&&t.jsxs(t.Fragment,{children:[he&&W&&t.jsx("div",{className:"ma-card",children:t.jsxs("div",{className:"ma-clip-row is-selected",children:[he.imageUrl?t.jsx("img",{src:he.imageUrl,alt:"",className:"ma-clip-thumb",referrerPolicy:"no-referrer"}):t.jsx("div",{className:"ma-clip-thumb ma-clip-thumb--placeholder",children:"♪"}),t.jsxs("div",{className:"ma-clip-meta",children:[t.jsx("span",{className:"ma-clip-title",children:he.title||he.clipId}),t.jsxs("span",{className:"ma-clip-duration",children:[Math.round(be),"s"]})]}),t.jsx("audio",{controls:!0,src:he.audioUrl,preload:"metadata",className:"ma-clip-player"})]})}),(e==null?void 0:e.characters)&&e.characters.length>0&&t.jsxs("div",{className:"ma-card",children:[t.jsx("div",{className:"ma-card-header",children:t.jsxs("span",{children:["角色(",e.characters.length," 个)"]})}),t.jsx("div",{className:"va-characters",children:e.characters.map(c=>t.jsx("div",{className:"va-character-item",children:t.jsxs("div",{className:"va-character-info",children:[t.jsx("span",{className:"va-character-name",children:c.name}),t.jsx("span",{className:"va-character-desc",children:c.description})]})},c.id))})]}),t.jsxs("div",{className:"ma-card",children:[t.jsx("div",{className:"ma-card-header",children:t.jsxs("span",{children:["分镜脚本(",de.length," 个镜头)"]})}),t.jsx("div",{className:"va-shots",children:de.map((c,g)=>t.jsx(Qt,{shot:c,index:g,compact:!0},c.id))})]}),m&&t.jsx("div",{className:"va-page-actions",children:t.jsx("button",{className:"va-btn-primary",onClick:m,children:"下一步:编辑脚本 →"})})]})]})};function ta(e){return gs(e,"mvCreatorAction",["storyboard","rewrite"])}function nr(e){return ta(e)!==null}function or(e){const o=Ua(e);if(!o)throw new Error("分镜任务缺少结果内容");try{const y=_s(o,$=>Array.isArray($.shots)),_=(y.shots||[]).map(($,M)=>({...$,id:$.id||`shot_${M+1}`})),k=Array.isArray(y.characters)?y.characters:[];return{shots:_,characters:k}}catch{}try{return{shots:bs(o,_=>Array.isArray(_)&&_.some(k=>k&&typeof k=="object")).map((_,k)=>({..._,id:_.id||`shot_${k+1}`})),characters:[]}}catch{}const i=[],m=[],u=ys(o,y=>{const _=y;return typeof _.id=="string"||_.startTime!==void 0});for(const y of u){const _=typeof y.id=="string"?y.id:"";_.startsWith("char_")&&y.name&&y.description?m.push(y):(_.startsWith("shot_")||y.startTime!==void 0)&&i.push({...y,id:_||`shot_${i.length+1}`})}if(i.length>0)return{shots:i,characters:m};throw new Error("响应中未找到有效 JSON(可能因输出过长被截断)")}function Aa(e,o){const i=new Map(e.map(m=>[m.id,m]));return o.map(m=>{const u=i.get(m.id);return{...m,referenceImageUrl:m.referenceImageUrl||(u==null?void 0:u.referenceImageUrl)}})}async function ir(e){if(e.status!=="completed"||ta(e)!=="storyboard")return null;const o=Fa(e,"mvCreatorRecordId");if(!o)return null;const m=(await $t()).find(M=>M.id===o);if(!m||m.pendingStoryboardTaskId!==e.id)return null;const{shots:u,characters:y}=or(e),_=(m.storyboardVersions||[]).length,k=Ha(u,`AI 分镜 #${_+1}`,e.params.prompt,{characters:y,videoStyle:m.videoStyle}),$=Wa(m,k);return za(m,{editedShots:u,pendingStoryboardTaskId:null,storyboardGeneratedAt:Date.now(),...y.length>0?{characters:y}:{},...$},le)}async function Zt(e){if(e.status!=="completed"||ta(e)!=="rewrite")return null;const o=Fa(e,"mvCreatorRecordId");if(!o)return null;const i=await $t(),m=i.find(p=>p.id===o);if(!m)return null;if(m.pendingRewriteTaskId!==e.id)return!m.pendingRewriteTaskId&&m.storyboardGeneratedAt&&(!e.completedAt||m.storyboardGeneratedAt>=e.completedAt)?{records:i,record:m}:null;const u=Ua(e);if(!u)return null;const y=m.editedShots||[],_=ps(u,y),k=_.shots,$=_.characters,M=_.hasCharacters,S=_.videoStyle,v=(m.storyboardVersions||[]).length,W=Ha(k,`AI 改编 #${v+1}`,e.params.prompt,{characters:M?Aa(m.characters||[],$||[]):m.characters||[],videoStyle:S||m.videoStyle}),F=Wa(m,W),L=M?Aa(m.characters||[],$||[]):void 0;return za(m,{editedShots:k,pendingRewriteTaskId:null,storyboardGeneratedAt:Date.now(),...L!==void 0?{characters:L}:{},...S?{videoStyle:S}:{},...F},le)}function lr(e){if(e.type!==He.AUDIO)return null;const o=e.params.batchId;return o?hs(o,{prefix:"mv_",marker:"_music_"}):null}async function cr(e,o){return vs(e,o,{loadRecords:$t,updateRecord:le})}function at(e){e.style.height="auto",e.style.height=e.scrollHeight+"px"}function mt(e){e&&at(e)}function ft(e,o=30){if(!e)return 1;const i=e.split(`
162
- `);let m=0;for(const u of i)m+=Math.max(1,Math.ceil(u.length/o));return Math.max(1,m)}function Je(e,o,i){return e.find(m=>m.id===o)||i}const dr=["固定镜头 (Static)","缓慢推近 (Dolly In)","缓慢拉远 (Dolly Out)","水平平移 (Pan)","垂直摇移 (Tilt)","跟随拍摄 (Follow)","手持感 (Handheld)","环绕拍摄 (Orbit)","升降镜头 (Crane)","快速推移 (Zoom In)","快速拉远 (Zoom Out)","航拍俯冲 (Drone Dive)"],ur=[{label:"硬切 (cut)",value:"cut"},{label:"交叉溶解 (dissolve)",value:"dissolve"},{label:"匹配切 (match_cut)",value:"match_cut"},{label:"淡出到黑 (fade_to_black)",value:"fade_to_black"}],Yt="mv-creator:script-model",$a="gemini-2.5-pro",mr=({record:e,onRecordUpdate:o,onRecordsChange:i,onNext:m})=>{var pe,we;const[u,y]=s.useState(e.editedShots||[]),[_,k]=s.useState(e.rewritePrompt||""),[$,M]=s.useState([]),[S,v]=s.useState(!1),[W,F]=s.useState(""),[L,p]=s.useState(""),[I,z]=s.useState(e.pendingRewriteTaskId||null),[T,N]=s.useState(!1),U=s.useRef(null),Q=s.useRef(!1),te=nt("video"),ce="mv-creator:video-model",[J,b]=s.useState(()=>e.videoModel||ye(ce,"veo3").modelId),[ge,se]=s.useState(()=>e.videoModelRef||ye(ce,"veo3").modelRef),We=s.useMemo(()=>st(J),[J]),[q,De]=s.useState(()=>e.segmentDuration||parseInt(We.defaultDuration,10)||8),ee=s.useMemo(()=>(We.durationOptions||[]).map(d=>({value:parseInt(d.value,10),label:d.label})),[We]),_e=e.selectedClipDuration||30,re=s.useMemo(()=>{const d=[{label:`${q}秒`,value:String(q)}];return Xt(_e,d)},[_e,q]),[xe,ne]=s.useState(e.videoStyle||""),[de,ue]=s.useState(()=>Tt(e.creativeBrief)),fe=s.useCallback((d,R)=>{b(d),se(R||null),rt(ce,d,R);const P=st(d),V=parseInt(P.defaultDuration,10)||8;De(V)},[]),Oe=s.useCallback(async d=>{const R=await le(e.id,d);i(R),o(Je(R,e.id,{...e,...d}))},[e,o,i]),he=s.useCallback((d,R)=>{const V=(e.characters||[]).map(Z=>Z.id===d?{...Z,description:R}:Z);Oe({characters:V})},[e,Oe]),je=nt("text"),[be,oe]=s.useState(()=>ye(Yt,$a).modelId),[Be,Pe]=s.useState(()=>ye(Yt,$a).modelRef),Se=s.useCallback((d,R)=>{oe(d),Pe(R||null),rt(Yt,d,R)},[]),Le=s.useRef();s.useEffect(()=>(clearTimeout(Le.current),Le.current=setTimeout(async()=>{const d=await le(e.id,{rewritePrompt:_,videoModel:J,videoModelRef:ge,segmentDuration:q,videoStyle:xe,creativeBrief:de});i(d),o(Je(d,e.id,{...e,rewritePrompt:_,videoModel:J,videoModelRef:ge,segmentDuration:q,videoStyle:xe,creativeBrief:de}))},500),()=>clearTimeout(Le.current)),[_,J,ge,q,xe,de]),s.useEffect(()=>{y(e.editedShots||[]),k(e.rewritePrompt||""),ne(e.videoStyle||""),ue(Tt(e.creativeBrief))},[e]),s.useEffect(()=>{M([])},[e.id]);const c=s.useCallback(async d=>{y(d);const R=Ke(e,d),P=await le(e.id,R);i(P),o(Je(P,e.id,{...e,...R}))},[e,o,i]),g=s.useCallback((d,R,P)=>{const V=u.map(Z=>Z.id===d?{...Z,[R]:P}:Z);c(V)},[u,c]),Y=s.useCallback(async()=>{if(!Q.current){Q.current=!0,v(!0),p(""),ze.trackUIInteraction({area:"popular_mv_tool",action:"script_rewrite_started",control:"rewrite_script",source:"mv_creator_script_page",metadata:{shotCount:u.length,hasRewritePrompt:!!_.trim(),segmentDuration:q,hasModelRef:!!Be}});try{const d=ar({record:{...e,creativeBrief:de},currentShots:u,rewritePrompt:_,videoModel:J,segmentDuration:q,videoStyle:xe}),R=Ce.createTask({prompt:d,model:be,modelRef:Be,mvCreatorAction:"rewrite",mvCreatorRecordId:e.id,knowledgeContextRefs:$},He.CHAT);z(R.id);const P=await le(e.id,{pendingRewriteTaskId:R.id});i(P),o(Je(P,e.id,{...e,pendingRewriteTaskId:R.id})),F("AI 改编中...")}catch(d){p(d.message||"提交失败")}finally{v(!1),Q.current=!1}}},[e,u,_,J,q,xe,de,be,Be,$,o,i]);s.useEffect(()=>{var P;if(!I)return;const d=Ce.getTask(I);if((d==null?void 0:d.status)==="failed"){z(null),F(""),p(((P=d.error)==null?void 0:P.message)||"改编失败"),le(e.id,{pendingRewriteTaskId:null}).then(V=>{i(V),o(Je(V,e.id,{...e,pendingRewriteTaskId:null}))});return}if((d==null?void 0:d.status)==="completed"){Zt(d).then(V=>{V?(i(V.records),o(V.record),y(V.record.editedShots||[]),ne(V.record.videoStyle||"")):p("改编任务已完成,但未找到可回填的记录")}).finally(()=>{z(null),F("")});return}typeof(d==null?void 0:d.progress)=="number"&&F(`AI 改编中 ${Math.round(d.progress)}%`);const R=Ce.observeTaskUpdates().subscribe(V=>{var Z;if(V.task.id===I){if(V.task.status==="failed"){z(null),F(""),p(((Z=V.task.error)==null?void 0:Z.message)||"改编失败"),le(e.id,{pendingRewriteTaskId:null}).then(Ie=>{i(Ie),o(Je(Ie,e.id,{...e,pendingRewriteTaskId:null}))});return}if(V.task.status==="completed"){Zt(V.task).then(Ie=>{Ie?(i(Ie.records),o(Ie.record),y(Ie.record.editedShots||[]),ne(Ie.record.videoStyle||"")):p("改编任务已完成,但未找到可回填的记录")}).catch(Ie=>{p(Ie.message||"改编结果同步失败")}).finally(()=>{z(null),F("")});return}typeof V.task.progress=="number"&&F(`AI 改编中 ${Math.round(V.task.progress)}%`)}});return()=>R.unsubscribe()},[I,e,o,i]);const ae=s.useCallback(async d=>{const R=er(e,d);if(!R)return;N(!1),y(R.editedShots);const P=await le(e.id,R);i(P),o(Je(P,e.id,{...e,...R}))},[e,o,i]);return s.useEffect(()=>{if(!T)return;const d=R=>{U.current&&!U.current.contains(R.target)&&N(!1)};return document.addEventListener("mousedown",d),()=>document.removeEventListener("mousedown",d)},[T]),t.jsxs("div",{className:"va-page",children:[t.jsxs("div",{className:"va-product-form",children:[t.jsx("textarea",{ref:mt,className:"va-form-textarea va-auto-resize",placeholder:"输入改编提示词,描述你想要的调整方向...",rows:Math.max(3,ft(_)),value:_,onChange:d=>k(d.target.value),onInput:d=>at(d.currentTarget)}),t.jsx(ea,{value:$,onChange:M,disabled:S||!!I,className:"mv-knowledge-context-selector"}),t.jsx(Ba,{value:de,onChange:ue,workflow:"mv",videoStyle:xe,onVideoStyleChange:ne}),t.jsxs("div",{className:"va-model-select",children:[t.jsx("label",{className:"va-model-label",children:"改编模型"}),t.jsx(Nt,{variant:"form",selectedModel:be,selectedSelectionKey:Ne(be,Be),onSelect:Se,models:je,placement:"down",disabled:!!I,placeholder:"选择文本模型"})]}),t.jsx(La,{selectedModel:J,selectedSelectionKey:Ne(J,ge),onSelectModel:fe,models:te,segmentDuration:q,durationOptions:ee,onSegmentDurationChange:De,disabled:!!I,placement:"down",overflowText:re.overflow>0?`实际 ${re.actualTotal}s(+${parseFloat(re.overflow.toFixed(2))}s)`:void 0}),t.jsxs("div",{className:"va-version-row",children:[t.jsx("button",{className:"va-analyze-btn",style:{flex:1},onClick:Y,disabled:S||!!I,children:S||I?W||"AI 改编中...":"AI 改编脚本"}),e.storyboardVersions&&e.storyboardVersions.length>0&&t.jsxs("div",{className:"va-version-select",ref:U,children:[t.jsxs("button",{className:"va-version-btn",onClick:()=>N(d=>!d),children:[e.activeVersionId===Mt?"原始版本":((pe=e.storyboardVersions.find(d=>d.id===e.activeVersionId))==null?void 0:pe.label)||`v${e.storyboardVersions.length}`," ▾"]}),T&&t.jsxs("div",{className:"va-version-menu",children:[e.storyboardVersions.map(d=>t.jsxs("div",{className:`va-version-item ${d.id===e.activeVersionId?"active":""}`,onClick:()=>ae(d.id),children:[t.jsx("span",{children:d.label}),d.prompt&&t.jsx("span",{className:"va-version-prompt",children:d.prompt.length>30?d.prompt.slice(0,30)+"...":d.prompt}),t.jsxs("span",{className:"va-version-time",children:[d.shots.length," 镜头 · ",new Date(d.createdAt).toLocaleTimeString()]})]},d.id)),t.jsxs("div",{className:`va-version-item ${e.activeVersionId===Mt||!e.activeVersionId?"active":""}`,onClick:()=>ae(Mt),children:[t.jsx("span",{children:"原始版本"}),t.jsxs("span",{className:"va-version-time",children:[(((we=e.storyboardVersions[e.storyboardVersions.length-1])==null?void 0:we.shots)||[]).length," 镜头"]})]})]})]})]}),L&&t.jsx("div",{className:"va-error",children:L})]}),W&&!S&&t.jsx("div",{className:"ma-progress",children:W}),t.jsx(Ss,{characters:e.characters||[],onChange:he}),t.jsx("div",{className:"va-shots",children:u.map((d,R)=>t.jsx(Qt,{shot:d,index:R,compact:!0,children:t.jsxs("div",{className:"va-edit-fields",children:[t.jsx("label",{className:"va-edit-label",children:"画面描述"}),t.jsx("textarea",{ref:mt,className:"va-edit-textarea va-auto-resize",rows:ft(d.description),value:d.description||"",onChange:P=>g(d.id,"description",P.target.value),onInput:P=>at(P.currentTarget)}),t.jsx("label",{className:"va-edit-label",children:"旁白"}),t.jsx("textarea",{ref:mt,className:"va-edit-textarea va-auto-resize",rows:ft(d.narration),value:d.narration||"",onChange:P=>g(d.id,"narration",P.target.value),onInput:P=>at(P.currentTarget)}),t.jsx("label",{className:"va-edit-label",children:"运镜方式"}),t.jsx(va,{value:d.camera_movement||"",onChange:P=>g(d.id,"camera_movement",P),options:dr,placeholder:"选择或输入运镜方式"}),t.jsx("label",{className:"va-edit-label",children:"首帧 Prompt"}),t.jsx("textarea",{ref:mt,className:"va-edit-textarea va-auto-resize",rows:ft(d.first_frame_prompt),value:d.first_frame_prompt||"",onChange:P=>g(d.id,"first_frame_prompt",P.target.value),onInput:P=>at(P.currentTarget)}),t.jsx("label",{className:"va-edit-label",children:"尾帧 Prompt"}),t.jsx("textarea",{ref:mt,className:"va-edit-textarea va-auto-resize",rows:ft(d.last_frame_prompt),value:d.last_frame_prompt||"",onChange:P=>g(d.id,"last_frame_prompt",P.target.value),onInput:P=>at(P.currentTarget)}),t.jsx("label",{className:"va-edit-label",children:"转场方式"}),t.jsx(va,{value:d.transition_hint||"",onChange:P=>g(d.id,"transition_hint",P),options:ur,placeholder:"选择转场方式"})]})},d.id))}),t.jsx("div",{className:"va-page-actions",children:t.jsx("button",{className:"va-btn-primary",onClick:m,children:"下一步:批量生成 →"})})]})};function fr(e,o,i){var u,y;const m=e.selectedClipAudioUrl||((y=(u=e.generatedClips)==null?void 0:u.find(_=>_.clipId===e.selectedClipId))==null?void 0:y.audioUrl)||null;return{recordId:e.id,fileNamePrefix:"mv",zipBaseName:"mv_assets",scriptMarkdown:Ya(e,o),recordMeta:{id:e.id,musicTitle:e.musicTitle||"",musicStyleTags:e.musicStyleTags||[],aspectRatio:e.aspectRatio||"16x9",videoStyle:e.videoStyle||"",creativeBrief:e.creativeBrief||{},creativeBriefSummary:Oa(e.creativeBrief),shotCount:o.length},shots:o,assets:i,audioAsset:m?{url:m,fallbackExtension:"mp3",downloadErrorMessage:"音乐下载失败"}:{url:"",missingErrorMessage:"缺少已选中的音乐文件"}}}function pr(e,o){return Ks(o,e.characters||[])}const jt="mv-creator:image-model",wt="mv-creator:gen-video-model";function Pa(e,o){const i=Object.keys(e),m=Object.keys(o);return i.length!==m.length?!1:i.every(u=>e[u]===o[u])}function Ea(e,o){return o.reduce((i,m)=>{var _;const u=e[m.id];return(m.valueType==="enum"?(_=m.options)==null?void 0:_.some(k=>k.value===u):typeof u=="string"&&u.trim()!=="")&&u?(i[m.id]=u,i):(m.defaultValue&&(i[m.id]=m.defaultValue),i)},{})}function Ra(e,o,i){return{...e,...o!=null?{duration:String(o)}:{},...i?{size:i}:{}}}function Va(e,o,i){const{duration:m,size:u,...y}=e;return{extraParams:y,duration:m||o,size:u||i}}function hr(e){if(!e||e==="auto")return;const o=e.trim().replace(/[xX]/g,":");return/^\d+:\d+$/.test(o)?o:void 0}const qt=({size:e=14})=>t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",width:e,height:e,"aria-hidden":"true",children:[t.jsx("rect",{x:"3",y:"3",width:"8",height:"8",rx:"1.5"}),t.jsx("circle",{cx:"17",cy:"7",r:"4"}),t.jsx("rect",{x:"3",y:"13",width:"8",height:"8",rx:"1.5"}),t.jsx("rect",{x:"13",y:"13",width:"8",height:"8",rx:"1.5"})]}),vr=({record:e,onRecordUpdate:o,onRecordsChange:i,onRestart:m})=>{const u=s.useMemo(()=>e.editedShots||[],[e.editedShots]),y=e.aspectRatio||"16x9",_=e.batchId||`mv_${e.id}`,{openDialog:k,board:$}=Is(),M=s.useRef(e),S=s.useRef(u),v=s.useRef(!1),W=s.useRef(!1),F=s.useRef(null),L=s.useRef(new Set),p=s.useRef(new Set),[I,z]=s.useState([]),[T,N]=s.useState([]),U=s.useMemo(()=>e.characters||[],[e.characters]),[Q,te]=s.useState(null),ce=nt("image"),J=nt("video"),[b,ge]=s.useState(()=>ye(jt,"").modelId),[se,We]=s.useState(()=>ye(jt,"").modelRef),[q,De]=s.useState(()=>{const a=ye(jt,"");return a.modelId?xa(a.modelId,Ne(a.modelId,a.modelRef)).extraParams:{}}),[ee,_e]=s.useState(()=>e.videoModel||ye(wt,"veo3").modelId),[re,xe]=s.useState(()=>e.videoModelRef||ye(wt,"veo3").modelRef),[ne,de]=s.useState(()=>{const a=ye(wt,e.videoModel||"veo3"),r=e.videoModel||a.modelId,n=e.videoModelRef||a.modelRef,l=ja(r,Ne(r,n));return Ra(l.extraParams,e.segmentDuration||l.duration,ga(r,e.videoSize||l.size,y))}),[ue,fe]=s.useState({running:!1,stopping:!1,currentIndex:-1,completedCount:0,retryCount:0}),[Oe,he]=s.useState(!1),je=s.useMemo(()=>Cs(b),[b]),be=s.useMemo(()=>xs(ee,re||ee,ne),[ee,re,ne]),oe=s.useMemo(()=>js(ee,re||ee,ne),[ee,re,ne]),Be=s.useMemo(()=>oe.sizeOptions,[oe]),Pe=s.useMemo(()=>Va(ne,oe.defaultDuration,oe.defaultSize),[oe.defaultDuration,oe.defaultSize,ne]),Se=Pe.size,Le=Number.parseFloat(Pe.duration)||8,c=s.useMemo(()=>Object.keys(q).length>0?q:void 0,[q]);s.useEffect(()=>{M.current=e},[e]),s.useEffect(()=>{N([])},[e.id]),s.useEffect(()=>{S.current=u},[u]);const g=s.useCallback(async a=>{const r=M.current,n={...r,...a};M.current=n,n.editedShots&&(S.current=n.editedShots);const l=await le(r.id,a);return i(l),o(n),n},[o,i]),Y=s.useCallback(async a=>{const r=M.current,n=Ke(r,a);return S.current=a,await g(n),a},[g]),ae=s.useCallback((a,r)=>{const n=r||null;ge(a),We(n),De(xa(a,Ne(a,n)).extraParams),rt(jt,a,r)},[]),pe=s.useCallback((a,r)=>{const n=r||null;_e(a),xe(n),rt(wt,a,r);const l=ja(a,Ne(a,n));de(Ra(l.extraParams,l.duration,ga(a,l.size,y)))},[y]),we=s.useCallback((a,r)=>{De(n=>{const l={...n};return!r||r==="default"?delete l[a]:l[a]=r,l})},[]),d=s.useCallback((a,r)=>{de(n=>{const l={...n};return!r||r==="default"?delete l[a]:l[a]=r,l})},[]);s.useEffect(()=>{const a=Ea(q,je);Pa(q,a)||De(a)},[je,q]),s.useEffect(()=>{const a=Ea(ne,be);Pa(ne,a)||de(a)},[be,ne]),s.useEffect(()=>{const a=Va(ne,oe.defaultDuration,oe.defaultSize);zs({currentModel:ee,currentSelectionKey:Ne(ee,re),extraParams:a.extraParams,duration:a.duration,size:a.size}),g({videoModel:ee,videoModelRef:re||null,segmentDuration:Number.parseFloat(a.duration)||8,videoSize:a.size})},[g,ee,oe.defaultDuration,oe.defaultSize,re,ne]);const R=s.useMemo(()=>I.map(a=>a.url).filter(Boolean),[I]),P=s.useMemo(()=>Hs(u),[u]),V=s.useMemo(()=>{var a;return{totalDuration:e.selectedClipDuration||30,productExposureDuration:0,productExposureRatio:0,shotCount:u.length,firstProductAppearance:0,aspect_ratio:y,video_style:e.videoStyle||"",bgm_mood:((a=e.musicStyleTags)==null?void 0:a.filter(Boolean).join(", "))||"",suggestion:"",shots:u}},[e,u,y]),Z=s.useMemo(()=>{var a,r,n;return{generationTopic:e.musicTitle||e.sourceLabel||"",videoStyle:e.videoStyle||"",bgmMood:((a=e.musicStyleTags)==null?void 0:a.filter(Boolean).join(", "))||"",creativeBrief:e.creativeBrief,generationContext:[e.musicTitle?`音乐标题:${e.musicTitle}`:"",(r=e.musicStyleTags)!=null&&r.length?`音乐风格:${e.musicStyleTags.join(", ")}`:"",e.selectedClipDuration?`音乐时长:${e.selectedClipDuration}秒`:"",(n=e.musicLyrics)!=null&&n.trim()?`歌词/意象:${e.musicLyrics.trim()}`:""].filter(Boolean).join(`
163
- `)}},[e]),Ie=s.useCallback(async(a,r)=>{const l=(M.current.characters||[]).map(f=>f.id===a?{...f,referenceImageUrl:r}:f);await g({characters:l})},[g]),qa=s.useCallback(async()=>{try{const a=M.current,r=S.current;Ia($);const n=await Ca("text",Ya(a,r));if(!n.success)throw new Error(n.error||"插入失败,请确认画布已打开");ze.trackUIInteraction({area:"popular_mv_tool",action:"script_inserted_to_canvas",control:"insert_script",source:"mv_creator_generate_page",metadata:{shotCount:r.length}}),et.success("脚本已插入画布")}catch(a){console.error("[MVCreator] Failed to insert script to canvas:",a);const r=a instanceof Error?a.message:"脚本插入画布失败";et.error(r)}},[$]),Pt=s.useCallback(async a=>{if(!$)return!1;try{Ia($);const r=await Ca("video",a);if(!r.success)throw new Error(r.error||"插入失败,请确认画布已打开");return!0}catch(r){return console.error("[MVCreator] Failed to insert generated video to canvas:",r),!1}},[$]),{isExportingAssets:aa,exportProgress:Ja,handleExportAssets:Za}=ws({onExport:async a=>{const r=M.current,n=S.current;return await qs({...fr(r,n,P),onProgress:a})},onExportSuccess:a=>{et.success(`素材导出完成,共 ${a.assetCount} 个文件`)},onExportError:a=>{console.error("[MVCreator] Failed to export mv assets:",a),et.error("素材导出失败")}}),Xa=s.useCallback(a=>{const r=`mv_${e.id}_char${a.id}_ref`,n=_a(a,V,Z);k(Ct.aiImageGeneration,{initialPrompt:n,initialKnowledgeContextRefs:T,batchId:r,initialAspectRatio:"1:1",initialModel:b||void 0,initialModelRef:se,autoInsertToCanvas:!1,assetMetadata:{category:Ft.CHARACTER,characterName:a.name,characterPrompt:n}})},[e.id,V,Z,T,k,b,se]),sa=s.useCallback(async()=>{e.batchId||await g({batchId:_})},[e.batchId,_,g]),{tasks:ra}=Ga(),Ue=s.useRef(new Set),Et=s.useRef(new Set),na=s.useCallback(async(a,r,n)=>{let l=[...r],f=!1;for(const{shotId:h,videoUrl:x}of n){const A=`auto_${h}`;if(!Et.current.has(A)){Et.current.add(A);try{const D=l.findIndex(B=>B.id===h);if(D===-1)continue;const C=D>0?l[D-1]:void 0;if(C&&!C.generated_last_frame_url&&!C.generated_video_url){const B=await wa(x,C.id,"last","first");B&&(l=l.map(O=>O.id===C.id?{...O,generated_last_frame_url:B}:O),f=!0)}}finally{Et.current.delete(A)}}}if(f){const h=e;le(a,Ke(h,l)).then(x=>{i(x),o({...h,editedShots:l})})}},[e,o,i]);s.useEffect(()=>{var A,D,C,B;const a=`mv_${e.id}_shot`,r=`mv_${e.id}_char`;let n=!1;const l=e,f=M.current.generatedAssetsResetAt||l.generatedAssetsResetAt;let h=l.editedShots||[];const x=[];for(const O of ra){if(O.status!==$e.COMPLETED||Ue.current.has(O.id))continue;const ie=(A=O.params)==null?void 0:A.batchId;if(!ie)continue;if(ie.startsWith(r)){if(f&&O.createdAt<=f){Ue.current.add(O.id);continue}const me=(D=O.result)==null?void 0:D.url;if(Ue.current.add(O.id),me){const Te=ie.slice(r.length),Ae=Te.lastIndexOf("_ref");if(Ae!==-1){const ve=Te.slice(0,Ae),Ve=(M.current.characters||[]).map(Ye=>Ye.id===ve?{...Ye,referenceImageUrl:me}:Ye);g({characters:Ve})}}continue}if(!ie.startsWith(a))continue;if(f&&O.createdAt<=f){Ue.current.add(O.id);continue}if(e.storyboardGeneratedAt&&O.createdAt<e.storyboardGeneratedAt){Ue.current.add(O.id);continue}const ke=(C=O.result)==null?void 0:C.url;if(!ke)continue;const E=ie.slice(a.length),j=E.lastIndexOf("_");if(j===-1)continue;const w=E.slice(0,j),G=E.slice(j+1);if(G!=="first"&&G!=="last"&&G!=="video")continue;const X=G==="first"?"generated_first_frame_url":G==="last"?"generated_last_frame_url":"generated_video_url",K=h.find(me=>me.id===w),H=G==="video"&&p.current.has(O.id),Me=(B=K==null?void 0:K.suppressed_generated_urls)==null?void 0:B[G];if(Me&&Me===ke){H&&p.current.delete(O.id),Ue.current.add(O.id);continue}if(!K||K[X]===ke){H&&p.current.delete(O.id),Ue.current.add(O.id);continue}h=h.map(me=>me.id===w?{...me,[X]:ke,suppressed_generated_urls:me.suppressed_generated_urls?{...me.suppressed_generated_urls,[G]:void 0}:void 0}:me),Ue.current.add(O.id),n=!0,G==="video"&&(H?p.current.delete(O.id):x.push({shotId:w,videoUrl:ke}))}n&&le(l.id,Ke(l,h)).then(O=>{i(O),o({...l,editedShots:h})}),x.length>0&&na(l.id,h,x)},[ra,na,e,o,i,g]);const[Ee,ot]=s.useState(null),Qa=s.useCallback(async a=>{if(!Ee)return;ot(null);const{shotId:r,assetType:n}=Ee,l=n==="first"?"generated_first_frame_url":n==="last"?"generated_last_frame_url":"generated_video_url",f=u.map(x=>x.id===r?{...x,[l]:a.url}:x),h=await le(e.id,Ke(e,f));i(h),o({...e,editedShots:f})},[Ee,e,u,i,o]),[Ze,Rt]=s.useState(null),it=s.useRef(null),Re=s.useCallback(()=>{it.current!==null&&(window.clearTimeout(it.current),it.current=null)},[]),oa=s.useCallback(()=>{Re(),Rt(null)},[Re]),ia=s.useCallback(()=>{Re(),it.current=window.setTimeout(()=>{it.current=null,Rt(null)},120)},[Re]),pt=s.useCallback((a,r,n)=>{Re();const l=n.currentTarget.getBoundingClientRect();Rt({url:a,type:r,x:l.left+l.width/2,y:l.top-8})},[Re]),ht=s.useCallback(()=>{ia()},[ia]),es=s.useCallback(()=>{Re()},[Re]),ts=s.useCallback(()=>{oa()},[oa]);s.useEffect(()=>()=>{Re()},[Re]);const lt=s.useMemo(()=>{var r;const a=(r=Be.find(n=>n.value===Se))==null?void 0:r.aspectRatio;if(a)return a;if(Se!=null&&Se.includes("x")){const[n,l]=Se.split("x").map(Number);if(n&&l){const f=(x,A)=>A===0?x:f(A,x%A),h=f(n,l);return`${n/h}:${l/h}`}}return y.replace("x",":")},[y,Be,Se]),Vt=lt,Xe=hr(q.size),vt=q.size||Vt;s.useEffect(()=>{b&&Us({currentModel:b,currentSelectionKey:Ne(b,se),extraParams:q,aspectRatio:Xe||Vt})},[Vt,b,se,q,Xe]);const Ge=s.useCallback(a=>a.map(r=>({url:r.url,name:r.name})),[]),gt=s.useCallback((a=[],r=[])=>a.length===r.length&&a.every((n,l)=>{var f,h;return n.url===((f=r[l])==null?void 0:f.url)&&n.name===((h=r[l])==null?void 0:h.name)}),[]),_t=s.useCallback((...a)=>{const r=new Set,n=[];return a.forEach(l=>{l==null||l.forEach(f=>{var x;const h=(x=f.url)==null?void 0:x.trim();!h||r.has(h)||(r.add(h),n.push({url:h,name:f.name||"参考图"}))})}),n.length>0?n:void 0},[]),bt=s.useCallback(a=>{var n;if(!((n=a.character_ids)!=null&&n.length))return[];const r=new Set;return a.character_ids.reduce((l,f)=>{var A;const h=U.find(D=>D.id===f),x=(A=h==null?void 0:h.referenceImageUrl)==null?void 0:A.trim();return!x||r.has(x)||(r.add(x),l.push({url:x,name:h!=null&&h.name?`角色:${h.name}`:"角色参考图"})),l},[])},[U]),Qe=s.useCallback(async(a,r,n)=>{let l=!1;const f=Ge(n.images),h=S.current.map(x=>{if(x.id!==a)return x;if(r==="first"){const C=x.first_frame_draft,B={prompt:n.prompt,images:f,aspectRatio:n.aspectRatio};return(C==null?void 0:C.prompt)===B.prompt&&(C==null?void 0:C.aspectRatio)===B.aspectRatio&&gt(C==null?void 0:C.images,B.images)?x:(l=!0,{...x,first_frame_draft:B})}if(r==="last"){const C=x.last_frame_draft,B={prompt:n.prompt,images:f,aspectRatio:n.aspectRatio};return(C==null?void 0:C.prompt)===B.prompt&&(C==null?void 0:C.aspectRatio)===B.aspectRatio&&gt(C==null?void 0:C.images,B.images)?x:(l=!0,{...x,last_frame_draft:B})}const A=x.video_draft,D={prompt:n.prompt,images:f,duration:n.duration,size:n.size};return(A==null?void 0:A.prompt)===D.prompt&&(A==null?void 0:A.duration)===D.duration&&(A==null?void 0:A.size)===D.size&&gt(A==null?void 0:A.images,D.images)?x:(l=!0,{...x,video_draft:D})});l&&await Y(h)},[Y,gt,Ge]),Dt=s.useCallback(a=>{const r=a.first_frame_prompt||a.description||"";if(!r)return;ze.trackUIInteraction({area:"popular_mv_tool",action:"shot_first_frame_generation_opened",control:"generate_first_frame",source:"mv_creator_generate_page",metadata:{shotId:a.id,hasDraft:!!a.first_frame_draft}});const n=zt(r,V,Z,{shot:a,characters:U}),l=a.first_frame_draft,f=l?Ge(l.images||[]):void 0,h=!l&&a.generated_first_frame_url?[{url:a.generated_first_frame_url,name:"首帧"}]:void 0,x=bt(a),A=`mv_${e.id}_shot${a.id}_first`;k(Ct.aiImageGeneration,{initialPrompt:(l==null?void 0:l.prompt)||n,initialKnowledgeContextRefs:T,batchId:A,initialAspectRatio:(l==null?void 0:l.aspectRatio)??Xe,initialModel:b||void 0,initialModelRef:se,autoInsertToCanvas:!1,initialImages:_t(f,h,x),onDraftChange:D=>Qe(a.id,"first",D)})},[e.id,V,Z,U,T,k,b,se,_t,bt,Qe,Xe,Ge]),ct=s.useCallback((a,r)=>{var n;return a.generated_last_frame_url?a.generated_last_frame_url:(n=u[r+1])==null?void 0:n.generated_first_frame_url},[u]),yt=s.useCallback((a,r)=>{const n=a.last_frame_prompt||"";if(!n)return;ze.trackUIInteraction({area:"popular_mv_tool",action:"shot_last_frame_generation_opened",control:"generate_last_frame",source:"mv_creator_generate_page",metadata:{shotId:a.id,shotIndex:r,hasDraft:!!a.last_frame_draft}});const l=zt(n,V,Z,{shot:a,characters:U}),f=a.last_frame_draft,h=f?Ge(f.images||[]):void 0,x=`mv_${e.id}_shot${a.id}_last`,A=ct(a,r),D=!f&&A?[{url:A,name:"尾帧"}]:void 0,C=bt(a);k(Ct.aiImageGeneration,{initialPrompt:(f==null?void 0:f.prompt)||l,initialKnowledgeContextRefs:T,batchId:x,initialAspectRatio:(f==null?void 0:f.aspectRatio)??Xe,initialModel:b||void 0,initialModelRef:se,autoInsertToCanvas:!1,initialImages:_t(h,D,C),onDraftChange:B=>Qe(a.id,"last",B)})},[e.id,V,Z,U,T,k,ct,b,se,_t,bt,Qe,Xe,Ge]),Ot=s.useCallback(async(a,r)=>{ze.trackUIInteraction({area:"popular_mv_tool",action:"shot_video_generation_opened",control:"generate_shot_video",source:"mv_creator_generate_page",metadata:{shotId:a.id,shotIndex:r,hasDraft:!!a.video_draft}});const n=a.video_draft,l=`mv_${e.id}_shot${a.id}_video`,f=[];a.generated_first_frame_url&&f.push({url:a.generated_first_frame_url,name:"首帧"});const h=ct(a,r);h&&f.push({url:h,name:"尾帧"});const x=Ge((n==null?void 0:n.images)||[]),A=x.length>0?x:f.length>0?f:void 0,D=ba(a,V,Z,{referenceImageDescriptions:ks(A)});if(!D)return;const C=String((n==null?void 0:n.duration)??Le),B=oe.durationOptions.some(ie=>ie.value===C)?(n==null?void 0:n.duration)??Le:void 0,O=oe.sizeOptions.some(ie=>ie.value===((n==null?void 0:n.size)??Se))?(n==null?void 0:n.size)??Se:void 0;k(Ct.aiVideoGeneration,{initialPrompt:(n==null?void 0:n.prompt)||D,initialKnowledgeContextRefs:T,initialImages:A,initialDuration:B,initialSize:O,initialModel:ee||void 0,initialModelRef:re,batchId:l,autoInsertToCanvas:!1,onDraftChange:ie=>Qe(a.id,"video",ie)})},[e.id,V,Z,T,Le,Se,ee,oe,re,k,ct,Qe,Ge]),Bt=s.useCallback((a,r)=>{const n=r==="first"?"generated_first_frame_url":r==="last"?"generated_last_frame_url":"generated_video_url",l=u.map(f=>f.id===a?{...f,[n]:void 0,suppressed_generated_urls:f[n]?{...f.suppressed_generated_urls||{},[r]:f[n]}:f.suppressed_generated_urls}:f);le(e.id,Ke(e,l)).then(f=>{i(f),o({...e,editedShots:l})})},[e,u,o,i]),la=s.useCallback(async(a,r,n)=>{if(!a.generated_video_url)return;const l=n==="next-first"?u[r+1]:u[r-1];if(!l)return;const f=n==="next-first"?"first":"last",h=n==="next-first"?"last":"first",x=await wa(a.generated_video_url,l.id,f,h);if(!x)return;const A=f==="first"?"generated_first_frame_url":"generated_last_frame_url",D=u.map(C=>C.id===l.id?{...C,[A]:x}:C);le(e.id,Ke(e,D)).then(C=>{i(C),o({...e,editedShots:D})})},[e,u,o,i]),ca=s.useCallback(async(a,r,n)=>{const l=a[r];if(!l||l.generated_video_url===n)return S.current;const f=S.current.map(h=>h.id===l.id?{...h,generated_video_url:n}:h);return await Y(f),f},[Y]),da=s.useCallback(async(a,r)=>{const n=S.current,l=n.find(h=>h.id===a);if(!l||l.generated_first_frame_url===r)return n;const f=n.map(h=>h.id===a?{...h,generated_first_frame_url:r}:h);return await Y(f),f},[Y]),ua=s.useCallback(async(a,r)=>{const n=S.current,l=n.find(h=>h.id===a);if(!l||l.generated_last_frame_url===r)return n;const f=n.map(h=>h.id===a?{...h,generated_last_frame_url:r}:h);return await Y(f),f},[Y]),St=s.useCallback(async(a,r,n)=>{var O,ie,ke;const l=n==="first"?a.first_frame_prompt||a.description||"":a.last_frame_prompt||"";if(!l)return null;const f=zt(l,V,Z,{shot:a,characters:r}),h=[...R];if(a.character_ids&&a.character_ids.length>0)for(const E of a.character_ids){const j=r.find(w=>w.id===E);j!=null&&j.referenceImageUrl&&!h.includes(j.referenceImageUrl)&&h.push(j.referenceImageUrl)}const x=`mv_${e.id}_shot${a.id}_${n}`,A=await Gt.executeTool({name:"generate_image",arguments:{prompt:f.trim(),count:1,size:vt,referenceImages:h.length>0?h:void 0,knowledgeContextRefs:T,batchId:x,autoInsertToCanvas:!1,...b?{model:b,modelRef:se}:{},...c?{params:c}:{}}},{mode:"queue"}),D=A.taskId||((O=A.data)==null?void 0:O.taskId);if(!A.success||!D)return null;L.current.add(D);let C=null;try{C=await Kt(D,(ie=F.current)==null?void 0:ie.signal)}finally{L.current.delete(D)}if(!(C!=null&&C.success))return null;const B=C.task||Ce.getTask(D);return((ke=B==null?void 0:B.result)==null?void 0:ke.url)||null},[e.id,V,Z,T,c,vt,b,se,R]),ma=s.useCallback((a,r)=>St(a,r,"first"),[St]),fa=s.useCallback((a,r)=>St(a,r,"last"),[St]),pa=s.useCallback(async(a,r,n,l,f)=>{var G;const h=n.find(X=>X.id===a.id)||n[r]||a,x=h.generated_first_frame_url,A=f||h.generated_last_frame_url,D=(h.character_ids||[]).map(X=>{var K;return(K=l.find(H=>H.id===X))==null?void 0:K.referenceImageUrl}).filter(X=>!!X),C=Array.from(new Set([...R])),{referenceImages:B,referenceImageDescriptions:O}=Ws({model:ee,firstFrameUrl:x,lastFrameUrl:A,extraReferenceUrls:C,characterReferenceUrls:D}),ie=ba(h,V,Z,{referenceImageDescriptions:O});if(!ie)return null;const ke=`mv_${e.id}_shot${a.id}_video`,E={...Pe.extraParams,...oe.provider==="seedance"?{aspect_ratio:lt}:{}},j=await Gt.executeTool({name:"generate_video",arguments:{prompt:ie,size:Pe.size,seconds:Pe.duration,count:1,batchId:ke,model:ee,modelRef:re,referenceImages:B,knowledgeContextRefs:T,autoInsertToCanvas:!1,params:Object.keys(E).length>0?E:void 0}},{mode:"queue"}),w=j.taskId||((G=j.data)==null?void 0:G.taskId);if(!j.success||!w)throw new Error(j.error||"创建视频任务失败");return w},[V,Z,R,e.id,T,Pe,ee,oe.provider,re,lt]),as=s.useCallback(()=>{var a;v.current=!0,fe(r=>r.running?{...r,stopping:!0}:r);for(const r of L.current)Ce.cancelTask(r);L.current.clear(),(a=F.current)==null||a.abort()},[]);s.useEffect(()=>()=>{var a;v.current=!0,(a=F.current)==null||a.abort()},[]);const ss=s.useCallback(async()=>{var r,n,l;if(W.current||ue.running)return;W.current=!0,ze.trackUIInteraction({area:"popular_mv_tool",action:"batch_video_generation_started",control:"generate_all_videos",source:"mv_creator_generate_page",metadata:{shotCount:S.current.length,charactersCount:((r=M.current.characters)==null?void 0:r.length)||0,insertToCanvasRequested:Oe,hasBoard:!!$}});let a=Oe;a&&!$&&(et.warning("画布未就绪,本次将只生成不插入画布"),a=!1),await sa(),v.current=!1,F.current=new AbortController,L.current.clear(),fe({running:!0,stopping:!1,currentIndex:-1,completedCount:0,retryCount:0});try{const h=(M.current.characters||[]).filter(E=>!E.referenceImageUrl);if(h.length>0&&!v.current){const j=(await Promise.all(h.map(async w=>{var K,H,Me;if(v.current)return null;const G=`mv_${e.id}_char${w.id}_ref`,X=_a(w,V,Z);try{const me=await Gt.executeTool({name:"generate_image",arguments:{prompt:X,count:1,size:vt,knowledgeContextRefs:T,batchId:G,autoInsertToCanvas:!1,assetMetadata:{category:Ft.CHARACTER,characterName:w.name,characterPrompt:X},...b?{model:b,modelRef:se}:{},...c?{params:c}:{}}},{mode:"queue"}),Te=me.taskId||((K=me.data)==null?void 0:K.taskId);if(!Te)return null;L.current.add(Te);let Ae=null;try{if(v.current)return Ce.cancelTask(Te),null;Ae=await Kt(Te,(H=F.current)==null?void 0:H.signal)}finally{L.current.delete(Te)}if(!(Ae!=null&&Ae.success))return null;const ve=Ae.task||Ce.getTask(Te),Fe=(Me=ve==null?void 0:ve.result)==null?void 0:Me.url;return Fe?{charId:w.id,url:Fe}:null}catch(me){return v.current||console.error("[MVCreator] Character reference generation failed:",{characterId:w.id,error:me}),null}}))).filter(w=>!!(w!=null&&w.url));if(j.length>0){const w=new Map(j.map(K=>[K.charId,K.url])),X=(M.current.characters||[]).map(K=>{const H=w.get(K.id);return H?{...K,referenceImageUrl:H}:K});await g({characters:X})}}let x=0;const A=new Set,D=(E,j=0)=>{A.has(E)||(A.add(E),x+=1,fe(w=>({...w,currentIndex:E,completedCount:x,retryCount:j})))},C=S.current,B=new Map,O=E=>{var X;const j=S.current.find(K=>K.id===E.id)||E;if(j.generated_first_frame_url)return Promise.resolve(j.generated_first_frame_url);const w=(X=B.get(E.id))==null?void 0:X.first;if(w)return w;const G=(async()=>{const K=M.current.characters||[],H=await ma(j,K);return H&&!v.current&&await da(j.id,H),H})();return B.set(E.id,{...B.get(E.id)||{},first:G}),G},ie=E=>{var X,K;const j=S.current.find(H=>H.id===E.id)||E;if(j.generated_last_frame_url)return Promise.resolve(j.generated_last_frame_url);if(!((X=j.last_frame_prompt)!=null&&X.trim()))return Promise.resolve(null);const w=(K=B.get(E.id))==null?void 0:K.last;if(w)return w;const G=(async()=>{const H=M.current.characters||[],Me=await fa(j,H);return Me&&!v.current&&await ua(j.id,Me),Me})();return B.set(E.id,{...B.get(E.id)||{},last:G}),G};for(let E=0;E<C.length;E+=1){const j=C[E],w=C[E+1];O(j).catch(G=>(v.current||console.error("[MVCreator] Batch first frame generation failed:",{shotId:j.id,error:G}),null)),w&&!j.generated_last_frame_url&&!((n=j.last_frame_prompt)!=null&&n.trim())?O(w).catch(G=>(v.current||console.error("[MVCreator] Batch next first frame generation failed:",{shotId:w.id,error:G}),null)):(l=j.last_frame_prompt)!=null&&l.trim()&&ie(j).catch(G=>(v.current||console.error("[MVCreator] Batch last frame generation failed:",{shotId:j.id,error:G}),null))}const ke=async(E,j)=>{var Me,me,Te,Ae;if(v.current)return;let w=S.current.find(ve=>ve.id===E.id)||E;if(fe(ve=>({...ve,currentIndex:j,retryCount:0})),w.generated_video_url){a&&await Pt(w.generated_video_url),D(j);return}const G=await O(w);if(G&&(w={...w,generated_first_frame_url:G}),w=S.current.find(ve=>ve.id===w.id)||w,!w.generated_first_frame_url){D(j);return}let X=w.generated_last_frame_url;if(!X)if((Me=w.last_frame_prompt)!=null&&Me.trim())X=await ie(w)||void 0;else{const ve=C[j+1];X=ve&&await O(ve)||void 0}if(v.current)return;let K=0,H=null;for(;!v.current;){if(!H){const qe=S.current,Lt=M.current.characters||[];H=await pa(qe.find(dt=>dt.id===w.id)||w,j,qe,Lt,X)}if(!H)break;p.current.add(H),L.current.add(H);const ve=K;fe(qe=>({...qe,currentIndex:j,retryCount:ve}));let Fe=null;try{Fe=await Kt(H,(me=F.current)==null?void 0:me.signal)}finally{L.current.delete(H)}if(v.current||!Fe)break;const Ve=Fe.task||Ce.getTask(H),Ye=(Te=Ve==null?void 0:Ve.result)==null?void 0:Te.url;if(Fe.success&&Ve&&Ye){await ca(S.current,j,Ye),a&&await Pt(Ye),D(j,K);break}if((Ve==null?void 0:Ve.status)===$e.FAILED){const qe=Ys(Ve,Fe.error);if(qe){v.current=!0;for(const dt of L.current)Ce.cancelTask(dt);L.current.clear(),(Ae=F.current)==null||Ae.abort(),et.error(`视频生成失败且不可重试,已停止:${qe}`);break}K+=1;const Lt=K;fe(dt=>({...dt,currentIndex:j,retryCount:Lt})),Ce.retryTask(H);continue}H=null}};await Promise.allSettled(C.map((E,j)=>ke(E,j).catch(w=>{v.current||console.error("[MVCreator] Batch shot pipeline failed:",{shotId:E.id,error:w})}).finally(()=>D(j))))}finally{W.current=!1,L.current.clear(),F.current=null,fe({running:!1,stopping:!1,currentIndex:-1,completedCount:0,retryCount:0})}},[ue.running,pa,sa,ma,fa,V,Z,Y,g,e.id,T,b,c,vt,se,Pt,Oe,da,ua,ca,$]),rs=s.useCallback(async()=>{const a=pr(M.current,S.current);await g({...Ke(M.current,a.shots),characters:a.characters,generatedAssetsResetAt:Date.now()})},[g]),It=s.useMemo(()=>{const[a,r]=lt.split(":").map(Number);if(!a||!r)return{};const n=Math.round(54*a/r);return{width:Math.max(n,48),height:n<48?Math.round(48*r/a):54}},[lt]);return t.jsxs("div",{className:"va-page",children:[t.jsxs("div",{className:"va-batch-config",children:[t.jsx("div",{className:"va-batch-config-title",children:"批量生成配置"}),t.jsx(Gs,{images:I,onImagesChange:z,multiple:!0,label:"参考图 (可选)"}),t.jsx(ea,{value:T,onChange:N,disabled:ue.running,className:"mv-knowledge-context-selector"}),U.length>0&&t.jsxs("div",{className:"va-characters",children:[t.jsx("div",{className:"va-characters-title",children:"角色"}),U.map(a=>t.jsxs("div",{className:"va-character-item",children:[t.jsxs("div",{className:"va-character-info",children:[t.jsx("span",{className:"va-character-name",children:a.name}),t.jsx("span",{className:"va-character-desc",children:a.description})]}),t.jsxs("div",{className:"va-character-ref",children:[a.referenceImageUrl?t.jsxs("div",{className:"va-character-ref-thumb",children:[t.jsx(ut,{src:a.referenceImageUrl,alt:a.name,showSkeleton:!1,eager:!0}),t.jsx("button",{className:"va-shot-frame-delete",onClick:()=>void Ie(a.id,void 0),children:"×"})]}):t.jsx("span",{className:"va-character-ref-empty",children:"未设置"}),t.jsx("button",{onClick:()=>Xa(a),children:"生成"}),t.jsx("button",{onClick:()=>te(a.id),children:"选主体"})]})]},a.id))]}),t.jsxs("div",{className:"va-product-form",children:[t.jsxs("div",{className:"va-model-select",children:[t.jsx("label",{className:"va-model-label",children:"图片模型"}),t.jsx(Nt,{variant:"form",selectedModel:b,selectedSelectionKey:Ne(b,se),onSelect:ae,models:ce,placement:"down",placeholder:"选择图片模型"}),je.length>0&&t.jsx(ka,{selectedParams:q,onParamChange:we,compatibleParams:je,modelId:b,placement:"down"})]}),t.jsxs("div",{className:"va-model-select",children:[t.jsx("label",{className:"va-model-label",children:"视频模型"}),t.jsx(Nt,{variant:"form",selectedModel:ee,selectedSelectionKey:Ne(ee,re),onSelect:pe,models:J,placement:"down",placeholder:"选择视频模型"}),be.length>0&&t.jsx(ka,{selectedParams:ne,onParamChange:d,compatibleParams:be,modelId:ee,placement:"down"})]})]}),ue.running&&t.jsxs("div",{className:"va-batch-config-title",children:["正在并行生成,已完成 ",ue.completedCount,"/",u.length," 段",ue.retryCount>0?`,已重试 ${ue.retryCount} 次`:""]}),t.jsxs("div",{className:"va-page-actions",children:[m&&t.jsx("button",{onClick:m,children:"重新开始"}),t.jsx("button",{onClick:rs,children:"重置生成"}),t.jsxs("label",{className:"va-inline-checkbox",children:[t.jsx("input",{type:"checkbox",checked:Oe,onChange:a=>he(a.target.checked)}),"生成后插入画布"]}),t.jsx("button",{onClick:ss,disabled:ue.running,children:"全部→生成视频"}),ue.running&&t.jsx("button",{onClick:as,children:ue.stopping?"停止中…":"停止全部生成"})]})]}),t.jsx("div",{className:"va-shots",children:u.map((a,r)=>t.jsx(Qt,{shot:a,index:r,actions:t.jsxs(t.Fragment,{children:[a.generated_first_frame_url?t.jsxs("div",{className:"va-shot-frame-thumb",style:It,onMouseEnter:n=>pt(a.generated_first_frame_url,"image",n),onMouseLeave:ht,children:[t.jsx(ut,{src:a.generated_first_frame_url,alt:"首帧",showSkeleton:!1,eager:!0,onClick:()=>Dt(a)}),t.jsx("button",{className:"va-shot-frame-delete",onClick:()=>Bt(a.id,"first"),children:"×"}),t.jsx("button",{className:"va-shot-frame-regen",onClick:()=>Dt(a),children:"↻"})]}):a.first_frame_prompt||a.description?t.jsxs("span",{className:"va-shot-frame-btn-group",children:[t.jsx("button",{onClick:()=>Dt(a),children:"生成首帧"}),t.jsx(tt,{content:"从素材库选择",showArrow:!1,children:t.jsx("button",{className:"va-shot-frame-library-btn",onClick:()=>ot({shotId:a.id,assetType:"first"}),children:t.jsx(qt,{})})})]}):null,(()=>{var l;const n=ct(a,r);return a.generated_last_frame_url?t.jsxs("div",{className:"va-shot-frame-thumb",style:It,onMouseEnter:f=>pt(a.generated_last_frame_url,"image",f),onMouseLeave:ht,children:[t.jsx(ut,{src:a.generated_last_frame_url,alt:"尾帧",showSkeleton:!1,eager:!0,onClick:()=>yt(a,r)}),t.jsx("button",{className:"va-shot-frame-delete",onClick:()=>Bt(a.id,"last"),children:"×"}),t.jsx("button",{className:"va-shot-frame-regen",onClick:()=>yt(a,r),children:"↻"})]}):!a.generated_last_frame_url&&n?t.jsxs("div",{className:"va-shot-frame-thumb va-shot-frame-thumb--borrowed",style:It,onMouseEnter:f=>pt(n,"image",f),onMouseLeave:ht,children:[t.jsx(ut,{src:n,alt:"尾帧(下一镜头首帧)",showSkeleton:!1,eager:!0,onClick:()=>yt(a,r)}),t.jsx("span",{className:"va-shot-frame-label",children:"下一镜头首帧"})]}):(l=a.last_frame_prompt)!=null&&l.trim()?t.jsxs("span",{className:"va-shot-frame-btn-group",children:[t.jsx("button",{onClick:()=>yt(a,r),children:"生成尾帧"}),t.jsx(tt,{content:"从素材库选择",showArrow:!1,children:t.jsx("button",{className:"va-shot-frame-library-btn",onClick:()=>ot({shotId:a.id,assetType:"last"}),children:t.jsx(qt,{})})})]}):null})(),a.generated_video_url?t.jsxs("div",{className:"va-shot-video-wrap",children:[t.jsxs("div",{className:"va-shot-frame-thumb",style:It,onMouseEnter:n=>pt(a.generated_video_url,"video",n),onMouseLeave:ht,children:[t.jsx(Fs,{src:a.generated_video_url,alt:"生成视频缩略图",className:"va-shot-frame-media",thumbnailSize:"small",onClick:()=>Ot(a,r),videoProps:{muted:!0,preload:"metadata",title:"重新生成视频"}}),t.jsx("button",{className:"va-shot-frame-delete",onClick:()=>Bt(a.id,"video"),children:"×"}),t.jsx("button",{className:"va-shot-frame-regen",onClick:()=>Ot(a,r),children:"↻"})]}),(r>0||r<u.length-1)&&t.jsxs("div",{className:"va-shot-frame-transfer",children:[r>0&&t.jsx(tt,{content:"提取首帧 → 前一片段尾帧",showArrow:!1,children:t.jsx("button",{className:"va-shot-frame-transfer-btn",onClick:()=>la(a,r,"prev-last"),children:t.jsx(Ts,{size:12})})}),r<u.length-1&&t.jsx(tt,{content:"提取尾帧 → 后一片段首帧",showArrow:!1,children:t.jsx("button",{className:"va-shot-frame-transfer-btn",onClick:()=>la(a,r,"next-first"),children:t.jsx(Ns,{size:12})})})]})]}):a.description?t.jsxs("span",{className:"va-shot-frame-btn-group",children:[t.jsx("button",{onClick:()=>Ot(a,r),children:"生成视频"}),t.jsx(tt,{content:"从素材库插入视频",showArrow:!1,children:t.jsx("button",{className:"va-shot-frame-library-btn",onClick:()=>ot({shotId:a.id,assetType:"video"}),children:t.jsx(qt,{})})})]}):null]})},a.id))}),t.jsxs("div",{className:"va-page-actions mv-generate-footer-actions",children:[t.jsx("button",{onClick:()=>void qa(),disabled:u.length===0,children:"脚本插入画布"}),t.jsx("button",{onClick:()=>void Za(),disabled:aa||u.length===0,children:aa?`素材下载 ${Ja}%`:"素材下载 ZIP"})]}),t.jsx("div",{className:"mv-generate-footer-hint",children:"若有素材未打包成功,解压后在 ZIP 根目录运行 `sh 00.补全下载.sh` 即可按 manifest 补全下载。"}),t.jsx(Sa,{isOpen:!!Ee,onClose:()=>ot(null),mode:ya.SELECT,filterType:(Ee==null?void 0:Ee.assetType)==="video"?Ut.VIDEO:Ut.IMAGE,onSelect:Qa,selectButtonText:(Ee==null?void 0:Ee.assetType)==="video"?"使用此视频":"使用此图片"}),t.jsx(Sa,{isOpen:!!Q,onClose:()=>te(null),mode:ya.SELECT,filterType:Ut.IMAGE,filterCategory:Ft.CHARACTER,onSelect:a=>{var r;if(Q){const n=(r=M.current.characters)==null?void 0:r.find(l=>l.id===Q);Ie(Q,a.url),n&&As(a,{name:n.name,prompt:n.description}).catch(l=>{console.warn("[MVCreator] Failed to mark asset as character:",l)})}te(null)},selectButtonText:"使用此主体"}),Ze&&Ms.createPortal(t.jsx("div",{className:"mv-hover-preview",style:{left:`${Ze.x}px`,top:`${Ze.y}px`},onMouseEnter:es,onMouseLeave:ts,children:Ze.type==="image"?t.jsx(ut,{src:Ze.url,alt:"Preview",showSkeleton:!1,eager:!0}):t.jsx("video",{src:Ze.url,controls:!0,muted:!0,preload:"metadata"})}),document.body)]})};function gr(e){switch(e){case $e.COMPLETED:return"已完成";case $e.PROCESSING:return"进行中";case $e.PENDING:return"等待中";case $e.FAILED:return"失败";default:return""}}function _r(e){switch(e){case $e.COMPLETED:return"completed";case $e.PROCESSING:return"processing";case $e.PENDING:return"pending";case $e.FAILED:return"failed";default:return"pending"}}function br(e){const o=new Date(e);return`${o.getMonth()+1}/${o.getDate()} ${String(o.getHours()).padStart(2,"0")}:${String(o.getMinutes()).padStart(2,"0")}`}function yr(e){var i;const o=e.creativeBrief;return(o==null?void 0:o.purpose)||(o==null?void 0:o.directorStyle)||(o==null?void 0:o.narrativeStyle)||e.videoStyle||((i=e.musicStyleTags)==null?void 0:i.filter(Boolean).join(" / "))||"暂无概要"}const Sr=({records:e,onSelect:o,onRecordsChange:i,showStarredOnly:m=!1})=>{const u=m?e.filter(p=>p.starred):e,[y,_]=s.useState(null),[k,$]=s.useState(null),{tasks:M}=Ga(),S=s.useMemo(()=>{const p=new Map,I=new Set(e.map(T=>T.id)),z=()=>({storyboard:[],music:[],video:[],image:[]});for(const T of M){const N=T.params;if(T.type===He.CHAT&&N.mvCreatorAction==="storyboard"&&typeof N.mvCreatorRecordId=="string"&&I.has(N.mvCreatorRecordId)){const te=N.mvCreatorRecordId;xt(p,te,"storyboard",T,z);continue}const U=typeof N.batchId=="string"?N.batchId:"";if(!U.startsWith("mv_"))continue;const Q=$s(U,"mv_",I);Q&&(T.type===He.AUDIO?xt(p,Q,"music",T,z):T.type===He.VIDEO?xt(p,Q,"video",T,z):T.type===He.IMAGE&&xt(p,Q,"image",T,z))}return Ps(p)},[M,e]),v=s.useCallback(async(p,I)=>{p.stopPropagation();const z=await le(I.id,{starred:!I.starred});i(z)},[i]),W=s.useCallback((p,I)=>{p.stopPropagation(),$(I)},[]),F=s.useCallback(async()=>{if(!k)return;const p=await Xs(k);i(p),$(null)},[i,k]),L=s.useCallback((p,I)=>{p.stopPropagation(),_(z=>z===I?null:I)},[]);return u.length===0?t.jsx("div",{className:"va-page va-empty",children:t.jsx("span",{children:m?"暂无收藏":"暂无 MV 记录"})}):t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"va-page",children:t.jsx("div",{className:"va-history-list",children:u.map(p=>{const I=S.get(p.id),z=I?I.storyboard.length+I.music.length+I.video.length+I.image.length:0,T=y===p.id;return t.jsxs("div",{className:"va-history-item",onClick:()=>o(p),children:[t.jsxs("div",{className:"va-history-header",children:[t.jsxs("span",{className:"va-history-source",children:[t.jsx("span",{role:"img","aria-label":"mv",children:"🎬"})," ",p.sourceLabel]}),t.jsx("button",{className:`va-star-btn ${p.starred?"starred":""}`,onClick:N=>v(N,p),children:p.starred?"★":"☆"})]}),t.jsxs("div",{className:"va-history-meta",children:[z>0&&t.jsxs("button",{className:`va-history-expand-btn ${T?"expanded":""}`,onClick:N=>L(N,p.id),children:[t.jsx(Es,{size:12}),t.jsx("span",{children:T?"收起":"关联任务"})]}),t.jsx("span",{children:new Date(p.createdAt).toLocaleString()}),t.jsx("button",{className:"va-history-delete",onClick:N=>W(N,p.id),children:"删除"})]}),t.jsx("div",{className:"ma-history-title",children:p.musicTitle||"未命名 MV"}),t.jsx("div",{className:"ma-history-summary",children:yr(p).slice(0,80)}),p.generatedClips&&p.generatedClips.length>0&&t.jsxs("div",{className:"ma-history-clips-count",children:[p.generatedClips.length," 首音乐",p.editedShots?` · ${p.editedShots.length} 个镜头`:""]}),T&&I&&t.jsxs("div",{className:"va-history-related",onClick:N=>N.stopPropagation(),children:[I.music.length>0&&t.jsxs("div",{children:[t.jsxs("div",{className:"va-history-related-group-title",children:["音乐生成 (",I.music.length,")"]}),I.music.map(N=>t.jsx(kt,{task:N},N.id))]}),I.storyboard.length>0&&t.jsxs("div",{children:[t.jsxs("div",{className:"va-history-related-group-title",children:["分镜规划 (",I.storyboard.length,")"]}),I.storyboard.map(N=>t.jsx(kt,{task:N},N.id))]}),I.video.length>0&&t.jsxs("div",{children:[t.jsxs("div",{className:"va-history-related-group-title",children:["视频生成 (",I.video.length,")"]}),I.video.map(N=>t.jsx(kt,{task:N},N.id))]}),I.image.length>0&&t.jsxs("div",{children:[t.jsxs("div",{className:"va-history-related-group-title",children:["图片生成 (",I.image.length,")"]}),I.image.map(N=>t.jsx(kt,{task:N},N.id))]})]})]},p.id)})})}),t.jsx(Rs,{open:k!==null,title:"确认删除",description:"确定要删除这条 MV 记录吗?此操作不可撤销。",confirmText:"删除",cancelText:"取消",danger:!0,onOpenChange:p=>{p||$(null)},onConfirm:F})]})},kt=({task:e})=>t.jsx(tt,{content:gr(e.status),showArrow:!1,children:t.jsxs("div",{className:"va-history-related-task",children:[t.jsx("span",{className:`va-history-related-task-status ${_r(e.status)}`}),t.jsx("span",{className:"va-history-related-task-prompt",children:String(e.params.prompt||"").slice(0,40)||e.id.slice(0,8)}),t.jsx("span",{className:"va-history-related-task-time",children:br(e.createdAt)})]})}),Ir=[{id:"analyze",label:"分析"},{id:"script",label:"脚本"},{id:"generate",label:"生成"}],Vr=()=>{var J;const{records:e,setRecords:o,currentRecord:i,showStarred:m,setShowStarred:u,starredCount:y,selectRecord:_,updateCurrentRecord:k,restart:$,applySyncedRecord:M}=Vs({loadRecords:$t,logPrefix:"[MVCreator]"}),{page:S,setPage:v,navigateToStep:W,goToDefaultPage:F,openHistory:L,openStarred:p,toggleStarred:I}=Ds({initialPage:"analyze",defaultPage:"analyze",historyPage:"history",setShowStarred:u}),z=s.useCallback(async b=>{if(nr(b))return await ir(b)||Zt(b);const ge=lr(b);return ge?cr(b,ge):null},[]);Js({syncTask:z,applySyncedRecord:M,logPrefix:"[MVCreator]"});const T=s.useCallback(b=>{k(b)},[k]),N=s.useCallback(b=>{_(b),b.editedShots&&b.editedShots.length>0?v("generate"):(b.selectedClipId,v("analyze"))},[_,v]),U=s.useCallback(b=>{k(b)},[k]),Q=s.useCallback(()=>{$(),F()},[F,$]),te=!!(i!=null&&i.editedShots&&i.editedShots.length>0),ce=s.useMemo(()=>Ir.map((b,ge)=>({...b,disabled:!i&&ge>0||(b.id==="script"||b.id==="generate")&&!te})),[i,te]);return t.jsxs("div",{className:"video-analyzer music-analyzer mv-creator",children:[t.jsx(Os,{isHistoryPage:S==="history",showStarred:m,recordsCount:e.length,starredCount:y,currentStep:S,steps:ce,onStepNavigate:W,onBackFromHistory:F,onOpenHistory:L,onOpenStarred:p,onToggleStarred:I}),S==="analyze"&&t.jsx(rr,{existingRecord:i,onComplete:T,onRecordsChange:o,onCreateNew:Q,onNext:(J=i==null?void 0:i.editedShots)!=null&&J.length?()=>v("script"):void 0}),S==="script"&&i&&te&&t.jsx(mr,{record:i,onRecordUpdate:U,onRecordsChange:o,onNext:()=>v("generate")}),S==="generate"&&i&&te&&t.jsx(vr,{record:i,onRecordUpdate:U,onRecordsChange:o,onRestart:Q}),S==="history"&&t.jsx(Sr,{records:e,onSelect:N,onRecordsChange:o,showStarredOnly:m})]})};export{Vr as default};
163
+ }`}const Ht="mv-creator:video-model",Wt="mv-creator:storyboard-model",Ta="gemini-2.5-pro",Na="AI 分镜草稿";function sr(e,o){return(e.purpose||e.directorStyle||e.narrativeStyle||o||Na).trim().slice(0,24)||Na}const rr=({existingRecord:e,onComplete:o,onRecordsChange:i,onNext:m})=>{const[u,y]=s.useState((e==null?void 0:e.videoStyle)||""),[_,k]=s.useState(()=>Tt(e==null?void 0:e.creativeBrief)),[$,M]=s.useState([]),[S,v]=s.useState((e==null?void 0:e.selectedClipId)||null),[W,z]=s.useState(!1),L=nt("video"),[p,I]=s.useState(()=>(e==null?void 0:e.videoModel)||ye(Ht,"veo3").modelId),[F,T]=s.useState(()=>(e==null?void 0:e.videoModelRef)||ye(Ht,"veo3").modelRef),N=s.useMemo(()=>st(p),[p]),[U,Q]=s.useState(()=>(e==null?void 0:e.segmentDuration)||parseInt(N.defaultDuration,10)||8),te=s.useMemo(()=>(N.durationOptions||[]).map(c=>({value:parseInt(c.value,10),label:c.label})),[N]),ce=nt("text"),J=s.useMemo(()=>ce.filter(c=>/^gemini/i.test(c.id)),[ce]),[b,ge]=s.useState(()=>ye(Wt,Ta).modelId),[se,We]=s.useState(()=>ye(Wt,Ta).modelRef),[q,De]=s.useState(!1),[ee,_e]=s.useState(""),re=s.useRef(!1),xe=s.useRef(),ne=s.useRef(e||null);s.useEffect(()=>{e&&(y(e.videoStyle||""),k(Tt(e.creativeBrief)),v(e.selectedClipId||null))},[e]),s.useEffect(()=>{ne.current=e||null},[e]),s.useEffect(()=>{M([])},[e==null?void 0:e.id]);const de=(e==null?void 0:e.editedShots)||[];s.useEffect(()=>{de.length>0&&z(!0)},[de.length]);const ue=e==null?void 0:e.id;s.useEffect(()=>{if(ue)return clearTimeout(xe.current),xe.current=setTimeout(async()=>{const c=ne.current;if(!c||c.id!==ue)return;const g={videoStyle:u,creativeBrief:_,videoModel:p,videoModelRef:F,segmentDuration:U},Y=await le(ue,g);i(Y),o({...c,...g})},500),()=>clearTimeout(xe.current)},[ue,u,_,p,F,U,o,i]),s.useEffect(()=>{var ae;const c=e==null?void 0:e.pendingStoryboardTaskId;if(!c){_e("");return}const g=Ce.getTask(c);if((g==null?void 0:g.status)==="failed"){_e(`分镜生成失败: ${((ae=g.error)==null?void 0:ae.message)||"未知错误"}`);return}if((g==null?void 0:g.status)==="completed"){_e("");return}const Y=Ce.observeTaskUpdates().subscribe(pe=>{var we;pe.task.id===c&&(pe.task.status==="failed"?_e(`分镜生成失败: ${((we=pe.task.error)==null?void 0:we.message)||"未知错误"}`):pe.task.status==="completed"&&_e(""))});return()=>Y.unsubscribe()},[e==null?void 0:e.pendingStoryboardTaskId]);const[fe,Oe]=s.useState([]);s.useEffect(()=>{let c=!1;return fs.getAllTasks({type:He.AUDIO,status:$e.COMPLETED,includeArchived:!0}).then(g=>{if(c)return;const Y=[];for(const ae of g){const pe=Bs(ae);for(const we of pe)Y.push({...we,prompt:String(ae.params.prompt||"")})}Oe(Y)}).catch(()=>{}),()=>{c=!0}},[]);const he=s.useMemo(()=>{var c;return S&&(((c=e==null?void 0:e.generatedClips)==null?void 0:c.find(g=>g.clipId===S))||fe.find(g=>g.clipId===S))||null},[S,e==null?void 0:e.generatedClips,fe]),je=(he==null?void 0:he.audioUrl)||(S?e==null?void 0:e.selectedClipAudioUrl:null),be=(e==null?void 0:e.selectedClipDuration)||(he==null?void 0:he.duration)||30,oe=s.useCallback(()=>{Fe.trackUIInteraction({area:"popular_mv_tool",action:"music_tool_opened",control:"open_music_tool",source:"mv_creator_analyze_page",metadata:{existingAudioClipsCount:fe.length}});const c=ha.getPrimaryToolState("mv-creator"),g=c==null?void 0:c.position,Y=g?{x:g.x+((c==null?void 0:c.tool.defaultWidth)||520)+16,y:g.y}:void 0;ha.openTool(Ls.manifest,{launchMode:"reuse",position:Y})},[fe.length]),Be=s.useCallback(async c=>{var Y;Fe.trackUIInteraction({area:"popular_mv_tool",action:"music_clip_selected",control:"select_music_clip",source:"mv_creator_analyze_page",metadata:{hasClipId:!!c.clipId,hasAudioUrl:!!c.audioUrl,duration:c.duration}});let g=e||null;if(g){const ae=g.generatedClips||[],d={generatedClips:ae.some(P=>P.clipId===c.clipId)?ae:[...ae,c],selectedClipId:c.clipId,selectedClipDuration:c.duration??null,selectedClipAudioUrl:c.audioUrl,musicTitle:g.musicTitle||c.title||""},V=await le(g.id,d);i(V),o({...g,...d})}else{const ae=c.title||((Y=c.prompt)==null?void 0:Y.slice(0,20))||"已有音频";g={id:Jt(),createdAt:Date.now(),sourceLabel:ae,starred:!1,musicTitle:c.title||"",generatedClips:[c],selectedClipId:c.clipId,selectedClipDuration:c.duration??null,selectedClipAudioUrl:c.audioUrl};const pe=await Ma(g);i(pe),o(g)}v(c.clipId),_e("")},[e,o,i]),Pe=s.useCallback((c,g)=>{I(c),T(g||null),rt(Ht,c,g);const Y=st(c);Q(parseInt(Y.defaultDuration,10)||8)},[]),Se=s.useCallback((c,g)=>{ge(c),We(g||null),rt(Wt,c,g)},[]),Le=s.useCallback(async()=>{if(re.current)return;if(!je){_e("请先选择配乐");return}re.current=!0;const c=e||{id:Jt(),createdAt:Date.now(),sourceLabel:sr(_,u),starred:!1,musicTitle:"",generatedClips:[],selectedClipId:null,selectedClipDuration:null,selectedClipAudioUrl:null};Fe.trackUIInteraction({area:"popular_mv_tool",action:"storyboard_generation_started",control:"generate_storyboard",source:"mv_creator_analyze_page",metadata:{hasSelectedClip:!!je,clipDuration:be,segmentDuration:U,hasStoryboardModelRef:!!se,hasVideoModelRef:!!F}}),De(!0),_e("");try{const g=tr({musicTitle:c.musicTitle,musicStyleTags:c.musicStyleTags,musicLyrics:c.musicLyrics,clipDuration:be,videoModel:p,segmentDuration:U,aspectRatio:c.aspectRatio||"16x9",videoStyle:u,creativeBrief:_,hasAudio:!!je}),ae={pendingStoryboardTaskId:Ce.createTask({prompt:g,model:b,modelRef:se,mvCreatorAction:"storyboard",mvCreatorRecordId:c.id,knowledgeContextRefs:$,audioCacheUrl:je},He.CHAT).id,videoModel:p,videoModelRef:F,segmentDuration:U,videoStyle:u,creativeBrief:_,aspectRatio:c.aspectRatio||"16x9"},pe={...c,...ae},we=e?await le(c.id,ae):await Ma(pe);i(we),o(pe),_e("分镜规划任务已提交,等待 AI 生成...")}catch(g){_e(g instanceof Error?g.message:"提交失败")}finally{De(!1),re.current=!1}},[e,be,p,F,U,u,_,b,se,$,je,o,i]);return t.jsxs("div",{className:"va-page",children:[de.length>0&&t.jsx("button",{className:"va-collapse-toggle",onClick:()=>z(c=>!c),children:W?"▶ 展开配置":"▼ 收起配置"}),!W&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"ma-card ma-card--grow",children:[t.jsxs("div",{className:"ma-card-header",children:[t.jsxs("span",{children:["选择配乐 (",fe.length,")"]}),t.jsx("button",{className:"ma-chip ma-chip--accent",style:{cursor:"pointer",fontSize:"11px",padding:"2px 8px"},onClick:oe,children:"+ 生成新音乐"})]}),fe.length===0?t.jsxs("div",{className:"ma-hint",children:["暂无已完成的音频,",t.jsx("button",{onClick:oe,style:{background:"none",border:"none",color:"#E67E22",cursor:"pointer",textDecoration:"underline",padding:0,font:"inherit"},children:"去生成音乐"})]}):t.jsx("div",{className:"ma-clips-gallery",children:fe.map((c,g)=>{var Y;return t.jsxs("div",{className:`ma-clip-row ${S===c.clipId?"is-selected":""}`,onClick:()=>Be(c),style:{cursor:"pointer"},children:[c.imageUrl?t.jsx("img",{src:c.imageUrl,alt:"",className:"ma-clip-thumb",referrerPolicy:"no-referrer"}):t.jsx("div",{className:"ma-clip-thumb ma-clip-thumb--placeholder",children:"♪"}),t.jsxs("div",{className:"ma-clip-meta",children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"4px"},children:[t.jsx("span",{className:"ma-clip-title",children:c.title||((Y=c.prompt)==null?void 0:Y.slice(0,30))||c.clipId}),S===c.clipId&&t.jsx("span",{className:"ma-chip ma-chip--accent",style:{flexShrink:0,padding:"0 4px",fontSize:"10px",height:"16px",lineHeight:"14px"},children:"已选"})]}),c.duration!=null&&t.jsxs("span",{className:"ma-clip-duration",children:[Math.round(c.duration),"s"]})]}),t.jsx("audio",{controls:!0,src:c.audioUrl,preload:"metadata",className:"ma-clip-player",onClick:ae=>ae.stopPropagation()})]},`${c.clipId||g}`)})})]}),t.jsx(Ba,{value:_,onChange:k,workflow:"mv",videoStyle:u,onVideoStyleChange:y}),S&&t.jsx(La,{selectedModel:p,selectedSelectionKey:Ne(p,F),onSelectModel:Pe,models:L,segmentDuration:U,durationOptions:te,onSegmentDurationChange:Q}),t.jsxs("div",{className:"ma-card mv-storyboard-control-card",children:[ee&&t.jsx("div",{className:"ma-progress mv-storyboard-message",children:ee}),t.jsxs("div",{className:"mv-storyboard-control-row",children:[t.jsxs("div",{className:"mv-storyboard-field mv-storyboard-field--knowledge",children:[t.jsx("label",{className:"mv-storyboard-field-label",children:"知识库上下文"}),t.jsx(ea,{value:$,onChange:M,disabled:q,className:"mv-knowledge-context-selector mv-knowledge-context-selector--inline"})]}),t.jsxs("div",{className:"mv-storyboard-field mv-storyboard-field--model",children:[t.jsx("label",{className:"mv-storyboard-field-label",children:"AI 分镜模型"}),t.jsx(Nt,{models:J,selectedModel:b,selectedSelectionKey:Ne(b,se),onSelect:(c,g)=>Se(c,g),variant:"form",placement:"auto",disabled:q})]}),t.jsx("button",{className:"va-analyze-btn va-analyze-btn--inline mv-storyboard-generate-btn",onClick:Le,disabled:q,children:q?"提交中...":de.length>0?"重新生成分镜":"AI 生成分镜"})]})]})]}),de.length>0&&t.jsxs(t.Fragment,{children:[he&&W&&t.jsx("div",{className:"ma-card",children:t.jsxs("div",{className:"ma-clip-row is-selected",children:[he.imageUrl?t.jsx("img",{src:he.imageUrl,alt:"",className:"ma-clip-thumb",referrerPolicy:"no-referrer"}):t.jsx("div",{className:"ma-clip-thumb ma-clip-thumb--placeholder",children:"♪"}),t.jsxs("div",{className:"ma-clip-meta",children:[t.jsx("span",{className:"ma-clip-title",children:he.title||he.clipId}),t.jsxs("span",{className:"ma-clip-duration",children:[Math.round(be),"s"]})]}),t.jsx("audio",{controls:!0,src:he.audioUrl,preload:"metadata",className:"ma-clip-player"})]})}),(e==null?void 0:e.characters)&&e.characters.length>0&&t.jsxs("div",{className:"ma-card",children:[t.jsx("div",{className:"ma-card-header",children:t.jsxs("span",{children:["角色(",e.characters.length," 个)"]})}),t.jsx("div",{className:"va-characters",children:e.characters.map(c=>t.jsx("div",{className:"va-character-item",children:t.jsxs("div",{className:"va-character-info",children:[t.jsx("span",{className:"va-character-name",children:c.name}),t.jsx("span",{className:"va-character-desc",children:c.description})]})},c.id))})]}),t.jsxs("div",{className:"ma-card",children:[t.jsx("div",{className:"ma-card-header",children:t.jsxs("span",{children:["分镜脚本(",de.length," 个镜头)"]})}),t.jsx("div",{className:"va-shots",children:de.map((c,g)=>t.jsx(Qt,{shot:c,index:g,compact:!0},c.id))})]}),m&&t.jsx("div",{className:"va-page-actions",children:t.jsx("button",{className:"va-btn-primary",onClick:m,children:"下一步:编辑脚本 →"})})]})]})};function ta(e){return gs(e,"mvCreatorAction",["storyboard","rewrite"])}function nr(e){return ta(e)!==null}function or(e){const o=Ua(e);if(!o)throw new Error("分镜任务缺少结果内容");try{const y=_s(o,$=>Array.isArray($.shots)),_=(y.shots||[]).map(($,M)=>({...$,id:$.id||`shot_${M+1}`})),k=Array.isArray(y.characters)?y.characters:[];return{shots:_,characters:k}}catch{}try{return{shots:bs(o,_=>Array.isArray(_)&&_.some(k=>k&&typeof k=="object")).map((_,k)=>({..._,id:_.id||`shot_${k+1}`})),characters:[]}}catch{}const i=[],m=[],u=ys(o,y=>{const _=y;return typeof _.id=="string"||_.startTime!==void 0});for(const y of u){const _=typeof y.id=="string"?y.id:"";_.startsWith("char_")&&y.name&&y.description?m.push(y):(_.startsWith("shot_")||y.startTime!==void 0)&&i.push({...y,id:_||`shot_${i.length+1}`})}if(i.length>0)return{shots:i,characters:m};throw new Error("响应中未找到有效 JSON(可能因输出过长被截断)")}function Aa(e,o){const i=new Map(e.map(m=>[m.id,m]));return o.map(m=>{const u=i.get(m.id);return{...m,referenceImageUrl:m.referenceImageUrl||(u==null?void 0:u.referenceImageUrl)}})}async function ir(e){if(e.status!=="completed"||ta(e)!=="storyboard")return null;const o=za(e,"mvCreatorRecordId");if(!o)return null;const m=(await $t()).find(M=>M.id===o);if(!m||m.pendingStoryboardTaskId!==e.id)return null;const{shots:u,characters:y}=or(e),_=(m.storyboardVersions||[]).length,k=Ha(u,`AI 分镜 #${_+1}`,e.params.prompt,{characters:y,videoStyle:m.videoStyle}),$=Wa(m,k);return Fa(m,{editedShots:u,pendingStoryboardTaskId:null,storyboardGeneratedAt:Date.now(),...y.length>0?{characters:y}:{},...$},le)}async function Zt(e){if(e.status!=="completed"||ta(e)!=="rewrite")return null;const o=za(e,"mvCreatorRecordId");if(!o)return null;const i=await $t(),m=i.find(p=>p.id===o);if(!m)return null;if(m.pendingRewriteTaskId!==e.id)return!m.pendingRewriteTaskId&&m.storyboardGeneratedAt&&(!e.completedAt||m.storyboardGeneratedAt>=e.completedAt)?{records:i,record:m}:null;const u=Ua(e);if(!u)return null;const y=m.editedShots||[],_=ps(u,y),k=_.shots,$=_.characters,M=_.hasCharacters,S=_.videoStyle,v=(m.storyboardVersions||[]).length,W=Ha(k,`AI 改编 #${v+1}`,e.params.prompt,{characters:M?Aa(m.characters||[],$||[]):m.characters||[],videoStyle:S||m.videoStyle}),z=Wa(m,W),L=M?Aa(m.characters||[],$||[]):void 0;return Fa(m,{editedShots:k,pendingRewriteTaskId:null,storyboardGeneratedAt:Date.now(),...L!==void 0?{characters:L}:{},...S?{videoStyle:S}:{},...z},le)}function lr(e){if(e.type!==He.AUDIO)return null;const o=e.params.batchId;return o?hs(o,{prefix:"mv_",marker:"_music_"}):null}async function cr(e,o){return vs(e,o,{loadRecords:$t,updateRecord:le})}function at(e){e.style.height="auto",e.style.height=e.scrollHeight+"px"}function mt(e){e&&at(e)}function ft(e,o=30){if(!e)return 1;const i=e.split(`
164
+ `);let m=0;for(const u of i)m+=Math.max(1,Math.ceil(u.length/o));return Math.max(1,m)}function Je(e,o,i){return e.find(m=>m.id===o)||i}const dr=["固定镜头 (Static)","缓慢推近 (Dolly In)","缓慢拉远 (Dolly Out)","水平平移 (Pan)","垂直摇移 (Tilt)","跟随拍摄 (Follow)","手持感 (Handheld)","环绕拍摄 (Orbit)","升降镜头 (Crane)","快速推移 (Zoom In)","快速拉远 (Zoom Out)","航拍俯冲 (Drone Dive)"],ur=[{label:"硬切 (cut)",value:"cut"},{label:"交叉溶解 (dissolve)",value:"dissolve"},{label:"匹配切 (match_cut)",value:"match_cut"},{label:"淡出到黑 (fade_to_black)",value:"fade_to_black"}],Yt="mv-creator:script-model",$a="gemini-2.5-pro",mr=({record:e,onRecordUpdate:o,onRecordsChange:i,onNext:m})=>{var pe,we;const[u,y]=s.useState(e.editedShots||[]),[_,k]=s.useState(e.rewritePrompt||""),[$,M]=s.useState([]),[S,v]=s.useState(!1),[W,z]=s.useState(""),[L,p]=s.useState(""),[I,F]=s.useState(e.pendingRewriteTaskId||null),[T,N]=s.useState(!1),U=s.useRef(null),Q=s.useRef(!1),te=nt("video"),ce="mv-creator:video-model",[J,b]=s.useState(()=>e.videoModel||ye(ce,"veo3").modelId),[ge,se]=s.useState(()=>e.videoModelRef||ye(ce,"veo3").modelRef),We=s.useMemo(()=>st(J),[J]),[q,De]=s.useState(()=>e.segmentDuration||parseInt(We.defaultDuration,10)||8),ee=s.useMemo(()=>(We.durationOptions||[]).map(d=>({value:parseInt(d.value,10),label:d.label})),[We]),_e=e.selectedClipDuration||30,re=s.useMemo(()=>{const d=[{label:`${q}秒`,value:String(q)}];return Xt(_e,d)},[_e,q]),[xe,ne]=s.useState(e.videoStyle||""),[de,ue]=s.useState(()=>Tt(e.creativeBrief)),fe=s.useCallback((d,V)=>{b(d),se(V||null),rt(ce,d,V);const P=st(d),R=parseInt(P.defaultDuration,10)||8;De(R)},[]),Oe=s.useCallback(async d=>{const V=await le(e.id,d);i(V),o(Je(V,e.id,{...e,...d}))},[e,o,i]),he=s.useCallback((d,V)=>{const R=(e.characters||[]).map(Z=>Z.id===d?{...Z,description:V}:Z);Oe({characters:R})},[e,Oe]),je=nt("text"),[be,oe]=s.useState(()=>ye(Yt,$a).modelId),[Be,Pe]=s.useState(()=>ye(Yt,$a).modelRef),Se=s.useCallback((d,V)=>{oe(d),Pe(V||null),rt(Yt,d,V)},[]),Le=s.useRef();s.useEffect(()=>(clearTimeout(Le.current),Le.current=setTimeout(async()=>{const d=await le(e.id,{rewritePrompt:_,videoModel:J,videoModelRef:ge,segmentDuration:q,videoStyle:xe,creativeBrief:de});i(d),o(Je(d,e.id,{...e,rewritePrompt:_,videoModel:J,videoModelRef:ge,segmentDuration:q,videoStyle:xe,creativeBrief:de}))},500),()=>clearTimeout(Le.current)),[_,J,ge,q,xe,de]),s.useEffect(()=>{y(e.editedShots||[]),k(e.rewritePrompt||""),ne(e.videoStyle||""),ue(Tt(e.creativeBrief))},[e]),s.useEffect(()=>{M([])},[e.id]);const c=s.useCallback(async d=>{y(d);const V=Ke(e,d),P=await le(e.id,V);i(P),o(Je(P,e.id,{...e,...V}))},[e,o,i]),g=s.useCallback((d,V,P)=>{const R=u.map(Z=>Z.id===d?{...Z,[V]:P}:Z);c(R)},[u,c]),Y=s.useCallback(async()=>{if(!Q.current){Q.current=!0,v(!0),p(""),Fe.trackUIInteraction({area:"popular_mv_tool",action:"script_rewrite_started",control:"rewrite_script",source:"mv_creator_script_page",metadata:{shotCount:u.length,hasRewritePrompt:!!_.trim(),segmentDuration:q,hasModelRef:!!Be}});try{const d=ar({record:{...e,creativeBrief:de},currentShots:u,rewritePrompt:_,videoModel:J,segmentDuration:q,videoStyle:xe}),V=Ce.createTask({prompt:d,model:be,modelRef:Be,mvCreatorAction:"rewrite",mvCreatorRecordId:e.id,knowledgeContextRefs:$},He.CHAT);F(V.id);const P=await le(e.id,{pendingRewriteTaskId:V.id});i(P),o(Je(P,e.id,{...e,pendingRewriteTaskId:V.id})),z("AI 改编中...")}catch(d){p(d.message||"提交失败")}finally{v(!1),Q.current=!1}}},[e,u,_,J,q,xe,de,be,Be,$,o,i]);s.useEffect(()=>{var P;if(!I)return;const d=Ce.getTask(I);if((d==null?void 0:d.status)==="failed"){F(null),z(""),p(((P=d.error)==null?void 0:P.message)||"改编失败"),le(e.id,{pendingRewriteTaskId:null}).then(R=>{i(R),o(Je(R,e.id,{...e,pendingRewriteTaskId:null}))});return}if((d==null?void 0:d.status)==="completed"){Zt(d).then(R=>{R?(i(R.records),o(R.record),y(R.record.editedShots||[]),ne(R.record.videoStyle||"")):p("改编任务已完成,但未找到可回填的记录")}).finally(()=>{F(null),z("")});return}typeof(d==null?void 0:d.progress)=="number"&&z(`AI 改编中 ${Math.round(d.progress)}%`);const V=Ce.observeTaskUpdates().subscribe(R=>{var Z;if(R.task.id===I){if(R.task.status==="failed"){F(null),z(""),p(((Z=R.task.error)==null?void 0:Z.message)||"改编失败"),le(e.id,{pendingRewriteTaskId:null}).then(Ie=>{i(Ie),o(Je(Ie,e.id,{...e,pendingRewriteTaskId:null}))});return}if(R.task.status==="completed"){Zt(R.task).then(Ie=>{Ie?(i(Ie.records),o(Ie.record),y(Ie.record.editedShots||[]),ne(Ie.record.videoStyle||"")):p("改编任务已完成,但未找到可回填的记录")}).catch(Ie=>{p(Ie.message||"改编结果同步失败")}).finally(()=>{F(null),z("")});return}typeof R.task.progress=="number"&&z(`AI 改编中 ${Math.round(R.task.progress)}%`)}});return()=>V.unsubscribe()},[I,e,o,i]);const ae=s.useCallback(async d=>{const V=er(e,d);if(!V)return;N(!1),y(V.editedShots);const P=await le(e.id,V);i(P),o(Je(P,e.id,{...e,...V}))},[e,o,i]);return s.useEffect(()=>{if(!T)return;const d=V=>{U.current&&!U.current.contains(V.target)&&N(!1)};return document.addEventListener("mousedown",d),()=>document.removeEventListener("mousedown",d)},[T]),t.jsxs("div",{className:"va-page",children:[t.jsxs("div",{className:"va-product-form",children:[t.jsx("textarea",{ref:mt,className:"va-form-textarea va-auto-resize",placeholder:"输入改编提示词,描述你想要的调整方向...",rows:Math.max(3,ft(_)),value:_,onChange:d=>k(d.target.value),onInput:d=>at(d.currentTarget)}),t.jsx(ea,{value:$,onChange:M,disabled:S||!!I,className:"mv-knowledge-context-selector"}),t.jsx(Ba,{value:de,onChange:ue,workflow:"mv",videoStyle:xe,onVideoStyleChange:ne}),t.jsxs("div",{className:"va-model-select",children:[t.jsx("label",{className:"va-model-label",children:"改编模型"}),t.jsx(Nt,{variant:"form",selectedModel:be,selectedSelectionKey:Ne(be,Be),onSelect:Se,models:je,placement:"down",disabled:!!I,placeholder:"选择文本模型"})]}),t.jsx(La,{selectedModel:J,selectedSelectionKey:Ne(J,ge),onSelectModel:fe,models:te,segmentDuration:q,durationOptions:ee,onSegmentDurationChange:De,disabled:!!I,placement:"down",overflowText:re.overflow>0?`实际 ${re.actualTotal}s(+${parseFloat(re.overflow.toFixed(2))}s)`:void 0}),t.jsxs("div",{className:"va-version-row",children:[t.jsx("button",{className:"va-analyze-btn",style:{flex:1},onClick:Y,disabled:S||!!I,children:S||I?W||"AI 改编中...":"AI 改编脚本"}),e.storyboardVersions&&e.storyboardVersions.length>0&&t.jsxs("div",{className:"va-version-select",ref:U,children:[t.jsxs("button",{className:"va-version-btn",onClick:()=>N(d=>!d),children:[e.activeVersionId===Mt?"原始版本":((pe=e.storyboardVersions.find(d=>d.id===e.activeVersionId))==null?void 0:pe.label)||`v${e.storyboardVersions.length}`," ▾"]}),T&&t.jsxs("div",{className:"va-version-menu",children:[e.storyboardVersions.map(d=>t.jsxs("div",{className:`va-version-item ${d.id===e.activeVersionId?"active":""}`,onClick:()=>ae(d.id),children:[t.jsx("span",{children:d.label}),d.prompt&&t.jsx("span",{className:"va-version-prompt",children:d.prompt.length>30?d.prompt.slice(0,30)+"...":d.prompt}),t.jsxs("span",{className:"va-version-time",children:[d.shots.length," 镜头 · ",new Date(d.createdAt).toLocaleTimeString()]})]},d.id)),t.jsxs("div",{className:`va-version-item ${e.activeVersionId===Mt||!e.activeVersionId?"active":""}`,onClick:()=>ae(Mt),children:[t.jsx("span",{children:"原始版本"}),t.jsxs("span",{className:"va-version-time",children:[(((we=e.storyboardVersions[e.storyboardVersions.length-1])==null?void 0:we.shots)||[]).length," 镜头"]})]})]})]})]}),L&&t.jsx("div",{className:"va-error",children:L})]}),W&&!S&&t.jsx("div",{className:"ma-progress",children:W}),t.jsx(Ss,{characters:e.characters||[],onChange:he}),t.jsx("div",{className:"va-shots",children:u.map((d,V)=>t.jsx(Qt,{shot:d,index:V,compact:!0,children:t.jsxs("div",{className:"va-edit-fields",children:[t.jsx("label",{className:"va-edit-label",children:"画面描述"}),t.jsx("textarea",{ref:mt,className:"va-edit-textarea va-auto-resize",rows:ft(d.description),value:d.description||"",onChange:P=>g(d.id,"description",P.target.value),onInput:P=>at(P.currentTarget)}),t.jsx("label",{className:"va-edit-label",children:"旁白"}),t.jsx("textarea",{ref:mt,className:"va-edit-textarea va-auto-resize",rows:ft(d.narration),value:d.narration||"",onChange:P=>g(d.id,"narration",P.target.value),onInput:P=>at(P.currentTarget)}),t.jsx("label",{className:"va-edit-label",children:"运镜方式"}),t.jsx(va,{value:d.camera_movement||"",onChange:P=>g(d.id,"camera_movement",P),options:dr,placeholder:"选择或输入运镜方式"}),t.jsx("label",{className:"va-edit-label",children:"首帧 Prompt"}),t.jsx("textarea",{ref:mt,className:"va-edit-textarea va-auto-resize",rows:ft(d.first_frame_prompt),value:d.first_frame_prompt||"",onChange:P=>g(d.id,"first_frame_prompt",P.target.value),onInput:P=>at(P.currentTarget)}),t.jsx("label",{className:"va-edit-label",children:"尾帧 Prompt"}),t.jsx("textarea",{ref:mt,className:"va-edit-textarea va-auto-resize",rows:ft(d.last_frame_prompt),value:d.last_frame_prompt||"",onChange:P=>g(d.id,"last_frame_prompt",P.target.value),onInput:P=>at(P.currentTarget)}),t.jsx("label",{className:"va-edit-label",children:"转场方式"}),t.jsx(va,{value:d.transition_hint||"",onChange:P=>g(d.id,"transition_hint",P),options:ur,placeholder:"选择转场方式"})]})},d.id))}),t.jsx("div",{className:"va-page-actions",children:t.jsx("button",{className:"va-btn-primary",onClick:m,children:"下一步:批量生成 →"})})]})};function fr(e,o,i){var u,y;const m=e.selectedClipAudioUrl||((y=(u=e.generatedClips)==null?void 0:u.find(_=>_.clipId===e.selectedClipId))==null?void 0:y.audioUrl)||null;return{recordId:e.id,fileNamePrefix:"mv",zipBaseName:"mv_assets",scriptMarkdown:Ya(e,o),recordMeta:{id:e.id,musicTitle:e.musicTitle||"",musicStyleTags:e.musicStyleTags||[],aspectRatio:e.aspectRatio||"16x9",videoStyle:e.videoStyle||"",creativeBrief:e.creativeBrief||{},creativeBriefSummary:Oa(e.creativeBrief),shotCount:o.length},shots:o,assets:i,audioAsset:m?{url:m,fallbackExtension:"mp3",downloadErrorMessage:"音乐下载失败"}:{url:"",missingErrorMessage:"缺少已选中的音乐文件"}}}function pr(e,o){return Ks(o,e.characters||[])}const jt="mv-creator:image-model",wt="mv-creator:gen-video-model";function Pa(e,o){const i=Object.keys(e),m=Object.keys(o);return i.length!==m.length?!1:i.every(u=>e[u]===o[u])}function Ea(e,o){return o.reduce((i,m)=>{var _;const u=e[m.id];return(m.valueType==="enum"?(_=m.options)==null?void 0:_.some(k=>k.value===u):typeof u=="string"&&u.trim()!=="")&&u?(i[m.id]=u,i):(m.defaultValue&&(i[m.id]=m.defaultValue),i)},{})}function Va(e,o,i){return{...e,...o!=null?{duration:String(o)}:{},...i?{size:i}:{}}}function Ra(e,o,i){const{duration:m,size:u,...y}=e;return{extraParams:y,duration:m||o,size:u||i}}function hr(e){if(!e||e==="auto")return;const o=e.trim().replace(/[xX]/g,":");return/^\d+:\d+$/.test(o)?o:void 0}const qt=({size:e=14})=>t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",width:e,height:e,"aria-hidden":"true",children:[t.jsx("rect",{x:"3",y:"3",width:"8",height:"8",rx:"1.5"}),t.jsx("circle",{cx:"17",cy:"7",r:"4"}),t.jsx("rect",{x:"3",y:"13",width:"8",height:"8",rx:"1.5"}),t.jsx("rect",{x:"13",y:"13",width:"8",height:"8",rx:"1.5"})]}),vr=({record:e,onRecordUpdate:o,onRecordsChange:i,onRestart:m})=>{const u=s.useMemo(()=>e.editedShots||[],[e.editedShots]),y=e.aspectRatio||"16x9",_=e.batchId||`mv_${e.id}`,{openDialog:k,board:$}=Is(),M=s.useRef(e),S=s.useRef(u),v=s.useRef(!1),W=s.useRef(!1),z=s.useRef(null),L=s.useRef(new Set),p=s.useRef(new Set),[I,F]=s.useState([]),[T,N]=s.useState([]),U=s.useMemo(()=>e.characters||[],[e.characters]),[Q,te]=s.useState(null),ce=nt("image"),J=nt("video"),[b,ge]=s.useState(()=>ye(jt,"").modelId),[se,We]=s.useState(()=>ye(jt,"").modelRef),[q,De]=s.useState(()=>{const a=ye(jt,"");return a.modelId?xa(a.modelId,Ne(a.modelId,a.modelRef)).extraParams:{}}),[ee,_e]=s.useState(()=>e.videoModel||ye(wt,"veo3").modelId),[re,xe]=s.useState(()=>e.videoModelRef||ye(wt,"veo3").modelRef),[ne,de]=s.useState(()=>{const a=ye(wt,e.videoModel||"veo3"),r=e.videoModel||a.modelId,n=e.videoModelRef||a.modelRef,l=ja(r,Ne(r,n));return Va(l.extraParams,e.segmentDuration||l.duration,ga(r,e.videoSize||l.size,y))}),[ue,fe]=s.useState({running:!1,stopping:!1,currentIndex:-1,completedCount:0,retryCount:0}),[Oe,he]=s.useState(!1),je=s.useMemo(()=>Cs(b),[b]),be=s.useMemo(()=>xs(ee,re||ee,ne),[ee,re,ne]),oe=s.useMemo(()=>js(ee,re||ee,ne),[ee,re,ne]),Be=s.useMemo(()=>oe.sizeOptions,[oe]),Pe=s.useMemo(()=>Ra(ne,oe.defaultDuration,oe.defaultSize),[oe.defaultDuration,oe.defaultSize,ne]),Se=Pe.size,Le=Number.parseFloat(Pe.duration)||8,c=s.useMemo(()=>Object.keys(q).length>0?q:void 0,[q]);s.useEffect(()=>{M.current=e},[e]),s.useEffect(()=>{N([])},[e.id]),s.useEffect(()=>{S.current=u},[u]);const g=s.useCallback(async a=>{const r=M.current,n={...r,...a};M.current=n,n.editedShots&&(S.current=n.editedShots);const l=await le(r.id,a);return i(l),o(n),n},[o,i]),Y=s.useCallback(async a=>{const r=M.current,n=Ke(r,a);return S.current=a,await g(n),a},[g]),ae=s.useCallback((a,r)=>{const n=r||null;ge(a),We(n),De(xa(a,Ne(a,n)).extraParams),rt(jt,a,r)},[]),pe=s.useCallback((a,r)=>{const n=r||null;_e(a),xe(n),rt(wt,a,r);const l=ja(a,Ne(a,n));de(Va(l.extraParams,l.duration,ga(a,l.size,y)))},[y]),we=s.useCallback((a,r)=>{De(n=>{const l={...n};return!r||r==="default"?delete l[a]:l[a]=r,l})},[]),d=s.useCallback((a,r)=>{de(n=>{const l={...n};return!r||r==="default"?delete l[a]:l[a]=r,l})},[]);s.useEffect(()=>{const a=Ea(q,je);Pa(q,a)||De(a)},[je,q]),s.useEffect(()=>{const a=Ea(ne,be);Pa(ne,a)||de(a)},[be,ne]),s.useEffect(()=>{const a=Ra(ne,oe.defaultDuration,oe.defaultSize);Fs({currentModel:ee,currentSelectionKey:Ne(ee,re),extraParams:a.extraParams,duration:a.duration,size:a.size}),g({videoModel:ee,videoModelRef:re||null,segmentDuration:Number.parseFloat(a.duration)||8,videoSize:a.size})},[g,ee,oe.defaultDuration,oe.defaultSize,re,ne]);const V=s.useMemo(()=>I.map(a=>a.url).filter(Boolean),[I]),P=s.useMemo(()=>Hs(u),[u]),R=s.useMemo(()=>{var a;return{totalDuration:e.selectedClipDuration||30,productExposureDuration:0,productExposureRatio:0,shotCount:u.length,firstProductAppearance:0,aspect_ratio:y,video_style:e.videoStyle||"",bgm_mood:((a=e.musicStyleTags)==null?void 0:a.filter(Boolean).join(", "))||"",suggestion:"",shots:u}},[e,u,y]),Z=s.useMemo(()=>{var a,r,n;return{generationTopic:e.musicTitle||e.sourceLabel||"",videoStyle:e.videoStyle||"",bgmMood:((a=e.musicStyleTags)==null?void 0:a.filter(Boolean).join(", "))||"",creativeBrief:e.creativeBrief,generationContext:[e.musicTitle?`音乐标题:${e.musicTitle}`:"",(r=e.musicStyleTags)!=null&&r.length?`音乐风格:${e.musicStyleTags.join(", ")}`:"",e.selectedClipDuration?`音乐时长:${e.selectedClipDuration}秒`:"",(n=e.musicLyrics)!=null&&n.trim()?`歌词/意象:${e.musicLyrics.trim()}`:""].filter(Boolean).join(`
165
+ `)}},[e]),Ie=s.useCallback(async(a,r)=>{const l=(M.current.characters||[]).map(f=>f.id===a?{...f,referenceImageUrl:r}:f);await g({characters:l})},[g]),qa=s.useCallback(async()=>{try{const a=M.current,r=S.current;Ia($);const n=await Ca("text",Ya(a,r));if(!n.success)throw new Error(n.error||"插入失败,请确认画布已打开");Fe.trackUIInteraction({area:"popular_mv_tool",action:"script_inserted_to_canvas",control:"insert_script",source:"mv_creator_generate_page",metadata:{shotCount:r.length}}),et.success("脚本已插入画布")}catch(a){console.error("[MVCreator] Failed to insert script to canvas:",a);const r=a instanceof Error?a.message:"脚本插入画布失败";et.error(r)}},[$]),Pt=s.useCallback(async a=>{if(!$)return!1;try{Ia($);const r=await Ca("video",a);if(!r.success)throw new Error(r.error||"插入失败,请确认画布已打开");return!0}catch(r){return console.error("[MVCreator] Failed to insert generated video to canvas:",r),!1}},[$]),{isExportingAssets:aa,exportProgress:Ja,handleExportAssets:Za}=ws({onExport:async a=>{const r=M.current,n=S.current;return await qs({...fr(r,n,P),onProgress:a})},onExportSuccess:a=>{et.success(`素材导出完成,共 ${a.assetCount} 个文件`)},onExportError:a=>{console.error("[MVCreator] Failed to export mv assets:",a),et.error("素材导出失败")}}),Xa=s.useCallback(a=>{const r=`mv_${e.id}_char${a.id}_ref`,n=_a(a,R,Z);k(Ct.aiImageGeneration,{initialPrompt:n,initialKnowledgeContextRefs:T,batchId:r,initialAspectRatio:"1:1",initialModel:b||void 0,initialModelRef:se,autoInsertToCanvas:!1,assetMetadata:{category:zt.CHARACTER,characterName:a.name,characterPrompt:n}})},[e.id,R,Z,T,k,b,se]),sa=s.useCallback(async()=>{e.batchId||await g({batchId:_})},[e.batchId,_,g]),{tasks:ra}=Ga(),Ue=s.useRef(new Set),Et=s.useRef(new Set),na=s.useCallback(async(a,r,n)=>{let l=[...r],f=!1;for(const{shotId:h,videoUrl:x}of n){const A=`auto_${h}`;if(!Et.current.has(A)){Et.current.add(A);try{const D=l.findIndex(B=>B.id===h);if(D===-1)continue;const C=D>0?l[D-1]:void 0;if(C&&!C.generated_last_frame_url&&!C.generated_video_url){const B=await wa(x,C.id,"last","first");B&&(l=l.map(O=>O.id===C.id?{...O,generated_last_frame_url:B}:O),f=!0)}}finally{Et.current.delete(A)}}}if(f){const h=e;le(a,Ke(h,l)).then(x=>{i(x),o({...h,editedShots:l})})}},[e,o,i]);s.useEffect(()=>{var A,D,C,B;const a=`mv_${e.id}_shot`,r=`mv_${e.id}_char`;let n=!1;const l=e,f=M.current.generatedAssetsResetAt||l.generatedAssetsResetAt;let h=l.editedShots||[];const x=[];for(const O of ra){if(O.status!==$e.COMPLETED||Ue.current.has(O.id))continue;const ie=(A=O.params)==null?void 0:A.batchId;if(!ie)continue;if(ie.startsWith(r)){if(f&&O.createdAt<=f){Ue.current.add(O.id);continue}const me=(D=O.result)==null?void 0:D.url;if(Ue.current.add(O.id),me){const Te=ie.slice(r.length),Ae=Te.lastIndexOf("_ref");if(Ae!==-1){const ve=Te.slice(0,Ae),Re=(M.current.characters||[]).map(Ye=>Ye.id===ve?{...Ye,referenceImageUrl:me}:Ye);g({characters:Re})}}continue}if(!ie.startsWith(a))continue;if(f&&O.createdAt<=f){Ue.current.add(O.id);continue}if(e.storyboardGeneratedAt&&O.createdAt<e.storyboardGeneratedAt){Ue.current.add(O.id);continue}const ke=(C=O.result)==null?void 0:C.url;if(!ke)continue;const E=ie.slice(a.length),j=E.lastIndexOf("_");if(j===-1)continue;const w=E.slice(0,j),G=E.slice(j+1);if(G!=="first"&&G!=="last"&&G!=="video")continue;const X=G==="first"?"generated_first_frame_url":G==="last"?"generated_last_frame_url":"generated_video_url",K=h.find(me=>me.id===w),H=G==="video"&&p.current.has(O.id),Me=(B=K==null?void 0:K.suppressed_generated_urls)==null?void 0:B[G];if(Me&&Me===ke){H&&p.current.delete(O.id),Ue.current.add(O.id);continue}if(!K||K[X]===ke){H&&p.current.delete(O.id),Ue.current.add(O.id);continue}h=h.map(me=>me.id===w?{...me,[X]:ke,suppressed_generated_urls:me.suppressed_generated_urls?{...me.suppressed_generated_urls,[G]:void 0}:void 0}:me),Ue.current.add(O.id),n=!0,G==="video"&&(H?p.current.delete(O.id):x.push({shotId:w,videoUrl:ke}))}n&&le(l.id,Ke(l,h)).then(O=>{i(O),o({...l,editedShots:h})}),x.length>0&&na(l.id,h,x)},[ra,na,e,o,i,g]);const[Ee,ot]=s.useState(null),Qa=s.useCallback(async a=>{if(!Ee)return;ot(null);const{shotId:r,assetType:n}=Ee,l=n==="first"?"generated_first_frame_url":n==="last"?"generated_last_frame_url":"generated_video_url",f=u.map(x=>x.id===r?{...x,[l]:a.url}:x),h=await le(e.id,Ke(e,f));i(h),o({...e,editedShots:f})},[Ee,e,u,i,o]),[Ze,Vt]=s.useState(null),it=s.useRef(null),Ve=s.useCallback(()=>{it.current!==null&&(window.clearTimeout(it.current),it.current=null)},[]),oa=s.useCallback(()=>{Ve(),Vt(null)},[Ve]),ia=s.useCallback(()=>{Ve(),it.current=window.setTimeout(()=>{it.current=null,Vt(null)},120)},[Ve]),pt=s.useCallback((a,r,n)=>{Ve();const l=n.currentTarget.getBoundingClientRect();Vt({url:a,type:r,x:l.left+l.width/2,y:l.top-8})},[Ve]),ht=s.useCallback(()=>{ia()},[ia]),es=s.useCallback(()=>{Ve()},[Ve]),ts=s.useCallback(()=>{oa()},[oa]);s.useEffect(()=>()=>{Ve()},[Ve]);const lt=s.useMemo(()=>{var r;const a=(r=Be.find(n=>n.value===Se))==null?void 0:r.aspectRatio;if(a)return a;if(Se!=null&&Se.includes("x")){const[n,l]=Se.split("x").map(Number);if(n&&l){const f=(x,A)=>A===0?x:f(A,x%A),h=f(n,l);return`${n/h}:${l/h}`}}return y.replace("x",":")},[y,Be,Se]),Rt=lt,Xe=hr(q.size),vt=q.size||Rt;s.useEffect(()=>{b&&Us({currentModel:b,currentSelectionKey:Ne(b,se),extraParams:q,aspectRatio:Xe||Rt})},[Rt,b,se,q,Xe]);const Ge=s.useCallback(a=>a.map(r=>({url:r.url,name:r.name})),[]),gt=s.useCallback((a=[],r=[])=>a.length===r.length&&a.every((n,l)=>{var f,h;return n.url===((f=r[l])==null?void 0:f.url)&&n.name===((h=r[l])==null?void 0:h.name)}),[]),_t=s.useCallback((...a)=>{const r=new Set,n=[];return a.forEach(l=>{l==null||l.forEach(f=>{var x;const h=(x=f.url)==null?void 0:x.trim();!h||r.has(h)||(r.add(h),n.push({url:h,name:f.name||"参考图"}))})}),n.length>0?n:void 0},[]),bt=s.useCallback(a=>{var n;if(!((n=a.character_ids)!=null&&n.length))return[];const r=new Set;return a.character_ids.reduce((l,f)=>{var A;const h=U.find(D=>D.id===f),x=(A=h==null?void 0:h.referenceImageUrl)==null?void 0:A.trim();return!x||r.has(x)||(r.add(x),l.push({url:x,name:h!=null&&h.name?`角色:${h.name}`:"角色参考图"})),l},[])},[U]),Qe=s.useCallback(async(a,r,n)=>{let l=!1;const f=Ge(n.images),h=S.current.map(x=>{if(x.id!==a)return x;if(r==="first"){const C=x.first_frame_draft,B={prompt:n.prompt,images:f,aspectRatio:n.aspectRatio};return(C==null?void 0:C.prompt)===B.prompt&&(C==null?void 0:C.aspectRatio)===B.aspectRatio&&gt(C==null?void 0:C.images,B.images)?x:(l=!0,{...x,first_frame_draft:B})}if(r==="last"){const C=x.last_frame_draft,B={prompt:n.prompt,images:f,aspectRatio:n.aspectRatio};return(C==null?void 0:C.prompt)===B.prompt&&(C==null?void 0:C.aspectRatio)===B.aspectRatio&&gt(C==null?void 0:C.images,B.images)?x:(l=!0,{...x,last_frame_draft:B})}const A=x.video_draft,D={prompt:n.prompt,images:f,duration:n.duration,size:n.size};return(A==null?void 0:A.prompt)===D.prompt&&(A==null?void 0:A.duration)===D.duration&&(A==null?void 0:A.size)===D.size&&gt(A==null?void 0:A.images,D.images)?x:(l=!0,{...x,video_draft:D})});l&&await Y(h)},[Y,gt,Ge]),Dt=s.useCallback(a=>{const r=a.first_frame_prompt||a.description||"";if(!r)return;Fe.trackUIInteraction({area:"popular_mv_tool",action:"shot_first_frame_generation_opened",control:"generate_first_frame",source:"mv_creator_generate_page",metadata:{shotId:a.id,hasDraft:!!a.first_frame_draft}});const n=Ft(r,R,Z,{shot:a,characters:U}),l=a.first_frame_draft,f=l?Ge(l.images||[]):void 0,h=!l&&a.generated_first_frame_url?[{url:a.generated_first_frame_url,name:"首帧"}]:void 0,x=bt(a),A=`mv_${e.id}_shot${a.id}_first`;k(Ct.aiImageGeneration,{initialPrompt:(l==null?void 0:l.prompt)||n,initialKnowledgeContextRefs:T,batchId:A,initialAspectRatio:(l==null?void 0:l.aspectRatio)??Xe,initialModel:b||void 0,initialModelRef:se,autoInsertToCanvas:!1,initialImages:_t(f,h,x),onDraftChange:D=>Qe(a.id,"first",D)})},[e.id,R,Z,U,T,k,b,se,_t,bt,Qe,Xe,Ge]),ct=s.useCallback((a,r)=>{var n;return a.generated_last_frame_url?a.generated_last_frame_url:(n=u[r+1])==null?void 0:n.generated_first_frame_url},[u]),yt=s.useCallback((a,r)=>{const n=a.last_frame_prompt||"";if(!n)return;Fe.trackUIInteraction({area:"popular_mv_tool",action:"shot_last_frame_generation_opened",control:"generate_last_frame",source:"mv_creator_generate_page",metadata:{shotId:a.id,shotIndex:r,hasDraft:!!a.last_frame_draft}});const l=Ft(n,R,Z,{shot:a,characters:U}),f=a.last_frame_draft,h=f?Ge(f.images||[]):void 0,x=`mv_${e.id}_shot${a.id}_last`,A=ct(a,r),D=!f&&A?[{url:A,name:"尾帧"}]:void 0,C=bt(a);k(Ct.aiImageGeneration,{initialPrompt:(f==null?void 0:f.prompt)||l,initialKnowledgeContextRefs:T,batchId:x,initialAspectRatio:(f==null?void 0:f.aspectRatio)??Xe,initialModel:b||void 0,initialModelRef:se,autoInsertToCanvas:!1,initialImages:_t(h,D,C),onDraftChange:B=>Qe(a.id,"last",B)})},[e.id,R,Z,U,T,k,ct,b,se,_t,bt,Qe,Xe,Ge]),Ot=s.useCallback(async(a,r)=>{Fe.trackUIInteraction({area:"popular_mv_tool",action:"shot_video_generation_opened",control:"generate_shot_video",source:"mv_creator_generate_page",metadata:{shotId:a.id,shotIndex:r,hasDraft:!!a.video_draft}});const n=a.video_draft,l=`mv_${e.id}_shot${a.id}_video`,f=[];a.generated_first_frame_url&&f.push({url:a.generated_first_frame_url,name:"首帧"});const h=ct(a,r);h&&f.push({url:h,name:"尾帧"});const x=Ge((n==null?void 0:n.images)||[]),A=x.length>0?x:f.length>0?f:void 0,D=ba(a,R,Z,{referenceImageDescriptions:ks(A)});if(!D)return;const C=String((n==null?void 0:n.duration)??Le),B=oe.durationOptions.some(ie=>ie.value===C)?(n==null?void 0:n.duration)??Le:void 0,O=oe.sizeOptions.some(ie=>ie.value===((n==null?void 0:n.size)??Se))?(n==null?void 0:n.size)??Se:void 0;k(Ct.aiVideoGeneration,{initialPrompt:(n==null?void 0:n.prompt)||D,initialKnowledgeContextRefs:T,initialImages:A,initialDuration:B,initialSize:O,initialModel:ee||void 0,initialModelRef:re,batchId:l,autoInsertToCanvas:!1,onDraftChange:ie=>Qe(a.id,"video",ie)})},[e.id,R,Z,T,Le,Se,ee,oe,re,k,ct,Qe,Ge]),Bt=s.useCallback((a,r)=>{const n=r==="first"?"generated_first_frame_url":r==="last"?"generated_last_frame_url":"generated_video_url",l=u.map(f=>f.id===a?{...f,[n]:void 0,suppressed_generated_urls:f[n]?{...f.suppressed_generated_urls||{},[r]:f[n]}:f.suppressed_generated_urls}:f);le(e.id,Ke(e,l)).then(f=>{i(f),o({...e,editedShots:l})})},[e,u,o,i]),la=s.useCallback(async(a,r,n)=>{if(!a.generated_video_url)return;const l=n==="next-first"?u[r+1]:u[r-1];if(!l)return;const f=n==="next-first"?"first":"last",h=n==="next-first"?"last":"first",x=await wa(a.generated_video_url,l.id,f,h);if(!x)return;const A=f==="first"?"generated_first_frame_url":"generated_last_frame_url",D=u.map(C=>C.id===l.id?{...C,[A]:x}:C);le(e.id,Ke(e,D)).then(C=>{i(C),o({...e,editedShots:D})})},[e,u,o,i]),ca=s.useCallback(async(a,r,n)=>{const l=a[r];if(!l||l.generated_video_url===n)return S.current;const f=S.current.map(h=>h.id===l.id?{...h,generated_video_url:n}:h);return await Y(f),f},[Y]),da=s.useCallback(async(a,r)=>{const n=S.current,l=n.find(h=>h.id===a);if(!l||l.generated_first_frame_url===r)return n;const f=n.map(h=>h.id===a?{...h,generated_first_frame_url:r}:h);return await Y(f),f},[Y]),ua=s.useCallback(async(a,r)=>{const n=S.current,l=n.find(h=>h.id===a);if(!l||l.generated_last_frame_url===r)return n;const f=n.map(h=>h.id===a?{...h,generated_last_frame_url:r}:h);return await Y(f),f},[Y]),St=s.useCallback(async(a,r,n)=>{var O,ie,ke;const l=n==="first"?a.first_frame_prompt||a.description||"":a.last_frame_prompt||"";if(!l)return null;const f=Ft(l,R,Z,{shot:a,characters:r}),h=[...V];if(a.character_ids&&a.character_ids.length>0)for(const E of a.character_ids){const j=r.find(w=>w.id===E);j!=null&&j.referenceImageUrl&&!h.includes(j.referenceImageUrl)&&h.push(j.referenceImageUrl)}const x=`mv_${e.id}_shot${a.id}_${n}`,A=await Gt.executeTool({name:"generate_image",arguments:{prompt:f.trim(),count:1,size:vt,referenceImages:h.length>0?h:void 0,knowledgeContextRefs:T,batchId:x,autoInsertToCanvas:!1,...b?{model:b,modelRef:se}:{},...c?{params:c}:{}}},{mode:"queue"}),D=A.taskId||((O=A.data)==null?void 0:O.taskId);if(!A.success||!D)return null;L.current.add(D);let C=null;try{C=await Kt(D,(ie=z.current)==null?void 0:ie.signal)}finally{L.current.delete(D)}if(!(C!=null&&C.success))return null;const B=C.task||Ce.getTask(D);return((ke=B==null?void 0:B.result)==null?void 0:ke.url)||null},[e.id,R,Z,T,c,vt,b,se,V]),ma=s.useCallback((a,r)=>St(a,r,"first"),[St]),fa=s.useCallback((a,r)=>St(a,r,"last"),[St]),pa=s.useCallback(async(a,r,n,l,f)=>{var G;const h=n.find(X=>X.id===a.id)||n[r]||a,x=h.generated_first_frame_url,A=f||h.generated_last_frame_url,D=(h.character_ids||[]).map(X=>{var K;return(K=l.find(H=>H.id===X))==null?void 0:K.referenceImageUrl}).filter(X=>!!X),C=Array.from(new Set([...V])),{referenceImages:B,referenceImageDescriptions:O}=Ws({model:ee,firstFrameUrl:x,lastFrameUrl:A,extraReferenceUrls:C,characterReferenceUrls:D}),ie=ba(h,R,Z,{referenceImageDescriptions:O});if(!ie)return null;const ke=`mv_${e.id}_shot${a.id}_video`,E={...Pe.extraParams,...oe.provider==="seedance"?{aspect_ratio:lt}:{}},j=await Gt.executeTool({name:"generate_video",arguments:{prompt:ie,size:Pe.size,seconds:Pe.duration,count:1,batchId:ke,model:ee,modelRef:re,referenceImages:B,knowledgeContextRefs:T,autoInsertToCanvas:!1,params:Object.keys(E).length>0?E:void 0}},{mode:"queue"}),w=j.taskId||((G=j.data)==null?void 0:G.taskId);if(!j.success||!w)throw new Error(j.error||"创建视频任务失败");return w},[R,Z,V,e.id,T,Pe,ee,oe.provider,re,lt]),as=s.useCallback(()=>{var a;v.current=!0,fe(r=>r.running?{...r,stopping:!0}:r);for(const r of L.current)Ce.cancelTask(r);L.current.clear(),(a=z.current)==null||a.abort()},[]);s.useEffect(()=>()=>{var a;v.current=!0,(a=z.current)==null||a.abort()},[]);const ss=s.useCallback(async()=>{var r,n,l;if(W.current||ue.running)return;W.current=!0,Fe.trackUIInteraction({area:"popular_mv_tool",action:"batch_video_generation_started",control:"generate_all_videos",source:"mv_creator_generate_page",metadata:{shotCount:S.current.length,charactersCount:((r=M.current.characters)==null?void 0:r.length)||0,insertToCanvasRequested:Oe,hasBoard:!!$}});let a=Oe;a&&!$&&(et.warning("画布未就绪,本次将只生成不插入画布"),a=!1),await sa(),v.current=!1,z.current=new AbortController,L.current.clear(),fe({running:!0,stopping:!1,currentIndex:-1,completedCount:0,retryCount:0});try{const h=(M.current.characters||[]).filter(E=>!E.referenceImageUrl);if(h.length>0&&!v.current){const j=(await Promise.all(h.map(async w=>{var K,H,Me;if(v.current)return null;const G=`mv_${e.id}_char${w.id}_ref`,X=_a(w,R,Z);try{const me=await Gt.executeTool({name:"generate_image",arguments:{prompt:X,count:1,size:vt,knowledgeContextRefs:T,batchId:G,autoInsertToCanvas:!1,assetMetadata:{category:zt.CHARACTER,characterName:w.name,characterPrompt:X},...b?{model:b,modelRef:se}:{},...c?{params:c}:{}}},{mode:"queue"}),Te=me.taskId||((K=me.data)==null?void 0:K.taskId);if(!Te)return null;L.current.add(Te);let Ae=null;try{if(v.current)return Ce.cancelTask(Te),null;Ae=await Kt(Te,(H=z.current)==null?void 0:H.signal)}finally{L.current.delete(Te)}if(!(Ae!=null&&Ae.success))return null;const ve=Ae.task||Ce.getTask(Te),ze=(Me=ve==null?void 0:ve.result)==null?void 0:Me.url;return ze?{charId:w.id,url:ze}:null}catch(me){return v.current||console.error("[MVCreator] Character reference generation failed:",{characterId:w.id,error:me}),null}}))).filter(w=>!!(w!=null&&w.url));if(j.length>0){const w=new Map(j.map(K=>[K.charId,K.url])),X=(M.current.characters||[]).map(K=>{const H=w.get(K.id);return H?{...K,referenceImageUrl:H}:K});await g({characters:X})}}let x=0;const A=new Set,D=(E,j=0)=>{A.has(E)||(A.add(E),x+=1,fe(w=>({...w,currentIndex:E,completedCount:x,retryCount:j})))},C=S.current,B=new Map,O=E=>{var X;const j=S.current.find(K=>K.id===E.id)||E;if(j.generated_first_frame_url)return Promise.resolve(j.generated_first_frame_url);const w=(X=B.get(E.id))==null?void 0:X.first;if(w)return w;const G=(async()=>{const K=M.current.characters||[],H=await ma(j,K);return H&&!v.current&&await da(j.id,H),H})();return B.set(E.id,{...B.get(E.id)||{},first:G}),G},ie=E=>{var X,K;const j=S.current.find(H=>H.id===E.id)||E;if(j.generated_last_frame_url)return Promise.resolve(j.generated_last_frame_url);if(!((X=j.last_frame_prompt)!=null&&X.trim()))return Promise.resolve(null);const w=(K=B.get(E.id))==null?void 0:K.last;if(w)return w;const G=(async()=>{const H=M.current.characters||[],Me=await fa(j,H);return Me&&!v.current&&await ua(j.id,Me),Me})();return B.set(E.id,{...B.get(E.id)||{},last:G}),G};for(let E=0;E<C.length;E+=1){const j=C[E],w=C[E+1];O(j).catch(G=>(v.current||console.error("[MVCreator] Batch first frame generation failed:",{shotId:j.id,error:G}),null)),w&&!j.generated_last_frame_url&&!((n=j.last_frame_prompt)!=null&&n.trim())?O(w).catch(G=>(v.current||console.error("[MVCreator] Batch next first frame generation failed:",{shotId:w.id,error:G}),null)):(l=j.last_frame_prompt)!=null&&l.trim()&&ie(j).catch(G=>(v.current||console.error("[MVCreator] Batch last frame generation failed:",{shotId:j.id,error:G}),null))}const ke=async(E,j)=>{var Me,me,Te,Ae;if(v.current)return;let w=S.current.find(ve=>ve.id===E.id)||E;if(fe(ve=>({...ve,currentIndex:j,retryCount:0})),w.generated_video_url){a&&await Pt(w.generated_video_url),D(j);return}const G=await O(w);if(G&&(w={...w,generated_first_frame_url:G}),w=S.current.find(ve=>ve.id===w.id)||w,!w.generated_first_frame_url){D(j);return}let X=w.generated_last_frame_url;if(!X)if((Me=w.last_frame_prompt)!=null&&Me.trim())X=await ie(w)||void 0;else{const ve=C[j+1];X=ve&&await O(ve)||void 0}if(v.current)return;let K=0,H=null;for(;!v.current;){if(!H){const qe=S.current,Lt=M.current.characters||[];H=await pa(qe.find(dt=>dt.id===w.id)||w,j,qe,Lt,X)}if(!H)break;p.current.add(H),L.current.add(H);const ve=K;fe(qe=>({...qe,currentIndex:j,retryCount:ve}));let ze=null;try{ze=await Kt(H,(me=z.current)==null?void 0:me.signal)}finally{L.current.delete(H)}if(v.current||!ze)break;const Re=ze.task||Ce.getTask(H),Ye=(Te=Re==null?void 0:Re.result)==null?void 0:Te.url;if(ze.success&&Re&&Ye){await ca(S.current,j,Ye),a&&await Pt(Ye),D(j,K);break}if((Re==null?void 0:Re.status)===$e.FAILED){const qe=Ys(Re,ze.error);if(qe){v.current=!0;for(const dt of L.current)Ce.cancelTask(dt);L.current.clear(),(Ae=z.current)==null||Ae.abort(),et.error(`视频生成失败且不可重试,已停止:${qe}`);break}K+=1;const Lt=K;fe(dt=>({...dt,currentIndex:j,retryCount:Lt})),Ce.retryTask(H);continue}H=null}};await Promise.allSettled(C.map((E,j)=>ke(E,j).catch(w=>{v.current||console.error("[MVCreator] Batch shot pipeline failed:",{shotId:E.id,error:w})}).finally(()=>D(j))))}finally{W.current=!1,L.current.clear(),z.current=null,fe({running:!1,stopping:!1,currentIndex:-1,completedCount:0,retryCount:0})}},[ue.running,pa,sa,ma,fa,R,Z,Y,g,e.id,T,b,c,vt,se,Pt,Oe,da,ua,ca,$]),rs=s.useCallback(async()=>{const a=pr(M.current,S.current);await g({...Ke(M.current,a.shots),characters:a.characters,generatedAssetsResetAt:Date.now()})},[g]),It=s.useMemo(()=>{const[a,r]=lt.split(":").map(Number);if(!a||!r)return{};const n=Math.round(54*a/r);return{width:Math.max(n,48),height:n<48?Math.round(48*r/a):54}},[lt]);return t.jsxs("div",{className:"va-page",children:[t.jsxs("div",{className:"va-batch-config",children:[t.jsx("div",{className:"va-batch-config-title",children:"批量生成配置"}),t.jsx(Gs,{images:I,onImagesChange:F,multiple:!0,label:"参考图 (可选)"}),t.jsx(ea,{value:T,onChange:N,disabled:ue.running,className:"mv-knowledge-context-selector"}),U.length>0&&t.jsxs("div",{className:"va-characters",children:[t.jsx("div",{className:"va-characters-title",children:"角色"}),U.map(a=>t.jsxs("div",{className:"va-character-item",children:[t.jsxs("div",{className:"va-character-info",children:[t.jsx("span",{className:"va-character-name",children:a.name}),t.jsx("span",{className:"va-character-desc",children:a.description})]}),t.jsxs("div",{className:"va-character-ref",children:[a.referenceImageUrl?t.jsxs("div",{className:"va-character-ref-thumb",children:[t.jsx(ut,{src:a.referenceImageUrl,alt:a.name,showSkeleton:!1,eager:!0}),t.jsx("button",{className:"va-shot-frame-delete",onClick:()=>void Ie(a.id,void 0),children:"×"})]}):t.jsx("span",{className:"va-character-ref-empty",children:"未设置"}),t.jsx("button",{onClick:()=>Xa(a),children:"生成"}),t.jsx("button",{onClick:()=>te(a.id),children:"选主体"})]})]},a.id))]}),t.jsxs("div",{className:"va-product-form",children:[t.jsxs("div",{className:"va-model-select",children:[t.jsx("label",{className:"va-model-label",children:"图片模型"}),t.jsx(Nt,{variant:"form",selectedModel:b,selectedSelectionKey:Ne(b,se),onSelect:ae,models:ce,placement:"down",placeholder:"选择图片模型"}),je.length>0&&t.jsx(ka,{selectedParams:q,onParamChange:we,compatibleParams:je,modelId:b,placement:"down"})]}),t.jsxs("div",{className:"va-model-select",children:[t.jsx("label",{className:"va-model-label",children:"视频模型"}),t.jsx(Nt,{variant:"form",selectedModel:ee,selectedSelectionKey:Ne(ee,re),onSelect:pe,models:J,placement:"down",placeholder:"选择视频模型"}),be.length>0&&t.jsx(ka,{selectedParams:ne,onParamChange:d,compatibleParams:be,modelId:ee,placement:"down"})]})]}),ue.running&&t.jsxs("div",{className:"va-batch-config-title",children:["正在并行生成,已完成 ",ue.completedCount,"/",u.length," 段",ue.retryCount>0?`,已重试 ${ue.retryCount} 次`:""]}),t.jsxs("div",{className:"va-page-actions",children:[m&&t.jsx("button",{onClick:m,children:"重新开始"}),t.jsx("button",{onClick:rs,children:"重置生成"}),t.jsxs("label",{className:"va-inline-checkbox",children:[t.jsx("input",{type:"checkbox",checked:Oe,onChange:a=>he(a.target.checked)}),"生成后插入画布"]}),t.jsx("button",{onClick:ss,disabled:ue.running,children:"全部→生成视频"}),ue.running&&t.jsx("button",{onClick:as,children:ue.stopping?"停止中…":"停止全部生成"})]})]}),t.jsx("div",{className:"va-shots",children:u.map((a,r)=>t.jsx(Qt,{shot:a,index:r,actions:t.jsxs(t.Fragment,{children:[a.generated_first_frame_url?t.jsxs("div",{className:"va-shot-frame-thumb",style:It,onMouseEnter:n=>pt(a.generated_first_frame_url,"image",n),onMouseLeave:ht,children:[t.jsx(ut,{src:a.generated_first_frame_url,alt:"首帧",showSkeleton:!1,eager:!0,onClick:()=>Dt(a)}),t.jsx("button",{className:"va-shot-frame-delete",onClick:()=>Bt(a.id,"first"),children:"×"}),t.jsx("button",{className:"va-shot-frame-regen",onClick:()=>Dt(a),children:"↻"})]}):a.first_frame_prompt||a.description?t.jsxs("span",{className:"va-shot-frame-btn-group",children:[t.jsx("button",{onClick:()=>Dt(a),children:"生成首帧"}),t.jsx(tt,{content:"从素材库选择",showArrow:!1,children:t.jsx("button",{className:"va-shot-frame-library-btn",onClick:()=>ot({shotId:a.id,assetType:"first"}),children:t.jsx(qt,{})})})]}):null,(()=>{var l;const n=ct(a,r);return a.generated_last_frame_url?t.jsxs("div",{className:"va-shot-frame-thumb",style:It,onMouseEnter:f=>pt(a.generated_last_frame_url,"image",f),onMouseLeave:ht,children:[t.jsx(ut,{src:a.generated_last_frame_url,alt:"尾帧",showSkeleton:!1,eager:!0,onClick:()=>yt(a,r)}),t.jsx("button",{className:"va-shot-frame-delete",onClick:()=>Bt(a.id,"last"),children:"×"}),t.jsx("button",{className:"va-shot-frame-regen",onClick:()=>yt(a,r),children:"↻"})]}):!a.generated_last_frame_url&&n?t.jsxs("div",{className:"va-shot-frame-thumb va-shot-frame-thumb--borrowed",style:It,onMouseEnter:f=>pt(n,"image",f),onMouseLeave:ht,children:[t.jsx(ut,{src:n,alt:"尾帧(下一镜头首帧)",showSkeleton:!1,eager:!0,onClick:()=>yt(a,r)}),t.jsx("span",{className:"va-shot-frame-label",children:"下一镜头首帧"})]}):(l=a.last_frame_prompt)!=null&&l.trim()?t.jsxs("span",{className:"va-shot-frame-btn-group",children:[t.jsx("button",{onClick:()=>yt(a,r),children:"生成尾帧"}),t.jsx(tt,{content:"从素材库选择",showArrow:!1,children:t.jsx("button",{className:"va-shot-frame-library-btn",onClick:()=>ot({shotId:a.id,assetType:"last"}),children:t.jsx(qt,{})})})]}):null})(),a.generated_video_url?t.jsxs("div",{className:"va-shot-video-wrap",children:[t.jsxs("div",{className:"va-shot-frame-thumb",style:It,onMouseEnter:n=>pt(a.generated_video_url,"video",n),onMouseLeave:ht,children:[t.jsx(zs,{src:a.generated_video_url,alt:"生成视频缩略图",className:"va-shot-frame-media",thumbnailSize:"small",onClick:()=>Ot(a,r),videoProps:{muted:!0,preload:"metadata",title:"重新生成视频"}}),t.jsx("button",{className:"va-shot-frame-delete",onClick:()=>Bt(a.id,"video"),children:"×"}),t.jsx("button",{className:"va-shot-frame-regen",onClick:()=>Ot(a,r),children:"↻"})]}),(r>0||r<u.length-1)&&t.jsxs("div",{className:"va-shot-frame-transfer",children:[r>0&&t.jsx(tt,{content:"提取首帧 → 前一片段尾帧",showArrow:!1,children:t.jsx("button",{className:"va-shot-frame-transfer-btn",onClick:()=>la(a,r,"prev-last"),children:t.jsx(Ts,{size:12})})}),r<u.length-1&&t.jsx(tt,{content:"提取尾帧 → 后一片段首帧",showArrow:!1,children:t.jsx("button",{className:"va-shot-frame-transfer-btn",onClick:()=>la(a,r,"next-first"),children:t.jsx(Ns,{size:12})})})]})]}):a.description?t.jsxs("span",{className:"va-shot-frame-btn-group",children:[t.jsx("button",{onClick:()=>Ot(a,r),children:"生成视频"}),t.jsx(tt,{content:"从素材库插入视频",showArrow:!1,children:t.jsx("button",{className:"va-shot-frame-library-btn",onClick:()=>ot({shotId:a.id,assetType:"video"}),children:t.jsx(qt,{})})})]}):null]})},a.id))}),t.jsxs("div",{className:"va-page-actions mv-generate-footer-actions",children:[t.jsx("button",{onClick:()=>void qa(),disabled:u.length===0,children:"脚本插入画布"}),t.jsx("button",{onClick:()=>void Za(),disabled:aa||u.length===0,children:aa?`素材下载 ${Ja}%`:"素材下载 ZIP"})]}),t.jsx("div",{className:"mv-generate-footer-hint",children:"若有素材未打包成功,解压后在 ZIP 根目录运行 `sh 00.补全下载.sh` 即可按 manifest 补全下载。"}),t.jsx(Sa,{isOpen:!!Ee,onClose:()=>ot(null),mode:ya.SELECT,filterType:(Ee==null?void 0:Ee.assetType)==="video"?Ut.VIDEO:Ut.IMAGE,onSelect:Qa,selectButtonText:(Ee==null?void 0:Ee.assetType)==="video"?"使用此视频":"使用此图片"}),t.jsx(Sa,{isOpen:!!Q,onClose:()=>te(null),mode:ya.SELECT,filterType:Ut.IMAGE,filterCategory:zt.CHARACTER,onSelect:a=>{var r;if(Q){const n=(r=M.current.characters)==null?void 0:r.find(l=>l.id===Q);Ie(Q,a.url),n&&As(a,{name:n.name,prompt:n.description}).catch(l=>{console.warn("[MVCreator] Failed to mark asset as character:",l)})}te(null)},selectButtonText:"使用此主体"}),Ze&&Ms.createPortal(t.jsx("div",{className:"mv-hover-preview",style:{left:`${Ze.x}px`,top:`${Ze.y}px`},onMouseEnter:es,onMouseLeave:ts,children:Ze.type==="image"?t.jsx(ut,{src:Ze.url,alt:"Preview",showSkeleton:!1,eager:!0}):t.jsx("video",{src:Ze.url,controls:!0,muted:!0,preload:"metadata"})}),document.body)]})};function gr(e){switch(e){case $e.COMPLETED:return"已完成";case $e.PROCESSING:return"进行中";case $e.PENDING:return"等待中";case $e.FAILED:return"失败";default:return""}}function _r(e){switch(e){case $e.COMPLETED:return"completed";case $e.PROCESSING:return"processing";case $e.PENDING:return"pending";case $e.FAILED:return"failed";default:return"pending"}}function br(e){const o=new Date(e);return`${o.getMonth()+1}/${o.getDate()} ${String(o.getHours()).padStart(2,"0")}:${String(o.getMinutes()).padStart(2,"0")}`}function yr(e){var i;const o=e.creativeBrief;return(o==null?void 0:o.purpose)||(o==null?void 0:o.directorStyle)||(o==null?void 0:o.narrativeStyle)||e.videoStyle||((i=e.musicStyleTags)==null?void 0:i.filter(Boolean).join(" / "))||"暂无概要"}const Sr=({records:e,onSelect:o,onRecordsChange:i,showStarredOnly:m=!1})=>{const u=m?e.filter(p=>p.starred):e,[y,_]=s.useState(null),[k,$]=s.useState(null),{tasks:M}=Ga(),S=s.useMemo(()=>{const p=new Map,I=new Set(e.map(T=>T.id)),F=()=>({storyboard:[],music:[],video:[],image:[]});for(const T of M){const N=T.params;if(T.type===He.CHAT&&N.mvCreatorAction==="storyboard"&&typeof N.mvCreatorRecordId=="string"&&I.has(N.mvCreatorRecordId)){const te=N.mvCreatorRecordId;xt(p,te,"storyboard",T,F);continue}const U=typeof N.batchId=="string"?N.batchId:"";if(!U.startsWith("mv_"))continue;const Q=$s(U,"mv_",I);Q&&(T.type===He.AUDIO?xt(p,Q,"music",T,F):T.type===He.VIDEO?xt(p,Q,"video",T,F):T.type===He.IMAGE&&xt(p,Q,"image",T,F))}return Ps(p)},[M,e]),v=s.useCallback(async(p,I)=>{p.stopPropagation();const F=await le(I.id,{starred:!I.starred});i(F)},[i]),W=s.useCallback((p,I)=>{p.stopPropagation(),$(I)},[]),z=s.useCallback(async()=>{if(!k)return;const p=await Xs(k);i(p),$(null)},[i,k]),L=s.useCallback((p,I)=>{p.stopPropagation(),_(F=>F===I?null:I)},[]);return u.length===0?t.jsx("div",{className:"va-page va-empty",children:t.jsx("span",{children:m?"暂无收藏":"暂无 MV 记录"})}):t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"va-page",children:t.jsx("div",{className:"va-history-list",children:u.map(p=>{const I=S.get(p.id),F=I?I.storyboard.length+I.music.length+I.video.length+I.image.length:0,T=y===p.id;return t.jsxs("div",{className:"va-history-item",onClick:()=>o(p),children:[t.jsxs("div",{className:"va-history-header",children:[t.jsxs("span",{className:"va-history-source",children:[t.jsx("span",{role:"img","aria-label":"mv",children:"🎬"})," ",p.sourceLabel]}),t.jsx("button",{className:`va-star-btn ${p.starred?"starred":""}`,onClick:N=>v(N,p),children:p.starred?"★":"☆"})]}),t.jsxs("div",{className:"va-history-meta",children:[F>0&&t.jsxs("button",{className:`va-history-expand-btn ${T?"expanded":""}`,onClick:N=>L(N,p.id),children:[t.jsx(Es,{size:12}),t.jsx("span",{children:T?"收起":"关联任务"})]}),t.jsx("span",{children:new Date(p.createdAt).toLocaleString()}),t.jsx("button",{className:"va-history-delete",onClick:N=>W(N,p.id),children:"删除"})]}),t.jsx("div",{className:"ma-history-title",children:p.musicTitle||"未命名 MV"}),t.jsx("div",{className:"ma-history-summary",children:yr(p).slice(0,80)}),p.generatedClips&&p.generatedClips.length>0&&t.jsxs("div",{className:"ma-history-clips-count",children:[p.generatedClips.length," 首音乐",p.editedShots?` · ${p.editedShots.length} 个镜头`:""]}),T&&I&&t.jsxs("div",{className:"va-history-related",onClick:N=>N.stopPropagation(),children:[I.music.length>0&&t.jsxs("div",{children:[t.jsxs("div",{className:"va-history-related-group-title",children:["音乐生成 (",I.music.length,")"]}),I.music.map(N=>t.jsx(kt,{task:N},N.id))]}),I.storyboard.length>0&&t.jsxs("div",{children:[t.jsxs("div",{className:"va-history-related-group-title",children:["分镜规划 (",I.storyboard.length,")"]}),I.storyboard.map(N=>t.jsx(kt,{task:N},N.id))]}),I.video.length>0&&t.jsxs("div",{children:[t.jsxs("div",{className:"va-history-related-group-title",children:["视频生成 (",I.video.length,")"]}),I.video.map(N=>t.jsx(kt,{task:N},N.id))]}),I.image.length>0&&t.jsxs("div",{children:[t.jsxs("div",{className:"va-history-related-group-title",children:["图片生成 (",I.image.length,")"]}),I.image.map(N=>t.jsx(kt,{task:N},N.id))]})]})]},p.id)})})}),t.jsx(Vs,{open:k!==null,title:"确认删除",description:"确定要删除这条 MV 记录吗?此操作不可撤销。",confirmText:"删除",cancelText:"取消",danger:!0,onOpenChange:p=>{p||$(null)},onConfirm:z})]})},kt=({task:e})=>t.jsx(tt,{content:gr(e.status),showArrow:!1,children:t.jsxs("div",{className:"va-history-related-task",children:[t.jsx("span",{className:`va-history-related-task-status ${_r(e.status)}`}),t.jsx("span",{className:"va-history-related-task-prompt",children:String(e.params.prompt||"").slice(0,40)||e.id.slice(0,8)}),t.jsx("span",{className:"va-history-related-task-time",children:br(e.createdAt)})]})}),Ir=[{id:"analyze",label:"分析"},{id:"script",label:"脚本"},{id:"generate",label:"生成"}],Rr=()=>{var J;const{records:e,setRecords:o,currentRecord:i,showStarred:m,setShowStarred:u,starredCount:y,selectRecord:_,updateCurrentRecord:k,restart:$,applySyncedRecord:M}=Rs({loadRecords:$t,logPrefix:"[MVCreator]"}),{page:S,setPage:v,navigateToStep:W,goToDefaultPage:z,openHistory:L,openStarred:p,toggleStarred:I}=Ds({initialPage:"analyze",defaultPage:"analyze",historyPage:"history",setShowStarred:u}),F=s.useCallback(async b=>{if(nr(b))return await ir(b)||Zt(b);const ge=lr(b);return ge?cr(b,ge):null},[]);Js({syncTask:F,applySyncedRecord:M,logPrefix:"[MVCreator]"});const T=s.useCallback(b=>{k(b)},[k]),N=s.useCallback(b=>{_(b),b.editedShots&&b.editedShots.length>0?v("generate"):(b.selectedClipId,v("analyze"))},[_,v]),U=s.useCallback(b=>{k(b)},[k]),Q=s.useCallback(()=>{$(),z()},[z,$]),te=!!(i!=null&&i.editedShots&&i.editedShots.length>0),ce=s.useMemo(()=>Ir.map((b,ge)=>({...b,disabled:!i&&ge>0||(b.id==="script"||b.id==="generate")&&!te})),[i,te]);return t.jsxs("div",{className:"video-analyzer music-analyzer mv-creator",children:[t.jsx(Os,{isHistoryPage:S==="history",showStarred:m,recordsCount:e.length,starredCount:y,currentStep:S,steps:ce,onStepNavigate:W,onBackFromHistory:z,onOpenHistory:L,onOpenStarred:p,onToggleStarred:I}),S==="analyze"&&t.jsx(rr,{existingRecord:i,onComplete:T,onRecordsChange:o,onCreateNew:Q,onNext:(J=i==null?void 0:i.editedShots)!=null&&J.length?()=>v("script"):void 0}),S==="script"&&i&&te&&t.jsx(mr,{record:i,onRecordUpdate:U,onRecordsChange:o,onNext:()=>v("generate")}),S==="generate"&&i&&te&&t.jsx(vr,{record:i,onRecordUpdate:U,onRecordsChange:o,onRestart:Q}),S==="history"&&t.jsx(Sr,{records:e,onSelect:N,onRecordsChange:o,showStarredOnly:m})]})};export{Rr as default};