ima2-gen 3.8.2 → 3.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/bin/commands/gen.js +10 -0
  2. package/docs/migration/runtime-test-inventory.md +5 -1
  3. package/lib/alphaDecode.js +18 -0
  4. package/lib/atlasCloudImageAdapter.js +6 -1
  5. package/lib/backgroundPresets.js +28 -1
  6. package/lib/generatePipeline.js +74 -5
  7. package/lib/imageBackgroundParam.js +108 -0
  8. package/lib/promptImport/gptImageHints.js +4 -1
  9. package/lib/responsesFallback.js +8 -2
  10. package/lib/responsesImageAdapter.js +10 -1
  11. package/package.json +2 -2
  12. package/routes/video.js +7 -0
  13. package/skills/ima2/SKILL.md +28 -4
  14. package/skills/ima2-front/references/asset-requirements.md +23 -8
  15. package/skills/ima2-uiux/SKILL.md +15 -4
  16. package/ui/dist/.vite/manifest.json +32 -32
  17. package/ui/dist/assets/{AgentWorkspace-bUd5NsQ_.js → AgentWorkspace-fcIXiWV6.js} +1 -1
  18. package/ui/dist/assets/AssetGenWorkspace-CqXyN9at.js +2 -0
  19. package/ui/dist/assets/{AssetsWorkspace-DO_wfFQB.js → AssetsWorkspace-xwHFVOb7.js} +1 -1
  20. package/ui/dist/assets/{CardNewsWorkspace-D3M0w8pg.js → CardNewsWorkspace-ltdjG40R.js} +1 -1
  21. package/ui/dist/assets/{GenerationRequestLogPanel-WvSV0yXP.js → GenerationRequestLogPanel-B68EUfUg.js} +1 -1
  22. package/ui/dist/assets/{HomeWorkspace-BGCBf9iK.js → HomeWorkspace-BBOG_aNm.js} +1 -1
  23. package/ui/dist/assets/KeyingPanel-Bv0n_bhk.js +1 -0
  24. package/ui/dist/assets/{NodeCanvas-DwbR2nol.js → NodeCanvas-VwdctvAW.js} +1 -1
  25. package/ui/dist/assets/{PromptBuilderPanel-KSH3ChjC.js → PromptBuilderPanel-BBMpF_3Q.js} +1 -1
  26. package/ui/dist/assets/{PromptImportDialog-CjHiCEo9.js → PromptImportDialog-D4QYbRfH.js} +2 -2
  27. package/ui/dist/assets/{PromptImportDiscoverySection-CWU-vKyM.js → PromptImportDiscoverySection-Bx7BeTFh.js} +1 -1
  28. package/ui/dist/assets/{PromptImportFolderSection-_zRnJGkJ.js → PromptImportFolderSection-Bwf60URx.js} +1 -1
  29. package/ui/dist/assets/{PromptLibraryPanel-64VN4nml.js → PromptLibraryPanel-mNG2wZkQ.js} +2 -2
  30. package/ui/dist/assets/{SettingsWorkspace-DZMNEpuq.js → SettingsWorkspace-DA5tIa0Q.js} +1 -1
  31. package/ui/dist/assets/{SpriteRecipeWorkspace-Y6GqpVHs.js → SpriteRecipeWorkspace-Da9qTQX0.js} +1 -1
  32. package/ui/dist/assets/{index-CFixfKaC.js → index-Bv1Yrz8W.js} +3 -3
  33. package/ui/dist/assets/{index-waPOg2eb.css → index-C0nfanMr.css} +1 -1
  34. package/ui/dist/assets/{index-XXtoj9ME.js → index-CxEuSZMC.js} +16 -16
  35. package/ui/dist/assets/{pptxgen.es-hCJot2gG.js → pptxgen.es-BE4CSd5F.js} +1 -1
  36. package/ui/dist/assets/{useAgentDialogFocus-PWmMjerz.js → useAgentDialogFocus-R64NV-ZZ.js} +1 -1
  37. package/ui/dist/index.html +2 -2
  38. package/ui/dist/assets/AssetGenWorkspace-8fK-K64E.js +0 -2
  39. package/ui/dist/assets/KeyingPanel-CEBLIhhu.js +0 -1
