diff --git a/web/util.js b/web/util.js index 316163c..919bf83 100644 --- a/web/util.js +++ b/web/util.js @@ -4,8 +4,8 @@ - `}svgStringToImage(e){let t=new Blob([e],{type:"image/svg+xml"}),s=URL.createObjectURL(t),n=new Image;return n.src=s,n}hex2rgb(e){let t=parseInt(e.slice(1,3),16),s=parseInt(e.slice(3,5),16),n=parseInt(e.slice(5,7),16);return{r:t,g:s,b:n}}getRandomHexColor(){return this.hexColors[Math.floor(Math.random()*this.hexColors.length)]}constructor(e,t,s){this.color=this.getRandomHexColor(),this.app=t,this.fps=s,this.canSendMouse=!1,this.nexusSocket=e,this.nexusSocket.onConnected.push(this.handleConnect.bind(this)),this.nexusSocket.onMessageReceive.push(this.handleMessageReceive.bind(this)),document.addEventListener("visibilitychange",this.handleVisiblityChange.bind(this)),document.addEventListener("mousemove",this.handleSendMouseControl.bind(this)),this.app.graph.list_of_graphcanvas[0].onDrawForeground=this.handlePointerDraw.bind(this),setInterval(this.handleSendMouse.bind(this),1e3/this.fps)}throttle(e,t){let s,n;return function(...o){let a=this;n?(clearTimeout(s),s=setTimeout(function(){Date.now()-n>=t&&(e.apply(a,o),n=Date.now())},t-(Date.now()-n))):(e.apply(a,o),n=Date.now())}}handleCanvasDraw(){this.app.graph&&this.app.graph.list_of_graphcanvas&&this.app.graph.list_of_graphcanvas.length>0&&this.app.graph.list_of_graphcanvas[0].draw(!0,!0)}handleConnect(){this.drawTimer=setInterval(this.handleCanvasDraw.bind(this),1e3/this.fps)}handleMessageReceive(e){let t=e.name,s=e.from,n=e.data;if(t=="mouse"){let o=this.nexusSocket.userManager.get(s,"mouse"),a=this.nexusSocket.userManager.get(s,"pointer");a?a&&o&&o[3]!=n.mouse[3]&&this.nexusSocket.userManager.set(s,"pointer",this.svgStringToImage(this.createMouseSvg(n.mouse[3]))):this.nexusSocket.userManager.set(s,"pointer",this.svgStringToImage(this.createMouseSvg(n.mouse[3]))),this.nexusSocket.userManager.set(s,"mouse",n.mouse)}else t=="hide_mouse"?this.nexusSocket.userManager.set(s,"mouse",null):t=="mouse_view_toggle"&&(this.nexusSocket.userManager.set(s,"mouse_view",n.on),n.on==0&&this.nexusSocket.sendMessage("hide_mouse",{receiver:s},!1))}handleVisiblityChange(){document.visibilityState==="hidden"?(clearInterval(this.drawTimer),this.nexusSocket.sendMessage("hide_mouse",{},!1),this.nexusSocket.sendMessage("afk",{},!1)):(this.handleConnect(),this.nexusSocket.sendMessage("online",{},!1))}handleSendMouse=function(){if(this.app.graph&&this.app.graph.list_of_graphcanvas&&this.app.graph.list_of_graphcanvas.length>0&&(this.mouse=this.app.graph.list_of_graphcanvas[0].canvas_mouse,this.scale=this.app.graph.list_of_graphcanvas[0].ds.scale),this.mouse[3]=this.color,this.mouse[4]=this.scale/10,this.canSendMouse){let e=Object.keys(this.nexusSocket.userManager.users);for(let t=0;t{if(t!=this.nexusSocket.uuid){let s=this.nexusSocket.userManager.get(t,"mouse"),n=this.nexusSocket.userManager.get(t,"name")||"User",o=this.nexusSocket.userManager.get(t,"pointer");if(this.nexusSocket.userManager.get(t,"mouse_hidden")==0&&(s=null),s&&s.length>0){let r=s[0]-4,h=s[1]-4,l=1-s[4];e.drawImage(o,r,h,18,18),e.font="14px Arial",e.fillStyle=s[3],e.fillText(n,r+22,h+16);let d=this.hex2rgb(s[3]);e.beginPath(),e.arc(r,h,l*600,0,2*Math.PI,!1),e.strokeStyle=`rgba(${d.r},${d.g},${d.b},0.1)`,e.lineWidth=2,e.stroke()}}})}};LiteGraph.use_uuids=!0;LiteGraph.uuidv4=function(){return Date.now()};LGraph.prototype.getGroupByUUID=function(i){let e=this._groups,t=null;for(let s=0;s=LiteGraph.MAX_NUMBER_OF_NODES)throw"LiteGraph: max number of nodes in a graph reached";if(LiteGraph.use_uuids){(i.id==null||i.id==-1)&&(i.id=LiteGraph.uuidv4());let t=localStorage.getItem("nexus-socket-uuid");t&&(i.properties.owner=t),this.last_node_id=i.id}else i.id==null||i.id==-1?i.id=++this.last_node_id:this.last_node_id=LiteGraph.MAX_NUMBER_OF_NODES)throw"LiteGraph: max number of nodes in a graph reached";return this.last_node_id=i.id,i.graph=this,this._version++,this._nodes.push(i),this._nodes_by_id[i.id]=i,this.config.align_to_grid&&i.alignToGrid(),e||this.updateExecutionOrder(),this.onNodeAddedNexus&&this.onNodeAddedNexus(i),this.setDirtyCanvas(!0),this.change(),i}};LGraph.prototype.remove=function(i){if(i.constructor===LiteGraph.LGraphGroup){var e=this._groups.indexOf(i);e!=-1&&this._groups.splice(e,1),i.graph=null,this._version++,this.setDirtyCanvas(!0,!0),this.change(),this.onGroupRemoved&&this.onGroupRemoved(i);return}if(this._nodes_by_id[i.id]!=null&&!i.ignore_remove){if(this.beforeChange(),i.inputs)for(var t=0;tthis.updateNode(e))};LGraph.prototype.updateLinks=function(i){i.forEach(e=>this.updateLink(e))};LGraph.prototype.updateGroups=function(i){i.forEach(e=>this.updateGroup(e))};var y="nexus";async function x(i,e={}){try{let t=await fetch(i,e),s=await t.json();if(!t.ok)throw new Error(s.error||"Something went wrong");return s}catch(t){return console.error(`Fetch error: ${t.message}`),{error:t.message}}}async function F(i,e){let t=`${y}/workflows/${e}`,s={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({user_id:i})};return await x(t,s)}async function U(i){let e=`${y}/workflows/meta`,t={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({user_id:i})};return await x(e,t)}async function D(i,e){let t=`${y}/workflow`,s={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({user_id:i,...e})};return await x(t,s)}async function H(i,e){let t=`${y}/workflow/backup`,s={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({user_id:i,...e})};return await x(t,s)}async function B(){let i=`${y}/workflow`;return await x(i)}async function O(i){let e=`${y}/permission/${i}`;return await x(e)}async function A(i,e,t,s){let n=`${y}/permission/${i}`,o={method:"POST",headers:{"Content-Type":"application/json",Authorization:s},body:JSON.stringify({admin_id:e,data:t})};return await x(n,o)}async function q(i,e,t){let s=`${y}/login`,n={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({uuid:i,account:e,password:t})};return await x(s,n)}async function j(i){let e=`${y}/verify`,t={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:i})};return await x(e,t)}var L=class{constructor(e,t,s){this.app=e,this.api=t,this.nexusSocket=s,this.nexusSocket.onMessageReceive.push(this.handleMessageReceive.bind(this)),this.init(),this.spectators=[],this.saveTime=0,setInterval(this.handleSpectators.bind(this),1e3/24)}async init(){let e=(await this.app.graphToPrompt()).workflow;await H(this.nexusSocket.uuid,e),this.app.graph.clear()}removeSaveManager(){this.saveTimer&&clearInterval(this.saveTimer)}async saveManager(e){this.nexusSocket.admin&&this.nexusSocket.sendMessage("workflow:timer",{time:e-2},!1),this.removeSaveManager(),this.saveTime=e,this.saveTimer=setInterval(this.sendWorkFlow.bind(this),e*1e3),console.log("Auto Backup Timer Setup:",e),document.addEventListener("visibilitychange",this.handleSaveWorkflowManager.bind(this))}async sendWorkFlow(){let e=(await this.app.graphToPrompt()).workflow;await D(this.nexusSocket.uuid,e)}async loadLatestWorkflow(){let e=await B(),t=e.links||[],s=e.nodes||[],n=e.groups||[];this.app.graph.updateNodes(s),this.app.graph.updateLinks(t),this.app.graph.updateGroups(n),this.app.graph.updateExecutionOrder(),this.app.graph.setDirtyCanvas(!0,!0)}async handleSaveWorkflowManager(){this.sendWorkFlow()}async handleSpectators(){if(this.spectators.length>0){let t=(await this.app.graphToPrompt()).workflow.extra;for(let s=0;s{t.onGroupMoved=this.onGroupMoved.bind(this,t),t.onGroupNodeMoved=this.onNodeMoved.bind(this)}),this.app.graph._nodes.forEach(t=>{t.onWidgetChanged=this.onWidgetChanged.bind(this,t),t.onConnectionsChange=this.onNodeConnectionChange.bind(this,t)})):(this.app.graph.onNodeAddedNexus=null,this.app.graph.onNodeAdded=null,this.app.graph.onNodeRemoved=null,this.app.canvas.onSelectionChange=null,this.app.canvas.onNodeDeselected=null,this.app.canvas.onNodeMoved=null,this.app.graph.onGroupAdded=null,this.app.graph.onGroupRemoved=null,this.app.graph._groups.forEach(t=>{t.onGroupMoved=null,t.onGroupNodeMoved=null}),this.app.graph._nodes.forEach(t=>{t.onWidgetChanged=null,t.onConnectionsChange=null}))}handleWorkflowUpdate(e,t){let s=this.app.graph,n=this.app.canvas,o=t.update,a=t.data,r;switch(o){case"node-added":s.updateNode(a);break;case"node-removed":s.removeNode(a);break;case"node-moved":s.updateNode(a);break;case"node-widget-changed":s.updateNode(a);break;case"node-selection":let h=[];a.forEach(l=>{r=s.getNodeById(l.id),r&&h.push(r)}),n.selectNodesNexus(h,!0);break;case"node-deselection":r=s.getNodeById(a.id),r&&n.deselectNodeNexus(r);break;case"group-added":s.updateGroup(a);break;case"group-moved":s.updateGroup(a);break;case"group-removed":s.removeGroup(a);break;case"node-connection":s.updateLinkManual(t.change,t.link,t.node,s);break;default:break}}onNodeAddedNexus(e){e.onWidgetChanged=this.onWidgetChanged.bind(this,e),e.onConnectionsChange=this.onNodeConnectionChange.bind(this,e)}onNodeAdded(e){let t=e.serialize();e.onWidgetChanged=this.onWidgetChanged.bind(this,e),e.onConnectionsChange=this.onNodeConnectionChange.bind(this,e),this.nexusSocket.sendMessage("workflow:update",{update:"node-added",data:t},!1)}onWidgetChanged(e){let t=e.serialize();this.nexusSocket.sendMessage("workflow:update",{update:"node-widget-changed",data:t},!1)}onNodeRemoved(e){let t=e.serialize();this.nexusSocket.sendMessage("workflow:update",{update:"node-removed",data:t},!1)}async onNodeConnectionChange(e,t,s,n,o,a){let r=n?"add":"remove",h=o;this.graphData=(await this.app.graphToPrompt()).workflow;let l=this.graphData.links;e=this.app.graph.getNodeById(e.id),e=e?e.serialize():null,this.nexusSocket.sendMessage("workflow:update",{node:e,update:"node-connection",link:h,change:r,data:l},!1)}onSelectionChange(e){let t=[];Object.keys(e).forEach(s=>{t.push(e[s].serialize())}),this.nexusSocket.sendMessage("workflow:update",{update:"node-selection",data:t},!1)}onNodeDeselected(e){let t=e.serialize();this.nexusSocket.sendMessage("workflow:update",{update:"node-deselection",data:t},!1)}onNodeMoved(e){let t=e.serialize();this.nexusSocket.sendMessage("workflow:update",{update:"node-moved",data:t},!1)}onGroupAdded(e){let t=e.serialize(),s=localStorage.getItem("nexus-socket-uuid");s&&(t.owner=s,e.configure(t)),e.onGroupMoved=this.onGroupMoved.bind(this,e),e.onGroupNodeMoved=this.onNodeMoved.bind(this),this.nexusSocket.sendMessage("workflow:update",{update:"group-added",data:t},!1)}onGroupRemoved(e){let t=e.serialize();this.nexusSocket.sendMessage("workflow:update",{update:"group-removed",data:t},!1)}onGroupMoved(e){let t=e.serialize();this.nexusSocket.sendMessage("workflow:update",{update:"group-moved",data:t},!1)}};var G=class extends EventTarget{constructor(e,t,s){super(),this.app=t,this.api=e,this.nexusSocket=s,this.comfy_events=["b_preview","progress","executing","executed","execution_start","execution_error","execution_cached"];let n=e.queuePrompt;this.apiWrapper={oqp:n,enableApi:!1,api:e,qp:async function(o,a){return this.enableApi?this.oqp.call(this.api,o,{output:a.output,workflow:a.workflow}):{node_errors:{}}}},this.api.queuePrompt=this.apiWrapper.qp.bind(this.apiWrapper),this.nexusSocket.onMessageReceive.push(this.handleMessageReceive.bind(this)),this.addEventListeners(),this.comfy_events.forEach(o=>{this.api.addEventListener(o,this.handleComfyEvents.bind(this))}),this.handleProgressDraw(),this.handleControl(!1),this.handleEditor(!1)}handleProgressDraw(){let e=LGraphCanvas.prototype.drawNodeShape,t=this.app;LGraphCanvas.prototype.drawNodeShape=function(s,n,o,a,r,h,l){let d=e.apply(this,arguments),p=t.lastNodeErrors?.[s.id],u=null,m=1;if(s.id===t.runningNodeId?u="#0f0":t.dragOverNode&&s.id===t.dragOverNode.id?u="dodgerblue":p?.errors?(u="red",m=2):t.lastExecutionError&&t.lastExecutionError.node_id===s.id&&(u="#f0f",m=2),u){let f=s._shape||s.constructor.shape||LiteGraph.ROUND_SHAPE;n.lineWidth=m,n.globalAlpha=.8,n.beginPath(),f==LiteGraph.BOX_SHAPE?n.rect(-6,-6-LiteGraph.NODE_TITLE_HEIGHT,12+o[0]+1,12+o[1]+LiteGraph.NODE_TITLE_HEIGHT):f==LiteGraph.ROUND_SHAPE||f==LiteGraph.CARD_SHAPE&&s.flags.collapsed?n.roundRect(-6,-6-LiteGraph.NODE_TITLE_HEIGHT,12+o[0]+1,12+o[1]+LiteGraph.NODE_TITLE_HEIGHT,this.round_radius*2):f==LiteGraph.CARD_SHAPE?n.roundRect(-6,-6-LiteGraph.NODE_TITLE_HEIGHT,12+o[0]+1,12+o[1]+LiteGraph.NODE_TITLE_HEIGHT,[this.round_radius*2,this.round_radius*2,2,2]):f==LiteGraph.CIRCLE_SHAPE&&n.arc(o[0]*.5,o[1]*.5,o[0]*.5+6,0,Math.PI*2),n.strokeStyle=u,n.stroke(),n.strokeStyle=a,n.globalAlpha=1}if(t.progress&&s.id===t.runningNodeId&&(n.fillStyle="green",n.fillRect(0,0,o[0]*(t.progress.value/t.progress.max),6),n.fillStyle=r),p){n.lineWidth=2,n.strokeStyle="red";for(let f of p.errors)if(f.extra_info&&f.extra_info.input_name){let g=s.findInputSlot(f.extra_info.input_name);if(g!==-1){let b=s.getConnectionPos(!0,g);n.beginPath(),n.arc(b[0]-s.pos[0],b[1]-s.pos[1],12,0,2*Math.PI,!1),n.stroke()}}}return d}}handleMessageReceive(e){try{this.dispatchEvent(new CustomEvent(e.name,{detail:e}))}catch(t){console.error("Error handling message:",t)}}handleComfyEvents(e){e.type==="b_preview"?this.blobToBase64(e.detail).then(t=>{this.nexusSocket.sendMessage(e.type,{detail:t},!1)}):this.nexusSocket.sendMessage(e.type,{detail:e.detail},!1)}addEventListeners(){this.addEventListener("progress",({detail:e})=>{e=e.data.detail,this.app.progress=e,this.app.graph.setDirtyCanvas(!0,!1)}),this.addEventListener("executing",({detail:e})=>{e=e.data.detail,this.app.progress=null,this.app.runningNodeId=e,this.app.graph.setDirtyCanvas(!0,!1),delete this.app.nodePreviewImages[this.app.runningNodeId]}),this.addEventListener("executed",({detail:e})=>{e=e.data.detail;let t=this.app.nodeOutputs[e.node];if(e.merge&&t)for(let n in e.output??{}){let o=t[n];o instanceof Array?t[n]=o.concat(e.output[n]):t[n]=e.output[n]}else this.app.nodeOutputs[e.node]=e.output;let s=this.app.graph.getNodeById(e.node);s&&s.onExecuted&&s.onExecuted(e.output)}),this.addEventListener("execution_start",({detail:e})=>{e=e.data.detail,this.app.runningNodeId=null,this.app.lastExecutionError=null,this.app.graph._nodes.forEach(t=>{t.onExecutionStart&&t.onExecutionStart()})}),this.addEventListener("execution_error",({detail:e})=>{e=e.data.detail,this.app.lastExecutionError=e;let t=this.formatExecutionError(e);this.app.ui.dialog.show(t),this.app.canvas.draw(!0,!0)}),this.addEventListener("b_preview",({detail:e})=>{e=e.data.detail;let t=this.app.runningNodeId;if(t==null)return;let s=this.base64ToBlob(e),n=URL.createObjectURL(s);this.app.nodePreviewImages[t]=[n]})}blobToBase64(e){return new Promise((t,s)=>{let n=new FileReader;n.onloadend=()=>{t(n.result)},n.onerror=s,n.readAsDataURL(e)})}base64ToBlob(e){let[t,s]=e.split(","),n=t.match(/:(.*?);/)[1],o=atob(s),a=new Array(o.length);for(let h=0;h`}svgStringToImage(e){let t=new Blob([e],{type:"image/svg+xml"}),s=URL.createObjectURL(t),n=new Image;return n.src=s,n}hex2rgb(e){let t=parseInt(e.slice(1,3),16),s=parseInt(e.slice(3,5),16),n=parseInt(e.slice(5,7),16);return{r:t,g:s,b:n}}getRandomHexColor(){return this.hexColors[Math.floor(Math.random()*this.hexColors.length)]}constructor(e,t,s){this.color=this.getRandomHexColor(),this.app=t,this.fps=s,this.canSendMouse=!1,this.nexusSocket=e,this.nexusSocket.onConnected.push(this.handleConnect.bind(this)),this.nexusSocket.onMessageReceive.push(this.handleMessageReceive.bind(this)),document.addEventListener("visibilitychange",this.handleVisiblityChange.bind(this)),document.addEventListener("mousemove",this.handleSendMouseControl.bind(this)),this.app.graph.list_of_graphcanvas[0].onDrawForeground=this.handlePointerDraw.bind(this),setInterval(this.handleSendMouse.bind(this),1e3/this.fps)}throttle(e,t){let s,n;return function(...o){let a=this;n?(clearTimeout(s),s=setTimeout(function(){Date.now()-n>=t&&(e.apply(a,o),n=Date.now())},t-(Date.now()-n))):(e.apply(a,o),n=Date.now())}}handleCanvasDraw(){this.app.graph&&this.app.graph.list_of_graphcanvas&&this.app.graph.list_of_graphcanvas.length>0&&this.app.graph.list_of_graphcanvas[0].draw(!0,!0)}handleConnect(){this.drawTimer=setInterval(this.handleCanvasDraw.bind(this),1e3/this.fps)}handleMessageReceive(e){let t=e.name,s=e.from,n=e.data;if(t=="mouse"){let o=this.nexusSocket.userManager.get(s,"mouse"),a=this.nexusSocket.userManager.get(s,"pointer");a?a&&o&&o[3]!=n.mouse[3]&&this.nexusSocket.userManager.set(s,"pointer",this.svgStringToImage(this.createMouseSvg(n.mouse[3]))):this.nexusSocket.userManager.set(s,"pointer",this.svgStringToImage(this.createMouseSvg(n.mouse[3]))),this.nexusSocket.userManager.set(s,"mouse",n.mouse)}else t=="hide_mouse"?this.nexusSocket.userManager.set(s,"mouse",null):t=="mouse_view_toggle"&&(this.nexusSocket.userManager.set(s,"mouse_view",n.on),n.on==0&&this.nexusSocket.sendMessage("hide_mouse",{receiver:s},!1))}handleVisiblityChange(){document.visibilityState==="hidden"?(clearInterval(this.drawTimer),this.nexusSocket.sendMessage("hide_mouse",{},!1),this.nexusSocket.sendMessage("afk",{},!1)):(this.handleConnect(),this.nexusSocket.sendMessage("online",{},!1))}handleSendMouse=function(){if(this.app.graph&&this.app.graph.list_of_graphcanvas&&this.app.graph.list_of_graphcanvas.length>0&&(this.mouse=this.app.graph.list_of_graphcanvas[0].canvas_mouse,this.scale=this.app.graph.list_of_graphcanvas[0].ds.scale),this.mouse[3]=this.color,this.mouse[4]=this.scale/10,this.canSendMouse){let e=Object.keys(this.nexusSocket.userManager.users);for(let t=0;t{if(t!=this.nexusSocket.uuid){let s=this.nexusSocket.userManager.get(t,"mouse"),n=this.nexusSocket.userManager.get(t,"name")||"User",o=this.nexusSocket.userManager.get(t,"pointer");if(this.nexusSocket.userManager.get(t,"mouse_hidden")==0&&(s=null),s&&s.length>0){let r=s[0]-4,h=s[1]-4,l=1-s[4];e.drawImage(o,r,h,18,18),e.font="14px Arial",e.fillStyle=s[3],e.fillText(n,r+22,h+16);let d=this.hex2rgb(s[3]);e.beginPath(),e.arc(r,h,l*600,0,2*Math.PI,!1),e.strokeStyle=`rgba(${d.r},${d.g},${d.b},0.1)`,e.lineWidth=2,e.stroke()}}})}};LiteGraph.use_uuids=!0;LiteGraph.uuidv4=function(){return Date.now()};LGraph.prototype.getGroupByUUID=function(i){let e=this._groups,t=null;for(let s=0;s=LiteGraph.MAX_NUMBER_OF_NODES)throw"LiteGraph: max number of nodes in a graph reached";if(LiteGraph.use_uuids){(i.id==null||i.id==-1)&&(i.id=LiteGraph.uuidv4());let t=localStorage.getItem("nexus-socket-uuid");t&&(i.properties.owner=t),this.last_node_id=i.id}else i.id==null||i.id==-1?i.id=++this.last_node_id:this.last_node_id=LiteGraph.MAX_NUMBER_OF_NODES)throw"LiteGraph: max number of nodes in a graph reached";return this.last_node_id=i.id,i.graph=this,this._version++,this._nodes.push(i),this._nodes_by_id[i.id]=i,this.config.align_to_grid&&i.alignToGrid(),e||this.updateExecutionOrder(),this.onNodeAddedNexus&&this.onNodeAddedNexus(i),this.setDirtyCanvas(!0),this.change(),i}};LGraph.prototype.remove=function(i){if(i.constructor===LiteGraph.LGraphGroup){var e=this._groups.indexOf(i);e!=-1&&this._groups.splice(e,1),i.graph=null,this._version++,this.setDirtyCanvas(!0,!0),this.change(),this.onGroupRemoved&&this.onGroupRemoved(i);return}if(this._nodes_by_id[i.id]!=null&&!i.ignore_remove){if(this.beforeChange(),i.inputs)for(var t=0;tthis.updateNode(e))};LGraph.prototype.updateLinks=function(i){i.forEach(e=>this.updateLink(e))};LGraph.prototype.updateGroups=function(i){i.forEach(e=>this.updateGroup(e))};var y="nexus";async function x(i,e={}){try{let t=await fetch(i,e),s=await t.json();if(!t.ok)throw new Error(s.error||"Something went wrong");return s}catch(t){return console.error(`Fetch error: ${t.message}`),{error:t.message}}}async function F(i,e){let t=`${y}/workflows/${e}`,s={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({user_id:i})};return await x(t,s)}async function U(i){let e=`${y}/workflows/meta`,t={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({user_id:i})};return await x(e,t)}async function D(i,e){let t=`${y}/workflow`,s={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({user_id:i,...e})};return await x(t,s)}async function H(i,e){let t=`${y}/workflow/backup`,s={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({user_id:i,...e})};return await x(t,s)}async function q(){let i=`${y}/workflow`;return await x(i)}async function O(i){let e=`${y}/permission/${i}`;return await x(e)}async function A(i,e,t,s){let n=`${y}/permission/${i}`,o={method:"POST",headers:{"Content-Type":"application/json",Authorization:s},body:JSON.stringify({admin_id:e,data:t})};return await x(n,o)}async function B(i,e,t){let s=`${y}/login`,n={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({uuid:i,account:e,password:t})};return await x(s,n)}async function j(i){let e=`${y}/verify`,t={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:i})};return await x(e,t)}var L=class{constructor(e,t,s){this.app=e,this.api=t,this.nexusSocket=s,this.nexusSocket.onMessageReceive.push(this.handleMessageReceive.bind(this)),this.init(),this.spectators=[],this.saveTime=0,setInterval(this.handleSpectators.bind(this),1e3/24)}async init(){let e=(await this.app.graphToPrompt()).workflow;await H(this.nexusSocket.uuid,e),this.app.graph.clear()}removeSaveManager(){this.saveTimer&&clearInterval(this.saveTimer)}async saveManager(e){this.nexusSocket.admin&&this.nexusSocket.sendMessage("workflow:timer",{time:e-2},!1),this.removeSaveManager(),this.saveTime=e,this.saveTimer=setInterval(this.sendWorkFlow.bind(this),e*1e3),console.log("Auto Backup Timer Setup:",e)}async sendWorkFlow(){let e=(await this.app.graphToPrompt()).workflow;await D(this.nexusSocket.uuid,e)}async loadLatestWorkflow(){let e=await q(),t=e.links||[],s=e.nodes||[],n=e.groups||[];this.app.graph.updateNodes(s),this.app.graph.updateLinks(t),this.app.graph.updateGroups(n),this.app.graph.updateExecutionOrder(),this.app.graph.setDirtyCanvas(!0,!0)}async handleSaveWorkflowManager(){this.sendWorkFlow()}async handleSpectators(){if(this.spectators.length>0){let t=(await this.app.graphToPrompt()).workflow.extra;for(let s=0;s{t.onGroupMoved=this.onGroupMoved.bind(this,t),t.onGroupNodeMoved=this.onNodeMoved.bind(this)}),this.app.graph._nodes.forEach(t=>{t.onWidgetChanged=this.onWidgetChanged.bind(this,t),t.onConnectionsChange=this.onNodeConnectionChange.bind(this,t)})):(this.app.graph.onNodeAddedNexus=null,this.app.graph.onNodeAdded=null,this.app.graph.onNodeRemoved=null,this.app.canvas.onSelectionChange=null,this.app.canvas.onNodeDeselected=null,this.app.canvas.onNodeMoved=null,this.app.graph.onGroupAdded=null,this.app.graph.onGroupRemoved=null,this.app.graph._groups.forEach(t=>{t.onGroupMoved=null,t.onGroupNodeMoved=null}),this.app.graph._nodes.forEach(t=>{t.onWidgetChanged=null,t.onConnectionsChange=null}))}handleWorkflowUpdate(e,t){let s=this.app.graph,n=this.app.canvas,o=t.update,a=t.data,r;switch(o){case"node-added":s.updateNode(a);break;case"node-removed":s.removeNode(a);break;case"node-moved":s.updateNode(a);break;case"node-widget-changed":s.updateNode(a);break;case"node-selection":let h=[];a.forEach(l=>{r=s.getNodeById(l.id),r&&h.push(r)}),n.selectNodesNexus(h,!0);break;case"node-deselection":r=s.getNodeById(a.id),r&&n.deselectNodeNexus(r);break;case"group-added":s.updateGroup(a);break;case"group-moved":s.updateGroup(a);break;case"group-removed":s.removeGroup(a);break;case"node-connection":s.updateLinkManual(t.change,t.link,t.node,s);break;default:break}}onNodeAddedNexus(e){e.onWidgetChanged=this.onWidgetChanged.bind(this,e),e.onConnectionsChange=this.onNodeConnectionChange.bind(this,e)}onNodeAdded(e){let t=e.serialize();e.onWidgetChanged=this.onWidgetChanged.bind(this,e),e.onConnectionsChange=this.onNodeConnectionChange.bind(this,e),this.nexusSocket.sendMessage("workflow:update",{update:"node-added",data:t},!1)}onWidgetChanged(e){let t=e.serialize();this.nexusSocket.sendMessage("workflow:update",{update:"node-widget-changed",data:t},!1)}onNodeRemoved(e){let t=e.serialize();this.nexusSocket.sendMessage("workflow:update",{update:"node-removed",data:t},!1)}async onNodeConnectionChange(e,t,s,n,o,a){let r=n?"add":"remove",h=o;this.graphData=(await this.app.graphToPrompt()).workflow;let l=this.graphData.links;e=this.app.graph.getNodeById(e.id),e=e?e.serialize():null,this.nexusSocket.sendMessage("workflow:update",{node:e,update:"node-connection",link:h,change:r,data:l},!1)}onSelectionChange(e){let t=[];Object.keys(e).forEach(s=>{t.push(e[s].serialize())}),this.nexusSocket.sendMessage("workflow:update",{update:"node-selection",data:t},!1)}onNodeDeselected(e){let t=e.serialize();this.nexusSocket.sendMessage("workflow:update",{update:"node-deselection",data:t},!1)}onNodeMoved(e){let t=e.serialize();this.nexusSocket.sendMessage("workflow:update",{update:"node-moved",data:t},!1)}onGroupAdded(e){let t=e.serialize(),s=localStorage.getItem("nexus-socket-uuid");s&&(t.owner=s,e.configure(t)),e.onGroupMoved=this.onGroupMoved.bind(this,e),e.onGroupNodeMoved=this.onNodeMoved.bind(this),this.nexusSocket.sendMessage("workflow:update",{update:"group-added",data:t},!1)}onGroupRemoved(e){let t=e.serialize();this.nexusSocket.sendMessage("workflow:update",{update:"group-removed",data:t},!1)}onGroupMoved(e){let t=e.serialize();this.nexusSocket.sendMessage("workflow:update",{update:"group-moved",data:t},!1)}};var G=class extends EventTarget{constructor(e,t,s){super(),this.app=t,this.api=e,this.nexusSocket=s,this.comfy_events=["b_preview","progress","executing","executed","execution_start","execution_error","execution_cached"];let n=e.queuePrompt;this.apiWrapper={oqp:n,enableApi:!1,api:e,qp:async function(o,a){return this.enableApi?this.oqp.call(this.api,o,{output:a.output,workflow:a.workflow}):{node_errors:{}}}},this.api.queuePrompt=this.apiWrapper.qp.bind(this.apiWrapper),this.nexusSocket.onMessageReceive.push(this.handleMessageReceive.bind(this)),this.addEventListeners(),this.comfy_events.forEach(o=>{this.api.addEventListener(o,this.handleComfyEvents.bind(this))}),this.handleProgressDraw(),this.handleControl(!1),this.handleEditor(!1)}handleProgressDraw(){let e=LGraphCanvas.prototype.drawNodeShape,t=this.app;LGraphCanvas.prototype.drawNodeShape=function(s,n,o,a,r,h,l){let d=e.apply(this,arguments),p=t.lastNodeErrors?.[s.id],u=null,m=1;if(s.id===t.runningNodeId?u="#0f0":t.dragOverNode&&s.id===t.dragOverNode.id?u="dodgerblue":p?.errors?(u="red",m=2):t.lastExecutionError&&t.lastExecutionError.node_id===s.id&&(u="#f0f",m=2),u){let f=s._shape||s.constructor.shape||LiteGraph.ROUND_SHAPE;n.lineWidth=m,n.globalAlpha=.8,n.beginPath(),f==LiteGraph.BOX_SHAPE?n.rect(-6,-6-LiteGraph.NODE_TITLE_HEIGHT,12+o[0]+1,12+o[1]+LiteGraph.NODE_TITLE_HEIGHT):f==LiteGraph.ROUND_SHAPE||f==LiteGraph.CARD_SHAPE&&s.flags.collapsed?n.roundRect(-6,-6-LiteGraph.NODE_TITLE_HEIGHT,12+o[0]+1,12+o[1]+LiteGraph.NODE_TITLE_HEIGHT,this.round_radius*2):f==LiteGraph.CARD_SHAPE?n.roundRect(-6,-6-LiteGraph.NODE_TITLE_HEIGHT,12+o[0]+1,12+o[1]+LiteGraph.NODE_TITLE_HEIGHT,[this.round_radius*2,this.round_radius*2,2,2]):f==LiteGraph.CIRCLE_SHAPE&&n.arc(o[0]*.5,o[1]*.5,o[0]*.5+6,0,Math.PI*2),n.strokeStyle=u,n.stroke(),n.strokeStyle=a,n.globalAlpha=1}if(t.progress&&s.id===t.runningNodeId&&(n.fillStyle="green",n.fillRect(0,0,o[0]*(t.progress.value/t.progress.max),6),n.fillStyle=r),p){n.lineWidth=2,n.strokeStyle="red";for(let f of p.errors)if(f.extra_info&&f.extra_info.input_name){let g=s.findInputSlot(f.extra_info.input_name);if(g!==-1){let b=s.getConnectionPos(!0,g);n.beginPath(),n.arc(b[0]-s.pos[0],b[1]-s.pos[1],12,0,2*Math.PI,!1),n.stroke()}}}return d}}handleMessageReceive(e){try{this.dispatchEvent(new CustomEvent(e.name,{detail:e}))}catch(t){console.error("Error handling message:",t)}}handleComfyEvents(e){e.type==="b_preview"?this.blobToBase64(e.detail).then(t=>{this.nexusSocket.sendMessage(e.type,{detail:t},!1)}):this.nexusSocket.sendMessage(e.type,{detail:e.detail},!1)}addEventListeners(){this.addEventListener("progress",({detail:e})=>{e=e.data.detail,this.app.progress=e,this.app.graph.setDirtyCanvas(!0,!1)}),this.addEventListener("executing",({detail:e})=>{e=e.data.detail,this.app.progress=null,this.app.runningNodeId=e,this.app.graph.setDirtyCanvas(!0,!1),delete this.app.nodePreviewImages[this.app.runningNodeId]}),this.addEventListener("executed",({detail:e})=>{e=e.data.detail;let t=this.app.nodeOutputs[e.node];if(e.merge&&t)for(let n in e.output??{}){let o=t[n];o instanceof Array?t[n]=o.concat(e.output[n]):t[n]=e.output[n]}else this.app.nodeOutputs[e.node]=e.output;let s=this.app.graph.getNodeById(e.node);s&&s.onExecuted&&s.onExecuted(e.output)}),this.addEventListener("execution_start",({detail:e})=>{e=e.data.detail,this.app.runningNodeId=null,this.app.lastExecutionError=null,this.app.graph._nodes.forEach(t=>{t.onExecutionStart&&t.onExecutionStart()})}),this.addEventListener("execution_error",({detail:e})=>{e=e.data.detail,this.app.lastExecutionError=e;let t=this.formatExecutionError(e);this.app.ui.dialog.show(t),this.app.canvas.draw(!0,!0)}),this.addEventListener("b_preview",({detail:e})=>{e=e.data.detail;let t=this.app.runningNodeId;if(t==null)return;let s=this.base64ToBlob(e),n=URL.createObjectURL(s);this.app.nodePreviewImages[t]=[n]})}blobToBase64(e){return new Promise((t,s)=>{let n=new FileReader;n.onloadend=()=>{t(n.result)},n.onerror=s,n.readAsDataURL(e)})}base64ToBlob(e){let[t,s]=e.split(","),n=t.match(/:(.*?);/)[1],o=atob(s),a=new Array(o.length);for(let h=0;h{e==="display"&&(this.defaultDisplay=t),this.el.style[e]=t})}removeStyles(){this.el&&(Object.keys(this.styles).forEach(e=>{this.el.style[e]=""}),this.styles={})}updateAttrs(e={}){this.attrs={...this.attrs,...e},this.addAttrs()}addAttrs(){this.el&&Object.entries(this.attrs).forEach(([e,t])=>{this.el.setAttribute(e,t)})}removeAttrs(){this.el&&(Object.keys(this.attrs).forEach(e=>{this.el.removeAttribute(e)}),this.attrs={})}addChildrens(){this.el&&(this.childrens.forEach(e=>{typeof e=="string"?this.el.insertAdjacentHTML("beforeend",e):e instanceof Node?this.el.appendChild(e):e instanceof v?this.el.appendChild(e.el):e instanceof i&&this.el.appendChild(e.el)}),this.afterChildrenAppend&&requestAnimationFrame(()=>this.afterChildrenAppend(this.childrens,this)))}addChild(e){this.el&&(typeof e=="string"?this.el.insertAdjacentHTML("beforeend",e):e instanceof Node?this.el.appendChild(e):e instanceof i&&this.el.appendChild(e.el),this.childrens.includes(e)||this.childrens.push(e),this.afterChildrenAppend&&this.afterChildrenAppend(this.childrens,this))}removeChildrens(){this.el&&(this.el.innerHTML="",this.childrens=[])}addEvents(){this.el&&Object.entries(this.events).forEach(([e,t])=>{this.el.addEventListener(e,s=>{t(s,this.parent)})})}removeEvents(){this.el&&(Object.entries(this.events).forEach(([e,t])=>{this.el.removeEventListener(e,t)}),this.events={})}show(){this.el&&(this.el.style.display=this.defaultDisplay,this.visible=!0)}hide(){this.el&&(this.el.style.display="none",this.visible=!1)}addStateStyles(){this.el&&(this.el.addEventListener("mouseenter",()=>this.applyStyles(this.hoverStyles)),this.el.addEventListener("mouseleave",()=>this.applyStyles(this.styles)),this.el.addEventListener("focus",()=>this.applyStyles(this.focusStyles),!0),this.el.addEventListener("blur",()=>this.applyStyles(this.styles),!0),this.el.addEventListener("mousedown",()=>this.applyStyles(this.activeStyles)),this.el.addEventListener("mouseup",()=>this.applyStyles(this.styles)))}applyStyles(e){this.visible&&Object.entries(e).forEach(([t,s])=>{this.el.style[t]=s})}};var z=new c({id:"nexus-chat-main",tag:"div",visible:!0,styles:{width:"512px",minHeight:"170px",maxHeight:"170px",overflow:"hidden",padding:"16px",borderRadius:"8px",border:"1px solid rgba(94,94,94,0.5)"},hoverStyles:{overflowY:"scroll"},afterChildrenAppend:function(i,e){i.length>50&&(i[0].removeElement(),i.shift()),e.el.scrollTop=e.el.scrollHeight}}),_=new c({id:"nexus-input-main",tag:"div",visible:!0,styles:{width:"100%",height:"32px",display:"flex",alignItems:"center"},childrens:[new c({id:"nexus-input-label",tag:"span",visible:!1,styles:{fontFamily:'Calibri, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',display:"block",fontSize:"14px",lineHeight:"14px",fontWeight:600,color:"white",padding:"0",margin:"0",textShadow:"1pt 1pt #000"},childrens:["Say:"]}),new c({id:"nexus-input",tag:"input",visible:!1,styles:{fontFamily:'Calibri, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',fontSize:"14px",lineHeight:"14px",fontWeight:600,width:"100%",color:"white",padding:"0",margin:"0",border:"none",background:"transparent",flexGrow:1,outline:"none",textIndent:"4pt",caretColor:"transparent",textShadow:"1pt 1pt #000"}})]}),C=new c({id:"nexus-chat-window",tag:"div",styles:{position:"absolute",left:"16px",top:"100px",display:"flex",flexDirection:"column",zIndex:1e3},childrens:[new c({id:"nexus-total-players",tag:"div",visible:!0,styles:{fontFamily:'Calibri, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',fontSize:"14px",lineHeight:"14px",fontWeight:600,left:"16px",top:"80px",color:"#a5a5a5",width:"100%",paddingBottom:"12px",textAlign:"right"},childrens:["Users Online: ",new c({id:"nexus-total-players-count",visible:!0,tag:"span",childrens:["0"]})]}),z,_,new v({styles:{"#nexus-chat-main::-webkit-scrollbar":{display:"none","scrollbar-width":"none","-ms-overflow-style":"none"},"#nexus-chat-window":{}}})]}),w=function(i,e,t,s,n){let o="";n?o=`${i} ${e}`:o=`${i}: ${e}`;let a=new c({tag:"span",visible:!0,styles:{fontFamily:'Calibri, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',display:"block",fontSize:"14px",lineHeight:"14px",fontWeight:600,width:"100%",color:"white",padding:"0",margin:"0",textShadow:"1pt 1pt #000",marginBottom:"1pt",lineBreak:"anywhere"},childrens:[o]});z.addChild(a)};var I=class{constructor(){this.active=0,this.panel=new c({id:"nexus-player-panel",tag:"div",visible:!1,styles:{width:"100%",height:"100vh",display:"flex","align-items":"center","justify-content":"center","box-sizing":"border-box",position:"absolute",left:"0",top:"0","z-index":"10000"},childrens:[new c({id:"nexus-player-panel-table",tag:"div",visible:!0,styles:{width:"832px",display:"flex","flex-direction":"column","border-radius":"6px","box-sizing":"border-box"},childrens:[new c({id:"nexus-player-panel-table-body",tag:"div",visible:!0,styles:{width:"100%",display:"flex","flex-direction":"column","align-items":"center","justify-content":"flex-start",color:"#a3a3a3","font-family":"Calibri","font-weight":"600",gap:"12px","padding-bottom":"12px","box-sizing":"border-box",background:"rgba(54,54,54,0.8)","border-radius":"6px","box-shadow":"4px 8px 8px rgba(0,0,0,0.5)","max-height":"540px",overflowY:"auto"}}),new v({styles:{"#nexus-player-panel .table-row":{width:"100%",display:"grid","align-items":"center","grid-template-columns":"20% 60% 20%","justify-content":"space-between"},"#nexus-player-panel .table-row:first-child":{width:"100%",color:"#a3a3a3",padding:"16px 0",background:"rgb(0,0,0,0.6)","border-top-left-radius":"6px","border-top-right-radius":"6px",position:"sticky",top:"0"},"#nexus-player-panel .table-row .table-row-child":{display:"flex","justify-content":"flex-start",gap:"12px","padding-left":"12px",width:"100%"},"#nexus-player-panel .table-row-child button":{border:"none",padding:"6px 12px","border-radius":"3px",cursor:"pointer",background:"rgba(94,94,94)",color:"#a1a1a1"},"#nexus-player-panel .table-row-child button:active":{opacity:"0.8"},"#nexus-player-panel .table-row-child button[active='1'][label='spectate']":{background:"#218c74",color:"#fafafa"},"#nexus-player-panel .table-row-child button[active='1'][label='editor']":{background:"#474787",color:"#fafafa"},"#nexus-player-panel .table-row-child button[active='1'][label='mouse']":{background:"#cd6133",color:"#fafafa"},"#nexus-player-panel .table-row-child button[active='1'][label='queue']":{background:"#6F1E51",color:"#fafafa"}}})]})]}),this.onCommandReceived=null,this.buttons=[],this.columns=[]}addColumnsToPanel(e){this.columns=e}addRowsToPanel(e,t,s,n){let o=this.panel.childrens[0].childrens[0];o.removeChildrens(),this.buttons=[];let a=document.createElement("div");a.className="table-row",this.columns.forEach(r=>{let h=document.createElement("span");h.className="table-row-child",h.textContent=r,a.appendChild(h)}),o.addChild(a),e.forEach((r,h)=>{let l=document.createElement("div");l.className="table-row",r.forEach((d,p)=>{let u=document.createElement("span");u.className="table-row-child";let m=d.indexOf(",")>-1,f=d.indexOf(":")>-1,g=[];m?(g=d.split(","),g.forEach((b,k)=>{let S=b.split(":");this.addChildToParent(S,u,t,s,n,h,p,k)})):f?(g=d.split(":"),this.addChildToParent(g,u,t,s,n,h,p,-1)):u.textContent=d,l.appendChild(u)}),o.addChild(l)})}addChildToParent(e,t,s,n,o,a,r,h){switch(e[0]){case"button":let l=document.createElement("button");if(e[1]=="none"&&(l.className="none"),this.buttons.includes(l)||this.buttons.push(l),l.textContent=e[1],s[a]&&s[a][r]&&n[a][r]&&o[a][r]){let d=n[a][r].split(","),p=o[a][r].split(",");h!=-1?(l.setAttribute("data",p[h]),l.setAttribute("active",d[h])):(l.setAttribute("data",o[a][r]),l.setAttribute("active",n[a][r])),l.setAttribute("kind",e[0]),l.setAttribute("label",e[1]),e[1]!="none"&&(l.onclick=s[a][r].bind(this))}t.appendChild(l);break}}disableButtons(e){this.buttons.forEach(t=>{let s=t.getAttribute("kind"),n=t.getAttribute("data"),o=parseInt(t.getAttribute("active")),a=t.getAttribute("label");a==e&&o==1&&(t.setAttribute("active",0),this.onCommandReceived&&this.onCommandReceived(s,a,n,0))})}onclick(e){let t=e.target.getAttribute("kind"),s=e.target.getAttribute("data"),n=e.target.getAttribute("label"),o=parseInt(e.target.getAttribute("active"));t=="button"&&(n=="spectate"&&this.disableButtons(n),o==0?e.target.setAttribute("active",1):o==1&&e.target.setAttribute("active",0)),o=parseInt(e.target.getAttribute("active")),this.onCommandReceived&&this.onCommandReceived(t,n,s,o)}};var P=class{constructor(){this.active=0,this.panel=new c({id:"nexus-workflow-panel",tag:"div",visible:!1,styles:{width:"100%",height:"100vh",display:"flex","align-items":"center","justify-content":"center","box-sizing":"border-box",position:"absolute",left:"0",top:"0","z-index":"10000"},childrens:[new c({id:"nexus-workflow-panel-table",tag:"div",visible:!0,styles:{width:"512px",display:"flex","flex-direction":"column","border-radius":"6px","box-sizing":"border-box"},childrens:[new c({id:"nexus-workflow-panel-table-body",tag:"div",visible:!0,styles:{width:"100%",display:"flex","flex-direction":"column","align-items":"center","justify-content":"flex-start",color:"#a3a3a3","font-family":"Calibri","font-weight":"600",gap:"12px","padding-bottom":"12px","box-sizing":"border-box",background:"rgba(54,54,54,0.8)","border-radius":"6px","box-shadow":"4px 8px 8px rgba(0,0,0,0.5)","max-height":"540px",overflowY:"auto"}}),new v({styles:{"#nexus-workflow-panel .table-row":{width:"100%",display:"flex","align-items":"center","justify-content":"center"},"#nexus-workflow-panel .table-row:first-child":{width:"100%",color:"#a3a3a3",padding:"16px 0",background:"rgb(0,0,0,0.6)","border-top-left-radius":"6px","border-top-right-radius":"6px",position:"sticky",top:"0"},"#nexus-workflow-panel .table-row .table-row-child":{display:"flex","justify-content":"flex-start",gap:"12px","padding-left":"12px",width:"100%"},"#nexus-workflow-panel .table-row-child button":{border:"none",padding:"6px 12px","border-radius":"3px",cursor:"pointer",background:"rgba(94,94,94)",color:"#a1a1a1",width:"100%"},"#nexus-workflow-panel .table-row-child:first-child":{width:"50%"},"#nexus-workflow-panel .table-row-child:last-child":{"padding-right":"12px"},"#nexus-workflow-panel .table-row-child button:active":{opacity:"0.8"},"#nexus-workflow-panel .table-row-child button[label='load']:active":{background:"#218c74",color:"#fafafa"},"#nexus-workflow-panel .table-row-child button[label='loadforall']:active":{background:"#474787",color:"#fafafa"}}})]})]}),this.onCommandReceived=null,this.buttons=[],this.columns=[]}addColumnsToPanel(e){this.columns=e}addRowsToPanel(e,t,s,n){let o=this.panel.childrens[0].childrens[0];o.removeChildrens(),this.buttons=[];let a=document.createElement("div");a.className="table-row",this.columns.forEach(r=>{let h=document.createElement("span");h.className="table-row-child",h.textContent=r,a.appendChild(h)}),o.addChild(a),e.forEach((r,h)=>{let l=document.createElement("div");l.className="table-row",r.forEach((d,p)=>{let u=document.createElement("span");u.className="table-row-child";let m=d.indexOf(",")>-1,f=d.indexOf(":")>-1,g=[];m?(g=d.split(","),g.forEach((b,k)=>{let S=b.split(":");this.addChildToParent(S,u,t,s,n,h,p,k)})):f?(g=d.split(":"),this.addChildToParent(g,u,t,s,n,h,p,-1)):(d=d.split("|"),d=d.join(":"),u.textContent=d),l.appendChild(u)}),o.addChild(l)})}addChildToParent(e,t,s,n,o,a,r,h){switch(e[0]){case"button":let l=document.createElement("button");if(e[1]=="none"&&(l.className="none"),this.buttons.includes(l)||this.buttons.push(l),l.textContent=e[1],s[a]&&s[a][r]&&n[a][r]&&o[a][r]){let d=n[a][r].split(","),p=o[a][r].split(",");h!=-1?(l.setAttribute("data",p[h]),l.setAttribute("active",d[h])):(l.setAttribute("data",o[a][r]),l.setAttribute("active",n[a][r])),l.setAttribute("kind",e[0]),l.setAttribute("label",e[1]),e[1]!="none"&&(l.onclick=s[a][r].bind(this))}t.appendChild(l);break}}onclick(e){let t=e.target.getAttribute("kind"),s=e.target.getAttribute("data"),n=e.target.getAttribute("label"),o=parseInt(e.target.getAttribute("active"));t=="button"&&(o==0?e.target.setAttribute("active",1):o==1&&e.target.setAttribute("active",0)),o=parseInt(e.target.getAttribute("active")),this.onCommandReceived&&this.onCommandReceived(t,n,s,o)}};var R=class{constructor(e,t,s,n,o,a,r){this.color=n,this.colors={join:"#ff6e4d",info:"#fba510",personal:"#fba510",name:"#00fa00",none:"#ffffff"},this.inputMain=_,this.nexusSocket=s,this.app=e,this.api=t,this.workflowManager=a,this.promptControl=r,this.mouseManger=o,this.nexusSocket.onConnected.push(this.handleConnect.bind(this)),this.nexusSocket.onMessageReceive.push(this.handleMessageReceive.bind(this)),this.inputMain.addEventListener("message",this.handleMessage.bind(this)),document.addEventListener("keydown",this.handleChatWindow.bind(this)),this.disableComfyThings=this.disableComfyThings.bind(this),this.enableComfyThings=this.enableComfyThings.bind(this),this.disableGraphSelectionWithExtremePrejudice=this.disableGraphSelectionWithExtremePrejudice.bind(this),this.comfyThings=["#extraOptions","#queue-button","#comfy-save-button","#comfy-file-input","#comfy-clear-button","#comfy-load-default-button",".queue-tab-button.side-bar-button",".queue-tab-button.side-bar-button","#comfy-refresh-button","#queue-front-button","#comfy-view-queue-button","#comfy-view-history-button"],C.childrens[3].softUpdate("#nexus-chat-window","pointer-events","none"),C.show(),setInterval(h=>{h.childrens[0].childrens[1].el.textContent=Object.keys(this.nexusSocket.userManager.users).length},1e3,C),this.up=new I,this.up.onCommandReceived=this.onPanelCommandReceived.bind(this),this.wp=new P,this.wp.onCommandReceived=this.onWFPanelCommandReceived.bind(this),this.spectating=null,this.lastkey=null}timeAgo(e){let t=new Date,s=new Date(e),n=Math.floor((t-s)/1e3),o=Math.floor(n/60),a=Math.floor(o/60),r=Math.floor(a/24);return o<1?"just now":o===1?"1 minute ago":o<60?`${o} minutes ago`:a===1?"1 hour ago":a<24?`${a} hours ago`:r===1?"1 day ago":`${r} days ago`}async verifyLogin(){this.disableComfyThings();let e=localStorage.getItem("nexus-socket-token");if(e){let t=await j(e);t&&this.nexusSocket.uuid==t.user_id?(this.enableComfyThings(),this.promptControl.handleControl(!0),this.promptControl.handleEditor(!0),this.workflowManager.handleWorkflowEvents(!0),this.nexusSocket.admin=!0,w("","You are now an admin!",this.color.info,this.colors.personal,!0),this.workflowManager.saveManager(60)):(this.promptControl.handleControl(!1),this.promptControl.handleEditor(!1),this.workflowManager.handleWorkflowEvents(!1),this.workflowManager.removeSaveManager(),w("","You are a viewer!",this.color.info,this.colors.info,!0))}else{let t=await O(this.nexusSocket.uuid);if(t){let s=t.editor?t.editor:!1,n=t.queue?t.queue:!1;this.workflowManager.handleWorkflowEvents(s),this.promptControl.handleEditor(s),this.promptControl.handleControl(n),this.nexusSocket.queue=n,this.nexusSocket.editor=s,s?this.workflowManager.saveManager(60):this.workflowManager.removeSaveManager(),w("",`Permission: Workflow Editor ${s?"Yes":"No"} | Queue Prompt ${n?"Yes":"No"} `,this.color.info,this.colors.personal,!0),n&&w("","You can now queue prompt press CTRL+Enter",this.color.info,this.colors.personal,!0)}}this.workflowManager.loadLatestWorkflow()}handleConnect(){let e=this.nexusSocket.userManager.get(this.nexusSocket.uuid,"name");this.nexusSocket.sendMessage("chat-join",{name:e},!1),this.verifyLogin()}findChildrenAfterHr(e){let t=document.querySelector(`.${e}`),s=[];if(t){let n=t.querySelector("hr");if(n){let o=n.nextElementSibling;for(;o;)s.push(o),o=o.nextElementSibling}}return s}disableGraphSelectionWithExtremePrejudice(){!this.nexusSocket.admin&&!this.nexusSocket.editor&&this.app.graph&&this.app.graph.list_of_graphcanvas&&this.app.graph.list_of_graphcanvas.length>0&&this.app.graph.list_of_graphcanvas[0].deselectAllNodes()}disableComfyThings(){this.comfyThings.forEach(t=>{document.querySelectorAll(t).forEach(n=>{n.disabled=!0,n.style.pointerEvents="none"})}),document.querySelectorAll(".comfy-settings-btn").forEach(t=>{t.disabled=!0,t.style.pointerEvents="none"}),this.findChildrenAfterHr("comfy-menu").forEach(t=>{(t.tagName==="BUTTON"||t.tagName==="INPUT"||t.tagName==="SELECT"||t.tagName==="TEXTAREA")&&(t.disabled=!0)}),document.querySelector(".comfy-menu").style.display="none",document.querySelector(".comfy-menu").style.pointerEvents="none",clearInterval(this.disableComfyThingsTimer),this.disableComfyThingsTimer=setInterval(()=>{this.comfyThings.forEach(s=>{document.querySelectorAll(s).forEach(o=>{o.disabled=!0,o.style.pointerEvents="none"})}),document.querySelectorAll(".comfy-settings-btn").forEach(s=>{s.disabled=!0,s.style.pointerEvents="none"}),this.findChildrenAfterHr("comfy-menu").forEach(s=>{(s.tagName==="BUTTON"||s.tagName==="INPUT"||s.tagName==="SELECT"||s.tagName==="TEXTAREA")&&(s.disabled=!0)}),document.querySelector(".comfy-menu").style.display="none",document.querySelector(".comfy-menu").style.pointerEvents="none",this.promptControl.handleEditor(this.nexusSocket.editor?this.nexusSocket.editor:!1),this.promptControl.handleControl(this.nexusSocket.queue?this.nexusSocket.queue:!1)},500),this.disableGraphSelectionWithExtremePrejudiceTimer=setInterval(this.disableGraphSelectionWithExtremePrejudice,50)}enableComfyThings(){clearInterval(this.disableComfyThingsTimer),clearInterval(this.disableGraphSelectionWithExtremePrejudiceTimer),this.comfyThings.forEach(t=>{document.querySelectorAll(t).forEach(n=>{n.disabled=!1,n.style.pointerEvents="all"})}),document.querySelectorAll(".comfy-settings-btn").forEach(t=>{t.disabled=!1,t.style.pointerEvents="all"}),this.findChildrenAfterHr("comfy-menu").forEach(t=>{(t.tagName==="BUTTON"||t.tagName==="INPUT"||t.tagName==="SELECT"||t.tagName==="TEXTAREA")&&(t.disabled=!1)}),document.querySelector(".comfy-menu").style.display="flex",document.querySelector(".comfy-menu").style.pointerEvents="all"}handleChatWindow(e){let t=e.key,s=_.childrens[0],n=_.childrens[1],o={tag:document.activeElement.tagName,el:document.activeElement,chat:document.activeElement==n.el};function a(){!["INPUT","TEXTAREA"].includes(o.tag)&&n.visible==!1&&(e.preventDefault(),s.show(),n.show(),n.el.focus(),n.el.value="",n.focusTimer=setInterval((d,p)=>{document.activeElement!=p&&d.visible==!0&&p.focus()},500,n,n.el),C.childrens[3].softUpdate("#nexus-chat-window","pointer-events","all"))}function r(){o.chat&&(s.hide(),n.el.blur(),n.el.value="",n.hide(),clearTimeout(n.focusTimer),C.childrens[3].softUpdate("#nexus-chat-window","pointer-events","none"))}function h(){if(!o.chat)return;let l=n.el.value;_.dispatchEvent(new CustomEvent("message",{detail:{message:l}})),r()}switch(t){case"t":case"T":a(),this.togglePlayerTab(!0),this.toggleWFTab(!0);break;case"Escape":r();break;case"Enter":h();break;case"p":case"P":e.altKey&&e.shiftKey&&(o.chat||this.togglePlayerTab());break;case"o":case"O":e.altKey&&e.shiftKey&&(o.chat||this.toggleWFTab());break}return o}toggleWFTab(e,t){(this.nexusSocket.admin||this.nexusSocket.editor)&&(e?(this.wp.active=0,this.wp.panel.hide()):t?this.prepareWFPanel():this.wp.active==0?(this.wp.active=1,this.wp.panel.show(),this.prepareWFPanel()):this.wp.active==1&&(this.wp.active=0,this.wp.panel.hide()),this.wp.active==1?this.workflowManager.removeSaveManager():this.workflowManager.saveManager(this.workflowManager.saveTime||60))}togglePlayerTab(e,t){e?(this.up.active=0,this.up.panel.hide()):t?this.preparePanel(this.nexusSocket.admin):this.up.active==0?(this.up.active=1,this.up.panel.show(),this.preparePanel(this.nexusSocket.admin)):this.up.active==1&&(this.up.active=0,this.up.panel.hide())}async onWFPanelCommandReceived(e,t,s,n){switch(e){case"button":if(t=="load"){let o=s,a=await F(this.nexusSocket.uuid,o);if(a){a.clear=!0;let r={name:"workflow",from:this.nexusSocket.uuid,data:{workflow:a}};this.nexusSocket.onMessageReceive.forEach(h=>{h(r)}),this.nexusSocket.admin&&this.nexusSocket.sendMessage("workflow",{workflow:a},!1)}}break}}async onPanelCommandReceived(e,t,s,n){switch(e){case"button":if(t=="spectate")this.nexusSocket.sendMessage("spectate",{on:n,receiver:s},!1),n==1?this.spectating=s:this.spectating=null;else if(t=="editor"){if(this.nexusSocket.admin){let o=localStorage.getItem("nexus-socket-token");await A(s,this.nexusSocket.uuid,{editor:!!n},o),this.nexusSocket.sendMessage("permission",{receiver:s},!1)}}else if(t=="queue"){if(this.nexusSocket.admin){let o=localStorage.getItem("nexus-socket-token");await A(s,this.nexusSocket.uuid,{queue:!!n},o),this.nexusSocket.sendMessage("permission",{receiver:s},!1)}}else t=="mouse"&&(this.nexusSocket.sendMessage("mouse_view_toggle",{on:n,receiver:s},!1),this.nexusSocket.userManager.set(s,"hide_mouse",n));break}}async prepareWFPanel(){let e=["Name","Updated","Action"];this.wp.addColumnsToPanel(e);let t=await U(this.nexusSocket.uuid),s=[],n=[],o=[],a=[];for(let r=0;r]+(>|$)/g;e=e.replace(a,"");for(let r of e)n.test(r)&&!o.test(r)||(s+=r);return s}}startsWithCommand(e){return/^\/\w+(\s+\S+)?/.test(e)}extractCommandAndValue(e){let t=/^\/(\w+)\s*(.*)/,s=e.match(t);if(s){let n=s[1],o=s[2].trim()?s[2].split(/\s+/):[];return{command:n,values:o}}else return null}};var J=window.comfyAPI.app.app,W=window.comfyAPI.api.api,E=new N,Y={name:"ComfyUI-Nexus",async setup(i){i=i;let e=new T(E,i,24),t=new L(i,W,E),s=new G(W,i,E);new R(i,W,E,e.color,e,t,s),E.connect()},async beforeConfigureGraph(){}};J.registerExtension(Y);})(); +${t}`}handleEditor(e){this.app.canvas.allow_dragnodes=e,this.app.canvas.allow_interaction=e,this.app.canvas.allow_reconnect_links=e,this.app.canvas.allow_searchbox=e}handleControl(e){this.apiWrapper.enableApi=e}};var v=class{constructor({styles:e}){this.el=null,this.styles=e,this.create()}create(){this.el=document.createElement("style");let e="";for(let t in this.styles){e+=`${t} { `;for(let s in this.styles[t])e+=`${s}: ${this.styles[t][s]}; `;e+="} "}this.el.textContent=e}softUpdate(e,t,s){let n="";for(let o in this.styles){n+=`${o} { `;for(let a in this.styles[o])n+=`${a}: ${this.styles[o][a]}; `;o==e&&(n+=`${t}: ${s}; `),n+="} "}this.el.textContent=n}};var c=class i extends EventTarget{id="";tag="";styles={};hoverStyles={};focusStyles={};activeStyles={};attrs={};childrens=[];events={};appendTo=document.body;visible=!1;afterChildrenAppend=null;afterCreated=null;defaultDisplay="initial";el=null;constructor({id:e,tag:t,styles:s={},hoverStyles:n={},focusStyles:o={},activeStyles:a={},attrs:r={},childrens:h=[],events:l={},appendTo:d=document.body,afterChildrenAppend:p=null,afterCreated:u=null,visible:m=!1}={}){super(),this.id=e,this.tag=t,this.styles=s,this.hoverStyles=n,this.focusStyles=o,this.activeStyles=a,this.attrs=r,this.childrens=h,this.events=l,this.appendTo=d,this.afterChildrenAppend=p,this.afterCreated=u,this.visible=m,this.createElement()}createElement(){if(!this.tag)throw new Error("Tag is required to create an element.");this.el=document.createElement(this.tag),this.id&&(this.el.id=this.id),this.appendTo.appendChild(this.el),this.addStyles(),this.addAttrs(),this.addChildrens(),this.addEvents(),this.addStateStyles(),this.visible||this.hide(),this.afterCreated&&this.afterCreated(this)}removeElement(){this.el&&(this.removeAttrs(),this.removeEvents(),this.removeStyles(),this.removeChildrens(),this.el.remove(),this.el=null)}updateStyles(e={}){this.styles={...this.styles,...e},this.addStyles()}addStyles(){this.el&&Object.entries(this.styles).forEach(([e,t])=>{e==="display"&&(this.defaultDisplay=t),this.el.style[e]=t})}removeStyles(){this.el&&(Object.keys(this.styles).forEach(e=>{this.el.style[e]=""}),this.styles={})}updateAttrs(e={}){this.attrs={...this.attrs,...e},this.addAttrs()}addAttrs(){this.el&&Object.entries(this.attrs).forEach(([e,t])=>{this.el.setAttribute(e,t)})}removeAttrs(){this.el&&(Object.keys(this.attrs).forEach(e=>{this.el.removeAttribute(e)}),this.attrs={})}addChildrens(){this.el&&(this.childrens.forEach(e=>{typeof e=="string"?this.el.insertAdjacentHTML("beforeend",e):e instanceof Node?this.el.appendChild(e):e instanceof v?this.el.appendChild(e.el):e instanceof i&&this.el.appendChild(e.el)}),this.afterChildrenAppend&&requestAnimationFrame(()=>this.afterChildrenAppend(this.childrens,this)))}addChild(e){this.el&&(typeof e=="string"?this.el.insertAdjacentHTML("beforeend",e):e instanceof Node?this.el.appendChild(e):e instanceof i&&this.el.appendChild(e.el),this.childrens.includes(e)||this.childrens.push(e),this.afterChildrenAppend&&this.afterChildrenAppend(this.childrens,this))}removeChildrens(){this.el&&(this.el.innerHTML="",this.childrens=[])}addEvents(){this.el&&Object.entries(this.events).forEach(([e,t])=>{this.el.addEventListener(e,s=>{t(s,this.parent)})})}removeEvents(){this.el&&(Object.entries(this.events).forEach(([e,t])=>{this.el.removeEventListener(e,t)}),this.events={})}show(){this.el&&(this.el.style.display=this.defaultDisplay,this.visible=!0)}hide(){this.el&&(this.el.style.display="none",this.visible=!1)}addStateStyles(){this.el&&(this.el.addEventListener("mouseenter",()=>this.applyStyles(this.hoverStyles)),this.el.addEventListener("mouseleave",()=>this.applyStyles(this.styles)),this.el.addEventListener("focus",()=>this.applyStyles(this.focusStyles),!0),this.el.addEventListener("blur",()=>this.applyStyles(this.styles),!0),this.el.addEventListener("mousedown",()=>this.applyStyles(this.activeStyles)),this.el.addEventListener("mouseup",()=>this.applyStyles(this.styles)))}applyStyles(e){this.visible&&Object.entries(e).forEach(([t,s])=>{this.el.style[t]=s})}};var z=new c({id:"nexus-chat-main",tag:"div",visible:!0,styles:{width:"512px",minHeight:"170px",maxHeight:"170px",overflow:"hidden",padding:"16px",borderRadius:"8px",border:"1px solid rgba(94,94,94,0.5)"},hoverStyles:{overflowY:"scroll"},afterChildrenAppend:function(i,e){i.length>50&&(i[0].removeElement(),i.shift()),e.el.scrollTop=e.el.scrollHeight}}),_=new c({id:"nexus-input-main",tag:"div",visible:!0,styles:{width:"100%",height:"32px",display:"flex",alignItems:"center"},childrens:[new c({id:"nexus-input-label",tag:"span",visible:!1,styles:{fontFamily:'Calibri, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',display:"block",fontSize:"14px",lineHeight:"14px",fontWeight:600,color:"white",padding:"0",margin:"0",textShadow:"1pt 1pt #000"},childrens:["Say:"]}),new c({id:"nexus-input",tag:"input",visible:!1,styles:{fontFamily:'Calibri, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',fontSize:"14px",lineHeight:"14px",fontWeight:600,width:"100%",color:"white",padding:"0",margin:"0",border:"none",background:"transparent",flexGrow:1,outline:"none",textIndent:"4pt",caretColor:"transparent",textShadow:"1pt 1pt #000"}})]}),C=new c({id:"nexus-chat-window",tag:"div",styles:{position:"absolute",left:"16px",top:"100px",display:"flex",flexDirection:"column",zIndex:1e3},childrens:[new c({id:"nexus-total-players",tag:"div",visible:!0,styles:{fontFamily:'Calibri, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',fontSize:"14px",lineHeight:"14px",fontWeight:600,left:"16px",top:"80px",color:"#a5a5a5",width:"100%",paddingBottom:"12px",textAlign:"right"},childrens:["Users Online: ",new c({id:"nexus-total-players-count",visible:!0,tag:"span",childrens:["0"]})]}),z,_,new v({styles:{"#nexus-chat-main::-webkit-scrollbar":{display:"none","scrollbar-width":"none","-ms-overflow-style":"none"},"#nexus-chat-window":{}}})]}),w=function(i,e,t,s,n){let o="";n?o=`${i} ${e}`:o=`${i}: ${e}`;let a=new c({tag:"span",visible:!0,styles:{fontFamily:'Calibri, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',display:"block",fontSize:"14px",lineHeight:"14px",fontWeight:600,width:"100%",color:"white",padding:"0",margin:"0",textShadow:"1pt 1pt #000",marginBottom:"1pt",lineBreak:"anywhere"},childrens:[o]});z.addChild(a)};var I=class{constructor(){this.active=0,this.panel=new c({id:"nexus-player-panel",tag:"div",visible:!1,styles:{width:"100%",height:"100vh",display:"flex","align-items":"center","justify-content":"center","box-sizing":"border-box",position:"absolute",left:"0",top:"0","z-index":"10000"},childrens:[new c({id:"nexus-player-panel-table",tag:"div",visible:!0,styles:{width:"832px",display:"flex","flex-direction":"column","border-radius":"6px","box-sizing":"border-box"},childrens:[new c({id:"nexus-player-panel-table-body",tag:"div",visible:!0,styles:{width:"100%",display:"flex","flex-direction":"column","align-items":"center","justify-content":"flex-start",color:"#a3a3a3","font-family":"Calibri","font-weight":"600",gap:"12px","padding-bottom":"12px","box-sizing":"border-box",background:"rgba(54,54,54,0.8)","border-radius":"6px","box-shadow":"4px 8px 8px rgba(0,0,0,0.5)","max-height":"540px",overflowY:"auto"}}),new v({styles:{"#nexus-player-panel .table-row":{width:"100%",display:"grid","align-items":"center","grid-template-columns":"20% 60% 20%","justify-content":"space-between"},"#nexus-player-panel .table-row:first-child":{width:"100%",color:"#a3a3a3",padding:"16px 0",background:"rgb(0,0,0,0.6)","border-top-left-radius":"6px","border-top-right-radius":"6px",position:"sticky",top:"0"},"#nexus-player-panel .table-row .table-row-child":{display:"flex","justify-content":"flex-start",gap:"12px","padding-left":"12px",width:"100%"},"#nexus-player-panel .table-row-child button":{border:"none",padding:"6px 12px","border-radius":"3px",cursor:"pointer",background:"rgba(94,94,94)",color:"#a1a1a1"},"#nexus-player-panel .table-row-child button:active":{opacity:"0.8"},"#nexus-player-panel .table-row-child button[active='1'][label='spectate']":{background:"#218c74",color:"#fafafa"},"#nexus-player-panel .table-row-child button[active='1'][label='editor']":{background:"#474787",color:"#fafafa"},"#nexus-player-panel .table-row-child button[active='1'][label='mouse']":{background:"#cd6133",color:"#fafafa"},"#nexus-player-panel .table-row-child button[active='1'][label='queue']":{background:"#6F1E51",color:"#fafafa"}}})]})]}),this.onCommandReceived=null,this.buttons=[],this.columns=[]}addColumnsToPanel(e){this.columns=e}addRowsToPanel(e,t,s,n){let o=this.panel.childrens[0].childrens[0];o.removeChildrens(),this.buttons=[];let a=document.createElement("div");a.className="table-row",this.columns.forEach(r=>{let h=document.createElement("span");h.className="table-row-child",h.textContent=r,a.appendChild(h)}),o.addChild(a),e.forEach((r,h)=>{let l=document.createElement("div");l.className="table-row",r.forEach((d,p)=>{let u=document.createElement("span");u.className="table-row-child";let m=d.indexOf(",")>-1,f=d.indexOf(":")>-1,g=[];m?(g=d.split(","),g.forEach((b,k)=>{let S=b.split(":");this.addChildToParent(S,u,t,s,n,h,p,k)})):f?(g=d.split(":"),this.addChildToParent(g,u,t,s,n,h,p,-1)):u.textContent=d,l.appendChild(u)}),o.addChild(l)})}addChildToParent(e,t,s,n,o,a,r,h){switch(e[0]){case"button":let l=document.createElement("button");if(e[1]=="none"&&(l.className="none"),this.buttons.includes(l)||this.buttons.push(l),l.textContent=e[1],s[a]&&s[a][r]&&n[a][r]&&o[a][r]){let d=n[a][r].split(","),p=o[a][r].split(",");h!=-1?(l.setAttribute("data",p[h]),l.setAttribute("active",d[h])):(l.setAttribute("data",o[a][r]),l.setAttribute("active",n[a][r])),l.setAttribute("kind",e[0]),l.setAttribute("label",e[1]),e[1]!="none"&&(l.onclick=s[a][r].bind(this))}t.appendChild(l);break}}disableButtons(e){this.buttons.forEach(t=>{let s=t.getAttribute("kind"),n=t.getAttribute("data"),o=parseInt(t.getAttribute("active")),a=t.getAttribute("label");a==e&&o==1&&(t.setAttribute("active",0),this.onCommandReceived&&this.onCommandReceived(s,a,n,0))})}onclick(e){let t=e.target.getAttribute("kind"),s=e.target.getAttribute("data"),n=e.target.getAttribute("label"),o=parseInt(e.target.getAttribute("active"));t=="button"&&(n=="spectate"&&this.disableButtons(n),o==0?e.target.setAttribute("active",1):o==1&&e.target.setAttribute("active",0)),o=parseInt(e.target.getAttribute("active")),this.onCommandReceived&&this.onCommandReceived(t,n,s,o)}};var P=class{constructor(){this.active=0,this.panel=new c({id:"nexus-workflow-panel",tag:"div",visible:!1,styles:{width:"100%",height:"100vh",display:"flex","align-items":"center","justify-content":"center","box-sizing":"border-box",position:"absolute",left:"0",top:"0","z-index":"10000"},childrens:[new c({id:"nexus-workflow-panel-table",tag:"div",visible:!0,styles:{width:"512px",display:"flex","flex-direction":"column","border-radius":"6px","box-sizing":"border-box"},childrens:[new c({id:"nexus-workflow-panel-table-body",tag:"div",visible:!0,styles:{width:"100%",display:"flex","flex-direction":"column","align-items":"center","justify-content":"flex-start",color:"#a3a3a3","font-family":"Calibri","font-weight":"600",gap:"12px","padding-bottom":"12px","box-sizing":"border-box",background:"rgba(54,54,54,0.8)","border-radius":"6px","box-shadow":"4px 8px 8px rgba(0,0,0,0.5)","max-height":"540px",overflowY:"auto"}}),new v({styles:{"#nexus-workflow-panel .table-row":{width:"100%",display:"flex","align-items":"center","justify-content":"center"},"#nexus-workflow-panel .table-row:first-child":{width:"100%",color:"#a3a3a3",padding:"16px 0",background:"rgb(0,0,0,0.6)","border-top-left-radius":"6px","border-top-right-radius":"6px",position:"sticky",top:"0"},"#nexus-workflow-panel .table-row .table-row-child":{display:"flex","justify-content":"flex-start",gap:"12px","padding-left":"12px",width:"100%"},"#nexus-workflow-panel .table-row-child button":{border:"none",padding:"6px 12px","border-radius":"3px",cursor:"pointer",background:"rgba(94,94,94)",color:"#a1a1a1",width:"100%"},"#nexus-workflow-panel .table-row-child:first-child":{width:"50%"},"#nexus-workflow-panel .table-row-child:last-child":{"padding-right":"12px"},"#nexus-workflow-panel .table-row-child button:active":{opacity:"0.8"},"#nexus-workflow-panel .table-row-child button[label='load']:active":{background:"#218c74",color:"#fafafa"},"#nexus-workflow-panel .table-row-child button[label='loadforall']:active":{background:"#474787",color:"#fafafa"}}})]})]}),this.onCommandReceived=null,this.buttons=[],this.columns=[]}addColumnsToPanel(e){this.columns=e}addRowsToPanel(e,t,s,n){let o=this.panel.childrens[0].childrens[0];o.removeChildrens(),this.buttons=[];let a=document.createElement("div");a.className="table-row",this.columns.forEach(r=>{let h=document.createElement("span");h.className="table-row-child",h.textContent=r,a.appendChild(h)}),o.addChild(a),e.forEach((r,h)=>{let l=document.createElement("div");l.className="table-row",r.forEach((d,p)=>{let u=document.createElement("span");u.className="table-row-child";let m=d.indexOf(",")>-1,f=d.indexOf(":")>-1,g=[];m?(g=d.split(","),g.forEach((b,k)=>{let S=b.split(":");this.addChildToParent(S,u,t,s,n,h,p,k)})):f?(g=d.split(":"),this.addChildToParent(g,u,t,s,n,h,p,-1)):(d=d.split("|"),d=d.join(":"),u.textContent=d),l.appendChild(u)}),o.addChild(l)})}addChildToParent(e,t,s,n,o,a,r,h){switch(e[0]){case"button":let l=document.createElement("button");if(e[1]=="none"&&(l.className="none"),this.buttons.includes(l)||this.buttons.push(l),l.textContent=e[1],s[a]&&s[a][r]&&n[a][r]&&o[a][r]){let d=n[a][r].split(","),p=o[a][r].split(",");h!=-1?(l.setAttribute("data",p[h]),l.setAttribute("active",d[h])):(l.setAttribute("data",o[a][r]),l.setAttribute("active",n[a][r])),l.setAttribute("kind",e[0]),l.setAttribute("label",e[1]),e[1]!="none"&&(l.onclick=s[a][r].bind(this))}t.appendChild(l);break}}onclick(e){let t=e.target.getAttribute("kind"),s=e.target.getAttribute("data"),n=e.target.getAttribute("label"),o=parseInt(e.target.getAttribute("active"));t=="button"&&(o==0?e.target.setAttribute("active",1):o==1&&e.target.setAttribute("active",0)),o=parseInt(e.target.getAttribute("active")),this.onCommandReceived&&this.onCommandReceived(t,n,s,o)}};var R=class{constructor(e,t,s,n,o,a,r){this.color=n,this.colors={join:"#ff6e4d",info:"#fba510",personal:"#fba510",name:"#00fa00",none:"#ffffff"},this.inputMain=_,this.nexusSocket=s,this.app=e,this.api=t,this.workflowManager=a,this.promptControl=r,this.mouseManger=o,this.nexusSocket.onConnected.push(this.handleConnect.bind(this)),this.nexusSocket.onMessageReceive.push(this.handleMessageReceive.bind(this)),this.inputMain.addEventListener("message",this.handleMessage.bind(this)),document.addEventListener("keydown",this.handleChatWindow.bind(this)),this.disableComfyThings=this.disableComfyThings.bind(this),this.enableComfyThings=this.enableComfyThings.bind(this),this.disableGraphSelectionWithExtremePrejudice=this.disableGraphSelectionWithExtremePrejudice.bind(this),this.comfyThings=["#extraOptions","#queue-button","#comfy-save-button","#comfy-file-input","#comfy-clear-button","#comfy-load-default-button",".queue-tab-button.side-bar-button",".queue-tab-button.side-bar-button","#comfy-refresh-button","#queue-front-button","#comfy-view-queue-button","#comfy-view-history-button"],C.childrens[3].softUpdate("#nexus-chat-window","pointer-events","none"),C.show(),setInterval(h=>{h.childrens[0].childrens[1].el.textContent=Object.keys(this.nexusSocket.userManager.users).length},1e3,C),this.up=new I,this.up.onCommandReceived=this.onPanelCommandReceived.bind(this),this.wp=new P,this.wp.onCommandReceived=this.onWFPanelCommandReceived.bind(this),this.spectating=null,this.lastkey=null}timeAgo(e){let t=new Date,s=new Date(e),n=Math.floor((t-s)/1e3),o=Math.floor(n/60),a=Math.floor(o/60),r=Math.floor(a/24);return o<1?"just now":o===1?"1 minute ago":o<60?`${o} minutes ago`:a===1?"1 hour ago":a<24?`${a} hours ago`:r===1?"1 day ago":`${r} days ago`}async verifyLogin(){this.disableComfyThings();let e=localStorage.getItem("nexus-socket-token");if(e){let t=await j(e);t&&this.nexusSocket.uuid==t.user_id?(this.enableComfyThings(),this.promptControl.handleControl(!0),this.promptControl.handleEditor(!0),this.workflowManager.handleWorkflowEvents(!0),this.nexusSocket.admin=!0,w("","You are now an admin!",this.color.info,this.colors.personal,!0),this.workflowManager.saveManager(60)):(this.promptControl.handleControl(!1),this.promptControl.handleEditor(!1),this.workflowManager.handleWorkflowEvents(!1),this.workflowManager.removeSaveManager(),w("","You are a viewer!",this.color.info,this.colors.info,!0))}else{let t=await O(this.nexusSocket.uuid);if(t){let s=t.editor?t.editor:!1,n=t.queue?t.queue:!1;this.workflowManager.handleWorkflowEvents(s),this.promptControl.handleEditor(s),this.promptControl.handleControl(n),this.nexusSocket.queue=n,this.nexusSocket.editor=s,s?this.workflowManager.saveManager(60):this.workflowManager.removeSaveManager(),w("",`Permission: Workflow Editor ${s?"Yes":"No"} | Queue Prompt ${n?"Yes":"No"} `,this.color.info,this.colors.personal,!0),n&&w("","You can now queue prompt press CTRL+Enter",this.color.info,this.colors.personal,!0)}}this.workflowManager.loadLatestWorkflow()}handleConnect(){let e=this.nexusSocket.userManager.get(this.nexusSocket.uuid,"name");this.nexusSocket.sendMessage("chat-join",{name:e},!1),this.verifyLogin()}findChildrenAfterHr(e){let t=document.querySelector(`.${e}`),s=[];if(t){let n=t.querySelector("hr");if(n){let o=n.nextElementSibling;for(;o;)s.push(o),o=o.nextElementSibling}}return s}disableGraphSelectionWithExtremePrejudice(){!this.nexusSocket.admin&&!this.nexusSocket.editor&&this.app.graph&&this.app.graph.list_of_graphcanvas&&this.app.graph.list_of_graphcanvas.length>0&&this.app.graph.list_of_graphcanvas[0].deselectAllNodes()}disableComfyThings(){this.comfyThings.forEach(t=>{document.querySelectorAll(t).forEach(n=>{n.disabled=!0,n.style.pointerEvents="none"})}),document.querySelectorAll(".comfy-settings-btn").forEach(t=>{t.disabled=!0,t.style.pointerEvents="none"}),this.findChildrenAfterHr("comfy-menu").forEach(t=>{(t.tagName==="BUTTON"||t.tagName==="INPUT"||t.tagName==="SELECT"||t.tagName==="TEXTAREA")&&(t.disabled=!0)}),document.querySelector(".comfy-menu").style.display="none",document.querySelector(".comfy-menu").style.pointerEvents="none",clearInterval(this.disableComfyThingsTimer),this.disableComfyThingsTimer=setInterval(()=>{this.comfyThings.forEach(s=>{document.querySelectorAll(s).forEach(o=>{o.disabled=!0,o.style.pointerEvents="none"})}),document.querySelectorAll(".comfy-settings-btn").forEach(s=>{s.disabled=!0,s.style.pointerEvents="none"}),this.findChildrenAfterHr("comfy-menu").forEach(s=>{(s.tagName==="BUTTON"||s.tagName==="INPUT"||s.tagName==="SELECT"||s.tagName==="TEXTAREA")&&(s.disabled=!0)}),document.querySelector(".comfy-menu").style.display="none",document.querySelector(".comfy-menu").style.pointerEvents="none",this.promptControl.handleEditor(this.nexusSocket.editor?this.nexusSocket.editor:!1),this.promptControl.handleControl(this.nexusSocket.queue?this.nexusSocket.queue:!1)},500),this.disableGraphSelectionWithExtremePrejudiceTimer=setInterval(this.disableGraphSelectionWithExtremePrejudice,50)}enableComfyThings(){clearInterval(this.disableComfyThingsTimer),clearInterval(this.disableGraphSelectionWithExtremePrejudiceTimer),this.comfyThings.forEach(t=>{document.querySelectorAll(t).forEach(n=>{n.disabled=!1,n.style.pointerEvents="all"})}),document.querySelectorAll(".comfy-settings-btn").forEach(t=>{t.disabled=!1,t.style.pointerEvents="all"}),this.findChildrenAfterHr("comfy-menu").forEach(t=>{(t.tagName==="BUTTON"||t.tagName==="INPUT"||t.tagName==="SELECT"||t.tagName==="TEXTAREA")&&(t.disabled=!1)}),document.querySelector(".comfy-menu").style.display="flex",document.querySelector(".comfy-menu").style.pointerEvents="all"}handleChatWindow(e){let t=e.key,s=_.childrens[0],n=_.childrens[1],o={tag:document.activeElement.tagName,el:document.activeElement,chat:document.activeElement==n.el};function a(){!["INPUT","TEXTAREA"].includes(o.tag)&&n.visible==!1&&(e.preventDefault(),s.show(),n.show(),n.el.focus(),n.el.value="",n.focusTimer=setInterval((d,p)=>{document.activeElement!=p&&d.visible==!0&&p.focus()},500,n,n.el),C.childrens[3].softUpdate("#nexus-chat-window","pointer-events","all"))}function r(){o.chat&&(s.hide(),n.el.blur(),n.el.value="",n.hide(),clearTimeout(n.focusTimer),C.childrens[3].softUpdate("#nexus-chat-window","pointer-events","none"))}function h(){if(!o.chat)return;let l=n.el.value;_.dispatchEvent(new CustomEvent("message",{detail:{message:l}})),r()}switch(t){case"t":case"T":a(),this.togglePlayerTab(!0),this.toggleWFTab(!0);break;case"Escape":r();break;case"Enter":h();break;case"p":case"P":e.altKey&&e.shiftKey&&(o.chat||this.togglePlayerTab());break;case"o":case"O":e.altKey&&e.shiftKey&&(o.chat||this.toggleWFTab());break}return o}toggleWFTab(e,t){(this.nexusSocket.admin||this.nexusSocket.editor)&&(e?(this.wp.active=0,this.wp.panel.hide()):t?this.prepareWFPanel():this.wp.active==0?(this.wp.active=1,this.wp.panel.show(),this.prepareWFPanel()):this.wp.active==1&&(this.wp.active=0,this.wp.panel.hide()),this.wp.active==1?this.workflowManager.removeSaveManager():this.workflowManager.saveManager(this.workflowManager.saveTime||60))}togglePlayerTab(e,t){e?(this.up.active=0,this.up.panel.hide()):t?this.preparePanel(this.nexusSocket.admin):this.up.active==0?(this.up.active=1,this.up.panel.show(),this.preparePanel(this.nexusSocket.admin)):this.up.active==1&&(this.up.active=0,this.up.panel.hide())}async onWFPanelCommandReceived(e,t,s,n){switch(e){case"button":if(t=="load"){let o=s,a=await F(this.nexusSocket.uuid,o);if(a){a.clear=!0;let r={name:"workflow",from:this.nexusSocket.uuid,data:{workflow:a}};this.nexusSocket.onMessageReceive.forEach(h=>{h(r)}),this.nexusSocket.admin&&this.nexusSocket.sendMessage("workflow",{workflow:a},!1)}}break}}async onPanelCommandReceived(e,t,s,n){switch(e){case"button":if(t=="spectate")this.nexusSocket.sendMessage("spectate",{on:n,receiver:s},!1),n==1?this.spectating=s:this.spectating=null;else if(t=="editor"){if(this.nexusSocket.admin){let o=localStorage.getItem("nexus-socket-token");await A(s,this.nexusSocket.uuid,{editor:!!n},o),this.nexusSocket.sendMessage("permission",{receiver:s},!1)}}else if(t=="queue"){if(this.nexusSocket.admin){let o=localStorage.getItem("nexus-socket-token");await A(s,this.nexusSocket.uuid,{queue:!!n},o),this.nexusSocket.sendMessage("permission",{receiver:s},!1)}}else t=="mouse"&&(this.nexusSocket.sendMessage("mouse_view_toggle",{on:n,receiver:s},!1),this.nexusSocket.userManager.set(s,"hide_mouse",n));break}}async prepareWFPanel(){let e=["Name","Created","Action"];this.wp.addColumnsToPanel(e);let t=await U(this.nexusSocket.uuid),s=[],n=[],o=[],a=[];for(let r=0;r]+(>|$)/g;e=e.replace(a,"");for(let r of e)n.test(r)&&!o.test(r)||(s+=r);return s}}startsWithCommand(e){return/^\/\w+(\s+\S+)?/.test(e)}extractCommandAndValue(e){let t=/^\/(\w+)\s*(.*)/,s=e.match(t);if(s){let n=s[1],o=s[2].trim()?s[2].split(/\s+/):[];return{command:n,values:o}}else return null}};var J=window.comfyAPI.app.app,W=window.comfyAPI.api.api,E=new N,Y={name:"ComfyUI-Nexus",async setup(i){i=i;let e=new T(E,i,24),t=new L(i,W,E),s=new G(W,i,E);new R(i,W,E,e.color,e,t,s),E.connect()},async beforeConfigureGraph(){}};J.registerExtension(Y);})();