diff --git a/dist/copilot_web/App-DU9tUae4.js b/dist/copilot_web/App-B_5DJBtC.js similarity index 95% rename from dist/copilot_web/App-DU9tUae4.js rename to dist/copilot_web/App-B_5DJBtC.js index 9bc061f..ef93826 100644 --- a/dist/copilot_web/App-DU9tUae4.js +++ b/dist/copilot_web/App-B_5DJBtC.js @@ -1,6 +1,6 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["copilot_web/workflowChat-Cr_yyziA.js","copilot_web/input.js","copilot_web/vendor-markdown-Dek94WS0.js","copilot_web/vendor-react-V04_Axys.js","copilot_web/message-components-D3rPBq8S.js","copilot_web/assets/input-CeTzrUyG.css"].map(path => { +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["copilot_web/workflowChat-m824ZHEN.js","copilot_web/input.js","copilot_web/vendor-markdown-Dek94WS0.js","copilot_web/vendor-react-V04_Axys.js","copilot_web/message-components-D3rPBq8S.js","copilot_web/assets/input-CeTzrUyG.css"].map(path => { const apiBase = window.comfyAPI?.api?.api?.api_base; const prefix = apiBase ? `${apiBase.substring(1)}/` : ''; return `${prefix}${path}`; }))))=>i.map(i=>d[i]); -import{_ as E}from"./input.js";import{j as s}from"./vendor-markdown-Dek94WS0.js";import{r as n,R as w}from"./vendor-react-V04_Axys.js";import{C as v}from"./message-components-D3rPBq8S.js";const y=9999999,x={EXPLAIN_NODE:"copilot:explain-node"},D="/copilot_web/assets/logo-BTZhX0BN.png";function _(e={}){const[u,l]=n.useState({x:e.initialX??window.innerWidth-160,y:e.initialY??20}),[o,r]=n.useState(!1),[a,m]=n.useState({x:0,y:0}),[d,c]=n.useState(0),[g,b]=n.useState({x:0,y:0}),f=n.useCallback(t=>{if(o){const i=Math.min(Math.max(0,t.clientX-g.x),window.innerWidth-(e.boundaryPadding?.right??100)),p=Math.min(Math.max(0,t.clientY-g.y),window.innerHeight-(e.boundaryPadding?.bottom??40));l({x:i,y:p})}},[o,g,e.boundaryPadding]),h=n.useCallback(t=>{if(o){const i=Math.sqrt(Math.pow(t.clientX-a.x,2)+Math.pow(t.clientY-a.y,2)),p=Date.now()-d;i<5&&p<200&&e.onClick?.()}r(!1)},[o,a,d,e.onClick]);return n.useEffect(()=>(o&&(document.addEventListener("mousemove",f),document.addEventListener("mouseup",h)),()=>{document.removeEventListener("mousemove",f),document.removeEventListener("mouseup",h)}),[o,f,h]),{position:u,isDragging:o,handleMouseDown:t=>{t.preventDefault(),r(!0),c(Date.now()),m({x:t.clientX,y:t.clientY});const i=t.currentTarget.getBoundingClientRect();b({x:t.clientX-i.left,y:t.clientY-i.top})}}}const C=w.lazy(()=>E(()=>import("./workflowChat-Cr_yyziA.js").then(e=>e.w),__vite__mapDeps([0,1,2,3,4,5])).then(e=>({default:e.default})));function M(){const e=n.useRef(null),[u,l]=n.useState(!1),[o,r]=n.useState(!1),{position:a,isDragging:m,handleMouseDown:d}=_({boundaryPadding:{right:100,bottom:40},onClick:()=>l(!0)});return n.useEffect(()=>{const c=()=>{l(!0),r(!0)};return window.addEventListener(x.EXPLAIN_NODE,c),()=>window.removeEventListener(x.EXPLAIN_NODE,c)},[]),a?s.jsx(v,{children:s.jsx("div",{ref:e,children:s.jsxs("div",{className:"fixed",style:{zIndex:y,left:a.x,top:a.y,cursor:m?"grabbing":"grab"},children:[s.jsxs("button",{onMouseDown:d,className:"px-2 py-1 border border-gray-300 rounded-md bg-white text-black hover:bg-blue-300 hover:font-bold transition-colors select-none w-40 flex items-center space-x-1",style:{marginLeft:"-40px"},children:[s.jsx("img",{src:D,alt:"ComfyUI-Copilot Logo",className:"h-8 w-8"}),s.jsx("span",{className:"text-[14px] font-medium text-gray-800",children:"ComfyUI-Copilot"})]}),s.jsx(w.Suspense,{fallback:s.jsx("div",{children:"Loading..."}),children:s.jsx(C,{onClose:()=>{l(!1),r(!1)},visible:u,triggerUsage:o,onUsageTriggered:()=>r(!1)})})]})})}):null}const I=Object.freeze(Object.defineProperty({__proto__:null,default:M},Symbol.toStringTag,{value:"Module"}));export{I as A,D as l}; +import{_ as E}from"./input.js";import{j as s}from"./vendor-markdown-Dek94WS0.js";import{r as n,R as w}from"./vendor-react-V04_Axys.js";import{C as v}from"./message-components-D3rPBq8S.js";const y=9999999,x={EXPLAIN_NODE:"copilot:explain-node"},D="/copilot_web/assets/logo-BTZhX0BN.png";function _(e={}){const[u,l]=n.useState({x:e.initialX??window.innerWidth-160,y:e.initialY??20}),[o,r]=n.useState(!1),[a,m]=n.useState({x:0,y:0}),[d,c]=n.useState(0),[g,b]=n.useState({x:0,y:0}),f=n.useCallback(t=>{if(o){const i=Math.min(Math.max(0,t.clientX-g.x),window.innerWidth-(e.boundaryPadding?.right??100)),p=Math.min(Math.max(0,t.clientY-g.y),window.innerHeight-(e.boundaryPadding?.bottom??40));l({x:i,y:p})}},[o,g,e.boundaryPadding]),h=n.useCallback(t=>{if(o){const i=Math.sqrt(Math.pow(t.clientX-a.x,2)+Math.pow(t.clientY-a.y,2)),p=Date.now()-d;i<5&&p<200&&e.onClick?.()}r(!1)},[o,a,d,e.onClick]);return n.useEffect(()=>(o&&(document.addEventListener("mousemove",f),document.addEventListener("mouseup",h)),()=>{document.removeEventListener("mousemove",f),document.removeEventListener("mouseup",h)}),[o,f,h]),{position:u,isDragging:o,handleMouseDown:t=>{t.preventDefault(),r(!0),c(Date.now()),m({x:t.clientX,y:t.clientY});const i=t.currentTarget.getBoundingClientRect();b({x:t.clientX-i.left,y:t.clientY-i.top})}}}const C=w.lazy(()=>E(()=>import("./workflowChat-m824ZHEN.js").then(e=>e.w),__vite__mapDeps([0,1,2,3,4,5])).then(e=>({default:e.default})));function M(){const e=n.useRef(null),[u,l]=n.useState(!1),[o,r]=n.useState(!1),{position:a,isDragging:m,handleMouseDown:d}=_({boundaryPadding:{right:100,bottom:40},onClick:()=>l(!0)});return n.useEffect(()=>{const c=()=>{l(!0),r(!0)};return window.addEventListener(x.EXPLAIN_NODE,c),()=>window.removeEventListener(x.EXPLAIN_NODE,c)},[]),a?s.jsx(v,{children:s.jsx("div",{ref:e,children:s.jsxs("div",{className:"fixed",style:{zIndex:y,left:a.x,top:a.y,cursor:m?"grabbing":"grab"},children:[s.jsxs("button",{onMouseDown:d,className:"px-2 py-1 border border-gray-300 rounded-md bg-white text-black hover:bg-blue-300 hover:font-bold transition-colors select-none w-40 flex items-center space-x-1",style:{marginLeft:"-40px"},children:[s.jsx("img",{src:D,alt:"ComfyUI-Copilot Logo",className:"h-8 w-8"}),s.jsx("span",{className:"text-[14px] font-medium text-gray-800",children:"ComfyUI-Copilot"})]}),s.jsx(w.Suspense,{fallback:s.jsx("div",{children:"Loading..."}),children:s.jsx(C,{onClose:()=>{l(!1),r(!1)},visible:u,triggerUsage:o,onUsageTriggered:()=>r(!1)})})]})})}):null}const I=Object.freeze(Object.defineProperty({__proto__:null,default:M},Symbol.toStringTag,{value:"Module"}));export{I as A,D as l}; diff --git a/dist/copilot_web/ParameterDebugInterfaceNew-L5N_y6IJ.js b/dist/copilot_web/ParameterDebugInterfaceNew-L5N_y6IJ.js deleted file mode 100644 index c152668..0000000 --- a/dist/copilot_web/ParameterDebugInterfaceNew-L5N_y6IJ.js +++ /dev/null @@ -1,29 +0,0 @@ -import{j as e}from"./vendor-markdown-Dek94WS0.js";import{r as b}from"./vendor-react-V04_Axys.js";import{r as Qe,g as Xe,m as Ze,i as et}from"./workflowChat-Cr_yyziA.js";import{a as Z,u as Ie,W as Me,g as tt}from"./message-components-D3rPBq8S.js";import"./input.js";import"./App-DU9tUae4.js";function st(l,n){try{if(!l)return console.error("Invalid prompt_output: ",l),l;for(const r of n){if(!l[r.nodeId]){console.error(`Node with ID ${r.nodeId} not found`);continue}if(!l[r.nodeId].inputs){console.error(`Inputs not found for node with ID ${r.nodeId}`);continue}l[r.nodeId].inputs[r.paramName]=r.paramValue}return l}catch(r){return console.error("Error updating prompt:",r),l}}async function rt(l){const n=await Z.graphToPrompt(),r=st(n.output,l);console.log("queuePrompt updated_prompt:",r);const u={prompt:r,client_id:Z.api.clientId,extra_data:{extra_pageinfo:{workflow:n.workflow}}};console.debug("queuePrompt request_body.prompt:",r);const p=await Qe(u);return console.debug("queuePrompt response:",p),p}function Pe(l){const n=document.createElement("canvas"),r=n.getContext("2d");if(n.width=512,n.height=512,r){r.fillStyle="#f8d7da",r.fillRect(0,0,n.width,n.height),r.strokeStyle="#dc3545",r.lineWidth=4,r.strokeRect(10,10,n.width-20,n.height-20),r.fillStyle="#dc3545",r.beginPath(),r.arc(n.width/2,150,50,0,2*Math.PI),r.fill(),r.fillStyle="white",r.font="bold 80px Arial",r.textAlign="center",r.textBaseline="middle",r.fillText("!",n.width/2,150),r.fillStyle="#721c24",r.font="20px Arial",r.textAlign="center",r.textBaseline="middle";const u=n.width-60,p=30,d=l.split(" ");let c="",g=250;for(let f=0;fu&&f>0?(r.fillText(c,n.width/2,g),c=d[f]+" ",g+=p):c=P}r.fillText(c,n.width/2,g)}return n.toDataURL("image/png")}async function nt(l){try{if(!l||l==="")return console.log("No prompt ID provided"),{1:[Pe("Fail to generate prompt ID")]};const n=await Xe(l);if(!n||!n[l])return console.log("Not finished for prompt ID:",l),{};const r=n[l];if(r.status&&r.status.status_str==="error"){console.error("Error for prompt ID:",l);const p=r.status.messages;if(p&&p.length>0){const d=p[p.length-1];if(d&&d.length>0){const c=d[0];return{1:[Pe(c)]}}}}const u={};if(r.outputs)for(const p in r.outputs){const d=r.outputs[p];if(d&&d.images){u[p]=[];for(const c of d.images)if(c&&c.filename&&c.type){const g=Z.graph._nodes_by_id[p].imgs[0].currentSrc.split("?")[0];u[p].push(g+"?filename="+encodeURIComponent(c.filename)+"&type="+encodeURIComponent(c.type)+(c.subfolder?"&subfolder="+encodeURIComponent(c.subfolder):""))}console.log("outputImages for nodeId:",p,u[p])}}return u}catch(n){throw console.error("Error getting output images from prompt:",n),n}}function ot(){const l=Object.values(Z.graph._nodes_by_id),n=[],r=[];for(const u of l)u.type==="SaveImage"?n.push(u.id):u.type==="PreviewImage"&&r.push(u.id);if(console.log("saveNodeIds:",n),console.log("previewNodeIds:",r),n.length===0&&r.length===0)throw new Error("No SaveImage or PreviewImage node found, please add one to the graph");return n.length===1?n[0]:n.length==0&&r.length===1?r[0]:null}async function at(l,n){const r=await nt(l);return Object.keys(r).length===0?null:r[n.toString()]&&r[n.toString()].length>0?r[n.toString()][0]:null}const lt=({selectedNodes:l,handleParamSelect:n,selectedParams:r,handleNext:u,handleClose:p})=>e.jsxs("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-4",children:[e.jsxs("div",{className:"mb-4 border-b pb-2 flex justify-between items-center",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-base font-medium text-gray-800",children:"Select Parameters for Testing"}),e.jsx("p",{className:"text-xs text-gray-500",children:"Choose the parameters you want to include in your batch test"})]}),e.jsx("button",{className:"text-gray-400 hover:text-gray-600",onClick:p,children:e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),l.map((d,c)=>{const g=d.title||"Unknown Node",f=d.widgets||[];return e.jsxs("div",{className:"border rounded-md mb-4 overflow-hidden",children:[e.jsx("div",{className:"bg-gray-50 px-3 py-2 text-sm font-medium text-gray-700 border-b",children:g}),e.jsx("div",{className:"p-4 space-y-3",children:e.jsx("div",{className:"flex items-center gap-3 flex-wrap",children:f.map((P,M)=>{const L=P.name;return e.jsxs("div",{className:"flex items-center",children:[e.jsx("div",{className:`w-5 h-5 rounded-full border flex items-center justify-center ${r[L]?"border-red-500 bg-red-100":"border-gray-300"}`,onClick:D=>n(L,D),children:r[L]&&e.jsx("div",{className:"w-3 h-3 rounded-full bg-red-500"})}),e.jsx("span",{className:"ml-2 text-gray-700 text-xs",children:L})]},`widget-${M}`)})})})]},`node-${c}`)}),e.jsx("div",{className:"mt-6 flex justify-center",children:e.jsx("button",{onClick:d=>u(d),className:"px-3 py-1.5 text-xs bg-pink-200 text-pink-700 rounded-md hover:bg-pink-300 transition-colors",children:"Next"})})]}),it=({selectedNodes:l,paramTestValues:n,selectedParams:r,updateParamTestValues:u,toggleDropdown:p,openDropdowns:d,handleTestValueSelect:c,searchTerms:g,handleSearch:f,handleSelectAll:P,handleNext:M,handlePrevious:L,handleClose:D,inputValues:J,setInputValues:A,textInputs:B,handleTextInputChange:_,handleAddTextInput:R,handleRemoveTextInput:j,openAiWritingModal:N})=>{const S=(w,I,H,q=0)=>{if(w=isNaN(w)?0:w,I=isNaN(I)?100:I,H=isNaN(H)||H<=0?1:H,I{!l||l.length===0||l.forEach(w=>{const I=w.id.toString(),H=w.widgets||{};Object.values(H).forEach(m=>{const E=m.name;if(!r[E])return;if(!(n[I]?.[E]?.length>0)&&m.type==="number"){const x=m.options?.min||0,V=m.options?.max||100,O=(m.options?.step||10)/10,k=m.options?.precision||0,T=S(x,V,O,k);if(T.length>0){u(I,E,T);const U=`${I}_${E}`;A(h=>({...h,[U]:{min:x.toString(),max:V.toString(),step:O.toString()}}))}}if(m.type==="customtext"||m.type.toLowerCase().includes("text")){const x=`${I}_${E}`,V=B[x]||[""];JSON.stringify(V)!==JSON.stringify(n[I]?.[E]||[""])&&u(I,E,V)}})})},[l,r,n,B,u,A,S]),e.jsxs("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-4",children:[e.jsxs("div",{className:"mb-4 border-b pb-2 flex justify-between items-center",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-base font-medium text-gray-800",children:"Parameter Options"}),e.jsx("p",{className:"text-xs text-gray-500",children:"Configure the test values for each parameter"})]}),e.jsx("button",{className:"text-gray-400 hover:text-gray-600",onClick:D,children:e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),l.length>0?l.map((w,I)=>{const H=w.widgets||{},q=Object.values(H),m=w.id;return e.jsxs("div",{className:"border rounded-md mb-4 overflow-hidden",children:[e.jsxs("div",{className:"bg-gray-50 px-3 py-2 text-xs font-medium text-gray-700 border-b flex justify-between items-center",children:[e.jsxs("span",{children:[w.type," (ID: ",m,")"]}),e.jsx("button",{className:"text-gray-400 hover:text-gray-600",onClick:E=>D(E,I),children:e.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),e.jsx("div",{className:"p-4 space-y-4",children:q.map((E,Y)=>{const x=E.name;if(!r[x])return null;const V=`${m}_${x}`;if(E.type==="customtext"||E.type.toLowerCase().includes("text")){const O=B[V]||[""];return e.jsxs("div",{className:"border-b pb-3",children:[e.jsxs("div",{className:"flex justify-between items-center mb-2",children:[e.jsxs("label",{className:"text-xs font-medium text-gray-700",children:[x,":"]}),e.jsxs("button",{className:"px-2 py-1 bg-blue-100 text-blue-700 rounded text-xs flex items-center hover:bg-blue-200 transition-colors",onClick:()=>N(m,x),children:[e.jsx("svg",{className:"w-3 h-3 mr-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"})}),"AI Writing"]})]}),e.jsx("div",{className:"space-y-2",children:O.map((k,T)=>e.jsxs("div",{className:"flex items-start",children:[e.jsx("textarea",{className:"flex-1 border border-gray-300 rounded p-2 text-xs resize-y",rows:2,placeholder:"Enter text...",value:k,onChange:U=>_(m,x,T,U.target.value)}),e.jsx("button",{className:"ml-2 text-red-500 hover:text-red-700",onClick:()=>j(m,x,T),title:"Remove",children:e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]},T))}),e.jsxs("button",{className:"mt-2 px-2 py-1 border border-dashed border-gray-300 rounded text-xs text-gray-600 hover:bg-gray-50 flex items-center",onClick:()=>R(m,x),children:[e.jsx("svg",{className:"w-3 h-3 mr-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 6v6m0 0v6m0-6h6m-6 0H6"})}),"Add Text"]})]},Y)}if(E.type==="number"){const O=E.options?.min||0,k=E.options?.max||100,T=(E.options?.step||10)/10,U=E.options?.precision||0,h=S(O,k,T,U),G=J[V]||{min:O.toString(),max:k.toString(),step:T.toString()};return e.jsxs("div",{className:"border-b pb-3",children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsxs("label",{className:"text-xs font-medium text-gray-700",children:[x,":"]}),e.jsx("div",{className:"w-4"})]}),e.jsxs("div",{className:"flex space-x-2 items-center",children:[e.jsx("label",{className:"text-xs text-gray-600",children:"Min"}),e.jsx("input",{type:"text",className:"w-12 h-6 border border-gray-300 rounded text-xs px-2",value:G.min,onClick:y=>{y.preventDefault(),y.stopPropagation()},onChange:y=>{y.preventDefault(),y.stopPropagation();const $=y.target.value;if(A(W=>({...W,[V]:{...W[V],min:$}})),$===""||!isNaN(parseFloat($))){const W=$===""?0:parseFloat($),z=parseFloat(G.max||k.toString()),Q=parseFloat(G.step||T.toString()),K=S(W,z,Q,U);u(m,x,K)}}}),e.jsx("label",{className:"text-xs text-gray-600",children:"Max"}),e.jsx("input",{type:"text",className:"w-12 h-6 border border-gray-300 rounded text-xs px-2",value:G.max,onClick:y=>{y.preventDefault(),y.stopPropagation()},onChange:y=>{y.preventDefault(),y.stopPropagation();const $=y.target.value;if(A(W=>({...W,[V]:{...W[V],max:$}})),$===""||!isNaN(parseFloat($))){const W=parseFloat(G.min||O.toString()),z=$===""?W:parseFloat($),Q=parseFloat(G.step||T.toString()),K=S(W,z,Q,U);u(m,x,K)}}}),e.jsx("label",{className:"text-xs text-gray-600",children:"Step"}),e.jsx("input",{type:"text",className:"w-12 h-6 border border-gray-300 rounded text-xs px-2",value:G.step,onClick:y=>{y.preventDefault(),y.stopPropagation()},onChange:y=>{y.preventDefault(),y.stopPropagation();const $=y.target.value;if(A(W=>({...W,[V]:{...W[V],step:$}})),$===""||!isNaN(parseFloat($))&&parseFloat($)>0){const W=parseFloat(G.min||O.toString()),z=parseFloat(G.max||k.toString()),Q=$===""?1:parseFloat($),K=S(W,z,Q,U);u(m,x,K)}}})]}),e.jsxs("div",{className:"mt-1",children:[e.jsx("label",{className:"text-xs text-gray-600",children:"Test values"}),e.jsx("div",{className:"mt-1 flex flex-wrap gap-1",children:(()=>{const y=n[m]?.[x]||h;if(y.length<=10)return y.map(($,W)=>e.jsxs("div",{className:"px-2 py-0.5 bg-blue-100 text-blue-800 rounded-md flex items-center text-xs cursor-pointer hover:bg-blue-200",onClick:z=>{z.stopPropagation(),c(m,x,$,z)},children:[e.jsx("span",{children:$}),e.jsx("svg",{className:"w-4 h-4 ml-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})]},W));{const $=y.slice(0,5),W=y.slice(y.length-5);return e.jsxs(e.Fragment,{children:[$.map((z,Q)=>e.jsxs("div",{className:"px-2 py-0.5 bg-blue-100 text-blue-800 rounded-md flex items-center text-xs cursor-pointer hover:bg-blue-200",onClick:K=>{K.stopPropagation(),c(m,x,z,K)},children:[e.jsx("span",{children:z}),e.jsx("svg",{className:"w-4 h-4 ml-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})]},`first-${Q}`)),e.jsx("div",{className:"px-2 py-0.5 bg-gray-100 text-gray-600 rounded-md flex items-center text-xs",children:"..."}),W.map((z,Q)=>e.jsxs("div",{className:"px-2 py-0.5 bg-blue-100 text-blue-800 rounded-md flex items-center text-xs cursor-pointer hover:bg-blue-200",onClick:K=>{K.stopPropagation(),c(m,x,z,K)},children:[e.jsx("span",{children:z}),e.jsx("svg",{className:"w-4 h-4 ml-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})]},`last-${Q}`))]})}})()})]}),e.jsx("div",{className:"mt-1",children:e.jsx("p",{className:"text-xs text-gray-500",children:"Values are distributed evenly between Min and Max"})})]},Y)}else if(E.type==="combo"){const O=E.options?.values||[],k=`${m}_${x}`,T=h=>typeof h=="string"?h:h&&typeof h=="object"&&"name"in h?h.name:String(h),U=h=>typeof h=="object"&&h!==null&&"name"in h?h.name:h;return e.jsxs("div",{className:"border-b pb-3",children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsx("label",{className:"text-xs font-medium text-gray-700",children:x}),e.jsxs("div",{className:"relative dropdown-container",children:[e.jsxs("button",{className:"appearance-none border border-gray-300 rounded px-2 py-0.5 pr-6 text-xs flex items-center bg-white text-gray-700",onClick:h=>{h.preventDefault(),h.stopPropagation(),p(m,x,h)},"data-dropdown":k,children:[e.jsx("span",{children:(n[m]?.[x]||[]).length>0?`${x}: ${(n[m]?.[x]||[]).length} selected`:`Select ${x}`}),e.jsx("div",{className:"ml-2",children:e.jsx("svg",{className:"fill-current h-4 w-4",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",children:e.jsx("path",{d:"M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"})})})]}),d[k]&&e.jsxs("div",{className:"absolute z-[9999] mt-1 w-64 bg-white border border-gray-300 rounded-md shadow-lg dropdown-menu",style:{position:"fixed",top:typeof d[k]=="object"?`${d[k].y}px`:"0px",left:typeof d[k]=="object"?`${d[k].x}px`:"0px",maxHeight:"300px",overflowY:"auto"},children:[e.jsx("div",{className:"p-2 border-b sticky top-0 bg-white",children:e.jsx("input",{type:"text",className:"w-full px-2 py-0.5 text-xs border border-gray-300 rounded",placeholder:"Search...",value:g[k]||"",onChange:h=>{h.preventDefault(),h.stopPropagation(),f(m,x,h.target.value)},onClick:h=>{h.preventDefault(),h.stopPropagation()},autoFocus:!0})}),e.jsxs("div",{className:"px-3 py-1.5 bg-gray-50 border-b cursor-pointer text-xs flex items-center text-gray-700 hover:bg-gray-100",onClick:h=>{h.preventDefault(),h.stopPropagation();const y=O.filter($=>!g[k]||T($).toLowerCase().includes((g[k]||"").toLowerCase())).map(U);P(m,x,y)},children:[e.jsx("div",{className:`w-4 h-4 mr-2 border rounded-sm flex items-center justify-center ${O.length>0&&(n[m]?.[x]||[]).length===O.length?"bg-blue-500 border-blue-500":(n[m]?.[x]||[]).length>0?"bg-blue-500 border-blue-500 opacity-50":"border-gray-300"}`,children:(n[m]?.[x]||[]).length>0&&e.jsx("svg",{className:"w-3 h-3 text-white",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})})}),e.jsx("span",{className:"font-medium",children:O.length>0&&(n[m]?.[x]||[]).length===O.length?"Deselect All":"Select All"})]}),e.jsxs("div",{className:"max-h-60 overflow-y-auto",children:[O.filter(h=>!g[k]||T(h).toLowerCase().includes((g[k]||"").toLowerCase())).map((h,G)=>e.jsxs("div",{className:"px-3 py-1.5 hover:bg-gray-100 cursor-pointer text-xs flex items-center text-gray-700",onClick:y=>{y.preventDefault(),y.stopPropagation(),c(m,x,U(h),y)},children:[e.jsx("div",{className:`w-4 h-4 mr-2 border rounded-sm flex items-center justify-center ${(n[m]?.[x]||[]).includes(U(h))?"bg-blue-500 border-blue-500":"border-gray-300"}`,children:(n[m]?.[x]||[]).includes(U(h))&&e.jsx("svg",{className:"w-3 h-3 text-white",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})})}),e.jsx("span",{className:"whitespace-normal overflow-hidden text-ellipsis",children:T(h)})]},G)),O.filter(h=>!g[k]||T(h).toLowerCase().includes((g[k]||"").toLowerCase())).length===0&&e.jsx("div",{className:"px-3 py-4 text-sm text-gray-500 text-center",children:"No matching options"})]})]})]})]}),e.jsxs("div",{className:"mt-2",children:[e.jsx("label",{className:"text-xs text-gray-600",children:"Test values"}),e.jsx("div",{className:"mt-1 flex flex-wrap gap-1",children:(n[m]?.[x]||[]).map((h,G)=>e.jsxs("div",{className:"px-2 py-0.5 bg-blue-100 text-blue-800 rounded-md flex items-center text-xs",children:[e.jsx("span",{children:h}),e.jsx("svg",{className:"w-4 h-4 ml-1 cursor-pointer hover:text-blue-600",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",onClick:y=>{y.preventDefault(),y.stopPropagation(),c(m,x,h,y)},children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})]},G))})]})]},Y)}else return e.jsxs("div",{className:"border-b pb-3",children:[e.jsx("div",{className:"flex justify-between items-center",children:e.jsx("label",{className:"text-xs font-medium text-gray-700",children:x})}),e.jsxs("div",{className:"mt-2",children:[e.jsx("label",{className:"text-xs text-gray-600",children:"Test values"}),e.jsxs("div",{className:"mt-1 flex flex-wrap gap-1",children:[(n[m]?.[x]||[]).map((O,k)=>e.jsxs("div",{className:"px-2 py-0.5 bg-blue-100 text-blue-800 rounded-md flex items-center text-xs",children:[e.jsx("span",{children:O}),e.jsx("svg",{className:"w-4 h-4 ml-1 cursor-pointer hover:text-blue-600",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",onClick:T=>{T.preventDefault(),T.stopPropagation(),c(m,x,O,T)},children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})]},k)),e.jsxs("button",{className:"px-2 py-0.5 border border-dashed border-blue-300 text-blue-600 rounded-md text-xs flex items-center hover:bg-blue-50",onClick:O=>{O.preventDefault(),O.stopPropagation();const k=`${x}${(n[m]?.[x]||[]).length+1}`;u(m,x,[...n[m]?.[x]||[],k])},children:[e.jsx("svg",{className:"w-4 h-4 mr-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 6v6m0 0v6m0-6h6m-6 0H6"})}),e.jsx("span",{children:"Add"})]})]})]})]},Y)})})]},I)}):e.jsx("div",{className:"border rounded-md mb-4 p-4 text-center text-gray-500",children:"No nodes selected. Please select a node in the workflow to configure parameters."}),e.jsxs("div",{className:"mt-6 flex justify-between",children:[e.jsx("button",{onClick:w=>L(w),className:"px-3 py-1.5 text-xs bg-gray-100 text-gray-800 rounded-md hover:bg-gray-200 transition-colors",children:"Previous"}),e.jsx("button",{onClick:w=>M(w),className:"px-3 py-1.5 text-xs bg-pink-200 text-pink-700 rounded-md hover:bg-pink-300 transition-colors",children:"Next"})]})]})},ct=({selectedNodes:l,paramTestValues:n,selectedParams:r,totalCount:u,errorMessage:p,handlePrevious:d,handleStartGeneration:c,handleClose:g})=>{const[f,P]=b.useState([]),[M,L]=b.useState(null),[D,J]=b.useState(!1);Ie();const A=()=>{const _=Object.values(Z.graph._nodes_by_id),R=[],j=[];for(const S of _)S.type==="SaveImage"?R.push(S.id):S.type==="PreviewImage"&&j.push(S.id);const N=[...R,...j];P(N),N.length===1?L(N[0]):N.length>1&&(J(!0),L(null))};b.useEffect(()=>{A()},[]),b.useEffect(()=>{const _=()=>{if(!Z.canvas.selected_nodes)return;const R=Object.values(Z.canvas.selected_nodes);if(R.length===0)return;const j=R[0];j&&(j.type==="SaveImage"||j.type==="PreviewImage")&&(console.log("Selected image node:",j.id),L(j.id))};return document.addEventListener("click",_),()=>{document.removeEventListener("click",_)}},[]);const B=_=>{if(_&&(_.preventDefault(),_.stopPropagation()),f.length>1&&!M){J(!0);return}c(_,M||void 0)};return e.jsxs("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-4",children:[e.jsxs("div",{className:"mb-4 border-b pb-2 flex justify-between items-center",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-base font-medium text-gray-800",children:"Confirm Test Configuration"}),e.jsxs("p",{className:"text-xs text-gray-500",children:["In the selected parameter combinations, there are ",u," total runs. Each run will generate a separate image."]})]}),e.jsx("button",{className:"text-gray-400 hover:text-gray-600",onClick:g,children:e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),D&&f.length>1&&e.jsx("div",{className:"mb-4 p-3 bg-yellow-50 border border-yellow-200 rounded-md text-amber-600 text-xs",children:e.jsxs("div",{className:"flex items-start",children:[e.jsx("div",{className:"flex-shrink-0 mt-0.5",children:e.jsx("svg",{className:"h-3 w-3",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})})}),e.jsx("div",{className:"ml-2",children:M===null?`Multiple SaveImage and PreviewImage nodes detected with IDs ${f.join(",")}. Please click the node on canvas.`:`Current node ID is ${M}, please click Start Generation again`})]})}),p&&e.jsx("div",{className:"mb-4 p-3 bg-red-50 border border-red-200 rounded-md text-red-600 text-xs",children:e.jsxs("div",{className:"flex items-start",children:[e.jsx("div",{className:"flex-shrink-0 mt-0.5",children:e.jsx("svg",{className:"h-3 w-3",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})})}),e.jsx("div",{className:"ml-2",children:p})]})}),l.length>0?l.map((_,R)=>{const j=_.type||"Unknown Node",N=_.widgets||[],S=_.id;return e.jsxs("div",{className:"border rounded-md mb-4 overflow-hidden",children:[e.jsxs("div",{className:"bg-gray-50 px-3 py-2 text-xs font-medium text-gray-700 border-b",children:[j," (ID: ",S,")"]}),e.jsx("div",{className:"p-4 space-y-3",children:N.map((w,I)=>{const H=w.name;if(!r[H])return null;const q=n[S]?.[H]||[],m=Array.isArray(q)?`[${q.join(", ")}]`:JSON.stringify(q);return e.jsxs("div",{className:IE.preventDefault()})})]},I)})})]},R)}):e.jsx("div",{className:"border rounded-md mb-4 p-4 text-center text-gray-500 text-xs",children:"No nodes selected. Please select a node in the workflow to configure parameters."}),e.jsxs("div",{className:"mt-6 flex justify-between",children:[e.jsx("button",{onClick:_=>d(_),className:"px-3 py-1.5 text-xs bg-gray-100 text-gray-800 rounded-md hover:bg-gray-200 transition-colors",children:"Previous"}),e.jsx("button",{onClick:_=>B(_),className:`px-3 py-1.5 text-xs rounded-md transition-colors ${f.length>1&&!M?"bg-gray-200 text-gray-500 cursor-not-allowed":"bg-pink-200 text-pink-700 hover:bg-pink-300"}`,disabled:f.length>1&&!M,children:"Start Generation"})]})]})},dt=({selectedNodes:l,paramTestValues:n,selectedParams:r,totalCount:u,completedCount:p,errorMessage:d,handleClose:c,setIsProcessing:g,setCurrentScreen:f,cleanupPolling:P})=>{const M=L=>{L.preventDefault(),L.stopPropagation(),Ze({clear:!0}),et(),P&&P(),g(!1),f(2)};return e.jsxs("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-4 relative",children:[e.jsx("div",{className:"absolute inset-0 bg-gray-500 bg-opacity-30 flex flex-col items-center justify-center z-10",children:e.jsxs("div",{className:"text-center text-gray-800 bg-white p-4 rounded-lg shadow-lg",children:[e.jsx("div",{className:"mb-2 text-sm font-medium",children:"Processing..."}),e.jsxs("div",{className:"text-xs mb-3",children:["Completed ",p," of ",u," runs"]}),e.jsx("div",{className:"w-48 h-2 bg-gray-200 rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full bg-pink-500 transition-all duration-200",style:{width:`${p/u*100}%`}})}),e.jsxs("div",{className:"mt-2 text-xs text-gray-600",children:["Already generated ",p," images"]}),e.jsx("button",{onClick:M,className:"mt-4 px-3 py-1.5 text-xs bg-gray-200 text-gray-800 rounded-md hover:bg-gray-300 transition-colors",children:"Cancel"})]})}),e.jsxs("div",{className:"mb-4 border-b pb-2 flex justify-between items-center",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-base font-medium text-gray-800",children:"Confirm Test Configuration"}),e.jsxs("p",{className:"text-xs text-gray-500",children:["In the selected parameter combinations, there are ",u," total runs. Each run will generate a separate image."]})]}),e.jsx("button",{className:"text-gray-400 hover:text-gray-600",onClick:c,children:e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),d&&e.jsx("div",{className:"mb-4 p-3 bg-red-50 border border-red-200 rounded-md text-red-600 text-xs",children:e.jsxs("div",{className:"flex items-start",children:[e.jsx("div",{className:"flex-shrink-0 mt-0.5",children:e.jsx("svg",{className:"h-3 w-3",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})})}),e.jsx("div",{className:"ml-2",children:d})]})}),l.length>0?l.map((L,D)=>{const J=L.type||"Unknown Node",A=L.widgets||[],B=L.id;return e.jsxs("div",{className:"border rounded-md mb-4 overflow-hidden",children:[e.jsxs("div",{className:"bg-gray-50 px-3 py-2 text-xs font-medium text-gray-700 border-b",children:[J," (ID: ",B,")"]}),e.jsx("div",{className:"p-4 space-y-3",children:A.map((_,R)=>{const j=_.name;if(!r[j])return null;const N=n[B]?.[j]||[],S=Array.isArray(N)?`[${N.join(", ")}]`:JSON.stringify(N);return e.jsxs("div",{className:Rw.preventDefault()})})]},R)})})]},D)}):e.jsx("div",{className:"border rounded-md mb-4 p-4 text-center text-gray-500",children:"No nodes selected. Please select a node in the workflow to configure parameters."})]})},xt=({generatedImages:l,selectedImageIndex:n,handleSelectImage:r,handleApplySelected:u,handlePrevious:p,handleClose:d,currentPage:c,handlePageChange:g,imagesPerPage:f,notificationVisible:P,modalVisible:M,modalImageUrl:L,openImageModal:D,closeImageModal:J})=>{const A=Math.ceil(l.length/f),B=(c-1)*f,_=Math.min(B+f,l.length),R=l.slice(B,_);return e.jsxs("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-4",children:[e.jsxs("div",{className:"mb-4 border-b pb-2 flex justify-between items-center",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-base font-medium text-gray-800",children:"Generation Complete"}),e.jsxs("p",{className:"text-xs text-gray-500",children:["All ",l.length," images have been generated."]})]}),e.jsx("button",{className:"text-gray-400 hover:text-gray-600",onClick:d,children:e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),P&&e.jsx("div",{className:"fixed top-4 right-4 bg-green-100 border-l-4 border-green-500 text-green-700 p-3 shadow-md rounded animate-fade-in-out z-50",children:e.jsxs("div",{className:"flex items-center",children:[e.jsx("div",{className:"py-1",children:e.jsx("svg",{className:"h-4 w-4 text-green-500 mr-3",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})})}),e.jsx("p",{className:"text-xs",children:"Parameters has been applied."})]})}),M&&e.jsx("div",{className:"fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50",onClick:J,children:e.jsxs("div",{className:"bg-white rounded-lg p-2 max-w-4xl max-h-[90vh] relative",onClick:j=>j.stopPropagation(),children:[e.jsx("button",{className:"absolute top-2 right-2 text-gray-700 hover:text-gray-900 rounded-full hover:bg-gray-200 p-1",onClick:J,children:e.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})}),e.jsx("div",{className:"overflow-auto max-h-[calc(90vh-4rem)]",children:e.jsx("img",{src:L,alt:"Enlarged image",className:"max-w-full h-auto"})})]})}),e.jsx("div",{className:"grid grid-cols-3 gap-4 mb-6",children:R.map((j,N)=>{const S=B+N;return e.jsxs("div",{className:`relative rounded-lg overflow-hidden border ${n===S?"border-pink-500 ring-2 ring-pink-300":"border-gray-200"}`,onClick:w=>r(S,w),children:[e.jsx("button",{className:"absolute top-2 right-2 bg-white bg-opacity-75 rounded-full p-0.5 text-gray-600 hover:text-gray-900 shadow-sm z-10",onClick:w=>D(j.url,w),children:e.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5v-4m0 4h-4m4 0l-5-5"})})}),e.jsx("div",{className:"aspect-square",children:e.jsx("img",{src:j.url,alt:`Generated image ${S+1}`,className:"w-full h-full object-cover"})}),e.jsx("div",{className:"p-2 text-xs text-gray-600 bg-white max-h-16 overflow-y-auto",children:Object.entries(j.params).filter(([w,I])=>w!=="nodeParams"&&typeof I!="object").map(([w,I])=>e.jsxs("div",{children:[w,": ",String(I)]},w))})]},S)})}),A>1&&e.jsxs("div",{className:"flex justify-center items-center space-x-2 mt-4 mb-4",children:[e.jsx("button",{onClick:j=>g(1,j),disabled:c===1,className:`px-2 py-1 rounded ${c===1?"text-gray-400 cursor-not-allowed":"text-gray-700 hover:bg-gray-100"}`,children:e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",viewBox:"0 0 20 20",fill:"currentColor",children:[e.jsx("path",{fillRule:"evenodd",d:"M15.707 15.707a1 1 0 01-1.414 0l-5-5a1 1 0 010-1.414l5-5a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 010 1.414z",clipRule:"evenodd"}),e.jsx("path",{fillRule:"evenodd",d:"M8.707 15.707a1 1 0 01-1.414 0l-5-5a1 1 0 010-1.414l5-5a1 1 0 111.414 1.414L4.414 10l4.293 4.293a1 1 0 010 1.414z",clipRule:"evenodd"})]})}),e.jsx("button",{onClick:j=>g(c-1,j),disabled:c===1,className:`px-2 py-1 rounded ${c===1?"text-gray-400 cursor-not-allowed":"text-gray-700 hover:bg-gray-100"}`,children:e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z",clipRule:"evenodd"})})}),e.jsxs("div",{className:"px-2 py-1 text-xs text-gray-800",children:["Page ",c," of ",A]}),e.jsx("button",{onClick:j=>g(c+1,j),disabled:c===A,className:`px-2 py-1 rounded ${c===A?"text-gray-400 cursor-not-allowed":"text-gray-700 hover:bg-gray-100"}`,children:e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z",clipRule:"evenodd"})})}),e.jsx("button",{onClick:j=>g(A,j),disabled:c===A,className:`px-2 py-1 rounded ${c===A?"text-gray-400 cursor-not-allowed":"text-gray-700 hover:bg-gray-100"}`,children:e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",viewBox:"0 0 20 20",fill:"currentColor",children:[e.jsx("path",{fillRule:"evenodd",d:"M4.293 15.707a1 1 0 001.414 0l5-5a1 1 0 000-1.414l-5-5a1 1 0 00-1.414 1.414L8.586 10 4.293 14.293a1 1 0 000 1.414z",clipRule:"evenodd"}),e.jsx("path",{fillRule:"evenodd",d:"M11.293 15.707a1 1 0 001.414 0l5-5a1 1 0 000-1.414l-5-5a1 1 0 00-1.414 1.414L15.586 10l-4.293 4.293a1 1 0 000 1.414z",clipRule:"evenodd"})]})})]}),e.jsxs("div",{className:"mt-6 flex justify-between",children:[e.jsx("button",{onClick:j=>p(j),className:"px-3 py-1.5 text-xs bg-gray-100 text-gray-800 rounded-md hover:bg-gray-200 transition-colors",children:"Previous"}),e.jsx("button",{onClick:j=>u(j),className:"px-3 py-1.5 text-xs bg-pink-200 text-pink-700 rounded-md hover:bg-pink-300 transition-colors",disabled:n===null,children:"Apply Selected"})]})]})},ut=({visible:l,aiWritingModalText:n,setAiWritingModalText:r,aiGeneratedTexts:u,aiSelectedTexts:p,aiWritingLoading:d,aiWritingError:c,handleAiWriting:g,toggleTextSelection:f,addSelectedTexts:P,onClose:M})=>l?e.jsx("div",{className:"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50",children:e.jsxs("div",{className:"bg-white rounded-lg shadow-lg w-full max-w-2xl max-h-[90vh] flex flex-col",children:[e.jsxs("div",{className:"p-4 border-b flex justify-between items-center",children:[e.jsx("h3",{className:"text-lg font-medium",children:"AI Writing Assistant"}),e.jsx("button",{className:"text-gray-400 hover:text-gray-600",onClick:M,children:e.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),e.jsxs("div",{className:"p-4 overflow-y-auto flex-1",children:[e.jsxs("div",{className:"mb-4",children:[e.jsx("p",{className:"text-sm text-gray-600 mb-2",children:"Enter text and AI will generate variations"}),e.jsx("textarea",{className:"w-full border border-gray-300 rounded-md p-2 text-sm",rows:3,placeholder:"Enter some text here...",value:n,onChange:L=>r(L.target.value)}),e.jsx("button",{className:"mt-2 px-4 py-2 bg-blue-100 text-blue-700 rounded-md text-sm flex items-center hover:bg-blue-200 transition-colors",onClick:g,disabled:d,children:d?e.jsxs(e.Fragment,{children:[e.jsxs("svg",{className:"animate-spin -ml-1 mr-2 h-4 w-4 text-blue-700",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",children:[e.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),e.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),"Generating..."]}):e.jsx(e.Fragment,{children:"Generate"})})]}),c&&e.jsx("div",{className:"mb-4 p-3 bg-red-50 border border-red-200 rounded-md text-red-600 text-sm",children:c}),u.length>0&&e.jsxs("div",{className:"mb-4",children:[e.jsx("p",{className:"text-sm font-medium mb-2",children:"Generated variations (select items to add):"}),e.jsx("div",{className:"space-y-2 max-h-[40vh] overflow-y-auto p-2",children:u.map((L,D)=>e.jsxs("div",{className:"flex items-start border border-gray-200 rounded-md p-2",children:[e.jsx("div",{className:"mr-2 mt-1",children:e.jsxs("div",{className:"relative",children:[e.jsx("input",{type:"checkbox",id:`text${D+1}`,checked:!!p[`text${D+1}`],onChange:()=>f(`text${D+1}`),className:"sr-only"}),e.jsx("div",{className:`h-4 w-4 rounded border ${p[`text${D+1}`]?"bg-blue-600 border-blue-600":"bg-white border-gray-300"} flex items-center justify-center`,onClick:()=>f(`text${D+1}`),children:p[`text${D+1}`]&&e.jsx("svg",{className:"h-3 w-3 text-white",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})})})]})}),e.jsx("label",{htmlFor:`text${D+1}`,className:"text-sm text-gray-700 cursor-pointer flex-1",children:L})]},D))})]})]}),e.jsxs("div",{className:"p-4 border-t flex justify-end flex-shrink-0",children:[e.jsx("button",{className:"px-4 py-2 bg-gray-100 text-gray-700 rounded-md text-sm mr-2 hover:bg-gray-200 transition-colors",onClick:M,children:"Cancel"}),e.jsx("button",{className:"px-4 py-2 bg-blue-500 text-white rounded-md text-sm hover:bg-blue-600 transition-colors",onClick:P,disabled:Object.values(p).every(L=>!L),children:"Add Selected"})]})]})}):null,ye=l=>{const n=[],r={};if(Object.keys(l).forEach(d=>{const c=parseInt(d),g=l[d]||{},f=Object.keys(g).filter(M=>g[M]&&g[M].length>0);if(f.length===0)return;const P=[[]];f.forEach(M=>{const L=g[M],D=[];P.forEach(J=>{L.forEach(A=>{const B=[...J,{nodeId:c,paramName:M,paramValue:String(A)}];D.push(B)})}),P.length=0,P.push(...D)}),r[d]=P}),Object.keys(r).length===0)return n;if(Object.keys(r).length===1){const d=Object.keys(r)[0];return r[d]}const u=Object.keys(r);let p=r[u[0]];for(let d=1;d{c.forEach(P=>{g.push([...f,...P])})}),p=g}return p},mt=(l,n)=>{const r={};r.nodeParams={};const u=ye(l);return n{const c=d.nodeId.toString(),g=d.paramName,f=d.paramValue;r.nodeParams[c]||(r.nodeParams[c]={}),r.nodeParams[c][g]=f,r[g]=f}),r},ht=` - @keyframes highlight-pulse { - 0% { - box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.5); - } - 70% { - box-shadow: 0 0 0 15px rgba(59, 130, 246, 0); - } - 100% { - box-shadow: 0 0 0 0 rgba(59, 130, 246, 0); - } - } - - .highlight-pulse { - animation: highlight-pulse 1.5s infinite; - border: 2px solid #3b82f6; - } - - @keyframes fade-in-out { - 0% { opacity: 0; transform: translateY(-20px); } - 10% { opacity: 1; transform: translateY(0); } - 90% { opacity: 1; transform: translateY(0); } - 100% { opacity: 0; transform: translateY(-20px); } - } - - .animate-fade-in-out { - animation: fade-in-out 3s forwards; - } -`,vt=({selectedNodes:l,visible:n,onClose:r})=>{const[u,p]=b.useState(0),[d,c]=b.useState({Steps:!0,CFG:!0,sampler_name:!0,threshold:!1,prompt:!1}),[g,f]=b.useState(!1),[P,M]=b.useState(!1),[L,D]=b.useState(0),[J,A]=b.useState(12),[B,_]=b.useState(null),[R,j]=b.useState(()=>Array(12).fill(null).map((t,s)=>({url:`https://source.unsplash.com/random/300x300?sig=${Math.random()}`,params:{step:s%3===0?5:s%3===1?10:15,sampler_name:"euler",cfg:1}}))),[N,S]=b.useState({}),[w,I]=b.useState({}),[H,q]=b.useState({}),[m,E]=b.useState({}),[Y,x]=b.useState(1),V=6,[O,k]=b.useState(null),[T,U]=b.useState(!1),[h,G]=b.useState(!1),[y,$]=b.useState(""),[W,z]=b.useState({}),[Q,K]=b.useState(!1),[pe,ge]=b.useState(""),[ve,de]=b.useState([]),[Ee,xe]=b.useState(!1),[we,Ne]=b.useState(""),[ke,Ce]=b.useState(""),[$e,ne]=b.useState(null),[Se,oe]=b.useState({}),{dispatch:ae}=Ie(),ue=b.useRef(null),le=b.useRef(null),We=async()=>{if(!pe.trim()){ne("Please enter some text to generate variations");return}xe(!0),ne(null),de([]),oe({});try{const t=await Me.generateSDPrompts(pe);de(t);const s={};t.forEach((i,o)=>{s[`text${o+1}`]=!1}),oe(s)}catch(t){console.error("Error generating text:",t),ne("Failed to generate text variations. Please try again.")}finally{xe(!1)}},De=(t,s,i,o)=>{const a=`${t}_${s}`;z(v=>{const F=[...v[a]||[]];return F[i]=o,{...v,[a]:F}});const C=[...W[a]||[]];C[i]=o,ee(t,s,C)},_e=(t,s)=>{const i=`${t}_${s}`;z(a=>{const C=[...a[i]||[]];return C.push(""),{...a,[i]:C}});const o=[...W[i]||[],""];ee(t,s,o)},Oe=(t,s,i)=>{const o=`${t}_${s}`;z(C=>{const v=[...C[o]||[]];return v.splice(i,1),{...C,[o]:v}});const a=[...W[o]||[]];a.splice(i,1),ee(t,s,a)},Ae=t=>{oe(s=>({...s,[t]:!s[t]}))},Te=()=>{const t=`${we}_${ke}`,s=Object.entries(Se).filter(([o,a])=>a).map(([o])=>{const a=parseInt(o.replace("text",""))-1;return ve[a]});if(s.length===0)return;z(o=>{const a=[...o[t]||[]];return{...o,[t]:[...a,...s]}});const i=[...W[t]||[],...s];ee(we,ke,i),K(!1)},Be=(t,s)=>{K(!0),Ne(t),Ce(s),ge(""),de([]),oe({}),xe(!1),ne(null)};b.useEffect(()=>{if(!l||l.length===0)return;const t={...N},s=l.map(o=>o.id.toString());Object.keys(t).forEach(o=>{s.includes(o)||delete t[o]}),l.forEach(o=>{const a=o.id.toString();t[a]||(t[a]={})}),JSON.stringify(t)!==JSON.stringify(N)&&S(t)},[l,N]),b.useEffect(()=>{ae({type:"SET_SCREEN_STATE",payload:{currentScreen:u,isProcessing:g,isCompleted:P}})},[u,g,P,ae]),b.useEffect(()=>{const t=document.createElement("style");return t.textContent=ht,document.head.appendChild(t),()=>{document.head.removeChild(t)}},[]),b.useEffect(()=>{const t=s=>{if(Object.values(w).some(i=>i)){const i=s.target,o=!!i.closest(".dropdown-menu"),a=!!i.closest("[data-dropdown]");!o&&!a&&I({})}};return document.addEventListener("mousedown",t),()=>{document.removeEventListener("mousedown",t)}},[w]);const Le=t=>{if(t&&(t.preventDefault(),t.stopPropagation()),u===0){const s={...N};Object.keys(s).forEach(i=>{const o=s[i];Object.keys(o).forEach(a=>{d[a]||delete o[a]})}),S(s)}if(u===1){const s={...N};l.forEach(o=>{const a=o.id.toString(),C=o.widgets||{};Object.values(C).forEach(v=>{const F=v.name;if(d[F]&&(v.type==="customtext"||v.type.toLowerCase().includes("text"))){const te=`${a}_${F}`,se=W[te]||[""];s[a]=s[a]||{},s[a][F]=se}})}),S(s);const i=ye(s);A(i.length)}k(null),p(s=>Math.min(s+1,2))},fe=t=>{if(t&&(t.preventDefault(),t.stopPropagation()),k(null),P&&M(!1),u===1){const s=l.map(a=>a.id.toString()),i=Object.keys(N),o={...N};i.forEach(a=>{s.includes(a)||delete o[a]}),S(o)}if(u===2||P){const s={...N};Object.entries(W).forEach(([i,o])=>{if(!o||o.length===0)return;const[a,C]=i.split("_");l.some(v=>v.id.toString()===a)&&(s[a]=s[a]||{},JSON.stringify(s[a][C])!==JSON.stringify(o)&&(s[a][C]=o))}),S(s)}p(s=>Math.max(s-1,0))},Re=(t,s)=>{s&&(s.preventDefault(),s.stopPropagation());const i=d[t];if(c(o=>({...o,[t]:!i})),i){const o={...N};Object.keys(o).forEach(a=>{o[a][t]&&delete o[a][t]}),S(o)}},ze=(t,s,i)=>{i.preventDefault(),i.stopPropagation();const o=`${t}_${s}`;I(a=>{if(a[o]&&typeof a[o]=="object"?a[o].isOpen:!!a[o])return{...a,[o]:!1};{let v=0,F=0;if(i.currentTarget){const ce=i.currentTarget.getBoundingClientRect();v=ce.left,F=ce.bottom}else v=i.clientX,F=i.clientY+20;const te=window.innerWidth,se=250;return v+se>te&&(v=te-se-10),v<0&&(v=10),{...a,[o]:{isOpen:!0,x:v,y:F}}}})},ee=(t,s,i)=>{S(o=>{const a={...o};return a[t]||(a[t]={}),a[t][s]=i,a})},Fe=(t,s,i,o)=>{o&&(o.preventDefault(),o.stopPropagation()),S(a=>{const C={...a};C[t]||(C[t]={}),C[t][s]||(C[t][s]=[]);const v=C[t][s];return v.includes(i)?C[t][s]=v.filter(F=>F!==i):C[t][s]=[...v,i],C})},Ve=(t,s,i)=>{const o=`${t}_${s}`;q(a=>({...a,[o]:i}))},Ge=(t,s,i)=>{if(!N[t]){ee(t,s,i);return}const o=N[t][s]||[];i.length===o.length?ee(t,s,[]):ee(t,s,[...i])},Ue=(t,s)=>{s&&(s.preventDefault(),s.stopPropagation()),x(Math.max(1,Math.min(t,Math.ceil(R.length/V))))},me=()=>{ue.current&&(clearTimeout(ue.current),ue.current=null),le.current=null};b.useEffect(()=>()=>{me()},[]);const He=async(t,s)=>{t&&(t.preventDefault(),t.stopPropagation()),me();const i=ye(N),o=i.length;if(o>100){k(`Cannot generate more than 100 images at once (currently: ${o} images)`);return}if(k(null),f(!0),D(0),console.log("Generated parameter combinations:",i),i.length===0){k("No valid parameter combinations found. Please check your parameter selections."),f(!1);return}let a=s||null;if(a===null){const v=ot();v!==null&&(a=v)}if(a===null){k("Please select a SaveImage or PreviewImage node first."),f(!1);return}const C=[];try{const v=Date.now().toString();le.current=v;for(const re of i){const X=await rt(re);X.prompt_id?C.push(X.prompt_id):(console.error("Failed to get prompt_id from response:",X),C.push(""))}const F=Array(i.length).fill(null).map((re,X)=>({url:`https://source.unsplash.com/random/300x300?sig=${Math.random()}`,params:mt(N,X)}));j(F);const te=Date.now(),se=5*60*1e3,ce=async()=>{if(le.current!==v){console.log("Another polling session has started, stopping this one");return}if(Date.now()-te>se){console.log("Timeout reached while waiting for images"),le.current===v&&(f(!1),M(!0),x(1));return}let re=0;for(let X=0;X{s&&(s.preventDefault(),s.stopPropagation()),_(t)},Je=(t,s)=>{s.preventDefault(),s.stopPropagation(),$(t),G(!0)},qe=t=>{t&&(t.preventDefault(),t.stopPropagation()),G(!1)},Ye=async t=>{if(t&&(t.preventDefault(),t.stopPropagation()),B!==null){console.log(`Applied image ${B+1} with parameters:`,R[B].params),Me.trackEvent({event_type:"parameter_debug_apply",message_type:"parameter_debug",message_id:tt(),data:{workflow:(await Z.graphToPrompt()).output,selected_params:R[B].params,all_params:N,count:Object.keys(N).length}});const s=R[B].params;s.nodeParams&&(Object.entries(s.nodeParams).forEach(([i,o])=>{const a=Z.graph._nodes_by_id[i];!a||!a.widgets||Object.entries(o).forEach(([C,v])=>{for(const F of a.widgets)if(F.name===C){F.value=v;break}})}),Z.graph.setDirtyCanvas(!1,!0),U(!0),setTimeout(()=>{U(!1)},3e3))}},ie=(t,s)=>{if(t&&(t.preventDefault(),t.stopPropagation()),u===1&&s!==void 0){const i=[...l],o=i[s];if(i.splice(s,1),o){const a=o.id.toString();S(C=>{const v={...C};return delete v[a],v})}i.length===0?r&&(ae({type:"SET_SCREEN_STATE",payload:null}),be(),r()):ae({type:"SET_SELECTED_NODE",payload:i});return}r?(ae({type:"SET_SCREEN_STATE",payload:null}),be(),r()):be()},be=()=>{p(0),c({Steps:!0,CFG:!0,sampler_name:!0,threshold:!1,prompt:!1}),me(),f(!1),M(!1),D(0),A(12),_(null),j(Array(12).fill(null).map((t,s)=>({url:`https://source.unsplash.com/random/300x300?sig=${Math.random()}`,params:{step:s%3===0?5:s%3===1?10:15,sampler_name:"euler",cfg:1}}))),S({}),I({}),q({}),E({}),x(1),k(null),U(!1),G(!1),$(""),z({}),K(!1),ge(""),de([]),xe(!1),Ne(""),Ce(""),ne(null),oe({})};return!n||l.length===0?e.jsx("div",{className:"flex-1 flex flex-col items-center justify-center p-8 bg-gray-50 overflow-y-auto",onClick:t=>t.stopPropagation(),children:e.jsxs("div",{className:"max-w-lg p-8 bg-white rounded-lg shadow-sm border border-blue-100 relative",children:[e.jsxs("div",{className:"mb-6 text-center",children:[e.jsx("h3",{className:"text-base font-bold text-blue-800 mb-2",children:"GenLab"}),e.jsx("div",{className:"h-1 w-16 bg-blue-500 mx-auto rounded-full mb-4"})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-start space-x-3",children:[e.jsx("div",{className:"bg-blue-100 p-2 rounded-full text-blue-600",children:e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{d:"M5 3a2 2 0 00-2 2v2a2 2 0 002 2h2a2 2 0 002-2V5a2 2 0 00-2-2H5zM5 11a2 2 0 00-2 2v2a2 2 0 002 2h2a2 2 0 002-2v-2a2 2 0 00-2-2H5zM11 5a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V5zM11 13a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"})})}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-medium text-gray-800",children:"Batch Test Parameter Pairs"}),e.jsx("p",{className:"text-xs text-gray-600",children:"Select a node to batch test parameter pairs"})]})]}),e.jsxs("div",{className:"flex items-start space-x-3",children:[e.jsx("div",{className:"bg-indigo-100 p-2 rounded-full text-indigo-600",children:e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z",clipRule:"evenodd"})})}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-medium text-gray-800",children:"How To Use"}),e.jsx("p",{className:"text-xs text-gray-600",children:"Click on any node in your workflow to start the parameter testing process"})]})]}),e.jsx("div",{className:"mt-6 text-center",children:e.jsx("p",{className:"text-xs text-gray-600 mb-3",children:"No node is currently selected"})})]})]})}):P?e.jsx("div",{className:"flex-1 overflow-y-auto bg-gray-50 p-4",onClick:t=>t.stopPropagation(),children:e.jsx(xt,{generatedImages:R,selectedImageIndex:B,handleSelectImage:Ke,handleApplySelected:Ye,handlePrevious:fe,handleClose:ie,currentPage:Y,handlePageChange:Ue,imagesPerPage:V,notificationVisible:T,modalVisible:h,modalImageUrl:y,openImageModal:Je,closeImageModal:qe})}):g?e.jsx("div",{className:"flex-1 overflow-y-auto bg-gray-50 p-4",onClick:t=>t.stopPropagation(),children:e.jsx(dt,{selectedNodes:l,paramTestValues:N,selectedParams:d,totalCount:J,completedCount:L,errorMessage:O,handleClose:ie,setIsProcessing:f,setCurrentScreen:p,cleanupPolling:me})}):u===0?e.jsx("div",{className:"flex-1 overflow-y-auto bg-gray-50 p-4 flex flex-col h-full max-h-[80vh]",onClick:t=>t.stopPropagation(),children:e.jsx(lt,{selectedNodes:l,handleParamSelect:Re,selectedParams:d,handleNext:Le,handleClose:ie})}):u===1?e.jsxs("div",{className:"flex-1 overflow-y-auto bg-gray-50 p-4 flex flex-col h-full max-h-[80vh]",onClick:t=>t.stopPropagation(),children:[e.jsx(it,{selectedNodes:l,paramTestValues:N,selectedParams:d,updateParamTestValues:ee,toggleDropdown:ze,openDropdowns:w,handleTestValueSelect:Fe,searchTerms:H,handleSearch:Ve,handleSelectAll:Ge,handleNext:Le,handlePrevious:fe,handleClose:ie,inputValues:m,setInputValues:E,textInputs:W,handleTextInputChange:De,handleAddTextInput:_e,handleRemoveTextInput:Oe,openAiWritingModal:Be}),e.jsx(ut,{visible:Q,aiWritingModalText:pe,setAiWritingModalText:ge,aiGeneratedTexts:ve,aiSelectedTexts:Se,aiWritingLoading:Ee,aiWritingError:$e,handleAiWriting:We,toggleTextSelection:Ae,addSelectedTexts:Te,onClose:()=>K(!1)})]}):e.jsx("div",{className:"flex-1 overflow-y-auto bg-gray-50 p-4 flex flex-col h-full max-h-[80vh]",onClick:t=>t.stopPropagation(),children:e.jsx(ct,{selectedNodes:l,paramTestValues:N,selectedParams:d,totalCount:J,errorMessage:O,handlePrevious:fe,handleStartGeneration:He,handleClose:ie})})};export{vt as ParameterDebugInterface}; diff --git a/dist/copilot_web/ParameterDebugInterfaceNew-gJw0-dqN.js b/dist/copilot_web/ParameterDebugInterfaceNew-gJw0-dqN.js new file mode 100644 index 0000000..26c3c19 --- /dev/null +++ b/dist/copilot_web/ParameterDebugInterfaceNew-gJw0-dqN.js @@ -0,0 +1,29 @@ +import{j as e}from"./vendor-markdown-Dek94WS0.js";import{r as b}from"./vendor-react-V04_Axys.js";import{r as Qe,g as Xe,m as Ze,i as et}from"./workflowChat-m824ZHEN.js";import{a as Z,u as Ie,W as Pe,g as tt}from"./message-components-D3rPBq8S.js";import"./input.js";import"./App-B_5DJBtC.js";function st(l,n){try{if(!l)return console.error("Invalid prompt_output: ",l),l;for(const r of n){if(!l[r.nodeId]){console.error(`Node with ID ${r.nodeId} not found`);continue}if(!l[r.nodeId].inputs){console.error(`Inputs not found for node with ID ${r.nodeId}`);continue}l[r.nodeId].inputs[r.paramName]=r.paramValue}return l}catch(r){return console.error("Error updating prompt:",r),l}}async function rt(l){const n=await Z.graphToPrompt(),r=st(n.output,l);console.log("queuePrompt updated_prompt:",r);const x={prompt:r,client_id:Z.api.clientId,extra_data:{extra_pageinfo:{workflow:n.workflow}}};console.debug("queuePrompt request_body.prompt:",r);const g=await Qe(x);return console.debug("queuePrompt response:",g),g}function Me(l){const n=document.createElement("canvas"),r=n.getContext("2d");if(n.width=512,n.height=512,r){r.fillStyle="#f8d7da",r.fillRect(0,0,n.width,n.height),r.strokeStyle="#dc3545",r.lineWidth=4,r.strokeRect(10,10,n.width-20,n.height-20),r.fillStyle="#dc3545",r.beginPath(),r.arc(n.width/2,150,50,0,2*Math.PI),r.fill(),r.fillStyle="white",r.font="bold 80px Arial",r.textAlign="center",r.textBaseline="middle",r.fillText("!",n.width/2,150),r.fillStyle="#721c24",r.font="20px Arial",r.textAlign="center",r.textBaseline="middle";const x=n.width-60,g=30,u=l.split(" ");let c="",m=250;for(let f=0;fx&&f>0?(r.fillText(c,n.width/2,m),c=u[f]+" ",m+=g):c=P}r.fillText(c,n.width/2,m)}return n.toDataURL("image/png")}async function nt(l){try{if(!l||l==="")return console.log("No prompt ID provided"),{1:[Me("Fail to generate prompt ID")]};const n=await Xe(l);if(!n||!n[l])return console.log("Not finished for prompt ID:",l),{};const r=n[l];if(r.status&&r.status.status_str==="error"){console.error("Error for prompt ID:",l);const g=r.status.messages;if(g&&g.length>0){const u=g[g.length-1];if(u&&u.length>0){const c=u[0];return{1:[Me(c)]}}}}const x={};if(r.outputs)for(const g in r.outputs){const u=r.outputs[g];if(u&&u.images){x[g]=[];for(const c of u.images)if(c&&c.filename&&c.type){const m=Z.graph._nodes_by_id[g].imgs[0].currentSrc.split("?")[0];x[g].push(m+"?filename="+encodeURIComponent(c.filename)+"&type="+encodeURIComponent(c.type)+(c.subfolder?"&subfolder="+encodeURIComponent(c.subfolder):""))}console.log("outputImages for nodeId:",g,x[g])}}return x}catch(n){throw console.error("Error getting output images from prompt:",n),n}}function ot(){const l=Object.values(Z.graph._nodes_by_id),n=[],r=[];for(const x of l)x.type==="SaveImage"?n.push(x.id):x.type==="PreviewImage"&&r.push(x.id);if(console.log("saveNodeIds:",n),console.log("previewNodeIds:",r),n.length===0&&r.length===0)throw new Error("No SaveImage or PreviewImage node found, please add one to the graph");return n.length===1?n[0]:n.length==0&&r.length===1?r[0]:null}async function at(l,n){const r=await nt(l);return Object.keys(r).length===0?null:r[n.toString()]&&r[n.toString()].length>0?r[n.toString()][0]:null}const lt=({selectedNodes:l,handleParamSelect:n,selectedParams:r,handleNext:x,handleClose:g})=>{const c=l.flatMap(m=>(m.widgets||[]).map(f=>f.name)).some(m=>r[m]===!0);return e.jsxs("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-4",children:[e.jsxs("div",{className:"mb-4 border-b pb-2 flex justify-between items-center",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-base font-medium text-gray-800",children:"Select Parameters for Testing"}),e.jsx("p",{className:"text-xs text-gray-500",children:"Choose the parameters you want to include in your batch test"})]}),e.jsx("button",{className:"text-gray-400 hover:text-gray-600",onClick:g,children:e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),l.map((m,f)=>{const P=m.title||"Unknown Node",L=m.widgets||[];return e.jsxs("div",{className:"border rounded-md mb-4 overflow-hidden",children:[e.jsx("div",{className:"bg-gray-50 px-3 py-2 text-sm font-medium text-gray-700 border-b",children:P}),e.jsx("div",{className:"p-4 space-y-3",children:e.jsx("div",{className:"flex items-center gap-3 flex-wrap",children:L.map(($,D)=>{const V=$.name;return e.jsxs("div",{className:"flex items-center",children:[e.jsx("div",{className:`w-5 h-5 rounded-full border flex items-center justify-center ${r[V]?"border-red-500 bg-red-100":"border-gray-300"}`,onClick:A=>n(V,A),children:r[V]&&e.jsx("div",{className:"w-3 h-3 rounded-full bg-red-500"})}),e.jsx("span",{className:"ml-2 text-gray-700 text-xs",children:V})]},`widget-${D}`)})})})]},`node-${f}`)}),e.jsx("div",{className:"mt-6 flex justify-center",children:e.jsx("button",{onClick:m=>x(m),disabled:!c,className:`px-3 py-1.5 text-xs ${c?"bg-pink-200 text-pink-700 hover:bg-pink-300":"bg-gray-200 text-gray-500 cursor-not-allowed"} rounded-md transition-colors`,children:"Next"})})]})},it=({selectedNodes:l,paramTestValues:n,selectedParams:r,updateParamTestValues:x,toggleDropdown:g,openDropdowns:u,handleTestValueSelect:c,searchTerms:m,handleSearch:f,handleSelectAll:P,handleNext:L,handlePrevious:$,handleClose:D,inputValues:V,setInputValues:A,textInputs:T,handleTextInputChange:_,handleAddTextInput:R,handleRemoveTextInput:j,openAiWritingModal:k})=>{const S=(w,M,q,J=0)=>{if(w=isNaN(w)?0:w,M=isNaN(M)?100:M,q=isNaN(q)||q<=0?1:q,M{!l||l.length===0||l.forEach(w=>{const M=w.id.toString(),q=w.widgets||{};Object.values(q).forEach(h=>{const I=h.name;if(!r[I])return;if(!(n[M]?.[I]?.length>0)&&h.type==="number"){const d=h.options?.min||0,G=h.options?.max||100,O=(h.options?.step||10)/10,N=h.options?.precision||0,B=S(d,G,O,N);if(B.length>0){x(M,I,B);const H=`${M}_${I}`;A(p=>({...p,[H]:{min:d.toString(),max:G.toString(),step:O.toString()}}))}}if(h.type==="customtext"||h.type.toLowerCase().includes("text")){const d=`${M}_${I}`,G=T[d]||[""];JSON.stringify(G)!==JSON.stringify(n[M]?.[I]||[""])&&x(M,I,G)}})})},[l,r,n,T,x,A,S]),e.jsxs("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-4",children:[e.jsxs("div",{className:"mb-4 border-b pb-2 flex justify-between items-center",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-base font-medium text-gray-800",children:"Parameter Options"}),e.jsx("p",{className:"text-xs text-gray-500",children:"Configure the test values for each parameter"})]}),e.jsx("button",{className:"text-gray-400 hover:text-gray-600",onClick:D,children:e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),l.length>0?l.map((w,M)=>{const q=w.widgets||{},J=Object.values(q),h=w.id;return e.jsxs("div",{className:"border rounded-md mb-4 overflow-hidden",children:[e.jsxs("div",{className:"bg-gray-50 px-3 py-2 text-xs font-medium text-gray-700 border-b flex justify-between items-center",children:[e.jsxs("span",{children:[w.type," (ID: ",h,")"]}),e.jsx("button",{className:"text-gray-400 hover:text-gray-600",onClick:I=>D(I,M),children:e.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),e.jsx("div",{className:"p-4 space-y-4",children:J.map((I,Y)=>{const d=I.name;if(!r[d])return null;const G=`${h}_${d}`;if(I.type==="customtext"||I.type.toLowerCase().includes("text")){const O=T[G]||[""];return e.jsxs("div",{className:"border-b pb-3",children:[e.jsxs("div",{className:"flex justify-between items-center mb-2",children:[e.jsxs("label",{className:"text-xs font-medium text-gray-700",children:[d,":"]}),e.jsxs("button",{className:"px-2 py-1 bg-blue-100 text-blue-700 rounded text-xs flex items-center hover:bg-blue-200 transition-colors",onClick:()=>k(h,d),children:[e.jsx("svg",{className:"w-3 h-3 mr-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"})}),"AI Writing"]})]}),e.jsx("div",{className:"space-y-2",children:O.map((N,B)=>e.jsxs("div",{className:"flex items-start",children:[e.jsx("textarea",{className:`flex-1 border ${N?"border-gray-300":"border-red-500"} rounded p-2 text-xs resize-y`,rows:2,placeholder:"Enter text...",value:N,onChange:H=>_(h,d,B,H.target.value),required:!0}),e.jsx("button",{className:"ml-2 text-red-500 hover:text-red-700",onClick:()=>j(h,d,B),title:"Remove",children:e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]},B))}),e.jsxs("button",{className:"mt-2 px-2 py-1 border border-dashed border-gray-300 rounded text-xs text-gray-600 hover:bg-gray-50 flex items-center",onClick:()=>R(h,d),children:[e.jsx("svg",{className:"w-3 h-3 mr-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 6v6m0 0v6m0-6h6m-6 0H6"})}),"Add Text"]})]},Y)}if(I.type==="number"){const O=I.options?.min||0,N=I.options?.max||100,B=(I.options?.step||10)/10,H=I.options?.precision||0,p=S(O,N,B,H),U=V[G]||{min:O.toString(),max:N.toString(),step:B.toString()};return e.jsxs("div",{className:"border-b pb-3",children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsxs("label",{className:"text-xs font-medium text-gray-700",children:[d,":"]}),e.jsx("div",{className:"w-4"})]}),e.jsxs("div",{className:"flex space-x-2 items-center",children:[e.jsx("label",{className:"text-xs text-gray-600",children:"Min"}),e.jsx("input",{type:"text",className:"w-12 h-6 border border-gray-300 rounded text-xs px-2",value:U.min,required:!0,onClick:y=>{y.preventDefault(),y.stopPropagation()},onChange:y=>{y.preventDefault(),y.stopPropagation();const E=y.target.value;if(A(W=>({...W,[G]:{...W[G],min:E}})),E===""||!isNaN(parseFloat(E))){const W=E===""?0:parseFloat(E),z=parseFloat(U.max||N.toString()),Q=parseFloat(U.step||B.toString()),K=S(W,z,Q,H);x(h,d,K)}}}),e.jsx("label",{className:"text-xs text-gray-600",children:"Max"}),e.jsx("input",{type:"text",className:"w-12 h-6 border border-gray-300 rounded text-xs px-2",value:U.max,onClick:y=>{y.preventDefault(),y.stopPropagation()},required:!0,onChange:y=>{y.preventDefault(),y.stopPropagation();const E=y.target.value;if(A(W=>({...W,[G]:{...W[G],max:E}})),E===""||!isNaN(parseFloat(E))){const W=parseFloat(U.min||O.toString()),z=E===""?W:parseFloat(E),Q=parseFloat(U.step||B.toString()),K=S(W,z,Q,H);x(h,d,K)}}}),e.jsx("label",{className:"text-xs text-gray-600",children:"Step"}),e.jsx("input",{type:"text",className:"w-12 h-6 border border-gray-300 rounded text-xs px-2",value:U.step,required:!0,onClick:y=>{y.preventDefault(),y.stopPropagation()},onChange:y=>{y.preventDefault(),y.stopPropagation();const E=y.target.value;if(A(W=>({...W,[G]:{...W[G],step:E}})),E===""||!isNaN(parseFloat(E))&&parseFloat(E)>0){const W=parseFloat(U.min||O.toString()),z=parseFloat(U.max||N.toString()),Q=E===""?1:parseFloat(E),K=S(W,z,Q,H);x(h,d,K)}}})]}),e.jsxs("div",{className:"mt-1",children:[e.jsx("label",{className:"text-xs text-gray-600",children:"Test values"}),e.jsx("div",{className:"mt-1 flex flex-wrap gap-1",children:(()=>{const y=n[h]?.[d]||p;if(y.length<=10)return y.map((E,W)=>e.jsxs("div",{className:"px-2 py-0.5 bg-blue-100 text-blue-800 rounded-md flex items-center text-xs cursor-pointer hover:bg-blue-200",onClick:z=>{z.stopPropagation(),c(h,d,E,z)},children:[e.jsx("span",{children:E}),e.jsx("svg",{className:"w-4 h-4 ml-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})]},W));{const E=y.slice(0,5),W=y.slice(y.length-5);return e.jsxs(e.Fragment,{children:[E.map((z,Q)=>e.jsxs("div",{className:"px-2 py-0.5 bg-blue-100 text-blue-800 rounded-md flex items-center text-xs cursor-pointer hover:bg-blue-200",onClick:K=>{K.stopPropagation(),c(h,d,z,K)},children:[e.jsx("span",{children:z}),e.jsx("svg",{className:"w-4 h-4 ml-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})]},`first-${Q}`)),e.jsx("div",{className:"px-2 py-0.5 bg-gray-100 text-gray-600 rounded-md flex items-center text-xs",children:"..."}),W.map((z,Q)=>e.jsxs("div",{className:"px-2 py-0.5 bg-blue-100 text-blue-800 rounded-md flex items-center text-xs cursor-pointer hover:bg-blue-200",onClick:K=>{K.stopPropagation(),c(h,d,z,K)},children:[e.jsx("span",{children:z}),e.jsx("svg",{className:"w-4 h-4 ml-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})]},`last-${Q}`))]})}})()})]}),e.jsx("div",{className:"mt-1",children:e.jsx("p",{className:"text-xs text-gray-500",children:"Values are distributed evenly between Min and Max"})})]},Y)}else if(I.type==="combo"){const O=I.options?.values||[],N=`${h}_${d}`,B=p=>typeof p=="string"?p:p&&typeof p=="object"&&"name"in p?p.name:String(p),H=p=>typeof p=="object"&&p!==null&&"name"in p?p.name:p;return e.jsxs("div",{className:"border-b pb-3",children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsx("label",{className:"text-xs font-medium text-gray-700",children:d}),e.jsxs("div",{className:"relative dropdown-container",children:[e.jsxs("button",{className:`appearance-none border ${(n[h]?.[d]||[]).length===0?"border-red-500":"border-gray-300"} rounded px-2 py-0.5 pr-6 text-xs flex items-center bg-white text-gray-700`,onClick:p=>{p.preventDefault(),p.stopPropagation(),g(h,d,p)},"data-dropdown":N,children:[e.jsx("span",{children:(n[h]?.[d]||[]).length>0?`${d}: ${(n[h]?.[d]||[]).length} selected`:`Select ${d}`}),e.jsx("div",{className:"ml-2",children:e.jsx("svg",{className:"fill-current h-4 w-4",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",children:e.jsx("path",{d:"M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"})})})]}),u[N]&&e.jsxs("div",{className:"absolute z-[9999] mt-1 w-64 bg-white border border-gray-300 rounded-md shadow-lg dropdown-menu",style:{position:"fixed",top:typeof u[N]=="object"?`${u[N].y}px`:"0px",left:typeof u[N]=="object"?`${u[N].x}px`:"0px",maxHeight:"300px",overflowY:"auto"},children:[e.jsx("div",{className:"p-2 border-b sticky top-0 bg-white",children:e.jsx("input",{type:"text",className:"w-full px-2 py-0.5 text-xs border border-gray-300 rounded",placeholder:"Search...",value:m[N]||"",onChange:p=>{p.preventDefault(),p.stopPropagation(),f(h,d,p.target.value)},onClick:p=>{p.preventDefault(),p.stopPropagation()},autoFocus:!0})}),e.jsxs("div",{className:"px-3 py-1.5 bg-gray-50 border-b cursor-pointer text-xs flex items-center text-gray-700 hover:bg-gray-100",onClick:p=>{p.preventDefault(),p.stopPropagation();const y=O.filter(E=>!m[N]||B(E).toLowerCase().includes((m[N]||"").toLowerCase())).map(H);P(h,d,y)},children:[e.jsx("div",{className:`w-4 h-4 mr-2 border rounded-sm flex items-center justify-center ${O.length>0&&(n[h]?.[d]||[]).length===O.length?"bg-blue-500 border-blue-500":(n[h]?.[d]||[]).length>0?"bg-blue-500 border-blue-500 opacity-50":"border-gray-300"}`,children:(n[h]?.[d]||[]).length>0&&e.jsx("svg",{className:"w-3 h-3 text-white",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})})}),e.jsx("span",{className:"font-medium",children:O.length>0&&(n[h]?.[d]||[]).length===O.length?"Deselect All":"Select All"})]}),e.jsxs("div",{className:"max-h-60 overflow-y-auto",children:[O.filter(p=>!m[N]||B(p).toLowerCase().includes((m[N]||"").toLowerCase())).map((p,U)=>e.jsxs("div",{className:"px-3 py-1.5 hover:bg-gray-100 cursor-pointer text-xs flex items-center text-gray-700",onClick:y=>{y.preventDefault(),y.stopPropagation(),c(h,d,H(p),y)},children:[e.jsx("div",{className:`w-4 h-4 mr-2 border rounded-sm flex items-center justify-center ${(n[h]?.[d]||[]).includes(H(p))?"bg-blue-500 border-blue-500":"border-gray-300"}`,children:(n[h]?.[d]||[]).includes(H(p))&&e.jsx("svg",{className:"w-3 h-3 text-white",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})})}),e.jsx("span",{className:"whitespace-normal overflow-hidden text-ellipsis",children:B(p)})]},U)),O.filter(p=>!m[N]||B(p).toLowerCase().includes((m[N]||"").toLowerCase())).length===0&&e.jsx("div",{className:"px-3 py-4 text-sm text-gray-500 text-center",children:"No matching options"})]})]})]})]}),e.jsxs("div",{className:"mt-2",children:[e.jsx("label",{className:"text-xs text-gray-600",children:"Test values"}),(n[h]?.[d]||[]).length===0&&e.jsx("div",{className:"text-xs text-red-500 mt-1",children:"Please select at least one value"}),e.jsx("div",{className:"mt-1 flex flex-wrap gap-1",children:(n[h]?.[d]||[]).map((p,U)=>e.jsxs("div",{className:"px-2 py-0.5 bg-blue-100 text-blue-800 rounded-md flex items-center text-xs",children:[e.jsx("span",{children:p}),e.jsx("svg",{className:"w-4 h-4 ml-1 cursor-pointer hover:text-blue-600",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",onClick:y=>{y.preventDefault(),y.stopPropagation(),c(h,d,p,y)},children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})]},U))})]})]},Y)}else return e.jsxs("div",{className:"border-b pb-3",children:[e.jsx("div",{className:"flex justify-between items-center",children:e.jsx("label",{className:"text-xs font-medium text-gray-700",children:d})}),e.jsxs("div",{className:"mt-2",children:[e.jsx("label",{className:"text-xs text-gray-600",children:"Test values"}),e.jsxs("div",{className:"mt-1 flex flex-wrap gap-1",children:[(n[h]?.[d]||[]).map((O,N)=>e.jsxs("div",{className:"px-2 py-0.5 bg-blue-100 text-blue-800 rounded-md flex items-center text-xs",children:[e.jsx("span",{children:O}),e.jsx("svg",{className:"w-4 h-4 ml-1 cursor-pointer hover:text-blue-600",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",onClick:B=>{B.preventDefault(),B.stopPropagation(),c(h,d,O,B)},children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})]},N)),e.jsxs("button",{className:"px-2 py-0.5 border border-dashed border-blue-300 text-blue-600 rounded-md text-xs flex items-center hover:bg-blue-50",onClick:O=>{O.preventDefault(),O.stopPropagation();const N=`${d}${(n[h]?.[d]||[]).length+1}`;x(h,d,[...n[h]?.[d]||[],N])},children:[e.jsx("svg",{className:"w-4 h-4 mr-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 6v6m0 0v6m0-6h6m-6 0H6"})}),e.jsx("span",{children:"Add"})]})]})]})]},Y)})})]},M)}):e.jsx("div",{className:"border rounded-md mb-4 p-4 text-center text-gray-500",children:"No nodes selected. Please select a node in the workflow to configure parameters."}),e.jsxs("div",{className:"mt-6 flex justify-between",children:[e.jsx("button",{onClick:w=>$(w),className:"px-3 py-1.5 text-xs bg-gray-100 text-gray-800 rounded-md hover:bg-gray-200 transition-colors",children:"Previous"}),e.jsx("button",{onClick:w=>L(w),className:"px-3 py-1.5 text-xs bg-pink-200 text-pink-700 rounded-md hover:bg-pink-300 transition-colors",children:"Next"})]})]})},ct=({selectedNodes:l,paramTestValues:n,selectedParams:r,totalCount:x,errorMessage:g,handlePrevious:u,handleStartGeneration:c,handleClose:m})=>{const[f,P]=b.useState([]),[L,$]=b.useState(null),[D,V]=b.useState(!1);Ie();const A=()=>{const _=Object.values(Z.graph._nodes_by_id),R=[],j=[];for(const S of _)S.type==="SaveImage"?R.push(S.id):S.type==="PreviewImage"&&j.push(S.id);const k=[...R,...j];P(k),k.length===1?$(k[0]):k.length>1&&(V(!0),$(null))};b.useEffect(()=>{A()},[]),b.useEffect(()=>{const _=()=>{if(!Z.canvas.selected_nodes)return;const R=Object.values(Z.canvas.selected_nodes);if(R.length===0)return;const j=R[0];j&&(j.type==="SaveImage"||j.type==="PreviewImage")&&(console.log("Selected image node:",j.id),$(j.id))};return document.addEventListener("click",_),()=>{document.removeEventListener("click",_)}},[]);const T=_=>{if(_&&(_.preventDefault(),_.stopPropagation()),f.length>1&&!L){V(!0);return}c(_,L||void 0)};return e.jsxs("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-4",children:[e.jsxs("div",{className:"mb-4 border-b pb-2 flex justify-between items-center",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-base font-medium text-gray-800",children:"Confirm Test Configuration"}),e.jsxs("p",{className:"text-xs text-gray-500",children:["In the selected parameter combinations, there are ",x," total runs. Each run will generate a separate image."]})]}),e.jsx("button",{className:"text-gray-400 hover:text-gray-600",onClick:m,children:e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),D&&f.length>1&&e.jsx("div",{className:"mb-4 p-3 bg-yellow-50 border border-yellow-200 rounded-md text-amber-600 text-xs",children:e.jsxs("div",{className:"flex items-start",children:[e.jsx("div",{className:"flex-shrink-0 mt-0.5",children:e.jsx("svg",{className:"h-3 w-3",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})})}),e.jsx("div",{className:"ml-2",children:L===null?`Multiple SaveImage and PreviewImage nodes detected with IDs ${f.join(",")}. Please click the node on canvas.`:`Current node ID is ${L}, please click Start Generation again`})]})}),g&&e.jsx("div",{className:"mb-4 p-3 bg-red-50 border border-red-200 rounded-md text-red-600 text-xs",children:e.jsxs("div",{className:"flex items-start",children:[e.jsx("div",{className:"flex-shrink-0 mt-0.5",children:e.jsx("svg",{className:"h-3 w-3",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})})}),e.jsx("div",{className:"ml-2",children:g})]})}),l.length>0?l.map((_,R)=>{const j=_.type||"Unknown Node",k=_.widgets||[],S=_.id;return e.jsxs("div",{className:"border rounded-md mb-4 overflow-hidden",children:[e.jsxs("div",{className:"bg-gray-50 px-3 py-2 text-xs font-medium text-gray-700 border-b",children:[j," (ID: ",S,")"]}),e.jsx("div",{className:"p-4 space-y-3",children:k.map((w,M)=>{const q=w.name;if(!r[q])return null;const J=n[S]?.[q]||[],h=Array.isArray(J)?`[${J.join(", ")}]`:JSON.stringify(J);return e.jsxs("div",{className:MI.preventDefault()})})]},M)})})]},R)}):e.jsx("div",{className:"border rounded-md mb-4 p-4 text-center text-gray-500 text-xs",children:"No nodes selected. Please select a node in the workflow to configure parameters."}),e.jsxs("div",{className:"mt-6 flex justify-between",children:[e.jsx("button",{onClick:_=>u(_),className:"px-3 py-1.5 text-xs bg-gray-100 text-gray-800 rounded-md hover:bg-gray-200 transition-colors",children:"Previous"}),e.jsx("button",{onClick:_=>T(_),className:`px-3 py-1.5 text-xs rounded-md transition-colors ${f.length>1&&!L?"bg-gray-200 text-gray-500 cursor-not-allowed":"bg-pink-200 text-pink-700 hover:bg-pink-300"}`,disabled:f.length>1&&!L,children:"Start Generation"})]})]})},dt=({selectedNodes:l,paramTestValues:n,selectedParams:r,totalCount:x,completedCount:g,errorMessage:u,handleClose:c,setIsProcessing:m,setCurrentScreen:f,cleanupPolling:P})=>{const L=$=>{$.preventDefault(),$.stopPropagation(),Ze({clear:!0}),et(),P&&P(),m(!1),f(2)};return e.jsxs("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-4 relative",children:[e.jsx("div",{className:"absolute inset-0 bg-gray-500 bg-opacity-30 flex flex-col items-center justify-center z-10",children:e.jsxs("div",{className:"text-center text-gray-800 bg-white p-4 rounded-lg shadow-lg",children:[e.jsx("div",{className:"mb-2 text-sm font-medium",children:"Processing..."}),e.jsxs("div",{className:"text-xs mb-3",children:["Completed ",g," of ",x," runs"]}),e.jsx("div",{className:"w-48 h-2 bg-gray-200 rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full bg-pink-500 transition-all duration-200",style:{width:`${g/x*100}%`}})}),e.jsxs("div",{className:"mt-2 text-xs text-gray-600",children:["Already generated ",g," images"]}),e.jsx("button",{onClick:L,className:"mt-4 px-3 py-1.5 text-xs bg-gray-200 text-gray-800 rounded-md hover:bg-gray-300 transition-colors",children:"Cancel"})]})}),e.jsxs("div",{className:"mb-4 border-b pb-2 flex justify-between items-center",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-base font-medium text-gray-800",children:"Confirm Test Configuration"}),e.jsxs("p",{className:"text-xs text-gray-500",children:["In the selected parameter combinations, there are ",x," total runs. Each run will generate a separate image."]})]}),e.jsx("button",{className:"text-gray-400 hover:text-gray-600",onClick:c,children:e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),u&&e.jsx("div",{className:"mb-4 p-3 bg-red-50 border border-red-200 rounded-md text-red-600 text-xs",children:e.jsxs("div",{className:"flex items-start",children:[e.jsx("div",{className:"flex-shrink-0 mt-0.5",children:e.jsx("svg",{className:"h-3 w-3",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})})}),e.jsx("div",{className:"ml-2",children:u})]})}),l.length>0?l.map(($,D)=>{const V=$.type||"Unknown Node",A=$.widgets||[],T=$.id;return e.jsxs("div",{className:"border rounded-md mb-4 overflow-hidden",children:[e.jsxs("div",{className:"bg-gray-50 px-3 py-2 text-xs font-medium text-gray-700 border-b",children:[V," (ID: ",T,")"]}),e.jsx("div",{className:"p-4 space-y-3",children:A.map((_,R)=>{const j=_.name;if(!r[j])return null;const k=n[T]?.[j]||[],S=Array.isArray(k)?`[${k.join(", ")}]`:JSON.stringify(k);return e.jsxs("div",{className:Rw.preventDefault()})})]},R)})})]},D)}):e.jsx("div",{className:"border rounded-md mb-4 p-4 text-center text-gray-500",children:"No nodes selected. Please select a node in the workflow to configure parameters."})]})},xt=({generatedImages:l,selectedImageIndex:n,handleSelectImage:r,handleApplySelected:x,handlePrevious:g,handleClose:u,currentPage:c,handlePageChange:m,imagesPerPage:f,notificationVisible:P,modalVisible:L,modalImageUrl:$,openImageModal:D,closeImageModal:V})=>{const A=Math.ceil(l.length/f),T=(c-1)*f,_=Math.min(T+f,l.length),R=l.slice(T,_);return e.jsxs("div",{className:"bg-white rounded-lg shadow-sm border border-gray-200 p-4",children:[e.jsxs("div",{className:"mb-4 border-b pb-2 flex justify-between items-center",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-base font-medium text-gray-800",children:"Generation Complete"}),e.jsxs("p",{className:"text-xs text-gray-500",children:["All ",l.length," images have been generated."]})]}),e.jsx("button",{className:"text-gray-400 hover:text-gray-600",onClick:u,children:e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),P&&e.jsx("div",{className:"fixed top-4 right-4 bg-green-100 border-l-4 border-green-500 text-green-700 p-3 shadow-md rounded animate-fade-in-out z-50",children:e.jsxs("div",{className:"flex items-center",children:[e.jsx("div",{className:"py-1",children:e.jsx("svg",{className:"h-4 w-4 text-green-500 mr-3",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})})}),e.jsx("p",{className:"text-xs",children:"Parameters has been applied."})]})}),L&&e.jsx("div",{className:"fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50",onClick:V,children:e.jsxs("div",{className:"bg-white rounded-lg p-2 max-w-4xl max-h-[90vh] relative",onClick:j=>j.stopPropagation(),children:[e.jsx("button",{className:"absolute top-2 right-2 text-gray-700 hover:text-gray-900 rounded-full hover:bg-gray-200 p-1",onClick:V,children:e.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})}),e.jsx("div",{className:"overflow-auto max-h-[calc(90vh-4rem)]",children:e.jsx("img",{src:$,alt:"Enlarged image",className:"max-w-full h-auto"})})]})}),e.jsx("div",{className:"grid grid-cols-3 gap-4 mb-6",children:R.map((j,k)=>{const S=T+k;return e.jsxs("div",{className:`relative rounded-lg overflow-hidden border ${n===S?"border-pink-500 ring-2 ring-pink-300":"border-gray-200"}`,onClick:w=>r(S,w),children:[e.jsx("button",{className:"absolute top-2 right-2 bg-white bg-opacity-75 rounded-full p-0.5 text-gray-600 hover:text-gray-900 shadow-sm z-10",onClick:w=>D(j.url,w),children:e.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5v-4m0 4h-4m4 0l-5-5"})})}),e.jsx("div",{className:"aspect-square",children:e.jsx("img",{src:j.url,alt:`Generated image ${S+1}`,className:"w-full h-full object-cover"})}),e.jsx("div",{className:"p-2 text-xs text-gray-600 bg-white max-h-16 overflow-y-auto",children:Object.entries(j.params).filter(([w,M])=>w!=="nodeParams"&&typeof M!="object").map(([w,M])=>e.jsxs("div",{children:[w,": ",String(M)]},w))})]},S)})}),A>1&&e.jsxs("div",{className:"flex justify-center items-center space-x-2 mt-4 mb-4",children:[e.jsx("button",{onClick:j=>m(1,j),disabled:c===1,className:`px-2 py-1 rounded ${c===1?"text-gray-400 cursor-not-allowed":"text-gray-700 hover:bg-gray-100"}`,children:e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",viewBox:"0 0 20 20",fill:"currentColor",children:[e.jsx("path",{fillRule:"evenodd",d:"M15.707 15.707a1 1 0 01-1.414 0l-5-5a1 1 0 010-1.414l5-5a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 010 1.414z",clipRule:"evenodd"}),e.jsx("path",{fillRule:"evenodd",d:"M8.707 15.707a1 1 0 01-1.414 0l-5-5a1 1 0 010-1.414l5-5a1 1 0 111.414 1.414L4.414 10l4.293 4.293a1 1 0 010 1.414z",clipRule:"evenodd"})]})}),e.jsx("button",{onClick:j=>m(c-1,j),disabled:c===1,className:`px-2 py-1 rounded ${c===1?"text-gray-400 cursor-not-allowed":"text-gray-700 hover:bg-gray-100"}`,children:e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z",clipRule:"evenodd"})})}),e.jsxs("div",{className:"px-2 py-1 text-xs text-gray-800",children:["Page ",c," of ",A]}),e.jsx("button",{onClick:j=>m(c+1,j),disabled:c===A,className:`px-2 py-1 rounded ${c===A?"text-gray-400 cursor-not-allowed":"text-gray-700 hover:bg-gray-100"}`,children:e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z",clipRule:"evenodd"})})}),e.jsx("button",{onClick:j=>m(A,j),disabled:c===A,className:`px-2 py-1 rounded ${c===A?"text-gray-400 cursor-not-allowed":"text-gray-700 hover:bg-gray-100"}`,children:e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",viewBox:"0 0 20 20",fill:"currentColor",children:[e.jsx("path",{fillRule:"evenodd",d:"M4.293 15.707a1 1 0 001.414 0l5-5a1 1 0 000-1.414l-5-5a1 1 0 00-1.414 1.414L8.586 10 4.293 14.293a1 1 0 000 1.414z",clipRule:"evenodd"}),e.jsx("path",{fillRule:"evenodd",d:"M11.293 15.707a1 1 0 001.414 0l5-5a1 1 0 000-1.414l-5-5a1 1 0 00-1.414 1.414L15.586 10l-4.293 4.293a1 1 0 000 1.414z",clipRule:"evenodd"})]})})]}),e.jsxs("div",{className:"mt-6 flex justify-between",children:[e.jsx("button",{onClick:j=>g(j),className:"px-3 py-1.5 text-xs bg-gray-100 text-gray-800 rounded-md hover:bg-gray-200 transition-colors",children:"Previous"}),e.jsx("button",{onClick:j=>x(j),className:"px-3 py-1.5 text-xs bg-pink-200 text-pink-700 rounded-md hover:bg-pink-300 transition-colors",disabled:n===null,children:"Apply Selected"})]})]})},ut=({visible:l,aiWritingModalText:n,setAiWritingModalText:r,aiGeneratedTexts:x,aiSelectedTexts:g,aiWritingLoading:u,aiWritingError:c,handleAiWriting:m,toggleTextSelection:f,addSelectedTexts:P,onClose:L})=>l?e.jsx("div",{className:"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50",children:e.jsxs("div",{className:"bg-white rounded-lg shadow-lg w-full max-w-2xl max-h-[90vh] flex flex-col",children:[e.jsxs("div",{className:"p-4 border-b flex justify-between items-center",children:[e.jsx("h3",{className:"text-lg font-medium",children:"AI Writing Assistant"}),e.jsx("button",{className:"text-gray-400 hover:text-gray-600",onClick:L,children:e.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),e.jsxs("div",{className:"p-4 overflow-y-auto flex-1",children:[e.jsxs("div",{className:"mb-4",children:[e.jsx("p",{className:"text-sm text-gray-600 mb-2",children:"Enter text and AI will generate variations"}),e.jsx("textarea",{className:"w-full border border-gray-300 rounded-md p-2 text-sm",rows:3,placeholder:"Enter some text here...",value:n,onChange:$=>r($.target.value)}),e.jsx("button",{className:"mt-2 px-4 py-2 bg-blue-100 text-blue-700 rounded-md text-sm flex items-center hover:bg-blue-200 transition-colors",onClick:m,disabled:u,children:u?e.jsxs(e.Fragment,{children:[e.jsxs("svg",{className:"animate-spin -ml-1 mr-2 h-4 w-4 text-blue-700",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",children:[e.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),e.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),"Generating..."]}):e.jsx(e.Fragment,{children:"Generate"})})]}),c&&e.jsx("div",{className:"mb-4 p-3 bg-red-50 border border-red-200 rounded-md text-red-600 text-sm",children:c}),x.length>0&&e.jsxs("div",{className:"mb-4",children:[e.jsx("p",{className:"text-sm font-medium mb-2",children:"Generated variations (select items to add):"}),e.jsx("div",{className:"space-y-2 max-h-[40vh] overflow-y-auto p-2",children:x.map(($,D)=>e.jsxs("div",{className:"flex items-start border border-gray-200 rounded-md p-2",children:[e.jsx("div",{className:"mr-2 mt-1",children:e.jsxs("div",{className:"relative",children:[e.jsx("input",{type:"checkbox",id:`text${D+1}`,checked:!!g[`text${D+1}`],onChange:()=>f(`text${D+1}`),className:"sr-only"}),e.jsx("div",{className:`h-4 w-4 rounded border ${g[`text${D+1}`]?"bg-blue-600 border-blue-600":"bg-white border-gray-300"} flex items-center justify-center`,onClick:()=>f(`text${D+1}`),children:g[`text${D+1}`]&&e.jsx("svg",{className:"h-3 w-3 text-white",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})})})]})}),e.jsx("label",{htmlFor:`text${D+1}`,className:"text-sm text-gray-700 cursor-pointer flex-1",children:$})]},D))})]})]}),e.jsxs("div",{className:"p-4 border-t flex justify-end flex-shrink-0",children:[e.jsx("button",{className:"px-4 py-2 bg-gray-100 text-gray-700 rounded-md text-sm mr-2 hover:bg-gray-200 transition-colors",onClick:L,children:"Cancel"}),e.jsx("button",{className:"px-4 py-2 bg-blue-500 text-white rounded-md text-sm hover:bg-blue-600 transition-colors",onClick:P,disabled:Object.values(g).every($=>!$),children:"Add Selected"})]})]})}):null,ye=l=>{const n=[],r={};if(Object.keys(l).forEach(u=>{const c=parseInt(u),m=l[u]||{},f=Object.keys(m).filter(L=>m[L]&&m[L].length>0);if(f.length===0)return;const P=[[]];f.forEach(L=>{const $=m[L],D=[];P.forEach(V=>{$.forEach(A=>{const T=[...V,{nodeId:c,paramName:L,paramValue:String(A)}];D.push(T)})}),P.length=0,P.push(...D)}),r[u]=P}),Object.keys(r).length===0)return n;if(Object.keys(r).length===1){const u=Object.keys(r)[0];return r[u]}const x=Object.keys(r);let g=r[x[0]];for(let u=1;u{c.forEach(P=>{m.push([...f,...P])})}),g=m}return g},mt=(l,n)=>{const r={};r.nodeParams={};const x=ye(l);return n{const c=u.nodeId.toString(),m=u.paramName,f=u.paramValue;r.nodeParams[c]||(r.nodeParams[c]={}),r.nodeParams[c][m]=f,r[m]=f}),r},ht=` + @keyframes highlight-pulse { + 0% { + box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.5); + } + 70% { + box-shadow: 0 0 0 15px rgba(59, 130, 246, 0); + } + 100% { + box-shadow: 0 0 0 0 rgba(59, 130, 246, 0); + } + } + + .highlight-pulse { + animation: highlight-pulse 1.5s infinite; + border: 2px solid #3b82f6; + } + + @keyframes fade-in-out { + 0% { opacity: 0; transform: translateY(-20px); } + 10% { opacity: 1; transform: translateY(0); } + 90% { opacity: 1; transform: translateY(0); } + 100% { opacity: 0; transform: translateY(-20px); } + } + + .animate-fade-in-out { + animation: fade-in-out 3s forwards; + } +`,vt=({selectedNodes:l,visible:n,onClose:r})=>{const[x,g]=b.useState(0),[u,c]=b.useState({Steps:!0,CFG:!0,sampler_name:!0,threshold:!1,prompt:!1}),[m,f]=b.useState(!1),[P,L]=b.useState(!1),[$,D]=b.useState(0),[V,A]=b.useState(12),[T,_]=b.useState(null),[R,j]=b.useState(()=>Array(12).fill(null).map((t,s)=>({url:`https://source.unsplash.com/random/300x300?sig=${Math.random()}`,params:{step:s%3===0?5:s%3===1?10:15,sampler_name:"euler",cfg:1}}))),[k,S]=b.useState({}),[w,M]=b.useState({}),[q,J]=b.useState({}),[h,I]=b.useState({}),[Y,d]=b.useState(1),G=6,[O,N]=b.useState(null),[B,H]=b.useState(!1),[p,U]=b.useState(!1),[y,E]=b.useState(""),[W,z]=b.useState({}),[Q,K]=b.useState(!1),[pe,ge]=b.useState(""),[ve,de]=b.useState([]),[Ee,xe]=b.useState(!1),[we,Ne]=b.useState(""),[ke,Ce]=b.useState(""),[$e,ne]=b.useState(null),[Se,oe]=b.useState({}),{dispatch:ae}=Ie(),ue=b.useRef(null),le=b.useRef(null),We=async()=>{if(!pe.trim()){ne("Please enter some text to generate variations");return}xe(!0),ne(null),de([]),oe({});try{const t=await Pe.generateSDPrompts(pe);de(t);const s={};t.forEach((i,o)=>{s[`text${o+1}`]=!1}),oe(s)}catch(t){console.error("Error generating text:",t),ne("Failed to generate text variations. Please try again.")}finally{xe(!1)}},De=(t,s,i,o)=>{const a=`${t}_${s}`;z(v=>{const F=[...v[a]||[]];return F[i]=o,{...v,[a]:F}});const C=[...W[a]||[]];C[i]=o,ee(t,s,C)},_e=(t,s)=>{const i=`${t}_${s}`;z(a=>{const C=[...a[i]||[]];return C.push(""),{...a,[i]:C}});const o=[...W[i]||[],""];ee(t,s,o)},Oe=(t,s,i)=>{const o=`${t}_${s}`;z(C=>{const v=[...C[o]||[]];return v.splice(i,1),{...C,[o]:v}});const a=[...W[o]||[]];a.splice(i,1),ee(t,s,a)},Ae=t=>{oe(s=>({...s,[t]:!s[t]}))},Be=()=>{const t=`${we}_${ke}`,s=Object.entries(Se).filter(([o,a])=>a).map(([o])=>{const a=parseInt(o.replace("text",""))-1;return ve[a]});if(s.length===0)return;z(o=>{const a=[...o[t]||[]];return{...o,[t]:[...a,...s]}});const i=[...W[t]||[],...s];ee(we,ke,i),K(!1)},Te=(t,s)=>{K(!0),Ne(t),Ce(s),ge(""),de([]),oe({}),xe(!1),ne(null)};b.useEffect(()=>{if(!l||l.length===0)return;const t={...k},s=l.map(o=>o.id.toString());Object.keys(t).forEach(o=>{s.includes(o)||delete t[o]}),l.forEach(o=>{const a=o.id.toString();t[a]||(t[a]={})}),JSON.stringify(t)!==JSON.stringify(k)&&S(t)},[l,k]),b.useEffect(()=>{ae({type:"SET_SCREEN_STATE",payload:{currentScreen:x,isProcessing:m,isCompleted:P}})},[x,m,P,ae]),b.useEffect(()=>{const t=document.createElement("style");return t.textContent=ht,document.head.appendChild(t),()=>{document.head.removeChild(t)}},[]),b.useEffect(()=>{const t=s=>{if(Object.values(w).some(i=>i)){const i=s.target,o=!!i.closest(".dropdown-menu"),a=!!i.closest("[data-dropdown]");!o&&!a&&M({})}};return document.addEventListener("mousedown",t),()=>{document.removeEventListener("mousedown",t)}},[w]);const Le=t=>{if(t&&(t.preventDefault(),t.stopPropagation()),x===0){const s={...k};Object.keys(s).forEach(i=>{const o=s[i];Object.keys(o).forEach(a=>{u[a]||delete o[a]})}),S(s)}if(x===1){const s={...k};l.forEach(o=>{const a=o.id.toString(),C=o.widgets||{};Object.values(C).forEach(v=>{const F=v.name;if(u[F]&&(v.type==="customtext"||v.type.toLowerCase().includes("text"))){const te=`${a}_${F}`,se=W[te]||[""];s[a]=s[a]||{},s[a][F]=se}})}),S(s);const i=ye(s);A(i.length)}N(null),g(s=>Math.min(s+1,2))},fe=t=>{if(t&&(t.preventDefault(),t.stopPropagation()),N(null),P&&L(!1),x===1){const s=l.map(a=>a.id.toString()),i=Object.keys(k),o={...k};i.forEach(a=>{s.includes(a)||delete o[a]}),S(o)}if(x===2||P){const s={...k};Object.entries(W).forEach(([i,o])=>{if(!o||o.length===0)return;const[a,C]=i.split("_");l.some(v=>v.id.toString()===a)&&(s[a]=s[a]||{},JSON.stringify(s[a][C])!==JSON.stringify(o)&&(s[a][C]=o))}),S(s)}g(s=>Math.max(s-1,0))},Re=(t,s)=>{s&&(s.preventDefault(),s.stopPropagation());const i=u[t];if(c(o=>({...o,[t]:!i})),i){const o={...k};Object.keys(o).forEach(a=>{o[a][t]&&delete o[a][t]}),S(o)}},ze=(t,s,i)=>{i.preventDefault(),i.stopPropagation();const o=`${t}_${s}`;M(a=>{if(a[o]&&typeof a[o]=="object"?a[o].isOpen:!!a[o])return{...a,[o]:!1};{let v=0,F=0;if(i.currentTarget){const ce=i.currentTarget.getBoundingClientRect();v=ce.left,F=ce.bottom}else v=i.clientX,F=i.clientY+20;const te=window.innerWidth,se=250;return v+se>te&&(v=te-se-10),v<0&&(v=10),{...a,[o]:{isOpen:!0,x:v,y:F}}}})},ee=(t,s,i)=>{S(o=>{const a={...o};return a[t]||(a[t]={}),a[t][s]=i,a})},Fe=(t,s,i,o)=>{o&&(o.preventDefault(),o.stopPropagation()),S(a=>{const C={...a};C[t]||(C[t]={}),C[t][s]||(C[t][s]=[]);const v=C[t][s];return v.includes(i)?C[t][s]=v.filter(F=>F!==i):C[t][s]=[...v,i],C})},Ve=(t,s,i)=>{const o=`${t}_${s}`;J(a=>({...a,[o]:i}))},Ge=(t,s,i)=>{if(!k[t]){ee(t,s,i);return}const o=k[t][s]||[];i.length===o.length?ee(t,s,[]):ee(t,s,[...i])},Ue=(t,s)=>{s&&(s.preventDefault(),s.stopPropagation()),d(Math.max(1,Math.min(t,Math.ceil(R.length/G))))},me=()=>{ue.current&&(clearTimeout(ue.current),ue.current=null),le.current=null};b.useEffect(()=>()=>{me()},[]);const He=async(t,s)=>{t&&(t.preventDefault(),t.stopPropagation()),me();const i=ye(k),o=i.length;if(o>100){N(`Cannot generate more than 100 images at once (currently: ${o} images)`);return}if(N(null),f(!0),D(0),console.log("Generated parameter combinations:",i),i.length===0){N("No valid parameter combinations found. Please check your parameter selections."),f(!1);return}let a=s||null;if(a===null){const v=ot();v!==null&&(a=v)}if(a===null){N("Please select a SaveImage or PreviewImage node first."),f(!1);return}const C=[];try{const v=Date.now().toString();le.current=v;for(const re of i){const X=await rt(re);X.prompt_id?C.push(X.prompt_id):(console.error("Failed to get prompt_id from response:",X),C.push(""))}const F=Array(i.length).fill(null).map((re,X)=>({url:`https://source.unsplash.com/random/300x300?sig=${Math.random()}`,params:mt(k,X)}));j(F);const te=Date.now(),se=5*60*1e3,ce=async()=>{if(le.current!==v){console.log("Another polling session has started, stopping this one");return}if(Date.now()-te>se){console.log("Timeout reached while waiting for images"),le.current===v&&(f(!1),L(!0),d(1));return}let re=0;for(let X=0;X{s&&(s.preventDefault(),s.stopPropagation()),_(t)},Ke=(t,s)=>{s.preventDefault(),s.stopPropagation(),E(t),U(!0)},Je=t=>{t&&(t.preventDefault(),t.stopPropagation()),U(!1)},Ye=async t=>{if(t&&(t.preventDefault(),t.stopPropagation()),T!==null){console.log(`Applied image ${T+1} with parameters:`,R[T].params),Pe.trackEvent({event_type:"parameter_debug_apply",message_type:"parameter_debug",message_id:tt(),data:{workflow:(await Z.graphToPrompt()).output,selected_params:R[T].params,all_params:k,count:Object.keys(k).length}});const s=R[T].params;s.nodeParams&&(Object.entries(s.nodeParams).forEach(([i,o])=>{const a=Z.graph._nodes_by_id[i];!a||!a.widgets||Object.entries(o).forEach(([C,v])=>{for(const F of a.widgets)if(F.name===C){F.value=v;break}})}),Z.graph.setDirtyCanvas(!1,!0),H(!0),setTimeout(()=>{H(!1)},3e3))}},ie=(t,s)=>{if(t&&(t.preventDefault(),t.stopPropagation()),x===1&&s!==void 0){const i=[...l],o=i[s];if(i.splice(s,1),o){const a=o.id.toString();S(C=>{const v={...C};return delete v[a],v})}i.length===0?r&&(ae({type:"SET_SCREEN_STATE",payload:null}),be(),r()):ae({type:"SET_SELECTED_NODE",payload:i});return}r?(ae({type:"SET_SCREEN_STATE",payload:null}),be(),r()):be()},be=()=>{g(0),c({Steps:!0,CFG:!0,sampler_name:!0,threshold:!1,prompt:!1}),me(),f(!1),L(!1),D(0),A(12),_(null),j(Array(12).fill(null).map((t,s)=>({url:`https://source.unsplash.com/random/300x300?sig=${Math.random()}`,params:{step:s%3===0?5:s%3===1?10:15,sampler_name:"euler",cfg:1}}))),S({}),M({}),J({}),I({}),d(1),N(null),H(!1),U(!1),E(""),z({}),K(!1),ge(""),de([]),xe(!1),Ne(""),Ce(""),ne(null),oe({})};return!n||l.length===0?e.jsx("div",{className:"flex-1 flex flex-col items-center justify-center p-8 bg-gray-50 overflow-y-auto",onClick:t=>t.stopPropagation(),children:e.jsxs("div",{className:"max-w-lg p-8 bg-white rounded-lg shadow-sm border border-blue-100 relative",children:[e.jsxs("div",{className:"mb-6 text-center",children:[e.jsx("h3",{className:"text-base font-bold text-blue-800 mb-2",children:"GenLab"}),e.jsx("div",{className:"h-1 w-16 bg-blue-500 mx-auto rounded-full mb-4"})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-start space-x-3",children:[e.jsx("div",{className:"bg-blue-100 p-2 rounded-full text-blue-600",children:e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{d:"M5 3a2 2 0 00-2 2v2a2 2 0 002 2h2a2 2 0 002-2V5a2 2 0 00-2-2H5zM5 11a2 2 0 00-2 2v2a2 2 0 002 2h2a2 2 0 002-2v-2a2 2 0 00-2-2H5zM11 5a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V5zM11 13a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"})})}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-medium text-gray-800",children:"Batch Test Parameter Pairs"}),e.jsx("p",{className:"text-xs text-gray-600",children:"Select a node to batch test parameter pairs"})]})]}),e.jsxs("div",{className:"flex items-start space-x-3",children:[e.jsx("div",{className:"bg-indigo-100 p-2 rounded-full text-indigo-600",children:e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z",clipRule:"evenodd"})})}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-medium text-gray-800",children:"How To Use"}),e.jsx("p",{className:"text-xs text-gray-600",children:"Click on any node in your workflow to start the parameter testing process"})]})]}),e.jsx("div",{className:"mt-6 text-center",children:e.jsx("p",{className:"text-xs text-gray-600 mb-3",children:"No node is currently selected"})})]})]})}):P?e.jsx("div",{className:"flex-1 overflow-y-auto bg-gray-50 p-4",onClick:t=>t.stopPropagation(),children:e.jsx(xt,{generatedImages:R,selectedImageIndex:T,handleSelectImage:qe,handleApplySelected:Ye,handlePrevious:fe,handleClose:ie,currentPage:Y,handlePageChange:Ue,imagesPerPage:G,notificationVisible:B,modalVisible:p,modalImageUrl:y,openImageModal:Ke,closeImageModal:Je})}):m?e.jsx("div",{className:"flex-1 overflow-y-auto bg-gray-50 p-4",onClick:t=>t.stopPropagation(),children:e.jsx(dt,{selectedNodes:l,paramTestValues:k,selectedParams:u,totalCount:V,completedCount:$,errorMessage:O,handleClose:ie,setIsProcessing:f,setCurrentScreen:g,cleanupPolling:me})}):x===0?e.jsx("div",{className:"flex-1 overflow-y-auto bg-gray-50 p-4 flex flex-col h-full max-h-[80vh]",onClick:t=>t.stopPropagation(),children:e.jsx(lt,{selectedNodes:l,handleParamSelect:Re,selectedParams:u,handleNext:Le,handleClose:ie})}):x===1?e.jsxs("div",{className:"flex-1 overflow-y-auto bg-gray-50 p-4 flex flex-col h-full max-h-[80vh]",onClick:t=>t.stopPropagation(),children:[e.jsx(it,{selectedNodes:l,paramTestValues:k,selectedParams:u,updateParamTestValues:ee,toggleDropdown:ze,openDropdowns:w,handleTestValueSelect:Fe,searchTerms:q,handleSearch:Ve,handleSelectAll:Ge,handleNext:Le,handlePrevious:fe,handleClose:ie,inputValues:h,setInputValues:I,textInputs:W,handleTextInputChange:De,handleAddTextInput:_e,handleRemoveTextInput:Oe,openAiWritingModal:Te}),e.jsx(ut,{visible:Q,aiWritingModalText:pe,setAiWritingModalText:ge,aiGeneratedTexts:ve,aiSelectedTexts:Se,aiWritingLoading:Ee,aiWritingError:$e,handleAiWriting:We,toggleTextSelection:Ae,addSelectedTexts:Be,onClose:()=>K(!1)})]}):e.jsx("div",{className:"flex-1 overflow-y-auto bg-gray-50 p-4 flex flex-col h-full max-h-[80vh]",onClick:t=>t.stopPropagation(),children:e.jsx(ct,{selectedNodes:l,paramTestValues:k,selectedParams:u,totalCount:V,errorMessage:O,handlePrevious:fe,handleStartGeneration:He,handleClose:ie})})};export{vt as ParameterDebugInterface}; diff --git a/dist/copilot_web/input.js b/dist/copilot_web/input.js index 32d49ac..c0ab0cd 100644 --- a/dist/copilot_web/input.js +++ b/dist/copilot_web/input.js @@ -1,2 +1,2 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["copilot_web/App-DU9tUae4.js","copilot_web/vendor-markdown-Dek94WS0.js","copilot_web/vendor-react-V04_Axys.js","copilot_web/message-components-D3rPBq8S.js"])))=>i.map(i=>d[i]); -import{j as u}from"./vendor-markdown-Dek94WS0.js";import{a as v,R as p}from"./vendor-react-V04_Axys.js";import{w}from"./message-components-D3rPBq8S.js";const R="modulepreload",b=function(e){return"/"+e},m={},P=function(a,s,S){let d=Promise.resolve();if(s&&s.length>0){document.getElementsByTagName("link");const r=document.querySelector("meta[property=csp-nonce]"),t=r?.nonce||r?.getAttribute("nonce");d=Promise.allSettled(s.map(o=>{if(o=b(o),o in m)return;m[o]=!0;const c=o.endsWith(".css"),h=c?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${o}"]${h}`))return;const n=document.createElement("link");if(n.rel=c?"stylesheet":R,c||(n.as="script"),n.crossOrigin="",n.href=o,t&&n.setAttribute("nonce",t),document.head.appendChild(n),c)return new Promise((y,E)=>{n.addEventListener("load",y),n.addEventListener("error",()=>E(new Error(`Unable to preload CSS for ${o}`)))})}))}function l(r){const t=new Event("vite:preloadError",{cancelable:!0});if(t.payload=r,window.dispatchEvent(t),!t.defaultPrevented)throw r}return d.then(r=>{for(const t of r||[])t.status==="rejected"&&l(t.reason);return a().catch(l)})};var i={},f=v;i.createRoot=f.createRoot,i.hydrateRoot=f.hydrateRoot;const _=p.lazy(()=>P(async()=>{const{default:e}=await import("./App-DU9tUae4.js").then(a=>a.A);return{default:e}},__vite__mapDeps([0,1,2,3])).then(({default:e})=>({default:e})));function A(){return new Promise(e=>{if(document.body)return e(document.body);document.addEventListener("DOMContentLoaded",()=>{e(document.body)})})}A().then(()=>w()).then(()=>{const e=document.createElement("div");e.id="comfyui-copilot-plugin",document.body.append(e),i.createRoot(e).render(u.jsx(p.StrictMode,{children:u.jsx(_,{})}))});export{P as _}; +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["copilot_web/App-B_5DJBtC.js","copilot_web/vendor-markdown-Dek94WS0.js","copilot_web/vendor-react-V04_Axys.js","copilot_web/message-components-D3rPBq8S.js"])))=>i.map(i=>d[i]); +import{j as u}from"./vendor-markdown-Dek94WS0.js";import{a as v,R as p}from"./vendor-react-V04_Axys.js";import{w}from"./message-components-D3rPBq8S.js";const R="modulepreload",b=function(e){return"/"+e},m={},P=function(a,s,S){let d=Promise.resolve();if(s&&s.length>0){document.getElementsByTagName("link");const r=document.querySelector("meta[property=csp-nonce]"),t=r?.nonce||r?.getAttribute("nonce");d=Promise.allSettled(s.map(o=>{if(o=b(o),o in m)return;m[o]=!0;const c=o.endsWith(".css"),h=c?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${o}"]${h}`))return;const n=document.createElement("link");if(n.rel=c?"stylesheet":R,c||(n.as="script"),n.crossOrigin="",n.href=o,t&&n.setAttribute("nonce",t),document.head.appendChild(n),c)return new Promise((y,E)=>{n.addEventListener("load",y),n.addEventListener("error",()=>E(new Error(`Unable to preload CSS for ${o}`)))})}))}function l(r){const t=new Event("vite:preloadError",{cancelable:!0});if(t.payload=r,window.dispatchEvent(t),!t.defaultPrevented)throw r}return d.then(r=>{for(const t of r||[])t.status==="rejected"&&l(t.reason);return a().catch(l)})};var i={},f=v;i.createRoot=f.createRoot,i.hydrateRoot=f.hydrateRoot;const _=p.lazy(()=>P(async()=>{const{default:e}=await import("./App-B_5DJBtC.js").then(a=>a.A);return{default:e}},__vite__mapDeps([0,1,2,3])).then(({default:e})=>({default:e})));function A(){return new Promise(e=>{if(document.body)return e(document.body);document.addEventListener("DOMContentLoaded",()=>{e(document.body)})})}A().then(()=>w()).then(()=>{const e=document.createElement("div");e.id="comfyui-copilot-plugin",document.body.append(e),i.createRoot(e).render(u.jsx(p.StrictMode,{children:u.jsx(_,{})}))});export{P as _}; diff --git a/dist/copilot_web/workflowChat-Cr_yyziA.js b/dist/copilot_web/workflowChat-m824ZHEN.js similarity index 99% rename from dist/copilot_web/workflowChat-Cr_yyziA.js rename to dist/copilot_web/workflowChat-m824ZHEN.js index b12d80a..7e5c2da 100644 --- a/dist/copilot_web/workflowChat-Cr_yyziA.js +++ b/dist/copilot_web/workflowChat-m824ZHEN.js @@ -1,5 +1,5 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["copilot_web/WorkflowOption-DWEyFLfP.js","copilot_web/vendor-markdown-Dek94WS0.js","copilot_web/vendor-react-V04_Axys.js","copilot_web/message-components-D3rPBq8S.js","copilot_web/ParameterDebugInterfaceNew-L5N_y6IJ.js","copilot_web/input.js","copilot_web/assets/input-CeTzrUyG.css","copilot_web/App-DU9tUae4.js"])))=>i.map(i=>d[i]); -import{_ as Dt}from"./input.js";import{j as h,r as yg,b as wg}from"./vendor-markdown-Dek94WS0.js";import{r as I,R as wn,c as Mt}from"./vendor-react-V04_Axys.js";import{f as bg,v as Sg,a as sn,B as Ag,U as Eg,A as Ir,b as Ig,g as Ve,c as Pt,u as is,M as Cg,W as Ot}from"./message-components-D3rPBq8S.js";import{l as Ng}from"./App-DU9tUae4.js";/** +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["copilot_web/WorkflowOption-DWEyFLfP.js","copilot_web/vendor-markdown-Dek94WS0.js","copilot_web/vendor-react-V04_Axys.js","copilot_web/message-components-D3rPBq8S.js","copilot_web/ParameterDebugInterfaceNew-gJw0-dqN.js","copilot_web/input.js","copilot_web/assets/input-CeTzrUyG.css","copilot_web/App-B_5DJBtC.js"])))=>i.map(i=>d[i]); +import{_ as Dt}from"./input.js";import{j as h,r as yg,b as wg}from"./vendor-markdown-Dek94WS0.js";import{r as I,R as wn,c as Mt}from"./vendor-react-V04_Axys.js";import{f as bg,v as Sg,a as sn,B as Ag,U as Eg,A as Ir,b as Ig,g as Ve,c as Pt,u as is,M as Cg,W as Ot}from"./message-components-D3rPBq8S.js";import{l as Ng}from"./App-B_5DJBtC.js";/** * @license lucide-react v0.475.0 - ISC * * This source code is licensed under the ISC license. @@ -128,4 +128,4 @@ __p += '`),K&&(v+=`' + function print() { __p += __j.call(arguments, '') } `:`; `)+v+`return __p -}`;var U=Oo(function(){return X(u,S+"return "+v).apply(o,a)});if(U.source=v,Hi(U))throw U;return U}function C0(e){return J(e).toLowerCase()}function N0(e){return J(e).toUpperCase()}function L0(e,n,t){if(e=J(e),e&&(t||n===o))return js(e);if(!e||!(n=Fe(n)))return e;var r=en(e),i=en(n),u=zs(r,i),a=Gs(r,i)+1;return Mn(r,u,a).join("")}function R0(e,n,t){if(e=J(e),e&&(t||n===o))return e.slice(0,$s(e)+1);if(!e||!(n=Fe(n)))return e;var r=en(e),i=Gs(r,en(n))+1;return Mn(r,0,i).join("")}function T0(e,n,t){if(e=J(e),e&&(t||n===o))return e.replace(Hr,"");if(!e||!(n=Fe(n)))return e;var r=en(e),i=zs(r,en(n));return Mn(r,i).join("")}function M0(e,n){var t=bn,r=Rr;if(ae(n)){var i="separator"in n?n.separator:i;t="length"in n?P(n.length):t,r="omission"in n?Fe(n.omission):r}e=J(e);var u=e.length;if(et(e)){var a=en(e);u=a.length}if(t>=u)return e;var l=t-nt(r);if(l<1)return r;var c=a?Mn(a,0,l).join(""):e.slice(0,l);if(i===o)return c+r;if(a&&(l+=c.length-l),qi(i)){if(e.slice(l).search(i)){var p,_=c;for(i.global||(i=li(i.source,J(ls.exec(i))+"g")),i.lastIndex=0;p=i.exec(_);)var v=p.index;c=c.slice(0,v===o?l:v)}}else if(e.indexOf(Fe(i),l)!=l){var y=c.lastIndexOf(i);y>-1&&(c=c.slice(0,y))}return c+r}function O0(e){return e=J(e),e&&Go.test(e)?e.replace(us,ol):e}var D0=at(function(e,n,t){return e+(t?" ":"")+n.toUpperCase()}),Xi=Ou("toUpperCase");function Mo(e,n,t){return e=J(e),n=t?o:n,n===o?tl(e)?fl(e):qa(e):e.match(n)||[]}var Oo=j(function(e,n){try{return Ue(e,o,n)}catch(t){return Hi(t)?t:new T(t)}}),P0=_n(function(e,n){return He(n,function(t){t=ln(t),gn(e,t,Ki(e[t],e))}),e});function k0(e){var n=e==null?0:e.length,t=C();return e=n?ue(e,function(r){if(typeof r[1]!="function")throw new qe(M);return[t(r[0]),r[1]]}):[],j(function(r){for(var i=-1;++ifn)return[];var t=ke,r=Ie(e,ke);n=C(n),e-=ke;for(var i=ui(r,n);++t0||n<0)?new G(t):(e<0?t=t.takeRight(-e):e&&(t=t.drop(e)),n!==o&&(n=P(n),t=n<0?t.dropRight(-n):t.take(n-e)),t)},G.prototype.takeRightWhile=function(e){return this.reverse().takeWhile(e).reverse()},G.prototype.toArray=function(){return this.take(ke)},on(G.prototype,function(e,n){var t=/^(?:filter|find|map|reject)|While$/.test(n),r=/^(?:head|last)$/.test(n),i=s[r?"take"+(n=="last"?"Right":""):n],u=r||/^find/.test(n);i&&(s.prototype[n]=function(){var a=this.__wrapped__,l=r?[1]:arguments,c=a instanceof G,p=l[0],_=c||O(a),v=function(z){var K=i.apply(s,In([z],l));return r&&y?K[0]:K};_&&t&&typeof p=="function"&&p.length!=1&&(c=_=!1);var y=this.__chain__,S=!!this.__actions__.length,N=u&&!y,U=c&&!S;if(!u&&_){a=U?a:new G(this);var L=e.apply(a,l);return L.__actions__.push({func:mr,args:[v],thisArg:o}),new Ze(L,y)}return N&&U?e.apply(this,l):(L=this.thru(v),N?r?L.value()[0]:L.value():L)})}),He(["pop","push","shift","sort","splice","unshift"],function(e){var n=Kt[e],t=/^(?:push|sort|unshift)$/.test(e)?"tap":"thru",r=/^(?:pop|shift)$/.test(e);s.prototype[e]=function(){var i=arguments;if(r&&!this.__chain__){var u=this.value();return n.apply(O(u)?u:[],i)}return this[t](function(a){return n.apply(O(a)?a:[],i)})}}),on(G.prototype,function(e,n){var t=s[n];if(t){var r=t.name+"";Q.call(st,r)||(st[r]=[]),st[r].push({name:n,func:t})}}),st[cr(o,le).name]=[{name:"wrapper",func:o}],G.prototype.clone=Ml,G.prototype.reverse=Ol,G.prototype.value=Dl,s.prototype.at=fh,s.prototype.chain=ch,s.prototype.commit=hh,s.prototype.next=dh,s.prototype.plant=ph,s.prototype.reverse=_h,s.prototype.toJSON=s.prototype.valueOf=s.prototype.value=vh,s.prototype.first=s.prototype.head,mt&&(s.prototype[mt]=gh),s},tt=cl();kn?((kn.exports=tt)._=tt,Qr._=tt):we._=tt}).call(Mt)})(Nr,Nr.exports);var Lr=Nr.exports;function ip(m=!0){I.useEffect(()=>{if(!m)return;const w=Lr.debounce(o=>{document.documentElement.style.setProperty("--mouse-x",`${o.clientX}px`),document.documentElement.style.setProperty("--mouse-y",`${o.clientY}px`)},16);return document.addEventListener("mousemove",w),()=>{w.cancel(),document.removeEventListener("mousemove",w)}},[m])}function sp(m={},w=!0){const[o,D]=I.useState(!1),[B,E]=I.useState({width:window.innerWidth/3,height:window.innerHeight,top:0});I.useCallback(Lr.debounce(q=>{o&&E(x=>{const $=window.innerWidth-q.clientX,k=Math.min(Math.max(m.minWidth||300,$),m.maxWidth||window.innerWidth*.8);return{...x,width:k}})},16),[o,m]);const M=I.useCallback(q=>{E(x=>{const $=x.height-q,k=x.top+q;return{...x,height:Math.min(Math.max(m.minHeight||300,$),m.maxHeight||window.innerHeight),top:Math.max(0,k)}})},[m]);return I.useEffect(()=>{if(!w||!o)return;const q=Lr.debounce($=>{E(k=>{const F=window.innerWidth-$.clientX,re=Math.min(Math.max(m.minWidth||300,F),m.maxWidth||window.innerWidth*.8);return{...k,width:re}})},16),x=()=>D(!1);return document.addEventListener("mousemove",q),document.addEventListener("mouseup",x),()=>{q.cancel(),document.removeEventListener("mousemove",q),document.removeEventListener("mouseup",x)}},[o,m,w]),{isResizing:o,setIsResizing:D,dimensions:B,handleHeightResize:M}}function up(m=!0){const{state:w,dispatch:o}=is(),{activeTab:D,screenState:B}=w;I.useEffect(()=>{if(!m)return;const E=M=>{const q=D==="parameter-debug",x=D==="chat",$=!B||B.currentScreen===0;if(x||$&&q){const k=sn.canvas.selected_nodes;if(Object.keys(k??{}).length){const F=Object.values(k);o({type:"SET_SELECTED_NODE",payload:F})}else o({type:"SET_SELECTED_NODE",payload:null})}};return document.addEventListener("click",E),()=>{document.removeEventListener("click",E)}},[o,m,D,B])}const op=({message:m,onClose:w})=>m?h.jsxs("div",{className:"bg-gradient-to-r from-amber-50 to-amber-100 border-b border-amber-200 px-5 py-2 mt-2 relative shadow-sm",children:[h.jsxs("div",{className:"flex items-center",children:[h.jsx("div",{className:"flex-shrink-0 mr-2",children:h.jsx("svg",{className:"w-3.5 h-3.5 text-amber-600",fill:"currentColor",viewBox:"0 0 20 20",xmlns:"http://www.w3.org/2000/svg",children:h.jsx("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z",clipRule:"evenodd"})})}),h.jsx("div",{className:"text-amber-800 font-medium leading-relaxed pr-6 markdown-content",style:{fontSize:"11px"},children:h.jsx(Cg,{rehypePlugins:[[yg,{target:"_blank",rel:["noopener","noreferrer"]}]],remarkPlugins:[wg],className:"prose !text-[11px] prose-a:text-amber-700 prose-a:underline prose-a:font-medium hover:prose-a:text-amber-800",components:{a:({node:o,...D})=>h.jsx("a",{...D,className:"text-amber-700 underline hover:text-amber-800 transition-colors",style:{fontSize:"11px"}}),p:({children:o})=>h.jsx("span",{className:"inline",style:{fontSize:"11px"},children:o}),span:({children:o})=>h.jsx("span",{style:{fontSize:"11px"},children:o}),li:({children:o})=>h.jsx("li",{style:{fontSize:"11px"},children:o}),ul:({children:o})=>h.jsx("ul",{style:{fontSize:"11px"},children:o}),ol:({children:o})=>h.jsx("ol",{style:{fontSize:"11px"},children:o})},children:m})})]}),h.jsx("button",{onClick:w,className:"absolute right-2 top-1/2 -translate-y-1/2 text-amber-500 hover:text-amber-700 transition-colors p-1 rounded-full hover:bg-amber-200/50","aria-label":"Close announcement",children:h.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:h.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}):null,ap=()=>{const{state:m,dispatch:w}=is(),{selectedNode:o,screenState:D}=m,B=o||[],E=wn.lazy(()=>Dt(()=>import("./ParameterDebugInterfaceNew-L5N_y6IJ.js"),__vite__mapDeps([4,1,2,3,5,6,7])).then(q=>({default:q.ParameterDebugInterface}))),M=()=>{w({type:"SET_SELECTED_NODE",payload:null}),w({type:"SET_SCREEN_STATE",payload:null})};return h.jsx("div",{className:"flex-1 flex flex-col overflow-y-auto",children:h.jsx(wn.Suspense,{fallback:h.jsx("div",{children:"Loading..."}),children:h.jsx(E,{selectedNodes:B,visible:!0,onClose:M})})})},Wo=({active:m,onClick:w,children:o})=>h.jsx("button",{onClick:w,className:`px-4 py-2 font-medium text-sm transition-colors duration-200 ${m?"text-blue-600 border-b-2 border-blue-600":"text-gray-600 hover:text-blue-500 hover:border-b-2 hover:border-blue-300"}`,children:o});function lp({onClose:m,visible:w=!0,triggerUsage:o=!1,onUsageTriggered:D}){const{state:B,dispatch:E}=is(),{messages:M,installedNodes:q,loading:x,sessionId:$,selectedNode:k,activeTab:F}=B,re=I.useRef(null),[ie,pe]=I.useState(""),[R,W]=I.useState(""),[le,he]=I.useState(window.innerWidth/3),[oe,Pe]=I.useState(!1),[fe,H]=I.useState([]),[Z,Se]=I.useState("gpt-4o-mini");I.useState(window.innerHeight),I.useState(0);const[_e,bn]=I.useState(""),[Rr,kt]=I.useState(!1);ip(w&&F==="chat"),up(w);const{isResizing:ss,setIsResizing:Wt,dimensions:dt,handleHeightResize:Tr}=sp({minWidth:300,maxWidth:window.innerWidth*.8,minHeight:300,maxHeight:window.innerHeight},w);I.useEffect(()=>{re.current&&(re.current.scrollTop=re.current.scrollHeight)},[M]),I.useEffect(()=>{if(F!=="chat")return;(async()=>{const Y=await rp();console.log("[WorkflowChat] Received installed nodes:",Y.length),E({type:"SET_INSTALLED_NODES",payload:Y})})()},[F]);const $n=async A=>{try{const Y=await Ot.fetchMessages(A);E({type:"SET_MESSAGES",payload:Y})}catch(Y){console.error("Error fetching messages:",Y)}};I.useEffect(()=>{if(F!=="chat")return;let A=localStorage.getItem("sessionId");A?(E({type:"SET_SESSION_ID",payload:A}),$n(A)):(A=Ve(),E({type:"SET_SESSION_ID",payload:A}),localStorage.setItem("sessionId",A))},[F]);const fn=wn.useCallback(A=>{if(!oe)return;const Y=window.innerWidth-A.clientX,ee=Math.min(Math.max(300,Y),window.innerWidth*.8);he(ee)},[oe]),Hn=wn.useMemo(()=>Lr.debounce(fn,16),[fn]);I.useEffect(()=>(oe&&(document.addEventListener("mousemove",Hn),document.addEventListener("mouseup",An)),()=>{document.removeEventListener("mousemove",Hn),document.removeEventListener("mouseup",An),Hn.cancel()}),[oe,Hn]);const qn=A=>{pe(A.target.value)},ke=async()=>{if(E({type:"SET_LOADING",payload:!0}),ie.trim()===""&&!k||!$)return;W(ie);const A=Ve(),Y={id:Ve(),role:"user",content:ie,trace_id:A};E({type:"ADD_MESSAGE",payload:Y}),pe("");try{const ee={type:"model_select",data:[Z]};let Ae=Ve(),un=!0;for await(const Ee of Ot.streamInvokeServer($,ie,fe.map(V=>V.file),null,ee,A)){const V={id:Ae,role:"ai",content:JSON.stringify(Ee),format:Ee.format,finished:Ee.finished,name:"Assistant"};if(un)E({type:"ADD_MESSAGE",payload:V}),un=!1;else{E({type:"UPDATE_MESSAGE",payload:V});const ve=B.messages.map(Ke=>Ke.id===V.id&&!Ke.finished?V:Ke);Zn(ve)}Ee.finished&&E({type:"SET_LOADING",payload:!1})}}catch(ee){console.error("Error sending message:",ee),E({type:"SET_LOADING",payload:!1})}finally{H([])}},Mr=async A=>{if(!$)return;E({type:"SET_LOADING",payload:!0}),W(A);const Y=Ve(),ee={id:Ve(),role:"user",content:A,trace_id:Y};E({type:"ADD_MESSAGE",payload:ee});try{const Ae={type:"model_select",data:[Z]};let un=Ve(),Ee=!0;for await(const V of Ot.streamInvokeServer($,A,fe.map(ve=>ve.file),null,Ae,Y)){const ve={id:un,role:"ai",content:JSON.stringify(V),format:V.format,finished:V.finished,name:"Assistant"};if(Ee)E({type:"ADD_MESSAGE",payload:ve}),Ee=!1;else{E({type:"UPDATE_MESSAGE",payload:ve});const Ke=B.messages.map(cn=>cn.id===ve.id&&!cn.finished?ve:cn);Zn(Ke)}V.finished&&E({type:"SET_LOADING",payload:!1})}}catch(Ae){console.error("Error sending message:",Ae),E({type:"SET_LOADING",payload:!1})}finally{H([])}},Or=A=>{A.metaKey&&A.key==="Enter"&&ke()},Dr=()=>{E({type:"CLEAR_MESSAGES"});const A=B.sessionId;A&&localStorage.removeItem(`messages_${A}`),localStorage.removeItem("sessionId");const Y=Ve();E({type:"SET_SESSION_ID",payload:Y}),localStorage.setItem("sessionId",Y)},Sn=A=>{pe(A)},Dn=async(A,Y)=>{if(!$||!k)return;E({type:"SET_LOADING",payload:!0});const ee=Ve(),Ae={id:Ve(),role:"user",content:k.comfyClass||k.type,trace_id:ee};E({type:"ADD_MESSAGE",payload:Ae});try{let un=Ve(),Ee=!0;for await(const V of Ot.streamInvokeServer($,k.comfyClass||k.type,[],A,Y,ee)){const ve={id:un,role:"ai",content:JSON.stringify(V),format:V.format,finished:V.finished,name:"Assistant"};if(A&&A!==""&&(ve.metadata={intent:A}),Ee)E({type:"ADD_MESSAGE",payload:ve}),Ee=!1;else{E({type:"UPDATE_MESSAGE",payload:ve});const Ke=B.messages.map(cn=>cn.id===ve.id&&!cn.finished?ve:cn);Zn(Ke)}V.finished&&E({type:"SET_LOADING",payload:!1})}}catch(un){console.error("Error sending message:",un),E({type:"SET_LOADING",payload:!1})}},Zn=A=>{B.sessionId&&localStorage.setItem(`messages_${B.sessionId}`,JSON.stringify(A))},Pn=A=>{console.log("[WorkflowChat] Adding new message:",A);const Y=[...B.messages,A];E({type:"ADD_MESSAGE",payload:A}),Zn(Y)},An=()=>{Pe(!1)},Pr=A=>{const Y=Array.from(A).map(ee=>({id:Math.random().toString(36).substr(2,9),file:ee,preview:URL.createObjectURL(ee)}));H(ee=>[...ee,...Y])},Yn=A=>{H(Y=>Y.filter(Ae=>Ae.id!==A))};wn.useEffect(()=>()=>{fe.forEach(A=>URL.revokeObjectURL(A.preview))},[fe]),I.useEffect(()=>{o&&D&&F==="chat"&&(Dn("node_explain"),D())},[o,F]),I.useEffect(()=>{if(!w||F!=="chat")return;(async()=>{try{const Y=new Date().toDateString();if(localStorage.getItem("announcementLastShownDate")!==Y){const Ae=await Ot.fetchAnnouncement();Ae&&Ae.trim()!==""&&(bn(Ae),kt(!0),localStorage.setItem("announcementLastShownDate",Y))}}catch(Y){console.error("Error fetching announcement:",Y)}})()},[w,F]);const Xn=()=>{kt(!1)},gt=A=>{E({type:"SET_ACTIVE_TAB",payload:A})},We=wn.useMemo(()=>h.jsx(ap,{}),[]);return h.jsxs("div",{className:"fixed right-0 shadow-lg bg-white duration-200 ease-out",style:{display:w?"block":"none",width:`${dt.width}px`,height:`${dt.height}px`,top:`${dt.top}px`},children:[h.jsx("div",{className:"absolute left-0 top-0 bottom-0 w-1 cursor-ew-resize hover:bg-gray-300",onMouseDown:A=>{Wt(!0),A.preventDefault()}}),h.jsxs("div",{className:"flex h-full flex-col",children:[h.jsx(Kg,{onClose:m,onClear:Dr,hasMessages:M.length>0,onHeightResize:Tr,title:"ComfyUI-Copilot"}),h.jsxs("div",{className:"flex border-b border-gray-200 mt-2",children:[h.jsx(Wo,{active:F==="chat",onClick:()=>gt("chat"),children:"Chat"}),h.jsx(Wo,{active:F==="parameter-debug",onClick:()=>gt("parameter-debug"),children:"GenLab"})]}),Rr&&_e&&F==="chat"&&h.jsx(op,{message:_e,onClose:Xn}),h.jsx("div",{className:"flex-1 overflow-y-auto p-4 scroll-smooth",style:{display:F==="chat"?"block":"none"},ref:re,children:h.jsx(np,{messages:M,latestInput:R,onOptionClick:Sn,installedNodes:q,onAddMessage:Pn,loading:x})}),h.jsxs("div",{className:"border-t px-4 py-3 border-gray-200 bg-white sticky bottom-0",style:{display:F==="chat"?"block":"none"},children:[k&&h.jsx(Zg,{nodeInfo:k,onSendWithIntent:Dn,loading:x,onSendWithContent:Mr}),h.jsx(Hg,{input:ie,loading:x,onChange:qn,onSend:ke,onKeyPress:Or,onUploadImages:Pr,uploadedImages:fe,onRemoveImage:Yn,selectedModel:Z,onModelChange:Se})]}),h.jsx("div",{className:"flex-1 flex flex-col",style:{display:F==="parameter-debug"?"flex":"none"},children:We})]})]})}const xp=Object.freeze(Object.defineProperty({__proto__:null,default:lp},Symbol.toStringTag,{value:"Module"}));export{mp as g,vp as i,_p as m,pp as r,xp as w}; +}`;var U=Oo(function(){return X(u,S+"return "+v).apply(o,a)});if(U.source=v,Hi(U))throw U;return U}function C0(e){return J(e).toLowerCase()}function N0(e){return J(e).toUpperCase()}function L0(e,n,t){if(e=J(e),e&&(t||n===o))return js(e);if(!e||!(n=Fe(n)))return e;var r=en(e),i=en(n),u=zs(r,i),a=Gs(r,i)+1;return Mn(r,u,a).join("")}function R0(e,n,t){if(e=J(e),e&&(t||n===o))return e.slice(0,$s(e)+1);if(!e||!(n=Fe(n)))return e;var r=en(e),i=Gs(r,en(n))+1;return Mn(r,0,i).join("")}function T0(e,n,t){if(e=J(e),e&&(t||n===o))return e.replace(Hr,"");if(!e||!(n=Fe(n)))return e;var r=en(e),i=zs(r,en(n));return Mn(r,i).join("")}function M0(e,n){var t=bn,r=Rr;if(ae(n)){var i="separator"in n?n.separator:i;t="length"in n?P(n.length):t,r="omission"in n?Fe(n.omission):r}e=J(e);var u=e.length;if(et(e)){var a=en(e);u=a.length}if(t>=u)return e;var l=t-nt(r);if(l<1)return r;var c=a?Mn(a,0,l).join(""):e.slice(0,l);if(i===o)return c+r;if(a&&(l+=c.length-l),qi(i)){if(e.slice(l).search(i)){var p,_=c;for(i.global||(i=li(i.source,J(ls.exec(i))+"g")),i.lastIndex=0;p=i.exec(_);)var v=p.index;c=c.slice(0,v===o?l:v)}}else if(e.indexOf(Fe(i),l)!=l){var y=c.lastIndexOf(i);y>-1&&(c=c.slice(0,y))}return c+r}function O0(e){return e=J(e),e&&Go.test(e)?e.replace(us,ol):e}var D0=at(function(e,n,t){return e+(t?" ":"")+n.toUpperCase()}),Xi=Ou("toUpperCase");function Mo(e,n,t){return e=J(e),n=t?o:n,n===o?tl(e)?fl(e):qa(e):e.match(n)||[]}var Oo=j(function(e,n){try{return Ue(e,o,n)}catch(t){return Hi(t)?t:new T(t)}}),P0=_n(function(e,n){return He(n,function(t){t=ln(t),gn(e,t,Ki(e[t],e))}),e});function k0(e){var n=e==null?0:e.length,t=C();return e=n?ue(e,function(r){if(typeof r[1]!="function")throw new qe(M);return[t(r[0]),r[1]]}):[],j(function(r){for(var i=-1;++ifn)return[];var t=ke,r=Ie(e,ke);n=C(n),e-=ke;for(var i=ui(r,n);++t0||n<0)?new G(t):(e<0?t=t.takeRight(-e):e&&(t=t.drop(e)),n!==o&&(n=P(n),t=n<0?t.dropRight(-n):t.take(n-e)),t)},G.prototype.takeRightWhile=function(e){return this.reverse().takeWhile(e).reverse()},G.prototype.toArray=function(){return this.take(ke)},on(G.prototype,function(e,n){var t=/^(?:filter|find|map|reject)|While$/.test(n),r=/^(?:head|last)$/.test(n),i=s[r?"take"+(n=="last"?"Right":""):n],u=r||/^find/.test(n);i&&(s.prototype[n]=function(){var a=this.__wrapped__,l=r?[1]:arguments,c=a instanceof G,p=l[0],_=c||O(a),v=function(z){var K=i.apply(s,In([z],l));return r&&y?K[0]:K};_&&t&&typeof p=="function"&&p.length!=1&&(c=_=!1);var y=this.__chain__,S=!!this.__actions__.length,N=u&&!y,U=c&&!S;if(!u&&_){a=U?a:new G(this);var L=e.apply(a,l);return L.__actions__.push({func:mr,args:[v],thisArg:o}),new Ze(L,y)}return N&&U?e.apply(this,l):(L=this.thru(v),N?r?L.value()[0]:L.value():L)})}),He(["pop","push","shift","sort","splice","unshift"],function(e){var n=Kt[e],t=/^(?:push|sort|unshift)$/.test(e)?"tap":"thru",r=/^(?:pop|shift)$/.test(e);s.prototype[e]=function(){var i=arguments;if(r&&!this.__chain__){var u=this.value();return n.apply(O(u)?u:[],i)}return this[t](function(a){return n.apply(O(a)?a:[],i)})}}),on(G.prototype,function(e,n){var t=s[n];if(t){var r=t.name+"";Q.call(st,r)||(st[r]=[]),st[r].push({name:n,func:t})}}),st[cr(o,le).name]=[{name:"wrapper",func:o}],G.prototype.clone=Ml,G.prototype.reverse=Ol,G.prototype.value=Dl,s.prototype.at=fh,s.prototype.chain=ch,s.prototype.commit=hh,s.prototype.next=dh,s.prototype.plant=ph,s.prototype.reverse=_h,s.prototype.toJSON=s.prototype.valueOf=s.prototype.value=vh,s.prototype.first=s.prototype.head,mt&&(s.prototype[mt]=gh),s},tt=cl();kn?((kn.exports=tt)._=tt,Qr._=tt):we._=tt}).call(Mt)})(Nr,Nr.exports);var Lr=Nr.exports;function ip(m=!0){I.useEffect(()=>{if(!m)return;const w=Lr.debounce(o=>{document.documentElement.style.setProperty("--mouse-x",`${o.clientX}px`),document.documentElement.style.setProperty("--mouse-y",`${o.clientY}px`)},16);return document.addEventListener("mousemove",w),()=>{w.cancel(),document.removeEventListener("mousemove",w)}},[m])}function sp(m={},w=!0){const[o,D]=I.useState(!1),[B,E]=I.useState({width:window.innerWidth/3,height:window.innerHeight,top:0});I.useCallback(Lr.debounce(q=>{o&&E(x=>{const $=window.innerWidth-q.clientX,k=Math.min(Math.max(m.minWidth||300,$),m.maxWidth||window.innerWidth*.8);return{...x,width:k}})},16),[o,m]);const M=I.useCallback(q=>{E(x=>{const $=x.height-q,k=x.top+q;return{...x,height:Math.min(Math.max(m.minHeight||300,$),m.maxHeight||window.innerHeight),top:Math.max(0,k)}})},[m]);return I.useEffect(()=>{if(!w||!o)return;const q=Lr.debounce($=>{E(k=>{const F=window.innerWidth-$.clientX,re=Math.min(Math.max(m.minWidth||300,F),m.maxWidth||window.innerWidth*.8);return{...k,width:re}})},16),x=()=>D(!1);return document.addEventListener("mousemove",q),document.addEventListener("mouseup",x),()=>{q.cancel(),document.removeEventListener("mousemove",q),document.removeEventListener("mouseup",x)}},[o,m,w]),{isResizing:o,setIsResizing:D,dimensions:B,handleHeightResize:M}}function up(m=!0){const{state:w,dispatch:o}=is(),{activeTab:D,screenState:B}=w;I.useEffect(()=>{if(!m)return;const E=M=>{const q=D==="parameter-debug",x=D==="chat",$=!B||B.currentScreen===0;if(x||$&&q){const k=sn.canvas.selected_nodes;if(Object.keys(k??{}).length){const F=Object.values(k);o({type:"SET_SELECTED_NODE",payload:F})}else o({type:"SET_SELECTED_NODE",payload:null})}};return document.addEventListener("click",E),()=>{document.removeEventListener("click",E)}},[o,m,D,B])}const op=({message:m,onClose:w})=>m?h.jsxs("div",{className:"bg-gradient-to-r from-amber-50 to-amber-100 border-b border-amber-200 px-5 py-2 mt-2 relative shadow-sm",children:[h.jsxs("div",{className:"flex items-center",children:[h.jsx("div",{className:"flex-shrink-0 mr-2",children:h.jsx("svg",{className:"w-3.5 h-3.5 text-amber-600",fill:"currentColor",viewBox:"0 0 20 20",xmlns:"http://www.w3.org/2000/svg",children:h.jsx("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z",clipRule:"evenodd"})})}),h.jsx("div",{className:"text-amber-800 font-medium leading-relaxed pr-6 markdown-content",style:{fontSize:"11px"},children:h.jsx(Cg,{rehypePlugins:[[yg,{target:"_blank",rel:["noopener","noreferrer"]}]],remarkPlugins:[wg],className:"prose !text-[11px] prose-a:text-amber-700 prose-a:underline prose-a:font-medium hover:prose-a:text-amber-800",components:{a:({node:o,...D})=>h.jsx("a",{...D,className:"text-amber-700 underline hover:text-amber-800 transition-colors",style:{fontSize:"11px"}}),p:({children:o})=>h.jsx("span",{className:"inline",style:{fontSize:"11px"},children:o}),span:({children:o})=>h.jsx("span",{style:{fontSize:"11px"},children:o}),li:({children:o})=>h.jsx("li",{style:{fontSize:"11px"},children:o}),ul:({children:o})=>h.jsx("ul",{style:{fontSize:"11px"},children:o}),ol:({children:o})=>h.jsx("ol",{style:{fontSize:"11px"},children:o})},children:m})})]}),h.jsx("button",{onClick:w,className:"absolute right-2 top-1/2 -translate-y-1/2 text-amber-500 hover:text-amber-700 transition-colors p-1 rounded-full hover:bg-amber-200/50","aria-label":"Close announcement",children:h.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:h.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}):null,ap=()=>{const{state:m,dispatch:w}=is(),{selectedNode:o,screenState:D}=m,B=o||[],E=wn.lazy(()=>Dt(()=>import("./ParameterDebugInterfaceNew-gJw0-dqN.js"),__vite__mapDeps([4,1,2,3,5,6,7])).then(q=>({default:q.ParameterDebugInterface}))),M=()=>{w({type:"SET_SELECTED_NODE",payload:null}),w({type:"SET_SCREEN_STATE",payload:null})};return h.jsx("div",{className:"flex-1 flex flex-col overflow-y-auto",children:h.jsx(wn.Suspense,{fallback:h.jsx("div",{children:"Loading..."}),children:h.jsx(E,{selectedNodes:B,visible:!0,onClose:M})})})},Wo=({active:m,onClick:w,children:o})=>h.jsx("button",{onClick:w,className:`px-4 py-2 font-medium text-sm transition-colors duration-200 ${m?"text-blue-600 border-b-2 border-blue-600":"text-gray-600 hover:text-blue-500 hover:border-b-2 hover:border-blue-300"}`,children:o});function lp({onClose:m,visible:w=!0,triggerUsage:o=!1,onUsageTriggered:D}){const{state:B,dispatch:E}=is(),{messages:M,installedNodes:q,loading:x,sessionId:$,selectedNode:k,activeTab:F}=B,re=I.useRef(null),[ie,pe]=I.useState(""),[R,W]=I.useState(""),[le,he]=I.useState(window.innerWidth/3),[oe,Pe]=I.useState(!1),[fe,H]=I.useState([]),[Z,Se]=I.useState("gpt-4o-mini");I.useState(window.innerHeight),I.useState(0);const[_e,bn]=I.useState(""),[Rr,kt]=I.useState(!1);ip(w&&F==="chat"),up(w);const{isResizing:ss,setIsResizing:Wt,dimensions:dt,handleHeightResize:Tr}=sp({minWidth:300,maxWidth:window.innerWidth*.8,minHeight:300,maxHeight:window.innerHeight},w);I.useEffect(()=>{re.current&&(re.current.scrollTop=re.current.scrollHeight)},[M]),I.useEffect(()=>{if(F!=="chat")return;(async()=>{const Y=await rp();console.log("[WorkflowChat] Received installed nodes:",Y.length),E({type:"SET_INSTALLED_NODES",payload:Y})})()},[F]);const $n=async A=>{try{const Y=await Ot.fetchMessages(A);E({type:"SET_MESSAGES",payload:Y})}catch(Y){console.error("Error fetching messages:",Y)}};I.useEffect(()=>{if(F!=="chat")return;let A=localStorage.getItem("sessionId");A?(E({type:"SET_SESSION_ID",payload:A}),$n(A)):(A=Ve(),E({type:"SET_SESSION_ID",payload:A}),localStorage.setItem("sessionId",A))},[F]);const fn=wn.useCallback(A=>{if(!oe)return;const Y=window.innerWidth-A.clientX,ee=Math.min(Math.max(300,Y),window.innerWidth*.8);he(ee)},[oe]),Hn=wn.useMemo(()=>Lr.debounce(fn,16),[fn]);I.useEffect(()=>(oe&&(document.addEventListener("mousemove",Hn),document.addEventListener("mouseup",An)),()=>{document.removeEventListener("mousemove",Hn),document.removeEventListener("mouseup",An),Hn.cancel()}),[oe,Hn]);const qn=A=>{pe(A.target.value)},ke=async()=>{if(E({type:"SET_LOADING",payload:!0}),ie.trim()===""&&!k||!$)return;W(ie);const A=Ve(),Y={id:Ve(),role:"user",content:ie,trace_id:A};E({type:"ADD_MESSAGE",payload:Y}),pe("");try{const ee={type:"model_select",data:[Z]};let Ae=Ve(),un=!0;for await(const Ee of Ot.streamInvokeServer($,ie,fe.map(V=>V.file),null,ee,A)){const V={id:Ae,role:"ai",content:JSON.stringify(Ee),format:Ee.format,finished:Ee.finished,name:"Assistant"};if(un)E({type:"ADD_MESSAGE",payload:V}),un=!1;else{E({type:"UPDATE_MESSAGE",payload:V});const ve=B.messages.map(Ke=>Ke.id===V.id&&!Ke.finished?V:Ke);Zn(ve)}Ee.finished&&E({type:"SET_LOADING",payload:!1})}}catch(ee){console.error("Error sending message:",ee),E({type:"SET_LOADING",payload:!1})}finally{H([])}},Mr=async A=>{if(!$)return;E({type:"SET_LOADING",payload:!0}),W(A);const Y=Ve(),ee={id:Ve(),role:"user",content:A,trace_id:Y};E({type:"ADD_MESSAGE",payload:ee});try{const Ae={type:"model_select",data:[Z]};let un=Ve(),Ee=!0;for await(const V of Ot.streamInvokeServer($,A,fe.map(ve=>ve.file),null,Ae,Y)){const ve={id:un,role:"ai",content:JSON.stringify(V),format:V.format,finished:V.finished,name:"Assistant"};if(Ee)E({type:"ADD_MESSAGE",payload:ve}),Ee=!1;else{E({type:"UPDATE_MESSAGE",payload:ve});const Ke=B.messages.map(cn=>cn.id===ve.id&&!cn.finished?ve:cn);Zn(Ke)}V.finished&&E({type:"SET_LOADING",payload:!1})}}catch(Ae){console.error("Error sending message:",Ae),E({type:"SET_LOADING",payload:!1})}finally{H([])}},Or=A=>{A.metaKey&&A.key==="Enter"&&ke()},Dr=()=>{E({type:"CLEAR_MESSAGES"});const A=B.sessionId;A&&localStorage.removeItem(`messages_${A}`),localStorage.removeItem("sessionId");const Y=Ve();E({type:"SET_SESSION_ID",payload:Y}),localStorage.setItem("sessionId",Y)},Sn=A=>{pe(A)},Dn=async(A,Y)=>{if(!$||!k)return;E({type:"SET_LOADING",payload:!0});const ee=Ve(),Ae={id:Ve(),role:"user",content:k.comfyClass||k.type,trace_id:ee};E({type:"ADD_MESSAGE",payload:Ae});try{let un=Ve(),Ee=!0;for await(const V of Ot.streamInvokeServer($,k.comfyClass||k.type,[],A,Y,ee)){const ve={id:un,role:"ai",content:JSON.stringify(V),format:V.format,finished:V.finished,name:"Assistant"};if(A&&A!==""&&(ve.metadata={intent:A}),Ee)E({type:"ADD_MESSAGE",payload:ve}),Ee=!1;else{E({type:"UPDATE_MESSAGE",payload:ve});const Ke=B.messages.map(cn=>cn.id===ve.id&&!cn.finished?ve:cn);Zn(Ke)}V.finished&&E({type:"SET_LOADING",payload:!1})}}catch(un){console.error("Error sending message:",un),E({type:"SET_LOADING",payload:!1})}},Zn=A=>{B.sessionId&&localStorage.setItem(`messages_${B.sessionId}`,JSON.stringify(A))},Pn=A=>{console.log("[WorkflowChat] Adding new message:",A);const Y=[...B.messages,A];E({type:"ADD_MESSAGE",payload:A}),Zn(Y)},An=()=>{Pe(!1)},Pr=A=>{const Y=Array.from(A).map(ee=>({id:Math.random().toString(36).substr(2,9),file:ee,preview:URL.createObjectURL(ee)}));H(ee=>[...ee,...Y])},Yn=A=>{H(Y=>Y.filter(Ae=>Ae.id!==A))};wn.useEffect(()=>()=>{fe.forEach(A=>URL.revokeObjectURL(A.preview))},[fe]),I.useEffect(()=>{o&&D&&F==="chat"&&(Dn("node_explain"),D())},[o,F]),I.useEffect(()=>{if(!w||F!=="chat")return;(async()=>{try{const Y=new Date().toDateString();if(localStorage.getItem("announcementLastShownDate")!==Y){const Ae=await Ot.fetchAnnouncement();Ae&&Ae.trim()!==""&&(bn(Ae),kt(!0),localStorage.setItem("announcementLastShownDate",Y))}}catch(Y){console.error("Error fetching announcement:",Y)}})()},[w,F]);const Xn=()=>{kt(!1)},gt=A=>{E({type:"SET_ACTIVE_TAB",payload:A})},We=wn.useMemo(()=>h.jsx(ap,{}),[]);return h.jsxs("div",{className:"fixed right-0 shadow-lg bg-white duration-200 ease-out",style:{display:w?"block":"none",width:`${dt.width}px`,height:`${dt.height}px`,top:`${dt.top}px`},children:[h.jsx("div",{className:"absolute left-0 top-0 bottom-0 w-1 cursor-ew-resize hover:bg-gray-300",onMouseDown:A=>{Wt(!0),A.preventDefault()}}),h.jsxs("div",{className:"flex h-full flex-col",children:[h.jsx(Kg,{onClose:m,onClear:Dr,hasMessages:M.length>0,onHeightResize:Tr,title:"ComfyUI-Copilot"}),h.jsxs("div",{className:"flex border-b border-gray-200 mt-2",children:[h.jsx(Wo,{active:F==="chat",onClick:()=>gt("chat"),children:"Chat"}),h.jsx(Wo,{active:F==="parameter-debug",onClick:()=>gt("parameter-debug"),children:"GenLab"})]}),Rr&&_e&&F==="chat"&&h.jsx(op,{message:_e,onClose:Xn}),h.jsx("div",{className:"flex-1 overflow-y-auto p-4 scroll-smooth",style:{display:F==="chat"?"block":"none"},ref:re,children:h.jsx(np,{messages:M,latestInput:R,onOptionClick:Sn,installedNodes:q,onAddMessage:Pn,loading:x})}),h.jsxs("div",{className:"border-t px-4 py-3 border-gray-200 bg-white sticky bottom-0",style:{display:F==="chat"?"block":"none"},children:[k&&h.jsx(Zg,{nodeInfo:k,onSendWithIntent:Dn,loading:x,onSendWithContent:Mr}),h.jsx(Hg,{input:ie,loading:x,onChange:qn,onSend:ke,onKeyPress:Or,onUploadImages:Pr,uploadedImages:fe,onRemoveImage:Yn,selectedModel:Z,onModelChange:Se})]}),h.jsx("div",{className:"flex-1 flex flex-col",style:{display:F==="parameter-debug"?"flex":"none"},children:We})]})]})}const xp=Object.freeze(Object.defineProperty({__proto__:null,default:lp},Symbol.toStringTag,{value:"Module"}));export{mp as g,vp as i,_p as m,pp as r,xp as w}; diff --git a/ui/src/components/debug/ParameterDebugInterface.tsx b/ui/src/components/debug/ParameterDebugInterface.tsx deleted file mode 100644 index f595307..0000000 --- a/ui/src/components/debug/ParameterDebugInterface.tsx +++ /dev/null @@ -1,2168 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { getOnlyOneImageNode, getOutputImageByPromptId, queuePrompt, WidgetParamConf } from '../../utils/queuePrompt'; -import { app } from '../../utils/comfyapp'; -import { interruptProcessing, manageQueue } from '../../apis/comfyApiCustom'; -import { useChatContext } from '../../context/ChatContext'; -import { WorkflowChatAPI } from '../../apis/workflowChatApi'; - -// Add CSS for the highlight pulse effect -const highlightPulseStyle = ` - @keyframes highlight-pulse { - 0% { - box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.5); - } - 70% { - box-shadow: 0 0 0 15px rgba(59, 130, 246, 0); - } - 100% { - box-shadow: 0 0 0 0 rgba(59, 130, 246, 0); - } - } - - .highlight-pulse { - animation: highlight-pulse 1.5s infinite; - border: 2px solid #3b82f6; - } - - @keyframes fade-in-out { - 0% { opacity: 0; transform: translateY(-20px); } - 10% { opacity: 1; transform: translateY(0); } - 90% { opacity: 1; transform: translateY(0); } - 100% { opacity: 0; transform: translateY(-20px); } - } - - .animate-fade-in-out { - animation: fade-in-out 3s forwards; - } -`; - -// 添加一个新的接口来定义图像类型 -interface GeneratedImage { - url: string; - params: { [key: string]: any }; -} - -interface ParameterDebugInterfaceProps { - selectedNodes: any[]; - visible: boolean; - onClose?: () => void; -} - -// Define WidgetPair interface here since it's not exported from queuePrompt -interface WidgetPair { - paramName: string; - paramValue: string; -} - -export const ParameterDebugInterface: React.FC = ({ - selectedNodes, - visible, - onClose -}) => { - const [currentScreen, setCurrentScreen] = useState(0); - const [selectedParams, setSelectedParams] = useState<{[key: string]: boolean}>({ - Steps: true, - CFG: true, - sampler_name: true, - threshold: false, - prompt: false - }); - const [isProcessing, setIsProcessing] = useState(false); - const [isCompleted, setIsCompleted] = useState(false); - const [completedCount, setCompletedCount] = useState(0); - const [totalCount, setTotalCount] = useState(12); - const [selectedImageIndex, setSelectedImageIndex] = useState(null); - const [generatedImages, setGeneratedImages] = useState(() => { - // Create an array of placeholder image URLs - return Array(12).fill(null).map((_, i) => ({ - url: `https://source.unsplash.com/random/300x300?sig=${Math.random()}`, - params: { - step: i % 3 === 0 ? 5 : i % 3 === 1 ? 10 : 15, - sampler_name: 'euler', - cfg: 1 - } - })); - }); - - // 修改参数测试值结构,使用嵌套对象,按节点ID进行分组 - const [paramTestValues, setParamTestValues] = useState<{[nodeId: string]: {[paramName: string]: any[]}}>({}); - // Add a state to store dropdown open status - const [openDropdowns, setOpenDropdowns] = useState<{[key: string]: boolean | {isOpen: boolean, x: number, y: number}}>({}); - - // Add new state to store search terms - const [searchTerms, setSearchTerms] = useState<{[key: string]: string}>({}); - - // Add state to track input values - 更新为使用nodeId_paramName作为键 - const [inputValues, setInputValues] = useState<{[nodeId_paramName: string]: {min?: string, max?: string, step?: string}}>({}); - - // Add a state to store current page - const [currentPage, setCurrentPage] = useState(1); - const imagesPerPage = 6; - const [errorMessage, setErrorMessage] = useState(null); - - // Add state to store notification visibility - const [notificationVisible, setNotificationVisible] = useState(false); - - // Add new state for modal - const [modalVisible, setModalVisible] = useState(false); - const [modalImageUrl, setModalImageUrl] = useState(''); - - // Add state for text inputs and AI writing modal - const [textInputs, setTextInputs] = useState<{[nodeId_paramName: string]: string[]}>({}); - const [aiWritingModalVisible, setAiWritingModalVisible] = useState(false); - const [aiWritingModalText, setAiWritingModalText] = useState(''); - const [aiGeneratedTexts, setAiGeneratedTexts] = useState([]); - const [aiWritingLoading, setAiWritingLoading] = useState(false); - const [aiWritingNodeId, setAiWritingNodeId] = useState(''); - const [aiWritingParamName, setAiWritingParamName] = useState(''); - const [aiWritingError, setAiWritingError] = useState(null); - const [aiSelectedTexts, setAiSelectedTexts] = useState<{[key: string]: boolean}>({}); - - // Get dispatch from context to update screen state - const { dispatch } = useChatContext(); - - // Add function to handle AI text generation - const handleAiWriting = async () => { - if (!aiWritingModalText.trim()) { - setAiWritingError("Please enter some text to generate variations"); - return; - } - - setAiWritingLoading(true); - setAiWritingError(null); - setAiGeneratedTexts([]); - setAiSelectedTexts({}); - - try { - const generatedTexts = await WorkflowChatAPI.generateSDPrompts(aiWritingModalText); - setAiGeneratedTexts(generatedTexts); - - // Pre-select all generated texts - const newSelectedTexts: {[key: string]: boolean} = {}; - generatedTexts.forEach((text, index) => { - newSelectedTexts[`text${index+1}`] = false; - }); - setAiSelectedTexts(newSelectedTexts); - } catch (error) { - console.error("Error generating text:", error); - setAiWritingError("Failed to generate text variations. Please try again."); - } finally { - setAiWritingLoading(false); - } - }; - - // Add function to handle text input changes - const handleTextInputChange = (nodeId: string, paramName: string, index: number, value: string) => { - const textKey = `${nodeId}_${paramName}`; - - setTextInputs(prev => { - const currentTexts = [...(prev[textKey] || [])]; - currentTexts[index] = value; - return { - ...prev, - [textKey]: currentTexts - }; - }); - - // Also update paramTestValues with the new value directly instead of using textInputs state - // (which hasn't been updated yet) - const currentTexts = [...(textInputs[textKey] || [])]; - currentTexts[index] = value; - updateParamTestValues(nodeId, paramName, currentTexts); - }; - - // Add function to add a new text input - const handleAddTextInput = (nodeId: string, paramName: string) => { - const textKey = `${nodeId}_${paramName}`; - - setTextInputs(prev => { - const currentTexts = [...(prev[textKey] || [])]; - currentTexts.push(''); - return { - ...prev, - [textKey]: currentTexts - }; - }); - - // Also update paramTestValues - const updatedTexts = [...(textInputs[textKey] || []), '']; - updateParamTestValues(nodeId, paramName, updatedTexts); - }; - - // Add function to remove a text input - const handleRemoveTextInput = (nodeId: string, paramName: string, index: number) => { - const textKey = `${nodeId}_${paramName}`; - - setTextInputs(prev => { - const currentTexts = [...(prev[textKey] || [])]; - currentTexts.splice(index, 1); - return { - ...prev, - [textKey]: currentTexts - }; - }); - - // Also update paramTestValues - const updatedTexts = [...(textInputs[textKey] || [])]; - updatedTexts.splice(index, 1); - updateParamTestValues(nodeId, paramName, updatedTexts); - }; - - // Add function to toggle text selection in AI writing modal - const toggleTextSelection = (textKey: string) => { - setAiSelectedTexts(prev => ({ - ...prev, - [textKey]: !prev[textKey] - })); - }; - - // Add function to add selected texts from AI modal - const addSelectedTexts = () => { - const textKey = `${aiWritingNodeId}_${aiWritingParamName}`; - const selectedTexts = Object.entries(aiSelectedTexts) - .filter(([_, isSelected]) => isSelected) - .map(([key]) => { - const index = parseInt(key.replace('text', '')) - 1; - return aiGeneratedTexts[index]; - }); - - if (selectedTexts.length === 0) { - return; - } - - setTextInputs(prev => { - const currentTexts = [...(prev[textKey] || [])]; - return { - ...prev, - [textKey]: [...currentTexts, ...selectedTexts] - }; - }); - - // Also update paramTestValues - const updatedTexts = [...(textInputs[textKey] || []), ...selectedTexts]; - updateParamTestValues(aiWritingNodeId, aiWritingParamName, updatedTexts); - - // Close the modal - setAiWritingModalVisible(false); - }; - - // Add function to open AI writing modal - const openAiWritingModal = (nodeId: string, paramName: string) => { - setAiWritingModalVisible(true); - setAiWritingNodeId(nodeId); - setAiWritingParamName(paramName); - setAiWritingModalText(''); - setAiGeneratedTexts([]); - setAiSelectedTexts({}); - setAiWritingLoading(false); - setAiWritingError(null); - }; - - // Add useEffect to initialize parameter test values when selectedNodes change - useEffect(() => { - if (!selectedNodes || selectedNodes.length === 0) return; - - // Initialize empty parameter test values for any newly selected nodes - const updatedParamTestValues = { ...paramTestValues }; - - // Clean up any nodes that are no longer selected - const selectedNodeIds = selectedNodes.map((node: any) => node.id.toString()); - const currentNodeIds = Object.keys(updatedParamTestValues); - - // Remove test values for nodes that are no longer selected - currentNodeIds.forEach(nodeId => { - if (!selectedNodeIds.includes(nodeId)) { - delete updatedParamTestValues[nodeId]; - } - }); - - // Add empty entries for newly selected nodes - selectedNodes.forEach((node: any) => { - const nodeId = node.id.toString(); - if (!updatedParamTestValues[nodeId]) { - updatedParamTestValues[nodeId] = {}; - } - }); - - // Update state if changes were made - if (JSON.stringify(updatedParamTestValues) !== JSON.stringify(paramTestValues)) { - setParamTestValues(updatedParamTestValues); - } - }, [selectedNodes, paramTestValues]); - - // Add useEffect to update screen state in context when screen changes - useEffect(() => { - dispatch({ - type: 'SET_SCREEN_STATE', - payload: { - currentScreen, - isProcessing, - isCompleted - } - }); - }, [currentScreen, isProcessing, isCompleted, dispatch]); - - // Add style to document head - useEffect(() => { - const styleElement = document.createElement('style'); - styleElement.textContent = highlightPulseStyle; - document.head.appendChild(styleElement); - - return () => { - document.head.removeChild(styleElement); - }; - }, []); - - // Add a useEffect to handle click outside - useEffect(() => { - const handleClickOutside = (event: MouseEvent) => { - // Only process if there are open dropdowns - if (Object.values(openDropdowns).some(isOpen => isOpen)) { - // Check if clicked element is inside dropdown-menu or its trigger - const target = event.target as Element; - - // Check if the click was inside any dropdown menu - const isInsideDropdown = !!target.closest('.dropdown-menu'); - - // Check if the click was on a dropdown trigger button - const isOnTrigger = !!target.closest('[data-dropdown]'); - - // If click was outside both dropdown and trigger, close all dropdowns - if (!isInsideDropdown && !isOnTrigger) { - setOpenDropdowns({}); - } - } - }; - - // Add listener to document once - document.addEventListener('mousedown', handleClickOutside); - - return () => { - document.removeEventListener('mousedown', handleClickOutside); - }; - }, [openDropdowns]); - - // Calculate total pages - const totalPages = Math.ceil(totalCount / imagesPerPage); - - // Handle page change - const handlePageChange = (newPage: number, event?: React.MouseEvent) => { - if (event) { - event.preventDefault(); - event.stopPropagation(); - } - setCurrentPage(Math.max(1, Math.min(newPage, totalPages))); - }; - - // Navigate to next screen - const handleNext = (event?: React.MouseEvent) => { - if (event) { - event.preventDefault(); - event.stopPropagation(); - } - // 如果要从屏幕 1 进入屏幕 2,更新 totalCount - if (currentScreen === 1) { - const combinations = generateParameterCombinations(); - setTotalCount(combinations.length); - } - // 清除错误消息 - setErrorMessage(null); - setCurrentScreen(prev => Math.min(prev + 1, 2)); - }; - - // Navigate to previous screen - const handlePrevious = (event?: React.MouseEvent) => { - if (event) { - event.preventDefault(); - event.stopPropagation(); - } - // 清除错误消息 - setErrorMessage(null); - // Reset completed state when going back - if (isCompleted) { - setIsCompleted(false); - } - - // If going back from screen 1 to 0, clean up any paramTestValues for nodes that are no longer selected - if (currentScreen === 1) { - const selectedNodeIds = selectedNodes.map(node => node.id.toString()); - const currentNodeIds = Object.keys(paramTestValues); - - // Remove test values for any nodes that are no longer selected - const updatedParamTestValues = { ...paramTestValues }; - currentNodeIds.forEach(nodeId => { - if (!selectedNodeIds.includes(nodeId)) { - delete updatedParamTestValues[nodeId]; - } - }); - - setParamTestValues(updatedParamTestValues); - } - - setCurrentScreen(prev => Math.max(prev - 1, 0)); - }; - - // Handle parameter selection - const handleParamSelect = (param: string, event?: React.MouseEvent) => { - if (event) { - event.preventDefault(); - event.stopPropagation(); - } - setSelectedParams(prev => ({ - ...prev, - [param]: !prev[param] - })); - }; - - // Generate numeric test values - const generateNumericTestValues = (min: number, max: number, step: number, precision: number = 0) => { - // Ensure all parameters have valid values - min = isNaN(min) ? 0 : min; - max = isNaN(max) ? 100 : max; - step = isNaN(step) || step <= 0 ? 1 : step; - - // Ensure max >= min - if (max < min) { - max = min; - } - - // Calculate count based on the actual step - const count = Math.floor((max - min) / step) + 1; - if (count <= 1) return [min]; - - // Generate values based on the actual step - const values = []; - let current = min; - if (count <= 10){ - while (current <= max && values.length <= 10) { - // Apply precision based on the parameter - const factor = Math.pow(10, precision); - const roundedValue = Math.round(current * factor) / factor; - - values.push(roundedValue); - current += step; - } - } - else{ - // For large ranges, generate evenly distributed values - const range = max - min; - const step = range / 9; // 9 steps to get 10 values - - for (let i = 0; i <= 9; i++) { - // Calculate the value at this position - const value = min + (step * i); - - // Apply precision - const factor = Math.pow(10, precision); - const roundedValue = Math.round(value * factor) / factor; - - values.push(roundedValue); - } - } - - return values; - }; - -// Generate all parameter combinations for the selected parameters -const generateParameterCombinations = () => { - // First, we need to get all the different parameter combinations - const result: WidgetParamConf[][] = []; - - // Create a list of all parameter combinations for each node - const nodeParamCombinations: {[nodeId: string]: Array} = {}; - - // For each node, generate all combinations of its parameters - Object.keys(paramTestValues).forEach(nodeIdStr => { - const nodeId = parseInt(nodeIdStr); - const nodeParams = paramTestValues[nodeIdStr] || {}; - - // Get all parameter names that have values - const paramNames = Object.keys(nodeParams).filter( - paramName => nodeParams[paramName] && nodeParams[paramName].length > 0 - ); - - if (paramNames.length === 0) return; - - // Create all possible combinations of parameter values for this node - const combinations: WidgetParamConf[][] = [[]]; - - // For each parameter, create combinations with all its values - paramNames.forEach(paramName => { - const values = nodeParams[paramName]; - const newCombinations: WidgetParamConf[][] = []; - - // For each existing combination - combinations.forEach(combo => { - // For each value of the current parameter - values.forEach(value => { - // Create a new combination by adding this parameter value - const newCombo = [...combo, { - nodeId, - paramName, - paramValue: String(value) - }]; - newCombinations.push(newCombo); - }); - }); - - // Replace combinations with the new ones - combinations.length = 0; - combinations.push(...newCombinations); - }); - - // Store all combinations for this node - nodeParamCombinations[nodeIdStr] = combinations; - }); - - // If no nodes have parameters, return empty result - if (Object.keys(nodeParamCombinations).length === 0) { - return result; - } - - // If there's only one node, return its combinations directly - if (Object.keys(nodeParamCombinations).length === 1) { - const nodeId = Object.keys(nodeParamCombinations)[0]; - return nodeParamCombinations[nodeId]; - } - - // For multiple nodes, we need to create combinations across nodes - const nodeIds = Object.keys(nodeParamCombinations); - - // Start with combinations from the first node - let allCombinations = nodeParamCombinations[nodeIds[0]]; - - // For each additional node, create combinations with all previous nodes - for (let i = 1; i < nodeIds.length; i++) { - const nodeCombinations = nodeParamCombinations[nodeIds[i]]; - const newCombinations: WidgetParamConf[][] = []; - - // For each existing combination across previous nodes - allCombinations.forEach(existingCombo => { - // For each combination from the current node - nodeCombinations.forEach(nodeCombo => { - // Combine them - newCombinations.push([...existingCombo, ...nodeCombo]); - }); - }); - - // Update all combinations - allCombinations = newCombinations; - } - - return allCombinations; -}; - - // Toggle dropdown open status - 使用nodeId_paramName作为键 - const toggleDropdown = (nodeId: string, paramName: string, event: React.MouseEvent) => { - event.preventDefault(); - event.stopPropagation(); - - const dropdownKey = `${nodeId}_${paramName}`; - - setOpenDropdowns(prev => { - const isCurrentlyOpen = prev[dropdownKey] && - typeof prev[dropdownKey] === 'object' ? - (prev[dropdownKey] as {isOpen: boolean}).isOpen : - Boolean(prev[dropdownKey]); - - if (isCurrentlyOpen) { - return { - ...prev, - [dropdownKey]: false - }; - } else { - // 确定下拉框的位置 - let x = 0; - let y = 0; - - // 尝试从事件目标获取位置 - if (event.currentTarget) { - const rect = event.currentTarget.getBoundingClientRect(); - x = rect.left; - y = rect.bottom; - } else { - // 如果无法获取元素位置,使用鼠标点击位置 - x = event.clientX; - y = event.clientY + 20; // 在鼠标位置下方20px显示 - } - - // 确保下拉框不会超出窗口边界 - const windowWidth = window.innerWidth; - const dropdownWidth = 250; // 估计的下拉框宽度 - - if (x + dropdownWidth > windowWidth) { - x = windowWidth - dropdownWidth - 10; // 确保距离右边界至少10px - } - - if (x < 0) x = 10; // 确保距离左边界至少10px - - return { - ...prev, - [dropdownKey]: { - isOpen: true, - x: x, - y: y - } - }; - } - }); - }; - - // Update parameter test values - 修改为支持新的参数结构 - const updateParamTestValues = (nodeId: string, paramName: string, values: any[]) => { - setParamTestValues(prev => { - const updatedValues = { ...prev }; - - // 确保节点ID存在 - if (!updatedValues[nodeId]) { - updatedValues[nodeId] = {}; - } - - // 更新特定节点和参数的值 - updatedValues[nodeId][paramName] = values; - - return updatedValues; - }); - }; - - // Handle selecting specific test values - 修改为支持新的参数结构 - const handleTestValueSelect = (nodeId: string, paramName: string, value: any, event?: React.MouseEvent) => { - if (event) { - event.preventDefault(); - event.stopPropagation(); - } - - setParamTestValues(prev => { - const updatedValues = { ...prev }; - - // 确保节点ID存在 - if (!updatedValues[nodeId]) { - updatedValues[nodeId] = {}; - } - - // 确保参数名存在 - if (!updatedValues[nodeId][paramName]) { - updatedValues[nodeId][paramName] = []; - } - - const currentValues = updatedValues[nodeId][paramName]; - - if (currentValues.includes(value)) { - updatedValues[nodeId][paramName] = currentValues.filter(v => v !== value); - } else { - updatedValues[nodeId][paramName] = [...currentValues, value]; - } - - return updatedValues; - }); - }; - - // Add processing search - 使用nodeId_paramName作为键 - const handleSearch = (nodeId: string, paramName: string, term: string) => { - const searchKey = `${nodeId}_${paramName}`; - setSearchTerms(prev => ({ - ...prev, - [searchKey]: term - })); - }; - - // Add select all - 修改为支持新的参数结构 - const handleSelectAll = (nodeId: string, paramName: string, values: any[]) => { - // 确保节点ID存在 - if (!paramTestValues[nodeId]) { - updateParamTestValues(nodeId, paramName, values); - return; - } - - // 获取当前值 - const currentValues = paramTestValues[nodeId][paramName] || []; - - // 如果所有值都已选择,则取消选择所有,否则选择所有 - if (values.length === currentValues.length) { - updateParamTestValues(nodeId, paramName, []); - } else { - updateParamTestValues(nodeId, paramName, [...values]); - } - }; - - // Add function to generate dynamic parameters - modified to work with the new structure - const generateDynamicParams = (paramTestValues: {[nodeId: string]: {[paramName: string]: any[]}}, index: number) => { - // Create object to store dynamic parameters - const dynamicParams: { - [key: string]: any, - nodeParams?: {[nodeId: string]: {[paramName: string]: any}} - } = {}; - - // Initialize nodeParams structure - dynamicParams.nodeParams = {}; - - // Get all parameter combinations - const allCombinations = generateParameterCombinations(); - - // Use the index to select a specific combination - if (index < allCombinations.length) { - const selectedCombination = allCombinations[index]; - - // Process each parameter in the combination - selectedCombination.forEach(param => { - const nodeId = param.nodeId.toString(); - const paramName = param.paramName; - const paramValue = param.paramValue; - - // Initialize node if needed - if (!dynamicParams.nodeParams![nodeId]) { - dynamicParams.nodeParams![nodeId] = {}; - } - - // Add to nodeParams structure - dynamicParams.nodeParams![nodeId][paramName] = paramValue; - - // Also add to flat structure for backwards compatibility and display - dynamicParams[paramName] = paramValue; - }); - } - - return dynamicParams; - }; - - // Handle start generation - const handleStartGeneration = async (event?: React.MouseEvent) => { - if (event) { - event.preventDefault(); - event.stopPropagation(); - } - - // Get parameter combinations - const paramCombinations = generateParameterCombinations(); - const totalCombinations = paramCombinations.length; - const showNodeId = getOnlyOneImageNode(); - - // Check if total runs exceed 100 - if (totalCombinations > 100) { - setErrorMessage(`Cannot generate more than 100 images at once (currently: ${totalCombinations} images)`); - return; - } - - setErrorMessage(null); - setIsProcessing(true); - setCompletedCount(0); - - console.log("Generated parameter combinations:", paramCombinations); - - // If we have no combinations, show error and return - if (paramCombinations.length === 0) { - setErrorMessage("No valid parameter combinations found. Please check your parameter selections."); - setIsProcessing(false); - return; - } - - const prompt_ids: string[] = []; - try { - // Each combination represents all parameters for a single image generation - for (const combination of paramCombinations) { - const response = await queuePrompt(combination); - if(response.prompt_id) { - prompt_ids.push(response.prompt_id); - } else { - console.error("Failed to get prompt_id from response:", response); - prompt_ids.push(""); - } - } - - // Create an array to track images and their parameters - const newImages: GeneratedImage[] = Array(paramCombinations.length).fill(null).map((_, i) => ({ - url: `https://source.unsplash.com/random/300x300?sig=${Math.random()}`, // Default placeholder - params: generateDynamicParams(paramTestValues, i) - })); - - // Set initial images - setGeneratedImages(newImages); - - // Track timeout - const startTime = Date.now(); - const timeoutDuration = 5 * 60 * 1000; // 5 minutes - - // Function to poll for images - const pollForImages = async () => { - // Check if timeout has been reached - if (Date.now() - startTime > timeoutDuration) { - console.log("Timeout reached while waiting for images"); - setIsProcessing(false); - setIsCompleted(true); - setCurrentPage(1); - return; - } - - let completedImagesCount = 0; - - // Check each prompt id to see if images are ready - - for (let i = 0; i < prompt_ids.length; i++) { - const promptId = prompt_ids[i]; - if (!promptId) continue; - - try { - const imageUrl = await getOutputImageByPromptId(promptId, showNodeId); - - if (imageUrl) { - // If we have an image URL, update in our array - newImages[i] = { - ...newImages[i], - url: imageUrl - }; - completedImagesCount++; - } - } catch (error) { - console.error(`Error fetching image for prompt ID ${promptId}:`, error); - } - } - - // Update the images in state - setGeneratedImages([...newImages]); - - // Update the completed count - setCompletedCount(completedImagesCount); - - // If all images are ready or timeout occurred, we're done - if (completedImagesCount === prompt_ids.length || Date.now() - startTime > timeoutDuration) { - setIsProcessing(false); - setIsCompleted(true); - setCurrentPage(1); - } else { - // Otherwise, poll again in 3 seconds - setTimeout(pollForImages, 3000); - } - }; - - // Start polling - pollForImages(); - } catch (error) { - console.error("Error generating images:", error); - setIsProcessing(false); - } - }; - - // Handle selecting an image - const handleSelectImage = (index: number, event?: React.MouseEvent) => { - if (event) { - event.preventDefault(); - event.stopPropagation(); - } - setSelectedImageIndex(index); - }; - - // Add new function to open image modal - const openImageModal = (imageUrl: string, event: React.MouseEvent) => { - event.preventDefault(); - event.stopPropagation(); - setModalImageUrl(imageUrl); - setModalVisible(true); - }; - - // Add new function to close image modal - const closeImageModal = (event?: React.MouseEvent) => { - if (event) { - event.preventDefault(); - event.stopPropagation(); - } - setModalVisible(false); - }; - - // Handle applying selected image - const handleApplySelected = (event?: React.MouseEvent) => { - if (event) { - event.preventDefault(); - event.stopPropagation(); - } - if (selectedImageIndex !== null) { - console.log(`Applied image ${selectedImageIndex + 1} with parameters:`, generatedImages[selectedImageIndex].params); - // 把选中图片的参数应用到画布上 - const selectedParams = generatedImages[selectedImageIndex].params; - - // 使用结构化的参数格式 - if (selectedParams.nodeParams) { - // 遍历所有节点参数 - Object.entries(selectedParams.nodeParams).forEach(([nodeId, nodeParams]) => { - // 获取节点 - const node = app.graph._nodes_by_id[nodeId]; - if (!node || !node.widgets) return; - - // 遍历节点的参数 - Object.entries(nodeParams as Record).forEach(([paramName, value]) => { - // 在节点的widgets中查找对应名称的widget - for (const widget of node.widgets) { - if (widget.name === paramName) { - // 设置widget的值 - widget.value = value; - break; - } - } - }); - }); - - // 标记画布为脏,触发重新渲染 - app.graph.setDirtyCanvas(false, true); - - // 显示通知消息 - setNotificationVisible(true); - - // 3秒后隐藏通知 - setTimeout(() => { - setNotificationVisible(false); - }, 3000); - } - } - }; - - // Modified handle close to implement different behaviors based on current screen - const handleClose = (event?: React.MouseEvent, nodeIndex?: number) => { - if (event) { - event.preventDefault(); - event.stopPropagation(); - } - - // Screen 2: Close individual node card - if (currentScreen === 1 && nodeIndex !== undefined) { - // Remove the node at specified index - const newSelectedNodes = [...selectedNodes]; - newSelectedNodes.splice(nodeIndex, 1); - - // If no nodes left, return to original screen - if (newSelectedNodes.length === 0) { - if (onClose) { - // Clear screen state from context when closing - dispatch({ type: 'SET_SCREEN_STATE', payload: null }); - // Call provided onClose to reset the interface - onClose(); - } - } else { - // Update the context with the new selected nodes - dispatch({ type: 'SET_SELECTED_NODE', payload: newSelectedNodes }); - } - return; - } - - // Screen 3, 4, 5 or original: Close the entire interface - if (onClose) { - // Clear screen state from context when closing - dispatch({ type: 'SET_SCREEN_STATE', payload: null }); - // Use the provided onClose callback - onClose(); - } else { - // For users of this component without a callback - // Reset internal states - setCurrentScreen(0); - setIsCompleted(false); - setIsProcessing(false); - setErrorMessage(null); - } - }; - - // Conditionally render based on whether nodes are selected - // Screen original - Only stop propagation, don't prevent default - if (!visible || selectedNodes.length === 0) { - return ( -
e.stopPropagation()} - > -
-
-

GenLab

-
-
- -
-
-
- - - -
-
-

Batch Test Parameter Pairs

-

Select a node to batch test parameter pairs

-
-
- -
-
- - - -
-
-

How To Use

-

Click on any node in your workflow to start the parameter testing process

-
-
- -
-

No node is currently selected

-
-
-
-
- ); - } - - // Screen 5: If we're in completed state, show the results gallery - if (isCompleted) { - // Calculate current page's image index range using generatedImages.length instead of totalCount - const startIndex = (currentPage - 1) * imagesPerPage; - const endIndex = Math.min(startIndex + imagesPerPage, generatedImages.length); - const currentImages = generatedImages.slice(startIndex, endIndex); - - // Update total pages calculation based on actual image count - const actualTotalPages = Math.ceil(generatedImages.length / imagesPerPage); - - return ( -
e.stopPropagation()} - > -
-
-
-

Generation Complete

-

All {generatedImages.length} images have been generated.

-
- -
- - {/* Notification toast */} - {notificationVisible && ( -
-
-
- - - -
-

Parameters has been applied.

-
-
- )} - - {/* Image Modal */} - {modalVisible && ( -
-
e.stopPropagation()}> - -
- Enlarged image -
-
-
- )} - -
- {currentImages.map((image, indexOnPage) => { - const actualIndex = startIndex + indexOnPage; - return ( -
handleSelectImage(actualIndex, e)} - > - {/* Zoom icon */} - -
- {`Generated -
-
- {Object.entries(image.params) - // Filter out nodeParams and other complex objects from display - .filter(([paramName, value]) => - paramName !== 'nodeParams' && - typeof value !== 'object' - ) - .map(([paramName, value]) => ( -
{paramName}: {String(value)}
- )) - } -
-
- ); - })} -
- - {/* Pagination controls */} - {actualTotalPages > 1 && ( -
- - - -
- Page {currentPage} of {actualTotalPages} -
- - - -
- )} - -
- - -
-
-
- ); - } - - // Screen 4: If processing, show the loading overlay - if (isProcessing) { - return ( -
e.stopPropagation()} - > -
- {/* Semi-transparent overlay */} -
-
-
Processing...
-
Completed {completedCount} of {totalCount} runs
-
-
-
-
- Already generated {completedCount} images -
- -
-
- - {/* Background content (same as screen 3 content) */} -
-
-

Confirm Test Configuration

-

- In the selected parameter combinations, there are {totalCount} total runs. Each run will generate a separate image. -

-
- -
- - {/* Display error message */} - {errorMessage && ( -
-
-
- - - -
-
{errorMessage}
-
-
- )} - - {selectedNodes.length > 0 ? ( - selectedNodes.map((node, nodeIndex) => { - const nodeType = node.type || "Unknown Node"; - const widgets = node.widgets || []; - const nodeId = node.id; - - return ( -
-
- {nodeType} (ID: {nodeId}) -
-
- {widgets.map((widget: any, widgetIndex: number) => { - const paramName = widget.name; - - if (!selectedParams[paramName]) { - return null; - } - - const testValues = paramTestValues[nodeId]?.[paramName] || []; - const displayValues = Array.isArray(testValues) - ? `[${testValues.join(', ')}]` - : JSON.stringify(testValues); - - return ( -
- -
- e.preventDefault()} - /> -
-
- ); - })} -
-
- ); - }) - ) : ( -
- No nodes selected. Please select a node in the workflow to configure parameters. -
- )} - -
- - -
-
-
- ); - } - - // Screen 1: Select parameters - if (currentScreen === 0) { - return ( -
e.stopPropagation()} - > -
-
-
-

Select Parameters for Testing

-

Choose the parameters you want to include in your batch test

-
- -
- - {/* Dynamically render nodes and their parameters */} - {selectedNodes.map((node, nodeIndex) => { - // Get node title - const nodeTitle = node.title || "Unknown Node"; - - // Get node widgets/parameters - const nodeWidgets = node.widgets || []; - - return ( -
-
- {nodeTitle} -
-
-
- {nodeWidgets.map((widget: any, widgetIndex: number) => { - const paramName = widget.name; - return ( -
-
handleParamSelect(paramName, e)} - > - {selectedParams[paramName] &&
} -
- {paramName} -
- ); - })} -
-
-
- ); - })} - -
- -
-
-
- ); - } - - // Screen 2: Configure parameter options - if (currentScreen === 1) { - return ( -
e.stopPropagation()} - > -
-
-
-

Parameter Options

-

Configure the test values for each parameter

-
- -
- - {/* AI Writing Modal */} - {aiWritingModalVisible && ( -
-
-
-

AI Writing Assistant

- -
- -
-
-

Enter text and AI will generate variations

-