@@ -1 +0,0 @@
1
- import{u as se,a as M,b as q,p as he,j as s,ab as fe,ac as ge,ad as me}from"./index-XXtoj9ME.js";import{u as pe}from"./useAgentDialogFocus-PWmMjerz.js";function ye(){return s.jsx("svg",{viewBox:"0 0 24 24",width:"18",height:"18","aria-hidden":"true",children:s.jsx("path",{d:"M6 6l12 12M18 6 6 18",fill:"none",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round"})})}function xe({zoomed:e}){return s.jsxs("svg",{viewBox:"0 0 24 24",width:"18",height:"18","aria-hidden":"true",children:[s.jsx("circle",{cx:"10.5",cy:"10.5",r:"6.5",fill:"none",stroke:"currentColor",strokeWidth:"1.7"}),s.jsx("path",{d:"M15.5 15.5 21 21M7.5 10.5h6",fill:"none",stroke:"currentColor",strokeWidth:"1.7",strokeLinecap:"round"}),e?null:s.jsx("path",{d:"M10.5 7.5v6",stroke:"currentColor",strokeWidth:"1.7",strokeLinecap:"round"})]})}function Le({item:e,onClose:t}){const{t:n}=se(),[o,i]=M.useState(!1),l=e.metadata??null,[f,u]=M.useState(l),d=M.useId(),h=q(U=>U.setKeyingTarget),g=q(U=>U.setCuratorTarget),r=M.useCallback(()=>t(),[t]),v=pe(!0,r),a=e.mediaType==="video",m=e.kind!=="edit"&&!!e.filename,E=l??f,y=typeof E?.spriteRunId=="string"?E.spriteRunId:null,R=typeof E?.manifestPath=="string"?E.manifestPath:null,K=!!(y&&R&&e.filename),P=n(a?"assetGen.videoFallback":"assetGen.imageFallback"),x=e.prompt?.trim()||P,L=M.useCallback(()=>{h(e),t()},[e,t,h]),T=M.useCallback(()=>{!y||!R||!e.filename||(g({runId:y,atlasFile:e.filename,manifestFile:R}),t())},[e.filename,R,t,g,y]);return M.useEffect(()=>{u(l);const U=e.requestId?.startsWith("asset:")?e.requestId.slice(6):null;if(!U||l)return;let B=!0;return he(U).then(({asset:S})=>{B&&u(S.metadata)}).catch(()=>{B&&u(null)}),()=>{B=!1}},[l,e.requestId]),M.useEffect(()=>{const U=document.body.style.overflow,B=document.documentElement.style.overflow;return document.body.style.overflow="hidden",document.documentElement.style.overflow="hidden",()=>{document.body.style.overflow=U,document.documentElement.style.overflow=B}},[]),s.jsxs("div",{className:"assetgen-lightbox",role:"presentation",children:[s.jsx("button",{type:"button",className:"assetgen-lightbox__backdrop","aria-label":n("assetGen.closePreview"),onClick:r}),s.jsxs("section",{ref:v,className:"assetgen-lightbox__panel",role:"dialog","aria-modal":"true","aria-labelledby":d,children:[s.jsxs("header",{className:"assetgen-lightbox__header",children:[s.jsx("h2",{id:d,children:n("assetGen.previewDialogTitle",{prompt:x})}),s.jsx("button",{type:"button",className:"assetgen-lightbox__control","aria-label":n("assetGen.closePreview"),onClick:r,children:s.jsx(ye,{})})]}),s.jsx("div",{className:["assetgen-lightbox__stage",e.kind==="edit"?"is-keyed":"",o?"is-zoomed":""].filter(Boolean).join(" "),tabIndex:o?0:void 0,children:a?s.jsx("video",{src:e.url||e.image,poster:e.thumb||void 0,controls:!0,autoPlay:!0,muted:!0,playsInline:!0,preload:"metadata","aria-label":x}):s.jsx("img",{src:e.url||e.image,alt:x})}),!a||m||K?s.jsxs("footer",{className:"assetgen-lightbox__footer",children:[K?s.jsx("button",{type:"button",className:"assetgen-lightbox__zoom assetgen-lightbox__curate",onClick:T,children:n("spriteCurator.open")}):null,m?s.jsx("button",{type:"button",className:"assetgen-lightbox__zoom assetgen-lightbox__keybtn",onClick:L,children:n("keying.open")}):null,a?null:s.jsxs("button",{type:"button",className:"assetgen-lightbox__zoom","aria-pressed":o,"aria-label":n(o?"assetGen.zoomOut":"assetGen.zoomIn"),onClick:()=>i(U=>!U),children:[s.jsx(xe,{zoomed:o}),s.jsx("span",{children:n(o?"assetGen.zoomOut":"assetGen.zoomIn")})]})]}):null]})]})}const H={tolerance:40,softness:10,spill:50};function ee(e,t,n){const o=128-.168736*e-.331264*t+.5*n,i=128+.5*e-.418688*t-.081312*n;return[o,i]}function te(e,t,n){return .299*e+.587*t+.114*n}function ke(e,t,n,o){const i=t*n,l=new Uint8Array(i);for(let r=0;r<i;r++)e[r]<o&&(l[r]=1);const f=new Uint8Array(i),u=new Int32Array(i);let d=0,h=0;const g=r=>{l[r]&&!f[r]&&(f[r]=1,u[h++]=r)};for(let r=0;r<t;r++)g(r),g((n-1)*t+r);for(let r=0;r<n;r++)g(r*t),g(r*t+t-1);for(;d<h;){const r=u[d++],v=r%t,a=(r-v)/t;v>0&&g(r-1),v<t-1&&g(r+1),a>0&&g(r-t),a<n-1&&g(r+t)}for(let r=0;r<i;r++)l[r]&&!f[r]&&(e[r]=o)}function ne(e){const{width:t,height:n,data:o}=e;if(t<2||n<2||o.length<t*n*4)throw new Error("colorKey: image too small or malformed pixel buffer");const i=4,l=[0,Math.max(0,t-i)],f=[0,Math.max(0,n-i)],u=[],d=[],h=[];for(const r of l)for(const v of f)for(let a=v;a<Math.min(v+i,n);a++)for(let m=r;m<Math.min(r+i,t);m++){const E=(a*t+m)*4;u.push(o[E]),d.push(o[E+1]),h.push(o[E+2])}const g=r=>{const v=[...r].sort((a,m)=>a-m);return v[Math.floor(v.length/2)]};return{r:g(u),g:g(d),b:g(h)}}function be(e,t){const{width:n,height:o,data:i}=e;if(!n||!o||i.length!==n*o*4)throw new Error("colorKey: empty or malformed pixel buffer");const l=Math.max(0,Math.min(100,t.tolerance)),f=Math.max(0,Math.min(50,t.softness)),u=Math.max(0,Math.min(100,t.spill))/100,d=l/100*120,h=d+f/100*120,[g,r]=ee(t.keyColor.r,t.keyColor.g,t.keyColor.b),v=t.keyColor.r,a=t.keyColor.g,m=t.keyColor.b,E=a>v+20&&a>m+20&&a>60,R=Math.max(v,a,m)-Math.min(v,a,m)<40,K=te(v,a,m),P=10+l/100*15,x=400,L=n*o,T=new Float32Array(L);for(let b=0;b<L;b++){const k=b*4,_=i[k],A=i[k+1],I=i[k+2],[F,C]=ee(_,A,I),w=Math.hypot(F-g,C-r);if(R)if(w>P)T[b]=x;else{const N=Math.abs(te(_,A,I)-K)*.8;T[b]=Math.hypot(w,N)}else T[b]=w}const U=new Float32Array(L);for(let b=0;b<o;b++)for(let k=0;k<n;k++){const _=b*n+k;if(T[_]>=x){U[_]=x;continue}let A=0,I=0;for(let F=-1;F<=1;F++){const C=b+F;if(!(C<0||C>=o))for(let w=-1;w<=1;w++){const N=k+w;if(N<0||N>=n)continue;const G=T[C*n+N];G>=x||(A+=G,I++)}}U[_]=I>0?A/I:x}R&&ke(U,n,o,h);const B=h+u*120,S=new Uint8ClampedArray(i.length);for(let b=0;b<L;b++){const k=b*4,_=i[k],A=i[k+1],I=i[k+2],F=i[k+3],C=U[b];let w;C<=d?w=0:C<h?w=Math.pow((C-d)/(h-d),1.5)*255:w=255;let N=_,G=A,$=I;if(E&&u>0&&w>0){const W=B>d?Math.max(0,1-(C-d)/(B-d)):0;if(W>0){const X=(_+I)/2,p=Math.max(0,A-X)*W*u;G=Math.round(A-p);const j=p*.3;N=Math.min(255,Math.round(_+j)),$=Math.min(255,Math.round(I+j))}}S[k]=N,S[k+1]=G,S[k+2]=$,S[k+3]=Math.min(F,Math.round(w))}if(E&&u>0){let b=new Uint8Array(L);for(let k=0;k<o;k++)for(let _=0;_<n;_++){const A=k*n+_;if(S[A*4+3]===0)continue;let I=!1;e:for(let F=-1;F<=1;F++){const C=k+F;if(!(C<0||C>=o))for(let w=-1;w<=1;w++){const N=_+w;if(!(N<0||N>=n)&&S[(C*n+N)*4+3]===0){I=!0;break e}}}I&&(b[A]=1)}for(let k=0;k<3;k++){const _=new Uint8Array(L);for(let A=0;A<o;A++)for(let I=0;I<n;I++){const F=A*n+I;if(b[F]){_[F]=1;continue}if(S[F*4+3]===0)continue;let C=!1;for(let w=-1;w<=1&&!C;w++){const N=A+w;if(!(N<0||N>=o))for(let G=-1;G<=1&&!C;G++){const $=I+G;$<0||$>=n||b[N*n+$]&&(C=!0)}}C&&(_[F]=1)}b=_}for(let k=0;k<L;k++){if(!b[k])continue;const _=k*4,A=S[_],I=S[_+1],F=S[_+2],C=Math.max(A,F);if(I>C-8){const w=Math.max(0,C-4),N=Math.max(0,I-w);S[_+1]=Math.max(0,I-N),S[_]=Math.min(255,A+Math.round(N*.25)),S[_+2]=Math.min(255,F+Math.round(N*.25))}}}return{width:n,height:o,data:S}}function _e(e){return Math.round(Math.max(0,Math.min(100,e))*.7)}function oe(e,t,n){const o=Math.max(0,Math.min(t-1,Math.round(e.x*(t-1))));return Math.max(0,Math.min(n-1,Math.round(e.y*(n-1))))*t+o}function ve(e,t,n,o){for(const i of n)if(Math.max(Math.abs(e[t]-i.r),Math.abs(e[t+1]-i.g),Math.abs(e[t+2]-i.b))<=o)return!0;return!1}function Me(e,t,n){const{width:o,height:i,data:l}=e,f=o*i,u=new Uint8Array(f),d=new Uint8Array(f),h=new Int32Array(f),g=t.map(a=>{const m=oe(a,o,i)*4;return{r:l[m],g:l[m+1],b:l[m+2]}});let r=0;const v=a=>{d[a]||(d[a]=1,l[a*4+3]!==0&&ve(l,a*4,g,n)&&(h[r++]=a))};for(const a of t)v(oe(a,o,i));for(;r>0;){const a=h[--r];u[a]=1;const m=a%o;m>0&&v(a-1),m<o-1&&v(a+1),a>=o&&v(a-o),a<f-o&&v(a+o)}return u}function we(e,t,n,o){if(n.length===0)return;if(e.width!==t.width||e.height!==t.height||e.data.length!==t.data.length)throw new Error("wandErase: target/source buffer size mismatch");const i=Me(t,n,_e(o));for(let l=0;l<i.length;l++)i[l]&&(e.data[l*4+3]=0)}const je={reach:4,spillMaxFraction:.005},re=18,Ce=180,Ne=40,Ee=2,J=0,Se=1,ie=2,le=3;function Q(e){const t=[e.r,e.g,e.b],n=[],o=[];for(let i=0;i<3;i++)if(t[i]>=192)n.push(i);else if(t[i]<64)o.push(i);else return null;return n.length===0||o.length===0?null:{keyed:n,unkeyed:o}}function V(e,t,n,o){const i=[e,t,n];let l=0;for(const u of o.keyed)l+=i[u];let f=0;for(const u of o.unkeyed)f+=i[u];return l/o.keyed.length-f/o.unkeyed.length}function Ae(e,t,n,o){return Math.hypot(e-o.r,t-o.g,n-o.b)}function ce(e,t,n,o,i,l){const f=Math.min(l/i,1),u=1-f;if(u<=0)return[0,0,0,0];const d=(h,g)=>Math.min(255,Math.max(0,Math.round((h-f*g)/u)));return[u,d(e,o.r),d(t,o.g),d(n,o.b)]}function Ie(e,t,n,o){const i=t*n,l=255,f=new Uint8Array(i).fill(l);let u=[];for(let h=0;h<i;h++)e[h]&&(f[h]=0,u.push(h));let d=0;for(;u.length>0&&d<o;){d++;const h=[];for(const g of u){const r=g%t,v=(g-r)/t;for(let a=-1;a<=1;a++){const m=v+a;if(!(m<0||m>=n))for(let E=-1;E<=1;E++){const y=r+E;if(y<0||y>=t)continue;const R=m*t+y;f[R]===l&&(f[R]=d,h.push(R))}}}u=h}return f}function Re(e,t,n,o){const i=e.width*e.height,l=new Uint8Array(i),f=new Uint8Array(i);for(let u=0;u<i;u++){const d=u*4;if(t.data[d+3]===0){l[u]=J,f[u]=1;continue}const h=e.data[d],g=e.data[d+1],r=e.data[d+2];V(h,g,r,o)<re?l[u]=Se:Ae(h,g,r,n)<=Ce?l[u]=ie:l[u]=le}return{classes:l,keyedMask:f}}function Ue(e,t,n,o,i,l,f,u){const d=t.width*t.height,h=new Uint8Array(d);for(let g=0;g<d;g++){const r=l[g];if(!(r>0&&r<=u))continue;const v=f[g];if(v===ie){if(r>Ee)continue}else if(v!==le)continue;const a=g*4,m=t.data[a],E=t.data[a+1],y=t.data[a+2],R=V(m,E,y,o),[K,P,x,L]=ce(m,E,y,n,i,R),T=Math.round(t.data[a+3]*K);T<=0?(e.data[a]=0,e.data[a+1]=0,e.data[a+2]=0,e.data[a+3]=0):(e.data[a]=P,e.data[a+1]=x,e.data[a+2]=L,e.data[a+3]=T),h[g]=1}return h}function Te(e,t,n,o,i,l,f,u){const{width:d,height:h}=t,g=d*h;let r=0;for(let y=0;y<g;y++)l[y]!==J&&r++;const v=Math.max(32,Math.round(r*u)),a=new Float32Array(g).fill(-1);for(let y=0;y<g;y++){if(f[y]||l[y]===J)continue;const R=y*4;if(e.data[R+3]===0)continue;const K=V(t.data[R],t.data[R+1],t.data[R+2],o);K>=re&&(a[y]=K)}const m=new Uint8Array(g),E=[];for(let y=0;y<g;y++){if(a[y]<0||m[y])continue;m[y]=1,E.length=0,E.push(y);const R=[];let K=-1;for(;E.length>0;){const P=E.pop();R.push(P),a[P]>K&&(K=a[P]);const x=P%d,L=(P-x)/d;for(let T=-1;T<=1;T++){const U=L+T;if(!(U<0||U>=h))for(let B=-1;B<=1;B++){const S=x+B;if(S<0||S>=d)continue;const b=U*d+S;a[b]>=0&&!m[b]&&(m[b]=1,E.push(b))}}}if(!(R.length>v)&&!(K<=Ne))for(const P of R){const x=P*4,L=t.data[x],T=t.data[x+1],U=t.data[x+2],[B,S,b,k]=ce(L,T,U,n,i,a[P]);B<=0||(e.data[x]=S,e.data[x+1]=b,e.data[x+2]=k)}}}function De(e,t,n){if(!e.width||!e.height||e.width!==t.width||e.height!==t.height||e.data.length!==t.data.length||e.data.length!==e.width*e.height*4)throw new Error("softUnmix: empty or mismatched pixel buffers");const o=Q(n.keyColor);if(!o)return;const i=V(n.keyColor.r,n.keyColor.g,n.keyColor.b,o);if(i<=0)return;const l=Math.max(0,Math.min(254,Math.round(n.reach))),{classes:f,keyedMask:u}=Re(t,e,n.keyColor,o);let d;if(l>0){const h=Ie(u,t.width,t.height,l);d=Ue(e,t,n.keyColor,o,i,h,f,l)}else d=new Uint8Array(t.width*t.height);n.spillMaxFraction>0&&Te(e,t,n.keyColor,o,i,f,d,n.spillMaxFraction)}function ae(e,t,n){const o=`/generated/${encodeURIComponent(t)}`;return{...e,image:o,url:o,filename:t,mediaType:n,kind:"edit",requestId:`derived:${t}`,createdAt:Date.now(),providerUrl:null}}function Be(){const{t:e}=se(),t=q(c=>c.keyingTarget),n=q(c=>c.setKeyingTarget),o=q(c=>c.addAssetGenDerivedItem),i=q(c=>c.selectedProjectId),l=q(c=>c.showToast),[f,u]=M.useState("loading"),[d,h]=M.useState(!1),[g,r]=M.useState(null),[v,a]=M.useState(null),[m,E]=M.useState(H.tolerance),[y,R]=M.useState(H.softness),[K,P]=M.useState(H.spill),[x,L]=M.useState(null),[T,U]=M.useState("erase"),[B,S]=M.useState([]),[b,k]=M.useState(!0),_=M.useRef(null),A=M.useRef(null),I=M.useRef(0),F=M.useRef(null),C=M.useRef(null),w=M.useCallback(()=>{F.current?.(),F.current=null},[]),N=t?.mediaType==="video",G=t?N&&t.filename?`/api/video/frame?file=${encodeURIComponent(t.filename)}&position=0`:t.url||t.image:null;M.useEffect(()=>{if(!G)return;let c=!0;u("loading"),_.current=null,L(null),S([]),U("erase");const p=new Image;return p.onload=()=>{if(c)try{const j=document.createElement("canvas");j.width=p.naturalWidth,j.height=p.naturalHeight;const D=j.getContext("2d");if(!D)throw new Error("no 2d context");D.drawImage(p,0,0);const O=D.getImageData(0,0,j.width,j.height);_.current=O,L(ne(O)),u("ready")}catch{c&&u("error")}},p.onerror=()=>{c&&u("error")},p.src=G,()=>{c=!1,p.onload=null,p.onerror=null}},[G]),M.useEffect(()=>(C.current=t?.filename??null,w(),h(!1),a(null),r(null),w),[w,t?.filename]),M.useEffect(()=>{if(!(f!=="ready"||!x))return cancelAnimationFrame(I.current),I.current=requestAnimationFrame(()=>{const c=_.current,p=A.current;if(!(!c||!p))try{const j=be({width:c.width,height:c.height,data:c.data},{keyColor:x,tolerance:m,softness:y,spill:K});b&&Q(x)&&De(j,{width:c.width,height:c.height,data:c.data},{keyColor:x,...je}),B.length>0&&we(j,{width:c.width,height:c.height,data:c.data},B,m),p.width=j.width,p.height=j.height;const D=p.getContext("2d");if(!D)return;const O=D.createImageData(j.width,j.height);O.data.set(j.data),D.putImageData(O,0,0)}catch{u("error")}}),()=>cancelAnimationFrame(I.current)},[f,x,m,y,K,B,b]);const $=M.useCallback(c=>{const p=_.current,j=A.current;if(!p||!j)return;const D=j.getBoundingClientRect(),O=Math.max(0,Math.min(1,(c.clientX-D.left)/D.width)),Y=Math.max(0,Math.min(1,(c.clientY-D.top)/D.height));if(T==="erase"&&!N){S(de=>[...de,{x:O,y:Y}]);return}const z=Math.floor((c.clientX-D.left)/D.width*p.width),ue=Math.floor((c.clientY-D.top)/D.height*p.height),Z=(Math.max(0,Math.min(p.height-1,ue))*p.width+Math.max(0,Math.min(p.width-1,z)))*4;L({r:p.data[Z],g:p.data[Z+1],b:p.data[Z+2]})},[T,N]),W=M.useCallback(()=>{const c=A.current;c&&c.toBlob(p=>{if(!p)return;const j=URL.createObjectURL(p),D=document.createElement("a");D.href=j,D.download=`${(t?.filename||"asset").replace(/\.[a-z]+$/i,"")}-keyed.png`,D.click(),URL.revokeObjectURL(j)},"image/png")},[t]),X=M.useCallback(()=>{const c=A.current;if(!(!c||!t?.filename||d)){if(h(!0),r(null),N){fe({source:t.filename,keyParams:{tolerance:m,softness:y,keyColor:x??void 0},projectId:i,name:`${(t.prompt||"asset").trim().slice(0,60)} (keyed)`}).then(({requestId:p})=>{if(C.current!==t.filename)return;a(0),w();const j=ge(p,null,(D,O)=>{const Y=O&&typeof O=="object"?O:{};if(D==="keying-progress"){const z=Y.outTimeMs;a(typeof z=="number"&&Number.isFinite(z)?z:0)}else if(D==="keying-done"){w();const z=Y.filePath;if(typeof z=="string"&&z.trim()){o(ae(t,z.trim(),"video")),h(!1),a(null),l(e("keying.videoSaved")),n(null);return}h(!1),a(null),r(e("keying.saveError"))}else D==="keying-error"&&(w(),h(!1),a(null),r(typeof Y.error=="string"&&Y.error?Y.error:e("keying.saveError")))});F.current=j}).catch(p=>{C.current===t.filename&&(h(!1),r(p instanceof Error?p.message:e("keying.saveError")))});return}c.toBlob(p=>{if(C.current===t.filename){if(!p){h(!1),r(e("keying.saveError"));return}me(p,{source:t.filename,projectId:i,name:`${(t.prompt||"asset").trim().slice(0,60)} (keyed)`,meta:{keyParams:{tolerance:m,softness:y,spill:K},prompt:t.prompt}}).then(({filePath:j})=>{if(C.current===t.filename){if(typeof j!="string"||!j.trim())throw new Error(e("keying.saveError"));o(ae(t,j.trim(),"image")),l(e("keying.saved")),n(null)}}).catch(j=>{C.current===t.filename&&r(j instanceof Error?j.message:e("keying.saveError"))}).finally(()=>{C.current===t.filename&&h(!1)})}},"image/png")}},[t,d,N,x,i,m,y,K,w,o,l,n,e]);return M.useEffect(()=>{const c=p=>{p.key==="Escape"&&n(null)};return window.addEventListener("keydown",c),()=>window.removeEventListener("keydown",c)},[n]),t?s.jsx("div",{className:"assetgen-popup-backdrop",onClick:()=>n(null),children:s.jsxs("div",{className:"keying-panel",role:"dialog","aria-modal":"true","aria-label":e("keying.title"),onClick:c=>c.stopPropagation(),children:[s.jsxs("header",{className:"keying-panel__head",children:[s.jsx("h2",{children:e("keying.title")}),x?s.jsxs("span",{className:"keying-panel__key",title:e("keying.keyColor"),children:[N?null:s.jsxs("span",{className:"keying-panel__modes",role:"group","aria-label":e("keying.clickMode"),children:[s.jsx("button",{type:"button",className:T==="erase"?"is-active":"","aria-pressed":T==="erase",onClick:()=>U("erase"),children:e("keying.modeErase")}),s.jsx("button",{type:"button",className:T==="pick"?"is-active":"","aria-pressed":T==="pick",onClick:()=>U("pick"),children:e("keying.modePick")})]}),B.length>0?s.jsx("button",{type:"button",className:"keying-panel__undo",onClick:()=>S(c=>c.slice(0,-1)),children:e("keying.undoClick",{count:String(B.length)})}):null,s.jsx("span",{className:"assetgen-bg-picker__swatch",style:{background:`rgb(${x.r},${x.g},${x.b})`},"aria-hidden":"true"}),s.jsx("span",{className:"keying-panel__hint",children:e(T==="erase"&&!N?"keying.eraseHint":"keying.pickHint")})]}):null]}),s.jsx("div",{className:"keying-panel__compare","aria-busy":f==="loading",children:f==="error"?s.jsxs("div",{className:"keying-panel__error",role:"alert",children:[s.jsx("p",{children:e("keying.loadError")}),s.jsx("button",{type:"button",onClick:()=>n(null),children:e("project.close")})]}):s.jsxs(s.Fragment,{children:[s.jsxs("figure",{className:"keying-panel__preview",children:[s.jsx("figcaption",{className:"keying-panel__preview-label",children:e("keying.original")}),s.jsx("div",{className:"keying-panel__stage keying-panel__stage--original",children:s.jsx("img",{src:G??"",alt:e("keying.originalAlt")})})]}),s.jsxs("figure",{className:"keying-panel__preview",children:[s.jsx("figcaption",{className:"keying-panel__preview-label",children:e("keying.removed")}),s.jsxs("div",{className:"keying-panel__stage",children:[s.jsx("canvas",{ref:A,className:"keying-panel__canvas",onClick:$,"aria-label":e("keying.previewAlt")}),f==="loading"?s.jsx("span",{className:"keying-panel__loading",role:"status",children:e("keying.previewLoading")}):null]})]})]})}),s.jsxs("details",{className:"keying-panel__advanced",children:[s.jsx("summary",{children:e("keying.advanced")}),s.jsxs("div",{className:"keying-panel__controls",children:[s.jsxs("label",{children:[e("keying.tolerance")," ",s.jsx("output",{children:m}),s.jsx("input",{type:"range",min:0,max:100,value:m,onChange:c=>E(Number(c.target.value))})]}),s.jsxs("label",{children:[e("keying.softness")," ",s.jsx("output",{children:y}),s.jsx("input",{type:"range",min:0,max:50,value:y,onChange:c=>R(Number(c.target.value))})]}),s.jsxs("label",{children:[e("keying.spill")," ",s.jsx("output",{children:K}),s.jsx("input",{type:"range",min:0,max:100,value:K,onChange:c=>P(Number(c.target.value))})]}),s.jsxs("label",{className:"keying-panel__unmix",children:[s.jsx("input",{type:"checkbox",checked:b,disabled:!x||!Q(x),onChange:c=>k(c.target.checked)}),e("keying.unmix"),s.jsx("span",{className:"keying-panel__hint",children:e("keying.unmixHint")})]}),s.jsx("button",{type:"button",className:"keying-panel__reset",onClick:()=>{E(H.tolerance),R(H.softness),P(H.spill),S([]),k(!0),_.current&&L(ne(_.current))},children:e("keying.reset")})]})]}),s.jsxs("footer",{className:"keying-panel__actions",children:[g?s.jsx("span",{className:"keying-panel__save-error",role:"alert",children:g}):null,s.jsx("button",{type:"button",className:"assetgen-generate",disabled:f!=="ready"||d||!t.filename,onClick:X,children:d?v!==null?e("keying.videoKeying",{seconds:String(Math.round(v/1e3))}):e("keying.saving"):e(N?"keying.videoSave":"keying.save")}),N?null:s.jsx("button",{type:"button",className:"assetgen-popup__close",disabled:f!=="ready",onClick:W,children:e("keying.download")}),s.jsx("button",{type:"button",className:"assetgen-popup__close",onClick:()=>n(null),children:e("project.close")})]})]})}):null}export{Le as A,Be as K};