force to use classes

This commit is contained in:
tamat
2014-04-16 20:25:37 +02:00
parent c9c11e6c46
commit a65f736e6d
11 changed files with 4381 additions and 1849 deletions

File diff suppressed because it is too large Load Diff

209
build/litegraph.min.js vendored
View File

@@ -1,32 +1,35 @@
var LiteGraph={NODE_TITLE_HEIGHT:16,NODE_SLOT_HEIGHT:15,NODE_WIDTH:140,NODE_MIN_WIDTH:50,NODE_COLLAPSED_RADIUS:10,NODE_COLLAPSED_WIDTH:80,CANVAS_GRID_SIZE:10,NODE_DEFAULT_COLOR:"#999",NODE_DEFAULT_BGCOLOR:"#444",NODE_DEFAULT_BOXCOLOR:"#AEF",NODE_DEFAULT_SHAPE:"box",MAX_NUMBER_OF_NODES:1E3,DEFAULT_POSITION:[100,100],node_images_path:"",debug:!1,registered_node_types:{},registerNodeType:function(a,b){b.type=a;LiteGraph.debug&&console.log("Node registered: "+a);a.split("/");var c=a.lastIndexOf("/");
b.category=a.substr(0,c);if(b.prototype)for(var d in LGraphNode.prototype)b.prototype[d]||(b.prototype[d]=LGraphNode.prototype[d]);this.registered_node_types[a]=b},createNode:function(a,b,c){var d=this.registered_node_types[a];if(!d)return LiteGraph.debug&&console.log('GraphNode type "'+a+'" not registered.'),null;var e=d.prototype||d;b=b||e.title||d.title||a;var f=null;if(d.prototype)f=new d(b);else{f=new LGraphNode(b);f.inputs=[];f.outputs=[];for(var g in e)if("inputs"==g)for(var h in e[g])f.addInput(e[g][h][0],
e[g][h][1],e[g][h][2]);else if("outputs"==g)for(h in e[g])f.addOutput(e[g][h][0],e[g][h][1],e[g][h][2]);else f[g]=e[g].concat?e[g].concat():"object"==typeof e[g]?LiteGraph.cloneObject(e[g]):e[g];d.size&&(f.size=d.size.concat())}f.type=a;f.name||(f.name=b);f.flags||(f.flags={});f.size||(f.size=f.computeSize());f.pos||(f.pos=LiteGraph.DEFAULT_POSITION.concat());if(c)for(g in c)f[g]=c[g];return f},getNodeType:function(a){return this.registered_node_types[a]},getNodeTypesInCategory:function(a){var b=
[],c;for(c in this.registered_node_types)""==a?null==this.registered_node_types[c].category&&b.push(this.registered_node_types[c]):this.registered_node_types[c].category==a&&b.push(this.registered_node_types[c]);return b},getNodeTypesCategories:function(){var a={"":1},b;for(b in this.registered_node_types)this.registered_node_types[b].category&&!this.registered_node_types[b].skip_list&&(a[this.registered_node_types[b].category]=1);var c=[];for(b in a)c.push(b);return c},reloadNodes:function(a){var b=
document.getElementsByTagName("script"),c=[],d;for(d in b)c.push(b[d]);b=document.getElementsByTagName("head")[0];a=document.location.href+a;for(d in c){var e=c[d].src;if(e&&e.substr(0,a.length)==a)try{LiteGraph.debug&&console.log("Reloading: "+e);var f=document.createElement("script");f.type="text/javascript";f.src=e;b.appendChild(f);b.removeChild(c[d])}catch(g){if(LiteGraph.throw_errors)throw g;LiteGraph.debug&&console.log("Error while reloading "+e)}}LiteGraph.debug&&console.log("Nodes reloaded")},
cloneObject:function(a,b){var c=JSON.parse(JSON.stringify(a));if(!b)return c;for(var d in c)b[d]=c[d];return b}};function LGraph(){LiteGraph.debug&&console.log("Graph created");this.list_of_graphcanvas=null;this.clear()}LGraph.STATUS_STOPPED=1;LGraph.STATUS_RUNNING=2;
LGraph.prototype.clear=function(){this.stop();this.status=LGraph.STATUS_STOPPED;this.last_node_id=0;this._nodes=[];this._nodes_by_id={};this.last_link_id=0;this.links={};this.iteration=0;this.config={};this.fixedtime=this.runningtime=this.globaltime=0;this.elapsed_time=this.fixedtime_lapse=0.01;this.starttime=0;this.globals={};this.graph={};this.debug=!0;this.change();this.sendActionToCanvas("clear")};
var LiteGraph={NODE_TITLE_HEIGHT:16,NODE_SLOT_HEIGHT:15,NODE_WIDTH:140,NODE_MIN_WIDTH:50,NODE_COLLAPSED_RADIUS:10,NODE_COLLAPSED_WIDTH:80,CANVAS_GRID_SIZE:10,NODE_DEFAULT_COLOR:"#999",NODE_DEFAULT_BGCOLOR:"#444",NODE_DEFAULT_BOXCOLOR:"#AEF",NODE_DEFAULT_SHAPE:"box",MAX_NUMBER_OF_NODES:1E3,DEFAULT_POSITION:[100,100],node_images_path:"",debug:!1,throw_errors:!0,registered_node_types:{},registerNodeType:function(a,b){if(!b.prototype)throw"Cannot register a simple object, it must be a class with a prototype";
b.type=a;LiteGraph.debug&&console.log("Node registered: "+a);a.split("/");var c=a.lastIndexOf("/");b.category=a.substr(0,c);if(b.prototype)for(var d in LGraphNode.prototype)b.prototype[d]||(b.prototype[d]=LGraphNode.prototype[d]);this.registered_node_types[a]=b},createNode:function(a,b,c){var d=this.registered_node_types[a];if(!d)return LiteGraph.debug&&console.log('GraphNode type "'+a+'" not registered.'),null;b=b||d.title||a;d=new d(name);d.type=a;d.title||(d.title=b);d.flags||(d.flags={});d.size||
(d.size=d.computeSize());d.pos||(d.pos=LiteGraph.DEFAULT_POSITION.concat());if(c)for(var e in c)d[e]=c[e];return d},getNodeType:function(a){return this.registered_node_types[a]},getNodeTypesInCategory:function(a){var b=[],c;for(c in this.registered_node_types)""==a?null==this.registered_node_types[c].category&&b.push(this.registered_node_types[c]):this.registered_node_types[c].category==a&&b.push(this.registered_node_types[c]);return b},getNodeTypesCategories:function(){var a={"":1},b;for(b in this.registered_node_types)this.registered_node_types[b].category&&
!this.registered_node_types[b].skip_list&&(a[this.registered_node_types[b].category]=1);var c=[];for(b in a)c.push(b);return c},reloadNodes:function(a){var b=document.getElementsByTagName("script"),c=[],d;for(d in b)c.push(b[d]);b=document.getElementsByTagName("head")[0];a=document.location.href+a;for(d in c){var e=c[d].src;if(e&&e.substr(0,a.length)==a)try{LiteGraph.debug&&console.log("Reloading: "+e);var f=document.createElement("script");f.type="text/javascript";f.src=e;b.appendChild(f);b.removeChild(c[d])}catch(g){if(LiteGraph.throw_errors)throw g;
LiteGraph.debug&&console.log("Error while reloading "+e)}}LiteGraph.debug&&console.log("Nodes reloaded")},cloneObject:function(a,b){if(null==a)return null;var c=JSON.parse(JSON.stringify(a));if(!b)return c;for(var d in c)b[d]=c[d];return b}};function LGraph(){LiteGraph.debug&&console.log("Graph created");this.list_of_graphcanvas=null;this.clear()}LGraph.supported_types=["number","string","boolean"];LGraph.prototype.getSupportedTypes=function(){return this.supported_types||LGraph.supported_types};
LGraph.STATUS_STOPPED=1;LGraph.STATUS_RUNNING=2;LGraph.prototype.clear=function(){this.stop();this.status=LGraph.STATUS_STOPPED;this.last_node_id=0;this._nodes=[];this._nodes_by_id={};this.last_link_id=0;this.links={};this.iteration=0;this.config={};this.fixedtime=this.runningtime=this.globaltime=0;this.elapsed_time=this.fixedtime_lapse=0.01;this.starttime=0;this.global_inputs={};this.global_outputs={};this.graph={};this.debug=!0;this.change();this.sendActionToCanvas("clear")};
LGraph.prototype.attachCanvas=function(a){if(a.constructor!=LGraphCanvas)throw"attachCanvas expects a LGraphCanvas instance";a.graph&&a.graph!=this&&a.graph.detachCanvas(a);a.graph=this;this.list_of_graphcanvas||(this.list_of_graphcanvas=[]);this.list_of_graphcanvas.push(a)};LGraph.prototype.detachCanvas=function(a){var b=this.list_of_graphcanvas.indexOf(a);-1!=b&&(a.graph=null,this.list_of_graphcanvas.splice(b,1))};
LGraph.prototype.start=function(a){if(this.status!=LGraph.STATUS_RUNNING){this.status=LGraph.STATUS_RUNNING;if(this.onPlayEvent)this.onPlayEvent();this.sendEventToAllNodes("onStart");this.starttime=window.performance.now();var b=this;this.execution_timer_id=setInterval(function(){b.runStep(1)},a||1)}};
LGraph.prototype.stop=function(){if(this.status!=LGraph.STATUS_STOPPED){this.status=LGraph.STATUS_STOPPED;if(this.onStopEvent)this.onStopEvent();null!=this.execution_timer_id&&clearInterval(this.execution_timer_id);this.execution_timer_id=null;this.sendEventToAllNodes("onStop")}};
LGraph.prototype.runStep=function(a){a=a||1;var b=window.performance.now();this.globaltime=0.001*(b-this.starttime);try{for(var c=0;c<a;c++)if(this.sendEventToAllNodes("onExecute"),this.fixedtime+=this.fixedtime_lapse,this.onExecuteStep)this.onExecuteStep();if(this.onAfterExecute)this.onAfterExecute();this.errors_in_execution=!1}catch(d){this.errors_in_execution=!0;if(LiteGraph.throw_errors)throw d;LiteGraph.debug&&console.log("Error during execution: "+d);this.stop()}a=window.performance.now()-b;
0==a&&(a=1);this.elapsed_time=0.001*a;this.globaltime+=0.001*a;this.iteration+=1};LGraph.prototype.updateExecutionOrder=function(){this._nodes_in_order=this.computeExecutionOrder()};
LGraph.prototype.computeExecutionOrder=function(){var a=[],b=[],c={},d={},e={},f;for(f in this._nodes){var g=this._nodes[f];c[g.id]=g;var h=0;if(g.inputs)for(var k=0,l=g.inputs.length;k<l;k++)g.inputs[k]&&null!=g.inputs[k].link&&(h+=1);0==h?b.push(g):e[g.id]=h}for(;0!=b.length;)if(g=b.shift(),a.push(g),delete c[g.id],g.outputs)for(f=0;f<g.outputs.length;f++)if(h=g.outputs[f],null!=h&&null!=h.links&&0!=h.links.length)for(k=0;k<h.links.length;k++)if(l=h.links[k],!d[l[0]]){var n=this.getNodeById(l[3]);
null==n?d[l[0]]=!0:(d[l[0]]=!0,e[n.id]-=1,0==e[n.id]&&b.push(n))}for(f in c)a.push(c[f]);a.length!=this._nodes.length&&LiteGraph.debug&&console.log("something went wrong, nodes missing");for(f in a)a[f].order=f;return a};LGraph.prototype.getTime=function(){return this.globaltime};LGraph.prototype.getFixedTime=function(){return this.fixedtime};LGraph.prototype.getElapsedTime=function(){return this.elapsed_time};
LGraph.prototype.computeExecutionOrder=function(){var a=[],b=[],c={},d={},e={},f;for(f in this._nodes){var g=this._nodes[f];c[g.id]=g;var h=0;if(g.inputs)for(var l=0,k=g.inputs.length;l<k;l++)g.inputs[l]&&null!=g.inputs[l].link&&(h+=1);0==h?b.push(g):e[g.id]=h}for(;0!=b.length;)if(g=b.shift(),a.push(g),delete c[g.id],g.outputs)for(f=0;f<g.outputs.length;f++)if(h=g.outputs[f],null!=h&&null!=h.links&&0!=h.links.length)for(l=0;l<h.links.length;l++)if(k=h.links[l],!d[k[0]]){var n=this.getNodeById(k[3]);
null==n?d[k[0]]=!0:(d[k[0]]=!0,e[n.id]-=1,0==e[n.id]&&b.push(n))}for(f in c)a.push(c[f]);a.length!=this._nodes.length&&LiteGraph.debug&&console.log("something went wrong, nodes missing");for(f in a)a[f].order=f;return a};LGraph.prototype.getTime=function(){return this.globaltime};LGraph.prototype.getFixedTime=function(){return this.fixedtime};LGraph.prototype.getElapsedTime=function(){return this.elapsed_time};
LGraph.prototype.sendEventToAllNodes=function(a,b){var c=this._nodes_in_order?this._nodes_in_order:this._nodes,d;for(d in c)if(c[d][a])c[d][a](b)};LGraph.prototype.sendActionToCanvas=function(a,b){if(this.list_of_graphcanvas)for(var c in this.list_of_graphcanvas){var d=this.list_of_graphcanvas[c];d[a]&&d[a].apply(d,b)}};
LGraph.prototype.add=function(a){if(a&&(-1==a.id||null==this._nodes_by_id[a.id])){if(this._nodes.length>=LiteGraph.MAX_NUMBER_OF_NODES)throw"LiteGraph: max number of nodes in a graph reached";if(null==a.id||-1==a.id)a.id=this.last_node_id++;a.graph=this;this._nodes.push(a);this._nodes_by_id[a.id]=a;if(a.onInit)a.onInit();this.config.align_to_grid&&a.alignToGrid();this.updateExecutionOrder();this.canvas&&(this.canvas.dirty_canvas=!0);this.change();return a}};
LGraph.prototype.remove=function(a){if(null!=this._nodes_by_id[a.id]&&!a.ignore_remove){if(a.inputs)for(var b=0;b<a.inputs.length;b++){var c=a.inputs[b];null!=c.link&&a.disconnectInput(b)}if(a.outputs)for(b=0;b<a.outputs.length;b++)c=a.outputs[b],null!=c.links&&c.links.length&&a.disconnectOutput(b);a.id=-1;if(a.onDelete)a.onDelete();this.canvas&&(this.canvas.selected_nodes[a.id]&&delete this.canvas.selected_nodes[a.id],this.canvas.node_dragged==a&&(this.canvas.node_dragged=null));b=this._nodes.indexOf(a);
-1!=b&&this._nodes.splice(b,1);delete this._nodes_by_id[a.id];this.canvas&&this.canvas.setDirty(!0,!0);this.change();this.updateExecutionOrder()}};LGraph.prototype.getNodeById=function(a){return null==a?null:this._nodes_by_id[a]};LGraph.prototype.findNodesByType=function(a){var b=[],c;for(c in this._nodes)this._nodes[c].type==a&&b.push(this._nodes[c]);return b};LGraph.prototype.findNodesByName=function(a){var b=[],c;for(c in this._nodes)this._nodes[c].name==a&&b.push(this._nodes[c]);return b};
LGraph.prototype.getNodeOnPos=function(a,b,c){c=c||this._nodes;for(var d=c.length-1;0<=d;d--){var e=c[d];if(e.isPointInsideNode(a,b))return e}return null};LGraph.prototype.setInputData=function(a,b){var c=this.findNodesByName(a),d;for(d in c)c[d].setValue(b)};LGraph.prototype.getOutputData=function(a){return this.findNodesByName(a).length?m[0].getValue():null};LGraph.prototype.triggerInput=function(a,b){var c=this.findNodesByName(a),d;for(d in c)c[d].onTrigger(b)};
LGraph.prototype.setCallback=function(a,b){var c=this.findNodesByName(a),d;for(d in c)c[d].setTrigger(b)};LGraph.prototype.onConnectionChange=function(){this.updateExecutionOrder()};LGraph.prototype.isLive=function(){return this.canvas?this.canvas.live_mode:!1};LGraph.prototype.change=function(){LiteGraph.debug&&console.log("Graph changed");this.sendActionToCanvas("setDirty",[!0,!0]);if(this.on_change)this.on_change(this)};
LGraph.prototype.add=function(a){if(a&&(-1==a.id||null==this._nodes_by_id[a.id])){if(this._nodes.length>=LiteGraph.MAX_NUMBER_OF_NODES)throw"LiteGraph: max number of nodes in a graph reached";if(null==a.id||-1==a.id)a.id=this.last_node_id++;a.graph=this;this._nodes.push(a);this._nodes_by_id[a.id]=a;if(a.onAdded)a.onAdded();this.config.align_to_grid&&a.alignToGrid();this.updateExecutionOrder();if(this.onNodeAdded)this.onNodeAdded(a);this.setDirtyCanvas(!0);this.change();return a}};
LGraph.prototype.remove=function(a){if(null!=this._nodes_by_id[a.id]&&!a.ignore_remove){if(a.inputs)for(var b=0;b<a.inputs.length;b++){var c=a.inputs[b];null!=c.link&&a.disconnectInput(b)}if(a.outputs)for(b=0;b<a.outputs.length;b++)c=a.outputs[b],null!=c.links&&c.links.length&&a.disconnectOutput(b);a.id=-1;if(a.onRemoved)a.onRemoved();a.graph=null;for(b in this.list_of_graphcanvas)c=this.list_of_graphcanvas[b],c.selected_nodes[a.id]&&delete c.selected_nodes[a.id],c.node_dragged==a&&(c.node_dragged=
null);b=this._nodes.indexOf(a);-1!=b&&this._nodes.splice(b,1);delete this._nodes_by_id[a.id];if(this.onNodeRemoved)this.onNodeRemoved(a);this.setDirtyCanvas(!0,!0);this.change();this.updateExecutionOrder()}};LGraph.prototype.getNodeById=function(a){return null==a?null:this._nodes_by_id[a]};LGraph.prototype.findNodesByType=function(a){var b=[],c;for(c in this._nodes)this._nodes[c].type==a&&b.push(this._nodes[c]);return b};
LGraph.prototype.findNodesByTitle=function(a){var b=[],c;for(c in this._nodes)this._nodes[c].title==a&&b.push(this._nodes[c]);return b};LGraph.prototype.getNodeOnPos=function(a,b,c){c=c||this._nodes;for(var d=c.length-1;0<=d;d--){var e=c[d];if(e.isPointInsideNode(a,b))return e}return null};LGraph.prototype.addGlobalInput=function(a,b,c){this.global_inputs[a]={type:b,value:c}};LGraph.prototype.setGlobalInputData=function(a,b){var c=this.global_inputs[a];c&&(c.value=b)};
LGraph.prototype.renameGlobalInput=function(a,b,c){};LGraph.prototype.addGlobalOutput=function(a,b,c){this.global_outputs[a]={type:b,value:c}};LGraph.prototype.setGlobalOutputData=function(a,b){var c=this.global_outputs[a];c&&(c.value=b)};LGraph.prototype.renameGlobalOutput=function(a,b,c){};LGraph.prototype.setInputData=function(a,b){var c=this.findNodesByName(a),d;for(d in c)c[d].setValue(b)};LGraph.prototype.getOutputData=function(a){return this.findNodesByName(a).length?m[0].getValue():null};
LGraph.prototype.triggerInput=function(a,b){var c=this.findNodesByName(a),d;for(d in c)c[d].onTrigger(b)};LGraph.prototype.setCallback=function(a,b){var c=this.findNodesByName(a),d;for(d in c)c[d].setTrigger(b)};LGraph.prototype.onConnectionChange=function(){this.updateExecutionOrder()};LGraph.prototype.isLive=function(){for(var a in this.list_of_graphcanvas)if(this.list_of_graphcanvas[a].live_mode)return!0;return!1};
LGraph.prototype.change=function(){LiteGraph.debug&&console.log("Graph changed");this.sendActionToCanvas("setDirty",[!0,!0]);if(this.on_change)this.on_change(this)};LGraph.prototype.setDirtyCanvas=function(a,b){this.sendActionToCanvas("setDirty",[a,b])};
LGraph.prototype.serialize=function(){var a=[],b;for(b in this._nodes)a.push(this._nodes[b].serialize());return{graph:this.graph,iteration:this.iteration,frame:this.frame,last_node_id:this.last_node_id,last_link_id:this.last_link_id,config:this.config,nodes:a}};
LGraph.prototype.configure=function(a,b){b||this.clear();var c=a.nodes,d;for(d in a)this[d]=a[d];var e=!1;this._nodes=[];for(d in c){var f=c[d],g=LiteGraph.createNode(f.type,f.name);g?(g.configure(f),this.add(g)):(LiteGraph.debug&&console.log("Node not found: "+f.type),e=!0)}this.canvas&&this.canvas.draw(!0,!0);return e};LGraph.prototype.onNodeTrace=function(a,b,c){if(this.canvas)this.canvas.onNodeTrace(a,b,c)};
function LGraphNode(a){this.name=a||"Unnamed";this.size=[LiteGraph.NODE_WIDTH,60];this.graph=null;this.pos=[10,10];this.id=-1;this.type=null;this.inputs=[];this.outputs=[];this.connections=[];this.data=null;this.flags={}}LGraphNode.prototype.configure=function(a){for(var b in a)"console"!=b&&null!=a[b]&&(this[b]=a[b].concat?a[b].concat():"object"==typeof a[b]?LiteGraph.cloneObject(a[b],this[b]||{}):a[b])};
LGraph.prototype.configure=function(a,b){b||this.clear();var c=a.nodes,d;for(d in a)this[d]=a[d];var e=!1;this._nodes=[];for(d in c){var f=c[d],g=LiteGraph.createNode(f.type,f.title);g?(g.configure(f),this.add(g)):(LiteGraph.debug&&console.log("Node not found: "+f.type),e=!0)}this.setDirtyCanvas(!0,!0);return e};LGraph.prototype.onNodeTrace=function(a,b,c){};
function LGraphNode(a){this.title=a||"Unnamed";this.size=[LiteGraph.NODE_WIDTH,60];this.graph=null;this.pos=[10,10];this.id=-1;this.type=null;this.inputs=[];this.outputs=[];this.connections=[];this.data=null;this.flags={}}LGraphNode.prototype.configure=function(a){for(var b in a)"console"!=b&&null!=a[b]&&(this[b]=a[b].concat?a[b].concat():"object"==typeof a[b]?LiteGraph.cloneObject(a[b],this[b]||{}):a[b])};
LGraphNode.prototype.copyFromObject=function(a,b){for(var c in a)(!b||"outputs"!=c&&"inputs"!=c)&&"console"!=c&&null!=a[c]&&(this[c]=a[c].concat?a[c].concat():"object"==typeof a[c]?LiteGraph.cloneObject(a[c]):a[c])};
LGraphNode.prototype.serialize=function(){var a={id:this.id,name:this.name,type:this.type,pos:this.pos,size:this.size,data:this.data,properties:LiteGraph.cloneObject(this.properties),flags:LiteGraph.cloneObject(this.flags),inputs:this.inputs,outputs:this.outputs};a.type||(a.type=this.constructor.type);this.color&&(a.color=this.color);this.bgcolor&&(a.bgcolor=this.bgcolor);this.boxcolor&&(a.boxcolor=this.boxcolor);this.shape&&(a.shape=this.shape);if(this.onSerialize)this.onSerialize(a);return a};
LGraphNode.prototype.toString=function(){return JSON.stringify(this.serialize())};LGraphNode.prototype.setOutputData=function(a,b){if(this.outputs&&-1<a&&a<this.outputs.length&&this.outputs[a]&&null!=this.outputs[a].links)for(var c=0;c<this.outputs[a].links.length;c++)this.graph.links[this.outputs[a].links[c][0]]=b};LGraphNode.prototype.getInputData=function(a){return this.inputs?a<this.inputs.length&&null!=this.inputs[a].link?this.graph.links[this.inputs[a].link[0]]:null:null};
LGraphNode.prototype.isInputConnected=function(a){return this.inputs?a<this.inputs.length&&null!=this.inputs[a].link:null};LGraphNode.prototype.getInputInfo=function(a){return this.inputs?a<this.inputs.length?this.inputs[a]:null:null};LGraphNode.prototype.getOutputInfo=function(a){return this.outputs?a<this.outputs.length?this.outputs[a]:null:null};LGraphNode.prototype.isOutputConnected=function(a){return this.outputs?a<this.outputs.length&&this.outputs[a].links&&this.outputs[a].links.length:null};
LGraphNode.prototype.getOutputNodes=function(a){if(!this.outputs||0==this.outputs.length)return null;if(a<this.outputs.length){a=this.outputs[a];for(var b=[],c=0;c<a.length;c++)b.push(this.graph.getNodeById(a.links[c][3]));return b}return null};LGraphNode.prototype.triggerOutput=function(a,b){var c=this.getOutputNode(a);if(c&&c.onTrigger)c.onTrigger(b)};
LGraphNode.prototype.addOutput=function(a,b,c){a={name:a,type:b,links:null};if(c)for(var d in c)a[d]=c[d];this.outputs||(this.outputs=[]);this.outputs.push(a);this.size=this.computeSize()};LGraphNode.prototype.removeOutput=function(a){this.disconnectOutput(a);this.outputs.splice(a,1);this.size=this.computeSize()};LGraphNode.prototype.addInput=function(a,b,c){a={name:a,type:b,link:null};if(c)for(var d in c)a[d]=c[d];this.inputs||(this.inputs=[]);this.inputs.push(a);this.size=this.computeSize()};
LGraphNode.prototype.serialize=function(){var a={id:this.id,title:this.title,type:this.type,pos:this.pos,size:this.size,data:this.data,flags:LiteGraph.cloneObject(this.flags),inputs:this.inputs,outputs:this.outputs};this.properties&&(a.properties=LiteGraph.cloneObject(this.properties));a.type||(a.type=this.constructor.type);this.color&&(a.color=this.color);this.bgcolor&&(a.bgcolor=this.bgcolor);this.boxcolor&&(a.boxcolor=this.boxcolor);this.shape&&(a.shape=this.shape);if(this.onSerialize)this.onSerialize(a);
return a};LGraphNode.prototype.toString=function(){return JSON.stringify(this.serialize())};LGraphNode.prototype.getTitle=function(){return this.title||this.constructor.title};LGraphNode.prototype.setOutputData=function(a,b){if(this.outputs&&-1<a&&a<this.outputs.length&&this.outputs[a]&&null!=this.outputs[a].links)for(var c=0;c<this.outputs[a].links.length;c++)this.graph.links[this.outputs[a].links[c][0]]=b};
LGraphNode.prototype.getInputData=function(a){return this.inputs?a<this.inputs.length&&null!=this.inputs[a].link?this.graph.links[this.inputs[a].link[0]]:null:null};LGraphNode.prototype.isInputConnected=function(a){return this.inputs?a<this.inputs.length&&null!=this.inputs[a].link:null};LGraphNode.prototype.getInputInfo=function(a){return this.inputs?a<this.inputs.length?this.inputs[a]:null:null};
LGraphNode.prototype.getOutputInfo=function(a){return this.outputs?a<this.outputs.length?this.outputs[a]:null:null};LGraphNode.prototype.isOutputConnected=function(a){return this.outputs?a<this.outputs.length&&this.outputs[a].links&&this.outputs[a].links.length:null};LGraphNode.prototype.getOutputNodes=function(a){if(!this.outputs||0==this.outputs.length)return null;if(a<this.outputs.length){a=this.outputs[a];for(var b=[],c=0;c<a.length;c++)b.push(this.graph.getNodeById(a.links[c][3]));return b}return null};
LGraphNode.prototype.triggerOutput=function(a,b){var c=this.getOutputNode(a);if(c&&c.onTrigger)c.onTrigger(b)};LGraphNode.prototype.addOutput=function(a,b,c){a={name:a,type:b,links:null};if(c)for(var d in c)a[d]=c[d];this.outputs||(this.outputs=[]);this.outputs.push(a);this.size=this.computeSize()};
LGraphNode.prototype.addOutputs=function(a){for(var b in a){var c=a[b],d={name:c[0],type:c[1],link:null};if(a[2])for(var e in c[2])d[e]=c[2][e];this.outputs||(this.outputs=[]);this.outputs.push(d)}this.size=this.computeSize()};LGraphNode.prototype.removeOutput=function(a){this.disconnectOutput(a);this.outputs.splice(a,1);this.size=this.computeSize()};
LGraphNode.prototype.addInput=function(a,b,c){a={name:a,type:b,link:null};if(c)for(var d in c)a[d]=c[d];this.inputs||(this.inputs=[]);this.inputs.push(a);this.size=this.computeSize()};LGraphNode.prototype.addInputs=function(a){for(var b in a){var c=a[b],d={name:c[0],type:c[1],link:null};if(a[2])for(var e in c[2])d[e]=c[2][e];this.inputs||(this.inputs=[]);this.inputs.push(d)}this.size=this.computeSize()};
LGraphNode.prototype.removeInput=function(a){this.disconnectInput(a);this.inputs.splice(a,1);this.size=this.computeSize()};LGraphNode.prototype.addConnection=function(a,b,c,d){this.connections.push({name:a,type:b,pos:c,direction:d,links:null})};
LGraphNode.prototype.computeSize=function(a){a=Math.max(this.inputs?this.inputs.length:1,this.outputs?this.outputs.length:1);var b=[0,0];b[1]=14*a+6;b[0]=this.inputs&&0!=this.inputs.length&&this.outputs&&0!=this.outputs.length?LiteGraph.NODE_WIDTH:0.5*LiteGraph.NODE_WIDTH;return b};LGraphNode.prototype.getBounding=function(){return new Float32Array([this.pos[0]-4,this.pos[1]-LiteGraph.NODE_TITLE_HEIGHT,this.pos[0]+this.size[0]+4,this.pos[1]+this.size[1]+LGraph.NODE_TITLE_HEIGHT])};
LGraphNode.prototype.isPointInsideNode=function(a,b){var c=this.graph.isLive()?0:20;if(this.flags.collapsed){if(isInsideRectangle(a,b,this.pos[0],this.pos[1]-LiteGraph.NODE_TITLE_HEIGHT,LiteGraph.NODE_COLLAPSED_WIDTH,LiteGraph.NODE_TITLE_HEIGHT))return!0}else if(this.pos[0]-4<a&&this.pos[0]+this.size[0]+4>a&&this.pos[1]-c<b&&this.pos[1]+this.size[1]>b)return!0;return!1};
@@ -42,7 +45,7 @@ a?[this.pos[0],this.pos[1]+10+b*LiteGraph.NODE_SLOT_HEIGHT]:[this.pos[0]+this.si
LGraphNode.prototype.clone=function(){var a=LiteGraph.createNode(this.type);a.size=this.size.concat();if(this.inputs)for(var b=0,c=this.inputs.length;b<c;++b)-1==a.findInputSlot(this.inputs[b].name)&&a.addInput(this.inputs[b].name,this.inputs[b].type);if(this.outputs)for(b=0,c=this.outputs.length;b<c;++b)-1==a.findOutputSlot(this.outputs[b].name)&&a.addOutput(this.outputs[b].name,this.outputs[b].type);return a};
LGraphNode.prototype.trace=function(a){this.console||(this.console=[]);this.console.push(a);this.console.length>LGraphNode.MAX_CONSOLE&&this.console.shift();this.graph.onNodeTrace(this,a)};LGraphNode.prototype.setDirtyCanvas=function(a,b){this.graph&&this.graph.sendActionToCanvas("setDirty",[a,b])};LGraphNode.prototype.loadImage=function(a){var b=new Image;b.src=LiteGraph.node_images_path+a;b.ready=!1;var c=this;b.onload=function(){this.ready=!0;c.setDirtyCanvas(!0)};return b};
LGraphNode.prototype.executeAction=function(a){if(""==a)return!1;if(-1!=a.indexOf(";")||-1!=a.indexOf("}"))return this.trace("Error: Action contains unsafe characters"),!1;var b=a.split("(")[0];if("function"!=typeof this[b])return this.trace("Error: Action not found on node: "+b),!1;try{b=eval,eval=null,(new Function("with(this) { "+a+"}")).call(this),eval=b}catch(c){return this.trace("Error executing action {"+a+"} :"+c),!1}return!0};
LGraphNode.prototype.captureInput=function(a){if(this.graph&&this.graph.list_of_graphcanvas){var b=this.graph.list_of_graphcanvas,c;for(c in b){var d=b[c];if(a||d.node_capturing_input==this)d.node_capturing_input=a?this:null,this.graph.debug&&console.log(this.name+": Capturing input "+(a?"ON":"OFF"))}}};LGraphNode.prototype.collapse=function(){this.flags.collapsed=this.flags.collapsed?!1:!0;this.setDirtyCanvas(!0,!0)};
LGraphNode.prototype.captureInput=function(a){if(this.graph&&this.graph.list_of_graphcanvas){var b=this.graph.list_of_graphcanvas,c;for(c in b){var d=b[c];if(a||d.node_capturing_input==this)d.node_capturing_input=a?this:null,this.graph.debug&&console.log(this.title+": Capturing input "+(a?"ON":"OFF"))}}};LGraphNode.prototype.collapse=function(){this.flags.collapsed=this.flags.collapsed?!1:!0;this.setDirtyCanvas(!0,!0)};
LGraphNode.prototype.pin=function(a){this.flags.pinned=void 0===a?!this.flags.pinned:a};LGraphNode.prototype.localToScreen=function(a,b,c){return[(a+this.pos[0])*c.scale+c.offset[0],(b+this.pos[1])*c.scale+c.offset[1]]};function LGraphCanvas(a,b){"string"==typeof a&&(a=document.querySelector(a));if(!a)throw"no canvas found";b&&b.attachCanvas(this);this.setCanvas(a);this.clear();this.startRendering()}LGraphCanvas.link_type_colors={number:"#AAC",node:"#DCA"};
LGraphCanvas.prototype.clear=function(){this.fps=this.render_time=this.last_draw_time=this.frame=0;this.scale=1;this.offset=[0,0];this.selected_nodes={};this.connecting_node=this.node_capturing_input=this.node_over=this.node_dragged=null;this.highquality_render=!0;this.editor_alpha=1;this.pause_rendering=!1;this.dirty_bgcanvas=this.dirty_canvas=this.render_shadows=!0;this.dirty_area=null;this.render_only_selected=!0;this.live_mode=!1;this.allow_dragnodes=this.allow_dragcanvas=this.show_info=!0;this.node_in_panel=
null;this.last_mouse=[0,0];this.last_mouseclick=0;this.title_text_font="bold 14px Arial";this.inner_text_font="normal 12px Arial";this.render_connections_shadows=!1;this.render_connection_arrows=this.render_curved_connections=this.render_connections_border=!0;this.connections_width=4;if(this.onClear)this.onClear()};LGraphCanvas.prototype.setGraph=function(a){this.graph!=a&&(this.clear(),!a&&this.graph?this.graph.detachCanvas(this):(a.attachCanvas(this),this.setDirty(!0,!0)))};
@@ -52,18 +55,18 @@ this.processMouseWheel.bind(this),!1);this.canvas.addEventListener("touchstart",
LGraphCanvas.prototype.setDirty=function(a,b){a&&(this.dirty_canvas=!0);b&&(this.dirty_bgcanvas=!0)};LGraphCanvas.prototype.getCanvasWindow=function(){var a=this.canvas.ownerDocument;return a.defaultView||a.parentWindow};LGraphCanvas.prototype.startRendering=function(){function a(){this.pause_rendering||this.draw();var b=this.getCanvasWindow();this.is_rendering&&b.requestAnimationFrame(a.bind(this))}this.is_rendering||(this.is_rendering=!0,a.call(this))};
LGraphCanvas.prototype.stopRendering=function(){this.is_rendering=!1};
LGraphCanvas.prototype.processMouseDown=function(a){if(this.graph){this.adjustMouseEvent(a);var b=this.getCanvasWindow();this.canvas.removeEventListener("mousemove",this._mousemove_callback);b.document.addEventListener("mousemove",this._mousemove_callback);b.document.addEventListener("mouseup",this._mouseup_callback);var c=this.graph.getNodeOnPos(a.canvasX,a.canvasY,this.visible_nodes);if(1==a.which){if(!a.shiftKey){var d=[],e;for(e in this.selected_nodes)this.selected_nodes[e]!=c&&d.push(this.selected_nodes[e]);
for(e in d)this.processNodeDeselected(d[e])}d=!1;if(c){this.live_mode||c.flags.pinned||this.bringToFront(c);var f=!1;if(!this.connecting_node&&!c.flags.collapsed&&!this.live_mode){if(c.outputs){e=0;for(var g=c.outputs.length;e<g;++e){var h=c.outputs[e],k=c.getConnectionPos(!1,e);if(isInsideRectangle(a.canvasX,a.canvasY,k[0]-10,k[1]-5,20,10)){this.connecting_node=c;this.connecting_output=h;this.connecting_pos=c.getConnectionPos(!1,e);this.connecting_slot=e;f=!0;break}}}if(c.inputs)for(e=0,g=c.inputs.length;e<
g;++e)h=c.inputs[e],k=c.getConnectionPos(!0,e),isInsideRectangle(a.canvasX,a.canvasY,k[0]-10,k[1]-5,20,10)&&h.link&&(c.disconnectInput(e),f=this.dirty_bgcanvas=!0);!f&&isInsideRectangle(a.canvasX,a.canvasY,c.pos[0]+c.size[0]-5,c.pos[1]+c.size[1]-5,5,5)&&(this.resizing_node=c,this.canvas.style.cursor="se-resize",f=!0)}if(!f){e=!1;if(300>window.performance.now()-this.last_mouseclick&&this.selected_nodes[c.id]){if(c.onDblClick)c.onDblClick(a);this.processNodeDblClicked(c);e=!0}c.onMouseDown&&c.onMouseDown(a)?
for(e in d)this.processNodeDeselected(d[e])}d=!1;if(c){this.live_mode||c.flags.pinned||this.bringToFront(c);var f=!1;if(!this.connecting_node&&!c.flags.collapsed&&!this.live_mode){if(c.outputs){e=0;for(var g=c.outputs.length;e<g;++e){var h=c.outputs[e],l=c.getConnectionPos(!1,e);if(isInsideRectangle(a.canvasX,a.canvasY,l[0]-10,l[1]-5,20,10)){this.connecting_node=c;this.connecting_output=h;this.connecting_pos=c.getConnectionPos(!1,e);this.connecting_slot=e;f=!0;break}}}if(c.inputs)for(e=0,g=c.inputs.length;e<
g;++e)h=c.inputs[e],l=c.getConnectionPos(!0,e),isInsideRectangle(a.canvasX,a.canvasY,l[0]-10,l[1]-5,20,10)&&h.link&&(c.disconnectInput(e),f=this.dirty_bgcanvas=!0);!f&&isInsideRectangle(a.canvasX,a.canvasY,c.pos[0]+c.size[0]-5,c.pos[1]+c.size[1]-5,5,5)&&(this.resizing_node=c,this.canvas.style.cursor="se-resize",f=!0)}if(!f){e=!1;if(300>window.performance.now()-this.last_mouseclick&&this.selected_nodes[c.id]){if(c.onDblClick)c.onDblClick(a);this.processNodeDblClicked(c);e=!0}c.onMouseDown&&c.onMouseDown(a)?
e=!0:this.live_mode&&(e=d=!0);e||(this.allow_dragnodes&&(this.node_dragged=c),this.selected_nodes[c.id]||this.processNodeSelected(c,a));this.dirty_canvas=!0}}else d=!0;d&&this.allow_dragcanvas&&(this.dragging_canvas=!0)}else 2!=a.which&&3==a.which&&this.processContextualMenu(c,a);this.last_mouse[0]=a.localX;this.last_mouse[1]=a.localY;this.last_mouseclick=window.performance.now();this.canvas_mouse=[a.canvasX,a.canvasY];this.graph.change();(!b.document.activeElement||"input"!=b.document.activeElement.nodeName.toLowerCase()&&
"textarea"!=b.document.activeElement.nodeName.toLowerCase())&&a.preventDefault();a.stopPropagation();return!1}};
LGraphCanvas.prototype.processMouseMove=function(a){if(this.graph){this.adjustMouseEvent(a);var b=[a.localX,a.localY],c=[b[0]-this.last_mouse[0],b[1]-this.last_mouse[1]];this.last_mouse=b;this.canvas_mouse=[a.canvasX,a.canvasY];if(this.dragging_canvas)this.offset[0]+=c[0]/this.scale,this.offset[1]+=c[1]/this.scale,this.dirty_bgcanvas=this.dirty_canvas=!0;else{this.connecting_node&&(this.dirty_canvas=!0);var b=this.graph.getNodeOnPos(a.canvasX,a.canvasY,this.visible_nodes),d;for(d in this.graph._nodes)if(this.graph._nodes[d].mouseOver&&
b!=this.graph._nodes[d]){this.graph._nodes[d].mouseOver=!1;if(this.node_over&&this.node_over.onMouseLeave)this.node_over.onMouseLeave(a);this.node_over=null;this.dirty_canvas=!0}if(b){if(!b.mouseOver&&(b.mouseOver=!0,this.node_over=b,this.dirty_canvas=!0,b.onMouseEnter))b.onMouseEnter(a);if(b.onMouseMove)b.onMouseMove(a);if(this.connecting_node){var e=this._highlight_input||[0,0],f=this.isOverNodeInput(b,a.canvasX,a.canvasY,e);if(-1!=f&&b.inputs[f]){if(f=b.inputs[f].type,f==this.connecting_output.type||
"*"==f||"*"==this.connecting_output.type)this._highlight_input=e}else this._highlight_input=null}isInsideRectangle(a.canvasX,a.canvasY,b.pos[0]+b.size[0]-5,b.pos[1]+b.size[1]-5,5,5)?this.canvas.style.cursor="se-resize":this.canvas.style.cursor=null}else this.canvas.style.cursor=null;if(this.node_capturing_input&&this.node_capturing_input!=b&&this.node_capturing_input.onMouseMove)this.node_capturing_input.onMouseMove(a);if(this.node_dragged&&!this.live_mode){for(d in this.selected_nodes)b=this.selected_nodes[d],
b.pos[0]+=c[0]/this.scale,b.pos[1]+=c[1]/this.scale,b.pos[0]=Math.round(b.pos[0]),b.pos[1]=Math.round(b.pos[1]);this.dirty_bgcanvas=this.dirty_canvas=!0}this.resizing_node&&!this.live_mode&&(this.resizing_node.size[0]+=c[0]/this.scale,this.resizing_node.size[1]+=c[1]/this.scale,c=Math.max(this.resizing_node.inputs?this.resizing_node.inputs.length:0,this.resizing_node.outputs?this.resizing_node.outputs.length:0),this.resizing_node.size[1]<c*LiteGraph.NODE_SLOT_HEIGHT+4&&(this.resizing_node.size[1]=
c*LiteGraph.NODE_SLOT_HEIGHT+4),this.resizing_node.size[0]<LiteGraph.NODE_MIN_WIDTH&&(this.resizing_node.size[0]=LiteGraph.NODE_MIN_WIDTH),this.canvas.style.cursor="se-resize",this.dirty_bgcanvas=this.dirty_canvas=!0)}a.preventDefault();a.stopPropagation();return!1}};
b.pos[0]+=c[0]/this.scale,b.pos[1]+=c[1]/this.scale;this.dirty_bgcanvas=this.dirty_canvas=!0}this.resizing_node&&!this.live_mode&&(this.resizing_node.size[0]+=c[0]/this.scale,this.resizing_node.size[1]+=c[1]/this.scale,c=Math.max(this.resizing_node.inputs?this.resizing_node.inputs.length:0,this.resizing_node.outputs?this.resizing_node.outputs.length:0),this.resizing_node.size[1]<c*LiteGraph.NODE_SLOT_HEIGHT+4&&(this.resizing_node.size[1]=c*LiteGraph.NODE_SLOT_HEIGHT+4),this.resizing_node.size[0]<
LiteGraph.NODE_MIN_WIDTH&&(this.resizing_node.size[0]=LiteGraph.NODE_MIN_WIDTH),this.canvas.style.cursor="se-resize",this.dirty_bgcanvas=this.dirty_canvas=!0)}a.preventDefault();a.stopPropagation();return!1}};
LGraphCanvas.prototype.processMouseUp=function(a){if(this.graph){var b=this.getCanvasWindow().document;b.removeEventListener("mousemove",this._mousemove_callback,!0);this.canvas.addEventListener("mousemove",this._mousemove_callback,!0);b.removeEventListener("mouseup",this._mouseup_callback,!0);this.adjustMouseEvent(a);if(1==a.which)if(this.connecting_node){this.dirty_bgcanvas=this.dirty_canvas=!0;if(b=this.graph.getNodeOnPos(a.canvasX,a.canvasY,this.visible_nodes))if("node"==this.connecting_output.type)this.connecting_node.connect(this.connecting_slot,
b,-1);else{var c=this.isOverNodeInput(b,a.canvasX,a.canvasY);-1!=c&&this.connecting_node.connect(this.connecting_slot,b,c)}this.connecting_node=this.connecting_pos=this.connecting_output=null;this.connecting_slot=-1}else if(this.resizing_node)this.dirty_bgcanvas=this.dirty_canvas=!0,this.resizing_node=null;else if(this.node_dragged)this.dirty_bgcanvas=this.dirty_canvas=!0,this.graph.config.align_to_grid&&this.node_dragged.alignToGrid(),this.node_dragged=null;else{this.dirty_canvas=!0;this.dragging_canvas=
!1;if(this.node_over&&this.node_over.onMouseUp)this.node_over.onMouseUp(a);if(this.node_capturing_input&&this.node_capturing_input.onMouseUp)this.node_capturing_input.onMouseUp(a)}else 2==a.which?(this.dirty_canvas=!0,this.dragging_canvas=!1):3==a.which&&(this.dirty_canvas=!0,this.dragging_canvas=!1);this.graph.change();a.stopPropagation();a.preventDefault();return!1}};
b,-1);else{var c=this.isOverNodeInput(b,a.canvasX,a.canvasY);-1!=c&&this.connecting_node.connect(this.connecting_slot,b,c)}this.connecting_node=this.connecting_pos=this.connecting_output=null;this.connecting_slot=-1}else if(this.resizing_node)this.dirty_bgcanvas=this.dirty_canvas=!0,this.resizing_node=null;else if(this.node_dragged)this.dirty_bgcanvas=this.dirty_canvas=!0,this.node_dragged.pos[0]=Math.round(this.node_dragged.pos[0]),this.node_dragged.pos[1]=Math.round(this.node_dragged.pos[1]),this.graph.config.align_to_grid&&
this.node_dragged.alignToGrid(),this.node_dragged=null;else{this.dirty_canvas=!0;this.dragging_canvas=!1;if(this.node_over&&this.node_over.onMouseUp)this.node_over.onMouseUp(a);if(this.node_capturing_input&&this.node_capturing_input.onMouseUp)this.node_capturing_input.onMouseUp(a)}else 2==a.which?(this.dirty_canvas=!0,this.dragging_canvas=!1):3==a.which&&(this.dirty_canvas=!0,this.dragging_canvas=!1);this.graph.change();a.stopPropagation();a.preventDefault();return!1}};
LGraphCanvas.prototype.isOverNodeInput=function(a,b,c,d){if(a.inputs)for(var e=0,f=a.inputs.length;e<f;++e){var g=a.getConnectionPos(!0,e);if(isInsideRectangle(b,c,g[0]-10,g[1]-5,20,10))return d&&(d[0]=g[0],d[1]=g[1]),e}return-1};
LGraphCanvas.prototype.processKeyDown=function(a){if(this.graph){var b=!1;65==a.keyCode&&a.ctrlKey&&(this.selectAllNodes(),b=!0);46!=a.keyCode&&8!=a.keyCode||this.deleteSelectedNodes();if(this.selected_nodes)for(var c in this.selected_nodes)if(this.selected_nodes[c].onKeyDown)this.selected_nodes[c].onKeyDown(a);this.graph.change();if(b)return a.preventDefault(),!1}};
LGraphCanvas.prototype.processKeyUp=function(a){if(this.graph){if(this.selected_nodes)for(var b in this.selected_nodes)if(this.selected_nodes[b].onKeyUp)this.selected_nodes[b].onKeyUp(a);this.graph.change()}};LGraphCanvas.prototype.processMouseWheel=function(a){if(this.graph&&this.allow_dragcanvas){var b=null!=a.wheelDeltaY?a.wheelDeltaY:-60*a.detail;this.adjustMouseEvent(a);var c=this.scale;0<b?c*=1.1:0>b&&(c*=1/1.1);this.setZoom(c,[a.localX,a.localY]);this.graph.change();a.preventDefault();return!1}};
@@ -82,33 +85,33 @@ this.frame,5,39),a.fillText("FPS:"+this.fps.toFixed(2),5,52)):a.fillText("No gra
LGraphCanvas.prototype.drawBgcanvas=function(){var a=this.bgcanvas,b=this.bgctx;a.width=a.width;b.restore();b.setTransform(1,0,0,1,0,0);if(this.graph){b.save();b.scale(this.scale,this.scale);b.translate(this.offset[0],this.offset[1]);if(this.background_image&&0.5<this.scale){b.globalAlpha=(1-0.5/this.scale)*this.editor_alpha;b.webkitImageSmoothingEnabled=b.mozImageSmoothingEnabled=b.imageSmoothingEnabled=!1;if(!this._bg_img||this._bg_img.name!=this.background_image){this._bg_img=new Image;this._bg_img.name=
this.background_image;this._bg_img.src=this.background_image;var c=this;this._bg_img.onload=function(){c.draw(!0,!0)}}var d=null;this._bg_img!=this._pattern_img&&0<this._bg_img.width?(d=b.createPattern(this._bg_img,"repeat"),this._pattern_img=this._bg_img,this._pattern=d):d=this._pattern;d&&(b.fillStyle=d,b.fillRect(this.visible_area[0],this.visible_area[1],this.visible_area[2]-this.visible_area[0],this.visible_area[3]-this.visible_area[1]),b.fillStyle="transparent");b.globalAlpha=1}b.strokeStyle=
"#235";b.strokeRect(0,0,a.width,a.height);this.render_connections_shadows?(b.shadowColor="#000",b.shadowOffsetX=0,b.shadowOffsetY=0,b.shadowBlur=6):b.shadowColor="rgba(0,0,0,0)";this.live_mode||this.drawConnections(b);b.shadowColor="rgba(0,0,0,0)";b.restore()}this.dirty_bgcanvas=!1;this.dirty_canvas=!0};
LGraphCanvas.prototype.drawNode=function(a,b){var c=a.color||LiteGraph.NODE_DEFAULT_COLOR,d=!0;if(a.flags.skip_title_render||a.graph.isLive())d=!1;a.mouseOver&&(d=!0);a.selected||(this.render_shadows?(b.shadowColor="#111",b.shadowOffsetX=2,b.shadowOffsetY=2,b.shadowBlur=4):b.shadowColor="transparent");if(this.live_mode){if(!a.flags.collapsed&&(b.shadowColor="transparent",a.onDrawForeground))a.onDrawForeground(b)}else{var e=this.editor_alpha;b.globalAlpha=e;var f=a.shape||"box",g=new Float32Array(a.size);
LGraphCanvas.prototype.drawNode=function(a,b){var c=a.color||LiteGraph.NODE_DEFAULT_COLOR,d=!0;if(a.flags.skip_title_render||a.graph.isLive())d=!1;a.mouseOver&&(d=!0);a.selected||(this.render_shadows?(b.shadowColor="rgba(0,0,0,0.5)",b.shadowOffsetX=2,b.shadowOffsetY=2,b.shadowBlur=3):b.shadowColor="transparent");if(this.live_mode){if(!a.flags.collapsed&&(b.shadowColor="transparent",a.onDrawForeground))a.onDrawForeground(b)}else{var e=this.editor_alpha;b.globalAlpha=e;var f=a.shape||"box",g=new Float32Array(a.size);
a.flags.collapsed&&g.set([LiteGraph.NODE_COLLAPSED_WIDTH,0]);a.flags.clip_area&&(b.save(),"box"==f?(b.beginPath(),b.rect(0,0,g[0],g[1])):"round"==f?b.roundRect(0,0,g[0],g[1],10):"circle"==f&&(b.beginPath(),b.arc(0.5*g[0],0.5*g[1],0.5*g[0],0,2*Math.PI)),b.clip());this.drawNodeShape(a,b,g,c,a.bgcolor,!d,a.selected);b.shadowColor="transparent";b.textAlign="left";b.font=this.inner_text_font;d=0.6<this.scale;if(!a.flags.collapsed){if(a.inputs)for(f=0;f<a.inputs.length;f++){var h=a.inputs[f];b.globalAlpha=
e;null!=this.connecting_node&&0!=this.connecting_output.type&&0!=a.inputs[f].type&&this.connecting_output.type!=a.inputs[f].type&&(b.globalAlpha=0.4*e);b.fillStyle=null!=h.link?"#7F7":"#AAA";g=a.getConnectionPos(!0,f);g[0]-=a.pos[0];g[1]-=a.pos[1];b.beginPath();b.arc(g[0],g[1],4,0,2*Math.PI);b.fill();d&&(h=null!=h.label?h.label:h.name)&&(b.fillStyle=c,b.fillText(h,g[0]+10,g[1]+5))}this.connecting_node&&(b.globalAlpha=0.4*e);b.lineWidth=1;b.textAlign="right";b.strokeStyle="black";if(a.outputs)for(f=
0;f<a.outputs.length;f++)if(h=a.outputs[f],g=a.getConnectionPos(!1,f),g[0]-=a.pos[0],g[1]-=a.pos[1],b.fillStyle=h.links&&h.links.length?"#7F7":"#AAA",b.beginPath(),b.arc(g[0],g[1],4,0,2*Math.PI),b.fill(),b.stroke(),d&&(h=null!=h.label?h.label:h.name))b.fillStyle=c,b.fillText(h,g[0]-10,g[1]+5);b.textAlign="left";b.globalAlpha=1;if(a.onDrawForeground)a.onDrawForeground(b)}a.flags.clip_area&&b.restore();b.globalAlpha=1}};
LGraphCanvas.prototype.drawNodeShape=function(a,b,c,d,e,f,g){b.strokeStyle=d||LiteGraph.NODE_DEFAULT_COLOR;b.fillStyle=e||LiteGraph.NODE_DEFAULT_BGCOLOR;e=LiteGraph.NODE_TITLE_HEIGHT;var h=a.shape||"box";"box"==h?(g&&(b.strokeStyle="#CCC",b.strokeRect(-0.5,f?-0.5:-e+-0.5,c[0]+2,f?c[1]+2:c[1]+e+2),b.strokeStyle=d),b.beginPath(),b.rect(0,f?0.5:-e+0.5,c[0]+1,f?c[1]:c[1]+e)):"round"==a.shape?b.roundRect(0,f?0:-e,c[0],f?c[1]:c[1]+e,10):"circle"==a.shape&&(b.beginPath(),b.arc(0.5*c[0],0.5*c[1],0.5*c[0],
0,2*Math.PI));b.fill();b.shadowColor="transparent";a.bgImage&&a.bgImage.width&&b.drawImage(a.bgImage,0.5*(c[0]-a.bgImage.width),0.5*(c[1]-a.bgImage.height));a.bgImageUrl&&!a.bgImage&&(a.bgImage=a.loadImage(a.bgImageUrl));if(a.onDrawBackground)a.onDrawBackground(b);f||(b.fillStyle=d||LiteGraph.NODE_DEFAULT_COLOR,d=b.globalAlpha,b.globalAlpha=0.5*d,"box"==h?(b.beginPath(),b.fillRect(0,-e,c[0]+1,e),b.stroke()):"round"==h&&(b.roundRect(0,-e,c[0],e,10,0),b.fill(),b.stroke()),b.fillStyle=a.boxcolor||LiteGraph.NODE_DEFAULT_BOXCOLOR,
b.beginPath(),"round"==h?b.arc(0.5*e,-0.5*e,0.5*(e-6),0,2*Math.PI):b.rect(3,-e+3,e-6,e-6),b.fill(),b.globalAlpha=d,b.font=this.title_text_font,""!=a.name&&0.8<this.scale&&(b.fillStyle="#222",b.fillText(a.name,16,13-e)))};
b.beginPath(),"round"==h?b.arc(0.5*e,-0.5*e,0.5*(e-6),0,2*Math.PI):b.rect(3,-e+3,e-6,e-6),b.fill(),b.globalAlpha=d,b.font=this.title_text_font,(a=a.getTitle())&&0.8<this.scale&&(b.fillStyle="#222",b.fillText(a,16,13-e)))};
LGraphCanvas.prototype.drawNodeCollapsed=function(a,b,c,d){b.strokeStyle=c||LiteGraph.NODE_DEFAULT_COLOR;b.fillStyle=d||LiteGraph.NODE_DEFAULT_BGCOLOR;c=LiteGraph.NODE_COLLAPSED_RADIUS;d=a.shape||"box";"circle"==d?(b.beginPath(),b.arc(0.5*a.size[0],0.5*a.size[1],c,0,2*Math.PI),b.fill(),b.shadowColor="rgba(0,0,0,0)",b.stroke(),b.fillStyle=a.boxcolor||LiteGraph.NODE_DEFAULT_BOXCOLOR,b.beginPath(),b.arc(0.5*a.size[0],0.5*a.size[1],0.5*c,0,2*Math.PI)):"round"==d?(b.beginPath(),b.roundRect(0.5*a.size[0]-
c,0.5*a.size[1]-c,2*c,2*c,5),b.fill(),b.shadowColor="rgba(0,0,0,0)",b.stroke(),b.fillStyle=a.boxcolor||LiteGraph.NODE_DEFAULT_BOXCOLOR,b.beginPath(),b.roundRect(0.5*a.size[0]-0.5*c,0.5*a.size[1]-0.5*c,c,c,2)):(b.beginPath(),b.rect(0,0,a.size[0],2*c),b.fill(),b.shadowColor="rgba(0,0,0,0)",b.stroke(),b.fillStyle=a.boxcolor||LiteGraph.NODE_DEFAULT_BOXCOLOR,b.beginPath(),b.rect(0.5*c,0.5*c,c,c));b.fill()};LGraphCanvas.link_colors=["#AAC","#ACA","#CAA"];
LGraphCanvas.prototype.drawConnections=function(a){a.lineWidth=this.connections_width;a.fillStyle="#AAA";a.strokeStyle="#AAA";a.globalAlpha=this.editor_alpha;for(var b in this.graph._nodes){var c=this.graph._nodes[b];if(c.inputs&&c.inputs.length)for(var d in c.inputs){var e=c.inputs[d];if(e&&e.link){var f=e.link,e=this.graph.getNodeById(f[1]);if(null!=e){var g=f[2],f=null,f=-1==g?[e.pos[0]+10,e.pos[1]+10]:e.getConnectionPos(!1,g),e=LGraphCanvas.link_type_colors[c.inputs[d].type];null==e&&(e=LGraphCanvas.link_colors[c.id%
LGraphCanvas.link_colors.length]);this.renderLink(a,f,c.getConnectionPos(!0,d),e)}}}}a.globalAlpha=1};
LGraphCanvas.prototype.renderLink=function(a,b,c,d){if(this.highquality_render){var e=distance(b,c);this.render_connections_border&&(a.lineWidth=this.connections_width+4);a.beginPath();this.render_curved_connections?(a.moveTo(b[0],b[1]),a.bezierCurveTo(b[0]+0.25*e,b[1],c[0]-0.25*e,c[1],c[0],c[1])):(a.moveTo(b[0]+10,b[1]),a.lineTo(0.5*(b[0]+10+(c[0]-10)),b[1]),a.lineTo(0.5*(b[0]+10+(c[0]-10)),c[1]),a.lineTo(c[0]-10,c[1]));this.render_connections_border&&(a.strokeStyle="rgba(0,0,0,0.5)",a.stroke());
a.lineWidth=this.connections_width;a.fillStyle=a.strokeStyle=d;a.stroke();if(this.render_connection_arrows&&0.6<this.scale){d=this.computeConnectionPoint(b,c,0.5);var e=this.computeConnectionPoint(b,c,0.51),f=0,f=this.render_curved_connections?-Math.atan2(e[0]-d[0],e[1]-d[1]):c[1]>b[1]?0:Math.PI;a.save();a.translate(d[0],d[1]);a.rotate(f);a.beginPath();a.moveTo(-5,-5);a.lineTo(0,5);a.lineTo(5,-5);a.fill();a.restore()}}else a.beginPath(),a.moveTo(b[0],b[1]),a.lineTo(c[0],c[1]),a.stroke()};
LGraphCanvas.prototype.computeConnectionPoint=function(a,b,c){var d=distance(a,b),e=[a[0]+0.25*d,a[1]],d=[b[0]-0.25*d,b[1]],f=(1-c)*(1-c)*(1-c),g=3*(1-c)*(1-c)*c,h=3*(1-c)*c*c;c*=c*c;return[f*a[0]+g*e[0]+h*d[0]+c*b[0],f*a[1]+g*e[1]+h*d[1]+c*b[1]]};
LGraphCanvas.prototype.renderLink=function(a,b,c,d){if(this.highquality_render){var e=distance(b,c);this.render_connections_border&&0.6<this.scale&&(a.lineWidth=this.connections_width+4);a.beginPath();this.render_curved_connections?(a.moveTo(b[0],b[1]),a.bezierCurveTo(b[0]+0.25*e,b[1],c[0]-0.25*e,c[1],c[0],c[1])):(a.moveTo(b[0]+10,b[1]),a.lineTo(0.5*(b[0]+10+(c[0]-10)),b[1]),a.lineTo(0.5*(b[0]+10+(c[0]-10)),c[1]),a.lineTo(c[0]-10,c[1]));this.render_connections_border&&0.6<this.scale&&(a.strokeStyle=
"rgba(0,0,0,0.5)",a.stroke());a.lineWidth=this.connections_width;a.fillStyle=a.strokeStyle=d;a.stroke();if(this.render_connection_arrows&&0.6<this.scale){d=this.computeConnectionPoint(b,c,0.5);var e=this.computeConnectionPoint(b,c,0.51),f=0,f=this.render_curved_connections?-Math.atan2(e[0]-d[0],e[1]-d[1]):c[1]>b[1]?0:Math.PI;a.save();a.translate(d[0],d[1]);a.rotate(f);a.beginPath();a.moveTo(-5,-5);a.lineTo(0,5);a.lineTo(5,-5);a.fill();a.restore()}}else a.beginPath(),a.moveTo(b[0],b[1]),a.lineTo(c[0],
c[1]),a.stroke()};LGraphCanvas.prototype.computeConnectionPoint=function(a,b,c){var d=distance(a,b),e=[a[0]+0.25*d,a[1]],d=[b[0]-0.25*d,b[1]],f=(1-c)*(1-c)*(1-c),g=3*(1-c)*(1-c)*c,h=3*(1-c)*c*c;c*=c*c;return[f*a[0]+g*e[0]+h*d[0]+c*b[0],f*a[1]+g*e[1]+h*d[1]+c*b[1]]};
LGraphCanvas.prototype.resize=function(a,b){if(!a&&!b){var c=this.canvas.parentNode;a=c.offsetWidth;b=c.offsetHeight}if(this.canvas.width!=a||this.canvas.height!=b)this.canvas.width=a,this.canvas.height=b,this.bgcanvas.width=this.canvas.width,this.bgcanvas.height=this.canvas.height,this.setDirty(!0,!0)};
LGraphCanvas.prototype.switchLiveMode=function(a){if(a){var b=this,c=this.live_mode?1.1:0.9;this.live_mode&&(this.live_mode=!1,this.editor_alpha=0.1);var d=setInterval(function(){b.editor_alpha*=c;b.dirty_canvas=!0;b.dirty_bgcanvas=!0;1>c&&0.01>b.editor_alpha&&(clearInterval(d),1>c&&(b.live_mode=!0));1<c&&0.99<b.editor_alpha&&(clearInterval(d),b.editor_alpha=1)},1)}else this.live_mode=!this.live_mode,this.dirty_bgcanvas=this.dirty_canvas=!0};LGraphCanvas.prototype.onNodeSelectionChange=function(a){};
LGraphCanvas.prototype.touchHandler=function(a){var b=a.changedTouches[0],c="";switch(a.type){case "touchstart":c="mousedown";break;case "touchmove":c="mousemove";break;case "touchend":c="mouseup";break;default:return}var d=this.getCanvasWindow(),e=d.document.createEvent("MouseEvent");e.initMouseEvent(c,!0,!0,d,1,b.screenX,b.screenY,b.clientX,b.clientY,!1,!1,!1,!1,0,null);b.target.dispatchEvent(e);a.preventDefault()};
LGraphCanvas.onMenuAdd=function(a,b,c,d,e){function f(a,b){var c=LiteGraph.createNode(a.value);c&&(c.pos=d.convertEventToCanvas(e),d.graph.add(c))}var g=d.getCanvasWindow();a=LiteGraph.getNodeTypesCategories();var h={},k;for(k in a)a[k]&&(h[k]={value:a[k],content:a[k],is_menu:!0});var l=LiteGraph.createContextualMenu(h,{event:b,callback:function(a,b){var c=LiteGraph.getNodeTypesInCategory(a.value),d=[],e;for(e in c)d.push({content:c[e].title,value:c[e].type});LiteGraph.createContextualMenu(d,{event:b,
callback:f,from:l},g);return!1},from:c},g);return!1};LGraphCanvas.onMenuCollapseAll=function(){};LGraphCanvas.onMenuNodeEdit=function(){};LGraphCanvas.onMenuNodeInputs=function(a,b,c){function d(b){a&&a.addInput(b.value[0],b.value[1],b.value[2])}if(a){var e=a.optional_inputs;a.onGetInputs&&(e=a.onGetInputs());if(e){var f=[],g;for(g in e){var h=e[g],k=h[0];h[2]&&h[2].label&&(k=h[2].label);f.push({content:k,value:h})}LiteGraph.createContextualMenu(f,{event:b,callback:d,from:c})}return!1}};
LGraphCanvas.onMenuNodeOutputs=function(a,b,c){function d(e){if(a){var f=e.value[1];if(!f||f.constructor!==Object&&f.constructor!==Array)a.addOutput(e.value[0],e.value[1]);else{e=[];for(var g in f)e.push({content:g,value:f[g]});LiteGraph.createContextualMenu(e,{event:b,callback:d,from:c});return!1}}}if(a){var e=a.optional_outputs;a.onGetOutputs&&(e=a.onGetOutputs());if(e){var f=[],g;for(g in e)-1==a.findOutputSlot(e[g][0])&&f.push({content:e[g][0],value:e[g]});f.length&&LiteGraph.createContextualMenu(f,
{event:b,callback:d,from:c})}return!1}};LGraphCanvas.onMenuNodeCollapse=function(a){a.flags.collapsed=!a.flags.collapsed;a.graph.canvas.setDirty(!0,!0)};LGraphCanvas.onMenuNodePin=function(a){a.pin()};
LGraphCanvas.onMenuNodeColors=function(a,b,c){var d=[],e;for(e in LGraphCanvas.node_colors){var f=LGraphCanvas.node_colors[e];d.push({value:e,content:"<span style='display: block; color:"+f.color+"; background-color:"+f.bgcolor+"'>"+e+"</span>"})}LiteGraph.createContextualMenu(d,{event:b,callback:function(b){a&&(b=LGraphCanvas.node_colors[b.value])&&(a.color=b.color,a.bgcolor=b.bgcolor,a.graph.canvas.setDirty(!0))},from:c});return!1};
LGraphCanvas.onMenuNodeShapes=function(a,b){LiteGraph.createContextualMenu(["box","round"],{event:b,callback:function(b){a&&(a.shape=b,a.graph.canvas.setDirty(!0))}});return!1};LGraphCanvas.onMenuNodeRemove=function(a){!1!=a.removable&&(a.graph.remove(a),a.graph.canvas.setDirty(!0,!0))};LGraphCanvas.onMenuNodeClone=function(a){if(!1!=a.clonable){var b=a.clone();b&&(b.pos=[a.pos[0]+5,a.pos[1]+5],a.graph.add(b),a.graph.canvas.setDirty(!0,!0))}};
LGraphCanvas.onMenuAdd=function(a,b,c,d,e){function f(a,b){var c=LiteGraph.createNode(a.value);c&&(c.pos=d.convertEventToCanvas(e),d.graph.add(c))}var g=d.getCanvasWindow();a=LiteGraph.getNodeTypesCategories();var h={},l;for(l in a)a[l]&&(h[l]={value:a[l],content:a[l],is_menu:!0});var k=LiteGraph.createContextualMenu(h,{event:b,callback:function(a,b){var c=LiteGraph.getNodeTypesInCategory(a.value),d=[],e;for(e in c)d.push({content:c[e].title,value:c[e].type});LiteGraph.createContextualMenu(d,{event:b,
callback:f,from:k},g);return!1},from:c},g);return!1};LGraphCanvas.onMenuCollapseAll=function(){};LGraphCanvas.onMenuNodeEdit=function(){};LGraphCanvas.onMenuNodeInputs=function(a,b,c){function d(b){a&&a.addInput(b.value[0],b.value[1],b.value[2])}if(a){var e=a.optional_inputs;a.onGetInputs&&(e=a.onGetInputs());if(e){var f=[],g;for(g in e){var h=e[g],l=h[0];h[2]&&h[2].label&&(l=h[2].label);f.push({content:l,value:h})}LiteGraph.createContextualMenu(f,{event:b,callback:d,from:c})}return!1}};
LGraphCanvas.onMenuNodeOutputs=function(a,b,c){function d(f){if(a){var e=f.value[1];if(!e||e.constructor!==Object&&e.constructor!==Array)a.addOutput(f.value[0],f.value[1]);else{f=[];for(var g in e)f.push({content:g,value:e[g]});LiteGraph.createContextualMenu(f,{event:b,callback:d,from:c});return!1}}}if(a){var e=a.optional_outputs;a.onGetOutputs&&(e=a.onGetOutputs());if(e){var f=[],g;for(g in e)-1==a.findOutputSlot(e[g][0])&&f.push({content:e[g][0],value:e[g]});f.length&&LiteGraph.createContextualMenu(f,
{event:b,callback:d,from:c})}return!1}};LGraphCanvas.onMenuNodeCollapse=function(a){a.flags.collapsed=!a.flags.collapsed;a.setDirtyCanvas(!0,!0)};LGraphCanvas.onMenuNodePin=function(a){a.pin()};
LGraphCanvas.onMenuNodeColors=function(a,b,c){var d=[],e;for(e in LGraphCanvas.node_colors){var f=LGraphCanvas.node_colors[e];d.push({value:e,content:"<span style='display: block; color:"+f.color+"; background-color:"+f.bgcolor+"'>"+e+"</span>"})}LiteGraph.createContextualMenu(d,{event:b,callback:function(b){a&&(b=LGraphCanvas.node_colors[b.value])&&(a.color=b.color,a.bgcolor=b.bgcolor,a.setDirtyCanvas(!0))},from:c});return!1};
LGraphCanvas.onMenuNodeShapes=function(a,b){LiteGraph.createContextualMenu(["box","round"],{event:b,callback:function(b){a&&(a.shape=b,a.setDirtyCanvas(!0))}});return!1};LGraphCanvas.onMenuNodeRemove=function(a){!1!=a.removable&&(a.graph.remove(a),a.setDirtyCanvas(!0,!0))};LGraphCanvas.onMenuNodeClone=function(a){if(!1!=a.clonable){var b=a.clone();b&&(b.pos=[a.pos[0]+5,a.pos[1]+5],a.graph.add(b),a.setDirtyCanvas(!0,!0))}};
LGraphCanvas.node_colors={red:{color:"#FAA",bgcolor:"#A44"},green:{color:"#AFA",bgcolor:"#4A4"},blue:{color:"#AAF",bgcolor:"#44A"},white:{color:"#FFF",bgcolor:"#AAA"}};LGraphCanvas.prototype.getCanvasMenuOptions=function(){return[{content:"Add Node",is_menu:!0,callback:LGraphCanvas.onMenuAdd}]};
LGraphCanvas.prototype.getNodeMenuOptions=function(a){var b=[{content:"Inputs",is_menu:!0,disabled:!0,callback:LGraphCanvas.onMenuNodeInputs},{content:"Outputs",is_menu:!0,disabled:!0,callback:LGraphCanvas.onMenuNodeOutputs},null,{content:"Collapse",callback:LGraphCanvas.onMenuNodeCollapse},{content:"Pin",callback:LGraphCanvas.onMenuNodePin},{content:"Colors",is_menu:!0,callback:LGraphCanvas.onMenuNodeColors},{content:"Shapes",is_menu:!0,callback:LGraphCanvas.onMenuNodeShapes},null,{content:"Clone",
callback:LGraphCanvas.onMenuNodeClone},null,{content:"Remove",callback:LGraphCanvas.onMenuNodeRemove}];!1==a.clonable&&(b[7].disabled=!0);!1==a.removable&&(b[9].disabled=!0);a.onGetInputs&&a.onGetInputs().length&&(b[0].disabled=!1);a.onGetOutputs&&a.onGetOutputs().length&&(b[1].disabled=!1);return b};
LGraphCanvas.prototype.processContextualMenu=function(a,b){var c=this,d=this.getCanvasWindow(),e=LiteGraph.createContextualMenu(a?this.getNodeMenuOptions(a):this.getCanvasMenuOptions(),{event:b,callback:function(d,g){if(d&&d.callback)return d.callback(a,g,e,c,b)}},d)};
LGraphCanvas.prototype.processContextualMenu=function(a,b){var c=this,d=this.getCanvasWindow(),e=LiteGraph.createContextualMenu(a?this.getNodeMenuOptions(a):this.getCanvasMenuOptions(),{event:b,callback:function(f,d){if(f&&f.callback)return f.callback(a,d,e,c,b)}},d)};
CanvasRenderingContext2D.prototype.roundRect=function(a,b,c,d,e,f){void 0===e&&(e=5);void 0===f&&(f=e);this.beginPath();this.moveTo(a+e,b);this.lineTo(a+c-e,b);this.quadraticCurveTo(a+c,b,a+c,b+e);this.lineTo(a+c,b+d-f);this.quadraticCurveTo(a+c,b+d,a+c-f,b+d);this.lineTo(a+f,b+d);this.quadraticCurveTo(a,b+d,a,b+d-f);this.lineTo(a,b+e);this.quadraticCurveTo(a,b,a+e,b)};function compareObjects(a,b){for(var c in a)if(a[c]!=b[c])return!1;return!0}
function distance(a,b){return Math.sqrt((b[0]-a[0])*(b[0]-a[0])+(b[1]-a[1])*(b[1]-a[1]))}function colorToString(a){return"rgba("+Math.round(255*a[0]).toFixed()+","+Math.round(255*a[1]).toFixed()+","+Math.round(255*a[2]).toFixed()+","+(4==a.length?a[3].toFixed(2):"1.0")+")"}function isInsideRectangle(a,b,c,d,e,f){return c<a&&c+e>a&&d<b&&d+f>b?!0:!1}function growBounding(a,b,c){b<a[0]?a[0]=b:b>a[2]&&(a[2]=b);c<a[1]?a[1]=c:c>a[3]&&(a[3]=c)}
function isInsideBounding(a,b){return a[0]<b[0][0]||a[1]<b[0][1]||a[0]>b[1][0]||a[1]>b[1][1]?!1:!0}function overlapBounding(a,b){return a[0]>b[2]||a[1]>b[3]||a[2]<b[0]||a[3]<b[1]?!1:!0}function hex2num(a){"#"==a.charAt(0)&&(a=a.slice(1));a=a.toUpperCase();for(var b=Array(3),c=0,d,e,f=0;6>f;f+=2)d="0123456789ABCDEF".indexOf(a.charAt(f)),e="0123456789ABCDEF".indexOf(a.charAt(f+1)),b[c]=16*d+e,c++;return b}
@@ -118,75 +121,57 @@ f.backgroundColor="#444";e.addEventListener("contextmenu",function(a){a.preventD
d));e.appendChild(h)}e.addEventListener("mouseover",function(a){this.mouse_inside=!0});e.addEventListener("mouseout",function(a){for(a=a.toElement;a!=this&&a!=c.document;)a=a.parentNode;a!=this&&(this.mouse_inside=!1,this.block_close||this.closeMenu())});c.document.body.appendChild(e);a=e.getClientRects()[0];b.from&&(b.from.block_close=!0);h=b.left||0;g=b.top||0;b.event&&(h=b.event.pageX-10,g=b.event.pageY-10,b.left&&(h=b.left),f=c.document.body.getClientRects()[0],b.from&&(h=b.from.getClientRects()[0],
h=h.left+h.width),h>f.width-a.width-10&&(h=f.width-a.width-10),g>f.height-a.height-10&&(g=f.height-a.height-10));e.style.left=h+"px";e.style.top=g+"px";e.closeMenu=function(){b.from&&(b.from.block_close=!1,b.from.mouse_inside||b.from.closeMenu());this.parentNode&&c.document.body.removeChild(this)};return e};LiteGraph.closeAllContextualMenus=function(){var a=document.querySelectorAll(".litecontextualmenu");if(a.length){for(var b=[],c=0;c<a.length;c++)b.push(a[c]);for(c in b)b[c].parentNode&&b[c].parentNode.removeChild(b[c])}};
LiteGraph.extendClass=function(a,b){for(var c in a)b[c]=a[c];if(a.prototype)for(c in a.prototype)b.prototype[c]=a.prototype[c]};window.requestAnimationFrame||(window.requestAnimationFrame=window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(a){window.setTimeout(a,1E3/60)});
LiteGraph.registerNodeType("basic/const",{title:"Const",desc:"Constant",outputs:[["value","number"]],properties:{value:1},editable:{property:"value",type:"number"},setValue:function(a){"string"==typeof a&&(a=parseFloat(a));this.properties.value=a;this.setDirtyCanvas(!0)},onExecute:function(){this.setOutputData(0,parseFloat(this.properties.value))},onDrawBackground:function(a){this.outputs[0].label=this.properties.value.toFixed(3)},onWidget:function(a,b){"value"==b.name&&this.setValue(b.value)}});
LiteGraph.registerNodeType("math/rand",{title:"Rand",desc:"Random number",outputs:[["value","number"]],properties:{min:0,max:1},size:[60,20],onExecute:function(){var a=this.properties.min,b=this.properties.max;this._last_v=Math.random()*(b-a)+a;this.setOutputData(0,this._last_v)},onDrawBackground:function(a){this.outputs[0].label=this._last_v?this._last_v.toFixed(3):"?"}});
LiteGraph.registerNodeType("math/clamp",{title:"Clamp",desc:"Clamp number between min and max",inputs:[["in","number"]],outputs:[["out","number"]],size:[60,20],properties:{min:0,max:1},onExecute:function(){var a=this.getInputData(0);null!=a&&(a=Math.max(this.properties.min,a),a=Math.min(this.properties.max,a),this.setOutputData(0,a))}});
LiteGraph.registerNodeType("math/abs",{title:"Abs",desc:"Absolute",inputs:[["in","number"]],outputs:[["out","number"]],size:[60,20],onExecute:function(){var a=this.getInputData(0);null!=a&&this.setOutputData(0,Math.abs(a))}});LiteGraph.registerNodeType("math/floor",{title:"Floor",desc:"Floor number to remove fractional part",inputs:[["in","number"]],outputs:[["out","number"]],size:[60,20],onExecute:function(){var a=this.getInputData(0);null!=a&&this.setOutputData(0,a|1)}});
LiteGraph.registerNodeType("math/frac",{title:"Frac",desc:"Returns fractional part",inputs:[["in","number"]],outputs:[["out","number"]],size:[60,20],onExecute:function(){var a=this.getInputData(0);null!=a&&this.setOutputData(0,a%1)}});
LiteGraph.registerNodeType("basic/watch",{title:"Watch",desc:"Show value",size:[60,20],inputs:[["value",0,{label:""}]],outputs:[["value",0,{label:""}]],properties:{value:""},onExecute:function(){this.properties.value=this.getInputData(0);this.setOutputData(0,this.properties.value)},onDrawBackground:function(a){this.inputs[0]&&null!=this.properties.value&&(this.inputs[0].label=this.properties.value.constructor===Number?this.properties.value.toFixed(3):this.properties.value)}});
LiteGraph.registerNodeType("math/scale",{title:"Scale",desc:"1 - value",inputs:[["value","number",{label:""}]],outputs:[["value","number",{label:""}]],size:[70,20],properties:{factor:1},onExecute:function(){var a=this.getInputData(0);null!=a&&this.setOutputData(0,a*this.properties.factor)}});
LiteGraph.registerNodeType("math/operation",{title:"Operation",desc:"Easy math operators",inputs:[["A","number"],["B","number"]],outputs:[["A+B","number"]],size:[80,20],properties:{A:1,B:1},setValue:function(a){"string"==typeof a&&(a=parseFloat(a));this.properties.value=a;this.setDirtyCanvas(!0)},onExecute:function(){var a=this.getInputData(0),b=this.getInputData(1);null!=a?this.properties.A=a:a=this.properties.A;null!=b?this.properties.B=b:b=this.properties.B;for(var c=0,d=this.outputs.length;c<
d;++c){var e=this.outputs[c];if(e.links&&e.links.length){switch(e.name){case "A+B":value=a+b;break;case "A-B":value=a-b;break;case "A*B":value=a*b;break;case "A/B":value=a/b}this.setOutputData(c,value)}}},onGetOutputs:function(){return[["A-B","number"],["A*B","number"],["A/B","number"]]}});
LiteGraph.registerNodeType("math/compare",{title:"Compare",desc:"compares between two values",inputs:[["A","number"],["B","number"]],outputs:[["A==B","number"],["A!=B","number"]],properties:{A:0,B:0},onExecute:function(){var a=this.getInputData(0),b=this.getInputData(1);null!=a?this.properties.A=a:a=this.properties.A;null!=b?this.properties.B=b:b=this.properties.B;for(var c=0,d=this.outputs.length;c<d;++c){var e=this.outputs[c];if(e.links&&e.links.length){switch(e.name){case "A==B":value=a==b;break;
case "A!=B":value=a!=b;break;case "A>B":value=a>b;break;case "A<B":value=a<b;break;case "A<=B":value=a<=b;break;case "A>=B":value=a>=b}this.setOutputData(c,value)}}},onGetOutputs:function(){return[["A==B","number"],["A!=B","number"],["A>B","number"],["A<B","number"],["A>=B","number"],["A<=B","number"]]}});
window.math&&LiteGraph.registerNodeType("math/formula",{title:"Formula",desc:"Compute safe formula",inputs:[["x","number"],["y","number"]],outputs:[["","number"]],properties:{x:1,y:1,formula:"x+y"},onExecute:function(){var a=this.getInputData(0),b=this.getInputData(1);null!=a?this.properties.x=a:a=this.properties.x;null!=b?this.properties.y=b:b=this.properties.y;a=math.eval(this.properties.formula,{x:a,y:b,T:this.graph.globaltime});this.setOutputData(0,a)},onDrawBackground:function(){this.outputs[0].label=
this.properties.formula},onGetOutputs:function(){return[["A-B","number"],["A*B","number"],["A/B","number"]]}});
LiteGraph.registerNodeType("math/trigonometry",{title:"Trigonometry",desc:"Sin Cos Tan",bgImageUrl:"nodes/imgs/icon-sin.png",inputs:[["v","number"]],outputs:[["sin","number"]],properties:{amplitude:1},size:[100,20],onExecute:function(){for(var a=this.getInputData(0),b=this.properties.amplitude,c=0,d=this.outputs.length;c<d;++c){switch(this.outputs[c].name){case "sin":value=Math.sin(a);break;case "cos":value=Math.cos(a);break;case "tan":value=Math.tan(a);break;case "asin":value=Math.asin(a);break;
case "acos":value=Math.acos(a);break;case "atan":value=Math.atan(a)}this.setOutputData(c,b*value)}},onGetOutputs:function(){return[["sin","number"],["cos","number"],["tan","number"],["asin","number"],["acos","number"],["atan","number"]]}});
window.glMatrix&&(LiteGraph.registerNodeType("math3d/vec3-to-xyz",{title:"Vec3->XYZ",desc:"vector 3 to components",inputs:[["vec3","vec3"]],outputs:[["x","number"],["y","number"],["z","number"]],onExecute:function(){var a=this.getInputData(0);null!=a&&(this.setOutputData(0,a[0]),this.setOutputData(1,a[1]),this.setOutputData(2,a[2]))}}),LiteGraph.registerNodeType("math3d/xyz-to-vec3",{title:"XYZ->Vec3",desc:"components to vector3",inputs:[["x","number"],["y","number"],["z","number"]],outputs:[["vec3",
"vec3"]],onExecute:function(){var a=this.getInputData(0);null==a&&(a=0);var b=this.getInputData(1);null==b&&(b=0);var c=this.getInputData(2);null==c&&(c=0);this.setOutputData(0,vec3.fromValues(a,b,c))}}),LiteGraph.registerNodeType("math3d/rotation",{title:"Rotation",desc:"rotation quaternion",inputs:[["degrees","number"],["axis","vec3"]],outputs:[["quat","quat"]],properties:{angle:90,axis:[0,1,0]},onExecute:function(){var a=this.getInputData(0);null==a&&(a=this.properties.angle);var b=this.getInputData(1);
null==b&&(b=this.properties.axis);a=quat.setAxisAngle(quat.create(),b,0.0174532925*a);this.setOutputData(0,a)}}),LiteGraph.registerNodeType("math3d/rotate_vec3",{title:"Rot. Vec3",desc:"rotate a point",inputs:[["vec3","vec3"],["quat","quat"]],outputs:[["result","vec3"]],properties:{vec:[0,0,1]},onExecute:function(){var a=this.getInputData(0);null==a&&(a=this.properties.vec);var b=this.getInputData(1);null==b?this.setOutputData(a):this.setOutputData(0,vec3.transformQuat(vec3.create(),a,b))}}),LiteGraph.registerNodeType("math3d/mult-quat",
{title:"Mult. Quat",desc:"rotate quaternion",inputs:[["A","quat"],["B","quat"]],outputs:[["A*B","quat"]],onExecute:function(){var a=this.getInputData(0);if(null!=a){var b=this.getInputData(1);null!=b&&(a=quat.multiply(quat.create(),a,b),this.setOutputData(0,a))}}}));
LiteGraph.registerNodeType("widget/knob",{title:"Knob",desc:"Circular controller",size:[64,84],outputs:[["","number"]],properties:{min:0,max:1,value:0.5,wcolor:"#7AF",size:50},widgets:[{name:"increase",text:"+",type:"minibutton"},{name:"decrease",text:"-",type:"minibutton"}],onInit:function(){this.value=(this.properties.value-this.properties.min)/(this.properties.max-this.properties.min);this.imgbg=this.loadImage("imgs/knob_bg.png");this.imgfg=this.loadImage("imgs/knob_fg.png")},onDrawImageKnob:function(a){if(this.imgfg&&
this.imgfg.width){var b=0.5*this.imgbg.width,c=this.size[0]/this.imgfg.width;a.save();a.translate(0,20);a.scale(c,c);a.drawImage(this.imgbg,0,0);a.translate(b,b);a.rotate(2*this.value*Math.PI*6/8+10*Math.PI/8);a.translate(-b,-b);a.drawImage(this.imgfg,0,0);a.restore();a.font="bold 16px Criticized,Tahoma";a.fillStyle="rgba(100,100,100,0.8)";a.textAlign="center";a.fillText(this.name.toUpperCase(),0.5*this.size[0],18);a.textAlign="left"}},onDrawVectorKnob:function(a){if(this.imgfg&&this.imgfg.width){a.lineWidth=
1;a.strokeStyle=this.mouseOver?"#FFF":"#AAA";a.fillStyle="#000";a.beginPath();a.arc(0.5*this.size[0],0.5*this.size[1]+10,0.5*this.properties.size,0,2*Math.PI,!0);a.stroke();0<this.value&&(a.strokeStyle=this.properties.wcolor,a.lineWidth=0.2*this.properties.size,a.beginPath(),a.arc(0.5*this.size[0],0.5*this.size[1]+10,0.35*this.properties.size,-0.5*Math.PI+2*Math.PI*this.value,-0.5*Math.PI,!0),a.stroke(),a.lineWidth=1);a.font=0.2*this.properties.size+"px Arial";a.fillStyle="#AAA";a.textAlign="center";
var b=this.properties.value;"number"==typeof b&&(b=b.toFixed(2));a.fillText(b,0.5*this.size[0],0.65*this.size[1]);a.textAlign="left"}},onDrawForeground:function(a){this.onDrawImageKnob(a)},onExecute:function(){this.setOutputData(0,this.properties.value);this.boxcolor=colorToString([this.value,this.value,this.value])},onMouseDown:function(a){if(this.imgfg&&this.imgfg.width){this.center=[0.5*this.size[0],0.5*this.size[1]+20];this.radius=0.5*this.size[0];if(20>a.canvasY-this.pos[1]||distance([a.canvasX,
a.canvasY],[this.pos[0]+this.center[0],this.pos[1]+this.center[1]])>this.radius)return!1;this.oldmouse=[a.canvasX-this.pos[0],a.canvasY-this.pos[1]];this.captureInput(!0);return!0}},onMouseMove:function(a){if(this.oldmouse){a=[a.canvasX-this.pos[0],a.canvasY-this.pos[1]];var b=this.value,b=b-0.01*(a[1]-this.oldmouse[1]);1<b?b=1:0>b&&(b=0);this.value=b;this.properties.value=this.properties.min+(this.properties.max-this.properties.min)*this.value;this.oldmouse=a;this.setDirtyCanvas(!0)}},onMouseUp:function(a){this.oldmouse&&
(this.oldmouse=null,this.captureInput(!1))},onMouseLeave:function(a){},onWidget:function(a,b){if("increase"==b.name)this.onPropertyChange("size",this.properties.size+10);else if("decrease"==b.name)this.onPropertyChange("size",this.properties.size-10)},onPropertyChange:function(a,b){if("wcolor"==a)this.properties[a]=b;else if("size"==a)b=parseInt(b),this.properties[a]=b,this.size=[b+4,b+24],this.setDirtyCanvas(!0,!0);else if("min"==a||"max"==a||"value"==a)this.properties[a]=parseFloat(b);else return!1;
return!0}});
LiteGraph.registerNodeType("widget/hslider",{title:"H.Slider",desc:"Linear slider controller",size:[160,26],outputs:[["","number"]],properties:{wcolor:"#7AF",min:0,max:1,value:0.5},onInit:function(){this.value=0.5;this.imgfg=this.loadImage("imgs/slider_fg.png")},onDrawVectorial:function(a){this.imgfg&&this.imgfg.width&&(a.lineWidth=1,a.strokeStyle=this.mouseOver?"#FFF":"#AAA",a.fillStyle="#000",a.beginPath(),a.rect(2,0,this.size[0]-4,20),a.stroke(),a.fillStyle=this.properties.wcolor,a.beginPath(),a.rect(2+
(this.size[0]-4-20)*this.value,0,20,20),a.fill())},onDrawImage:function(a){this.imgfg&&this.imgfg.width&&(a.lineWidth=1,a.fillStyle="#000",a.fillRect(2,9,this.size[0]-4,2),a.strokeStyle="#333",a.beginPath(),a.moveTo(2,9),a.lineTo(this.size[0]-4,9),a.stroke(),a.strokeStyle="#AAA",a.beginPath(),a.moveTo(2,11),a.lineTo(this.size[0]-4,11),a.stroke(),a.drawImage(this.imgfg,2+(this.size[0]-4)*this.value-0.5*this.imgfg.width,0.5*-this.imgfg.height+10))},onDrawForeground:function(a){this.onDrawImage(a)},
onExecute:function(){this.properties.value=this.properties.min+(this.properties.max-this.properties.min)*this.value;this.setOutputData(0,this.properties.value);this.boxcolor=colorToString([this.value,this.value,this.value])},onMouseDown:function(a){if(0>a.canvasY-this.pos[1])return!1;this.oldmouse=[a.canvasX-this.pos[0],a.canvasY-this.pos[1]];this.captureInput(!0);return!0},onMouseMove:function(a){if(this.oldmouse){a=[a.canvasX-this.pos[0],a.canvasY-this.pos[1]];var b=this.value,b=b+(a[0]-this.oldmouse[0])/
this.size[0];1<b?b=1:0>b&&(b=0);this.value=b;this.oldmouse=a;this.setDirtyCanvas(!0)}},onMouseUp:function(a){this.oldmouse=null;this.captureInput(!1)},onMouseLeave:function(a){},onPropertyChange:function(a,b){if("wcolor"==a)this.properties[a]=b;else return!1;return!0}});
LiteGraph.registerNodeType("widget/kpad",{title:"KPad",desc:"bidimensional slider",size:[200,200],outputs:[["x","number"],["y","number"]],properties:{x:0,y:0,borderColor:"#333",bgcolorTop:"#444",bgcolorBottom:"#000",shadowSize:1,borderRadius:2},createGradient:function(a){this.lineargradient=a.createLinearGradient(0,0,0,this.size[1]);this.lineargradient.addColorStop(0,this.properties.bgcolorTop);this.lineargradient.addColorStop(1,this.properties.bgcolorBottom)},onDrawBackground:function(a){this.lineargradient||
this.createGradient(a);a.lineWidth=1;a.strokeStyle=this.properties.borderColor;a.fillStyle=this.lineargradient;a.shadowColor="#000";a.shadowOffsetX=0;a.shadowOffsetY=0;a.shadowBlur=this.properties.shadowSize;a.roundRect(0,0,this.size[0],this.size[1],this.properties.shadowSize);a.fill();a.shadowColor="rgba(0,0,0,0)";a.stroke();a.fillStyle="#A00";a.fillRect(this.size[0]*this.properties.x-5,this.size[1]*this.properties.y-5,10,10)},onWidget:function(a,b){"update"==b.name&&(this.lineargradient=null,this.setDirtyCanvas(!0))},
onExecute:function(){this.setOutputData(0,this.properties.x);this.setOutputData(1,this.properties.y)},onMouseDown:function(a){if(0>a.canvasY-this.pos[1])return!1;this.oldmouse=[a.canvasX-this.pos[0],a.canvasY-this.pos[1]];this.captureInput(!0);return!0},onMouseMove:function(a){this.oldmouse&&(a=[a.canvasX-this.pos[0],a.canvasY-this.pos[1]],this.properties.x=a[0]/this.size[0],this.properties.y=a[1]/this.size[1],1<this.properties.x?this.properties.x=1:0>this.properties.x&&(this.properties.x=0),1<this.properties.y?
this.properties.y=1:0>this.properties.y&&(this.properties.y=0),this.oldmouse=a,this.setDirtyCanvas(!0))},onMouseUp:function(a){this.oldmouse&&(this.oldmouse=null,this.captureInput(!1))},onMouseLeave:function(a){}});
LiteGraph.registerNodeType("widget/button",{title:"Button",desc:"A send command button",widgets:[{name:"test",text:"Test Button",type:"button"}],size:[100,40],properties:{text:"clickme",command:"",color:"#7AF",bgcolorTop:"#f0f0f0",bgcolorBottom:"#e0e0e0",fontsize:"16"},outputs:[["M","module"]],createGradient:function(a){this.lineargradient=a.createLinearGradient(0,0,0,this.size[1]);this.lineargradient.addColorStop(0,this.properties.bgcolorTop);this.lineargradient.addColorStop(1,this.properties.bgcolorBottom)},
drawVectorShape:function(a){a.fillStyle=this.mouseOver?this.properties.color:"#AAA";this.clicking&&(a.fillStyle="#FFF");a.strokeStyle="#AAA";a.roundRect(5,5,this.size[0]-10,this.size[1]-10,4);a.stroke();this.mouseOver&&a.fill();a.fillStyle=this.mouseOver?"#000":"#AAA";a.font="bold "+this.properties.fontsize+"px Criticized,Tahoma";a.textAlign="center";a.fillText(this.properties.text,0.5*this.size[0],0.5*this.size[1]+0.5*parseInt(this.properties.fontsize));a.textAlign="left"},drawBevelShape:function(a){a.shadowColor=
"#000";a.shadowOffsetX=0;a.shadowOffsetY=0;a.shadowBlur=this.properties.shadowSize;this.lineargradient||this.createGradient(a);a.fillStyle=this.mouseOver?this.properties.color:this.lineargradient;this.clicking&&(a.fillStyle="#444");a.strokeStyle="#FFF";a.roundRect(5,5,this.size[0]-10,this.size[1]-10,4);a.fill();a.shadowColor="rgba(0,0,0,0)";a.stroke();a.fillStyle=this.mouseOver?"#000":"#444";a.font="bold "+this.properties.fontsize+"px Century Gothic";a.textAlign="center";a.fillText(this.properties.text,
0.5*this.size[0],0.5*this.size[1]+0.4*parseInt(this.properties.fontsize));a.textAlign="left"},onDrawForeground:function(a){this.drawBevelShape(a)},clickButton:function(){var a=this.getOutputModule(0);if(this.properties.command&&""!=this.properties.command)a.executeAction(this.properties.command)||this.trace("Error executing action in other module");else if(a&&a.onTrigger)a.onTrigger()},onMouseDown:function(a){if(2>a.canvasY-this.pos[1])return!1;this.clickButton();return this.clicking=!0},onMouseUp:function(a){this.clicking=
!1},onExecute:function(){},onWidget:function(a,b){"test"==b.name&&this.clickButton()},onPropertyChange:function(a,b){this.properties[a]=b;return!0}});
LiteGraph.registerNodeType("widget/progress",{title:"Progress",desc:"Shows data in linear progress",size:[160,26],inputs:[["","number"]],properties:{min:0,max:1,value:0,wcolor:"#AAF"},onExecute:function(){var a=this.getInputData(0);void 0!=a&&(this.properties.value=a)},onDrawForeground:function(a){a.lineWidth=1;a.fillStyle=this.properties.wcolor;var b=(this.properties.value-this.properties.min)/(this.properties.max-this.properties.min),b=Math.min(1,b),b=Math.max(0,b);a.fillRect(2,2,(this.size[0]-
4)*b,this.size[1]-4)}});
LiteGraph.registerNodeType("widget/text",{title:"Text",desc:"Shows the input value",widgets:[{name:"resize",text:"Resize box",type:"button"},{name:"led_text",text:"LED",type:"minibutton"},{name:"normal_text",text:"Normal",type:"minibutton"}],inputs:[["",0]],properties:{value:"...",font:"Arial",fontsize:18,color:"#AAA",align:"left",glowSize:0,decimals:1},onDrawForeground:function(a){a.fillStyle=this.properties.color;var b=this.properties.value;this.properties.glowSize?(a.shadowColor=this.properties.color,
a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=this.properties.glowSize):a.shadowColor="transparent";var c=this.properties.fontsize;a.textAlign=this.properties.align;a.font=c.toString()+"px "+this.properties.font;this.str="number"==typeof b?b.toFixed(this.properties.decimals):b;if("string"==typeof this.str){var b=this.str.split("\\n"),d;for(d in b)a.fillText(b[d],"left"==this.properties.align?15:this.size[0]-15,-0.15*c+c*(parseInt(d)+1))}a.shadowColor="transparent";this.last_ctx=a;a.textAlign="left"},
onExecute:function(){var a=this.getInputData(0);this.properties.value=null!=a?a:"";this.setDirtyCanvas(!0)},resize:function(){if(this.last_ctx){var a=this.str.split("\\n");this.last_ctx.font=this.properties.fontsize+"px "+this.properties.font;var b=0,c;for(c in a){var d=this.last_ctx.measureText(a[c]).width;b<d&&(b=d)}this.size[0]=b+20;this.size[1]=4+a.length*this.properties.fontsize;this.setDirtyCanvas(!0)}},onWidget:function(a,b){"resize"==b.name?this.resize():"led_text"==b.name?(this.properties.font=
"Digital",this.properties.glowSize=4,this.setDirtyCanvas(!0)):"normal_text"==b.name&&(this.properties.font="Arial",this.setDirtyCanvas(!0))},onPropertyChange:function(a,b){this.properties[a]=b;this.str="number"==typeof b?b.toFixed(3):b;return!0}});
LiteGraph.registerNodeType("widget/panel",{title:"Panel",desc:"Non interactive panel",widgets:[{name:"update",text:"Update",type:"button"}],size:[200,100],properties:{borderColor:"#ffffff",bgcolorTop:"#f0f0f0",bgcolorBottom:"#e0e0e0",shadowSize:2,borderRadius:3},createGradient:function(a){""==this.properties.bgcolorTop||""==this.properties.bgcolorBottom?this.lineargradient=0:(this.lineargradient=a.createLinearGradient(0,0,0,this.size[1]),this.lineargradient.addColorStop(0,this.properties.bgcolorTop),
this.lineargradient.addColorStop(1,this.properties.bgcolorBottom))},onDrawForeground:function(a){null==this.lineargradient&&this.createGradient(a);this.lineargradient&&(a.lineWidth=1,a.strokeStyle=this.properties.borderColor,a.fillStyle=this.lineargradient,this.properties.shadowSize?(a.shadowColor="#000",a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=this.properties.shadowSize):a.shadowColor="transparent",a.roundRect(0,0,this.size[0]-1,this.size[1]-1,this.properties.shadowSize),a.fill(),a.shadowColor=
"transparent",a.stroke())},onWidget:function(a,b){"update"==b.name&&(this.lineargradient=null,this.setDirtyCanvas(!0))}});
LiteGraph.registerNodeType("color/palette",{title:"Palette",desc:"Generates a color",inputs:[["f","number"]],outputs:[["Color","color"]],properties:{colorA:"#444444",colorB:"#44AAFF",colorC:"#44FFAA",colorD:"#FFFFFF"},onExecute:function(){var a=[];null!=this.properties.colorA&&a.push(hex2num(this.properties.colorA));null!=this.properties.colorB&&a.push(hex2num(this.properties.colorB));null!=this.properties.colorC&&a.push(hex2num(this.properties.colorC));null!=this.properties.colorD&&a.push(hex2num(this.properties.colorD));
var b=this.getInputData(0);null==b&&(b=0.5);1<b?b=1:0>b&&(b=0);if(0!=a.length){var c=[0,0,0];if(0==b)c=a[0];else if(1==b)c=a[a.length-1];else{var d=(a.length-1)*b,b=a[Math.floor(d)],a=a[Math.floor(d)+1],d=d-Math.floor(d);c[0]=b[0]*(1-d)+a[0]*d;c[1]=b[1]*(1-d)+a[1]*d;c[2]=b[2]*(1-d)+a[2]*d}for(var e in c)c[e]/=255;this.boxcolor=colorToString(c);this.setOutputData(0,c)}}});
LiteGraph.registerNodeType("graphics/frame",{title:"Frame",desc:"Frame viewerew",inputs:[["","image"]],size:[200,200],widgets:[{name:"resize",text:"Resize box",type:"button"},{name:"view",text:"View Image",type:"button"}],onDrawBackground:function(a){this.frame&&a.drawImage(this.frame,0,0,this.size[0],this.size[1])},onExecute:function(){this.frame=this.getInputData(0);this.setDirtyCanvas(!0)},onWidget:function(a,b){if("resize"==b.name&&this.frame){var c=this.frame.width,d=this.frame.height;c||null==
this.frame.videoWidth||(c=this.frame.videoWidth,d=this.frame.videoHeight);c&&d&&(this.size=[c,d]);this.setDirtyCanvas(!0,!0)}else"view"==b.name&&this.show()},show:function(){showElement&&this.frame&&showElement(this.frame)}});
LiteGraph.registerNodeType("visualization/graph",{desc:"Shows a graph of the inputs",inputs:[["",0],["",0],["",0],["",0]],size:[200,200],properties:{min:-1,max:1,bgColor:"#000"},onDrawBackground:function(a){var b=["#FFF","#FAA","#AFA","#AAF"];null!=this.properties.bgColor&&""!=this.properties.bgColor&&(a.fillStyle="#000",a.fillRect(2,2,this.size[0]-4,this.size[1]-4));if(this.data){var c=this.properties.min,d=this.properties.max,e;for(e in this.data){var f=this.data[e];if(f&&null!=this.getInputInfo(e)){a.strokeStyle=
b[e];a.beginPath();for(var g=f.length/this.size[0],h=0;h<f.length;h+=g){var k=f[Math.floor(h)],k=(k-c)/(d-c);1<k?k=1:0>k&&(k=0);0==h?a.moveTo(h/g,this.size[1]-5-(this.size[1]-10)*k):a.lineTo(h/g,this.size[1]-5-(this.size[1]-10)*k)}a.stroke()}}}},onExecute:function(){this.data||(this.data=[]);for(var a in this.inputs){var b=this.getInputData(a);"number"==typeof b?(b=b?b:0,this.data[a]||(this.data[a]=[]),this.data[a].push(b),this.data[a].length>this.size[1]-4&&(this.data[a]=this.data[a].slice(1,this.data[a].length))):
this.data[a]=b}this.data.length&&this.setDirtyCanvas(!0)}});
LiteGraph.registerNodeType("graphics/supergraph",{title:"Supergraph",desc:"Shows a nice circular graph",inputs:[["x","number"],["y","number"],["c","color"]],outputs:[["","image"]],widgets:[{name:"clear_alpha",text:"Clear Alpha",type:"minibutton"},{name:"clear_color",text:"Clear color",type:"minibutton"}],properties:{size:256,bgcolor:"#000",lineWidth:1},bgcolor:"#000",flags:{allow_fastrender:!0},onLoad:function(){this.createCanvas()},createCanvas:function(){this.canvas=document.createElement("canvas");
this.canvas.width=this.properties.size;this.canvas.height=this.properties.size;this.oldpos=null;this.clearCanvas(!0)},onExecute:function(){var a=this.getInputData(0),b=this.getInputData(1),c=this.getInputData(2);if(null!=a||null!=b){a||(a=0);b||(b=0);var a=0.95*a,b=0.95*b,d=this.properties.size;d==this.canvas.width&&d==this.canvas.height||this.createCanvas();if(this.oldpos){var e=this.canvas.getContext("2d");null==c?c="rgba(255,255,255,0.5)":"object"==typeof c&&(c=colorToString(c));e.strokeStyle=
c;e.beginPath();e.moveTo(this.oldpos[0],this.oldpos[1]);this.oldpos=[(0.5*a+0.5)*d,(0.5*b+0.5)*d];e.lineTo(this.oldpos[0],this.oldpos[1]);e.stroke();this.canvas.dirty=!0;this.setOutputData(0,this.canvas)}else this.oldpos=[(0.5*a+0.5)*d,(0.5*b+0.5)*d]}},clearCanvas:function(a){var b=this.canvas.getContext("2d");a?(b.clearRect(0,0,this.canvas.width,this.canvas.height),this.trace("Clearing alpha")):(b.fillStyle=this.properties.bgcolor,b.fillRect(0,0,this.canvas.width,this.canvas.height))},onWidget:function(a,
b){"clear_color"==b.name?this.clearCanvas(!1):"clear_alpha"==b.name&&this.clearCanvas(!0)},onPropertyChange:function(a,b){if("size"==a)this.properties.size=parseInt(b),this.createCanvas();else if("bgcolor"==a)this.properties.bgcolor=b,this.createCanvas();else if("lineWidth"==a)this.properties.lineWidth=parseInt(b),this.canvas.getContext("2d").lineWidth=this.properties.lineWidth;else return!1;return!0}});
LiteGraph.registerNodeType("graphics/imagefade",{title:"Image fade",desc:"Fades between images",inputs:[["img1","image"],["img2","image"],["fade","number"]],outputs:[["","image"]],properties:{fade:0.5,width:512,height:512},widgets:[{name:"resizeA",text:"Resize to A",type:"button"},{name:"resizeB",text:"Resize to B",type:"button"}],onLoad:function(){this.createCanvas();var a=this.canvas.getContext("2d");a.fillStyle="#000";a.fillRect(0,0,this.properties.width,this.properties.height)},createCanvas:function(){this.canvas=
document.createElement("canvas");this.canvas.width=this.properties.width;this.canvas.height=this.properties.height},onExecute:function(){var a=this.canvas.getContext("2d");this.canvas.width=this.canvas.width;var b=this.getInputData(0);null!=b&&a.drawImage(b,0,0,this.canvas.width,this.canvas.height);b=this.getInputData(2);null==b?b=this.properties.fade:this.properties.fade=b;a.globalAlpha=b;b=this.getInputData(1);null!=b&&a.drawImage(b,0,0,this.canvas.width,this.canvas.height);a.globalAlpha=1;this.setOutputData(0,
this.canvas);this.setDirtyCanvas(!0)}});
LiteGraph.registerNodeType("graphics/image",{title:"Image",desc:"Image loader",inputs:[],outputs:[["frame","image"]],properties:{url:""},widgets:[{name:"load",text:"Load",type:"button"}],onLoad:function(){""!=this.properties.url&&null==this.img&&this.loadImage(this.properties.url)},onStart:function(){},onExecute:function(){this.img||(this.boxcolor="#000");this.img&&this.img.width?this.setOutputData(0,this.img):this.setOutputData(0,null);this.img.dirty&&(this.img.dirty=!1)},onPropertyChange:function(a,
b){this.properties[a]=b;"url"==a&&""!=b&&this.loadImage(b);return!0},loadImage:function(a){if(""==a)this.img=null;else{this.trace("loading image...");this.img=document.createElement("img");this.img.src="miniproxy.php?url="+a;this.boxcolor="#F95";var b=this;this.img.onload=function(){b.trace("Image loaded, size: "+b.img.width+"x"+b.img.height);this.dirty=!0;b.boxcolor="#9F9";b.setDirtyCanvas(!0)}}},onWidget:function(a,b){"load"==b.name&&this.loadImage(this.properties.url)}});
LiteGraph.registerNodeType("graphics/cropImage",{title:"Crop",desc:"Crop Image",inputs:[["","image"]],outputs:[["","image"]],properties:{width:256,height:256,x:0,y:0,scale:1},size:[50,20],onLoad:function(){this.createCanvas()},createCanvas:function(){this.canvas=document.createElement("canvas");this.canvas.width=this.properties.width;this.canvas.height=this.properties.height},onExecute:function(){var a=this.getInputData(0);a&&(a.width?(this.canvas.getContext("2d").drawImage(a,-this.properties.x,-this.properties.y,
a.width*this.properties.scale,a.height*this.properties.scale),this.setOutputData(0,this.canvas)):this.setOutputData(0,null))},onPropertyChange:function(a,b){this.properties[a]=b;"scale"==a?(this.properties[a]=parseFloat(b),0==this.properties[a]&&(this.trace("Error in scale"),this.properties[a]=1)):this.properties[a]=parseInt(b);this.createCanvas();return!0}});
LiteGraph.registerNodeType("graphics/video",{title:"Video",desc:"Video playback",inputs:[["t","number"]],outputs:[["frame","image"],["t","number"],["d","number"]],properties:{url:""},widgets:[{name:"play",text:"PLAY",type:"minibutton"},{name:"stop",text:"STOP",type:"minibutton"},{name:"demo",text:"Demo video",type:"button"},{name:"mute",text:"Mute video",type:"button"}],onClick:function(a){if(this.video&&20>distance([a.canvasX,a.canvasY],[this.pos[0]+55,this.pos[1]+40]))return this.play(),!0},onKeyDown:function(a){32==
a.keyCode&&this.playPause()},onLoad:function(){""!=this.properties.url&&this.loadVideo(this.properties.url)},play:function(){this.video&&(this.trace("Video playing"),this.video.play())},playPause:function(){this.video&&(this.video.paused?this.play():this.pause())},stop:function(){this.video&&(this.trace("Video stopped"),this.video.pause(),this.video.currentTime=0)},pause:function(){this.video&&(this.trace("Video paused"),this.video.pause())},onExecute:function(){if(this.video){var a=this.getInputData(0);
a&&0<=a&&1>=a&&(this.video.currentTime=a*this.video.duration,this.video.pause());this.video.dirty=!0;this.setOutputData(0,this.video);this.setOutputData(1,this.video.currentTime);this.setOutputData(2,this.video.duration);this.setDirtyCanvas(!0)}},onStart:function(){},onStop:function(){this.pause()},loadVideo:function(a){this.video=document.createElement("video");a?this.video.src=a:(this.video.src="modules/data/video.webm",this.properties.url=this.video.src);this.video.type="type=video/mp4";this.video.muted=
!0;this.video.autoplay=!1;var b=this;this.video.addEventListener("loadedmetadata",function(a){b.trace("Duration: "+b.video.duration+" seconds");b.trace("Size: "+b.video.videoWidth+","+b.video.videoHeight);b.setDirtyCanvas(!0);this.width=this.videoWidth;this.height=this.videoHeight});this.video.addEventListener("progress",function(a){});this.video.addEventListener("error",function(a){b.trace("Error loading video: "+this.src);if(this.error)switch(this.error.code){case this.error.MEDIA_ERR_ABORTED:b.trace("You stopped the video.");
break;case this.error.MEDIA_ERR_NETWORK:b.trace("Network error - please try again later.");break;case this.error.MEDIA_ERR_DECODE:b.trace("Video is broken..");break;case this.error.MEDIA_ERR_SRC_NOT_SUPPORTED:b.trace("Sorry, your browser can't play this video.")}});this.video.addEventListener("ended",function(a){b.trace("Ended.");this.play()})},onPropertyChange:function(a,b){this.properties[a]=b;"url"==a&&""!=b&&this.loadVideo(b);return!0},onWidget:function(a,b){"demo"==b.name?this.loadVideo():"play"==
b.name&&this.video&&this.playPause();"stop"==b.name?this.stop():"mute"==b.name&&this.video&&(this.video.muted=!this.video.muted)}});
(function(){function a(){this.addOutput("value",0)}function b(){this.title="Output";this.properties={name:"input_"+(1E3*Math.random()).toFixed(),type:"number"};this.addInput("value","number")}function c(){this.subgraph=new LGraph;this.bgcolor="#FA3"}function d(){this.addOutput("value","number");this.properties={value:1};this.editable={property:"value",type:"number"}}function e(){this.size=[60,20];this.addInput("value",0,{label:""});this.addOutput("value",0,{label:""});this.properties={value:""}}a.prototype.onExecute=
function(){this.setOutputData(0,node.graph.global_inputs[this.title])};LiteGraph.registerNodeType("graph/input",a);b.prototype.onAdded=function(){this.graph.addGlobalOutput(this.properties.name,this.properties.type)};b.prototype.onExecute=function(){var a=this.getInputData(0);this.graph.setGlobalOutputData(this.properties.name,a)};LiteGraph.registerNodeType("graph/output",b);c.prototype.onExecute=function(){for(var a in this.inputs);};c.prototype.configure=function(a){LGraph.prototype.configure.call(this,
a)};LiteGraph.registerNodeType("graph/subgraph",c);d.title="Const";d.desc="Constant value";d.prototype.setValue=function(a){"string"==typeof a&&(a=parseFloat(a));this.properties.value=a;this.setDirtyCanvas(!0)};d.prototype.onExecute=function(){this.setOutputData(0,parseFloat(this.properties.value))};d.prototype.onDrawBackground=function(a){this.outputs[0].label=this.properties.value.toFixed(3)};d.prototype.onWidget=function(a,b){"value"==b.name&&this.setValue(b.value)};LiteGraph.registerNodeType("basic/const",
d);e.title="Watch";e.desc="Show value of input";e.prototype.onExecute=function(){this.properties.value=this.getInputData(0);this.setOutputData(0,this.properties.value)};e.prototype.onDrawBackground=function(a){this.inputs[0]&&null!=this.properties.value&&(this.inputs[0].label=this.properties.value.constructor===Number?this.properties.value.toFixed(3):this.properties.value)};LiteGraph.registerNodeType("basic/watch",e)})();
(function(){function a(){this.size=[64,84];this.addOutput("","number");this.properties={min:0,max:1,value:0.5,wcolor:"#7AF",size:50}}function b(){this.size=[160,26];this.addOutput("","number");this.properties={wcolor:"#7AF",min:0,max:1,value:0.5}}function c(){this.size=[160,26];this.addInput("","number");this.properties={min:0,max:1,value:0,wcolor:"#AAF"}}function d(){this.addInputs("",0);this.properties={value:"...",font:"Arial",fontsize:18,color:"#AAA",align:"left",glowSize:0,decimals:1}}function e(){this.size=
[200,100];this.properties={borderColor:"#ffffff",bgcolorTop:"#f0f0f0",bgcolorBottom:"#e0e0e0",shadowSize:2,borderRadius:3}}a.title="Knob";a.desc="Circular controller";a.widgets=[{name:"increase",text:"+",type:"minibutton"},{name:"decrease",text:"-",type:"minibutton"}];a.prototype.onAdded=function(){this.value=(this.properties.value-this.properties.min)/(this.properties.max-this.properties.min);this.imgbg=this.loadImage("imgs/knob_bg.png");this.imgfg=this.loadImage("imgs/knob_fg.png")};a.prototype.onDrawImageKnob=
function(a){if(this.imgfg&&this.imgfg.width){var b=0.5*this.imgbg.width,c=this.size[0]/this.imgfg.width;a.save();a.translate(0,20);a.scale(c,c);a.drawImage(this.imgbg,0,0);a.translate(b,b);a.rotate(2*this.value*Math.PI*6/8+10*Math.PI/8);a.translate(-b,-b);a.drawImage(this.imgfg,0,0);a.restore();a.font="bold 16px Criticized,Tahoma";a.fillStyle="rgba(100,100,100,0.8)";a.textAlign="center";a.fillText(this.name.toUpperCase(),0.5*this.size[0],18);a.textAlign="left"}};a.prototype.onDrawVectorKnob=function(a){if(this.imgfg&&
this.imgfg.width){a.lineWidth=1;a.strokeStyle=this.mouseOver?"#FFF":"#AAA";a.fillStyle="#000";a.beginPath();a.arc(0.5*this.size[0],0.5*this.size[1]+10,0.5*this.properties.size,0,2*Math.PI,!0);a.stroke();0<this.value&&(a.strokeStyle=this.properties.wcolor,a.lineWidth=0.2*this.properties.size,a.beginPath(),a.arc(0.5*this.size[0],0.5*this.size[1]+10,0.35*this.properties.size,-0.5*Math.PI+2*Math.PI*this.value,-0.5*Math.PI,!0),a.stroke(),a.lineWidth=1);a.font=0.2*this.properties.size+"px Arial";a.fillStyle=
"#AAA";a.textAlign="center";var b=this.properties.value;"number"==typeof b&&(b=b.toFixed(2));a.fillText(b,0.5*this.size[0],0.65*this.size[1]);a.textAlign="left"}};a.prototype.onDrawForeground=function(a){this.onDrawImageKnob(a)};a.prototype.onExecute=function(){this.setOutputData(0,this.properties.value);this.boxcolor=colorToString([this.value,this.value,this.value])};a.prototype.onMouseDown=function(a){if(this.imgfg&&this.imgfg.width){this.center=[0.5*this.size[0],0.5*this.size[1]+20];this.radius=
0.5*this.size[0];if(20>a.canvasY-this.pos[1]||distance([a.canvasX,a.canvasY],[this.pos[0]+this.center[0],this.pos[1]+this.center[1]])>this.radius)return!1;this.oldmouse=[a.canvasX-this.pos[0],a.canvasY-this.pos[1]];this.captureInput(!0);return!0}};a.prototype.onMouseMove=function(a){if(this.oldmouse){a=[a.canvasX-this.pos[0],a.canvasY-this.pos[1]];var b=this.value,b=b-0.01*(a[1]-this.oldmouse[1]);1<b?b=1:0>b&&(b=0);this.value=b;this.properties.value=this.properties.min+(this.properties.max-this.properties.min)*
this.value;this.oldmouse=a;this.setDirtyCanvas(!0)}};a.prototype.onMouseUp=function(a){this.oldmouse&&(this.oldmouse=null,this.captureInput(!1))};a.prototype.onMouseLeave=function(a){};a.prototype.onWidget=function(a,b){if("increase"==b.name)this.onPropertyChange("size",this.properties.size+10);else if("decrease"==b.name)this.onPropertyChange("size",this.properties.size-10)};a.prototype.onPropertyChange=function(a,b){if("wcolor"==a)this.properties[a]=b;else if("size"==a)b=parseInt(b),this.properties[a]=
b,this.size=[b+4,b+24],this.setDirtyCanvas(!0,!0);else if("min"==a||"max"==a||"value"==a)this.properties[a]=parseFloat(b);else return!1;return!0};LiteGraph.registerNodeType("widget/knob",a);b.title="H.Slider";b.desc="Linear slider controller";b.prototype.onInit=function(){this.value=0.5;this.imgfg=this.loadImage("imgs/slider_fg.png")};b.prototype.onDrawVectorial=function(a){this.imgfg&&this.imgfg.width&&(a.lineWidth=1,a.strokeStyle=this.mouseOver?"#FFF":"#AAA",a.fillStyle="#000",a.beginPath(),a.rect(2,
0,this.size[0]-4,20),a.stroke(),a.fillStyle=this.properties.wcolor,a.beginPath(),a.rect(2+(this.size[0]-4-20)*this.value,0,20,20),a.fill())};b.prototype.onDrawImage=function(a){this.imgfg&&this.imgfg.width&&(a.lineWidth=1,a.fillStyle="#000",a.fillRect(2,9,this.size[0]-4,2),a.strokeStyle="#333",a.beginPath(),a.moveTo(2,9),a.lineTo(this.size[0]-4,9),a.stroke(),a.strokeStyle="#AAA",a.beginPath(),a.moveTo(2,11),a.lineTo(this.size[0]-4,11),a.stroke(),a.drawImage(this.imgfg,2+(this.size[0]-4)*this.value-
0.5*this.imgfg.width,0.5*-this.imgfg.height+10))};b.prototype.onDrawForeground=function(a){this.onDrawImage(a)};b.prototype.onExecute=function(){this.properties.value=this.properties.min+(this.properties.max-this.properties.min)*this.value;this.setOutputData(0,this.properties.value);this.boxcolor=colorToString([this.value,this.value,this.value])};b.prototype.onMouseDown=function(a){if(0>a.canvasY-this.pos[1])return!1;this.oldmouse=[a.canvasX-this.pos[0],a.canvasY-this.pos[1]];this.captureInput(!0);
return!0};b.prototype.onMouseMove=function(a){if(this.oldmouse){a=[a.canvasX-this.pos[0],a.canvasY-this.pos[1]];var b=this.value,b=b+(a[0]-this.oldmouse[0])/this.size[0];1<b?b=1:0>b&&(b=0);this.value=b;this.oldmouse=a;this.setDirtyCanvas(!0)}};b.prototype.onMouseUp=function(a){this.oldmouse=null;this.captureInput(!1)};b.prototype.onMouseLeave=function(a){};b.prototype.onPropertyChange=function(a,b){if("wcolor"==a)this.properties[a]=b;else return!1;return!0};LiteGraph.registerNodeType("widget/hslider",
b);c.title="Progress";c.desc="Shows data in linear progress";c.prototype.onExecute=function(){var a=this.getInputData(0);void 0!=a&&(this.properties.value=a)};c.prototype.onDrawForeground=function(a){a.lineWidth=1;a.fillStyle=this.properties.wcolor;var b=(this.properties.value-this.properties.min)/(this.properties.max-this.properties.min),b=Math.min(1,b),b=Math.max(0,b);a.fillRect(2,2,(this.size[0]-4)*b,this.size[1]-4)};LiteGraph.registerNodeType("widget/progress",c);d.title="Text";d.desc="Shows the input value";
d.widgets=[{name:"resize",text:"Resize box",type:"button"},{name:"led_text",text:"LED",type:"minibutton"},{name:"normal_text",text:"Normal",type:"minibutton"}];d.prototype.onDrawForeground=function(a){a.fillStyle=this.properties.color;var b=this.properties.value;this.properties.glowSize?(a.shadowColor=this.properties.color,a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=this.properties.glowSize):a.shadowColor="transparent";var c=this.properties.fontsize;a.textAlign=this.properties.align;a.font=c.toString()+
"px "+this.properties.font;this.str="number"==typeof b?b.toFixed(this.properties.decimals):b;if("string"==typeof this.str){var b=this.str.split("\\n"),d;for(d in b)a.fillText(b[d],"left"==this.properties.align?15:this.size[0]-15,-0.15*c+c*(parseInt(d)+1))}a.shadowColor="transparent";this.last_ctx=a;a.textAlign="left"};d.prototype.onExecute=function(){var a=this.getInputData(0);this.properties.value=null!=a?a:"";this.setDirtyCanvas(!0)};d.prototype.resize=function(){if(this.last_ctx){var a=this.str.split("\\n");
this.last_ctx.font=this.properties.fontsize+"px "+this.properties.font;var b=0,c;for(c in a){var d=this.last_ctx.measureText(a[c]).width;b<d&&(b=d)}this.size[0]=b+20;this.size[1]=4+a.length*this.properties.fontsize;this.setDirtyCanvas(!0)}};d.prototype.onWidget=function(a,b){"resize"==b.name?this.resize():"led_text"==b.name?(this.properties.font="Digital",this.properties.glowSize=4,this.setDirtyCanvas(!0)):"normal_text"==b.name&&(this.properties.font="Arial",this.setDirtyCanvas(!0))};d.prototype.onPropertyChange=
function(a,b){this.properties[a]=b;this.str="number"==typeof b?b.toFixed(3):b;return!0};LiteGraph.registerNodeType("widget/text",d);e.title="Panel";e.desc="Non interactive panel";e.widgets=[{name:"update",text:"Update",type:"button"}];e.prototype.createGradient=function(a){""==this.properties.bgcolorTop||""==this.properties.bgcolorBottom?this.lineargradient=0:(this.lineargradient=a.createLinearGradient(0,0,0,this.size[1]),this.lineargradient.addColorStop(0,this.properties.bgcolorTop),this.lineargradient.addColorStop(1,
this.properties.bgcolorBottom))};e.prototype.onDrawForeground=function(a){null==this.lineargradient&&this.createGradient(a);this.lineargradient&&(a.lineWidth=1,a.strokeStyle=this.properties.borderColor,a.fillStyle=this.lineargradient,this.properties.shadowSize?(a.shadowColor="#000",a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=this.properties.shadowSize):a.shadowColor="transparent",a.roundRect(0,0,this.size[0]-1,this.size[1]-1,this.properties.shadowSize),a.fill(),a.shadowColor="transparent",a.stroke())};
e.prototype.onWidget=function(a,b){"update"==b.name&&(this.lineargradient=null,this.setDirtyCanvas(!0))};LiteGraph.registerNodeType("widget/panel",e)})();
(function(){function a(){this.addOutput("value","number");this.properties={min:0,max:1};this.size=[60,20]}function b(){this.addInput("in","number");this.addOutput("out","number");this.size=[60,20];this.properties={min:0,max:1}}function c(){this.addInput("in","number");this.addOutput("out","number");this.size=[60,20]}function d(){this.addInput("in","number");this.addOutput("out","number");this.size=[60,20]}function e(){this.addInput("in","number");this.addOutput("out","number");this.size=[60,20]}function f(){this.addInput("in",
"number",{label:""});this.addOutput("out","number",{label:""});this.size=[60,20];this.properties={factor:1}}function g(){this.addInput("A","number");this.addInput("B","number");this.addOutput("A+B","number");this.size=[80,20];this.properties={A:1,B:1}}function h(){this.addInputs("A","number");this.addInputs("B","number");this.addOutputs("A==B","number");this.addOutputs("A!=B","number");this.properties={A:0,B:0}}function l(){this.addInputs("v","number");this.addOutputs("sin","number");this.properties=
{amplitude:1};this.size=[100,20];this.bgImageUrl="nodes/imgs/icon-sin.png"}a.title="Rand";a.desc="Random number";a.prototype.onExecute=function(){var a=this.properties.min,b=this.properties.max;this._last_v=Math.random()*(b-a)+a;this.setOutputData(0,this._last_v)};a.prototype.onDrawBackground=function(a){this.outputs[0].label=this._last_v?this._last_v.toFixed(3):"?"};LiteGraph.registerNodeType("math/rand",a);b.title="Clamp";b.desc="Clamp number between min and max";b.prototype.onExecute=function(){var a=
this.getInputData(0);null!=a&&(a=Math.max(this.properties.min,a),a=Math.min(this.properties.max,a),this.setOutputData(0,a))};LiteGraph.registerNodeType("math/clamp",b);c.title="Abs";c.desc="Absolute";c.prototype.onExecute=function(){var a=this.getInputData(0);null!=a&&this.setOutputData(0,Math.abs(a))};LiteGraph.registerNodeType("math/abs",c);d.title="Floor";d.desc="Floor number to remove fractional part";d.prototype.onExecute=function(){var a=this.getInputData(0);null!=a&&this.setOutputData(0,a|
1)};LiteGraph.registerNodeType("math/floor",d);e.title="Frac";e.desc="Returns fractional part";e.prototype.onExecute=function(){var a=this.getInputData(0);null!=a&&this.setOutputData(0,a%1)};LiteGraph.registerNodeType("math/frac",e);f.title="Scale";f.desc="v * factor";f.prototype.onExecute=function(){var a=this.getInputData(0);null!=a&&this.setOutputData(0,a*this.properties.factor)};LiteGraph.registerNodeType("math/scale",f);g.title="Operation";g.desc="Easy math operators";g.prototype.setValue=function(a){"string"==
typeof a&&(a=parseFloat(a));this.properties.value=a;this.setDirtyCanvas(!0)};g.prototype.onExecute=function(){var a=this.getInputData(0),b=this.getInputData(1);null!=a?this.properties.A=a:a=this.properties.A;null!=b?this.properties.B=b:b=this.properties.B;for(var c=0,d=this.outputs.length;c<d;++c){var e=this.outputs[c];if(e.links&&e.links.length){var f=0;switch(e.name){case "A+B":f=a+b;break;case "A-B":f=a-b;break;case "A*B":f=a*b;break;case "A/B":f=a/b}this.setOutputData(c,f)}}};g.prototype.onGetOutputs=
function(){return[["A-B","number"],["A*B","number"],["A/B","number"]]};LiteGraph.registerNodeType("math/operation",g);h.title="Compare";h.desc="compares between two values";h.prototype.onExecute=function(){var a=this.getInputData(0),b=this.getInputData(1);null!=a?this.properties.A=a:a=this.properties.A;null!=b?this.properties.B=b:b=this.properties.B;for(var c=0,d=this.outputs.length;c<d;++c){var e=this.outputs[c];if(e.links&&e.links.length){switch(e.name){case "A==B":value=a==b;break;case "A!=B":value=
a!=b;break;case "A>B":value=a>b;break;case "A<B":value=a<b;break;case "A<=B":value=a<=b;break;case "A>=B":value=a>=b}this.setOutputData(c,value)}}};h.prototype.onGetOutputs=function(){return[["A==B","number"],["A!=B","number"],["A>B","number"],["A<B","number"],["A>=B","number"],["A<=B","number"]]};LiteGraph.registerNodeType("math/compare",h);l.title="Trigonometry";l.desc="Sin Cos Tan";l.prototype.onExecute=function(){for(var a=this.getInputData(0),b=this.properties.amplitude,c=0,d=this.outputs.length;c<
d;++c){switch(this.outputs[c].name){case "sin":value=Math.sin(a);break;case "cos":value=Math.cos(a);break;case "tan":value=Math.tan(a);break;case "asin":value=Math.asin(a);break;case "acos":value=Math.acos(a);break;case "atan":value=Math.atan(a)}this.setOutputData(c,b*value)}};l.prototype.onGetOutputs=function(){return[["sin","number"],["cos","number"],["tan","number"],["asin","number"],["acos","number"],["atan","number"]]};LiteGraph.registerNodeType("math/trigonometry",l);if(window.math){var k=function(){this.addInputs("x",
"number");this.addInputs("y","number");this.addOutputs("","number");this.properties={x:1,y:1,formula:"x+y"}};k.title="Formula";k.desc="Compute safe formula";k.prototype.onExecute=function(){var a=this.getInputData(0),b=this.getInputData(1);null!=a?this.properties.x=a:a=this.properties.x;null!=b?this.properties.y=b:b=this.properties.y;a=math.eval(this.properties.formula,{x:a,y:b,T:this.graph.globaltime});this.setOutputData(0,a)};k.prototype.onDrawBackground=function(){this.outputs[0].label=this.properties.formula};
k.prototype.onGetOutputs=function(){return[["A-B","number"],["A*B","number"],["A/B","number"]]};LiteGraph.registerNodeType("math/formula",k)}window.glMatrix&&(k=function(){this.addInput("vec3","vec3");this.addOutput("x","number");this.addOutput("y","number");this.addOutput("z","number")},k.title="Vec3->XYZ",k.desc="vector 3 to components",k.prototype.onExecute=function(){var a=this.getInputData(0);null!=a&&(this.setOutputData(0,a[0]),this.setOutputData(1,a[1]),this.setOutputData(2,a[2]))},LiteGraph.registerNodeType("math3d/vec3-to-xyz",
k),k=function(){this.addInputs([["x","number"],["y","number"],["z","number"]]);this.addOutput("vec3","vec3")},k.title="XYZ->Vec3",k.desc="components to vector3",k.prototype.onExecute=function(){var a=this.getInputData(0);null==a&&(a=0);var b=this.getInputData(1);null==b&&(b=0);var c=this.getInputData(2);null==c&&(c=0);this.setOutputData(0,vec3.fromValues(a,b,c))},LiteGraph.registerNodeType("math3d/xyz-to-vec3",k),k=function(){this.addInputs([["degrees","number"],["axis","vec3"]]);this.addOutput("quat",
"quat");this.properties={angle:90,axis:vec3.fromValues(0,1,0)}},k.title="Rotation",k.desc="quaternion rotation",k.prototype.onExecute=function(){var a=this.getInputData(0);null==a&&(a=this.properties.angle);var b=this.getInputData(1);null==b&&(b=this.properties.axis);a=quat.setAxisAngle(quat.create(),b,0.0174532925*a);this.setOutputData(0,a)},LiteGraph.registerNodeType("math3d/rotation",k),k=function(){this.addInputs([["vec3","vec3"],["quat","quat"]]);this.addOutput("result","vec3");this.properties=
{vec:[0,0,1]}},k.title="Rot. Vec3",k.desc="rotate a point",k.prototype.onExecute=function(){var a=this.getInputData(0);null==a&&(a=this.properties.vec);var b=this.getInputData(1);null==b?this.setOutputData(a):this.setOutputData(0,vec3.transformQuat(vec3.create(),a,b))},LiteGraph.registerNodeType("math3d/rotate_vec3",k),k=function(){this.addInputs([["A","quat"],["B","quat"]]);this.addOutput("A*B","quat")},k.title="Mult. Quat",k.desc="rotate quaternion",k.prototype.onExecute=function(){var a=this.getInputData(0);
if(null!=a){var b=this.getInputData(1);null!=b&&(a=quat.multiply(quat.create(),a,b),this.setOutputData(0,a))}},LiteGraph.registerNodeType("math3d/mult-quat",k))})();
(function(){function a(){this.addInput("f","number");this.addOutput("Color","color");this.properties={colorA:"#444444",colorB:"#44AAFF",colorC:"#44FFAA",colorD:"#FFFFFF"}}function b(){this.addInput("","image");this.size=[200,200]}function c(){this.addInputs([["img1","image"],["img2","image"],["fade","number"]]);this.addInput("","image");this.properties={fade:0.5,width:512,height:512}}function d(){this.inputs=[];this.addOutput("frame","image");this.properties={url:""}}function e(){this.addInput("",
"image");this.addOutputs("","image");this.properties={width:256,height:256,x:0,y:0,scale:1};this.size=[50,20]}function f(){this.addInput("t","number");this.addOutputs([["frame","image"],["t","number"],["d","number"]]);this.properties={url:""}}function g(){this.addOutput("Webcam","image");this.properties={}}a.title="Palette";a.desc="Generates a color";a.prototype.onExecute=function(){var a=[];null!=this.properties.colorA&&a.push(hex2num(this.properties.colorA));null!=this.properties.colorB&&a.push(hex2num(this.properties.colorB));
null!=this.properties.colorC&&a.push(hex2num(this.properties.colorC));null!=this.properties.colorD&&a.push(hex2num(this.properties.colorD));var b=this.getInputData(0);null==b&&(b=0.5);1<b?b=1:0>b&&(b=0);if(0!=a.length){var c=[0,0,0];if(0==b)c=a[0];else if(1==b)c=a[a.length-1];else{var d=(a.length-1)*b,b=a[Math.floor(d)],a=a[Math.floor(d)+1],d=d-Math.floor(d);c[0]=b[0]*(1-d)+a[0]*d;c[1]=b[1]*(1-d)+a[1]*d;c[2]=b[2]*(1-d)+a[2]*d}for(var e in c)c[e]/=255;this.boxcolor=colorToString(c);this.setOutputData(0,
c)}};LiteGraph.registerNodeType("color/palette",a);b.title="Frame";b.desc="Frame viewerew";b.widgets=[{name:"resize",text:"Resize box",type:"button"},{name:"view",text:"View Image",type:"button"}];b.prototype.onDrawBackground=function(a){this.frame&&a.drawImage(this.frame,0,0,this.size[0],this.size[1])};b.prototype.onExecute=function(){this.frame=this.getInputData(0);this.setDirtyCanvas(!0)};b.prototype.onWidget=function(a,b){if("resize"==b.name&&this.frame){var c=this.frame.width,d=this.frame.height;
c||null==this.frame.videoWidth||(c=this.frame.videoWidth,d=this.frame.videoHeight);c&&d&&(this.size=[c,d]);this.setDirtyCanvas(!0,!0)}else"view"==b.name&&this.show()};b.prototype.show=function(){showElement&&this.frame&&showElement(this.frame)};LiteGraph.registerNodeType("graphics/frame",b);c.title="Image fade";c.desc="Fades between images";c.widgets=[{name:"resizeA",text:"Resize to A",type:"button"},{name:"resizeB",text:"Resize to B",type:"button"}];c.prototype.onAdded=function(){this.createCanvas();
var a=this.canvas.getContext("2d");a.fillStyle="#000";a.fillRect(0,0,this.properties.width,this.properties.height)};c.prototype.createCanvas=function(){this.canvas=document.createElement("canvas");this.canvas.width=this.properties.width;this.canvas.height=this.properties.height};c.prototype.onExecute=function(){var a=this.canvas.getContext("2d");this.canvas.width=this.canvas.width;var b=this.getInputData(0);null!=b&&a.drawImage(b,0,0,this.canvas.width,this.canvas.height);b=this.getInputData(2);null==
b?b=this.properties.fade:this.properties.fade=b;a.globalAlpha=b;b=this.getInputData(1);null!=b&&a.drawImage(b,0,0,this.canvas.width,this.canvas.height);a.globalAlpha=1;this.setOutputData(0,this.canvas);this.setDirtyCanvas(!0)};LiteGraph.registerNodeType("graphics/imagefade",c);d.title="Image";d.desc="Image loader";d.widgets=[{name:"load",text:"Load",type:"button"}];d.prototype.onAdded=function(){""!=this.properties.url&&null==this.img&&this.loadImage(this.properties.url)};d.prototype.onExecute=function(){this.img||
(this.boxcolor="#000");this.img&&this.img.width?this.setOutputData(0,this.img):this.setOutputData(0,null);this.img.dirty&&(this.img.dirty=!1)};d.prototype.onPropertyChange=function(a,b){this.properties[a]=b;"url"==a&&""!=b&&this.loadImage(b);return!0};d.prototype.loadImage=function(a){if(""==a)this.img=null;else{this.trace("loading image...");this.img=document.createElement("img");this.img.src="miniproxy.php?url="+a;this.boxcolor="#F95";var b=this;this.img.onload=function(){b.trace("Image loaded, size: "+
b.img.width+"x"+b.img.height);this.dirty=!0;b.boxcolor="#9F9";b.setDirtyCanvas(!0)}}};d.prototype.onWidget=function(a,b){"load"==b.name&&this.loadImage(this.properties.url)};LiteGraph.registerNodeType("graphics/image",d);e.title="Crop";e.desc="Crop Image";e.prototype.onAdded=function(){this.createCanvas()};e.prototype.createCanvas=function(){this.canvas=document.createElement("canvas");this.canvas.width=this.properties.width;this.canvas.height=this.properties.height};e.prototype.onExecute=function(){var a=
this.getInputData(0);a&&(a.width?(this.canvas.getContext("2d").drawImage(a,-this.properties.x,-this.properties.y,a.width*this.properties.scale,a.height*this.properties.scale),this.setOutputData(0,this.canvas)):this.setOutputData(0,null))};e.prototype.onPropertyChange=function(a,b){this.properties[a]=b;"scale"==a?(this.properties[a]=parseFloat(b),0==this.properties[a]&&(this.trace("Error in scale"),this.properties[a]=1)):this.properties[a]=parseInt(b);this.createCanvas();return!0};LiteGraph.registerNodeType("graphics/cropImage",
c);f.title="Video";f.desc="Video playback";f.widgets=[{name:"play",text:"PLAY",type:"minibutton"},{name:"stop",text:"STOP",type:"minibutton"},{name:"demo",text:"Demo video",type:"button"},{name:"mute",text:"Mute video",type:"button"}];f.prototype.onExecute=function(){if(this.properties.url&&(this.properties.url!=this._video_url&&this.loadVideo(this.properties.url),this._video&&0!=this._video.width)){var a=this.getInputData(0);a&&0<=a&&1>=a&&(this._video.currentTime=a*this._video.duration,this._video.pause());
this._video.dirty=!0;this.setOutputData(0,this._video);this.setOutputData(1,this._video.currentTime);this.setOutputData(2,this._video.duration);this.setDirtyCanvas(!0)}};f.prototype.onStart=function(){this.play()};f.prototype.onStop=function(){this.stop()};f.prototype.loadVideo=function(a){this._video_url=a;this._video=document.createElement("video");this._video.src=a;this._video.type="type=video/mp4";this._video.muted=!0;this._video.autoplay=!0;var b=this;this._video.addEventListener("loadedmetadata",
function(a){b.trace("Duration: "+this.duration+" seconds");b.trace("Size: "+this.videoWidth+","+this.videoHeight);b.setDirtyCanvas(!0);this.width=this.videoWidth;this.height=this.videoHeight});this._video.addEventListener("progress",function(a){});this._video.addEventListener("error",function(a){console.log("Error loading video: "+this.src);b.trace("Error loading video: "+this.src);if(this.error)switch(this.error.code){case this.error.MEDIA_ERR_ABORTED:b.trace("You stopped the video.");break;case this.error.MEDIA_ERR_NETWORK:b.trace("Network error - please try again later.");
break;case this.error.MEDIA_ERR_DECODE:b.trace("Video is broken..");break;case this.error.MEDIA_ERR_SRC_NOT_SUPPORTED:b.trace("Sorry, your browser can't play this video.")}});this._video.addEventListener("ended",function(a){b.trace("Ended.");this.play()})};f.prototype.onPropertyChange=function(a,b){this.properties[a]=b;"url"==a&&""!=b&&this.loadVideo(b);return!0};f.prototype.play=function(){this._video&&this._video.play()};f.prototype.playPause=function(){this._video&&(this._video.paused?this.play():
this.pause())};f.prototype.stop=function(){this._video&&(this._video.pause(),this._video.currentTime=0)};f.prototype.pause=function(){this._video&&(this.trace("Video paused"),this._video.pause())};f.prototype.onWidget=function(a,b){};LiteGraph.registerNodeType("graphics/video",f);g.title="Webcam";g.desc="Webcam image";g.prototype.openStream=function(){function a(c){trace("Webcam rejected",c);b._webcam_stream=!1;b.box_color="red"}navigator.getUserMedia=navigator.getUserMedia||navigator.webkitGetUserMedia||
navigator.mozGetUserMedia||navigator.msGetUserMedia;window.URL=window.URL||window.webkitURL;if(navigator.getUserMedia){this._waiting_confirmation=!0;navigator.getUserMedia({video:!0},this.streamReady.bind(this),a);var b=this}};g.prototype.streamReady=function(a){this._webcam_stream=a;var b=this._video;b||(b=document.createElement("video"),b.autoplay=!0,b.src=window.URL.createObjectURL(a),this._video=b,b.onloadedmetadata=function(a){console.log(a)})};g.prototype.onExecute=function(){null!=this._webcam_stream||
this._waiting_confirmation||this.openStream();this._video&&this._video.videoWidth&&(this._video.width=this._video.videoWidth,this._video.hieght=this._video.videoHeight,this.setOutputData(0,this._video))};LiteGraph.registerNodeType("graphics/webcam",g)})();

BIN
demo/demodata/video.webm Normal file

Binary file not shown.

View File

@@ -64,9 +64,10 @@
<script type="text/javascript" src="../src/litegraph.js"></script>
<script type="text/javascript" src="../src/litegraph-editor.js"></script>
<script type="text/javascript" src="../src/nodes/basicnodes.js"></script>
<script type="text/javascript" src="../src/nodes/uinodes.js"></script>
<script type="text/javascript" src="../src/nodes/imagenodes.js"></script>
<script type="text/javascript" src="../src/nodes/base.js"></script>
<script type="text/javascript" src="../src/nodes/math.js"></script>
<script type="text/javascript" src="../src/nodes/interface.js"></script>
<script type="text/javascript" src="../src/nodes/image.js"></script>
<script type="text/javascript" src="demo.js"></script>
<script type="text/javascript" src="code.js"></script>

View File

@@ -28,6 +28,7 @@ var LiteGraph = {
node_images_path: "",
debug: false,
throw_errors: true,
registered_node_types: {},
/**
@@ -39,13 +40,10 @@ var LiteGraph = {
registerNodeType: function(type, base_class)
{
var title = type;
if(base_class.prototype && base_class.prototype.title)
title = base_class.prototype.title;
else if(base_class.title)
title = base_class.title;
if(!base_class.prototype)
throw("Cannot register a simple object, it must be a class with a prototype");
base_class.type = type;
if(LiteGraph.debug)
console.log("Node registered: " + type);
@@ -55,13 +53,13 @@ var LiteGraph = {
base_class.category = type.substr(0,pos);
//info.name = name.substr(pos+1,name.length - pos);
//inheritance
//extend class
if(base_class.prototype) //is a class
for(var i in LGraphNode.prototype)
if(!base_class.prototype[i])
base_class.prototype[i] = LGraphNode.prototype[i];
this.registered_node_types[type] = base_class;
this.registered_node_types[ type ] = base_class;
},
/**
@@ -72,7 +70,7 @@ var LiteGraph = {
* @param {Object} options to set options
*/
createNode: function(type,name, options)
createNode: function(type, title, options)
{
var base_class = this.registered_node_types[type];
if (!base_class)
@@ -84,9 +82,11 @@ var LiteGraph = {
var prototype = base_class.prototype || base_class;
name = name || prototype.title || base_class.title || type;
title = title || base_class.title || type;
var node = null;
var node = new base_class( name );
/*
if (base_class.prototype) //is a class
{
node = new base_class(name);
@@ -123,9 +123,10 @@ var LiteGraph = {
//set size
if(base_class.size) node.size = base_class.size.concat(); //save size
}
*/
node.type = type;
if(!node.name) node.name = name;
if(!node.title) node.title = title;
if(!node.flags) node.flags = {};
if(!node.size) node.size = node.computeSize();
if(!node.pos) node.pos = LiteGraph.DEFAULT_POSITION.concat();
@@ -238,6 +239,7 @@ var LiteGraph = {
//separated just to improve if it doesnt work
cloneObject: function(obj, target)
{
if(obj == null) return null;
var r = JSON.parse( JSON.stringify( obj ) );
if(!target) return r;
@@ -245,52 +247,11 @@ var LiteGraph = {
target[i] = r[i];
return target;
}
/*
benchmark: function(mode)
{
mode = mode || "all";
trace("Benchmarking " + mode + "...");
trace(" Num. nodes: " + this._nodes.length );
var links = 0;
for(var i in this._nodes)
for(var j in this._nodes[i].outputs)
if(this._nodes[i].outputs[j].node_id != null)
links++;
trace(" Num. links: " + links );
var numTimes = 200;
if(mode == "core")
numTimes = 30000;
var start = new Date().getTime();
for(var i = 0; i < numTimes; i++)
{
if(mode == "render")
this.draw(false);
else if(mode == "core")
this.sendEventToAllNodes("onExecute");
else
{
this.sendEventToAllNodes("onExecute");
this.draw(false);
}
}
var elapsed = (new Date().getTime()) - start;
trace(" Time take for " + numTimes + " iterations: " + (elapsed*0.001).toFixed(3) + " seconds.");
var seconds_per_iteration = (elapsed*0.001)/numTimes;
trace(" Time per iteration: " + seconds_per_iteration.toFixed( seconds_per_iteration < 0.001 ? 6 : 3) + " seconds");
trace(" Avg FPS: " + (1000/(elapsed/numTimes)).toFixed(3));
}
*/
};
//*********************************************************************************
// LGraph CLASS
@@ -311,6 +272,12 @@ function LGraph()
this.clear();
}
//default supported types
LGraph.supported_types = ["number","string","boolean"];
//used to know which types of connections support this graph (some graphs do not allow certain types)
LGraph.prototype.getSupportedTypes = function() { return this.supported_types || LGraph.supported_types; }
LGraph.STATUS_STOPPED = 1;
LGraph.STATUS_RUNNING = 2;
@@ -348,7 +315,8 @@ LGraph.prototype.clear = function()
this.starttime = 0;
//globals
this.globals = {};
this.global_inputs = {};
this.global_outputs = {};
this.graph = {};
this.debug = true;
@@ -671,16 +639,19 @@ LGraph.prototype.add = function(node)
node.bgImage = node.loadImage(node.bgImageUrl);
*/
if(node.onInit)
node.onInit();
if(node.onAdded)
node.onAdded();
if(this.config.align_to_grid)
node.alignToGrid();
this.updateExecutionOrder();
this.updateExecutionOrder();
if(this.canvas)
this.canvas.dirty_canvas = true;
if(this.onNodeAdded)
this.onNodeAdded(node);
this.setDirtyCanvas(true);
this.change();
@@ -722,16 +693,19 @@ LGraph.prototype.remove = function(node)
node.id = -1;
//callback
if(node.onDelete)
node.onDelete();
if(node.onRemoved)
node.onRemoved();
//remove from environment
if(this.canvas)
node.graph = null;
//remove from canvas render
for(var i in this.list_of_graphcanvas)
{
if(this.canvas.selected_nodes[node.id])
delete this.canvas.selected_nodes[node.id];
if(this.canvas.node_dragged == node)
this.canvas.node_dragged = null;
var canvas = this.list_of_graphcanvas[i];
if(canvas.selected_nodes[node.id])
delete canvas.selected_nodes[node.id];
if(canvas.node_dragged == node)
canvas.node_dragged = null;
}
//remove from containers
@@ -740,8 +714,10 @@ LGraph.prototype.remove = function(node)
this._nodes.splice(pos,1);
delete this._nodes_by_id[node.id];
if(this.canvas)
this.canvas.setDirty(true,true);
if(this.onNodeRemoved)
this.onNodeRemoved(node);
this.setDirtyCanvas(true,true);
this.change();
@@ -784,11 +760,11 @@ LGraph.prototype.findNodesByType = function(type)
* @return {Array} a list with all the nodes with this name
*/
LGraph.prototype.findNodesByName = function(name)
LGraph.prototype.findNodesByTitle = function(title)
{
var result = [];
for (var i in this._nodes)
if(this._nodes[i].name == name)
if(this._nodes[i].title == title)
result.push(this._nodes[i]);
return result;
}
@@ -814,6 +790,47 @@ LGraph.prototype.getNodeOnPos = function(x,y, nodes_list)
return null;
}
//Tell this graph has a global input of this type
LGraph.prototype.addGlobalInput = function(name, type, value)
{
this.global_inputs[name] = { type: type, value: value };
}
//assign a data to the global input
LGraph.prototype.setGlobalInputData = function(name, data)
{
var input = this.global_inputs[name];
if (!input)
return;
input.value = data;
}
//rename the global input
LGraph.prototype.renameGlobalInput = function(old_name, name, data)
{
}
LGraph.prototype.addGlobalOutput = function(name, type, value)
{
this.global_outputs[name] = { type: type, value: value };
}
//assign a data to the global output
LGraph.prototype.setGlobalOutputData = function(name, data)
{
var output = this.global_outputs[ name ];
if (!output)
return;
output.value = data;
}
//rename the global output
LGraph.prototype.renameGlobalOutput = function(old_name, name, data)
{
}
/**
* Assigns a value to all the nodes that matches this name. This is used to create global variables of the node that
* can be easily accesed from the outside of the graph
@@ -873,8 +890,12 @@ LGraph.prototype.onConnectionChange = function()
LGraph.prototype.isLive = function()
{
if(!this.canvas) return false;
return this.canvas.live_mode;
for(var i in this.list_of_graphcanvas)
{
var c = this.list_of_graphcanvas[i];
if(c.live_mode) return true;
}
return false;
}
/* Called when something visually changed */
@@ -889,6 +910,11 @@ LGraph.prototype.change = function()
this.on_change(this);
}
LGraph.prototype.setDirtyCanvas = function(fg,bg)
{
this.sendActionToCanvas("setDirty",[fg,bg]);
}
//save and recover app state ***************************************
/**
* Creates a Object containing all the info about this graph, it can be serialized
@@ -940,7 +966,7 @@ LGraph.prototype.configure = function(data, keep_old)
for (var i in nodes)
{
var n_info = nodes[i]; //stored info
var n = LiteGraph.createNode( n_info.type, n_info.name );
var n = LiteGraph.createNode( n_info.type, n_info.title );
if(!n)
{
if(LiteGraph.debug)
@@ -953,17 +979,13 @@ LGraph.prototype.configure = function(data, keep_old)
this.add(n);
}
//TODO: dispatch redraw
if(this.canvas)
this.canvas.draw(true,true);
this.setDirtyCanvas(true,true);
return error;
}
LGraph.prototype.onNodeTrace = function(node, msg, color)
{
if(this.canvas)
this.canvas.onNodeTrace(node,msg,color);
//TODO
}
// *************************************************************
@@ -976,18 +998,21 @@ LGraph.prototype.onNodeTrace = function(node, msg, color)
+ unsafe_execution: not allowed for safe execution
supported callbacks:
+ onInit: when added to graph
+ onAdded: when added to graph
+ onRemoved: when removed from graph
+ onStart: when starts playing
+ onStop: when stops playing
+ onDrawForeground
+ onDrawBackground
+ onDrawForeground: render the inside widgets inside the node
+ onDrawBackground: render the background area inside the node (only in edit mode)
+ onMouseDown
+ onMouseMove
+ onMouseOver
+ onMouseUp
+ onMouseEnter
+ onMouseLeave
+ onExecute: execute the node
+ onPropertyChange: when a property is changed in the panel (return true to skip default behaviour)
+ onGetInputs: returns an array of possible inputs
+ onGetOutputs: returns an array of possible outputs
+ onClick
+ onDblClick
+ onSerialize
+ onSelected
@@ -1000,9 +1025,9 @@ LGraph.prototype.onNodeTrace = function(node, msg, color)
* @param {String} name a name for the node
*/
function LGraphNode(name)
function LGraphNode(title)
{
this.name = name || "Unnamed";
this.title = title || "Unnamed";
this.size = [LiteGraph.NODE_WIDTH,60];
this.graph = null;
@@ -1079,17 +1104,19 @@ LGraphNode.prototype.serialize = function()
{
var o = {
id: this.id,
name: this.name,
title: this.title,
type: this.type,
pos: this.pos,
size: this.size,
data: this.data,
properties: LiteGraph.cloneObject(this.properties),
flags: LiteGraph.cloneObject(this.flags),
inputs: this.inputs,
outputs: this.outputs
};
if(this.properties)
o.properties = LiteGraph.cloneObject(this.properties);
if(!o.type)
o.type = this.constructor.type;
@@ -1116,8 +1143,8 @@ LGraphNode.prototype.reducedObjectivize = function()
var type = LiteGraph.getNodeType(o.type);
if(type.name == o.name)
delete o["name"];
if(type.title == o.title)
delete o["title"];
if(type.size && compareObjects(o.size,type.size))
delete o["size"];
@@ -1141,6 +1168,18 @@ LGraphNode.prototype.toString = function()
//LGraphNode.prototype.unserialize = function(info) {} //this cannot be done from within, must be done in LiteGraph
/**
* get the title string
* @method getTitle
*/
LGraphNode.prototype.getTitle = function()
{
return this.title || this.constructor.title;
}
// Execution *************************
/**
* sets the output data
@@ -1274,6 +1313,29 @@ LGraphNode.prototype.addOutput = function(name,type,extra_info)
this.size = this.computeSize();
}
/**
* add a new output slot to use in this node
* @method addOutputs
* @param {Array} array of triplets like [[name,type,extra_info],[...]]
*/
LGraphNode.prototype.addOutputs = function(array)
{
for(var i in array)
{
var info = array[i];
var o = {name:info[0],type:info[1],link:null};
if(array[2])
for(var j in info[2])
o[j] = info[2][j];
if(!this.outputs)
this.outputs = [];
this.outputs.push(o);
}
this.size = this.computeSize();
}
/**
* remove an existing output slot
* @method removeOutput
@@ -1305,6 +1367,29 @@ LGraphNode.prototype.addInput = function(name,type,extra_info)
this.size = this.computeSize();
}
/**
* add several new input slots in this node
* @method addInputs
* @param {Array} array of triplets like [[name,type,extra_info],[...]]
*/
LGraphNode.prototype.addInputs = function(array)
{
for(var i in array)
{
var info = array[i];
var o = {name:info[0],type:info[1],link:null};
if(array[2])
for(var j in info[2])
o[j] = info[2][j];
if(!this.inputs)
this.inputs = [];
this.inputs.push(o);
}
this.size = this.computeSize();
}
/**
* remove an existing input slot
* @method removeInput
@@ -1520,7 +1605,7 @@ LGraphNode.prototype.disconnectOutput = function(slot, target_node)
{
output.links.splice(i,1); //remove here
target_node.inputs[ link[4] ].link = null; //remove there
delete this.graph.links[link[0]];
delete this.graph.links[link[0]]; //remove the link from the links pool
break;
}
}
@@ -1749,7 +1834,7 @@ LGraphNode.prototype.captureInput = function(v)
//change
c.node_capturing_input = v ? this : null;
if(this.graph.debug)
console.log(this.name + ": Capturing input " + (v?"ON":"OFF"));
console.log(this.title + ": Capturing input " + (v?"ON":"OFF"));
}
}
@@ -2328,8 +2413,8 @@ LGraphCanvas.prototype.processMouseMove = function(e)
n.pos[0] += delta[0] / this.scale;
n.pos[1] += delta[1] / this.scale;
n.pos[0] = Math.round(n.pos[0]);
n.pos[1] = Math.round(n.pos[1]);
//n.pos[0] = Math.round(n.pos[0]);
//n.pos[1] = Math.round(n.pos[1]);
}
this.dirty_canvas = true;
@@ -2422,7 +2507,8 @@ LGraphCanvas.prototype.processMouseUp = function(e)
{
this.dirty_canvas = true;
this.dirty_bgcanvas = true;
this.node_dragged.pos[0] = Math.round(this.node_dragged.pos[0]);
this.node_dragged.pos[1] = Math.round(this.node_dragged.pos[1]);
if(this.graph.config.align_to_grid)
this.node_dragged.alignToGrid();
this.node_dragged = null;
@@ -3009,10 +3095,10 @@ LGraphCanvas.prototype.drawNode = function(node, ctx )
}
else if(this.render_shadows)
{
ctx.shadowColor = "#111";
ctx.shadowColor = "rgba(0,0,0,0.5)";
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.shadowBlur = 4;
ctx.shadowBlur = 3;
}
else
ctx.shadowColor = "transparent";
@@ -3269,10 +3355,11 @@ LGraphCanvas.prototype.drawNodeShape = function(node, ctx, size, fgcolor, bgcolo
//title text
ctx.font = this.title_text_font;
if(node.name != "" && this.scale > 0.8)
var title = node.getTitle();
if(title && this.scale > 0.8)
{
ctx.fillStyle = "#222";
ctx.fillText(node.name,16,13-title_height );
ctx.fillText( title, 16, 13 - title_height );
}
}
}
@@ -3385,7 +3472,7 @@ LGraphCanvas.prototype.renderLink = function(ctx,a,b,color)
var dist = distance(a,b);
if(this.render_connections_border)
if(this.render_connections_border && this.scale > 0.6)
ctx.lineWidth = this.connections_width + 4;
ctx.beginPath();
@@ -3405,7 +3492,7 @@ LGraphCanvas.prototype.renderLink = function(ctx,a,b,color)
ctx.lineTo(b[0]-10,b[1]);
}
if(this.render_connections_border)
if(this.render_connections_border && this.scale > 0.6)
{
ctx.strokeStyle = "rgba(0,0,0,0.5)";
ctx.stroke();
@@ -3688,7 +3775,7 @@ LGraphCanvas.onMenuNodeOutputs = function(node, e, prev_menu)
LGraphCanvas.onMenuNodeCollapse = function(node)
{
node.flags.collapsed = !node.flags.collapsed;
node.graph.canvas.setDirty(true,true);
node.setDirtyCanvas(true,true);
}
LGraphCanvas.onMenuNodePin = function(node)
@@ -3715,7 +3802,7 @@ LGraphCanvas.onMenuNodeColors = function(node, e, prev_menu)
{
node.color = color.color;
node.bgcolor = color.bgcolor;
node.graph.canvas.setDirty(true);
node.setDirtyCanvas(true);
}
}
@@ -3730,7 +3817,7 @@ LGraphCanvas.onMenuNodeShapes = function(node,e)
{
if(!node) return;
node.shape = v;
node.graph.canvas.setDirty(true);
node.setDirtyCanvas(true);
}
return false;
@@ -3740,7 +3827,7 @@ LGraphCanvas.onMenuNodeRemove = function(node)
{
if(node.removable == false) return;
node.graph.remove(node);
node.graph.canvas.setDirty(true,true);
node.setDirtyCanvas(true,true);
}
LGraphCanvas.onMenuNodeClone = function(node)
@@ -3750,7 +3837,7 @@ LGraphCanvas.onMenuNodeClone = function(node)
if(!newnode) return;
newnode.pos = [node.pos[0]+5,node.pos[1]+5];
node.graph.add(newnode);
node.graph.canvas.setDirty(true,true);
node.setDirtyCanvas(true,true);
}
LGraphCanvas.node_colors = {

348
src/nodes/base.js Normal file
View File

@@ -0,0 +1,348 @@
//basic nodes
(function(){
//Input for a subgraph
function GlobalInput()
{
this.addOutput("value",0);
}
GlobalInput.prototype.onExecute = function()
{
var name = this.title;
//read input
var value = node.graph.global_inputs[name];
this.setOutputData(0,value);
}
LiteGraph.registerNodeType("graph/input", GlobalInput);
//Output for a subgraph
function GlobalOutput()
{
this.title = "Output";
//random name to avoid problems with other outputs when added
var genname = "input_" + (Math.random()*1000).toFixed();
this.properties = { name: genname, type: "number" };
this.addInput("value","number");
}
GlobalOutput.prototype.onAdded = function()
{
var name = this.graph.addGlobalOutput( this.properties.name, this.properties.type );
}
GlobalOutput.prototype.onExecute = function()
{
var value = this.getInputData(0);
this.graph.setGlobalOutputData( this.properties.name, value );
}
LiteGraph.registerNodeType("graph/output", GlobalOutput);
//Subgraph: a node that contains a graph
function Subgraph()
{
this.subgraph = new LGraph();
this.bgcolor = "#FA3";
}
Subgraph.prototype.onExecute = function()
{
//send inputs to subgraph global inputs
for(var i in this.inputs)
{
var input = this.inputs[i];
//this.subgraph.setGlobalInputData( input.name, input.value );
}
//send subgraph global outputs to outputs
}
Subgraph.prototype.configure = function(o)
{
LGraph.prototype.configure.call(this, o);
//after configure, ...
}
LiteGraph.registerNodeType("graph/subgraph", Subgraph);
//Constant
function Constant()
{
this.addOutput("value","number");
this.properties = { value:1.0 };
this.editable = { property:"value", type:"number" };
}
Constant.title = "Const";
Constant.desc = "Constant value";
Constant.prototype.setValue = function(v)
{
if( typeof(v) == "string") v = parseFloat(v);
this.properties["value"] = v;
this.setDirtyCanvas(true);
};
Constant.prototype.onExecute = function()
{
this.setOutputData(0, parseFloat( this.properties["value"] ) );
}
Constant.prototype.onDrawBackground = function(ctx)
{
//show the current value
this.outputs[0].label = this.properties["value"].toFixed(3);
}
Constant.prototype.onWidget = function(e,widget)
{
if(widget.name == "value")
this.setValue(widget.value);
}
LiteGraph.registerNodeType("basic/const", Constant);
//Watch a value in the editor
function Watch()
{
this.size = [60,20];
this.addInput("value",0,{label:""});
this.addOutput("value",0,{label:""});
this.properties = { value:"" };
}
Watch.title = "Watch";
Watch.desc = "Show value of input";
Watch.prototype.onExecute = function()
{
this.properties.value = this.getInputData(0);
this.setOutputData(0, this.properties.value);
}
Watch.prototype.onDrawBackground = function(ctx)
{
//show the current value
if(this.inputs[0] && this.properties["value"] != null)
{
if (this.properties["value"].constructor === Number )
this.inputs[0].label = this.properties["value"].toFixed(3);
else
this.inputs[0].label = this.properties["value"];
}
}
LiteGraph.registerNodeType("basic/watch", Watch);
/*
LiteGraph.registerNodeType("math/sinusoid",{
title: "Sin",
desc: "Sinusoidal value generator",
bgImageUrl: "nodes/imgs/icon-sin.png",
inputs: [["f",'number'],["q",'number'],["a",'number'],["t",'number']],
outputs: [["",'number']],
properties: {amplitude:1.0, freq: 1, phase:0},
onExecute: function()
{
var f = this.getInputData(0);
if(f != null)
this.properties["freq"] = f;
var q = this.getInputData(1);
if(q != null)
this.properties["phase"] = q;
var a = this.getInputData(2);
if(a != null)
this.properties["amplitude"] = a;
var t = this.graph.getFixedTime();
if(this.getInputData(3) != null)
t = this.getInputData(3);
// t = t/(2*Math.PI); t = (t-Math.floor(t))*(2*Math.PI);
var v = this.properties["amplitude"] * Math.sin((2*Math.PI) * t * this.properties["freq"] + this.properties["phase"]);
this.setOutputData(0, v );
},
onDragBackground: function(ctx)
{
this.boxcolor = colorToString(v > 0 ? [0.5,0.8,1,0.5] : [0,0,0,0.5]);
this.setDirtyCanvas(true);
},
});
*/
/*
LiteGraph.registerNodeType("basic/number",{
title: "Number",
// System vars *********************************
LiteGraph.registerNodeType("session/info",{
title: "Time",
desc: "Seconds since start",
outputs: [["secs",'number']],
properties: {scale:1.0},
onExecute: function()
{
this.setOutputData(0, this.session.getTime() * this.properties.scale);
}
});
LiteGraph.registerNodeType("system/fixedtime",{
title: "F.Time",
desc: "Constant time value",
outputs: [["secs",'number']],
properties: {scale:1.0},
onExecute: function()
{
this.setOutputData(0, this.session.getFixedTime() * this.properties.scale);
}
});
LiteGraph.registerNodeType("system/elapsedtime",{
title: "Elapsed",
desc: "Seconds elapsed since last execution",
outputs: [["secs",'number']],
properties: {scale:1.0},
onExecute: function()
{
this.setOutputData(0, this.session.getElapsedTime() * this.properties.scale);
}
});
LiteGraph.registerNodeType("system/iterations",{
title: "Iterations",
desc: "Number of iterations (executions)",
outputs: [["",'number']],
onExecute: function()
{
this.setOutputData(0, this.session.iterations );
}
});
LiteGraph.registerNodeType("system/trace",{
desc: "Outputs input to browser's console",
inputs: [["",0]],
onExecute: function()
{
var data = this.getInputData(0);
if(data)
trace("DATA: "+data);
}
});
/*
LiteGraph.registerNodeType("math/not",{
title: "Not",
desc: "0 -> 1 or 0 -> 1",
inputs: [["A",'number']],
outputs: [["!A",'number']],
size: [60,22],
onExecute: function()
{
var v = this.getInputData(0);
if(v != null)
this.setOutputData(0, v ? 0 : 1);
}
});
// Nodes for network in and out
LiteGraph.registerNodeType("network/general/network_input",{
title: "N.Input",
desc: "Network Input",
outputs: [["",0]],
color: "#00ff96",
bgcolor: "#004327",
setValue: function(v)
{
this.value = v;
},
onExecute: function()
{
this.setOutputData(0, this.value);
}
});
LiteGraph.registerNodeType("network/general/network_output",{
title: "N.Output",
desc: "Network output",
inputs: [["",0]],
color: "#a8ff00",
bgcolor: "#293e00",
properties: {value:null},
getValue: function()
{
return this.value;
},
onExecute: function()
{
this.value = this.getOutputData(0);
}
});
LiteGraph.registerNodeType("network/network_trigger",{
title: "N.Trigger",
desc: "Network input trigger",
outputs: [["",0]],
color: "#ff9000",
bgcolor: "#522e00",
onTrigger: function(v)
{
this.triggerOutput(0,v);
},
});
LiteGraph.registerNodeType("network/network_callback",{
title: "N.Callback",
desc: "Network callback output.",
outputs: [["",0]],
color: "#6A6",
bgcolor: "#363",
setTrigger: function(func)
{
this.callback = func;
},
onTrigger: function(v)
{
if(this.callback)
this.callback(v);
},
});
*/
})();

645
src/nodes/image.js Normal file
View File

@@ -0,0 +1,645 @@
(function(){
function ColorPalette()
{
this.addInput("f","number");
this.addOutput("Color","color");
this.properties = {colorA:"#444444",colorB:"#44AAFF",colorC:"#44FFAA",colorD:"#FFFFFF"};
}
ColorPalette.title = "Palette";
ColorPalette.desc = "Generates a color";
ColorPalette.prototype.onExecute = function()
{
var c = [];
if (this.properties.colorA != null)
c.push( hex2num( this.properties.colorA ) );
if (this.properties.colorB != null)
c.push( hex2num( this.properties.colorB ) );
if (this.properties.colorC != null)
c.push( hex2num( this.properties.colorC ) );
if (this.properties.colorD != null)
c.push( hex2num( this.properties.colorD ) );
var f = this.getInputData(0);
if(f == null) f = 0.5;
if (f > 1.0)
f = 1.0;
else if (f < 0.0)
f = 0.0;
if(c.length == 0)
return;
var result = [0,0,0];
if(f == 0)
result = c[0];
else if(f == 1)
result = c[ c.length - 1];
else
{
var pos = (c.length - 1)* f;
var c1 = c[ Math.floor(pos) ];
var c2 = c[ Math.floor(pos)+1 ];
var t = pos - Math.floor(pos);
result[0] = c1[0] * (1-t) + c2[0] * (t);
result[1] = c1[1] * (1-t) + c2[1] * (t);
result[2] = c1[2] * (1-t) + c2[2] * (t);
}
/*
c[0] = 1.0 - Math.abs( Math.sin( 0.1 * reModular.getTime() * Math.PI) );
c[1] = Math.abs( Math.sin( 0.07 * reModular.getTime() * Math.PI) );
c[2] = Math.abs( Math.sin( 0.01 * reModular.getTime() * Math.PI) );
*/
for(var i in result)
result[i] /= 255;
this.boxcolor = colorToString(result);
this.setOutputData(0, result);
}
LiteGraph.registerNodeType("color/palette", ColorPalette );
function ImageFrame()
{
this.addInput("","image");
this.size = [200,200];
}
ImageFrame.title = "Frame";
ImageFrame.desc = "Frame viewerew";
ImageFrame.widgets = [{name:"resize",text:"Resize box",type:"button"},{name:"view",text:"View Image",type:"button"}];
ImageFrame.prototype.onDrawBackground = function(ctx)
{
if(this.frame)
ctx.drawImage(this.frame, 0,0,this.size[0],this.size[1]);
}
ImageFrame.prototype.onExecute = function()
{
this.frame = this.getInputData(0);
this.setDirtyCanvas(true);
}
ImageFrame.prototype.onWidget = function(e,widget)
{
if(widget.name == "resize" && this.frame)
{
var width = this.frame.width;
var height = this.frame.height;
if(!width && this.frame.videoWidth != null )
{
width = this.frame.videoWidth;
height = this.frame.videoHeight;
}
if(width && height)
this.size = [width, height];
this.setDirtyCanvas(true,true);
}
else if(widget.name == "view")
this.show();
}
ImageFrame.prototype.show = function()
{
//var str = this.canvas.toDataURL("image/png");
if(showElement && this.frame)
showElement(this.frame);
}
LiteGraph.registerNodeType("graphics/frame", ImageFrame );
/*
LiteGraph.registerNodeType("visualization/graph", {
desc: "Shows a graph of the inputs",
inputs: [["",0],["",0],["",0],["",0]],
size: [200,200],
properties: {min:-1,max:1,bgColor:"#000"},
onDrawBackground: function(ctx)
{
var colors = ["#FFF","#FAA","#AFA","#AAF"];
if(this.properties.bgColor != null && this.properties.bgColor != "")
{
ctx.fillStyle="#000";
ctx.fillRect(2,2,this.size[0] - 4, this.size[1]-4);
}
if(this.data)
{
var min = this.properties["min"];
var max = this.properties["max"];
for(var i in this.data)
{
var data = this.data[i];
if(!data) continue;
if(this.getInputInfo(i) == null) continue;
ctx.strokeStyle = colors[i];
ctx.beginPath();
var d = data.length / this.size[0];
for(var j = 0; j < data.length; j += d)
{
var value = data[ Math.floor(j) ];
value = (value - min) / (max - min);
if (value > 1.0) value = 1.0;
else if(value < 0) value = 0;
if(j == 0)
ctx.moveTo( j / d, (this.size[1] - 5) - (this.size[1] - 10) * value);
else
ctx.lineTo( j / d, (this.size[1] - 5) - (this.size[1] - 10) * value);
}
ctx.stroke();
}
}
//ctx.restore();
},
onExecute: function()
{
if(!this.data) this.data = [];
for(var i in this.inputs)
{
var value = this.getInputData(i);
if(typeof(value) == "number")
{
value = value ? value : 0;
if(!this.data[i])
this.data[i] = [];
this.data[i].push(value);
if(this.data[i].length > (this.size[1] - 4))
this.data[i] = this.data[i].slice(1,this.data[i].length);
}
else
this.data[i] = value;
}
if(this.data.length)
this.setDirtyCanvas(true);
}
});
*/
function ImageFade()
{
this.addInputs([["img1","image"],["img2","image"],["fade","number"]]);
this.addInput("","image");
this.properties = {fade:0.5,width:512,height:512};
}
ImageFade.title = "Image fade";
ImageFade.desc = "Fades between images";
ImageFade.widgets = [{name:"resizeA",text:"Resize to A",type:"button"},{name:"resizeB",text:"Resize to B",type:"button"}];
ImageFade.prototype.onAdded = function()
{
this.createCanvas();
var ctx = this.canvas.getContext("2d");
ctx.fillStyle = "#000";
ctx.fillRect(0,0,this.properties["width"],this.properties["height"]);
}
ImageFade.prototype.createCanvas = function()
{
this.canvas = document.createElement("canvas");
this.canvas.width = this.properties["width"];
this.canvas.height = this.properties["height"];
}
ImageFade.prototype.onExecute = function()
{
var ctx = this.canvas.getContext("2d");
this.canvas.width = this.canvas.width;
var A = this.getInputData(0);
if (A != null)
{
ctx.drawImage(A,0,0,this.canvas.width, this.canvas.height);
}
var fade = this.getInputData(2);
if(fade == null)
fade = this.properties["fade"];
else
this.properties["fade"] = fade;
ctx.globalAlpha = fade;
var B = this.getInputData(1);
if (B != null)
{
ctx.drawImage(B,0,0,this.canvas.width, this.canvas.height);
}
ctx.globalAlpha = 1.0;
this.setOutputData(0,this.canvas);
this.setDirtyCanvas(true);
}
LiteGraph.registerNodeType("graphics/imagefade", ImageFade);
function GraphicsImage()
{
this.inputs = [];
this.addOutput("frame","image");
this.properties = {"url":""};
}
GraphicsImage.title = "Image";
GraphicsImage.desc = "Image loader";
GraphicsImage.widgets = [{name:"load",text:"Load",type:"button"}];
GraphicsImage.prototype.onAdded = function()
{
if(this.properties["url"] != "" && this.img == null)
{
this.loadImage(this.properties["url"]);
}
}
GraphicsImage.prototype.onExecute = function()
{
if(!this.img)
this.boxcolor = "#000";
if(this.img && this.img.width)
this.setOutputData(0,this.img);
else
this.setOutputData(0,null);
if(this.img.dirty)
this.img.dirty = false;
}
GraphicsImage.prototype.onPropertyChange = function(name,value)
{
this.properties[name] = value;
if (name == "url" && value != "")
this.loadImage(value);
return true;
}
GraphicsImage.prototype.loadImage = function(url)
{
if(url == "")
{
this.img = null;
return;
}
this.trace("loading image...");
this.img = document.createElement("img");
this.img.src = "miniproxy.php?url=" + url;
this.boxcolor = "#F95";
var that = this;
this.img.onload = function()
{
that.trace("Image loaded, size: " + that.img.width + "x" + that.img.height );
this.dirty = true;
that.boxcolor = "#9F9";
that.setDirtyCanvas(true);
}
}
GraphicsImage.prototype.onWidget = function(e,widget)
{
if(widget.name == "load")
{
this.loadImage(this.properties["url"]);
}
}
LiteGraph.registerNodeType("graphics/image", GraphicsImage);
function ImageCrop()
{
this.addInput("","image");
this.addOutputs("","image");
this.properties = {width:256,height:256,x:0,y:0,scale:1.0 };
this.size = [50,20];
}
ImageCrop.title = "Crop";
ImageCrop.desc = "Crop Image";
ImageCrop.prototype.onAdded = function()
{
this.createCanvas();
}
ImageCrop.prototype.createCanvas = function()
{
this.canvas = document.createElement("canvas");
this.canvas.width = this.properties["width"];
this.canvas.height = this.properties["height"];
}
ImageCrop.prototype.onExecute = function()
{
var input = this.getInputData(0);
if(!input) return;
if(input.width)
{
var ctx = this.canvas.getContext("2d");
ctx.drawImage(input, -this.properties["x"],-this.properties["y"], input.width * this.properties["scale"], input.height * this.properties["scale"]);
this.setOutputData(0,this.canvas);
}
else
this.setOutputData(0,null);
}
ImageCrop.prototype.onPropertyChange = function(name,value)
{
this.properties[name] = value;
if(name == "scale")
{
this.properties[name] = parseFloat(value);
if(this.properties[name] == 0)
{
this.trace("Error in scale");
this.properties[name] = 1.0;
}
}
else
this.properties[name] = parseInt(value);
this.createCanvas();
return true;
}
LiteGraph.registerNodeType("graphics/cropImage", ImageFade );
function ImageVideo()
{
this.addInput("t","number");
this.addOutputs([["frame","image"],["t","number"],["d","number"]]);
this.properties = {"url":""};
}
ImageVideo.title = "Video";
ImageVideo.desc = "Video playback";
ImageVideo.widgets = [{name:"play",text:"PLAY",type:"minibutton"},{name:"stop",text:"STOP",type:"minibutton"},{name:"demo",text:"Demo video",type:"button"},{name:"mute",text:"Mute video",type:"button"}];
ImageVideo.prototype.onExecute = function()
{
if(!this.properties.url)
return;
if(this.properties.url != this._video_url)
this.loadVideo(this.properties.url);
if(!this._video || this._video.width == 0)
return;
var t = this.getInputData(0);
if(t && t >= 0 && t <= 1.0)
{
this._video.currentTime = t * this._video.duration;
this._video.pause();
}
this._video.dirty = true;
this.setOutputData(0,this._video);
this.setOutputData(1,this._video.currentTime);
this.setOutputData(2,this._video.duration);
this.setDirtyCanvas(true);
}
ImageVideo.prototype.onStart = function()
{
this.play();
}
ImageVideo.prototype.onStop = function()
{
this.stop();
}
ImageVideo.prototype.loadVideo = function(url)
{
this._video_url = url;
this._video = document.createElement("video");
this._video.src = url;
this._video.type = "type=video/mp4";
this._video.muted = true;
this._video.autoplay = true;
var that = this;
this._video.addEventListener("loadedmetadata",function(e) {
//onload
that.trace("Duration: " + this.duration + " seconds");
that.trace("Size: " + this.videoWidth + "," + this.videoHeight);
that.setDirtyCanvas(true);
this.width = this.videoWidth;
this.height = this.videoHeight;
});
this._video.addEventListener("progress",function(e) {
//onload
//that.trace("loading...");
});
this._video.addEventListener("error",function(e) {
console.log("Error loading video: " + this.src);
that.trace("Error loading video: " + this.src);
if (this.error) {
switch (this.error.code) {
case this.error.MEDIA_ERR_ABORTED:
that.trace("You stopped the video.");
break;
case this.error.MEDIA_ERR_NETWORK:
that.trace("Network error - please try again later.");
break;
case this.error.MEDIA_ERR_DECODE:
that.trace("Video is broken..");
break;
case this.error.MEDIA_ERR_SRC_NOT_SUPPORTED:
that.trace("Sorry, your browser can't play this video.");
break;
}
}
});
this._video.addEventListener("ended",function(e) {
that.trace("Ended.");
this.play(); //loop
});
//document.body.appendChild(this.video);
}
ImageVideo.prototype.onPropertyChange = function(name,value)
{
this.properties[name] = value;
if (name == "url" && value != "")
this.loadVideo(value);
return true;
}
ImageVideo.prototype.play = function()
{
if(this._video)
this._video.play();
}
ImageVideo.prototype.playPause = function()
{
if(!this._video)
return;
if(this._video.paused)
this.play();
else
this.pause();
}
ImageVideo.prototype.stop = function()
{
if(!this._video)
return;
this._video.pause();
this._video.currentTime = 0;
}
ImageVideo.prototype.pause = function()
{
if(!this._video)
return;
this.trace("Video paused");
this._video.pause();
}
ImageVideo.prototype.onWidget = function(e,widget)
{
/*
if(widget.name == "demo")
{
this.loadVideo();
}
else if(widget.name == "play")
{
if(this._video)
this.playPause();
}
if(widget.name == "stop")
{
this.stop();
}
else if(widget.name == "mute")
{
if(this._video)
this._video.muted = !this._video.muted;
}
*/
}
LiteGraph.registerNodeType("graphics/video", ImageVideo );
// Texture Webcam *****************************************
function ImageWebcam()
{
this.addOutput("Webcam","image");
this.properties = {};
}
ImageWebcam.title = "Webcam";
ImageWebcam.desc = "Webcam image";
ImageWebcam.prototype.openStream = function()
{
//Vendor prefixes hell
navigator.getUserMedia = (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);
window.URL = window.URL || window.webkitURL;
if (!navigator.getUserMedia) {
//console.log('getUserMedia() is not supported in your browser, use chrome and enable WebRTC from about://flags');
return;
}
this._waiting_confirmation = true;
// Not showing vendor prefixes.
navigator.getUserMedia({video: true}, this.streamReady.bind(this), onFailSoHard);
var that = this;
function onFailSoHard(e) {
trace('Webcam rejected', e);
that._webcam_stream = false;
that.box_color = "red";
};
}
ImageWebcam.prototype.streamReady = function(localMediaStream)
{
this._webcam_stream = localMediaStream;
//this._waiting_confirmation = false;
var video = this._video;
if(!video)
{
video = document.createElement("video");
video.autoplay = true;
video.src = window.URL.createObjectURL(localMediaStream);
this._video = video;
//document.body.appendChild( video ); //debug
//when video info is loaded (size and so)
video.onloadedmetadata = function(e) {
// Ready to go. Do some stuff.
console.log(e);
};
}
},
ImageWebcam.prototype.onExecute = function()
{
if(this._webcam_stream == null && !this._waiting_confirmation)
this.openStream();
if(!this._video || !this._video.videoWidth) return;
this._video.width = this._video.videoWidth;
this._video.hieght = this._video.videoHeight;
this.setOutputData(0, this._video);
}
LiteGraph.registerNodeType("graphics/webcam", ImageWebcam );
})();

720
src/nodes/interface.js Normal file
View File

@@ -0,0 +1,720 @@
//widgets
(function(){
function WidgetKnob()
{
this.size = [64,84];
this.addOutput("",'number');
this.properties = {min:0,max:1,value:0.5,wcolor:"#7AF",size:50};
}
WidgetKnob.title = "Knob";
WidgetKnob.desc = "Circular controller";
WidgetKnob.widgets = [{name:"increase",text:"+",type:"minibutton"},{name:"decrease",text:"-",type:"minibutton"}];
WidgetKnob.prototype.onAdded = function()
{
this.value = (this.properties["value"] - this.properties["min"]) / (this.properties["max"] - this.properties["min"]);
this.imgbg = this.loadImage("imgs/knob_bg.png");
this.imgfg = this.loadImage("imgs/knob_fg.png");
}
WidgetKnob.prototype.onDrawImageKnob = function(ctx)
{
if(!this.imgfg || !this.imgfg.width) return;
var d = this.imgbg.width*0.5;
var scale = this.size[0] / this.imgfg.width;
ctx.save();
ctx.translate(0,20);
ctx.scale(scale,scale);
ctx.drawImage(this.imgbg,0,0);
//ctx.drawImage(this.imgfg,0,20);
ctx.translate(d,d);
ctx.rotate(this.value * (Math.PI*2) * 6/8 + Math.PI * 10/8);
//ctx.rotate(this.value * (Math.PI*2));
ctx.translate(-d,-d);
ctx.drawImage(this.imgfg,0,0);
ctx.restore();
ctx.font = "bold 16px Criticized,Tahoma";
ctx.fillStyle="rgba(100,100,100,0.8)";
ctx.textAlign = "center";
ctx.fillText(this.name.toUpperCase(), this.size[0] * 0.5, 18 );
ctx.textAlign = "left";
}
WidgetKnob.prototype.onDrawVectorKnob = function(ctx)
{
if(!this.imgfg || !this.imgfg.width) return;
//circle around
ctx.lineWidth = 1;
ctx.strokeStyle= this.mouseOver ? "#FFF" : "#AAA";
ctx.fillStyle="#000";
ctx.beginPath();
ctx.arc(this.size[0] * 0.5,this.size[1] * 0.5 + 10,this.properties.size * 0.5,0,Math.PI*2,true);
ctx.stroke();
if(this.value > 0)
{
ctx.strokeStyle=this.properties["wcolor"];
ctx.lineWidth = (this.properties.size * 0.2);
ctx.beginPath();
ctx.arc(this.size[0] * 0.5,this.size[1] * 0.5 + 10,this.properties.size * 0.35,Math.PI * -0.5 + Math.PI*2 * this.value,Math.PI * -0.5,true);
ctx.stroke();
ctx.lineWidth = 1;
}
ctx.font = (this.properties.size * 0.2) + "px Arial";
ctx.fillStyle="#AAA";
ctx.textAlign = "center";
var str = this.properties["value"];
if(typeof(str) == 'number')
str = str.toFixed(2);
ctx.fillText(str,this.size[0] * 0.5,this.size[1]*0.65);
ctx.textAlign = "left";
}
WidgetKnob.prototype.onDrawForeground = function(ctx)
{
this.onDrawImageKnob(ctx);
}
WidgetKnob.prototype.onExecute = function()
{
this.setOutputData(0, this.properties["value"] );
this.boxcolor = colorToString([this.value,this.value,this.value]);
}
WidgetKnob.prototype.onMouseDown = function(e)
{
if(!this.imgfg || !this.imgfg.width) return;
//this.center = [this.imgbg.width * 0.5, this.imgbg.height * 0.5 + 20];
//this.radius = this.imgbg.width * 0.5;
this.center = [this.size[0] * 0.5, this.size[1] * 0.5 + 20];
this.radius = this.size[0] * 0.5;
if(e.canvasY - this.pos[1] < 20 || distance([e.canvasX,e.canvasY],[this.pos[0] + this.center[0],this.pos[1] + this.center[1]]) > this.radius)
return false;
this.oldmouse = [ e.canvasX - this.pos[0], e.canvasY - this.pos[1] ];
this.captureInput(true);
/*
var tmp = this.localToScreenSpace(0,0);
this.trace(tmp[0] + "," + tmp[1]); */
return true;
}
WidgetKnob.prototype.onMouseMove = function(e)
{
if(!this.oldmouse) return;
var m = [ e.canvasX - this.pos[0], e.canvasY - this.pos[1] ];
var v = this.value;
v -= (m[1] - this.oldmouse[1]) * 0.01;
if(v > 1.0) v = 1.0;
else if(v < 0.0) v = 0.0;
this.value = v;
this.properties["value"] = this.properties["min"] + (this.properties["max"] - this.properties["min"]) * this.value;
this.oldmouse = m;
this.setDirtyCanvas(true);
}
WidgetKnob.prototype.onMouseUp = function(e)
{
if(this.oldmouse)
{
this.oldmouse = null;
this.captureInput(false);
}
}
WidgetKnob.prototype.onMouseLeave = function(e)
{
//this.oldmouse = null;
}
WidgetKnob.prototype.onWidget = function(e,widget)
{
if(widget.name=="increase")
this.onPropertyChange("size", this.properties.size + 10);
else if(widget.name=="decrease")
this.onPropertyChange("size", this.properties.size - 10);
}
WidgetKnob.prototype.onPropertyChange = function(name,value)
{
if(name=="wcolor")
this.properties[name] = value;
else if(name=="size")
{
value = parseInt(value);
this.properties[name] = value;
this.size = [value+4,value+24];
this.setDirtyCanvas(true,true);
}
else if(name=="min" || name=="max" || name=="value")
{
this.properties[name] = parseFloat(value);
}
else
return false;
return true;
}
LiteGraph.registerNodeType("widget/knob", WidgetKnob);
//Widget H SLIDER
function WidgetHSlider()
{
this.size = [160,26];
this.addOutput("",'number');
this.properties = {wcolor:"#7AF",min:0,max:1,value:0.5};
}
WidgetHSlider.title = "H.Slider";
WidgetHSlider.desc = "Linear slider controller";
WidgetHSlider.prototype.onInit = function()
{
this.value = 0.5;
this.imgfg = this.loadImage("imgs/slider_fg.png");
}
WidgetHSlider.prototype.onDrawVectorial = function(ctx)
{
if(!this.imgfg || !this.imgfg.width) return;
//border
ctx.lineWidth = 1;
ctx.strokeStyle= this.mouseOver ? "#FFF" : "#AAA";
ctx.fillStyle="#000";
ctx.beginPath();
ctx.rect(2,0,this.size[0]-4,20);
ctx.stroke();
ctx.fillStyle=this.properties["wcolor"];
ctx.beginPath();
ctx.rect(2+(this.size[0]-4-20)*this.value,0, 20,20);
ctx.fill();
}
WidgetHSlider.prototype.onDrawImage = function(ctx)
{
if(!this.imgfg || !this.imgfg.width)
return;
//border
ctx.lineWidth = 1;
ctx.fillStyle="#000";
ctx.fillRect(2,9,this.size[0]-4,2);
ctx.strokeStyle= "#333";
ctx.beginPath();
ctx.moveTo(2,9);
ctx.lineTo(this.size[0]-4,9);
ctx.stroke();
ctx.strokeStyle= "#AAA";
ctx.beginPath();
ctx.moveTo(2,11);
ctx.lineTo(this.size[0]-4,11);
ctx.stroke();
ctx.drawImage(this.imgfg, 2+(this.size[0]-4)*this.value - this.imgfg.width*0.5,-this.imgfg.height*0.5 + 10);
},
WidgetHSlider.prototype.onDrawForeground = function(ctx)
{
this.onDrawImage(ctx);
}
WidgetHSlider.prototype.onExecute = function()
{
this.properties["value"] = this.properties["min"] + (this.properties["max"] - this.properties["min"]) * this.value;
this.setOutputData(0, this.properties["value"] );
this.boxcolor = colorToString([this.value,this.value,this.value]);
}
WidgetHSlider.prototype.onMouseDown = function(e)
{
if(e.canvasY - this.pos[1] < 0)
return false;
this.oldmouse = [ e.canvasX - this.pos[0], e.canvasY - this.pos[1] ];
this.captureInput(true);
return true;
}
WidgetHSlider.prototype.onMouseMove = function(e)
{
if(!this.oldmouse) return;
var m = [ e.canvasX - this.pos[0], e.canvasY - this.pos[1] ];
var v = this.value;
var delta = (m[0] - this.oldmouse[0]);
v += delta / this.size[0];
if(v > 1.0) v = 1.0;
else if(v < 0.0) v = 0.0;
this.value = v;
this.oldmouse = m;
this.setDirtyCanvas(true);
}
WidgetHSlider.prototype.onMouseUp = function(e)
{
this.oldmouse = null;
this.captureInput(false);
}
WidgetHSlider.prototype.onMouseLeave = function(e)
{
//this.oldmouse = null;
}
WidgetHSlider.prototype.onPropertyChange = function(name,value)
{
if(name=="wcolor")
this.properties[name] = value;
else
return false;
return true;
}
LiteGraph.registerNodeType("widget/hslider", WidgetHSlider );
function WidgetProgress()
{
this.size = [160,26];
this.addInput("",'number');
this.properties = {min:0,max:1,value:0,wcolor:"#AAF"};
}
WidgetProgress.title = "Progress";
WidgetProgress.desc = "Shows data in linear progress";
WidgetProgress.prototype.onExecute = function()
{
var v = this.getInputData(0);
if( v != undefined )
this.properties["value"] = v;
}
WidgetProgress.prototype.onDrawForeground = function(ctx)
{
//border
ctx.lineWidth = 1;
ctx.fillStyle=this.properties.wcolor;
var v = (this.properties.value - this.properties.min) / (this.properties.max - this.properties.min);
v = Math.min(1,v);
v = Math.max(0,v);
ctx.fillRect(2,2,(this.size[0]-4)*v,this.size[1]-4);
}
LiteGraph.registerNodeType("widget/progress", WidgetProgress);
/*
LiteGraph.registerNodeType("widget/kpad",{
title: "KPad",
desc: "bidimensional slider",
size: [200,200],
outputs: [["x",'number'],["y",'number']],
properties:{x:0,y:0,borderColor:"#333",bgcolorTop:"#444",bgcolorBottom:"#000",shadowSize:1, borderRadius:2},
createGradient: function(ctx)
{
this.lineargradient = ctx.createLinearGradient(0,0,0,this.size[1]);
this.lineargradient.addColorStop(0,this.properties["bgcolorTop"]);
this.lineargradient.addColorStop(1,this.properties["bgcolorBottom"]);
},
onDrawBackground: function(ctx)
{
if(!this.lineargradient)
this.createGradient(ctx);
ctx.lineWidth = 1;
ctx.strokeStyle = this.properties["borderColor"];
//ctx.fillStyle = "#ebebeb";
ctx.fillStyle = this.lineargradient;
ctx.shadowColor = "#000";
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = this.properties["shadowSize"];
ctx.roundRect(0,0,this.size[0],this.size[1],this.properties["shadowSize"]);
ctx.fill();
ctx.shadowColor = "rgba(0,0,0,0)";
ctx.stroke();
ctx.fillStyle = "#A00";
ctx.fillRect(this.size[0] * this.properties["x"] - 5, this.size[1] * this.properties["y"] - 5,10,10);
},
onWidget: function(e,widget)
{
if(widget.name == "update")
{
this.lineargradient = null;
this.setDirtyCanvas(true);
}
},
onExecute: function()
{
this.setOutputData(0, this.properties["x"] );
this.setOutputData(1, this.properties["y"] );
},
onMouseDown: function(e)
{
if(e.canvasY - this.pos[1] < 0)
return false;
this.oldmouse = [ e.canvasX - this.pos[0], e.canvasY - this.pos[1] ];
this.captureInput(true);
return true;
},
onMouseMove: function(e)
{
if(!this.oldmouse) return;
var m = [ e.canvasX - this.pos[0], e.canvasY - this.pos[1] ];
this.properties.x = m[0] / this.size[0];
this.properties.y = m[1] / this.size[1];
if(this.properties.x > 1.0) this.properties.x = 1.0;
else if(this.properties.x < 0.0) this.properties.x = 0.0;
if(this.properties.y > 1.0) this.properties.y = 1.0;
else if(this.properties.y < 0.0) this.properties.y = 0.0;
this.oldmouse = m;
this.setDirtyCanvas(true);
},
onMouseUp: function(e)
{
if(this.oldmouse)
{
this.oldmouse = null;
this.captureInput(false);
}
},
onMouseLeave: function(e)
{
//this.oldmouse = null;
}
});
LiteGraph.registerNodeType("widget/button", {
title: "Button",
desc: "A send command button",
widgets: [{name:"test",text:"Test Button",type:"button"}],
size: [100,40],
properties:{text:"clickme",command:"",color:"#7AF",bgcolorTop:"#f0f0f0",bgcolorBottom:"#e0e0e0",fontsize:"16"},
outputs:[["M","module"]],
createGradient: function(ctx)
{
this.lineargradient = ctx.createLinearGradient(0,0,0,this.size[1]);
this.lineargradient.addColorStop(0,this.properties["bgcolorTop"]);
this.lineargradient.addColorStop(1,this.properties["bgcolorBottom"]);
},
drawVectorShape: function(ctx)
{
ctx.fillStyle = this.mouseOver ? this.properties["color"] : "#AAA";
if(this.clicking)
ctx.fillStyle = "#FFF";
ctx.strokeStyle = "#AAA";
ctx.roundRect(5,5,this.size[0] - 10,this.size[1] - 10,4);
ctx.stroke();
if(this.mouseOver)
ctx.fill();
//ctx.fillRect(5,20,this.size[0] - 10,this.size[1] - 30);
ctx.fillStyle = this.mouseOver ? "#000" : "#AAA";
ctx.font = "bold " + this.properties["fontsize"] + "px Criticized,Tahoma";
ctx.textAlign = "center";
ctx.fillText(this.properties["text"],this.size[0]*0.5,this.size[1]*0.5 + 0.5*parseInt(this.properties["fontsize"]));
ctx.textAlign = "left";
},
drawBevelShape: function(ctx)
{
ctx.shadowColor = "#000";
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = this.properties["shadowSize"];
if(!this.lineargradient)
this.createGradient(ctx);
ctx.fillStyle = this.mouseOver ? this.properties["color"] : this.lineargradient;
if(this.clicking)
ctx.fillStyle = "#444";
ctx.strokeStyle = "#FFF";
ctx.roundRect(5,5,this.size[0] - 10,this.size[1] - 10,4);
ctx.fill();
ctx.shadowColor = "rgba(0,0,0,0)";
ctx.stroke();
ctx.fillStyle = this.mouseOver ? "#000" : "#444";
ctx.font = "bold " + this.properties["fontsize"] + "px Century Gothic";
ctx.textAlign = "center";
ctx.fillText(this.properties["text"],this.size[0]*0.5,this.size[1]*0.5 + 0.40*parseInt(this.properties["fontsize"]));
ctx.textAlign = "left";
},
onDrawForeground: function(ctx)
{
this.drawBevelShape(ctx);
},
clickButton: function()
{
var module = this.getOutputModule(0);
if(this.properties["command"] && this.properties["command"] != "")
{
if (! module.executeAction(this.properties["command"]) )
this.trace("Error executing action in other module");
}
else if(module && module.onTrigger)
{
module.onTrigger();
}
},
onMouseDown: function(e)
{
if(e.canvasY - this.pos[1] < 2)
return false;
this.clickButton();
this.clicking = true;
return true;
},
onMouseUp: function(e)
{
this.clicking = false;
},
onExecute: function()
{
},
onWidget: function(e,widget)
{
if(widget.name == "test")
{
this.clickButton();
}
},
onPropertyChange: function(name,value)
{
this.properties[name] = value;
return true;
}
});
*/
function WidgetText()
{
this.addInputs("",0);
this.properties = { value:"...",font:"Arial", fontsize:18, color:"#AAA", align:"left", glowSize:0, decimals:1 };
}
WidgetText.title = "Text";
WidgetText.desc = "Shows the input value";
WidgetText.widgets = [{name:"resize",text:"Resize box",type:"button"},{name:"led_text",text:"LED",type:"minibutton"},{name:"normal_text",text:"Normal",type:"minibutton"}];
WidgetText.prototype.onDrawForeground = function(ctx)
{
//ctx.fillStyle="#000";
//ctx.fillRect(0,0,100,60);
ctx.fillStyle = this.properties["color"];
var v = this.properties["value"];
if(this.properties["glowSize"])
{
ctx.shadowColor = this.properties["color"];
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = this.properties["glowSize"];
}
else
ctx.shadowColor = "transparent";
var fontsize = this.properties["fontsize"];
ctx.textAlign = this.properties["align"];
ctx.font = fontsize.toString() + "px " + this.properties["font"];
this.str = typeof(v) == 'number' ? v.toFixed(this.properties["decimals"]) : v;
if( typeof(this.str) == 'string')
{
var lines = this.str.split("\\n");
for(var i in lines)
ctx.fillText(lines[i],this.properties["align"] == "left" ? 15 : this.size[0] - 15, fontsize * -0.15 + fontsize * (parseInt(i)+1) );
}
ctx.shadowColor = "transparent";
this.last_ctx = ctx;
ctx.textAlign = "left";
}
WidgetText.prototype.onExecute = function()
{
var v = this.getInputData(0);
if(v != null)
this.properties["value"] = v;
else
this.properties["value"] = "";
this.setDirtyCanvas(true);
}
WidgetText.prototype.resize = function()
{
if(!this.last_ctx) return;
var lines = this.str.split("\\n");
this.last_ctx.font = this.properties["fontsize"] + "px " + this.properties["font"];
var max = 0;
for(var i in lines)
{
var w = this.last_ctx.measureText(lines[i]).width;
if(max < w) max = w;
}
this.size[0] = max + 20;
this.size[1] = 4 + lines.length * this.properties["fontsize"];
this.setDirtyCanvas(true);
}
WidgetText.prototype.onWidget = function(e,widget)
{
if(widget.name == "resize")
this.resize();
else if (widget.name == "led_text")
{
this.properties["font"] = "Digital";
this.properties["glowSize"] = 4;
this.setDirtyCanvas(true);
}
else if (widget.name == "normal_text")
{
this.properties["font"] = "Arial";
this.setDirtyCanvas(true);
}
}
WidgetText.prototype.onPropertyChange = function(name,value)
{
this.properties[name] = value;
this.str = typeof(value) == 'number' ? value.toFixed(3) : value;
//this.resize();
return true;
}
LiteGraph.registerNodeType("widget/text", WidgetText );
function WidgetPanel()
{
this.size = [200,100];
this.properties = {borderColor:"#ffffff",bgcolorTop:"#f0f0f0",bgcolorBottom:"#e0e0e0",shadowSize:2, borderRadius:3};
}
WidgetPanel.title = "Panel";
WidgetPanel.desc = "Non interactive panel";
WidgetPanel.widgets = [{name:"update",text:"Update",type:"button"}];
WidgetPanel.prototype.createGradient = function(ctx)
{
if(this.properties["bgcolorTop"] == "" || this.properties["bgcolorBottom"] == "")
{
this.lineargradient = 0;
return;
}
this.lineargradient = ctx.createLinearGradient(0,0,0,this.size[1]);
this.lineargradient.addColorStop(0,this.properties["bgcolorTop"]);
this.lineargradient.addColorStop(1,this.properties["bgcolorBottom"]);
}
WidgetPanel.prototype.onDrawForeground = function(ctx)
{
if(this.lineargradient == null)
this.createGradient(ctx);
if(!this.lineargradient)
return;
ctx.lineWidth = 1;
ctx.strokeStyle = this.properties["borderColor"];
//ctx.fillStyle = "#ebebeb";
ctx.fillStyle = this.lineargradient;
if(this.properties["shadowSize"])
{
ctx.shadowColor = "#000";
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = this.properties["shadowSize"];
}
else
ctx.shadowColor = "transparent";
ctx.roundRect(0,0,this.size[0]-1,this.size[1]-1,this.properties["shadowSize"]);
ctx.fill();
ctx.shadowColor = "transparent";
ctx.stroke();
}
WidgetPanel.prototype.onWidget = function(e,widget)
{
if(widget.name == "update")
{
this.lineargradient = null;
this.setDirtyCanvas(true);
}
}
LiteGraph.registerNodeType("widget/panel", WidgetPanel );
})();

472
src/nodes/math.js Normal file
View File

@@ -0,0 +1,472 @@
(function(){
function MathRand()
{
this.addOutput("value","number");
this.properties = { min:0, max:1 };
this.size = [60,20];
}
MathRand.title = "Rand";
MathRand.desc = "Random number";
MathRand.prototype.onExecute = function()
{
var min = this.properties.min;
var max = this.properties.max;
this._last_v = Math.random() * (max-min) + min;
this.setOutputData(0, this._last_v );
}
MathRand.prototype.onDrawBackground = function(ctx)
{
//show the current value
if(this._last_v)
this.outputs[0].label = this._last_v.toFixed(3);
else
this.outputs[0].label = "?";
}
LiteGraph.registerNodeType("math/rand", MathRand);
//Math clamp
function MathClamp()
{
this.addInput("in","number");
this.addOutput("out","number");
this.size = [60,20];
this.properties = {min:0, max:1};
}
MathClamp.title = "Clamp";
MathClamp.desc = "Clamp number between min and max";
MathClamp.prototype.onExecute = function()
{
var v = this.getInputData(0);
if(v == null) return;
v = Math.max(this.properties.min,v);
v = Math.min(this.properties.max,v);
this.setOutputData(0, v );
}
LiteGraph.registerNodeType("math/clamp", MathClamp );
//Math ABS
function MathAbs()
{
this.addInput("in","number");
this.addOutput("out","number");
this.size = [60,20];
}
MathAbs.title = "Abs";
MathAbs.desc = "Absolute";
MathAbs.prototype.onExecute = function()
{
var v = this.getInputData(0);
if(v == null) return;
this.setOutputData(0, Math.abs(v) );
}
LiteGraph.registerNodeType("math/abs", MathAbs);
//Math Floor
function MathFloor()
{
this.addInput("in","number");
this.addOutput("out","number");
this.size = [60,20];
}
MathFloor.title = "Floor";
MathFloor.desc = "Floor number to remove fractional part";
MathFloor.prototype.onExecute = function()
{
var v = this.getInputData(0);
if(v == null) return;
this.setOutputData(0, v|1 );
}
LiteGraph.registerNodeType("math/floor", MathFloor );
//Math frac
function MathFrac()
{
this.addInput("in","number");
this.addOutput("out","number");
this.size = [60,20];
}
MathFrac.title = "Frac";
MathFrac.desc = "Returns fractional part";
MathFrac.prototype.onExecute = function()
{
var v = this.getInputData(0);
if(v == null)
return;
this.setOutputData(0, v%1 );
}
LiteGraph.registerNodeType("math/frac",MathFrac);
//Math scale
function MathScale()
{
this.addInput("in","number",{label:""});
this.addOutput("out","number",{label:""});
this.size = [60,20];
this.properties = {"factor":1};
}
MathScale.title = "Scale";
MathScale.desc = "v * factor";
MathScale.prototype.onExecute = function()
{
var value = this.getInputData(0);
if(value != null)
this.setOutputData(0, value * this.properties.factor );
}
LiteGraph.registerNodeType("math/scale", MathScale );
//Math operation
function MathOperation()
{
this.addInput("A","number");
this.addInput("B","number");
this.addOutput("A+B","number");
this.size = [80,20];
this.properties = {A:1.0, B:1.0};
}
MathOperation.title = "Operation";
MathOperation.desc = "Easy math operators";
MathOperation.prototype.setValue = function(v)
{
if( typeof(v) == "string") v = parseFloat(v);
this.properties["value"] = v;
this.setDirtyCanvas(true);
}
MathOperation.prototype.onExecute = function()
{
var A = this.getInputData(0);
var B = this.getInputData(1);
if(A!=null)
this.properties["A"] = A;
else
A = this.properties["A"];
if(B!=null)
this.properties["B"] = B;
else
B = this.properties["B"];
for(var i = 0, l = this.outputs.length; i < l; ++i)
{
var output = this.outputs[i];
if(!output.links || !output.links.length)
continue;
var value = 0;
switch( output.name )
{
case "A+B": value = A+B; break;
case "A-B": value = A-B; break;
case "A*B": value = A*B; break;
case "A/B": value = A/B; break;
}
this.setOutputData(i, value );
}
}
MathOperation.prototype.onGetOutputs = function()
{
return [["A-B","number"],["A*B","number"],["A/B","number"]];
}
LiteGraph.registerNodeType("math/operation", MathOperation );
//Math compare
function MathCompare()
{
this.addInputs( "A","number" );
this.addInputs( "B","number" );
this.addOutputs("A==B","number");
this.addOutputs("A!=B","number");
this.properties = {A:0,B:0};
}
MathCompare.title = "Compare";
MathCompare.desc = "compares between two values";
MathCompare.prototype.onExecute = function()
{
var A = this.getInputData(0);
var B = this.getInputData(1);
if(A!=null)
this.properties["A"] = A;
else
A = this.properties["A"];
if(B!=null)
this.properties["B"] = B;
else
B = this.properties["B"];
for(var i = 0, l = this.outputs.length; i < l; ++i)
{
var output = this.outputs[i];
if(!output.links || !output.links.length)
continue;
switch( output.name )
{
case "A==B": value = A==B; break;
case "A!=B": value = A!=B; break;
case "A>B": value = A>B; break;
case "A<B": value = A<B; break;
case "A<=B": value = A<=B; break;
case "A>=B": value = A>=B; break;
}
this.setOutputData(i, value );
}
};
MathCompare.prototype.onGetOutputs = function()
{
return [["A==B","number"],["A!=B","number"],["A>B","number"],["A<B","number"],["A>=B","number"],["A<=B","number"]];
}
LiteGraph.registerNodeType("math/compare",MathCompare);
//Math Trigonometry
function MathTrigonometry()
{
this.addInputs("v","number");
this.addOutputs("sin","number");
this.properties = {amplitude:1.0};
this.size = [100,20];
this.bgImageUrl = "nodes/imgs/icon-sin.png";
}
MathTrigonometry.title = "Trigonometry";
MathTrigonometry.desc = "Sin Cos Tan";
MathTrigonometry.prototype.onExecute = function()
{
var v = this.getInputData(0);
var amp = this.properties["amplitude"];
for(var i = 0, l = this.outputs.length; i < l; ++i)
{
var output = this.outputs[i];
switch( output.name )
{
case "sin": value = Math.sin(v); break;
case "cos": value = Math.cos(v); break;
case "tan": value = Math.tan(v); break;
case "asin": value = Math.asin(v); break;
case "acos": value = Math.acos(v); break;
case "atan": value = Math.atan(v); break;
}
this.setOutputData(i, amp * value );
}
}
MathTrigonometry.prototype.onGetOutputs = function()
{
return [["sin","number"],["cos","number"],["tan","number"],["asin","number"],["acos","number"],["atan","number"]];
}
LiteGraph.registerNodeType("math/trigonometry", MathTrigonometry );
//math library for safe math operations without eval
if(window.math)
{
function MathFormula()
{
this.addInputs("x","number");
this.addInputs("y","number");
this.addOutputs("","number");
this.properties = {x:1.0, y:1.0, formula:"x+y"};
}
MathFormula.title = "Formula";
MathFormula.desc = "Compute safe formula";
MathFormula.prototype.onExecute = function()
{
var x = this.getInputData(0);
var y = this.getInputData(1);
if(x != null)
this.properties["x"] = x;
else
x = this.properties["x"];
if(y!=null)
this.properties["y"] = y;
else
y = this.properties["y"];
var f = this.properties["formula"];
var value = math.eval(f,{x:x,y:y,T: this.graph.globaltime });
this.setOutputData(0, value );
}
MathFormula.prototype.onDrawBackground = function()
{
var f = this.properties["formula"];
this.outputs[0].label = f;
}
MathFormula.prototype.onGetOutputs = function()
{
return [["A-B","number"],["A*B","number"],["A/B","number"]];
}
LiteGraph.registerNodeType("math/formula", MathFormula );
}
//if glMatrix is installed...
if(window.glMatrix)
{
function Math3DVec3ToXYZ()
{
this.addInput("vec3","vec3");
this.addOutput("x","number");
this.addOutput("y","number");
this.addOutput("z","number");
}
Math3DVec3ToXYZ.title = "Vec3->XYZ";
Math3DVec3ToXYZ.desc = "vector 3 to components";
Math3DVec3ToXYZ.prototype.onExecute = function()
{
var v = this.getInputData(0);
if(v == null) return;
this.setOutputData( 0, v[0] );
this.setOutputData( 1, v[1] );
this.setOutputData( 2, v[2] );
}
LiteGraph.registerNodeType("math3d/vec3-to-xyz", Math3DVec3ToXYZ );
function Math3DXYZToVec3()
{
this.addInputs([["x","number"],["y","number"],["z","number"]]);
this.addOutput("vec3","vec3");
}
Math3DXYZToVec3.title = "XYZ->Vec3";
Math3DXYZToVec3.desc = "components to vector3";
Math3DXYZToVec3.prototype.onExecute = function()
{
var x = this.getInputData(0);
if(x == null) x = 0;
var y = this.getInputData(1);
if(y == null) y = 0;
var z = this.getInputData(2);
if(z == null) z = 0;
this.setOutputData( 0, vec3.fromValues(x,y,z) );
}
LiteGraph.registerNodeType("math3d/xyz-to-vec3", Math3DXYZToVec3 );
function Math3DRotation()
{
this.addInputs([["degrees","number"],["axis","vec3"]]);
this.addOutput("quat","quat");
this.properties = { angle:90.0, axis: vec3.fromValues(0,1,0) };
}
Math3DRotation.title = "Rotation";
Math3DRotation.desc = "quaternion rotation";
Math3DRotation.prototype.onExecute = function()
{
var angle = this.getInputData(0);
if(angle == null) angle = this.properties.angle;
var axis = this.getInputData(1);
if(axis == null) axis = this.properties.axis;
var R = quat.setAxisAngle(quat.create(), axis, angle * 0.0174532925 );
this.setOutputData( 0, R );
}
LiteGraph.registerNodeType("math3d/rotation", Math3DRotation );
//Math3D rotate vec3
function Math3DRotateVec3()
{
this.addInputs([["vec3","vec3"],["quat","quat"]]);
this.addOutput("result","vec3");
this.properties = { vec: [0,0,1] };
}
Math3DRotateVec3.title = "Rot. Vec3";
Math3DRotateVec3.desc = "rotate a point";
Math3DRotateVec3.prototype.onExecute = function()
{
var vec = this.getInputData(0);
if(vec == null) vec = this.properties.vec;
var quat = this.getInputData(1);
if(quat == null)
this.setOutputData(vec);
else
this.setOutputData( 0, vec3.transformQuat( vec3.create(), vec, quat ) );
}
LiteGraph.registerNodeType("math3d/rotate_vec3", Math3DRotateVec3);
function Math3DMultQuat()
{
this.addInputs( [["A","quat"],["B","quat"]] );
this.addOutput( "A*B","quat" );
}
Math3DMultQuat.title = "Mult. Quat";
Math3DMultQuat.desc = "rotate quaternion";
Math3DMultQuat.prototype.onExecute = function()
{
var A = this.getInputData(0);
if(A == null) return;
var B = this.getInputData(1);
if(B == null) return;
var R = quat.multiply(quat.create(), A,B);
this.setOutputData( 0, R );
}
LiteGraph.registerNodeType("math3d/mult-quat", Math3DMultQuat );
} //glMatrix
})();

118
src/nodes/others.js Normal file
View File

@@ -0,0 +1,118 @@
/*
LiteGraph.registerNodeType("graphics/supergraph", {
title: "Supergraph",
desc: "Shows a nice circular graph",
inputs: [["x","number"],["y","number"],["c","color"]],
outputs: [["","image"]],
widgets: [{name:"clear_alpha",text:"Clear Alpha",type:"minibutton"},{name:"clear_color",text:"Clear color",type:"minibutton"}],
properties: {size:256,bgcolor:"#000",lineWidth:1},
bgcolor: "#000",
flags: {allow_fastrender:true},
onLoad: function()
{
this.createCanvas();
},
createCanvas: function()
{
this.canvas = document.createElement("canvas");
this.canvas.width = this.properties["size"];
this.canvas.height = this.properties["size"];
this.oldpos = null;
this.clearCanvas(true);
},
onExecute: function()
{
var x = this.getInputData(0);
var y = this.getInputData(1);
var c = this.getInputData(2);
if(x == null && y == null) return;
if(!x) x = 0;
if(!y) y = 0;
x*= 0.95;
y*= 0.95;
var size = this.properties["size"];
if(size != this.canvas.width || size != this.canvas.height)
this.createCanvas();
if (!this.oldpos)
{
this.oldpos = [ (x * 0.5 + 0.5) * size, (y*0.5 + 0.5) * size];
return;
}
var ctx = this.canvas.getContext("2d");
if(c == null)
c = "rgba(255,255,255,0.5)";
else if(typeof(c) == "object") //array
c = colorToString(c);
//stroke line
ctx.strokeStyle = c;
ctx.beginPath();
ctx.moveTo( this.oldpos[0], this.oldpos[1] );
this.oldpos = [ (x * 0.5 + 0.5) * size, (y*0.5 + 0.5) * size];
ctx.lineTo( this.oldpos[0], this.oldpos[1] );
ctx.stroke();
this.canvas.dirty = true;
this.setOutputData(0,this.canvas);
},
clearCanvas: function(alpha)
{
var ctx = this.canvas.getContext("2d");
if(alpha)
{
ctx.clearRect(0,0,this.canvas.width,this.canvas.height);
this.trace("Clearing alpha");
}
else
{
ctx.fillStyle = this.properties["bgcolor"];
ctx.fillRect(0,0,this.canvas.width,this.canvas.height);
}
},
onWidget: function(e,widget)
{
if(widget.name == "clear_color")
{
this.clearCanvas(false);
}
else if(widget.name == "clear_alpha")
{
this.clearCanvas(true);
}
},
onPropertyChange: function(name,value)
{
if(name == "size")
{
this.properties["size"] = parseInt(value);
this.createCanvas();
}
else if(name == "bgcolor")
{
this.properties["bgcolor"] = value;
this.createCanvas();
}
else if(name == "lineWidth")
{
this.properties["lineWidth"] = parseInt(value);
this.canvas.getContext("2d").lineWidth = this.properties["lineWidth"];
}
else
return false;
return true;
}
});
*/

View File

@@ -1,4 +1,5 @@
../src/litegraph.js
../src/nodes/basicnodes.js
../src/nodes/uinodes.js
../src/nodes/imagenodes.js
../src/nodes/base.js
../src/nodes/interface.js
../src/nodes/math.js
../src/nodes/image.js